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:
authorJulian Eisel <julian@blender.org>2022-11-10 15:17:42 +0300
committerJulian Eisel <julian@blender.org>2022-11-10 15:17:42 +0300
commit7246c387435769a169ac24c91434c615df6434b4 (patch)
tree61842e3e0ce85e80720fdd7476d44d2e629f59fd
parentc5f55d17096d373791363e46004176e3f7f7ae52 (diff)
parent0b4bd3ddc016298e868169a541cf6c132b10c587 (diff)
Merge branch 'master' into asset-browser-grid-viewasset-browser-grid-view
-rw-r--r--CMakeLists.txt420
-rw-r--r--GNUmakefile2
-rw-r--r--build_files/build_environment/CMakeLists.txt17
-rw-r--r--build_files/build_environment/cmake/aom.cmake6
-rw-r--r--build_files/build_environment/cmake/check_software.cmake2
-rw-r--r--build_files/build_environment/cmake/cve_check.cmake75
-rw-r--r--build_files/build_environment/cmake/cve_check.csv.in29
-rw-r--r--build_files/build_environment/cmake/download.cmake49
-rw-r--r--build_files/build_environment/cmake/dpcpp.cmake9
-rw-r--r--build_files/build_environment/cmake/ffmpeg.cmake6
-rw-r--r--build_files/build_environment/cmake/freetype.cmake4
-rw-r--r--build_files/build_environment/cmake/gmp.cmake1
-rw-r--r--build_files/build_environment/cmake/harvest.cmake352
-rw-r--r--build_files/build_environment/cmake/jpeg.cmake6
-rw-r--r--build_files/build_environment/cmake/llvm.cmake1
-rw-r--r--build_files/build_environment/cmake/opencollada.cmake51
-rw-r--r--build_files/build_environment/cmake/openpgl.cmake47
-rw-r--r--build_files/build_environment/cmake/options.cmake43
-rw-r--r--build_files/build_environment/cmake/osl.cmake3
-rw-r--r--build_files/build_environment/cmake/png.cmake8
-rw-r--r--build_files/build_environment/cmake/python.cmake17
-rw-r--r--build_files/build_environment/cmake/setup_mingw64.cmake6
-rw-r--r--build_files/build_environment/cmake/sndfile.cmake7
-rw-r--r--build_files/build_environment/cmake/sqlite.cmake1
-rw-r--r--build_files/build_environment/cmake/ssl.cmake1
-rw-r--r--build_files/build_environment/cmake/tiff.cmake1
-rw-r--r--build_files/build_environment/cmake/usd.cmake8
-rw-r--r--build_files/build_environment/cmake/versions.cmake224
-rw-r--r--build_files/build_environment/cmake/wayland.cmake27
-rw-r--r--build_files/build_environment/cmake/wayland_libdecor.cmake15
-rw-r--r--build_files/build_environment/cmake/wayland_protocols.cmake9
-rw-r--r--build_files/build_environment/cmake/xml2.cmake64
-rw-r--r--build_files/build_environment/dependencies.dot120
-rwxr-xr-xbuild_files/build_environment/install_deps.sh263
-rw-r--r--build_files/build_environment/linux/linux-centos7-setup.sh130
-rw-r--r--build_files/build_environment/patches/aom.diff18
-rw-r--r--build_files/build_environment/patches/cmake/modules/FindIlmBase.cmake12
-rw-r--r--build_files/build_environment/patches/cmake/modules/FindOpenEXR.cmake3
-rw-r--r--build_files/build_environment/patches/ffmpeg.diff40
-rw-r--r--build_files/build_environment/patches/gmp.diff15
-rw-r--r--build_files/build_environment/patches/opencollada.diff25
-rw-r--r--build_files/build_environment/patches/opencolorio.diff12
-rw-r--r--build_files/build_environment/patches/osl.diff135
-rw-r--r--build_files/build_environment/patches/python_windows.diff24
-rw-r--r--build_files/build_environment/patches/sndfile.diff42
-rw-r--r--build_files/build_environment/patches/sqlite.diff14
-rw-r--r--build_files/build_environment/patches/ssl.diff10
-rw-r--r--build_files/build_environment/patches/wayland.diff11
-rw-r--r--build_files/cmake/Modules/FindOSL.cmake15
-rw-r--r--build_files/cmake/Modules/FindOpenEXR.cmake3
-rw-r--r--build_files/cmake/Modules/FindOpenSubdiv.cmake15
-rw-r--r--build_files/cmake/Modules/FindSYCL.cmake41
-rw-r--r--build_files/cmake/Modules/FindUSD.cmake3
-rw-r--r--build_files/cmake/Modules/GTestTesting.cmake6
-rw-r--r--build_files/cmake/buildinfo.cmake4
-rw-r--r--build_files/cmake/config/blender_developer.cmake6
-rw-r--r--build_files/cmake/config/blender_full.cmake5
-rw-r--r--build_files/cmake/config/blender_release.cmake5
-rw-r--r--build_files/cmake/macros.cmake144
-rw-r--r--build_files/cmake/packaging.cmake8
-rw-r--r--build_files/cmake/platform/platform_apple.cmake129
-rw-r--r--build_files/cmake/platform/platform_unix.cmake387
-rw-r--r--build_files/cmake/platform/platform_win32.cmake196
-rw-r--r--build_files/cmake/platform/platform_win32_bundle_crt.cmake26
-rw-r--r--build_files/config/pipeline_config.yaml2
-rwxr-xr-xbuild_files/utils/make_bpy_wheel.py225
-rwxr-xr-xbuild_files/utils/make_source_archive.py66
-rwxr-xr-xbuild_files/utils/make_update.py86
-rwxr-xr-xbuild_files/utils/make_utils.py84
-rw-r--r--build_files/windows/parse_arguments.cmd2
-rw-r--r--build_files/windows/reset_variables.cmd1
-rw-r--r--build_files/windows/svn_update.cmd24
-rw-r--r--doc/doxygen/Doxyfile2
-rwxr-xr-xdoc/manpage/blender.1.py2
-rw-r--r--doc/python_api/examples/gpu.1.py1
-rw-r--r--doc/python_api/examples/gpu.10.py1
-rw-r--r--doc/python_api/examples/gpu.2.py1
-rw-r--r--doc/python_api/examples/gpu.3.py1
-rw-r--r--doc/python_api/examples/gpu.5.py1
-rw-r--r--doc/python_api/examples/gpu.6.py1
-rw-r--r--doc/python_api/examples/gpu.7.py1
-rw-r--r--doc/python_api/requirements.txt10
-rw-r--r--doc/python_api/rst/change_log.rst6
-rw-r--r--doc/python_api/rst/info_advanced.rst15
-rw-r--r--doc/python_api/rst/info_advanced_blender_as_bpy.rst126
-rw-r--r--doc/python_api/rst/info_api_reference.rst2
-rw-r--r--doc/python_api/rst/info_overview.rst6
-rw-r--r--doc/python_api/rst_from_bmesh_opdefines.py22
-rw-r--r--doc/python_api/sphinx_changelog_gen.py22
-rw-r--r--doc/python_api/sphinx_doc_gen.py53
-rw-r--r--extern/audaspace/include/devices/DeviceManager.h1
-rw-r--r--extern/gflags/CMakeLists.txt4
-rw-r--r--extern/hipew/src/hipew.c2
-rw-r--r--extern/mantaflow/CMakeLists.txt3
-rw-r--r--intern/atomic/intern/atomic_ops_utils.h3
-rw-r--r--intern/atomic/tests/atomic_test.cc8
-rw-r--r--intern/cycles/CMakeLists.txt52
-rw-r--r--intern/cycles/app/CMakeLists.txt5
-rw-r--r--intern/cycles/blender/CMakeLists.txt1
-rw-r--r--intern/cycles/blender/addon/__init__.py2
-rw-r--r--intern/cycles/blender/addon/engine.py27
-rw-r--r--intern/cycles/blender/addon/operators.py2
-rw-r--r--intern/cycles/blender/addon/properties.py104
-rw-r--r--intern/cycles/blender/addon/ui.py84
-rw-r--r--intern/cycles/blender/camera.cpp6
-rw-r--r--intern/cycles/blender/id_map.h32
-rw-r--r--intern/cycles/blender/mesh.cpp14
-rw-r--r--intern/cycles/blender/object.cpp83
-rw-r--r--intern/cycles/blender/pointcloud.cpp23
-rw-r--r--intern/cycles/blender/python.cpp12
-rw-r--r--intern/cycles/blender/session.cpp9
-rw-r--r--intern/cycles/blender/shader.cpp115
-rw-r--r--intern/cycles/blender/sync.cpp235
-rw-r--r--intern/cycles/blender/sync.h10
-rw-r--r--intern/cycles/bvh/split.cpp2
-rw-r--r--intern/cycles/cmake/external_libs.cmake103
-rw-r--r--intern/cycles/cmake/macros.cmake7
-rw-r--r--intern/cycles/device/CMakeLists.txt26
-rw-r--r--intern/cycles/device/cpu/device.cpp7
-rw-r--r--intern/cycles/device/cpu/device_impl.cpp18
-rw-r--r--intern/cycles/device/cpu/device_impl.h8
-rw-r--r--intern/cycles/device/cpu/kernel_thread_globals.cpp27
-rw-r--r--intern/cycles/device/cpu/kernel_thread_globals.h2
-rw-r--r--intern/cycles/device/cuda/device_impl.cpp6
-rw-r--r--intern/cycles/device/cuda/device_impl.h4
-rw-r--r--intern/cycles/device/cuda/queue.cpp6
-rw-r--r--intern/cycles/device/cuda/queue.h2
-rw-r--r--intern/cycles/device/device.cpp2
-rw-r--r--intern/cycles/device/device.h16
-rw-r--r--intern/cycles/device/hip/device_impl.h2
-rw-r--r--intern/cycles/device/hip/queue.cpp6
-rw-r--r--intern/cycles/device/hip/queue.h2
-rw-r--r--intern/cycles/device/kernel.cpp24
-rw-r--r--intern/cycles/device/kernel.h3
-rw-r--r--intern/cycles/device/metal/device_impl.mm14
-rw-r--r--intern/cycles/device/metal/kernel.mm107
-rw-r--r--intern/cycles/device/metal/queue.h2
-rw-r--r--intern/cycles/device/metal/queue.mm51
-rw-r--r--intern/cycles/device/metal/util.mm6
-rw-r--r--intern/cycles/device/multi/device.cpp15
-rw-r--r--intern/cycles/device/oneapi/device.cpp69
-rw-r--r--intern/cycles/device/oneapi/device_impl.cpp527
-rw-r--r--intern/cycles/device/oneapi/device_impl.h48
-rw-r--r--intern/cycles/device/oneapi/dll_interface.h17
-rw-r--r--intern/cycles/device/oneapi/queue.cpp17
-rw-r--r--intern/cycles/device/oneapi/queue.h6
-rw-r--r--intern/cycles/device/optix/device.cpp7
-rw-r--r--intern/cycles/device/optix/device_impl.cpp525
-rw-r--r--intern/cycles/device/optix/device_impl.h32
-rw-r--r--intern/cycles/device/optix/queue.cpp94
-rw-r--r--intern/cycles/device/queue.cpp27
-rw-r--r--intern/cycles/device/queue.h8
-rw-r--r--intern/cycles/integrator/CMakeLists.txt6
-rw-r--r--intern/cycles/integrator/guiding.h32
-rw-r--r--intern/cycles/integrator/path_trace.cpp140
-rw-r--r--intern/cycles/integrator/path_trace.h33
-rw-r--r--intern/cycles/integrator/path_trace_work.cpp4
-rw-r--r--intern/cycles/integrator/path_trace_work.h7
-rw-r--r--intern/cycles/integrator/path_trace_work_cpu.cpp110
-rw-r--r--intern/cycles/integrator/path_trace_work_cpu.h17
-rw-r--r--intern/cycles/integrator/path_trace_work_gpu.cpp31
-rw-r--r--intern/cycles/integrator/render_scheduler.cpp15
-rw-r--r--intern/cycles/integrator/render_scheduler.h6
-rw-r--r--intern/cycles/integrator/work_balancer.cpp3
-rw-r--r--intern/cycles/kernel/CMakeLists.txt212
-rw-r--r--intern/cycles/kernel/bvh/shadow_all.h2
-rw-r--r--intern/cycles/kernel/bvh/util.h8
-rw-r--r--intern/cycles/kernel/camera/projection.h26
-rw-r--r--intern/cycles/kernel/closure/alloc.h3
-rw-r--r--intern/cycles/kernel/closure/bsdf.h589
-rw-r--r--intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h244
-rw-r--r--intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h120
-rw-r--r--intern/cycles/kernel/closure/bsdf_diffuse.h34
-rw-r--r--intern/cycles/kernel/closure/bsdf_diffuse_ramp.h26
-rw-r--r--intern/cycles/kernel/closure/bsdf_hair.h52
-rw-r--r--intern/cycles/kernel/closure/bsdf_hair_principled.h201
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h394
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet_multi.h96
-rw-r--r--intern/cycles/kernel/closure/bsdf_oren_nayar.h17
-rw-r--r--intern/cycles/kernel/closure/bsdf_phong_ramp.h21
-rw-r--r--intern/cycles/kernel/closure/bsdf_principled_diffuse.h24
-rw-r--r--intern/cycles/kernel/closure/bsdf_principled_sheen.h27
-rw-r--r--intern/cycles/kernel/closure/bsdf_reflection.h21
-rw-r--r--intern/cycles/kernel/closure/bsdf_refraction.h22
-rw-r--r--intern/cycles/kernel/closure/bsdf_toon.h53
-rw-r--r--intern/cycles/kernel/closure/bsdf_transparent.h17
-rw-r--r--intern/cycles/kernel/data_template.h17
-rw-r--r--intern/cycles/kernel/device/cpu/bvh.h2
-rw-r--r--intern/cycles/kernel/device/cpu/globals.h19
-rw-r--r--intern/cycles/kernel/device/cpu/kernel.cpp9
-rw-r--r--intern/cycles/kernel/device/cuda/compat.h5
-rw-r--r--intern/cycles/kernel/device/gpu/parallel_active_index.h33
-rw-r--r--intern/cycles/kernel/device/hip/compat.h1
-rw-r--r--intern/cycles/kernel/device/metal/compat.h28
-rw-r--r--intern/cycles/kernel/device/metal/context_begin.h37
-rw-r--r--intern/cycles/kernel/device/metal/kernel.metal2
-rw-r--r--intern/cycles/kernel/device/oneapi/compat.h65
-rw-r--r--intern/cycles/kernel/device/oneapi/dll_interface_template.h54
-rw-r--r--intern/cycles/kernel/device/oneapi/globals.h9
-rw-r--r--intern/cycles/kernel/device/oneapi/kernel.cpp577
-rw-r--r--intern/cycles/kernel/device/oneapi/kernel.h21
-rw-r--r--intern/cycles/kernel/device/optix/bvh.h2
-rw-r--r--intern/cycles/kernel/device/optix/compat.h31
-rw-r--r--intern/cycles/kernel/device/optix/globals.h7
-rw-r--r--intern/cycles/kernel/device/optix/kernel_osl.cu83
-rw-r--r--intern/cycles/kernel/film/denoising_passes.h4
-rw-r--r--intern/cycles/kernel/integrator/displacement_shader.h4
-rw-r--r--intern/cycles/kernel/integrator/guiding.h547
-rw-r--r--intern/cycles/kernel/integrator/init_from_bake.h54
-rw-r--r--intern/cycles/kernel/integrator/intersect_closest.h11
-rw-r--r--intern/cycles/kernel/integrator/mnee.h12
-rw-r--r--intern/cycles/kernel/integrator/path_state.h18
-rw-r--r--intern/cycles/kernel/integrator/shade_background.h3
-rw-r--r--intern/cycles/kernel/integrator/shade_light.h3
-rw-r--r--intern/cycles/kernel/integrator/shade_shadow.h2
-rw-r--r--intern/cycles/kernel/integrator/shade_surface.h108
-rw-r--r--intern/cycles/kernel/integrator/shade_volume.h125
-rw-r--r--intern/cycles/kernel/integrator/shadow_state_template.h10
-rw-r--r--intern/cycles/kernel/integrator/state.h4
-rw-r--r--intern/cycles/kernel/integrator/state_flow.h6
-rw-r--r--intern/cycles/kernel/integrator/state_template.h33
-rw-r--r--intern/cycles/kernel/integrator/subsurface.h3
-rw-r--r--intern/cycles/kernel/integrator/subsurface_disk.h9
-rw-r--r--intern/cycles/kernel/integrator/subsurface_random_walk.h16
-rw-r--r--intern/cycles/kernel/integrator/surface_shader.h307
-rw-r--r--intern/cycles/kernel/integrator/volume_shader.h271
-rw-r--r--intern/cycles/kernel/osl/closures.cpp282
-rw-r--r--intern/cycles/kernel/osl/closures_setup.h27
-rw-r--r--intern/cycles/kernel/osl/closures_template.h4
-rw-r--r--intern/cycles/kernel/osl/osl.h183
-rw-r--r--intern/cycles/kernel/osl/services.cpp62
-rw-r--r--intern/cycles/kernel/osl/services.h10
-rw-r--r--intern/cycles/kernel/osl/services_gpu.h2149
-rw-r--r--intern/cycles/kernel/osl/services_optix.cu17
-rw-r--r--intern/cycles/kernel/osl/types.h102
-rw-r--r--intern/cycles/kernel/sample/pattern.h2
-rw-r--r--intern/cycles/kernel/svm/closure.h4
-rw-r--r--intern/cycles/kernel/svm/noise.h268
-rw-r--r--intern/cycles/kernel/types.h50
-rw-r--r--intern/cycles/scene/CMakeLists.txt2
-rw-r--r--intern/cycles/scene/bake.cpp11
-rw-r--r--intern/cycles/scene/bake.h3
-rw-r--r--intern/cycles/scene/camera.cpp1
-rw-r--r--intern/cycles/scene/film.cpp13
-rw-r--r--intern/cycles/scene/image_oiio.cpp18
-rw-r--r--intern/cycles/scene/integrator.cpp46
-rw-r--r--intern/cycles/scene/integrator.h13
-rw-r--r--intern/cycles/scene/osl.cpp282
-rw-r--r--intern/cycles/scene/osl.h18
-rw-r--r--intern/cycles/scene/pass.cpp15
-rw-r--r--intern/cycles/scene/scene.cpp15
-rw-r--r--intern/cycles/scene/scene.h2
-rw-r--r--intern/cycles/scene/shader.cpp13
-rw-r--r--intern/cycles/scene/shader.h2
-rw-r--r--intern/cycles/scene/shader_nodes.h4
-rw-r--r--intern/cycles/session/merge.h2
-rw-r--r--intern/cycles/session/session.cpp11
-rw-r--r--intern/cycles/session/tile.cpp5
-rw-r--r--intern/cycles/test/CMakeLists.txt18
-rw-r--r--intern/cycles/test/util_avxf_test.h211
-rw-r--r--intern/cycles/test/util_float8_avx2_test.cpp (renamed from intern/cycles/test/util_avxf_avx2_test.cpp)4
-rw-r--r--intern/cycles/test/util_float8_avx_test.cpp (renamed from intern/cycles/test/util_avxf_avx_test.cpp)3
-rw-r--r--intern/cycles/test/util_float8_sse2_test.cpp12
-rw-r--r--intern/cycles/test/util_float8_test.h103
-rw-r--r--intern/cycles/test/util_md5_test.cpp16
-rw-r--r--intern/cycles/util/CMakeLists.txt10
-rw-r--r--intern/cycles/util/avxb.h230
-rw-r--r--intern/cycles/util/avxf.h379
-rw-r--r--intern/cycles/util/avxi.h732
-rw-r--r--intern/cycles/util/color.h48
-rw-r--r--intern/cycles/util/defines.h1
-rw-r--r--intern/cycles/util/guiding.h41
-rw-r--r--intern/cycles/util/half.h16
-rw-r--r--intern/cycles/util/hash.h52
-rw-r--r--intern/cycles/util/math.h14
-rw-r--r--intern/cycles/util/math_fast.h2
-rw-r--r--intern/cycles/util/math_float2.h133
-rw-r--r--intern/cycles/util/math_float3.h230
-rw-r--r--intern/cycles/util/math_float4.h475
-rw-r--r--intern/cycles/util/math_float8.h483
-rw-r--r--intern/cycles/util/math_int2.h17
-rw-r--r--intern/cycles/util/math_int3.h29
-rw-r--r--intern/cycles/util/math_int4.h216
-rw-r--r--intern/cycles/util/math_int8.h355
-rw-r--r--intern/cycles/util/math_intersect.h11
-rw-r--r--intern/cycles/util/md5.cpp9
-rw-r--r--intern/cycles/util/sseb.h345
-rw-r--r--intern/cycles/util/ssef.h1091
-rw-r--r--intern/cycles/util/ssei.h633
-rw-r--r--intern/cycles/util/transform.cpp2
-rw-r--r--intern/cycles/util/transform.h49
-rw-r--r--intern/cycles/util/transform_inverse.h31
-rw-r--r--intern/cycles/util/types.h14
-rw-r--r--intern/cycles/util/types_float3.h5
-rw-r--r--intern/cycles/util/types_float8.h29
-rw-r--r--intern/cycles/util/types_float8_impl.h63
-rw-r--r--intern/cycles/util/types_int8.h51
-rw-r--r--intern/cycles/util/types_int8_impl.h95
-rw-r--r--intern/cycles/util/version.h4
-rw-r--r--intern/ffmpeg/CMakeLists.txt1
-rw-r--r--intern/ffmpeg/ffmpeg_compat.h8
-rw-r--r--intern/ffmpeg/tests/ffmpeg_codecs.cc13
-rw-r--r--intern/ghost/CMakeLists.txt51
-rw-r--r--intern/ghost/GHOST_C-api.h13
-rw-r--r--intern/ghost/GHOST_ISystem.h25
-rw-r--r--intern/ghost/GHOST_Path-api.h8
-rw-r--r--intern/ghost/GHOST_Types.h36
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp24
-rw-r--r--intern/ghost/intern/GHOST_Context.cpp11
-rw-r--r--intern/ghost/intern/GHOST_Context.h8
-rw-r--r--intern/ghost/intern/GHOST_ContextCGL.h80
-rw-r--r--intern/ghost/intern/GHOST_ContextCGL.mm809
-rw-r--r--intern/ghost/intern/GHOST_ContextEGL.cpp4
-rw-r--r--intern/ghost/intern/GHOST_ContextGLX.cpp10
-rw-r--r--intern/ghost/intern/GHOST_ContextWGL.cpp2
-rw-r--r--intern/ghost/intern/GHOST_Debug.h34
-rw-r--r--intern/ghost/intern/GHOST_DisplayManager.cpp6
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerSDL.cpp2
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerX11.cpp4
-rw-r--r--intern/ghost/intern/GHOST_DropTargetWin32.cpp6
-rw-r--r--intern/ghost/intern/GHOST_DropTargetX11.cpp16
-rw-r--r--intern/ghost/intern/GHOST_EventManager.cpp2
-rw-r--r--intern/ghost/intern/GHOST_EventPrinter.cpp9
-rw-r--r--intern/ghost/intern/GHOST_ISystem.cpp72
-rw-r--r--intern/ghost/intern/GHOST_ImeWin32.cpp2
-rw-r--r--intern/ghost/intern/GHOST_ImeWin32.h2
-rw-r--r--intern/ghost/intern/GHOST_ModifierKeys.cpp31
-rw-r--r--intern/ghost/intern/GHOST_ModifierKeys.h17
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.cpp574
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.h56
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerUnix.cpp22
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerUnix.h2
-rw-r--r--intern/ghost/intern/GHOST_PathUtils.cpp10
-rw-r--r--intern/ghost/intern/GHOST_System.cpp10
-rw-r--r--intern/ghost/intern/GHOST_System.h17
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.h4
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm16
-rw-r--r--intern/ghost/intern/GHOST_SystemHeadless.h3
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsUnix.cpp9
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.cpp12
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.h1
-rw-r--r--intern/ghost/intern/GHOST_SystemWayland.cpp3739
-rw-r--r--intern/ghost/intern/GHOST_SystemWayland.h49
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp54
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h4
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp114
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.h6
-rw-r--r--intern/ghost/intern/GHOST_TimerManager.cpp2
-rw-r--r--intern/ghost/intern/GHOST_Window.cpp7
-rw-r--r--intern/ghost/intern/GHOST_Window.h78
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.mm6
-rw-r--r--intern/ghost/intern/GHOST_WindowManager.h4
-rw-r--r--intern/ghost/intern/GHOST_WindowSDL.cpp86
-rw-r--r--intern/ghost/intern/GHOST_WindowViewCocoa.h2
-rw-r--r--intern/ghost/intern/GHOST_WindowWayland.cpp549
-rw-r--r--intern/ghost/intern/GHOST_WindowWayland.h10
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp2
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp83
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.h4
-rw-r--r--intern/ghost/intern/GHOST_Wintab.cpp20
-rw-r--r--intern/ghost/intern/GHOST_XrAction.cpp2
-rw-r--r--intern/ghost/intern/GHOST_XrControllerModel.cpp38
-rw-r--r--intern/ghost/intern/GHOST_XrGraphicsBinding.cpp4
-rw-r--r--intern/ghost/intern/GHOST_XrSession.cpp8
-rw-r--r--intern/ghost/intern/GHOST_utildefines.h29
-rw-r--r--intern/ghost/test/gears/GHOST_C-Test.c2
-rw-r--r--intern/ghost/test/gears/GHOST_Test.cpp23
-rw-r--r--intern/ghost/test/multitest/MultiTest.c6
-rw-r--r--intern/guardedalloc/CMakeLists.txt1
-rw-r--r--intern/guardedalloc/MEM_guardedalloc.h2
-rw-r--r--intern/guardedalloc/intern/leak_detector.cc4
-rw-r--r--intern/guardedalloc/intern/mallocn.c2
-rw-r--r--intern/guardedalloc/intern/mallocn_guarded_impl.c18
-rw-r--r--intern/guardedalloc/intern/mallocn_lockfree_impl.c10
-rw-r--r--intern/guardedalloc/tests/guardedalloc_alignment_test.cc2
-rw-r--r--intern/libmv/libmv/simple_pipeline/keyframe_selection.cc2
-rw-r--r--intern/libmv/libmv/simple_pipeline/pipeline.cc12
-rw-r--r--intern/mantaflow/intern/MANTA_main.cpp42
-rw-r--r--intern/mikktspace/mikk_util.hh4
-rw-r--r--intern/mikktspace/mikktspace.hh51
-rw-r--r--intern/opencolorio/gpu_shader_display_transform_frag.glsl2
-rw-r--r--intern/opensubdiv/CMakeLists.txt7
-rw-r--r--intern/sky/source/sky_model.cpp23
-rw-r--r--intern/sky/source/sky_nishita.cpp2
-rw-r--r--intern/wayland_dynload/extern/wayland_dynload_client.h1
-rw-r--r--intern/wayland_dynload/intern/wayland_dynload_client.c5
-rw-r--r--intern/wayland_dynload/intern/wayland_dynload_cursor.c2
-rw-r--r--intern/wayland_dynload/intern/wayland_dynload_egl.c4
-rw-r--r--intern/wayland_dynload/intern/wayland_dynload_libdecor.c2
-rw-r--r--intern/wayland_dynload/intern/wayland_dynload_utils.c9
-rw-r--r--intern/wayland_dynload/intern/wayland_dynload_utils.h3
-rw-r--r--make.bat12
-rw-r--r--release/datafiles/blender_icons.svg30
-rw-r--r--release/datafiles/blender_icons16/icon16_mod_envelope.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_mod_outline.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_mod_envelope.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_mod_outline.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons_geom.py8
-rwxr-xr-xrelease/datafiles/ctodata.py2
-rw-r--r--release/datafiles/fonts/Noto Sans CJK Regular.woff2bin11672912 -> 11425316 bytes
m---------release/datafiles/locale0
m---------release/scripts/addons0
m---------release/scripts/addons_contrib0
-rw-r--r--release/scripts/freestyle/modules/freestyle/functions.py2
-rw-r--r--release/scripts/modules/bl_app_override/__init__.py8
-rw-r--r--release/scripts/modules/bl_app_override/helpers.py4
-rw-r--r--release/scripts/modules/bl_console_utils/autocomplete/complete_calltip.py18
-rw-r--r--release/scripts/modules/bl_console_utils/autocomplete/complete_import.py8
-rw-r--r--release/scripts/modules/bl_console_utils/autocomplete/complete_namespace.py22
-rw-r--r--release/scripts/modules/bl_console_utils/autocomplete/intellisense.py16
-rw-r--r--release/scripts/modules/bl_i18n_utils/bl_extract_messages.py19
-rw-r--r--release/scripts/modules/bl_i18n_utils/settings.py12
-rw-r--r--release/scripts/modules/bl_i18n_utils/utils.py2
-rw-r--r--release/scripts/modules/bl_i18n_utils/utils_spell_check.py8
-rw-r--r--release/scripts/modules/bl_keymap_utils/io.py2
-rw-r--r--release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py4
-rw-r--r--release/scripts/modules/bpy/utils/__init__.py94
-rw-r--r--release/scripts/modules/bpy_extras/io_utils.py2
-rw-r--r--release/scripts/modules/bpy_extras/node_shader_utils.py2
-rw-r--r--release/scripts/modules/bpy_extras/object_utils.py13
-rw-r--r--release/scripts/modules/bpy_extras/wm_utils/progress_report.py4
-rw-r--r--release/scripts/modules/bpy_types.py1
-rw-r--r--release/scripts/modules/console_python.py2
-rw-r--r--release/scripts/modules/gpu_extras/batch.py4
-rw-r--r--release/scripts/modules/gpu_extras/presets.py1
-rw-r--r--release/scripts/modules/rna_info.py6
-rw-r--r--release/scripts/modules/rna_manual_reference.py96
-rw-r--r--release/scripts/modules/rna_prop_ui.py4
-rw-r--r--release/scripts/modules/sys_info.py17
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/blender_default.py11
-rw-r--r--release/scripts/startup/bl_operators/assets.py5
-rw-r--r--release/scripts/startup/bl_operators/node.py73
-rw-r--r--release/scripts/startup/bl_operators/spreadsheet.py1
-rw-r--r--release/scripts/startup/bl_operators/userpref.py11
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_follow_active.py2
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_lightmap.py2
-rw-r--r--release/scripts/startup/bl_operators/wm.py44
-rw-r--r--release/scripts/startup/bl_ui/__init__.py2
-rw-r--r--release/scripts/startup/bl_ui/node_add_menu.py76
-rw-r--r--release/scripts/startup/bl_ui/node_add_menu_geometry.py470
-rw-r--r--release/scripts/startup/bl_ui/properties_data_curves.py8
-rw-r--r--release/scripts/startup/bl_ui/properties_data_mesh.py19
-rw-r--r--release/scripts/startup/bl_ui/properties_grease_pencil_common.py5
-rw-r--r--release/scripts/startup/bl_ui/properties_output.py21
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py63
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py3
-rw-r--r--release/scripts/startup/bl_ui/space_clip.py6
-rw-r--r--release/scripts/startup/bl_ui/space_dopesheet.py1
-rw-r--r--release/scripts/startup/bl_ui/space_image.py38
-rw-r--r--release/scripts/startup/bl_ui/space_nla.py6
-rw-r--r--release/scripts/startup/bl_ui/space_node.py9
-rw-r--r--release/scripts/startup/bl_ui/space_outliner.py2
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py2
-rw-r--r--release/scripts/startup/bl_ui/space_spreadsheet.py75
-rw-r--r--release/scripts/startup/bl_ui/space_time.py4
-rw-r--r--release/scripts/startup/bl_ui/space_toolsystem_common.py2
-rw-r--r--release/scripts/startup/bl_ui/space_topbar.py18
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py34
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py181
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py88
-rw-r--r--release/scripts/startup/nodeitems_builtins.py308
-rw-r--r--release/scripts/templates_py/custom_nodes.py2
-rw-r--r--release/scripts/templates_py/operator_modal_draw.py1
-rw-r--r--source/blender/CMakeLists.txt1
-rw-r--r--source/blender/blendthumb/src/blender_thumbnailer.cc2
-rw-r--r--source/blender/blendthumb/src/blendthumb_extract.cc5
-rw-r--r--source/blender/blendthumb/src/blendthumb_png.cc6
-rw-r--r--source/blender/blendthumb/src/blendthumb_win32.cc12
-rw-r--r--source/blender/blenfont/BLF_api.h42
-rw-r--r--source/blender/blenfont/intern/blf.c77
-rw-r--r--source/blender/blenfont/intern/blf_default.c10
-rw-r--r--source/blender/blenfont/intern/blf_dir.c2
-rw-r--r--source/blender/blenfont/intern/blf_font.c389
-rw-r--r--source/blender/blenfont/intern/blf_font_default.c2
-rw-r--r--source/blender/blenfont/intern/blf_font_win32_compat.c5
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c11
-rw-r--r--source/blender/blenfont/intern/blf_internal.h30
-rw-r--r--source/blender/blenfont/intern/blf_internal_types.h6
-rw-r--r--source/blender/blenfont/intern/blf_thumbs.c423
-rw-r--r--source/blender/blenfont/intern/blf_util.c6
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h3
-rw-r--r--source/blender/blenkernel/BKE_appdir.h5
-rw-r--r--source/blender/blenkernel/BKE_armature.h4
-rw-r--r--source/blender/blenkernel/BKE_asset.h19
-rw-r--r--source/blender/blenkernel/BKE_asset_catalog.hh11
-rw-r--r--source/blender/blenkernel/BKE_asset_catalog_path.hh2
-rw-r--r--source/blender/blenkernel/BKE_asset_library.h40
-rw-r--r--source/blender/blenkernel/BKE_asset_library.hh91
-rw-r--r--source/blender/blenkernel/BKE_asset_representation.hh64
-rw-r--r--source/blender/blenkernel/BKE_attribute.hh64
-rw-r--r--source/blender/blenkernel/BKE_attribute_math.hh132
-rw-r--r--source/blender/blenkernel/BKE_blender.h16
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h6
-rw-r--r--source/blender/blenkernel/BKE_bpath.h36
-rw-r--r--source/blender/blenkernel/BKE_brush.h21
-rw-r--r--source/blender/blenkernel/BKE_bvhutils.h10
-rw-r--r--source/blender/blenkernel/BKE_cloth.h2
-rw-r--r--source/blender/blenkernel/BKE_collection.h6
-rw-r--r--source/blender/blenkernel/BKE_collision.h3
-rw-r--r--source/blender/blenkernel/BKE_context.h46
-rw-r--r--source/blender/blenkernel/BKE_cryptomatte.hh4
-rw-r--r--source/blender/blenkernel/BKE_curves.h2
-rw-r--r--source/blender/blenkernel/BKE_curves.hh95
-rw-r--r--source/blender/blenkernel/BKE_curves_utils.hh505
-rw-r--r--source/blender/blenkernel/BKE_customdata.h53
-rw-r--r--source/blender/blenkernel/BKE_duplilist.h44
-rw-r--r--source/blender/blenkernel/BKE_dynamicpaint.h2
-rw-r--r--source/blender/blenkernel/BKE_editmesh.h2
-rw-r--r--source/blender/blenkernel/BKE_editmesh_cache.h20
-rw-r--r--source/blender/blenkernel/BKE_effect.h1
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h7
-rw-r--r--source/blender/blenkernel/BKE_geometry_fields.hh31
-rw-r--r--source/blender/blenkernel/BKE_geometry_set.hh300
-rw-r--r--source/blender/blenkernel/BKE_global.h21
-rw-r--r--source/blender/blenkernel/BKE_gpencil_geom.h6
-rw-r--r--source/blender/blenkernel/BKE_icons.h4
-rw-r--r--source/blender/blenkernel/BKE_idprop.h2
-rw-r--r--source/blender/blenkernel/BKE_idprop.hh8
-rw-r--r--source/blender/blenkernel/BKE_image_format.h2
-rw-r--r--source/blender/blenkernel/BKE_image_partial_update.hh4
-rw-r--r--source/blender/blenkernel/BKE_instances.hh270
-rw-r--r--source/blender/blenkernel/BKE_key.h6
-rw-r--r--source/blender/blenkernel/BKE_layer.h96
-rw-r--r--source/blender/blenkernel/BKE_lib_id.h32
-rw-r--r--source/blender/blenkernel/BKE_lib_override.h2
-rw-r--r--source/blender/blenkernel/BKE_lib_remap.h8
-rw-r--r--source/blender/blenkernel/BKE_main.h30
-rw-r--r--source/blender/blenkernel/BKE_mball.h4
-rw-r--r--source/blender/blenkernel/BKE_mesh.h32
-rw-r--r--source/blender/blenkernel/BKE_mesh_legacy_convert.h47
-rw-r--r--source/blender/blenkernel/BKE_mesh_mapping.h28
-rw-r--r--source/blender/blenkernel/BKE_mesh_runtime.h19
-rw-r--r--source/blender/blenkernel/BKE_mesh_types.h146
-rw-r--r--source/blender/blenkernel/BKE_modifier.h6
-rw-r--r--source/blender/blenkernel/BKE_multires.h5
-rw-r--r--source/blender/blenkernel/BKE_nla.h20
-rw-r--r--source/blender/blenkernel/BKE_node.h54
-rw-r--r--source/blender/blenkernel/BKE_node_runtime.hh20
-rw-r--r--source/blender/blenkernel/BKE_object.h38
-rw-r--r--source/blender/blenkernel/BKE_paint.h232
-rw-r--r--source/blender/blenkernel/BKE_particle.h8
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h46
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h3
-rw-r--r--source/blender/blenkernel/BKE_pointcloud.h5
-rw-r--r--source/blender/blenkernel/BKE_scene.h2
-rw-r--r--source/blender/blenkernel/BKE_screen.h20
-rw-r--r--source/blender/blenkernel/BKE_sound.h2
-rw-r--r--source/blender/blenkernel/BKE_spline.hh688
-rw-r--r--source/blender/blenkernel/BKE_subdiv.h1
-rw-r--r--source/blender/blenkernel/BKE_subdiv_ccg.h1
-rw-r--r--source/blender/blenkernel/BKE_subsurf.h4
-rw-r--r--source/blender/blenkernel/BKE_tracking.h4
-rw-r--r--source/blender/blenkernel/BKE_undo_system.h2
-rw-r--r--source/blender/blenkernel/BKE_viewer_path.h58
-rw-r--r--source/blender/blenkernel/BKE_writeffmpeg.h2
-rw-r--r--source/blender/blenkernel/CMakeLists.txt35
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.h8
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.cc72
-rw-r--r--source/blender/blenkernel/intern/action.c4
-rw-r--r--source/blender/blenkernel/intern/anim_data.c14
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c2
-rw-r--r--source/blender/blenkernel/intern/appdir.c101
-rw-r--r--source/blender/blenkernel/intern/armature.c14
-rw-r--r--source/blender/blenkernel/intern/armature_deform.c24
-rw-r--r--source/blender/blenkernel/intern/armature_update.c8
-rw-r--r--source/blender/blenkernel/intern/asset.cc30
-rw-r--r--source/blender/blenkernel/intern/asset_catalog.cc56
-rw-r--r--source/blender/blenkernel/intern/asset_catalog_path.cc2
-rw-r--r--source/blender/blenkernel/intern/asset_catalog_test.cc76
-rw-r--r--source/blender/blenkernel/intern/asset_library.cc120
-rw-r--r--source/blender/blenkernel/intern/asset_library_service.cc47
-rw-r--r--source/blender/blenkernel/intern/asset_library_service.hh11
-rw-r--r--source/blender/blenkernel/intern/asset_library_service_test.cc32
-rw-r--r--source/blender/blenkernel/intern/asset_representation.cc98
-rw-r--r--source/blender/blenkernel/intern/asset_test.cc2
-rw-r--r--source/blender/blenkernel/intern/attribute.cc16
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc68
-rw-r--r--source/blender/blenkernel/intern/attribute_access_intern.hh42
-rw-r--r--source/blender/blenkernel/intern/blender.c30
-rw-r--r--source/blender/blenkernel/intern/blender_copybuffer.c2
-rw-r--r--source/blender/blenkernel/intern/blender_undo.c2
-rw-r--r--source/blender/blenkernel/intern/blender_user_menu.c2
-rw-r--r--source/blender/blenkernel/intern/blendfile.c67
-rw-r--r--source/blender/blenkernel/intern/blendfile_link_append.c29
-rw-r--r--source/blender/blenkernel/intern/boids.c2
-rw-r--r--source/blender/blenkernel/intern/bpath.c4
-rw-r--r--source/blender/blenkernel/intern/brush.cc44
-rw-r--r--source/blender/blenkernel/intern/bvhutils.cc18
-rw-r--r--source/blender/blenkernel/intern/camera.c34
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c9
-rw-r--r--source/blender/blenkernel/intern/cloth.c56
-rw-r--r--source/blender/blenkernel/intern/collection.c35
-rw-r--r--source/blender/blenkernel/intern/collision.c18
-rw-r--r--source/blender/blenkernel/intern/colortools.c62
-rw-r--r--source/blender/blenkernel/intern/constraint.c102
-rw-r--r--source/blender/blenkernel/intern/context.c68
-rw-r--r--source/blender/blenkernel/intern/crazyspace.cc37
-rw-r--r--source/blender/blenkernel/intern/cryptomatte.cc8
-rw-r--r--source/blender/blenkernel/intern/cryptomatte_test.cc4
-rw-r--r--source/blender/blenkernel/intern/curve.cc73
-rw-r--r--source/blender/blenkernel/intern/curve_bezier.cc2
-rw-r--r--source/blender/blenkernel/intern/curve_catmull_rom.cc26
-rw-r--r--source/blender/blenkernel/intern/curve_deform.c6
-rw-r--r--source/blender/blenkernel/intern/curve_eval.cc587
-rw-r--r--source/blender/blenkernel/intern/curve_to_mesh_convert.cc14
-rw-r--r--source/blender/blenkernel/intern/curveprofile.cc24
-rw-r--r--source/blender/blenkernel/intern/curves.cc13
-rw-r--r--source/blender/blenkernel/intern/curves_geometry.cc154
-rw-r--r--source/blender/blenkernel/intern/curves_utils.cc15
-rw-r--r--source/blender/blenkernel/intern/customdata.cc382
-rw-r--r--source/blender/blenkernel/intern/customdata_file.c4
-rw-r--r--source/blender/blenkernel/intern/data_transfer.c64
-rw-r--r--source/blender/blenkernel/intern/deform.c10
-rw-r--r--source/blender/blenkernel/intern/displist.cc28
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c66
-rw-r--r--source/blender/blenkernel/intern/editmesh.cc (renamed from source/blender/blenkernel/intern/editmesh.c)120
-rw-r--r--source/blender/blenkernel/intern/editmesh_bvh.c4
-rw-r--r--source/blender/blenkernel/intern/editmesh_tangent.cc34
-rw-r--r--source/blender/blenkernel/intern/effect.c27
-rw-r--r--source/blender/blenkernel/intern/fcurve.c20
-rw-r--r--source/blender/blenkernel/intern/fcurve_driver.c16
-rw-r--r--source/blender/blenkernel/intern/fluid.c189
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c2
-rw-r--r--source/blender/blenkernel/intern/freestyle.c2
-rw-r--r--source/blender/blenkernel/intern/geometry_component_curve.cc1464
-rw-r--r--source/blender/blenkernel/intern/geometry_component_curves.cc65
-rw-r--r--source/blender/blenkernel/intern/geometry_component_instances.cc395
-rw-r--r--source/blender/blenkernel/intern/geometry_component_mesh.cc216
-rw-r--r--source/blender/blenkernel/intern/geometry_component_pointcloud.cc4
-rw-r--r--source/blender/blenkernel/intern/geometry_fields.cc192
-rw-r--r--source/blender/blenkernel/intern/geometry_set.cc63
-rw-r--r--source/blender/blenkernel/intern/geometry_set_instances.cc48
-rw-r--r--source/blender/blenkernel/intern/gpencil.c69
-rw-r--r--source/blender/blenkernel/intern/gpencil_curve.c10
-rw-r--r--source/blender/blenkernel/intern/gpencil_geom.cc89
-rw-r--r--source/blender/blenkernel/intern/gpencil_modifier.c29
-rw-r--r--source/blender/blenkernel/intern/icons.cc14
-rw-r--r--source/blender/blenkernel/intern/icons_rasterize.c4
-rw-r--r--source/blender/blenkernel/intern/idprop.c4
-rw-r--r--source/blender/blenkernel/intern/idprop_create.cc2
-rw-r--r--source/blender/blenkernel/intern/idprop_serialize.cc4
-rw-r--r--source/blender/blenkernel/intern/image.cc126
-rw-r--r--source/blender/blenkernel/intern/image_format.cc11
-rw-r--r--source/blender/blenkernel/intern/image_gen.c48
-rw-r--r--source/blender/blenkernel/intern/image_gpu.cc10
-rw-r--r--source/blender/blenkernel/intern/image_save.cc22
-rw-r--r--source/blender/blenkernel/intern/instances.cc337
-rw-r--r--source/blender/blenkernel/intern/ipo.c12
-rw-r--r--source/blender/blenkernel/intern/kelvinlet.c4
-rw-r--r--source/blender/blenkernel/intern/lattice.c8
-rw-r--r--source/blender/blenkernel/intern/lattice_deform.c6
-rw-r--r--source/blender/blenkernel/intern/layer.c156
-rw-r--r--source/blender/blenkernel/intern/layer_utils.c69
-rw-r--r--source/blender/blenkernel/intern/lib_id.c10
-rw-r--r--source/blender/blenkernel/intern/lib_id_delete.c86
-rw-r--r--source/blender/blenkernel/intern/lib_id_remapper.cc2
-rw-r--r--source/blender/blenkernel/intern/lib_override.cc52
-rw-r--r--source/blender/blenkernel/intern/lib_remap.c4
-rw-r--r--source/blender/blenkernel/intern/main.c3
-rw-r--r--source/blender/blenkernel/intern/main_idmap.c4
-rw-r--r--source/blender/blenkernel/intern/main_namemap.cc4
-rw-r--r--source/blender/blenkernel/intern/mask.c4
-rw-r--r--source/blender/blenkernel/intern/mask_evaluate.c62
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c195
-rw-r--r--source/blender/blenkernel/intern/material.c120
-rw-r--r--source/blender/blenkernel/intern/mball.cc13
-rw-r--r--source/blender/blenkernel/intern/mball_tessellate.cc (renamed from source/blender/blenkernel/intern/mball_tessellate.c)288
-rw-r--r--source/blender/blenkernel/intern/mesh.cc121
-rw-r--r--source/blender/blenkernel/intern/mesh_boolean_convert.cc21
-rw-r--r--source/blender/blenkernel/intern/mesh_calc_edges.cc32
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.cc67
-rw-r--r--source/blender/blenkernel/intern/mesh_debug.cc17
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.cc151
-rw-r--r--source/blender/blenkernel/intern/mesh_fair.cc14
-rw-r--r--source/blender/blenkernel/intern/mesh_iterators.cc (renamed from source/blender/blenkernel/intern/mesh_iterators.c)103
-rw-r--r--source/blender/blenkernel/intern/mesh_legacy_convert.cc637
-rw-r--r--source/blender/blenkernel/intern/mesh_mapping.cc (renamed from source/blender/blenkernel/intern/mesh_mapping.c)252
-rw-r--r--source/blender/blenkernel/intern/mesh_merge_customdata.cc2
-rw-r--r--source/blender/blenkernel/intern/mesh_mirror.c10
-rw-r--r--source/blender/blenkernel/intern/mesh_normals.cc155
-rw-r--r--source/blender/blenkernel/intern/mesh_remap.c6
-rw-r--r--source/blender/blenkernel/intern/mesh_remesh_voxel.cc214
-rw-r--r--source/blender/blenkernel/intern/mesh_runtime.cc200
-rw-r--r--source/blender/blenkernel/intern/mesh_sample.cc21
-rw-r--r--source/blender/blenkernel/intern/mesh_tangent.cc104
-rw-r--r--source/blender/blenkernel/intern/mesh_tessellate.cc26
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.cc214
-rw-r--r--source/blender/blenkernel/intern/mesh_wrapper.cc74
-rw-r--r--source/blender/blenkernel/intern/modifier.cc (renamed from source/blender/blenkernel/intern/modifier.c)281
-rw-r--r--source/blender/blenkernel/intern/movieclip.c12
-rw-r--r--source/blender/blenkernel/intern/multires.cc (renamed from source/blender/blenkernel/intern/multires.c)279
-rw-r--r--source/blender/blenkernel/intern/multires_reshape.h2
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_smooth.c16
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_util.c3
-rw-r--r--source/blender/blenkernel/intern/nla.c41
-rw-r--r--source/blender/blenkernel/intern/node.cc241
-rw-r--r--source/blender/blenkernel/intern/node_runtime.cc48
-rw-r--r--source/blender/blenkernel/intern/node_tree_update.cc127
-rw-r--r--source/blender/blenkernel/intern/object.cc338
-rw-r--r--source/blender/blenkernel/intern/object_deform.c12
-rw-r--r--source/blender/blenkernel/intern/object_dupli.cc458
-rw-r--r--source/blender/blenkernel/intern/object_update.cc (renamed from source/blender/blenkernel/intern/object_update.c)69
-rw-r--r--source/blender/blenkernel/intern/ocean.c31
-rw-r--r--source/blender/blenkernel/intern/outliner_treehash.cc7
-rw-r--r--source/blender/blenkernel/intern/packedFile.c2
-rw-r--r--source/blender/blenkernel/intern/paint.cc883
-rw-r--r--source/blender/blenkernel/intern/particle.c107
-rw-r--r--source/blender/blenkernel/intern/particle_child.c4
-rw-r--r--source/blender/blenkernel/intern/particle_distribute.c9
-rw-r--r--source/blender/blenkernel/intern/particle_system.c76
-rw-r--r--source/blender/blenkernel/intern/pbvh.c539
-rw-r--r--source/blender/blenkernel/intern/pbvh.cc8
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c129
-rw-r--r--source/blender/blenkernel/intern/pbvh_intern.h7
-rw-r--r--source/blender/blenkernel/intern/pbvh_pixels.cc2
-rw-r--r--source/blender/blenkernel/intern/pointcache.c191
-rw-r--r--source/blender/blenkernel/intern/pointcloud.cc41
-rw-r--r--source/blender/blenkernel/intern/preferences.c3
-rw-r--r--source/blender/blenkernel/intern/report.c16
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c38
-rw-r--r--source/blender/blenkernel/intern/scene.cc195
-rw-r--r--source/blender/blenkernel/intern/screen.c612
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.cc (renamed from source/blender/blenkernel/intern/shrinkwrap.c)234
-rw-r--r--source/blender/blenkernel/intern/simulation.cc6
-rw-r--r--source/blender/blenkernel/intern/softbody.c35
-rw-r--r--source/blender/blenkernel/intern/sound.c30
-rw-r--r--source/blender/blenkernel/intern/spline_base.cc526
-rw-r--r--source/blender/blenkernel/intern/spline_bezier.cc646
-rw-r--r--source/blender/blenkernel/intern/spline_nurbs.cc395
-rw-r--r--source/blender/blenkernel/intern/spline_poly.cc97
-rw-r--r--source/blender/blenkernel/intern/studiolight.c10
-rw-r--r--source/blender/blenkernel/intern/subdiv_ccg.cc (renamed from source/blender/blenkernel/intern/subdiv_ccg.c)314
-rw-r--r--source/blender/blenkernel/intern/subdiv_converter_mesh.c9
-rw-r--r--source/blender/blenkernel/intern/subdiv_mesh.cc86
-rw-r--r--source/blender/blenkernel/intern/subdiv_modifier.cc (renamed from source/blender/blenkernel/intern/subdiv_modifier.c)17
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c23
-rw-r--r--source/blender/blenkernel/intern/text.c58
-rw-r--r--source/blender/blenkernel/intern/tracking.c20
-rw-r--r--source/blender/blenkernel/intern/tracking_detect.c2
-rw-r--r--source/blender/blenkernel/intern/tracking_region_tracker.c6
-rw-r--r--source/blender/blenkernel/intern/tracking_solver.c8
-rw-r--r--source/blender/blenkernel/intern/tracking_util.c2
-rw-r--r--source/blender/blenkernel/intern/type_conversions.cc32
-rw-r--r--source/blender/blenkernel/intern/undo_system.c4
-rw-r--r--source/blender/blenkernel/intern/unit.c2
-rw-r--r--source/blender/blenkernel/intern/vfont.c18
-rw-r--r--source/blender/blenkernel/intern/vfontdata_freetype.c146
-rw-r--r--source/blender/blenkernel/intern/viewer_path.cc270
-rw-r--r--source/blender/blenkernel/intern/volume.cc17
-rw-r--r--source/blender/blenkernel/intern/volume_render.cc5
-rw-r--r--source/blender/blenkernel/intern/workspace.cc (renamed from source/blender/blenkernel/intern/workspace.c)162
-rw-r--r--source/blender/blenkernel/intern/writeavi.c7
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c290
-rw-r--r--source/blender/blenlib/BLI_allocator.hh11
-rw-r--r--source/blender/blenlib/BLI_any.hh9
-rw-r--r--source/blender/blenlib/BLI_array.hh3
-rw-r--r--source/blender/blenlib/BLI_array_utils.hh115
-rw-r--r--source/blender/blenlib/BLI_assert.h2
-rw-r--r--source/blender/blenlib/BLI_bit_vector.hh8
-rw-r--r--source/blender/blenlib/BLI_cache_mutex.hh106
-rw-r--r--source/blender/blenlib/BLI_color_mix.hh2
-rw-r--r--source/blender/blenlib/BLI_compiler_attrs.h8
-rw-r--r--source/blender/blenlib/BLI_compute_context.hh2
-rw-r--r--source/blender/blenlib/BLI_convexhull_2d.h37
-rw-r--r--source/blender/blenlib/BLI_cpp_type.hh2
-rw-r--r--source/blender/blenlib/BLI_cpp_type_make.hh8
-rw-r--r--source/blender/blenlib/BLI_dot_export.hh2
-rw-r--r--source/blender/blenlib/BLI_endian_switch_inline.h2
-rw-r--r--source/blender/blenlib/BLI_fileops.h1
-rw-r--r--source/blender/blenlib/BLI_function_ref.hh2
-rw-r--r--source/blender/blenlib/BLI_generic_array.hh6
-rw-r--r--source/blender/blenlib/BLI_generic_virtual_array.hh34
-rw-r--r--source/blender/blenlib/BLI_generic_virtual_vector_array.hh4
-rw-r--r--source/blender/blenlib/BLI_hash.hh10
-rw-r--r--source/blender/blenlib/BLI_hash_tables.hh18
-rw-r--r--source/blender/blenlib/BLI_index_range.hh17
-rw-r--r--source/blender/blenlib/BLI_lazy_threading.hh94
-rw-r--r--source/blender/blenlib/BLI_linear_allocator.hh8
-rw-r--r--source/blender/blenlib/BLI_listbase.h15
-rw-r--r--source/blender/blenlib/BLI_listbase_wrapper.hh2
-rw-r--r--source/blender/blenlib/BLI_map.hh29
-rw-r--r--source/blender/blenlib/BLI_map_slots.hh8
-rw-r--r--source/blender/blenlib/BLI_math_inline.h4
-rw-r--r--source/blender/blenlib/BLI_math_matrix.h4
-rw-r--r--source/blender/blenlib/BLI_math_vec_types.hh243
-rw-r--r--source/blender/blenlib/BLI_math_vector.hh8
-rw-r--r--source/blender/blenlib/BLI_memory_utils.hh4
-rw-r--r--source/blender/blenlib/BLI_mesh_intersect.hh12
-rw-r--r--source/blender/blenlib/BLI_path_util.h138
-rw-r--r--source/blender/blenlib/BLI_probing_strategies.hh2
-rw-r--r--source/blender/blenlib/BLI_rand.hh8
-rw-r--r--source/blender/blenlib/BLI_resource_scope.hh2
-rw-r--r--source/blender/blenlib/BLI_set.hh24
-rw-r--r--source/blender/blenlib/BLI_set_slots.hh10
-rw-r--r--source/blender/blenlib/BLI_span.hh8
-rw-r--r--source/blender/blenlib/BLI_strict_flags.h10
-rw-r--r--source/blender/blenlib/BLI_string.h30
-rw-r--r--source/blender/blenlib/BLI_string_cursor_utf8.h3
-rw-r--r--source/blender/blenlib/BLI_string_ref.hh56
-rw-r--r--source/blender/blenlib/BLI_string_utils.h393
-rw-r--r--source/blender/blenlib/BLI_task.hh5
-rw-r--r--source/blender/blenlib/BLI_utildefines.h13
-rw-r--r--source/blender/blenlib/BLI_uvproject.h2
-rw-r--r--source/blender/blenlib/BLI_vector.hh24
-rw-r--r--source/blender/blenlib/BLI_vector_adaptor.hh88
-rw-r--r--source/blender/blenlib/BLI_vector_set.hh25
-rw-r--r--source/blender/blenlib/BLI_vector_set_slots.hh4
-rw-r--r--source/blender/blenlib/BLI_virtual_array.hh10
-rw-r--r--source/blender/blenlib/BLI_winstuff.h5
-rw-r--r--source/blender/blenlib/CMakeLists.txt10
-rw-r--r--source/blender/blenlib/intern/BLI_args.c4
-rw-r--r--source/blender/blenlib/intern/BLI_filelist.c16
-rw-r--r--source/blender/blenlib/intern/BLI_ghash_utils.c6
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c6
-rw-r--r--source/blender/blenlib/intern/BLI_memarena.c10
-rw-r--r--source/blender/blenlib/intern/array_store.c10
-rw-r--r--source/blender/blenlib/intern/array_store_utils.c4
-rw-r--r--source/blender/blenlib/intern/array_utils.cc36
-rw-r--r--source/blender/blenlib/intern/boxpack_2d.c8
-rw-r--r--source/blender/blenlib/intern/cache_mutex.cc25
-rw-r--r--source/blender/blenlib/intern/convexhull_2d.c71
-rw-r--r--source/blender/blenlib/intern/delaunay_2d.cc18
-rw-r--r--source/blender/blenlib/intern/dot_export.cc4
-rw-r--r--source/blender/blenlib/intern/endian_switch.c4
-rw-r--r--source/blender/blenlib/intern/fileops.c6
-rw-r--r--source/blender/blenlib/intern/generic_virtual_array.cc12
-rw-r--r--source/blender/blenlib/intern/generic_virtual_vector_array.cc8
-rw-r--r--source/blender/blenlib/intern/hash_mm2a.c8
-rw-r--r--source/blender/blenlib/intern/hash_mm3.c2
-rw-r--r--source/blender/blenlib/intern/jitter_2d.c8
-rw-r--r--source/blender/blenlib/intern/kdtree_impl.h6
-rw-r--r--source/blender/blenlib/intern/lasso_2d.c10
-rw-r--r--source/blender/blenlib/intern/lazy_threading.cc50
-rw-r--r--source/blender/blenlib/intern/list_sort_impl.h49
-rw-r--r--source/blender/blenlib/intern/math_base.c4
-rw-r--r--source/blender/blenlib/intern/math_boolean.cc82
-rw-r--r--source/blender/blenlib/intern/math_color.c60
-rw-r--r--source/blender/blenlib/intern/math_geom.c46
-rw-r--r--source/blender/blenlib/intern/math_interp.c98
-rw-r--r--source/blender/blenlib/intern/math_matrix.c28
-rw-r--r--source/blender/blenlib/intern/math_rotation.c111
-rw-r--r--source/blender/blenlib/intern/math_solvers.c4
-rw-r--r--source/blender/blenlib/intern/math_vec.cc2
-rw-r--r--source/blender/blenlib/intern/math_vector.c2
-rw-r--r--source/blender/blenlib/intern/mesh_boolean.cc2
-rw-r--r--source/blender/blenlib/intern/mesh_intersect.cc22
-rw-r--r--source/blender/blenlib/intern/noise.c28
-rw-r--r--source/blender/blenlib/intern/noise.cc46
-rw-r--r--source/blender/blenlib/intern/path_util.c273
-rw-r--r--source/blender/blenlib/intern/polyfill_2d.c8
-rw-r--r--source/blender/blenlib/intern/rand.cc83
-rw-r--r--source/blender/blenlib/intern/scanfill.c39
-rw-r--r--source/blender/blenlib/intern/scanfill_utils.c22
-rw-r--r--source/blender/blenlib/intern/stack.c4
-rw-r--r--source/blender/blenlib/intern/storage.c2
-rw-r--r--source/blender/blenlib/intern/string.c51
-rw-r--r--source/blender/blenlib/intern/string_cursor_utf8.c59
-rw-r--r--source/blender/blenlib/intern/string_search.cc19
-rw-r--r--source/blender/blenlib/intern/string_utf8.c14
-rw-r--r--source/blender/blenlib/intern/string_utils.c14
-rw-r--r--source/blender/blenlib/intern/system.c4
-rw-r--r--source/blender/blenlib/intern/task_graph.cc2
-rw-r--r--source/blender/blenlib/intern/task_iterator.c4
-rw-r--r--source/blender/blenlib/intern/task_range.cc5
-rw-r--r--source/blender/blenlib/intern/task_scheduler.cc2
-rw-r--r--source/blender/blenlib/intern/threads.cc38
-rw-r--r--source/blender/blenlib/intern/timecode.c2
-rw-r--r--source/blender/blenlib/intern/uuid.cc35
-rw-r--r--source/blender/blenlib/intern/uvproject.c2
-rw-r--r--source/blender/blenlib/intern/winstuff.c14
-rw-r--r--source/blender/blenlib/tests/BLI_array_store_test.cc25
-rw-r--r--source/blender/blenlib/tests/BLI_cpp_type_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_delaunay_2d_test.cc20
-rw-r--r--source/blender/blenlib/tests/BLI_edgehash_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_exception_safety_test_utils.hh2
-rw-r--r--source/blender/blenlib/tests/BLI_generic_array_test.cc17
-rw-r--r--source/blender/blenlib/tests/BLI_ghash_test.cc14
-rw-r--r--source/blender/blenlib/tests/BLI_hash_mm2a_test.cc12
-rw-r--r--source/blender/blenlib/tests/BLI_heap_simple_test.cc8
-rw-r--r--source/blender/blenlib/tests/BLI_heap_test.cc20
-rw-r--r--source/blender/blenlib/tests/BLI_index_range_test.cc11
-rw-r--r--source/blender/blenlib/tests/BLI_kdopbvh_test.cc4
-rw-r--r--source/blender/blenlib/tests/BLI_linear_allocator_test.cc18
-rw-r--r--source/blender/blenlib/tests/BLI_listbase_test.cc4
-rw-r--r--source/blender/blenlib/tests/BLI_map_test.cc22
-rw-r--r--source/blender/blenlib/tests/BLI_math_color_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_math_rotation_test.cc18
-rw-r--r--source/blender/blenlib/tests/BLI_memory_utils_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_mesh_boolean_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_mesh_intersect_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_path_util_test.cc506
-rw-r--r--source/blender/blenlib/tests/BLI_polyfill_2d_test.cc122
-rw-r--r--source/blender/blenlib/tests/BLI_set_test.cc13
-rw-r--r--source/blender/blenlib/tests/BLI_span_test.cc4
-rw-r--r--source/blender/blenlib/tests/BLI_stack_cxx_test.cc10
-rw-r--r--source/blender/blenlib/tests/BLI_stack_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_string_ref_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_string_test.cc103
-rw-r--r--source/blender/blenlib/tests/BLI_string_utf8_test.cc492
-rw-r--r--source/blender/blenlib/tests/BLI_task_test.cc13
-rw-r--r--source/blender/blenlib/tests/BLI_vector_set_test.cc13
-rw-r--r--source/blender/blenlib/tests/BLI_vector_test.cc19
-rw-r--r--source/blender/blenlib/tests/BLI_virtual_array_test.cc6
-rw-r--r--source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc40
-rw-r--r--source/blender/blenlib/tests/performance/BLI_task_performance_test.cc16
-rw-r--r--source/blender/blenlib/tests/performance/CMakeLists.txt8
-rw-r--r--source/blender/blenloader/BLO_blend_validate.h8
-rw-r--r--source/blender/blenloader/BLO_read_write.h4
-rw-r--r--source/blender/blenloader/BLO_readfile.h5
-rw-r--r--source/blender/blenloader/BLO_undofile.h8
-rw-r--r--source/blender/blenloader/CMakeLists.txt28
-rw-r--r--source/blender/blenloader/intern/blend_validate.cc (renamed from source/blender/blenloader/intern/blend_validate.c)30
-rw-r--r--source/blender/blenloader/intern/readblenentry.cc (renamed from source/blender/blenloader/intern/readblenentry.c)99
-rw-r--r--source/blender/blenloader/intern/readfile.cc (renamed from source/blender/blenloader/intern/readfile.c)982
-rw-r--r--source/blender/blenloader/intern/readfile.h12
-rw-r--r--source/blender/blenloader/intern/readfile_tempload.cc (renamed from source/blender/blenloader/intern/readfile_tempload.c)3
-rw-r--r--source/blender/blenloader/intern/undofile.cc (renamed from source/blender/blenloader/intern/undofile.c)77
-rw-r--r--source/blender/blenloader/intern/versioning_250.c4
-rw-r--r--source/blender/blenloader/intern/versioning_260.c13
-rw-r--r--source/blender/blenloader/intern/versioning_280.c20
-rw-r--r--source/blender/blenloader/intern/versioning_290.c5
-rw-r--r--source/blender/blenloader/intern/versioning_300.cc (renamed from source/blender/blenloader/intern/versioning_300.c)713
-rw-r--r--source/blender/blenloader/intern/versioning_400.cc55
-rw-r--r--source/blender/blenloader/intern/versioning_common.cc29
-rw-r--r--source/blender/blenloader/intern/versioning_common.h11
-rw-r--r--source/blender/blenloader/intern/versioning_cycles.c2
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.cc (renamed from source/blender/blenloader/intern/versioning_defaults.c)132
-rw-r--r--source/blender/blenloader/intern/versioning_legacy.c3
-rw-r--r--source/blender/blenloader/intern/versioning_userdef.c2
-rw-r--r--source/blender/blenloader/intern/writefile.cc (renamed from source/blender/blenloader/intern/writefile.c)241
-rw-r--r--source/blender/blenloader/tests/blendfile_loading_base_test.cc10
-rw-r--r--source/blender/blentranslation/BLT_translation.h2
-rw-r--r--source/blender/blentranslation/intern/blt_lang.c3
-rw-r--r--source/blender/blentranslation/msgfmt/CMakeLists.txt21
-rw-r--r--source/blender/bmesh/CMakeLists.txt16
-rw-r--r--source/blender/bmesh/bmesh.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.c72
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.h3
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_log.c31
-rw-r--r--source/blender/bmesh/intern/bmesh_log.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.cc2
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_convert.cc403
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_convert.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_normals.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_partial_update.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon_edgenet.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_query.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_query.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_query_uv.cc15
-rw-r--r--source/blender/bmesh/intern/bmesh_query_uv.h1
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_impl.c2
-rw-r--r--source/blender/bmesh/operators/bmo_bridge.c124
-rw-r--r--source/blender/bmesh/operators/bmo_connect.c2
-rw-r--r--source/blender/bmesh/operators/bmo_fill_edgeloop.c2
-rw-r--r--source/blender/bmesh/operators/bmo_inset.c2
-rw-r--r--source/blender/bmesh/operators/bmo_join_triangles.c14
-rw-r--r--source/blender/bmesh/operators/bmo_normals.c4
-rw-r--r--source/blender/bmesh/operators/bmo_removedoubles.c6
-rw-r--r--source/blender/bmesh/operators/bmo_rotate_edges.c2
-rw-r--r--source/blender/bmesh/operators/bmo_smooth_laplacian.c4
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c4
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide_edgering.c28
-rw-r--r--source/blender/bmesh/tests/bmesh_core_test.cc2
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c18
-rw-r--r--source/blender/bmesh/tools/bmesh_bisect_plane.c4
-rw-r--r--source/blender/bmesh/tools/bmesh_boolean.cc34
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_collapse.c8
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_dissolve.c4
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c17
-rw-r--r--source/blender/bmesh/tools/bmesh_edgenet.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_edgesplit.c4
-rw-r--r--source/blender/bmesh/tools/bmesh_intersect.c4
-rw-r--r--source/blender/bmesh/tools/bmesh_path.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_path_region.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_path_uv.c4
-rw-r--r--source/blender/bmesh/tools/bmesh_region_match.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_wireframe.c2
-rw-r--r--source/blender/compositor/intern/COM_CPUDevice.cc2
-rw-r--r--source/blender/compositor/intern/COM_ChunkOrder.cc2
-rw-r--r--source/blender/compositor/intern/COM_ChunkOrder.h6
-rw-r--r--source/blender/compositor/intern/COM_ChunkOrderHotspot.cc4
-rw-r--r--source/blender/compositor/intern/COM_Debug.cc4
-rw-r--r--source/blender/compositor/intern/COM_ExecutionGroup.cc68
-rw-r--r--source/blender/compositor/intern/COM_FullFrameExecutionModel.cc2
-rw-r--r--source/blender/compositor/intern/COM_MemoryBuffer.cc12
-rw-r--r--source/blender/compositor/intern/COM_MemoryProxy.cc2
-rw-r--r--source/blender/compositor/intern/COM_MetaData.cc2
-rw-r--r--source/blender/compositor/intern/COM_MultiThreadedOperation.h12
-rw-r--r--source/blender/compositor/intern/COM_Node.cc8
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.cc12
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.h6
-rw-r--r--source/blender/compositor/intern/COM_NodeOperationBuilder.cc2
-rw-r--r--source/blender/compositor/intern/COM_OpenCLDevice.cc6
-rw-r--r--source/blender/compositor/intern/COM_TiledExecutionModel.cc4
-rw-r--r--source/blender/compositor/intern/COM_WorkScheduler.cc6
-rw-r--r--source/blender/compositor/intern/COM_compositor.cc6
-rw-r--r--source/blender/compositor/nodes/COM_CombineColorNode.cc2
-rw-r--r--source/blender/compositor/nodes/COM_CombineXYZNode.cc2
-rw-r--r--source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc2
-rw-r--r--source/blender/compositor/nodes/COM_CropNode.cc4
-rw-r--r--source/blender/compositor/nodes/COM_CryptomatteNode.cc7
-rw-r--r--source/blender/compositor/nodes/COM_MapUVNode.cc2
-rw-r--r--source/blender/compositor/nodes/COM_MaskNode.cc2
-rw-r--r--source/blender/compositor/nodes/COM_OutputFileNode.cc4
-rw-r--r--source/blender/compositor/nodes/COM_SceneTimeNode.cc2
-rw-r--r--source/blender/compositor/nodes/COM_SeparateColorNode.cc2
-rw-r--r--source/blender/compositor/nodes/COM_SeparateXYZNode.cc2
-rw-r--r--source/blender/compositor/nodes/COM_TimeNode.cc2
-rw-r--r--source/blender/compositor/operations/COM_AntiAliasOperation.cc26
-rw-r--r--source/blender/compositor/operations/COM_BilateralBlurOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_BlurBaseOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_BokehImageOperation.cc14
-rw-r--r--source/blender/compositor/operations/COM_BoxMaskOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_BrightnessOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_CalculateMeanOperation.cc8
-rw-r--r--source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cc11
-rw-r--r--source/blender/compositor/operations/COM_CompositorOperation.cc6
-rw-r--r--source/blender/compositor/operations/COM_ConstantOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_ConvertOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_CryptomatteOperation.cc8
-rw-r--r--source/blender/compositor/operations/COM_DenoiseOperation.cc16
-rw-r--r--source/blender/compositor/operations/COM_DespeckleOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_DilateErodeOperation.cc8
-rw-r--r--source/blender/compositor/operations/COM_DirectionalBlurOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_DisplaceOperation.cc10
-rw-r--r--source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cc222
-rw-r--r--source/blender/compositor/operations/COM_EllipseMaskOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc23
-rw-r--r--source/blender/compositor/operations/COM_FastGaussianBlurOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_FlipOperation.cc16
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc40
-rw-r--r--source/blender/compositor/operations/COM_GlareBaseOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_GlareFogGlowOperation.cc69
-rw-r--r--source/blender/compositor/operations/COM_GlareGhostOperation.cc12
-rw-r--r--source/blender/compositor/operations/COM_GlareStreaksOperation.cc14
-rw-r--r--source/blender/compositor/operations/COM_ImageOperation.cc10
-rw-r--r--source/blender/compositor/operations/COM_InpaintOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_KeyingBlurOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_KeyingClipOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_KeyingScreenOperation.cc20
-rw-r--r--source/blender/compositor/operations/COM_MapUVOperation.cc10
-rw-r--r--source/blender/compositor/operations/COM_MaskOperation.cc10
-rw-r--r--source/blender/compositor/operations/COM_MovieClipOperation.cc6
-rw-r--r--source/blender/compositor/operations/COM_MovieDistortionOperation.cc16
-rw-r--r--source/blender/compositor/operations/COM_MultilayerImageOperation.cc11
-rw-r--r--source/blender/compositor/operations/COM_NormalizeOperation.cc8
-rw-r--r--source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc24
-rw-r--r--source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_OutputFileOperation.cc24
-rw-r--r--source/blender/compositor/operations/COM_OutputFileOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc14
-rw-r--r--source/blender/compositor/operations/COM_PlaneTrackOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_PreviewOperation.cc21
-rw-r--r--source/blender/compositor/operations/COM_ReadBufferOperation.cc3
-rw-r--r--source/blender/compositor/operations/COM_RenderLayersProg.cc18
-rw-r--r--source/blender/compositor/operations/COM_RotateOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_SMAAOperation.cc22
-rw-r--r--source/blender/compositor/operations/COM_ScaleOperation.cc6
-rw-r--r--source/blender/compositor/operations/COM_ScaleOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc30
-rw-r--r--source/blender/compositor/operations/COM_SunBeamsOperation.cc34
-rw-r--r--source/blender/compositor/operations/COM_TonemapOperation.cc18
-rw-r--r--source/blender/compositor/operations/COM_TonemapOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_TransformOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc30
-rw-r--r--source/blender/compositor/operations/COM_VectorBlurOperation.cc39
-rw-r--r--source/blender/compositor/operations/COM_ViewerOperation.cc6
-rw-r--r--source/blender/compositor/operations/COM_WriteBufferOperation.cc8
-rw-r--r--source/blender/compositor/realtime_compositor/CMakeLists.txt144
-rw-r--r--source/blender/compositor/realtime_compositor/COM_context.hh11
-rw-r--r--source/blender/compositor/realtime_compositor/COM_conversion_operation.hh76
-rw-r--r--source/blender/compositor/realtime_compositor/COM_domain.hh2
-rw-r--r--source/blender/compositor/realtime_compositor/COM_result.hh12
-rw-r--r--source/blender/compositor/realtime_compositor/COM_scheduler.hh2
-rw-r--r--source/blender/compositor/realtime_compositor/COM_static_cache_manager.hh77
-rw-r--r--source/blender/compositor/realtime_compositor/COM_texture_pool.hh4
-rw-r--r--source/blender/compositor/realtime_compositor/COM_utilities.hh2
-rw-r--r--source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_parallel_reduction.hh103
-rw-r--r--source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc309
-rw-r--r--source/blender/compositor/realtime_compositor/cached_resources/COM_cached_resource.hh31
-rw-r--r--source/blender/compositor/realtime_compositor/cached_resources/COM_morphological_distance_feather_weights.hh61
-rw-r--r--source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_blur_weights.hh52
-rw-r--r--source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_separable_blur_weights.hh53
-rw-r--r--source/blender/compositor/realtime_compositor/cached_resources/intern/morphological_distance_feather_weights.cc159
-rw-r--r--source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc115
-rw-r--r--source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_separable_blur_weights.cc93
-rw-r--r--source/blender/compositor/realtime_compositor/intern/context.cc11
-rw-r--r--source/blender/compositor/realtime_compositor/intern/conversion_operation.cc64
-rw-r--r--source/blender/compositor/realtime_compositor/intern/evaluator.cc1
-rw-r--r--source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc2
-rw-r--r--source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc4
-rw-r--r--source/blender/compositor/realtime_compositor/intern/result.cc8
-rw-r--r--source/blender/compositor/realtime_compositor/intern/scheduler.cc96
-rw-r--r--source/blender/compositor/realtime_compositor/intern/shader_operation.cc2
-rw-r--r--source/blender/compositor/realtime_compositor/intern/static_cache_manager.cc74
-rw-r--r--source/blender/compositor/realtime_compositor/intern/texture_pool.cc18
-rw-r--r--source/blender/compositor/realtime_compositor/intern/utilities.cc4
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_alpha_crop.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_alpha_crop.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_bilateral_blur.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_bilateral_blur.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_blur.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_blur.glsl)21
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_blur_variable_size.glsl71
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_bokeh_image.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_bokeh_image.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_box_mask.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_box_mask.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_convert.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_convert.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_despeckle.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_despeckle.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_directional_blur.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_directional_blur.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_edge_filter.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_edge_filter.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_ellipse_mask.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_ellipse_mask.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_filter.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_filter.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_flip.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_flip.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_image_crop.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_image_crop.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_morphological_distance.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_feather.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_morphological_distance_feather.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_threshold.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_morphological_distance_threshold.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_morphological_step.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_morphological_step.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_normalize.glsl10
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_parallel_reduction.glsl98
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_projector_lens_distortion.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_projector_lens_distortion.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_realize_on_domain.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_realize_on_domain.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_screen_lens_distortion.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_set_alpha.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_set_alpha.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_split_viewer.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_split_viewer.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_symmetric_blur.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_separable_blur.glsl (renamed from source/blender/gpu/shaders/compositor/compositor_symmetric_separable_blur.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_photoreceptor.glsl22
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_simple.glsl26
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_alpha_crop_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_alpha_crop_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_bilateral_blur_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_bilateral_blur_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_blur_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_variable_size_info.hh15
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_bokeh_image_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_bokeh_image_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_box_mask_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_box_mask_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_convert_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_convert_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_despeckle_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_despeckle_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_directional_blur_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_directional_blur_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_edge_filter_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_edge_filter_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_ellipse_mask_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_ellipse_mask_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_filter_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_filter_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_flip_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_flip_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_image_crop_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_image_crop_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_feather_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_morphological_distance_feather_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_morphological_distance_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_threshold_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_morphological_distance_threshold_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_step_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_morphological_step_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_normalize_info.hh12
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_parallel_reduction_info.hh149
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_projector_lens_distortion_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_projector_lens_distortion_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_realize_on_domain_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_realize_on_domain_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_screen_lens_distortion_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_screen_lens_distortion_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_set_alpha_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_set_alpha_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_split_viewer_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_split_viewer_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_blur_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_symmetric_blur_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_separable_blur_info.hh (renamed from source/blender/gpu/shaders/compositor/infos/compositor_symmetric_separable_blur_info.hh)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_photoreceptor_info.hh16
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_simple_info.hh13
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_alpha_over.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_alpha_over.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_blur_common.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_blur_common.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_bright_contrast.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_bright_contrast.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_channel_matte.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_channel_matte.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_chroma_matte.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_chroma_matte.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_balance.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_balance.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_correction.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_correction.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_matte.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_matte.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_spill.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_spill.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_to_luminance.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_to_luminance.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_difference_matte.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_difference_matte.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_distance_matte.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_distance_matte.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_exposure.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_exposure.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_gamma.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_gamma.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_correct.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_hue_correct.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_saturation_value.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_hue_saturation_value.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_invert.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_invert.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_luminance_matte.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_luminance_matte.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_main.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_main.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_map_value.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_map_value.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_normal.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_normal.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_posterize.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_posterize.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_separate_combine.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_separate_combine.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_set_alpha.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_set_alpha.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_store_output.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_store_output.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_texture_utilities.glsl)0
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_type_conversion.glsl (renamed from source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_type_conversion.glsl)0
-rw-r--r--source/blender/compositor/tests/COM_BuffersIterator_test.cc8
-rw-r--r--source/blender/datatoc/datatoc_icon.c7
-rwxr-xr-xsource/blender/datatoc/datatoc_icon.py4
-rw-r--r--source/blender/depsgraph/CMakeLists.txt3
-rw-r--r--source/blender/depsgraph/DEG_depsgraph.h8
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_build.h3
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_query.h60
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.cc3
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cache.cc6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cycle.cc2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_key.cc (renamed from source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc)32
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_key.h201
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc95
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h32
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc3
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc31
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h127
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc3
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_rna.cc4
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc1
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc7
-rw-r--r--source/blender/depsgraph/intern/depsgraph.h3
-rw-r--r--source/blender/depsgraph/intern/depsgraph_debug.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_physics.cc12
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_foreach.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_iter.cc51
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc29
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval.cc58
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc9
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc21
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.cc2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_visibility.cc15
-rw-r--r--source/blender/depsgraph/intern/node/deg_node.cc4
-rw-r--r--source/blender/depsgraph/intern/node/deg_node.h2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_component.cc17
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_component.h1
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_factory.cc6
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_factory_impl.h9
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_id.cc7
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_id.h3
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.cc2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.h1
-rw-r--r--source/blender/draw/CMakeLists.txt96
-rw-r--r--source/blender/draw/DRW_engine.h12
-rw-r--r--source/blender/draw/DRW_pbvh.h98
-rw-r--r--source/blender/draw/engines/basic/basic_engine.c15
-rw-r--r--source/blender/draw/engines/basic/shaders/basic_conservative_depth_geom.glsl10
-rw-r--r--source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh2
-rw-r--r--source/blender/draw/engines/compositor/compositor_engine.cc2
-rw-r--r--source/blender/draw/engines/eevee/eevee_depth_of_field.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.c31
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.h2
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c45
-rw-r--r--source/blender/draw/engines/eevee/eevee_lights.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c31
-rw-r--r--source/blender/draw/engines/eevee/eevee_motion_blur.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h19
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_shaders.c16
-rw-r--r--source/blender/draw/engines/eevee/eevee_shadows.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_volumes.c58
-rw-r--r--source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl9
-rw-r--r--source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_dof_scatter_vert.glsl6
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl6
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl6
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_vert.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/ssr_lib.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/surface_lib.glsl11
-rw-r--r--source/blender/draw/engines/eevee/shaders/surface_vert.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl11
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_resolve_comp.glsl38
-rw-r--r--source/blender/draw/engines/eevee/shaders/world_vert.glsl2
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_camera.cc6
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_camera.hh4
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc4
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh3
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_defines.hh2
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc4
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_engine.cc6
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_film.cc4
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_instance.cc23
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_instance.hh1
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_light.cc6
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_material.cc7
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_material.hh4
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_motion_blur.cc4
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_pipeline.cc16
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc6
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_sampling.cc10
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_shader_shared.hh4
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_sync.cc24
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_sync.hh10
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_velocity.cc20
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_view.cc2
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_world.cc3
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl2
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_accumulator_lib.glsl2
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_reduce_comp.glsl2
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl2
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl35
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_hiz_update_comp.glsl4
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_debug_frag.glsl2
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_light_iter_lib.glsl2
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_light_lib.glsl2
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl4
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_sampling_lib.glsl2
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_velocity_lib.glsl4
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/infos/eevee_light_culling_info.hh4
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh13
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_cache_utils.c12
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_data.c8
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.c59
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_shader_fx.c32
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_shader_shared.h3
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl617
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_depth_merge_vert.glsl2
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_vert.glsl27
-rw-r--r--source/blender/draw/engines/gpencil/shaders/infos/gpencil_info.hh13
-rw-r--r--source/blender/draw/engines/image/image_drawing_mode.hh37
-rw-r--r--source/blender/draw/engines/image/image_engine.cc2
-rw-r--r--source/blender/draw/engines/image/image_space_image.hh6
-rw-r--r--source/blender/draw/engines/overlay/overlay_antialiasing.cc (renamed from source/blender/draw/engines/overlay/overlay_antialiasing.c)29
-rw-r--r--source/blender/draw/engines/overlay/overlay_armature.cc (renamed from source/blender/draw/engines/overlay/overlay_armature.c)304
-rw-r--r--source/blender/draw/engines/overlay/overlay_background.cc (renamed from source/blender/draw/engines/overlay/overlay_background.c)12
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_curve.cc (renamed from source/blender/draw/engines/overlay/overlay_edit_curve.c)4
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_curves.cc2
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_mesh.cc (renamed from source/blender/draw/engines/overlay/overlay_edit_mesh.c)35
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_text.cc (renamed from source/blender/draw/engines/overlay/overlay_edit_text.c)20
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_uv.cc (renamed from source/blender/draw/engines/overlay/overlay_edit_uv.c)110
-rw-r--r--source/blender/draw/engines/overlay/overlay_engine.cc (renamed from source/blender/draw/engines/overlay/overlay_engine.c)324
-rw-r--r--source/blender/draw/engines/overlay/overlay_engine.h8
-rw-r--r--source/blender/draw/engines/overlay/overlay_extra.cc (renamed from source/blender/draw/engines/overlay/overlay_extra.c)187
-rw-r--r--source/blender/draw/engines/overlay/overlay_facing.cc (renamed from source/blender/draw/engines/overlay/overlay_facing.c)8
-rw-r--r--source/blender/draw/engines/overlay/overlay_fade.cc (renamed from source/blender/draw/engines/overlay/overlay_fade.c)10
-rw-r--r--source/blender/draw/engines/overlay/overlay_gpencil.cc (renamed from source/blender/draw/engines/overlay/overlay_gpencil.c)73
-rw-r--r--source/blender/draw/engines/overlay/overlay_grid.cc (renamed from source/blender/draw/engines/overlay/overlay_grid.c)60
-rw-r--r--source/blender/draw/engines/overlay/overlay_image.cc (renamed from source/blender/draw/engines/overlay/overlay_image.c)74
-rw-r--r--source/blender/draw/engines/overlay/overlay_lattice.cc (renamed from source/blender/draw/engines/overlay/overlay_lattice.c)4
-rw-r--r--source/blender/draw/engines/overlay/overlay_metaball.cc (renamed from source/blender/draw/engines/overlay/overlay_metaball.c)19
-rw-r--r--source/blender/draw/engines/overlay/overlay_mode_transfer.cc (renamed from source/blender/draw/engines/overlay/overlay_mode_transfer.c)8
-rw-r--r--source/blender/draw/engines/overlay/overlay_motion_path.cc (renamed from source/blender/draw/engines/overlay/overlay_motion_path.c)14
-rw-r--r--source/blender/draw/engines/overlay/overlay_outline.cc (renamed from source/blender/draw/engines/overlay/overlay_outline.c)103
-rw-r--r--source/blender/draw/engines/overlay/overlay_paint.cc (renamed from source/blender/draw/engines/overlay/overlay_paint.c)27
-rw-r--r--source/blender/draw/engines/overlay/overlay_particle.cc (renamed from source/blender/draw/engines/overlay/overlay_particle.c)26
-rw-r--r--source/blender/draw/engines/overlay/overlay_private.hh (renamed from source/blender/draw/engines/overlay/overlay_private.h)16
-rw-r--r--source/blender/draw/engines/overlay/overlay_sculpt.cc (renamed from source/blender/draw/engines/overlay/overlay_sculpt.c)8
-rw-r--r--source/blender/draw/engines/overlay/overlay_sculpt_curves.cc6
-rw-r--r--source/blender/draw/engines/overlay/overlay_shader.cc (renamed from source/blender/draw/engines/overlay/overlay_shader.c)76
-rw-r--r--source/blender/draw/engines/overlay/overlay_shader_shared.h3
-rw-r--r--source/blender/draw/engines/overlay/overlay_viewer_attribute.cc181
-rw-r--r--source/blender/draw/engines/overlay/overlay_volume.cc (renamed from source/blender/draw/engines/overlay/overlay_volume.c)8
-rw-r--r--source/blender/draw/engines/overlay/overlay_wireframe.cc (renamed from source/blender/draw/engines/overlay/overlay_wireframe.c)54
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh21
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/overlay_background_info.hh2
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh73
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh32
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/overlay_grid_info.hh2
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/overlay_outline_info.hh4
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/overlay_paint_info.hh2
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/overlay_viewer_attribute_info.hh66
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_solid_vert.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_geom.glsl4
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert.glsl4
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl178
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_armature_shape_solid_vert.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_outline_vert.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_armature_stick_vert.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_background_frag.glsl4
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_geom.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl16
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_geom.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_skin_root_vert.glsl6
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl208
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl4
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_geom.glsl4
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_vert.glsl4
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_extra_groundline_vert.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_extra_point_vert.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_extra_vert.glsl7
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_extra_wire_vert.glsl3
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_grid_frag.glsl103
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_grid_vert.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_image_frag.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_geom.glsl3
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert_no_geom.glsl160
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_motion_path_point_vert.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_outline_detect_frag.glsl22
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_curves_vert.glsl4
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_gpencil_frag.glsl4
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_gpencil_vert.glsl15
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_paint_point_vert.glsl4
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_paint_wire_vert.glsl4
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_particle_vert.glsl6
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_pointcloud_only_vert.glsl9
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_uniform_color_frag.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_curve_vert.glsl9
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_curves_vert.glsl28
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_frag.glsl8
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_mesh_vert.glsl9
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_pointcloud_vert.glsl10
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_wireframe_frag.glsl4
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_wireframe_vert.glsl5
-rw-r--r--source/blender/draw/engines/select/select_engine.c10
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl4
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl7
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl2
-rw-r--r--source/blender/draw/engines/workbench/workbench_data.c6
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_dof.c2
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.c28
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c6
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h5
-rw-r--r--source/blender/draw/engines/workbench/workbench_shader.cc4
-rw-r--r--source/blender/draw/engines/workbench/workbench_shadow.c5
-rw-r--r--source/blender/draw/engines/workbench/workbench_volume.c4
-rw-r--r--source/blender/draw/intern/DRW_gpu_wrapper.hh102
-rw-r--r--source/blender/draw/intern/DRW_render.h29
-rw-r--r--source/blender/draw/intern/draw_attributes.cc7
-rw-r--r--source/blender/draw/intern/draw_attributes.h26
-rw-r--r--source/blender/draw/intern/draw_cache.c46
-rw-r--r--source/blender/draw/intern/draw_cache.h19
-rw-r--r--source/blender/draw/intern/draw_cache_extract.hh19
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.cc7
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc37
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h16
-rw-r--r--source/blender/draw/intern/draw_cache_impl_curve.cc45
-rw-r--r--source/blender/draw/intern/draw_cache_impl_curves.cc184
-rw-r--r--source/blender/draw/intern/draw_cache_impl_gpencil.cc (renamed from source/blender/draw/intern/draw_cache_impl_gpencil.c)265
-rw-r--r--source/blender/draw/intern/draw_cache_impl_lattice.c8
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.cc113
-rw-r--r--source/blender/draw/intern/draw_cache_impl_particles.c47
-rw-r--r--source/blender/draw/intern/draw_cache_impl_pointcloud.cc408
-rw-r--r--source/blender/draw/intern/draw_cache_impl_subdivision.cc105
-rw-r--r--source/blender/draw/intern/draw_cache_impl_volume.cc (renamed from source/blender/draw/intern/draw_cache_impl_volume.c)57
-rw-r--r--source/blender/draw/intern/draw_command.cc34
-rw-r--r--source/blender/draw/intern/draw_command.hh41
-rw-r--r--source/blender/draw/intern/draw_common.c17
-rw-r--r--source/blender/draw/intern/draw_common.h9
-rw-r--r--source/blender/draw/intern/draw_common_shader_shared.h5
-rw-r--r--source/blender/draw/intern/draw_curves.cc57
-rw-r--r--source/blender/draw/intern/draw_curves_private.h10
-rw-r--r--source/blender/draw/intern/draw_debug.cc12
-rw-r--r--source/blender/draw/intern/draw_defines.h4
-rw-r--r--source/blender/draw/intern/draw_fluid.c2
-rw-r--r--source/blender/draw/intern/draw_hair.cc27
-rw-r--r--source/blender/draw/intern/draw_hair_private.h5
-rw-r--r--source/blender/draw/intern/draw_instance_data.c139
-rw-r--r--source/blender/draw/intern/draw_instance_data.h8
-rw-r--r--source/blender/draw/intern/draw_manager.c185
-rw-r--r--source/blender/draw/intern/draw_manager.cc34
-rw-r--r--source/blender/draw/intern/draw_manager.h28
-rw-r--r--source/blender/draw/intern/draw_manager.hh32
-rw-r--r--source/blender/draw/intern/draw_manager_data.cc (renamed from source/blender/draw/intern/draw_manager_data.c)811
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c24
-rw-r--r--source/blender/draw/intern/draw_manager_profiling.c48
-rw-r--r--source/blender/draw/intern/draw_manager_shader.c63
-rw-r--r--source/blender/draw/intern/draw_manager_text.cc (renamed from source/blender/draw/intern/draw_manager_text.c)89
-rw-r--r--source/blender/draw/intern/draw_pass.hh46
-rw-r--r--source/blender/draw/intern/draw_pbvh.cc1301
-rw-r--r--source/blender/draw/intern/draw_pbvh.h24
-rw-r--r--source/blender/draw/intern/draw_pointcloud.cc103
-rw-r--r--source/blender/draw/intern/draw_pointcloud_private.hh19
-rw-r--r--source/blender/draw/intern/draw_resource.cc90
-rw-r--r--source/blender/draw/intern/draw_resource.hh4
-rw-r--r--source/blender/draw/intern/draw_shader.cc7
-rw-r--r--source/blender/draw/intern/draw_shader_shared.h64
-rw-r--r--source/blender/draw/intern/draw_view.cc110
-rw-r--r--source/blender/draw/intern/draw_view.hh32
-rw-r--r--source/blender/draw/intern/draw_volume.cc4
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh.hh18
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc98
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc12
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc37
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc32
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc35
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc32
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc14
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc48
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc22
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc20
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc8
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc12
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc8
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc6
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_nor.cc16
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc12
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc12
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc16
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc22
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc8
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc34
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc16
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc48
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_skin_roots.cc4
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc10
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc8
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc6
-rw-r--r--source/blender/draw/intern/shaders/common_debug_print_lib.glsl4
-rw-r--r--source/blender/draw/intern/shaders/common_fxaa_lib.glsl2
-rw-r--r--source/blender/draw/intern/shaders/common_globals_lib.glsl148
-rw-r--r--source/blender/draw/intern/shaders/common_gpencil_lib.glsl88
-rw-r--r--source/blender/draw/intern/shaders/common_intersect_lib.glsl14
-rw-r--r--source/blender/draw/intern/shaders/common_pointcloud_lib.glsl78
-rw-r--r--source/blender/draw/intern/shaders/common_shape_lib.glsl2
-rw-r--r--source/blender/draw/intern/shaders/common_smaa_lib.glsl37
-rw-r--r--source/blender/draw/intern/shaders/common_view_clipping_lib.glsl12
-rw-r--r--source/blender/draw/intern/shaders/common_view_lib.glsl75
-rw-r--r--source/blender/draw/intern/shaders/draw_debug_info.hh1
-rw-r--r--source/blender/draw/intern/shaders/draw_debug_print_display_vert.glsl3
-rw-r--r--source/blender/draw/intern/shaders/draw_object_infos_info.hh12
-rw-r--r--source/blender/draw/intern/shaders/draw_view_info.hh34
-rw-r--r--source/blender/draw/tests/draw_pass_test.cc7
-rw-r--r--source/blender/draw/tests/shaders_test.cc9
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c10
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c163
-rw-r--r--source/blender/editors/animation/anim_draw.c230
-rw-r--r--source/blender/editors/animation/anim_filter.c41
-rw-r--r--source/blender/editors/animation/anim_markers.c17
-rw-r--r--source/blender/editors/animation/anim_motion_paths.c4
-rw-r--r--source/blender/editors/animation/drivers.c12
-rw-r--r--source/blender/editors/animation/keyframes_draw.c2
-rw-r--r--source/blender/editors/animation/keyframes_edit.c8
-rw-r--r--source/blender/editors/animation/keyframes_general.c6
-rw-r--r--source/blender/editors/animation/keyframes_keylist.cc4
-rw-r--r--source/blender/editors/animation/keyframing.c6
-rw-r--r--source/blender/editors/animation/keyingsets.c16
-rw-r--r--source/blender/editors/armature/armature_add.c21
-rw-r--r--source/blender/editors/armature/armature_edit.c51
-rw-r--r--source/blender/editors/armature/armature_naming.c6
-rw-r--r--source/blender/editors/armature/armature_relations.c9
-rw-r--r--source/blender/editors/armature/armature_select.c52
-rw-r--r--source/blender/editors/armature/armature_skinning.c15
-rw-r--r--source/blender/editors/armature/armature_utils.c8
-rw-r--r--source/blender/editors/armature/editarmature_undo.c5
-rw-r--r--source/blender/editors/armature/meshlaplacian.c26
-rw-r--r--source/blender/editors/armature/pose_edit.c19
-rw-r--r--source/blender/editors/armature/pose_lib_2.c95
-rw-r--r--source/blender/editors/armature/pose_select.c37
-rw-r--r--source/blender/editors/armature/pose_slide.c9
-rw-r--r--source/blender/editors/armature/pose_transform.c27
-rw-r--r--source/blender/editors/armature/pose_utils.c4
-rw-r--r--source/blender/editors/asset/ED_asset_handle.h13
-rw-r--r--source/blender/editors/asset/ED_asset_list.h1
-rw-r--r--source/blender/editors/asset/intern/asset_handle.cc39
-rw-r--r--source/blender/editors/asset/intern/asset_list.cc14
-rw-r--r--source/blender/editors/asset/intern/asset_ops.cc18
-rw-r--r--source/blender/editors/asset/intern/asset_temp_id_consumer.cc2
-rw-r--r--source/blender/editors/curve/editcurve.c118
-rw-r--r--source/blender/editors/curve/editcurve_add.c3
-rw-r--r--source/blender/editors/curve/editcurve_paint.c18
-rw-r--r--source/blender/editors/curve/editcurve_pen.c27
-rw-r--r--source/blender/editors/curve/editcurve_query.c2
-rw-r--r--source/blender/editors/curve/editcurve_select.c44
-rw-r--r--source/blender/editors/curve/editcurve_undo.c5
-rw-r--r--source/blender/editors/curve/editfont.c30
-rw-r--r--source/blender/editors/curve/editfont_undo.c2
-rw-r--r--source/blender/editors/curves/intern/curves_add.cc2
-rw-r--r--source/blender/editors/curves/intern/curves_ops.cc26
-rw-r--r--source/blender/editors/datafiles/CMakeLists.txt2
-rw-r--r--source/blender/editors/geometry/geometry_attributes.cc13
-rw-r--r--source/blender/editors/gizmo_library/gizmo_library_presets.c2
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c2
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c4
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c6
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c6
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c6
-rw-r--r--source/blender/editors/gpencil/annotate_paint.c17
-rw-r--r--source/blender/editors/gpencil/gpencil_armature.c19
-rw-r--r--source/blender/editors/gpencil/gpencil_bake_animation.cc23
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c8
-rw-r--r--source/blender/editors/gpencil/gpencil_data.c6
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c60
-rw-r--r--source/blender/editors/gpencil/gpencil_fill.c857
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h26
-rw-r--r--source/blender/editors/gpencil/gpencil_interpolate.c10
-rw-r--r--source/blender/editors/gpencil/gpencil_mesh.cc18
-rw-r--r--source/blender/editors/gpencil/gpencil_ops_versioning.c6
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c56
-rw-r--r--source/blender/editors/gpencil/gpencil_primitive.c28
-rw-r--r--source/blender/editors/gpencil/gpencil_sculpt_paint.c346
-rw-r--r--source/blender/editors/gpencil/gpencil_select.c27
-rw-r--r--source/blender/editors/gpencil/gpencil_trace_ops.c39
-rw-r--r--source/blender/editors/gpencil/gpencil_trace_utils.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c120
-rw-r--r--source/blender/editors/gpencil/gpencil_uv.c4
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_ops.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_paint.c16
-rw-r--r--source/blender/editors/gpencil/gpencil_weight_paint.c16
-rw-r--r--source/blender/editors/include/ED_anim_api.h23
-rw-r--r--source/blender/editors/include/ED_armature.h9
-rw-r--r--source/blender/editors/include/ED_gpencil.h3
-rw-r--r--source/blender/editors/include/ED_image.h6
-rw-r--r--source/blender/editors/include/ED_keyframes_edit.h2
-rw-r--r--source/blender/editors/include/ED_mesh.h11
-rw-r--r--source/blender/editors/include/ED_node.h28
-rw-r--r--source/blender/editors/include/ED_object.h16
-rw-r--r--source/blender/editors/include/ED_screen.h6
-rw-r--r--source/blender/editors/include/ED_screen_types.h2
-rw-r--r--source/blender/editors/include/ED_sculpt.h5
-rw-r--r--source/blender/editors/include/ED_space_api.h2
-rw-r--r--source/blender/editors/include/ED_spreadsheet.h22
-rw-r--r--source/blender/editors/include/ED_transform.h3
-rw-r--r--source/blender/editors/include/ED_undo.h8
-rw-r--r--source/blender/editors/include/ED_uvedit.h37
-rw-r--r--source/blender/editors/include/ED_view3d.h11
-rw-r--r--source/blender/editors/include/ED_viewer_path.hh69
-rw-r--r--source/blender/editors/include/UI_icons.h4
-rw-r--r--source/blender/editors/include/UI_interface.h17
-rw-r--r--source/blender/editors/include/UI_interface.hh1
-rw-r--r--source/blender/editors/include/UI_interface_icons.h12
-rw-r--r--source/blender/editors/include/UI_view2d.h128
-rw-r--r--source/blender/editors/interface/eyedroppers/eyedropper_depth.c2
-rw-r--r--source/blender/editors/interface/eyedroppers/interface_eyedropper.c2
-rw-r--r--source/blender/editors/interface/interface.cc175
-rw-r--r--source/blender/editors/interface/interface_anim.cc2
-rw-r--r--source/blender/editors/interface/interface_context_path.cc14
-rw-r--r--source/blender/editors/interface/interface_drag.cc5
-rw-r--r--source/blender/editors/interface/interface_draw.c6
-rw-r--r--source/blender/editors/interface/interface_dropboxes.cc19
-rw-r--r--source/blender/editors/interface/interface_handlers.c77
-rw-r--r--source/blender/editors/interface/interface_icons.c129
-rw-r--r--source/blender/editors/interface/interface_icons_event.c2
-rw-r--r--source/blender/editors/interface/interface_intern.h16
-rw-r--r--source/blender/editors/interface/interface_layout.c20
-rw-r--r--source/blender/editors/interface/interface_ops.cc54
-rw-r--r--source/blender/editors/interface/interface_panel.cc48
-rw-r--r--source/blender/editors/interface/interface_query.cc14
-rw-r--r--source/blender/editors/interface/interface_region_color_picker.cc18
-rw-r--r--source/blender/editors/interface/interface_region_hud.cc2
-rw-r--r--source/blender/editors/interface/interface_region_menu_pie.cc4
-rw-r--r--source/blender/editors/interface/interface_region_menu_popup.cc335
-rw-r--r--source/blender/editors/interface/interface_region_popover.cc8
-rw-r--r--source/blender/editors/interface/interface_region_popup.cc29
-rw-r--r--source/blender/editors/interface/interface_region_search.cc26
-rw-r--r--source/blender/editors/interface/interface_region_tooltip.cc35
-rw-r--r--source/blender/editors/interface/interface_regions.cc2
-rw-r--r--source/blender/editors/interface/interface_style.cc34
-rw-r--r--source/blender/editors/interface/interface_template_asset_view.cc15
-rw-r--r--source/blender/editors/interface/interface_template_list.cc34
-rw-r--r--source/blender/editors/interface/interface_template_search_menu.cc19
-rw-r--r--source/blender/editors/interface/interface_template_search_operator.cc6
-rw-r--r--source/blender/editors/interface/interface_templates.c45
-rw-r--r--source/blender/editors/interface/interface_utils.cc6
-rw-r--r--source/blender/editors/interface/interface_widgets.c90
-rw-r--r--source/blender/editors/interface/view2d.cc219
-rw-r--r--source/blender/editors/interface/view2d_draw.cc14
-rw-r--r--source/blender/editors/interface/view2d_edge_pan.cc20
-rw-r--r--source/blender/editors/interface/view2d_gizmo_navigate.cc4
-rw-r--r--source/blender/editors/interface/view2d_ops.cc60
-rw-r--r--source/blender/editors/interface/views/abstract_view_item.cc2
-rw-r--r--source/blender/editors/interface/views/grid_view.cc4
-rw-r--r--source/blender/editors/interface/views/interface_view.cc2
-rw-r--r--source/blender/editors/io/io_alembic.c2
-rw-r--r--source/blender/editors/io/io_collada.c16
-rw-r--r--source/blender/editors/io/io_gpencil_import.c4
-rw-r--r--source/blender/editors/io/io_obj.c40
-rw-r--r--source/blender/editors/io/io_stl_ops.c4
-rw-r--r--source/blender/editors/io/io_usd.c2
-rw-r--r--source/blender/editors/lattice/editlattice_select.c24
-rw-r--r--source/blender/editors/lattice/editlattice_tools.c6
-rw-r--r--source/blender/editors/lattice/editlattice_undo.c5
-rw-r--r--source/blender/editors/mask/mask_add.c4
-rw-r--r--source/blender/editors/mask/mask_draw.c6
-rw-r--r--source/blender/editors/mask/mask_editaction.c2
-rw-r--r--source/blender/editors/mask/mask_shapekey.c4
-rw-r--r--source/blender/editors/mesh/CMakeLists.txt4
-rw-r--r--source/blender/editors/mesh/editface.cc328
-rw-r--r--source/blender/editors/mesh/editmesh_add_gizmo.c4
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c12
-rw-r--r--source/blender/editors/mesh/editmesh_bisect.c9
-rw-r--r--source/blender/editors/mesh/editmesh_extrude.c48
-rw-r--r--source/blender/editors/mesh/editmesh_extrude_screw.c11
-rw-r--r--source/blender/editors/mesh/editmesh_extrude_spin.c7
-rw-r--r--source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c2
-rw-r--r--source/blender/editors/mesh/editmesh_inset.c4
-rw-r--r--source/blender/editors/mesh/editmesh_intersect.c9
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c272
-rw-r--r--source/blender/editors/mesh/editmesh_knife_project.c11
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c11
-rw-r--r--source/blender/editors/mesh/editmesh_mask_extract.c12
-rw-r--r--source/blender/editors/mesh/editmesh_path.c15
-rw-r--r--source/blender/editors/mesh/editmesh_polybuild.c72
-rw-r--r--source/blender/editors/mesh/editmesh_preselect_edgering.c2
-rw-r--r--source/blender/editors/mesh/editmesh_preselect_elem.c8
-rw-r--r--source/blender/editors/mesh/editmesh_rip.c7
-rw-r--r--source/blender/editors/mesh/editmesh_rip_edge.c3
-rw-r--r--source/blender/editors/mesh/editmesh_select.cc (renamed from source/blender/editors/mesh/editmesh_select.c)651
-rw-r--r--source/blender/editors/mesh/editmesh_select_similar.c41
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c198
-rw-r--r--source/blender/editors/mesh/editmesh_undo.cc (renamed from source/blender/editors/mesh/editmesh_undo.c)219
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c58
-rw-r--r--source/blender/editors/mesh/mesh_data.cc188
-rw-r--r--source/blender/editors/mesh/mesh_intern.h15
-rw-r--r--source/blender/editors/mesh/mesh_ops.c4
-rw-r--r--source/blender/editors/mesh/meshtools.cc35
-rw-r--r--source/blender/editors/metaball/editmball_undo.c5
-rw-r--r--source/blender/editors/metaball/mball_edit.c25
-rw-r--r--source/blender/editors/object/object_add.cc264
-rw-r--r--source/blender/editors/object/object_bake.c4
-rw-r--r--source/blender/editors/object/object_bake_api.c64
-rw-r--r--source/blender/editors/object/object_collection.c1
-rw-r--r--source/blender/editors/object/object_constraint.c28
-rw-r--r--source/blender/editors/object/object_data_transform.c2
-rw-r--r--source/blender/editors/object/object_edit.c37
-rw-r--r--source/blender/editors/object/object_gpencil_modifier.c236
-rw-r--r--source/blender/editors/object/object_hook.c38
-rw-r--r--source/blender/editors/object/object_intern.h4
-rw-r--r--source/blender/editors/object/object_modes.c8
-rw-r--r--source/blender/editors/object/object_modifier.cc212
-rw-r--r--source/blender/editors/object/object_ops.c4
-rw-r--r--source/blender/editors/object/object_random.c4
-rw-r--r--source/blender/editors/object/object_relations.c71
-rw-r--r--source/blender/editors/object/object_remesh.cc38
-rw-r--r--source/blender/editors/object/object_select.c60
-rw-r--r--source/blender/editors/object/object_transform.cc73
-rw-r--r--source/blender/editors/object/object_utils.c33
-rw-r--r--source/blender/editors/object/object_vgroup.cc254
-rw-r--r--source/blender/editors/object/object_warp.c2
-rw-r--r--source/blender/editors/physics/dynamicpaint_ops.c10
-rw-r--r--source/blender/editors/physics/particle_edit.c42
-rw-r--r--source/blender/editors/physics/particle_edit_undo.c2
-rw-r--r--source/blender/editors/physics/particle_object.c27
-rw-r--r--source/blender/editors/physics/physics_fluid.c50
-rw-r--r--source/blender/editors/physics/physics_pointcache.c6
-rw-r--r--source/blender/editors/physics/rigidbody_constraint.c2
-rw-r--r--source/blender/editors/render/render_internal.cc53
-rw-r--r--source/blender/editors/render/render_opengl.cc4
-rw-r--r--source/blender/editors/render/render_preview.cc88
-rw-r--r--source/blender/editors/render/render_shading.cc64
-rw-r--r--source/blender/editors/render/render_update.cc6
-rw-r--r--source/blender/editors/render/render_view.cc6
-rw-r--r--source/blender/editors/scene/scene_edit.c3
-rw-r--r--source/blender/editors/screen/CMakeLists.txt1
-rw-r--r--source/blender/editors/screen/area.c18
-rw-r--r--source/blender/editors/screen/screen_context.c127
-rw-r--r--source/blender/editors/screen/screen_edit.c11
-rw-r--r--source/blender/editors/screen/screen_intern.h2
-rw-r--r--source/blender/editors/screen/screen_ops.c33
-rw-r--r--source/blender/editors/screen/screen_user_menu.c2
-rw-r--r--source/blender/editors/screen/screendump.c5
-rw-r--r--source/blender/editors/screen/workspace_edit.c5
-rw-r--r--source/blender/editors/screen/workspace_listen.cc37
-rw-r--r--source/blender/editors/sculpt_paint/CMakeLists.txt2
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_add.cc10
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_brush.cc45
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_density.cc18
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc6
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_intern.hh18
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_ops.cc33
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_puff.cc3
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_slide.cc14
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc10
-rw-r--r--source/blender/editors/sculpt_paint/paint_canvas.cc1
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c52
-rw-r--r--source/blender/editors/sculpt_paint/paint_curve.c5
-rw-r--r--source/blender/editors/sculpt_paint/paint_curve_undo.c7
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c3
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.cc30
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c12
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d_curve_mask.cc19
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_ops_paint.cc25
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c56
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h2
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c42
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c26
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c9
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.cc171
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc37
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_proj.c1
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c11
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c636
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_automasking.cc673
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_boundary.c44
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_brush_types.c302
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_cloth.c101
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_detail.c15
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_dyntopo.c68
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_expand.c33
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_face_set.cc (renamed from source/blender/editors/sculpt_paint/sculpt_face_set.c)657
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_color.c37
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mask.c187
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mesh.c138
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_geodesic.c30
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h94
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_mask_expand.c23
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_mask_init.c14
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c34
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_ops.c439
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_paint_color.c58
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_paint_image.cc29
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_pose.c14
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_smooth.c58
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_transform.c17
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c171
-rw-r--r--source/blender/editors/space_action/CMakeLists.txt6
-rw-r--r--source/blender/editors/space_action/action_data.c5
-rw-r--r--source/blender/editors/space_action/action_draw.c2
-rw-r--r--source/blender/editors/space_action/action_edit.c2
-rw-r--r--source/blender/editors/space_action/action_select.c25
-rw-r--r--source/blender/editors/space_action/space_action.c32
-rw-r--r--source/blender/editors/space_buttons/CMakeLists.txt6
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c63
-rw-r--r--source/blender/editors/space_buttons/buttons_intern.h2
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c10
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c7
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c32
-rw-r--r--source/blender/editors/space_clip/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_clip/clip_buttons.c2
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_draw.c2
-rw-r--r--source/blender/editors/space_clip/clip_draw.c2
-rw-r--r--source/blender/editors/space_clip/clip_editor.c28
-rw-r--r--source/blender/editors/space_clip/clip_ops.c30
-rw-r--r--source/blender/editors/space_clip/space_clip.c26
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c3
-rw-r--r--source/blender/editors/space_clip/tracking_ops_orient.c3
-rw-r--r--source/blender/editors/space_clip/tracking_ops_solve.c2
-rw-r--r--source/blender/editors/space_clip/tracking_ops_track.c6
-rw-r--r--source/blender/editors/space_console/CMakeLists.txt7
-rw-r--r--source/blender/editors/space_console/console_intern.h2
-rw-r--r--source/blender/editors/space_console/console_ops.c2
-rw-r--r--source/blender/editors/space_console/space_console.c46
-rw-r--r--source/blender/editors/space_file/CMakeLists.txt12
-rw-r--r--source/blender/editors/space_file/asset_catalog_tree_view.cc2
-rw-r--r--source/blender/editors/space_file/file_draw.c75
-rw-r--r--source/blender/editors/space_file/file_indexer.cc17
-rw-r--r--source/blender/editors/space_file/file_intern.h23
-rw-r--r--source/blender/editors/space_file/file_ops.c100
-rw-r--r--source/blender/editors/space_file/filelist.cc (renamed from source/blender/editors/space_file/filelist.c)899
-rw-r--r--source/blender/editors/space_file/filelist.h11
-rw-r--r--source/blender/editors/space_file/filesel.c19
-rw-r--r--source/blender/editors/space_file/folder_history.cc199
-rw-r--r--source/blender/editors/space_file/fsmenu.c30
-rw-r--r--source/blender/editors/space_file/space_file.c55
-rw-r--r--source/blender/editors/space_graph/CMakeLists.txt6
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c44
-rw-r--r--source/blender/editors/space_graph/graph_draw.c2
-rw-r--r--source/blender/editors/space_graph/graph_edit.c52
-rw-r--r--source/blender/editors/space_graph/graph_select.c13
-rw-r--r--source/blender/editors/space_graph/graph_slider_ops.c15
-rw-r--r--source/blender/editors/space_graph/space_graph.c43
-rw-r--r--source/blender/editors/space_image/CMakeLists.txt6
-rw-r--r--source/blender/editors/space_image/image_buttons.c14
-rw-r--r--source/blender/editors/space_image/image_draw.c47
-rw-r--r--source/blender/editors/space_image/image_edit.c30
-rw-r--r--source/blender/editors/space_image/image_ops.c44
-rw-r--r--source/blender/editors/space_image/image_sequence.c8
-rw-r--r--source/blender/editors/space_image/image_undo.cc8
-rw-r--r--source/blender/editors/space_image/space_image.c55
-rw-r--r--source/blender/editors/space_info/CMakeLists.txt5
-rw-r--r--source/blender/editors/space_info/info_stats.cc40
-rw-r--r--source/blender/editors/space_info/space_info.c8
-rw-r--r--source/blender/editors/space_info/textview.c5
-rw-r--r--source/blender/editors/space_nla/CMakeLists.txt6
-rw-r--r--source/blender/editors/space_nla/nla_buttons.c11
-rw-r--r--source/blender/editors/space_nla/nla_channels.c6
-rw-r--r--source/blender/editors/space_nla/nla_draw.c30
-rw-r--r--source/blender/editors/space_nla/nla_edit.c19
-rw-r--r--source/blender/editors/space_nla/nla_select.c2
-rw-r--r--source/blender/editors/space_nla/space_nla.c35
-rw-r--r--source/blender/editors/space_node/CMakeLists.txt8
-rw-r--r--source/blender/editors/space_node/add_menu_assets.cc316
-rw-r--r--source/blender/editors/space_node/add_node_search.cc358
-rw-r--r--source/blender/editors/space_node/drawnode.cc142
-rw-r--r--source/blender/editors/space_node/link_drag_search.cc175
-rw-r--r--source/blender/editors/space_node/node_add.cc195
-rw-r--r--source/blender/editors/space_node/node_draw.cc123
-rw-r--r--source/blender/editors/space_node/node_edit.cc182
-rw-r--r--source/blender/editors/space_node/node_geometry_attribute_search.cc2
-rw-r--r--source/blender/editors/space_node/node_gizmo.cc24
-rw-r--r--source/blender/editors/space_node/node_group.cc99
-rw-r--r--source/blender/editors/space_node/node_intern.hh25
-rw-r--r--source/blender/editors/space_node/node_ops.cc16
-rw-r--r--source/blender/editors/space_node/node_relationships.cc600
-rw-r--r--source/blender/editors/space_node/node_select.cc37
-rw-r--r--source/blender/editors/space_node/node_templates.cc2
-rw-r--r--source/blender/editors/space_node/node_view.cc30
-rw-r--r--source/blender/editors/space_node/space_node.cc135
-rw-r--r--source/blender/editors/space_outliner/CMakeLists.txt6
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.cc36
-rw-r--r--source/blender/editors/space_outliner/outliner_context.cc2
-rw-r--r--source/blender/editors/space_outliner/outliner_dragdrop.cc24
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.cc223
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.cc74
-rw-r--r--source/blender/editors/space_outliner/outliner_select.cc89
-rw-r--r--source/blender/editors/space_outliner/outliner_sync.cc22
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.cc281
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.cc29
-rw-r--r--source/blender/editors/space_outliner/outliner_utils.cc3
-rw-r--r--source/blender/editors/space_outliner/space_outliner.cc133
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display.hh1
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display_override_library_hierarchies.cc2
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display_view_layer.cc5
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_rna.cc9
-rw-r--r--source/blender/editors/space_script/CMakeLists.txt7
-rw-r--r--source/blender/editors/space_script/space_script.c23
-rw-r--r--source/blender/editors/space_sequencer/CMakeLists.txt6
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c14
-rw-r--r--source/blender/editors/space_sequencer/sequencer_channels_draw.c6
-rw-r--r--source/blender/editors/space_sequencer/sequencer_drag_drop.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c23
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c7
-rw-r--r--source/blender/editors/space_sequencer/sequencer_preview.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_proxy.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_scopes.c6
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c16
-rw-r--r--source/blender/editors/space_sequencer/sequencer_thumbnails.c15
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c50
-rw-r--r--source/blender/editors/space_spreadsheet/CMakeLists.txt8
-rw-r--r--source/blender/editors/space_spreadsheet/space_spreadsheet.cc243
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_cache.cc11
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_column.cc3
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_context.cc591
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_context.hh13
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc156
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh2
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_draw.cc16
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_layout.cc19
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_ops.cc6
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc20
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc8
-rw-r--r--source/blender/editors/space_statusbar/CMakeLists.txt5
-rw-r--r--source/blender/editors/space_statusbar/space_statusbar.c8
-rw-r--r--source/blender/editors/space_text/CMakeLists.txt7
-rw-r--r--source/blender/editors/space_text/space_text.c22
-rw-r--r--source/blender/editors/space_text/text_autocomplete.c8
-rw-r--r--source/blender/editors/space_text/text_draw.c10
-rw-r--r--source/blender/editors/space_text/text_format_py.c2
-rw-r--r--source/blender/editors/space_text/text_ops.c6
-rw-r--r--source/blender/editors/space_topbar/CMakeLists.txt5
-rw-r--r--source/blender/editors/space_topbar/space_topbar.c8
-rw-r--r--source/blender/editors/space_userpref/CMakeLists.txt7
-rw-r--r--source/blender/editors/space_userpref/space_userpref.c8
-rw-r--r--source/blender/editors/space_view3d/CMakeLists.txt11
-rw-r--r--source/blender/editors/space_view3d/drawobject.c5
-rw-r--r--source/blender/editors/space_view3d/space_view3d.cc (renamed from source/blender/editors/space_view3d/space_view3d.c)389
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c39
-rw-r--r--source/blender/editors/space_view3d/view3d_camera_control.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_cursor_snap.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.cc (renamed from source/blender/editors/space_view3d/view3d_draw.c)327
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_armature.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_camera.c30
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_empty.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_forcefield.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_light.c28
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_navigate.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_preselect_type.cc (renamed from source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c)117
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_ruler.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h2
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.cc (renamed from source/blender/editors/space_view3d/view3d_iterators.c)151
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate.c49
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate.h8
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_dolly.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_fly.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_move.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_ndof.c18
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_rotate.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_smoothview.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_walk.c18
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_zoom.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_zoom_border.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_placement.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c33
-rw-r--r--source/blender/editors/space_view3d/view3d_select.cc506
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c69
-rw-r--r--source/blender/editors/space_view3d/view3d_utils.c23
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c43
-rw-r--r--source/blender/editors/transform/CMakeLists.txt2
-rw-r--r--source/blender/editors/transform/transform.c178
-rw-r--r--source/blender/editors/transform/transform.h19
-rw-r--r--source/blender/editors/transform/transform_constraints.c39
-rw-r--r--source/blender/editors/transform/transform_convert.c27
-rw-r--r--source/blender/editors/transform/transform_convert.h12
-rw-r--r--source/blender/editors/transform/transform_convert_action.c2
-rw-r--r--source/blender/editors/transform/transform_convert_armature.c11
-rw-r--r--source/blender/editors/transform/transform_convert_curve.c2
-rw-r--r--source/blender/editors/transform/transform_convert_gpencil.c3
-rw-r--r--source/blender/editors/transform/transform_convert_graph.c4
-rw-r--r--source/blender/editors/transform/transform_convert_lattice.c2
-rw-r--r--source/blender/editors/transform/transform_convert_mball.c2
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c7
-rw-r--r--source/blender/editors/transform/transform_convert_mesh_edge.c8
-rw-r--r--source/blender/editors/transform/transform_convert_mesh_skin.c2
-rw-r--r--source/blender/editors/transform/transform_convert_mesh_uv.c33
-rw-r--r--source/blender/editors/transform/transform_convert_mesh_vert_cdata.c6
-rw-r--r--source/blender/editors/transform/transform_convert_nla.c43
-rw-r--r--source/blender/editors/transform/transform_convert_node.cc (renamed from source/blender/editors/transform/transform_convert_node.c)81
-rw-r--r--source/blender/editors/transform/transform_convert_object.c73
-rw-r--r--source/blender/editors/transform/transform_convert_object_texspace.c5
-rw-r--r--source/blender/editors/transform/transform_convert_particle.c6
-rw-r--r--source/blender/editors/transform/transform_convert_sculpt.c17
-rw-r--r--source/blender/editors/transform/transform_convert_sequencer.c4
-rw-r--r--source/blender/editors/transform/transform_generics.c22
-rw-r--r--source/blender/editors/transform/transform_gizmo_2d.c2
-rw-r--r--source/blender/editors/transform/transform_gizmo_3d.c80
-rw-r--r--source/blender/editors/transform/transform_gizmo_extrude_3d.c2
-rw-r--r--source/blender/editors/transform/transform_mode.c4
-rw-r--r--source/blender/editors/transform/transform_mode_curveshrinkfatten.c22
-rw-r--r--source/blender/editors/transform/transform_mode_edge_slide.c6
-rw-r--r--source/blender/editors/transform/transform_mode_rotate.c2
-rw-r--r--source/blender/editors/transform/transform_mode_translate.c103
-rw-r--r--source/blender/editors/transform/transform_mode_vert_slide.c15
-rw-r--r--source/blender/editors/transform/transform_ops.c70
-rw-r--r--source/blender/editors/transform/transform_orientations.c33
-rw-r--r--source/blender/editors/transform/transform_orientations.h3
-rw-r--r--source/blender/editors/transform/transform_snap.c173
-rw-r--r--source/blender/editors/transform/transform_snap.h11
-rw-r--r--source/blender/editors/transform/transform_snap_animation.c2
-rw-r--r--source/blender/editors/transform/transform_snap_object.cc1279
-rw-r--r--source/blender/editors/transform/transform_snap_sequencer.c6
-rw-r--r--source/blender/editors/undo/ed_undo.c46
-rw-r--r--source/blender/editors/util/CMakeLists.txt2
-rw-r--r--source/blender/editors/util/ed_draw.c3
-rw-r--r--source/blender/editors/util/ed_transverts.c4
-rw-r--r--source/blender/editors/util/ed_util.c19
-rw-r--r--source/blender/editors/util/ed_util_imbuf.c10
-rw-r--r--source/blender/editors/util/ed_util_ops.cc10
-rw-r--r--source/blender/editors/util/ed_viewer_path.cc365
-rw-r--r--source/blender/editors/uvedit/uvedit_buttons.c4
-rw-r--r--source/blender/editors/uvedit/uvedit_islands.cc522
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c32
-rw-r--r--source/blender/editors/uvedit/uvedit_path.c6
-rw-r--r--source/blender/editors/uvedit/uvedit_rip.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_select.c66
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c40
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c204
-rw-r--r--source/blender/freestyle/CMakeLists.txt4
-rw-r--r--source/blender/freestyle/intern/application/AppCanvas.cpp18
-rw-r--r--source/blender/freestyle/intern/application/Controller.cpp30
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp58
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp9
-rw-r--r--source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp8
-rw-r--r--source/blender/freestyle/intern/geometry/Bezier.cpp2
-rw-r--r--source/blender/freestyle/intern/geometry/FastGrid.cpp4
-rw-r--r--source/blender/freestyle/intern/geometry/FitCurve.cpp10
-rw-r--r--source/blender/freestyle/intern/geometry/GeomCleaner.cpp74
-rw-r--r--source/blender/freestyle/intern/geometry/GeomUtils.cpp28
-rw-r--r--source/blender/freestyle/intern/geometry/Grid.cpp41
-rw-r--r--source/blender/freestyle/intern/geometry/HashGrid.cpp4
-rw-r--r--source/blender/freestyle/intern/geometry/Noise.cpp15
-rw-r--r--source/blender/freestyle/intern/image/GaussianFilter.cpp2
-rw-r--r--source/blender/freestyle/intern/image/ImagePyramid.cpp32
-rw-r--r--source/blender/freestyle/intern/python/BPy_BBox.cpp75
-rw-r--r--source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp77
-rw-r--r--source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp77
-rw-r--r--source/blender/freestyle/intern/python/BPy_ContextFunctions.cpp22
-rw-r--r--source/blender/freestyle/intern/python/BPy_Convert.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Freestyle.cpp18
-rw-r--r--source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp107
-rw-r--r--source/blender/freestyle/intern/python/BPy_FrsNoise.cpp85
-rw-r--r--source/blender/freestyle/intern/python/BPy_Id.cpp85
-rw-r--r--source/blender/freestyle/intern/python/BPy_IntegrationType.cpp93
-rw-r--r--source/blender/freestyle/intern/python/BPy_Interface0D.cpp91
-rw-r--r--source/blender/freestyle/intern/python/BPy_Interface1D.cpp91
-rw-r--r--source/blender/freestyle/intern/python/BPy_Iterator.cpp81
-rw-r--r--source/blender/freestyle/intern/python/BPy_MediumType.cpp75
-rw-r--r--source/blender/freestyle/intern/python/BPy_Nature.cpp145
-rw-r--r--source/blender/freestyle/intern/python/BPy_Operators.cpp83
-rw-r--r--source/blender/freestyle/intern/python/BPy_SShape.cpp97
-rw-r--r--source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp93
-rw-r--r--source/blender/freestyle/intern/python/BPy_StrokeShader.cpp77
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryFunction0D.cpp77
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryFunction1D.cpp77
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp77
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp77
-rw-r--r--source/blender/freestyle/intern/python/BPy_ViewMap.cpp79
-rw-r--r--source/blender/freestyle/intern/python/BPy_ViewShape.cpp101
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/Director.cpp6
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp93
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp101
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.cpp79
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp106
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.cpp79
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.cpp87
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp129
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp79
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp121
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.cpp119
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp75
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp115
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp95
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp80
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp75
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp75
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp82
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp81
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp85
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp81
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp81
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp91
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp77
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp81
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp81
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.cpp79
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp79
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp79
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp79
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp88
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp79
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp79
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp86
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp81
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.cpp79
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp74
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp79
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp79
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp79
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp75
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp75
-rw-r--r--source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp80
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeTransform.cpp9
-rw-r--r--source/blender/freestyle/intern/scene_graph/SceneHash.cpp26
-rw-r--r--source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp22
-rw-r--r--source/blender/freestyle/intern/stroke/AdvancedFunctions0D.cpp24
-rw-r--r--source/blender/freestyle/intern/stroke/AdvancedFunctions1D.cpp8
-rw-r--r--source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h2
-rw-r--r--source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp4
-rw-r--r--source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp40
-rw-r--r--source/blender/freestyle/intern/stroke/Canvas.cpp43
-rw-r--r--source/blender/freestyle/intern/stroke/Chain.cpp2
-rw-r--r--source/blender/freestyle/intern/stroke/ChainingIterators.cpp2
-rw-r--r--source/blender/freestyle/intern/stroke/ContextFunctions.cpp16
-rw-r--r--source/blender/freestyle/intern/stroke/Operators.cpp12
-rw-r--r--source/blender/freestyle/intern/stroke/Stroke.cpp16
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeRenderer.cpp6
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeRep.cpp8
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeTesselator.cpp2
-rw-r--r--source/blender/freestyle/intern/system/PseudoNoise.cpp14
-rw-r--r--source/blender/freestyle/intern/system/RandGen.cpp18
-rw-r--r--source/blender/freestyle/intern/system/StringUtils.cpp8
-rw-r--r--source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp11
-rw-r--r--source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp6
-rw-r--r--source/blender/freestyle/intern/view_map/BoxGrid.cpp16
-rw-r--r--source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp4
-rw-r--r--source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp20
-rw-r--r--source/blender/freestyle/intern/view_map/Functions0D.cpp16
-rw-r--r--source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp4
-rw-r--r--source/blender/freestyle/intern/view_map/Interface0D.cpp2
-rw-r--r--source/blender/freestyle/intern/view_map/OccluderSource.cpp4
-rw-r--r--source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp10
-rw-r--r--source/blender/freestyle/intern/view_map/Silhouette.cpp2
-rw-r--r--source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp6
-rw-r--r--source/blender/freestyle/intern/view_map/SphericalGrid.cpp16
-rw-r--r--source/blender/freestyle/intern/view_map/SteerableViewMap.cpp57
-rw-r--r--source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp40
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMap.cpp6
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp158
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp2
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapTesselator.h4
-rw-r--r--source/blender/freestyle/intern/winged_edge/Curvature.cpp4
-rw-r--r--source/blender/freestyle/intern/winged_edge/WEdge.cpp16
-rw-r--r--source/blender/freestyle/intern/winged_edge/WXEdge.cpp21
-rw-r--r--source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp6
-rw-r--r--source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp80
-rw-r--r--source/blender/functions/FN_field.hh4
-rw-r--r--source/blender/functions/FN_lazy_function.hh66
-rw-r--r--source/blender/functions/FN_lazy_function_execute.hh7
-rw-r--r--source/blender/functions/FN_multi_function.hh2
-rw-r--r--source/blender/functions/FN_multi_function_builder.hh11
-rw-r--r--source/blender/functions/intern/field.cc56
-rw-r--r--source/blender/functions/intern/lazy_function.cc7
-rw-r--r--source/blender/functions/intern/lazy_function_execute.cc7
-rw-r--r--source/blender/functions/intern/lazy_function_graph_executor.cc285
-rw-r--r--source/blender/functions/intern/multi_function_builder.cc16
-rw-r--r--source/blender/functions/intern/multi_function_procedure.cc4
-rw-r--r--source/blender/functions/intern/multi_function_procedure_executor.cc13
-rw-r--r--source/blender/functions/tests/FN_field_test.cc6
-rw-r--r--source/blender/functions/tests/FN_lazy_function_test.cc6
-rw-r--r--source/blender/functions/tests/FN_multi_function_test.cc4
-rw-r--r--source/blender/functions/tests/FN_multi_function_test_common.hh14
-rw-r--r--source/blender/geometry/CMakeLists.txt2
-rw-r--r--source/blender/geometry/GEO_resample_curves.hh15
-rw-r--r--source/blender/geometry/GEO_trim_curves.hh24
-rw-r--r--source/blender/geometry/intern/add_curves_on_mesh.cc9
-rw-r--r--source/blender/geometry/intern/fillet_curves.cc6
-rw-r--r--source/blender/geometry/intern/mesh_merge_by_distance.cc33
-rw-r--r--source/blender/geometry/intern/mesh_primitive_cuboid.cc6
-rw-r--r--source/blender/geometry/intern/mesh_to_curve_convert.cc16
-rw-r--r--source/blender/geometry/intern/mesh_to_volume.cc14
-rw-r--r--source/blender/geometry/intern/realize_instances.cc84
-rw-r--r--source/blender/geometry/intern/resample_curves.cc186
-rw-r--r--source/blender/geometry/intern/set_curve_type.cc13
-rw-r--r--source/blender/geometry/intern/trim_curves.cc1031
-rw-r--r--source/blender/geometry/intern/uv_parametrizer.cc44
-rw-r--r--source/blender/gpencil_modifiers/CMakeLists.txt1
-rw-r--r--source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h1
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c1
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c4
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c4
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c8
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencillength.c2
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c18
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c4
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilmultiply.c2
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpenciloutline.c343
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c211
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c2
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilweight_angle.c6
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilweight_proximity.c4
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h1
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c10
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_cpp_bridge.cc20
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c82
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c14
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c6
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_util.c4
-rw-r--r--source/blender/gpu/CMakeLists.txt128
-rw-r--r--source/blender/gpu/GPU_buffers.h157
-rw-r--r--source/blender/gpu/GPU_context.h4
-rw-r--r--source/blender/gpu/GPU_framebuffer.h9
-rw-r--r--source/blender/gpu/GPU_material.h41
-rw-r--r--source/blender/gpu/GPU_platform.h1
-rw-r--r--source/blender/gpu/GPU_shader.h8
-rw-r--r--source/blender/gpu/GPU_texture.h9
-rw-r--r--source/blender/gpu/GPU_uniform_buffer.h1
-rw-r--r--source/blender/gpu/intern/gpu_backend.hh2
-rw-r--r--source/blender/gpu/intern/gpu_batch.cc1
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c1475
-rw-r--r--source/blender/gpu/intern/gpu_codegen.cc12
-rw-r--r--source/blender/gpu/intern/gpu_context.cc39
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.cc18
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer_private.hh18
-rw-r--r--source/blender/gpu/intern/gpu_immediate.cc11
-rw-r--r--source/blender/gpu/intern/gpu_immediate_private.hh8
-rw-r--r--source/blender/gpu/intern/gpu_immediate_util.c8
-rw-r--r--source/blender/gpu/intern/gpu_index_buffer.cc6
-rw-r--r--source/blender/gpu/intern/gpu_init_exit.c8
-rw-r--r--source/blender/gpu/intern/gpu_material.c71
-rw-r--r--source/blender/gpu/intern/gpu_matrix.cc8
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.c115
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.h16
-rw-r--r--source/blender/gpu/intern/gpu_shader_builder.cc53
-rw-r--r--source/blender/gpu/intern/gpu_shader_builder_stubs.cc147
-rw-r--r--source/blender/gpu/intern/gpu_shader_builtin.c5
-rw-r--r--source/blender/gpu/intern/gpu_shader_create_info.cc26
-rw-r--r--source/blender/gpu/intern/gpu_shader_dependency.cc7
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.cc4
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.hh2
-rw-r--r--source/blender/gpu/intern/gpu_shader_log.cc6
-rw-r--r--source/blender/gpu/intern/gpu_state.cc30
-rw-r--r--source/blender/gpu/intern/gpu_texture.cc29
-rw-r--r--source/blender/gpu/intern/gpu_texture_private.hh10
-rw-r--r--source/blender/gpu/intern/gpu_vertex_buffer.cc2
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format.cc10
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c4
-rw-r--r--source/blender/gpu/metal/mtl_backend.hh2
-rw-r--r--source/blender/gpu/metal/mtl_backend.mm18
-rw-r--r--source/blender/gpu/metal/mtl_batch.hh135
-rw-r--r--source/blender/gpu/metal/mtl_batch.mm998
-rw-r--r--source/blender/gpu/metal/mtl_command_buffer.mm174
-rw-r--r--source/blender/gpu/metal/mtl_common.hh4
-rw-r--r--source/blender/gpu/metal/mtl_context.hh136
-rw-r--r--source/blender/gpu/metal/mtl_context.mm1192
-rw-r--r--source/blender/gpu/metal/mtl_drawlist.hh58
-rw-r--r--source/blender/gpu/metal/mtl_drawlist.mm284
-rw-r--r--source/blender/gpu/metal/mtl_immediate.hh40
-rw-r--r--source/blender/gpu/metal/mtl_immediate.mm401
-rw-r--r--source/blender/gpu/metal/mtl_index_buffer.mm2
-rw-r--r--source/blender/gpu/metal/mtl_memory.hh6
-rw-r--r--source/blender/gpu/metal/mtl_pso_descriptor_state.hh51
-rw-r--r--source/blender/gpu/metal/mtl_shader.hh2
-rw-r--r--source/blender/gpu/metal/mtl_shader.mm26
-rw-r--r--source/blender/gpu/metal/mtl_shader_generator.hh2
-rw-r--r--source/blender/gpu/metal/mtl_shader_generator.mm4
-rw-r--r--source/blender/gpu/metal/mtl_shader_interface.mm10
-rw-r--r--source/blender/gpu/metal/mtl_texture.hh41
-rw-r--r--source/blender/gpu/metal/mtl_texture.mm129
-rw-r--r--source/blender/gpu/metal/mtl_texture_util.mm32
-rw-r--r--source/blender/gpu/metal/mtl_vertex_buffer.hh75
-rw-r--r--source/blender/gpu/metal/mtl_vertex_buffer.mm368
-rw-r--r--source/blender/gpu/opengl/gl_backend.cc8
-rw-r--r--source/blender/gpu/opengl/gl_backend.hh2
-rw-r--r--source/blender/gpu/opengl/gl_batch.cc4
-rw-r--r--source/blender/gpu/opengl/gl_context.cc8
-rw-r--r--source/blender/gpu/opengl/gl_debug.cc12
-rw-r--r--source/blender/gpu/opengl/gl_framebuffer.cc9
-rw-r--r--source/blender/gpu/opengl/gl_framebuffer.hh2
-rw-r--r--source/blender/gpu/opengl/gl_index_buffer.hh6
-rw-r--r--source/blender/gpu/opengl/gl_shader.cc4
-rw-r--r--source/blender/gpu/opengl/gl_shader_interface.cc14
-rw-r--r--source/blender/gpu/opengl/gl_vertex_array.cc4
-rw-r--r--source/blender/gpu/opengl/gl_vertex_buffer.cc4
-rw-r--r--source/blender/gpu/shaders/common/gpu_shader_common_math.glsl2
-rw-r--r--source/blender/gpu/shaders/common/gpu_shader_common_math_utils.glsl2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl4
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_polyline_frag.glsl2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_polyline_geom.glsl6
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_polyline_vert.glsl2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_polyline_vert_no_geom.glsl162
-rw-r--r--source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_icon_frag.glsl42
-rw-r--r--source/blender/gpu/shaders/gpu_shader_icon_vert.glsl37
-rw-r--r--source/blender/gpu/shaders/gpu_shader_text_vert.glsl2
-rw-r--r--source/blender/gpu/shaders/infos/gpu_interface_info.hh3
-rw-r--r--source/blender/gpu/shaders/infos/gpu_shader_3D_polyline_info.hh41
-rw-r--r--source/blender/gpu/shaders/infos/gpu_shader_icon_info.hh22
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_attribute.glsl25
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl4
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_tex_sky.glsl44
-rw-r--r--source/blender/gpu/shaders/opengl/glsl_shader_defines.glsl2
-rw-r--r--source/blender/gpu/tests/gpu_testing.cc2
-rw-r--r--source/blender/gpu/vulkan/vk_backend.cc107
-rw-r--r--source/blender/gpu/vulkan/vk_backend.hh42
-rw-r--r--source/blender/gpu/vulkan/vk_batch.cc27
-rw-r--r--source/blender/gpu/vulkan/vk_batch.hh24
-rw-r--r--source/blender/gpu/vulkan/vk_context.cc48
-rw-r--r--source/blender/gpu/vulkan/vk_context.hh34
-rw-r--r--source/blender/gpu/vulkan/vk_drawlist.cc20
-rw-r--r--source/blender/gpu/vulkan/vk_drawlist.hh20
-rw-r--r--source/blender/gpu/vulkan/vk_framebuffer.cc62
-rw-r--r--source/blender/gpu/vulkan/vk_framebuffer.hh50
-rw-r--r--source/blender/gpu/vulkan/vk_index_buffer.cc33
-rw-r--r--source/blender/gpu/vulkan/vk_index_buffer.hh28
-rw-r--r--source/blender/gpu/vulkan/vk_query.cc28
-rw-r--r--source/blender/gpu/vulkan/vk_query.hh22
-rw-r--r--source/blender/gpu/vulkan/vk_shader.cc102
-rw-r--r--source/blender/gpu/vulkan/vk_shader.hh48
-rw-r--r--source/blender/gpu/vulkan/vk_storage_buffer.cc42
-rw-r--r--source/blender/gpu/vulkan/vk_storage_buffer.hh30
-rw-r--r--source/blender/gpu/vulkan/vk_texture.cc70
-rw-r--r--source/blender/gpu/vulkan/vk_texture.hh39
-rw-r--r--source/blender/gpu/vulkan/vk_uniform_buffer.cc24
-rw-r--r--source/blender/gpu/vulkan/vk_uniform_buffer.hh25
-rw-r--r--source/blender/gpu/vulkan/vk_vertex_buffer.cc58
-rw-r--r--source/blender/gpu/vulkan/vk_vertex_buffer.hh32
-rw-r--r--source/blender/ikplugin/intern/iksolver_plugin.c4
-rw-r--r--source/blender/ikplugin/intern/itasc_plugin.cpp50
-rw-r--r--source/blender/imbuf/IMB_imbuf.h13
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h2
-rw-r--r--source/blender/imbuf/IMB_thumbs.h2
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c2
-rw-r--r--source/blender/imbuf/intern/anim_movie.c23
-rw-r--r--source/blender/imbuf/intern/bmp.c2
-rw-r--r--source/blender/imbuf/intern/cache.c2
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.c2
-rw-r--r--source/blender/imbuf/intern/cineon/logImageCore.c2
-rw-r--r--source/blender/imbuf/intern/colormanagement.c77
-rw-r--r--source/blender/imbuf/intern/dds/ColorBlock.h4
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.cpp22
-rw-r--r--source/blender/imbuf/intern/imageprocess.c2
-rw-r--r--source/blender/imbuf/intern/indexer.c49
-rw-r--r--source/blender/imbuf/intern/iris.c2
-rw-r--r--source/blender/imbuf/intern/jp2.c29
-rw-r--r--source/blender/imbuf/intern/jpeg.c2
-rw-r--r--source/blender/imbuf/intern/oiio/openimageio_api.cpp2
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp88
-rw-r--r--source/blender/imbuf/intern/png.c2
-rw-r--r--source/blender/imbuf/intern/rectop.c4
-rw-r--r--source/blender/imbuf/intern/scaling.c10
-rw-r--r--source/blender/imbuf/intern/thumbs_font.c81
-rw-r--r--source/blender/imbuf/intern/tiff.c4
-rw-r--r--source/blender/imbuf/intern/transform.cc19
-rw-r--r--source/blender/imbuf/intern/util_gpu.c27
-rw-r--r--source/blender/imbuf/intern/webp.c2
-rw-r--r--source/blender/io/alembic/exporter/abc_archive.cc4
-rw-r--r--source/blender/io/alembic/exporter/abc_export_capi.cc10
-rw-r--r--source/blender/io/alembic/exporter/abc_subdiv_disabler.cc4
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_curves.cc2
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_hair.cc6
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_mesh.cc9
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_points.cc9
-rw-r--r--source/blender/io/alembic/intern/abc_axis_conversion.cc8
-rw-r--r--source/blender/io/alembic/intern/abc_customdata.cc4
-rw-r--r--source/blender/io/alembic/intern/abc_reader_camera.cc18
-rw-r--r--source/blender/io/alembic/intern/abc_reader_curves.cc2
-rw-r--r--source/blender/io/alembic/intern/abc_reader_mesh.cc25
-rw-r--r--source/blender/io/alembic/intern/abc_reader_object.cc14
-rw-r--r--source/blender/io/alembic/intern/abc_reader_transform.cc2
-rw-r--r--source/blender/io/alembic/intern/abc_util.cc4
-rw-r--r--source/blender/io/alembic/intern/alembic_capi.cc24
-rw-r--r--source/blender/io/avi/intern/avi.c18
-rw-r--r--source/blender/io/avi/intern/avi_codecs.c6
-rw-r--r--source/blender/io/avi/intern/avi_mjpeg.c53
-rw-r--r--source/blender/io/avi/intern/avi_mjpeg.h7
-rw-r--r--source/blender/io/avi/intern/avi_rgb.c25
-rw-r--r--source/blender/io/avi/intern/avi_rgb32.c14
-rw-r--r--source/blender/io/collada/AnimationExporter.cpp5
-rw-r--r--source/blender/io/collada/AnimationImporter.cpp108
-rw-r--r--source/blender/io/collada/ArmatureImporter.cpp12
-rw-r--r--source/blender/io/collada/BCAnimationCurve.cpp13
-rw-r--r--source/blender/io/collada/BCMath.cpp8
-rw-r--r--source/blender/io/collada/BCSampleData.cpp2
-rw-r--r--source/blender/io/collada/BlenderContext.cpp28
-rw-r--r--source/blender/io/collada/BlenderContext.h8
-rw-r--r--source/blender/io/collada/CMakeLists.txt9
-rw-r--r--source/blender/io/collada/CameraExporter.cpp4
-rw-r--r--source/blender/io/collada/ControllerExporter.cpp4
-rw-r--r--source/blender/io/collada/DocumentExporter.cpp2
-rw-r--r--source/blender/io/collada/DocumentImporter.cpp40
-rw-r--r--source/blender/io/collada/EffectExporter.cpp2
-rw-r--r--source/blender/io/collada/ExportSettings.h7
-rw-r--r--source/blender/io/collada/ExtraHandler.cpp4
-rw-r--r--source/blender/io/collada/ExtraTags.cpp6
-rw-r--r--source/blender/io/collada/GeometryExporter.cpp24
-rw-r--r--source/blender/io/collada/ImageExporter.cpp2
-rw-r--r--source/blender/io/collada/ImportSettings.h1
-rw-r--r--source/blender/io/collada/MeshImporter.cpp156
-rw-r--r--source/blender/io/collada/MeshImporter.h5
-rw-r--r--source/blender/io/collada/SceneExporter.cpp8
-rw-r--r--source/blender/io/collada/SkinInfo.cpp20
-rw-r--r--source/blender/io/collada/TransformReader.cpp14
-rw-r--r--source/blender/io/collada/collada.cpp4
-rw-r--r--source/blender/io/collada/collada_internal.cpp14
-rw-r--r--source/blender/io/collada/collada_utils.cpp23
-rw-r--r--source/blender/io/common/intern/abstract_hierarchy_iterator.cc11
-rw-r--r--source/blender/io/common/intern/path_util.cc3
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_base.cc27
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_base.hh2
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_capi.cc2
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc4
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_export_svg.cc9
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_import_base.cc2
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_import_svg.cc22
-rw-r--r--source/blender/io/stl/CMakeLists.txt2
-rw-r--r--source/blender/io/stl/importer/stl_import.cc3
-rw-r--r--source/blender/io/stl/importer/stl_import_ascii_reader.cc2
-rw-r--r--source/blender/io/usd/CMakeLists.txt16
-rw-r--r--source/blender/io/usd/intern/usd_capi_export.cc11
-rw-r--r--source/blender/io/usd/intern/usd_capi_import.cc21
-rw-r--r--source/blender/io/usd/intern/usd_hierarchy_iterator.cc2
-rw-r--r--source/blender/io/usd/intern/usd_reader_camera.cc2
-rw-r--r--source/blender/io/usd/intern/usd_reader_curve.cc6
-rw-r--r--source/blender/io/usd/intern/usd_reader_curve.h2
-rw-r--r--source/blender/io/usd/intern/usd_reader_light.cc4
-rw-r--r--source/blender/io/usd/intern/usd_reader_material.cc2
-rw-r--r--source/blender/io/usd/intern/usd_reader_mesh.cc39
-rw-r--r--source/blender/io/usd/intern/usd_reader_nurbs.cc10
-rw-r--r--source/blender/io/usd/intern/usd_reader_nurbs.h2
-rw-r--r--source/blender/io/usd/intern/usd_reader_volume.cc6
-rw-r--r--source/blender/io/usd/intern/usd_reader_volume.h2
-rw-r--r--source/blender/io/usd/intern/usd_writer_hair.cc2
-rw-r--r--source/blender/io/usd/intern/usd_writer_material.cc16
-rw-r--r--source/blender/io/usd/intern/usd_writer_mesh.cc26
-rw-r--r--source/blender/io/usd/intern/usd_writer_volume.cc4
-rw-r--r--source/blender/io/usd/tests/usd_imaging_test.cc7
-rw-r--r--source/blender/io/usd/tests/usd_tests_common.cc2
-rw-r--r--source/blender/io/wavefront_obj/CMakeLists.txt4
-rw-r--r--source/blender/io/wavefront_obj/IO_wavefront_obj.h3
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc28
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc35
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh7
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc10
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh6
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc12
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_nurbs.hh2
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_exporter.cc11
-rw-r--r--source/blender/io/wavefront_obj/importer/importer_mesh_utils.cc3
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc32
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_mesh.cc14
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_mtl.cc8
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_objects.hh2
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc4
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_importer.cc12
-rw-r--r--source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc4
-rw-r--r--source/blender/io/wavefront_obj/tests/obj_exporter_tests.hh2
-rw-r--r--source/blender/io/wavefront_obj/tests/obj_importer_tests.cc89
-rw-r--r--source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc2
-rw-r--r--source/blender/makesdna/DNA_ID.h2
-rw-r--r--source/blender/makesdna/DNA_asset_types.h6
-rw-r--r--source/blender/makesdna/DNA_brush_defaults.h2
-rw-r--r--source/blender/makesdna/DNA_brush_enums.h27
-rw-r--r--source/blender/makesdna/DNA_brush_types.h12
-rw-r--r--source/blender/makesdna/DNA_collection_types.h1
-rw-r--r--source/blender/makesdna/DNA_color_types.h3
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h2
-rw-r--r--source/blender/makesdna/DNA_customdata_types.h12
-rw-r--r--source/blender/makesdna/DNA_fileglobal_types.h4
-rw-r--r--source/blender/makesdna/DNA_gpencil_modifier_defaults.h25
-rw-r--r--source/blender/makesdna/DNA_gpencil_modifier_types.h56
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h14
-rw-r--r--source/blender/makesdna/DNA_layer_types.h37
-rw-r--r--source/blender/makesdna/DNA_lightprobe_types.h1
-rw-r--r--source/blender/makesdna/DNA_mesh_types.h172
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h33
-rw-r--r--source/blender/makesdna/DNA_meta_types.h4
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h78
-rw-r--r--source/blender/makesdna/DNA_node_types.h65
-rw-r--r--source/blender/makesdna/DNA_object_defaults.h2
-rw-r--r--source/blender/makesdna/DNA_object_types.h13
-rw-r--r--source/blender/makesdna/DNA_particle_types.h8
-rw-r--r--source/blender/makesdna/DNA_scene_types.h45
-rw-r--r--source/blender/makesdna/DNA_screen_types.h4
-rw-r--r--source/blender/makesdna/DNA_sequence_types.h2
-rw-r--r--source/blender/makesdna/DNA_sound_types.h2
-rw-r--r--source/blender/makesdna/DNA_space_types.h84
-rw-r--r--source/blender/makesdna/DNA_texture_types.h2
-rw-r--r--source/blender/makesdna/DNA_userdef_enums.h1
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h3
-rw-r--r--source/blender/makesdna/DNA_view2d_types.h18
-rw-r--r--source/blender/makesdna/DNA_view3d_defaults.h4
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h12
-rw-r--r--source/blender/makesdna/DNA_viewer_path_types.h40
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h29
-rw-r--r--source/blender/makesdna/DNA_workspace_types.h16
-rw-r--r--source/blender/makesdna/intern/CMakeLists.txt42
-rw-r--r--source/blender/makesdna/intern/dna_defaults.c4
-rw-r--r--source/blender/makesdna/intern/dna_genfile.c18
-rw-r--r--source/blender/makesdna/intern/dna_rename_defs.h8
-rw-r--r--source/blender/makesdna/intern/makesdna.c2
-rw-r--r--source/blender/makesrna/RNA_access.h4
-rw-r--r--source/blender/makesrna/RNA_enum_items.h3
-rw-r--r--source/blender/makesrna/RNA_types.h14
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt64
-rw-r--r--source/blender/makesrna/intern/makesrna.c8
-rw-r--r--source/blender/makesrna/intern/rna_ID.c31
-rw-r--r--source/blender/makesrna/intern/rna_access.c14
-rw-r--r--source/blender/makesrna/intern/rna_access_compare_override.c1
-rw-r--r--source/blender/makesrna/intern/rna_animation.c1
-rw-r--r--source/blender/makesrna/intern/rna_armature.c12
-rw-r--r--source/blender/makesrna/intern/rna_asset.c7
-rw-r--r--source/blender/makesrna/intern/rna_attribute.c62
-rw-r--r--source/blender/makesrna/intern/rna_brush.c173
-rw-r--r--source/blender/makesrna/intern/rna_collection.c5
-rw-r--r--source/blender/makesrna/intern/rna_color.c25
-rw-r--r--source/blender/makesrna/intern/rna_curve.c19
-rw-r--r--source/blender/makesrna/intern/rna_curves.c61
-rw-r--r--source/blender/makesrna/intern/rna_define.c8
-rw-r--r--source/blender/makesrna/intern/rna_depsgraph.c43
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c2
-rw-r--r--source/blender/makesrna/intern/rna_fluid.c122
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c8
-rw-r--r--source/blender/makesrna/intern/rna_gpencil_modifier.c281
-rw-r--r--source/blender/makesrna/intern/rna_image.c6
-rw-r--r--source/blender/makesrna/intern/rna_internal.h6
-rw-r--r--source/blender/makesrna/intern/rna_layer.c90
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_material.c21
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c329
-rw-r--r--source/blender/makesrna/intern/rna_nla.c2
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c272
-rw-r--r--source/blender/makesrna/intern/rna_object.c20
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c101
-rw-r--r--source/blender/makesrna/intern/rna_particle.c8
-rw-r--r--source/blender/makesrna/intern/rna_path.cc8
-rw-r--r--source/blender/makesrna/intern/rna_pointcloud.c40
-rw-r--r--source/blender/makesrna/intern/rna_rna.c15
-rw-r--r--source/blender/makesrna/intern/rna_scene.c75
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c190
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c12
-rw-r--r--source/blender/makesrna/intern/rna_space.c267
-rw-r--r--source/blender/makesrna/intern/rna_space_api.c6
-rw-r--r--source/blender/makesrna/intern/rna_test.c2
-rw-r--r--source/blender/makesrna/intern/rna_text.c1
-rw-r--r--source/blender/makesrna/intern/rna_texture.c5
-rw-r--r--source/blender/makesrna/intern/rna_tracking.c7
-rw-r--r--source/blender/makesrna/intern/rna_ui_api.c4
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c32
-rw-r--r--source/blender/makesrna/intern/rna_wm.c39
-rw-r--r--source/blender/makesrna/intern/rna_xr.c2
-rw-r--r--source/blender/modifiers/CMakeLists.txt24
-rw-r--r--source/blender/modifiers/MOD_modifiertypes.h4
-rw-r--r--source/blender/modifiers/intern/MOD_armature.c4
-rw-r--r--source/blender/modifiers/intern/MOD_array.c8
-rw-r--r--source/blender/modifiers/intern/MOD_bevel.c4
-rw-r--r--source/blender/modifiers/intern/MOD_boolean.cc48
-rw-r--r--source/blender/modifiers/intern/MOD_cast.c23
-rw-r--r--source/blender/modifiers/intern/MOD_cloth.c4
-rw-r--r--source/blender/modifiers/intern/MOD_collision.c4
-rw-r--r--source/blender/modifiers/intern/MOD_correctivesmooth.c223
-rw-r--r--source/blender/modifiers/intern/MOD_curve.c4
-rw-r--r--source/blender/modifiers/intern/MOD_datatransfer.cc (renamed from source/blender/modifiers/intern/MOD_datatransfer.c)138
-rw-r--r--source/blender/modifiers/intern/MOD_decimate.c4
-rw-r--r--source/blender/modifiers/intern/MOD_displace.c6
-rw-r--r--source/blender/modifiers/intern/MOD_dynamicpaint.c4
-rw-r--r--source/blender/modifiers/intern/MOD_explode.c17
-rw-r--r--source/blender/modifiers/intern/MOD_fluid.c4
-rw-r--r--source/blender/modifiers/intern/MOD_hook.c12
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciandeform.c4
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciansmooth.c6
-rw-r--r--source/blender/modifiers/intern/MOD_lattice.c4
-rw-r--r--source/blender/modifiers/intern/MOD_mask.cc16
-rw-r--r--source/blender/modifiers/intern/MOD_mesh_to_volume.cc6
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c8
-rw-r--r--source/blender/modifiers/intern/MOD_meshsequencecache.cc12
-rw-r--r--source/blender/modifiers/intern/MOD_multires.cc (renamed from source/blender/modifiers/intern/MOD_multires.c)111
-rw-r--r--source/blender/modifiers/intern/MOD_nodes.cc176
-rw-r--r--source/blender/modifiers/intern/MOD_normal_edit.cc (renamed from source/blender/modifiers/intern/MOD_normal_edit.c)138
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c9
-rw-r--r--source/blender/modifiers/intern/MOD_particleinstance.c13
-rw-r--r--source/blender/modifiers/intern/MOD_particlesystem.cc10
-rw-r--r--source/blender/modifiers/intern/MOD_remesh.c5
-rw-r--r--source/blender/modifiers/intern/MOD_screw.c116
-rw-r--r--source/blender/modifiers/intern/MOD_shrinkwrap.c4
-rw-r--r--source/blender/modifiers/intern/MOD_simpledeform.c4
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c8
-rw-r--r--source/blender/modifiers/intern/MOD_smooth.c4
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c19
-rw-r--r--source/blender/modifiers/intern/MOD_solidify_extrude.c26
-rw-r--r--source/blender/modifiers/intern/MOD_solidify_nonmanifold.c61
-rw-r--r--source/blender/modifiers/intern/MOD_subsurf.cc (renamed from source/blender/modifiers/intern/MOD_subsurf.c)94
-rw-r--r--source/blender/modifiers/intern/MOD_surface.c2
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c12
-rw-r--r--source/blender/modifiers/intern/MOD_triangulate.c2
-rw-r--r--source/blender/modifiers/intern/MOD_ui_common.c28
-rw-r--r--source/blender/modifiers/intern/MOD_util.cc (renamed from source/blender/modifiers/intern/MOD_util.c)56
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.cc (renamed from source/blender/modifiers/intern/MOD_uvproject.c)82
-rw-r--r--source/blender/modifiers/intern/MOD_uvwarp.cc (renamed from source/blender/modifiers/intern/MOD_uvwarp.c)97
-rw-r--r--source/blender/modifiers/intern/MOD_volume_displace.cc11
-rw-r--r--source/blender/modifiers/intern/MOD_volume_to_mesh.cc6
-rw-r--r--source/blender/modifiers/intern/MOD_warp.c10
-rw-r--r--source/blender/modifiers/intern/MOD_wave.cc (renamed from source/blender/modifiers/intern/MOD_wave.c)123
-rw-r--r--source/blender/modifiers/intern/MOD_weighted_normal.cc (renamed from source/blender/modifiers/intern/MOD_weighted_normal.c)214
-rw-r--r--source/blender/modifiers/intern/MOD_weightvg_util.h8
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgedit.cc (renamed from source/blender/modifiers/intern/MOD_weightvgedit.c)71
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgmix.cc (renamed from source/blender/modifiers/intern/MOD_weightvgmix.c)88
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgproximity.cc (renamed from source/blender/modifiers/intern/MOD_weightvgproximity.c)153
-rw-r--r--source/blender/modifiers/intern/MOD_weld.cc8
-rw-r--r--source/blender/modifiers/intern/MOD_wireframe.c4
-rw-r--r--source/blender/nodes/CMakeLists.txt17
-rw-r--r--source/blender/nodes/NOD_geometry.h19
-rw-r--r--source/blender/nodes/NOD_geometry_exec.hh4
-rw-r--r--source/blender/nodes/NOD_geometry_nodes_lazy_function.hh13
-rw-r--r--source/blender/nodes/NOD_geometry_nodes_log.hh39
-rw-r--r--source/blender/nodes/NOD_node_declaration.hh21
-rw-r--r--source/blender/nodes/NOD_static_types.h21
-rw-r--r--source/blender/nodes/composite/CMakeLists.txt2
-rw-r--r--source/blender/nodes/composite/node_composite_tree.cc15
-rw-r--r--source/blender/nodes/composite/node_composite_util.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_alpha_over.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_antialiasing.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_bilateralblur.cc8
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_blur.cc233
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_bokehblur.cc69
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_bokehimage.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_boxmask.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_brightness.cc8
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_channel_matte.cc8
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_chroma_matte.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_color_matte.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_color_spill.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_colorbalance.cc14
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_colorcorrection.cc10
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_common.cc2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_composite.cc2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_crop.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc13
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_curves.cc17
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_defocus.cc4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_denoise.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_despeckle.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_diff_matte.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_dilate.cc195
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_directionalblur.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_distance_matte.cc8
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_double_edge_mask.cc2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_filter.cc2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_flip.cc2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_glare.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_huecorrect.cc4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_id_mask.cc2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_image.cc27
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_inpaint.cc2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_invert.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_keying.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_lensdist.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_levels.cc150
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_luma_matte.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_map_range.cc2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_map_uv.cc2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_map_value.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_mask.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_math.cc2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_moviedistortion.cc4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_normalize.cc47
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_output_file.cc8
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_pixelate.cc5
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_premulkey.cc2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_rotate.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_scale.cc5
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_scene_time.cc2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_sepcomb_color.cc14
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_sepcomb_hsva.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_sepcomb_rgba.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_sepcomb_ycca.cc14
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_sepcomb_yuva.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_setalpha.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_split_viewer.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_sunbeams.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_switch.cc2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_switchview.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_tonemap.cc254
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_transform.cc2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_translate.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_val_to_rgb.cc4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_vec_blur.cc6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_viewer.cc8
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_zcombine.cc2
-rw-r--r--source/blender/nodes/function/node_function_util.cc2
-rw-r--r--source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc4
-rw-r--r--source/blender/nodes/function/nodes/node_fn_boolean_math.cc6
-rw-r--r--source/blender/nodes/function/nodes/node_fn_combine_color.cc10
-rw-r--r--source/blender/nodes/function/nodes/node_fn_compare.cc10
-rw-r--r--source/blender/nodes/function/nodes/node_fn_float_to_int.cc12
-rw-r--r--source/blender/nodes/function/nodes/node_fn_input_bool.cc6
-rw-r--r--source/blender/nodes/function/nodes/node_fn_input_color.cc6
-rw-r--r--source/blender/nodes/function/nodes/node_fn_input_int.cc6
-rw-r--r--source/blender/nodes/function/nodes/node_fn_input_special_characters.cc2
-rw-r--r--source/blender/nodes/function/nodes/node_fn_input_string.cc10
-rw-r--r--source/blender/nodes/function/nodes/node_fn_input_vector.cc6
-rw-r--r--source/blender/nodes/function/nodes/node_fn_random_value.cc10
-rw-r--r--source/blender/nodes/function/nodes/node_fn_rotate_euler.cc4
-rw-r--r--source/blender/nodes/function/nodes/node_fn_separate_color.cc16
-rw-r--r--source/blender/nodes/geometry/CMakeLists.txt33
-rw-r--r--source/blender/nodes/geometry/node_geometry_tree.cc15
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.cc6
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.hh29
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc30
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc49
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc8
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc18
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_boolean.cc11
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_collection_info.cc36
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_common.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc8
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc7
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc13
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_primitive_arc.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_primitive_bezier_segment.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_primitive_circle.cc16
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_primitive_line.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadrilateral.cc15
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_primitive_spiral.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc357
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc18
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc407
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc131
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc192
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc485
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc39
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc57
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_distribute_points_in_volume.cc288
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc34
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc46
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc63
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc117
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc125
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc3
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_geometry_to_instance.cc12
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_image_texture.cc62
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_instance_rotation.cc9
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_instance_scale.cc9
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_material.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc7
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc49
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc7
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc8
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_scene_time.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc7
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc7
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc58
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc7
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc16
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc43
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_material_selection.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc94
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc12
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc53
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc3
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc19
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc28
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_to_volume.cc25
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc199
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc219
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc146
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc221
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc126
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc118
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc84
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_object_info.cc20
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc169
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_points.cc5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc17
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_proximity.cc13
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_raycast.cc22
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc17
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_sample_index.cc337
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc342
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc278
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc294
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc17
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_self_object.cc29
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc8
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc12
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_curve_normal.cc73
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_id.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_position.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc73
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc46
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_switch.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc830
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_transform.cc19
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc19
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_triangulate.cc12
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc7
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc13
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_viewer.cc24
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_volume_cube.cc19
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc15
-rw-r--r--source/blender/nodes/intern/derived_node_tree.cc2
-rw-r--r--source/blender/nodes/intern/geometry_nodes_lazy_function.cc279
-rw-r--r--source/blender/nodes/intern/geometry_nodes_log.cc77
-rw-r--r--source/blender/nodes/intern/node_common.cc169
-rw-r--r--source/blender/nodes/intern/node_declaration.cc27
-rw-r--r--source/blender/nodes/intern/node_exec.cc2
-rw-r--r--source/blender/nodes/intern/node_exec.h4
-rw-r--r--source/blender/nodes/intern/node_geometry_exec.cc12
-rw-r--r--source/blender/nodes/intern/node_socket.cc26
-rw-r--r--source/blender/nodes/intern/node_socket_declarations.cc2
-rw-r--r--source/blender/nodes/intern/node_util.cc (renamed from source/blender/nodes/intern/node_util.c)16
-rw-r--r--source/blender/nodes/intern/socket_search_link.cc63
-rw-r--r--source/blender/nodes/shader/CMakeLists.txt26
-rw-r--r--source/blender/nodes/shader/node_shader_tree.cc29
-rw-r--r--source/blender/nodes/shader/node_shader_util.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_add_shader.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.cc12
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_attribute.cc27
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_background.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bevel.cc10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_blackbody.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_brightness.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.cc10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_hair.cc6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.cc16
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc12
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_toon.cc6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bump.cc6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_camera.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_clamp.cc10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_color_ramp.cc10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_common.cc6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_curves.cc45
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_displacement.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_eevee_specular.cc6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_emission.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_fresnel.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_gamma.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_geometry.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_hair_info.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_holdout.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_hueSatVal.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_ies_light.cc6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_invert.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_layer_weight.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_light_falloff.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_light_path.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_map_range.cc12
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mapping.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_math.cc6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mix.cc42
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mix_shader.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_normal.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_normal_map.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_object_info.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_aov.cc10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_light.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_linestyle.cc2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_material.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_world.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_particle_info.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_point_info.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_rgb.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_rgb_to_bw.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_script.cc10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcomb_color.cc22
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcomb_hsv.cc12
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc16
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_shader_to_rgb.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_squeeze.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.cc12
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tangent.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_brick.cc23
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_checker.cc21
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_coord.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc16
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.cc10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_magic.cc14
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc18
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_noise.cc16
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_pointdensity.cc10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_sky.cc70
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc24
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_wave.cc14
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc21
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_uv_along_stroke.cc2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_uvmap.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_value.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_displacement.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_math.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_transform.cc10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vertex_color.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_volume_absorption.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_volume_info.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_volume_principled.cc8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_volume_scatter.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_wavelength.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_wireframe.cc6
-rw-r--r--source/blender/nodes/texture/CMakeLists.txt17
-rw-r--r--source/blender/nodes/texture/node_texture_tree.c6
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_at.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_bricks.c4
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_checker.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_combine_color.c4
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_common.c6
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_compose.c5
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_coord.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_curves.c10
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_decompose.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_distance.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_hueSatVal.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_image.c4
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_invert.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_math.c4
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_mixRgb.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_output.c6
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_proc.c4
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_rotate.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_scale.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_separate_color.c4
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_texture.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_translate.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_valToNor.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_valToRgb.c6
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_viewer.c2
-rw-r--r--source/blender/python/CMakeLists.txt4
-rw-r--r--source/blender/python/bmesh/bmesh_py_api.c16
-rw-r--r--source/blender/python/bmesh/bmesh_py_geometry.c16
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops.c140
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.c4
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c66
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_customdata.c31
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_meshdata.c34
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_select.c30
-rw-r--r--source/blender/python/bmesh/bmesh_py_utils.c16
-rw-r--r--source/blender/python/generic/bgl.c187
-rw-r--r--source/blender/python/generic/bl_math_py_api.c16
-rw-r--r--source/blender/python/generic/blf_py_api.c33
-rw-r--r--source/blender/python/generic/idprop_py_api.c391
-rw-r--r--source/blender/python/generic/idprop_py_ui_api.c106
-rw-r--r--source/blender/python/generic/imbuf_py_api.c145
-rw-r--r--source/blender/python/generic/py_capi_utils.c10
-rw-r--r--source/blender/python/generic/py_capi_utils.h4
-rw-r--r--source/blender/python/gpu/gpu_py_api.c10
-rw-r--r--source/blender/python/gpu/gpu_py_batch.c13
-rw-r--r--source/blender/python/gpu/gpu_py_buffer.c55
-rw-r--r--source/blender/python/gpu/gpu_py_capabilities.c59
-rw-r--r--source/blender/python/gpu/gpu_py_element.c2
-rw-r--r--source/blender/python/gpu/gpu_py_framebuffer.c26
-rw-r--r--source/blender/python/gpu/gpu_py_matrix.c23
-rw-r--r--source/blender/python/gpu/gpu_py_platform.c40
-rw-r--r--source/blender/python/gpu/gpu_py_select.c13
-rw-r--r--source/blender/python/gpu/gpu_py_shader.c123
-rw-r--r--source/blender/python/gpu/gpu_py_shader_create_info.cc187
-rw-r--r--source/blender/python/gpu/gpu_py_state.c38
-rw-r--r--source/blender/python/gpu/gpu_py_texture.c15
-rw-r--r--source/blender/python/gpu/gpu_py_types.c9
-rw-r--r--source/blender/python/gpu/gpu_py_vertex_buffer.c12
-rw-r--r--source/blender/python/gpu/gpu_py_vertex_format.c8
-rw-r--r--source/blender/python/intern/bpy.c29
-rw-r--r--source/blender/python/intern/bpy.h2
-rw-r--r--source/blender/python/intern/bpy_app.c2
-rw-r--r--source/blender/python/intern/bpy_app_handlers.c90
-rw-r--r--source/blender/python/intern/bpy_app_icons.c16
-rw-r--r--source/blender/python/intern/bpy_app_timers.c16
-rw-r--r--source/blender/python/intern/bpy_app_translations.c128
-rw-r--r--source/blender/python/intern/bpy_driver.c2
-rw-r--r--source/blender/python/intern/bpy_gizmo_wrap.c2
-rw-r--r--source/blender/python/intern/bpy_gizmo_wrap.h2
-rw-r--r--source/blender/python/intern/bpy_interface.c16
-rw-r--r--source/blender/python/intern/bpy_interface_run.c2
-rw-r--r--source/blender/python/intern/bpy_library_load.c125
-rw-r--r--source/blender/python/intern/bpy_msgbus.c14
-rw-r--r--source/blender/python/intern/bpy_operator.c18
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.h5
-rw-r--r--source/blender/python/intern/bpy_path.c16
-rw-r--r--source/blender/python/intern/bpy_props.c29
-rw-r--r--source/blender/python/intern/bpy_rna.c1262
-rw-r--r--source/blender/python/intern/bpy_rna.h6
-rw-r--r--source/blender/python/intern/bpy_rna_array.c2
-rw-r--r--source/blender/python/intern/bpy_rna_data.c127
-rw-r--r--source/blender/python/intern/bpy_rna_operator.c2
-rw-r--r--source/blender/python/intern/bpy_rna_types_capi.c12
-rw-r--r--source/blender/python/intern/bpy_traceback.c2
-rw-r--r--source/blender/python/intern/bpy_utils_previews.c16
-rw-r--r--source/blender/python/intern/bpy_utils_units.c20
-rw-r--r--source/blender/python/mathutils/mathutils.c70
-rw-r--r--source/blender/python/mathutils/mathutils.h14
-rw-r--r--source/blender/python/mathutils/mathutils_Color.c229
-rw-r--r--source/blender/python/mathutils/mathutils_Euler.c149
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.c302
-rw-r--r--source/blender/python/mathutils/mathutils_Quaternion.c219
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.c248
-rw-r--r--source/blender/python/mathutils/mathutils_bvhtree.c111
-rw-r--r--source/blender/python/mathutils/mathutils_geometry.c25
-rw-r--r--source/blender/python/mathutils/mathutils_interpolate.c16
-rw-r--r--source/blender/python/mathutils/mathutils_kdtree.c112
-rw-r--r--source/blender/python/mathutils/mathutils_noise.c20
-rw-r--r--source/blender/render/RE_multires_bake.h4
-rw-r--r--source/blender/render/RE_pipeline.h6
-rw-r--r--source/blender/render/intern/bake.c12
-rw-r--r--source/blender/render/intern/engine.cc61
-rw-r--r--source/blender/render/intern/initrender.cc2
-rw-r--r--source/blender/render/intern/multires_bake.c36
-rw-r--r--source/blender/render/intern/pipeline.cc159
-rw-r--r--source/blender/render/intern/pipeline.h9
-rw-r--r--source/blender/render/intern/render_result.cc123
-rw-r--r--source/blender/render/intern/render_result.h5
-rw-r--r--source/blender/render/intern/render_types.h8
-rw-r--r--source/blender/render/intern/texture_image.c2
-rw-r--r--source/blender/render/intern/texture_margin.cc22
-rw-r--r--source/blender/render/intern/texture_pointdensity.c26
-rw-r--r--source/blender/sequencer/SEQ_proxy.h4
-rw-r--r--source/blender/sequencer/SEQ_render.h10
-rw-r--r--source/blender/sequencer/SEQ_time.h66
-rw-r--r--source/blender/sequencer/SEQ_transform.h1
-rw-r--r--source/blender/sequencer/intern/animation.c2
-rw-r--r--source/blender/sequencer/intern/disk_cache.c38
-rw-r--r--source/blender/sequencer/intern/effects.c215
-rw-r--r--source/blender/sequencer/intern/image_cache.c20
-rw-r--r--source/blender/sequencer/intern/image_cache.h2
-rw-r--r--source/blender/sequencer/intern/modifier.c92
-rw-r--r--source/blender/sequencer/intern/proxy.c12
-rw-r--r--source/blender/sequencer/intern/proxy_job.c4
-rw-r--r--source/blender/sequencer/intern/render.c64
-rw-r--r--source/blender/sequencer/intern/sequencer.c2
-rw-r--r--source/blender/sequencer/intern/sound.c3
-rw-r--r--source/blender/sequencer/intern/strip_add.c5
-rw-r--r--source/blender/sequencer/intern/strip_edit.c59
-rw-r--r--source/blender/sequencer/intern/strip_time.c71
-rw-r--r--source/blender/sequencer/intern/strip_time.h1
-rw-r--r--source/blender/sequencer/intern/strip_transform.c28
-rw-r--r--source/blender/sequencer/intern/utils.c4
-rw-r--r--source/blender/simulation/intern/SIM_mass_spring.cpp47
-rw-r--r--source/blender/simulation/intern/hair_volume.cpp78
-rw-r--r--source/blender/simulation/intern/implicit_blender.c110
-rw-r--r--source/blender/windowmanager/WM_api.h52
-rw-r--r--source/blender/windowmanager/WM_toolsystem.h8
-rw-r--r--source/blender/windowmanager/WM_types.h4
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c2
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c2
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.cc35
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c3
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.cc82
-rw-r--r--source/blender/windowmanager/intern/wm_files.c137
-rw-r--r--source/blender/windowmanager/intern/wm_files_link.c12
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c6
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c7
-rw-r--r--source/blender/windowmanager/intern/wm_jobs.c22
-rw-r--r--source/blender/windowmanager/intern/wm_operator_props.c18
-rw-r--r--source/blender/windowmanager/intern/wm_operator_type.c4
-rw-r--r--source/blender/windowmanager/intern/wm_operator_utils.c3
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c67
-rw-r--r--source/blender/windowmanager/intern/wm_platform_support.c2
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c21
-rw-r--r--source/blender/windowmanager/intern/wm_splash_screen.c4
-rw-r--r--source/blender/windowmanager/intern/wm_toolsystem.c57
-rw-r--r--source/blender/windowmanager/intern/wm_window.c269
-rw-r--r--source/blender/windowmanager/intern/wm_window_private.h5
-rw-r--r--source/blender/windowmanager/message_bus/intern/wm_message_bus_rna.c4
-rw-r--r--source/blender/windowmanager/message_bus/intern/wm_message_bus_static.c2
-rw-r--r--source/blender/windowmanager/wm.h4
-rw-r--r--source/blender/windowmanager/wm_event_system.h8
-rw-r--r--source/blender/windowmanager/wm_event_types.h55
-rw-r--r--source/blender/windowmanager/wm_files.h2
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr_action.c22
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr_draw.c7
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr_operators.c2
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr_session.c36
-rw-r--r--source/creator/CMakeLists.txt50
-rw-r--r--source/creator/creator.c42
-rw-r--r--source/creator/creator_args.c81
-rw-r--r--source/creator/creator_intern.h12
-rw-r--r--source/creator/creator_signals.c9
m---------source/tools0
-rw-r--r--tests/CMakeLists.txt25
-rw-r--r--tests/blender_as_python_module/CMakeLists.txt12
-rw-r--r--tests/blender_as_python_module/import_bpy.py4
-rw-r--r--tests/gtests/runner/CMakeLists.txt2
-rw-r--r--tests/python/CMakeLists.txt41
-rw-r--r--tests/python/bl_blendfile_io.py4
-rw-r--r--tests/python/bl_blendfile_liblink.py264
-rw-r--r--tests/python/bl_blendfile_library_overrides.py140
-rw-r--r--tests/python/bl_io_curve_svg_test.py64
-rw-r--r--tests/python/bl_keymap_validate.py2
-rw-r--r--tests/python/bl_load_addons.py8
-rw-r--r--tests/python/bl_load_py_modules.py4
-rw-r--r--tests/python/bl_mesh_modifiers.py6
-rw-r--r--tests/python/bl_pyapi_idprop.py2
-rw-r--r--tests/python/bl_rna_manual_reference.py8
-rw-r--r--tests/python/bl_run_operators.py2
-rw-r--r--tests/python/bl_run_operators_event_simulate.py2
-rw-r--r--tests/python/collada/CMakeLists.txt4
-rw-r--r--tests/python/cycles_render_tests.py4
-rw-r--r--tests/python/modifiers.py10
-rw-r--r--tests/python/modules/mesh_test.py96
-rwxr-xr-xtests/python/modules/render_report.py3
-rwxr-xr-xtests/python/modules/test_utils.py4
-rw-r--r--tests/python/view_layer/CMakeLists.txt254
3226 files changed, 93474 insertions, 62185 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 85e2a1450d8..30a186318ce 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -112,6 +112,25 @@ enable_testing()
# -----------------------------------------------------------------------------
+# Test Compiler Support
+#
+# Keep in sync with: https://wiki.blender.org/wiki/Building_Blender
+
+if(CMAKE_COMPILER_IS_GNUCC)
+ if("${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "9.3.1")
+ message(FATAL_ERROR "The minimum supported version of GCC is 9.3.1")
+ endif()
+elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
+ if(CMAKE_COMPILER_IS_GNUCC AND ("${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "8.0"))
+ message(FATAL_ERROR "The minimum supported version of CLANG is 8.0")
+ endif()
+elseif(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
+ if(MSVC_VERSION VERSION_LESS "1928")
+ message(FATAL_ERROR "The minimum supported version of MSVC is 2019 (16.9.16)")
+ endif()
+endif()
+
+# -----------------------------------------------------------------------------
# Test Compiler/Library Features
include(build_files/cmake/have_features.cmake)
@@ -158,8 +177,11 @@ option(WITH_INTERNATIONAL "Enable I18N (International fonts and text)" ON)
option(WITH_PYTHON "Enable Embedded Python API (only disable for development)" ON)
option(WITH_PYTHON_SECURITY "Disables execution of scripts within blend files by default" ON)
-mark_as_advanced(WITH_PYTHON) # don't want people disabling this unless they really know what they are doing.
-mark_as_advanced(WITH_PYTHON_SECURITY) # some distributions see this as a security issue, rather than have them patch it, make a build option.
+# Don't want people disabling this unless they really know what they are doing.
+mark_as_advanced(WITH_PYTHON)
+# Some distributions see this as a security issue, rather than have them patch it,
+# make a build option.
+mark_as_advanced(WITH_PYTHON_SECURITY)
option(WITH_PYTHON_SAFETY "Enable internal API error checking to track invalid data to prevent crash on access (at the expense of some efficiency, only enable for development)." OFF)
mark_as_advanced(WITH_PYTHON_SAFETY)
@@ -223,17 +245,17 @@ if(UNIX AND NOT (APPLE OR HAIKU))
option(WITH_GHOST_X11 "Enable building Blender against X11 for windowing" ON)
mark_as_advanced(WITH_GHOST_X11)
- option(WITH_GHOST_WAYLAND "Enable building Blender against Wayland for windowing (under development)" OFF)
+ option(WITH_GHOST_WAYLAND "Enable building Blender against Wayland for windowing" ON)
mark_as_advanced(WITH_GHOST_WAYLAND)
if(WITH_GHOST_WAYLAND)
- option(WITH_GHOST_WAYLAND_LIBDECOR "Optionally build with LibDecor window decorations" OFF)
+ option(WITH_GHOST_WAYLAND_LIBDECOR "Optionally build with LibDecor window decorations" ON)
mark_as_advanced(WITH_GHOST_WAYLAND_LIBDECOR)
option(WITH_GHOST_WAYLAND_DBUS "Optionally build with DBUS support (used for Cursor themes). May hang on startup systems where DBUS is not used." OFF)
mark_as_advanced(WITH_GHOST_WAYLAND_DBUS)
- option(WITH_GHOST_WAYLAND_DYNLOAD "Enable runtime dynamic WAYLAND libraries loading" OFF)
+ option(WITH_GHOST_WAYLAND_DYNLOAD "Enable runtime dynamic WAYLAND libraries loading" ON)
mark_as_advanced(WITH_GHOST_WAYLAND_DYNLOAD)
endif()
endif()
@@ -317,11 +339,9 @@ if(APPLE)
else()
set(WITH_COREAUDIO OFF)
endif()
-if(NOT WIN32)
+if(UNIX AND NOT APPLE)
option(WITH_JACK "Enable JACK Support (http://www.jackaudio.org)" ON)
- if(UNIX AND NOT APPLE)
- option(WITH_JACK_DYNLOAD "Enable runtime dynamic JACK libraries loading" OFF)
- endif()
+ option(WITH_JACK_DYNLOAD "Enable runtime dynamic JACK libraries loading" OFF)
else()
set(WITH_JACK OFF)
endif()
@@ -410,6 +430,7 @@ mark_as_advanced(WITH_CPU_SIMD)
# Cycles
option(WITH_CYCLES "Enable Cycles Render Engine" ON)
option(WITH_CYCLES_OSL "Build Cycles with OpenShadingLanguage support" ON)
+option(WITH_CYCLES_PATH_GUIDING "Build Cycles with path guiding support" ON)
option(WITH_CYCLES_EMBREE "Build Cycles with Embree support" ON)
option(WITH_CYCLES_LOGGING "Build Cycles with logging support" ON)
option(WITH_CYCLES_DEBUG "Build Cycles with options useful for debugging (e.g., MIS)" OFF)
@@ -469,13 +490,12 @@ endif()
if(NOT APPLE)
option(WITH_CYCLES_DEVICE_ONEAPI "Enable Cycles oneAPI compute support" OFF)
option(WITH_CYCLES_ONEAPI_BINARIES "Enable Ahead-Of-Time compilation for Cycles oneAPI device" OFF)
- option(WITH_CYCLES_ONEAPI_SYCL_HOST_ENABLED "Enable use of SYCL host (CPU) device execution by oneAPI implementation. This option is for debugging purposes and impacts GPU execution." OFF)
# https://www.intel.com/content/www/us/en/develop/documentation/oneapi-dpcpp-cpp-compiler-dev-guide-and-reference/top/compilation/ahead-of-time-compilation.html
- set(CYCLES_ONEAPI_SPIR64_GEN_DEVICES "dg2" CACHE STRING "oneAPI Intel GPU architectures to build binaries for")
+ # acm-g10 is the target for the first Intel Arc Alchemist GPUs.
+ set(CYCLES_ONEAPI_SPIR64_GEN_DEVICES "acm-g10" CACHE STRING "oneAPI Intel GPU architectures to build binaries for")
set(CYCLES_ONEAPI_SYCL_TARGETS spir64 spir64_gen CACHE STRING "oneAPI targets to build AOT binaries for")
- mark_as_advanced(WITH_CYCLES_ONEAPI_SYCL_HOST_ENABLED)
mark_as_advanced(CYCLES_ONEAPI_SPIR64_GEN_DEVICES)
mark_as_advanced(CYCLES_ONEAPI_SYCL_TARGETS)
endif()
@@ -533,6 +553,7 @@ endif()
option(WITH_GTESTS "Enable GTest unit testing" OFF)
option(WITH_OPENGL_RENDER_TESTS "Enable OpenGL render related unit testing (Experimental)" OFF)
option(WITH_OPENGL_DRAW_TESTS "Enable OpenGL UI drawing related unit testing (Experimental)" OFF)
+# NOTE: All callers of this must add `TEST_PYTHON_EXE_EXTRA_ARGS` before any other arguments.
set(TEST_PYTHON_EXE "" CACHE PATH "Python executable to run unit tests")
mark_as_advanced(TEST_PYTHON_EXE)
@@ -552,6 +573,12 @@ mark_as_advanced(
WITH_GPU_BUILDTIME_SHADER_BUILDER
)
+# Vulkan
+option(WITH_VULKAN_BACKEND "Enable Vulkan as graphics backend (only for development)" OFF)
+mark_as_advanced(
+ WITH_VULKAN_BACKEND
+)
+
# Metal
if(APPLE)
@@ -628,8 +655,8 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
unset(_asan_defaults)
if(MSVC)
- find_library(
- COMPILER_ASAN_LIBRARY NAMES clang_rt.asan-x86_64
+ find_library(
+ COMPILER_ASAN_LIBRARY NAMES clang_rt.asan-x86_64
PATHS
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\LLVM\\LLVM;]/lib/clang/7.0.0/lib/windows
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\LLVM\\LLVM;]/lib/clang/6.0.0/lib/windows
@@ -760,6 +787,8 @@ endif()
# -----------------------------------------------------------------------------
# Check for Conflicting/Unsupported Configurations
+option(WITH_STRICT_BUILD_OPTIONS "When requirements for a build option are not met, error instead of disabling the option" OFF)
+
if(NOT WITH_BLENDER AND NOT WITH_CYCLES_STANDALONE AND NOT WITH_CYCLES_HYDRA_RENDER_DELEGATE)
message(FATAL_ERROR
"At least one of WITH_BLENDER or WITH_CYCLES_STANDALONE "
@@ -808,7 +837,7 @@ endif()
set_and_warn_dependency(WITH_PUGIXML WITH_OPENIMAGEIO OFF)
if(WITH_BOOST AND NOT (WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_INTERNATIONAL OR
- WITH_OPENVDB OR WITH_OPENCOLORIO OR WITH_USD OR WITH_ALEMBIC))
+ WITH_OPENVDB OR WITH_OPENCOLORIO OR WITH_USD OR WITH_ALEMBIC))
message(STATUS "No dependencies need 'WITH_BOOST' forcing WITH_BOOST=OFF")
set(WITH_BOOST OFF)
endif()
@@ -875,10 +904,7 @@ endif()
if(WITH_BUILDINFO)
find_package(Git)
- if(NOT GIT_FOUND)
- message(WARNING "Git was not found, disabling WITH_BUILDINFO")
- set(WITH_BUILDINFO OFF)
- endif()
+ set_and_warn_library_found("Git" GIT_FOUND WITH_BUILDINFO)
endif()
if(WITH_AUDASPACE)
@@ -918,9 +944,10 @@ if(WITH_INTERNATIONAL)
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'."
+ "control systems."
)
- set(WITH_INTERNATIONAL OFF)
+ set(TRANSLATIONS_FOUND OFF)
+ set_and_warn_library_found("Translations" TRANSLATIONS_FOUND WITH_INTERNATIONAL)
endif()
endif()
@@ -1022,9 +1049,9 @@ if(WITH_CPU_SIMD)
set(COMPILER_SSE2_FLAG)
# Test Neon first since macOS Arm can compile and run x86-64 SSE binaries.
- TEST_NEON_SUPPORT()
+ test_neon_support()
if(NOT SUPPORT_NEON_BUILD)
- TEST_SSE_SUPPORT(COMPILER_SSE_FLAG COMPILER_SSE2_FLAG)
+ test_sse_support(COMPILER_SSE_FLAG COMPILER_SSE2_FLAG)
endif()
endif()
@@ -1089,7 +1116,7 @@ if(WITH_INTERNATIONAL)
endif()
endif()
-# Enable SIMD support if detected by TEST_SSE_SUPPORT() or TEST_NEON_SUPPORT().
+# Enable SIMD support if detected by `test_sse_support()` or `test_neon_support()`.
#
# This is done globally, so that all modules can use it if available, and
# because these are used in headers used by many modules.
@@ -1097,7 +1124,7 @@ if(WITH_CPU_SIMD)
if(SUPPORT_NEON_BUILD)
# Neon
if(SSE2NEON_FOUND)
- blender_include_dirs_sys("${SSE2NEON_INCLUDE_DIRS}")
+ include_directories(SYSTEM "${SSE2NEON_INCLUDE_DIRS}")
add_definitions(-DWITH_SSE2NEON)
endif()
else()
@@ -1206,6 +1233,13 @@ endif()
# -----------------------------------------------------------------------------
+# Configure Vulkan.
+
+if(WITH_VULKAN_BACKEND)
+ add_definitions(-DWITH_VULKAN_BACKEND)
+endif()
+
+# -----------------------------------------------------------------------------
# Configure Metal
if(WITH_METAL_BACKEND)
@@ -1225,6 +1259,8 @@ if(WITH_OPENMP)
find_package(OpenMP)
endif()
+ set_and_warn_library_found("OpenMP" OPENMP_FOUND WITH_OPENMP)
+
if(OPENMP_FOUND)
if(NOT WITH_OPENMP_STATIC)
string(APPEND CMAKE_C_FLAGS " ${OpenMP_C_FLAGS}")
@@ -1240,9 +1276,6 @@ if(WITH_OPENMP)
find_library_static(OpenMP_LIBRARIES gomp ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES})
endif()
- else()
- message(STATUS "OpenMP not found, disabling WITH_OPENMP")
- set(WITH_OPENMP OFF)
endif()
mark_as_advanced(
@@ -1257,10 +1290,7 @@ endif()
if(WITH_BULLET AND WITH_SYSTEM_BULLET)
find_package(Bullet)
- if(NOT BULLET_FOUND)
- message(STATUS "Bullet not found, disabling WITH_BULLET")
- set(WITH_BULLET OFF)
- endif()
+ set_and_warn_library_found("Bullet" BULLET_FOUND WITH_BULLET)
else()
set(BULLET_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/extern/bullet2/src")
# set(BULLET_LIBRARIES "")
@@ -1271,7 +1301,11 @@ endif()
# Configure Python
if(WITH_PYTHON_MODULE)
- add_definitions(-DPy_ENABLE_SHARED)
+ # Not currently supported due to different required Python link flags.
+ if(WITH_GTESTS)
+ message(STATUS "GTests not compatible with Python module, disabling WITH_GTESTS")
+ set(WITH_GTESTS OFF)
+ endif()
endif()
@@ -1399,91 +1433,75 @@ endif()
if(CMAKE_COMPILER_IS_GNUCC)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ALL -Wall)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ERROR_IMPLICIT_FUNCTION_DECLARATION -Werror=implicit-function-declaration)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ERROR_RETURN_TYPE -Werror=return-type)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ERROR_VLA -Werror=vla)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_ALL -Wall)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_ERROR_IMPLICIT_FUNCTION_DECLARATION -Werror=implicit-function-declaration)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_ERROR_RETURN_TYPE -Werror=return-type)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_ERROR_VLA -Werror=vla)
# system headers sometimes do this, disable for now, was: -Werror=strict-prototypes
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_STRICT_PROTOTYPES -Wstrict-prototypes)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_MISSING_PROTOTYPES -Wmissing-prototypes)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_POINTER_ARITH -Wpointer-arith)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNUSED_PARAMETER -Wunused-parameter)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_WRITE_STRINGS -Wwrite-strings)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_LOGICAL_OP -Wlogical-op)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNDEF -Wundef)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_INIT_SELF -Winit-self) # needs -Wuninitialized
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_MISSING_INCLUDE_DIRS -Wmissing-include-dirs)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_DIV_BY_ZERO -Wno-div-by-zero)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_TYPE_LIMITS -Wtype-limits)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_FORMAT_SIGN -Wformat-signedness)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_RESTRICT -Wrestrict)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_STRICT_PROTOTYPES -Wstrict-prototypes)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_MISSING_PROTOTYPES -Wmissing-prototypes)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_POINTER_ARITH -Wpointer-arith)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_UNUSED_PARAMETER -Wunused-parameter)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_WRITE_STRINGS -Wwrite-strings)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_LOGICAL_OP -Wlogical-op)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_UNDEF -Wundef)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_INIT_SELF -Winit-self) # needs -Wuninitialized
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_MISSING_INCLUDE_DIRS -Wmissing-include-dirs)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_DIV_BY_ZERO -Wno-div-by-zero)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_TYPE_LIMITS -Wtype-limits)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_FORMAT_SIGN -Wformat-signedness)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_RESTRICT -Wrestrict)
# C-only.
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_NULL -Wnonnull)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ABSOLUTE_VALUE -Wabsolute-value)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_NULL -Wnonnull)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_ABSOLUTE_VALUE -Wabsolute-value)
- # gcc 4.2 gives annoying warnings on every file with this
- if(NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "4.3")
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNINITIALIZED -Wuninitialized)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNINITIALIZED -Wuninitialized)
- endif()
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_UNINITIALIZED -Wuninitialized)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_UNINITIALIZED -Wuninitialized)
- # versions before gcc4.6 give many BLI_math warnings
- if(NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "4.6")
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_REDUNDANT_DECLS -Wredundant-decls)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_REDUNDANT_DECLS -Wredundant-decls)
- endif()
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_REDUNDANT_DECLS -Wredundant-decls)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_REDUNDANT_DECLS -Wredundant-decls)
- # versions before gcc4.8 include global name-space.
- if(NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "4.8")
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_SHADOW -Wshadow)
- endif()
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_SHADOW -Wshadow)
# disable because it gives warnings for printf() & friends.
- # ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_DOUBLE_PROMOTION -Wdouble-promotion -Wno-error=double-promotion)
+ # add_check_c_compiler_flag(C_WARNINGS C_WARN_DOUBLE_PROMOTION -Wdouble-promotion -Wno-error=double-promotion)
if(NOT APPLE)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable)
endif()
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_ALL -Wall)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_LOGICAL_OP -Wlogical-op)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_INIT_SELF -Winit-self) # needs -Wuninitialized
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_MISSING_INCLUDE_DIRS -Wmissing-include-dirs)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_DIV_BY_ZERO -Wno-div-by-zero)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_TYPE_LIMITS -Wtype-limits)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_ERROR_RETURN_TYPE -Werror=return-type)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_POINTER_ARITH -Wpointer-arith)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNUSED_PARAMETER -Wunused-parameter)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_WRITE_STRINGS -Wwrite-strings)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNDEF -Wundef)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_FORMAT_SIGN -Wformat-signedness)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_RESTRICT -Wrestrict)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_SUGGEST_OVERRIDE -Wno-suggest-override)
-
- # gcc 4.2 gives annoying warnings on every file with this
- if(NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "4.3")
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNINITIALIZED -Wuninitialized)
- endif()
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_ALL -Wall)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_LOGICAL_OP -Wlogical-op)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_INIT_SELF -Winit-self) # needs -Wuninitialized
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_MISSING_INCLUDE_DIRS -Wmissing-include-dirs)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_DIV_BY_ZERO -Wno-div-by-zero)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_TYPE_LIMITS -Wtype-limits)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_ERROR_RETURN_TYPE -Werror=return-type)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_POINTER_ARITH -Wpointer-arith)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_UNUSED_PARAMETER -Wunused-parameter)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_WRITE_STRINGS -Wwrite-strings)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_UNDEF -Wundef)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_FORMAT_SIGN -Wformat-signedness)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_RESTRICT -Wrestrict)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_SUGGEST_OVERRIDE -Wno-suggest-override)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_UNINITIALIZED -Wuninitialized)
# causes too many warnings
if(NOT APPLE)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNDEF -Wundef)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_MISSING_DECLARATIONS -Wmissing-declarations)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_UNDEF -Wundef)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_MISSING_DECLARATIONS -Wmissing-declarations)
endif()
# Use 'ATTR_FALLTHROUGH' macro to suppress.
- if(CMAKE_COMPILER_IS_GNUCC AND (NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "7.0"))
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_IMPLICIT_FALLTHROUGH -Wimplicit-fallthrough=5)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_IMPLICIT_FALLTHROUGH -Wimplicit-fallthrough=5)
- endif()
-
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_IMPLICIT_FALLTHROUGH -Wimplicit-fallthrough=5)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_IMPLICIT_FALLTHROUGH -Wimplicit-fallthrough=5)
# ---------------------
# Suppress Strict Flags
@@ -1497,102 +1515,100 @@ if(CMAKE_COMPILER_IS_GNUCC)
# If code in `./extern/` needs to suppress these flags that can be done on a case-by-case basis.
# flags to undo strict flags
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_DEPRECATED_DECLARATIONS -Wno-deprecated-declarations)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_FUNCTION -Wno-unused-function)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_TYPE_LIMITS -Wno-type-limits)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_INT_IN_BOOL_CONTEXT -Wno-int-in-bool-context)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_FORMAT -Wno-format)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_SWITCH -Wno-switch)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_VARIABLE -Wno-unused-variable)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_VARIABLE -Wno-uninitialized)
-
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_CLASS_MEMACCESS -Wno-class-memaccess)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_COMMENT -Wno-comment)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_TYPEDEFS -Wno-unused-local-typedefs)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_VARIABLE -Wno-unused-variable)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_VARIABLE -Wno-uninitialized)
-
- if(CMAKE_COMPILER_IS_GNUCC AND (NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "7.0"))
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_IMPLICIT_FALLTHROUGH -Wno-implicit-fallthrough)
- endif()
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_DEPRECATED_DECLARATIONS -Wno-deprecated-declarations)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_FUNCTION -Wno-unused-function)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_TYPE_LIMITS -Wno-type-limits)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_INT_IN_BOOL_CONTEXT -Wno-int-in-bool-context)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_FORMAT -Wno-format)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_SWITCH -Wno-switch)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_VARIABLE -Wno-unused-variable)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_VARIABLE -Wno-uninitialized)
+
+ add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_CLASS_MEMACCESS -Wno-class-memaccess)
+ add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_COMMENT -Wno-comment)
+ add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_TYPEDEFS -Wno-unused-local-typedefs)
+ add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_VARIABLE -Wno-unused-variable)
+ add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_VARIABLE -Wno-uninitialized)
+
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_IMPLICIT_FALLTHROUGH -Wno-implicit-fallthrough)
if(NOT APPLE)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable)
endif()
elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
# strange, clang complains these are not supported, but then uses them.
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ALL -Wall)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ERROR_IMPLICIT_FUNCTION_DECLARATION -Werror=implicit-function-declaration)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ERROR_RETURN_TYPE -Werror=return-type)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_STRICT_PROTOTYPES -Wstrict-prototypes)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_MISSING_PROTOTYPES -Wmissing-prototypes)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNUSED_PARAMETER -Wunused-parameter)
-
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_ALL -Wall)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_ALL -Wall)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_ERROR_IMPLICIT_FUNCTION_DECLARATION -Werror=implicit-function-declaration)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_ERROR_RETURN_TYPE -Werror=return-type)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_STRICT_PROTOTYPES -Wstrict-prototypes)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_MISSING_PROTOTYPES -Wmissing-prototypes)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_UNUSED_PARAMETER -Wunused-parameter)
+
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_ALL -Wall)
# Using C++20 features while having C++17 as the project language isn't allowed by MSVC.
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_CXX20_DESIGNATOR -Wc++20-designator)
-
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_OVERLOADED_VIRTUAL -Wno-overloaded-virtual) # we get a lot of these, if its a problem a dev needs to look into it.
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_CXX20_DESIGNATOR -Wc++20-designator)
+
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_OVERLOADED_VIRTUAL -Wno-overloaded-virtual) # we get a lot of these, if its a problem a dev needs to look into it.
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
# Apple Clang (tested on version 12) doesn't support this flag while LLVM Clang 11 does.
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_SUGGEST_OVERRIDE -Wno-suggest-override)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_SUGGEST_OVERRIDE -Wno-suggest-override)
# gives too many unfixable warnings
- # ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNUSED_MACROS -Wunused-macros)
- # ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNUSED_MACROS -Wunused-macros)
+ # add_check_c_compiler_flag(C_WARNINGS C_WARN_UNUSED_MACROS -Wunused-macros)
+ # add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_UNUSED_MACROS -Wunused-macros)
# ---------------------
# Suppress Strict Flags
# flags to undo strict flags
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_VARIABLE -Wno-unused-variable)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_MACROS -Wno-unused-macros)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_MISLEADING_INDENTATION -Wno-misleading-indentation)
-
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_MISSING_VARIABLE_DECLARATIONS -Wno-missing-variable-declarations)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_INCOMPAT_PTR_DISCARD_QUAL -Wno-incompatible-pointer-types-discards-qualifiers)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_FUNCTION -Wno-unused-function)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_INT_TO_VOID_POINTER_CAST -Wno-int-to-void-pointer-cast)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_MISSING_PROTOTYPES -Wno-missing-prototypes)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_DUPLICATE_ENUM -Wno-duplicate-enum)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNDEF -Wno-undef)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_MISSING_NORETURN -Wno-missing-noreturn)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_BUT_SET_VARIABLE -Wno-unused-but-set-variable)
- ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_DEPRECATED_DECLARATIONS -Wno-deprecated-declarations)
-
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_PRIVATE_FIELD -Wno-unused-private-field)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_CXX11_NARROWING -Wno-c++11-narrowing)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_NON_VIRTUAL_DTOR -Wno-non-virtual-dtor)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_MACROS -Wno-unused-macros)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_VARIABLE -Wno-unused-variable)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_REORDER -Wno-reorder)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_COMMENT -Wno-comment)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_TYPEDEFS -Wno-unused-local-typedefs)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNDEFINED_VAR_TEMPLATE -Wno-undefined-var-template)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_INSTANTIATION_AFTER_SPECIALIZATION -Wno-instantiation-after-specialization)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_MISLEADING_INDENTATION -Wno-misleading-indentation)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_VARIABLE -Wno-unused-variable)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_MACROS -Wno-unused-macros)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_MISLEADING_INDENTATION -Wno-misleading-indentation)
+
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_MISSING_VARIABLE_DECLARATIONS -Wno-missing-variable-declarations)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_INCOMPAT_PTR_DISCARD_QUAL -Wno-incompatible-pointer-types-discards-qualifiers)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_FUNCTION -Wno-unused-function)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_INT_TO_VOID_POINTER_CAST -Wno-int-to-void-pointer-cast)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_MISSING_PROTOTYPES -Wno-missing-prototypes)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_DUPLICATE_ENUM -Wno-duplicate-enum)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNDEF -Wno-undef)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_MISSING_NORETURN -Wno-missing-noreturn)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_BUT_SET_VARIABLE -Wno-unused-but-set-variable)
+ add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_DEPRECATED_DECLARATIONS -Wno-deprecated-declarations)
+
+ add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter)
+ add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_PRIVATE_FIELD -Wno-unused-private-field)
+ add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_CXX11_NARROWING -Wno-c++11-narrowing)
+ add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_NON_VIRTUAL_DTOR -Wno-non-virtual-dtor)
+ add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_MACROS -Wno-unused-macros)
+ add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_VARIABLE -Wno-unused-variable)
+ add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_REORDER -Wno-reorder)
+ add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_COMMENT -Wno-comment)
+ add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_TYPEDEFS -Wno-unused-local-typedefs)
+ add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNDEFINED_VAR_TEMPLATE -Wno-undefined-var-template)
+ add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_INSTANTIATION_AFTER_SPECIALIZATION -Wno-instantiation-after-specialization)
+ add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_MISLEADING_INDENTATION -Wno-misleading-indentation)
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ALL -Wall)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_POINTER_ARITH -Wpointer-arith)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_ALL -Wall)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_POINTER_ARITH -Wpointer-arith)
+ add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_ALL -Wall)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_ALL -Wall)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
+ add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare)
# disable numbered, false positives
string(APPEND C_WARNINGS " -wd188,186,144,913,556,858,597,177,1292,167,279,592,94,2722,3199")
@@ -1605,6 +1621,8 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "MSVC")
"/w34062" # switch statement contains 'default' but no 'case' labels
"/w34115" # 'type' : named type definition in parentheses
"/w34189" # local variable is initialized but not referenced
+ # see https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/c5038?view=vs-2017
+ "/w35038" # order of initialization in c++ constructors
# disable:
"/wd4018" # signed/unsigned mismatch
"/wd4146" # unary minus operator applied to unsigned type, result still unsigned
@@ -1624,13 +1642,9 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "MSVC")
"/we4013" # 'function' undefined; assuming extern returning int
"/we4133" # incompatible pointer types
"/we4431" # missing type specifier - int assumed
+ "/we4033" # 'function' must return a value
)
- if(MSVC_VERSION GREATER_EQUAL 1911)
- # see https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/c5038?view=vs-2017
- string(APPEND _WARNINGS " /w35038") # order of initialization in c++ constructors
- endif()
-
string(REPLACE ";" " " _WARNINGS "${_WARNINGS}")
set(C_WARNINGS "${_WARNINGS}")
set(CXX_WARNINGS "${_WARNINGS}")
@@ -1682,7 +1696,7 @@ set(CMAKE_CXX_EXTENSIONS OFF)
# Make MSVC properly report the value of the __cplusplus preprocessor macro
# Available MSVC 15.7 (1914) and up, without this it reports 199711L regardless
# of the C++ standard chosen above.
-if(MSVC AND MSVC_VERSION GREATER 1913)
+if(MSVC)
string(APPEND CMAKE_CXX_FLAGS " /Zc:__cplusplus")
endif()
@@ -1705,8 +1719,8 @@ endif()
if(WITH_COMPILER_SHORT_FILE_MACRO)
# Use '-fmacro-prefix-map' for Clang and GCC (MSVC doesn't support this).
- ADD_CHECK_C_COMPILER_FLAG(C_PREFIX_MAP_FLAGS C_MACRO_PREFIX_MAP -fmacro-prefix-map=foo=bar)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_PREFIX_MAP_FLAGS CXX_MACRO_PREFIX_MAP -fmacro-prefix-map=foo=bar)
+ add_check_c_compiler_flag(C_PREFIX_MAP_FLAGS C_MACRO_PREFIX_MAP -fmacro-prefix-map=foo=bar)
+ add_check_cxx_compiler_flag(CXX_PREFIX_MAP_FLAGS CXX_MACRO_PREFIX_MAP -fmacro-prefix-map=foo=bar)
if(C_MACRO_PREFIX_MAP AND CXX_MACRO_PREFIX_MAP)
if(APPLE)
if(XCODE AND ${XCODE_VERSION} VERSION_LESS 12.0)
@@ -1909,9 +1923,25 @@ if(FIRST_RUN)
info_cfg_option(WITH_INSTALL_PORTABLE)
info_cfg_option(WITH_MEM_JEMALLOC)
info_cfg_option(WITH_MEM_VALGRIND)
- info_cfg_option(WITH_X11_XF86VMODE)
- info_cfg_option(WITH_X11_XFIXES)
- info_cfg_option(WITH_X11_XINPUT)
+
+ info_cfg_text("GHOST Options:")
+ info_cfg_option(WITH_GHOST_DEBUG)
+ info_cfg_option(WITH_GHOST_SDL)
+ if(UNIX AND NOT APPLE)
+ info_cfg_option(WITH_GHOST_X11)
+ info_cfg_option(WITH_GHOST_WAYLAND)
+ if(WITH_GHOST_X11)
+ info_cfg_option(WITH_GHOST_XDND)
+ info_cfg_option(WITH_X11_XF86VMODE)
+ info_cfg_option(WITH_X11_XFIXES)
+ info_cfg_option(WITH_X11_XINPUT)
+ endif()
+ if(WITH_GHOST_WAYLAND)
+ info_cfg_option(WITH_GHOST_WAYLAND_DYNLOAD)
+ info_cfg_option(WITH_GHOST_WAYLAND_LIBDECOR)
+ info_cfg_option(WITH_GHOST_WAYLAND_DBUS)
+ endif()
+ endif()
info_cfg_text("Image Formats:")
info_cfg_option(WITH_IMAGE_CINEON)
@@ -1952,6 +1982,22 @@ if(FIRST_RUN)
info_cfg_option(WITH_MOD_OCEANSIM)
info_cfg_option(WITH_MOD_REMESH)
+ if(WITH_CYCLES)
+ info_cfg_text("Cycles:")
+ info_cfg_option(WITH_CYCLES_OSL)
+ info_cfg_option(WITH_CYCLES_EMBREE)
+ info_cfg_option(WITH_CYCLES_PATH_GUIDING)
+ if(NOT APPLE)
+ info_cfg_option(WITH_CYCLES_DEVICE_OPTIX)
+ info_cfg_option(WITH_CYCLES_DEVICE_CUDA)
+ info_cfg_option(WITH_CYCLES_CUDA_BINARIES)
+ info_cfg_option(WITH_CYCLES_DEVICE_HIP)
+ info_cfg_option(WITH_CYCLES_HIP_BINARIES)
+ info_cfg_option(WITH_CYCLES_DEVICE_ONEAPI)
+ info_cfg_option(WITH_CYCLES_ONEAPI_BINARIES)
+ endif()
+ endif()
+
info_cfg_text("")
message("${_config_msg}")
diff --git a/GNUmakefile b/GNUmakefile
index 884d2232d71..439b435f5f4 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -364,7 +364,7 @@ all: .FORCE
$(BUILD_COMMAND) -C "$(BUILD_DIR)" -j $(NPROCS) install
@echo
@echo Edit build configuration with: \"$(BUILD_DIR)/CMakeCache.txt\" run make again to rebuild.
- @if test "$(BLENDER_IS_PYTHON_MODULE)" == ""; then \
+ @if test -z "$(BLENDER_IS_PYTHON_MODULE)"; then \
echo Blender successfully built, run from: $(BLENDER_BIN); \
else \
echo Blender successfully built as a Python module, \"bpy\" can be imported from: $(BLENDER_BIN_DIR); \
diff --git a/build_files/build_environment/CMakeLists.txt b/build_files/build_environment/CMakeLists.txt
index ee8a9a26c53..999223603d5 100644
--- a/build_files/build_environment/CMakeLists.txt
+++ b/build_files/build_environment/CMakeLists.txt
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-or-later
-####################################################################################################
+##################################################################################################
#
# This is a build system used by platform maintainers to build library dependencies on
# Windows, macOS and Linux.
@@ -22,7 +22,7 @@
# Install compiler cmake autoconf automake libtool yasm tcl
# Run "make deps" from main Blender directory
#
-####################################################################################################
+##################################################################################################
project("BlenderDependencies")
cmake_minimum_required(VERSION 3.5)
@@ -30,7 +30,8 @@ cmake_minimum_required(VERSION 3.5)
include(ExternalProject)
include(cmake/check_software.cmake)
include(cmake/options.cmake)
-# versions.cmake needs to be included after options.cmake due to the BLENDER_PLATFORM_ARM variable being needed.
+# `versions.cmake` needs to be included after `options.cmake`
+# due to the `BLENDER_PLATFORM_ARM` variable being needed.
include(cmake/versions.cmake)
include(cmake/boost_build_options.cmake)
include(cmake/download.cmake)
@@ -88,14 +89,17 @@ include(cmake/package_python.cmake)
include(cmake/usd.cmake)
include(cmake/potrace.cmake)
include(cmake/haru.cmake)
-# Boost needs to be included after python.cmake due to the PYTHON_BINARY variable being needed.
+# Boost needs to be included after `python.cmake` due to the PYTHON_BINARY variable being needed.
include(cmake/boost.cmake)
include(cmake/pugixml.cmake)
include(cmake/ispc.cmake)
include(cmake/openimagedenoise.cmake)
include(cmake/embree.cmake)
+include(cmake/openpgl.cmake)
include(cmake/fmt.cmake)
include(cmake/robinmap.cmake)
+include(cmake/xml2.cmake)
+
if(NOT APPLE)
include(cmake/xr_openxr.cmake)
if(NOT WIN32 OR BUILD_MODE STREQUAL Release)
@@ -148,7 +152,6 @@ if(NOT WIN32 OR ENABLE_MINGW64)
endif()
if(UNIX)
include(cmake/flac.cmake)
- include(cmake/xml2.cmake)
if(NOT APPLE)
include(cmake/spnav.cmake)
include(cmake/jemalloc.cmake)
@@ -169,6 +172,10 @@ if(UNIX AND NOT APPLE)
include(cmake/libglu.cmake)
include(cmake/mesa.cmake)
include(cmake/wayland_protocols.cmake)
+ # Can be removed when the build-bot upgrades to v1.20.x or newer.
+ include(cmake/wayland.cmake)
+ include(cmake/wayland_libdecor.cmake)
endif()
include(cmake/harvest.cmake)
+include(cmake/cve_check.cmake)
diff --git a/build_files/build_environment/cmake/aom.cmake b/build_files/build_environment/cmake/aom.cmake
index 9f64439771f..11c81c3f6e4 100644
--- a/build_files/build_environment/cmake/aom.cmake
+++ b/build_files/build_environment/cmake/aom.cmake
@@ -8,11 +8,6 @@ if(WIN32)
# building with mingw, it'll have an unhappy time with that and
# we need to clear them out.
set(AOM_CMAKE_FLAGS )
- # CMake will correctly identify phreads being available, however
- # we do not want to use them, as that gains a dependency on
- # libpthreadswin.dll which we do not want. when pthreads is not
- # available oam will use a pthreads emulation layer using win32 threads
- set(AOM_EXTRA_ARGS_WIN32 -DCMAKE_HAVE_PTHREAD_H=OFF)
else()
set(AOM_GENERATOR "Unix Makefiles")
set(AOM_CMAKE_FLAGS ${DEFAULT_CMAKE_FLAGS})
@@ -36,6 +31,7 @@ ExternalProject_Add(external_aom
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH ${AOM_HASH_TYPE}=${AOM_HASH}
PREFIX ${BUILD_DIR}/aom
+ PATCH_COMMAND ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/aom/src/external_aom < ${PATCH_DIR}/aom.diff
CONFIGURE_COMMAND ${CONFIGURE_ENV} &&
cd ${BUILD_DIR}/aom/src/external_aom-build/ &&
${CMAKE_COMMAND} -G "${AOM_GENERATOR}" -DCMAKE_INSTALL_PREFIX=${LIBDIR}/aom ${AOM_CMAKE_FLAGS} ${AOM_EXTRA_ARGS} ${BUILD_DIR}/aom/src/external_aom/
diff --git a/build_files/build_environment/cmake/check_software.cmake b/build_files/build_environment/cmake/check_software.cmake
index cc8fead6f81..bdb9036e3f9 100644
--- a/build_files/build_environment/cmake/check_software.cmake
+++ b/build_files/build_environment/cmake/check_software.cmake
@@ -46,7 +46,7 @@ if(UNIX)
" ${_software_missing}\n"
"\n"
"On Debian and Ubuntu:\n"
- " apt install autoconf automake libtool yasm tcl ninja-build meson python3-mako\n"
+ " apt install autoconf automake bison libtool yasm tcl ninja-build meson python3-mako\n"
"\n"
"On macOS (with homebrew):\n"
" brew install autoconf automake bison flex libtool meson ninja pkg-config yasm\n"
diff --git a/build_files/build_environment/cmake/cve_check.cmake b/build_files/build_environment/cmake/cve_check.cmake
new file mode 100644
index 00000000000..ac42444aef1
--- /dev/null
+++ b/build_files/build_environment/cmake/cve_check.cmake
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# CVE Check requirements
+#
+# - A working installation of intels cve-bin-tool [1] has to be available in
+# your path
+#
+# - Not strictly required, but highly recommended is obtaining a NVD key from
+# nist since it significantly speeds up downloading/updating the required
+# databases one can request a key on the following website:
+# https://nvd.nist.gov/developers/request-an-api-key
+
+# Bill of Materials construction
+#
+# This constructs a CSV cve-bin-tool [1] can read and process. Sadly
+# cve-bin-tool at this point does not take a list of CPE's and output a check
+# based on that list. so we need to pick apart the CPE retrieve the vendor,
+# product and version tokens and generate a CSV.
+#
+# [1] https://github.com/intel/cve-bin-tool
+
+# Because not all deps are downloaded (ie python packages) but can still have a
+# xxx_CPE declared loop over all variables and look for variables ending in CPE.
+
+set(SBOMCONTENTS)
+get_cmake_property(_variableNames VARIABLES)
+foreach (_variableName ${_variableNames})
+ if(_variableName MATCHES "CPE$")
+ string(REPLACE ":" ";" CPE_LIST ${${_variableName}})
+ string(REPLACE "_CPE" "_ID" CPE_DEPNAME ${_variableName})
+ list(GET CPE_LIST 3 CPE_VENDOR)
+ list(GET CPE_LIST 4 CPE_NAME)
+ list(GET CPE_LIST 5 CPE_VERSION)
+ set(${CPE_DEPNAME} "${CPE_VENDOR},${CPE_NAME},${CPE_VERSION}")
+ set(SBOMCONTENTS "${SBOMCONTENTS}${CPE_VENDOR},${CPE_NAME},${CPE_VERSION},,,\n")
+ endif()
+endforeach()
+configure_file(${CMAKE_SOURCE_DIR}/cmake/cve_check.csv.in ${CMAKE_CURRENT_BINARY_DIR}/cve_check.csv @ONLY)
+
+# Custom Targets
+#
+# This defines two new custom targets one could run in the build folder
+# `cve_check` which will output the report to the console, and `cve_check_html`
+# which will write out blender_dependencies.html in the build folder that one
+# could share with other people or be used to get more information on the
+# reported CVE's.
+#
+# cve-bin-tool takes data from the nist nvd database which rate limits
+# unauthenticated requests to 1 requests per 6 seconds making the database
+# download take "quite a bit" of time.
+#
+# When adding -DCVE_CHECK_NVD_KEY=your_api_key_here to your cmake invocation
+# this key will be passed on to cve-bin-tool speeding up the process.
+#
+if(DEFINED CVE_CHECK_NVD_KEY)
+ set(NVD_ARGS --nvd-api-key ${CVE_CHECK_NVD_KEY})
+endif()
+
+# This will just report to the console
+add_custom_target(cve_check
+ COMMAND cve-bin-tool
+ ${NVD_ARGS}
+ -i ${CMAKE_CURRENT_BINARY_DIR}/cve_check.csv
+ --affected-versions
+ SOURCES ${CMAKE_CURRENT_BINARY_DIR}/cve_check.csv
+)
+
+# This will write out blender_dependencies.html
+add_custom_target(cve_check_html
+ COMMAND cve-bin-tool
+ ${NVD_ARGS}
+ -i ${CMAKE_CURRENT_BINARY_DIR}/cve_check.csv
+ -f html
+ SOURCES ${CMAKE_CURRENT_BINARY_DIR}/cve_check.csv
+)
diff --git a/build_files/build_environment/cmake/cve_check.csv.in b/build_files/build_environment/cmake/cve_check.csv.in
new file mode 100644
index 00000000000..946dda5ab17
--- /dev/null
+++ b/build_files/build_environment/cmake/cve_check.csv.in
@@ -0,0 +1,29 @@
+vendor,product,version,cve_number,remarks,comment
+@OPENJPEG_ID@,CVE-2016-9675,Ignored,issue in convert command line tool not used by blender
+@PYTHON_ID@,CVE-2009-2940,Ignored,issue in pygresql not used by blender
+@PYTHON_ID@,CVE-2020-29396,Ignored,issue in odoo not used by blender
+@PYTHON_ID@,CVE-2021-32052,Ignored,issue in django not used by blender
+@PYTHON_ID@,CVE-2009-3720,Ignored,already fixed in libexpat version used
+@SSL_ID@,CVE-2009-1390,Ignored,issue in mutt not used by blender
+@SSL_ID@,CVE-2009-3765,Ignored,issue in mutt not used by blender
+@SSL_ID@,CVE-2009-3766,Ignored,issue in mutt not used by blender
+@SSL_ID@,CVE-2009-3767,Ignored,issue in ldap not used by blender
+@SSL_ID@,CVE-2019-0190,Ignored,issue in apache not used by blender
+@TIFF_ID@,CVE-2022-2056,Ignored,issue in tiff command line tool not used by blender
+@TIFF_ID@,CVE-2022-2057,Ignored,issue in tiff command line tool not used by blender
+@TIFF_ID@,CVE-2022-2058,Ignored,issue in tiff command line tool not used by blender
+@TIFF_ID@,CVE-2022-2519,Ignored,issue in tiff command line tool not used by blender
+@TIFF_ID@,CVE-2022-2520,Ignored,issue in tiff command line tool not used by blender
+@TIFF_ID@,CVE-2022-2521,Ignored,issue in tiff command line tool not used by blender
+@TIFF_ID@,CVE-2022-2953,Ignored,issue in tiff command line tool not used by blender
+@TIFF_ID@,CVE-2022-34526,Ignored,issue in tiff command line tool not used by blender
+@TIFF_ID@,CVE-2022-3570,Ignored,issue in tiff command line tool not used by blender
+@TIFF_ID@,CVE-2022-3597,Ignored,issue in tiff command line tool not used by blender
+@TIFF_ID@,CVE-2022-3598,Ignored,issue in tiff command line tool not used by blender
+@TIFF_ID@,CVE-2022-3599,Ignored,issue in tiff command line tool not used by blender
+@TIFF_ID@,CVE-2022-3626,Ignored,issue in tiff command line tool not used by blender
+@TIFF_ID@,CVE-2022-3627,Ignored,issue in tiff command line tool not used by blender
+@XML2_ID@,CVE-2016-3709,Ignored,not affecting blender and not considered a security issue upstream
+@GMP_ID@,CVE-2021-43618,Mitigated,patched using upstream commit 561a9c25298e
+@SQLITE_ID@,CVE-2022-35737,Ignored,only affects SQLITE_ENABLE_STAT4 compile option not used by blender or python
+@SBOMCONTENTS@
diff --git a/build_files/build_environment/cmake/download.cmake b/build_files/build_environment/cmake/download.cmake
index 6f0dd80ea6a..8d75f0ff0ed 100644
--- a/build_files/build_environment/cmake/download.cmake
+++ b/build_files/build_environment/cmake/download.cmake
@@ -14,6 +14,20 @@ function(download_source dep)
else()
set(TARGET_URI https://svn.blender.org/svnroot/bf-blender/trunk/lib/packages/${TARGET_FILE})
endif()
+ # Validate all required variables are set and give an explicit error message
+ # rather than CMake erroring out later on with a more ambigious error.
+ if (NOT DEFINED TARGET_FILE)
+ message(FATAL_ERROR "${dep}_FILE variable not set")
+ endif()
+ if (NOT DEFINED TARGET_HASH)
+ message(FATAL_ERROR "${dep}_HASH variable not set")
+ endif()
+ if (NOT DEFINED TARGET_HASH_TYPE)
+ message(FATAL_ERROR "${dep}_HASH_TYPE variable not set")
+ endif()
+ if (NOT DEFINED TARGET_URI)
+ message(FATAL_ERROR "${dep}_URI variable not set")
+ endif()
set(TARGET_FILE ${PACKAGE_DIR}/${TARGET_FILE})
message("Checking source : ${dep} (${TARGET_FILE})")
if(NOT EXISTS ${TARGET_FILE})
@@ -25,6 +39,36 @@ function(download_source dep)
SHOW_PROGRESS
)
endif()
+ if(EXISTS ${TARGET_FILE})
+ # Sometimes the download fails, but that is not a
+ # fail condition for "file(DOWNLOAD" it will warn about
+ # a crc mismatch and just carry on, we need to explicitly
+ # catch this and remove the bogus 0 byte file so we can
+ # retry without having to go find the file and manually
+ # delete it.
+ file (SIZE ${TARGET_FILE} TARGET_SIZE)
+ if(${TARGET_SIZE} EQUAL 0)
+ file(REMOVE ${TARGET_FILE})
+ message(FATAL_ERROR "for ${TARGET_FILE} file size 0, download likely failed, deleted...")
+ endif()
+
+ # If we are using sources from the blender repo also
+ # validate that the hashes match, this takes a
+ # little more time, but protects us when we are
+ # building a release package and one of the packages
+ # is missing or incorrect.
+ #
+ # For regular platform maintenaince this is not needed
+ # since the actual build of the dep will notify the
+ # platform maintainer if there is a problem with the
+ # source package and refuse to build.
+ if(NOT PACKAGE_USE_UPSTREAM_SOURCES OR FORCE_CHECK_HASH)
+ file(${TARGET_HASH_TYPE} ${TARGET_FILE} LOCAL_HASH)
+ if(NOT ${TARGET_HASH} STREQUAL ${LOCAL_HASH})
+ message(FATAL_ERROR "${TARGET_FILE} ${TARGET_HASH_TYPE} mismatch\nExpected\t: ${TARGET_HASH}\nActual\t: ${LOCAL_HASH}")
+ endif()
+ endif()
+ endif()
endfunction(download_source)
download_source(ZLIB)
@@ -51,7 +95,6 @@ download_source(OSL)
download_source(PYTHON)
download_source(TBB)
download_source(OPENVDB)
-download_source(NANOVDB)
download_source(NUMPY)
download_source(LAME)
download_source(OGG)
@@ -71,7 +114,6 @@ download_source(WEBP)
download_source(SPNAV)
download_source(JEMALLOC)
download_source(XML2)
-download_source(TINYXML)
download_source(YAMLCPP)
download_source(EXPAT)
download_source(PUGIXML)
@@ -89,6 +131,8 @@ download_source(MESA)
download_source(NASM)
download_source(XR_OPENXR_SDK)
download_source(WL_PROTOCOLS)
+download_source(WAYLAND)
+download_source(WAYLAND_LIBDECOR)
download_source(ISPC)
download_source(GMP)
download_source(POTRACE)
@@ -101,6 +145,7 @@ download_source(FMT)
download_source(ROBINMAP)
download_source(IMATH)
download_source(PYSTRING)
+download_source(OPENPGL)
download_source(LEVEL_ZERO)
download_source(DPCPP)
download_source(VCINTRINSICS)
diff --git a/build_files/build_environment/cmake/dpcpp.cmake b/build_files/build_environment/cmake/dpcpp.cmake
index 3c3fe201073..28315d1f703 100644
--- a/build_files/build_environment/cmake/dpcpp.cmake
+++ b/build_files/build_environment/cmake/dpcpp.cmake
@@ -68,7 +68,7 @@ set(DPCPP_EXTRA_ARGS
)
if(WIN32)
- list(APPEND DPCPP_EXTRA_ARGS -DPython3_FIND_REGISTRY=NEVER)
+ list(APPEND DPCPP_EXTRA_ARGS -DPython3_FIND_REGISTRY=NEVER)
endif()
ExternalProject_Add(external_dpcpp
@@ -80,8 +80,11 @@ ExternalProject_Add(external_dpcpp
SOURCE_SUBDIR llvm
LIST_SEPARATOR ^^
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/dpcpp ${DEFAULT_CMAKE_FLAGS} ${DPCPP_EXTRA_ARGS}
- #CONFIGURE_COMMAND ${PYTHON_BINARY} ${BUILD_DIR}/dpcpp/src/external_dpcpp/buildbot/configure.py ${DPCPP_CONFIGURE_ARGS}
- #BUILD_COMMAND echo "." #${PYTHON_BINARY} ${BUILD_DIR}/dpcpp/src/external_dpcpp/buildbot/compile.py
+ # CONFIGURE_COMMAND
+ # ${PYTHON_BINARY}
+ # ${BUILD_DIR}/dpcpp/src/external_dpcpp/buildbot/configure.py ${DPCPP_CONFIGURE_ARGS}
+ # BUILD_COMMAND
+ # echo "." # ${PYTHON_BINARY} ${BUILD_DIR}/dpcpp/src/external_dpcpp/buildbot/compile.py
INSTALL_COMMAND ${CMAKE_COMMAND} --build . -- deploy-sycl-toolchain
PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/dpcpp/src/external_dpcpp < ${PATCH_DIR}/dpcpp.diff
INSTALL_DIR ${LIBDIR}/dpcpp
diff --git a/build_files/build_environment/cmake/ffmpeg.cmake b/build_files/build_environment/cmake/ffmpeg.cmake
index 7730607c514..e2b60e161f2 100644
--- a/build_files/build_environment/cmake/ffmpeg.cmake
+++ b/build_files/build_environment/cmake/ffmpeg.cmake
@@ -16,12 +16,6 @@ if(WIN32)
--enable-libopenjpeg
--disable-mediafoundation
)
- if("${CMAKE_SIZEOF_VOID_P}" EQUAL "4")
- set(FFMPEG_EXTRA_FLAGS
- ${FFMPEG_EXTRA_FLAGS}
- --x86asmexe=yasm
- )
- endif()
else()
set(FFMPEG_EXTRA_FLAGS
${FFMPEG_EXTRA_FLAGS}
diff --git a/build_files/build_environment/cmake/freetype.cmake b/build_files/build_environment/cmake/freetype.cmake
index b6f53ede2db..842e5c42e25 100644
--- a/build_files/build_environment/cmake/freetype.cmake
+++ b/build_files/build_environment/cmake/freetype.cmake
@@ -7,8 +7,11 @@ set(FREETYPE_EXTRA_ARGS
-DFT_DISABLE_HARFBUZZ=ON
-DFT_DISABLE_PNG=ON
-DFT_REQUIRE_BROTLI=ON
+ -DFT_REQUIRE_ZLIB=ON
-DPC_BROTLIDEC_INCLUDEDIR=${LIBDIR}/brotli/include
-DPC_BROTLIDEC_LIBDIR=${LIBDIR}/brotli/lib
+ -DZLIB_LIBRARY=${LIBDIR}/zlib/lib/${ZLIB_LIBRARY}
+ -DZLIB_INCLUDE_DIR=${LIBDIR}/zlib/include
)
ExternalProject_Add(external_freetype
@@ -23,6 +26,7 @@ ExternalProject_Add(external_freetype
add_dependencies(
external_freetype
external_brotli
+ external_zlib
)
if(BUILD_MODE STREQUAL Release AND WIN32)
diff --git a/build_files/build_environment/cmake/gmp.cmake b/build_files/build_environment/cmake/gmp.cmake
index e624778869e..ddfdba6662d 100644
--- a/build_files/build_environment/cmake/gmp.cmake
+++ b/build_files/build_environment/cmake/gmp.cmake
@@ -27,6 +27,7 @@ ExternalProject_Add(external_gmp
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH ${GMP_HASH_TYPE}=${GMP_HASH}
PREFIX ${BUILD_DIR}/gmp
+ PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/gmp/src/external_gmp < ${PATCH_DIR}/gmp.diff
CONFIGURE_COMMAND ${CONFIGURE_ENV_NO_PERL} && cd ${BUILD_DIR}/gmp/src/external_gmp/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/gmp ${GMP_OPTIONS} ${GMP_EXTRA_ARGS}
BUILD_COMMAND ${CONFIGURE_ENV_NO_PERL} && cd ${BUILD_DIR}/gmp/src/external_gmp/ && make -j${MAKE_THREADS}
INSTALL_COMMAND ${CONFIGURE_ENV_NO_PERL} && cd ${BUILD_DIR}/gmp/src/external_gmp/ && make install
diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake
index 6ed98398fde..9afc1974677 100644
--- a/build_files/build_environment/cmake/harvest.cmake
+++ b/build_files/build_environment/cmake/harvest.cmake
@@ -11,188 +11,194 @@ message("HARVEST_TARGET = ${HARVEST_TARGET}")
if(WIN32)
-if(BUILD_MODE STREQUAL Release)
- add_custom_target(Harvest_Release_Results
- COMMAND # jpeg rename libfile + copy include
- ${CMAKE_COMMAND} -E copy ${LIBDIR}/jpeg/lib/jpeg-static.lib ${HARVEST_TARGET}/jpeg/lib/libjpeg.lib &&
- ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/jpeg/include/ ${HARVEST_TARGET}/jpeg/include/ &&
- # png
- ${CMAKE_COMMAND} -E copy ${LIBDIR}/png/lib/libpng16_static.lib ${HARVEST_TARGET}/png/lib/libpng.lib &&
- ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/png/include/ ${HARVEST_TARGET}/png/include/ &&
- # freeglut-> opengl
- ${CMAKE_COMMAND} -E copy ${LIBDIR}/freeglut/lib/freeglut_static.lib ${HARVEST_TARGET}/opengl/lib/freeglut_static.lib &&
- ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/freeglut/include/ ${HARVEST_TARGET}/opengl/include/ &&
- DEPENDS
- )
-endif()
+ if(BUILD_MODE STREQUAL Release)
+ add_custom_target(Harvest_Release_Results
+ COMMAND # jpeg rename libfile + copy include
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/jpeg/lib/jpeg-static.lib ${HARVEST_TARGET}/jpeg/lib/libjpeg.lib &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/jpeg/include/ ${HARVEST_TARGET}/jpeg/include/ &&
+ # png
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/png/lib/libpng16_static.lib ${HARVEST_TARGET}/png/lib/libpng.lib &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/png/include/ ${HARVEST_TARGET}/png/include/ &&
+ # freeglut-> opengl
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/freeglut/lib/freeglut_static.lib ${HARVEST_TARGET}/opengl/lib/freeglut_static.lib &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/freeglut/include/ ${HARVEST_TARGET}/opengl/include/ &&
+ DEPENDS
+ )
+ endif()
-else(WIN32)
+else()
-function(harvest from to)
- set(pattern "")
- foreach(f ${ARGN})
- set(pattern ${f})
- endforeach()
+ function(harvest from to)
+ set(pattern "")
+ foreach(f ${ARGN})
+ set(pattern ${f})
+ endforeach()
- if(pattern STREQUAL "")
- get_filename_component(dirpath ${to} DIRECTORY)
- get_filename_component(filename ${to} NAME)
- install(
- FILES ${LIBDIR}/${from}
- DESTINATION ${HARVEST_TARGET}/${dirpath}
- RENAME ${filename}
- )
- else()
- install(
- DIRECTORY ${LIBDIR}/${from}/
- DESTINATION ${HARVEST_TARGET}/${to}
- USE_SOURCE_PERMISSIONS
- FILES_MATCHING PATTERN ${pattern}
- PATTERN "pkgconfig" EXCLUDE
- PATTERN "cmake" EXCLUDE
- PATTERN "__pycache__" EXCLUDE
- PATTERN "tests" EXCLUDE
- )
- endif()
-endfunction()
+ if(pattern STREQUAL "")
+ get_filename_component(dirpath ${to} DIRECTORY)
+ get_filename_component(filename ${to} NAME)
+ install(
+ FILES ${LIBDIR}/${from}
+ DESTINATION ${HARVEST_TARGET}/${dirpath}
+ RENAME ${filename}
+ )
+ else()
+ install(
+ DIRECTORY ${LIBDIR}/${from}/
+ DESTINATION ${HARVEST_TARGET}/${to}
+ USE_SOURCE_PERMISSIONS
+ FILES_MATCHING PATTERN ${pattern}
+ PATTERN "pkgconfig" EXCLUDE
+ PATTERN "cmake" EXCLUDE
+ PATTERN "__pycache__" EXCLUDE
+ PATTERN "tests" EXCLUDE
+ )
+ endif()
+ endfunction()
-harvest(alembic/include alembic/include "*.h")
-harvest(alembic/lib/libAlembic.a alembic/lib/libAlembic.a)
-harvest(alembic/bin alembic/bin "*")
-harvest(brotli/include brotli/include "*.h")
-harvest(brotli/lib brotli/lib "*.a")
-harvest(boost/include boost/include "*")
-harvest(boost/lib boost/lib "*.a")
-harvest(imath/include imath/include "*.h")
-harvest(imath/lib imath/lib "*.a")
-harvest(ffmpeg/include ffmpeg/include "*.h")
-harvest(ffmpeg/lib ffmpeg/lib "*.a")
-harvest(fftw3/include fftw3/include "*.h")
-harvest(fftw3/lib fftw3/lib "*.a")
-harvest(flac/lib sndfile/lib "libFLAC.a")
-harvest(freetype/include freetype/include "*.h")
-harvest(freetype/lib/libfreetype2ST.a freetype/lib/libfreetype.a)
-harvest(epoxy/include epoxy/include "*.h")
-harvest(epoxy/lib epoxy/lib "*.a")
-harvest(gmp/include gmp/include "*.h")
-harvest(gmp/lib gmp/lib "*.a")
-harvest(jemalloc/include jemalloc/include "*.h")
-harvest(jemalloc/lib jemalloc/lib "*.a")
-harvest(jpeg/include jpeg/include "*.h")
-harvest(jpeg/lib jpeg/lib "libjpeg.a")
-harvest(lame/lib ffmpeg/lib "*.a")
-if(NOT APPLE)
- harvest(level-zero/include/level_zero level-zero/include/level_zero "*.h")
- harvest(level-zero/lib level-zero/lib "*.so*")
-endif()
-harvest(llvm/bin llvm/bin "clang-format")
-if(BUILD_CLANG_TOOLS)
- harvest(llvm/bin llvm/bin "clang-tidy")
- harvest(llvm/share/clang llvm/share "run-clang-tidy.py")
-endif()
-harvest(llvm/include llvm/include "*")
-harvest(llvm/bin llvm/bin "llvm-config")
-harvest(llvm/lib llvm/lib "libLLVM*.a")
-harvest(llvm/lib llvm/lib "libclang*.a")
-harvest(llvm/lib/clang llvm/lib/clang "*.h")
-if(APPLE)
- harvest(openmp/lib openmp/lib "*")
- harvest(openmp/include openmp/include "*.h")
-endif()
-if(BLENDER_PLATFORM_ARM)
- harvest(sse2neon sse2neon "*.h")
-endif()
-harvest(ogg/lib ffmpeg/lib "*.a")
-harvest(openal/include openal/include "*.h")
-if(UNIX AND NOT APPLE)
- harvest(openal/lib openal/lib "*.a")
+ harvest(alembic/include alembic/include "*.h")
+ harvest(alembic/lib/libAlembic.a alembic/lib/libAlembic.a)
+ harvest(alembic/bin alembic/bin "*")
+ harvest(brotli/include brotli/include "*.h")
+ harvest(brotli/lib brotli/lib "*.a")
+ harvest(boost/include boost/include "*")
+ harvest(boost/lib boost/lib "*.a")
+ harvest(imath/include imath/include "*.h")
+ harvest(imath/lib imath/lib "*.a")
+ harvest(ffmpeg/include ffmpeg/include "*.h")
+ harvest(ffmpeg/lib ffmpeg/lib "*.a")
+ harvest(fftw3/include fftw3/include "*.h")
+ harvest(fftw3/lib fftw3/lib "*.a")
+ harvest(flac/lib sndfile/lib "libFLAC.a")
+ harvest(freetype/include freetype/include "*.h")
+ harvest(freetype/lib/libfreetype2ST.a freetype/lib/libfreetype.a)
+ harvest(epoxy/include epoxy/include "*.h")
+ harvest(epoxy/lib epoxy/lib "*.a")
+ harvest(gmp/include gmp/include "*.h")
+ harvest(gmp/lib gmp/lib "*.a")
+ harvest(jemalloc/include jemalloc/include "*.h")
+ harvest(jemalloc/lib jemalloc/lib "*.a")
+ harvest(jpeg/include jpeg/include "*.h")
+ harvest(jpeg/lib jpeg/lib "libjpeg.a")
+ harvest(lame/lib ffmpeg/lib "*.a")
+ if(NOT APPLE)
+ harvest(level-zero/include/level_zero level-zero/include/level_zero "*.h")
+ harvest(level-zero/lib level-zero/lib "*.so*")
+ endif()
+ harvest(llvm/bin llvm/bin "clang-format")
+ if(BUILD_CLANG_TOOLS)
+ harvest(llvm/bin llvm/bin "clang-tidy")
+ harvest(llvm/share/clang llvm/share "run-clang-tidy.py")
+ endif()
+ harvest(llvm/include llvm/include "*")
+ harvest(llvm/bin llvm/bin "llvm-config")
+ harvest(llvm/lib llvm/lib "libLLVM*.a")
+ harvest(llvm/lib llvm/lib "libclang*.a")
+ harvest(llvm/lib/clang llvm/lib/clang "*.h")
+ if(APPLE)
+ harvest(openmp/lib openmp/lib "*")
+ harvest(openmp/include openmp/include "*.h")
+ endif()
+ if(BLENDER_PLATFORM_ARM)
+ harvest(sse2neon sse2neon "*.h")
+ endif()
+ harvest(ogg/lib ffmpeg/lib "*.a")
+ harvest(openal/include openal/include "*.h")
+ if(UNIX AND NOT APPLE)
+ harvest(openal/lib openal/lib "*.a")
- harvest(blosc/include blosc/include "*.h")
- harvest(blosc/lib blosc/lib "*.a")
+ harvest(blosc/include blosc/include "*.h")
+ harvest(blosc/lib blosc/lib "*.a")
- harvest(zlib/include zlib/include "*.h")
- harvest(zlib/lib zlib/lib "*.a")
+ harvest(zlib/include zlib/include "*.h")
+ harvest(zlib/lib zlib/lib "*.a")
- harvest(xml2/include xml2/include "*.h")
- harvest(xml2/lib xml2/lib "*.a")
+ harvest(xml2/include xml2/include "*.h")
+ harvest(xml2/lib xml2/lib "*.a")
- harvest(wayland-protocols/share/wayland-protocols wayland-protocols/share/wayland-protocols/ "*.xml")
-else()
- harvest(blosc/lib openvdb/lib "*.a")
- harvest(xml2/lib opencollada/lib "*.a")
-endif()
-harvest(opencollada/include/opencollada opencollada/include "*.h")
-harvest(opencollada/lib/opencollada opencollada/lib "*.a")
-harvest(opencolorio/include opencolorio/include "*.h")
-harvest(opencolorio/lib opencolorio/lib "*.a")
-harvest(opencolorio/lib/static opencolorio/lib "*.a")
-harvest(openexr/include openexr/include "*.h")
-harvest(openexr/lib openexr/lib "*.a")
-harvest(openimageio/bin openimageio/bin "idiff")
-harvest(openimageio/bin openimageio/bin "maketx")
-harvest(openimageio/bin openimageio/bin "oiiotool")
-harvest(openimageio/include openimageio/include "*")
-harvest(openimageio/lib openimageio/lib "*.a")
-harvest(openimagedenoise/include openimagedenoise/include "*")
-harvest(openimagedenoise/lib openimagedenoise/lib "*.a")
-harvest(embree/include embree/include "*.h")
-harvest(embree/lib embree/lib "*.a")
-harvest(openjpeg/include/openjpeg-${OPENJPEG_SHORT_VERSION} openjpeg/include "*.h")
-harvest(openjpeg/lib openjpeg/lib "*.a")
-harvest(opensubdiv/include opensubdiv/include "*.h")
-harvest(opensubdiv/lib opensubdiv/lib "*.a")
-harvest(openvdb/include/openvdb openvdb/include/openvdb "*.h")
-harvest(openvdb/include/nanovdb openvdb/include/nanovdb "*.h")
-harvest(openvdb/lib openvdb/lib "*.a")
-harvest(xr_openxr_sdk/include/openxr xr_openxr_sdk/include/openxr "*.h")
-harvest(xr_openxr_sdk/lib xr_openxr_sdk/lib "*.a")
-harvest(osl/bin osl/bin "oslc")
-harvest(osl/include osl/include "*.h")
-harvest(osl/lib osl/lib "*.a")
-harvest(osl/share/OSL/shaders osl/share/OSL/shaders "*.h")
-harvest(png/include png/include "*.h")
-harvest(png/lib png/lib "*.a")
-harvest(pugixml/include pugixml/include "*.hpp")
-harvest(pugixml/lib pugixml/lib "*.a")
-harvest(python/bin python/bin "python${PYTHON_SHORT_VERSION}")
-harvest(python/include python/include "*h")
-harvest(python/lib python/lib "*")
-harvest(sdl/include/SDL2 sdl/include "*.h")
-harvest(sdl/lib sdl/lib "libSDL2.a")
-harvest(sndfile/include sndfile/include "*.h")
-harvest(sndfile/lib sndfile/lib "*.a")
-harvest(spnav/include spnav/include "*.h")
-harvest(spnav/lib spnav/lib "*.a")
-harvest(tbb/include tbb/include "*.h")
-harvest(tbb/lib/libtbb_static.a tbb/lib/libtbb.a)
-harvest(theora/lib ffmpeg/lib "*.a")
-harvest(tiff/include tiff/include "*.h")
-harvest(tiff/lib tiff/lib "*.a")
-harvest(vorbis/lib ffmpeg/lib "*.a")
-harvest(opus/lib ffmpeg/lib "*.a")
-harvest(vpx/lib ffmpeg/lib "*.a")
-harvest(x264/lib ffmpeg/lib "*.a")
-harvest(xvidcore/lib ffmpeg/lib "*.a")
-harvest(aom/lib ffmpeg/lib "*.a")
-harvest(webp/lib webp/lib "*.a")
-harvest(webp/include webp/include "*.h")
-harvest(usd/include usd/include "*.h")
-harvest(usd/lib/usd usd/lib/usd "*")
-harvest(usd/plugin usd/plugin "*")
-harvest(potrace/include potrace/include "*.h")
-harvest(potrace/lib potrace/lib "*.a")
-harvest(haru/include haru/include "*.h")
-harvest(haru/lib haru/lib "*.a")
-harvest(zstd/include zstd/include "*.h")
-harvest(zstd/lib zstd/lib "*.a")
+ harvest(wayland-protocols/share/wayland-protocols wayland-protocols/share/wayland-protocols/ "*.xml")
+ harvest(wayland/bin wayland/bin "wayland-scanner")
+ harvest(wayland/include wayland/include "*.h")
+ harvest(wayland_libdecor/include wayland_libdecor/include "*.h")
+ else()
+ harvest(blosc/lib openvdb/lib "*.a")
+ harvest(xml2/lib opencollada/lib "*.a")
+ endif()
+ harvest(opencollada/include/opencollada opencollada/include "*.h")
+ harvest(opencollada/lib/opencollada opencollada/lib "*.a")
+ harvest(opencolorio/include opencolorio/include "*.h")
+ harvest(opencolorio/lib opencolorio/lib "*.a")
+ harvest(opencolorio/lib/static opencolorio/lib "*.a")
+ harvest(openexr/include openexr/include "*.h")
+ harvest(openexr/lib openexr/lib "*.a")
+ harvest(openimageio/bin openimageio/bin "idiff")
+ harvest(openimageio/bin openimageio/bin "maketx")
+ harvest(openimageio/bin openimageio/bin "oiiotool")
+ harvest(openimageio/include openimageio/include "*")
+ harvest(openimageio/lib openimageio/lib "*.a")
+ harvest(openimagedenoise/include openimagedenoise/include "*")
+ harvest(openimagedenoise/lib openimagedenoise/lib "*.a")
+ harvest(embree/include embree/include "*.h")
+ harvest(embree/lib embree/lib "*.a")
+ harvest(openpgl/include openpgl/include "*.h")
+ harvest(openpgl/lib openpgl/lib "*.a")
+ harvest(openpgl/lib/cmake/openpgl-${OPENPGL_SHORT_VERSION} openpgl/lib/cmake/openpgl "*.cmake")
+ harvest(openjpeg/include/openjpeg-${OPENJPEG_SHORT_VERSION} openjpeg/include "*.h")
+ harvest(openjpeg/lib openjpeg/lib "*.a")
+ harvest(opensubdiv/include opensubdiv/include "*.h")
+ harvest(opensubdiv/lib opensubdiv/lib "*.a")
+ harvest(openvdb/include/openvdb openvdb/include/openvdb "*.h")
+ harvest(openvdb/include/nanovdb openvdb/include/nanovdb "*.h")
+ harvest(openvdb/lib openvdb/lib "*.a")
+ harvest(xr_openxr_sdk/include/openxr xr_openxr_sdk/include/openxr "*.h")
+ harvest(xr_openxr_sdk/lib xr_openxr_sdk/lib "*.a")
+ harvest(osl/bin osl/bin "oslc")
+ harvest(osl/include osl/include "*.h")
+ harvest(osl/lib osl/lib "*.a")
+ harvest(osl/share/OSL/shaders osl/share/OSL/shaders "*.h")
+ harvest(png/include png/include "*.h")
+ harvest(png/lib png/lib "*.a")
+ harvest(pugixml/include pugixml/include "*.hpp")
+ harvest(pugixml/lib pugixml/lib "*.a")
+ harvest(python/bin python/bin "python${PYTHON_SHORT_VERSION}")
+ harvest(python/include python/include "*h")
+ harvest(python/lib python/lib "*")
+ harvest(sdl/include/SDL2 sdl/include "*.h")
+ harvest(sdl/lib sdl/lib "libSDL2.a")
+ harvest(sndfile/include sndfile/include "*.h")
+ harvest(sndfile/lib sndfile/lib "*.a")
+ harvest(spnav/include spnav/include "*.h")
+ harvest(spnav/lib spnav/lib "*.a")
+ harvest(tbb/include tbb/include "*.h")
+ harvest(tbb/lib/libtbb_static.a tbb/lib/libtbb.a)
+ harvest(theora/lib ffmpeg/lib "*.a")
+ harvest(tiff/include tiff/include "*.h")
+ harvest(tiff/lib tiff/lib "*.a")
+ harvest(vorbis/lib ffmpeg/lib "*.a")
+ harvest(opus/lib ffmpeg/lib "*.a")
+ harvest(vpx/lib ffmpeg/lib "*.a")
+ harvest(x264/lib ffmpeg/lib "*.a")
+ harvest(xvidcore/lib ffmpeg/lib "*.a")
+ harvest(aom/lib ffmpeg/lib "*.a")
+ harvest(webp/lib webp/lib "*.a")
+ harvest(webp/include webp/include "*.h")
+ harvest(usd/include usd/include "*.h")
+ harvest(usd/lib/usd usd/lib/usd "*")
+ harvest(usd/plugin usd/plugin "*")
+ harvest(potrace/include potrace/include "*.h")
+ harvest(potrace/lib potrace/lib "*.a")
+ harvest(haru/include haru/include "*.h")
+ harvest(haru/lib haru/lib "*.a")
+ harvest(zstd/include zstd/include "*.h")
+ harvest(zstd/lib zstd/lib "*.a")
-if(UNIX AND NOT APPLE)
- harvest(libglu/lib mesa/lib "*.so*")
- harvest(mesa/lib64 mesa/lib "*.so*")
+ if(UNIX AND NOT APPLE)
+ harvest(libglu/lib mesa/lib "*.so*")
+ harvest(mesa/lib64 mesa/lib "*.so*")
- harvest(dpcpp dpcpp "*")
- harvest(igc dpcpp/lib/igc "*")
- harvest(ocloc dpcpp/lib/ocloc "*")
- endif()
+ harvest(dpcpp dpcpp "*")
+ harvest(igc dpcpp/lib/igc "*")
+ harvest(ocloc dpcpp/lib/ocloc "*")
+ endif()
endif()
diff --git a/build_files/build_environment/cmake/jpeg.cmake b/build_files/build_environment/cmake/jpeg.cmake
index 39388ad466b..118785d859b 100644
--- a/build_files/build_environment/cmake/jpeg.cmake
+++ b/build_files/build_environment/cmake/jpeg.cmake
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
if(WIN32)
- # cmake for windows
+ # CMAKE for MS-Windows.
set(JPEG_EXTRA_ARGS
-DNASM=${NASM_PATH}
-DWITH_JPEG8=ON
@@ -33,8 +33,8 @@ if(WIN32)
)
endif()
-else(WIN32)
- # cmake for unix
+else()
+ # CMAKE for UNIX.
set(JPEG_EXTRA_ARGS
-DWITH_JPEG8=ON
-DENABLE_STATIC=ON
diff --git a/build_files/build_environment/cmake/llvm.cmake b/build_files/build_environment/cmake/llvm.cmake
index e4ddc7db846..11f6bf7c218 100644
--- a/build_files/build_environment/cmake/llvm.cmake
+++ b/build_files/build_environment/cmake/llvm.cmake
@@ -9,6 +9,7 @@ endif()
if(APPLE)
set(LLVM_XML2_ARGS
-DLIBXML2_LIBRARY=${LIBDIR}/xml2/lib/libxml2.a
+ -DLIBXML2_INCLUDE_DIR=${LIBDIR}/xml2/include/libxml2
)
set(LLVM_BUILD_CLANG_TOOLS_EXTRA ^^clang-tools-extra)
set(BUILD_CLANG_TOOLS ON)
diff --git a/build_files/build_environment/cmake/opencollada.cmake b/build_files/build_environment/cmake/opencollada.cmake
index b2ae1a1a351..b1a3028debd 100644
--- a/build_files/build_environment/cmake/opencollada.cmake
+++ b/build_files/build_environment/cmake/opencollada.cmake
@@ -4,6 +4,29 @@ if(UNIX)
set(OPENCOLLADA_EXTRA_ARGS
-DLIBXML2_INCLUDE_DIR=${LIBDIR}/xml2/include/libxml2
-DLIBXML2_LIBRARIES=${LIBDIR}/xml2/lib/libxml2.a)
+
+ # WARNING: the patch contains mixed UNIX and DOS line endings
+ # as does the OPENCOLLADA package, if this can be corrected upstream that would be better.
+ # For now use `sed` to force UNIX line endings so the patch applies.
+ # Needed as neither ignoring white-space or applying as a binary resolve this problem.
+ set(PATCH_MAYBE_DOS2UNIX_CMD
+ sed -i "s/\\r//"
+ ${PATCH_DIR}/opencollada.diff
+ ${BUILD_DIR}/opencollada/src/external_opencollada/CMakeLists.txt
+ ${BUILD_DIR}/opencollada/src/external_opencollada/Externals/LibXML/CMakeLists.txt &&
+ )
+
+else()
+ set(OPENCOLLADA_EXTRA_ARGS
+ -DCMAKE_DEBUG_POSTFIX=_d
+ -DLIBXML2_INCLUDE_DIR=${LIBDIR}/xml2/include/libxml2
+ )
+ if(BUILD_MODE STREQUAL Release)
+ list(APPEND OPENCOLLADA_EXTRA_ARGS -DLIBXML2_LIBRARIES=${LIBDIR}/xml2/lib/libxml2s.lib)
+ else()
+ list(APPEND OPENCOLLADA_EXTRA_ARGS -DLIBXML2_LIBRARIES=${LIBDIR}/xml2/lib/libxml2sd.lib)
+ endif()
+ set(PATCH_MAYBE_DOS2UNIX_CMD)
endif()
ExternalProject_Add(external_opencollada
@@ -11,17 +34,19 @@ ExternalProject_Add(external_opencollada
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH ${OPENCOLLADA_HASH_TYPE}=${OPENCOLLADA_HASH}
PREFIX ${BUILD_DIR}/opencollada
- PATCH_COMMAND ${PATCH_CMD} -p 1 -N -d ${BUILD_DIR}/opencollada/src/external_opencollada < ${PATCH_DIR}/opencollada.diff
+ PATCH_COMMAND
+ ${PATCH_MAYBE_DOS2UNIX_CMD}
+ ${PATCH_CMD} -p 1 -N -d ${BUILD_DIR}/opencollada/src/external_opencollada < ${PATCH_DIR}/opencollada.diff
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/opencollada ${DEFAULT_CMAKE_FLAGS} ${OPENCOLLADA_EXTRA_ARGS}
INSTALL_DIR ${LIBDIR}/opencollada
)
-if(UNIX)
- add_dependencies(
- external_opencollada
- external_xml2
- )
-endif()
+unset(PATCH_MAYBE_DOS2UNIX_CMD)
+
+add_dependencies(
+ external_opencollada
+ external_xml2
+)
if(WIN32)
if(BUILD_MODE STREQUAL Release)
@@ -32,17 +57,7 @@ if(WIN32)
endif()
if(BUILD_MODE STREQUAL Debug)
ExternalProject_Add_Step(external_opencollada after_install
- COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/buffer.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/buffer_d.lib
- COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/ftoa.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/ftoa_d.lib
- COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/GeneratedSaxParser.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/GeneratedSaxParser_d.lib
- COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/MathMLSolver.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/MathMLSolver_d.lib
- COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/OpenCOLLADABaseUtils.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/OpenCOLLADABaseUtils_d.lib
- COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/OpenCOLLADAFramework.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/OpenCOLLADAFramework_d.lib
- COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/OpenCOLLADASaxFrameworkLoader.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/OpenCOLLADASaxFrameworkLoader_d.lib
- COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/OpenCOLLADAStreamWriter.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/OpenCOLLADAStreamWriter_d.lib
- COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/pcre.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/pcre_d.lib
- COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/UTF.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/UTF_d.lib
- COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/xml.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/xml_d.lib
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/opencollada/lib ${HARVEST_TARGET}/opencollada/lib
DEPENDEES install
)
endif()
diff --git a/build_files/build_environment/cmake/openpgl.cmake b/build_files/build_environment/cmake/openpgl.cmake
new file mode 100644
index 00000000000..b41264ac22b
--- /dev/null
+++ b/build_files/build_environment/cmake/openpgl.cmake
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# Note the utility apps may use png/tiff/gif system libraries, but the
+# library itself does not depend on them, so should give no problems.
+
+set(OPENPGL_EXTRA_ARGS
+ -DOPENPGL_BUILD_STATIC=ON
+ -DOPENPGL_TBB_ROOT=${LIBDIR}/tbb
+ -DTBB_ROOT=${LIBDIR}/tbb
+ -DCMAKE_DEBUG_POSTFIX=_d
+)
+
+if(TBB_STATIC_LIBRARY)
+ set(OPENPGL_EXTRA_ARGS
+ ${OPENPGL_EXTRA_ARGS}
+ -DOPENPGL_TBB_COMPONENT=tbb_static
+ )
+endif()
+
+ExternalProject_Add(external_openpgl
+ URL file://${PACKAGE_DIR}/${OPENPGL_FILE}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH ${OPENPGL_HASH_TYPE}=${OPENPGL_HASH}
+ PREFIX ${BUILD_DIR}/openpgl
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openpgl ${DEFAULT_CMAKE_FLAGS} ${OPENPGL_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/openpgl
+)
+
+add_dependencies(
+ external_openpgl
+ external_tbb
+)
+
+if(WIN32)
+ if(BUILD_MODE STREQUAL Release)
+ ExternalProject_Add_Step(external_openpgl after_install
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openpgl ${HARVEST_TARGET}/openpgl
+ DEPENDEES install
+ )
+ else()
+ ExternalProject_Add_Step(external_openpgl after_install
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openpgl/lib/openpgl_d.lib ${HARVEST_TARGET}/openpgl/lib/openpgl_d.lib
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openpgl/lib/cmake/openpgl-${OPENPGL_SHORT_VERSION}/openpgl_Exports-debug.cmake ${HARVEST_TARGET}/openpgl/lib/cmake/openpgl-${OPENPGL_SHORT_VERSION}/openpgl_Exports-debug.cmake
+ DEPENDEES install
+ )
+ endif()
+endif()
diff --git a/build_files/build_environment/cmake/options.cmake b/build_files/build_environment/cmake/options.cmake
index 9015ef9ac7c..13e7fb58be2 100644
--- a/build_files/build_environment/cmake/options.cmake
+++ b/build_files/build_environment/cmake/options.cmake
@@ -3,6 +3,7 @@
if(WIN32)
option(ENABLE_MINGW64 "Enable building of ffmpeg/iconv/libsndfile/fftw3 by installing mingw64" ON)
endif()
+option(FORCE_CHECK_HASH "Force a check of all hashses during CMake the configure phase" OFF)
option(WITH_BOOST_PYTHON "Enable building of boost with python support" OFF)
cmake_host_system_information(RESULT NUM_CORES QUERY NUMBER_OF_LOGICAL_CORES)
set(MAKE_THREADS ${NUM_CORES} CACHE STRING "Number of threads to run make with")
@@ -15,13 +16,13 @@ message("BuildMode = ${BUILD_MODE}")
if(BUILD_MODE STREQUAL "Debug")
set(LIBDIR ${CMAKE_CURRENT_BINARY_DIR}/Debug)
-else(BUILD_MODE STREQUAL "Debug")
+else()
set(LIBDIR ${CMAKE_CURRENT_BINARY_DIR}/Release)
endif()
set(DOWNLOAD_DIR "${CMAKE_CURRENT_BINARY_DIR}/downloads" CACHE STRING "Path for downloaded files")
-# This path must be hard-coded like this, so that the GNUmakefile knows where it is and can pass it to make_source_archive.py:
-set(PACKAGE_DIR "${CMAKE_CURRENT_BINARY_DIR}/packages")
+
+set(PACKAGE_DIR "${CMAKE_CURRENT_BINARY_DIR}/packages" CACHE PATH "default path for downloaded packages")
option(PACKAGE_USE_UPSTREAM_SOURCES "Use sources upstream to download the package sources, when OFF the blender mirror will be used" ON)
file(TO_CMAKE_PATH ${DOWNLOAD_DIR} DOWNLOAD_DIR)
@@ -101,34 +102,16 @@ else()
set(LIBPREFIX "lib")
if(APPLE)
- # Let's get the current Xcode dir, to support xcode-select
- execute_process(
- COMMAND xcode-select --print-path
- OUTPUT_VARIABLE XCODE_DEV_PATH OUTPUT_STRIP_TRAILING_WHITESPACE
- )
- execute_process(
- COMMAND xcodebuild -version -sdk macosx SDKVersion
- OUTPUT_VARIABLE MACOSX_SDK_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
-
- if(NOT CMAKE_OSX_ARCHITECTURES)
- execute_process(COMMAND uname -m OUTPUT_VARIABLE ARCHITECTURE OUTPUT_STRIP_TRAILING_WHITESPACE)
- message(STATUS "Detected native architecture ${ARCHITECTURE}.")
- set(CMAKE_OSX_ARCHITECTURES "${ARCHITECTURE}")
- endif()
- if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64")
- set(OSX_DEPLOYMENT_TARGET 10.13)
- else()
- set(OSX_DEPLOYMENT_TARGET 11.00)
- endif()
- set(OSX_SYSROOT ${XCODE_DEV_PATH}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk)
+ # Use same Xcode detection as Blender itself.
+ include(../cmake/platform/platform_apple_xcode.cmake)
if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
set(BLENDER_PLATFORM_ARM ON)
endif()
- set(PLATFORM_CFLAGS "-isysroot ${OSX_SYSROOT} -mmacosx-version-min=${OSX_DEPLOYMENT_TARGET} -arch ${CMAKE_OSX_ARCHITECTURES}")
- set(PLATFORM_CXXFLAGS "-isysroot ${OSX_SYSROOT} -mmacosx-version-min=${OSX_DEPLOYMENT_TARGET} -std=c++11 -stdlib=libc++ -arch ${CMAKE_OSX_ARCHITECTURES}")
- set(PLATFORM_LDFLAGS "-isysroot ${OSX_SYSROOT} -mmacosx-version-min=${OSX_DEPLOYMENT_TARGET} -arch ${CMAKE_OSX_ARCHITECTURES}")
+ set(PLATFORM_CFLAGS "-isysroot ${CMAKE_OSX_SYSROOT} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} -arch ${CMAKE_OSX_ARCHITECTURES}")
+ set(PLATFORM_CXXFLAGS "-isysroot ${CMAKE_OSX_SYSROOT} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} -std=c++11 -stdlib=libc++ -arch ${CMAKE_OSX_ARCHITECTURES}")
+ set(PLATFORM_LDFLAGS "-isysroot ${CMAKE_OSX_SYSROOT} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} -arch ${CMAKE_OSX_ARCHITECTURES}")
if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64")
set(PLATFORM_BUILD_TARGET --build=x86_64-apple-darwin17.0.0) # OS X 10.13
else()
@@ -136,8 +119,8 @@ else()
endif()
set(PLATFORM_CMAKE_FLAGS
-DCMAKE_OSX_ARCHITECTURES:STRING=${CMAKE_OSX_ARCHITECTURES}
- -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${OSX_DEPLOYMENT_TARGET}
- -DCMAKE_OSX_SYSROOT:PATH=${OSX_SYSROOT}
+ -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET}
+ -DCMAKE_OSX_SYSROOT:PATH=${CMAKE_OSX_SYSROOT}
)
else()
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64")
@@ -171,8 +154,8 @@ else()
set(BLENDER_CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DNDEBUG ${PLATFORM_CXXFLAGS}")
set(CONFIGURE_ENV
- export MACOSX_DEPLOYMENT_TARGET=${OSX_DEPLOYMENT_TARGET} &&
- export MACOSX_SDK_VERSION=${OSX_DEPLOYMENT_TARGET} &&
+ export MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} &&
+ export MACOSX_SDK_VERSION=${CMAKE_OSX_DEPLOYMENT_TARGET} &&
export CFLAGS=${PLATFORM_CFLAGS} &&
export CXXFLAGS=${PLATFORM_CXXFLAGS} &&
export LDFLAGS=${PLATFORM_LDFLAGS}
diff --git a/build_files/build_environment/cmake/osl.cmake b/build_files/build_environment/cmake/osl.cmake
index 9719de94d47..a5d000e4f44 100644
--- a/build_files/build_environment/cmake/osl.cmake
+++ b/build_files/build_environment/cmake/osl.cmake
@@ -32,6 +32,8 @@ set(OSL_EXTRA_ARGS
-DUSE_Qt5=OFF
-DINSTALL_DOCS=OFF
-Dpugixml_ROOT=${LIBDIR}/pugixml
+ -DTIFF_ROOT=${LIBDIR}/tiff
+ -DJPEG_ROOT=${LIBDIR}/jpeg
-DUSE_PYTHON=OFF
-DCMAKE_CXX_STANDARD=14
-DImath_ROOT=${LIBDIR}/imath
@@ -81,6 +83,7 @@ if(WIN32)
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/osl/lib/oslcomp.lib ${HARVEST_TARGET}/osl/lib/oslcomp_d.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/osl/lib/oslexec.lib ${HARVEST_TARGET}/osl/lib/oslexec_d.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/osl/lib/oslquery.lib ${HARVEST_TARGET}/osl/lib/oslquery_d.lib
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/osl/lib/oslnoise.lib ${HARVEST_TARGET}/osl/lib/oslnoise_d.lib
DEPENDEES install
)
endif()
diff --git a/build_files/build_environment/cmake/png.cmake b/build_files/build_environment/cmake/png.cmake
index 890be673cb8..371f2608e2a 100644
--- a/build_files/build_environment/cmake/png.cmake
+++ b/build_files/build_environment/cmake/png.cmake
@@ -24,6 +24,14 @@ add_dependencies(
external_zlib
)
+if(WIN32 AND BUILD_MODE STREQUAL Release)
+ ExternalProject_Add_Step(external_png after_install
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/png/include/ ${HARVEST_TARGET}/png/include/
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/png/lib/libpng16_static${LIBEXT} ${HARVEST_TARGET}/png/lib/libpng${LIBEXT}
+ DEPENDEES install
+ )
+endif()
+
if(WIN32 AND BUILD_MODE STREQUAL Debug)
ExternalProject_Add_Step(external_png after_install
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/png/lib/libpng16_staticd${LIBEXT} ${LIBDIR}/png/lib/libpng16${LIBEXT}
diff --git a/build_files/build_environment/cmake/python.cmake b/build_files/build_environment/cmake/python.cmake
index 8fed10e9d72..72ae27ddfdb 100644
--- a/build_files/build_environment/cmake/python.cmake
+++ b/build_files/build_environment/cmake/python.cmake
@@ -15,9 +15,11 @@ if(WIN32)
endmacro()
set(PYTHON_EXTERNALS_FOLDER ${BUILD_DIR}/python/src/external_python/externals)
+ set(ZLIB_SOURCE_FOLDER ${BUILD_DIR}/zlib/src/external_zlib)
set(DOWNLOADS_EXTERNALS_FOLDER ${DOWNLOAD_DIR}/externals)
cmake_to_dos_path(${PYTHON_EXTERNALS_FOLDER} PYTHON_EXTERNALS_FOLDER_DOS)
+ cmake_to_dos_path(${ZLIB_SOURCE_FOLDER} ZLIB_SOURCE_FOLDER_DOS)
cmake_to_dos_path(${DOWNLOADS_EXTERNALS_FOLDER} DOWNLOADS_EXTERNALS_FOLDER_DOS)
ExternalProject_Add(external_python
@@ -25,12 +27,21 @@ if(WIN32)
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH ${PYTHON_HASH_TYPE}=${PYTHON_HASH}
PREFIX ${BUILD_DIR}/python
- CONFIGURE_COMMAND ""
+ # Python will download its own deps and there's very little we can do about
+ # that beyond placing some code in their externals dir before it tries.
+ # the foldernames *HAVE* to match the ones inside pythons get_externals.cmd.
+ # python 3.10.8 still ships zlib 1.2.12, replace it with our 1.2.13
+ # copy until they update.
+ CONFIGURE_COMMAND mkdir ${PYTHON_EXTERNALS_FOLDER_DOS} &&
+ mklink /J ${PYTHON_EXTERNALS_FOLDER_DOS}\\zlib-1.2.12 ${ZLIB_SOURCE_FOLDER_DOS} &&
+ ${CMAKE_COMMAND} -E copy ${ZLIB_SOURCE_FOLDER}/../external_zlib-build/zconf.h ${PYTHON_EXTERNALS_FOLDER}/zlib-1.2.12/zconf.h
BUILD_COMMAND cd ${BUILD_DIR}/python/src/external_python/pcbuild/ && set IncludeTkinter=false && call build.bat -e -p x64 -c ${BUILD_MODE}
- PATCH_COMMAND ${PATCH_CMD} --verbose -p1 -d ${BUILD_DIR}/python/src/external_python < ${PATCH_DIR}/python_windows.diff
INSTALL_COMMAND ${PYTHON_BINARY_INTERNAL} ${PYTHON_SRC}/PC/layout/main.py -b ${PYTHON_SRC}/PCbuild/amd64 -s ${PYTHON_SRC} -t ${PYTHON_SRC}/tmp/ --include-stable --include-pip --include-dev --include-launchers --include-venv --include-symbols ${PYTHON_EXTRA_INSTLAL_FLAGS} --copy ${LIBDIR}/python
)
-
+ add_dependencies(
+ external_python
+ external_zlib
+ )
else()
if(APPLE)
# Disable functions that can be in 10.13 sdk but aren't available on 10.9 target.
diff --git a/build_files/build_environment/cmake/setup_mingw64.cmake b/build_files/build_environment/cmake/setup_mingw64.cmake
index fa65212e056..6f53edb38ea 100644
--- a/build_files/build_environment/cmake/setup_mingw64.cmake
+++ b/build_files/build_environment/cmake/setup_mingw64.cmake
@@ -1,10 +1,10 @@
# SPDX-License-Identifier: GPL-2.0-or-later
-####################################################################################################################
+##################################################################################################
# Mingw64 Builds
-####################################################################################################################
+##################################################################################################
# This installs mingw64+msys to compile ffmpeg/iconv/libsndfile/fftw3
-####################################################################################################################
+##################################################################################################
message("LIBDIR = ${LIBDIR}")
macro(cmake_to_msys_path MsysPath ResultingPath)
diff --git a/build_files/build_environment/cmake/sndfile.cmake b/build_files/build_environment/cmake/sndfile.cmake
index 192c25f5ed1..a2ac2a33779 100644
--- a/build_files/build_environment/cmake/sndfile.cmake
+++ b/build_files/build_environment/cmake/sndfile.cmake
@@ -11,18 +11,11 @@ else()
set(SNDFILE_OPTIONS --enable-static --disable-shared )
endif()
-if(UNIX)
- set(SNDFILE_PATCH_CMD ${PATCH_CMD} --verbose -p 0 -d ${BUILD_DIR}/sndfile/src/external_sndfile < ${PATCH_DIR}/sndfile.diff)
-else()
- set(SNDFILE_PATCH_CMD)
-endif()
-
ExternalProject_Add(external_sndfile
URL file://${PACKAGE_DIR}/${SNDFILE_FILE}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH ${SNDFILE_HASH_TYPE}=${SNDFILE_HASH}
PREFIX ${BUILD_DIR}/sndfile
- PATCH_COMMAND ${SNDFILE_PATCH_CMD}
CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/sndfile/src/external_sndfile/ && ${SNDFILE_ENV} ${CONFIGURE_COMMAND} ${SNDFILE_OPTIONS} --prefix=${mingw_LIBDIR}/sndfile
BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/sndfile/src/external_sndfile/ && make -j${MAKE_THREADS}
INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/sndfile/src/external_sndfile/ && make install
diff --git a/build_files/build_environment/cmake/sqlite.cmake b/build_files/build_environment/cmake/sqlite.cmake
index c82d832574a..c151a495ff1 100644
--- a/build_files/build_environment/cmake/sqlite.cmake
+++ b/build_files/build_environment/cmake/sqlite.cmake
@@ -48,7 +48,6 @@ ExternalProject_Add(external_sqlite
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH ${SQLITE_HASH_TYPE}=${SQLITE_HASH}
PREFIX ${BUILD_DIR}/sqlite
- PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/sqlite/src/external_sqlite < ${PATCH_DIR}/sqlite.diff
CONFIGURE_COMMAND ${SQLITE_CONFIGURE_ENV} && cd ${BUILD_DIR}/sqlite/src/external_sqlite/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/sqlite ${SQLITE_CONFIGURATION_ARGS}
BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/sqlite/src/external_sqlite/ && make -j${MAKE_THREADS}
INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/sqlite/src/external_sqlite/ && make install
diff --git a/build_files/build_environment/cmake/ssl.cmake b/build_files/build_environment/cmake/ssl.cmake
index 21c4d2418c3..628187dc0ac 100644
--- a/build_files/build_environment/cmake/ssl.cmake
+++ b/build_files/build_environment/cmake/ssl.cmake
@@ -5,6 +5,7 @@ set(SSL_PATCH_CMD echo .)
if(APPLE)
set(SSL_OS_COMPILER "blender-darwin-${CMAKE_OSX_ARCHITECTURES}")
+ set(SSL_PATCH_CMD ${PATCH_CMD} --verbose -p 0 -d ${BUILD_DIR}/ssl/src/external_ssl < ${PATCH_DIR}/ssl.diff)
else()
if(BLENDER_PLATFORM_ARM)
set(SSL_OS_COMPILER "blender-linux-aarch64")
diff --git a/build_files/build_environment/cmake/tiff.cmake b/build_files/build_environment/cmake/tiff.cmake
index 1f8e9442ae5..1ac2e4c6058 100644
--- a/build_files/build_environment/cmake/tiff.cmake
+++ b/build_files/build_environment/cmake/tiff.cmake
@@ -25,6 +25,7 @@ ExternalProject_Add(external_tiff
add_dependencies(
external_tiff
external_zlib
+ external_jpeg
)
if(WIN32)
if(BUILD_MODE STREQUAL Release)
diff --git a/build_files/build_environment/cmake/usd.cmake b/build_files/build_environment/cmake/usd.cmake
index 34e43383637..0661be3ba14 100644
--- a/build_files/build_environment/cmake/usd.cmake
+++ b/build_files/build_environment/cmake/usd.cmake
@@ -58,8 +58,9 @@ set(USD_EXTRA_ARGS
-DPXR_BUILD_USD_TOOLS=OFF
-DCMAKE_DEBUG_POSTFIX=_d
-DBUILD_SHARED_LIBS=Off
- # USD is hellbound on making a shared lib, unless you point this variable to a valid cmake file
- # doesn't have to make sense, but as long as it points somewhere valid it will skip the shared lib.
+ # USD is hellbound on making a shared library,
+ # unless you point this variable to a valid CMAKE file doesn't have to make sense,
+ # but as long as it points somewhere valid it will skip the shared library.
-DPXR_MONOLITHIC_IMPORT=${BUILD_DIR}/usd/src/external_usd/cmake/defaults/Version.cmake
-DTBB_INCLUDE_DIRS=${LIBDIR}/tbb/include
-DTBB_LIBRARIES=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${LIBEXT}
@@ -86,7 +87,8 @@ add_dependencies(
external_opensubdiv
)
-# Since USD 21.11 the libraries are prefixed with "usd_", i.e. "libusd_m.a" became "libusd_usd_m.a".
+# Since USD 21.11 the libraries are prefixed with "usd_", i.e.
+# "libusd_m.a" became "libusd_usd_m.a".
# See https://github.com/PixarAnimationStudios/USD/blob/release/CHANGELOG.md#2111---2021-11-01
if(NOT WIN32)
if (USD_VERSION VERSION_LESS 21.11)
diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake
index 95425300923..4f4330b56f4 100644
--- a/build_files/build_environment/cmake/versions.cmake
+++ b/build_files/build_environment/cmake/versions.cmake
@@ -1,10 +1,19 @@
# SPDX-License-Identifier: GPL-2.0-or-later
-set(ZLIB_VERSION 1.2.12)
+# CPE's are used to identify dependencies, for more information on what they
+# are please see https://nvd.nist.gov/products/cpe
+#
+# We use them in combination with cve-bin-tool to scan for known security issues.
+#
+# Not all of our dependencies are currently in the nvd database so not all
+# dependencies have one assigned.
+
+set(ZLIB_VERSION 1.2.13)
set(ZLIB_URI https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz)
-set(ZLIB_HASH 5fc414a9726be31427b440b434d05f78)
+set(ZLIB_HASH 9b8aa094c4e5765dabf4da391f00d15c)
set(ZLIB_HASH_TYPE MD5)
set(ZLIB_FILE zlib-${ZLIB_VERSION}.tar.gz)
+set(ZLIB_CPE "cpe:2.3:a:zlib:zlib:${ZLIB_VERSION}:*:*:*:*:*:*:*")
set(OPENAL_VERSION 1.21.1)
set(OPENAL_URI http://openal-soft.org/openal-releases/openal-soft-${OPENAL_VERSION}.tar.bz2)
@@ -17,12 +26,14 @@ set(PNG_URI http://prdownloads.sourceforge.net/libpng/libpng-${PNG_VERSION}.tar.
set(PNG_HASH 505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca)
set(PNG_HASH_TYPE SHA256)
set(PNG_FILE libpng-${PNG_VERSION}.tar.xz)
+set(PNG_CPE "cpe:2.3:a:libpng:libpng:${PNG_VERSION}:*:*:*:*:*:*:*")
set(JPEG_VERSION 2.1.3)
set(JPEG_URI https://github.com/libjpeg-turbo/libjpeg-turbo/archive/${JPEG_VERSION}.tar.gz)
set(JPEG_HASH 627b980fad0573e08e4c3b80b290fc91)
set(JPEG_HASH_TYPE MD5)
set(JPEG_FILE libjpeg-turbo-${JPEG_VERSION}.tar.gz)
+set(JPEG_CPE "cpe:2.3:a:d.r.commander:libjpeg-turbo:${JPEG_VERSION}:*:*:*:*:*:*:*")
set(BOOST_VERSION 1.78.0)
set(BOOST_VERSION_SHORT 1.78)
@@ -32,12 +43,14 @@ set(BOOST_URI https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION
set(BOOST_HASH c2f6428ac52b0e5a3c9b2e1d8cc832b5)
set(BOOST_HASH_TYPE MD5)
set(BOOST_FILE boost_${BOOST_VERSION_NODOTS}.tar.gz)
+set(BOOST_CPE "cpe:2.3:a:boost:boost:${BOOST_VERSION}:*:*:*:*:*:*:*")
set(BLOSC_VERSION 1.21.1)
set(BLOSC_URI https://github.com/Blosc/c-blosc/archive/v${BLOSC_VERSION}.tar.gz)
set(BLOSC_HASH 134b55813b1dca57019d2a2dc1f7a923)
set(BLOSC_HASH_TYPE MD5)
set(BLOSC_FILE blosc-${BLOSC_VERSION}.tar.gz)
+set(BLOSC_CPE "cpe:2.3:a:c-blosc2_project:c-blosc2:${BLOSC_VERSION}:*:*:*:*:*:*:*")
set(PTHREADS_VERSION 3.0.0)
set(PTHREADS_URI http://prdownloads.sourceforge.net/pthreads4w/pthreads4w-code-v${PTHREADS_VERSION}.zip)
@@ -50,6 +63,7 @@ set(OPENEXR_URI https://github.com/AcademySoftwareFoundation/openexr/archive/v${
set(OPENEXR_HASH a92f38eedd43e56c0af56d4852506886)
set(OPENEXR_HASH_TYPE MD5)
set(OPENEXR_FILE openexr-${OPENEXR_VERSION}.tar.gz)
+set(OPENEXR_CPE "cpe:2.3:a:openexr:openexr:${OPENEXR_VERSION}:*:*:*:*:*:*:*")
set(IMATH_VERSION 3.1.5)
set(IMATH_URI https://github.com/AcademySoftwareFoundation/Imath/archive/v${OPENEXR_VERSION}.tar.gz)
@@ -74,11 +88,12 @@ else()
set(OPENEXR_VERSION_POSTFIX)
endif()
-set(FREETYPE_VERSION 2.11.1)
+set(FREETYPE_VERSION 2.12.1)
set(FREETYPE_URI http://prdownloads.sourceforge.net/freetype/freetype-${FREETYPE_VERSION}.tar.gz)
-set(FREETYPE_HASH bd4e3b007474319909a6b79d50908e85)
+set(FREETYPE_HASH 8bc5c9c9df7ac12c504f8918552a7cf2)
set(FREETYPE_HASH_TYPE MD5)
set(FREETYPE_FILE freetype-${FREETYPE_VERSION}.tar.gz)
+SET(FREETYPE_CPE "cpe:2.3:a:freetype:freetype:${FREETYPE_VERSION}:*:*:*:*:*:*:*")
set(EPOXY_VERSION 1.5.10)
set(EPOXY_URI https://github.com/anholt/libepoxy/archive/refs/tags/${EPOXY_VERSION}.tar.gz)
@@ -97,6 +112,7 @@ set(ALEMBIC_URI https://github.com/alembic/alembic/archive/${ALEMBIC_VERSION}.ta
set(ALEMBIC_HASH 2cd8d6e5a3ac4a014e24a4b04f4fadf9)
set(ALEMBIC_HASH_TYPE MD5)
set(ALEMBIC_FILE alembic-${ALEMBIC_VERSION}.tar.gz)
+SET(FREETYPE_CPE "cpe:2.3:a:freetype:freetype:${FREETYPE_VERSION}:*:*:*:*:*:*:*")
set(OPENSUBDIV_VERSION v3_4_4)
set(OPENSUBDIV_URI https://github.com/PixarAnimationStudios/OpenSubdiv/archive/${OPENSUBDIV_VERSION}.tar.gz)
@@ -109,6 +125,7 @@ set(SDL_URI https://www.libsdl.org/release/SDL2-${SDL_VERSION}.tar.gz)
set(SDL_HASH a53acc02e1cca98c4123229069b67c9e)
set(SDL_HASH_TYPE MD5)
set(SDL_FILE SDL2-${SDL_VERSION}.tar.gz)
+set(SDL_CPE "cpe:2.3:a:libsdl:sdl:${SDL_VERSION}:*:*:*:*:*:*:*")
set(OPENCOLLADA_VERSION v1.6.68)
set(OPENCOLLADA_URI https://github.com/KhronosGroup/OpenCOLLADA/archive/${OPENCOLLADA_VERSION}.tar.gz)
@@ -127,6 +144,7 @@ set(LLVM_URI https://github.com/llvm/llvm-project/releases/download/llvmorg-${LL
set(LLVM_HASH 5a4fab4d7fc84aefffb118ac2c8a4fc0)
set(LLVM_HASH_TYPE MD5)
set(LLVM_FILE llvm-project-${LLVM_VERSION}.src.tar.xz)
+set(LLVM_CPE "cpe:2.3:a:llvm:compiler:${LLVM_VERSION}:*:*:*:*:*:*:*")
if(APPLE)
# Cloth physics test is crashing due to this bug:
@@ -141,9 +159,9 @@ set(OPENMP_URI https://github.com/llvm/llvm-project/releases/download/llvmorg-${
set(OPENMP_HASH_TYPE MD5)
set(OPENMP_FILE openmp-${OPENMP_VERSION}.src.tar.xz)
-set(OPENIMAGEIO_VERSION v2.3.13.0)
+set(OPENIMAGEIO_VERSION v2.3.20.0)
set(OPENIMAGEIO_URI https://github.com/OpenImageIO/oiio/archive/refs/tags/${OPENIMAGEIO_VERSION}.tar.gz)
-set(OPENIMAGEIO_HASH de45fb38501c4581062b522b53b6141c)
+set(OPENIMAGEIO_HASH defb1fe7c8e64bac60eb3cacaf5c3736)
set(OPENIMAGEIO_HASH_TYPE MD5)
set(OPENIMAGEIO_FILE OpenImageIO-${OPENIMAGEIO_VERSION}.tar.gz)
@@ -154,6 +172,7 @@ set(FMT_URI https://github.com/fmtlib/fmt/archive/refs/tags/${FMT_VERSION}.tar.g
set(FMT_HASH 7bce0e9e022e586b178b150002e7c2339994e3c2bbe44027e9abb0d60f9cce83)
set(FMT_HASH_TYPE SHA256)
set(FMT_FILE fmt-${FMT_VERSION}.tar.gz)
+set(FMT_CPE "cpe:2.3:a:fmt:fmt:${FMT_VERSION}:*:*:*:*:*:*:*")
# 0.6.2 is currently oiio's preferred version although never versions may be available.
# the preferred version can be found in oiio's externalpackages.cmake
@@ -168,26 +187,30 @@ set(TIFF_URI http://download.osgeo.org/libtiff/tiff-${TIFF_VERSION}.tar.gz)
set(TIFF_HASH 376f17f189e9d02280dfe709b2b2bbea)
set(TIFF_HASH_TYPE MD5)
set(TIFF_FILE tiff-${TIFF_VERSION}.tar.gz)
+set(TIFF_CPE "cpe:2.3:a:libtiff:libtiff:${TIFF_VERSION}:*:*:*:*:*:*:*")
-set(OSL_VERSION 1.11.17.0)
-set(OSL_URI https://github.com/imageworks/OpenShadingLanguage/archive/Release-${OSL_VERSION}.tar.gz)
-set(OSL_HASH 63265472ce14548839ace2e21e401544)
+set(OSL_VERSION 1.12.6.2)
+set(OSL_URI https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/archive/refs/tags/v${OSL_VERSION}.tar.gz)
+set(OSL_HASH 6fef11548adfdd3e5b25c49d2dae96ee)
set(OSL_HASH_TYPE MD5)
set(OSL_FILE OpenShadingLanguage-${OSL_VERSION}.tar.gz)
-set(PYTHON_VERSION 3.10.2)
+set(PYTHON_VERSION 3.10.8)
set(PYTHON_SHORT_VERSION 3.10)
set(PYTHON_SHORT_VERSION_NO_DOTS 310)
set(PYTHON_URI https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tar.xz)
-set(PYTHON_HASH 14e8c22458ed7779a1957b26cde01db9)
+set(PYTHON_HASH e92356b012ed4d0e09675131d39b1bde)
set(PYTHON_HASH_TYPE MD5)
set(PYTHON_FILE Python-${PYTHON_VERSION}.tar.xz)
+set(PYTHON_CPE "cpe:2.3:a:python:python:${PYTHON_VERSION}:-:*:*:*:*:*:*")
-set(TBB_VERSION 2020_U3)
+set(TBB_YEAR 2020)
+set(TBB_VERSION ${TBB_YEAR}_U3)
set(TBB_URI https://github.com/oneapi-src/oneTBB/archive/${TBB_VERSION}.tar.gz)
set(TBB_HASH 55ec8df6eae5ed6364a47f0e671e460c)
set(TBB_HASH_TYPE MD5)
set(TBB_FILE oneTBB-${TBB_VERSION}.tar.gz)
+set(TBB_CPE "cpe:2.3:a:intel:threading_building_blocks:${TBB_YEAR}:*:*:*:*:*:*:*")
set(OPENVDB_VERSION 9.0.0)
set(OPENVDB_URI https://github.com/AcademySoftwareFoundation/openvdb/archive/v${OPENVDB_VERSION}.tar.gz)
@@ -198,11 +221,13 @@ set(OPENVDB_FILE openvdb-${OPENVDB_VERSION}.tar.gz)
set(IDNA_VERSION 3.3)
set(CHARSET_NORMALIZER_VERSION 2.0.10)
set(URLLIB3_VERSION 1.26.8)
+set(URLLIB3_CPE "cpe:2.3:a:urllib3:urllib3:${URLLIB3_VERSION}:*:*:*:*:*:*:*")
set(CERTIFI_VERSION 2021.10.8)
set(REQUESTS_VERSION 2.27.1)
set(CYTHON_VERSION 0.29.26)
-# The version of the zstd library used to build the Python package should match ZSTD_VERSION defined below.
-# At this time of writing, 0.17.0 was already released, but built against zstd 1.5.1, while we use 1.5.0.
+# The version of the zstd library used to build the Python package should match ZSTD_VERSION
+# defined below. At this time of writing, 0.17.0 was already released,
+# but built against zstd 1.5.1, while we use 1.5.0.
set(ZSTANDARD_VERSION 0.16.0)
set(AUTOPEP8_VERSION 1.6.0)
set(PYCODESTYLE_VERSION 2.8.0)
@@ -214,12 +239,14 @@ set(NUMPY_URI https://github.com/numpy/numpy/releases/download/v${NUMPY_VERSION}
set(NUMPY_HASH 252de134862a27bd66705d29622edbfe)
set(NUMPY_HASH_TYPE MD5)
set(NUMPY_FILE numpy-${NUMPY_VERSION}.zip)
+set(NUMPY_CPE "cpe:2.3:a:numpy:numpy:${NUMPY_VERSION}:*:*:*:*:*:*:*")
set(LAME_VERSION 3.100)
set(LAME_URI http://downloads.sourceforge.net/project/lame/lame/3.100/lame-${LAME_VERSION}.tar.gz)
set(LAME_HASH 83e260acbe4389b54fe08e0bdbf7cddb)
set(LAME_HASH_TYPE MD5)
set(LAME_FILE lame-${LAME_VERSION}.tar.gz)
+set(LAME_CPE "cpe:2.3:a:lame_project:lame:${LAME_VERSION}:*:*:*:*:*:*:*")
set(OGG_VERSION 1.3.5)
set(OGG_URI http://downloads.xiph.org/releases/ogg/libogg-${OGG_VERSION}.tar.gz)
@@ -232,6 +259,7 @@ set(VORBIS_URI http://downloads.xiph.org/releases/vorbis/libvorbis-${VORBIS_VERS
set(VORBIS_HASH 0e982409a9c3fc82ee06e08205b1355e5c6aa4c36bca58146ef399621b0ce5ab)
set(VORBIS_HASH_TYPE SHA256)
set(VORBIS_FILE libvorbis-${VORBIS_VERSION}.tar.gz)
+set(VORBIS_CPE "cpe:2.3:a:xiph.org:libvorbis:${VORBIS_VERSION}:*:*:*:*:*:*:*")
set(THEORA_VERSION 1.1.1)
set(THEORA_URI http://downloads.xiph.org/releases/theora/libtheora-${THEORA_VERSION}.tar.bz2)
@@ -244,12 +272,14 @@ set(FLAC_URI http://downloads.xiph.org/releases/flac/flac-${FLAC_VERSION}.tar.xz
set(FLAC_HASH 8ff0607e75a322dd7cd6ec48f4f225471404ae2730d0ea945127b1355155e737 )
set(FLAC_HASH_TYPE SHA256)
set(FLAC_FILE flac-${FLAC_VERSION}.tar.xz)
+set(FLAC_CPE "cpe:2.3:a:flac_project:flac:${FLAC_VERSION}:*:*:*:*:*:*:*")
set(VPX_VERSION 1.11.0)
set(VPX_URI https://github.com/webmproject/libvpx/archive/v${VPX_VERSION}/libvpx-v${VPX_VERSION}.tar.gz)
set(VPX_HASH 965e51c91ad9851e2337aebcc0f517440c637c506f3a03948062e3d5ea129a83)
set(VPX_HASH_TYPE SHA256)
set(VPX_FILE libvpx-v${VPX_VERSION}.tar.gz)
+set(VPX_CPE "cpe:2.3:a:webmproject:libvpx:${VPX_VERSION}:*:*:*:*:*:*:*")
set(OPUS_VERSION 1.3.1)
set(OPUS_URI https://archive.mozilla.org/pub/opus/opus-${OPUS_VERSION}.tar.gz)
@@ -269,18 +299,20 @@ set(XVIDCORE_HASH abbdcbd39555691dd1c9b4d08f0a031376a3b211652c0d8b3b8aa9be1303ce
set(XVIDCORE_HASH_TYPE SHA256)
set(XVIDCORE_FILE xvidcore-${XVIDCORE_VERSION}.tar.gz)
-set(OPENJPEG_VERSION 2.4.0)
-set(OPENJPEG_SHORT_VERSION 2.4)
+set(OPENJPEG_VERSION 2.5.0)
+set(OPENJPEG_SHORT_VERSION 2.5)
set(OPENJPEG_URI https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}.tar.gz)
-set(OPENJPEG_HASH 8702ba68b442657f11aaeb2b338443ca8d5fb95b0d845757968a7be31ef7f16d)
+set(OPENJPEG_HASH 0333806d6adecc6f7a91243b2b839ff4d2053823634d4f6ed7a59bc87409122a)
set(OPENJPEG_HASH_TYPE SHA256)
set(OPENJPEG_FILE openjpeg-v${OPENJPEG_VERSION}.tar.gz)
+set(OPENJPEG_CPE "cpe:2.3:a:uclouvain:openjpeg:${OPENJPEG_VERSION}:*:*:*:*:*:*:*")
-set(FFMPEG_VERSION 5.0)
+set(FFMPEG_VERSION 5.1.2)
set(FFMPEG_URI http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2)
-set(FFMPEG_HASH c0130b8db2c763430fd1c6905288d61bc44ee0548ad5fcd2dfd650b88432bed9)
+set(FFMPEG_HASH 39a0bcc8d98549f16c570624678246a6ac736c066cebdb409f9502e915b22f2b)
set(FFMPEG_HASH_TYPE SHA256)
set(FFMPEG_FILE ffmpeg-${FFMPEG_VERSION}.tar.bz2)
+set(FFMPEG_CPE "cpe:2.3:a:ffmpeg:ffmpeg:${FFMPEG_VERSION}:*:*:*:*:*:*:*")
set(FFTW_VERSION 3.3.10)
set(FFTW_URI http://www.fftw.org/fftw-${FFTW_VERSION}.tar.gz)
@@ -294,17 +326,19 @@ set(ICONV_HASH 7d2a800b952942bb2880efb00cfd524c)
set(ICONV_HASH_TYPE MD5)
set(ICONV_FILE libiconv-${ICONV_VERSION}.tar.gz)
-set(SNDFILE_VERSION 1.0.28)
-set(SNDFILE_URI http://www.mega-nerd.com/libsndfile/files/libsndfile-${SNDFILE_VERSION}.tar.gz)
-set(SNDFILE_HASH 646b5f98ce89ac60cdb060fcd398247c)
+set(SNDFILE_VERSION 1.1.0)
+set(SNDFILE_URI https://github.com/libsndfile/libsndfile/releases/download/1.1.0/libsndfile-${SNDFILE_VERSION}.tar.xz)
+set(SNDFILE_HASH e63dead2b4f0aaf323687619d007ee6a)
set(SNDFILE_HASH_TYPE MD5)
set(SNDFILE_FILE libsndfile-${SNDFILE_VERSION}.tar.gz)
+set(SNDFILE_CPE "cpe:2.3:a:libsndfile_project:libsndfile:${SNDFILE_VERSION}:*:*:*:*:*:*:*")
set(WEBP_VERSION 1.2.2)
set(WEBP_URI https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-${WEBP_VERSION}.tar.gz)
set(WEBP_HASH b5e2e414a8adee4c25fe56b18dd9c549)
set(WEBP_HASH_TYPE MD5)
set(WEBP_FILE libwebp-${WEBP_VERSION}.tar.gz)
+set(WEBP_CPE "cpe:2.3:a:webmproject:libwebp:${WEBP_VERSION}:*:*:*:*:*:*:*")
set(SPNAV_VERSION 0.2.3)
set(SPNAV_URI http://downloads.sourceforge.net/project/spacenav/spacenav%20library%20%28SDK%29/libspnav%20${SPNAV_VERSION}/libspnav-${SPNAV_VERSION}.tar.gz)
@@ -318,24 +352,19 @@ set(JEMALLOC_HASH 3d41fbf006e6ebffd489bdb304d009ae)
set(JEMALLOC_HASH_TYPE MD5)
set(JEMALLOC_FILE jemalloc-${JEMALLOC_VERSION}.tar.bz2)
-set(XML2_VERSION 2.9.10)
-set(XML2_URI http://xmlsoft.org/sources/libxml2-${XML2_VERSION}.tar.gz)
-set(XML2_HASH 10942a1dc23137a8aa07f0639cbfece5)
+set(XML2_VERSION 2.10.3)
+set(XML2_URI https://download.gnome.org/sources/libxml2/2.10/libxml2-${XML2_VERSION}.tar.xz)
+set(XML2_HASH f9edac7fac232b3657a003fd9a5bbe42)
set(XML2_HASH_TYPE MD5)
-set(XML2_FILE libxml2-${XML2_VERSION}.tar.gz)
-
-set(TINYXML_VERSION 2_6_2)
-set(TINYXML_VERSION_DOTS 2.6.2)
-set(TINYXML_URI https://nchc.dl.sourceforge.net/project/tinyxml/tinyxml/${TINYXML_VERSION_DOTS}/tinyxml_${TINYXML_VERSION}.tar.gz)
-set(TINYXML_HASH c1b864c96804a10526540c664ade67f0)
-set(TINYXML_HASH_TYPE MD5)
-set(TINYXML_FILE tinyxml_${TINYXML_VERSION}.tar.gz)
+set(XML2_FILE libxml2-${XML2_VERSION}.tar.xz)
+set(XML2_CPE "cpe:2.3:a:xmlsoft:libxml2:${XML2_VERSION}:*:*:*:*:*:*:*")
set(YAMLCPP_VERSION 0.6.3)
set(YAMLCPP_URI https://codeload.github.com/jbeder/yaml-cpp/tar.gz/yaml-cpp-${YAMLCPP_VERSION})
set(YAMLCPP_HASH b45bf1089a382e81f6b661062c10d0c2)
set(YAMLCPP_HASH_TYPE MD5)
set(YAMLCPP_FILE yaml-cpp-${YAMLCPP_VERSION}.tar.gz)
+set(YAMLCPP "cpe:2.3:a:yaml-cpp_project:yaml-cpp:${YAMLCPP_VERSION}:*:*:*:*:*:*:*")
set(PYSTRING_VERSION v1.1.3)
set(PYSTRING_URI https://codeload.github.com/imageworks/pystring/tar.gz/refs/tags/${PYSTRING_VERSION})
@@ -343,17 +372,20 @@ set(PYSTRING_HASH f2c68786b359f5e4e62bed53bc4fb86d)
set(PYSTRING_HASH_TYPE MD5)
set(PYSTRING_FILE pystring-${PYSTRING_VERSION}.tar.gz)
-set(EXPAT_VERSION 2_4_4)
+set(EXPAT_VERSION 2_5_0)
+set(EXPAT_VERSION_DOTS 2.5.0)
set(EXPAT_URI https://github.com/libexpat/libexpat/archive/R_${EXPAT_VERSION}.tar.gz)
-set(EXPAT_HASH 2d3e81dee94b452369dc6394ff0f8f98)
+set(EXPAT_HASH d375fa3571c0abb945873f5061a8f2e2)
set(EXPAT_HASH_TYPE MD5)
set(EXPAT_FILE libexpat-${EXPAT_VERSION}.tar.gz)
+set(EXPAT_CPE "cpe:2.3:a:libexpat_project:libexpat:${EXPAT_VERSION_DOTS}:*:*:*:*:*:*:*")
set(PUGIXML_VERSION 1.10)
set(PUGIXML_URI https://github.com/zeux/pugixml/archive/v${PUGIXML_VERSION}.tar.gz)
set(PUGIXML_HASH 0c208b0664c7fb822bf1b49ad035e8fd)
set(PUGIXML_HASH_TYPE MD5)
set(PUGIXML_FILE pugixml-${PUGIXML_VERSION}.tar.gz)
+set(PUGIXML_CPE "cpe:2.3:a:pugixml_project:pugixml:${PUGIXML_VERSION}:*:*:*:*:*:*:*")
set(FLEXBISON_VERSION 2.5.24)
set(FLEXBISON_URI http://prdownloads.sourceforge.net/winflexbison/win_flex_bison-${FLEXBISON_VERSION}.zip)
@@ -371,17 +403,26 @@ set(FLEX_FILE flex-${FLEX_VERSION}.tar.gz)
# NOTE: bzip.org domain does no longer belong to BZip 2 project, so we download
# sources from Debian packaging.
+#
+# NOTE 2: This will *HAVE* to match the version python ships on windows which
+# is hardcoded in pythons PCbuild/get_externals.bat. For compliance reasons there
+# can be no exceptions to this.
set(BZIP2_VERSION 1.0.8)
set(BZIP2_URI http://http.debian.net/debian/pool/main/b/bzip2/bzip2_${BZIP2_VERSION}.orig.tar.gz)
set(BZIP2_HASH ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269)
set(BZIP2_HASH_TYPE SHA256)
set(BZIP2_FILE bzip2_${BZIP2_VERSION}.orig.tar.gz)
+set(BZIP2_CPE "cpe:2.3:a:bzip:bzip2:${BZIP2_VERSION}:*:*:*:*:*:*:*")
+# NOTE: This will *HAVE* to match the version python ships on windows which
+# is hardcoded in pythons PCbuild/get_externals.bat. For compliance reasons there
+# can be no exceptions to this.
set(FFI_VERSION 3.3)
set(FFI_URI https://sourceware.org/pub/libffi/libffi-${FFI_VERSION}.tar.gz)
set(FFI_HASH 72fba7922703ddfa7a028d513ac15a85c8d54c8d67f55fa5a4802885dc652056)
set(FFI_HASH_TYPE SHA256)
set(FFI_FILE libffi-${FFI_VERSION}.tar.gz)
+set(FFI_CPE "cpe:2.3:a:libffi_project:libffi:${FFI_VERSION}:*:*:*:*:*:*:*")
set(LZMA_VERSION 5.2.5)
set(LZMA_URI https://tukaani.org/xz/xz-${LZMA_VERSION}.tar.bz2)
@@ -389,26 +430,26 @@ set(LZMA_HASH 5117f930900b341493827d63aa910ff5e011e0b994197c3b71c08a20228a42df)
set(LZMA_HASH_TYPE SHA256)
set(LZMA_FILE xz-${LZMA_VERSION}.tar.bz2)
-if(BLENDER_PLATFORM_ARM)
- # Need at least 1.1.1i for aarch64 support (https://github.com/openssl/openssl/pull/13218)
- set(SSL_VERSION 1.1.1i)
- set(SSL_URI https://www.openssl.org/source/openssl-${SSL_VERSION}.tar.gz)
- set(SSL_HASH e8be6a35fe41d10603c3cc635e93289ed00bf34b79671a3a4de64fcee00d5242)
- set(SSL_HASH_TYPE SHA256)
- set(SSL_FILE openssl-${SSL_VERSION}.tar.gz)
-else()
- set(SSL_VERSION 1.1.1g)
- set(SSL_URI https://www.openssl.org/source/openssl-${SSL_VERSION}.tar.gz)
- set(SSL_HASH ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46)
- set(SSL_HASH_TYPE SHA256)
- set(SSL_FILE openssl-${SSL_VERSION}.tar.gz)
-endif()
-
-set(SQLITE_VERSION 3.31.1)
-set(SQLITE_URI https://www.sqlite.org/2018/sqlite-src-3240000.zip)
-set(SQLITE_HASH fb558c49ee21a837713c4f1e7e413309aabdd9c7)
+# NOTE: This will *HAVE* to match the version python ships on windows which
+# is hardcoded in pythons PCbuild/get_externals.bat. For compliance reasons there
+# can be no exceptions to this.
+set(SSL_VERSION 1.1.1q)
+set(SSL_URI https://www.openssl.org/source/openssl-${SSL_VERSION}.tar.gz)
+set(SSL_HASH d7939ce614029cdff0b6c20f0e2e5703158a489a72b2507b8bd51bf8c8fd10ca)
+set(SSL_HASH_TYPE SHA256)
+set(SSL_FILE openssl-${SSL_VERSION}.tar.gz)
+set(SSL_CPE "cpe:2.3:a:openssl:openssl:${SSL_VERSION}:*:*:*:*:*:*:*")
+
+# Note: This will *HAVE* to match the version python ships on windows which
+# is hardcoded in pythons PCbuild/get_externals.bat for compliance reasons there
+# can be no exceptions to this.
+set(SQLITE_VERSION 3.37.2)
+set(SQLLITE_LONG_VERSION 3370200)
+set(SQLITE_URI https://www.sqlite.org/2022/sqlite-autoconf-${SQLLITE_LONG_VERSION}.tar.gz)
+set(SQLITE_HASH e56faacadfb4154f8fbd0f2a3f827d13706b70a1)
set(SQLITE_HASH_TYPE SHA1)
-set(SQLITE_FILE sqlite-src-3240000.zip)
+set(SQLITE_FILE sqlite-autoconf-${SQLLITE_LONG_VERSION}.tar.gz)
+set(SQLITE_CPE "cpe:2.3:a:sqlite:sqlite:${SQLITE_VERSION}:*:*:*:*:*:*:*")
set(EMBREE_VERSION 3.13.4)
set(EMBREE_URI https://github.com/embree/embree/archive/v${EMBREE_VERSION}.zip)
@@ -439,12 +480,14 @@ set(MESA_URI ftp://ftp.freedesktop.org/pub/mesa/mesa-${MESA_VERSION}.tar.xz)
set(MESA_HASH 022c7293074aeeced2278c872db4fa693147c70f8595b076cf3f1ef81520766d)
set(MESA_HASH_TYPE SHA256)
set(MESA_FILE mesa-${MESA_VERSION}.tar.xz)
+set(MESA_CPE "cpe:2.3:a:mesa3d:mesa:${MESA_VERSION}:*:*:*:*:*:*:*")
set(NASM_VERSION 2.15.02)
set(NASM_URI https://github.com/netwide-assembler/nasm/archive/nasm-${NASM_VERSION}.tar.gz)
set(NASM_HASH aded8b796c996a486a56e0515c83e414116decc3b184d88043480b32eb0a8589)
set(NASM_HASH_TYPE SHA256)
set(NASM_FILE nasm-${NASM_VERSION}.tar.gz)
+set(NASM_PCE "cpe:2.3:a:nasm:nasm:${NASM_VERSION}:*:*:*:*:*:*:*")
set(XR_OPENXR_SDK_VERSION 1.0.22)
set(XR_OPENXR_SDK_URI https://github.com/KhronosGroup/OpenXR-SDK/archive/release-${XR_OPENXR_SDK_VERSION}.tar.gz)
@@ -458,6 +501,18 @@ set(WL_PROTOCOLS_URI https://gitlab.freedesktop.org/wayland/wayland-protocols/-/
set(WL_PROTOCOLS_HASH af5ca07e13517cdbab33504492cef54a)
set(WL_PROTOCOLS_HASH_TYPE MD5)
+set(WAYLAND_VERSION 1.21.0)
+set(WAYLAND_FILE wayland-${WAYLAND_VERSION}.tar.xz)
+set(WAYLAND_URI https://gitlab.freedesktop.org/wayland/wayland/-/releases/1.21.0/downloads/wayland-${WAYLAND_VERSION}.tar.xz)
+set(WAYLAND_HASH f2653a2293bcd882d756c6a83d278903)
+set(WAYLAND_HASH_TYPE MD5)
+
+set(WAYLAND_LIBDECOR_VERSION 0.1.0)
+set(WAYLAND_LIBDECOR_FILE libdecor-${WAYLAND_LIBDECOR_VERSION}.tar.xz)
+set(WAYLAND_LIBDECOR_URI https://gitlab.gnome.org/jadahl/libdecor/uploads/81adf91d27620e20bcc5f6b9b312d768/libdecor-${WAYLAND_LIBDECOR_VERSION}.tar.xz )
+set(WAYLAND_LIBDECOR_HASH 47b59eba76faa3787f0878bf8700e912)
+set(WAYLAND_LIBDECOR_HASH_TYPE MD5)
+
set(ISPC_VERSION v1.17.0)
set(ISPC_URI https://github.com/ispc/ispc/archive/${ISPC_VERSION}.tar.gz)
set(ISPC_HASH 4f476a3109332a77fe839a9014c60ca9)
@@ -469,12 +524,14 @@ set(GMP_URI https://gmplib.org/download/gmp/gmp-${GMP_VERSION}.tar.xz)
set(GMP_HASH 0b82665c4a92fd2ade7440c13fcaa42b)
set(GMP_HASH_TYPE MD5)
set(GMP_FILE gmp-${GMP_VERSION}.tar.xz)
+set(GMP_CPE "cpe:2.3:a:gmplib:gmp:${GMP_VERSION}:*:*:*:*:*:*:*")
set(POTRACE_VERSION 1.16)
set(POTRACE_URI http://potrace.sourceforge.net/download/${POTRACE_VERSION}/potrace-${POTRACE_VERSION}.tar.gz)
set(POTRACE_HASH 5f0bd87ddd9a620b0c4e65652ef93d69)
set(POTRACE_HASH_TYPE MD5)
set(POTRACE_FILE potrace-${POTRACE_VERSION}.tar.gz)
+set(POTRACE_CPE "cpe:2.3:a:icoasoft:potrace:${POTRACE_VERSION}:*:*:*:*:*:*:*")
set(HARU_VERSION 2_3_0)
set(HARU_URI https://github.com/libharu/libharu/archive/RELEASE_${HARU_VERSION}.tar.gz)
@@ -487,6 +544,7 @@ set(ZSTD_URI https://github.com/facebook/zstd/releases/download/v${ZSTD_VERSION}
set(ZSTD_HASH 5194fbfa781fcf45b98c5e849651aa7b3b0a008c6b72d4a0db760f3002291e94)
set(ZSTD_HASH_TYPE SHA256)
set(ZSTD_FILE zstd-${ZSTD_VERSION}.tar.gz)
+set(ZSTD_CPE "cpe:2.3:a:facebook:zstandard:${ZSTD_VERSION}:*:*:*:*:*:*:*")
set(SSE2NEON_VERSION fe5ff00bb8d19b327714a3c290f3e2ce81ba3525)
set(SSE2NEON_URI https://github.com/DLTcollab/sse2neon/archive/${SSE2NEON_VERSION}.tar.gz)
@@ -494,21 +552,29 @@ set(SSE2NEON_HASH 0780253525d299c31775ef95853698d03db9c7739942af8570000f4a25a5d6
set(SSE2NEON_HASH_TYPE SHA256)
set(SSE2NEON_FILE sse2neon-${SSE2NEON_VERSION}.tar.gz)
-set(BROTLI_VERSION v1.0.9)
-set(BROTLI_URI https://github.com/google/brotli/archive/refs/tags/${BROTLI_VERSION}.tar.gz)
+set(BROTLI_VERSION 1.0.9)
+set(BROTLI_URI https://github.com/google/brotli/archive/refs/tags/v${BROTLI_VERSION}.tar.gz)
set(BROTLI_HASH f9e8d81d0405ba66d181529af42a3354f838c939095ff99930da6aa9cdf6fe46)
set(BROTLI_HASH_TYPE SHA256)
-set(BROTLI_FILE brotli-${BROTLI_VERSION}.tar.gz)
+set(BROTLI_FILE brotli-v${BROTLI_VERSION}.tar.gz)
+set(BROTLI_CPE "cpe:2.3:a:google:brotli:${BROTLI_VERSION}:*:*:*:*:*:*:*")
+
+set(OPENPGL_VERSION v0.4.1-beta)
+set(OPENPGL_SHORT_VERSION 0.4.1)
+set(OPENPGL_URI https://github.com/OpenPathGuidingLibrary/openpgl/archive/refs/tags/${OPENPGL_VERSION}.tar.gz)
+set(OPENPGL_HASH db63f5dac5cfa8c110ede241f0c413f00db0c4748697381c4fa23e0f9e82a754)
+set(OPENPGL_HASH_TYPE SHA256)
+set(OPENPGL_FILE openpgl-${OPENPGL_VERSION}.tar.gz)
-set(LEVEL_ZERO_VERSION v1.7.15)
+set(LEVEL_ZERO_VERSION v1.8.5)
set(LEVEL_ZERO_URI https://github.com/oneapi-src/level-zero/archive/refs/tags/${LEVEL_ZERO_VERSION}.tar.gz)
-set(LEVEL_ZERO_HASH c39bb05a8e5898aa6c444e1704105b93d3f1888b9c333f8e7e73825ffbfb2617)
+set(LEVEL_ZERO_HASH b6e9663bbcc53c148d32376998298bec6f7c434ef2218c61fa708963e3a09394)
set(LEVEL_ZERO_HASH_TYPE SHA256)
set(LEVEL_ZERO_FILE level-zero-${LEVEL_ZERO_VERSION}.tar.gz)
-set(DPCPP_VERSION 20220812)
+set(DPCPP_VERSION 20221019)
set(DPCPP_URI https://github.com/intel/llvm/archive/refs/tags/sycl-nightly/${DPCPP_VERSION}.tar.gz)
-set(DPCPP_HASH 0e3c95346c295f5cf80f3a42d80b1c49481955898530242636ddc002627248d6)
+set(DPCPP_HASH 2f533946e91ce3829431758ea17b0b834b960c1a796e9e4563c86e03eb9603a2)
set(DPCPP_HASH_TYPE SHA256)
set(DPCPP_FILE DPCPP-${DPCPP_VERSION}.tar.gz)
@@ -521,9 +587,9 @@ set(DPCPP_FILE DPCPP-${DPCPP_VERSION}.tar.gz)
# will take care of building them, unpack is being done in dpcpp_deps.cmake
# Source llvm/lib/SYCLLowerIR/CMakeLists.txt
-set(VCINTRINSICS_VERSION 984bb27baacce6ee5c716c2e64845f2a1928025b)
+set(VCINTRINSICS_VERSION abce9184b7a3a7fe1b02289b9285610d9dc45465)
set(VCINTRINSICS_URI https://github.com/intel/vc-intrinsics/archive/${VCINTRINSICS_VERSION}.tar.gz)
-set(VCINTRINSICS_HASH abea415a15a0dd11fdc94dee8fb462910f2548311b787e02f42509789e1b0d7b)
+set(VCINTRINSICS_HASH 3e9fd471246b87633b26f7e15e17ab7733d357458c53d5c5881c03929d6c551f)
set(VCINTRINSICS_HASH_TYPE SHA256)
set(VCINTRINSICS_FILE vc-intrinsics-${VCINTRINSICS_VERSION}.tar.gz)
@@ -535,9 +601,9 @@ set(OPENCLHEADERS_HASH_TYPE SHA256)
set(OPENCLHEADERS_FILE opencl_headers-${OPENCLHEADERS_VERSION}.tar.gz)
# Source opencl/CMakeLists.txt
-set(ICDLOADER_VERSION aec3952654832211636fc4af613710f80e203b0a)
+set(ICDLOADER_VERSION 792682ad3d877ab38573b997808bab3b43902b70)
set(ICDLOADER_URI https://github.com/KhronosGroup/OpenCL-ICD-Loader/archive/${ICDLOADER_VERSION}.tar.gz)
-set(ICDLOADER_HASH e1880551d67bd8dc31d13de63b94bbfd6b1f315b6145dad1ffcd159b89bda93c)
+set(ICDLOADER_HASH b33a0320d94bf300efa1da97931ded506d27813bd1148da6858fe79d412d1ea2)
set(ICDLOADER_HASH_TYPE SHA256)
set(ICDLOADER_FILE icdloader-${ICDLOADER_VERSION}.tar.gz)
@@ -552,9 +618,9 @@ set(MP11_FILE mp11-${MP11_VERSION}.tar.gz)
# Source llvm-spirv/CMakeLists.txt (repo)
# Source llvm-spirv/spirv-headers-tag.conf (hash)
-set(SPIRV_HEADERS_VERSION 36c0c1596225e728bd49abb7ef56a3953e7ed468)
+set(SPIRV_HEADERS_VERSION 5a121866927a16ab9d49bed4788b532c7fcea766)
set(SPIRV_HEADERS_URI https://github.com/KhronosGroup/SPIRV-Headers/archive/${SPIRV_HEADERS_VERSION}.tar.gz)
-set(SPIRV_HEADERS_HASH 7a5c89633f8740456fe8adee052033e134476d267411d1336c0cb1e587a9229a)
+set(SPIRV_HEADERS_HASH ec8ecb471a62672697846c436501638ab25447ae9d4a6761e0bfe8a9a839502a)
set(SPIRV_HEADERS_HASH_TYPE SHA256)
set(SPIRV_HEADERS_FILE SPIR-V-Headers-${SPIRV_HEADERS_VERSION}.tar.gz)
@@ -569,9 +635,9 @@ set(SPIRV_HEADERS_FILE SPIR-V-Headers-${SPIRV_HEADERS_VERSION}.tar.gz)
# compiler, the versions used are taken from the following location
# https://github.com/intel/intel-graphics-compiler/releases
-set(IGC_VERSION 1.0.11222)
+set(IGC_VERSION 1.0.12149.1)
set(IGC_URI https://github.com/intel/intel-graphics-compiler/archive/refs/tags/igc-${IGC_VERSION}.tar.gz)
-set(IGC_HASH d92f0608dcbb52690855685f9447282e5c09c0ba98ae35fabf114fcf8b1e9fcf)
+set(IGC_HASH 44f67f24e3bc5130f9f062533abf8154782a9d0a992bc19b498639a8521ae836)
set(IGC_HASH_TYPE SHA256)
set(IGC_FILE igc-${IGC_VERSION}.tar.gz)
@@ -591,15 +657,15 @@ set(IGC_LLVM_FILE ${IGC_LLVM_VERSION}.tar.gz)
#
# WARNING WARNING WARNING
-set(IGC_OPENCL_CLANG_VERSION bbdd1587f577397a105c900be114b56755d1f7dc)
+set(IGC_OPENCL_CLANG_VERSION 363a5262d8c7cff3fb28f3bdb5d85c8d7e91c1bb)
set(IGC_OPENCL_CLANG_URI https://github.com/intel/opencl-clang/archive/${IGC_OPENCL_CLANG_VERSION}.tar.gz)
-set(IGC_OPENCL_CLANG_HASH d08315f1b0d8a6fef33de2b3e6aa7356534c324910634962c72523d970773efc)
+set(IGC_OPENCL_CLANG_HASH aa8cf72bb239722ce8ce44f79413c6887ecc8ca18477dd520aa5c4809756da9a)
set(IGC_OPENCL_CLANG_HASH_TYPE SHA256)
set(IGC_OPENCL_CLANG_FILE opencl-clang-${IGC_OPENCL_CLANG_VERSION}.tar.gz)
-set(IGC_VCINTRINSICS_VERSION v0.4.0)
+set(IGC_VCINTRINSICS_VERSION v0.5.0)
set(IGC_VCINTRINSICS_URI https://github.com/intel/vc-intrinsics/archive/refs/tags/${IGC_VCINTRINSICS_VERSION}.tar.gz)
-set(IGC_VCINTRINSICS_HASH c8b92682ad5031cf9d5b82a40e7d5c0e763cd9278660adbcaa69aab988e4b589)
+set(IGC_VCINTRINSICS_HASH 70bb47c5e32173cf61514941e83ae7c7eb4485e6d2fca60cfa1f50d4f42c41f2)
set(IGC_VCINTRINSICS_HASH_TYPE SHA256)
set(IGC_VCINTRINSICS_FILE vc-intrinsics-${IGC_VCINTRINSICS_VERSION}.tar.gz)
@@ -615,9 +681,9 @@ set(IGC_SPIRV_TOOLS_HASH 6e19900e948944243024aedd0a201baf3854b377b9cc7a386553bc1
set(IGC_SPIRV_TOOLS_HASH_TYPE SHA256)
set(IGC_SPIRV_TOOLS_FILE SPIR-V-Tools-${IGC_SPIRV_TOOLS_VERSION}.tar.gz)
-set(IGC_SPIRV_TRANSLATOR_VERSION 99420daab98998a7e36858befac9c5ed109d4920)
+set(IGC_SPIRV_TRANSLATOR_VERSION a31ffaeef77e23d500b3ea3d35e0c42ff5648ad9)
set(IGC_SPIRV_TRANSLATOR_URI https://github.com/KhronosGroup/SPIRV-LLVM-Translator/archive/${IGC_SPIRV_TRANSLATOR_VERSION}.tar.gz)
-set(IGC_SPIRV_TRANSLATOR_HASH 77dfb4ddb6bfb993535562c02ddea23f0a0d1c5a0258c1afe7e27c894ff783a8)
+set(IGC_SPIRV_TRANSLATOR_HASH 9e26c96a45341b8f8af521bacea20e752623346340addd02af95d669f6e89252)
set(IGC_SPIRV_TRANSLATOR_HASH_TYPE SHA256)
set(IGC_SPIRV_TRANSLATOR_FILE SPIR-V-Translator-${IGC_SPIRV_TRANSLATOR_VERSION}.tar.gz)
@@ -625,15 +691,15 @@ set(IGC_SPIRV_TRANSLATOR_FILE SPIR-V-Translator-${IGC_SPIRV_TRANSLATOR_VERSION}.
### Intel Graphics Compiler DEPS END ###
########################################
-set(GMMLIB_VERSION intel-gmmlib-22.1.2)
+set(GMMLIB_VERSION intel-gmmlib-22.1.8)
set(GMMLIB_URI https://github.com/intel/gmmlib/archive/refs/tags/${GMMLIB_VERSION}.tar.gz)
-set(GMMLIB_HASH 3b9a6d5e7e3f5748b3d0a2fb0e980ae943907fece0980bd9c0508e71c838e334)
+set(GMMLIB_HASH bf23e9a3742b4fb98c7666c9e9b29f3219e4b2fb4d831aaf4eed71f5e2d17368)
set(GMMLIB_HASH_TYPE SHA256)
set(GMMLIB_FILE ${GMMLIB_VERSION}.tar.gz)
-set(OCLOC_VERSION 22.20.23198)
+set(OCLOC_VERSION 22.38.24278)
set(OCLOC_URI https://github.com/intel/compute-runtime/archive/refs/tags/${OCLOC_VERSION}.tar.gz)
-set(OCLOC_HASH ab22b8bf2560a57fdd3def0e35a62ca75991406f959c0263abb00cd6cd9ae998)
+set(OCLOC_HASH db0c542fccd651e6404b15a74d46027f1ce0eda8dc9e25a40cbb6c0faef257ee)
set(OCLOC_HASH_TYPE SHA256)
set(OCLOC_FILE ocloc-${OCLOC_VERSION}.tar.gz)
diff --git a/build_files/build_environment/cmake/wayland.cmake b/build_files/build_environment/cmake/wayland.cmake
new file mode 100644
index 00000000000..c73db1d10ff
--- /dev/null
+++ b/build_files/build_environment/cmake/wayland.cmake
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+ExternalProject_Add(external_wayland
+ URL file://${PACKAGE_DIR}/${WAYLAND_FILE}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH ${WAYLAND_HASH_TYPE}=${WAYLAND_HASH}
+ PREFIX ${BUILD_DIR}/wayland
+ PATCH_COMMAND ${PATCH_CMD} -d ${BUILD_DIR}/wayland/src/external_wayland < ${PATCH_DIR}/wayland.diff
+ # Use `-E` so the `PKG_CONFIG_PATH` can be defined to link against our own LIBEXPAT & LIBXML2.
+ #
+ # NOTE: passing link args "ffi/lib" should not be needed, but
+ # `pkgconfig` would incorrectly look in "ffi/lib/../lib64" otherwise.
+ #
+ # NOTE: `-lm` is needed for `libxml2` which is a static library that uses `libm.so`,
+ # without this, math symbols such as `floor` aren't found.
+ CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env PKG_CONFIG_PATH=${LIBDIR}/expat/lib/pkgconfig:${LIBDIR}/xml2/lib/pkgconfig:${LIBDIR}/ffi/lib/pkgconfig:$PKG_CONFIG_PATH
+ meson --prefix ${LIBDIR}/wayland -Ddocumentation=false -Dtests=false -D "c_link_args=-L${LIBDIR}/ffi/lib -lm" . ../external_wayland
+ BUILD_COMMAND ninja
+ INSTALL_COMMAND ninja install
+)
+
+add_dependencies(
+ external_wayland
+ external_expat
+ external_xml2
+ external_ffi
+)
diff --git a/build_files/build_environment/cmake/wayland_libdecor.cmake b/build_files/build_environment/cmake/wayland_libdecor.cmake
new file mode 100644
index 00000000000..f4628fa3a1b
--- /dev/null
+++ b/build_files/build_environment/cmake/wayland_libdecor.cmake
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# NOTE: currently only the header file is extracted, no compilation is needed
+# as the library is dynamically loaded when found on the system.
+
+ExternalProject_Add(external_wayland_libdecor
+ URL file://${PACKAGE_DIR}/${WAYLAND_LIBDECOR_FILE}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH ${WAYLAND_LIBDECOR_HASH_TYPE}=${WAYLAND_LIBDECOR_HASH}
+ PREFIX ${BUILD_DIR}/wayland_libdecor
+ BUILD_COMMAND echo .
+ CONFIGURE_COMMAND echo .
+ INSTALL_COMMAND cp ../external_wayland_libdecor/src/libdecor.h ${LIBDIR}/wayland_libdecor/include/libdecor-0/libdecor.h
+ INSTALL_DIR ${LIBDIR}/wayland_libdecor/include/libdecor-0
+)
diff --git a/build_files/build_environment/cmake/wayland_protocols.cmake b/build_files/build_environment/cmake/wayland_protocols.cmake
index 23d29b49260..9bdbc38fd6c 100644
--- a/build_files/build_environment/cmake/wayland_protocols.cmake
+++ b/build_files/build_environment/cmake/wayland_protocols.cmake
@@ -5,7 +5,14 @@ ExternalProject_Add(external_wayland_protocols
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH ${WL_PROTOCOLS_HASH_TYPE}=${WL_PROTOCOLS_HASH}
PREFIX ${BUILD_DIR}/wayland-protocols
- CONFIGURE_COMMAND meson --prefix ${LIBDIR}/wayland-protocols . ../external_wayland_protocols -Dtests=false
+ # Use `-E` so the `PKG_CONFIG_PATH` can be defined to link against our own WAYLAND.
+ CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env PKG_CONFIG_PATH=${LIBDIR}/wayland/lib64/pkgconfig:$PKG_CONFIG_PATH
+ meson --prefix ${LIBDIR}/wayland-protocols . ../external_wayland_protocols -Dtests=false
BUILD_COMMAND ninja
INSTALL_COMMAND ninja install
)
+
+add_dependencies(
+ external_wayland_protocols
+ external_wayland
+)
diff --git a/build_files/build_environment/cmake/xml2.cmake b/build_files/build_environment/cmake/xml2.cmake
index cd24fd836b0..3d31ec131bb 100644
--- a/build_files/build_environment/cmake/xml2.cmake
+++ b/build_files/build_environment/cmake/xml2.cmake
@@ -1,20 +1,48 @@
# SPDX-License-Identifier: GPL-2.0-or-later
-ExternalProject_Add(external_xml2
- URL file://${PACKAGE_DIR}/${XML2_FILE}
- DOWNLOAD_DIR ${DOWNLOAD_DIR}
- URL_HASH ${XML2_HASH_TYPE}=${XML2_HASH}
- PREFIX ${BUILD_DIR}/xml2
- CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/xml2/src/external_xml2/ && ${CONFIGURE_COMMAND}
- --prefix=${LIBDIR}/xml2
- --disable-shared
- --enable-static
- --with-pic
- --with-python=no
- --with-lzma=no
- --with-zlib=no
- --with-iconv=no
- BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/xml2/src/external_xml2/ && make -j${MAKE_THREADS}
- INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/xml2/src/external_xml2/ && make install
- INSTALL_DIR ${LIBDIR}/xml2
-)
+if(WIN32)
+ set(XML2_EXTRA_ARGS
+ -DLIBXML2_WITH_ZLIB=OFF
+ -DLIBXML2_WITH_LZMA=OFF
+ -DLIBXML2_WITH_PYTHON=OFF
+ -DLIBXML2_WITH_ICONV=OFF
+ -DLIBXML2_WITH_TESTS=OFF
+ -DLIBXML2_WITH_PROGRAMS=OFF
+ -DBUILD_SHARED_LIBS=OFF
+ )
+ ExternalProject_Add(external_xml2
+ URL file://${PACKAGE_DIR}/${XML2_FILE}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH ${XML2_HASH_TYPE}=${XML2_HASH}
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/xml2 ${DEFAULT_CMAKE_FLAGS} ${XML2_EXTRA_ARGS}
+ PREFIX ${BUILD_DIR}/xml2
+ INSTALL_DIR ${LIBDIR}/xml2
+ )
+else()
+ ExternalProject_Add(external_xml2
+ URL file://${PACKAGE_DIR}/${XML2_FILE}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH ${XML2_HASH_TYPE}=${XML2_HASH}
+ PREFIX ${BUILD_DIR}/xml2
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/xml2/src/external_xml2/ && ${CONFIGURE_COMMAND}
+ --prefix=${LIBDIR}/xml2
+ --disable-shared
+ --enable-static
+ --with-pic
+ --with-python=no
+ --with-lzma=no
+ --with-zlib=no
+ --with-iconv=no
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/xml2/src/external_xml2/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/xml2/src/external_xml2/ && make install
+ INSTALL_DIR ${LIBDIR}/xml2
+ )
+endif()
+
+if(WIN32 AND BUILD_MODE STREQUAL Release)
+ ExternalProject_Add_Step(external_xml2 after_install
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/xml2/include ${HARVEST_TARGET}/xml2/include
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/xml2/lib/libxml2s.lib ${HARVEST_TARGET}/xml2/lib/libxml2s.lib
+ DEPENDEES install
+ )
+endif()
diff --git a/build_files/build_environment/dependencies.dot b/build_files/build_environment/dependencies.dot
index 7e8637fbced..bb42856c3ac 100644
--- a/build_files/build_environment/dependencies.dot
+++ b/build_files/build_environment/dependencies.dot
@@ -1,96 +1,114 @@
strict graph {
-graph[autosize = false, size = "25.7,8.3!", resolution = 300, overlap = false, splines = false, outputorder=edgesfirst ];
- node [style=filled fillcolor=white];
- external_alembic -- external_boost;
- external_alembic -- external_zlib;
+graph[autosize = false, size = "25.7,8.3!", resolution = 300];
external_alembic -- external_openexr;
+ external_alembic -- external_imath;
external_blosc -- external_zlib;
external_blosc -- external_pthreads;
- external_boost -- Make_Python_Environment;
- external_clang -- ll;
+ external_boost -- external_python;
+ external_boost -- external_numpy;
+ external_dpcpp -- external_python;
+ external_dpcpp -- external_python_site_packages;
+ external_dpcpp -- external_vcintrinsics;
+ external_dpcpp -- external_openclheaders;
+ external_dpcpp -- external_icdloader;
+ external_dpcpp -- external_mp11;
+ external_dpcpp -- external_level_zero;
+ external_dpcpp -- external_spirvheaders;
+ external_embree -- external_tbb;
external_ffmpeg -- external_zlib;
- external_ffmpeg -- external_faad;
external_ffmpeg -- external_openjpeg;
external_ffmpeg -- external_xvidcore;
external_ffmpeg -- external_x264;
+ external_ffmpeg -- external_opus;
external_ffmpeg -- external_vpx;
external_ffmpeg -- external_theora;
external_ffmpeg -- external_vorbis;
external_ffmpeg -- external_ogg;
external_ffmpeg -- external_lame;
+ external_ffmpeg -- external_aom;
external_ffmpeg -- external_zlib_mingw;
- external_numpy -- Make_Python_Environment;
+ external_ffmpeg -- external_nasm;
+ external_freetype -- external_brotli;
+ external_freetype -- external_zlib;
+ external_gmpxx -- external_gmp;
+ external_igc_llvm -- external_igc_opencl_clang;
+ external_igc_spirv_translator -- external_igc_opencl_clang;
+ external_igc -- external_igc_vcintrinsics;
+ external_igc -- external_igc_llvm;
+ external_igc -- external_igc_opencl_clang;
+ external_igc -- external_igc_vcintrinsics;
+ external_igc -- external_igc_spirv_headers;
+ external_igc -- external_igc_spirv_tools;
+ external_igc -- external_igc_spirv_translator;
+ external_igc -- external_flex;
+ external_ispc -- ll;
+ external_ispc -- external_python;
+ external_ispc -- external_flexbison;
+ external_ispc -- external_flex;
+ ll -- external_xml2;
+ ll -- external_python;
+ external_mesa -- ll;
+ external_numpy -- external_python;
+ external_numpy -- external_python_site_packages;
+ external_ocloc -- external_igc;
+ external_ocloc -- external_gmmlib;
external_opencollada -- external_xml2;
- external_opencolorio -- external_boost;
- external_opencolorio -- external_tinyxml;
external_opencolorio -- external_yamlcpp;
+ external_opencolorio -- external_expat;
+ external_opencolorio -- external_imath;
+ external_opencolorio -- external_pystring;
external_openexr -- external_zlib;
+ external_openimagedenoise -- external_tbb;
+ external_openimagedenoise -- external_ispc;
+ external_openimagedenoise -- external_python;
external_openimageio -- external_png;
external_openimageio -- external_zlib;
external_openimageio -- external_openexr;
- external_openimageio -- external_openexr;
+ external_openimageio -- external_imath;
external_openimageio -- external_jpeg;
external_openimageio -- external_boost;
external_openimageio -- external_tiff;
- external_openimageio -- external_opencolorio;
+ external_openimageio -- external_pugixml;
+ external_openimageio -- external_fmt;
+ external_openimageio -- external_robinmap;
external_openimageio -- external_openjpeg;
external_openimageio -- external_webp;
- external_openimageio -- external_opencolorio_extra;
- external_openmp -- external_clang;
+ external_openmp -- ll;
+ external_openpgl -- external_tbb;
external_opensubdiv -- external_tbb;
openvdb -- external_tbb;
openvdb -- external_boost;
- openvdb -- external_openexr;
- openvdb -- external_openexr;
openvdb -- external_zlib;
openvdb -- external_blosc;
external_osl -- external_boost;
external_osl -- ll;
- external_osl -- external_clang;
- external_osl -- external_openexr;
external_osl -- external_openexr;
external_osl -- external_zlib;
- external_osl -- external_flexbison;
external_osl -- external_openimageio;
external_osl -- external_pugixml;
+ external_osl -- external_flexbison;
+ external_osl -- external_flex;
external_png -- external_zlib;
- external_python_site_packages -- Make_Python_Environment;
+ external_python -- external_bzip2;
+ external_python -- external_ffi;
+ external_python -- external_lzma;
+ external_python -- external_ssl;
+ external_python -- external_sqlite;
+ external_python -- external_zlib;
+ external_python_site_packages -- external_python;
external_sndfile -- external_ogg;
external_sndfile -- external_vorbis;
external_sndfile -- external_flac;
external_theora -- external_vorbis;
external_theora -- external_ogg;
external_tiff -- external_zlib;
+ external_usd -- external_tbb;
+ external_usd -- external_boost;
+ external_usd -- external_opensubdiv;
external_vorbis -- external_ogg;
- blender-- external_ffmpeg;
- blender-- external_alembic;
- blender-- external_openjpeg;
- blender-- external_opencolorio;
- blender-- external_openexr;
- blender-- external_opensubdiv;
- blender-- openvdb;
- blender-- external_osl;
- blender-- external_boost;
- blender-- external_jpeg;
- blender-- external_png;
- blender-- external_python;
- blender-- external_sndfile;
- blender-- external_iconv;
- blender-- external_fftw3;
- external_python-- external_python_site_packages;
- external_python_site_packages-- requests;
- external_python_site_packages-- idna;
- external_python_site_packages-- chardet;
- external_python_site_packages-- urllib3;
- external_python_site_packages-- certifi;
- external_python-- external_numpy;
- external_usd-- external_boost;
- external_usd-- external_tbb;
- blender-- external_opencollada;
- blender-- external_sdl;
- blender-- external_freetype;
- blender-- external_pthreads;
- blender-- external_zlib;
- blender-- external_openal;
- blender-- external_usd;
+ external_wayland -- external_expat;
+ external_wayland -- external_xml2;
+ external_wayland -- external_ffi;
+ external_wayland_protocols -- external_wayland;
+ external_x264 -- external_nasm;
}
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh
index 287a7a0c962..5a191f7669b 100755
--- a/build_files/build_environment/install_deps.sh
+++ b/build_files/build_environment/install_deps.sh
@@ -40,15 +40,15 @@ ver-ocio:,ver-oiio:,ver-llvm:,ver-osl:,ver-osd:,ver-openvdb:,ver-xr-openxr:,ver-
force-all,force-python,force-boost,force-tbb,\
force-ocio,force-imath,force-openexr,force-oiio,force-llvm,force-osl,force-osd,force-openvdb,\
force-ffmpeg,force-opencollada,force-alembic,force-embree,force-oidn,force-usd,\
-force-xr-openxr,force-level-zero,\
+force-xr-openxr,force-level-zero, force-openpgl,\
build-all,build-python,build-boost,build-tbb,\
build-ocio,build-imath,build-openexr,build-oiio,build-llvm,build-osl,build-osd,build-openvdb,\
build-ffmpeg,build-opencollada,build-alembic,build-embree,build-oidn,build-usd,\
-build-xr-openxr,build-level-zero,\
+build-xr-openxr,build-level-zero, build-openpgl,\
skip-python,skip-boost,skip-tbb,\
skip-ocio,skip-imath,skip-openexr,skip-oiio,skip-llvm,skip-osl,skip-osd,skip-openvdb,\
skip-ffmpeg,skip-opencollada,skip-alembic,skip-embree,skip-oidn,skip-usd,\
-skip-xr-openxr,skip-level-zero \
+skip-xr-openxr,skip-level-zero, skip-openpgl \
-- "$@" \
)
@@ -136,7 +136,7 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
Build and install the OpenImageDenoise libraries.
--with-nanovdb
- Build and install NanoVDB together with OpenVDB.
+ Build and install the NanoVDB branch of OpenVDB (instead of official release of OpenVDB).
--with-jack
Install the jack libraries.
@@ -232,6 +232,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
--build-level-zero=<ver>
Force the build of OneAPI Level Zero library.
+ --build-openpgl
+ Force the build of OpenPGL library.
+
Note about the --build-foo options:
* They force the script to prefer building dependencies rather than using available packages.
This may make things simpler and allow working around some distribution bugs, but on the other hand it will
@@ -302,6 +305,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
--force-level-zero=<ver>
Force the rebuild of OneAPI Level Zero library.
+ --force-openpgl
+ Force the rebuild of OpenPGL library.
+
Note about the --force-foo options:
* They obviously only have an effect if those libraries are built by this script
(i.e. if there is no available and satisfactory package)!
@@ -363,7 +369,10 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
Unconditionally skip OpenXR-SDK installation/building.
--skip-level-zero=<ver>
- Unconditionally skip OneAPI Level Zero installation/building.\""
+ Unconditionally skip OneAPI Level Zero installation/building.
+
+ --skip-openpgl
+ Unconditionally skip OpenPGL installation/building.\""
# ----------------------------------------------------------------------------
# Main Vars
@@ -385,7 +394,7 @@ CLANG_FORMAT_VERSION="10.0"
CLANG_FORMAT_VERSION_MIN="6.0"
CLANG_FORMAT_VERSION_MEX="14.0"
-PYTHON_VERSION="3.10.6"
+PYTHON_VERSION="3.10.8"
PYTHON_VERSION_SHORT="3.10"
PYTHON_VERSION_MIN="3.10"
PYTHON_VERSION_MEX="3.12"
@@ -425,7 +434,7 @@ PYTHON_ZSTANDARD_VERSION_MIN="0.15.2"
PYTHON_ZSTANDARD_VERSION_MEX="0.20.0"
PYTHON_ZSTANDARD_NAME="zstandard"
-PYTHON_NUMPY_VERSION="1.23.2"
+PYTHON_NUMPY_VERSION="1.22.0"
PYTHON_NUMPY_VERSION_MIN="1.14"
PYTHON_NUMPY_VERSION_MEX="2.0"
PYTHON_NUMPY_NAME="numpy"
@@ -453,8 +462,8 @@ PYTHON_MODULES_PIP=(
)
-BOOST_VERSION="1.80.0"
-BOOST_VERSION_SHORT="1.80"
+BOOST_VERSION="1.78.0"
+BOOST_VERSION_SHORT="1.78"
BOOST_VERSION_MIN="1.49"
BOOST_VERSION_MEX="2.0"
BOOST_FORCE_BUILD=false
@@ -496,7 +505,7 @@ OPENEXR_FORCE_REBUILD=false
OPENEXR_SKIP=false
_with_built_openexr=false
-OIIO_VERSION="2.3.18.0"
+OIIO_VERSION="2.3.20.0"
OIIO_VERSION_SHORT="2.3"
OIIO_VERSION_MIN="2.1.12"
OIIO_VERSION_MEX="2.4.0"
@@ -514,8 +523,8 @@ LLVM_FORCE_REBUILD=false
LLVM_SKIP=false
# OSL needs to be compiled for now!
-OSL_VERSION="1.11.17.0"
-OSL_VERSION_SHORT="1.11"
+OSL_VERSION="1.12.6.2"
+OSL_VERSION_SHORT="1.12"
OSL_VERSION_MIN="1.11"
OSL_VERSION_MEX="2.0"
OSL_FORCE_BUILD=false
@@ -534,10 +543,10 @@ OSD_SKIP=false
# OpenVDB needs to be compiled for now
OPENVDB_BLOSC_VERSION="1.21.1"
-OPENVDB_VERSION="9.1.0"
-OPENVDB_VERSION_SHORT="9.1"
+OPENVDB_VERSION="9.0.0"
+OPENVDB_VERSION_SHORT="9.0"
OPENVDB_VERSION_MIN="9.0"
-OPENVDB_VERSION_MEX="9.2"
+OPENVDB_VERSION_MEX="9.1"
OPENVDB_FORCE_BUILD=false
OPENVDB_FORCE_REBUILD=false
OPENVDB_SKIP=false
@@ -593,6 +602,14 @@ LEVEL_ZERO_FORCE_BUILD=false
LEVEL_ZERO_FORCE_REBUILD=false
LEVEL_ZERO_SKIP=false
+OPENPGL_VERSION="0.4.0"
+OPENPGL_VERSION_SHORT="0.4"
+OPENPGL_VERSION_MIN="0.3.1"
+OPENPGL_VERSION_MEX="0.5"
+OPENPGL_FORCE_BUILD=false
+OPENPGL_FORCE_REBUILD=false
+OPENPGL_SKIP=false
+
XR_OPENXR_VERSION="1.0.22"
XR_OPENXR_VERSION_SHORT="1.0"
XR_OPENXR_VERSION_MIN="1.0.8"
@@ -601,8 +618,8 @@ XR_OPENXR_FORCE_BUILD=false
XR_OPENXR_FORCE_REBUILD=false
XR_OPENXR_SKIP=false
-FFMPEG_VERSION="5.0"
-FFMPEG_VERSION_SHORT="5.0"
+FFMPEG_VERSION="5.1.2"
+FFMPEG_VERSION_SHORT="5.1"
FFMPEG_VERSION_MIN="4.0"
FFMPEG_VERSION_MEX="6.0"
FFMPEG_FORCE_BUILD=false
@@ -827,6 +844,7 @@ while true; do
USD_FORCE_BUILD=true
XR_OPENXR_FORCE_BUILD=true
LEVEL_ZERO_FORCE_BUILD=true
+ OPENPGL_FORCE_BUILD=true
shift; continue
;;
--build-python)
@@ -887,6 +905,9 @@ while true; do
--build-level-zero)
LEVEL_ZERO_FORCE_BUILD=true; shift; continue
;;
+ --build-openpgl)
+ OPENPGL_FORCE_BUILD=true; shift; continue
+ ;;
--force-all)
PYTHON_FORCE_REBUILD=true
BOOST_FORCE_REBUILD=true
@@ -907,6 +928,7 @@ while true; do
USD_FORCE_REBUILD=true
XR_OPENXR_FORCE_REBUILD=true
LEVEL_ZERO_FORCE_REBUILD=true
+ OPENPGL_FORCE_REBUILD=true
shift; continue
;;
--force-python)
@@ -967,6 +989,9 @@ while true; do
--force-level-zero)
LEVEL_ZERO_FORCE_REBUILD=true; shift; continue
;;
+ --force-openpgl)
+ OPENPGL_FORCE_REBUILD=true; shift; continue
+ ;;
--skip-python)
PYTHON_SKIP=true; shift; continue
;;
@@ -1024,6 +1049,9 @@ while true; do
--skip-level-zero)
LEVEL_ZERO_SKIP=true; shift; continue
;;
+ --skip-openpgl)
+ OPENPGL_SKIP=true; shift; continue
+ ;;
--)
# no more arguments to parse
break
@@ -1111,7 +1139,7 @@ LLVM_SOURCE=( "$_LLVM_SOURCE_ROOT/llvm-$LLVM_VERSION.src.tar.xz" )
LLVM_CLANG_SOURCE=( "$_LLVM_SOURCE_ROOT/clang-$LLVM_VERSION.src.tar.xz" "$_LLVM_SOURCE_ROOT/cfe-$LLVM_VERSION.src.tar.xz" )
OSL_USE_REPO=false
-OSL_SOURCE=( "https://github.com/imageworks/OpenShadingLanguage/archive/Release-$OSL_VERSION.tar.gz" )
+OSL_SOURCE=( "https://github.com/imageworks/OpenShadingLanguage/archive/v$OSL_VERSION.tar.gz" )
#~ OSL_SOURCE_REPO=( "https://github.com/imageworks/OpenShadingLanguage.git" )
#~ OSL_SOURCE_REPO_BRANCH="master"
#~ OSL_SOURCE_REPO_UID="85179714e1bc69cd25ecb6bb711c1a156685d395"
@@ -1173,6 +1201,9 @@ XR_OPENXR_REPO_BRANCH="master"
LEVEL_ZERO_SOURCE=("https://github.com/oneapi-src/level-zero/archive/refs/tags/v${LEVEL_ZERO_VERSION}.tar.gz")
+OPENPGL_USE_REPO=false
+OPENPGL_SOURCE=( "https://github.com/OpenPathGuidingLibrary/openpgl/archive/refs/tags/v${OPENPGL_VERSION}-beta.tar.gz" )
+
FFMPEG_SOURCE=( "http://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2" )
# C++11 is required now
@@ -1191,7 +1222,7 @@ Those libraries should be available as packages in all recent distributions (opt
* Basics of dev environment (cmake, gcc, svn , git, ...).
* libjpeg, libpng, libtiff, [openjpeg2], [libopenal].
* libx11, libxcursor, libxi, libxrandr, libxinerama (and other libx... as needed).
- * libwayland-client0, libwayland-cursor0, libwayland-egl1, libxkbcommon0, libdbus-1-3, libegl1 (Wayland)
+ * libwayland-client0, libdecor, libwayland-cursor0, libwayland-egl1, libxkbcommon0, libdbus-1-3, libegl1 (Wayland)
* libsqlite3, libzstd, libbz2, libssl, libfftw3, libxml2, libtinyxml, yasm, libyaml-cpp, flex.
* libsdl2, libepoxy, libpugixml, libpotrace, [libgmp], fontconfig, [libharu/libhpdf].\""
@@ -1227,7 +1258,8 @@ You may also want to build them yourself (optional ones are [between brackets]):
* [Alembic $ALEMBIC_VERSION] (from $ALEMBIC_SOURCE).
* [Universal Scene Description $USD_VERSION] (from $USD_SOURCE).
* [OpenXR-SDK $XR_OPENXR_VERSION] (from $XR_OPENXR_SOURCE).
- * [OneAPI Level Zero $LEVEL_ZERO_VERSION] (from $LEVEL_ZERO_SOURCE).\""
+ * [OneAPI Level Zero $LEVEL_ZERO_VERSION] (from $LEVEL_ZERO_SOURCE).
+ * [OpenPGL $OPENPGL_VERSION] (from $OPENPGL_SOURCE).\""
if [ "$DO_SHOW_DEPS" = true ]; then
PRINT ""
@@ -1661,6 +1693,7 @@ _update_deps_tbb() {
USD_FORCE_BUILD=true
EMBREE_FORCE_BUILD=true
OIDN_FORCE_BUILD=true
+ OPENPGL_FORCE_BUILD=true
fi
if [ "$2" = true ]; then
OSD_FORCE_REBUILD=true
@@ -1668,6 +1701,7 @@ _update_deps_tbb() {
USD_FORCE_REBUILD=true
EMBREE_FORCE_REBUILD=true
OIDN_FORCE_REBUILD=true
+ OPENPGL_FORCE_REBUILD=true
fi
}
@@ -2919,10 +2953,6 @@ compile_OPENVDB() {
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
cmake_d="$cmake_d -D USE_STATIC_DEPENDENCIES=OFF"
cmake_d="$cmake_d -D OPENVDB_BUILD_BINARIES=OFF"
- # Unfortunately OpenVDB currently forces using recent oneTBB over older versions when it finds it,
- # even when TBB_ROOT is specified. So have to prevent any check for system library -
- # in the hope it will not break in some other cases.
- cmake_d="$cmake_d -D DISABLE_CMAKE_SEARCH_PATHS=ON"
if [ "$WITH_NANOVDB" = true ]; then
cmake_d="$cmake_d -D USE_NANOVDB=ON"
@@ -2935,6 +2965,7 @@ compile_OPENVDB() {
cmake_d="$cmake_d -D Boost_USE_MULTITHREADED=ON"
cmake_d="$cmake_d -D Boost_NO_SYSTEM_PATHS=ON"
cmake_d="$cmake_d -D Boost_NO_BOOST_CMAKE=ON"
+ cmake_d="$cmake_d -D Boost_NO_BOOST_CMAKE=ON"
fi
if [ -d $INST/tbb ]; then
cmake_d="$cmake_d -D TBB_ROOT=$INST/tbb"
@@ -3198,7 +3229,7 @@ _init_opencollada() {
_inst_shortcut=$INST/opencollada
}
-_update_deps_opencollada() {
+_update_deps_collada() {
:
}
@@ -3309,7 +3340,12 @@ _init_embree() {
}
_update_deps_embree() {
- :
+ if [ "$1" = true ]; then
+ OPENPGL_FORCE_BUILD=true
+ fi
+ if [ "$2" = true ]; then
+ OPENPGL_FORCE_REBUILD=true
+ fi
}
clean_Embree() {
@@ -3328,7 +3364,7 @@ compile_Embree() {
fi
# To be changed each time we make edits that would modify the compiled results!
- embree_magic=11
+ embree_magic=12
_init_embree
# Force having own builds for the dependencies.
@@ -3966,6 +4002,112 @@ compile_Level_Zero() {
# ----------------------------------------------------------------------------
+# Build OpenPGL
+
+_init_openpgl() {
+ _src=$SRC/openpgl-$OPENPGL_VERSION
+ _git=false
+ _inst=$INST/openpgl-$OPENPGL_VERSION_SHORT
+ _inst_shortcut=$INST/openpgl
+}
+
+_update_deps_openpgl() {
+ :
+}
+
+clean_OpenPGL() {
+ _init_openpgl
+ if [ -d $_inst ]; then
+ # Force rebuilding the dependencies if needed.
+ _update_deps_openpgl false true
+ fi
+ _clean
+}
+
+compile_OpenPGL() {
+ if [ "$NO_BUILD" = true ]; then
+ WARNING "--no-build enabled, OpenPGL will not be compiled!"
+ return
+ fi
+
+ # To be changed each time we make edits that would modify the compiled results!
+ openpgl_magic=1
+ _init_openpgl
+
+ # Force having own builds for the dependencies.
+ _update_deps_openpgl true false
+
+ # Clean install if needed!
+ magic_compile_check openpgl-$OPENPGL_VERSION $openpgl_magic
+ if [ $? -eq 1 -o "$OPENPGL_FORCE_REBUILD" = true ]; then
+ clean_OpenPGL
+ fi
+
+ if [ ! -d $_inst ]; then
+ INFO "Building OpenPGL-$OPENPGL_VERSION"
+
+ # Force rebuilding the dependencies.
+ _update_deps_openpgl true true
+
+ prepare_inst
+
+ if [ ! -d $_src ]; then
+ mkdir -p $SRC
+ download OPENPGL_SOURCE[@] "$_src.tar.gz"
+ INFO "Unpacking OpenPGL-$OPENPGL_VERSION"
+ tar -C $SRC --transform "s,(.*/?)openpgl-$OPENPGL_VERSION-beta[^/]*(.*),\1openpgl-$OPENPGL_VERSION\2,x" \
+ -xf $_src.tar.gz
+ fi
+
+ cd $_src
+
+ INFO "$_src"
+
+ # Always refresh the whole build!
+ if [ -d build ]; then
+ rm -rf build
+ fi
+ mkdir build
+ cd build
+
+ cmake_d="-D CMAKE_BUILD_TYPE=Release"
+ cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
+ cmake_d="$cmake_d -D OPENPGL_BUILD_STATIC=OFF"
+ cmake_d="$cmake_d -D OPENPGL_BUILD_PYTHON=OFF"
+ cmake_d="$cmake_d -D EMBREE_ISPC_SUPPORT=OFF"
+ if [ -d $INST/tbb ]; then
+ cmake_d="$cmake_d -D OPENPGL_TBB_ROOT=$INST/tbb"
+ cmake_d="$cmake_d -D TBB_ROOT=$INST/tbb"
+ fi
+
+ cmake $cmake_d ../
+
+ make -j$THREADS && make install
+ make clean
+
+ if [ ! -d $_inst ]; then
+ ERROR "OpenPGL-$OPENPGL_VERSION failed to compile, exiting"
+ exit 1
+ fi
+
+ magic_compile_set openpgl-$OPENPGL_VERSION $openpgl_magic
+
+ cd $CWD
+ INFO "Done compiling OpenPGL-$OPENPGL_VERSION!"
+ else
+ INFO "Own OpenPGL-$OPENPGL_VERSION is up to date, nothing to do!"
+ INFO "If you want to force rebuild of this lib, use the --force-openpgl option."
+ fi
+
+ if [ -d $_inst ]; then
+ _create_inst_shortcut
+ fi
+
+ run_ldconfig "openpgl"
+}
+
+
+# ----------------------------------------------------------------------------
# Install on DEB-like
get_package_version_DEB() {
@@ -4063,11 +4205,12 @@ install_DEB() {
_packages="gawk cmake cmake-curses-gui build-essential libjpeg-dev libpng-dev libtiff-dev \
git libfreetype6-dev libfontconfig-dev libx11-dev flex bison libxxf86vm-dev \
libxcursor-dev libxi-dev wget libsqlite3-dev libxrandr-dev libxinerama-dev \
- libwayland-dev wayland-protocols libegl-dev libxkbcommon-dev libdbus-1-dev linux-libc-dev \
+ libwayland-dev libdecor-0-dev wayland-protocols libegl-dev libxkbcommon-dev libdbus-1-dev linux-libc-dev \
libbz2-dev libncurses5-dev libssl-dev liblzma-dev libreadline-dev \
libopenal-dev libepoxy-dev yasm \
libsdl2-dev libfftw3-dev patch bzip2 libxml2-dev libtinyxml-dev libjemalloc-dev \
- libgmp-dev libpugixml-dev libpotrace-dev libhpdf-dev libzstd-dev libpystring-dev"
+ libgmp-dev libpugixml-dev libpotrace-dev libhpdf-dev libzstd-dev libpystring-dev \
+ libglfw3-dev"
VORBIS_USE=true
OGG_USE=true
@@ -4597,6 +4740,18 @@ install_DEB() {
PRINT ""
compile_Level_Zero
fi
+
+ PRINT ""
+ if [ "$OPENPGL_SKIP" = true ]; then
+ WARNING "Skipping OpenPGL installation, as requested..."
+ elif [ "$OPENPGL_FORCE_BUILD" = true ]; then
+ INFO "Forced OpenPGL building, as requested..."
+ compile_OpenPGL
+ else
+ # No package currently!
+ PRINT ""
+ compile_OpenPGL
+ fi
}
@@ -4773,7 +4928,7 @@ install_RPM() {
_packages="gcc gcc-c++ git make cmake tar bzip2 xz findutils flex bison fontconfig-devel \
libtiff-devel libjpeg-devel libpng-devel sqlite-devel fftw-devel SDL2-devel \
libX11-devel libXi-devel libXcursor-devel libXrandr-devel libXinerama-devel \
- wayland-devel wayland-protocols-devel mesa-libEGL-devel libxkbcommon-devel dbus-devel kernel-headers \
+ wayland-devel libdecor-devel wayland-protocols-devel mesa-libEGL-devel libxkbcommon-devel dbus-devel kernel-headers \
wget ncurses-devel readline-devel $OPENJPEG_DEV openal-soft-devel \
libepoxy-devel yasm patch \
libxml2-devel yaml-cpp-devel tinyxml-devel jemalloc-devel \
@@ -5304,6 +5459,18 @@ install_RPM() {
PRINT ""
compile_Level_Zero
fi
+
+ PRINT ""
+ if [ "$OPENPGL_SKIP" = true ]; then
+ WARNING "Skipping OpenPGL installation, as requested..."
+ elif [ "$OPENPGL_FORCE_BUILD" = true ]; then
+ INFO "Forced OpenPGL building, as requested..."
+ compile_OpenPGL
+ else
+ # No package currently!
+ PRINT ""
+ compile_OpenPGL
+ fi
}
@@ -5415,7 +5582,7 @@ install_ARCH() {
fi
_packages="$BASE_DEVEL git cmake fontconfig flex \
- libxi libxcursor libxrandr libxinerama libepoxy libpng libtiff wget openal \
+ libxi libxcursor libxrandr libxinerama libepoxy libdecor libpng libtiff wget openal \
$OPENJPEG_DEV yasm sdl2 fftw \
libxml2 yaml-cpp tinyxml python-requests jemalloc gmp potrace pugixml libharu \
zstd pystring"
@@ -5900,6 +6067,18 @@ install_ARCH() {
PRINT ""
compile_Level_Zero
fi
+
+ PRINT ""
+ if [ "$OPENPGL_SKIP" = true ]; then
+ WARNING "Skipping OpenPGL installation, as requested..."
+ elif [ "$OPENPGL_FORCE_BUILD" = true ]; then
+ INFO "Forced OpenPGL building, as requested..."
+ compile_OpenPGL
+ else
+ # No package currently!
+ PRINT ""
+ compile_OpenPGL
+ fi
}
@@ -6082,6 +6261,14 @@ install_OTHER() {
INFO "Forced Level Zero building, as requested..."
compile_Level_Zero
fi
+
+ PRINT ""
+ if [ "$OPENPGL_SKIP" = true ]; then
+ WARNING "Skipping OpenPGL installation, as requested..."
+ elif [ "$OPENPGL_FORCE_BUILD" = true ]; then
+ INFO "Forced OpenPGL building, as requested..."
+ compile_OpenPGL
+ fi
}
# ----------------------------------------------------------------------------
@@ -6099,7 +6286,7 @@ print_info() {
_buildargs="-U *SNDFILE* -U PYTHON* -U *BOOST* -U *Boost* -U *TBB*"
_buildargs="$_buildargs -U *OPENCOLORIO* -U *OPENEXR* -U *OPENIMAGEIO* -U *LLVM* -U *CLANG* -U *CYCLES*"
_buildargs="$_buildargs -U *OPENSUBDIV* -U *OPENVDB* -U *BLOSC* -U *COLLADA* -U *FFMPEG* -U *ALEMBIC* -U *USD*"
- _buildargs="$_buildargs -U *EMBREE* -U *OPENIMAGEDENOISE* -U *OPENXR*"
+ _buildargs="$_buildargs -U *EMBREE* -U *OPENIMAGEDENOISE* -U *OPENXR* -U *OPENPGL*"
_1="-D WITH_CODEC_SNDFILE=ON"
PRINT " $_1"
@@ -6218,7 +6405,7 @@ print_info() {
fi
if [ -d $INST/nanovdb ]; then
_1="-D WITH_NANOVDB=ON"
- _2="-D NANOVDB_ROOT_DIR=$INST/openvdb"
+ _2="-D NANOVDB_ROOT_DIR=$INST/nanovdb"
PRINT " $_1"
PRINT " $_2"
_buildargs="$_buildargs $_1 $_2"
@@ -6330,6 +6517,16 @@ print_info() {
#~ fi
#~ fi
+ if [ "$OPENPGL_SKIP" = false ]; then
+ if [ -d $INST/openpgl ]; then
+ _1="-D openpgl_DIR=$INST/openpgl/lib/cmake/openpgl-$OPENPGL_VERSION"
+ _2="-D WITH_CYCLES_PATH_GUIDING=ON"
+ PRINT " $_1"
+ PRINT " $_2"
+ _buildargs="$_buildargs $_1 $_2"
+ fi
+ fi
+
PRINT ""
PRINT "Or even simpler, just run (in your blender-source dir):"
PRINT " make -j$THREADS BUILD_CMAKE_ARGS=\"$_buildargs\""
diff --git a/build_files/build_environment/linux/linux-centos7-setup.sh b/build_files/build_environment/linux/linux-centos7-setup.sh
new file mode 100644
index 00000000000..e664f530edb
--- /dev/null
+++ b/build_files/build_environment/linux/linux-centos7-setup.sh
@@ -0,0 +1,130 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# This script is part of the official build environment, see WIKI page for details.
+# https://wiki.blender.org/wiki/Building_Blender/Other/CentOS7ReleaseEnvironment
+
+set -e
+
+if [ `id -u` -ne 0 ]; then
+ echo "This script must be run as root"
+ exit 1
+fi
+
+# yum-config-manager does not come in the default minimal install,
+# so make sure it is installed and available.
+yum -y update
+yum -y install yum-utils
+
+# Install all the packages needed for a new toolchain.
+#
+# NOTE: Keep this separate from the packages install, since otherwise
+# older toolchain will be installed.
+yum -y update
+yum -y install epel-release
+yum -y install centos-release-scl
+yum -y install devtoolset-9
+
+# Install packages needed for Blender's dependencies.
+PACKAGES_FOR_LIBS=(
+ # Used to checkout Blender's code.
+ git
+ # Used to checkout Blender's `../lib/` directory.
+ subversion
+ # Used to extract packages.
+ bzip2
+ # Used to extract packages.
+ tar
+ # Blender and some dependencies use `cmake`.
+ cmake3
+ # Apply patches from Blender's: `./build_files/build_environment/patches`
+ patch
+ # Use by `cmake` and `autoconf`.
+ make
+
+ # Required by: `external_nasm` which uses an `autoconf` build-system.
+ autoconf
+ automake
+ libtool
+
+ # Meta-build system used by various packages.
+ meson
+ # Builds generated by meson use Ninja for the actual build.
+ ninja-build
+
+ # Required by Blender build option: `WITH_GHOST_X11`.
+ libXrandr-devel
+ libXinerama-devel
+ libXcursor-devel
+ libXi-devel
+ libX11-devel
+ libXt-devel
+
+ # Required by Blender build option: `WITH_GHOST_WAYLAND`.
+ mesa-libEGL-devel
+ # Required by: Blender & `external_opensubdiv` (probably others).
+ mesa-libGL-devel
+ mesa-libGLU-devel
+
+ # Required by: `external_ispc`.
+ zlib-devel
+ # TODO: dependencies build without this, consider removal.
+ rubygem-asciidoctor
+ # TODO: dependencies build without this, consider removal.
+ wget
+ # Required by: `external_sqlite` as a build-time dependency (needed for the `tclsh` command).
+ tcl
+ # Required by: `external_aom`.
+ # TODO: Blender is already building `external_nasm` which is listed as an alternative to `yasm`.
+ # Why are both needed?
+ yasm
+
+ # Required by: `meson` (Python based build system).
+ python36
+ # Required by: `mako` (Python module used for building `external_mesa`)
+ python-setuptools
+
+ # Required by: `external_igc` & `external_osl` as a build-time dependency.
+ bison
+ # Required by: `external_osl` as a build-time dependency.
+ flex
+ # TODO: dependencies build without this, consider removal.
+ ncurses-devel
+)
+
+# Additional packages needed for building Blender.
+PACKAGES_FOR_BLENDER=(
+ # Required by Blender build option: `WITH_GHOST_WAYLAND`.
+ libxkbcommon-devel
+)
+
+yum -y install -y ${PACKAGES_FOR_LIBS[@]} ${PACKAGES_FOR_BLENDER[@]}
+
+# Dependencies for Mesa
+yum -y install expat-devel
+python3 -m pip install mako
+
+# Dependencies for pip (needed for buildbot-worker).
+yum -y install python36-pip python36-devel
+
+# Dependencies for asound.
+yum -y install -y \
+ alsa-lib-devel pulseaudio-libs-devel
+
+alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake 10 \
+ --slave /usr/local/bin/ctest ctest /usr/bin/ctest \
+ --slave /usr/local/bin/cpack cpack /usr/bin/cpack \
+ --slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake \
+ --family cmake
+
+alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake3 20 \
+ --slave /usr/local/bin/ctest ctest /usr/bin/ctest3 \
+ --slave /usr/local/bin/cpack cpack /usr/bin/cpack3 \
+ --slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake3 \
+ --family cmake
+
+alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake3 20 \
+ --slave /usr/local/bin/ctest ctest /usr/bin/ctest3 \
+ --slave /usr/local/bin/cpack cpack /usr/bin/cpack3 \
+ --slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake3 \
+ --family cmake
diff --git a/build_files/build_environment/patches/aom.diff b/build_files/build_environment/patches/aom.diff
new file mode 100644
index 00000000000..1611cff5dca
--- /dev/null
+++ b/build_files/build_environment/patches/aom.diff
@@ -0,0 +1,18 @@
+diff -Naur libaom-3.4.0/build/cmake/aom_configure.cmake external_aom/build/cmake/aom_configure.cmake
+--- libaom-3.4.0/build/cmake/aom_configure.cmake 2022-06-17 11:46:18 -0600
++++ external_aom/build/cmake/aom_configure.cmake 2022-10-16 15:35:54 -0600
+@@ -15,8 +15,12 @@
+
+ include(FindGit)
+ include(FindPerl)
+-include(FindThreads)
+-
++# Blender: This will drag in a dep on libwinpthreads which we prefer
++# not to have, aom will fallback on a native win32 thread wrapper
++# if pthreads are not found.
++if(NOT WIN32)
++ include(FindThreads)
++endif()
+ include("${AOM_ROOT}/build/cmake/aom_config_defaults.cmake")
+ include("${AOM_ROOT}/build/cmake/aom_experiment_deps.cmake")
+ include("${AOM_ROOT}/build/cmake/aom_optimization.cmake")
diff --git a/build_files/build_environment/patches/cmake/modules/FindIlmBase.cmake b/build_files/build_environment/patches/cmake/modules/FindIlmBase.cmake
index 7611ca21708..c74ff788a75 100644
--- a/build_files/build_environment/patches/cmake/modules/FindIlmBase.cmake
+++ b/build_files/build_environment/patches/cmake/modules/FindIlmBase.cmake
@@ -177,7 +177,8 @@ if(ILMBASE_INCLUDE_DIR)
"\\1" XYZ ${ILMBASE_BUILD_SPECIFICATION})
set("ILMBASE_VERSION" ${XYZ} CACHE STRING "Version of ILMBase lib")
else()
- # Old versions (before 2.0?) do not have any version string, just assuming 2.0 should be fine though.
+ # Old versions (before 2.0?) do not have any version string,
+ # just assuming 2.0 should be fine though.
message(WARNING "Could not determine ILMBase library version, assuming 2.0.")
set("ILMBASE_VERSION" "2.0" CACHE STRING "Version of ILMBase lib")
endif()
@@ -195,8 +196,13 @@ else()
# elseif(${ILMBASE_VERSION} VERSION_LESS "2.1")
set(IlmBase_Libraries Half Iex Imath IlmThread)
# else()
-# string(REGEX REPLACE "([0-9]+)[.]([0-9]+).*" "\\1_\\2" _ilmbase_libs_ver ${ILMBASE_VERSION})
-# set(IlmBase_Libraries Half Iex-${_ilmbase_libs_ver} Imath-${_ilmbase_libs_ver} IlmThread-${_ilmbase_libs_ver})
+ # string(REGEX REPLACE "([0-9]+)[.]([0-9]+).*" "\\1_\\2" _ilmbase_libs_ver ${ILMBASE_VERSION})
+ # set(IlmBase_Libraries
+ # Half
+ # Iex-${_ilmbase_libs_ver}
+ # Imath-${_ilmbase_libs_ver}
+ # IlmThread-${_ilmbase_libs_ver}
+ # )
endif()
diff --git a/build_files/build_environment/patches/cmake/modules/FindOpenEXR.cmake b/build_files/build_environment/patches/cmake/modules/FindOpenEXR.cmake
index 8b08b047eac..040dfe1c16f 100644
--- a/build_files/build_environment/patches/cmake/modules/FindOpenEXR.cmake
+++ b/build_files/build_environment/patches/cmake/modules/FindOpenEXR.cmake
@@ -175,7 +175,8 @@ if(OPENEXR_INCLUDE_DIR)
"\\1" XYZ ${OPENEXR_BUILD_SPECIFICATION})
set("OPENEXR_VERSION" ${XYZ} CACHE STRING "Version of OpenEXR lib")
else()
- # Old versions (before 2.0?) do not have any version string, just assuming 2.0 should be fine though.
+ # Old versions (before 2.0?) do not have any version string,
+ # just assuming 2.0 should be fine though.
message(WARNING "Could not determine ILMBase library version, assuming 2.0.")
set("OPENEXR_VERSION" "2.0" CACHE STRING "Version of OpenEXR lib")
endif()
diff --git a/build_files/build_environment/patches/ffmpeg.diff b/build_files/build_environment/patches/ffmpeg.diff
index c255f7c37a3..ac104a20ffe 100644
--- a/build_files/build_environment/patches/ffmpeg.diff
+++ b/build_files/build_environment/patches/ffmpeg.diff
@@ -68,34 +68,18 @@
+
return ret;
}
---- a/libavcodec/rl.c
-+++ b/libavcodec/rl.c
-@@ -71,17 +71,19 @@
- av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size)
- {
- int i, q;
-- VLC_TYPE table[1500][2] = {{0}};
-+ VLC_TYPE (*table)[2] = av_calloc(sizeof(VLC_TYPE), 1500 * 2);
- VLC vlc = { .table = table, .table_allocated = static_size };
-- av_assert0(static_size <= FF_ARRAY_ELEMS(table));
-+ av_assert0(static_size < 1500);
- init_vlc(&vlc, 9, rl->n + 1, &rl->table_vlc[0][1], 4, 2, &rl->table_vlc[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC);
+diff --git a/libavcodec/x86/simple_idct.asm b/libavcodec/x86/simple_idct.asm
+index dcf0da6df121..982b2f0bbba1 100644
+--- a/libavcodec/x86/simple_idct.asm
++++ b/libavcodec/x86/simple_idct.asm
+@@ -25,9 +25,9 @@
- for (q = 0; q < 32; q++) {
- int qmul = q * 2;
- int qadd = (q - 1) | 1;
+ %include "libavutil/x86/x86util.asm"
-- if (!rl->rl_vlc[q])
-+ if (!rl->rl_vlc[q]){
-+ av_free(table);
- return;
-+ }
+-%if ARCH_X86_32
+ SECTION_RODATA
- if (q == 0) {
- qmul = 1;
-@@ -113,4 +115,5 @@
- rl->rl_vlc[q][i].run = run;
- }
- }
-+ av_free(table);
- }
++%if ARCH_X86_32
+ cextern pb_80
+
+ wm1010: dw 0, 0xffff, 0, 0xffff
diff --git a/build_files/build_environment/patches/gmp.diff b/build_files/build_environment/patches/gmp.diff
new file mode 100644
index 00000000000..bf22f93bc4f
--- /dev/null
+++ b/build_files/build_environment/patches/gmp.diff
@@ -0,0 +1,15 @@
+--- a/mpz/inp_raw.c Tue Dec 22 23:49:51 2020 +0100
++++ b/mpz/inp_raw.c Thu Oct 21 19:06:49 2021 +0200
+@@ -88,8 +88,11 @@
+
+ abs_csize = ABS (csize);
+
++ if (UNLIKELY (abs_csize > ~(mp_bitcnt_t) 0 / 8))
++ return 0; /* Bit size overflows */
++
+ /* round up to a multiple of limbs */
+- abs_xsize = BITS_TO_LIMBS (abs_csize*8);
++ abs_xsize = BITS_TO_LIMBS ((mp_bitcnt_t) abs_csize * 8);
+
+ if (abs_xsize != 0)
+ {
diff --git a/build_files/build_environment/patches/opencollada.diff b/build_files/build_environment/patches/opencollada.diff
index e8efc1a6909..02eab251a13 100644
--- a/build_files/build_environment/patches/opencollada.diff
+++ b/build_files/build_environment/patches/opencollada.diff
@@ -130,3 +130,28 @@ index 715d903..24423ce 100644
{
string id = node.attribute("id").value();
size_t line = node.line();
+diff -Naur a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -274,7 +274,7 @@
+ add_subdirectory(${EXTERNAL_LIBRARIES}/UTF)
+ add_subdirectory(common/libBuffer)
+ add_subdirectory(${EXTERNAL_LIBRARIES}/MathMLSolver)
+-add_subdirectory(${EXTERNAL_LIBRARIES}/zlib)
++#add_subdirectory(${EXTERNAL_LIBRARIES}/zlib)
+
+ # building OpenCOLLADA libs
+ add_subdirectory(COLLADABaseUtils)
+@@ -284,10 +284,10 @@
+ add_subdirectory(COLLADAStreamWriter)
+
+ # building COLLADAValidator app
+-add_subdirectory(COLLADAValidator)
++#add_subdirectory(COLLADAValidator)
+
+ # DAE validator app
+-add_subdirectory(DAEValidator)
++#add_subdirectory(DAEValidator)
+
+ # Library export
+ install(EXPORT LibraryExport DESTINATION ${OPENCOLLADA_INST_CMAKECONFIG} FILE OpenCOLLADATargets.cmake)
diff --git a/build_files/build_environment/patches/opencolorio.diff b/build_files/build_environment/patches/opencolorio.diff
index 2255cbc02ed..278dfe0d857 100644
--- a/build_files/build_environment/patches/opencolorio.diff
+++ b/build_files/build_environment/patches/opencolorio.diff
@@ -14,3 +14,15 @@ index 7b894a45..92618215 100644
)
if(CMAKE_TOOLCHAIN_FILE)
set(pystring_CMAKE_ARGS
+--- a/src/OpenColorIO/FileRules.cpp
++++ b/src/OpenColorIO/FileRules.cpp
+@@ -7,6 +7,9 @@
+ #include <regex>
+ #include <sstream>
+
++/* NOTE: this has been applied up-stream, this edit can be removed after upgrading OpenColorIO. */
++#include <cstring>
++
+ #include <OpenColorIO/OpenColorIO.h>
+
+ #include "CustomKeys.h"
diff --git a/build_files/build_environment/patches/osl.diff b/build_files/build_environment/patches/osl.diff
index 28e1d6e101d..3f4a485b037 100644
--- a/build_files/build_environment/patches/osl.diff
+++ b/build_files/build_environment/patches/osl.diff
@@ -1,67 +1,53 @@
-diff -Naur OpenShadingLanguage-Release-1.9.9/src/include/OSL/llvm_util.h external_osl/src/include/OSL/llvm_util.h
---- OpenShadingLanguage-Release-1.9.9/src/include/OSL/llvm_util.h 2018-05-01 16:39:02 -0600
-+++ external_osl/src/include/OSL/llvm_util.h 2018-08-25 14:05:00 -0600
-@@ -33,6 +33,8 @@
-
- #include <vector>
-
-+#define OSL_HAS_BLENDER_CLEANUP_FIX
-+
- #ifdef LLVM_NAMESPACE
- namespace llvm = LLVM_NAMESPACE;
- #endif
-@@ -487,6 +489,7 @@
- std::string func_name (llvm::Function *f);
-
- static size_t total_jit_memory_held ();
-+ static void Cleanup ();
-
- private:
- class MemoryManager;
-diff -Naur OpenShadingLanguage-Release-1.9.9/src/liboslexec/llvm_util.cpp external_osl/src/liboslexec/llvm_util.cpp
---- OpenShadingLanguage-Release-1.9.9/src/liboslexec/llvm_util.cpp 2018-05-01 16:39:02 -0600
-+++ external_osl/src/liboslexec/llvm_util.cpp 2018-08-25 14:04:27 -0600
-@@ -140,7 +140,10 @@
- };
-
-
--
-+void LLVM_Util::Cleanup ()
-+{
-+ if(jitmm_hold) jitmm_hold->clear();
-+}
-
- size_t
- LLVM_Util::total_jit_memory_held ()
-diff -Naur org/CMakeLists.txt external_osl/CMakeLists.txt
---- org/CMakeLists.txt 2020-12-01 12:37:15 -0700
-+++ external_osl/CMakeLists.txt 2021-01-20 13:26:50 -0700
-@@ -84,6 +84,11 @@
+diff -Naur OpenShadingLanguage-1.12.6.2/CMakeLists.txt external_osl/CMakeLists.txt
+--- OpenShadingLanguage-1.12.6.2/CMakeLists.txt 2022-09-30 17:43:53 -0600
++++ external_osl/CMakeLists.txt 2022-10-15 14:49:26 -0600
+@@ -101,6 +101,11 @@
CACHE STRING "Directory where OptiX PTX files will be installed")
set (CMAKE_DEBUG_POSTFIX "" CACHE STRING "Library naming postfix for Debug builds (e.g., '_debug')")
-
+
+set (USE_OIIO_STATIC ON CACHE BOOL "If OIIO is built static")
+if (USE_OIIO_STATIC)
+ add_definitions ("-DOIIO_STATIC_BUILD=1")
+ add_definitions ("-DOIIO_STATIC_DEFINE=1")
+endif ()
-
+
set (OSL_NO_DEFAULT_TEXTURESYSTEM OFF CACHE BOOL "Do not use create a raw OIIO::TextureSystem")
if (OSL_NO_DEFAULT_TEXTURESYSTEM)
-diff -Naur external_osl_orig/src/cmake/externalpackages.cmake external_osl/src/cmake/externalpackages.cmake
---- external_osl_orig/src/cmake/externalpackages.cmake 2021-06-01 13:44:18 -0600
-+++ external_osl/src/cmake/externalpackages.cmake 2021-06-28 07:44:32 -0600
-@@ -80,6 +80,7 @@
-
-
+diff -Naur OpenShadingLanguage-1.12.6.2/src/cmake/externalpackages.cmake external_osl/src/cmake/externalpackages.cmake
+--- OpenShadingLanguage-1.12.6.2/src/cmake/externalpackages.cmake 2022-09-30 17:43:53 -0600
++++ external_osl/src/cmake/externalpackages.cmake 2022-10-15 14:49:26 -0600
+@@ -77,6 +77,7 @@
+
+
checked_find_package (ZLIB REQUIRED) # Needed by several packages
+checked_find_package (PNG REQUIRED) # Needed since OIIO needs it
-
+
# IlmBase & OpenEXR
checked_find_package (OpenEXR REQUIRED
-diff -Naur external_osl_orig/src/liboslcomp/oslcomp.cpp external_osl/src/liboslcomp/oslcomp.cpp
---- external_osl_orig/src/liboslcomp/oslcomp.cpp 2021-06-01 13:44:18 -0600
-+++ external_osl/src/liboslcomp/oslcomp.cpp 2021-06-28 09:11:06 -0600
+diff -Naur OpenShadingLanguage-1.12.6.2/src/include/OSL/llvm_util.h external_osl/src/include/OSL/llvm_util.h
+--- OpenShadingLanguage-1.12.6.2/src/include/OSL/llvm_util.h 2022-09-30 17:43:53 -0600
++++ external_osl/src/include/OSL/llvm_util.h 2022-10-15 15:37:24 -0600
+@@ -9,6 +9,8 @@
+ #include <unordered_set>
+ #include <vector>
+
++#define OSL_HAS_BLENDER_CLEANUP_FIX
++
+ #ifdef LLVM_NAMESPACE
+ namespace llvm = LLVM_NAMESPACE;
+ #endif
+@@ -455,7 +457,7 @@
+ llvm::BasicBlock* masked_return_block() const;
+
+ bool is_masking_required() const { return m_is_masking_required; }
+-
++ static void Cleanup ();
+ struct ScopedMasking {
+ ScopedMasking() {}
+
+diff -Naur OpenShadingLanguage-1.12.6.2/src/liboslcomp/oslcomp.cpp external_osl/src/liboslcomp/oslcomp.cpp
+--- OpenShadingLanguage-1.12.6.2/src/liboslcomp/oslcomp.cpp 2022-09-30 17:43:53 -0600
++++ external_osl/src/liboslcomp/oslcomp.cpp 2022-10-15 14:49:26 -0600
@@ -21,6 +21,13 @@
#if !defined(__STDC_CONSTANT_MACROS)
# define __STDC_CONSTANT_MACROS 1
@@ -76,3 +62,50 @@ diff -Naur external_osl_orig/src/liboslcomp/oslcomp.cpp external_osl/src/liboslc
#include <clang/Basic/TargetInfo.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/TextDiagnosticPrinter.h>
+diff -Naur OpenShadingLanguage-1.12.6.2/src/liboslexec/llvm_util.cpp external_osl/src/liboslexec/llvm_util.cpp
+--- OpenShadingLanguage-1.12.6.2/src/liboslexec/llvm_util.cpp 2022-09-30 17:43:53 -0600
++++ external_osl/src/liboslexec/llvm_util.cpp 2022-10-15 15:53:11 -0600
+@@ -116,8 +116,6 @@
+ return { A.data(), size_t(A.size()) };
+ }
+
+-
+-
+ namespace pvt {
+
+ typedef llvm::SectionMemoryManager LLVMMemoryManager;
+@@ -182,6 +180,13 @@
+ ++jit_mem_hold_users;
+ }
+
++void
++LLVM_Util::Cleanup()
++{
++ if (jitmm_hold)
++ jitmm_hold->clear();
++}
++
+
+ LLVM_Util::ScopedJitMemoryUser::~ScopedJitMemoryUser()
+ {
+diff --git a/src/include/OSL/mask.h b/src/include/OSL/mask.h
+index 24197af..b9275f6 100644
+--- a/src/include/OSL/mask.h
++++ b/src/include/OSL/mask.h
+@@ -4,7 +4,6 @@
+
+ #pragma once
+
+-#include <immintrin.h>
+ #include <type_traits>
+
+ #include <OSL/oslconfig.h>
+@@ -23,6 +22,8 @@ using std::countr_zero;
+
+ #elif OSL_INTEL_CLASSIC_COMPILER_VERSION
+
++#include <immintrin.h>
++
+ OSL_FORCEINLINE int popcount(uint32_t x) noexcept { return _mm_popcnt_u32(x);}
+ OSL_FORCEINLINE int popcount(uint64_t x) noexcept { return _mm_popcnt_u64(x); }
+ OSL_FORCEINLINE int countr_zero(uint32_t x) noexcept { return _bit_scan_forward(x); }
diff --git a/build_files/build_environment/patches/python_windows.diff b/build_files/build_environment/patches/python_windows.diff
deleted file mode 100644
index f9c89a90fde..00000000000
--- a/build_files/build_environment/patches/python_windows.diff
+++ /dev/null
@@ -1,24 +0,0 @@
-diff -Naur orig/PCbuild/get_externals.bat Python-3.10.2/PCbuild/get_externals.bat
---- orig/PCbuild/get_externals.bat 2022-01-13 11:52:14 -0700
-+++ Python-3.10.2/PCbuild/get_externals.bat 2022-08-17 11:24:42 -0600
-@@ -51,7 +51,7 @@
- echo.Fetching external libraries...
-
- set libraries=
--set libraries=%libraries% bzip2-1.0.6
-+set libraries=%libraries% bzip2-1.0.8
- if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.3.0
- if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1m
- set libraries=%libraries% sqlite-3.35.5.0
- diff -Naur orig/PCbuild/python.props external_python/PCbuild/python.props
---- orig/PCbuild/python.props 2022-01-13 11:52:14 -0700
-+++ external_python/PCbuild/python.props 2022-08-17 11:38:38 -0600
-@@ -58,7 +58,7 @@
- <ExternalsDir Condition="$(ExternalsDir) == ''">$([System.IO.Path]::GetFullPath(`$(PySourcePath)externals`))</ExternalsDir>
- <ExternalsDir Condition="!HasTrailingSlash($(ExternalsDir))">$(ExternalsDir)\</ExternalsDir>
- <sqlite3Dir>$(ExternalsDir)sqlite-3.35.5.0\</sqlite3Dir>
-- <bz2Dir>$(ExternalsDir)bzip2-1.0.6\</bz2Dir>
-+ <bz2Dir>$(ExternalsDir)bzip2-1.0.8\</bz2Dir>
- <lzmaDir>$(ExternalsDir)xz-5.2.2\</lzmaDir>
- <libffiDir>$(ExternalsDir)libffi-3.3.0\</libffiDir>
- <libffiOutDir>$(ExternalsDir)libffi-3.3.0\$(ArchName)\</libffiOutDir>
diff --git a/build_files/build_environment/patches/sndfile.diff b/build_files/build_environment/patches/sndfile.diff
deleted file mode 100644
index ab43baa78df..00000000000
--- a/build_files/build_environment/patches/sndfile.diff
+++ /dev/null
@@ -1,42 +0,0 @@
---- src/Makefile.in 2017-09-26 01:28:47.000000000 +0300
-+++ src/Makefile.in 2017-09-26 01:19:06.000000000 +0300
-@@ -513,7 +513,7 @@
- libcommon_la_SOURCES = common.c file_io.c command.c pcm.c ulaw.c alaw.c \
- float32.c double64.c ima_adpcm.c ms_adpcm.c gsm610.c dwvw.c vox_adpcm.c \
- interleave.c strings.c dither.c cart.c broadcast.c audio_detect.c \
-- ima_oki_adpcm.c ima_oki_adpcm.h alac.c chunk.c ogg.c chanmap.c \
-+ ima_oki_adpcm.c ima_oki_adpcm.h alac.c chunk.c ogg.c chanmap.c \
- windows.c id3.c $(WIN_VERSION_FILE)
-
-
-@@ -719,10 +719,10 @@
- $(AM_V_CCLD)$(LINK) $(GSM610_libgsm_la_OBJECTS) $(GSM610_libgsm_la_LIBADD) $(LIBS)
-
- libcommon.la: $(libcommon_la_OBJECTS) $(libcommon_la_DEPENDENCIES) $(EXTRA_libcommon_la_DEPENDENCIES)
-- $(AM_V_CCLD)$(LINK) $(libcommon_la_OBJECTS) $(libcommon_la_LIBADD) $(LIBS)
-+ $(AM_V_CCLD)$(LINK) $(libcommon_la_OBJECTS) $(libcommon_la_LIBADD) $(LIBS) $(EXTERNAL_XIPH_LIBS)
-
- libsndfile.la: $(libsndfile_la_OBJECTS) $(libsndfile_la_DEPENDENCIES) $(EXTRA_libsndfile_la_DEPENDENCIES)
-- $(AM_V_CCLD)$(libsndfile_la_LINK) -rpath $(libdir) $(libsndfile_la_OBJECTS) $(libsndfile_la_LIBADD) $(LIBS)
-+ $(AM_V_CCLD)$(libsndfile_la_LINK) -rpath $(libdir) $(libsndfile_la_OBJECTS) $(libsndfile_la_LIBADD) $(LIBS) $(EXTERNAL_XIPH_LIBS)
-
- clean-checkPROGRAMS:
- @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
-@@ -924,7 +924,7 @@
- @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsndfile_la_CPPFLAGS) $(CPPFLAGS) $(libsndfile_la_CFLAGS) $(CFLAGS) -c -o libsndfile_la-dwd.lo `test -f 'dwd.c' || echo '$(srcdir)/'`dwd.c
-
- libsndfile_la-flac.lo: flac.c
--@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsndfile_la_CPPFLAGS) $(CPPFLAGS) $(libsndfile_la_CFLAGS) $(CFLAGS) -MT libsndfile_la-flac.lo -MD -MP -MF $(DEPDIR)/libsndfile_la-flac.Tpo -c -o libsndfile_la-flac.lo `test -f 'flac.c' || echo '$(srcdir)/'`flac.c
-+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsndfile_la_CPPFLAGS) $(CPPFLAGS) $(libsndfile_la_CFLAGS) $(CFLAGS) $(EXTERNAL_XIPH_CFLAGS) -MT libsndfile_la-flac.lo -MD -MP -MF $(DEPDIR)/libsndfile_la-flac.Tpo -c -o libsndfile_la-flac.lo `test -f 'flac.c' || echo '$(srcdir)/'`flac.c
- @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsndfile_la-flac.Tpo $(DEPDIR)/libsndfile_la-flac.Plo
- @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='flac.c' object='libsndfile_la-flac.lo' libtool=yes @AMDEPBACKSLASH@
- @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@@ -1092,7 +1092,7 @@
- @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsndfile_la_CPPFLAGS) $(CPPFLAGS) $(libsndfile_la_CFLAGS) $(CFLAGS) -c -o libsndfile_la-rf64.lo `test -f 'rf64.c' || echo '$(srcdir)/'`rf64.c
-
- libsndfile_la-ogg_vorbis.lo: ogg_vorbis.c
--@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsndfile_la_CPPFLAGS) $(CPPFLAGS) $(libsndfile_la_CFLAGS) $(CFLAGS) -MT libsndfile_la-ogg_vorbis.lo -MD -MP -MF $(DEPDIR)/libsndfile_la-ogg_vorbis.Tpo -c -o libsndfile_la-ogg_vorbis.lo `test -f 'ogg_vorbis.c' || echo '$(srcdir)/'`ogg_vorbis.c
-+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsndfile_la_CPPFLAGS) $(CPPFLAGS) $(libsndfile_la_CFLAGS) $(CFLAGS) $(EXTERNAL_XIPH_CFLAGS) -MT libsndfile_la-ogg_vorbis.lo -MD -MP -MF $(DEPDIR)/libsndfile_la-ogg_vorbis.Tpo -c -o libsndfile_la-ogg_vorbis.lo `test -f 'ogg_vorbis.c' || echo '$(srcdir)/'`ogg_vorbis.c
- @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsndfile_la-ogg_vorbis.Tpo $(DEPDIR)/libsndfile_la-ogg_vorbis.Plo
- @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ogg_vorbis.c' object='libsndfile_la-ogg_vorbis.lo' libtool=yes @AMDEPBACKSLASH@
- @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
diff --git a/build_files/build_environment/patches/sqlite.diff b/build_files/build_environment/patches/sqlite.diff
deleted file mode 100644
index 80f1384f9cf..00000000000
--- a/build_files/build_environment/patches/sqlite.diff
+++ /dev/null
@@ -1,14 +0,0 @@
-Only in external_sqlite_orig: config.log
-diff -ru external_sqlite_orig/config.sub external_sqlite/config.sub
---- external_sqlite_orig/config.sub 2020-07-10 14:06:42.000000000 +0200
-+++ external_sqlite/config.sub 2020-07-10 14:10:24.000000000 +0200
-@@ -314,6 +314,7 @@
- # Recognize the basic CPU types with company name.
- 580-* \
- | a29k-* \
-+ | aarch64-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
-Only in external_sqlite: mksourceid
-Only in external_sqlite: sqlite3session.h
diff --git a/build_files/build_environment/patches/ssl.diff b/build_files/build_environment/patches/ssl.diff
new file mode 100644
index 00000000000..7bb4413952c
--- /dev/null
+++ b/build_files/build_environment/patches/ssl.diff
@@ -0,0 +1,10 @@
+--- ./test/v3ext.c 2022-07-05 11:08:33.000000000 +0200
++++ ./test/v3ext.c 2022-10-18 13:58:05.000000000 +0200
+@@ -8,6 +8,7 @@
+ */
+
+ #include <stdio.h>
++#include <string.h>
+ #include <openssl/x509.h>
+ #include <openssl/x509v3.h>
+ #include <openssl/pem.h>
diff --git a/build_files/build_environment/patches/wayland.diff b/build_files/build_environment/patches/wayland.diff
new file mode 100644
index 00000000000..c080b7b2964
--- /dev/null
+++ b/build_files/build_environment/patches/wayland.diff
@@ -0,0 +1,11 @@
+--- meson.build.orig 2022-06-30 22:59:11.000000000 +0100
++++ meson.build 2022-09-27 13:21:26.428517668 +0100
+@@ -2,7 +2,7 @@
+ 'wayland', 'c',
+ version: '1.21.0',
+ license: 'MIT',
+- meson_version: '>= 0.56.0',
++ meson_version: '>= 0.55.1',
+ default_options: [
+ 'warning_level=2',
+ 'buildtype=debugoptimized',
diff --git a/build_files/cmake/Modules/FindOSL.cmake b/build_files/cmake/Modules/FindOSL.cmake
index ab5de53d3c9..a8d8344ae66 100644
--- a/build_files/cmake/Modules/FindOSL.cmake
+++ b/build_files/cmake/Modules/FindOSL.cmake
@@ -20,6 +20,7 @@ IF(NOT OSL_ROOT_DIR AND NOT $ENV{OSL_ROOT_DIR} STREQUAL "")
ENDIF()
SET(_osl_FIND_COMPONENTS
+ oslnoise
oslcomp
oslexec
oslquery
@@ -39,7 +40,6 @@ FIND_PATH(OSL_INCLUDE_DIR
include
)
-SET(_osl_LIBRARIES)
FOREACH(COMPONENT ${_osl_FIND_COMPONENTS})
STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
@@ -51,9 +51,20 @@ FOREACH(COMPONENT ${_osl_FIND_COMPONENTS})
PATH_SUFFIXES
lib64 lib
)
- LIST(APPEND _osl_LIBRARIES "${OSL_${UPPERCOMPONENT}_LIBRARY}")
ENDFOREACH()
+# Note linking order matters, and oslnoise existence depends on version.
+SET(_osl_LIBRARIES ${OSL_OSLCOMP_LIBRARY})
+IF(APPLE)
+ list(APPEND _osl_LIBRARIES -force_load ${OSL_OSLEXEC_LIBRARY})
+ELSE()
+ list(APPEND _osl_LIBRARIES ${OSL_OSLEXEC_LIBRARY})
+ENDIF()
+list(APPEND _osl_LIBRARIES ${OSL_OSLQUERY_LIBRARY})
+IF(OSL_OSLNOISE_LIBRARY)
+ list(APPEND _osl_LIBRARIES ${OSL_OSLNOISE_LIBRARY})
+ENDIF()
+
FIND_PROGRAM(OSL_COMPILER oslc
HINTS ${_osl_SEARCH_DIRS}
PATH_SUFFIXES bin)
diff --git a/build_files/cmake/Modules/FindOpenEXR.cmake b/build_files/cmake/Modules/FindOpenEXR.cmake
index 9107b562711..1cc3e50ba92 100644
--- a/build_files/cmake/Modules/FindOpenEXR.cmake
+++ b/build_files/cmake/Modules/FindOpenEXR.cmake
@@ -26,7 +26,8 @@ IF(NOT OPENEXR_ROOT_DIR AND NOT $ENV{OPENEXR_ROOT_DIR} STREQUAL "")
SET(OPENEXR_ROOT_DIR $ENV{OPENEXR_ROOT_DIR})
ENDIF()
-# Old versions (before 2.0?) do not have any version string, just assuming this should be fine though.
+# Old versions (before 2.0?) do not have any version string,
+# just assuming this should be fine though.
SET(_openexr_libs_ver_init "2.0")
SET(_openexr_SEARCH_DIRS
diff --git a/build_files/cmake/Modules/FindOpenSubdiv.cmake b/build_files/cmake/Modules/FindOpenSubdiv.cmake
index 37a2cddf3de..66d3b435c46 100644
--- a/build_files/cmake/Modules/FindOpenSubdiv.cmake
+++ b/build_files/cmake/Modules/FindOpenSubdiv.cmake
@@ -71,21 +71,6 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenSubdiv DEFAULT_MSG
IF(OPENSUBDIV_FOUND)
SET(OPENSUBDIV_LIBRARIES ${_opensubdiv_LIBRARIES})
SET(OPENSUBDIV_INCLUDE_DIRS ${OPENSUBDIV_INCLUDE_DIR})
-
- # Find available compute controllers.
-
- FIND_PACKAGE(OpenMP)
- IF(OPENMP_FOUND)
- SET(OPENSUBDIV_HAS_OPENMP TRUE)
- ELSE()
- SET(OPENSUBDIV_HAS_OPENMP FALSE)
- ENDIF()
-
- OPENSUBDIV_CHECK_CONTROLLER("tbbEvaluator.h" OPENSUBDIV_HAS_TBB)
- OPENSUBDIV_CHECK_CONTROLLER("clEvaluator.h" OPENSUBDIV_HAS_OPENCL)
- OPENSUBDIV_CHECK_CONTROLLER("cudaEvaluator.h" OPENSUBDIV_HAS_CUDA)
- OPENSUBDIV_CHECK_CONTROLLER("glXFBEvaluator.h" OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK)
- OPENSUBDIV_CHECK_CONTROLLER("glComputeEvaluator.h" OPENSUBDIV_HAS_GLSL_COMPUTE)
ENDIF()
MARK_AS_ADVANCED(
diff --git a/build_files/cmake/Modules/FindSYCL.cmake b/build_files/cmake/Modules/FindSYCL.cmake
index ac90cbfbe43..1ccbee179fb 100644
--- a/build_files/cmake/Modules/FindSYCL.cmake
+++ b/build_files/cmake/Modules/FindSYCL.cmake
@@ -30,6 +30,7 @@ SET(_sycl_search_dirs
# dpcpp binary.
FIND_PROGRAM(SYCL_COMPILER
NAMES
+ icpx
dpcpp
clang++
HINTS
@@ -44,7 +45,8 @@ FIND_PROGRAM(SYCL_COMPILER
# compiler.
if(NOT SYCL_COMPILER)
FIND_PROGRAM(SYCL_COMPILER
- NAMES
+ NAMES
+ icpx
dpcpp
HINTS
${_sycl_search_dirs}
@@ -55,6 +57,8 @@ endif()
FIND_LIBRARY(SYCL_LIBRARY
NAMES
+ sycl7
+ sycl6
sycl
HINTS
${_sycl_search_dirs}
@@ -62,23 +66,48 @@ FIND_LIBRARY(SYCL_LIBRARY
lib64 lib
)
+if(WIN32)
+ FIND_LIBRARY(SYCL_LIBRARY_DEBUG
+ NAMES
+ sycl7d
+ sycl6d
+ sycld
+ HINTS
+ ${_sycl_search_dirs}
+ PATH_SUFFIXES
+ lib64 lib
+ )
+endif()
+
FIND_PATH(SYCL_INCLUDE_DIR
NAMES
- CL/sycl.hpp
+ sycl/sycl.hpp
HINTS
${_sycl_search_dirs}
PATH_SUFFIXES
include
- include/sycl
)
+IF(EXISTS "${SYCL_INCLUDE_DIR}/sycl/version.hpp")
+ FILE(STRINGS "${SYCL_INCLUDE_DIR}/sycl/version.hpp" _libsycl_major_version REGEX "^#define __LIBSYCL_MAJOR_VERSION[ \t].*$")
+ STRING(REGEX MATCHALL "[0-9]+" _libsycl_major_version ${_libsycl_major_version})
+ FILE(STRINGS "${SYCL_INCLUDE_DIR}/sycl/version.hpp" _libsycl_minor_version REGEX "^#define __LIBSYCL_MINOR_VERSION[ \t].*$")
+ STRING(REGEX MATCHALL "[0-9]+" _libsycl_minor_version ${_libsycl_minor_version})
+ FILE(STRINGS "${SYCL_INCLUDE_DIR}/sycl/version.hpp" _libsycl_patch_version REGEX "^#define __LIBSYCL_PATCH_VERSION[ \t].*$")
+ STRING(REGEX MATCHALL "[0-9]+" _libsycl_patch_version ${_libsycl_patch_version})
+
+ SET(SYCL_VERSION "${_libsycl_major_version}.${_libsycl_minor_version}.${_libsycl_patch_version}")
+ENDIF()
+
INCLUDE(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(SYCL DEFAULT_MSG SYCL_LIBRARY SYCL_INCLUDE_DIR)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SYCL
+ REQUIRED_VARS SYCL_LIBRARY SYCL_INCLUDE_DIR
+ VERSION_VAR SYCL_VERSION
+)
IF(SYCL_FOUND)
- get_filename_component(_SYCL_INCLUDE_PARENT_DIR ${SYCL_INCLUDE_DIR} DIRECTORY)
- SET(SYCL_INCLUDE_DIR ${SYCL_INCLUDE_DIR} ${_SYCL_INCLUDE_PARENT_DIR})
+ SET(SYCL_INCLUDE_DIR ${SYCL_INCLUDE_DIR} ${SYCL_INCLUDE_DIR}/sycl)
ELSE()
SET(SYCL_SYCL_FOUND FALSE)
ENDIF()
diff --git a/build_files/cmake/Modules/FindUSD.cmake b/build_files/cmake/Modules/FindUSD.cmake
index 0fd5f06bb35..ba5a3d7c843 100644
--- a/build_files/cmake/Modules/FindUSD.cmake
+++ b/build_files/cmake/Modules/FindUSD.cmake
@@ -32,7 +32,8 @@ FIND_PATH(USD_INCLUDE_DIR
DOC "Universal Scene Description (USD) header files"
)
-# Since USD 21.11 the libraries are prefixed with "usd_", i.e. "libusd_m.a" became "libusd_usd_m.a".
+# Since USD 21.11 the libraries are prefixed with "usd_", i.e.
+# "libusd_m.a" became "libusd_usd_m.a".
# See https://github.com/PixarAnimationStudios/USD/blob/release/CHANGELOG.md#2111---2021-11-01
FIND_LIBRARY(USD_LIBRARY
NAMES
diff --git a/build_files/cmake/Modules/GTestTesting.cmake b/build_files/cmake/Modules/GTestTesting.cmake
index 92ce403d5f3..5ffd158361e 100644
--- a/build_files/cmake/Modules/GTestTesting.cmake
+++ b/build_files/cmake/Modules/GTestTesting.cmake
@@ -40,12 +40,10 @@ macro(BLENDER_SRC_GTEST_EX)
set(MANIFEST "${CMAKE_BINARY_DIR}/tests.exe.manifest")
endif()
- add_definitions(-DBLENDER_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
- add_definitions(${GFLAGS_DEFINES})
- add_definitions(${GLOG_DEFINES})
-
add_executable(${TARGET_NAME} ${ARG_SRC} ${MANIFEST})
setup_platform_linker_flags(${TARGET_NAME})
+ target_compile_definitions(${TARGET_NAME} PRIVATE ${GFLAGS_DEFINES})
+ target_compile_definitions(${TARGET_NAME} PRIVATE ${GLOG_DEFINES})
target_include_directories(${TARGET_NAME} PUBLIC "${TEST_INC}")
target_include_directories(${TARGET_NAME} SYSTEM PUBLIC "${TEST_INC_SYS}")
target_link_libraries(${TARGET_NAME} ${ARG_EXTRA_LIBS} ${PLATFORM_LINKLIBS})
diff --git a/build_files/cmake/buildinfo.cmake b/build_files/cmake/buildinfo.cmake
index 53e22ed23ad..b0640acbe96 100644
--- a/build_files/cmake/buildinfo.cmake
+++ b/build_files/cmake/buildinfo.cmake
@@ -150,10 +150,10 @@ endif()
# BUILD_PLATFORM is taken from CMake
# but BUILD_DATE and BUILD_TIME are platform dependent
if(NOT BUILD_DATE)
- STRING(TIMESTAMP BUILD_DATE "%Y-%m-%d" UTC)
+ string(TIMESTAMP BUILD_DATE "%Y-%m-%d" UTC)
endif()
if(NOT BUILD_TIME)
- STRING(TIMESTAMP BUILD_TIME "%H:%M:%S" UTC)
+ string(TIMESTAMP BUILD_TIME "%H:%M:%S" UTC)
endif()
# Write a file with the BUILD_HASH define
diff --git a/build_files/cmake/config/blender_developer.cmake b/build_files/cmake/config/blender_developer.cmake
index 1f1a100d958..ebc5727a79c 100644
--- a/build_files/cmake/config/blender_developer.cmake
+++ b/build_files/cmake/config/blender_developer.cmake
@@ -8,7 +8,11 @@
set(WITH_ASSERT_ABORT ON CACHE BOOL "" FORCE)
set(WITH_BUILDINFO OFF CACHE BOOL "" FORCE)
-set(WITH_COMPILER_ASAN ON CACHE BOOL "" FORCE)
+# Sadly ASAN is more often broken than working with MSVC do not enable it in the
+# developer profile for now.
+if(NOT WIN32)
+ set(WITH_COMPILER_ASAN ON CACHE BOOL "" FORCE)
+endif()
set(WITH_CYCLES_NATIVE_ONLY ON CACHE BOOL "" FORCE)
set(WITH_DOC_MANPAGE OFF CACHE BOOL "" FORCE)
set(WITH_GTESTS ON CACHE BOOL "" FORCE)
diff --git a/build_files/cmake/config/blender_full.cmake b/build_files/cmake/config/blender_full.cmake
index 27577a9fbf7..95304bd64c7 100644
--- a/build_files/cmake/config/blender_full.cmake
+++ b/build_files/cmake/config/blender_full.cmake
@@ -17,6 +17,7 @@ set(WITH_COMPOSITOR_CPU ON CACHE BOOL "" FORCE)
set(WITH_CYCLES ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_EMBREE ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_OSL ON CACHE BOOL "" FORCE)
+set(WITH_CYCLES_PATH_GUIDING ON CACHE BOOL "" FORCE)
set(WITH_DRACO ON CACHE BOOL "" FORCE)
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
@@ -65,13 +66,11 @@ set(WITH_MEM_JEMALLOC ON CACHE BOOL "" FORCE)
if(APPLE)
set(WITH_COREAUDIO ON CACHE BOOL "" FORCE)
endif()
-if(NOT WIN32)
- set(WITH_JACK ON CACHE BOOL "" FORCE)
-endif()
if(WIN32)
set(WITH_WASAPI ON CACHE BOOL "" FORCE)
endif()
if(UNIX AND NOT APPLE)
+ set(WITH_JACK ON CACHE BOOL "" FORCE)
set(WITH_DOC_MANPAGE ON CACHE BOOL "" FORCE)
set(WITH_GHOST_XDND ON CACHE BOOL "" FORCE)
set(WITH_PULSEAUDIO ON CACHE BOOL "" FORCE)
diff --git a/build_files/cmake/config/blender_release.cmake b/build_files/cmake/config/blender_release.cmake
index 793d1cb0853..74bbcb223c3 100644
--- a/build_files/cmake/config/blender_release.cmake
+++ b/build_files/cmake/config/blender_release.cmake
@@ -18,6 +18,7 @@ set(WITH_COMPOSITOR_CPU ON CACHE BOOL "" FORCE)
set(WITH_CYCLES ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_EMBREE ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_OSL ON CACHE BOOL "" FORCE)
+set(WITH_CYCLES_PATH_GUIDING ON CACHE BOOL "" FORCE)
set(WITH_DRACO ON CACHE BOOL "" FORCE)
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
@@ -66,13 +67,11 @@ if(APPLE)
set(WITH_COREAUDIO ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_DEVICE_METAL ON CACHE BOOL "" FORCE)
endif()
-if(NOT WIN32)
- set(WITH_JACK ON CACHE BOOL "" FORCE)
-endif()
if(WIN32)
set(WITH_WASAPI ON CACHE BOOL "" FORCE)
endif()
if(UNIX AND NOT APPLE)
+ set(WITH_JACK ON CACHE BOOL "" FORCE)
set(WITH_DOC_MANPAGE ON CACHE BOOL "" FORCE)
set(WITH_GHOST_XDND ON CACHE BOOL "" FORCE)
set(WITH_PULSEAUDIO ON CACHE BOOL "" FORCE)
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index d271d8f216f..73883376060 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -57,6 +57,25 @@ macro(path_ensure_trailing_slash
unset(_path_sep)
endmacro()
+# Our own version of `cmake_path(IS_PREFIX ..)`.
+# This can be removed when 3.20 or greater is the minimum supported version.
+macro(path_is_prefix
+ path_prefix path result_var
+ )
+ # Remove when CMAKE version is bumped to "3.20" or greater.
+ # `cmake_path(IS_PREFIX ${path_prefix} ${path} NORMALIZE result_var)`
+ # Get the normalized paths (needed to remove `..`).
+ get_filename_component(_abs_prefix "${${path_prefix}}" ABSOLUTE)
+ get_filename_component(_abs_suffix "${${path}}" ABSOLUTE)
+ string(LENGTH "${_abs_prefix}" _len)
+ string(SUBSTRING "${_abs_suffix}" 0 "${_len}" _substr)
+ string(COMPARE EQUAL "${_abs_prefix}" "${_substr}" "${result_var}")
+ unset(_abs_prefix)
+ unset(_abs_suffix)
+ unset(_len)
+ unset(_substr)
+endmacro()
+
# foo_bar.spam --> foo_barMySuffix.spam
macro(file_suffix
file_name_new file_name file_suffix
@@ -134,12 +153,11 @@ endfunction()
# Nicer makefiles with -I/1/foo/ instead of -I/1/2/3/../../foo/
# use it instead of include_directories()
-function(blender_include_dirs
- includes
- )
+function(absolute_include_dirs
+ includes_absolute)
set(_ALL_INCS "")
- foreach(_INC ${ARGV})
+ foreach(_INC ${ARGN})
get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
list(APPEND _ALL_INCS ${_ABS_INC})
# for checking for invalid includes, disable for regular use
@@ -147,22 +165,24 @@ function(blender_include_dirs
# message(FATAL_ERROR "Include not found: ${_ABS_INC}/")
# endif()
endforeach()
- include_directories(${_ALL_INCS})
+
+ set(${includes_absolute} ${_ALL_INCS} PARENT_SCOPE)
endfunction()
-function(blender_include_dirs_sys
- includes
+function(blender_target_include_dirs
+ name
)
- set(_ALL_INCS "")
- foreach(_INC ${ARGV})
- get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
- list(APPEND _ALL_INCS ${_ABS_INC})
- # if(NOT EXISTS "${_ABS_INC}/")
- # message(FATAL_ERROR "Include not found: ${_ABS_INC}/")
- # endif()
- endforeach()
- include_directories(SYSTEM ${_ALL_INCS})
+ absolute_include_dirs(_ALL_INCS ${ARGN})
+ target_include_directories(${name} PRIVATE ${_ALL_INCS})
+endfunction()
+
+function(blender_target_include_dirs_sys
+ name
+ )
+
+ absolute_include_dirs(_ALL_INCS ${ARGN})
+ target_include_directories(${name} SYSTEM PRIVATE ${_ALL_INCS})
endfunction()
# Set include paths for header files included with "*.h" syntax.
@@ -268,13 +288,11 @@ function(blender_add_lib__impl
# message(STATUS "Configuring library ${name}")
- # include_directories(${includes})
- # include_directories(SYSTEM ${includes_sys})
- blender_include_dirs("${includes}")
- blender_include_dirs_sys("${includes_sys}")
-
add_library(${name} ${sources})
+ blender_target_include_dirs(${name} ${includes})
+ blender_target_include_dirs_sys(${name} ${includes_sys})
+
# On Windows certain libraries have two sets of binaries: one for debug builds and one for
# release builds. The root of this requirement goes into ABI, I believe, but that's outside
# of a scope of this comment.
@@ -382,7 +400,7 @@ function(blender_add_test_suite)
cmake_parse_arguments(ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# Figure out the release dir, as some tests need files from there.
- GET_BLENDER_TEST_INSTALL_DIR(TEST_INSTALL_DIR)
+ get_blender_test_install_dir(TEST_INSTALL_DIR)
if(APPLE)
set(_test_release_dir ${TEST_INSTALL_DIR}/Blender.app/Contents/Resources/${BLENDER_VERSION})
else()
@@ -425,21 +443,21 @@ function(blender_add_test_lib
# This duplicates logic that's also in GTestTesting.cmake, macro BLENDER_SRC_GTEST_EX.
# TODO(Sybren): deduplicate after the general approach in D7649 has been approved.
- LIST(APPEND includes
+ list(APPEND includes
${CMAKE_SOURCE_DIR}/tests/gtests
)
- LIST(APPEND includes_sys
+ list(APPEND includes_sys
${GLOG_INCLUDE_DIRS}
${GFLAGS_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/extern/gtest/include
${CMAKE_SOURCE_DIR}/extern/gmock/include
)
- add_definitions(-DBLENDER_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
- add_definitions(${GFLAGS_DEFINES})
- add_definitions(${GLOG_DEFINES})
blender_add_lib__impl(${name} "${sources}" "${includes}" "${includes_sys}" "${library_deps}")
+ target_compile_definitions(${name} PRIVATE ${GFLAGS_DEFINES})
+ target_compile_definitions(${name} PRIVATE ${GLOG_DEFINES})
+
set_property(GLOBAL APPEND PROPERTY BLENDER_TEST_LIBS ${name})
blender_add_test_suite(
@@ -469,16 +487,16 @@ function(blender_add_test_executable
## Otherwise external projects will produce warnings that we cannot fix.
remove_strict_flags()
- include_directories(${includes})
- include_directories(${includes_sys})
-
- BLENDER_SRC_GTEST_EX(
+ blender_src_gtest_ex(
NAME ${name}
SRC "${sources}"
EXTRA_LIBS "${library_deps}"
SKIP_ADD_TEST
)
+ blender_target_include_dirs(${name}_test ${includes})
+ blender_target_include_dirs_sys(${name}_test ${includes_sys})
+
blender_add_test_suite(
TARGET ${name}_test
SUITE_NAME ${name}
@@ -513,6 +531,11 @@ function(setup_platform_linker_flags
set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " ${PLATFORM_LINKFLAGS}")
set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE " ${PLATFORM_LINKFLAGS_RELEASE}")
set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG " ${PLATFORM_LINKFLAGS_DEBUG}")
+
+ get_target_property(target_type ${target} TYPE)
+ if (target_type STREQUAL "EXECUTABLE")
+ set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " ${PLATFORM_LINKFLAGS_EXECUTABLE}")
+ endif()
endfunction()
# Platform specific libraries for targets.
@@ -760,7 +783,7 @@ function(ADD_CHECK_C_COMPILER_FLAG
include(CheckCCompilerFlag)
- CHECK_C_COMPILER_FLAG("${_FLAG}" "${_CACHE_VAR}")
+ check_c_compiler_flag("${_FLAG}" "${_CACHE_VAR}")
if(${_CACHE_VAR})
# message(STATUS "Using CFLAG: ${_FLAG}")
set(${_CFLAGS} "${${_CFLAGS}} ${_FLAG}" PARENT_SCOPE)
@@ -777,7 +800,7 @@ function(ADD_CHECK_CXX_COMPILER_FLAG
include(CheckCXXCompilerFlag)
- CHECK_CXX_COMPILER_FLAG("${_FLAG}" "${_CACHE_VAR}")
+ check_cxx_compiler_flag("${_FLAG}" "${_CACHE_VAR}")
if(${_CACHE_VAR})
# message(STATUS "Using CXXFLAG: ${_FLAG}")
set(${_CXXFLAGS} "${${_CXXFLAGS}} ${_FLAG}" PARENT_SCOPE)
@@ -795,9 +818,11 @@ function(get_blender_version)
# - BLENDER_VERSION_PATCH
# - BLENDER_VERSION_CYCLE (alpha, beta, rc, release)
- # So cmake depends on BKE_blender.h, beware of inf-loops!
- CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/source/blender/blenkernel/BKE_blender_version.h
- ${CMAKE_BINARY_DIR}/source/blender/blenkernel/BKE_blender_version.h.done)
+ # So CMAKE depends on `BKE_blender.h`, beware of infinite-loops!
+ configure_file(
+ ${CMAKE_SOURCE_DIR}/source/blender/blenkernel/BKE_blender_version.h
+ ${CMAKE_BINARY_DIR}/source/blender/blenkernel/BKE_blender_version.h.done
+ )
file(STRINGS ${CMAKE_SOURCE_DIR}/source/blender/blenkernel/BKE_blender_version.h _contents REGEX "^#define[ \t]+BLENDER_.*$")
@@ -989,7 +1014,8 @@ function(data_to_c_simple_icons
add_custom_command(
OUTPUT ${_file_from} ${_file_to}
COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_to_path}
- # COMMAND python3 ${CMAKE_SOURCE_DIR}/source/blender/datatoc/datatoc_icon.py ${_path_from_abs} ${_file_from}
+ # COMMAND python3 ${CMAKE_SOURCE_DIR}/source/blender/datatoc/datatoc_icon.py
+ # ${_path_from_abs} ${_file_from}
COMMAND "$<TARGET_FILE:datatoc_icon>" ${_path_from_abs} ${_file_from}
COMMAND "$<TARGET_FILE:datatoc>" ${_file_from} ${_file_to}
DEPENDS
@@ -1067,23 +1093,27 @@ function(msgfmt_simple
endfunction()
function(find_python_package
- package
- relative_include_dir
+ package
+ relative_include_dir
)
string(TOUPPER ${package} _upper_package)
- # set but invalid
+ # Set but invalid.
if((NOT ${PYTHON_${_upper_package}_PATH} STREQUAL "") AND
(NOT ${PYTHON_${_upper_package}_PATH} MATCHES NOTFOUND))
-# if(NOT EXISTS "${PYTHON_${_upper_package}_PATH}/${package}")
-# message(WARNING "PYTHON_${_upper_package}_PATH is invalid, ${package} not found in '${PYTHON_${_upper_package}_PATH}' "
-# "WITH_PYTHON_INSTALL_${_upper_package} option will be ignored when installing python")
-# set(WITH_PYTHON_INSTALL${_upper_package} OFF)
-# endif()
- # not set, so initialize
+ # if(NOT EXISTS "${PYTHON_${_upper_package}_PATH}/${package}")
+ # message(
+ # WARNING
+ # "PYTHON_${_upper_package}_PATH is invalid, ${package} not found in "
+ # "'${PYTHON_${_upper_package}_PATH}' "
+ # "WITH_PYTHON_INSTALL_${_upper_package} option will be ignored when installing Python"
+ # )
+ # set(WITH_PYTHON_INSTALL${_upper_package} OFF)
+ # endif()
+ # Not set, so initialize.
else()
- string(REPLACE "." ";" _PY_VER_SPLIT "${PYTHON_VERSION}")
+ string(REPLACE "." ";" _PY_VER_SPLIT "${PYTHON_VERSION}")
list(GET _PY_VER_SPLIT 0 _PY_VER_MAJOR)
# re-cache
@@ -1184,8 +1214,6 @@ macro(openmp_delayload
if(WITH_OPENMP)
if(MSVC_CLANG)
set(OPENMP_DLL_NAME "libomp")
- elseif(MSVC_VERSION EQUAL 1800)
- set(OPENMP_DLL_NAME "vcomp120")
else()
set(OPENMP_DLL_NAME "vcomp140")
endif()
@@ -1201,11 +1229,27 @@ macro(set_and_warn_dependency
_dependency _setting _val)
# when $_dependency is disabled, forces $_setting = $_val
if(NOT ${${_dependency}} AND ${${_setting}})
- message(STATUS "'${_dependency}' is disabled: forcing 'set(${_setting} ${_val})'")
+ if(WITH_STRICT_BUILD_OPTIONS)
+ message(SEND_ERROR "${_dependency} disabled but required by ${_setting}")
+ else()
+ message(STATUS "${_dependency} is disabled, setting ${_setting}=${_val}")
+ endif()
set(${_setting} ${_val})
endif()
endmacro()
+macro(set_and_warn_library_found
+ _library_name _library_found _setting)
+ if(NOT ${${_library_found}} AND ${${_setting}})
+ if(WITH_STRICT_BUILD_OPTIONS)
+ message(SEND_ERROR "${_library_name} required but not found")
+ else()
+ message(STATUS "${_library_name} not found, disabling ${_setting}")
+ endif()
+ set(${_setting} OFF)
+ endif()
+endmacro()
+
macro(without_system_libs_begin)
set(CMAKE_IGNORE_PATH "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES};${CMAKE_SYSTEM_INCLUDE_PATH};${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES};${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}")
endmacro()
diff --git a/build_files/cmake/packaging.cmake b/build_files/cmake/packaging.cmake
index f6073eba82e..f178317fc36 100644
--- a/build_files/cmake/packaging.cmake
+++ b/build_files/cmake/packaging.cmake
@@ -17,9 +17,9 @@ set(CPACK_PACKAGE_VENDOR ${PROJECT_VENDOR})
set(CPACK_PACKAGE_CONTACT ${PROJECT_CONTACT})
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
-SET(CPACK_PACKAGE_VERSION_MAJOR "${MAJOR_VERSION}")
-SET(CPACK_PACKAGE_VERSION_MINOR "${MINOR_VERSION}")
-SET(CPACK_PACKAGE_VERSION_PATCH "${PATCH_VERSION}")
+set(CPACK_PACKAGE_VERSION_MAJOR "${MAJOR_VERSION}")
+set(CPACK_PACKAGE_VERSION_MINOR "${MINOR_VERSION}")
+set(CPACK_PACKAGE_VERSION_PATCH "${PATCH_VERSION}")
# Get the build revision, note that this can get out-of-sync, so for packaging run cmake first.
@@ -48,7 +48,7 @@ if(MSVC)
else()
set(PACKAGE_ARCH windows32)
endif()
-else(MSVC)
+else()
set(PACKAGE_ARCH ${CMAKE_SYSTEM_PROCESSOR})
endif()
diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake
index f2a8bd42a3e..c5fe3c908de 100644
--- a/build_files/cmake/platform/platform_apple.cmake
+++ b/build_files/cmake/platform/platform_apple.cmake
@@ -30,16 +30,12 @@ macro(add_bundled_libraries library)
list(APPEND PLATFORM_BUNDLED_LIBRARY_DIRS ${_library_dir})
unset(_all_library_versions)
unset(_library_dir)
- endif()
+ endif()
endmacro()
# ------------------------------------------------------------------------
# Find system provided libraries.
-# Avoid searching for headers since this would otherwise override our lib
-# directory as well as PYTHON_ROOT_DIR.
-set(CMAKE_FIND_FRAMEWORK NEVER)
-
# Find system ZLIB, not the pre-compiled one supplied with OpenCollada.
set(ZLIB_ROOT /usr)
find_package(ZLIB REQUIRED)
@@ -47,22 +43,18 @@ find_package(BZip2 REQUIRED)
list(APPEND ZLIB_LIBRARIES ${BZIP2_LIBRARIES})
if(WITH_OPENAL)
- find_package(OpenAL)
- if(NOT OPENAL_FOUND)
- message(WARNING "OpenAL not found, disabling WITH_OPENAL")
- set(WITH_OPENAL OFF)
- endif()
+ find_package(OpenAL REQUIRED)
endif()
if(WITH_JACK)
find_library(JACK_FRAMEWORK
NAMES jackmp
)
- if(NOT JACK_FRAMEWORK)
- message(STATUS "JACK not found, disabling WITH_JACK")
- set(WITH_JACK OFF)
- else()
+
+ if(JACK_FRAMEWORK)
set(JACK_INCLUDE_DIRS ${JACK_FRAMEWORK}/headers)
+ else()
+ set_and_warn_library_found("JACK" JACK_FRAMEWORK WITH_JACK)
endif()
endif()
@@ -79,6 +71,10 @@ if(NOT EXISTS "${LIBDIR}/")
message(FATAL_ERROR "Mac OSX requires pre-compiled libs at: '${LIBDIR}'")
endif()
+# Avoid searching for headers since this would otherwise override our lib
+# directory as well as PYTHON_ROOT_DIR.
+set(CMAKE_FIND_FRAMEWORK NEVER)
+
# Optionally use system Python if PYTHON_ROOT_DIR is specified.
if(WITH_PYTHON AND (WITH_PYTHON_MODULE AND PYTHON_ROOT_DIR))
find_package(PythonLibsUnix REQUIRED)
@@ -101,11 +97,7 @@ if(WITH_ALEMBIC)
endif()
if(WITH_USD)
- find_package(USD)
- if(NOT USD_FOUND)
- message(STATUS "USD not found, disabling WITH_USD")
- set(WITH_USD OFF)
- endif()
+ find_package(USD REQUIRED)
endif()
if(WITH_OPENSUBDIV)
@@ -227,20 +219,12 @@ find_package(JPEG REQUIRED)
if(WITH_IMAGE_TIFF)
set(TIFF_ROOT ${LIBDIR}/tiff)
- find_package(TIFF)
- if(NOT TIFF_FOUND)
- message(WARNING "TIFF not found, disabling WITH_IMAGE_TIFF")
- set(WITH_IMAGE_TIFF OFF)
- endif()
+ find_package(TIFF REQUIRED)
endif()
if(WITH_IMAGE_WEBP)
set(WEBP_ROOT_DIR ${LIBDIR}/webp)
- find_package(WebP)
- if(NOT WEBP_FOUND)
- message(WARNING "WebP not found, disabling WITH_IMAGE_WEBP")
- set(WITH_IMAGE_WEBP OFF)
- endif()
+ find_package(WebP REQUIRED)
endif()
if(WITH_BOOST)
@@ -270,11 +254,7 @@ if(WITH_INTERNATIONAL OR WITH_CODEC_FFMPEG)
endif()
if(WITH_PUGIXML)
- find_package(PugiXML)
- if(NOT PUGIXML_FOUND)
- message(WARNING "PugiXML not found, disabling WITH_PUGIXML")
- set(WITH_PUGIXML OFF)
- endif()
+ find_package(PugiXML REQUIRED)
endif()
if(WITH_OPENIMAGEIO)
@@ -292,12 +272,7 @@ if(WITH_OPENIMAGEIO)
endif()
if(WITH_OPENCOLORIO)
- find_package(OpenColorIO 2.0.0)
-
- if(NOT OPENCOLORIO_FOUND)
- set(WITH_OPENCOLORIO OFF)
- message(STATUS "OpenColorIO not found, disabling WITH_OPENCOLORIO")
- endif()
+ find_package(OpenColorIO 2.0.0 REQUIRED)
endif()
if(WITH_OPENVDB)
@@ -324,38 +299,18 @@ if(WITH_LLVM)
if(WITH_CLANG)
find_package(Clang)
if(NOT CLANG_FOUND)
- message(FATAL_ERROR "Clang not found.")
+ message(FATAL_ERROR "Clang not found.")
endif()
endif()
endif()
if(WITH_CYCLES AND WITH_CYCLES_OSL)
- set(CYCLES_OSL ${LIBDIR}/osl)
-
- 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)
- # WARNING! depends on correct order of OSL libs linking
- list(APPEND OSL_LIBRARIES ${OSL_LIB_COMP} -force_load ${OSL_LIB_EXEC} ${OSL_LIB_QUERY})
- find_path(OSL_INCLUDE_DIR OSL/oslclosure.h PATHS ${CYCLES_OSL}/include)
- find_program(OSL_COMPILER NAMES oslc PATHS ${CYCLES_OSL}/bin)
- find_path(OSL_SHADER_DIR NAMES stdosl.h PATHS ${CYCLES_OSL}/share/OSL/shaders)
-
- if(OSL_INCLUDE_DIR AND OSL_LIBRARIES AND OSL_COMPILER AND OSL_SHADER_DIR)
- set(OSL_FOUND TRUE)
- else()
- message(WARNING "OSL not found, disabling WITH_CYCLES_OSL")
- set(WITH_CYCLES_OSL OFF)
- endif()
+ find_package(OSL REQUIRED)
endif()
if(WITH_CYCLES AND WITH_CYCLES_EMBREE)
find_package(Embree 3.8.0 REQUIRED)
- # Increase stack size for Embree, only works for executables.
- if(NOT WITH_PYTHON_MODULE)
- string(APPEND PLATFORM_LINKFLAGS " -Wl,-stack_size,0x100000")
- endif()
# Embree static library linking can mix up SSE and AVX symbols, causing
# crashes on macOS systems with older CPUs that don't have AVX. Using
@@ -369,28 +324,15 @@ if(WITH_CYCLES AND WITH_CYCLES_EMBREE)
endif()
if(WITH_OPENIMAGEDENOISE)
- find_package(OpenImageDenoise)
-
- if(NOT OPENIMAGEDENOISE_FOUND)
- set(WITH_OPENIMAGEDENOISE OFF)
- message(STATUS "OpenImageDenoise not found, disabling WITH_OPENIMAGEDENOISE")
- endif()
+ find_package(OpenImageDenoise REQUIRED)
endif()
if(WITH_TBB)
- find_package(TBB)
- if(NOT TBB_FOUND)
- message(WARNING "TBB not found, disabling WITH_TBB")
- set(WITH_TBB OFF)
- endif()
+ find_package(TBB REQUIRED)
endif()
if(WITH_POTRACE)
- find_package(Potrace)
- if(NOT POTRACE_FOUND)
- message(WARNING "potrace not found, disabling WITH_POTRACE")
- set(WITH_POTRACE OFF)
- endif()
+ find_package(Potrace REQUIRED)
endif()
# CMake FindOpenMP doesn't know about AppleClang before 3.12, so provide custom flags.
@@ -410,26 +352,26 @@ if(WITH_OPENMP)
endif()
if(WITH_XR_OPENXR)
- find_package(XR_OpenXR_SDK)
- if(NOT XR_OPENXR_SDK_FOUND)
- message(WARNING "OpenXR-SDK was not found, disabling WITH_XR_OPENXR")
- set(WITH_XR_OPENXR OFF)
- endif()
+ find_package(XR_OpenXR_SDK REQUIRED)
endif()
if(WITH_GMP)
- find_package(GMP)
- if(NOT GMP_FOUND)
- message(WARNING "GMP not found, disabling WITH_GMP")
- set(WITH_GMP OFF)
- endif()
+ find_package(GMP REQUIRED)
endif()
if(WITH_HARU)
- find_package(Haru)
- if(NOT HARU_FOUND)
- message(WARNING "Haru not found, disabling WITH_HARU")
- set(WITH_HARU OFF)
+ find_package(Haru REQUIRED)
+endif()
+
+if(WITH_CYCLES AND WITH_CYCLES_PATH_GUIDING)
+ find_package(openpgl QUIET)
+ if(openpgl_FOUND)
+ get_target_property(OPENPGL_LIBRARIES openpgl::openpgl LOCATION)
+ get_target_property(OPENPGL_INCLUDE_DIR openpgl::openpgl INTERFACE_INCLUDE_DIRECTORIES)
+ message(STATUS "Found OpenPGL: ${OPENPGL_LIBRARIES}")
+ else()
+ set(WITH_CYCLES_PATH_GUIDING OFF)
+ message(STATUS "OpenPGL not found, disabling WITH_CYCLES_PATH_GUIDING")
endif()
endif()
@@ -475,6 +417,9 @@ string(APPEND PLATFORM_LINKFLAGS
string(APPEND CMAKE_CXX_FLAGS " -stdlib=libc++")
string(APPEND PLATFORM_LINKFLAGS " -stdlib=libc++")
+# Make stack size more similar to Embree, required for Embree.
+string(APPEND PLATFORM_LINKFLAGS_EXECUTABLE " -Wl,-stack_size,0x100000")
+
# Suppress ranlib "has no symbols" warnings (workaround for T48250)
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake
index f65fda83504..f1ce3221440 100644
--- a/build_files/cmake/platform/platform_unix.cmake
+++ b/build_files/cmake/platform/platform_unix.cmake
@@ -26,11 +26,6 @@ if(NOT DEFINED LIBDIR)
else()
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND True)
endif()
-
- if(CMAKE_COMPILER_IS_GNUCC AND
- CMAKE_C_COMPILER_VERSION VERSION_LESS 9.3)
- message(FATAL_ERROR "GCC version must be at least 9.3 for precompiled libraries, found ${CMAKE_C_COMPILER_VERSION}")
- endif()
endif()
# Avoid namespace pollustion.
@@ -94,7 +89,7 @@ macro(add_bundled_libraries library)
file(GLOB _all_library_versions ${LIBDIR}/${library}/lib/*\.so*)
list(APPEND PLATFORM_BUNDLED_LIBRARIES ${_all_library_versions})
unset(_all_library_versions)
- endif()
+ endif()
endmacro()
# ----------------------------------------------------------------------------
@@ -143,44 +138,60 @@ if(NOT WITH_SYSTEM_FREETYPE)
endif()
if(WITH_PYTHON)
- # No way to set py35, remove for now.
- # find_package(PythonLibs)
+ # This could be used, see: D14954 for details.
+ # `find_package(PythonLibs)`
- # Use our own instead, since without py is such a rare case,
- # require this package
- # XXX Linking errors with debian static python :/
-# find_package_wrapper(PythonLibsUnix REQUIRED)
+ # Use our own instead, since without Python is such a rare case,
+ # require this package.
+ # XXX: Linking errors with Debian static Python (sigh).
+ # find_package_wrapper(PythonLibsUnix REQUIRED)
find_package(PythonLibsUnix REQUIRED)
+
+ if(WITH_PYTHON_MODULE AND NOT WITH_INSTALL_PORTABLE)
+ # Installing into `site-packages`, warn when installing into `./../lib/`
+ # which script authors almost certainly don't want.
+ if(EXISTS ${LIBDIR})
+ path_is_prefix(LIBDIR PYTHON_SITE_PACKAGES _is_prefix)
+ if(_is_prefix)
+ message(WARNING "
+Building Blender with the following configuration:
+ - WITH_PYTHON_MODULE=ON
+ - WITH_INSTALL_PORTABLE=OFF
+ - LIBDIR=\"${LIBDIR}\"
+ - PYTHON_SITE_PACKAGES=\"${PYTHON_SITE_PACKAGES}\"
+In this case you may want to either:
+ - Use the system Python's site-packages, see:
+ python -c \"import site; print(site.getsitepackages()[0])\"
+ - Set WITH_INSTALL_PORTABLE=ON to create a stand-alone \"bpy\" module
+ which you will need to ensure is in Python's module search path.
+Proceeding with PYTHON_SITE_PACKAGES install target, you have been warned!"
+ )
+ endif()
+ unset(_is_prefix)
+ endif()
+ endif()
endif()
if(WITH_IMAGE_OPENEXR)
find_package_wrapper(OpenEXR) # our own module
- if(NOT OPENEXR_FOUND)
- set(WITH_IMAGE_OPENEXR OFF)
- endif()
+ set_and_warn_library_found("OpenEXR" OPENEXR_FOUND WITH_IMAGE_OPENEXR)
endif()
if(WITH_IMAGE_OPENJPEG)
find_package_wrapper(OpenJPEG)
- if(NOT OPENJPEG_FOUND)
- set(WITH_IMAGE_OPENJPEG OFF)
- endif()
+ set_and_warn_library_found("OpenJPEG" OPENJPEG_FOUND WITH_IMAGE_OPENJPEG)
endif()
if(WITH_IMAGE_TIFF)
# XXX Linking errors with debian static tiff :/
# find_package_wrapper(TIFF)
find_package(TIFF)
- if(NOT TIFF_FOUND)
- set(WITH_IMAGE_TIFF OFF)
- endif()
+ set_and_warn_library_found("TIFF" TIFF_FOUND WITH_IMAGE_TIFF)
endif()
if(WITH_OPENAL)
find_package_wrapper(OpenAL)
- if(NOT OPENAL_FOUND)
- set(WITH_OPENAL OFF)
- endif()
+ set_and_warn_library_found("OpenAL" OPENAL_FOUND WITH_OPENAL)
endif()
if(WITH_SDL)
@@ -202,18 +213,14 @@ if(WITH_SDL)
SDL_LIBRARY
)
# unset(SDLMAIN_LIBRARY CACHE)
- if(NOT SDL_FOUND)
- set(WITH_SDL OFF)
- endif()
+ set_and_warn_library_found("SDL" SDL_FOUND WITH_SDL)
endif()
endif()
# Codecs
if(WITH_CODEC_SNDFILE)
find_package_wrapper(SndFile)
- if(NOT SNDFILE_FOUND)
- set(WITH_CODEC_SNDFILE OFF)
- endif()
+ set_and_warn_library_found("libsndfile" SNDFILE_FOUND WITH_CODEC_SNDFILE)
endif()
if(WITH_CODEC_FFMPEG)
@@ -241,17 +248,12 @@ if(WITH_CODEC_FFMPEG)
endif()
find_package(FFmpeg)
- if(NOT FFMPEG_FOUND)
- set(WITH_CODEC_FFMPEG OFF)
- message(STATUS "FFmpeg not found, disabling it")
- endif()
+ set_and_warn_library_found("FFmpeg" FFMPEG_FOUND WITH_CODEC_FFMPEG)
endif()
if(WITH_FFTW3)
find_package_wrapper(Fftw3)
- if(NOT FFTW3_FOUND)
- set(WITH_FFTW3 OFF)
- endif()
+ set_and_warn_library_found("fftw3" FFTW3_FOUND WITH_FFTW3)
endif()
if(WITH_OPENCOLLADA)
@@ -266,25 +268,23 @@ if(WITH_OPENCOLLADA)
endif()
find_package_wrapper(XML2)
else()
- set(WITH_OPENCOLLADA OFF)
+ set_and_warn_library_found("OpenCollada" OPENCOLLADA_FOUND WITH_OPENCOLLADA)
endif()
endif()
if(WITH_MEM_JEMALLOC)
find_package_wrapper(JeMalloc)
- if(NOT JEMALLOC_FOUND)
- set(WITH_MEM_JEMALLOC OFF)
- endif()
+ set_and_warn_library_found("JeMalloc" JEMALLOC_FOUND WITH_MEM_JEMALLOC)
endif()
if(WITH_INPUT_NDOF)
find_package_wrapper(Spacenav)
+ set_and_warn_library_found("SpaceNav" SPACENAV_FOUND WITH_INPUT_NDOF)
+
if(SPACENAV_FOUND)
# use generic names within blenders buildsystem.
set(NDOF_INCLUDE_DIRS ${SPACENAV_INCLUDE_DIRS})
set(NDOF_LIBRARIES ${SPACENAV_LIBRARIES})
- else()
- set(WITH_INPUT_NDOF OFF)
endif()
endif()
@@ -294,6 +294,8 @@ if(WITH_CYCLES AND WITH_CYCLES_OSL)
set(OSL_ROOT ${CYCLES_OSL})
endif()
find_package_wrapper(OSL)
+ set_and_warn_library_found("OSL" OSL_FOUND WITH_CYCLES_OSL)
+
if(OSL_FOUND)
if(${OSL_LIBRARY_VERSION_MAJOR} EQUAL "1" AND ${OSL_LIBRARY_VERSION_MINOR} LESS "6")
# Note: --whole-archive is needed to force loading of all symbols in liboslexec,
@@ -304,45 +306,42 @@ if(WITH_CYCLES AND WITH_CYCLES_OSL)
-Wl,--no-whole-archive ${OSL_OSLQUERY_LIBRARY}
)
endif()
- else()
- message(STATUS "OSL not found, disabling it from Cycles")
- set(WITH_CYCLES_OSL OFF)
endif()
endif()
-if(WITH_CYCLES_DEVICE_ONEAPI)
+if(WITH_CYCLES AND WITH_CYCLES_DEVICE_ONEAPI)
set(CYCLES_LEVEL_ZERO ${LIBDIR}/level-zero CACHE PATH "Path to Level Zero installation")
if(EXISTS ${CYCLES_LEVEL_ZERO} AND NOT LEVEL_ZERO_ROOT_DIR)
set(LEVEL_ZERO_ROOT_DIR ${CYCLES_LEVEL_ZERO})
endif()
- set(CYCLES_SYCL ${LIBDIR}/dpcpp CACHE PATH "Path to DPC++ and SYCL installation")
+ set(CYCLES_SYCL ${LIBDIR}/dpcpp CACHE PATH "Path to oneAPI DPC++ compiler")
if(EXISTS ${CYCLES_SYCL} AND NOT SYCL_ROOT_DIR)
set(SYCL_ROOT_DIR ${CYCLES_SYCL})
endif()
+ file(GLOB _sycl_runtime_libraries
+ ${SYCL_ROOT_DIR}/lib/libsycl.so
+ ${SYCL_ROOT_DIR}/lib/libsycl.so.*
+ ${SYCL_ROOT_DIR}/lib/libpi_level_zero.so
+ )
+ list(FILTER _sycl_runtime_libraries EXCLUDE REGEX ".*\.py")
+ list(APPEND PLATFORM_BUNDLED_LIBRARIES ${_sycl_runtime_libraries})
+ unset(_sycl_runtime_libraries)
endif()
if(WITH_OPENVDB)
find_package_wrapper(OpenVDB)
- find_package_wrapper(Blosc)
-
- if(NOT OPENVDB_FOUND)
- set(WITH_OPENVDB OFF)
- set(WITH_OPENVDB_BLOSC OFF)
- message(STATUS "OpenVDB not found, disabling it")
- elseif(NOT BLOSC_FOUND)
- set(WITH_OPENVDB_BLOSC OFF)
- message(STATUS "Blosc not found, disabling it for OpenVBD")
+ set_and_warn_library_found("OpenVDB" OPENVDB_FOUND WITH_OPENVDB)
+
+ if(OPENVDB_FOUND)
+ find_package_wrapper(Blosc)
+ set_and_warn_library_found("Blosc" BLOSC_FOUND WITH_OPENVDB_BLOSC)
endif()
endif()
if(WITH_NANOVDB)
find_package_wrapper(NanoVDB)
-
- if(NOT NANOVDB_FOUND)
- set(WITH_NANOVDB OFF)
- message(STATUS "NanoVDB not found, disabling it")
- endif()
+ set_and_warn_library_found("NanoVDB" NANOVDB_FOUND WITH_NANOVDB)
endif()
if(WITH_CPU_SIMD AND SUPPORT_NEON_BUILD)
@@ -351,18 +350,12 @@ endif()
if(WITH_ALEMBIC)
find_package_wrapper(Alembic)
-
- if(NOT ALEMBIC_FOUND)
- set(WITH_ALEMBIC OFF)
- endif()
+ set_and_warn_library_found("Alembic" ALEMBIC_FOUND WITH_ALEMBIC)
endif()
if(WITH_USD)
find_package_wrapper(USD)
-
- if(NOT USD_FOUND)
- set(WITH_USD OFF)
- endif()
+ set_and_warn_library_found("USD" USD_FOUND WITH_USD)
endif()
if(WITH_BOOST)
@@ -415,20 +408,13 @@ endif()
if(WITH_PUGIXML)
find_package_wrapper(PugiXML)
-
- if(NOT PUGIXML_FOUND)
- set(WITH_PUGIXML OFF)
- message(STATUS "PugiXML not found, disabling WITH_PUGIXML")
- endif()
+ set_and_warn_library_found("PugiXML" PUGIXML_FOUND WITH_PUGIXML)
endif()
if(WITH_IMAGE_WEBP)
set(WEBP_ROOT_DIR ${LIBDIR}/webp)
find_package_wrapper(WebP)
- if(NOT WEBP_FOUND)
- set(WITH_IMAGE_WEBP OFF)
- message(WARNING "WebP not found, disabling WITH_IMAGE_WEBP")
- endif()
+ set_and_warn_library_found("WebP" WEBP_FOUND WITH_IMAGE_WEBP)
endif()
if(WITH_OPENIMAGEIO)
@@ -453,10 +439,7 @@ if(WITH_OPENIMAGEIO)
list(APPEND OPENIMAGEIO_LIBRARIES "${WEBP_LIBRARIES}")
endif()
- if(NOT OPENIMAGEIO_FOUND)
- set(WITH_OPENIMAGEIO OFF)
- message(STATUS "OpenImageIO not found, disabling WITH_CYCLES")
- endif()
+ set_and_warn_library_found("OPENIMAGEIO" OPENIMAGEIO_FOUND WITH_OPENIMAGEIO)
endif()
if(WITH_OPENCOLORIO)
@@ -466,10 +449,7 @@ if(WITH_OPENCOLORIO)
set(OPENCOLORIO_LIBPATH) # TODO, remove and reference the absolute path everywhere
set(OPENCOLORIO_DEFINITIONS)
- if(NOT OPENCOLORIO_FOUND)
- set(WITH_OPENCOLORIO OFF)
- message(STATUS "OpenColorIO not found")
- endif()
+ set_and_warn_library_found("OpenColorIO" OPENCOLORIO_FOUND WITH_OPENCOLORIO)
endif()
if(WITH_CYCLES AND WITH_CYCLES_EMBREE)
@@ -478,11 +458,7 @@ endif()
if(WITH_OPENIMAGEDENOISE)
find_package_wrapper(OpenImageDenoise)
-
- if(NOT OPENIMAGEDENOISE_FOUND)
- set(WITH_OPENIMAGEDENOISE OFF)
- message(STATUS "OpenImageDenoise not found")
- endif()
+ set_and_warn_library_found("OpenImageDenoise" OPENIMAGEDENOISE_FOUND WITH_OPENIMAGEDENOISE)
endif()
if(WITH_LLVM)
@@ -491,24 +467,19 @@ if(WITH_LLVM)
endif()
find_package_wrapper(LLVM)
- if(WITH_CLANG)
- find_package_wrapper(Clang)
- endif()
- # Symbol conflicts with same UTF library used by OpenCollada
- if(EXISTS ${LIBDIR})
- if(WITH_OPENCOLLADA AND (${LLVM_VERSION} VERSION_LESS "4.0.0"))
- list(REMOVE_ITEM OPENCOLLADA_LIBRARIES ${OPENCOLLADA_UTF_LIBRARY})
+ set_and_warn_library_found("LLVM" LLVM_FOUND WITH_LLVM)
+
+ if(LLVM_FOUND)
+ if(WITH_CLANG)
+ find_package_wrapper(Clang)
+ set_and_warn_library_found("Clang" CLANG_FOUND WITH_CLANG)
endif()
- endif()
- if(NOT LLVM_FOUND)
- set(WITH_LLVM OFF)
- set(WITH_CLANG OFF)
- message(STATUS "LLVM not found")
- else()
- if(NOT CLANG_FOUND)
- set(WITH_CLANG OFF)
- message(STATUS "Clang not found")
+ # Symbol conflicts with same UTF library used by OpenCollada
+ if(EXISTS ${LIBDIR})
+ if(WITH_OPENCOLLADA AND (${LLVM_VERSION} VERSION_LESS "4.0.0"))
+ list(REMOVE_ITEM OPENCOLLADA_LIBRARIES ${OPENCOLLADA_UTF_LIBRARY})
+ endif()
endif()
endif()
endif()
@@ -519,49 +490,43 @@ if(WITH_OPENSUBDIV)
set(OPENSUBDIV_LIBRARIES ${OPENSUBDIV_LIBRARIES})
set(OPENSUBDIV_LIBPATH) # TODO, remove and reference the absolute path everywhere
- if(NOT OPENSUBDIV_FOUND)
- set(WITH_OPENSUBDIV OFF)
- message(STATUS "OpenSubdiv not found")
- endif()
+ set_and_warn_library_found("OpenSubdiv" OPENSUBDIV_FOUND WITH_OPENSUBDIV)
endif()
if(WITH_TBB)
find_package_wrapper(TBB)
- if(NOT TBB_FOUND)
- message(WARNING "TBB not found, disabling WITH_TBB")
- set(WITH_TBB OFF)
- endif()
+ set_and_warn_library_found("TBB" TBB_FOUND WITH_TBB)
endif()
if(WITH_XR_OPENXR)
find_package(XR_OpenXR_SDK)
- if(NOT XR_OPENXR_SDK_FOUND)
- message(WARNING "OpenXR-SDK not found, disabling WITH_XR_OPENXR")
- set(WITH_XR_OPENXR OFF)
- endif()
+ set_and_warn_library_found("OpenXR-SDK" XR_OPENXR_SDK_FOUND WITH_XR_OPENXR)
endif()
if(WITH_GMP)
find_package_wrapper(GMP)
- if(NOT GMP_FOUND)
- message(WARNING "GMP not found, disabling WITH_GMP")
- set(WITH_GMP OFF)
- endif()
+ set_and_warn_library_found("GMP" GMP_FOUND WITH_GMP)
endif()
if(WITH_POTRACE)
find_package_wrapper(Potrace)
- if(NOT POTRACE_FOUND)
- message(WARNING "potrace not found, disabling WITH_POTRACE")
- set(WITH_POTRACE OFF)
- endif()
+ set_and_warn_library_found("Potrace" POTRACE_FOUND WITH_POTRACE)
endif()
if(WITH_HARU)
find_package_wrapper(Haru)
- if(NOT HARU_FOUND)
- message(WARNING "Haru not found, disabling WITH_HARU")
- set(WITH_HARU OFF)
+ set_and_warn_library_found("Haru" HARU_FOUND WITH_HARU)
+endif()
+
+if(WITH_CYCLES AND WITH_CYCLES_PATH_GUIDING)
+ find_package_wrapper(openpgl)
+ if(openpgl_FOUND)
+ get_target_property(OPENPGL_LIBRARIES openpgl::openpgl LOCATION)
+ get_target_property(OPENPGL_INCLUDE_DIR openpgl::openpgl INTERFACE_INCLUDE_DIRECTORIES)
+ message(STATUS "Found OpenPGL: ${OPENPGL_LIBRARIES}")
+ else()
+ set(WITH_CYCLES_PATH_GUIDING OFF)
+ message(STATUS "OpenPGL not found, disabling WITH_CYCLES_PATH_GUIDING")
endif()
endif()
@@ -637,37 +602,41 @@ endif()
# Jack is intended to use the system library.
if(WITH_JACK)
find_package_wrapper(Jack)
- if(NOT JACK_FOUND)
- set(WITH_JACK OFF)
- endif()
+ set_and_warn_library_found("JACK" JACK_FOUND WITH_JACK)
endif()
# Pulse is intended to use the system library.
if(WITH_PULSEAUDIO)
find_package_wrapper(Pulse)
- if(NOT PULSE_FOUND)
- set(WITH_PULSEAUDIO OFF)
- endif()
+ set_and_warn_library_found("PulseAudio" PULSE_FOUND WITH_PULSEAUDIO)
endif()
# Audio IO
if(WITH_SYSTEM_AUDASPACE)
find_package_wrapper(Audaspace)
- if(NOT AUDASPACE_FOUND OR NOT AUDASPACE_C_FOUND)
- message(FATAL_ERROR "Audaspace external library not found!")
- endif()
+ set(AUDASPACE_FOUND ${AUDASPACE_FOUND} AND ${AUDASPACE_C_FOUND})
+ set_and_warn_library_found("External Audaspace" AUDASPACE_FOUND WITH_SYSTEM_AUDASPACE)
endif()
if(WITH_GHOST_WAYLAND)
find_package(PkgConfig)
- pkg_check_modules(wayland-client wayland-client>=1.12)
- pkg_check_modules(wayland-egl wayland-egl)
- pkg_check_modules(wayland-scanner wayland-scanner)
pkg_check_modules(xkbcommon xkbcommon)
- pkg_check_modules(wayland-cursor wayland-cursor)
- pkg_check_modules(wayland-protocols wayland-protocols>=1.15)
- if(${wayland-protocols_FOUND})
+ # When dynamically linked WAYLAND is used and `${LIBDIR}/wayland` is present,
+ # there is no need to search for the libraries as they are not needed for building.
+ # Only the headers are needed which can reference the known paths.
+ if(EXISTS "${LIBDIR}/wayland" AND WITH_GHOST_WAYLAND_DYNLOAD)
+ set(_use_system_wayland OFF)
+ else()
+ set(_use_system_wayland ON)
+ endif()
+
+ if(_use_system_wayland)
+ pkg_check_modules(wayland-client wayland-client>=1.12)
+ pkg_check_modules(wayland-egl wayland-egl)
+ pkg_check_modules(wayland-scanner wayland-scanner)
+ pkg_check_modules(wayland-cursor wayland-cursor)
+ pkg_check_modules(wayland-protocols wayland-protocols>=1.15)
pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
else()
# CentOS 7 packages have too old a version, a newer version exist in the
@@ -681,32 +650,24 @@ if(WITH_GHOST_WAYLAND)
if(EXISTS ${WAYLAND_PROTOCOLS_DIR})
set(wayland-protocols_FOUND ON)
endif()
- endif()
- if (NOT ${wayland-client_FOUND})
- message(STATUS "wayland-client not found, disabling WITH_GHOST_WAYLAND")
- set(WITH_GHOST_WAYLAND OFF)
- endif()
- if (NOT ${wayland-egl_FOUND})
- message(STATUS "wayland-egl not found, disabling WITH_GHOST_WAYLAND")
- set(WITH_GHOST_WAYLAND OFF)
- endif()
- if (NOT ${wayland-scanner_FOUND})
- message(STATUS "wayland-scanner not found, disabling WITH_GHOST_WAYLAND")
- set(WITH_GHOST_WAYLAND OFF)
- endif()
- if (NOT ${wayland-cursor_FOUND})
- message(STATUS "wayland-cursor not found, disabling WITH_GHOST_WAYLAND")
- set(WITH_GHOST_WAYLAND OFF)
- endif()
- if (NOT ${wayland-protocols_FOUND})
- message(STATUS "wayland-protocols not found, disabling WITH_GHOST_WAYLAND")
- set(WITH_GHOST_WAYLAND OFF)
- endif()
- if (NOT ${xkbcommon_FOUND})
- message(STATUS "xkbcommon not found, disabling WITH_GHOST_WAYLAND")
- set(WITH_GHOST_WAYLAND OFF)
+ set(wayland-client_INCLUDE_DIRS "${LIBDIR}/wayland/include")
+ set(wayland-egl_INCLUDE_DIRS "${LIBDIR}/wayland/include")
+ set(wayland-cursor_INCLUDE_DIRS "${LIBDIR}/wayland/include")
+
+ set(wayland-client_FOUND ON)
+ set(wayland-egl_FOUND ON)
+ set(wayland-scanner_FOUND ON)
+ set(wayland-cursor_FOUND ON)
endif()
+ mark_as_advanced(WAYLAND_PROTOCOLS_DIR)
+
+ set_and_warn_library_found("wayland-client" wayland-client_FOUND WITH_GHOST_WAYLAND)
+ set_and_warn_library_found("wayland-egl" wayland-egl_FOUND WITH_GHOST_WAYLAND)
+ set_and_warn_library_found("wayland-scanner" wayland-scanner_FOUND WITH_GHOST_WAYLAND)
+ set_and_warn_library_found("wayland-cursor" wayland-cursor_FOUND WITH_GHOST_WAYLAND)
+ set_and_warn_library_found("wayland-protocols" wayland-protocols_FOUND WITH_GHOST_WAYLAND)
+ set_and_warn_library_found("xkbcommon" xkbcommon_FOUND WITH_GHOST_WAYLAND)
if(WITH_GHOST_WAYLAND)
if(WITH_GHOST_WAYLAND_DBUS)
@@ -714,39 +675,63 @@ if(WITH_GHOST_WAYLAND)
endif()
if(WITH_GHOST_WAYLAND_LIBDECOR)
- pkg_check_modules(libdecor REQUIRED libdecor-0>=0.1)
- endif()
-
- list(APPEND PLATFORM_LINKLIBS
- ${xkbcommon_LINK_LIBRARIES}
- )
-
- if(NOT WITH_GHOST_WAYLAND_DYNLOAD)
- list(APPEND PLATFORM_LINKLIBS
- ${wayland-client_LINK_LIBRARIES}
- ${wayland-egl_LINK_LIBRARIES}
- ${wayland-cursor_LINK_LIBRARIES}
- )
+ if(_use_system_wayland)
+ pkg_check_modules(libdecor REQUIRED libdecor-0>=0.1)
+ else()
+ set(libdecor_INCLUDE_DIRS "${LIBDIR}/wayland_libdecor/include/libdecor-0")
+ endif()
endif()
if(WITH_GHOST_WAYLAND_DBUS)
- list(APPEND PLATFORM_LINKLIBS
- ${dbus_LINK_LIBRARIES}
- )
add_definitions(-DWITH_GHOST_WAYLAND_DBUS)
endif()
if(WITH_GHOST_WAYLAND_LIBDECOR)
- if(NOT WITH_GHOST_WAYLAND_DYNLOAD)
- list(APPEND PLATFORM_LINKLIBS
- ${libdecor_LIBRARIES}
+ add_definitions(-DWITH_GHOST_WAYLAND_LIBDECOR)
+ endif()
+
+ if(EXISTS "${LIBDIR}/wayland/bin/wayland-scanner")
+ set(WAYLAND_SCANNER "${LIBDIR}/wayland/bin/wayland-scanner")
+ else()
+ pkg_get_variable(WAYLAND_SCANNER wayland-scanner wayland_scanner)
+ endif()
+ mark_as_advanced(WAYLAND_SCANNER)
+
+ # When using dynamic loading, headers generated
+ # from older versions of `wayland-scanner` aren't compatible.
+ if(WITH_GHOST_WAYLAND_DYNLOAD)
+ execute_process(
+ COMMAND ${WAYLAND_SCANNER} --version
+ # The version is written to the `stderr`.
+ ERROR_VARIABLE _wayland_scanner_out
+ ERROR_STRIP_TRAILING_WHITESPACE
+ )
+ if(NOT "${_wayland_scanner_out}" STREQUAL "")
+ string(
+ REGEX REPLACE
+ "^wayland-scanner[ \t]+([0-9]+)\.([0-9]+).*"
+ "\\1.\\2"
+ _wayland_scanner_ver
+ "${_wayland_scanner_out}"
)
+ if("${_wayland_scanner_ver}" VERSION_LESS "1.20")
+ message(
+ FATAL_ERROR
+ "Found ${WAYLAND_SCANNER} version \"${_wayland_scanner_ver}\", "
+ "the minimum version is 1.20!"
+ )
+ endif()
+ unset(_wayland_scanner_ver)
+ else()
+ message(WARNING "Unable to access the version from ${WAYLAND_SCANNER}, continuing.")
endif()
- add_definitions(-DWITH_GHOST_WAYLAND_LIBDECOR)
+ unset(_wayland_scanner_out)
endif()
+ # End wayland-scanner version check.
- pkg_get_variable(WAYLAND_SCANNER wayland-scanner wayland_scanner)
endif()
+
+ unset(_use_system_wayland)
endif()
if(WITH_GHOST_X11)
@@ -755,12 +740,8 @@ if(WITH_GHOST_X11)
find_path(X11_XF86keysym_INCLUDE_PATH X11/XF86keysym.h ${X11_INC_SEARCH_PATH})
mark_as_advanced(X11_XF86keysym_INCLUDE_PATH)
- list(APPEND PLATFORM_LINKLIBS ${X11_X11_LIB})
-
if(WITH_X11_XINPUT)
- if(X11_Xinput_LIB)
- list(APPEND PLATFORM_LINKLIBS ${X11_Xinput_LIB})
- else()
+ if(NOT X11_Xinput_LIB)
message(FATAL_ERROR "LibXi not found. Disable WITH_X11_XINPUT if you
want to build without tablet support")
endif()
@@ -770,18 +751,14 @@ if(WITH_GHOST_X11)
# XXX, why doesn't cmake make this available?
find_library(X11_Xxf86vmode_LIB Xxf86vm ${X11_LIB_SEARCH_PATH})
mark_as_advanced(X11_Xxf86vmode_LIB)
- if(X11_Xxf86vmode_LIB)
- list(APPEND PLATFORM_LINKLIBS ${X11_Xxf86vmode_LIB})
- else()
+ if(NOT X11_Xxf86vmode_LIB)
message(FATAL_ERROR "libXxf86vm not found. Disable WITH_X11_XF86VMODE if you
want to build without")
endif()
endif()
if(WITH_X11_XFIXES)
- if(X11_Xfixes_LIB)
- list(APPEND PLATFORM_LINKLIBS ${X11_Xfixes_LIB})
- else()
+ if(NOT X11_Xfixes_LIB)
message(FATAL_ERROR "libXfixes not found. Disable WITH_X11_XFIXES if you
want to build without")
endif()
@@ -790,9 +767,7 @@ if(WITH_GHOST_X11)
if(WITH_X11_ALPHA)
find_library(X11_Xrender_LIB Xrender ${X11_LIB_SEARCH_PATH})
mark_as_advanced(X11_Xrender_LIB)
- if(X11_Xrender_LIB)
- list(APPEND PLATFORM_LINKLIBS ${X11_Xrender_LIB})
- else()
+ if(NOT X11_Xrender_LIB)
message(FATAL_ERROR "libXrender not found. Disable WITH_X11_ALPHA if you
want to build without")
endif()
@@ -1032,7 +1007,7 @@ function(CONFIGURE_ATOMIC_LIB_IF_NEEDED)
endif()
endfunction()
-CONFIGURE_ATOMIC_LIB_IF_NEEDED()
+configure_atomic_lib_if_needed()
if(PLATFORM_BUNDLED_LIBRARIES)
# For the installed Python module and installed Blender executable, we set the
diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake
index 66ab0d4169a..47673794652 100644
--- a/build_files/cmake/platform/platform_win32.cmake
+++ b/build_files/cmake/platform/platform_win32.cmake
@@ -26,7 +26,7 @@ if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(OPENMP_FOUND ON)
set(OpenMP_C_FLAGS "/clang:-fopenmp")
set(OpenMP_CXX_FLAGS "/clang:-fopenmp")
- GET_FILENAME_COMPONENT(LLVMROOT "[HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\LLVM\\LLVM;]" ABSOLUTE CACHE)
+ get_filename_component(LLVMROOT "[HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\LLVM\\LLVM;]" ABSOLUTE CACHE)
set(CLANG_OPENMP_DLL "${LLVMROOT}/bin/libomp.dll")
set(CLANG_OPENMP_LIB "${LLVMROOT}/lib/libomp.lib")
if(NOT EXISTS "${CLANG_OPENMP_DLL}")
@@ -74,27 +74,6 @@ add_definitions(-DWIN32)
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
-# Minimum MSVC Version
-if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
- if(MSVC_VERSION EQUAL 1800)
- set(_min_ver "18.0.31101")
- if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${_min_ver})
- message(FATAL_ERROR
- "Visual Studio 2013 (Update 4, ${_min_ver}) required, "
- "found (${CMAKE_CXX_COMPILER_VERSION})")
- endif()
- endif()
- if(MSVC_VERSION EQUAL 1900)
- set(_min_ver "19.0.24210")
- if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${_min_ver})
- message(FATAL_ERROR
- "Visual Studio 2015 (Update 3, ${_min_ver}) required, "
- "found (${CMAKE_CXX_COMPILER_VERSION})")
- endif()
- endif()
-endif()
-unset(_min_ver)
-
# needed for some MSVC installations
# 4099 : PDB 'filename' was not found with 'object/library'
string(APPEND CMAKE_EXE_LINKER_FLAGS " /SAFESEH:NO /ignore:4099")
@@ -158,7 +137,7 @@ endif()
# C++ standards conformace (/permissive-) is available on msvc 15.5 (1912) and up
-if(MSVC_VERSION GREATER 1911 AND NOT MSVC_CLANG)
+if(NOT MSVC_CLANG)
string(APPEND CMAKE_CXX_FLAGS " /permissive-")
# Two-phase name lookup does not place nicely with OpenMP yet, so disable for now
string(APPEND CMAKE_CXX_FLAGS " /Zc:twoPhase-")
@@ -171,10 +150,11 @@ endif()
# Debug Symbol format
# sccache # MSVC_ASAN # format # why
-# ON # ON # Z7 # sccache will only play nice with Z7
-# ON # OFF # Z7 # sccache will only play nice with Z7
-# OFF # ON # Zi # Asan will not play nice with Edit and Continue
-# OFF # OFF # ZI # Neither asan nor sscache is enabled Edit and Continue is available
+# ON # ON # Z7 # sccache will only play nice with Z7.
+# ON # OFF # Z7 # sccache will only play nice with Z7.
+# OFF # ON # Zi # Asan will not play nice with Edit and Continue.
+# OFF # OFF # ZI # Neither ASAN nor sscache is enabled Edit and
+# Continue is available.
# Release Symbol format
# sccache # MSVC_ASAN # format # why
@@ -218,7 +198,7 @@ unset(SYMBOL_FORMAT)
unset(SYMBOL_FORMAT_RELEASE)
# JMC is available on msvc 15.8 (1915) and up
-if(MSVC_VERSION GREATER 1914 AND NOT MSVC_CLANG)
+if(NOT MSVC_CLANG)
string(APPEND CMAKE_CXX_FLAGS_DEBUG " /JMC")
endif()
@@ -251,9 +231,6 @@ if(NOT DEFINED LIBDIR)
elseif(MSVC_VERSION GREATER 1919)
message(STATUS "Visual Studio 2019 detected.")
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_BASE}_vc15)
- elseif(MSVC_VERSION GREATER 1909)
- message(STATUS "Visual Studio 2017 detected.")
- set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_BASE}_vc15)
endif()
else()
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
@@ -264,10 +241,8 @@ endif()
include(platform_old_libs_update)
-if(CMAKE_GENERATOR MATCHES "^Visual Studio.+" AND # Only supported in the VS IDE
- MSVC_VERSION GREATER_EQUAL 1924 AND # Supported for 16.4+
- WITH_CLANG_TIDY # And Clang Tidy needs to be on
- )
+# Only supported in the VS IDE & Clang Tidy needs to be on.
+if(CMAKE_GENERATOR MATCHES "^Visual Studio.+" AND WITH_CLANG_TIDY)
set(CMAKE_VS_GLOBALS
"RunCodeAnalysis=false"
"EnableMicrosoftCodeAnalysis=false"
@@ -278,8 +253,7 @@ endif()
# Mark libdir as system headers with a lower warn level, to resolve some warnings
# that we have very little control over
-if(MSVC_VERSION GREATER_EQUAL 1914 AND # Available with 15.7+
- NOT MSVC_CLANG AND # But not for clang
+if(NOT MSVC_CLANG AND # Available with MSVC 15.7+ but not for CLANG.
NOT WITH_WINDOWS_SCCACHE AND # And not when sccache is enabled
NOT VS_CLANG_TIDY) # Clang-tidy does not like these options
add_compile_options(/experimental:external /external:templates- /external:I "${LIBDIR}" /external:W0)
@@ -353,18 +327,10 @@ if(WITH_FFTW3)
endif()
if(WITH_IMAGE_WEBP)
- windows_find_package(WebP)
- if(NOT WEBP_FOUND)
- if(EXISTS ${LIBDIR}/webp)
- set(WEBP_INCLUDE_DIRS ${LIBDIR}/webp/include)
- set(WEBP_ROOT_DIR ${LIBDIR}/webp)
- set(WEBP_LIBRARIES ${LIBDIR}/webp/lib/webp.lib ${LIBDIR}/webp/lib/webpdemux.lib ${LIBDIR}/webp/lib/webpmux.lib)
- set(WEBP_FOUND ON)
- else()
- message(STATUS "WITH_IMAGE_WEBP is ON but WEBP libraries are not found, setting WITH_IMAGE_WEBP=OFF")
- set(WITH_IMAGE_WEBP OFF)
- endif()
- endif()
+ set(WEBP_INCLUDE_DIRS ${LIBDIR}/webp/include)
+ set(WEBP_ROOT_DIR ${LIBDIR}/webp)
+ set(WEBP_LIBRARIES ${LIBDIR}/webp/lib/webp.lib ${LIBDIR}/webp/lib/webpdemux.lib ${LIBDIR}/webp/lib/webpmux.lib)
+ set(WEBP_FOUND ON)
endif()
if(WITH_OPENCOLLADA)
@@ -385,7 +351,6 @@ if(WITH_OPENCOLLADA)
optimized ${OPENCOLLADA}/lib/opencollada/OpenCOLLADAStreamWriter.lib
optimized ${OPENCOLLADA}/lib/opencollada/MathMLSolver.lib
optimized ${OPENCOLLADA}/lib/opencollada/GeneratedSaxParser.lib
- optimized ${OPENCOLLADA}/lib/opencollada/xml.lib
optimized ${OPENCOLLADA}/lib/opencollada/buffer.lib
optimized ${OPENCOLLADA}/lib/opencollada/ftoa.lib
@@ -395,10 +360,14 @@ if(WITH_OPENCOLLADA)
debug ${OPENCOLLADA}/lib/opencollada/OpenCOLLADAStreamWriter_d.lib
debug ${OPENCOLLADA}/lib/opencollada/MathMLSolver_d.lib
debug ${OPENCOLLADA}/lib/opencollada/GeneratedSaxParser_d.lib
- debug ${OPENCOLLADA}/lib/opencollada/xml_d.lib
debug ${OPENCOLLADA}/lib/opencollada/buffer_d.lib
debug ${OPENCOLLADA}/lib/opencollada/ftoa_d.lib
)
+ if(EXISTS ${LIBDIR}/xml2/lib/libxml2s.lib) # 3.4 libraries
+ list(APPEND OPENCOLLADA_LIBRARIES ${LIBDIR}/xml2/lib/libxml2s.lib)
+ else()
+ list(APPEND OPENCOLLADA_LIBRARIES ${OPENCOLLADA}/lib/opencollada/xml.lib)
+ endif()
list(APPEND OPENCOLLADA_LIBRARIES ${OPENCOLLADA}/lib/opencollada/UTF.lib)
@@ -450,7 +419,7 @@ if(WITH_IMAGE_OPENEXR)
warn_hardcoded_paths(OpenEXR)
set(OPENEXR ${LIBDIR}/openexr)
set(OPENEXR_INCLUDE_DIR ${OPENEXR}/include)
- set(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCLUDE_DIR} ${IMATH_INCLUDE_DIRS} ${OPENEXR}/include/OpenEXR)
+ set(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCLUDE_DIR} ${IMATH_INCLUDE_DIRS} ${OPENEXR_INCLUDE_DIR}/OpenEXR)
set(OPENEXR_LIBPATH ${OPENEXR}/lib)
# Check if the 3.x library name exists
# if not assume this is a 2.x library folder
@@ -504,12 +473,16 @@ if(WITH_JACK)
endif()
if(WITH_PYTHON)
- set(PYTHON_VERSION 3.10) # CACHE STRING)
+ # Cache version for make_bpy_wheel.py to detect.
+ unset(PYTHON_VERSION CACHE)
+ set(PYTHON_VERSION "3.10" CACHE STRING "Python version")
string(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
set(PYTHON_LIBRARY ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/libs/python${_PYTHON_VERSION_NO_DOTS}.lib)
set(PYTHON_LIBRARY_DEBUG ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/libs/python${_PYTHON_VERSION_NO_DOTS}_d.lib)
+ set(PYTHON_EXECUTABLE ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/bin/python$<$<CONFIG:Debug>:_d>.exe)
+
set(PYTHON_INCLUDE_DIR ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/include)
set(PYTHON_NUMPY_INCLUDE_DIRS ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/lib/site-packages/numpy/core/include)
set(NUMPY_FOUND ON)
@@ -595,7 +568,8 @@ if(WITH_OPENIMAGEIO)
if(NOT OpenImageIO_FOUND)
set(OPENIMAGEIO ${LIBDIR}/OpenImageIO)
set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib)
- set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include)
+ set(OPENIMAGEIO_INCLUDE_DIR ${OPENIMAGEIO}/include)
+ set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO_INCLUDE_DIR})
set(OIIO_OPTIMIZED optimized ${OPENIMAGEIO_LIBPATH}/OpenImageIO.lib optimized ${OPENIMAGEIO_LIBPATH}/OpenImageIO_Util.lib)
set(OIIO_DEBUG debug ${OPENIMAGEIO_LIBPATH}/OpenImageIO_d.lib debug ${OPENIMAGEIO_LIBPATH}/OpenImageIO_Util_d.lib)
set(OPENIMAGEIO_LIBRARIES ${OIIO_OPTIMIZED} ${OIIO_DEBUG})
@@ -702,11 +676,11 @@ endif()
if(WITH_IMAGE_OPENJPEG)
set(OPENJPEG ${LIBDIR}/openjpeg)
- set(OPENJPEG_INCLUDE_DIRS ${OPENJPEG}/include/openjpeg-2.4)
+ set(OPENJPEG_INCLUDE_DIRS ${OPENJPEG}/include/openjpeg-2.5)
if(NOT EXISTS "${OPENJPEG_INCLUDE_DIRS}")
- # when not found, could be an older lib folder with openjpeg 2.3
- # to ease the transition period, fall back if 2.4 is not found.
- set(OPENJPEG_INCLUDE_DIRS ${OPENJPEG}/include/openjpeg-2.3)
+ # when not found, could be an older lib folder with openjpeg 2.4
+ # to ease the transition period, fall back if 2.5 is not found.
+ set(OPENJPEG_INCLUDE_DIRS ${OPENJPEG}/include/openjpeg-2.4)
endif()
set(OPENJPEG_LIBRARIES ${OPENJPEG}/lib/openjp2.lib)
endif()
@@ -723,12 +697,6 @@ if(WITH_OPENSUBDIV)
debug ${OPENSUBDIV_LIBPATH}/osdCPU_d.lib
debug ${OPENSUBDIV_LIBPATH}/osdGPU_d.lib
)
- set(OPENSUBDIV_HAS_OPENMP TRUE)
- set(OPENSUBDIV_HAS_TBB FALSE)
- set(OPENSUBDIV_HAS_OPENCL TRUE)
- set(OPENSUBDIV_HAS_CUDA FALSE)
- set(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK TRUE)
- set(OPENSUBDIV_HAS_GLSL_COMPUTE TRUE)
endif()
endif()
@@ -763,7 +731,7 @@ if(WITH_TBB)
endif()
# used in many places so include globally, like OpenGL
-blender_include_dirs_sys("${PTHREADS_INCLUDE_DIRS}")
+include_directories(SYSTEM "${PTHREADS_INCLUDE_DIRS}")
set(WINTAB_INC ${LIBDIR}/wintab/include)
@@ -796,9 +764,11 @@ if(WITH_CYCLES AND WITH_CYCLES_OSL)
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)
+ find_library(OSL_LIB_NOISE NAMES oslnoise PATHS ${CYCLES_OSL}/lib)
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)
+ find_library(OSL_LIB_NOISE_DEBUG NAMES oslnoise_d PATHS ${CYCLES_OSL}/lib)
list(APPEND OSL_LIBRARIES
optimized ${OSL_LIB_COMP}
optimized ${OSL_LIB_EXEC}
@@ -808,15 +778,22 @@ if(WITH_CYCLES AND WITH_CYCLES_OSL)
debug ${OSL_LIB_QUERY_DEBUG}
${PUGIXML_LIBRARIES}
)
+ if(OSL_LIB_NOISE)
+ list(APPEND OSL_LIBRARIES optimized ${OSL_LIB_NOISE})
+ endif()
+ if(OSL_LIB_NOISE_DEBUG)
+ list(APPEND OSL_LIBRARIES debug ${OSL_LIB_NOISE_DEBUG})
+ endif()
find_path(OSL_INCLUDE_DIR OSL/oslclosure.h PATHS ${CYCLES_OSL}/include)
find_program(OSL_COMPILER NAMES oslc PATHS ${CYCLES_OSL}/bin)
-
- if(OSL_INCLUDE_DIR AND OSL_LIBRARIES AND OSL_COMPILER)
- set(OSL_FOUND TRUE)
- else()
- message(STATUS "OSL not found")
- set(WITH_CYCLES_OSL OFF)
- endif()
+ file(STRINGS "${OSL_INCLUDE_DIR}/OSL/oslversion.h" OSL_LIBRARY_VERSION_MAJOR
+ REGEX "^[ \t]*#define[ \t]+OSL_LIBRARY_VERSION_MAJOR[ \t]+[0-9]+.*$")
+ file(STRINGS "${OSL_INCLUDE_DIR}/OSL/oslversion.h" OSL_LIBRARY_VERSION_MINOR
+ REGEX "^[ \t]*#define[ \t]+OSL_LIBRARY_VERSION_MINOR[ \t]+[0-9]+.*$")
+ string(REGEX REPLACE ".*#define[ \t]+OSL_LIBRARY_VERSION_MAJOR[ \t]+([.0-9]+).*"
+ "\\1" OSL_LIBRARY_VERSION_MAJOR ${OSL_LIBRARY_VERSION_MAJOR})
+ string(REGEX REPLACE ".*#define[ \t]+OSL_LIBRARY_VERSION_MINOR[ \t]+([.0-9]+).*"
+ "\\1" OSL_LIBRARY_VERSION_MINOR ${OSL_LIBRARY_VERSION_MINOR})
endif()
if(WITH_CYCLES AND WITH_CYCLES_EMBREE)
@@ -870,8 +847,8 @@ endif()
if(WINDOWS_PYTHON_DEBUG)
# Include the system scripts in the blender_python_system_scripts project.
- FILE(GLOB_RECURSE inFiles "${CMAKE_SOURCE_DIR}/release/scripts/*.*" )
- ADD_CUSTOM_TARGET(blender_python_system_scripts SOURCES ${inFiles})
+ file(GLOB_RECURSE inFiles "${CMAKE_SOURCE_DIR}/release/scripts/*.*" )
+ add_custom_target(blender_python_system_scripts SOURCES ${inFiles})
foreach(_source IN ITEMS ${inFiles})
get_filename_component(_source_path "${_source}" PATH)
string(REPLACE "${CMAKE_SOURCE_DIR}/release/scripts/" "" _source_path "${_source_path}")
@@ -891,8 +868,8 @@ if(WINDOWS_PYTHON_DEBUG)
endif()
file(TO_CMAKE_PATH ${USER_SCRIPTS_ROOT} USER_SCRIPTS_ROOT)
- FILE(GLOB_RECURSE inFiles "${USER_SCRIPTS_ROOT}/*.*" )
- ADD_CUSTOM_TARGET(blender_python_user_scripts SOURCES ${inFiles})
+ file(GLOB_RECURSE inFiles "${USER_SCRIPTS_ROOT}/*.*" )
+ add_custom_target(blender_python_user_scripts SOURCES ${inFiles})
foreach(_source IN ITEMS ${inFiles})
get_filename_component(_source_path "${_source}" PATH)
string(REPLACE "${USER_SCRIPTS_ROOT}" "" _source_path "${_source_path}")
@@ -916,21 +893,16 @@ if(WINDOWS_PYTHON_DEBUG)
endif()
if(WITH_XR_OPENXR)
- if(EXISTS ${LIBDIR}/xr_openxr_sdk)
- set(XR_OPENXR_SDK ${LIBDIR}/xr_openxr_sdk)
- set(XR_OPENXR_SDK_LIBPATH ${LIBDIR}/xr_openxr_sdk/lib)
- set(XR_OPENXR_SDK_INCLUDE_DIR ${XR_OPENXR_SDK}/include)
- # This is the old name of this library, it is checked to
- # support the transition between the old and new lib versions
- # this can be removed after the next lib update.
- if(EXISTS ${XR_OPENXR_SDK_LIBPATH}/openxr_loader_d.lib)
- set(XR_OPENXR_SDK_LIBRARIES optimized ${XR_OPENXR_SDK_LIBPATH}/openxr_loader.lib debug ${XR_OPENXR_SDK_LIBPATH}/openxr_loader_d.lib)
- else()
- set(XR_OPENXR_SDK_LIBRARIES optimized ${XR_OPENXR_SDK_LIBPATH}/openxr_loader.lib debug ${XR_OPENXR_SDK_LIBPATH}/openxr_loaderd.lib)
- endif()
+ set(XR_OPENXR_SDK ${LIBDIR}/xr_openxr_sdk)
+ set(XR_OPENXR_SDK_LIBPATH ${LIBDIR}/xr_openxr_sdk/lib)
+ set(XR_OPENXR_SDK_INCLUDE_DIR ${XR_OPENXR_SDK}/include)
+ # This is the old name of this library, it is checked to
+ # support the transition between the old and new lib versions
+ # this can be removed after the next lib update.
+ if(EXISTS ${XR_OPENXR_SDK_LIBPATH}/openxr_loader_d.lib)
+ set(XR_OPENXR_SDK_LIBRARIES optimized ${XR_OPENXR_SDK_LIBPATH}/openxr_loader.lib debug ${XR_OPENXR_SDK_LIBPATH}/openxr_loader_d.lib)
else()
- message(WARNING "OpenXR-SDK was not found, disabling WITH_XR_OPENXR")
- set(WITH_XR_OPENXR OFF)
+ set(XR_OPENXR_SDK_LIBRARIES optimized ${XR_OPENXR_SDK_LIBPATH}/openxr_loader.lib debug ${XR_OPENXR_SDK_LIBPATH}/openxr_loaderd.lib)
endif()
endif()
@@ -948,19 +920,45 @@ if(WITH_POTRACE)
endif()
if(WITH_HARU)
- if(EXISTS ${LIBDIR}/haru)
- set(HARU_FOUND ON)
- set(HARU_ROOT_DIR ${LIBDIR}/haru)
- set(HARU_INCLUDE_DIRS ${HARU_ROOT_DIR}/include)
- set(HARU_LIBRARIES ${HARU_ROOT_DIR}/lib/libhpdfs.lib)
+ set(HARU_FOUND ON)
+ set(HARU_ROOT_DIR ${LIBDIR}/haru)
+ set(HARU_INCLUDE_DIRS ${HARU_ROOT_DIR}/include)
+ set(HARU_LIBRARIES ${HARU_ROOT_DIR}/lib/libhpdfs.lib)
+endif()
+
+if(WITH_CYCLES AND WITH_CYCLES_PATH_GUIDING)
+ find_package(openpgl QUIET)
+ if(openpgl_FOUND)
+ get_target_property(OPENPGL_LIBRARIES_RELEASE openpgl::openpgl LOCATION_RELEASE)
+ get_target_property(OPENPGL_LIBRARIES_DEBUG openpgl::openpgl LOCATION_DEBUG)
+ set(OPENPGL_LIBRARIES optimized ${OPENPGL_LIBRARIES_RELEASE} debug ${OPENPGL_LIBRARIES_DEBUG})
+ get_target_property(OPENPGL_INCLUDE_DIR openpgl::openpgl INTERFACE_INCLUDE_DIRECTORIES)
else()
- message(WARNING "Haru was not found, disabling WITH_HARU")
- set(WITH_HARU OFF)
+ set(WITH_CYCLES_PATH_GUIDING OFF)
+ message(STATUS "OpenPGL not found, disabling WITH_CYCLES_PATH_GUIDING")
endif()
endif()
set(ZSTD_INCLUDE_DIRS ${LIBDIR}/zstd/include)
set(ZSTD_LIBRARIES ${LIBDIR}/zstd/lib/zstd_static.lib)
-set(LEVEL_ZERO_ROOT_DIR ${LIBDIR}/level_zero)
-set(SYCL_ROOT_DIR ${LIBDIR}/dpcpp)
+if(WITH_CYCLES AND WITH_CYCLES_DEVICE_ONEAPI)
+ set(LEVEL_ZERO_ROOT_DIR ${LIBDIR}/level_zero)
+ set(CYCLES_SYCL ${LIBDIR}/dpcpp CACHE PATH "Path to oneAPI DPC++ compiler")
+ if(EXISTS ${CYCLES_SYCL} AND NOT SYCL_ROOT_DIR)
+ set(SYCL_ROOT_DIR ${CYCLES_SYCL})
+ endif()
+ file(GLOB _sycl_runtime_libraries_glob
+ ${SYCL_ROOT_DIR}/bin/sycl.dll
+ ${SYCL_ROOT_DIR}/bin/sycl[0-9].dll
+ )
+ foreach(sycl_runtime_library IN LISTS _sycl_runtime_libraries_glob)
+ string(REPLACE ".dll" "$<$<CONFIG:Debug>:d>.dll" sycl_runtime_library ${sycl_runtime_library})
+ list(APPEND _sycl_runtime_libraries ${sycl_runtime_library})
+ endforeach()
+ unset(_sycl_runtime_libraries_glob)
+
+ list(APPEND _sycl_runtime_libraries ${SYCL_ROOT_DIR}/bin/pi_level_zero.dll)
+ list(APPEND PLATFORM_BUNDLED_LIBRARIES ${_sycl_runtime_libraries})
+ unset(_sycl_runtime_libraries)
+endif()
diff --git a/build_files/cmake/platform/platform_win32_bundle_crt.cmake b/build_files/cmake/platform/platform_win32_bundle_crt.cmake
index f5dd0c8c7bc..f197498d97b 100644
--- a/build_files/cmake/platform/platform_win32_bundle_crt.cmake
+++ b/build_files/cmake/platform/platform_win32_bundle_crt.cmake
@@ -3,20 +3,22 @@
# First generate the manifest for tests since it will not need the dependency on the CRT.
configure_file(${CMAKE_SOURCE_DIR}/release/windows/manifest/blender.exe.manifest.in ${CMAKE_CURRENT_BINARY_DIR}/tests.exe.manifest @ONLY)
-if(WITH_WINDOWS_BUNDLE_CRT)
- set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
- set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
- set(CMAKE_INSTALL_OPENMP_LIBRARIES ${WITH_OPENMP})
-
- # This sometimes can change when updates are installed and the compiler version
- # changes, so test if it exists and if not, give InstallRequiredSystemLibraries
- # another chance to figure out the path.
- if(MSVC_REDIST_DIR AND NOT EXISTS "${MSVC_REDIST_DIR}")
- unset(MSVC_REDIST_DIR CACHE)
- endif()
+# Always detect system libraries, since they are also used by oneAPI.
+# But don't always install them, only for WITH_WINDOWS_BUNDLE_CRT=ON.
+set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
+set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
+set(CMAKE_INSTALL_OPENMP_LIBRARIES ${WITH_OPENMP})
+
+# This sometimes can change when updates are installed and the compiler version
+# changes, so test if it exists and if not, give InstallRequiredSystemLibraries
+# another chance to figure out the path.
+if(MSVC_REDIST_DIR AND NOT EXISTS "${MSVC_REDIST_DIR}")
+ unset(MSVC_REDIST_DIR CACHE)
+endif()
- include(InstallRequiredSystemLibraries)
+include(InstallRequiredSystemLibraries)
+if(WITH_WINDOWS_BUNDLE_CRT)
# ucrtbase(d).dll cannot be in the manifest, due to the way windows 10 handles
# redirects for this dll, for details see T88813.
foreach(lib ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS})
diff --git a/build_files/config/pipeline_config.yaml b/build_files/config/pipeline_config.yaml
index 82cd009ea95..3359f89c41e 100644
--- a/build_files/config/pipeline_config.yaml
+++ b/build_files/config/pipeline_config.yaml
@@ -58,6 +58,8 @@ buildbot:
version: '5.2.21440'
optix:
version: '7.3.0'
+ ocloc:
+ version: '101.3430'
cmake:
default:
version: any
diff --git a/build_files/utils/make_bpy_wheel.py b/build_files/utils/make_bpy_wheel.py
new file mode 100755
index 00000000000..81d267c6e10
--- /dev/null
+++ b/build_files/utils/make_bpy_wheel.py
@@ -0,0 +1,225 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+"""
+Make Python wheel package (`*.whl`) file from Blender built with 'WITH_PYTHON_MODULE' enabled.
+
+Example
+=======
+
+If the "bpy" module was build on Linux using the command:
+
+ make bpy lite
+
+The command to package it as a wheel is:
+
+ ./build_files/utils/make_bpy_wheel.py ../build_linux_bpy_lite/bin --output-dir=./
+
+This will create a `*.whl` file in the current directory.
+"""
+
+import argparse
+import make_utils
+import os
+import re
+import platform
+import string
+import setuptools # type: ignore
+import sys
+
+from typing import (
+ Generator,
+ List,
+ Optional,
+ Sequence,
+ Tuple,
+)
+
+
+# ------------------------------------------------------------------------------
+# Generic Functions
+
+def find_dominating_file(
+ path: str,
+ search: Sequence[str],
+) -> str:
+ while True:
+ for d in search:
+ if os.path.exists(os.path.join(path, d)):
+ return os.path.join(path, d)
+ path_next = os.path.normpath(os.path.join(path, ".."))
+ if path == path_next:
+ break
+ path = path_next
+ return ""
+
+
+# ------------------------------------------------------------------------------
+# CMake Cache Access
+
+def cmake_cache_var_iter(filepath_cmake_cache: str) -> Generator[Tuple[str, str, str], None, None]:
+ import re
+ re_cache = re.compile(r"([A-Za-z0-9_\-]+)?:?([A-Za-z0-9_\-]+)?=(.*)$")
+ with open(filepath_cmake_cache, "r", encoding="utf-8") as cache_file:
+ for l in cache_file:
+ match = re_cache.match(l.strip())
+ if match is not None:
+ var, type_, val = match.groups()
+ yield (var, type_ or "", val)
+
+
+def cmake_cache_var(filepath_cmake_cache: str, var: str) -> Optional[str]:
+ for var_iter, type_iter, value_iter in cmake_cache_var_iter(filepath_cmake_cache):
+ if var == var_iter:
+ return value_iter
+ return None
+
+
+def cmake_cache_var_or_exit(filepath_cmake_cache: str, var: str) -> str:
+ value = cmake_cache_var(filepath_cmake_cache, var)
+ if value is None:
+ sys.stderr.write("Unable to find %r in %r, abort!\n" % (var, filepath_cmake_cache))
+ sys.exit(1)
+ return value
+
+
+# ------------------------------------------------------------------------------
+# Argument Parser
+
+def argparse_create() -> argparse.ArgumentParser:
+ parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawTextHelpFormatter)
+ parser.add_argument(
+ "install_dir",
+ metavar='INSTALL_DIR',
+ type=str,
+ help="The installation directory containing the \"bpy\" package.",
+ )
+ parser.add_argument(
+ "--build-dir",
+ metavar='BUILD_DIR',
+ default=None,
+ help="The build directory containing 'CMakeCache.txt' (search parent directories of INSTALL_DIR when omitted).",
+ required=False,
+ )
+ parser.add_argument(
+ "--output-dir",
+ metavar='OUTPUT_DIR',
+ default=None,
+ help="The destination directory for the '*.whl' file (use INSTALL_DIR when omitted).",
+ required=False,
+ )
+
+ return parser
+
+
+# ------------------------------------------------------------------------------
+# Main Function
+
+def main() -> None:
+
+ # Parse arguments.
+ args = argparse_create().parse_args()
+
+ install_dir = os.path.abspath(args.install_dir)
+ output_dir = os.path.abspath(args.output_dir) if args.output_dir else install_dir
+
+ if args.build_dir:
+ build_dir = os.path.abspath(args.build_dir)
+ filepath_cmake_cache = os.path.join(build_dir, "CMakeCache.txt")
+ del build_dir
+ if not os.path.exists(filepath_cmake_cache):
+ sys.stderr.write("File not found %r, abort!\n" % filepath_cmake_cache)
+ sys.exit(1)
+ else:
+ filepath_cmake_cache = find_dominating_file(install_dir, ("CMakeCache.txt",))
+ if not filepath_cmake_cache:
+ # Should never fail.
+ sys.stderr.write("Unable to find CMakeCache.txt in or above %r, abort!\n" % install_dir)
+ sys.exit(1)
+
+ # Get the major and minor Python version.
+ python_version = cmake_cache_var_or_exit(filepath_cmake_cache, "PYTHON_VERSION")
+ python_version_number = (
+ tuple(int("".join(c for c in digit if c in string.digits)) for digit in python_version.split(".")) +
+ # Support version without a minor version "3" (add zero).
+ tuple((0, 0, 0))
+ )
+ python_version_str = "%d.%d" % python_version_number[:2]
+
+ # Get Blender version.
+ blender_version_str = str(make_utils.parse_blender_version())
+
+ # Set platform tag following conventions.
+ if sys.platform == "darwin":
+ target = cmake_cache_var_or_exit(filepath_cmake_cache, "CMAKE_OSX_DEPLOYMENT_TARGET").split(".")
+ machine = cmake_cache_var_or_exit(filepath_cmake_cache, "CMAKE_OSX_ARCHITECTURES")
+ platform_tag = "macosx_%d_%d_%s" % (int(target[0]), int(target[1]), machine)
+ elif sys.platform == "win32":
+ platform_tag = "win_%s" % (platform.machine().lower())
+ elif sys.platform == "linux":
+ glibc = os.confstr("CS_GNU_LIBC_VERSION")
+ if glibc is None:
+ sys.stderr.write("Unable to find \"CS_GNU_LIBC_VERSION\", abort!\n")
+ sys.exit(1)
+ glibc = "%s_%s" % tuple(glibc.split()[1].split(".")[:2])
+ platform_tag = "manylinux_%s_%s" % (glibc, platform.machine().lower())
+ else:
+ sys.stderr.write("Unsupported platform: %s, abort!\n" % (sys.platform))
+ sys.exit(1)
+
+ os.chdir(install_dir)
+
+ # Include all files recursively.
+ def package_files(root_dir: str) -> List[str]:
+ paths = []
+ for path, dirs, files in os.walk(root_dir):
+ paths += [os.path.join("..", path, f) for f in files]
+ return paths
+
+ # Ensure this wheel is marked platform specific.
+ class BinaryDistribution(setuptools.dist.Distribution): # type: ignore
+ def has_ext_modules(self) -> bool:
+ return True
+
+ # Build wheel.
+ sys.argv = [sys.argv[0], "bdist_wheel"]
+
+ setuptools.setup(
+ name="bpy",
+ version=blender_version_str,
+ install_requires=["cython", "numpy", "requests", "zstandard"],
+ python_requires="==%d.%d.*" % (python_version_number[0], python_version_number[1]),
+ packages=["bpy"],
+ package_data={"": package_files("bpy")},
+ distclass=BinaryDistribution,
+ options={"bdist_wheel": {"plat_name": platform_tag}},
+
+ description="Blender as a Python module",
+ license="GPL-3.0",
+ author="Blender Foundation",
+ author_email="bf-committers@blender.org",
+ url="https://www.blender.org"
+ )
+
+ if not os.path.exists(output_dir):
+ os.makedirs(output_dir)
+
+ # Move wheel to output directory.
+ dist_dir = os.path.join(install_dir, "dist")
+ for f in os.listdir(dist_dir):
+ if f.endswith(".whl"):
+ blender_py = "cp%d%d" % (python_version_number[0], python_version_number[1])
+
+ # No apparent way to override this ABI version with setuptools, so rename.
+ sys_py = "cp%d%d" % (sys.version_info.major, sys.version_info.minor)
+ if hasattr(sys, "abiflags"):
+ sys_py_abi = sys_py + sys.abiflags
+ renamed_f = f.replace(sys_py_abi, blender_py).replace(sys_py, blender_py)
+ else:
+ renamed_f = f.replace(sys_py, blender_py)
+
+ os.rename(os.path.join(dist_dir, f), os.path.join(output_dir, renamed_f))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/build_files/utils/make_source_archive.py b/build_files/utils/make_source_archive.py
index befd6d84534..71fe7788b90 100755
--- a/build_files/utils/make_source_archive.py
+++ b/build_files/utils/make_source_archive.py
@@ -2,7 +2,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
import argparse
-import dataclasses
+import make_utils
import os
import re
import subprocess
@@ -19,6 +19,8 @@ from typing import Iterable, TextIO, Optional, Any, Union
SKIP_NAMES = {
".gitignore",
".gitmodules",
+ ".gitattributes",
+ ".git-blame-ignore-revs",
".arcconfig",
".svn",
}
@@ -50,7 +52,7 @@ def main() -> None:
print(f"Output dir: {curdir}")
- version = parse_blender_version(blender_srcdir)
+ version = make_utils.parse_blender_version()
tarball = tarball_path(curdir, version, cli_args)
manifest = manifest_path(tarball)
packages_dir = packages_path(curdir, cli_args)
@@ -62,53 +64,7 @@ def main() -> None:
print("Done!")
-@dataclasses.dataclass
-class BlenderVersion:
- version: int # 293 for 2.93.1
- patch: int # 1 for 2.93.1
- cycle: str # 'alpha', 'beta', 'release', maybe others.
-
- @property
- def is_release(self) -> bool:
- return self.cycle == "release"
-
- def __str__(self) -> str:
- """Convert to version string.
-
- >>> str(BlenderVersion(293, 1, "alpha"))
- '2.93.1-alpha'
- >>> str(BlenderVersion(327, 0, "release"))
- '3.27.0'
- """
- version_major = self.version // 100
- version_minor = self.version % 100
- as_string = f"{version_major}.{version_minor}.{self.patch}"
- if self.is_release:
- return as_string
- return f"{as_string}-{self.cycle}"
-
-
-def parse_blender_version(blender_srcdir: Path) -> BlenderVersion:
- version_path = blender_srcdir / "source/blender/blenkernel/BKE_blender_version.h"
-
- version_info = {}
- line_re = re.compile(r"^#define (BLENDER_VERSION[A-Z_]*)\s+([0-9a-z]+)$")
-
- with version_path.open(encoding="utf-8") as version_file:
- for line in version_file:
- match = line_re.match(line.strip())
- if not match:
- continue
- version_info[match.group(1)] = match.group(2)
-
- return BlenderVersion(
- int(version_info["BLENDER_VERSION"]),
- int(version_info["BLENDER_VERSION_PATCH"]),
- version_info["BLENDER_VERSION_CYCLE"],
- )
-
-
-def tarball_path(output_dir: Path, version: BlenderVersion, cli_args: Any) -> Path:
+def tarball_path(output_dir: Path, version: make_utils.BlenderVersion, cli_args: Any) -> Path:
extra = ""
if cli_args.include_packages:
extra = "-with-libraries"
@@ -148,7 +104,7 @@ def packages_path(current_directory: Path, cli_args: Any) -> Optional[Path]:
def create_manifest(
- version: BlenderVersion,
+ version: make_utils.BlenderVersion,
outpath: Path,
blender_srcdir: Path,
packages_dir: Optional[Path],
@@ -170,9 +126,9 @@ def main_files_to_manifest(blender_srcdir: Path, outfile: TextIO) -> None:
def submodules_to_manifest(
- blender_srcdir: Path, version: BlenderVersion, outfile: TextIO
+ blender_srcdir: Path, version: make_utils.BlenderVersion, outfile: TextIO
) -> None:
- skip_addon_contrib = version.is_release
+ skip_addon_contrib = version.is_release()
assert not blender_srcdir.is_absolute()
for line in git_command("-C", blender_srcdir, "submodule"):
@@ -200,7 +156,11 @@ def packages_to_manifest(outfile: TextIO, packages_dir: Path) -> None:
def create_tarball(
- version: BlenderVersion, tarball: Path, manifest: Path, blender_srcdir: Path, packages_dir: Optional[Path]
+ version: make_utils.BlenderVersion,
+ tarball: Path,
+ manifest: Path,
+ blender_srcdir: Path,
+ packages_dir: Optional[Path],
) -> None:
print(f'Creating archive: "{tarball}" ...', end="", flush=True)
command = ["tar"]
diff --git a/build_files/utils/make_update.py b/build_files/utils/make_update.py
index 254cccda301..a0b61b18e60 100755
--- a/build_files/utils/make_update.py
+++ b/build_files/utils/make_update.py
@@ -18,8 +18,13 @@ import sys
import make_utils
from make_utils import call, check_output
+from typing import (
+ List,
+ Optional,
+)
-def print_stage(text):
+
+def print_stage(text: str) -> None:
print("")
print(text)
print("")
@@ -27,7 +32,7 @@ def print_stage(text):
# Parse arguments
-def parse_arguments():
+def parse_arguments() -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument("--no-libraries", action="store_true")
parser.add_argument("--no-blender", action="store_true")
@@ -40,13 +45,13 @@ def parse_arguments():
return parser.parse_args()
-def get_blender_git_root():
+def get_blender_git_root() -> str:
return check_output([args.git_command, "rev-parse", "--show-toplevel"])
# Setup for precompiled libraries and tests from svn.
-def svn_update(args, release_version):
+def svn_update(args: argparse.Namespace, release_version: Optional[str]) -> None:
svn_non_interactive = [args.svn_command, '--non-interactive']
lib_dirpath = os.path.join(get_blender_git_root(), '..', 'lib')
@@ -99,42 +104,42 @@ def svn_update(args, release_version):
call(svn_non_interactive + ["checkout", svn_url_tests, lib_tests_dirpath])
# Update precompiled libraries and tests
- print_stage("Updating Precompiled Libraries and Tests")
-
- if os.path.isdir(lib_dirpath):
- for dirname in os.listdir(lib_dirpath):
- dirpath = os.path.join(lib_dirpath, dirname)
-
- if dirname == ".svn":
- # Cleanup must be run from svn root directory if it exists.
- if not make_utils.command_missing(args.svn_command):
- call(svn_non_interactive + ["cleanup", lib_dirpath])
- continue
- elif dirname.startswith("."):
- # Temporary paths such as ".mypy_cache" will report a warning, skip hidden directories.
- continue
-
- svn_dirpath = os.path.join(dirpath, ".svn")
- svn_root_dirpath = os.path.join(lib_dirpath, ".svn")
-
- if (
- os.path.isdir(dirpath) and
- (os.path.exists(svn_dirpath) or os.path.exists(svn_root_dirpath))
- ):
- if make_utils.command_missing(args.svn_command):
- sys.stderr.write("svn not found, can't update libraries\n")
- sys.exit(1)
-
- # Cleanup to continue with interrupted downloads.
- if os.path.exists(svn_dirpath):
- call(svn_non_interactive + ["cleanup", dirpath])
+
+ if not os.path.isdir(lib_dirpath):
+ print("Library path: %r, not found, skipping" % lib_dirpath)
+ else:
+ paths_local_and_remote = []
+ if os.path.exists(os.path.join(lib_dirpath, ".svn")):
+ print_stage("Updating Precompiled Libraries and Tests (one repository)")
+ paths_local_and_remote.append((lib_dirpath, svn_url))
+ else:
+ print_stage("Updating Precompiled Libraries and Tests (multiple repositories)")
+ # Separate paths checked out.
+ for dirname in os.listdir(lib_dirpath):
+ if dirname.startswith("."):
+ # Temporary paths such as ".mypy_cache" will report a warning, skip hidden directories.
+ continue
+
+ dirpath = os.path.join(lib_dirpath, dirname)
+ if not (os.path.isdir(dirpath) and os.path.exists(os.path.join(dirpath, ".svn"))):
+ continue
+
+ paths_local_and_remote.append((dirpath, svn_url + dirname))
+
+ if paths_local_and_remote:
+ if make_utils.command_missing(args.svn_command):
+ sys.stderr.write("svn not found, can't update libraries\n")
+ sys.exit(1)
+
+ for dirpath, svn_url_full in paths_local_and_remote:
+ call(svn_non_interactive + ["cleanup", dirpath])
# Switch to appropriate branch and update.
- call(svn_non_interactive + ["switch", svn_url + dirname, dirpath], exit_on_error=False)
+ call(svn_non_interactive + ["switch", svn_url_full, dirpath], exit_on_error=False)
call(svn_non_interactive + ["update", dirpath])
# Test if git repo can be updated.
-def git_update_skip(args, check_remote_exists=True):
+def git_update_skip(args: argparse.Namespace, check_remote_exists: bool = True) -> str:
if make_utils.command_missing(args.git_command):
sys.stderr.write("git not found, can't update code\n")
sys.exit(1)
@@ -166,13 +171,17 @@ def git_update_skip(args, check_remote_exists=True):
# Update blender repository.
-def blender_update(args):
+def blender_update(args: argparse.Namespace) -> None:
print_stage("Updating Blender Git Repository")
call([args.git_command, "pull", "--rebase"])
# Update submodules.
-def submodules_update(args, release_version, branch):
+def submodules_update(
+ args: argparse.Namespace,
+ release_version: Optional[str],
+ branch: Optional[str],
+) -> str:
print_stage("Updating Submodules")
if make_utils.command_missing(args.git_command):
sys.stderr.write("git not found, can't update code\n")
@@ -214,7 +223,8 @@ def submodules_update(args, release_version, branch):
elif make_utils.git_branch_exists(args.git_command, submodule_branch_fallback):
submodule_branch = submodule_branch_fallback
else:
- submodule_branch = None
+ # Skip.
+ submodule_branch = ""
# Switch to branch and pull.
if submodule_branch:
diff --git a/build_files/utils/make_utils.py b/build_files/utils/make_utils.py
index e4c676474b5..9b15eb363bc 100755
--- a/build_files/utils/make_utils.py
+++ b/build_files/utils/make_utils.py
@@ -9,9 +9,15 @@ import re
import shutil
import subprocess
import sys
+from pathlib import Path
+from typing import (
+ Sequence,
+ Optional,
+)
-def call(cmd, exit_on_error=True, silent=False):
+
+def call(cmd: Sequence[str], exit_on_error: bool = True, silent: bool = False) -> int:
if not silent:
print(" ".join(cmd))
@@ -29,7 +35,7 @@ def call(cmd, exit_on_error=True, silent=False):
return retcode
-def check_output(cmd, exit_on_error=True):
+def check_output(cmd: Sequence[str], exit_on_error: bool = True) -> str:
# Flush to ensure correct order output on Windows.
sys.stdout.flush()
sys.stderr.flush()
@@ -46,14 +52,14 @@ def check_output(cmd, exit_on_error=True):
return output.strip()
-def git_branch_exists(git_command, branch):
+def git_branch_exists(git_command: str, branch: str) -> bool:
return (
call([git_command, "rev-parse", "--verify", branch], exit_on_error=False, silent=True) == 0 or
call([git_command, "rev-parse", "--verify", "remotes/origin/" + branch], exit_on_error=False, silent=True) == 0
)
-def git_branch(git_command):
+def git_branch(git_command: str) -> str:
# Get current branch name.
try:
branch = subprocess.check_output([git_command, "rev-parse", "--abbrev-ref", "HEAD"])
@@ -64,7 +70,7 @@ def git_branch(git_command):
return branch.strip().decode('utf8')
-def git_tag(git_command):
+def git_tag(git_command: str) -> Optional[str]:
# Get current tag name.
try:
tag = subprocess.check_output([git_command, "describe", "--exact-match"], stderr=subprocess.STDOUT)
@@ -74,18 +80,19 @@ def git_tag(git_command):
return tag.strip().decode('utf8')
-def git_branch_release_version(branch, tag):
- release_version = re.search("^blender-v(.*)-release$", branch)
- if release_version:
- release_version = release_version.group(1)
+def git_branch_release_version(branch: str, tag: Optional[str]) -> Optional[str]:
+ re_match = re.search("^blender-v(.*)-release$", branch)
+ release_version = None
+ if re_match:
+ release_version = re_match.group(1)
elif tag:
- release_version = re.search(r"^v([0-9]*\.[0-9]*).*", tag)
- if release_version:
- release_version = release_version.group(1)
+ re_match = re.search(r"^v([0-9]*\.[0-9]*).*", tag)
+ if re_match:
+ release_version = re_match.group(1)
return release_version
-def svn_libraries_base_url(release_version, branch=None):
+def svn_libraries_base_url(release_version: Optional[str], branch: Optional[str] = None) -> str:
if release_version:
svn_branch = "tags/blender-" + release_version + "-release"
elif branch:
@@ -95,9 +102,58 @@ def svn_libraries_base_url(release_version, branch=None):
return "https://svn.blender.org/svnroot/bf-blender/" + svn_branch + "/lib/"
-def command_missing(command):
+def command_missing(command: str) -> bool:
# Support running with Python 2 for macOS
if sys.version_info >= (3, 0):
return shutil.which(command) is None
else:
return False
+
+
+class BlenderVersion:
+ def __init__(self, version: int, patch: int, cycle: str):
+ # 293 for 2.93.1
+ self.version = version
+ # 1 for 2.93.1
+ self.patch = patch
+ # 'alpha', 'beta', 'release', maybe others.
+ self.cycle = cycle
+
+ def is_release(self) -> bool:
+ return self.cycle == "release"
+
+ def __str__(self) -> str:
+ """Convert to version string.
+
+ >>> str(BlenderVersion(293, 1, "alpha"))
+ '2.93.1-alpha'
+ >>> str(BlenderVersion(327, 0, "release"))
+ '3.27.0'
+ """
+ version_major = self.version // 100
+ version_minor = self.version % 100
+ as_string = f"{version_major}.{version_minor}.{self.patch}"
+ if self.is_release():
+ return as_string
+ return f"{as_string}-{self.cycle}"
+
+
+def parse_blender_version() -> BlenderVersion:
+ blender_srcdir = Path(__file__).absolute().parent.parent.parent
+ version_path = blender_srcdir / "source/blender/blenkernel/BKE_blender_version.h"
+
+ version_info = {}
+ line_re = re.compile(r"^#define (BLENDER_VERSION[A-Z_]*)\s+([0-9a-z]+)$")
+
+ with version_path.open(encoding="utf-8") as version_file:
+ for line in version_file:
+ match = line_re.match(line.strip())
+ if not match:
+ continue
+ version_info[match.group(1)] = match.group(2)
+
+ return BlenderVersion(
+ int(version_info["BLENDER_VERSION"]),
+ int(version_info["BLENDER_VERSION_PATCH"]),
+ version_info["BLENDER_VERSION_CYCLE"],
+ )
diff --git a/build_files/windows/parse_arguments.cmd b/build_files/windows/parse_arguments.cmd
index eaf4a85f7ac..a2ff4c1ff95 100644
--- a/build_files/windows/parse_arguments.cmd
+++ b/build_files/windows/parse_arguments.cmd
@@ -80,9 +80,11 @@ if NOT "%1" == "" (
REM Non-Build Commands
) else if "%1" == "update" (
SET BUILD_UPDATE=1
+ SET BUILD_UPDATE_SVN=1
set BUILD_UPDATE_ARGS=
) else if "%1" == "code_update" (
SET BUILD_UPDATE=1
+ SET BUILD_UPDATE_SVN=0
set BUILD_UPDATE_ARGS="--no-libraries"
) else if "%1" == "ninja" (
SET BUILD_WITH_NINJA=1
diff --git a/build_files/windows/reset_variables.cmd b/build_files/windows/reset_variables.cmd
index 8ba7b4d3307..37c5d1034ea 100644
--- a/build_files/windows/reset_variables.cmd
+++ b/build_files/windows/reset_variables.cmd
@@ -34,3 +34,4 @@ set BUILD_WITH_SCCACHE=
set ICONS=
set ICONS_GEOM=
set DOC_PY=
+SET BUILD_UPDATE_SVN= \ No newline at end of file
diff --git a/build_files/windows/svn_update.cmd b/build_files/windows/svn_update.cmd
new file mode 100644
index 00000000000..f91f03f15b3
--- /dev/null
+++ b/build_files/windows/svn_update.cmd
@@ -0,0 +1,24 @@
+if "%BUILD_VS_YEAR%"=="2019" set BUILD_VS_LIBDIRPOST=vc15
+if "%BUILD_VS_YEAR%"=="2022" set BUILD_VS_LIBDIRPOST=vc15
+
+set BUILD_VS_SVNDIR=win64_%BUILD_VS_LIBDIRPOST%
+set BUILD_VS_LIBDIR="%BLENDER_DIR%..\lib\%BUILD_VS_SVNDIR%"
+
+cd %BUILD_VS_LIBDIR%
+:RETRY
+"%SVN%" update
+if errorlevel 1 (
+ set /p LibRetry= "Error during update, retry? y/n"
+ if /I "!LibRetry!"=="Y" (
+ "%SVN%" cleanup
+ goto RETRY
+ )
+ echo.
+ echo Error: Download of external libraries failed.
+ echo This is needed for building, please manually run 'svn cleanup' and 'svn update' in
+ echo %BUILD_VS_LIBDIR% , until this is resolved you CANNOT make a successful blender build
+ echo.
+ exit /b 1
+)
+
+cd %BLENDER_DIR% \ No newline at end of file
diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile
index 18c16a60993..e1d8ac39bcf 100644
--- a/doc/doxygen/Doxyfile
+++ b/doc/doxygen/Doxyfile
@@ -38,7 +38,7 @@ PROJECT_NAME = Blender
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = V3.4
+PROJECT_NUMBER = V3.5
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/doc/manpage/blender.1.py b/doc/manpage/blender.1.py
index 7d35dc0abb1..49dae35e0c5 100755
--- a/doc/manpage/blender.1.py
+++ b/doc/manpage/blender.1.py
@@ -139,7 +139,7 @@ https://www.blender.org''')
l = lines.pop(0)
if l:
- assert(l.startswith('\t'))
+ assert l.startswith('\t')
l = l[1:] # Remove first white-space (tab).
fh.write('%s\n' % man_format(l))
diff --git a/doc/python_api/examples/gpu.1.py b/doc/python_api/examples/gpu.1.py
index a014e69c2d2..c44e79a77aa 100644
--- a/doc/python_api/examples/gpu.1.py
+++ b/doc/python_api/examples/gpu.1.py
@@ -134,7 +134,6 @@ batch = batch_for_shader(shader, 'LINES', {"pos": coords})
def draw():
- shader.bind()
shader.uniform_float("color", (1, 1, 0, 1))
batch.draw(shader)
diff --git a/doc/python_api/examples/gpu.10.py b/doc/python_api/examples/gpu.10.py
index b47ff732e2b..6c438bd396e 100644
--- a/doc/python_api/examples/gpu.10.py
+++ b/doc/python_api/examples/gpu.10.py
@@ -58,7 +58,6 @@ batch = batch_for_shader(
def draw():
- shader.bind()
matrix = bpy.context.region_data.perspective_matrix
shader.uniform_float("u_ViewProjectionMatrix", matrix)
shader.uniform_float("u_Scale", 10)
diff --git a/doc/python_api/examples/gpu.2.py b/doc/python_api/examples/gpu.2.py
index 2a46e833752..e308ce7f78e 100644
--- a/doc/python_api/examples/gpu.2.py
+++ b/doc/python_api/examples/gpu.2.py
@@ -41,7 +41,6 @@ batch = batch_for_shader(shader, 'TRIS', {"position": coords})
def draw():
- shader.bind()
matrix = bpy.context.region_data.perspective_matrix
shader.uniform_float("viewProjectionMatrix", matrix)
shader.uniform_float("brightness", 0.5)
diff --git a/doc/python_api/examples/gpu.3.py b/doc/python_api/examples/gpu.3.py
index 0c86b52bcf5..9e8f762d9c9 100644
--- a/doc/python_api/examples/gpu.3.py
+++ b/doc/python_api/examples/gpu.3.py
@@ -22,7 +22,6 @@ batch = batch_for_shader(shader, 'LINES', {"pos": coords}, indices=indices)
def draw():
- shader.bind()
shader.uniform_float("color", (1, 0, 0, 1))
batch.draw(shader)
diff --git a/doc/python_api/examples/gpu.5.py b/doc/python_api/examples/gpu.5.py
index 2edde46a364..983372706c1 100644
--- a/doc/python_api/examples/gpu.5.py
+++ b/doc/python_api/examples/gpu.5.py
@@ -18,7 +18,6 @@ batch = batch_for_shader(shader, 'TRIS', {"pos": vertices}, indices=indices)
def draw():
- shader.bind()
shader.uniform_float("color", (0, 0.5, 0.5, 1.0))
batch.draw(shader)
diff --git a/doc/python_api/examples/gpu.6.py b/doc/python_api/examples/gpu.6.py
index 5576b2d0bfe..96decf571ee 100644
--- a/doc/python_api/examples/gpu.6.py
+++ b/doc/python_api/examples/gpu.6.py
@@ -56,7 +56,6 @@ batch = batch_for_shader(
def draw():
- shader.bind()
shader.uniform_sampler("image", texture)
batch.draw(shader)
diff --git a/doc/python_api/examples/gpu.7.py b/doc/python_api/examples/gpu.7.py
index e3bfbd14e34..5d25b42728d 100644
--- a/doc/python_api/examples/gpu.7.py
+++ b/doc/python_api/examples/gpu.7.py
@@ -76,7 +76,6 @@ batch = batch_for_shader(
def draw():
- shader.bind()
shader.uniform_float("modelMatrix", Matrix.Translation((1, 2, 3)) @ Matrix.Scale(3, 4))
shader.uniform_float("viewProjectionMatrix", bpy.context.region_data.perspective_matrix)
shader.uniform_sampler("image", offscreen.texture_color)
diff --git a/doc/python_api/requirements.txt b/doc/python_api/requirements.txt
index f93947c9d2d..4b31c3f1344 100644
--- a/doc/python_api/requirements.txt
+++ b/doc/python_api/requirements.txt
@@ -1,13 +1,13 @@
-sphinx==5.0.1
+sphinx==5.3.0
# Sphinx dependencies that are important
Jinja2==3.1.2
-Pygments==2.12.0
+Pygments==2.13.0
docutils==0.17.1
snowballstemmer==2.2.0
-babel==2.10.1
-requests==2.27.1
+babel==2.11.0
+requests==2.28.1
# Only needed to match the theme used for the official documentation.
# Without this theme, the default theme will be used.
-sphinx_rtd_theme==1.0.0
+sphinx_rtd_theme==1.1.0
diff --git a/doc/python_api/rst/change_log.rst b/doc/python_api/rst/change_log.rst
index 957bf8605e3..ef289cd0762 100644
--- a/doc/python_api/rst/change_log.rst
+++ b/doc/python_api/rst/change_log.rst
@@ -1,7 +1,9 @@
:tocdepth: 2
-Blender API Change Log
-**********************
+Change Log
+**********
+
+Changes in Blender's Python API between releases.
.. note, this document is auto generated by sphinx_changelog_gen.py
diff --git a/doc/python_api/rst/info_advanced.rst b/doc/python_api/rst/info_advanced.rst
new file mode 100644
index 00000000000..cae1e711722
--- /dev/null
+++ b/doc/python_api/rst/info_advanced.rst
@@ -0,0 +1,15 @@
+.. _info_advanced-index:
+
+********
+Advanced
+********
+
+This chapter covers advanced use (topics which may not be required for typical usage).
+
+.. NOTE(@campbellbarton): Blender-as-a-Python-module is too obscure a topic to list directly on the main-page,
+ so opt for an "Advanced" page which can be expanded on as needed.
+
+.. toctree::
+ :maxdepth: 1
+
+ info_advanced_blender_as_bpy.rst
diff --git a/doc/python_api/rst/info_advanced_blender_as_bpy.rst b/doc/python_api/rst/info_advanced_blender_as_bpy.rst
new file mode 100644
index 00000000000..9d2861ff627
--- /dev/null
+++ b/doc/python_api/rst/info_advanced_blender_as_bpy.rst
@@ -0,0 +1,126 @@
+
+**************************
+Blender as a Python Module
+**************************
+
+Blender supports being built as a Python module,
+allowing ``import bpy`` to be added to any Python script, providing access to Blender's features.
+
+.. note::
+
+ At time of writing official builds are not available,
+ using this requires compiling Blender yourself see
+ `build instructions <https://wiki.blender.org/w/index.php?title=Building_Blender/Other/BlenderAsPyModule>`__.
+
+
+Use Cases
+=========
+
+Python developers may wish to integrate Blender scripts which don't center around Blender.
+
+Possible uses include:
+
+- Visualizing data by rendering images and animations.
+- Image processing using Blender's compositor.
+- Video editing (using Blender's sequencer).
+- 3D file conversion.
+- Development, accessing ``bpy`` from Python IDE's and debugging tools for example.
+- Automation.
+
+
+Usage
+=====
+
+For the most part using Blender as a Python module is equivalent to running a script in background-mode
+(passing the command-line arguments ``--background`` or ``-b``),
+however there are some differences to be aware of.
+
+.. Sorted alphabetically as there isn't an especially a logical order to show them.
+
+Blender's Executable Access
+ The attribute :class:`bpy.app.binary_path` defaults to an empty string.
+
+ If you wish to point this to the location of a known executable you may set the value.
+
+ This example searches for the binary, setting it when found:
+
+ .. code-block:: python
+
+ import bpy
+ import shutil
+
+ blender_bin = shutil.which("blender")
+ if blender_bin:
+ print("Found:", blender_bin)
+ bpy.app.binary_path = blender_bin
+ else:
+ print("Unable to find blender!")
+
+Blender's Internal Modules
+ There are many modules included with Blender such as :mod:`gpu` and :mod:`mathuils`.
+ It's important that these are imported after ``bpy`` or they will not be found.
+
+Command Line Arguments Unsupported
+ Functionality controlled by command line arguments (shown by calling ``blender --help`` aren't accessible).
+
+ Typically this isn't such a limitation although there are some command line arguments that don't have
+ equivalents in Blender's Python API (``--threads`` and ``--log`` for example).
+
+ .. note::
+
+ Access to these settings may be added in the future as needed.
+
+Resource Sharing (GPU)
+ It's possible other Python modules make use of the GPU in a way that prevents Blender/Cycles from accessing the GPU.
+
+Signal Handlers
+ Blender's typical signal handlers are not initialized, so there is no special handling for ``Control-C``
+ to cancel a render and a crash log is not written in the event of a crash.
+
+Startup and Preferences
+ When the ``bpy`` module loads it contains the default startup scene
+ (instead of an "empty" blend-file as you might expect), so there is a default cube, camera and light.
+
+ If you wish to start from an empty file use: ``bpy.ops.wm.read_factory_settings(use_empty=True)``.
+
+ The users startup and preferences are ignored to prevent your local configuration from impacting scripts behavior.
+ The Python module behaves as if ``--factory-startup`` was passed as a command line argument.
+
+ The users preferences and startup can be loaded using operators:
+
+ .. code-block:: python
+
+ import bpy
+
+ bpy.ops.wm.read_userpref()
+ bpy.ops.wm.read_homefile()
+
+
+Limitations
+===========
+
+Most constraints of Blender as an application still apply:
+
+Reloading Unsupported
+ Reloading the ``bpy`` module via ``importlib.reload`` will raise an exception
+ instead of reloading and resetting the module.
+
+ Instead, the operator ``bpy.ops.wm.read_factory_settings()`` can be used to reset the internal state.
+
+Single Blend File Restriction
+ Only a single ``.blend`` file can be edited at a time.
+
+ .. hint::
+
+ As with the application it's possible to start multiple instances,
+ each with their own ``bpy`` and therefor Blender state.
+ Python provides the ``multiprocessing`` module to make communicating with sub-processes more convenient.
+
+ In some cases the library API may be an alternative to starting separate processes,
+ although this API operates on reading and writing ID data-blocks and isn't
+ a complete substitute for loading ``.blend`` files, see:
+
+ - :meth:`bpy.types.BlendDataLibraries.load`
+ - :meth:`bpy.types.BlendDataLibraries.write`
+ - :meth:`bpy.types.BlendData.temp_data`
+ supports a temporary data-context to avoid manipulating the current ``.blend`` file.
diff --git a/doc/python_api/rst/info_api_reference.rst b/doc/python_api/rst/info_api_reference.rst
index 70d201016f0..3deb96dbb52 100644
--- a/doc/python_api/rst/info_api_reference.rst
+++ b/doc/python_api/rst/info_api_reference.rst
@@ -1,6 +1,6 @@
*******************
-Reference API Usage
+API Reference Usage
*******************
Blender has many interlinking data types which have an auto-generated reference API which often has the information
diff --git a/doc/python_api/rst/info_overview.rst b/doc/python_api/rst/info_overview.rst
index 50928963f60..638420a53ae 100644
--- a/doc/python_api/rst/info_overview.rst
+++ b/doc/python_api/rst/info_overview.rst
@@ -1,8 +1,8 @@
.. _info_overview:
-*******************
-Python API Overview
-*******************
+************
+API Overview
+************
The purpose of this document is to explain how Python and Blender fit together,
covering some of the functionality that may not be obvious from reading the API references
diff --git a/doc/python_api/rst_from_bmesh_opdefines.py b/doc/python_api/rst_from_bmesh_opdefines.py
index 3d8ff1e6248..0614538964d 100644
--- a/doc/python_api/rst_from_bmesh_opdefines.py
+++ b/doc/python_api/rst_from_bmesh_opdefines.py
@@ -241,9 +241,9 @@ def main():
comment_washed = []
comment = [] if comment is None else comment
for i, l in enumerate(comment):
- assert((l.strip() == "") or
- (l in {"/*", " *"}) or
- (l.startswith(("/* ", " * "))))
+ assert ((l.strip() == "") or
+ (l in {"/*", " *"}) or
+ (l.startswith(("/* ", " * "))))
l = l[3:]
if i == 0 and not l.strip():
@@ -270,7 +270,7 @@ def main():
tp_sub = None
else:
print(arg)
- assert(0)
+ assert 0
tp_str = ""
@@ -315,7 +315,7 @@ def main():
tp_str += " or any sequence of 3 floats"
elif tp == BMO_OP_SLOT_PTR:
tp_str = "dict"
- assert(tp_sub is not None)
+ assert tp_sub is not None
if tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_BMESH:
tp_str = ":class:`bmesh.types.BMesh`"
elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_SCENE:
@@ -330,10 +330,10 @@ def main():
tp_str = ":class:`bpy.types.bpy_struct`"
else:
print("Can't find", vars_dict_reverse[tp_sub])
- assert(0)
+ assert 0
elif tp == BMO_OP_SLOT_ELEMENT_BUF:
- assert(tp_sub is not None)
+ assert tp_sub is not None
ls = []
if tp_sub & BM_VERT:
@@ -342,7 +342,7 @@ def main():
ls.append(":class:`bmesh.types.BMEdge`")
if tp_sub & BM_FACE:
ls.append(":class:`bmesh.types.BMFace`")
- assert(ls) # must be at least one
+ assert ls # Must be at least one.
if tp_sub & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE:
tp_str = "/".join(ls)
@@ -367,10 +367,10 @@ def main():
tp_str += "unknown internal data, not compatible with python"
else:
print("Can't find", vars_dict_reverse[tp_sub])
- assert(0)
+ assert 0
else:
print("Can't find", vars_dict_reverse[tp])
- assert(0)
+ assert 0
args_wash.append((name, tp_str, comment))
return args_wash
@@ -394,7 +394,7 @@ def main():
fw(" :return:\n\n")
for (name, tp, comment) in args_out_wash:
- assert(name.endswith(".out"))
+ assert name.endswith(".out")
name = name[:-4]
fw(" - ``%s``: %s\n\n" % (name, comment))
fw(" **type** %s\n" % tp)
diff --git a/doc/python_api/sphinx_changelog_gen.py b/doc/python_api/sphinx_changelog_gen.py
index 4c9f7232a74..fb93c301280 100644
--- a/doc/python_api/sphinx_changelog_gen.py
+++ b/doc/python_api/sphinx_changelog_gen.py
@@ -101,7 +101,7 @@ def api_dump(args):
version, version_key = api_version()
if version is None:
- raise(ValueError("API dumps can only be generated from within Blender."))
+ raise ValueError("API dumps can only be generated from within Blender.")
dump = {}
dump_module = dump["bpy.types"] = {}
@@ -250,7 +250,7 @@ def api_changelog(args):
version, version_key = api_version()
if version is None and (filepath_in_from is None or filepath_in_to is None):
- raise(ValueError("API dumps files must be given when ran outside of Blender."))
+ raise ValueError("API dumps files must be given when ran outside of Blender.")
with open(indexpath, 'r', encoding='utf-8') as file_handle:
index = json.load(file_handle)
@@ -258,17 +258,21 @@ def api_changelog(args):
if filepath_in_to is None:
filepath_in_to = index.get(version_key, None)
if filepath_in_to is None:
- raise(ValueError("Cannot find API dump file for Blender version " + str(version) + " in index file."))
+ raise ValueError("Cannot find API dump file for Blender version " + str(version) + " in index file.")
print("Found to file: %r" % filepath_in_to)
if filepath_in_from is None:
version_from, version_from_key = api_version_previous_in_index(index, version)
if version_from is None:
- raise(ValueError("No previous version of Blender could be found in the index."))
+ raise ValueError("No previous version of Blender could be found in the index.")
filepath_in_from = index.get(version_from_key, None)
if filepath_in_from is None:
- raise(ValueError("Cannot find API dump file for previous Blender version " + str(version_from) + " in index file."))
+ raise ValueError(
+ "Cannot find API dump file for previous Blender version " +
+ str(version_from) +
+ " in index file."
+ )
print("Found from file: %r" % filepath_in_from)
@@ -277,7 +281,7 @@ def api_changelog(args):
with open(os.path.join(rootpath, filepath_in_to), 'r', encoding='utf-8') as file_handle:
dump_version, dict_to = json.load(file_handle)
- assert(tuple(dump_version) == version)
+ assert tuple(dump_version) == version
api_changes = []
@@ -345,8 +349,10 @@ def api_changelog(args):
fw(""
":tocdepth: 2\n"
"\n"
- "Blender API Change Log\n"
- "**********************\n"
+ "Change Log\n"
+ "**********\n"
+ "\n"
+ "Changes in Blender's Python API between releases.\n"
"\n"
".. note, this document is auto generated by sphinx_changelog_gen.py\n"
"\n"
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index 240bec6fd30..f51ab8d6591 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -387,23 +387,35 @@ EXAMPLE_SET_USED = set()
# RST files directory.
RST_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "rst"))
-# extra info, not api reference docs
-# stored in ./rst/info_*
+# Extra info, not api reference docs stored in `./rst/info_*`.
+# Pairs of (file, description), the title makes from the RST files are displayed before the description.
INFO_DOCS = (
("info_quickstart.rst",
- "Quickstart: New to Blender or scripting and want to get your feet wet?"),
+ "New to Blender or scripting and want to get your feet wet?"),
("info_overview.rst",
- "API Overview: A more complete explanation of Python integration"),
+ "A more complete explanation of Python integration."),
("info_api_reference.rst",
- "API Reference Usage: examples of how to use the API reference docs"),
+ "Examples of how to use the API reference docs."),
("info_best_practice.rst",
- "Best Practice: Conventions to follow for writing good scripts"),
+ "Conventions to follow for writing good scripts."),
("info_tips_and_tricks.rst",
- "Tips and Tricks: Hints to help you while writing scripts for Blender"),
+ "Hints to help you while writing scripts for Blender."),
("info_gotcha.rst",
- "Gotcha's: Some of the problems you may encounter when writing scripts"),
- ("change_log.rst", "Change Log: List of changes since last Blender release"),
+ "Some of the problems you may encounter when writing scripts."),
+ ("info_advanced.rst",
+ "Topics which may not be required for typical usage."),
+ ("change_log.rst",
+ "List of changes since last Blender release"),
)
+# Referenced indirectly.
+INFO_DOCS_OTHER = (
+ # Included by: `info_advanced.rst`.
+ "info_advanced_blender_as_bpy.rst",
+)
+
+# Hide the actual TOC, use a separate list that links to the items.
+# This is done so a short description can be included with each link.
+USE_INFO_DOCS_FANCY_INDEX = True
# only support for properties atm.
RNA_BLACKLIST = {
@@ -1447,15 +1459,15 @@ def pyrna2sphinx(basepath):
# If the link has been written, no need to inline the enum items.
enum_text = "" if enum_descr_override else pyrna_enum2sphinx(prop)
if prop.name or prop.description or enum_text:
- fw(ident + ":%s%s:\n\n" % (id_name, identifier))
+ fw(ident + ":%s%s: " % (id_name, identifier))
if prop.name or prop.description:
- fw(indent(", ".join(val for val in (prop.name, prop.description) if val), ident + " ") + "\n\n")
+ fw(", ".join(val for val in (prop.name, prop.description.replace("\n", "")) if val) + "\n")
# Special exception, can't use generic code here for enums.
if enum_text:
- write_indented_lines(ident + " ", fw, enum_text)
fw("\n")
+ write_indented_lines(ident + " ", fw, enum_text)
del enum_text
# end enum exception
@@ -1470,7 +1482,7 @@ def pyrna2sphinx(basepath):
struct_module_name = struct.module_name
if USE_ONLY_BUILTIN_RNA_TYPES:
- assert(struct_module_name == "bpy.types")
+ assert struct_module_name == "bpy.types"
filepath = os.path.join(basepath, "%s.%s.rst" % (struct_module_name, struct.identifier))
file = open(filepath, "w", encoding="utf-8")
fw = file.write
@@ -1904,7 +1916,7 @@ except ModuleNotFoundError:
# fw(" 'collapse_navigation': True,\n")
fw(" 'sticky_navigation': False,\n")
fw(" 'navigation_depth': 1,\n")
- # fw(" 'includehidden': True,\n")
+ fw(" 'includehidden': False,\n")
# fw(" 'titles_only': False\n")
fw(" }\n\n")
@@ -1976,12 +1988,21 @@ def write_rst_index(basepath):
if not EXCLUDE_INFO_DOCS:
fw(".. toctree::\n")
+ if USE_INFO_DOCS_FANCY_INDEX:
+ fw(" :hidden:\n")
fw(" :maxdepth: 1\n")
fw(" :caption: Documentation\n\n")
for info, info_desc in INFO_DOCS:
- fw(" %s <%s>\n" % (info_desc, info))
+ fw(" %s\n" % info)
fw("\n")
+ if USE_INFO_DOCS_FANCY_INDEX:
+ # Show a fake TOC, allowing for an extra description to be shown as well as the title.
+ fw(title_string("Documentation", "="))
+ for info, info_desc in INFO_DOCS:
+ fw("- :doc:`%s`: %s\n" % (info.removesuffix(".rst"), info_desc))
+ fw("\n")
+
fw(".. toctree::\n")
fw(" :maxdepth: 1\n")
fw(" :caption: Application Modules\n\n")
@@ -2314,6 +2335,8 @@ def copy_handwritten_rsts(basepath):
if not EXCLUDE_INFO_DOCS:
for info, _info_desc in INFO_DOCS:
shutil.copy2(os.path.join(RST_DIR, info), basepath)
+ for info in INFO_DOCS_OTHER:
+ shutil.copy2(os.path.join(RST_DIR, info), basepath)
# TODO: put this docs in Blender's code and use import as per modules above.
handwritten_modules = [
diff --git a/extern/audaspace/include/devices/DeviceManager.h b/extern/audaspace/include/devices/DeviceManager.h
index 27a546630e8..fa84025478f 100644
--- a/extern/audaspace/include/devices/DeviceManager.h
+++ b/extern/audaspace/include/devices/DeviceManager.h
@@ -27,6 +27,7 @@
#include <memory>
#include <vector>
#include <unordered_map>
+#include <string>
AUD_NAMESPACE_BEGIN
diff --git a/extern/gflags/CMakeLists.txt b/extern/gflags/CMakeLists.txt
index 4f2fce3778b..63749aad46d 100644
--- a/extern/gflags/CMakeLists.txt
+++ b/extern/gflags/CMakeLists.txt
@@ -3,9 +3,7 @@
# Too noisy for code we don't maintain.
if(CMAKE_COMPILER_IS_GNUCC)
- if(NOT "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "8.0")
- add_cxx_flag("-Wno-cast-function-type")
- endif()
+ add_cxx_flag("-Wno-cast-function-type")
endif()
set(INC
diff --git a/extern/hipew/src/hipew.c b/extern/hipew/src/hipew.c
index ecf952e266f..7cafe7727f5 100644
--- a/extern/hipew/src/hipew.c
+++ b/extern/hipew/src/hipew.c
@@ -253,7 +253,7 @@ static int hipewHipInit(void) {
/* Default installation path. */
const char *hip_paths[] = {"", NULL};
#else
- const char *hip_paths[] = {"/opt/rocm/hip/lib/libamdhip64.so", NULL};
+ const char *hip_paths[] = {"libamdhip64.so", "/opt/rocm/hip/lib/libamdhip64.so", NULL};
#endif
static int initialized = 0;
static int result = 0;
diff --git a/extern/mantaflow/CMakeLists.txt b/extern/mantaflow/CMakeLists.txt
index 908c5d2ffd9..06767e9af1e 100644
--- a/extern/mantaflow/CMakeLists.txt
+++ b/extern/mantaflow/CMakeLists.txt
@@ -25,7 +25,8 @@ set(MANTAVERSION "0.13")
add_definitions(-DWITH_FLUID=1)
# Compile Mantaflow dependencies too (e.g. cnpy for numpy file IO).
-# Make sure that dependencies exist before enabling this option by updating the source files in extern/
+# Make sure that dependencies exist before enabling this option
+# by updating the source files in `extern/`.
set(WITH_MANTA_DEPENDENCIES 0)
# Enable Mantaflow numpy support
diff --git a/intern/atomic/intern/atomic_ops_utils.h b/intern/atomic/intern/atomic_ops_utils.h
index 533cfbe9e1f..1c4cef564c3 100644
--- a/intern/atomic/intern/atomic_ops_utils.h
+++ b/intern/atomic/intern/atomic_ops_utils.h
@@ -106,8 +106,7 @@
/* Copied from BLI_utils... */
/* C++ can't use _Static_assert, expects static_assert() but c++0x only,
* Coverity also errors out. */
-#if (!defined(__cplusplus)) && (!defined(__COVERITY__)) && \
- (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 406)) /* gcc4.6+ only */
+#if (!defined(__cplusplus)) && (!defined(__COVERITY__)) && (defined(__GNUC__)) /* GCC only. */
# define ATOMIC_STATIC_ASSERT(a, msg) __extension__ _Static_assert(a, msg);
#else
/* Code adapted from http://www.pixelbeat.org/programming/gcc/static_assert.html */
diff --git a/intern/atomic/tests/atomic_test.cc b/intern/atomic/tests/atomic_test.cc
index 37a66cf0e9c..6c0e96b9d91 100644
--- a/intern/atomic/tests/atomic_test.cc
+++ b/intern/atomic/tests/atomic_test.cc
@@ -6,12 +6,8 @@
#include "testing/testing.h"
#ifdef __GNUC__
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 /* gcc4.6+ only */
-# pragma GCC diagnostic error "-Wsign-compare"
-# endif
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 408
-# pragma GCC diagnostic error "-Wsign-conversion"
-# endif
+# pragma GCC diagnostic error "-Wsign-compare"
+# pragma GCC diagnostic error "-Wsign-conversion"
#endif
/* -------------------------------------------------------------------- */
diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt
index 89dad8ed36e..329aa3990f6 100644
--- a/intern/cycles/CMakeLists.txt
+++ b/intern/cycles/CMakeLists.txt
@@ -36,7 +36,7 @@ if(WITH_CYCLES_NATIVE_ONLY)
)
if(NOT MSVC)
- ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_march_native "-march=native")
+ add_check_cxx_compiler_flag(CMAKE_CXX_FLAGS _has_march_native "-march=native")
if(_has_march_native)
set(CYCLES_KERNEL_FLAGS "-march=native")
else()
@@ -45,18 +45,18 @@ if(WITH_CYCLES_NATIVE_ONLY)
unset(_has_march_native)
else()
if(NOT MSVC_NATIVE_ARCH_FLAGS)
- TRY_RUN(
- arch_run_result
- arch_compile_result
- ${CMAKE_CURRENT_BINARY_DIR}/
- ${CMAKE_CURRENT_SOURCE_DIR}/cmake/msvc_arch_flags.c
- COMPILE_OUTPUT_VARIABLE arch_compile_output
- RUN_OUTPUT_VARIABLE arch_run_output
- )
- if(arch_compile_result AND "${arch_run_result}" EQUAL "0")
- string(STRIP ${arch_run_output} arch_run_output)
- set(MSVC_NATIVE_ARCH_FLAGS ${arch_run_output} CACHE STRING "MSVC Native architecture flags")
- endif()
+ try_run(
+ arch_run_result
+ arch_compile_result
+ ${CMAKE_CURRENT_BINARY_DIR}/
+ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/msvc_arch_flags.c
+ COMPILE_OUTPUT_VARIABLE arch_compile_output
+ RUN_OUTPUT_VARIABLE arch_run_output
+ )
+ if(arch_compile_result AND "${arch_run_result}" EQUAL "0")
+ string(STRIP ${arch_run_output} arch_run_output)
+ set(MSVC_NATIVE_ARCH_FLAGS ${arch_run_output} CACHE STRING "MSVC Native architecture flags")
+ endif()
endif()
set(CYCLES_KERNEL_FLAGS "${MSVC_NATIVE_ARCH_FLAGS}")
endif()
@@ -263,8 +263,7 @@ if(WITH_CYCLES_DEVICE_OPTIX)
${OPTIX_INCLUDE_DIR}
)
else()
- message(STATUS "OptiX not found, disabling it from Cycles")
- set(WITH_CYCLES_DEVICE_OPTIX OFF)
+ set_and_warn_library_found("OptiX" OPTIX_FOUND WITH_CYCLES_DEVICE_OPTIX)
endif()
endif()
@@ -347,6 +346,24 @@ if(WITH_OPENCOLORIO)
)
endif()
+if(WITH_CYCLES_PATH_GUIDING)
+ add_definitions(-DWITH_PATH_GUIDING)
+
+ # The level of the guiding integration.
+ # Different levels can be selected to measure the overhead of different stages.
+ # 1 = recording the path segments
+ # 2 = 1 + generating (not storing) sample data from the segments
+ # 3 = 2 + storing the generates sample data
+ # 4 = 3 + training the guiding fields
+ # 5 = 4 + querying the trained guiding for sampling (full path guiding)
+ add_definitions(-DPATH_GUIDING_LEVEL=5)
+
+ include_directories(
+ SYSTEM
+ ${OPENPGL_INCLUDE_DIR}
+ )
+endif()
+
# NaN debugging
if(WITH_CYCLES_DEBUG_NAN)
add_definitions(-DWITH_CYCLES_DEBUG_NAN)
@@ -364,13 +381,12 @@ endif()
# Warnings
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER_ID MATCHES "Clang")
- ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_no_error_unused_macros "-Wno-error=unused-macros")
+ add_check_cxx_compiler_flag(CMAKE_CXX_FLAGS _has_no_error_unused_macros "-Wno-error=unused-macros")
unset(_has_no_error_unused_macros)
endif()
if(WITH_CYCLES_HYDRA_RENDER_DELEGATE AND (NOT WITH_USD))
- message(STATUS "USD not found, disabling WITH_CYCLES_HYDRA_RENDER_DELEGATE")
- set(WITH_CYCLES_HYDRA_RENDER_DELEGATE OFF)
+ set_and_warn_library_found("USD" WITH_USD WITH_CYCLES_HYDRA_RENDER_DELEGATE)
endif()
if(WITH_CYCLES_HYDRA_RENDER_DELEGATE AND (NOT WITH_BLENDER) AND (NOT WITH_CYCLES_STANDALONE))
set(CYCLES_INSTALL_PATH ${CYCLES_INSTALL_PATH}/hdCycles/resources)
diff --git a/intern/cycles/app/CMakeLists.txt b/intern/cycles/app/CMakeLists.txt
index 0988b1c0ac4..1c7a861ea93 100644
--- a/intern/cycles/app/CMakeLists.txt
+++ b/intern/cycles/app/CMakeLists.txt
@@ -43,7 +43,10 @@ else()
endif()
if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI)
- list(APPEND INC_SYS ${Epoxy_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS})
+ list(APPEND INC_SYS
+ ${Epoxy_INCLUDE_DIRS}
+ ${SDL2_INCLUDE_DIRS}
+ )
list(APPEND LIB ${Epoxy_LIBRARIES} ${SDL2_LIBRARIES})
endif()
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index 666b0077a72..ceb024ba5e7 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -7,6 +7,7 @@ set(INC
../../mikktspace
../../../source/blender/makesdna
../../../source/blender/makesrna
+ ../../../source/blender/blenkernel
../../../source/blender/blenlib
../../../source/blender/gpu
../../../source/blender/render
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index 05f27bdbd4d..354c9c23a53 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -58,7 +58,7 @@ class CyclesRender(bpy.types.RenderEngine):
if not self.session:
if self.is_preview:
cscene = bpy.context.scene.cycles
- use_osl = cscene.shading_system and cscene.device == 'CPU'
+ use_osl = cscene.shading_system
engine.create(self, data, preview_osl=use_osl)
else:
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index e211f53cf31..4ac078ed8a5 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -13,7 +13,7 @@ def _configure_argument_parser():
action='store_true')
parser.add_argument("--cycles-device",
help="Set the device to use for Cycles, overriding user preferences and the scene setting."
- "Valid options are 'CPU', 'CUDA', 'OPTIX', 'HIP' or 'METAL'."
+ "Valid options are 'CPU', 'CUDA', 'OPTIX', 'HIP', 'ONEAPI', or 'METAL'."
"Additionally, you can append '+CPU' to any GPU type for hybrid rendering.",
default=None)
return parser
@@ -156,6 +156,16 @@ def with_osl():
return _cycles.with_osl
+def osl_version():
+ import _cycles
+ return _cycles.osl_version
+
+
+def with_path_guiding():
+ import _cycles
+ return _cycles.with_path_guiding
+
+
def system_info():
import _cycles
return _cycles.system_info()
@@ -204,22 +214,25 @@ def list_render_passes(scene, srl):
yield ("Debug Sample Count", "X", 'VALUE')
# Cryptomatte passes.
- crypto_depth = (srl.pass_cryptomatte_depth + 1) // 2
+ # NOTE: Name channels are lowercase RGBA so that compression rules check in OpenEXR DWA code
+ # uses lossless compression. Reportedly this naming is the only one which works good from the
+ # interoperability point of view. Using XYZW naming is not portable.
+ crypto_depth = (min(16, srl.pass_cryptomatte_depth) + 1) // 2
if srl.use_pass_cryptomatte_object:
for i in range(0, crypto_depth):
- yield ("CryptoObject" + '{:02d}'.format(i), "RGBA", 'COLOR')
+ yield ("CryptoObject" + '{:02d}'.format(i), "rgba", 'COLOR')
if srl.use_pass_cryptomatte_material:
for i in range(0, crypto_depth):
- yield ("CryptoMaterial" + '{:02d}'.format(i), "RGBA", 'COLOR')
+ yield ("CryptoMaterial" + '{:02d}'.format(i), "rgba", 'COLOR')
if srl.use_pass_cryptomatte_asset:
for i in range(0, crypto_depth):
- yield ("CryptoAsset" + '{:02d}'.format(i), "RGBA", 'COLOR')
+ yield ("CryptoAsset" + '{:02d}'.format(i), "rgba", 'COLOR')
# Denoising passes.
if scene.cycles.use_denoising and crl.use_denoising:
yield ("Noisy Image", "RGBA", 'COLOR')
if crl.use_pass_shadow_catcher:
- yield ("Noisy Shadow Catcher", "RGBA", 'COLOR')
+ yield ("Noisy Shadow Catcher", "RGB", 'COLOR')
if crl.denoising_store_passes:
yield ("Denoising Normal", "XYZ", 'VECTOR')
yield ("Denoising Albedo", "RGB", 'COLOR')
@@ -227,6 +240,8 @@ def list_render_passes(scene, srl):
# Custom AOV passes.
for aov in srl.aovs:
+ if not aov.is_valid:
+ continue
if aov.type == 'VALUE':
yield (aov.name, "X", 'VALUE')
else:
diff --git a/intern/cycles/blender/addon/operators.py b/intern/cycles/blender/addon/operators.py
index ab474cda0ab..3680d11359e 100644
--- a/intern/cycles/blender/addon/operators.py
+++ b/intern/cycles/blender/addon/operators.py
@@ -114,7 +114,7 @@ class CYCLES_OT_denoise_animation(Operator):
class CYCLES_OT_merge_images(Operator):
- "Combine OpenEXR multilayer images rendered with different sample " \
+ "Combine OpenEXR multi-layer images rendered with different sample " \
"ranges into one image with reduced noise"
bl_idname = "cycles.merge_images"
bl_label = "Merge Images"
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 699c90183fe..9d7c71417f2 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -60,13 +60,14 @@ enum_filter_types = (
)
enum_panorama_types = (
- ('EQUIRECTANGULAR', "Equirectangular", "Render the scene with a spherical camera, also known as Lat Long panorama"),
- ('FISHEYE_EQUIDISTANT', "Fisheye Equidistant", "Ideal for fulldomes, ignore the sensor dimensions"),
+ ('EQUIRECTANGULAR', "Equirectangular", "Spherical camera for environment maps, also known as Lat Long panorama", 0),
+ ('EQUIANGULAR_CUBEMAP_FACE', "Equiangular Cubemap Face", "Single face of an equiangular cubemap", 5),
+ ('MIRRORBALL', "Mirror Ball", "Mirror ball mapping for environment maps", 3),
+ ('FISHEYE_EQUIDISTANT', "Fisheye Equidistant", "Ideal for fulldomes, ignore the sensor dimensions", 1),
('FISHEYE_EQUISOLID', "Fisheye Equisolid",
- "Similar to most fisheye modern lens, takes sensor dimensions into consideration"),
- ('MIRRORBALL', "Mirror Ball", "Uses the mirror ball mapping"),
+ "Similar to most fisheye modern lens, takes sensor dimensions into consideration", 2),
('FISHEYE_LENS_POLYNOMIAL', "Fisheye Lens Polynomial",
- "Defines the lens projection as polynomial to allow real world camera lenses to be mimicked"),
+ "Defines the lens projection as polynomial to allow real world camera lenses to be mimicked", 4),
)
enum_curve_shape = (
@@ -179,6 +180,12 @@ enum_view3d_shading_render_pass = (
('SAMPLE_COUNT', "Sample Count", "Per-pixel number of samples"),
)
+enum_guiding_distribution = (
+ ('PARALLAX_AWARE_VMM', "Parallax-Aware VMM", "Use Parallax-aware von Mises-Fisher models as directional distribution", 0),
+ ('DIRECTIONAL_QUAD_TREE', "Directional Quad Tree", "Use Directional Quad Trees as directional distribution", 1),
+ ('VMM', "VMM", "Use von Mises-Fisher models as directional distribution", 2),
+)
+
def enum_openimagedenoise_denoiser(self, context):
import _cycles
@@ -283,7 +290,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
)
shading_system: BoolProperty(
name="Open Shading Language",
- description="Use Open Shading Language (CPU rendering only)",
+ description="Use Open Shading Language",
)
preview_pause: BoolProperty(
@@ -358,7 +365,9 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
preview_samples: IntProperty(
name="Viewport Samples",
description="Number of samples to render in the viewport, unlimited if 0",
- min=0, max=(1 << 24),
+ min=0,
+ soft_min=1,
+ max=(1 << 24),
default=1024,
)
@@ -507,6 +516,78 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default=1.0,
)
+ use_guiding: BoolProperty(
+ name="Guiding",
+ description="Use path guiding for sampling paths. Path guiding incrementally "
+ "learns the light distribution of the scene and guides path into directions "
+ "with high direct and indirect light contributions",
+ default=False,
+ )
+
+ use_deterministic_guiding: BoolProperty(
+ name="Deterministic",
+ description="Makes path guiding deterministic which means renderings will be "
+ "reproducible with the same pixel values every time. This feature slows down "
+ "training",
+ default=True,
+ )
+
+ guiding_distribution_type: EnumProperty(
+ name="Guiding Distribution Type",
+ description="Type of representation for the guiding distribution",
+ items=enum_guiding_distribution,
+ default='PARALLAX_AWARE_VMM',
+ )
+
+ use_surface_guiding: BoolProperty(
+ name="Surface Guiding",
+ description="Use guiding when sampling directions on a surface",
+ default=True,
+ )
+
+ surface_guiding_probability: FloatProperty(
+ name="Surface Guiding Probability",
+ description="The probability of guiding a direction on a surface",
+ min=0.0, max=1.0,
+ default=0.5,
+ )
+
+ use_volume_guiding: BoolProperty(
+ name="Volume Guiding",
+ description="Use guiding when sampling directions inside a volume",
+ default=True,
+ )
+
+ guiding_training_samples: IntProperty(
+ name="Training Samples",
+ description="The maximum number of samples used for training path guiding. "
+ "Higher samples lead to more accurate guiding, however may also unnecessarily slow "
+ "down rendering once guiding is accurate enough. "
+ "A value of 0 will continue training until the last sample",
+ min=0,
+ soft_min=1,
+ default=128,
+ )
+
+ volume_guiding_probability: FloatProperty(
+ name="Volume Guiding Probability",
+ description="The probability of guiding a direction inside a volume",
+ min=0.0, max=1.0,
+ default=0.5,
+ )
+
+ use_guiding_direct_light: BoolProperty(
+ name="Guide Direct Light",
+ description="Consider the contribution of directly visible light sources during guiding",
+ default=True,
+ )
+
+ use_guiding_mis_weights: BoolProperty(
+ name="Use MIS Weights",
+ description="Use the MIS weight to weight the contribution of directly visible light sources during guiding",
+ default=True,
+ )
+
max_bounces: IntProperty(
name="Max Bounces",
description="Total maximum number of bounces",
@@ -1556,11 +1637,13 @@ class CyclesPreferences(bpy.types.AddonPreferences):
col.label(text="and AMD driver version 22.10 or newer", icon='BLANK1')
elif device_type == 'ONEAPI':
import sys
- col.label(text="Requires Intel GPU with Xe-HPG architecture", icon='BLANK1')
if sys.platform.startswith("win"):
- col.label(text="and Windows driver version 101.3268 or newer", icon='BLANK1')
+ col.label(text="Requires Intel GPU with Xe-HPG architecture", icon='BLANK1')
+ col.label(text="and Windows driver version 101.3430 or newer", icon='BLANK1')
elif sys.platform.startswith("linux"):
- col.label(text="and Linux driver version xx.xx.23570 or newer", icon='BLANK1')
+ col.label(text="Requires Intel GPU with Xe-HPG architecture and", icon='BLANK1')
+ col.label(text=" - Linux driver version xx.xx.23904 or newer", icon='BLANK1')
+ col.label(text=" - oneAPI Level-Zero Loader", icon='BLANK1')
elif device_type == 'METAL':
col.label(text="Requires Apple Silicon with macOS 12.2 or newer", icon='BLANK1')
col.label(text="or AMD with macOS 12.3 or newer", icon='BLANK1')
@@ -1571,6 +1654,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
box.prop(
device, "use", text=device.name
.replace('(TM)', unicodedata.lookup('TRADE MARK SIGN'))
+ .replace('(tm)', unicodedata.lookup('TRADE MARK SIGN'))
.replace('(R)', unicodedata.lookup('REGISTERED SIGN'))
.replace('(C)', unicodedata.lookup('COPYRIGHT SIGN'))
)
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index ee284dd899a..10a37688f45 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -150,6 +150,16 @@ def get_effective_preview_denoiser(context):
return 'OIDN'
+def use_mnee(context):
+ # The MNEE kernel doesn't compile on macOS < 13.
+ if use_metal(context):
+ import platform
+ v, _, _ = platform.mac_ver()
+ if float(v) < 13.0:
+ return False
+ return True
+
+
class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel):
bl_label = "Sampling"
@@ -278,6 +288,63 @@ class CYCLES_RENDER_PT_sampling_render_denoise(CyclesButtonsPanel, Panel):
col.prop(cscene, "denoising_prefilter", text="Prefilter")
+class CYCLES_RENDER_PT_sampling_path_guiding(CyclesButtonsPanel, Panel):
+ bl_label = "Path Guiding"
+ bl_parent_id = "CYCLES_RENDER_PT_sampling"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ from . import engine
+ return use_cpu(context) and engine.with_path_guiding()
+
+ def draw_header(self, context):
+ scene = context.scene
+ cscene = scene.cycles
+
+ self.layout.prop(cscene, "use_guiding", text="")
+
+ def draw(self, context):
+ scene = context.scene
+ cscene = scene.cycles
+
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+ layout.active = cscene.use_guiding
+
+ col = layout.column(align=True)
+ col.prop(cscene, "use_surface_guiding")
+ col.prop(cscene, "use_volume_guiding")
+ col.prop(cscene, "guiding_training_samples")
+
+
+class CYCLES_RENDER_PT_sampling_path_guiding_debug(CyclesDebugButtonsPanel, Panel):
+ bl_label = "Debug"
+ bl_parent_id = "CYCLES_RENDER_PT_sampling_path_guiding"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ scene = context.scene
+ cscene = scene.cycles
+
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+ layout.active = cscene.use_guiding
+
+ layout.prop(cscene, "guiding_distribution_type", text="Distribution Type")
+
+ col = layout.column(align=True)
+ col.prop(cscene, "surface_guiding_probability")
+ col.prop(cscene, "volume_guiding_probability")
+
+ col = layout.column(align=True)
+ col.prop(cscene, "use_deterministic_guiding")
+ col.prop(cscene, "use_guiding_direct_light")
+ col.prop(cscene, "use_guiding_mis_weights")
+
+
class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
bl_label = "Advanced"
bl_parent_id = "CYCLES_RENDER_PT_sampling"
@@ -1178,7 +1245,7 @@ class CYCLES_OBJECT_PT_shading_caustics(CyclesButtonsPanel, Panel):
@classmethod
def poll(cls, context):
- return CyclesButtonsPanel.poll(context) and not use_metal(context) and context.object.type != 'LIGHT'
+ return CyclesButtonsPanel.poll(context) and use_mnee(context) and context.object.type != 'LIGHT'
def draw(self, context):
layout = self.layout
@@ -1392,7 +1459,7 @@ class CYCLES_LIGHT_PT_light(CyclesButtonsPanel, Panel):
sub.active = not (light.type == 'AREA' and clamp.is_portal)
sub.prop(clamp, "cast_shadow")
sub.prop(clamp, "use_multiple_importance_sampling", text="Multiple Importance")
- if not use_metal(context):
+ if use_mnee(context):
sub.prop(clamp, "is_caustics_light", text="Shadow Caustics")
if light.type == 'AREA':
@@ -1823,6 +1890,12 @@ class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel):
layout.prop(rd, "use_bake_multires")
layout.prop(cscene, "bake_type")
+ if not rd.use_bake_multires and cscene.bake_type not in {
+ "AO", "POSITION", "NORMAL", "UV", "ROUGHNESS", "ENVIRONMENT"}:
+ row = layout.row()
+ row.prop(cbk, "view_from")
+ row.active = scene.camera is not None
+
class CYCLES_RENDER_PT_bake_influence(CyclesButtonsPanel, Panel):
bl_label = "Influence"
@@ -2232,7 +2305,10 @@ def draw_device(self, context):
col.prop(cscene, "device")
from . import engine
- if engine.with_osl() and use_cpu(context):
+ if engine.with_osl() and (
+ use_cpu(context) or
+ (use_optix(context) and (engine.osl_version()[1] >= 13 or engine.osl_version()[0] > 1))
+ ):
col.prop(cscene, "shading_system")
@@ -2286,6 +2362,8 @@ classes = (
CYCLES_RENDER_PT_sampling_viewport_denoise,
CYCLES_RENDER_PT_sampling_render,
CYCLES_RENDER_PT_sampling_render_denoise,
+ CYCLES_RENDER_PT_sampling_path_guiding,
+ CYCLES_RENDER_PT_sampling_path_guiding_debug,
CYCLES_RENDER_PT_sampling_advanced,
CYCLES_RENDER_PT_light_paths,
CYCLES_RENDER_PT_light_paths_max_bounces,
diff --git a/intern/cycles/blender/camera.cpp b/intern/cycles/blender/camera.cpp
index 6926c833096..d7def9fdb7c 100644
--- a/intern/cycles/blender/camera.cpp
+++ b/intern/cycles/blender/camera.cpp
@@ -2,6 +2,7 @@
* Copyright 2011-2022 Blender Foundation */
#include "scene/camera.h"
+#include "scene/bake.h"
#include "scene/scene.h"
#include "blender/sync.h"
@@ -592,6 +593,11 @@ void BlenderSync::sync_camera(BL::RenderSettings &b_render,
blender_camera_from_object(&bcam, b_engine, b_ob);
b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
bcam.matrix = get_transform(b_ob_matrix);
+ scene->bake_manager->set_use_camera(b_render.bake().view_from() ==
+ BL::BakeSettings::view_from_ACTIVE_CAMERA);
+ }
+ else {
+ scene->bake_manager->set_use_camera(false);
}
/* sync */
diff --git a/intern/cycles/blender/id_map.h b/intern/cycles/blender/id_map.h
index e77d2f647bf..5fb17bb0d50 100644
--- a/intern/cycles/blender/id_map.h
+++ b/intern/cycles/blender/id_map.h
@@ -20,7 +20,7 @@ CCL_NAMESPACE_BEGIN
* Utility class to map between Blender datablocks and Cycles data structures,
* and keep track of recalc tags from the dependency graph. */
-template<typename K, typename T> class id_map {
+template<typename K, typename T, typename Flags = uint> class id_map {
public:
id_map(Scene *scene_) : scene(scene_)
{
@@ -63,6 +63,11 @@ template<typename K, typename T> class id_map {
b_recalc.insert(id_ptr);
}
+ bool check_recalc(const BL::ID &id)
+ {
+ return id.ptr.data && b_recalc.find(id.ptr.data) != b_recalc.end();
+ }
+
bool has_recalc()
{
return !(b_recalc.empty());
@@ -154,6 +159,7 @@ template<typename K, typename T> class id_map {
TMapPair &pair = *jt;
if (do_delete && used_set.find(pair.second) == used_set.end()) {
+ flags.erase(pair.second);
scene->delete_node(pair.second);
}
else {
@@ -171,9 +177,33 @@ template<typename K, typename T> class id_map {
return b_map;
}
+ bool test_flag(T *data, Flags val)
+ {
+ typename map<T *, uint>::iterator it = flags.find(data);
+ return it != flags.end() && (it->second & (1 << val)) != 0;
+ }
+
+ void set_flag(T *data, Flags val)
+ {
+ flags[data] |= (1 << val);
+ }
+
+ void clear_flag(T *data, Flags val)
+ {
+ typename map<T *, uint>::iterator it = flags.find(data);
+ if (it != flags.end()) {
+ it->second &= ~(1 << val);
+
+ if (it->second == 0) {
+ flags.erase(it);
+ }
+ }
+ }
+
protected:
map<K, T *> b_map;
set<T *> used_set;
+ map<T *, uint> flags;
set<void *> b_recalc;
Scene *scene;
};
diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp
index 1d1eadebc39..fbc470cada4 100644
--- a/intern/cycles/blender/mesh.cpp
+++ b/intern/cycles/blender/mesh.cpp
@@ -1084,23 +1084,23 @@ static void create_subd_mesh(Scene *scene,
const int edges_num = b_mesh.edges.length();
- if (edges_num != 0) {
+ if (edges_num != 0 && b_mesh.edge_creases.length() > 0) {
size_t num_creases = 0;
- const MEdge *edges = static_cast<MEdge *>(b_mesh.edges[0].ptr.data);
+ const float *creases = static_cast<float *>(b_mesh.edge_creases[0].ptr.data);
for (int i = 0; i < edges_num; i++) {
- const MEdge &b_edge = edges[i];
- if (b_edge.crease != 0) {
+ if (creases[i] != 0.0f) {
num_creases++;
}
}
mesh->reserve_subd_creases(num_creases);
+ const MEdge *edges = static_cast<MEdge *>(b_mesh.edges[0].ptr.data);
for (int i = 0; i < edges_num; i++) {
- const MEdge &b_edge = edges[i];
- if (b_edge.crease != 0) {
- mesh->add_edge_crease(b_edge.v1, b_edge.v2, float(b_edge.crease) / 255.0f);
+ if (creases[i] != 0.0f) {
+ const MEdge &b_edge = edges[i];
+ mesh->add_edge_crease(b_edge.v1, b_edge.v2, creases[i]);
}
}
diff --git a/intern/cycles/blender/object.cpp b/intern/cycles/blender/object.cpp
index 109408c354d..5af1e18a597 100644
--- a/intern/cycles/blender/object.cpp
+++ b/intern/cycles/blender/object.cpp
@@ -23,6 +23,8 @@
#include "util/log.h"
#include "util/task.h"
+#include "BKE_duplilist.h"
+
CCL_NAMESPACE_BEGIN
/* Utilities */
@@ -94,6 +96,13 @@ bool BlenderSync::object_is_light(BL::Object &b_ob)
return (b_ob_data && b_ob_data.is_a(&RNA_Light));
}
+bool BlenderSync::object_is_camera(BL::Object &b_ob)
+{
+ BL::ID b_ob_data = b_ob.data();
+
+ return (b_ob_data && b_ob_data.is_a(&RNA_Camera));
+}
+
void BlenderSync::sync_object_motion_init(BL::Object &b_parent, BL::Object &b_ob, Object *object)
{
/* Initialize motion blur for object, detecting if it's enabled and creating motion
@@ -353,79 +362,26 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
return object;
}
-/* This function mirrors drw_uniform_property_lookup in draw_instance_data.cpp */
-static bool lookup_property(BL::ID b_id, const string &name, float4 *r_value)
-{
- PointerRNA ptr;
- PropertyRNA *prop;
-
- if (!RNA_path_resolve(&b_id.ptr, name.c_str(), &ptr, &prop)) {
- return false;
- }
-
- if (prop == NULL) {
- return false;
- }
-
- PropertyType type = RNA_property_type(prop);
- int arraylen = RNA_property_array_length(&ptr, prop);
-
- if (arraylen == 0) {
- float value;
-
- if (type == PROP_FLOAT)
- value = RNA_property_float_get(&ptr, prop);
- else if (type == PROP_INT)
- value = static_cast<float>(RNA_property_int_get(&ptr, prop));
- else
- return false;
-
- *r_value = make_float4(value, value, value, 1.0f);
- return true;
- }
- else if (type == PROP_FLOAT && arraylen <= 4) {
- *r_value = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
- RNA_property_float_get_array(&ptr, prop, &r_value->x);
- return true;
- }
+extern "C" DupliObject *rna_hack_DepsgraphObjectInstance_dupli_object_get(PointerRNA *ptr);
- return false;
-}
-
-/* This function mirrors drw_uniform_attribute_lookup in draw_instance_data.cpp */
static float4 lookup_instance_property(BL::DepsgraphObjectInstance &b_instance,
const string &name,
bool use_instancer)
{
- string idprop_name = string_printf("[\"%s\"]", name.c_str());
- float4 value;
+ ::Object *ob = (::Object *)b_instance.object().ptr.data;
+ ::DupliObject *dupli = nullptr;
+ ::Object *dupli_parent = nullptr;
/* If requesting instance data, check the parent particle system and object. */
if (use_instancer && b_instance.is_instance()) {
- BL::ParticleSystem b_psys = b_instance.particle_system();
-
- if (b_psys) {
- if (lookup_property(b_psys.settings(), idprop_name, &value) ||
- lookup_property(b_psys.settings(), name, &value)) {
- return value;
- }
- }
- if (lookup_property(b_instance.parent(), idprop_name, &value) ||
- lookup_property(b_instance.parent(), name, &value)) {
- return value;
- }
+ dupli = rna_hack_DepsgraphObjectInstance_dupli_object_get(&b_instance.ptr);
+ dupli_parent = (::Object *)b_instance.parent().ptr.data;
}
- /* Check the object and mesh. */
- BL::Object b_ob = b_instance.object();
- BL::ID b_data = b_ob.data();
-
- if (lookup_property(b_ob, idprop_name, &value) || lookup_property(b_ob, name, &value) ||
- lookup_property(b_data, idprop_name, &value) || lookup_property(b_data, name, &value)) {
- return value;
- }
+ float4 value;
+ BKE_object_dupli_find_rgba_attribute(ob, dupli, dupli_parent, name.c_str(), &value.x);
- return zero_float4();
+ return value;
}
bool BlenderSync::sync_object_attributes(BL::DepsgraphObjectInstance &b_instance, Object *object)
@@ -451,7 +407,8 @@ bool BlenderSync::sync_object_attributes(BL::DepsgraphObjectInstance &b_instance
std::string real_name;
BlenderAttributeType type = blender_attribute_name_split_type(name, &real_name);
- if (type != BL::ShaderNodeAttribute::attribute_type_GEOMETRY) {
+ if (type == BL::ShaderNodeAttribute::attribute_type_OBJECT ||
+ type == BL::ShaderNodeAttribute::attribute_type_INSTANCER) {
bool use_instancer = (type == BL::ShaderNodeAttribute::attribute_type_INSTANCER);
float4 value = lookup_instance_property(b_instance, real_name, use_instancer);
diff --git a/intern/cycles/blender/pointcloud.cpp b/intern/cycles/blender/pointcloud.cpp
index b4e90859877..a679a92d997 100644
--- a/intern/cycles/blender/pointcloud.cpp
+++ b/intern/cycles/blender/pointcloud.cpp
@@ -194,7 +194,7 @@ static void export_pointcloud(Scene *scene,
/* Export points. */
for (int i = 0; i < num_points; i++) {
const float3 co = get_float3(b_attr_position.data[i].vector());
- const float radius = b_attr_radius ? b_attr_radius->data[i].value() : 0.0f;
+ const float radius = b_attr_radius ? b_attr_radius->data[i].value() : 0.01f;
pointcloud->add_point(co, radius);
/* Random number per point. */
@@ -224,27 +224,24 @@ static void export_pointcloud_motion(PointCloud *pointcloud,
const int num_points = pointcloud->num_points();
float3 *mP = attr_mP->data_float3() + motion_step * num_points;
bool have_motion = false;
- int num_motion_points = 0;
const array<float3> &pointcloud_points = pointcloud->get_points();
+ const int b_points_num = b_pointcloud.points.length();
BL::FloatVectorAttribute b_attr_position = find_position_attribute(b_pointcloud);
std::optional<BL::FloatAttribute> b_attr_radius = find_radius_attribute(b_pointcloud);
- for (int i = 0; i < num_points; i++) {
- if (num_motion_points < num_points) {
- const float3 co = get_float3(b_attr_position.data[i].vector());
- const float radius = b_attr_radius ? b_attr_radius->data[i].value() : 0.0f;
- float3 P = co;
- P.w = radius;
- mP[num_motion_points] = P;
- have_motion = have_motion || (P != pointcloud_points[num_motion_points]);
- num_motion_points++;
- }
+ for (int i = 0; i < std::min(num_points, b_points_num); i++) {
+ const float3 co = get_float3(b_attr_position.data[i].vector());
+ const float radius = b_attr_radius ? b_attr_radius->data[i].value() : 0.01f;
+ float3 P = co;
+ P.w = radius;
+ mP[i] = P;
+ have_motion = have_motion || (P != pointcloud_points[i]);
}
/* In case of new attribute, we verify if there really was any motion. */
if (new_attribute) {
- if (num_motion_points != num_points || !have_motion) {
+ if (b_points_num != num_points || !have_motion) {
pointcloud->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
}
else if (motion_step > 0) {
diff --git a/intern/cycles/blender/python.cpp b/intern/cycles/blender/python.cpp
index 1e33b0b7207..9e42f6b8b60 100644
--- a/intern/cycles/blender/python.cpp
+++ b/intern/cycles/blender/python.cpp
@@ -15,6 +15,7 @@
#include "util/debug.h"
#include "util/foreach.h"
+#include "util/guiding.h"
#include "util/log.h"
#include "util/md5.h"
#include "util/opengl.h"
@@ -534,7 +535,7 @@ static PyObject *osl_update_node_func(PyObject * /*self*/, PyObject *args)
socket_type = "NodeSocketBool";
data_type = BL::NodeSocket::type_BOOLEAN;
if (param->validdefault) {
- default_boolean = (bool)param->idefault[0];
+ default_boolean = bool(param->idefault[0]);
}
}
else {
@@ -1008,6 +1009,15 @@ void *CCL_python_module_init()
PyModule_AddStringConstant(mod, "osl_version_string", "unknown");
#endif
+ if (ccl::guiding_supported()) {
+ PyModule_AddObject(mod, "with_path_guiding", Py_True);
+ Py_INCREF(Py_True);
+ }
+ else {
+ PyModule_AddObject(mod, "with_path_guiding", Py_False);
+ Py_INCREF(Py_False);
+ }
+
#ifdef WITH_EMBREE
PyModule_AddObject(mod, "with_embree", Py_True);
Py_INCREF(Py_True);
diff --git a/intern/cycles/blender/session.cpp b/intern/cycles/blender/session.cpp
index 1b7aa38efb4..6641e2b8ac5 100644
--- a/intern/cycles/blender/session.cpp
+++ b/intern/cycles/blender/session.cpp
@@ -60,7 +60,8 @@ BlenderSession::BlenderSession(BL::RenderEngine &b_engine,
height(0),
preview_osl(preview_osl),
python_thread_state(NULL),
- use_developer_ui(false)
+ use_developer_ui(b_userpref.experimental().use_cycles_debug() &&
+ b_userpref.view().show_developer_ui())
{
/* offline render */
background = true;
@@ -496,9 +497,9 @@ void BlenderSession::render_frame_finish()
session->full_buffer_written_cb = function_null;
/* The display driver is the source of drawing context for both drawing and possible graphics
- * interop objects in the path trace. Once the frame is finished the OpenGL context might be
- * freed form Blender side. Need to ensure that all GPU resources are freed prior to that
- * point.
+ * interoperability objects in the path trace. Once the frame is finished the OpenGL context
+ * might be freed form Blender side. Need to ensure that all GPU resources are freed prior to
+ * that point.
* Ideally would only do this when OpenGL context is actually destroyed, but there is no way to
* know when this happens (at least in the code at the time when this comment was written).
* The penalty of re-creating resources on every frame is unlikely to be noticed. */
diff --git a/intern/cycles/blender/shader.cpp b/intern/cycles/blender/shader.cpp
index 9505f4ba58f..dbc49df7f22 100644
--- a/intern/cycles/blender/shader.cpp
+++ b/intern/cycles/blender/shader.cpp
@@ -22,6 +22,8 @@
#include "util/string.h"
#include "util/task.h"
+#include "BKE_duplilist.h"
+
CCL_NAMESPACE_BEGIN
typedef map<void *, ShaderInput *> PtrInputMap;
@@ -103,6 +105,7 @@ static ImageAlphaType get_image_alpha_type(BL::Image &b_image)
static const string_view object_attr_prefix("\x01object:");
static const string_view instancer_attr_prefix("\x01instancer:");
+static const string_view view_layer_attr_prefix("\x01layer:");
static ustring blender_attribute_name_add_type(const string &name, BlenderAttributeType type)
{
@@ -111,6 +114,8 @@ static ustring blender_attribute_name_add_type(const string &name, BlenderAttrib
return ustring::concat(object_attr_prefix, name);
case BL::ShaderNodeAttribute::attribute_type_INSTANCER:
return ustring::concat(instancer_attr_prefix, name);
+ case BL::ShaderNodeAttribute::attribute_type_VIEW_LAYER:
+ return ustring::concat(view_layer_attr_prefix, name);
default:
return ustring(name);
}
@@ -130,6 +135,11 @@ BlenderAttributeType blender_attribute_name_split_type(ustring name, string *r_r
return BL::ShaderNodeAttribute::attribute_type_INSTANCER;
}
+ if (sname.substr(0, view_layer_attr_prefix.size()) == view_layer_attr_prefix) {
+ *r_real_name = sname.substr(view_layer_attr_prefix.size());
+ return BL::ShaderNodeAttribute::attribute_type_VIEW_LAYER;
+ }
+
return BL::ShaderNodeAttribute::attribute_type_GEOMETRY;
}
@@ -205,7 +215,9 @@ static void set_default_value(ShaderInput *input,
}
case SocketType::INT: {
if (b_sock.type() == BL::NodeSocket::type_BOOLEAN) {
- node->set(socket, get_boolean(b_sock.ptr, "default_value"));
+ /* Make sure to call the int overload of set() since this is an integer socket as far as
+ * Cycles is concerned. */
+ node->set(socket, get_boolean(b_sock.ptr, "default_value") ? 1 : 0);
}
else {
node->set(socket, get_int(b_sock.ptr, "default_value"));
@@ -1420,6 +1432,89 @@ static void add_nodes(Scene *scene,
empty_proxy_map);
}
+/* Look up and constant fold all references to View Layer attributes. */
+void BlenderSync::resolve_view_layer_attributes(Shader *shader,
+ ShaderGraph *graph,
+ BL::Depsgraph &b_depsgraph)
+{
+ bool updated = false;
+
+ foreach (ShaderNode *node, graph->nodes) {
+ if (node->is_a(AttributeNode::node_type)) {
+ AttributeNode *attr_node = static_cast<AttributeNode *>(node);
+
+ std::string real_name;
+ BlenderAttributeType type = blender_attribute_name_split_type(attr_node->get_attribute(),
+ &real_name);
+
+ if (type == BL::ShaderNodeAttribute::attribute_type_VIEW_LAYER) {
+ /* Look up the value. */
+ BL::ViewLayer b_layer = b_depsgraph.view_layer_eval();
+ BL::Scene b_scene = b_depsgraph.scene_eval();
+ float4 value;
+
+ BKE_view_layer_find_rgba_attribute((::Scene *)b_scene.ptr.data,
+ (::ViewLayer *)b_layer.ptr.data,
+ real_name.c_str(),
+ &value.x);
+
+ /* Replace all outgoing links, using appropriate output types. */
+ float val_avg = (value.x + value.y + value.z) / 3.0f;
+
+ foreach (ShaderOutput *output, node->outputs) {
+ float val_float;
+ float3 val_float3;
+
+ if (output->type() == SocketType::FLOAT) {
+ val_float = (output->name() == "Alpha") ? value.w : val_avg;
+ val_float3 = make_float3(val_float);
+ }
+ else {
+ val_float = val_avg;
+ val_float3 = float4_to_float3(value);
+ }
+
+ foreach (ShaderInput *sock, output->links) {
+ if (sock->type() == SocketType::FLOAT) {
+ sock->set(val_float);
+ }
+ else if (SocketType::is_float3(sock->type())) {
+ sock->set(val_float3);
+ }
+
+ sock->constant_folded_in = true;
+ }
+
+ graph->disconnect(output);
+ }
+
+ /* Clear the attribute name to avoid further attempts to look up. */
+ attr_node->set_attribute(ustring());
+ updated = true;
+ }
+ }
+ }
+
+ if (updated) {
+ shader_map.set_flag(shader, SHADER_WITH_LAYER_ATTRS);
+ }
+ else {
+ shader_map.clear_flag(shader, SHADER_WITH_LAYER_ATTRS);
+ }
+}
+
+bool BlenderSync::scene_attr_needs_recalc(Shader *shader, BL::Depsgraph &b_depsgraph)
+{
+ if (shader && shader_map.test_flag(shader, SHADER_WITH_LAYER_ATTRS)) {
+ BL::Scene scene = b_depsgraph.scene_eval();
+
+ return shader_map.check_recalc(scene) || shader_map.check_recalc(scene.world()) ||
+ shader_map.check_recalc(scene.camera());
+ }
+
+ return false;
+}
+
/* Sync Materials */
void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
@@ -1438,7 +1533,8 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
Shader *shader;
/* test if we need to sync */
- if (shader_map.add_or_update(&shader, b_mat) || update_all) {
+ if (shader_map.add_or_update(&shader, b_mat) || update_all ||
+ scene_attr_needs_recalc(shader, b_depsgraph)) {
ShaderGraph *graph = new ShaderGraph();
shader->name = b_mat.name().c_str();
@@ -1459,6 +1555,8 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
graph->connect(diffuse->output("BSDF"), out->input("Surface"));
}
+ resolve_view_layer_attributes(shader, graph, b_depsgraph);
+
/* settings */
PointerRNA cmat = RNA_pointer_get(&b_mat.ptr, "cycles");
shader->set_use_mis(get_boolean(cmat, "sample_as_light"));
@@ -1515,9 +1613,11 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
BlenderViewportParameters new_viewport_parameters(b_v3d, use_developer_ui);
+ Shader *shader = scene->default_background;
+
if (world_recalc || update_all || b_world.ptr.data != world_map ||
- viewport_parameters.shader_modified(new_viewport_parameters)) {
- Shader *shader = scene->default_background;
+ viewport_parameters.shader_modified(new_viewport_parameters) ||
+ scene_attr_needs_recalc(shader, b_depsgraph)) {
ShaderGraph *graph = new ShaderGraph();
/* create nodes */
@@ -1615,6 +1715,8 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
background->set_visibility(visibility);
}
+ resolve_view_layer_attributes(shader, graph, b_depsgraph);
+
shader->set_graph(graph);
shader->tag_update(scene);
}
@@ -1681,7 +1783,8 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
Shader *shader;
/* test if we need to sync */
- if (shader_map.add_or_update(&shader, b_light) || update_all) {
+ if (shader_map.add_or_update(&shader, b_light) || update_all ||
+ scene_attr_needs_recalc(shader, b_depsgraph)) {
ShaderGraph *graph = new ShaderGraph();
/* create nodes */
@@ -1702,6 +1805,8 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
graph->connect(emission->output("Emission"), out->input("Surface"));
}
+ resolve_view_layer_attributes(shader, graph, b_depsgraph);
+
shader->set_graph(graph);
shader->tag_update(scene);
}
diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp
index 6081c4626f0..5251f0fee9c 100644
--- a/intern/cycles/blender/sync.cpp
+++ b/intern/cycles/blender/sync.cpp
@@ -206,6 +206,9 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
}
}
}
+ else if (object_is_camera(b_ob)) {
+ shader_map.set_recalc(b_ob);
+ }
}
/* Mesh */
else if (b_id.is_a(&RNA_Mesh)) {
@@ -218,6 +221,11 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
if (world_map == b_world.ptr.data) {
world_recalc = true;
}
+ shader_map.set_recalc(b_world);
+ }
+ /* World */
+ else if (b_id.is_a(&RNA_Scene)) {
+ shader_map.set_recalc(b_id);
}
/* Volume */
else if (b_id.is_a(&RNA_Volume)) {
@@ -413,6 +421,22 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
integrator->set_direct_light_sampling_type(direct_light_sampling_type);
#endif
+ integrator->set_use_guiding(get_boolean(cscene, "use_guiding"));
+ integrator->set_use_surface_guiding(get_boolean(cscene, "use_surface_guiding"));
+ integrator->set_use_volume_guiding(get_boolean(cscene, "use_volume_guiding"));
+ integrator->set_guiding_training_samples(get_int(cscene, "guiding_training_samples"));
+
+ if (use_developer_ui) {
+ integrator->set_deterministic_guiding(get_boolean(cscene, "use_deterministic_guiding"));
+ integrator->set_surface_guiding_probability(get_float(cscene, "surface_guiding_probability"));
+ integrator->set_volume_guiding_probability(get_float(cscene, "volume_guiding_probability"));
+ integrator->set_use_guiding_direct_light(get_boolean(cscene, "use_guiding_direct_light"));
+ integrator->set_use_guiding_mis_weights(get_boolean(cscene, "use_guiding_mis_weights"));
+ GuidingDistributionType guiding_distribution_type = (GuidingDistributionType)get_enum(
+ cscene, "guiding_distribution_type", GUIDING_NUM_TYPES, GUIDING_TYPE_PARALLAX_AWARE_VMM);
+ integrator->set_guiding_distribution_type(guiding_distribution_type);
+ }
+
DenoiseParams denoise_params = get_denoise_params(b_scene, b_view_layer, background);
/* No denoising support for vertex color baking, vertices packed into image
@@ -551,68 +575,72 @@ void BlenderSync::sync_images()
/* Passes */
-static PassType get_blender_pass_type(BL::RenderPass &b_pass)
+static bool get_known_pass_type(BL::RenderPass &b_pass, PassType &type, PassMode &mode)
{
string name = b_pass.name();
-#define MAP_PASS(passname, passtype) \
+#define MAP_PASS(passname, passtype, noisy) \
if (name == passname) { \
- return passtype; \
+ type = passtype; \
+ mode = (noisy) ? PassMode::NOISY : PassMode::DENOISED; \
+ return true; \
} \
((void)0)
- /* NOTE: Keep in sync with defined names from DNA_scene_types.h */
+ /* NOTE: Keep in sync with defined names from engine.py */
- MAP_PASS("Combined", PASS_COMBINED);
- MAP_PASS("Noisy Image", PASS_COMBINED);
+ MAP_PASS("Combined", PASS_COMBINED, false);
+ MAP_PASS("Noisy Image", PASS_COMBINED, true);
- MAP_PASS("Depth", PASS_DEPTH);
- MAP_PASS("Mist", PASS_MIST);
- MAP_PASS("Position", PASS_POSITION);
- MAP_PASS("Normal", PASS_NORMAL);
- MAP_PASS("IndexOB", PASS_OBJECT_ID);
- MAP_PASS("UV", PASS_UV);
- MAP_PASS("Vector", PASS_MOTION);
- MAP_PASS("IndexMA", PASS_MATERIAL_ID);
+ MAP_PASS("Depth", PASS_DEPTH, false);
+ MAP_PASS("Mist", PASS_MIST, false);
+ MAP_PASS("Position", PASS_POSITION, false);
+ MAP_PASS("Normal", PASS_NORMAL, false);
+ MAP_PASS("IndexOB", PASS_OBJECT_ID, false);
+ MAP_PASS("UV", PASS_UV, false);
+ MAP_PASS("Vector", PASS_MOTION, false);
+ MAP_PASS("IndexMA", PASS_MATERIAL_ID, false);
- MAP_PASS("DiffDir", PASS_DIFFUSE_DIRECT);
- MAP_PASS("GlossDir", PASS_GLOSSY_DIRECT);
- MAP_PASS("TransDir", PASS_TRANSMISSION_DIRECT);
- MAP_PASS("VolumeDir", PASS_VOLUME_DIRECT);
+ MAP_PASS("DiffDir", PASS_DIFFUSE_DIRECT, false);
+ MAP_PASS("GlossDir", PASS_GLOSSY_DIRECT, false);
+ MAP_PASS("TransDir", PASS_TRANSMISSION_DIRECT, false);
+ MAP_PASS("VolumeDir", PASS_VOLUME_DIRECT, false);
- MAP_PASS("DiffInd", PASS_DIFFUSE_INDIRECT);
- MAP_PASS("GlossInd", PASS_GLOSSY_INDIRECT);
- MAP_PASS("TransInd", PASS_TRANSMISSION_INDIRECT);
- MAP_PASS("VolumeInd", PASS_VOLUME_INDIRECT);
+ MAP_PASS("DiffInd", PASS_DIFFUSE_INDIRECT, false);
+ MAP_PASS("GlossInd", PASS_GLOSSY_INDIRECT, false);
+ MAP_PASS("TransInd", PASS_TRANSMISSION_INDIRECT, false);
+ MAP_PASS("VolumeInd", PASS_VOLUME_INDIRECT, false);
- MAP_PASS("DiffCol", PASS_DIFFUSE_COLOR);
- MAP_PASS("GlossCol", PASS_GLOSSY_COLOR);
- MAP_PASS("TransCol", PASS_TRANSMISSION_COLOR);
+ MAP_PASS("DiffCol", PASS_DIFFUSE_COLOR, false);
+ MAP_PASS("GlossCol", PASS_GLOSSY_COLOR, false);
+ MAP_PASS("TransCol", PASS_TRANSMISSION_COLOR, false);
- MAP_PASS("Emit", PASS_EMISSION);
- MAP_PASS("Env", PASS_BACKGROUND);
- MAP_PASS("AO", PASS_AO);
- MAP_PASS("Shadow", PASS_SHADOW);
+ MAP_PASS("Emit", PASS_EMISSION, false);
+ MAP_PASS("Env", PASS_BACKGROUND, false);
+ MAP_PASS("AO", PASS_AO, false);
+ MAP_PASS("Shadow", PASS_SHADOW, false);
- MAP_PASS("BakePrimitive", PASS_BAKE_PRIMITIVE);
- MAP_PASS("BakeDifferential", PASS_BAKE_DIFFERENTIAL);
+ MAP_PASS("BakePrimitive", PASS_BAKE_PRIMITIVE, false);
+ MAP_PASS("BakeDifferential", PASS_BAKE_DIFFERENTIAL, false);
- MAP_PASS("Denoising Normal", PASS_DENOISING_NORMAL);
- MAP_PASS("Denoising Albedo", PASS_DENOISING_ALBEDO);
- MAP_PASS("Denoising Depth", PASS_DENOISING_DEPTH);
+ MAP_PASS("Denoising Normal", PASS_DENOISING_NORMAL, true);
+ MAP_PASS("Denoising Albedo", PASS_DENOISING_ALBEDO, true);
+ MAP_PASS("Denoising Depth", PASS_DENOISING_DEPTH, true);
- MAP_PASS("Shadow Catcher", PASS_SHADOW_CATCHER);
- MAP_PASS("Noisy Shadow Catcher", PASS_SHADOW_CATCHER);
+ MAP_PASS("Shadow Catcher", PASS_SHADOW_CATCHER, false);
+ MAP_PASS("Noisy Shadow Catcher", PASS_SHADOW_CATCHER, true);
- MAP_PASS("AdaptiveAuxBuffer", PASS_ADAPTIVE_AUX_BUFFER);
- MAP_PASS("Debug Sample Count", PASS_SAMPLE_COUNT);
+ MAP_PASS("AdaptiveAuxBuffer", PASS_ADAPTIVE_AUX_BUFFER, false);
+ MAP_PASS("Debug Sample Count", PASS_SAMPLE_COUNT, false);
if (string_startswith(name, cryptomatte_prefix)) {
- return PASS_CRYPTOMATTE;
+ type = PASS_CRYPTOMATTE;
+ mode = PassMode::DENOISED;
+ return true;
}
#undef MAP_PASS
- return PASS_NONE;
+ return false;
}
static Pass *pass_add(Scene *scene,
@@ -631,8 +659,6 @@ static Pass *pass_add(Scene *scene,
void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_view_layer)
{
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
-
/* Delete all existing passes. */
set<Pass *> clear_passes(scene->passes.begin(), scene->passes.end());
scene->delete_nodes(clear_passes);
@@ -640,102 +666,35 @@ void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_v
/* Always add combined pass. */
pass_add(scene, PASS_COMBINED, "Combined");
- /* Blender built-in data and light passes. */
- for (BL::RenderPass &b_pass : b_rlay.passes) {
- const PassType pass_type = get_blender_pass_type(b_pass);
-
- if (pass_type == PASS_NONE) {
- LOG(ERROR) << "Unknown pass " << b_pass.name();
- continue;
- }
-
- if (pass_type == PASS_MOTION &&
- (b_view_layer.use_motion_blur() && b_scene.render().use_motion_blur())) {
- continue;
- }
-
- pass_add(scene, pass_type, b_pass.name().c_str());
- }
-
- PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles");
-
- /* Debug passes. */
- if (get_boolean(crl, "pass_debug_sample_count")) {
- b_engine.add_pass("Debug Sample Count", 1, "X", b_view_layer.name().c_str());
- pass_add(scene, PASS_SAMPLE_COUNT, "Debug Sample Count");
- }
-
- /* Cycles specific passes. */
- if (get_boolean(crl, "use_pass_volume_direct")) {
- b_engine.add_pass("VolumeDir", 3, "RGB", b_view_layer.name().c_str());
- pass_add(scene, PASS_VOLUME_DIRECT, "VolumeDir");
- }
- if (get_boolean(crl, "use_pass_volume_indirect")) {
- b_engine.add_pass("VolumeInd", 3, "RGB", b_view_layer.name().c_str());
- pass_add(scene, PASS_VOLUME_INDIRECT, "VolumeInd");
- }
- if (get_boolean(crl, "use_pass_shadow_catcher")) {
- b_engine.add_pass("Shadow Catcher", 3, "RGB", b_view_layer.name().c_str());
- pass_add(scene, PASS_SHADOW_CATCHER, "Shadow Catcher");
- }
-
/* Cryptomatte stores two ID/weight pairs per RGBA layer.
- * User facing parameter is the number of pairs.
- *
- * NOTE: Name channels lowercase RGBA so that compression rules check in OpenEXR DWA code uses
- * lossless compression. Reportedly this naming is the only one which works good from the
- * interoperability point of view. Using XYZW naming is not portable. */
+ * User facing parameter is the number of pairs. */
int crypto_depth = divide_up(min(16, b_view_layer.pass_cryptomatte_depth()), 2);
scene->film->set_cryptomatte_depth(crypto_depth);
CryptomatteType cryptomatte_passes = CRYPT_NONE;
if (b_view_layer.use_pass_cryptomatte_object()) {
- for (int i = 0; i < crypto_depth; i++) {
- string passname = cryptomatte_prefix + string_printf("Object%02d", i);
- b_engine.add_pass(passname.c_str(), 4, "rgba", b_view_layer.name().c_str());
- pass_add(scene, PASS_CRYPTOMATTE, passname.c_str());
- }
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_OBJECT);
}
if (b_view_layer.use_pass_cryptomatte_material()) {
- for (int i = 0; i < crypto_depth; i++) {
- string passname = cryptomatte_prefix + string_printf("Material%02d", i);
- b_engine.add_pass(passname.c_str(), 4, "rgba", b_view_layer.name().c_str());
- pass_add(scene, PASS_CRYPTOMATTE, passname.c_str());
- }
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_MATERIAL);
}
if (b_view_layer.use_pass_cryptomatte_asset()) {
- for (int i = 0; i < crypto_depth; i++) {
- string passname = cryptomatte_prefix + string_printf("Asset%02d", i);
- b_engine.add_pass(passname.c_str(), 4, "rgba", b_view_layer.name().c_str());
- pass_add(scene, PASS_CRYPTOMATTE, passname.c_str());
- }
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_ASSET);
}
scene->film->set_cryptomatte_passes(cryptomatte_passes);
- /* Denoising passes. */
- const bool use_denoising = get_boolean(cscene, "use_denoising") &&
- get_boolean(crl, "use_denoising");
- const bool store_denoising_passes = get_boolean(crl, "denoising_store_passes");
- if (use_denoising) {
- b_engine.add_pass("Noisy Image", 4, "RGBA", b_view_layer.name().c_str());
- pass_add(scene, PASS_COMBINED, "Noisy Image", PassMode::NOISY);
- if (get_boolean(crl, "use_pass_shadow_catcher")) {
- b_engine.add_pass("Noisy Shadow Catcher", 3, "RGB", b_view_layer.name().c_str());
- pass_add(scene, PASS_SHADOW_CATCHER, "Noisy Shadow Catcher", PassMode::NOISY);
- }
- }
- if (store_denoising_passes) {
- b_engine.add_pass("Denoising Normal", 3, "XYZ", b_view_layer.name().c_str());
- pass_add(scene, PASS_DENOISING_NORMAL, "Denoising Normal", PassMode::NOISY);
+ /* Path guiding debug passes. */
+#ifdef WITH_CYCLES_DEBUG
+ b_engine.add_pass("Guiding Color", 3, "RGB", b_view_layer.name().c_str());
+ pass_add(scene, PASS_GUIDING_COLOR, "Guiding Color", PassMode::NOISY);
- b_engine.add_pass("Denoising Albedo", 3, "RGB", b_view_layer.name().c_str());
- pass_add(scene, PASS_DENOISING_ALBEDO, "Denoising Albedo", PassMode::NOISY);
+ b_engine.add_pass("Guiding Probability", 1, "X", b_view_layer.name().c_str());
+ pass_add(scene, PASS_GUIDING_PROBABILITY, "Guiding Probability", PassMode::NOISY);
- b_engine.add_pass("Denoising Depth", 1, "Z", b_view_layer.name().c_str());
- pass_add(scene, PASS_DENOISING_DEPTH, "Denoising Depth", PassMode::NOISY);
- }
+ b_engine.add_pass("Guiding Average Roughness", 1, "X", b_view_layer.name().c_str());
+ pass_add(scene, PASS_GUIDING_AVG_ROUGHNESS, "Guiding Average Roughness", PassMode::NOISY);
+#endif
+
+ unordered_set<string> expected_passes;
/* Custom AOV passes. */
BL::ViewLayer::aovs_iterator b_aov_iter;
@@ -746,16 +705,10 @@ void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_v
}
string name = b_aov.name();
- bool is_color = b_aov.type() == BL::AOV::type_COLOR;
+ PassType type = (b_aov.type() == BL::AOV::type_COLOR) ? PASS_AOV_COLOR : PASS_AOV_VALUE;
- if (is_color) {
- b_engine.add_pass(name.c_str(), 4, "RGBA", b_view_layer.name().c_str());
- pass_add(scene, PASS_AOV_COLOR, name.c_str());
- }
- else {
- b_engine.add_pass(name.c_str(), 1, "X", b_view_layer.name().c_str());
- pass_add(scene, PASS_AOV_VALUE, name.c_str());
- }
+ pass_add(scene, type, name.c_str());
+ expected_passes.insert(name);
}
/* Light Group passes. */
@@ -767,9 +720,29 @@ void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_v
string name = string_printf("Combined_%s", b_lightgroup.name().c_str());
- b_engine.add_pass(name.c_str(), 3, "RGB", b_view_layer.name().c_str());
Pass *pass = pass_add(scene, PASS_COMBINED, name.c_str(), PassMode::NOISY);
pass->set_lightgroup(ustring(b_lightgroup.name()));
+ expected_passes.insert(name);
+ }
+
+ /* Sync the passes that were defined in engine.py. */
+ for (BL::RenderPass &b_pass : b_rlay.passes) {
+ PassType pass_type = PASS_NONE;
+ PassMode pass_mode = PassMode::DENOISED;
+
+ if (!get_known_pass_type(b_pass, pass_type, pass_mode)) {
+ if (!expected_passes.count(b_pass.name())) {
+ LOG(ERROR) << "Unknown pass " << b_pass.name();
+ }
+ continue;
+ }
+
+ if (pass_type == PASS_MOTION &&
+ (b_view_layer.use_motion_blur() && b_scene.render().use_motion_blur())) {
+ continue;
+ }
+
+ pass_add(scene, pass_type, b_pass.name().c_str(), pass_mode);
}
scene->film->set_pass_alpha_threshold(b_view_layer.pass_alpha_threshold());
diff --git a/intern/cycles/blender/sync.h b/intern/cycles/blender/sync.h
index ae6c2420e55..fbb17bab0c8 100644
--- a/intern/cycles/blender/sync.h
+++ b/intern/cycles/blender/sync.h
@@ -120,6 +120,11 @@ class BlenderSync {
void sync_shaders(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, bool update_all);
void sync_nodes(Shader *shader, BL::ShaderNodeTree &b_ntree);
+ bool scene_attr_needs_recalc(Shader *shader, BL::Depsgraph &b_depsgraph);
+ void resolve_view_layer_attributes(Shader *shader,
+ ShaderGraph *graph,
+ BL::Depsgraph &b_depsgraph);
+
/* Object */
Object *sync_object(BL::Depsgraph &b_depsgraph,
BL::ViewLayer &b_view_layer,
@@ -207,13 +212,16 @@ class BlenderSync {
bool object_is_geometry(BObjectInfo &b_ob_info);
bool object_can_have_geometry(BL::Object &b_ob);
bool object_is_light(BL::Object &b_ob);
+ bool object_is_camera(BL::Object &b_ob);
/* variables */
BL::RenderEngine b_engine;
BL::BlendData b_data;
BL::Scene b_scene;
- id_map<void *, Shader> shader_map;
+ enum ShaderFlags { SHADER_WITH_LAYER_ATTRS };
+
+ id_map<void *, Shader, ShaderFlags> shader_map;
id_map<ObjectKey, Object> object_map;
id_map<void *, Procedural> procedural_map;
id_map<GeometryKey, Geometry> geometry_map;
diff --git a/intern/cycles/bvh/split.cpp b/intern/cycles/bvh/split.cpp
index f80305c149a..37b08ffbebb 100644
--- a/intern/cycles/bvh/split.cpp
+++ b/intern/cycles/bvh/split.cpp
@@ -515,7 +515,7 @@ void BVHSpatialSplit::split_reference(const BVHBuild &builder,
int dim,
float pos)
{
- /* initialize boundboxes */
+ /* Initialize bounding-boxes. */
BoundBox left_bounds = BoundBox::empty;
BoundBox right_bounds = BoundBox::empty;
diff --git a/intern/cycles/cmake/external_libs.cmake b/intern/cycles/cmake/external_libs.cmake
index aaeb85f700d..44542a08156 100644
--- a/intern/cycles/cmake/external_libs.cmake
+++ b/intern/cycles/cmake/external_libs.cmake
@@ -69,6 +69,7 @@ if(CYCLES_STANDALONE_REPOSITORY)
_set_default(BOOST_ROOT "${_cycles_lib_dir}/boost")
_set_default(BLOSC_ROOT_DIR "${_cycles_lib_dir}/blosc")
_set_default(EMBREE_ROOT_DIR "${_cycles_lib_dir}/embree")
+ _set_default(EPOXY_ROOT_DIR "${_cycles_lib_dir}/epoxy")
_set_default(IMATH_ROOT_DIR "${_cycles_lib_dir}/imath")
_set_default(GLEW_ROOT_DIR "${_cycles_lib_dir}/glew")
_set_default(JPEG_ROOT "${_cycles_lib_dir}/jpeg")
@@ -91,7 +92,11 @@ if(CYCLES_STANDALONE_REPOSITORY)
_set_default(USD_ROOT_DIR "${_cycles_lib_dir}/usd")
_set_default(WEBP_ROOT_DIR "${_cycles_lib_dir}/webp")
_set_default(ZLIB_ROOT "${_cycles_lib_dir}/zlib")
- _set_default(LEVEL_ZERO_ROOT_DIR "${_cycles_lib_dir}/level-zero")
+ if(WIN32)
+ set(LEVEL_ZERO_ROOT_DIR ${_cycles_lib_dir}/level_zero)
+ else()
+ set(LEVEL_ZERO_ROOT_DIR ${_cycles_lib_dir}/level-zero)
+ endif()
_set_default(SYCL_ROOT_DIR "${_cycles_lib_dir}/dpcpp")
# Ignore system libraries
@@ -197,17 +202,17 @@ endif()
if(CYCLES_STANDALONE_REPOSITORY)
if(MSVC AND EXISTS ${_cycles_lib_dir})
set(OPENEXR_INCLUDE_DIR ${OPENEXR_ROOT_DIR}/include)
- set(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCLUDE_DIR} ${OPENEXR_ROOT_DIR}/include/OpenEXR)
+ set(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCLUDE_DIR} ${OPENEXR_ROOT_DIR}/include/OpenEXR ${IMATH_ROOT_DIR}/include ${IMATH_ROOT_DIR}/include/Imath)
set(OPENEXR_LIBRARIES
+ optimized ${OPENEXR_ROOT_DIR}/lib/OpenEXR_s.lib
+ optimized ${OPENEXR_ROOT_DIR}/lib/OpenEXRCore_s.lib
optimized ${OPENEXR_ROOT_DIR}/lib/Iex_s.lib
- optimized ${OPENEXR_ROOT_DIR}/lib/Half_s.lib
- optimized ${OPENEXR_ROOT_DIR}/lib/IlmImf_s.lib
- optimized ${OPENEXR_ROOT_DIR}/lib/Imath_s.lib
+ optimized ${IMATH_ROOT_DIR}/lib/Imath_s.lib
optimized ${OPENEXR_ROOT_DIR}/lib/IlmThread_s.lib
+ debug ${OPENEXR_ROOT_DIR}/lib/OpenEXR_s_d.lib
+ debug ${OPENEXR_ROOT_DIR}/lib/OpenEXRCore_s_d.lib
debug ${OPENEXR_ROOT_DIR}/lib/Iex_s_d.lib
- debug ${OPENEXR_ROOT_DIR}/lib/Half_s_d.lib
- debug ${OPENEXR_ROOT_DIR}/lib/IlmImf_s_d.lib
- debug ${OPENEXR_ROOT_DIR}/lib/Imath_s_d.lib
+ debug ${IMATH_ROOT_DIR}/lib/Imath_s_d.lib
debug ${OPENEXR_ROOT_DIR}/lib/IlmThread_s_d.lib
)
else()
@@ -265,6 +270,30 @@ if(CYCLES_STANDALONE_REPOSITORY AND WITH_CYCLES_OSL)
endif()
###########################################################################
+# OpenPGL
+###########################################################################
+
+if(CYCLES_STANDALONE_REPOSITORY AND WITH_CYCLES_PATH_GUIDING)
+ if(NOT openpgl_DIR AND EXISTS ${_cycles_lib_dir})
+ set(openpgl_DIR ${_cycles_lib_dir}/openpgl/lib/cmake/openpgl)
+ endif()
+
+ find_package(openpgl QUIET)
+ if(openpgl_FOUND)
+ if(WIN32)
+ get_target_property(OPENPGL_LIBRARIES_RELEASE openpgl::openpgl LOCATION_RELEASE)
+ get_target_property(OPENPGL_LIBRARIES_DEBUG openpgl::openpgl LOCATION_DEBUG)
+ set(OPENPGL_LIBRARIES optimized ${OPENPGL_LIBRARIES_RELEASE} debug ${OPENPGL_LIBRARIES_DEBUG})
+ else()
+ get_target_property(OPENPGL_LIBRARIES openpgl::openpgl LOCATION)
+ endif()
+ get_target_property(OPENPGL_INCLUDE_DIR openpgl::openpgl INTERFACE_INCLUDE_DIRECTORIES)
+ else()
+ set_and_warn_library_found("OpenPGL" openpgl_FOUND WITH_CYCLES_PATH_GUIDING)
+ endif()
+endif()
+
+###########################################################################
# OpenColorIO
###########################################################################
@@ -319,8 +348,8 @@ if(CYCLES_STANDALONE_REPOSITORY)
if(NOT BOOST_VERSION)
message(FATAL_ERROR "Unable to determine Boost version")
endif()
- set(BOOST_POSTFIX "vc141-mt-x64-${BOOST_VERSION}.lib")
- set(BOOST_DEBUG_POSTFIX "vc141-mt-gd-x64-${BOOST_VERSION}.lib")
+ set(BOOST_POSTFIX "vc142-mt-x64-${BOOST_VERSION}.lib")
+ set(BOOST_DEBUG_POSTFIX "vc142-mt-gd-x64-${BOOST_VERSION}.lib")
set(BOOST_LIBRARIES
optimized ${BOOST_ROOT}/lib/libboost_date_time-${BOOST_POSTFIX}
optimized ${BOOST_ROOT}/lib/libboost_iostreams-${BOOST_POSTFIX}
@@ -459,6 +488,7 @@ if(CYCLES_STANDALONE_REPOSITORY AND WITH_CYCLES_NANOVDB)
if(MSVC AND EXISTS ${_cycles_lib_dir})
set(NANOVDB_INCLUDE_DIR ${NANOVDB_ROOT_DIR}/include)
+ set(NANOVDB_INCLUDE_DIRS ${NANOVDB_INCLUDE_DIR})
else()
find_package(NanoVDB REQUIRED)
endif()
@@ -557,16 +587,14 @@ if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI)
# We can't use the version from the Blender precompiled libraries because
# it does not include the video subsystem.
find_package(SDL2 REQUIRED)
+ set_and_warn_library_found("SDL" SDL2_FOUND WITH_CYCLES_STANDALONE_GUI)
- if(NOT SDL2_FOUND)
- set(WITH_CYCLES_STANDALONE_GUI OFF)
- message(STATUS "SDL not found, disabling Cycles standalone GUI")
+ if(SDL2_FOUND)
+ include_directories(
+ SYSTEM
+ ${SDL2_INCLUDE_DIRS}
+ )
endif()
-
- include_directories(
- SYSTEM
- ${SDL2_INCLUDE_DIRS}
- )
endif()
###########################################################################
@@ -575,11 +603,11 @@ endif()
if(WITH_CYCLES_DEVICE_CUDA AND (WITH_CYCLES_CUDA_BINARIES OR NOT WITH_CUDA_DYNLOAD))
find_package(CUDA) # Try to auto locate CUDA toolkit
+ set_and_warn_library_found("CUDA compiler" CUDA_FOUND WITH_CYCLES_CUDA_BINARIES)
+
if(CUDA_FOUND)
message(STATUS "Found CUDA ${CUDA_NVCC_EXECUTABLE} (${CUDA_VERSION})")
else()
- message(STATUS "CUDA compiler not found, disabling WITH_CYCLES_CUDA_BINARIES")
- set(WITH_CYCLES_CUDA_BINARIES OFF)
if(NOT WITH_CUDA_DYNLOAD)
message(STATUS "Additionally falling back to dynamic CUDA load")
set(WITH_CUDA_DYNLOAD ON)
@@ -593,11 +621,10 @@ endif()
if(WITH_CYCLES_HIP_BINARIES AND WITH_CYCLES_DEVICE_HIP)
find_package(HIP)
+ set_and_warn_library_found("HIP compiler" HIP_FOUND WITH_CYCLES_HIP_BINARIES)
+
if(HIP_FOUND)
message(STATUS "Found HIP ${HIP_HIPCC_EXECUTABLE} (${HIP_VERSION})")
- else()
- message(STATUS "HIP compiler not found, disabling WITH_CYCLES_HIP_BINARIES")
- set(WITH_CYCLES_HIP_BINARIES OFF)
endif()
endif()
@@ -613,13 +640,17 @@ if(WITH_CYCLES_DEVICE_METAL)
find_library(METAL_LIBRARY Metal)
# This file was added in the 12.0 SDK, use it as a way to detect the version.
- if(METAL_LIBRARY AND NOT EXISTS "${METAL_LIBRARY}/Headers/MTLFunctionStitching.h")
- message(STATUS "Metal version too old, must be SDK 12.0 or newer, disabling WITH_CYCLES_DEVICE_METAL")
- set(WITH_CYCLES_DEVICE_METAL OFF)
- elseif(NOT METAL_LIBRARY)
- message(STATUS "Metal not found, disabling WITH_CYCLES_DEVICE_METAL")
- set(WITH_CYCLES_DEVICE_METAL OFF)
- else()
+ if(METAL_LIBRARY)
+ if(EXISTS "${METAL_LIBRARY}/Headers/MTLFunctionStitching.h")
+ set(METAL_FOUND ON)
+ else()
+ message(STATUS "Metal version too old, must be SDK 12.0 or newer")
+ set(METAL_FOUND OFF)
+ endif()
+ endif()
+
+ set_and_warn_library_found("Metal" METAL_FOUND WITH_CYCLES_DEVICE_METAL)
+ if(METAL_FOUND)
message(STATUS "Found Metal: ${METAL_LIBRARY}")
endif()
endif()
@@ -631,9 +662,10 @@ endif()
if(WITH_CYCLES_DEVICE_ONEAPI)
find_package(SYCL)
find_package(LevelZero)
+ set_and_warn_library_found("oneAPI" SYCL_FOUND WITH_CYCLES_DEVICE_ONEAPI)
+ set_and_warn_library_found("Level Zero" LEVEL_ZERO_FOUND WITH_CYCLES_DEVICE_ONEAPI)
- if(SYCL_FOUND AND LEVEL_ZERO_FOUND)
- message(STATUS "Found oneAPI: ${SYCL_LIBRARY}")
+ if(SYCL_FOUND AND SYCL_VERSION VERSION_GREATER_EQUAL 6.0 AND LEVEL_ZERO_FOUND)
message(STATUS "Found Level Zero: ${LEVEL_ZERO_LIBRARY}")
if(WITH_CYCLES_ONEAPI_BINARIES)
@@ -644,13 +676,14 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
endif()
if(NOT EXISTS ${OCLOC_INSTALL_DIR})
- message(STATUS "oneAPI ocloc not found in ${OCLOC_INSTALL_DIR}, disabling WITH_CYCLES_ONEAPI_BINARIES."
+ set(OCLOC_FOUND OFF)
+ message(STATUS "oneAPI ocloc not found in ${OCLOC_INSTALL_DIR}."
" A different ocloc directory can be set using OCLOC_INSTALL_DIR cmake variable.")
- set(WITH_CYCLES_ONEAPI_BINARIES OFF)
+ set_and_warn_library_found("ocloc" OCLOC_FOUND WITH_CYCLES_ONEAPI_BINARIES)
endif()
endif()
else()
- message(STATUS "oneAPI or Level Zero not found, disabling WITH_CYCLES_DEVICE_ONEAPI")
+ message(STATUS "SYCL 6.0+ or Level Zero not found, disabling WITH_CYCLES_DEVICE_ONEAPI")
set(WITH_CYCLES_DEVICE_ONEAPI OFF)
endif()
endif()
diff --git a/intern/cycles/cmake/macros.cmake b/intern/cycles/cmake/macros.cmake
index abadfc2c1ac..4ad438c65f9 100644
--- a/intern/cycles/cmake/macros.cmake
+++ b/intern/cycles/cmake/macros.cmake
@@ -118,6 +118,9 @@ macro(cycles_external_libraries_append libraries)
if(WITH_ALEMBIC)
list(APPEND ${libraries} ${ALEMBIC_LIBRARIES})
endif()
+ if(WITH_PATH_GUIDING)
+ target_link_libraries(${target} ${OPENPGL_LIBRARIES})
+ endif()
list(APPEND ${libraries}
${OPENIMAGEIO_LIBRARIES}
@@ -169,13 +172,13 @@ macro(cycles_install_libraries target)
FILES
${TBB_ROOT_DIR}/bin/tbb_debug${CMAKE_SHARED_LIBRARY_SUFFIX}
${OPENVDB_ROOT_DIR}/bin/openvdb_d${CMAKE_SHARED_LIBRARY_SUFFIX}
- DESTINATION $<TARGET_FILE_DIR:${target}>)
+ DESTINATION ${CMAKE_INSTALL_PREFIX})
else()
install(
FILES
${TBB_ROOT_DIR}/bin/tbb${CMAKE_SHARED_LIBRARY_SUFFIX}
${OPENVDB_ROOT_DIR}/bin/openvdb${CMAKE_SHARED_LIBRARY_SUFFIX}
- DESTINATION $<TARGET_FILE_DIR:${target}>)
+ DESTINATION ${CMAKE_INSTALL_PREFIX})
endif()
endif()
endmacro()
diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt
index 24855d795d1..bfca3ab6aea 100644
--- a/intern/cycles/device/CMakeLists.txt
+++ b/intern/cycles/device/CMakeLists.txt
@@ -142,7 +142,6 @@ set(SRC
${SRC_DUMMY}
${SRC_MULTI}
${SRC_OPTIX}
- ${SRC_ONEAPI}
${SRC_HEADERS}
)
@@ -188,7 +187,29 @@ if(WITH_CYCLES_DEVICE_METAL)
)
endif()
if (WITH_CYCLES_DEVICE_ONEAPI)
+ if(WITH_CYCLES_ONEAPI_BINARIES)
+ set(cycles_kernel_oneapi_lib_suffix "_aot")
+ else()
+ set(cycles_kernel_oneapi_lib_suffix "_jit")
+ endif()
+ if(WIN32)
+ set(cycles_kernel_oneapi_lib ${CMAKE_CURRENT_BINARY_DIR}/../kernel/cycles_kernel_oneapi${cycles_kernel_oneapi_lib_suffix}.lib)
+ else()
+ set(cycles_kernel_oneapi_lib ${CMAKE_CURRENT_BINARY_DIR}/../kernel/libcycles_kernel_oneapi${cycles_kernel_oneapi_lib_suffix}.so)
+ endif()
+ list(APPEND LIB ${cycles_kernel_oneapi_lib})
+ if(WIN32)
+ list(APPEND LIB debug ${SYCL_LIBRARY_DEBUG} optimized ${SYCL_LIBRARY})
+ else()
+ list(APPEND LIB ${SYCL_LIBRARY})
+ endif()
add_definitions(-DWITH_ONEAPI)
+ list(APPEND SRC
+ ${SRC_ONEAPI}
+ )
+ list(APPEND INC_SYS
+ ${SYCL_INCLUDE_DIR}
+ )
endif()
if(WITH_OPENIMAGEDENOISE)
@@ -203,7 +224,8 @@ include_directories(SYSTEM ${INC_SYS})
cycles_add_library(cycles_device "${LIB}" ${SRC})
if(WITH_CYCLES_DEVICE_ONEAPI)
- # Need to have proper rebuilding in case of changes in cycles_kernel_oneapi due external project behaviour
+ # Need to have proper rebuilding in case of changes
+ # in cycles_kernel_oneapi due external project behavior.
add_dependencies(cycles_device cycles_kernel_oneapi)
endif()
diff --git a/intern/cycles/device/cpu/device.cpp b/intern/cycles/device/cpu/device.cpp
index 5ae0130785b..9b249063aec 100644
--- a/intern/cycles/device/cpu/device.cpp
+++ b/intern/cycles/device/cpu/device.cpp
@@ -7,6 +7,7 @@
/* Used for `info.denoisers`. */
/* TODO(sergey): The denoisers are probably to be moved completely out of the device into their
* own class. But until then keep API consistent with how it used to work before. */
+#include "util/guiding.h"
#include "util/openimagedenoise.h"
CCL_NAMESPACE_BEGIN
@@ -27,6 +28,12 @@ void device_cpu_info(vector<DeviceInfo> &devices)
info.has_osl = true;
info.has_nanovdb = true;
info.has_profiling = true;
+ if (guiding_supported()) {
+ info.has_guiding = true;
+ }
+ else {
+ info.has_guiding = false;
+ }
if (openimagedenoise_supported()) {
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
}
diff --git a/intern/cycles/device/cpu/device_impl.cpp b/intern/cycles/device/cpu/device_impl.cpp
index a2b8d1cbbfa..3d0f3195f74 100644
--- a/intern/cycles/device/cpu/device_impl.cpp
+++ b/intern/cycles/device/cpu/device_impl.cpp
@@ -38,6 +38,7 @@
#include "util/debug.h"
#include "util/foreach.h"
#include "util/function.h"
+#include "util/guiding.h"
#include "util/log.h"
#include "util/map.h"
#include "util/openimagedenoise.h"
@@ -278,6 +279,23 @@ void CPUDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
Device::build_bvh(bvh, progress, refit);
}
+void *CPUDevice::get_guiding_device() const
+{
+#ifdef WITH_PATH_GUIDING
+ if (!guiding_device) {
+ if (guiding_device_type() == 8) {
+ guiding_device = make_unique<openpgl::cpp::Device>(PGL_DEVICE_TYPE_CPU_8);
+ }
+ else if (guiding_device_type() == 4) {
+ guiding_device = make_unique<openpgl::cpp::Device>(PGL_DEVICE_TYPE_CPU_4);
+ }
+ }
+ return guiding_device.get();
+#else
+ return nullptr;
+#endif
+}
+
void CPUDevice::get_cpu_kernel_thread_globals(
vector<CPUKernelThreadGlobals> &kernel_thread_globals)
{
diff --git a/intern/cycles/device/cpu/device_impl.h b/intern/cycles/device/cpu/device_impl.h
index e7e77f18194..cbc78d3247a 100644
--- a/intern/cycles/device/cpu/device_impl.h
+++ b/intern/cycles/device/cpu/device_impl.h
@@ -26,6 +26,9 @@
#include "kernel/osl/globals.h"
// clang-format on
+#include "util/guiding.h"
+#include "util/unique_ptr.h"
+
CCL_NAMESPACE_BEGIN
class CPUDevice : public Device {
@@ -42,6 +45,9 @@ class CPUDevice : public Device {
RTCScene embree_scene = NULL;
RTCDevice embree_device;
#endif
+#ifdef WITH_PATH_GUIDING
+ mutable unique_ptr<openpgl::cpp::Device> guiding_device;
+#endif
CPUDevice(const DeviceInfo &info_, Stats &stats_, Profiler &profiler_);
~CPUDevice();
@@ -72,6 +78,8 @@ class CPUDevice : public Device {
void build_bvh(BVH *bvh, Progress &progress, bool refit) override;
+ void *get_guiding_device() const override;
+
virtual void get_cpu_kernel_thread_globals(
vector<CPUKernelThreadGlobals> &kernel_thread_globals) override;
virtual void *get_cpu_osl_memory() override;
diff --git a/intern/cycles/device/cpu/kernel_thread_globals.cpp b/intern/cycles/device/cpu/kernel_thread_globals.cpp
index 99af1525d92..90880f5e5f7 100644
--- a/intern/cycles/device/cpu/kernel_thread_globals.cpp
+++ b/intern/cycles/device/cpu/kernel_thread_globals.cpp
@@ -14,19 +14,23 @@ CPUKernelThreadGlobals::CPUKernelThreadGlobals(const KernelGlobalsCPU &kernel_gl
Profiler &cpu_profiler)
: KernelGlobalsCPU(kernel_globals), cpu_profiler_(cpu_profiler)
{
- reset_runtime_memory();
+ clear_runtime_pointers();
#ifdef WITH_OSL
OSLGlobals::thread_init(this, static_cast<OSLGlobals *>(osl_globals_memory));
#else
(void)osl_globals_memory;
#endif
+
+#ifdef WITH_PATH_GUIDING
+ opgl_path_segment_storage = new openpgl::cpp::PathSegmentStorage();
+#endif
}
CPUKernelThreadGlobals::CPUKernelThreadGlobals(CPUKernelThreadGlobals &&other) noexcept
: KernelGlobalsCPU(std::move(other)), cpu_profiler_(other.cpu_profiler_)
{
- other.reset_runtime_memory();
+ other.clear_runtime_pointers();
}
CPUKernelThreadGlobals::~CPUKernelThreadGlobals()
@@ -34,6 +38,12 @@ CPUKernelThreadGlobals::~CPUKernelThreadGlobals()
#ifdef WITH_OSL
OSLGlobals::thread_free(this);
#endif
+
+#ifdef WITH_PATH_GUIDING
+ delete opgl_path_segment_storage;
+ delete opgl_surface_sampling_distribution;
+ delete opgl_volume_sampling_distribution;
+#endif
}
CPUKernelThreadGlobals &CPUKernelThreadGlobals::operator=(CPUKernelThreadGlobals &&other)
@@ -44,16 +54,25 @@ CPUKernelThreadGlobals &CPUKernelThreadGlobals::operator=(CPUKernelThreadGlobals
*static_cast<KernelGlobalsCPU *>(this) = *static_cast<KernelGlobalsCPU *>(&other);
- other.reset_runtime_memory();
+ other.clear_runtime_pointers();
return *this;
}
-void CPUKernelThreadGlobals::reset_runtime_memory()
+void CPUKernelThreadGlobals::clear_runtime_pointers()
{
#ifdef WITH_OSL
osl = nullptr;
#endif
+
+#ifdef WITH_PATH_GUIDING
+ opgl_sample_data_storage = nullptr;
+ opgl_guiding_field = nullptr;
+
+ opgl_path_segment_storage = nullptr;
+ opgl_surface_sampling_distribution = nullptr;
+ opgl_volume_sampling_distribution = nullptr;
+#endif
}
void CPUKernelThreadGlobals::start_profiling()
diff --git a/intern/cycles/device/cpu/kernel_thread_globals.h b/intern/cycles/device/cpu/kernel_thread_globals.h
index 96d2bd9e165..2462eb4cb2c 100644
--- a/intern/cycles/device/cpu/kernel_thread_globals.h
+++ b/intern/cycles/device/cpu/kernel_thread_globals.h
@@ -36,7 +36,7 @@ class CPUKernelThreadGlobals : public KernelGlobalsCPU {
void stop_profiling();
protected:
- void reset_runtime_memory();
+ void clear_runtime_pointers();
Profiler &cpu_profiler_;
};
diff --git a/intern/cycles/device/cuda/device_impl.cpp b/intern/cycles/device/cuda/device_impl.cpp
index 01c021551f3..c9764d1c21b 100644
--- a/intern/cycles/device/cuda/device_impl.cpp
+++ b/intern/cycles/device/cuda/device_impl.cpp
@@ -232,7 +232,7 @@ string CUDADevice::compile_kernel_get_common_cflags(const uint kernel_features)
return cflags;
}
-string CUDADevice::compile_kernel(const uint kernel_features,
+string CUDADevice::compile_kernel(const string &common_cflags,
const char *name,
const char *base,
bool force_ptx)
@@ -281,7 +281,6 @@ string CUDADevice::compile_kernel(const uint kernel_features,
/* We include cflags into md5 so changing cuda toolkit or changing other
* compiler command line arguments makes sure cubin gets re-built.
*/
- string common_cflags = compile_kernel_get_common_cflags(kernel_features);
const string kernel_md5 = util_md5_string(source_md5 + common_cflags);
const char *const kernel_ext = force_ptx ? "ptx" : "cubin";
@@ -417,7 +416,8 @@ bool CUDADevice::load_kernels(const uint kernel_features)
/* get kernel */
const char *kernel_name = "kernel";
- string cubin = compile_kernel(kernel_features, kernel_name);
+ string cflags = compile_kernel_get_common_cflags(kernel_features);
+ string cubin = compile_kernel(cflags, kernel_name);
if (cubin.empty())
return false;
diff --git a/intern/cycles/device/cuda/device_impl.h b/intern/cycles/device/cuda/device_impl.h
index a754c33f79d..c18f2811161 100644
--- a/intern/cycles/device/cuda/device_impl.h
+++ b/intern/cycles/device/cuda/device_impl.h
@@ -77,9 +77,9 @@ class CUDADevice : public Device {
bool use_adaptive_compilation();
- virtual string compile_kernel_get_common_cflags(const uint kernel_features);
+ string compile_kernel_get_common_cflags(const uint kernel_features);
- string compile_kernel(const uint kernel_features,
+ string compile_kernel(const string &cflags,
const char *name,
const char *base = "cuda",
bool force_ptx = false);
diff --git a/intern/cycles/device/cuda/queue.cpp b/intern/cycles/device/cuda/queue.cpp
index 5912e68a92b..69fae03e32c 100644
--- a/intern/cycles/device/cuda/queue.cpp
+++ b/intern/cycles/device/cuda/queue.cpp
@@ -49,7 +49,7 @@ int CUDADeviceQueue::num_concurrent_states(const size_t state_size) const
return num_states;
}
-int CUDADeviceQueue::num_concurrent_busy_states() const
+int CUDADeviceQueue::num_concurrent_busy_states(const size_t /*state_size*/) const
{
const int max_num_threads = cuda_device_->get_num_multiprocessors() *
cuda_device_->get_max_num_threads_per_multiprocessor();
@@ -79,7 +79,7 @@ bool CUDADeviceQueue::enqueue(DeviceKernel kernel,
return false;
}
- debug_enqueue(kernel, work_size);
+ debug_enqueue_begin(kernel, work_size);
const CUDAContextScope scope(cuda_device_);
const CUDADeviceKernel &cuda_kernel = cuda_device_->kernels.get(kernel);
@@ -121,6 +121,8 @@ bool CUDADeviceQueue::enqueue(DeviceKernel kernel,
0),
"enqueue");
+ debug_enqueue_end();
+
return !(cuda_device_->have_error());
}
diff --git a/intern/cycles/device/cuda/queue.h b/intern/cycles/device/cuda/queue.h
index b450f5b3592..7107afe70c9 100644
--- a/intern/cycles/device/cuda/queue.h
+++ b/intern/cycles/device/cuda/queue.h
@@ -23,7 +23,7 @@ class CUDADeviceQueue : public DeviceQueue {
~CUDADeviceQueue();
virtual int num_concurrent_states(const size_t state_size) const override;
- virtual int num_concurrent_busy_states() const override;
+ virtual int num_concurrent_busy_states(const size_t state_size) const override;
virtual void init_execution() override;
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index ace6ed517f5..6aef5458246 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -352,6 +352,7 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
info.has_nanovdb = true;
info.has_osl = true;
+ info.has_guiding = true;
info.has_profiling = true;
info.has_peer_memory = false;
info.use_metalrt = false;
@@ -399,6 +400,7 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
/* Accumulate device info. */
info.has_nanovdb &= device.has_nanovdb;
info.has_osl &= device.has_osl;
+ info.has_guiding &= device.has_guiding;
info.has_profiling &= device.has_profiling;
info.has_peer_memory |= device.has_peer_memory;
info.use_metalrt |= device.use_metalrt;
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index cdb13ca0a97..06a2f5c7b01 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -66,6 +66,7 @@ class DeviceInfo {
bool display_device; /* GPU is used as a display device. */
bool has_nanovdb; /* Support NanoVDB volumes. */
bool has_osl; /* Support Open Shading Language. */
+ bool has_guiding; /* Support path guiding. */
bool has_profiling; /* Supports runtime collection of profiling info. */
bool has_peer_memory; /* GPU has P2P access to memory of another GPU. */
bool has_gpu_queue; /* Device supports GPU queue. */
@@ -84,6 +85,7 @@ class DeviceInfo {
display_device = false;
has_nanovdb = false;
has_osl = false;
+ has_guiding = false;
has_profiling = false;
has_peer_memory = false;
has_gpu_queue = false;
@@ -158,6 +160,11 @@ class Device {
return true;
}
+ virtual bool load_osl_kernels()
+ {
+ return true;
+ }
+
/* GPU device only functions.
* These may not be used on CPU or multi-devices. */
@@ -217,6 +224,15 @@ class Device {
return false;
}
+ /* Guiding */
+
+ /* Returns path guiding device handle. */
+ virtual void *get_guiding_device() const
+ {
+ LOG(ERROR) << "Request guiding field from a device which does not support it.";
+ return nullptr;
+ }
+
/* Buffer denoising. */
/* Returns true if task is fully handled. */
diff --git a/intern/cycles/device/hip/device_impl.h b/intern/cycles/device/hip/device_impl.h
index 9afef3789af..efdc15dca79 100644
--- a/intern/cycles/device/hip/device_impl.h
+++ b/intern/cycles/device/hip/device_impl.h
@@ -74,7 +74,7 @@ class HIPDevice : public Device {
bool use_adaptive_compilation();
- virtual string compile_kernel_get_common_cflags(const uint kernel_features);
+ string compile_kernel_get_common_cflags(const uint kernel_features);
string compile_kernel(const uint kernel_features, const char *name, const char *base = "hip");
diff --git a/intern/cycles/device/hip/queue.cpp b/intern/cycles/device/hip/queue.cpp
index 8b3d963a32f..e93a9b4df3a 100644
--- a/intern/cycles/device/hip/queue.cpp
+++ b/intern/cycles/device/hip/queue.cpp
@@ -49,7 +49,7 @@ int HIPDeviceQueue::num_concurrent_states(const size_t state_size) const
return num_states;
}
-int HIPDeviceQueue::num_concurrent_busy_states() const
+int HIPDeviceQueue::num_concurrent_busy_states(const size_t /*state_size*/) const
{
const int max_num_threads = hip_device_->get_num_multiprocessors() *
hip_device_->get_max_num_threads_per_multiprocessor();
@@ -79,7 +79,7 @@ bool HIPDeviceQueue::enqueue(DeviceKernel kernel,
return false;
}
- debug_enqueue(kernel, work_size);
+ debug_enqueue_begin(kernel, work_size);
const HIPContextScope scope(hip_device_);
const HIPDeviceKernel &hip_kernel = hip_device_->kernels.get(kernel);
@@ -120,6 +120,8 @@ bool HIPDeviceQueue::enqueue(DeviceKernel kernel,
0),
"enqueue");
+ debug_enqueue_end();
+
return !(hip_device_->have_error());
}
diff --git a/intern/cycles/device/hip/queue.h b/intern/cycles/device/hip/queue.h
index 729d8a19acb..df0678108af 100644
--- a/intern/cycles/device/hip/queue.h
+++ b/intern/cycles/device/hip/queue.h
@@ -23,7 +23,7 @@ class HIPDeviceQueue : public DeviceQueue {
~HIPDeviceQueue();
virtual int num_concurrent_states(const size_t state_size) const override;
- virtual int num_concurrent_busy_states() const override;
+ virtual int num_concurrent_busy_states(const size_t state_size) const override;
virtual void init_execution() override;
diff --git a/intern/cycles/device/kernel.cpp b/intern/cycles/device/kernel.cpp
index 96a99cd62cd..27ca0d81817 100644
--- a/intern/cycles/device/kernel.cpp
+++ b/intern/cycles/device/kernel.cpp
@@ -7,6 +7,30 @@
CCL_NAMESPACE_BEGIN
+bool device_kernel_has_shading(DeviceKernel kernel)
+{
+ return (kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND ||
+ kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_LIGHT ||
+ kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE ||
+ kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE ||
+ kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_MNEE ||
+ kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME ||
+ kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_SHADOW ||
+ kernel == DEVICE_KERNEL_SHADER_EVAL_DISPLACE ||
+ kernel == DEVICE_KERNEL_SHADER_EVAL_BACKGROUND ||
+ kernel == DEVICE_KERNEL_SHADER_EVAL_CURVE_SHADOW_TRANSPARENCY);
+}
+
+bool device_kernel_has_intersection(DeviceKernel kernel)
+{
+ return (kernel == DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST ||
+ kernel == DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW ||
+ kernel == DEVICE_KERNEL_INTEGRATOR_INTERSECT_SUBSURFACE ||
+ kernel == DEVICE_KERNEL_INTEGRATOR_INTERSECT_VOLUME_STACK ||
+ kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE ||
+ kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_MNEE);
+}
+
const char *device_kernel_as_string(DeviceKernel kernel)
{
switch (kernel) {
diff --git a/intern/cycles/device/kernel.h b/intern/cycles/device/kernel.h
index 4ae461f1f67..b829a891260 100644
--- a/intern/cycles/device/kernel.h
+++ b/intern/cycles/device/kernel.h
@@ -11,6 +11,9 @@
CCL_NAMESPACE_BEGIN
+bool device_kernel_has_shading(DeviceKernel kernel);
+bool device_kernel_has_intersection(DeviceKernel kernel);
+
const char *device_kernel_as_string(DeviceKernel kernel);
std::ostream &operator<<(std::ostream &os, DeviceKernel kernel);
diff --git a/intern/cycles/device/metal/device_impl.mm b/intern/cycles/device/metal/device_impl.mm
index d1250b83d22..6f1042b1e55 100644
--- a/intern/cycles/device/metal/device_impl.mm
+++ b/intern/cycles/device/metal/device_impl.mm
@@ -254,6 +254,10 @@ void MetalDevice::make_source(MetalPipelineType pso_type, const uint kernel_feat
break;
}
+ NSProcessInfo *processInfo = [NSProcessInfo processInfo];
+ NSOperatingSystemVersion macos_ver = [processInfo operatingSystemVersion];
+ global_defines += "#define __KERNEL_METAL_MACOS__ " + to_string(macos_ver.majorVersion) + "\n";
+
string &source = this->source[pso_type];
source = "\n#include \"kernel/device/metal/kernel.metal\"\n";
source = path_source_replace_includes(source, path_get("source"));
@@ -292,9 +296,11 @@ void MetalDevice::make_source(MetalPipelineType pso_type, const uint kernel_feat
}
source = global_defines + source;
+# if 0
metal_printf("================\n%s================\n\%s================\n",
global_defines.c_str(),
baked_constants.c_str());
+# endif
/* Generate an MD5 from the source and include any baked constants. This is used when caching
* PSOs. */
@@ -335,6 +341,14 @@ bool MetalDevice::compile_and_load(MetalPipelineType pso_type)
MTLCompileOptions *options = [[MTLCompileOptions alloc] init];
+# if defined(MAC_OS_VERSION_13_0)
+ if (@available(macos 13.0, *)) {
+ if (device_vendor == METAL_GPU_INTEL) {
+ [options setOptimizationLevel:MTLLibraryOptimizationLevelSize];
+ }
+ }
+# endif
+
options.fastMathEnabled = YES;
if (@available(macOS 12.0, *)) {
options.languageVersion = MTLLanguageVersion2_4;
diff --git a/intern/cycles/device/metal/kernel.mm b/intern/cycles/device/metal/kernel.mm
index 385cb412b06..dc8af9a5358 100644
--- a/intern/cycles/device/metal/kernel.mm
+++ b/intern/cycles/device/metal/kernel.mm
@@ -45,6 +45,36 @@ bool kernel_has_intersection(DeviceKernel device_kernel)
struct ShaderCache {
ShaderCache(id<MTLDevice> _mtlDevice) : mtlDevice(_mtlDevice)
{
+ /* Initialize occupancy tuning LUT. */
+ if (MetalInfo::get_device_vendor(mtlDevice) == METAL_GPU_APPLE) {
+ switch (MetalInfo::get_apple_gpu_architecture(mtlDevice)) {
+ default:
+ case APPLE_M2:
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_COMPACT_SHADOW_STATES] = {32, 32};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INIT_FROM_CAMERA] = {832, 32};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST] = {64, 64};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW] = {64, 64};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INTERSECT_SUBSURFACE] = {704, 32};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_QUEUED_PATHS_ARRAY] = {1024, 256};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND] = {64, 32};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_SHADE_SHADOW] = {256, 256};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE] = {448, 384};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_SORTED_PATHS_ARRAY] = {1024, 1024};
+ break;
+ case APPLE_M1:
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_COMPACT_SHADOW_STATES] = {256, 128};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INIT_FROM_CAMERA] = {768, 32};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST] = {512, 128};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW] = {384, 128};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INTERSECT_SUBSURFACE] = {512, 64};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_QUEUED_PATHS_ARRAY] = {512, 256};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND] = {512, 128};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_SHADE_SHADOW] = {384, 32};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE] = {576, 384};
+ occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_SORTED_PATHS_ARRAY] = {832, 832};
+ break;
+ }
+ }
}
~ShaderCache();
@@ -73,6 +103,11 @@ struct ShaderCache {
std::function<void(MetalKernelPipeline *)> completionHandler;
};
+ struct OccupancyTuningParameters {
+ int threads_per_threadgroup = 0;
+ int num_threads_per_block = 0;
+ } occupancy_tuning[DEVICE_KERNEL_NUM];
+
std::mutex cache_mutex;
PipelineCollection pipelines[DEVICE_KERNEL_NUM];
@@ -162,6 +197,13 @@ bool ShaderCache::should_load_kernel(DeviceKernel device_kernel,
}
}
+ if (device_kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_MNEE) {
+ if ((device->kernel_features & KERNEL_FEATURE_MNEE) == 0) {
+ /* Skip shade_surface_mnee kernel if the scene doesn't require it. */
+ return false;
+ }
+ }
+
if (pso_type != PSO_GENERIC) {
/* Only specialize kernels where it can make an impact. */
if (device_kernel < DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST ||
@@ -223,6 +265,13 @@ void ShaderCache::load_kernel(DeviceKernel device_kernel,
request.pipeline->device_kernel = device_kernel;
request.pipeline->threads_per_threadgroup = device->max_threads_per_threadgroup;
+ if (occupancy_tuning[device_kernel].threads_per_threadgroup) {
+ request.pipeline->threads_per_threadgroup =
+ occupancy_tuning[device_kernel].threads_per_threadgroup;
+ request.pipeline->num_threads_per_block =
+ occupancy_tuning[device_kernel].num_threads_per_block;
+ }
+
/* metalrt options */
request.pipeline->use_metalrt = device->use_metalrt;
request.pipeline->metalrt_hair = device->use_metalrt &&
@@ -308,26 +357,35 @@ MetalKernelPipeline *ShaderCache::get_best_pipeline(DeviceKernel kernel, const M
bool MetalKernelPipeline::should_use_binary_archive() const
{
- if (auto str = getenv("CYCLES_METAL_DISABLE_BINARY_ARCHIVES")) {
- if (atoi(str) != 0) {
- /* Don't archive if we have opted out by env var. */
+ /* Issues with binary archives in older macOS versions. */
+ if (@available(macOS 13.0, *)) {
+ if (auto str = getenv("CYCLES_METAL_DISABLE_BINARY_ARCHIVES")) {
+ if (atoi(str) != 0) {
+ /* Don't archive if we have opted out by env var. */
+ return false;
+ }
+ }
+
+ /* Workaround for Intel GPU having issue using Binary Archives */
+ MetalGPUVendor gpu_vendor = MetalInfo::get_device_vendor(mtlDevice);
+ if (gpu_vendor == METAL_GPU_INTEL) {
return false;
}
- }
- if (pso_type == PSO_GENERIC) {
- /* Archive the generic kernels. */
- return true;
- }
+ if (pso_type == PSO_GENERIC) {
+ /* Archive the generic kernels. */
+ return true;
+ }
- if (device_kernel >= DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND &&
- device_kernel <= DEVICE_KERNEL_INTEGRATOR_SHADE_SHADOW) {
- /* Archive all shade kernels - they take a long time to compile. */
- return true;
- }
+ if (device_kernel >= DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND &&
+ device_kernel <= DEVICE_KERNEL_INTEGRATOR_SHADE_SHADOW) {
+ /* Archive all shade kernels - they take a long time to compile. */
+ return true;
+ }
- /* The remaining kernels are all fast to compile. They may get cached by the system shader cache,
- * but will be quick to regenerate if not. */
+ /* The remaining kernels are all fast to compile. They may get cached by the system shader
+ * cache, but will be quick to regenerate if not. */
+ }
return false;
}
@@ -358,13 +416,6 @@ void MetalKernelPipeline::compile()
const std::string function_name = std::string("cycles_metal_") +
device_kernel_as_string(device_kernel);
- int threads_per_threadgroup = this->threads_per_threadgroup;
- if (device_kernel > DEVICE_KERNEL_INTEGRATOR_MEGAKERNEL &&
- device_kernel < DEVICE_KERNEL_INTEGRATOR_RESET) {
- /* Always use 512 for the sorting kernels */
- threads_per_threadgroup = 512;
- }
-
NSString *entryPoint = [@(function_name.c_str()) copy];
NSError *error = NULL;
@@ -628,12 +679,14 @@ void MetalKernelPipeline::compile()
return;
}
- int num_threads_per_block = round_down(computePipelineState.maxTotalThreadsPerThreadgroup,
- computePipelineState.threadExecutionWidth);
- num_threads_per_block = std::max(num_threads_per_block,
- (int)computePipelineState.threadExecutionWidth);
+ if (!num_threads_per_block) {
+ num_threads_per_block = round_down(computePipelineState.maxTotalThreadsPerThreadgroup,
+ computePipelineState.threadExecutionWidth);
+ num_threads_per_block = std::max(num_threads_per_block,
+ (int)computePipelineState.threadExecutionWidth);
+ }
+
this->pipeline = computePipelineState;
- this->num_threads_per_block = num_threads_per_block;
if (@available(macOS 11.0, *)) {
if (creating_new_archive || recreate_archive) {
diff --git a/intern/cycles/device/metal/queue.h b/intern/cycles/device/metal/queue.h
index fc32740f3e1..2a6c12e2a60 100644
--- a/intern/cycles/device/metal/queue.h
+++ b/intern/cycles/device/metal/queue.h
@@ -23,7 +23,7 @@ class MetalDeviceQueue : public DeviceQueue {
~MetalDeviceQueue();
virtual int num_concurrent_states(const size_t) const override;
- virtual int num_concurrent_busy_states() const override;
+ virtual int num_concurrent_busy_states(const size_t) const override;
virtual int num_sort_partition_elements() const override;
virtual void init_execution() override;
diff --git a/intern/cycles/device/metal/queue.mm b/intern/cycles/device/metal/queue.mm
index 5ac63a16c61..c0df2c8553f 100644
--- a/intern/cycles/device/metal/queue.mm
+++ b/intern/cycles/device/metal/queue.mm
@@ -264,33 +264,46 @@ MetalDeviceQueue::~MetalDeviceQueue()
}
}
-int MetalDeviceQueue::num_concurrent_states(const size_t /*state_size*/) const
+int MetalDeviceQueue::num_concurrent_states(const size_t state_size) const
{
- /* METAL_WIP */
- /* TODO: compute automatically. */
- /* TODO: must have at least num_threads_per_block. */
- int result = 1048576;
- if (metal_device_->device_vendor == METAL_GPU_AMD) {
- result *= 2;
+ static int result = 0;
+ if (result) {
+ return result;
}
- else if (metal_device_->device_vendor == METAL_GPU_APPLE) {
+
+ result = 1048576;
+ if (metal_device_->device_vendor == METAL_GPU_APPLE) {
result *= 4;
+
+ if (MetalInfo::get_apple_gpu_architecture(metal_device_->mtlDevice) == APPLE_M2) {
+ size_t system_ram = system_physical_ram();
+ size_t allocated_so_far = [metal_device_->mtlDevice currentAllocatedSize];
+ size_t max_recommended_working_set = [metal_device_->mtlDevice recommendedMaxWorkingSetSize];
+
+ /* Determine whether we can double the state count, and leave enough GPU-available memory
+ * (1/8 the system RAM or 1GB - whichever is largest). Enlarging the state size allows us to
+ * keep dispatch sizes high and minimize work submission overheads. */
+ size_t min_headroom = std::max(system_ram / 8, size_t(1024 * 1024 * 1024));
+ size_t total_state_size = result * state_size;
+ if (max_recommended_working_set - allocated_so_far - total_state_size * 2 >= min_headroom) {
+ result *= 2;
+ metal_printf("Doubling state count to exploit available RAM (new size = %d)\n", result);
+ }
+ }
+ }
+ else if (metal_device_->device_vendor == METAL_GPU_AMD) {
+ /* METAL_WIP */
+ /* TODO: compute automatically. */
+ /* TODO: must have at least num_threads_per_block. */
+ result *= 2;
}
return result;
}
-int MetalDeviceQueue::num_concurrent_busy_states() const
+int MetalDeviceQueue::num_concurrent_busy_states(const size_t state_size) const
{
- /* METAL_WIP */
- /* TODO: compute automatically. */
- int result = 65536;
- if (metal_device_->device_vendor == METAL_GPU_AMD) {
- result *= 2;
- }
- else if (metal_device_->device_vendor == METAL_GPU_APPLE) {
- result *= 4;
- }
- return result;
+ /* A 1:4 busy:total ratio gives best rendering performance, independent of total state count. */
+ return num_concurrent_states(state_size) / 4;
}
int MetalDeviceQueue::num_sort_partition_elements() const
diff --git a/intern/cycles/device/metal/util.mm b/intern/cycles/device/metal/util.mm
index 65c67c400fe..f47638fac15 100644
--- a/intern/cycles/device/metal/util.mm
+++ b/intern/cycles/device/metal/util.mm
@@ -110,6 +110,12 @@ vector<id<MTLDevice>> const &MetalInfo::get_usable_devices()
usable |= (vendor == METAL_GPU_AMD);
}
+# if defined(MAC_OS_VERSION_13_0)
+ if (@available(macos 13.0, *)) {
+ usable |= (vendor == METAL_GPU_INTEL);
+ }
+# endif
+
if (usable) {
metal_printf("- %s\n", device_name.c_str());
[device retain];
diff --git a/intern/cycles/device/multi/device.cpp b/intern/cycles/device/multi/device.cpp
index 6904d2c2dc6..9605c6a7538 100644
--- a/intern/cycles/device/multi/device.cpp
+++ b/intern/cycles/device/multi/device.cpp
@@ -138,6 +138,15 @@ class MultiDevice : public Device {
return true;
}
+ bool load_osl_kernels() override
+ {
+ foreach (SubDevice &sub, devices)
+ if (!sub.device->load_osl_kernels())
+ return false;
+
+ return true;
+ }
+
void build_bvh(BVH *bvh, Progress &progress, bool refit) override
{
/* Try to build and share a single acceleration structure, if possible */
@@ -204,10 +213,12 @@ class MultiDevice : public Device {
virtual void *get_cpu_osl_memory() override
{
- if (devices.size() > 1) {
+ /* Always return the OSL memory of the CPU device (this works since the constructor above
+ * guarantees that CPU devices are always added to the back). */
+ if (devices.size() > 1 && devices.back().device->info.type != DEVICE_CPU) {
return NULL;
}
- return devices.front().device->get_cpu_osl_memory();
+ return devices.back().device->get_cpu_osl_memory();
}
bool is_resident(device_ptr key, Device *sub_device) override
diff --git a/intern/cycles/device/oneapi/device.cpp b/intern/cycles/device/oneapi/device.cpp
index 4aa307e9300..66d6f749e30 100644
--- a/intern/cycles/device/oneapi/device.cpp
+++ b/intern/cycles/device/oneapi/device.cpp
@@ -19,62 +19,12 @@
CCL_NAMESPACE_BEGIN
-#ifdef WITH_ONEAPI
-static OneAPIDLLInterface oneapi_dll;
-#endif
-
-#ifdef _WIN32
-# define LOAD_ONEAPI_SHARED_LIBRARY(path) (void *)(LoadLibrary(path))
-# define LOAD_ONEAPI_SHARED_LIBRARY_ERROR() GetLastError()
-# define FREE_SHARED_LIBRARY(handle) FreeLibrary((HMODULE)handle)
-# define GET_SHARED_LIBRARY_SYMBOL(handle, name) GetProcAddress((HMODULE)handle, name)
-#elif __linux__
-# define LOAD_ONEAPI_SHARED_LIBRARY(path) dlopen(path, RTLD_NOW)
-# define LOAD_ONEAPI_SHARED_LIBRARY_ERROR() dlerror()
-# define FREE_SHARED_LIBRARY(handle) dlclose(handle)
-# define GET_SHARED_LIBRARY_SYMBOL(handle, name) dlsym(handle, name)
-#endif
-
bool device_oneapi_init()
{
#if !defined(WITH_ONEAPI)
return false;
#else
- string lib_path = path_get("lib");
-# ifdef _WIN32
- lib_path = path_join(lib_path, "cycles_kernel_oneapi.dll");
-# else
- lib_path = path_join(lib_path, "cycles_kernel_oneapi.so");
-# endif
- void *lib_handle = LOAD_ONEAPI_SHARED_LIBRARY(lib_path.c_str());
-
- /* This shouldn't happen, but it still makes sense to have a branch for this. */
- if (lib_handle == NULL) {
- LOG(ERROR) << "oneAPI kernel shared library cannot be loaded: "
- << LOAD_ONEAPI_SHARED_LIBRARY_ERROR();
- return false;
- }
-
-# define DLL_INTERFACE_CALL(function, return_type, ...) \
- (oneapi_dll.function) = reinterpret_cast<decltype(oneapi_dll.function)>( \
- GET_SHARED_LIBRARY_SYMBOL(lib_handle, #function)); \
- if (oneapi_dll.function == NULL) { \
- LOG(ERROR) << "oneAPI shared library function \"" << #function \
- << "\" has not been loaded from kernel shared - disable oneAPI " \
- "library disable oneAPI implementation due to this"; \
- FREE_SHARED_LIBRARY(lib_handle); \
- return false; \
- }
-# include "kernel/device/oneapi/dll_interface_template.h"
-# undef DLL_INTERFACE_CALL
-
- VLOG_INFO << "oneAPI kernel shared library has been loaded successfully";
-
- /* We need to have this oneapi kernel shared library during all life-span of the Blender.
- * So it is not unloaded because of this.
- * FREE_SHARED_LIBRARY(lib_handle); */
-
/* NOTE(@nsirgien): we need to enable JIT cache from here and
* right now this cache policy is controlled by env. variables. */
/* NOTE(hallade) we also disable use of copy engine as it
@@ -89,7 +39,7 @@ bool device_oneapi_init()
_putenv_s("SYCL_CACHE_THRESHOLD", "0");
}
if (getenv("SYCL_DEVICE_FILTER") == nullptr) {
- _putenv_s("SYCL_DEVICE_FILTER", "host,level_zero");
+ _putenv_s("SYCL_DEVICE_FILTER", "level_zero");
}
if (getenv("SYCL_ENABLE_PCI") == nullptr) {
_putenv_s("SYCL_ENABLE_PCI", "1");
@@ -100,7 +50,7 @@ bool device_oneapi_init()
# elif __linux__
setenv("SYCL_CACHE_PERSISTENT", "1", false);
setenv("SYCL_CACHE_THRESHOLD", "0", false);
- setenv("SYCL_DEVICE_FILTER", "host,level_zero", false);
+ setenv("SYCL_DEVICE_FILTER", "level_zero", false);
setenv("SYCL_ENABLE_PCI", "1", false);
setenv("SYCL_PI_LEVEL_ZERO_USE_COPY_ENGINE_FOR_IN_ORDER_QUEUE", "0", false);
# endif
@@ -109,17 +59,10 @@ bool device_oneapi_init()
#endif
}
-#if defined(_WIN32) || defined(__linux__)
-# undef LOAD_SYCL_SHARED_LIBRARY
-# undef LOAD_ONEAPI_SHARED_LIBRARY
-# undef FREE_SHARED_LIBRARY
-# undef GET_SHARED_LIBRARY_SYMBOL
-#endif
-
Device *device_oneapi_create(const DeviceInfo &info, Stats &stats, Profiler &profiler)
{
#ifdef WITH_ONEAPI
- return new OneapiDevice(info, oneapi_dll, stats, profiler);
+ return new OneapiDevice(info, stats, profiler);
#else
(void)info;
(void)stats;
@@ -165,7 +108,7 @@ static void device_iterator_cb(const char *id, const char *name, int num, void *
void device_oneapi_info(vector<DeviceInfo> &devices)
{
#ifdef WITH_ONEAPI
- (oneapi_dll.oneapi_iterate_devices)(device_iterator_cb, &devices);
+ OneapiDevice::iterate_devices(device_iterator_cb, &devices);
#else /* WITH_ONEAPI */
(void)devices;
#endif /* WITH_ONEAPI */
@@ -175,10 +118,10 @@ string device_oneapi_capabilities()
{
string capabilities;
#ifdef WITH_ONEAPI
- char *c_capabilities = (oneapi_dll.oneapi_device_capabilities)();
+ char *c_capabilities = OneapiDevice::device_capabilities();
if (c_capabilities) {
capabilities = c_capabilities;
- (oneapi_dll.oneapi_free)(c_capabilities);
+ free(c_capabilities);
}
#endif
return capabilities;
diff --git a/intern/cycles/device/oneapi/device_impl.cpp b/intern/cycles/device/oneapi/device_impl.cpp
index dd0622a5bd5..d0ddd69289c 100644
--- a/intern/cycles/device/oneapi/device_impl.cpp
+++ b/intern/cycles/device/oneapi/device_impl.cpp
@@ -8,7 +8,7 @@
# include "util/debug.h"
# include "util/log.h"
-# include "kernel/device/oneapi/kernel.h"
+# include "kernel/device/oneapi/globals.h"
CCL_NAMESPACE_BEGIN
@@ -19,26 +19,19 @@ static void queue_error_cb(const char *message, void *user_ptr)
}
}
-OneapiDevice::OneapiDevice(const DeviceInfo &info,
- OneAPIDLLInterface &oneapi_dll_object,
- Stats &stats,
- Profiler &profiler)
+OneapiDevice::OneapiDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler)
: Device(info, stats, profiler),
device_queue_(nullptr),
texture_info_(this, "texture_info", MEM_GLOBAL),
kg_memory_(nullptr),
kg_memory_device_(nullptr),
- kg_memory_size_(0),
- oneapi_dll_(oneapi_dll_object)
+ kg_memory_size_(0)
{
need_texture_info_ = false;
- oneapi_dll_.oneapi_set_error_cb(queue_error_cb, &oneapi_error_string_);
+ oneapi_set_error_cb(queue_error_cb, &oneapi_error_string_);
- /* OneAPI calls should be initialized on this moment. */
- assert(oneapi_dll_.oneapi_create_queue != nullptr);
-
- bool is_finished_ok = oneapi_dll_.oneapi_create_queue(device_queue_, info.num);
+ bool is_finished_ok = create_queue(device_queue_, info.num);
if (is_finished_ok == false) {
set_error("oneAPI queue initialization error: got runtime exception \"" +
oneapi_error_string_ + "\"");
@@ -50,7 +43,7 @@ OneapiDevice::OneapiDevice(const DeviceInfo &info,
}
size_t globals_segment_size;
- is_finished_ok = oneapi_dll_.oneapi_kernel_globals_size(device_queue_, globals_segment_size);
+ is_finished_ok = kernel_globals_size(globals_segment_size);
if (is_finished_ok == false) {
set_error("oneAPI constant memory initialization got runtime exception \"" +
oneapi_error_string_ + "\"");
@@ -59,27 +52,27 @@ OneapiDevice::OneapiDevice(const DeviceInfo &info,
VLOG_DEBUG << "Successfully created global/constant memory segment (kernel globals object)";
}
- kg_memory_ = oneapi_dll_.oneapi_usm_aligned_alloc_host(device_queue_, globals_segment_size, 16);
- oneapi_dll_.oneapi_usm_memset(device_queue_, kg_memory_, 0, globals_segment_size);
+ kg_memory_ = usm_aligned_alloc_host(device_queue_, globals_segment_size, 16);
+ usm_memset(device_queue_, kg_memory_, 0, globals_segment_size);
- kg_memory_device_ = oneapi_dll_.oneapi_usm_alloc_device(device_queue_, globals_segment_size);
+ kg_memory_device_ = usm_alloc_device(device_queue_, globals_segment_size);
kg_memory_size_ = globals_segment_size;
- max_memory_on_device_ = oneapi_dll_.oneapi_get_memcapacity(device_queue_);
+ max_memory_on_device_ = get_memcapacity();
}
OneapiDevice::~OneapiDevice()
{
texture_info_.free();
- oneapi_dll_.oneapi_usm_free(device_queue_, kg_memory_);
- oneapi_dll_.oneapi_usm_free(device_queue_, kg_memory_device_);
+ usm_free(device_queue_, kg_memory_);
+ usm_free(device_queue_, kg_memory_device_);
for (ConstMemMap::iterator mt = const_mem_map_.begin(); mt != const_mem_map_.end(); mt++)
delete mt->second;
if (device_queue_)
- oneapi_dll_.oneapi_free_queue(device_queue_);
+ free_queue(device_queue_);
}
bool OneapiDevice::check_peer_access(Device * /*peer_device*/)
@@ -95,18 +88,26 @@ BVHLayoutMask OneapiDevice::get_bvh_layout_mask() const
bool OneapiDevice::load_kernels(const uint requested_features)
{
assert(device_queue_);
- /* NOTE(@nsirgien): oneAPI can support compilation of kernel code with certain feature set
- * with specialization constants, but it hasn't been implemented yet. */
- (void)requested_features;
- bool is_finished_ok = oneapi_dll_.oneapi_run_test_kernel(device_queue_);
+ bool is_finished_ok = oneapi_run_test_kernel(device_queue_);
if (is_finished_ok == false) {
- set_error("oneAPI kernel load: got runtime exception \"" + oneapi_error_string_ + "\"");
+ set_error("oneAPI test kernel execution: got a runtime exception \"" + oneapi_error_string_ +
+ "\"");
+ return false;
}
else {
- VLOG_INFO << "Runtime compilation done for \"" << info.description << "\"";
+ VLOG_INFO << "Test kernel has been executed successfully for \"" << info.description << "\"";
assert(device_queue_);
}
+
+ is_finished_ok = oneapi_load_kernels(device_queue_, (const unsigned int)requested_features);
+ if (is_finished_ok == false) {
+ set_error("oneAPI kernels loading: got a runtime exception \"" + oneapi_error_string_ + "\"");
+ }
+ else {
+ VLOG_INFO << "Kernels loading (compilation) has been done for \"" << info.description << "\"";
+ }
+
return is_finished_ok;
}
@@ -138,7 +139,7 @@ void OneapiDevice::generic_alloc(device_memory &mem)
* type has been used for oneAPI device in order to better fit in Cycles architecture. */
void *device_pointer = nullptr;
if (mem.memory_size() + stats.mem_used < max_memory_on_device_)
- device_pointer = oneapi_dll_.oneapi_usm_alloc_device(device_queue_, memory_size);
+ device_pointer = usm_alloc_device(device_queue_, memory_size);
if (device_pointer == nullptr) {
set_error("oneAPI kernel - device memory allocation error for " +
string_human_readable_size(mem.memory_size()) +
@@ -163,8 +164,7 @@ void OneapiDevice::generic_copy_to(device_memory &mem)
/* Copy operation from host shouldn't be requested if there is no memory allocated on host. */
assert(mem.host_pointer);
assert(device_queue_);
- oneapi_dll_.oneapi_usm_memcpy(
- device_queue_, (void *)mem.device_pointer, (void *)mem.host_pointer, memory_size);
+ usm_memcpy(device_queue_, (void *)mem.device_pointer, (void *)mem.host_pointer, memory_size);
}
/* TODO: Make sycl::queue part of OneapiQueue and avoid using pointers to sycl::queue. */
@@ -178,11 +178,6 @@ string OneapiDevice::oneapi_error_message()
return string(oneapi_error_string_);
}
-OneAPIDLLInterface OneapiDevice::oneapi_dll_object()
-{
- return oneapi_dll_;
-}
-
void *OneapiDevice::kernel_globals_device_pointer()
{
return kg_memory_device_;
@@ -198,7 +193,7 @@ void OneapiDevice::generic_free(device_memory &mem)
mem.device_size = 0;
assert(device_queue_);
- oneapi_dll_.oneapi_usm_free(device_queue_, (void *)mem.device_pointer);
+ usm_free(device_queue_, (void *)mem.device_pointer);
mem.device_pointer = 0;
}
@@ -266,8 +261,7 @@ void OneapiDevice::mem_copy_from(device_memory &mem, size_t y, size_t w, size_t
if (mem.device_pointer) {
char *shifted_host = reinterpret_cast<char *>(mem.host_pointer) + offset;
char *shifted_device = reinterpret_cast<char *>(mem.device_pointer) + offset;
- bool is_finished_ok = oneapi_dll_.oneapi_usm_memcpy(
- device_queue_, shifted_host, shifted_device, size);
+ bool is_finished_ok = usm_memcpy(device_queue_, shifted_host, shifted_device, size);
if (is_finished_ok == false) {
set_error("oneAPI memory operation error: got runtime exception \"" +
oneapi_error_string_ + "\"");
@@ -292,7 +286,7 @@ void OneapiDevice::mem_zero(device_memory &mem)
}
assert(device_queue_);
- bool is_finished_ok = oneapi_dll_.oneapi_usm_memset(
+ bool is_finished_ok = usm_memset(
device_queue_, (void *)mem.device_pointer, 0, mem.memory_size());
if (is_finished_ok == false) {
set_error("oneAPI memory operation error: got runtime exception \"" + oneapi_error_string_ +
@@ -349,10 +343,9 @@ void OneapiDevice::const_copy_to(const char *name, void *host, size_t size)
memcpy(data->data(), host, size);
data->copy_to_device();
- oneapi_dll_.oneapi_set_global_memory(
- device_queue_, kg_memory_, name, (void *)data->device_pointer);
+ set_global_memory(device_queue_, kg_memory_, name, (void *)data->device_pointer);
- oneapi_dll_.oneapi_usm_memcpy(device_queue_, kg_memory_device_, kg_memory_, kg_memory_size_);
+ usm_memcpy(device_queue_, kg_memory_device_, kg_memory_, kg_memory_size_);
}
void OneapiDevice::global_alloc(device_memory &mem)
@@ -367,10 +360,9 @@ void OneapiDevice::global_alloc(device_memory &mem)
generic_alloc(mem);
generic_copy_to(mem);
- oneapi_dll_.oneapi_set_global_memory(
- device_queue_, kg_memory_, mem.name, (void *)mem.device_pointer);
+ set_global_memory(device_queue_, kg_memory_, mem.name, (void *)mem.device_pointer);
- oneapi_dll_.oneapi_usm_memcpy(device_queue_, kg_memory_device_, kg_memory_, kg_memory_size_);
+ usm_memcpy(device_queue_, kg_memory_device_, kg_memory_, kg_memory_size_);
}
void OneapiDevice::global_free(device_memory &mem)
@@ -410,18 +402,6 @@ unique_ptr<DeviceQueue> OneapiDevice::gpu_queue_create()
return make_unique<OneapiDeviceQueue>(this);
}
-int OneapiDevice::get_num_multiprocessors()
-{
- assert(device_queue_);
- return oneapi_dll_.oneapi_get_num_multiprocessors(device_queue_);
-}
-
-int OneapiDevice::get_max_num_threads_per_multiprocessor()
-{
- assert(device_queue_);
- return oneapi_dll_.oneapi_get_max_num_threads_per_multiprocessor(device_queue_);
-}
-
bool OneapiDevice::should_use_graphics_interop()
{
/* NOTE(@nsirgien): oneAPI doesn't yet support direct writing into graphics API objects, so
@@ -432,13 +412,444 @@ bool OneapiDevice::should_use_graphics_interop()
void *OneapiDevice::usm_aligned_alloc_host(size_t memory_size, size_t alignment)
{
assert(device_queue_);
- return oneapi_dll_.oneapi_usm_aligned_alloc_host(device_queue_, memory_size, alignment);
+ return usm_aligned_alloc_host(device_queue_, memory_size, alignment);
}
void OneapiDevice::usm_free(void *usm_ptr)
{
assert(device_queue_);
- return oneapi_dll_.oneapi_usm_free(device_queue_, usm_ptr);
+ return usm_free(device_queue_, usm_ptr);
+}
+
+void OneapiDevice::check_usm(SyclQueue *queue_, const void *usm_ptr, bool allow_host = false)
+{
+# ifdef _DEBUG
+ sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
+ sycl::info::device_type device_type =
+ queue->get_device().get_info<sycl::info::device::device_type>();
+ sycl::usm::alloc usm_type = get_pointer_type(usm_ptr, queue->get_context());
+ (void)usm_type;
+ assert(usm_type == sycl::usm::alloc::device ||
+ ((device_type == sycl::info::device_type::cpu || allow_host) &&
+ usm_type == sycl::usm::alloc::host ||
+ usm_type == sycl::usm::alloc::unknown));
+# else
+ /* Silence warning about unused arguments. */
+ (void)queue_;
+ (void)usm_ptr;
+ (void)allow_host;
+# endif
+}
+
+bool OneapiDevice::create_queue(SyclQueue *&external_queue, int device_index)
+{
+ bool finished_correct = true;
+ try {
+ std::vector<sycl::device> devices = OneapiDevice::available_devices();
+ if (device_index < 0 || device_index >= devices.size()) {
+ return false;
+ }
+ sycl::queue *created_queue = new sycl::queue(devices[device_index],
+ sycl::property::queue::in_order());
+ external_queue = reinterpret_cast<SyclQueue *>(created_queue);
+ }
+ catch (sycl::exception const &e) {
+ finished_correct = false;
+ oneapi_error_string_ = e.what();
+ }
+ return finished_correct;
+}
+
+void OneapiDevice::free_queue(SyclQueue *queue_)
+{
+ assert(queue_);
+ sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
+ delete queue;
+}
+
+void *OneapiDevice::usm_aligned_alloc_host(SyclQueue *queue_, size_t memory_size, size_t alignment)
+{
+ assert(queue_);
+ sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
+ return sycl::aligned_alloc_host(alignment, memory_size, *queue);
+}
+
+void *OneapiDevice::usm_alloc_device(SyclQueue *queue_, size_t memory_size)
+{
+ assert(queue_);
+ sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
+ return sycl::malloc_device(memory_size, *queue);
+}
+
+void OneapiDevice::usm_free(SyclQueue *queue_, void *usm_ptr)
+{
+ assert(queue_);
+ sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
+ OneapiDevice::check_usm(queue_, usm_ptr, true);
+ sycl::free(usm_ptr, *queue);
+}
+
+bool OneapiDevice::usm_memcpy(SyclQueue *queue_, void *dest, void *src, size_t num_bytes)
+{
+ assert(queue_);
+ sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
+ OneapiDevice::check_usm(queue_, dest, true);
+ OneapiDevice::check_usm(queue_, src, true);
+ sycl::event mem_event = queue->memcpy(dest, src, num_bytes);
+# ifdef WITH_CYCLES_DEBUG
+ try {
+ /* NOTE(@nsirgien) Waiting on memory operation may give more precise error
+ * messages. Due to impact on occupancy, it makes sense to enable it only during Cycles debug.
+ */
+ mem_event.wait_and_throw();
+ return true;
+ }
+ catch (sycl::exception const &e) {
+ oneapi_error_string_ = e.what();
+ return false;
+ }
+# else
+ sycl::usm::alloc dest_type = get_pointer_type(dest, queue->get_context());
+ sycl::usm::alloc src_type = get_pointer_type(src, queue->get_context());
+ bool from_device_to_host = dest_type == sycl::usm::alloc::host &&
+ src_type == sycl::usm::alloc::device;
+ bool host_or_device_memop_with_offset = dest_type == sycl::usm::alloc::unknown ||
+ src_type == sycl::usm::alloc::unknown;
+ /* NOTE(@sirgienko) Host-side blocking wait on this operation is mandatory, otherwise the host
+ * may not wait until the end of the transfer before using the memory.
+ */
+ if (from_device_to_host || host_or_device_memop_with_offset)
+ mem_event.wait();
+ return true;
+# endif
+}
+
+bool OneapiDevice::usm_memset(SyclQueue *queue_,
+ void *usm_ptr,
+ unsigned char value,
+ size_t num_bytes)
+{
+ assert(queue_);
+ sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
+ OneapiDevice::check_usm(queue_, usm_ptr, true);
+ sycl::event mem_event = queue->memset(usm_ptr, value, num_bytes);
+# ifdef WITH_CYCLES_DEBUG
+ try {
+ /* NOTE(@nsirgien) Waiting on memory operation may give more precise error
+ * messages. Due to impact on occupancy, it makes sense to enable it only during Cycles debug.
+ */
+ mem_event.wait_and_throw();
+ return true;
+ }
+ catch (sycl::exception const &e) {
+ oneapi_error_string_ = e.what();
+ return false;
+ }
+# else
+ (void)mem_event;
+ return true;
+# endif
+}
+
+bool OneapiDevice::queue_synchronize(SyclQueue *queue_)
+{
+ assert(queue_);
+ sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
+ try {
+ queue->wait_and_throw();
+ return true;
+ }
+ catch (sycl::exception const &e) {
+ oneapi_error_string_ = e.what();
+ return false;
+ }
+}
+
+bool OneapiDevice::kernel_globals_size(size_t &kernel_global_size)
+{
+ kernel_global_size = sizeof(KernelGlobalsGPU);
+
+ return true;
+}
+
+void OneapiDevice::set_global_memory(SyclQueue *queue_,
+ void *kernel_globals,
+ const char *memory_name,
+ void *memory_device_pointer)
+{
+ assert(queue_);
+ assert(kernel_globals);
+ assert(memory_name);
+ assert(memory_device_pointer);
+ KernelGlobalsGPU *globals = (KernelGlobalsGPU *)kernel_globals;
+ OneapiDevice::check_usm(queue_, memory_device_pointer);
+ OneapiDevice::check_usm(queue_, kernel_globals, true);
+
+ std::string matched_name(memory_name);
+
+/* This macro will change global ptr of KernelGlobals via name matching. */
+# define KERNEL_DATA_ARRAY(type, name) \
+ else if (#name == matched_name) \
+ { \
+ globals->__##name = (type *)memory_device_pointer; \
+ return; \
+ }
+ if (false) {
+ }
+ else if ("integrator_state" == matched_name) {
+ globals->integrator_state = (IntegratorStateGPU *)memory_device_pointer;
+ return;
+ }
+ KERNEL_DATA_ARRAY(KernelData, data)
+# include "kernel/data_arrays.h"
+ else
+ {
+ std::cerr << "Can't found global/constant memory with name \"" << matched_name << "\"!"
+ << std::endl;
+ assert(false);
+ }
+# undef KERNEL_DATA_ARRAY
+}
+
+bool OneapiDevice::enqueue_kernel(KernelContext *kernel_context,
+ int kernel,
+ size_t global_size,
+ void **args)
+{
+ return oneapi_enqueue_kernel(kernel_context, kernel, global_size, args);
+}
+
+/* Compute-runtime (ie. NEO) version is what gets returned by sycl/L0 on Windows
+ * since Windows driver 101.3268. */
+/* The same min compute-runtime version is currently required across Windows and Linux.
+ * For Windows driver 101.3430, compute-runtime version is 23904. */
+static const int lowest_supported_driver_version_win = 1013430;
+static const int lowest_supported_driver_version_neo = 23904;
+
+int OneapiDevice::parse_driver_build_version(const sycl::device &device)
+{
+ const std::string &driver_version = device.get_info<sycl::info::device::driver_version>();
+ int driver_build_version = 0;
+
+ size_t second_dot_position = driver_version.find('.', driver_version.find('.') + 1);
+ if (second_dot_position == std::string::npos) {
+ std::cerr << "Unable to parse unknown Intel GPU driver version \"" << driver_version
+ << "\" does not match xx.xx.xxxxx (Linux), x.x.xxxx (L0),"
+ << " xx.xx.xxx.xxxx (Windows) for device \""
+ << device.get_info<sycl::info::device::name>() << "\"." << std::endl;
+ }
+ else {
+ try {
+ size_t third_dot_position = driver_version.find('.', second_dot_position + 1);
+ if (third_dot_position != std::string::npos) {
+ const std::string &third_number_substr = driver_version.substr(
+ second_dot_position + 1, third_dot_position - second_dot_position - 1);
+ const std::string &forth_number_substr = driver_version.substr(third_dot_position + 1);
+ if (third_number_substr.length() == 3 && forth_number_substr.length() == 4)
+ driver_build_version = std::stoi(third_number_substr) * 10000 +
+ std::stoi(forth_number_substr);
+ }
+ else {
+ const std::string &third_number_substr = driver_version.substr(second_dot_position + 1);
+ driver_build_version = std::stoi(third_number_substr);
+ }
+ }
+ catch (std::invalid_argument &) {
+ std::cerr << "Unable to parse unknown Intel GPU driver version \"" << driver_version
+ << "\" does not match xx.xx.xxxxx (Linux), x.x.xxxx (L0),"
+ << " xx.xx.xxx.xxxx (Windows) for device \""
+ << device.get_info<sycl::info::device::name>() << "\"." << std::endl;
+ }
+ }
+
+ return driver_build_version;
+}
+
+std::vector<sycl::device> OneapiDevice::available_devices()
+{
+ bool allow_all_devices = false;
+ if (getenv("CYCLES_ONEAPI_ALL_DEVICES") != nullptr) {
+ allow_all_devices = true;
+ }
+
+ const std::vector<sycl::platform> &oneapi_platforms = sycl::platform::get_platforms();
+
+ std::vector<sycl::device> available_devices;
+ for (const sycl::platform &platform : oneapi_platforms) {
+ /* ignore OpenCL platforms to avoid using the same devices through both Level-Zero and OpenCL.
+ */
+ if (platform.get_backend() == sycl::backend::opencl) {
+ continue;
+ }
+
+ const std::vector<sycl::device> &oneapi_devices =
+ (allow_all_devices) ? platform.get_devices(sycl::info::device_type::all) :
+ platform.get_devices(sycl::info::device_type::gpu);
+
+ for (const sycl::device &device : oneapi_devices) {
+ bool filter_out = false;
+ if (!allow_all_devices) {
+ /* For now we support all Intel(R) Arc(TM) devices and likely any future GPU,
+ * assuming they have either more than 96 Execution Units or not 7 threads per EU.
+ * Official support can be broaden to older and smaller GPUs once ready. */
+ if (!device.is_gpu() || platform.get_backend() != sycl::backend::ext_oneapi_level_zero) {
+ filter_out = true;
+ }
+ else {
+ /* Filtered-out defaults in-case these values aren't available. */
+ int number_of_eus = 96;
+ int threads_per_eu = 7;
+ if (device.has(sycl::aspect::ext_intel_gpu_eu_count)) {
+ number_of_eus = device.get_info<sycl::ext::intel::info::device::gpu_eu_count>();
+ }
+ if (device.has(sycl::aspect::ext_intel_gpu_hw_threads_per_eu)) {
+ threads_per_eu =
+ device.get_info<sycl::ext::intel::info::device::gpu_hw_threads_per_eu>();
+ }
+ /* This filters out all Level-Zero supported GPUs from older generation than Arc. */
+ if (number_of_eus <= 96 && threads_per_eu == 7) {
+ filter_out = true;
+ }
+ /* if not already filtered out, check driver version. */
+ if (!filter_out) {
+ int driver_build_version = parse_driver_build_version(device);
+ if ((driver_build_version > 100000 &&
+ driver_build_version < lowest_supported_driver_version_win) ||
+ driver_build_version < lowest_supported_driver_version_neo) {
+ filter_out = true;
+ }
+ }
+ }
+ }
+ if (!filter_out) {
+ available_devices.push_back(device);
+ }
+ }
+ }
+
+ return available_devices;
+}
+
+char *OneapiDevice::device_capabilities()
+{
+ std::stringstream capabilities;
+
+ const std::vector<sycl::device> &oneapi_devices = available_devices();
+ for (const sycl::device &device : oneapi_devices) {
+ const std::string &name = device.get_info<sycl::info::device::name>();
+
+ capabilities << std::string("\t") << name << "\n";
+# define WRITE_ATTR(attribute_name, attribute_variable) \
+ capabilities << "\t\tsycl::info::device::" #attribute_name "\t\t\t" << attribute_variable \
+ << "\n";
+# define GET_NUM_ATTR(attribute) \
+ { \
+ size_t attribute = (size_t)device.get_info<sycl::info::device ::attribute>(); \
+ capabilities << "\t\tsycl::info::device::" #attribute "\t\t\t" << attribute << "\n"; \
+ }
+
+ GET_NUM_ATTR(vendor_id)
+ GET_NUM_ATTR(max_compute_units)
+ GET_NUM_ATTR(max_work_item_dimensions)
+
+ sycl::id<3> max_work_item_sizes =
+ device.get_info<sycl::info::device::max_work_item_sizes<3>>();
+ WRITE_ATTR("max_work_item_sizes_dim0", ((size_t)max_work_item_sizes.get(0)))
+ WRITE_ATTR("max_work_item_sizes_dim1", ((size_t)max_work_item_sizes.get(1)))
+ WRITE_ATTR("max_work_item_sizes_dim2", ((size_t)max_work_item_sizes.get(2)))
+
+ GET_NUM_ATTR(max_work_group_size)
+ GET_NUM_ATTR(max_num_sub_groups)
+ GET_NUM_ATTR(sub_group_independent_forward_progress)
+
+ GET_NUM_ATTR(preferred_vector_width_char)
+ GET_NUM_ATTR(preferred_vector_width_short)
+ GET_NUM_ATTR(preferred_vector_width_int)
+ GET_NUM_ATTR(preferred_vector_width_long)
+ GET_NUM_ATTR(preferred_vector_width_float)
+ GET_NUM_ATTR(preferred_vector_width_double)
+ GET_NUM_ATTR(preferred_vector_width_half)
+
+ GET_NUM_ATTR(native_vector_width_char)
+ GET_NUM_ATTR(native_vector_width_short)
+ GET_NUM_ATTR(native_vector_width_int)
+ GET_NUM_ATTR(native_vector_width_long)
+ GET_NUM_ATTR(native_vector_width_float)
+ GET_NUM_ATTR(native_vector_width_double)
+ GET_NUM_ATTR(native_vector_width_half)
+
+ size_t max_clock_frequency = device.get_info<sycl::info::device::max_clock_frequency>();
+ WRITE_ATTR("max_clock_frequency", max_clock_frequency)
+
+ GET_NUM_ATTR(address_bits)
+ GET_NUM_ATTR(max_mem_alloc_size)
+
+ /* NOTE(@nsirgien): Implementation doesn't use image support as bindless images aren't
+ * supported so we always return false, even if device supports HW texture usage acceleration.
+ */
+ bool image_support = false;
+ WRITE_ATTR("image_support", (size_t)image_support)
+
+ GET_NUM_ATTR(max_parameter_size)
+ GET_NUM_ATTR(mem_base_addr_align)
+ GET_NUM_ATTR(global_mem_size)
+ GET_NUM_ATTR(local_mem_size)
+ GET_NUM_ATTR(error_correction_support)
+ GET_NUM_ATTR(profiling_timer_resolution)
+ GET_NUM_ATTR(is_available)
+
+# undef GET_NUM_ATTR
+# undef WRITE_ATTR
+ capabilities << "\n";
+ }
+
+ return ::strdup(capabilities.str().c_str());
+}
+
+void OneapiDevice::iterate_devices(OneAPIDeviceIteratorCallback cb, void *user_ptr)
+{
+ int num = 0;
+ std::vector<sycl::device> devices = OneapiDevice::available_devices();
+ for (sycl::device &device : devices) {
+ const std::string &platform_name =
+ device.get_platform().get_info<sycl::info::platform::name>();
+ std::string name = device.get_info<sycl::info::device::name>();
+ std::string id = "ONEAPI_" + platform_name + "_" + name;
+ if (device.has(sycl::aspect::ext_intel_pci_address)) {
+ id.append("_" + device.get_info<sycl::ext::intel::info::device::pci_address>());
+ }
+ (cb)(id.c_str(), name.c_str(), num, user_ptr);
+ num++;
+ }
+}
+
+size_t OneapiDevice::get_memcapacity()
+{
+ return reinterpret_cast<sycl::queue *>(device_queue_)
+ ->get_device()
+ .get_info<sycl::info::device::global_mem_size>();
+}
+
+int OneapiDevice::get_num_multiprocessors()
+{
+ const sycl::device &device = reinterpret_cast<sycl::queue *>(device_queue_)->get_device();
+ if (device.has(sycl::aspect::ext_intel_gpu_eu_count)) {
+ return device.get_info<sycl::ext::intel::info::device::gpu_eu_count>();
+ }
+ else
+ return 0;
+}
+
+int OneapiDevice::get_max_num_threads_per_multiprocessor()
+{
+ const sycl::device &device = reinterpret_cast<sycl::queue *>(device_queue_)->get_device();
+ if (device.has(sycl::aspect::ext_intel_gpu_eu_simd_width) &&
+ device.has(sycl::aspect::ext_intel_gpu_hw_threads_per_eu)) {
+ return device.get_info<sycl::ext::intel::info::device::gpu_eu_simd_width>() *
+ device.get_info<sycl::ext::intel::info::device::gpu_hw_threads_per_eu>();
+ }
+ else
+ return 0;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/oneapi/device_impl.h b/intern/cycles/device/oneapi/device_impl.h
index 6abebf98684..197cf03d60d 100644
--- a/intern/cycles/device/oneapi/device_impl.h
+++ b/intern/cycles/device/oneapi/device_impl.h
@@ -3,9 +3,12 @@
#ifdef WITH_ONEAPI
+# include <sycl/sycl.hpp>
+
# include "device/device.h"
# include "device/oneapi/device.h"
# include "device/oneapi/queue.h"
+# include "kernel/device/oneapi/kernel.h"
# include "util/map.h"
@@ -13,6 +16,11 @@ CCL_NAMESPACE_BEGIN
class DeviceQueue;
+typedef void (*OneAPIDeviceIteratorCallback)(const char *id,
+ const char *name,
+ int num,
+ void *user_ptr);
+
class OneapiDevice : public Device {
private:
SyclQueue *device_queue_;
@@ -25,16 +33,12 @@ class OneapiDevice : public Device {
void *kg_memory_device_;
size_t kg_memory_size_ = (size_t)0;
size_t max_memory_on_device_ = (size_t)0;
- OneAPIDLLInterface oneapi_dll_;
std::string oneapi_error_string_;
public:
virtual BVHLayoutMask get_bvh_layout_mask() const override;
- OneapiDevice(const DeviceInfo &info,
- OneAPIDLLInterface &oneapi_dll_object,
- Stats &stats,
- Profiler &profiler);
+ OneapiDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler);
virtual ~OneapiDevice();
@@ -50,12 +54,8 @@ class OneapiDevice : public Device {
void generic_free(device_memory &mem);
- SyclQueue *sycl_queue();
-
string oneapi_error_message();
- OneAPIDLLInterface oneapi_dll_object();
-
void *kernel_globals_device_pointer();
void mem_alloc(device_memory &mem) override;
@@ -90,13 +90,37 @@ class OneapiDevice : public Device {
virtual unique_ptr<DeviceQueue> gpu_queue_create() override;
- int get_num_multiprocessors();
- int get_max_num_threads_per_multiprocessor();
-
/* NOTE(@nsirgien): Create this methods to avoid some compilation problems on Windows with host
* side compilation (MSVC). */
void *usm_aligned_alloc_host(size_t memory_size, size_t alignment);
void usm_free(void *usm_ptr);
+
+ static std::vector<sycl::device> available_devices();
+ static char *device_capabilities();
+ static int parse_driver_build_version(const sycl::device &device);
+ static void iterate_devices(OneAPIDeviceIteratorCallback cb, void *user_ptr);
+
+ size_t get_memcapacity();
+ int get_num_multiprocessors();
+ int get_max_num_threads_per_multiprocessor();
+ bool queue_synchronize(SyclQueue *queue);
+ bool kernel_globals_size(size_t &kernel_global_size);
+ void set_global_memory(SyclQueue *queue,
+ void *kernel_globals,
+ const char *memory_name,
+ void *memory_device_pointer);
+ bool enqueue_kernel(KernelContext *kernel_context, int kernel, size_t global_size, void **args);
+ SyclQueue *sycl_queue();
+
+ protected:
+ void check_usm(SyclQueue *queue, const void *usm_ptr, bool allow_host);
+ bool create_queue(SyclQueue *&external_queue, int device_index);
+ void free_queue(SyclQueue *queue);
+ void *usm_aligned_alloc_host(SyclQueue *queue, size_t memory_size, size_t alignment);
+ void *usm_alloc_device(SyclQueue *queue, size_t memory_size);
+ void usm_free(SyclQueue *queue, void *usm_ptr);
+ bool usm_memcpy(SyclQueue *queue, void *dest, void *src, size_t num_bytes);
+ bool usm_memset(SyclQueue *queue, void *usm_ptr, unsigned char value, size_t num_bytes);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/oneapi/dll_interface.h b/intern/cycles/device/oneapi/dll_interface.h
deleted file mode 100644
index 0a888194e98..00000000000
--- a/intern/cycles/device/oneapi/dll_interface.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: Apache-2.0
- * Copyright 2011-2022 Blender Foundation */
-
-#pragma once
-
-/* Include kernel header to get access to SYCL-specific types, like SyclQueue and
- * OneAPIDeviceIteratorCallback. */
-#include "kernel/device/oneapi/kernel.h"
-
-#ifdef WITH_ONEAPI
-struct OneAPIDLLInterface {
-# define DLL_INTERFACE_CALL(function, return_type, ...) \
- return_type (*function)(__VA_ARGS__) = nullptr;
-# include "kernel/device/oneapi/dll_interface_template.h"
-# undef DLL_INTERFACE_CALL
-};
-#endif
diff --git a/intern/cycles/device/oneapi/queue.cpp b/intern/cycles/device/oneapi/queue.cpp
index 1e822e25f1a..3d019661aa8 100644
--- a/intern/cycles/device/oneapi/queue.cpp
+++ b/intern/cycles/device/oneapi/queue.cpp
@@ -22,10 +22,7 @@ struct KernelExecutionInfo {
/* OneapiDeviceQueue */
OneapiDeviceQueue::OneapiDeviceQueue(OneapiDevice *device)
- : DeviceQueue(device),
- oneapi_device_(device),
- oneapi_dll_(device->oneapi_dll_object()),
- kernel_context_(nullptr)
+ : DeviceQueue(device), oneapi_device_(device), kernel_context_(nullptr)
{
}
@@ -46,7 +43,7 @@ int OneapiDeviceQueue::num_concurrent_states(const size_t state_size) const
return num_states;
}
-int OneapiDeviceQueue::num_concurrent_busy_states() const
+int OneapiDeviceQueue::num_concurrent_busy_states(const size_t /*state_size*/) const
{
const int max_num_threads = oneapi_device_->get_num_multiprocessors() *
oneapi_device_->get_max_num_threads_per_multiprocessor();
@@ -77,18 +74,18 @@ bool OneapiDeviceQueue::enqueue(DeviceKernel kernel,
void **args = const_cast<void **>(_args.values);
- debug_enqueue(kernel, signed_kernel_work_size);
+ debug_enqueue_begin(kernel, signed_kernel_work_size);
assert(signed_kernel_work_size >= 0);
size_t kernel_work_size = (size_t)signed_kernel_work_size;
- size_t kernel_local_size = oneapi_dll_.oneapi_kernel_preferred_local_size(
+ size_t kernel_local_size = oneapi_kernel_preferred_local_size(
kernel_context_->queue, (::DeviceKernel)kernel, kernel_work_size);
size_t uniformed_kernel_work_size = round_up(kernel_work_size, kernel_local_size);
assert(kernel_context_);
/* Call the oneAPI kernel DLL to launch the requested kernel. */
- bool is_finished_ok = oneapi_dll_.oneapi_enqueue_kernel(
+ bool is_finished_ok = oneapi_device_->enqueue_kernel(
kernel_context_, kernel, uniformed_kernel_work_size, args);
if (is_finished_ok == false) {
@@ -97,6 +94,8 @@ bool OneapiDeviceQueue::enqueue(DeviceKernel kernel,
oneapi_device_->oneapi_error_message() + "\"");
}
+ debug_enqueue_end();
+
return is_finished_ok;
}
@@ -106,7 +105,7 @@ bool OneapiDeviceQueue::synchronize()
return false;
}
- bool is_finished_ok = oneapi_dll_.oneapi_queue_synchronize(oneapi_device_->sycl_queue());
+ bool is_finished_ok = oneapi_device_->queue_synchronize(oneapi_device_->sycl_queue());
if (is_finished_ok == false)
oneapi_device_->set_error("oneAPI unknown kernel execution error: got runtime exception \"" +
oneapi_device_->oneapi_error_message() + "\"");
diff --git a/intern/cycles/device/oneapi/queue.h b/intern/cycles/device/oneapi/queue.h
index 716cbfdc88c..bbd947b49cb 100644
--- a/intern/cycles/device/oneapi/queue.h
+++ b/intern/cycles/device/oneapi/queue.h
@@ -10,7 +10,7 @@
# include "device/queue.h"
# include "device/oneapi/device.h"
-# include "device/oneapi/dll_interface.h"
+# include "kernel/device/oneapi/kernel.h"
CCL_NAMESPACE_BEGIN
@@ -25,7 +25,7 @@ class OneapiDeviceQueue : public DeviceQueue {
virtual int num_concurrent_states(const size_t state_size) const override;
- virtual int num_concurrent_busy_states() const override;
+ virtual int num_concurrent_busy_states(const size_t state_size) const override;
virtual void init_execution() override;
@@ -41,9 +41,7 @@ class OneapiDeviceQueue : public DeviceQueue {
protected:
OneapiDevice *oneapi_device_;
- OneAPIDLLInterface oneapi_dll_;
KernelContext *kernel_context_;
- bool with_kernel_statistics_;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/optix/device.cpp b/intern/cycles/device/optix/device.cpp
index 68ca21374fd..58b72374a7d 100644
--- a/intern/cycles/device/optix/device.cpp
+++ b/intern/cycles/device/optix/device.cpp
@@ -9,6 +9,10 @@
#include "util/log.h"
+#ifdef WITH_OSL
+# include <OSL/oslversion.h>
+#endif
+
#ifdef WITH_OPTIX
# include <optix_function_table_definition.h>
#endif
@@ -65,6 +69,9 @@ void device_optix_info(const vector<DeviceInfo> &cuda_devices, vector<DeviceInfo
info.type = DEVICE_OPTIX;
info.id += "_OptiX";
+# if defined(WITH_OSL) && (OSL_VERSION_MINOR >= 13 || OSL_VERSION_MAJOR > 1)
+ info.has_osl = true;
+# endif
info.denoisers |= DENOISER_OPTIX;
devices.push_back(info);
diff --git a/intern/cycles/device/optix/device_impl.cpp b/intern/cycles/device/optix/device_impl.cpp
index 6c64e7106d5..02f34bf3bd0 100644
--- a/intern/cycles/device/optix/device_impl.cpp
+++ b/intern/cycles/device/optix/device_impl.cpp
@@ -312,16 +312,34 @@ OptiXDevice::~OptiXDevice()
if (optix_module != NULL) {
optixModuleDestroy(optix_module);
}
- for (unsigned int i = 0; i < 2; ++i) {
+ for (int i = 0; i < 2; ++i) {
if (builtin_modules[i] != NULL) {
optixModuleDestroy(builtin_modules[i]);
}
}
- for (unsigned int i = 0; i < NUM_PIPELINES; ++i) {
+ for (int i = 0; i < NUM_PIPELINES; ++i) {
if (pipelines[i] != NULL) {
optixPipelineDestroy(pipelines[i]);
}
}
+ for (int i = 0; i < NUM_PROGRAM_GROUPS; ++i) {
+ if (groups[i] != NULL) {
+ optixProgramGroupDestroy(groups[i]);
+ }
+ }
+
+# ifdef WITH_OSL
+ for (const OptixModule &module : osl_modules) {
+ if (module != NULL) {
+ optixModuleDestroy(module);
+ }
+ }
+ for (const OptixProgramGroup &group : osl_groups) {
+ if (group != NULL) {
+ optixProgramGroupDestroy(group);
+ }
+ }
+# endif
/* Make sure denoiser is destroyed before device context! */
if (denoiser_.optix_denoiser != nullptr) {
@@ -381,13 +399,51 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
return false;
}
+# ifdef WITH_OSL
+ const bool use_osl = (kernel_features & KERNEL_FEATURE_OSL);
+# else
+ const bool use_osl = false;
+# endif
+
+ /* Skip creating OptiX module if only doing denoising. */
+ const bool need_optix_kernels = (kernel_features &
+ (KERNEL_FEATURE_PATH_TRACING | KERNEL_FEATURE_BAKING));
+
+ /* Detect existence of OptiX kernel and SDK here early. So we can error out
+ * before compiling the CUDA kernels, to avoid failing right after when
+ * compiling the OptiX kernel. */
+ string suffix = use_osl ? "_osl" :
+ (kernel_features & (KERNEL_FEATURE_NODE_RAYTRACE | KERNEL_FEATURE_MNEE)) ?
+ "_shader_raytrace" :
+ "";
+ string ptx_filename;
+ if (need_optix_kernels) {
+ ptx_filename = path_get("lib/kernel_optix" + suffix + ".ptx");
+ if (use_adaptive_compilation() || path_file_size(ptx_filename) == -1) {
+ std::string optix_include_dir = get_optix_include_dir();
+ if (optix_include_dir.empty()) {
+ set_error(
+ "Unable to compile OptiX kernels at runtime. Set OPTIX_ROOT_DIR environment variable "
+ "to a directory containing the OptiX SDK.");
+ return false;
+ }
+ else if (!path_is_directory(optix_include_dir)) {
+ set_error(string_printf(
+ "OptiX headers not found at %s, unable to compile OptiX kernels at runtime. Install "
+ "OptiX SDK in the specified location, or set OPTIX_ROOT_DIR environment variable to a "
+ "directory containing the OptiX SDK.",
+ optix_include_dir.c_str()));
+ return false;
+ }
+ }
+ }
+
/* Load CUDA modules because we need some of the utility kernels. */
if (!CUDADevice::load_kernels(kernel_features)) {
return false;
}
- /* Skip creating OptiX module if only doing denoising. */
- if (!(kernel_features & (KERNEL_FEATURE_PATH_TRACING | KERNEL_FEATURE_BAKING))) {
+ if (!need_optix_kernels) {
return true;
}
@@ -398,18 +454,41 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
optixModuleDestroy(optix_module);
optix_module = NULL;
}
- for (unsigned int i = 0; i < 2; ++i) {
+ for (int i = 0; i < 2; ++i) {
if (builtin_modules[i] != NULL) {
optixModuleDestroy(builtin_modules[i]);
builtin_modules[i] = NULL;
}
}
- for (unsigned int i = 0; i < NUM_PIPELINES; ++i) {
+ for (int i = 0; i < NUM_PIPELINES; ++i) {
if (pipelines[i] != NULL) {
optixPipelineDestroy(pipelines[i]);
pipelines[i] = NULL;
}
}
+ for (int i = 0; i < NUM_PROGRAM_GROUPS; ++i) {
+ if (groups[i] != NULL) {
+ optixProgramGroupDestroy(groups[i]);
+ groups[i] = NULL;
+ }
+ }
+
+# ifdef WITH_OSL
+ /* Recreating base OptiX module invalidates all OSL modules too, since they link against it. */
+ for (const OptixModule &module : osl_modules) {
+ if (module != NULL) {
+ optixModuleDestroy(module);
+ }
+ }
+ osl_modules.clear();
+
+ for (const OptixProgramGroup &group : osl_groups) {
+ if (group != NULL) {
+ optixProgramGroupDestroy(group);
+ }
+ }
+ osl_groups.clear();
+# endif
OptixModuleCompileOptions module_options = {};
module_options.maxRegisterCount = 0; /* Do not set an explicit register limit. */
@@ -430,7 +509,6 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
module_options.numPayloadTypes = 0;
# endif
- OptixPipelineCompileOptions pipeline_options = {};
/* Default to no motion blur and two-level graph, since it is the fastest option. */
pipeline_options.usesMotionBlur = false;
pipeline_options.traversableGraphFlags =
@@ -459,9 +537,7 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
/* Keep track of whether motion blur is enabled, so to enable/disable motion in BVH builds
* This is necessary since objects may be reported to have motion if the Vector pass is
* active, but may still need to be rendered without motion blur if that isn't active as well. */
- motion_blur = (kernel_features & KERNEL_FEATURE_OBJECT_MOTION) != 0;
-
- if (motion_blur) {
+ if (kernel_features & KERNEL_FEATURE_OBJECT_MOTION) {
pipeline_options.usesMotionBlur = true;
/* Motion blur can insert motion transforms into the traversal graph.
* It is no longer a two-level graph then, so need to set flags to allow any configuration. */
@@ -469,33 +545,10 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
}
{ /* Load and compile PTX module with OptiX kernels. */
- string ptx_data, ptx_filename = path_get(
- (kernel_features & (KERNEL_FEATURE_NODE_RAYTRACE | KERNEL_FEATURE_MNEE)) ?
- "lib/kernel_optix_shader_raytrace.ptx" :
- "lib/kernel_optix.ptx");
+ string ptx_data;
if (use_adaptive_compilation() || path_file_size(ptx_filename) == -1) {
- std::string optix_include_dir = get_optix_include_dir();
- if (optix_include_dir.empty()) {
- set_error(
- "Unable to compile OptiX kernels at runtime. Set OPTIX_ROOT_DIR environment variable "
- "to a directory containing the OptiX SDK.");
- return false;
- }
- else if (!path_is_directory(optix_include_dir)) {
- set_error(string_printf(
- "OptiX headers not found at %s, unable to compile OptiX kernels at runtime. Install "
- "OptiX SDK in the specified location, or set OPTIX_ROOT_DIR environment variable to a "
- "directory containing the OptiX SDK.",
- optix_include_dir.c_str()));
- return false;
- }
- ptx_filename = compile_kernel(
- kernel_features,
- (kernel_features & (KERNEL_FEATURE_NODE_RAYTRACE | KERNEL_FEATURE_MNEE)) ?
- "kernel_shader_raytrace" :
- "kernel",
- "optix",
- true);
+ string cflags = compile_kernel_get_common_cflags(kernel_features);
+ ptx_filename = compile_kernel(cflags, ("kernel" + suffix).c_str(), "optix", true);
}
if (ptx_filename.empty() || !path_read_text(ptx_filename, ptx_data)) {
set_error(string_printf("Failed to load OptiX kernel from '%s'", ptx_filename.c_str()));
@@ -537,7 +590,6 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
}
/* Create program groups. */
- OptixProgramGroup groups[NUM_PROGRAM_GROUPS] = {};
OptixProgramGroupDesc group_descs[NUM_PROGRAM_GROUPS] = {};
OptixProgramGroupOptions group_options = {}; /* There are no options currently. */
group_descs[PG_RGEN_INTERSECT_CLOSEST].kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
@@ -595,7 +647,7 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
group_descs[PG_HITS].hitgroup.moduleIS = builtin_modules[0];
group_descs[PG_HITS].hitgroup.entryFunctionNameIS = nullptr;
- if (motion_blur) {
+ if (pipeline_options.usesMotionBlur) {
builtin_options.usesMotionBlur = true;
optix_assert(optixBuiltinISModuleGet(
@@ -616,7 +668,6 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
}
}
- /* Pointclouds */
if (kernel_features & KERNEL_FEATURE_POINTCLOUD) {
group_descs[PG_HITD_POINTCLOUD] = group_descs[PG_HITD];
group_descs[PG_HITD_POINTCLOUD].kind = OPTIX_PROGRAM_GROUP_KIND_HITGROUP;
@@ -628,8 +679,8 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
group_descs[PG_HITS_POINTCLOUD].hitgroup.entryFunctionNameIS = "__intersection__point";
}
+ /* Add hit group for local intersections. */
if (kernel_features & (KERNEL_FEATURE_SUBSURFACE | KERNEL_FEATURE_NODE_RAYTRACE)) {
- /* Add hit group for local intersections. */
group_descs[PG_HITL].kind = OPTIX_PROGRAM_GROUP_KIND_HITGROUP;
group_descs[PG_HITL].hitgroup.moduleAH = optix_module;
group_descs[PG_HITL].hitgroup.entryFunctionNameAH = "__anyhit__kernel_optix_local_hit";
@@ -641,16 +692,19 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
group_descs[PG_RGEN_SHADE_SURFACE_RAYTRACE].raygen.module = optix_module;
group_descs[PG_RGEN_SHADE_SURFACE_RAYTRACE].raygen.entryFunctionName =
"__raygen__kernel_optix_integrator_shade_surface_raytrace";
- group_descs[PG_CALL_SVM_AO].kind = OPTIX_PROGRAM_GROUP_KIND_CALLABLES;
- group_descs[PG_CALL_SVM_AO].callables.moduleDC = optix_module;
- group_descs[PG_CALL_SVM_AO].callables.entryFunctionNameDC = "__direct_callable__svm_node_ao";
- group_descs[PG_CALL_SVM_BEVEL].kind = OPTIX_PROGRAM_GROUP_KIND_CALLABLES;
- group_descs[PG_CALL_SVM_BEVEL].callables.moduleDC = optix_module;
- group_descs[PG_CALL_SVM_BEVEL].callables.entryFunctionNameDC =
- "__direct_callable__svm_node_bevel";
+
+ /* Kernels with OSL support are built without SVM, so can skip those direct callables there. */
+ if (!use_osl) {
+ group_descs[PG_CALL_SVM_AO].kind = OPTIX_PROGRAM_GROUP_KIND_CALLABLES;
+ group_descs[PG_CALL_SVM_AO].callables.moduleDC = optix_module;
+ group_descs[PG_CALL_SVM_AO].callables.entryFunctionNameDC = "__direct_callable__svm_node_ao";
+ group_descs[PG_CALL_SVM_BEVEL].kind = OPTIX_PROGRAM_GROUP_KIND_CALLABLES;
+ group_descs[PG_CALL_SVM_BEVEL].callables.moduleDC = optix_module;
+ group_descs[PG_CALL_SVM_BEVEL].callables.entryFunctionNameDC =
+ "__direct_callable__svm_node_bevel";
+ }
}
- /* MNEE. */
if (kernel_features & KERNEL_FEATURE_MNEE) {
group_descs[PG_RGEN_SHADE_SURFACE_MNEE].kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
group_descs[PG_RGEN_SHADE_SURFACE_MNEE].raygen.module = optix_module;
@@ -658,6 +712,42 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
"__raygen__kernel_optix_integrator_shade_surface_mnee";
}
+ /* OSL uses direct callables to execute, so shading needs to be done in OptiX if OSL is used. */
+ if (use_osl) {
+ group_descs[PG_RGEN_SHADE_BACKGROUND].kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
+ group_descs[PG_RGEN_SHADE_BACKGROUND].raygen.module = optix_module;
+ group_descs[PG_RGEN_SHADE_BACKGROUND].raygen.entryFunctionName =
+ "__raygen__kernel_optix_integrator_shade_background";
+ group_descs[PG_RGEN_SHADE_LIGHT].kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
+ group_descs[PG_RGEN_SHADE_LIGHT].raygen.module = optix_module;
+ group_descs[PG_RGEN_SHADE_LIGHT].raygen.entryFunctionName =
+ "__raygen__kernel_optix_integrator_shade_light";
+ group_descs[PG_RGEN_SHADE_SURFACE].kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
+ group_descs[PG_RGEN_SHADE_SURFACE].raygen.module = optix_module;
+ group_descs[PG_RGEN_SHADE_SURFACE].raygen.entryFunctionName =
+ "__raygen__kernel_optix_integrator_shade_surface";
+ group_descs[PG_RGEN_SHADE_VOLUME].kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
+ group_descs[PG_RGEN_SHADE_VOLUME].raygen.module = optix_module;
+ group_descs[PG_RGEN_SHADE_VOLUME].raygen.entryFunctionName =
+ "__raygen__kernel_optix_integrator_shade_volume";
+ group_descs[PG_RGEN_SHADE_SHADOW].kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
+ group_descs[PG_RGEN_SHADE_SHADOW].raygen.module = optix_module;
+ group_descs[PG_RGEN_SHADE_SHADOW].raygen.entryFunctionName =
+ "__raygen__kernel_optix_integrator_shade_shadow";
+ group_descs[PG_RGEN_EVAL_DISPLACE].kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
+ group_descs[PG_RGEN_EVAL_DISPLACE].raygen.module = optix_module;
+ group_descs[PG_RGEN_EVAL_DISPLACE].raygen.entryFunctionName =
+ "__raygen__kernel_optix_shader_eval_displace";
+ group_descs[PG_RGEN_EVAL_BACKGROUND].kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
+ group_descs[PG_RGEN_EVAL_BACKGROUND].raygen.module = optix_module;
+ group_descs[PG_RGEN_EVAL_BACKGROUND].raygen.entryFunctionName =
+ "__raygen__kernel_optix_shader_eval_background";
+ group_descs[PG_RGEN_EVAL_CURVE_SHADOW_TRANSPARENCY].kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
+ group_descs[PG_RGEN_EVAL_CURVE_SHADOW_TRANSPARENCY].raygen.module = optix_module;
+ group_descs[PG_RGEN_EVAL_CURVE_SHADOW_TRANSPARENCY].raygen.entryFunctionName =
+ "__raygen__kernel_optix_shader_eval_curve_shadow_transparency";
+ }
+
optix_assert(optixProgramGroupCreate(
context, group_descs, NUM_PROGRAM_GROUPS, &group_options, nullptr, 0, groups));
@@ -666,7 +756,7 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
/* Set up SBT, which in this case is used only to select between different programs. */
sbt_data.alloc(NUM_PROGRAM_GROUPS);
memset(sbt_data.host_pointer, 0, sizeof(SbtRecord) * NUM_PROGRAM_GROUPS);
- for (unsigned int i = 0; i < NUM_PROGRAM_GROUPS; ++i) {
+ for (int i = 0; i < NUM_PROGRAM_GROUPS; ++i) {
optix_assert(optixSbtRecordPackHeader(groups[i], &sbt_data[i]));
optix_assert(optixProgramGroupGetStackSize(groups[i], &stack_size[i]));
}
@@ -690,25 +780,26 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
OptixPipelineLinkOptions link_options = {};
link_options.maxTraceDepth = 1;
+ link_options.debugLevel = module_options.debugLevel;
- if (DebugFlags().optix.use_debug) {
- link_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_FULL;
- }
- else {
- link_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_NONE;
- }
-
- if (kernel_features & KERNEL_FEATURE_NODE_RAYTRACE) {
- /* Create shader raytracing pipeline. */
+ if (kernel_features & (KERNEL_FEATURE_NODE_RAYTRACE | KERNEL_FEATURE_MNEE) && !use_osl) {
+ /* Create shader raytracing and MNEE pipeline. */
vector<OptixProgramGroup> pipeline_groups;
pipeline_groups.reserve(NUM_PROGRAM_GROUPS);
- pipeline_groups.push_back(groups[PG_RGEN_SHADE_SURFACE_RAYTRACE]);
+ if (kernel_features & KERNEL_FEATURE_NODE_RAYTRACE) {
+ pipeline_groups.push_back(groups[PG_RGEN_SHADE_SURFACE_RAYTRACE]);
+ pipeline_groups.push_back(groups[PG_CALL_SVM_AO]);
+ pipeline_groups.push_back(groups[PG_CALL_SVM_BEVEL]);
+ }
+ if (kernel_features & KERNEL_FEATURE_MNEE) {
+ pipeline_groups.push_back(groups[PG_RGEN_SHADE_SURFACE_MNEE]);
+ }
pipeline_groups.push_back(groups[PG_MISS]);
pipeline_groups.push_back(groups[PG_HITD]);
pipeline_groups.push_back(groups[PG_HITS]);
pipeline_groups.push_back(groups[PG_HITL]);
pipeline_groups.push_back(groups[PG_HITV]);
- if (motion_blur) {
+ if (pipeline_options.usesMotionBlur) {
pipeline_groups.push_back(groups[PG_HITD_MOTION]);
pipeline_groups.push_back(groups[PG_HITS_MOTION]);
}
@@ -716,8 +807,6 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
pipeline_groups.push_back(groups[PG_HITD_POINTCLOUD]);
pipeline_groups.push_back(groups[PG_HITS_POINTCLOUD]);
}
- pipeline_groups.push_back(groups[PG_CALL_SVM_AO]);
- pipeline_groups.push_back(groups[PG_CALL_SVM_BEVEL]);
optix_assert(optixPipelineCreate(context,
&pipeline_options,
@@ -726,30 +815,33 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
pipeline_groups.size(),
nullptr,
0,
- &pipelines[PIP_SHADE_RAYTRACE]));
+ &pipelines[PIP_SHADE]));
/* Combine ray generation and trace continuation stack size. */
- const unsigned int css = stack_size[PG_RGEN_SHADE_SURFACE_RAYTRACE].cssRG +
+ const unsigned int css = std::max(stack_size[PG_RGEN_SHADE_SURFACE_RAYTRACE].cssRG,
+ stack_size[PG_RGEN_SHADE_SURFACE_MNEE].cssRG) +
link_options.maxTraceDepth * trace_css;
const unsigned int dss = std::max(stack_size[PG_CALL_SVM_AO].dssDC,
stack_size[PG_CALL_SVM_BEVEL].dssDC);
/* Set stack size depending on pipeline options. */
optix_assert(optixPipelineSetStackSize(
- pipelines[PIP_SHADE_RAYTRACE], 0, dss, css, motion_blur ? 3 : 2));
+ pipelines[PIP_SHADE], 0, dss, css, pipeline_options.usesMotionBlur ? 3 : 2));
}
- if (kernel_features & KERNEL_FEATURE_MNEE) {
- /* Create MNEE pipeline. */
+ { /* Create intersection-only pipeline. */
vector<OptixProgramGroup> pipeline_groups;
pipeline_groups.reserve(NUM_PROGRAM_GROUPS);
- pipeline_groups.push_back(groups[PG_RGEN_SHADE_SURFACE_MNEE]);
+ pipeline_groups.push_back(groups[PG_RGEN_INTERSECT_CLOSEST]);
+ pipeline_groups.push_back(groups[PG_RGEN_INTERSECT_SHADOW]);
+ pipeline_groups.push_back(groups[PG_RGEN_INTERSECT_SUBSURFACE]);
+ pipeline_groups.push_back(groups[PG_RGEN_INTERSECT_VOLUME_STACK]);
pipeline_groups.push_back(groups[PG_MISS]);
pipeline_groups.push_back(groups[PG_HITD]);
pipeline_groups.push_back(groups[PG_HITS]);
pipeline_groups.push_back(groups[PG_HITL]);
pipeline_groups.push_back(groups[PG_HITV]);
- if (motion_blur) {
+ if (pipeline_options.usesMotionBlur) {
pipeline_groups.push_back(groups[PG_HITD_MOTION]);
pipeline_groups.push_back(groups[PG_HITS_MOTION]);
}
@@ -757,8 +849,6 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
pipeline_groups.push_back(groups[PG_HITD_POINTCLOUD]);
pipeline_groups.push_back(groups[PG_HITS_POINTCLOUD]);
}
- pipeline_groups.push_back(groups[PG_CALL_SVM_AO]);
- pipeline_groups.push_back(groups[PG_CALL_SVM_BEVEL]);
optix_assert(optixPipelineCreate(context,
&pipeline_options,
@@ -767,37 +857,234 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
pipeline_groups.size(),
nullptr,
0,
- &pipelines[PIP_SHADE_MNEE]));
+ &pipelines[PIP_INTERSECT]));
- /* Combine ray generation and trace continuation stack size. */
- const unsigned int css = stack_size[PG_RGEN_SHADE_SURFACE_MNEE].cssRG +
- link_options.maxTraceDepth * trace_css;
- const unsigned int dss = 0;
+ /* Calculate continuation stack size based on the maximum of all ray generation stack sizes. */
+ const unsigned int css =
+ std::max(stack_size[PG_RGEN_INTERSECT_CLOSEST].cssRG,
+ std::max(stack_size[PG_RGEN_INTERSECT_SHADOW].cssRG,
+ std::max(stack_size[PG_RGEN_INTERSECT_SUBSURFACE].cssRG,
+ stack_size[PG_RGEN_INTERSECT_VOLUME_STACK].cssRG))) +
+ link_options.maxTraceDepth * trace_css;
- /* Set stack size depending on pipeline options. */
- optix_assert(
- optixPipelineSetStackSize(pipelines[PIP_SHADE_MNEE], 0, dss, css, motion_blur ? 3 : 2));
+ optix_assert(optixPipelineSetStackSize(
+ pipelines[PIP_INTERSECT], 0, 0, css, pipeline_options.usesMotionBlur ? 3 : 2));
}
- { /* Create intersection-only pipeline. */
+ return !have_error();
+}
+
+bool OptiXDevice::load_osl_kernels()
+{
+# ifdef WITH_OSL
+ if (have_error()) {
+ return false;
+ }
+
+ struct OSLKernel {
+ string ptx;
+ string init_entry;
+ string exec_entry;
+ };
+
+ /* This has to be in the same order as the ShaderType enum, so that the index calculation in
+ * osl_eval_nodes checks out */
+ vector<OSLKernel> osl_kernels;
+
+ for (ShaderType type = SHADER_TYPE_SURFACE; type <= SHADER_TYPE_BUMP;
+ type = static_cast<ShaderType>(type + 1)) {
+ const vector<OSL::ShaderGroupRef> &groups = (type == SHADER_TYPE_SURFACE ?
+ osl_globals.surface_state :
+ type == SHADER_TYPE_VOLUME ?
+ osl_globals.volume_state :
+ type == SHADER_TYPE_DISPLACEMENT ?
+ osl_globals.displacement_state :
+ osl_globals.bump_state);
+ for (const OSL::ShaderGroupRef &group : groups) {
+ if (group) {
+ string osl_ptx, init_name, entry_name;
+ osl_globals.ss->getattribute(group.get(), "group_init_name", init_name);
+ osl_globals.ss->getattribute(group.get(), "group_entry_name", entry_name);
+ osl_globals.ss->getattribute(
+ group.get(), "ptx_compiled_version", OSL::TypeDesc::PTR, &osl_ptx);
+
+ int groupdata_size = 0;
+ osl_globals.ss->getattribute(group.get(), "groupdata_size", groupdata_size);
+ if (groupdata_size > 2048) { /* See 'group_data' array in kernel/osl/osl.h */
+ set_error(
+ string_printf("Requested OSL group data size (%d) is greater than the maximum "
+ "supported with OptiX (2048)",
+ groupdata_size));
+ return false;
+ }
+
+ osl_kernels.push_back({std::move(osl_ptx), std::move(init_name), std::move(entry_name)});
+ }
+ else {
+ /* Add empty entry for non-existent shader groups, so that the index stays stable. */
+ osl_kernels.emplace_back();
+ }
+ }
+ }
+
+ const CUDAContextScope scope(this);
+
+ if (pipelines[PIP_SHADE]) {
+ optixPipelineDestroy(pipelines[PIP_SHADE]);
+ }
+
+ for (OptixModule &module : osl_modules) {
+ if (module != NULL) {
+ optixModuleDestroy(module);
+ module = NULL;
+ }
+ }
+ for (OptixProgramGroup &group : osl_groups) {
+ if (group != NULL) {
+ optixProgramGroupDestroy(group);
+ group = NULL;
+ }
+ }
+
+ OptixProgramGroupOptions group_options = {}; /* There are no options currently. */
+ OptixModuleCompileOptions module_options = {};
+ module_options.optLevel = OPTIX_COMPILE_OPTIMIZATION_LEVEL_3;
+ module_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_NONE;
+
+ osl_groups.resize(osl_kernels.size() * 2 + 1);
+ osl_modules.resize(osl_kernels.size() + 1);
+
+ { /* Load and compile PTX module with OSL services. */
+ string ptx_data, ptx_filename = path_get("lib/kernel_optix_osl_services.ptx");
+ if (!path_read_text(ptx_filename, ptx_data)) {
+ set_error(string_printf("Failed to load OptiX OSL services kernel from '%s'",
+ ptx_filename.c_str()));
+ return false;
+ }
+
+ const OptixResult result = optixModuleCreateFromPTX(context,
+ &module_options,
+ &pipeline_options,
+ ptx_data.data(),
+ ptx_data.size(),
+ nullptr,
+ 0,
+ &osl_modules.back());
+ if (result != OPTIX_SUCCESS) {
+ set_error(string_printf("Failed to load OptiX OSL services kernel from '%s' (%s)",
+ ptx_filename.c_str(),
+ optixGetErrorName(result)));
+ return false;
+ }
+
+ OptixProgramGroupDesc group_desc = {};
+ group_desc.kind = OPTIX_PROGRAM_GROUP_KIND_CALLABLES;
+ group_desc.callables.entryFunctionNameDC = "__direct_callable__dummy_services";
+ group_desc.callables.moduleDC = osl_modules.back();
+
+ optix_assert(optixProgramGroupCreate(
+ context, &group_desc, 1, &group_options, nullptr, 0, &osl_groups.back()));
+ }
+
+ TaskPool pool;
+ vector<OptixResult> results(osl_kernels.size(), OPTIX_SUCCESS);
+
+ for (size_t i = 0; i < osl_kernels.size(); ++i) {
+ if (osl_kernels[i].ptx.empty()) {
+ continue;
+ }
+
+# if OPTIX_ABI_VERSION >= 55
+ OptixTask task = nullptr;
+ results[i] = optixModuleCreateFromPTXWithTasks(context,
+ &module_options,
+ &pipeline_options,
+ osl_kernels[i].ptx.data(),
+ osl_kernels[i].ptx.size(),
+ nullptr,
+ nullptr,
+ &osl_modules[i],
+ &task);
+ if (results[i] == OPTIX_SUCCESS) {
+ execute_optix_task(pool, task, results[i]);
+ }
+# else
+ pool.push([this, &results, i, &module_options, &osl_kernels]() {
+ results[i] = optixModuleCreateFromPTX(context,
+ &module_options,
+ &pipeline_options,
+ osl_kernels[i].ptx.data(),
+ osl_kernels[i].ptx.size(),
+ nullptr,
+ 0,
+ &osl_modules[i]);
+ });
+# endif
+ }
+
+ pool.wait_work();
+
+ for (size_t i = 0; i < osl_kernels.size(); ++i) {
+ if (osl_kernels[i].ptx.empty()) {
+ continue;
+ }
+
+ if (results[i] != OPTIX_SUCCESS) {
+ set_error(string_printf("Failed to load OptiX OSL kernel for %s (%s)",
+ osl_kernels[i].init_entry.c_str(),
+ optixGetErrorName(results[i])));
+ return false;
+ }
+
+ OptixProgramGroupDesc group_descs[2] = {};
+ group_descs[0].kind = OPTIX_PROGRAM_GROUP_KIND_CALLABLES;
+ group_descs[0].callables.entryFunctionNameDC = osl_kernels[i].init_entry.c_str();
+ group_descs[0].callables.moduleDC = osl_modules[i];
+ group_descs[1].kind = OPTIX_PROGRAM_GROUP_KIND_CALLABLES;
+ group_descs[1].callables.entryFunctionNameDC = osl_kernels[i].exec_entry.c_str();
+ group_descs[1].callables.moduleDC = osl_modules[i];
+
+ optix_assert(optixProgramGroupCreate(
+ context, group_descs, 2, &group_options, nullptr, 0, &osl_groups[i * 2]));
+ }
+
+ vector<OptixStackSizes> osl_stack_size(osl_groups.size());
+
+ /* Update SBT with new entries. */
+ sbt_data.alloc(NUM_PROGRAM_GROUPS + osl_groups.size());
+ for (int i = 0; i < NUM_PROGRAM_GROUPS; ++i) {
+ optix_assert(optixSbtRecordPackHeader(groups[i], &sbt_data[i]));
+ }
+ for (size_t i = 0; i < osl_groups.size(); ++i) {
+ if (osl_groups[i] != NULL) {
+ optix_assert(optixSbtRecordPackHeader(osl_groups[i], &sbt_data[NUM_PROGRAM_GROUPS + i]));
+ optix_assert(optixProgramGroupGetStackSize(osl_groups[i], &osl_stack_size[i]));
+ }
+ }
+ sbt_data.copy_to_device(); /* Upload updated SBT to device. */
+
+ OptixPipelineLinkOptions link_options = {};
+ link_options.maxTraceDepth = 0;
+ link_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_NONE;
+
+ {
vector<OptixProgramGroup> pipeline_groups;
pipeline_groups.reserve(NUM_PROGRAM_GROUPS);
- pipeline_groups.push_back(groups[PG_RGEN_INTERSECT_CLOSEST]);
- pipeline_groups.push_back(groups[PG_RGEN_INTERSECT_SHADOW]);
- pipeline_groups.push_back(groups[PG_RGEN_INTERSECT_SUBSURFACE]);
- pipeline_groups.push_back(groups[PG_RGEN_INTERSECT_VOLUME_STACK]);
- pipeline_groups.push_back(groups[PG_MISS]);
- pipeline_groups.push_back(groups[PG_HITD]);
- pipeline_groups.push_back(groups[PG_HITS]);
- pipeline_groups.push_back(groups[PG_HITL]);
- pipeline_groups.push_back(groups[PG_HITV]);
- if (motion_blur) {
- pipeline_groups.push_back(groups[PG_HITD_MOTION]);
- pipeline_groups.push_back(groups[PG_HITS_MOTION]);
- }
- if (kernel_features & KERNEL_FEATURE_POINTCLOUD) {
- pipeline_groups.push_back(groups[PG_HITD_POINTCLOUD]);
- pipeline_groups.push_back(groups[PG_HITS_POINTCLOUD]);
+ pipeline_groups.push_back(groups[PG_RGEN_SHADE_BACKGROUND]);
+ pipeline_groups.push_back(groups[PG_RGEN_SHADE_LIGHT]);
+ pipeline_groups.push_back(groups[PG_RGEN_SHADE_SURFACE]);
+ pipeline_groups.push_back(groups[PG_RGEN_SHADE_SURFACE_RAYTRACE]);
+ pipeline_groups.push_back(groups[PG_RGEN_SHADE_SURFACE_MNEE]);
+ pipeline_groups.push_back(groups[PG_RGEN_SHADE_VOLUME]);
+ pipeline_groups.push_back(groups[PG_RGEN_SHADE_SHADOW]);
+ pipeline_groups.push_back(groups[PG_RGEN_EVAL_DISPLACE]);
+ pipeline_groups.push_back(groups[PG_RGEN_EVAL_BACKGROUND]);
+ pipeline_groups.push_back(groups[PG_RGEN_EVAL_CURVE_SHADOW_TRANSPARENCY]);
+
+ for (const OptixProgramGroup &group : osl_groups) {
+ if (group != NULL) {
+ pipeline_groups.push_back(group);
+ }
}
optix_assert(optixPipelineCreate(context,
@@ -807,26 +1094,30 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
pipeline_groups.size(),
nullptr,
0,
- &pipelines[PIP_INTERSECT]));
+ &pipelines[PIP_SHADE]));
- /* Calculate continuation stack size based on the maximum of all ray generation stack sizes. */
- const unsigned int css =
- std::max(stack_size[PG_RGEN_INTERSECT_CLOSEST].cssRG,
- std::max(stack_size[PG_RGEN_INTERSECT_SHADOW].cssRG,
- std::max(stack_size[PG_RGEN_INTERSECT_SUBSURFACE].cssRG,
- stack_size[PG_RGEN_INTERSECT_VOLUME_STACK].cssRG))) +
- link_options.maxTraceDepth * trace_css;
+ unsigned int dss = 0;
+ for (unsigned int i = 0; i < osl_stack_size.size(); ++i) {
+ dss = std::max(dss, osl_stack_size[i].dssDC);
+ }
- optix_assert(
- optixPipelineSetStackSize(pipelines[PIP_INTERSECT], 0, 0, css, motion_blur ? 3 : 2));
+ optix_assert(optixPipelineSetStackSize(
+ pipelines[PIP_SHADE], 0, dss, 0, pipeline_options.usesMotionBlur ? 3 : 2));
}
- /* Clean up program group objects. */
- for (unsigned int i = 0; i < NUM_PROGRAM_GROUPS; ++i) {
- optixProgramGroupDestroy(groups[i]);
- }
+ return !have_error();
+# else
+ return false;
+# endif
+}
- return true;
+void *OptiXDevice::get_cpu_osl_memory()
+{
+# ifdef WITH_OSL
+ return &osl_globals;
+# else
+ return NULL;
+# endif
}
/* --------------------------------------------------------------------
@@ -1553,7 +1844,7 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
size_t num_motion_steps = 1;
Attribute *motion_keys = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- if (motion_blur && hair->get_use_motion_blur() && motion_keys) {
+ if (pipeline_options.usesMotionBlur && hair->get_use_motion_blur() && motion_keys) {
num_motion_steps = hair->get_motion_steps();
}
@@ -1707,7 +1998,7 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
size_t num_motion_steps = 1;
Attribute *motion_keys = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- if (motion_blur && mesh->get_use_motion_blur() && motion_keys) {
+ if (pipeline_options.usesMotionBlur && mesh->get_use_motion_blur() && motion_keys) {
num_motion_steps = mesh->get_motion_steps();
}
@@ -1774,7 +2065,7 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
size_t num_motion_steps = 1;
Attribute *motion_points = pointcloud->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- if (motion_blur && pointcloud->get_use_motion_blur() && motion_points) {
+ if (pipeline_options.usesMotionBlur && pointcloud->get_use_motion_blur() && motion_points) {
num_motion_steps = pointcloud->get_motion_steps();
}
@@ -1871,7 +2162,7 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
/* Calculate total motion transform size and allocate memory for them. */
size_t motion_transform_offset = 0;
- if (motion_blur) {
+ if (pipeline_options.usesMotionBlur) {
size_t total_motion_transform_size = 0;
for (Object *const ob : bvh->objects) {
if (ob->is_traceable() && ob->use_motion()) {
@@ -1922,7 +2213,7 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
if (ob->get_geometry()->geometry_type == Geometry::HAIR &&
static_cast<const Hair *>(ob->get_geometry())->curve_shape == CURVE_THICK) {
- if (motion_blur && ob->get_geometry()->has_motion_blur()) {
+ if (pipeline_options.usesMotionBlur && ob->get_geometry()->has_motion_blur()) {
/* Select between motion blur and non-motion blur built-in intersection module. */
instance.sbtOffset = PG_HITD_MOTION - PG_HITD;
}
@@ -1950,7 +2241,7 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
}
/* Insert motion traversable if object has motion. */
- if (motion_blur && ob->use_motion()) {
+ if (pipeline_options.usesMotionBlur && ob->use_motion()) {
size_t motion_keys = max(ob->get_motion().size(), (size_t)2) - 2;
size_t motion_transform_size = sizeof(OptixSRTMotionTransform) +
motion_keys * sizeof(OptixSRTData);
diff --git a/intern/cycles/device/optix/device_impl.h b/intern/cycles/device/optix/device_impl.h
index 817afdc8384..ad0e7b93454 100644
--- a/intern/cycles/device/optix/device_impl.h
+++ b/intern/cycles/device/optix/device_impl.h
@@ -9,6 +9,7 @@
# include "device/cuda/device_impl.h"
# include "device/optix/queue.h"
# include "device/optix/util.h"
+# include "kernel/osl/globals.h"
# include "kernel/types.h"
# include "util/unique_ptr.h"
@@ -23,8 +24,16 @@ enum {
PG_RGEN_INTERSECT_SHADOW,
PG_RGEN_INTERSECT_SUBSURFACE,
PG_RGEN_INTERSECT_VOLUME_STACK,
+ PG_RGEN_SHADE_BACKGROUND,
+ PG_RGEN_SHADE_LIGHT,
+ PG_RGEN_SHADE_SURFACE,
PG_RGEN_SHADE_SURFACE_RAYTRACE,
PG_RGEN_SHADE_SURFACE_MNEE,
+ PG_RGEN_SHADE_VOLUME,
+ PG_RGEN_SHADE_SHADOW,
+ PG_RGEN_EVAL_DISPLACE,
+ PG_RGEN_EVAL_BACKGROUND,
+ PG_RGEN_EVAL_CURVE_SHADOW_TRANSPARENCY,
PG_MISS,
PG_HITD, /* Default hit group. */
PG_HITS, /* __SHADOW_RECORD_ALL__ hit group. */
@@ -40,14 +49,14 @@ enum {
};
static const int MISS_PROGRAM_GROUP_OFFSET = PG_MISS;
-static const int NUM_MIS_PROGRAM_GROUPS = 1;
+static const int NUM_MISS_PROGRAM_GROUPS = 1;
static const int HIT_PROGAM_GROUP_OFFSET = PG_HITD;
static const int NUM_HIT_PROGRAM_GROUPS = 8;
static const int CALLABLE_PROGRAM_GROUPS_BASE = PG_CALL_SVM_AO;
static const int NUM_CALLABLE_PROGRAM_GROUPS = 2;
/* List of OptiX pipelines. */
-enum { PIP_SHADE_RAYTRACE, PIP_SHADE_MNEE, PIP_INTERSECT, NUM_PIPELINES };
+enum { PIP_SHADE, PIP_INTERSECT, NUM_PIPELINES };
/* A single shader binding table entry. */
struct SbtRecord {
@@ -61,12 +70,20 @@ class OptiXDevice : public CUDADevice {
OptixModule optix_module = NULL; /* All necessary OptiX kernels are in one module. */
OptixModule builtin_modules[2] = {};
OptixPipeline pipelines[NUM_PIPELINES] = {};
+ OptixProgramGroup groups[NUM_PROGRAM_GROUPS] = {};
+ OptixPipelineCompileOptions pipeline_options = {};
- bool motion_blur = false;
device_vector<SbtRecord> sbt_data;
device_only_memory<KernelParamsOptiX> launch_params;
- OptixTraversableHandle tlas_handle = 0;
+# ifdef WITH_OSL
+ OSLGlobals osl_globals;
+ vector<OptixModule> osl_modules;
+ vector<OptixProgramGroup> osl_groups;
+# endif
+
+ private:
+ OptixTraversableHandle tlas_handle = 0;
vector<unique_ptr<device_only_memory<char>>> delayed_free_bvh_memory;
thread_mutex delayed_free_bvh_mutex;
@@ -100,13 +117,14 @@ class OptiXDevice : public CUDADevice {
OptiXDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler);
~OptiXDevice();
- private:
BVHLayoutMask get_bvh_layout_mask() const override;
- string compile_kernel_get_common_cflags(const uint kernel_features) override;
+ string compile_kernel_get_common_cflags(const uint kernel_features);
bool load_kernels(const uint kernel_features) override;
+ bool load_osl_kernels() override;
+
bool build_optix_bvh(BVHOptiX *bvh,
OptixBuildOperation operation,
const OptixBuildInput &build_input,
@@ -123,6 +141,8 @@ class OptiXDevice : public CUDADevice {
virtual unique_ptr<DeviceQueue> gpu_queue_create() override;
+ void *get_cpu_osl_memory() override;
+
/* --------------------------------------------------------------------
* Denoising.
*/
diff --git a/intern/cycles/device/optix/queue.cpp b/intern/cycles/device/optix/queue.cpp
index f0d49ad6f6c..1bfd154d449 100644
--- a/intern/cycles/device/optix/queue.cpp
+++ b/intern/cycles/device/optix/queue.cpp
@@ -24,21 +24,33 @@ void OptiXDeviceQueue::init_execution()
CUDADeviceQueue::init_execution();
}
-static bool is_optix_specific_kernel(DeviceKernel kernel)
+static bool is_optix_specific_kernel(DeviceKernel kernel, bool use_osl)
{
- return (kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE ||
- kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_MNEE ||
- kernel == DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST ||
- kernel == DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW ||
- kernel == DEVICE_KERNEL_INTEGRATOR_INTERSECT_SUBSURFACE ||
- kernel == DEVICE_KERNEL_INTEGRATOR_INTERSECT_VOLUME_STACK);
+# ifdef WITH_OSL
+ /* OSL uses direct callables to execute, so shading needs to be done in OptiX if OSL is used. */
+ if (use_osl && device_kernel_has_shading(kernel)) {
+ return true;
+ }
+# else
+ (void)use_osl;
+# endif
+
+ return device_kernel_has_intersection(kernel);
}
bool OptiXDeviceQueue::enqueue(DeviceKernel kernel,
const int work_size,
DeviceKernelArguments const &args)
{
- if (!is_optix_specific_kernel(kernel)) {
+ OptiXDevice *const optix_device = static_cast<OptiXDevice *>(cuda_device_);
+
+# ifdef WITH_OSL
+ const bool use_osl = static_cast<OSLGlobals *>(optix_device->get_cpu_osl_memory())->use;
+# else
+ const bool use_osl = false;
+# endif
+
+ if (!is_optix_specific_kernel(kernel, use_osl)) {
return CUDADeviceQueue::enqueue(kernel, work_size, args);
}
@@ -46,12 +58,10 @@ bool OptiXDeviceQueue::enqueue(DeviceKernel kernel,
return false;
}
- debug_enqueue(kernel, work_size);
+ debug_enqueue_begin(kernel, work_size);
const CUDAContextScope scope(cuda_device_);
- OptiXDevice *const optix_device = static_cast<OptiXDevice *>(cuda_device_);
-
const device_ptr sbt_data_ptr = optix_device->sbt_data.device_pointer;
const device_ptr launch_params_ptr = optix_device->launch_params.device_pointer;
@@ -62,9 +72,7 @@ bool OptiXDeviceQueue::enqueue(DeviceKernel kernel,
sizeof(device_ptr),
cuda_stream_));
- if (kernel == DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST ||
- kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE ||
- kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_MNEE) {
+ if (kernel == DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST || device_kernel_has_shading(kernel)) {
cuda_device_assert(
cuda_device_,
cuMemcpyHtoDAsync(launch_params_ptr + offsetof(KernelParamsOptiX, render_buffer),
@@ -72,6 +80,15 @@ bool OptiXDeviceQueue::enqueue(DeviceKernel kernel,
sizeof(device_ptr),
cuda_stream_));
}
+ if (kernel == DEVICE_KERNEL_SHADER_EVAL_DISPLACE ||
+ kernel == DEVICE_KERNEL_SHADER_EVAL_BACKGROUND ||
+ kernel == DEVICE_KERNEL_SHADER_EVAL_CURVE_SHADOW_TRANSPARENCY) {
+ cuda_device_assert(cuda_device_,
+ cuMemcpyHtoDAsync(launch_params_ptr + offsetof(KernelParamsOptiX, offset),
+ args.values[2], // &d_offset
+ sizeof(int32_t),
+ cuda_stream_));
+ }
cuda_device_assert(cuda_device_, cuStreamSynchronize(cuda_stream_));
@@ -79,14 +96,35 @@ bool OptiXDeviceQueue::enqueue(DeviceKernel kernel,
OptixShaderBindingTable sbt_params = {};
switch (kernel) {
+ case DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND:
+ pipeline = optix_device->pipelines[PIP_SHADE];
+ sbt_params.raygenRecord = sbt_data_ptr + PG_RGEN_SHADE_BACKGROUND * sizeof(SbtRecord);
+ break;
+ case DEVICE_KERNEL_INTEGRATOR_SHADE_LIGHT:
+ pipeline = optix_device->pipelines[PIP_SHADE];
+ sbt_params.raygenRecord = sbt_data_ptr + PG_RGEN_SHADE_LIGHT * sizeof(SbtRecord);
+ break;
+ case DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE:
+ pipeline = optix_device->pipelines[PIP_SHADE];
+ sbt_params.raygenRecord = sbt_data_ptr + PG_RGEN_SHADE_SURFACE * sizeof(SbtRecord);
+ break;
case DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE:
- pipeline = optix_device->pipelines[PIP_SHADE_RAYTRACE];
+ pipeline = optix_device->pipelines[PIP_SHADE];
sbt_params.raygenRecord = sbt_data_ptr + PG_RGEN_SHADE_SURFACE_RAYTRACE * sizeof(SbtRecord);
break;
case DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_MNEE:
- pipeline = optix_device->pipelines[PIP_SHADE_MNEE];
+ pipeline = optix_device->pipelines[PIP_SHADE];
sbt_params.raygenRecord = sbt_data_ptr + PG_RGEN_SHADE_SURFACE_MNEE * sizeof(SbtRecord);
break;
+ case DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME:
+ pipeline = optix_device->pipelines[PIP_SHADE];
+ sbt_params.raygenRecord = sbt_data_ptr + PG_RGEN_SHADE_VOLUME * sizeof(SbtRecord);
+ break;
+ case DEVICE_KERNEL_INTEGRATOR_SHADE_SHADOW:
+ pipeline = optix_device->pipelines[PIP_SHADE];
+ sbt_params.raygenRecord = sbt_data_ptr + PG_RGEN_SHADE_SHADOW * sizeof(SbtRecord);
+ break;
+
case DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST:
pipeline = optix_device->pipelines[PIP_INTERSECT];
sbt_params.raygenRecord = sbt_data_ptr + PG_RGEN_INTERSECT_CLOSEST * sizeof(SbtRecord);
@@ -104,6 +142,20 @@ bool OptiXDeviceQueue::enqueue(DeviceKernel kernel,
sbt_params.raygenRecord = sbt_data_ptr + PG_RGEN_INTERSECT_VOLUME_STACK * sizeof(SbtRecord);
break;
+ case DEVICE_KERNEL_SHADER_EVAL_DISPLACE:
+ pipeline = optix_device->pipelines[PIP_SHADE];
+ sbt_params.raygenRecord = sbt_data_ptr + PG_RGEN_EVAL_DISPLACE * sizeof(SbtRecord);
+ break;
+ case DEVICE_KERNEL_SHADER_EVAL_BACKGROUND:
+ pipeline = optix_device->pipelines[PIP_SHADE];
+ sbt_params.raygenRecord = sbt_data_ptr + PG_RGEN_EVAL_BACKGROUND * sizeof(SbtRecord);
+ break;
+ case DEVICE_KERNEL_SHADER_EVAL_CURVE_SHADOW_TRANSPARENCY:
+ pipeline = optix_device->pipelines[PIP_SHADE];
+ sbt_params.raygenRecord = sbt_data_ptr +
+ PG_RGEN_EVAL_CURVE_SHADOW_TRANSPARENCY * sizeof(SbtRecord);
+ break;
+
default:
LOG(ERROR) << "Invalid kernel " << device_kernel_as_string(kernel)
<< " is attempted to be enqueued.";
@@ -112,7 +164,7 @@ bool OptiXDeviceQueue::enqueue(DeviceKernel kernel,
sbt_params.missRecordBase = sbt_data_ptr + MISS_PROGRAM_GROUP_OFFSET * sizeof(SbtRecord);
sbt_params.missRecordStrideInBytes = sizeof(SbtRecord);
- sbt_params.missRecordCount = NUM_MIS_PROGRAM_GROUPS;
+ sbt_params.missRecordCount = NUM_MISS_PROGRAM_GROUPS;
sbt_params.hitgroupRecordBase = sbt_data_ptr + HIT_PROGAM_GROUP_OFFSET * sizeof(SbtRecord);
sbt_params.hitgroupRecordStrideInBytes = sizeof(SbtRecord);
sbt_params.hitgroupRecordCount = NUM_HIT_PROGRAM_GROUPS;
@@ -120,6 +172,12 @@ bool OptiXDeviceQueue::enqueue(DeviceKernel kernel,
sbt_params.callablesRecordCount = NUM_CALLABLE_PROGRAM_GROUPS;
sbt_params.callablesRecordStrideInBytes = sizeof(SbtRecord);
+# ifdef WITH_OSL
+ if (use_osl) {
+ sbt_params.callablesRecordCount += static_cast<unsigned int>(optix_device->osl_groups.size());
+ }
+# endif
+
/* Launch the ray generation program. */
optix_device_assert(optix_device,
optixLaunch(pipeline,
@@ -131,6 +189,8 @@ bool OptiXDeviceQueue::enqueue(DeviceKernel kernel,
1,
1));
+ debug_enqueue_end();
+
return !(optix_device->have_error());
}
diff --git a/intern/cycles/device/queue.cpp b/intern/cycles/device/queue.cpp
index cc0cf0ccf84..8c997b184b6 100644
--- a/intern/cycles/device/queue.cpp
+++ b/intern/cycles/device/queue.cpp
@@ -12,9 +12,13 @@
CCL_NAMESPACE_BEGIN
DeviceQueue::DeviceQueue(Device *device)
- : device(device), last_kernels_enqueued_(0), last_sync_time_(0.0)
+ : device(device),
+ last_kernels_enqueued_(0),
+ last_sync_time_(0.0),
+ is_per_kernel_performance_(false)
{
DCHECK_NE(device, nullptr);
+ is_per_kernel_performance_ = getenv("CYCLES_DEBUG_PER_KERNEL_PERFORMANCE");
}
DeviceQueue::~DeviceQueue()
@@ -33,11 +37,17 @@ DeviceQueue::~DeviceQueue()
});
VLOG_DEVICE_STATS << "GPU queue stats:";
+ double total_time = 0.0;
for (const auto &[mask, time] : stats_sorted) {
+ total_time += time;
VLOG_DEVICE_STATS << " " << std::setfill(' ') << std::setw(10) << std::fixed
<< std::setprecision(5) << std::right << time
<< "s: " << device_kernel_mask_as_string(mask);
}
+
+ if (is_per_kernel_performance_)
+ VLOG_DEVICE_STATS << "GPU queue total time: " << std::fixed << std::setprecision(5)
+ << total_time;
}
}
@@ -50,7 +60,7 @@ void DeviceQueue::debug_init_execution()
last_kernels_enqueued_ = 0;
}
-void DeviceQueue::debug_enqueue(DeviceKernel kernel, const int work_size)
+void DeviceQueue::debug_enqueue_begin(DeviceKernel kernel, const int work_size)
{
if (VLOG_DEVICE_STATS_IS_ON) {
VLOG_DEVICE_STATS << "GPU queue launch " << device_kernel_as_string(kernel) << ", work_size "
@@ -60,6 +70,13 @@ void DeviceQueue::debug_enqueue(DeviceKernel kernel, const int work_size)
last_kernels_enqueued_ |= (uint64_t(1) << (uint64_t)kernel);
}
+void DeviceQueue::debug_enqueue_end()
+{
+ if (VLOG_DEVICE_STATS_IS_ON && is_per_kernel_performance_) {
+ synchronize();
+ }
+}
+
void DeviceQueue::debug_synchronize()
{
if (VLOG_DEVICE_STATS_IS_ON) {
@@ -67,7 +84,11 @@ void DeviceQueue::debug_synchronize()
const double elapsed_time = new_time - last_sync_time_;
VLOG_DEVICE_STATS << "GPU queue synchronize, elapsed " << std::setw(10) << elapsed_time << "s";
- stats_kernel_time_[last_kernels_enqueued_] += elapsed_time;
+ /* There is no sense to have an entries in the performance data
+ * container without related kernel information. */
+ if (last_kernels_enqueued_ != 0) {
+ stats_kernel_time_[last_kernels_enqueued_] += elapsed_time;
+ }
last_sync_time_ = new_time;
}
diff --git a/intern/cycles/device/queue.h b/intern/cycles/device/queue.h
index 808431af401..e27e081a407 100644
--- a/intern/cycles/device/queue.h
+++ b/intern/cycles/device/queue.h
@@ -103,7 +103,7 @@ class DeviceQueue {
/* Number of states which keeps the device occupied with work without losing performance.
* The renderer will add more work (when available) when number of active paths falls below this
* value. */
- virtual int num_concurrent_busy_states() const = 0;
+ virtual int num_concurrent_busy_states(const size_t state_size) const = 0;
/* Number of elements in a partition of sorted shaders, that improves memory locality of
* integrator state fetch at the cost of decreased coherence for shader kernel execution. */
@@ -162,7 +162,8 @@ class DeviceQueue {
/* Implementations call these from the corresponding methods to generate debugging logs. */
void debug_init_execution();
- void debug_enqueue(DeviceKernel kernel, const int work_size);
+ void debug_enqueue_begin(DeviceKernel kernel, const int work_size);
+ void debug_enqueue_end();
void debug_synchronize();
string debug_active_kernels();
@@ -172,6 +173,9 @@ class DeviceQueue {
double last_sync_time_;
/* Accumulated execution time for combinations of kernels launched together. */
map<DeviceKernelMask, double> stats_kernel_time_;
+ /* If it is true, then a performance statistics in the debugging logs will have focus on kernels
+ * and an explicit queue synchronization will be added after each kernel execution. */
+ bool is_per_kernel_performance_;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/integrator/CMakeLists.txt b/intern/cycles/integrator/CMakeLists.txt
index 9722003083e..ef2a07854ec 100644
--- a/intern/cycles/integrator/CMakeLists.txt
+++ b/intern/cycles/integrator/CMakeLists.txt
@@ -65,6 +65,12 @@ if(WITH_OPENIMAGEDENOISE)
)
endif()
+if(WITH_CYCLES_PATH_GUIDING)
+ list(APPEND LIB
+ ${OPENPGL_LIBRARIES}
+ )
+endif()
+
include_directories(${INC})
include_directories(SYSTEM ${INC_SYS})
diff --git a/intern/cycles/integrator/guiding.h b/intern/cycles/integrator/guiding.h
new file mode 100644
index 00000000000..b7d7e2fe51e
--- /dev/null
+++ b/intern/cycles/integrator/guiding.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#pragma once
+
+#include "kernel/types.h"
+
+CCL_NAMESPACE_BEGIN
+
+struct GuidingParams {
+ /* The subset of path guiding parameters that can trigger a creation/rebuild
+ * of the guiding field. */
+ bool use = false;
+ bool use_surface_guiding = false;
+ bool use_volume_guiding = false;
+
+ GuidingDistributionType type = GUIDING_TYPE_PARALLAX_AWARE_VMM;
+ int training_samples = 128;
+ bool deterministic = false;
+
+ GuidingParams() = default;
+
+ bool modified(const GuidingParams &other) const
+ {
+ return !((use == other.use) && (use_surface_guiding == other.use_surface_guiding) &&
+ (use_volume_guiding == other.use_volume_guiding) && (type == other.type) &&
+ (training_samples == other.training_samples) &&
+ (deterministic == other.deterministic));
+ }
+};
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/integrator/path_trace.cpp b/intern/cycles/integrator/path_trace.cpp
index 3ec7b601d9f..8e8fbd86be0 100644
--- a/intern/cycles/integrator/path_trace.cpp
+++ b/intern/cycles/integrator/path_trace.cpp
@@ -43,8 +43,11 @@ PathTrace::PathTrace(Device *device,
/* Create path tracing work in advance, so that it can be reused by incremental sampling as much
* as possible. */
device_->foreach_device([&](Device *path_trace_device) {
- path_trace_works_.emplace_back(PathTraceWork::create(
- path_trace_device, film, device_scene, &render_cancel_.is_requested));
+ unique_ptr<PathTraceWork> work = PathTraceWork::create(
+ path_trace_device, film, device_scene, &render_cancel_.is_requested);
+ if (work) {
+ path_trace_works_.emplace_back(std::move(work));
+ }
});
work_balance_infos_.resize(path_trace_works_.size());
@@ -185,11 +188,25 @@ void PathTrace::render_pipeline(RenderWork render_work)
rebalance(render_work);
+ /* Prepare all per-thread guiding structures before we start with the next rendering
+ * iteration/progression. */
+ const bool use_guiding = device_scene_->data.integrator.use_guiding;
+ if (use_guiding) {
+ guiding_prepare_structures();
+ }
+
path_trace(render_work);
if (render_cancel_.is_requested) {
return;
}
+ /* Update the guiding field using the training data/samples collected during the rendering
+ * iteration/progression. */
+ const bool train_guiding = device_scene_->data.integrator.train_guiding;
+ if (use_guiding && train_guiding) {
+ guiding_update_structures();
+ }
+
adaptive_sample(render_work);
if (render_cancel_.is_requested) {
return;
@@ -1241,4 +1258,123 @@ string PathTrace::full_report() const
return result;
}
+void PathTrace::set_guiding_params(const GuidingParams &guiding_params, const bool reset)
+{
+#ifdef WITH_PATH_GUIDING
+ if (guiding_params_.modified(guiding_params)) {
+ guiding_params_ = guiding_params;
+
+ if (guiding_params_.use) {
+ PGLFieldArguments field_args;
+ switch (guiding_params_.type) {
+ default:
+ /* Parallax-aware von Mises-Fisher mixture models. */
+ case GUIDING_TYPE_PARALLAX_AWARE_VMM: {
+ pglFieldArgumentsSetDefaults(
+ field_args,
+ PGL_SPATIAL_STRUCTURE_TYPE::PGL_SPATIAL_STRUCTURE_KDTREE,
+ PGL_DIRECTIONAL_DISTRIBUTION_TYPE::PGL_DIRECTIONAL_DISTRIBUTION_PARALLAX_AWARE_VMM);
+ break;
+ }
+ /* Directional quad-trees. */
+ case GUIDING_TYPE_DIRECTIONAL_QUAD_TREE: {
+ pglFieldArgumentsSetDefaults(
+ field_args,
+ PGL_SPATIAL_STRUCTURE_TYPE::PGL_SPATIAL_STRUCTURE_KDTREE,
+ PGL_DIRECTIONAL_DISTRIBUTION_TYPE::PGL_DIRECTIONAL_DISTRIBUTION_QUADTREE);
+ break;
+ }
+ /* von Mises-Fisher mixture models. */
+ case GUIDING_TYPE_VMM: {
+ pglFieldArgumentsSetDefaults(
+ field_args,
+ PGL_SPATIAL_STRUCTURE_TYPE::PGL_SPATIAL_STRUCTURE_KDTREE,
+ PGL_DIRECTIONAL_DISTRIBUTION_TYPE::PGL_DIRECTIONAL_DISTRIBUTION_VMM);
+ break;
+ }
+ }
+# if OPENPGL_VERSION_MINOR >= 4
+ field_args.deterministic = guiding_params.deterministic;
+# endif
+ reinterpret_cast<PGLKDTreeArguments *>(field_args.spatialSturctureArguments)->maxDepth = 16;
+ openpgl::cpp::Device *guiding_device = static_cast<openpgl::cpp::Device *>(
+ device_->get_guiding_device());
+ if (guiding_device) {
+ guiding_sample_data_storage_ = make_unique<openpgl::cpp::SampleStorage>();
+ guiding_field_ = make_unique<openpgl::cpp::Field>(guiding_device, field_args);
+ }
+ else {
+ guiding_sample_data_storage_ = nullptr;
+ guiding_field_ = nullptr;
+ }
+ }
+ else {
+ guiding_sample_data_storage_ = nullptr;
+ guiding_field_ = nullptr;
+ }
+ }
+ else if (reset) {
+ if (guiding_field_) {
+ guiding_field_->Reset();
+ }
+ }
+#else
+ (void)guiding_params;
+ (void)reset;
+#endif
+}
+
+void PathTrace::guiding_prepare_structures()
+{
+#ifdef WITH_PATH_GUIDING
+ const bool train = (guiding_params_.training_samples == 0) ||
+ (guiding_field_->GetIteration() < guiding_params_.training_samples);
+
+ for (auto &&path_trace_work : path_trace_works_) {
+ path_trace_work->guiding_init_kernel_globals(
+ guiding_field_.get(), guiding_sample_data_storage_.get(), train);
+ }
+
+ if (train) {
+ /* For training the guiding distribution we need to force the number of samples
+ * per update to be limited, for reproducible results and reasonable training size.
+ *
+ * Idea: we could stochastically discard samples with a probability of 1/num_samples_per_update
+ * we can then update only after the num_samples_per_update iterations are rendered. */
+ render_scheduler_.set_limit_samples_per_update(4);
+ }
+ else {
+ render_scheduler_.set_limit_samples_per_update(0);
+ }
+#endif
+}
+
+void PathTrace::guiding_update_structures()
+{
+#ifdef WITH_PATH_GUIDING
+ VLOG_WORK << "Update path guiding structures";
+
+ VLOG_DEBUG << "Number of surface samples: " << guiding_sample_data_storage_->GetSizeSurface();
+ VLOG_DEBUG << "Number of volume samples: " << guiding_sample_data_storage_->GetSizeVolume();
+
+ const size_t num_valid_samples = guiding_sample_data_storage_->GetSizeSurface() +
+ guiding_sample_data_storage_->GetSizeVolume();
+
+ /* we wait until we have at least 1024 samples */
+ if (num_valid_samples >= 1024) {
+# if OPENPGL_VERSION_MINOR < 4
+ const size_t num_samples = 1;
+ guiding_field_->Update(*guiding_sample_data_storage_, num_samples);
+# else
+ guiding_field_->Update(*guiding_sample_data_storage_);
+# endif
+ guiding_update_count++;
+
+ VLOG_DEBUG << "Path guiding field valid: " << guiding_field_->Validate();
+
+ guiding_sample_data_storage_->Clear();
+ }
+#endif
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/integrator/path_trace.h b/intern/cycles/integrator/path_trace.h
index 59382b51d23..d3a238696fd 100644
--- a/intern/cycles/integrator/path_trace.h
+++ b/intern/cycles/integrator/path_trace.h
@@ -4,11 +4,15 @@
#pragma once
#include "integrator/denoiser.h"
+#include "integrator/guiding.h"
#include "integrator/pass_accessor.h"
#include "integrator/path_trace_work.h"
#include "integrator/work_balancer.h"
+
#include "session/buffers.h"
+
#include "util/function.h"
+#include "util/guiding.h"
#include "util/thread.h"
#include "util/unique_ptr.h"
#include "util/vector.h"
@@ -89,6 +93,10 @@ class PathTrace {
* Use this to configure the adaptive sampler before rendering any samples. */
void set_adaptive_sampling(const AdaptiveSampling &adaptive_sampling);
+ /* Set the parameters for guiding.
+ * Use to setup the guiding structures before each rendering iteration.*/
+ void set_guiding_params(const GuidingParams &params, const bool reset);
+
/* Sets output driver for render buffer output. */
void set_output_driver(unique_ptr<OutputDriver> driver);
@@ -205,6 +213,15 @@ class PathTrace {
void write_tile_buffer(const RenderWork &render_work);
void finalize_full_buffer_on_disk(const RenderWork &render_work);
+ /* Updates/initializes the guiding structures after a rendering iteration.
+ * The structures are updated using the training data/samples generated during the previous
+ * rendering iteration */
+ void guiding_update_structures();
+
+ /* Prepares the per-kernel thread related guiding structures (e.g., PathSegmentStorage,
+ * pointers to the global Field and SegmentStorage)*/
+ void guiding_prepare_structures();
+
/* Get number of samples in the current state of the render buffers. */
int get_num_samples_in_buffer();
@@ -265,6 +282,22 @@ class PathTrace {
/* Denoiser device descriptor which holds the denoised big tile for multi-device workloads. */
unique_ptr<PathTraceWork> big_tile_denoise_work_;
+#ifdef WITH_PATH_GUIDING
+ /* Guiding related attributes */
+ GuidingParams guiding_params_;
+
+ /* The guiding field which holds the representation of the incident radiance field for the
+ * complete scene. */
+ unique_ptr<openpgl::cpp::Field> guiding_field_;
+
+ /* The storage container which holds the training data/samples generated during the last
+ * rendering iteration. */
+ unique_ptr<openpgl::cpp::SampleStorage> guiding_sample_data_storage_;
+
+ /* The number of already performed training iterations for the guiding field.*/
+ int guiding_update_count = 0;
+#endif
+
/* State which is common for all the steps of the render work.
* Is brought up to date in the `render()` call and is accessed from all the steps involved into
* rendering the work. */
diff --git a/intern/cycles/integrator/path_trace_work.cpp b/intern/cycles/integrator/path_trace_work.cpp
index bb5c6e1a61a..a5f98b5475a 100644
--- a/intern/cycles/integrator/path_trace_work.cpp
+++ b/intern/cycles/integrator/path_trace_work.cpp
@@ -23,6 +23,10 @@ unique_ptr<PathTraceWork> PathTraceWork::create(Device *device,
if (device->info.type == DEVICE_CPU) {
return make_unique<PathTraceWorkCPU>(device, film, device_scene, cancel_requested_flag);
}
+ if (device->info.type == DEVICE_DUMMY) {
+ /* Dummy devices can't perform any work. */
+ return nullptr;
+ }
return make_unique<PathTraceWorkGPU>(device, film, device_scene, cancel_requested_flag);
}
diff --git a/intern/cycles/integrator/path_trace_work.h b/intern/cycles/integrator/path_trace_work.h
index 737d6babc08..e31a6ef8819 100644
--- a/intern/cycles/integrator/path_trace_work.h
+++ b/intern/cycles/integrator/path_trace_work.h
@@ -140,6 +140,13 @@ class PathTraceWork {
return device_;
}
+#ifdef WITH_PATH_GUIDING
+ /* Initializes the per-thread guiding kernel data. */
+ virtual void guiding_init_kernel_globals(void *, void *, const bool)
+ {
+ }
+#endif
+
protected:
PathTraceWork(Device *device,
Film *film,
diff --git a/intern/cycles/integrator/path_trace_work_cpu.cpp b/intern/cycles/integrator/path_trace_work_cpu.cpp
index 518ef3185f9..188ec28cf65 100644
--- a/intern/cycles/integrator/path_trace_work_cpu.cpp
+++ b/intern/cycles/integrator/path_trace_work_cpu.cpp
@@ -6,6 +6,7 @@
#include "device/cpu/kernel.h"
#include "device/device.h"
+#include "kernel/film/write.h"
#include "kernel/integrator/path_state.h"
#include "integrator/pass_accessor_cpu.h"
@@ -145,6 +146,13 @@ void PathTraceWorkCPU::render_samples_full_pipeline(KernelGlobalsCPU *kernel_glo
kernels_.integrator_megakernel(kernel_globals, state, render_buffer);
+#ifdef WITH_PATH_GUIDING
+ if (kernel_globals->data.integrator.train_guiding) {
+ /* Push the generated sample data to the global sample data storage. */
+ guiding_push_sample_data_to_global_storage(kernel_globals, state, render_buffer);
+ }
+#endif
+
if (shadow_catcher_state) {
kernels_.integrator_megakernel(kernel_globals, shadow_catcher_state, render_buffer);
}
@@ -276,4 +284,106 @@ void PathTraceWorkCPU::cryptomatte_postproces()
});
}
+#ifdef WITH_PATH_GUIDING
+/* NOTE: It seems that this is called before every rendering iteration/progression and not once per
+ * rendering. May be we find a way to call it only once per rendering. */
+void PathTraceWorkCPU::guiding_init_kernel_globals(void *guiding_field,
+ void *sample_data_storage,
+ const bool train)
+{
+ /* Linking the global guiding structures (e.g., Field and SampleStorage) to the per-thread
+ * kernel globals. */
+ for (int thread_index = 0; thread_index < kernel_thread_globals_.size(); thread_index++) {
+ CPUKernelThreadGlobals &kg = kernel_thread_globals_[thread_index];
+ openpgl::cpp::Field *field = (openpgl::cpp::Field *)guiding_field;
+
+ /* Allocate sampling distributions. */
+ kg.opgl_guiding_field = field;
+
+# if PATH_GUIDING_LEVEL >= 4
+ if (kg.opgl_surface_sampling_distribution) {
+ delete kg.opgl_surface_sampling_distribution;
+ kg.opgl_surface_sampling_distribution = nullptr;
+ }
+ if (kg.opgl_volume_sampling_distribution) {
+ delete kg.opgl_volume_sampling_distribution;
+ kg.opgl_volume_sampling_distribution = nullptr;
+ }
+
+ if (field) {
+ kg.opgl_surface_sampling_distribution = new openpgl::cpp::SurfaceSamplingDistribution(field);
+ kg.opgl_volume_sampling_distribution = new openpgl::cpp::VolumeSamplingDistribution(field);
+ }
+# endif
+
+ /* Reserve storage for training. */
+ kg.data.integrator.train_guiding = train;
+ kg.opgl_sample_data_storage = (openpgl::cpp::SampleStorage *)sample_data_storage;
+
+ if (train) {
+ kg.opgl_path_segment_storage->Reserve(kg.data.integrator.transparent_max_bounce +
+ kg.data.integrator.max_bounce + 3);
+ kg.opgl_path_segment_storage->Clear();
+ }
+ }
+}
+
+void PathTraceWorkCPU::guiding_push_sample_data_to_global_storage(
+ KernelGlobalsCPU *kg, IntegratorStateCPU *state, ccl_global float *ccl_restrict render_buffer)
+{
+# ifdef WITH_CYCLES_DEBUG
+ if (VLOG_WORK_IS_ON) {
+ /* Check if the generated path segments contain valid values. */
+ const bool validSegments = kg->opgl_path_segment_storage->ValidateSegments();
+ if (!validSegments) {
+ VLOG_WORK << "Guiding: invalid path segments!";
+ }
+ }
+
+ /* Write debug render pass to validate it matches combined pass. */
+ pgl_vec3f pgl_final_color = kg->opgl_path_segment_storage->CalculatePixelEstimate(false);
+ const uint32_t render_pixel_index = INTEGRATOR_STATE(state, path, render_pixel_index);
+ const uint64_t render_buffer_offset = (uint64_t)render_pixel_index *
+ kernel_data.film.pass_stride;
+ ccl_global float *buffer = render_buffer + render_buffer_offset;
+ float3 final_color = make_float3(pgl_final_color.x, pgl_final_color.y, pgl_final_color.z);
+ if (kernel_data.film.pass_guiding_color != PASS_UNUSED) {
+ film_write_pass_float3(buffer + kernel_data.film.pass_guiding_color, final_color);
+ }
+# else
+ (void)state;
+ (void)render_buffer;
+# endif
+
+ /* Convert the path segment representation of the random walk into radiance samples. */
+# if PATH_GUIDING_LEVEL >= 2
+ const bool use_direct_light = kernel_data.integrator.use_guiding_direct_light;
+ const bool use_mis_weights = kernel_data.integrator.use_guiding_mis_weights;
+ kg->opgl_path_segment_storage->PrepareSamples(
+ false, nullptr, use_mis_weights, use_direct_light, false);
+# endif
+
+# ifdef WITH_CYCLES_DEBUG
+ /* Check if the training/radiance samples generated py the path segment storage are valid.*/
+ if (VLOG_WORK_IS_ON) {
+ const bool validSamples = kg->opgl_path_segment_storage->ValidateSamples();
+ if (!validSamples) {
+ VLOG_WORK
+ << "Guiding: path segment storage generated/contains invalid radiance/training samples!";
+ }
+ }
+# endif
+
+# if PATH_GUIDING_LEVEL >= 3
+ /* Push radiance samples from current random walk/path to the global sample storage. */
+ size_t num_samples = 0;
+ const openpgl::cpp::SampleData *samples = kg->opgl_path_segment_storage->GetSamples(num_samples);
+ kg->opgl_sample_data_storage->AddSamples(samples, num_samples);
+# endif
+
+ /* Clear storage for the current path, to be ready for the next path. */
+ kg->opgl_path_segment_storage->Clear();
+}
+#endif
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/integrator/path_trace_work_cpu.h b/intern/cycles/integrator/path_trace_work_cpu.h
index 5a0918aecec..e50ba8721d9 100644
--- a/intern/cycles/integrator/path_trace_work_cpu.h
+++ b/intern/cycles/integrator/path_trace_work_cpu.h
@@ -16,6 +16,7 @@ CCL_NAMESPACE_BEGIN
struct KernelWorkTile;
struct KernelGlobalsCPU;
+struct IntegratorStateCPU;
class CPUKernels;
@@ -50,6 +51,22 @@ class PathTraceWorkCPU : public PathTraceWork {
virtual int adaptive_sampling_converge_filter_count_active(float threshold, bool reset) override;
virtual void cryptomatte_postproces() override;
+#ifdef WITH_PATH_GUIDING
+ /* Initializes the per-thread guiding kernel data. The function sets the pointers to the
+ * global guiding field and the sample data storage as well es initializes the per-thread
+ * guided sampling distributions (e.g., SurfaceSamplingDistribution and
+ * VolumeSamplingDistribution). */
+ void guiding_init_kernel_globals(void *guiding_field,
+ void *sample_data_storage,
+ const bool train) override;
+
+ /* Pushes the collected training data/samples of a path to the global sample storage.
+ * This function is called at the end of a random walk/path generation. */
+ void guiding_push_sample_data_to_global_storage(KernelGlobalsCPU *kernel_globals,
+ IntegratorStateCPU *state,
+ ccl_global float *ccl_restrict render_buffer);
+#endif
+
protected:
/* Core path tracing routine. Renders given work time on the given queue. */
void render_samples_full_pipeline(KernelGlobalsCPU *kernel_globals,
diff --git a/intern/cycles/integrator/path_trace_work_gpu.cpp b/intern/cycles/integrator/path_trace_work_gpu.cpp
index ee250a6916b..547e8d50a22 100644
--- a/intern/cycles/integrator/path_trace_work_gpu.cpp
+++ b/intern/cycles/integrator/path_trace_work_gpu.cpp
@@ -18,13 +18,15 @@
CCL_NAMESPACE_BEGIN
-static size_t estimate_single_state_size()
+static size_t estimate_single_state_size(const uint kernel_features)
{
size_t state_size = 0;
#define KERNEL_STRUCT_BEGIN(name) for (int array_index = 0;; array_index++) {
-#define KERNEL_STRUCT_MEMBER(parent_struct, type, name, feature) state_size += sizeof(type);
-#define KERNEL_STRUCT_ARRAY_MEMBER(parent_struct, type, name, feature) state_size += sizeof(type);
+#define KERNEL_STRUCT_MEMBER(parent_struct, type, name, feature) \
+ state_size += (kernel_features & (feature)) ? sizeof(type) : 0;
+#define KERNEL_STRUCT_ARRAY_MEMBER(parent_struct, type, name, feature) \
+ state_size += (kernel_features & (feature)) ? sizeof(type) : 0;
#define KERNEL_STRUCT_END(name) \
break; \
}
@@ -76,16 +78,11 @@ PathTraceWorkGPU::PathTraceWorkGPU(Device *device,
num_queued_paths_(device, "num_queued_paths", MEM_READ_WRITE),
work_tiles_(device, "work_tiles", MEM_READ_WRITE),
display_rgba_half_(device, "display buffer half", MEM_READ_WRITE),
- max_num_paths_(queue_->num_concurrent_states(estimate_single_state_size())),
- min_num_active_main_paths_(queue_->num_concurrent_busy_states()),
+ max_num_paths_(0),
+ min_num_active_main_paths_(0),
max_active_main_path_index_(0)
{
memset(&integrator_state_gpu_, 0, sizeof(integrator_state_gpu_));
-
- /* Limit number of active paths to the half of the overall state. This is due to the logic in the
- * path compaction which relies on the fact that regeneration does not happen sooner than half of
- * the states are available again. */
- min_num_active_main_paths_ = min(min_num_active_main_paths_, max_num_paths_ / 2);
}
void PathTraceWorkGPU::alloc_integrator_soa()
@@ -103,6 +100,20 @@ void PathTraceWorkGPU::alloc_integrator_soa()
integrator_state_soa_volume_stack_size_ = max(integrator_state_soa_volume_stack_size_,
requested_volume_stack_size);
+ /* Determine the number of path states. Deferring this for as long as possible allows the
+ * back-end to make better decisions about memory availability. */
+ if (max_num_paths_ == 0) {
+ size_t single_state_size = estimate_single_state_size(kernel_features);
+
+ max_num_paths_ = queue_->num_concurrent_states(single_state_size);
+ min_num_active_main_paths_ = queue_->num_concurrent_busy_states(single_state_size);
+
+ /* Limit number of active paths to the half of the overall state. This is due to the logic in
+ * the path compaction which relies on the fact that regeneration does not happen sooner than
+ * half of the states are available again. */
+ min_num_active_main_paths_ = min(min_num_active_main_paths_, max_num_paths_ / 2);
+ }
+
/* Allocate a device only memory buffer before for each struct member, and then
* write the pointers into a struct that resides in constant memory.
*
diff --git a/intern/cycles/integrator/render_scheduler.cpp b/intern/cycles/integrator/render_scheduler.cpp
index e4676bd059c..2e05dbbaf6e 100644
--- a/intern/cycles/integrator/render_scheduler.cpp
+++ b/intern/cycles/integrator/render_scheduler.cpp
@@ -45,6 +45,11 @@ void RenderScheduler::set_denoiser_params(const DenoiseParams &params)
denoiser_params_ = params;
}
+void RenderScheduler::set_limit_samples_per_update(const int limit_samples)
+{
+ limit_samples_per_update_ = limit_samples;
+}
+
void RenderScheduler::set_adaptive_sampling(const AdaptiveSampling &adaptive_sampling)
{
adaptive_sampling_ = adaptive_sampling;
@@ -760,7 +765,13 @@ int RenderScheduler::calculate_num_samples_per_update() const
const double update_interval_in_seconds = guess_display_update_interval_in_seconds();
- return max(int(num_samples_in_second * update_interval_in_seconds), 1);
+ int num_samples_per_update = max(int(num_samples_in_second * update_interval_in_seconds), 1);
+
+ if (limit_samples_per_update_) {
+ num_samples_per_update = min(limit_samples_per_update_, num_samples_per_update);
+ }
+
+ return num_samples_per_update;
}
int RenderScheduler::get_start_sample_to_path_trace() const
@@ -808,7 +819,7 @@ int RenderScheduler::get_num_samples_to_path_trace() const
return 1;
}
- const int num_samples_per_update = calculate_num_samples_per_update();
+ int num_samples_per_update = calculate_num_samples_per_update();
const int path_trace_start_sample = get_start_sample_to_path_trace();
/* Round number of samples to a power of two, so that division of path states into tiles goes in
diff --git a/intern/cycles/integrator/render_scheduler.h b/intern/cycles/integrator/render_scheduler.h
index dce876d44bd..a0ab17b3794 100644
--- a/intern/cycles/integrator/render_scheduler.h
+++ b/intern/cycles/integrator/render_scheduler.h
@@ -187,6 +187,8 @@ class RenderScheduler {
* times, and so on. */
string full_report() const;
+ void set_limit_samples_per_update(const int limit_samples);
+
protected:
/* Check whether all work has been scheduled and time limit was not exceeded.
*
@@ -450,6 +452,10 @@ class RenderScheduler {
* (quadratic dependency from the resolution divider): resolution divider of 2 brings render time
* down by a factor of 4. */
int calculate_resolution_divider_for_time(double desired_time, double actual_time);
+
+ /* If the number of samples per rendering progression should be limited because of path guiding
+ * being activated or is still inside its training phase */
+ int limit_samples_per_update_ = 0;
};
int calculate_resolution_divider_for_resolution(int width, int height, int resolution);
diff --git a/intern/cycles/integrator/work_balancer.cpp b/intern/cycles/integrator/work_balancer.cpp
index 5f1c6c92b9d..0fe170b2791 100644
--- a/intern/cycles/integrator/work_balancer.cpp
+++ b/intern/cycles/integrator/work_balancer.cpp
@@ -17,6 +17,9 @@ void work_balance_do_initial(vector<WorkBalanceInfo> &work_balance_infos)
work_balance_infos[0].weight = 1.0;
return;
}
+ else if (num_infos == 0) {
+ return;
+ }
/* There is no statistics available, so start with an equal distribution. */
const double weight = 1.0 / num_infos;
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index a89c5679b27..99f9e536977 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -37,6 +37,14 @@ set(SRC_KERNEL_DEVICE_OPTIX
device/optix/kernel_shader_raytrace.cu
)
+if(WITH_CYCLES_OSL AND (OSL_LIBRARY_VERSION_MINOR GREATER_EQUAL 13 OR OSL_LIBRARY_VERSION_MAJOR GREATER 1))
+ set(SRC_KERNEL_DEVICE_OPTIX
+ ${SRC_KERNEL_DEVICE_OPTIX}
+ osl/services_optix.cu
+ device/optix/kernel_osl.cu
+ )
+endif()
+
set(SRC_KERNEL_DEVICE_ONEAPI
device/oneapi/kernel.cpp
)
@@ -181,6 +189,16 @@ set(SRC_KERNEL_SVM_HEADERS
svm/vertex_color.h
)
+if(WITH_CYCLES_OSL)
+ set(SRC_KERNEL_OSL_HEADERS
+ osl/osl.h
+ osl/closures_setup.h
+ osl/closures_template.h
+ osl/services_gpu.h
+ osl/types.h
+ )
+endif()
+
set(SRC_KERNEL_GEOM_HEADERS
geom/geom.h
geom/attribute.h
@@ -243,6 +261,7 @@ set(SRC_KERNEL_INTEGRATOR_HEADERS
integrator/intersect_shadow.h
integrator/intersect_subsurface.h
integrator/intersect_volume_stack.h
+ integrator/guiding.h
integrator/megakernel.h
integrator/mnee.h
integrator/path_state.h
@@ -305,6 +324,7 @@ set(SRC_KERNEL_HEADERS
${SRC_KERNEL_GEOM_HEADERS}
${SRC_KERNEL_INTEGRATOR_HEADERS}
${SRC_KERNEL_LIGHT_HEADERS}
+ ${SRC_KERNEL_OSL_HEADERS}
${SRC_KERNEL_SAMPLE_HEADERS}
${SRC_KERNEL_SVM_HEADERS}
${SRC_KERNEL_TYPES_HEADERS}
@@ -327,6 +347,7 @@ set(SRC_UTIL_HEADERS
../util/math_int2.h
../util/math_int3.h
../util/math_int4.h
+ ../util/math_int8.h
../util/math_matrix.h
../util/projection.h
../util/rect.h
@@ -349,6 +370,8 @@ set(SRC_UTIL_HEADERS
../util/types_int3_impl.h
../util/types_int4.h
../util/types_int4_impl.h
+ ../util/types_int8.h
+ ../util/types_int8_impl.h
../util/types_spectrum.h
../util/types_uchar2.h
../util/types_uchar2_impl.h
@@ -529,7 +552,7 @@ if(WITH_CYCLES_CUDA_BINARIES)
endif()
if(DEFINED cuda_nvcc_executable AND DEFINED cuda_toolkit_root_dir)
# Compile regular kernel
- CYCLES_CUDA_KERNEL_ADD(${arch} ${prev_arch} kernel "" "${cuda_sources}" FALSE)
+ cycles_cuda_kernel_add(${arch} ${prev_arch} kernel "" "${cuda_sources}" FALSE)
if(WITH_CYCLES_CUDA_BUILD_SERIAL)
set(prev_arch ${arch})
@@ -611,7 +634,7 @@ if(WITH_CYCLES_HIP_BINARIES AND WITH_CYCLES_DEVICE_HIP)
foreach(arch ${CYCLES_HIP_BINARIES_ARCH})
# Compile regular kernel
- CYCLES_HIP_KERNEL_ADD(${arch} kernel "" "${hip_sources}" FALSE)
+ cycles_hip_kernel_add(${arch} kernel "" "${hip_sources}" FALSE)
endforeach()
add_custom_target(cycles_kernel_hip ALL DEPENDS ${hip_fatbins})
@@ -696,14 +719,24 @@ if(WITH_CYCLES_DEVICE_OPTIX AND WITH_CYCLES_CUDA_BINARIES)
delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${output}" ${CYCLES_INSTALL_PATH}/lib)
endmacro()
- CYCLES_OPTIX_KERNEL_ADD(
+ cycles_optix_kernel_add(
kernel_optix
"device/optix/kernel.cu"
"")
- CYCLES_OPTIX_KERNEL_ADD(
+ cycles_optix_kernel_add(
kernel_optix_shader_raytrace
"device/optix/kernel_shader_raytrace.cu"
"--keep-device-functions")
+ if(WITH_CYCLES_OSL AND (OSL_LIBRARY_VERSION_MINOR GREATER_EQUAL 13 OR OSL_LIBRARY_VERSION_MAJOR GREATER 1))
+ CYCLES_OPTIX_KERNEL_ADD(
+ kernel_optix_osl
+ "device/optix/kernel_osl.cu"
+ "--relocatable-device-code=true")
+ CYCLES_OPTIX_KERNEL_ADD(
+ kernel_optix_osl_services
+ "osl/services_optix.cu"
+ "--relocatable-device-code=true")
+ endif()
add_custom_target(cycles_kernel_optix ALL DEPENDS ${optix_ptx})
cycles_set_solution_folder(cycles_kernel_optix)
@@ -712,10 +745,17 @@ endif()
# oneAPI module
if(WITH_CYCLES_DEVICE_ONEAPI)
+ if(WITH_CYCLES_ONEAPI_BINARIES)
+ set(cycles_kernel_oneapi_lib_suffix "_aot")
+ else()
+ set(cycles_kernel_oneapi_lib_suffix "_jit")
+ endif()
+
if(WIN32)
- set(cycles_kernel_oneapi_lib ${CMAKE_CURRENT_BINARY_DIR}/cycles_kernel_oneapi.dll)
+ set(cycles_kernel_oneapi_lib ${CMAKE_CURRENT_BINARY_DIR}/cycles_kernel_oneapi${cycles_kernel_oneapi_lib_suffix}.dll)
+ set(cycles_kernel_oneapi_linker_lib ${CMAKE_CURRENT_BINARY_DIR}/cycles_kernel_oneapi${cycles_kernel_oneapi_lib_suffix}.lib)
else()
- set(cycles_kernel_oneapi_lib ${CMAKE_CURRENT_BINARY_DIR}/cycles_kernel_oneapi.so)
+ set(cycles_kernel_oneapi_lib ${CMAKE_CURRENT_BINARY_DIR}/libcycles_kernel_oneapi${cycles_kernel_oneapi_lib_suffix}.so)
endif()
set(cycles_oneapi_kernel_sources
@@ -726,14 +766,20 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
${SRC_UTIL_HEADERS}
)
+ set (SYCL_OFFLINE_COMPILER_PARALLEL_JOBS 1 CACHE STRING "Number of parallel compiler instances to use for device binaries compilation (expect ~8GB peak memory usage per instance).")
+ if (WITH_CYCLES_ONEAPI_BINARIES)
+ message(STATUS "${SYCL_OFFLINE_COMPILER_PARALLEL_JOBS} instance(s) of oneAPI offline compiler will be used.")
+ endif()
# SYCL_CPP_FLAGS is a variable that the user can set to pass extra compiler options
set(sycl_compiler_flags
${CMAKE_CURRENT_SOURCE_DIR}/${SRC_KERNEL_DEVICE_ONEAPI}
-fsycl
-fsycl-unnamed-lambda
-fdelayed-template-parsing
- -mllvm -inlinedefault-threshold=300
- -mllvm -inlinehint-threshold=400
+ -mllvm -inlinedefault-threshold=250
+ -mllvm -inlinehint-threshold=350
+ -fsycl-device-code-split=per_kernel
+ -fsycl-max-parallel-link-jobs=${SYCL_OFFLINE_COMPILER_PARALLEL_JOBS}
-shared
-DWITH_ONEAPI
-ffast-math
@@ -744,11 +790,6 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
${SYCL_CPP_FLAGS}
)
-
- if (WITH_CYCLES_ONEAPI_SYCL_HOST_ENABLED)
- list(APPEND sycl_compiler_flags -DWITH_ONEAPI_SYCL_HOST_ENABLED)
- endif()
-
# Set defaults for spir64 and spir64_gen options
if (NOT DEFINED CYCLES_ONEAPI_SYCL_OPTIONS_spir64)
set(CYCLES_ONEAPI_SYCL_OPTIONS_spir64 "-options '-ze-opt-large-register-file -ze-opt-regular-grf-kernel integrator_intersect'")
@@ -761,6 +802,8 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
string(PREPEND CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen "-device ${CYCLES_ONEAPI_SPIR64_GEN_DEVICES} ")
if (WITH_CYCLES_ONEAPI_BINARIES)
+ # AoT binaries aren't currently reused when calling sycl::build.
+ list (APPEND sycl_compiler_flags -DSYCL_SKIP_KERNELS_PRELOAD)
# Iterate over all targest and their options
list (JOIN CYCLES_ONEAPI_SYCL_TARGETS "," targets_string)
list (APPEND sycl_compiler_flags -fsycl-targets=${targets_string})
@@ -801,6 +844,7 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
if(WIN32)
list(APPEND sycl_compiler_flags
+ -fuse-ld=link
-fms-extensions
-fms-compatibility
-D_WINDLL
@@ -811,96 +855,88 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
-D_CRT_SECURE_NO_DEPRECATE
-DONEAPI_EXPORT)
- if(sycl_compiler_compiler_name MATCHES "dpcpp")
- # The oneAPI distribution calls the compiler "dpcpp" and comes with a script that sets environment variables.
- add_custom_command(
- OUTPUT ${cycles_kernel_oneapi_lib}
- COMMAND "${sycl_compiler_root}/../../env/vars.bat"
- COMMAND ${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}
- DEPENDS ${cycles_oneapi_kernel_sources})
- else()
- # The open source SYCL compiler just goes by clang++ and does not have such a script.
- # Set the variables manually.
- string(REPLACE /Redist/ /Tools/ MSVC_TOOLS_DIR ${MSVC_REDIST_DIR})
- if(NOT CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION) # case for Ninja on Windows
- get_filename_component(cmake_mt_dir ${CMAKE_MT} DIRECTORY)
- string(REPLACE /bin/ /Lib/ WINDOWS_KIT_DIR ${cmake_mt_dir})
- get_filename_component(WINDOWS_KIT_DIR "${WINDOWS_KIT_DIR}/../" ABSOLUTE)
- else()
- set(WINDOWS_KIT_DIR ${WINDOWS_KITS_DIR}/Lib/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION})
- endif()
- list(APPEND sycl_compiler_flags
- -L "${MSVC_TOOLS_DIR}/lib/x64"
- -L "${WINDOWS_KIT_DIR}/um/x64"
- -L "${WINDOWS_KIT_DIR}/ucrt/x64")
- add_custom_command(
- OUTPUT ${cycles_kernel_oneapi_lib}
- COMMAND ${CMAKE_COMMAND} -E env
- "LIB=${sycl_compiler_root}/../lib" # for compiler to find sycl.lib
- "PATH=${OCLOC_INSTALL_DIR};${sycl_compiler_root}"
- ${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}
- DEPENDS ${cycles_oneapi_kernel_sources})
+ string(REPLACE /Redist/ /Tools/ MSVC_TOOLS_DIR ${MSVC_REDIST_DIR})
+ # Version Folder between Redist and Tools can mismatch sometimes
+ if(NOT EXISTS ${MSVC_TOOLS_DIR})
+ get_filename_component(cmake_ar_dir ${CMAKE_AR} DIRECTORY)
+ get_filename_component(MSVC_TOOLS_DIR "${cmake_ar_dir}/../../../" ABSOLUTE)
endif()
+ if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION)
+ set(WINDOWS_KIT_DIR ${WINDOWS_KITS_DIR}/Lib/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION})
+ else() # case for Ninja on Windows
+ get_filename_component(cmake_mt_dir ${CMAKE_MT} DIRECTORY)
+ string(REPLACE /bin/ /Lib/ WINDOWS_KIT_DIR ${cmake_mt_dir})
+ get_filename_component(WINDOWS_KIT_DIR "${WINDOWS_KIT_DIR}/../" ABSOLUTE)
+ endif()
+ list(APPEND sycl_compiler_flags
+ -L "${MSVC_TOOLS_DIR}/lib/x64"
+ -L "${WINDOWS_KIT_DIR}/um/x64"
+ -L "${WINDOWS_KIT_DIR}/ucrt/x64")
+
+ set(sycl_compiler_flags_Release ${sycl_compiler_flags})
+ set(sycl_compiler_flags_Debug ${sycl_compiler_flags})
+ set(sycl_compiler_flags_RelWithDebInfo ${sycl_compiler_flags})
+ set(sycl_compiler_flags_MinSizeRel ${sycl_compiler_flags})
+ list(APPEND sycl_compiler_flags_RelWithDebInfo -g)
+ list(APPEND sycl_compiler_flags_Debug
+ -g
+ -D_DEBUG
+ -nostdlib -Xclang --dependent-lib=msvcrtd)
+
+ add_custom_command(
+ OUTPUT ${cycles_kernel_oneapi_lib} ${cycles_kernel_oneapi_linker_lib}
+ COMMAND ${CMAKE_COMMAND} -E env
+ "LIB=${sycl_compiler_root}/../lib" # for compiler to find sycl.lib
+ "PATH=${OCLOC_INSTALL_DIR}\;${sycl_compiler_root}"
+ ${SYCL_COMPILER}
+ "$<$<CONFIG:Release>:${sycl_compiler_flags_Release}>"
+ "$<$<CONFIG:RelWithDebInfo>:${sycl_compiler_flags_RelWithDebInfo}>"
+ "$<$<CONFIG:Debug>:${sycl_compiler_flags_Debug}>"
+ "$<$<CONFIG:MinSizeRel>:${sycl_compiler_flags_Release}>"
+ COMMAND_EXPAND_LISTS
+ DEPENDS ${cycles_oneapi_kernel_sources})
else()
list(APPEND sycl_compiler_flags -fPIC)
- # We avoid getting __FAST_MATH__ to be defined when building on CentOS 7 until the compilation crash
- # it triggers at either AoT or JIT stages gets fixed.
+ # We avoid getting __FAST_MATH__ to be defined when building on CentOS 7 until the compilation
+ # crash it triggers at either AoT or JIT stages gets fixed.
list(APPEND sycl_compiler_flags -fhonor-nans)
# add $ORIGIN to cycles_kernel_oneapi.so rpath so libsycl.so and
# libpi_level_zero.so can be placed next to it and get found.
list(APPEND sycl_compiler_flags -Wl,-rpath,'$$ORIGIN')
- # The oneAPI distribution calls the compiler "dpcpp" and comes with a script that sets environment variables.
- if(sycl_compiler_compiler_name MATCHES "dpcpp")
- add_custom_command(
- OUTPUT ${cycles_kernel_oneapi_lib}
- COMMAND bash -c \"source ${sycl_compiler_root}/../../env/vars.sh&&${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}\"
- DEPENDS ${cycles_oneapi_kernel_sources})
- else()
- # The open source SYCL compiler just goes by clang++ and does not have such a script.
- # Set the variables manually.
- if(NOT IGC_INSTALL_DIR)
- get_filename_component(IGC_INSTALL_DIR "${sycl_compiler_root}/../lib/igc" ABSOLUTE)
- endif()
- add_custom_command(
- OUTPUT ${cycles_kernel_oneapi_lib}
- COMMAND ${CMAKE_COMMAND} -E env
- "LD_LIBRARY_PATH=${sycl_compiler_root}/../lib:${OCLOC_INSTALL_DIR}/lib:${IGC_INSTALL_DIR}/lib"
- "PATH=${OCLOC_INSTALL_DIR}/bin:${sycl_compiler_root}:$ENV{PATH}" # env PATH is for compiler to find ld
- ${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}
- DEPENDS ${cycles_oneapi_kernel_sources})
+ if(NOT IGC_INSTALL_DIR)
+ get_filename_component(IGC_INSTALL_DIR "${sycl_compiler_root}/../lib/igc" ABSOLUTE)
endif()
+ add_custom_command(
+ OUTPUT ${cycles_kernel_oneapi_lib}
+ COMMAND ${CMAKE_COMMAND} -E env
+ "LD_LIBRARY_PATH=${sycl_compiler_root}/../lib:${OCLOC_INSTALL_DIR}/lib:${IGC_INSTALL_DIR}/lib"
+ # `$ENV{PATH}` is for compiler to find `ld`.
+ "PATH=${OCLOC_INSTALL_DIR}/bin:${sycl_compiler_root}:$ENV{PATH}"
+ ${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}
+ DEPENDS ${cycles_oneapi_kernel_sources})
+ endif()
+
+ if(NOT WITH_BLENDER)
+ # For the Cycles standalone put libraries next to the Cycles application.
+ set(cycles_oneapi_target_path ${CYCLES_INSTALL_PATH})
+ else()
+ # For Blender put the libraries next to the Blender executable.
+ #
+ # Note that the installation path in the delayed_install is relative to the versioned folder,
+ # which means we need to go one level up.
+ set(cycles_oneapi_target_path "../")
endif()
# install dynamic libraries required at runtime
if(WIN32)
- set(SYCL_RUNTIME_DEPENDENCIES
- sycl.dll
- pi_level_zero.dll
- )
- if(NOT WITH_BLENDER)
- # For the Cycles standalone put libraries next to the Cycles application.
- delayed_install("${sycl_compiler_root}" "${SYCL_RUNTIME_DEPENDENCIES}" ${CYCLES_INSTALL_PATH})
- else()
- # For Blender put the libraries next to the Blender executable.
- #
- # Note that the installation path in the delayed_install is relative to the versioned folder,
- # which means we need to go one level up.
- delayed_install("${sycl_compiler_root}" "${SYCL_RUNTIME_DEPENDENCIES}" "../")
- endif()
+ delayed_install("" "${cycles_kernel_oneapi_lib}" ${cycles_oneapi_target_path})
elseif(UNIX AND NOT APPLE)
- file(GLOB SYCL_RUNTIME_DEPENDENCIES
- ${sycl_compiler_root}/../lib/libsycl.so
- ${sycl_compiler_root}/../lib/libsycl.so.[0-9]
- ${sycl_compiler_root}/../lib/libsycl.so.[0-9].[0-9].[0-9]-[0-9]
- )
- list(APPEND SYCL_RUNTIME_DEPENDENCIES ${sycl_compiler_root}/../lib/libpi_level_zero.so)
- delayed_install("" "${SYCL_RUNTIME_DEPENDENCIES}" ${CYCLES_INSTALL_PATH}/lib)
+ delayed_install("" "${cycles_kernel_oneapi_lib}" ${cycles_oneapi_target_path}/lib)
endif()
- delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${cycles_kernel_oneapi_lib}" ${CYCLES_INSTALL_PATH}/lib)
add_custom_target(cycles_kernel_oneapi ALL DEPENDS ${cycles_kernel_oneapi_lib})
endif()
@@ -950,8 +986,8 @@ endif()
# Warnings to avoid using doubles in the kernel.
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER_ID MATCHES "Clang")
- ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_cxxflag_float_conversion "-Werror=float-conversion")
- ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_cxxflag_double_promotion "-Werror=double-promotion")
+ add_check_cxx_compiler_flag(CMAKE_CXX_FLAGS _has_cxxflag_float_conversion "-Werror=float-conversion")
+ add_check_cxx_compiler_flag(CMAKE_CXX_FLAGS _has_cxxflag_double_promotion "-Werror=double-promotion")
unset(_has_cxxflag_float_conversion)
unset(_has_cxxflag_double_promotion)
endif()
@@ -988,6 +1024,7 @@ source_group("geom" FILES ${SRC_KERNEL_GEOM_HEADERS})
source_group("integrator" FILES ${SRC_KERNEL_INTEGRATOR_HEADERS})
source_group("kernel" FILES ${SRC_KERNEL_TYPES_HEADERS})
source_group("light" FILES ${SRC_KERNEL_LIGHT_HEADERS})
+source_group("osl" FILES ${SRC_KERNEL_OSL_HEADERS})
source_group("sample" FILES ${SRC_KERNEL_SAMPLE_HEADERS})
source_group("svm" FILES ${SRC_KERNEL_SVM_HEADERS})
source_group("util" FILES ${SRC_KERNEL_UTIL_HEADERS})
@@ -1024,6 +1061,7 @@ delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_KERNEL_FILM_HEADERS}" ${CYCLE
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_KERNEL_GEOM_HEADERS}" ${CYCLES_INSTALL_PATH}/source/kernel/geom)
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_KERNEL_INTEGRATOR_HEADERS}" ${CYCLES_INSTALL_PATH}/source/kernel/integrator)
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_KERNEL_LIGHT_HEADERS}" ${CYCLES_INSTALL_PATH}/source/kernel/light)
+delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_KERNEL_OSL_HEADERS}" ${CYCLES_INSTALL_PATH}/source/kernel/osl)
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_KERNEL_SAMPLE_HEADERS}" ${CYCLES_INSTALL_PATH}/source/kernel/sample)
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_KERNEL_SVM_HEADERS}" ${CYCLES_INSTALL_PATH}/source/kernel/svm)
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_KERNEL_TYPES_HEADERS}" ${CYCLES_INSTALL_PATH}/source/kernel)
diff --git a/intern/cycles/kernel/bvh/shadow_all.h b/intern/cycles/kernel/bvh/shadow_all.h
index 2ffe1496c72..b31ba479e4f 100644
--- a/intern/cycles/kernel/bvh/shadow_all.h
+++ b/intern/cycles/kernel/bvh/shadow_all.h
@@ -229,7 +229,7 @@ ccl_device_inline
/* Always use baked shadow transparency for curves. */
if (isect.type & PRIMITIVE_CURVE) {
*r_throughput *= intersection_curve_shadow_transparency(
- kg, isect.object, isect.prim, isect.u);
+ kg, isect.object, isect.prim, isect.type, isect.u);
if (*r_throughput < CURVE_SHADOW_TRANSPARENCY_CUTOFF) {
return true;
diff --git a/intern/cycles/kernel/bvh/util.h b/intern/cycles/kernel/bvh/util.h
index a57703a8b8c..9ba787550c5 100644
--- a/intern/cycles/kernel/bvh/util.h
+++ b/intern/cycles/kernel/bvh/util.h
@@ -190,10 +190,8 @@ ccl_device_inline int intersection_find_attribute(KernelGlobals kg,
/* Cut-off value to stop transparent shadow tracing when practically opaque. */
#define CURVE_SHADOW_TRANSPARENCY_CUTOFF 0.001f
-ccl_device_inline float intersection_curve_shadow_transparency(KernelGlobals kg,
- const int object,
- const int prim,
- const float u)
+ccl_device_inline float intersection_curve_shadow_transparency(
+ KernelGlobals kg, const int object, const int prim, const int type, const float u)
{
/* Find attribute. */
const int offset = intersection_find_attribute(kg, object, ATTR_STD_SHADOW_TRANSPARENCY);
@@ -204,7 +202,7 @@ ccl_device_inline float intersection_curve_shadow_transparency(KernelGlobals kg,
/* Interpolate transparency between curve keys. */
const KernelCurve kcurve = kernel_data_fetch(curves, prim);
- const int k0 = kcurve.first_key + PRIMITIVE_UNPACK_SEGMENT(kcurve.type);
+ const int k0 = kcurve.first_key + PRIMITIVE_UNPACK_SEGMENT(type);
const int k1 = k0 + 1;
const float f0 = kernel_data_fetch(attributes_float, offset + k0);
diff --git a/intern/cycles/kernel/camera/projection.h b/intern/cycles/kernel/camera/projection.h
index c9fe3a6c7fb..1d16aa35abe 100644
--- a/intern/cycles/kernel/camera/projection.h
+++ b/intern/cycles/kernel/camera/projection.h
@@ -201,11 +201,35 @@ ccl_device float2 direction_to_mirrorball(float3 dir)
return make_float2(u, v);
}
+/* Single face of a equiangular cube map projection as described in
+ https://blog.google/products/google-ar-vr/bringing-pixels-front-and-center-vr-video/ */
+ccl_device float3 equiangular_cubemap_face_to_direction(float u, float v)
+{
+ u = (1.0f - u);
+
+ u = tanf(u * M_PI_2_F - M_PI_4_F);
+ v = tanf(v * M_PI_2_F - M_PI_4_F);
+
+ return make_float3(1.0f, u, v);
+}
+
+ccl_device float2 direction_to_equiangular_cubemap_face(float3 dir)
+{
+ float u = atan2f(dir.y, dir.x) * 2.0f / M_PI_F + 0.5f;
+ float v = atan2f(dir.z, dir.x) * 2.0f / M_PI_F + 0.5f;
+
+ u = 1.0f - u;
+
+ return make_float2(u, v);
+}
+
ccl_device_inline float3 panorama_to_direction(ccl_constant KernelCamera *cam, float u, float v)
{
switch (cam->panorama_type) {
case PANORAMA_EQUIRECTANGULAR:
return equirectangular_range_to_direction(u, v, cam->equirectangular_range);
+ case PANORAMA_EQUIANGULAR_CUBEMAP_FACE:
+ return equiangular_cubemap_face_to_direction(u, v);
case PANORAMA_MIRRORBALL:
return mirrorball_to_direction(u, v);
case PANORAMA_FISHEYE_EQUIDISTANT:
@@ -230,6 +254,8 @@ ccl_device_inline float2 direction_to_panorama(ccl_constant KernelCamera *cam, f
switch (cam->panorama_type) {
case PANORAMA_EQUIRECTANGULAR:
return direction_to_equirectangular_range(dir, cam->equirectangular_range);
+ case PANORAMA_EQUIANGULAR_CUBEMAP_FACE:
+ return direction_to_equiangular_cubemap_face(dir);
case PANORAMA_MIRRORBALL:
return direction_to_mirrorball(dir);
case PANORAMA_FISHEYE_EQUIDISTANT:
diff --git a/intern/cycles/kernel/closure/alloc.h b/intern/cycles/kernel/closure/alloc.h
index 1cf06614f3b..f1af3b12269 100644
--- a/intern/cycles/kernel/closure/alloc.h
+++ b/intern/cycles/kernel/closure/alloc.h
@@ -53,6 +53,9 @@ ccl_device_inline ccl_private ShaderClosure *bsdf_alloc(ccl_private ShaderData *
{
kernel_assert(isfinite_safe(weight));
+ /* No negative weights allowed. */
+ weight = max(weight, zero_float3());
+
const float sample_weight = fabsf(average(weight));
/* Use comparison this way to help dealing with non-finite weight: if the average is not finite
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index f0b28ff77c4..2f5c5d7bd0c 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -69,7 +69,11 @@ ccl_device_inline float bsdf_get_roughness_squared(ccl_private const ShaderClosu
* Yining Karl Li and Brent Burley. */
ccl_device_inline float bump_shadowing_term(float3 Ng, float3 N, float3 I)
{
- float g = safe_divide(dot(Ng, I), dot(N, I) * dot(Ng, N));
+ const float cosNI = dot(N, I);
+ if (cosNI < 0.0f) {
+ Ng = -Ng;
+ }
+ float g = safe_divide(dot(Ng, I), cosNI * dot(Ng, N));
/* If the incoming light is on the unshadowed side, return full brightness. */
if (g >= 1.0f) {
@@ -98,6 +102,12 @@ ccl_device_inline float shift_cos_in(float cos_in, const float frequency_multipl
return val;
}
+ccl_device_inline bool bsdf_is_transmission(ccl_private const ShaderClosure *sc,
+ const float3 omega_in)
+{
+ return dot(sc->N, omega_in) < 0.0f;
+}
+
ccl_device_inline int bsdf_sample(KernelGlobals kg,
ccl_private ShaderData *sd,
ccl_private const ShaderClosure *sc,
@@ -105,7 +115,9 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ ccl_private float2 *sampled_roughness,
+ ccl_private float *eta)
{
/* For curves use the smooth normal, particularly for ribbons the geometric
* normal gives too much darkening otherwise. */
@@ -115,78 +127,131 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
switch (sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
label = bsdf_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
break;
#if defined(__SVM__) || defined(__OSL__)
case CLOSURE_BSDF_OREN_NAYAR_ID:
label = bsdf_oren_nayar_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
break;
# ifdef __OSL__
case CLOSURE_BSDF_PHONG_RAMP_ID:
- label = bsdf_phong_ramp_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ label = bsdf_phong_ramp_sample(
+ sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness);
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
label = bsdf_diffuse_ramp_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
break;
# endif
case CLOSURE_BSDF_TRANSLUCENT_ID:
label = bsdf_translucent_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_REFLECTION_ID:
- label = bsdf_reflection_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ label = bsdf_reflection_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, eta);
+ *sampled_roughness = zero_float2();
break;
case CLOSURE_BSDF_REFRACTION_ID:
- label = bsdf_refraction_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ label = bsdf_refraction_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, eta);
+ *sampled_roughness = zero_float2();
break;
case CLOSURE_BSDF_TRANSPARENT_ID:
label = bsdf_transparent_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = zero_float2();
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- label = bsdf_microfacet_ggx_sample(kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ label = bsdf_microfacet_ggx_sample(
+ kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness, eta);
break;
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
- label = bsdf_microfacet_multi_ggx_sample(
- kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, &sd->lcg_state);
+ label = bsdf_microfacet_multi_ggx_sample(kg,
+ sc,
+ Ng,
+ sd->I,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ pdf,
+ &sd->lcg_state,
+ sampled_roughness,
+ eta);
break;
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
- label = bsdf_microfacet_multi_ggx_glass_sample(
- kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, &sd->lcg_state);
+ label = bsdf_microfacet_multi_ggx_glass_sample(kg,
+ sc,
+ Ng,
+ sd->I,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ pdf,
+ &sd->lcg_state,
+ sampled_roughness,
+ eta);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
label = bsdf_microfacet_beckmann_sample(
- kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness, eta);
break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
- label = bsdf_ashikhmin_shirley_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ label = bsdf_ashikhmin_shirley_sample(
+ sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness);
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
label = bsdf_ashikhmin_velvet_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_DIFFUSE_TOON_ID:
label = bsdf_diffuse_toon_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_GLOSSY_TOON_ID:
label = bsdf_glossy_toon_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ // double check if this is valid
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_HAIR_REFLECTION_ID:
- label = bsdf_hair_reflection_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ label = bsdf_hair_reflection_sample(
+ sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness);
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
- label = bsdf_hair_transmission_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ label = bsdf_hair_transmission_sample(
+ sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness);
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
- label = bsdf_principled_hair_sample(kg, sc, sd, randu, randv, eval, omega_in, pdf);
+ label = bsdf_principled_hair_sample(
+ kg, sc, sd, randu, randv, eval, omega_in, pdf, sampled_roughness, eta);
break;
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
label = bsdf_principled_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
label = bsdf_principled_sheen_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
break;
#endif
default:
@@ -209,11 +274,12 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
const float frequency_multiplier =
kernel_data_fetch(objects, sd->object).shadow_terminator_shading_offset;
if (frequency_multiplier > 1.0f) {
- *eval *= shift_cos_in(dot(*omega_in, sc->N), frequency_multiplier);
+ const float cosNI = dot(*omega_in, sc->N);
+ *eval *= shift_cos_in(cosNI, frequency_multiplier);
}
if (label & LABEL_DIFFUSE) {
if (!isequal(sc->N, sd->N)) {
- *eval *= bump_shadowing_term((label & LABEL_TRANSMIT) ? -sd->N : sd->N, sc->N, *omega_in);
+ *eval *= bump_shadowing_term(sd->N, sc->N, *omega_in);
}
}
}
@@ -226,6 +292,248 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
return label;
}
+ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
+ ccl_private const ShaderClosure *sc,
+ ccl_private float2 *roughness,
+ ccl_private float *eta)
+{
+#ifdef __SVM__
+ bool refractive = false;
+ float alpha = 1.0f;
+#endif
+ switch (sc->type) {
+ case CLOSURE_BSDF_DIFFUSE_ID:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+#ifdef __SVM__
+ case CLOSURE_BSDF_OREN_NAYAR_ID:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+# ifdef __OSL__
+ case CLOSURE_BSDF_PHONG_RAMP_ID:
+ alpha = phong_ramp_exponent_to_roughness(((ccl_private const PhongRampBsdf *)sc)->exponent);
+ *roughness = make_float2(alpha, alpha);
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+# endif
+ case CLOSURE_BSDF_TRANSLUCENT_ID:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_REFLECTION_ID: {
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ *roughness = zero_float2();
+ *eta = bsdf->ior;
+ break;
+ }
+ case CLOSURE_BSDF_REFRACTION_ID: {
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ *roughness = zero_float2();
+ // do we need to inverse eta??
+ *eta = bsdf->ior;
+ break;
+ }
+ case CLOSURE_BSDF_TRANSPARENT_ID:
+ *roughness = zero_float2();
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: {
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ *roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
+ refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ *eta = refractive ? 1.0f / bsdf->ior : bsdf->ior;
+ break;
+ }
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID: {
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ *roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
+ *eta = bsdf->ior;
+ break;
+ }
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID: {
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ *roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
+ *eta = bsdf->ior;
+ break;
+ }
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: {
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ *roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
+ refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ *eta = refractive ? 1.0f / bsdf->ior : bsdf->ior;
+ } break;
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: {
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ *roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
+ *eta = 1.0f;
+ break;
+ }
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_DIFFUSE_TOON_ID:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_GLOSSY_TOON_ID:
+ // double check if this is valid
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_HAIR_REFLECTION_ID:
+ *roughness = make_float2(((ccl_private HairBsdf *)sc)->roughness1,
+ ((ccl_private HairBsdf *)sc)->roughness2);
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
+ *roughness = make_float2(((ccl_private HairBsdf *)sc)->roughness1,
+ ((ccl_private HairBsdf *)sc)->roughness2);
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
+ alpha = ((ccl_private PrincipledHairBSDF *)sc)->m0_roughness;
+ *roughness = make_float2(alpha, alpha);
+ *eta = ((ccl_private PrincipledHairBSDF *)sc)->eta;
+ break;
+ case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+#endif
+ default:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+ }
+}
+
+ccl_device_inline int bsdf_label(const KernelGlobals kg,
+ ccl_private const ShaderClosure *sc,
+ const float3 omega_in)
+{
+ /* For curves use the smooth normal, particularly for ribbons the geometric
+ * normal gives too much darkening otherwise. */
+ int label;
+ switch (sc->type) {
+ case CLOSURE_BSDF_DIFFUSE_ID:
+ case CLOSURE_BSSRDF_BURLEY_ID:
+ case CLOSURE_BSSRDF_RANDOM_WALK_ID:
+ case CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID:
+ label = LABEL_REFLECT | LABEL_DIFFUSE;
+ break;
+#ifdef __SVM__
+ case CLOSURE_BSDF_OREN_NAYAR_ID:
+ label = LABEL_REFLECT | LABEL_DIFFUSE;
+ break;
+# ifdef __OSL__
+ case CLOSURE_BSDF_PHONG_RAMP_ID:
+ label = LABEL_REFLECT | LABEL_GLOSSY;
+ break;
+ case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
+ label = LABEL_REFLECT | LABEL_DIFFUSE;
+ break;
+# endif
+ case CLOSURE_BSDF_TRANSLUCENT_ID:
+ label = LABEL_TRANSMIT | LABEL_DIFFUSE;
+ break;
+ case CLOSURE_BSDF_REFLECTION_ID:
+ label = LABEL_REFLECT | LABEL_SINGULAR;
+ break;
+ case CLOSURE_BSDF_REFRACTION_ID:
+ label = LABEL_TRANSMIT | LABEL_SINGULAR;
+ break;
+ case CLOSURE_BSDF_TRANSPARENT_ID:
+ label = LABEL_TRANSMIT | LABEL_TRANSPARENT;
+ break;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: {
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ label = (bsdf->alpha_x * bsdf->alpha_y <= 1e-7f) ? LABEL_REFLECT | LABEL_SINGULAR :
+ LABEL_REFLECT | LABEL_GLOSSY;
+ break;
+ }
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: {
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ label = (bsdf->alpha_x * bsdf->alpha_y <= 1e-7f) ? LABEL_TRANSMIT | LABEL_SINGULAR :
+ LABEL_TRANSMIT | LABEL_GLOSSY;
+ break;
+ }
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
+ label = (bsdf_is_transmission(sc, omega_in)) ? LABEL_TRANSMIT | LABEL_GLOSSY :
+ LABEL_REFLECT | LABEL_GLOSSY;
+ break;
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
+ label = LABEL_REFLECT | LABEL_GLOSSY;
+ break;
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ label = LABEL_REFLECT | LABEL_DIFFUSE;
+ break;
+ case CLOSURE_BSDF_DIFFUSE_TOON_ID:
+ label = LABEL_REFLECT | LABEL_DIFFUSE;
+ break;
+ case CLOSURE_BSDF_GLOSSY_TOON_ID:
+ label = LABEL_REFLECT | LABEL_GLOSSY;
+ break;
+ case CLOSURE_BSDF_HAIR_REFLECTION_ID:
+ label = LABEL_REFLECT | LABEL_GLOSSY;
+ break;
+ case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
+ label = LABEL_TRANSMIT | LABEL_GLOSSY;
+ break;
+ case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
+ if (bsdf_is_transmission(sc, omega_in))
+ label = LABEL_TRANSMIT | LABEL_GLOSSY;
+ else
+ label = LABEL_REFLECT | LABEL_GLOSSY;
+ break;
+ case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
+ label = LABEL_REFLECT | LABEL_DIFFUSE;
+ break;
+ case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
+ label = LABEL_REFLECT | LABEL_DIFFUSE;
+ break;
+#endif
+ default:
+ label = LABEL_NONE;
+ break;
+ }
+
+ /* Test if BSDF sample should be treated as transparent for background. */
+ if (label & LABEL_TRANSMIT) {
+ float threshold_squared = kernel_data.background.transparent_roughness_squared_threshold;
+
+ if (threshold_squared >= 0.0f) {
+ if (bsdf_get_specular_roughness_squared(sc) <= threshold_squared) {
+ label |= LABEL_TRANSMIT_TRANSPARENT;
+ }
+ }
+ }
+ return label;
+}
+
#ifndef __KERNEL_CUDA__
ccl_device
#else
@@ -236,179 +544,104 @@ ccl_device_inline
ccl_private ShaderData *sd,
ccl_private const ShaderClosure *sc,
const float3 omega_in,
- const bool is_transmission,
ccl_private float *pdf)
{
Spectrum eval = zero_spectrum();
- if (!is_transmission) {
- switch (sc->type) {
- case CLOSURE_BSDF_DIFFUSE_ID:
- eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
+ switch (sc->type) {
+ case CLOSURE_BSDF_DIFFUSE_ID:
+ eval = bsdf_diffuse_eval(sc, sd->I, omega_in, pdf);
+ break;
#if defined(__SVM__) || defined(__OSL__)
- case CLOSURE_BSDF_OREN_NAYAR_ID:
- eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
+ case CLOSURE_BSDF_OREN_NAYAR_ID:
+ eval = bsdf_oren_nayar_eval(sc, sd->I, omega_in, pdf);
+ break;
# ifdef __OSL__
- case CLOSURE_BSDF_PHONG_RAMP_ID:
- eval = bsdf_phong_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
- eval = bsdf_diffuse_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
+ case CLOSURE_BSDF_PHONG_RAMP_ID:
+ eval = bsdf_phong_ramp_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
+ eval = bsdf_diffuse_ramp_eval(sc, sd->I, omega_in, pdf);
+ break;
# endif
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFLECTION_ID:
- eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFRACTION_ID:
- eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_TRANSPARENT_ID:
- eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
- eval = bsdf_microfacet_multi_ggx_eval_reflect(sc, sd->I, omega_in, pdf, &sd->lcg_state);
- break;
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
- eval = bsdf_microfacet_multi_ggx_glass_eval_reflect(
- sc, sd->I, omega_in, pdf, &sd->lcg_state);
- break;
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
- eval = bsdf_ashikhmin_shirley_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_DIFFUSE_TOON_ID:
- eval = bsdf_diffuse_toon_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_GLOSSY_TOON_ID:
- eval = bsdf_glossy_toon_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
- eval = bsdf_principled_hair_eval(kg, sd, sc, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_REFLECTION_ID:
- eval = bsdf_hair_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
- eval = bsdf_hair_transmission_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
- eval = bsdf_principled_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
- eval = bsdf_principled_sheen_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
+ case CLOSURE_BSDF_TRANSLUCENT_ID:
+ eval = bsdf_translucent_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_REFLECTION_ID:
+ eval = bsdf_reflection_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_REFRACTION_ID:
+ eval = bsdf_refraction_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_TRANSPARENT_ID:
+ eval = bsdf_transparent_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ eval = bsdf_microfacet_ggx_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
+ eval = bsdf_microfacet_multi_ggx_eval(sc, sd->I, omega_in, pdf, &sd->lcg_state);
+ break;
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
+ eval = bsdf_microfacet_multi_ggx_glass_eval(sc, sd->I, omega_in, pdf, &sd->lcg_state);
+ break;
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+ eval = bsdf_microfacet_beckmann_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
+ eval = bsdf_ashikhmin_shirley_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ eval = bsdf_ashikhmin_velvet_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_DIFFUSE_TOON_ID:
+ eval = bsdf_diffuse_toon_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_GLOSSY_TOON_ID:
+ eval = bsdf_glossy_toon_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
+ eval = bsdf_principled_hair_eval(kg, sd, sc, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_HAIR_REFLECTION_ID:
+ eval = bsdf_hair_reflection_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
+ eval = bsdf_hair_transmission_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
+ eval = bsdf_principled_diffuse_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
+ eval = bsdf_principled_sheen_eval(sc, sd->I, omega_in, pdf);
+ break;
#endif
- default:
- break;
- }
- if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
- if (!isequal(sc->N, sd->N)) {
- eval *= bump_shadowing_term(sd->N, sc->N, omega_in);
- }
- }
- /* Shadow terminator offset. */
- const float frequency_multiplier =
- kernel_data_fetch(objects, sd->object).shadow_terminator_shading_offset;
- if (frequency_multiplier > 1.0f) {
- eval *= shift_cos_in(dot(omega_in, sc->N), frequency_multiplier);
- }
+ default:
+ break;
}
- else {
- switch (sc->type) {
- case CLOSURE_BSDF_DIFFUSE_ID:
- eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
-#if defined(__SVM__) || defined(__OSL__)
- case CLOSURE_BSDF_OREN_NAYAR_ID:
- eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFLECTION_ID:
- eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFRACTION_ID:
- eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_TRANSPARENT_ID:
- eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
- eval = bsdf_microfacet_multi_ggx_eval_transmit(sc, sd->I, omega_in, pdf, &sd->lcg_state);
- break;
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
- eval = bsdf_microfacet_multi_ggx_glass_eval_transmit(
- sc, sd->I, omega_in, pdf, &sd->lcg_state);
- break;
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
- eval = bsdf_ashikhmin_shirley_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_DIFFUSE_TOON_ID:
- eval = bsdf_diffuse_toon_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_GLOSSY_TOON_ID:
- eval = bsdf_glossy_toon_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
- eval = bsdf_principled_hair_eval(kg, sd, sc, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_REFLECTION_ID:
- eval = bsdf_hair_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
- eval = bsdf_hair_transmission_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
- eval = bsdf_principled_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
- eval = bsdf_principled_sheen_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
-#endif
- default:
- break;
+
+ if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
+ if (!isequal(sc->N, sd->N)) {
+ eval *= bump_shadowing_term(sd->N, sc->N, omega_in);
}
- if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
- if (!isequal(sc->N, sd->N)) {
- eval *= bump_shadowing_term(-sd->N, sc->N, omega_in);
- }
+ }
+
+ /* Shadow terminator offset. */
+ const float frequency_multiplier =
+ kernel_data_fetch(objects, sd->object).shadow_terminator_shading_offset;
+ if (frequency_multiplier > 1.0f) {
+ const float cosNI = dot(omega_in, sc->N);
+ if (cosNI >= 0.0f) {
+ eval *= shift_cos_in(cosNI, frequency_multiplier);
}
}
+
#ifdef WITH_CYCLES_DEBUG
kernel_assert(*pdf >= 0.0f);
kernel_assert(eval.x >= 0.0f && eval.y >= 0.0f && eval.z >= 0.0f);
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
index 75995262030..14a4094d485 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
@@ -39,11 +39,10 @@ ccl_device_inline float bsdf_ashikhmin_shirley_roughness_to_exponent(float rough
return 2.0f / (roughness * roughness) - 2.0f;
}
-ccl_device_forceinline Spectrum
-bsdf_ashikhmin_shirley_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device_forceinline Spectrum bsdf_ashikhmin_shirley_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
float3 N = bsdf->N;
@@ -53,70 +52,60 @@ bsdf_ashikhmin_shirley_eval_reflect(ccl_private const ShaderClosure *sc,
float out = 0.0f;
- if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) {
+ if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f || !(NdotI > 0.0f && NdotO > 0.0f)) {
*pdf = 0.0f;
return zero_spectrum();
}
- if (NdotI > 0.0f && NdotO > 0.0f) {
- NdotI = fmaxf(NdotI, 1e-6f);
- NdotO = fmaxf(NdotO, 1e-6f);
- float3 H = normalize(omega_in + I);
- float HdotI = fmaxf(fabsf(dot(H, I)), 1e-6f);
- float HdotN = fmaxf(dot(H, N), 1e-6f);
-
- /* pump from original paper
- * (first derivative disc., but cancels the HdotI in the pdf nicely) */
- float pump = 1.0f / fmaxf(1e-6f, (HdotI * fmaxf(NdotO, NdotI)));
- /* pump from d-brdf paper */
- /*float pump = 1.0f / fmaxf(1e-4f, ((NdotO + NdotI) * (NdotO*NdotI))); */
-
- float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_x);
- float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_y);
-
- if (n_x == n_y) {
- /* isotropic */
- float e = n_x;
- float lobe = powf(HdotN, e);
- float norm = (n_x + 1.0f) / (8.0f * M_PI_F);
-
- out = NdotO * norm * lobe * pump;
- /* this is p_h / 4(H.I) (conversion from 'wh measure' to 'wi measure', eq. 8 in paper). */
- *pdf = norm * lobe / HdotI;
+
+ NdotI = fmaxf(NdotI, 1e-6f);
+ NdotO = fmaxf(NdotO, 1e-6f);
+ float3 H = normalize(omega_in + I);
+ float HdotI = fmaxf(fabsf(dot(H, I)), 1e-6f);
+ float HdotN = fmaxf(dot(H, N), 1e-6f);
+
+ /* pump from original paper
+ * (first derivative disc., but cancels the HdotI in the pdf nicely) */
+ float pump = 1.0f / fmaxf(1e-6f, (HdotI * fmaxf(NdotO, NdotI)));
+ /* pump from d-brdf paper */
+ /*float pump = 1.0f / fmaxf(1e-4f, ((NdotO + NdotI) * (NdotO*NdotI))); */
+
+ float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_x);
+ float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_y);
+
+ if (n_x == n_y) {
+ /* isotropic */
+ float e = n_x;
+ float lobe = powf(HdotN, e);
+ float norm = (n_x + 1.0f) / (8.0f * M_PI_F);
+
+ out = NdotO * norm * lobe * pump;
+ /* this is p_h / 4(H.I) (conversion from 'wh measure' to 'wi measure', eq. 8 in paper). */
+ *pdf = norm * lobe / HdotI;
+ }
+ else {
+ /* anisotropic */
+ float3 X, Y;
+ make_orthonormals_tangent(N, bsdf->T, &X, &Y);
+
+ float HdotX = dot(H, X);
+ float HdotY = dot(H, Y);
+ float lobe;
+ if (HdotN < 1.0f) {
+ float e = (n_x * HdotX * HdotX + n_y * HdotY * HdotY) / (1.0f - HdotN * HdotN);
+ lobe = powf(HdotN, e);
}
else {
- /* anisotropic */
- float3 X, Y;
- make_orthonormals_tangent(N, bsdf->T, &X, &Y);
-
- float HdotX = dot(H, X);
- float HdotY = dot(H, Y);
- float lobe;
- if (HdotN < 1.0f) {
- float e = (n_x * HdotX * HdotX + n_y * HdotY * HdotY) / (1.0f - HdotN * HdotN);
- lobe = powf(HdotN, e);
- }
- else {
- lobe = 1.0f;
- }
- float norm = sqrtf((n_x + 1.0f) * (n_y + 1.0f)) / (8.0f * M_PI_F);
-
- out = NdotO * norm * lobe * pump;
- *pdf = norm * lobe / HdotI;
+ lobe = 1.0f;
}
+ float norm = sqrtf((n_x + 1.0f) * (n_y + 1.0f)) / (8.0f * M_PI_F);
+
+ out = NdotO * norm * lobe * pump;
+ *pdf = norm * lobe / HdotI;
}
return make_spectrum(out);
}
-ccl_device Spectrum bsdf_ashikhmin_shirley_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
ccl_device_inline void bsdf_ashikhmin_shirley_sample_first_quadrant(float n_x,
float n_y,
float randu,
@@ -137,88 +126,93 @@ ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ ccl_private float2 *sampled_roughness)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ *sampled_roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
float3 N = bsdf->N;
int label = LABEL_REFLECT | LABEL_GLOSSY;
float NdotI = dot(N, I);
- if (NdotI > 0.0f) {
+ if (!(NdotI > 0.0f)) {
+ *pdf = 0.0f;
+ *eval = zero_spectrum();
+ return LABEL_NONE;
+ }
- float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_x);
- float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_y);
+ float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_x);
+ float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_y);
- /* get x,y basis on the surface for anisotropy */
- float3 X, Y;
+ /* get x,y basis on the surface for anisotropy */
+ float3 X, Y;
+
+ if (n_x == n_y)
+ make_orthonormals(N, &X, &Y);
+ else
+ make_orthonormals_tangent(N, bsdf->T, &X, &Y);
- if (n_x == n_y)
- make_orthonormals(N, &X, &Y);
- else
- make_orthonormals_tangent(N, bsdf->T, &X, &Y);
-
- /* sample spherical coords for h in tangent space */
- float phi;
- float cos_theta;
- if (n_x == n_y) {
- /* isotropic sampling */
- phi = M_2PI_F * randu;
- cos_theta = powf(randv, 1.0f / (n_x + 1.0f));
+ /* sample spherical coords for h in tangent space */
+ float phi;
+ float cos_theta;
+ if (n_x == n_y) {
+ /* isotropic sampling */
+ phi = M_2PI_F * randu;
+ cos_theta = powf(randv, 1.0f / (n_x + 1.0f));
+ }
+ else {
+ /* anisotropic sampling */
+ if (randu < 0.25f) { /* first quadrant */
+ float remapped_randu = 4.0f * randu;
+ bsdf_ashikhmin_shirley_sample_first_quadrant(
+ n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
}
- else {
- /* anisotropic sampling */
- if (randu < 0.25f) { /* first quadrant */
- float remapped_randu = 4.0f * randu;
- bsdf_ashikhmin_shirley_sample_first_quadrant(
- n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
- }
- else if (randu < 0.5f) { /* second quadrant */
- float remapped_randu = 4.0f * (.5f - randu);
- bsdf_ashikhmin_shirley_sample_first_quadrant(
- n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
- phi = M_PI_F - phi;
- }
- else if (randu < 0.75f) { /* third quadrant */
- float remapped_randu = 4.0f * (randu - 0.5f);
- bsdf_ashikhmin_shirley_sample_first_quadrant(
- n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
- phi = M_PI_F + phi;
- }
- else { /* fourth quadrant */
- float remapped_randu = 4.0f * (1.0f - randu);
- bsdf_ashikhmin_shirley_sample_first_quadrant(
- n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
- phi = 2.0f * M_PI_F - phi;
- }
+ else if (randu < 0.5f) { /* second quadrant */
+ float remapped_randu = 4.0f * (.5f - randu);
+ bsdf_ashikhmin_shirley_sample_first_quadrant(
+ n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
+ phi = M_PI_F - phi;
}
-
- /* get half vector in tangent space */
- float sin_theta = sqrtf(fmaxf(0.0f, 1.0f - cos_theta * cos_theta));
- float cos_phi = cosf(phi);
- float sin_phi = sinf(phi); /* no sqrt(1-cos^2) here b/c it causes artifacts */
- float3 h = make_float3(sin_theta * cos_phi, sin_theta * sin_phi, cos_theta);
-
- /* half vector to world space */
- float3 H = h.x * X + h.y * Y + h.z * N;
- float HdotI = dot(H, I);
- if (HdotI < 0.0f)
- H = -H;
-
- /* reflect I on H to get omega_in */
- *omega_in = -I + (2.0f * HdotI) * H;
-
- if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) {
- /* Some high number for MIS. */
- *pdf = 1e6f;
- *eval = make_spectrum(1e6f);
- label = LABEL_REFLECT | LABEL_SINGULAR;
+ else if (randu < 0.75f) { /* third quadrant */
+ float remapped_randu = 4.0f * (randu - 0.5f);
+ bsdf_ashikhmin_shirley_sample_first_quadrant(
+ n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
+ phi = M_PI_F + phi;
}
- else {
- /* leave the rest to eval_reflect */
- *eval = bsdf_ashikhmin_shirley_eval_reflect(sc, I, *omega_in, pdf);
+ else { /* fourth quadrant */
+ float remapped_randu = 4.0f * (1.0f - randu);
+ bsdf_ashikhmin_shirley_sample_first_quadrant(
+ n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
+ phi = 2.0f * M_PI_F - phi;
}
}
+ /* get half vector in tangent space */
+ float sin_theta = sqrtf(fmaxf(0.0f, 1.0f - cos_theta * cos_theta));
+ float cos_phi = cosf(phi);
+ float sin_phi = sinf(phi); /* no sqrt(1-cos^2) here b/c it causes artifacts */
+ float3 h = make_float3(sin_theta * cos_phi, sin_theta * sin_phi, cos_theta);
+
+ /* half vector to world space */
+ float3 H = h.x * X + h.y * Y + h.z * N;
+ float HdotI = dot(H, I);
+ if (HdotI < 0.0f)
+ H = -H;
+
+ /* reflect I on H to get omega_in */
+ *omega_in = -I + (2.0f * HdotI) * H;
+
+ if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) {
+ /* Some high number for MIS. */
+ *pdf = 1e6f;
+ *eval = make_spectrum(1e6f);
+ label = LABEL_REFLECT | LABEL_SINGULAR;
+ }
+ else {
+ /* leave the rest to eval */
+ *eval = bsdf_ashikhmin_shirley_eval(sc, I, *omega_in, pdf);
+ }
+
return label;
}
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
index 9e68ea5d5e5..ac2183e0848 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
@@ -31,10 +31,10 @@ ccl_device int bsdf_ashikhmin_velvet_setup(ccl_private VelvetBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_ashikhmin_velvet_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_ashikhmin_velvet_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const VelvetBsdf *bsdf = (ccl_private const VelvetBsdf *)sc;
float m_invsigma2 = bsdf->invsigma2;
@@ -42,46 +42,37 @@ ccl_device Spectrum bsdf_ashikhmin_velvet_eval_reflect(ccl_private const ShaderC
float cosNO = dot(N, I);
float cosNI = dot(N, omega_in);
- if (cosNO > 0 && cosNI > 0) {
- float3 H = normalize(omega_in + I);
+ if (!(cosNO > 0 && cosNI > 0)) {
+ *pdf = 0.0f;
+ return zero_spectrum();
+ }
- float cosNH = dot(N, H);
- float cosHO = fabsf(dot(I, H));
+ float3 H = normalize(omega_in + I);
- if (!(fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f)) {
- *pdf = 0.0f;
- return zero_spectrum();
- }
- float cosNHdivHO = cosNH / cosHO;
- cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f);
+ float cosNH = dot(N, H);
+ float cosHO = fabsf(dot(I, H));
- float fac1 = 2 * fabsf(cosNHdivHO * cosNO);
- float fac2 = 2 * fabsf(cosNHdivHO * cosNI);
+ if (!(fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f)) {
+ *pdf = 0.0f;
+ return zero_spectrum();
+ }
+ float cosNHdivHO = cosNH / cosHO;
+ cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f);
- float sinNH2 = 1 - cosNH * cosNH;
- float sinNH4 = sinNH2 * sinNH2;
- float cotangent2 = (cosNH * cosNH) / sinNH2;
+ float fac1 = 2 * fabsf(cosNHdivHO * cosNO);
+ float fac2 = 2 * fabsf(cosNHdivHO * cosNI);
- float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4;
- float G = fminf(1.0f, fminf(fac1, fac2)); // TODO: derive G from D analytically
+ float sinNH2 = 1 - cosNH * cosNH;
+ float sinNH4 = sinNH2 * sinNH2;
+ float cotangent2 = (cosNH * cosNH) / sinNH2;
- float out = 0.25f * (D * G) / cosNO;
+ float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4;
+ float G = fminf(1.0f, fminf(fac1, fac2)); // TODO: derive G from D analytically
- *pdf = 0.5f * M_1_PI_F;
- return make_spectrum(out);
- }
+ float out = 0.25f * (D * G) / cosNO;
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
-ccl_device Spectrum bsdf_ashikhmin_velvet_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
+ *pdf = 0.5f * M_1_PI_F;
+ return make_spectrum(out);
}
ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc,
@@ -101,41 +92,42 @@ ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc,
// distribution over the hemisphere
sample_uniform_hemisphere(N, randu, randv, omega_in, pdf);
- if (dot(Ng, *omega_in) > 0) {
- float3 H = normalize(*omega_in + I);
+ if (!(dot(Ng, *omega_in) > 0)) {
+ *pdf = 0.0f;
+ *eval = zero_spectrum();
+ return LABEL_NONE;
+ }
+
+ float3 H = normalize(*omega_in + I);
- float cosNI = dot(N, *omega_in);
- float cosNO = dot(N, I);
- float cosNH = dot(N, H);
- float cosHO = fabsf(dot(I, H));
+ float cosNI = dot(N, *omega_in);
+ float cosNO = dot(N, I);
+ float cosNH = dot(N, H);
+ float cosHO = fabsf(dot(I, H));
- if (fabsf(cosNO) > 1e-5f && fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f) {
- float cosNHdivHO = cosNH / cosHO;
- cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f);
+ if (!(fabsf(cosNO) > 1e-5f && fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f)) {
+ *pdf = 0.0f;
+ *eval = zero_spectrum();
+ return LABEL_NONE;
+ }
- float fac1 = 2 * fabsf(cosNHdivHO * cosNO);
- float fac2 = 2 * fabsf(cosNHdivHO * cosNI);
+ float cosNHdivHO = cosNH / cosHO;
+ cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f);
- float sinNH2 = 1 - cosNH * cosNH;
- float sinNH4 = sinNH2 * sinNH2;
- float cotangent2 = (cosNH * cosNH) / sinNH2;
+ float fac1 = 2 * fabsf(cosNHdivHO * cosNO);
+ float fac2 = 2 * fabsf(cosNHdivHO * cosNI);
- float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4;
- float G = fminf(1.0f, fminf(fac1, fac2)); // TODO: derive G from D analytically
+ float sinNH2 = 1 - cosNH * cosNH;
+ float sinNH4 = sinNH2 * sinNH2;
+ float cotangent2 = (cosNH * cosNH) / sinNH2;
- float power = 0.25f * (D * G) / cosNO;
+ float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4;
+ float G = fminf(1.0f, fminf(fac1, fac2)); // TODO: derive G from D analytically
+
+ float power = 0.25f * (D * G) / cosNO;
+
+ *eval = make_spectrum(power);
- *eval = make_spectrum(power);
- }
- else {
- *pdf = 0.0f;
- *eval = zero_spectrum();
- }
- }
- else {
- *pdf = 0.0f;
- *eval = zero_spectrum();
- }
return LABEL_REFLECT | LABEL_DIFFUSE;
}
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h
index ec64c375666..c9c26754651 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse.h
@@ -26,10 +26,10 @@ ccl_device int bsdf_diffuse_setup(ccl_private DiffuseBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_diffuse_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_diffuse_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc;
float3 N = bsdf->N;
@@ -39,15 +39,6 @@ ccl_device Spectrum bsdf_diffuse_eval_reflect(ccl_private const ShaderClosure *s
return make_spectrum(cos_pi);
}
-ccl_device Spectrum bsdf_diffuse_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
ccl_device int bsdf_diffuse_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
@@ -81,19 +72,10 @@ ccl_device int bsdf_translucent_setup(ccl_private DiffuseBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_translucent_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
-ccl_device Spectrum bsdf_translucent_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_translucent_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc;
float3 N = bsdf->N;
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
index d7faf5c9e9a..e955ed00b92 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
@@ -47,25 +47,23 @@ ccl_device void bsdf_diffuse_ramp_blur(ccl_private ShaderClosure *sc, float roug
{
}
-ccl_device Spectrum bsdf_diffuse_ramp_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_diffuse_ramp_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
const DiffuseRampBsdf *bsdf = (const DiffuseRampBsdf *)sc;
float3 N = bsdf->N;
float cos_pi = fmaxf(dot(N, omega_in), 0.0f);
- *pdf = cos_pi * M_1_PI_F;
- return rgb_to_spectrum(bsdf_diffuse_ramp_get_color(bsdf->colors, cos_pi) * M_1_PI_F);
-}
-
-ccl_device Spectrum bsdf_diffuse_ramp_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- return zero_spectrum();
+ if (cos_pi >= 0.0f) {
+ *pdf = cos_pi * M_1_PI_F;
+ return rgb_to_spectrum(bsdf_diffuse_ramp_get_color(bsdf->colors, cos_pi) * M_1_PI_F);
+ }
+ else {
+ *pdf = 0.0f;
+ return zero_spectrum();
+ }
}
ccl_device int bsdf_diffuse_ramp_sample(ccl_private const ShaderClosure *sc,
diff --git a/intern/cycles/kernel/closure/bsdf_hair.h b/intern/cycles/kernel/closure/bsdf_hair.h
index a29f7c444ae..a8ba4044758 100644
--- a/intern/cycles/kernel/closure/bsdf_hair.h
+++ b/intern/cycles/kernel/closure/bsdf_hair.h
@@ -37,12 +37,17 @@ ccl_device int bsdf_hair_transmission_setup(ccl_private HairBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_hair_reflection_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_hair_reflection_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc;
+ if (dot(bsdf->N, omega_in) < 0.0f) {
+ *pdf = 0.0f;
+ return zero_spectrum();
+ }
+
float offset = bsdf->offset;
float3 Tg = bsdf->T;
float roughness1 = bsdf->roughness1;
@@ -84,30 +89,17 @@ ccl_device Spectrum bsdf_hair_reflection_eval_reflect(ccl_private const ShaderCl
return make_spectrum(*pdf);
}
-ccl_device Spectrum bsdf_hair_transmission_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
-ccl_device Spectrum bsdf_hair_reflection_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
-ccl_device Spectrum bsdf_hair_transmission_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_hair_transmission_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc;
+ if (dot(bsdf->N, omega_in) >= 0.0f) {
+ *pdf = 0.0f;
+ return zero_spectrum();
+ }
+
float offset = bsdf->offset;
float3 Tg = bsdf->T;
float roughness1 = bsdf->roughness1;
@@ -155,13 +147,15 @@ ccl_device int bsdf_hair_reflection_sample(ccl_private const ShaderClosure *sc,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ ccl_private float2 *sampled_roughness)
{
ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc;
float offset = bsdf->offset;
float3 Tg = bsdf->T;
float roughness1 = bsdf->roughness1;
float roughness2 = bsdf->roughness2;
+ *sampled_roughness = make_float2(roughness1, roughness2);
float Iz = dot(Tg, I);
float3 locy = normalize(I - Tg * Iz);
float3 locx = cross(locy, Tg);
@@ -206,13 +200,15 @@ ccl_device int bsdf_hair_transmission_sample(ccl_private const ShaderClosure *sc
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ ccl_private float2 *sampled_roughness)
{
ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc;
float offset = bsdf->offset;
float3 Tg = bsdf->T;
float roughness1 = bsdf->roughness1;
float roughness2 = bsdf->roughness2;
+ *sampled_roughness = make_float2(roughness1, roughness2);
float Iz = dot(Tg, I);
float3 locy = normalize(I - Tg * Iz);
float3 locx = cross(locy, Tg);
diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h
index 2236bc62050..857b3fbf3a6 100644
--- a/intern/cycles/kernel/closure/bsdf_hair_principled.h
+++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h
@@ -56,13 +56,7 @@ ccl_device_inline float delta_phi(int p, float gamma_o, float gamma_t)
/* Remaps the given angle to [-pi, pi]. */
ccl_device_inline float wrap_angle(float a)
{
- while (a > M_PI_F) {
- a -= M_2PI_F;
- }
- while (a < -M_PI_F) {
- a += M_2PI_F;
- }
- return a;
+ return (a + M_PI_F) - M_2PI_F * floorf((a + M_PI_F) / M_2PI_F) - M_PI_F;
}
/* Logistic distribution function. */
@@ -271,76 +265,72 @@ ccl_device Spectrum bsdf_principled_hair_eval(KernelGlobals kg,
kernel_assert(isfinite_safe(sd->P) && isfinite_safe(sd->ray_length));
ccl_private const PrincipledHairBSDF *bsdf = (ccl_private const PrincipledHairBSDF *)sc;
- float3 Y = float4_to_float3(bsdf->extra->geom);
+ const float3 Y = float4_to_float3(bsdf->extra->geom);
- float3 X = safe_normalize(sd->dPdu);
+ const float3 X = safe_normalize(sd->dPdu);
kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
- float3 Z = safe_normalize(cross(X, Y));
+ const float3 Z = safe_normalize(cross(X, Y));
- float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
- float3 wi = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
+ const float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
+ const float3 wi = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
- float sin_theta_o = wo.x;
- float cos_theta_o = cos_from_sin(sin_theta_o);
- float phi_o = atan2f(wo.z, wo.y);
+ const float sin_theta_o = wo.x;
+ const float cos_theta_o = cos_from_sin(sin_theta_o);
+ const float phi_o = atan2f(wo.z, wo.y);
- float sin_theta_t = sin_theta_o / bsdf->eta;
- float cos_theta_t = cos_from_sin(sin_theta_t);
+ const float sin_theta_t = sin_theta_o / bsdf->eta;
+ const float cos_theta_t = cos_from_sin(sin_theta_t);
- float sin_gamma_o = bsdf->extra->geom.w;
- float cos_gamma_o = cos_from_sin(sin_gamma_o);
- float gamma_o = safe_asinf(sin_gamma_o);
+ const float sin_gamma_o = bsdf->extra->geom.w;
+ const float cos_gamma_o = cos_from_sin(sin_gamma_o);
+ const float gamma_o = safe_asinf(sin_gamma_o);
- float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
- float cos_gamma_t = cos_from_sin(sin_gamma_t);
- float gamma_t = safe_asinf(sin_gamma_t);
+ const float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
+ const float cos_gamma_t = cos_from_sin(sin_gamma_t);
+ const float gamma_t = safe_asinf(sin_gamma_t);
- Spectrum T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
+ const Spectrum T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
Spectrum Ap[4];
float Ap_energy[4];
hair_attenuation(
kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap, Ap_energy);
- float sin_theta_i = wi.x;
- float cos_theta_i = cos_from_sin(sin_theta_i);
- float phi_i = atan2f(wi.z, wi.y);
+ const float sin_theta_i = wi.x;
+ const float cos_theta_i = cos_from_sin(sin_theta_i);
+ const float phi_i = atan2f(wi.z, wi.y);
- float phi = phi_i - phi_o;
+ const float phi = phi_i - phi_o;
float angles[6];
hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles);
- Spectrum F;
- float F_energy;
- float Mp, Np;
-
- /* Primary specular (R). */
- Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness);
- Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t);
- F = Ap[0] * Mp * Np;
- F_energy = Ap_energy[0] * Mp * Np;
- kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
-
- /* Transmission (TT). */
- Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f * bsdf->v);
- Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t);
- F += Ap[1] * Mp * Np;
- F_energy += Ap_energy[1] * Mp * Np;
- kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
-
- /* Secondary specular (TRT). */
- Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
- Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t);
- F += Ap[2] * Mp * Np;
- F_energy += Ap_energy[2] * Mp * Np;
- kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
+ Spectrum F = zero_spectrum();
+ float F_energy = 0.0f;
+
+ /* Primary specular (R), Transmission (TT) and Secondary Specular (TRT). */
+ for (int i = 0; i < 3; i++) {
+ const float Mp = longitudinal_scattering(angles[2 * i],
+ angles[2 * i + 1],
+ sin_theta_o,
+ cos_theta_o,
+ (i == 0) ? bsdf->m0_roughness :
+ (i == 1) ? 0.25f * bsdf->v :
+ 4.0f * bsdf->v);
+ const float Np = azimuthal_scattering(phi, i, bsdf->s, gamma_o, gamma_t);
+ F += Ap[i] * Mp * Np;
+ F_energy += Ap_energy[i] * Mp * Np;
+ kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
+ }
/* Residual component (TRRT+). */
- Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
- Np = M_1_2PI_F;
- F += Ap[3] * Mp * Np;
- F_energy += Ap_energy[3] * Mp * Np;
- kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
+ {
+ const float Mp = longitudinal_scattering(
+ sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
+ const float Np = M_1_2PI_F;
+ F += Ap[3] * Mp * Np;
+ F_energy += Ap_energy[3] * Mp * Np;
+ kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
+ }
*pdf = F_energy;
return F;
@@ -354,39 +344,44 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ ccl_private float2 *sampled_roughness,
+ ccl_private float *eta)
{
ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)sc;
- float3 Y = float4_to_float3(bsdf->extra->geom);
+ *sampled_roughness = make_float2(bsdf->m0_roughness, bsdf->m0_roughness);
+ *eta = bsdf->eta;
- float3 X = safe_normalize(sd->dPdu);
+ const float3 Y = float4_to_float3(bsdf->extra->geom);
+
+ const float3 X = safe_normalize(sd->dPdu);
kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
- float3 Z = safe_normalize(cross(X, Y));
+ const float3 Z = safe_normalize(cross(X, Y));
- float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
+ const float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
float2 u[2];
u[0] = make_float2(randu, randv);
u[1].x = lcg_step_float(&sd->lcg_state);
u[1].y = lcg_step_float(&sd->lcg_state);
- float sin_theta_o = wo.x;
- float cos_theta_o = cos_from_sin(sin_theta_o);
- float phi_o = atan2f(wo.z, wo.y);
+ const float sin_theta_o = wo.x;
+ const float cos_theta_o = cos_from_sin(sin_theta_o);
+ const float phi_o = atan2f(wo.z, wo.y);
- float sin_theta_t = sin_theta_o / bsdf->eta;
- float cos_theta_t = cos_from_sin(sin_theta_t);
+ const float sin_theta_t = sin_theta_o / bsdf->eta;
+ const float cos_theta_t = cos_from_sin(sin_theta_t);
- float sin_gamma_o = bsdf->extra->geom.w;
- float cos_gamma_o = cos_from_sin(sin_gamma_o);
- float gamma_o = safe_asinf(sin_gamma_o);
+ const float sin_gamma_o = bsdf->extra->geom.w;
+ const float cos_gamma_o = cos_from_sin(sin_gamma_o);
+ const float gamma_o = safe_asinf(sin_gamma_o);
- float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
- float cos_gamma_t = cos_from_sin(sin_gamma_t);
- float gamma_t = safe_asinf(sin_gamma_t);
+ const float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
+ const float cos_gamma_t = cos_from_sin(sin_gamma_t);
+ const float gamma_t = safe_asinf(sin_gamma_t);
- Spectrum T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
+ const Spectrum T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
Spectrum Ap[4];
float Ap_energy[4];
hair_attenuation(
@@ -409,7 +404,7 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
}
u[1].x = max(u[1].x, 1e-5f);
- float fac = 1.0f + v * logf(u[1].x + (1.0f - u[1].x) * expf(-2.0f / v));
+ const float fac = 1.0f + v * logf(u[1].x + (1.0f - u[1].x) * expf(-2.0f / v));
float sin_theta_i = -fac * sin_theta_o +
cos_from_sin(fac) * cosf(M_2PI_F * u[1].y) * cos_theta_o;
float cos_theta_i = cos_from_sin(sin_theta_i);
@@ -428,41 +423,37 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
else {
phi = M_2PI_F * u[0].y;
}
- float phi_i = phi_o + phi;
+ const float phi_i = phi_o + phi;
hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles);
- Spectrum F;
- float F_energy;
- float Mp, Np;
-
- /* Primary specular (R). */
- Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness);
- Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t);
- F = Ap[0] * Mp * Np;
- F_energy = Ap_energy[0] * Mp * Np;
- kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
-
- /* Transmission (TT). */
- Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f * bsdf->v);
- Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t);
- F += Ap[1] * Mp * Np;
- F_energy += Ap_energy[1] * Mp * Np;
- kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
-
- /* Secondary specular (TRT). */
- Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
- Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t);
- F += Ap[2] * Mp * Np;
- F_energy += Ap_energy[2] * Mp * Np;
- kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
+ Spectrum F = zero_spectrum();
+ float F_energy = 0.0f;
+
+ /* Primary specular (R), Transmission (TT) and Secondary Specular (TRT). */
+ for (int i = 0; i < 3; i++) {
+ const float Mp = longitudinal_scattering(angles[2 * i],
+ angles[2 * i + 1],
+ sin_theta_o,
+ cos_theta_o,
+ (i == 0) ? bsdf->m0_roughness :
+ (i == 1) ? 0.25f * bsdf->v :
+ 4.0f * bsdf->v);
+ const float Np = azimuthal_scattering(phi, i, bsdf->s, gamma_o, gamma_t);
+ F += Ap[i] * Mp * Np;
+ F_energy += Ap_energy[i] * Mp * Np;
+ kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
+ }
/* Residual component (TRRT+). */
- Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
- Np = M_1_2PI_F;
- F += Ap[3] * Mp * Np;
- F_energy += Ap_energy[3] * Mp * Np;
- kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
+ {
+ const float Mp = longitudinal_scattering(
+ sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
+ const float Np = M_1_2PI_F;
+ F += Ap[3] * Mp * Np;
+ F_energy += Ap_energy[3] * Mp * Np;
+ kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
+ }
*eval = F;
*pdf = F_energy;
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index 04d5ca90bfd..4eb7cd5df22 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -357,146 +357,129 @@ ccl_device void bsdf_microfacet_ggx_blur(ccl_private ShaderClosure *sc, float ro
bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y);
}
-ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const ShaderClosure *sc,
+ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const MicrofacetBsdf *bsdf,
+ const float3 N,
const float3 I,
const float3 omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ const float alpha_x,
+ const float alpha_y,
+ const float cosNO,
+ const float cosNI)
{
- ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- float3 N = bsdf->N;
-
- if (m_refractive || alpha_x * alpha_y <= 1e-7f) {
+ if (!(cosNI > 0 && cosNO > 0)) {
*pdf = 0.0f;
return zero_spectrum();
}
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
-
- if (cosNI > 0 && cosNO > 0) {
- /* get half vector */
- float3 m = normalize(omega_in + I);
- float alpha2 = alpha_x * alpha_y;
- float D, G1o, G1i;
-
- if (alpha_x == alpha_y) {
- /* isotropic
- * eq. 20: (F*G*D)/(4*in*on)
- * eq. 33: first we calculate D(m) */
- float cosThetaM = dot(N, m);
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
-
- if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
- /* use GTR1 for clearcoat */
- D = D_GTR1(cosThetaM, bsdf->alpha_x);
-
- /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */
- alpha2 = 0.0625f;
- }
- else {
- /* use GTR2 otherwise */
- D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
- }
+ /* get half vector */
+ float3 m = normalize(omega_in + I);
+ float alpha2 = alpha_x * alpha_y;
+ float D, G1o, G1i;
+
+ if (alpha_x == alpha_y) {
+ /* isotropic
+ * eq. 20: (F*G*D)/(4*in*on)
+ * eq. 33: first we calculate D(m) */
+ float cosThetaM = dot(N, m);
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
- /* eq. 34: now calculate G1(i,m) and G1(o,m) */
- G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
- G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
+ if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
+ /* use GTR1 for clearcoat */
+ D = D_GTR1(cosThetaM, bsdf->alpha_x);
+
+ /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */
+ alpha2 = 0.0625f;
}
else {
- /* anisotropic */
- float3 X, Y, Z = N;
- make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
+ /* use GTR2 otherwise */
+ D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
+ }
- /* distribution */
- float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
- float slope_x = -local_m.x / (local_m.z * alpha_x);
- float slope_y = -local_m.y / (local_m.z * alpha_y);
- float slope_len = 1 + slope_x * slope_x + slope_y * slope_y;
+ /* eq. 34: now calculate G1(i,m) and G1(o,m) */
+ G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
+ G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
+ }
+ else {
+ /* anisotropic */
+ float3 X, Y, Z = N;
+ make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
- float cosThetaM = local_m.z;
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ /* distribution */
+ float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
+ float slope_x = -local_m.x / (local_m.z * alpha_x);
+ float slope_y = -local_m.y / (local_m.z * alpha_y);
+ float slope_len = 1 + slope_x * slope_x + slope_y * slope_y;
- D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4);
+ float cosThetaM = local_m.z;
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
- /* G1(i,m) and G1(o,m) */
- float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO);
- float cosPhiO = dot(I, X);
- float sinPhiO = dot(I, Y);
+ D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4);
- float alphaO2 = (cosPhiO * cosPhiO) * (alpha_x * alpha_x) +
- (sinPhiO * sinPhiO) * (alpha_y * alpha_y);
- alphaO2 /= cosPhiO * cosPhiO + sinPhiO * sinPhiO;
+ /* G1(i,m) and G1(o,m) */
+ float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO);
+ float cosPhiO = dot(I, X);
+ float sinPhiO = dot(I, Y);
- G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2));
+ float alphaO2 = (cosPhiO * cosPhiO) * (alpha_x * alpha_x) +
+ (sinPhiO * sinPhiO) * (alpha_y * alpha_y);
+ alphaO2 /= cosPhiO * cosPhiO + sinPhiO * sinPhiO;
- float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI);
- float cosPhiI = dot(omega_in, X);
- float sinPhiI = dot(omega_in, Y);
+ G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2));
- float alphaI2 = (cosPhiI * cosPhiI) * (alpha_x * alpha_x) +
- (sinPhiI * sinPhiI) * (alpha_y * alpha_y);
- alphaI2 /= cosPhiI * cosPhiI + sinPhiI * sinPhiI;
+ float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI);
+ float cosPhiI = dot(omega_in, X);
+ float sinPhiI = dot(omega_in, Y);
- G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
- }
+ float alphaI2 = (cosPhiI * cosPhiI) * (alpha_x * alpha_x) +
+ (sinPhiI * sinPhiI) * (alpha_y * alpha_y);
+ alphaI2 /= cosPhiI * cosPhiI + sinPhiI * sinPhiI;
- float G = G1o * G1i;
+ G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
+ }
- /* eq. 20 */
- float common = D * 0.25f / cosNO;
+ float G = G1o * G1i;
- Spectrum F = reflection_color(bsdf, omega_in, m);
- if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
- F *= 0.25f * bsdf->extra->clearcoat;
- }
+ /* eq. 20 */
+ float common = D * 0.25f / cosNO;
- Spectrum out = F * G * common;
+ Spectrum F = reflection_color(bsdf, omega_in, m);
+ if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
+ F *= 0.25f * bsdf->extra->clearcoat;
+ }
- /* eq. 2 in distribution of visible normals sampling
- * `pm = Dw = G1o * dot(m, I) * D / dot(N, I);` */
+ Spectrum out = F * G * common;
- /* eq. 38 - but see also:
- * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
- * `pdf = pm * 0.25 / dot(m, I);` */
- *pdf = G1o * common;
+ /* eq. 2 in distribution of visible normals sampling
+ * `pm = Dw = G1o * dot(m, I) * D / dot(N, I);` */
- return out;
- }
+ /* eq. 38 - but see also:
+ * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
+ * `pdf = pm * 0.25 / dot(m, I);` */
+ *pdf = G1o * common;
- return zero_spectrum();
+ return out;
}
-ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderClosure *sc,
+ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const MicrofacetBsdf *bsdf,
+ const float3 N,
const float3 I,
const float3 omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ const float alpha_x,
+ const float alpha_y,
+ const float cosNO,
+ const float cosNI)
{
- ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- float m_eta = bsdf->ior;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- float3 N = bsdf->N;
-
- if (!m_refractive || alpha_x * alpha_y <= 1e-7f) {
- *pdf = 0.0f;
- return zero_spectrum();
- }
-
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
-
if (cosNO <= 0 || cosNI >= 0) {
*pdf = 0.0f;
return zero_spectrum(); /* vectors on same side -- not possible */
}
/* compute half-vector of the refraction (eq. 16) */
+ float m_eta = bsdf->ior;
float3 ht = -(m_eta * omega_in + I);
float3 Ht = normalize(ht);
float cosHO = dot(Ht, I);
@@ -533,6 +516,30 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderCl
return make_spectrum(out);
}
+ccl_device Spectrum bsdf_microfacet_ggx_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
+{
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ const float alpha_x = bsdf->alpha_x;
+ const float alpha_y = bsdf->alpha_y;
+ const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ const float3 N = bsdf->N;
+ const float cosNO = dot(N, I);
+ const float cosNI = dot(N, omega_in);
+
+ if (((cosNI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) {
+ *pdf = 0.0f;
+ return zero_spectrum();
+ }
+
+ return (cosNI < 0.0f) ? bsdf_microfacet_ggx_eval_transmit(
+ bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI) :
+ bsdf_microfacet_ggx_eval_reflect(
+ bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI);
+}
+
ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
ccl_private const ShaderClosure *sc,
float3 Ng,
@@ -541,12 +548,18 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ ccl_private float2 *sampled_roughness,
+ ccl_private float *eta)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
float alpha_x = bsdf->alpha_x;
float alpha_y = bsdf->alpha_y;
bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+
+ *sampled_roughness = make_float2(alpha_x, alpha_y);
+ *eta = m_refractive ? 1.0f / bsdf->ior : bsdf->ior;
+
float3 N = bsdf->N;
int label;
@@ -805,111 +818,95 @@ ccl_device_inline float bsdf_beckmann_aniso_G1(
return ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f);
}
-ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const ShaderClosure *sc,
+ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const MicrofacetBsdf *bsdf,
+ const float3 N,
const float3 I,
const float3 omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ const float alpha_x,
+ const float alpha_y,
+ const float cosNO,
+ const float cosNI)
{
- ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- float3 N = bsdf->N;
-
- if (m_refractive || alpha_x * alpha_y <= 1e-7f) {
+ if (!(cosNO > 0 && cosNI > 0)) {
*pdf = 0.0f;
return zero_spectrum();
}
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
-
- if (cosNO > 0 && cosNI > 0) {
- /* get half vector */
- float3 m = normalize(omega_in + I);
-
- float alpha2 = alpha_x * alpha_y;
- float D, G1o, G1i;
-
- if (alpha_x == alpha_y) {
- /* isotropic
- * eq. 20: (F*G*D)/(4*in*on)
- * eq. 25: first we calculate D(m) */
- float cosThetaM = dot(N, m);
- float cosThetaM2 = cosThetaM * cosThetaM;
- float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
-
- /* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */
- G1o = bsdf_beckmann_G1(alpha_x, cosNO);
- G1i = bsdf_beckmann_G1(alpha_x, cosNI);
- }
- else {
- /* anisotropic */
- float3 X, Y, Z = N;
- make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
+ /* get half vector */
+ float3 m = normalize(omega_in + I);
- /* distribution */
- float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
- float slope_x = -local_m.x / (local_m.z * alpha_x);
- float slope_y = -local_m.y / (local_m.z * alpha_y);
+ float alpha2 = alpha_x * alpha_y;
+ float D, G1o, G1i;
- float cosThetaM = local_m.z;
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ if (alpha_x == alpha_y) {
+ /* isotropic
+ * eq. 20: (F*G*D)/(4*in*on)
+ * eq. 25: first we calculate D(m) */
+ float cosThetaM = dot(N, m);
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
+
+ /* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */
+ G1o = bsdf_beckmann_G1(alpha_x, cosNO);
+ G1i = bsdf_beckmann_G1(alpha_x, cosNI);
+ }
+ else {
+ /* anisotropic */
+ float3 X, Y, Z = N;
+ make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
- D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4);
+ /* distribution */
+ float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
+ float slope_x = -local_m.x / (local_m.z * alpha_x);
+ float slope_y = -local_m.y / (local_m.z * alpha_y);
- /* G1(i,m) and G1(o,m) */
- G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(I, X), dot(I, Y));
- G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(omega_in, X), dot(omega_in, Y));
- }
+ float cosThetaM = local_m.z;
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float G = G1o * G1i;
+ D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4);
- /* eq. 20 */
- float common = D * 0.25f / cosNO;
- float out = G * common;
+ /* G1(i,m) and G1(o,m) */
+ G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(I, X), dot(I, Y));
+ G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(omega_in, X), dot(omega_in, Y));
+ }
- /* eq. 2 in distribution of visible normals sampling
- * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
+ float G = G1o * G1i;
- /* eq. 38 - but see also:
- * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
- * pdf = pm * 0.25 / dot(m, I); */
- *pdf = G1o * common;
+ /* eq. 20 */
+ float common = D * 0.25f / cosNO;
+ float out = G * common;
- return make_spectrum(out);
- }
+ /* eq. 2 in distribution of visible normals sampling
+ * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
- return zero_spectrum();
+ /* eq. 38 - but see also:
+ * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
+ * pdf = pm * 0.25 / dot(m, I); */
+ *pdf = G1o * common;
+
+ return make_spectrum(out);
}
-ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const ShaderClosure *sc,
+ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const MicrofacetBsdf *bsdf,
+ const float3 N,
const float3 I,
const float3 omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ const float alpha_x,
+ const float alpha_y,
+ const float cosNO,
+ const float cosNI)
{
- ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- float m_eta = bsdf->ior;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- float3 N = bsdf->N;
-
- if (!m_refractive || alpha_x * alpha_y <= 1e-7f) {
- *pdf = 0.0f;
- return zero_spectrum();
- }
-
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
-
if (cosNO <= 0 || cosNI >= 0) {
*pdf = 0.0f;
return zero_spectrum();
}
+
+ const float m_eta = bsdf->ior;
/* compute half-vector of the refraction (eq. 16) */
float3 ht = -(m_eta * omega_in + I);
float3 Ht = normalize(ht);
@@ -944,6 +941,30 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const Sha
return make_spectrum(out);
}
+ccl_device Spectrum bsdf_microfacet_beckmann_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
+{
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ const float alpha_x = bsdf->alpha_x;
+ const float alpha_y = bsdf->alpha_y;
+ const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ const float3 N = bsdf->N;
+ const float cosNO = dot(N, I);
+ const float cosNI = dot(N, omega_in);
+
+ if (((cosNI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) {
+ *pdf = 0.0f;
+ return zero_spectrum();
+ }
+
+ return (cosNI < 0.0f) ? bsdf_microfacet_beckmann_eval_transmit(
+ bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI) :
+ bsdf_microfacet_beckmann_eval_reflect(
+ bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI);
+}
+
ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
ccl_private const ShaderClosure *sc,
float3 Ng,
@@ -952,7 +973,9 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ ccl_private float2 *sampled_roughness,
+ ccl_private float *eta)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
float alpha_x = bsdf->alpha_x;
@@ -961,6 +984,9 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
float3 N = bsdf->N;
int label;
+ *sampled_roughness = make_float2(alpha_x, alpha_y);
+ *eta = m_refractive ? 1.0f / bsdf->ior : bsdf->ior;
+
float cosNO = dot(N, I);
if (cosNO > 0) {
float3 X, Y, Z = N;
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
index 9402ce11f7a..73cc0d292a1 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
@@ -415,21 +415,11 @@ ccl_device int bsdf_microfacet_multi_ggx_refraction_setup(ccl_private Microfacet
return bsdf_microfacet_multi_ggx_common_setup(bsdf);
}
-ccl_device Spectrum bsdf_microfacet_multi_ggx_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf,
- ccl_private uint *lcg_state)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
-ccl_device Spectrum bsdf_microfacet_multi_ggx_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf,
- ccl_private uint *lcg_state)
+ccl_device Spectrum bsdf_microfacet_multi_ggx_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf,
+ ccl_private uint *lcg_state)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
@@ -462,6 +452,12 @@ ccl_device Spectrum bsdf_microfacet_multi_ggx_eval_reflect(ccl_private const Sha
*pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y));
else
*pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x);
+
+ if (*pdf <= 0.f) {
+ *pdf = 0.f;
+ return make_float3(0.f, 0.f, 0.f);
+ }
+
return mf_eval_glossy(localI,
localO,
true,
@@ -483,7 +479,9 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float *pdf,
- ccl_private uint *lcg_state)
+ ccl_private uint *lcg_state,
+ ccl_private float2 *sampled_roughness,
+ ccl_private float *eta)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
@@ -511,6 +509,9 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID);
+ *eta = bsdf->ior;
+ *sampled_roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
+
bool is_aniso = (bsdf->alpha_x != bsdf->alpha_y);
if (is_aniso)
make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
@@ -541,6 +542,7 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
*pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y));
else
*pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x);
+ *pdf = fmaxf(0.f, *pdf);
*eval *= *pdf;
return LABEL_REFLECT | LABEL_GLOSSY;
@@ -576,12 +578,11 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(ccl_private Microfa
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
}
-ccl_device Spectrum
-bsdf_microfacet_multi_ggx_glass_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf,
- ccl_private uint *lcg_state)
+ccl_device Spectrum bsdf_microfacet_multi_ggx_glass_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf,
+ ccl_private uint *lcg_state)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
@@ -597,53 +598,22 @@ bsdf_microfacet_multi_ggx_glass_eval_transmit(ccl_private const ShaderClosure *s
float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
- *pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
- return mf_eval_glass(localI,
- localO,
- false,
- bsdf->extra->color,
- bsdf->alpha_x,
- bsdf->alpha_y,
- lcg_state,
- bsdf->ior,
- false,
- bsdf->extra->color);
-}
-
-ccl_device Spectrum
-bsdf_microfacet_multi_ggx_glass_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf,
- ccl_private uint *lcg_state)
-{
- ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
-
- if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
- *pdf = 0.0f;
- return zero_spectrum();
- }
-
- bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID);
-
- float3 X, Y, Z;
- Z = bsdf->N;
- make_orthonormals(Z, &X, &Y);
-
- float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
- float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
+ const bool is_transmission = localO.z < 0.0f;
+ const bool use_fresnel = !is_transmission &&
+ (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID);
*pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
+ kernel_assert(*pdf >= 0.f);
return mf_eval_glass(localI,
localO,
- true,
+ !is_transmission,
bsdf->extra->color,
bsdf->alpha_x,
bsdf->alpha_y,
lcg_state,
bsdf->ior,
use_fresnel,
- bsdf->extra->cspec0);
+ (is_transmission) ? bsdf->extra->color : bsdf->extra->cspec0);
}
ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg,
@@ -655,13 +625,18 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float *pdf,
- ccl_private uint *lcg_state)
+ ccl_private uint *lcg_state,
+ ccl_private float2 *sampled_roughness,
+ ccl_private float *eta)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
float3 X, Y, Z;
Z = bsdf->N;
+ *eta = bsdf->ior;
+ *sampled_roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
+
if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
float3 R, T;
bool inside;
@@ -696,6 +671,7 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg,
use_fresnel,
bsdf->extra->cspec0);
*pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
+ kernel_assert(*pdf >= 0.f);
*eval *= *pdf;
*omega_in = X * localO.x + Y * localO.y + Z * localO.z;
diff --git a/intern/cycles/kernel/closure/bsdf_oren_nayar.h b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
index b85390f0676..6912d5b3f18 100644
--- a/intern/cycles/kernel/closure/bsdf_oren_nayar.h
+++ b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
@@ -47,10 +47,10 @@ ccl_device int bsdf_oren_nayar_setup(ccl_private OrenNayarBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_oren_nayar_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_oren_nayar_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const OrenNayarBsdf *bsdf = (ccl_private const OrenNayarBsdf *)sc;
if (dot(bsdf->N, omega_in) > 0.0f) {
@@ -63,15 +63,6 @@ ccl_device Spectrum bsdf_oren_nayar_eval_reflect(ccl_private const ShaderClosure
}
}
-ccl_device Spectrum bsdf_oren_nayar_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
ccl_device int bsdf_oren_nayar_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
diff --git a/intern/cycles/kernel/closure/bsdf_phong_ramp.h b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
index 4236e77ae6c..04bc165af30 100644
--- a/intern/cycles/kernel/closure/bsdf_phong_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
@@ -44,10 +44,10 @@ ccl_device int bsdf_phong_ramp_setup(ccl_private PhongRampBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_phong_ramp_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_phong_ramp_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const PhongRampBsdf *bsdf = (ccl_private const PhongRampBsdf *)sc;
float m_exponent = bsdf->exponent;
@@ -70,13 +70,9 @@ ccl_device Spectrum bsdf_phong_ramp_eval_reflect(ccl_private const ShaderClosure
return zero_spectrum();
}
-ccl_device float3 bsdf_phong_ramp_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device_inline float phong_ramp_exponent_to_roughness(float exponent)
{
- *pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return sqrt(1.0f / ((exponent + 2.0f) / 2.0f));
}
ccl_device int bsdf_phong_ramp_sample(ccl_private const ShaderClosure *sc,
@@ -86,11 +82,14 @@ ccl_device int bsdf_phong_ramp_sample(ccl_private const ShaderClosure *sc,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ ccl_private float2 *sampled_roughness)
{
ccl_private const PhongRampBsdf *bsdf = (ccl_private const PhongRampBsdf *)sc;
float cosNO = dot(bsdf->N, I);
float m_exponent = bsdf->exponent;
+ const float m_roughness = phong_ramp_exponent_to_roughness(m_exponent);
+ *sampled_roughness = make_float2(m_roughness, m_roughness);
if (cosNO > 0) {
// reflect the view vector
diff --git a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h
index 39cca1bd970..be8ee78fcac 100644
--- a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h
@@ -109,18 +109,17 @@ ccl_device int bsdf_principled_diffuse_setup(ccl_private PrincipledDiffuseBsdf *
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_principled_diffuse_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_principled_diffuse_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const PrincipledDiffuseBsdf *bsdf = (ccl_private const PrincipledDiffuseBsdf *)sc;
-
- float3 N = bsdf->N;
- float3 V = I; // outgoing
- float3 L = omega_in; // incoming
+ const float3 N = bsdf->N;
if (dot(N, omega_in) > 0.0f) {
+ const float3 V = I; // outgoing
+ const float3 L = omega_in; // incoming
*pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
return bsdf_principled_diffuse_compute_brdf(bsdf, N, V, L, pdf);
}
@@ -130,15 +129,6 @@ ccl_device Spectrum bsdf_principled_diffuse_eval_reflect(ccl_private const Shade
}
}
-ccl_device Spectrum bsdf_principled_diffuse_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
ccl_device int bsdf_principled_diffuse_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
diff --git a/intern/cycles/kernel/closure/bsdf_principled_sheen.h b/intern/cycles/kernel/closure/bsdf_principled_sheen.h
index fa46f47eb21..f6499cc437c 100644
--- a/intern/cycles/kernel/closure/bsdf_principled_sheen.h
+++ b/intern/cycles/kernel/closure/bsdf_principled_sheen.h
@@ -59,19 +59,19 @@ ccl_device int bsdf_principled_sheen_setup(ccl_private const ShaderData *sd,
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_principled_sheen_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_principled_sheen_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const PrincipledSheenBsdf *bsdf = (ccl_private const PrincipledSheenBsdf *)sc;
-
- float3 N = bsdf->N;
- float3 V = I; // outgoing
- float3 L = omega_in; // incoming
- float3 H = normalize(L + V);
+ const float3 N = bsdf->N;
if (dot(N, omega_in) > 0.0f) {
+ const float3 V = I; // outgoing
+ const float3 L = omega_in; // incoming
+ const float3 H = normalize(L + V);
+
*pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
return calculate_principled_sheen_brdf(N, V, L, H, pdf);
}
@@ -81,15 +81,6 @@ ccl_device Spectrum bsdf_principled_sheen_eval_reflect(ccl_private const ShaderC
}
}
-ccl_device Spectrum bsdf_principled_sheen_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
ccl_device int bsdf_principled_sheen_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
diff --git a/intern/cycles/kernel/closure/bsdf_reflection.h b/intern/cycles/kernel/closure/bsdf_reflection.h
index 5e6c6cdcde6..2f761974e9a 100644
--- a/intern/cycles/kernel/closure/bsdf_reflection.h
+++ b/intern/cycles/kernel/closure/bsdf_reflection.h
@@ -18,19 +18,10 @@ ccl_device int bsdf_reflection_setup(ccl_private MicrofacetBsdf *bsdf)
return SD_BSDF;
}
-ccl_device Spectrum bsdf_reflection_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
-ccl_device Spectrum bsdf_reflection_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_reflection_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
return zero_spectrum();
@@ -43,10 +34,12 @@ ccl_device int bsdf_reflection_sample(ccl_private const ShaderClosure *sc,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ ccl_private float *eta)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
float3 N = bsdf->N;
+ *eta = bsdf->ior;
// only one direction is possible
float cosNO = dot(N, I);
diff --git a/intern/cycles/kernel/closure/bsdf_refraction.h b/intern/cycles/kernel/closure/bsdf_refraction.h
index e680a9617db..e4f66245a0b 100644
--- a/intern/cycles/kernel/closure/bsdf_refraction.h
+++ b/intern/cycles/kernel/closure/bsdf_refraction.h
@@ -18,19 +18,10 @@ ccl_device int bsdf_refraction_setup(ccl_private MicrofacetBsdf *bsdf)
return SD_BSDF;
}
-ccl_device Spectrum bsdf_refraction_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
-ccl_device Spectrum bsdf_refraction_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_refraction_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
return zero_spectrum();
@@ -43,10 +34,13 @@ ccl_device int bsdf_refraction_sample(ccl_private const ShaderClosure *sc,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ ccl_private float *eta)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
float m_eta = bsdf->ior;
+
+ *eta = 1.0f / m_eta;
float3 N = bsdf->N;
float3 R, T;
diff --git a/intern/cycles/kernel/closure/bsdf_toon.h b/intern/cycles/kernel/closure/bsdf_toon.h
index c9086823de9..9f78c86b3b7 100644
--- a/intern/cycles/kernel/closure/bsdf_toon.h
+++ b/intern/cycles/kernel/closure/bsdf_toon.h
@@ -49,33 +49,29 @@ ccl_device float bsdf_toon_get_sample_angle(float max_angle, float smooth)
return fminf(max_angle + smooth, M_PI_2_F);
}
-ccl_device Spectrum bsdf_diffuse_toon_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_diffuse_toon_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc;
- float max_angle = bsdf->size * M_PI_2_F;
- float smooth = bsdf->smooth * M_PI_2_F;
- float angle = safe_acosf(fmaxf(dot(bsdf->N, omega_in), 0.0f));
+ float cosNI = dot(bsdf->N, omega_in);
- float eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
+ if (cosNI >= 0.0f) {
+ float max_angle = bsdf->size * M_PI_2_F;
+ float smooth = bsdf->smooth * M_PI_2_F;
+ float angle = safe_acosf(fmaxf(cosNI, 0.0f));
- if (eval > 0.0f) {
- float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
+ float eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
- *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle));
- return make_spectrum(*pdf * eval);
+ if (eval > 0.0f) {
+ float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
+
+ *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle));
+ return make_spectrum(*pdf * eval);
+ }
}
- *pdf = 0.0f;
- return zero_spectrum();
-}
-ccl_device Spectrum bsdf_diffuse_toon_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
*pdf = 0.0f;
return zero_spectrum();
}
@@ -125,10 +121,10 @@ ccl_device int bsdf_glossy_toon_setup(ccl_private ToonBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_glossy_toon_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_glossy_toon_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc;
float max_angle = bsdf->size * M_PI_2_F;
@@ -153,15 +149,6 @@ ccl_device Spectrum bsdf_glossy_toon_eval_reflect(ccl_private const ShaderClosur
return zero_spectrum();
}
-ccl_device Spectrum bsdf_glossy_toon_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
ccl_device int bsdf_glossy_toon_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
diff --git a/intern/cycles/kernel/closure/bsdf_transparent.h b/intern/cycles/kernel/closure/bsdf_transparent.h
index c2aee1e1633..9306e82b579 100644
--- a/intern/cycles/kernel/closure/bsdf_transparent.h
+++ b/intern/cycles/kernel/closure/bsdf_transparent.h
@@ -59,19 +59,10 @@ ccl_device void bsdf_transparent_setup(ccl_private ShaderData *sd,
}
}
-ccl_device Spectrum bsdf_transparent_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
-ccl_device Spectrum bsdf_transparent_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_transparent_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
return zero_spectrum();
diff --git a/intern/cycles/kernel/data_template.h b/intern/cycles/kernel/data_template.h
index 807d0650fc3..1e9e25f2f9d 100644
--- a/intern/cycles/kernel/data_template.h
+++ b/intern/cycles/kernel/data_template.h
@@ -133,6 +133,10 @@ KERNEL_STRUCT_MEMBER(film, int, pass_bake_primitive)
KERNEL_STRUCT_MEMBER(film, int, pass_bake_differential)
/* Shadow catcher. */
KERNEL_STRUCT_MEMBER(film, int, use_approximate_shadow_catcher)
+/* Path Guiding */
+KERNEL_STRUCT_MEMBER(film, int, pass_guiding_color)
+KERNEL_STRUCT_MEMBER(film, int, pass_guiding_probability)
+KERNEL_STRUCT_MEMBER(film, int, pass_guiding_avg_roughness)
/* Padding. */
KERNEL_STRUCT_MEMBER(film, int, pad1)
KERNEL_STRUCT_MEMBER(film, int, pad2)
@@ -190,8 +194,17 @@ KERNEL_STRUCT_MEMBER(integrator, int, has_shadow_catcher)
KERNEL_STRUCT_MEMBER(integrator, int, filter_closures)
/* MIS debugging. */
KERNEL_STRUCT_MEMBER(integrator, int, direct_light_sampling_type)
-/* Padding */
-KERNEL_STRUCT_MEMBER(integrator, int, pad1)
+
+/* Path Guiding */
+KERNEL_STRUCT_MEMBER(integrator, float, surface_guiding_probability)
+KERNEL_STRUCT_MEMBER(integrator, float, volume_guiding_probability)
+KERNEL_STRUCT_MEMBER(integrator, int, guiding_distribution_type)
+KERNEL_STRUCT_MEMBER(integrator, int, use_guiding)
+KERNEL_STRUCT_MEMBER(integrator, int, train_guiding)
+KERNEL_STRUCT_MEMBER(integrator, int, use_surface_guiding)
+KERNEL_STRUCT_MEMBER(integrator, int, use_volume_guiding)
+KERNEL_STRUCT_MEMBER(integrator, int, use_guiding_direct_light)
+KERNEL_STRUCT_MEMBER(integrator, int, use_guiding_mis_weights)
KERNEL_STRUCT_END(KernelIntegrator)
/* SVM. For shader specialization. */
diff --git a/intern/cycles/kernel/device/cpu/bvh.h b/intern/cycles/kernel/device/cpu/bvh.h
index d9267e1cd6d..2d7d8c2d704 100644
--- a/intern/cycles/kernel/device/cpu/bvh.h
+++ b/intern/cycles/kernel/device/cpu/bvh.h
@@ -252,7 +252,7 @@ ccl_device void kernel_embree_filter_occluded_func(const RTCFilterFunctionNArgum
/* Always use baked shadow transparency for curves. */
if (current_isect.type & PRIMITIVE_CURVE) {
ctx->throughput *= intersection_curve_shadow_transparency(
- kg, current_isect.object, current_isect.prim, current_isect.u);
+ kg, current_isect.object, current_isect.prim, current_isect.type, current_isect.u);
if (ctx->throughput < CURVE_SHADOW_TRANSPARENCY_CUTOFF) {
ctx->opaque_hit = true;
diff --git a/intern/cycles/kernel/device/cpu/globals.h b/intern/cycles/kernel/device/cpu/globals.h
index 309afae412e..f7f1a36b2a7 100644
--- a/intern/cycles/kernel/device/cpu/globals.h
+++ b/intern/cycles/kernel/device/cpu/globals.h
@@ -9,6 +9,8 @@
#include "kernel/types.h"
#include "kernel/util/profiling.h"
+#include "util/guiding.h"
+
CCL_NAMESPACE_BEGIN
/* On the CPU, we pass along the struct KernelGlobals to nearly everywhere in
@@ -43,9 +45,20 @@ typedef struct KernelGlobalsCPU {
#ifdef __OSL__
/* On the CPU, we also have the OSL globals here. Most data structures are shared
* with SVM, the difference is in the shaders and object/mesh attributes. */
- OSLGlobals *osl;
- OSLShadingSystem *osl_ss;
- OSLThreadData *osl_tdata;
+ OSLGlobals *osl = nullptr;
+ OSLShadingSystem *osl_ss = nullptr;
+ OSLThreadData *osl_tdata = nullptr;
+#endif
+
+#ifdef __PATH_GUIDING__
+ /* Pointers to global data structures. */
+ openpgl::cpp::SampleStorage *opgl_sample_data_storage = nullptr;
+ openpgl::cpp::Field *opgl_guiding_field = nullptr;
+
+ /* Local data structures owned by the thread. */
+ openpgl::cpp::PathSegmentStorage *opgl_path_segment_storage = nullptr;
+ openpgl::cpp::SurfaceSamplingDistribution *opgl_surface_sampling_distribution = nullptr;
+ openpgl::cpp::VolumeSamplingDistribution *opgl_volume_sampling_distribution = nullptr;
#endif
/* **** Run-time data **** */
diff --git a/intern/cycles/kernel/device/cpu/kernel.cpp b/intern/cycles/kernel/device/cpu/kernel.cpp
index 01087c96dd6..558431961ab 100644
--- a/intern/cycles/kernel/device/cpu/kernel.cpp
+++ b/intern/cycles/kernel/device/cpu/kernel.cpp
@@ -7,6 +7,7 @@
* one with SSE2 intrinsics.
*/
#if defined(__x86_64__) || defined(_M_X64)
+# define __KERNEL_SSE__
# define __KERNEL_SSE2__
#endif
@@ -29,11 +30,15 @@
# define __KERNEL_SSE41__
# endif
# ifdef __AVX__
-# define __KERNEL_SSE__
+# ifndef __KERNEL_SSE__
+# define __KERNEL_SSE__
+# endif
# define __KERNEL_AVX__
# endif
# ifdef __AVX2__
-# define __KERNEL_SSE__
+# ifndef __KERNEL_SSE__
+# define __KERNEL_SSE__
+# endif
# define __KERNEL_AVX2__
# endif
#endif
diff --git a/intern/cycles/kernel/device/cuda/compat.h b/intern/cycles/kernel/device/cuda/compat.h
index 51e1381d552..3a950779c11 100644
--- a/intern/cycles/kernel/device/cuda/compat.h
+++ b/intern/cycles/kernel/device/cuda/compat.h
@@ -30,6 +30,7 @@ typedef unsigned long long uint64_t;
/* Qualifiers */
#define ccl_device __device__ __inline__
+#define ccl_device_extern extern "C" __device__
#if __CUDA_ARCH__ < 500
# define ccl_device_inline __device__ __forceinline__
# define ccl_device_forceinline __device__ __forceinline__
@@ -109,14 +110,14 @@ ccl_device_forceinline T ccl_gpu_tex_object_read_3D(const ccl_gpu_tex_object_3D
typedef unsigned short half;
-__device__ half __float2half(const float f)
+ccl_device_forceinline half __float2half(const float f)
{
half val;
asm("{ cvt.rn.f16.f32 %0, %1;}\n" : "=h"(val) : "f"(f));
return val;
}
-__device__ float __half2float(const half h)
+ccl_device_forceinline float __half2float(const half h)
{
float val;
asm("{ cvt.f32.f16 %0, %1;}\n" : "=f"(val) : "h"(h));
diff --git a/intern/cycles/kernel/device/gpu/parallel_active_index.h b/intern/cycles/kernel/device/gpu/parallel_active_index.h
index c1df49c4f49..38cdcb572eb 100644
--- a/intern/cycles/kernel/device/gpu/parallel_active_index.h
+++ b/intern/cycles/kernel/device/gpu/parallel_active_index.h
@@ -23,22 +23,6 @@ CCL_NAMESPACE_BEGIN
* and keep device specific code in compat.h */
#ifdef __KERNEL_ONEAPI__
-# ifdef WITH_ONEAPI_SYCL_HOST_ENABLED
-template<typename IsActiveOp>
-void cpu_serial_active_index_array_impl(const uint num_states,
- ccl_global int *ccl_restrict indices,
- ccl_global int *ccl_restrict num_indices,
- IsActiveOp is_active_op)
-{
- int write_index = 0;
- for (int state_index = 0; state_index < num_states; state_index++) {
- if (is_active_op(state_index))
- indices[write_index++] = state_index;
- }
- *num_indices = write_index;
- return;
-}
-# endif /* WITH_ONEAPI_SYCL_HOST_ENABLED */
template<typename IsActiveOp>
void gpu_parallel_active_index_array_impl(const uint num_states,
@@ -182,18 +166,11 @@ __device__
num_simd_groups, \
simdgroup_offset)
#elif defined(__KERNEL_ONEAPI__)
-# ifdef WITH_ONEAPI_SYCL_HOST_ENABLED
-# define gpu_parallel_active_index_array( \
- blocksize, num_states, indices, num_indices, is_active_op) \
- if (ccl_gpu_global_size_x() == 1) \
- cpu_serial_active_index_array_impl(num_states, indices, num_indices, is_active_op); \
- else \
- gpu_parallel_active_index_array_impl(num_states, indices, num_indices, is_active_op);
-# else
-# define gpu_parallel_active_index_array( \
- blocksize, num_states, indices, num_indices, is_active_op) \
- gpu_parallel_active_index_array_impl(num_states, indices, num_indices, is_active_op)
-# endif
+
+# define gpu_parallel_active_index_array( \
+ blocksize, num_states, indices, num_indices, is_active_op) \
+ gpu_parallel_active_index_array_impl(num_states, indices, num_indices, is_active_op)
+
#else
# define gpu_parallel_active_index_array( \
diff --git a/intern/cycles/kernel/device/hip/compat.h b/intern/cycles/kernel/device/hip/compat.h
index 648988c31b6..8755395c82c 100644
--- a/intern/cycles/kernel/device/hip/compat.h
+++ b/intern/cycles/kernel/device/hip/compat.h
@@ -28,6 +28,7 @@ typedef unsigned long long uint64_t;
/* Qualifiers */
#define ccl_device __device__ __inline__
+#define ccl_device_extern extern "C" __device__
#define ccl_device_inline __device__ __inline__
#define ccl_device_forceinline __device__ __forceinline__
#define ccl_device_noinline __device__ __noinline__
diff --git a/intern/cycles/kernel/device/metal/compat.h b/intern/cycles/kernel/device/metal/compat.h
index 130a9ebafae..2dd6cc98b59 100644
--- a/intern/cycles/kernel/device/metal/compat.h
+++ b/intern/cycles/kernel/device/metal/compat.h
@@ -29,30 +29,16 @@ using namespace metal::raytracing;
/* Qualifiers */
-/* Inline everything for Apple GPUs. This gives ~1.1x speedup and 10% spill
- * reduction for integator_shade_surface. However it comes at the cost of
- * longer compile times (~4.5 minutes on M1 Max) and is disabled for that
- * reason, until there is a user option to manually enable it. */
-
-#if 0 // defined(__KERNEL_METAL_APPLE__)
-
-# define ccl_device __attribute__((always_inline))
-# define ccl_device_inline __attribute__((always_inline))
-# define ccl_device_forceinline __attribute__((always_inline))
-# define ccl_device_noinline __attribute__((always_inline))
-
+#define ccl_device
+#define ccl_device_inline ccl_device __attribute__((always_inline))
+#define ccl_device_forceinline ccl_device __attribute__((always_inline))
+#if defined(__KERNEL_METAL_APPLE__)
+# define ccl_device_noinline ccl_device
#else
-
-# define ccl_device
-# define ccl_device_inline ccl_device
-# define ccl_device_forceinline ccl_device
-# if defined(__KERNEL_METAL_APPLE__)
-# define ccl_device_noinline ccl_device
-# else
-# define ccl_device_noinline ccl_device __attribute__((noinline))
-# endif
+# define ccl_device_noinline ccl_device __attribute__((noinline))
#endif
+#define ccl_device_extern extern "C"
#define ccl_device_noinline_cpu ccl_device
#define ccl_device_inline_method ccl_device
#define ccl_global device
diff --git a/intern/cycles/kernel/device/metal/context_begin.h b/intern/cycles/kernel/device/metal/context_begin.h
index 99cb1e3826e..e75ec9cadec 100644
--- a/intern/cycles/kernel/device/metal/context_begin.h
+++ b/intern/cycles/kernel/device/metal/context_begin.h
@@ -34,21 +34,48 @@ class MetalKernelContext {
kernel_assert(0);
return 0;
}
-
+
+#ifdef __KERNEL_METAL_INTEL__
+ template<typename TextureType, typename CoordsType>
+ inline __attribute__((__always_inline__))
+ auto ccl_gpu_tex_object_read_intel_workaround(TextureType texture_array,
+ const uint tid, const uint sid,
+ CoordsType coords) const
+ {
+ switch(sid) {
+ default:
+ case 0: return texture_array[tid].tex.sample(sampler(address::repeat, filter::nearest), coords);
+ case 1: return texture_array[tid].tex.sample(sampler(address::clamp_to_edge, filter::nearest), coords);
+ case 2: return texture_array[tid].tex.sample(sampler(address::clamp_to_zero, filter::nearest), coords);
+ case 3: return texture_array[tid].tex.sample(sampler(address::repeat, filter::linear), coords);
+ case 4: return texture_array[tid].tex.sample(sampler(address::clamp_to_edge, filter::linear), coords);
+ case 5: return texture_array[tid].tex.sample(sampler(address::clamp_to_zero, filter::linear), coords);
+ }
+ }
+#endif
+
// texture2d
template<>
inline __attribute__((__always_inline__))
float4 ccl_gpu_tex_object_read_2D(ccl_gpu_tex_object_2D tex, float x, float y) const {
const uint tid(tex);
const uint sid(tex >> 32);
+#ifndef __KERNEL_METAL_INTEL__
return metal_ancillaries->textures_2d[tid].tex.sample(metal_samplers[sid], float2(x, y));
+#else
+ return ccl_gpu_tex_object_read_intel_workaround(metal_ancillaries->textures_2d, tid, sid, float2(x, y));
+#endif
}
template<>
inline __attribute__((__always_inline__))
float ccl_gpu_tex_object_read_2D(ccl_gpu_tex_object_2D tex, float x, float y) const {
const uint tid(tex);
const uint sid(tex >> 32);
+#ifndef __KERNEL_METAL_INTEL__
return metal_ancillaries->textures_2d[tid].tex.sample(metal_samplers[sid], float2(x, y)).x;
+#else
+ return ccl_gpu_tex_object_read_intel_workaround(metal_ancillaries->textures_2d, tid, sid, float2(x, y)).x;
+#endif
}
// texture3d
@@ -57,14 +84,22 @@ class MetalKernelContext {
float4 ccl_gpu_tex_object_read_3D(ccl_gpu_tex_object_3D tex, float x, float y, float z) const {
const uint tid(tex);
const uint sid(tex >> 32);
+#ifndef __KERNEL_METAL_INTEL__
return metal_ancillaries->textures_3d[tid].tex.sample(metal_samplers[sid], float3(x, y, z));
+#else
+ return ccl_gpu_tex_object_read_intel_workaround(metal_ancillaries->textures_3d, tid, sid, float3(x, y, z));
+#endif
}
template<>
inline __attribute__((__always_inline__))
float ccl_gpu_tex_object_read_3D(ccl_gpu_tex_object_3D tex, float x, float y, float z) const {
const uint tid(tex);
const uint sid(tex >> 32);
+#ifndef __KERNEL_METAL_INTEL__
return metal_ancillaries->textures_3d[tid].tex.sample(metal_samplers[sid], float3(x, y, z)).x;
+#else
+ return ccl_gpu_tex_object_read_intel_workaround(metal_ancillaries->textures_3d, tid, sid, float3(x, y, z)).x;
+#endif
}
# include "kernel/device/gpu/image.h"
diff --git a/intern/cycles/kernel/device/metal/kernel.metal b/intern/cycles/kernel/device/metal/kernel.metal
index 5646c7446db..8b69ee025cd 100644
--- a/intern/cycles/kernel/device/metal/kernel.metal
+++ b/intern/cycles/kernel/device/metal/kernel.metal
@@ -228,7 +228,7 @@ bool metalrt_shadow_all_hit(constant KernelParamsMetal &launch_params_metal,
/* Always use baked shadow transparency for curves. */
if (type & PRIMITIVE_CURVE) {
float throughput = payload.throughput;
- throughput *= context.intersection_curve_shadow_transparency(nullptr, object, prim, u);
+ throughput *= context.intersection_curve_shadow_transparency(nullptr, object, prim, type, u);
payload.throughput = throughput;
payload.num_hits += 1;
diff --git a/intern/cycles/kernel/device/oneapi/compat.h b/intern/cycles/kernel/device/oneapi/compat.h
index 5c49674f247..b83512180d7 100644
--- a/intern/cycles/kernel/device/oneapi/compat.h
+++ b/intern/cycles/kernel/device/oneapi/compat.h
@@ -10,6 +10,7 @@
#define CCL_NAMESPACE_END
#include <cstdint>
+#include <math.h>
#ifndef __NODES_MAX_GROUP__
# define __NODES_MAX_GROUP__ NODE_GROUP_LEVEL_MAX
@@ -27,6 +28,7 @@
/* Qualifier wrappers for different names on different devices */
#define ccl_device
+#define ccl_device_extern extern "C"
#define ccl_global
#define ccl_always_inline __attribute__((always_inline))
#define ccl_device_inline inline
@@ -54,18 +56,6 @@
#define ccl_gpu_kernel(block_num_threads, thread_num_registers)
#define ccl_gpu_kernel_threads(block_num_threads)
-#ifdef WITH_ONEAPI_SYCL_HOST_ENABLED
-# define KG_ND_ITEMS \
- kg->nd_item_local_id_0 = item.get_local_id(0); \
- kg->nd_item_local_range_0 = item.get_local_range(0); \
- kg->nd_item_group_0 = item.get_group(0); \
- kg->nd_item_group_range_0 = item.get_group_range(0); \
- kg->nd_item_global_id_0 = item.get_global_id(0); \
- kg->nd_item_global_range_0 = item.get_global_range(0);
-#else
-# define KG_ND_ITEMS
-#endif
-
#define ccl_gpu_kernel_signature(name, ...) \
void oneapi_kernel_##name(KernelGlobalsGPU *ccl_restrict kg, \
size_t kernel_global_size, \
@@ -75,8 +65,7 @@ void oneapi_kernel_##name(KernelGlobalsGPU *ccl_restrict kg, \
(kg); \
cgh.parallel_for<class kernel_##name>( \
sycl::nd_range<1>(kernel_global_size, kernel_local_size), \
- [=](sycl::nd_item<1> item) { \
- KG_ND_ITEMS
+ [=](sycl::nd_item<1> item) {
#define ccl_gpu_kernel_postfix \
}); \
@@ -94,31 +83,17 @@ void oneapi_kernel_##name(KernelGlobalsGPU *ccl_restrict kg, \
} ccl_gpu_kernel_lambda_pass((ONEAPIKernelContext *)kg)
/* GPU thread, block, grid size and index */
-#ifndef WITH_ONEAPI_SYCL_HOST_ENABLED
-# define ccl_gpu_thread_idx_x (sycl::ext::oneapi::experimental::this_nd_item<1>().get_local_id(0))
-# define ccl_gpu_block_dim_x (sycl::ext::oneapi::experimental::this_nd_item<1>().get_local_range(0))
-# define ccl_gpu_block_idx_x (sycl::ext::oneapi::experimental::this_nd_item<1>().get_group(0))
-# define ccl_gpu_grid_dim_x (sycl::ext::oneapi::experimental::this_nd_item<1>().get_group_range(0))
-# define ccl_gpu_warp_size (sycl::ext::oneapi::experimental::this_sub_group().get_local_range()[0])
-# define ccl_gpu_thread_mask(thread_warp) uint(0xFFFFFFFF >> (ccl_gpu_warp_size - thread_warp))
-
-# define ccl_gpu_global_id_x() (sycl::ext::oneapi::experimental::this_nd_item<1>().get_global_id(0))
-# define ccl_gpu_global_size_x() (sycl::ext::oneapi::experimental::this_nd_item<1>().get_global_range(0))
-#else
-# define ccl_gpu_thread_idx_x (kg->nd_item_local_id_0)
-# define ccl_gpu_block_dim_x (kg->nd_item_local_range_0)
-# define ccl_gpu_block_idx_x (kg->nd_item_group_0)
-# define ccl_gpu_grid_dim_x (kg->nd_item_group_range_0)
-# define ccl_gpu_warp_size (sycl::ext::oneapi::experimental::this_sub_group().get_local_range()[0])
-# define ccl_gpu_thread_mask(thread_warp) uint(0xFFFFFFFF >> (ccl_gpu_warp_size - thread_warp))
-
-# define ccl_gpu_global_id_x() (kg->nd_item_global_id_0)
-# define ccl_gpu_global_size_x() (kg->nd_item_global_range_0)
-#endif
+#define ccl_gpu_thread_idx_x (sycl::ext::oneapi::experimental::this_nd_item<1>().get_local_id(0))
+#define ccl_gpu_block_dim_x (sycl::ext::oneapi::experimental::this_nd_item<1>().get_local_range(0))
+#define ccl_gpu_block_idx_x (sycl::ext::oneapi::experimental::this_nd_item<1>().get_group(0))
+#define ccl_gpu_grid_dim_x (sycl::ext::oneapi::experimental::this_nd_item<1>().get_group_range(0))
+#define ccl_gpu_warp_size (sycl::ext::oneapi::experimental::this_sub_group().get_local_range()[0])
+#define ccl_gpu_thread_mask(thread_warp) uint(0xFFFFFFFF >> (ccl_gpu_warp_size - thread_warp))
+#define ccl_gpu_global_id_x() (sycl::ext::oneapi::experimental::this_nd_item<1>().get_global_id(0))
+#define ccl_gpu_global_size_x() (sycl::ext::oneapi::experimental::this_nd_item<1>().get_global_range(0))
/* GPU warp synchronization */
-
#define ccl_gpu_syncthreads() sycl::ext::oneapi::experimental::this_nd_item<1>().barrier()
#define ccl_gpu_local_syncthreads() sycl::ext::oneapi::experimental::this_nd_item<1>().barrier(sycl::access::fence_space::local_space)
#ifdef __SYCL_DEVICE_ONLY__
@@ -174,21 +149,15 @@ using sycl::half;
#define fmodf(x, y) sycl::fmod((x), (y))
#define lgammaf(x) sycl::lgamma((x))
-#define __forceinline __attribute__((always_inline))
-
-/* Types */
-#include "util/half.h"
-#include "util/types.h"
-
-/* NOTE(@nsirgien): Declaring these functions after types headers is very important because they
- * include oneAPI headers, which transitively include math.h headers which will cause redefinitions
- * of the math defines because math.h also uses them and having them defined before math.h include
- * is actually UB. */
-/* Use fast math functions - get them from sycl::native namespace for native math function
- * implementations */
#define cosf(x) sycl::native::cos(((float)(x)))
#define sinf(x) sycl::native::sin(((float)(x)))
#define powf(x, y) sycl::native::powr(((float)(x)), ((float)(y)))
#define tanf(x) sycl::native::tan(((float)(x)))
#define logf(x) sycl::native::log(((float)(x)))
#define expf(x) sycl::native::exp(((float)(x)))
+
+#define __forceinline __attribute__((always_inline))
+
+/* Types */
+#include "util/half.h"
+#include "util/types.h"
diff --git a/intern/cycles/kernel/device/oneapi/dll_interface_template.h b/intern/cycles/kernel/device/oneapi/dll_interface_template.h
deleted file mode 100644
index 5dd0d4203a4..00000000000
--- a/intern/cycles/kernel/device/oneapi/dll_interface_template.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* SPDX-License-Identifier: Apache-2.0
- * Copyright 2022 Intel Corporation */
-
-/* device_capabilities() returns a C string that must be free'd with oneapi_free(). */
-DLL_INTERFACE_CALL(oneapi_device_capabilities, char *)
-DLL_INTERFACE_CALL(oneapi_free, void, void *)
-DLL_INTERFACE_CALL(oneapi_get_memcapacity, size_t, SyclQueue *queue)
-
-DLL_INTERFACE_CALL(oneapi_get_num_multiprocessors, int, SyclQueue *queue)
-DLL_INTERFACE_CALL(oneapi_get_max_num_threads_per_multiprocessor, int, SyclQueue *queue)
-DLL_INTERFACE_CALL(oneapi_iterate_devices, void, OneAPIDeviceIteratorCallback cb, void *user_ptr)
-DLL_INTERFACE_CALL(oneapi_set_error_cb, void, OneAPIErrorCallback, void *user_ptr)
-
-DLL_INTERFACE_CALL(oneapi_create_queue, bool, SyclQueue *&external_queue, int device_index)
-DLL_INTERFACE_CALL(oneapi_free_queue, void, SyclQueue *queue)
-DLL_INTERFACE_CALL(
- oneapi_usm_aligned_alloc_host, void *, SyclQueue *queue, size_t memory_size, size_t alignment)
-DLL_INTERFACE_CALL(oneapi_usm_alloc_device, void *, SyclQueue *queue, size_t memory_size)
-DLL_INTERFACE_CALL(oneapi_usm_free, void, SyclQueue *queue, void *usm_ptr)
-
-DLL_INTERFACE_CALL(
- oneapi_usm_memcpy, bool, SyclQueue *queue, void *dest, void *src, size_t num_bytes)
-DLL_INTERFACE_CALL(oneapi_queue_synchronize, bool, SyclQueue *queue)
-DLL_INTERFACE_CALL(oneapi_usm_memset,
- bool,
- SyclQueue *queue,
- void *usm_ptr,
- unsigned char value,
- size_t num_bytes)
-
-DLL_INTERFACE_CALL(oneapi_run_test_kernel, bool, SyclQueue *queue)
-
-/* Operation with Kernel globals structure - map of global/constant allocation - filled before
- * render/kernel execution As we don't know in cycles `sizeof` this - Cycles will manage just as
- * pointer. */
-DLL_INTERFACE_CALL(oneapi_kernel_globals_size, bool, SyclQueue *queue, size_t &kernel_global_size)
-DLL_INTERFACE_CALL(oneapi_set_global_memory,
- void,
- SyclQueue *queue,
- void *kernel_globals,
- const char *memory_name,
- void *memory_device_pointer)
-
-DLL_INTERFACE_CALL(oneapi_kernel_preferred_local_size,
- size_t,
- SyclQueue *queue,
- const DeviceKernel kernel,
- const size_t kernel_global_size)
-DLL_INTERFACE_CALL(oneapi_enqueue_kernel,
- bool,
- KernelContext *context,
- int kernel,
- size_t global_size,
- void **args)
diff --git a/intern/cycles/kernel/device/oneapi/globals.h b/intern/cycles/kernel/device/oneapi/globals.h
index d60f4f135ba..116620eb725 100644
--- a/intern/cycles/kernel/device/oneapi/globals.h
+++ b/intern/cycles/kernel/device/oneapi/globals.h
@@ -23,15 +23,6 @@ typedef struct KernelGlobalsGPU {
#undef KERNEL_DATA_ARRAY
IntegratorStateGPU *integrator_state;
const KernelData *__data;
-#ifdef WITH_ONEAPI_SYCL_HOST_ENABLED
- size_t nd_item_local_id_0;
- size_t nd_item_local_range_0;
- size_t nd_item_group_0;
- size_t nd_item_group_range_0;
-
- size_t nd_item_global_id_0;
- size_t nd_item_global_range_0;
-#endif
} KernelGlobalsGPU;
typedef ccl_global KernelGlobalsGPU *ccl_restrict KernelGlobals;
diff --git a/intern/cycles/kernel/device/oneapi/kernel.cpp b/intern/cycles/kernel/device/oneapi/kernel.cpp
index 097d21b963f..525ae288f0c 100644
--- a/intern/cycles/kernel/device/oneapi/kernel.cpp
+++ b/intern/cycles/kernel/device/oneapi/kernel.cpp
@@ -3,208 +3,79 @@
#ifdef WITH_ONEAPI
-/* clang-format off */
# include "kernel.h"
# include <iostream>
# include <map>
# include <set>
-# include <CL/sycl.hpp>
+# include <sycl/sycl.hpp>
# include "kernel/device/oneapi/compat.h"
# include "kernel/device/oneapi/globals.h"
# include "kernel/device/oneapi/kernel_templates.h"
# include "kernel/device/gpu/kernel.h"
-/* clang-format on */
static OneAPIErrorCallback s_error_cb = nullptr;
static void *s_error_user_ptr = nullptr;
-static std::vector<sycl::device> oneapi_available_devices();
-
void oneapi_set_error_cb(OneAPIErrorCallback cb, void *user_ptr)
{
s_error_cb = cb;
s_error_user_ptr = user_ptr;
}
-void oneapi_check_usm(SyclQueue *queue_, const void *usm_ptr, bool allow_host = false)
-{
-# ifdef _DEBUG
- sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
- sycl::info::device_type device_type =
- queue->get_device().get_info<sycl::info::device::device_type>();
- sycl::usm::alloc usm_type = get_pointer_type(usm_ptr, queue->get_context());
- (void)usm_type;
- assert(usm_type == sycl::usm::alloc::device ||
- ((device_type == sycl::info::device_type::host ||
- device_type == sycl::info::device_type::is_cpu || allow_host) &&
- usm_type == sycl::usm::alloc::host));
-# endif
-}
-
-bool oneapi_create_queue(SyclQueue *&external_queue, int device_index)
-{
- bool finished_correct = true;
- try {
- std::vector<sycl::device> devices = oneapi_available_devices();
- if (device_index < 0 || device_index >= devices.size()) {
- return false;
- }
- sycl::queue *created_queue = new sycl::queue(devices[device_index],
- sycl::property::queue::in_order());
- external_queue = reinterpret_cast<SyclQueue *>(created_queue);
- }
- catch (sycl::exception const &e) {
- finished_correct = false;
- if (s_error_cb) {
- s_error_cb(e.what(), s_error_user_ptr);
- }
- }
- return finished_correct;
-}
-
-void oneapi_free_queue(SyclQueue *queue_)
-{
- assert(queue_);
- sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
- delete queue;
-}
-
-void *oneapi_usm_aligned_alloc_host(SyclQueue *queue_, size_t memory_size, size_t alignment)
-{
- assert(queue_);
- sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
- return sycl::aligned_alloc_host(alignment, memory_size, *queue);
-}
-
-void *oneapi_usm_alloc_device(SyclQueue *queue_, size_t memory_size)
-{
- assert(queue_);
- sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
- return sycl::malloc_device(memory_size, *queue);
-}
-
-void oneapi_usm_free(SyclQueue *queue_, void *usm_ptr)
+/* NOTE(@nsirgien): Execution of this simple kernel will check basic functionality like
+ * memory allocations, memory transfers and execution of kernel with USM memory. */
+bool oneapi_run_test_kernel(SyclQueue *queue_)
{
assert(queue_);
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
- oneapi_check_usm(queue_, usm_ptr, true);
- sycl::free(usm_ptr, *queue);
-}
+ const size_t N = 8;
+ const size_t memory_byte_size = sizeof(int) * N;
-bool oneapi_usm_memcpy(SyclQueue *queue_, void *dest, void *src, size_t num_bytes)
-{
- assert(queue_);
- sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
- oneapi_check_usm(queue_, dest, true);
- oneapi_check_usm(queue_, src, true);
- sycl::event mem_event = queue->memcpy(dest, src, num_bytes);
-# ifdef WITH_CYCLES_DEBUG
+ bool is_computation_correct = true;
try {
- /* NOTE(@nsirgien) Waiting on memory operation may give more precise error
- * messages. Due to impact on occupancy, it makes sense to enable it only during Cycles debug.
- */
- mem_event.wait_and_throw();
- return true;
- }
- catch (sycl::exception const &e) {
- if (s_error_cb) {
- s_error_cb(e.what(), s_error_user_ptr);
- }
- return false;
- }
-# else
- sycl::usm::alloc dest_type = get_pointer_type(dest, queue->get_context());
- sycl::usm::alloc src_type = get_pointer_type(src, queue->get_context());
- bool from_device_to_host = dest_type == sycl::usm::alloc::host &&
- src_type == sycl::usm::alloc::device;
- bool host_or_device_memop_with_offset = dest_type == sycl::usm::alloc::unknown ||
- src_type == sycl::usm::alloc::unknown;
- /* NOTE(@sirgienko) Host-side blocking wait on this operation is mandatory, otherwise the host
- * may not wait until the end of the transfer before using the memory.
- */
- if (from_device_to_host || host_or_device_memop_with_offset)
- mem_event.wait();
- return true;
-# endif
-}
+ int *A_host = (int *)sycl::aligned_alloc_host(16, memory_byte_size, *queue);
-bool oneapi_usm_memset(SyclQueue *queue_, void *usm_ptr, unsigned char value, size_t num_bytes)
-{
- assert(queue_);
- sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
- oneapi_check_usm(queue_, usm_ptr, true);
- sycl::event mem_event = queue->memset(usm_ptr, value, num_bytes);
-# ifdef WITH_CYCLES_DEBUG
- try {
- /* NOTE(@nsirgien) Waiting on memory operation may give more precise error
- * messages. Due to impact on occupancy, it makes sense to enable it only during Cycles debug.
- */
- mem_event.wait_and_throw();
- return true;
- }
- catch (sycl::exception const &e) {
- if (s_error_cb) {
- s_error_cb(e.what(), s_error_user_ptr);
+ for (size_t i = (size_t)0; i < N; i++) {
+ A_host[i] = rand() % 32;
}
- return false;
- }
-# else
- (void)mem_event;
- return true;
-# endif
-}
-bool oneapi_queue_synchronize(SyclQueue *queue_)
-{
- assert(queue_);
- sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
- try {
- queue->wait_and_throw();
- return true;
- }
- catch (sycl::exception const &e) {
- if (s_error_cb) {
- s_error_cb(e.what(), s_error_user_ptr);
- }
- return false;
- }
-}
+ int *A_device = (int *)sycl::malloc_device(memory_byte_size, *queue);
+ int *B_device = (int *)sycl::malloc_device(memory_byte_size, *queue);
-/* NOTE(@nsirgien): Execution of this simple kernel will check basic functionality and
- * also trigger runtime compilation of all existing oneAPI kernels */
-bool oneapi_run_test_kernel(SyclQueue *queue_)
-{
- assert(queue_);
- sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
- size_t N = 8;
- sycl::buffer<float, 1> A(N);
- sycl::buffer<float, 1> B(N);
-
- {
- sycl::host_accessor A_host_acc(A, sycl::write_only);
- for (size_t i = (size_t)0; i < N; i++)
- A_host_acc[i] = rand() % 32;
- }
+ queue->memcpy(A_device, A_host, memory_byte_size);
+ queue->wait_and_throw();
- try {
queue->submit([&](sycl::handler &cgh) {
- sycl::accessor A_acc(A, cgh, sycl::read_only);
- sycl::accessor B_acc(B, cgh, sycl::write_only, sycl::no_init);
-
- cgh.parallel_for(N, [=](sycl::id<1> idx) { B_acc[idx] = A_acc[idx] + idx.get(0); });
+ cgh.parallel_for(N, [=](sycl::id<1> idx) { B_device[idx] = A_device[idx] + idx.get(0); });
});
queue->wait_and_throw();
- sycl::host_accessor A_host_acc(A, sycl::read_only);
- sycl::host_accessor B_host_acc(B, sycl::read_only);
+ int *B_host = (int *)sycl::aligned_alloc_host(16, memory_byte_size, *queue);
+
+ queue->memcpy(B_host, B_device, memory_byte_size);
+ queue->wait_and_throw();
for (size_t i = (size_t)0; i < N; i++) {
- float result = A_host_acc[i] + B_host_acc[i];
- (void)result;
+ const int expected_result = i + A_host[i];
+ if (B_host[i] != expected_result) {
+ is_computation_correct = false;
+ if (s_error_cb) {
+ s_error_cb(("Incorrect result in test kernel execution - expected " +
+ std::to_string(expected_result) + ", got " + std::to_string(B_host[i]))
+ .c_str(),
+ s_error_user_ptr);
+ }
+ }
}
+
+ sycl::free(A_host, *queue);
+ sycl::free(B_host, *queue);
+ sycl::free(A_device, *queue);
+ sycl::free(B_device, *queue);
+ queue->wait_and_throw();
}
catch (sycl::exception const &e) {
if (s_error_cb) {
@@ -213,63 +84,16 @@ bool oneapi_run_test_kernel(SyclQueue *queue_)
return false;
}
- return true;
-}
-
-bool oneapi_kernel_globals_size(SyclQueue *queue_, size_t &kernel_global_size)
-{
- kernel_global_size = sizeof(KernelGlobalsGPU);
-
- return true;
-}
-
-void oneapi_set_global_memory(SyclQueue *queue_,
- void *kernel_globals,
- const char *memory_name,
- void *memory_device_pointer)
-{
- assert(queue_);
- assert(kernel_globals);
- assert(memory_name);
- assert(memory_device_pointer);
- KernelGlobalsGPU *globals = (KernelGlobalsGPU *)kernel_globals;
- oneapi_check_usm(queue_, memory_device_pointer);
- oneapi_check_usm(queue_, kernel_globals, true);
-
- std::string matched_name(memory_name);
-
-/* This macro will change global ptr of KernelGlobals via name matching. */
-# define KERNEL_DATA_ARRAY(type, name) \
- else if (#name == matched_name) \
- { \
- globals->__##name = (type *)memory_device_pointer; \
- return; \
- }
- if (false) {
- }
- else if ("integrator_state" == matched_name) {
- globals->integrator_state = (IntegratorStateGPU *)memory_device_pointer;
- return;
- }
- KERNEL_DATA_ARRAY(KernelData, data)
-# include "kernel/data_arrays.h"
- else
- {
- std::cerr << "Can't found global/constant memory with name \"" << matched_name << "\"!"
- << std::endl;
- assert(false);
- }
-# undef KERNEL_DATA_ARRAY
+ return is_computation_correct;
}
/* TODO: Move device information to OneapiDevice initialized on creation and use it. */
/* TODO: Move below function to oneapi/queue.cpp. */
-size_t oneapi_kernel_preferred_local_size(SyclQueue *queue_,
+size_t oneapi_kernel_preferred_local_size(SyclQueue *queue,
const DeviceKernel kernel,
const size_t kernel_global_size)
{
- assert(queue_);
- sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
+ assert(queue);
(void)kernel_global_size;
const static size_t preferred_work_group_size_intersect_shading = 32;
const static size_t preferred_work_group_size_technical = 1024;
@@ -311,11 +135,63 @@ size_t oneapi_kernel_preferred_local_size(SyclQueue *queue_,
preferred_work_group_size = 512;
}
- const size_t limit_work_group_size =
- queue->get_device().get_info<sycl::info::device::max_work_group_size>();
+ const size_t limit_work_group_size = reinterpret_cast<sycl::queue *>(queue)
+ ->get_device()
+ .get_info<sycl::info::device::max_work_group_size>();
+
return std::min(limit_work_group_size, preferred_work_group_size);
}
+bool oneapi_load_kernels(SyclQueue *queue_, const uint requested_features)
+{
+# ifdef SYCL_SKIP_KERNELS_PRELOAD
+ (void)queue_;
+ (void)requested_features;
+# else
+ assert(queue_);
+ sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
+
+ try {
+ sycl::kernel_bundle<sycl::bundle_state::input> all_kernels_bundle =
+ sycl::get_kernel_bundle<sycl::bundle_state::input>(queue->get_context(),
+ {queue->get_device()});
+
+ for (const sycl::kernel_id &kernel_id : all_kernels_bundle.get_kernel_ids()) {
+ const std::string &kernel_name = kernel_id.get_name();
+
+ /* NOTE(@nsirgien): Names in this conditions below should match names from
+ * oneapi_call macro in oneapi_enqueue_kernel below */
+ if (((requested_features & KERNEL_FEATURE_VOLUME) == 0) &&
+ kernel_name.find("oneapi_kernel_integrator_shade_volume") != std::string::npos) {
+ continue;
+ }
+
+ if (((requested_features & KERNEL_FEATURE_MNEE) == 0) &&
+ kernel_name.find("oneapi_kernel_integrator_shade_surface_mnee") != std::string::npos) {
+ continue;
+ }
+
+ if (((requested_features & KERNEL_FEATURE_NODE_RAYTRACE) == 0) &&
+ kernel_name.find("oneapi_kernel_integrator_shade_surface_raytrace") !=
+ std::string::npos) {
+ continue;
+ }
+
+ sycl::kernel_bundle<sycl::bundle_state::input> one_kernel_bundle =
+ sycl::get_kernel_bundle<sycl::bundle_state::input>(queue->get_context(), {kernel_id});
+ sycl::build(one_kernel_bundle);
+ }
+ }
+ catch (sycl::exception const &e) {
+ if (s_error_cb) {
+ s_error_cb(e.what(), s_error_user_ptr);
+ }
+ return false;
+ }
+# endif
+ return true;
+}
+
bool oneapi_enqueue_kernel(KernelContext *kernel_context,
int kernel,
size_t global_size,
@@ -354,13 +230,6 @@ bool oneapi_enqueue_kernel(KernelContext *kernel_context,
/* NOTE(@nsirgien): As for now non-uniform work-groups don't work on most oneAPI devices,
* we extend work size to fit uniformity requirements. */
global_size = groups_count * local_size;
-
-# ifdef WITH_ONEAPI_SYCL_HOST_ENABLED
- if (queue->get_device().is_host()) {
- global_size = 1;
- local_size = 1;
- }
-# endif
}
/* Let the compiler throw an error if there are any kernels missing in this implementation. */
@@ -664,266 +533,4 @@ bool oneapi_enqueue_kernel(KernelContext *kernel_context,
# endif
return success;
}
-
-/* Compute-runtime (ie. NEO) version is what gets returned by sycl/L0 on Windows
- * since Windows driver 101.3268. */
-/* The same min compute-runtime version is currently required across Windows and Linux.
- * For Windows driver 101.3268, compute-runtime version is 23570. */
-static const int lowest_supported_driver_version_win = 1013268;
-static const int lowest_supported_driver_version_neo = 23570;
-
-static int parse_driver_build_version(const sycl::device &device)
-{
- const std::string &driver_version = device.get_info<sycl::info::device::driver_version>();
- int driver_build_version = 0;
-
- size_t second_dot_position = driver_version.find('.', driver_version.find('.') + 1);
- if (second_dot_position == std::string::npos) {
- std::cerr << "Unable to parse unknown Intel GPU driver version \"" << driver_version
- << "\" does not match xx.xx.xxxxx (Linux), x.x.xxxx (L0),"
- << " xx.xx.xxx.xxxx (Windows) for device \""
- << device.get_info<sycl::info::device::name>() << "\"." << std::endl;
- }
- else {
- try {
- size_t third_dot_position = driver_version.find('.', second_dot_position + 1);
- if (third_dot_position != std::string::npos) {
- const std::string &third_number_substr = driver_version.substr(
- second_dot_position + 1, third_dot_position - second_dot_position - 1);
- const std::string &forth_number_substr = driver_version.substr(third_dot_position + 1);
- if (third_number_substr.length() == 3 && forth_number_substr.length() == 4)
- driver_build_version = std::stoi(third_number_substr) * 10000 +
- std::stoi(forth_number_substr);
- }
- else {
- const std::string &third_number_substr = driver_version.substr(second_dot_position + 1);
- driver_build_version = std::stoi(third_number_substr);
- }
- }
- catch (std::invalid_argument &e) {
- std::cerr << "Unable to parse unknown Intel GPU driver version \"" << driver_version
- << "\" does not match xx.xx.xxxxx (Linux), x.x.xxxx (L0),"
- << " xx.xx.xxx.xxxx (Windows) for device \""
- << device.get_info<sycl::info::device::name>() << "\"." << std::endl;
- }
- }
-
- return driver_build_version;
-}
-
-static std::vector<sycl::device> oneapi_available_devices()
-{
- bool allow_all_devices = false;
- if (getenv("CYCLES_ONEAPI_ALL_DEVICES") != nullptr)
- allow_all_devices = true;
-
- /* Host device is useful only for debugging at the moment
- * so we hide this device with default build settings. */
-# ifdef WITH_ONEAPI_SYCL_HOST_ENABLED
- bool allow_host = true;
-# else
- bool allow_host = false;
-# endif
-
- const std::vector<sycl::platform> &oneapi_platforms = sycl::platform::get_platforms();
-
- std::vector<sycl::device> available_devices;
- for (const sycl::platform &platform : oneapi_platforms) {
- /* ignore OpenCL platforms to avoid using the same devices through both Level-Zero and OpenCL.
- */
- if (platform.get_backend() == sycl::backend::opencl) {
- continue;
- }
-
- const std::vector<sycl::device> &oneapi_devices =
- (allow_all_devices || allow_host) ? platform.get_devices(sycl::info::device_type::all) :
- platform.get_devices(sycl::info::device_type::gpu);
-
- for (const sycl::device &device : oneapi_devices) {
- if (allow_all_devices) {
- /* still filter out host device if build doesn't support it. */
- if (allow_host || !device.is_host()) {
- available_devices.push_back(device);
- }
- }
- else {
- bool filter_out = false;
-
- /* For now we support all Intel(R) Arc(TM) devices and likely any future GPU,
- * assuming they have either more than 96 Execution Units or not 7 threads per EU.
- * Official support can be broaden to older and smaller GPUs once ready. */
- if (device.is_gpu() && platform.get_backend() == sycl::backend::ext_oneapi_level_zero) {
- /* Filtered-out defaults in-case these values aren't available through too old L0
- * runtime. */
- int number_of_eus = 96;
- int threads_per_eu = 7;
- if (device.has(sycl::aspect::ext_intel_gpu_eu_count)) {
- number_of_eus = device.get_info<sycl::info::device::ext_intel_gpu_eu_count>();
- }
- if (device.has(sycl::aspect::ext_intel_gpu_hw_threads_per_eu)) {
- threads_per_eu =
- device.get_info<sycl::info::device::ext_intel_gpu_hw_threads_per_eu>();
- }
- /* This filters out all Level-Zero supported GPUs from older generation than Arc. */
- if (number_of_eus <= 96 && threads_per_eu == 7) {
- filter_out = true;
- }
- /* if not already filtered out, check driver version. */
- if (!filter_out) {
- int driver_build_version = parse_driver_build_version(device);
- if ((driver_build_version > 100000 &&
- driver_build_version < lowest_supported_driver_version_win) ||
- driver_build_version < lowest_supported_driver_version_neo) {
- filter_out = true;
- }
- }
- }
- else if (!allow_host && device.is_host()) {
- filter_out = true;
- }
- else if (!allow_all_devices) {
- filter_out = true;
- }
-
- if (!filter_out) {
- available_devices.push_back(device);
- }
- }
- }
- }
-
- return available_devices;
-}
-
-char *oneapi_device_capabilities()
-{
- std::stringstream capabilities;
-
- const std::vector<sycl::device> &oneapi_devices = oneapi_available_devices();
- for (const sycl::device &device : oneapi_devices) {
- const std::string &name = device.get_info<sycl::info::device::name>();
-
- capabilities << std::string("\t") << name << "\n";
-# define WRITE_ATTR(attribute_name, attribute_variable) \
- capabilities << "\t\tsycl::info::device::" #attribute_name "\t\t\t" << attribute_variable \
- << "\n";
-# define GET_NUM_ATTR(attribute) \
- { \
- size_t attribute = (size_t)device.get_info<sycl::info::device ::attribute>(); \
- capabilities << "\t\tsycl::info::device::" #attribute "\t\t\t" << attribute << "\n"; \
- }
-
- GET_NUM_ATTR(vendor_id)
- GET_NUM_ATTR(max_compute_units)
- GET_NUM_ATTR(max_work_item_dimensions)
-
- sycl::id<3> max_work_item_sizes =
- device.get_info<sycl::info::device::max_work_item_sizes<3>>();
- WRITE_ATTR("max_work_item_sizes_dim0", ((size_t)max_work_item_sizes.get(0)))
- WRITE_ATTR("max_work_item_sizes_dim1", ((size_t)max_work_item_sizes.get(1)))
- WRITE_ATTR("max_work_item_sizes_dim2", ((size_t)max_work_item_sizes.get(2)))
-
- GET_NUM_ATTR(max_work_group_size)
- GET_NUM_ATTR(max_num_sub_groups)
- GET_NUM_ATTR(sub_group_independent_forward_progress)
-
- GET_NUM_ATTR(preferred_vector_width_char)
- GET_NUM_ATTR(preferred_vector_width_short)
- GET_NUM_ATTR(preferred_vector_width_int)
- GET_NUM_ATTR(preferred_vector_width_long)
- GET_NUM_ATTR(preferred_vector_width_float)
- GET_NUM_ATTR(preferred_vector_width_double)
- GET_NUM_ATTR(preferred_vector_width_half)
-
- GET_NUM_ATTR(native_vector_width_char)
- GET_NUM_ATTR(native_vector_width_short)
- GET_NUM_ATTR(native_vector_width_int)
- GET_NUM_ATTR(native_vector_width_long)
- GET_NUM_ATTR(native_vector_width_float)
- GET_NUM_ATTR(native_vector_width_double)
- GET_NUM_ATTR(native_vector_width_half)
-
- size_t max_clock_frequency =
- (size_t)(device.is_host() ? (size_t)0 :
- device.get_info<sycl::info::device::max_clock_frequency>());
- WRITE_ATTR("max_clock_frequency", max_clock_frequency)
-
- GET_NUM_ATTR(address_bits)
- GET_NUM_ATTR(max_mem_alloc_size)
-
- /* NOTE(@nsirgien): Implementation doesn't use image support as bindless images aren't
- * supported so we always return false, even if device supports HW texture usage acceleration.
- */
- bool image_support = false;
- WRITE_ATTR("image_support", (size_t)image_support)
-
- GET_NUM_ATTR(max_parameter_size)
- GET_NUM_ATTR(mem_base_addr_align)
- GET_NUM_ATTR(global_mem_size)
- GET_NUM_ATTR(local_mem_size)
- GET_NUM_ATTR(error_correction_support)
- GET_NUM_ATTR(profiling_timer_resolution)
- GET_NUM_ATTR(is_available)
-
-# undef GET_NUM_ATTR
-# undef WRITE_ATTR
- capabilities << "\n";
- }
-
- return ::strdup(capabilities.str().c_str());
-}
-
-void oneapi_free(void *p)
-{
- if (p) {
- ::free(p);
- }
-}
-
-void oneapi_iterate_devices(OneAPIDeviceIteratorCallback cb, void *user_ptr)
-{
- int num = 0;
- std::vector<sycl::device> devices = oneapi_available_devices();
- for (sycl::device &device : devices) {
- const std::string &platform_name =
- device.get_platform().get_info<sycl::info::platform::name>();
- std::string name = device.get_info<sycl::info::device::name>();
- std::string id = "ONEAPI_" + platform_name + "_" + name;
- if (device.has(sycl::aspect::ext_intel_pci_address)) {
- id.append("_" + device.get_info<sycl::info::device::ext_intel_pci_address>());
- }
- (cb)(id.c_str(), name.c_str(), num, user_ptr);
- num++;
- }
-}
-
-size_t oneapi_get_memcapacity(SyclQueue *queue)
-{
- return reinterpret_cast<sycl::queue *>(queue)
- ->get_device()
- .get_info<sycl::info::device::global_mem_size>();
-}
-
-int oneapi_get_num_multiprocessors(SyclQueue *queue)
-{
- const sycl::device &device = reinterpret_cast<sycl::queue *>(queue)->get_device();
- if (device.has(sycl::aspect::ext_intel_gpu_eu_count)) {
- return device.get_info<sycl::info::device::ext_intel_gpu_eu_count>();
- }
- else
- return 0;
-}
-
-int oneapi_get_max_num_threads_per_multiprocessor(SyclQueue *queue)
-{
- const sycl::device &device = reinterpret_cast<sycl::queue *>(queue)->get_device();
- if (device.has(sycl::aspect::ext_intel_gpu_eu_simd_width) &&
- device.has(sycl::aspect::ext_intel_gpu_hw_threads_per_eu)) {
- return device.get_info<sycl::info::device::ext_intel_gpu_eu_simd_width>() *
- device.get_info<sycl::info::device::ext_intel_gpu_hw_threads_per_eu>();
- }
- else
- return 0;
-}
-
#endif /* WITH_ONEAPI */
diff --git a/intern/cycles/kernel/device/oneapi/kernel.h b/intern/cycles/kernel/device/oneapi/kernel.h
index c5f853742ed..2bfc0b89c87 100644
--- a/intern/cycles/kernel/device/oneapi/kernel.h
+++ b/intern/cycles/kernel/device/oneapi/kernel.h
@@ -25,11 +25,6 @@ enum DeviceKernel : int;
class SyclQueue;
-typedef void (*OneAPIDeviceIteratorCallback)(const char *id,
- const char *name,
- int num,
- void *user_ptr);
-
typedef void (*OneAPIErrorCallback)(const char *error, void *user_ptr);
struct KernelContext {
@@ -45,13 +40,17 @@ struct KernelContext {
extern "C" {
# endif
-# define DLL_INTERFACE_CALL(function, return_type, ...) \
- CYCLES_KERNEL_ONEAPI_EXPORT return_type function(__VA_ARGS__);
-# include "kernel/device/oneapi/dll_interface_template.h"
-# undef DLL_INTERFACE_CALL
-
+CYCLES_KERNEL_ONEAPI_EXPORT bool oneapi_run_test_kernel(SyclQueue *queue_);
+CYCLES_KERNEL_ONEAPI_EXPORT void oneapi_set_error_cb(OneAPIErrorCallback cb, void *user_ptr);
+CYCLES_KERNEL_ONEAPI_EXPORT size_t oneapi_kernel_preferred_local_size(
+ SyclQueue *queue, const DeviceKernel kernel, const size_t kernel_global_size);
+CYCLES_KERNEL_ONEAPI_EXPORT bool oneapi_enqueue_kernel(KernelContext *context,
+ int kernel,
+ size_t global_size,
+ void **args);
+CYCLES_KERNEL_ONEAPI_EXPORT bool oneapi_load_kernels(SyclQueue *queue,
+ const unsigned int requested_features);
# ifdef __cplusplus
}
# endif
-
#endif /* WITH_ONEAPI */
diff --git a/intern/cycles/kernel/device/optix/bvh.h b/intern/cycles/kernel/device/optix/bvh.h
index fb9907709ce..6d81b44660c 100644
--- a/intern/cycles/kernel/device/optix/bvh.h
+++ b/intern/cycles/kernel/device/optix/bvh.h
@@ -202,7 +202,7 @@ extern "C" __global__ void __anyhit__kernel_optix_shadow_all_hit()
/* Always use baked shadow transparency for curves. */
if (type & PRIMITIVE_CURVE) {
float throughput = __uint_as_float(optixGetPayload_1());
- throughput *= intersection_curve_shadow_transparency(nullptr, object, prim, u);
+ throughput *= intersection_curve_shadow_transparency(nullptr, object, prim, type, u);
optixSetPayload_1(__float_as_uint(throughput));
optixSetPayload_2(uint16_pack_to_uint(num_recorded_hits, num_hits + 1));
diff --git a/intern/cycles/kernel/device/optix/compat.h b/intern/cycles/kernel/device/optix/compat.h
index 1a11a533b7e..e13101f57b8 100644
--- a/intern/cycles/kernel/device/optix/compat.h
+++ b/intern/cycles/kernel/device/optix/compat.h
@@ -33,14 +33,16 @@ typedef unsigned long long uint64_t;
#endif
#define ccl_device \
- __device__ __forceinline__ // Function calls are bad for OptiX performance, so inline everything
+ static __device__ \
+ __forceinline__ // Function calls are bad for OptiX performance, so inline everything
+#define ccl_device_extern extern "C" __device__
#define ccl_device_inline ccl_device
#define ccl_device_forceinline ccl_device
-#define ccl_device_inline_method ccl_device
-#define ccl_device_noinline __device__ __noinline__
+#define ccl_device_inline_method __device__ __forceinline__
+#define ccl_device_noinline static __device__ __noinline__
#define ccl_device_noinline_cpu ccl_device
#define ccl_global
-#define ccl_inline_constant __constant__
+#define ccl_inline_constant static __constant__
#define ccl_device_constant __constant__ __device__
#define ccl_constant const
#define ccl_gpu_shared __shared__
@@ -57,23 +59,6 @@ typedef unsigned long long uint64_t;
#define kernel_assert(cond)
-/* GPU thread, block, grid size and index */
-
-#define ccl_gpu_thread_idx_x (threadIdx.x)
-#define ccl_gpu_block_dim_x (blockDim.x)
-#define ccl_gpu_block_idx_x (blockIdx.x)
-#define ccl_gpu_grid_dim_x (gridDim.x)
-#define ccl_gpu_warp_size (warpSize)
-#define ccl_gpu_thread_mask(thread_warp) uint(0xFFFFFFFF >> (ccl_gpu_warp_size - thread_warp))
-
-#define ccl_gpu_global_id_x() (ccl_gpu_block_idx_x * ccl_gpu_block_dim_x + ccl_gpu_thread_idx_x)
-#define ccl_gpu_global_size_x() (ccl_gpu_grid_dim_x * ccl_gpu_block_dim_x)
-
-/* GPU warp synchronization. */
-
-#define ccl_gpu_syncthreads() __syncthreads()
-#define ccl_gpu_ballot(predicate) __ballot_sync(0xFFFFFFFF, predicate)
-
/* GPU texture objects */
typedef unsigned long long CUtexObject;
@@ -101,14 +86,14 @@ ccl_device_forceinline T ccl_gpu_tex_object_read_3D(const ccl_gpu_tex_object_3D
typedef unsigned short half;
-__device__ half __float2half(const float f)
+ccl_device_forceinline half __float2half(const float f)
{
half val;
asm("{ cvt.rn.f16.f32 %0, %1;}\n" : "=h"(val) : "f"(f));
return val;
}
-__device__ float __half2float(const half h)
+ccl_device_forceinline float __half2float(const half h)
{
float val;
asm("{ cvt.f32.f16 %0, %1;}\n" : "=f"(val) : "h"(h));
diff --git a/intern/cycles/kernel/device/optix/globals.h b/intern/cycles/kernel/device/optix/globals.h
index 7af2e421378..126df74bc8c 100644
--- a/intern/cycles/kernel/device/optix/globals.h
+++ b/intern/cycles/kernel/device/optix/globals.h
@@ -25,6 +25,7 @@ struct KernelParamsOptiX {
/* Kernel arguments */
const int *path_index_array;
float *render_buffer;
+ int offset;
/* Global scene data and textures */
KernelData data;
@@ -36,7 +37,11 @@ struct KernelParamsOptiX {
};
#ifdef __NVCC__
-extern "C" static __constant__ KernelParamsOptiX kernel_params;
+extern "C"
+# ifndef __CUDACC_RDC__
+ static
+# endif
+ __constant__ KernelParamsOptiX kernel_params;
#endif
/* Abstraction macros */
diff --git a/intern/cycles/kernel/device/optix/kernel_osl.cu b/intern/cycles/kernel/device/optix/kernel_osl.cu
new file mode 100644
index 00000000000..0f3f477935b
--- /dev/null
+++ b/intern/cycles/kernel/device/optix/kernel_osl.cu
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#define WITH_OSL
+
+/* Copy of the regular OptiX kernels with additional OSL support. */
+
+#include "kernel/device/optix/kernel_shader_raytrace.cu"
+
+#include "kernel/bake/bake.h"
+#include "kernel/integrator/shade_background.h"
+#include "kernel/integrator/shade_light.h"
+#include "kernel/integrator/shade_shadow.h"
+#include "kernel/integrator/shade_volume.h"
+
+extern "C" __global__ void __raygen__kernel_optix_integrator_shade_background()
+{
+ const int global_index = optixGetLaunchIndex().x;
+ const int path_index = (kernel_params.path_index_array) ?
+ kernel_params.path_index_array[global_index] :
+ global_index;
+ integrator_shade_background(nullptr, path_index, kernel_params.render_buffer);
+}
+
+extern "C" __global__ void __raygen__kernel_optix_integrator_shade_light()
+{
+ const int global_index = optixGetLaunchIndex().x;
+ const int path_index = (kernel_params.path_index_array) ?
+ kernel_params.path_index_array[global_index] :
+ global_index;
+ integrator_shade_light(nullptr, path_index, kernel_params.render_buffer);
+}
+
+extern "C" __global__ void __raygen__kernel_optix_integrator_shade_surface()
+{
+ const int global_index = optixGetLaunchIndex().x;
+ const int path_index = (kernel_params.path_index_array) ?
+ kernel_params.path_index_array[global_index] :
+ global_index;
+ integrator_shade_surface(nullptr, path_index, kernel_params.render_buffer);
+}
+
+extern "C" __global__ void __raygen__kernel_optix_integrator_shade_volume()
+{
+ const int global_index = optixGetLaunchIndex().x;
+ const int path_index = (kernel_params.path_index_array) ?
+ kernel_params.path_index_array[global_index] :
+ global_index;
+ integrator_shade_volume(nullptr, path_index, kernel_params.render_buffer);
+}
+
+extern "C" __global__ void __raygen__kernel_optix_integrator_shade_shadow()
+{
+ const int global_index = optixGetLaunchIndex().x;
+ const int path_index = (kernel_params.path_index_array) ?
+ kernel_params.path_index_array[global_index] :
+ global_index;
+ integrator_shade_shadow(nullptr, path_index, kernel_params.render_buffer);
+}
+
+extern "C" __global__ void __raygen__kernel_optix_shader_eval_displace()
+{
+ KernelShaderEvalInput *const input = (KernelShaderEvalInput *)kernel_params.path_index_array;
+ float *const output = kernel_params.render_buffer;
+ const int global_index = kernel_params.offset + optixGetLaunchIndex().x;
+ kernel_displace_evaluate(nullptr, input, output, global_index);
+}
+
+extern "C" __global__ void __raygen__kernel_optix_shader_eval_background()
+{
+ KernelShaderEvalInput *const input = (KernelShaderEvalInput *)kernel_params.path_index_array;
+ float *const output = kernel_params.render_buffer;
+ const int global_index = kernel_params.offset + optixGetLaunchIndex().x;
+ kernel_background_evaluate(nullptr, input, output, global_index);
+}
+
+extern "C" __global__ void __raygen__kernel_optix_shader_eval_curve_shadow_transparency()
+{
+ KernelShaderEvalInput *const input = (KernelShaderEvalInput *)kernel_params.path_index_array;
+ float *const output = kernel_params.render_buffer;
+ const int global_index = kernel_params.offset + optixGetLaunchIndex().x;
+ kernel_curve_shadow_transparency_evaluate(nullptr, input, output, global_index);
+}
diff --git a/intern/cycles/kernel/film/denoising_passes.h b/intern/cycles/kernel/film/denoising_passes.h
index 1517e8bad56..dfc21d787f2 100644
--- a/intern/cycles/kernel/film/denoising_passes.h
+++ b/intern/cycles/kernel/film/denoising_passes.h
@@ -30,8 +30,8 @@ ccl_device_forceinline void film_write_denoising_features_surface(KernelGlobals
if (kernel_data.film.pass_denoising_depth != PASS_UNUSED) {
const Spectrum denoising_feature_throughput = INTEGRATOR_STATE(
state, path, denoising_feature_throughput);
- const float denoising_depth = ensure_finite(average(denoising_feature_throughput) *
- sd->ray_length);
+ const float depth = sd->ray_length - INTEGRATOR_STATE(state, ray, tmin);
+ const float denoising_depth = ensure_finite(average(denoising_feature_throughput) * depth);
film_write_pass_float(buffer + kernel_data.film.pass_denoising_depth, denoising_depth);
}
diff --git a/intern/cycles/kernel/integrator/displacement_shader.h b/intern/cycles/kernel/integrator/displacement_shader.h
index 839dfe244ac..a6e9d674396 100644
--- a/intern/cycles/kernel/integrator/displacement_shader.h
+++ b/intern/cycles/kernel/integrator/displacement_shader.h
@@ -24,8 +24,8 @@ ccl_device void displacement_shader_eval(KernelGlobals kg,
/* this will modify sd->P */
#ifdef __OSL__
- if (kg->osl) {
- OSLShader::eval_displacement(kg, state, sd);
+ if (kernel_data.kernel_features & KERNEL_FEATURE_OSL) {
+ osl_eval_nodes<SHADER_TYPE_DISPLACEMENT>(kg, state, sd, 0);
}
else
#endif
diff --git a/intern/cycles/kernel/integrator/guiding.h b/intern/cycles/kernel/integrator/guiding.h
new file mode 100644
index 00000000000..634bba2a9b4
--- /dev/null
+++ b/intern/cycles/kernel/integrator/guiding.h
@@ -0,0 +1,547 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#pragma once
+
+#include "kernel/closure/alloc.h"
+#include "kernel/closure/bsdf.h"
+#include "kernel/film/write.h"
+
+CCL_NAMESPACE_BEGIN
+
+/* Utilities. */
+
+#if defined(__PATH_GUIDING__)
+static pgl_vec3f guiding_vec3f(const float3 v)
+{
+ return openpgl::cpp::Vector3(v.x, v.y, v.z);
+}
+
+static pgl_point3f guiding_point3f(const float3 v)
+{
+ return openpgl::cpp::Point3(v.x, v.y, v.z);
+}
+#endif
+
+/* Path recording for guiding. */
+
+/* Record Surface Interactions */
+
+/* Records/Adds a new path segment with the current path vertex on a surface.
+ * If the path is not terminated this call is usually followed by a call of
+ * guiding_record_surface_bounce. */
+ccl_device_forceinline void guiding_record_surface_segment(KernelGlobals kg,
+ IntegratorState state,
+ ccl_private const ShaderData *sd)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
+ if (!kernel_data.integrator.train_guiding) {
+ return;
+ }
+
+ const pgl_vec3f zero = guiding_vec3f(zero_float3());
+ const pgl_vec3f one = guiding_vec3f(one_float3());
+
+ state->guiding.path_segment = kg->opgl_path_segment_storage->NextSegment();
+ openpgl::cpp::SetPosition(state->guiding.path_segment, guiding_point3f(sd->P));
+ openpgl::cpp::SetDirectionOut(state->guiding.path_segment, guiding_vec3f(sd->I));
+ openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, false);
+ openpgl::cpp::SetScatteredContribution(state->guiding.path_segment, zero);
+ openpgl::cpp::SetDirectContribution(state->guiding.path_segment, zero);
+ openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, one);
+ openpgl::cpp::SetEta(state->guiding.path_segment, 1.0);
+#endif
+}
+
+/* Records the surface scattering event at the current vertex position of the segment.*/
+ccl_device_forceinline void guiding_record_surface_bounce(KernelGlobals kg,
+ IntegratorState state,
+ ccl_private const ShaderData *sd,
+ const Spectrum weight,
+ const float pdf,
+ const float3 N,
+ const float3 omega_in,
+ const float2 roughness,
+ const float eta)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
+ if (!kernel_data.integrator.train_guiding) {
+ return;
+ }
+ const float min_roughness = safe_sqrtf(fminf(roughness.x, roughness.y));
+ const bool is_delta = (min_roughness == 0.0f);
+ const float3 weight_rgb = spectrum_to_rgb(weight);
+ const float3 normal = clamp(N, -one_float3(), one_float3());
+
+ kernel_assert(state->guiding.path_segment != nullptr);
+
+ openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, guiding_vec3f(one_float3()));
+ openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, false);
+ openpgl::cpp::SetNormal(state->guiding.path_segment, guiding_vec3f(normal));
+ openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(omega_in));
+ openpgl::cpp::SetPDFDirectionIn(state->guiding.path_segment, pdf);
+ openpgl::cpp::SetScatteringWeight(state->guiding.path_segment, guiding_vec3f(weight_rgb));
+ openpgl::cpp::SetIsDelta(state->guiding.path_segment, is_delta);
+ openpgl::cpp::SetEta(state->guiding.path_segment, eta);
+ openpgl::cpp::SetRoughness(state->guiding.path_segment, min_roughness);
+#endif
+}
+
+/* Records the emission at the current surface intersection (physical or virtual) */
+ccl_device_forceinline void guiding_record_surface_emission(KernelGlobals kg,
+ IntegratorState state,
+ const Spectrum Le,
+ const float mis_weight)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
+ if (!kernel_data.integrator.train_guiding) {
+ return;
+ }
+ const float3 Le_rgb = spectrum_to_rgb(Le);
+
+ openpgl::cpp::SetDirectContribution(state->guiding.path_segment, guiding_vec3f(Le_rgb));
+ openpgl::cpp::SetMiWeight(state->guiding.path_segment, mis_weight);
+#endif
+}
+
+/* Record BSSRDF Interactions */
+
+/* Records/Adds a new path segment where the vertex position is the point of entry
+ * of the sub surface scattering boundary.
+ * If the path is not terminated this call is usually followed by a call of
+ * guiding_record_bssrdf_weight and guiding_record_bssrdf_bounce. */
+ccl_device_forceinline void guiding_record_bssrdf_segment(KernelGlobals kg,
+ IntegratorState state,
+ const float3 P,
+ const float3 I)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
+ if (!kernel_data.integrator.train_guiding) {
+ return;
+ }
+ const pgl_vec3f zero = guiding_vec3f(zero_float3());
+ const pgl_vec3f one = guiding_vec3f(one_float3());
+
+ state->guiding.path_segment = kg->opgl_path_segment_storage->NextSegment();
+ openpgl::cpp::SetPosition(state->guiding.path_segment, guiding_point3f(P));
+ openpgl::cpp::SetDirectionOut(state->guiding.path_segment, guiding_vec3f(I));
+ openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, true);
+ openpgl::cpp::SetScatteredContribution(state->guiding.path_segment, zero);
+ openpgl::cpp::SetDirectContribution(state->guiding.path_segment, zero);
+ openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, one);
+ openpgl::cpp::SetEta(state->guiding.path_segment, 1.0);
+#endif
+}
+
+/* Records the transmission of the path at the point of entry while passing
+ * the surface boundary.*/
+ccl_device_forceinline void guiding_record_bssrdf_weight(KernelGlobals kg,
+ IntegratorState state,
+ const Spectrum weight,
+ const Spectrum albedo)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
+ if (!kernel_data.integrator.train_guiding) {
+ return;
+ }
+
+ /* Note albedo left out here, will be included in guiding_record_bssrdf_bounce. */
+ const float3 weight_rgb = spectrum_to_rgb(safe_divide_color(weight, albedo));
+
+ kernel_assert(state->guiding.path_segment != nullptr);
+
+ openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, guiding_vec3f(zero_float3()));
+ openpgl::cpp::SetScatteringWeight(state->guiding.path_segment, guiding_vec3f(weight_rgb));
+ openpgl::cpp::SetIsDelta(state->guiding.path_segment, false);
+ openpgl::cpp::SetEta(state->guiding.path_segment, 1.0f);
+ openpgl::cpp::SetRoughness(state->guiding.path_segment, 1.0f);
+#endif
+}
+
+/* Records the direction at the point of entry the path takes when sampling the SSS contribution.
+ * If not terminated this function is usually followed by a call of
+ * guiding_record_volume_transmission to record the transmittance between the point of entry and
+ * the point of exit.*/
+ccl_device_forceinline void guiding_record_bssrdf_bounce(KernelGlobals kg,
+ IntegratorState state,
+ const float pdf,
+ const float3 N,
+ const float3 omega_in,
+ const Spectrum weight,
+ const Spectrum albedo)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
+ if (!kernel_data.integrator.train_guiding) {
+ return;
+ }
+ const float3 normal = clamp(N, -one_float3(), one_float3());
+ const float3 weight_rgb = spectrum_to_rgb(weight * albedo);
+
+ kernel_assert(state->guiding.path_segment != nullptr);
+
+ openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, false);
+ openpgl::cpp::SetNormal(state->guiding.path_segment, guiding_vec3f(normal));
+ openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(omega_in));
+ openpgl::cpp::SetPDFDirectionIn(state->guiding.path_segment, pdf);
+ openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, guiding_vec3f(weight_rgb));
+#endif
+}
+
+/* Record Volume Interactions */
+
+/* Records/Adds a new path segment with the current path vertex being inside a volume.
+ * If the path is not terminated this call is usually followed by a call of
+ * guiding_record_volume_bounce. */
+ccl_device_forceinline void guiding_record_volume_segment(KernelGlobals kg,
+ IntegratorState state,
+ const float3 P,
+ const float3 I)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
+ if (!kernel_data.integrator.train_guiding) {
+ return;
+ }
+ const pgl_vec3f zero = guiding_vec3f(zero_float3());
+ const pgl_vec3f one = guiding_vec3f(one_float3());
+
+ state->guiding.path_segment = kg->opgl_path_segment_storage->NextSegment();
+
+ openpgl::cpp::SetPosition(state->guiding.path_segment, guiding_point3f(P));
+ openpgl::cpp::SetDirectionOut(state->guiding.path_segment, guiding_vec3f(I));
+ openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, true);
+ openpgl::cpp::SetScatteredContribution(state->guiding.path_segment, zero);
+ openpgl::cpp::SetDirectContribution(state->guiding.path_segment, zero);
+ openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, one);
+ openpgl::cpp::SetEta(state->guiding.path_segment, 1.0);
+#endif
+}
+
+/* Records the volume scattering event at the current vertex position of the segment.*/
+ccl_device_forceinline void guiding_record_volume_bounce(KernelGlobals kg,
+ IntegratorState state,
+ ccl_private const ShaderData *sd,
+ const Spectrum weight,
+ const float pdf,
+ const float3 omega_in,
+ const float roughness)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
+ if (!kernel_data.integrator.train_guiding) {
+ return;
+ }
+ const float3 weight_rgb = spectrum_to_rgb(weight);
+ const float3 normal = make_float3(0.0f, 0.0f, 1.0f);
+
+ kernel_assert(state->guiding.path_segment != nullptr);
+
+ openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, true);
+ openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, guiding_vec3f(one_float3()));
+ openpgl::cpp::SetNormal(state->guiding.path_segment, guiding_vec3f(normal));
+ openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(omega_in));
+ openpgl::cpp::SetPDFDirectionIn(state->guiding.path_segment, pdf);
+ openpgl::cpp::SetScatteringWeight(state->guiding.path_segment, guiding_vec3f(weight_rgb));
+ openpgl::cpp::SetIsDelta(state->guiding.path_segment, false);
+ openpgl::cpp::SetEta(state->guiding.path_segment, 1.f);
+ openpgl::cpp::SetRoughness(state->guiding.path_segment, roughness);
+#endif
+}
+
+/* Records the transmission (a.k.a. transmittance weight) between the current path segment
+ * and the next one, when the path is inside or passes a volume.*/
+ccl_device_forceinline void guiding_record_volume_transmission(KernelGlobals kg,
+ IntegratorState state,
+ const float3 transmittance_weight)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
+ if (!kernel_data.integrator.train_guiding) {
+ return;
+ }
+
+ if (state->guiding.path_segment) {
+ // TODO (sherholz): need to find a better way to avoid this check
+ if ((transmittance_weight[0] < 0.f || !std::isfinite(transmittance_weight[0]) ||
+ std::isnan(transmittance_weight[0])) ||
+ (transmittance_weight[1] < 0.f || !std::isfinite(transmittance_weight[1]) ||
+ std::isnan(transmittance_weight[1])) ||
+ (transmittance_weight[2] < 0.f || !std::isfinite(transmittance_weight[2]) ||
+ std::isnan(transmittance_weight[2]))) {
+ }
+ else {
+ openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment,
+ guiding_vec3f(transmittance_weight));
+ }
+ }
+#endif
+}
+
+/* Records the emission of a volume at the vertex of the current path segment. */
+ccl_device_forceinline void guiding_record_volume_emission(KernelGlobals kg,
+ IntegratorState state,
+ const Spectrum Le)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
+ if (!kernel_data.integrator.train_guiding) {
+ return;
+ }
+
+ if (state->guiding.path_segment) {
+ const float3 Le_rgb = spectrum_to_rgb(Le);
+
+ openpgl::cpp::SetDirectContribution(state->guiding.path_segment, guiding_vec3f(Le_rgb));
+ openpgl::cpp::SetMiWeight(state->guiding.path_segment, 1.0f);
+ }
+#endif
+}
+
+/* Record Light Interactions */
+
+/* Adds a pseudo path vertex/segment when intersecting a virtual light source.
+ * (e.g., area, sphere, or disk light). This call is often followed
+ * a call of guiding_record_surface_emission, if the intersected light source
+ * emits light in the direction of the path. */
+ccl_device_forceinline void guiding_record_light_surface_segment(
+ KernelGlobals kg, IntegratorState state, ccl_private const Intersection *ccl_restrict isect)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
+ if (!kernel_data.integrator.train_guiding) {
+ return;
+ }
+ const pgl_vec3f zero = guiding_vec3f(zero_float3());
+ const pgl_vec3f one = guiding_vec3f(one_float3());
+ const float3 ray_P = INTEGRATOR_STATE(state, ray, P);
+ const float3 ray_D = INTEGRATOR_STATE(state, ray, D);
+ const float3 P = ray_P + isect->t * ray_D;
+
+ state->guiding.path_segment = kg->opgl_path_segment_storage->NextSegment();
+ openpgl::cpp::SetPosition(state->guiding.path_segment, guiding_point3f(P));
+ openpgl::cpp::SetDirectionOut(state->guiding.path_segment, guiding_vec3f(-ray_D));
+ openpgl::cpp::SetNormal(state->guiding.path_segment, guiding_vec3f(-ray_D));
+ openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(ray_D));
+ openpgl::cpp::SetPDFDirectionIn(state->guiding.path_segment, 1.0f);
+ openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, false);
+ openpgl::cpp::SetScatteredContribution(state->guiding.path_segment, zero);
+ openpgl::cpp::SetDirectContribution(state->guiding.path_segment, zero);
+ openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, one);
+ openpgl::cpp::SetScatteringWeight(state->guiding.path_segment, one);
+ openpgl::cpp::SetEta(state->guiding.path_segment, 1.0f);
+#endif
+}
+
+/* Records/Adds a final path segment when the path leaves the scene and
+ * intersects with a background light (e.g., background color,
+ * distant light, or env map). The vertex for this segment is placed along
+ * the current ray far out the scene.*/
+ccl_device_forceinline void guiding_record_background(KernelGlobals kg,
+ IntegratorState state,
+ const Spectrum L,
+ const float mis_weight)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
+ if (!kernel_data.integrator.train_guiding) {
+ return;
+ }
+
+ const float3 L_rgb = spectrum_to_rgb(L);
+ const float3 ray_P = INTEGRATOR_STATE(state, ray, P);
+ const float3 ray_D = INTEGRATOR_STATE(state, ray, D);
+ const float3 P = ray_P + (1e6f) * ray_D;
+ const float3 normal = make_float3(0.0f, 0.0f, 1.0f);
+
+ openpgl::cpp::PathSegment background_segment;
+ openpgl::cpp::SetPosition(&background_segment, guiding_vec3f(P));
+ openpgl::cpp::SetNormal(&background_segment, guiding_vec3f(normal));
+ openpgl::cpp::SetDirectionOut(&background_segment, guiding_vec3f(-ray_D));
+ openpgl::cpp::SetDirectContribution(&background_segment, guiding_vec3f(L_rgb));
+ openpgl::cpp::SetMiWeight(&background_segment, mis_weight);
+ kg->opgl_path_segment_storage->AddSegment(background_segment);
+#endif
+}
+
+/* Records the scattered contribution of a next event estimation
+ * (i.e., a direct light estimate scattered at the current path vertex
+ * towards the previous vertex).*/
+ccl_device_forceinline void guiding_record_direct_light(KernelGlobals kg,
+ IntegratorShadowState state)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
+ if (!kernel_data.integrator.train_guiding) {
+ return;
+ }
+ if (state->shadow_path.path_segment) {
+ const Spectrum Lo = safe_divide_color(INTEGRATOR_STATE(state, shadow_path, throughput),
+ INTEGRATOR_STATE(state, shadow_path, unlit_throughput));
+
+ const float3 Lo_rgb = spectrum_to_rgb(Lo);
+ openpgl::cpp::AddScatteredContribution(state->shadow_path.path_segment, guiding_vec3f(Lo_rgb));
+ }
+#endif
+}
+
+/* Record Russian Roulette */
+/* Records the probability of continuing the path at the current path segment. */
+ccl_device_forceinline void guiding_record_continuation_probability(
+ KernelGlobals kg, IntegratorState state, const float continuation_probability)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
+ if (!kernel_data.integrator.train_guiding) {
+ return;
+ }
+
+ if (state->guiding.path_segment) {
+ openpgl::cpp::SetRussianRouletteProbability(state->guiding.path_segment,
+ continuation_probability);
+ }
+#endif
+}
+
+/* Path guiding debug render passes. */
+
+/* Write a set of path guiding related debug information (e.g., guiding probability at first
+ * bounce) into separate rendering passes.*/
+ccl_device_forceinline void guiding_write_debug_passes(KernelGlobals kg,
+ IntegratorState state,
+ ccl_private const ShaderData *sd,
+ ccl_global float *ccl_restrict
+ render_buffer)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
+# ifdef WITH_CYCLES_DEBUG
+ if (!kernel_data.integrator.train_guiding) {
+ return;
+ }
+
+ if (INTEGRATOR_STATE(state, path, bounce) != 0) {
+ return;
+ }
+
+ const uint32_t render_pixel_index = INTEGRATOR_STATE(state, path, render_pixel_index);
+ const uint64_t render_buffer_offset = (uint64_t)render_pixel_index *
+ kernel_data.film.pass_stride;
+ ccl_global float *buffer = render_buffer + render_buffer_offset;
+
+ if (kernel_data.film.pass_guiding_probability != PASS_UNUSED) {
+ float guiding_prob = state->guiding.surface_guiding_sampling_prob;
+ film_write_pass_float(buffer + kernel_data.film.pass_guiding_probability, guiding_prob);
+ }
+
+ if (kernel_data.film.pass_guiding_avg_roughness != PASS_UNUSED) {
+ float avg_roughness = 0.0f;
+ float sum_sample_weight = 0.0f;
+ for (int i = 0; i < sd->num_closure; i++) {
+ ccl_private const ShaderClosure *sc = &sd->closure[i];
+
+ if (!CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
+ continue;
+ }
+ avg_roughness += sc->sample_weight * bsdf_get_specular_roughness_squared(sc);
+ sum_sample_weight += sc->sample_weight;
+ }
+
+ avg_roughness = avg_roughness > 0.f ? avg_roughness / sum_sample_weight : 0.f;
+
+ film_write_pass_float(buffer + kernel_data.film.pass_guiding_avg_roughness, avg_roughness);
+ }
+# endif
+#endif
+}
+
+/* Guided BSDFs */
+
+ccl_device_forceinline bool guiding_bsdf_init(KernelGlobals kg,
+ IntegratorState state,
+ const float3 P,
+ const float3 N,
+ ccl_private float &rand)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
+ if (kg->opgl_surface_sampling_distribution->Init(
+ kg->opgl_guiding_field, guiding_point3f(P), rand, true)) {
+ kg->opgl_surface_sampling_distribution->ApplyCosineProduct(guiding_point3f(N));
+ return true;
+ }
+#endif
+
+ return false;
+}
+
+ccl_device_forceinline float guiding_bsdf_sample(KernelGlobals kg,
+ IntegratorState state,
+ const float2 rand_bsdf,
+ ccl_private float3 *omega_in)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
+ pgl_vec3f wo;
+ const pgl_point2f rand = openpgl::cpp::Point2(rand_bsdf.x, rand_bsdf.y);
+ const float pdf = kg->opgl_surface_sampling_distribution->SamplePDF(rand, wo);
+ *omega_in = make_float3(wo.x, wo.y, wo.z);
+ return pdf;
+#else
+ return 0.0f;
+#endif
+}
+
+ccl_device_forceinline float guiding_bsdf_pdf(KernelGlobals kg,
+ IntegratorState state,
+ const float3 omega_in)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
+ return kg->opgl_surface_sampling_distribution->PDF(guiding_vec3f(omega_in));
+#else
+ return 0.0f;
+#endif
+}
+
+/* Guided Volume Phases */
+
+ccl_device_forceinline bool guiding_phase_init(KernelGlobals kg,
+ IntegratorState state,
+ const float3 P,
+ const float3 D,
+ const float g,
+ ccl_private float &rand)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
+ /* we do not need to guide almost delta phase functions */
+ if (fabsf(g) >= 0.99f) {
+ return false;
+ }
+
+ if (kg->opgl_volume_sampling_distribution->Init(
+ kg->opgl_guiding_field, guiding_point3f(P), rand, true)) {
+ kg->opgl_volume_sampling_distribution->ApplySingleLobeHenyeyGreensteinProduct(guiding_vec3f(D),
+ g);
+ return true;
+ }
+#endif
+
+ return false;
+}
+
+ccl_device_forceinline float guiding_phase_sample(KernelGlobals kg,
+ IntegratorState state,
+ const float2 rand_phase,
+ ccl_private float3 *omega_in)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
+ pgl_vec3f wo;
+ const pgl_point2f rand = openpgl::cpp::Point2(rand_phase.x, rand_phase.y);
+ const float pdf = kg->opgl_volume_sampling_distribution->SamplePDF(rand, wo);
+ *omega_in = make_float3(wo.x, wo.y, wo.z);
+ return pdf;
+#else
+ return 0.0f;
+#endif
+}
+
+ccl_device_forceinline float guiding_phase_pdf(KernelGlobals kg,
+ IntegratorState state,
+ const float3 omega_in)
+{
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
+ return kg->opgl_volume_sampling_distribution->PDF(guiding_vec3f(omega_in));
+#else
+ return 0.0f;
+#endif
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/integrator/init_from_bake.h b/intern/cycles/kernel/integrator/init_from_bake.h
index eca2c0b9ffb..cc3fbe3fe39 100644
--- a/intern/cycles/kernel/integrator/init_from_bake.h
+++ b/intern/cycles/kernel/integrator/init_from_bake.h
@@ -156,6 +156,13 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg,
u = v;
v = 1.0f - tmp - v;
+ const float tmpdx = dudx;
+ const float tmpdy = dudy;
+ dudx = dvdx;
+ dudy = dvdy;
+ dvdx = -tmpdx - dvdx;
+ dvdy = -tmpdy - dvdy;
+
/* Position and normal on triangle. */
const int object = kernel_data.bake.object_index;
float3 P, Ng;
@@ -210,8 +217,51 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg,
/* Setup ray. */
Ray ray ccl_optional_struct_init;
- ray.P = P + N;
- ray.D = -N;
+
+ if (kernel_data.bake.use_camera) {
+ float3 D = camera_direction_from_point(kg, P);
+
+ const float DN = dot(D, N);
+
+ /* Nudge camera direction, so that the faces facing away from the camera still have
+ * somewhat usable shading. (Otherwise, glossy faces would be simply black.)
+ *
+ * The surface normal offset affects smooth surfaces. Lower values will make
+ * smooth surfaces more faceted, but higher values may show up from the camera
+ * at grazing angles.
+ *
+ * This value can actually be pretty high before it's noticeably wrong. */
+ const float surface_normal_offset = 0.2f;
+
+ /* Keep the ray direction at least `surface_normal_offset` "above" the smooth normal. */
+ if (DN <= surface_normal_offset) {
+ D -= N * (DN - surface_normal_offset);
+ D = normalize(D);
+ }
+
+ /* On the backside, just lerp towards the surface normal for the ray direction,
+ * as DN goes from 0.0 to -1.0. */
+ if (DN <= 0.0f) {
+ D = normalize(mix(D, N, -DN));
+ }
+
+ /* We don't want to bake the back face, so make sure the ray direction never
+ * goes behind the geometry (flat) normal. This is a fail-safe, and should rarely happen. */
+ const float true_normal_epsilon = 0.00001f;
+
+ if (dot(D, Ng) <= true_normal_epsilon) {
+ D -= Ng * (dot(D, Ng) - true_normal_epsilon);
+ D = normalize(D);
+ }
+
+ ray.P = P + D;
+ ray.D = -D;
+ }
+ else {
+ ray.P = P + N;
+ ray.D = -N;
+ }
+
ray.tmin = 0.0f;
ray.tmax = FLT_MAX;
ray.time = 0.5f;
diff --git a/intern/cycles/kernel/integrator/intersect_closest.h b/intern/cycles/kernel/integrator/intersect_closest.h
index c7c3d74fa21..b9a81e25bcc 100644
--- a/intern/cycles/kernel/integrator/intersect_closest.h
+++ b/intern/cycles/kernel/integrator/intersect_closest.h
@@ -7,6 +7,7 @@
#include "kernel/film/light_passes.h"
+#include "kernel/integrator/guiding.h"
#include "kernel/integrator/path_state.h"
#include "kernel/integrator/shadow_catcher.h"
@@ -48,13 +49,15 @@ ccl_device_forceinline bool integrator_intersect_terminate(KernelGlobals kg,
* surfaces in front of emission do we need to evaluate the shader, since we
* perform MIS as part of indirect rays. */
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
- const float probability = path_state_continuation_probability(kg, state, path_flag);
- INTEGRATOR_STATE_WRITE(state, path, continuation_probability) = probability;
+ const float continuation_probability = path_state_continuation_probability(kg, state, path_flag);
+ INTEGRATOR_STATE_WRITE(state, path, continuation_probability) = continuation_probability;
- if (probability != 1.0f) {
+ guiding_record_continuation_probability(kg, state, continuation_probability);
+
+ if (continuation_probability != 1.0f) {
const float terminate = path_state_rng_1D(kg, &rng_state, PRNG_TERMINATE);
- if (probability == 0.0f || terminate >= probability) {
+ if (continuation_probability == 0.0f || terminate >= continuation_probability) {
if (shader_flags & SD_HAS_EMISSION) {
/* Mark path to be terminated right after shader evaluation on the surface. */
INTEGRATOR_STATE_WRITE(state, path, flag) |= PATH_RAY_TERMINATE_ON_NEXT_SURFACE;
diff --git a/intern/cycles/kernel/integrator/mnee.h b/intern/cycles/kernel/integrator/mnee.h
index a0ad7afe591..23885306885 100644
--- a/intern/cycles/kernel/integrator/mnee.h
+++ b/intern/cycles/kernel/integrator/mnee.h
@@ -279,7 +279,15 @@ ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg,
}
/* Compute constraint derivatives. */
-ccl_device_forceinline bool mnee_compute_constraint_derivatives(
+
+# if defined(__KERNEL_METAL__)
+/* Temporary workaround for front-end compilation bug (incorrect MNEE rendering when this is
+ * inlined). */
+__attribute__((noinline))
+# else
+ccl_device_forceinline
+# endif
+bool mnee_compute_constraint_derivatives(
int vertex_count,
ccl_private ManifoldVertex *vertices,
ccl_private const float3 &surface_sample_pos,
@@ -807,7 +815,7 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg,
float3 wo = normalize_len(vertices[0].p - sd->P, &wo_len);
/* Initialize throughput and evaluate receiver bsdf * |n.wo|. */
- surface_shader_bsdf_eval(kg, sd, wo, false, throughput, ls->shader);
+ surface_shader_bsdf_eval(kg, state, sd, wo, throughput, ls->shader);
/* Update light sample with new position / direct.ion
* and keep pdf in vertex area measure */
diff --git a/intern/cycles/kernel/integrator/path_state.h b/intern/cycles/kernel/integrator/path_state.h
index 54560905397..7197f0f2f3a 100644
--- a/intern/cycles/kernel/integrator/path_state.h
+++ b/intern/cycles/kernel/integrator/path_state.h
@@ -56,6 +56,18 @@ ccl_device_inline void path_state_init_integrator(KernelGlobals kg,
INTEGRATOR_STATE_WRITE(state, path, continuation_probability) = 1.0f;
INTEGRATOR_STATE_WRITE(state, path, throughput) = one_spectrum();
+#ifdef __PATH_GUIDING__
+ INTEGRATOR_STATE_WRITE(state, path, unguided_throughput) = 1.0f;
+ INTEGRATOR_STATE_WRITE(state, guiding, path_segment) = nullptr;
+ INTEGRATOR_STATE_WRITE(state, guiding, use_surface_guiding) = false;
+ INTEGRATOR_STATE_WRITE(state, guiding, sample_surface_guiding_rand) = 0.5f;
+ INTEGRATOR_STATE_WRITE(state, guiding, surface_guiding_sampling_prob) = 0.0f;
+ INTEGRATOR_STATE_WRITE(state, guiding, bssrdf_sampling_prob) = 0.0f;
+ INTEGRATOR_STATE_WRITE(state, guiding, use_volume_guiding) = false;
+ INTEGRATOR_STATE_WRITE(state, guiding, sample_volume_guiding_rand) = 0.5f;
+ INTEGRATOR_STATE_WRITE(state, guiding, volume_guiding_sampling_prob) = 0.0f;
+#endif
+
#ifdef __MNEE__
INTEGRATOR_STATE_WRITE(state, path, mnee) = 0;
#endif
@@ -249,7 +261,11 @@ ccl_device_inline float path_state_continuation_probability(KernelGlobals kg,
/* Probabilistic termination: use sqrt() to roughly match typical view
* transform and do path termination a bit later on average. */
- return min(sqrtf(reduce_max(fabs(INTEGRATOR_STATE(state, path, throughput)))), 1.0f);
+ Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
+ throughput *= INTEGRATOR_STATE(state, path, unguided_throughput);
+#endif
+ return min(sqrtf(reduce_max(fabs(throughput))), 1.0f);
}
ccl_device_inline bool path_state_ao_bounce(KernelGlobals kg, ConstIntegratorState state)
diff --git a/intern/cycles/kernel/integrator/shade_background.h b/intern/cycles/kernel/integrator/shade_background.h
index 30ce0999258..8fc5689683a 100644
--- a/intern/cycles/kernel/integrator/shade_background.h
+++ b/intern/cycles/kernel/integrator/shade_background.h
@@ -5,6 +5,7 @@
#include "kernel/film/light_passes.h"
+#include "kernel/integrator/guiding.h"
#include "kernel/integrator/surface_shader.h"
#include "kernel/light/light.h"
@@ -124,6 +125,7 @@ ccl_device_inline void integrate_background(KernelGlobals kg,
mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, pdf);
}
+ guiding_record_background(kg, state, L, mis_weight);
L *= mis_weight;
}
@@ -185,6 +187,7 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg,
}
/* Write to render buffer. */
+ guiding_record_background(kg, state, light_eval, mis_weight);
film_write_surface_emission(
kg, state, light_eval, mis_weight, render_buffer, kernel_data.background.lightgroup);
}
diff --git a/intern/cycles/kernel/integrator/shade_light.h b/intern/cycles/kernel/integrator/shade_light.h
index f2d65eddfbb..e0b0500dc78 100644
--- a/intern/cycles/kernel/integrator/shade_light.h
+++ b/intern/cycles/kernel/integrator/shade_light.h
@@ -18,6 +18,8 @@ ccl_device_inline void integrate_light(KernelGlobals kg,
Intersection isect ccl_optional_struct_init;
integrator_state_read_isect(kg, state, &isect);
+ guiding_record_light_surface_segment(kg, state, &isect);
+
float3 ray_P = INTEGRATOR_STATE(state, ray, P);
const float3 ray_D = INTEGRATOR_STATE(state, ray, D);
const float ray_time = INTEGRATOR_STATE(state, ray, time);
@@ -66,6 +68,7 @@ ccl_device_inline void integrate_light(KernelGlobals kg,
}
/* Write to render buffer. */
+ guiding_record_surface_emission(kg, state, light_eval, mis_weight);
film_write_surface_emission(kg, state, light_eval, mis_weight, render_buffer, ls.group);
}
diff --git a/intern/cycles/kernel/integrator/shade_shadow.h b/intern/cycles/kernel/integrator/shade_shadow.h
index ba18aed6ff0..bedb15ddf89 100644
--- a/intern/cycles/kernel/integrator/shade_shadow.h
+++ b/intern/cycles/kernel/integrator/shade_shadow.h
@@ -3,6 +3,7 @@
#pragma once
+#include "kernel/integrator/guiding.h"
#include "kernel/integrator/shade_volume.h"
#include "kernel/integrator/surface_shader.h"
#include "kernel/integrator/volume_stack.h"
@@ -165,6 +166,7 @@ ccl_device void integrator_shade_shadow(KernelGlobals kg,
return;
}
else {
+ guiding_record_direct_light(kg, state);
film_write_direct_light(kg, state, render_buffer);
integrator_shadow_path_terminate(kg, state, DEVICE_KERNEL_INTEGRATOR_SHADE_SHADOW);
return;
diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h
index c19f56a9b70..067d35ef9e3 100644
--- a/intern/cycles/kernel/integrator/shade_surface.h
+++ b/intern/cycles/kernel/integrator/shade_surface.h
@@ -9,6 +9,7 @@
#include "kernel/integrator/mnee.h"
+#include "kernel/integrator/guiding.h"
#include "kernel/integrator/path_state.h"
#include "kernel/integrator/subsurface.h"
#include "kernel/integrator/surface_shader.h"
@@ -101,7 +102,7 @@ ccl_device_forceinline bool integrate_surface_holdout(KernelGlobals kg,
}
ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg,
- ConstIntegratorState state,
+ IntegratorState state,
ccl_private const ShaderData *sd,
ccl_global float *ccl_restrict
render_buffer)
@@ -128,6 +129,7 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg,
mis_weight = light_sample_mis_weight_forward(kg, bsdf_pdf, pdf);
}
+ guiding_record_surface_emission(kg, state, L, mis_weight);
film_write_surface_emission(
kg, state, L, mis_weight, render_buffer, object_lightgroup(kg, sd->object));
}
@@ -171,7 +173,8 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
Ray ray ccl_optional_struct_init;
BsdfEval bsdf_eval ccl_optional_struct_init;
- const bool is_transmission = surface_shader_is_transmission(sd, ls.D);
+
+ const bool is_transmission = dot(ls.D, sd->N) < 0.0f;
#ifdef __MNEE__
int mnee_vertex_count = 0;
@@ -182,13 +185,15 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
const bool use_caustics = kernel_data_fetch(lights, ls.lamp).use_caustics;
if (use_caustics) {
/* Are we on a caustic caster? */
- if (is_transmission && (sd->object_flag & SD_OBJECT_CAUSTICS_CASTER))
+ if (is_transmission && (sd->object_flag & SD_OBJECT_CAUSTICS_CASTER)) {
return;
+ }
/* Are we on a caustic receiver? */
- if (!is_transmission && (sd->object_flag & SD_OBJECT_CAUSTICS_RECEIVER))
+ if (!is_transmission && (sd->object_flag & SD_OBJECT_CAUSTICS_RECEIVER)) {
mnee_vertex_count = kernel_path_mnee_sample(
kg, state, sd, emission_sd, rng_state, &ls, &bsdf_eval);
+ }
}
}
}
@@ -207,8 +212,7 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
}
/* Evaluate BSDF. */
- const float bsdf_pdf = surface_shader_bsdf_eval(
- kg, sd, ls.D, is_transmission, &bsdf_eval, ls.shader);
+ const float bsdf_pdf = surface_shader_bsdf_eval(kg, state, sd, ls.D, &bsdf_eval, ls.shader);
bsdf_eval_mul(&bsdf_eval, light_eval / ls.pdf);
if (ls.shader & SHADER_USE_MIS) {
@@ -256,8 +260,8 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
/* Copy state from main path to shadow path. */
uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag);
shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0;
- const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput) *
- bsdf_eval_sum(&bsdf_eval);
+ const Spectrum unlit_throughput = INTEGRATOR_STATE(state, path, throughput);
+ const Spectrum throughput = unlit_throughput * bsdf_eval_sum(&bsdf_eval);
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
PackedSpectrum pass_diffuse_weight;
@@ -327,6 +331,11 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
shadow_state, shadow_path, lightgroup) = (ls.type != LIGHT_BACKGROUND) ?
ls.group + 1 :
kernel_data.background.lightgroup + 1;
+#ifdef __PATH_GUIDING__
+ INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unlit_throughput) = unlit_throughput;
+ INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = INTEGRATOR_STATE(
+ state, guiding, path_segment);
+#endif
}
/* Path tracing: bounce off or through surface with new direction. */
@@ -352,16 +361,52 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce(
#endif
/* BSDF closure, sample direction. */
- float bsdf_pdf;
+ float bsdf_pdf = 0.0f, unguided_bsdf_pdf = 0.0f;
BsdfEval bsdf_eval ccl_optional_struct_init;
float3 bsdf_omega_in ccl_optional_struct_init;
int label;
- label = surface_shader_bsdf_sample_closure(
- kg, sd, sc, rand_bsdf, &bsdf_eval, &bsdf_omega_in, &bsdf_pdf);
+ float2 bsdf_sampled_roughness = make_float2(1.0f, 1.0f);
+ float bsdf_eta = 1.0f;
+
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
+ if (kernel_data.integrator.use_surface_guiding) {
+ label = surface_shader_bsdf_guided_sample_closure(kg,
+ state,
+ sd,
+ sc,
+ rand_bsdf,
+ &bsdf_eval,
+ &bsdf_omega_in,
+ &bsdf_pdf,
+ &unguided_bsdf_pdf,
+ &bsdf_sampled_roughness,
+ &bsdf_eta);
+
+ if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) {
+ return LABEL_NONE;
+ }
- if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) {
- return LABEL_NONE;
+ INTEGRATOR_STATE_WRITE(state, path, unguided_throughput) *= bsdf_pdf / unguided_bsdf_pdf;
+ }
+ else
+#endif
+ {
+ label = surface_shader_bsdf_sample_closure(kg,
+ sd,
+ sc,
+ rand_bsdf,
+ &bsdf_eval,
+ &bsdf_omega_in,
+ &bsdf_pdf,
+ &bsdf_sampled_roughness,
+ &bsdf_eta);
+
+ if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) {
+ return LABEL_NONE;
+ }
+
+ unguided_bsdf_pdf = bsdf_pdf;
}
if (label & LABEL_TRANSPARENT) {
@@ -381,9 +426,8 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce(
}
/* Update throughput. */
- Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
- throughput *= bsdf_eval_sum(&bsdf_eval) / bsdf_pdf;
- INTEGRATOR_STATE_WRITE(state, path, throughput) = throughput;
+ const Spectrum bsdf_weight = bsdf_eval_sum(&bsdf_eval) / bsdf_pdf;
+ INTEGRATOR_STATE_WRITE(state, path, throughput) *= bsdf_weight;
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
if (INTEGRATOR_STATE(state, path, bounce) == 0) {
@@ -398,10 +442,21 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce(
if (!(label & LABEL_TRANSPARENT)) {
INTEGRATOR_STATE_WRITE(state, path, mis_ray_pdf) = bsdf_pdf;
INTEGRATOR_STATE_WRITE(state, path, min_ray_pdf) = fminf(
- bsdf_pdf, INTEGRATOR_STATE(state, path, min_ray_pdf));
+ unguided_bsdf_pdf, INTEGRATOR_STATE(state, path, min_ray_pdf));
}
path_state_next(kg, state, label);
+
+ guiding_record_surface_bounce(kg,
+ state,
+ sd,
+ bsdf_weight,
+ bsdf_pdf,
+ sd->N,
+ normalize(bsdf_omega_in),
+ bsdf_sampled_roughness,
+ bsdf_eta);
+
return label;
}
@@ -423,14 +478,15 @@ ccl_device_forceinline int integrate_surface_volume_only_bounce(IntegratorState
ccl_device_forceinline bool integrate_surface_terminate(IntegratorState state,
const uint32_t path_flag)
{
- const float probability = (path_flag & PATH_RAY_TERMINATE_ON_NEXT_SURFACE) ?
- 0.0f :
- INTEGRATOR_STATE(state, path, continuation_probability);
- if (probability == 0.0f) {
+ const float continuation_probability = (path_flag & PATH_RAY_TERMINATE_ON_NEXT_SURFACE) ?
+ 0.0f :
+ INTEGRATOR_STATE(
+ state, path, continuation_probability);
+ if (continuation_probability == 0.0f) {
return true;
}
- else if (probability != 1.0f) {
- INTEGRATOR_STATE_WRITE(state, path, throughput) /= probability;
+ else if (continuation_probability != 1.0f) {
+ INTEGRATOR_STATE_WRITE(state, path, throughput) /= continuation_probability;
}
return false;
@@ -538,6 +594,8 @@ ccl_device bool integrate_surface(KernelGlobals kg,
#ifdef __VOLUME__
if (!(sd.flag & SD_HAS_ONLY_VOLUME)) {
#endif
+ guiding_record_surface_segment(kg, state, &sd);
+
#ifdef __SUBSURFACE__
/* Can skip shader evaluation for BSSRDF exit point without bump mapping. */
if (!(path_flag & PATH_RAY_SUBSURFACE) || ((sd.flag & SD_HAS_BSSRDF_BUMP)))
@@ -603,6 +661,10 @@ ccl_device bool integrate_surface(KernelGlobals kg,
RNGState rng_state;
path_state_rng_load(state, &rng_state);
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
+ surface_shader_prepare_guiding(kg, state, &sd, &rng_state);
+ guiding_write_debug_passes(kg, state, &sd, render_buffer);
+#endif
/* Direct light. */
PROFILING_EVENT(PROFILING_SHADE_SURFACE_DIRECT_LIGHT);
integrate_surface_direct_light<node_feature_mask>(kg, state, &sd, &rng_state);
diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h
index aaef92729d6..a8324cda2dc 100644
--- a/intern/cycles/kernel/integrator/shade_volume.h
+++ b/intern/cycles/kernel/integrator/shade_volume.h
@@ -7,6 +7,7 @@
#include "kernel/film/denoising_passes.h"
#include "kernel/film/light_passes.h"
+#include "kernel/integrator/guiding.h"
#include "kernel/integrator/intersect_closest.h"
#include "kernel/integrator/path_state.h"
#include "kernel/integrator/volume_shader.h"
@@ -612,6 +613,7 @@ ccl_device_forceinline void volume_integrate_heterogeneous(
const Spectrum emission = volume_emission_integrate(
&coeff, closure_flag, transmittance, dt);
accum_emission += result.indirect_throughput * emission;
+ guiding_record_volume_emission(kg, state, emission);
}
}
@@ -761,7 +763,7 @@ ccl_device_forceinline void integrate_volume_direct_light(
/* Evaluate BSDF. */
BsdfEval phase_eval ccl_optional_struct_init;
- const float phase_pdf = volume_shader_phase_eval(kg, sd, phases, ls->D, &phase_eval);
+ float phase_pdf = volume_shader_phase_eval(kg, state, sd, phases, ls->D, &phase_eval);
if (ls->shader & SHADER_USE_MIS) {
float mis_weight = light_sample_mis_weight_nee(kg, ls->pdf, phase_pdf);
@@ -848,6 +850,12 @@ ccl_device_forceinline void integrate_volume_direct_light(
ls->group + 1 :
kernel_data.background.lightgroup + 1;
+# ifdef __PATH_GUIDING__
+ INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unlit_throughput) = throughput;
+ INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = INTEGRATOR_STATE(
+ state, guiding, path_segment);
+# endif
+
integrator_state_copy_volume_stack_to_shadow(kg, shadow_state, state);
}
@@ -861,18 +869,54 @@ ccl_device_forceinline bool integrate_volume_phase_scatter(
{
PROFILING_INIT(kg, PROFILING_SHADE_VOLUME_INDIRECT_LIGHT);
- const float2 rand_phase = path_state_rng_2D(kg, rng_state, PRNG_VOLUME_PHASE);
+ float2 rand_phase = path_state_rng_2D(kg, rng_state, PRNG_VOLUME_PHASE);
+
+ ccl_private const ShaderVolumeClosure *svc = volume_shader_phase_pick(phases, &rand_phase);
/* Phase closure, sample direction. */
- float phase_pdf;
+ float phase_pdf = 0.0f, unguided_phase_pdf = 0.0f;
BsdfEval phase_eval ccl_optional_struct_init;
float3 phase_omega_in ccl_optional_struct_init;
+ float sampled_roughness = 1.0f;
+ int label;
+
+# if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
+ if (kernel_data.integrator.use_guiding) {
+ label = volume_shader_phase_guided_sample(kg,
+ state,
+ sd,
+ svc,
+ rand_phase,
+ &phase_eval,
+ &phase_omega_in,
+ &phase_pdf,
+ &unguided_phase_pdf,
+ &sampled_roughness);
+
+ if (phase_pdf == 0.0f || bsdf_eval_is_zero(&phase_eval)) {
+ return false;
+ }
- const int label = volume_shader_phase_sample(
- kg, sd, phases, rand_phase, &phase_eval, &phase_omega_in, &phase_pdf);
+ INTEGRATOR_STATE_WRITE(state, path, unguided_throughput) *= phase_pdf / unguided_phase_pdf;
+ }
+ else
+# endif
+ {
+ label = volume_shader_phase_sample(kg,
+ sd,
+ phases,
+ svc,
+ rand_phase,
+ &phase_eval,
+ &phase_omega_in,
+ &phase_pdf,
+ &sampled_roughness);
+
+ if (phase_pdf == 0.0f || bsdf_eval_is_zero(&phase_eval)) {
+ return false;
+ }
- if (phase_pdf == 0.0f || bsdf_eval_is_zero(&phase_eval)) {
- return false;
+ unguided_phase_pdf = phase_pdf;
}
/* Setup ray. */
@@ -887,9 +931,15 @@ ccl_device_forceinline bool integrate_volume_phase_scatter(
INTEGRATOR_STATE_WRITE(state, isect, prim) = sd->prim;
INTEGRATOR_STATE_WRITE(state, isect, object) = sd->object;
+ const Spectrum phase_weight = bsdf_eval_sum(&phase_eval) / phase_pdf;
+
+ /* Add phase function sampling data to the path segment. */
+ guiding_record_volume_bounce(
+ kg, state, sd, phase_weight, phase_pdf, normalize(phase_omega_in), sampled_roughness);
+
/* Update throughput. */
const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
- const Spectrum throughput_phase = throughput * bsdf_eval_sum(&phase_eval) / phase_pdf;
+ const Spectrum throughput_phase = throughput * phase_weight;
INTEGRATOR_STATE_WRITE(state, path, throughput) = throughput_phase;
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
@@ -900,7 +950,7 @@ ccl_device_forceinline bool integrate_volume_phase_scatter(
/* Update path state */
INTEGRATOR_STATE_WRITE(state, path, mis_ray_pdf) = phase_pdf;
INTEGRATOR_STATE_WRITE(state, path, min_ray_pdf) = fminf(
- phase_pdf, INTEGRATOR_STATE(state, path, min_ray_pdf));
+ unguided_phase_pdf, INTEGRATOR_STATE(state, path, min_ray_pdf));
path_state_next(kg, state, label);
return true;
@@ -939,6 +989,10 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
VOLUME_READ_LAMBDA(integrator_state_read_volume_stack(state, i))
const float step_size = volume_stack_step_size(kg, volume_read_lambda_pass);
+# if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
+ const float3 initial_throughput = INTEGRATOR_STATE(state, path, throughput);
+# endif
+
/* TODO: expensive to zero closures? */
VolumeIntegrateResult result = {};
volume_integrate_heterogeneous(kg,
@@ -956,17 +1010,50 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
* to be terminated. That will shading evaluating to leave out any scattering closures,
* but emission and absorption are still handled for multiple importance sampling. */
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
- const float probability = (path_flag & PATH_RAY_TERMINATE_IN_NEXT_VOLUME) ?
- 0.0f :
- INTEGRATOR_STATE(state, path, continuation_probability);
- if (probability == 0.0f) {
+ const float continuation_probability = (path_flag & PATH_RAY_TERMINATE_IN_NEXT_VOLUME) ?
+ 0.0f :
+ INTEGRATOR_STATE(
+ state, path, continuation_probability);
+ if (continuation_probability == 0.0f) {
return VOLUME_PATH_MISSED;
}
+# if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
+ bool guiding_generated_new_segment = false;
+ if (kernel_data.integrator.use_guiding) {
+ /* Record transmittance using change in throughput. */
+ float3 transmittance_weight = spectrum_to_rgb(
+ safe_divide_color(result.indirect_throughput, initial_throughput));
+ guiding_record_volume_transmission(kg, state, transmittance_weight);
+
+ if (result.indirect_scatter) {
+ const float3 P = ray->P + result.indirect_t * ray->D;
+
+ /* Record volume segment up to direct scatter position.
+ * TODO: volume segment is wrong when direct_t and indirect_t. */
+ if (result.direct_scatter && (result.direct_t == result.indirect_t)) {
+ guiding_record_volume_segment(kg, state, P, sd.I);
+ guiding_generated_new_segment = true;
+ }
+
+# if PATH_GUIDING_LEVEL >= 4
+ /* TODO: this position will be wrong for direct light pdf computation,
+ * since the direct light position may be different? */
+ volume_shader_prepare_guiding(
+ kg, state, &sd, &rng_state, P, ray->D, &result.direct_phases, direct_sample_method);
+# endif
+ }
+ else {
+ /* No guiding if we don't scatter. */
+ state->guiding.use_volume_guiding = false;
+ }
+ }
+# endif
+
/* Direct light. */
if (result.direct_scatter) {
const float3 direct_P = ray->P + result.direct_t * ray->D;
- result.direct_throughput /= probability;
+ result.direct_throughput /= continuation_probability;
integrate_volume_direct_light(kg,
state,
&sd,
@@ -979,16 +1066,22 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
/* Indirect light.
*
- * Only divide throughput by probability if we scatter. For the attenuation
+ * Only divide throughput by continuation_probability if we scatter. For the attenuation
* case the next surface will already do this division. */
if (result.indirect_scatter) {
- result.indirect_throughput /= probability;
+ result.indirect_throughput /= continuation_probability;
}
INTEGRATOR_STATE_WRITE(state, path, throughput) = result.indirect_throughput;
if (result.indirect_scatter) {
sd.P = ray->P + result.indirect_t * ray->D;
+# if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
+ if (!guiding_generated_new_segment) {
+ guiding_record_volume_segment(kg, state, sd.P, sd.I);
+ }
+# endif
+
if (integrate_volume_phase_scatter(kg, state, &sd, &rng_state, &result.indirect_phases)) {
return VOLUME_PATH_SCATTERED;
}
diff --git a/intern/cycles/kernel/integrator/shadow_state_template.h b/intern/cycles/kernel/integrator/shadow_state_template.h
index 3b490ecffdd..d731d1df339 100644
--- a/intern/cycles/kernel/integrator/shadow_state_template.h
+++ b/intern/cycles/kernel/integrator/shadow_state_template.h
@@ -40,6 +40,16 @@ KERNEL_STRUCT_MEMBER(shadow_path, PackedSpectrum, pass_glossy_weight, KERNEL_FEA
KERNEL_STRUCT_MEMBER(shadow_path, uint16_t, num_hits, KERNEL_FEATURE_PATH_TRACING)
/* Light group. */
KERNEL_STRUCT_MEMBER(shadow_path, uint8_t, lightgroup, KERNEL_FEATURE_PATH_TRACING)
+/* Path guiding. */
+KERNEL_STRUCT_MEMBER(shadow_path, PackedSpectrum, unlit_throughput, KERNEL_FEATURE_PATH_GUIDING)
+#ifdef __PATH_GUIDING__
+KERNEL_STRUCT_MEMBER(shadow_path,
+ openpgl::cpp::PathSegment *,
+ path_segment,
+ KERNEL_FEATURE_PATH_GUIDING)
+#else
+KERNEL_STRUCT_MEMBER(shadow_path, uint64_t, path_segment, KERNEL_FEATURE_PATH_GUIDING)
+#endif
KERNEL_STRUCT_END(shadow_path)
/********************************** Shadow Ray *******************************/
diff --git a/intern/cycles/kernel/integrator/state.h b/intern/cycles/kernel/integrator/state.h
index d1907bd6e16..f0fdc6f0d54 100644
--- a/intern/cycles/kernel/integrator/state.h
+++ b/intern/cycles/kernel/integrator/state.h
@@ -31,6 +31,10 @@
#include "util/types.h"
+#ifdef __PATH_GUIDING__
+# include "util/guiding.h"
+#endif
+
#pragma once
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/integrator/state_flow.h b/intern/cycles/kernel/integrator/state_flow.h
index 4b03c665e17..40961b1c5fb 100644
--- a/intern/cycles/kernel/integrator/state_flow.h
+++ b/intern/cycles/kernel/integrator/state_flow.h
@@ -76,6 +76,9 @@ ccl_device_forceinline IntegratorShadowState integrator_shadow_path_init(
&kernel_integrator_state.next_shadow_path_index[0], 1);
atomic_fetch_and_add_uint32(&kernel_integrator_state.queue_counter->num_queued[next_kernel], 1);
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, queued_kernel) = next_kernel;
+# ifdef __PATH_GUIDING__
+ INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = nullptr;
+# endif
return shadow_state;
}
@@ -181,6 +184,9 @@ ccl_device_forceinline IntegratorShadowState integrator_shadow_path_init(
{
IntegratorShadowState shadow_state = (is_ao) ? &state->ao : &state->shadow;
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, queued_kernel) = next_kernel;
+# ifdef __PATH_GUIDING__
+ INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = nullptr;
+# endif
return shadow_state;
}
diff --git a/intern/cycles/kernel/integrator/state_template.h b/intern/cycles/kernel/integrator/state_template.h
index f4e280e4cb2..610621f0abe 100644
--- a/intern/cycles/kernel/integrator/state_template.h
+++ b/intern/cycles/kernel/integrator/state_template.h
@@ -47,6 +47,9 @@ KERNEL_STRUCT_MEMBER(path, float, min_ray_pdf, KERNEL_FEATURE_PATH_TRACING)
KERNEL_STRUCT_MEMBER(path, float, continuation_probability, KERNEL_FEATURE_PATH_TRACING)
/* Throughput. */
KERNEL_STRUCT_MEMBER(path, PackedSpectrum, throughput, KERNEL_FEATURE_PATH_TRACING)
+/* Factor to multiple with throughput to get remove any guiding PDFS.
+ * Such throughput without guiding PDFS is used for Russian roulette termination. */
+KERNEL_STRUCT_MEMBER(path, float, unguided_throughput, KERNEL_FEATURE_PATH_GUIDING)
/* Ratio of throughput to distinguish diffuse / glossy / transmission render passes. */
KERNEL_STRUCT_MEMBER(path, PackedSpectrum, pass_diffuse_weight, KERNEL_FEATURE_LIGHT_PASSES)
KERNEL_STRUCT_MEMBER(path, PackedSpectrum, pass_glossy_weight, KERNEL_FEATURE_LIGHT_PASSES)
@@ -98,3 +101,33 @@ KERNEL_STRUCT_ARRAY_MEMBER(volume_stack, int, shader, KERNEL_FEATURE_VOLUME)
KERNEL_STRUCT_END_ARRAY(volume_stack,
KERNEL_STRUCT_VOLUME_STACK_SIZE,
KERNEL_STRUCT_VOLUME_STACK_SIZE)
+
+/************************************ Path Guiding *****************************/
+KERNEL_STRUCT_BEGIN(guiding)
+#ifdef __PATH_GUIDING__
+/* Current path segment of the random walk/path. */
+KERNEL_STRUCT_MEMBER(guiding,
+ openpgl::cpp::PathSegment *,
+ path_segment,
+ KERNEL_FEATURE_PATH_GUIDING)
+#else
+/* Current path segment of the random walk/path. */
+KERNEL_STRUCT_MEMBER(guiding, uint64_t, path_segment, KERNEL_FEATURE_PATH_GUIDING)
+#endif
+/* If surface guiding is enabled */
+KERNEL_STRUCT_MEMBER(guiding, bool, use_surface_guiding, KERNEL_FEATURE_PATH_GUIDING)
+/* Random number used for additional guiding decisions (e.g., cache query, selection to use guiding
+ * or BSDF sampling) */
+KERNEL_STRUCT_MEMBER(guiding, float, sample_surface_guiding_rand, KERNEL_FEATURE_PATH_GUIDING)
+/* The probability to use surface guiding (i.e., diffuse sampling prob * guiding prob)*/
+KERNEL_STRUCT_MEMBER(guiding, float, surface_guiding_sampling_prob, KERNEL_FEATURE_PATH_GUIDING)
+/* Probability of sampling a BSSRDF closure instead of a BSDF closure*/
+KERNEL_STRUCT_MEMBER(guiding, float, bssrdf_sampling_prob, KERNEL_FEATURE_PATH_GUIDING)
+/* If volume guiding is enabled */
+KERNEL_STRUCT_MEMBER(guiding, bool, use_volume_guiding, KERNEL_FEATURE_PATH_GUIDING)
+/* Random number used for additional guiding decisions (e.g., cache query, selection to use guiding
+ * or BSDF sampling) */
+KERNEL_STRUCT_MEMBER(guiding, float, sample_volume_guiding_rand, KERNEL_FEATURE_PATH_GUIDING)
+/* The probability to use surface guiding (i.e., diffuse sampling prob * guiding prob). */
+KERNEL_STRUCT_MEMBER(guiding, float, volume_guiding_sampling_prob, KERNEL_FEATURE_PATH_GUIDING)
+KERNEL_STRUCT_END(guiding)
diff --git a/intern/cycles/kernel/integrator/subsurface.h b/intern/cycles/kernel/integrator/subsurface.h
index 15c2cb1c708..efd293e4141 100644
--- a/intern/cycles/kernel/integrator/subsurface.h
+++ b/intern/cycles/kernel/integrator/subsurface.h
@@ -78,6 +78,9 @@ ccl_device int subsurface_bounce(KernelGlobals kg,
INTEGRATOR_STATE_WRITE(state, subsurface, radius) = bssrdf->radius;
INTEGRATOR_STATE_WRITE(state, subsurface, anisotropy) = bssrdf->anisotropy;
+ /* Path guiding. */
+ guiding_record_bssrdf_weight(kg, state, weight, bssrdf->albedo);
+
return LABEL_SUBSURFACE_SCATTER;
}
diff --git a/intern/cycles/kernel/integrator/subsurface_disk.h b/intern/cycles/kernel/integrator/subsurface_disk.h
index a44b6a74d7b..16fb45392f4 100644
--- a/intern/cycles/kernel/integrator/subsurface_disk.h
+++ b/intern/cycles/kernel/integrator/subsurface_disk.h
@@ -1,6 +1,8 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
+#include "kernel/integrator/guiding.h"
+
CCL_NAMESPACE_BEGIN
/* BSSRDF using disk based importance sampling.
@@ -173,8 +175,8 @@ ccl_device_inline bool subsurface_disk(KernelGlobals kg,
if (r < next_sum) {
/* Return exit point. */
- INTEGRATOR_STATE_WRITE(state, path, throughput) *= weight * sum_weights / sample_weight;
-
+ const Spectrum resampled_weight = weight * sum_weights / sample_weight;
+ INTEGRATOR_STATE_WRITE(state, path, throughput) *= resampled_weight;
ss_isect.hits[0] = ss_isect.hits[hit];
ss_isect.Ng[0] = ss_isect.Ng[hit];
@@ -182,6 +184,9 @@ ccl_device_inline bool subsurface_disk(KernelGlobals kg,
ray.D = ss_isect.Ng[hit];
ray.tmin = 0.0f;
ray.tmax = 1.0f;
+
+ guiding_record_bssrdf_bounce(
+ kg, state, 1.0f, Ng, -Ng, resampled_weight, INTEGRATOR_STATE(state, subsurface, albedo));
return true;
}
diff --git a/intern/cycles/kernel/integrator/subsurface_random_walk.h b/intern/cycles/kernel/integrator/subsurface_random_walk.h
index a6a59e286c9..fdcb66c32f5 100644
--- a/intern/cycles/kernel/integrator/subsurface_random_walk.h
+++ b/intern/cycles/kernel/integrator/subsurface_random_walk.h
@@ -5,6 +5,8 @@
#include "kernel/bvh/bvh.h"
+#include "kernel/integrator/guiding.h"
+
CCL_NAMESPACE_BEGIN
/* Random walk subsurface scattering.
@@ -203,7 +205,7 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg,
const float anisotropy = INTEGRATOR_STATE(state, subsurface, anisotropy);
Spectrum sigma_t, alpha;
- Spectrum throughput = INTEGRATOR_STATE_WRITE(state, path, throughput);
+ Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
subsurface_random_walk_coefficients(albedo, radius, anisotropy, &sigma_t, &alpha, &throughput);
Spectrum sigma_s = sigma_t * alpha;
@@ -350,7 +352,7 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg,
}
}
- /* Sample direction along ray. */
+ /* Sample distance along ray. */
float t = -logf(1.0f - randt) / sample_sigma_t;
/* On the first bounce, we use the ray-cast to check if the opposite side is nearby.
@@ -432,6 +434,16 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg,
if (hit) {
kernel_assert(isfinite_safe(throughput));
+
+ guiding_record_bssrdf_bounce(
+ kg,
+ state,
+ pdf,
+ N,
+ D,
+ safe_divide_color(throughput, INTEGRATOR_STATE(state, path, throughput)),
+ albedo);
+
INTEGRATOR_STATE_WRITE(state, path, throughput) = throughput;
}
diff --git a/intern/cycles/kernel/integrator/surface_shader.h b/intern/cycles/kernel/integrator/surface_shader.h
index 64b5556f7e9..5e47a34f77e 100644
--- a/intern/cycles/kernel/integrator/surface_shader.h
+++ b/intern/cycles/kernel/integrator/surface_shader.h
@@ -10,6 +10,8 @@
#include "kernel/closure/bsdf_util.h"
#include "kernel/closure/emissive.h"
+#include "kernel/integrator/guiding.h"
+
#ifdef __SVM__
# include "kernel/svm/svm.h"
#endif
@@ -19,6 +21,67 @@
CCL_NAMESPACE_BEGIN
+/* Guiding */
+
+#ifdef __PATH_GUIDING__
+ccl_device_inline void surface_shader_prepare_guiding(KernelGlobals kg,
+ IntegratorState state,
+ ccl_private ShaderData *sd,
+ ccl_private const RNGState *rng_state)
+{
+ /* Have any BSDF to guide? */
+ if (!(kernel_data.integrator.use_surface_guiding && (sd->flag & SD_BSDF_HAS_EVAL))) {
+ state->guiding.use_surface_guiding = false;
+ return;
+ }
+
+ const float surface_guiding_probability = kernel_data.integrator.surface_guiding_probability;
+ float rand_bsdf_guiding = path_state_rng_1D(kg, rng_state, PRNG_SURFACE_BSDF_GUIDING);
+
+ /* Compute proportion of diffuse BSDF and BSSRDFs .*/
+ float diffuse_sampling_fraction = 0.0f;
+ float bssrdf_sampling_fraction = 0.0f;
+ float bsdf_bssrdf_sampling_sum = 0.0f;
+
+ for (int i = 0; i < sd->num_closure; i++) {
+ ShaderClosure *sc = &sd->closure[i];
+ if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
+ const float sweight = sc->sample_weight;
+ kernel_assert(sweight >= 0.0f);
+
+ bsdf_bssrdf_sampling_sum += sweight;
+ if (CLOSURE_IS_BSDF_DIFFUSE(sc->type) && sc->type < CLOSURE_BSDF_TRANSLUCENT_ID) {
+ diffuse_sampling_fraction += sweight;
+ }
+ if (CLOSURE_IS_BSSRDF(sc->type)) {
+ bssrdf_sampling_fraction += sweight;
+ }
+ }
+ }
+
+ if (bsdf_bssrdf_sampling_sum > 0.0f) {
+ diffuse_sampling_fraction /= bsdf_bssrdf_sampling_sum;
+ bssrdf_sampling_fraction /= bsdf_bssrdf_sampling_sum;
+ }
+
+ /* Init guiding (diffuse BSDFs only for now). */
+ if (!(diffuse_sampling_fraction > 0.0f &&
+ guiding_bsdf_init(kg, state, sd->P, sd->N, rand_bsdf_guiding))) {
+ state->guiding.use_surface_guiding = false;
+ return;
+ }
+
+ state->guiding.use_surface_guiding = true;
+ state->guiding.surface_guiding_sampling_prob = surface_guiding_probability *
+ diffuse_sampling_fraction;
+ state->guiding.bssrdf_sampling_prob = bssrdf_sampling_fraction;
+ state->guiding.sample_surface_guiding_rand = rand_bsdf_guiding;
+
+ kernel_assert(state->guiding.surface_guiding_sampling_prob > 0.0f &&
+ state->guiding.surface_guiding_sampling_prob <= 1.0f);
+}
+#endif
+
ccl_device_inline void surface_shader_prepare_closures(KernelGlobals kg,
ConstIntegratorState state,
ccl_private ShaderData *sd,
@@ -108,12 +171,27 @@ ccl_device_inline void surface_shader_prepare_closures(KernelGlobals kg,
}
/* BSDF */
-
-ccl_device_inline bool surface_shader_is_transmission(ccl_private const ShaderData *sd,
- const float3 omega_in)
+#if 0
+ccl_device_inline void surface_shader_validate_bsdf_sample(const KernelGlobals kg,
+ const ShaderClosure *sc,
+ const float3 omega_in,
+ const int org_label,
+ const float2 org_roughness,
+ const float org_eta)
{
- return dot(sd->N, omega_in) < 0.0f;
+ /* Validate the the bsdf_label and bsdf_roughness_eta functions
+ * by estimating the values after a bsdf sample. */
+ const int comp_label = bsdf_label(kg, sc, omega_in);
+ kernel_assert(org_label == comp_label);
+
+ float2 comp_roughness;
+ float comp_eta;
+ bsdf_roughness_eta(kg, sc, &comp_roughness, &comp_eta);
+ kernel_assert(org_eta == comp_eta);
+ kernel_assert(org_roughness.x == comp_roughness.x);
+ kernel_assert(org_roughness.y == comp_roughness.y);
}
+#endif
ccl_device_forceinline bool _surface_shader_exclude(ClosureType type, uint light_shader_flags)
{
@@ -141,7 +219,6 @@ ccl_device_forceinline bool _surface_shader_exclude(ClosureType type, uint light
ccl_device_inline float _surface_shader_bsdf_eval_mis(KernelGlobals kg,
ccl_private ShaderData *sd,
const float3 omega_in,
- const bool is_transmission,
ccl_private const ShaderClosure *skip_sc,
ccl_private BsdfEval *result_eval,
float sum_pdf,
@@ -160,7 +237,7 @@ ccl_device_inline float _surface_shader_bsdf_eval_mis(KernelGlobals kg,
if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
if (CLOSURE_IS_BSDF(sc->type) && !_surface_shader_exclude(sc->type, light_shader_flags)) {
float bsdf_pdf = 0.0f;
- Spectrum eval = bsdf_eval(kg, sd, sc, omega_in, is_transmission, &bsdf_pdf);
+ Spectrum eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
if (bsdf_pdf != 0.0f) {
bsdf_eval_accum(result_eval, sc->type, eval * sc->weight);
@@ -175,6 +252,55 @@ ccl_device_inline float _surface_shader_bsdf_eval_mis(KernelGlobals kg,
return (sum_sample_weight > 0.0f) ? sum_pdf / sum_sample_weight : 0.0f;
}
+ccl_device_inline float surface_shader_bsdf_eval_pdfs(const KernelGlobals kg,
+ ccl_private ShaderData *sd,
+ const float3 omega_in,
+ ccl_private BsdfEval *result_eval,
+ ccl_private float *pdfs,
+ const uint light_shader_flags)
+{
+ /* This is the veach one-sample model with balance heuristic, some pdf
+ * factors drop out when using balance heuristic weighting. */
+ float sum_pdf = 0.0f;
+ float sum_sample_weight = 0.0f;
+ bsdf_eval_init(result_eval, CLOSURE_NONE_ID, zero_spectrum());
+ for (int i = 0; i < sd->num_closure; i++) {
+ ccl_private const ShaderClosure *sc = &sd->closure[i];
+
+ if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
+ if (CLOSURE_IS_BSDF(sc->type) && !_surface_shader_exclude(sc->type, light_shader_flags)) {
+ float bsdf_pdf = 0.0f;
+ Spectrum eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
+ kernel_assert(bsdf_pdf >= 0.0f);
+ if (bsdf_pdf != 0.0f) {
+ bsdf_eval_accum(result_eval, sc->type, eval * sc->weight);
+ sum_pdf += bsdf_pdf * sc->sample_weight;
+ kernel_assert(bsdf_pdf * sc->sample_weight >= 0.0f);
+ pdfs[i] = bsdf_pdf * sc->sample_weight;
+ }
+ else {
+ pdfs[i] = 0.0f;
+ }
+ }
+ else {
+ pdfs[i] = 0.0f;
+ }
+
+ sum_sample_weight += sc->sample_weight;
+ }
+ else {
+ pdfs[i] = 0.0f;
+ }
+ }
+ if (sum_pdf > 0.0f) {
+ for (int i = 0; i < sd->num_closure; i++) {
+ pdfs[i] /= sum_pdf;
+ }
+ }
+
+ return (sum_sample_weight > 0.0f) ? sum_pdf / sum_sample_weight : 0.0f;
+}
+
#ifndef __KERNEL_CUDA__
ccl_device
#else
@@ -182,16 +308,28 @@ ccl_device_inline
#endif
float
surface_shader_bsdf_eval(KernelGlobals kg,
+ IntegratorState state,
ccl_private ShaderData *sd,
const float3 omega_in,
- const bool is_transmission,
ccl_private BsdfEval *bsdf_eval,
const uint light_shader_flags)
{
bsdf_eval_init(bsdf_eval, CLOSURE_NONE_ID, zero_spectrum());
- return _surface_shader_bsdf_eval_mis(
- kg, sd, omega_in, is_transmission, NULL, bsdf_eval, 0.0f, 0.0f, light_shader_flags);
+ float pdf = _surface_shader_bsdf_eval_mis(
+ kg, sd, omega_in, NULL, bsdf_eval, 0.0f, 0.0f, light_shader_flags);
+
+#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
+ if (state->guiding.use_surface_guiding) {
+ const float guiding_sampling_prob = state->guiding.surface_guiding_sampling_prob;
+ const float bssrdf_sampling_prob = state->guiding.bssrdf_sampling_prob;
+ const float guide_pdf = guiding_bsdf_pdf(kg, state, omega_in);
+ pdf = (guiding_sampling_prob * guide_pdf * (1.0f - bssrdf_sampling_prob)) +
+ (1.0f - guiding_sampling_prob) * pdf;
+ }
+#endif
+
+ return pdf;
}
/* Randomly sample a BSSRDF or BSDF proportional to ShaderClosure.sample_weight. */
@@ -259,6 +397,135 @@ surface_shader_bssrdf_sample_weight(ccl_private const ShaderData *ccl_restrict s
return weight;
}
+#ifdef __PATH_GUIDING__
+/* Sample direction for picked BSDF, and return evaluation and pdf for all
+ * BSDFs combined using MIS. */
+
+ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg,
+ IntegratorState state,
+ ccl_private ShaderData *sd,
+ ccl_private const ShaderClosure *sc,
+ const float2 rand_bsdf,
+ ccl_private BsdfEval *bsdf_eval,
+ ccl_private float3 *omega_in,
+ ccl_private float *bsdf_pdf,
+ ccl_private float *unguided_bsdf_pdf,
+ ccl_private float2 *sampled_rougness,
+ ccl_private float *eta)
+{
+ /* BSSRDF should already have been handled elsewhere. */
+ kernel_assert(CLOSURE_IS_BSDF(sc->type));
+
+ const bool use_surface_guiding = state->guiding.use_surface_guiding;
+ const float guiding_sampling_prob = state->guiding.surface_guiding_sampling_prob;
+ const float bssrdf_sampling_prob = state->guiding.bssrdf_sampling_prob;
+
+ /* Decide between sampling guiding distribution and BSDF. */
+ bool sample_guiding = false;
+ float rand_bsdf_guiding = state->guiding.sample_surface_guiding_rand;
+
+ if (use_surface_guiding && rand_bsdf_guiding < guiding_sampling_prob) {
+ sample_guiding = true;
+ rand_bsdf_guiding /= guiding_sampling_prob;
+ }
+ else {
+ rand_bsdf_guiding -= guiding_sampling_prob;
+ rand_bsdf_guiding /= (1.0f - guiding_sampling_prob);
+ }
+
+ /* Initialize to zero. */
+ int label = LABEL_NONE;
+ Spectrum eval = zero_spectrum();
+ bsdf_eval_init(bsdf_eval, CLOSURE_NONE_ID, eval);
+
+ *unguided_bsdf_pdf = 0.0f;
+ float guide_pdf = 0.0f;
+
+ if (sample_guiding) {
+ /* Sample guiding distribution. */
+ guide_pdf = guiding_bsdf_sample(kg, state, rand_bsdf, omega_in);
+ *bsdf_pdf = 0.0f;
+
+ if (guide_pdf != 0.0f) {
+ float unguided_bsdf_pdfs[MAX_CLOSURE];
+
+ *unguided_bsdf_pdf = surface_shader_bsdf_eval_pdfs(
+ kg, sd, *omega_in, bsdf_eval, unguided_bsdf_pdfs, 0);
+ *bsdf_pdf = (guiding_sampling_prob * guide_pdf * (1.0f - bssrdf_sampling_prob)) +
+ ((1.0f - guiding_sampling_prob) * (*unguided_bsdf_pdf));
+ float sum_pdfs = 0.0f;
+
+ if (*unguided_bsdf_pdf > 0.0f) {
+ int idx = -1;
+ for (int i = 0; i < sd->num_closure; i++) {
+ sum_pdfs += unguided_bsdf_pdfs[i];
+ if (rand_bsdf_guiding <= sum_pdfs) {
+ idx = i;
+ break;
+ }
+ }
+
+ kernel_assert(idx >= 0);
+ /* Set the default idx to the last in the list.
+ * in case of numerical problems and rand_bsdf_guiding is just >=1.0f and
+ * the sum of all unguided_bsdf_pdfs is just < 1.0f. */
+ idx = (rand_bsdf_guiding > sum_pdfs) ? sd->num_closure - 1 : idx;
+
+ label = bsdf_label(kg, &sd->closure[idx], *omega_in);
+ }
+ }
+
+ kernel_assert(reduce_min(bsdf_eval_sum(bsdf_eval)) >= 0.0f);
+
+ *sampled_rougness = make_float2(1.0f, 1.0f);
+ *eta = 1.0f;
+ }
+ else {
+ /* Sample BSDF. */
+ *bsdf_pdf = 0.0f;
+ label = bsdf_sample(kg,
+ sd,
+ sc,
+ rand_bsdf.x,
+ rand_bsdf.y,
+ &eval,
+ omega_in,
+ unguided_bsdf_pdf,
+ sampled_rougness,
+ eta);
+# if 0
+ if (*unguided_bsdf_pdf > 0.0f) {
+ surface_shader_validate_bsdf_sample(kg, sc, *omega_in, label, sampled_roughness, eta);
+ }
+# endif
+
+ if (*unguided_bsdf_pdf != 0.0f) {
+ bsdf_eval_init(bsdf_eval, sc->type, eval * sc->weight);
+
+ kernel_assert(reduce_min(bsdf_eval_sum(bsdf_eval)) >= 0.0f);
+
+ if (sd->num_closure > 1) {
+ float sweight = sc->sample_weight;
+ *unguided_bsdf_pdf = _surface_shader_bsdf_eval_mis(
+ kg, sd, *omega_in, sc, bsdf_eval, (*unguided_bsdf_pdf) * sweight, sweight, 0);
+ kernel_assert(reduce_min(bsdf_eval_sum(bsdf_eval)) >= 0.0f);
+ }
+ *bsdf_pdf = *unguided_bsdf_pdf;
+
+ if (use_surface_guiding) {
+ guide_pdf = guiding_bsdf_pdf(kg, state, *omega_in);
+ *bsdf_pdf *= 1.0f - guiding_sampling_prob;
+ *bsdf_pdf += guiding_sampling_prob * guide_pdf * (1.0f - bssrdf_sampling_prob);
+ }
+ }
+
+ kernel_assert(reduce_min(bsdf_eval_sum(bsdf_eval)) >= 0.0f);
+ }
+
+ return label;
+}
+#endif
+
/* Sample direction for picked BSDF, and return evaluation and pdf for all
* BSDFs combined using MIS. */
ccl_device int surface_shader_bsdf_sample_closure(KernelGlobals kg,
@@ -267,7 +534,9 @@ ccl_device int surface_shader_bsdf_sample_closure(KernelGlobals kg,
const float2 rand_bsdf,
ccl_private BsdfEval *bsdf_eval,
ccl_private float3 *omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ ccl_private float2 *sampled_roughness,
+ ccl_private float *eta)
{
/* BSSRDF should already have been handled elsewhere. */
kernel_assert(CLOSURE_IS_BSDF(sc->type));
@@ -276,18 +545,21 @@ ccl_device int surface_shader_bsdf_sample_closure(KernelGlobals kg,
Spectrum eval = zero_spectrum();
*pdf = 0.0f;
- label = bsdf_sample(kg, sd, sc, rand_bsdf.x, rand_bsdf.y, &eval, omega_in, pdf);
+ label = bsdf_sample(
+ kg, sd, sc, rand_bsdf.x, rand_bsdf.y, &eval, omega_in, pdf, sampled_roughness, eta);
if (*pdf != 0.0f) {
bsdf_eval_init(bsdf_eval, sc->type, eval * sc->weight);
if (sd->num_closure > 1) {
- const bool is_transmission = surface_shader_is_transmission(sd, *omega_in);
float sweight = sc->sample_weight;
*pdf = _surface_shader_bsdf_eval_mis(
- kg, sd, *omega_in, is_transmission, sc, bsdf_eval, *pdf * sweight, sweight, 0);
+ kg, sd, *omega_in, sc, bsdf_eval, *pdf * sweight, sweight, 0);
}
}
+ else {
+ bsdf_eval_init(bsdf_eval, sc->type, zero_spectrum());
+ }
return label;
}
@@ -555,13 +827,8 @@ ccl_device void surface_shader_eval(KernelGlobals kg,
sd->num_closure_left = max_closures;
#ifdef __OSL__
- if (kg->osl) {
- if (sd->object == OBJECT_NONE && sd->lamp == LAMP_NONE) {
- OSLShader::eval_background(kg, state, sd, path_flag);
- }
- else {
- OSLShader::eval_surface(kg, state, sd, path_flag);
- }
+ if (kernel_data.kernel_features & KERNEL_FEATURE_OSL) {
+ osl_eval_nodes<SHADER_TYPE_SURFACE>(kg, state, sd, path_flag);
}
else
#endif
diff --git a/intern/cycles/kernel/integrator/volume_shader.h b/intern/cycles/kernel/integrator/volume_shader.h
index 31039bfdcf5..f9050647c6d 100644
--- a/intern/cycles/kernel/integrator/volume_shader.h
+++ b/intern/cycles/kernel/integrator/volume_shader.h
@@ -22,6 +22,7 @@ CCL_NAMESPACE_BEGIN
#ifdef __VOLUME__
/* Merging */
+
ccl_device_inline void volume_shader_merge_closures(ccl_private ShaderData *sd)
{
/* Merge identical closures to save closure space with stacked volumes. */
@@ -88,6 +89,119 @@ ccl_device_inline void volume_shader_copy_phases(ccl_private ShaderVolumePhases
}
}
+/* Guiding */
+
+# ifdef __PATH_GUIDING__
+ccl_device_inline void volume_shader_prepare_guiding(KernelGlobals kg,
+ IntegratorState state,
+ ccl_private ShaderData *sd,
+ ccl_private const RNGState *rng_state,
+ const float3 P,
+ const float3 D,
+ ccl_private ShaderVolumePhases *phases,
+ const VolumeSampleMethod direct_sample_method)
+{
+ /* Have any phase functions to guide? */
+ const int num_phases = phases->num_closure;
+ if (!kernel_data.integrator.use_volume_guiding || num_phases == 0) {
+ state->guiding.use_volume_guiding = false;
+ return;
+ }
+
+ const float volume_guiding_probability = kernel_data.integrator.volume_guiding_probability;
+ float rand_phase_guiding = path_state_rng_1D(kg, rng_state, PRNG_VOLUME_PHASE_GUIDING);
+
+ /* If we have more than one phase function we select one random based on its
+ * sample weight to calculate the product distribution for guiding. */
+ int phase_id = 0;
+ float phase_weight = 1.0f;
+
+ if (num_phases > 1) {
+ /* Pick a phase closure based on sample weights. */
+ float sum = 0.0f;
+
+ for (phase_id = 0; phase_id < num_phases; phase_id++) {
+ ccl_private const ShaderVolumeClosure *svc = &phases->closure[phase_id];
+ sum += svc->sample_weight;
+ }
+
+ float r = rand_phase_guiding * sum;
+ float partial_sum = 0.0f;
+
+ for (phase_id = 0; phase_id < num_phases; phase_id++) {
+ ccl_private const ShaderVolumeClosure *svc = &phases->closure[phase_id];
+ float next_sum = partial_sum + svc->sample_weight;
+
+ if (r <= next_sum) {
+ /* Rescale to reuse. */
+ rand_phase_guiding = (r - partial_sum) / svc->sample_weight;
+ phase_weight = svc->sample_weight / sum;
+ break;
+ }
+
+ partial_sum = next_sum;
+ }
+
+ /* Adjust the sample weight of the component used for guiding. */
+ phases->closure[phase_id].sample_weight *= volume_guiding_probability;
+ }
+
+ /* Init guiding for selected phase function. */
+ ccl_private const ShaderVolumeClosure *svc = &phases->closure[phase_id];
+ if (!guiding_phase_init(kg, state, P, D, svc->g, rand_phase_guiding)) {
+ state->guiding.use_volume_guiding = false;
+ return;
+ }
+
+ state->guiding.use_volume_guiding = true;
+ state->guiding.sample_volume_guiding_rand = rand_phase_guiding;
+ state->guiding.volume_guiding_sampling_prob = volume_guiding_probability * phase_weight;
+
+ kernel_assert(state->guiding.volume_guiding_sampling_prob > 0.0f &&
+ state->guiding.volume_guiding_sampling_prob <= 1.0f);
+}
+# endif
+
+/* Phase Evaluation & Sampling */
+
+/* Randomly sample a volume phase function proportional to ShaderClosure.sample_weight. */
+ccl_device_inline ccl_private const ShaderVolumeClosure *volume_shader_phase_pick(
+ ccl_private const ShaderVolumePhases *phases, ccl_private float2 *rand_phase)
+{
+ int sampled = 0;
+
+ if (phases->num_closure > 1) {
+ /* pick a phase closure based on sample weights */
+ float sum = 0.0f;
+
+ for (int i = 0; i < phases->num_closure; i++) {
+ ccl_private const ShaderVolumeClosure *svc = &phases->closure[sampled];
+ sum += svc->sample_weight;
+ }
+
+ float r = (*rand_phase).x * sum;
+ float partial_sum = 0.0f;
+
+ for (int i = 0; i < phases->num_closure; i++) {
+ ccl_private const ShaderVolumeClosure *svc = &phases->closure[i];
+ float next_sum = partial_sum + svc->sample_weight;
+
+ if (r <= next_sum) {
+ /* Rescale to reuse for volume phase direction sample. */
+ sampled = i;
+ (*rand_phase).x = (r - partial_sum) / svc->sample_weight;
+ break;
+ }
+
+ partial_sum = next_sum;
+ }
+ }
+
+ /* todo: this isn't quite correct, we don't weight anisotropy properly
+ * depending on color channels, even if this is perhaps not a common case */
+ return &phases->closure[sampled];
+}
+
ccl_device_inline float _volume_shader_phase_eval_mis(ccl_private const ShaderData *sd,
ccl_private const ShaderVolumePhases *phases,
const float3 omega_in,
@@ -117,88 +231,139 @@ ccl_device_inline float _volume_shader_phase_eval_mis(ccl_private const ShaderDa
ccl_device float volume_shader_phase_eval(KernelGlobals kg,
ccl_private const ShaderData *sd,
- ccl_private const ShaderVolumePhases *phases,
+ ccl_private const ShaderVolumeClosure *svc,
const float3 omega_in,
ccl_private BsdfEval *phase_eval)
{
- bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, zero_spectrum());
+ float phase_pdf = 0.0f;
+ Spectrum eval = volume_phase_eval(sd, svc, omega_in, &phase_pdf);
+
+ if (phase_pdf != 0.0f) {
+ bsdf_eval_accum(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval);
+ }
- return _volume_shader_phase_eval_mis(sd, phases, omega_in, -1, phase_eval, 0.0f, 0.0f);
+ return phase_pdf;
}
-ccl_device int volume_shader_phase_sample(KernelGlobals kg,
+ccl_device float volume_shader_phase_eval(KernelGlobals kg,
+ IntegratorState state,
ccl_private const ShaderData *sd,
ccl_private const ShaderVolumePhases *phases,
- float2 rand_phase,
- ccl_private BsdfEval *phase_eval,
- ccl_private float3 *omega_in,
- ccl_private float *pdf)
+ const float3 omega_in,
+ ccl_private BsdfEval *phase_eval)
{
- int sampled = 0;
+ bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, zero_spectrum());
- if (phases->num_closure > 1) {
- /* pick a phase closure based on sample weights */
- float sum = 0.0f;
+ float pdf = _volume_shader_phase_eval_mis(sd, phases, omega_in, -1, phase_eval, 0.0f, 0.0f);
- for (sampled = 0; sampled < phases->num_closure; sampled++) {
- ccl_private const ShaderVolumeClosure *svc = &phases->closure[sampled];
- sum += svc->sample_weight;
- }
+# if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
+ if (state->guiding.use_volume_guiding) {
+ const float guiding_sampling_prob = state->guiding.volume_guiding_sampling_prob;
+ const float guide_pdf = guiding_phase_pdf(kg, state, omega_in);
+ pdf = (guiding_sampling_prob * guide_pdf) + (1.0f - guiding_sampling_prob) * pdf;
+ }
+# endif
- float r = rand_phase.x * sum;
- float partial_sum = 0.0f;
+ return pdf;
+}
- for (sampled = 0; sampled < phases->num_closure; sampled++) {
- ccl_private const ShaderVolumeClosure *svc = &phases->closure[sampled];
- float next_sum = partial_sum + svc->sample_weight;
+# ifdef __PATH_GUIDING__
+ccl_device int volume_shader_phase_guided_sample(KernelGlobals kg,
+ IntegratorState state,
+ ccl_private const ShaderData *sd,
+ ccl_private const ShaderVolumeClosure *svc,
+ const float2 rand_phase,
+ ccl_private BsdfEval *phase_eval,
+ ccl_private float3 *omega_in,
+ ccl_private float *phase_pdf,
+ ccl_private float *unguided_phase_pdf,
+ ccl_private float *sampled_roughness)
+{
+ const bool use_volume_guiding = state->guiding.use_volume_guiding;
+ const float guiding_sampling_prob = state->guiding.volume_guiding_sampling_prob;
+
+ /* Decide between sampling guiding distribution and phase. */
+ float rand_phase_guiding = state->guiding.sample_volume_guiding_rand;
+ bool sample_guiding = false;
+ if (use_volume_guiding && rand_phase_guiding < guiding_sampling_prob) {
+ sample_guiding = true;
+ rand_phase_guiding /= guiding_sampling_prob;
+ }
+ else {
+ rand_phase_guiding -= guiding_sampling_prob;
+ rand_phase_guiding /= (1.0f - guiding_sampling_prob);
+ }
- if (r <= next_sum) {
- /* Rescale to reuse for BSDF direction sample. */
- rand_phase.x = (r - partial_sum) / svc->sample_weight;
- break;
- }
+ /* Initialize to zero. */
+ int label = LABEL_NONE;
+ Spectrum eval = zero_spectrum();
- partial_sum = next_sum;
- }
+ *unguided_phase_pdf = 0.0f;
+ float guide_pdf = 0.0f;
+ *sampled_roughness = 1.0f - fabsf(svc->g);
+
+ bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, zero_spectrum());
- if (sampled == phases->num_closure) {
- *pdf = 0.0f;
- return LABEL_NONE;
+ if (sample_guiding) {
+ /* Sample guiding distribution. */
+ guide_pdf = guiding_phase_sample(kg, state, rand_phase, omega_in);
+ *phase_pdf = 0.0f;
+
+ if (guide_pdf != 0.0f) {
+ *unguided_phase_pdf = volume_shader_phase_eval(kg, sd, svc, *omega_in, phase_eval);
+ *phase_pdf = (guiding_sampling_prob * guide_pdf) +
+ ((1.0f - guiding_sampling_prob) * (*unguided_phase_pdf));
+ label = LABEL_VOLUME_SCATTER;
}
}
+ else {
+ /* Sample phase. */
+ *phase_pdf = 0.0f;
+ label = volume_phase_sample(
+ sd, svc, rand_phase.x, rand_phase.y, &eval, omega_in, unguided_phase_pdf);
+
+ if (*unguided_phase_pdf != 0.0f) {
+ bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval);
+
+ *phase_pdf = *unguided_phase_pdf;
+ if (use_volume_guiding) {
+ guide_pdf = guiding_phase_pdf(kg, state, *omega_in);
+ *phase_pdf *= 1.0f - guiding_sampling_prob;
+ *phase_pdf += guiding_sampling_prob * guide_pdf;
+ }
- /* todo: this isn't quite correct, we don't weight anisotropy properly
- * depending on color channels, even if this is perhaps not a common case */
- ccl_private const ShaderVolumeClosure *svc = &phases->closure[sampled];
- int label;
- Spectrum eval = zero_spectrum();
-
- *pdf = 0.0f;
- label = volume_phase_sample(sd, svc, rand_phase.x, rand_phase.y, &eval, omega_in, pdf);
+ kernel_assert(reduce_min(bsdf_eval_sum(phase_eval)) >= 0.0f);
+ }
+ else {
+ bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, zero_spectrum());
+ }
- if (*pdf != 0.0f) {
- bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval);
+ kernel_assert(reduce_min(bsdf_eval_sum(phase_eval)) >= 0.0f);
}
return label;
}
+# endif
-ccl_device int volume_shader_phase_sample_closure(KernelGlobals kg,
- ccl_private const ShaderData *sd,
- ccl_private const ShaderVolumeClosure *sc,
- const float2 rand_phase,
- ccl_private BsdfEval *phase_eval,
- ccl_private float3 *omega_in,
- ccl_private float *pdf)
+ccl_device int volume_shader_phase_sample(KernelGlobals kg,
+ ccl_private const ShaderData *sd,
+ ccl_private const ShaderVolumePhases *phases,
+ ccl_private const ShaderVolumeClosure *svc,
+ float2 rand_phase,
+ ccl_private BsdfEval *phase_eval,
+ ccl_private float3 *omega_in,
+ ccl_private float *pdf,
+ ccl_private float *sampled_roughness)
{
- int label;
+ *sampled_roughness = 1.0f - fabsf(svc->g);
Spectrum eval = zero_spectrum();
*pdf = 0.0f;
- label = volume_phase_sample(sd, sc, rand_phase.x, rand_phase.y, &eval, omega_in, pdf);
+ int label = volume_phase_sample(sd, svc, rand_phase.x, rand_phase.y, &eval, omega_in, pdf);
- if (*pdf != 0.0f)
+ if (*pdf != 0.0f) {
bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval);
+ }
return label;
}
@@ -328,8 +493,8 @@ ccl_device_inline void volume_shader_eval(KernelGlobals kg,
/* evaluate shader */
# ifdef __OSL__
- if (kg->osl) {
- OSLShader::eval_volume(kg, state, sd, path_flag);
+ if (kernel_data.kernel_features & KERNEL_FEATURE_OSL) {
+ osl_eval_nodes<SHADER_TYPE_VOLUME>(kg, state, sd, path_flag);
}
else
# endif
diff --git a/intern/cycles/kernel/osl/closures.cpp b/intern/cycles/kernel/osl/closures.cpp
index d56e0551a91..6800c765345 100644
--- a/intern/cycles/kernel/osl/closures.cpp
+++ b/intern/cycles/kernel/osl/closures.cpp
@@ -25,13 +25,18 @@
#include "kernel/osl/osl.h"
-#include "kernel/osl/closures_setup.h"
-
#define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z)
#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2])
CCL_NAMESPACE_BEGIN
+static_assert(sizeof(OSLClosure) == sizeof(OSL::ClosureColor) &&
+ sizeof(OSLClosureAdd) == sizeof(OSL::ClosureAdd) &&
+ sizeof(OSLClosureMul) == sizeof(OSL::ClosureMul) &&
+ sizeof(OSLClosureComponent) == sizeof(OSL::ClosureComponent));
+static_assert(sizeof(ShaderGlobals) == sizeof(OSL::ShaderGlobals) &&
+ offsetof(ShaderGlobals, Ci) == offsetof(OSL::ShaderGlobals, Ci));
+
/* Registration */
#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \
@@ -60,53 +65,18 @@ void OSLRenderServices::register_closures(OSL::ShadingSystem *ss)
#include "closures_template.h"
}
-/* Globals */
+/* Surface & Background */
-static void shaderdata_to_shaderglobals(const KernelGlobalsCPU *kg,
- ShaderData *sd,
- const void *state,
- uint32_t path_flag,
- OSLThreadData *tdata)
+template<>
+void osl_eval_nodes<SHADER_TYPE_SURFACE>(const KernelGlobalsCPU *kg,
+ const void *state,
+ ShaderData *sd,
+ uint32_t path_flag)
{
- OSL::ShaderGlobals *globals = &tdata->globals;
-
- const differential3 dP = differential_from_compact(sd->Ng, sd->dP);
- const differential3 dI = differential_from_compact(sd->I, sd->dI);
-
- /* copy from shader data to shader globals */
- globals->P = TO_VEC3(sd->P);
- globals->dPdx = TO_VEC3(dP.dx);
- globals->dPdy = TO_VEC3(dP.dy);
- globals->I = TO_VEC3(sd->I);
- globals->dIdx = TO_VEC3(dI.dx);
- globals->dIdy = TO_VEC3(dI.dy);
- globals->N = TO_VEC3(sd->N);
- globals->Ng = TO_VEC3(sd->Ng);
- globals->u = sd->u;
- globals->dudx = sd->du.dx;
- globals->dudy = sd->du.dy;
- globals->v = sd->v;
- globals->dvdx = sd->dv.dx;
- globals->dvdy = sd->dv.dy;
- globals->dPdu = TO_VEC3(sd->dPdu);
- globals->dPdv = TO_VEC3(sd->dPdv);
- globals->surfacearea = 1.0f;
- globals->time = sd->time;
-
- /* booleans */
- globals->raytype = path_flag;
- globals->flipHandedness = 0;
- globals->backfacing = (sd->flag & SD_BACKFACING);
-
- /* shader data to be used in services callbacks */
- globals->renderstate = sd;
-
- /* hacky, we leave it to services to fetch actual object matrix */
- globals->shader2common = sd;
- globals->object2common = sd;
-
- /* must be set to NULL before execute */
- globals->Ci = NULL;
+ /* setup shader globals from shader data */
+ OSLThreadData *tdata = kg->osl_tdata;
+ shaderdata_to_shaderglobals(
+ kg, sd, path_flag, reinterpret_cast<ShaderGlobals *>(&tdata->globals));
/* clear trace data */
tdata->tracedata.init = false;
@@ -121,53 +91,6 @@ static void shaderdata_to_shaderglobals(const KernelGlobalsCPU *kg,
sd->osl_path_state = (const IntegratorStateCPU *)state;
sd->osl_shadow_path_state = nullptr;
}
-}
-
-static void flatten_closure_tree(const KernelGlobalsCPU *kg,
- ShaderData *sd,
- uint32_t path_flag,
- const OSL::ClosureColor *closure,
- float3 weight = make_float3(1.0f, 1.0f, 1.0f))
-{
- /* OSL gives us a closure tree, we flatten it into arrays per
- * closure type, for evaluation, sampling, etc later on. */
-
- switch (closure->id) {
- case OSL::ClosureColor::MUL: {
- OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
- flatten_closure_tree(kg, sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight);
- break;
- }
- case OSL::ClosureColor::ADD: {
- OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
- flatten_closure_tree(kg, sd, path_flag, add->closureA, weight);
- flatten_closure_tree(kg, sd, path_flag, add->closureB, weight);
- break;
- }
-#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \
- case OSL_CLOSURE_##Upper##_ID: { \
- const OSL::ClosureComponent *comp = reinterpret_cast<const OSL::ClosureComponent *>(closure); \
- weight *= TO_FLOAT3(comp->w); \
- osl_closure_##lower##_setup( \
- kg, sd, path_flag, weight, reinterpret_cast<const Upper##Closure *>(comp + 1)); \
- break; \
- }
-#include "closures_template.h"
- default:
- break;
- }
-}
-
-/* Surface */
-
-void OSLShader::eval_surface(const KernelGlobalsCPU *kg,
- const void *state,
- ShaderData *sd,
- uint32_t path_flag)
-{
- /* setup shader globals from shader data */
- OSLThreadData *tdata = kg->osl_tdata;
- shaderdata_to_shaderglobals(kg, sd, state, path_flag, tdata);
/* execute shader for this point */
OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
@@ -175,101 +98,99 @@ void OSLShader::eval_surface(const KernelGlobalsCPU *kg,
OSL::ShadingContext *octx = tdata->context;
int shader = sd->shader & SHADER_MASK;
- /* automatic bump shader */
- if (kg->osl->bump_state[shader]) {
- /* save state */
- const float3 P = sd->P;
- const float dP = sd->dP;
- const OSL::Vec3 dPdx = globals->dPdx;
- const OSL::Vec3 dPdy = globals->dPdy;
-
- /* set state as if undisplaced */
- if (sd->flag & SD_HAS_DISPLACEMENT) {
- float data[9];
- bool found = kg->osl->services->get_attribute(sd,
- true,
- OSLRenderServices::u_empty,
- TypeDesc::TypeVector,
- OSLRenderServices::u_geom_undisplaced,
- data);
- (void)found;
- assert(found);
-
- differential3 tmp_dP;
- memcpy(&sd->P, data, sizeof(float) * 3);
- memcpy(&tmp_dP.dx, data + 3, sizeof(float) * 3);
- memcpy(&tmp_dP.dy, data + 6, sizeof(float) * 3);
-
- object_position_transform(kg, sd, &sd->P);
- object_dir_transform(kg, sd, &tmp_dP.dx);
- object_dir_transform(kg, sd, &tmp_dP.dy);
-
- sd->dP = differential_make_compact(tmp_dP);
-
- globals->P = TO_VEC3(sd->P);
- globals->dPdx = TO_VEC3(tmp_dP.dx);
- globals->dPdy = TO_VEC3(tmp_dP.dy);
+ if (sd->object == OBJECT_NONE && sd->lamp == LAMP_NONE) {
+ /* background */
+ if (kg->osl->background_state) {
+ ss->execute(octx, *(kg->osl->background_state), *globals);
}
-
- /* execute bump shader */
- ss->execute(octx, *(kg->osl->bump_state[shader]), *globals);
-
- /* reset state */
- sd->P = P;
- sd->dP = dP;
-
- globals->P = TO_VEC3(P);
- globals->dPdx = TO_VEC3(dPdx);
- globals->dPdy = TO_VEC3(dPdy);
}
+ else {
+ /* automatic bump shader */
+ if (kg->osl->bump_state[shader]) {
+ /* save state */
+ const float3 P = sd->P;
+ const float dP = sd->dP;
+ const OSL::Vec3 dPdx = globals->dPdx;
+ const OSL::Vec3 dPdy = globals->dPdy;
+
+ /* set state as if undisplaced */
+ if (sd->flag & SD_HAS_DISPLACEMENT) {
+ float data[9];
+ bool found = kg->osl->services->get_attribute(sd,
+ true,
+ OSLRenderServices::u_empty,
+ TypeDesc::TypeVector,
+ OSLRenderServices::u_geom_undisplaced,
+ data);
+ (void)found;
+ assert(found);
+
+ differential3 tmp_dP;
+ memcpy(&sd->P, data, sizeof(float) * 3);
+ memcpy(&tmp_dP.dx, data + 3, sizeof(float) * 3);
+ memcpy(&tmp_dP.dy, data + 6, sizeof(float) * 3);
+
+ object_position_transform(kg, sd, &sd->P);
+ object_dir_transform(kg, sd, &tmp_dP.dx);
+ object_dir_transform(kg, sd, &tmp_dP.dy);
+
+ sd->dP = differential_make_compact(tmp_dP);
+
+ globals->P = TO_VEC3(sd->P);
+ globals->dPdx = TO_VEC3(tmp_dP.dx);
+ globals->dPdy = TO_VEC3(tmp_dP.dy);
+ }
+
+ /* execute bump shader */
+ ss->execute(octx, *(kg->osl->bump_state[shader]), *globals);
+
+ /* reset state */
+ sd->P = P;
+ sd->dP = dP;
+
+ globals->P = TO_VEC3(P);
+ globals->dPdx = TO_VEC3(dPdx);
+ globals->dPdy = TO_VEC3(dPdy);
+ }
- /* surface shader */
- if (kg->osl->surface_state[shader]) {
- ss->execute(octx, *(kg->osl->surface_state[shader]), *globals);
+ /* surface shader */
+ if (kg->osl->surface_state[shader]) {
+ ss->execute(octx, *(kg->osl->surface_state[shader]), *globals);
+ }
}
/* flatten closure tree */
if (globals->Ci) {
- flatten_closure_tree(kg, sd, path_flag, globals->Ci);
+ flatten_closure_tree(kg, sd, path_flag, reinterpret_cast<OSLClosure *>(globals->Ci));
}
}
-/* Background */
+/* Volume */
-void OSLShader::eval_background(const KernelGlobalsCPU *kg,
- const void *state,
- ShaderData *sd,
- uint32_t path_flag)
+template<>
+void osl_eval_nodes<SHADER_TYPE_VOLUME>(const KernelGlobalsCPU *kg,
+ const void *state,
+ ShaderData *sd,
+ uint32_t path_flag)
{
/* setup shader globals from shader data */
OSLThreadData *tdata = kg->osl_tdata;
- shaderdata_to_shaderglobals(kg, sd, state, path_flag, tdata);
+ shaderdata_to_shaderglobals(
+ kg, sd, path_flag, reinterpret_cast<ShaderGlobals *>(&tdata->globals));
- /* execute shader for this point */
- OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
- OSL::ShaderGlobals *globals = &tdata->globals;
- OSL::ShadingContext *octx = tdata->context;
+ /* clear trace data */
+ tdata->tracedata.init = false;
- if (kg->osl->background_state) {
- ss->execute(octx, *(kg->osl->background_state), *globals);
+ /* Used by render-services. */
+ sd->osl_globals = kg;
+ if (path_flag & PATH_RAY_SHADOW) {
+ sd->osl_path_state = nullptr;
+ sd->osl_shadow_path_state = (const IntegratorShadowStateCPU *)state;
}
-
- /* return background color immediately */
- if (globals->Ci) {
- flatten_closure_tree(kg, sd, path_flag, globals->Ci);
+ else {
+ sd->osl_path_state = (const IntegratorStateCPU *)state;
+ sd->osl_shadow_path_state = nullptr;
}
-}
-
-/* Volume */
-
-void OSLShader::eval_volume(const KernelGlobalsCPU *kg,
- const void *state,
- ShaderData *sd,
- uint32_t path_flag)
-{
- /* setup shader globals from shader data */
- OSLThreadData *tdata = kg->osl_tdata;
- shaderdata_to_shaderglobals(kg, sd, state, path_flag, tdata);
/* execute shader */
OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
@@ -283,17 +204,30 @@ void OSLShader::eval_volume(const KernelGlobalsCPU *kg,
/* flatten closure tree */
if (globals->Ci) {
- flatten_closure_tree(kg, sd, path_flag, globals->Ci);
+ flatten_closure_tree(kg, sd, path_flag, reinterpret_cast<OSLClosure *>(globals->Ci));
}
}
/* Displacement */
-void OSLShader::eval_displacement(const KernelGlobalsCPU *kg, const void *state, ShaderData *sd)
+template<>
+void osl_eval_nodes<SHADER_TYPE_DISPLACEMENT>(const KernelGlobalsCPU *kg,
+ const void *state,
+ ShaderData *sd,
+ uint32_t path_flag)
{
/* setup shader globals from shader data */
OSLThreadData *tdata = kg->osl_tdata;
- shaderdata_to_shaderglobals(kg, sd, state, 0, tdata);
+ shaderdata_to_shaderglobals(
+ kg, sd, path_flag, reinterpret_cast<ShaderGlobals *>(&tdata->globals));
+
+ /* clear trace data */
+ tdata->tracedata.init = false;
+
+ /* Used by render-services. */
+ sd->osl_globals = kg;
+ sd->osl_path_state = (const IntegratorStateCPU *)state;
+ sd->osl_shadow_path_state = nullptr;
/* execute shader */
OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
diff --git a/intern/cycles/kernel/osl/closures_setup.h b/intern/cycles/kernel/osl/closures_setup.h
index f8d68444f90..ceaf56ccba6 100644
--- a/intern/cycles/kernel/osl/closures_setup.h
+++ b/intern/cycles/kernel/osl/closures_setup.h
@@ -40,12 +40,7 @@ CCL_NAMESPACE_BEGIN
const char *label;
#define OSL_CLOSURE_STRUCT_END(Upper, lower) \
} \
- ; \
- ccl_device void osl_closure_##lower##_setup(KernelGlobals kg, \
- ccl_private ShaderData *sd, \
- uint32_t path_flag, \
- float3 weight, \
- ccl_private Upper##Closure *closure);
+ ;
#define OSL_CLOSURE_STRUCT_MEMBER(Upper, TYPE, type, name, key) type name;
#define OSL_CLOSURE_STRUCT_ARRAY_MEMBER(Upper, TYPE, type, name, key, size) type name[size];
@@ -210,11 +205,9 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg,
bsdf->ior = closure->ior;
bsdf->T = closure->T;
- static OSL::ustring u_ggx("ggx");
- static OSL::ustring u_default("default");
-
/* GGX */
- if (closure->distribution == u_ggx || closure->distribution == u_default) {
+ if (closure->distribution == make_string("ggx", 11253504724482777663ull) ||
+ closure->distribution == make_string("default", 4430693559278735917ull)) {
if (!closure->refract) {
if (closure->alpha_x == closure->alpha_y) {
/* Isotropic */
@@ -428,7 +421,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_setup(
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = bsdf->alpha_x;
- bsdf->ior = 0.0f;
+ bsdf->ior = 1.0f;
bsdf->extra = extra;
bsdf->extra->color = rgb_to_spectrum(closure->color);
@@ -510,7 +503,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup(
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
- bsdf->ior = 0.0f;
+ bsdf->ior = 1.0f;
bsdf->extra = extra;
bsdf->extra->color = rgb_to_spectrum(closure->color);
@@ -1000,18 +993,14 @@ ccl_device void osl_closure_bssrdf_setup(KernelGlobals kg,
float3 weight,
ccl_private const BSSRDFClosure *closure)
{
- static ustring u_burley("burley");
- static ustring u_random_walk_fixed_radius("random_walk_fixed_radius");
- static ustring u_random_walk("random_walk");
-
ClosureType type;
- if (closure->method == u_burley) {
+ if (closure->method == make_string("burley", 186330084368958868ull)) {
type = CLOSURE_BSSRDF_BURLEY_ID;
}
- else if (closure->method == u_random_walk_fixed_radius) {
+ else if (closure->method == make_string("random_walk_fixed_radius", 5695810351010063150ull)) {
type = CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID;
}
- else if (closure->method == u_random_walk) {
+ else if (closure->method == make_string("random_walk", 11360609267673527222ull)) {
type = CLOSURE_BSSRDF_RANDOM_WALK_ID;
}
else {
diff --git a/intern/cycles/kernel/osl/closures_template.h b/intern/cycles/kernel/osl/closures_template.h
index c808b275966..b9e9b52dcf8 100644
--- a/intern/cycles/kernel/osl/closures_template.h
+++ b/intern/cycles/kernel/osl/closures_template.h
@@ -40,7 +40,7 @@ OSL_CLOSURE_STRUCT_BEGIN(Transparent, transparent)
OSL_CLOSURE_STRUCT_END(Transparent, transparent)
OSL_CLOSURE_STRUCT_BEGIN(Microfacet, microfacet)
- OSL_CLOSURE_STRUCT_MEMBER(Microfacet, STRING, ustring, distribution, NULL)
+ OSL_CLOSURE_STRUCT_MEMBER(Microfacet, STRING, DeviceString, distribution, NULL)
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, VECTOR, packed_float3, T, NULL)
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, FLOAT, float, alpha_x, NULL)
@@ -210,7 +210,7 @@ OSL_CLOSURE_STRUCT_BEGIN(PhongRamp, phong_ramp)
OSL_CLOSURE_STRUCT_END(PhongRamp, phong_ramp)
OSL_CLOSURE_STRUCT_BEGIN(BSSRDF, bssrdf)
- OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, STRING, ustring, method, NULL)
+ OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, STRING, DeviceString, method, NULL)
OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, VECTOR, packed_float3, radius, NULL)
OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, VECTOR, packed_float3, albedo, NULL)
diff --git a/intern/cycles/kernel/osl/osl.h b/intern/cycles/kernel/osl/osl.h
index bef23f3eea1..cc5c81ad027 100644
--- a/intern/cycles/kernel/osl/osl.h
+++ b/intern/cycles/kernel/osl/osl.h
@@ -1,38 +1,171 @@
-/* SPDX-License-Identifier: Apache-2.0
- * Copyright 2011-2022 Blender Foundation */
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Adapted from Open Shading Language
+ * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
+ * All Rights Reserved.
+ *
+ * Modifications Copyright 2011-2022 Blender Foundation. */
#pragma once
/* OSL Shader Engine
*
- * Holds all variables to execute and use OSL shaders from the kernel. These
- * are initialized externally by OSLShaderManager before rendering starts.
- *
- * Before/after a thread starts rendering, thread_init/thread_free must be
- * called, which will store any per thread OSL state in thread local storage.
- * This means no thread state must be passed along in the kernel itself.
+ * Holds all variables to execute and use OSL shaders from the kernel.
*/
#include "kernel/osl/types.h"
+#include "kernel/osl/closures_setup.h"
+
CCL_NAMESPACE_BEGIN
-class OSLShader {
- public:
- /* eval */
- static void eval_surface(const KernelGlobalsCPU *kg,
- const void *state,
- ShaderData *sd,
- uint32_t path_flag);
- static void eval_background(const KernelGlobalsCPU *kg,
- const void *state,
- ShaderData *sd,
- uint32_t path_flag);
- static void eval_volume(const KernelGlobalsCPU *kg,
- const void *state,
- ShaderData *sd,
- uint32_t path_flag);
- static void eval_displacement(const KernelGlobalsCPU *kg, const void *state, ShaderData *sd);
-};
+ccl_device_inline void shaderdata_to_shaderglobals(KernelGlobals kg,
+ ccl_private ShaderData *sd,
+ uint32_t path_flag,
+ ccl_private ShaderGlobals *globals)
+{
+ const differential3 dP = differential_from_compact(sd->Ng, sd->dP);
+ const differential3 dI = differential_from_compact(sd->I, sd->dI);
+
+ /* copy from shader data to shader globals */
+ globals->P = sd->P;
+ globals->dPdx = dP.dx;
+ globals->dPdy = dP.dy;
+ globals->I = sd->I;
+ globals->dIdx = dI.dx;
+ globals->dIdy = dI.dy;
+ globals->N = sd->N;
+ globals->Ng = sd->Ng;
+ globals->u = sd->u;
+ globals->dudx = sd->du.dx;
+ globals->dudy = sd->du.dy;
+ globals->v = sd->v;
+ globals->dvdx = sd->dv.dx;
+ globals->dvdy = sd->dv.dy;
+ globals->dPdu = sd->dPdu;
+ globals->dPdv = sd->dPdv;
+ globals->time = sd->time;
+ globals->dtime = 1.0f;
+ globals->surfacearea = 1.0f;
+ globals->raytype = path_flag;
+ globals->flipHandedness = 0;
+ globals->backfacing = (sd->flag & SD_BACKFACING);
+
+ /* shader data to be used in services callbacks */
+ globals->renderstate = sd;
+
+ /* hacky, we leave it to services to fetch actual object matrix */
+ globals->shader2common = sd;
+ globals->object2common = sd;
+
+ /* must be set to NULL before execute */
+ globals->Ci = nullptr;
+}
+
+ccl_device void flatten_closure_tree(KernelGlobals kg,
+ ccl_private ShaderData *sd,
+ uint32_t path_flag,
+ ccl_private const OSLClosure *closure)
+{
+ int stack_size = 0;
+ float3 weight = one_float3();
+ float3 weight_stack[16];
+ ccl_private const OSLClosure *closure_stack[16];
+
+ while (closure) {
+ switch (closure->id) {
+ case OSL_CLOSURE_MUL_ID: {
+ ccl_private const OSLClosureMul *mul = static_cast<ccl_private const OSLClosureMul *>(
+ closure);
+ weight *= mul->weight;
+ closure = mul->closure;
+ continue;
+ }
+ case OSL_CLOSURE_ADD_ID: {
+ if (stack_size >= 16) {
+ kernel_assert(!"Exhausted OSL closure stack");
+ break;
+ }
+ ccl_private const OSLClosureAdd *add = static_cast<ccl_private const OSLClosureAdd *>(
+ closure);
+ closure = add->closureA;
+ weight_stack[stack_size] = weight;
+ closure_stack[stack_size++] = add->closureB;
+ continue;
+ }
+#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \
+ case OSL_CLOSURE_##Upper##_ID: { \
+ ccl_private const OSLClosureComponent *comp = \
+ static_cast<ccl_private const OSLClosureComponent *>(closure); \
+ osl_closure_##lower##_setup(kg, \
+ sd, \
+ path_flag, \
+ weight * comp->weight, \
+ reinterpret_cast<ccl_private const Upper##Closure *>(comp + 1)); \
+ break; \
+ }
+#include "closures_template.h"
+ default:
+ break;
+ }
+
+ if (stack_size > 0) {
+ weight = weight_stack[--stack_size];
+ closure = closure_stack[stack_size];
+ }
+ else {
+ closure = nullptr;
+ }
+ }
+}
+
+#ifndef __KERNEL_GPU__
+
+template<ShaderType type>
+void osl_eval_nodes(const KernelGlobalsCPU *kg,
+ const void *state,
+ ShaderData *sd,
+ uint32_t path_flag);
+
+#else
+
+template<ShaderType type, typename ConstIntegratorGenericState>
+ccl_device_inline void osl_eval_nodes(KernelGlobals kg,
+ ConstIntegratorGenericState state,
+ ccl_private ShaderData *sd,
+ uint32_t path_flag)
+{
+ ShaderGlobals globals;
+ shaderdata_to_shaderglobals(kg, sd, path_flag, &globals);
+
+ const int shader = sd->shader & SHADER_MASK;
+
+# ifdef __KERNEL_OPTIX__
+ uint8_t group_data[2048];
+ uint8_t closure_pool[1024];
+ sd->osl_closure_pool = closure_pool;
+
+ unsigned int optix_dc_index = 2 /* NUM_CALLABLE_PROGRAM_GROUPS */ +
+ (shader + type * kernel_data.max_shaders) * 2;
+ optixDirectCall<void>(optix_dc_index + 0,
+ /* shaderglobals_ptr = */ &globals,
+ /* groupdata_ptr = */ (void *)group_data,
+ /* userdata_base_ptr = */ (void *)nullptr,
+ /* output_base_ptr = */ (void *)nullptr,
+ /* shadeindex = */ 0);
+ optixDirectCall<void>(optix_dc_index + 1,
+ /* shaderglobals_ptr = */ &globals,
+ /* groupdata_ptr = */ (void *)group_data,
+ /* userdata_base_ptr = */ (void *)nullptr,
+ /* output_base_ptr = */ (void *)nullptr,
+ /* shadeindex = */ 0);
+# endif
+
+ if (globals.Ci) {
+ flatten_closure_tree(kg, sd, path_flag, globals.Ci);
+ }
+}
+
+#endif
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/services.cpp b/intern/cycles/kernel/osl/services.cpp
index b744422ee78..3fd098de4bb 100644
--- a/intern/cycles/kernel/osl/services.cpp
+++ b/intern/cycles/kernel/osl/services.cpp
@@ -119,8 +119,8 @@ ustring OSLRenderServices::u_u("u");
ustring OSLRenderServices::u_v("v");
ustring OSLRenderServices::u_empty;
-OSLRenderServices::OSLRenderServices(OSL::TextureSystem *texture_system)
- : OSL::RendererServices(texture_system)
+OSLRenderServices::OSLRenderServices(OSL::TextureSystem *texture_system, int device_type)
+ : OSL::RendererServices(texture_system), device_type_(device_type)
{
}
@@ -131,6 +131,17 @@ OSLRenderServices::~OSLRenderServices()
}
}
+int OSLRenderServices::supports(string_view feature) const
+{
+#ifdef WITH_OPTIX
+ if (feature == "OptiX") {
+ return device_type_ == DEVICE_OPTIX;
+ }
+#endif
+
+ return false;
+}
+
bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
OSL::Matrix44 &result,
OSL::TransformationPtr xform,
@@ -1139,29 +1150,40 @@ TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(ustring file
{
OSLTextureHandleMap::iterator it = textures.find(filename);
- /* For non-OIIO textures, just return a pointer to our own OSLTextureHandle. */
- if (it != textures.end()) {
- if (it->second->type != OSLTextureHandle::OIIO) {
- return (TextureSystem::TextureHandle *)it->second.get();
+ if (device_type_ == DEVICE_CPU) {
+ /* For non-OIIO textures, just return a pointer to our own OSLTextureHandle. */
+ if (it != textures.end()) {
+ if (it->second->type != OSLTextureHandle::OIIO) {
+ return (TextureSystem::TextureHandle *)it->second.get();
+ }
}
- }
- /* Get handle from OpenImageIO. */
- OSL::TextureSystem *ts = m_texturesys;
- TextureSystem::TextureHandle *handle = ts->get_texture_handle(filename);
- if (handle == NULL) {
- return NULL;
- }
+ /* Get handle from OpenImageIO. */
+ OSL::TextureSystem *ts = m_texturesys;
+ TextureSystem::TextureHandle *handle = ts->get_texture_handle(filename);
+ if (handle == NULL) {
+ return NULL;
+ }
+
+ /* Insert new OSLTextureHandle if needed. */
+ if (it == textures.end()) {
+ textures.insert(filename, new OSLTextureHandle(OSLTextureHandle::OIIO));
+ it = textures.find(filename);
+ }
- /* Insert new OSLTextureHandle if needed. */
- if (it == textures.end()) {
- textures.insert(filename, new OSLTextureHandle(OSLTextureHandle::OIIO));
- it = textures.find(filename);
+ /* Assign OIIO texture handle and return. */
+ it->second->oiio_handle = handle;
+ return (TextureSystem::TextureHandle *)it->second.get();
}
+ else {
+ if (it != textures.end() && it->second->type == OSLTextureHandle::SVM &&
+ it->second->svm_slots[0].w == -1) {
+ return reinterpret_cast<TextureSystem::TextureHandle *>(
+ static_cast<uintptr_t>(it->second->svm_slots[0].y + 1));
+ }
- /* Assign OIIO texture handle and return. */
- it->second->oiio_handle = handle;
- return (TextureSystem::TextureHandle *)it->second.get();
+ return NULL;
+ }
}
bool OSLRenderServices::good(TextureSystem::TextureHandle *texture_handle)
diff --git a/intern/cycles/kernel/osl/services.h b/intern/cycles/kernel/osl/services.h
index 334b6682e34..9d875ae8e94 100644
--- a/intern/cycles/kernel/osl/services.h
+++ b/intern/cycles/kernel/osl/services.h
@@ -22,11 +22,8 @@ class PtexCache;
CCL_NAMESPACE_BEGIN
-class Object;
class Scene;
-class Shader;
struct ShaderData;
-struct float3;
struct KernelGlobalsCPU;
/* OSL Texture Handle
@@ -73,11 +70,13 @@ typedef OIIO::unordered_map_concurrent<ustring, OSLTextureHandleRef, ustringHash
class OSLRenderServices : public OSL::RendererServices {
public:
- OSLRenderServices(OSL::TextureSystem *texture_system);
+ OSLRenderServices(OSL::TextureSystem *texture_system, int device_type);
~OSLRenderServices();
static void register_closures(OSL::ShadingSystem *ss);
+ int supports(string_view feature) const override;
+
bool get_matrix(OSL::ShaderGlobals *sg,
OSL::Matrix44 &result,
OSL::TransformationPtr xform,
@@ -324,6 +323,9 @@ class OSLRenderServices : public OSL::RendererServices {
* and is required because texture handles are cached as part of the shared
* shading system. */
OSLTextureHandleMap textures;
+
+ private:
+ int device_type_;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/services_gpu.h b/intern/cycles/kernel/osl/services_gpu.h
new file mode 100644
index 00000000000..e6e19b8c484
--- /dev/null
+++ b/intern/cycles/kernel/osl/services_gpu.h
@@ -0,0 +1,2149 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Adapted from Open Shading Language
+ * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
+ * All Rights Reserved.
+ *
+ * Modifications Copyright 2011-2022 Blender Foundation. */
+
+#include "kernel/tables.h"
+#include "kernel/util/differential.h"
+
+#include "kernel/osl/osl.h"
+
+namespace DeviceStrings {
+
+/* "" */
+ccl_device_constant DeviceString _emptystring_ = {0ull};
+/* "NDC" */
+ccl_device_constant DeviceString u_ndc = {5148305047403260775ull};
+/* "screen" */
+ccl_device_constant DeviceString u_screen = {14159088609039777114ull};
+/* "camera" */
+ccl_device_constant DeviceString u_camera = {2159505832145726196ull};
+/* "raster" */
+ccl_device_constant DeviceString u_raster = {7759263238610201778ull};
+/* "world" */
+ccl_device_constant DeviceString u_world = {16436542438370751598ull};
+/* "common" */
+ccl_device_constant DeviceString u_common = {14645198576927606093ull};
+/* "hsv" */
+ccl_device_constant DeviceString u_hsv = {2177035556331879497ull};
+/* "hsl" */
+ccl_device_constant DeviceString u_hsl = {7749766809258288148ull};
+/* "XYZ" */
+ccl_device_constant DeviceString u_xyz = {4957977063494975483ull};
+/* "xyY" */
+ccl_device_constant DeviceString u_xyy = {5138822319725660255ull};
+/* "sRGB" */
+ccl_device_constant DeviceString u_srgb = {15368599878474175032ull};
+/* "object:location" */
+ccl_device_constant DeviceString u_object_location = {7846190347358762897ull};
+/* "object:color" */
+ccl_device_constant DeviceString u_object_color = {12695623857059169556ull};
+/* "object:alpha" */
+ccl_device_constant DeviceString u_object_alpha = {11165053919428293151ull};
+/* "object:index" */
+ccl_device_constant DeviceString u_object_index = {6588325838217472556ull};
+/* "geom:dupli_generated" */
+ccl_device_constant DeviceString u_geom_dupli_generated = {6715607178003388908ull};
+/* "geom:dupli_uv" */
+ccl_device_constant DeviceString u_geom_dupli_uv = {1294253317490155849ull};
+/* "material:index" */
+ccl_device_constant DeviceString u_material_index = {741770758159634623ull};
+/* "object:random" */
+ccl_device_constant DeviceString u_object_random = {15789063994977955884ull};
+/* "particle:index" */
+ccl_device_constant DeviceString u_particle_index = {9489711748229903784ull};
+/* "particle:random" */
+ccl_device_constant DeviceString u_particle_random = {17993722202766855761ull};
+/* "particle:age" */
+ccl_device_constant DeviceString u_particle_age = {7380730644710951109ull};
+/* "particle:lifetime" */
+ccl_device_constant DeviceString u_particle_lifetime = {16576828923156200061ull};
+/* "particle:location" */
+ccl_device_constant DeviceString u_particle_location = {10309536211423573010ull};
+/* "particle:rotation" */
+ccl_device_constant DeviceString u_particle_rotation = {17858543768041168459ull};
+/* "particle:size" */
+ccl_device_constant DeviceString u_particle_size = {16461524249715420389ull};
+/* "particle:velocity" */
+ccl_device_constant DeviceString u_particle_velocity = {13199101248768308863ull};
+/* "particle:angular_velocity" */
+ccl_device_constant DeviceString u_particle_angular_velocity = {16327930120486517910ull};
+/* "geom:numpolyvertices" */
+ccl_device_constant DeviceString u_geom_numpolyvertices = {382043551489988826ull};
+/* "geom:trianglevertices" */
+ccl_device_constant DeviceString u_geom_trianglevertices = {17839267571524187074ull};
+/* "geom:polyvertices" */
+ccl_device_constant DeviceString u_geom_polyvertices = {1345577201967881769ull};
+/* "geom:name" */
+ccl_device_constant DeviceString u_geom_name = {13606338128269760050ull};
+/* "geom:undisplaced" */
+ccl_device_constant DeviceString u_geom_undisplaced = {12431586303019276305ull};
+/* "geom:is_smooth" */
+ccl_device_constant DeviceString u_is_smooth = {857544214094480123ull};
+/* "geom:is_curve" */
+ccl_device_constant DeviceString u_is_curve = {129742495633653138ull};
+/* "geom:curve_thickness" */
+ccl_device_constant DeviceString u_curve_thickness = {10605802038397633852ull};
+/* "geom:curve_length" */
+ccl_device_constant DeviceString u_curve_length = {11423459517663715453ull};
+/* "geom:curve_tangent_normal" */
+ccl_device_constant DeviceString u_curve_tangent_normal = {12301397394034985633ull};
+/* "geom:curve_random" */
+ccl_device_constant DeviceString u_curve_random = {15293085049960492358ull};
+/* "geom:is_point" */
+ccl_device_constant DeviceString u_is_point = {2511357849436175953ull};
+/* "geom:point_radius" */
+ccl_device_constant DeviceString u_point_radius = {9956381140398668479ull};
+/* "geom:point_position" */
+ccl_device_constant DeviceString u_point_position = {15684484280742966916ull};
+/* "geom:point_random" */
+ccl_device_constant DeviceString u_point_random = {5632627207092325544ull};
+/* "geom:normal_map_normal" */
+ccl_device_constant DeviceString u_normal_map_normal = {10718948685686827073};
+/* "path:ray_length" */
+ccl_device_constant DeviceString u_path_ray_length = {16391985802412544524ull};
+/* "path:ray_depth" */
+ccl_device_constant DeviceString u_path_ray_depth = {16643933224879500399ull};
+/* "path:diffuse_depth" */
+ccl_device_constant DeviceString u_path_diffuse_depth = {13191651286699118408ull};
+/* "path:glossy_depth" */
+ccl_device_constant DeviceString u_path_glossy_depth = {15717768399057252940ull};
+/* "path:transparent_depth" */
+ccl_device_constant DeviceString u_path_transparent_depth = {7821650266475578543ull};
+/* "path:transmission_depth" */
+ccl_device_constant DeviceString u_path_transmission_depth = {15113408892323917624ull};
+
+} // namespace DeviceStrings
+
+/* Closure */
+
+ccl_device_extern ccl_private OSLClosure *osl_mul_closure_color(ccl_private ShaderGlobals *sg,
+ ccl_private OSLClosure *a,
+ ccl_private const float3 *weight)
+{
+ if (*weight == zero_float3() || !a) {
+ return nullptr;
+ }
+ else if (*weight == one_float3()) {
+ return a;
+ }
+
+ ccl_private ShaderData *const sd = static_cast<ccl_private ShaderData *>(sg->renderstate);
+
+ ccl_private uint8_t *closure_pool = sd->osl_closure_pool;
+ /* Align pointer to closure struct requirement */
+ closure_pool = reinterpret_cast<uint8_t *>(
+ (reinterpret_cast<size_t>(closure_pool) + alignof(OSLClosureMul) - 1) &
+ (-alignof(OSLClosureMul)));
+ sd->osl_closure_pool = closure_pool + sizeof(OSLClosureMul);
+
+ ccl_private OSLClosureMul *const closure = reinterpret_cast<ccl_private OSLClosureMul *>(
+ closure_pool);
+ closure->id = OSL_CLOSURE_MUL_ID;
+ closure->weight = *weight;
+ closure->closure = a;
+
+ return closure;
+}
+
+ccl_device_extern ccl_private OSLClosure *osl_mul_closure_float(ccl_private ShaderGlobals *sg,
+ ccl_private OSLClosure *a,
+ float weight)
+{
+ if (weight == 0.0f || !a) {
+ return nullptr;
+ }
+ else if (weight == 1.0f) {
+ return a;
+ }
+
+ ccl_private ShaderData *const sd = static_cast<ccl_private ShaderData *>(sg->renderstate);
+
+ uint8_t *closure_pool = sd->osl_closure_pool;
+ /* Align pointer to closure struct requirement */
+ closure_pool = reinterpret_cast<uint8_t *>(
+ (reinterpret_cast<size_t>(closure_pool) + alignof(OSLClosureMul) - 1) &
+ (-alignof(OSLClosureMul)));
+ sd->osl_closure_pool = closure_pool + sizeof(OSLClosureMul);
+
+ ccl_private OSLClosureMul *const closure = reinterpret_cast<ccl_private OSLClosureMul *>(
+ closure_pool);
+ closure->id = OSL_CLOSURE_MUL_ID;
+ closure->weight = make_float3(weight, weight, weight);
+ closure->closure = a;
+
+ return closure;
+}
+
+ccl_device_extern ccl_private OSLClosure *osl_add_closure_closure(ccl_private ShaderGlobals *sg,
+ ccl_private OSLClosure *a,
+ ccl_private OSLClosure *b)
+{
+ if (!a) {
+ return b;
+ }
+ if (!b) {
+ return a;
+ }
+
+ ccl_private ShaderData *const sd = static_cast<ccl_private ShaderData *>(sg->renderstate);
+
+ ccl_private uint8_t *closure_pool = sd->osl_closure_pool;
+ /* Align pointer to closure struct requirement */
+ closure_pool = reinterpret_cast<uint8_t *>(
+ (reinterpret_cast<size_t>(closure_pool) + alignof(OSLClosureAdd) - 1) &
+ (-alignof(OSLClosureAdd)));
+ sd->osl_closure_pool = closure_pool + sizeof(OSLClosureAdd);
+
+ ccl_private OSLClosureAdd *const closure = reinterpret_cast<ccl_private OSLClosureAdd *>(
+ closure_pool);
+ closure->id = OSL_CLOSURE_ADD_ID;
+ closure->closureA = a;
+ closure->closureB = b;
+
+ return closure;
+}
+
+ccl_device_extern ccl_private OSLClosure *osl_allocate_closure_component(
+ ccl_private ShaderGlobals *sg, int id, int size)
+{
+ ccl_private ShaderData *const sd = static_cast<ccl_private ShaderData *>(sg->renderstate);
+
+ ccl_private uint8_t *closure_pool = sd->osl_closure_pool;
+ /* Align pointer to closure struct requirement */
+ closure_pool = reinterpret_cast<uint8_t *>(
+ (reinterpret_cast<size_t>(closure_pool) + alignof(OSLClosureComponent) - 1) &
+ (-alignof(OSLClosureComponent)));
+ sd->osl_closure_pool = closure_pool + sizeof(OSLClosureComponent) + size;
+
+ ccl_private OSLClosureComponent *const closure =
+ reinterpret_cast<ccl_private OSLClosureComponent *>(closure_pool);
+ closure->id = static_cast<OSLClosureType>(id);
+ closure->weight = one_float3();
+
+ return closure;
+}
+
+ccl_device_extern ccl_private OSLClosure *osl_allocate_weighted_closure_component(
+ ccl_private ShaderGlobals *sg, int id, int size, ccl_private const float3 *weight)
+{
+ ccl_private ShaderData *const sd = static_cast<ccl_private ShaderData *>(sg->renderstate);
+
+ ccl_private uint8_t *closure_pool = sd->osl_closure_pool;
+ /* Align pointer to closure struct requirement */
+ closure_pool = reinterpret_cast<uint8_t *>(
+ (reinterpret_cast<size_t>(closure_pool) + alignof(OSLClosureComponent) - 1) &
+ (-alignof(OSLClosureComponent)));
+ sd->osl_closure_pool = closure_pool + sizeof(OSLClosureComponent) + size;
+
+ ccl_private OSLClosureComponent *const closure =
+ reinterpret_cast<ccl_private OSLClosureComponent *>(closure_pool);
+ closure->id = static_cast<OSLClosureType>(id);
+ closure->weight = *weight;
+
+ return closure;
+}
+
+/* Utilities */
+
+#include "kernel/svm/math_util.h"
+#include "kernel/util/color.h"
+
+ccl_device_extern void osl_error(ccl_private ShaderGlobals *sg, const char *format, void *args)
+{
+}
+
+ccl_device_extern void osl_printf(ccl_private ShaderGlobals *sg, const char *format, void *args)
+{
+}
+
+ccl_device_extern void osl_warning(ccl_private ShaderGlobals *sg, const char *format, void *args)
+{
+}
+
+ccl_device_extern uint osl_range_check(int indexvalue,
+ int length,
+ DeviceString symname,
+ ccl_private ShaderGlobals *sg,
+ DeviceString sourcefile,
+ int sourceline,
+ DeviceString groupname,
+ int layer,
+ DeviceString layername,
+ DeviceString shadername)
+{
+ const int result = indexvalue < 0 ? 0 : indexvalue >= length ? length - 1 : indexvalue;
+#if 0
+ if (result != indexvalue) {
+ printf("Index [%d] out of range\n", indexvalue);
+ }
+#endif
+ return result;
+}
+
+ccl_device_extern uint osl_range_check_err(int indexvalue,
+ int length,
+ DeviceString symname,
+ ccl_private ShaderGlobals *sg,
+ DeviceString sourcefile,
+ int sourceline,
+ DeviceString groupname,
+ int layer,
+ DeviceString layername,
+ DeviceString shadername)
+{
+ return osl_range_check(indexvalue,
+ length,
+ symname,
+ sg,
+ sourcefile,
+ sourceline,
+ groupname,
+ layer,
+ layername,
+ shadername);
+}
+
+/* Color Utilities */
+
+ccl_device_extern void osl_blackbody_vf(ccl_private ShaderGlobals *sg,
+ ccl_private float3 *result,
+ float temperature)
+{
+ float3 color_rgb = rec709_to_rgb(nullptr, svm_math_blackbody_color_rec709(temperature));
+ color_rgb = max(color_rgb, zero_float3());
+ *result = color_rgb;
+}
+
+#if 0
+ccl_device_extern void osl_wavelength_color_vf(ccl_private ShaderGlobals *sg,
+ ccl_private float3 *result,
+ float wavelength)
+{
+}
+#endif
+
+ccl_device_extern void osl_luminance_fv(ccl_private ShaderGlobals *sg,
+ ccl_private float *result,
+ ccl_private float3 *color)
+{
+ *result = linear_rgb_to_gray(nullptr, *color);
+}
+
+ccl_device_extern void osl_luminance_dfdv(ccl_private ShaderGlobals *sg,
+ ccl_private float *result,
+ ccl_private float3 *color)
+{
+ for (int i = 0; i < 3; ++i) {
+ osl_luminance_fv(sg, result + i, color + i);
+ }
+}
+
+ccl_device_extern void osl_prepend_color_from(ccl_private ShaderGlobals *sg,
+ ccl_private float3 *res,
+ DeviceString from)
+{
+ if (from == DeviceStrings::u_hsv) {
+ *res = hsv_to_rgb(*res);
+ }
+ else if (from == DeviceStrings::u_hsl) {
+ *res = hsl_to_rgb(*res);
+ }
+ else if (from == DeviceStrings::u_xyz) {
+ *res = xyz_to_rgb(nullptr, *res);
+ }
+ else if (from == DeviceStrings::u_xyy) {
+ *res = xyz_to_rgb(nullptr, xyY_to_xyz(res->x, res->y, res->z));
+ }
+}
+
+ccl_device_extern bool osl_transformc(ccl_private ShaderGlobals *sg,
+ ccl_private float3 *c_in,
+ int c_in_derivs,
+ ccl_private float3 *c_out,
+ int c_out_derivs,
+ DeviceString from,
+ DeviceString to)
+{
+ if (!c_out_derivs) {
+ c_in_derivs = false;
+ }
+ else if (!c_in_derivs) {
+ c_out[1] = zero_float3();
+ c_out[2] = zero_float3();
+ }
+
+ float3 rgb;
+
+ for (int i = 0; i < (c_in_derivs ? 3 : 1); ++i) {
+ if (from == DeviceStrings::u_hsv) {
+ rgb = hsv_to_rgb(c_in[i]);
+ }
+ else if (from == DeviceStrings::u_hsl) {
+ rgb = hsl_to_rgb(c_in[i]);
+ }
+ else if (from == DeviceStrings::u_xyz) {
+ rgb = xyz_to_rgb(nullptr, c_in[i]);
+ }
+ else if (from == DeviceStrings::u_xyy) {
+ rgb = xyz_to_rgb(nullptr, xyY_to_xyz(c_in[i].x, c_in[i].y, c_in[i].z));
+ }
+ else if (from == DeviceStrings::u_srgb) {
+ rgb = color_srgb_to_linear_v3(c_in[i]);
+ }
+ else {
+ rgb = c_in[i];
+ }
+
+ if (to == DeviceStrings::u_hsv) {
+ c_out[i] = rgb_to_hsv(rgb);
+ }
+ else if (to == DeviceStrings::u_hsl) {
+ c_out[i] = rgb_to_hsl(rgb);
+ }
+#if 0
+ else if (to == DeviceStrings::u_xyz) {
+ c_out[i] = rgb_to_xyz(nullptr, rgb);
+ }
+ else if (to == DeviceStrings::u_xyy) {
+ c_out[i] = xyz_to_xyY(rgb_to_xyz(nullptr, rgb));
+ }
+#endif
+ else if (to == DeviceStrings::u_srgb) {
+ c_out[i] = color_linear_to_srgb_v3(rgb);
+ }
+ else {
+ c_out[i] = rgb;
+ }
+ }
+}
+
+/* Matrix Utilities */
+
+#include "util/transform.h"
+
+ccl_device_forceinline void copy_matrix(ccl_private float *res, const Transform &tfm)
+{
+ res[0] = tfm.x.x;
+ res[1] = tfm.y.x;
+ res[2] = tfm.z.x;
+ res[3] = 0.0f;
+ res[4] = tfm.x.y;
+ res[5] = tfm.y.y;
+ res[6] = tfm.z.y;
+ res[7] = 0.0f;
+ res[8] = tfm.x.z;
+ res[9] = tfm.y.z;
+ res[10] = tfm.z.z;
+ res[11] = 0.0f;
+ res[12] = tfm.x.w;
+ res[13] = tfm.y.w;
+ res[14] = tfm.z.w;
+ res[15] = 1.0f;
+}
+ccl_device_forceinline void copy_matrix(ccl_private float *res, const ProjectionTransform &tfm)
+{
+ res[0] = tfm.x.x;
+ res[1] = tfm.y.x;
+ res[2] = tfm.z.x;
+ res[3] = tfm.w.x;
+ res[4] = tfm.x.y;
+ res[5] = tfm.y.y;
+ res[6] = tfm.z.y;
+ res[7] = tfm.w.y;
+ res[8] = tfm.x.z;
+ res[9] = tfm.y.z;
+ res[10] = tfm.z.z;
+ res[11] = tfm.w.z;
+ res[12] = tfm.x.w;
+ res[13] = tfm.y.w;
+ res[14] = tfm.z.w;
+ res[15] = tfm.w.w;
+}
+ccl_device_forceinline void copy_identity_matrix(ccl_private float *res)
+{
+ res[0] = 1.0f;
+ res[1] = 0.0f;
+ res[2] = 0.0f;
+ res[3] = 0.0f;
+ res[4] = 0.0f;
+ res[5] = 1.0f;
+ res[6] = 0.0f;
+ res[7] = 0.0f;
+ res[8] = 0.0f;
+ res[9] = 0.0f;
+ res[10] = 1.0f;
+ res[11] = 0.0f;
+ res[12] = 0.0f;
+ res[13] = 0.0f;
+ res[14] = 0.0f;
+ res[15] = 1.0f;
+}
+ccl_device_forceinline Transform convert_transform(ccl_private const float *m)
+{
+ return make_transform(
+ m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13], m[2], m[6], m[10], m[14]);
+}
+
+ccl_device_extern void osl_mul_mmm(ccl_private float *res,
+ ccl_private const float *a,
+ ccl_private const float *b)
+{
+ const Transform tfm_a = convert_transform(a);
+ const Transform tfm_b = convert_transform(b);
+ copy_matrix(res, tfm_a * tfm_b);
+}
+
+ccl_device_extern void osl_mul_mmf(ccl_private float *res, ccl_private const float *a, float b)
+{
+ for (int i = 0; i < 16; ++i) {
+ res[i] = a[i] * b;
+ }
+}
+
+ccl_device_extern void osl_div_mmm(ccl_private float *res,
+ ccl_private const float *a,
+ ccl_private const float *b)
+{
+ const Transform tfm_a = convert_transform(a);
+ const Transform tfm_b = convert_transform(b);
+ copy_matrix(res, tfm_a * transform_inverse(tfm_b));
+}
+
+ccl_device_extern void osl_div_mmf(ccl_private float *res, ccl_private const float *a, float b)
+{
+ for (int i = 0; i < 16; ++i) {
+ res[i] = a[i] / b;
+ }
+}
+
+ccl_device_extern void osl_div_mfm(ccl_private float *res, float a, ccl_private const float *b)
+{
+ const Transform tfm_b = convert_transform(b);
+ copy_matrix(res, transform_inverse(tfm_b));
+ for (int i = 0; i < 16; ++i) {
+ res[i] *= a;
+ }
+}
+
+ccl_device_extern void osl_div_m_ff(ccl_private float *res, float a, float b)
+{
+ float f = (b == 0) ? 0.0f : (a / b);
+ res[0] = f;
+ res[1] = 0.0f;
+ res[2] = 0.0f;
+ res[3] = 0.0f;
+ res[4] = 0.0f;
+ res[5] = f;
+ res[6] = 0.0f;
+ res[7] = 0.0f;
+ res[8] = 0.0f;
+ res[9] = 0.0f;
+ res[10] = f;
+ res[11] = 0.0f;
+ res[12] = 0.0f;
+ res[13] = 0.0f;
+ res[14] = 0.0f;
+ res[15] = f;
+}
+
+ccl_device_extern void osl_transform_vmv(ccl_private float3 *res,
+ ccl_private const float *m,
+ ccl_private const float3 *v)
+{
+ const Transform tfm_m = convert_transform(m);
+ *res = transform_point(&tfm_m, *v);
+}
+
+ccl_device_extern void osl_transform_dvmdv(ccl_private float3 *res,
+ ccl_private const float *m,
+ ccl_private const float3 *v)
+{
+ for (int i = 0; i < 3; ++i) {
+ const Transform tfm_m = convert_transform(m + i * 16);
+ res[i] = transform_point(&tfm_m, v[i]);
+ }
+}
+
+ccl_device_extern void osl_transformv_vmv(ccl_private float3 *res,
+ ccl_private const float *m,
+ ccl_private const float3 *v)
+{
+ const Transform tfm_m = convert_transform(m);
+ *res = transform_direction(&tfm_m, *v);
+}
+
+ccl_device_extern void osl_transformv_dvmdv(ccl_private float3 *res,
+ ccl_private const float *m,
+ ccl_private const float3 *v)
+{
+ for (int i = 0; i < 3; ++i) {
+ const Transform tfm_m = convert_transform(m + i * 16);
+ res[i] = transform_direction(&tfm_m, v[i]);
+ }
+}
+
+ccl_device_extern void osl_transformn_vmv(ccl_private float3 *res,
+ ccl_private const float *m,
+ ccl_private const float3 *v)
+{
+ const Transform tfm_m = convert_transform(m);
+ *res = transform_direction(&tfm_m, *v);
+}
+
+ccl_device_extern void osl_transformn_dvmdv(ccl_private float3 *res,
+ ccl_private const float *m,
+ ccl_private const float3 *v)
+{
+ for (int i = 0; i < 3; ++i) {
+ const Transform tfm_m = convert_transform(m + i * 16);
+ res[i] = transform_direction(&tfm_m, v[i]);
+ }
+}
+
+ccl_device_extern bool osl_get_matrix(ccl_private ShaderGlobals *sg,
+ ccl_private float *result,
+ DeviceString from)
+{
+ if (from == DeviceStrings::u_ndc) {
+ copy_matrix(result, kernel_data.cam.ndctoworld);
+ return true;
+ }
+ if (from == DeviceStrings::u_raster) {
+ copy_matrix(result, kernel_data.cam.rastertoworld);
+ return true;
+ }
+ if (from == DeviceStrings::u_screen) {
+ copy_matrix(result, kernel_data.cam.screentoworld);
+ return true;
+ }
+ if (from == DeviceStrings::u_camera) {
+ copy_matrix(result, kernel_data.cam.cameratoworld);
+ return true;
+ }
+ if (from == DeviceStrings::u_world) {
+ copy_identity_matrix(result);
+ return true;
+ }
+
+ return false;
+}
+
+ccl_device_extern bool osl_get_inverse_matrix(ccl_private ShaderGlobals *sg,
+ ccl_private float *res,
+ DeviceString to)
+{
+ if (to == DeviceStrings::u_ndc) {
+ copy_matrix(res, kernel_data.cam.worldtondc);
+ return true;
+ }
+ if (to == DeviceStrings::u_raster) {
+ copy_matrix(res, kernel_data.cam.worldtoraster);
+ return true;
+ }
+ if (to == DeviceStrings::u_screen) {
+ copy_matrix(res, kernel_data.cam.worldtoscreen);
+ return true;
+ }
+ if (to == DeviceStrings::u_camera) {
+ copy_matrix(res, kernel_data.cam.worldtocamera);
+ return true;
+ }
+ if (to == DeviceStrings::u_world) {
+ copy_identity_matrix(res);
+ return true;
+ }
+
+ return false;
+}
+
+ccl_device_extern bool osl_get_from_to_matrix(ccl_private ShaderGlobals *sg,
+ ccl_private float *res,
+ DeviceString from,
+ DeviceString to)
+{
+ float m_from[16], m_to[16];
+ if (osl_get_matrix(sg, m_from, from) && osl_get_inverse_matrix(sg, m_to, to)) {
+ osl_mul_mmm(res, m_from, m_to);
+ return true;
+ }
+
+ return false;
+}
+
+ccl_device_extern void osl_prepend_matrix_from(ccl_private ShaderGlobals *sg,
+ ccl_private float *res,
+ DeviceString from)
+{
+ float m[16];
+ if (osl_get_matrix(sg, m, from)) {
+ osl_mul_mmm(res, m, res);
+ }
+}
+
+ccl_device_extern bool osl_transform_triple(ccl_private ShaderGlobals *sg,
+ ccl_private float3 *p_in,
+ int p_in_derivs,
+ ccl_private float3 *p_out,
+ int p_out_derivs,
+ DeviceString from,
+ DeviceString to,
+ int vectype)
+{
+ if (!p_out_derivs) {
+ p_in_derivs = false;
+ }
+ else if (!p_in_derivs) {
+ p_out[1] = zero_float3();
+ p_out[2] = zero_float3();
+ }
+
+ bool res;
+ float m[16];
+
+ if (from == DeviceStrings::u_common) {
+ res = osl_get_inverse_matrix(sg, m, to);
+ }
+ else if (to == DeviceStrings::u_common) {
+ res = osl_get_matrix(sg, m, from);
+ }
+ else {
+ res = osl_get_from_to_matrix(sg, m, from, to);
+ }
+
+ if (res) {
+ if (vectype == 2 /* TypeDesc::POINT */) {
+ if (p_in_derivs)
+ osl_transform_dvmdv(p_out, m, p_in);
+ else
+ osl_transform_vmv(p_out, m, p_in);
+ }
+ else if (vectype == 3 /* TypeDesc::VECTOR */) {
+ if (p_in_derivs)
+ osl_transformv_dvmdv(p_out, m, p_in);
+ else
+ osl_transformv_vmv(p_out, m, p_in);
+ }
+ else if (vectype == 4 /* TypeDesc::NORMAL */) {
+ if (p_in_derivs)
+ osl_transformn_dvmdv(p_out, m, p_in);
+ else
+ osl_transformn_vmv(p_out, m, p_in);
+ }
+ else {
+ res = false;
+ }
+ }
+ else {
+ p_out[0] = p_in[0];
+ if (p_in_derivs) {
+ p_out[1] = p_in[1];
+ p_out[2] = p_in[2];
+ }
+ }
+
+ return res;
+}
+
+ccl_device_extern bool osl_transform_triple_nonlinear(ccl_private ShaderGlobals *sg,
+ ccl_private float3 *p_in,
+ int p_in_derivs,
+ ccl_private float3 *p_out,
+ int p_out_derivs,
+ DeviceString from,
+ DeviceString to,
+ int vectype)
+{
+ return osl_transform_triple(sg, p_in, p_in_derivs, p_out, p_out_derivs, from, to, vectype);
+}
+
+ccl_device_extern void osl_transpose_mm(ccl_private float *res, ccl_private const float *m)
+{
+ copy_matrix(res, *reinterpret_cast<ccl_private const ProjectionTransform *>(m));
+}
+
+#if 0
+ccl_device_extern float osl_determinant_fm(ccl_private const float *m)
+{
+}
+#endif
+
+/* Attributes */
+
+#include "kernel/geom/geom.h"
+
+typedef long long TypeDesc;
+
+ccl_device_inline bool set_attribute_float(ccl_private float fval[3],
+ TypeDesc type,
+ bool derivatives,
+ ccl_private void *val)
+{
+ const unsigned char type_basetype = type & 0xF;
+ const unsigned char type_aggregate = (type >> 8) & 0xF;
+ const int type_arraylen = type >> 32;
+
+ if (type_basetype == 11 /* TypeDesc::FLOAT */) {
+ if ((type_aggregate == 2 /* TypeDesc::VEC2 */) ||
+ (type_aggregate == 1 && type_arraylen == 2)) {
+ for (int i = 0; i < (derivatives ? 3 : 1); ++i) {
+ static_cast<ccl_private float *>(val)[i * 2 + 0] = fval[i];
+ static_cast<ccl_private float *>(val)[i * 2 + 1] = fval[i];
+ }
+ return true;
+ }
+ if ((type_aggregate == 3 /* TypeDesc::VEC3 */) ||
+ (type_aggregate == 1 && type_arraylen == 3)) {
+ for (int i = 0; i < (derivatives ? 3 : 1); ++i) {
+ static_cast<ccl_private float *>(val)[i * 3 + 0] = fval[i];
+ static_cast<ccl_private float *>(val)[i * 3 + 1] = fval[i];
+ static_cast<ccl_private float *>(val)[i * 3 + 2] = fval[i];
+ }
+ return true;
+ }
+ if ((type_aggregate == 4 /* TypeDesc::VEC4 */) ||
+ (type_aggregate == 1 && type_arraylen == 4)) {
+ for (int i = 0; i < (derivatives ? 3 : 1); ++i) {
+ static_cast<ccl_private float *>(val)[i * 4 + 0] = fval[i];
+ static_cast<ccl_private float *>(val)[i * 4 + 1] = fval[i];
+ static_cast<ccl_private float *>(val)[i * 4 + 2] = fval[i];
+ static_cast<ccl_private float *>(val)[i * 4 + 3] = 1.0f;
+ }
+ return true;
+ }
+ if ((type_aggregate == 1 /* TypeDesc::SCALAR */)) {
+ for (int i = 0; i < (derivatives ? 3 : 1); ++i) {
+ static_cast<ccl_private float *>(val)[i] = fval[i];
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+ccl_device_inline bool set_attribute_float(float f,
+ TypeDesc type,
+ bool derivatives,
+ ccl_private void *val)
+{
+ float fv[3];
+
+ fv[0] = f;
+ fv[1] = 0.0f;
+ fv[2] = 0.0f;
+
+ return set_attribute_float(fv, type, derivatives, val);
+}
+ccl_device_inline bool set_attribute_float2(ccl_private float2 fval[3],
+ TypeDesc type,
+ bool derivatives,
+ ccl_private void *val)
+{
+ const unsigned char type_basetype = type & 0xF;
+ const unsigned char type_aggregate = (type >> 8) & 0xF;
+ const int type_arraylen = type >> 32;
+
+ if (type_basetype == 11 /* TypeDesc::FLOAT */) {
+ if ((type_aggregate == 2 /* TypeDesc::VEC2 */) ||
+ (type_aggregate == 1 && type_arraylen == 2)) {
+ for (int i = 0; i < (derivatives ? 3 : 1); ++i) {
+ static_cast<ccl_private float *>(val)[i * 2 + 0] = fval[i].x;
+ static_cast<ccl_private float *>(val)[i * 2 + 1] = fval[i].y;
+ }
+ return true;
+ }
+ if ((type_aggregate == 3 /* TypeDesc::VEC3 */) ||
+ (type_aggregate == 1 && type_arraylen == 3)) {
+ for (int i = 0; i < (derivatives ? 3 : 1); ++i) {
+ static_cast<ccl_private float *>(val)[i * 3 + 0] = fval[i].x;
+ static_cast<ccl_private float *>(val)[i * 3 + 1] = fval[i].y;
+ static_cast<ccl_private float *>(val)[i * 3 + 2] = 0.0f;
+ }
+ return true;
+ }
+ if ((type_aggregate == 4 /* TypeDesc::VEC4 */) ||
+ (type_aggregate == 1 && type_arraylen == 4)) {
+ for (int i = 0; i < (derivatives ? 3 : 1); ++i) {
+ static_cast<ccl_private float *>(val)[i * 4 + 0] = fval[i].x;
+ static_cast<ccl_private float *>(val)[i * 4 + 1] = fval[i].y;
+ static_cast<ccl_private float *>(val)[i * 4 + 2] = 0.0f;
+ static_cast<ccl_private float *>(val)[i * 4 + 3] = 1.0f;
+ }
+ return true;
+ }
+ if ((type_aggregate == 1 /* TypeDesc::SCALAR */)) {
+ for (int i = 0; i < (derivatives ? 3 : 1); ++i) {
+ static_cast<ccl_private float *>(val)[i] = fval[i].x;
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+ccl_device_inline bool set_attribute_float3(ccl_private float3 fval[3],
+ TypeDesc type,
+ bool derivatives,
+ ccl_private void *val)
+{
+ const unsigned char type_basetype = type & 0xF;
+ const unsigned char type_aggregate = (type >> 8) & 0xF;
+ const int type_arraylen = type >> 32;
+
+ if (type_basetype == 11 /* TypeDesc::FLOAT */) {
+ if ((type_aggregate == 3 /* TypeDesc::VEC3 */) ||
+ (type_aggregate == 1 && type_arraylen == 3)) {
+ for (int i = 0; i < (derivatives ? 3 : 1); ++i) {
+ static_cast<ccl_private float *>(val)[i * 3 + 0] = fval[i].x;
+ static_cast<ccl_private float *>(val)[i * 3 + 1] = fval[i].y;
+ static_cast<ccl_private float *>(val)[i * 3 + 2] = fval[i].z;
+ }
+ return true;
+ }
+ if ((type_aggregate == 4 /* TypeDesc::VEC4 */) ||
+ (type_aggregate == 1 && type_arraylen == 4)) {
+ for (int i = 0; i < (derivatives ? 3 : 1); ++i) {
+ static_cast<ccl_private float *>(val)[i * 4 + 0] = fval[i].x;
+ static_cast<ccl_private float *>(val)[i * 4 + 1] = fval[i].y;
+ static_cast<ccl_private float *>(val)[i * 4 + 2] = fval[i].z;
+ static_cast<ccl_private float *>(val)[i * 4 + 3] = 1.0f;
+ }
+ return true;
+ }
+ if ((type_aggregate == 1 /* TypeDesc::SCALAR */)) {
+ for (int i = 0; i < (derivatives ? 3 : 1); ++i) {
+ static_cast<ccl_private float *>(val)[i] = average(fval[i]);
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+ccl_device_inline bool set_attribute_float3(float3 f,
+ TypeDesc type,
+ bool derivatives,
+ ccl_private void *val)
+{
+ float3 fv[3];
+
+ fv[0] = f;
+ fv[1] = make_float3(0.0f, 0.0f, 0.0f);
+ fv[2] = make_float3(0.0f, 0.0f, 0.0f);
+
+ return set_attribute_float3(fv, type, derivatives, val);
+}
+ccl_device_inline bool set_attribute_float4(ccl_private float4 fval[3],
+ TypeDesc type,
+ bool derivatives,
+ ccl_private void *val)
+{
+ const unsigned char type_basetype = type & 0xF;
+ const unsigned char type_aggregate = (type >> 8) & 0xF;
+ const int type_arraylen = type >> 32;
+
+ if (type_basetype == 11 /* TypeDesc::FLOAT */) {
+ if ((type_aggregate == 3 /* TypeDesc::VEC3 */) ||
+ (type_aggregate == 1 && type_arraylen == 3)) {
+ for (int i = 0; i < (derivatives ? 3 : 1); ++i) {
+ static_cast<ccl_private float *>(val)[i * 3 + 0] = fval[i].x;
+ static_cast<ccl_private float *>(val)[i * 3 + 1] = fval[i].y;
+ static_cast<ccl_private float *>(val)[i * 3 + 2] = fval[i].z;
+ }
+ return true;
+ }
+ if ((type_aggregate == 4 /* TypeDesc::VEC4 */) ||
+ (type_aggregate == 1 && type_arraylen == 4)) {
+ for (int i = 0; i < (derivatives ? 3 : 1); ++i) {
+ static_cast<ccl_private float *>(val)[i * 4 + 0] = fval[i].x;
+ static_cast<ccl_private float *>(val)[i * 4 + 1] = fval[i].y;
+ static_cast<ccl_private float *>(val)[i * 4 + 2] = fval[i].z;
+ static_cast<ccl_private float *>(val)[i * 4 + 3] = fval[i].w;
+ }
+ return true;
+ }
+ if ((type_aggregate == 1 /* TypeDesc::SCALAR */)) {
+ for (int i = 0; i < (derivatives ? 3 : 1); ++i) {
+ static_cast<ccl_private float *>(val)[i] = average(float4_to_float3(fval[i]));
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+ccl_device_inline bool set_attribute_matrix(ccl_private const Transform &tfm,
+ TypeDesc type,
+ ccl_private void *val)
+{
+ const unsigned char type_basetype = type & 0xF;
+ const unsigned char type_aggregate = (type >> 8) & 0xF;
+
+ if (type_basetype == 11 /* TypeDesc::FLOAT */ && type_aggregate == 16 /* TypeDesc::MATRIX44 */) {
+ copy_matrix(static_cast<ccl_private float *>(val), tfm);
+ return true;
+ }
+
+ return false;
+}
+
+ccl_device_inline bool get_background_attribute(KernelGlobals kg,
+ ccl_private ShaderData *sd,
+ DeviceString name,
+ TypeDesc type,
+ bool derivatives,
+ ccl_private void *val)
+{
+ if (name == DeviceStrings::u_path_ray_length) {
+ /* Ray Length */
+ float f = sd->ray_length;
+ return set_attribute_float(f, type, derivatives, val);
+ }
+
+ return false;
+}
+
+ccl_device_inline bool get_object_attribute(KernelGlobals kg,
+ ccl_private ShaderData *sd,
+ const AttributeDescriptor &desc,
+ TypeDesc type,
+ bool derivatives,
+ ccl_private void *val)
+{
+ if (desc.type == NODE_ATTR_FLOAT) {
+ float fval[3];
+#ifdef __VOLUME__
+ if (primitive_is_volume_attribute(sd, desc))
+ fval[0] = primitive_volume_attribute_float(kg, sd, desc);
+ else
+#endif
+ fval[0] = primitive_surface_attribute_float(
+ kg, sd, desc, derivatives ? &fval[1] : nullptr, derivatives ? &fval[2] : nullptr);
+ return set_attribute_float(fval, type, derivatives, val);
+ }
+ else if (desc.type == NODE_ATTR_FLOAT2) {
+ float2 fval[3];
+#ifdef __VOLUME__
+ if (primitive_is_volume_attribute(sd, desc))
+ return false;
+ else
+#endif
+ fval[0] = primitive_surface_attribute_float2(
+ kg, sd, desc, derivatives ? &fval[1] : nullptr, derivatives ? &fval[2] : nullptr);
+ return set_attribute_float2(fval, type, derivatives, val);
+ }
+ else if (desc.type == NODE_ATTR_FLOAT3) {
+ float3 fval[3];
+#ifdef __VOLUME__
+ if (primitive_is_volume_attribute(sd, desc))
+ fval[0] = primitive_volume_attribute_float3(kg, sd, desc);
+ else
+#endif
+ fval[0] = primitive_surface_attribute_float3(
+ kg, sd, desc, derivatives ? &fval[1] : nullptr, derivatives ? &fval[2] : nullptr);
+ return set_attribute_float3(fval, type, derivatives, val);
+ }
+ else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
+ float4 fval[3];
+#ifdef __VOLUME__
+ if (primitive_is_volume_attribute(sd, desc))
+ fval[0] = primitive_volume_attribute_float4(kg, sd, desc);
+ else
+#endif
+ fval[0] = primitive_surface_attribute_float4(
+ kg, sd, desc, derivatives ? &fval[1] : nullptr, derivatives ? &fval[2] : nullptr);
+ return set_attribute_float4(fval, type, derivatives, val);
+ }
+ else if (desc.type == NODE_ATTR_MATRIX) {
+ Transform tfm = primitive_attribute_matrix(kg, desc);
+ return set_attribute_matrix(tfm, type, val);
+ }
+
+ return false;
+}
+
+ccl_device_inline bool get_object_standard_attribute(KernelGlobals kg,
+ ccl_private ShaderData *sd,
+ DeviceString name,
+ TypeDesc type,
+ bool derivatives,
+ ccl_private void *val)
+{
+ /* Object attributes */
+ if (name == DeviceStrings::u_object_location) {
+ float3 f = object_location(kg, sd);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else if (name == DeviceStrings::u_object_color) {
+ float3 f = object_color(kg, sd->object);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else if (name == DeviceStrings::u_object_alpha) {
+ float f = object_alpha(kg, sd->object);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == DeviceStrings::u_object_index) {
+ float f = object_pass_id(kg, sd->object);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == DeviceStrings::u_geom_dupli_generated) {
+ float3 f = object_dupli_generated(kg, sd->object);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else if (name == DeviceStrings::u_geom_dupli_uv) {
+ float3 f = object_dupli_uv(kg, sd->object);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else if (name == DeviceStrings::u_material_index) {
+ float f = shader_pass_id(kg, sd);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == DeviceStrings::u_object_random) {
+ float f = object_random_number(kg, sd->object);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+
+ /* Particle attributes */
+ else if (name == DeviceStrings::u_particle_index) {
+ 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 == DeviceStrings::u_particle_random) {
+ int particle_id = object_particle_id(kg, sd->object);
+ float f = hash_uint2_to_float(particle_index(kg, particle_id), 0);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+
+ else if (name == DeviceStrings::u_particle_age) {
+ 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 == DeviceStrings::u_particle_lifetime) {
+ 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 == DeviceStrings::u_particle_location) {
+ 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 == DeviceStrings::u_particle_rotation) {
+ 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 == DeviceStrings::u_particle_size) {
+ 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 == DeviceStrings::u_particle_velocity) {
+ 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 == DeviceStrings::u_particle_angular_velocity) {
+ 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);
+ }
+
+ /* Geometry attributes */
+#if 0 /* TODO */
+ else if (name == DeviceStrings::u_geom_numpolyvertices) {
+ return false;
+ }
+ else if (name == DeviceStrings::u_geom_trianglevertices ||
+ name == DeviceStrings::u_geom_polyvertices) {
+ return false;
+ }
+ else if (name == DeviceStrings::u_geom_name) {
+ return false;
+ }
+#endif
+ else if (name == DeviceStrings::u_is_smooth) {
+ float f = ((sd->shader & SHADER_SMOOTH_NORMAL) != 0);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+
+#ifdef __HAIR__
+ /* Hair attributes */
+ else if (name == DeviceStrings::u_is_curve) {
+ float f = (sd->type & PRIMITIVE_CURVE) != 0;
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == DeviceStrings::u_curve_thickness) {
+ float f = curve_thickness(kg, sd);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == DeviceStrings::u_curve_tangent_normal) {
+ float3 f = curve_tangent_normal(kg, sd);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else if (name == DeviceStrings::u_curve_random) {
+ float f = curve_random(kg, sd);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+#endif
+
+#ifdef __POINTCLOUD__
+ /* Point attributes */
+ else if (name == DeviceStrings::u_is_point) {
+ float f = (sd->type & PRIMITIVE_POINT) != 0;
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == DeviceStrings::u_point_radius) {
+ float f = point_radius(kg, sd);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == DeviceStrings::u_point_position) {
+ float3 f = point_position(kg, sd);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else if (name == DeviceStrings::u_point_random) {
+ float f = point_random(kg, sd);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+#endif
+
+ else if (name == DeviceStrings::u_normal_map_normal) {
+ if (sd->type & PRIMITIVE_TRIANGLE) {
+ float3 f = triangle_smooth_normal_unnormalized(kg, sd, sd->Ng, sd->prim, sd->u, sd->v);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else {
+ return false;
+ }
+ }
+
+ return get_background_attribute(kg, sd, name, type, derivatives, val);
+}
+
+ccl_device_extern bool osl_get_attribute(ccl_private ShaderGlobals *sg,
+ int derivatives,
+ DeviceString object_name,
+ DeviceString name,
+ int array_lookup,
+ int index,
+ TypeDesc type,
+ ccl_private void *res)
+{
+ KernelGlobals kg = nullptr;
+ ccl_private ShaderData *const sd = static_cast<ccl_private ShaderData *>(sg->renderstate);
+ int object;
+
+ if (object_name != DeviceStrings::_emptystring_) {
+ /* TODO: Get object index from name */
+ return false;
+ }
+ else {
+ object = sd->object;
+ }
+
+ const uint64_t id = name.hash();
+
+ const AttributeDescriptor desc = find_attribute(kg, object, sd->prim, sd->type, id);
+ if (desc.offset != ATTR_STD_NOT_FOUND) {
+ return get_object_attribute(kg, sd, desc, type, derivatives, res);
+ }
+ else {
+ return get_object_standard_attribute(kg, sd, name, type, derivatives, res);
+ }
+}
+
+#if 0
+ccl_device_extern bool osl_bind_interpolated_param(ccl_private ShaderGlobals *sg,
+ DeviceString name,
+ long long type,
+ int userdata_has_derivs,
+ ccl_private void *userdata_data,
+ int symbol_has_derivs,
+ ccl_private void *symbol_data,
+ int symbol_data_size,
+ ccl_private void *userdata_initialized,
+ int userdata_index)
+{
+ return false;
+}
+#endif
+
+/* Noise */
+
+#include "kernel/svm/noise.h"
+#include "util/hash.h"
+
+ccl_device_extern uint osl_hash_ii(int x)
+{
+ return hash_uint(x);
+}
+
+ccl_device_extern uint osl_hash_if(float x)
+{
+ return hash_uint(__float_as_uint(x));
+}
+
+ccl_device_extern uint osl_hash_iff(float x, float y)
+{
+ return hash_uint2(__float_as_uint(x), __float_as_uint(y));
+}
+
+ccl_device_extern uint osl_hash_iv(ccl_private const float3 *v)
+{
+ return hash_uint3(__float_as_uint(v->x), __float_as_uint(v->y), __float_as_uint(v->z));
+}
+
+ccl_device_extern uint osl_hash_ivf(ccl_private const float3 *v, float w)
+{
+ return hash_uint4(
+ __float_as_uint(v->x), __float_as_uint(v->y), __float_as_uint(v->z), __float_as_uint(w));
+}
+
+ccl_device_extern OSLNoiseOptions *osl_get_noise_options(ccl_private ShaderGlobals *sg)
+{
+ return nullptr;
+}
+
+ccl_device_extern void osl_noiseparams_set_anisotropic(ccl_private OSLNoiseOptions *opt,
+ int anisotropic)
+{
+}
+
+ccl_device_extern void osl_noiseparams_set_do_filter(ccl_private OSLNoiseOptions *opt,
+ int do_filter)
+{
+}
+
+ccl_device_extern void osl_noiseparams_set_direction(ccl_private OSLNoiseOptions *opt,
+ float3 *direction)
+{
+}
+
+ccl_device_extern void osl_noiseparams_set_bandwidth(ccl_private OSLNoiseOptions *opt,
+ float bandwidth)
+{
+}
+
+ccl_device_extern void osl_noiseparams_set_impulses(ccl_private OSLNoiseOptions *opt,
+ float impulses)
+{
+}
+
+#define OSL_NOISE_IMPL(name, op) \
+ ccl_device_extern float name##_ff(float x) \
+ { \
+ return op##_1d(x); \
+ } \
+ ccl_device_extern float name##_fff(float x, float y) \
+ { \
+ return op##_2d(make_float2(x, y)); \
+ } \
+ ccl_device_extern float name##_fv(ccl_private const float3 *v) \
+ { \
+ return op##_3d(*v); \
+ } \
+ ccl_device_extern float name##_fvf(ccl_private const float3 *v, float w) \
+ { \
+ return op##_4d(make_float4(v->x, v->y, v->z, w)); \
+ } \
+ ccl_device_extern void name##_vf(ccl_private float3 *res, float x) \
+ { \
+ /* TODO: This is not correct. Really need to change the hash function inside the noise \
+ * function to spit out a vector instead of a scalar. */ \
+ const float n = name##_ff(x); \
+ res->x = n; \
+ res->y = n; \
+ res->z = n; \
+ } \
+ ccl_device_extern void name##_vff(ccl_private float3 *res, float x, float y) \
+ { \
+ const float n = name##_fff(x, y); \
+ res->x = n; \
+ res->y = n; \
+ res->z = n; \
+ } \
+ ccl_device_extern void name##_vv(ccl_private float3 *res, const float3 *v) \
+ { \
+ const float n = name##_fv(v); \
+ res->x = n; \
+ res->y = n; \
+ res->z = n; \
+ } \
+ ccl_device_extern void name##_vvf(ccl_private float3 *res, const float3 *v, float w) \
+ { \
+ const float n = name##_fvf(v, w); \
+ res->x = n; \
+ res->y = n; \
+ res->z = n; \
+ }
+
+ccl_device_forceinline float hashnoise_1d(float p)
+{
+ const uint x = __float_as_uint(p);
+ return hash_uint(x) / static_cast<float>(~0u);
+}
+ccl_device_forceinline float hashnoise_2d(float2 p)
+{
+ const uint x = __float_as_uint(p.x);
+ const uint y = __float_as_uint(p.y);
+ return hash_uint2(x, y) / static_cast<float>(~0u);
+}
+ccl_device_forceinline float hashnoise_3d(float3 p)
+{
+ const uint x = __float_as_uint(p.x);
+ const uint y = __float_as_uint(p.y);
+ const uint z = __float_as_uint(p.z);
+ return hash_uint3(x, y, z) / static_cast<float>(~0u);
+}
+ccl_device_forceinline float hashnoise_4d(float4 p)
+{
+ const uint x = __float_as_uint(p.x);
+ const uint y = __float_as_uint(p.y);
+ const uint z = __float_as_uint(p.z);
+ const uint w = __float_as_uint(p.w);
+ return hash_uint4(x, y, z, w) / static_cast<float>(~0u);
+}
+
+/* TODO: Implement all noise functions */
+OSL_NOISE_IMPL(osl_hashnoise, hashnoise)
+OSL_NOISE_IMPL(osl_noise, noise)
+OSL_NOISE_IMPL(osl_snoise, snoise)
+
+/* Texturing */
+
+ccl_device_extern ccl_private OSLTextureOptions *osl_get_texture_options(
+ ccl_private ShaderGlobals *sg)
+{
+ return nullptr;
+}
+
+ccl_device_extern void osl_texture_set_firstchannel(ccl_private OSLTextureOptions *opt,
+ int firstchannel)
+{
+}
+
+ccl_device_extern void osl_texture_set_swrap_code(ccl_private OSLTextureOptions *opt, int mode)
+{
+}
+
+ccl_device_extern void osl_texture_set_twrap_code(ccl_private OSLTextureOptions *opt, int mode)
+{
+}
+
+ccl_device_extern void osl_texture_set_rwrap_code(ccl_private OSLTextureOptions *opt, int mode)
+{
+}
+
+ccl_device_extern void osl_texture_set_stwrap_code(ccl_private OSLTextureOptions *opt, int mode)
+{
+}
+
+ccl_device_extern void osl_texture_set_sblur(ccl_private OSLTextureOptions *opt, float blur)
+{
+}
+
+ccl_device_extern void osl_texture_set_tblur(ccl_private OSLTextureOptions *opt, float blur)
+{
+}
+
+ccl_device_extern void osl_texture_set_rblur(ccl_private OSLTextureOptions *opt, float blur)
+{
+}
+
+ccl_device_extern void osl_texture_set_stblur(ccl_private OSLTextureOptions *opt, float blur)
+{
+}
+
+ccl_device_extern void osl_texture_set_swidth(ccl_private OSLTextureOptions *opt, float width)
+{
+}
+
+ccl_device_extern void osl_texture_set_twidth(ccl_private OSLTextureOptions *opt, float width)
+{
+}
+
+ccl_device_extern void osl_texture_set_rwidth(ccl_private OSLTextureOptions *opt, float width)
+{
+}
+
+ccl_device_extern void osl_texture_set_stwidth(ccl_private OSLTextureOptions *opt, float width)
+{
+}
+
+ccl_device_extern void osl_texture_set_fill(ccl_private OSLTextureOptions *opt, float fill)
+{
+}
+
+ccl_device_extern void osl_texture_set_time(ccl_private OSLTextureOptions *opt, float time)
+{
+}
+
+ccl_device_extern void osl_texture_set_interp_code(ccl_private OSLTextureOptions *opt, int mode)
+{
+}
+
+ccl_device_extern void osl_texture_set_subimage(ccl_private OSLTextureOptions *opt, int subimage)
+{
+}
+
+ccl_device_extern void osl_texture_set_missingcolor_arena(ccl_private OSLTextureOptions *opt,
+ ccl_private float3 *color)
+{
+}
+
+ccl_device_extern void osl_texture_set_missingcolor_alpha(ccl_private OSLTextureOptions *opt,
+ int nchannels,
+ float alpha)
+{
+}
+
+ccl_device_extern bool osl_texture(ccl_private ShaderGlobals *sg,
+ DeviceString filename,
+ ccl_private void *texture_handle,
+ OSLTextureOptions *opt,
+ float s,
+ float t,
+ float dsdx,
+ float dtdx,
+ float dsdy,
+ float dtdy,
+ int nchannels,
+ ccl_private float *result,
+ ccl_private float *dresultdx,
+ ccl_private float *dresultdy,
+ ccl_private float *alpha,
+ ccl_private float *dalphadx,
+ ccl_private float *dalphady,
+ ccl_private void *errormessage)
+{
+ if (!texture_handle) {
+ return false;
+ }
+
+ /* Only SVM textures are supported. */
+ int id = static_cast<int>(reinterpret_cast<size_t>(texture_handle) - 1);
+
+ const float4 rgba = kernel_tex_image_interp(nullptr, id, s, 1.0f - t);
+
+ result[0] = rgba.x;
+ if (nchannels > 1)
+ result[1] = rgba.y;
+ if (nchannels > 2)
+ result[2] = rgba.z;
+ if (nchannels > 3)
+ result[3] = rgba.w;
+
+ return true;
+}
+
+ccl_device_extern bool osl_texture3d(ccl_private ShaderGlobals *sg,
+ DeviceString filename,
+ ccl_private void *texture_handle,
+ OSLTextureOptions *opt,
+ ccl_private const float3 *P,
+ ccl_private const float3 *dPdx,
+ ccl_private const float3 *dPdy,
+ ccl_private const float3 *dPdz,
+ int nchannels,
+ ccl_private float *result,
+ ccl_private float *dresultds,
+ ccl_private float *dresultdt,
+ ccl_private float *alpha,
+ ccl_private float *dalphadx,
+ ccl_private float *dalphady,
+ ccl_private void *errormessage)
+{
+ if (!texture_handle) {
+ return false;
+ }
+
+ /* Only SVM textures are supported. */
+ int id = static_cast<int>(reinterpret_cast<size_t>(texture_handle) - 1);
+
+ const float4 rgba = kernel_tex_image_interp_3d(nullptr, id, *P, INTERPOLATION_NONE);
+
+ result[0] = rgba.x;
+ if (nchannels > 1)
+ result[1] = rgba.y;
+ if (nchannels > 2)
+ result[2] = rgba.z;
+ if (nchannels > 3)
+ result[3] = rgba.w;
+
+ return true;
+}
+
+ccl_device_extern bool osl_environment(ccl_private ShaderGlobals *sg,
+ DeviceString filename,
+ ccl_private void *texture_handle,
+ OSLTextureOptions *opt,
+ ccl_private const float3 *R,
+ ccl_private const float3 *dRdx,
+ ccl_private const float3 *dRdy,
+ int nchannels,
+ ccl_private float *result,
+ ccl_private float *dresultds,
+ ccl_private float *dresultdt,
+ ccl_private float *alpha,
+ ccl_private float *dalphax,
+ ccl_private float *dalphay,
+ ccl_private void *errormessage)
+{
+ result[0] = 1.0f;
+ if (nchannels > 1)
+ result[1] = 0.0f;
+ if (nchannels > 2)
+ result[2] = 1.0f;
+ if (nchannels > 3)
+ result[3] = 1.0f;
+
+ return false;
+}
+
+ccl_device_extern bool osl_get_textureinfo(ccl_private ShaderGlobals *sg,
+ DeviceString filename,
+ ccl_private void *texture_handle,
+ DeviceString dataname,
+ int basetype,
+ int arraylen,
+ int aggegrate,
+ ccl_private void *data,
+ ccl_private void *errormessage)
+{
+ return false;
+}
+
+ccl_device_extern bool osl_get_textureinfo_st(ccl_private ShaderGlobals *sg,
+ DeviceString filename,
+ ccl_private void *texture_handle,
+ float s,
+ float t,
+ DeviceString dataname,
+ int basetype,
+ int arraylen,
+ int aggegrate,
+ ccl_private void *data,
+ ccl_private void *errormessage)
+{
+ return osl_get_textureinfo(
+ sg, filename, texture_handle, dataname, basetype, arraylen, aggegrate, data, errormessage);
+}
+
+/* Standard library */
+
+#define OSL_OP_IMPL_II(name, op) \
+ ccl_device_extern int name##_ii(int a) \
+ { \
+ return op(a); \
+ }
+#define OSL_OP_IMPL_IF(name, op) \
+ ccl_device_extern int name##_if(float a) \
+ { \
+ return op(a); \
+ }
+#define OSL_OP_IMPL_FF(name, op) \
+ ccl_device_extern float name##_ff(float a) \
+ { \
+ return op(a); \
+ }
+#define OSL_OP_IMPL_DFDF(name, op) \
+ ccl_device_extern void name##_dfdf(ccl_private float *res, ccl_private const float *a) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a[i]); \
+ } \
+ }
+#define OSL_OP_IMPL_DFDV(name, op) \
+ ccl_device_extern void name##_dfdv(ccl_private float *res, ccl_private const float3 *a) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a[i]); \
+ } \
+ }
+#define OSL_OP_IMPL_FV(name, op) \
+ ccl_device_extern float name##_fv(ccl_private const float3 *a) \
+ { \
+ return op(*a); \
+ }
+#define OSL_OP_IMPL_VV(name, op) \
+ ccl_device_extern void name##_vv(ccl_private float3 *res, ccl_private const float3 *a) \
+ { \
+ *res = op(*a); \
+ }
+#define OSL_OP_IMPL_VV_(name, op) \
+ ccl_device_extern void name##_vv(ccl_private float3 *res, ccl_private const float3 *a) \
+ { \
+ res->x = op(a->x); \
+ res->y = op(a->y); \
+ res->z = op(a->z); \
+ }
+#define OSL_OP_IMPL_DVDV(name, op) \
+ ccl_device_extern void name##_dvdv(ccl_private float3 *res, ccl_private const float3 *a) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a[i]); \
+ } \
+ }
+#define OSL_OP_IMPL_DVDV_(name, op) \
+ ccl_device_extern void name##_dvdv(ccl_private float3 *res, ccl_private const float3 *a) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i].x = op(a[i].x); \
+ res[i].y = op(a[i].y); \
+ res[i].z = op(a[i].z); \
+ } \
+ }
+
+#define OSL_OP_IMPL_III(name, op) \
+ ccl_device_extern int name##_iii(int a, int b) \
+ { \
+ return op(a, b); \
+ }
+#define OSL_OP_IMPL_FFF(name, op) \
+ ccl_device_extern float name##_fff(float a, float b) \
+ { \
+ return op(a, b); \
+ }
+#define OSL_OP_IMPL_FVV(name, op) \
+ ccl_device_extern float name##_fvv(ccl_private const float3 *a, ccl_private const float3 *b) \
+ { \
+ return op(*a, *b); \
+ }
+#define OSL_OP_IMPL_DFFDF(name, op) \
+ ccl_device_extern void name##_dffdf( \
+ ccl_private float *res, float a, ccl_private const float *b) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a, b[i]); \
+ } \
+ }
+#define OSL_OP_IMPL_DFDFF(name, op) \
+ ccl_device_extern void name##_dfdff( \
+ ccl_private float *res, ccl_private const float *a, float b) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a[i], b); \
+ } \
+ }
+#define OSL_OP_IMPL_DFDFDF(name, op) \
+ ccl_device_extern void name##_dfdfdf( \
+ ccl_private float *res, ccl_private const float *a, ccl_private const float *b) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a[i], b[i]); \
+ } \
+ }
+#define OSL_OP_IMPL_DFVDV(name, op) \
+ ccl_device_extern void name##_dfvdv( \
+ ccl_private float *res, ccl_private const float3 *a, ccl_private const float3 *b) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a[0], b[i]); \
+ } \
+ }
+#define OSL_OP_IMPL_DFDVV(name, op) \
+ ccl_device_extern void name##_dfdvv( \
+ ccl_private float *res, ccl_private const float3 *a, ccl_private const float3 *b) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a[i], b[0]); \
+ } \
+ }
+#define OSL_OP_IMPL_DFDVDV(name, op) \
+ ccl_device_extern void name##_dfdvdv( \
+ ccl_private float *res, ccl_private const float3 *a, ccl_private const float3 *b) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a[i], b[i]); \
+ } \
+ }
+#define OSL_OP_IMPL_VVF_(name, op) \
+ ccl_device_extern void name##_vvf( \
+ ccl_private float3 *res, ccl_private const float3 *a, float b) \
+ { \
+ res->x = op(a->x, b); \
+ res->y = op(a->y, b); \
+ res->z = op(a->z, b); \
+ }
+#define OSL_OP_IMPL_VVV(name, op) \
+ ccl_device_extern void name##_vvv( \
+ ccl_private float3 *res, ccl_private const float3 *a, ccl_private const float3 *b) \
+ { \
+ *res = op(*a, *b); \
+ }
+#define OSL_OP_IMPL_VVV_(name, op) \
+ ccl_device_extern void name##_vvv( \
+ ccl_private float3 *res, ccl_private const float3 *a, ccl_private const float3 *b) \
+ { \
+ res->x = op(a->x, b->x); \
+ res->y = op(a->y, b->y); \
+ res->z = op(a->z, b->z); \
+ }
+#define OSL_OP_IMPL_DVVDF_(name, op) \
+ ccl_device_extern void name##_dvvdf( \
+ ccl_private float3 *res, ccl_private const float3 *a, ccl_private const float *b) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i].x = op(a[0].x, b[i]); \
+ res[i].y = op(a[0].y, b[i]); \
+ res[i].z = op(a[0].z, b[i]); \
+ } \
+ }
+#define OSL_OP_IMPL_DVDVF_(name, op) \
+ ccl_device_extern void name##_dvdvf( \
+ ccl_private float3 *res, ccl_private const float3 *a, float b) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i].x = op(a[i].x, b); \
+ res[i].y = op(a[i].y, b); \
+ res[i].z = op(a[i].z, b); \
+ } \
+ }
+#define OSL_OP_IMPL_DVVDV(name, op) \
+ ccl_device_extern void name##_dvvdv( \
+ ccl_private float3 *res, ccl_private const float3 *a, ccl_private const float3 *b) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a[0], b[i]); \
+ } \
+ }
+#define OSL_OP_IMPL_DVVDV_(name, op) \
+ ccl_device_extern void name##_dvvdv( \
+ ccl_private float3 *res, ccl_private const float3 *a, ccl_private const float3 *b) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i].x = op(a[0].x, b[i].x); \
+ res[i].y = op(a[0].y, b[i].y); \
+ res[i].z = op(a[0].z, b[i].z); \
+ } \
+ }
+#define OSL_OP_IMPL_DVDVV(name, op) \
+ ccl_device_extern void name##_dvdvv( \
+ ccl_private float3 *res, ccl_private const float3 *a, ccl_private const float3 *b) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a[i], b[0]); \
+ } \
+ }
+#define OSL_OP_IMPL_DVDVV_(name, op) \
+ ccl_device_extern void name##_dvdvv( \
+ ccl_private float3 *res, ccl_private const float3 *a, ccl_private const float3 *b) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i].x = op(a[i].x, b[0].x); \
+ res[i].y = op(a[i].y, b[0].y); \
+ res[i].z = op(a[i].z, b[0].z); \
+ } \
+ }
+#define OSL_OP_IMPL_DVDVDF_(name, op) \
+ ccl_device_extern void name##_dvdvdf( \
+ ccl_private float3 *res, ccl_private const float3 *a, ccl_private const float *b) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i].x = op(a[i].x, b[i]); \
+ res[i].y = op(a[i].y, b[i]); \
+ res[i].z = op(a[i].z, b[i]); \
+ } \
+ }
+#define OSL_OP_IMPL_DVDVDV(name, op) \
+ ccl_device_extern void name##_dvdvdv( \
+ ccl_private float3 *res, ccl_private const float3 *a, ccl_private const float3 *b) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a[i], b[i]); \
+ } \
+ }
+#define OSL_OP_IMPL_DVDVDV_(name, op) \
+ ccl_device_extern void name##_dvdvdv( \
+ ccl_private float3 *res, ccl_private const float3 *a, ccl_private const float3 *b) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i].x = op(a[i].x, b[i].x); \
+ res[i].y = op(a[i].y, b[i].y); \
+ res[i].z = op(a[i].z, b[i].z); \
+ } \
+ }
+
+#define OSL_OP_IMPL_FFFF(name, op) \
+ ccl_device_extern float name##_ffff(float a, float b, float c) \
+ { \
+ return op(a, b, c); \
+ }
+#define OSL_OP_IMPL_DFFFDF(name, op) \
+ ccl_device_extern void name##_dfffdf( \
+ ccl_private float *res, float a, float b, ccl_private const float *c) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a, b, c[i]); \
+ } \
+ }
+#define OSL_OP_IMPL_DFFDFF(name, op) \
+ ccl_device_extern void name##_dffdff( \
+ ccl_private float *res, float a, ccl_private const float *b, float c) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a, b[i], c); \
+ } \
+ }
+#define OSL_OP_IMPL_DFFDFDF(name, op) \
+ ccl_device_extern void name##_dffdfdf( \
+ ccl_private float *res, float a, ccl_private const float *b, ccl_private const float *c) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a, b[i], c[i]); \
+ } \
+ }
+
+#define OSL_OP_IMPL_DFDFFF(name, op) \
+ ccl_device_extern void name##_dfdfff( \
+ ccl_private float *res, ccl_private const float *a, float b, float c) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a[i], b, c); \
+ } \
+ }
+#define OSL_OP_IMPL_DFDFFDF(name, op) \
+ ccl_device_extern void name##_dfdffdf( \
+ ccl_private float *res, ccl_private const float *a, float b, ccl_private const float *c) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a[i], b, c[i]); \
+ } \
+ }
+#define OSL_OP_IMPL_DFDFDFF(name, op) \
+ ccl_device_extern void name##_dfdfdff( \
+ ccl_private float *res, ccl_private const float *a, ccl_private const float *b, float c) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a[i], b[i], c); \
+ } \
+ }
+#define OSL_OP_IMPL_DFDFDFDF(name, op) \
+ ccl_device_extern void name##_dfdfdfdf(ccl_private float *res, \
+ ccl_private const float *a, \
+ ccl_private const float *b, \
+ ccl_private const float *c) \
+ { \
+ for (int i = 0; i < 3; ++i) { \
+ res[i] = op(a[i], b[i], c[i]); \
+ } \
+ }
+
+#define OSL_OP_IMPL_XX(name, op) \
+ OSL_OP_IMPL_FF(name, op) \
+ OSL_OP_IMPL_DFDF(name, op) \
+ OSL_OP_IMPL_VV_(name, op) \
+ OSL_OP_IMPL_DVDV_(name, op)
+
+#define OSL_OP_IMPL_XXX(name, op) \
+ OSL_OP_IMPL_FFF(name, op) \
+ OSL_OP_IMPL_DFFDF(name, op) \
+ OSL_OP_IMPL_DFDFF(name, op) \
+ OSL_OP_IMPL_DFDFDF(name, op) \
+ OSL_OP_IMPL_VVV_(name, op) \
+ OSL_OP_IMPL_DVVDV_(name, op) \
+ OSL_OP_IMPL_DVDVV_(name, op) \
+ OSL_OP_IMPL_DVDVDV_(name, op)
+
+OSL_OP_IMPL_XX(osl_acos, acosf)
+OSL_OP_IMPL_XX(osl_asin, asinf)
+OSL_OP_IMPL_XX(osl_atan, atanf)
+OSL_OP_IMPL_XXX(osl_atan2, atan2f)
+OSL_OP_IMPL_XX(osl_cos, cosf)
+OSL_OP_IMPL_XX(osl_sin, sinf)
+OSL_OP_IMPL_XX(osl_tan, tanf)
+OSL_OP_IMPL_XX(osl_cosh, coshf)
+OSL_OP_IMPL_XX(osl_sinh, sinhf)
+OSL_OP_IMPL_XX(osl_tanh, tanhf)
+
+ccl_device_forceinline int safe_divide(int a, int b)
+{
+ return (b != 0) ? a / b : 0;
+}
+ccl_device_forceinline int safe_modulo(int a, int b)
+{
+ return (b != 0) ? a % b : 0;
+}
+
+OSL_OP_IMPL_III(osl_safe_div, safe_divide)
+OSL_OP_IMPL_FFF(osl_safe_div, safe_divide)
+OSL_OP_IMPL_III(osl_safe_mod, safe_modulo)
+
+ccl_device_extern void osl_sincos_fff(float a, ccl_private float *b, ccl_private float *c)
+{
+ sincos(a, b, c);
+}
+ccl_device_extern void osl_sincos_dfdff(ccl_private const float *a,
+ ccl_private float *b,
+ ccl_private float *c)
+{
+ for (int i = 0; i < 3; ++i)
+ sincos(a[i], b + i, c);
+}
+ccl_device_extern void osl_sincos_dffdf(ccl_private const float *a,
+ ccl_private float *b,
+ ccl_private float *c)
+{
+ for (int i = 0; i < 3; ++i)
+ sincos(a[i], b, c + i);
+}
+ccl_device_extern void osl_sincos_dfdfdf(ccl_private const float *a,
+ ccl_private float *b,
+ ccl_private float *c)
+{
+ for (int i = 0; i < 3; ++i)
+ sincos(a[i], b + i, c + i);
+}
+ccl_device_extern void osl_sincos_vvv(ccl_private const float3 *a,
+ ccl_private float3 *b,
+ ccl_private float3 *c)
+{
+ sincos(a->x, &b->x, &c->x);
+ sincos(a->y, &b->y, &c->y);
+ sincos(a->z, &b->z, &c->z);
+}
+ccl_device_extern void osl_sincos_dvdvv(ccl_private const float3 *a,
+ ccl_private float3 *b,
+ ccl_private float3 *c)
+{
+ for (int i = 0; i < 3; ++i) {
+ sincos(a[i].x, &b[i].x, &c->x);
+ sincos(a[i].y, &b[i].y, &c->y);
+ sincos(a[i].z, &b[i].z, &c->z);
+ }
+}
+ccl_device_extern void osl_sincos_dvvdv(ccl_private const float3 *a,
+ ccl_private float3 *b,
+ ccl_private float3 *c)
+{
+ for (int i = 0; i < 3; ++i) {
+ sincos(a[i].x, &b->x, &c[i].x);
+ sincos(a[i].y, &b->y, &c[i].y);
+ sincos(a[i].z, &b->z, &c[i].z);
+ }
+}
+ccl_device_extern void osl_sincos_dvdvdv(ccl_private const float3 *a,
+ ccl_private float3 *b,
+ ccl_private float3 *c)
+{
+ for (int i = 0; i < 3; ++i) {
+ sincos(a[i].x, &b[i].x, &c[i].x);
+ sincos(a[i].y, &b[i].y, &c[i].y);
+ sincos(a[i].z, &b[i].z, &c[i].z);
+ }
+}
+
+OSL_OP_IMPL_XX(osl_log, logf)
+OSL_OP_IMPL_XX(osl_log2, log2f)
+OSL_OP_IMPL_XX(osl_log10, log10f)
+OSL_OP_IMPL_XX(osl_exp, expf)
+OSL_OP_IMPL_XX(osl_exp2, exp2f)
+OSL_OP_IMPL_XX(osl_expm1, expm1f)
+OSL_OP_IMPL_XX(osl_erf, erff)
+OSL_OP_IMPL_XX(osl_erfc, erfcf)
+
+OSL_OP_IMPL_XXX(osl_pow, safe_powf)
+OSL_OP_IMPL_VVF_(osl_pow, safe_powf)
+OSL_OP_IMPL_DVVDF_(osl_pow, safe_powf)
+OSL_OP_IMPL_DVDVF_(osl_pow, safe_powf)
+OSL_OP_IMPL_DVDVDF_(osl_pow, safe_powf)
+
+OSL_OP_IMPL_XX(osl_sqrt, sqrtf)
+OSL_OP_IMPL_XX(osl_inversesqrt, 1.0f / sqrtf)
+OSL_OP_IMPL_XX(osl_cbrt, cbrtf)
+
+OSL_OP_IMPL_FF(osl_logb, logbf)
+OSL_OP_IMPL_VV_(osl_logb, logbf)
+
+OSL_OP_IMPL_FF(osl_floor, floorf)
+OSL_OP_IMPL_VV_(osl_floor, floorf)
+OSL_OP_IMPL_FF(osl_ceil, ceilf)
+OSL_OP_IMPL_VV_(osl_ceil, ceilf)
+OSL_OP_IMPL_FF(osl_round, roundf)
+OSL_OP_IMPL_VV_(osl_round, roundf)
+OSL_OP_IMPL_FF(osl_trunc, truncf)
+OSL_OP_IMPL_VV_(osl_trunc, truncf)
+
+ccl_device_forceinline float step_impl(float edge, float x)
+{
+ return x < edge ? 0.0f : 1.0f;
+}
+
+OSL_OP_IMPL_FF(osl_sign, compatible_signf)
+OSL_OP_IMPL_VV_(osl_sign, compatible_signf)
+OSL_OP_IMPL_FFF(osl_step, step_impl)
+OSL_OP_IMPL_VVV_(osl_step, step_impl)
+
+OSL_OP_IMPL_IF(osl_isnan, isnan)
+OSL_OP_IMPL_IF(osl_isinf, isinf)
+OSL_OP_IMPL_IF(osl_isfinite, isfinite)
+
+OSL_OP_IMPL_II(osl_abs, abs)
+OSL_OP_IMPL_XX(osl_abs, fabsf)
+OSL_OP_IMPL_II(osl_fabs, abs)
+OSL_OP_IMPL_XX(osl_fabs, fabsf)
+OSL_OP_IMPL_XXX(osl_fmod, safe_modulo)
+
+OSL_OP_IMPL_FFFF(osl_smoothstep, smoothstep)
+OSL_OP_IMPL_DFFFDF(osl_smoothstep, smoothstep)
+OSL_OP_IMPL_DFFDFF(osl_smoothstep, smoothstep)
+OSL_OP_IMPL_DFFDFDF(osl_smoothstep, smoothstep)
+OSL_OP_IMPL_DFDFFF(osl_smoothstep, smoothstep)
+OSL_OP_IMPL_DFDFFDF(osl_smoothstep, smoothstep)
+OSL_OP_IMPL_DFDFDFF(osl_smoothstep, smoothstep)
+OSL_OP_IMPL_DFDFDFDF(osl_smoothstep, smoothstep)
+
+OSL_OP_IMPL_FVV(osl_dot, dot)
+OSL_OP_IMPL_DFDVV(osl_dot, dot)
+OSL_OP_IMPL_DFVDV(osl_dot, dot)
+OSL_OP_IMPL_DFDVDV(osl_dot, dot)
+OSL_OP_IMPL_VVV(osl_cross, cross)
+OSL_OP_IMPL_DVDVV(osl_cross, cross)
+OSL_OP_IMPL_DVVDV(osl_cross, cross)
+OSL_OP_IMPL_DVDVDV(osl_cross, cross)
+OSL_OP_IMPL_FV(osl_length, len)
+OSL_OP_IMPL_DFDV(osl_length, len)
+OSL_OP_IMPL_FVV(osl_distance, distance)
+OSL_OP_IMPL_DFDVV(osl_distance, distance)
+OSL_OP_IMPL_DFVDV(osl_distance, distance)
+OSL_OP_IMPL_DFDVDV(osl_distance, distance)
+OSL_OP_IMPL_VV(osl_normalize, safe_normalize)
+OSL_OP_IMPL_DVDV(osl_normalize, safe_normalize)
+
+ccl_device_extern void osl_calculatenormal(ccl_private float3 *res,
+ ccl_private ShaderGlobals *sg,
+ ccl_private const float3 *p)
+{
+ if (sg->flipHandedness)
+ *res = cross(p[2], p[1]);
+ else
+ *res = cross(p[1], p[2]);
+}
+
+ccl_device_extern float osl_area(ccl_private const float3 *p)
+{
+ return len(cross(p[2], p[1]));
+}
+
+ccl_device_extern float osl_filterwidth_fdf(ccl_private const float *x)
+{
+ return sqrtf(x[1] * x[1] + x[2] * x[2]);
+}
+
+ccl_device_extern void osl_filterwidth_vdv(ccl_private float *res, ccl_private const float *x)
+{
+ for (int i = 0; i < 3; ++i)
+ res[i] = osl_filterwidth_fdf(x + i);
+}
+
+ccl_device_extern bool osl_raytype_bit(ccl_private ShaderGlobals *sg, int bit)
+{
+ return (sg->raytype & bit) != 0;
+}
diff --git a/intern/cycles/kernel/osl/services_optix.cu b/intern/cycles/kernel/osl/services_optix.cu
new file mode 100644
index 00000000000..2a43a89a956
--- /dev/null
+++ b/intern/cycles/kernel/osl/services_optix.cu
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#define WITH_OSL
+
+// clang-format off
+#include "kernel/device/optix/compat.h"
+#include "kernel/device/optix/globals.h"
+
+#include "kernel/device/gpu/image.h" /* Texture lookup uses normal CUDA intrinsics. */
+
+#include "kernel/osl/services_gpu.h"
+// clang-format on
+
+extern "C" __device__ void __direct_callable__dummy_services()
+{
+}
diff --git a/intern/cycles/kernel/osl/types.h b/intern/cycles/kernel/osl/types.h
index 46e06114360..717306a3d07 100644
--- a/intern/cycles/kernel/osl/types.h
+++ b/intern/cycles/kernel/osl/types.h
@@ -5,9 +5,53 @@
CCL_NAMESPACE_BEGIN
+struct DeviceString {
+#if defined(__KERNEL_GPU__)
+ /* Strings are represented by their hashes in CUDA and OptiX. */
+ size_t str_;
+
+ ccl_device_inline_method uint64_t hash() const
+ {
+ return str_;
+ }
+#elif defined(OPENIMAGEIO_USTRING_H)
+ ustring str_;
+
+ ccl_device_inline_method uint64_t hash() const
+ {
+ return str_.hash();
+ }
+#else
+ const char *str_;
+#endif
+
+ ccl_device_inline_method bool operator==(DeviceString b) const
+ {
+ return str_ == b.str_;
+ }
+ ccl_device_inline_method bool operator!=(DeviceString b) const
+ {
+ return str_ != b.str_;
+ }
+};
+
+ccl_device_inline DeviceString make_string(const char *str, size_t hash)
+{
+#if defined(__KERNEL_GPU__)
+ (void)str;
+ return {hash};
+#elif defined(OPENIMAGEIO_USTRING_H)
+ (void)hash;
+ return {ustring(str)};
+#else
+ (void)hash;
+ return {str};
+#endif
+}
+
/* Closure */
-enum ClosureTypeOSL {
+enum OSLClosureType {
OSL_CLOSURE_MUL_ID = -1,
OSL_CLOSURE_ADD_ID = -2,
@@ -17,4 +61,60 @@ enum ClosureTypeOSL {
#include "closures_template.h"
};
+struct OSLClosure {
+ OSLClosureType id;
+};
+
+struct ccl_align(8) OSLClosureMul : public OSLClosure
+{
+ packed_float3 weight;
+ ccl_private const OSLClosure *closure;
+};
+
+struct ccl_align(8) OSLClosureAdd : public OSLClosure
+{
+ ccl_private const OSLClosure *closureA;
+ ccl_private const OSLClosure *closureB;
+};
+
+struct ccl_align(8) OSLClosureComponent : public OSLClosure
+{
+ packed_float3 weight;
+};
+
+/* Globals */
+
+struct ShaderGlobals {
+ packed_float3 P, dPdx, dPdy;
+ packed_float3 dPdz;
+ packed_float3 I, dIdx, dIdy;
+ packed_float3 N;
+ packed_float3 Ng;
+ float u, dudx, dudy;
+ float v, dvdx, dvdy;
+ packed_float3 dPdu, dPdv;
+ float time;
+ float dtime;
+ packed_float3 dPdtime;
+ packed_float3 Ps, dPsdx, dPsdy;
+ ccl_private void *renderstate;
+ ccl_private void *tracedata;
+ ccl_private void *objdata;
+ void *context;
+ void *renderer;
+ ccl_private void *object2common;
+ ccl_private void *shader2common;
+ ccl_private OSLClosure *Ci;
+ float surfacearea;
+ int raytype;
+ int flipHandedness;
+ int backfacing;
+};
+
+struct OSLNoiseOptions {
+};
+
+struct OSLTextureOptions {
+};
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/sample/pattern.h b/intern/cycles/kernel/sample/pattern.h
index ebdecc1bff9..e12f333b3a5 100644
--- a/intern/cycles/kernel/sample/pattern.h
+++ b/intern/cycles/kernel/sample/pattern.h
@@ -100,7 +100,7 @@ ccl_device_inline bool sample_is_class_A(int pattern, int sample)
if (!(pattern == SAMPLING_PATTERN_PMJ || pattern == SAMPLING_PATTERN_SOBOL_BURLEY)) {
/* Fallback: assign samples randomly.
* This is guaranteed to work "okay" for any sampler, but isn't good.
- * (Note: the seed constant is just a random number to guard against
+ * (NOTE: the seed constant is just a random number to guard against
* possible interactions with other uses of the hash. There's nothing
* special about it.)
*/
diff --git a/intern/cycles/kernel/svm/closure.h b/intern/cycles/kernel/svm/closure.h
index 2d91b014f60..d18f2cc0854 100644
--- a/intern/cycles/kernel/svm/closure.h
+++ b/intern/cycles/kernel/svm/closure.h
@@ -31,7 +31,7 @@ ccl_device void svm_node_glass_setup(ccl_private ShaderData *sd,
else {
bsdf->alpha_y = 0.0f;
bsdf->alpha_x = 0.0f;
- bsdf->ior = 0.0f;
+ bsdf->ior = eta;
sd->flag |= bsdf_reflection_setup(bsdf);
}
}
@@ -542,7 +542,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
float roughness = sqr(param1);
bsdf->N = N;
- bsdf->ior = 0.0f;
+ bsdf->ior = 1.0f;
bsdf->extra = NULL;
if (data_node.y == SVM_STACK_INVALID) {
diff --git a/intern/cycles/kernel/svm/noise.h b/intern/cycles/kernel/svm/noise.h
index 31e77d87413..209195a03f1 100644
--- a/intern/cycles/kernel/svm/noise.h
+++ b/intern/cycles/kernel/svm/noise.h
@@ -39,11 +39,11 @@ ccl_device_noinline_cpu float perlin_1d(float x)
}
/* 2D, 3D, and 4D noise can be accelerated using SSE, so we first check if
- * SSE is supported, that is, if __KERNEL_SSE2__ is defined. If it is not
+ * SSE is supported, that is, if __KERNEL_SSE__ is defined. If it is not
* supported, we do a standard implementation, but if it is supported, we
* do an implementation using SSE intrinsics.
*/
-#if !defined(__KERNEL_SSE2__)
+#if !defined(__KERNEL_SSE__)
/* ** Standard Implementation ** */
@@ -250,18 +250,18 @@ ccl_device_noinline_cpu float perlin_4d(float x, float y, float z, float w)
/* SSE Bilinear Interpolation:
*
- * The function takes two ssef inputs:
+ * The function takes two float4 inputs:
* - p : Contains the values at the points (v0, v1, v2, v3).
* - f : Contains the values (x, y, _, _). The third and fourth values are unused.
*
* The interpolation is done in two steps:
* 1. Interpolate (v0, v1) and (v2, v3) along the x axis to get g (g0, g1).
* (v2, v3) is generated by moving v2 and v3 to the first and second
- * places of the ssef using the shuffle mask <2, 3, 2, 3>. The third and
+ * places of the float4 using the shuffle mask <2, 3, 2, 3>. The third and
* fourth values are unused.
* 2. Interpolate g0 and g1 along the y axis to get the final value.
- * g1 is generated by populating an ssef with the second value of g.
- * Only the first value is important in the final ssef.
+ * g1 is generated by populating an float4 with the second value of g.
+ * Only the first value is important in the final float4.
*
* v1 v3 g1
* @ + + + + @ @ y
@@ -272,27 +272,27 @@ ccl_device_noinline_cpu float perlin_4d(float x, float y, float z, float w)
* v0 v2 g0
*
*/
-ccl_device_inline ssef bi_mix(ssef p, ssef f)
+ccl_device_inline float4 bi_mix(float4 p, float4 f)
{
- ssef g = mix(p, shuffle<2, 3, 2, 3>(p), shuffle<0>(f));
+ float4 g = mix(p, shuffle<2, 3, 2, 3>(p), shuffle<0>(f));
return mix(g, shuffle<1>(g), shuffle<1>(f));
}
-ccl_device_inline ssef fade(const ssef &t)
+ccl_device_inline float4 fade(const float4 t)
{
- ssef a = madd(t, 6.0f, -15.0f);
- ssef b = madd(t, a, 10.0f);
+ float4 a = madd(t, make_float4(6.0f), make_float4(-15.0f));
+ float4 b = madd(t, a, make_float4(10.0f));
return (t * t) * (t * b);
}
/* Negate val if the nth bit of h is 1. */
# define negate_if_nth_bit(val, h, n) ((val) ^ cast(((h) & (1 << (n))) << (31 - (n))))
-ccl_device_inline ssef grad(const ssei &hash, const ssef &x, const ssef &y)
+ccl_device_inline float4 grad(const int4 hash, const float4 x, const float4 y)
{
- ssei h = hash & 7;
- ssef u = select(h < 4, x, y);
- ssef v = 2.0f * select(h < 4, y, x);
+ int4 h = hash & 7;
+ float4 u = select(h < 4, x, y);
+ float4 v = 2.0f * select(h < 4, y, x);
return negate_if_nth_bit(u, h, 0) + negate_if_nth_bit(v, h, 1);
}
@@ -310,28 +310,28 @@ ccl_device_inline ssef grad(const ssei &hash, const ssef &x, const ssef &y)
*/
ccl_device_noinline_cpu float perlin_2d(float x, float y)
{
- ssei XY;
- ssef fxy = floorfrac(ssef(x, y, 0.0f, 0.0f), &XY);
- ssef uv = fade(fxy);
+ int4 XY;
+ float4 fxy = floorfrac(make_float4(x, y, 0.0f, 0.0f), &XY);
+ float4 uv = fade(fxy);
- ssei XY1 = XY + 1;
- ssei X = shuffle<0, 0, 0, 0>(XY, XY1);
- ssei Y = shuffle<0, 2, 0, 2>(shuffle<1, 1, 1, 1>(XY, XY1));
+ int4 XY1 = XY + make_int4(1);
+ int4 X = shuffle<0, 0, 0, 0>(XY, XY1);
+ int4 Y = shuffle<0, 2, 0, 2>(shuffle<1, 1, 1, 1>(XY, XY1));
- ssei h = hash_ssei2(X, Y);
+ int4 h = hash_int4_2(X, Y);
- ssef fxy1 = fxy - 1.0f;
- ssef fx = shuffle<0, 0, 0, 0>(fxy, fxy1);
- ssef fy = shuffle<0, 2, 0, 2>(shuffle<1, 1, 1, 1>(fxy, fxy1));
+ float4 fxy1 = fxy - make_float4(1.0f);
+ float4 fx = shuffle<0, 0, 0, 0>(fxy, fxy1);
+ float4 fy = shuffle<0, 2, 0, 2>(shuffle<1, 1, 1, 1>(fxy, fxy1));
- ssef g = grad(h, fx, fy);
+ float4 g = grad(h, fx, fy);
return extract<0>(bi_mix(g, uv));
}
/* SSE Trilinear Interpolation:
*
- * The function takes three ssef inputs:
+ * The function takes three float4 inputs:
* - p : Contains the values at the points (v0, v1, v2, v3).
* - q : Contains the values at the points (v4, v5, v6, v7).
* - f : Contains the values (x, y, z, _). The fourth value is unused.
@@ -340,11 +340,11 @@ ccl_device_noinline_cpu float perlin_2d(float x, float y)
* 1. Interpolate p and q along the x axis to get s (s0, s1, s2, s3).
* 2. Interpolate (s0, s1) and (s2, s3) along the y axis to get g (g0, g1).
* (s2, s3) is generated by moving v2 and v3 to the first and second
- * places of the ssef using the shuffle mask <2, 3, 2, 3>. The third and
+ * places of the float4 using the shuffle mask <2, 3, 2, 3>. The third and
* fourth values are unused.
* 3. Interpolate g0 and g1 along the z axis to get the final value.
- * g1 is generated by populating an ssef with the second value of g.
- * Only the first value is important in the final ssef.
+ * g1 is generated by populating an float4 with the second value of g.
+ * Only the first value is important in the final float4.
*
* v3 v7
* @ + + + + + + @ s3 @
@@ -362,10 +362,10 @@ ccl_device_noinline_cpu float perlin_2d(float x, float y)
* @ + + + + + + @ @
* v0 v4 s0
*/
-ccl_device_inline ssef tri_mix(ssef p, ssef q, ssef f)
+ccl_device_inline float4 tri_mix(float4 p, float4 q, float4 f)
{
- ssef s = mix(p, q, shuffle<0>(f));
- ssef g = mix(s, shuffle<2, 3, 2, 3>(s), shuffle<1>(f));
+ float4 s = mix(p, q, shuffle<0>(f));
+ float4 g = mix(s, shuffle<2, 3, 2, 3>(s), shuffle<1>(f));
return mix(g, shuffle<1>(g), shuffle<2>(f));
}
@@ -374,24 +374,24 @@ ccl_device_inline ssef tri_mix(ssef p, ssef q, ssef f)
* supported, we do an SSE implementation, but if it is supported,
* we do an implementation using AVX intrinsics.
*/
-# if !defined(__KERNEL_AVX__)
+# if !defined(__KERNEL_AVX2__)
-ccl_device_inline ssef grad(const ssei &hash, const ssef &x, const ssef &y, const ssef &z)
+ccl_device_inline float4 grad(const int4 hash, const float4 x, const float4 y, const float4 z)
{
- ssei h = hash & 15;
- ssef u = select(h < 8, x, y);
- ssef vt = select((h == 12) | (h == 14), x, z);
- ssef v = select(h < 4, y, vt);
+ int4 h = hash & 15;
+ float4 u = select(h < 8, x, y);
+ float4 vt = select((h == 12) | (h == 14), x, z);
+ float4 v = select(h < 4, y, vt);
return negate_if_nth_bit(u, h, 0) + negate_if_nth_bit(v, h, 1);
}
-ccl_device_inline ssef
-grad(const ssei &hash, const ssef &x, const ssef &y, const ssef &z, const ssef &w)
+ccl_device_inline float4
+grad(const int4 hash, const float4 x, const float4 y, const float4 z, const float4 w)
{
- ssei h = hash & 31;
- ssef u = select(h < 24, x, y);
- ssef v = select(h < 16, y, z);
- ssef s = select(h < 8, z, w);
+ int4 h = hash & 31;
+ float4 u = select(h < 24, x, y);
+ float4 v = select(h < 16, y, z);
+ float4 s = select(h < 8, z, w);
return negate_if_nth_bit(u, h, 0) + negate_if_nth_bit(v, h, 1) + negate_if_nth_bit(s, h, 2);
}
@@ -401,7 +401,7 @@ grad(const ssei &hash, const ssef &x, const ssef &y, const ssef &z, const ssef &
* between two trilinear interpolations.
*
*/
-ccl_device_inline ssef quad_mix(ssef p, ssef q, ssef r, ssef s, ssef f)
+ccl_device_inline float4 quad_mix(float4 p, float4 q, float4 r, float4 s, float4 f)
{
return mix(tri_mix(p, q, f), tri_mix(r, s, f), shuffle<3>(f));
}
@@ -427,23 +427,23 @@ ccl_device_inline ssef quad_mix(ssef p, ssef q, ssef r, ssef s, ssef f)
*/
ccl_device_noinline_cpu float perlin_3d(float x, float y, float z)
{
- ssei XYZ;
- ssef fxyz = floorfrac(ssef(x, y, z, 0.0f), &XYZ);
- ssef uvw = fade(fxyz);
+ int4 XYZ;
+ float4 fxyz = floorfrac(make_float4(x, y, z, 0.0f), &XYZ);
+ float4 uvw = fade(fxyz);
- ssei XYZ1 = XYZ + 1;
- ssei Y = shuffle<1, 1, 1, 1>(XYZ, XYZ1);
- ssei Z = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(XYZ, XYZ1));
+ int4 XYZ1 = XYZ + make_int4(1);
+ int4 Y = shuffle<1, 1, 1, 1>(XYZ, XYZ1);
+ int4 Z = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(XYZ, XYZ1));
- ssei h1 = hash_ssei3(shuffle<0>(XYZ), Y, Z);
- ssei h2 = hash_ssei3(shuffle<0>(XYZ1), Y, Z);
+ int4 h1 = hash_int4_3(shuffle<0>(XYZ), Y, Z);
+ int4 h2 = hash_int4_3(shuffle<0>(XYZ1), Y, Z);
- ssef fxyz1 = fxyz - 1.0f;
- ssef fy = shuffle<1, 1, 1, 1>(fxyz, fxyz1);
- ssef fz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(fxyz, fxyz1));
+ float4 fxyz1 = fxyz - make_float4(1.0f);
+ float4 fy = shuffle<1, 1, 1, 1>(fxyz, fxyz1);
+ float4 fz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(fxyz, fxyz1));
- ssef g1 = grad(h1, shuffle<0>(fxyz), fy, fz);
- ssef g2 = grad(h2, shuffle<0>(fxyz1), fy, fz);
+ float4 g1 = grad(h1, shuffle<0>(fxyz), fy, fz);
+ float4 g2 = grad(h2, shuffle<0>(fxyz1), fy, fz);
return extract<0>(tri_mix(g1, g2, uvw));
}
@@ -481,29 +481,29 @@ ccl_device_noinline_cpu float perlin_3d(float x, float y, float z)
*/
ccl_device_noinline_cpu float perlin_4d(float x, float y, float z, float w)
{
- ssei XYZW;
- ssef fxyzw = floorfrac(ssef(x, y, z, w), &XYZW);
- ssef uvws = fade(fxyzw);
+ int4 XYZW;
+ float4 fxyzw = floorfrac(make_float4(x, y, z, w), &XYZW);
+ float4 uvws = fade(fxyzw);
- ssei XYZW1 = XYZW + 1;
- ssei Y = shuffle<1, 1, 1, 1>(XYZW, XYZW1);
- ssei Z = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(XYZW, XYZW1));
+ int4 XYZW1 = XYZW + make_int4(1);
+ int4 Y = shuffle<1, 1, 1, 1>(XYZW, XYZW1);
+ int4 Z = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(XYZW, XYZW1));
- ssei h1 = hash_ssei4(shuffle<0>(XYZW), Y, Z, shuffle<3>(XYZW));
- ssei h2 = hash_ssei4(shuffle<0>(XYZW1), Y, Z, shuffle<3>(XYZW));
+ int4 h1 = hash_int4_4(shuffle<0>(XYZW), Y, Z, shuffle<3>(XYZW));
+ int4 h2 = hash_int4_4(shuffle<0>(XYZW1), Y, Z, shuffle<3>(XYZW));
- ssei h3 = hash_ssei4(shuffle<0>(XYZW), Y, Z, shuffle<3>(XYZW1));
- ssei h4 = hash_ssei4(shuffle<0>(XYZW1), Y, Z, shuffle<3>(XYZW1));
+ int4 h3 = hash_int4_4(shuffle<0>(XYZW), Y, Z, shuffle<3>(XYZW1));
+ int4 h4 = hash_int4_4(shuffle<0>(XYZW1), Y, Z, shuffle<3>(XYZW1));
- ssef fxyzw1 = fxyzw - 1.0f;
- ssef fy = shuffle<1, 1, 1, 1>(fxyzw, fxyzw1);
- ssef fz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(fxyzw, fxyzw1));
+ float4 fxyzw1 = fxyzw - make_float4(1.0f);
+ float4 fy = shuffle<1, 1, 1, 1>(fxyzw, fxyzw1);
+ float4 fz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(fxyzw, fxyzw1));
- ssef g1 = grad(h1, shuffle<0>(fxyzw), fy, fz, shuffle<3>(fxyzw));
- ssef g2 = grad(h2, shuffle<0>(fxyzw1), fy, fz, shuffle<3>(fxyzw));
+ float4 g1 = grad(h1, shuffle<0>(fxyzw), fy, fz, shuffle<3>(fxyzw));
+ float4 g2 = grad(h2, shuffle<0>(fxyzw1), fy, fz, shuffle<3>(fxyzw));
- ssef g3 = grad(h3, shuffle<0>(fxyzw), fy, fz, shuffle<3>(fxyzw1));
- ssef g4 = grad(h4, shuffle<0>(fxyzw1), fy, fz, shuffle<3>(fxyzw1));
+ float4 g3 = grad(h3, shuffle<0>(fxyzw), fy, fz, shuffle<3>(fxyzw1));
+ float4 g4 = grad(h4, shuffle<0>(fxyzw1), fy, fz, shuffle<3>(fxyzw1));
return extract<0>(quad_mix(g1, g2, g3, g4, uvws));
}
@@ -512,22 +512,22 @@ ccl_device_noinline_cpu float perlin_4d(float x, float y, float z, float w)
/* AVX Implementation */
-ccl_device_inline avxf grad(const avxi &hash, const avxf &x, const avxf &y, const avxf &z)
+ccl_device_inline vfloat8 grad(const vint8 hash, const vfloat8 x, const vfloat8 y, const vfloat8 z)
{
- avxi h = hash & 15;
- avxf u = select(h < 8, x, y);
- avxf vt = select((h == 12) | (h == 14), x, z);
- avxf v = select(h < 4, y, vt);
+ vint8 h = hash & 15;
+ vfloat8 u = select(h < 8, x, y);
+ vfloat8 vt = select((h == 12) | (h == 14), x, z);
+ vfloat8 v = select(h < 4, y, vt);
return negate_if_nth_bit(u, h, 0) + negate_if_nth_bit(v, h, 1);
}
-ccl_device_inline avxf
-grad(const avxi &hash, const avxf &x, const avxf &y, const avxf &z, const avxf &w)
+ccl_device_inline vfloat8
+grad(const vint8 hash, const vfloat8 x, const vfloat8 y, const vfloat8 z, const vfloat8 w)
{
- avxi h = hash & 31;
- avxf u = select(h < 24, x, y);
- avxf v = select(h < 16, y, z);
- avxf s = select(h < 8, z, w);
+ vint8 h = hash & 31;
+ vfloat8 u = select(h < 24, x, y);
+ vfloat8 v = select(h < 16, y, z);
+ vfloat8 s = select(h < 8, z, w);
return negate_if_nth_bit(u, h, 0) + negate_if_nth_bit(v, h, 1) + negate_if_nth_bit(s, h, 2);
}
@@ -537,13 +537,13 @@ grad(const avxi &hash, const avxf &x, const avxf &y, const avxf &z, const avxf &
* 1. Interpolate p and q along the w axis to get s.
* 2. Trilinearly interpolate (s0, s1, s2, s3) and (s4, s5, s6, s7) to get the final
* value. (s0, s1, s2, s3) and (s4, s5, s6, s7) are generated by extracting the
- * low and high ssef from s.
+ * low and high float4 from s.
*
*/
-ccl_device_inline ssef quad_mix(avxf p, avxf q, ssef f)
+ccl_device_inline float4 quad_mix(vfloat8 p, vfloat8 q, float4 f)
{
- ssef fv = shuffle<3>(f);
- avxf s = mix(p, q, avxf(fv, fv));
+ float4 fv = shuffle<3>(f);
+ vfloat8 s = mix(p, q, make_vfloat8(fv, fv));
return tri_mix(low(s), high(s), f);
}
@@ -565,25 +565,25 @@ ccl_device_inline ssef quad_mix(avxf p, avxf q, ssef f)
*/
ccl_device_noinline_cpu float perlin_3d(float x, float y, float z)
{
- ssei XYZ;
- ssef fxyz = floorfrac(ssef(x, y, z, 0.0f), &XYZ);
- ssef uvw = fade(fxyz);
+ int4 XYZ;
+ float4 fxyz = floorfrac(make_float4(x, y, z, 0.0f), &XYZ);
+ float4 uvw = fade(fxyz);
- ssei XYZ1 = XYZ + 1;
- ssei X = shuffle<0>(XYZ);
- ssei X1 = shuffle<0>(XYZ1);
- ssei Y = shuffle<1, 1, 1, 1>(XYZ, XYZ1);
- ssei Z = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(XYZ, XYZ1));
+ int4 XYZ1 = XYZ + make_int4(1);
+ int4 X = shuffle<0>(XYZ);
+ int4 X1 = shuffle<0>(XYZ1);
+ int4 Y = shuffle<1, 1, 1, 1>(XYZ, XYZ1);
+ int4 Z = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(XYZ, XYZ1));
- avxi h = hash_avxi3(avxi(X, X1), avxi(Y, Y), avxi(Z, Z));
+ vint8 h = hash_int8_3(make_vint8(X, X1), make_vint8(Y, Y), make_vint8(Z, Z));
- ssef fxyz1 = fxyz - 1.0f;
- ssef fx = shuffle<0>(fxyz);
- ssef fx1 = shuffle<0>(fxyz1);
- ssef fy = shuffle<1, 1, 1, 1>(fxyz, fxyz1);
- ssef fz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(fxyz, fxyz1));
+ float4 fxyz1 = fxyz - make_float4(1.0f);
+ float4 fx = shuffle<0>(fxyz);
+ float4 fx1 = shuffle<0>(fxyz1);
+ float4 fy = shuffle<1, 1, 1, 1>(fxyz, fxyz1);
+ float4 fz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(fxyz, fxyz1));
- avxf g = grad(h, avxf(fx, fx1), avxf(fy, fy), avxf(fz, fz));
+ vfloat8 g = grad(h, make_vfloat8(fx, fx1), make_vfloat8(fy, fy), make_vfloat8(fz, fz));
return extract<0>(tri_mix(low(g), high(g), uvw));
}
@@ -617,31 +617,37 @@ ccl_device_noinline_cpu float perlin_3d(float x, float y, float z)
*/
ccl_device_noinline_cpu float perlin_4d(float x, float y, float z, float w)
{
- ssei XYZW;
- ssef fxyzw = floorfrac(ssef(x, y, z, w), &XYZW);
- ssef uvws = fade(fxyzw);
-
- ssei XYZW1 = XYZW + 1;
- ssei X = shuffle<0>(XYZW);
- ssei X1 = shuffle<0>(XYZW1);
- ssei Y = shuffle<1, 1, 1, 1>(XYZW, XYZW1);
- ssei Z = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(XYZW, XYZW1));
- ssei W = shuffle<3>(XYZW);
- ssei W1 = shuffle<3>(XYZW1);
-
- avxi h1 = hash_avxi4(avxi(X, X1), avxi(Y, Y), avxi(Z, Z), avxi(W, W));
- avxi h2 = hash_avxi4(avxi(X, X1), avxi(Y, Y), avxi(Z, Z), avxi(W1, W1));
-
- ssef fxyzw1 = fxyzw - 1.0f;
- ssef fx = shuffle<0>(fxyzw);
- ssef fx1 = shuffle<0>(fxyzw1);
- ssef fy = shuffle<1, 1, 1, 1>(fxyzw, fxyzw1);
- ssef fz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(fxyzw, fxyzw1));
- ssef fw = shuffle<3>(fxyzw);
- ssef fw1 = shuffle<3>(fxyzw1);
-
- avxf g1 = grad(h1, avxf(fx, fx1), avxf(fy, fy), avxf(fz, fz), avxf(fw, fw));
- avxf g2 = grad(h2, avxf(fx, fx1), avxf(fy, fy), avxf(fz, fz), avxf(fw1, fw1));
+ int4 XYZW;
+ float4 fxyzw = floorfrac(make_float4(x, y, z, w), &XYZW);
+ float4 uvws = fade(fxyzw);
+
+ int4 XYZW1 = XYZW + make_int4(1);
+ int4 X = shuffle<0>(XYZW);
+ int4 X1 = shuffle<0>(XYZW1);
+ int4 Y = shuffle<1, 1, 1, 1>(XYZW, XYZW1);
+ int4 Z = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(XYZW, XYZW1));
+ int4 W = shuffle<3>(XYZW);
+ int4 W1 = shuffle<3>(XYZW1);
+
+ vint8 h1 = hash_int8_4(make_vint8(X, X1), make_vint8(Y, Y), make_vint8(Z, Z), make_vint8(W, W));
+ vint8 h2 = hash_int8_4(
+ make_vint8(X, X1), make_vint8(Y, Y), make_vint8(Z, Z), make_vint8(W1, W1));
+
+ float4 fxyzw1 = fxyzw - make_float4(1.0f);
+ float4 fx = shuffle<0>(fxyzw);
+ float4 fx1 = shuffle<0>(fxyzw1);
+ float4 fy = shuffle<1, 1, 1, 1>(fxyzw, fxyzw1);
+ float4 fz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(fxyzw, fxyzw1));
+ float4 fw = shuffle<3>(fxyzw);
+ float4 fw1 = shuffle<3>(fxyzw1);
+
+ vfloat8 g1 = grad(
+ h1, make_vfloat8(fx, fx1), make_vfloat8(fy, fy), make_vfloat8(fz, fz), make_vfloat8(fw, fw));
+ vfloat8 g2 = grad(h2,
+ make_vfloat8(fx, fx1),
+ make_vfloat8(fy, fy),
+ make_vfloat8(fz, fz),
+ make_vfloat8(fw1, fw1));
return extract<0>(quad_mix(g1, g2, uvws));
}
diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h
index bd3791594e0..a6f8914a9b8 100644
--- a/intern/cycles/kernel/types.h
+++ b/intern/cycles/kernel/types.h
@@ -75,16 +75,23 @@ CCL_NAMESPACE_BEGIN
#define __VOLUME__
/* Device specific features */
+#ifdef WITH_OSL
+# define __OSL__
+# ifdef __KERNEL_OPTIX__
+/* Kernels with OSL support are built separately in OptiX and don't need SVM. */
+# undef __SVM__
+# endif
+#endif
#ifndef __KERNEL_GPU__
-# ifdef WITH_OSL
-# define __OSL__
+# ifdef WITH_PATH_GUIDING
+# define __PATH_GUIDING__
# endif
# define __VOLUME_RECORD_ALL__
#endif /* !__KERNEL_GPU__ */
-/* MNEE currently causes "Compute function exceeds available temporary registers"
- * on Metal, disabled for now. */
-#ifndef __KERNEL_METAL__
+/* MNEE caused "Compute function exceeds available temporary registers" in macOS < 13 due to a bug
+ * in spill buffer allocation sizing. */
+#if !defined(__KERNEL_METAL__) || (__KERNEL_METAL_MACOS__ >= 13)
# define __MNEE__
#endif
@@ -146,12 +153,14 @@ enum PathTraceDimension {
PRNG_SURFACE_BSDF = 3,
PRNG_SURFACE_AO = 4,
PRNG_SURFACE_BEVEL = 5,
+ PRNG_SURFACE_BSDF_GUIDING = 6,
/* Volume */
PRNG_VOLUME_PHASE = 3,
PRNG_VOLUME_PHASE_CHANNEL = 4,
PRNG_VOLUME_SCATTER_DISTANCE = 5,
PRNG_VOLUME_OFFSET = 6,
PRNG_VOLUME_SHADE_OFFSET = 7,
+ PRNG_VOLUME_PHASE_GUIDING = 8,
/* Subsurface random walk bounces */
PRNG_SUBSURFACE_BSDF = 0,
@@ -387,6 +396,14 @@ typedef enum PassType {
PASS_SHADOW_CATCHER_SAMPLE_COUNT,
PASS_SHADOW_CATCHER_MATTE,
+ /* Guiding related debug rendering passes */
+ /* The estimated sample color from the PathSegmentStorage. If everything is integrated correctly
+ * the output should be similar to PASS_COMBINED. */
+ PASS_GUIDING_COLOR,
+ /* The guiding probability at the first bounce. */
+ PASS_GUIDING_PROBABILITY,
+ /* The avg. roughness at the first bounce. */
+ PASS_GUIDING_AVG_ROUGHNESS,
PASS_CATEGORY_DATA_END = 63,
PASS_BAKE_PRIMITIVE,
@@ -455,6 +472,16 @@ typedef enum LightType {
LIGHT_TRIANGLE
} LightType;
+/* Guiding Distribution Type */
+
+typedef enum GuidingDistributionType {
+ GUIDING_TYPE_PARALLAX_AWARE_VMM = 0,
+ GUIDING_TYPE_DIRECTIONAL_QUAD_TREE = 1,
+ GUIDING_TYPE_VMM = 2,
+
+ GUIDING_NUM_TYPES,
+} GuidingDistributionType;
+
/* Camera Type */
enum CameraType { CAMERA_PERSPECTIVE, CAMERA_ORTHOGRAPHIC, CAMERA_PANORAMA };
@@ -467,6 +494,7 @@ enum PanoramaType {
PANORAMA_FISHEYE_EQUISOLID = 2,
PANORAMA_MIRRORBALL = 3,
PANORAMA_FISHEYE_LENS_POLYNOMIAL = 4,
+ PANORAMA_EQUIANGULAR_CUBEMAP_FACE = 5,
PANORAMA_NUM_TYPES,
};
@@ -893,9 +921,13 @@ typedef struct ccl_align(16) ShaderData
float ray_dP;
#ifdef __OSL__
+# ifdef __KERNEL_GPU__
+ ccl_private uint8_t *osl_closure_pool;
+# else
const struct KernelGlobalsCPU *osl_globals;
const struct IntegratorStateCPU *osl_path_state;
const struct IntegratorShadowStateCPU *osl_shadow_path_state;
+# endif
#endif
/* LCG state for closures that require additional random numbers. */
@@ -1137,7 +1169,7 @@ typedef struct KernelBake {
int use;
int object_index;
int tri_offset;
- int pad1;
+ int use_camera;
} KernelBake;
static_assert_align(KernelBake, 16);
@@ -1502,6 +1534,12 @@ enum KernelFeatureFlag : uint32_t {
/* MNEE. */
KERNEL_FEATURE_MNEE = (1U << 25U),
+
+ /* Path guiding. */
+ KERNEL_FEATURE_PATH_GUIDING = (1U << 26U),
+
+ /* OSL. */
+ KERNEL_FEATURE_OSL = (1U << 27U),
};
/* Shader node feature mask, to specialize shader evaluation for kernels. */
diff --git a/intern/cycles/scene/CMakeLists.txt b/intern/cycles/scene/CMakeLists.txt
index 10a06ee595d..1bce93aa140 100644
--- a/intern/cycles/scene/CMakeLists.txt
+++ b/intern/cycles/scene/CMakeLists.txt
@@ -101,7 +101,7 @@ if(WITH_CYCLES_OSL)
cycles_kernel_osl
)
- SET_PROPERTY(SOURCE osl.cpp PROPERTY COMPILE_FLAGS ${RTTI_DISABLE_FLAGS})
+ set_property(SOURCE osl.cpp PROPERTY COMPILE_FLAGS ${RTTI_DISABLE_FLAGS})
endif()
if(WITH_OPENCOLORIO)
diff --git a/intern/cycles/scene/bake.cpp b/intern/cycles/scene/bake.cpp
index 1947b9d71a4..768e723b587 100644
--- a/intern/cycles/scene/bake.cpp
+++ b/intern/cycles/scene/bake.cpp
@@ -16,6 +16,7 @@ CCL_NAMESPACE_BEGIN
BakeManager::BakeManager()
{
need_update_ = true;
+ use_camera_ = false;
}
BakeManager::~BakeManager()
@@ -38,6 +39,14 @@ void BakeManager::set(Scene *scene, const std::string &object_name_)
need_update_ = true;
}
+void BakeManager::set_use_camera(const bool use_camera)
+{
+ if (use_camera_ != use_camera) {
+ use_camera_ = use_camera;
+ need_update_ = true;
+ }
+}
+
void BakeManager::device_update(Device * /*device*/,
DeviceScene *dscene,
Scene *scene,
@@ -49,6 +58,8 @@ void BakeManager::device_update(Device * /*device*/,
KernelBake *kbake = &dscene->data.bake;
memset(kbake, 0, sizeof(*kbake));
+ kbake->use_camera = use_camera_;
+
if (!object_name.empty()) {
scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {
diff --git a/intern/cycles/scene/bake.h b/intern/cycles/scene/bake.h
index 0d90ece5628..e3f3911ab05 100644
--- a/intern/cycles/scene/bake.h
+++ b/intern/cycles/scene/bake.h
@@ -20,6 +20,8 @@ class BakeManager {
void set(Scene *scene, const std::string &object_name);
bool get_baking() const;
+ void set_use_camera(bool use_camera);
+
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
void device_free(Device *device, DeviceScene *dscene);
@@ -30,6 +32,7 @@ class BakeManager {
private:
bool need_update_;
std::string object_name;
+ bool use_camera_;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/scene/camera.cpp b/intern/cycles/scene/camera.cpp
index 240e5d9c128..255dd320ec7 100644
--- a/intern/cycles/scene/camera.cpp
+++ b/intern/cycles/scene/camera.cpp
@@ -84,6 +84,7 @@ NODE_DEFINE(Camera)
static NodeEnum panorama_type_enum;
panorama_type_enum.insert("equirectangular", PANORAMA_EQUIRECTANGULAR);
+ panorama_type_enum.insert("equiangular_cubemap_face", PANORAMA_EQUIANGULAR_CUBEMAP_FACE);
panorama_type_enum.insert("mirrorball", PANORAMA_MIRRORBALL);
panorama_type_enum.insert("fisheye_equidistant", PANORAMA_FISHEYE_EQUIDISTANT);
panorama_type_enum.insert("fisheye_equisolid", PANORAMA_FISHEYE_EQUISOLID);
diff --git a/intern/cycles/scene/film.cpp b/intern/cycles/scene/film.cpp
index a6a8f90a449..41ae73b2f27 100644
--- a/intern/cycles/scene/film.cpp
+++ b/intern/cycles/scene/film.cpp
@@ -200,6 +200,10 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kfilm->pass_shadow_catcher_sample_count = PASS_UNUSED;
kfilm->pass_shadow_catcher_matte = PASS_UNUSED;
+ kfilm->pass_guiding_color = PASS_UNUSED;
+ kfilm->pass_guiding_probability = PASS_UNUSED;
+ kfilm->pass_guiding_avg_roughness = PASS_UNUSED;
+
bool have_cryptomatte = false;
bool have_aov_color = false;
bool have_aov_value = false;
@@ -382,6 +386,15 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
have_aov_value = true;
}
break;
+ case PASS_GUIDING_COLOR:
+ kfilm->pass_guiding_color = kfilm->pass_stride;
+ break;
+ case PASS_GUIDING_PROBABILITY:
+ kfilm->pass_guiding_probability = kfilm->pass_stride;
+ break;
+ case PASS_GUIDING_AVG_ROUGHNESS:
+ kfilm->pass_guiding_avg_roughness = kfilm->pass_stride;
+ break;
default:
assert(false);
break;
diff --git a/intern/cycles/scene/image_oiio.cpp b/intern/cycles/scene/image_oiio.cpp
index 8792393e5a1..7bcf1ccb073 100644
--- a/intern/cycles/scene/image_oiio.cpp
+++ b/intern/cycles/scene/image_oiio.cpp
@@ -192,8 +192,22 @@ bool OIIOImageLoader::load_pixels(const ImageMetaData &metadata,
return false;
}
- const bool do_associate_alpha = associate_alpha &&
- spec.get_int_attribute("oiio:UnassociatedAlpha", 0);
+ bool do_associate_alpha = false;
+ if (associate_alpha) {
+ do_associate_alpha = spec.get_int_attribute("oiio:UnassociatedAlpha", 0);
+
+ if (!do_associate_alpha && spec.alpha_channel != -1) {
+ /* Workaround OIIO not detecting TGA file alpha the same as Blender (since #3019).
+ * We want anything not marked as premultiplied alpha to get associated. */
+ if (strcmp(in->format_name(), "targa") == 0) {
+ do_associate_alpha = spec.get_int_attribute("targa:alpha_type", -1) != 4;
+ }
+ /* OIIO DDS reader never sets UnassociatedAlpha attribute. */
+ if (strcmp(in->format_name(), "dds") == 0) {
+ do_associate_alpha = true;
+ }
+ }
+ }
switch (metadata.type) {
case IMAGE_DATA_TYPE_BYTE:
diff --git a/intern/cycles/scene/integrator.cpp b/intern/cycles/scene/integrator.cpp
index e9cd753854f..ade4716242b 100644
--- a/intern/cycles/scene/integrator.cpp
+++ b/intern/cycles/scene/integrator.cpp
@@ -60,6 +60,25 @@ NODE_DEFINE(Integrator)
SOCKET_INT(volume_max_steps, "Volume Max Steps", 1024);
SOCKET_FLOAT(volume_step_rate, "Volume Step Rate", 1.0f);
+ static NodeEnum guiding_ditribution_enum;
+ guiding_ditribution_enum.insert("PARALLAX_AWARE_VMM", GUIDING_TYPE_PARALLAX_AWARE_VMM);
+ guiding_ditribution_enum.insert("DIRECTIONAL_QUAD_TREE", GUIDING_TYPE_DIRECTIONAL_QUAD_TREE);
+ guiding_ditribution_enum.insert("VMM", GUIDING_TYPE_VMM);
+
+ SOCKET_BOOLEAN(use_guiding, "Guiding", false);
+ SOCKET_BOOLEAN(deterministic_guiding, "Deterministic Guiding", true);
+ SOCKET_BOOLEAN(use_surface_guiding, "Surface Guiding", true);
+ SOCKET_FLOAT(surface_guiding_probability, "Surface Guiding Probability", 0.5f);
+ SOCKET_BOOLEAN(use_volume_guiding, "Volume Guiding", true);
+ SOCKET_FLOAT(volume_guiding_probability, "Volume Guiding Probability", 0.5f);
+ SOCKET_INT(guiding_training_samples, "Training Samples", 128);
+ SOCKET_BOOLEAN(use_guiding_direct_light, "Guide Direct Light", true);
+ SOCKET_BOOLEAN(use_guiding_mis_weights, "Use MIS Weights", true);
+ SOCKET_ENUM(guiding_distribution_type,
+ "Guiding Distribution Type",
+ guiding_ditribution_enum,
+ GUIDING_TYPE_PARALLAX_AWARE_VMM);
+
SOCKET_BOOLEAN(caustics_reflective, "Reflective Caustics", true);
SOCKET_BOOLEAN(caustics_refractive, "Refractive Caustics", true);
SOCKET_FLOAT(filter_glossy, "Filter Glossy", 0.0f);
@@ -209,6 +228,17 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
kintegrator->filter_closures |= FILTER_CLOSURE_TRANSPARENT;
}
+ GuidingParams guiding_params = get_guiding_params(device);
+ kintegrator->use_guiding = guiding_params.use;
+ kintegrator->train_guiding = kintegrator->use_guiding;
+ kintegrator->use_surface_guiding = guiding_params.use_surface_guiding;
+ kintegrator->use_volume_guiding = guiding_params.use_volume_guiding;
+ kintegrator->surface_guiding_probability = surface_guiding_probability;
+ kintegrator->volume_guiding_probability = volume_guiding_probability;
+ kintegrator->use_guiding_direct_light = use_guiding_direct_light;
+ kintegrator->use_guiding_mis_weights = use_guiding_mis_weights;
+ kintegrator->guiding_distribution_type = guiding_params.type;
+
kintegrator->seed = seed;
kintegrator->sample_clamp_direct = (sample_clamp_direct == 0.0f) ? FLT_MAX :
@@ -354,4 +384,20 @@ DenoiseParams Integrator::get_denoise_params() const
return denoise_params;
}
+GuidingParams Integrator::get_guiding_params(const Device *device) const
+{
+ const bool use = use_guiding && device->info.has_guiding;
+
+ GuidingParams guiding_params;
+ guiding_params.use_surface_guiding = use && use_surface_guiding &&
+ surface_guiding_probability > 0.0f;
+ guiding_params.use_volume_guiding = use && use_volume_guiding &&
+ volume_guiding_probability > 0.0f;
+ guiding_params.use = guiding_params.use_surface_guiding || guiding_params.use_volume_guiding;
+ guiding_params.type = guiding_distribution_type;
+ guiding_params.training_samples = guiding_training_samples;
+ guiding_params.deterministic = deterministic_guiding;
+
+ return guiding_params;
+}
CCL_NAMESPACE_END
diff --git a/intern/cycles/scene/integrator.h b/intern/cycles/scene/integrator.h
index d54a44b6177..8fdf53547b0 100644
--- a/intern/cycles/scene/integrator.h
+++ b/intern/cycles/scene/integrator.h
@@ -9,6 +9,7 @@
#include "device/denoise.h" /* For the parameters and type enum. */
#include "graph/node.h"
#include "integrator/adaptive_sampling.h"
+#include "integrator/guiding.h"
CCL_NAMESPACE_BEGIN
@@ -43,6 +44,17 @@ class Integrator : public Node {
NODE_SOCKET_API(int, volume_max_steps)
NODE_SOCKET_API(float, volume_step_rate)
+ NODE_SOCKET_API(bool, use_guiding);
+ NODE_SOCKET_API(bool, deterministic_guiding);
+ NODE_SOCKET_API(bool, use_surface_guiding);
+ NODE_SOCKET_API(float, surface_guiding_probability);
+ NODE_SOCKET_API(bool, use_volume_guiding);
+ NODE_SOCKET_API(float, volume_guiding_probability);
+ NODE_SOCKET_API(int, guiding_training_samples);
+ NODE_SOCKET_API(bool, use_guiding_direct_light);
+ NODE_SOCKET_API(bool, use_guiding_mis_weights);
+ NODE_SOCKET_API(GuidingDistributionType, guiding_distribution_type);
+
NODE_SOCKET_API(bool, caustics_reflective)
NODE_SOCKET_API(bool, caustics_refractive)
NODE_SOCKET_API(float, filter_glossy)
@@ -105,6 +117,7 @@ class Integrator : public Node {
AdaptiveSampling get_adaptive_sampling() const;
DenoiseParams get_denoise_params() const;
+ GuidingParams get_guiding_params(const Device *device) const;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/scene/osl.cpp b/intern/cycles/scene/osl.cpp
index 93839facdbe..3ea406b6935 100644
--- a/intern/cycles/scene/osl.cpp
+++ b/intern/cycles/scene/osl.cpp
@@ -38,16 +38,17 @@ OSL::TextureSystem *OSLShaderManager::ts_shared = NULL;
int OSLShaderManager::ts_shared_users = 0;
thread_mutex OSLShaderManager::ts_shared_mutex;
-OSL::ShadingSystem *OSLShaderManager::ss_shared = NULL;
-OSLRenderServices *OSLShaderManager::services_shared = NULL;
+OSL::ErrorHandler OSLShaderManager::errhandler;
+map<int, OSL::ShadingSystem *> OSLShaderManager::ss_shared;
int OSLShaderManager::ss_shared_users = 0;
thread_mutex OSLShaderManager::ss_shared_mutex;
thread_mutex OSLShaderManager::ss_mutex;
+
int OSLCompiler::texture_shared_unique_id = 0;
/* Shader Manager */
-OSLShaderManager::OSLShaderManager()
+OSLShaderManager::OSLShaderManager(Device *device) : device_(device)
{
texture_system_init();
shading_system_init();
@@ -107,11 +108,12 @@ void OSLShaderManager::device_update_specific(Device *device,
device_free(device, dscene, scene);
- /* set texture system */
- scene->image_manager->set_osl_texture_system((void *)ts);
+ /* set texture system (only on CPU devices, since GPU devices cannot use OIIO) */
+ if (device->info.type == DEVICE_CPU) {
+ scene->image_manager->set_osl_texture_system((void *)ts_shared);
+ }
/* create shaders */
- OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
Shader *background_shader = scene->background->get_shader(scene);
foreach (Shader *shader, scene->shaders) {
@@ -125,22 +127,34 @@ void OSLShaderManager::device_update_specific(Device *device,
* compile shaders alternating */
thread_scoped_lock lock(ss_mutex);
- OSLCompiler compiler(this, services, ss, scene);
- compiler.background = (shader == background_shader);
- compiler.compile(og, shader);
+ device->foreach_device(
+ [this, scene, shader, background = (shader == background_shader)](Device *sub_device) {
+ OSLGlobals *og = (OSLGlobals *)sub_device->get_cpu_osl_memory();
+ OSL::ShadingSystem *ss = ss_shared[sub_device->info.type];
+
+ OSLCompiler compiler(this, ss, scene);
+ compiler.background = background;
+ compiler.compile(og, shader);
+ });
if (shader->get_use_mis() && shader->has_surface_emission)
scene->light_manager->tag_update(scene, LightManager::SHADER_COMPILED);
}
/* setup shader engine */
- og->ss = ss;
- og->ts = ts;
- og->services = services;
-
int background_id = scene->shader_manager->get_shader_id(background_shader);
- og->background_state = og->surface_state[background_id & SHADER_MASK];
- og->use = true;
+
+ device->foreach_device([background_id](Device *sub_device) {
+ OSLGlobals *og = (OSLGlobals *)sub_device->get_cpu_osl_memory();
+ OSL::ShadingSystem *ss = ss_shared[sub_device->info.type];
+
+ og->ss = ss;
+ og->ts = ts_shared;
+ og->services = static_cast<OSLRenderServices *>(ss->renderer());
+
+ og->background_state = og->surface_state[background_id & SHADER_MASK];
+ og->use = true;
+ });
foreach (Shader *shader, scene->shaders)
shader->clear_modified();
@@ -148,8 +162,12 @@ void OSLShaderManager::device_update_specific(Device *device,
update_flags = UPDATE_NONE;
/* add special builtin texture types */
- services->textures.insert(ustring("@ao"), new OSLTextureHandle(OSLTextureHandle::AO));
- services->textures.insert(ustring("@bevel"), new OSLTextureHandle(OSLTextureHandle::BEVEL));
+ for (const auto &[device_type, ss] : ss_shared) {
+ OSLRenderServices *services = static_cast<OSLRenderServices *>(ss->renderer());
+
+ services->textures.insert(ustring("@ao"), new OSLTextureHandle(OSLTextureHandle::AO));
+ services->textures.insert(ustring("@bevel"), new OSLTextureHandle(OSLTextureHandle::BEVEL));
+ }
device_update_common(device, dscene, scene, progress);
@@ -166,26 +184,35 @@ void OSLShaderManager::device_update_specific(Device *device,
* is being freed after the Session is freed.
*/
thread_scoped_lock lock(ss_shared_mutex);
- ss->optimize_all_groups();
+ for (const auto &[device_type, ss] : ss_shared) {
+ ss->optimize_all_groups();
+ }
+ }
+
+ /* load kernels */
+ if (!device->load_osl_kernels()) {
+ progress.set_error(device->error_message());
}
}
void OSLShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *scene)
{
- OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
-
device_free_common(device, dscene, scene);
/* clear shader engine */
- og->use = false;
- og->ss = NULL;
- og->ts = NULL;
-
- og->surface_state.clear();
- og->volume_state.clear();
- og->displacement_state.clear();
- og->bump_state.clear();
- og->background_state.reset();
+ device->foreach_device([](Device *sub_device) {
+ OSLGlobals *og = (OSLGlobals *)sub_device->get_cpu_osl_memory();
+
+ og->use = false;
+ og->ss = NULL;
+ og->ts = NULL;
+
+ og->surface_state.clear();
+ og->volume_state.clear();
+ og->displacement_state.clear();
+ og->bump_state.clear();
+ og->background_state.reset();
+ });
}
void OSLShaderManager::texture_system_init()
@@ -193,7 +220,7 @@ void OSLShaderManager::texture_system_init()
/* create texture system, shared between different renders to reduce memory usage */
thread_scoped_lock lock(ts_shared_mutex);
- if (ts_shared_users == 0) {
+ if (ts_shared_users++ == 0) {
ts_shared = TextureSystem::create(true);
ts_shared->attribute("automip", 1);
@@ -203,24 +230,18 @@ void OSLShaderManager::texture_system_init()
/* effectively unlimited for now, until we support proper mipmap lookups */
ts_shared->attribute("max_memory_MB", 16384);
}
-
- ts = ts_shared;
- ts_shared_users++;
}
void OSLShaderManager::texture_system_free()
{
/* shared texture system decrease users and destroy if no longer used */
thread_scoped_lock lock(ts_shared_mutex);
- ts_shared_users--;
- if (ts_shared_users == 0) {
+ if (--ts_shared_users == 0) {
ts_shared->invalidate_all(true);
OSL::TextureSystem::destroy(ts_shared);
ts_shared = NULL;
}
-
- ts = NULL;
}
void OSLShaderManager::shading_system_init()
@@ -228,101 +249,105 @@ void OSLShaderManager::shading_system_init()
/* create shading system, shared between different renders to reduce memory usage */
thread_scoped_lock lock(ss_shared_mutex);
- if (ss_shared_users == 0) {
- /* Must use aligned new due to concurrent hash map. */
- services_shared = util_aligned_new<OSLRenderServices>(ts_shared);
+ device_->foreach_device([](Device *sub_device) {
+ const DeviceType device_type = sub_device->info.type;
- string shader_path = path_get("shader");
+ if (ss_shared_users++ == 0 || ss_shared.find(device_type) == ss_shared.end()) {
+ /* Must use aligned new due to concurrent hash map. */
+ OSLRenderServices *services = util_aligned_new<OSLRenderServices>(ts_shared, device_type);
+
+ string shader_path = path_get("shader");
# ifdef _WIN32
- /* Annoying thing, Cycles stores paths in UTF-8 codepage, so it can
- * operate with file paths with any character. This requires to use wide
- * char functions, but OSL uses old fashioned ANSI functions which means:
- *
- * - We have to convert our paths to ANSI before passing to OSL
- * - OSL can't be used when there's a multi-byte character in the path
- * to the shaders folder.
- */
- shader_path = string_to_ansi(shader_path);
+ /* Annoying thing, Cycles stores paths in UTF-8 codepage, so it can
+ * operate with file paths with any character. This requires to use wide
+ * char functions, but OSL uses old fashioned ANSI functions which means:
+ *
+ * - We have to convert our paths to ANSI before passing to OSL
+ * - OSL can't be used when there's a multi-byte character in the path
+ * to the shaders folder.
+ */
+ shader_path = string_to_ansi(shader_path);
# endif
- ss_shared = new OSL::ShadingSystem(services_shared, ts_shared, &errhandler);
- ss_shared->attribute("lockgeom", 1);
- ss_shared->attribute("commonspace", "world");
- ss_shared->attribute("searchpath:shader", shader_path);
- ss_shared->attribute("greedyjit", 1);
-
- VLOG_INFO << "Using shader search path: " << shader_path;
-
- /* our own ray types */
- static const char *raytypes[] = {
- "camera", /* PATH_RAY_CAMERA */
- "reflection", /* PATH_RAY_REFLECT */
- "refraction", /* PATH_RAY_TRANSMIT */
- "diffuse", /* PATH_RAY_DIFFUSE */
- "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 */
-
- "__unused__", /* PATH_RAY_NODE_UNALIGNED */
- "__unused__", /* PATH_RAY_MIS_SKIP */
-
- "diffuse_ancestor", /* PATH_RAY_DIFFUSE_ANCESTOR */
-
- /* Remaining irrelevant bits up to 32. */
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- "__unused__",
- };
-
- const int nraytypes = sizeof(raytypes) / sizeof(raytypes[0]);
- ss_shared->attribute("raytypes", TypeDesc(TypeDesc::STRING, nraytypes), raytypes);
-
- OSLRenderServices::register_closures(ss_shared);
-
- loaded_shaders.clear();
- }
+ OSL::ShadingSystem *ss = new OSL::ShadingSystem(services, ts_shared, &errhandler);
+ ss->attribute("lockgeom", 1);
+ ss->attribute("commonspace", "world");
+ ss->attribute("searchpath:shader", shader_path);
+ ss->attribute("greedyjit", 1);
+
+ VLOG_INFO << "Using shader search path: " << shader_path;
+
+ /* our own ray types */
+ static const char *raytypes[] = {
+ "camera", /* PATH_RAY_CAMERA */
+ "reflection", /* PATH_RAY_REFLECT */
+ "refraction", /* PATH_RAY_TRANSMIT */
+ "diffuse", /* PATH_RAY_DIFFUSE */
+ "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 */
+
+ "__unused__", /* PATH_RAY_NODE_UNALIGNED */
+ "__unused__", /* PATH_RAY_MIS_SKIP */
+
+ "diffuse_ancestor", /* PATH_RAY_DIFFUSE_ANCESTOR */
+
+ /* Remaining irrelevant bits up to 32. */
+ "__unused__",
+ "__unused__",
+ "__unused__",
+ "__unused__",
+ "__unused__",
+ "__unused__",
+ "__unused__",
+ "__unused__",
+ "__unused__",
+ "__unused__",
+ "__unused__",
+ "__unused__",
+ "__unused__",
+ "__unused__",
+ "__unused__",
+ "__unused__",
+ "__unused__",
+ "__unused__",
+ "__unused__",
+ };
+
+ const int nraytypes = sizeof(raytypes) / sizeof(raytypes[0]);
+ ss->attribute("raytypes", TypeDesc(TypeDesc::STRING, nraytypes), raytypes);
+
+ OSLRenderServices::register_closures(ss);
+
+ ss_shared[device_type] = ss;
+ }
+ });
- ss = ss_shared;
- services = services_shared;
- ss_shared_users++;
+ loaded_shaders.clear();
}
void OSLShaderManager::shading_system_free()
{
/* shared shading system decrease users and destroy if no longer used */
thread_scoped_lock lock(ss_shared_mutex);
- ss_shared_users--;
- if (ss_shared_users == 0) {
- delete ss_shared;
- ss_shared = NULL;
+ device_->foreach_device([](Device * /*sub_device*/) {
+ if (--ss_shared_users == 0) {
+ for (const auto &[device_type, ss] : ss_shared) {
+ OSLRenderServices *services = static_cast<OSLRenderServices *>(ss->renderer());
- util_aligned_delete(services_shared);
- services_shared = NULL;
- }
+ delete ss;
+
+ util_aligned_delete(services);
+ }
- ss = NULL;
- services = NULL;
+ ss_shared.clear();
+ }
+ });
}
bool OSLShaderManager::osl_compile(const string &inputfile, const string &outputfile)
@@ -447,7 +472,9 @@ const char *OSLShaderManager::shader_load_filepath(string filepath)
const char *OSLShaderManager::shader_load_bytecode(const string &hash, const string &bytecode)
{
- ss->LoadMemoryCompiledShader(hash.c_str(), bytecode.c_str());
+ for (const auto &[device_type, ss] : ss_shared) {
+ ss->LoadMemoryCompiledShader(hash.c_str(), bytecode.c_str());
+ }
OSLShaderInfo info;
@@ -599,11 +626,11 @@ OSLNode *OSLShaderManager::osl_node(ShaderGraph *graph,
/* Graph Compiler */
-OSLCompiler::OSLCompiler(OSLShaderManager *manager,
- OSLRenderServices *services,
- OSL::ShadingSystem *ss,
- Scene *scene)
- : scene(scene), manager(manager), services(services), ss(ss)
+OSLCompiler::OSLCompiler(OSLShaderManager *manager, OSL::ShadingSystem *ss, Scene *scene)
+ : scene(scene),
+ manager(manager),
+ services(static_cast<OSLRenderServices *>(ss->renderer())),
+ ss(ss)
{
current_type = SHADER_TYPE_SURFACE;
current_shader = NULL;
@@ -1105,7 +1132,12 @@ OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph
{
current_type = type;
- OSL::ShaderGroupRef group = ss->ShaderGroupBegin(shader->name.c_str());
+ string name = shader->name.string();
+ /* Replace invalid characters. */
+ for (size_t i; (i = name.find_first_of(" .,:;+-*/#")) != string::npos;)
+ name.replace(i, 1, "_");
+
+ OSL::ShaderGroupRef group = ss->ShaderGroupBegin(name);
ShaderNode *output = graph->output();
ShaderNodeSet dependencies;
diff --git a/intern/cycles/scene/osl.h b/intern/cycles/scene/osl.h
index 76c6bd96ce1..c0e82a9dc8d 100644
--- a/intern/cycles/scene/osl.h
+++ b/intern/cycles/scene/osl.h
@@ -54,7 +54,7 @@ struct OSLShaderInfo {
class OSLShaderManager : public ShaderManager {
public:
- OSLShaderManager();
+ OSLShaderManager(Device *device);
~OSLShaderManager();
static void free_memory();
@@ -92,25 +92,22 @@ class OSLShaderManager : public ShaderManager {
const std::string &bytecode_hash = "",
const std::string &bytecode = "");
- protected:
+ private:
void texture_system_init();
void texture_system_free();
void shading_system_init();
void shading_system_free();
- OSL::ShadingSystem *ss;
- OSL::TextureSystem *ts;
- OSLRenderServices *services;
- OSL::ErrorHandler errhandler;
+ Device *device_;
map<string, OSLShaderInfo> loaded_shaders;
static OSL::TextureSystem *ts_shared;
static thread_mutex ts_shared_mutex;
static int ts_shared_users;
- static OSL::ShadingSystem *ss_shared;
- static OSLRenderServices *services_shared;
+ static OSL::ErrorHandler errhandler;
+ static map<int, OSL::ShadingSystem *> ss_shared;
static thread_mutex ss_shared_mutex;
static thread_mutex ss_mutex;
static int ss_shared_users;
@@ -123,10 +120,7 @@ class OSLShaderManager : public ShaderManager {
class OSLCompiler {
public:
#ifdef WITH_OSL
- OSLCompiler(OSLShaderManager *manager,
- OSLRenderServices *services,
- OSL::ShadingSystem *shadingsys,
- Scene *scene);
+ OSLCompiler(OSLShaderManager *manager, OSL::ShadingSystem *shadingsys, Scene *scene);
#endif
void compile(OSLGlobals *og, Shader *shader);
diff --git a/intern/cycles/scene/pass.cpp b/intern/cycles/scene/pass.cpp
index c2f12355ac7..5833b45c409 100644
--- a/intern/cycles/scene/pass.cpp
+++ b/intern/cycles/scene/pass.cpp
@@ -96,6 +96,12 @@ const NodeEnum *Pass::get_type_enum()
pass_type_enum.insert("bake_primitive", PASS_BAKE_PRIMITIVE);
pass_type_enum.insert("bake_differential", PASS_BAKE_DIFFERENTIAL);
+
+#ifdef WITH_CYCLES_DEBUG
+ pass_type_enum.insert("guiding_color", PASS_GUIDING_COLOR);
+ pass_type_enum.insert("guiding_probability", PASS_GUIDING_PROBABILITY);
+ pass_type_enum.insert("guiding_avg_roughness", PASS_GUIDING_AVG_ROUGHNESS);
+#endif
}
return &pass_type_enum;
@@ -341,6 +347,15 @@ PassInfo Pass::get_info(const PassType type, const bool include_albedo, const bo
LOG(DFATAL) << "Unexpected pass type is used " << type;
pass_info.num_components = 0;
break;
+ case PASS_GUIDING_COLOR:
+ pass_info.num_components = 3;
+ break;
+ case PASS_GUIDING_PROBABILITY:
+ pass_info.num_components = 1;
+ break;
+ case PASS_GUIDING_AVG_ROUGHNESS:
+ pass_info.num_components = 1;
+ break;
}
return pass_info;
diff --git a/intern/cycles/scene/scene.cpp b/intern/cycles/scene/scene.cpp
index 478396ea98e..d5be86e1db9 100644
--- a/intern/cycles/scene/scene.cpp
+++ b/intern/cycles/scene/scene.cpp
@@ -99,11 +99,8 @@ Scene::Scene(const SceneParams &params_, Device *device)
{
memset((void *)&dscene.data, 0, sizeof(dscene.data));
- /* OSL only works on the CPU */
- if (device->info.has_osl)
- shader_manager = ShaderManager::create(params.shadingsystem);
- else
- shader_manager = ShaderManager::create(SHADINGSYSTEM_SVM);
+ shader_manager = ShaderManager::create(
+ device->info.has_osl ? params.shadingsystem : SHADINGSYSTEM_SVM, device);
light_manager = new LightManager();
geometry_manager = new GeometryManager();
@@ -439,9 +436,9 @@ bool Scene::need_data_update()
film->is_modified() || procedural_manager->need_update());
}
-bool Scene::need_reset()
+bool Scene::need_reset(const bool check_camera)
{
- return need_data_update() || camera->is_modified();
+ return need_data_update() || (check_camera && camera->is_modified());
}
void Scene::reset()
@@ -549,6 +546,10 @@ void Scene::update_kernel_features()
kernel_features |= KERNEL_FEATURE_MNEE;
}
+ if (integrator->get_guiding_params(device).use) {
+ kernel_features |= KERNEL_FEATURE_PATH_GUIDING;
+ }
+
if (bake_manager->get_baking()) {
kernel_features |= KERNEL_FEATURE_BAKING;
}
diff --git a/intern/cycles/scene/scene.h b/intern/cycles/scene/scene.h
index d1004bb7b66..d87cc37aafe 100644
--- a/intern/cycles/scene/scene.h
+++ b/intern/cycles/scene/scene.h
@@ -261,7 +261,7 @@ class Scene : public NodeOwner {
float motion_shutter_time();
bool need_update();
- bool need_reset();
+ bool need_reset(const bool check_camera = true);
void reset();
void device_free();
diff --git a/intern/cycles/scene/shader.cpp b/intern/cycles/scene/shader.cpp
index 96a8f40bbad..f176c19ec95 100644
--- a/intern/cycles/scene/shader.cpp
+++ b/intern/cycles/scene/shader.cpp
@@ -395,15 +395,16 @@ ShaderManager::~ShaderManager()
{
}
-ShaderManager *ShaderManager::create(int shadingsystem)
+ShaderManager *ShaderManager::create(int shadingsystem, Device *device)
{
ShaderManager *manager;
(void)shadingsystem; /* Ignored when built without OSL. */
+ (void)device;
#ifdef WITH_OSL
if (shadingsystem == SHADINGSYSTEM_OSL) {
- manager = new OSLShaderManager();
+ manager = new OSLShaderManager(device);
}
else
#endif
@@ -722,6 +723,10 @@ uint ShaderManager::get_kernel_features(Scene *scene)
}
}
+ if (use_osl()) {
+ kernel_features |= KERNEL_FEATURE_OSL;
+ }
+
return kernel_features;
}
@@ -780,7 +785,7 @@ static bool to_scene_linear_transform(OCIO::ConstConfigRcPtr &config,
{
OCIO::ConstProcessorRcPtr processor;
try {
- processor = config->getProcessor(OCIO::ROLE_SCENE_LINEAR, colorspace);
+ processor = config->getProcessor("scene_linear", colorspace);
}
catch (OCIO::Exception &) {
return false;
@@ -834,7 +839,7 @@ void ShaderManager::init_xyz_transforms()
#ifdef WITH_OCIO
/* Get from OpenColorO config if it has the required roles. */
OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
- if (!(config && config->hasRole(OCIO::ROLE_SCENE_LINEAR))) {
+ if (!(config && config->hasRole("scene_linear"))) {
return;
}
diff --git a/intern/cycles/scene/shader.h b/intern/cycles/scene/shader.h
index 2670776aca4..69b22d2ad19 100644
--- a/intern/cycles/scene/shader.h
+++ b/intern/cycles/scene/shader.h
@@ -170,7 +170,7 @@ class ShaderManager {
UPDATE_NONE = 0u,
};
- static ShaderManager *create(int shadingsystem);
+ static ShaderManager *create(int shadingsystem, Device *device);
virtual ~ShaderManager();
virtual void reset(Scene *scene) = 0;
diff --git a/intern/cycles/scene/shader_nodes.h b/intern/cycles/scene/shader_nodes.h
index cc3a71a0697..a3a931bb0b3 100644
--- a/intern/cycles/scene/shader_nodes.h
+++ b/intern/cycles/scene/shader_nodes.h
@@ -1542,6 +1542,10 @@ class OSLNode final : public ShaderNode {
{
return true;
}
+ virtual int get_feature()
+ {
+ return ShaderNode::get_feature() | KERNEL_FEATURE_NODE_RAYTRACE;
+ }
virtual bool equals(const ShaderNode & /*other*/)
{
diff --git a/intern/cycles/session/merge.h b/intern/cycles/session/merge.h
index 702ca5c3eb8..d8a4f04a27b 100644
--- a/intern/cycles/session/merge.h
+++ b/intern/cycles/session/merge.h
@@ -9,7 +9,7 @@
CCL_NAMESPACE_BEGIN
-/* Merge OpenEXR multilayer renders. */
+/* Merge OpenEXR multi-layer renders. */
class ImageMerger {
public:
diff --git a/intern/cycles/session/session.cpp b/intern/cycles/session/session.cpp
index a2955da5480..acaa55f4990 100644
--- a/intern/cycles/session/session.cpp
+++ b/intern/cycles/session/session.cpp
@@ -43,6 +43,10 @@ Session::Session(const SessionParams &params_, const SceneParams &scene_params)
device = Device::create(params.device, stats, profiler);
+ if (device->have_error()) {
+ progress.set_error(device->error_message());
+ }
+
scene = new Scene(scene_params, device);
/* Configure path tracer. */
@@ -318,6 +322,13 @@ RenderWork Session::run_update_for_next_iteration()
path_trace_->set_adaptive_sampling(adaptive_sampling);
}
+ /* Update path guiding. */
+ {
+ const GuidingParams guiding_params = scene->integrator->get_guiding_params(device);
+ const bool guiding_reset = (guiding_params.use) ? scene->need_reset(false) : false;
+ path_trace_->set_guiding_params(guiding_params, guiding_reset);
+ }
+
render_scheduler_.set_num_samples(params.samples);
render_scheduler_.set_start_sample(params.sample_offset);
render_scheduler_.set_time_limit(params.time_limit);
diff --git a/intern/cycles/session/tile.cpp b/intern/cycles/session/tile.cpp
index f4930cbb945..362372f1d7b 100644
--- a/intern/cycles/session/tile.cpp
+++ b/intern/cycles/session/tile.cpp
@@ -7,6 +7,7 @@
#include "graph/node.h"
#include "scene/background.h"
+#include "scene/bake.h"
#include "scene/film.h"
#include "scene/integrator.h"
#include "scene/scene.h"
@@ -367,7 +368,9 @@ void TileManager::update(const BufferParams &params, const Scene *scene)
node_to_image_spec_atttributes(
&write_state_.image_spec, &denoise_params, ATTR_DENOISE_SOCKET_PREFIX);
- if (adaptive_sampling.use) {
+ /* Not adaptive sampling overscan yet for baking, would need overscan also
+ * for buffers read from the output driver. */
+ if (adaptive_sampling.use && !scene->bake_manager->get_baking()) {
overscan_ = 4;
}
else {
diff --git a/intern/cycles/test/CMakeLists.txt b/intern/cycles/test/CMakeLists.txt
index 3f64febf4df..34e5a4770ea 100644
--- a/intern/cycles/test/CMakeLists.txt
+++ b/intern/cycles/test/CMakeLists.txt
@@ -34,6 +34,7 @@ set(SRC
render_graph_finalize_test.cpp
util_aligned_malloc_test.cpp
util_math_test.cpp
+ util_md5_test.cpp
util_path_test.cpp
util_string_test.cpp
util_task_test.cpp
@@ -44,20 +45,27 @@ set(SRC
# Disable AVX tests on macOS. Rosetta has problems running them, and other
# platforms should be enough to verify AVX operations are implemented correctly.
if(NOT APPLE)
+ if(CXX_HAS_SSE)
+ list(APPEND SRC
+ util_float8_sse2_test.cpp
+ )
+ set_source_files_properties(util_float8_avx_test.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE2_KERNEL_FLAGS}")
+ endif()
+
if(CXX_HAS_AVX)
list(APPEND SRC
- util_avxf_avx_test.cpp
+ util_float8_avx_test.cpp
)
- set_source_files_properties(util_avxf_avx_test.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX_KERNEL_FLAGS}")
+ set_source_files_properties(util_float8_avx_test.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX_KERNEL_FLAGS}")
endif()
if(CXX_HAS_AVX2)
list(APPEND SRC
- util_avxf_avx2_test.cpp
+ util_float8_avx2_test.cpp
)
- set_source_files_properties(util_avxf_avx2_test.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX2_KERNEL_FLAGS}")
+ set_source_files_properties(util_float8_avx2_test.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX2_KERNEL_FLAGS}")
endif()
endif()
if(WITH_GTESTS)
- BLENDER_SRC_GTEST(cycles "${SRC}" "${LIB}")
+ blender_src_gtest(cycles "${SRC}" "${LIB}")
endif()
diff --git a/intern/cycles/test/util_avxf_test.h b/intern/cycles/test/util_avxf_test.h
deleted file mode 100644
index 34d966cc1a4..00000000000
--- a/intern/cycles/test/util_avxf_test.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/* SPDX-License-Identifier: Apache-2.0
- * Copyright 2011-2022 Blender Foundation */
-
-#include "testing/testing.h"
-#include "util/system.h"
-#include "util/types.h"
-
-CCL_NAMESPACE_BEGIN
-
-static bool validate_cpu_capabilities()
-{
-
-#ifdef __KERNEL_AVX2__
- return system_cpu_support_avx2();
-#else
-# ifdef __KERNEL_AVX__
- return system_cpu_support_avx();
-# endif
-#endif
-}
-
-#define INIT_AVX_TEST \
- if (!validate_cpu_capabilities()) \
- return; \
-\
- const avxf avxf_a(0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f); \
- const avxf avxf_b(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f); \
- const avxf avxf_c(1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f);
-
-#define compare_vector_scalar(a, b) \
- for (size_t index = 0; index < a.size; index++) \
- EXPECT_FLOAT_EQ(a[index], b);
-
-#define compare_vector_vector(a, b) \
- for (size_t index = 0; index < a.size; index++) \
- EXPECT_FLOAT_EQ(a[index], b[index]);
-
-#define compare_vector_vector_near(a, b, abserror) \
- for (size_t index = 0; index < a.size; index++) \
- EXPECT_NEAR(a[index], b[index], abserror);
-
-#define basic_test_vv(a, b, op) \
- INIT_AVX_TEST \
- avxf c = a op b; \
- for (size_t i = 0; i < a.size; i++) \
- EXPECT_FLOAT_EQ(c[i], a[i] op b[i]);
-
-/* vector op float tests */
-#define basic_test_vf(a, b, op) \
- INIT_AVX_TEST \
- avxf c = a op b; \
- for (size_t i = 0; i < a.size; i++) \
- EXPECT_FLOAT_EQ(c[i], a[i] op b);
-
-static const float float_b = 1.5f;
-
-TEST(TEST_CATEGORY_NAME, avxf_add_vv){basic_test_vv(avxf_a, avxf_b, +)} TEST(TEST_CATEGORY_NAME,
- avxf_sub_vv){
- basic_test_vv(avxf_a, avxf_b, -)} TEST(TEST_CATEGORY_NAME, avxf_mul_vv){
- basic_test_vv(avxf_a, avxf_b, *)} TEST(TEST_CATEGORY_NAME, avxf_div_vv){
- basic_test_vv(avxf_a, avxf_b, /)} TEST(TEST_CATEGORY_NAME, avxf_add_vf){
- basic_test_vf(avxf_a, float_b, +)} TEST(TEST_CATEGORY_NAME, avxf_sub_vf){
- basic_test_vf(avxf_a, float_b, -)} TEST(TEST_CATEGORY_NAME, avxf_mul_vf){
- basic_test_vf(avxf_a, float_b, *)} TEST(TEST_CATEGORY_NAME,
- avxf_div_vf){basic_test_vf(avxf_a, float_b, /)}
-
-TEST(TEST_CATEGORY_NAME, avxf_ctor)
-{
- INIT_AVX_TEST
- compare_vector_scalar(avxf(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f),
- static_cast<float>(index));
- compare_vector_scalar(avxf(1.0f), 1.0f);
- compare_vector_vector(avxf(1.0f, 2.0f), avxf(1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 2.0f));
- compare_vector_vector(avxf(1.0f, 2.0f, 3.0f, 4.0f),
- avxf(1.0f, 2.0f, 3.0f, 4.0f, 1.0f, 2.0f, 3.0f, 4.0f));
- compare_vector_vector(avxf(make_float3(1.0f, 2.0f, 3.0f)),
- avxf(0.0f, 3.0f, 2.0f, 1.0f, 0.0f, 3.0f, 2.0f, 1.0f));
-}
-
-TEST(TEST_CATEGORY_NAME, avxf_sqrt)
-{
- INIT_AVX_TEST
- compare_vector_vector(mm256_sqrt(avxf(1.0f, 4.0f, 9.0f, 16.0f, 25.0f, 36.0f, 49.0f, 64.0f)),
- avxf(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f));
-}
-
-TEST(TEST_CATEGORY_NAME, avxf_min_max)
-{
- INIT_AVX_TEST
- compare_vector_vector(min(avxf_a, avxf_b), avxf_a);
- compare_vector_vector(max(avxf_a, avxf_b), avxf_b);
-}
-
-TEST(TEST_CATEGORY_NAME, avxf_set_sign)
-{
- INIT_AVX_TEST
- avxf res = set_sign_bit<1, 0, 0, 0, 0, 0, 0, 0>(avxf_a);
- compare_vector_vector(res, avxf(0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, -0.8f));
-}
-
-TEST(TEST_CATEGORY_NAME, avxf_msub)
-{
- INIT_AVX_TEST
- avxf res = msub(avxf_a, avxf_b, avxf_c);
- avxf exp = avxf((avxf_a[7] * avxf_b[7]) - avxf_c[7],
- (avxf_a[6] * avxf_b[6]) - avxf_c[6],
- (avxf_a[5] * avxf_b[5]) - avxf_c[5],
- (avxf_a[4] * avxf_b[4]) - avxf_c[4],
- (avxf_a[3] * avxf_b[3]) - avxf_c[3],
- (avxf_a[2] * avxf_b[2]) - avxf_c[2],
- (avxf_a[1] * avxf_b[1]) - avxf_c[1],
- (avxf_a[0] * avxf_b[0]) - avxf_c[0]);
- compare_vector_vector(res, exp);
-}
-
-TEST(TEST_CATEGORY_NAME, avxf_madd)
-{
- INIT_AVX_TEST
- avxf res = madd(avxf_a, avxf_b, avxf_c);
- avxf exp = avxf((avxf_a[7] * avxf_b[7]) + avxf_c[7],
- (avxf_a[6] * avxf_b[6]) + avxf_c[6],
- (avxf_a[5] * avxf_b[5]) + avxf_c[5],
- (avxf_a[4] * avxf_b[4]) + avxf_c[4],
- (avxf_a[3] * avxf_b[3]) + avxf_c[3],
- (avxf_a[2] * avxf_b[2]) + avxf_c[2],
- (avxf_a[1] * avxf_b[1]) + avxf_c[1],
- (avxf_a[0] * avxf_b[0]) + avxf_c[0]);
- compare_vector_vector(res, exp);
-}
-
-TEST(TEST_CATEGORY_NAME, avxf_nmadd)
-{
- INIT_AVX_TEST
- avxf res = nmadd(avxf_a, avxf_b, avxf_c);
- avxf exp = avxf(avxf_c[7] - (avxf_a[7] * avxf_b[7]),
- avxf_c[6] - (avxf_a[6] * avxf_b[6]),
- avxf_c[5] - (avxf_a[5] * avxf_b[5]),
- avxf_c[4] - (avxf_a[4] * avxf_b[4]),
- avxf_c[3] - (avxf_a[3] * avxf_b[3]),
- avxf_c[2] - (avxf_a[2] * avxf_b[2]),
- avxf_c[1] - (avxf_a[1] * avxf_b[1]),
- avxf_c[0] - (avxf_a[0] * avxf_b[0]));
- compare_vector_vector(res, exp);
-}
-
-TEST(TEST_CATEGORY_NAME, avxf_compare)
-{
- INIT_AVX_TEST
- avxf a(0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f);
- avxf b(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f);
- avxb res = a <= b;
- int exp[8] = {
- a[0] <= b[0] ? -1 : 0,
- a[1] <= b[1] ? -1 : 0,
- a[2] <= b[2] ? -1 : 0,
- a[3] <= b[3] ? -1 : 0,
- a[4] <= b[4] ? -1 : 0,
- a[5] <= b[5] ? -1 : 0,
- a[6] <= b[6] ? -1 : 0,
- a[7] <= b[7] ? -1 : 0,
- };
- compare_vector_vector(res, exp);
-}
-
-TEST(TEST_CATEGORY_NAME, avxf_permute)
-{
- INIT_AVX_TEST
- avxf res = permute<3, 0, 1, 7, 6, 5, 2, 4>(avxf_b);
- compare_vector_vector(res, avxf(4.0f, 6.0f, 3.0f, 2.0f, 1.0f, 7.0f, 8.0f, 5.0f));
-}
-
-TEST(TEST_CATEGORY_NAME, avxf_blend)
-{
- INIT_AVX_TEST
- avxf res = blend<0, 0, 1, 0, 1, 0, 1, 0>(avxf_a, avxf_b);
- compare_vector_vector(res, avxf(0.1f, 0.2f, 3.0f, 0.4f, 5.0f, 0.6f, 7.0f, 0.8f));
-}
-
-TEST(TEST_CATEGORY_NAME, avxf_shuffle)
-{
- INIT_AVX_TEST
- avxf res = shuffle<0, 1, 2, 3, 1, 3, 2, 0>(avxf_a);
- compare_vector_vector(res, avxf(0.4f, 0.2f, 0.1f, 0.3f, 0.5f, 0.6f, 0.7f, 0.8f));
-}
-
-TEST(TEST_CATEGORY_NAME, avxf_cross)
-{
- INIT_AVX_TEST
- avxf res = cross(avxf_b, avxf_c);
- compare_vector_vector_near(res,
- avxf(0.0f,
- -9.5367432e-07f,
- 0.0f,
- 4.7683716e-07f,
- 0.0f,
- -3.8146973e-06f,
- 3.8146973e-06f,
- 3.8146973e-06f),
- 0.000002000f);
-}
-
-TEST(TEST_CATEGORY_NAME, avxf_dot3)
-{
- INIT_AVX_TEST
- float den, den2;
- dot3(avxf_a, avxf_b, den, den2);
- EXPECT_FLOAT_EQ(den, 14.9f);
- EXPECT_FLOAT_EQ(den2, 2.9f);
-}
-
-CCL_NAMESPACE_END
diff --git a/intern/cycles/test/util_avxf_avx2_test.cpp b/intern/cycles/test/util_float8_avx2_test.cpp
index 992c4d9a913..4682dce5b23 100644
--- a/intern/cycles/test/util_avxf_avx2_test.cpp
+++ b/intern/cycles/test/util_float8_avx2_test.cpp
@@ -1,11 +1,13 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
+#define __KERNEL_SSE__
+#define __KERNEL_AVX__
#define __KERNEL_AVX2__
#define TEST_CATEGORY_NAME util_avx2
#if (defined(i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)) && \
defined(__AVX2__)
-# include "util_avxf_test.h"
+# include "util_float8_test.h"
#endif
diff --git a/intern/cycles/test/util_avxf_avx_test.cpp b/intern/cycles/test/util_float8_avx_test.cpp
index abb98cdfb38..34fe750e766 100644
--- a/intern/cycles/test/util_avxf_avx_test.cpp
+++ b/intern/cycles/test/util_float8_avx_test.cpp
@@ -1,11 +1,12 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
+#define __KERNEL_SSE__
#define __KERNEL_AVX__
#define TEST_CATEGORY_NAME util_avx
#if (defined(i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)) && \
defined(__AVX__)
-# include "util_avxf_test.h"
+# include "util_float8_test.h"
#endif
diff --git a/intern/cycles/test/util_float8_sse2_test.cpp b/intern/cycles/test/util_float8_sse2_test.cpp
new file mode 100644
index 00000000000..ba8952a2b08
--- /dev/null
+++ b/intern/cycles/test/util_float8_sse2_test.cpp
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#define __KERNEL_SSE__
+#define __KERNEL_SSE2__
+
+#define TEST_CATEGORY_NAME util_sse2
+
+#if (defined(i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)) && \
+ defined(__SSE2__)
+# include "util_float8_test.h"
+#endif
diff --git a/intern/cycles/test/util_float8_test.h b/intern/cycles/test/util_float8_test.h
new file mode 100644
index 00000000000..54701afaf8b
--- /dev/null
+++ b/intern/cycles/test/util_float8_test.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#include "testing/testing.h"
+#include "util/math.h"
+#include "util/system.h"
+#include "util/types.h"
+
+CCL_NAMESPACE_BEGIN
+
+static bool validate_cpu_capabilities()
+{
+
+#if defined(__KERNEL_AVX2__)
+ return system_cpu_support_avx2();
+#elif defined(__KERNEL_AVX__)
+ return system_cpu_support_avx();
+#elif defined(__KERNEL_SSE2__)
+ return system_cpu_support_sse2();
+#else
+ return false;
+#endif
+}
+
+#define INIT_FLOAT8_TEST \
+ if (!validate_cpu_capabilities()) \
+ return; \
+\
+ const vfloat8 float8_a = make_vfloat8(0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f); \
+ const vfloat8 float8_b = make_vfloat8(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f); \
+ const vfloat8 float8_c = make_vfloat8(1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f);
+
+#define compare_vector_scalar(a, b) \
+ for (size_t index = 0; index < 8; index++) \
+ EXPECT_FLOAT_EQ(a[index], b);
+
+#define compare_vector_vector(a, b) \
+ for (size_t index = 0; index < 8; index++) \
+ EXPECT_FLOAT_EQ(a[index], b[index]);
+
+#define compare_vector_vector_near(a, b, abserror) \
+ for (size_t index = 0; index < 8; index++) \
+ EXPECT_NEAR(a[index], b[index], abserror);
+
+#define basic_test_vv(a, b, op) \
+ INIT_FLOAT8_TEST \
+ vfloat8 c = a op b; \
+ for (size_t i = 0; i < 8; i++) \
+ EXPECT_FLOAT_EQ(c[i], a[i] op b[i]);
+
+/* vector op float tests */
+#define basic_test_vf(a, b, op) \
+ INIT_FLOAT8_TEST \
+ vfloat8 c = a op b; \
+ for (size_t i = 0; i < 8; i++) \
+ EXPECT_FLOAT_EQ(c[i], a[i] op b);
+
+static const float float_b = 1.5f;
+
+TEST(TEST_CATEGORY_NAME,
+ float8_add_vv){basic_test_vv(float8_a, float8_b, +)} TEST(TEST_CATEGORY_NAME, float8_sub_vv){
+ basic_test_vv(float8_a, float8_b, -)} TEST(TEST_CATEGORY_NAME, float8_mul_vv){
+ basic_test_vv(float8_a, float8_b, *)} TEST(TEST_CATEGORY_NAME, float8_div_vv){
+ basic_test_vv(float8_a, float8_b, /)} TEST(TEST_CATEGORY_NAME, float8_add_vf){
+ basic_test_vf(float8_a, float_b, +)} TEST(TEST_CATEGORY_NAME, float8_sub_vf){
+ basic_test_vf(float8_a, float_b, -)} TEST(TEST_CATEGORY_NAME, float8_mul_vf){
+ basic_test_vf(float8_a, float_b, *)} TEST(TEST_CATEGORY_NAME,
+ float8_div_vf){basic_test_vf(float8_a, float_b, /)}
+
+TEST(TEST_CATEGORY_NAME, float8_ctor)
+{
+ INIT_FLOAT8_TEST
+ compare_vector_scalar(make_vfloat8(0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f),
+ static_cast<float>(index));
+ compare_vector_scalar(make_vfloat8(1.0f), 1.0f);
+}
+
+TEST(TEST_CATEGORY_NAME, float8_sqrt)
+{
+ INIT_FLOAT8_TEST
+ compare_vector_vector(sqrt(make_vfloat8(1.0f, 4.0f, 9.0f, 16.0f, 25.0f, 36.0f, 49.0f, 64.0f)),
+ make_vfloat8(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f));
+}
+
+TEST(TEST_CATEGORY_NAME, float8_min_max)
+{
+ INIT_FLOAT8_TEST
+ compare_vector_vector(min(float8_a, float8_b), float8_a);
+ compare_vector_vector(max(float8_a, float8_b), float8_b);
+}
+
+TEST(TEST_CATEGORY_NAME, float8_shuffle)
+{
+ INIT_FLOAT8_TEST
+ vfloat8 res0 = shuffle<0, 1, 2, 3, 1, 3, 2, 0>(float8_a);
+ compare_vector_vector(res0, make_vfloat8(0.1f, 0.2f, 0.3f, 0.4f, 0.6f, 0.8f, 0.7f, 0.5f));
+ vfloat8 res1 = shuffle<3>(float8_a);
+ compare_vector_vector(res1, make_vfloat8(0.4f, 0.4f, 0.4f, 0.4f, 0.8f, 0.8f, 0.8f, 0.8f));
+ vfloat8 res2 = shuffle<3, 2, 1, 0>(float8_a, float8_b);
+ compare_vector_vector(res2, make_vfloat8(0.4f, 0.3f, 2.0f, 1.0f, 0.8f, 0.7f, 6.0f, 5.0f));
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/test/util_md5_test.cpp b/intern/cycles/test/util_md5_test.cpp
new file mode 100644
index 00000000000..abc147b70a1
--- /dev/null
+++ b/intern/cycles/test/util_md5_test.cpp
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#include "testing/testing.h"
+
+#include "util/md5.h"
+
+CCL_NAMESPACE_BEGIN
+
+TEST(util, util_md5_string)
+{
+ /* The hash is calculated using `echo -n "Hello, World\!" | md5 | tr '[:lower:]' '[:upper:]'`. */
+ EXPECT_EQ(util_md5_string("Hello, World!"), "65A8E27D8879283831B664BD8B7F0AD4");
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt
index 997d574a3b0..7f8f4a5ce76 100644
--- a/intern/cycles/util/CMakeLists.txt
+++ b/intern/cycles/util/CMakeLists.txt
@@ -49,6 +49,7 @@ set(SRC_HEADERS
foreach.h
function.h
guarded_allocator.h
+ guiding.h
half.h
hash.h
ies.h
@@ -68,6 +69,7 @@ set(SRC_HEADERS
math_int2.h
math_int3.h
math_int4.h
+ math_int8.h
math_matrix.h
md5.h
murmurhash.h
@@ -84,13 +86,7 @@ set(SRC_HEADERS
rect.h
set.h
simd.h
- avxf.h
- avxb.h
- avxi.h
semaphore.h
- sseb.h
- ssef.h
- ssei.h
stack_allocator.h
static_assert.h
stats.h
@@ -117,6 +113,8 @@ set(SRC_HEADERS
types_int3_impl.h
types_int4.h
types_int4_impl.h
+ types_int8.h
+ types_int8_impl.h
types_spectrum.h
types_uchar2.h
types_uchar2_impl.h
diff --git a/intern/cycles/util/avxb.h b/intern/cycles/util/avxb.h
deleted file mode 100644
index fa3cb565309..00000000000
--- a/intern/cycles/util/avxb.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/* SPDX-License-Identifier: Apache-2.0
- * Copyright 2011-2013 Intel Corporation
- * Modifications Copyright 2014-2022 Blender Foundation. */
-
-#ifndef __UTIL_AVXB_H__
-#define __UTIL_AVXB_H__
-
-CCL_NAMESPACE_BEGIN
-
-struct avxf;
-
-/*! 4-wide SSE bool type. */
-struct avxb {
- typedef avxb Mask; // mask type
- typedef avxf Float; // float type
-
- enum { size = 8 }; // number of SIMD elements
- union {
- __m256 m256;
- int32_t v[8];
- }; // data
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Constructors, Assignment & Cast Operators
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline avxb()
- {
- }
- __forceinline avxb(const avxb &other)
- {
- m256 = other.m256;
- }
- __forceinline avxb &operator=(const avxb &other)
- {
- m256 = other.m256;
- return *this;
- }
-
- __forceinline avxb(const __m256 input) : m256(input)
- {
- }
- __forceinline avxb(const __m128 &a, const __m128 &b)
- : m256(_mm256_insertf128_ps(_mm256_castps128_ps256(a), b, 1))
- {
- }
- __forceinline operator const __m256 &(void) const
- {
- return m256;
- }
- __forceinline operator const __m256i(void) const
- {
- return _mm256_castps_si256(m256);
- }
- __forceinline operator const __m256d(void) const
- {
- return _mm256_castps_pd(m256);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Constants
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline avxb(FalseTy) : m256(_mm256_setzero_ps())
- {
- }
- __forceinline avxb(TrueTy) : m256(_mm256_castsi256_ps(_mm256_set1_epi32(-1)))
- {
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Array Access
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline bool operator[](const size_t i) const
- {
- assert(i < 8);
- return (_mm256_movemask_ps(m256) >> i) & 1;
- }
- __forceinline int32_t &operator[](const size_t i)
- {
- assert(i < 8);
- return v[i];
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// Unary Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const avxb operator!(const avxb &a)
-{
- return _mm256_xor_ps(a, avxb(True));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Binary Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const avxb operator&(const avxb &a, const avxb &b)
-{
- return _mm256_and_ps(a, b);
-}
-__forceinline const avxb operator|(const avxb &a, const avxb &b)
-{
- return _mm256_or_ps(a, b);
-}
-__forceinline const avxb operator^(const avxb &a, const avxb &b)
-{
- return _mm256_xor_ps(a, b);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Assignment Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const avxb operator&=(avxb &a, const avxb &b)
-{
- return a = a & b;
-}
-__forceinline const avxb operator|=(avxb &a, const avxb &b)
-{
- return a = a | b;
-}
-__forceinline const avxb operator^=(avxb &a, const avxb &b)
-{
- return a = a ^ b;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Comparison Operators + Select
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const avxb operator!=(const avxb &a, const avxb &b)
-{
- return _mm256_xor_ps(a, b);
-}
-__forceinline const avxb operator==(const avxb &a, const avxb &b)
-{
-#ifdef __KERNEL_AVX2__
- return _mm256_castsi256_ps(_mm256_cmpeq_epi32(a, b));
-#else
- __m128i a_lo = _mm_castps_si128(_mm256_extractf128_ps(a, 0));
- __m128i a_hi = _mm_castps_si128(_mm256_extractf128_ps(a, 1));
- __m128i b_lo = _mm_castps_si128(_mm256_extractf128_ps(b, 0));
- __m128i b_hi = _mm_castps_si128(_mm256_extractf128_ps(b, 1));
- __m128i c_lo = _mm_cmpeq_epi32(a_lo, b_lo);
- __m128i c_hi = _mm_cmpeq_epi32(a_hi, b_hi);
- __m256i result = _mm256_insertf128_si256(_mm256_castsi128_si256(c_lo), c_hi, 1);
- return _mm256_castsi256_ps(result);
-#endif
-}
-
-__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)
-{
-#if defined(__KERNEL_SSE41__)
- return _mm256_blendv_ps(f, t, m);
-#else
- return _mm256_or_ps(_mm256_and_ps(m, t), _mm256_andnot_ps(m, f));
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Movement/Shifting/Shuffling Functions
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const avxb unpacklo(const avxb &a, const avxb &b)
-{
- return _mm256_unpacklo_ps(a, b);
-}
-__forceinline const avxb unpackhi(const avxb &a, const avxb &b)
-{
- return _mm256_unpackhi_ps(a, b);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Reduction Operations
-////////////////////////////////////////////////////////////////////////////////
-
-#if defined(__KERNEL_SSE41__)
-__forceinline uint32_t popcnt(const avxb &a)
-{
- return _mm_popcnt_u32(_mm256_movemask_ps(a));
-}
-#else
-__forceinline uint32_t popcnt(const avxb &a)
-{
- return bool(a[0]) + bool(a[1]) + bool(a[2]) + bool(a[3]) + bool(a[4]) + bool(a[5]) + bool(a[6]) +
- bool(a[7]);
-}
-#endif
-
-__forceinline bool reduce_and(const avxb &a)
-{
- return _mm256_movemask_ps(a) == 0xf;
-}
-__forceinline bool reduce_or(const avxb &a)
-{
- return _mm256_movemask_ps(a) != 0x0;
-}
-__forceinline bool all(const avxb &b)
-{
- return _mm256_movemask_ps(b) == 0xf;
-}
-__forceinline bool any(const avxb &b)
-{
- return _mm256_movemask_ps(b) != 0x0;
-}
-__forceinline bool none(const avxb &b)
-{
- return _mm256_movemask_ps(b) == 0x0;
-}
-
-__forceinline uint32_t movemask(const avxb &a)
-{
- return _mm256_movemask_ps(a);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Debug Functions
-////////////////////////////////////////////////////////////////////////////////
-
-ccl_device_inline void print_avxb(const char *label, const avxb &a)
-{
- printf("%s: %d %d %d %d %d %d %d %d\n", label, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
-}
-
-CCL_NAMESPACE_END
-
-#endif
diff --git a/intern/cycles/util/avxf.h b/intern/cycles/util/avxf.h
deleted file mode 100644
index 03a13f30490..00000000000
--- a/intern/cycles/util/avxf.h
+++ /dev/null
@@ -1,379 +0,0 @@
-/* SPDX-License-Identifier: Apache-2.0
- * Copyright 2016 Intel Corporation */
-
-#ifndef __UTIL_AVXF_H__
-#define __UTIL_AVXF_H__
-
-CCL_NAMESPACE_BEGIN
-
-struct avxb;
-
-struct avxf {
- typedef avxf Float;
-
- enum { size = 8 }; /* Number of SIMD elements. */
-
- union {
- __m256 m256;
- float f[8];
- int i[8];
- };
-
- __forceinline avxf()
- {
- }
- __forceinline avxf(const avxf &other)
- {
- m256 = other.m256;
- }
- __forceinline avxf &operator=(const avxf &other)
- {
- m256 = other.m256;
- return *this;
- }
-
- __forceinline avxf(const __m256 a) : m256(a)
- {
- }
- __forceinline avxf(const __m256i a) : m256(_mm256_castsi256_ps(a))
- {
- }
-
- __forceinline operator const __m256 &() const
- {
- return m256;
- }
- __forceinline operator __m256 &()
- {
- return m256;
- }
-
- __forceinline avxf(float a) : m256(_mm256_set1_ps(a))
- {
- }
-
- __forceinline avxf(float high32x4, float low32x4)
- : m256(_mm256_set_ps(
- high32x4, high32x4, high32x4, high32x4, low32x4, low32x4, low32x4, low32x4))
- {
- }
-
- __forceinline avxf(float a3, float a2, float a1, float a0)
- : m256(_mm256_set_ps(a3, a2, a1, a0, a3, a2, a1, a0))
- {
- }
-
- __forceinline avxf(
- float a7, float a6, float a5, float a4, float a3, float a2, float a1, float a0)
- : m256(_mm256_set_ps(a7, a6, a5, a4, a3, a2, a1, a0))
- {
- }
-
- __forceinline avxf(float3 a) : m256(_mm256_set_ps(a.w, a.z, a.y, a.x, a.w, a.z, a.y, a.x))
- {
- }
-
- __forceinline avxf(int a3, int a2, int a1, int a0)
- {
- const __m256i foo = _mm256_set_epi32(a3, a2, a1, a0, a3, a2, a1, a0);
- m256 = _mm256_castsi256_ps(foo);
- }
-
- __forceinline avxf(int a7, int a6, int a5, int a4, int a3, int a2, int a1, int a0)
- {
- const __m256i foo = _mm256_set_epi32(a7, a6, a5, a4, a3, a2, a1, a0);
- m256 = _mm256_castsi256_ps(foo);
- }
-
- __forceinline avxf(__m128 a, __m128 b)
- {
- const __m256 foo = _mm256_castps128_ps256(a);
- m256 = _mm256_insertf128_ps(foo, b, 1);
- }
-
- __forceinline const float &operator[](const size_t i) const
- {
- assert(i < 8);
- return f[i];
- }
- __forceinline float &operator[](const size_t i)
- {
- assert(i < 8);
- return f[i];
- }
-};
-
-__forceinline avxf cross(const avxf &a, const avxf &b)
-{
- avxf r(0.0,
- a[4] * b[5] - a[5] * b[4],
- a[6] * b[4] - a[4] * b[6],
- a[5] * b[6] - a[6] * b[5],
- 0.0,
- a[0] * b[1] - a[1] * b[0],
- a[2] * b[0] - a[0] * b[2],
- a[1] * b[2] - a[2] * b[1]);
- return r;
-}
-
-__forceinline void dot3(const avxf &a, const avxf &b, float &den, float &den2)
-{
- const avxf t = _mm256_mul_ps(a.m256, b.m256);
- den = ((float *)&t)[0] + ((float *)&t)[1] + ((float *)&t)[2];
- den2 = ((float *)&t)[4] + ((float *)&t)[5] + ((float *)&t)[6];
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Unary Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const avxf cast(const __m256i &a)
-{
- return _mm256_castsi256_ps(a);
-}
-
-__forceinline const avxf mm256_sqrt(const avxf &a)
-{
- return _mm256_sqrt_ps(a.m256);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Binary Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const avxf operator+(const avxf &a, const avxf &b)
-{
- return _mm256_add_ps(a.m256, b.m256);
-}
-__forceinline const avxf operator+(const avxf &a, const float &b)
-{
- return a + avxf(b);
-}
-__forceinline const avxf operator+(const float &a, const avxf &b)
-{
- return avxf(a) + b;
-}
-
-__forceinline const avxf operator-(const avxf &a, const avxf &b)
-{
- return _mm256_sub_ps(a.m256, b.m256);
-}
-__forceinline const avxf operator-(const avxf &a, const float &b)
-{
- return a - avxf(b);
-}
-__forceinline const avxf operator-(const float &a, const avxf &b)
-{
- return avxf(a) - b;
-}
-
-__forceinline const avxf operator*(const avxf &a, const avxf &b)
-{
- return _mm256_mul_ps(a.m256, b.m256);
-}
-__forceinline const avxf operator*(const avxf &a, const float &b)
-{
- return a * avxf(b);
-}
-__forceinline const avxf operator*(const float &a, const avxf &b)
-{
- return avxf(a) * b;
-}
-
-__forceinline const avxf operator/(const avxf &a, const avxf &b)
-{
- return _mm256_div_ps(a.m256, b.m256);
-}
-__forceinline const avxf operator/(const avxf &a, const float &b)
-{
- return a / avxf(b);
-}
-__forceinline const avxf operator/(const float &a, const avxf &b)
-{
- return avxf(a) / b;
-}
-
-__forceinline const avxf operator|(const avxf &a, const avxf &b)
-{
- return _mm256_or_ps(a.m256, b.m256);
-}
-
-__forceinline const avxf operator^(const avxf &a, const avxf &b)
-{
- return _mm256_xor_ps(a.m256, b.m256);
-}
-
-__forceinline const avxf operator&(const avxf &a, const avxf &b)
-{
- return _mm256_and_ps(a.m256, b.m256);
-}
-
-__forceinline const avxf max(const avxf &a, const avxf &b)
-{
- return _mm256_max_ps(a.m256, b.m256);
-}
-__forceinline const avxf min(const avxf &a, const avxf &b)
-{
- return _mm256_min_ps(a.m256, b.m256);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Movement/Shifting/Shuffling Functions
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const avxf shuffle(const avxf &a, const __m256i &shuf)
-{
- return _mm256_permutevar_ps(a, shuf);
-}
-
-template<int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7>
-__forceinline const avxf shuffle(const avxf &a)
-{
- return _mm256_permutevar_ps(a, _mm256_set_epi32(i7, i6, i5, i4, i3, i2, i1, i0));
-}
-
-template<size_t i0, size_t i1, size_t i2, size_t i3>
-__forceinline const avxf shuffle(const avxf &a, const avxf &b)
-{
- return _mm256_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
-}
-template<size_t i0, size_t i1, size_t i2, size_t i3>
-__forceinline const avxf shuffle(const avxf &a)
-{
- return shuffle<i0, i1, i2, i3>(a, a);
-}
-template<size_t i0> __forceinline const avxf shuffle(const avxf &a, const avxf &b)
-{
- return shuffle<i0, i0, i0, i0>(a, b);
-}
-template<size_t i0> __forceinline const avxf shuffle(const avxf &a)
-{
- return shuffle<i0>(a, a);
-}
-
-template<size_t i> __forceinline float extract(const avxf &a)
-{
- __m256 b = shuffle<i, i, i, i>(a).m256;
- return _mm256_cvtss_f32(b);
-}
-template<> __forceinline float extract<0>(const avxf &a)
-{
- return _mm256_cvtss_f32(a.m256);
-}
-
-__forceinline ssef low(const avxf &a)
-{
- return _mm256_extractf128_ps(a.m256, 0);
-}
-__forceinline ssef high(const avxf &a)
-{
- return _mm256_extractf128_ps(a.m256, 1);
-}
-
-template<int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7>
-__forceinline const avxf permute(const avxf &a)
-{
-#ifdef __KERNEL_AVX2__
- return _mm256_permutevar8x32_ps(a, _mm256_set_epi32(i7, i6, i5, i4, i3, i2, i1, i0));
-#else
- float temp[8];
- _mm256_storeu_ps((float *)&temp, a);
- return avxf(temp[i7], temp[i6], temp[i5], temp[i4], temp[i3], temp[i2], temp[i1], temp[i0]);
-#endif
-}
-
-template<int S0, int S1, int S2, int S3, int S4, int S5, int S6, int S7>
-ccl_device_inline const avxf set_sign_bit(const avxf &a)
-{
- return a ^ avxf(S7 << 31, S6 << 31, S5 << 31, S4 << 31, S3 << 31, S2 << 31, S1 << 31, S0 << 31);
-}
-
-template<size_t S0, size_t S1, size_t S2, size_t S3, size_t S4, size_t S5, size_t S6, size_t S7>
-ccl_device_inline const avxf blend(const avxf &a, const avxf &b)
-{
- return _mm256_blend_ps(
- a, b, S7 << 0 | S6 << 1 | S5 << 2 | S4 << 3 | S3 << 4 | S2 << 5 | S1 << 6 | S0 << 7);
-}
-
-template<size_t S0, size_t S1, size_t S2, size_t S3>
-ccl_device_inline const avxf blend(const avxf &a, const avxf &b)
-{
- return blend<S0, S1, S2, S3, S0, S1, S2, S3>(a, b);
-}
-
-//#if defined(__KERNEL_SSE41__)
-__forceinline avxf maxi(const avxf &a, const avxf &b)
-{
- const avxf ci = _mm256_max_ps(a, b);
- return ci;
-}
-
-__forceinline avxf mini(const avxf &a, const avxf &b)
-{
- const avxf ci = _mm256_min_ps(a, b);
- return ci;
-}
-//#endif
-
-////////////////////////////////////////////////////////////////////////////////
-/// Ternary Operators
-////////////////////////////////////////////////////////////////////////////////
-__forceinline const avxf madd(const avxf &a, const avxf &b, const avxf &c)
-{
-#ifdef __KERNEL_AVX2__
- return _mm256_fmadd_ps(a, b, c);
-#else
- return c + (a * b);
-#endif
-}
-
-__forceinline const avxf nmadd(const avxf &a, const avxf &b, const avxf &c)
-{
-#ifdef __KERNEL_AVX2__
- return _mm256_fnmadd_ps(a, b, c);
-#else
- return c - (a * b);
-#endif
-}
-__forceinline const avxf msub(const avxf &a, const avxf &b, const avxf &c)
-{
-#ifdef __KERNEL_AVX2__
- return _mm256_fmsub_ps(a, b, c);
-#else
- return (a * b) - c;
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Comparison Operators + Select
-////////////////////////////////////////////////////////////////////////////////
-__forceinline const avxb operator<=(const avxf &a, const avxf &b)
-{
- return _mm256_cmp_ps(a.m256, b.m256, _CMP_LE_OS);
-}
-
-__forceinline const avxf select(const avxb &m, const avxf &t, const avxf &f)
-{
- return _mm256_blendv_ps(f, t, m);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Common Functions
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline avxf mix(const avxf &a, const avxf &b, const avxf &t)
-{
- return madd(t, b, (avxf(1.0f) - t) * a);
-}
-
-#ifndef _mm256_set_m128
-# define _mm256_set_m128(/* __m128 */ hi, /* __m128 */ lo) \
- _mm256_insertf128_ps(_mm256_castps128_ps256(lo), (hi), 0x1)
-#endif
-
-#define _mm256_loadu2_m128(/* float const* */ hiaddr, /* float const* */ loaddr) \
- _mm256_set_m128(_mm_loadu_ps(hiaddr), _mm_loadu_ps(loaddr))
-
-CCL_NAMESPACE_END
-
-#endif
diff --git a/intern/cycles/util/avxi.h b/intern/cycles/util/avxi.h
deleted file mode 100644
index 966a04a6b97..00000000000
--- a/intern/cycles/util/avxi.h
+++ /dev/null
@@ -1,732 +0,0 @@
-/* SPDX-License-Identifier: Apache-2.0
- * Copyright 2009-2013 Intel Corporation */
-
-#ifndef __UTIL_AVXI_H__
-#define __UTIL_AVXI_H__
-
-CCL_NAMESPACE_BEGIN
-
-struct avxb;
-
-struct avxi {
- typedef avxb Mask; // mask type for us
- enum { size = 8 }; // number of SIMD elements
- union { // data
- __m256i m256;
-#if !defined(__KERNEL_AVX2__)
- struct {
- __m128i l, h;
- };
-#endif
- int32_t v[8];
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Constructors, Assignment & Cast Operators
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline avxi()
- {
- }
- __forceinline avxi(const avxi &a)
- {
- m256 = a.m256;
- }
- __forceinline avxi &operator=(const avxi &a)
- {
- m256 = a.m256;
- return *this;
- }
-
- __forceinline avxi(const __m256i a) : m256(a)
- {
- }
- __forceinline operator const __m256i &(void) const
- {
- return m256;
- }
- __forceinline operator __m256i &(void)
- {
- return m256;
- }
-
- __forceinline explicit avxi(const ssei &a)
- : m256(_mm256_insertf128_si256(_mm256_castsi128_si256(a), a, 1))
- {
- }
- __forceinline avxi(const ssei &a, const ssei &b)
- : m256(_mm256_insertf128_si256(_mm256_castsi128_si256(a), b, 1))
- {
- }
-#if defined(__KERNEL_AVX2__)
- __forceinline avxi(const __m128i &a, const __m128i &b)
- : m256(_mm256_insertf128_si256(_mm256_castsi128_si256(a), b, 1))
- {
- }
-#else
- __forceinline avxi(const __m128i &a, const __m128i &b) : l(a), h(b)
- {
- }
-#endif
- __forceinline explicit avxi(const int32_t *const a)
- : m256(_mm256_castps_si256(_mm256_loadu_ps((const float *)a)))
- {
- }
- __forceinline avxi(int32_t a) : m256(_mm256_set1_epi32(a))
- {
- }
- __forceinline avxi(int32_t a, int32_t b) : m256(_mm256_set_epi32(b, a, b, a, b, a, b, a))
- {
- }
- __forceinline avxi(int32_t a, int32_t b, int32_t c, int32_t d)
- : m256(_mm256_set_epi32(d, c, b, a, d, c, b, a))
- {
- }
- __forceinline avxi(
- int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, int32_t f, int32_t g, int32_t h)
- : m256(_mm256_set_epi32(h, g, f, e, d, c, b, a))
- {
- }
-
- __forceinline explicit avxi(const __m256 a) : m256(_mm256_cvtps_epi32(a))
- {
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Constants
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline avxi(ZeroTy) : m256(_mm256_setzero_si256())
- {
- }
-#if defined(__KERNEL_AVX2__)
- __forceinline avxi(OneTy) : m256(_mm256_set1_epi32(1))
- {
- }
- __forceinline avxi(PosInfTy) : m256(_mm256_set1_epi32(pos_inf))
- {
- }
- __forceinline avxi(NegInfTy) : m256(_mm256_set1_epi32(neg_inf))
- {
- }
-#else
- __forceinline avxi(OneTy) : m256(_mm256_set_epi32(1, 1, 1, 1, 1, 1, 1, 1))
- {
- }
- __forceinline avxi(PosInfTy)
- : m256(_mm256_set_epi32(
- pos_inf, pos_inf, pos_inf, pos_inf, pos_inf, pos_inf, pos_inf, pos_inf))
- {
- }
- __forceinline avxi(NegInfTy)
- : m256(_mm256_set_epi32(
- neg_inf, neg_inf, neg_inf, neg_inf, neg_inf, neg_inf, neg_inf, neg_inf))
- {
- }
-#endif
- __forceinline avxi(StepTy) : m256(_mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0))
- {
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Array Access
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline const int32_t &operator[](const size_t i) const
- {
- assert(i < 8);
- return v[i];
- }
- __forceinline int32_t &operator[](const size_t i)
- {
- assert(i < 8);
- return v[i];
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// Unary Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const avxi cast(const __m256 &a)
-{
- return _mm256_castps_si256(a);
-}
-__forceinline const avxi operator+(const avxi &a)
-{
- return a;
-}
-#if defined(__KERNEL_AVX2__)
-__forceinline const avxi operator-(const avxi &a)
-{
- return _mm256_sub_epi32(_mm256_setzero_si256(), a.m256);
-}
-__forceinline const avxi abs(const avxi &a)
-{
- return _mm256_abs_epi32(a.m256);
-}
-#else
-__forceinline const avxi operator-(const avxi &a)
-{
- return avxi(_mm_sub_epi32(_mm_setzero_si128(), a.l), _mm_sub_epi32(_mm_setzero_si128(), a.h));
-}
-__forceinline const avxi abs(const avxi &a)
-{
- return avxi(_mm_abs_epi32(a.l), _mm_abs_epi32(a.h));
-}
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-/// Binary Operators
-////////////////////////////////////////////////////////////////////////////////
-
-#if defined(__KERNEL_AVX2__)
-__forceinline const avxi operator+(const avxi &a, const avxi &b)
-{
- return _mm256_add_epi32(a.m256, b.m256);
-}
-#else
-__forceinline const avxi operator+(const avxi &a, const avxi &b)
-{
- return avxi(_mm_add_epi32(a.l, b.l), _mm_add_epi32(a.h, b.h));
-}
-#endif
-__forceinline const avxi operator+(const avxi &a, const int32_t b)
-{
- return a + avxi(b);
-}
-__forceinline const avxi operator+(const int32_t a, const avxi &b)
-{
- return avxi(a) + b;
-}
-
-#if defined(__KERNEL_AVX2__)
-__forceinline const avxi operator-(const avxi &a, const avxi &b)
-{
- return _mm256_sub_epi32(a.m256, b.m256);
-}
-#else
-__forceinline const avxi operator-(const avxi &a, const avxi &b)
-{
- return avxi(_mm_sub_epi32(a.l, b.l), _mm_sub_epi32(a.h, b.h));
-}
-#endif
-__forceinline const avxi operator-(const avxi &a, const int32_t b)
-{
- return a - avxi(b);
-}
-__forceinline const avxi operator-(const int32_t a, const avxi &b)
-{
- return avxi(a) - b;
-}
-
-#if defined(__KERNEL_AVX2__)
-__forceinline const avxi operator*(const avxi &a, const avxi &b)
-{
- return _mm256_mullo_epi32(a.m256, b.m256);
-}
-#else
-__forceinline const avxi operator*(const avxi &a, const avxi &b)
-{
- return avxi(_mm_mullo_epi32(a.l, b.l), _mm_mullo_epi32(a.h, b.h));
-}
-#endif
-__forceinline const avxi operator*(const avxi &a, const int32_t b)
-{
- return a * avxi(b);
-}
-__forceinline const avxi operator*(const int32_t a, const avxi &b)
-{
- return avxi(a) * b;
-}
-
-#if defined(__KERNEL_AVX2__)
-__forceinline const avxi operator&(const avxi &a, const avxi &b)
-{
- return _mm256_and_si256(a.m256, b.m256);
-}
-#else
-__forceinline const avxi operator&(const avxi &a, const avxi &b)
-{
- return _mm256_castps_si256(_mm256_and_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b)));
-}
-#endif
-__forceinline const avxi operator&(const avxi &a, const int32_t b)
-{
- return a & avxi(b);
-}
-__forceinline const avxi operator&(const int32_t a, const avxi &b)
-{
- return avxi(a) & b;
-}
-
-#if defined(__KERNEL_AVX2__)
-__forceinline const avxi operator|(const avxi &a, const avxi &b)
-{
- return _mm256_or_si256(a.m256, b.m256);
-}
-#else
-__forceinline const avxi operator|(const avxi &a, const avxi &b)
-{
- return _mm256_castps_si256(_mm256_or_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b)));
-}
-#endif
-__forceinline const avxi operator|(const avxi &a, const int32_t b)
-{
- return a | avxi(b);
-}
-__forceinline const avxi operator|(const int32_t a, const avxi &b)
-{
- return avxi(a) | b;
-}
-
-#if defined(__KERNEL_AVX2__)
-__forceinline const avxi operator^(const avxi &a, const avxi &b)
-{
- return _mm256_xor_si256(a.m256, b.m256);
-}
-#else
-__forceinline const avxi operator^(const avxi &a, const avxi &b)
-{
- return _mm256_castps_si256(_mm256_xor_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b)));
-}
-#endif
-__forceinline const avxi operator^(const avxi &a, const int32_t b)
-{
- return a ^ avxi(b);
-}
-__forceinline const avxi operator^(const int32_t a, const avxi &b)
-{
- return avxi(a) ^ b;
-}
-
-#if defined(__KERNEL_AVX2__)
-__forceinline const avxi operator<<(const avxi &a, const int32_t n)
-{
- return _mm256_slli_epi32(a.m256, n);
-}
-__forceinline const avxi operator>>(const avxi &a, const int32_t n)
-{
- return _mm256_srai_epi32(a.m256, n);
-}
-
-__forceinline const avxi sra(const avxi &a, const int32_t b)
-{
- return _mm256_srai_epi32(a.m256, b);
-}
-__forceinline const avxi srl(const avxi &a, const int32_t b)
-{
- return _mm256_srli_epi32(a.m256, b);
-}
-#else
-__forceinline const avxi operator<<(const avxi &a, const int32_t n)
-{
- return avxi(_mm_slli_epi32(a.l, n), _mm_slli_epi32(a.h, n));
-}
-__forceinline const avxi operator>>(const avxi &a, const int32_t n)
-{
- return avxi(_mm_srai_epi32(a.l, n), _mm_srai_epi32(a.h, n));
-}
-
-__forceinline const avxi sra(const avxi &a, const int32_t b)
-{
- return avxi(_mm_srai_epi32(a.l, b), _mm_srai_epi32(a.h, b));
-}
-__forceinline const avxi srl(const avxi &a, const int32_t b)
-{
- return avxi(_mm_srli_epi32(a.l, b), _mm_srli_epi32(a.h, b));
-}
-#endif
-
-#if defined(__KERNEL_AVX2__)
-__forceinline const avxi min(const avxi &a, const avxi &b)
-{
- return _mm256_min_epi32(a.m256, b.m256);
-}
-#else
-__forceinline const avxi min(const avxi &a, const avxi &b)
-{
- return avxi(_mm_min_epi32(a.l, b.l), _mm_min_epi32(a.h, b.h));
-}
-#endif
-__forceinline const avxi min(const avxi &a, const int32_t b)
-{
- return min(a, avxi(b));
-}
-__forceinline const avxi min(const int32_t a, const avxi &b)
-{
- return min(avxi(a), b);
-}
-
-#if defined(__KERNEL_AVX2__)
-__forceinline const avxi max(const avxi &a, const avxi &b)
-{
- return _mm256_max_epi32(a.m256, b.m256);
-}
-#else
-__forceinline const avxi max(const avxi &a, const avxi &b)
-{
- return avxi(_mm_max_epi32(a.l, b.l), _mm_max_epi32(a.h, b.h));
-}
-#endif
-__forceinline const avxi max(const avxi &a, const int32_t b)
-{
- return max(a, avxi(b));
-}
-__forceinline const avxi max(const int32_t a, const avxi &b)
-{
- return max(avxi(a), b);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Assignment Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline avxi &operator+=(avxi &a, const avxi &b)
-{
- return a = a + b;
-}
-__forceinline avxi &operator+=(avxi &a, const int32_t b)
-{
- return a = a + b;
-}
-
-__forceinline avxi &operator-=(avxi &a, const avxi &b)
-{
- return a = a - b;
-}
-__forceinline avxi &operator-=(avxi &a, const int32_t b)
-{
- return a = a - b;
-}
-
-__forceinline avxi &operator*=(avxi &a, const avxi &b)
-{
- return a = a * b;
-}
-__forceinline avxi &operator*=(avxi &a, const int32_t b)
-{
- return a = a * b;
-}
-
-__forceinline avxi &operator&=(avxi &a, const avxi &b)
-{
- return a = a & b;
-}
-__forceinline avxi &operator&=(avxi &a, const int32_t b)
-{
- return a = a & b;
-}
-
-__forceinline avxi &operator|=(avxi &a, const avxi &b)
-{
- return a = a | b;
-}
-__forceinline avxi &operator|=(avxi &a, const int32_t b)
-{
- return a = a | b;
-}
-
-__forceinline avxi &operator^=(avxi &a, const avxi &b)
-{
- return a = a ^ b;
-}
-__forceinline avxi &operator^=(avxi &a, const int32_t b)
-{
- return a = a ^ b;
-}
-
-__forceinline avxi &operator<<=(avxi &a, const int32_t b)
-{
- return a = a << b;
-}
-__forceinline avxi &operator>>=(avxi &a, const int32_t b)
-{
- return a = a >> b;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Comparison Operators + Select
-////////////////////////////////////////////////////////////////////////////////
-
-#if defined(__KERNEL_AVX2__)
-__forceinline const avxb operator==(const avxi &a, const avxi &b)
-{
- return _mm256_castsi256_ps(_mm256_cmpeq_epi32(a.m256, b.m256));
-}
-#else
-__forceinline const avxb operator==(const avxi &a, const avxi &b)
-{
- return avxb(_mm_castsi128_ps(_mm_cmpeq_epi32(a.l, b.l)),
- _mm_castsi128_ps(_mm_cmpeq_epi32(a.h, b.h)));
-}
-#endif
-__forceinline const avxb operator==(const avxi &a, const int32_t b)
-{
- return a == avxi(b);
-}
-__forceinline const avxb operator==(const int32_t a, const avxi &b)
-{
- return avxi(a) == b;
-}
-
-__forceinline const avxb operator!=(const avxi &a, const avxi &b)
-{
- return !(a == b);
-}
-__forceinline const avxb operator!=(const avxi &a, const int32_t b)
-{
- return a != avxi(b);
-}
-__forceinline const avxb operator!=(const int32_t a, const avxi &b)
-{
- return avxi(a) != b;
-}
-
-#if defined(__KERNEL_AVX2__)
-__forceinline const avxb operator<(const avxi &a, const avxi &b)
-{
- return _mm256_castsi256_ps(_mm256_cmpgt_epi32(b.m256, a.m256));
-}
-#else
-__forceinline const avxb operator<(const avxi &a, const avxi &b)
-{
- return avxb(_mm_castsi128_ps(_mm_cmplt_epi32(a.l, b.l)),
- _mm_castsi128_ps(_mm_cmplt_epi32(a.h, b.h)));
-}
-#endif
-__forceinline const avxb operator<(const avxi &a, const int32_t b)
-{
- return a < avxi(b);
-}
-__forceinline const avxb operator<(const int32_t a, const avxi &b)
-{
- return avxi(a) < b;
-}
-
-__forceinline const avxb operator>=(const avxi &a, const avxi &b)
-{
- return !(a < b);
-}
-__forceinline const avxb operator>=(const avxi &a, const int32_t b)
-{
- return a >= avxi(b);
-}
-__forceinline const avxb operator>=(const int32_t a, const avxi &b)
-{
- return avxi(a) >= b;
-}
-
-#if defined(__KERNEL_AVX2__)
-__forceinline const avxb operator>(const avxi &a, const avxi &b)
-{
- return _mm256_castsi256_ps(_mm256_cmpgt_epi32(a.m256, b.m256));
-}
-#else
-__forceinline const avxb operator>(const avxi &a, const avxi &b)
-{
- return avxb(_mm_castsi128_ps(_mm_cmpgt_epi32(a.l, b.l)),
- _mm_castsi128_ps(_mm_cmpgt_epi32(a.h, b.h)));
-}
-#endif
-__forceinline const avxb operator>(const avxi &a, const int32_t b)
-{
- return a > avxi(b);
-}
-__forceinline const avxb operator>(const int32_t a, const avxi &b)
-{
- return avxi(a) > b;
-}
-
-__forceinline const avxb operator<=(const avxi &a, const avxi &b)
-{
- return !(a > b);
-}
-__forceinline const avxb operator<=(const avxi &a, const int32_t b)
-{
- return a <= avxi(b);
-}
-__forceinline const avxb operator<=(const int32_t a, const avxi &b)
-{
- return avxi(a) <= b;
-}
-
-__forceinline const avxi select(const avxb &m, const avxi &t, const avxi &f)
-{
- return _mm256_castps_si256(_mm256_blendv_ps(_mm256_castsi256_ps(f), _mm256_castsi256_ps(t), m));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Movement/Shifting/Shuffling Functions
-////////////////////////////////////////////////////////////////////////////////
-
-#if defined(__KERNEL_AVX2__)
-__forceinline avxi unpacklo(const avxi &a, const avxi &b)
-{
- return _mm256_unpacklo_epi32(a.m256, b.m256);
-}
-__forceinline avxi unpackhi(const avxi &a, const avxi &b)
-{
- return _mm256_unpackhi_epi32(a.m256, b.m256);
-}
-#else
-__forceinline avxi unpacklo(const avxi &a, const avxi &b)
-{
- return _mm256_castps_si256(_mm256_unpacklo_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b)));
-}
-__forceinline avxi unpackhi(const avxi &a, const avxi &b)
-{
- return _mm256_castps_si256(_mm256_unpackhi_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b)));
-}
-#endif
-
-template<size_t i> __forceinline const avxi shuffle(const avxi &a)
-{
- return _mm256_castps_si256(_mm256_permute_ps(_mm256_castsi256_ps(a), _MM_SHUFFLE(i, i, i, i)));
-}
-
-template<size_t i0, size_t i1> __forceinline const avxi shuffle(const avxi &a)
-{
- return _mm256_permute2f128_si256(a, a, (i1 << 4) | (i0 << 0));
-}
-
-template<size_t i0, size_t i1> __forceinline const avxi shuffle(const avxi &a, const avxi &b)
-{
- return _mm256_permute2f128_si256(a, b, (i1 << 4) | (i0 << 0));
-}
-
-template<size_t i0, size_t i1, size_t i2, size_t i3>
-__forceinline const avxi shuffle(const avxi &a)
-{
- return _mm256_castps_si256(
- _mm256_permute_ps(_mm256_castsi256_ps(a), _MM_SHUFFLE(i3, i2, i1, i0)));
-}
-
-template<size_t i0, size_t i1, size_t i2, size_t i3>
-__forceinline const avxi shuffle(const avxi &a, const avxi &b)
-{
- return _mm256_castps_si256(_mm256_shuffle_ps(
- _mm256_castsi256_ps(a), _mm256_castsi256_ps(b), _MM_SHUFFLE(i3, i2, i1, i0)));
-}
-
-template<> __forceinline const avxi shuffle<0, 0, 2, 2>(const avxi &b)
-{
- return _mm256_castps_si256(_mm256_moveldup_ps(_mm256_castsi256_ps(b)));
-}
-template<> __forceinline const avxi shuffle<1, 1, 3, 3>(const avxi &b)
-{
- return _mm256_castps_si256(_mm256_movehdup_ps(_mm256_castsi256_ps(b)));
-}
-template<> __forceinline const avxi shuffle<0, 1, 0, 1>(const avxi &b)
-{
- return _mm256_castps_si256(
- _mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(_mm256_castsi256_ps(b)))));
-}
-
-__forceinline const avxi broadcast(const int *ptr)
-{
- return _mm256_castps_si256(_mm256_broadcast_ss((const float *)ptr));
-}
-template<size_t i> __forceinline const avxi insert(const avxi &a, const ssei &b)
-{
- return _mm256_insertf128_si256(a, b, i);
-}
-template<size_t i> __forceinline const ssei extract(const avxi &a)
-{
- return _mm256_extractf128_si256(a, i);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Reductions
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const avxi vreduce_min2(const avxi &v)
-{
- return min(v, shuffle<1, 0, 3, 2>(v));
-}
-__forceinline const avxi vreduce_min4(const avxi &v)
-{
- avxi v1 = vreduce_min2(v);
- return min(v1, shuffle<2, 3, 0, 1>(v1));
-}
-__forceinline const avxi vreduce_min(const avxi &v)
-{
- avxi v1 = vreduce_min4(v);
- return min(v1, shuffle<1, 0>(v1));
-}
-
-__forceinline const avxi vreduce_max2(const avxi &v)
-{
- return max(v, shuffle<1, 0, 3, 2>(v));
-}
-__forceinline const avxi vreduce_max4(const avxi &v)
-{
- avxi v1 = vreduce_max2(v);
- return max(v1, shuffle<2, 3, 0, 1>(v1));
-}
-__forceinline const avxi vreduce_max(const avxi &v)
-{
- avxi v1 = vreduce_max4(v);
- return max(v1, shuffle<1, 0>(v1));
-}
-
-__forceinline const avxi vreduce_add2(const avxi &v)
-{
- return v + shuffle<1, 0, 3, 2>(v);
-}
-__forceinline const avxi vreduce_add4(const avxi &v)
-{
- avxi v1 = vreduce_add2(v);
- return v1 + shuffle<2, 3, 0, 1>(v1);
-}
-__forceinline const avxi vreduce_add(const avxi &v)
-{
- avxi v1 = vreduce_add4(v);
- return v1 + shuffle<1, 0>(v1);
-}
-
-__forceinline int reduce_min(const avxi &v)
-{
- return extract<0>(extract<0>(vreduce_min(v)));
-}
-__forceinline int reduce_max(const avxi &v)
-{
- return extract<0>(extract<0>(vreduce_max(v)));
-}
-__forceinline int reduce_add(const avxi &v)
-{
- return extract<0>(extract<0>(vreduce_add(v)));
-}
-
-__forceinline uint32_t select_min(const avxi &v)
-{
- return __bsf(movemask(v == vreduce_min(v)));
-}
-__forceinline uint32_t select_max(const avxi &v)
-{
- return __bsf(movemask(v == vreduce_max(v)));
-}
-
-__forceinline uint32_t select_min(const avxb &valid, const avxi &v)
-{
- const avxi a = select(valid, v, avxi(pos_inf));
- return __bsf(movemask(valid & (a == vreduce_min(a))));
-}
-__forceinline uint32_t select_max(const avxb &valid, const avxi &v)
-{
- const avxi a = select(valid, v, avxi(neg_inf));
- return __bsf(movemask(valid & (a == vreduce_max(a))));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Output Operators
-////////////////////////////////////////////////////////////////////////////////
-
-ccl_device_inline void print_avxi(const char *label, const avxi &a)
-{
- printf("%s: %d %d %d %d %d %d %d %d\n", label, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
-}
-
-CCL_NAMESPACE_END
-
-#endif
diff --git a/intern/cycles/util/color.h b/intern/cycles/util/color.h
index 537f8ab6771..93e984120f2 100644
--- a/intern/cycles/util/color.h
+++ b/intern/cycles/util/color.h
@@ -228,28 +228,27 @@ ccl_device float3 xyY_to_xyz(float x, float y, float Y)
* exp = exponent, encoded as uint32_t
* e2coeff = 2^(127/exponent - 127) * bias_coeff^(1/exponent), encoded as uint32_t
*/
-template<unsigned exp, unsigned e2coeff> ccl_device_inline ssef fastpow(const ssef &arg)
+template<unsigned exp, unsigned e2coeff> ccl_device_inline float4 fastpow(const float4 &arg)
{
- ssef ret;
- ret = arg * cast(ssei(e2coeff));
- ret = ssef(cast(ret));
- ret = ret * cast(ssei(exp));
- ret = cast(ssei(ret));
+ float4 ret = arg * cast(make_int4(e2coeff));
+ ret = make_float4(cast(ret));
+ ret = ret * cast(make_int4(exp));
+ ret = cast(make_int4(ret));
return ret;
}
/* Improve x ^ 1.0f/5.0f solution with Newton-Raphson method */
-ccl_device_inline ssef improve_5throot_solution(const ssef &old_result, const ssef &x)
+ccl_device_inline float4 improve_5throot_solution(const float4 &old_result, const float4 &x)
{
- ssef approx2 = old_result * old_result;
- ssef approx4 = approx2 * approx2;
- ssef t = x / approx4;
- ssef summ = madd(ssef(4.0f), old_result, t);
- return summ * ssef(1.0f / 5.0f);
+ float4 approx2 = old_result * old_result;
+ float4 approx4 = approx2 * approx2;
+ float4 t = x / approx4;
+ float4 summ = madd(make_float4(4.0f), old_result, t);
+ return summ * make_float4(1.0f / 5.0f);
}
/* Calculate powf(x, 2.4). Working domain: 1e-10 < x < 1e+10 */
-ccl_device_inline ssef fastpow24(const ssef &arg)
+ccl_device_inline float4 fastpow24(const float4 &arg)
{
/* max, avg and |avg| errors were calculated in gcc without FMA instructions
* The final precision should be better than powf in glibc */
@@ -257,9 +256,10 @@ ccl_device_inline ssef fastpow24(const ssef &arg)
/* Calculate x^4/5, coefficient 0.994 was constructed manually to minimize avg error */
/* 0x3F4CCCCD = 4/5 */
/* 0x4F55A7FB = 2^(127/(4/5) - 127) * 0.994^(1/(4/5)) */
- ssef x = fastpow<0x3F4CCCCD, 0x4F55A7FB>(arg); // error max = 0.17 avg = 0.0018 |avg| = 0.05
- ssef arg2 = arg * arg;
- ssef arg4 = arg2 * arg2;
+ float4 x = fastpow<0x3F4CCCCD, 0x4F55A7FB>(
+ arg); // error max = 0.17 avg = 0.0018 |avg| = 0.05
+ float4 arg2 = arg * arg;
+ float4 arg4 = arg2 * arg2;
/* error max = 0.018 avg = 0.0031 |avg| = 0.0031 */
x = improve_5throot_solution(x, arg4);
@@ -271,12 +271,12 @@ ccl_device_inline ssef fastpow24(const ssef &arg)
return x * (x * x);
}
-ccl_device ssef color_srgb_to_linear(const ssef &c)
+ccl_device float4 color_srgb_to_linear(const float4 &c)
{
- sseb cmp = c < ssef(0.04045f);
- ssef lt = max(c * ssef(1.0f / 12.92f), ssef(0.0f));
- ssef gtebase = (c + ssef(0.055f)) * ssef(1.0f / 1.055f); /* fma */
- ssef gte = fastpow24(gtebase);
+ int4 cmp = c < make_float4(0.04045f);
+ float4 lt = max(c * make_float4(1.0f / 12.92f), make_float4(0.0f));
+ float4 gtebase = (c + make_float4(0.055f)) * make_float4(1.0f / 1.055f); /* fma */
+ float4 gte = fastpow24(gtebase);
return select(cmp, lt, gte);
}
#endif /* __KERNEL_SSE2__ */
@@ -302,10 +302,8 @@ ccl_device float4 color_linear_to_srgb_v4(float4 c)
ccl_device float4 color_srgb_to_linear_v4(float4 c)
{
#ifdef __KERNEL_SSE2__
- ssef r_ssef;
- float4 &r = (float4 &)r_ssef;
- r = c;
- r_ssef = color_srgb_to_linear(r_ssef);
+ float4 r = c;
+ r = color_srgb_to_linear(r);
r.w = c.w;
return r;
#else
diff --git a/intern/cycles/util/defines.h b/intern/cycles/util/defines.h
index 1969529eff0..d5be14c8eba 100644
--- a/intern/cycles/util/defines.h
+++ b/intern/cycles/util/defines.h
@@ -23,6 +23,7 @@
/* Leave inlining decisions to compiler for these, the inline keyword here
* is not about performance but including function definitions in headers. */
# define ccl_device static inline
+# define ccl_device_extern extern "C"
# define ccl_device_noinline static inline
# define ccl_device_noinline_cpu ccl_device_noinline
diff --git a/intern/cycles/util/guiding.h b/intern/cycles/util/guiding.h
new file mode 100644
index 00000000000..7dc74f0d8c0
--- /dev/null
+++ b/intern/cycles/util/guiding.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2022 Blender Foundation */
+
+#pragma once
+
+#ifdef WITH_PATH_GUIDING
+# include <openpgl/cpp/OpenPGL.h>
+# include <openpgl/version.h>
+#endif
+
+#include "util/system.h"
+
+CCL_NAMESPACE_BEGIN
+
+static int guiding_device_type()
+{
+#ifdef WITH_PATH_GUIDING
+# if defined(__ARM_NEON)
+ return 8;
+# else
+# if OPENPGL_VERSION_MINOR >= 4
+ if (system_cpu_support_avx2()) {
+ return 8;
+ }
+# endif
+ if (system_cpu_support_sse41()) {
+ return 4;
+ }
+ return 0;
+# endif
+#else
+ return 0;
+#endif
+}
+
+static inline bool guiding_supported()
+{
+ return guiding_device_type() != 0;
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/util/half.h b/intern/cycles/util/half.h
index c668638eb02..5665dd4c075 100644
--- a/intern/cycles/util/half.h
+++ b/intern/cycles/util/half.h
@@ -154,17 +154,17 @@ ccl_device_inline half float_to_half_display(const float f)
ccl_device_inline half4 float4_to_half4_display(const float4 f)
{
-#ifdef __KERNEL_SSE2__
+#ifdef __KERNEL_SSE__
/* CPU: SSE and AVX. */
- ssef x = min(max(load4f(f), 0.0f), 65504.0f);
+ float4 x = min(max(f, make_float4(0.0f)), make_float4(65504.0f));
# ifdef __KERNEL_AVX2__
- ssei rpack = _mm_cvtps_ph(x, 0);
+ int4 rpack = int4(_mm_cvtps_ph(x, 0));
# else
- ssei absolute = cast(x) & 0x7FFFFFFF;
- ssei Z = absolute + 0xC8000000;
- ssei result = andnot(absolute < 0x38800000, Z);
- ssei rshift = (result >> 13) & 0x7FFF;
- ssei rpack = _mm_packs_epi32(rshift, rshift);
+ int4 absolute = cast(x) & make_int4(0x7FFFFFFF);
+ int4 Z = absolute + make_int4(0xC8000000);
+ int4 result = andnot(absolute < make_int4(0x38800000), Z);
+ int4 rshift = (result >> 13) & make_int4(0x7FFF);
+ int4 rpack = int4(_mm_packs_epi32(rshift, rshift));
# endif
half4 h;
_mm_storel_pi((__m64 *)&h, _mm_castsi128_ps(rpack));
diff --git a/intern/cycles/util/hash.h b/intern/cycles/util/hash.h
index 4f83f331229..74210ff020e 100644
--- a/intern/cycles/util/hash.h
+++ b/intern/cycles/util/hash.h
@@ -222,7 +222,7 @@ ccl_device_inline float3 hash_float4_to_float3(float4 k)
/* SSE Versions Of Jenkins Lookup3 Hash Functions */
-#ifdef __KERNEL_SSE2__
+#ifdef __KERNEL_SSE__
# define rot(x, k) (((x) << (k)) | (srl(x, 32 - (k))))
# define mix(a, b, c) \
@@ -265,10 +265,10 @@ ccl_device_inline float3 hash_float4_to_float3(float4 k)
c -= rot(b, 24); \
}
-ccl_device_inline ssei hash_ssei(ssei kx)
+ccl_device_inline int4 hash_int4(int4 kx)
{
- ssei a, b, c;
- a = b = c = ssei(0xdeadbeef + (1 << 2) + 13);
+ int4 a, b, c;
+ a = b = c = make_int4(0xdeadbeef + (1 << 2) + 13);
a += kx;
final(a, b, c);
@@ -276,10 +276,10 @@ ccl_device_inline ssei hash_ssei(ssei kx)
return c;
}
-ccl_device_inline ssei hash_ssei2(ssei kx, ssei ky)
+ccl_device_inline int4 hash_int4_2(int4 kx, int4 ky)
{
- ssei a, b, c;
- a = b = c = ssei(0xdeadbeef + (2 << 2) + 13);
+ int4 a, b, c;
+ a = b = c = make_int4(0xdeadbeef + (2 << 2) + 13);
b += ky;
a += kx;
@@ -288,10 +288,10 @@ ccl_device_inline ssei hash_ssei2(ssei kx, ssei ky)
return c;
}
-ccl_device_inline ssei hash_ssei3(ssei kx, ssei ky, ssei kz)
+ccl_device_inline int4 hash_int4_3(int4 kx, int4 ky, int4 kz)
{
- ssei a, b, c;
- a = b = c = ssei(0xdeadbeef + (3 << 2) + 13);
+ int4 a, b, c;
+ a = b = c = make_int4(0xdeadbeef + (3 << 2) + 13);
c += kz;
b += ky;
@@ -301,10 +301,10 @@ ccl_device_inline ssei hash_ssei3(ssei kx, ssei ky, ssei kz)
return c;
}
-ccl_device_inline ssei hash_ssei4(ssei kx, ssei ky, ssei kz, ssei kw)
+ccl_device_inline int4 hash_int4_4(int4 kx, int4 ky, int4 kz, int4 kw)
{
- ssei a, b, c;
- a = b = c = ssei(0xdeadbeef + (4 << 2) + 13);
+ int4 a, b, c;
+ a = b = c = make_int4(0xdeadbeef + (4 << 2) + 13);
a += kx;
b += ky;
@@ -317,11 +317,11 @@ ccl_device_inline ssei hash_ssei4(ssei kx, ssei ky, ssei kz, ssei kw)
return c;
}
-# if defined(__KERNEL_AVX__)
-ccl_device_inline avxi hash_avxi(avxi kx)
+# if defined(__KERNEL_AVX2__)
+ccl_device_inline vint8 hash_int8(vint8 kx)
{
- avxi a, b, c;
- a = b = c = avxi(0xdeadbeef + (1 << 2) + 13);
+ vint8 a, b, c;
+ a = b = c = make_vint8(0xdeadbeef + (1 << 2) + 13);
a += kx;
final(a, b, c);
@@ -329,10 +329,10 @@ ccl_device_inline avxi hash_avxi(avxi kx)
return c;
}
-ccl_device_inline avxi hash_avxi2(avxi kx, avxi ky)
+ccl_device_inline vint8 hash_int8_2(vint8 kx, vint8 ky)
{
- avxi a, b, c;
- a = b = c = avxi(0xdeadbeef + (2 << 2) + 13);
+ vint8 a, b, c;
+ a = b = c = make_vint8(0xdeadbeef + (2 << 2) + 13);
b += ky;
a += kx;
@@ -341,10 +341,10 @@ ccl_device_inline avxi hash_avxi2(avxi kx, avxi ky)
return c;
}
-ccl_device_inline avxi hash_avxi3(avxi kx, avxi ky, avxi kz)
+ccl_device_inline vint8 hash_int8_3(vint8 kx, vint8 ky, vint8 kz)
{
- avxi a, b, c;
- a = b = c = avxi(0xdeadbeef + (3 << 2) + 13);
+ vint8 a, b, c;
+ a = b = c = make_vint8(0xdeadbeef + (3 << 2) + 13);
c += kz;
b += ky;
@@ -354,10 +354,10 @@ ccl_device_inline avxi hash_avxi3(avxi kx, avxi ky, avxi kz)
return c;
}
-ccl_device_inline avxi hash_avxi4(avxi kx, avxi ky, avxi kz, avxi kw)
+ccl_device_inline vint8 hash_int8_4(vint8 kx, vint8 ky, vint8 kz, vint8 kw)
{
- avxi a, b, c;
- a = b = c = avxi(0xdeadbeef + (4 << 2) + 13);
+ vint8 a, b, c;
+ a = b = c = make_vint8(0xdeadbeef + (4 << 2) + 13);
a += kx;
b += ky;
diff --git a/intern/cycles/util/math.h b/intern/cycles/util/math.h
index 0905b3ec5c9..0fbe7a67a4f 100644
--- a/intern/cycles/util/math.h
+++ b/intern/cycles/util/math.h
@@ -417,15 +417,11 @@ ccl_device_inline int floor_to_int(float f)
return float_to_int(floorf(f));
}
-ccl_device_inline int quick_floor_to_int(float x)
-{
- return float_to_int(x) - ((x < 0) ? 1 : 0);
-}
-
ccl_device_inline float floorfrac(float x, ccl_private int *i)
{
- *i = quick_floor_to_int(x);
- return x - *i;
+ float f = floorf(x);
+ *i = float_to_int(f);
+ return x - f;
}
ccl_device_inline int ceil_to_int(float f)
@@ -536,12 +532,14 @@ CCL_NAMESPACE_END
#include "util/math_int2.h"
#include "util/math_int3.h"
#include "util/math_int4.h"
+#include "util/math_int8.h"
#include "util/math_float2.h"
-#include "util/math_float3.h"
#include "util/math_float4.h"
#include "util/math_float8.h"
+#include "util/math_float3.h"
+
#include "util/rect.h"
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/util/math_fast.h b/intern/cycles/util/math_fast.h
index 142a664a1d2..fc7eadb112b 100644
--- a/intern/cycles/util/math_fast.h
+++ b/intern/cycles/util/math_fast.h
@@ -589,7 +589,7 @@ ccl_device_inline float fast_erfcf(float x)
ccl_device_inline float fast_ierff(float x)
{
/* From: Approximating the `erfinv` function by Mike Giles. */
- /* To avoid trouble at the limit, clamp input to 1-eps. */
+ /* To avoid trouble at the limit, clamp input to 1-epsilon. */
float a = fabsf(x);
if (a > 0.99999994f) {
a = 0.99999994f;
diff --git a/intern/cycles/util/math_float2.h b/intern/cycles/util/math_float2.h
index 542dad93467..ad806d0f08a 100644
--- a/intern/cycles/util/math_float2.h
+++ b/intern/cycles/util/math_float2.h
@@ -10,55 +10,6 @@
CCL_NAMESPACE_BEGIN
-/*******************************************************************************
- * Declaration.
- */
-
-#if !defined(__KERNEL_METAL__)
-ccl_device_inline float2 operator-(const float2 &a);
-ccl_device_inline float2 operator*(const float2 &a, const float2 &b);
-ccl_device_inline float2 operator*(const float2 &a, float f);
-ccl_device_inline float2 operator*(float f, const float2 &a);
-ccl_device_inline float2 operator/(float f, const float2 &a);
-ccl_device_inline float2 operator/(const float2 &a, float f);
-ccl_device_inline float2 operator/(const float2 &a, const float2 &b);
-ccl_device_inline float2 operator+(const float2 &a, const float f);
-ccl_device_inline float2 operator+(const float2 &a, const float2 &b);
-ccl_device_inline float2 operator-(const float2 &a, const float f);
-ccl_device_inline float2 operator-(const float2 &a, const float2 &b);
-ccl_device_inline float2 operator+=(float2 &a, const float2 &b);
-ccl_device_inline float2 operator*=(float2 &a, const float2 &b);
-ccl_device_inline float2 operator*=(float2 &a, float f);
-ccl_device_inline float2 operator/=(float2 &a, const float2 &b);
-ccl_device_inline float2 operator/=(float2 &a, float f);
-
-ccl_device_inline bool operator==(const float2 &a, const float2 &b);
-ccl_device_inline bool operator!=(const float2 &a, const float2 &b);
-
-ccl_device_inline bool is_zero(const float2 &a);
-ccl_device_inline float average(const float2 &a);
-ccl_device_inline float distance(const float2 &a, const float2 &b);
-ccl_device_inline float dot(const float2 &a, const float2 &b);
-ccl_device_inline float cross(const float2 &a, const float2 &b);
-ccl_device_inline float len(const float2 a);
-ccl_device_inline float2 normalize(const float2 &a);
-ccl_device_inline float2 normalize_len(const float2 &a, float *t);
-ccl_device_inline float2 safe_normalize(const float2 &a);
-ccl_device_inline float2 min(const float2 &a, const float2 &b);
-ccl_device_inline float2 max(const float2 &a, const float2 &b);
-ccl_device_inline float2 clamp(const float2 &a, const float2 &mn, const float2 &mx);
-ccl_device_inline float2 fabs(const float2 &a);
-ccl_device_inline float2 as_float2(const float4 &a);
-ccl_device_inline float2 interp(const float2 &a, const float2 &b, float t);
-ccl_device_inline float2 floor(const float2 &a);
-#endif /* !__KERNEL_METAL__ */
-
-ccl_device_inline float2 safe_divide_float2_float(const float2 a, const float b);
-
-/*******************************************************************************
- * Definition.
- */
-
ccl_device_inline float2 zero_float2()
{
return make_float2(0.0f, 0.0f);
@@ -75,63 +26,63 @@ ccl_device_inline float2 operator-(const float2 &a)
return make_float2(-a.x, -a.y);
}
-ccl_device_inline float2 operator*(const float2 &a, const float2 &b)
+ccl_device_inline float2 operator*(const float2 a, const float2 b)
{
return make_float2(a.x * b.x, a.y * b.y);
}
-ccl_device_inline float2 operator*(const float2 &a, float f)
+ccl_device_inline float2 operator*(const float2 a, float f)
{
return make_float2(a.x * f, a.y * f);
}
-ccl_device_inline float2 operator*(float f, const float2 &a)
+ccl_device_inline float2 operator*(float f, const float2 a)
{
return make_float2(a.x * f, a.y * f);
}
-ccl_device_inline float2 operator/(float f, const float2 &a)
+ccl_device_inline float2 operator/(float f, const float2 a)
{
return make_float2(f / a.x, f / a.y);
}
-ccl_device_inline float2 operator/(const float2 &a, float f)
+ccl_device_inline float2 operator/(const float2 a, float f)
{
float invf = 1.0f / f;
return make_float2(a.x * invf, a.y * invf);
}
-ccl_device_inline float2 operator/(const float2 &a, const float2 &b)
+ccl_device_inline float2 operator/(const float2 a, const float2 b)
{
return make_float2(a.x / b.x, a.y / b.y);
}
-ccl_device_inline float2 operator+(const float2 &a, const float f)
+ccl_device_inline float2 operator+(const float2 a, const float2 b)
{
- return a + make_float2(f, f);
+ return make_float2(a.x + b.x, a.y + b.y);
}
-ccl_device_inline float2 operator+(const float2 &a, const float2 &b)
+ccl_device_inline float2 operator+(const float2 a, const float f)
{
- return make_float2(a.x + b.x, a.y + b.y);
+ return a + make_float2(f, f);
}
-ccl_device_inline float2 operator-(const float2 &a, const float f)
+ccl_device_inline float2 operator-(const float2 a, const float2 b)
{
- return a - make_float2(f, f);
+ return make_float2(a.x - b.x, a.y - b.y);
}
-ccl_device_inline float2 operator-(const float2 &a, const float2 &b)
+ccl_device_inline float2 operator-(const float2 a, const float f)
{
- return make_float2(a.x - b.x, a.y - b.y);
+ return a - make_float2(f, f);
}
-ccl_device_inline float2 operator+=(float2 &a, const float2 &b)
+ccl_device_inline float2 operator+=(float2 &a, const float2 b)
{
return a = a + b;
}
-ccl_device_inline float2 operator*=(float2 &a, const float2 &b)
+ccl_device_inline float2 operator*=(float2 &a, const float2 b)
{
return a = a * b;
}
@@ -141,7 +92,7 @@ ccl_device_inline float2 operator*=(float2 &a, float f)
return a = a * f;
}
-ccl_device_inline float2 operator/=(float2 &a, const float2 &b)
+ccl_device_inline float2 operator/=(float2 &a, const float2 b)
{
return a = a / b;
}
@@ -152,74 +103,81 @@ ccl_device_inline float2 operator/=(float2 &a, float f)
return a = a * invf;
}
-ccl_device_inline bool operator==(const float2 &a, const float2 &b)
+ccl_device_inline bool operator==(const float2 a, const float2 b)
{
return (a.x == b.x && a.y == b.y);
}
-ccl_device_inline bool operator!=(const float2 &a, const float2 &b)
+ccl_device_inline bool operator!=(const float2 a, const float2 b)
{
return !(a == b);
}
-ccl_device_inline bool is_zero(const float2 &a)
+ccl_device_inline bool is_zero(const float2 a)
{
return (a.x == 0.0f && a.y == 0.0f);
}
-ccl_device_inline float average(const float2 &a)
+ccl_device_inline float average(const float2 a)
{
return (a.x + a.y) * (1.0f / 2.0f);
}
-ccl_device_inline float distance(const float2 &a, const float2 &b)
+ccl_device_inline float dot(const float2 a, const float2 b)
{
- return len(a - b);
+ return a.x * b.x + a.y * b.y;
}
+#endif
-ccl_device_inline float dot(const float2 &a, const float2 &b)
+ccl_device_inline float len(const float2 a)
{
- return a.x * b.x + a.y * b.y;
+ return sqrtf(dot(a, a));
}
-ccl_device_inline float cross(const float2 &a, const float2 &b)
+#if !defined(__KERNEL_METAL__)
+ccl_device_inline float distance(const float2 a, const float2 b)
+{
+ return len(a - b);
+}
+
+ccl_device_inline float cross(const float2 a, const float2 b)
{
return (a.x * b.y - a.y * b.x);
}
-ccl_device_inline float2 normalize(const float2 &a)
+ccl_device_inline float2 normalize(const float2 a)
{
return a / len(a);
}
-ccl_device_inline float2 normalize_len(const float2 &a, ccl_private float *t)
+ccl_device_inline float2 normalize_len(const float2 a, ccl_private float *t)
{
*t = len(a);
return a / (*t);
}
-ccl_device_inline float2 safe_normalize(const float2 &a)
+ccl_device_inline float2 safe_normalize(const float2 a)
{
float t = len(a);
return (t != 0.0f) ? a / t : a;
}
-ccl_device_inline float2 min(const float2 &a, const float2 &b)
+ccl_device_inline float2 min(const float2 a, const float2 b)
{
return make_float2(min(a.x, b.x), min(a.y, b.y));
}
-ccl_device_inline float2 max(const float2 &a, const float2 &b)
+ccl_device_inline float2 max(const float2 a, const float2 b)
{
return make_float2(max(a.x, b.x), max(a.y, b.y));
}
-ccl_device_inline float2 clamp(const float2 &a, const float2 &mn, const float2 &mx)
+ccl_device_inline float2 clamp(const float2 a, const float2 mn, const float2 mx)
{
return min(max(a, mn), mx);
}
-ccl_device_inline float2 fabs(const float2 &a)
+ccl_device_inline float2 fabs(const float2 a)
{
return make_float2(fabsf(a.x), fabsf(a.y));
}
@@ -229,28 +187,23 @@ ccl_device_inline float2 as_float2(const float4 &a)
return make_float2(a.x, a.y);
}
-ccl_device_inline float2 interp(const float2 &a, const float2 &b, float t)
+ccl_device_inline float2 interp(const float2 a, const float2 b, float t)
{
return a + t * (b - a);
}
-ccl_device_inline float2 mix(const float2 &a, const float2 &b, float t)
+ccl_device_inline float2 mix(const float2 a, const float2 b, float t)
{
return a + t * (b - a);
}
-ccl_device_inline float2 floor(const float2 &a)
+ccl_device_inline float2 floor(const float2 a)
{
return make_float2(floorf(a.x), floorf(a.y));
}
#endif /* !__KERNEL_METAL__ */
-ccl_device_inline float len(const float2 a)
-{
- return sqrtf(dot(a, a));
-}
-
ccl_device_inline float2 safe_divide_float2_float(const float2 a, const float b)
{
return (b != 0.0f) ? a / b : zero_float2();
diff --git a/intern/cycles/util/math_float3.h b/intern/cycles/util/math_float3.h
index c408eadf195..79ee86d9c82 100644
--- a/intern/cycles/util/math_float3.h
+++ b/intern/cycles/util/math_float3.h
@@ -1,4 +1,5 @@
/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2013 Intel Corporation
* Copyright 2011-2022 Blender Foundation */
#ifndef __UTIL_MATH_FLOAT3_H__
@@ -10,73 +11,6 @@
CCL_NAMESPACE_BEGIN
-/*******************************************************************************
- * Declaration.
- */
-
-#if !defined(__KERNEL_METAL__)
-ccl_device_inline float3 operator-(const float3 &a);
-ccl_device_inline float3 operator*(const float3 &a, const float3 &b);
-ccl_device_inline float3 operator*(const float3 &a, const float f);
-ccl_device_inline float3 operator*(const float f, const float3 &a);
-ccl_device_inline float3 operator/(const float f, const float3 &a);
-ccl_device_inline float3 operator/(const float3 &a, const float f);
-ccl_device_inline float3 operator/(const float3 &a, const float3 &b);
-ccl_device_inline float3 operator+(const float3 &a, const float f);
-ccl_device_inline float3 operator+(const float3 &a, const float3 &b);
-ccl_device_inline float3 operator-(const float3 &a, const float f);
-ccl_device_inline float3 operator-(const float3 &a, const float3 &b);
-ccl_device_inline float3 operator+=(float3 &a, const float3 &b);
-ccl_device_inline float3 operator-=(float3 &a, const float3 &b);
-ccl_device_inline float3 operator*=(float3 &a, const float3 &b);
-ccl_device_inline float3 operator*=(float3 &a, float f);
-ccl_device_inline float3 operator/=(float3 &a, const float3 &b);
-ccl_device_inline float3 operator/=(float3 &a, float f);
-
-ccl_device_inline bool operator==(const float3 &a, const float3 &b);
-ccl_device_inline bool operator!=(const float3 &a, const float3 &b);
-
-ccl_device_inline float distance(const float3 &a, const float3 &b);
-ccl_device_inline float dot(const float3 &a, const float3 &b);
-ccl_device_inline float dot_xy(const float3 &a, const float3 &b);
-ccl_device_inline float3 cross(const float3 &a, const float3 &b);
-ccl_device_inline float3 normalize(const float3 &a);
-ccl_device_inline float3 min(const float3 &a, const float3 &b);
-ccl_device_inline float3 max(const float3 &a, const float3 &b);
-ccl_device_inline float3 clamp(const float3 &a, const float3 &mn, const float3 &mx);
-ccl_device_inline float3 fabs(const float3 &a);
-ccl_device_inline float3 mix(const float3 &a, const float3 &b, float t);
-ccl_device_inline float3 rcp(const float3 &a);
-ccl_device_inline float3 sqrt(const float3 &a);
-ccl_device_inline float3 floor(const float3 &a);
-ccl_device_inline float3 ceil(const float3 &a);
-ccl_device_inline float3 reflect(const float3 incident, const float3 normal);
-#endif /* !defined(__KERNEL_METAL__) */
-
-ccl_device_inline float reduce_min(float3 a);
-ccl_device_inline float reduce_max(float3 a);
-ccl_device_inline float len(const float3 a);
-ccl_device_inline float len_squared(const float3 a);
-
-ccl_device_inline float3 project(const float3 v, const float3 v_proj);
-
-ccl_device_inline float3 safe_normalize(const float3 a);
-ccl_device_inline float3 normalize_len(const float3 a, ccl_private float *t);
-ccl_device_inline float3 safe_normalize_len(const float3 a, ccl_private float *t);
-ccl_device_inline float3 safe_divide(const float3 a, const float3 b);
-ccl_device_inline float3 safe_divide(const float3 a, const float b);
-ccl_device_inline float3 interp(float3 a, float3 b, float t);
-ccl_device_inline float3 sqr(float3 a);
-
-ccl_device_inline bool is_zero(const float3 a);
-ccl_device_inline float reduce_add(const float3 a);
-ccl_device_inline float average(const float3 a);
-ccl_device_inline bool isequal(const float3 a, const float3 b);
-
-/*******************************************************************************
- * Definition.
- */
-
ccl_device_inline float3 zero_float3()
{
#ifdef __KERNEL_SSE__
@@ -109,7 +43,7 @@ ccl_device_inline float3 operator-(const float3 &a)
# endif
}
-ccl_device_inline float3 operator*(const float3 &a, const float3 &b)
+ccl_device_inline float3 operator*(const float3 a, const float3 b)
{
# ifdef __KERNEL_SSE__
return float3(_mm_mul_ps(a.m128, b.m128));
@@ -118,7 +52,7 @@ ccl_device_inline float3 operator*(const float3 &a, const float3 &b)
# endif
}
-ccl_device_inline float3 operator*(const float3 &a, const float f)
+ccl_device_inline float3 operator*(const float3 a, const float f)
{
# ifdef __KERNEL_SSE__
return float3(_mm_mul_ps(a.m128, _mm_set1_ps(f)));
@@ -127,7 +61,7 @@ ccl_device_inline float3 operator*(const float3 &a, const float f)
# endif
}
-ccl_device_inline float3 operator*(const float f, const float3 &a)
+ccl_device_inline float3 operator*(const float f, const float3 a)
{
# if defined(__KERNEL_SSE__)
return float3(_mm_mul_ps(_mm_set1_ps(f), a.m128));
@@ -136,7 +70,7 @@ ccl_device_inline float3 operator*(const float f, const float3 &a)
# endif
}
-ccl_device_inline float3 operator/(const float f, const float3 &a)
+ccl_device_inline float3 operator/(const float f, const float3 a)
{
# if defined(__KERNEL_SSE__)
return float3(_mm_div_ps(_mm_set1_ps(f), a.m128));
@@ -145,7 +79,7 @@ ccl_device_inline float3 operator/(const float f, const float3 &a)
# endif
}
-ccl_device_inline float3 operator/(const float3 &a, const float f)
+ccl_device_inline float3 operator/(const float3 a, const float f)
{
# if defined(__KERNEL_SSE__)
return float3(_mm_div_ps(a.m128, _mm_set1_ps(f)));
@@ -154,7 +88,7 @@ ccl_device_inline float3 operator/(const float3 &a, const float f)
# endif
}
-ccl_device_inline float3 operator/(const float3 &a, const float3 &b)
+ccl_device_inline float3 operator/(const float3 a, const float3 b)
{
# if defined(__KERNEL_SSE__)
return float3(_mm_div_ps(a.m128, b.m128));
@@ -163,12 +97,7 @@ ccl_device_inline float3 operator/(const float3 &a, const float3 &b)
# endif
}
-ccl_device_inline float3 operator+(const float3 &a, const float f)
-{
- return a + make_float3(f, f, f);
-}
-
-ccl_device_inline float3 operator+(const float3 &a, const float3 &b)
+ccl_device_inline float3 operator+(const float3 a, const float3 b)
{
# ifdef __KERNEL_SSE__
return float3(_mm_add_ps(a.m128, b.m128));
@@ -177,12 +106,12 @@ ccl_device_inline float3 operator+(const float3 &a, const float3 &b)
# endif
}
-ccl_device_inline float3 operator-(const float3 &a, const float f)
+ccl_device_inline float3 operator+(const float3 a, const float f)
{
- return a - make_float3(f, f, f);
+ return a + make_float3(f, f, f);
}
-ccl_device_inline float3 operator-(const float3 &a, const float3 &b)
+ccl_device_inline float3 operator-(const float3 a, const float3 b)
{
# ifdef __KERNEL_SSE__
return float3(_mm_sub_ps(a.m128, b.m128));
@@ -191,17 +120,22 @@ ccl_device_inline float3 operator-(const float3 &a, const float3 &b)
# endif
}
-ccl_device_inline float3 operator+=(float3 &a, const float3 &b)
+ccl_device_inline float3 operator-(const float3 a, const float f)
+{
+ return a - make_float3(f, f, f);
+}
+
+ccl_device_inline float3 operator+=(float3 &a, const float3 b)
{
return a = a + b;
}
-ccl_device_inline float3 operator-=(float3 &a, const float3 &b)
+ccl_device_inline float3 operator-=(float3 &a, const float3 b)
{
return a = a - b;
}
-ccl_device_inline float3 operator*=(float3 &a, const float3 &b)
+ccl_device_inline float3 operator*=(float3 &a, const float3 b)
{
return a = a * b;
}
@@ -211,7 +145,7 @@ ccl_device_inline float3 operator*=(float3 &a, float f)
return a = a * f;
}
-ccl_device_inline float3 operator/=(float3 &a, const float3 &b)
+ccl_device_inline float3 operator/=(float3 &a, const float3 b)
{
return a = a / b;
}
@@ -223,7 +157,7 @@ ccl_device_inline float3 operator/=(float3 &a, float f)
}
# if !(defined(__KERNEL_METAL__) || defined(__KERNEL_CUDA__))
-ccl_device_inline packed_float3 operator*=(packed_float3 &a, const float3 &b)
+ccl_device_inline packed_float3 operator*=(packed_float3 &a, const float3 b)
{
a = float3(a) * b;
return a;
@@ -235,7 +169,7 @@ ccl_device_inline packed_float3 operator*=(packed_float3 &a, float f)
return a;
}
-ccl_device_inline packed_float3 operator/=(packed_float3 &a, const float3 &b)
+ccl_device_inline packed_float3 operator/=(packed_float3 &a, const float3 b)
{
a = float3(a) / b;
return a;
@@ -248,7 +182,7 @@ ccl_device_inline packed_float3 operator/=(packed_float3 &a, float f)
}
# endif
-ccl_device_inline bool operator==(const float3 &a, const float3 &b)
+ccl_device_inline bool operator==(const float3 a, const float3 b)
{
# ifdef __KERNEL_SSE__
return (_mm_movemask_ps(_mm_cmpeq_ps(a.m128, b.m128)) & 7) == 7;
@@ -257,17 +191,12 @@ ccl_device_inline bool operator==(const float3 &a, const float3 &b)
# endif
}
-ccl_device_inline bool operator!=(const float3 &a, const float3 &b)
+ccl_device_inline bool operator!=(const float3 a, const float3 b)
{
return !(a == b);
}
-ccl_device_inline float distance(const float3 &a, const float3 &b)
-{
- return len(a - b);
-}
-
-ccl_device_inline float dot(const float3 &a, const float3 &b)
+ccl_device_inline float dot(const float3 a, const float3 b)
{
# if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
return _mm_cvtss_f32(_mm_dp_ps(a, b, 0x7F));
@@ -276,26 +205,62 @@ ccl_device_inline float dot(const float3 &a, const float3 &b)
# endif
}
-ccl_device_inline float dot_xy(const float3 &a, const float3 &b)
+#endif
+
+ccl_device_inline float dot_xy(const float3 a, const float3 b)
{
-# if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
+#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
return _mm_cvtss_f32(_mm_hadd_ps(_mm_mul_ps(a, b), b));
-# else
+#else
return a.x * b.x + a.y * b.y;
-# endif
+#endif
+}
+
+ccl_device_inline float len(const float3 a)
+{
+#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
+ return _mm_cvtss_f32(_mm_sqrt_ss(_mm_dp_ps(a.m128, a.m128, 0x7F)));
+#else
+ return sqrtf(dot(a, a));
+#endif
+}
+
+ccl_device_inline float reduce_min(float3 a)
+{
+ return min(min(a.x, a.y), a.z);
+}
+
+ccl_device_inline float reduce_max(float3 a)
+{
+ return max(max(a.x, a.y), a.z);
}
-ccl_device_inline float3 cross(const float3 &a, const float3 &b)
+ccl_device_inline float len_squared(const float3 a)
+{
+ return dot(a, a);
+}
+
+#ifndef __KERNEL_METAL__
+
+ccl_device_inline float distance(const float3 a, const float3 b)
+{
+ return len(a - b);
+}
+
+ccl_device_inline float3 cross(const float3 a, const float3 b)
{
# ifdef __KERNEL_SSE__
- return float3(shuffle<1, 2, 0, 3>(
- msub(ssef(a), shuffle<1, 2, 0, 3>(ssef(b)), shuffle<1, 2, 0, 3>(ssef(a)) * ssef(b))));
+ const float4 x = float4(a.m128);
+ const float4 y = shuffle<1, 2, 0, 3>(float4(b.m128));
+ const float4 z = float4(_mm_mul_ps(shuffle<1, 2, 0, 3>(float4(a.m128)), float4(b.m128)));
+
+ return float3(shuffle<1, 2, 0, 3>(msub(x, y, z)).m128);
# else
return 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);
# endif
}
-ccl_device_inline float3 normalize(const float3 &a)
+ccl_device_inline float3 normalize(const float3 a)
{
# if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
__m128 norm = _mm_sqrt_ps(_mm_dp_ps(a.m128, a.m128, 0x7F));
@@ -305,7 +270,7 @@ ccl_device_inline float3 normalize(const float3 &a)
# endif
}
-ccl_device_inline float3 min(const float3 &a, const float3 &b)
+ccl_device_inline float3 min(const float3 a, const float3 b)
{
# ifdef __KERNEL_SSE__
return float3(_mm_min_ps(a.m128, b.m128));
@@ -314,7 +279,7 @@ ccl_device_inline float3 min(const float3 &a, const float3 &b)
# endif
}
-ccl_device_inline float3 max(const float3 &a, const float3 &b)
+ccl_device_inline float3 max(const float3 a, const float3 b)
{
# ifdef __KERNEL_SSE__
return float3(_mm_max_ps(a.m128, b.m128));
@@ -323,12 +288,12 @@ ccl_device_inline float3 max(const float3 &a, const float3 &b)
# endif
}
-ccl_device_inline float3 clamp(const float3 &a, const float3 &mn, const float3 &mx)
+ccl_device_inline float3 clamp(const float3 a, const float3 mn, const float3 mx)
{
return min(max(a, mn), mx);
}
-ccl_device_inline float3 fabs(const float3 &a)
+ccl_device_inline float3 fabs(const float3 a)
{
# ifdef __KERNEL_SSE__
# ifdef __KERNEL_NEON__
@@ -342,7 +307,7 @@ ccl_device_inline float3 fabs(const float3 &a)
# endif
}
-ccl_device_inline float3 sqrt(const float3 &a)
+ccl_device_inline float3 sqrt(const float3 a)
{
# ifdef __KERNEL_SSE__
return float3(_mm_sqrt_ps(a));
@@ -351,7 +316,7 @@ ccl_device_inline float3 sqrt(const float3 &a)
# endif
}
-ccl_device_inline float3 floor(const float3 &a)
+ccl_device_inline float3 floor(const float3 a)
{
# ifdef __KERNEL_SSE__
return float3(_mm_floor_ps(a));
@@ -360,7 +325,7 @@ ccl_device_inline float3 floor(const float3 &a)
# endif
}
-ccl_device_inline float3 ceil(const float3 &a)
+ccl_device_inline float3 ceil(const float3 a)
{
# ifdef __KERNEL_SSE__
return float3(_mm_ceil_ps(a));
@@ -369,12 +334,12 @@ ccl_device_inline float3 ceil(const float3 &a)
# endif
}
-ccl_device_inline float3 mix(const float3 &a, const float3 &b, float t)
+ccl_device_inline float3 mix(const float3 a, const float3 b, float t)
{
return a + t * (b - a);
}
-ccl_device_inline float3 rcp(const float3 &a)
+ccl_device_inline float3 rcp(const float3 a)
{
# ifdef __KERNEL_SSE__
/* Don't use _mm_rcp_ps due to poor precision. */
@@ -399,33 +364,6 @@ ccl_device_inline float3 log(float3 v)
return make_float3(logf(v.x), logf(v.y), logf(v.z));
}
-#endif /* !__KERNEL_METAL__ */
-
-ccl_device_inline float reduce_min(float3 a)
-{
- return min(min(a.x, a.y), a.z);
-}
-
-ccl_device_inline float reduce_max(float3 a)
-{
- return max(max(a.x, a.y), a.z);
-}
-
-ccl_device_inline float len(const float3 a)
-{
-#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
- return _mm_cvtss_f32(_mm_sqrt_ss(_mm_dp_ps(a.m128, a.m128, 0x7F)));
-#else
- return sqrtf(dot(a, a));
-#endif
-}
-
-ccl_device_inline float len_squared(const float3 a)
-{
- return dot(a, a);
-}
-
-#if !defined(__KERNEL_METAL__)
ccl_device_inline float3 reflect(const float3 incident, const float3 normal)
{
float3 unit_normal = normalize(normal);
@@ -535,18 +473,6 @@ ccl_device_inline float3 pow(float3 v, float e)
return make_float3(powf(v.x, e), powf(v.y, e), powf(v.z, e));
}
-ccl_device_inline int3 quick_floor_to_int3(const float3 a)
-{
-#ifdef __KERNEL_SSE__
- int3 b = int3(_mm_cvttps_epi32(a.m128));
- int3 isneg = int3(_mm_castps_si128(_mm_cmplt_ps(a.m128, _mm_set_ps1(0.0f))));
- /* Unsaturated add 0xffffffff is the same as subtract -1. */
- return b + isneg;
-#else
- return make_int3(quick_floor_to_int(a.x), quick_floor_to_int(a.y), quick_floor_to_int(a.z));
-#endif
-}
-
ccl_device_inline bool isfinite_safe(float3 v)
{
return isfinite_safe(v.x) && isfinite_safe(v.y) && isfinite_safe(v.z);
diff --git a/intern/cycles/util/math_float4.h b/intern/cycles/util/math_float4.h
index c2721873037..301d2d789c0 100644
--- a/intern/cycles/util/math_float4.h
+++ b/intern/cycles/util/math_float4.h
@@ -1,4 +1,5 @@
/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2013 Intel Corporation
* Copyright 2011-2022 Blender Foundation */
#ifndef __UTIL_MATH_FLOAT4_H__
@@ -10,85 +11,6 @@
CCL_NAMESPACE_BEGIN
-/*******************************************************************************
- * Declaration.
- */
-
-#if !defined(__KERNEL_METAL__)
-ccl_device_inline float4 operator-(const float4 &a);
-ccl_device_inline float4 operator*(const float4 &a, const float4 &b);
-ccl_device_inline float4 operator*(const float4 &a, float f);
-ccl_device_inline float4 operator*(float f, const float4 &a);
-ccl_device_inline float4 operator/(const float4 &a, float f);
-ccl_device_inline float4 operator/(const float4 &a, const float4 &b);
-ccl_device_inline float4 operator+(const float4 &a, const float f);
-ccl_device_inline float4 operator+(const float4 &a, const float4 &b);
-ccl_device_inline float4 operator-(const float4 &a, const float f);
-ccl_device_inline float4 operator-(const float4 &a, const float4 &b);
-ccl_device_inline float4 operator+=(float4 &a, const float4 &b);
-ccl_device_inline float4 operator*=(float4 &a, const float4 &b);
-ccl_device_inline float4 operator*=(float4 &a, float f);
-ccl_device_inline float4 operator/=(float4 &a, float f);
-
-ccl_device_inline int4 operator<(const float4 &a, const float4 &b);
-ccl_device_inline int4 operator>=(const float4 &a, const float4 &b);
-ccl_device_inline int4 operator<=(const float4 &a, const float4 &b);
-ccl_device_inline bool operator==(const float4 &a, const float4 &b);
-
-ccl_device_inline float distance(const float4 &a, const float4 &b);
-ccl_device_inline float dot(const float4 &a, const float4 &b);
-ccl_device_inline float len_squared(const float4 &a);
-ccl_device_inline float4 rcp(const float4 &a);
-ccl_device_inline float4 sqrt(const float4 &a);
-ccl_device_inline float4 sqr(const float4 &a);
-ccl_device_inline float4 cross(const float4 &a, const float4 &b);
-ccl_device_inline bool is_zero(const float4 &a);
-ccl_device_inline float average(const float4 &a);
-ccl_device_inline float len(const float4 &a);
-ccl_device_inline float4 normalize(const float4 &a);
-ccl_device_inline float4 safe_normalize(const float4 &a);
-ccl_device_inline float4 min(const float4 &a, const float4 &b);
-ccl_device_inline float4 max(const float4 &a, const float4 &b);
-ccl_device_inline float4 clamp(const float4 &a, const float4 &mn, const float4 &mx);
-ccl_device_inline float4 fabs(const float4 &a);
-ccl_device_inline float4 floor(const float4 &a);
-ccl_device_inline float4 mix(const float4 &a, const float4 &b, float t);
-#endif /* !__KERNEL_METAL__*/
-
-ccl_device_inline float4 safe_divide(const float4 a, const float4 b);
-ccl_device_inline float4 safe_divide(const float4 a, const float b);
-
-#ifdef __KERNEL_SSE__
-template<size_t index_0, size_t index_1, size_t index_2, size_t index_3>
-__forceinline const float4 shuffle(const float4 &b);
-template<size_t index_0, size_t index_1, size_t index_2, size_t index_3>
-__forceinline const float4 shuffle(const float4 &a, const float4 &b);
-
-template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4 &b);
-
-template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4 &a, const float4 &b);
-template<> __forceinline const float4 shuffle<2, 3, 2, 3>(const float4 &a, const float4 &b);
-
-# ifdef __KERNEL_SSE3__
-template<> __forceinline const float4 shuffle<0, 0, 2, 2>(const float4 &b);
-template<> __forceinline const float4 shuffle<1, 1, 3, 3>(const float4 &b);
-# endif
-#endif /* __KERNEL_SSE__ */
-
-ccl_device_inline float reduce_min(const float4 a);
-ccl_device_inline float reduce_max(const float4 a);
-ccl_device_inline float reduce_add(const float4 a);
-
-ccl_device_inline bool isequal(const float4 a, const float4 b);
-
-#ifndef __KERNEL_GPU__
-ccl_device_inline float4 select(const int4 &mask, const float4 &a, const float4 &b);
-#endif /* !__KERNEL_GPU__ */
-
-/*******************************************************************************
- * Definition.
- */
-
ccl_device_inline float4 zero_float4()
{
#ifdef __KERNEL_SSE__
@@ -103,6 +25,16 @@ ccl_device_inline float4 one_float4()
return make_float4(1.0f, 1.0f, 1.0f, 1.0f);
}
+ccl_device_inline int4 cast(const float4 a)
+{
+#ifdef __KERNEL_SSE__
+ return int4(_mm_castps_si128(a));
+#else
+ return make_int4(
+ __float_as_int(a.x), __float_as_int(a.y), __float_as_int(a.z), __float_as_int(a.w));
+#endif
+}
+
#if !defined(__KERNEL_METAL__)
ccl_device_inline float4 operator-(const float4 &a)
{
@@ -114,7 +46,7 @@ ccl_device_inline float4 operator-(const float4 &a)
# endif
}
-ccl_device_inline float4 operator*(const float4 &a, const float4 &b)
+ccl_device_inline float4 operator*(const float4 a, const float4 b)
{
# ifdef __KERNEL_SSE__
return float4(_mm_mul_ps(a.m128, b.m128));
@@ -123,7 +55,7 @@ ccl_device_inline float4 operator*(const float4 &a, const float4 &b)
# endif
}
-ccl_device_inline float4 operator*(const float4 &a, float f)
+ccl_device_inline float4 operator*(const float4 a, float f)
{
# if defined(__KERNEL_SSE__)
return a * make_float4(f);
@@ -132,17 +64,17 @@ ccl_device_inline float4 operator*(const float4 &a, float f)
# endif
}
-ccl_device_inline float4 operator*(float f, const float4 &a)
+ccl_device_inline float4 operator*(float f, const float4 a)
{
return a * f;
}
-ccl_device_inline float4 operator/(const float4 &a, float f)
+ccl_device_inline float4 operator/(const float4 a, float f)
{
return a * (1.0f / f);
}
-ccl_device_inline float4 operator/(const float4 &a, const float4 &b)
+ccl_device_inline float4 operator/(const float4 a, const float4 b)
{
# ifdef __KERNEL_SSE__
return float4(_mm_div_ps(a.m128, b.m128));
@@ -151,12 +83,7 @@ ccl_device_inline float4 operator/(const float4 &a, const float4 &b)
# endif
}
-ccl_device_inline float4 operator+(const float4 &a, const float f)
-{
- return a + make_float4(f, f, f, f);
-}
-
-ccl_device_inline float4 operator+(const float4 &a, const float4 &b)
+ccl_device_inline float4 operator+(const float4 a, const float4 b)
{
# ifdef __KERNEL_SSE__
return float4(_mm_add_ps(a.m128, b.m128));
@@ -165,12 +92,12 @@ ccl_device_inline float4 operator+(const float4 &a, const float4 &b)
# endif
}
-ccl_device_inline float4 operator-(const float4 &a, const float f)
+ccl_device_inline float4 operator+(const float4 a, const float f)
{
- return a - make_float4(f, f, f, f);
+ return a + make_float4(f);
}
-ccl_device_inline float4 operator-(const float4 &a, const float4 &b)
+ccl_device_inline float4 operator-(const float4 a, const float4 b)
{
# ifdef __KERNEL_SSE__
return float4(_mm_sub_ps(a.m128, b.m128));
@@ -179,17 +106,22 @@ ccl_device_inline float4 operator-(const float4 &a, const float4 &b)
# endif
}
-ccl_device_inline float4 operator+=(float4 &a, const float4 &b)
+ccl_device_inline float4 operator-(const float4 a, const float f)
+{
+ return a - make_float4(f);
+}
+
+ccl_device_inline float4 operator+=(float4 &a, const float4 b)
{
return a = a + b;
}
-ccl_device_inline float4 operator-=(float4 &a, const float4 &b)
+ccl_device_inline float4 operator-=(float4 &a, const float4 b)
{
return a = a - b;
}
-ccl_device_inline float4 operator*=(float4 &a, const float4 &b)
+ccl_device_inline float4 operator*=(float4 &a, const float4 b)
{
return a = a * b;
}
@@ -204,7 +136,7 @@ ccl_device_inline float4 operator/=(float4 &a, float f)
return a = a / f;
}
-ccl_device_inline int4 operator<(const float4 &a, const float4 &b)
+ccl_device_inline int4 operator<(const float4 a, const float4 b)
{
# ifdef __KERNEL_SSE__
return int4(_mm_castps_si128(_mm_cmplt_ps(a.m128, b.m128)));
@@ -213,7 +145,7 @@ ccl_device_inline int4 operator<(const float4 &a, const float4 &b)
# endif
}
-ccl_device_inline int4 operator>=(const float4 &a, const float4 &b)
+ccl_device_inline int4 operator>=(const float4 a, const float4 b)
{
# ifdef __KERNEL_SSE__
return int4(_mm_castps_si128(_mm_cmpge_ps(a.m128, b.m128)));
@@ -222,7 +154,7 @@ ccl_device_inline int4 operator>=(const float4 &a, const float4 &b)
# endif
}
-ccl_device_inline int4 operator<=(const float4 &a, const float4 &b)
+ccl_device_inline int4 operator<=(const float4 a, const float4 b)
{
# ifdef __KERNEL_SSE__
return int4(_mm_castps_si128(_mm_cmple_ps(a.m128, b.m128)));
@@ -231,7 +163,7 @@ ccl_device_inline int4 operator<=(const float4 &a, const float4 &b)
# endif
}
-ccl_device_inline bool operator==(const float4 &a, const float4 &b)
+ccl_device_inline bool operator==(const float4 a, const float4 b)
{
# ifdef __KERNEL_SSE__
return (_mm_movemask_ps(_mm_cmpeq_ps(a.m128, b.m128)) & 15) == 15;
@@ -240,160 +172,148 @@ ccl_device_inline bool operator==(const float4 &a, const float4 &b)
# endif
}
-ccl_device_inline float distance(const float4 &a, const float4 &b)
-{
- return len(a - b);
-}
-
-ccl_device_inline float dot(const float4 &a, const float4 &b)
+ccl_device_inline const float4 operator^(const float4 a, const float4 b)
{
-# if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
-# if defined(__KERNEL_NEON__)
- __m128 t = vmulq_f32(a, b);
- return vaddvq_f32(t);
-# else
- return _mm_cvtss_f32(_mm_dp_ps(a, b, 0xFF));
-# endif
+# ifdef __KERNEL_SSE__
+ return float4(_mm_xor_ps(a.m128, b.m128));
# else
- return (a.x * b.x + a.y * b.y) + (a.z * b.z + a.w * b.w);
+ return make_float4(__uint_as_float(__float_as_uint(a.x) ^ __float_as_uint(b.x)),
+ __uint_as_float(__float_as_uint(a.y) ^ __float_as_uint(b.y)),
+ __uint_as_float(__float_as_uint(a.z) ^ __float_as_uint(b.z)),
+ __uint_as_float(__float_as_uint(a.w) ^ __float_as_uint(b.w)));
# endif
}
-ccl_device_inline float len_squared(const float4 &a)
-{
- return dot(a, a);
-}
-
-ccl_device_inline float4 rcp(const float4 &a)
+ccl_device_inline float4 min(const float4 a, const float4 b)
{
# ifdef __KERNEL_SSE__
- /* Don't use _mm_rcp_ps due to poor precision. */
- return float4(_mm_div_ps(_mm_set_ps1(1.0f), a.m128));
+ return float4(_mm_min_ps(a.m128, b.m128));
# else
- return make_float4(1.0f / a.x, 1.0f / a.y, 1.0f / a.z, 1.0f / a.w);
+ return make_float4(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z), min(a.w, b.w));
# endif
}
-ccl_device_inline float4 sqrt(const float4 &a)
+ccl_device_inline float4 max(const float4 a, const float4 b)
{
# ifdef __KERNEL_SSE__
- return float4(_mm_sqrt_ps(a.m128));
+ return float4(_mm_max_ps(a.m128, b.m128));
# else
- return make_float4(sqrtf(a.x), sqrtf(a.y), sqrtf(a.z), sqrtf(a.w));
+ return make_float4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w));
# endif
}
-ccl_device_inline float4 sqr(const float4 &a)
+ccl_device_inline float4 clamp(const float4 a, const float4 mn, const float4 mx)
{
- return a * a;
+ return min(max(a, mn), mx);
}
+#endif /* !__KERNEL_METAL__*/
-ccl_device_inline float4 cross(const float4 &a, const float4 &b)
+ccl_device_inline const float4 madd(const float4 a, const float4 b, const float4 c)
{
-# ifdef __KERNEL_SSE__
- return (shuffle<1, 2, 0, 0>(a) * shuffle<2, 0, 1, 0>(b)) -
- (shuffle<2, 0, 1, 0>(a) * shuffle<1, 2, 0, 0>(b));
+#ifdef __KERNEL_SSE__
+# ifdef __KERNEL_NEON__
+ return float4(vfmaq_f32(c, a, b));
+# elif defined(__KERNEL_AVX2__)
+ return float4(_mm_fmadd_ps(a, b, c));
# else
- return make_float4(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x, 0.0f);
+ return a * b + c;
# endif
+#else
+ return a * b + c;
+#endif
}
-ccl_device_inline bool is_zero(const float4 &a)
+ccl_device_inline float4 msub(const float4 a, const float4 b, const float4 c)
{
-# ifdef __KERNEL_SSE__
- return a == zero_float4();
+#ifdef __KERNEL_SSE__
+# ifdef __KERNEL_NEON__
+ return float4(vfmaq_f32(vnegq_f32(c), a, b));
+# elif defined(__KERNEL_AVX2__)
+ return float4(_mm_fmsub_ps(a, b, c));
# else
- return (a.x == 0.0f && a.y == 0.0f && a.z == 0.0f && a.w == 0.0f);
+ return a * b - c;
# endif
+#else
+ return a * b - c;
+#endif
}
-ccl_device_inline float average(const float4 &a)
+#ifdef __KERNEL_SSE__
+template<size_t i0, size_t i1, size_t i2, size_t i3>
+__forceinline const float4 shuffle(const float4 b)
{
- return reduce_add(a) * 0.25f;
+# ifdef __KERNEL_NEON__
+ return float4(shuffle_neon<float32x4_t, i0, i1, i2, i3>(b.m128));
+# else
+ return float4(
+ _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(b), _MM_SHUFFLE(i3, i2, i1, i0))));
+# endif
}
-ccl_device_inline float len(const float4 &a)
+template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4 a)
{
- return sqrtf(dot(a, a));
+ return float4(_mm_movelh_ps(a, a));
}
-ccl_device_inline float4 normalize(const float4 &a)
+template<> __forceinline const float4 shuffle<2, 3, 2, 3>(const float4 a)
{
- return a / len(a);
+ return float4(_mm_movehl_ps(a, a));
}
-ccl_device_inline float4 safe_normalize(const float4 &a)
+# ifdef __KERNEL_SSE3__
+template<> __forceinline const float4 shuffle<0, 0, 2, 2>(const float4 b)
{
- float t = len(a);
- return (t != 0.0f) ? a / t : a;
+ return float4(_mm_moveldup_ps(b));
}
-ccl_device_inline float4 min(const float4 &a, const float4 &b)
+template<> __forceinline const float4 shuffle<1, 1, 3, 3>(const float4 b)
{
-# ifdef __KERNEL_SSE__
- return float4(_mm_min_ps(a.m128, b.m128));
-# else
- return make_float4(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z), min(a.w, b.w));
-# endif
+ return float4(_mm_movehdup_ps(b));
}
+# endif /* __KERNEL_SSE3__ */
-ccl_device_inline float4 max(const float4 &a, const float4 &b)
+template<size_t i0, size_t i1, size_t i2, size_t i3>
+__forceinline const float4 shuffle(const float4 a, const float4 b)
{
-# ifdef __KERNEL_SSE__
- return float4(_mm_max_ps(a.m128, b.m128));
+# ifdef __KERNEL_NEON__
+ return float4(shuffle_neon<float32x4_t, i0, i1, i2, i3>(a, b));
# else
- return make_float4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w));
+ return float4(_mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0)));
# endif
}
-ccl_device_inline float4 clamp(const float4 &a, const float4 &mn, const float4 &mx)
+template<size_t i0> __forceinline const float4 shuffle(const float4 b)
{
- return min(max(a, mn), mx);
+ return shuffle<i0, i0, i0, i0>(b);
}
-
-ccl_device_inline float4 fabs(const float4 &a)
+template<size_t i0> __forceinline const float4 shuffle(const float4 a, const float4 b)
{
-# if defined(__KERNEL_SSE__)
-# if defined(__KERNEL_NEON__)
- return float4(vabsq_f32(a));
-# else
- return float4(_mm_and_ps(a.m128, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff))));
-# endif
-# else
- return make_float4(fabsf(a.x), fabsf(a.y), fabsf(a.z), fabsf(a.w));
-# endif
-}
-
-ccl_device_inline float4 floor(const float4 &a)
-{
-# ifdef __KERNEL_SSE__
- return float4(_mm_floor_ps(a));
+# ifdef __KERNEL_NEON__
+ return float4(shuffle_neon<float32x4_t, i0, i0, i0, i0>(a, b));
# else
- return make_float4(floorf(a.x), floorf(a.y), floorf(a.z), floorf(a.w));
+ return float4(_mm_shuffle_ps(a, b, _MM_SHUFFLE(i0, i0, i0, i0)));
# endif
}
-ccl_device_inline float4 mix(const float4 &a, const float4 &b, float t)
+template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4 a, const float4 b)
{
- return a + t * (b - a);
+ return float4(_mm_movelh_ps(a, b));
}
-ccl_device_inline float4 saturate(const float4 &a)
+template<> __forceinline const float4 shuffle<2, 3, 2, 3>(const float4 a, const float4 b)
{
- return make_float4(saturatef(a.x), saturatef(a.y), saturatef(a.z), saturatef(a.w));
+ return float4(_mm_movehl_ps(b, a));
}
-ccl_device_inline float4 exp(float4 v)
+template<size_t i> __forceinline float extract(const float4 a)
{
- return make_float4(expf(v.x), expf(v.y), expf(v.z), expf(v.z));
+ return _mm_cvtss_f32(shuffle<i, i, i, i>(a));
}
-
-ccl_device_inline float4 log(float4 v)
+template<> __forceinline float extract<0>(const float4 a)
{
- return make_float4(logf(v.x), logf(v.y), logf(v.z), logf(v.z));
+ return _mm_cvtss_f32(a);
}
-
-#endif /* !__KERNEL_METAL__*/
+#endif
ccl_device_inline float reduce_add(const float4 a)
{
@@ -440,77 +360,192 @@ ccl_device_inline float reduce_max(const float4 a)
#endif
}
-ccl_device_inline bool isequal(const float4 a, const float4 b)
+#if !defined(__KERNEL_METAL__)
+ccl_device_inline float dot(const float4 a, const float4 b)
{
-#if defined(__KERNEL_METAL__)
- return all(a == b);
-#else
- return a == b;
-#endif
+# if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
+# if defined(__KERNEL_NEON__)
+ __m128 t = vmulq_f32(a, b);
+ return vaddvq_f32(t);
+# else
+ return _mm_cvtss_f32(_mm_dp_ps(a, b, 0xFF));
+# endif
+# else
+ return (a.x * b.x + a.y * b.y) + (a.z * b.z + a.w * b.w);
+# endif
}
+#endif /* !defined(__KERNEL_METAL__) */
-#ifdef __KERNEL_SSE__
-template<size_t index_0, size_t index_1, size_t index_2, size_t index_3>
-__forceinline const float4 shuffle(const float4 &b)
+ccl_device_inline float len(const float4 a)
{
-# if defined(__KERNEL_NEON__)
- return float4(shuffle_neon<__m128, index_0, index_1, index_2, index_3>(b.m128));
+ return sqrtf(dot(a, a));
+}
+
+ccl_device_inline float len_squared(const float4 a)
+{
+ return dot(a, a);
+}
+
+#if !defined(__KERNEL_METAL__)
+ccl_device_inline float distance(const float4 a, const float4 b)
+{
+ return len(a - b);
+}
+
+ccl_device_inline float4 rcp(const float4 a)
+{
+# ifdef __KERNEL_SSE__
+ /* Don't use _mm_rcp_ps due to poor precision. */
+ return float4(_mm_div_ps(_mm_set_ps1(1.0f), a.m128));
# else
- return float4(_mm_castsi128_ps(
- _mm_shuffle_epi32(_mm_castps_si128(b), _MM_SHUFFLE(index_3, index_2, index_1, index_0))));
+ return make_float4(1.0f / a.x, 1.0f / a.y, 1.0f / a.z, 1.0f / a.w);
# endif
}
-template<size_t index_0, size_t index_1, size_t index_2, size_t index_3>
-__forceinline const float4 shuffle(const float4 &a, const float4 &b)
+ccl_device_inline float4 sqrt(const float4 a)
{
-# if defined(__KERNEL_NEON__)
- return float4(shuffle_neon<__m128, index_0, index_1, index_2, index_3>(a.m128, b.m128));
+# ifdef __KERNEL_SSE__
+ return float4(_mm_sqrt_ps(a.m128));
# else
- return float4(_mm_shuffle_ps(a.m128, b.m128, _MM_SHUFFLE(index_3, index_2, index_1, index_0)));
+ return make_float4(sqrtf(a.x), sqrtf(a.y), sqrtf(a.z), sqrtf(a.w));
# endif
}
-template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4 &b)
+ccl_device_inline float4 sqr(const float4 a)
{
- return float4(_mm_castpd_ps(_mm_movedup_pd(_mm_castps_pd(b))));
+ return a * a;
}
-template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4 &a, const float4 &b)
+ccl_device_inline float4 cross(const float4 a, const float4 b)
{
- return float4(_mm_movelh_ps(a.m128, b.m128));
+# ifdef __KERNEL_SSE__
+ return (shuffle<1, 2, 0, 0>(a) * shuffle<2, 0, 1, 0>(b)) -
+ (shuffle<2, 0, 1, 0>(a) * shuffle<1, 2, 0, 0>(b));
+# else
+ return make_float4(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x, 0.0f);
+# endif
}
-template<> __forceinline const float4 shuffle<2, 3, 2, 3>(const float4 &a, const float4 &b)
+ccl_device_inline bool is_zero(const float4 a)
{
- return float4(_mm_movehl_ps(b.m128, a.m128));
+# ifdef __KERNEL_SSE__
+ return a == zero_float4();
+# else
+ return (a.x == 0.0f && a.y == 0.0f && a.z == 0.0f && a.w == 0.0f);
+# endif
}
-# ifdef __KERNEL_SSE3__
-template<> __forceinline const float4 shuffle<0, 0, 2, 2>(const float4 &b)
+ccl_device_inline float average(const float4 a)
{
- return float4(_mm_moveldup_ps(b));
+ return reduce_add(a) * 0.25f;
}
-template<> __forceinline const float4 shuffle<1, 1, 3, 3>(const float4 &b)
+ccl_device_inline float4 normalize(const float4 a)
{
- return float4(_mm_movehdup_ps(b));
+ return a / len(a);
+}
+
+ccl_device_inline float4 safe_normalize(const float4 a)
+{
+ float t = len(a);
+ return (t != 0.0f) ? a / t : a;
+}
+
+ccl_device_inline float4 fabs(const float4 a)
+{
+# if defined(__KERNEL_SSE__)
+# if defined(__KERNEL_NEON__)
+ return float4(vabsq_f32(a));
+# else
+ return float4(_mm_and_ps(a.m128, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff))));
+# endif
+# else
+ return make_float4(fabsf(a.x), fabsf(a.y), fabsf(a.z), fabsf(a.w));
+# endif
+}
+
+ccl_device_inline float4 floor(const float4 a)
+{
+# ifdef __KERNEL_SSE__
+# if defined(__KERNEL_NEON__)
+ return float4(vrndmq_f32(a));
+# else
+ return float4(_mm_floor_ps(a));
+# endif
+# else
+ return make_float4(floorf(a.x), floorf(a.y), floorf(a.z), floorf(a.w));
+# endif
+}
+
+ccl_device_inline float4 floorfrac(const float4 x, ccl_private int4 *i)
+{
+# ifdef __KERNEL_SSE__
+ const float4 f = floor(x);
+ *i = int4(_mm_cvttps_epi32(f.m128));
+ return x - f;
+# else
+ float4 r;
+ r.x = floorfrac(x.x, &i->x);
+ r.y = floorfrac(x.y, &i->y);
+ r.z = floorfrac(x.z, &i->z);
+ r.w = floorfrac(x.w, &i->w);
+ return r;
+# endif
+}
+
+ccl_device_inline float4 mix(const float4 a, const float4 b, float t)
+{
+ return a + t * (b - a);
+}
+
+ccl_device_inline float4 mix(const float4 a, const float4 b, const float4 t)
+{
+ return a + t * (b - a);
+}
+
+ccl_device_inline float4 saturate(const float4 a)
+{
+ return make_float4(saturatef(a.x), saturatef(a.y), saturatef(a.z), saturatef(a.w));
+}
+
+ccl_device_inline float4 exp(float4 v)
+{
+ return make_float4(expf(v.x), expf(v.y), expf(v.z), expf(v.z));
+}
+
+ccl_device_inline float4 log(float4 v)
+{
+ return make_float4(logf(v.x), logf(v.y), logf(v.z), logf(v.z));
+}
+
+#endif /* !__KERNEL_METAL__*/
+
+ccl_device_inline bool isequal(const float4 a, const float4 b)
+{
+#if defined(__KERNEL_METAL__)
+ return all(a == b);
+#else
+ return a == b;
+#endif
}
-# endif /* __KERNEL_SSE3__ */
-#endif /* __KERNEL_SSE__ */
#ifndef __KERNEL_GPU__
-ccl_device_inline float4 select(const int4 &mask, const float4 &a, const float4 &b)
+ccl_device_inline float4 select(const int4 mask, const float4 a, const float4 b)
{
# ifdef __KERNEL_SSE__
+# ifdef __KERNEL_SSE41__
return float4(_mm_blendv_ps(b.m128, a.m128, _mm_castsi128_ps(mask.m128)));
+# else
+ return float4(
+ _mm_or_ps(_mm_and_ps(_mm_castsi128_ps(mask), a), _mm_andnot_ps(_mm_castsi128_ps(mask), b)));
+# endif
# else
return make_float4(
(mask.x) ? a.x : b.x, (mask.y) ? a.y : b.y, (mask.z) ? a.z : b.z, (mask.w) ? a.w : b.w);
# endif
}
-ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
+ccl_device_inline float4 mask(const int4 mask, const float4 a)
{
/* Replace elements of x with zero where mask isn't set. */
return select(mask, a, zero_float4());
diff --git a/intern/cycles/util/math_float8.h b/intern/cycles/util/math_float8.h
index b538cfbe70b..755a720a10b 100644
--- a/intern/cycles/util/math_float8.h
+++ b/intern/cycles/util/math_float8.h
@@ -1,4 +1,5 @@
/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2013 Intel Corporation
* Copyright 2022 Blender Foundation */
#ifndef __UTIL_MATH_FLOAT8_H__
@@ -10,193 +11,138 @@
CCL_NAMESPACE_BEGIN
-/*******************************************************************************
- * Declaration.
- */
-
-ccl_device_inline float8_t operator+(const float8_t a, const float8_t b);
-ccl_device_inline float8_t operator+(const float8_t a, const float f);
-ccl_device_inline float8_t operator+(const float f, const float8_t a);
-
-ccl_device_inline float8_t operator-(const float8_t a);
-ccl_device_inline float8_t operator-(const float8_t a, const float8_t b);
-ccl_device_inline float8_t operator-(const float8_t a, const float f);
-ccl_device_inline float8_t operator-(const float f, const float8_t a);
-
-ccl_device_inline float8_t operator*(const float8_t a, const float8_t b);
-ccl_device_inline float8_t operator*(const float8_t a, const float f);
-ccl_device_inline float8_t operator*(const float f, const float8_t a);
-
-ccl_device_inline float8_t operator/(const float8_t a, const float8_t b);
-ccl_device_inline float8_t operator/(const float8_t a, float f);
-ccl_device_inline float8_t operator/(const float f, const float8_t a);
-
-ccl_device_inline float8_t operator+=(float8_t a, const float8_t b);
-
-ccl_device_inline float8_t operator*=(float8_t a, const float8_t b);
-ccl_device_inline float8_t operator*=(float8_t a, float f);
-
-ccl_device_inline float8_t operator/=(float8_t a, float f);
-
-ccl_device_inline bool operator==(const float8_t a, const float8_t b);
-
-ccl_device_inline float8_t rcp(const float8_t a);
-ccl_device_inline float8_t sqrt(const float8_t a);
-ccl_device_inline float8_t sqr(const float8_t a);
-ccl_device_inline bool is_zero(const float8_t a);
-ccl_device_inline float average(const float8_t a);
-ccl_device_inline float8_t min(const float8_t a, const float8_t b);
-ccl_device_inline float8_t max(const float8_t a, const float8_t b);
-ccl_device_inline float8_t clamp(const float8_t a, const float8_t mn, const float8_t mx);
-ccl_device_inline float8_t fabs(const float8_t a);
-ccl_device_inline float8_t mix(const float8_t a, const float8_t b, float t);
-ccl_device_inline float8_t saturate(const float8_t a);
-
-ccl_device_inline float8_t safe_divide(const float8_t a, const float b);
-ccl_device_inline float8_t safe_divide(const float8_t a, const float8_t b);
-
-ccl_device_inline float reduce_min(const float8_t a);
-ccl_device_inline float reduce_max(const float8_t a);
-ccl_device_inline float reduce_add(const float8_t a);
-
-ccl_device_inline bool isequal(const float8_t a, const float8_t b);
-
-/*******************************************************************************
- * Definition.
- */
-
-ccl_device_inline float8_t zero_float8_t()
+ccl_device_inline vfloat8 zero_vfloat8()
{
-#ifdef __KERNEL_AVX2__
- return float8_t(_mm256_setzero_ps());
+#ifdef __KERNEL_AVX__
+ return vfloat8(_mm256_setzero_ps());
#else
- return make_float8_t(0.0f);
+ return make_vfloat8(0.0f);
#endif
}
-ccl_device_inline float8_t one_float8_t()
+ccl_device_inline vfloat8 one_vfloat8()
{
- return make_float8_t(1.0f);
+ return make_vfloat8(1.0f);
}
-ccl_device_inline float8_t operator+(const float8_t a, const float8_t b)
+ccl_device_inline vfloat8 operator+(const vfloat8 a, const vfloat8 b)
{
-#ifdef __KERNEL_AVX2__
- return float8_t(_mm256_add_ps(a.m256, b.m256));
+#ifdef __KERNEL_AVX__
+ return vfloat8(_mm256_add_ps(a.m256, b.m256));
#else
- return make_float8_t(
+ return make_vfloat8(
a.a + b.a, a.b + b.b, a.c + b.c, a.d + b.d, a.e + b.e, a.f + b.f, a.g + b.g, a.h + b.h);
#endif
}
-ccl_device_inline float8_t operator+(const float8_t a, const float f)
+ccl_device_inline vfloat8 operator+(const vfloat8 a, const float f)
{
- return a + make_float8_t(f);
+ return a + make_vfloat8(f);
}
-ccl_device_inline float8_t operator+(const float f, const float8_t a)
+ccl_device_inline vfloat8 operator+(const float f, const vfloat8 a)
{
- return make_float8_t(f) + a;
+ return make_vfloat8(f) + a;
}
-ccl_device_inline float8_t operator-(const float8_t a)
+ccl_device_inline vfloat8 operator-(const vfloat8 a)
{
-#ifdef __KERNEL_AVX2__
+#ifdef __KERNEL_AVX__
__m256 mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x80000000));
- return float8_t(_mm256_xor_ps(a.m256, mask));
+ return vfloat8(_mm256_xor_ps(a.m256, mask));
#else
- return make_float8_t(-a.a, -a.b, -a.c, -a.d, -a.e, -a.f, -a.g, -a.h);
+ return make_vfloat8(-a.a, -a.b, -a.c, -a.d, -a.e, -a.f, -a.g, -a.h);
#endif
}
-ccl_device_inline float8_t operator-(const float8_t a, const float8_t b)
+ccl_device_inline vfloat8 operator-(const vfloat8 a, const vfloat8 b)
{
-#ifdef __KERNEL_AVX2__
- return float8_t(_mm256_sub_ps(a.m256, b.m256));
+#ifdef __KERNEL_AVX__
+ return vfloat8(_mm256_sub_ps(a.m256, b.m256));
#else
- return make_float8_t(
+ return make_vfloat8(
a.a - b.a, a.b - b.b, a.c - b.c, a.d - b.d, a.e - b.e, a.f - b.f, a.g - b.g, a.h - b.h);
#endif
}
-ccl_device_inline float8_t operator-(const float8_t a, const float f)
+ccl_device_inline vfloat8 operator-(const vfloat8 a, const float f)
{
- return a - make_float8_t(f);
+ return a - make_vfloat8(f);
}
-ccl_device_inline float8_t operator-(const float f, const float8_t a)
+ccl_device_inline vfloat8 operator-(const float f, const vfloat8 a)
{
- return make_float8_t(f) - a;
+ return make_vfloat8(f) - a;
}
-ccl_device_inline float8_t operator*(const float8_t a, const float8_t b)
+ccl_device_inline vfloat8 operator*(const vfloat8 a, const vfloat8 b)
{
-#ifdef __KERNEL_AVX2__
- return float8_t(_mm256_mul_ps(a.m256, b.m256));
+#ifdef __KERNEL_AVX__
+ return vfloat8(_mm256_mul_ps(a.m256, b.m256));
#else
- return make_float8_t(
+ return make_vfloat8(
a.a * b.a, a.b * b.b, a.c * b.c, a.d * b.d, a.e * b.e, a.f * b.f, a.g * b.g, a.h * b.h);
#endif
}
-ccl_device_inline float8_t operator*(const float8_t a, const float f)
+ccl_device_inline vfloat8 operator*(const vfloat8 a, const float f)
{
- return a * make_float8_t(f);
+ return a * make_vfloat8(f);
}
-ccl_device_inline float8_t operator*(const float f, const float8_t a)
+ccl_device_inline vfloat8 operator*(const float f, const vfloat8 a)
{
- return make_float8_t(f) * a;
+ return make_vfloat8(f) * a;
}
-ccl_device_inline float8_t operator/(const float8_t a, const float8_t b)
+ccl_device_inline vfloat8 operator/(const vfloat8 a, const vfloat8 b)
{
-#ifdef __KERNEL_AVX2__
- return float8_t(_mm256_div_ps(a.m256, b.m256));
+#ifdef __KERNEL_AVX__
+ return vfloat8(_mm256_div_ps(a.m256, b.m256));
#else
- return make_float8_t(
+ return make_vfloat8(
a.a / b.a, a.b / b.b, a.c / b.c, a.d / b.d, a.e / b.e, a.f / b.f, a.g / b.g, a.h / b.h);
#endif
}
-ccl_device_inline float8_t operator/(const float8_t a, const float f)
+ccl_device_inline vfloat8 operator/(const vfloat8 a, const float f)
{
- return a / make_float8_t(f);
+ return a / make_vfloat8(f);
}
-ccl_device_inline float8_t operator/(const float f, const float8_t a)
+ccl_device_inline vfloat8 operator/(const float f, const vfloat8 a)
{
- return make_float8_t(f) / a;
+ return make_vfloat8(f) / a;
}
-ccl_device_inline float8_t operator+=(float8_t a, const float8_t b)
+ccl_device_inline vfloat8 operator+=(vfloat8 a, const vfloat8 b)
{
return a = a + b;
}
-ccl_device_inline float8_t operator-=(float8_t a, const float8_t b)
+ccl_device_inline vfloat8 operator-=(vfloat8 a, const vfloat8 b)
{
return a = a - b;
}
-ccl_device_inline float8_t operator*=(float8_t a, const float8_t b)
+ccl_device_inline vfloat8 operator*=(vfloat8 a, const vfloat8 b)
{
return a = a * b;
}
-ccl_device_inline float8_t operator*=(float8_t a, float f)
+ccl_device_inline vfloat8 operator*=(vfloat8 a, float f)
{
return a = a * f;
}
-ccl_device_inline float8_t operator/=(float8_t a, float f)
+ccl_device_inline vfloat8 operator/=(vfloat8 a, float f)
{
return a = a / f;
}
-ccl_device_inline bool operator==(const float8_t a, const float8_t b)
+ccl_device_inline bool operator==(const vfloat8 a, const vfloat8 b)
{
-#ifdef __KERNEL_AVX2__
+#ifdef __KERNEL_AVX__
return (_mm256_movemask_ps(_mm256_castsi256_ps(
_mm256_cmpeq_epi32(_mm256_castps_si256(a.m256), _mm256_castps_si256(b.m256)))) &
0b11111111) == 0b11111111;
@@ -206,132 +152,180 @@ ccl_device_inline bool operator==(const float8_t a, const float8_t b)
#endif
}
-ccl_device_inline float8_t rcp(const float8_t a)
+ccl_device_inline const vfloat8 operator^(const vfloat8 a, const vfloat8 b)
{
-#ifdef __KERNEL_AVX2__
- return float8_t(_mm256_rcp_ps(a.m256));
+#ifdef __KERNEL_AVX__
+ return vfloat8(_mm256_xor_ps(a.m256, b.m256));
#else
- return make_float8_t(1.0f / a.a,
- 1.0f / a.b,
- 1.0f / a.c,
- 1.0f / a.d,
- 1.0f / a.e,
- 1.0f / a.f,
- 1.0f / a.g,
- 1.0f / a.h);
+ return make_vfloat8(__uint_as_float(__float_as_uint(a.a) ^ __float_as_uint(b.a)),
+ __uint_as_float(__float_as_uint(a.b) ^ __float_as_uint(b.b)),
+ __uint_as_float(__float_as_uint(a.c) ^ __float_as_uint(b.c)),
+ __uint_as_float(__float_as_uint(a.d) ^ __float_as_uint(b.d)),
+ __uint_as_float(__float_as_uint(a.e) ^ __float_as_uint(b.e)),
+ __uint_as_float(__float_as_uint(a.f) ^ __float_as_uint(b.f)),
+ __uint_as_float(__float_as_uint(a.g) ^ __float_as_uint(b.g)),
+ __uint_as_float(__float_as_uint(a.h) ^ __float_as_uint(b.h)));
#endif
}
-ccl_device_inline float8_t sqrt(const float8_t a)
+ccl_device_inline vfloat8 rcp(const vfloat8 a)
{
-#ifdef __KERNEL_AVX2__
- return float8_t(_mm256_sqrt_ps(a.m256));
+#ifdef __KERNEL_AVX__
+ return vfloat8(_mm256_rcp_ps(a.m256));
#else
- return make_float8_t(sqrtf(a.a),
- sqrtf(a.b),
- sqrtf(a.c),
- sqrtf(a.d),
- sqrtf(a.e),
- sqrtf(a.f),
- sqrtf(a.g),
- sqrtf(a.h));
+ return make_vfloat8(1.0f / a.a,
+ 1.0f / a.b,
+ 1.0f / a.c,
+ 1.0f / a.d,
+ 1.0f / a.e,
+ 1.0f / a.f,
+ 1.0f / a.g,
+ 1.0f / a.h);
#endif
}
-ccl_device_inline float8_t sqr(const float8_t a)
+ccl_device_inline vfloat8 sqrt(const vfloat8 a)
+{
+#ifdef __KERNEL_AVX__
+ return vfloat8(_mm256_sqrt_ps(a.m256));
+#else
+ return make_vfloat8(sqrtf(a.a),
+ sqrtf(a.b),
+ sqrtf(a.c),
+ sqrtf(a.d),
+ sqrtf(a.e),
+ sqrtf(a.f),
+ sqrtf(a.g),
+ sqrtf(a.h));
+#endif
+}
+
+ccl_device_inline vfloat8 sqr(const vfloat8 a)
{
return a * a;
}
-ccl_device_inline bool is_zero(const float8_t a)
+ccl_device_inline bool is_zero(const vfloat8 a)
{
- return a == make_float8_t(0.0f);
+ return a == make_vfloat8(0.0f);
}
-ccl_device_inline float average(const float8_t a)
+ccl_device_inline float reduce_add(const vfloat8 a)
+{
+#ifdef __KERNEL_AVX__
+ vfloat8 b(_mm256_hadd_ps(a.m256, a.m256));
+ vfloat8 h(_mm256_hadd_ps(b.m256, b.m256));
+ return h[0] + h[4];
+#else
+ return a.a + a.b + a.c + a.d + a.e + a.f + a.g + a.h;
+#endif
+}
+
+ccl_device_inline float average(const vfloat8 a)
{
return reduce_add(a) / 8.0f;
}
-ccl_device_inline float8_t min(const float8_t a, const float8_t b)
+ccl_device_inline vfloat8 min(const vfloat8 a, const vfloat8 b)
{
-#ifdef __KERNEL_AVX2__
- return float8_t(_mm256_min_ps(a.m256, b.m256));
+#ifdef __KERNEL_AVX__
+ return vfloat8(_mm256_min_ps(a.m256, b.m256));
#else
- return make_float8_t(min(a.a, b.a),
- min(a.b, b.b),
- min(a.c, b.c),
- min(a.d, b.d),
- min(a.e, b.e),
- min(a.f, b.f),
- min(a.g, b.g),
- min(a.h, b.h));
+ return make_vfloat8(min(a.a, b.a),
+ min(a.b, b.b),
+ min(a.c, b.c),
+ min(a.d, b.d),
+ min(a.e, b.e),
+ min(a.f, b.f),
+ min(a.g, b.g),
+ min(a.h, b.h));
#endif
}
-ccl_device_inline float8_t max(const float8_t a, const float8_t b)
+ccl_device_inline vfloat8 max(const vfloat8 a, const vfloat8 b)
{
-#ifdef __KERNEL_AVX2__
- return float8_t(_mm256_max_ps(a.m256, b.m256));
+#ifdef __KERNEL_AVX__
+ return vfloat8(_mm256_max_ps(a.m256, b.m256));
#else
- return make_float8_t(max(a.a, b.a),
- max(a.b, b.b),
- max(a.c, b.c),
- max(a.d, b.d),
- max(a.e, b.e),
- max(a.f, b.f),
- max(a.g, b.g),
- max(a.h, b.h));
+ return make_vfloat8(max(a.a, b.a),
+ max(a.b, b.b),
+ max(a.c, b.c),
+ max(a.d, b.d),
+ max(a.e, b.e),
+ max(a.f, b.f),
+ max(a.g, b.g),
+ max(a.h, b.h));
#endif
}
-ccl_device_inline float8_t clamp(const float8_t a, const float8_t mn, const float8_t mx)
+ccl_device_inline vfloat8 clamp(const vfloat8 a, const vfloat8 mn, const vfloat8 mx)
{
return min(max(a, mn), mx);
}
-ccl_device_inline float8_t fabs(const float8_t a)
+ccl_device_inline vfloat8 select(const vint8 mask, const vfloat8 a, const vfloat8 b)
{
-#ifdef __KERNEL_AVX2__
- return float8_t(_mm256_and_ps(a.m256, _mm256_castsi256_ps(_mm256_set1_epi32(0x7fffffff))));
+#ifdef __KERNEL_AVX__
+ return vfloat8(_mm256_blendv_ps(b, a, _mm256_castsi256_ps(mask)));
#else
- return make_float8_t(fabsf(a.a),
- fabsf(a.b),
- fabsf(a.c),
- fabsf(a.d),
- fabsf(a.e),
- fabsf(a.f),
- fabsf(a.g),
- fabsf(a.h));
+ return make_vfloat8((mask.a) ? a.a : b.a,
+ (mask.b) ? a.b : b.b,
+ (mask.c) ? a.c : b.c,
+ (mask.d) ? a.d : b.d,
+ (mask.e) ? a.e : b.e,
+ (mask.f) ? a.f : b.f,
+ (mask.g) ? a.g : b.g,
+ (mask.h) ? a.h : b.h);
#endif
}
-ccl_device_inline float8_t mix(const float8_t a, const float8_t b, float t)
+ccl_device_inline vfloat8 fabs(const vfloat8 a)
+{
+#ifdef __KERNEL_AVX__
+ return vfloat8(_mm256_and_ps(a.m256, _mm256_castsi256_ps(_mm256_set1_epi32(0x7fffffff))));
+#else
+ return make_vfloat8(fabsf(a.a),
+ fabsf(a.b),
+ fabsf(a.c),
+ fabsf(a.d),
+ fabsf(a.e),
+ fabsf(a.f),
+ fabsf(a.g),
+ fabsf(a.h));
+#endif
+}
+
+ccl_device_inline vfloat8 mix(const vfloat8 a, const vfloat8 b, float t)
+{
+ return a + t * (b - a);
+}
+
+ccl_device_inline vfloat8 mix(const vfloat8 a, const vfloat8 b, vfloat8 t)
{
return a + t * (b - a);
}
-ccl_device_inline float8_t saturate(const float8_t a)
+ccl_device_inline vfloat8 saturate(const vfloat8 a)
{
- return clamp(a, make_float8_t(0.0f), make_float8_t(1.0f));
+ return clamp(a, make_vfloat8(0.0f), make_vfloat8(1.0f));
}
-ccl_device_inline float8_t exp(float8_t v)
+ccl_device_inline vfloat8 exp(vfloat8 v)
{
- return make_float8_t(
+ return make_vfloat8(
expf(v.a), expf(v.b), expf(v.c), expf(v.d), expf(v.e), expf(v.f), expf(v.g), expf(v.h));
}
-ccl_device_inline float8_t log(float8_t v)
+ccl_device_inline vfloat8 log(vfloat8 v)
{
- return make_float8_t(
+ return make_vfloat8(
logf(v.a), logf(v.b), logf(v.c), logf(v.d), logf(v.e), logf(v.f), logf(v.g), logf(v.h));
}
-ccl_device_inline float dot(const float8_t a, const float8_t b)
+ccl_device_inline float dot(const vfloat8 a, const vfloat8 b)
{
-#ifdef __KERNEL_AVX2__
- float8_t t(_mm256_dp_ps(a.m256, b.m256, 0xFF));
+#ifdef __KERNEL_AVX__
+ vfloat8 t(_mm256_dp_ps(a.m256, b.m256, 0xFF));
return t[0] + t[4];
#else
return (a.a * b.a) + (a.b * b.b) + (a.c * b.c) + (a.d * b.d) + (a.e * b.e) + (a.f * b.f) +
@@ -339,62 +333,51 @@ ccl_device_inline float dot(const float8_t a, const float8_t b)
#endif
}
-ccl_device_inline float8_t pow(float8_t v, float e)
+ccl_device_inline vfloat8 pow(vfloat8 v, float e)
{
- return make_float8_t(powf(v.a, e),
- powf(v.b, e),
- powf(v.c, e),
- powf(v.d, e),
- powf(v.e, e),
- powf(v.f, e),
- powf(v.g, e),
- powf(v.h, e));
+ return make_vfloat8(powf(v.a, e),
+ powf(v.b, e),
+ powf(v.c, e),
+ powf(v.d, e),
+ powf(v.e, e),
+ powf(v.f, e),
+ powf(v.g, e),
+ powf(v.h, e));
}
-ccl_device_inline float reduce_min(const float8_t a)
+ccl_device_inline float reduce_min(const vfloat8 a)
{
return min(min(min(a.a, a.b), min(a.c, a.d)), min(min(a.e, a.f), min(a.g, a.h)));
}
-ccl_device_inline float reduce_max(const float8_t a)
+ccl_device_inline float reduce_max(const vfloat8 a)
{
return max(max(max(a.a, a.b), max(a.c, a.d)), max(max(a.e, a.f), max(a.g, a.h)));
}
-ccl_device_inline float reduce_add(const float8_t a)
-{
-#ifdef __KERNEL_AVX2__
- float8_t b(_mm256_hadd_ps(a.m256, a.m256));
- float8_t h(_mm256_hadd_ps(b.m256, b.m256));
- return h[0] + h[4];
-#else
- return a.a + a.b + a.c + a.d + a.e + a.f + a.g + a.h;
-#endif
-}
-
-ccl_device_inline bool isequal(const float8_t a, const float8_t b)
+ccl_device_inline bool isequal(const vfloat8 a, const vfloat8 b)
{
return a == b;
}
-ccl_device_inline float8_t safe_divide(const float8_t a, const float b)
+ccl_device_inline vfloat8 safe_divide(const vfloat8 a, const float b)
{
- return (b != 0.0f) ? a / b : make_float8_t(0.0f);
+ return (b != 0.0f) ? a / b : make_vfloat8(0.0f);
}
-ccl_device_inline float8_t safe_divide(const float8_t a, const float8_t b)
+ccl_device_inline vfloat8 safe_divide(const vfloat8 a, const vfloat8 b)
{
- return make_float8_t((b.a != 0.0f) ? a.a / b.a : 0.0f,
- (b.b != 0.0f) ? a.b / b.b : 0.0f,
- (b.c != 0.0f) ? a.c / b.c : 0.0f,
- (b.d != 0.0f) ? a.d / b.d : 0.0f,
- (b.e != 0.0f) ? a.e / b.e : 0.0f,
- (b.f != 0.0f) ? a.f / b.f : 0.0f,
- (b.g != 0.0f) ? a.g / b.g : 0.0f,
- (b.h != 0.0f) ? a.h / b.h : 0.0f);
+ return make_vfloat8((b.a != 0.0f) ? a.a / b.a : 0.0f,
+ (b.b != 0.0f) ? a.b / b.b : 0.0f,
+ (b.c != 0.0f) ? a.c / b.c : 0.0f,
+ (b.d != 0.0f) ? a.d / b.d : 0.0f,
+ (b.e != 0.0f) ? a.e / b.e : 0.0f,
+ (b.f != 0.0f) ? a.f / b.f : 0.0f,
+ (b.g != 0.0f) ? a.g / b.g : 0.0f,
+ (b.h != 0.0f) ? a.h / b.h : 0.0f);
}
-ccl_device_inline float8_t ensure_finite(float8_t v)
+ccl_device_inline vfloat8 ensure_finite(vfloat8 v)
{
v.a = ensure_finite(v.a);
v.b = ensure_finite(v.b);
@@ -408,12 +391,92 @@ ccl_device_inline float8_t ensure_finite(float8_t v)
return v;
}
-ccl_device_inline bool isfinite_safe(float8_t v)
+ccl_device_inline bool isfinite_safe(vfloat8 v)
{
return isfinite_safe(v.a) && isfinite_safe(v.b) && isfinite_safe(v.c) && isfinite_safe(v.d) &&
isfinite_safe(v.e) && isfinite_safe(v.f) && isfinite_safe(v.g) && isfinite_safe(v.h);
}
+ccl_device_inline vint8 cast(const vfloat8 a)
+{
+#ifdef __KERNEL_AVX__
+ return vint8(_mm256_castps_si256(a));
+#else
+ return make_vint8(__float_as_int(a.a),
+ __float_as_int(a.b),
+ __float_as_int(a.c),
+ __float_as_int(a.d),
+ __float_as_int(a.e),
+ __float_as_int(a.f),
+ __float_as_int(a.g),
+ __float_as_int(a.h));
+#endif
+}
+
+#ifdef __KERNEL_SSE__
+ccl_device_forceinline float4 low(const vfloat8 a)
+{
+# ifdef __KERNEL_AVX__
+ return float4(_mm256_extractf128_ps(a.m256, 0));
+# else
+ return make_float4(a.e, a.f, a.g, a.h);
+# endif
+}
+ccl_device_forceinline float4 high(const vfloat8 a)
+{
+# ifdef __KERNEL_AVX__
+ return float4(_mm256_extractf128_ps(a.m256, 1));
+# else
+ return make_float4(a.a, a.b, a.c, a.d);
+# endif
+}
+
+template<int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7>
+ccl_device_forceinline const vfloat8 shuffle(const vfloat8 a)
+{
+# ifdef __KERNEL_AVX__
+ return vfloat8(_mm256_permutevar_ps(a, _mm256_set_epi32(i7, i6, i5, i4, i3, i2, i1, i0)));
+# else
+ return make_vfloat8(a[i0], a[i1], a[i2], a[i3], a[i4 + 4], a[i5 + 4], a[i6 + 4], a[i7 + 4]);
+# endif
+}
+
+template<size_t i0, size_t i1, size_t i2, size_t i3>
+ccl_device_forceinline const vfloat8 shuffle(const vfloat8 a, const vfloat8 b)
+{
+# ifdef __KERNEL_AVX__
+ return vfloat8(_mm256_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0)));
+# else
+ return make_vfloat8(shuffle<i0, i1, i2, i3>(high(a), high(b)),
+ shuffle<i0, i1, i2, i3>(low(a), low(b)));
+# endif
+}
+
+template<size_t i0, size_t i1, size_t i2, size_t i3>
+ccl_device_forceinline const vfloat8 shuffle(const vfloat8 a)
+{
+ return shuffle<i0, i1, i2, i3>(a, a);
+}
+template<size_t i0> ccl_device_forceinline const vfloat8 shuffle(const vfloat8 a, const vfloat8 b)
+{
+ return shuffle<i0, i0, i0, i0>(a, b);
+}
+template<size_t i0> ccl_device_forceinline const vfloat8 shuffle(const vfloat8 a)
+{
+ return shuffle<i0>(a, a);
+}
+
+template<size_t i> ccl_device_forceinline float extract(const vfloat8 a)
+{
+# ifdef __KERNEL_AVX__
+ __m256 b = shuffle<i, i, i, i>(a).m256;
+ return _mm256_cvtss_f32(b);
+# else
+ return a[i];
+# endif
+}
+#endif
+
CCL_NAMESPACE_END
#endif /* __UTIL_MATH_FLOAT8_H__ */
diff --git a/intern/cycles/util/math_int2.h b/intern/cycles/util/math_int2.h
index f4d8a71221a..2df2ec5505b 100644
--- a/intern/cycles/util/math_int2.h
+++ b/intern/cycles/util/math_int2.h
@@ -10,23 +10,6 @@
CCL_NAMESPACE_BEGIN
-/*******************************************************************************
- * Declaration.
- */
-
-#if !defined(__KERNEL_METAL__)
-ccl_device_inline bool operator==(const int2 a, const int2 b);
-ccl_device_inline int2 operator+(const int2 &a, const int2 &b);
-ccl_device_inline int2 operator+=(int2 &a, const int2 &b);
-ccl_device_inline int2 operator-(const int2 &a, const int2 &b);
-ccl_device_inline int2 operator*(const int2 &a, const int2 &b);
-ccl_device_inline int2 operator/(const int2 &a, const int2 &b);
-#endif /* !__KERNEL_METAL__ */
-
-/*******************************************************************************
- * Definition.
- */
-
#if !defined(__KERNEL_METAL__)
ccl_device_inline bool operator==(const int2 a, const int2 b)
{
diff --git a/intern/cycles/util/math_int3.h b/intern/cycles/util/math_int3.h
index 48bffeaf553..b5b972ddfb5 100644
--- a/intern/cycles/util/math_int3.h
+++ b/intern/cycles/util/math_int3.h
@@ -10,21 +10,6 @@
CCL_NAMESPACE_BEGIN
-/*******************************************************************************
- * Declaration.
- */
-
-#if !defined(__KERNEL_METAL__)
-ccl_device_inline int3 min(int3 a, int3 b);
-ccl_device_inline int3 max(int3 a, int3 b);
-ccl_device_inline int3 clamp(const int3 &a, int mn, int mx);
-ccl_device_inline int3 clamp(const int3 &a, int3 &mn, int mx);
-#endif /* !defined(__KERNEL_METAL__) */
-
-/*******************************************************************************
- * Definition.
- */
-
#if !defined(__KERNEL_METAL__)
ccl_device_inline int3 min(int3 a, int3 b)
{
@@ -44,7 +29,7 @@ ccl_device_inline int3 max(int3 a, int3 b)
# endif
}
-ccl_device_inline int3 clamp(const int3 &a, int mn, int mx)
+ccl_device_inline int3 clamp(const int3 a, int mn, int mx)
{
# ifdef __KERNEL_SSE__
return min(max(a, make_int3(mn)), make_int3(mx));
@@ -53,7 +38,7 @@ ccl_device_inline int3 clamp(const int3 &a, int mn, int mx)
# endif
}
-ccl_device_inline int3 clamp(const int3 &a, int3 &mn, int mx)
+ccl_device_inline int3 clamp(const int3 a, int3 &mn, int mx)
{
# ifdef __KERNEL_SSE__
return min(max(a, mn), make_int3(mx));
@@ -62,22 +47,22 @@ ccl_device_inline int3 clamp(const int3 &a, int3 &mn, int mx)
# endif
}
-ccl_device_inline bool operator==(const int3 &a, const int3 &b)
+ccl_device_inline bool operator==(const int3 a, const int3 b)
{
return a.x == b.x && a.y == b.y && a.z == b.z;
}
-ccl_device_inline bool operator!=(const int3 &a, const int3 &b)
+ccl_device_inline bool operator!=(const int3 a, const int3 b)
{
return !(a == b);
}
-ccl_device_inline bool operator<(const int3 &a, const int3 &b)
+ccl_device_inline bool operator<(const int3 a, const int3 b)
{
return a.x < b.x && a.y < b.y && a.z < b.z;
}
-ccl_device_inline int3 operator+(const int3 &a, const int3 &b)
+ccl_device_inline int3 operator+(const int3 a, const int3 b)
{
# ifdef __KERNEL_SSE__
return int3(_mm_add_epi32(a.m128, b.m128));
@@ -86,7 +71,7 @@ ccl_device_inline int3 operator+(const int3 &a, const int3 &b)
# endif
}
-ccl_device_inline int3 operator-(const int3 &a, const int3 &b)
+ccl_device_inline int3 operator-(const int3 a, const int3 b)
{
# ifdef __KERNEL_SSE__
return int3(_mm_sub_epi32(a.m128, b.m128));
diff --git a/intern/cycles/util/math_int4.h b/intern/cycles/util/math_int4.h
index fbdada223cb..c6d767d7587 100644
--- a/intern/cycles/util/math_int4.h
+++ b/intern/cycles/util/math_int4.h
@@ -1,4 +1,5 @@
/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2013 Intel Corporation
* Copyright 2011-2022 Blender Foundation */
#ifndef __UTIL_MATH_INT4_H__
@@ -10,30 +11,8 @@
CCL_NAMESPACE_BEGIN
-/*******************************************************************************
- * Declaration.
- */
-
#ifndef __KERNEL_GPU__
-ccl_device_inline int4 operator+(const int4 &a, const int4 &b);
-ccl_device_inline int4 operator+=(int4 &a, const int4 &b);
-ccl_device_inline int4 operator>>(const int4 &a, int i);
-ccl_device_inline int4 operator<<(const int4 &a, int i);
-ccl_device_inline int4 operator<(const int4 &a, const int4 &b);
-ccl_device_inline int4 operator>=(const int4 &a, const int4 &b);
-ccl_device_inline int4 operator&(const int4 &a, const int4 &b);
-ccl_device_inline int4 min(int4 a, int4 b);
-ccl_device_inline int4 max(int4 a, int4 b);
-ccl_device_inline int4 clamp(const int4 &a, const int4 &mn, const int4 &mx);
-ccl_device_inline int4 select(const int4 &mask, const int4 &a, const int4 &b);
-#endif /* __KERNEL_GPU__ */
-
-/*******************************************************************************
- * Definition.
- */
-
-#ifndef __KERNEL_GPU__
-ccl_device_inline int4 operator+(const int4 &a, const int4 &b)
+ccl_device_inline int4 operator+(const int4 a, const int4 b)
{
# ifdef __KERNEL_SSE__
return int4(_mm_add_epi32(a.m128, b.m128));
@@ -42,12 +21,26 @@ ccl_device_inline int4 operator+(const int4 &a, const int4 &b)
# endif
}
-ccl_device_inline int4 operator+=(int4 &a, const int4 &b)
+ccl_device_inline int4 operator+=(int4 &a, const int4 b)
{
return a = a + b;
}
-ccl_device_inline int4 operator>>(const int4 &a, int i)
+ccl_device_inline int4 operator-(const int4 a, const int4 b)
+{
+# ifdef __KERNEL_SSE__
+ return int4(_mm_sub_epi32(a.m128, b.m128));
+# else
+ return make_int4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
+# endif
+}
+
+ccl_device_inline int4 operator-=(int4 &a, const int4 b)
+{
+ return a = a - b;
+}
+
+ccl_device_inline int4 operator>>(const int4 a, int i)
{
# ifdef __KERNEL_SSE__
return int4(_mm_srai_epi32(a.m128, i));
@@ -56,7 +49,7 @@ ccl_device_inline int4 operator>>(const int4 &a, int i)
# endif
}
-ccl_device_inline int4 operator<<(const int4 &a, int i)
+ccl_device_inline int4 operator<<(const int4 a, int i)
{
# ifdef __KERNEL_SSE__
return int4(_mm_slli_epi32(a.m128, i));
@@ -65,7 +58,7 @@ ccl_device_inline int4 operator<<(const int4 &a, int i)
# endif
}
-ccl_device_inline int4 operator<(const int4 &a, const int4 &b)
+ccl_device_inline int4 operator<(const int4 a, const int4 b)
{
# ifdef __KERNEL_SSE__
return int4(_mm_cmplt_epi32(a.m128, b.m128));
@@ -74,7 +67,26 @@ ccl_device_inline int4 operator<(const int4 &a, const int4 &b)
# endif
}
-ccl_device_inline int4 operator>=(const int4 &a, const int4 &b)
+ccl_device_inline int4 operator<(const int4 a, const int b)
+{
+ return a < make_int4(b);
+}
+
+ccl_device_inline int4 operator==(const int4 a, const int4 b)
+{
+# ifdef __KERNEL_SSE__
+ return int4(_mm_cmpeq_epi32(a.m128, b.m128));
+# else
+ return make_int4(a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w);
+# endif
+}
+
+ccl_device_inline int4 operator==(const int4 a, const int b)
+{
+ return a == make_int4(b);
+}
+
+ccl_device_inline int4 operator>=(const int4 a, const int4 b)
{
# ifdef __KERNEL_SSE__
return int4(_mm_xor_si128(_mm_set1_epi32(0xffffffff), _mm_cmplt_epi32(a.m128, b.m128)));
@@ -83,7 +95,12 @@ ccl_device_inline int4 operator>=(const int4 &a, const int4 &b)
# endif
}
-ccl_device_inline int4 operator&(const int4 &a, const int4 &b)
+ccl_device_inline int4 operator>=(const int4 a, const int b)
+{
+ return a >= make_int4(b);
+}
+
+ccl_device_inline int4 operator&(const int4 a, const int4 b)
{
# ifdef __KERNEL_SSE__
return int4(_mm_and_si128(a.m128, b.m128));
@@ -92,6 +109,97 @@ ccl_device_inline int4 operator&(const int4 &a, const int4 &b)
# endif
}
+ccl_device_inline int4 operator|(const int4 a, const int4 b)
+{
+# ifdef __KERNEL_SSE__
+ return int4(_mm_or_si128(a.m128, b.m128));
+# else
+ return make_int4(a.x | b.x, a.y | b.y, a.z | b.z, a.w | b.w);
+# endif
+}
+
+ccl_device_inline int4 operator^(const int4 a, const int4 b)
+{
+# ifdef __KERNEL_SSE__
+ return int4(_mm_xor_si128(a.m128, b.m128));
+# else
+ return make_int4(a.x ^ b.x, a.y ^ b.y, a.z ^ b.z, a.w ^ b.w);
+# endif
+}
+
+ccl_device_inline int4 operator&(const int32_t a, const int4 b)
+{
+ return make_int4(a) & b;
+}
+
+ccl_device_inline int4 operator&(const int4 a, const int32_t b)
+{
+ return a & make_int4(b);
+}
+
+ccl_device_inline int4 operator|(const int32_t a, const int4 b)
+{
+ return make_int4(a) | b;
+}
+
+ccl_device_inline int4 operator|(const int4 a, const int32_t b)
+{
+ return a | make_int4(b);
+}
+
+ccl_device_inline int4 operator^(const int32_t a, const int4 b)
+{
+ return make_int4(a) ^ b;
+}
+
+ccl_device_inline int4 operator^(const int4 a, const int32_t b)
+{
+ return a ^ make_int4(b);
+}
+
+ccl_device_inline int4 &operator&=(int4 &a, const int4 b)
+{
+ return a = a & b;
+}
+ccl_device_inline int4 &operator&=(int4 &a, const int32_t b)
+{
+ return a = a & b;
+}
+
+ccl_device_inline int4 &operator|=(int4 &a, const int4 b)
+{
+ return a = a | b;
+}
+ccl_device_inline int4 &operator|=(int4 &a, const int32_t b)
+{
+ return a = a | b;
+}
+
+ccl_device_inline int4 &operator^=(int4 &a, const int4 b)
+{
+ return a = a ^ b;
+}
+ccl_device_inline int4 &operator^=(int4 &a, const int32_t b)
+{
+ return a = a ^ b;
+}
+
+ccl_device_inline int4 &operator<<=(int4 &a, const int32_t b)
+{
+ return a = a << b;
+}
+ccl_device_inline int4 &operator>>=(int4 &a, const int32_t b)
+{
+ return a = a >> b;
+}
+
+# ifdef __KERNEL_SSE__
+ccl_device_forceinline const int4 srl(const int4 a, const int32_t b)
+{
+ return int4(_mm_srli_epi32(a.m128, b));
+}
+# endif
+
ccl_device_inline int4 min(int4 a, int4 b)
{
# if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE41__)
@@ -110,12 +218,12 @@ ccl_device_inline int4 max(int4 a, int4 b)
# endif
}
-ccl_device_inline int4 clamp(const int4 &a, const int4 &mn, const int4 &mx)
+ccl_device_inline int4 clamp(const int4 a, const int4 mn, const int4 mx)
{
return min(max(a, mn), mx);
}
-ccl_device_inline int4 select(const int4 &mask, const int4 &a, const int4 &b)
+ccl_device_inline int4 select(const int4 mask, const int4 a, const int4 b)
{
# ifdef __KERNEL_SSE__
return int4(_mm_or_si128(_mm_and_si128(mask, a), _mm_andnot_si128(mask, b)));
@@ -135,6 +243,52 @@ ccl_device_inline int4 load_int4(const int *v)
}
#endif /* __KERNEL_GPU__ */
+ccl_device_inline float4 cast(const int4 a)
+{
+#ifdef __KERNEL_SSE__
+ return float4(_mm_castsi128_ps(a));
+#else
+ return make_float4(
+ __int_as_float(a.x), __int_as_float(a.y), __int_as_float(a.z), __int_as_float(a.w));
+#endif
+}
+
+#ifdef __KERNEL_SSE__
+ccl_device_forceinline int4 andnot(const int4 a, const int4 b)
+{
+ return int4(_mm_andnot_si128(a.m128, b.m128));
+}
+
+template<size_t i0, size_t i1, size_t i2, size_t i3>
+ccl_device_forceinline int4 shuffle(const int4 a)
+{
+# ifdef __KERNEL_NEON__
+ int32x4_t result = shuffle_neon<int32x4_t, i0, i1, i2, i3>(vreinterpretq_s32_m128i(a));
+ return int4(vreinterpretq_m128i_s32(result));
+# else
+ return int4(_mm_shuffle_epi32(a, _MM_SHUFFLE(i3, i2, i1, i0)));
+# endif
+}
+
+template<size_t i0, size_t i1, size_t i2, size_t i3>
+ccl_device_forceinline int4 shuffle(const int4 a, const int4 b)
+{
+# ifdef __KERNEL_NEON__
+ int32x4_t result = shuffle_neon<int32x4_t, i0, i1, i2, i3>(vreinterpretq_s32_m128i(a),
+ vreinterpretq_s32_m128i(b));
+ return int4(vreinterpretq_m128i_s32(result));
+# else
+ return int4(_mm_castps_si128(
+ _mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _MM_SHUFFLE(i3, i2, i1, i0))));
+# endif
+}
+
+template<size_t i0> ccl_device_forceinline int4 shuffle(const int4 b)
+{
+ return shuffle<i0, i0, i0, i0>(b);
+}
+#endif
+
CCL_NAMESPACE_END
#endif /* __UTIL_MATH_INT4_H__ */
diff --git a/intern/cycles/util/math_int8.h b/intern/cycles/util/math_int8.h
new file mode 100644
index 00000000000..d150b0b74ec
--- /dev/null
+++ b/intern/cycles/util/math_int8.h
@@ -0,0 +1,355 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2013 Intel Corporation
+ * Copyright 2011-2022 Blender Foundation */
+
+#ifndef __UTIL_MATH_INT8_H__
+#define __UTIL_MATH_INT8_H__
+
+#ifndef __UTIL_MATH_H__
+# error "Do not include this file directly, include util/types.h instead."
+#endif
+
+CCL_NAMESPACE_BEGIN
+
+#ifndef __KERNEL_GPU__
+ccl_device_inline vint8 operator+(const vint8 a, const vint8 b)
+{
+# ifdef __KERNEL_AVX__
+ return vint8(_mm256_add_epi32(a.m256, b.m256));
+# else
+ return make_vint8(
+ a.a + b.a, a.b + b.b, a.c + b.c, a.d + b.d, a.e + b.e, a.f + b.f, a.g + b.g, a.h + b.h);
+# endif
+}
+
+ccl_device_inline vint8 operator+=(vint8 &a, const vint8 b)
+{
+ return a = a + b;
+}
+
+ccl_device_inline vint8 operator-(const vint8 a, const vint8 b)
+{
+# ifdef __KERNEL_AVX__
+ return vint8(_mm256_sub_epi32(a.m256, b.m256));
+# else
+ return make_vint8(
+ a.a - b.a, a.b - b.b, a.c - b.c, a.d - b.d, a.e - b.e, a.f - b.f, a.g - b.g, a.h - b.h);
+# endif
+}
+
+ccl_device_inline vint8 operator-=(vint8 &a, const vint8 b)
+{
+ return a = a - b;
+}
+
+ccl_device_inline vint8 operator>>(const vint8 a, int i)
+{
+# ifdef __KERNEL_AVX__
+ return vint8(_mm256_srai_epi32(a.m256, i));
+# else
+ return make_vint8(
+ a.a >> i, a.b >> i, a.c >> i, a.d >> i, a.e >> i, a.f >> i, a.g >> i, a.h >> i);
+# endif
+}
+
+ccl_device_inline vint8 operator<<(const vint8 a, int i)
+{
+# ifdef __KERNEL_AVX__
+ return vint8(_mm256_slli_epi32(a.m256, i));
+# else
+ return make_vint8(
+ a.a << i, a.b << i, a.c << i, a.d << i, a.e << i, a.f << i, a.g << i, a.h << i);
+# endif
+}
+
+ccl_device_inline vint8 operator<(const vint8 a, const vint8 b)
+{
+# ifdef __KERNEL_AVX__
+ return vint8(_mm256_cmpgt_epi32(b.m256, a.m256));
+# else
+ return make_vint8(
+ a.a < b.a, a.b < b.b, a.c < b.c, a.d < b.d, a.e < b.e, a.f < b.f, a.g < b.g, a.h < b.h);
+# endif
+}
+
+ccl_device_inline vint8 operator<(const vint8 a, const int b)
+{
+ return a < make_vint8(b);
+}
+
+ccl_device_inline vint8 operator==(const vint8 a, const vint8 b)
+{
+# ifdef __KERNEL_AVX__
+ return vint8(_mm256_cmpeq_epi32(a.m256, b.m256));
+# else
+ return make_vint8(a.a == b.a,
+ a.b == b.b,
+ a.c == b.c,
+ a.d == b.d,
+ a.e == b.e,
+ a.f == b.f,
+ a.g == b.g,
+ a.h == b.h);
+# endif
+}
+
+ccl_device_inline vint8 operator==(const vint8 a, const int b)
+{
+ return a == make_vint8(b);
+}
+
+ccl_device_inline vint8 operator>=(const vint8 a, const vint8 b)
+{
+# ifdef __KERNEL_AVX__
+ return vint8(
+ _mm256_xor_si256(_mm256_set1_epi32(0xffffffff), _mm256_cmpgt_epi32(b.m256, a.m256)));
+# else
+ return make_vint8(a.a >= b.a,
+ a.b >= b.b,
+ a.c >= b.c,
+ a.d >= b.d,
+ a.e >= b.e,
+ a.f >= b.f,
+ a.g >= b.g,
+ a.h >= b.h);
+# endif
+}
+
+ccl_device_inline vint8 operator>=(const vint8 a, const int b)
+{
+ return a >= make_vint8(b);
+}
+
+ccl_device_inline vint8 operator&(const vint8 a, const vint8 b)
+{
+# ifdef __KERNEL_AVX__
+ return vint8(_mm256_and_si256(a.m256, b.m256));
+# else
+ return make_vint8(
+ a.a & b.a, a.b & b.b, a.c & b.c, a.d & b.d, a.e & b.e, a.f & b.f, a.g & b.g, a.h & b.h);
+# endif
+}
+
+ccl_device_inline vint8 operator|(const vint8 a, const vint8 b)
+{
+# ifdef __KERNEL_AVX__
+ return vint8(_mm256_or_si256(a.m256, b.m256));
+# else
+ return make_vint8(
+ a.a | b.a, a.b | b.b, a.c | b.c, a.d | b.d, a.e | b.e, a.f | b.f, a.g | b.g, a.h | b.h);
+# endif
+}
+
+ccl_device_inline vint8 operator^(const vint8 a, const vint8 b)
+{
+# ifdef __KERNEL_AVX__
+ return vint8(_mm256_xor_si256(a.m256, b.m256));
+# else
+ return make_vint8(
+ a.a ^ b.a, a.b ^ b.b, a.c ^ b.c, a.d ^ b.d, a.e ^ b.e, a.f ^ b.f, a.g ^ b.g, a.h ^ b.h);
+# endif
+}
+
+ccl_device_inline vint8 operator&(const int32_t a, const vint8 b)
+{
+ return make_vint8(a) & b;
+}
+
+ccl_device_inline vint8 operator&(const vint8 a, const int32_t b)
+{
+ return a & make_vint8(b);
+}
+
+ccl_device_inline vint8 operator|(const int32_t a, const vint8 b)
+{
+ return make_vint8(a) | b;
+}
+
+ccl_device_inline vint8 operator|(const vint8 a, const int32_t b)
+{
+ return a | make_vint8(b);
+}
+
+ccl_device_inline vint8 operator^(const int32_t a, const vint8 b)
+{
+ return make_vint8(a) ^ b;
+}
+
+ccl_device_inline vint8 operator^(const vint8 a, const int32_t b)
+{
+ return a ^ make_vint8(b);
+}
+
+ccl_device_inline vint8 &operator&=(vint8 &a, const vint8 b)
+{
+ return a = a & b;
+}
+ccl_device_inline vint8 &operator&=(vint8 &a, const int32_t b)
+{
+ return a = a & b;
+}
+
+ccl_device_inline vint8 &operator|=(vint8 &a, const vint8 b)
+{
+ return a = a | b;
+}
+ccl_device_inline vint8 &operator|=(vint8 &a, const int32_t b)
+{
+ return a = a | b;
+}
+
+ccl_device_inline vint8 &operator^=(vint8 &a, const vint8 b)
+{
+ return a = a ^ b;
+}
+ccl_device_inline vint8 &operator^=(vint8 &a, const int32_t b)
+{
+ return a = a ^ b;
+}
+
+ccl_device_inline vint8 &operator<<=(vint8 &a, const int32_t b)
+{
+ return a = a << b;
+}
+ccl_device_inline vint8 &operator>>=(vint8 &a, const int32_t b)
+{
+ return a = a >> b;
+}
+
+# ifdef __KERNEL_AVX__
+ccl_device_forceinline const vint8 srl(const vint8 a, const int32_t b)
+{
+ return vint8(_mm256_srli_epi32(a.m256, b));
+}
+# endif
+
+ccl_device_inline vint8 min(vint8 a, vint8 b)
+{
+# if defined(__KERNEL_AVX__) && defined(__KERNEL_AVX41__)
+ return vint8(_mm256_min_epi32(a.m256, b.m256));
+# else
+ return make_vint8(min(a.a, b.a),
+ min(a.b, b.b),
+ min(a.c, b.c),
+ min(a.d, b.d),
+ min(a.e, b.e),
+ min(a.f, b.f),
+ min(a.g, b.g),
+ min(a.h, b.h));
+# endif
+}
+
+ccl_device_inline vint8 max(vint8 a, vint8 b)
+{
+# if defined(__KERNEL_AVX__) && defined(__KERNEL_AVX41__)
+ return vint8(_mm256_max_epi32(a.m256, b.m256));
+# else
+ return make_vint8(max(a.a, b.a),
+ max(a.b, b.b),
+ max(a.c, b.c),
+ max(a.d, b.d),
+ max(a.e, b.e),
+ max(a.f, b.f),
+ max(a.g, b.g),
+ max(a.h, b.h));
+# endif
+}
+
+ccl_device_inline vint8 clamp(const vint8 a, const vint8 mn, const vint8 mx)
+{
+ return min(max(a, mn), mx);
+}
+
+ccl_device_inline vint8 select(const vint8 mask, const vint8 a, const vint8 b)
+{
+# ifdef __KERNEL_AVX__
+ return vint8(_mm256_castps_si256(_mm256_blendv_ps(
+ _mm256_castsi256_ps(b), _mm256_castsi256_ps(a), _mm256_castsi256_ps(mask))));
+# else
+ return make_vint8((mask.a) ? a.a : b.a,
+ (mask.b) ? a.b : b.b,
+ (mask.c) ? a.c : b.c,
+ (mask.d) ? a.d : b.d,
+ (mask.e) ? a.e : b.e,
+ (mask.f) ? a.f : b.f,
+ (mask.g) ? a.g : b.g,
+ (mask.h) ? a.h : b.h);
+# endif
+}
+
+ccl_device_inline vint8 load_vint8(const int *v)
+{
+# ifdef __KERNEL_AVX__
+ return vint8(_mm256_loadu_si256((__m256i *)v));
+# else
+ return make_vint8(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);
+# endif
+}
+#endif /* __KERNEL_GPU__ */
+
+ccl_device_inline vfloat8 cast(const vint8 a)
+{
+#ifdef __KERNEL_AVX__
+ return vfloat8(_mm256_castsi256_ps(a));
+#else
+ return make_vfloat8(__int_as_float(a.a),
+ __int_as_float(a.b),
+ __int_as_float(a.c),
+ __int_as_float(a.d),
+ __int_as_float(a.e),
+ __int_as_float(a.f),
+ __int_as_float(a.g),
+ __int_as_float(a.h));
+#endif
+}
+
+#ifdef __KERNEL_AVX__
+template<size_t i> ccl_device_forceinline const vint8 shuffle(const vint8 a)
+{
+ return vint8(
+ _mm256_castps_si256(_mm256_permute_ps(_mm256_castsi256_ps(a), _MM_SHUFFLE(i, i, i, i))));
+}
+
+template<size_t i0, size_t i1> ccl_device_forceinline const vint8 shuffle(const vint8 a)
+{
+ return vint8(_mm256_permute2f128_si256(a, a, (i1 << 4) | (i0 << 0)));
+}
+
+template<size_t i0, size_t i1>
+ccl_device_forceinline const vint8 shuffle(const vint8 a, const vint8 b)
+{
+ return vint8(_mm256_permute2f128_si256(a, b, (i1 << 4) | (i0 << 0)));
+}
+
+template<size_t i0, size_t i1, size_t i2, size_t i3>
+ccl_device_forceinline const vint8 shuffle(const vint8 a)
+{
+ return vint8(
+ _mm256_castps_si256(_mm256_permute_ps(_mm256_castsi256_ps(a), _MM_SHUFFLE(i3, i2, i1, i0))));
+}
+
+template<size_t i0, size_t i1, size_t i2, size_t i3>
+ccl_device_forceinline const vint8 shuffle(const vint8 a, const vint8 b)
+{
+ return vint8(_mm256_castps_si256(_mm256_shuffle_ps(
+ _mm256_castsi256_ps(a), _mm256_castsi256_ps(b), _MM_SHUFFLE(i3, i2, i1, i0))));
+}
+
+template<> __forceinline const vint8 shuffle<0, 0, 2, 2>(const vint8 b)
+{
+ return vint8(_mm256_castps_si256(_mm256_moveldup_ps(_mm256_castsi256_ps(b))));
+}
+template<> __forceinline const vint8 shuffle<1, 1, 3, 3>(const vint8 b)
+{
+ return vint8(_mm256_castps_si256(_mm256_movehdup_ps(_mm256_castsi256_ps(b))));
+}
+template<> __forceinline const vint8 shuffle<0, 1, 0, 1>(const vint8 b)
+{
+ return vint8(_mm256_castps_si256(
+ _mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(_mm256_castsi256_ps(b))))));
+}
+#endif
+
+CCL_NAMESPACE_END
+
+#endif /* __UTIL_MATH_INT8_H__ */
diff --git a/intern/cycles/util/math_intersect.h b/intern/cycles/util/math_intersect.h
index aa28682f8c1..0727debf775 100644
--- a/intern/cycles/util/math_intersect.h
+++ b/intern/cycles/util/math_intersect.h
@@ -133,7 +133,9 @@ ccl_device_forceinline float ray_triangle_rcp(const float x)
ccl_device_inline float ray_triangle_dot(const float3 a, const float3 b)
{
#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
- return madd(ssef(a.x), ssef(b.x), madd(ssef(a.y), ssef(b.y), ssef(a.z) * ssef(b.z)))[0];
+ return madd(make_float4(a.x),
+ make_float4(b.x),
+ madd(make_float4(a.y), make_float4(b.y), make_float4(a.z) * make_float4(b.z)))[0];
#else
return a.x * b.x + a.y * b.y + a.z * b.z;
#endif
@@ -142,9 +144,10 @@ ccl_device_inline float ray_triangle_dot(const float3 a, const float3 b)
ccl_device_inline float3 ray_triangle_cross(const float3 a, const float3 b)
{
#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
- return make_float3(msub(ssef(a.y), ssef(b.z), ssef(a.z) * ssef(b.y))[0],
- msub(ssef(a.z), ssef(b.x), ssef(a.x) * ssef(b.z))[0],
- msub(ssef(a.x), ssef(b.y), ssef(a.y) * ssef(b.x))[0]);
+ return make_float3(
+ msub(make_float4(a.y), make_float4(b.z), make_float4(a.z) * make_float4(b.y))[0],
+ msub(make_float4(a.z), make_float4(b.x), make_float4(a.x) * make_float4(b.z))[0],
+ msub(make_float4(a.x), make_float4(b.y), make_float4(a.y) * make_float4(b.x))[0]);
#else
return 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);
#endif
diff --git a/intern/cycles/util/md5.cpp b/intern/cycles/util/md5.cpp
index 1c7e6b9bf3e..3342d7a509a 100644
--- a/intern/cycles/util/md5.cpp
+++ b/intern/cycles/util/md5.cpp
@@ -347,13 +347,18 @@ void MD5Hash::finish(uint8_t digest[16])
string MD5Hash::get_hex()
{
+ constexpr char kHexDigits[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+
uint8_t digest[16];
char buf[16 * 2 + 1];
finish(digest);
- for (int i = 0; i < 16; i++)
- sprintf(buf + i * 2, "%02X", (unsigned int)digest[i]);
+ for (int i = 0; i < 16; i++) {
+ buf[i * 2 + 0] = kHexDigits[digest[i] / 0x10];
+ buf[i * 2 + 1] = kHexDigits[digest[i] % 0x10];
+ }
buf[sizeof(buf) - 1] = '\0';
return string(buf);
diff --git a/intern/cycles/util/sseb.h b/intern/cycles/util/sseb.h
deleted file mode 100644
index 6f78299711e..00000000000
--- a/intern/cycles/util/sseb.h
+++ /dev/null
@@ -1,345 +0,0 @@
-/* SPDX-License-Identifier: Apache-2.0
- * Copyright 2011-2013 Intel Corporation
- * Modifications Copyright 2014-2022 Blender Foundation. */
-
-#ifndef __UTIL_SSEB_H__
-#define __UTIL_SSEB_H__
-
-CCL_NAMESPACE_BEGIN
-
-#ifdef __KERNEL_SSE2__
-
-struct ssei;
-struct ssef;
-
-/*! 4-wide SSE bool type. */
-struct sseb {
- typedef sseb Mask; // mask type
- typedef ssei Int; // int type
- typedef ssef Float; // float type
-
- enum { size = 4 }; // number of SIMD elements
- union {
- __m128 m128;
- int32_t v[4];
- }; // data
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Constructors, Assignment & Cast Operators
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline sseb()
- {
- }
- __forceinline sseb(const sseb &other)
- {
- m128 = other.m128;
- }
- __forceinline sseb &operator=(const sseb &other)
- {
- m128 = other.m128;
- return *this;
- }
-
- __forceinline sseb(const __m128 input) : m128(input)
- {
- }
- __forceinline operator const __m128 &(void) const
- {
- return m128;
- }
- __forceinline operator const __m128i(void) const
- {
- return _mm_castps_si128(m128);
- }
- __forceinline operator const __m128d(void) const
- {
- return _mm_castps_pd(m128);
- }
-
- __forceinline sseb(bool a)
- : m128(_mm_lookupmask_ps[(size_t(a) << 3) | (size_t(a) << 2) | (size_t(a) << 1) | size_t(a)])
- {
- }
- __forceinline sseb(bool a, bool b)
- : m128(_mm_lookupmask_ps[(size_t(b) << 3) | (size_t(a) << 2) | (size_t(b) << 1) | size_t(a)])
- {
- }
- __forceinline sseb(bool a, bool b, bool c, bool d)
- : m128(_mm_lookupmask_ps[(size_t(d) << 3) | (size_t(c) << 2) | (size_t(b) << 1) | size_t(a)])
- {
- }
- __forceinline sseb(int mask)
- {
- assert(mask >= 0 && mask < 16);
- m128 = _mm_lookupmask_ps[mask];
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Constants
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline sseb(FalseTy) : m128(_mm_setzero_ps())
- {
- }
- __forceinline sseb(TrueTy)
- : m128(_mm_castsi128_ps(_mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128())))
- {
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Array Access
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline bool operator[](const size_t i) const
- {
- assert(i < 4);
- return (_mm_movemask_ps(m128) >> i) & 1;
- }
- __forceinline int32_t &operator[](const size_t i)
- {
- assert(i < 4);
- return v[i];
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// Unary Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const sseb operator!(const sseb &a)
-{
- return _mm_xor_ps(a, sseb(True));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Binary Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const sseb operator&(const sseb &a, const sseb &b)
-{
- return _mm_and_ps(a, b);
-}
-__forceinline const sseb operator|(const sseb &a, const sseb &b)
-{
- return _mm_or_ps(a, b);
-}
-__forceinline const sseb operator^(const sseb &a, const sseb &b)
-{
- return _mm_xor_ps(a, b);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Assignment Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const sseb operator&=(sseb &a, const sseb &b)
-{
- return a = a & b;
-}
-__forceinline const sseb operator|=(sseb &a, const sseb &b)
-{
- return a = a | b;
-}
-__forceinline const sseb operator^=(sseb &a, const sseb &b)
-{
- return a = a ^ b;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Comparison Operators + Select
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const sseb operator!=(const sseb &a, const sseb &b)
-{
- return _mm_xor_ps(a, b);
-}
-__forceinline const sseb operator==(const sseb &a, const sseb &b)
-{
- return _mm_castsi128_ps(_mm_cmpeq_epi32(a, b));
-}
-
-__forceinline const sseb select(const sseb &m, const sseb &t, const sseb &f)
-{
-# if defined(__KERNEL_SSE41__)
- return _mm_blendv_ps(f, t, m);
-# else
- return _mm_or_ps(_mm_and_ps(m, t), _mm_andnot_ps(m, f));
-# endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Movement/Shifting/Shuffling Functions
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const sseb unpacklo(const sseb &a, const sseb &b)
-{
- return _mm_unpacklo_ps(a, b);
-}
-__forceinline const sseb unpackhi(const sseb &a, const sseb &b)
-{
- return _mm_unpackhi_ps(a, b);
-}
-
-template<size_t i0, size_t i1, size_t i2, size_t i3>
-__forceinline const sseb shuffle(const sseb &a)
-{
-# ifdef __KERNEL_NEON__
- return shuffle_neon<int32x4_t, i0, i1, i2, i3>(a);
-# else
- return _mm_castsi128_ps(_mm_shuffle_epi32(a, _MM_SHUFFLE(i3, i2, i1, i0)));
-# endif
-}
-
-# ifndef __KERNEL_NEON__
-template<> __forceinline const sseb shuffle<0, 1, 0, 1>(const sseb &a)
-{
- return _mm_movelh_ps(a, a);
-}
-
-template<> __forceinline const sseb shuffle<2, 3, 2, 3>(const sseb &a)
-{
- return _mm_movehl_ps(a, a);
-}
-# endif
-
-template<size_t i0, size_t i1, size_t i2, size_t i3>
-__forceinline const sseb shuffle(const sseb &a, const sseb &b)
-{
-# ifdef __KERNEL_NEON__
- return shuffle_neon<int32x4_t, i0, i1, i2, i3>(a, b);
-# else
- return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
-# endif
-}
-
-# ifndef __KERNEL_NEON__
-template<> __forceinline const sseb shuffle<0, 1, 0, 1>(const sseb &a, const sseb &b)
-{
- return _mm_movelh_ps(a, b);
-}
-
-template<> __forceinline const sseb shuffle<2, 3, 2, 3>(const sseb &a, const sseb &b)
-{
- return _mm_movehl_ps(b, a);
-}
-# endif
-
-# if defined(__KERNEL_SSE3__) && !defined(__KERNEL_NEON__)
-template<> __forceinline const sseb shuffle<0, 0, 2, 2>(const sseb &a)
-{
- return _mm_moveldup_ps(a);
-}
-template<> __forceinline const sseb shuffle<1, 1, 3, 3>(const sseb &a)
-{
- return _mm_movehdup_ps(a);
-}
-# endif
-
-# if defined(__KERNEL_SSE41__)
-template<size_t dst, size_t src, size_t clr>
-__forceinline const sseb insert(const sseb &a, const sseb &b)
-{
-# ifdef __KERNEL_NEON__
- sseb res = a;
- if (clr)
- res[dst] = 0;
- else
- res[dst] = b[src];
- return res;
-# else
- return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr);
-# endif
-}
-template<size_t dst, size_t src> __forceinline const sseb insert(const sseb &a, const sseb &b)
-{
- return insert<dst, src, 0>(a, b);
-}
-template<size_t dst> __forceinline const sseb insert(const sseb &a, const bool b)
-{
- return insert<dst, 0>(a, sseb(b));
-}
-# endif
-
-////////////////////////////////////////////////////////////////////////////////
-/// Reduction Operations
-////////////////////////////////////////////////////////////////////////////////
-
-# if defined(__KERNEL_SSE41__)
-__forceinline uint32_t popcnt(const sseb &a)
-{
-# if defined(__KERNEL_NEON__)
- const int32x4_t mask = {1, 1, 1, 1};
- int32x4_t t = vandq_s32(vreinterpretq_s32_m128(a.m128), mask);
- return vaddvq_s32(t);
-# else
- return _mm_popcnt_u32(_mm_movemask_ps(a));
-# endif
-}
-# else
-__forceinline uint32_t popcnt(const sseb &a)
-{
- return bool(a[0]) + bool(a[1]) + bool(a[2]) + bool(a[3]);
-}
-# endif
-
-__forceinline bool reduce_and(const sseb &a)
-{
-# if defined(__KERNEL_NEON__)
- return vaddvq_s32(vreinterpretq_s32_m128(a.m128)) == -4;
-# else
- return _mm_movemask_ps(a) == 0xf;
-# endif
-}
-__forceinline bool reduce_or(const sseb &a)
-{
-# if defined(__KERNEL_NEON__)
- return vaddvq_s32(vreinterpretq_s32_m128(a.m128)) != 0x0;
-# else
- return _mm_movemask_ps(a) != 0x0;
-# endif
-}
-__forceinline bool all(const sseb &b)
-{
-# if defined(__KERNEL_NEON__)
- return vaddvq_s32(vreinterpretq_s32_m128(b.m128)) == -4;
-# else
- return _mm_movemask_ps(b) == 0xf;
-# endif
-}
-__forceinline bool any(const sseb &b)
-{
-# if defined(__KERNEL_NEON__)
- return vaddvq_s32(vreinterpretq_s32_m128(b.m128)) != 0x0;
-# else
- return _mm_movemask_ps(b) != 0x0;
-# endif
-}
-__forceinline bool none(const sseb &b)
-{
-# if defined(__KERNEL_NEON__)
- return vaddvq_s32(vreinterpretq_s32_m128(b.m128)) == 0x0;
-# else
- return _mm_movemask_ps(b) == 0x0;
-# endif
-}
-
-__forceinline uint32_t movemask(const sseb &a)
-{
- return _mm_movemask_ps(a);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Debug Functions
-////////////////////////////////////////////////////////////////////////////////
-
-ccl_device_inline void print_sseb(const char *label, const sseb &a)
-{
- printf("%s: %d %d %d %d\n", label, a[0], a[1], a[2], a[3]);
-}
-
-#endif
-
-CCL_NAMESPACE_END
-
-#endif
diff --git a/intern/cycles/util/ssef.h b/intern/cycles/util/ssef.h
deleted file mode 100644
index a2fff94303e..00000000000
--- a/intern/cycles/util/ssef.h
+++ /dev/null
@@ -1,1091 +0,0 @@
-/* SPDX-License-Identifier: Apache-2.0
- * Copyright 2011-2013 Intel Corporation
- * Modifications Copyright 2014-2022 Blender Foundation. */
-
-#ifndef __UTIL_SSEF_H__
-#define __UTIL_SSEF_H__
-
-#include "util/ssei.h"
-
-CCL_NAMESPACE_BEGIN
-
-#ifdef __KERNEL_SSE2__
-
-struct sseb;
-struct ssef;
-
-/*! 4-wide SSE float type. */
-struct ssef {
- typedef sseb Mask; // mask type
- typedef ssei Int; // int type
- typedef ssef Float; // float type
-
- enum { size = 4 }; // number of SIMD elements
- union {
- __m128 m128;
- float f[4];
- int i[4];
- }; // data
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Constructors, Assignment & Cast Operators
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline ssef()
- {
- }
- __forceinline ssef(const ssef &other)
- {
- m128 = other.m128;
- }
- __forceinline ssef &operator=(const ssef &other)
- {
- m128 = other.m128;
- return *this;
- }
-
- __forceinline ssef(const __m128 a) : m128(a)
- {
- }
- __forceinline operator const __m128 &() const
- {
- return m128;
- }
- __forceinline operator __m128 &()
- {
- return m128;
- }
-
- __forceinline ssef(float a) : m128(_mm_set1_ps(a))
- {
- }
- __forceinline ssef(float a, float b, float c, float d) : m128(_mm_setr_ps(a, b, c, d))
- {
- }
-
- __forceinline explicit ssef(const __m128i a) : m128(_mm_cvtepi32_ps(a))
- {
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Loads and Stores
- ////////////////////////////////////////////////////////////////////////////////
-
-# if defined(__KERNEL_AVX__)
- static __forceinline ssef broadcast(const void *const a)
- {
- return _mm_broadcast_ss((float *)a);
- }
-# else
- static __forceinline ssef broadcast(const void *const a)
- {
- return _mm_set1_ps(*(float *)a);
- }
-# endif
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Array Access
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline const float &operator[](const size_t i) const
- {
- assert(i < 4);
- return f[i];
- }
- __forceinline float &operator[](const size_t i)
- {
- assert(i < 4);
- return f[i];
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// Unary Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const ssef cast(const __m128i &a)
-{
- return _mm_castsi128_ps(a);
-}
-__forceinline const ssef operator+(const ssef &a)
-{
- return a;
-}
-__forceinline const ssef operator-(const ssef &a)
-{
- return _mm_xor_ps(a.m128, _mm_castsi128_ps(_mm_set1_epi32(0x80000000)));
-}
-__forceinline const ssef abs(const ssef &a)
-{
- return _mm_and_ps(a.m128, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff)));
-}
-# if defined(__KERNEL_SSE41__)
-__forceinline const ssef sign(const ssef &a)
-{
- return _mm_blendv_ps(ssef(1.0f), -ssef(1.0f), _mm_cmplt_ps(a, ssef(0.0f)));
-}
-# endif
-__forceinline const ssef signmsk(const ssef &a)
-{
- return _mm_and_ps(a.m128, _mm_castsi128_ps(_mm_set1_epi32(0x80000000)));
-}
-
-__forceinline const ssef rcp(const ssef &a)
-{
- const ssef r = _mm_rcp_ps(a.m128);
- return _mm_sub_ps(_mm_add_ps(r, r), _mm_mul_ps(_mm_mul_ps(r, r), a));
-}
-__forceinline const ssef sqr(const ssef &a)
-{
- return _mm_mul_ps(a, a);
-}
-__forceinline const ssef mm_sqrt(const ssef &a)
-{
- return _mm_sqrt_ps(a.m128);
-}
-__forceinline const ssef rsqrt(const ssef &a)
-{
- const ssef r = _mm_rsqrt_ps(a.m128);
- return _mm_add_ps(
- _mm_mul_ps(_mm_set_ps(1.5f, 1.5f, 1.5f, 1.5f), r),
- _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set_ps(-0.5f, -0.5f, -0.5f, -0.5f)), r),
- _mm_mul_ps(r, r)));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Binary Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const ssef operator+(const ssef &a, const ssef &b)
-{
- return _mm_add_ps(a.m128, b.m128);
-}
-__forceinline const ssef operator+(const ssef &a, const float &b)
-{
- return a + ssef(b);
-}
-__forceinline const ssef operator+(const float &a, const ssef &b)
-{
- return ssef(a) + b;
-}
-
-__forceinline const ssef operator-(const ssef &a, const ssef &b)
-{
- return _mm_sub_ps(a.m128, b.m128);
-}
-__forceinline const ssef operator-(const ssef &a, const float &b)
-{
- return a - ssef(b);
-}
-__forceinline const ssef operator-(const float &a, const ssef &b)
-{
- return ssef(a) - b;
-}
-
-__forceinline const ssef operator*(const ssef &a, const ssef &b)
-{
- return _mm_mul_ps(a.m128, b.m128);
-}
-__forceinline const ssef operator*(const ssef &a, const float &b)
-{
- return a * ssef(b);
-}
-__forceinline const ssef operator*(const float &a, const ssef &b)
-{
- return ssef(a) * b;
-}
-
-__forceinline const ssef operator/(const ssef &a, const ssef &b)
-{
- return _mm_div_ps(a.m128, b.m128);
-}
-__forceinline const ssef operator/(const ssef &a, const float &b)
-{
- return a / ssef(b);
-}
-__forceinline const ssef operator/(const float &a, const ssef &b)
-{
- return ssef(a) / b;
-}
-
-__forceinline const ssef operator^(const ssef &a, const ssef &b)
-{
- return _mm_xor_ps(a.m128, b.m128);
-}
-__forceinline const ssef operator^(const ssef &a, const ssei &b)
-{
- return _mm_xor_ps(a.m128, _mm_castsi128_ps(b.m128));
-}
-
-__forceinline const ssef operator&(const ssef &a, const ssef &b)
-{
- return _mm_and_ps(a.m128, b.m128);
-}
-__forceinline const ssef operator&(const ssef &a, const ssei &b)
-{
- return _mm_and_ps(a.m128, _mm_castsi128_ps(b.m128));
-}
-
-__forceinline const ssef operator|(const ssef &a, const ssef &b)
-{
- return _mm_or_ps(a.m128, b.m128);
-}
-__forceinline const ssef operator|(const ssef &a, const ssei &b)
-{
- return _mm_or_ps(a.m128, _mm_castsi128_ps(b.m128));
-}
-
-__forceinline const ssef andnot(const ssef &a, const ssef &b)
-{
- return _mm_andnot_ps(a.m128, b.m128);
-}
-
-__forceinline const ssef min(const ssef &a, const ssef &b)
-{
- return _mm_min_ps(a.m128, b.m128);
-}
-__forceinline const ssef min(const ssef &a, const float &b)
-{
- return _mm_min_ps(a.m128, ssef(b));
-}
-__forceinline const ssef min(const float &a, const ssef &b)
-{
- return _mm_min_ps(ssef(a), b.m128);
-}
-
-__forceinline const ssef max(const ssef &a, const ssef &b)
-{
- return _mm_max_ps(a.m128, b.m128);
-}
-__forceinline const ssef max(const ssef &a, const float &b)
-{
- return _mm_max_ps(a.m128, ssef(b));
-}
-__forceinline const ssef max(const float &a, const ssef &b)
-{
- return _mm_max_ps(ssef(a), b.m128);
-}
-
-# if defined(__KERNEL_SSE41__)
-__forceinline ssef mini(const ssef &a, const ssef &b)
-{
- const ssei ai = _mm_castps_si128(a);
- const ssei bi = _mm_castps_si128(b);
- const ssei ci = _mm_min_epi32(ai, bi);
- return _mm_castsi128_ps(ci);
-}
-# endif
-
-# if defined(__KERNEL_SSE41__)
-__forceinline ssef maxi(const ssef &a, const ssef &b)
-{
- const ssei ai = _mm_castps_si128(a);
- const ssei bi = _mm_castps_si128(b);
- const ssei ci = _mm_max_epi32(ai, bi);
- return _mm_castsi128_ps(ci);
-}
-# endif
-
-////////////////////////////////////////////////////////////////////////////////
-/// Ternary Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const ssef madd(const ssef &a, const ssef &b, const ssef &c)
-{
-# if defined(__KERNEL_NEON__)
- return vfmaq_f32(c, a, b);
-# elif defined(__KERNEL_AVX2__)
- return _mm_fmadd_ps(a, b, c);
-# else
- return a * b + c;
-# endif
-}
-__forceinline const ssef msub(const ssef &a, const ssef &b, const ssef &c)
-{
-# if defined(__KERNEL_NEON__)
- return vfmaq_f32(vnegq_f32(c), a, b);
-# elif defined(__KERNEL_AVX2__)
- return _mm_fmsub_ps(a, b, c);
-# else
- return a * b - c;
-# endif
-}
-__forceinline const ssef nmadd(const ssef &a, const ssef &b, const ssef &c)
-{
-# if defined(__KERNEL_NEON__)
- return vfmsq_f32(c, a, b);
-# elif defined(__KERNEL_AVX2__)
- return _mm_fnmadd_ps(a, b, c);
-# else
- return c - a * b;
-# endif
-}
-__forceinline const ssef nmsub(const ssef &a, const ssef &b, const ssef &c)
-{
-# if defined(__KERNEL_NEON__)
- return vfmsq_f32(vnegq_f32(c), a, b);
-# elif defined(__KERNEL_AVX2__)
- return _mm_fnmsub_ps(a, b, c);
-# else
- return -a * b - c;
-# endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Assignment Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline ssef &operator+=(ssef &a, const ssef &b)
-{
- return a = a + b;
-}
-__forceinline ssef &operator+=(ssef &a, const float &b)
-{
- return a = a + b;
-}
-
-__forceinline ssef &operator-=(ssef &a, const ssef &b)
-{
- return a = a - b;
-}
-__forceinline ssef &operator-=(ssef &a, const float &b)
-{
- return a = a - b;
-}
-
-__forceinline ssef &operator*=(ssef &a, const ssef &b)
-{
- return a = a * b;
-}
-__forceinline ssef &operator*=(ssef &a, const float &b)
-{
- return a = a * b;
-}
-
-__forceinline ssef &operator/=(ssef &a, const ssef &b)
-{
- return a = a / b;
-}
-__forceinline ssef &operator/=(ssef &a, const float &b)
-{
- return a = a / b;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Comparison Operators + Select
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const sseb operator==(const ssef &a, const ssef &b)
-{
- return _mm_cmpeq_ps(a.m128, b.m128);
-}
-__forceinline const sseb operator==(const ssef &a, const float &b)
-{
- return a == ssef(b);
-}
-__forceinline const sseb operator==(const float &a, const ssef &b)
-{
- return ssef(a) == b;
-}
-
-__forceinline const sseb operator!=(const ssef &a, const ssef &b)
-{
- return _mm_cmpneq_ps(a.m128, b.m128);
-}
-__forceinline const sseb operator!=(const ssef &a, const float &b)
-{
- return a != ssef(b);
-}
-__forceinline const sseb operator!=(const float &a, const ssef &b)
-{
- return ssef(a) != b;
-}
-
-__forceinline const sseb operator<(const ssef &a, const ssef &b)
-{
- return _mm_cmplt_ps(a.m128, b.m128);
-}
-__forceinline const sseb operator<(const ssef &a, const float &b)
-{
- return a < ssef(b);
-}
-__forceinline const sseb operator<(const float &a, const ssef &b)
-{
- return ssef(a) < b;
-}
-
-__forceinline const sseb operator>=(const ssef &a, const ssef &b)
-{
- return _mm_cmpnlt_ps(a.m128, b.m128);
-}
-__forceinline const sseb operator>=(const ssef &a, const float &b)
-{
- return a >= ssef(b);
-}
-__forceinline const sseb operator>=(const float &a, const ssef &b)
-{
- return ssef(a) >= b;
-}
-
-__forceinline const sseb operator>(const ssef &a, const ssef &b)
-{
- return _mm_cmpnle_ps(a.m128, b.m128);
-}
-__forceinline const sseb operator>(const ssef &a, const float &b)
-{
- return a > ssef(b);
-}
-__forceinline const sseb operator>(const float &a, const ssef &b)
-{
- return ssef(a) > b;
-}
-
-__forceinline const sseb operator<=(const ssef &a, const ssef &b)
-{
- return _mm_cmple_ps(a.m128, b.m128);
-}
-__forceinline const sseb operator<=(const ssef &a, const float &b)
-{
- return a <= ssef(b);
-}
-__forceinline const sseb operator<=(const float &a, const ssef &b)
-{
- return ssef(a) <= b;
-}
-
-__forceinline const ssef select(const sseb &m, const ssef &t, const ssef &f)
-{
-# ifdef __KERNEL_SSE41__
- return _mm_blendv_ps(f, t, m);
-# else
- return _mm_or_ps(_mm_and_ps(m, t), _mm_andnot_ps(m, f));
-# endif
-}
-
-__forceinline const ssef select(const ssef &m, const ssef &t, const ssef &f)
-{
-# ifdef __KERNEL_SSE41__
- return _mm_blendv_ps(f, t, m);
-# else
- return _mm_or_ps(_mm_and_ps(m, t), _mm_andnot_ps(m, f));
-# endif
-}
-
-__forceinline const ssef select(const int mask, const ssef &t, const ssef &f)
-{
-# if defined(__KERNEL_SSE41__) && \
- ((!defined(__clang__) && !defined(_MSC_VER)) || defined(__INTEL_COMPILER))
- return _mm_blend_ps(f, t, mask);
-# else
- return select(sseb(mask), t, f);
-# endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Rounding Functions
-////////////////////////////////////////////////////////////////////////////////
-
-# if defined(__KERNEL_SSE41__)
-__forceinline const ssef round_even(const ssef &a)
-{
-# ifdef __KERNEL_NEON__
- return vrndnq_f32(a);
-# else
- return _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT);
-# endif
-}
-__forceinline const ssef round_down(const ssef &a)
-{
-# ifdef __KERNEL_NEON__
- return vrndmq_f32(a);
-# else
- return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF);
-# endif
-}
-__forceinline const ssef round_up(const ssef &a)
-{
-# ifdef __KERNEL_NEON__
- return vrndpq_f32(a);
-# else
- return _mm_round_ps(a, _MM_FROUND_TO_POS_INF);
-# endif
-}
-__forceinline const ssef round_zero(const ssef &a)
-{
-# ifdef __KERNEL_NEON__
- return vrndq_f32(a);
-# else
- return _mm_round_ps(a, _MM_FROUND_TO_ZERO);
-# endif
-}
-__forceinline const ssef floor(const ssef &a)
-{
-# ifdef __KERNEL_NEON__
- return vrndnq_f32(a);
-# else
- return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF);
-# endif
-}
-__forceinline const ssef ceil(const ssef &a)
-{
-# ifdef __KERNEL_NEON__
- return vrndpq_f32(a);
-# else
- return _mm_round_ps(a, _MM_FROUND_TO_POS_INF);
-# endif
-}
-# endif
-
-__forceinline ssei truncatei(const ssef &a)
-{
- return _mm_cvttps_epi32(a.m128);
-}
-
-/* This is about 25% faster than straightforward floor to integer conversion
- * due to better pipelining.
- *
- * Unsaturated add 0xffffffff (a < 0) is the same as subtract -1.
- */
-__forceinline ssei floori(const ssef &a)
-{
- return truncatei(a) + cast((a < 0.0f).m128);
-}
-
-__forceinline ssef floorfrac(const ssef &x, ssei *i)
-{
- *i = floori(x);
- return x - ssef(*i);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Common Functions
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline ssef mix(const ssef &a, const ssef &b, const ssef &t)
-{
- return madd(t, b, (ssef(1.0f) - t) * a);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Movement/Shifting/Shuffling Functions
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline ssef unpacklo(const ssef &a, const ssef &b)
-{
- return _mm_unpacklo_ps(a.m128, b.m128);
-}
-__forceinline ssef unpackhi(const ssef &a, const ssef &b)
-{
- return _mm_unpackhi_ps(a.m128, b.m128);
-}
-
-template<size_t i0, size_t i1, size_t i2, size_t i3>
-__forceinline const ssef shuffle(const ssef &b)
-{
-# ifdef __KERNEL_NEON__
- return shuffle_neon<float32x4_t, i0, i1, i2, i3>(b.m128);
-# else
- return _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(b), _MM_SHUFFLE(i3, i2, i1, i0)));
-# endif
-}
-
-template<> __forceinline const ssef shuffle<0, 1, 0, 1>(const ssef &a)
-{
- return _mm_movelh_ps(a, a);
-}
-
-template<> __forceinline const ssef shuffle<2, 3, 2, 3>(const ssef &a)
-{
- return _mm_movehl_ps(a, a);
-}
-
-template<size_t i0, size_t i1, size_t i2, size_t i3>
-__forceinline const ssef shuffle(const ssef &a, const ssef &b)
-{
-# ifdef __KERNEL_NEON__
- return shuffle_neon<float32x4_t, i0, i1, i2, i3>(a, b);
-# else
- return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
-# endif
-}
-
-template<size_t i0> __forceinline const ssef shuffle(const ssef &a, const ssef &b)
-{
-# ifdef __KERNEL_NEON__
- return shuffle_neon<float32x4_t, i0, i0, i0, i0>(a, b);
-# else
- return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i0, i0, i0, i0));
-# endif
-}
-
-# ifndef __KERNEL_NEON__
-template<> __forceinline const ssef shuffle<0, 1, 0, 1>(const ssef &a, const ssef &b)
-{
- return _mm_movelh_ps(a, b);
-}
-
-template<> __forceinline const ssef shuffle<2, 3, 2, 3>(const ssef &a, const ssef &b)
-{
- return _mm_movehl_ps(b, a);
-}
-# endif
-
-# if defined(__KERNEL_SSSE3__)
-__forceinline const ssef shuffle8(const ssef &a, const ssei &shuf)
-{
- return _mm_castsi128_ps(_mm_shuffle_epi8(_mm_castps_si128(a), shuf));
-}
-# endif
-
-# if defined(__KERNEL_SSE3__)
-template<> __forceinline const ssef shuffle<0, 0, 2, 2>(const ssef &b)
-{
- return _mm_moveldup_ps(b);
-}
-template<> __forceinline const ssef shuffle<1, 1, 3, 3>(const ssef &b)
-{
- return _mm_movehdup_ps(b);
-}
-# endif
-
-template<size_t i0> __forceinline const ssef shuffle(const ssef &b)
-{
- return shuffle<i0, i0, i0, i0>(b);
-}
-
-# if defined(__KERNEL_AVX__)
-__forceinline const ssef shuffle(const ssef &a, const ssei &shuf)
-{
- return _mm_permutevar_ps(a, shuf);
-}
-# endif
-
-template<size_t i> __forceinline float extract(const ssef &a)
-{
- return _mm_cvtss_f32(shuffle<i, i, i, i>(a));
-}
-template<> __forceinline float extract<0>(const ssef &a)
-{
- return _mm_cvtss_f32(a);
-}
-
-# if defined(__KERNEL_SSE41__)
-template<size_t dst, size_t src, size_t clr>
-__forceinline const ssef insert(const ssef &a, const ssef &b)
-{
-# ifdef __KERNEL_NEON__
- ssef res = a;
- if (clr)
- res[dst] = 0;
- else
- res[dst] = b[src];
- return res;
-# else
- return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr);
-# endif
-}
-template<size_t dst, size_t src> __forceinline const ssef insert(const ssef &a, const ssef &b)
-{
- return insert<dst, src, 0>(a, b);
-}
-template<size_t dst> __forceinline const ssef insert(const ssef &a, const float b)
-{
- return insert<dst, 0>(a, _mm_set_ss(b));
-}
-# else
-template<size_t dst> __forceinline const ssef insert(const ssef &a, const float b)
-{
- ssef c = a;
- c[dst] = b;
- return c;
-}
-# endif
-
-////////////////////////////////////////////////////////////////////////////////
-/// Transpose
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline void transpose(const ssef &r0,
- const ssef &r1,
- const ssef &r2,
- const ssef &r3,
- ssef &c0,
- ssef &c1,
- ssef &c2,
- ssef &c3)
-{
- ssef l02 = unpacklo(r0, r2);
- ssef h02 = unpackhi(r0, r2);
- ssef l13 = unpacklo(r1, r3);
- ssef h13 = unpackhi(r1, r3);
- c0 = unpacklo(l02, l13);
- c1 = unpackhi(l02, l13);
- c2 = unpacklo(h02, h13);
- c3 = unpackhi(h02, h13);
-}
-
-__forceinline void transpose(
- const ssef &r0, const ssef &r1, const ssef &r2, const ssef &r3, ssef &c0, ssef &c1, ssef &c2)
-{
- ssef l02 = unpacklo(r0, r2);
- ssef h02 = unpackhi(r0, r2);
- ssef l13 = unpacklo(r1, r3);
- ssef h13 = unpackhi(r1, r3);
- c0 = unpacklo(l02, l13);
- c1 = unpackhi(l02, l13);
- c2 = unpacklo(h02, h13);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Reductions
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const ssef vreduce_min(const ssef &v)
-{
-# ifdef __KERNEL_NEON__
- return vdupq_n_f32(vminvq_f32(v));
-# else
- ssef h = min(shuffle<1, 0, 3, 2>(v), v);
- return min(shuffle<2, 3, 0, 1>(h), h);
-# endif
-}
-__forceinline const ssef vreduce_max(const ssef &v)
-{
-# ifdef __KERNEL_NEON__
- return vdupq_n_f32(vmaxvq_f32(v));
-# else
- ssef h = max(shuffle<1, 0, 3, 2>(v), v);
- return max(shuffle<2, 3, 0, 1>(h), h);
-# endif
-}
-__forceinline const ssef vreduce_add(const ssef &v)
-{
-# ifdef __KERNEL_NEON__
- return vdupq_n_f32(vaddvq_f32(v));
-# else
- ssef h = shuffle<1, 0, 3, 2>(v) + v;
- return shuffle<2, 3, 0, 1>(h) + h;
-# endif
-}
-
-__forceinline float reduce_min(const ssef &v)
-{
-# ifdef __KERNEL_NEON__
- return vminvq_f32(v);
-# else
- return _mm_cvtss_f32(vreduce_min(v));
-# endif
-}
-__forceinline float reduce_max(const ssef &v)
-{
-# ifdef __KERNEL_NEON__
- return vmaxvq_f32(v);
-# else
- return _mm_cvtss_f32(vreduce_max(v));
-# endif
-}
-__forceinline float reduce_add(const ssef &v)
-{
-# ifdef __KERNEL_NEON__
- return vaddvq_f32(v);
-# else
- return _mm_cvtss_f32(vreduce_add(v));
-# endif
-}
-
-__forceinline uint32_t select_min(const ssef &v)
-{
- return __bsf(movemask(v == vreduce_min(v)));
-}
-__forceinline uint32_t select_max(const ssef &v)
-{
- return __bsf(movemask(v == vreduce_max(v)));
-}
-
-__forceinline uint32_t select_min(const sseb &valid, const ssef &v)
-{
- const ssef a = select(valid, v, ssef(pos_inf));
- return __bsf(movemask(valid & (a == vreduce_min(a))));
-}
-__forceinline uint32_t select_max(const sseb &valid, const ssef &v)
-{
- const ssef a = select(valid, v, ssef(neg_inf));
- return __bsf(movemask(valid & (a == vreduce_max(a))));
-}
-
-__forceinline uint32_t movemask(const ssef &a)
-{
- return _mm_movemask_ps(a);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Memory load and store operations
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline ssef load4f(const float4 &a)
-{
-# ifdef __KERNEL_WITH_SSE_ALIGN__
- return _mm_load_ps(&a.x);
-# else
- return _mm_loadu_ps(&a.x);
-# endif
-}
-
-__forceinline ssef load4f(const float3 &a)
-{
-# ifdef __KERNEL_WITH_SSE_ALIGN__
- return _mm_load_ps(&a.x);
-# else
- return _mm_loadu_ps(&a.x);
-# endif
-}
-
-__forceinline ssef load4f(const void *const a)
-{
- return _mm_load_ps((float *)a);
-}
-
-__forceinline ssef load1f_first(const float a)
-{
- return _mm_set_ss(a);
-}
-
-__forceinline void store4f(void *ptr, const ssef &v)
-{
- _mm_store_ps((float *)ptr, v);
-}
-
-__forceinline ssef loadu4f(const void *const a)
-{
- return _mm_loadu_ps((float *)a);
-}
-
-__forceinline void storeu4f(void *ptr, const ssef &v)
-{
- _mm_storeu_ps((float *)ptr, v);
-}
-
-__forceinline void store4f(const sseb &mask, void *ptr, const ssef &f)
-{
-# if defined(__KERNEL_AVX__)
- _mm_maskstore_ps((float *)ptr, (__m128i)mask, f);
-# else
- *(ssef *)ptr = select(mask, f, *(ssef *)ptr);
-# endif
-}
-
-__forceinline ssef load4f_nt(void *ptr)
-{
-# if defined(__KERNEL_SSE41__)
- return _mm_castsi128_ps(_mm_stream_load_si128((__m128i *)ptr));
-# else
- return _mm_load_ps((float *)ptr);
-# endif
-}
-
-__forceinline void store4f_nt(void *ptr, const ssef &v)
-{
-# if defined(__KERNEL_SSE41__)
- _mm_stream_ps((float *)ptr, v);
-# else
- _mm_store_ps((float *)ptr, v);
-# endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Euclidean Space Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline float dot(const ssef &a, const ssef &b)
-{
- return reduce_add(a * b);
-}
-
-/* calculate shuffled cross product, useful when order of components does not matter */
-__forceinline ssef cross_zxy(const ssef &a, const ssef &b)
-{
- const ssef a0 = a;
- const ssef b0 = shuffle<1, 2, 0, 3>(b);
- const ssef a1 = shuffle<1, 2, 0, 3>(a);
- const ssef b1 = b;
- return msub(a0, b0, a1 * b1);
-}
-
-__forceinline ssef cross(const ssef &a, const ssef &b)
-{
- return shuffle<1, 2, 0, 3>(cross_zxy(a, b));
-}
-
-ccl_device_inline const ssef dot3_splat(const ssef &a, const ssef &b)
-{
-# ifdef __KERNEL_SSE41__
- return _mm_dp_ps(a.m128, b.m128, 0x7f);
-# else
- ssef t = a * b;
- return ssef(((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 ssef &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 extract<0>(
- ssef(_mm_dp_ps(a.m128, a.m128, (X << 4) | (Y << 5) | (Z << 6) | (W << 7) | 0xf)));
-# endif
-}
-
-ccl_device_inline float dot3(const ssef &a, const ssef &b)
-{
-# ifdef __KERNEL_SSE41__
- return extract<0>(ssef(_mm_dp_ps(a.m128, b.m128, 0x7f)));
-# else
- ssef t = a * b;
- return ((float *)&t)[0] + ((float *)&t)[1] + ((float *)&t)[2];
-# endif
-}
-
-ccl_device_inline const ssef len3_squared_splat(const ssef &a)
-{
- return dot3_splat(a, a);
-}
-
-ccl_device_inline float len3_squared(const ssef &a)
-{
- return dot3(a, a);
-}
-
-ccl_device_inline float len3(const ssef &a)
-{
- return extract<0>(mm_sqrt(dot3_splat(a, a)));
-}
-
-/* SSE shuffle utility functions */
-
-# ifdef __KERNEL_SSSE3__
-
-/* faster version for SSSE3 */
-typedef ssei shuffle_swap_t;
-
-ccl_device_inline shuffle_swap_t shuffle_swap_identity()
-{
- return _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
-}
-
-ccl_device_inline shuffle_swap_t shuffle_swap_swap()
-{
- return _mm_set_epi8(7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8);
-}
-
-ccl_device_inline const ssef shuffle_swap(const ssef &a, const shuffle_swap_t &shuf)
-{
- return cast(_mm_shuffle_epi8(cast(a), shuf));
-}
-
-# else
-
-/* somewhat slower version for SSE2 */
-typedef int shuffle_swap_t;
-
-ccl_device_inline shuffle_swap_t shuffle_swap_identity()
-{
- return 0;
-}
-
-ccl_device_inline shuffle_swap_t shuffle_swap_swap()
-{
- return 1;
-}
-
-ccl_device_inline const ssef shuffle_swap(const ssef &a, shuffle_swap_t shuf)
-{
- /* shuffle value must be a constant, so we need to branch */
- if (shuf)
- return shuffle<1, 0, 3, 2>(a);
- else
- return shuffle<3, 2, 1, 0>(a);
-}
-
-# endif
-
-# if defined(__KERNEL_SSE41__) && !defined(__KERNEL_NEON__)
-
-ccl_device_inline void gen_idirsplat_swap(const ssef &pn,
- const shuffle_swap_t &shuf_identity,
- const shuffle_swap_t &shuf_swap,
- const float3 &idir,
- ssef 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);
- idirsplat[1] = _mm_xor_ps(idirsplat_raw[1], pn);
- idirsplat[2] = _mm_xor_ps(idirsplat_raw[2], pn);
-
- const ssef signmask = cast(ssei(0x80000000));
- const ssef shuf_identity_f = cast(shuf_identity);
- const ssef shuf_swap_f = cast(shuf_swap);
-
- shufflexyz[0] = _mm_castps_si128(
- _mm_blendv_ps(shuf_identity_f, shuf_swap_f, _mm_and_ps(idirsplat_raw[0], signmask)));
- shufflexyz[1] = _mm_castps_si128(
- _mm_blendv_ps(shuf_identity_f, shuf_swap_f, _mm_and_ps(idirsplat_raw[1], signmask)));
- shufflexyz[2] = _mm_castps_si128(
- _mm_blendv_ps(shuf_identity_f, shuf_swap_f, _mm_and_ps(idirsplat_raw[2], signmask)));
-}
-
-# else
-
-ccl_device_inline void gen_idirsplat_swap(const ssef &pn,
- const shuffle_swap_t &shuf_identity,
- const shuffle_swap_t &shuf_swap,
- const float3 &idir,
- ssef idirsplat[3],
- shuffle_swap_t shufflexyz[3])
-{
- idirsplat[0] = ssef(idir.x) ^ pn;
- idirsplat[1] = ssef(idir.y) ^ pn;
- idirsplat[2] = ssef(idir.z) ^ pn;
-
- shufflexyz[0] = (idir.x >= 0) ? shuf_identity : shuf_swap;
- shufflexyz[1] = (idir.y >= 0) ? shuf_identity : shuf_swap;
- shufflexyz[2] = (idir.z >= 0) ? shuf_identity : shuf_swap;
-}
-
-# endif
-
-ccl_device_inline const ssef uint32_to_float(const ssei &in)
-{
- ssei a = _mm_srli_epi32(in, 16);
- ssei b = _mm_and_si128(in, _mm_set1_epi32(0x0000ffff));
- ssei c = _mm_or_si128(a, _mm_set1_epi32(0x53000000));
- ssef d = _mm_cvtepi32_ps(b);
- ssef e = _mm_sub_ps(_mm_castsi128_ps(c), _mm_castsi128_ps(_mm_set1_epi32(0x53000000)));
- return _mm_add_ps(e, d);
-}
-
-template<size_t S1, size_t S2, size_t S3, size_t S4>
-ccl_device_inline const ssef set_sign_bit(const ssef &a)
-{
- return cast(cast(a) ^ ssei(S1 << 31, S2 << 31, S3 << 31, S4 << 31));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Debug Functions
-////////////////////////////////////////////////////////////////////////////////
-
-ccl_device_inline void print_ssef(const char *label, const ssef &a)
-{
- printf(
- "%s: %.8f %.8f %.8f %.8f\n", label, (double)a[0], (double)a[1], (double)a[2], (double)a[3]);
-}
-
-#endif
-
-CCL_NAMESPACE_END
-
-#endif
diff --git a/intern/cycles/util/ssei.h b/intern/cycles/util/ssei.h
deleted file mode 100644
index 5caf44c967f..00000000000
--- a/intern/cycles/util/ssei.h
+++ /dev/null
@@ -1,633 +0,0 @@
-/* SPDX-License-Identifier: Apache-2.0
- * Copyright 2011-2013 Intel Corporation
- * Modifications Copyright 2014-2022 Blender Foundation. */
-
-#ifndef __UTIL_SSEI_H__
-#define __UTIL_SSEI_H__
-
-CCL_NAMESPACE_BEGIN
-
-#ifdef __KERNEL_SSE2__
-
-struct sseb;
-struct ssef;
-
-/*! 4-wide SSE integer type. */
-struct ssei {
- typedef sseb Mask; // mask type
- typedef ssei Int; // int type
- typedef ssef Float; // float type
-
- enum { size = 4 }; // number of SIMD elements
- union {
- __m128i m128;
- int32_t i[4];
- }; // data
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Constructors, Assignment & Cast Operators
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline ssei()
- {
- }
- __forceinline ssei(const ssei &a)
- {
- m128 = a.m128;
- }
- __forceinline ssei &operator=(const ssei &a)
- {
- m128 = a.m128;
- return *this;
- }
-
- __forceinline ssei(const __m128i a) : m128(a)
- {
- }
- __forceinline operator const __m128i &(void) const
- {
- return m128;
- }
- __forceinline operator __m128i &(void)
- {
- return m128;
- }
-
- __forceinline ssei(const int a) : m128(_mm_set1_epi32(a))
- {
- }
- __forceinline ssei(int a, int b, int c, int d) : m128(_mm_setr_epi32(a, b, c, d))
- {
- }
-
- __forceinline explicit ssei(const __m128 a) : m128(_mm_cvtps_epi32(a))
- {
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- /// Array Access
- ////////////////////////////////////////////////////////////////////////////////
-
- __forceinline const int32_t &operator[](const size_t index) const
- {
- assert(index < 4);
- return i[index];
- }
- __forceinline int32_t &operator[](const size_t index)
- {
- assert(index < 4);
- return i[index];
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// Unary Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const ssei cast(const __m128 &a)
-{
- return _mm_castps_si128(a);
-}
-__forceinline const ssei operator+(const ssei &a)
-{
- return a;
-}
-__forceinline const ssei operator-(const ssei &a)
-{
- return _mm_sub_epi32(_mm_setzero_si128(), a.m128);
-}
-# if defined(__KERNEL_SSSE3__)
-__forceinline const ssei abs(const ssei &a)
-{
- return _mm_abs_epi32(a.m128);
-}
-# endif
-
-////////////////////////////////////////////////////////////////////////////////
-/// Binary Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const ssei operator+(const ssei &a, const ssei &b)
-{
- return _mm_add_epi32(a.m128, b.m128);
-}
-__forceinline const ssei operator+(const ssei &a, const int32_t &b)
-{
- return a + ssei(b);
-}
-__forceinline const ssei operator+(const int32_t &a, const ssei &b)
-{
- return ssei(a) + b;
-}
-
-__forceinline const ssei operator-(const ssei &a, const ssei &b)
-{
- return _mm_sub_epi32(a.m128, b.m128);
-}
-__forceinline const ssei operator-(const ssei &a, const int32_t &b)
-{
- return a - ssei(b);
-}
-__forceinline const ssei operator-(const int32_t &a, const ssei &b)
-{
- return ssei(a) - b;
-}
-
-# if defined(__KERNEL_SSE41__)
-__forceinline const ssei operator*(const ssei &a, const ssei &b)
-{
- return _mm_mullo_epi32(a.m128, b.m128);
-}
-__forceinline const ssei operator*(const ssei &a, const int32_t &b)
-{
- return a * ssei(b);
-}
-__forceinline const ssei operator*(const int32_t &a, const ssei &b)
-{
- return ssei(a) * b;
-}
-# endif
-
-__forceinline const ssei operator&(const ssei &a, const ssei &b)
-{
- return _mm_and_si128(a.m128, b.m128);
-}
-__forceinline const ssei operator&(const ssei &a, const int32_t &b)
-{
- return a & ssei(b);
-}
-__forceinline const ssei operator&(const int32_t &a, const ssei &b)
-{
- return ssei(a) & b;
-}
-
-__forceinline const ssei operator|(const ssei &a, const ssei &b)
-{
- return _mm_or_si128(a.m128, b.m128);
-}
-__forceinline const ssei operator|(const ssei &a, const int32_t &b)
-{
- return a | ssei(b);
-}
-__forceinline const ssei operator|(const int32_t &a, const ssei &b)
-{
- return ssei(a) | b;
-}
-
-__forceinline const ssei operator^(const ssei &a, const ssei &b)
-{
- return _mm_xor_si128(a.m128, b.m128);
-}
-__forceinline const ssei operator^(const ssei &a, const int32_t &b)
-{
- return a ^ ssei(b);
-}
-__forceinline const ssei operator^(const int32_t &a, const ssei &b)
-{
- return ssei(a) ^ b;
-}
-
-__forceinline const ssei operator<<(const ssei &a, const int32_t &n)
-{
- return _mm_slli_epi32(a.m128, n);
-}
-__forceinline const ssei operator>>(const ssei &a, const int32_t &n)
-{
- return _mm_srai_epi32(a.m128, n);
-}
-
-__forceinline const ssei andnot(const ssei &a, const ssei &b)
-{
- return _mm_andnot_si128(a.m128, b.m128);
-}
-__forceinline const ssei andnot(const sseb &a, const ssei &b)
-{
- return _mm_andnot_si128(cast(a.m128), b.m128);
-}
-__forceinline const ssei andnot(const ssei &a, const sseb &b)
-{
- return _mm_andnot_si128(a.m128, cast(b.m128));
-}
-
-__forceinline const ssei sra(const ssei &a, const int32_t &b)
-{
- return _mm_srai_epi32(a.m128, b);
-}
-__forceinline const ssei srl(const ssei &a, const int32_t &b)
-{
- return _mm_srli_epi32(a.m128, b);
-}
-
-# if defined(__KERNEL_SSE41__)
-__forceinline const ssei min(const ssei &a, const ssei &b)
-{
- return _mm_min_epi32(a.m128, b.m128);
-}
-__forceinline const ssei min(const ssei &a, const int32_t &b)
-{
- return min(a, ssei(b));
-}
-__forceinline const ssei min(const int32_t &a, const ssei &b)
-{
- return min(ssei(a), b);
-}
-
-__forceinline const ssei max(const ssei &a, const ssei &b)
-{
- return _mm_max_epi32(a.m128, b.m128);
-}
-__forceinline const ssei max(const ssei &a, const int32_t &b)
-{
- return max(a, ssei(b));
-}
-__forceinline const ssei max(const int32_t &a, const ssei &b)
-{
- return max(ssei(a), b);
-}
-# endif
-
-////////////////////////////////////////////////////////////////////////////////
-/// Assignment Operators
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline ssei &operator+=(ssei &a, const ssei &b)
-{
- return a = a + b;
-}
-__forceinline ssei &operator+=(ssei &a, const int32_t &b)
-{
- return a = a + b;
-}
-
-__forceinline ssei &operator-=(ssei &a, const ssei &b)
-{
- return a = a - b;
-}
-__forceinline ssei &operator-=(ssei &a, const int32_t &b)
-{
- return a = a - b;
-}
-
-# if defined(__KERNEL_SSE41__)
-__forceinline ssei &operator*=(ssei &a, const ssei &b)
-{
- return a = a * b;
-}
-__forceinline ssei &operator*=(ssei &a, const int32_t &b)
-{
- return a = a * b;
-}
-# endif
-
-__forceinline ssei &operator&=(ssei &a, const ssei &b)
-{
- return a = a & b;
-}
-__forceinline ssei &operator&=(ssei &a, const int32_t &b)
-{
- return a = a & b;
-}
-
-__forceinline ssei &operator|=(ssei &a, const ssei &b)
-{
- return a = a | b;
-}
-__forceinline ssei &operator|=(ssei &a, const int32_t &b)
-{
- return a = a | b;
-}
-
-__forceinline ssei &operator^=(ssei &a, const ssei &b)
-{
- return a = a ^ b;
-}
-__forceinline ssei &operator^=(ssei &a, const int32_t &b)
-{
- return a = a ^ b;
-}
-
-__forceinline ssei &operator<<=(ssei &a, const int32_t &b)
-{
- return a = a << b;
-}
-__forceinline ssei &operator>>=(ssei &a, const int32_t &b)
-{
- return a = a >> b;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Comparison Operators + Select
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline const sseb operator==(const ssei &a, const ssei &b)
-{
- return _mm_castsi128_ps(_mm_cmpeq_epi32(a.m128, b.m128));
-}
-__forceinline const sseb operator==(const ssei &a, const int32_t &b)
-{
- return a == ssei(b);
-}
-__forceinline const sseb operator==(const int32_t &a, const ssei &b)
-{
- return ssei(a) == b;
-}
-
-__forceinline const sseb operator!=(const ssei &a, const ssei &b)
-{
- return !(a == b);
-}
-__forceinline const sseb operator!=(const ssei &a, const int32_t &b)
-{
- return a != ssei(b);
-}
-__forceinline const sseb operator!=(const int32_t &a, const ssei &b)
-{
- return ssei(a) != b;
-}
-
-__forceinline const sseb operator<(const ssei &a, const ssei &b)
-{
- return _mm_castsi128_ps(_mm_cmplt_epi32(a.m128, b.m128));
-}
-__forceinline const sseb operator<(const ssei &a, const int32_t &b)
-{
- return a < ssei(b);
-}
-__forceinline const sseb operator<(const int32_t &a, const ssei &b)
-{
- return ssei(a) < b;
-}
-
-__forceinline const sseb operator>=(const ssei &a, const ssei &b)
-{
- return !(a < b);
-}
-__forceinline const sseb operator>=(const ssei &a, const int32_t &b)
-{
- return a >= ssei(b);
-}
-__forceinline const sseb operator>=(const int32_t &a, const ssei &b)
-{
- return ssei(a) >= b;
-}
-
-__forceinline const sseb operator>(const ssei &a, const ssei &b)
-{
- return _mm_castsi128_ps(_mm_cmpgt_epi32(a.m128, b.m128));
-}
-__forceinline const sseb operator>(const ssei &a, const int32_t &b)
-{
- return a > ssei(b);
-}
-__forceinline const sseb operator>(const int32_t &a, const ssei &b)
-{
- return ssei(a) > b;
-}
-
-__forceinline const sseb operator<=(const ssei &a, const ssei &b)
-{
- return !(a > b);
-}
-__forceinline const sseb operator<=(const ssei &a, const int32_t &b)
-{
- return a <= ssei(b);
-}
-__forceinline const sseb operator<=(const int32_t &a, const ssei &b)
-{
- return ssei(a) <= b;
-}
-
-__forceinline const ssei select(const sseb &m, const ssei &t, const ssei &f)
-{
-# ifdef __KERNEL_SSE41__
- return _mm_castps_si128(_mm_blendv_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), m));
-# else
- return _mm_or_si128(_mm_and_si128(m, t), _mm_andnot_si128(m, f));
-# endif
-}
-
-__forceinline const ssei select(const int mask, const ssei &t, const ssei &f)
-{
-# if defined(__KERNEL_SSE41__) && \
- ((!defined(__clang__) && !defined(_MSC_VER)) || defined(__INTEL_COMPILER))
- return _mm_castps_si128(_mm_blend_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), mask));
-# else
- return select(sseb(mask), t, f);
-# endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Movement/Shifting/Shuffling Functions
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline ssei unpacklo(const ssei &a, const ssei &b)
-{
- return _mm_unpacklo_epi32(a, b);
-}
-__forceinline ssei unpackhi(const ssei &a, const ssei &b)
-{
- return _mm_unpackhi_epi32(a, b);
-}
-
-template<size_t i0, size_t i1, size_t i2, size_t i3>
-__forceinline const ssei shuffle(const ssei &a)
-{
-# ifdef __KERNEL_NEON__
- int32x4_t result = shuffle_neon<int32x4_t, i0, i1, i2, i3>(vreinterpretq_s32_m128i(a));
- return vreinterpretq_m128i_s32(result);
-# else
- return _mm_shuffle_epi32(a, _MM_SHUFFLE(i3, i2, i1, i0));
-# endif
-}
-
-template<size_t i0, size_t i1, size_t i2, size_t i3>
-__forceinline const ssei shuffle(const ssei &a, const ssei &b)
-{
-# ifdef __KERNEL_NEON__
- int32x4_t result = shuffle_neon<int32x4_t, i0, i1, i2, i3>(vreinterpretq_s32_m128i(a),
- vreinterpretq_s32_m128i(b));
- return vreinterpretq_m128i_s32(result);
-# else
- return _mm_castps_si128(
- _mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _MM_SHUFFLE(i3, i2, i1, i0)));
-# endif
-}
-
-template<size_t i0> __forceinline const ssei shuffle(const ssei &b)
-{
- return shuffle<i0, i0, i0, i0>(b);
-}
-
-# if defined(__KERNEL_SSE41__)
-template<size_t src> __forceinline int extract(const ssei &b)
-{
- return _mm_extract_epi32(b, src);
-}
-template<size_t dst> __forceinline const ssei insert(const ssei &a, const int32_t b)
-{
- return _mm_insert_epi32(a, b, dst);
-}
-# else
-template<size_t src> __forceinline int extract(const ssei &b)
-{
- return b[src];
-}
-template<size_t dst> __forceinline const ssei insert(const ssei &a, const int32_t b)
-{
- ssei c = a;
- c[dst] = b;
- return c;
-}
-# endif
-
-////////////////////////////////////////////////////////////////////////////////
-/// Reductions
-////////////////////////////////////////////////////////////////////////////////
-
-# if defined(__KERNEL_SSE41__)
-__forceinline const ssei vreduce_min(const ssei &v)
-{
- ssei h = min(shuffle<1, 0, 3, 2>(v), v);
- return min(shuffle<2, 3, 0, 1>(h), h);
-}
-__forceinline const ssei vreduce_max(const ssei &v)
-{
- ssei h = max(shuffle<1, 0, 3, 2>(v), v);
- return max(shuffle<2, 3, 0, 1>(h), h);
-}
-__forceinline const ssei vreduce_add(const ssei &v)
-{
- ssei h = shuffle<1, 0, 3, 2>(v) + v;
- return shuffle<2, 3, 0, 1>(h) + h;
-}
-
-__forceinline int reduce_min(const ssei &v)
-{
-# ifdef __KERNEL_NEON__
- return vminvq_s32(vreinterpretq_s32_m128i(v));
-# else
- return extract<0>(vreduce_min(v));
-# endif
-}
-__forceinline int reduce_max(const ssei &v)
-{
-# ifdef __KERNEL_NEON__
- return vmaxvq_s32(vreinterpretq_s32_m128i(v));
-# else
- return extract<0>(vreduce_max(v));
-# endif
-}
-__forceinline int reduce_add(const ssei &v)
-{
-# ifdef __KERNEL_NEON__
- return vaddvq_s32(vreinterpretq_s32_m128i(v));
-# else
- return extract<0>(vreduce_add(v));
-# endif
-}
-
-__forceinline uint32_t select_min(const ssei &v)
-{
- return __bsf(movemask(v == vreduce_min(v)));
-}
-__forceinline uint32_t select_max(const ssei &v)
-{
- return __bsf(movemask(v == vreduce_max(v)));
-}
-
-__forceinline uint32_t select_min(const sseb &valid, const ssei &v)
-{
- const ssei a = select(valid, v, ssei((int)pos_inf));
- return __bsf(movemask(valid & (a == vreduce_min(a))));
-}
-__forceinline uint32_t select_max(const sseb &valid, const ssei &v)
-{
- const ssei a = select(valid, v, ssei((int)neg_inf));
- return __bsf(movemask(valid & (a == vreduce_max(a))));
-}
-
-# else
-
-__forceinline int ssei_min(int a, int b)
-{
- return (a < b) ? a : b;
-}
-__forceinline int ssei_max(int a, int b)
-{
- return (a > b) ? a : b;
-}
-__forceinline int reduce_min(const ssei &v)
-{
- return ssei_min(ssei_min(v[0], v[1]), ssei_min(v[2], v[3]));
-}
-__forceinline int reduce_max(const ssei &v)
-{
- return ssei_max(ssei_max(v[0], v[1]), ssei_max(v[2], v[3]));
-}
-__forceinline int reduce_add(const ssei &v)
-{
- return v[0] + v[1] + v[2] + v[3];
-}
-
-# endif
-
-////////////////////////////////////////////////////////////////////////////////
-/// Memory load and store operations
-////////////////////////////////////////////////////////////////////////////////
-
-__forceinline ssei load4i(const void *const a)
-{
- return _mm_load_si128((__m128i *)a);
-}
-
-__forceinline void store4i(void *ptr, const ssei &v)
-{
- _mm_store_si128((__m128i *)ptr, v);
-}
-
-__forceinline void storeu4i(void *ptr, const ssei &v)
-{
- _mm_storeu_si128((__m128i *)ptr, v);
-}
-
-__forceinline void store4i(const sseb &mask, void *ptr, const ssei &i)
-{
-# if defined(__KERNEL_AVX__)
- _mm_maskstore_ps((float *)ptr, (__m128i)mask, _mm_castsi128_ps(i));
-# else
- *(ssei *)ptr = select(mask, i, *(ssei *)ptr);
-# endif
-}
-
-__forceinline ssei load4i_nt(void *ptr)
-{
-# if defined(__KERNEL_SSE41__)
- return _mm_stream_load_si128((__m128i *)ptr);
-# else
- return _mm_load_si128((__m128i *)ptr);
-# endif
-}
-
-__forceinline void store4i_nt(void *ptr, const ssei &v)
-{
-# if defined(__KERNEL_SSE41__)
- _mm_stream_ps((float *)ptr, _mm_castsi128_ps(v));
-# else
- _mm_store_si128((__m128i *)ptr, v);
-# endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Debug Functions
-////////////////////////////////////////////////////////////////////////////////
-
-ccl_device_inline void print_ssei(const char *label, const ssei &a)
-{
- printf("%s: %df %df %df %d\n", label, a[0], a[1], a[2], a[3]);
-}
-
-#endif
-
-CCL_NAMESPACE_END
-
-#endif
diff --git a/intern/cycles/util/transform.cpp b/intern/cycles/util/transform.cpp
index cb985c65dd8..84116262437 100644
--- a/intern/cycles/util/transform.cpp
+++ b/intern/cycles/util/transform.cpp
@@ -102,7 +102,7 @@ ProjectionTransform projection_inverse(const ProjectionTransform &tfm)
return projection_identity();
}
- memcpy(&tfmR, R, sizeof(R));
+ memcpy(&tfmR.x[0], R, sizeof(R));
return tfmR;
}
diff --git a/intern/cycles/util/transform.h b/intern/cycles/util/transform.h
index 24184dc7074..0c39901a63c 100644
--- a/intern/cycles/util/transform.h
+++ b/intern/cycles/util/transform.h
@@ -63,17 +63,16 @@ ccl_device_inline float3 transform_point(ccl_private const Transform *t, const f
{
/* TODO(sergey): Disabled for now, causes crashes in certain cases. */
#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE2__)
- ssef x, y, z, w, aa;
- aa = a.m128;
+ const float4 aa(a.m128);
- x = _mm_loadu_ps(&t->x.x);
- y = _mm_loadu_ps(&t->y.x);
- z = _mm_loadu_ps(&t->z.x);
- w = _mm_set_ps(1.0f, 0.0f, 0.0f, 0.0f);
+ float4 x(_mm_loadu_ps(&t->x.x));
+ float4 y(_mm_loadu_ps(&t->y.x));
+ float4 z(_mm_loadu_ps(&t->z.x));
+ float4 w(_mm_set_ps(1.0f, 0.0f, 0.0f, 0.0f));
- _MM_TRANSPOSE4_PS(x, y, z, w);
+ _MM_TRANSPOSE4_PS(x.m128, y.m128, z.m128, w.m128);
- ssef tmp = w;
+ float4 tmp = w;
tmp = madd(shuffle<2>(aa), z, tmp);
tmp = madd(shuffle<1>(aa), y, tmp);
tmp = madd(shuffle<0>(aa), x, tmp);
@@ -94,16 +93,16 @@ ccl_device_inline float3 transform_point(ccl_private const Transform *t, const f
ccl_device_inline float3 transform_direction(ccl_private const Transform *t, const float3 a)
{
#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE2__)
- ssef x, y, z, w, aa;
- aa = a.m128;
- x = _mm_loadu_ps(&t->x.x);
- y = _mm_loadu_ps(&t->y.x);
- z = _mm_loadu_ps(&t->z.x);
- w = _mm_setzero_ps();
+ const float4 aa(a.m128);
- _MM_TRANSPOSE4_PS(x, y, z, w);
+ float4 x(_mm_loadu_ps(&t->x.x));
+ float4 y(_mm_loadu_ps(&t->y.x));
+ float4 z(_mm_loadu_ps(&t->z.x));
+ float4 w(_mm_setzero_ps());
- ssef tmp = shuffle<2>(aa) * z;
+ _MM_TRANSPOSE4_PS(x.m128, y.m128, z.m128, w.m128);
+
+ float4 tmp = shuffle<2>(aa) * z;
tmp = madd(shuffle<1>(aa), y, tmp);
tmp = madd(shuffle<0>(aa), x, tmp);
@@ -197,14 +196,7 @@ ccl_device_inline Transform make_transform_frame(float3 N)
return make_transform(dx.x, dx.y, dx.z, 0.0f, dy.x, dy.y, dy.z, 0.0f, N.x, N.y, N.z, 0.0f);
}
-#ifndef __KERNEL_GPU__
-
-ccl_device_inline Transform transform_zero()
-{
- Transform zero = {zero_float4(), zero_float4(), zero_float4()};
- return zero;
-}
-
+#if !defined(__KERNEL_METAL__)
ccl_device_inline Transform operator*(const Transform a, const Transform b)
{
float4 c_x = make_float4(b.x.x, b.y.x, b.z.x, 0.0f);
@@ -219,6 +211,15 @@ ccl_device_inline Transform operator*(const Transform a, const Transform b)
return t;
}
+#endif
+
+#ifndef __KERNEL_GPU__
+
+ccl_device_inline Transform transform_zero()
+{
+ Transform zero = {zero_float4(), zero_float4(), zero_float4()};
+ return zero;
+}
ccl_device_inline void print_transform(const char *label, const Transform &t)
{
diff --git a/intern/cycles/util/transform_inverse.h b/intern/cycles/util/transform_inverse.h
index 07fd06c1467..2faac576d82 100644
--- a/intern/cycles/util/transform_inverse.h
+++ b/intern/cycles/util/transform_inverse.h
@@ -9,29 +9,36 @@ CCL_NAMESPACE_BEGIN
* Normally we don't use SSE41/AVX outside the kernel, but for this it's
* important to match exactly for ray tracing precision. */
-ccl_device_forceinline float3 transform_inverse_cross(const float3 a, const float3 b)
+ccl_device_forceinline float3 transform_inverse_cross(const float3 a_, const float3 b_)
{
-#ifdef __AVX2__
- const ssef sse_a = (const __m128 &)a;
- const ssef sse_b = (const __m128 &)b;
- const ssef r = shuffle<1, 2, 0, 3>(
- ssef(_mm_fmsub_ps(sse_a, shuffle<1, 2, 0, 3>(sse_b), shuffle<1, 2, 0, 3>(sse_a) * sse_b)));
+#if defined(__AVX2__) && defined(__KERNEL_SSE2__)
+ const __m128 a = (const __m128 &)a_;
+ const __m128 b = (const __m128 &)b_;
+ const __m128 a_shuffle = _mm_castsi128_ps(
+ _mm_shuffle_epi32(_mm_castps_si128(a), _MM_SHUFFLE(3, 0, 2, 1)));
+ const __m128 b_shuffle = _mm_castsi128_ps(
+ _mm_shuffle_epi32(_mm_castps_si128(b), _MM_SHUFFLE(3, 0, 2, 1)));
+ const __m128 r = _mm_castsi128_ps(
+ _mm_shuffle_epi32(_mm_castps_si128(_mm_fmsub_ps(a, b_shuffle, _mm_mul_ps(a_shuffle, b))),
+ _MM_SHUFFLE(3, 0, 2, 1)));
return (const float3 &)r;
#endif
- return cross(a, b);
+ return cross(a_, b_);
}
-ccl_device_forceinline float transform_inverse_dot(const float3 a, const float3 b)
+ccl_device_forceinline float transform_inverse_dot(const float3 a_, const float3 b_)
{
-#ifdef __SSE4_1__
- return _mm_cvtss_f32(_mm_dp_ps((const __m128 &)a, (const __m128 &)b, 0x7F));
+#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE41__)
+ const __m128 a = (const __m128 &)a_;
+ const __m128 b = (const __m128 &)b_;
+ return _mm_cvtss_f32(_mm_dp_ps(a, b, 0x7F));
#endif
- return dot(a, b);
+ return dot(a_, b_);
}
-ccl_device_inline Transform transform_inverse_impl(const Transform tfm)
+ccl_device_forceinline Transform transform_inverse_impl(const Transform tfm)
{
/* This implementation matches the one in Embree exactly, to ensure consistent
* results with the ray intersection of instances. */
diff --git a/intern/cycles/util/types.h b/intern/cycles/util/types.h
index 1ab6f76f9bc..cf7f35c4116 100644
--- a/intern/cycles/util/types.h
+++ b/intern/cycles/util/types.h
@@ -97,6 +97,7 @@ ccl_device_inline void print_float(ccl_private const char *label, const float a)
#include "util/types_int2.h"
#include "util/types_int3.h"
#include "util/types_int4.h"
+#include "util/types_int8.h"
#include "util/types_uint2.h"
#include "util/types_uint3.h"
@@ -119,6 +120,7 @@ ccl_device_inline void print_float(ccl_private const char *label, const float a)
#include "util/types_int2_impl.h"
#include "util/types_int3_impl.h"
#include "util/types_int4_impl.h"
+#include "util/types_int8_impl.h"
#include "util/types_uint2_impl.h"
#include "util/types_uint3_impl.h"
@@ -129,16 +131,4 @@ ccl_device_inline void print_float(ccl_private const char *label, const float a)
#include "util/types_float4_impl.h"
#include "util/types_float8_impl.h"
-/* SSE types. */
-#ifndef __KERNEL_GPU__
-# include "util/sseb.h"
-# include "util/ssef.h"
-# include "util/ssei.h"
-# if defined(__KERNEL_AVX__) || defined(__KERNEL_AVX2__)
-# include "util/avxb.h"
-# include "util/avxf.h"
-# include "util/avxi.h"
-# endif
-#endif
-
#endif /* __UTIL_TYPES_H__ */
diff --git a/intern/cycles/util/types_float3.h b/intern/cycles/util/types_float3.h
index 87c6b1d3654..34430945c38 100644
--- a/intern/cycles/util/types_float3.h
+++ b/intern/cycles/util/types_float3.h
@@ -10,7 +10,12 @@
CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
+# ifdef __KERNEL_ONEAPI__
+/* Define float3 as packed for oneAPI. */
+struct float3
+# else
struct ccl_try_align(16) float3
+# endif
{
# ifdef __KERNEL_GPU__
/* Compact structure for GPU. */
diff --git a/intern/cycles/util/types_float8.h b/intern/cycles/util/types_float8.h
index 29fd632f08e..121141ddfd9 100644
--- a/intern/cycles/util/types_float8.h
+++ b/intern/cycles/util/types_float8.h
@@ -11,15 +11,15 @@
CCL_NAMESPACE_BEGIN
/* float8 is a reserved type in Metal that has not been implemented. For
- * that reason this is named float8_t and not using native vector types. */
+ * that reason this is named vfloat8 and not using native vector types. */
#ifdef __KERNEL_GPU__
-struct float8_t
+struct vfloat8
#else
-struct ccl_try_align(32) float8_t
+struct ccl_try_align(32) vfloat8
#endif
{
-#ifdef __KERNEL_AVX2__
+#ifdef __KERNEL_AVX__
union {
__m256 m256;
struct {
@@ -27,18 +27,18 @@ struct ccl_try_align(32) float8_t
};
};
- __forceinline float8_t();
- __forceinline float8_t(const float8_t &a);
- __forceinline explicit float8_t(const __m256 &a);
+ __forceinline vfloat8();
+ __forceinline vfloat8(const vfloat8 &a);
+ __forceinline explicit vfloat8(const __m256 &a);
__forceinline operator const __m256 &() const;
__forceinline operator __m256 &();
- __forceinline float8_t &operator=(const float8_t &a);
+ __forceinline vfloat8 &operator=(const vfloat8 &a);
-#else /* __KERNEL_AVX2__ */
+#else /* __KERNEL_AVX__ */
float a, b, c, d, e, f, g, h;
-#endif /* __KERNEL_AVX2__ */
+#endif /* __KERNEL_AVX__ */
#ifndef __KERNEL_GPU__
__forceinline float operator[](int i) const;
@@ -46,8 +46,11 @@ struct ccl_try_align(32) float8_t
#endif
};
-ccl_device_inline float8_t make_float8_t(float f);
-ccl_device_inline float8_t
-make_float8_t(float a, float b, float c, float d, float e, float f, float g, float h);
+ccl_device_inline vfloat8 make_vfloat8(float f);
+ccl_device_inline vfloat8
+make_vfloat8(float a, float b, float c, float d, float e, float f, float g, float h);
+ccl_device_inline vfloat8 make_vfloat8(const float4 a, const float4 b);
+
+ccl_device_inline void print_vfloat8(ccl_private const char *label, const vfloat8 a);
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/types_float8_impl.h b/intern/cycles/util/types_float8_impl.h
index e8576cdaf70..9f42e0f663c 100644
--- a/intern/cycles/util/types_float8_impl.h
+++ b/intern/cycles/util/types_float8_impl.h
@@ -10,45 +10,45 @@
CCL_NAMESPACE_BEGIN
-#ifdef __KERNEL_AVX2__
-__forceinline float8_t::float8_t()
+#ifdef __KERNEL_AVX__
+__forceinline vfloat8::vfloat8()
{
}
-__forceinline float8_t::float8_t(const float8_t &f) : m256(f.m256)
+__forceinline vfloat8::vfloat8(const vfloat8 &f) : m256(f.m256)
{
}
-__forceinline float8_t::float8_t(const __m256 &f) : m256(f)
+__forceinline vfloat8::vfloat8(const __m256 &f) : m256(f)
{
}
-__forceinline float8_t::operator const __m256 &() const
+__forceinline vfloat8::operator const __m256 &() const
{
return m256;
}
-__forceinline float8_t::operator __m256 &()
+__forceinline vfloat8::operator __m256 &()
{
return m256;
}
-__forceinline float8_t &float8_t::operator=(const float8_t &f)
+__forceinline vfloat8 &vfloat8::operator=(const vfloat8 &f)
{
m256 = f.m256;
return *this;
}
-#endif /* __KERNEL_AVX2__ */
+#endif /* __KERNEL_AVX__ */
#ifndef __KERNEL_GPU__
-__forceinline float float8_t::operator[](int i) const
+__forceinline float vfloat8::operator[](int i) const
{
util_assert(i >= 0);
util_assert(i < 8);
return *(&a + i);
}
-__forceinline float &float8_t::operator[](int i)
+__forceinline float &vfloat8::operator[](int i)
{
util_assert(i >= 0);
util_assert(i < 8);
@@ -56,25 +56,50 @@ __forceinline float &float8_t::operator[](int i)
}
#endif
-ccl_device_inline float8_t make_float8_t(float f)
+ccl_device_inline vfloat8 make_vfloat8(float f)
{
-#ifdef __KERNEL_AVX2__
- float8_t r(_mm256_set1_ps(f));
+#ifdef __KERNEL_AVX__
+ vfloat8 r(_mm256_set1_ps(f));
#else
- float8_t r = {f, f, f, f, f, f, f, f};
+ vfloat8 r = {f, f, f, f, f, f, f, f};
#endif
return r;
}
-ccl_device_inline float8_t
-make_float8_t(float a, float b, float c, float d, float e, float f, float g, float h)
+ccl_device_inline vfloat8
+make_vfloat8(float a, float b, float c, float d, float e, float f, float g, float h)
{
-#ifdef __KERNEL_AVX2__
- float8_t r(_mm256_setr_ps(a, b, c, d, e, f, g, h));
+#ifdef __KERNEL_AVX__
+ vfloat8 r(_mm256_setr_ps(a, b, c, d, e, f, g, h));
#else
- float8_t r = {a, b, c, d, e, f, g, h};
+ vfloat8 r = {a, b, c, d, e, f, g, h};
#endif
return r;
}
+ccl_device_inline vfloat8 make_vfloat8(const float4 a, const float4 b)
+{
+#ifdef __KERNEL_AVX__
+ return vfloat8(_mm256_insertf128_ps(_mm256_castps128_ps256(a), b, 1));
+#else
+ return make_vfloat8(a.x, a.y, a.z, a.w, b.x, b.y, b.z, b.w);
+#endif
+}
+
+ccl_device_inline void print_vfloat8(ccl_private const char *label, const vfloat8 a)
+{
+#ifdef __KERNEL_PRINTF__
+ printf("%s: %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f\n",
+ label,
+ (double)a.a,
+ (double)a.b,
+ (double)a.c,
+ (double)a.d,
+ (double)a.e,
+ (double)a.f,
+ (double)a.g,
+ (double)a.h);
+#endif
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/types_int8.h b/intern/cycles/util/types_int8.h
new file mode 100644
index 00000000000..8643ebe96ad
--- /dev/null
+++ b/intern/cycles/util/types_int8.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#pragma once
+
+#ifndef __UTIL_TYPES_H__
+# error "Do not include this file directly, include util/types.h instead."
+#endif
+
+CCL_NAMESPACE_BEGIN
+
+struct vfloat8;
+
+#ifdef __KERNEL_GPU__
+struct vint8
+#else
+struct ccl_try_align(32) vint8
+#endif
+{
+#ifdef __KERNEL_AVX__
+ union {
+ __m256i m256;
+ struct {
+ int a, b, c, d, e, f, g, h;
+ };
+ };
+
+ __forceinline vint8();
+ __forceinline vint8(const vint8 &a);
+ __forceinline explicit vint8(const __m256i &a);
+
+ __forceinline operator const __m256i &() const;
+ __forceinline operator __m256i &();
+
+ __forceinline vint8 &operator=(const vint8 &a);
+#else /* __KERNEL_AVX__ */
+ int a, b, c, d, e, f, g, h;
+#endif /* __KERNEL_AVX__ */
+
+#ifndef __KERNEL_GPU__
+ __forceinline int operator[](int i) const;
+ __forceinline int &operator[](int i);
+#endif
+};
+
+ccl_device_inline vint8 make_vint8(int a, int b, int c, int d, int e, int f, int g, int h);
+ccl_device_inline vint8 make_vint8(int i);
+ccl_device_inline vint8 make_vint8(const vfloat8 f);
+ccl_device_inline vint8 make_vint8(const int4 a, const int4 b);
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/util/types_int8_impl.h b/intern/cycles/util/types_int8_impl.h
new file mode 100644
index 00000000000..080bcaa6a2b
--- /dev/null
+++ b/intern/cycles/util/types_int8_impl.h
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#pragma once
+
+#ifndef __UTIL_TYPES_H__
+# error "Do not include this file directly, include util/types.h instead."
+#endif
+
+CCL_NAMESPACE_BEGIN
+
+#ifdef __KERNEL_AVX__
+__forceinline vint8::vint8()
+{
+}
+
+__forceinline vint8::vint8(const vint8 &a) : m256(a.m256)
+{
+}
+
+__forceinline vint8::vint8(const __m256i &a) : m256(a)
+{
+}
+
+__forceinline vint8::operator const __m256i &() const
+{
+ return m256;
+}
+
+__forceinline vint8::operator __m256i &()
+{
+ return m256;
+}
+
+__forceinline vint8 &vint8::operator=(const vint8 &a)
+{
+ m256 = a.m256;
+ return *this;
+}
+#endif /* __KERNEL_AVX__ */
+
+#ifndef __KERNEL_GPU__
+__forceinline int vint8::operator[](int i) const
+{
+ util_assert(i >= 0);
+ util_assert(i < 8);
+ return *(&a + i);
+}
+
+__forceinline int &vint8::operator[](int i)
+{
+ util_assert(i >= 0);
+ util_assert(i < 8);
+ return *(&a + i);
+}
+#endif
+
+ccl_device_inline vint8 make_vint8(int a, int b, int c, int d, int e, int f, int g, int h)
+{
+#ifdef __KERNEL_AVX__
+ return vint8(_mm256_set_epi32(h, g, f, e, d, c, b, a));
+#else
+ return {a, b, c, d, e, f, g, h};
+#endif
+}
+
+ccl_device_inline vint8 make_vint8(int i)
+{
+#ifdef __KERNEL_AVX__
+ return vint8(_mm256_set1_epi32(i));
+#else
+ return make_vint8(i, i, i, i, i, i, i, i);
+#endif
+}
+
+ccl_device_inline vint8 make_vint8(const vfloat8 f)
+{
+#ifdef __KERNEL_AVX__
+ return vint8(_mm256_cvtps_epi32(f.m256));
+#else
+ return make_vint8(
+ (int)f.a, (int)f.b, (int)f.c, (int)f.d, (int)f.e, (int)f.f, (int)f.g, (int)f.h);
+#endif
+}
+
+ccl_device_inline vint8 make_vint8(const int4 a, const int4 b)
+{
+#ifdef __KERNEL_AVX__
+ return vint8(_mm256_insertf128_si256(_mm256_castsi128_si256(a.m128), b.m128, 1));
+#else
+ return make_vint8(a.x, a.y, a.z, a.w, b.x, b.y, b.z, b.w);
+#endif
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/util/version.h b/intern/cycles/util/version.h
index 8260dd4f55d..fb02c3eaeb7 100644
--- a/intern/cycles/util/version.h
+++ b/intern/cycles/util/version.h
@@ -9,7 +9,7 @@
CCL_NAMESPACE_BEGIN
#define CYCLES_VERSION_MAJOR 3
-#define CYCLES_VERSION_MINOR 2
+#define CYCLES_VERSION_MINOR 4
#define CYCLES_VERSION_PATCH 0
#define CYCLES_MAKE_VERSION_STRING2(a, b, c) #a "." #b "." #c
@@ -19,7 +19,7 @@ CCL_NAMESPACE_BEGIN
/* Blender libraries version compatible with this version */
-#define CYCLES_BLENDER_LIBRARIES_VERSION 3.1
+#define CYCLES_BLENDER_LIBRARIES_VERSION 3.3
CCL_NAMESPACE_END
diff --git a/intern/ffmpeg/CMakeLists.txt b/intern/ffmpeg/CMakeLists.txt
index 0de8496f3f3..4fb5df9d4cd 100644
--- a/intern/ffmpeg/CMakeLists.txt
+++ b/intern/ffmpeg/CMakeLists.txt
@@ -6,6 +6,7 @@ if(WITH_GTESTS)
tests/ffmpeg_codecs.cc
)
set(TEST_INC
+ .
)
set(TEST_INC_SYS
${FFMPEG_INCLUDE_DIRS}
diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h
index f311e04d8e0..f7d87af8bca 100644
--- a/intern/ffmpeg/ffmpeg_compat.h
+++ b/intern/ffmpeg/ffmpeg_compat.h
@@ -36,6 +36,14 @@
# define FFMPEG_INLINE static inline
#endif
+#if (LIBAVFORMAT_VERSION_MAJOR < 59)
+/* For versions older than ffmpeg 5.0, use the old channel layout variables.
+ * We intend to only keep this workaround for around two releases (3.5, 3.6).
+ * If it sticks around any longer, then we should consider refactoring this.
+ */
+# define FFMPEG_USE_OLD_CHANNEL_VARS
+#endif
+
#if (LIBAVFORMAT_VERSION_MAJOR < 58) || \
((LIBAVFORMAT_VERSION_MAJOR == 58) && (LIBAVFORMAT_VERSION_MINOR < 76))
# define FFMPEG_USE_DURATION_WORKAROUND 1
diff --git a/intern/ffmpeg/tests/ffmpeg_codecs.cc b/intern/ffmpeg/tests/ffmpeg_codecs.cc
index d0c40736884..cd06917f59b 100644
--- a/intern/ffmpeg/tests/ffmpeg_codecs.cc
+++ b/intern/ffmpeg/tests/ffmpeg_codecs.cc
@@ -3,6 +3,8 @@
#include "testing/testing.h"
extern "C" {
+#include "ffmpeg_compat.h"
+
#include <libavcodec/avcodec.h>
#include <libavutil/channel_layout.h>
#include <libavutil/log.h>
@@ -40,7 +42,11 @@ bool test_acodec(const AVCodec *codec, AVSampleFormat fmt)
if (ctx) {
ctx->sample_fmt = fmt;
ctx->sample_rate = 48000;
+#ifdef FFMPEG_USE_OLD_CHANNEL_VARS
ctx->channel_layout = AV_CH_LAYOUT_MONO;
+#else
+ av_channel_layout_from_mask(&ctx->ch_layout, AV_CH_LAYOUT_MONO);
+#endif
ctx->bit_rate = 128000;
int open = avcodec_open2(ctx, codec, NULL);
if (open >= 0) {
@@ -130,6 +136,7 @@ FFMPEG_TEST_VCODEC_ID(AV_CODEC_ID_DVVIDEO, AV_PIX_FMT_YUV420P)
FFMPEG_TEST_VCODEC_ID(AV_CODEC_ID_MPEG1VIDEO, AV_PIX_FMT_YUV420P)
FFMPEG_TEST_VCODEC_ID(AV_CODEC_ID_MPEG2VIDEO, AV_PIX_FMT_YUV420P)
FFMPEG_TEST_VCODEC_ID(AV_CODEC_ID_FLV1, AV_PIX_FMT_YUV420P)
+FFMPEG_TEST_VCODEC_ID(AV_CODEC_ID_AV1, AV_PIX_FMT_YUV420P)
/* Audio codecs */
@@ -149,6 +156,12 @@ FFMPEG_TEST_VCODEC_NAME(libx264, AV_PIX_FMT_YUV420P)
FFMPEG_TEST_VCODEC_NAME(libvpx, AV_PIX_FMT_YUV420P)
FFMPEG_TEST_VCODEC_NAME(libopenjpeg, AV_PIX_FMT_YUV420P)
FFMPEG_TEST_VCODEC_NAME(libxvid, AV_PIX_FMT_YUV420P)
+/* aom's AV1 encoder is "libaom-av1". FFMPEG_TEST_VCODEC_NAME(libaom-av1, ...)
+ * will not work because the dash will not work with the test macro. */
+TEST(ffmpeg, libaom_av1_AV_PIX_FMT_YUV420P)
+{
+ EXPECT_TRUE(test_codec_video_by_name("libaom-av1", AV_PIX_FMT_YUV420P));
+}
FFMPEG_TEST_ACODEC_NAME(libvorbis, AV_SAMPLE_FMT_FLTP)
FFMPEG_TEST_ACODEC_NAME(libopus, AV_SAMPLE_FMT_FLT)
FFMPEG_TEST_ACODEC_NAME(libmp3lame, AV_SAMPLE_FMT_FLTP)
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index aa23618ca39..ea21d831b0c 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -262,27 +262,44 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
${xkbcommon_INCLUDE_DIRS}
${wayland-cursor_INCLUDE_DIRS}
)
+ list(APPEND LIB
+ ${xkbcommon_LINK_LIBRARIES}
+ )
if(WITH_GHOST_WAYLAND_DYNLOAD)
list(APPEND INC_SYS
- ../../intern/wayland_dynload/extern
+ ../wayland_dynload/extern
)
list(APPEND LIB
bf_intern_wayland_dynload
)
add_definitions(-DWITH_GHOST_WAYLAND_DYNLOAD)
+ else()
+ list(APPEND LIB
+ ${wayland-client_LINK_LIBRARIES}
+ ${wayland-egl_LINK_LIBRARIES}
+ ${wayland-cursor_LINK_LIBRARIES}
+ )
endif()
if(WITH_GHOST_WAYLAND_DBUS)
list(APPEND INC_SYS
${dbus_INCLUDE_DIRS}
)
+ list(APPEND LIB
+ ${dbus_LINK_LIBRARIES}
+ )
endif()
if(WITH_GHOST_WAYLAND_LIBDECOR)
list(APPEND INC_SYS
${libdecor_INCLUDE_DIRS}
)
+ if(NOT WITH_GHOST_WAYLAND_DYNLOAD)
+ list(APPEND LIB
+ ${libdecor_LIBRARIES}
+ )
+ endif()
endif()
include(CheckSymbolExists)
@@ -332,16 +349,16 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
${INC_DST}
)
- if(NOT WITH_GHOST_WAYLAND_LIBDECOR)
- # `xdg-shell`.
- generate_protocol_bindings(
- "${WAYLAND_PROTOCOLS_DIR}/stable/xdg-shell/xdg-shell.xml"
- )
- # `xdg-decoration`.
- generate_protocol_bindings(
- "${WAYLAND_PROTOCOLS_DIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"
- )
- endif()
+ # Used when: LIBDECOR is not needed.
+ # `xdg-shell`.
+ generate_protocol_bindings(
+ "${WAYLAND_PROTOCOLS_DIR}/stable/xdg-shell/xdg-shell.xml"
+ )
+ # `xdg-decoration`.
+ generate_protocol_bindings(
+ "${WAYLAND_PROTOCOLS_DIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"
+ )
+ # End LIBDECOR alternative.
# `xdg-output`.
generate_protocol_bindings(
@@ -355,14 +372,22 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
generate_protocol_bindings(
"${WAYLAND_PROTOCOLS_DIR}/unstable/relative-pointer/relative-pointer-unstable-v1.xml"
)
+ # Pointer-gestures (multi-touch).
+ generate_protocol_bindings(
+ "${WAYLAND_PROTOCOLS_DIR}/unstable/pointer-gestures/pointer-gestures-unstable-v1.xml"
+ )
# Tablet.
generate_protocol_bindings(
"${WAYLAND_PROTOCOLS_DIR}/unstable/tablet/tablet-unstable-v2.xml"
)
-
- add_definitions(-DWITH_GHOST_WAYLAND)
+ # Primary-selection.
+ generate_protocol_bindings(
+ "${WAYLAND_PROTOCOLS_DIR}/unstable/primary-selection/primary-selection-unstable-v1.xml"
+ )
unset(INC_DST)
+
+ add_definitions(-DWITH_GHOST_WAYLAND)
endif()
if(WITH_INPUT_NDOF)
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 399ee67a8fa..62984c762c1 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -36,6 +36,10 @@ extern GHOST_SystemHandle GHOST_CreateSystemBackground(void);
*/
extern void GHOST_SystemInitDebug(GHOST_SystemHandle systemhandle, GHOST_Debug debug);
+#if !(defined(WIN32) || defined(__APPLE__))
+extern const char *GHOST_SystemBackend(void);
+#endif
+
/**
* Disposes the one and only system.
* \param systemhandle: The handle to the system.
@@ -158,7 +162,6 @@ extern void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle,
* \param height: The height the window.
* \param state: The state of the window when opened.
* \param is_dialog: Stay on top of parent window, no icon in taskbar, can't be minimized.
- * \param type: The type of drawing context installed in this window.
* \param glSettings: Misc OpenGL options.
* \return A handle to the new window ( == NULL if creation failed).
*/
@@ -171,7 +174,6 @@ extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
uint32_t height,
GHOST_TWindowState state,
bool is_dialog,
- GHOST_TDrawingContextType type,
GHOST_GLSettings glSettings);
/**
@@ -741,6 +743,13 @@ extern unsigned int GHOST_GetContextDefaultOpenGLFramebuffer(GHOST_ContextHandle
extern unsigned int GHOST_GetDefaultOpenGLFramebuffer(GHOST_WindowHandle windowhandle);
/**
+ * Use multi-touch gestures if supported.
+ * \param systemhandle: The handle to the system.
+ * \param use: Enable or disable.
+ */
+extern void GHOST_SetMultitouchGestures(GHOST_SystemHandle systemhandle, const bool use);
+
+/**
* Set which tablet API to use. Only affects Windows, other platforms have a single API.
* \param systemhandle: The handle to the system.
* \param api: Enum indicating which API to use.
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index aa893a66a9d..edaeca1e159 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -117,9 +117,12 @@ class GHOST_ISystem {
public:
/**
* Creates the one and only system.
+ * \param verbose: report back-ends that were attempted no back-end could be loaded.
+ * \param background: loading the system for background rendering (no visible windows).
* \return An indication of success.
*/
- static GHOST_TSuccess createSystem();
+
+ static GHOST_TSuccess createSystem(bool verbose, bool background);
static GHOST_TSuccess createSystemBackground();
/**
@@ -133,6 +136,15 @@ class GHOST_ISystem {
* \return A pointer to the system.
*/
static GHOST_ISystem *getSystem();
+ /**
+ * Return an identifier for the one and only system.
+ * \warning while it may be tempting this should never be used to check for supported features,
+ * in that case, the GHOST API should be extended to query capabilities.
+ * This is needed for X11/WAYLAND on Unix, without this - there is no convenient way for users to
+ * check if WAYLAND or XWAYLAND are in use since they are dynamically selected at startup.
+ * When dynamically switching between X11/WAYLAND is removed, this function can go too.
+ */
+ static const char *getSystemBackend();
static GHOST_TBacktraceFn getBacktraceFn();
static void setBacktraceFn(GHOST_TBacktraceFn backtrace_fn);
@@ -222,7 +234,6 @@ class GHOST_ISystem {
* \param width: The width the window.
* \param height: The height the window.
* \param state: The state of the window when opened.
- * \param type: The type of drawing context installed in this window.
* \param glSettings: Misc OpenGL settings.
* \param exclusive: Use to show the window on top and ignore others (used full-screen).
* \param is_dialog: Stay on top of parent window, no icon in taskbar, can't be minimized.
@@ -235,7 +246,6 @@ class GHOST_ISystem {
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
GHOST_GLSettings glSettings,
const bool exclusive = false,
const bool is_dialog = false,
@@ -281,7 +291,7 @@ class GHOST_ISystem {
const bool stereoVisual) = 0;
/**
- * Updates the resolution while in fullscreen mode.
+ * Updates the resolution while in full-screen mode.
* \param setting: The new setting of the display.
* \param window: Window displayed in full screen.
*
@@ -421,6 +431,12 @@ class GHOST_ISystem {
virtual GHOST_TSuccess getButtonState(GHOST_TButton mask, bool &isDown) const = 0;
/**
+ * Enable multi-touch gestures if supported.
+ * \param use: Enable or disable.
+ */
+ virtual void setMultitouchGestures(const bool use) = 0;
+
+ /**
* Set which tablet API to use. Only affects Windows, other platforms have a single API.
* \param api: Enum indicating which API to use.
*/
@@ -508,6 +524,7 @@ class GHOST_ISystem {
/** The one and only system */
static GHOST_ISystem *m_system;
+ static const char *m_system_backend_id;
/** Function to call that sets the back-trace. */
static GHOST_TBacktraceFn m_backtrace_fn;
diff --git a/intern/ghost/GHOST_Path-api.h b/intern/ghost/GHOST_Path-api.h
index d303654d3e6..42c7cc75668 100644
--- a/intern/ghost/GHOST_Path-api.h
+++ b/intern/ghost/GHOST_Path-api.h
@@ -30,13 +30,19 @@ extern GHOST_TSuccess GHOST_DisposeSystemPaths(void);
/**
* Determine the base dir in which shared resources are located. It will first try to use
* "unpack and run" path, then look for properly installed path, including versioning.
- * \return Unsigned char string pointing to system dir (eg /usr/share/blender/).
+ * \return Unsigned char string pointing to system dir (eg `/usr/share/blender/`).
+ *
+ * \note typically: `BKE_appdir_resource_path_id(BLENDER_RESOURCE_PATH_SYSTEM, false)` should be
+ * used instead of this function directly as it ensures environment variable overrides are used.
*/
extern const char *GHOST_getSystemDir(int version, const char *versionstr);
/**
* Determine the base dir in which user configuration is stored, including versioning.
* \return Unsigned char string pointing to user dir (eg ~).
+ *
+ * \note typically: `BKE_appdir_resource_path_id(BLENDER_RESOURCE_PATH_USER, false)` should be
+ * used instead of this function directly as it ensures environment variable overrides are used.
*/
extern const char *GHOST_getUserDir(int version, const char *versionstr);
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index adc45285f94..db4eeff3122 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -11,6 +11,12 @@
#ifdef WITH_CXX_GUARDEDALLOC
# include "MEM_guardedalloc.h"
+#else
+/* Convenience unsigned abbreviations (#WITH_CXX_GUARDEDALLOC defines these). */
+typedef unsigned int uint;
+typedef unsigned short ushort;
+typedef unsigned long ulong;
+typedef unsigned char uchar;
#endif
#if defined(WITH_CXX_GUARDEDALLOC) && defined(__cplusplus)
@@ -54,10 +60,6 @@ typedef struct {
int hot_spot[2];
} GHOST_CursorBitmapRef;
-typedef struct {
- int flags;
-} GHOST_GLSettings;
-
typedef enum {
GHOST_glStereoVisual = (1 << 0),
GHOST_glDebugContext = (1 << 1),
@@ -121,7 +123,8 @@ typedef enum {
GHOST_kModifierKeyRightAlt,
GHOST_kModifierKeyLeftControl,
GHOST_kModifierKeyRightControl,
- GHOST_kModifierKeyOS,
+ GHOST_kModifierKeyLeftOS,
+ GHOST_kModifierKeyRightOS,
GHOST_kModifierKeyNum
} GHOST_TModifierKey;
@@ -150,6 +153,9 @@ typedef enum {
#ifdef WIN32
GHOST_kDrawingContextTypeD3D,
#endif
+#ifdef __APPLE__
+ GHOST_kDrawingContextTypeMetal,
+#endif
} GHOST_TDrawingContextType;
typedef enum {
@@ -320,13 +326,18 @@ typedef enum {
GHOST_kKeyBackslash = 0x5C,
GHOST_kKeyAccentGrave = '`',
+#define _GHOST_KEY_MODIFIER_MIN GHOST_kKeyLeftShift
+ /* Modifiers: See #GHOST_KEY_MODIFIER_CHECK. */
GHOST_kKeyLeftShift = 0x100,
GHOST_kKeyRightShift,
GHOST_kKeyLeftControl,
GHOST_kKeyRightControl,
GHOST_kKeyLeftAlt,
GHOST_kKeyRightAlt,
- GHOST_kKeyOS, /* Command key on Apple, Windows key(s) on Windows. */
+ GHOST_kKeyLeftOS, /* Command key on Apple, Windows key(s) on Windows. */
+ GHOST_kKeyRightOS,
+#define _GHOST_KEY_MODIFIER_MAX GHOST_kKeyRightOS
+
GHOST_kKeyGrLess, /* German PC only! */
GHOST_kKeyApp, /* Also known as menu key. */
@@ -400,6 +411,12 @@ typedef enum {
GHOST_kKeyMediaLast
} GHOST_TKey;
+#define GHOST_KEY_MODIFIER_NUM ((_GHOST_KEY_MODIFIER_MAX - _GHOST_KEY_MODIFIER_MIN) + 1)
+#define GHOST_KEY_MODIFIER_TO_INDEX(key) ((unsigned int)(key)-_GHOST_KEY_MODIFIER_MIN)
+#define GHOST_KEY_MODIFIER_FROM_INDEX(key) \
+ (GHOST_TKey)(((unsigned int)(key) + _GHOST_KEY_MODIFIER_MIN))
+#define GHOST_KEY_MODIFIER_CHECK(key) (GHOST_KEY_MODIFIER_TO_INDEX(key) < GHOST_KEY_MODIFIER_NUM)
+
typedef enum {
/** Grab not set. */
GHOST_kGrabDisable = 0,
@@ -508,7 +525,7 @@ typedef struct {
} GHOST_TStringArray;
typedef enum {
- GHOST_kNotStarted,
+ GHOST_kNotStarted = 0,
GHOST_kStarting,
GHOST_kInProgress,
GHOST_kFinishing,
@@ -580,6 +597,11 @@ typedef struct {
uint32_t frequency;
} GHOST_DisplaySetting;
+typedef struct {
+ int flags;
+ GHOST_TDrawingContextType context_type;
+} GHOST_GLSettings;
+
typedef enum {
/** Axis that cursor grab will wrap. */
GHOST_kDebugDefault = (1 << 1),
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 710512881e8..0c595b27148 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -24,7 +24,7 @@
GHOST_SystemHandle GHOST_CreateSystem(void)
{
- GHOST_ISystem::createSystem();
+ GHOST_ISystem::createSystem(true, false);
GHOST_ISystem *system = GHOST_ISystem::getSystem();
return (GHOST_SystemHandle)system;
@@ -52,6 +52,13 @@ GHOST_TSuccess GHOST_DisposeSystem(GHOST_SystemHandle systemhandle)
return system->disposeSystem();
}
+#if !(defined(WIN32) || defined(__APPLE__))
+const char *GHOST_SystemBackend()
+{
+ return GHOST_ISystem::getSystemBackend();
+}
+#endif
+
void GHOST_ShowMessageBox(GHOST_SystemHandle systemhandle,
const char *title,
const char *message,
@@ -154,7 +161,6 @@ GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
uint32_t height,
GHOST_TWindowState state,
bool is_dialog,
- GHOST_TDrawingContextType type,
GHOST_GLSettings glSettings)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
@@ -165,7 +171,6 @@ GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
width,
height,
state,
- type,
glSettings,
false,
is_dialog,
@@ -722,14 +727,14 @@ GHOST_TSuccess GHOST_ReleaseOpenGLContext(GHOST_ContextHandle contexthandle)
return context->releaseDrawingContext();
}
-unsigned int GHOST_GetContextDefaultOpenGLFramebuffer(GHOST_ContextHandle contexthandle)
+uint GHOST_GetContextDefaultOpenGLFramebuffer(GHOST_ContextHandle contexthandle)
{
GHOST_IContext *context = (GHOST_IContext *)contexthandle;
return context->getDefaultFramebuffer();
}
-unsigned int GHOST_GetDefaultOpenGLFramebuffer(GHOST_WindowHandle windowhandle)
+uint GHOST_GetDefaultOpenGLFramebuffer(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
@@ -743,6 +748,12 @@ GHOST_TSuccess GHOST_InvalidateWindow(GHOST_WindowHandle windowhandle)
return window->invalidate();
}
+void GHOST_SetMultitouchGestures(GHOST_SystemHandle systemhandle, const bool use)
+{
+ GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
+ return system->setMultitouchGestures(use);
+}
+
void GHOST_SetTabletAPI(GHOST_SystemHandle systemhandle, GHOST_TTabletAPI api)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
@@ -1125,8 +1136,7 @@ void *GHOST_XrGetActionCustomdata(GHOST_XrContextHandle xr_contexthandle,
return 0;
}
-unsigned int GHOST_XrGetActionCount(GHOST_XrContextHandle xr_contexthandle,
- const char *action_set_name)
+uint GHOST_XrGetActionCount(GHOST_XrContextHandle xr_contexthandle, const char *action_set_name)
{
GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
GHOST_XrSession *xr_session = xr_context->getSession();
diff --git a/intern/ghost/intern/GHOST_Context.cpp b/intern/ghost/intern/GHOST_Context.cpp
index aa379efbc1f..17ee39d952c 100644
--- a/intern/ghost/intern/GHOST_Context.cpp
+++ b/intern/ghost/intern/GHOST_Context.cpp
@@ -100,15 +100,10 @@ bool win32_chk(bool result, const char *file, int line, const char *text)
}
# ifndef NDEBUG
- _ftprintf(stderr,
- "%s(%d):[%s] -> Win32 Error# (%lu): %s",
- file,
- line,
- text,
- (unsigned long)error,
- msg);
+ _ftprintf(
+ stderr, "%s(%d):[%s] -> Win32 Error# (%lu): %s", file, line, text, ulong(error), msg);
# else
- _ftprintf(stderr, "Win32 Error# (%lu): %s", (unsigned long)error, msg);
+ _ftprintf(stderr, "Win32 Error# (%lu): %s", ulong(error), msg);
# endif
SetLastError(NO_ERROR);
diff --git a/intern/ghost/intern/GHOST_Context.h b/intern/ghost/intern/GHOST_Context.h
index 3546fb6bbc7..04d445e7f85 100644
--- a/intern/ghost/intern/GHOST_Context.h
+++ b/intern/ghost/intern/GHOST_Context.h
@@ -36,19 +36,19 @@ class GHOST_Context : public GHOST_IContext {
* Swaps front and back buffers of a window.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess swapBuffers() = 0;
+ virtual GHOST_TSuccess swapBuffers() override = 0;
/**
* Activates the drawing context of this window.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess activateDrawingContext() = 0;
+ virtual GHOST_TSuccess activateDrawingContext() override = 0;
/**
* Release the drawing context of the calling thread.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess releaseDrawingContext() = 0;
+ virtual GHOST_TSuccess releaseDrawingContext() override = 0;
/**
* Call immediately after new to initialize. If this fails then immediately delete the object.
@@ -130,7 +130,7 @@ class GHOST_Context : public GHOST_IContext {
* Gets the OpenGL frame-buffer associated with the OpenGL context
* \return The ID of an OpenGL frame-buffer object.
*/
- virtual unsigned int getDefaultFramebuffer()
+ virtual unsigned int getDefaultFramebuffer() override
{
return 0;
}
diff --git a/intern/ghost/intern/GHOST_ContextCGL.h b/intern/ghost/intern/GHOST_ContextCGL.h
index fa6d6fc6fa0..d19fffffb43 100644
--- a/intern/ghost/intern/GHOST_ContextCGL.h
+++ b/intern/ghost/intern/GHOST_ContextCGL.h
@@ -9,8 +9,13 @@
#include "GHOST_Context.h"
+#include <Cocoa/Cocoa.h>
+#include <Metal/Metal.h>
+#include <QuartzCore/QuartzCore.h>
+
@class CAMetalLayer;
@class MTLCommandQueue;
+@class MTLDevice;
@class MTLRenderPipelineState;
@class MTLTexture;
@class NSOpenGLContext;
@@ -25,7 +30,8 @@ class GHOST_ContextCGL : public GHOST_Context {
GHOST_ContextCGL(bool stereoVisual,
NSView *metalView,
CAMetalLayer *metalLayer,
- NSOpenGLView *openglView);
+ NSOpenGLView *openglView,
+ GHOST_TDrawingContextType type);
/**
* Destructor.
@@ -36,62 +42,89 @@ class GHOST_ContextCGL : public GHOST_Context {
* Swaps front and back buffers of a window.
* \return A boolean success indicator.
*/
- GHOST_TSuccess swapBuffers();
+ GHOST_TSuccess swapBuffers() override;
/**
* Activates the drawing context of this window.
* \return A boolean success indicator.
*/
- GHOST_TSuccess activateDrawingContext();
+ GHOST_TSuccess activateDrawingContext() override;
/**
* Release the drawing context of the calling thread.
* \return A boolean success indicator.
*/
- GHOST_TSuccess releaseDrawingContext();
+ GHOST_TSuccess releaseDrawingContext() override;
- unsigned int getDefaultFramebuffer();
+ unsigned int getDefaultFramebuffer() override;
/**
* Call immediately after new to initialize. If this fails then immediately delete the object.
* \return Indication as to whether initialization has succeeded.
*/
- GHOST_TSuccess initializeDrawingContext();
+ GHOST_TSuccess initializeDrawingContext() override;
/**
* Removes references to native handles from this context and then returns
* \return GHOST_kSuccess if it is OK for the parent to release the handles and
* GHOST_kFailure if releasing the handles will interfere with sharing
*/
- GHOST_TSuccess releaseNativeHandles();
+ GHOST_TSuccess releaseNativeHandles() override;
/**
* Sets the swap interval for #swapBuffers.
* \param interval: The swap interval to use.
* \return A boolean success indicator.
*/
- GHOST_TSuccess setSwapInterval(int interval);
+ GHOST_TSuccess setSwapInterval(int interval) override;
/**
* Gets the current swap interval for #swapBuffers.
* \param intervalOut: Variable to store the swap interval if it can be read.
* \return Whether the swap interval can be read.
*/
- GHOST_TSuccess getSwapInterval(int &);
+ GHOST_TSuccess getSwapInterval(int &) override;
/**
* Updates the drawing context of this window.
* Needed whenever the window is changed.
* \return Indication of success.
*/
- GHOST_TSuccess updateDrawingContext();
+ GHOST_TSuccess updateDrawingContext() override;
+
+ /**
+ * Returns a texture that Metal code can use as a render target. The current
+ * contents of this texture will be composited on top of the frame-buffer
+ * each time `swapBuffers` is called.
+ */
+ id<MTLTexture> metalOverlayTexture();
+
+ /**
+ * Return a pointer to the Metal command queue used by this context.
+ */
+ MTLCommandQueue *metalCommandQueue();
+
+ /**
+ * Return a pointer to the Metal device associated with this context.
+ */
+ MTLDevice *metalDevice();
+
+ /**
+ * Register present callback
+ */
+ void metalRegisterPresentCallback(void (*callback)(
+ MTLRenderPassDescriptor *, id<MTLRenderPipelineState>, id<MTLTexture>, id<CAMetalDrawable>));
private:
/** Metal state */
+ /* Set this flag to `true` when rendering with Metal API for Viewport.
+ * TODO(Metal): This should be assigned to externally. */
+ bool m_useMetalForRendering = false;
NSView *m_metalView;
CAMetalLayer *m_metalLayer;
MTLCommandQueue *m_metalCmdQueue;
MTLRenderPipelineState *m_metalRenderPipeline;
+ bool m_ownsMetalDevice;
/** OpenGL state, for GPUs that don't support Metal */
NSOpenGLView *m_openGLView;
@@ -103,8 +136,30 @@ class GHOST_ContextCGL : public GHOST_Context {
unsigned int m_defaultFramebuffer;
/** The virtualized default frame-buffer's texture. */
- MTLTexture *m_defaultFramebufferMetalTexture;
-
+ /**
+ * Texture that you can render into with Metal. The texture will be
+ * composited on top of `m_defaultFramebufferMetalTexture` whenever
+ * `swapBuffers` is called.
+ */
+ static const int METAL_SWAPCHAIN_SIZE = 3;
+ struct MTLSwapchainTexture {
+ id<MTLTexture> texture;
+ unsigned int index;
+ };
+ MTLSwapchainTexture m_defaultFramebufferMetalTexture[METAL_SWAPCHAIN_SIZE];
+ unsigned int current_swapchain_index = 0;
+
+ /* Present callback.
+ * We use this such that presentation can be controlled from within the Metal
+ * Context. This is required for optimal performance and clean control flow.
+ * Also helps ensure flickering does not occur by present being dependent
+ * on existing submissions. */
+ void (*contextPresentCallback)(MTLRenderPassDescriptor *,
+ id<MTLRenderPipelineState>,
+ id<MTLTexture>,
+ id<CAMetalDrawable>);
+
+ int mtl_SwapInterval;
const bool m_debug;
/** The first created OpenGL context (for sharing display lists) */
@@ -117,4 +172,5 @@ class GHOST_ContextCGL : public GHOST_Context {
void metalInitFramebuffer();
void metalUpdateFramebuffer();
void metalSwapBuffers();
+ void initClear();
};
diff --git a/intern/ghost/intern/GHOST_ContextCGL.mm b/intern/ghost/intern/GHOST_ContextCGL.mm
index 488aa58aa59..9dad337a5d6 100644
--- a/intern/ghost/intern/GHOST_ContextCGL.mm
+++ b/intern/ghost/intern/GHOST_ContextCGL.mm
@@ -46,8 +46,10 @@ int GHOST_ContextCGL::s_sharedCount = 0;
GHOST_ContextCGL::GHOST_ContextCGL(bool stereoVisual,
NSView *metalView,
CAMetalLayer *metalLayer,
- NSOpenGLView *openGLView)
+ NSOpenGLView *openGLView,
+ GHOST_TDrawingContextType type)
: GHOST_Context(stereoVisual),
+ m_useMetalForRendering(type == GHOST_kDrawingContextTypeMetal),
m_metalView(metalView),
m_metalLayer(metalLayer),
m_metalCmdQueue(nil),
@@ -55,139 +57,277 @@ GHOST_ContextCGL::GHOST_ContextCGL(bool stereoVisual,
m_openGLView(openGLView),
m_openGLContext(nil),
m_defaultFramebuffer(0),
- m_defaultFramebufferMetalTexture(nil),
m_debug(false)
{
+ /* Initialize Metal Swap-chain. */
+ current_swapchain_index = 0;
+ for (int i = 0; i < METAL_SWAPCHAIN_SIZE; i++) {
+ m_defaultFramebufferMetalTexture[i].texture = nil;
+ m_defaultFramebufferMetalTexture[i].index = i;
+ }
if (m_metalView) {
+ m_ownsMetalDevice = false;
metalInit();
}
+ else {
+ /* Prepare offscreen GHOST Context Metal device. */
+ id<MTLDevice> metalDevice = MTLCreateSystemDefaultDevice();
+
+ if (m_debug) {
+ printf("Selected Metal Device: %s\n", [metalDevice.name UTF8String]);
+ }
+
+ m_ownsMetalDevice = true;
+ if (metalDevice) {
+ m_metalLayer = [[CAMetalLayer alloc] init];
+ [m_metalLayer setEdgeAntialiasingMask:0];
+ [m_metalLayer setMasksToBounds:NO];
+ [m_metalLayer setOpaque:YES];
+ [m_metalLayer setFramebufferOnly:YES];
+ [m_metalLayer setPresentsWithTransaction:NO];
+ [m_metalLayer removeAllAnimations];
+ [m_metalLayer setDevice:metalDevice];
+ m_metalLayer.allowsNextDrawableTimeout = NO;
+ metalInit();
+ }
+ else {
+ ghost_fatal_error_dialog(
+ "[ERROR] Failed to create Metal device for offscreen GHOST Context.\n");
+ }
+ }
+
+ /* Initialize swap-interval. */
+ mtl_SwapInterval = 60;
}
GHOST_ContextCGL::~GHOST_ContextCGL()
{
metalFree();
- if (m_openGLContext != nil) {
- if (m_openGLContext == [NSOpenGLContext currentContext]) {
- [NSOpenGLContext clearCurrentContext];
+ if (!m_useMetalForRendering) {
+#if WITH_OPENGL
+ if (m_openGLContext != nil) {
+ if (m_openGLContext == [NSOpenGLContext currentContext]) {
+ [NSOpenGLContext clearCurrentContext];
- if (m_openGLView) {
- [m_openGLView clearGLContext];
+ if (m_openGLView) {
+ [m_openGLView clearGLContext];
+ }
}
- }
- if (m_openGLContext != s_sharedOpenGLContext || s_sharedCount == 1) {
- assert(s_sharedCount > 0);
+ if (m_openGLContext != s_sharedOpenGLContext || s_sharedCount == 1) {
+ assert(s_sharedCount > 0);
- s_sharedCount--;
+ s_sharedCount--;
- if (s_sharedCount == 0)
- s_sharedOpenGLContext = nil;
+ if (s_sharedCount == 0)
+ s_sharedOpenGLContext = nil;
- [m_openGLContext release];
+ [m_openGLContext release];
+ }
+ }
+#endif
+ }
+
+ if (m_ownsMetalDevice) {
+ if (m_metalLayer) {
+ [m_metalLayer release];
+ m_metalLayer = nil;
}
}
}
GHOST_TSuccess GHOST_ContextCGL::swapBuffers()
{
- if (m_openGLContext != nil) {
- if (m_metalView) {
- metalSwapBuffers();
+ GHOST_TSuccess return_value = GHOST_kFailure;
+
+ if (!m_useMetalForRendering) {
+#if WITH_OPENGL
+ if (m_openGLContext != nil) {
+ if (m_metalView) {
+ metalSwapBuffers();
+ }
+ else if (m_openGLView) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [m_openGLContext flushBuffer];
+ [pool drain];
+ }
+ return_value = GHOST_kSuccess;
}
- else if (m_openGLView) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [m_openGLContext flushBuffer];
- [pool drain];
+ else {
+ return_value = GHOST_kFailure;
}
- return GHOST_kSuccess;
+#endif
}
else {
- return GHOST_kFailure;
+ if (m_metalView) {
+ metalSwapBuffers();
+ }
+ return_value = GHOST_kSuccess;
}
+ return return_value;
}
GHOST_TSuccess GHOST_ContextCGL::setSwapInterval(int interval)
{
- if (m_openGLContext != nil) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [m_openGLContext setValues:&interval forParameter:NSOpenGLCPSwapInterval];
- [pool drain];
- return GHOST_kSuccess;
+
+ if (!m_useMetalForRendering) {
+#if WITH_OPENGL
+ if (m_openGLContext != nil) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [m_openGLContext setValues:&interval forParameter:NSOpenGLCPSwapInterval];
+ [pool drain];
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
+#endif
}
else {
- return GHOST_kFailure;
+ mtl_SwapInterval = interval;
+ return GHOST_kSuccess;
}
}
GHOST_TSuccess GHOST_ContextCGL::getSwapInterval(int &intervalOut)
{
- if (m_openGLContext != nil) {
- GLint interval;
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ if (!m_useMetalForRendering) {
+#if WITH_OPENGL
+ if (m_openGLContext != nil) {
+ GLint interval;
- [m_openGLContext getValues:&interval forParameter:NSOpenGLCPSwapInterval];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [pool drain];
+ [m_openGLContext getValues:&interval forParameter:NSOpenGLCPSwapInterval];
- intervalOut = static_cast<int>(interval);
+ [pool drain];
- return GHOST_kSuccess;
+ intervalOut = static_cast<int>(interval);
+
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
+#endif
}
else {
- return GHOST_kFailure;
+ intervalOut = mtl_SwapInterval;
+ return GHOST_kSuccess;
}
}
GHOST_TSuccess GHOST_ContextCGL::activateDrawingContext()
{
- if (m_openGLContext != nil) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [m_openGLContext makeCurrentContext];
- [pool drain];
- return GHOST_kSuccess;
+
+ if (!m_useMetalForRendering) {
+#if WITH_OPENGL
+ if (m_openGLContext != nil) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [m_openGLContext makeCurrentContext];
+ [pool drain];
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
+#endif
}
else {
- return GHOST_kFailure;
+ return GHOST_kSuccess;
}
}
GHOST_TSuccess GHOST_ContextCGL::releaseDrawingContext()
{
- if (m_openGLContext != nil) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [NSOpenGLContext clearCurrentContext];
- [pool drain];
- return GHOST_kSuccess;
+
+ if (!m_useMetalForRendering) {
+#if WITH_OPENGL
+ if (m_openGLContext != nil) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [NSOpenGLContext clearCurrentContext];
+ [pool drain];
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
+#endif
}
else {
- return GHOST_kFailure;
+ return GHOST_kSuccess;
}
}
unsigned int GHOST_ContextCGL::getDefaultFramebuffer()
{
- return m_defaultFramebuffer;
+
+ if (!m_useMetalForRendering) {
+ return m_defaultFramebuffer;
+ }
+ /* NOTE(Metal): This is not valid. */
+ return 0;
}
GHOST_TSuccess GHOST_ContextCGL::updateDrawingContext()
{
- if (m_openGLContext != nil) {
- if (m_metalView) {
- metalUpdateFramebuffer();
+
+ if (!m_useMetalForRendering) {
+#if WITH_OPENGL
+ if (m_openGLContext != nil) {
+ if (m_metalView) {
+ metalUpdateFramebuffer();
+ }
+ else if (m_openGLView) {
+ @autoreleasepool {
+ [m_openGLContext update];
+ }
+ }
+
+ return GHOST_kSuccess;
}
- else if (m_openGLView) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [m_openGLContext update];
- [pool drain];
+ else {
+ return GHOST_kFailure;
}
-
- return GHOST_kSuccess;
+#endif
}
else {
- return GHOST_kFailure;
+ if (m_metalView) {
+ metalUpdateFramebuffer();
+ return GHOST_kSuccess;
+ }
}
+ return GHOST_kFailure;
+}
+
+id<MTLTexture> GHOST_ContextCGL::metalOverlayTexture()
+{
+ /* Increment Swap-chain - Only needed if context is requesting a new texture */
+ current_swapchain_index = (current_swapchain_index + 1) % METAL_SWAPCHAIN_SIZE;
+
+ /* Ensure backing texture is ready for current swapchain index */
+ updateDrawingContext();
+
+ /* Return texture. */
+ return m_defaultFramebufferMetalTexture[current_swapchain_index].texture;
+}
+
+MTLCommandQueue *GHOST_ContextCGL::metalCommandQueue()
+{
+ return m_metalCmdQueue;
+}
+MTLDevice *GHOST_ContextCGL::metalDevice()
+{
+ id<MTLDevice> device = m_metalLayer.device;
+ return (MTLDevice *)device;
+}
+
+void GHOST_ContextCGL::metalRegisterPresentCallback(void (*callback)(
+ MTLRenderPassDescriptor *, id<MTLRenderPipelineState>, id<MTLTexture>, id<CAMetalDrawable>))
+{
+ this->contextPresentCallback = callback;
}
static void makeAttribList(std::vector<NSOpenGLPixelFormatAttribute> &attribs,
@@ -241,120 +381,134 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext()
#endif
/* Command-line argument would be better. */
- static bool softwareGL = getenv("BLENDER_SOFTWAREGL");
-
- NSOpenGLPixelFormat *pixelFormat = nil;
- std::vector<NSOpenGLPixelFormatAttribute> attribs;
- bool increasedSamplerLimit = false;
-
- /* Attempt to initialize device with increased sampler limit.
- * If this is unsupported and initialization fails, initialize GL Context as normal.
- *
- * NOTE: This is not available when using the SoftwareGL path, or for Intel-based
- * platforms. */
- if (!softwareGL) {
- if (@available(macos 11.0, *)) {
- increasedSamplerLimit = true;
+ if (!m_useMetalForRendering) {
+#if WITH_OPENGL
+ /* Command-line argument would be better. */
+ static bool softwareGL = getenv("BLENDER_SOFTWAREGL");
+
+ NSOpenGLPixelFormat *pixelFormat = nil;
+ std::vector<NSOpenGLPixelFormatAttribute> attribs;
+ bool increasedSamplerLimit = false;
+
+ /* Attempt to initialize device with increased sampler limit.
+ * If this is unsupported and initialization fails, initialize GL Context as normal.
+ *
+ * NOTE: This is not available when using the SoftwareGL path, or for Intel-based
+ * platforms. */
+ if (!softwareGL) {
+ if (@available(macos 11.0, *)) {
+ increasedSamplerLimit = true;
+ }
}
- }
- const int max_ctx_attempts = increasedSamplerLimit ? 2 : 1;
- for (int ctx_create_attempt = 0; ctx_create_attempt < max_ctx_attempts; ctx_create_attempt++) {
-
- attribs.clear();
- attribs.reserve(40);
- makeAttribList(attribs, m_stereoVisual, needAlpha, softwareGL, increasedSamplerLimit);
+ const int max_ctx_attempts = increasedSamplerLimit ? 2 : 1;
+ for (int ctx_create_attempt = 0; ctx_create_attempt < max_ctx_attempts;
+ ctx_create_attempt++) {
+
+ attribs.clear();
+ attribs.reserve(40);
+ makeAttribList(attribs, m_stereoVisual, needAlpha, softwareGL, increasedSamplerLimit);
+
+ pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
+ if (pixelFormat == nil) {
+ /* If pixel format creation fails when testing increased sampler limit,
+ * attempt initialization again with feature disabled, otherwise, fail. */
+ if (increasedSamplerLimit) {
+ increasedSamplerLimit = false;
+ continue;
+ }
+ return GHOST_kFailure;
+ }
- pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
- if (pixelFormat == nil) {
- /* If pixel format creation fails when testing increased sampler limit,
- * attempt initialization again with feature disabled, otherwise, fail. */
- if (increasedSamplerLimit) {
- increasedSamplerLimit = false;
- continue;
+ /* Attempt to create context. */
+ m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
+ shareContext:s_sharedOpenGLContext];
+ [pixelFormat release];
+
+ if (m_openGLContext == nil) {
+ /* If context creation fails when testing increased sampler limit,
+ * attempt re-creation with feature disabled. Otherwise, error. */
+ if (increasedSamplerLimit) {
+ increasedSamplerLimit = false;
+ continue;
+ }
+
+ /* Default context creation attempt failed. */
+ return GHOST_kFailure;
}
- return GHOST_kFailure;
- }
- /* Attempt to create context. */
- m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
- shareContext:s_sharedOpenGLContext];
- [pixelFormat release];
+ /* Created GL context successfully, activate. */
+ [m_openGLContext makeCurrentContext];
- if (m_openGLContext == nil) {
- /* If context creation fails when testing increased sampler limit,
- * attempt re-creation with feature disabled. Otherwise, error. */
+ /* When increasing sampler limit, verify created context is a supported configuration. */
if (increasedSamplerLimit) {
- increasedSamplerLimit = false;
- continue;
+ const char *vendor = (const char *)glGetString(GL_VENDOR);
+ const char *renderer = (const char *)glGetString(GL_RENDERER);
+
+ /* If generated context type is unsupported, release existing context and
+ * fallback to creating a normal context below. */
+ if (strstr(vendor, "Intel") || strstr(renderer, "Software")) {
+ [m_openGLContext release];
+ m_openGLContext = nil;
+ increasedSamplerLimit = false;
+ continue;
+ }
}
-
- /* Default context creation attempt failed. */
- return GHOST_kFailure;
}
- /* Created GL context successfully, activate. */
- [m_openGLContext makeCurrentContext];
+ if (m_debug) {
+ GLint major = 0, minor = 0;
+ glGetIntegerv(GL_MAJOR_VERSION, &major);
+ glGetIntegerv(GL_MINOR_VERSION, &minor);
+ fprintf(stderr, "OpenGL version %d.%d%s\n", major, minor, softwareGL ? " (software)" : "");
+ fprintf(stderr, "Renderer: %s\n", glGetString(GL_RENDERER));
+ }
- /* When increasing sampler limit, verify created context is a supported configuration. */
- if (increasedSamplerLimit) {
- const char *vendor = (const char *)glGetString(GL_VENDOR);
- const char *renderer = (const char *)glGetString(GL_RENDERER);
-
- /* If generated context type is unsupported, release existing context and
- * fallback to creating a normal context below. */
- if (strstr(vendor, "Intel") || strstr(renderer, "Software")) {
- [m_openGLContext release];
- m_openGLContext = nil;
- increasedSamplerLimit = false;
- continue;
+# ifdef GHOST_WAIT_FOR_VSYNC
+ {
+ GLint swapInt = 1;
+ /* Wait for vertical-sync, to avoid tearing artifacts. */
+ [m_openGLContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
+ }
+# endif
+
+ if (m_metalView) {
+ if (m_defaultFramebuffer == 0) {
+ /* Create a virtual frame-buffer. */
+ [m_openGLContext makeCurrentContext];
+ metalInitFramebuffer();
+ initClearGL();
}
}
- }
+ else if (m_openGLView) {
+ [m_openGLView setOpenGLContext:m_openGLContext];
+ [m_openGLContext setView:m_openGLView];
+ initClearGL();
+ }
- if (m_debug) {
- GLint major = 0, minor = 0;
- glGetIntegerv(GL_MAJOR_VERSION, &major);
- glGetIntegerv(GL_MINOR_VERSION, &minor);
- fprintf(stderr, "OpenGL version %d.%d%s\n", major, minor, softwareGL ? " (software)" : "");
- fprintf(stderr, "Renderer: %s\n", glGetString(GL_RENDERER));
- }
+ [m_openGLContext flushBuffer];
-#ifdef GHOST_WAIT_FOR_VSYNC
- {
- GLint swapInt = 1;
- /* Wait for vertical-sync, to avoid tearing artifacts. */
- [m_openGLContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
- }
-#endif
+ if (s_sharedCount == 0)
+ s_sharedOpenGLContext = m_openGLContext;
- if (m_metalView) {
- if (m_defaultFramebuffer == 0) {
- /* Create a virtual frame-buffer. */
- [m_openGLContext makeCurrentContext];
+ s_sharedCount++;
+#endif
+ }
+ else {
+ /* NOTE(Metal): Metal-only path. */
+ if (m_metalView) {
metalInitFramebuffer();
- initClearGL();
}
}
- else if (m_openGLView) {
- [m_openGLView setOpenGLContext:m_openGLContext];
- [m_openGLContext setView:m_openGLView];
- initClearGL();
- }
-
- [m_openGLContext flushBuffer];
-
- if (s_sharedCount == 0)
- s_sharedOpenGLContext = m_openGLContext;
-
- s_sharedCount++;
}
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_ContextCGL::releaseNativeHandles()
{
+#if WITH_OPENGL
m_openGLContext = nil;
m_openGLView = nil;
+#endif
m_metalView = nil;
return GHOST_kSuccess;
@@ -404,10 +558,14 @@ void GHOST_ContextCGL::metalInit()
fragment float4 fragment_shader(Vertex v [[stage_in]],
texture2d<float> t [[texture(0)]]) {
- return t.sample(s, v.texCoord);
- }
- )msl";
+ /* Final blit should ensure alpha is 1.0. This resolves
+ * rendering artifacts for blitting of final backbuffer. */
+ float4 out_tex = t.sample(s, v.texCoord);
+ out_tex.a = 1.0;
+ return out_tex;
+ }
+ )msl";
MTLCompileOptions *options = [[[MTLCompileOptions alloc] init] autorelease];
options.languageVersion = MTLLanguageVersion1_1;
@@ -424,6 +582,8 @@ void GHOST_ContextCGL::metalInit()
desc.fragmentFunction = [library newFunctionWithName:@"fragment_shader"];
desc.vertexFunction = [library newFunctionWithName:@"vertex_shader"];
+ /* Ensure library is released. */
+ [library autorelease];
[desc.colorAttachments objectAtIndexedSubscript:0].pixelFormat = METAL_FRAMEBUFFERPIXEL_FORMAT;
@@ -434,6 +594,20 @@ void GHOST_ContextCGL::metalInit()
ghost_fatal_error_dialog(
"GHOST_ContextCGL::metalInit: newRenderPipelineStateWithDescriptor:error: failed!");
}
+
+ /* Create a render pipeline to composite things rendered with Metal on top
+ * of the frame-buffer contents. Uses the same vertex and fragment shader
+ * as the blit above, but with alpha blending enabled. */
+ desc.label = @"Metal Overlay";
+ desc.colorAttachments[0].blendingEnabled = YES;
+ desc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
+ desc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
+
+ if (error) {
+ ghost_fatal_error_dialog(
+ "GHOST_ContextCGL::metalInit: newRenderPipelineStateWithDescriptor:error: failed (when "
+ "creating the Metal overlay pipeline)!");
+ }
}
}
@@ -445,123 +619,206 @@ void GHOST_ContextCGL::metalFree()
if (m_metalRenderPipeline) {
[m_metalRenderPipeline release];
}
- if (m_defaultFramebufferMetalTexture) {
- [m_defaultFramebufferMetalTexture release];
+
+ for (int i = 0; i < METAL_SWAPCHAIN_SIZE; i++) {
+ if (m_defaultFramebufferMetalTexture[i].texture) {
+ [m_defaultFramebufferMetalTexture[i].texture release];
+ }
}
}
void GHOST_ContextCGL::metalInitFramebuffer()
{
- glGenFramebuffers(1, &m_defaultFramebuffer);
+ if (!m_useMetalForRendering) {
+#if WITH_OPENGL
+ glGenFramebuffers(1, &m_defaultFramebuffer);
+#endif
+ }
updateDrawingContext();
- glBindFramebuffer(GL_FRAMEBUFFER, m_defaultFramebuffer);
+
+ if (!m_useMetalForRendering) {
+#if WITH_OPENGL
+ glBindFramebuffer(GL_FRAMEBUFFER, m_defaultFramebuffer);
+#endif
+ }
}
void GHOST_ContextCGL::metalUpdateFramebuffer()
{
- assert(m_defaultFramebuffer != 0);
+ if (!m_useMetalForRendering) {
+#if WITH_OPENGL
+ assert(m_defaultFramebuffer != 0);
+#endif
+ }
NSRect bounds = [m_metalView bounds];
NSSize backingSize = [m_metalView convertSizeToBacking:bounds.size];
size_t width = (size_t)backingSize.width;
size_t height = (size_t)backingSize.height;
- {
- /* Test if there is anything to update */
- id<MTLTexture> tex = (id<MTLTexture>)m_defaultFramebufferMetalTexture;
- if (tex && tex.width == width && tex.height == height) {
- return;
+#if WITH_OPENGL
+ unsigned int glTex;
+ CVPixelBufferRef cvPixelBuffer = nil;
+ CVOpenGLTextureCacheRef cvGLTexCache = nil;
+ CVOpenGLTextureRef cvGLTex = nil;
+ CVMetalTextureCacheRef cvMetalTexCache = nil;
+ CVMetalTextureRef cvMetalTex = nil;
+#endif
+
+ if (!m_useMetalForRendering) {
+#if WITH_OPENGL
+ /* OPENGL path */
+ {
+ /* Test if there is anything to update */
+ id<MTLTexture> tex = m_defaultFramebufferMetalTexture[current_swapchain_index].texture;
+ if (tex && tex.width == width && tex.height == height) {
+ return;
+ }
}
- }
- activateDrawingContext();
+ activateDrawingContext();
+
+ NSDictionary *cvPixelBufferProps = @{
+ (__bridge NSString *)kCVPixelBufferOpenGLCompatibilityKey : @YES,
+ (__bridge NSString *)kCVPixelBufferMetalCompatibilityKey : @YES,
+ };
+ CVReturn cvret = CVPixelBufferCreate(kCFAllocatorDefault,
+ width,
+ height,
+ METAL_CORE_VIDEO_PIXEL_FORMAT,
+ (__bridge CFDictionaryRef)cvPixelBufferProps,
+ &cvPixelBuffer);
+ if (cvret != kCVReturnSuccess) {
+ ghost_fatal_error_dialog(
+ "GHOST_ContextCGL::metalUpdateFramebuffer: CVPixelBufferCreate failed!");
+ }
- NSDictionary *cvPixelBufferProps = @{
- (__bridge NSString *)kCVPixelBufferOpenGLCompatibilityKey : @YES,
- (__bridge NSString *)kCVPixelBufferMetalCompatibilityKey : @YES,
- };
- CVPixelBufferRef cvPixelBuffer = nil;
- CVReturn cvret = CVPixelBufferCreate(kCFAllocatorDefault,
- width,
- height,
- METAL_CORE_VIDEO_PIXEL_FORMAT,
- (__bridge CFDictionaryRef)cvPixelBufferProps,
- &cvPixelBuffer);
- if (cvret != kCVReturnSuccess) {
- ghost_fatal_error_dialog(
- "GHOST_ContextCGL::metalUpdateFramebuffer: CVPixelBufferCreate failed!");
- }
-
- /* Create an OpenGL texture. */
- CVOpenGLTextureCacheRef cvGLTexCache = nil;
- cvret = CVOpenGLTextureCacheCreate(kCFAllocatorDefault,
- nil,
- m_openGLContext.CGLContextObj,
- m_openGLContext.pixelFormat.CGLPixelFormatObj,
- nil,
- &cvGLTexCache);
- if (cvret != kCVReturnSuccess) {
- ghost_fatal_error_dialog(
- "GHOST_ContextCGL::metalUpdateFramebuffer: CVOpenGLTextureCacheCreate failed!");
- }
+ /* Create an OpenGL texture. */
+ cvret = CVOpenGLTextureCacheCreate(kCFAllocatorDefault,
+ nil,
+ m_openGLContext.CGLContextObj,
+ m_openGLContext.pixelFormat.CGLPixelFormatObj,
+ nil,
+ &cvGLTexCache);
+ if (cvret != kCVReturnSuccess) {
+ ghost_fatal_error_dialog(
+ "GHOST_ContextCGL::metalUpdateFramebuffer: CVOpenGLTextureCacheCreate failed!");
+ }
- CVOpenGLTextureRef cvGLTex = nil;
- cvret = CVOpenGLTextureCacheCreateTextureFromImage(
- kCFAllocatorDefault, cvGLTexCache, cvPixelBuffer, nil, &cvGLTex);
- if (cvret != kCVReturnSuccess) {
- ghost_fatal_error_dialog(
- "GHOST_ContextCGL::metalUpdateFramebuffer: "
- "CVOpenGLTextureCacheCreateTextureFromImage failed!");
- }
+ cvret = CVOpenGLTextureCacheCreateTextureFromImage(
+ kCFAllocatorDefault, cvGLTexCache, cvPixelBuffer, nil, &cvGLTex);
+ if (cvret != kCVReturnSuccess) {
+ ghost_fatal_error_dialog(
+ "GHOST_ContextCGL::metalUpdateFramebuffer: "
+ "CVOpenGLTextureCacheCreateTextureFromImage failed!");
+ }
- unsigned int glTex;
- glTex = CVOpenGLTextureGetName(cvGLTex);
+ glTex = CVOpenGLTextureGetName(cvGLTex);
- /* Create a Metal texture. */
- CVMetalTextureCacheRef cvMetalTexCache = nil;
- cvret = CVMetalTextureCacheCreate(
- kCFAllocatorDefault, nil, m_metalLayer.device, nil, &cvMetalTexCache);
- if (cvret != kCVReturnSuccess) {
- ghost_fatal_error_dialog(
- "GHOST_ContextCGL::metalUpdateFramebuffer: CVMetalTextureCacheCreate failed!");
- }
+ /* Create a Metal texture. */
+ cvret = CVMetalTextureCacheCreate(
+ kCFAllocatorDefault, nil, m_metalLayer.device, nil, &cvMetalTexCache);
+ if (cvret != kCVReturnSuccess) {
+ ghost_fatal_error_dialog(
+ "GHOST_ContextCGL::metalUpdateFramebuffer: CVMetalTextureCacheCreate failed!");
+ }
- CVMetalTextureRef cvMetalTex = nil;
- cvret = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
- cvMetalTexCache,
- cvPixelBuffer,
- nil,
- METAL_FRAMEBUFFERPIXEL_FORMAT,
- width,
- height,
- 0,
- &cvMetalTex);
- if (cvret != kCVReturnSuccess) {
- ghost_fatal_error_dialog(
- "GHOST_ContextCGL::metalUpdateFramebuffer: "
- "CVMetalTextureCacheCreateTextureFromImage failed!");
- }
+ cvret = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
+ cvMetalTexCache,
+ cvPixelBuffer,
+ nil,
+ METAL_FRAMEBUFFERPIXEL_FORMAT,
+ width,
+ height,
+ 0,
+ &cvMetalTex);
+ if (cvret != kCVReturnSuccess) {
+ ghost_fatal_error_dialog(
+ "GHOST_ContextCGL::metalUpdateFramebuffer: "
+ "CVMetalTextureCacheCreateTextureFromImage failed!");
+ }
- MTLTexture *tex = (MTLTexture *)CVMetalTextureGetTexture(cvMetalTex);
+ id<MTLTexture> tex = CVMetalTextureGetTexture(cvMetalTex);
- if (!tex) {
- ghost_fatal_error_dialog(
- "GHOST_ContextCGL::metalUpdateFramebuffer: CVMetalTextureGetTexture failed!");
+ if (!tex) {
+ ghost_fatal_error_dialog(
+ "GHOST_ContextCGL::metalUpdateFramebuffer: CVMetalTextureGetTexture failed!");
+ }
+
+ [m_defaultFramebufferMetalTexture[current_swapchain_index].texture release];
+ m_defaultFramebufferMetalTexture[current_swapchain_index].texture = [tex retain];
+#endif
}
+ else {
+ /* NOTE(Metal): Metal API Path. */
+ if (m_defaultFramebufferMetalTexture[current_swapchain_index].texture &&
+ m_defaultFramebufferMetalTexture[current_swapchain_index].texture.width == width &&
+ m_defaultFramebufferMetalTexture[current_swapchain_index].texture.height == height) {
+ return;
+ }
- [m_defaultFramebufferMetalTexture release];
- m_defaultFramebufferMetalTexture = [tex retain];
+ /* Free old texture */
+ [m_defaultFramebufferMetalTexture[current_swapchain_index].texture release];
- glBindFramebuffer(GL_FRAMEBUFFER, m_defaultFramebuffer);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, glTex, 0);
+ id<MTLDevice> device = m_metalLayer.device;
+ MTLTextureDescriptor *overlayDesc = [MTLTextureDescriptor
+ texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA16Float
+ width:width
+ height:height
+ mipmapped:NO];
+ overlayDesc.storageMode = MTLStorageModePrivate;
+ overlayDesc.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
+
+ id<MTLTexture> overlayTex = [device newTextureWithDescriptor:overlayDesc];
+ if (!overlayTex) {
+ ghost_fatal_error_dialog(
+ "GHOST_ContextCGL::metalUpdateFramebuffer: failed to create Metal overlay texture!");
+ }
+ else {
+ overlayTex.label = [NSString
+ stringWithFormat:@"Metal Overlay for GHOST Context %p", this]; //@"";
- [m_metalLayer setDrawableSize:CGSizeMake((CGFloat)width, (CGFloat)height)];
+ // NSLog(@"Created new Metal Overlay (backbuffer) for context %p\n", this);
+ }
+
+ m_defaultFramebufferMetalTexture[current_swapchain_index].texture =
+ overlayTex; //[(MTLTexture *)overlayTex retain];
+
+ /* Clear texture on create */
+ id<MTLCommandBuffer> cmdBuffer = [m_metalCmdQueue commandBuffer];
+ MTLRenderPassDescriptor *passDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
+ {
+ auto attachment = [passDescriptor.colorAttachments objectAtIndexedSubscript:0];
+ attachment.texture = m_defaultFramebufferMetalTexture[current_swapchain_index].texture;
+ attachment.loadAction = MTLLoadActionClear;
+ attachment.clearColor = MTLClearColorMake(0.294, 0.294, 0.294, 1.000);
+ attachment.storeAction = MTLStoreActionStore;
+ }
+ {
+ id<MTLRenderCommandEncoder> enc = [cmdBuffer
+ renderCommandEncoderWithDescriptor:passDescriptor];
+ [enc endEncoding];
+ }
+ [cmdBuffer commit];
+ }
- CVPixelBufferRelease(cvPixelBuffer);
- CVOpenGLTextureCacheRelease(cvGLTexCache);
- CVOpenGLTextureRelease(cvGLTex);
- CFRelease(cvMetalTexCache);
- CFRelease(cvMetalTex);
+ if (!m_useMetalForRendering) {
+#if WITH_OPENGL
+ glBindFramebuffer(GL_FRAMEBUFFER, m_defaultFramebuffer);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, glTex, 0);
+#endif
+ }
+
+ [m_metalLayer setDrawableSize:CGSizeMake((CGFloat)width, (CGFloat)height)];
+ if (!m_useMetalForRendering) {
+#if WITH_OPENGL
+ CVPixelBufferRelease(cvPixelBuffer);
+ CVOpenGLTextureCacheRelease(cvGLTexCache);
+ CVOpenGLTextureRelease(cvGLTex);
+ CFRelease(cvMetalTexCache);
+ CFRelease(cvMetalTex);
+#endif
+ }
}
void GHOST_ContextCGL::metalSwapBuffers()
@@ -570,40 +827,88 @@ void GHOST_ContextCGL::metalSwapBuffers()
@autoreleasepool {
/* clang-format on */
updateDrawingContext();
- glFlush();
- assert(m_defaultFramebufferMetalTexture != 0);
+ if (!m_useMetalForRendering) {
+#if WITH_OPENGL
+ glFlush();
+ assert(m_defaultFramebufferMetalTexture[current_swapchain_index].texture != nil);
+#endif
+ }
id<CAMetalDrawable> drawable = [m_metalLayer nextDrawable];
if (!drawable) {
return;
}
- id<MTLCommandBuffer> cmdBuffer = [m_metalCmdQueue commandBuffer];
-
MTLRenderPassDescriptor *passDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
{
auto attachment = [passDescriptor.colorAttachments objectAtIndexedSubscript:0];
attachment.texture = drawable.texture;
- attachment.loadAction = MTLLoadActionDontCare;
+ attachment.loadAction = MTLLoadActionClear;
+ attachment.clearColor = MTLClearColorMake(1.0, 0.294, 0.294, 1.000);
attachment.storeAction = MTLStoreActionStore;
}
- id<MTLTexture> srcTexture = (id<MTLTexture>)m_defaultFramebufferMetalTexture;
+ if (!m_useMetalForRendering) {
+ id<MTLCommandBuffer> cmdBuffer = [m_metalCmdQueue commandBuffer];
+ {
+ assert(m_defaultFramebufferMetalTexture[current_swapchain_index].texture != nil);
+ id<MTLRenderCommandEncoder> enc = [cmdBuffer
+ renderCommandEncoderWithDescriptor:passDescriptor];
+ [enc setRenderPipelineState:(id<MTLRenderPipelineState>)m_metalRenderPipeline];
+ [enc setFragmentTexture:m_defaultFramebufferMetalTexture[current_swapchain_index].texture
+ atIndex:0];
+ [enc drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:3];
+ [enc endEncoding];
+ }
+
+ [cmdBuffer presentDrawable:drawable];
+ /* Submit command buffer */
+ [cmdBuffer commit];
+ }
+ else {
+ assert(contextPresentCallback);
+ assert(m_defaultFramebufferMetalTexture[current_swapchain_index].texture != nil);
+ (*contextPresentCallback)(passDescriptor,
+ (id<MTLRenderPipelineState>)m_metalRenderPipeline,
+ m_defaultFramebufferMetalTexture[current_swapchain_index].texture,
+ drawable);
+ }
+ }
+}
+
+void GHOST_ContextCGL::initClear()
+{
+
+ if (!m_useMetalForRendering) {
+#if WITH_OPENGL
+ glClearColor(0.294, 0.294, 0.294, 0.000);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glClearColor(0.000, 0.000, 0.000, 0.000);
+#endif
+ }
+ else {
+#if WITH_METAL
+ // TODO (mg_gpusw_apple) this path is never taken, this is legacy left from inital integration
+ // of metal and gl, the whole file should be cleaned up and stripped of the legacy path
+ id<MTLCommandBuffer> cmdBuffer = [m_metalCmdQueue commandBuffer];
+ MTLRenderPassDescriptor *passDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
+ {
+ auto attachment = [passDescriptor.colorAttachments objectAtIndexedSubscript:0];
+ attachment.texture = m_defaultFramebufferMetalTexture[current_swapchain_index].texture;
+ attachment.loadAction = MTLLoadActionClear;
+ attachment.clearColor = MTLClearColorMake(0.294, 0.294, 0.294, 1.000);
+ attachment.storeAction = MTLStoreActionStore;
+ }
+
+ // encoding
{
id<MTLRenderCommandEncoder> enc = [cmdBuffer
renderCommandEncoderWithDescriptor:passDescriptor];
-
- [enc setRenderPipelineState:(id<MTLRenderPipelineState>)m_metalRenderPipeline];
- [enc setFragmentTexture:srcTexture atIndex:0];
- [enc drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:3];
-
[enc endEncoding];
}
-
- [cmdBuffer presentDrawable:drawable];
-
[cmdBuffer commit];
+#endif
}
}
diff --git a/intern/ghost/intern/GHOST_ContextEGL.cpp b/intern/ghost/intern/GHOST_ContextEGL.cpp
index ef13133d3a3..fb1865630e3 100644
--- a/intern/ghost/intern/GHOST_ContextEGL.cpp
+++ b/intern/ghost/intern/GHOST_ContextEGL.cpp
@@ -127,13 +127,13 @@ static bool egl_chk(bool result,
file,
line,
text,
- static_cast<unsigned int>(error),
+ uint(error),
code ? code : "<Unknown>",
msg ? msg : "<Unknown>");
#else
fprintf(stderr,
"EGL Error (0x%04X): %s: %s\n",
- static_cast<unsigned int>(error),
+ uint(error),
code ? code : "<Unknown>",
msg ? msg : "<Unknown>");
(void)(file);
diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp
index ed1c874c236..d9f2df21ee0 100644
--- a/intern/ghost/intern/GHOST_ContextGLX.cpp
+++ b/intern/ghost/intern/GHOST_ContextGLX.cpp
@@ -140,7 +140,7 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
/* End Inline GLEW. */
/* -------------------------------------------------------------------- */
#else
- /* Important to initialize only glxew (_not_ GLEW),
+ /* Important to initialize only GLXEW (_not_ GLEW),
* since this breaks w/ Mesa's `swrast`, see: T46431. */
glxewInit();
#endif /* USE_GLXEW_INIT_WORKAROUND */
@@ -264,7 +264,7 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
GHOST_TSuccess success;
if (m_context != nullptr) {
- const unsigned char *version;
+ const uchar *version;
if (!s_sharedContext) {
s_sharedContext = m_context;
@@ -306,7 +306,7 @@ GHOST_TSuccess GHOST_ContextGLX::releaseNativeHandles()
GHOST_TSuccess GHOST_ContextGLX::setSwapInterval(int interval)
{
- if (!epoxy_has_glx_extension(m_display, DefaultScreen(m_display), "GLX_EXT_swap_control")) {
+ if (epoxy_has_glx_extension(m_display, DefaultScreen(m_display), "GLX_EXT_swap_control")) {
::glXSwapIntervalEXT(m_display, m_window, interval);
return GHOST_kSuccess;
}
@@ -316,11 +316,11 @@ GHOST_TSuccess GHOST_ContextGLX::setSwapInterval(int interval)
GHOST_TSuccess GHOST_ContextGLX::getSwapInterval(int &intervalOut)
{
if (epoxy_has_glx_extension(m_display, DefaultScreen(m_display), "GLX_EXT_swap_control")) {
- unsigned int interval = 0;
+ uint interval = 0;
::glXQueryDrawable(m_display, m_window, GLX_SWAP_INTERVAL_EXT, &interval);
- intervalOut = static_cast<int>(interval);
+ intervalOut = int(interval);
return GHOST_kSuccess;
}
diff --git a/intern/ghost/intern/GHOST_ContextWGL.cpp b/intern/ghost/intern/GHOST_ContextWGL.cpp
index d3c190a13b1..0b1cf56c549 100644
--- a/intern/ghost/intern/GHOST_ContextWGL.cpp
+++ b/intern/ghost/intern/GHOST_ContextWGL.cpp
@@ -437,7 +437,7 @@ int GHOST_ContextWGL::_choose_pixel_format_arb_1(bool stereoVisual, bool needAlp
makeAttribList(iAttributes, stereoVisual, needAlpha);
- UINT nNumFormats;
+ uint nNumFormats;
WIN32_CHK(wglChoosePixelFormatARB(
m_hDC, &(iAttributes[0]), NULL, _MAX_PIXEL_FORMATS, iPixelFormats, &nNumFormats));
diff --git a/intern/ghost/intern/GHOST_Debug.h b/intern/ghost/intern/GHOST_Debug.h
index ec1a0b34be6..64eff7f9aed 100644
--- a/intern/ghost/intern/GHOST_Debug.h
+++ b/intern/ghost/intern/GHOST_Debug.h
@@ -15,29 +15,41 @@
# endif
#endif
-#if defined(WITH_GHOST_DEBUG) || (!defined(NDEBUG))
-# include <iostream>
-# include <stdio.h> //for printf()
-#endif // WITH_GHOST_DEBUG
+#include <iostream>
+#include <stdio.h> /* For `printf()`. */
#if defined(WITH_GHOST_DEBUG)
# define GHOST_PRINT(x) \
{ \
std::cout << x; \
} \
- (void)0
+ ((void)0)
# define GHOST_PRINTF(x, ...) \
{ \
printf(x, __VA_ARGS__); \
} \
- (void)0
+ ((void)0)
#else
-# define GHOST_PRINT(x)
-# define GHOST_PRINTF(x, ...)
+/* Expand even when `WITH_GHOST_DEBUG` is disabled to prevent expressions
+ * becoming invalid even when the option is disable. */
+# define GHOST_PRINT(x) \
+ { \
+ if (false) { \
+ std::cout << x; \
+ } \
+ } \
+ ((void)0)
+# define GHOST_PRINTF(x, ...) \
+ { \
+ if (false) { \
+ printf(x, __VA_ARGS__); \
+ } \
+ } \
+ ((void)0)
+
#endif /* `!defined(WITH_GHOST_DEBUG)` */
#ifdef WITH_ASSERT_ABORT
-# include <stdio.h> //for fprintf()
# include <stdlib.h> //for abort()
# define GHOST_ASSERT(x, info) \
{ \
@@ -48,7 +60,7 @@
abort(); \
} \
} \
- (void)0
+ ((void)0)
/* Assert in non-release builds too. */
#elif defined(WITH_GHOST_DEBUG) || (!defined(NDEBUG))
# define GHOST_ASSERT(x, info) \
@@ -59,7 +71,7 @@
GHOST_PRINT("\n"); \
} \
} \
- (void)0
+ ((void)0)
#else /* `defined(WITH_GHOST_DEBUG) || (!defined(NDEBUG))` */
# define GHOST_ASSERT(x, info) ((void)0)
#endif /* `defined(WITH_GHOST_DEBUG) || (!defined(NDEBUG))` */
diff --git a/intern/ghost/intern/GHOST_DisplayManager.cpp b/intern/ghost/intern/GHOST_DisplayManager.cpp
index fa15d05232d..55f4b29e009 100644
--- a/intern/ghost/intern/GHOST_DisplayManager.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManager.cpp
@@ -70,7 +70,7 @@ GHOST_TSuccess GHOST_DisplayManager::getDisplaySetting(uint8_t display,
uint8_t numDisplays;
success = getNumDisplays(numDisplays);
if (success == GHOST_kSuccess) {
- if (display < numDisplays && ((uint8_t)index < m_settings[display].size())) {
+ if (display < numDisplays && (uint8_t(index) < m_settings[display].size())) {
setting = m_settings[display][index];
}
else {
@@ -101,14 +101,14 @@ GHOST_TSuccess GHOST_DisplayManager::findMatch(uint8_t display,
"GHOST_DisplayManager::findMatch(): m_settingsInitialized=false");
int criteria[4] = {
- (int)setting.xPixels, (int)setting.yPixels, (int)setting.bpp, (int)setting.frequency};
+ int(setting.xPixels), int(setting.yPixels), int(setting.bpp), int(setting.frequency)};
int capabilities[4];
double field, score;
double best = 1e12; /* A big number. */
int found = 0;
/* Look at all the display modes. */
- for (int i = 0; (i < (int)m_settings[display].size()); i++) {
+ for (int i = 0; (i < int(m_settings[display].size())); i++) {
/* Store the capabilities of the display device. */
capabilities[0] = m_settings[display][i].xPixels;
capabilities[1] = m_settings[display][i].yPixels;
diff --git a/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp b/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp
index a2fe6a41fb4..eed437adc6c 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp
@@ -109,7 +109,7 @@ GHOST_TSuccess GHOST_DisplayManagerSDL::setCurrentDisplaySetting(
SDL_GetDisplayMode(display, i, &mode);
- if ((int)setting.xPixels > mode.w || (int)setting.yPixels > mode.h) {
+ if (int(setting.xPixels) > mode.w || int(setting.yPixels) > mode.h) {
continue;
}
diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
index ab4a77cd660..53189c6551b 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
@@ -185,8 +185,8 @@ GHOST_TSuccess GHOST_DisplayManagerX11::setCurrentDisplaySetting(
}
}
else {
- if (abs(calculate_rate(vidmodes[i]) - (int)setting.frequency) <
- abs(calculate_rate(vidmodes[best_fit]) - (int)setting.frequency)) {
+ if (abs(calculate_rate(vidmodes[i]) - int(setting.frequency)) <
+ abs(calculate_rate(vidmodes[best_fit]) - int(setting.frequency))) {
best_fit = i;
}
}
diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.cpp b/intern/ghost/intern/GHOST_DropTargetWin32.cpp
index 2831f2ee8ad..86483118b3d 100644
--- a/intern/ghost/intern/GHOST_DropTargetWin32.cpp
+++ b/intern/ghost/intern/GHOST_DropTargetWin32.cpp
@@ -212,13 +212,13 @@ void *GHOST_DropTargetWin32::getDropDataAsFilenames(IDataObject *p_data_object)
if (p_data_object->GetData(&fmtetc, &stgmed) == S_OK) {
const HDROP hdrop = (HDROP)::GlobalLock(stgmed.hGlobal);
- const UINT totfiles = ::DragQueryFileW(hdrop, -1, NULL, 0);
+ const uint totfiles = ::DragQueryFileW(hdrop, -1, NULL, 0);
if (totfiles) {
str_array = (GHOST_TStringArray *)::malloc(sizeof(GHOST_TStringArray));
str_array->count = 0;
str_array->strings = (uint8_t **)::malloc(totfiles * sizeof(uint8_t *));
- for (UINT nfile = 0; nfile < totfiles; nfile++) {
+ for (uint nfile = 0; nfile < totfiles; nfile++) {
WCHAR fpath[MAX_PATH];
if (::DragQueryFileW(hdrop, nfile, fpath, MAX_PATH) > 0) {
char *temp_path;
@@ -341,7 +341,7 @@ void printLastError(void)
(LPTSTR)&s,
0,
NULL)) {
- printf("\nLastError: (%d) %s\n", (int)err, s);
+ printf("\nLastError: (%d) %s\n", int(err), s);
LocalFree(s);
}
}
diff --git a/intern/ghost/intern/GHOST_DropTargetX11.cpp b/intern/ghost/intern/GHOST_DropTargetX11.cpp
index 4da3c7c996d..b37aa410198 100644
--- a/intern/ghost/intern/GHOST_DropTargetX11.cpp
+++ b/intern/ghost/intern/GHOST_DropTargetX11.cpp
@@ -107,14 +107,14 @@ char *GHOST_DropTargetX11::FileUrlDecode(char *fileUrl)
return nullptr;
}
-void *GHOST_DropTargetX11::getURIListGhostData(unsigned char *dropBuffer, int dropBufferSize)
+void *GHOST_DropTargetX11::getURIListGhostData(uchar *dropBuffer, int dropBufferSize)
{
GHOST_TStringArray *strArray = nullptr;
int totPaths = 0, curLength = 0;
/* Count total number of file paths in buffer. */
for (int i = 0; i <= dropBufferSize; i++) {
- if (dropBuffer[i] == 0 || dropBuffer[i] == '\n' || dropBuffer[i] == '\r') {
+ if (ELEM(dropBuffer[i], 0, '\n', '\r')) {
if (curLength) {
totPaths++;
curLength = 0;
@@ -131,7 +131,7 @@ void *GHOST_DropTargetX11::getURIListGhostData(unsigned char *dropBuffer, int dr
curLength = 0;
for (int i = 0; i <= dropBufferSize; i++) {
- if (dropBuffer[i] == 0 || dropBuffer[i] == '\n' || dropBuffer[i] == '\r') {
+ if (ELEM(dropBuffer[i], 0, '\n', '\r')) {
if (curLength) {
char *curPath = (char *)malloc(curLength + 1);
char *decodedPath;
@@ -157,12 +157,10 @@ void *GHOST_DropTargetX11::getURIListGhostData(unsigned char *dropBuffer, int dr
return strArray;
}
-void *GHOST_DropTargetX11::getGhostData(Atom dropType,
- unsigned char *dropBuffer,
- int dropBufferSize)
+void *GHOST_DropTargetX11::getGhostData(Atom dropType, uchar *dropBuffer, int dropBufferSize)
{
void *data = nullptr;
- unsigned char *tmpBuffer = (unsigned char *)malloc(dropBufferSize + 1);
+ uchar *tmpBuffer = (uchar *)malloc(dropBufferSize + 1);
bool needsFree = true;
/* Ensure nil-terminator. */
@@ -182,7 +180,7 @@ void *GHOST_DropTargetX11::getGhostData(Atom dropType,
data = decodedPath;
}
}
- else if (dropType == dndTypePlainText || dropType == dndTypeOctetStream) {
+ else if (ELEM(dropType, dndTypePlainText, dndTypeOctetStream)) {
m_draggedObjectType = GHOST_kDragnDropTypeString;
data = tmpBuffer;
needsFree = false;
@@ -201,7 +199,7 @@ void *GHOST_DropTargetX11::getGhostData(Atom dropType,
bool GHOST_DropTargetX11::GHOST_HandleClientMessage(XEvent *event)
{
Atom dropType;
- unsigned char *dropBuffer;
+ uchar *dropBuffer;
int dropBufferSize, dropX, dropY;
if (xdnd_get_drop(m_system->getXDisplay(),
diff --git a/intern/ghost/intern/GHOST_EventManager.cpp b/intern/ghost/intern/GHOST_EventManager.cpp
index 670631e4e16..184052aa6ab 100644
--- a/intern/ghost/intern/GHOST_EventManager.cpp
+++ b/intern/ghost/intern/GHOST_EventManager.cpp
@@ -31,7 +31,7 @@ GHOST_EventManager::~GHOST_EventManager()
uint32_t GHOST_EventManager::getNumEvents()
{
- return (uint32_t)m_events.size();
+ return uint32_t(m_events.size());
}
uint32_t GHOST_EventManager::getNumEvents(GHOST_TEventType type)
diff --git a/intern/ghost/intern/GHOST_EventPrinter.cpp b/intern/ghost/intern/GHOST_EventPrinter.cpp
index 2620bcc075d..0d7f05009ff 100644
--- a/intern/ghost/intern/GHOST_EventPrinter.cpp
+++ b/intern/ghost/intern/GHOST_EventPrinter.cpp
@@ -161,7 +161,7 @@ bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
void GHOST_EventPrinter::getKeyString(GHOST_TKey key, char str[32]) const
{
if ((key >= GHOST_kKeyComma) && (key <= GHOST_kKeyRightBracket)) {
- sprintf(str, "%c", (char)key);
+ sprintf(str, "%c", char(key));
}
else if ((key >= GHOST_kKeyNumpad0) && (key <= GHOST_kKeyNumpad9)) {
sprintf(str, "Numpad %d", (key - GHOST_kKeyNumpad0));
@@ -220,8 +220,11 @@ void GHOST_EventPrinter::getKeyString(GHOST_TKey key, char str[32]) const
case GHOST_kKeyRightAlt:
tstr = "RightAlt";
break;
- case GHOST_kKeyOS:
- tstr = "OS";
+ case GHOST_kKeyLeftOS:
+ tstr = "LeftOS";
+ break;
+ case GHOST_kKeyRightOS:
+ tstr = "RightOS";
break;
case GHOST_kKeyApp:
tstr = "App";
diff --git a/intern/ghost/intern/GHOST_ISystem.cpp b/intern/ghost/intern/GHOST_ISystem.cpp
index 13eccf661f5..696848ce623 100644
--- a/intern/ghost/intern/GHOST_ISystem.cpp
+++ b/intern/ghost/intern/GHOST_ISystem.cpp
@@ -30,11 +30,17 @@
#endif
GHOST_ISystem *GHOST_ISystem::m_system = nullptr;
+const char *GHOST_ISystem::m_system_backend_id = nullptr;
GHOST_TBacktraceFn GHOST_ISystem::m_backtrace_fn = nullptr;
-GHOST_TSuccess GHOST_ISystem::createSystem()
+GHOST_TSuccess GHOST_ISystem::createSystem(bool verbose, [[maybe_unused]] bool background)
{
+ /* When GHOST fails to start, report the back-ends that were attempted.
+ * A Verbose argument could be supported in printing isn't always desired. */
+ const char *backends_attempted[8] = {nullptr};
+ int backends_attempted_num = 0;
+
GHOST_TSuccess success;
if (!m_system) {
@@ -42,7 +48,7 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
/* Pass. */
#elif defined(WITH_GHOST_WAYLAND)
# if defined(WITH_GHOST_WAYLAND_DYNLOAD)
- const bool has_wayland_libraries = ghost_wl_dynload_libraries();
+ const bool has_wayland_libraries = ghost_wl_dynload_libraries_init();
# else
const bool has_wayland_libraries = true;
# endif
@@ -52,15 +58,26 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
/* Pass. */
#elif defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND)
/* Special case, try Wayland, fall back to X11. */
- try {
- m_system = has_wayland_libraries ? new GHOST_SystemWayland() : nullptr;
+ if (has_wayland_libraries) {
+ backends_attempted[backends_attempted_num++] = "WAYLAND";
+ try {
+ m_system = new GHOST_SystemWayland(background);
+ }
+ catch (const std::runtime_error &) {
+ delete m_system;
+ m_system = nullptr;
+# ifdef WITH_GHOST_WAYLAND_DYNLOAD
+ ghost_wl_dynload_libraries_exit();
+# endif
+ }
}
- catch (const std::runtime_error &) {
- delete m_system;
+ else {
m_system = nullptr;
}
+
if (!m_system) {
/* Try to fallback to X11. */
+ backends_attempted[backends_attempted_num++] = "X11";
try {
m_system = new GHOST_SystemX11();
}
@@ -70,6 +87,7 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
}
}
#elif defined(WITH_GHOST_X11)
+ backends_attempted[backends_attempted_num++] = "X11";
try {
m_system = new GHOST_SystemX11();
}
@@ -78,14 +96,24 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
m_system = nullptr;
}
#elif defined(WITH_GHOST_WAYLAND)
- try {
- m_system = has_wayland_libraries ? new GHOST_SystemWayland() : nullptr;
+ if (has_wayland_libraries) {
+ backends_attempted[backends_attempted_num++] = "WAYLAND";
+ try {
+ m_system = new GHOST_SystemWayland(background);
+ }
+ catch (const std::runtime_error &) {
+ delete m_system;
+ m_system = nullptr;
+# ifdef WITH_GHOST_WAYLAND_DYNLOAD
+ ghost_wl_dynload_libraries_exit();
+# endif
+ }
}
- catch (const std::runtime_error &) {
- delete m_system;
+ else {
m_system = nullptr;
}
#elif defined(WITH_GHOST_SDL)
+ backends_attempted[backends_attempted_num++] = "SDL";
try {
m_system = new GHOST_SystemSDL();
}
@@ -94,10 +122,27 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
m_system = nullptr;
}
#elif defined(WIN32)
+ backends_attempted[backends_attempted_num++] = "WIN32";
m_system = new GHOST_SystemWin32();
#elif defined(__APPLE__)
+ backends_attempted[backends_attempted_num++] = "COCOA";
m_system = new GHOST_SystemCocoa();
#endif
+
+ if (m_system) {
+ m_system_backend_id = backends_attempted[backends_attempted_num - 1];
+ }
+ else if (verbose) {
+ fprintf(stderr, "GHOST: failed to initialize display for back-end(s): [");
+ for (int i = 0; i < backends_attempted_num; i++) {
+ if (i != 0) {
+ fprintf(stderr, ", ");
+ }
+ fprintf(stderr, "'%s'", backends_attempted[i]);
+ }
+ fprintf(stderr, "]\n");
+ }
+
success = m_system != nullptr ? GHOST_kSuccess : GHOST_kFailure;
}
else {
@@ -115,7 +160,7 @@ GHOST_TSuccess GHOST_ISystem::createSystemBackground()
if (!m_system) {
#if !defined(WITH_HEADLESS)
/* Try to create a off-screen render surface with the graphical systems. */
- success = createSystem();
+ success = createSystem(false, true);
if (success) {
return success;
}
@@ -151,6 +196,11 @@ GHOST_ISystem *GHOST_ISystem::getSystem()
return m_system;
}
+const char *GHOST_ISystem::getSystemBackend()
+{
+ return m_system_backend_id;
+}
+
GHOST_TBacktraceFn GHOST_ISystem::getBacktraceFn()
{
return GHOST_ISystem::m_backtrace_fn;
diff --git a/intern/ghost/intern/GHOST_ImeWin32.cpp b/intern/ghost/intern/GHOST_ImeWin32.cpp
index 0a62359cd77..780d93ac995 100644
--- a/intern/ghost/intern/GHOST_ImeWin32.cpp
+++ b/intern/ghost/intern/GHOST_ImeWin32.cpp
@@ -270,7 +270,7 @@ void GHOST_ImeWin32::GetCaret(HIMC imm_context, LPARAM lparam, ImeComposition *c
else if (IsLanguage(IMELANG_CHINESE)) {
int clause_size = ImmGetCompositionStringW(imm_context, GCS_COMPCLAUSE, NULL, 0);
if (clause_size) {
- static std::vector<unsigned long> clauses;
+ static std::vector<ulong> clauses;
clause_size = clause_size / sizeof(clauses[0]);
clauses.resize(clause_size);
ImmGetCompositionStringW(
diff --git a/intern/ghost/intern/GHOST_ImeWin32.h b/intern/ghost/intern/GHOST_ImeWin32.h
index 85c8ed7b4bd..cb6d8a770cf 100644
--- a/intern/ghost/intern/GHOST_ImeWin32.h
+++ b/intern/ghost/intern/GHOST_ImeWin32.h
@@ -266,7 +266,7 @@ class GHOST_ImeWin32 {
* Parameters
* * window_handle [in] (HWND)
* Represents the window handle of the caller.
- * * caret_rect [in] (const gfx::Rect&)
+ * * caret_rect [in] (`const gfx::Rect&`)
* Represent the rectangle of the input caret.
* This rectangle is used for controlling the positions of IME windows.
* * complete [in] (bool)
diff --git a/intern/ghost/intern/GHOST_ModifierKeys.cpp b/intern/ghost/intern/GHOST_ModifierKeys.cpp
index d31dc8f0770..5ecbae77f46 100644
--- a/intern/ghost/intern/GHOST_ModifierKeys.cpp
+++ b/intern/ghost/intern/GHOST_ModifierKeys.cpp
@@ -10,6 +10,7 @@
*/
#include "GHOST_ModifierKeys.h"
+#include "GHOST_Debug.h"
GHOST_ModifierKeys::GHOST_ModifierKeys()
{
@@ -42,11 +43,15 @@ GHOST_TKey GHOST_ModifierKeys::getModifierKeyCode(GHOST_TModifierKey mask)
case GHOST_kModifierKeyRightControl:
key = GHOST_kKeyRightControl;
break;
- case GHOST_kModifierKeyOS:
- key = GHOST_kKeyOS;
+ case GHOST_kModifierKeyLeftOS:
+ key = GHOST_kKeyLeftOS;
+ break;
+ case GHOST_kModifierKeyRightOS:
+ key = GHOST_kKeyRightOS;
break;
default:
- // Should not happen
+ /* Should not happen. */
+ GHOST_ASSERT(0, "Invalid key!");
key = GHOST_kKeyUnknown;
break;
}
@@ -68,9 +73,12 @@ bool GHOST_ModifierKeys::get(GHOST_TModifierKey mask) const
return m_LeftControl;
case GHOST_kModifierKeyRightControl:
return m_RightControl;
- case GHOST_kModifierKeyOS:
- return m_OS;
+ case GHOST_kModifierKeyLeftOS:
+ return m_LeftOS;
+ case GHOST_kModifierKeyRightOS:
+ return m_RightOS;
default:
+ GHOST_ASSERT(0, "Invalid key!");
return false;
}
}
@@ -96,10 +104,14 @@ void GHOST_ModifierKeys::set(GHOST_TModifierKey mask, bool down)
case GHOST_kModifierKeyRightControl:
m_RightControl = down;
break;
- case GHOST_kModifierKeyOS:
- m_OS = down;
+ case GHOST_kModifierKeyLeftOS:
+ m_LeftOS = down;
+ break;
+ case GHOST_kModifierKeyRightOS:
+ m_RightOS = down;
break;
default:
+ GHOST_ASSERT(0, "Invalid key!");
break;
}
}
@@ -112,7 +124,8 @@ void GHOST_ModifierKeys::clear()
m_RightAlt = false;
m_LeftControl = false;
m_RightControl = false;
- m_OS = false;
+ m_LeftOS = false;
+ m_RightOS = false;
}
bool GHOST_ModifierKeys::equals(const GHOST_ModifierKeys &keys) const
@@ -120,5 +133,5 @@ bool GHOST_ModifierKeys::equals(const GHOST_ModifierKeys &keys) const
return (m_LeftShift == keys.m_LeftShift) && (m_RightShift == keys.m_RightShift) &&
(m_LeftAlt == keys.m_LeftAlt) && (m_RightAlt == keys.m_RightAlt) &&
(m_LeftControl == keys.m_LeftControl) && (m_RightControl == keys.m_RightControl) &&
- (m_OS == keys.m_OS);
+ (m_LeftOS == keys.m_LeftOS) && (m_RightOS == keys.m_RightOS);
}
diff --git a/intern/ghost/intern/GHOST_ModifierKeys.h b/intern/ghost/intern/GHOST_ModifierKeys.h
index ce1bf3df2ae..e2afc879411 100644
--- a/intern/ghost/intern/GHOST_ModifierKeys.h
+++ b/intern/ghost/intern/GHOST_ModifierKeys.h
@@ -55,18 +55,19 @@ struct GHOST_ModifierKeys {
*/
bool equals(const GHOST_ModifierKeys &keys) const;
- /** Bitfield that stores the appropriate key state. */
+ /** Bit-field that stores the appropriate key state. */
uint8_t m_LeftShift : 1;
- /** Bitfield that stores the appropriate key state. */
+ /** Bit-field that stores the appropriate key state. */
uint8_t m_RightShift : 1;
- /** Bitfield that stores the appropriate key state. */
+ /** Bit-field that stores the appropriate key state. */
uint8_t m_LeftAlt : 1;
- /** Bitfield that stores the appropriate key state. */
+ /** Bit-field that stores the appropriate key state. */
uint8_t m_RightAlt : 1;
- /** Bitfield that stores the appropriate key state. */
+ /** Bit-field that stores the appropriate key state. */
uint8_t m_LeftControl : 1;
- /** Bitfield that stores the appropriate key state. */
+ /** Bit-field that stores the appropriate key state. */
uint8_t m_RightControl : 1;
- /** Bitfield that stores the appropriate key state. */
- uint8_t m_OS : 1;
+ /** Bit-field that stores the appropriate key state. */
+ uint8_t m_LeftOS : 1;
+ uint8_t m_RightOS : 1;
};
diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp
index 746e3532b03..5484da82a18 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManager.cpp
@@ -7,53 +7,50 @@
#include "GHOST_WindowManager.h"
#include "GHOST_utildefines.h"
+/* Logging, use `ghost.ndof.*` prefix. */
+#include "CLG_log.h"
+
#include <climits>
#include <cmath>
-#include <cstdio> /* For error/info reporting. */
#include <cstring> /* For memory functions. */
-#ifdef DEBUG_NDOF_MOTION
-/* Printable version of each GHOST_TProgress value. */
-static const char *progress_string[] = {
- "not started", "starting", "in progress", "finishing", "finished"};
-#endif
+/* -------------------------------------------------------------------- */
+/** \name NDOF Enum Strings
+ * \{ */
+
+/* Printable values for #GHOST_TProgress enum (keep aligned). */
+static const char *ndof_progress_string[] = {
+ "not started",
+ "starting",
+ "in progress",
+ "finishing",
+ "finished",
+};
-#ifdef DEBUG_NDOF_BUTTONS
+/* Printable values for #NDOF_ButtonT enum (keep aligned) */
static const char *ndof_button_names[] = {
- /* used internally, never sent */
- "NDOF_BUTTON_NONE",
- /* these two are available from any 3Dconnexion device */
+ /* Exclude `NDOF_BUTTON_NONE` (-1). */
"NDOF_BUTTON_MENU",
"NDOF_BUTTON_FIT",
- /* standard views */
"NDOF_BUTTON_TOP",
"NDOF_BUTTON_BOTTOM",
"NDOF_BUTTON_LEFT",
"NDOF_BUTTON_RIGHT",
"NDOF_BUTTON_FRONT",
"NDOF_BUTTON_BACK",
- /* more views */
"NDOF_BUTTON_ISO1",
"NDOF_BUTTON_ISO2",
- /* 90 degree rotations */
"NDOF_BUTTON_ROLL_CW",
"NDOF_BUTTON_ROLL_CCW",
"NDOF_BUTTON_SPIN_CW",
"NDOF_BUTTON_SPIN_CCW",
"NDOF_BUTTON_TILT_CW",
"NDOF_BUTTON_TILT_CCW",
- /* device control */
"NDOF_BUTTON_ROTATE",
"NDOF_BUTTON_PANZOOM",
"NDOF_BUTTON_DOMINANT",
"NDOF_BUTTON_PLUS",
"NDOF_BUTTON_MINUS",
- /* keyboard emulation */
- "NDOF_BUTTON_ESC",
- "NDOF_BUTTON_ALT",
- "NDOF_BUTTON_SHIFT",
- "NDOF_BUTTON_CTRL",
- /* general-purpose buttons */
"NDOF_BUTTON_1",
"NDOF_BUTTON_2",
"NDOF_BUTTON_3",
@@ -64,18 +61,47 @@ static const char *ndof_button_names[] = {
"NDOF_BUTTON_8",
"NDOF_BUTTON_9",
"NDOF_BUTTON_10",
- /* more general-purpose buttons */
"NDOF_BUTTON_A",
"NDOF_BUTTON_B",
"NDOF_BUTTON_C",
- /* the end */
- "NDOF_BUTTON_LAST"};
-#endif
+ "NDOF_BUTTON_V1",
+ "NDOF_BUTTON_V2",
+ "NDOF_BUTTON_V3",
+ /* Keyboard emulation. */
+ "NDOF_BUTTON_ESC",
+ "NDOF_BUTTON_ENTER",
+ "NDOF_BUTTON_DELETE",
+ "NDOF_BUTTON_TAB",
+ "NDOF_BUTTON_SPACE",
+ "NDOF_BUTTON_ALT",
+ "NDOF_BUTTON_SHIFT",
+ "NDOF_BUTTON_CTRL",
+};
+
+static const char *ndof_device_names[] = {
+ "UnknownDevice",
+ "SpaceNavigator",
+ "SpaceExplorer",
+ "SpacePilotPro",
+ "SpaceMousePro",
+ "SpaceMouseWireless",
+ "SpaceMouseProWireless",
+ "SpaceMouseEnterprise",
+ "SpacePilot",
+ "Spaceball5000",
+ "SpaceTraveler",
+};
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name NDOF Button Maps
+ * \{ */
/* Shared by the latest 3Dconnexion hardware
* SpacePilotPro uses all of these
* smaller devices use only some, based on button mask. */
-static const NDOF_ButtonT Modern3Dx_HID_map[] = {
+static const NDOF_ButtonT ndof_HID_map_Modern3Dx[] = {
NDOF_BUTTON_MENU, NDOF_BUTTON_FIT, NDOF_BUTTON_TOP, NDOF_BUTTON_LEFT,
NDOF_BUTTON_RIGHT, NDOF_BUTTON_FRONT, NDOF_BUTTON_BOTTOM, NDOF_BUTTON_BACK,
NDOF_BUTTON_ROLL_CW, NDOF_BUTTON_ROLL_CCW, NDOF_BUTTON_ISO1, NDOF_BUTTON_ISO2,
@@ -85,7 +111,7 @@ static const NDOF_ButtonT Modern3Dx_HID_map[] = {
NDOF_BUTTON_SHIFT, NDOF_BUTTON_CTRL, NDOF_BUTTON_ROTATE, NDOF_BUTTON_PANZOOM,
NDOF_BUTTON_DOMINANT, NDOF_BUTTON_PLUS, NDOF_BUTTON_MINUS};
-static const NDOF_ButtonT SpaceExplorer_HID_map[] = {
+static const NDOF_ButtonT ndof_HID_map_SpaceExplorer[] = {
NDOF_BUTTON_1,
NDOF_BUTTON_2,
NDOF_BUTTON_TOP,
@@ -103,9 +129,8 @@ static const NDOF_ButtonT SpaceExplorer_HID_map[] = {
NDOF_BUTTON_ROTATE,
};
-/* This is the older SpacePilot (sans Pro)
- * thanks to polosson for info about this device. */
-static const NDOF_ButtonT SpacePilot_HID_map[] = {
+/* This is the older SpacePilot (sans Pro). */
+static const NDOF_ButtonT ndof_HID_map_SpacePilot[] = {
NDOF_BUTTON_1, NDOF_BUTTON_2, NDOF_BUTTON_3, NDOF_BUTTON_4,
NDOF_BUTTON_5, NDOF_BUTTON_6, NDOF_BUTTON_TOP, NDOF_BUTTON_LEFT,
NDOF_BUTTON_RIGHT, NDOF_BUTTON_FRONT, NDOF_BUTTON_ESC, NDOF_BUTTON_ALT,
@@ -114,7 +139,7 @@ static const NDOF_ButtonT SpacePilot_HID_map[] = {
NDOF_BUTTON_NONE /* the CONFIG button -- what does it do? */
};
-static const NDOF_ButtonT Generic_HID_map[] = {
+static const NDOF_ButtonT ndof_HID_map_Generic[] = {
NDOF_BUTTON_1,
NDOF_BUTTON_2,
NDOF_BUTTON_3,
@@ -129,41 +154,91 @@ static const NDOF_ButtonT Generic_HID_map[] = {
NDOF_BUTTON_C,
};
-static const int genericButtonCount = ARRAY_SIZE(Generic_HID_map);
+/* Values taken from: https://github.com/FreeSpacenav/spacenavd/wiki/Device-button-names */
+static const NDOF_ButtonT ndof_HID_map_SpaceMouseEnterprise[] = {
+ NDOF_BUTTON_1, /* (0) */
+ NDOF_BUTTON_2, /* (1) */
+ NDOF_BUTTON_3, /* (2) */
+ NDOF_BUTTON_4, /* (3) */
+ NDOF_BUTTON_5, /* (4) */
+ NDOF_BUTTON_6, /* (5) */
+ NDOF_BUTTON_7, /* (6) */
+ NDOF_BUTTON_8, /* (7) */
+ NDOF_BUTTON_9, /* (8) */
+ NDOF_BUTTON_A, /* Labeled "10" (9). */
+ NDOF_BUTTON_B, /* Labeled "11" (10). */
+ NDOF_BUTTON_C, /* Labeled "12" (11). */
+ NDOF_BUTTON_MENU, /* (12). */
+ NDOF_BUTTON_FIT, /* (13). */
+ NDOF_BUTTON_TOP, /* (14). */
+ NDOF_BUTTON_RIGHT, /* (15). */
+ NDOF_BUTTON_FRONT, /* (16). */
+ NDOF_BUTTON_ROLL_CW, /* (17). */
+ NDOF_BUTTON_ESC, /* (18). */
+ NDOF_BUTTON_ALT, /* (19). */
+ NDOF_BUTTON_SHIFT, /* (20). */
+ NDOF_BUTTON_CTRL, /* (21). */
+ NDOF_BUTTON_ROTATE, /* Labeled "Lock Rotate" (22). */
+ NDOF_BUTTON_ENTER, /* Labeled "Enter" (23). */
+ NDOF_BUTTON_DELETE, /* (24). */
+ NDOF_BUTTON_TAB, /* (25). */
+ NDOF_BUTTON_SPACE, /* (26). */
+ NDOF_BUTTON_V1, /* Labeled "V1" (27). */
+ NDOF_BUTTON_V2, /* Labeled "V2" (28). */
+ NDOF_BUTTON_V3, /* Labeled "V3" (29). */
+ NDOF_BUTTON_ISO1, /* Labeled "ISO1" (30). */
+};
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name NDOF Manager Class
+ * \{ */
+
+static const int genericButtonCount = ARRAY_SIZE(ndof_HID_map_Generic);
GHOST_NDOFManager::GHOST_NDOFManager(GHOST_System &sys)
- : m_system(sys),
- m_deviceType(NDOF_UnknownDevice), /* Each platform has its own device detection code. */
- m_buttonCount(genericButtonCount),
- m_buttonMask(0),
- m_hidMap(Generic_HID_map),
- m_buttons(0),
- m_motionTime(0),
- m_prevMotionTime(0),
- m_motionState(GHOST_kNotStarted),
- m_motionEventPending(false),
- m_deadZone(0.0f)
+ : system_(sys),
+ device_type_(NDOF_UnknownDevice), /* Each platform has its own device detection code. */
+ hid_map_button_num_(genericButtonCount),
+ hid_map_button_mask_(0),
+ hid_map_(ndof_HID_map_Generic),
+ button_depressed_(0),
+ motion_time_(0),
+ motion_time_prev_(0),
+ motion_state_(GHOST_kNotStarted),
+ motion_event_pending_(false),
+ motion_dead_zone_(0.0f)
{
/* To avoid the rare situation where one triple is updated and
* the other is not, initialize them both here: */
- memset(m_translation, 0, sizeof(m_translation));
- memset(m_rotation, 0, sizeof(m_rotation));
+ memset(translation_, 0, sizeof(translation_));
+ memset(rotation_, 0, sizeof(rotation_));
}
-bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short product_id)
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name NDOF Device Setup
+ * \{ */
+
+static CLG_LogRef LOG_NDOF_DEVICE = {"ghost.ndof.device"};
+#define LOG (&LOG_NDOF_DEVICE)
+
+bool GHOST_NDOFManager::setDevice(ushort vendor_id, ushort product_id)
{
/* Call this function until it returns true
* it's a good idea to stop calling it after that, as it will "forget"
- * whichever device it already found */
+ * whichever device it already found. */
/* Default to safe generic behavior for "unknown" devices
* unidentified devices will emit motion events like normal
* rogue buttons do nothing by default, but can be customized by the user. */
- m_deviceType = NDOF_UnknownDevice;
- m_hidMap = Generic_HID_map;
- m_buttonCount = genericButtonCount;
- m_buttonMask = 0;
+ device_type_ = NDOF_UnknownDevice;
+ hid_map_ = ndof_HID_map_Generic;
+ hid_map_button_num_ = genericButtonCount;
+ hid_map_button_mask_ = 0;
/* "mystery device" owners can help build a HID_map for their hardware
* A few users have already contributed information about several older devices
@@ -173,112 +248,166 @@ bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ
case 0x046D: /* Logitech (3Dconnexion was a subsidiary). */
switch (product_id) {
/* -- current devices -- */
- case 0xC626: /* full-size SpaceNavigator */
- case 0xC628: /* the "for Notebooks" one */
- puts("ndof: using SpaceNavigator");
- m_deviceType = NDOF_SpaceNavigator;
- m_buttonCount = 2;
- m_hidMap = Modern3Dx_HID_map;
+ case 0xC626: /* Full-size SpaceNavigator. */
+ case 0xC628: /* The "for Notebooks" one. */
+ {
+ device_type_ = NDOF_SpaceNavigator;
+ hid_map_button_num_ = 2;
+ hid_map_ = ndof_HID_map_Modern3Dx;
break;
- case 0xC627:
- puts("ndof: using SpaceExplorer");
- m_deviceType = NDOF_SpaceExplorer;
- m_buttonCount = 15;
- m_hidMap = SpaceExplorer_HID_map;
+ }
+ case 0xC627: {
+ device_type_ = NDOF_SpaceExplorer;
+ hid_map_button_num_ = 15;
+ hid_map_ = ndof_HID_map_SpaceExplorer;
break;
- case 0xC629:
- puts("ndof: using SpacePilot Pro");
- m_deviceType = NDOF_SpacePilotPro;
- m_buttonCount = 31;
- m_hidMap = Modern3Dx_HID_map;
+ }
+ case 0xC629: {
+ device_type_ = NDOF_SpacePilotPro;
+ hid_map_button_num_ = 31;
+ hid_map_ = ndof_HID_map_Modern3Dx;
break;
- case 0xC62B:
- puts("ndof: using SpaceMouse Pro");
- m_deviceType = NDOF_SpaceMousePro;
- m_buttonCount = 27;
- /* ^^ actually has 15 buttons, but their HID codes range from 0 to 26 */
- m_buttonMask = 0x07C0F137;
- m_hidMap = Modern3Dx_HID_map;
+ }
+ case 0xC62B: {
+ device_type_ = NDOF_SpaceMousePro;
+ hid_map_button_num_ = 27; /* 15 physical buttons, but HID codes range from 0 to 26. */
+ hid_map_button_mask_ = 0x07C0F137;
+ hid_map_ = ndof_HID_map_Modern3Dx;
break;
+ }
/* -- older devices -- */
- case 0xC625:
- puts("ndof: using SpacePilot");
- m_deviceType = NDOF_SpacePilot;
- m_buttonCount = 21;
- m_hidMap = SpacePilot_HID_map;
+ case 0xC625: {
+ device_type_ = NDOF_SpacePilot;
+ hid_map_button_num_ = 21;
+ hid_map_ = ndof_HID_map_SpacePilot;
break;
- case 0xC621:
- puts("ndof: using Spaceball 5000");
- m_deviceType = NDOF_Spaceball5000;
- m_buttonCount = 12;
+ }
+ case 0xC621: {
+ device_type_ = NDOF_Spaceball5000;
+ hid_map_button_num_ = 12;
break;
- case 0xC623:
- puts("ndof: using SpaceTraveler");
- m_deviceType = NDOF_SpaceTraveler;
- m_buttonCount = 8;
+ }
+ case 0xC623: {
+ device_type_ = NDOF_SpaceTraveler;
+ hid_map_button_num_ = 8;
break;
-
- default:
- printf("ndof: unknown Logitech product %04hx\n", product_id);
+ }
+ default: {
+ CLOG_INFO(LOG, 2, "unknown Logitech product %04hx", product_id);
+ }
}
break;
- case 0x256F: /* 3Dconnexion */
+ case 0x256F: /* 3Dconnexion. */
switch (product_id) {
case 0xC62E: /* Plugged in. */
case 0xC62F: /* Wireless. */
- puts("ndof: using SpaceMouse Wireless");
- m_deviceType = NDOF_SpaceMouseWireless;
- m_buttonCount = 2;
- m_hidMap = Modern3Dx_HID_map;
+ case 0xC658: /* Wireless (3DConnexion Universal Wireless Receiver in WIN32), see T82412. */
+ {
+ device_type_ = NDOF_SpaceMouseWireless;
+ hid_map_button_num_ = 2;
+ hid_map_ = ndof_HID_map_Modern3Dx;
break;
+ }
case 0xC631: /* Plugged in. */
case 0xC632: /* Wireless. */
- puts("ndof: using SpaceMouse Pro Wireless");
- m_deviceType = NDOF_SpaceMouseProWireless;
- m_buttonCount = 27;
- /* ^^ actually has 15 buttons, but their HID codes range from 0 to 26. */
- m_buttonMask = 0x07C0F137;
- m_hidMap = Modern3Dx_HID_map;
+ {
+ device_type_ = NDOF_SpaceMouseProWireless;
+ hid_map_button_num_ = 27; /* 15 physical buttons, but HID codes range from 0 to 26. */
+ hid_map_button_mask_ = 0x07C0F137;
+ hid_map_ = ndof_HID_map_Modern3Dx;
break;
- case 0xC633:
- puts("ndof: using SpaceMouse Enterprise");
- m_deviceType = NDOF_SpaceMouseEnterprise;
- m_buttonCount = 31;
- m_hidMap = Modern3Dx_HID_map;
+ }
+ case 0xC633: {
+ device_type_ = NDOF_SpaceMouseEnterprise;
+ hid_map_button_num_ = 31;
+ hid_map_ = ndof_HID_map_SpaceMouseEnterprise;
break;
-
- default:
- printf("ndof: unknown 3Dconnexion product %04hx\n", product_id);
+ }
+ default: {
+ CLOG_INFO(LOG, 2, "unknown 3Dconnexion product %04hx", product_id);
+ }
}
break;
default:
- printf("ndof: unknown device %04hx:%04hx\n", vendor_id, product_id);
+ CLOG_INFO(LOG, 2, "unknown device %04hx:%04hx", vendor_id, product_id);
}
- if (m_buttonMask == 0) {
- m_buttonMask = (int)~(UINT_MAX << m_buttonCount);
+ if (device_type_ != NDOF_UnknownDevice) {
+ CLOG_INFO(LOG, 2, "using %s", ndof_device_names[device_type_]);
}
-#ifdef DEBUG_NDOF_BUTTONS
- printf("ndof: %d buttons -> hex:%X\n", m_buttonCount, m_buttonMask);
-#endif
+ if (hid_map_button_mask_ == 0) {
+ hid_map_button_mask_ = int(~(UINT_MAX << hid_map_button_num_));
+ }
+
+ CLOG_INFO(LOG, 2, "%d buttons -> hex:%X", hid_map_button_num_, (uint)hid_map_button_mask_);
- return m_deviceType != NDOF_UnknownDevice;
+ return device_type_ != NDOF_UnknownDevice;
}
+#undef LOG
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name NDOF Update State
+ * \{ */
+
void GHOST_NDOFManager::updateTranslation(const int t[3], uint64_t time)
{
- memcpy(m_translation, t, sizeof(m_translation));
- m_motionTime = time;
- m_motionEventPending = true;
+ memcpy(translation_, t, sizeof(translation_));
+ motion_time_ = time;
+ motion_event_pending_ = true;
}
void GHOST_NDOFManager::updateRotation(const int r[3], uint64_t time)
{
- memcpy(m_rotation, r, sizeof(m_rotation));
- m_motionTime = time;
- m_motionEventPending = true;
+ memcpy(rotation_, r, sizeof(rotation_));
+ motion_time_ = time;
+ motion_event_pending_ = true;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name NDOF Buttons
+ * \{ */
+
+static CLG_LogRef LOG_NDOF_BUTTONS = {"ghost.ndof.buttons"};
+#define LOG (&LOG_NDOF_BUTTONS)
+
+static GHOST_TKey ghost_map_keyboard_from_ndof_buttom(const NDOF_ButtonT button)
+{
+ switch (button) {
+ case NDOF_BUTTON_ESC: {
+ return GHOST_kKeyEsc;
+ }
+ case NDOF_BUTTON_ENTER: {
+ return GHOST_kKeyEnter;
+ }
+ case NDOF_BUTTON_DELETE: {
+ return GHOST_kKeyDelete;
+ }
+ case NDOF_BUTTON_TAB: {
+ return GHOST_kKeyTab;
+ }
+ case NDOF_BUTTON_SPACE: {
+ return GHOST_kKeySpace;
+ }
+ case NDOF_BUTTON_ALT: {
+ return GHOST_kKeyLeftAlt;
+ }
+ case NDOF_BUTTON_SHIFT: {
+ return GHOST_kKeyLeftShift;
+ }
+ case NDOF_BUTTON_CTRL: {
+ return GHOST_kKeyLeftControl;
+ }
+ default: {
+ return GHOST_kKeyUnknown;
+ }
+ }
}
void GHOST_NDOFManager::sendButtonEvent(NDOF_ButtonT button,
@@ -286,7 +415,7 @@ void GHOST_NDOFManager::sendButtonEvent(NDOF_ButtonT button,
uint64_t time,
GHOST_IWindow *window)
{
- GHOST_ASSERT(button > NDOF_BUTTON_NONE && button < NDOF_BUTTON_LAST,
+ GHOST_ASSERT(button > NDOF_BUTTON_NONE && button < NDOF_BUTTON_NUM,
"rogue button trying to escape NDOF manager");
GHOST_EventNDOFButton *event = new GHOST_EventNDOFButton(time, window);
@@ -295,11 +424,7 @@ void GHOST_NDOFManager::sendButtonEvent(NDOF_ButtonT button,
data->action = press ? GHOST_kPress : GHOST_kRelease;
data->button = button;
-#ifdef DEBUG_NDOF_BUTTONS
- printf("%s %s\n", ndof_button_names[button], press ? "pressed" : "released");
-#endif
-
- m_system.pushEvent(event);
+ system_.pushEvent(event);
}
void GHOST_NDOFManager::sendKeyEvent(GHOST_TKey key,
@@ -310,62 +435,59 @@ void GHOST_NDOFManager::sendKeyEvent(GHOST_TKey key,
GHOST_TEventType type = press ? GHOST_kEventKeyDown : GHOST_kEventKeyUp;
GHOST_EventKey *event = new GHOST_EventKey(time, type, window, key, false);
-#ifdef DEBUG_NDOF_BUTTONS
- printf("keyboard %s\n", press ? "down" : "up");
-#endif
-
- m_system.pushEvent(event);
+ system_.pushEvent(event);
}
void GHOST_NDOFManager::updateButton(int button_number, bool press, uint64_t time)
{
- GHOST_IWindow *window = m_system.getWindowManager()->getActiveWindow();
-
-#ifdef DEBUG_NDOF_BUTTONS
- printf("ndof: button %d -> ", button_number);
-#endif
-
- NDOF_ButtonT button = (button_number < m_buttonCount) ? m_hidMap[button_number] :
- NDOF_BUTTON_NONE;
+ if (button_number >= hid_map_button_num_) {
+ CLOG_INFO(LOG,
+ 2,
+ "button=%d, press=%d (out of range %d, ignoring!)",
+ button_number,
+ (int)press,
+ hid_map_button_num_);
+ return;
+ }
+ const NDOF_ButtonT button = hid_map_[button_number];
+ if (button == NDOF_BUTTON_NONE) {
+ CLOG_INFO(
+ LOG, 2, "button=%d, press=%d (mapped to none, ignoring!)", button_number, (int)press);
+ return;
+ }
- switch (button) {
- case NDOF_BUTTON_NONE:
-#ifdef DEBUG_NDOF_BUTTONS
- printf("discarded\n");
-#endif
- break;
- case NDOF_BUTTON_ESC:
- sendKeyEvent(GHOST_kKeyEsc, press, time, window);
- break;
- case NDOF_BUTTON_ALT:
- sendKeyEvent(GHOST_kKeyLeftAlt, press, time, window);
- break;
- case NDOF_BUTTON_SHIFT:
- sendKeyEvent(GHOST_kKeyLeftShift, press, time, window);
- break;
- case NDOF_BUTTON_CTRL:
- sendKeyEvent(GHOST_kKeyLeftControl, press, time, window);
- break;
- default:
- sendButtonEvent(button, press, time, window);
+ CLOG_INFO(LOG,
+ 2,
+ "button=%d, press=%d, name=%s",
+ button_number,
+ (int)press,
+ ndof_button_names[button]);
+
+ GHOST_IWindow *window = system_.getWindowManager()->getActiveWindow();
+ const GHOST_TKey key = ghost_map_keyboard_from_ndof_buttom(button);
+ if (key != GHOST_kKeyUnknown) {
+ sendKeyEvent(key, press, time, window);
+ }
+ else {
+ sendButtonEvent(button, press, time, window);
}
int mask = 1 << button_number;
if (press) {
- m_buttons |= mask; /* Set this button's bit. */
+ button_depressed_ |= mask; /* Set this button's bit. */
}
else {
- m_buttons &= ~mask; /* Clear this button's bit. */
+ button_depressed_ &= ~mask; /* Clear this button's bit. */
}
}
void GHOST_NDOFManager::updateButtons(int button_bits, uint64_t time)
{
- button_bits &= m_buttonMask; /* Discard any "garbage" bits. */
+ button_bits &= hid_map_button_mask_; /* Discard any "garbage" bits. */
- int diff = m_buttons ^ button_bits;
+ int diff = button_depressed_ ^ button_bits;
- for (int button_number = 0; button_number < m_buttonCount; ++button_number) {
+ for (int button_number = 0; button_number < hid_map_button_num_; ++button_number) {
int mask = 1 << button_number;
if (diff & mask) {
@@ -375,19 +497,27 @@ void GHOST_NDOFManager::updateButtons(int button_bits, uint64_t time)
}
}
+#undef LOG
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name NDOF Motion
+ * \{ */
+
+static CLG_LogRef LOG_NDOF_MOTION = {"ghost.ndof.motion"};
+#define LOG (&LOG_NDOF_MOTION)
+
void GHOST_NDOFManager::setDeadZone(float dz)
{
if (dz < 0.0f) {
/* Negative values don't make sense, so clamp at zero. */
dz = 0.0f;
}
- else if (dz > 0.5f) {
- /* Warn the rogue user/developer, but allow it. */
- GHOST_PRINTF("ndof: dead zone of %.2f is rather high...\n", dz);
- }
- m_deadZone = dz;
+ motion_dead_zone_ = dz;
- GHOST_PRINTF("ndof: dead zone set to %.2f\n", dz);
+ /* Warn the rogue user/developer about high dead-zone, but allow it. */
+ CLOG_INFO(LOG, 2, "dead zone set to %.2f%s", dz, (dz > 0.5f) ? " (unexpectedly high)" : "");
}
static bool atHomePosition(GHOST_TEventNDOFMotionData *ndof)
@@ -402,29 +532,27 @@ static bool nearHomePosition(GHOST_TEventNDOFMotionData *ndof, float threshold)
if (threshold == 0.0f) {
return atHomePosition(ndof);
}
- else {
#define HOME(foo) (fabsf(ndof->foo) < threshold)
- return HOME(tx) && HOME(ty) && HOME(tz) && HOME(rx) && HOME(ry) && HOME(rz);
+ return HOME(tx) && HOME(ty) && HOME(tz) && HOME(rx) && HOME(ry) && HOME(rz);
#undef HOME
- }
}
bool GHOST_NDOFManager::sendMotionEvent()
{
- if (!m_motionEventPending) {
+ if (!motion_event_pending_) {
return false;
}
- m_motionEventPending = false; /* Any pending motion is handled right now. */
+ motion_event_pending_ = false; /* Any pending motion is handled right now. */
- GHOST_IWindow *window = m_system.getWindowManager()->getActiveWindow();
+ GHOST_IWindow *window = system_.getWindowManager()->getActiveWindow();
- if (window == NULL) {
- m_motionState = GHOST_kNotStarted; /* Avoid large `dt` times when changing windows. */
+ if (window == nullptr) {
+ motion_state_ = GHOST_kNotStarted; /* Avoid large `dt` times when changing windows. */
return false; /* Delivery will fail, so don't bother sending. */
}
- GHOST_EventNDOFMotion *event = new GHOST_EventNDOFMotion(m_motionTime, window);
+ GHOST_EventNDOFMotion *event = new GHOST_EventNDOFMotion(motion_time_, window);
GHOST_TEventNDOFMotionData *data = (GHOST_TEventNDOFMotionData *)event->getData();
/* Scale axis values here to normalize them to around +/- 1
@@ -432,76 +560,82 @@ bool GHOST_NDOFManager::sendMotionEvent()
const float scale = 1.0f / 350.0f; /* 3Dconnexion devices send +/- 350 usually */
- data->tx = scale * m_translation[0];
- data->ty = scale * m_translation[1];
- data->tz = scale * m_translation[2];
-
- data->rx = scale * m_rotation[0];
- data->ry = scale * m_rotation[1];
- data->rz = scale * m_rotation[2];
+ data->tx = scale * translation_[0];
+ data->ty = scale * translation_[1];
+ data->tz = scale * translation_[2];
- data->dt = 0.001f * (m_motionTime - m_prevMotionTime); /* In seconds. */
- m_prevMotionTime = m_motionTime;
+ data->rx = scale * rotation_[0];
+ data->ry = scale * rotation_[1];
+ data->rz = scale * rotation_[2];
+ data->dt = 0.001f * (motion_time_ - motion_time_prev_); /* In seconds. */
+ motion_time_prev_ = motion_time_;
- bool weHaveMotion = !nearHomePosition(data, m_deadZone);
+ bool weHaveMotion = !nearHomePosition(data, motion_dead_zone_);
/* Determine what kind of motion event to send `(Starting, InProgress, Finishing)`
* and where that leaves this NDOF manager `(NotStarted, InProgress, Finished)`. */
- switch (m_motionState) {
+ switch (motion_state_) {
case GHOST_kNotStarted:
- case GHOST_kFinished:
+ case GHOST_kFinished: {
if (weHaveMotion) {
data->progress = GHOST_kStarting;
- m_motionState = GHOST_kInProgress;
+ motion_state_ = GHOST_kInProgress;
/* Previous motion time will be ancient, so just make up a reasonable time delta. */
data->dt = 0.0125f;
}
else {
/* Send no event and keep current state. */
-#ifdef DEBUG_NDOF_MOTION
- printf("ndof motion ignored -- %s\n", progress_string[data->progress]);
-#endif
+ CLOG_INFO(LOG, 2, "motion ignored");
delete event;
return false;
}
break;
- case GHOST_kInProgress:
+ }
+ case GHOST_kInProgress: {
if (weHaveMotion) {
data->progress = GHOST_kInProgress;
/* Remain 'InProgress'. */
}
else {
data->progress = GHOST_kFinishing;
- m_motionState = GHOST_kFinished;
+ motion_state_ = GHOST_kFinished;
}
break;
- default:
+ }
+ default: {
/* Will always be one of the above. */
break;
+ }
}
-#ifdef DEBUG_NDOF_MOTION
- printf("ndof motion sent -- %s\n", progress_string[data->progress]);
-
- /* Show details about this motion event. */
- printf(" T=(%d,%d,%d) R=(%d,%d,%d) raw\n",
- m_translation[0],
- m_translation[1],
- m_translation[2],
- m_rotation[0],
- m_rotation[1],
- m_rotation[2]);
- printf(" T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f\n",
- data->tx,
- data->ty,
- data->tz,
- data->rx,
- data->ry,
- data->rz,
- data->dt);
+#if 1
+ CLOG_INFO(LOG,
+ 2,
+ "motion sent, T=(%.2f,%.2f,%.2f), R=(%.2f,%.2f,%.2f) dt=%.3f, status=%s",
+ data->tx,
+ data->ty,
+ data->tz,
+ data->rx,
+ data->ry,
+ data->rz,
+ data->dt,
+ ndof_progress_string[data->progress]);
+#else
+ /* Raw values, may be useful for debugging. */
+ CLOG_INFO(LOG,
+ 2,
+ "motion sent, T=(%d,%d,%d) R=(%d,%d,%d) status=%s",
+ translation_[0],
+ translation_[1],
+ translation_[2],
+ rotation_[0],
+ rotation_[1],
+ rotation_[2],
+ ndof_progress_string[data->progress]);
#endif
-
- m_system.pushEvent(event);
+ system_.pushEvent(event);
return true;
}
+
+/** \} */
diff --git a/intern/ghost/intern/GHOST_NDOFManager.h b/intern/ghost/intern/GHOST_NDOFManager.h
index d49e6326722..2d5bba14aa4 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.h
+++ b/intern/ghost/intern/GHOST_NDOFManager.h
@@ -8,11 +8,8 @@
#include "GHOST_System.h"
-// #define DEBUG_NDOF_MOTION
-// #define DEBUG_NDOF_BUTTONS
-
typedef enum {
- NDOF_UnknownDevice,
+ NDOF_UnknownDevice = 0,
/* Current devices. */
NDOF_SpaceNavigator,
@@ -32,8 +29,8 @@ typedef enum {
/* NDOF device button event types */
typedef enum {
- /* Used internally, never sent. */
- NDOF_BUTTON_NONE,
+ /* Used internally, never sent or used as an index. */
+ NDOF_BUTTON_NONE = -1,
/* These two are available from any 3Dconnexion device. */
NDOF_BUTTON_MENU,
NDOF_BUTTON_FIT,
@@ -61,11 +58,6 @@ typedef enum {
NDOF_BUTTON_DOMINANT,
NDOF_BUTTON_PLUS,
NDOF_BUTTON_MINUS,
- /* Keyboard emulation. */
- NDOF_BUTTON_ESC,
- NDOF_BUTTON_ALT,
- NDOF_BUTTON_SHIFT,
- NDOF_BUTTON_CTRL,
/* General-purpose buttons.
* Users can assign functions via keymap editor. */
NDOF_BUTTON_1,
@@ -82,8 +74,20 @@ typedef enum {
NDOF_BUTTON_A,
NDOF_BUTTON_B,
NDOF_BUTTON_C,
- /* The end. */
- NDOF_BUTTON_LAST
+ /* Store Views. */
+ NDOF_BUTTON_V1,
+ NDOF_BUTTON_V2,
+ NDOF_BUTTON_V3,
+ /* Keyboard emulation. */
+ NDOF_BUTTON_ESC,
+ NDOF_BUTTON_ENTER,
+ NDOF_BUTTON_DELETE,
+ NDOF_BUTTON_TAB,
+ NDOF_BUTTON_SPACE,
+ NDOF_BUTTON_ALT,
+ NDOF_BUTTON_SHIFT,
+ NDOF_BUTTON_CTRL,
+#define NDOF_BUTTON_NUM (NDOF_BUTTON_CTRL + 1)
} NDOF_ButtonT;
class GHOST_NDOFManager {
@@ -143,25 +147,25 @@ class GHOST_NDOFManager {
bool sendMotionEvent();
protected:
- GHOST_System &m_system;
+ GHOST_System &system_;
private:
void sendButtonEvent(NDOF_ButtonT, bool press, uint64_t time, GHOST_IWindow *);
void sendKeyEvent(GHOST_TKey, bool press, uint64_t time, GHOST_IWindow *);
- NDOF_DeviceT m_deviceType;
- int m_buttonCount;
- int m_buttonMask;
- const NDOF_ButtonT *m_hidMap;
+ NDOF_DeviceT device_type_;
+ int hid_map_button_num_;
+ int hid_map_button_mask_;
+ const NDOF_ButtonT *hid_map_;
- int m_translation[3];
- int m_rotation[3];
- int m_buttons; /* Bit field. */
+ int translation_[3];
+ int rotation_[3];
+ int button_depressed_; /* Bit field. */
- uint64_t m_motionTime; /* In milliseconds. */
- uint64_t m_prevMotionTime; /* Time of most recent motion event sent. */
+ uint64_t motion_time_; /* In milliseconds. */
+ uint64_t motion_time_prev_; /* Time of most recent motion event sent. */
- GHOST_TProgress m_motionState;
- bool m_motionEventPending;
- float m_deadZone; /* Discard motion with each component < this. */
+ GHOST_TProgress motion_state_;
+ bool motion_event_pending_;
+ float motion_dead_zone_; /* Discard motion with each component < this. */
};
diff --git a/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp b/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp
index 7770f5f39ce..0ccf4dc9bfb 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp
@@ -10,7 +10,7 @@
#define SPNAV_SOCK_PATH "/var/run/spnav.sock"
GHOST_NDOFManagerUnix::GHOST_NDOFManagerUnix(GHOST_System &sys)
- : GHOST_NDOFManager(sys), m_available(false)
+ : GHOST_NDOFManager(sys), available_(false)
{
if (access(SPNAV_SOCK_PATH, F_OK) != 0) {
#ifdef DEBUG
@@ -20,7 +20,7 @@ GHOST_NDOFManagerUnix::GHOST_NDOFManagerUnix(GHOST_System &sys)
#endif
}
else if (spnav_open() != -1) {
- m_available = true;
+ available_ = true;
/* determine exactly which device (if any) is plugged in */
@@ -31,7 +31,7 @@ GHOST_NDOFManagerUnix::GHOST_NDOFManagerUnix(GHOST_System &sys)
if (command_output) {
char line[MAX_LINE_LENGTH] = {0};
while (fgets(line, MAX_LINE_LENGTH, command_output)) {
- unsigned short vendor_id = 0, product_id = 0;
+ ushort vendor_id = 0, product_id = 0;
if (sscanf(line, "Bus %*d Device %*d: ID %hx:%hx", &vendor_id, &product_id) == 2) {
if (setDevice(vendor_id, product_id)) {
break; /* stop looking once the first 3D mouse is found */
@@ -45,14 +45,14 @@ GHOST_NDOFManagerUnix::GHOST_NDOFManagerUnix(GHOST_System &sys)
GHOST_NDOFManagerUnix::~GHOST_NDOFManagerUnix()
{
- if (m_available) {
+ if (available_) {
spnav_close();
}
}
bool GHOST_NDOFManagerUnix::available()
{
- return m_available;
+ return available_;
}
/*
@@ -74,7 +74,7 @@ bool GHOST_NDOFManagerUnix::processEvents()
{
bool anyProcessed = false;
- if (m_available) {
+ if (available_) {
spnav_event e;
#ifdef USE_FINISH_GLITCH_WORKAROUND
@@ -85,9 +85,9 @@ bool GHOST_NDOFManagerUnix::processEvents()
switch (e.type) {
case SPNAV_EVENT_MOTION: {
/* convert to blender view coords */
- uint64_t now = m_system.getMilliSeconds();
- const int t[3] = {(int)e.motion.x, (int)e.motion.y, (int)-e.motion.z};
- const int r[3] = {(int)-e.motion.rx, (int)-e.motion.ry, (int)e.motion.rz};
+ uint64_t now = system_.getMilliSeconds();
+ const int t[3] = {int(e.motion.x), int(e.motion.y), int(-e.motion.z)};
+ const int r[3] = {int(-e.motion.rx), int(-e.motion.ry), int(e.motion.rz)};
updateTranslation(t, now);
updateRotation(r, now);
@@ -97,7 +97,7 @@ bool GHOST_NDOFManagerUnix::processEvents()
break;
}
case SPNAV_EVENT_BUTTON:
- uint64_t now = m_system.getMilliSeconds();
+ uint64_t now = system_.getMilliSeconds();
updateButton(e.button.bnum, e.button.press, now);
break;
}
@@ -106,7 +106,7 @@ bool GHOST_NDOFManagerUnix::processEvents()
#ifdef USE_FINISH_GLITCH_WORKAROUND
if (motion_test_prev == true && motion_test == false) {
- uint64_t now = m_system.getMilliSeconds();
+ uint64_t now = system_.getMilliSeconds();
const int v[3] = {0, 0, 0};
updateTranslation(v, now);
diff --git a/intern/ghost/intern/GHOST_NDOFManagerUnix.h b/intern/ghost/intern/GHOST_NDOFManagerUnix.h
index fd603e3cb54..2b98fad974f 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerUnix.h
+++ b/intern/ghost/intern/GHOST_NDOFManagerUnix.h
@@ -15,5 +15,5 @@ class GHOST_NDOFManagerUnix : public GHOST_NDOFManager {
bool processEvents();
private:
- bool m_available;
+ bool available_;
};
diff --git a/intern/ghost/intern/GHOST_PathUtils.cpp b/intern/ghost/intern/GHOST_PathUtils.cpp
index 3b57480039a..2161708fb3c 100644
--- a/intern/ghost/intern/GHOST_PathUtils.cpp
+++ b/intern/ghost/intern/GHOST_PathUtils.cpp
@@ -25,19 +25,19 @@ using DecodeState_e = enum DecodeState_e {
void GHOST_URL_decode(char *buf_dst, int buf_dst_size, const char *buf_src)
{
- const unsigned int buf_src_len = strlen(buf_src);
+ const uint buf_src_len = strlen(buf_src);
DecodeState_e state = STATE_SEARCH;
- unsigned int ascii_character;
+ uint ascii_character;
char temp_num_buf[3] = {0};
memset(buf_dst, 0, buf_dst_size);
- for (unsigned int i = 0; i < buf_src_len; i++) {
+ for (uint i = 0; i < buf_src_len; i++) {
switch (state) {
case STATE_SEARCH: {
if (buf_src[i] != '%') {
strncat(buf_dst, &buf_src[i], 1);
- assert((int)strlen(buf_dst) < buf_dst_size);
+ assert(int(strlen(buf_dst)) < buf_dst_size);
break;
}
@@ -71,7 +71,7 @@ void GHOST_URL_decode(char *buf_dst, int buf_dst_size, const char *buf_src)
sscanf(temp_num_buf, "%x", &ascii_character);
/* Ensure we aren't going to overflow. */
- assert((int)strlen(buf_dst) < buf_dst_size);
+ assert(int(strlen(buf_dst)) < buf_dst_size);
/* Concatenate this character onto the output. */
strncat(buf_dst, (char *)&ascii_character, 1);
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index bfb7c958048..670ede35989 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -8,7 +8,7 @@
#include "GHOST_System.h"
#include <chrono>
-#include <cstdio> /* just for printf */
+#include <cstdio> /* Just for #printf. */
#include "GHOST_DisplayManager.h"
#include "GHOST_EventManager.h"
@@ -30,6 +30,7 @@ GHOST_System::GHOST_System()
#ifdef WITH_INPUT_NDOF
m_ndofManager(0),
#endif
+ m_multitouchGestures(true),
m_tabletAPI(GHOST_kTabletAutomatic),
m_is_debug_enabled(false)
{
@@ -305,6 +306,11 @@ GHOST_TSuccess GHOST_System::getButtonState(GHOST_TButton mask, bool &isDown) co
return success;
}
+void GHOST_System::setMultitouchGestures(const bool use)
+{
+ m_multitouchGestures = use;
+}
+
void GHOST_System::setTabletAPI(GHOST_TTabletAPI api)
{
m_tabletAPI = api;
@@ -378,6 +384,7 @@ GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window,
if (stereoVisual) {
glSettings.flags |= GHOST_glStereoVisual;
}
+ glSettings.context_type = GHOST_kDrawingContextTypeOpenGL;
/* NOTE: don't use #getCurrentDisplaySetting() because on X11 we may
* be zoomed in and the desktop may be bigger than the viewport. */
GHOST_ASSERT(m_displayManager,
@@ -389,7 +396,6 @@ GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window,
settings.xPixels,
settings.yPixels,
GHOST_kWindowStateNormal,
- GHOST_kDrawingContextTypeOpenGL,
glSettings,
true /* exclusive */);
return (*window == nullptr) ? GHOST_kFailure : GHOST_kSuccess;
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index 8c51b3421b2..924a4bff790 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -76,7 +76,7 @@ class GHOST_System : public GHOST_ISystem {
GHOST_ITimerTask *installTimer(uint64_t delay,
uint64_t interval,
GHOST_TimerProcPtr timerProc,
- GHOST_TUserDataPtr userData = NULL);
+ GHOST_TUserDataPtr userData = nullptr);
/**
* Removes a timer.
@@ -123,7 +123,7 @@ class GHOST_System : public GHOST_ISystem {
const bool stereoVisual);
/**
- * Updates the resolution while in fullscreen mode.
+ * Updates the resolution while in full-screen mode.
* \param setting: The new setting of the display.
* \param window: Window displayed in full screen.
*
@@ -240,6 +240,12 @@ class GHOST_System : public GHOST_ISystem {
GHOST_TSuccess getButtonState(GHOST_TButton mask, bool &isDown) const;
/**
+ * Enable multi-touch gestures if supported.
+ * \param use: Enable or disable.
+ */
+ void setMultitouchGestures(const bool use);
+
+ /**
* Set which tablet API to use. Only affects Windows, other platforms have a single API.
* \param api: Enum indicating which API to use.
*/
@@ -369,7 +375,7 @@ class GHOST_System : public GHOST_ISystem {
virtual GHOST_TSuccess exit();
/**
- * Creates a fullscreen window.
+ * Creates a full-screen window.
* \param window: The window created.
* \return Indication of success.
*/
@@ -399,9 +405,12 @@ class GHOST_System : public GHOST_ISystem {
GHOST_EventPrinter *m_eventPrinter;
#endif // WITH_GHOST_DEBUG
- /** Settings of the display before the display went fullscreen. */
+ /** Settings of the display before the display went full-screen. */
GHOST_DisplaySetting m_preFullScreenSetting;
+ /* Use multi-touch gestures? */
+ bool m_multitouchGestures;
+
/** Which tablet API to use. */
GHOST_TTabletAPI m_tabletAPI;
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
index a9e659d3565..0211694aad4 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h
@@ -77,9 +77,8 @@ class GHOST_SystemCocoa : public GHOST_System {
* \param width: The width the window.
* \param height: The height the window.
* \param state: The state of the window when opened.
- * \param type: The type of drawing context installed in this window.
* \param glSettings: Misc OpenGL settings.
- * \param exclusive: Use to show the window ontop and ignore others (used fullscreen).
+ * \param exclusive: Use to show the window on top and ignore others (used full-screen).
* \param parentWindow: Parent (embedder) window.
* \return The new window (or 0 if creation failed).
*/
@@ -89,7 +88,6 @@ class GHOST_SystemCocoa : public GHOST_System {
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
GHOST_GLSettings glSettings,
const bool exclusive = false,
const bool is_dialog = false,
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index c247ef3daa0..a1016dd4843 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -689,7 +689,6 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title,
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
GHOST_GLSettings glSettings,
const bool exclusive,
const bool is_dialog,
@@ -719,7 +718,7 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title,
width,
height,
state,
- type,
+ glSettings.context_type,
glSettings.flags & GHOST_glStereoVisual,
glSettings.flags & GHOST_glDebugContext,
is_dialog,
@@ -751,7 +750,7 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title,
*/
GHOST_IContext *GHOST_SystemCocoa::createOffscreenContext(GHOST_GLSettings glSettings)
{
- GHOST_Context *context = new GHOST_ContextCGL(false, NULL, NULL, NULL);
+ GHOST_Context *context = new GHOST_ContextCGL(false, NULL, NULL, NULL, glSettings.context_type);
if (context->initializeDrawingContext())
return context;
else
@@ -856,7 +855,7 @@ GHOST_TSuccess GHOST_SystemCocoa::setMouseCursorPosition(int32_t x, int32_t y)
GHOST_TSuccess GHOST_SystemCocoa::getModifierKeys(GHOST_ModifierKeys &keys) const
{
- keys.set(GHOST_kModifierKeyOS, (m_modifierMask & NSEventModifierFlagCommand) ? true : false);
+ keys.set(GHOST_kModifierKeyLeftOS, (m_modifierMask & NSEventModifierFlagCommand) ? true : false);
keys.set(GHOST_kModifierKeyLeftAlt, (m_modifierMask & NSEventModifierFlagOption) ? true : false);
keys.set(GHOST_kModifierKeyLeftShift,
(m_modifierMask & NSEventModifierFlagShift) ? true : false);
@@ -1020,7 +1019,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleApplicationBecomeActiveEvent()
(modifiers & NSEventModifierFlagCommand) ? GHOST_kEventKeyDown :
GHOST_kEventKeyUp,
window,
- GHOST_kKeyOS,
+ GHOST_kKeyLeftOS,
false));
}
@@ -1123,6 +1122,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
case GHOST_kEventDraggingEntered:
case GHOST_kEventDraggingUpdated:
case GHOST_kEventDraggingExited:
+ window->clientToScreenIntern(mouseX, mouseY, mouseX, mouseY);
pushEvent(new GHOST_EventDragnDrop(
getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, NULL));
break;
@@ -1331,6 +1331,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
return GHOST_kFailure;
break;
}
+
+ window->clientToScreenIntern(mouseX, mouseY, mouseX, mouseY);
pushEvent(new GHOST_EventDragnDrop(
getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, eventData));
@@ -1678,7 +1680,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
/* we assume phases are only set for gestures from trackpad or magic
* mouse events. note that using tablet at the same time may not work
* since this is a static variable */
- if (phase == NSEventPhaseBegan)
+ if (phase == NSEventPhaseBegan && m_multitouchGestures)
m_multiTouchScroll = true;
else if (phase == NSEventPhaseEnded)
m_multiTouchScroll = false;
@@ -1898,7 +1900,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
[event timestamp] * 1000,
(modifiers & NSEventModifierFlagCommand) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp,
window,
- GHOST_kKeyOS,
+ GHOST_kKeyLeftOS,
false));
}
diff --git a/intern/ghost/intern/GHOST_SystemHeadless.h b/intern/ghost/intern/GHOST_SystemHeadless.h
index b02a82fc9eb..66af65f763d 100644
--- a/intern/ghost/intern/GHOST_SystemHeadless.h
+++ b/intern/ghost/intern/GHOST_SystemHeadless.h
@@ -142,7 +142,6 @@ class GHOST_SystemHeadless : public GHOST_System {
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
GHOST_GLSettings glSettings,
const bool /*exclusive*/,
const bool /*is_dialog*/,
@@ -155,7 +154,7 @@ class GHOST_SystemHeadless : public GHOST_System {
height,
state,
parentWindow,
- type,
+ glSettings.context_type,
((glSettings.flags & GHOST_glStereoVisual) != 0));
}
diff --git a/intern/ghost/intern/GHOST_SystemPathsUnix.cpp b/intern/ghost/intern/GHOST_SystemPathsUnix.cpp
index 41babc5d312..7e1d3d868c6 100644
--- a/intern/ghost/intern/GHOST_SystemPathsUnix.cpp
+++ b/intern/ghost/intern/GHOST_SystemPathsUnix.cpp
@@ -5,22 +5,17 @@
* \ingroup GHOST
*/
-#include <cstdio>
#include <sstream>
#include "GHOST_SystemPathsUnix.h"
#include "GHOST_Debug.h"
-// For timing
-
+/* For timing. */
#include <sys/time.h>
#include <unistd.h>
-#include <cstdio> /* for fprintf only */
-#include <cstdlib> /* for exit */
-
-#include <pwd.h> /* for get home without use getenv() */
+#include <pwd.h> /* For get home without use `getenv()`. */
#include <string>
using std::string;
diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp
index 6d0b2b8aa55..9174664adc4 100644
--- a/intern/ghost/intern/GHOST_SystemSDL.cpp
+++ b/intern/ghost/intern/GHOST_SystemSDL.cpp
@@ -42,7 +42,6 @@ GHOST_IWindow *GHOST_SystemSDL::createWindow(const char *title,
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
GHOST_GLSettings glSettings,
const bool exclusive,
const bool /* is_dialog */,
@@ -57,7 +56,7 @@ GHOST_IWindow *GHOST_SystemSDL::createWindow(const char *title,
width,
height,
state,
- type,
+ glSettings.context_type,
((glSettings.flags & GHOST_glStereoVisual) != 0),
exclusive,
parentWindow);
@@ -161,7 +160,8 @@ GHOST_TSuccess GHOST_SystemSDL::getModifierKeys(GHOST_ModifierKeys &keys) const
keys.set(GHOST_kModifierKeyRightControl, (mod & KMOD_RCTRL) != 0);
keys.set(GHOST_kModifierKeyLeftAlt, (mod & KMOD_LALT) != 0);
keys.set(GHOST_kModifierKeyRightAlt, (mod & KMOD_RALT) != 0);
- keys.set(GHOST_kModifierKeyOS, (mod & (KMOD_LGUI | KMOD_RGUI)) != 0);
+ keys.set(GHOST_kModifierKeyLeftOS, (mod & KMOD_LGUI) != 0);
+ keys.set(GHOST_kModifierKeyRightOS, (mod & KMOD_RGUI) != 0);
return GHOST_kSuccess;
}
@@ -219,8 +219,8 @@ static GHOST_TKey convertSDLKey(SDL_Scancode key)
GXMAP(type, SDL_SCANCODE_RCTRL, GHOST_kKeyRightControl);
GXMAP(type, SDL_SCANCODE_LALT, GHOST_kKeyLeftAlt);
GXMAP(type, SDL_SCANCODE_RALT, GHOST_kKeyRightAlt);
- GXMAP(type, SDL_SCANCODE_LGUI, GHOST_kKeyOS);
- GXMAP(type, SDL_SCANCODE_RGUI, GHOST_kKeyOS);
+ GXMAP(type, SDL_SCANCODE_LGUI, GHOST_kKeyLeftOS);
+ GXMAP(type, SDL_SCANCODE_RGUI, GHOST_kKeyRightOS);
GXMAP(type, SDL_SCANCODE_APPLICATION, GHOST_kKeyApp);
GXMAP(type, SDL_SCANCODE_INSERT, GHOST_kKeyInsert);
@@ -412,7 +412,7 @@ static char convert_keyboard_event_to_ascii(const SDL_KeyboardEvent &sdl_sub_evt
}
}
}
- return (char)sym;
+ return char(sym);
}
/**
diff --git a/intern/ghost/intern/GHOST_SystemSDL.h b/intern/ghost/intern/GHOST_SystemSDL.h
index bee277ba674..385bfb841e3 100644
--- a/intern/ghost/intern/GHOST_SystemSDL.h
+++ b/intern/ghost/intern/GHOST_SystemSDL.h
@@ -71,7 +71,6 @@ class GHOST_SystemSDL : public GHOST_System {
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
GHOST_GLSettings glSettings,
const bool exclusive = false,
const bool is_dialog = false,
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp
index 4c663e98824..528aa6e1884 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.cpp
+++ b/intern/ghost/intern/GHOST_SystemWayland.cpp
@@ -10,6 +10,7 @@
#include "GHOST_EventCursor.h"
#include "GHOST_EventDragnDrop.h"
#include "GHOST_EventKey.h"
+#include "GHOST_EventTrackpad.h"
#include "GHOST_EventWheel.h"
#include "GHOST_PathUtils.h"
#include "GHOST_TimerManager.h"
@@ -50,10 +51,17 @@
/* Generated by `wayland-scanner`. */
#include <pointer-constraints-unstable-v1-client-protocol.h>
+#include <pointer-gestures-unstable-v1-client-protocol.h>
+#include <primary-selection-unstable-v1-client-protocol.h>
#include <relative-pointer-unstable-v1-client-protocol.h>
#include <tablet-unstable-v2-client-protocol.h>
#include <xdg-output-unstable-v1-client-protocol.h>
+/* Decorations `xdg_decor`. */
+#include <xdg-decoration-unstable-v1-client-protocol.h>
+#include <xdg-shell-client-protocol.h>
+/* End `xdg_decor`. */
+
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
@@ -64,10 +72,38 @@
/* Logging, use `ghost.wl.*` prefix. */
#include "CLG_log.h"
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+static bool use_libdecor = true;
+# ifdef WITH_GHOST_WAYLAND_DYNLOAD
+static bool has_libdecor = false;
+# else
+static bool has_libdecor = true;
+# endif
+#endif
+
static void keyboard_handle_key_repeat_cancel(struct GWL_Seat *seat);
static void output_handle_done(void *data, struct wl_output *wl_output);
+static void gwl_seat_capability_pointer_disable(GWL_Seat *seat);
+static void gwl_seat_capability_keyboard_disable(GWL_Seat *seat);
+static void gwl_seat_capability_touch_disable(GWL_Seat *seat);
+
+static bool gwl_registry_entry_remove_by_name(GWL_Display *display,
+ uint32_t name,
+ int *r_interface_slot);
+static void gwl_registry_entry_remove_all(GWL_Display *display);
+
+struct GWL_RegistryHandler;
+static int gwl_registry_handler_interface_slot_max();
+static int gwl_registry_handler_interface_slot_from_string(const char *interface);
+static const struct GWL_RegistryHandler *gwl_registry_handler_from_interface_slot(
+ int interface_slot);
+
+/* -------------------------------------------------------------------- */
+/** \name Workaround Compositor Specific Bugs
+ * \{ */
+
/**
* GNOME (mutter 42.2 had a bug with confine not respecting scale - Hi-DPI), See: T98793.
* Even though this has been fixed, at time of writing it's not yet in a release.
@@ -86,9 +122,53 @@ static void output_handle_done(void *data, struct wl_output *wl_output);
static bool use_gnome_confine_hack = false;
#endif
-#define XKB_STATE_MODS_ALL \
- (enum xkb_state_component)(XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED | \
- XKB_STATE_MODS_LOCKED | XKB_STATE_MODS_EFFECTIVE)
+/**
+ * GNOME (mutter 42.5) doesn't follow the WAYLAND spec regarding keyboard handling,
+ * unlike (other compositors: KDE-plasma, River & Sway which work without problems).
+ *
+ * This means GNOME can't know which modifiers are held when activating windows,
+ * so we guess the left modifiers are held.
+ *
+ * This define could be removed without changing any functionality,
+ * it just means GNOME users will see verbose warning messages that alert them about
+ * a known problem that needs to be fixed up-stream.
+ *
+ * This has been fixed for GNOME 43. Keep the workaround until support for gnome 42 is dropped.
+ * See: https://gitlab.gnome.org/GNOME/mutter/-/issues/2457
+ */
+#define USE_GNOME_KEYBOARD_SUPPRESS_WARNING
+
+/**
+ * KDE (plasma 5.26.1) has a bug where the cursor surface needs to be committed
+ * (via `wl_surface_commit`) when it was hidden and is being set to visible again, see: T102048.
+ * See: https://bugs.kde.org/show_bug.cgi?id=461001
+ */
+#define USE_KDE_TABLET_HIDDEN_CURSOR_HACK
+
+/**
+ * When GNOME is found, require `libdecor`.
+ * This is a hack because it seems there is no way to check if the compositor supports
+ * server side decorations when initializing WAYLAND.
+ */
+#if defined(WITH_GHOST_WAYLAND_LIBDECOR) && defined(WITH_GHOST_X11)
+# define USE_GNOME_NEEDS_LIBDECOR_HACK
+#endif
+
+/* -------------------------------------------------------------------- */
+/** \name Local Defines
+ *
+ * Control local functionality, compositors specific workarounds.
+ * \{ */
+
+/**
+ * Fix short-cut part of keyboard reading code not properly handling some keys, see: T102194.
+ * \note This is similar to X11 workaround by the same name, see: T47228.
+ */
+#define USE_NON_LATIN_KB_WORKAROUND
+
+#define WL_NAME_UNSET uint32_t(-1)
+
+/** \} */
/* -------------------------------------------------------------------- */
/** \name Inline Event Codes
@@ -99,8 +179,7 @@ static bool use_gnome_confine_hack = false;
* \{ */
/**
- * The event codes are used to
- * to differentiate from which mouse button an event comes from.
+ * The event codes are used to differentiate from which mouse button an event comes from.
*/
#define BTN_LEFT 0x110
#define BTN_RIGHT 0x111
@@ -113,9 +192,14 @@ static bool use_gnome_confine_hack = false;
/**
* Tablet events.
+ *
+ * \note Gnome/GTK swap middle/right, where the same application in X11 will swap the middle/right
+ * mouse button when running under WAYLAND. KDE doesn't do this, and according to artists
+ * at the Blender studio, having the button closest to the nib be MMB is preferable,
+ * so use this as a default. If needs be - swapping these could be a preference.
*/
-#define BTN_STYLUS 0x14b /* Use as right-mouse. */
-#define BTN_STYLUS2 0x14c /* Use as middle-mouse. */
+#define BTN_STYLUS 0x14b /* Use as middle-mouse. */
+#define BTN_STYLUS2 0x14c /* Use as right-mouse. */
/* NOTE(@campbellbarton): Map to an additional button (not sure which hardware uses this). */
#define BTN_STYLUS3 0x149
@@ -124,10 +208,114 @@ static bool use_gnome_confine_hack = false;
*/
#define KEY_GRAVE 41
+#ifdef USE_NON_LATIN_KB_WORKAROUND
+# define KEY_1 2
+# define KEY_2 3
+# define KEY_3 4
+# define KEY_4 5
+# define KEY_5 6
+# define KEY_6 7
+# define KEY_7 8
+# define KEY_8 9
+# define KEY_9 10
+# define KEY_0 11
+#endif
+
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Private Types & Defines
+/** \name Modifier Table
+ *
+ * Convenient access to modifier key values, allow looping over modifier keys.
+ * \{ */
+
+enum {
+ MOD_INDEX_SHIFT = 0,
+ MOD_INDEX_ALT = 1,
+ MOD_INDEX_CTRL = 2,
+ MOD_INDEX_OS = 3,
+};
+#define MOD_INDEX_NUM (MOD_INDEX_OS + 1)
+
+struct GWL_ModifierInfo {
+ /** Only for printing messages. */
+ const char *display_name;
+ const char *xkb_id;
+ GHOST_TKey key_l, key_r;
+ GHOST_TModifierKey mod_l, mod_r;
+};
+
+static const GWL_ModifierInfo g_modifier_info_table[MOD_INDEX_NUM] = {
+ /* MOD_INDEX_SHIFT */
+ {
+ /* display_name */ "Shift",
+ /* xkb_id */ XKB_MOD_NAME_SHIFT,
+ /* key_l */ GHOST_kKeyLeftShift,
+ /* key_r */ GHOST_kKeyRightShift,
+ /* mod_l */ GHOST_kModifierKeyLeftShift,
+ /* mod_r */ GHOST_kModifierKeyRightShift,
+ },
+ /* MOD_INDEX_ALT */
+ {
+ /* display_name */ "Alt",
+ /* xkb_id */ XKB_MOD_NAME_ALT,
+ /* key_l */ GHOST_kKeyLeftAlt,
+ /* key_r */ GHOST_kKeyRightAlt,
+ /* mod_l */ GHOST_kModifierKeyLeftAlt,
+ /* mod_r */ GHOST_kModifierKeyRightAlt,
+ },
+ /* MOD_INDEX_CTRL */
+ {
+ /* display_name */ "Control",
+ /* xkb_id */ XKB_MOD_NAME_CTRL,
+ /* key_l */ GHOST_kKeyLeftControl,
+ /* key_r */ GHOST_kKeyRightControl,
+ /* mod_l */ GHOST_kModifierKeyLeftControl,
+ /* mod_r */ GHOST_kModifierKeyRightControl,
+ },
+ /* MOD_INDEX_OS */
+ {
+ /* display_name */ "OS",
+ /* xkb_id */ XKB_MOD_NAME_LOGO,
+ /* key_l */ GHOST_kKeyLeftOS,
+ /* key_r */ GHOST_kKeyRightOS,
+ /* mod_l */ GHOST_kModifierKeyLeftOS,
+ /* mod_r */ GHOST_kModifierKeyRightOS,
+ },
+};
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal #GWL_SimpleBuffer Type
+ * \{ */
+
+struct GWL_SimpleBuffer {
+ /** Constant data, but may be freed. */
+ const char *data = nullptr;
+ size_t data_size = 0;
+};
+
+static void gwl_simple_buffer_free_data(GWL_SimpleBuffer *buffer)
+{
+ free(const_cast<char *>(buffer->data));
+ buffer->data = nullptr;
+ buffer->data_size = 0;
+}
+
+static void gwl_simple_buffer_set_from_string(GWL_SimpleBuffer *buffer, const char *str)
+{
+ free(const_cast<char *>(buffer->data));
+ buffer->data_size = strlen(str);
+ char *data = static_cast<char *>(malloc(buffer->data_size));
+ std::memcpy(data, str, buffer->data_size);
+ buffer->data = data;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal #GWL_Cursor Type
* \{ */
/**
@@ -145,16 +333,26 @@ struct GWL_Cursor {
* the hardware cursor is used.
*/
bool is_hardware = true;
+ /** When true, a custom image is used to display the cursor (stored in `wl_image`). */
bool is_custom = false;
- struct wl_surface *wl_surface = nullptr;
+ struct wl_surface *wl_surface_cursor = nullptr;
struct wl_buffer *wl_buffer = nullptr;
struct wl_cursor_image wl_image = {0};
struct wl_cursor_theme *wl_theme = nullptr;
void *custom_data = nullptr;
+ /** The size of `custom_data` in bytes. */
size_t custom_data_size = 0;
- int size = 0;
+ /**
+ * The name of the theme (loaded by DBUS, depends on #WITH_GHOST_WAYLAND_DBUS).
+ * When disabled, leave as an empty string and the default theme will be used.
+ */
std::string theme_name;
-
+ /**
+ * The size of the cursor (when looking up a cursor theme).
+ * This must be scaled by the maximum output scale when passing to wl_cursor_theme_load.
+ * See #update_cursor_scale.
+ * */
+ int theme_size = 0;
int custom_scale = 1;
};
@@ -165,6 +363,7 @@ struct GWL_Cursor {
*/
struct GWL_TabletTool {
struct GWL_Seat *seat = nullptr;
+ /** Tablets have a separate cursor to the 'pointer', this surface is used for cursor drawing. */
struct wl_surface *wl_surface_cursor = nullptr;
/** Used to delay clearing tablet focused wl_surface until the frame is handled. */
bool proximity = false;
@@ -172,23 +371,55 @@ struct GWL_TabletTool {
GHOST_TabletData data = GHOST_TABLET_DATA_NONE;
};
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal #GWL_DataOffer Type
+ * \{ */
+
+/**
+ * Data storage used for clipboard paste & drag-and-drop.
+ */
struct GWL_DataOffer {
- std::unordered_set<std::string> types;
- uint32_t source_actions = 0;
- uint32_t dnd_action = 0;
struct wl_data_offer *id = nullptr;
- std::atomic<bool> in_use = false;
+ std::unordered_set<std::string> types;
+
struct {
+ /**
+ * Prevents freeing after #wl_data_device_listener.leave,
+ * before #wl_data_device_listener.drop.
+ */
+ bool in_use = false;
+ /**
+ * Bit-mask with available drop options.
+ * #WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY, #WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE.. etc.
+ * The application that initializes the drag may set these depending on modifiers held
+ * \note when dragging begins. Currently ghost doesn't make use of these.
+ */
+ enum wl_data_device_manager_dnd_action source_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
+ enum wl_data_device_manager_dnd_action action = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
/** Compatible with #GWL_Seat.xy coordinates. */
wl_fixed_t xy[2] = {0, 0};
} dnd;
};
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal #GWL_DataSource Type
+ * \{ */
+
struct GWL_DataSource {
- struct wl_data_source *data_source = nullptr;
- char *buffer_out = nullptr;
+ struct wl_data_source *wl_source = nullptr;
+ GWL_SimpleBuffer buffer_out;
};
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal #GWL_Seat Type (#wl_seat wrapper & associated types)
+ * \{ */
+
/**
* Data used to implement client-side key-repeat.
*
@@ -248,12 +479,58 @@ struct GWL_SeatStatePointer {
* The wl_surface last used with this pointing device
* (events with this pointing device will be sent here).
*/
- struct wl_surface *wl_surface = nullptr;
+ struct wl_surface *wl_surface_window = nullptr;
GHOST_Buttons buttons = GHOST_Buttons();
};
/**
+ * Scroll state, applying to pointer (not tablet) events.
+ * Otherwise this would be part of #GWL_SeatStatePointer.
+ */
+struct GWL_SeatStatePointerScroll {
+ /** Smooth scrolling (handled & reset with pointer "frame" callback). */
+ wl_fixed_t smooth_xy[2] = {0, 0};
+ /** Discrete scrolling (handled & reset with pointer "frame" callback). */
+ int32_t discrete_xy[2] = {0, 0};
+ /** The source of scroll event. */
+ enum wl_pointer_axis_source axis_source = WL_POINTER_AXIS_SOURCE_WHEEL;
+};
+
+/**
+ * Utility struct to access rounded values from a scaled `wl_fixed_t`,
+ * without loosing information.
+ *
+ * As the rounded result is rounded to a lower precision integer,
+ * the high precision value is accumulated and converted to an integer to
+ * prevent the accumulation of rounded values giving an inaccurate result.
+ *
+ * \note This is simple but doesn't read well when expanded multiple times inline.
+ */
+struct GWL_ScaledFixedT {
+ wl_fixed_t value = 0;
+ wl_fixed_t factor = 1;
+};
+
+static int gwl_scaled_fixed_t_add_and_calc_rounded_delta(GWL_ScaledFixedT *sf,
+ const wl_fixed_t add)
+{
+ const int result_prev = wl_fixed_to_int(sf->value * sf->factor);
+ sf->value += add;
+ const int result_curr = wl_fixed_to_int(sf->value * sf->factor);
+ return result_curr - result_prev;
+}
+
+/**
+ * Gesture state.
+ * This is needed so the gesture values can be converted to deltas.
+ */
+struct GWL_SeatStatePointerGesture_Pinch {
+ GWL_ScaledFixedT scale;
+ GWL_ScaledFixedT rotation;
+};
+
+/**
* State of the keyboard (in #GWL_Seat).
*/
struct GWL_SeatStateKeyboard {
@@ -264,17 +541,118 @@ struct GWL_SeatStateKeyboard {
* The wl_surface last used with this pointing device
* (events with this pointing device will be sent here).
*/
- struct wl_surface *wl_surface = nullptr;
+ struct wl_surface *wl_surface_window = nullptr;
};
+/**
+ * Store held keys (only modifiers), could store other keys in the future.
+ *
+ * Needed as #GWL_Seat.xkb_state doesn't store which modifier keys are held.
+ */
+struct GWL_KeyboardDepressedState {
+ int16_t mods[GHOST_KEY_MODIFIER_NUM] = {0};
+};
+
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+struct GWL_LibDecor_System {
+ struct libdecor *context = nullptr;
+};
+
+static void gwl_libdecor_system_destroy(GWL_LibDecor_System *decor)
+{
+ if (decor->context) {
+ libdecor_unref(decor->context);
+ decor->context = nullptr;
+ }
+ delete decor;
+}
+#endif
+
+struct GWL_XDG_Decor_System {
+ struct xdg_wm_base *shell = nullptr;
+ uint32_t shell_name = WL_NAME_UNSET;
+
+ struct zxdg_decoration_manager_v1 *manager = nullptr;
+ uint32_t manager_name = WL_NAME_UNSET;
+};
+
+static void gwl_xdg_decor_system_destroy(struct GWL_Display *display, GWL_XDG_Decor_System *decor)
+{
+ if (decor->manager) {
+ gwl_registry_entry_remove_by_name(display, decor->manager_name, nullptr);
+ GHOST_ASSERT(decor->manager == nullptr, "Internal registry error");
+ }
+ if (decor->shell) {
+ gwl_registry_entry_remove_by_name(display, decor->shell_name, nullptr);
+ GHOST_ASSERT(decor->shell == nullptr, "Internal registry error");
+ }
+ delete decor;
+}
+
+struct GWL_PrimarySelection_DataOffer {
+ struct zwp_primary_selection_offer_v1 *id = nullptr;
+
+ std::unordered_set<std::string> types;
+};
+
+struct GWL_PrimarySelection_DataSource {
+ struct zwp_primary_selection_source_v1 *wp_source = nullptr;
+ GWL_SimpleBuffer buffer_out;
+};
+
+/** Primary selection support. */
+struct GWL_PrimarySelection {
+
+ GWL_PrimarySelection_DataSource *data_source = nullptr;
+ std::mutex data_source_mutex;
+
+ GWL_PrimarySelection_DataOffer *data_offer = nullptr;
+ std::mutex data_offer_mutex;
+};
+
+static void gwl_primary_selection_discard_offer(GWL_PrimarySelection *primary)
+{
+ if (primary->data_offer == nullptr) {
+ return;
+ }
+ zwp_primary_selection_offer_v1_destroy(primary->data_offer->id);
+ delete primary->data_offer;
+ primary->data_offer = nullptr;
+}
+
+static void gwl_primary_selection_discard_source(GWL_PrimarySelection *primary)
+{
+ GWL_PrimarySelection_DataSource *data_source = primary->data_source;
+ if (data_source == nullptr) {
+ return;
+ }
+ gwl_simple_buffer_free_data(&data_source->buffer_out);
+ if (data_source->wp_source) {
+ zwp_primary_selection_source_v1_destroy(data_source->wp_source);
+ }
+ delete primary->data_source;
+ primary->data_source = nullptr;
+}
+
struct GWL_Seat {
GHOST_SystemWayland *system = nullptr;
std::string name;
struct wl_seat *wl_seat = nullptr;
struct wl_pointer *wl_pointer = nullptr;
+ struct wl_touch *wl_touch = nullptr;
struct wl_keyboard *wl_keyboard = nullptr;
- struct zwp_tablet_seat_v2 *tablet_seat = nullptr;
+ struct zwp_tablet_seat_v2 *wp_tablet_seat = nullptr;
+
+#ifdef ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE
+ struct zwp_pointer_gesture_hold_v1 *wp_pointer_gesture_hold = nullptr;
+#endif
+#ifdef ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE
+ struct zwp_pointer_gesture_pinch_v1 *wp_pointer_gesture_pinch = nullptr;
+#endif
+#ifdef ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE
+ struct zwp_pointer_gesture_swipe_v1 *wp_pointer_gesture_swipe = nullptr;
+#endif
/** All currently active tablet tools (needed for changing the cursor). */
std::unordered_set<zwp_tablet_tool_v2 *> tablet_tools;
@@ -283,6 +661,8 @@ struct GWL_Seat {
uint32_t cursor_source_serial = 0;
GWL_SeatStatePointer pointer;
+ GWL_SeatStatePointerScroll pointer_scroll;
+ GWL_SeatStatePointerGesture_Pinch pointer_gesture_pinch;
/** Mostly this can be interchanged with `pointer` however it can't be locked/confined. */
GWL_SeatStatePointer tablet;
@@ -297,9 +677,9 @@ struct GWL_Seat {
struct GWL_Cursor cursor;
- struct zwp_relative_pointer_v1 *relative_pointer = nullptr;
- struct zwp_locked_pointer_v1 *locked_pointer = nullptr;
- struct zwp_confined_pointer_v1 *confined_pointer = nullptr;
+ struct zwp_relative_pointer_v1 *wp_relative_pointer = nullptr;
+ struct zwp_locked_pointer_v1 *wp_locked_pointer = nullptr;
+ struct zwp_confined_pointer_v1 *wp_confined_pointer = nullptr;
struct xkb_context *xkb_context = nullptr;
@@ -308,25 +688,38 @@ struct GWL_Seat {
* Keep a state with no modifiers active, use for symbol lookups.
*/
struct xkb_state *xkb_state_empty = nullptr;
+
+ /**
+ * Keep a state with shift enabled, use to access predictable number access for AZERTY keymaps.
+ * If shift is not supported by the key-map, this is set to NULL.
+ */
+ struct xkb_state *xkb_state_empty_with_shift = nullptr;
/**
* Keep a state with number-lock enabled, use to access predictable key-pad symbols.
* If number-lock is not supported by the key-map, this is set to NULL.
*/
struct xkb_state *xkb_state_empty_with_numlock = nullptr;
+#ifdef USE_NON_LATIN_KB_WORKAROUND
+ bool xkb_use_non_latin_workaround = false;
+#endif
+
+ /** Keys held matching `xkb_state`. */
+ struct GWL_KeyboardDepressedState key_depressed;
+
+#ifdef USE_GNOME_KEYBOARD_SUPPRESS_WARNING
+ struct {
+ bool any_mod_held = false;
+ bool any_keys_held_on_enter = false;
+ } key_depressed_suppress_warning;
+#endif
+
/**
* Cache result of `xkb_keymap_mod_get_index`
* so every time a modifier is accessed a string lookup isn't required.
* Be sure to check for #XKB_MOD_INVALID before using.
*/
- struct {
- xkb_mod_index_t shift; /* #XKB_MOD_NAME_SHIFT */
- xkb_mod_index_t caps; /* #XKB_MOD_NAME_CAPS */
- xkb_mod_index_t ctrl; /* #XKB_MOD_NAME_CTRL */
- xkb_mod_index_t alt; /* #XKB_MOD_NAME_ALT */
- xkb_mod_index_t num; /* #XKB_MOD_NAME_NUM */
- xkb_mod_index_t logo; /* #XKB_MOD_NAME_LOGO */
- } xkb_keymap_mod_index;
+ xkb_mod_index_t xkb_keymap_mod_index[MOD_INDEX_NUM];
struct {
/** Key repetition in character per second. */
@@ -337,9 +730,9 @@ struct GWL_Seat {
GHOST_ITimerTask *timer = nullptr;
} key_repeat;
- struct wl_surface *wl_surface_focus_dnd = nullptr;
+ struct wl_surface *wl_surface_window_focus_dnd = nullptr;
- struct wl_data_device *data_device = nullptr;
+ struct wl_data_device *wl_data_device = nullptr;
/** Drag & Drop. */
struct GWL_DataOffer *data_offer_dnd = nullptr;
std::mutex data_offer_dnd_mutex;
@@ -351,210 +744,446 @@ struct GWL_Seat {
struct GWL_DataSource *data_source = nullptr;
std::mutex data_source_mutex;
+ struct zwp_primary_selection_device_v1 *wp_primary_selection_device = nullptr;
+ struct GWL_PrimarySelection primary_selection;
+
/** Last device that was active. */
uint32_t data_source_serial = 0;
};
+static GWL_SeatStatePointer *gwl_seat_state_pointer_active(GWL_Seat *seat)
+{
+ if (seat->pointer.serial == seat->cursor_source_serial) {
+ return &seat->pointer;
+ }
+ if (seat->tablet.serial == seat->cursor_source_serial) {
+ return &seat->tablet;
+ }
+ return nullptr;
+}
+
+static GWL_SeatStatePointer *gwl_seat_state_pointer_from_cursor_surface(
+ GWL_Seat *seat, const wl_surface *wl_surface)
+{
+ if (ghost_wl_surface_own_cursor_pointer(wl_surface)) {
+ return &seat->pointer;
+ }
+ if (ghost_wl_surface_own_cursor_tablet(wl_surface)) {
+ return &seat->tablet;
+ }
+ GHOST_ASSERT(0, "Surface found without pointer/tablet tag");
+ return nullptr;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal #GWL_Display Type (#wl_display & #wl_compositor wrapper)
+ * \{ */
+
+struct GWL_RegistryEntry;
+
struct GWL_Display {
GHOST_SystemWayland *system = nullptr;
- struct wl_display *display = nullptr;
- struct wl_compositor *compositor = nullptr;
+ /**
+ * True when initializing registration, while updating all other entries wont cause problems,
+ * it will preform many redundant update calls.
+ */
+ bool registry_skip_update_all = false;
+
+ /** Registry entries, kept to allow updating & removal at run-time. */
+ struct GWL_RegistryEntry *registry_entry = nullptr;
+
+ struct wl_registry *wl_registry = nullptr;
+ struct wl_display *wl_display = nullptr;
+ struct wl_compositor *wl_compositor = nullptr;
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- struct libdecor *decor_context = nullptr;
-#else
- struct xdg_wm_base *xdg_shell = nullptr;
- struct zxdg_decoration_manager_v1 *xdg_decoration_manager = nullptr;
+ GWL_LibDecor_System *libdecor = nullptr;
+ bool libdecor_required = false;
#endif
+ GWL_XDG_Decor_System *xdg_decor = nullptr;
struct zxdg_output_manager_v1 *xdg_output_manager = nullptr;
- struct wl_shm *shm = nullptr;
+ struct wl_shm *wl_shm = nullptr;
std::vector<GWL_Output *> outputs;
std::vector<GWL_Seat *> seats;
+ /**
+ * Support a single active seat at once, this isn't an exact or correct mapping from WAYLAND.
+ * Only allow input from different seats, not full concurrent multi-seat support.
+ *
+ * The main purpose of having an active seat is an alternative from always using the first
+ * seat which prevents events from any other seat.
+ *
+ * NOTE(@campbellbarton): This could be extended and developed further extended to support
+ * an active seat per window (for e.g.), basic support is sufficient for now as currently isn't
+ * a widely used feature.
+ */
+ int seats_active_index = 0;
- struct wl_data_device_manager *data_device_manager = nullptr;
- struct zwp_tablet_manager_v2 *tablet_manager = nullptr;
- struct zwp_relative_pointer_manager_v1 *relative_pointer_manager = nullptr;
- struct zwp_pointer_constraints_v1 *pointer_constraints = nullptr;
-};
-
-#undef LOG
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Private Utility Functions
- * \{ */
-
-static GHOST_WindowManager *window_manager = nullptr;
+ /* Managers. */
+ struct wl_data_device_manager *wl_data_device_manager = nullptr;
+ struct zwp_tablet_manager_v2 *wp_tablet_manager = nullptr;
+ struct zwp_relative_pointer_manager_v1 *wp_relative_pointer_manager = nullptr;
+ struct zwp_primary_selection_device_manager_v1 *wp_primary_selection_device_manager = nullptr;
-/** Check this lock before accessing `GHOST_SystemWayland::selection` from a thread. */
-static std::mutex system_selection_mutex;
+ struct zwp_pointer_constraints_v1 *wp_pointer_constraints = nullptr;
+ struct zwp_pointer_gestures_v1 *wp_pointer_gestures = nullptr;
+};
/**
- * Callback for WAYLAND to run when there is an error.
+ * Free the #GWL_Display and it's related members.
*
- * \note It's useful to set a break-point on this function as some errors are fatal
- * (for all intents and purposes) but don't crash the process.
+ * \note This may run on a partially initialized struct,
+ * so it can't be assumed all members are set.
*/
-static void ghost_wayland_log_handler(const char *msg, va_list arg)
+static void gwl_display_destroy(GWL_Display *display)
{
- fprintf(stderr, "GHOST/Wayland: ");
- vfprintf(stderr, msg, arg); /* Includes newline. */
+ /* For typical WAYLAND use this will always be set.
+ * However when WAYLAND isn't running, this will early-exit and be null. */
+ if (display->wl_registry) {
+ wl_registry_destroy(display->wl_registry);
+ display->wl_registry = nullptr;
+ }
- GHOST_TBacktraceFn backtrace_fn = GHOST_ISystem::getBacktraceFn();
- if (backtrace_fn) {
- backtrace_fn(stderr); /* Includes newline. */
+ /* Unregister items in reverse order. */
+ gwl_registry_entry_remove_all(display);
+
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+ if (use_libdecor) {
+ if (display->libdecor) {
+ gwl_libdecor_system_destroy(display->libdecor);
+ display->libdecor = nullptr;
+ }
+ }
+ else
+#endif
+ {
+ if (display->xdg_decor) {
+ gwl_xdg_decor_system_destroy(display, display->xdg_decor);
+ display->xdg_decor = nullptr;
+ }
}
-}
-static GWL_SeatStatePointer *seat_state_pointer_active(GWL_Seat *seat)
-{
- if (seat->pointer.serial == seat->cursor_source_serial) {
- return &seat->pointer;
+ if (eglGetDisplay) {
+ ::eglTerminate(eglGetDisplay(EGLNativeDisplayType(display->wl_display)));
}
- if (seat->tablet.serial == seat->cursor_source_serial) {
- return &seat->tablet;
+
+ if (display->wl_display) {
+ wl_display_disconnect(display->wl_display);
}
- return nullptr;
+
+ delete display;
}
-static GWL_SeatStatePointer *seat_state_pointer_from_cursor_surface(GWL_Seat *seat,
- const wl_surface *wl_surface)
+static int gwl_display_seat_index(GWL_Display *display, const GWL_Seat *seat)
{
- if (ghost_wl_surface_own_cursor_pointer(wl_surface)) {
- return &seat->pointer;
- }
- if (ghost_wl_surface_own_cursor_tablet(wl_surface)) {
- return &seat->tablet;
- }
- GHOST_ASSERT(0, "Surface found without pointer/tablet tag");
- return nullptr;
+ std::vector<GWL_Seat *>::iterator iter = std::find(
+ display->seats.begin(), display->seats.end(), seat);
+ const int index = (iter != display->seats.cend()) ? std::distance(display->seats.begin(), iter) :
+ -1;
+ GHOST_ASSERT(index != -1, "invalid internal state");
+ return index;
}
-static void display_destroy(GWL_Display *d)
+static GWL_Seat *gwl_display_seat_active_get(const GWL_Display *display)
{
- if (d->data_device_manager) {
- wl_data_device_manager_destroy(d->data_device_manager);
+ if (UNLIKELY(display->seats.empty())) {
+ return nullptr;
}
+ return display->seats[display->seats_active_index];
+}
- if (d->tablet_manager) {
- zwp_tablet_manager_v2_destroy(d->tablet_manager);
+static bool gwl_display_seat_active_set(GWL_Display *display, const GWL_Seat *seat)
+{
+ if (UNLIKELY(display->seats.empty())) {
+ return false;
}
-
- for (GWL_Output *output : d->outputs) {
- wl_output_destroy(output->wl_output);
- delete output;
+ const int index = gwl_display_seat_index(display, seat);
+ if (index == display->seats_active_index) {
+ return false;
}
+ display->seats_active_index = index;
+ return true;
+}
- for (GWL_Seat *seat : d->seats) {
+/** \} */
- /* First handle members that require locking.
- * While highly unlikely, it's possible they are being used while this function runs. */
- {
- std::lock_guard lock{seat->data_source_mutex};
- if (seat->data_source) {
- free(seat->data_source->buffer_out);
- if (seat->data_source->data_source) {
- wl_data_source_destroy(seat->data_source->data_source);
- }
- delete seat->data_source;
- }
- }
+/* -------------------------------------------------------------------- */
+/** \name Internal #GWL_RegistryHandler
+ * \{ */
- {
- std::lock_guard lock{seat->data_offer_dnd_mutex};
- if (seat->data_offer_dnd) {
- wl_data_offer_destroy(seat->data_offer_dnd->id);
- delete seat->data_offer_dnd;
- }
- }
+struct GWL_RegisteryAdd_Params {
+ uint32_t name = 0;
+ /** Index within `gwl_registry_handlers`. */
+ int interface_slot = 0;
+ uint32_t version = 0;
+};
- {
- std::lock_guard lock{seat->data_offer_copy_paste_mutex};
- if (seat->data_offer_copy_paste) {
- wl_data_offer_destroy(seat->data_offer_copy_paste->id);
- delete seat->data_offer_copy_paste;
- }
- }
+/**
+ * Add callback for object registry.
+ * \note Any operations that depend on other interfaces being registered must be performed in the
+ * #GWL_RegistryHandler_UpdateFn callback as the order interfaces are added is out of our control.
+ *
+ * \param display: The display which holes a reference to the global object.
+ * \param params: Various arguments needed for registration.
+ */
+using GWL_RegistryHandler_AddFn = void (*)(GWL_Display *display,
+ const GWL_RegisteryAdd_Params *params);
- if (seat->data_device) {
- wl_data_device_release(seat->data_device);
- }
+struct GWL_RegisteryUpdate_Params {
+ uint32_t name = 0;
+ /** Index within `gwl_registry_handlers`. */
+ int interface_slot = 0;
+ uint32_t version = 0;
- if (seat->cursor.custom_data) {
- munmap(seat->cursor.custom_data, seat->cursor.custom_data_size);
- }
+ /** Set to #GWL_RegistryEntry.user_data. */
+ void *user_data = nullptr;
+};
- if (seat->wl_pointer) {
- if (seat->cursor.wl_surface) {
- wl_surface_destroy(seat->cursor.wl_surface);
- }
- if (seat->cursor.wl_theme) {
- wl_cursor_theme_destroy(seat->cursor.wl_theme);
- }
- if (seat->wl_pointer) {
- wl_pointer_destroy(seat->wl_pointer);
- }
- }
- if (seat->wl_keyboard) {
- if (seat->key_repeat.timer) {
- keyboard_handle_key_repeat_cancel(seat);
- }
- wl_keyboard_destroy(seat->wl_keyboard);
- }
+/**
+ * Optional update callback to refresh internal data when another interface has been added/removed.
+ *
+ * \param display: The display which holes a reference to the global object.
+ * \param params: Various arguments needed for updating.
+ */
+using GWL_RegistryHandler_UpdateFn = void (*)(GWL_Display *display,
+ const GWL_RegisteryUpdate_Params *params);
- /* Un-referencing checks for NULL case. */
- xkb_state_unref(seat->xkb_state);
- xkb_state_unref(seat->xkb_state_empty);
- xkb_state_unref(seat->xkb_state_empty_with_numlock);
+/**
+ * Remove callback for object registry.
+ * \param display: The display which holes a reference to the global object.
+ * \param user_data: Optional reference to a sub element of `display`,
+ * use for outputs or seats for e.g. when the display may hold multiple references.
+ * \param on_exit: Enabled when freeing on exit.
+ * When true the consistency of references between objects should be kept valid.
+ * Otherwise it can be assumed that all objects will be freed and none will be used again,
+ * so there is no need to ensure a valid state.
+ */
+using GWL_RegistryEntry_RemoveFn = void (*)(GWL_Display *display, void *user_data, bool on_exit);
+
+struct GWL_RegistryHandler {
+ /** Pointer to the name (not the name it's self), needed as the values aren't set on startup. */
+ const char *const *interface_p = nullptr;
+
+ /** Add the interface. */
+ GWL_RegistryHandler_AddFn add_fn = nullptr;
+ /** Optional update the interface (when other interfaces have been added/removed). */
+ GWL_RegistryHandler_UpdateFn update_fn = nullptr;
+ /** Remove the interface. */
+ GWL_RegistryEntry_RemoveFn remove_fn = nullptr;
+};
- xkb_context_unref(seat->xkb_context);
+/** \} */
- wl_seat_destroy(seat->wl_seat);
- delete seat;
- }
+/* -------------------------------------------------------------------- */
+/** \name Internal #GWL_RegistryEntry
+ * \{ */
- if (d->shm) {
- wl_shm_destroy(d->shm);
- }
+/**
+ * Registered global objects can be removed by the compositor,
+ * these entries are a registry of objects and callbacks to properly remove them.
+ * These are also used to remove all registered objects before exiting.
+ */
+struct GWL_RegistryEntry {
+ GWL_RegistryEntry *next = nullptr;
+ /**
+ * Optional pointer passed to `remove_fn`, typically the container in #GWL_Display
+ * in cases multiple instances of the same interface are supported.
+ */
+ void *user_data = nullptr;
+ /**
+ * A unique identifier used as a handle by `wl_registry_listener.global_remove`.
+ */
+ uint32_t name = WL_NAME_UNSET;
+ /**
+ * Version passed by the add callback.
+ */
+ uint32_t version;
+ /**
+ * The index in `gwl_registry_handlers`,
+ * useful for accessing the interface name (for logging for example).
+ */
+ int interface_slot = 0;
+};
- if (d->relative_pointer_manager) {
- zwp_relative_pointer_manager_v1_destroy(d->relative_pointer_manager);
- }
+static void gwl_registry_entry_add(GWL_Display *display,
+ const GWL_RegisteryAdd_Params *params,
+ void *user_data)
+{
+ GWL_RegistryEntry *reg = new GWL_RegistryEntry;
- if (d->pointer_constraints) {
- zwp_pointer_constraints_v1_destroy(d->pointer_constraints);
- }
+ reg->interface_slot = params->interface_slot;
+ reg->name = params->name;
+ reg->version = params->version;
+ reg->user_data = user_data;
- if (d->compositor) {
- wl_compositor_destroy(d->compositor);
- }
+ reg->next = display->registry_entry;
+ display->registry_entry = reg;
+}
-#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- if (d->decor_context) {
- libdecor_unref(d->decor_context);
+static bool gwl_registry_entry_remove_by_name(GWL_Display *display,
+ uint32_t name,
+ int *r_interface_slot)
+{
+ GWL_RegistryEntry *reg = display->registry_entry;
+ GWL_RegistryEntry **reg_link_p = &display->registry_entry;
+ bool found = false;
+
+ if (r_interface_slot) {
+ *r_interface_slot = -1;
}
-#else
- if (d->xdg_decoration_manager) {
- zxdg_decoration_manager_v1_destroy(d->xdg_decoration_manager);
+
+ while (reg) {
+ if (reg->name == name) {
+ GWL_RegistryEntry *reg_next = reg->next;
+ const GWL_RegistryHandler *handler = gwl_registry_handler_from_interface_slot(
+ reg->interface_slot);
+ handler->remove_fn(display, reg->user_data, false);
+ if (r_interface_slot) {
+ *r_interface_slot = reg->interface_slot;
+ }
+ delete reg;
+ *reg_link_p = reg_next;
+ found = true;
+ break;
+ }
+ reg_link_p = &reg->next;
+ reg = reg->next;
+ }
+ return found;
+}
+
+static bool gwl_registry_entry_remove_by_interface_slot(GWL_Display *display,
+ int interface_slot,
+ bool on_exit)
+{
+ GWL_RegistryEntry *reg = display->registry_entry;
+ GWL_RegistryEntry **reg_link_p = &display->registry_entry;
+ bool found = false;
+
+ while (reg) {
+ if (reg->interface_slot == interface_slot) {
+ GWL_RegistryEntry *reg_next = reg->next;
+ const GWL_RegistryHandler *handler = gwl_registry_handler_from_interface_slot(
+ interface_slot);
+ handler->remove_fn(display, reg->user_data, on_exit);
+ delete reg;
+ *reg_link_p = reg_next;
+ reg = reg_next;
+ found = true;
+ continue;
+ }
+ reg_link_p = &reg->next;
+ reg = reg->next;
}
+ return found;
+}
+
+/**
+ * Remove all global objects (on exit).
+ */
+static void gwl_registry_entry_remove_all(GWL_Display *display)
+{
+ const bool on_exit = true;
- if (d->xdg_shell) {
- xdg_wm_base_destroy(d->xdg_shell);
+ /* NOTE(@campbellbarton): Free by slot instead of simply looping over
+ * `display->registry_entry` so the order of freeing is always predictable.
+ * Otherwise global objects would be feed in the order they are registered.
+ * While this works in my tests, it could cause difficult to reproduce bugs
+ * where lesser used compositors or changes to existing compositors could
+ * crash on exit based on the order of freeing objects is out of our control.
+ *
+ * To give a concrete example of how this could fail, it's possible removing
+ * a tablet interface could reference the pointer interface, or the output interface.
+ * Even though references between interfaces shouldn't be necessary in most cases
+ * when `on_exit` is enabled. */
+ int interface_slot = gwl_registry_handler_interface_slot_max();
+ while (interface_slot--) {
+ gwl_registry_entry_remove_by_interface_slot(display, interface_slot, on_exit);
}
-#endif /* !WITH_GHOST_WAYLAND_LIBDECOR */
- if (eglGetDisplay) {
- ::eglTerminate(eglGetDisplay(EGLNativeDisplayType(d->display)));
+ GHOST_ASSERT(display->registry_entry == nullptr, "Failed to remove all entries!");
+ display->registry_entry = nullptr;
+}
+
+/**
+ * Run GWL_RegistryHandler.update_fn an all registered interface instances.
+ * This is needed to refresh the state of interfaces that may reference other interfaces.
+ * Called when interfaces are added/removed.
+ *
+ * \param interface_slot_exclude: Skip updating slots of this type.
+ * Note that while harmless dependencies only exist between different types,
+ * so there is no reason to update all other outputs that an output was removed (for e.g.).
+ * Pass as -1 to update all slots.
+ *
+ * NOTE(@campbellbarton): Updating all other items on a single change is typically worth avoiding.
+ * In practice this isn't a problem as so there are so few elements in `display->registry_entry`,
+ * so few use update functions and adding/removal at runtime is rarely called (plugging/unplugging)
+ * hardware for e.g. So while it's possible to store dependency links to avoid unnecessary
+ * looping over data - it ends up being a non issue.
+ */
+static void gwl_registry_entry_update_all(GWL_Display *display, const int interface_slot_exclude)
+{
+ GHOST_ASSERT(interface_slot_exclude == -1 || (uint(interface_slot_exclude) <
+ uint(gwl_registry_handler_interface_slot_max())),
+ "Invalid exclude slot");
+
+ for (GWL_RegistryEntry *reg = display->registry_entry; reg; reg = reg->next) {
+ if (reg->interface_slot == interface_slot_exclude) {
+ continue;
+ }
+ const GWL_RegistryHandler *handler = gwl_registry_handler_from_interface_slot(
+ reg->interface_slot);
+ if (handler->update_fn == nullptr) {
+ continue;
+ }
+
+ GWL_RegisteryUpdate_Params params = {
+ .name = reg->name,
+ .interface_slot = reg->interface_slot,
+ .version = reg->version,
+
+ .user_data = reg->user_data,
+ };
+ handler->update_fn(display, &params);
}
+}
- if (d->display) {
- wl_display_disconnect(d->display);
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Private Utility Functions
+ * \{ */
+
+static void ghost_wl_display_report_error(struct wl_display *display)
+{
+ int ecode = wl_display_get_error(display);
+ GHOST_ASSERT(ecode, "Error not set!");
+ if ((ecode == EPIPE || ecode == ECONNRESET)) {
+ fprintf(stderr, "The Wayland connection broke. Did the Wayland compositor die?\n");
}
+ else {
+ fprintf(stderr, "The Wayland connection experienced a fatal error: %s\n", strerror(ecode));
+ }
+}
+
+/**
+ * Callback for WAYLAND to run when there is an error.
+ *
+ * \note It's useful to set a break-point on this function as some errors are fatal
+ * (for all intents and purposes) but don't crash the process.
+ */
+static void ghost_wayland_log_handler(const char *msg, va_list arg)
+{
+ fprintf(stderr, "GHOST/Wayland: ");
+ vfprintf(stderr, msg, arg); /* Includes newline. */
- delete d;
+ GHOST_TBacktraceFn backtrace_fn = GHOST_ISystem::getBacktraceFn();
+ if (backtrace_fn) {
+ backtrace_fn(stderr); /* Includes newline. */
+ }
}
static GHOST_TKey xkb_map_gkey(const xkb_keysym_t sym)
@@ -613,8 +1242,8 @@ static GHOST_TKey xkb_map_gkey(const xkb_keysym_t sym)
GXMAP(gkey, XKB_KEY_Control_R, GHOST_kKeyRightControl);
GXMAP(gkey, XKB_KEY_Alt_L, GHOST_kKeyLeftAlt);
GXMAP(gkey, XKB_KEY_Alt_R, GHOST_kKeyRightAlt);
- GXMAP(gkey, XKB_KEY_Super_L, GHOST_kKeyOS);
- GXMAP(gkey, XKB_KEY_Super_R, GHOST_kKeyOS);
+ GXMAP(gkey, XKB_KEY_Super_L, GHOST_kKeyLeftOS);
+ GXMAP(gkey, XKB_KEY_Super_R, GHOST_kKeyRightOS);
GXMAP(gkey, XKB_KEY_Menu, GHOST_kKeyApp);
GXMAP(gkey, XKB_KEY_Caps_Lock, GHOST_kKeyCapsLock);
@@ -647,6 +1276,12 @@ static GHOST_TKey xkb_map_gkey(const xkb_keysym_t sym)
GXMAP(gkey, XKB_KEY_XF86AudioStop, GHOST_kKeyMediaStop);
GXMAP(gkey, XKB_KEY_XF86AudioPrev, GHOST_kKeyMediaFirst);
GXMAP(gkey, XKB_KEY_XF86AudioNext, GHOST_kKeyMediaLast);
+
+ /* Additional keys for non US layouts. */
+
+ /* Uses the same physical key as #XKB_KEY_KP_Decimal for QWERTZ layout, see: T102287. */
+ GXMAP(gkey, XKB_KEY_KP_Separator, GHOST_kKeyNumpadPeriod);
+
default:
/* Rely on #xkb_map_gkey_or_scan_code to report when no key can be found. */
gkey = GHOST_kKeyUnknown;
@@ -692,9 +1327,24 @@ static GHOST_TKey xkb_map_gkey_or_scan_code(const xkb_keysym_t sym, const uint32
return gkey;
}
-static GHOST_TTabletMode tablet_tool_map_type(enum zwp_tablet_tool_v2_type wl_tablet_tool_type)
+static int pointer_axis_as_index(const uint32_t axis)
{
- switch (wl_tablet_tool_type) {
+ switch (axis) {
+ case WL_POINTER_AXIS_HORIZONTAL_SCROLL: {
+ return 0;
+ }
+ case WL_POINTER_AXIS_VERTICAL_SCROLL: {
+ return 1;
+ }
+ default: {
+ return -1;
+ }
+ }
+}
+
+static GHOST_TTabletMode tablet_tool_map_type(enum zwp_tablet_tool_v2_type wp_tablet_tool_type)
+{
+ switch (wp_tablet_tool_type) {
case ZWP_TABLET_TOOL_V2_TYPE_ERASER: {
return GHOST_kTabletModeEraser;
}
@@ -709,13 +1359,13 @@ static GHOST_TTabletMode tablet_tool_map_type(enum zwp_tablet_tool_v2_type wl_ta
}
}
- GHOST_PRINT("unknown tablet tool: " << wl_tablet_tool_type << std::endl);
+ GHOST_PRINT("unknown tablet tool: " << wp_tablet_tool_type << std::endl);
return GHOST_kTabletModeStylus;
}
static const int default_cursor_size = 24;
-static const std::unordered_map<GHOST_TStandardCursor, const char *> cursors = {
+static const std::unordered_map<GHOST_TStandardCursor, const char *> ghost_wl_cursors = {
{GHOST_kStandardCursorDefault, "left_ptr"},
{GHOST_kStandardCursorRightArrow, "right_ptr"},
{GHOST_kStandardCursorLeftArrow, "left_ptr"},
@@ -756,23 +1406,23 @@ static const std::unordered_map<GHOST_TStandardCursor, const char *> cursors = {
{GHOST_kStandardCursorCopy, "copy"},
};
-static constexpr const char *mime_text_plain = "text/plain";
-static constexpr const char *mime_text_utf8 = "text/plain;charset=utf-8";
-static constexpr const char *mime_text_uri = "text/uri-list";
+static constexpr const char *ghost_wl_mime_text_plain = "text/plain";
+static constexpr const char *ghost_wl_mime_text_utf8 = "text/plain;charset=utf-8";
+static constexpr const char *ghost_wl_mime_text_uri = "text/uri-list";
-static const std::unordered_map<std::string, GHOST_TDragnDropTypes> mime_dnd = {
- {mime_text_plain, GHOST_kDragnDropTypeString},
- {mime_text_utf8, GHOST_kDragnDropTypeString},
- {mime_text_uri, GHOST_kDragnDropTypeFilenames},
+static const char *ghost_wl_mime_preference_order[] = {
+ ghost_wl_mime_text_uri,
+ ghost_wl_mime_text_utf8,
+ ghost_wl_mime_text_plain,
};
-
-static const std::vector<std::string> mime_preference_order = {
- mime_text_uri,
- mime_text_utf8,
- mime_text_plain,
+/* Aligned to `ghost_wl_mime_preference_order`. */
+static const GHOST_TDragnDropTypes ghost_wl_mime_preference_order_type[] = {
+ GHOST_kDragnDropTypeString,
+ GHOST_kDragnDropTypeString,
+ GHOST_kDragnDropTypeFilenames,
};
-static const std::vector<std::string> mime_send = {
+static const char *ghost_wl_mime_send[] = {
"UTF8_STRING",
"COMPOUND_TEXT",
"TEXT",
@@ -846,7 +1496,7 @@ static wl_buffer *ghost_wl_buffer_create_for_image(struct wl_shm *shm,
wl_shm_pool_destroy(pool);
if (buffer) {
*r_buffer_data = buffer_data;
- *r_buffer_data_size = (size_t)buffer_size;
+ *r_buffer_data_size = size_t(buffer_size);
}
else {
/* Highly unlikely. */
@@ -862,6 +1512,78 @@ static wl_buffer *ghost_wl_buffer_create_for_image(struct wl_shm *shm,
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Private Keyboard Depressed Key Tracking
+ *
+ * Don't track physical key-codes because there may be multiple keyboards connected.
+ * Instead, count the number of #GHOST_kKey are pressed.
+ * This may seem susceptible to bugs with sticky-keys however XKB works this way internally.
+ * \{ */
+
+static CLG_LogRef LOG_WL_KEYBOARD_DEPRESSED_STATE = {"ghost.wl.keyboard.depressed"};
+#define LOG (&LOG_WL_KEYBOARD_DEPRESSED_STATE)
+
+static void keyboard_depressed_state_reset(GWL_Seat *seat)
+{
+ for (int i = 0; i < GHOST_KEY_MODIFIER_NUM; i++) {
+ seat->key_depressed.mods[i] = 0;
+ }
+}
+
+static void keyboard_depressed_state_key_event(GWL_Seat *seat,
+ const GHOST_TKey gkey,
+ const GHOST_TEventType etype)
+{
+ if (GHOST_KEY_MODIFIER_CHECK(gkey)) {
+ const int index = GHOST_KEY_MODIFIER_TO_INDEX(gkey);
+ int16_t &value = seat->key_depressed.mods[index];
+ if (etype == GHOST_kEventKeyUp) {
+ value -= 1;
+ if (UNLIKELY(value < 0)) {
+ CLOG_WARN(LOG, "modifier (%d) has negative keys held (%d)!", index, value);
+ value = 0;
+ }
+ }
+ else {
+ value += 1;
+ }
+ }
+}
+
+static void keyboard_depressed_state_push_events_from_change(
+ GWL_Seat *seat, const GWL_KeyboardDepressedState &key_depressed_prev)
+{
+ GHOST_IWindow *win = ghost_wl_surface_user_data(seat->keyboard.wl_surface_window);
+ GHOST_SystemWayland *system = seat->system;
+
+ /* Separate key up and down into separate passes so key down events always come after key up.
+ * Do this so users of GHOST can use the last pressed or released modifier to check
+ * if the modifier is held instead of counting modifiers pressed as is done here,
+ * this isn't perfect but works well enough in practice. */
+ for (int i = 0; i < GHOST_KEY_MODIFIER_NUM; i++) {
+ for (int d = seat->key_depressed.mods[i] - key_depressed_prev.mods[i]; d < 0; d++) {
+ const GHOST_TKey gkey = GHOST_KEY_MODIFIER_FROM_INDEX(i);
+ seat->system->pushEvent(
+ new GHOST_EventKey(system->getMilliSeconds(), GHOST_kEventKeyUp, win, gkey, false));
+
+ CLOG_INFO(LOG, 2, "modifier (%d) up", i);
+ }
+ }
+
+ for (int i = 0; i < GHOST_KEY_MODIFIER_NUM; i++) {
+ for (int d = seat->key_depressed.mods[i] - key_depressed_prev.mods[i]; d > 0; d--) {
+ const GHOST_TKey gkey = GHOST_KEY_MODIFIER_FROM_INDEX(i);
+ seat->system->pushEvent(
+ new GHOST_EventKey(system->getMilliSeconds(), GHOST_kEventKeyDown, win, gkey, false));
+ CLOG_INFO(LOG, 2, "modifier (%d) down", i);
+ }
+ }
+}
+
+#undef LOG
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Listener (Relative Motion), #zwp_relative_pointer_v1_listener
*
* These callbacks are registered for Wayland interfaces and called when
@@ -917,7 +1639,7 @@ static void relative_pointer_handle_relative_motion(
const wl_fixed_t /*dy_unaccel*/)
{
GWL_Seat *seat = static_cast<GWL_Seat *>(data);
- if (wl_surface *wl_surface_focus = seat->pointer.wl_surface) {
+ if (wl_surface *wl_surface_focus = seat->pointer.wl_surface_window) {
CLOG_INFO(LOG, 2, "relative_motion");
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
const wl_fixed_t scale = win->scale();
@@ -950,7 +1672,7 @@ static CLG_LogRef LOG_WL_DATA_SOURCE = {"ghost.wl.handle.data_source"};
static void dnd_events(const GWL_Seat *const seat, const GHOST_TEventType event)
{
/* NOTE: `seat->data_offer_dnd_mutex` must already be locked. */
- if (wl_surface *wl_surface_focus = seat->wl_surface_focus_dnd) {
+ if (wl_surface *wl_surface_focus = seat->wl_surface_window_focus_dnd) {
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
const wl_fixed_t scale = win->scale();
const int event_xy[2] = {
@@ -959,40 +1681,144 @@ static void dnd_events(const GWL_Seat *const seat, const GHOST_TEventType event)
};
const uint64_t time = seat->system->getMilliSeconds();
- for (const std::string &type : mime_preference_order) {
- seat->system->pushEvent(new GHOST_EventDragnDrop(
- time, event, mime_dnd.at(type), win, UNPACK2(event_xy), nullptr));
+ for (size_t i = 0; i < ARRAY_SIZE(ghost_wl_mime_preference_order_type); i++) {
+ const GHOST_TDragnDropTypes type = ghost_wl_mime_preference_order_type[i];
+ seat->system->pushEvent(
+ new GHOST_EventDragnDrop(time, event, type, win, UNPACK2(event_xy), nullptr));
+ }
+ }
+}
+
+/**
+ * Read from `fd` into a buffer which is returned.
+ * \return the buffer or null on failure.
+ */
+static char *read_file_as_buffer(const int fd, const bool nil_terminate, size_t *r_len)
+{
+ struct ByteChunk {
+ ByteChunk *next;
+ char data[4096 - sizeof(ByteChunk *)];
+ };
+ ByteChunk *chunk_first = nullptr, **chunk_link_p = &chunk_first;
+ bool ok = true;
+ size_t len = 0;
+ while (true) {
+ ByteChunk *chunk = static_cast<typeof(chunk)>(malloc(sizeof(*chunk)));
+ if (UNLIKELY(chunk == nullptr)) {
+ CLOG_WARN(LOG, "unable to allocate chunk for file buffer");
+ ok = false;
+ break;
+ }
+ chunk->next = nullptr;
+ const ssize_t len_chunk = read(fd, chunk->data, sizeof(chunk->data));
+ if (len_chunk <= 0) {
+ if (UNLIKELY(len_chunk < 0)) {
+ CLOG_WARN(LOG, "error reading from pipe: %s", std::strerror(errno));
+ ok = false;
+ }
+ free(chunk);
+ break;
}
+ if (chunk_first == nullptr) {
+ chunk_first = chunk;
+ }
+ *chunk_link_p = chunk;
+ chunk_link_p = &chunk->next;
+ len += len_chunk;
+ }
+
+ char *buf = nullptr;
+ if (ok) {
+ buf = static_cast<char *>(malloc(len + (nil_terminate ? 1 : 0)));
+ if (UNLIKELY(buf == nullptr)) {
+ CLOG_WARN(LOG, "unable to allocate file buffer: %zu bytes", len);
+ ok = false;
+ }
+ }
+
+ if (ok) {
+ *r_len = len;
+ if (nil_terminate) {
+ buf[len] = '\0';
+ }
+ }
+ else {
+ *r_len = 0;
}
+
+ char *buf_stride = buf;
+ while (chunk_first) {
+ if (ok) {
+ const size_t len_chunk = std::min(len, sizeof(chunk_first->data));
+ memcpy(buf_stride, chunk_first->data, len_chunk);
+ buf_stride += len_chunk;
+ len -= len_chunk;
+ }
+ ByteChunk *chunk = chunk_first->next;
+ free(chunk_first);
+ chunk_first = chunk;
+ }
+
+ return buf;
}
-static std::string read_pipe(GWL_DataOffer *data_offer,
- const std::string mime_receive,
- std::mutex *mutex)
+static char *read_buffer_from_data_offer(GWL_DataOffer *data_offer,
+ const char *mime_receive,
+ std::mutex *mutex,
+ const bool nil_terminate,
+ size_t *r_len)
{
int pipefd[2];
- if (UNLIKELY(pipe(pipefd) != 0)) {
- return {};
+ const bool pipefd_ok = pipe(pipefd) == 0;
+ if (pipefd_ok) {
+ wl_data_offer_receive(data_offer->id, mime_receive, pipefd[1]);
+ close(pipefd[1]);
+ }
+ else {
+ CLOG_WARN(LOG, "error creating pipe: %s", std::strerror(errno));
}
- wl_data_offer_receive(data_offer->id, mime_receive.c_str(), pipefd[1]);
- close(pipefd[1]);
- data_offer->in_use.store(false);
+ /* Only for DND (A no-op to disable for clipboard data-offer). */
+ data_offer->dnd.in_use = false;
if (mutex) {
mutex->unlock();
}
/* WARNING: `data_offer` may be freed from now on. */
+ char *buf = nullptr;
+ if (pipefd_ok) {
+ buf = read_file_as_buffer(pipefd[0], nil_terminate, r_len);
+ close(pipefd[0]);
+ }
+ return buf;
+}
- std::string data;
- ssize_t len;
- char buffer[4096];
- while ((len = read(pipefd[0], buffer, sizeof(buffer))) > 0) {
- data.insert(data.end(), buffer, buffer + len);
+static char *read_buffer_from_primary_selection_offer(GWL_PrimarySelection_DataOffer *data_offer,
+ const char *mime_receive,
+ std::mutex *mutex,
+ const bool nil_terminate,
+ size_t *r_len)
+{
+ int pipefd[2];
+ const bool pipefd_ok = pipe(pipefd) == 0;
+ if (pipefd_ok) {
+ zwp_primary_selection_offer_v1_receive(data_offer->id, mime_receive, pipefd[1]);
+ close(pipefd[1]);
+ }
+ else {
+ CLOG_WARN(LOG, "error creating pipe: %s", std::strerror(errno));
}
- close(pipefd[0]);
- return data;
+ if (mutex) {
+ mutex->unlock();
+ }
+ /* WARNING: `data_offer` may be freed from now on. */
+ char *buf = nullptr;
+ if (pipefd_ok) {
+ buf = read_file_as_buffer(pipefd[0], nil_terminate, r_len);
+ close(pipefd[0]);
+ }
+ return buf;
}
/**
@@ -1014,20 +1840,33 @@ static void data_source_handle_send(void *data,
const int32_t fd)
{
GWL_Seat *seat = static_cast<GWL_Seat *>(data);
- std::lock_guard lock{seat->data_source_mutex};
CLOG_INFO(LOG, 2, "send");
- const char *const buffer = seat->data_source->buffer_out;
- if (write(fd, buffer, strlen(buffer)) < 0) {
- GHOST_PRINT("error writing to clipboard: " << std::strerror(errno) << std::endl);
- }
- close(fd);
+ auto write_file_fn = [](GWL_Seat *seat, const int fd) {
+ if (UNLIKELY(write(fd,
+ seat->data_source->buffer_out.data,
+ seat->data_source->buffer_out.data_size) < 0)) {
+ CLOG_WARN(LOG, "error writing to clipboard: %s", std::strerror(errno));
+ }
+ close(fd);
+ seat->data_source_mutex.unlock();
+ };
+
+ seat->data_source_mutex.lock();
+ std::thread write_thread(write_file_fn, seat, fd);
+ write_thread.detach();
}
-static void data_source_handle_cancelled(void * /*data*/, struct wl_data_source *wl_data_source)
+static void data_source_handle_cancelled(void *data, struct wl_data_source *wl_data_source)
{
CLOG_INFO(LOG, 2, "cancelled");
+ GWL_Seat *seat = static_cast<GWL_Seat *>(data);
+ GWL_DataSource *data_source = seat->data_source;
+ if (seat->data_source->wl_source == wl_data_source) {
+ data_source->wl_source = nullptr;
+ }
+
wl_data_source_destroy(wl_data_source);
}
@@ -1096,7 +1935,8 @@ static void data_offer_handle_offer(void *data,
const char *mime_type)
{
CLOG_INFO(LOG, 2, "offer (mime_type=%s)", mime_type);
- static_cast<GWL_DataOffer *>(data)->types.insert(mime_type);
+ GWL_DataOffer *data_offer = static_cast<GWL_DataOffer *>(data);
+ data_offer->types.insert(mime_type);
}
static void data_offer_handle_source_actions(void *data,
@@ -1104,7 +1944,8 @@ static void data_offer_handle_source_actions(void *data,
const uint32_t source_actions)
{
CLOG_INFO(LOG, 2, "source_actions (%u)", source_actions);
- static_cast<GWL_DataOffer *>(data)->source_actions = source_actions;
+ GWL_DataOffer *data_offer = static_cast<GWL_DataOffer *>(data);
+ data_offer->dnd.source_actions = (enum wl_data_device_manager_dnd_action)source_actions;
}
static void data_offer_handle_action(void *data,
@@ -1112,7 +1953,8 @@ static void data_offer_handle_action(void *data,
const uint32_t dnd_action)
{
CLOG_INFO(LOG, 2, "actions (%u)", dnd_action);
- static_cast<GWL_DataOffer *>(data)->dnd_action = dnd_action;
+ GWL_DataOffer *data_offer = static_cast<GWL_DataOffer *>(data);
+ data_offer->dnd.action = (enum wl_data_device_manager_dnd_action)dnd_action;
}
static const struct wl_data_offer_listener data_offer_listener = {
@@ -1164,7 +2006,7 @@ static void data_device_handle_enter(void *data,
seat->data_offer_dnd = static_cast<GWL_DataOffer *>(wl_data_offer_get_user_data(id));
GWL_DataOffer *data_offer = seat->data_offer_dnd;
- data_offer->in_use.store(true);
+ data_offer->dnd.in_use = true;
data_offer->dnd.xy[0] = x;
data_offer->dnd.xy[1] = y;
@@ -1173,11 +2015,15 @@ static void data_device_handle_enter(void *data,
WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE,
WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY);
- for (const std::string &type : mime_preference_order) {
- wl_data_offer_accept(id, serial, type.c_str());
+ for (size_t i = 0; i < ARRAY_SIZE(ghost_wl_mime_preference_order); i++) {
+ const char *type = ghost_wl_mime_preference_order[i];
+ wl_data_offer_accept(id, serial, type);
}
- seat->wl_surface_focus_dnd = wl_surface;
+ seat->wl_surface_window_focus_dnd = wl_surface;
+
+ seat->system->seat_active_set(seat);
+
dnd_events(seat, GHOST_kEventDraggingEntered);
}
@@ -1189,9 +2035,9 @@ static void data_device_handle_leave(void *data, struct wl_data_device * /*wl_da
CLOG_INFO(LOG, 2, "leave");
dnd_events(seat, GHOST_kEventDraggingExited);
- seat->wl_surface_focus_dnd = nullptr;
+ seat->wl_surface_window_focus_dnd = nullptr;
- if (seat->data_offer_dnd && !seat->data_offer_dnd->in_use.load()) {
+ if (seat->data_offer_dnd && !seat->data_offer_dnd->dnd.in_use) {
wl_data_offer_destroy(seat->data_offer_dnd->id);
delete seat->data_offer_dnd;
seat->data_offer_dnd = nullptr;
@@ -1222,23 +2068,35 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat
GWL_DataOffer *data_offer = seat->data_offer_dnd;
- const std::string mime_receive = *std::find_first_of(mime_preference_order.begin(),
- mime_preference_order.end(),
- data_offer->types.begin(),
- data_offer->types.end());
+ /* Use a blank string for `mime_receive` to prevent crashes, although could also be `nullptr`.
+ * Failure to set this to a known type just means the file won't have any special handling.
+ * GHOST still generates a dropped file event.
+ * NOTE: this string can be compared with `mime_text_plain`, `mime_text_uri` etc...
+ * as the this always points to the same values. */
+ const char *mime_receive = "";
+ for (size_t i = 0; i < ARRAY_SIZE(ghost_wl_mime_preference_order); i++) {
+ const char *type = ghost_wl_mime_preference_order[i];
+ if (data_offer->types.count(type)) {
+ mime_receive = type;
+ break;
+ }
+ }
- CLOG_INFO(LOG, 2, "drop mime_recieve=%s", mime_receive.c_str());
+ CLOG_INFO(LOG, 2, "drop mime_recieve=%s", mime_receive);
auto read_uris_fn = [](GWL_Seat *const seat,
GWL_DataOffer *data_offer,
- wl_surface *wl_surface,
- const std::string mime_receive) {
+ wl_surface *wl_surface_window,
+ const char *mime_receive) {
const wl_fixed_t xy[2] = {UNPACK2(data_offer->dnd.xy)};
- const std::string data = read_pipe(data_offer, mime_receive, nullptr);
+ size_t data_buf_len = 0;
+ const char *data_buf = read_buffer_from_data_offer(
+ data_offer, mime_receive, nullptr, false, &data_buf_len);
+ std::string data = data_buf ? std::string(data_buf, data_buf_len) : "";
+ free(const_cast<char *>(data_buf));
- CLOG_INFO(
- LOG, 2, "drop_read_uris mime_receive=%s, data=%s", mime_receive.c_str(), data.c_str());
+ CLOG_INFO(LOG, 2, "drop_read_uris mime_receive=%s, data=%s", mime_receive, data.c_str());
wl_data_offer_finish(data_offer->id);
wl_data_offer_destroy(data_offer->id);
@@ -1251,13 +2109,13 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat
GHOST_SystemWayland *const system = seat->system;
- if (mime_receive == mime_text_uri) {
+ if (mime_receive == ghost_wl_mime_text_uri) {
static constexpr const char *file_proto = "file://";
/* NOTE: some applications CRLF (`\r\n`) GTK3 for e.g. & others don't `pcmanfm-qt`.
* So support both, once `\n` is found, strip the preceding `\r` if found. */
static constexpr const char *lf = "\n";
- GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface);
+ GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_window);
std::vector<std::string> uris;
size_t pos = 0;
@@ -1296,18 +2154,18 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat
wl_fixed_to_int(scale * xy[1]),
flist));
}
- else if (ELEM(mime_receive, mime_text_plain, mime_text_utf8)) {
+ else if (ELEM(mime_receive, ghost_wl_mime_text_plain, ghost_wl_mime_text_utf8)) {
/* TODO: enable use of internal functions 'txt_insert_buf' and
* 'text_update_edited' to behave like dropped text was pasted. */
CLOG_INFO(LOG, 2, "drop_read_uris_fn (text_plain, text_utf8), unhandled!");
}
- wl_display_roundtrip(system->display());
+ wl_display_roundtrip(system->wl_display());
};
- /* Pass in `seat->wl_surface_focus_dnd` instead of accessing it from `seat` since the leave
- * callback (#data_device_handle_leave) will clear the value once this function starts. */
+ /* Pass in `seat->wl_surface_window_focus_dnd` instead of accessing it from `seat` since the
+ * leave callback (#data_device_handle_leave) will clear the value once this function starts. */
std::thread read_thread(
- read_uris_fn, seat, data_offer, seat->wl_surface_focus_dnd, mime_receive);
+ read_uris_fn, seat, data_offer, seat->wl_surface_window_focus_dnd, mime_receive);
read_thread.detach();
}
@@ -1334,34 +2192,9 @@ static void data_device_handle_selection(void *data,
return;
}
CLOG_INFO(LOG, 2, "selection");
-
/* Get new data offer. */
data_offer = static_cast<GWL_DataOffer *>(wl_data_offer_get_user_data(id));
seat->data_offer_copy_paste = data_offer;
-
- auto read_selection_fn = [](GWL_Seat *seat) {
- GHOST_SystemWayland *const system = seat->system;
- seat->data_offer_copy_paste_mutex.lock();
-
- GWL_DataOffer *data_offer = seat->data_offer_copy_paste;
- std::string mime_receive;
- for (const std::string type : {mime_text_utf8, mime_text_plain}) {
- if (data_offer->types.count(type)) {
- mime_receive = type;
- break;
- }
- }
- const std::string data = read_pipe(
- data_offer, mime_receive, &seat->data_offer_copy_paste_mutex);
-
- {
- std::lock_guard lock{system_selection_mutex};
- system->selection_set(data);
- }
- };
-
- std::thread read_thread(read_selection_fn, seat);
- read_thread.detach();
}
static const struct wl_data_device_listener data_device_listener = {
@@ -1415,7 +2248,7 @@ static CLG_LogRef LOG_WL_CURSOR_SURFACE = {"ghost.wl.handle.cursor_surface"};
static bool update_cursor_scale(GWL_Cursor &cursor,
wl_shm *shm,
GWL_SeatStatePointer *seat_state_pointer,
- wl_surface *wl_cursor_surface)
+ wl_surface *wl_surface_cursor)
{
int scale = 0;
for (const GWL_Output *output : seat_state_pointer->outputs) {
@@ -1427,10 +2260,11 @@ static bool update_cursor_scale(GWL_Cursor &cursor,
if (scale > 0 && seat_state_pointer->theme_scale != scale) {
seat_state_pointer->theme_scale = scale;
if (!cursor.is_custom) {
- wl_surface_set_buffer_scale(wl_cursor_surface, scale);
+ wl_surface_set_buffer_scale(wl_surface_cursor, scale);
}
wl_cursor_theme_destroy(cursor.wl_theme);
- cursor.wl_theme = wl_cursor_theme_load(cursor.theme_name.c_str(), scale * cursor.size, shm);
+ cursor.wl_theme = wl_cursor_theme_load(
+ cursor.theme_name.c_str(), scale * cursor.theme_size, shm);
return true;
}
return false;
@@ -1447,11 +2281,11 @@ static void cursor_surface_handle_enter(void *data,
CLOG_INFO(LOG, 2, "handle_enter");
GWL_Seat *seat = static_cast<GWL_Seat *>(data);
- GWL_SeatStatePointer *seat_state_pointer = seat_state_pointer_from_cursor_surface(seat,
- wl_surface);
+ GWL_SeatStatePointer *seat_state_pointer = gwl_seat_state_pointer_from_cursor_surface(
+ seat, wl_surface);
const GWL_Output *reg_output = ghost_wl_output_user_data(wl_output);
seat_state_pointer->outputs.insert(reg_output);
- update_cursor_scale(seat->cursor, seat->system->shm(), seat_state_pointer, wl_surface);
+ update_cursor_scale(seat->cursor, seat->system->wl_shm(), seat_state_pointer, wl_surface);
}
static void cursor_surface_handle_leave(void *data,
@@ -1465,11 +2299,11 @@ static void cursor_surface_handle_leave(void *data,
CLOG_INFO(LOG, 2, "handle_leave");
GWL_Seat *seat = static_cast<GWL_Seat *>(data);
- GWL_SeatStatePointer *seat_state_pointer = seat_state_pointer_from_cursor_surface(seat,
- wl_surface);
+ GWL_SeatStatePointer *seat_state_pointer = gwl_seat_state_pointer_from_cursor_surface(
+ seat, wl_surface);
const GWL_Output *reg_output = ghost_wl_output_user_data(wl_output);
seat_state_pointer->outputs.erase(reg_output);
- update_cursor_scale(seat->cursor, seat->system->shm(), seat_state_pointer, wl_surface);
+ update_cursor_scale(seat->cursor, seat->system->wl_shm(), seat_state_pointer, wl_surface);
}
static const struct wl_surface_listener cursor_surface_listener = {
@@ -1510,7 +2344,18 @@ static void pointer_handle_enter(void *data,
seat->pointer.serial = serial;
seat->pointer.xy[0] = surface_x;
seat->pointer.xy[1] = surface_y;
- seat->pointer.wl_surface = wl_surface;
+
+ /* Resetting scroll events is likely unnecessary,
+ * do this to avoid any possible problems as it's harmless. */
+ seat->pointer_scroll.smooth_xy[0] = 0;
+ seat->pointer_scroll.smooth_xy[1] = 0;
+ seat->pointer_scroll.discrete_xy[0] = 0;
+ seat->pointer_scroll.discrete_xy[1] = 0;
+ seat->pointer_scroll.axis_source = WL_POINTER_AXIS_SOURCE_WHEEL;
+
+ seat->pointer.wl_surface_window = wl_surface;
+
+ seat->system->seat_active_set(seat);
win->setCursorShape(win->getCursorShape());
@@ -1529,7 +2374,7 @@ static void pointer_handle_leave(void *data,
struct wl_surface *wl_surface)
{
/* First clear the `pointer.wl_surface`, since the window won't exist when closing the window. */
- static_cast<GWL_Seat *>(data)->pointer.wl_surface = nullptr;
+ static_cast<GWL_Seat *>(data)->pointer.wl_surface_window = nullptr;
if (wl_surface && ghost_wl_surface_own(wl_surface)) {
CLOG_INFO(LOG, 2, "leave");
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface);
@@ -1550,7 +2395,7 @@ static void pointer_handle_motion(void *data,
seat->pointer.xy[0] = surface_x;
seat->pointer.xy[1] = surface_y;
- if (wl_surface *wl_surface_focus = seat->pointer.wl_surface) {
+ if (wl_surface *wl_surface_focus = seat->pointer.wl_surface_window) {
CLOG_INFO(LOG, 2, "motion");
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
const wl_fixed_t scale = win->scale();
@@ -1614,31 +2459,99 @@ static void pointer_handle_button(void *data,
seat->data_source_serial = serial;
seat->pointer.buttons.set(ebutton, state == WL_POINTER_BUTTON_STATE_PRESSED);
- if (wl_surface *wl_surface_focus = seat->pointer.wl_surface) {
+ if (wl_surface *wl_surface_focus = seat->pointer.wl_surface_window) {
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
seat->system->pushEvent(new GHOST_EventButton(
seat->system->getMilliSeconds(), etype, win, ebutton, GHOST_TABLET_DATA_NONE));
}
}
-static void pointer_handle_axis(void * /*data*/,
+static void pointer_handle_axis(void *data,
struct wl_pointer * /*wl_pointer*/,
const uint32_t /*time*/,
const uint32_t axis,
const wl_fixed_t value)
{
+ /* NOTE: this is used for touch based scrolling - or other input that doesn't scroll with
+ * discrete "steps". This allows supporting smooth-scrolling without "touch" gesture support. */
CLOG_INFO(LOG, 2, "axis (axis=%u, value=%d)", axis, value);
+ const int index = pointer_axis_as_index(axis);
+ if (UNLIKELY(index == -1)) {
+ return;
+ }
+ GWL_Seat *seat = static_cast<GWL_Seat *>(data);
+ seat->pointer_scroll.smooth_xy[index] = value;
}
-static void pointer_handle_frame(void * /*data*/, struct wl_pointer * /*wl_pointer*/)
+static void pointer_handle_frame(void *data, struct wl_pointer * /*wl_pointer*/)
{
CLOG_INFO(LOG, 2, "frame");
+ GWL_Seat *seat = static_cast<GWL_Seat *>(data);
+
+ /* Both discrete and smooth events may be set at once, never generate events for both
+ * as this will be handling the same event in to different ways.
+ * Prioritize discrete axis events for the mouse wheel, otherwise smooth scroll. */
+ if (seat->pointer_scroll.axis_source == WL_POINTER_AXIS_SOURCE_WHEEL) {
+ if (seat->pointer_scroll.discrete_xy[0]) {
+ seat->pointer_scroll.smooth_xy[0] = 0;
+ }
+ if (seat->pointer_scroll.discrete_xy[1]) {
+ seat->pointer_scroll.smooth_xy[1] = 0;
+ }
+ }
+ else {
+ if (seat->pointer_scroll.smooth_xy[0]) {
+ seat->pointer_scroll.discrete_xy[0] = 0;
+ }
+ if (seat->pointer_scroll.smooth_xy[1]) {
+ seat->pointer_scroll.discrete_xy[1] = 0;
+ }
+ }
+
+ /* Discrete X axis currently unsupported. */
+ if (seat->pointer_scroll.discrete_xy[1]) {
+ if (wl_surface *wl_surface_focus = seat->pointer.wl_surface_window) {
+ GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
+ const int32_t discrete = seat->pointer_scroll.discrete_xy[1];
+ seat->system->pushEvent(new GHOST_EventWheel(
+ seat->system->getMilliSeconds(), win, std::signbit(discrete) ? +1 : -1));
+ }
+ seat->pointer_scroll.discrete_xy[0] = 0;
+ seat->pointer_scroll.discrete_xy[1] = 0;
+ }
+
+ if (seat->pointer_scroll.smooth_xy[0] || seat->pointer_scroll.smooth_xy[1]) {
+ if (wl_surface *wl_surface_focus = seat->pointer.wl_surface_window) {
+ GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
+ const wl_fixed_t scale = win->scale();
+ seat->system->pushEvent(new GHOST_EventTrackpad(
+ seat->system->getMilliSeconds(),
+ win,
+ GHOST_kTrackpadEventScroll,
+ wl_fixed_to_int(scale * seat->pointer.xy[0]),
+ wl_fixed_to_int(scale * seat->pointer.xy[1]),
+ /* NOTE: scaling the delta doesn't seem necessary.
+ * NOTE: inverting delta gives correct results, see: QTBUG-85767.
+ * NOTE: the preference to invert scrolling (in GNOME at least)
+ * has already been applied so there is no need to read this preference. */
+ -wl_fixed_to_int(seat->pointer_scroll.smooth_xy[0]),
+ -wl_fixed_to_int(seat->pointer_scroll.smooth_xy[1]),
+ false));
+ }
+
+ seat->pointer_scroll.smooth_xy[0] = 0;
+ seat->pointer_scroll.smooth_xy[1] = 0;
+ }
+
+ seat->pointer_scroll.axis_source = WL_POINTER_AXIS_SOURCE_WHEEL;
}
-static void pointer_handle_axis_source(void * /*data*/,
+static void pointer_handle_axis_source(void *data,
struct wl_pointer * /*wl_pointer*/,
uint32_t axis_source)
{
CLOG_INFO(LOG, 2, "axis_source (axis_source=%u)", axis_source);
+ GWL_Seat *seat = static_cast<GWL_Seat *>(data);
+ seat->pointer_scroll.axis_source = (enum wl_pointer_axis_source)axis_source;
}
static void pointer_handle_axis_stop(void * /*data*/,
struct wl_pointer * /*wl_pointer*/,
@@ -1652,18 +2565,15 @@ static void pointer_handle_axis_discrete(void *data,
uint32_t axis,
int32_t discrete)
{
+ /* NOTE: a discrete axis are typically mouse wheel events.
+ * The non-discrete version of this function is used for touch-pad. */
CLOG_INFO(LOG, 2, "axis_discrete (axis=%u, discrete=%d)", axis, discrete);
-
- GWL_Seat *seat = static_cast<GWL_Seat *>(data);
- if (axis != WL_POINTER_AXIS_VERTICAL_SCROLL) {
+ const int index = pointer_axis_as_index(axis);
+ if (UNLIKELY(index == -1)) {
return;
}
-
- if (wl_surface *wl_surface_focus = seat->pointer.wl_surface) {
- GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
- seat->system->pushEvent(new GHOST_EventWheel(
- seat->system->getMilliSeconds(), win, std::signbit(discrete) ? +1 : -1));
- }
+ GWL_Seat *seat = static_cast<GWL_Seat *>(data);
+ seat->pointer_scroll.discrete_xy[index] = discrete;
}
static const struct wl_pointer_listener pointer_listener = {
@@ -1683,6 +2593,325 @@ static const struct wl_pointer_listener pointer_listener = {
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Listener (Pointer Gesture: Hold), #zwp_pointer_gesture_hold_v1_listener
+ * \{ */
+
+#ifdef ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE
+static CLG_LogRef LOG_WL_POINTER_GESTURE_HOLD = {"ghost.wl.handle.pointer_gesture.hold"};
+# define LOG (&LOG_WL_POINTER_GESTURE_HOLD)
+
+static void gesture_hold_handle_begin(
+ void * /*data*/,
+ struct zwp_pointer_gesture_hold_v1 * /*zwp_pointer_gesture_hold_v1*/,
+ uint32_t /*serial*/,
+ uint32_t /*time*/,
+ struct wl_surface * /*surface*/,
+ uint32_t fingers)
+{
+ CLOG_INFO(LOG, 2, "begin (fingers=%u)", fingers);
+}
+
+static void gesture_hold_handle_end(
+ void * /*data*/,
+ struct zwp_pointer_gesture_hold_v1 * /*zwp_pointer_gesture_hold_v1*/,
+ uint32_t /*serial*/,
+ uint32_t /*time*/,
+ int32_t cancelled)
+{
+ CLOG_INFO(LOG, 2, "end (cancelled=%i)", cancelled);
+}
+
+static const struct zwp_pointer_gesture_hold_v1_listener gesture_hold_listener = {
+ gesture_hold_handle_begin,
+ gesture_hold_handle_end,
+};
+
+# undef LOG
+#endif /* ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE */
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Listener (Pointer Gesture: Pinch), #zwp_pointer_gesture_pinch_v1_listener
+ * \{ */
+
+#ifdef ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE
+static CLG_LogRef LOG_WL_POINTER_GESTURE_PINCH = {"ghost.wl.handle.pointer_gesture.pinch"};
+# define LOG (&LOG_WL_POINTER_GESTURE_PINCH)
+
+static void gesture_pinch_handle_begin(void *data,
+ struct zwp_pointer_gesture_pinch_v1 * /*pinch*/,
+ uint32_t /*serial*/,
+ uint32_t /*time*/,
+ struct wl_surface * /*surface*/,
+ uint32_t fingers)
+{
+ CLOG_INFO(LOG, 2, "begin (fingers=%u)", fingers);
+ GWL_Seat *seat = static_cast<GWL_Seat *>(data);
+ /* Reset defaults. */
+ seat->pointer_gesture_pinch = GWL_SeatStatePointerGesture_Pinch{};
+
+ GHOST_WindowWayland *win = nullptr;
+ if (wl_surface *wl_surface_focus = seat->pointer.wl_surface_window) {
+ win = ghost_wl_surface_user_data(wl_surface_focus);
+ }
+ /* NOTE(@campbellbarton): Blender's use of track-pad coordinates is inconsistent and needs work.
+ * This isn't specific to WAYLAND, in practice they tend to work well enough in most cases.
+ * Some operators scale by the UI scale, some don't.
+ * Even this window scale is not correct because it doesn't account for:
+ * 1) Fractional window scale.
+ * 2) Blender's UI scale preference (which GHOST doesn't know about).
+ *
+ * If support for this were all that was needed it could be handled in GHOST,
+ * however as the operators are not even using coordinates compatible with each other,
+ * it would be better to resolve this by passing rotation & zoom levels directly,
+ * instead of attempting to handle them as cursor coordinates.
+ */
+ const wl_fixed_t win_scale = win ? win->scale() : 1;
+
+ /* NOTE(@campbellbarton): Scale factors match Blender's operators & default preferences.
+ * For these values to work correctly, operator logic will need to be changed not to scale input
+ * by the region size (as with 3D view zoom) or preference for 3D view orbit sensitivity.
+ *
+ * By working "correctly" I mean that a rotation action where the users fingers rotate to
+ * opposite locations should always rotate the viewport 180d, since users will expect the
+ * physical location of their fingers to match the viewport.
+ * Similarly with zoom, the scale value from the pinch action can be mapped to a zoom level
+ * although unlike rotation, an inexact mapping is less noticeable.
+ * Users may even prefer the zoom level to be scaled - which could be a preference. */
+ seat->pointer_gesture_pinch.scale.value = wl_fixed_from_int(1);
+ /* The value 300 matches a value used in clip & image zoom operators.
+ * It seems OK for the 3D view too. */
+ seat->pointer_gesture_pinch.scale.factor = 300 * win_scale;
+ /* The value 5 is used on macOS and roughly maps 1:1 with turntable rotation,
+ * although preferences can scale the sensitivity (which would be skipped ideally). */
+ seat->pointer_gesture_pinch.rotation.factor = 5 * win_scale;
+}
+
+static void gesture_pinch_handle_update(void *data,
+ struct zwp_pointer_gesture_pinch_v1 * /*pinch*/,
+ uint32_t /*time*/,
+ wl_fixed_t dx,
+ wl_fixed_t dy,
+ wl_fixed_t scale,
+ wl_fixed_t rotation)
+{
+ CLOG_INFO(LOG,
+ 2,
+ "update (dx=%.3f, dy=%.3f, scale=%.3f, rotation=%.3f)",
+ wl_fixed_to_double(dx),
+ wl_fixed_to_double(dy),
+ wl_fixed_to_double(scale),
+ wl_fixed_to_double(rotation));
+
+ GWL_Seat *seat = static_cast<GWL_Seat *>(data);
+
+ GHOST_WindowWayland *win = nullptr;
+
+ if (wl_surface *wl_surface_focus = seat->pointer.wl_surface_window) {
+ win = ghost_wl_surface_user_data(wl_surface_focus);
+ }
+
+ /* Scale defaults to `wl_fixed_from_int(1)` which may change while pinching.
+ * This needs to be converted to a delta. */
+ const wl_fixed_t scale_delta = scale - seat->pointer_gesture_pinch.scale.value;
+ const int scale_as_delta_px = gwl_scaled_fixed_t_add_and_calc_rounded_delta(
+ &seat->pointer_gesture_pinch.scale, scale_delta);
+
+ /* Rotation in degrees, unlike scale this is a delta. */
+ const int rotation_as_delta_px = gwl_scaled_fixed_t_add_and_calc_rounded_delta(
+ &seat->pointer_gesture_pinch.rotation, rotation);
+
+ if (win) {
+ const wl_fixed_t win_scale = win->scale();
+ const int32_t event_xy[2] = {
+ wl_fixed_to_int(win_scale * seat->pointer.xy[0]),
+ wl_fixed_to_int(win_scale * seat->pointer.xy[1]),
+ };
+ if (scale_as_delta_px) {
+ seat->system->pushEvent(new GHOST_EventTrackpad(seat->system->getMilliSeconds(),
+ win,
+ GHOST_kTrackpadEventMagnify,
+ event_xy[0],
+ event_xy[1],
+ scale_as_delta_px,
+ 0,
+ false));
+ }
+
+ if (rotation_as_delta_px) {
+ seat->system->pushEvent(new GHOST_EventTrackpad(seat->system->getMilliSeconds(),
+ win,
+ GHOST_kTrackpadEventRotate,
+ event_xy[0],
+ event_xy[1],
+ rotation_as_delta_px,
+ 0,
+ false));
+ }
+ }
+}
+
+static void gesture_pinch_handle_end(void * /*data*/,
+ struct zwp_pointer_gesture_pinch_v1 * /*pinch*/,
+ uint32_t /*serial*/,
+ uint32_t /*time*/,
+ int32_t cancelled)
+{
+ CLOG_INFO(LOG, 2, "end (cancelled=%i)", cancelled);
+}
+
+static const struct zwp_pointer_gesture_pinch_v1_listener gesture_pinch_listener = {
+ gesture_pinch_handle_begin,
+ gesture_pinch_handle_update,
+ gesture_pinch_handle_end,
+};
+
+# undef LOG
+#endif /* ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE */
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Listener (Pointer Gesture: Swipe), #zwp_pointer_gesture_swipe_v1
+ *
+ * \note In both Gnome-Shell & KDE this gesture isn't emitted at time of writing,
+ * instead, high resolution 2D #wl_pointer_listener.axis data is generated which works well.
+ * There may be some situations where WAYLAND compositors generate this gesture
+ * (swiping with 3+ fingers, for e.g.). So keep this to allow logging & testing gestures.
+ * \{ */
+
+#ifdef ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE
+static CLG_LogRef LOG_WL_POINTER_GESTURE_SWIPE = {"ghost.wl.handle.pointer_gesture.swipe"};
+# define LOG (&LOG_WL_POINTER_GESTURE_SWIPE)
+
+static void gesture_swipe_handle_begin(
+ void * /*data*/,
+ struct zwp_pointer_gesture_swipe_v1 * /*zwp_pointer_gesture_swipe_v1*/,
+ uint32_t /*serial*/,
+ uint32_t /*time*/,
+ struct wl_surface * /*surface*/,
+ uint32_t fingers)
+{
+ CLOG_INFO(LOG, 2, "begin (fingers=%u)", fingers);
+}
+
+static void gesture_swipe_handle_update(
+ void * /*data*/,
+ struct zwp_pointer_gesture_swipe_v1 * /*zwp_pointer_gesture_swipe_v1*/,
+ uint32_t /*time*/,
+ wl_fixed_t dx,
+ wl_fixed_t dy)
+{
+ CLOG_INFO(LOG, 2, "update (dx=%.3f, dy=%.3f)", wl_fixed_to_double(dx), wl_fixed_to_double(dy));
+}
+
+static void gesture_swipe_handle_end(
+ void * /*data*/,
+ struct zwp_pointer_gesture_swipe_v1 * /*zwp_pointer_gesture_swipe_v1*/,
+ uint32_t /*serial*/,
+ uint32_t /*time*/,
+ int32_t cancelled)
+{
+ CLOG_INFO(LOG, 2, "end (cancelled=%i)", cancelled);
+}
+
+static const struct zwp_pointer_gesture_swipe_v1_listener gesture_swipe_listener = {
+ gesture_swipe_handle_begin,
+ gesture_swipe_handle_update,
+ gesture_swipe_handle_end,
+};
+
+# undef LOG
+#endif /* ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE */
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Listener (Touch Seat), #wl_touch_listener
+ *
+ * NOTE(@campbellbarton): It's not clear if this interface is used by popular compositors.
+ * It looks like GNOME/KDE only support `zwp_pointer_gestures_v1_interface`.
+ * If this isn't used anywhere, it could be removed.
+ * \{ */
+
+static CLG_LogRef LOG_WL_TOUCH = {"ghost.wl.handle.touch"};
+#define LOG (&LOG_WL_TOUCH)
+
+static void touch_seat_handle_down(void * /*data*/,
+ struct wl_touch * /*wl_touch*/,
+ uint32_t /*serial*/,
+ uint32_t /*time*/,
+ struct wl_surface * /*wl_surface*/,
+ int32_t /*id*/,
+ wl_fixed_t /*x*/,
+ wl_fixed_t /*y*/)
+{
+ CLOG_INFO(LOG, 2, "down");
+}
+
+static void touch_seat_handle_up(void * /*data*/,
+ struct wl_touch * /*wl_touch*/,
+ uint32_t /*serial*/,
+ uint32_t /*time*/,
+ int32_t /*id*/)
+{
+ CLOG_INFO(LOG, 2, "up");
+}
+
+static void touch_seat_handle_motion(void * /*data*/,
+ struct wl_touch * /*wl_touch*/,
+ uint32_t /*time*/,
+ int32_t /*id*/,
+ wl_fixed_t /*x*/,
+ wl_fixed_t /*y*/)
+{
+ CLOG_INFO(LOG, 2, "motion");
+}
+
+static void touch_seat_handle_frame(void * /*data*/, struct wl_touch * /*wl_touch*/)
+{
+ CLOG_INFO(LOG, 2, "frame");
+}
+
+static void touch_seat_handle_cancel(void * /*data*/, struct wl_touch * /*wl_touch*/)
+{
+
+ CLOG_INFO(LOG, 2, "cancel");
+}
+
+static void touch_seat_handle_shape(void * /*data*/,
+ struct wl_touch * /*touch*/,
+ int32_t /*id*/,
+ wl_fixed_t /*major*/,
+ wl_fixed_t /*minor*/)
+{
+ CLOG_INFO(LOG, 2, "shape");
+}
+
+static void touch_seat_handle_orientation(void * /*data*/,
+ struct wl_touch * /*touch*/,
+ int32_t /*id*/,
+ wl_fixed_t /*orientation*/)
+{
+ CLOG_INFO(LOG, 2, "orientation");
+}
+
+static const struct wl_touch_listener touch_seat_listener = {
+ touch_seat_handle_down,
+ touch_seat_handle_up,
+ touch_seat_handle_motion,
+ touch_seat_handle_frame,
+ touch_seat_handle_cancel,
+ touch_seat_handle_shape,
+ touch_seat_handle_orientation,
+};
+
+#undef LOG
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Listener (Tablet Tool), #zwp_tablet_tool_v2_listener
* \{ */
@@ -1767,11 +2996,13 @@ static void tablet_tool_handle_proximity_in(void *data,
GWL_Seat *seat = tablet_tool->seat;
seat->cursor_source_serial = serial;
- seat->tablet.wl_surface = wl_surface;
+ seat->tablet.wl_surface_window = wl_surface;
seat->tablet.serial = serial;
seat->data_source_serial = serial;
+ seat->system->seat_active_set(seat);
+
/* Update #GHOST_TabletData. */
GHOST_TabletData &td = tablet_tool->data;
/* Reset, to avoid using stale tilt/pressure. */
@@ -1780,7 +3011,7 @@ static void tablet_tool_handle_proximity_in(void *data,
/* In case pressure isn't supported. */
td.Pressure = 1.0f;
- GHOST_WindowWayland *win = ghost_wl_surface_user_data(seat->tablet.wl_surface);
+ GHOST_WindowWayland *win = ghost_wl_surface_user_data(seat->tablet.wl_surface_window);
win->activate();
@@ -1810,7 +3041,7 @@ static void tablet_tool_handle_down(void *data,
seat->data_source_serial = serial;
seat->tablet.buttons.set(ebutton, true);
- if (wl_surface *wl_surface_focus = seat->tablet.wl_surface) {
+ if (wl_surface *wl_surface_focus = seat->tablet.wl_surface_window) {
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
seat->system->pushEvent(new GHOST_EventButton(
seat->system->getMilliSeconds(), etype, win, ebutton, tablet_tool->data));
@@ -1828,7 +3059,7 @@ static void tablet_tool_handle_up(void *data, struct zwp_tablet_tool_v2 * /*zwp_
seat->tablet.buttons.set(ebutton, false);
- if (wl_surface *wl_surface_focus = seat->tablet.wl_surface) {
+ if (wl_surface *wl_surface_focus = seat->tablet.wl_surface_window) {
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
seat->system->pushEvent(new GHOST_EventButton(
seat->system->getMilliSeconds(), etype, win, ebutton, tablet_tool->data));
@@ -1855,7 +3086,7 @@ static void tablet_tool_handle_pressure(void *data,
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
const uint32_t pressure)
{
- const float pressure_unit = (float)pressure / 65535;
+ const float pressure_unit = float(pressure) / 65535;
CLOG_INFO(LOG, 2, "pressure (%.4f)", pressure_unit);
GWL_TabletTool *tablet_tool = static_cast<GWL_TabletTool *>(data);
@@ -1876,8 +3107,8 @@ static void tablet_tool_handle_tilt(void *data,
{
/* Map degrees to `-1.0..1.0`. */
const float tilt_unit[2] = {
- (float)(wl_fixed_to_double(tilt_x) / 90.0),
- (float)(wl_fixed_to_double(tilt_y) / 90.0),
+ float(wl_fixed_to_double(tilt_x) / 90.0),
+ float(wl_fixed_to_double(tilt_y) / 90.0),
};
CLOG_INFO(LOG, 2, "tilt (x=%.4f, y=%.4f)", UNPACK2(tilt_unit));
GWL_TabletTool *tablet_tool = static_cast<GWL_TabletTool *>(data);
@@ -1913,7 +3144,7 @@ static void tablet_tool_handle_wheel(void *data,
GWL_TabletTool *tablet_tool = static_cast<GWL_TabletTool *>(data);
GWL_Seat *seat = tablet_tool->seat;
- if (wl_surface *wl_surface_focus = seat->tablet.wl_surface) {
+ if (wl_surface *wl_surface_focus = seat->tablet.wl_surface_window) {
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
seat->system->pushEvent(new GHOST_EventWheel(seat->system->getMilliSeconds(), win, clicks));
}
@@ -1942,10 +3173,10 @@ static void tablet_tool_handle_button(void *data,
GHOST_TButton ebutton = GHOST_kButtonMaskLeft;
switch (button) {
case BTN_STYLUS:
- ebutton = GHOST_kButtonMaskRight;
+ ebutton = GHOST_kButtonMaskMiddle;
break;
case BTN_STYLUS2:
- ebutton = GHOST_kButtonMaskMiddle;
+ ebutton = GHOST_kButtonMaskRight;
break;
case BTN_STYLUS3:
ebutton = GHOST_kButtonMaskButton4;
@@ -1955,7 +3186,7 @@ static void tablet_tool_handle_button(void *data,
seat->data_source_serial = serial;
seat->tablet.buttons.set(ebutton, state == WL_POINTER_BUTTON_STATE_PRESSED);
- if (wl_surface *wl_surface_focus = seat->tablet.wl_surface) {
+ if (wl_surface *wl_surface_focus = seat->tablet.wl_surface_window) {
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
seat->system->pushEvent(new GHOST_EventButton(
seat->system->getMilliSeconds(), etype, win, ebutton, tablet_tool->data));
@@ -1971,7 +3202,7 @@ static void tablet_tool_handle_frame(void *data,
GWL_Seat *seat = tablet_tool->seat;
/* No need to check the surfaces origin, it's already known to be owned by GHOST. */
- if (wl_surface *wl_surface_focus = seat->tablet.wl_surface) {
+ if (wl_surface *wl_surface_focus = seat->tablet.wl_surface_window) {
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
const wl_fixed_t scale = win->scale();
seat->system->pushEvent(new GHOST_EventCursor(seat->system->getMilliSeconds(),
@@ -1986,7 +3217,7 @@ static void tablet_tool_handle_frame(void *data,
}
if (tablet_tool->proximity == false) {
- seat->tablet.wl_surface = nullptr;
+ seat->tablet.wl_surface_window = nullptr;
}
}
@@ -2041,7 +3272,7 @@ static void tablet_seat_handle_tool_added(void *data,
tablet_tool->seat = seat;
/* Every tool has it's own cursor wl_surface. */
- tablet_tool->wl_surface_cursor = wl_compositor_create_surface(seat->system->compositor());
+ tablet_tool->wl_surface_cursor = wl_compositor_create_surface(seat->system->wl_compositor());
ghost_wl_surface_tag_cursor_tablet(tablet_tool->wl_surface_cursor);
wl_surface_add_listener(tablet_tool->wl_surface_cursor, &cursor_surface_listener, (void *)seat);
@@ -2114,9 +3345,23 @@ static void keyboard_handle_keymap(void *data,
xkb_state_unref(seat->xkb_state_empty);
seat->xkb_state_empty = xkb_state_new(keymap);
+ for (int i = 0; i < MOD_INDEX_NUM; i++) {
+ const GWL_ModifierInfo &mod_info = g_modifier_info_table[i];
+ seat->xkb_keymap_mod_index[i] = xkb_keymap_mod_get_index(keymap, mod_info.xkb_id);
+ }
+
+ xkb_state_unref(seat->xkb_state_empty_with_shift);
+ seat->xkb_state_empty_with_shift = nullptr;
+ {
+ const xkb_mod_index_t mod_shift = seat->xkb_keymap_mod_index[MOD_INDEX_SHIFT];
+ if (mod_shift != XKB_MOD_INVALID) {
+ seat->xkb_state_empty_with_shift = xkb_state_new(keymap);
+ xkb_state_update_mask(seat->xkb_state_empty_with_shift, (1 << mod_shift), 0, 0, 0, 0, 0);
+ }
+ }
+
xkb_state_unref(seat->xkb_state_empty_with_numlock);
seat->xkb_state_empty_with_numlock = nullptr;
-
{
const xkb_mod_index_t mod2 = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_NUM);
const xkb_mod_index_t num = xkb_keymap_mod_get_index(keymap, "NumLock");
@@ -2127,12 +3372,23 @@ static void keyboard_handle_keymap(void *data,
}
}
- seat->xkb_keymap_mod_index.shift = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
- seat->xkb_keymap_mod_index.caps = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
- seat->xkb_keymap_mod_index.ctrl = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
- seat->xkb_keymap_mod_index.alt = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_ALT);
- seat->xkb_keymap_mod_index.num = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_NUM);
- seat->xkb_keymap_mod_index.logo = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
+#ifdef USE_NON_LATIN_KB_WORKAROUND
+ seat->xkb_use_non_latin_workaround = false;
+ if (seat->xkb_state_empty_with_shift) {
+ seat->xkb_use_non_latin_workaround = true;
+ for (xkb_keycode_t key_code = KEY_1 + EVDEV_OFFSET; key_code <= KEY_0 + EVDEV_OFFSET;
+ key_code++) {
+ const xkb_keysym_t sym_test = xkb_state_key_get_one_sym(seat->xkb_state_empty_with_shift,
+ key_code);
+ if (!(sym_test >= XKB_KEY_0 && sym_test <= XKB_KEY_9)) {
+ seat->xkb_use_non_latin_workaround = false;
+ break;
+ }
+ }
+ }
+#endif
+
+ keyboard_depressed_state_reset(seat);
xkb_keymap_unref(keymap);
}
@@ -2156,50 +3412,32 @@ static void keyboard_handle_enter(void *data,
GWL_Seat *seat = static_cast<GWL_Seat *>(data);
seat->keyboard.serial = serial;
- seat->keyboard.wl_surface = wl_surface;
-
- if (keys->size != 0) {
- /* If there are any keys held when activating the window,
- * modifiers will be compared against the seat state,
- * only enabling modifiers that were previously disabled. */
-
- const xkb_mod_mask_t state = xkb_state_serialize_mods(seat->xkb_state, XKB_STATE_MODS_ALL);
- uint32_t *key;
- WL_ARRAY_FOR_EACH (key, keys) {
- const xkb_keycode_t key_code = *key + EVDEV_OFFSET;
- const xkb_keysym_t sym = xkb_state_key_get_one_sym(seat->xkb_state, key_code);
- GHOST_TKey gkey = GHOST_kKeyUnknown;
-
-#define MOD_TEST(state, mod) ((mod != XKB_MOD_INVALID) && (state & (1 << mod)))
-#define MOD_TEST_CASE(xkb_key, ghost_key, mod_index) \
- case xkb_key: \
- if (!MOD_TEST(state, seat->xkb_keymap_mod_index.mod_index)) { \
- gkey = ghost_key; \
- } \
- break
-
- switch (sym) {
- MOD_TEST_CASE(XKB_KEY_Shift_L, GHOST_kKeyLeftShift, shift);
- MOD_TEST_CASE(XKB_KEY_Shift_R, GHOST_kKeyRightShift, shift);
- MOD_TEST_CASE(XKB_KEY_Control_L, GHOST_kKeyLeftControl, ctrl);
- MOD_TEST_CASE(XKB_KEY_Control_R, GHOST_kKeyRightControl, ctrl);
- MOD_TEST_CASE(XKB_KEY_Alt_L, GHOST_kKeyLeftAlt, alt);
- MOD_TEST_CASE(XKB_KEY_Alt_R, GHOST_kKeyRightAlt, alt);
- MOD_TEST_CASE(XKB_KEY_Super_L, GHOST_kKeyOS, logo);
- MOD_TEST_CASE(XKB_KEY_Super_R, GHOST_kKeyOS, logo);
- }
-
-#undef MOD_TEST
-#undef MOD_TEST_CASE
-
- if (gkey != GHOST_kKeyUnknown) {
- GHOST_IWindow *win = ghost_wl_surface_user_data(wl_surface);
- GHOST_SystemWayland *system = seat->system;
- seat->system->pushEvent(
- new GHOST_EventKey(system->getMilliSeconds(), GHOST_kEventKeyDown, win, gkey, false));
- }
+ seat->keyboard.wl_surface_window = wl_surface;
+
+ seat->system->seat_active_set(seat);
+
+ /* If there are any keys held when activating the window,
+ * modifiers will be compared against the seat state,
+ * only enabling modifiers that were previously disabled. */
+ GWL_KeyboardDepressedState key_depressed_prev = seat->key_depressed;
+ keyboard_depressed_state_reset(seat);
+
+ uint32_t *key;
+ WL_ARRAY_FOR_EACH (key, keys) {
+ const xkb_keycode_t key_code = *key + EVDEV_OFFSET;
+ CLOG_INFO(LOG, 2, "enter (key_held=%d)", int(key_code));
+ const xkb_keysym_t sym = xkb_state_key_get_one_sym(seat->xkb_state, key_code);
+ const GHOST_TKey gkey = xkb_map_gkey_or_scan_code(sym, *key);
+ if (gkey != GHOST_kKeyUnknown) {
+ keyboard_depressed_state_key_event(seat, gkey, GHOST_kEventKeyDown);
}
}
+
+ keyboard_depressed_state_push_events_from_change(seat, key_depressed_prev);
+
+#ifdef USE_GNOME_KEYBOARD_SUPPRESS_WARNING
+ seat->key_depressed_suppress_warning.any_keys_held_on_enter = keys->size != 0;
+#endif
}
/**
@@ -2219,12 +3457,17 @@ static void keyboard_handle_leave(void *data,
CLOG_INFO(LOG, 2, "leave");
GWL_Seat *seat = static_cast<GWL_Seat *>(data);
- seat->keyboard.wl_surface = nullptr;
+ seat->keyboard.wl_surface_window = nullptr;
/* Losing focus must stop repeating text. */
if (seat->key_repeat.timer) {
keyboard_handle_key_repeat_cancel(seat);
}
+
+#ifdef USE_GNOME_KEYBOARD_SUPPRESS_WARNING
+ seat->key_depressed_suppress_warning.any_mod_held = false;
+ seat->key_depressed_suppress_warning.any_keys_held_on_enter = false;
+#endif
}
/**
@@ -2234,6 +3477,8 @@ static void keyboard_handle_leave(void *data,
static xkb_keysym_t xkb_state_key_get_one_sym_without_modifiers(
struct xkb_state *xkb_state_empty,
struct xkb_state *xkb_state_empty_with_numlock,
+ struct xkb_state *xkb_state_empty_with_shift,
+ const bool xkb_use_non_latin_workaround,
const xkb_keycode_t key)
{
/* Use an empty keyboard state to access key symbol without modifiers. */
@@ -2247,11 +3492,30 @@ static xkb_keysym_t xkb_state_key_get_one_sym_without_modifiers(
/* Accounts for key-pad keys typically swapped for numbers when number-lock is enabled:
* `Home Left Up Right Down Prior Page_Up Next Page_Dow End Begin Insert Delete`. */
- if (xkb_state_empty_with_numlock && (sym >= XKB_KEY_KP_Home && sym <= XKB_KEY_KP_Delete)) {
- const xkb_keysym_t sym_test = xkb_state_key_get_one_sym(xkb_state_empty_with_numlock, key);
- if (sym_test != XKB_KEY_NoSymbol) {
- sym = sym_test;
+ if (sym >= XKB_KEY_KP_Home && sym <= XKB_KEY_KP_Delete) {
+ if (xkb_state_empty_with_numlock) {
+ const xkb_keysym_t sym_test = xkb_state_key_get_one_sym(xkb_state_empty_with_numlock, key);
+ if (sym_test != XKB_KEY_NoSymbol) {
+ sym = sym_test;
+ }
+ }
+ }
+ else {
+#ifdef USE_NON_LATIN_KB_WORKAROUND
+ if (key >= (KEY_1 + EVDEV_OFFSET) && key <= (KEY_0 + EVDEV_OFFSET)) {
+ if (xkb_state_empty_with_shift && xkb_use_non_latin_workaround) {
+ const xkb_keysym_t sym_test = xkb_state_key_get_one_sym(xkb_state_empty_with_shift, key);
+ if (sym_test != XKB_KEY_NoSymbol) {
+ /* Should never happen as enabling `xkb_use_non_latin_workaround` checks this. */
+ GHOST_ASSERT(sym_test >= XKB_KEY_0 && sym_test <= XKB_KEY_9, "Unexpected key");
+ sym = sym_test;
+ }
+ }
}
+#else
+ (void)xkb_state_empty_with_shift;
+ (void)xkb_use_non_latin_workaround;
+#endif
}
return sym;
@@ -2294,12 +3558,20 @@ static void keyboard_handle_key(void *data,
const xkb_keycode_t key_code = key + EVDEV_OFFSET;
const xkb_keysym_t sym = xkb_state_key_get_one_sym_without_modifiers(
- seat->xkb_state_empty, seat->xkb_state_empty_with_numlock, key_code);
+ seat->xkb_state_empty,
+ seat->xkb_state_empty_with_numlock,
+ seat->xkb_state_empty_with_shift,
+#ifdef USE_NON_LATIN_KB_WORKAROUND
+ seat->xkb_use_non_latin_workaround,
+#else
+ false,
+#endif
+ key_code);
if (sym == XKB_KEY_NoSymbol) {
- CLOG_INFO(LOG, 2, "key (no symbol, skipped)");
+ CLOG_INFO(LOG, 2, "key (code=%d, state=%u, no symbol, skipped)", int(key_code), state);
return;
}
- CLOG_INFO(LOG, 2, "key");
+ CLOG_INFO(LOG, 2, "key (code=%d, state=%u)", int(key_code), state);
GHOST_TEventType etype = GHOST_kEventUnknown;
switch (state) {
@@ -2373,7 +3645,9 @@ static void keyboard_handle_key(void *data,
seat->data_source_serial = serial;
- if (wl_surface *wl_surface_focus = seat->keyboard.wl_surface) {
+ keyboard_depressed_state_key_event(seat, gkey, etype);
+
+ if (wl_surface *wl_surface_focus = seat->keyboard.wl_surface_window) {
GHOST_IWindow *win = ghost_wl_surface_user_data(wl_surface_focus);
seat->system->pushEvent(
new GHOST_EventKey(seat->system->getMilliSeconds(), etype, win, gkey, false, utf8_buf));
@@ -2384,11 +3658,10 @@ static void keyboard_handle_key(void *data,
/* Start timer for repeating key, if applicable. */
if ((seat->key_repeat.rate > 0) && (etype == GHOST_kEventKeyDown) &&
xkb_keymap_key_repeats(xkb_state_get_keymap(seat->xkb_state), key_code)) {
- key_repeat_payload = new GWL_KeyRepeatPlayload({
- .seat = seat,
- .key_code = key_code,
- .key_data = {.gkey = gkey},
- });
+ key_repeat_payload = new GWL_KeyRepeatPlayload();
+ key_repeat_payload->seat = seat;
+ key_repeat_payload->key_code = key_code;
+ key_repeat_payload->key_data.gkey = gkey;
}
}
@@ -2398,7 +3671,7 @@ static void keyboard_handle_key(void *data,
task->getUserData());
GWL_Seat *seat = payload->seat;
- if (wl_surface *wl_surface_focus = seat->keyboard.wl_surface) {
+ if (wl_surface *wl_surface_focus = seat->keyboard.wl_surface_window) {
GHOST_IWindow *win = ghost_wl_surface_user_data(wl_surface_focus);
GHOST_SystemWayland *system = seat->system;
/* Calculate this value every time in case modifier keys are pressed. */
@@ -2441,6 +3714,10 @@ static void keyboard_handle_modifiers(void *data,
if (seat->key_repeat.timer) {
keyboard_handle_key_repeat_reset(seat, true);
}
+
+#ifdef USE_GNOME_KEYBOARD_SUPPRESS_WARNING
+ seat->key_depressed_suppress_warning.any_mod_held = mods_depressed != 0;
+#endif
}
static void keyboard_repeat_handle_info(void *data,
@@ -2474,14 +3751,288 @@ static const struct wl_keyboard_listener keyboard_listener = {
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Listener (Primary Selection Offer), #zwp_primary_selection_offer_v1_listener
+ * \{ */
+
+static CLG_LogRef LOG_WL_PRIMARY_SELECTION_OFFER = {"ghost.wl.handle.primary_selection_offer"};
+#define LOG (&LOG_WL_PRIMARY_SELECTION_OFFER)
+
+static void primary_selection_offer_offer(void *data,
+ struct zwp_primary_selection_offer_v1 *id,
+ const char *type)
+{
+ GWL_PrimarySelection_DataOffer *data_offer = static_cast<GWL_PrimarySelection_DataOffer *>(data);
+ if (data_offer->id != id) {
+ CLOG_INFO(LOG, 2, "offer: %p: offer for unknown selection %p of %s (skipped)", data, id, type);
+ return;
+ }
+
+ data_offer->types.insert(std::string(type));
+}
+
+static const struct zwp_primary_selection_offer_v1_listener primary_selection_offer_listener = {
+ primary_selection_offer_offer,
+};
+
+#undef LOG
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Listener (Primary Selection Device), #zwp_primary_selection_device_v1_listener
+ * \{ */
+
+static CLG_LogRef LOG_WL_PRIMARY_SELECTION_DEVICE = {"ghost.wl.handle.primary_selection_device"};
+#define LOG (&LOG_WL_PRIMARY_SELECTION_DEVICE)
+
+static void primary_selection_device_handle_data_offer(
+ void * /*data*/,
+ struct zwp_primary_selection_device_v1 * /*zwp_primary_selection_device_v1*/,
+ struct zwp_primary_selection_offer_v1 *id)
+{
+ CLOG_INFO(LOG, 2, "data_offer");
+
+ GWL_PrimarySelection_DataOffer *data_offer = new GWL_PrimarySelection_DataOffer;
+ data_offer->id = id;
+ zwp_primary_selection_offer_v1_add_listener(id, &primary_selection_offer_listener, data_offer);
+}
+
+static void primary_selection_device_handle_selection(
+ void *data,
+ struct zwp_primary_selection_device_v1 * /*zwp_primary_selection_device_v1*/,
+ struct zwp_primary_selection_offer_v1 *id)
+{
+ GWL_PrimarySelection *primary = static_cast<GWL_PrimarySelection *>(data);
+
+ std::lock_guard lock{primary->data_offer_mutex};
+
+ /* Delete old data offer. */
+ if (primary->data_offer != nullptr) {
+ gwl_primary_selection_discard_offer(primary);
+ }
+
+ if (id == nullptr) {
+ CLOG_INFO(LOG, 2, "selection: (skipped)");
+ return;
+ }
+ CLOG_INFO(LOG, 2, "selection");
+ /* Get new data offer. */
+ GWL_PrimarySelection_DataOffer *data_offer = static_cast<GWL_PrimarySelection_DataOffer *>(
+ zwp_primary_selection_offer_v1_get_user_data(id));
+ primary->data_offer = data_offer;
+}
+
+static const struct zwp_primary_selection_device_v1_listener primary_selection_device_listener = {
+ primary_selection_device_handle_data_offer,
+ primary_selection_device_handle_selection,
+};
+
+#undef LOG
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Listener (Primary Selection Source), #zwp_primary_selection_source_v1_listener
+ * \{ */
+
+static CLG_LogRef LOG_WL_PRIMARY_SELECTION_SOURCE = {"ghost.wl.handle.primary_selection_source"};
+#define LOG (&LOG_WL_PRIMARY_SELECTION_SOURCE)
+
+static void primary_selection_source_send(void *data,
+ struct zwp_primary_selection_source_v1 * /*source*/,
+ const char * /*mime_type*/,
+ int32_t fd)
+{
+ CLOG_INFO(LOG, 2, "send");
+
+ GWL_PrimarySelection *primary = static_cast<GWL_PrimarySelection *>(data);
+
+ auto write_file_fn = [](GWL_PrimarySelection *primary, const int fd) {
+ if (UNLIKELY(write(fd,
+ primary->data_source->buffer_out.data,
+ primary->data_source->buffer_out.data_size) < 0)) {
+ CLOG_WARN(LOG, "error writing to primary clipboard: %s", std::strerror(errno));
+ }
+ close(fd);
+ primary->data_source_mutex.unlock();
+ };
+
+ primary->data_source_mutex.lock();
+ std::thread write_thread(write_file_fn, primary, fd);
+ write_thread.detach();
+}
+
+static void primary_selection_source_cancelled(void *data,
+ struct zwp_primary_selection_source_v1 *source)
+{
+ CLOG_INFO(LOG, 2, "cancelled");
+
+ GWL_PrimarySelection *primary = static_cast<GWL_PrimarySelection *>(data);
+
+ if (source == primary->data_source->wp_source) {
+ gwl_primary_selection_discard_source(primary);
+ }
+}
+
+static const struct zwp_primary_selection_source_v1_listener primary_selection_source_listener = {
+ primary_selection_source_send,
+ primary_selection_source_cancelled,
+};
+
+#undef LOG
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Listener (Seat), #wl_seat_listener
* \{ */
static CLG_LogRef LOG_WL_SEAT = {"ghost.wl.handle.seat"};
#define LOG (&LOG_WL_SEAT)
+static void gwl_seat_capability_pointer_enable(GWL_Seat *seat)
+{
+ if (seat->wl_pointer) {
+ return;
+ }
+ seat->wl_pointer = wl_seat_get_pointer(seat->wl_seat);
+ seat->cursor.wl_surface_cursor = wl_compositor_create_surface(seat->system->wl_compositor());
+ seat->cursor.visible = true;
+ seat->cursor.wl_buffer = nullptr;
+ if (!get_cursor_settings(seat->cursor.theme_name, seat->cursor.theme_size)) {
+ seat->cursor.theme_name = std::string();
+ seat->cursor.theme_size = default_cursor_size;
+ }
+ wl_pointer_add_listener(seat->wl_pointer, &pointer_listener, seat);
+
+ wl_surface_add_listener(seat->cursor.wl_surface_cursor, &cursor_surface_listener, seat);
+ ghost_wl_surface_tag_cursor_pointer(seat->cursor.wl_surface_cursor);
+
+ zwp_pointer_gestures_v1 *pointer_gestures = seat->system->wp_pointer_gestures();
+ if (pointer_gestures) {
+#ifdef ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE
+ { /* Hold gesture. */
+ struct zwp_pointer_gesture_hold_v1 *gesture = zwp_pointer_gestures_v1_get_hold_gesture(
+ pointer_gestures, seat->wl_pointer);
+ zwp_pointer_gesture_hold_v1_set_user_data(gesture, seat);
+ zwp_pointer_gesture_hold_v1_add_listener(gesture, &gesture_hold_listener, seat);
+ seat->wp_pointer_gesture_hold = gesture;
+ }
+#endif
+#ifdef ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE
+ { /* Pinch gesture. */
+ struct zwp_pointer_gesture_pinch_v1 *gesture = zwp_pointer_gestures_v1_get_pinch_gesture(
+ pointer_gestures, seat->wl_pointer);
+ zwp_pointer_gesture_pinch_v1_set_user_data(gesture, seat);
+ zwp_pointer_gesture_pinch_v1_add_listener(gesture, &gesture_pinch_listener, seat);
+ seat->wp_pointer_gesture_pinch = gesture;
+ }
+#endif
+#ifdef ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE
+ { /* Swipe gesture. */
+ struct zwp_pointer_gesture_swipe_v1 *gesture = zwp_pointer_gestures_v1_get_swipe_gesture(
+ pointer_gestures, seat->wl_pointer);
+ zwp_pointer_gesture_swipe_v1_set_user_data(gesture, seat);
+ zwp_pointer_gesture_swipe_v1_add_listener(gesture, &gesture_swipe_listener, seat);
+ seat->wp_pointer_gesture_swipe = gesture;
+ }
+#endif
+ }
+}
+
+static void gwl_seat_capability_pointer_disable(GWL_Seat *seat)
+{
+ if (!seat->wl_pointer) {
+ return;
+ }
+
+ zwp_pointer_gestures_v1 *pointer_gestures = seat->system->wp_pointer_gestures();
+ if (pointer_gestures) {
+#ifdef ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE
+ { /* Hold gesture. */
+ struct zwp_pointer_gesture_hold_v1 **gesture_p = &seat->wp_pointer_gesture_hold;
+ if (*gesture_p) {
+ zwp_pointer_gesture_hold_v1_destroy(*gesture_p);
+ *gesture_p = nullptr;
+ }
+ }
+#endif
+#ifdef ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE
+ { /* Pinch gesture. */
+ struct zwp_pointer_gesture_pinch_v1 **gesture_p = &seat->wp_pointer_gesture_pinch;
+ if (*gesture_p) {
+ zwp_pointer_gesture_pinch_v1_destroy(*gesture_p);
+ *gesture_p = nullptr;
+ }
+ }
+#endif
+#ifdef ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE
+ { /* Swipe gesture. */
+ struct zwp_pointer_gesture_swipe_v1 **gesture_p = &seat->wp_pointer_gesture_swipe;
+ if (*gesture_p) {
+ zwp_pointer_gesture_swipe_v1_destroy(*gesture_p);
+ *gesture_p = nullptr;
+ }
+ }
+#endif
+ }
+
+ if (seat->cursor.wl_surface_cursor) {
+ wl_surface_destroy(seat->cursor.wl_surface_cursor);
+ seat->cursor.wl_surface_cursor = nullptr;
+ }
+ if (seat->cursor.wl_theme) {
+ wl_cursor_theme_destroy(seat->cursor.wl_theme);
+ seat->cursor.wl_theme = nullptr;
+ }
+
+ wl_pointer_destroy(seat->wl_pointer);
+ seat->wl_pointer = nullptr;
+}
+
+static void gwl_seat_capability_keyboard_enable(GWL_Seat *seat)
+{
+ if (seat->wl_keyboard) {
+ return;
+ }
+ seat->wl_keyboard = wl_seat_get_keyboard(seat->wl_seat);
+ wl_keyboard_add_listener(seat->wl_keyboard, &keyboard_listener, seat);
+}
+
+static void gwl_seat_capability_keyboard_disable(GWL_Seat *seat)
+{
+ if (!seat->wl_keyboard) {
+ return;
+ }
+ if (seat->key_repeat.timer) {
+ keyboard_handle_key_repeat_cancel(seat);
+ }
+ wl_keyboard_destroy(seat->wl_keyboard);
+ seat->wl_keyboard = nullptr;
+}
+
+static void gwl_seat_capability_touch_enable(GWL_Seat *seat)
+{
+ if (seat->wl_touch) {
+ return;
+ }
+ seat->wl_touch = wl_seat_get_touch(seat->wl_seat);
+ wl_touch_set_user_data(seat->wl_touch, seat);
+ wl_touch_add_listener(seat->wl_touch, &touch_seat_listener, seat);
+}
+
+static void gwl_seat_capability_touch_disable(GWL_Seat *seat)
+{
+ if (!seat->wl_touch) {
+ return;
+ }
+ wl_touch_destroy(seat->wl_touch);
+ seat->wl_touch = nullptr;
+}
+
static void seat_handle_capabilities(void *data,
- struct wl_seat *wl_seat,
+ /* Only used in an assert. */
+ [[maybe_unused]] struct wl_seat *wl_seat,
const uint32_t capabilities)
{
CLOG_INFO(LOG,
@@ -2492,27 +4043,27 @@ static void seat_handle_capabilities(void *data,
(capabilities & WL_SEAT_CAPABILITY_TOUCH) != 0);
GWL_Seat *seat = static_cast<GWL_Seat *>(data);
- seat->wl_pointer = nullptr;
- seat->wl_keyboard = nullptr;
+ GHOST_ASSERT(seat->wl_seat == wl_seat, "Seat mismatch");
if (capabilities & WL_SEAT_CAPABILITY_POINTER) {
- seat->wl_pointer = wl_seat_get_pointer(wl_seat);
- seat->cursor.wl_surface = wl_compositor_create_surface(seat->system->compositor());
- seat->cursor.visible = true;
- seat->cursor.wl_buffer = nullptr;
- if (!get_cursor_settings(seat->cursor.theme_name, seat->cursor.size)) {
- seat->cursor.theme_name = std::string();
- seat->cursor.size = default_cursor_size;
- }
- wl_pointer_add_listener(seat->wl_pointer, &pointer_listener, data);
-
- wl_surface_add_listener(seat->cursor.wl_surface, &cursor_surface_listener, data);
- ghost_wl_surface_tag_cursor_pointer(seat->cursor.wl_surface);
+ gwl_seat_capability_pointer_enable(seat);
+ }
+ else {
+ gwl_seat_capability_pointer_disable(seat);
}
if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD) {
- seat->wl_keyboard = wl_seat_get_keyboard(wl_seat);
- wl_keyboard_add_listener(seat->wl_keyboard, &keyboard_listener, data);
+ gwl_seat_capability_keyboard_enable(seat);
+ }
+ else {
+ gwl_seat_capability_keyboard_disable(seat);
+ }
+
+ if (capabilities & WL_SEAT_CAPABILITY_TOUCH) {
+ gwl_seat_capability_touch_enable(seat);
+ }
+ else {
+ gwl_seat_capability_touch_disable(seat);
}
}
@@ -2722,11 +4273,17 @@ static void output_handle_done(void *data, struct wl_output * /*wl_output*/)
static void output_handle_scale(void *data, struct wl_output * /*wl_output*/, const int32_t factor)
{
CLOG_INFO(LOG, 2, "scale");
- static_cast<GWL_Output *>(data)->scale = factor;
+ GWL_Output *output = static_cast<GWL_Output *>(data);
+ output->scale = factor;
+ GHOST_WindowManager *window_manager = output->system->getWindowManager();
if (window_manager) {
for (GHOST_IWindow *iwin : window_manager->getWindows()) {
GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(iwin);
+ const std::vector<GWL_Output *> &outputs = win->outputs();
+ if (std::find(outputs.begin(), outputs.end(), output) == outputs.cend()) {
+ continue;
+ }
win->outputs_changed_update_scale();
}
}
@@ -2747,10 +4304,8 @@ static const struct wl_output_listener output_listener = {
/** \name Listener (XDG WM Base), #xdg_wm_base_listener
* \{ */
-#ifndef WITH_GHOST_WAYLAND_LIBDECOR
-
static CLG_LogRef LOG_WL_XDG_WM_BASE = {"ghost.wl.handle.xdg_wm_base"};
-# define LOG (&LOG_WL_XDG_WM_BASE)
+#define LOG (&LOG_WL_XDG_WM_BASE)
static void shell_handle_ping(void * /*data*/,
struct xdg_wm_base *xdg_wm_base,
@@ -2764,9 +4319,7 @@ static const struct xdg_wm_base_listener shell_listener = {
shell_handle_ping,
};
-# undef LOG
-
-#endif /* !WITH_GHOST_WAYLAND_LIBDECOR. */
+#undef LOG
/** \} */
@@ -2808,99 +4361,597 @@ static struct libdecor_interface libdecor_interface = {
static CLG_LogRef LOG_WL_REGISTRY = {"ghost.wl.handle.registry"};
#define LOG (&LOG_WL_REGISTRY)
-static void global_handle_add(void *data,
- struct wl_registry *wl_registry,
- const uint32_t name,
- const char *interface,
- const uint32_t version)
+/* #GWL_Display.wl_compositor */
+
+static void gwl_registry_compositor_add(GWL_Display *display,
+ const GWL_RegisteryAdd_Params *params)
+{
+ display->wl_compositor = static_cast<wl_compositor *>(
+ wl_registry_bind(display->wl_registry, params->name, &wl_compositor_interface, 3));
+ gwl_registry_entry_add(display, params, nullptr);
+}
+static void gwl_registry_compositor_remove(GWL_Display *display,
+ void * /*user_data*/,
+ const bool /*on_exit*/)
{
- /* Log last since it can be noted if the interface was handled or not. */
- bool found = true;
+ struct wl_compositor **value_p = &display->wl_compositor;
+ wl_compositor_destroy(*value_p);
+ *value_p = nullptr;
+}
- struct GWL_Display *display = static_cast<struct GWL_Display *>(data);
- if (!strcmp(interface, wl_compositor_interface.name)) {
- display->compositor = static_cast<wl_compositor *>(
- wl_registry_bind(wl_registry, name, &wl_compositor_interface, 3));
- }
-#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- /* Pass. */
-#else
- else if (!strcmp(interface, xdg_wm_base_interface.name)) {
- display->xdg_shell = static_cast<xdg_wm_base *>(
- wl_registry_bind(wl_registry, name, &xdg_wm_base_interface, 1));
- xdg_wm_base_add_listener(display->xdg_shell, &shell_listener, nullptr);
- }
- else if (!strcmp(interface, zxdg_decoration_manager_v1_interface.name)) {
- display->xdg_decoration_manager = static_cast<zxdg_decoration_manager_v1 *>(
- wl_registry_bind(wl_registry, name, &zxdg_decoration_manager_v1_interface, 1));
- }
-#endif /* !WITH_GHOST_WAYLAND_LIBDECOR. */
- else if (!strcmp(interface, zxdg_output_manager_v1_interface.name)) {
- display->xdg_output_manager = static_cast<zxdg_output_manager_v1 *>(
- wl_registry_bind(wl_registry, name, &zxdg_output_manager_v1_interface, 2));
- for (GWL_Output *output : display->outputs) {
+/* #GWL_Display.xdg_decor.shell */
+
+static void gwl_registry_xdg_wm_base_add(GWL_Display *display,
+ const GWL_RegisteryAdd_Params *params)
+{
+ GWL_XDG_Decor_System &decor = *display->xdg_decor;
+ decor.shell = static_cast<xdg_wm_base *>(
+ wl_registry_bind(display->wl_registry, params->name, &xdg_wm_base_interface, 1));
+ xdg_wm_base_add_listener(decor.shell, &shell_listener, nullptr);
+ decor.shell_name = params->name;
+ gwl_registry_entry_add(display, params, nullptr);
+}
+static void gwl_registry_xdg_wm_base_remove(GWL_Display *display,
+ void * /*user_data*/,
+ const bool /*on_exit*/)
+{
+ GWL_XDG_Decor_System &decor = *display->xdg_decor;
+ struct xdg_wm_base **value_p = &decor.shell;
+ uint32_t *name_p = &decor.shell_name;
+ xdg_wm_base_destroy(*value_p);
+ *value_p = nullptr;
+ *name_p = WL_NAME_UNSET;
+}
+
+/* #GWL_Display.xdg_decor.manager */
+
+static void gwl_registry_xdg_decoration_manager_add(GWL_Display *display,
+ const GWL_RegisteryAdd_Params *params)
+{
+ GWL_XDG_Decor_System &decor = *display->xdg_decor;
+ decor.manager = static_cast<zxdg_decoration_manager_v1 *>(wl_registry_bind(
+ display->wl_registry, params->name, &zxdg_decoration_manager_v1_interface, 1));
+ decor.manager_name = params->name;
+ gwl_registry_entry_add(display, params, nullptr);
+}
+static void gwl_registry_xdg_decoration_manager_remove(GWL_Display *display,
+ void * /*user_data*/,
+ const bool /*on_exit*/)
+{
+ GWL_XDG_Decor_System &decor = *display->xdg_decor;
+ struct zxdg_decoration_manager_v1 **value_p = &decor.manager;
+ uint32_t *name_p = &decor.manager_name;
+ zxdg_decoration_manager_v1_destroy(*value_p);
+ *value_p = nullptr;
+ *name_p = WL_NAME_UNSET;
+}
+
+/* #GWL_Display.xdg_output_manager */
+
+static void gwl_registry_xdg_output_manager_add(GWL_Display *display,
+ const GWL_RegisteryAdd_Params *params)
+{
+ display->xdg_output_manager = static_cast<zxdg_output_manager_v1 *>(
+ wl_registry_bind(display->wl_registry, params->name, &zxdg_output_manager_v1_interface, 2));
+ gwl_registry_entry_add(display, params, nullptr);
+}
+static void gwl_registry_xdg_output_manager_remove(GWL_Display *display,
+ void * /*user_data*/,
+ const bool /*on_exit*/)
+{
+ struct zxdg_output_manager_v1 **value_p = &display->xdg_output_manager;
+ zxdg_output_manager_v1_destroy(*value_p);
+ *value_p = nullptr;
+}
+
+/* #GWL_Display.wl_output */
+
+static void gwl_registry_wl_output_add(GWL_Display *display, const GWL_RegisteryAdd_Params *params)
+{
+ GWL_Output *output = new GWL_Output;
+ output->system = display->system;
+ output->wl_output = static_cast<wl_output *>(
+ wl_registry_bind(display->wl_registry, params->name, &wl_output_interface, 2));
+ ghost_wl_output_tag(output->wl_output);
+ wl_output_set_user_data(output->wl_output, output);
+
+ display->outputs.push_back(output);
+ wl_output_add_listener(output->wl_output, &output_listener, output);
+ gwl_registry_entry_add(display, params, static_cast<void *>(output));
+}
+static void gwl_registry_wl_output_update(GWL_Display *display,
+ const GWL_RegisteryUpdate_Params *params)
+{
+ GWL_Output *output = static_cast<GWL_Output *>(params->user_data);
+ if (display->xdg_output_manager) {
+ if (output->xdg_output == nullptr) {
output->xdg_output = zxdg_output_manager_v1_get_xdg_output(display->xdg_output_manager,
output->wl_output);
zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, output);
}
}
- else if (!strcmp(interface, wl_output_interface.name)) {
- GWL_Output *output = new GWL_Output;
- output->wl_output = static_cast<wl_output *>(
- wl_registry_bind(wl_registry, name, &wl_output_interface, 2));
- ghost_wl_output_tag(output->wl_output);
- wl_output_set_user_data(output->wl_output, output);
+ else {
+ output->xdg_output = nullptr;
+ }
+}
+static void gwl_registry_wl_output_remove(GWL_Display *display,
+ void *user_data,
+ const bool /*on_exit*/)
+{
+ /* While windows & cursors hold references to outputs, there is no need to manually remove
+ * these references as the compositor will remove references via #wl_surface_listener.leave. */
+ GWL_Output *output = static_cast<GWL_Output *>(user_data);
+ wl_output_destroy(output->wl_output);
+ std::vector<GWL_Output *>::iterator iter = std::find(
+ display->outputs.begin(), display->outputs.end(), output);
+ const int index = (iter != display->outputs.cend()) ?
+ std::distance(display->outputs.begin(), iter) :
+ -1;
+ GHOST_ASSERT(index != -1, "invalid internal state");
+ /* NOTE: always erase even when `on_exit` because `output->xdg_output` is cleared later. */
+ display->outputs.erase(display->outputs.begin() + index);
+ delete output;
+}
+
+/* #GWL_Display.seats */
+
+static void gwl_registry_wl_seat_add(GWL_Display *display, const GWL_RegisteryAdd_Params *params)
+{
+ GWL_Seat *seat = new GWL_Seat;
+ seat->system = display->system;
+ seat->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
+ seat->data_source = new GWL_DataSource;
+ seat->wl_seat = static_cast<wl_seat *>(
+ wl_registry_bind(display->wl_registry, params->name, &wl_seat_interface, 5));
+ display->seats.push_back(seat);
+ wl_seat_add_listener(seat->wl_seat, &seat_listener, seat);
+ gwl_registry_entry_add(display, params, static_cast<void *>(seat));
+}
+static void gwl_registry_wl_seat_update(GWL_Display *display,
+ const GWL_RegisteryUpdate_Params *params)
+{
+ GWL_Seat *seat = static_cast<GWL_Seat *>(params->user_data);
+
+ /* Register data device per seat for IPC between WAYLAND clients. */
+ if (display->wl_data_device_manager) {
+ if (seat->wl_data_device == nullptr) {
+ seat->wl_data_device = wl_data_device_manager_get_data_device(
+ display->wl_data_device_manager, seat->wl_seat);
+ wl_data_device_add_listener(seat->wl_data_device, &data_device_listener, seat);
+ }
+ }
+ else {
+ seat->wl_data_device = nullptr;
+ }
+
+ if (display->wp_tablet_manager) {
+ if (seat->wp_tablet_seat == nullptr) {
+ seat->wp_tablet_seat = zwp_tablet_manager_v2_get_tablet_seat(display->wp_tablet_manager,
+ seat->wl_seat);
+ zwp_tablet_seat_v2_add_listener(seat->wp_tablet_seat, &tablet_seat_listener, seat);
+ }
+ }
+ else {
+ seat->wp_tablet_seat = nullptr;
+ }
- display->outputs.push_back(output);
- wl_output_add_listener(output->wl_output, &output_listener, output);
+ if (display->wp_primary_selection_device_manager) {
+ if (seat->wp_primary_selection_device == nullptr) {
+ seat->wp_primary_selection_device = zwp_primary_selection_device_manager_v1_get_device(
+ display->wp_primary_selection_device_manager, seat->wl_seat);
- if (display->xdg_output_manager) {
- output->xdg_output = zxdg_output_manager_v1_get_xdg_output(display->xdg_output_manager,
- output->wl_output);
- zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, output);
+ zwp_primary_selection_device_v1_add_listener(seat->wp_primary_selection_device,
+ &primary_selection_device_listener,
+ &seat->primary_selection);
+ }
+ }
+ else {
+ seat->wp_primary_selection_device = nullptr;
+ }
+}
+static void gwl_registry_wl_seat_remove(GWL_Display *display, void *user_data, const bool on_exit)
+{
+ GWL_Seat *seat = static_cast<GWL_Seat *>(user_data);
+
+ /* First handle members that require locking.
+ * While highly unlikely, it's possible they are being used while this function runs. */
+ {
+ std::lock_guard lock{seat->data_source_mutex};
+ if (seat->data_source) {
+ gwl_simple_buffer_free_data(&seat->data_source->buffer_out);
+ if (seat->data_source->wl_source) {
+ wl_data_source_destroy(seat->data_source->wl_source);
+ }
+ delete seat->data_source;
}
}
- else if (!strcmp(interface, wl_seat_interface.name)) {
- GWL_Seat *seat = new GWL_Seat;
- seat->system = display->system;
- seat->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
- seat->data_source = new GWL_DataSource;
- seat->wl_seat = static_cast<wl_seat *>(
- wl_registry_bind(wl_registry, name, &wl_seat_interface, 5));
- display->seats.push_back(seat);
- wl_seat_add_listener(seat->wl_seat, &seat_listener, seat);
+
+ {
+ std::lock_guard lock{seat->data_offer_dnd_mutex};
+ if (seat->data_offer_dnd) {
+ wl_data_offer_destroy(seat->data_offer_dnd->id);
+ delete seat->data_offer_dnd;
+ }
}
- else if (!strcmp(interface, wl_shm_interface.name)) {
- display->shm = static_cast<wl_shm *>(
- wl_registry_bind(wl_registry, name, &wl_shm_interface, 1));
+
+ {
+ std::lock_guard lock{seat->data_offer_copy_paste_mutex};
+ if (seat->data_offer_copy_paste) {
+ wl_data_offer_destroy(seat->data_offer_copy_paste->id);
+ delete seat->data_offer_copy_paste;
+ }
}
- else if (!strcmp(interface, wl_data_device_manager_interface.name)) {
- display->data_device_manager = static_cast<wl_data_device_manager *>(
- wl_registry_bind(wl_registry, name, &wl_data_device_manager_interface, 3));
+
+ {
+ GWL_PrimarySelection *primary = &seat->primary_selection;
+ std::lock_guard lock{primary->data_offer_mutex};
+ gwl_primary_selection_discard_offer(primary);
}
- else if (!strcmp(interface, zwp_tablet_manager_v2_interface.name)) {
- display->tablet_manager = static_cast<zwp_tablet_manager_v2 *>(
- wl_registry_bind(wl_registry, name, &zwp_tablet_manager_v2_interface, 1));
+
+ {
+ GWL_PrimarySelection *primary = &seat->primary_selection;
+ std::lock_guard lock{primary->data_source_mutex};
+ gwl_primary_selection_discard_source(primary);
}
- else if (!strcmp(interface, zwp_relative_pointer_manager_v1_interface.name)) {
- display->relative_pointer_manager = static_cast<zwp_relative_pointer_manager_v1 *>(
- wl_registry_bind(wl_registry, name, &zwp_relative_pointer_manager_v1_interface, 1));
+
+ if (seat->wp_primary_selection_device) {
+ zwp_primary_selection_device_v1_destroy(seat->wp_primary_selection_device);
+ }
+
+ if (seat->wl_data_device) {
+ wl_data_device_release(seat->wl_data_device);
+ }
+
+ if (seat->cursor.custom_data) {
+ munmap(seat->cursor.custom_data, seat->cursor.custom_data_size);
+ }
+
+ /* Disable all capabilities as a way to free:
+ * - `seat.wl_pointer` (and related cursor variables).
+ * - `seat.wl_touch`.
+ * - `seat.wl_keyboard`.
+ */
+ gwl_seat_capability_pointer_disable(seat);
+ gwl_seat_capability_keyboard_disable(seat);
+ gwl_seat_capability_touch_disable(seat);
+
+ /* Un-referencing checks for NULL case. */
+ xkb_state_unref(seat->xkb_state);
+ xkb_state_unref(seat->xkb_state_empty);
+ xkb_state_unref(seat->xkb_state_empty_with_shift);
+ xkb_state_unref(seat->xkb_state_empty_with_numlock);
+
+ xkb_context_unref(seat->xkb_context);
+
+ /* Remove the seat. */
+ wl_seat_destroy(seat->wl_seat);
+
+ std::vector<GWL_Seat *>::iterator iter = std::find(
+ display->seats.begin(), display->seats.end(), seat);
+ const int index = (iter != display->seats.cend()) ? std::distance(display->seats.begin(), iter) :
+ -1;
+ GHOST_ASSERT(index != -1, "invalid internal state");
+
+ if (!on_exit) {
+ if (display->seats_active_index >= index) {
+ display->seats_active_index -= 1;
+ }
+ display->seats.erase(display->seats.begin() + index);
+ }
+ delete seat;
+}
+
+/* #GWL_Display.wl_shm */
+
+static void gwl_registry_wl_shm_add(GWL_Display *display, const GWL_RegisteryAdd_Params *params)
+{
+ display->wl_shm = static_cast<wl_shm *>(
+ wl_registry_bind(display->wl_registry, params->name, &wl_shm_interface, 1));
+ gwl_registry_entry_add(display, params, nullptr);
+}
+static void gwl_registry_wl_shm_remove(GWL_Display *display,
+ void * /*user_data*/,
+ const bool /*on_exit*/)
+{
+ struct wl_shm **value_p = &display->wl_shm;
+ wl_shm_destroy(*value_p);
+ *value_p = nullptr;
+}
+
+/* #GWL_Display.wl_data_device_manager */
+
+static void gwl_registry_wl_data_device_manager_add(GWL_Display *display,
+ const GWL_RegisteryAdd_Params *params)
+{
+ display->wl_data_device_manager = static_cast<wl_data_device_manager *>(
+ wl_registry_bind(display->wl_registry, params->name, &wl_data_device_manager_interface, 3));
+ gwl_registry_entry_add(display, params, nullptr);
+}
+static void gwl_registry_wl_data_device_manager_remove(GWL_Display *display,
+ void * /*user_data*/,
+ const bool /*on_exit*/)
+{
+ struct wl_data_device_manager **value_p = &display->wl_data_device_manager;
+ wl_data_device_manager_destroy(*value_p);
+ *value_p = nullptr;
+}
+
+/* #GWL_Display.wp_tablet_manager */
+
+static void gwl_registry_wp_tablet_manager_add(GWL_Display *display,
+ const GWL_RegisteryAdd_Params *params)
+{
+ display->wp_tablet_manager = static_cast<zwp_tablet_manager_v2 *>(
+ wl_registry_bind(display->wl_registry, params->name, &zwp_tablet_manager_v2_interface, 1));
+ gwl_registry_entry_add(display, params, nullptr);
+}
+static void gwl_registry_wp_tablet_manager_remove(GWL_Display *display,
+ void * /*user_data*/,
+ const bool /*on_exit*/)
+{
+ struct zwp_tablet_manager_v2 **value_p = &display->wp_tablet_manager;
+ zwp_tablet_manager_v2_destroy(*value_p);
+ *value_p = nullptr;
+}
+
+/* #GWL_Display.wp_relative_pointer_manager */
+
+static void gwl_registry_wp_relative_pointer_manager_add(GWL_Display *display,
+ const GWL_RegisteryAdd_Params *params)
+{
+ display->wp_relative_pointer_manager = static_cast<zwp_relative_pointer_manager_v1 *>(
+ wl_registry_bind(
+ display->wl_registry, params->name, &zwp_relative_pointer_manager_v1_interface, 1));
+ gwl_registry_entry_add(display, params, nullptr);
+}
+static void gwl_registry_wp_relative_pointer_manager_remove(GWL_Display *display,
+ void * /*user_data*/,
+ const bool /*on_exit*/)
+{
+ struct zwp_relative_pointer_manager_v1 **value_p = &display->wp_relative_pointer_manager;
+ zwp_relative_pointer_manager_v1_destroy(*value_p);
+ *value_p = nullptr;
+}
+
+/* #GWL_Display.wp_pointer_constraints */
+
+static void gwl_registry_wp_pointer_constraints_add(GWL_Display *display,
+ const GWL_RegisteryAdd_Params *params)
+{
+ display->wp_pointer_constraints = static_cast<zwp_pointer_constraints_v1 *>(wl_registry_bind(
+ display->wl_registry, params->name, &zwp_pointer_constraints_v1_interface, 1));
+ gwl_registry_entry_add(display, params, nullptr);
+}
+static void gwl_registry_wp_pointer_constraints_remove(GWL_Display *display,
+ void * /*user_data*/,
+ const bool /*on_exit*/)
+{
+ struct zwp_pointer_constraints_v1 **value_p = &display->wp_pointer_constraints;
+ zwp_pointer_constraints_v1_destroy(*value_p);
+ *value_p = nullptr;
+}
+
+/* #GWL_Display.wp_pointer_gestures */
+
+static void gwl_registry_wp_pointer_gestures_add(GWL_Display *display,
+ const GWL_RegisteryAdd_Params *params)
+{
+ display->wp_pointer_gestures = static_cast<zwp_pointer_gestures_v1 *>(
+ wl_registry_bind(display->wl_registry, params->name, &zwp_pointer_gestures_v1_interface, 3));
+ gwl_registry_entry_add(display, params, nullptr);
+}
+static void gwl_registry_wp_pointer_gestures_remove(GWL_Display *display,
+ void * /*user_data*/,
+ const bool /*on_exit*/)
+{
+ struct zwp_pointer_gestures_v1 **value_p = &display->wp_pointer_gestures;
+ zwp_pointer_gestures_v1_destroy(*value_p);
+ *value_p = nullptr;
+}
+
+/* #GWL_Display.wp_primary_selection_device_manager */
+
+static void gwl_registry_wp_primary_selection_device_manager_add(
+ struct GWL_Display *display, const GWL_RegisteryAdd_Params *params)
+{
+ display->wp_primary_selection_device_manager =
+ static_cast<zwp_primary_selection_device_manager_v1 *>(
+ wl_registry_bind(display->wl_registry,
+ params->name,
+ &zwp_primary_selection_device_manager_v1_interface,
+ 1));
+ gwl_registry_entry_add(display, params, nullptr);
+}
+static void gwl_registry_wp_primary_selection_device_manager_remove(GWL_Display *display,
+ void * /*user_data*/,
+ const bool /*on_exit*/)
+{
+ struct zwp_primary_selection_device_manager_v1 **value_p =
+ &display->wp_primary_selection_device_manager;
+ zwp_primary_selection_device_manager_v1_destroy(*value_p);
+ *value_p = nullptr;
+}
+
+/**
+ * Map interfaces to initialization functions.
+ *
+ * \note This list also defines the order interfaces are removed.
+ * On exit interface removal runs from last to first to avoid potential bugs
+ * caused by undefined order of removal.
+ *
+ * In general fundamental, low level objects such as the compositor and shared memory
+ * should be declared earlier and other interfaces that may use them should be declared later.
+ */
+static const GWL_RegistryHandler gwl_registry_handlers[] = {
+ /* Low level interfaces. */
+ {
+ &wl_compositor_interface.name,
+ gwl_registry_compositor_add,
+ nullptr,
+ gwl_registry_compositor_remove,
+ },
+ {
+ &wl_shm_interface.name,
+ gwl_registry_wl_shm_add,
+ nullptr,
+ gwl_registry_wl_shm_remove,
+ },
+ {
+ &xdg_wm_base_interface.name,
+ gwl_registry_xdg_wm_base_add,
+ nullptr,
+ gwl_registry_xdg_wm_base_remove,
+ },
+ /* Managers. */
+ {
+ &zxdg_decoration_manager_v1_interface.name,
+ gwl_registry_xdg_decoration_manager_add,
+ nullptr,
+ gwl_registry_xdg_decoration_manager_remove,
+ },
+ {
+ &zxdg_output_manager_v1_interface.name,
+ gwl_registry_xdg_output_manager_add,
+ nullptr,
+ gwl_registry_xdg_output_manager_remove,
+ },
+ {
+ &wl_data_device_manager_interface.name,
+ gwl_registry_wl_data_device_manager_add,
+ nullptr,
+ gwl_registry_wl_data_device_manager_remove,
+ },
+ {
+ &zwp_primary_selection_device_manager_v1_interface.name,
+ gwl_registry_wp_primary_selection_device_manager_add,
+ nullptr,
+ gwl_registry_wp_primary_selection_device_manager_remove,
+ },
+ {
+ &zwp_tablet_manager_v2_interface.name,
+ gwl_registry_wp_tablet_manager_add,
+ nullptr,
+ gwl_registry_wp_tablet_manager_remove,
+ },
+ {
+ &zwp_relative_pointer_manager_v1_interface.name,
+ gwl_registry_wp_relative_pointer_manager_add,
+ nullptr,
+ gwl_registry_wp_relative_pointer_manager_remove,
+ },
+ /* Higher level interfaces. */
+ {
+ &zwp_pointer_constraints_v1_interface.name,
+ gwl_registry_wp_pointer_constraints_add,
+ nullptr,
+ gwl_registry_wp_pointer_constraints_remove,
+ },
+ {
+ &zwp_pointer_gestures_v1_interface.name,
+ gwl_registry_wp_pointer_gestures_add,
+ nullptr,
+ gwl_registry_wp_pointer_gestures_remove,
+ },
+ /* Display outputs. */
+ {
+ &wl_output_interface.name,
+ gwl_registry_wl_output_add,
+ gwl_registry_wl_output_update,
+ gwl_registry_wl_output_remove,
+ },
+ /* Seats.
+ * Keep the seat near the end to ensure other types are created first.
+ * as the seat creates data based on other interfaces. */
+ {
+ &wl_seat_interface.name,
+ gwl_registry_wl_seat_add,
+ gwl_registry_wl_seat_update,
+ gwl_registry_wl_seat_remove,
+ },
+ {nullptr, nullptr, nullptr},
+};
+
+/**
+ * Workaround for `gwl_registry_handlers` order of declaration,
+ * preventing `ARRAY_SIZE(gwl_registry_handlers) - 1` being used.
+ */
+static int gwl_registry_handler_interface_slot_max()
+{
+ return ARRAY_SIZE(gwl_registry_handlers) - 1;
+}
+
+static int gwl_registry_handler_interface_slot_from_string(const char *interface)
+{
+ for (const GWL_RegistryHandler *handler = gwl_registry_handlers; handler->interface_p != nullptr;
+ handler++) {
+ if (STREQ(interface, *handler->interface_p)) {
+ return int(handler - gwl_registry_handlers);
+ }
}
- else if (!strcmp(interface, zwp_pointer_constraints_v1_interface.name)) {
- display->pointer_constraints = static_cast<zwp_pointer_constraints_v1 *>(
- wl_registry_bind(wl_registry, name, &zwp_pointer_constraints_v1_interface, 1));
+ return -1;
+}
+
+static const GWL_RegistryHandler *gwl_registry_handler_from_interface_slot(int interface_slot)
+{
+ GHOST_ASSERT(uint32_t(interface_slot) < uint32_t(gwl_registry_handler_interface_slot_max()),
+ "Index out of range");
+ return &gwl_registry_handlers[interface_slot];
+}
+
+static void global_handle_add(void *data,
+ [[maybe_unused]] struct wl_registry *wl_registry,
+ const uint32_t name,
+ const char *interface,
+ const uint32_t version)
+{
+ /* Log last since it's useful to know if the interface was handled or not. */
+ GWL_Display *display = static_cast<GWL_Display *>(data);
+ GHOST_ASSERT(display->wl_registry == wl_registry, "Registry argument must match!");
+
+ const int interface_slot = gwl_registry_handler_interface_slot_from_string(interface);
+ bool added = false;
+
+ if (interface_slot != -1) {
+ const GWL_RegistryHandler *handler = &gwl_registry_handlers[interface_slot];
+ const GWL_RegistryEntry *registry_entry_prev = display->registry_entry;
+
+ /* The interface name that is ensured not to be freed. */
+ GWL_RegisteryAdd_Params params = {
+ .name = name,
+ .interface_slot = interface_slot,
+ .version = version,
+ };
+
+ handler->add_fn(display, &params);
+
+ added = display->registry_entry != registry_entry_prev;
}
else {
- found = false;
+ /* Not found. */
+#ifdef USE_GNOME_NEEDS_LIBDECOR_HACK
+ if (STRPREFIX(interface, "gtk_shell")) { /* `gtk_shell1` at time of writing. */
+ /* Only require `libdecor` when built with X11 support,
+ * otherwise there is nothing to fall back on. */
+ display->libdecor_required = true;
+ }
+#endif
}
CLOG_INFO(LOG,
2,
"add %s(interface=%s, version=%u, name=%u)",
- found ? "" : "(skipped), ",
+ (interface_slot != -1) ? (added ? "" : "(found but not added)") : "(skipped), ",
interface,
version,
name);
+
+ /* Initialization avoids excessive calls by calling update after all have been initialized. */
+ if (added) {
+ if (display->registry_skip_update_all == false) {
+ /* See doc-string for rationale on updating all on add/removal. */
+ gwl_registry_entry_update_all(display, interface_slot);
+ }
+ }
}
/**
@@ -2912,11 +4963,28 @@ static void global_handle_add(void *data,
* name is no longer available. If the client bound to the global
* using the bind request, the client should now destroy that object.
*/
-static void global_handle_remove(void * /*data*/,
- struct wl_registry * /*wl_registry*/,
+static void global_handle_remove(void *data,
+ [[maybe_unused]] struct wl_registry *wl_registry,
const uint32_t name)
{
- CLOG_INFO(LOG, 2, "remove (name=%u)", name);
+ GWL_Display *display = static_cast<GWL_Display *>(data);
+ GHOST_ASSERT(display->wl_registry == wl_registry, "Registry argument must match!");
+
+ int interface_slot = 0;
+ const bool removed = gwl_registry_entry_remove_by_name(display, name, &interface_slot);
+
+ CLOG_INFO(LOG,
+ 2,
+ "remove (name=%u, interface=%s)",
+ name,
+ removed ? *gwl_registry_handlers[interface_slot].interface_p : "(unknown)");
+
+ if (removed) {
+ if (display->registry_skip_update_all == false) {
+ /* See doc-string for rationale on updating all on add/removal. */
+ gwl_registry_entry_update_all(display, interface_slot);
+ }
+ }
}
static const struct wl_registry_listener registry_listener = {
@@ -2929,65 +4997,139 @@ static const struct wl_registry_listener registry_listener = {
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Listener (Display), #wl_display_listener
+ * \{ */
+
+static CLG_LogRef LOG_WL_DISPLAY = {"ghost.wl.handle.display"};
+#define LOG (&LOG_WL_DISPLAY)
+
+static void display_handle_error(
+ void *data, struct wl_display *wl_display, void *object_id, uint32_t code, const char *message)
+{
+ GWL_Display *display = static_cast<GWL_Display *>(data);
+ GHOST_ASSERT(display->wl_display == wl_display, "Invalid internal state");
+ (void)display;
+
+ /* NOTE: code is #wl_display_error, there isn't a convenient way to convert to an ID. */
+ CLOG_INFO(LOG, 2, "error (code=%u, object_id=%p, message=%s)", code, object_id, message);
+}
+
+static void display_handle_delete_id(void *data, struct wl_display *wl_display, uint32_t id)
+{
+ GWL_Display *display = static_cast<GWL_Display *>(data);
+ GHOST_ASSERT(display->wl_display == wl_display, "Invalid internal state");
+ (void)display;
+
+ CLOG_INFO(LOG, 2, "delete_id (id=%u)", id);
+}
+
+static const struct wl_display_listener display_listener = {
+ display_handle_error,
+ display_handle_delete_id,
+};
+
+#undef LOG
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name GHOST Implementation
*
* WAYLAND specific implementation of the #GHOST_System interface.
* \{ */
-GHOST_SystemWayland::GHOST_SystemWayland() : GHOST_System(), d(new GWL_Display)
+GHOST_SystemWayland::GHOST_SystemWayland(bool background)
+ : GHOST_System(), display_(new GWL_Display)
{
wl_log_set_handler_client(ghost_wayland_log_handler);
- d->system = this;
+ display_->system = this;
/* Connect to the Wayland server. */
- d->display = wl_display_connect(nullptr);
- if (!d->display) {
- display_destroy(d);
+ display_->wl_display = wl_display_connect(nullptr);
+ if (!display_->wl_display) {
+ gwl_display_destroy(display_);
throw std::runtime_error("Wayland: unable to connect to display!");
}
+ /* This may be removed later if decorations are required, needed as part of registration. */
+ display_->xdg_decor = new GWL_XDG_Decor_System;
+
+ wl_display_add_listener(display_->wl_display, &display_listener, display_);
+
/* Register interfaces. */
- struct wl_registry *registry = wl_display_get_registry(d->display);
- wl_registry_add_listener(registry, &registry_listener, d);
- /* Call callback for registry listener. */
- wl_display_roundtrip(d->display);
- /* Call callbacks for registered listeners. */
- wl_display_roundtrip(d->display);
- wl_registry_destroy(registry);
+ {
+ display_->registry_skip_update_all = true;
+ struct wl_registry *registry = wl_display_get_registry(display_->wl_display);
+ display_->wl_registry = registry;
+ wl_registry_add_listener(registry, &registry_listener, display_);
+ /* First round-trip to receive all registry objects. */
+ wl_display_roundtrip(display_->wl_display);
+ /* Second round-trip to receive all output events. */
+ wl_display_roundtrip(display_->wl_display);
-#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- d->decor_context = libdecor_new(d->display, &libdecor_interface);
- if (!d->decor_context) {
- display_destroy(d);
- throw std::runtime_error("Wayland: unable to create window decorations!");
+ /* Account for dependencies between interfaces. */
+ gwl_registry_entry_update_all(display_, -1);
+
+ display_->registry_skip_update_all = false;
}
-#else
- if (!d->xdg_shell) {
- display_destroy(d);
- throw std::runtime_error("Wayland: unable to access xdg_shell!");
+
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+ /* Ignore windowing requirements when running in background mode,
+ * as it doesn't make sense to fall back to X11 because of windowing functionality
+ * in background mode, also LIBDECOR is crashing in background mode `blender -b -f 1`
+ * for e.g. while it could be fixed, requiring the library at all makes no sense . */
+ if (background) {
+ display_->libdecor_required = false;
}
-#endif
- /* Register data device per seat for IPC between Wayland clients. */
- if (d->data_device_manager) {
- for (GWL_Seat *seat : d->seats) {
- seat->data_device = wl_data_device_manager_get_data_device(d->data_device_manager,
- seat->wl_seat);
- wl_data_device_add_listener(seat->data_device, &data_device_listener, seat);
+ if (display_->libdecor_required) {
+ gwl_xdg_decor_system_destroy(display_, display_->xdg_decor);
+ display_->xdg_decor = nullptr;
+
+ if (!has_libdecor) {
+# ifdef WITH_GHOST_X11
+ /* LIBDECOR was the only reason X11 was used, let the user know they need it installed. */
+ fprintf(stderr,
+ "WAYLAND found but libdecor was not, install libdecor for Wayland support, "
+ "falling back to X11\n");
+# endif
+ gwl_display_destroy(display_);
+ throw std::runtime_error("Wayland: unable to find libdecor!");
+
+ use_libdecor = true;
}
}
+ else {
+ use_libdecor = false;
+ }
+#endif /* WITH_GHOST_WAYLAND_LIBDECOR */
- if (d->tablet_manager) {
- for (GWL_Seat *seat : d->seats) {
- seat->tablet_seat = zwp_tablet_manager_v2_get_tablet_seat(d->tablet_manager, seat->wl_seat);
- zwp_tablet_seat_v2_add_listener(seat->tablet_seat, &tablet_seat_listener, seat);
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+ if (use_libdecor) {
+ display_->libdecor = new GWL_LibDecor_System;
+ GWL_LibDecor_System &decor = *display_->libdecor;
+ decor.context = libdecor_new(display_->wl_display, &libdecor_interface);
+ if (!decor.context) {
+ gwl_display_destroy(display_);
+ throw std::runtime_error("Wayland: unable to create window decorations!");
+ }
+ }
+ else
+#else
+ (void)background;
+#endif
+ {
+ GWL_XDG_Decor_System &decor = *display_->xdg_decor;
+ if (!decor.shell) {
+ gwl_display_destroy(display_);
+ throw std::runtime_error("Wayland: unable to access xdg_shell!");
}
}
}
GHOST_SystemWayland::~GHOST_SystemWayland()
{
- display_destroy(d);
+ gwl_display_destroy(display_);
}
GHOST_TSuccess GHOST_SystemWayland::init()
@@ -3022,13 +5164,17 @@ bool GHOST_SystemWayland::processEvents(bool waitForEvent)
#endif /* WITH_INPUT_NDOF */
if (waitForEvent) {
- wl_display_dispatch(d->display);
+ if (wl_display_dispatch(display_->wl_display) == -1) {
+ ghost_wl_display_report_error(display_->wl_display);
+ }
}
else {
- wl_display_roundtrip(d->display);
+ if (wl_display_roundtrip(display_->wl_display) == -1) {
+ ghost_wl_display_report_error(display_->wl_display);
+ }
}
- if ((getEventManager()->getNumEvents() > 0)) {
+ if (getEventManager()->getNumEvents() > 0) {
any_processed = true;
}
@@ -3042,50 +5188,72 @@ bool GHOST_SystemWayland::setConsoleWindowState(GHOST_TConsoleWindowState /*acti
GHOST_TSuccess GHOST_SystemWayland::getModifierKeys(GHOST_ModifierKeys &keys) const
{
- if (UNLIKELY(d->seats.empty())) {
+ GWL_Seat *seat = gwl_display_seat_active_get(display_);
+ if (UNLIKELY(!seat)) {
return GHOST_kFailure;
}
- GWL_Seat *seat = d->seats[0];
-
- bool val;
-
- /* NOTE: XKB doesn't differentiate between left/right modifiers
- * for it's internal modifier state storage. */
- const xkb_mod_mask_t state = xkb_state_serialize_mods(seat->xkb_state, XKB_STATE_MODS_ALL);
-
-#define MOD_TEST(state, mod) ((mod != XKB_MOD_INVALID) && (state & (1 << mod)))
-
- val = MOD_TEST(state, seat->xkb_keymap_mod_index.shift);
- keys.set(GHOST_kModifierKeyLeftShift, val);
- keys.set(GHOST_kModifierKeyRightShift, val);
+ const xkb_mod_mask_t state = xkb_state_serialize_mods(seat->xkb_state, XKB_STATE_MODS_DEPRESSED);
- val = MOD_TEST(state, seat->xkb_keymap_mod_index.alt);
- keys.set(GHOST_kModifierKeyLeftAlt, val);
- keys.set(GHOST_kModifierKeyRightAlt, val);
-
- val = MOD_TEST(state, seat->xkb_keymap_mod_index.ctrl);
- keys.set(GHOST_kModifierKeyLeftControl, val);
- keys.set(GHOST_kModifierKeyRightControl, val);
-
- val = MOD_TEST(state, seat->xkb_keymap_mod_index.logo);
- keys.set(GHOST_kModifierKeyOS, val);
+ bool show_warning = true;
+#ifdef USE_GNOME_KEYBOARD_SUPPRESS_WARNING
+ if ((seat->key_depressed_suppress_warning.any_mod_held == true) &&
+ (seat->key_depressed_suppress_warning.any_keys_held_on_enter == false)) {
+ /* The compositor gave us invalid information, don't show a warning. */
+ show_warning = false;
+ }
+#endif
- val = MOD_TEST(state, seat->xkb_keymap_mod_index.num);
- keys.set(GHOST_kModifierKeyNum, val);
+ /* Use local #GWL_KeyboardDepressedState to check which key is pressed.
+ * Use XKB as the source of truth, if there is any discrepancy. */
+ for (int i = 0; i < MOD_INDEX_NUM; i++) {
+ if (UNLIKELY(seat->xkb_keymap_mod_index[i] == XKB_MOD_INVALID)) {
+ continue;
+ }
+ const GWL_ModifierInfo &mod_info = g_modifier_info_table[i];
+ const bool val = (state & (1 << seat->xkb_keymap_mod_index[i])) != 0;
+ bool val_l = seat->key_depressed.mods[GHOST_KEY_MODIFIER_TO_INDEX(mod_info.key_l)] > 0;
+ bool val_r = seat->key_depressed.mods[GHOST_KEY_MODIFIER_TO_INDEX(mod_info.key_r)] > 0;
+
+ /* This shouldn't be needed, but guard against any possibility of modifiers being stuck.
+ * Warn so if this happens it can be investigated. */
+ if (val) {
+ if (UNLIKELY(!(val_l || val_r))) {
+ if (show_warning) {
+ CLOG_WARN(&LOG_WL_KEYBOARD_DEPRESSED_STATE,
+ "modifier (%s) state is inconsistent (GHOST held keys do not match XKB)",
+ mod_info.display_name);
+ }
+ /* Picking the left is arbitrary. */
+ val_l = true;
+ }
+ }
+ else {
+ if (UNLIKELY(val_l || val_r)) {
+ if (show_warning) {
+ CLOG_WARN(&LOG_WL_KEYBOARD_DEPRESSED_STATE,
+ "modifier (%s) state is inconsistent (GHOST released keys do not match XKB)",
+ mod_info.display_name);
+ }
+ val_l = false;
+ val_r = false;
+ }
+ }
-#undef MOD_TEST
+ keys.set(mod_info.mod_l, val_l);
+ keys.set(mod_info.mod_r, val_r);
+ }
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_SystemWayland::getButtons(GHOST_Buttons &buttons) const
{
- if (UNLIKELY(d->seats.empty())) {
+ GWL_Seat *seat = gwl_display_seat_active_get(display_);
+ if (UNLIKELY(!seat)) {
return GHOST_kFailure;
}
- GWL_Seat *seat = d->seats[0];
- GWL_SeatStatePointer *seat_state_pointer = seat_state_pointer_active(seat);
+ GWL_SeatStatePointer *seat_state_pointer = gwl_seat_state_pointer_active(seat);
if (!seat_state_pointer) {
return GHOST_kFailure;
}
@@ -3094,48 +5262,214 @@ GHOST_TSuccess GHOST_SystemWayland::getButtons(GHOST_Buttons &buttons) const
return GHOST_kSuccess;
}
-char *GHOST_SystemWayland::getClipboard(bool /*selection*/) const
+/**
+ * Return a mime type which is supported by GHOST and exists in `types`
+ * (defined by the data offer).
+ */
+static const char *system_clipboard_text_mime_type(
+ const std::unordered_set<std::string> &data_offer_types)
+{
+ const char *ghost_supported_types[] = {ghost_wl_mime_text_utf8, ghost_wl_mime_text_plain};
+ for (size_t i = 0; i < ARRAY_SIZE(ghost_supported_types); i++) {
+ if (data_offer_types.count(ghost_supported_types[i])) {
+ return ghost_supported_types[i];
+ }
+ }
+ return nullptr;
+}
+
+static char *system_clipboard_get_primary_selection(GWL_Display *display)
+{
+ GWL_Seat *seat = gwl_display_seat_active_get(display);
+ if (UNLIKELY(!seat)) {
+ return nullptr;
+ }
+ GWL_PrimarySelection *primary = &seat->primary_selection;
+ std::mutex &mutex = primary->data_offer_mutex;
+
+ mutex.lock();
+ bool mutex_locked = true;
+ char *data = nullptr;
+
+ GWL_PrimarySelection_DataOffer *data_offer = primary->data_offer;
+ if (data_offer != nullptr) {
+ const char *mime_receive = system_clipboard_text_mime_type(data_offer->types);
+ if (mime_receive) {
+ /* Receive the clipboard in a thread, performing round-trips while waiting.
+ * This is needed so pasting contents from our own `primary->data_source` doesn't hang. */
+ struct ThreadResult {
+ char *data = nullptr;
+ std::atomic<bool> done = false;
+ } thread_result;
+ auto read_clipboard_fn = [](GWL_PrimarySelection_DataOffer *data_offer,
+ const char *mime_receive,
+ std::mutex *mutex,
+ struct ThreadResult *thread_result) {
+ size_t data_len = 0;
+ thread_result->data = read_buffer_from_primary_selection_offer(
+ data_offer, mime_receive, mutex, true, &data_len);
+ thread_result->done = true;
+ };
+ std::thread read_thread(read_clipboard_fn, data_offer, mime_receive, &mutex, &thread_result);
+ read_thread.detach();
+
+ while (!thread_result.done) {
+ wl_display_roundtrip(display->wl_display);
+ }
+ data = thread_result.data;
+
+ /* Reading the data offer unlocks the mutex. */
+ mutex_locked = false;
+ }
+ }
+ if (mutex_locked) {
+ mutex.unlock();
+ }
+ return data;
+}
+
+static char *system_clipboard_get(GWL_Display *display)
{
- char *clipboard = static_cast<char *>(malloc((selection.size() + 1)));
- memcpy(clipboard, selection.data(), selection.size() + 1);
- return clipboard;
+ GWL_Seat *seat = gwl_display_seat_active_get(display);
+ if (UNLIKELY(!seat)) {
+ return nullptr;
+ }
+ std::mutex &mutex = seat->data_offer_copy_paste_mutex;
+
+ mutex.lock();
+ bool mutex_locked = true;
+ char *data = nullptr;
+
+ GWL_DataOffer *data_offer = seat->data_offer_copy_paste;
+ if (data_offer != nullptr) {
+ const char *mime_receive = system_clipboard_text_mime_type(data_offer->types);
+ if (mime_receive) {
+ /* Receive the clipboard in a thread, performing round-trips while waiting.
+ * This is needed so pasting contents from our own `seat->data_source` doesn't hang. */
+ struct ThreadResult {
+ char *data = nullptr;
+ std::atomic<bool> done = false;
+ } thread_result;
+ auto read_clipboard_fn = [](GWL_DataOffer *data_offer,
+ const char *mime_receive,
+ std::mutex *mutex,
+ struct ThreadResult *thread_result) {
+ size_t data_len = 0;
+ thread_result->data = read_buffer_from_data_offer(
+ data_offer, mime_receive, mutex, true, &data_len);
+ thread_result->done = true;
+ };
+ std::thread read_thread(read_clipboard_fn, data_offer, mime_receive, &mutex, &thread_result);
+ read_thread.detach();
+
+ while (!thread_result.done) {
+ wl_display_roundtrip(display->wl_display);
+ }
+ data = thread_result.data;
+
+ /* Reading the data offer unlocks the mutex. */
+ mutex_locked = false;
+ }
+ }
+ if (mutex_locked) {
+ mutex.unlock();
+ }
+ return data;
}
-void GHOST_SystemWayland::putClipboard(const char *buffer, bool /*selection*/) const
+char *GHOST_SystemWayland::getClipboard(bool selection) const
{
- if (UNLIKELY(!d->data_device_manager || d->seats.empty())) {
+ char *data = nullptr;
+ if (selection) {
+ data = system_clipboard_get_primary_selection(display_);
+ }
+ else {
+ data = system_clipboard_get(display_);
+ }
+ return data;
+}
+
+static void system_clipboard_put_primary_selection(GWL_Display *display, const char *buffer)
+{
+ if (!display->wp_primary_selection_device_manager) {
return;
}
+ GWL_Seat *seat = gwl_display_seat_active_get(display);
+ if (UNLIKELY(!seat)) {
+ return;
+ }
+ GWL_PrimarySelection *primary = &seat->primary_selection;
+
+ std::lock_guard lock{primary->data_source_mutex};
+
+ gwl_primary_selection_discard_source(primary);
+
+ GWL_PrimarySelection_DataSource *data_source = new GWL_PrimarySelection_DataSource;
+ primary->data_source = data_source;
+
+ /* Copy buffer. */
+ gwl_simple_buffer_set_from_string(&data_source->buffer_out, buffer);
+
+ data_source->wp_source = zwp_primary_selection_device_manager_v1_create_source(
+ display->wp_primary_selection_device_manager);
+
+ zwp_primary_selection_source_v1_add_listener(
+ data_source->wp_source, &primary_selection_source_listener, primary);
+
+ for (size_t i = 0; i < ARRAY_SIZE(ghost_wl_mime_send); i++) {
+ zwp_primary_selection_source_v1_offer(data_source->wp_source, ghost_wl_mime_send[i]);
+ }
- GWL_Seat *seat = d->seats[0];
+ if (seat->wp_primary_selection_device) {
+ zwp_primary_selection_device_v1_set_selection(
+ seat->wp_primary_selection_device, data_source->wp_source, seat->data_source_serial);
+ }
+}
+static void system_clipboard_put(GWL_Display *display, const char *buffer)
+{
+ if (!display->wl_data_device_manager) {
+ return;
+ }
+ GWL_Seat *seat = gwl_display_seat_active_get(display);
+ if (UNLIKELY(!seat)) {
+ return;
+ }
std::lock_guard lock{seat->data_source_mutex};
GWL_DataSource *data_source = seat->data_source;
/* Copy buffer. */
- free(data_source->buffer_out);
- const size_t buffer_size = strlen(buffer) + 1;
- data_source->buffer_out = static_cast<char *>(malloc(buffer_size));
- std::memcpy(data_source->buffer_out, buffer, buffer_size);
+ gwl_simple_buffer_set_from_string(&data_source->buffer_out, buffer);
- data_source->data_source = wl_data_device_manager_create_data_source(d->data_device_manager);
+ data_source->wl_source = wl_data_device_manager_create_data_source(
+ display->wl_data_device_manager);
- wl_data_source_add_listener(data_source->data_source, &data_source_listener, seat);
+ wl_data_source_add_listener(data_source->wl_source, &data_source_listener, seat);
- for (const std::string &type : mime_send) {
- wl_data_source_offer(data_source->data_source, type.c_str());
+ for (size_t i = 0; i < ARRAY_SIZE(ghost_wl_mime_send); i++) {
+ wl_data_source_offer(data_source->wl_source, ghost_wl_mime_send[i]);
}
- if (seat->data_device) {
+ if (seat->wl_data_device) {
wl_data_device_set_selection(
- seat->data_device, data_source->data_source, seat->data_source_serial);
+ seat->wl_data_device, data_source->wl_source, seat->data_source_serial);
+ }
+}
+
+void GHOST_SystemWayland::putClipboard(const char *buffer, bool selection) const
+{
+ if (selection) {
+ system_clipboard_put_primary_selection(display_, buffer);
+ }
+ else {
+ system_clipboard_put(display_, buffer);
}
}
uint8_t GHOST_SystemWayland::getNumDisplays() const
{
- return d ? uint8_t(d->outputs.size()) : 0;
+ return display_ ? uint8_t(display_->outputs.size()) : 0;
}
static GHOST_TSuccess getCursorPositionClientRelative_impl(
@@ -3158,7 +5492,7 @@ static GHOST_TSuccess setCursorPositionClientRelative_impl(GWL_Seat *seat,
/* NOTE: WAYLAND doesn't support warping the cursor.
* However when grab is enabled, we already simulate a cursor location
* so that can be set to a new location. */
- if (!seat->relative_pointer) {
+ if (!seat->wp_relative_pointer) {
return GHOST_kFailure;
}
const wl_fixed_t scale = win->scale();
@@ -3177,12 +5511,12 @@ GHOST_TSuccess GHOST_SystemWayland::getCursorPositionClientRelative(const GHOST_
int32_t &x,
int32_t &y) const
{
- if (UNLIKELY(d->seats.empty())) {
+ GWL_Seat *seat = gwl_display_seat_active_get(display_);
+ if (UNLIKELY(!seat)) {
return GHOST_kFailure;
}
- GWL_Seat *seat = d->seats[0];
- GWL_SeatStatePointer *seat_state_pointer = seat_state_pointer_active(seat);
- if (!seat_state_pointer || !seat_state_pointer->wl_surface) {
+ GWL_SeatStatePointer *seat_state_pointer = gwl_seat_state_pointer_active(seat);
+ if (!seat_state_pointer || !seat_state_pointer->wl_surface_window) {
return GHOST_kFailure;
}
const GHOST_WindowWayland *win = static_cast<const GHOST_WindowWayland *>(window);
@@ -3193,26 +5527,26 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorPositionClientRelative(GHOST_IWindo
const int32_t x,
const int32_t y)
{
- if (UNLIKELY(d->seats.empty())) {
+ GWL_Seat *seat = gwl_display_seat_active_get(display_);
+ if (UNLIKELY(!seat)) {
return GHOST_kFailure;
}
- GWL_Seat *seat = d->seats[0];
GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(window);
return setCursorPositionClientRelative_impl(seat, win, x, y);
}
GHOST_TSuccess GHOST_SystemWayland::getCursorPosition(int32_t &x, int32_t &y) const
{
- if (UNLIKELY(d->seats.empty())) {
+ GWL_Seat *seat = gwl_display_seat_active_get(display_);
+ if (UNLIKELY(!seat)) {
return GHOST_kFailure;
}
- GWL_Seat *seat = d->seats[0];
- GWL_SeatStatePointer *seat_state_pointer = seat_state_pointer_active(seat);
+ GWL_SeatStatePointer *seat_state_pointer = gwl_seat_state_pointer_active(seat);
if (!seat_state_pointer) {
return GHOST_kFailure;
}
- if (wl_surface *wl_surface_focus = seat_state_pointer->wl_surface) {
+ if (wl_surface *wl_surface_focus = seat_state_pointer->wl_surface_window) {
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
return getCursorPositionClientRelative_impl(seat_state_pointer, win, x, y);
}
@@ -3221,14 +5555,14 @@ GHOST_TSuccess GHOST_SystemWayland::getCursorPosition(int32_t &x, int32_t &y) co
GHOST_TSuccess GHOST_SystemWayland::setCursorPosition(const int32_t x, const int32_t y)
{
- if (UNLIKELY(d->seats.empty())) {
+ GWL_Seat *seat = gwl_display_seat_active_get(display_);
+ if (UNLIKELY(!seat)) {
return GHOST_kFailure;
}
- GWL_Seat *seat = d->seats[0];
/* Intentionally different from `getCursorPosition` which supports both tablet & pointer.
* In the case of setting the cursor location, tablets don't support this. */
- if (wl_surface *wl_surface_focus = seat->pointer.wl_surface) {
+ if (wl_surface *wl_surface_focus = seat->pointer.wl_surface_window) {
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
return setCursorPositionClientRelative_impl(seat, win, x, y);
}
@@ -3241,8 +5575,8 @@ void GHOST_SystemWayland::getMainDisplayDimensions(uint32_t &width, uint32_t &he
return;
}
/* We assume first output as main. */
- width = uint32_t(d->outputs[0]->size_native[0]);
- height = uint32_t(d->outputs[0]->size_native[1]);
+ width = uint32_t(display_->outputs[0]->size_native[0]);
+ height = uint32_t(display_->outputs[0]->size_native[1]);
}
void GHOST_SystemWayland::getAllDisplayDimensions(uint32_t &width, uint32_t &height) const
@@ -3250,7 +5584,7 @@ void GHOST_SystemWayland::getAllDisplayDimensions(uint32_t &width, uint32_t &hei
int32_t xy_min[2] = {INT32_MAX, INT32_MAX};
int32_t xy_max[2] = {INT32_MIN, INT32_MIN};
- for (const GWL_Output *output : d->outputs) {
+ for (const GWL_Output *output : display_->outputs) {
int32_t xy[2] = {0, 0};
if (output->has_position_logical) {
xy[0] = output->position_logical[0];
@@ -3311,10 +5645,10 @@ static GHOST_Context *createOffscreenContext_impl(GHOST_SystemWayland *system,
GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GLSettings /*glSettings*/)
{
/* Create new off-screen window. */
- wl_surface *wl_surface = wl_compositor_create_surface(compositor());
+ wl_surface *wl_surface = wl_compositor_create_surface(wl_compositor());
wl_egl_window *egl_window = wl_surface ? wl_egl_window_create(wl_surface, 1, 1) : nullptr;
- GHOST_Context *context = createOffscreenContext_impl(this, d->display, egl_window);
+ GHOST_Context *context = createOffscreenContext_impl(this, display_->wl_display, egl_window);
if (!context) {
GHOST_PRINT("Cannot create off-screen EGL context" << std::endl);
@@ -3351,17 +5685,12 @@ GHOST_IWindow *GHOST_SystemWayland::createWindow(const char *title,
const uint32_t width,
const uint32_t height,
const GHOST_TWindowState state,
- const GHOST_TDrawingContextType type,
const GHOST_GLSettings glSettings,
const bool exclusive,
const bool is_dialog,
const GHOST_IWindow *parentWindow)
{
/* Globally store pointer to window manager. */
- if (!window_manager) {
- window_manager = getWindowManager();
- }
-
GHOST_WindowWayland *window = new GHOST_WindowWayland(
this,
title,
@@ -3371,7 +5700,7 @@ GHOST_IWindow *GHOST_SystemWayland::createWindow(const char *title,
height,
state,
parentWindow,
- type,
+ glSettings.context_type,
is_dialog,
((glSettings.flags & GHOST_glStereoVisual) != 0),
exclusive);
@@ -3399,22 +5728,22 @@ GHOST_IWindow *GHOST_SystemWayland::createWindow(const char *title,
*/
static void cursor_buffer_show(const GWL_Seat *seat)
{
- const GWL_Cursor *c = &seat->cursor;
+ const GWL_Cursor *cursor = &seat->cursor;
if (seat->wl_pointer) {
- const int scale = c->is_custom ? c->custom_scale : seat->pointer.theme_scale;
- const int32_t hotspot_x = int32_t(c->wl_image.hotspot_x) / scale;
- const int32_t hotspot_y = int32_t(c->wl_image.hotspot_y) / scale;
+ const int scale = cursor->is_custom ? cursor->custom_scale : seat->pointer.theme_scale;
+ const int32_t hotspot_x = int32_t(cursor->wl_image.hotspot_x) / scale;
+ const int32_t hotspot_y = int32_t(cursor->wl_image.hotspot_y) / scale;
if (seat->wl_pointer) {
wl_pointer_set_cursor(
- seat->wl_pointer, seat->pointer.serial, c->wl_surface, hotspot_x, hotspot_y);
+ seat->wl_pointer, seat->pointer.serial, cursor->wl_surface_cursor, hotspot_x, hotspot_y);
}
}
if (!seat->tablet_tools.empty()) {
- const int scale = c->is_custom ? c->custom_scale : seat->tablet.theme_scale;
- const int32_t hotspot_x = int32_t(c->wl_image.hotspot_x) / scale;
- const int32_t hotspot_y = int32_t(c->wl_image.hotspot_y) / scale;
+ const int scale = cursor->is_custom ? cursor->custom_scale : seat->tablet.theme_scale;
+ const int32_t hotspot_x = int32_t(cursor->wl_image.hotspot_x) / scale;
+ const int32_t hotspot_y = int32_t(cursor->wl_image.hotspot_y) / scale;
for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : seat->tablet_tools) {
GWL_TabletTool *tablet_tool = static_cast<GWL_TabletTool *>(
zwp_tablet_tool_v2_get_user_data(zwp_tablet_tool_v2));
@@ -3423,6 +5752,9 @@ static void cursor_buffer_show(const GWL_Seat *seat)
tablet_tool->wl_surface_cursor,
hotspot_x,
hotspot_y);
+#ifdef USE_KDE_TABLET_HIDDEN_CURSOR_HACK
+ wl_surface_commit(tablet_tool->wl_surface_cursor);
+#endif
}
}
}
@@ -3477,21 +5809,21 @@ static void cursor_buffer_set_surface_impl(const GWL_Seat *seat,
static void cursor_buffer_set(const GWL_Seat *seat, wl_buffer *buffer)
{
- const GWL_Cursor *c = &seat->cursor;
+ const GWL_Cursor *cursor = &seat->cursor;
const wl_cursor_image *wl_image = &seat->cursor.wl_image;
- const bool visible = (c->visible && c->is_hardware);
+ const bool visible = (cursor->visible && cursor->is_hardware);
/* This is a requirement of WAYLAND, when this isn't the case,
* it causes Blender's window to close intermittently. */
if (seat->wl_pointer) {
const int scale = cursor_buffer_compatible_scale_from_image(
- wl_image, c->is_custom ? c->custom_scale : seat->pointer.theme_scale);
+ wl_image, cursor->is_custom ? cursor->custom_scale : seat->pointer.theme_scale);
const int32_t hotspot_x = int32_t(wl_image->hotspot_x) / scale;
const int32_t hotspot_y = int32_t(wl_image->hotspot_y) / scale;
- cursor_buffer_set_surface_impl(seat, buffer, c->wl_surface, scale);
+ cursor_buffer_set_surface_impl(seat, buffer, cursor->wl_surface_cursor, scale);
wl_pointer_set_cursor(seat->wl_pointer,
seat->pointer.serial,
- visible ? c->wl_surface : nullptr,
+ visible ? cursor->wl_surface_cursor : nullptr,
hotspot_x,
hotspot_y);
}
@@ -3499,7 +5831,7 @@ static void cursor_buffer_set(const GWL_Seat *seat, wl_buffer *buffer)
/* Set the cursor for all tablet tools as well. */
if (!seat->tablet_tools.empty()) {
const int scale = cursor_buffer_compatible_scale_from_image(
- wl_image, c->is_custom ? c->custom_scale : seat->tablet.theme_scale);
+ wl_image, cursor->is_custom ? cursor->custom_scale : seat->tablet.theme_scale);
const int32_t hotspot_x = int32_t(wl_image->hotspot_x) / scale;
const int32_t hotspot_y = int32_t(wl_image->hotspot_y) / scale;
for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : seat->tablet_tools) {
@@ -3533,12 +5865,12 @@ static void cursor_visible_set(GWL_Seat *seat,
if (set_mode == CURSOR_VISIBLE_ALWAYS_SET) {
/* Pass. */
}
- else if ((set_mode == CURSOR_VISIBLE_ONLY_SHOW)) {
+ else if (set_mode == CURSOR_VISIBLE_ONLY_SHOW) {
if (!use_visible) {
return;
}
}
- else if ((set_mode == CURSOR_VISIBLE_ONLY_HIDE)) {
+ else if (set_mode == CURSOR_VISIBLE_ONLY_HIDE) {
if (use_visible) {
return;
}
@@ -3577,39 +5909,40 @@ static bool cursor_is_software(const GHOST_TGrabCursorMode mode, const bool use_
GHOST_TSuccess GHOST_SystemWayland::setCursorShape(const GHOST_TStandardCursor shape)
{
- if (UNLIKELY(d->seats.empty())) {
+ GWL_Seat *seat = gwl_display_seat_active_get(display_);
+ if (UNLIKELY(!seat)) {
return GHOST_kFailure;
}
- auto cursor_find = cursors.find(shape);
- const char *cursor_name = (cursor_find == cursors.end()) ?
- cursors.at(GHOST_kStandardCursorDefault) :
+ auto cursor_find = ghost_wl_cursors.find(shape);
+ const char *cursor_name = (cursor_find == ghost_wl_cursors.end()) ?
+ ghost_wl_cursors.at(GHOST_kStandardCursorDefault) :
(*cursor_find).second;
- GWL_Seat *seat = d->seats[0];
- GWL_Cursor *c = &seat->cursor;
+ GWL_Cursor *cursor = &seat->cursor;
- if (!c->wl_theme) {
+ if (!cursor->wl_theme) {
/* The cursor wl_surface hasn't entered an output yet. Initialize theme with scale 1. */
- c->wl_theme = wl_cursor_theme_load(c->theme_name.c_str(), c->size, d->seats[0]->system->shm());
+ cursor->wl_theme = wl_cursor_theme_load(
+ cursor->theme_name.c_str(), cursor->theme_size, wl_shm());
}
- wl_cursor *cursor = wl_cursor_theme_get_cursor(c->wl_theme, cursor_name);
+ wl_cursor *wl_cursor = wl_cursor_theme_get_cursor(cursor->wl_theme, cursor_name);
- if (!cursor) {
+ if (!wl_cursor) {
GHOST_PRINT("cursor '" << cursor_name << "' does not exist" << std::endl);
return GHOST_kFailure;
}
- struct wl_cursor_image *image = cursor->images[0];
+ struct wl_cursor_image *image = wl_cursor->images[0];
struct wl_buffer *buffer = wl_cursor_image_get_buffer(image);
if (!buffer) {
return GHOST_kFailure;
}
- c->visible = true;
- c->is_custom = false;
- c->wl_buffer = buffer;
- c->wl_image = *image;
+ cursor->visible = true;
+ cursor->is_custom = false;
+ cursor->wl_buffer = buffer;
+ cursor->wl_image = *image;
cursor_buffer_set(seat, buffer);
@@ -3618,8 +5951,8 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorShape(const GHOST_TStandardCursor s
GHOST_TSuccess GHOST_SystemWayland::hasCursorShape(const GHOST_TStandardCursor cursorShape)
{
- auto cursor_find = cursors.find(cursorShape);
- if (cursor_find == cursors.end()) {
+ auto cursor_find = ghost_wl_cursors.find(cursorShape);
+ if (cursor_find == ghost_wl_cursors.end()) {
return GHOST_kFailure;
}
const char *value = (*cursor_find).second;
@@ -3637,12 +5970,12 @@ GHOST_TSuccess GHOST_SystemWayland::setCustomCursorShape(uint8_t *bitmap,
const int hotY,
const bool /*canInvertColor*/)
{
- if (UNLIKELY(d->seats.empty())) {
+ GWL_Seat *seat = gwl_display_seat_active_get(display_);
+ if (UNLIKELY(!seat)) {
return GHOST_kFailure;
}
- GWL_Cursor *cursor = &d->seats[0]->cursor;
-
+ GWL_Cursor *cursor = &seat->cursor;
if (cursor->custom_data) {
munmap(cursor->custom_data, cursor->custom_data_size);
cursor->custom_data = nullptr;
@@ -3650,8 +5983,11 @@ GHOST_TSuccess GHOST_SystemWayland::setCustomCursorShape(uint8_t *bitmap,
}
const int32_t size_xy[2] = {sizex, sizey};
- wl_buffer *buffer = ghost_wl_buffer_create_for_image(
- d->shm, size_xy, WL_SHM_FORMAT_ARGB8888, &cursor->custom_data, &cursor->custom_data_size);
+ wl_buffer *buffer = ghost_wl_buffer_create_for_image(display_->wl_shm,
+ size_xy,
+ WL_SHM_FORMAT_ARGB8888,
+ &cursor->custom_data,
+ &cursor->custom_data_size);
if (buffer == nullptr) {
return GHOST_kFailure;
}
@@ -3697,14 +6033,19 @@ GHOST_TSuccess GHOST_SystemWayland::setCustomCursorShape(uint8_t *bitmap,
cursor->wl_image.hotspot_x = uint32_t(hotX);
cursor->wl_image.hotspot_y = uint32_t(hotY);
- cursor_buffer_set(d->seats[0], buffer);
+ cursor_buffer_set(seat, buffer);
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_SystemWayland::getCursorBitmap(GHOST_CursorBitmapRef *bitmap)
{
- GWL_Cursor *cursor = &d->seats[0]->cursor;
+ GWL_Seat *seat = gwl_display_seat_active_get(display_);
+ if (UNLIKELY(!seat)) {
+ return GHOST_kFailure;
+ }
+
+ GWL_Cursor *cursor = &seat->cursor;
if (cursor->custom_data == nullptr) {
return GHOST_kFailure;
}
@@ -3725,11 +6066,11 @@ GHOST_TSuccess GHOST_SystemWayland::getCursorBitmap(GHOST_CursorBitmapRef *bitma
GHOST_TSuccess GHOST_SystemWayland::setCursorVisibility(const bool visible)
{
- if (UNLIKELY(d->seats.empty())) {
+ GWL_Seat *seat = gwl_display_seat_active_get(display_);
+ if (UNLIKELY(!seat)) {
return GHOST_kFailure;
}
- GWL_Seat *seat = d->seats[0];
cursor_visible_set(seat, visible, seat->cursor.is_hardware, CURSOR_VISIBLE_ALWAYS_SET);
return GHOST_kSuccess;
}
@@ -3749,12 +6090,12 @@ bool GHOST_SystemWayland::supportsWindowPosition()
bool GHOST_SystemWayland::getCursorGrabUseSoftwareDisplay(const GHOST_TGrabCursorMode mode)
{
- if (UNLIKELY(d->seats.empty())) {
+ GWL_Seat *seat = gwl_display_seat_active_get(display_);
+ if (UNLIKELY(!seat)) {
return false;
}
#ifdef USE_GNOME_CONFINE_HACK
- GWL_Seat *seat = d->seats[0];
const bool use_software_confine = seat->use_pointer_software_confine;
#else
const bool use_software_confine = false;
@@ -3793,11 +6134,10 @@ static GWL_SeatStateGrab seat_grab_state_from_mode(const GHOST_TGrabCursorMode m
const bool use_software_confine)
{
/* Initialize all members. */
- const struct GWL_SeatStateGrab grab_state = {
- /* Warping happens to require software cursor which also hides. */
- .use_lock = ELEM(mode, GHOST_kGrabWrap, GHOST_kGrabHide) || use_software_confine,
- .use_confine = (mode == GHOST_kGrabNormal) && (use_software_confine == false),
- };
+ GWL_SeatStateGrab grab_state;
+ /* Warping happens to require software cursor which also hides. */
+ grab_state.use_lock = ELEM(mode, GHOST_kGrabWrap, GHOST_kGrabHide) || use_software_confine;
+ grab_state.use_confine = (mode == GHOST_kGrabNormal) && (use_software_confine == false);
return grab_state;
}
@@ -3861,45 +6201,55 @@ void ghost_wl_surface_tag_cursor_tablet(struct wl_surface *wl_surface)
* Expose some members via methods.
* \{ */
-wl_display *GHOST_SystemWayland::display()
+wl_display *GHOST_SystemWayland::wl_display()
+{
+ return display_->wl_display;
+}
+
+wl_compositor *GHOST_SystemWayland::wl_compositor()
{
- return d->display;
+ return display_->wl_compositor;
}
-wl_compositor *GHOST_SystemWayland::compositor()
+struct zwp_primary_selection_device_manager_v1 *GHOST_SystemWayland::wp_primary_selection_manager()
{
- return d->compositor;
+ return display_->wp_primary_selection_device_manager;
+}
+
+struct zwp_pointer_gestures_v1 *GHOST_SystemWayland::wp_pointer_gestures()
+{
+ return display_->wp_pointer_gestures;
}
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
-libdecor *GHOST_SystemWayland::decor_context()
+libdecor *GHOST_SystemWayland::libdecor_context()
{
- return d->decor_context;
+ return display_->libdecor->context;
}
-#else /* WITH_GHOST_WAYLAND_LIBDECOR */
+#endif /* !WITH_GHOST_WAYLAND_LIBDECOR */
-xdg_wm_base *GHOST_SystemWayland::xdg_shell()
+xdg_wm_base *GHOST_SystemWayland::xdg_decor_shell()
{
- return d->xdg_shell;
+ return display_->xdg_decor->shell;
}
-zxdg_decoration_manager_v1 *GHOST_SystemWayland::xdg_decoration_manager()
+zxdg_decoration_manager_v1 *GHOST_SystemWayland::xdg_decor_manager()
{
- return d->xdg_decoration_manager;
+ return display_->xdg_decor->manager;
}
-#endif /* !WITH_GHOST_WAYLAND_LIBDECOR */
+/* End `xdg_decor`. */
const std::vector<GWL_Output *> &GHOST_SystemWayland::outputs() const
{
- return d->outputs;
+ return display_->outputs;
}
-wl_shm *GHOST_SystemWayland::shm() const
+struct wl_shm *GHOST_SystemWayland::wl_shm() const
{
- return d->shm;
+ return display_->wl_shm;
}
/** \} */
@@ -3933,9 +6283,9 @@ GHOST_WindowWayland *ghost_wl_surface_user_data(struct wl_surface *wl_surface)
* Functionality only used for the WAYLAND implementation.
* \{ */
-void GHOST_SystemWayland::selection_set(const std::string &selection)
+void GHOST_SystemWayland::seat_active_set(const struct GWL_Seat *seat)
{
- this->selection = selection;
+ gwl_display_seat_active_set(display_, seat);
}
void GHOST_SystemWayland::window_surface_unref(const wl_surface *wl_surface)
@@ -3947,11 +6297,11 @@ void GHOST_SystemWayland::window_surface_unref(const wl_surface *wl_surface)
((void)0);
/* Only clear window surfaces (not cursors, off-screen surfaces etc). */
- for (GWL_Seat *seat : d->seats) {
- SURFACE_CLEAR_PTR(seat->pointer.wl_surface);
- SURFACE_CLEAR_PTR(seat->tablet.wl_surface);
- SURFACE_CLEAR_PTR(seat->keyboard.wl_surface);
- SURFACE_CLEAR_PTR(seat->wl_surface_focus_dnd);
+ for (GWL_Seat *seat : display_->seats) {
+ SURFACE_CLEAR_PTR(seat->pointer.wl_surface_window);
+ SURFACE_CLEAR_PTR(seat->tablet.wl_surface_window);
+ SURFACE_CLEAR_PTR(seat->keyboard.wl_surface_window);
+ SURFACE_CLEAR_PTR(seat->wl_surface_window_focus_dnd);
}
#undef SURFACE_CLEAR_PTR
}
@@ -3965,11 +6315,12 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
const int scale)
{
/* Ignore, if the required protocols are not supported. */
- if (UNLIKELY(!d->relative_pointer_manager || !d->pointer_constraints)) {
+ if (UNLIKELY(!display_->wp_relative_pointer_manager || !display_->wp_pointer_constraints)) {
return GHOST_kFailure;
}
- if (UNLIKELY(d->seats.empty())) {
+ GWL_Seat *seat = gwl_display_seat_active_get(display_);
+ if (UNLIKELY(!seat)) {
return GHOST_kFailure;
}
/* No change, success. */
@@ -3977,8 +6328,6 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
return GHOST_kSuccess;
}
- GWL_Seat *seat = d->seats[0];
-
#ifdef USE_GNOME_CONFINE_HACK
const bool was_software_confine = seat->use_pointer_software_confine;
const bool use_software_confine = setCursorGrab_use_software_confine(mode, wl_surface);
@@ -4004,11 +6353,11 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
* in this case disable the current locks as it makes logic confusing,
* postpone changing the cursor to avoid flickering. */
if (!grab_state_next.use_lock) {
- if (seat->relative_pointer) {
- zwp_relative_pointer_v1_destroy(seat->relative_pointer);
- seat->relative_pointer = nullptr;
+ if (seat->wp_relative_pointer) {
+ zwp_relative_pointer_v1_destroy(seat->wp_relative_pointer);
+ seat->wp_relative_pointer = nullptr;
}
- if (seat->locked_pointer) {
+ if (seat->wp_locked_pointer) {
/* Potentially add a motion event so the application has updated X/Y coordinates. */
int32_t xy_motion[2] = {0, 0};
bool xy_motion_create_event = false;
@@ -4037,7 +6386,7 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
seat->pointer.xy[0] = xy_next[0];
seat->pointer.xy[1] = xy_next[1];
- zwp_locked_pointer_v1_set_cursor_position_hint(seat->locked_pointer, UNPACK2(xy_next));
+ zwp_locked_pointer_v1_set_cursor_position_hint(seat->wp_locked_pointer, UNPACK2(xy_next));
wl_surface_commit(wl_surface);
}
else if (mode_current == GHOST_kGrabHide) {
@@ -4047,7 +6396,8 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
wl_fixed_from_int(init_grab_xy[0]) / scale,
wl_fixed_from_int(init_grab_xy[1]) / scale,
};
- zwp_locked_pointer_v1_set_cursor_position_hint(seat->locked_pointer, UNPACK2(xy_next));
+ zwp_locked_pointer_v1_set_cursor_position_hint(seat->wp_locked_pointer,
+ UNPACK2(xy_next));
wl_surface_commit(wl_surface);
/* NOTE(@campbellbarton): The new cursor position is a hint,
@@ -4061,7 +6411,7 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
#ifdef USE_GNOME_CONFINE_HACK
else if (mode_current == GHOST_kGrabNormal) {
if (was_software_confine) {
- zwp_locked_pointer_v1_set_cursor_position_hint(seat->locked_pointer,
+ zwp_locked_pointer_v1_set_cursor_position_hint(seat->wp_locked_pointer,
UNPACK2(seat->pointer.xy));
wl_surface_commit(wl_surface);
}
@@ -4077,15 +6427,15 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
GHOST_TABLET_DATA_NONE));
}
- zwp_locked_pointer_v1_destroy(seat->locked_pointer);
- seat->locked_pointer = nullptr;
+ zwp_locked_pointer_v1_destroy(seat->wp_locked_pointer);
+ seat->wp_locked_pointer = nullptr;
}
}
if (!grab_state_next.use_confine) {
- if (seat->confined_pointer) {
- zwp_confined_pointer_v1_destroy(seat->confined_pointer);
- seat->confined_pointer = nullptr;
+ if (seat->wp_confined_pointer) {
+ zwp_confined_pointer_v1_destroy(seat->wp_confined_pointer);
+ seat->wp_confined_pointer = nullptr;
}
}
@@ -4096,12 +6446,12 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
* possible to support #GHOST_kGrabWrap by pragmatically settings it's coordinates.
* An alternative could be to draw the cursor in software (and hide the real cursor),
* or just accept a locked cursor on WAYLAND. */
- seat->relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(
- d->relative_pointer_manager, seat->wl_pointer);
+ seat->wp_relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(
+ display_->wp_relative_pointer_manager, seat->wl_pointer);
zwp_relative_pointer_v1_add_listener(
- seat->relative_pointer, &relative_pointer_listener, seat);
- seat->locked_pointer = zwp_pointer_constraints_v1_lock_pointer(
- d->pointer_constraints,
+ seat->wp_relative_pointer, &relative_pointer_listener, seat);
+ seat->wp_locked_pointer = zwp_pointer_constraints_v1_lock_pointer(
+ display_->wp_pointer_constraints,
wl_surface,
seat->wl_pointer,
nullptr,
@@ -4118,8 +6468,8 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
}
else if (grab_state_next.use_confine) {
if (!grab_state_prev.use_confine) {
- seat->confined_pointer = zwp_pointer_constraints_v1_confine_pointer(
- d->pointer_constraints,
+ seat->wp_confined_pointer = zwp_pointer_constraints_v1_confine_pointer(
+ display_->wp_pointer_constraints,
wl_surface,
seat->wl_pointer,
nullptr,
@@ -4138,35 +6488,52 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
return GHOST_kSuccess;
}
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+bool GHOST_SystemWayland::use_libdecor_runtime()
+{
+ return use_libdecor;
+}
+#endif
+
#ifdef WITH_GHOST_WAYLAND_DYNLOAD
-bool ghost_wl_dynload_libraries()
+bool ghost_wl_dynload_libraries_init()
{
- /* Only report when `libwayland-client` is not found when building without X11,
- * which will be used as a fallback. */
# ifdef WITH_GHOST_X11
- bool verbose = false;
+ /* When running in WAYLAND, let the user know when a missing library is the only reason
+ * WAYLAND could not be used. Otherwise it's not obvious why X11 is used as a fallback.
+ * Otherwise when X11 is used, reporting WAYLAND library warnings is unwelcome noise. */
+ bool verbose = getenv("WAYLAND_DISPLAY") != nullptr;
# else
bool verbose = true;
-# endif
+# endif /* !WITH_GHOST_X11 */
if (wayland_dynload_client_init(verbose) && /* `libwayland-client`. */
wayland_dynload_cursor_init(verbose) && /* `libwayland-cursor`. */
- wayland_dynload_egl_init(verbose) && /* `libwayland-egl`. */
+ wayland_dynload_egl_init(verbose) /* `libwayland-egl`. */
+ ) {
# ifdef WITH_GHOST_WAYLAND_LIBDECOR
- wayland_dynload_libdecor_init(verbose) && /* `libdecor-0`. */
+ has_libdecor = wayland_dynload_libdecor_init(verbose); /* `libdecor-0`. */
# endif
- true) {
return true;
}
-# ifdef WITH_GHOST_WAYLAND_LIBDECOR
- wayland_dynload_libdecor_exit();
-# endif
+
wayland_dynload_client_exit();
wayland_dynload_cursor_exit();
wayland_dynload_egl_exit();
return false;
}
+
+void ghost_wl_dynload_libraries_exit()
+{
+ wayland_dynload_client_exit();
+ wayland_dynload_cursor_exit();
+ wayland_dynload_egl_exit();
+# ifdef WITH_GHOST_WAYLAND_LIBDECOR
+ wayland_dynload_libdecor_exit();
+# endif
+}
+
#endif /* WITH_GHOST_WAYLAND_DYNLOAD */
/** \} */
diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h
index caea7b0d748..a8e8d8ddc45 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.h
+++ b/intern/ghost/intern/GHOST_SystemWayland.h
@@ -21,18 +21,13 @@
# include <wayland_dynload_libdecor.h>
# endif
# include <libdecor.h>
-#else
-/* Generated by `wayland-scanner`. */
-# include <xdg-decoration-unstable-v1-client-protocol.h>
-# include <xdg-shell-client-protocol.h>
#endif
+#include <mutex>
#include <string>
class GHOST_WindowWayland;
-struct GWL_Display;
-
bool ghost_wl_output_own(const struct wl_output *wl_output);
void ghost_wl_output_tag(struct wl_output *wl_output);
struct GWL_Output *ghost_wl_output_user_data(struct wl_output *wl_output);
@@ -52,10 +47,13 @@ void ghost_wl_surface_tag_cursor_tablet(struct wl_surface *surface);
* Return true when all required WAYLAND libraries are present,
* Performs dynamic loading when `WITH_GHOST_WAYLAND_DYNLOAD` is in use.
*/
-bool ghost_wl_dynload_libraries();
+bool ghost_wl_dynload_libraries_init();
+void ghost_wl_dynload_libraries_exit();
#endif
struct GWL_Output {
+ GHOST_SystemWayland *system = nullptr;
+
struct wl_output *wl_output = nullptr;
struct zxdg_output_v1 *xdg_output = nullptr;
/** Dimensions in pixels. */
@@ -89,11 +87,12 @@ struct GWL_Output {
class GHOST_SystemWayland : public GHOST_System {
public:
- GHOST_SystemWayland();
+ GHOST_SystemWayland(bool background);
+ GHOST_SystemWayland() : GHOST_SystemWayland(true){};
~GHOST_SystemWayland() override;
- GHOST_TSuccess init();
+ GHOST_TSuccess init() override;
bool processEvents(bool waitForEvent) override;
@@ -133,7 +132,6 @@ class GHOST_SystemWayland : public GHOST_System {
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
GHOST_GLSettings glSettings,
const bool exclusive,
const bool is_dialog,
@@ -155,31 +153,33 @@ class GHOST_SystemWayland : public GHOST_System {
GHOST_TSuccess setCursorVisibility(bool visible);
- bool supportsCursorWarp();
- bool supportsWindowPosition();
+ bool supportsCursorWarp() override;
+ bool supportsWindowPosition() override;
bool getCursorGrabUseSoftwareDisplay(const GHOST_TGrabCursorMode mode);
/* WAYLAND direct-data access. */
- wl_display *display();
-
- wl_compositor *compositor();
+ struct wl_display *wl_display();
+ struct wl_compositor *wl_compositor();
+ struct zwp_primary_selection_device_manager_v1 *wp_primary_selection_manager();
+ struct zwp_pointer_gestures_v1 *wp_pointer_gestures();
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- libdecor *decor_context();
-#else
- xdg_wm_base *xdg_shell();
- zxdg_decoration_manager_v1 *xdg_decoration_manager();
+ libdecor *libdecor_context();
#endif
+ struct xdg_wm_base *xdg_decor_shell();
+ struct zxdg_decoration_manager_v1 *xdg_decor_manager();
+ /* End `xdg_decor`. */
const std::vector<GWL_Output *> &outputs() const;
- wl_shm *shm() const;
+ struct wl_shm *wl_shm() const;
/* WAYLAND utility functions. */
- void selection_set(const std::string &selection);
+ /** Set this seat to be active. */
+ void seat_active_set(const struct GWL_Seat *seat);
/** Clear all references to this surface to prevent accessing NULL pointers. */
void window_surface_unref(const wl_surface *wl_surface);
@@ -192,7 +192,10 @@ class GHOST_SystemWayland : public GHOST_System {
wl_surface *wl_surface,
int scale);
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+ static bool use_libdecor_runtime();
+#endif
+
private:
- struct GWL_Display *d;
- std::string selection;
+ struct GWL_Display *display_;
};
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 6cb36337b55..54c892d296e 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -213,7 +213,6 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(const char *title,
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
GHOST_GLSettings glSettings,
const bool exclusive,
const bool is_dialog,
@@ -227,7 +226,7 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(const char *title,
width,
height,
state,
- type,
+ glSettings.context_type,
((glSettings.flags & GHOST_glStereoVisual) != 0),
false,
(GHOST_WindowWin32 *)parentWindow,
@@ -456,14 +455,11 @@ GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys &keys) cons
down = HIBYTE(::GetKeyState(VK_RCONTROL)) != 0;
keys.set(GHOST_kModifierKeyRightControl, down);
- bool lwindown = HIBYTE(::GetKeyState(VK_LWIN)) != 0;
- bool rwindown = HIBYTE(::GetKeyState(VK_RWIN)) != 0;
- if (lwindown || rwindown) {
- keys.set(GHOST_kModifierKeyOS, true);
- }
- else {
- keys.set(GHOST_kModifierKeyOS, false);
- }
+ down = HIBYTE(::GetKeyState(VK_LWIN)) != 0;
+ keys.set(GHOST_kModifierKeyLeftOS, down);
+ down = HIBYTE(::GetKeyState(VK_RWIN)) != 0;
+ keys.set(GHOST_kModifierKeyRightOS, down);
+
return GHOST_kSuccess;
}
@@ -543,7 +539,7 @@ GHOST_TSuccess GHOST_SystemWin32::exit()
GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, bool *r_key_down)
{
/* #RI_KEY_BREAK doesn't work for sticky keys release, so we also check for the up message. */
- unsigned int msg = raw.data.keyboard.Message;
+ uint msg = raw.data.keyboard.Message;
*r_key_down = !(raw.data.keyboard.Flags & RI_KEY_BREAK) && msg != WM_KEYUP && msg != WM_SYSKEYUP;
return this->convertKey(raw.data.keyboard.VKey,
@@ -565,7 +561,7 @@ GHOST_TKey GHOST_SystemWin32::processSpecialKey(short vKey, short scanCode) cons
return key;
}
- char ch = (char)MapVirtualKeyA(vKey, MAPVK_VK_TO_CHAR);
+ char ch = char(MapVirtualKeyA(vKey, MAPVK_VK_TO_CHAR));
switch (ch) {
case u'\"':
case u'\'':
@@ -751,8 +747,10 @@ GHOST_TKey GHOST_SystemWin32::convertKey(short vKey, short scanCode, short exten
key = (extend) ? GHOST_kKeyRightAlt : GHOST_kKeyLeftAlt;
break;
case VK_LWIN:
+ key = GHOST_kKeyLeftOS;
+ break;
case VK_RWIN:
- key = GHOST_kKeyOS;
+ key = GHOST_kKeyRightOS;
break;
case VK_APPS:
key = GHOST_kKeyApp;
@@ -856,7 +854,7 @@ void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
case GHOST_kEventButtonDown: {
WINTAB_PRINTF("HWND %p Wintab button down", window->getHWND());
- UINT message;
+ uint message;
switch (info.button) {
case GHOST_kButtonMaskLeft:
message = WM_LBUTTONDOWN;
@@ -914,7 +912,7 @@ void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
continue;
}
- UINT message;
+ uint message;
switch (info.button) {
case GHOST_kButtonMaskLeft:
message = WM_LBUTTONUP;
@@ -964,7 +962,7 @@ void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
}
void GHOST_SystemWin32::processPointerEvent(
- UINT type, GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam, bool &eventHandled)
+ uint type, GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam, bool &eventHandled)
{
/* Pointer events might fire when changing windows for a device which is set to use Wintab,
* even when Wintab is left enabled but set to the bottom of Wintab overlap order. */
@@ -1137,12 +1135,18 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA
GHOST_TKey key = system->hardKey(raw, &key_down);
GHOST_EventKey *event;
+ /* NOTE(@campbellbarton): key repeat in WIN32 also applies to modifier-keys.
+ * Check for this case and filter out modifier-repeat.
+ * Typically keyboard events are *not* filtered as part of GHOST's event handling.
+ * As other GHOST back-ends don't have the behavior, it's simplest not to send them through.
+ * Ideally it would be possible to check the key-map for keys that repeat but this doesn't look
+ * to be supported. */
bool is_repeat = false;
bool is_repeated_modifier = false;
if (key_down) {
if (system->m_keycode_last_repeat_key == vk) {
is_repeat = true;
- is_repeated_modifier = (key >= GHOST_kKeyLeftShift && key <= GHOST_kKeyRightAlt);
+ is_repeated_modifier = GHOST_KEY_MODIFIER_CHECK(key);
}
system->m_keycode_last_repeat_key = vk;
}
@@ -1411,7 +1415,7 @@ void GHOST_SystemWin32::processTrackpad()
}
}
-LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, uint msg, WPARAM wParam, LPARAM lParam)
{
GHOST_Event *event = NULL;
bool eventHandled = false;
@@ -1457,7 +1461,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
case WM_INPUT: {
RAWINPUT raw;
RAWINPUT *raw_ptr = &raw;
- UINT rawSize = sizeof(RAWINPUT);
+ uint rawSize = sizeof(RAWINPUT);
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, raw_ptr, &rawSize, sizeof(RAWINPUTHEADER));
@@ -1742,10 +1746,10 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
break;
}
case WM_XBUTTONDOWN: {
- if ((short)HIWORD(wParam) == XBUTTON1) {
+ if (short(HIWORD(wParam)) == XBUTTON1) {
event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton4);
}
- else if ((short)HIWORD(wParam) == XBUTTON2) {
+ else if (short(HIWORD(wParam)) == XBUTTON2) {
event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton5);
}
break;
@@ -1763,10 +1767,10 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
break;
}
case WM_XBUTTONUP: {
- if ((short)HIWORD(wParam) == XBUTTON1) {
+ if (short(HIWORD(wParam)) == XBUTTON1) {
event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton4);
}
- else if ((short)HIWORD(wParam) == XBUTTON2) {
+ else if (short(HIWORD(wParam)) == XBUTTON2) {
event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton5);
}
break;
@@ -2088,7 +2092,9 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
/* The DM_POINTERHITTEST message is sent to a window, when pointer input is first
* detected, in order to determine the most probable input target for Direct
* Manipulation. */
- window->onPointerHitTest(wParam);
+ if (system->m_multitouchGestures) {
+ window->onPointerHitTest(wParam);
+ }
break;
}
}
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
index 81c565ae732..98a7e5dfb35 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.h
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -103,9 +103,8 @@ class GHOST_SystemWin32 : public GHOST_System {
* \param width: The width the window.
* \param height: The height the window.
* \param state: The state of the window when opened.
- * \param type: The type of drawing context installed in this window.
* \param glSettings: Misc OpenGL settings.
- * \param exclusive: Use to show the window ontop and ignore others (used fullscreen).
+ * \param exclusive: Use to show the window on top and ignore others (used full-screen).
* \param parentWindow: Parent window.
* \return The new window (or 0 if creation failed).
*/
@@ -115,7 +114,6 @@ class GHOST_SystemWin32 : public GHOST_System {
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
GHOST_GLSettings glSettings,
const bool exclusive = false,
const bool is_dialog = false,
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index bb98c0de19b..5c89febe97c 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -308,7 +308,6 @@ void GHOST_SystemX11::getAllDisplayDimensions(uint32_t &width, uint32_t &height)
* \param width: The width the window.
* \param height: The height the window.
* \param state: The state of the window when opened.
- * \param type: The type of drawing context installed in this window.
* \param glSettings: Misc OpenGL settings.
* \param exclusive: Use to show the window on top and ignore others (used full-screen).
* \param parentWindow: Parent window.
@@ -320,7 +319,6 @@ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title,
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
GHOST_GLSettings glSettings,
const bool exclusive,
const bool is_dialog,
@@ -341,7 +339,7 @@ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title,
height,
state,
(GHOST_WindowX11 *)parentWindow,
- type,
+ glSettings.context_type,
is_dialog,
((glSettings.flags & GHOST_glStereoVisual) != 0),
exclusive,
@@ -660,7 +658,7 @@ bool GHOST_SystemX11::processEvents(bool waitForEvent)
}
/* dispatch event to XIM server */
- if ((XFilterEvent(&xevent, (Window) nullptr) == True)) {
+ if (XFilterEvent(&xevent, (Window) nullptr) == True) {
/* do nothing now, the event is consumed by XIM. */
continue;
}
@@ -673,7 +671,7 @@ bool GHOST_SystemX11::processEvents(bool waitForEvent)
}
else if (xevent.type == KeyPress) {
if ((xevent.xkey.keycode == m_last_release_keycode) &&
- ((xevent.xkey.time <= m_last_release_time))) {
+ (xevent.xkey.time <= m_last_release_time)) {
continue;
}
}
@@ -715,7 +713,7 @@ bool GHOST_SystemX11::processEvents(bool waitForEvent)
XK_Super_R,
};
- for (int i = 0; i < (int)ARRAY_SIZE(modifiers); i++) {
+ for (int i = 0; i < int(ARRAY_SIZE(modifiers)); i++) {
KeyCode kc = XKeysymToKeycode(m_display, modifiers[i]);
if (kc != 0 && ((xevent.xkeymap.key_vector[kc >> 3] >> (kc & 7)) & 1) != 0) {
pushEvent(new GHOST_EventKey(getMilliSeconds(),
@@ -845,14 +843,14 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
}
else {
if (m_keycode_last_repeat_key == xke->keycode) {
- m_keycode_last_repeat_key = (uint)-1;
+ m_keycode_last_repeat_key = uint(-1);
}
}
}
}
else if (xe->type == EnterNotify) {
/* We can't tell how the key state changed, clear it to avoid stuck keys. */
- m_keycode_last_repeat_key = (uint)-1;
+ m_keycode_last_repeat_key = uint(-1);
}
#ifdef USE_XINPUT_HOTPLUG
@@ -1038,8 +1036,8 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
KeySym key_sym_str;
/* Mode_switch 'modifier' is `AltGr` - when this one or Shift are enabled,
* we do not want to apply that 'forced number' hack. */
- const unsigned int mode_switch_mask = XkbKeysymToModifiers(xke->display, XK_Mode_switch);
- const unsigned int number_hack_forbidden_kmods_mask = mode_switch_mask | ShiftMask;
+ const uint mode_switch_mask = XkbKeysymToModifiers(xke->display, XK_Mode_switch);
+ const uint number_hack_forbidden_kmods_mask = mode_switch_mask | ShiftMask;
if ((xke->keycode >= 10 && xke->keycode < 20) &&
((xke->state & number_hack_forbidden_kmods_mask) == 0)) {
key_sym = XLookupKeysym(xke, ShiftMask);
@@ -1065,7 +1063,8 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
case GHOST_kKeyLeftShift:
case GHOST_kKeyRightControl:
case GHOST_kKeyLeftControl:
- case GHOST_kKeyOS:
+ case GHOST_kKeyLeftOS:
+ case GHOST_kKeyRightOS:
case GHOST_kKey0:
case GHOST_kKey1:
case GHOST_kKey2:
@@ -1151,7 +1150,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
}
if (ELEM(status, XLookupChars, XLookupBoth)) {
- if ((unsigned char)utf8_buf[0] >= 32) { /* not an ascii control character */
+ if (uchar(utf8_buf[0]) >= 32) { /* not an ascii control character */
/* do nothing for now, this is valid utf8 */
}
else {
@@ -1164,7 +1163,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
}
else {
printf("Bad keycode lookup. Keysym 0x%x Status: %s\n",
- (unsigned int)key_sym,
+ uint(key_sym),
(status == XLookupNone ? "XLookupNone" :
status == XLookupKeySym ? "XLookupKeySym" :
"Unknown status"));
@@ -1188,11 +1187,11 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
/* when using IM for some languages such as Japanese,
* one event inserts multiple utf8 characters */
if (xke->type == KeyPress && xic) {
- unsigned char c;
+ uchar c;
int i = 0;
while (true) {
/* Search character boundary. */
- if ((uchar)utf8_buf[i++] > 0x7f) {
+ if (uchar(utf8_buf[i++]) > 0x7f) {
for (; i < len; ++i) {
c = utf8_buf[i];
if (c < 0x80 || c > 0xbf) {
@@ -1451,7 +1450,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
xse->target,
8,
PropModeReplace,
- (unsigned char *)txt_select_buffer,
+ (uchar *)txt_select_buffer,
strlen(txt_select_buffer));
}
else if (xse->selection == XInternAtom(m_display, "CLIPBOARD", False)) {
@@ -1461,7 +1460,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
xse->target,
8,
PropModeReplace,
- (unsigned char *)txt_cut_buffer,
+ (uchar *)txt_cut_buffer,
strlen(txt_cut_buffer));
}
}
@@ -1478,7 +1477,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
xse->target,
32,
PropModeReplace,
- (unsigned char *)alist,
+ (uchar *)alist,
5);
XFlush(m_display);
}
@@ -1502,8 +1501,8 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
continue;
}
- const unsigned char axis_first = data->first_axis;
- const unsigned char axes_end = axis_first + data->axes_count; /* after the last */
+ const uchar axis_first = data->first_axis;
+ const uchar axes_end = axis_first + data->axes_count; /* after the last */
int axis_value;
/* stroke might begin without leading ProxyIn event,
@@ -1522,7 +1521,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
((void)(val = data->axis_data[axis - axis_first]), true))
if (AXIS_VALUE_GET(2, axis_value)) {
- window->GetTabletData().Pressure = axis_value / ((float)xtablet.PressureLevels);
+ window->GetTabletData().Pressure = axis_value / float(xtablet.PressureLevels);
}
/* NOTE(@broken): the (short) cast and the & 0xffff is bizarre and unexplained anywhere,
@@ -1534,12 +1533,12 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
* I don't think we need to cast to short here, but do not have a device to check this.
*/
if (AXIS_VALUE_GET(3, axis_value)) {
- window->GetTabletData().Xtilt = (short)(axis_value & 0xffff) /
- ((float)xtablet.XtiltLevels);
+ window->GetTabletData().Xtilt = short(axis_value & 0xffff) /
+ float(xtablet.XtiltLevels);
}
if (AXIS_VALUE_GET(4, axis_value)) {
- window->GetTabletData().Ytilt = (short)(axis_value & 0xffff) /
- ((float)xtablet.YtiltLevels);
+ window->GetTabletData().Ytilt = short(axis_value & 0xffff) /
+ float(xtablet.YtiltLevels);
}
# undef AXIS_VALUE_GET
@@ -1600,9 +1599,10 @@ GHOST_TSuccess GHOST_SystemX11::getModifierKeys(GHOST_ModifierKeys &keys) const
keys.set(GHOST_kModifierKeyLeftAlt, ((m_keyboard_vector[alt_l >> 3] >> (alt_l & 7)) & 1) != 0);
keys.set(GHOST_kModifierKeyRightAlt, ((m_keyboard_vector[alt_r >> 3] >> (alt_r & 7)) & 1) != 0);
/* super (windows) - only one GHOST-kModifierKeyOS, so mapping to either */
- keys.set(GHOST_kModifierKeyOS,
- (((m_keyboard_vector[super_l >> 3] >> (super_l & 7)) & 1) ||
- ((m_keyboard_vector[super_r >> 3] >> (super_r & 7)) & 1)) != 0);
+ keys.set(GHOST_kModifierKeyLeftOS,
+ ((m_keyboard_vector[super_l >> 3] >> (super_l & 7)) & 1) != 0);
+ keys.set(GHOST_kModifierKeyRightOS,
+ ((m_keyboard_vector[super_r >> 3] >> (super_r & 7)) & 1) != 0);
return GHOST_kSuccess;
}
@@ -1611,7 +1611,7 @@ GHOST_TSuccess GHOST_SystemX11::getButtons(GHOST_Buttons &buttons) const
{
Window root_return, child_return;
int rx, ry, wx, wy;
- unsigned int mask_return;
+ uint mask_return;
if (XQueryPointer(m_display,
RootWindow(m_display, DefaultScreen(m_display)),
@@ -1641,7 +1641,7 @@ static GHOST_TSuccess getCursorPosition_impl(Display *display,
Window *child_return)
{
int rx, ry, wx, wy;
- unsigned int mask_return;
+ uint mask_return;
Window root_return;
if (XQueryPointer(display,
@@ -1818,8 +1818,8 @@ static GHOST_TKey ghost_key_from_keysym(const KeySym key)
GXMAP(type, XK_Control_R, GHOST_kKeyRightControl);
GXMAP(type, XK_Alt_L, GHOST_kKeyLeftAlt);
GXMAP(type, XK_Alt_R, GHOST_kKeyRightAlt);
- GXMAP(type, XK_Super_L, GHOST_kKeyOS);
- GXMAP(type, XK_Super_R, GHOST_kKeyOS);
+ GXMAP(type, XK_Super_L, GHOST_kKeyLeftOS);
+ GXMAP(type, XK_Super_R, GHOST_kKeyRightOS);
GXMAP(type, XK_Insert, GHOST_kKeyInsert);
GXMAP(type, XK_Delete, GHOST_kKeyDelete);
@@ -1895,7 +1895,7 @@ static GHOST_TKey ghost_key_from_keysym(const KeySym key)
#undef GXMAP
-#define MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a))
+#define MAKE_ID(a, b, c, d) (int(d) << 24 | int(c) << 16 | (b) << 8 | (a))
static GHOST_TKey ghost_key_from_keycode(const XkbDescPtr xkb_descr, const KeyCode keycode)
{
@@ -1932,18 +1932,14 @@ static GHOST_TKey ghost_key_from_keycode(const XkbDescPtr xkb_descr, const KeyCo
#define XCLIB_XCOUT_FALLBACK_TEXT 6
/* Retrieves the contents of a selections. */
-void GHOST_SystemX11::getClipboard_xcout(const XEvent *evt,
- Atom sel,
- Atom target,
- unsigned char **txt,
- unsigned long *len,
- unsigned int *context) const
+void GHOST_SystemX11::getClipboard_xcout(
+ const XEvent *evt, Atom sel, Atom target, uchar **txt, ulong *len, uint *context) const
{
Atom pty_type;
int pty_format;
- unsigned char *buffer;
- unsigned long pty_size, pty_items;
- unsigned char *ltxt = *txt;
+ uchar *buffer;
+ ulong pty_size, pty_items;
+ uchar *ltxt = *txt;
const vector<GHOST_IWindow *> &win_vec = m_windowManager->getWindows();
vector<GHOST_IWindow *>::const_iterator win_it = win_vec.begin();
@@ -2018,7 +2014,7 @@ void GHOST_SystemX11::getClipboard_xcout(const XEvent *evt,
win,
m_atom.XCLIP_OUT,
0,
- (long)pty_size,
+ long(pty_size),
False,
AnyPropertyType,
&pty_type,
@@ -2031,7 +2027,7 @@ void GHOST_SystemX11::getClipboard_xcout(const XEvent *evt,
XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
/* copy the buffer to the pointer for returned data */
- ltxt = (unsigned char *)malloc(pty_items);
+ ltxt = (uchar *)malloc(pty_items);
memcpy(ltxt, buffer, pty_items);
/* set the length of the returned data */
@@ -2104,7 +2100,7 @@ void GHOST_SystemX11::getClipboard_xcout(const XEvent *evt,
win,
m_atom.XCLIP_OUT,
0,
- (long)pty_size,
+ long(pty_size),
False,
AnyPropertyType,
&pty_type,
@@ -2116,11 +2112,11 @@ void GHOST_SystemX11::getClipboard_xcout(const XEvent *evt,
/* allocate memory to accommodate data in *txt */
if (*len == 0) {
*len = pty_items;
- ltxt = (unsigned char *)malloc(*len);
+ ltxt = (uchar *)malloc(*len);
}
else {
*len += pty_items;
- ltxt = (unsigned char *)realloc(ltxt, *len);
+ ltxt = (uchar *)realloc(ltxt, *len);
}
/* add data to ltxt */
@@ -2144,9 +2140,9 @@ char *GHOST_SystemX11::getClipboard(bool selection) const
/* from xclip.c doOut() v0.11 */
char *sel_buf;
- unsigned long sel_len = 0;
+ ulong sel_len = 0;
XEvent evt;
- unsigned int context = XCLIB_XCOUT_NONE;
+ uint context = XCLIB_XCOUT_NONE;
if (selection == True) {
sseln = m_atom.PRIMARY;
@@ -2188,7 +2184,7 @@ char *GHOST_SystemX11::getClipboard(bool selection) const
}
/* fetch the selection, or part of it */
- getClipboard_xcout(&evt, sseln, target, (unsigned char **)&sel_buf, &sel_len, &context);
+ getClipboard_xcout(&evt, sseln, target, (uchar **)&sel_buf, &sel_len, &context);
if (restore_this_event) {
restore_events.push_back(evt);
@@ -2361,10 +2357,10 @@ class DialogData {
bool isInsideButton(XEvent &e, uint button_num)
{
return (
- (e.xmotion.y > (int)(height - padding_y - button_height)) &&
- (e.xmotion.y < (int)(height - padding_y)) &&
- (e.xmotion.x > (int)(width - (padding_x + button_width) * button_num)) &&
- (e.xmotion.x < (int)(width - padding_x - (padding_x + button_width) * (button_num - 1))));
+ (e.xmotion.y > int(height - padding_y - button_height)) &&
+ (e.xmotion.y < int(height - padding_y)) &&
+ (e.xmotion.x > int(width - (padding_x + button_width) * button_num)) &&
+ (e.xmotion.x < int(width - padding_x - (padding_x + button_width) * (button_num - 1))));
}
};
@@ -2381,7 +2377,7 @@ static void split(const char *text, const char *seps, char ***str, int *count)
free(data);
data = strdup(text);
- *str = (char **)malloc((size_t)(*count) * sizeof(char *));
+ *str = (char **)malloc(size_t(*count) * sizeof(char *));
for (i = 0, tok = strtok(data, seps); tok != nullptr; tok = strtok(nullptr, seps), i++) {
(*str)[i] = strdup(tok);
}
@@ -2437,11 +2433,11 @@ GHOST_TSuccess GHOST_SystemX11::showMessageBox(const char *title,
utf8Str,
8,
PropModeReplace,
- (const unsigned char *)title,
- (int)strlen(title));
+ (const uchar *)title,
+ int(strlen(title)));
XChangeProperty(
- m_display, window, winType, XA_ATOM, 32, PropModeReplace, (unsigned char *)&typeDialog, 1);
+ m_display, window, winType, XA_ATOM, 32, PropModeReplace, (uchar *)&typeDialog, 1);
}
/* Create buttons GC */
@@ -2468,7 +2464,7 @@ GHOST_TSuccess GHOST_SystemX11::showMessageBox(const char *title,
dialog_data.padding_x,
dialog_data.padding_x + (i + 1) * dialog_data.line_height,
text_splitted[i],
- (int)strlen(text_splitted[i]));
+ int(strlen(text_splitted[i])));
}
dialog_data.drawButton(m_display, window, buttonBorderGC, buttonGC, 1, continue_label);
if (strlen(link)) {
diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h
index bd6ace101e9..1f071da6da7 100644
--- a/intern/ghost/intern/GHOST_SystemX11.h
+++ b/intern/ghost/intern/GHOST_SystemX11.h
@@ -14,7 +14,7 @@
#include "../GHOST_Types.h"
#include "GHOST_System.h"
-// For tablets
+/* For tablets. */
#ifdef WITH_X11_XINPUT
# include <X11/extensions/XInput.h>
@@ -113,9 +113,8 @@ class GHOST_SystemX11 : public GHOST_System {
* \param width: The width the window.
* \param height: The height the window.
* \param state: The state of the window when opened.
- * \param type: The type of drawing context installed in this window.
* \param stereoVisual: Create a stereo visual for quad buffered stereo.
- * \param exclusive: Use to show the window ontop and ignore others (used full*screen).
+ * \param exclusive: Use to show the window on top and ignore others (used full-screen).
* \param parentWindow: Parent (embedder) window.
* \return The new window (or 0 if creation failed).
*/
@@ -125,7 +124,6 @@ class GHOST_SystemX11 : public GHOST_System {
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
GHOST_GLSettings glSettings,
const bool exclusive = false,
const bool is_dialog = false,
diff --git a/intern/ghost/intern/GHOST_TimerManager.cpp b/intern/ghost/intern/GHOST_TimerManager.cpp
index e54c2515029..0cdaad20611 100644
--- a/intern/ghost/intern/GHOST_TimerManager.cpp
+++ b/intern/ghost/intern/GHOST_TimerManager.cpp
@@ -26,7 +26,7 @@ GHOST_TimerManager::~GHOST_TimerManager()
uint32_t GHOST_TimerManager::getNumTimers()
{
- return (uint32_t)m_timers.size();
+ return uint32_t(m_timers.size());
}
bool GHOST_TimerManager::getTimerFound(GHOST_TimerTask *timer)
diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp
index db4d6c3bb71..eaa4cdcffac 100644
--- a/intern/ghost/intern/GHOST_Window.cpp
+++ b/intern/ghost/intern/GHOST_Window.cpp
@@ -92,7 +92,12 @@ GHOST_TSuccess GHOST_Window::getSwapInterval(int &intervalOut)
return m_context->getSwapInterval(intervalOut);
}
-unsigned int GHOST_Window::getDefaultFramebuffer()
+GHOST_Context *GHOST_Window::getContext()
+{
+ return m_context;
+}
+
+uint GHOST_Window::getDefaultFramebuffer()
{
return (m_context) ? m_context->getDefaultFramebuffer() : 0;
}
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index 5ff91c05b16..396691fa161 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -29,7 +29,7 @@ class GHOST_Window : public GHOST_IWindow {
* \param height: The height of the window.
* \param state: The state the window is initially opened with.
* \param wantStereoVisual: Stereo visual for quad buffered stereo.
- * \param exclusive: Use to show the window ontop and ignore others (used full-screen).
+ * \param exclusive: Use to show the window on top and ignore others (used full-screen).
*/
GHOST_Window(uint32_t width,
uint32_t height,
@@ -72,24 +72,24 @@ class GHOST_Window : public GHOST_IWindow {
* Returns indication as to whether the window is valid.
* \return The validity of the window.
*/
- virtual bool getValid() const
+ virtual bool getValid() const override
{
- return m_context != NULL;
+ return m_context != nullptr;
}
/**
* Returns the associated OS object/handle
* \return The associated OS object/handle
*/
- virtual void *getOSWindow() const;
+ virtual void *getOSWindow() const override;
/**
* Returns the current cursor shape.
* \return The current cursor shape.
*/
- inline GHOST_TStandardCursor getCursorShape() const;
+ inline GHOST_TStandardCursor getCursorShape() const override;
- inline bool isDialog() const
+ inline bool isDialog() const override
{
return false;
}
@@ -99,7 +99,7 @@ class GHOST_Window : public GHOST_IWindow {
* \param cursorShape: The new cursor shape type id.
* \return Indication of success.
*/
- GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape);
+ GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape) override;
/**
* Set the shape of the cursor to a custom cursor.
@@ -115,15 +115,15 @@ class GHOST_Window : public GHOST_IWindow {
int sizey,
int hotX,
int hotY,
- bool canInvertColor);
+ bool canInvertColor) override;
- GHOST_TSuccess getCursorBitmap(GHOST_CursorBitmapRef *bitmap);
+ GHOST_TSuccess getCursorBitmap(GHOST_CursorBitmapRef *bitmap) override;
/**
* Returns the visibility state of the cursor.
* \return The visibility state of the cursor.
*/
- inline bool getCursorVisibility() const;
+ inline bool getCursorVisibility() const override;
inline GHOST_TGrabCursorMode getCursorGrabMode() const;
inline bool getCursorGrabModeIsWarp() const;
inline GHOST_TAxisFlag getCursorGrabAxis() const;
@@ -136,7 +136,7 @@ class GHOST_Window : public GHOST_IWindow {
* \param visible: The new visibility state of the cursor.
* \return Indication of success.
*/
- GHOST_TSuccess setCursorVisibility(bool visible);
+ GHOST_TSuccess setCursorVisibility(bool visible) override;
/**
* Sets the cursor grab.
@@ -146,28 +146,28 @@ class GHOST_Window : public GHOST_IWindow {
GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode,
GHOST_TAxisFlag wrap_axis,
GHOST_Rect *bounds,
- int32_t mouse_ungrab_xy[2]);
+ int32_t mouse_ungrab_xy[2]) override;
/**
* Gets the cursor grab region, if unset the window is used.
* reset when grab is disabled.
*/
- GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds);
+ GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) override;
void getCursorGrabState(GHOST_TGrabCursorMode &mode,
GHOST_TAxisFlag &axis_flag,
GHOST_Rect &bounds,
- bool &use_software_cursor);
+ bool &use_software_cursor) override;
/**
* Return true when a software cursor should be used.
*/
- bool getCursorGrabUseSoftwareDisplay();
+ bool getCursorGrabUseSoftwareDisplay() override;
/**
* Sets the progress bar value displayed in the window/application icon
* \param progress: The progress percentage (0.0 to 1.0).
*/
- virtual GHOST_TSuccess setProgressBar(float /*progress*/)
+ virtual GHOST_TSuccess setProgressBar(float /*progress*/) override
{
return GHOST_kFailure;
}
@@ -175,7 +175,7 @@ class GHOST_Window : public GHOST_IWindow {
/**
* Hides the progress bar in the icon
*/
- virtual GHOST_TSuccess endProgressBar()
+ virtual GHOST_TSuccess endProgressBar() override
{
return GHOST_kFailure;
}
@@ -185,43 +185,43 @@ class GHOST_Window : public GHOST_IWindow {
* \param interval: The swap interval to use.
* \return A boolean success indicator.
*/
- GHOST_TSuccess setSwapInterval(int interval);
+ GHOST_TSuccess setSwapInterval(int interval) override;
/**
* Gets the current swap interval for #swapBuffers.
* \return An integer.
*/
- GHOST_TSuccess getSwapInterval(int &intervalOut);
+ GHOST_TSuccess getSwapInterval(int &intervalOut) override;
/**
* Tells if the ongoing drag'n'drop object can be accepted upon mouse drop
*/
- void setAcceptDragOperation(bool canAccept);
+ void setAcceptDragOperation(bool canAccept) override;
/**
* Returns acceptance of the dropped object
* Usually called by the "object dropped" event handling function
*/
- bool canAcceptDragOperation() const;
+ bool canAcceptDragOperation() const override;
/**
* Sets the window "modified" status, indicating unsaved changes
* \param isUnsavedChanges: Unsaved changes or not.
* \return Indication of success.
*/
- virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges);
+ virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges) override;
/**
* Gets the window "modified" status, indicating unsaved changes
* \return True if there are unsaved changes
*/
- virtual bool getModifiedState();
+ virtual bool getModifiedState() override;
/**
* Returns the type of drawing context used in this window.
* \return The current type of drawing context.
*/
- inline GHOST_TDrawingContextType getDrawingContextType();
+ inline GHOST_TDrawingContextType getDrawingContextType() override;
/**
* Tries to install a rendering context in this window.
@@ -230,19 +230,19 @@ class GHOST_Window : public GHOST_IWindow {
* \param type: The type of rendering context installed.
* \return Indication as to whether installation has succeeded.
*/
- GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type);
+ GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type) override;
/**
* Swaps front and back buffers of a window.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess swapBuffers();
+ virtual GHOST_TSuccess swapBuffers() override;
/**
* Activates the drawing context of this window.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess activateDrawingContext();
+ virtual GHOST_TSuccess activateDrawingContext() override;
/**
* Updates the drawing context of this window. Needed
@@ -252,16 +252,22 @@ class GHOST_Window : public GHOST_IWindow {
GHOST_TSuccess updateDrawingContext();
/**
+ * Get the drawing context associated with this window.
+ *\return Pointer to the context object.
+ */
+ GHOST_Context *getContext();
+
+ /**
* Gets the OpenGL frame-buffer associated with the window's contents.
* \return The ID of an OpenGL frame-buffer object.
*/
- virtual unsigned int getDefaultFramebuffer();
+ virtual unsigned int getDefaultFramebuffer() override;
/**
* Returns the window user data.
* \return The window user data.
*/
- inline GHOST_TUserDataPtr getUserData() const
+ inline GHOST_TUserDataPtr getUserData() const override
{
return m_userData;
}
@@ -270,15 +276,16 @@ class GHOST_Window : public GHOST_IWindow {
* Changes the window user data.
* \param userData: The window user data.
*/
- void setUserData(const GHOST_TUserDataPtr userData)
+ void setUserData(const GHOST_TUserDataPtr userData) override
{
m_userData = userData;
}
- float getNativePixelSize(void)
+ float getNativePixelSize(void) override
{
- if (m_nativePixelSize > 0.0f)
+ if (m_nativePixelSize > 0.0f) {
return m_nativePixelSize;
+ }
return 1.0f;
}
@@ -286,18 +293,19 @@ class GHOST_Window : public GHOST_IWindow {
* Returns the recommended DPI for this window.
* \return The recommended DPI for this window.
*/
- virtual inline uint16_t getDPIHint()
+ virtual inline uint16_t getDPIHint() override
{
return 96;
}
#ifdef WITH_INPUT_IME
- virtual void beginIME(int32_t x, int32_t y, int32_t w, int32_t h, bool completed)
+ virtual void beginIME(
+ int32_t /*x*/, int32_t /*y*/, int32_t /*w*/, int32_t /*h*/, bool /*completed*/) override
{
/* do nothing temporarily if not in windows */
}
- virtual void endIME()
+ virtual void endIME() override
{
/* do nothing temporarily if not in windows */
}
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm
index e7f5fdaa011..bc1f1e99a3a 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.mm
+++ b/intern/ghost/intern/GHOST_WindowCocoa.mm
@@ -719,7 +719,7 @@ void GHOST_WindowCocoa::setNativePixelSize(void)
}
/**
- * \note Fullscreen switch is not actual fullscreen with display capture.
+ * \note Full-screen switch is not actual fullscreen with display capture.
* As this capture removes all OS X window manager features.
*
* Instead, the menu bar and the dock are hidden, and the window is made border-less and enlarged.
@@ -803,10 +803,10 @@ GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order)
GHOST_Context *GHOST_WindowCocoa::newDrawingContext(GHOST_TDrawingContextType type)
{
- if (type == GHOST_kDrawingContextTypeOpenGL) {
+ if (type == GHOST_kDrawingContextTypeOpenGL || type == GHOST_kDrawingContextTypeMetal) {
GHOST_Context *context = new GHOST_ContextCGL(
- m_wantStereoVisual, m_metalView, m_metalLayer, m_openGLView);
+ m_wantStereoVisual, m_metalView, m_metalLayer, m_openGLView, type);
if (context->initializeDrawingContext())
return context;
diff --git a/intern/ghost/intern/GHOST_WindowManager.h b/intern/ghost/intern/GHOST_WindowManager.h
index bf7a0f4ec61..a0a58fa82d8 100644
--- a/intern/ghost/intern/GHOST_WindowManager.h
+++ b/intern/ghost/intern/GHOST_WindowManager.h
@@ -113,13 +113,13 @@ class GHOST_WindowManager {
/** The list of windows managed */
std::vector<GHOST_IWindow *> m_windows;
- /** Window in fullscreen state. There can be only one of this which is not in or window list. */
+ /** Window in full-screen state. There can be only one of this which is not in or window list. */
GHOST_IWindow *m_fullScreenWindow;
/** The active window. */
GHOST_IWindow *m_activeWindow;
- /** Window that was active before entering fullscreen state. */
+ /** Window that was active before entering full-screen state. */
GHOST_IWindow *m_activeWindowBeforeFullScreen;
#ifdef WITH_CXX_GUARDEDALLOC
diff --git a/intern/ghost/intern/GHOST_WindowSDL.cpp b/intern/ghost/intern/GHOST_WindowSDL.cpp
index 59dc80cf7e6..f0d5f5d93ab 100644
--- a/intern/ghost/intern/GHOST_WindowSDL.cpp
+++ b/intern/ghost/intern/GHOST_WindowSDL.cpp
@@ -205,11 +205,11 @@ void GHOST_WindowSDL::clientToScreen(int32_t inX, int32_t inY, int32_t &outX, in
}
/* mouse cursor */
-static unsigned char sdl_std_cursor_mask_xterm[] = {
+static uchar sdl_std_cursor_mask_xterm[] = {
0xef, 0x01, 0xff, 0x01, 0xff, 0x01, 0x7c, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00,
0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xff, 0x01, 0xff, 0x01, 0xef, 0x01,
};
-static unsigned char sdl_std_cursor_xterm[] = {
+static uchar sdl_std_cursor_xterm[] = {
0x00, 0x77, 0x00, 0x1c, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08,
0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x1c, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00,
};
@@ -218,11 +218,11 @@ static unsigned char sdl_std_cursor_xterm[] = {
#define sdl_std_cursor_HOT_X_xterm -3
#define sdl_std_cursor_HOT_Y_xterm -7
-static unsigned char sdl_std_cursor_mask_watch[] = {
+static uchar sdl_std_cursor_mask_watch[] = {
0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, 0xfe, 0x1f, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0x1f, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f,
};
-static unsigned char sdl_std_cursor_watch[] = {
+static uchar sdl_std_cursor_watch[] = {
0xf8, 0x07, 0xf8, 0x07, 0xf8, 0x07, 0xfc, 0x0f, 0x86, 0x18, 0x83, 0x30, 0x81, 0xe0, 0xc1, 0xe1,
0xc1, 0xe1, 0x21, 0xe0, 0x13, 0x30, 0x06, 0x18, 0xfc, 0x0f, 0xf8, 0x07, 0xf8, 0x07, 0xf8, 0x07,
};
@@ -231,11 +231,11 @@ static unsigned char sdl_std_cursor_watch[] = {
#define sdl_std_cursor_HOT_X_watch -15
#define sdl_std_cursor_HOT_Y_watch -7
-static unsigned char sdl_std_cursor_mask_umbrella[] = {
+static uchar sdl_std_cursor_mask_umbrella[] = {
0xe8, 0x76, 0xfb, 0xdf, 0xfd, 0x3f, 0xfe, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xcf, 0x79, 0xc0, 0x01,
0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0x80, 0x03,
};
-static unsigned char sdl_std_cursor_umbrella[] = {
+static uchar sdl_std_cursor_umbrella[] = {
0x88, 0x04, 0x20, 0x0a, 0xc9, 0x32, 0xf2, 0x09, 0x4c, 0x06, 0x43, 0x18, 0x40, 0x00, 0x40, 0x00,
0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x01, 0x40, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
};
@@ -244,11 +244,11 @@ static unsigned char sdl_std_cursor_umbrella[] = {
#define sdl_std_cursor_HOT_X_umbrella -7
#define sdl_std_cursor_HOT_Y_umbrella -12
-static unsigned char sdl_std_cursor_mask_top_side[] = {
+static uchar sdl_std_cursor_mask_top_side[] = {
0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f,
0xdc, 0x1d, 0xcc, 0x19, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,
};
-static unsigned char sdl_std_cursor_top_side[] = {
+static uchar sdl_std_cursor_top_side[] = {
0xff, 0x1f, 0xff, 0x1f, 0x00, 0x00, 0x40, 0x00, 0xe0, 0x00, 0x50, 0x01, 0x48, 0x02, 0x44, 0x04,
0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
};
@@ -257,11 +257,11 @@ static unsigned char sdl_std_cursor_top_side[] = {
#define sdl_std_cursor_HOT_X_top_side -6
#define sdl_std_cursor_HOT_Y_top_side -14
-static unsigned char sdl_std_cursor_mask_top_right_corner[] = {
+static uchar sdl_std_cursor_mask_top_right_corner[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0xfc, 0xf7, 0xfc, 0xf7, 0xfc, 0xf7,
0xc0, 0xf7, 0xe0, 0xf7, 0x70, 0xf7, 0x38, 0xf7, 0x1c, 0xf7, 0x0c, 0xf7, 0x00, 0xf0, 0x00, 0xf0,
};
-static unsigned char sdl_std_cursor_top_right_corner[] = {
+static uchar sdl_std_cursor_top_right_corner[] = {
0xff, 0x3f, 0xff, 0x3f, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0xfc, 0x31, 0x80, 0x31, 0x40, 0x31,
0x20, 0x31, 0x10, 0x31, 0x08, 0x31, 0x04, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
};
@@ -270,11 +270,11 @@ static unsigned char sdl_std_cursor_top_right_corner[] = {
#define sdl_std_cursor_HOT_X_top_right_corner -13
#define sdl_std_cursor_HOT_Y_top_right_corner -14
-static unsigned char sdl_std_cursor_mask_top_left_corner[] = {
+static uchar sdl_std_cursor_mask_top_left_corner[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xef, 0x3f, 0xef, 0x3f, 0xef, 0x3f,
0xef, 0x03, 0xef, 0x07, 0xef, 0x0e, 0xef, 0x1c, 0xef, 0x38, 0xef, 0x30, 0x0f, 0x00, 0x0f, 0x00,
};
-static unsigned char sdl_std_cursor_top_left_corner[] = {
+static uchar sdl_std_cursor_top_left_corner[] = {
0xff, 0x3f, 0xff, 0x3f, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0xe3, 0x0f, 0x63, 0x00, 0xa3, 0x00,
0x23, 0x01, 0x23, 0x02, 0x23, 0x04, 0x23, 0x08, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
};
@@ -283,11 +283,11 @@ static unsigned char sdl_std_cursor_top_left_corner[] = {
#define sdl_std_cursor_HOT_X_top_left_corner 0
#define sdl_std_cursor_HOT_Y_top_left_corner -14
-static unsigned char sdl_std_cursor_mask_sb_v_double_arrow[] = {
+static uchar sdl_std_cursor_mask_sb_v_double_arrow[] = {
0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0xff, 0x01, 0xff, 0x01, 0x7c, 0x00, 0x7c, 0x00, 0x7c,
0x00, 0x7c, 0x00, 0x7c, 0x00, 0xff, 0x01, 0xff, 0x01, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00,
};
-static unsigned char sdl_std_cursor_sb_v_double_arrow[] = {
+static uchar sdl_std_cursor_sb_v_double_arrow[] = {
0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28,
0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00, 0x10, 0x00,
};
@@ -296,7 +296,7 @@ static unsigned char sdl_std_cursor_sb_v_double_arrow[] = {
#define sdl_std_cursor_HOT_X_sb_v_double_arrow -3
#define sdl_std_cursor_HOT_Y_sb_v_double_arrow -8
-static unsigned char sdl_std_cursor_mask_sb_h_double_arrow[] = {
+static uchar sdl_std_cursor_mask_sb_h_double_arrow[] = {
0x18,
0x0c,
0x1c,
@@ -316,7 +316,7 @@ static unsigned char sdl_std_cursor_mask_sb_h_double_arrow[] = {
0x18,
0x0c,
};
-static unsigned char sdl_std_cursor_sb_h_double_arrow[] = {
+static uchar sdl_std_cursor_sb_h_double_arrow[] = {
0x00,
0x00,
0x08,
@@ -341,11 +341,11 @@ static unsigned char sdl_std_cursor_sb_h_double_arrow[] = {
#define sdl_std_cursor_HOT_X_sb_h_double_arrow -7
#define sdl_std_cursor_HOT_Y_sb_h_double_arrow -4
-static unsigned char sdl_std_cursor_mask_right_side[] = {
+static uchar sdl_std_cursor_mask_right_side[] = {
0x00, 0xf0, 0x00, 0xf0, 0xc0, 0xf0, 0xc0, 0xf1, 0x80, 0xf3, 0x00, 0xf7, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0xf7, 0x80, 0xf3, 0xc0, 0xf1, 0xc0, 0xf0, 0x00, 0xf0, 0x00, 0xf0,
};
-static unsigned char sdl_std_cursor_right_side[] = {
+static uchar sdl_std_cursor_right_side[] = {
0x00, 0x30, 0x00, 0x30, 0x40, 0x30, 0x80, 0x30, 0x00, 0x31, 0x00, 0x32, 0xff, 0x37, 0x00,
0x32, 0x00, 0x31, 0x80, 0x30, 0x40, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
};
@@ -354,11 +354,11 @@ static unsigned char sdl_std_cursor_right_side[] = {
#define sdl_std_cursor_HOT_X_right_side -13
#define sdl_std_cursor_HOT_Y_right_side -7
-static unsigned char sdl_std_cursor_mask_right_ptr[] = {
+static uchar sdl_std_cursor_mask_right_ptr[] = {
0x00, 0x03, 0x80, 0x03, 0xc0, 0x03, 0xe0, 0x03, 0xf0, 0x03, 0xf8, 0x03, 0xfc, 0x03, 0xfe, 0x03,
0xff, 0x03, 0xff, 0x03, 0xf8, 0x03, 0xbc, 0x03, 0x3c, 0x03, 0x1e, 0x00, 0x1e, 0x00, 0x0c, 0x00,
};
-static unsigned char sdl_std_cursor_right_ptr[] = {
+static uchar sdl_std_cursor_right_ptr[] = {
0x00, 0x80, 0x00, 0xc0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf8, 0x00, 0xfc, 0x00, 0xfe, 0x00, 0xff,
0x00, 0xf8, 0x00, 0xd8, 0x00, 0x8c, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
};
@@ -367,11 +367,11 @@ static unsigned char sdl_std_cursor_right_ptr[] = {
#define sdl_std_cursor_HOT_X_right_ptr -7
#define sdl_std_cursor_HOT_Y_right_ptr -14
-static unsigned char sdl_std_cursor_mask_question_arrow[] = {
+static uchar sdl_std_cursor_mask_question_arrow[] = {
0xf8, 0x00, 0xfc, 0x01, 0xfe, 0x03, 0xff, 0x07, 0x8f, 0x07, 0x9f, 0x07, 0xde, 0x07, 0xfc, 0x03,
0xf8, 0x01, 0xf8, 0x00, 0xf8, 0x00, 0xfc, 0x01, 0xfe, 0x03, 0xfc, 0x01, 0xf8, 0x00, 0x70, 0x00,
};
-static unsigned char sdl_std_cursor_question_arrow[] = {
+static uchar sdl_std_cursor_question_arrow[] = {
0x7c, 0x00, 0xfe, 0x00, 0xc7, 0x01, 0x83, 0x01, 0x87, 0x01, 0xc6, 0x01, 0xe0, 0x00, 0x78, 0x00,
0x38, 0x00, 0x28, 0x00, 0x28, 0x00, 0xee, 0x00, 0x6c, 0x00, 0x38, 0x00, 0x10, 0x00, 0x00, 0x00,
};
@@ -380,11 +380,11 @@ static unsigned char sdl_std_cursor_question_arrow[] = {
#define sdl_std_cursor_HOT_X_question_arrow -4
#define sdl_std_cursor_HOT_Y_question_arrow -8
-static unsigned char sdl_std_cursor_mask_pirate[] = {
+static uchar sdl_std_cursor_mask_pirate[] = {
0xf0, 0x03, 0xf8, 0x07, 0xfc, 0x0f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfc, 0x0f, 0xf8, 0x07, 0xf1, 0x83,
0xf1, 0xe3, 0xf3, 0xf3, 0xef, 0x39, 0x1e, 0x1e, 0xe0, 0x01, 0xfe, 0xc7, 0xff, 0xff, 0x0f, 0x7c,
};
-static unsigned char sdl_std_cursor_pirate[] = {
+static uchar sdl_std_cursor_pirate[] = {
0xe0, 0x01, 0xf0, 0x03, 0xf8, 0x07, 0xcc, 0x0c, 0xcc, 0x0c, 0xf8, 0x07, 0xf0, 0x03, 0xe0, 0x01,
0xe1, 0x21, 0xe1, 0x61, 0xc2, 0x10, 0x1c, 0x0e, 0xe0, 0x01, 0xf8, 0x47, 0x0f, 0x7c, 0x01, 0x20,
};
@@ -393,11 +393,11 @@ static unsigned char sdl_std_cursor_pirate[] = {
#define sdl_std_cursor_HOT_X_pirate -7
#define sdl_std_cursor_HOT_Y_pirate -4
-static unsigned char sdl_std_cursor_mask_left_side[] = {
+static uchar sdl_std_cursor_mask_left_side[] = {
0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x03, 0x8f, 0x03, 0xcf, 0x01, 0xef, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xef, 0x00, 0xcf, 0x01, 0x8f, 0x03, 0x0f, 0x03, 0x0f, 0x00, 0x0f, 0x00,
};
-static unsigned char sdl_std_cursor_left_side[] = {
+static uchar sdl_std_cursor_left_side[] = {
0x03, 0x00, 0x03, 0x00, 0x83, 0x00, 0x43, 0x00, 0x23, 0x00, 0x13, 0x00, 0xfb, 0x3f, 0x13,
0x00, 0x23, 0x00, 0x43, 0x00, 0x83, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
};
@@ -406,11 +406,11 @@ static unsigned char sdl_std_cursor_left_side[] = {
#define sdl_std_cursor_HOT_X_left_side 0
#define sdl_std_cursor_HOT_Y_left_side -7
-static unsigned char sdl_std_cursor_mask_left_ptr[] = {
+static uchar sdl_std_cursor_mask_left_ptr[] = {
0x03, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x3f, 0x00, 0x7f, 0x00, 0xff, 0x00, 0xff, 0x01,
0xff, 0x03, 0xff, 0x03, 0x7f, 0x00, 0xf7, 0x00, 0xf3, 0x00, 0xe0, 0x01, 0xe0, 0x01, 0xc0, 0x00,
};
-static unsigned char sdl_std_cursor_left_ptr[] = {
+static uchar sdl_std_cursor_left_ptr[] = {
0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x1e, 0x00, 0x3e, 0x00, 0x7e, 0x00, 0xfe, 0x00,
0xfe, 0x00, 0x3e, 0x00, 0x36, 0x00, 0x62, 0x00, 0x60, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0x00, 0x00,
};
@@ -419,11 +419,11 @@ static unsigned char sdl_std_cursor_left_ptr[] = {
#define sdl_std_cursor_HOT_X_left_ptr -8
#define sdl_std_cursor_HOT_Y_left_ptr -14
-static unsigned char sdl_std_cursor_mask_crosshair[] = {
+static uchar sdl_std_cursor_mask_crosshair[] = {
0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,
};
-static unsigned char sdl_std_cursor_crosshair[] = {
+static uchar sdl_std_cursor_crosshair[] = {
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x7f, 0xff,
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00,
};
@@ -432,11 +432,11 @@ static unsigned char sdl_std_cursor_crosshair[] = {
#define sdl_std_cursor_HOT_X_crosshair -7
#define sdl_std_cursor_HOT_Y_crosshair -8
-static unsigned char sdl_std_cursor_mask_bottom_side[] = {
+static uchar sdl_std_cursor_mask_bottom_side[] = {
0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xcc, 0x19, 0xdc, 0x1d,
0xf8, 0x0f, 0xf0, 0x07, 0xe0, 0x03, 0xc0, 0x01, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f,
};
-static unsigned char sdl_std_cursor_bottom_side[] = {
+static uchar sdl_std_cursor_bottom_side[] = {
0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x44, 0x04, 0x48, 0x02,
0x50, 0x01, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0xff, 0x1f, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00,
};
@@ -445,11 +445,11 @@ static unsigned char sdl_std_cursor_bottom_side[] = {
#define sdl_std_cursor_HOT_X_bottom_side -6
#define sdl_std_cursor_HOT_Y_bottom_side -1
-static unsigned char sdl_std_cursor_mask_bottom_right_corner[] = {
+static uchar sdl_std_cursor_mask_bottom_right_corner[] = {
0x00, 0xf0, 0x00, 0xf0, 0x0c, 0xf7, 0x1c, 0xf7, 0x38, 0xf7, 0x70, 0xf7, 0xe0, 0xf7, 0xc0, 0xf7,
0xfc, 0xf7, 0xfc, 0xf7, 0xfc, 0xf7, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};
-static unsigned char sdl_std_cursor_bottom_right_corner[] = {
+static uchar sdl_std_cursor_bottom_right_corner[] = {
0x00, 0x30, 0x00, 0x30, 0x04, 0x31, 0x08, 0x31, 0x10, 0x31, 0x20, 0x31, 0x40, 0x31, 0x80, 0x31,
0xfc, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00,
};
@@ -458,11 +458,11 @@ static unsigned char sdl_std_cursor_bottom_right_corner[] = {
#define sdl_std_cursor_HOT_X_bottom_right_corner -13
#define sdl_std_cursor_HOT_Y_bottom_right_corner -1
-static unsigned char sdl_std_cursor_mask_bottom_left_corner[] = {
+static uchar sdl_std_cursor_mask_bottom_left_corner[] = {
0x0f, 0x00, 0x0f, 0x00, 0xef, 0x30, 0xef, 0x38, 0xef, 0x1c, 0xef, 0x0e, 0xef, 0x07, 0xef, 0x03,
0xef, 0x3f, 0xef, 0x3f, 0xef, 0x3f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};
-static unsigned char sdl_std_cursor_bottom_left_corner[] = {
+static uchar sdl_std_cursor_bottom_left_corner[] = {
0x03, 0x00, 0x03, 0x00, 0x23, 0x08, 0x23, 0x04, 0x23, 0x02, 0x23, 0x01, 0xa3, 0x00, 0x63, 0x00,
0xe3, 0x0f, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00,
};
@@ -471,11 +471,11 @@ static unsigned char sdl_std_cursor_bottom_left_corner[] = {
#define sdl_std_cursor_HOT_X_bottom_left_corner 0
#define sdl_std_cursor_HOT_Y_bottom_left_corner -1
-static unsigned char sdl_std_cursor_mask_arrow[] = {
+static uchar sdl_std_cursor_mask_arrow[] = {
0x00, 0xe0, 0x00, 0xf8, 0x00, 0xfe, 0x80, 0x7f, 0xe0, 0x7f, 0xf8, 0x3f, 0xfc, 0x3f, 0xfc, 0x1f,
0xe0, 0x1f, 0xf0, 0x0f, 0xf8, 0x0f, 0x7c, 0x07, 0x3e, 0x07, 0x1f, 0x02, 0x0e, 0x00, 0x04, 0x00,
};
-static unsigned char sdl_std_cursor_arrow[] = {
+static uchar sdl_std_cursor_arrow[] = {
0x00, 0x30, 0x00, 0x3c, 0x00, 0x1f, 0xc0, 0x1f, 0xf0, 0x0f, 0xfc, 0x0f, 0xc0, 0x07, 0xe0, 0x07,
0x70, 0x03, 0x38, 0x03, 0x1c, 0x01, 0x0e, 0x01, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
};
@@ -485,7 +485,7 @@ static unsigned char sdl_std_cursor_arrow[] = {
#define sdl_std_cursor_HOT_Y_arrow -14
/* end cursor data */
-static SDL_Cursor *sdl_std_cursor_array[(int)GHOST_kStandardCursorNumCursors] = {nullptr};
+static SDL_Cursor *sdl_std_cursor_array[int(GHOST_kStandardCursorNumCursors)] = {nullptr};
/* utility function mostly a copy of SDL_CreateCursor but allows us to change
* color and supports blenders flipped bits */
@@ -544,14 +544,14 @@ static SDL_Cursor *getStandardCursorShape(GHOST_TStandardCursor shape)
if (sdl_std_cursor_array[0] == nullptr) {
#define DEF_CURSOR(name, ind) \
{ \
- sdl_std_cursor_array[(int)ind] = sdl_ghost_CreateCursor( \
+ sdl_std_cursor_array[int(ind)] = sdl_ghost_CreateCursor( \
sdl_std_cursor_##name, \
sdl_std_cursor_mask_##name, \
sdl_std_cursor_WIDTH_##name, \
sdl_std_cursor_HEIGHT_##name, \
(sdl_std_cursor_WIDTH_##name + (sdl_std_cursor_HOT_X_##name)) - 1, \
(sdl_std_cursor_HEIGHT_##name + (sdl_std_cursor_HOT_Y_##name)) - 1); \
- assert(sdl_std_cursor_array[(int)ind] != nullptr); \
+ assert(sdl_std_cursor_array[int(ind)] != nullptr); \
} \
(void)0
@@ -580,7 +580,7 @@ static SDL_Cursor *getStandardCursorShape(GHOST_TStandardCursor shape)
#undef DEF_CURSOR
}
- return sdl_std_cursor_array[(int)shape];
+ return sdl_std_cursor_array[int(shape)];
}
GHOST_TSuccess GHOST_WindowSDL::setWindowCursorGrab(GHOST_TGrabCursorMode /*mode*/)
@@ -641,5 +641,5 @@ uint16_t GHOST_WindowSDL::getDPIHint()
return 96;
}
- return (int)ddpi;
+ return int(ddpi);
}
diff --git a/intern/ghost/intern/GHOST_WindowViewCocoa.h b/intern/ghost/intern/GHOST_WindowViewCocoa.h
index 58c029620da..29653bd5ea2 100644
--- a/intern/ghost/intern/GHOST_WindowViewCocoa.h
+++ b/intern/ghost/intern/GHOST_WindowViewCocoa.h
@@ -226,7 +226,7 @@
[super drawRect:rect];
systemCocoa->handleWindowEvent(GHOST_kEventWindowUpdate, associatedWindow);
- /* For some cases like entering fullscreen we need to redraw immediately
+ /* For some cases like entering full-screen we need to redraw immediately
* so our window does not show blank during the animation */
if (associatedWindow->getImmediateDraw())
systemCocoa->dispatchEvents();
diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp
index 5f3cb3e3f3a..9d62c69edef 100644
--- a/intern/ghost/intern/GHOST_WindowWayland.cpp
+++ b/intern/ghost/intern/GHOST_WindowWayland.cpp
@@ -31,15 +31,54 @@
# include <libdecor.h>
#endif
+/* Generated by `wayland-scanner`. */
+#include <xdg-decoration-unstable-v1-client-protocol.h>
+#include <xdg-shell-client-protocol.h>
+
/* Logging, use `ghost.wl.*` prefix. */
#include "CLG_log.h"
static constexpr size_t base_dpi = 96;
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+/* Access `use_libdecor` in #GHOST_SystemWayland. */
+# define use_libdecor GHOST_SystemWayland::use_libdecor_runtime()
+#endif
+
static GHOST_WindowManager *window_manager = nullptr;
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+struct WGL_LibDecor_Window {
+ struct libdecor_frame *frame = nullptr;
+ bool configured = false;
+};
+
+static void gwl_libdecor_window_destroy(WGL_LibDecor_Window *decor)
+{
+ libdecor_frame_unref(decor->frame);
+ delete decor;
+}
+#endif /* WITH_GHOST_WAYLAND_LIBDECOR */
+
+struct WGL_XDG_Decor_Window {
+ struct xdg_surface *surface = nullptr;
+ struct zxdg_toplevel_decoration_v1 *toplevel_decor = nullptr;
+ struct xdg_toplevel *toplevel = nullptr;
+ enum zxdg_toplevel_decoration_v1_mode mode = (enum zxdg_toplevel_decoration_v1_mode)0;
+};
+
+static void gwl_xdg_decor_window_destroy(WGL_XDG_Decor_Window *decor)
+{
+ if (decor->toplevel_decor) {
+ zxdg_toplevel_decoration_v1_destroy(decor->toplevel_decor);
+ }
+ xdg_toplevel_destroy(decor->toplevel);
+ xdg_surface_destroy(decor->surface);
+ delete decor;
+}
+
struct GWL_Window {
- GHOST_WindowWayland *w = nullptr;
+ GHOST_WindowWayland *ghost_window = nullptr;
struct wl_surface *wl_surface = nullptr;
/**
* Outputs on which the window is currently shown on.
@@ -52,23 +91,15 @@ struct GWL_Window {
/** The scale value written to #wl_surface_set_buffer_scale. */
int scale = 0;
/**
- * The DPI, either:
- * - `scale * base_dpi`
- * - `wl_fixed_to_int(scale_fractional * base_dpi)`
- * When fractional scaling is available.
+ * The fractional scale used to calculate the DPI.
+ * (always set, even when scaling is rounded to whole units).
*/
- uint32_t dpi = 0;
+ wl_fixed_t scale_fractional = 0;
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- struct libdecor_frame *decor_frame = nullptr;
- bool decor_configured = false;
-#else
- struct xdg_surface *xdg_surface = nullptr;
- struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration = nullptr;
- struct xdg_toplevel *xdg_toplevel = nullptr;
-
- enum zxdg_toplevel_decoration_v1_mode decoration_mode = (enum zxdg_toplevel_decoration_v1_mode)0;
+ WGL_LibDecor_Window *libdecor = nullptr;
#endif
+ WGL_XDG_Decor_Window *xdg_decor = nullptr;
wl_egl_window *egl_window = nullptr;
bool is_maximised = false;
@@ -114,7 +145,7 @@ static int output_scale_cmp(const GWL_Output *output_a, const GWL_Output *output
static int outputs_max_scale_or_default(const std::vector<GWL_Output *> &outputs,
const int32_t scale_default,
- uint32_t *r_dpi)
+ wl_fixed_t *r_scale_fractional)
{
const GWL_Output *output_max = nullptr;
for (const GWL_Output *reg_output : outputs) {
@@ -124,18 +155,16 @@ static int outputs_max_scale_or_default(const std::vector<GWL_Output *> &outputs
}
if (output_max) {
- if (r_dpi) {
- *r_dpi = output_max->has_scale_fractional ?
- /* Fractional DPI. */
- wl_fixed_to_int(output_max->scale_fractional * base_dpi) :
- /* Simple non-fractional DPI. */
- (output_max->scale * base_dpi);
+ if (r_scale_fractional) {
+ *r_scale_fractional = output_max->has_scale_fractional ?
+ output_max->scale_fractional :
+ wl_fixed_from_int(output_max->scale);
}
return output_max->scale;
}
- if (r_dpi) {
- *r_dpi = scale_default * base_dpi;
+ if (r_scale_fractional) {
+ *r_scale_fractional = wl_fixed_from_int(scale_default);
}
return scale_default;
}
@@ -146,10 +175,8 @@ static int outputs_max_scale_or_default(const std::vector<GWL_Output *> &outputs
/** \name Listener (XDG Top Level), #xdg_toplevel_listener
* \{ */
-#ifndef WITH_GHOST_WAYLAND_LIBDECOR
-
static CLG_LogRef LOG_WL_XDG_TOPLEVEL = {"ghost.wl.handle.xdg_toplevel"};
-# define LOG (&LOG_WL_XDG_TOPLEVEL)
+#define LOG (&LOG_WL_XDG_TOPLEVEL)
static void xdg_toplevel_handle_configure(void *data,
xdg_toplevel * /*xdg_toplevel*/,
@@ -189,17 +216,15 @@ static void xdg_toplevel_handle_configure(void *data,
static void xdg_toplevel_handle_close(void *data, xdg_toplevel * /*xdg_toplevel*/)
{
CLOG_INFO(LOG, 2, "close");
- static_cast<GWL_Window *>(data)->w->close();
+ static_cast<GWL_Window *>(data)->ghost_window->close();
}
-static const xdg_toplevel_listener toplevel_listener = {
+static const xdg_toplevel_listener xdg_toplevel_listener = {
xdg_toplevel_handle_configure,
xdg_toplevel_handle_close,
};
-# undef LOG
-
-#endif /* !WITH_GHOST_WAYLAND_LIBDECOR. */
+#undef LOG
/** \} */
@@ -234,7 +259,7 @@ static void frame_handle_configure(struct libdecor_frame *frame,
win->size[1] = win->scale * size_next[1];
wl_egl_window_resize(win->egl_window, UNPACK2(win->size), 0, 0);
- win->w->notify_size();
+ win->ghost_window->notify_size();
if (!libdecor_configuration_get_window_state(configuration, &window_state)) {
window_state = LIBDECOR_WINDOW_STATE_NONE;
@@ -244,20 +269,20 @@ static void frame_handle_configure(struct libdecor_frame *frame,
win->is_fullscreen = window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN;
win->is_active = window_state & LIBDECOR_WINDOW_STATE_ACTIVE;
- win->is_active ? win->w->activate() : win->w->deactivate();
+ win->is_active ? win->ghost_window->activate() : win->ghost_window->deactivate();
state = libdecor_state_new(UNPACK2(size_next));
libdecor_frame_commit(frame, state, configuration);
libdecor_state_free(state);
- win->decor_configured = true;
+ win->libdecor->configured = true;
}
static void frame_handle_close(struct libdecor_frame * /*frame*/, void *data)
{
CLOG_INFO(LOG, 2, "close");
- static_cast<GWL_Window *>(data)->w->close();
+ static_cast<GWL_Window *>(data)->ghost_window->close();
}
static void frame_handle_commit(struct libdecor_frame * /*frame*/, void *data)
@@ -265,8 +290,8 @@ static void frame_handle_commit(struct libdecor_frame * /*frame*/, void *data)
CLOG_INFO(LOG, 2, "commit");
/* We have to swap twice to keep any pop-up menus alive. */
- static_cast<GWL_Window *>(data)->w->swapBuffers();
- static_cast<GWL_Window *>(data)->w->swapBuffers();
+ static_cast<GWL_Window *>(data)->ghost_window->swapBuffers();
+ static_cast<GWL_Window *>(data)->ghost_window->swapBuffers();
}
static struct libdecor_frame_interface libdecor_frame_iface = {
@@ -285,10 +310,8 @@ static struct libdecor_frame_interface libdecor_frame_iface = {
/** \name Listener (XDG Decoration Listener), #zxdg_toplevel_decoration_v1_listener
* \{ */
-#ifndef WITH_GHOST_WAYLAND_LIBDECOR
-
static CLG_LogRef LOG_WL_XDG_TOPLEVEL_DECORATION = {"ghost.wl.handle.xdg_toplevel_decoration"};
-# define LOG (&LOG_WL_XDG_TOPLEVEL_DECORATION)
+#define LOG (&LOG_WL_XDG_TOPLEVEL_DECORATION)
static void xdg_toplevel_decoration_handle_configure(
void *data,
@@ -296,16 +319,14 @@ static void xdg_toplevel_decoration_handle_configure(
const uint32_t mode)
{
CLOG_INFO(LOG, 2, "configure (mode=%u)", mode);
- static_cast<GWL_Window *>(data)->decoration_mode = (zxdg_toplevel_decoration_v1_mode)mode;
+ static_cast<GWL_Window *>(data)->xdg_decor->mode = (zxdg_toplevel_decoration_v1_mode)mode;
}
-static const zxdg_toplevel_decoration_v1_listener toplevel_decoration_v1_listener = {
+static const zxdg_toplevel_decoration_v1_listener xdg_toplevel_decoration_v1_listener = {
xdg_toplevel_decoration_handle_configure,
};
-# undef LOG
-
-#endif /* !WITH_GHOST_WAYLAND_LIBDECOR. */
+#undef LOG
/** \} */
@@ -313,10 +334,8 @@ static const zxdg_toplevel_decoration_v1_listener toplevel_decoration_v1_listene
/** \name Listener (XDG Surface Handle Configure), #xdg_surface_listener
* \{ */
-#ifndef WITH_GHOST_WAYLAND_LIBDECOR
-
static CLG_LogRef LOG_WL_XDG_SURFACE = {"ghost.wl.handle.xdg_surface"};
-# define LOG (&LOG_WL_XDG_SURFACE)
+#define LOG (&LOG_WL_XDG_SURFACE)
static void xdg_surface_handle_configure(void *data,
xdg_surface *xdg_surface,
@@ -324,7 +343,7 @@ static void xdg_surface_handle_configure(void *data,
{
GWL_Window *win = static_cast<GWL_Window *>(data);
- if (win->xdg_surface != xdg_surface) {
+ if (win->xdg_decor->surface != xdg_surface) {
CLOG_INFO(LOG, 2, "configure (skipped)");
return;
}
@@ -337,14 +356,14 @@ static void xdg_surface_handle_configure(void *data,
wl_egl_window_resize(win->egl_window, UNPACK2(win->size), 0, 0);
win->size_pending[0] = 0;
win->size_pending[1] = 0;
- win->w->notify_size();
+ win->ghost_window->notify_size();
}
if (win->is_active) {
- win->w->activate();
+ win->ghost_window->activate();
}
else {
- win->w->deactivate();
+ win->ghost_window->deactivate();
}
xdg_surface_ack_configure(xdg_surface, serial);
@@ -354,9 +373,7 @@ static const xdg_surface_listener xdg_surface_listener = {
xdg_surface_handle_configure,
};
-# undef LOG
-
-#endif /* !WITH_GHOST_WAYLAND_LIBDECOR. */
+#undef LOG
/** \} */
@@ -401,7 +418,7 @@ static void surface_handle_leave(void *data,
}
}
-static struct wl_surface_listener wl_surface_listener = {
+static const struct wl_surface_listener wl_surface_listener = {
surface_handle_enter,
surface_handle_leave,
};
@@ -418,7 +435,7 @@ static struct wl_surface_listener wl_surface_listener = {
GHOST_TSuccess GHOST_WindowWayland::hasCursorShape(GHOST_TStandardCursor cursorShape)
{
- return m_system->hasCursorShape(cursorShape);
+ return system_->hasCursorShape(cursorShape);
}
GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
@@ -434,20 +451,20 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
const bool stereoVisual,
const bool exclusive)
: GHOST_Window(width, height, state, stereoVisual, exclusive),
- m_system(system),
- w(new GWL_Window)
+ system_(system),
+ window_(new GWL_Window)
{
/* Globally store pointer to window manager. */
if (!window_manager) {
- window_manager = m_system->getWindowManager();
+ window_manager = system_->getWindowManager();
}
- w->w = this;
+ window_->ghost_window = this;
- w->size[0] = int32_t(width);
- w->size[1] = int32_t(height);
+ window_->size[0] = int32_t(width);
+ window_->size[1] = int32_t(height);
- w->is_dialog = is_dialog;
+ window_->is_dialog = is_dialog;
/* NOTE(@campbellbarton): The scale set here to avoid flickering on startup.
* When all monitors use the same scale (which is quite common) there aren't any problems.
@@ -458,75 +475,100 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
*
* Using the maximum scale is best as it results in the window first being smaller,
* avoiding a large window flashing before it's made smaller. */
- w->scale = outputs_max_scale_or_default(this->m_system->outputs(), 1, &w->dpi);
+ window_->scale = outputs_max_scale_or_default(system_->outputs(), 1, &window_->scale_fractional);
/* Window surfaces. */
- w->wl_surface = wl_compositor_create_surface(m_system->compositor());
- ghost_wl_surface_tag(w->wl_surface);
+ window_->wl_surface = wl_compositor_create_surface(system_->wl_compositor());
+ ghost_wl_surface_tag(window_->wl_surface);
- wl_surface_set_buffer_scale(w->wl_surface, w->scale);
+ wl_surface_set_buffer_scale(window_->wl_surface, window_->scale);
- wl_surface_add_listener(w->wl_surface, &wl_surface_listener, this);
+ wl_surface_add_listener(window_->wl_surface, &wl_surface_listener, window_);
- w->egl_window = wl_egl_window_create(w->wl_surface, int(w->size[0]), int(w->size[1]));
+ window_->egl_window = wl_egl_window_create(
+ window_->wl_surface, int(window_->size[0]), int(window_->size[1]));
/* NOTE: The limit is in points (not pixels) so Hi-DPI will limit to larger number of pixels.
* This has the advantage that the size limit is the same when moving the window between monitors
* with different scales set. If it was important to limit in pixels it could be re-calculated
- * when the `w->scale` changed. */
+ * when the `window_->scale` changed. */
const int32_t size_min[2] = {320, 240};
-#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- /* create window decorations */
- w->decor_frame = libdecor_decorate(
- m_system->decor_context(), w->wl_surface, &libdecor_frame_iface, w);
- libdecor_frame_map(w->decor_frame);
-
- libdecor_frame_set_min_content_size(w->decor_frame, UNPACK2(size_min));
-
- if (parentWindow) {
- libdecor_frame_set_parent(
- w->decor_frame, dynamic_cast<const GHOST_WindowWayland *>(parentWindow)->w->decor_frame);
- }
-#else
- w->xdg_surface = xdg_wm_base_get_xdg_surface(m_system->xdg_shell(), w->wl_surface);
- w->xdg_toplevel = xdg_surface_get_toplevel(w->xdg_surface);
-
- xdg_toplevel_set_min_size(w->xdg_toplevel, UNPACK2(size_min));
+ /* This value is expected to match the base name of the `.desktop` file. see T101805.
+ *
+ * NOTE: the XDG desktop-entry-spec defines that this should follow the "reverse DNS" convention.
+ * For e.g. `org.blender.Blender` - however the `.desktop` file distributed with Blender is
+ * simply called `blender.desktop`, so the it's important to follow that name.
+ * Other distributions such as SNAP & FLATPAK may need to change this value T101779.
+ * Currently there isn't a way to configure this, we may want to support that. */
+ const char *xdg_app_id = "blender";
- if (m_system->xdg_decoration_manager()) {
- w->xdg_toplevel_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(
- m_system->xdg_decoration_manager(), w->xdg_toplevel);
- zxdg_toplevel_decoration_v1_add_listener(
- w->xdg_toplevel_decoration, &toplevel_decoration_v1_listener, w);
- zxdg_toplevel_decoration_v1_set_mode(w->xdg_toplevel_decoration,
- ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+ if (use_libdecor) {
+ window_->libdecor = new WGL_LibDecor_Window;
+ WGL_LibDecor_Window &decor = *window_->libdecor;
+
+ /* create window decorations */
+ decor.frame = libdecor_decorate(
+ system_->libdecor_context(), window_->wl_surface, &libdecor_frame_iface, window_);
+ libdecor_frame_map(window_->libdecor->frame);
+
+ libdecor_frame_set_min_content_size(decor.frame, UNPACK2(size_min));
+ libdecor_frame_set_app_id(decor.frame, xdg_app_id);
+
+ if (parentWindow) {
+ WGL_LibDecor_Window &decor_parent =
+ *dynamic_cast<const GHOST_WindowWayland *>(parentWindow)->window_->libdecor;
+ libdecor_frame_set_parent(decor.frame, decor_parent.frame);
+ }
}
+ else
+#endif
+ {
+ window_->xdg_decor = new WGL_XDG_Decor_Window;
+ WGL_XDG_Decor_Window &decor = *window_->xdg_decor;
+ decor.surface = xdg_wm_base_get_xdg_surface(system_->xdg_decor_shell(), window_->wl_surface);
+ decor.toplevel = xdg_surface_get_toplevel(decor.surface);
+
+ xdg_toplevel_set_min_size(decor.toplevel, UNPACK2(size_min));
+ xdg_toplevel_set_app_id(decor.toplevel, xdg_app_id);
+
+ if (system_->xdg_decor_manager()) {
+ decor.toplevel_decor = zxdg_decoration_manager_v1_get_toplevel_decoration(
+ system_->xdg_decor_manager(), decor.toplevel);
+ zxdg_toplevel_decoration_v1_add_listener(
+ decor.toplevel_decor, &xdg_toplevel_decoration_v1_listener, window_);
+ zxdg_toplevel_decoration_v1_set_mode(decor.toplevel_decor,
+ ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
+ }
- xdg_surface_add_listener(w->xdg_surface, &xdg_surface_listener, w);
- xdg_toplevel_add_listener(w->xdg_toplevel, &toplevel_listener, w);
+ xdg_surface_add_listener(decor.surface, &xdg_surface_listener, window_);
+ xdg_toplevel_add_listener(decor.toplevel, &xdg_toplevel_listener, window_);
- if (parentWindow && is_dialog) {
- xdg_toplevel_set_parent(
- w->xdg_toplevel, dynamic_cast<const GHOST_WindowWayland *>(parentWindow)->w->xdg_toplevel);
+ if (parentWindow && is_dialog) {
+ WGL_XDG_Decor_Window &decor_parent =
+ *dynamic_cast<const GHOST_WindowWayland *>(parentWindow)->window_->xdg_decor;
+ xdg_toplevel_set_parent(decor.toplevel, decor_parent.toplevel);
+ }
}
-#endif /* !WITH_GHOST_WAYLAND_LIBDECOR */
-
setTitle(title);
- wl_surface_set_user_data(w->wl_surface, this);
+ wl_surface_set_user_data(window_->wl_surface, this);
/* Call top-level callbacks. */
- wl_surface_commit(w->wl_surface);
- wl_display_roundtrip(m_system->display());
+ wl_surface_commit(window_->wl_surface);
+ wl_display_roundtrip(system_->wl_display());
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- /* It's important not to return until the window is configured or
- * calls to `setState` from Blender will crash `libdecor`. */
- while (!w->decor_configured) {
- if (libdecor_dispatch(m_system->decor_context(), 0) < 0) {
- break;
+ if (use_libdecor) {
+ WGL_LibDecor_Window &decor = *window_->libdecor;
+ /* It's important not to return until the window is configured or
+ * calls to `setState` from Blender will crash `libdecor`. */
+ while (!decor.configured) {
+ if (libdecor_dispatch(system_->libdecor_context(), 0) < 0) {
+ break;
+ }
}
}
#endif
@@ -535,9 +577,13 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
setOpaque();
#endif
-#ifndef WITH_GHOST_WAYLAND_LIBDECOR /* Causes a glitch with `libdecor` for some reason. */
- setState(state);
+ /* Causes a glitch with `libdecor` for some reason. */
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+ if (use_libdecor == false)
#endif
+ {
+ setState(state);
+ }
/* EGL context. */
if (setDrawingContextType(type) == GHOST_kFailure) {
@@ -558,13 +604,13 @@ GHOST_TSuccess GHOST_WindowWayland::setWindowCursorGrab(GHOST_TGrabCursorMode mo
}
bounds = &bounds_buf;
}
- if (m_system->window_cursor_grab_set(mode,
- m_cursorGrab,
- m_cursorGrabInitPos,
- bounds,
- m_cursorGrabAxis,
- w->wl_surface,
- w->scale)) {
+ if (system_->window_cursor_grab_set(mode,
+ m_cursorGrab,
+ m_cursorGrabInitPos,
+ bounds,
+ m_cursorGrabAxis,
+ window_->wl_surface,
+ window_->scale)) {
return GHOST_kSuccess;
}
return GHOST_kFailure;
@@ -572,43 +618,47 @@ GHOST_TSuccess GHOST_WindowWayland::setWindowCursorGrab(GHOST_TGrabCursorMode mo
GHOST_TSuccess GHOST_WindowWayland::setWindowCursorShape(GHOST_TStandardCursor shape)
{
- const GHOST_TSuccess ok = m_system->setCursorShape(shape);
+ const GHOST_TSuccess ok = system_->setCursorShape(shape);
m_cursorShape = (ok == GHOST_kSuccess) ? shape : GHOST_kStandardCursorDefault;
return ok;
}
bool GHOST_WindowWayland::getCursorGrabUseSoftwareDisplay()
{
- return m_system->getCursorGrabUseSoftwareDisplay(m_cursorGrab);
+ return system_->getCursorGrabUseSoftwareDisplay(m_cursorGrab);
}
GHOST_TSuccess GHOST_WindowWayland::setWindowCustomCursorShape(
uint8_t *bitmap, uint8_t *mask, int sizex, int sizey, int hotX, int hotY, bool canInvertColor)
{
- return m_system->setCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, canInvertColor);
+ return system_->setCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, canInvertColor);
}
GHOST_TSuccess GHOST_WindowWayland::getCursorBitmap(GHOST_CursorBitmapRef *bitmap)
{
- return m_system->getCursorBitmap(bitmap);
+ return system_->getCursorBitmap(bitmap);
}
void GHOST_WindowWayland::setTitle(const char *title)
{
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- libdecor_frame_set_app_id(w->decor_frame, title);
- libdecor_frame_set_title(w->decor_frame, title);
-#else
- xdg_toplevel_set_title(w->xdg_toplevel, title);
- xdg_toplevel_set_app_id(w->xdg_toplevel, title);
+ if (use_libdecor) {
+ WGL_LibDecor_Window &decor = *window_->libdecor;
+ libdecor_frame_set_title(decor.frame, title);
+ }
+ else
#endif
+ {
+ WGL_XDG_Decor_Window &decor = *window_->xdg_decor;
+ xdg_toplevel_set_title(decor.toplevel, title);
+ }
- this->title = title;
+ title_ = title;
}
std::string GHOST_WindowWayland::getTitle() const
{
- return this->title.empty() ? "untitled" : this->title;
+ return title_.empty() ? "untitled" : title_;
}
void GHOST_WindowWayland::getWindowBounds(GHOST_Rect &bounds) const
@@ -618,29 +668,29 @@ void GHOST_WindowWayland::getWindowBounds(GHOST_Rect &bounds) const
void GHOST_WindowWayland::getClientBounds(GHOST_Rect &bounds) const
{
- bounds.set(0, 0, UNPACK2(w->size));
+ bounds.set(0, 0, UNPACK2(window_->size));
}
GHOST_TSuccess GHOST_WindowWayland::setClientWidth(const uint32_t width)
{
- return setClientSize(width, uint32_t(w->size[1]));
+ return setClientSize(width, uint32_t(window_->size[1]));
}
GHOST_TSuccess GHOST_WindowWayland::setClientHeight(const uint32_t height)
{
- return setClientSize(uint32_t(w->size[0]), height);
+ return setClientSize(uint32_t(window_->size[0]), height);
}
GHOST_TSuccess GHOST_WindowWayland::setClientSize(const uint32_t width, const uint32_t height)
{
- wl_egl_window_resize(w->egl_window, int(width), int(height), 0, 0);
+ wl_egl_window_resize(window_->egl_window, int(width), int(height), 0, 0);
/* Override any pending size that may be set. */
- w->size_pending[0] = 0;
- w->size_pending[1] = 0;
+ window_->size_pending[0] = 0;
+ window_->size_pending[1] = 0;
- w->size[0] = width;
- w->size[1] = height;
+ window_->size[0] = width;
+ window_->size[1] = height;
notify_size();
@@ -669,40 +719,42 @@ GHOST_WindowWayland::~GHOST_WindowWayland()
{
releaseNativeHandles();
- wl_egl_window_destroy(w->egl_window);
+ wl_egl_window_destroy(window_->egl_window);
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- libdecor_frame_unref(w->decor_frame);
-#else
- if (w->xdg_toplevel_decoration) {
- zxdg_toplevel_decoration_v1_destroy(w->xdg_toplevel_decoration);
+ if (use_libdecor) {
+ gwl_libdecor_window_destroy(window_->libdecor);
}
- xdg_toplevel_destroy(w->xdg_toplevel);
- xdg_surface_destroy(w->xdg_surface);
+ else
#endif
+ {
+ gwl_xdg_decor_window_destroy(window_->xdg_decor);
+ }
/* Clear any pointers to this window. This is needed because there are no guarantees
* that flushing the display will the "leave" handlers before handling events. */
- m_system->window_surface_unref(w->wl_surface);
+ system_->window_surface_unref(window_->wl_surface);
- wl_surface_destroy(w->wl_surface);
+ wl_surface_destroy(window_->wl_surface);
/* NOTE(@campbellbarton): Flushing will often run the appropriate handlers event
* (#wl_surface_listener.leave in particular) to avoid attempted access to the freed surfaces.
* This is not fool-proof though, hence the call to #window_surface_unref, see: T99078. */
- wl_display_flush(m_system->display());
+ wl_display_flush(system_->wl_display());
- delete w;
+ delete window_;
}
uint16_t GHOST_WindowWayland::getDPIHint()
{
- return w->dpi;
+ /* Using the physical DPI will cause wrong scaling of the UI
+ * use a multiplier for the default DPI as a workaround. */
+ return wl_fixed_to_int(window_->scale_fractional * base_dpi);
}
GHOST_TSuccess GHOST_WindowWayland::setWindowCursorVisibility(bool visible)
{
- return m_system->setCursorVisibility(visible);
+ return system_->setCursorVisibility(visible);
}
GHOST_TSuccess GHOST_WindowWayland::setState(GHOST_TWindowState state)
@@ -711,57 +763,84 @@ GHOST_TSuccess GHOST_WindowWayland::setState(GHOST_TWindowState state)
case GHOST_kWindowStateNormal:
/* Unset states. */
switch (getState()) {
- case GHOST_kWindowStateMaximized:
+ case GHOST_kWindowStateMaximized: {
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- libdecor_frame_unset_maximized(w->decor_frame);
-#else
- xdg_toplevel_unset_maximized(w->xdg_toplevel);
+ if (use_libdecor) {
+ libdecor_frame_unset_maximized(window_->libdecor->frame);
+ }
+ else
#endif
+ {
+ xdg_toplevel_unset_maximized(window_->xdg_decor->toplevel);
+ }
break;
- case GHOST_kWindowStateFullScreen:
+ }
+ case GHOST_kWindowStateFullScreen: {
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- libdecor_frame_unset_fullscreen(w->decor_frame);
-#else
- xdg_toplevel_unset_fullscreen(w->xdg_toplevel);
+ if (use_libdecor) {
+ libdecor_frame_unset_fullscreen(window_->libdecor->frame);
+ }
+ else
#endif
+ {
+ xdg_toplevel_unset_fullscreen(window_->xdg_decor->toplevel);
+ }
break;
- default:
+ }
+ default: {
break;
+ }
}
break;
- case GHOST_kWindowStateMaximized:
+ case GHOST_kWindowStateMaximized: {
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- libdecor_frame_set_maximized(w->decor_frame);
-#else
- xdg_toplevel_set_maximized(w->xdg_toplevel);
+ if (use_libdecor) {
+ libdecor_frame_set_maximized(window_->libdecor->frame);
+ }
+ else
#endif
+ {
+ xdg_toplevel_set_maximized(window_->xdg_decor->toplevel);
+ }
break;
- case GHOST_kWindowStateMinimized:
+ }
+ case GHOST_kWindowStateMinimized: {
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- libdecor_frame_set_minimized(w->decor_frame);
-#else
- xdg_toplevel_set_minimized(w->xdg_toplevel);
+ if (use_libdecor) {
+ libdecor_frame_set_minimized(window_->libdecor->frame);
+ }
+ else
#endif
+ {
+ xdg_toplevel_set_minimized(window_->xdg_decor->toplevel);
+ }
break;
- case GHOST_kWindowStateFullScreen:
+ }
+ case GHOST_kWindowStateFullScreen: {
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- libdecor_frame_set_fullscreen(w->decor_frame, nullptr);
-#else
- xdg_toplevel_set_fullscreen(w->xdg_toplevel, nullptr);
+ if (use_libdecor) {
+ libdecor_frame_set_fullscreen(window_->libdecor->frame, nullptr);
+ }
+ else
#endif
+ {
+ xdg_toplevel_set_fullscreen(window_->xdg_decor->toplevel, nullptr);
+ }
break;
- case GHOST_kWindowStateEmbedded:
+ }
+ case GHOST_kWindowStateEmbedded: {
return GHOST_kFailure;
+ }
}
return GHOST_kSuccess;
}
GHOST_TWindowState GHOST_WindowWayland::getState() const
{
- if (w->is_fullscreen) {
+ if (window_->is_fullscreen) {
return GHOST_kWindowStateFullScreen;
}
- if (w->is_maximised) {
+ if (window_->is_maximised) {
return GHOST_kWindowStateMaximized;
}
return GHOST_kWindowStateNormal;
@@ -780,26 +859,35 @@ GHOST_TSuccess GHOST_WindowWayland::setOrder(GHOST_TWindowOrder /*order*/)
GHOST_TSuccess GHOST_WindowWayland::beginFullScreen() const
{
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- libdecor_frame_set_fullscreen(w->decor_frame, nullptr);
-#else
- xdg_toplevel_set_fullscreen(w->xdg_toplevel, nullptr);
+ if (use_libdecor) {
+ libdecor_frame_set_fullscreen(window_->libdecor->frame, nullptr);
+ }
+ else
#endif
+ {
+ xdg_toplevel_set_fullscreen(window_->xdg_decor->toplevel, nullptr);
+ }
+
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_WindowWayland::endFullScreen() const
{
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- libdecor_frame_unset_fullscreen(w->decor_frame);
-#else
- xdg_toplevel_unset_fullscreen(w->xdg_toplevel);
+ if (use_libdecor) {
+ libdecor_frame_unset_fullscreen(window_->libdecor->frame);
+ }
+ else
#endif
+ {
+ xdg_toplevel_unset_fullscreen(window_->xdg_decor->toplevel);
+ }
return GHOST_kSuccess;
}
bool GHOST_WindowWayland::isDialog() const
{
- return w->is_dialog;
+ return window_->is_dialog;
}
#ifdef GHOST_OPENGL_ALPHA
@@ -808,9 +896,9 @@ void GHOST_WindowWayland::setOpaque() const
struct wl_region *region;
/* Make the window opaque. */
- region = wl_compositor_create_region(m_system->compositor());
- wl_region_add(region, 0, 0, UNPACK2(w->size));
- wl_surface_set_opaque_region(w->surface, region);
+ region = wl_compositor_create_region(system_->compositor());
+ wl_region_add(region, 0, 0, UNPACK2(window_->size));
+ wl_surface_set_opaque_region(window_->surface, region);
wl_region_destroy(region);
}
#endif
@@ -828,10 +916,10 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
break;
case GHOST_kDrawingContextTypeOpenGL:
for (int minor = 6; minor >= 0; --minor) {
- context = new GHOST_ContextEGL(this->m_system,
+ context = new GHOST_ContextEGL(system_,
m_wantStereoVisual,
- EGLNativeWindowType(w->egl_window),
- EGLNativeDisplayType(m_system->display()),
+ EGLNativeWindowType(window_->egl_window),
+ EGLNativeDisplayType(system_->wl_display()),
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
4,
minor,
@@ -844,10 +932,10 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
}
delete context;
}
- context = new GHOST_ContextEGL(this->m_system,
+ context = new GHOST_ContextEGL(system_,
m_wantStereoVisual,
- EGLNativeWindowType(w->egl_window),
- EGLNativeDisplayType(m_system->display()),
+ EGLNativeWindowType(window_->egl_window),
+ EGLNativeDisplayType(system_->wl_display()),
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
3,
3,
@@ -856,7 +944,12 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
EGL_OPENGL_API);
}
- return (context->initializeDrawingContext() == GHOST_kSuccess) ? context : nullptr;
+ if (context->initializeDrawingContext()) {
+ return context;
+ }
+
+ delete context;
+ return nullptr;
}
/** \} */
@@ -867,24 +960,24 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
* Expose some members via methods.
* \{ */
-uint16_t GHOST_WindowWayland::dpi() const
+int GHOST_WindowWayland::scale() const
{
- return w->dpi;
+ return window_->scale;
}
-int GHOST_WindowWayland::scale() const
+wl_fixed_t GHOST_WindowWayland::scale_fractional() const
{
- return w->scale;
+ return window_->scale_fractional;
}
wl_surface *GHOST_WindowWayland::wl_surface() const
{
- return w->wl_surface;
+ return window_->wl_surface;
}
const std::vector<GWL_Output *> &GHOST_WindowWayland::outputs()
{
- return w->outputs;
+ return window_->outputs;
}
/** \} */
@@ -897,24 +990,24 @@ const std::vector<GWL_Output *> &GHOST_WindowWayland::outputs()
GHOST_TSuccess GHOST_WindowWayland::close()
{
- return m_system->pushEvent(
- new GHOST_Event(m_system->getMilliSeconds(), GHOST_kEventWindowClose, this));
+ return system_->pushEvent(
+ new GHOST_Event(system_->getMilliSeconds(), GHOST_kEventWindowClose, this));
}
GHOST_TSuccess GHOST_WindowWayland::activate()
{
- if (m_system->getWindowManager()->setActiveWindow(this) == GHOST_kFailure) {
+ if (system_->getWindowManager()->setActiveWindow(this) == GHOST_kFailure) {
return GHOST_kFailure;
}
- return m_system->pushEvent(
- new GHOST_Event(m_system->getMilliSeconds(), GHOST_kEventWindowActivate, this));
+ return system_->pushEvent(
+ new GHOST_Event(system_->getMilliSeconds(), GHOST_kEventWindowActivate, this));
}
GHOST_TSuccess GHOST_WindowWayland::deactivate()
{
- m_system->getWindowManager()->setWindowInactive(this);
- return m_system->pushEvent(
- new GHOST_Event(m_system->getMilliSeconds(), GHOST_kEventWindowDeactivate, this));
+ system_->getWindowManager()->setWindowInactive(this);
+ return system_->pushEvent(
+ new GHOST_Event(system_->getMilliSeconds(), GHOST_kEventWindowDeactivate, this));
}
GHOST_TSuccess GHOST_WindowWayland::notify_size()
@@ -923,8 +1016,8 @@ GHOST_TSuccess GHOST_WindowWayland::notify_size()
setOpaque();
#endif
- return m_system->pushEvent(
- new GHOST_Event(m_system->getMilliSeconds(), GHOST_kEventWindowSize, this));
+ return system_->pushEvent(
+ new GHOST_Event(system_->getMilliSeconds(), GHOST_kEventWindowSize, this));
}
/** \} */
@@ -940,31 +1033,39 @@ GHOST_TSuccess GHOST_WindowWayland::notify_size()
*/
bool GHOST_WindowWayland::outputs_changed_update_scale()
{
- uint32_t dpi_next;
- const int scale_next = outputs_max_scale_or_default(this->outputs(), 0, &dpi_next);
+ wl_fixed_t scale_fractional_next = 0;
+ const int scale_next = outputs_max_scale_or_default(outputs(), 0, &scale_fractional_next);
if (UNLIKELY(scale_next == 0)) {
return false;
}
- GWL_Window *win = this->w;
- const uint32_t dpi_curr = win->dpi;
- const int scale_curr = win->scale;
+ const wl_fixed_t scale_fractional_curr = window_->scale_fractional;
+ const int scale_curr = window_->scale;
bool changed = false;
if (scale_next != scale_curr) {
- /* Unlikely but possible there is a pending size change is set. */
- win->size_pending[0] = (win->size_pending[0] / scale_curr) * scale_next;
- win->size_pending[1] = (win->size_pending[1] / scale_curr) * scale_next;
+ window_->scale = scale_next;
+ wl_surface_set_buffer_scale(window_->wl_surface, scale_next);
+
+ /* It's important to resize the window immediately, to avoid the window changing size
+ * and flickering in a constant feedback loop (in some bases). */
+ if ((window_->size_pending[0] != 0) && (window_->size_pending[1] != 0)) {
+ /* Unlikely but possible there is a pending size change is set. */
+ window_->size[0] = window_->size_pending[0];
+ window_->size[1] = window_->size_pending[1];
+ window_->size_pending[0] = 0;
+ window_->size_pending[1] = 0;
+ }
+ window_->size[0] = (window_->size[0] / scale_curr) * scale_next;
+ window_->size[1] = (window_->size[1] / scale_curr) * scale_next;
+ wl_egl_window_resize(window_->egl_window, UNPACK2(window_->size), 0, 0);
+ window_->ghost_window->notify_size();
- win->scale = scale_next;
- wl_surface_set_buffer_scale(w->wl_surface, scale_next);
changed = true;
}
- if (dpi_next != dpi_curr) {
- /* Using the real DPI will cause wrong scaling of the UI
- * use a multiplier for the default DPI as workaround. */
- win->dpi = dpi_next;
+ if (scale_fractional_next != scale_fractional_curr) {
+ window_->scale_fractional = scale_fractional_next;
changed = true;
/* As this is a low-level function, we might want adding this event to be optional,
@@ -979,7 +1080,7 @@ bool GHOST_WindowWayland::outputs_changed_update_scale()
bool GHOST_WindowWayland::outputs_enter(GWL_Output *output)
{
- std::vector<GWL_Output *> &outputs = w->outputs;
+ std::vector<GWL_Output *> &outputs = window_->outputs;
auto it = std::find(outputs.begin(), outputs.end(), output);
if (it != outputs.end()) {
return false;
@@ -990,7 +1091,7 @@ bool GHOST_WindowWayland::outputs_enter(GWL_Output *output)
bool GHOST_WindowWayland::outputs_leave(GWL_Output *output)
{
- std::vector<GWL_Output *> &outputs = w->outputs;
+ std::vector<GWL_Output *> &outputs = window_->outputs;
auto it = std::find(outputs.begin(), outputs.end(), output);
if (it == outputs.end()) {
return false;
diff --git a/intern/ghost/intern/GHOST_WindowWayland.h b/intern/ghost/intern/GHOST_WindowWayland.h
index 9b4c17ecd95..ec473c4a710 100644
--- a/intern/ghost/intern/GHOST_WindowWayland.h
+++ b/intern/ghost/intern/GHOST_WindowWayland.h
@@ -12,6 +12,8 @@
#include <vector>
+#include <wayland-util.h> /* For #wl_fixed_t */
+
class GHOST_SystemWayland;
struct GWL_Output;
@@ -95,8 +97,8 @@ class GHOST_WindowWayland : public GHOST_Window {
/* WAYLAND direct-data access. */
- uint16_t dpi() const;
int scale() const;
+ wl_fixed_t scale_fractional() const;
struct wl_surface *wl_surface() const;
const std::vector<GWL_Output *> &outputs();
@@ -115,9 +117,9 @@ class GHOST_WindowWayland : public GHOST_Window {
bool outputs_changed_update_scale();
private:
- GHOST_SystemWayland *m_system;
- struct GWL_Window *w;
- std::string title;
+ GHOST_SystemWayland *system_;
+ struct GWL_Window *window_;
+ std::string title_;
/**
* \param type: The type of rendering context create.
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 50ee9385e39..e2d143ee5e6 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -89,7 +89,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
*/
}
- RECT win_rect = {left, top, (long)(left + width), (long)(top + height)};
+ RECT win_rect = {left, top, long(left + width), long(top + height)};
adjustWindowRectForClosestMonitor(&win_rect, style, extended_style);
wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0);
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 0b2617c1b9e..8d8ce3643f4 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -14,6 +14,7 @@
#include "GHOST_Debug.h"
#include "GHOST_IconX11.h"
#include "GHOST_SystemX11.h"
+#include "GHOST_Types.h"
#include "GHOST_WindowX11.h"
#include "GHOST_utildefines.h"
@@ -24,18 +25,18 @@
#include "GHOST_ContextEGL.h"
#include "GHOST_ContextGLX.h"
-/* for XIWarpPointer */
+/* For #XIWarpPointer. */
#ifdef WITH_X11_XINPUT
# include <X11/extensions/XInput2.h>
#endif
-// For DPI value
+/* For DPI value. */
#include <X11/Xresource.h>
#include <cstdio>
#include <cstring>
-/* gethostname */
+/* For `gethostname`. */
#include <unistd.h>
#include <algorithm>
@@ -140,7 +141,7 @@ GHOST_WindowX11::GHOST_WindowX11(GHOST_SystemX11 *system,
return;
}
- unsigned int xattributes_valuemask = 0;
+ uint xattributes_valuemask = 0;
XSetWindowAttributes xattributes;
memset(&xattributes, 0, sizeof(xattributes));
@@ -202,7 +203,7 @@ GHOST_WindowX11::GHOST_WindowX11(GHOST_SystemX11 *system,
XA_ATOM,
32,
PropModeReplace,
- (unsigned char *)atoms,
+ (uchar *)atoms,
count);
m_post_init = False;
}
@@ -217,7 +218,7 @@ GHOST_WindowX11::GHOST_WindowX11(GHOST_SystemX11 *system,
* So, m_post_init indicate that we need wait for the MapNotify
* event and then set the Window state to the m_post_state.
*/
- else if ((state != GHOST_kWindowStateNormal) && (state != GHOST_kWindowStateMinimized)) {
+ else if (!ELEM(state, GHOST_kWindowStateNormal, GHOST_kWindowStateMinimized)) {
m_post_init = True;
m_post_state = state;
}
@@ -300,7 +301,7 @@ GHOST_WindowX11::GHOST_WindowX11(GHOST_SystemX11 *system,
XA_CARDINAL,
32,
PropModeReplace,
- (unsigned char *)BLENDER_ICONS_WM_X11,
+ (uchar *)BLENDER_ICONS_WM_X11,
ARRAY_SIZE(BLENDER_ICONS_WM_X11));
}
@@ -308,14 +309,8 @@ GHOST_WindowX11::GHOST_WindowX11(GHOST_SystemX11 *system,
{
Atom _NET_WM_PID = XInternAtom(m_display, "_NET_WM_PID", False);
pid_t pid = getpid();
- XChangeProperty(m_display,
- m_window,
- _NET_WM_PID,
- XA_CARDINAL,
- 32,
- PropModeReplace,
- (unsigned char *)&pid,
- 1);
+ XChangeProperty(
+ m_display, m_window, _NET_WM_PID, XA_CARDINAL, 32, PropModeReplace, (uchar *)&pid, 1);
}
/* set the hostname (WM_CLIENT_MACHINE) */
@@ -399,7 +394,7 @@ bool GHOST_WindowX11::createX11_XIC()
if (!m_xic)
return false;
- unsigned long fevent;
+ ulong fevent;
XGetICValues(m_xic, XNFilterEvents, &fevent, nullptr);
XSelectInput(m_display,
m_window,
@@ -442,7 +437,7 @@ void GHOST_WindowX11::refreshXInputDevices()
}
}
- XSelectExtensionEvent(m_display, m_window, xevents.data(), (int)xevents.size());
+ XSelectExtensionEvent(m_display, m_window, xevents.data(), int(xevents.size()));
}
}
@@ -462,14 +457,8 @@ void GHOST_WindowX11::setTitle(const char *title)
{
Atom name = XInternAtom(m_display, "_NET_WM_NAME", 0);
Atom utf8str = XInternAtom(m_display, "UTF8_STRING", 0);
- XChangeProperty(m_display,
- m_window,
- name,
- utf8str,
- 8,
- PropModeReplace,
- (const unsigned char *)title,
- strlen(title));
+ XChangeProperty(
+ m_display, m_window, name, utf8str, 8, PropModeReplace, (const uchar *)title, strlen(title));
/* This should convert to valid x11 string
* and getTitle would need matching change */
@@ -499,7 +488,7 @@ void GHOST_WindowX11::getClientBounds(GHOST_Rect &bounds) const
{
Window root_return;
int x_return, y_return;
- unsigned int w_return, h_return, border_w_return, depth_return;
+ uint w_return, h_return, border_w_return, depth_return;
int32_t screen_x, screen_y;
XGetGeometry(m_display,
@@ -523,7 +512,7 @@ void GHOST_WindowX11::getClientBounds(GHOST_Rect &bounds) const
GHOST_TSuccess GHOST_WindowX11::setClientWidth(uint32_t width)
{
XWindowChanges values;
- unsigned int value_mask = CWWidth;
+ uint value_mask = CWWidth;
values.width = width;
XConfigureWindow(m_display, m_window, value_mask, &values);
@@ -533,7 +522,7 @@ GHOST_TSuccess GHOST_WindowX11::setClientWidth(uint32_t width)
GHOST_TSuccess GHOST_WindowX11::setClientHeight(uint32_t height)
{
XWindowChanges values;
- unsigned int value_mask = CWHeight;
+ uint value_mask = CWHeight;
values.height = height;
XConfigureWindow(m_display, m_window, value_mask, &values);
return GHOST_kSuccess;
@@ -542,7 +531,7 @@ GHOST_TSuccess GHOST_WindowX11::setClientHeight(uint32_t height)
GHOST_TSuccess GHOST_WindowX11::setClientSize(uint32_t width, uint32_t height)
{
XWindowChanges values;
- unsigned int value_mask = CWWidth | CWHeight;
+ uint value_mask = CWWidth | CWHeight;
values.width = width;
values.height = height;
XConfigureWindow(m_display, m_window, value_mask, &values);
@@ -586,7 +575,7 @@ GHOST_TSuccess GHOST_WindowX11::setDialogHints(GHOST_WindowX11 *parentWindow)
XA_ATOM,
32,
PropModeReplace,
- (unsigned char *)&atom_dialog,
+ (uchar *)&atom_dialog,
1);
XSetTransientForHint(m_display, m_window, parentWindow->m_window);
@@ -603,7 +592,7 @@ GHOST_TSuccess GHOST_WindowX11::setDialogHints(GHOST_WindowX11 *parentWindow)
m_system->m_atom._MOTIF_WM_HINTS,
32,
PropModeReplace,
- (unsigned char *)&hints,
+ (uchar *)&hints,
4);
return GHOST_kSuccess;
@@ -638,7 +627,7 @@ int GHOST_WindowX11::icccmGetState() const
CARD32 state;
XID icon;
} * prop_ret;
- unsigned long bytes_after, num_ret;
+ ulong bytes_after, num_ret;
Atom type_ret;
int ret, format_ret;
CARD32 st;
@@ -655,7 +644,7 @@ int GHOST_WindowX11::icccmGetState() const
&format_ret,
&num_ret,
&bytes_after,
- ((unsigned char **)&prop_ret));
+ ((uchar **)&prop_ret));
if ((ret == Success) && (prop_ret != nullptr) && (num_ret == 2)) {
st = prop_ret->state;
}
@@ -702,7 +691,7 @@ void GHOST_WindowX11::netwmMaximized(bool set)
bool GHOST_WindowX11::netwmIsMaximized() const
{
Atom *prop_ret;
- unsigned long bytes_after, num_ret, i;
+ ulong bytes_after, num_ret, i;
Atom type_ret;
bool st;
int format_ret, ret, count;
@@ -720,7 +709,7 @@ bool GHOST_WindowX11::netwmIsMaximized() const
&format_ret,
&num_ret,
&bytes_after,
- (unsigned char **)&prop_ret);
+ (uchar **)&prop_ret);
if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
count = 0;
for (i = 0; i < num_ret; i++) {
@@ -775,7 +764,7 @@ void GHOST_WindowX11::netwmFullScreen(bool set)
bool GHOST_WindowX11::netwmIsFullScreen() const
{
Atom *prop_ret;
- unsigned long bytes_after, num_ret, i;
+ ulong bytes_after, num_ret, i;
Atom type_ret;
bool st;
int format_ret, ret;
@@ -793,7 +782,7 @@ bool GHOST_WindowX11::netwmIsFullScreen() const
&format_ret,
&num_ret,
&bytes_after,
- (unsigned char **)&prop_ret);
+ (uchar **)&prop_ret);
if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
for (i = 0; i < num_ret; i++) {
if (prop_ret[i] == m_system->m_atom._NET_WM_STATE_FULLSCREEN) {
@@ -827,14 +816,14 @@ void GHOST_WindowX11::motifFullScreen(bool set)
m_system->m_atom._MOTIF_WM_HINTS,
32,
PropModeReplace,
- (unsigned char *)&hints,
+ (uchar *)&hints,
4);
}
bool GHOST_WindowX11::motifIsFullScreen() const
{
MotifWmHints *prop_ret;
- unsigned long bytes_after, num_ret;
+ ulong bytes_after, num_ret;
Atom type_ret;
bool state;
int format_ret, st;
@@ -852,7 +841,7 @@ bool GHOST_WindowX11::motifIsFullScreen() const
&format_ret,
&num_ret,
&bytes_after,
- (unsigned char **)&prop_ret);
+ (uchar **)&prop_ret);
if ((st == Success) && prop_ret) {
if (prop_ret->flags & MWM_HINTS_DECORATIONS) {
if (!prop_ret->decorations) {
@@ -899,7 +888,7 @@ GHOST_TSuccess GHOST_WindowX11::setState(GHOST_TWindowState state)
bool is_max, is_full, is_motif_full;
cur_state = getState();
- if (state == (int)cur_state) {
+ if (state == int(cur_state)) {
return GHOST_kSuccess;
}
@@ -1055,7 +1044,7 @@ bool GHOST_WindowX11::isDialog() const
Atom atom_dialog = XInternAtom(m_display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
Atom *prop_ret;
- unsigned long bytes_after, num_ret;
+ ulong bytes_after, num_ret;
Atom type_ret;
bool st;
int format_ret, ret;
@@ -1073,7 +1062,7 @@ bool GHOST_WindowX11::isDialog() const
&format_ret,
&num_ret,
&bytes_after,
- (unsigned char **)&prop_ret);
+ (uchar **)&prop_ret);
if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
if (prop_ret[0] == atom_dialog) {
st = True;
@@ -1127,7 +1116,7 @@ void GHOST_WindowX11::validate()
GHOST_WindowX11::~GHOST_WindowX11()
{
- std::map<unsigned int, Cursor>::iterator it = m_standard_cursors.begin();
+ std::map<uint, Cursor>::iterator it = m_standard_cursors.begin();
for (; it != m_standard_cursors.end(); ++it) {
XFreeCursor(m_display, it->second);
}
@@ -1308,7 +1297,7 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
GHOST_TSuccess GHOST_WindowX11::getStandardCursor(GHOST_TStandardCursor g_cursor, Cursor &xcursor)
{
- unsigned int xcursor_id;
+ uint xcursor_id;
switch (g_cursor) {
case GHOST_kStandardCursorHelp:
@@ -1546,7 +1535,7 @@ GHOST_TSuccess GHOST_WindowX11::beginFullScreen() const
{
Window root_return;
int x_return, y_return;
- unsigned int w_return, h_return, border_w_return, depth_return;
+ uint w_return, h_return, border_w_return, depth_return;
XGetGeometry(m_display,
m_window,
@@ -1605,7 +1594,7 @@ uint16_t GHOST_WindowX11::getDPIHint()
int success = XrmGetResource(xrdb, "Xft.dpi", "Xft.Dpi", &type, &val);
if (success && type) {
- if (strcmp(type, "String") == 0) {
+ if (STREQ(type, "String")) {
return atoi((char *)val.addr);
}
}
diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h
index c7a6b5e7357..e9bee43c035 100644
--- a/intern/ghost/intern/GHOST_WindowX11.h
+++ b/intern/ghost/intern/GHOST_WindowX11.h
@@ -11,7 +11,7 @@
#include "GHOST_Window.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-// For tablets
+/* For tablets. */
#ifdef WITH_X11_XINPUT
# include <X11/extensions/XInput.h>
#endif
@@ -234,7 +234,7 @@ class GHOST_WindowX11 : public GHOST_Window {
Cursor m_visible_cursor;
/** Cache of XC_* ID's to XCursor structures */
- std::map<unsigned int, Cursor> m_standard_cursors;
+ std::map<uint, Cursor> m_standard_cursors;
GHOST_TaskBarX11 m_taskbar;
diff --git a/intern/ghost/intern/GHOST_Wintab.cpp b/intern/ghost/intern/GHOST_Wintab.cpp
index c75a39bb34b..f7075efcbdd 100644
--- a/intern/ghost/intern/GHOST_Wintab.cpp
+++ b/intern/ghost/intern/GHOST_Wintab.cpp
@@ -331,7 +331,7 @@ void GHOST_Wintab::getInput(std::vector<GHOST_WintabInfoWin32> &outWintabInfo)
out.y = pkt.pkY;
if (m_maxPressure > 0) {
- out.tabletData.Pressure = (float)pkt.pkNormalPressure / (float)m_maxPressure;
+ out.tabletData.Pressure = float(pkt.pkNormalPressure) / float(m_maxPressure);
}
if ((m_maxAzimuth > 0) && (m_maxAltitude > 0)) {
@@ -342,7 +342,7 @@ void GHOST_Wintab::getInput(std::vector<GHOST_WintabInfoWin32> &outWintabInfo)
* Positive values specify an angle upward toward the positive z axis; negative values
* specify an angle downward toward the negative z axis.
*
- * wintab.h defines orAltitude as a UINT but documents orAltitude as positive for upward
+ * wintab.h defines orAltitude as a `uint` but documents orAltitude as positive for upward
* angles and negative for downward angles. WACOM uses negative altitude values to show that
* the pen is inverted; therefore we cast orAltitude as an (int) and then use the absolute
* value.
@@ -351,15 +351,15 @@ void GHOST_Wintab::getInput(std::vector<GHOST_WintabInfoWin32> &outWintabInfo)
ORIENTATION ort = pkt.pkOrientation;
/* Convert raw fixed point data to radians. */
- float altRad = (float)((fabs((float)ort.orAltitude) / (float)m_maxAltitude) * M_PI_2);
- float azmRad = (float)(((float)ort.orAzimuth / (float)m_maxAzimuth) * M_PI * 2.0);
+ float altRad = float((fabs(float(ort.orAltitude)) / float(m_maxAltitude)) * M_PI_2);
+ float azmRad = float((float(ort.orAzimuth) / float(m_maxAzimuth)) * M_PI * 2.0);
/* Find length of the stylus' projected vector on the XY plane. */
float vecLen = cos(altRad);
/* From there calculate X and Y components based on azimuth. */
out.tabletData.Xtilt = sin(azmRad) * vecLen;
- out.tabletData.Ytilt = (float)(sin(M_PI_2 - azmRad) * vecLen);
+ out.tabletData.Ytilt = float(sin(M_PI_2 - azmRad) * vecLen);
}
out.time = pkt.pkTime;
@@ -397,7 +397,7 @@ void GHOST_Wintab::getInput(std::vector<GHOST_WintabInfoWin32> &outWintabInfo)
}
}
-GHOST_TButton GHOST_Wintab::mapWintabToGhostButton(UINT cursor, WORD physicalButton)
+GHOST_TButton GHOST_Wintab::mapWintabToGhostButton(uint cursor, WORD physicalButton)
{
const WORD numButtons = 32;
BYTE logicalButtons[numButtons] = {0};
@@ -502,7 +502,7 @@ void GHOST_Wintab::printContextDebugInfo()
BYTE systemButtons[32] = {0};
for (int i = 0; i < 3; i++) {
printf("initializeWintab cursor %d buttons\n", i);
- UINT lbut = m_fpInfo(WTI_CURSORS + i, CSR_BUTTONMAP, &logicalButtons);
+ uint lbut = m_fpInfo(WTI_CURSORS + i, CSR_BUTTONMAP, &logicalButtons);
if (lbut) {
printf("%d", logicalButtons[0]);
for (int j = 1; j < lbut; j++) {
@@ -513,7 +513,7 @@ void GHOST_Wintab::printContextDebugInfo()
else {
printf("logical button error\n");
}
- UINT sbut = m_fpInfo(WTI_CURSORS + i, CSR_SYSBTNMAP, &systemButtons);
+ uint sbut = m_fpInfo(WTI_CURSORS + i, CSR_SYSBTNMAP, &systemButtons);
if (sbut) {
printf("%d", systemButtons[0]);
for (int j = 1; j < sbut; j++) {
@@ -529,7 +529,7 @@ void GHOST_Wintab::printContextDebugInfo()
/* Print context information. */
/* Print open context constraints. */
- UINT maxcontexts, opencontexts;
+ uint maxcontexts, opencontexts;
m_fpInfo(WTI_INTERFACE, IFC_NCONTEXTS, &maxcontexts);
m_fpInfo(WTI_STATUS, STA_CONTEXTS, &opencontexts);
printf("%u max contexts, %u open contexts\n", maxcontexts, opencontexts);
@@ -582,7 +582,7 @@ void GHOST_Wintab::printContextDebugInfo()
printf("WTI_DEFSYSCTX CTX_*\n");
printContextRanges(lc);
- for (unsigned int i = 0; i < m_numDevices; i++) {
+ for (uint i = 0; i < m_numDevices; i++) {
/* Print individual device system context. */
m_fpInfo(WTI_DSCTXS + i, 0, &lc);
printf("WTI_DSCTXS %u\n", i);
diff --git a/intern/ghost/intern/GHOST_XrAction.cpp b/intern/ghost/intern/GHOST_XrAction.cpp
index 0e725bf4075..9fbe033ade9 100644
--- a/intern/ghost/intern/GHOST_XrAction.cpp
+++ b/intern/ghost/intern/GHOST_XrAction.cpp
@@ -528,7 +528,7 @@ void *GHOST_XrActionSet::getCustomdata()
uint32_t GHOST_XrActionSet::getActionCount() const
{
- return (uint32_t)m_actions.size();
+ return uint32_t(m_actions.size());
}
void GHOST_XrActionSet::getActionCustomdataArray(void **r_customdata_array)
diff --git a/intern/ghost/intern/GHOST_XrControllerModel.cpp b/intern/ghost/intern/GHOST_XrControllerModel.cpp
index 5be3a8e70ad..0a8b0dcb003 100644
--- a/intern/ghost/intern/GHOST_XrControllerModel.cpp
+++ b/intern/ghost/intern/GHOST_XrControllerModel.cpp
@@ -230,10 +230,10 @@ static void calc_node_transforms(const tinygltf::Node &gltf_node,
* both. */
if (gltf_node.matrix.size() == 16) {
const std::vector<double> &dm = gltf_node.matrix;
- float m[4][4] = {{(float)dm[0], (float)dm[1], (float)dm[2], (float)dm[3]},
- {(float)dm[4], (float)dm[5], (float)dm[6], (float)dm[7]},
- {(float)dm[8], (float)dm[9], (float)dm[10], (float)dm[11]},
- {(float)dm[12], (float)dm[13], (float)dm[14], (float)dm[15]}};
+ float m[4][4] = {{float(dm[0]), float(dm[1]), float(dm[2]), float(dm[3])},
+ {float(dm[4]), float(dm[5]), float(dm[6]), float(dm[7])},
+ {float(dm[8]), float(dm[9]), float(dm[10]), float(dm[11])},
+ {float(dm[12]), float(dm[13]), float(dm[14]), float(dm[15])}};
memcpy(r_local_transform, m, sizeof(float[4][4]));
}
else {
@@ -259,21 +259,21 @@ static void calc_node_transforms(const tinygltf::Node &gltf_node,
scale[0] = scale[1] = scale[2] = 1.0;
}
- q.w() = (float)rotation[3];
- q.x() = (float)rotation[0];
- q.y() = (float)rotation[1];
- q.z() = (float)rotation[2];
+ q.w() = float(rotation[3]);
+ q.x() = float(rotation[0]);
+ q.y() = float(rotation[1]);
+ q.z() = float(rotation[2]);
q.normalize();
scalemat.setIdentity();
- scalemat(0, 0) = (float)scale[0];
- scalemat(1, 1) = (float)scale[1];
- scalemat(2, 2) = (float)scale[2];
+ scalemat(0, 0) = float(scale[0]);
+ scalemat(1, 1) = float(scale[1]);
+ scalemat(2, 2) = float(scale[2]);
m.setIdentity();
m.block<3, 3>(0, 0) = q.toRotationMatrix() * scalemat;
m.block<3, 1>(0, 3) = Eigen::Vector3f(
- (float)translation[0], (float)translation[1], (float)translation[2]);
+ float(translation[0]), float(translation[1]), float(translation[2]));
}
*(Eigen::Matrix4f *)r_world_transform = *(Eigen::Matrix4f *)parent_transform *
@@ -296,7 +296,7 @@ static void load_node(const tinygltf::Model &gltf_model,
float world_transform[4][4];
GHOST_XrControllerModelNode &node = nodes.emplace_back();
- const int32_t node_idx = (int32_t)(nodes.size() - 1);
+ const int32_t node_idx = int32_t(nodes.size() - 1);
node.parent_idx = parent_idx;
calc_node_transforms(gltf_node, parent_transform, node.local_transform, world_transform);
@@ -450,7 +450,7 @@ void GHOST_XrControllerModel::loadControllerModel(XrSession session)
CHECK_XR(g_xrLoadControllerModelMSFT(session, m_model_key, 0, &buf_size, nullptr),
"Failed to get controller model buffer size.");
- std::vector<uint8_t> buf((size_t)buf_size);
+ std::vector<uint8_t> buf((size_t(buf_size)));
CHECK_XR(g_xrLoadControllerModelMSFT(session, m_model_key, buf_size, &buf_size, buf.data()),
"Failed to load controller model binary buffers.");
@@ -467,7 +467,7 @@ void GHOST_XrControllerModel::loadControllerModel(XrSession session)
std::string *p2,
int p3,
int p4,
- const unsigned char *p5,
+ const uchar *p5,
int p6,
void *user_pointer) -> bool {
(void)img;
@@ -496,7 +496,7 @@ void GHOST_XrControllerModel::loadControllerModel(XrSession session)
std::vector<XrControllerModelNodePropertiesMSFT> node_properties(
model_properties.nodeCountOutput, {XR_TYPE_CONTROLLER_MODEL_NODE_PROPERTIES_MSFT});
- model_properties.nodeCapacityInput = (uint32_t)node_properties.size();
+ model_properties.nodeCapacityInput = uint32_t(node_properties.size());
model_properties.nodeProperties = node_properties.data();
CHECK_XR(g_xrGetControllerModelPropertiesMSFT(session, m_model_key, &model_properties),
"Failed to get controller model node properties.");
@@ -583,11 +583,11 @@ void GHOST_XrControllerModel::updateComponents(XrSession session)
void GHOST_XrControllerModel::getData(GHOST_XrControllerModelData &r_data)
{
if (m_data_loaded) {
- r_data.count_vertices = (uint32_t)m_vertices.size();
+ r_data.count_vertices = uint32_t(m_vertices.size());
r_data.vertices = m_vertices.data();
- r_data.count_indices = (uint32_t)m_indices.size();
+ r_data.count_indices = uint32_t(m_indices.size());
r_data.indices = m_indices.data();
- r_data.count_components = (uint32_t)m_components.size();
+ r_data.count_components = uint32_t(m_components.size());
r_data.components = m_components.data();
}
else {
diff --git a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
index 6a7eb25925a..d387b222538 100644
--- a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
+++ b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
@@ -85,7 +85,7 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
XrGraphicsRequirementsOpenGLKHR gpu_requirements = {XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR};
const XrVersion gl_version = XR_MAKE_VERSION(gl_major_version, gl_minor_version, 0);
- /* Although it would seem reasonable that the proc address would not change if the instance was
+ /* Although it would seem reasonable that the PROC address would not change if the instance was
* the same, in testing, repeated calls to #xrGetInstanceProcAddress() with the same instance
* can still result in changes so the workaround is to simply set the function pointer every
* time (trivializing its 'static' designation). */
@@ -343,7 +343,7 @@ class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding {
// static XrInstance s_instance = XR_NULL_HANDLE;
XrGraphicsRequirementsD3D11KHR gpu_requirements = {XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR};
- /* Although it would seem reasonable that the proc address would not change if the instance was
+ /* Although it would seem reasonable that the PROC address would not change if the instance was
* the same, in testing, repeated calls to #xrGetInstanceProcAddress() with the same instance
* can still result in changes so the workaround is to simply set the function pointer every
* time (trivializing its 'static' designation). */
diff --git a/intern/ghost/intern/GHOST_XrSession.cpp b/intern/ghost/intern/GHOST_XrSession.cpp
index 1966a4e77da..e8f9b96b15c 100644
--- a/intern/ghost/intern/GHOST_XrSession.cpp
+++ b/intern/ghost/intern/GHOST_XrSession.cpp
@@ -484,7 +484,7 @@ void GHOST_XrSession::drawView(GHOST_XrSwapchain &swapchain,
swapchain.updateCompositionLayerProjectViewSubImage(r_proj_layer_view.subImage);
assert(view_idx < 256);
- draw_view_info.view_idx = (char)view_idx;
+ draw_view_info.view_idx = char(view_idx);
draw_view_info.swapchain_format = swapchain.getFormat();
draw_view_info.expects_srgb_buffer = swapchain.isBufferSRGB();
draw_view_info.ofsx = r_proj_layer_view.subImage.imageRect.offset.x;
@@ -745,7 +745,7 @@ bool GHOST_XrSession::attachActionSets()
for (auto &[profile, bindings] : profile_bindings) {
bindings_info.interactionProfile = profile;
- bindings_info.countSuggestedBindings = (uint32_t)bindings.size();
+ bindings_info.countSuggestedBindings = uint32_t(bindings.size());
bindings_info.suggestedBindings = bindings.data();
CHECK_XR(xrSuggestInteractionProfileBindings(instance, &bindings_info),
@@ -754,7 +754,7 @@ bool GHOST_XrSession::attachActionSets()
/* Attach action sets. */
XrSessionActionSetsAttachInfo attach_info{XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO};
- attach_info.countActionSets = (uint32_t)m_oxr->action_sets.size();
+ attach_info.countActionSets = uint32_t(m_oxr->action_sets.size());
/* Create an aligned copy of the action sets to pass to xrAttachSessionActionSets(). */
std::vector<XrActionSet> action_sets(attach_info.countActionSets);
@@ -776,7 +776,7 @@ bool GHOST_XrSession::syncActions(const char *action_set_name)
XrActionsSyncInfo sync_info{XR_TYPE_ACTIONS_SYNC_INFO};
sync_info.countActiveActionSets = (action_set_name != nullptr) ? 1 :
- (uint32_t)action_sets.size();
+ uint32_t(action_sets.size());
if (sync_info.countActiveActionSets < 1) {
return false;
}
diff --git a/intern/ghost/intern/GHOST_utildefines.h b/intern/ghost/intern/GHOST_utildefines.h
index f0ae6e12d3e..ff092099c7c 100644
--- a/intern/ghost/intern/GHOST_utildefines.h
+++ b/intern/ghost/intern/GHOST_utildefines.h
@@ -208,3 +208,32 @@
(void)0
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name String Macros
+ * \{ */
+
+/* Macro to convert a value to string in the preprocessor:
+ * - `STRINGIFY_ARG`: gives the argument as a string
+ * - `STRINGIFY_APPEND`: appends any argument 'b' onto the string argument 'a',
+ * used by `STRINGIFY` because some preprocessors warn about zero arguments.
+ * - `STRINGIFY`: gives the argument's value as a string. */
+
+#define STRINGIFY_ARG(x) "" #x
+#define STRINGIFY_APPEND(a, b) "" a #b
+#define STRINGIFY(x) STRINGIFY_APPEND("", x)
+
+/* generic strcmp macros */
+#if defined(_MSC_VER)
+# define strcasecmp _stricmp
+# define strncasecmp _strnicmp
+#endif
+
+#define STREQ(a, b) (strcmp(a, b) == 0)
+#define STRCASEEQ(a, b) (strcasecmp(a, b) == 0)
+#define STREQLEN(a, b, n) (strncmp(a, b, n) == 0)
+#define STRCASEEQLEN(a, b, n) (strncasecmp(a, b, n) == 0)
+
+#define STRPREFIX(a, b) (strncmp((a), (b), strlen(b)) == 0)
+
+/** \} */
diff --git a/intern/ghost/test/gears/GHOST_C-Test.c b/intern/ghost/test/gears/GHOST_C-Test.c
index 46c8fda0665..1ecc4b481d3 100644
--- a/intern/ghost/test/gears/GHOST_C-Test.c
+++ b/intern/ghost/test/gears/GHOST_C-Test.c
@@ -315,7 +315,7 @@ bool processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
} break;
case GHOST_kKeyF:
if (!GHOST_GetFullScreen(shSystem)) {
- /* Begin fullscreen mode */
+ /* Begin full-screen mode. */
setting.bpp = 24;
setting.frequency = 85;
setting.xPixels = 640;
diff --git a/intern/ghost/test/gears/GHOST_Test.cpp b/intern/ghost/test/gears/GHOST_Test.cpp
index f5ef2527d75..3c9206b2010 100644
--- a/intern/ghost/test/gears/GHOST_Test.cpp
+++ b/intern/ghost/test/gears/GHOST_Test.cpp
@@ -57,7 +57,7 @@ void StereoProjection(float left,
static void testTimerProc(GHOST_ITimerTask * /*task*/, uint64_t time)
{
- std::cout << "timer1, time=" << (int)time << "\n";
+ std::cout << "timer1, time=" << int(time) << "\n";
}
static void gearGL(
@@ -407,17 +407,12 @@ Application::Application(GHOST_ISystem *system)
stereo(false)
{
GHOST_GLSettings glSettings = {0};
+ glSettings.context_type = GHOST_kDrawingContextTypeOpenGL;
fApp = this;
// Create the main window
- m_mainWindow = system->createWindow("gears - main window",
- 10,
- 64,
- 320,
- 200,
- GHOST_kWindowStateNormal,
- GHOST_kDrawingContextTypeOpenGL,
- glSettings);
+ m_mainWindow = system->createWindow(
+ "gears - main window", 10, 64, 320, 200, GHOST_kWindowStateNormal, glSettings);
if (!m_mainWindow) {
std::cout << "could not create main window\n";
@@ -425,14 +420,8 @@ Application::Application(GHOST_ISystem *system)
}
// Create a secondary window
- m_secondaryWindow = system->createWindow("gears - secondary window",
- 340,
- 64,
- 320,
- 200,
- GHOST_kWindowStateNormal,
- GHOST_kDrawingContextTypeOpenGL,
- glSettings);
+ m_secondaryWindow = system->createWindow(
+ "gears - secondary window", 340, 64, 320, 200, GHOST_kWindowStateNormal, glSettings);
if (!m_secondaryWindow) {
std::cout << "could not create secondary window\n";
exit(-1);
diff --git a/intern/ghost/test/multitest/MultiTest.c b/intern/ghost/test/multitest/MultiTest.c
index 99b88dfb525..6a6a042f4ac 100644
--- a/intern/ghost/test/multitest/MultiTest.c
+++ b/intern/ghost/test/multitest/MultiTest.c
@@ -323,7 +323,7 @@ MainWindow *mainwindow_new(MultiTestApp *app)
if (win) {
MainWindow *mw = MEM_callocN(sizeof(*mw), "mainwindow_new");
- mw->gpu_context = GPU_context_create(win);
+ mw->gpu_context = GPU_context_create(win, NULL);
GPU_init();
mw->app = app;
@@ -578,7 +578,7 @@ LoggerWindow *loggerwindow_new(MultiTestApp *app)
if (win) {
LoggerWindow *lw = MEM_callocN(sizeof(*lw), "loggerwindow_new");
- lw->gpu_context = GPU_context_create(win);
+ lw->gpu_context = GPU_context_create(win, NULL);
GPU_init();
int bbox[2][2];
@@ -780,7 +780,7 @@ ExtraWindow *extrawindow_new(MultiTestApp *app)
if (win) {
ExtraWindow *ew = MEM_callocN(sizeof(*ew), "mainwindow_new");
- ew->gpu_context = GPU_context_create(win);
+ ew->gpu_context = GPU_context_create(win, NULL);
GPU_init();
ew->app = app;
diff --git a/intern/guardedalloc/CMakeLists.txt b/intern/guardedalloc/CMakeLists.txt
index 89fdf367037..0d16879adb5 100644
--- a/intern/guardedalloc/CMakeLists.txt
+++ b/intern/guardedalloc/CMakeLists.txt
@@ -7,6 +7,7 @@ endif()
set(INC
.
+ ..
../atomic
)
diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h
index fdd77fb9eef..5ae33343949 100644
--- a/intern/guardedalloc/MEM_guardedalloc.h
+++ b/intern/guardedalloc/MEM_guardedalloc.h
@@ -271,7 +271,7 @@ void MEM_use_guarded_allocator(void);
template<typename T, typename... Args>
inline T *MEM_new(const char *allocation_name, Args &&...args)
{
- void *buffer = MEM_mallocN(sizeof(T), allocation_name);
+ void *buffer = MEM_mallocN_aligned(sizeof(T), alignof(T), allocation_name);
return new (buffer) T(std::forward<Args>(args)...);
}
diff --git a/intern/guardedalloc/intern/leak_detector.cc b/intern/guardedalloc/intern/leak_detector.cc
index 48df71e410d..5b565b15920 100644
--- a/intern/guardedalloc/intern/leak_detector.cc
+++ b/intern/guardedalloc/intern/leak_detector.cc
@@ -36,12 +36,12 @@ class MemLeakPrinter {
const size_t mem_in_use = MEM_get_memory_in_use();
printf("Error: Not freed memory blocks: %u, total unfreed memory %f MB\n",
leaked_blocks,
- (double)mem_in_use / 1024 / 1024);
+ double(mem_in_use) / 1024 / 1024);
MEM_printmemlist();
if (fail_on_memleak) {
/* There are many other ways to change the exit code to failure here:
- * - Make the destructor noexcept(false) and throw an exception.
+ * - Make the destructor `noexcept(false)` and throw an exception.
* - Call exit(EXIT_FAILURE).
* - Call terminate().
*/
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index 63f06ced31d..984e641e7c1 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -43,7 +43,7 @@ void (*MEM_set_error_callback)(void (*func)(const char *)) = MEM_lockfree_set_er
bool (*MEM_consistency_check)(void) = MEM_lockfree_consistency_check;
void (*MEM_set_memory_debug)(void) = MEM_lockfree_set_memory_debug;
size_t (*MEM_get_memory_in_use)(void) = MEM_lockfree_get_memory_in_use;
-unsigned int (*MEM_get_memory_blocks_in_use)(void) = MEM_lockfree_get_memory_blocks_in_use;
+uint (*MEM_get_memory_blocks_in_use)(void) = MEM_lockfree_get_memory_blocks_in_use;
void (*MEM_reset_peak_memory)(void) = MEM_lockfree_reset_peak_memory;
size_t (*MEM_get_peak_memory)(void) = MEM_lockfree_get_peak_memory;
diff --git a/intern/guardedalloc/intern/mallocn_guarded_impl.c b/intern/guardedalloc/intern/mallocn_guarded_impl.c
index cd4b99ecde8..8deeb862b35 100644
--- a/intern/guardedalloc/intern/mallocn_guarded_impl.c
+++ b/intern/guardedalloc/intern/mallocn_guarded_impl.c
@@ -144,7 +144,7 @@ static const char *check_memlist(MemHead *memh);
/* vars */
/* --------------------------------------------------------------------- */
-static unsigned int totblock = 0;
+static uint totblock = 0;
static size_t mem_in_use = 0, peak_mem = 0;
static volatile struct localListBase _membase;
@@ -453,7 +453,7 @@ void *MEM_guarded_mallocN(size_t len, const char *str)
print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
SIZET_ARG(len),
str,
- (unsigned int)mem_in_use);
+ (uint)mem_in_use);
return NULL;
}
@@ -467,7 +467,7 @@ void *MEM_guarded_malloc_arrayN(size_t len, size_t size, const char *str)
SIZET_ARG(len),
SIZET_ARG(size),
str,
- (unsigned int)mem_in_use);
+ (uint)mem_in_use);
abort();
return NULL;
}
@@ -526,7 +526,7 @@ void *MEM_guarded_mallocN_aligned(size_t len, size_t alignment, const char *str)
print_error("aligned_malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
SIZET_ARG(len),
str,
- (unsigned int)mem_in_use);
+ (uint)mem_in_use);
return NULL;
}
@@ -550,7 +550,7 @@ void *MEM_guarded_callocN(size_t len, const char *str)
print_error("Calloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
SIZET_ARG(len),
str,
- (unsigned int)mem_in_use);
+ (uint)mem_in_use);
return NULL;
}
@@ -564,7 +564,7 @@ void *MEM_guarded_calloc_arrayN(size_t len, size_t size, const char *str)
SIZET_ARG(len),
SIZET_ARG(size),
str,
- (unsigned int)mem_in_use);
+ (uint)mem_in_use);
abort();
return NULL;
}
@@ -606,7 +606,7 @@ void MEM_guarded_printmemlist_stats(void)
{
MemHead *membl;
MemPrintBlock *pb, *printblock;
- unsigned int totpb, a, b;
+ uint totpb, a, b;
size_t mem_in_use_slop = 0;
mem_lock_thread();
@@ -1177,9 +1177,9 @@ size_t MEM_guarded_get_memory_in_use(void)
return _mem_in_use;
}
-unsigned int MEM_guarded_get_memory_blocks_in_use(void)
+uint MEM_guarded_get_memory_blocks_in_use(void)
{
- unsigned int _totblock;
+ uint _totblock;
mem_lock_thread();
_totblock = totblock;
diff --git a/intern/guardedalloc/intern/mallocn_lockfree_impl.c b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
index b5ee539ff4d..5a969186b19 100644
--- a/intern/guardedalloc/intern/mallocn_lockfree_impl.c
+++ b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
@@ -233,7 +233,7 @@ void *MEM_lockfree_callocN(size_t len, const char *str)
print_error("Calloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
SIZET_ARG(len),
str,
- (unsigned int)mem_in_use);
+ (uint)mem_in_use);
return NULL;
}
@@ -278,7 +278,7 @@ void *MEM_lockfree_mallocN(size_t len, const char *str)
print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
SIZET_ARG(len),
str,
- (unsigned int)mem_in_use);
+ (uint)mem_in_use);
return NULL;
}
@@ -292,7 +292,7 @@ void *MEM_lockfree_malloc_arrayN(size_t len, size_t size, const char *str)
SIZET_ARG(len),
SIZET_ARG(size),
str,
- (unsigned int)mem_in_use);
+ (uint)mem_in_use);
abort();
return NULL;
}
@@ -349,7 +349,7 @@ void *MEM_lockfree_mallocN_aligned(size_t len, size_t alignment, const char *str
print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
SIZET_ARG(len),
str,
- (unsigned int)mem_in_use);
+ (uint)mem_in_use);
return NULL;
}
@@ -401,7 +401,7 @@ size_t MEM_lockfree_get_memory_in_use(void)
return mem_in_use;
}
-unsigned int MEM_lockfree_get_memory_blocks_in_use(void)
+uint MEM_lockfree_get_memory_blocks_in_use(void)
{
return totblock;
}
diff --git a/intern/guardedalloc/tests/guardedalloc_alignment_test.cc b/intern/guardedalloc/tests/guardedalloc_alignment_test.cc
index ceda01c2fba..b1a2143c8dc 100644
--- a/intern/guardedalloc/tests/guardedalloc_alignment_test.cc
+++ b/intern/guardedalloc/tests/guardedalloc_alignment_test.cc
@@ -7,7 +7,7 @@
#include "MEM_guardedalloc.h"
#include "guardedalloc_test_base.h"
-#define CHECK_ALIGNMENT(ptr, align) EXPECT_EQ((size_t)ptr % align, 0)
+#define CHECK_ALIGNMENT(ptr, align) EXPECT_EQ(size_t(ptr) % align, 0)
namespace {
diff --git a/intern/libmv/libmv/simple_pipeline/keyframe_selection.cc b/intern/libmv/libmv/simple_pipeline/keyframe_selection.cc
index 5526d730651..e3e59171b63 100644
--- a/intern/libmv/libmv/simple_pipeline/keyframe_selection.cc
+++ b/intern/libmv/libmv/simple_pipeline/keyframe_selection.cc
@@ -333,7 +333,7 @@ void SelectKeyframesBasedOnGRICAndVariance(const Tracks& _tracks,
}
double success_intersects_factor =
- (double)intersects_success / intersects_total;
+ double(intersects_success) / intersects_total;
if (success_intersects_factor < success_intersects_factor_best) {
LG << "Skip keyframe candidate because of "
diff --git a/intern/libmv/libmv/simple_pipeline/pipeline.cc b/intern/libmv/libmv/simple_pipeline/pipeline.cc
index 5d52aeb7406..7203ddf1329 100644
--- a/intern/libmv/libmv/simple_pipeline/pipeline.cc
+++ b/intern/libmv/libmv/simple_pipeline/pipeline.cc
@@ -180,7 +180,7 @@ void InternalCompleteReconstruction(
<< " reconstructed markers for track " << track;
if (reconstructed_markers.size() >= 2) {
CompleteReconstructionLogProgress(update_callback,
- (double)tot_resects / (max_image));
+ double(tot_resects) / (max_image));
if (PipelineRoutines::Intersect(reconstructed_markers,
reconstruction)) {
num_intersects++;
@@ -192,7 +192,7 @@ void InternalCompleteReconstruction(
}
if (num_intersects) {
CompleteReconstructionLogProgress(
- update_callback, (double)tot_resects / (max_image), "Bundling...");
+ update_callback, double(tot_resects) / (max_image), "Bundling...");
PipelineRoutines::Bundle(tracks, reconstruction);
LG << "Ran Bundle() after intersections.";
}
@@ -218,7 +218,7 @@ void InternalCompleteReconstruction(
<< " reconstructed markers for image " << image;
if (reconstructed_markers.size() >= 5) {
CompleteReconstructionLogProgress(update_callback,
- (double)tot_resects / (max_image));
+ double(tot_resects) / (max_image));
if (PipelineRoutines::Resect(
reconstructed_markers, reconstruction, false)) {
num_resects++;
@@ -231,7 +231,7 @@ void InternalCompleteReconstruction(
}
if (num_resects) {
CompleteReconstructionLogProgress(
- update_callback, (double)tot_resects / (max_image), "Bundling...");
+ update_callback, double(tot_resects) / (max_image), "Bundling...");
PipelineRoutines::Bundle(tracks, reconstruction);
}
LG << "Did " << num_resects << " resects.";
@@ -254,7 +254,7 @@ void InternalCompleteReconstruction(
}
if (reconstructed_markers.size() >= 5) {
CompleteReconstructionLogProgress(update_callback,
- (double)tot_resects / (max_image));
+ double(tot_resects) / (max_image));
if (PipelineRoutines::Resect(
reconstructed_markers, reconstruction, true)) {
num_resects++;
@@ -266,7 +266,7 @@ void InternalCompleteReconstruction(
}
if (num_resects) {
CompleteReconstructionLogProgress(
- update_callback, (double)tot_resects / (max_image), "Bundling...");
+ update_callback, double(tot_resects) / (max_image), "Bundling...");
PipelineRoutines::Bundle(tracks, reconstruction);
}
}
diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp
index f5f22dc700b..d94c8943f78 100644
--- a/intern/mantaflow/intern/MANTA_main.cpp
+++ b/intern/mantaflow/intern/MANTA_main.cpp
@@ -58,7 +58,6 @@ MANTA::MANTA(int *res, FluidModifierData *fmd)
mUsingDiffusion = (fds->flags & FLUID_DOMAIN_USE_DIFFUSION) && mUsingLiquid;
mUsingViscosity = (fds->flags & FLUID_DOMAIN_USE_VISCOSITY) && mUsingLiquid;
mUsingMVel = (fds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS) && mUsingLiquid;
- mUsingGuiding = (fds->flags & FLUID_DOMAIN_USE_GUIDE);
mUsingDrops = (fds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) && mUsingLiquid;
mUsingBubbles = (fds->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) && mUsingLiquid;
mUsingFloats = (fds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) && mUsingLiquid;
@@ -68,6 +67,7 @@ MANTA::MANTA(int *res, FluidModifierData *fmd)
mUsingFire = (fds->active_fields & FLUID_DOMAIN_ACTIVE_FIRE) && mUsingSmoke;
mUsingColors = (fds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS) && mUsingSmoke;
mUsingObstacle = (fds->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE);
+ mUsingGuiding = (fds->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE);
mUsingInvel = (fds->active_fields & FLUID_DOMAIN_ACTIVE_INVEL);
mUsingOutflow = (fds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW);
@@ -1507,13 +1507,9 @@ bool MANTA::bakeData(FluidModifierData *fmd, int framenr)
string volume_format = getCacheFileEnding(fds->cache_data_format);
+ BLI_path_join(cacheDirData, sizeof(cacheDirData), fds->cache_directory, FLUID_DOMAIN_DIR_DATA);
BLI_path_join(
- cacheDirData, sizeof(cacheDirData), fds->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr);
- BLI_path_join(cacheDirGuiding,
- sizeof(cacheDirGuiding),
- fds->cache_directory,
- FLUID_DOMAIN_DIR_GUIDE,
- nullptr);
+ cacheDirGuiding, sizeof(cacheDirGuiding), fds->cache_directory, FLUID_DOMAIN_DIR_GUIDE);
BLI_path_make_safe(cacheDirData);
BLI_path_make_safe(cacheDirGuiding);
@@ -1540,7 +1536,7 @@ bool MANTA::bakeNoise(FluidModifierData *fmd, int framenr)
string volume_format = getCacheFileEnding(fds->cache_data_format);
BLI_path_join(
- cacheDirNoise, sizeof(cacheDirNoise), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE, nullptr);
+ cacheDirNoise, sizeof(cacheDirNoise), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE);
BLI_path_make_safe(cacheDirNoise);
ss.str("");
@@ -1566,8 +1562,7 @@ bool MANTA::bakeMesh(FluidModifierData *fmd, int framenr)
string volume_format = getCacheFileEnding(fds->cache_data_format);
string mesh_format = getCacheFileEnding(fds->cache_mesh_format);
- BLI_path_join(
- cacheDirMesh, sizeof(cacheDirMesh), fds->cache_directory, FLUID_DOMAIN_DIR_MESH, nullptr);
+ BLI_path_join(cacheDirMesh, sizeof(cacheDirMesh), fds->cache_directory, FLUID_DOMAIN_DIR_MESH);
BLI_path_make_safe(cacheDirMesh);
ss.str("");
@@ -1596,8 +1591,7 @@ bool MANTA::bakeParticles(FluidModifierData *fmd, int framenr)
BLI_path_join(cacheDirParticles,
sizeof(cacheDirParticles),
fds->cache_directory,
- FLUID_DOMAIN_DIR_PARTICLES,
- nullptr);
+ FLUID_DOMAIN_DIR_PARTICLES);
BLI_path_make_safe(cacheDirParticles);
ss.str("");
@@ -1623,11 +1617,8 @@ bool MANTA::bakeGuiding(FluidModifierData *fmd, int framenr)
string volume_format = getCacheFileEnding(fds->cache_data_format);
string resumable_cache = !(fds->flags & FLUID_DOMAIN_USE_RESUMABLE_CACHE) ? "False" : "True";
- BLI_path_join(cacheDirGuiding,
- sizeof(cacheDirGuiding),
- fds->cache_directory,
- FLUID_DOMAIN_DIR_GUIDE,
- nullptr);
+ BLI_path_join(
+ cacheDirGuiding, sizeof(cacheDirGuiding), fds->cache_directory, FLUID_DOMAIN_DIR_GUIDE);
BLI_path_make_safe(cacheDirGuiding);
ss.str("");
@@ -1678,13 +1669,11 @@ bool MANTA::exportSmokeScript(FluidModifierData *fmd)
FluidDomainSettings *fds = fmd->domain;
- BLI_path_join(
- cacheDir, sizeof(cacheDir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, nullptr);
+ BLI_path_join(cacheDir, sizeof(cacheDir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT);
BLI_path_make_safe(cacheDir);
/* Create 'script' subdir if it does not exist already */
BLI_dir_create_recursive(cacheDir);
- BLI_path_join(
- cacheDirScript, sizeof(cacheDirScript), cacheDir, FLUID_DOMAIN_SMOKE_SCRIPT, nullptr);
+ BLI_path_join(cacheDirScript, sizeof(cacheDirScript), cacheDir, FLUID_DOMAIN_SMOKE_SCRIPT);
BLI_path_make_safe(cacheDir);
bool noise = fds->flags & FLUID_DOMAIN_USE_NOISE;
@@ -1791,13 +1780,11 @@ bool MANTA::exportLiquidScript(FluidModifierData *fmd)
FluidDomainSettings *fds = fmd->domain;
- BLI_path_join(
- cacheDir, sizeof(cacheDir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, nullptr);
+ BLI_path_join(cacheDir, sizeof(cacheDir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT);
BLI_path_make_safe(cacheDir);
/* Create 'script' subdir if it does not exist already */
BLI_dir_create_recursive(cacheDir);
- BLI_path_join(
- cacheDirScript, sizeof(cacheDirScript), cacheDir, FLUID_DOMAIN_LIQUID_SCRIPT, nullptr);
+ BLI_path_join(cacheDirScript, sizeof(cacheDirScript), cacheDir, FLUID_DOMAIN_LIQUID_SCRIPT);
BLI_path_make_safe(cacheDirScript);
bool mesh = fds->flags & FLUID_DOMAIN_USE_MESH;
@@ -2323,8 +2310,7 @@ bool MANTA::hasGuiding(FluidModifierData *fmd, int framenr, bool sourceDomain)
string MANTA::getDirectory(FluidModifierData *fmd, string subdirectory)
{
char directory[FILE_MAX];
- BLI_path_join(
- directory, sizeof(directory), fmd->domain->cache_directory, subdirectory.c_str(), nullptr);
+ BLI_path_join(directory, sizeof(directory), fmd->domain->cache_directory, subdirectory.c_str());
BLI_path_make_safe(directory);
return directory;
}
@@ -2335,7 +2321,7 @@ string MANTA::getFile(
char targetFile[FILE_MAX];
string path = getDirectory(fmd, subdirectory);
string filename = fname + "_####" + extension;
- BLI_join_dirfile(targetFile, sizeof(targetFile), path.c_str(), filename.c_str());
+ BLI_path_join(targetFile, sizeof(targetFile), path.c_str(), filename.c_str());
BLI_path_frame(targetFile, framenr, 0);
return targetFile;
}
diff --git a/intern/mikktspace/mikk_util.hh b/intern/mikktspace/mikk_util.hh
index 857ca95910b..4064d2af617 100644
--- a/intern/mikktspace/mikk_util.hh
+++ b/intern/mikktspace/mikk_util.hh
@@ -139,8 +139,8 @@ void radixsort(std::vector<T> &data, std::vector<T> &data2, KeyGetter getKey)
static void float_add_atomic(float *val, float add)
{
- /* Hacky, but atomic floats are only supported from C++20 onwards.
- * This works in practise since std::atomic<uint32_t> is really just an uint32_t in memory,
+ /* Hacky, but atomic floats are only supported from C++20 onward.
+ * This works in practice since `std::atomic<uint32_t>` is really just an `uint32_t` in memory,
* so this cast lets us do a 32-bit CAS operation (which is used to build the atomic float
* operation) without needing any external libraries or compiler-specific builtins. */
std::atomic<uint32_t> *atomic_val = reinterpret_cast<std::atomic<uint32_t> *>(val);
diff --git a/intern/mikktspace/mikktspace.hh b/intern/mikktspace/mikktspace.hh
index 4b45fa86e14..9bfa6881f0d 100644
--- a/intern/mikktspace/mikktspace.hh
+++ b/intern/mikktspace/mikktspace.hh
@@ -151,7 +151,7 @@ template<typename Mesh> class Mikktspace {
void genTangSpace()
{
- nrFaces = (uint)mesh.GetNumFaces();
+ nrFaces = uint(mesh.GetNumFaces());
#ifdef WITH_TBB
nrThreads = tbb::this_task_arena::max_concurrency();
@@ -178,24 +178,30 @@ template<typename Mesh> class Mikktspace {
// put the degenerate triangles last.
degenPrologue();
- // evaluate triangle level attributes and neighbor list
- initTriangle();
+ if (nrTriangles == 0) {
+ // No point in building tangents if there are no non-degenerate triangles, so just zero them
+ tSpaces.resize(nrTSpaces);
+ }
+ else {
+ // evaluate triangle level attributes and neighbor list
+ initTriangle();
- // match up edge pairs
- buildNeighbors();
+ // match up edge pairs
+ buildNeighbors();
- // based on the 4 rules, identify groups based on connectivity
- build4RuleGroups();
+ // based on the 4 rules, identify groups based on connectivity
+ build4RuleGroups();
- // make tspaces, each group is split up into subgroups.
- // Finally a tangent space is made for every resulting subgroup
- generateTSpaces();
+ // make tspaces, each group is split up into subgroups.
+ // Finally a tangent space is made for every resulting subgroup
+ generateTSpaces();
- // degenerate quads with one good triangle will be fixed by copying a space from
- // the good triangle to the coinciding vertex.
- // all other degenerate triangles will just copy a space from any good triangle
- // with the same welded index in vertices[].
- degenEpilogue();
+ // degenerate quads with one good triangle will be fixed by copying a space from
+ // the good triangle to the coinciding vertex.
+ // all other degenerate triangles will just copy a space from any good triangle
+ // with the same welded index in vertices[].
+ degenEpilogue();
+ }
uint index = 0;
for (uint f = 0; f < nrFaces; f++) {
@@ -276,7 +282,7 @@ template<typename Mesh> class Mikktspace {
if (verts != 3 && verts != 4)
continue;
- uint tA = (uint)triangles.size();
+ uint tA = uint(triangles.size());
triangles.emplace_back(f, nrTSpaces);
Triangle &triA = triangles[tA];
@@ -284,7 +290,7 @@ template<typename Mesh> class Mikktspace {
triA.setVertices(0, 1, 2);
}
else {
- uint tB = (uint)triangles.size();
+ uint tB = uint(triangles.size());
triangles.emplace_back(f, nrTSpaces);
Triangle &triB = triangles[tB];
@@ -401,7 +407,7 @@ template<typename Mesh> class Mikktspace {
});
std::stable_partition(triangles.begin(), triangles.end(), [](const Triangle &tri) {
- return tri.markDegenerate;
+ return !tri.markDegenerate;
});
}
@@ -717,12 +723,11 @@ template<typename Mesh> class Mikktspace {
void build4RuleGroups()
{
- /* Note: This could be parallelized by grouping all [t, i] pairs into
+ /* NOTE: This could be parallelized by grouping all [t, i] pairs into
* shards by hash(triangles[t].vertices[i]). This way, each shard can be processed
* independently and in parallel.
- * However, the groupWithAny logic needs special handling (e.g. lock a mutex when
- * encountering a groupWithAny triangle, then sort it out, then unlock and proceed).
- */
+ * However, the `groupWithAny` logic needs special handling (e.g. lock a mutex when
+ * encountering a `groupWithAny` triangle, then sort it out, then unlock and proceed). */
for (uint t = 0; t < nrTriangles; t++) {
Triangle &triangle = triangles[t];
for (uint i = 0; i < 3; i++) {
@@ -731,7 +736,7 @@ template<typename Mesh> class Mikktspace {
continue;
}
- const uint newGroupId = (uint)groups.size();
+ const uint newGroupId = uint(groups.size());
triangle.group[i] = newGroupId;
groups.emplace_back(triangle.vertices[i], bool(triangle.orientPreserving));
diff --git a/intern/opencolorio/gpu_shader_display_transform_frag.glsl b/intern/opencolorio/gpu_shader_display_transform_frag.glsl
index 3c2352c13ba..92cf9b013fd 100644
--- a/intern/opencolorio/gpu_shader_display_transform_frag.glsl
+++ b/intern/opencolorio/gpu_shader_display_transform_frag.glsl
@@ -130,8 +130,10 @@ vec4 apply_dither(vec4 col, vec2 uv)
* \{ */
/* Prototypes: Implementation is generaterd and defined after. */
+#ifndef GPU_METAL /* Forward declaration invalid in MSL. */
vec4 OCIO_to_scene_linear(vec4 pixel);
vec4 OCIO_to_display(vec4 pixel);
+#endif
vec4 OCIO_ProcessColor(vec4 col, vec4 col_overlay)
{
diff --git a/intern/opensubdiv/CMakeLists.txt b/intern/opensubdiv/CMakeLists.txt
index 596534fc82c..920b8d5c542 100644
--- a/intern/opensubdiv/CMakeLists.txt
+++ b/intern/opensubdiv/CMakeLists.txt
@@ -81,12 +81,6 @@ if(WITH_OPENSUBDIV)
)
endif()
- OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_OPENMP)
- OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_OPENCL)
- OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_CUDA)
- OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK)
- OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_COMPUTE)
-
if(WIN32)
add_definitions(-DNOMINMAX)
add_definitions(-D_USE_MATH_DEFINES)
@@ -110,7 +104,6 @@ if(WITH_GTESTS AND WITH_OPENSUBDIV)
add_definitions(${GFLAGS_DEFINES})
add_definitions(${GLOG_DEFINES})
- add_definitions(-DBLENDER_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
blender_add_test_executable(opensubdiv_mesh_topology_test "internal/topology/mesh_topology_test.cc" "${INC}" "${INC_SYS}" "${LIB};bf_intern_opensubdiv")
endif()
diff --git a/intern/sky/source/sky_model.cpp b/intern/sky/source/sky_model.cpp
index d67fe08772d..4dd9fd11925 100644
--- a/intern/sky/source/sky_model.cpp
+++ b/intern/sky/source/sky_model.cpp
@@ -105,6 +105,9 @@ All instructions on how to use this code are in the accompanying header file.
# define ALLOC(_struct) ((_struct *)malloc(sizeof(_struct)))
#endif
+/* Not defined on all platforms (macOS & WIN32). */
+typedef unsigned int uint;
+
// internal definitions
typedef const double *ArHosekSkyModel_Dataset;
@@ -120,8 +123,8 @@ static void ArHosekSkyModel_CookConfiguration(ArHosekSkyModel_Dataset dataset,
{
const double *elev_matrix;
- int int_turbidity = (int)turbidity;
- double turbidity_rem = turbidity - (double)int_turbidity;
+ int int_turbidity = int(turbidity);
+ double turbidity_rem = turbidity - double(int_turbidity);
solar_elevation = pow(solar_elevation / (MATH_PI / 2.0), (1.0 / 3.0));
@@ -129,7 +132,7 @@ static void ArHosekSkyModel_CookConfiguration(ArHosekSkyModel_Dataset dataset,
elev_matrix = dataset + (9 * 6 * (int_turbidity - 1));
- for (unsigned int i = 0; i < 9; ++i) {
+ for (uint i = 0; i < 9; ++i) {
//(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
config[i] =
(1.0 - albedo) * (1.0 - turbidity_rem) *
@@ -143,7 +146,7 @@ static void ArHosekSkyModel_CookConfiguration(ArHosekSkyModel_Dataset dataset,
// alb 1 low turb
elev_matrix = dataset + (9 * 6 * 10 + 9 * 6 * (int_turbidity - 1));
- for (unsigned int i = 0; i < 9; ++i) {
+ for (uint i = 0; i < 9; ++i) {
//(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
config[i] +=
(albedo) * (1.0 - turbidity_rem) *
@@ -161,7 +164,7 @@ static void ArHosekSkyModel_CookConfiguration(ArHosekSkyModel_Dataset dataset,
// alb 0 high turb
elev_matrix = dataset + (9 * 6 * (int_turbidity));
- for (unsigned int i = 0; i < 9; ++i) {
+ for (uint i = 0; i < 9; ++i) {
//(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
config[i] +=
(1.0 - albedo) * (turbidity_rem) *
@@ -175,7 +178,7 @@ static void ArHosekSkyModel_CookConfiguration(ArHosekSkyModel_Dataset dataset,
// alb 1 high turb
elev_matrix = dataset + (9 * 6 * 10 + 9 * 6 * (int_turbidity));
- for (unsigned int i = 0; i < 9; ++i) {
+ for (uint i = 0; i < 9; ++i) {
//(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4;
config[i] +=
(albedo) * (turbidity_rem) *
@@ -195,8 +198,8 @@ static double ArHosekSkyModel_CookRadianceConfiguration(ArHosekSkyModel_Radiance
{
const double *elev_matrix;
- int int_turbidity = (int)turbidity;
- double turbidity_rem = turbidity - (double)int_turbidity;
+ int int_turbidity = int(turbidity);
+ double turbidity_rem = turbidity - double(int_turbidity);
double res;
solar_elevation = pow(solar_elevation / (MATH_PI / 2.0), (1.0 / 3.0));
@@ -274,7 +277,7 @@ double SKY_arhosekskymodel_radiance(SKY_ArHosekSkyModelState *state,
double gamma,
double wavelength)
{
- int low_wl = (int)((wavelength - 320.0) / 40.0);
+ int low_wl = int((wavelength - 320.0) / 40.0);
if (low_wl < 0 || low_wl >= 11) {
return 0.0;
@@ -313,7 +316,7 @@ SKY_ArHosekSkyModelState *SKY_arhosek_xyz_skymodelstate_alloc_init(const double
state->albedo = albedo;
state->elevation = elevation;
- for (unsigned int channel = 0; channel < 3; ++channel) {
+ for (uint channel = 0; channel < 3; ++channel) {
ArHosekSkyModel_CookConfiguration(
datasetsXYZ[channel], state->configs[channel], turbidity, albedo, elevation);
diff --git a/intern/sky/source/sky_nishita.cpp b/intern/sky/source/sky_nishita.cpp
index f1eab181189..d00ef51e152 100644
--- a/intern/sky/source/sky_nishita.cpp
+++ b/intern/sky/source/sky_nishita.cpp
@@ -316,7 +316,7 @@ void SKY_nishita_skymodel_precompute_texture(float *pixels,
for (int y = start_y; y < end_y; y++) {
/* sample more pixels toward the horizon */
- float latitude = (M_PI_2_F + half_lat_step) * sqr((float)y / height);
+ float latitude = (M_PI_2_F + half_lat_step) * sqr(float(y) / height);
float *pixel_row = pixels + (y * width * stride);
for (int x = 0; x < half_width; x++) {
diff --git a/intern/wayland_dynload/extern/wayland_dynload_client.h b/intern/wayland_dynload/extern/wayland_dynload_client.h
index 8e9dddd91a3..d80ef5c9f0c 100644
--- a/intern/wayland_dynload/extern/wayland_dynload_client.h
+++ b/intern/wayland_dynload/extern/wayland_dynload_client.h
@@ -41,6 +41,7 @@ WAYLAND_DYNLOAD_IFACE(wl_seat_interface)
WAYLAND_DYNLOAD_IFACE(wl_shm_interface)
WAYLAND_DYNLOAD_IFACE(wl_shm_pool_interface)
WAYLAND_DYNLOAD_IFACE(wl_surface_interface)
+WAYLAND_DYNLOAD_IFACE(wl_touch_interface)
#else
/* Header guard. */
diff --git a/intern/wayland_dynload/intern/wayland_dynload_client.c b/intern/wayland_dynload/intern/wayland_dynload_client.c
index 68ba5374aba..617a8878199 100644
--- a/intern/wayland_dynload/intern/wayland_dynload_client.c
+++ b/intern/wayland_dynload/intern/wayland_dynload_client.c
@@ -44,7 +44,8 @@ bool wayland_dynload_client_init(const bool verbose)
#define WAYLAND_DYNLOAD_IFACE(symbol) \
{ \
const void *symbol_val; \
- if (!(symbol_val = dynamic_library_find_with_error(lib, #symbol, paths[path_found]))) { \
+ if (!(symbol_val = dynamic_library_find_with_error( \
+ lib, #symbol, paths[path_found], verbose))) { \
return false; \
} \
memcpy(&symbol, symbol_val, sizeof(symbol)); \
@@ -54,7 +55,7 @@ bool wayland_dynload_client_init(const bool verbose)
#define WAYLAND_DYNLOAD_FN(symbol) \
if (!(wayland_dynload_client.symbol = dynamic_library_find_with_error( \
- lib, #symbol, paths[path_found]))) { \
+ lib, #symbol, paths[path_found], verbose))) { \
return false; \
}
#include "wayland_dynload_client.h"
diff --git a/intern/wayland_dynload/intern/wayland_dynload_cursor.c b/intern/wayland_dynload/intern/wayland_dynload_cursor.c
index 3d0526c7ba6..cc62a43bc01 100644
--- a/intern/wayland_dynload/intern/wayland_dynload_cursor.c
+++ b/intern/wayland_dynload/intern/wayland_dynload_cursor.c
@@ -36,7 +36,7 @@ bool wayland_dynload_cursor_init(const bool verbose)
#define WAYLAND_DYNLOAD_FN(symbol) \
if (!(wayland_dynload_cursor.symbol = dynamic_library_find_with_error( \
- lib, #symbol, paths[path_index]))) { \
+ lib, #symbol, paths[path_index], verbose))) { \
return false; \
}
#include "wayland_dynload_cursor.h"
diff --git a/intern/wayland_dynload/intern/wayland_dynload_egl.c b/intern/wayland_dynload/intern/wayland_dynload_egl.c
index b62adb6c90e..d8e4dfe0dad 100644
--- a/intern/wayland_dynload/intern/wayland_dynload_egl.c
+++ b/intern/wayland_dynload/intern/wayland_dynload_egl.c
@@ -22,7 +22,7 @@ bool wayland_dynload_egl_init(const bool verbose)
{
/* Library paths. */
const char *paths[] = {
- "libwayland-egl.so.0",
+ "libwayland-egl.so.1",
"libwayland-egl.so",
};
const int paths_num = sizeof(paths) / sizeof(*paths);
@@ -36,7 +36,7 @@ bool wayland_dynload_egl_init(const bool verbose)
#define WAYLAND_DYNLOAD_FN(symbol) \
if (!(wayland_dynload_egl.symbol = dynamic_library_find_with_error( \
- lib, #symbol, paths[path_found]))) { \
+ lib, #symbol, paths[path_found], verbose))) { \
return false; \
}
#include "wayland_dynload_egl.h"
diff --git a/intern/wayland_dynload/intern/wayland_dynload_libdecor.c b/intern/wayland_dynload/intern/wayland_dynload_libdecor.c
index d8bdd27bb27..dafd1badfda 100644
--- a/intern/wayland_dynload/intern/wayland_dynload_libdecor.c
+++ b/intern/wayland_dynload/intern/wayland_dynload_libdecor.c
@@ -36,7 +36,7 @@ bool wayland_dynload_libdecor_init(const bool verbose)
#define WAYLAND_DYNLOAD_FN(symbol) \
if (!(wayland_dynload_libdecor.symbol = dynamic_library_find_with_error( \
- lib, #symbol, paths[path_index]))) { \
+ lib, #symbol, paths[path_index], verbose))) { \
return false; \
}
#include "wayland_dynload_libdecor.h"
diff --git a/intern/wayland_dynload/intern/wayland_dynload_utils.c b/intern/wayland_dynload/intern/wayland_dynload_utils.c
index 743dac14eec..666de20c5d3 100644
--- a/intern/wayland_dynload/intern/wayland_dynload_utils.c
+++ b/intern/wayland_dynload/intern/wayland_dynload_utils.c
@@ -30,11 +30,16 @@ DynamicLibrary dynamic_library_open_array_with_error(const char **paths,
return lib;
}
-void *dynamic_library_find_with_error(DynamicLibrary lib, const char *symbol, const char *path_lib)
+void *dynamic_library_find_with_error(DynamicLibrary lib,
+ const char *symbol,
+ const char *path_lib,
+ const bool verbose)
{
void *symbol_var = dynamic_library_find(lib, symbol);
if (symbol_var == NULL) {
- fprintf(stderr, "Unable to find '%s' in '%s'.\n", symbol, path_lib);
+ if (verbose) {
+ fprintf(stderr, "Unable to find '%s' in '%s'.\n", symbol, path_lib);
+ }
}
return symbol_var;
}
diff --git a/intern/wayland_dynload/intern/wayland_dynload_utils.h b/intern/wayland_dynload/intern/wayland_dynload_utils.h
index 785f32521e4..1814879615b 100644
--- a/intern/wayland_dynload/intern/wayland_dynload_utils.h
+++ b/intern/wayland_dynload/intern/wayland_dynload_utils.h
@@ -26,4 +26,5 @@ DynamicLibrary dynamic_library_open_array_with_error(const char **paths,
/** Find a symbol, printing an error when the symbol isn't found. */
void *dynamic_library_find_with_error(DynamicLibrary lib,
const char *symbol,
- const char *path_lib);
+ const char *path_lib,
+ bool verbose);
diff --git a/make.bat b/make.bat
index ff8059b0754..394b2d0dad5 100644
--- a/make.bat
+++ b/make.bat
@@ -62,9 +62,19 @@ if "%SVN_FIX%" == "1" (
)
if "%BUILD_UPDATE%" == "1" (
+ REM First see if the SVN libs are there and check them out if they are not.
call "%BLENDER_DIR%\build_files\windows\check_libraries.cmd"
if errorlevel 1 goto EOF
-
+ if "%BUILD_UPDATE_SVN%" == "1" (
+ REM Then update SVN platform libraries, since updating python while python is
+ REM running tends to be problematic. The python script that update_sources
+ REM calls later on may still try to switch branches and run into trouble,
+ REM but for *most* people this will side step the problem.
+ call "%BLENDER_DIR%\build_files\windows\svn_update.cmd"
+ )
+ REM Finally call the python script shared between all platforms that updates git
+ REM and does any other SVN work like update the tests or branch switches
+ REM if required.
call "%BLENDER_DIR%\build_files\windows\update_sources.cmd"
goto EOF
)
diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg
index 41707261ac6..9dc7b184b12 100644
--- a/release/datafiles/blender_icons.svg
+++ b/release/datafiles/blender_icons.svg
@@ -18997,6 +18997,36 @@
id="path4817-4"
inkscape:connector-curvature="0" />
</g>
+ <g
+ id="g24638">
+ <path
+ style="color:#000000;fill:none;stroke-linecap:round;-inkscape-stroke:none;opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-linejoin:round"
+ d="m 374.12695,305.31445 c -1.10721,0 -1.93616,0.24199 -2.97851,0.63086 -1.04236,0.38888 -2.18224,0.95849 -3.30078,1.77735 -2.2371,1.63771 -4.46485,4.54533 -4.46485,8.40625 a 3.0581999,3.0581999 0 0 0 3.0586,3.05859 3.0581999,3.0581999 0 0 0 3.05859,-3.05859 c 0,-1.63187 0.77567,-2.603 1.96094,-3.47071 0.59263,-0.43385 1.26841,-0.77311 1.82422,-0.98047 0.5558,-0.20735 1.10962,-0.24804 0.84179,-0.24804 a 3.0581999,3.0581999 0 0 0 3.05664,-3.0586 3.0581999,3.0581999 0 0 0 -3.05664,-3.05664 z"
+ id="path6454-6" />
+ <path
+ style="display:inline;opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1;enable-background:new"
+ d="m 366.4419,316.12916 c 0,-5.49278 6.00534,-7.75723 7.68412,-7.75723"
+ id="path15424"
+ sodipodi:nodetypes="cc" />
+ </g>
+ <g
+ id="g24643">
+ <path
+ style="opacity:0.5;fill:#ffffff;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"
+ d="m 343.45275,317.52104 4.51631,-3.99333"
+ id="path4694"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"
+ d="m 342.44508,318.83525 c 14.125,0.14581 -0.42233,-12.9179 13.5429,-12.85486"
+ id="path6454"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="opacity:0.5;fill:#ffffff;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"
+ d="m 350.84964,311.18794 4.21454,-3.72502"
+ id="path19640"
+ sodipodi:nodetypes="cc" />
+ </g>
</g>
<g
inkscape:groupmode="layer"
diff --git a/release/datafiles/blender_icons16/icon16_mod_envelope.dat b/release/datafiles/blender_icons16/icon16_mod_envelope.dat
new file mode 100644
index 00000000000..7a4a1c2e569
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_mod_envelope.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_mod_outline.dat b/release/datafiles/blender_icons16/icon16_mod_outline.dat
new file mode 100644
index 00000000000..fa15aabec55
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_mod_outline.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_mod_envelope.dat b/release/datafiles/blender_icons32/icon32_mod_envelope.dat
new file mode 100644
index 00000000000..b0799fc33f2
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_mod_envelope.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_mod_outline.dat b/release/datafiles/blender_icons32/icon32_mod_outline.dat
new file mode 100644
index 00000000000..19d31834fcb
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_mod_outline.dat
Binary files differ
diff --git a/release/datafiles/blender_icons_geom.py b/release/datafiles/blender_icons_geom.py
index b95baf3419e..878cc4b46f6 100644
--- a/release/datafiles/blender_icons_geom.py
+++ b/release/datafiles/blender_icons_geom.py
@@ -72,7 +72,7 @@ class TriMesh:
@staticmethod
def _tri_copy_from_object(ob):
import bmesh
- assert(ob.type in OBJECTS_TYPES_MESH_COMPATIBLE)
+ assert ob.type in OBJECTS_TYPES_MESH_COMPATIBLE
bm = bmesh.new()
bm.from_mesh(ob.to_mesh())
bmesh.ops.triangulate(bm, faces=bm.faces)
@@ -143,7 +143,7 @@ def mesh_data_lists_from_mesh(me, material_colors):
i1 = 1
# we only write tris now
- assert(len(loops_poly) == 3)
+ assert len(loops_poly) == 3
for i2 in range(2, l_len):
l0 = loops_poly[i0]
@@ -217,7 +217,7 @@ def mesh_data_lists_from_objects(ob_parent, ob_children):
def write_mesh_to_py(fh, ob, ob_children):
def float_as_byte(f, axis_range):
- assert(axis_range <= 255)
+ assert axis_range <= 255
# -1..1 -> 0..255
f = (f + 1.0) * 0.5
f = round(f * axis_range)
@@ -238,7 +238,7 @@ def write_mesh_to_py(fh, ob, ob_children):
if 0:
# make as large as we can, keeping alignment
def size_scale_up(size):
- assert(size != 0)
+ assert size != 0
while size * 2 <= 255:
size *= 2
return size
diff --git a/release/datafiles/ctodata.py b/release/datafiles/ctodata.py
index b6420d5c9a2..6c5afdb1b5b 100755
--- a/release/datafiles/ctodata.py
+++ b/release/datafiles/ctodata.py
@@ -31,7 +31,7 @@ data = [int(v) for v in data]
if strip_byte:
# String data gets trailing byte.
last = data.pop()
- assert(last == 0)
+ assert last == 0
data = bytes(data)
diff --git a/release/datafiles/fonts/Noto Sans CJK Regular.woff2 b/release/datafiles/fonts/Noto Sans CJK Regular.woff2
index 5d3854b6bf7..4180a5914fa 100644
--- a/release/datafiles/fonts/Noto Sans CJK Regular.woff2
+++ b/release/datafiles/fonts/Noto Sans CJK Regular.woff2
Binary files differ
diff --git a/release/datafiles/locale b/release/datafiles/locale
-Subproject 1b891478f44dd047c3a92fda3ebd17fae1c3acd
+Subproject fe221a8bc934385d9f302c46a5c7cbeacddafe3
diff --git a/release/scripts/addons b/release/scripts/addons
-Subproject 67f1fbca1482d9d9362a4001332e785c3fd5d23
+Subproject 5a818af95080cccf04dfa8317f0e966bff515c6
diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib
-Subproject 95107484d076bc965239942e857c83433bfa86d
+Subproject c43c0b2bcf08c34d933c3b56f096c9a23c8eff6
diff --git a/release/scripts/freestyle/modules/freestyle/functions.py b/release/scripts/freestyle/modules/freestyle/functions.py
index 4a4a2f036e1..326e072d34a 100644
--- a/release/scripts/freestyle/modules/freestyle/functions.py
+++ b/release/scripts/freestyle/modules/freestyle/functions.py
@@ -198,7 +198,7 @@ class pyInverseCurvature2DAngleF0D(UnaryFunction0DDouble):
class pyCurvilinearLengthF0D(UnaryFunction0DDouble):
def __call__(self, inter):
cp = inter.object
- assert(isinstance(cp, CurvePoint))
+ assert isinstance(cp, CurvePoint)
return cp.t2d
diff --git a/release/scripts/modules/bl_app_override/__init__.py b/release/scripts/modules/bl_app_override/__init__.py
index 4d6194e71cd..1408cf3594f 100644
--- a/release/scripts/modules/bl_app_override/__init__.py
+++ b/release/scripts/modules/bl_app_override/__init__.py
@@ -74,7 +74,7 @@ def ui_draw_filter_register(
if ui_test is None:
UILayout.__getattribute__(self, "label")(text="")
else:
- assert(ui_test is True)
+ assert ui_test is True
# may need to be set
ret = OperatorProperties_Fake()
return ret
@@ -95,7 +95,7 @@ def ui_draw_filter_register(
if ui_test is None:
UILayout.__getattribute__(self, "label")(text="")
else:
- assert(ui_test is True)
+ assert ui_test is True
ret = None
return ret
return dummy_func
@@ -115,7 +115,7 @@ def ui_draw_filter_register(
if ui_test is None:
UILayout.__getattribute__(self, "label")(text="")
else:
- assert(ui_test is True)
+ assert ui_test is True
ret = None
return ret
return dummy_func
@@ -135,7 +135,7 @@ def ui_draw_filter_register(
if ui_test is None:
real_func(text="")
else:
- assert(ui_test is True)
+ assert ui_test is True
ret = None
return ret
return dummy_func
diff --git a/release/scripts/modules/bl_app_override/helpers.py b/release/scripts/modules/bl_app_override/helpers.py
index 4759e0ae8e5..0b785511886 100644
--- a/release/scripts/modules/bl_app_override/helpers.py
+++ b/release/scripts/modules/bl_app_override/helpers.py
@@ -44,14 +44,14 @@ class AppOverrideState:
self._ui_ignore_store = None
def _setup_classes(self):
- assert(self._class_store is None)
+ assert self._class_store is None
self._class_store = self.class_ignore()
from bpy.utils import unregister_class
for cls in self._class_store:
unregister_class(cls)
def _teardown_classes(self):
- assert(self._class_store is not None)
+ assert self._class_store is not None
from bpy.utils import register_class
for cls in self._class_store:
diff --git a/release/scripts/modules/bl_console_utils/autocomplete/complete_calltip.py b/release/scripts/modules/bl_console_utils/autocomplete/complete_calltip.py
index 07ccac81f91..419a6dc9852 100644
--- a/release/scripts/modules/bl_console_utils/autocomplete/complete_calltip.py
+++ b/release/scripts/modules/bl_console_utils/autocomplete/complete_calltip.py
@@ -29,7 +29,7 @@ RE_DEF_COMPLETE = re.compile(
def reduce_newlines(text):
"""Reduces multiple newlines to a single newline.
- :param text: text with multiple newlines
+ :arg text: text with multiple newlines
:type text: str
:returns: text with single newlines
:rtype: str
@@ -43,7 +43,7 @@ def reduce_newlines(text):
def reduce_spaces(text):
"""Reduces multiple whitespaces to a single space.
- :param text: text with multiple spaces
+ :arg text: text with multiple spaces
:type text: str
:returns: text with single spaces
:rtype: str
@@ -57,7 +57,7 @@ def reduce_spaces(text):
def get_doc(obj):
"""Get the doc string or comments for an object.
- :param object: object
+ :arg object: object
:returns: doc string
:rtype: str
@@ -71,11 +71,11 @@ def get_doc(obj):
def get_argspec(func, *, strip_self=True, doc=None, source=None):
"""Get argument specifications.
- :param strip_self: strip `self` from argspec
+ :arg strip_self: strip `self` from argspec
:type strip_self: bool
- :param doc: doc string of func (optional)
+ :arg doc: doc string of func (optional)
:type doc: str
- :param source: source code of func (optional)
+ :arg source: source code of func (optional)
:type source: str
:returns: argument specification
:rtype: str
@@ -131,11 +131,11 @@ def get_argspec(func, *, strip_self=True, doc=None, source=None):
def complete(line, cursor, namespace):
"""Complete callable with calltip.
- :param line: incomplete text line
+ :arg line: incomplete text line
:type line: str
- :param cursor: current character position
+ :arg cursor: current character position
:type cursor: int
- :param namespace: namespace
+ :arg namespace: namespace
:type namespace: dict
:returns: (matches, world, scrollback)
:rtype: (list of str, str, str)
diff --git a/release/scripts/modules/bl_console_utils/autocomplete/complete_import.py b/release/scripts/modules/bl_console_utils/autocomplete/complete_import.py
index 2f321fee0b2..c506e674cd5 100644
--- a/release/scripts/modules/bl_console_utils/autocomplete/complete_import.py
+++ b/release/scripts/modules/bl_console_utils/autocomplete/complete_import.py
@@ -42,7 +42,7 @@ def get_root_modules():
"""
global ROOT_MODULES
modules = []
- if not(ROOT_MODULES is None):
+ if not (ROOT_MODULES is None):
return ROOT_MODULES
from time import time
t = time()
@@ -76,7 +76,7 @@ def module_list(path):
Return the list containing the names of the modules available in
the given folder.
- :param path: folder path
+ :arg path: folder path
:type path: str
:returns: modules
:rtype: list
@@ -107,7 +107,7 @@ def complete(line):
"""
Returns a list containing the completion possibilities for an import line.
- :param line:
+ :arg line:
incomplete line which contains an import statement::
@@ -131,7 +131,7 @@ def complete(line):
if only_modules:
return inspect.ismodule(getattr(module, attr))
else:
- return not(attr[:2] == '__' and attr[-2:] == '__')
+ return not (attr[:2] == '__' and attr[-2:] == '__')
try:
m = __import__(mod)
diff --git a/release/scripts/modules/bl_console_utils/autocomplete/complete_namespace.py b/release/scripts/modules/bl_console_utils/autocomplete/complete_namespace.py
index 4ba446d6832..b1b751c96ab 100644
--- a/release/scripts/modules/bl_console_utils/autocomplete/complete_namespace.py
+++ b/release/scripts/modules/bl_console_utils/autocomplete/complete_namespace.py
@@ -27,9 +27,9 @@ def is_struct_seq(obj):
def complete_names(word, namespace):
"""Complete variable names or attributes
- :param word: word to be completed
+ :arg word: word to be completed
:type word: str
- :param namespace: namespace
+ :arg namespace: namespace
:type namespace: dict
:returns: completion matches
:rtype: list of str
@@ -50,12 +50,12 @@ def complete_indices(word, namespace, *, obj=None, base=None):
* integer numbers for list
* any keys for dictionary
- :param word: word to be completed
+ :arg word: word to be completed
:type word: str
- :param namespace: namespace
+ :arg namespace: namespace
:type namespace: dict
- :param obj: object evaluated from base
- :param base: sub-string which can be evaluated into an object.
+ :arg obj: object evaluated from base
+ :arg base: sub-string which can be evaluated into an object.
:type base: str
:returns: completion matches
:rtype: list of str
@@ -103,11 +103,11 @@ def complete(word, namespace, *, private=True):
"""Complete word within a namespace with the standard rlcompleter
module. Also supports index or key access [].
- :param word: word to be completed
+ :arg word: word to be completed
:type word: str
- :param namespace: namespace
+ :arg namespace: namespace
:type namespace: dict
- :param private: whether private attribute/methods should be returned
+ :arg private: whether private attribute/methods should be returned
:type private: bool
:returns: completion matches
:rtype: list of str
@@ -132,7 +132,7 @@ def complete(word, namespace, *, private=True):
matches = complete_indices(word, namespace,
base=re_incomplete_index.group(1))
- elif not('[' in word):
+ elif not ('[' in word):
matches = complete_names(word, namespace)
elif word[-1] == ']':
@@ -182,7 +182,7 @@ def complete(word, namespace, *, private=True):
matches = [word + '.']
# separate public from private
- public_matches = [match for match in matches if not('._' in match)]
+ public_matches = [match for match in matches if not ('._' in match)]
if private:
private_matches = [match for match in matches if '._' in match]
return public_matches + private_matches
diff --git a/release/scripts/modules/bl_console_utils/autocomplete/intellisense.py b/release/scripts/modules/bl_console_utils/autocomplete/intellisense.py
index e53e38dbc53..7aff3596c42 100644
--- a/release/scripts/modules/bl_console_utils/autocomplete/intellisense.py
+++ b/release/scripts/modules/bl_console_utils/autocomplete/intellisense.py
@@ -43,13 +43,13 @@ def complete(line, cursor, namespace, private):
* index completion for lists and dictionaries
* module completion (from/import)
- :param line: incomplete text line
+ :arg line: incomplete text line
:type line: str
- :param cursor: current character position
+ :arg cursor: current character position
:type cursor: int
- :param namespace: namespace
+ :arg namespace: namespace
:type namespace: dict
- :param private: whether private variables should be listed
+ :arg private: whether private variables should be listed
:type private: bool
:returns: list of completions, word
:rtype: list, str
@@ -82,13 +82,13 @@ def expand(line, cursor, namespace, *, private=True):
"""This method is invoked when the user asks autocompletion,
e.g. when Ctrl+Space is clicked.
- :param line: incomplete text line
+ :arg line: incomplete text line
:type line: str
- :param cursor: current character position
+ :arg cursor: current character position
:type cursor: int
- :param namespace: namespace
+ :arg namespace: namespace
:type namespace: dict
- :param private: whether private variables should be listed
+ :arg private: whether private variables should be listed
:type private: bool
:returns:
diff --git a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
index 21ca38bff20..18a41d86322 100644
--- a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
+++ b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
@@ -978,17 +978,30 @@ def dump_messages(do_messages, do_checks, settings):
# Get strings from addons' bl_info.
import addon_utils
for module in addon_utils.modules():
- if module.bl_info['support'] != 'OFFICIAL':
+ # Only process official add-ons, i.e. those marked as 'OFFICIAL' and
+ # existing in the system add-ons directory (not user-installed ones).
+ if (module.bl_info['support'] != 'OFFICIAL'
+ or not bpy.path.is_subdir(module.__file__, bpy.utils.system_resource('SCRIPTS'))):
continue
dump_addon_bl_info(msgs, reports, module, settings)
# Get strings from addons' categories.
+ system_categories = set()
+ for module in addon_utils.modules():
+ if bpy.path.is_subdir(module.__file__, bpy.utils.system_resource('SCRIPTS')):
+ system_categories.add(module.bl_info['category'])
for uid, label, tip in bpy.types.WindowManager.addon_filter.keywords['items'](
bpy.context.window_manager,
bpy.context,
):
- process_msg(msgs, settings.DEFAULT_CONTEXT, label, "Add-ons' categories", reports, None, settings)
- if tip:
+ if label in system_categories:
+ # Only process add-on if it a system one (i.e shipped with Blender). Also,
+ # we do want to translate official categories, even if they have no official add-ons,
+ # hence the different test than below.
+ process_msg(msgs, settings.DEFAULT_CONTEXT, label, "Add-ons' categories", reports, None, settings)
+ elif tip:
+ # Only special categories get a tip (All and User).
+ process_msg(msgs, settings.DEFAULT_CONTEXT, label, "Add-ons' categories", reports, None, settings)
process_msg(msgs, settings.DEFAULT_CONTEXT, tip, "Add-ons' categories", reports, None, settings)
# Get strings specific to translations' menu.
diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py
index 77ab70f8d91..d8f8d58f609 100644
--- a/release/scripts/modules/bl_i18n_utils/settings.py
+++ b/release/scripts/modules/bl_i18n_utils/settings.py
@@ -49,7 +49,7 @@ LANGUAGES = (
(15, "Russian (Русский)", "ru_RU"),
(16, "Croatian (Hrvatski)", "hr_HR"),
(17, "Serbian (Српски)", "sr_RS"),
- (18, "Ukrainian (Український)", "uk_UA"),
+ (18, "Ukrainian (Українська)", "uk_UA"),
(19, "Polish (Polski)", "pl_PL"),
(20, "Romanian (Român)", "ro_RO"),
# Using the utf8 flipped form of Arabic (العربية).
@@ -87,7 +87,7 @@ LANGUAGES = (
# Default context, in py (keep in sync with `BLT_translation.h`)!
if bpy is not None:
- assert(bpy.app.translations.contexts.default == "*")
+ assert bpy.app.translations.contexts.default == "*"
DEFAULT_CONTEXT = "*"
# Name of language file used by Blender to generate translations' menu.
@@ -260,9 +260,9 @@ PYGETTEXT_KEYWORDS = (() +
# NOTE: regex is a bit more complex than it would need too. Since the actual
# identifier (`B_UNIT_DEF_`) is at the end, if it's simpler/too general it
# becomes extremely slow to process some (unrelated) source files.
- ((r"\{(?:(?:\s*\"[^\"',]+\"\s*,)|(?:\s*NULL\s*,)){4}\s*" +
+ ((r"\{(?:(?:\s*\"[^\",]+\"\s*,)|(?:\s*\"\\\"\",)|(?:\s*NULL\s*,)){4}\s*" +
_msg_re + r"\s*,(?:(?:\s*\"[^\"',]+\"\s*,)|(?:\s*NULL\s*,))(?:[^,]+,){2}"
- + "\s*B_UNIT_DEF_[_A-Z]+\s*\}"),) +
+ + "(?:\|?\s*B_UNIT_DEF_[_A-Z]+\s*)+\}"),) +
tuple((r"{}\(\s*" + _msg_re + r"\s*,\s*(?:" +
r"\s*,\s*)?(?:".join(_ctxt_re_gen(i) for i in range(PYGETTEXT_MAX_MULTI_CTXT)) + r")?\s*\)").format(it)
@@ -367,9 +367,9 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = {
"all and invert unselected",
"and AMD driver version 22.10 or newer",
"and AMD Radeon Pro 21.Q4 driver or newer",
- "and Linux driver version xx.xx.23570 or newer",
+ "and Linux driver version xx.xx.23904 or newer",
"and NVIDIA driver version 470 or newer",
- "and Windows driver version 101.3268 or newer",
+ "and Windows driver version 101.3430 or newer",
"available with",
"brown fox",
"can't save image while rendering",
diff --git a/release/scripts/modules/bl_i18n_utils/utils.py b/release/scripts/modules/bl_i18n_utils/utils.py
index 324c3ea261d..784b206fb84 100644
--- a/release/scripts/modules/bl_i18n_utils/utils.py
+++ b/release/scripts/modules/bl_i18n_utils/utils.py
@@ -68,7 +68,7 @@ def locale_explode(locale):
try:
import bpy.app.translations as bpy_translations
- assert(ret == bpy_translations.locale_explode(locale))
+ assert ret == bpy_translations.locale_explode(locale)
except ModuleNotFoundError:
pass
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 a93f1323562..7fe4d0da0a4 100644
--- a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
+++ b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
@@ -389,6 +389,8 @@ class SpellChecker:
"albedo",
"anamorphic",
"anisotropic", "anisotropy",
+ "arcminute", "arcminutes",
+ "arcsecond", "arcseconds",
"bimanual", # OpenXR?
"bitangent",
"boid", "boids",
@@ -449,7 +451,7 @@ class SpellChecker:
"superellipse",
"thumbstick",
"tooltip", "tooltips",
- "trackpad",
+ "touchpad", "trackpad",
"tuple",
"unicode",
"viewport", "viewports",
@@ -650,6 +652,7 @@ class SpellChecker:
"mikktspace",
"minkowski",
"minnaert",
+ "mises", # von Mises-Fisher
"moskowitz", # Pierson-Moskowitz
"musgrave",
"nayar",
@@ -665,6 +668,7 @@ class SpellChecker:
"runge",
"sobol",
"verlet",
+ "von", # von Mises-Fisher
"wilkie",
"worley",
@@ -724,6 +728,7 @@ class SpellChecker:
"lmb", "mmb", "rmb",
"lscm",
"kb",
+ "mis",
"mocap",
"msgid", "msgids",
"mux",
@@ -751,6 +756,7 @@ class SpellChecker:
"uuid",
"vbo", "vbos",
"vfx",
+ "vmm",
"vr",
"wxyz",
"xr",
diff --git a/release/scripts/modules/bl_keymap_utils/io.py b/release/scripts/modules/bl_keymap_utils/io.py
index 5d74ffbcf56..8d849498bd7 100644
--- a/release/scripts/modules/bl_keymap_utils/io.py
+++ b/release/scripts/modules/bl_keymap_utils/io.py
@@ -229,7 +229,7 @@ def keyconfig_export_as_data(wm, kc, filepath, *, all_keymaps=False):
# Take care making changes that could impact performance.
def _init_properties_from_data(base_props, base_value):
- assert(type(base_value) is list)
+ assert type(base_value) is list
for attr, value in base_value:
if type(value) is list:
base_props.property_unset(attr)
diff --git a/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py b/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py
index f75a38c1c66..09a55827128 100644
--- a/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py
+++ b/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py
@@ -173,7 +173,7 @@ def generate(context, space_type, *, use_fallback_keys=True, use_reset=True):
mode = context.active_object.mode
# See: BKE_paint_get_tool_prop_id_from_paintmode
if space_type == 'IMAGE_EDITOR':
- if context.space_data.ui_mode == 'PAINT':
+ if context.space_data.mode == 'PAINT':
attr = "image_tool"
else:
attr = None
@@ -200,7 +200,7 @@ def generate(context, space_type, *, use_fallback_keys=True, use_reset=True):
properties=kmi_hack_brush_select_properties,
include={'KEYBOARD'},
)[1]
- elif mode in {'PARTICLE_EDIT', 'SCULPT_GPENCIL'}:
+ elif mode in {'EDIT', 'PARTICLE_EDIT', 'SCULPT_GPENCIL'}:
# Doesn't use brushes
pass
else:
diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py
index 54fcb4cdc67..22577dbd1cf 100644
--- a/release/scripts/modules/bpy/utils/__init__.py
+++ b/release/scripts/modules/bpy/utils/__init__.py
@@ -61,9 +61,18 @@ import sys as _sys
import addon_utils as _addon_utils
_preferences = _bpy.context.preferences
-_script_module_dirs = "startup", "modules"
_is_factory_startup = _bpy.app.factory_startup
+# Directories added to the start of `sys.path` for all of Blender's "scripts" directories.
+_script_module_dirs = "startup", "modules"
+
+# Base scripts, this points to the directory containing: "modules" & "startup" (see `_script_module_dirs`).
+# In Blender's code-base this is `./release/scripts`.
+#
+# NOTE: in virtually all cases this should match `BLENDER_SYSTEM_SCRIPTS` as this script is it's self a system script,
+# it must be in the `BLENDER_SYSTEM_SCRIPTS` by definition and there is no need for a look-up from `_bpy_script_paths`.
+_script_base_dir = _os.path.dirname(_os.path.dirname(_os.path.dirname(_os.path.dirname(__file__))))
+
def execfile(filepath, *, mod=None):
"""
@@ -324,12 +333,6 @@ def load_scripts(*, reload_scripts=False, refresh_scripts=False):
)
-# base scripts
-_scripts = (
- _os.path.dirname(_os.path.dirname(_os.path.dirname(__file__))),
-)
-
-
def script_path_user():
"""returns the env var and falls back to home dir or None"""
path = _user_resource('SCRIPTS')
@@ -350,60 +353,55 @@ def script_paths(*, subdir=None, user_pref=True, check_all=False, use_user=True)
:type subdir: string
:arg user_pref: Include the user preference script path.
:type user_pref: bool
- :arg check_all: Include local, user and system paths rather just the paths
- blender uses.
+ :arg check_all: Include local, user and system paths rather just the paths Blender uses.
:type check_all: bool
:return: script paths.
:rtype: list
"""
- scripts = list(_scripts)
- # Only paths Blender uses.
- #
- # Needed this is needed even when 'check_all' is enabled,
- # so the 'BLENDER_SYSTEM_SCRIPTS' environment variable will be used.
- base_paths = _bpy_script_paths()
+ if check_all or use_user:
+ path_system, path_user = _bpy_script_paths()
- # Defined to be (system, user) so we can skip the second if needed.
- if not use_user:
- base_paths = base_paths[:1]
+ base_paths = []
if check_all:
- # All possible paths, no duplicates, keep order.
+ # Order: 'LOCAL', 'USER', 'SYSTEM' (where user is optional).
+ if path_local := resource_path('LOCAL'):
+ base_paths.append(_os.path.join(path_local, "scripts"))
if use_user:
- test_paths = ('LOCAL', 'USER', 'SYSTEM')
- else:
- test_paths = ('LOCAL', 'SYSTEM')
-
- base_paths = (
- *(path for path in (
- _os.path.join(resource_path(res), "scripts")
- for res in test_paths) if path not in base_paths),
- *base_paths,
- )
-
- test_paths = (
- *base_paths,
- *((script_path_user(),) if use_user else ()),
- *((script_path_pref(),) if user_pref else ()),
- )
+ base_paths.append(path_user)
+ base_paths.append(path_system) # Same as: `system_resource('SCRIPTS')`.
- for path in test_paths:
- if path:
- path = _os.path.normpath(path)
- if path not in scripts and _os.path.isdir(path):
- scripts.append(path)
+ # Note that `_script_base_dir` may be either:
+ # - `os.path.join(bpy.utils.resource_path('LOCAL'), "scripts")`
+ # - `bpy.utils.system_resource('SCRIPTS')`.
+ # When `check_all` is enabled duplicate paths will be added however
+ # paths are de-duplicated so it wont cause problems.
+ base_paths.append(_script_base_dir)
- if subdir is None:
- return scripts
+ if not check_all:
+ if use_user:
+ base_paths.append(path_user)
- scripts_subdir = []
- for path in scripts:
- path_subdir = _os.path.join(path, subdir)
- if _os.path.isdir(path_subdir):
- scripts_subdir.append(path_subdir)
+ if user_pref:
+ base_paths.append(script_path_pref())
+
+ scripts = []
+ for path in base_paths:
+ if not path:
+ continue
+
+ path = _os.path.normpath(path)
+ if subdir is not None:
+ path = _os.path.join(path, subdir)
+
+ if path in scripts:
+ continue
+ if not _os.path.isdir(path):
+ continue
+ scripts.append(path)
- return scripts_subdir
+ return scripts
def refresh_script_paths():
diff --git a/release/scripts/modules/bpy_extras/io_utils.py b/release/scripts/modules/bpy_extras/io_utils.py
index 35b7d564a5e..b6da6c7768c 100644
--- a/release/scripts/modules/bpy_extras/io_utils.py
+++ b/release/scripts/modules/bpy_extras/io_utils.py
@@ -295,7 +295,7 @@ def axis_conversion(from_forward='Y', from_up='Z', to_forward='Y', to_up='Z'):
for i, axis_lut in enumerate(_axis_convert_lut):
if value in axis_lut:
return Matrix(_axis_convert_matrix[i])
- assert(0)
+ assert 0
def axis_conversion_ensure(operator, forward_attr, up_attr):
diff --git a/release/scripts/modules/bpy_extras/node_shader_utils.py b/release/scripts/modules/bpy_extras/node_shader_utils.py
index cda291c6c90..0c349084220 100644
--- a/release/scripts/modules/bpy_extras/node_shader_utils.py
+++ b/release/scripts/modules/bpy_extras/node_shader_utils.py
@@ -13,7 +13,7 @@ def _set_check(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
if self.is_readonly:
- assert(not "Trying to set value to read-only shader!")
+ assert not "Trying to set value to read-only shader!"
return
return func(self, *args, **kwargs)
return wrapper
diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py
index ab678ba27c8..5275a83e062 100644
--- a/release/scripts/modules/bpy_extras/object_utils.py
+++ b/release/scripts/modules/bpy_extras/object_utils.py
@@ -142,8 +142,17 @@ def object_data_add(context, obdata, operator=None, name=None):
bpy.ops.object.mode_set(mode='EDIT')
else:
layer.objects.active = obj_new
- if obdata and context.preferences.edit.use_enter_edit_mode:
- bpy.ops.object.mode_set(mode='EDIT')
+ if context.preferences.edit.use_enter_edit_mode:
+ if obdata and obdata.library is None:
+ obtype = obj_new.type
+ mode = None
+ if obtype in {'ARMATURE', 'CURVE', 'CURVES', 'FONT', 'LATTICE', 'MESH', 'META', 'SURFACE'}:
+ mode = 'EDIT'
+ elif obtype == 'GPENCIL':
+ mode = 'EDIT_GPENCIL'
+
+ if mode is not None:
+ bpy.ops.object.mode_set(mode=mode)
return obj_new
diff --git a/release/scripts/modules/bpy_extras/wm_utils/progress_report.py b/release/scripts/modules/bpy_extras/wm_utils/progress_report.py
index 637d60838db..371d598042c 100644
--- a/release/scripts/modules/bpy_extras/wm_utils/progress_report.py
+++ b/release/scripts/modules/bpy_extras/wm_utils/progress_report.py
@@ -93,7 +93,7 @@ class ProgressReport:
def leave_substeps(self, msg=""):
if (msg):
self.update(msg)
- assert(len(self.steps) > 1)
+ assert len(self.steps) > 1
del self.steps[-1]
del self.curr_step[-1]
del self.start_time[-1]
@@ -134,7 +134,7 @@ class ProgressReportSubstep:
return self
def __exit__(self, exc_type, exc_value, traceback):
- assert(len(self.progress.steps) > self.level)
+ assert len(self.progress.steps) > self.level
while len(self.progress.steps) > self.level + 1:
self.progress.leave_substeps()
self.progress.leave_substeps(self.final_msg)
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index b2f4d71ed92..d8d6a9123f2 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -742,7 +742,6 @@ class Gizmo(StructRNA):
matrix = self.matrix_world
batch, shader = shape
- shader.bind()
if select_id is not None:
gpu.select.load_id(select_id)
diff --git a/release/scripts/modules/console_python.py b/release/scripts/modules/console_python.py
index 2aa4caab7f6..5cf55d3c3b5 100644
--- a/release/scripts/modules/console_python.py
+++ b/release/scripts/modules/console_python.py
@@ -325,7 +325,7 @@ def banner(context):
"PYTHON INTERACTIVE CONSOLE %s" % version_string,
"",
"Builtin Modules: "
- "bpy, bpy.data, bpy.ops, bpy.props, bpy.types, bpy.context, bpy.utils, bgl, blf, mathutils",
+ "bpy, bpy.data, bpy.ops, bpy.props, bpy.types, bpy.context, bpy.utils, bgl, gpu, blf, mathutils",
"Convenience Imports: from mathutils import *; from math import *",
"Convenience Variables: C = bpy.context, D = bpy.data",
diff --git a/release/scripts/modules/gpu_extras/batch.py b/release/scripts/modules/gpu_extras/batch.py
index ba8e3879a8e..6c9ab52c1a3 100644
--- a/release/scripts/modules/gpu_extras/batch.py
+++ b/release/scripts/modules/gpu_extras/batch.py
@@ -34,13 +34,13 @@ def batch_for_shader(shader, type, content, *, indices=None):
return 'I32'
def recommended_attr_len(attr_name):
- item = content[attr_name][0]
attr_len = 1
try:
+ item = content[attr_name][0]
while True:
attr_len *= len(item)
item = item[0]
- except TypeError:
+ except (TypeError, IndexError):
pass
return attr_len
diff --git a/release/scripts/modules/gpu_extras/presets.py b/release/scripts/modules/gpu_extras/presets.py
index f68824d76c8..f0d80e855c1 100644
--- a/release/scripts/modules/gpu_extras/presets.py
+++ b/release/scripts/modules/gpu_extras/presets.py
@@ -78,7 +78,6 @@ def draw_texture_2d(texture, position, width, height):
gpu.matrix.scale((width, height))
shader = gpu.shader.from_builtin('IMAGE')
- shader.bind()
if isinstance(texture, int):
# Call the legacy bgl to not break the existing API
diff --git a/release/scripts/modules/rna_info.py b/release/scripts/modules/rna_info.py
index e2bbc4077a1..07daf7c55eb 100644
--- a/release/scripts/modules/rna_info.py
+++ b/release/scripts/modules/rna_info.py
@@ -286,7 +286,10 @@ class InfoPropertyRNA:
self.enum_pointer = 0
if self.type == "enum":
- items = tuple(rna_prop.enum_items)
+ # WARNING: don't convert to a tuple as this causes dynamically allocated enums to access freed memory
+ # since freeing the iterator may free the memory used to store the internal `EnumPropertyItem` array.
+ # To support this properly RNA would have to support owning the dynamically allocated memory.
+ items = rna_prop.enum_items
items_static = tuple(rna_prop.enum_items_static)
self.enum_items[:] = [(item.identifier, item.name, item.description) for item in items]
self.is_enum_flag = rna_prop.is_enum_flag
@@ -295,6 +298,7 @@ class InfoPropertyRNA:
item = (items_static or items)
if item:
self.enum_pointer = item[0].as_pointer()
+ del items, items_static, item
else:
self.is_enum_flag = False
diff --git a/release/scripts/modules/rna_manual_reference.py b/release/scripts/modules/rna_manual_reference.py
index 10925e78ef3..dfebf9132d2 100644
--- a/release/scripts/modules/rna_manual_reference.py
+++ b/release/scripts/modules/rna_manual_reference.py
@@ -58,6 +58,7 @@ url_manual_mapping = (
("bpy.types.cyclesrendersettings.preview_denoising_input_passes*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoising-input-passes"),
("bpy.types.cyclesrendersettings.preview_denoising_start_sample*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoising-start-sample"),
("bpy.types.fluiddomainsettings.sndparticle_sampling_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-trappedair"),
+ ("bpy.types.brush.automasking_boundary_edges_propagation_steps*", "sculpt_paint/sculpting/controls.html#bpy-types-brush-automasking-boundary-edges-propagation-steps"),
("bpy.types.fluiddomainsettings.sndparticle_sampling_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-wavecrest"),
("bpy.types.lineartgpencilmodifier.use_image_boundary_trimming*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-image-boundary-trimming"),
("bpy.types.materiallineart.use_intersection_priority_override*", "render/materials/line_art.html#bpy-types-materiallineart-use-intersection-priority-override"),
@@ -179,6 +180,7 @@ url_manual_mapping = (
("bpy.types.brushgpencilsettings.use_random_press_hue*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-hue"),
("bpy.types.brushgpencilsettings.use_random_press_sat*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-sat"),
("bpy.types.brushgpencilsettings.use_random_press_val*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-val"),
+ ("bpy.types.brushgpencilsettings.use_settings_outline*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-settings-outline"),
("bpy.types.brushgpencilsettings.use_stroke_random_uv*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-uv"),
("bpy.types.cyclesmaterialsettings.homogeneous_volume*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-homogeneous-volume"),
("bpy.types.cyclesobjectsettings.is_caustics_receiver*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-is-caustics-receiver"),
@@ -203,12 +205,14 @@ url_manual_mapping = (
("bpy.types.materialgpencilstyle.use_fill_texture_mix*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-use-fill-texture-mix"),
("bpy.types.rendersettings_simplify_gpencil_shader_fx*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-shader-fx"),
("bpy.types.rendersettings_simplify_gpencil_view_fill*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-view-fill"),
+ ("bpy.types.sculpt.use_automasking_boundary_face_sets*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-use-automasking-boundary-face-sets"),
("bpy.types.sequencertoolsettings.snap_to_hold_offset*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-snap-to-hold-offset"),
("bpy.types.toolsettings.use_mesh_automerge_and_split*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-mesh-automerge-and-split"),
("bpy.ops.scene.view_layer_remove_unused_lightgroups*", "render/layers/passes.html#bpy-ops-scene-view-layer-remove-unused-lightgroups"),
("bpy.types.animvizmotionpaths.show_keyframe_numbers*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-show-keyframe-numbers"),
("bpy.types.brush.cloth_constraint_softbody_strength*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-constraint-softbody-strength"),
("bpy.types.brush.elastic_deform_volume_preservation*", "sculpt_paint/sculpting/tools/elastic_deform.html#bpy-types-brush-elastic-deform-volume-preservation"),
+ ("bpy.types.brush.use_automasking_boundary_face_sets*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-use-automasking-boundary-face-sets"),
("bpy.types.brushcurvessculptsettings.minimum_length*", "sculpt_paint/curves_sculpting/tools/grow_shrink_curves.html#bpy-types-brushcurvessculptsettings-minimum-length"),
("bpy.types.brushgpencilsettings.fill_simplify_level*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-simplify-level"),
("bpy.types.brushgpencilsettings.random_value_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-value-factor"),
@@ -241,6 +245,7 @@ url_manual_mapping = (
("bpy.types.spacespreadsheet.geometry_component_type*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-geometry-component-type"),
("bpy.types.toolsettings.use_gpencil_weight_data_add*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-weight-data-add"),
("bpy.types.view3doverlay.texture_paint_mode_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-texture-paint-mode-opacity"),
+ ("bpy.ops.mesh.customdata_bevel_weight_vertex_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-bevel-weight-vertex-clear"),
("bpy.ops.mesh.customdata_custom_splitnormals_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-custom-splitnormals-clear"),
("bpy.types.bakesettings.use_pass_ambient_occlusion*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-ambient-occlusion"),
("bpy.types.brush.surface_smooth_shape_preservation*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-shape-preservation"),
@@ -344,9 +349,12 @@ url_manual_mapping = (
("bpy.types.toolsettings.use_snap_uv_grid_absolute*", "editors/uv/controls/snapping.html#bpy-types-toolsettings-use-snap-uv-grid-absolute"),
("bpy.types.toolsettings.use_transform_data_origin*", "scene_layout/object/tools/tool_settings.html#bpy-types-toolsettings-use-transform-data-origin"),
("bpy.types.view3doverlay.sculpt_mode_mask_opacity*", "sculpt_paint/sculpting/editing/mask.html#bpy-types-view3doverlay-sculpt-mode-mask-opacity"),
+ ("bpy.ops.mesh.customdata_bevel_weight_edge_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-bevel-weight-edge-clear"),
+ ("bpy.ops.mesh.customdata_bevel_weight_vertex_add*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-bevel-weight-vertex-add"),
("bpy.ops.mesh.customdata_custom_splitnormals_add*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-custom-splitnormals-add"),
("bpy.ops.outliner.collection_indirect_only_clear*", "render/layers/introduction.html#bpy-ops-outliner-collection-indirect-only-clear"),
("bpy.types.animvizmotionpaths.show_frame_numbers*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-show-frame-numbers"),
+ ("bpy.types.brushgpencilsettings.fill_extend_mode*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-extend-mode"),
("bpy.types.brushgpencilsettings.pen_smooth_steps*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-smooth-steps"),
("bpy.types.brushgpencilsettings.show_fill_extend*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-show-fill-extend"),
("bpy.types.cycleslightsettings.is_caustics_light*", "render/cycles/light_settings.html#bpy-types-cycleslightsettings-is-caustics-light"),
@@ -384,6 +392,7 @@ url_manual_mapping = (
("bpy.types.movietrackingplanetrack.image_opacity*", "movie_clip/tracking/clip/sidebar/track/plane_track.html#bpy-types-movietrackingplanetrack-image-opacity"),
("bpy.types.particlesettings.use_parent_particles*", "physics/particles/emitter/render.html#bpy-types-particlesettings-use-parent-particles"),
("bpy.types.rigidbodyconstraint.solver_iterations*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-solver-iterations"),
+ ("bpy.types.sculpt.use_automasking_boundary_edges*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-use-automasking-boundary-edges"),
("bpy.types.sequenceeditor.use_overlay_frame_lock*", "editors/video_sequencer/preview/sidebar.html#bpy-types-sequenceeditor-use-overlay-frame-lock"),
("bpy.types.sequencerpreviewoverlay.show_metadata*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-metadata"),
("bpy.types.sequencertimelineoverlay.show_fcurves*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-fcurves"),
@@ -398,6 +407,7 @@ url_manual_mapping = (
("bpy.types.viewlayer.use_pass_cryptomatte_object*", "render/layers/passes.html#bpy-types-viewlayer-use-pass-cryptomatte-object"),
("bpy.ops.armature.rigify_apply_selection_colors*", "addons/rigging/rigify/metarigs.html#bpy-ops-armature-rigify-apply-selection-colors"),
("bpy.ops.ed.lib_id_generate_preview_from_object*", "editors/asset_browser.html#bpy-ops-ed-lib-id-generate-preview-from-object"),
+ ("bpy.types.brush.use_automasking_boundary_edges*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-use-automasking-boundary-edges"),
("bpy.types.brushcurvessculptsettings.add_amount*", "sculpt_paint/curves_sculpting/tools/add_curves.html#bpy-types-brushcurvessculptsettings-add-amount"),
("bpy.types.brushgpencilsettings.fill_layer_mode*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-layer-mode"),
("bpy.types.brushgpencilsettings.random_strength*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-strength"),
@@ -444,6 +454,7 @@ url_manual_mapping = (
("bpy.types.toolsettings.use_snap_align_rotation*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-align-rotation"),
("bpy.types.toolsettings.use_snap_to_same_target*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-to-same-target"),
("bpy.types.viewlayer.use_pass_cryptomatte_asset*", "render/layers/passes.html#bpy-types-viewlayer-use-pass-cryptomatte-asset"),
+ ("bpy.ops.mesh.customdata_bevel_weight_edge_add*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-bevel-weight-edge-add"),
("bpy.ops.outliner.collection_indirect_only_set*", "render/layers/introduction.html#bpy-ops-outliner-collection-indirect-only-set"),
("bpy.ops.scene.freestyle_geometry_modifier_add*", "render/freestyle/view_layer/line_style/geometry.html#bpy-ops-scene-freestyle-geometry-modifier-add"),
("bpy.ops.scene.view_layer_add_used_lightgroups*", "render/layers/passes.html#bpy-ops-scene-view-layer-add-used-lightgroups"),
@@ -574,6 +585,8 @@ url_manual_mapping = (
("bpy.types.toolsettings.uv_sticky_select_mode*", "editors/uv/selecting.html#bpy-types-toolsettings-uv-sticky-select-mode"),
("bpy.types.volumedisplay.interpolation_method*", "modeling/volumes/properties.html#bpy-types-volumedisplay-interpolation-method"),
("bpy.ops.geometry.color_attribute_render_set*", "modeling/meshes/properties/object_data.html#bpy-ops-geometry-color-attribute-render-set"),
+ ("bpy.ops.mesh.customdata_crease_vertex_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-crease-vertex-clear"),
+ ("bpy.types.brush.html#bpy.types.brush.jitter*", "sculpt_paint/brush/stroke.html#bpy-types-brush-html-bpy-types-brush-jitter"),
("bpy.types.brushgpencilsettings.angle_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle-factor"),
("bpy.types.brushgpencilsettings.pen_strength*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-pen-strength"),
("bpy.types.clothsettings.use_pressure_volume*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-use-pressure-volume"),
@@ -600,6 +613,7 @@ url_manual_mapping = (
("bpy.types.geometrynodeinputmeshedgevertices*", "modeling/geometry_nodes/mesh/edge_vertices.html#bpy-types-geometrynodeinputmeshedgevertices"),
("bpy.types.geometrynodeinputmeshfaceisplanar*", "modeling/geometry_nodes/mesh/face_is_planar.html#bpy-types-geometrynodeinputmeshfaceisplanar"),
("bpy.types.geometrynodeinputsplineresolution*", "modeling/geometry_nodes/curve/spline_resolution.html#bpy-types-geometrynodeinputsplineresolution"),
+ ("bpy.types.geometrynodemeshfacesetboundaries*", "modeling/geometry_nodes/mesh/face_set_boundaries.html#bpy-types-geometrynodemeshfacesetboundaries"),
("bpy.types.greasepencil.curve_edit_threshold*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-threshold"),
("bpy.types.lineartgpencilmodifier.use_crease*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-crease"),
("bpy.types.lineartgpencilmodifier.use_shadow*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-shadow"),
@@ -678,13 +692,13 @@ url_manual_mapping = (
("bpy.types.lineartgpencilmodifier.use_cache*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-cache"),
("bpy.types.lineartgpencilmodifier.use_loose*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-loose"),
("bpy.types.materialgpencilstyle.show_stroke*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-show-stroke"),
- ("bpy.types.mesh.use_customdata_vertex_bevel*", "modeling/meshes/properties/custom_data.html#bpy-types-mesh-use-customdata-vertex-bevel"),
("bpy.types.movietrackingcamera.focal_length*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-focal-length"),
("bpy.types.movietrackingcamera.pixel_aspect*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-pixel-aspect"),
("bpy.types.movietrackingcamera.sensor_width*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-sensor-width"),
("bpy.types.posebone.use_ik_rotation_control*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-use-ik-rotation-control"),
("bpy.types.rendersettings.use_bake_multires*", "render/cycles/baking.html#bpy-types-rendersettings-use-bake-multires"),
("bpy.types.scenegpencil.antialias_threshold*", "render/cycles/render_settings/grease_pencil.html#bpy-types-scenegpencil-antialias-threshold"),
+ ("bpy.types.sculpt.use_automasking_face_sets*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-use-automasking-face-sets"),
("bpy.types.spaceclipeditor.show_mask_spline*", "editors/clip/display/mask_display.html#bpy-types-spaceclipeditor-show-mask-spline"),
("bpy.types.spaceclipeditor.show_red_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-red-channel"),
("bpy.types.spaceclipeditor.use_mute_footage*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-mute-footage"),
@@ -698,6 +712,8 @@ url_manual_mapping = (
("bpy.ops.constraint.disable_keep_transform*", "animation/constraints/interface/common.html#bpy-ops-constraint-disable-keep-transform"),
("bpy.ops.curves.convert_to_particle_system*", "sculpt_paint/curves_sculpting/introduction.html#bpy-ops-curves-convert-to-particle-system"),
("bpy.ops.gpencil.stroke_reset_vertex_color*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-stroke-reset-vertex-color"),
+ ("bpy.ops.mesh.customdata_crease_edge_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-crease-edge-clear"),
+ ("bpy.ops.mesh.customdata_crease_vertex_add*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-crease-vertex-add"),
("bpy.ops.object.modifier_apply_as_shapekey*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-apply-as-shapekey"),
("bpy.ops.object.vertex_group_normalize_all*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-normalize-all"),
("bpy.ops.outliner.collection_color_tag_set*", "editors/outliner/editing.html#bpy-ops-outliner-collection-color-tag-set"),
@@ -709,6 +725,7 @@ url_manual_mapping = (
("bpy.types.animvizmotionpaths.frame_before*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-before"),
("bpy.types.brush.disconnected_distance_max*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-disconnected-distance-max"),
("bpy.types.brush.surface_smooth_iterations*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-iterations"),
+ ("bpy.types.brush.use_automasking_face_sets*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-use-automasking-face-sets"),
("bpy.types.brushgpencilsettings.pen_jitter*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-jitter"),
("bpy.types.brushgpencilsettings.show_lasso*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-show-lasso"),
("bpy.types.compositornodeconvertcolorspace*", "compositing/types/converter/color_space.html#bpy-types-compositornodeconvertcolorspace"),
@@ -753,7 +770,6 @@ url_manual_mapping = (
("bpy.types.materialgpencilstyle.fill_style*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-fill-style"),
("bpy.types.materialgpencilstyle.mix_factor*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-mix-factor"),
("bpy.types.materialgpencilstyle.pass_index*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-pass-index"),
- ("bpy.types.mesh.use_customdata_edge_crease*", "modeling/meshes/properties/custom_data.html#bpy-types-mesh-use-customdata-edge-crease"),
("bpy.types.nodesocketinterface.description*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-description"),
("bpy.types.rendersettings.dither_intensity*", "render/output/properties/post_processing.html#bpy-types-rendersettings-dither-intensity"),
("bpy.types.rendersettings.film_transparent*", "render/cycles/render_settings/film.html#bpy-types-rendersettings-film-transparent"),
@@ -761,6 +777,7 @@ url_manual_mapping = (
("bpy.types.rendersettings.use_render_cache*", "render/output/properties/output.html#bpy-types-rendersettings-use-render-cache"),
("bpy.types.rendersettings.use_single_layer*", "render/layers/view_layer.html#bpy-types-rendersettings-use-single-layer"),
("bpy.types.sceneeevee.use_taa_reprojection*", "render/eevee/render_settings/sampling.html#bpy-types-sceneeevee-use-taa-reprojection"),
+ ("bpy.types.sculpt.use_automasking_topology*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-use-automasking-topology"),
("bpy.types.spaceclipeditor.cursor_location*", "editors/clip/sidebar.html#bpy-types-spaceclipeditor-cursor-location"),
("bpy.types.spacefilebrowser.recent_folders*", "editors/file_browser.html#bpy-types-spacefilebrowser-recent-folders"),
("bpy.types.spacefilebrowser.system_folders*", "editors/file_browser.html#bpy-types-spacefilebrowser-system-folders"),
@@ -789,10 +806,11 @@ url_manual_mapping = (
("bpy.types.animvizmotionpaths.frame_start*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-start"),
("bpy.types.bakesettings.use_pass_indirect*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-indirect"),
("bpy.types.brush.cloth_force_falloff_type*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-force-falloff-type"),
+ ("bpy.types.brush.use_automasking_topology*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-use-automasking-topology"),
("bpy.types.brushgpencilsettings.caps_type*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-caps-type"),
- ("bpy.types.brushgpencilsettings.fill_leak*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-leak"),
("bpy.types.brushgpencilsettings.show_fill*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-show-fill"),
("bpy.types.brushgpencilsettings.uv_random*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-uv-random"),
+ ("bpy.types.brushtextureslot.mask_map_mode*", "sculpt_paint/brush/texture_mask.html#bpy-types-brushtextureslot-mask-map-mode"),
("bpy.types.clothsettings.internal_tension*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-tension"),
("bpy.types.colormanagedviewsettings.gamma*", "render/color_management.html#bpy-types-colormanagedviewsettings-gamma"),
("bpy.types.compositornodeplanetrackdeform*", "compositing/types/distort/plane_track_deform.html#bpy-types-compositornodeplanetrackdeform"),
@@ -801,7 +819,7 @@ url_manual_mapping = (
("bpy.types.editbone.bbone_handle_type_end*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-type-end"),
("bpy.types.editbone.use_endroll_as_inroll*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-use-endroll-as-inroll"),
("bpy.types.fieldsettings.guide_kink_shape*", "physics/forces/force_fields/types/curve_guide.html#bpy-types-fieldsettings-guide-kink-shape"),
- ("bpy.types.fieldsettings.use_max_distance*", "physics/forces/force_fields/types/curve_guide.html#bpy-types-fieldsettings-use-max-distance"),
+ ("bpy.types.fieldsettings.use_max_distance*", "physics/forces/force_fields/introduction.html#bpy-types-fieldsettings-use-max-distance"),
("bpy.types.fieldsettings.use_min_distance*", "physics/forces/force_fields/introduction.html#bpy-types-fieldsettings-use-min-distance"),
("bpy.types.fileselectparams.filter_search*", "editors/file_browser.html#bpy-types-fileselectparams-filter-search"),
("bpy.types.fluiddomainsettings.cache_type*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-type"),
@@ -837,7 +855,6 @@ url_manual_mapping = (
("bpy.types.material.use_screen_refraction*", "render/eevee/materials/settings.html#bpy-types-material-use-screen-refraction"),
("bpy.types.materialgpencilstyle.mix_color*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-mix-color"),
("bpy.types.materialgpencilstyle.show_fill*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-show-fill"),
- ("bpy.types.mesh.use_customdata_edge_bevel*", "modeling/meshes/properties/custom_data.html#bpy-types-mesh-use-customdata-edge-bevel"),
("bpy.types.mesh.use_mirror_vertex_group_x*", "sculpt_paint/weight_paint/tool_settings/symmetry.html#bpy-types-mesh-use-mirror-vertex-group-x"),
("bpy.types.movietrackingcamera.division_k*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-division-k"),
("bpy.types.movietrackingobject.keyframe_a*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingobject-keyframe-a"),
@@ -858,6 +875,7 @@ url_manual_mapping = (
("bpy.types.spaceoutliner.show_mode_column*", "editors/outliner/interface.html#bpy-types-spaceoutliner-show-mode-column"),
("bpy.types.spacesequenceeditor.show_gizmo*", "editors/video_sequencer/preview/display/gizmos.html#bpy-types-spacesequenceeditor-show-gizmo"),
("bpy.types.spacetexteditor.use_match_case*", "editors/text_editor.html#bpy-types-spacetexteditor-use-match-case"),
+ ("bpy.types.spaceuveditor.pixel_round_mode*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-pixel-round-mode"),
("bpy.types.spaceview3d.show_object_select*", "editors/3dview/display/visibility.html#bpy-types-spaceview3d-show-object-select"),
("bpy.types.toolsettings.use_lock_relative*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-toolsettings-use-lock-relative"),
("bpy.types.vertexpaint.use_group_restrict*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-vertexpaint-use-group-restrict"),
@@ -865,6 +883,7 @@ url_manual_mapping = (
("bpy.types.windowmanager.asset_path_dummy*", "editors/asset_browser.html#bpy-types-windowmanager-asset-path-dummy"),
("bpy.ops.armature.rigify_add_bone_groups*", "addons/rigging/rigify/metarigs.html#bpy-ops-armature-rigify-add-bone-groups"),
("bpy.ops.geometry.color_attribute_remove*", "modeling/meshes/properties/object_data.html#bpy-ops-geometry-color-attribute-remove"),
+ ("bpy.ops.mesh.customdata_crease_edge_add*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-crease-edge-add"),
("bpy.ops.object.assign_property_defaults*", "animation/armatures/posing/editing/apply.html#bpy-ops-object-assign-property-defaults"),
("bpy.ops.object.vertex_group_limit_total*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-limit-total"),
("bpy.ops.object.vertex_group_remove_from*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-remove-from"),
@@ -872,6 +891,7 @@ url_manual_mapping = (
("bpy.ops.outliner.collection_hide_inside*", "editors/outliner/editing.html#bpy-ops-outliner-collection-hide-inside"),
("bpy.ops.outliner.collection_holdout_set*", "render/layers/introduction.html#bpy-ops-outliner-collection-holdout-set"),
("bpy.ops.outliner.collection_show_inside*", "editors/outliner/editing.html#bpy-ops-outliner-collection-show-inside"),
+ ("bpy.ops.poselib.pose_asset_select_bones*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-asset-select-bones"),
("bpy.ops.poselib.restore_previous_action*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-restore-previous-action"),
("bpy.ops.preferences.reset_default_theme*", "editors/preferences/themes.html#bpy-ops-preferences-reset-default-theme"),
("bpy.ops.scene.view_layer_add_lightgroup*", "render/layers/passes.html#bpy-ops-scene-view-layer-add-lightgroup"),
@@ -885,6 +905,7 @@ url_manual_mapping = (
("bpy.types.brush.multiplane_scrape_angle*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-multiplane-scrape-angle"),
("bpy.types.brushgpencilsettings.hardness*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-hardness"),
("bpy.types.brushgpencilsettings.use_trim*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-trim"),
+ ("bpy.types.brushtextureslot.random_angle*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot-random-angle"),
("bpy.types.clothsettings.internal_spring*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-spring"),
("bpy.types.clothsettings.pressure_factor*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-pressure-factor"),
("bpy.types.colormanagedviewsettings.look*", "render/color_management.html#bpy-types-colormanagedviewsettings-look"),
@@ -920,6 +941,7 @@ url_manual_mapping = (
("bpy.types.geometrynodeinputsplinecyclic*", "modeling/geometry_nodes/curve/is_spline_cyclic.html#bpy-types-geometrynodeinputsplinecyclic"),
("bpy.types.geometrynodeinstancestopoints*", "modeling/geometry_nodes/instances/instances_to_points.html#bpy-types-geometrynodeinstancestopoints"),
("bpy.types.gpencillayer.viewlayer_render*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-viewlayer-render"),
+ ("bpy.types.imagepaint.use_normal_falloff*", "sculpt_paint/brush/falloff.html#bpy-types-imagepaint-use-normal-falloff"),
("bpy.types.layercollection.hide_viewport*", "editors/outliner/interface.html#bpy-types-layercollection-hide-viewport"),
("bpy.types.layercollection.indirect_only*", "editors/outliner/interface.html#bpy-types-layercollection-indirect-only"),
("bpy.types.material.use_backface_culling*", "render/eevee/materials/settings.html#bpy-types-material-use-backface-culling"),
@@ -941,7 +963,6 @@ url_manual_mapping = (
("bpy.types.spacesequenceeditor.view_type*", "editors/video_sequencer/introduction.html#bpy-types-spacesequenceeditor-view-type"),
("bpy.types.spacetexteditor.margin_column*", "editors/text_editor.html#bpy-types-spacetexteditor-margin-column"),
("bpy.types.spacetexteditor.use_find_wrap*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-wrap"),
- ("bpy.types.spaceuveditor.pixel_snap_mode*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-pixel-snap-mode"),
("bpy.types.spaceuveditor.tile_grid_shape*", "editors/uv/overlays.html#bpy-types-spaceuveditor-tile-grid-shape"),
("bpy.types.spaceuveditor.use_custom_grid*", "editors/uv/overlays.html#bpy-types-spaceuveditor-use-custom-grid"),
("bpy.types.spaceuveditor.use_live_unwrap*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-use-live-unwrap"),
@@ -955,7 +976,9 @@ url_manual_mapping = (
("bpy.types.vertexweightproximitymodifier*", "modeling/modifiers/modify/weight_proximity.html#bpy-types-vertexweightproximitymodifier"),
("bpy.types.view3doverlay.show_wireframes*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-wireframes"),
("bpy.types.view3dshading.background_type*", "editors/3dview/display/shading.html#bpy-types-view3dshading-background-type"),
+ ("bpy.types.windowmanager.poselib_flipped*", "animation/armatures/posing/editing/pose_library.html#bpy-types-windowmanager-poselib-flipped"),
("bpy.types.workspace.use_filter_by_owner*", "interface/window_system/workspaces.html#bpy-types-workspace-use-filter-by-owner"),
+ ("bpy.ops.brush.stencil_fit_image_aspect*", "sculpt_paint/brush/texture.html#bpy-ops-brush-stencil-fit-image-aspect"),
("bpy.ops.gpencil.image_to_grease_pencil*", "editors/image/editing.html#bpy-ops-gpencil-image-to-grease-pencil"),
("bpy.ops.mesh.vertices_smooth_laplacian*", "modeling/meshes/editing/vertex/laplacian_smooth.html#bpy-ops-mesh-vertices-smooth-laplacian"),
("bpy.ops.object.multires_rebuild_subdiv*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-rebuild-subdiv"),
@@ -1033,6 +1056,7 @@ url_manual_mapping = (
("bpy.types.volumedisplay.wireframe_type*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-type"),
("bpy.ops.anim.channels_editable_toggle*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-editable-toggle"),
("bpy.ops.anim.channels_setting_disable*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-setting-disable"),
+ ("bpy.ops.brush.stencil_reset_transform*", "sculpt_paint/brush/texture.html#bpy-ops-brush-stencil-reset-transform"),
("bpy.ops.curve.normals_make_consistent*", "modeling/curves/editing/control_points.html#bpy-ops-curve-normals-make-consistent"),
("bpy.ops.curves.snap_curves_to_surface*", "sculpt_paint/curves_sculpting/introduction.html#bpy-ops-curves-snap-curves-to-surface"),
("bpy.ops.ed.lib_id_load_custom_preview*", "editors/asset_browser.html#bpy-ops-ed-lib-id-load-custom-preview"),
@@ -1061,9 +1085,11 @@ url_manual_mapping = (
("bpy.types.brush.boundary_falloff_type*", "sculpt_paint/sculpting/tools/boundary.html#bpy-types-brush-boundary-falloff-type"),
("bpy.types.brush.cursor_color_subtract*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-color-subtract"),
("bpy.types.brush.texture_overlay_alpha*", "sculpt_paint/brush/cursor.html#bpy-types-brush-texture-overlay-alpha"),
+ ("bpy.types.brush.use_space_attenuation*", "sculpt_paint/brush/stroke.html#bpy-types-brush-use-space-attenuation"),
("bpy.types.brushgpencilsettings.aspect*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-aspect"),
("bpy.types.brushgpencilsettings.dilate*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-dilate"),
("bpy.types.brushgpencilsettings.random*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random"),
+ ("bpy.types.brushtextureslot.use_random*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot-use-random"),
("bpy.types.clothsettings.target_volume*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-target-volume"),
("bpy.types.colormanageddisplaysettings*", "render/color_management.html#bpy-types-colormanageddisplaysettings"),
("bpy.types.colorramp.hue_interpolation*", "interface/controls/templates/color_ramp.html#bpy-types-colorramp-hue-interpolation"),
@@ -1076,7 +1102,7 @@ url_manual_mapping = (
("bpy.types.editbone.use_local_location*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-use-local-location"),
("bpy.types.ffmpegsettings.audio_volume*", "render/output/properties/output.html#bpy-types-ffmpegsettings-audio-volume"),
("bpy.types.ffmpegsettings.max_b_frames*", "render/output/properties/output.html#bpy-types-ffmpegsettings-max-b-frames"),
- ("bpy.types.fieldsettings.falloff_power*", "physics/forces/force_fields/types/curve_guide.html#bpy-types-fieldsettings-falloff-power"),
+ ("bpy.types.fieldsettings.falloff_power*", "physics/forces/force_fields/introduction.html#bpy-types-fieldsettings-falloff-power"),
("bpy.types.fieldsettings.guide_minimum*", "physics/forces/force_fields/types/curve_guide.html#bpy-types-fieldsettings-guide-minimum"),
("bpy.types.fileselectparams.use_filter*", "editors/file_browser.html#bpy-types-fileselectparams-use-filter"),
("bpy.types.fluiddomainsettings.gravity*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-gravity"),
@@ -1140,6 +1166,7 @@ url_manual_mapping = (
("bpy.ops.mesh.normals_make_consistent*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-normals-make-consistent"),
("bpy.ops.mesh.offset_edge_loops_slide*", "modeling/meshes/editing/edge/offset_edge_slide.html#bpy-ops-mesh-offset-edge-loops-slide"),
("bpy.ops.mesh.primitive_uv_sphere_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-uv-sphere-add"),
+ ("bpy.ops.object.curves_empty_hair_add*", "modeling/curves/primitives.html#bpy-ops-object-curves-empty-hair-add"),
("bpy.ops.object.duplicate_move_linked*", "scene_layout/object/editing/duplicate_linked.html#bpy-ops-object-duplicate-move-linked"),
("bpy.ops.object.make_override_library*", "files/linked_libraries/library_overrides.html#bpy-ops-object-make-override-library"),
("bpy.ops.object.parent_no_inverse_set*", "scene_layout/object/editing/parent.html#bpy-ops-object-parent-no-inverse-set"),
@@ -1157,10 +1184,12 @@ url_manual_mapping = (
("bpy.types.brush.boundary_deform_type*", "sculpt_paint/sculpting/tools/boundary.html#bpy-types-brush-boundary-deform-type"),
("bpy.types.brush.cursor_overlay_alpha*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-overlay-alpha"),
("bpy.types.brush.normal_radius_factor*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-normal-radius-factor"),
- ("bpy.types.brush.smooth_stroke_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brush-smooth-stroke-factor"),
- ("bpy.types.brush.smooth_stroke_radius*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brush-smooth-stroke-radius"),
+ ("bpy.types.brush.smooth_stroke_factor*", "sculpt_paint/brush/stroke.html#bpy-types-brush-smooth-stroke-factor"),
+ ("bpy.types.brush.smooth_stroke_radius*", "sculpt_paint/brush/stroke.html#bpy-types-brush-smooth-stroke-radius"),
("bpy.types.brush.topology_rake_factor*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-brush-topology-rake-factor"),
("bpy.types.brush.use_pose_ik_anchored*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-use-pose-ik-anchored"),
+ ("bpy.types.brush.use_pressure_masking*", "sculpt_paint/brush/texture_mask.html#bpy-types-brush-use-pressure-masking"),
+ ("bpy.types.brush.use_pressure_spacing*", "sculpt_paint/brush/stroke.html#bpy-types-brush-use-pressure-spacing"),
("bpy.types.brushgpencilsettings.angle*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle"),
("bpy.types.clothsettings.use_pressure*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-use-pressure"),
("bpy.types.compositornodeantialiasing*", "compositing/types/filter/anti_aliasing.html#bpy-types-compositornodeantialiasing"),
@@ -1170,7 +1199,7 @@ url_manual_mapping = (
("bpy.types.compositornodekeyingscreen*", "compositing/types/matte/keying_screen.html#bpy-types-compositornodekeyingscreen"),
("bpy.types.dynamicpaintcanvassettings*", "physics/dynamic_paint/canvas.html#bpy-types-dynamicpaintcanvassettings"),
("bpy.types.ffmpegsettings.audio_codec*", "render/output/properties/output.html#bpy-types-ffmpegsettings-audio-codec"),
- ("bpy.types.fieldsettings.distance_max*", "physics/forces/force_fields/types/curve_guide.html#bpy-types-fieldsettings-distance-max"),
+ ("bpy.types.fieldsettings.distance_max*", "physics/forces/force_fields/introduction.html#bpy-types-fieldsettings-distance-max"),
("bpy.types.fieldsettings.distance_min*", "physics/forces/force_fields/introduction.html#bpy-types-fieldsettings-distance-min"),
("bpy.types.fieldsettings.falloff_type*", "physics/forces/force_fields/introduction.html#bpy-types-fieldsettings-falloff-type"),
("bpy.types.fileselectparams.directory*", "editors/file_browser.html#bpy-types-fileselectparams-directory"),
@@ -1198,7 +1227,7 @@ url_manual_mapping = (
("bpy.types.object.display_bounds_type*", "scene_layout/object/properties/display.html#bpy-types-object-display-bounds-type"),
("bpy.types.object.show_only_shape_key*", "animation/shape_keys/shape_keys_panel.html#bpy-types-object-show-only-shape-key"),
("bpy.types.regionview3d.lock_rotation*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-lock-rotation"),
- ("bpy.types.rendersettings.hair_subdiv*", "render/cycles/render_settings/hair.html#bpy-types-rendersettings-hair-subdiv"),
+ ("bpy.types.rendersettings.hair_subdiv*", "render/eevee/render_settings/hair.html#bpy-types-rendersettings-hair-subdiv"),
("bpy.types.scene.audio_distance_model*", "scene_layout/scene/properties.html#bpy-types-scene-audio-distance-model"),
("bpy.types.scene.audio_doppler_factor*", "scene_layout/scene/properties.html#bpy-types-scene-audio-doppler-factor"),
("bpy.types.sequencetransform.rotation*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencetransform-rotation"),
@@ -1251,11 +1280,15 @@ url_manual_mapping = (
("bpy.types.bakesettings.normal_space*", "render/cycles/baking.html#bpy-types-bakesettings-normal-space"),
("bpy.types.brush.crease_pinch_factor*", "sculpt_paint/sculpting/tools/snake_hook.html#bpy-types-brush-crease-pinch-factor"),
("bpy.types.brush.elastic_deform_type*", "sculpt_paint/sculpting/tools/elastic_deform.html#bpy-types-brush-elastic-deform-type"),
+ ("bpy.types.brush.texture_sample_bias*", "sculpt_paint/brush/texture.html#bpy-types-brush-texture-sample-bias"),
("bpy.types.brush.use_cloth_collision*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-use-cloth-collision"),
("bpy.types.brush.use_grab_silhouette*", "sculpt_paint/sculpting/tools/grab.html#bpy-types-brush-use-grab-silhouette"),
+ ("bpy.types.brush.use_original_normal*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-use-original-normal"),
+ ("bpy.types.brush.use_pressure_jitter*", "sculpt_paint/brush/stroke.html#bpy-types-brush-use-pressure-jitter"),
("bpy.types.brush.use_primary_overlay*", "sculpt_paint/brush/cursor.html#bpy-types-brush-use-primary-overlay"),
("bpy.types.brushcurvessculptsettings*", "sculpt_paint/curves_sculpting/index.html#bpy-types-brushcurvessculptsettings"),
("bpy.types.brushtextureslot.map_mode*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot-map-mode"),
+ ("bpy.types.brushtextureslot.use_rake*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot-use-rake"),
("bpy.types.camera.passepartout_alpha*", "render/cameras.html#bpy-types-camera-passepartout-alpha"),
("bpy.types.colorrampelement.position*", "interface/controls/templates/color_ramp.html#bpy-types-colorrampelement-position"),
("bpy.types.compositornodechromamatte*", "compositing/types/matte/chroma_key.html#bpy-types-compositornodechromamatte"),
@@ -1370,6 +1403,7 @@ url_manual_mapping = (
("bpy.types.brush.smooth_deform_type*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-smooth-deform-type"),
("bpy.types.brush.use_connected_only*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-use-connected-only"),
("bpy.types.brush.use_cursor_overlay*", "sculpt_paint/brush/cursor.html#bpy-types-brush-use-cursor-overlay"),
+ ("bpy.types.brush.use_original_plane*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-use-original-plane"),
("bpy.types.camera.show_passepartout*", "render/cameras.html#bpy-types-camera-show-passepartout"),
("bpy.types.collection.lineart_usage*", "scene_layout/collections/collections.html#bpy-types-collection-lineart-usage"),
("bpy.types.colormanagedviewsettings*", "render/color_management.html#bpy-types-colormanagedviewsettings"),
@@ -1440,6 +1474,7 @@ url_manual_mapping = (
("bpy.types.transformcacheconstraint*", "animation/constraints/transform/transform_cache.html#bpy-types-transformcacheconstraint"),
("bpy.types.unitsettings.length_unit*", "scene_layout/scene/properties.html#bpy-types-unitsettings-length-unit"),
("bpy.types.vertexweighteditmodifier*", "modeling/modifiers/modify/weight_edit.html#bpy-types-vertexweighteditmodifier"),
+ ("bpy.types.view3dshading.color_type*", "render/workbench/color.html#bpy-types-view3dshading-color-type"),
("bpy.types.volumedisplay.slice_axis*", "modeling/volumes/properties.html#bpy-types-volumedisplay-slice-axis"),
("bpy.ops.action.markers_make_local*", "animation/markers.html#bpy-ops-action-markers-make-local"),
("bpy.ops.anim.channels_clean_empty*", "editors/nla/editing.html#bpy-ops-anim-channels-clean-empty"),
@@ -1458,7 +1493,7 @@ url_manual_mapping = (
("bpy.ops.mask.feather_weight_clear*", "movie_clip/masking/editing.html#bpy-ops-mask-feather-weight-clear"),
("bpy.ops.mask.primitive_circle_add*", "movie_clip/masking/scurve.html#bpy-ops-mask-primitive-circle-add"),
("bpy.ops.mask.primitive_square_add*", "movie_clip/masking/scurve.html#bpy-ops-mask-primitive-square-add"),
- ("bpy.ops.mesh.dupli_extrude_cursor*", "modeling/meshes/tools/extrude_cursor.html#bpy-ops-mesh-dupli-extrude-cursor"),
+ ("bpy.ops.mesh.dupli_extrude_cursor*", "modeling/meshes/editing/vertex/extrude_cursor.html#bpy-ops-mesh-dupli-extrude-cursor"),
("bpy.ops.mesh.primitive_circle_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-circle-add"),
("bpy.ops.mesh.primitive_monkey_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-monkey-add"),
("bpy.ops.mesh.select_face_by_sides*", "modeling/meshes/selecting/all_by_trait.html#bpy-ops-mesh-select-face-by-sides"),
@@ -1486,6 +1521,8 @@ url_manual_mapping = (
("bpy.types.brush.cloth_deform_type*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-deform-type"),
("bpy.types.brush.cloth_sim_falloff*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-sim-falloff"),
("bpy.types.brush.slide_deform_type*", "sculpt_paint/sculpting/tools/slide_relax.html#bpy-types-brush-slide-deform-type"),
+ ("bpy.types.brush.use_scene_spacing*", "sculpt_paint/brush/stroke.html#bpy-types-brush-use-scene-spacing"),
+ ("bpy.types.brush.use_smooth_stroke*", "sculpt_paint/brush/stroke.html#bpy-types-brush-use-smooth-stroke"),
("bpy.types.camera.show_composition*", "render/cameras.html#bpy-types-camera-show-composition"),
("bpy.types.colorramp.interpolation*", "interface/controls/templates/color_ramp.html#bpy-types-colorramp-interpolation"),
("bpy.types.compositornodealphaover*", "compositing/types/color/alpha_over.html#bpy-types-compositornodealphaover"),
@@ -1539,6 +1576,7 @@ url_manual_mapping = (
("bpy.types.gpencilsculptguide.type*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide-type"),
("bpy.types.greasepencil.onion_mode*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-onion-mode"),
("bpy.types.greasepencilgrid.offset*", "grease_pencil/properties/display.html#bpy-types-greasepencilgrid-offset"),
+ ("bpy.types.imagepaint.normal_angle*", "sculpt_paint/brush/falloff.html#bpy-types-imagepaint-normal-angle"),
("bpy.types.laplaciandeformmodifier*", "modeling/modifiers/deform/laplacian_deform.html#bpy-types-laplaciandeformmodifier"),
("bpy.types.laplaciansmoothmodifier*", "modeling/modifiers/deform/laplacian_smooth.html#bpy-types-laplaciansmoothmodifier"),
("bpy.types.layercollection.exclude*", "editors/outliner/interface.html#bpy-types-layercollection-exclude"),
@@ -1577,6 +1615,7 @@ url_manual_mapping = (
("bpy.ops.constraint.move_to_index*", "animation/constraints/interface/header.html#bpy-ops-constraint-move-to-index"),
("bpy.ops.gpencil.frame_clean_fill*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-frame-clean-fill"),
("bpy.ops.gpencil.select_alternate*", "grease_pencil/selecting.html#bpy-ops-gpencil-select-alternate"),
+ ("bpy.ops.gpencil.stroke_start_set*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-start-set"),
("bpy.ops.gpencil.stroke_subdivide*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-subdivide"),
("bpy.ops.gpencil.vertex_color_hsv*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-hsv"),
("bpy.ops.gpencil.vertex_color_set*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-set"),
@@ -1600,6 +1639,8 @@ url_manual_mapping = (
("bpy.ops.outliner.collection_hide*", "editors/outliner/editing.html#bpy-ops-outliner-collection-hide"),
("bpy.ops.outliner.collection_show*", "editors/outliner/editing.html#bpy-ops-outliner-collection-show"),
("bpy.ops.paint.mask_lasso_gesture*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-paint-mask-lasso-gesture"),
+ ("bpy.ops.poselib.apply_pose_asset*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-apply-pose-asset"),
+ ("bpy.ops.poselib.blend_pose_asset*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-blend-pose-asset"),
("bpy.ops.rigidbody.mass_calculate*", "scene_layout/object/editing/rigid_body.html#bpy-ops-rigidbody-mass-calculate"),
("bpy.ops.screen.spacedata_cleanup*", "advanced/operators.html#bpy-ops-screen-spacedata-cleanup"),
("bpy.ops.sculpt.detail_flood_fill*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-ops-sculpt-detail-flood-fill"),
@@ -1620,6 +1661,8 @@ url_manual_mapping = (
("bpy.types.brush.pose_deform_type*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-deform-type"),
("bpy.types.brush.pose_ik_segments*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-ik-segments"),
("bpy.types.brush.pose_origin_type*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-origin-type"),
+ ("bpy.types.brush.use_edge_to_edge*", "sculpt_paint/brush/stroke.html#bpy-types-brush-use-edge-to-edge"),
+ ("bpy.types.brushtextureslot.angle*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot-angle"),
("bpy.types.camerasolverconstraint*", "animation/constraints/motion_tracking/camera_solver.html#bpy-types-camerasolverconstraint"),
("bpy.types.clothcollisionsettings*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings"),
("bpy.types.collection.hide_select*", "editors/outliner/interface.html#bpy-types-collection-hide-select"),
@@ -1681,6 +1724,7 @@ url_manual_mapping = (
("bpy.types.object.visible_diffuse*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-diffuse"),
("bpy.types.objectsolverconstraint*", "animation/constraints/motion_tracking/object_solver.html#bpy-types-objectsolverconstraint"),
("bpy.types.opacitygpencilmodifier*", "grease_pencil/modifiers/color/opacity.html#bpy-types-opacitygpencilmodifier"),
+ ("bpy.types.outlinegpencilmodifier*", "grease_pencil/modifiers/generate/outline.html#bpy-types-outlinegpencilmodifier"),
("bpy.types.particlesystemmodifier*", "physics/particles/index.html#bpy-types-particlesystemmodifier"),
("bpy.types.rendersettings.threads*", "render/cycles/render_settings/performance.html#bpy-types-rendersettings-threads"),
("bpy.types.scenedisplay.render_aa*", "render/workbench/sampling.html#bpy-types-scenedisplay-render-aa"),
@@ -1752,6 +1796,7 @@ url_manual_mapping = (
("bpy.ops.outliner.show_one_level*", "editors/outliner/editing.html#bpy-ops-outliner-show-one-level"),
("bpy.ops.paint.brush_colors_flip*", "sculpt_paint/texture_paint/tool_settings/brush_settings.html#bpy-ops-paint-brush-colors-flip"),
("bpy.ops.paint.weight_from_bones*", "sculpt_paint/weight_paint/editing.html#bpy-ops-paint-weight-from-bones"),
+ ("bpy.ops.paintcurve.delete_point*", "sculpt_paint/brush/stroke.html#bpy-ops-paintcurve-delete-point"),
("bpy.ops.pose.paths_range_update*", "animation/motion_paths.html#bpy-ops-pose-paths-range-update"),
("bpy.ops.poselib.action_sanitize*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-action-sanitize"),
("bpy.ops.preferences.studiolight*", "editors/preferences/lights.html#bpy-ops-preferences-studiolight"),
@@ -1791,7 +1836,7 @@ url_manual_mapping = (
("bpy.types.compositornodevecblur*", "compositing/types/filter/vector_blur.html#bpy-types-compositornodevecblur"),
("bpy.types.curve.use_fill_deform*", "modeling/curves/properties/shape.html#bpy-types-curve-use-fill-deform"),
("bpy.types.curve.use_path_follow*", "modeling/curves/properties/path_animation.html#bpy-types-curve-use-path-follow"),
- ("bpy.types.curves.surface_uv_map*", "sculpt_paint/curves_sculpting/introduction.html#bpy-types-curves-surface-uv-map"),
+ ("bpy.types.curves.surface_uv_map*", "modeling/curves/primitives.html#bpy-types-curves-surface-uv-map"),
("bpy.types.dampedtrackconstraint*", "animation/constraints/tracking/damped_track.html#bpy-types-dampedtrackconstraint"),
("bpy.types.distortednoisetexture*", "render/materials/legacy_textures/types/distorted_noise.html#bpy-types-distortednoisetexture"),
("bpy.types.dopesheet.filter_text*", "editors/graph_editor/channels.html#bpy-types-dopesheet-filter-text"),
@@ -1862,6 +1907,7 @@ url_manual_mapping = (
("bpy.ops.gpencil.duplicate_move*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-duplicate-move"),
("bpy.ops.gpencil.select_grouped*", "grease_pencil/selecting.html#bpy-ops-gpencil-select-grouped"),
("bpy.ops.gpencil.stroke_arrange*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-arrange"),
+ ("bpy.ops.gpencil.stroke_outline*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-outline"),
("bpy.ops.graph.blend_to_default*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-blend-to-default"),
("bpy.ops.graph.equalize_handles*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-equalize-handles"),
("bpy.ops.mball.delete_metaelems*", "modeling/metas/editing.html#bpy-ops-mball-delete-metaelems"),
@@ -2041,7 +2087,9 @@ url_manual_mapping = (
("bpy.types.bakesettings.margin*", "render/cycles/baking.html#bpy-types-bakesettings-margin"),
("bpy.types.bakesettings.target*", "render/cycles/baking.html#bpy-types-bakesettings-target"),
("bpy.types.brush.cloth_damping*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-damping"),
+ ("bpy.types.brush.falloff_shape*", "sculpt_paint/brush/falloff.html#bpy-types-brush-falloff-shape"),
("bpy.types.brush.icon_filepath*", "sculpt_paint/brush/brush.html#bpy-types-brush-icon-filepath"),
+ ("bpy.types.brush.stroke_method*", "sculpt_paint/brush/stroke.html#bpy-types-brush-stroke-method"),
("bpy.types.brush.tip_roundness*", "sculpt_paint/sculpting/tools/clay_strips.html#bpy-types-brush-tip-roundness"),
("bpy.types.camera.display_size*", "render/cameras.html#bpy-types-camera-display-size"),
("bpy.types.camera.sensor_width*", "render/cameras.html#bpy-types-camera-sensor-width"),
@@ -2074,6 +2122,7 @@ url_manual_mapping = (
("bpy.types.mesh.use_paint_mask*", "sculpt_paint/brush/introduction.html#bpy-types-mesh-use-paint-mask"),
("bpy.types.object.display_type*", "scene_layout/object/properties/display.html#bpy-types-object-display-type"),
("bpy.types.objectlineart.usage*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart-usage"),
+ ("bpy.types.paint.input_samples*", "sculpt_paint/brush/stroke.html#bpy-types-paint-input-samples"),
("bpy.types.particledupliweight*", "physics/particles/emitter/vertex_groups.html#bpy-types-particledupliweight"),
("bpy.types.posebone.bone_group*", "animation/armatures/bones/properties/relations.html#bpy-types-posebone-bone-group"),
("bpy.types.poseboneconstraints*", "animation/armatures/posing/bone_constraints/index.html#bpy-types-poseboneconstraints"),
@@ -2109,6 +2158,7 @@ url_manual_mapping = (
("bpy.types.transformconstraint*", "animation/constraints/transform/transformation.html#bpy-types-transformconstraint"),
("bpy.types.triangulatemodifier*", "modeling/modifiers/generate/triangulate.html#bpy-types-triangulatemodifier"),
("bpy.types.unitsettings.system*", "scene_layout/scene/properties.html#bpy-types-unitsettings-system"),
+ ("bpy.types.view3dshading.light*", "render/workbench/lighting.html#bpy-types-view3dshading-light"),
("bpy.types.viewlayer.use_solid*", "render/layers/introduction.html#bpy-types-viewlayer-use-solid"),
("bpy.types.volume.frame_offset*", "modeling/volumes/properties.html#bpy-types-volume-frame-offset"),
("bpy.types.windowmanager.addon*", "editors/preferences/addons.html#bpy-types-windowmanager-addon"),
@@ -2184,6 +2234,8 @@ url_manual_mapping = (
("bpy.types.animvizmotionpaths*", "animation/motion_paths.html#bpy-types-animvizmotionpaths"),
("bpy.types.armature.show_axes*", "animation/armatures/properties/display.html#bpy-types-armature-show-axes"),
("bpy.types.armatureconstraint*", "animation/constraints/relationship/armature.html#bpy-types-armatureconstraint"),
+ ("bpy.types.brush.dash_samples*", "sculpt_paint/brush/stroke.html#bpy-types-brush-dash-samples"),
+ ("bpy.types.brush.sculpt_plane*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-sculpt-plane"),
("bpy.types.compositornodeblur*", "compositing/types/filter/blur_node.html#bpy-types-compositornodeblur"),
("bpy.types.compositornodecrop*", "compositing/types/distort/crop.html#bpy-types-compositornodecrop"),
("bpy.types.compositornodeflip*", "compositing/types/distort/flip.html#bpy-types-compositornodeflip"),
@@ -2242,6 +2294,7 @@ url_manual_mapping = (
("bpy.types.texturenodechecker*", "editors/texture_node/types/patterns/checker.html#bpy-types-texturenodechecker"),
("bpy.types.texturenodetexture*", "editors/texture_node/types/input/texture.html#bpy-types-texturenodetexture"),
("bpy.types.texturenodetexwood*", "editors/texture_node/types/textures/wood.html#bpy-types-texturenodetexwood"),
+ ("bpy.types.textureslot.offset*", "sculpt_paint/brush/texture.html#bpy-types-textureslot-offset"),
("bpy.types.view3dshading.type*", "editors/3dview/display/shading.html#bpy-types-view3dshading-type"),
("bpy.types.volume.frame_start*", "modeling/volumes/properties.html#bpy-types-volume-frame-start"),
("bpy.types.volume.is_sequence*", "modeling/volumes/properties.html#bpy-types-volume-is-sequence"),
@@ -2320,6 +2373,7 @@ url_manual_mapping = (
("bpy.types.action.use_cyclic*", "animation/actions.html#bpy-types-action-use-cyclic"),
("bpy.types.alphaoversequence*", "video_editing/edit/montage/strips/effects/alpha_over_under_overdrop.html#bpy-types-alphaoversequence"),
("bpy.types.armatureeditbones*", "animation/armatures/bones/editing/index.html#bpy-types-armatureeditbones"),
+ ("bpy.types.brush.jitter_unit*", "sculpt_paint/brush/stroke.html#bpy-types-brush-jitter-unit"),
("bpy.types.brush.pose_offset*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-offset"),
("bpy.types.brush.rake_factor*", "sculpt_paint/sculpting/tools/snake_hook.html#bpy-types-brush-rake-factor"),
("bpy.types.camera.sensor_fit*", "render/cameras.html#bpy-types-camera-sensor-fit"),
@@ -2374,6 +2428,7 @@ url_manual_mapping = (
("bpy.types.texturenodeoutput*", "editors/texture_node/types/output/output.html#bpy-types-texturenodeoutput"),
("bpy.types.texturenoderotate*", "editors/texture_node/types/distort/rotate.html#bpy-types-texturenoderotate"),
("bpy.types.texturenodeviewer*", "editors/texture_node/types/output/viewer.html#bpy-types-texturenodeviewer"),
+ ("bpy.types.textureslot.scale*", "sculpt_paint/brush/texture.html#bpy-types-textureslot-scale"),
("bpy.types.tracktoconstraint*", "animation/constraints/tracking/track_to.html#bpy-types-tracktoconstraint"),
("bpy.types.transformsequence*", "video_editing/edit/montage/strips/effects/transform.html#bpy-types-transformsequence"),
("bpy.types.uvprojectmodifier*", "modeling/modifiers/modify/uv_project.html#bpy-types-uvprojectmodifier"),
@@ -2383,6 +2438,7 @@ url_manual_mapping = (
("bpy.types.worldmistsettings*", "render/cycles/world_settings.html#bpy-types-worldmistsettings"),
("bpy.ops.anim.channels_move*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-move"),
("bpy.ops.armature.subdivide*", "animation/armatures/bones/editing/subdivide.html#bpy-ops-armature-subdivide"),
+ ("bpy.ops.brush.curve_preset*", "sculpt_paint/brush/falloff.html#bpy-ops-brush-curve-preset"),
("bpy.ops.buttons.toggle_pin*", "editors/properties_editor.html#bpy-ops-buttons-toggle-pin"),
("bpy.ops.clip.delete_marker*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-delete-marker"),
("bpy.ops.clip.filter_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-filter-tracks"),
@@ -2444,6 +2500,7 @@ url_manual_mapping = (
("bpy.types.bone.head_radius*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-head-radius"),
("bpy.types.bone.tail_radius*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-tail-radius"),
("bpy.types.brush.cloth_mass*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-mass"),
+ ("bpy.types.brush.dash_ratio*", "sculpt_paint/brush/stroke.html#bpy-types-brush-dash-ratio"),
("bpy.types.brushtextureslot*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot"),
("bpy.types.colormixsequence*", "video_editing/edit/montage/strips/effects/color_mix.html#bpy-types-colormixsequence"),
("bpy.types.curve.dimensions*", "modeling/curves/properties/shape.html#bpy-types-curve-dimensions"),
@@ -2541,6 +2598,7 @@ url_manual_mapping = (
("bpy.ops.object.pointcloud*", "modeling/point_cloud.html#bpy-ops-object-pointcloud"),
("bpy.ops.object.select_all*", "scene_layout/object/selecting.html#bpy-ops-object-select-all"),
("bpy.ops.object.shade_flat*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-flat"),
+ ("bpy.ops.paintcurve.select*", "sculpt_paint/brush/stroke.html#bpy-ops-paintcurve-select"),
("bpy.ops.pose.group_assign*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-assign"),
("bpy.ops.pose.group_select*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-select"),
("bpy.ops.pose.paths_update*", "animation/motion_paths.html#bpy-ops-pose-paths-update"),
@@ -2552,6 +2610,7 @@ url_manual_mapping = (
("bpy.ops.screen.area_split*", "interface/window_system/areas.html#bpy-ops-screen-area-split"),
("bpy.ops.screen.screenshot*", "interface/window_system/topbar.html#bpy-ops-screen-screenshot"),
("bpy.ops.sculpt.dirty_mask*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-dirty-mask"),
+ ("bpy.ops.sculpt.reveal_all*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-reveal-all"),
("bpy.ops.sculpt.symmetrize*", "sculpt_paint/sculpting/tool_settings/symmetry.html#bpy-ops-sculpt-symmetrize"),
("bpy.ops.uv.remove_doubles*", "modeling/meshes/uv/editing.html#bpy-ops-uv-remove-doubles"),
("bpy.ops.uv.select_similar*", "editors/uv/selecting.html#bpy-ops-uv-select-similar"),
@@ -2655,7 +2714,7 @@ url_manual_mapping = (
("bpy.ops.wm.save_mainfile*", "files/blend/open_save.html#bpy-ops-wm-save-mainfile"),
("bpy.types.bone.show_wire*", "animation/armatures/bones/properties/display.html#bpy-types-bone-show-wire"),
("bpy.types.brush.hardness*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-hardness"),
- ("bpy.types.curves.surface*", "sculpt_paint/curves_sculpting/introduction.html#bpy-types-curves-surface"),
+ ("bpy.types.curves.surface*", "modeling/curves/primitives.html#bpy-types-curves-surface"),
("bpy.types.curvesmodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-curvesmodifier"),
("bpy.types.ffmpegsettings*", "render/output/properties/output.html#bpy-types-ffmpegsettings"),
("bpy.types.fmodifiernoise*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifiernoise"),
@@ -2725,13 +2784,13 @@ url_manual_mapping = (
("bpy.ops.object.face_map*", "modeling/meshes/properties/object_data.html#bpy-ops-object-face-map"),
("bpy.ops.object.join_uvs*", "scene_layout/object/editing/link_transfer/copy_uvmaps.html#bpy-ops-object-join-uvs"),
("bpy.ops.outliner.delete*", "editors/outliner/editing.html#bpy-ops-outliner-delete"),
+ ("bpy.ops.paintcurve.draw*", "sculpt_paint/brush/stroke.html#bpy-ops-paintcurve-draw"),
("bpy.ops.pose.relax_rest*", "animation/armatures/posing/editing/in_betweens.html#bpy-ops-pose-relax-rest"),
("bpy.ops.pose.select_all*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-all"),
("bpy.ops.rigidbody.world*", "physics/rigid_body/world.html#bpy-ops-rigidbody-world"),
("bpy.ops.sculpt.optimize*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-sculpt-optimize"),
("bpy.ops.sequencer.split*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-split"),
("bpy.ops.transform.shear*", "modeling/meshes/editing/mesh/transform/shear.html#bpy-ops-transform-shear"),
- ("bpy.ops.ui.eyedropper_**", "interface/controls/buttons/eyedropper.html#bpy-ops-ui-eyedropper"),
("bpy.ops.uv.cube_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-cube-project"),
("bpy.ops.uv.pack_islands*", "modeling/meshes/uv/editing.html#bpy-ops-uv-pack-islands"),
("bpy.ops.uv.select_split*", "modeling/meshes/uv/editing.html#bpy-ops-uv-select-split"),
@@ -2743,12 +2802,14 @@ url_manual_mapping = (
("bpy.ops.wm.batch_rename*", "files/blend/rename.html#bpy-ops-wm-batch-rename"),
("bpy.ops.wm.owner_enable*", "interface/window_system/workspaces.html#bpy-ops-wm-owner-enable"),
("bpy.ops.wm.redraw_timer*", "advanced/operators.html#bpy-ops-wm-redraw-timer"),
+ ("bpy.ops.wm.splash_about*", "interface/window_system/topbar.html#bpy-ops-wm-splash-about"),
("bpy.types.*light.shadow*", "render/eevee/lighting.html#bpy-types-light-shadow"),
("bpy.types.armature.show*", "animation/armatures/properties/display.html#bpy-types-armature-show"),
("bpy.types.armaturebones*", "animation/armatures/bones/index.html#bpy-types-armaturebones"),
("bpy.types.arraymodifier*", "modeling/modifiers/generate/array.html#bpy-types-arraymodifier"),
("bpy.types.assetmetadata*", "editors/asset_browser.html#bpy-types-assetmetadata"),
("bpy.types.bevelmodifier*", "modeling/modifiers/generate/bevel.html#bpy-types-bevelmodifier"),
+ ("bpy.types.brush.spacing*", "sculpt_paint/brush/stroke.html#bpy-types-brush-spacing"),
("bpy.types.buildmodifier*", "modeling/modifiers/generate/build.html#bpy-types-buildmodifier"),
("bpy.types.clothmodifier*", "physics/cloth/index.html#bpy-types-clothmodifier"),
("bpy.types.clothsettings*", "physics/cloth/settings/index.html#bpy-types-clothsettings"),
@@ -2783,6 +2844,7 @@ url_manual_mapping = (
("bpy.types.sequence.name*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequence-name"),
("bpy.types.sequenceproxy*", "editors/video_sequencer/sequencer/sidebar/proxy.html#bpy-types-sequenceproxy"),
("bpy.types.shaderfxswirl*", "grease_pencil/visual_effects/swirl.html#bpy-types-shaderfxswirl"),
+ ("bpy.types.shadernodemix*", "render/shader_nodes/converter/mix.html#bpy-types-shadernodemix"),
("bpy.types.shadernodergb*", "render/shader_nodes/input/rgb.html#bpy-types-shadernodergb"),
("bpy.types.shapekey.mute*", "animation/shape_keys/shape_keys_panel.html#bpy-types-shapekey-mute"),
("bpy.types.soundsequence*", "video_editing/edit/montage/strips/sound.html#bpy-types-soundsequence"),
@@ -2821,6 +2883,7 @@ url_manual_mapping = (
("bpy.ops.object.convert*", "scene_layout/object/editing/convert.html#bpy-ops-object-convert"),
("bpy.ops.object.gpencil*", "grease_pencil/index.html#bpy-ops-object-gpencil"),
("bpy.ops.object.speaker*", "render/output/audio/speaker.html#bpy-ops-object-speaker"),
+ ("bpy.ops.paintcurve.new*", "sculpt_paint/brush/stroke.html#bpy-ops-paintcurve-new"),
("bpy.ops.pose.breakdown*", "animation/armatures/posing/editing/in_betweens.html#bpy-ops-pose-breakdown"),
("bpy.ops.pose.loc_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-loc-clear"),
("bpy.ops.pose.propagate*", "animation/armatures/posing/editing/propagate.html#bpy-ops-pose-propagate"),
@@ -2902,6 +2965,7 @@ url_manual_mapping = (
("bpy.ops.script.reload*", "advanced/operators.html#bpy-ops-script-reload"),
("bpy.ops.sculpt.expand*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-expand"),
("bpy.ops.sculpt_curves*", "sculpt_paint/curves_sculpting/index.html#bpy-ops-sculpt-curves"),
+ ("bpy.ops.ui.eyedropper*", "interface/controls/buttons/eyedropper.html#bpy-ops-ui-eyedropper"),
("bpy.ops.view3d.select*", "editors/3dview/selecting.html#bpy-ops-view3d-select"),
("bpy.ops.wm.debug_menu*", "advanced/operators.html#bpy-ops-wm-debug-menu"),
("bpy.ops.wm.obj_export*", "files/import_export/obj.html#bpy-ops-wm-obj-export"),
@@ -2911,6 +2975,7 @@ url_manual_mapping = (
("bpy.ops.wm.usd_export*", "files/import_export/usd.html#bpy-ops-wm-usd-export"),
("bpy.types.addsequence*", "video_editing/edit/montage/strips/effects/add.html#bpy-types-addsequence"),
("bpy.types.brush.cloth*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth"),
+ ("bpy.types.brush.curve*", "sculpt_paint/brush/falloff.html#bpy-types-brush-curve"),
("bpy.types.camera.show*", "render/cameras.html#bpy-types-camera-show"),
("bpy.types.consoleline*", "editors/python_console.html#bpy-types-consoleline"),
("bpy.types.curve.bevel*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel"),
@@ -2960,6 +3025,7 @@ url_manual_mapping = (
("bpy.types.areaspaces*", "interface/window_system/areas.html#bpy-types-areaspaces"),
("bpy.types.bonegroups*", "animation/armatures/properties/bone_groups.html#bpy-types-bonegroups"),
("bpy.types.bpy_struct*", "files/data_blocks.html#bpy-types-bpy-struct"),
+ ("bpy.types.brush.rate*", "sculpt_paint/brush/stroke.html#bpy-types-brush-rate"),
("bpy.types.collection*", "scene_layout/collections/collections.html#bpy-types-collection"),
("bpy.types.compositor*", "compositing/index.html#bpy-types-compositor"),
("bpy.types.constraint*", "animation/constraints/index.html#bpy-types-constraint"),
diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py
index 8b8cfaaccc5..5f4a6b8cf38 100644
--- a/release/scripts/modules/rna_prop_ui.py
+++ b/release/scripts/modules/rna_prop_ui.py
@@ -127,7 +127,7 @@ def draw(layout, context, context_member, property_type, *, use_edit=True):
use_edit = False
is_lib_override = rna_item.id_data.override_library and rna_item.id_data.override_library.reference
- assert(isinstance(rna_item, property_type))
+ assert isinstance(rna_item, property_type)
items = list(rna_item.items())
items.sort()
@@ -183,7 +183,7 @@ def draw(layout, context, context_member, property_type, *, use_edit=True):
# Do not allow editing of overridden properties (we cannot use a poll function
# of the operators here since they's have no access to the specific property).
- operator_row.enabled = not(is_lib_override and key in rna_item.id_data.override_library.reference)
+ operator_row.enabled = not (is_lib_override and key in rna_item.id_data.override_library.reference)
if use_edit:
if is_rna:
diff --git a/release/scripts/modules/sys_info.py b/release/scripts/modules/sys_info.py
index a5bae1b97af..5bd38acb19c 100644
--- a/release/scripts/modules/sys_info.py
+++ b/release/scripts/modules/sys_info.py
@@ -53,6 +53,13 @@ def write_sysinfo(filepath):
output.write("build linkflags: %s\n" % prepr(bpy.app.build_linkflags))
output.write("build system: %s\n" % prepr(bpy.app.build_system))
+ # Windowing Environment (include when dynamically selectable).
+ from _bpy import _ghost_backend
+ ghost_backend = _ghost_backend()
+ if ghost_backend not in {'NONE', 'DEFAULT'}:
+ output.write("windowing environment: %s\n" % prepr(ghost_backend))
+ del _ghost_backend, ghost_backend
+
# Python info.
output.write(title("Python"))
output.write("version: %s\n" % (sys.version.replace("\n", " ")))
@@ -176,6 +183,8 @@ def write_sysinfo(filepath):
output.write("renderer:\t%r\n" % gpu.platform.renderer_get())
output.write("vendor:\t\t%r\n" % gpu.platform.vendor_get())
output.write("version:\t%r\n" % gpu.platform.version_get())
+ output.write("device type:\t%r\n" % gpu.platform.device_type_get())
+ output.write("backend type:\t%r\n" % gpu.platform.backend_type_get())
output.write("extensions:\n")
glext = sorted(gpu.capabilities.extensions_get())
@@ -196,6 +205,14 @@ def write_sysinfo(filepath):
output.write("Maximum Fragment Image Units:\t%d\n" % gpu.capabilities.max_textures_frag_get())
output.write("Maximum Pipeline Image Units:\t%d\n" % gpu.capabilities.max_textures_get())
+ output.write("\nFeatures:\n")
+ output.write("Compute Shader Support: \t%d\n" %
+ gpu.capabilities.compute_shader_support_get())
+ output.write("Shader Storage Buffer Objects Support:\t%d\n" %
+ gpu.capabilities.shader_storage_buffer_objects_support_get())
+ output.write("Image Load/Store Support: \t%d\n" %
+ gpu.capabilities.shader_image_load_store_support_get())
+
if bpy.app.build_options.cycles:
import cycles
output.write(title("Cycles"))
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 446d242c2f3..8e879f3f81d 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -128,7 +128,7 @@ class Params:
self.legacy = legacy
if use_mouse_emulate_3_button:
- assert(use_alt_tool_or_cursor is False)
+ assert use_alt_tool_or_cursor is False
if select_mouse == 'RIGHT':
# Right mouse select.
@@ -2073,6 +2073,8 @@ def km_node_editor(params):
op_menu("NODE_MT_add", {"type": 'A', "value": 'PRESS', "shift": True}),
("node.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True},
{"properties": [("NODE_OT_translate_attach", [("TRANSFORM_OT_translate", [("view2d_edge_pan", True)])])]}),
+ ("node.duplicate_move_linked", {"type": 'D', "value": 'PRESS', "alt": True},
+ {"properties": [("NODE_OT_translate_attach", [("TRANSFORM_OT_translate", [("view2d_edge_pan", True)])])]}),
("node.duplicate_move_keep_inputs", {"type": 'D', "value": 'PRESS', "shift": True, "ctrl": True},
{"properties": [("NODE_OT_translate_attach", [("TRANSFORM_OT_translate", [("view2d_edge_pan", True)])])]}),
("node.parent_set", {"type": 'P', "value": 'PRESS', "ctrl": True}, None),
@@ -3988,6 +3990,9 @@ def km_grease_pencil_stroke_sculpt_mode(params):
op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}),
# Context menu
*_template_items_context_panel("VIEW3D_PT_gpencil_sculpt_context_menu", params.context_menu_event),
+ # Automasking Pie menu
+ op_menu_pie("VIEW3D_MT_sculpt_gpencil_automasking_pie", {
+ "type": 'A', "shift": True, "alt": True, "value": 'PRESS'}),
])
return keymap
@@ -5090,8 +5095,8 @@ def km_sculpt(params):
{"properties": [("mode", 'TOGGLE')]}),
("sculpt.face_set_change_visibility", {"type": 'H', "value": 'PRESS', "shift": True},
{"properties": [("mode", 'HIDE_ACTIVE')]}),
- ("sculpt.face_set_change_visibility", {"type": 'H', "value": 'PRESS', "alt": True},
- {"properties": [("mode", 'SHOW_ALL')]}),
+ ("sculpt.reveal_all", {"type": 'H', "value": 'PRESS', "alt": True},
+ {"properties": []}),
("sculpt.face_set_edit", {"type": 'W', "value": 'PRESS', "ctrl": True},
{"properties": [("mode", 'GROW')]}),
diff --git a/release/scripts/startup/bl_operators/assets.py b/release/scripts/startup/bl_operators/assets.py
index 088f4189ca5..d8182e25641 100644
--- a/release/scripts/startup/bl_operators/assets.py
+++ b/release/scripts/startup/bl_operators/assets.py
@@ -4,6 +4,9 @@ from __future__ import annotations
import bpy
from bpy.types import Operator
+from bpy.app.translations import pgettext_data as data_
+
+
from bpy_extras.asset_utils import (
SpaceAssetInfo,
)
@@ -33,7 +36,7 @@ class ASSET_OT_tag_add(AssetBrowserMetadataOperator, Operator):
def execute(self, context):
active_asset = SpaceAssetInfo.get_active_asset(context)
- active_asset.tags.new("Tag")
+ active_asset.tags.new(data_("Tag"))
return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py
index ff9b5a06fb7..5cc9c850ebe 100644
--- a/release/scripts/startup/bl_operators/node.py
+++ b/release/scripts/startup/bl_operators/node.py
@@ -149,78 +149,6 @@ class NODE_OT_add_node(NodeAddOperator, Operator):
bl_options = {'REGISTER', 'UNDO'}
-class NODE_OT_add_search(NodeAddOperator, Operator):
- '''Add a node to the active tree'''
- bl_idname = "node.add_search"
- bl_label = "Search and Add Node"
- bl_options = {'REGISTER', 'UNDO'}
- bl_property = "node_item"
-
- _enum_item_hack = []
-
- # Create an enum list from node items
- def node_enum_items(self, context):
- import nodeitems_utils
-
- enum_items = NODE_OT_add_search._enum_item_hack
- enum_items.clear()
-
- for index, item in enumerate(nodeitems_utils.node_items_iter(context)):
- if isinstance(item, nodeitems_utils.NodeItem):
- enum_items.append(
- (str(index),
- item.label,
- "",
- index,
- ))
- return enum_items
-
- # Look up the item based on index
- def find_node_item(self, context):
- import nodeitems_utils
-
- node_item = int(self.node_item)
- for index, item in enumerate(nodeitems_utils.node_items_iter(context)):
- if index == node_item:
- return item
- return None
-
- node_item: EnumProperty(
- name="Node Type",
- description="Node type",
- items=NODE_OT_add_search.node_enum_items,
- )
-
- def execute(self, context):
- item = self.find_node_item(context)
-
- # no need to keep
- self._enum_item_hack.clear()
-
- if item:
- # apply settings from the node item
- for setting in item.settings.items():
- ops = self.settings.add()
- ops.name = setting[0]
- ops.value = setting[1]
-
- self.create_node(context, item.nodetype)
-
- if self.use_transform:
- bpy.ops.node.translate_attach_remove_on_cancel(
- 'INVOKE_DEFAULT')
-
- return {'FINISHED'}
- else:
- return {'CANCELLED'}
-
- def invoke(self, context, event):
- self.store_mouse_cursor(context, event)
- # Delayed execution in the search popup
- context.window_manager.invoke_search_popup(self)
- return {'CANCELLED'}
-
-
class NODE_OT_collapse_hide_unused_toggle(Operator):
'''Toggle collapsed nodes and hide unused sockets'''
bl_idname = "node.collapse_hide_unused_toggle"
@@ -276,7 +204,6 @@ classes = (
NodeSetting,
NODE_OT_add_node,
- NODE_OT_add_search,
NODE_OT_collapse_hide_unused_toggle,
NODE_OT_tree_path_parent,
)
diff --git a/release/scripts/startup/bl_operators/spreadsheet.py b/release/scripts/startup/bl_operators/spreadsheet.py
index 1ba7d2db2fd..aef4231d573 100644
--- a/release/scripts/startup/bl_operators/spreadsheet.py
+++ b/release/scripts/startup/bl_operators/spreadsheet.py
@@ -32,7 +32,6 @@ class SPREADSHEET_OT_toggle_pin(Operator):
def unpin(self, context):
space = context.space_data
space.is_pinned = False
- space.context_path.guess()
classes = (
diff --git a/release/scripts/startup/bl_operators/userpref.py b/release/scripts/startup/bl_operators/userpref.py
index ce23024fed5..6a027c0ce1f 100644
--- a/release/scripts/startup/bl_operators/userpref.py
+++ b/release/scripts/startup/bl_operators/userpref.py
@@ -89,6 +89,17 @@ class PREFERENCES_OT_copy_prev(Operator):
if os.path.isdir(cls._old_version_path(version_split)):
return version_split
version_old = version_old - 1
+
+ # Support loading 2.8x..2.9x startup (any older isn't so useful to load).
+ # NOTE: remove this block for Blender 4.0 and later.
+ if version_old == 299:
+ version_old = 294
+ while version_old >= 280:
+ version_split = version_old // 100, version_old % 100
+ if os.path.isdir(cls._old_version_path(version_split)):
+ return version_split
+ version_old = version_old - 1
+
return None
@classmethod
diff --git a/release/scripts/startup/bl_operators/uvcalc_follow_active.py b/release/scripts/startup/bl_operators/uvcalc_follow_active.py
index a5c91f238d2..f9f8d7d1019 100644
--- a/release/scripts/startup/bl_operators/uvcalc_follow_active.py
+++ b/release/scripts/startup/bl_operators/uvcalc_follow_active.py
@@ -229,7 +229,7 @@ def main(context, operator):
elif status & STATUS_ERR_NOT_SELECTED:
operator.report({'ERROR'}, "Active face not selected")
else:
- assert((status & STATUS_ERR_ACTIVE_FACE) != 0)
+ assert status & STATUS_ERR_ACTIVE_FACE != 0
operator.report({'ERROR'}, "No active face")
diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
index 93c72c97129..995ec721046 100644
--- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py
+++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
@@ -452,7 +452,7 @@ def lightmap_uvpack(
pretty_faces.append(pf_parent)
w, h = pf_parent.width, pf_parent.height
- assert(w <= h)
+ assert w <= h
if w == h:
even_dict.setdefault(w, []).append(pf_parent)
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index cbb5a63b754..3b81f75b08a 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -178,10 +178,10 @@ def context_path_decompose(data_path):
prop_item = "".join(path_split[i + 1:])
if base_path:
- assert(base_path.startswith("."))
+ assert base_path.startswith(".")
base_path = base_path[1:]
if prop_attr:
- assert(prop_attr.startswith("."))
+ assert prop_attr.startswith(".")
prop_attr = prop_attr[1:]
else:
# If there are no properties, everything is an item.
@@ -2518,6 +2518,7 @@ class WM_OT_batch_rename(Operator):
('BONE', "Bones", ""),
('NODE', "Nodes", ""),
('SEQUENCE_STRIP', "Sequence Strips", ""),
+ ('ACTION_CLIP', "Action Clips", ""),
),
description="Type of data to rename",
)
@@ -2690,6 +2691,30 @@ class WM_OT_batch_rename(Operator):
"name",
iface_("Material(s)"),
)
+ elif data_type == "ACTION_CLIP":
+ data = (
+ (
+ # Outliner.
+ tuple(set(
+ action for id in context.selected_ids
+ if (((animation_data := id.animation_data) is not None) and
+ ((action := animation_data.action) is not None) and
+ (action.library is None))
+ ))
+ if space_type == 'OUTLINER' else
+ # 3D View (default).
+ tuple(set(
+ action for ob in context.selected_objects
+ if (((animation_data := ob.animation_data) is not None) and
+ ((action := animation_data.action) is not None) and
+ (action.library is None))
+ ))
+ )
+ if only_selected else
+ [id for id in bpy.data.actions if id.library is None],
+ "name",
+ iface_("Action(s)"),
+ )
elif data_type in object_data_type_attrs_map.keys():
attr, descr, ty = object_data_type_attrs_map[data_type]
data = (
@@ -2730,7 +2755,7 @@ class WM_OT_batch_rename(Operator):
elif method == 'SUFFIX':
name = name + text
else:
- assert(0)
+ assert 0
elif ty == 'STRIP':
chars = action.strip_chars
@@ -2775,9 +2800,9 @@ class WM_OT_batch_rename(Operator):
elif method == 'TITLE':
name = name.title()
else:
- assert(0)
+ assert 0
else:
- assert(0)
+ assert 0
return name
def _data_update(self, context):
@@ -3133,6 +3158,15 @@ class WM_MT_splash_about(Menu):
bpy.app.build_commit_time.decode('utf-8', 'replace')), translate=False)
col.label(text=iface_("Hash: %s") % bpy.app.build_hash.decode('ascii'), translate=False)
col.label(text=iface_("Branch: %s") % bpy.app.build_branch.decode('utf-8', 'replace'), translate=False)
+
+ # This isn't useful information on MS-Windows or Apple systems as dynamically switching
+ # between windowing systems is only supported between X11/WAYLAND.
+ from _bpy import _ghost_backend
+ ghost_backend = _ghost_backend()
+ if ghost_backend not in {'NONE', 'DEFAULT'}:
+ col.label(text=iface_("Windowing Environment: %s") % _ghost_backend(), translate=False)
+ del _ghost_backend, ghost_backend
+
col.separator(factor=2.0)
col.label(text="Blender is free software")
col.label(text="Licensed under the GNU General Public License")
diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py
index a986d4be993..e4fa10438e0 100644
--- a/release/scripts/startup/bl_ui/__init__.py
+++ b/release/scripts/startup/bl_ui/__init__.py
@@ -9,6 +9,8 @@ if "bpy" in locals():
del reload
_modules = [
+ "node_add_menu",
+ "node_add_menu_geometry",
"properties_animviz",
"properties_constraint",
"properties_data_armature",
diff --git a/release/scripts/startup/bl_ui/node_add_menu.py b/release/scripts/startup/bl_ui/node_add_menu.py
new file mode 100644
index 00000000000..873dbd533a5
--- /dev/null
+++ b/release/scripts/startup/bl_ui/node_add_menu.py
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+import bpy
+from bpy.types import Menu
+from bpy.app.translations import (
+ pgettext_iface as iface_,
+ contexts as i18n_contexts,
+)
+
+
+def add_node_type(layout, node_type, *, label=None):
+ """Add a node type to a menu."""
+ bl_rna = bpy.types.Node.bl_rna_get_subclass(node_type)
+ if not label:
+ label = bl_rna.name if bl_rna else iface_("Unknown")
+ translation_context = bl_rna.translation_context if bl_rna else i18n_contexts.default
+ props = layout.operator("node.add_node", text=label, text_ctxt=translation_context)
+ props.type = node_type
+ props.use_transform = True
+ return props
+
+
+def draw_node_group_add_menu(context, layout):
+ """Add items to the layout used for interacting with node groups."""
+ space_node = context.space_data
+ node_tree = space_node.edit_tree
+ all_node_groups = context.blend_data.node_groups
+
+ layout.operator("node.group_make")
+ layout.operator("node.group_ungroup")
+ if node_tree in all_node_groups.values():
+ layout.separator()
+ add_node_type(layout, "NodeGroupInput")
+ add_node_type(layout, "NodeGroupOutput")
+
+ if node_tree:
+ from nodeitems_builtins import node_tree_group_type
+
+ def contains_group(nodetree, group):
+ if nodetree == group:
+ return True
+ for node in nodetree.nodes:
+ if node.bl_idname in node_tree_group_type.values() and node.node_tree is not None:
+ if contains_group(node.node_tree, group):
+ return True
+ return False
+
+ groups = [
+ group for group in context.blend_data.node_groups
+ if (group.bl_idname == node_tree.bl_idname and
+ not contains_group(group, node_tree) and
+ not group.name.startswith('.'))
+ ]
+ if groups:
+ layout.separator()
+ for group in groups:
+ props = add_node_type(layout, node_tree_group_type[group.bl_idname], label=group.name)
+ ops = props.settings.add()
+ ops.name = "node_tree"
+ ops.value = "bpy.data.node_groups[%r]" % group.name
+
+
+def draw_assets_for_catalog(layout, catalog_path):
+ layout.template_node_asset_menu_items(catalog_path=catalog_path)
+
+
+def draw_root_assets(layout):
+ layout.menu_contents("NODE_MT_node_add_root_catalogs")
+
+
+classes = (
+)
+
+if __name__ == "__main__": # only for live edit.
+ from bpy.utils import register_class
+ for cls in classes:
+ register_class(cls)
diff --git a/release/scripts/startup/bl_ui/node_add_menu_geometry.py b/release/scripts/startup/bl_ui/node_add_menu_geometry.py
new file mode 100644
index 00000000000..c076cd7395a
--- /dev/null
+++ b/release/scripts/startup/bl_ui/node_add_menu_geometry.py
@@ -0,0 +1,470 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+import bpy
+from bpy.types import Menu
+from bl_ui import node_add_menu
+from bpy.app.translations import pgettext_iface as iface_
+
+
+class NODE_MT_geometry_node_GEO_ATTRIBUTE(Menu):
+ bl_idname = "NODE_MT_geometry_node_GEO_ATTRIBUTE"
+ bl_label = "Attribute"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "GeometryNodeAttributeStatistic")
+ node_add_menu.add_node_type(layout, "GeometryNodeCaptureAttribute")
+ node_add_menu.add_node_type(layout, "GeometryNodeAttributeDomainSize")
+ node_add_menu.add_node_type(layout, "GeometryNodeRemoveAttribute")
+ node_add_menu.add_node_type(layout, "GeometryNodeStoreNamedAttribute")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_geometry_node_GEO_COLOR(Menu):
+ bl_idname = "NODE_MT_geometry_node_GEO_COLOR"
+ bl_label = "Color"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "ShaderNodeValToRGB")
+ node_add_menu.add_node_type(layout, "FunctionNodeCombineColor")
+ props = node_add_menu.add_node_type(layout, "ShaderNodeMix", label=iface_("Mix Color"))
+ ops = props.settings.add()
+ ops.name = "data_type"
+ ops.value = "'RGBA'"
+ node_add_menu.add_node_type(layout, "ShaderNodeRGBCurve")
+ node_add_menu.add_node_type(layout, "FunctionNodeSeparateColor")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_geometry_node_GEO_CURVE(Menu):
+ bl_idname = "NODE_MT_geometry_node_GEO_CURVE"
+ bl_label = "Curve"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "GeometryNodeCurveLength")
+ node_add_menu.add_node_type(layout, "GeometryNodeCurveToMesh")
+ node_add_menu.add_node_type(layout, "GeometryNodeCurveToPoints")
+ node_add_menu.add_node_type(layout, "GeometryNodeDeformCurvesOnSurface")
+ node_add_menu.add_node_type(layout, "GeometryNodeFillCurve")
+ node_add_menu.add_node_type(layout, "GeometryNodeFilletCurve")
+ node_add_menu.add_node_type(layout, "GeometryNodeResampleCurve")
+ node_add_menu.add_node_type(layout, "GeometryNodeReverseCurve")
+ node_add_menu.add_node_type(layout, "GeometryNodeSampleCurve")
+ node_add_menu.add_node_type(layout, "GeometryNodeSubdivideCurve")
+ node_add_menu.add_node_type(layout, "GeometryNodeTrimCurve")
+ layout.separator()
+ node_add_menu.add_node_type(layout, "GeometryNodeInputCurveHandlePositions")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputTangent")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputCurveTilt")
+ node_add_menu.add_node_type(layout, "GeometryNodeCurveEndpointSelection")
+ node_add_menu.add_node_type(layout, "GeometryNodeCurveHandleTypeSelection")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputSplineCyclic")
+ node_add_menu.add_node_type(layout, "GeometryNodeSplineLength")
+ node_add_menu.add_node_type(layout, "GeometryNodeSplineParameter")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputSplineResolution")
+ layout.separator()
+ node_add_menu.add_node_type(layout, "GeometryNodeSetCurveNormal")
+ node_add_menu.add_node_type(layout, "GeometryNodeSetCurveRadius")
+ node_add_menu.add_node_type(layout, "GeometryNodeSetCurveTilt")
+ node_add_menu.add_node_type(layout, "GeometryNodeSetCurveHandlePositions")
+ node_add_menu.add_node_type(layout, "GeometryNodeCurveSetHandles")
+ node_add_menu.add_node_type(layout, "GeometryNodeSetSplineCyclic")
+ node_add_menu.add_node_type(layout, "GeometryNodeSetSplineResolution")
+ node_add_menu.add_node_type(layout, "GeometryNodeCurveSplineType")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_geometry_node_GEO_PRIMITIVES_CURVE(Menu):
+ bl_idname = "NODE_MT_geometry_node_GEO_PRIMITIVES_CURVE"
+ bl_label = "Curve Primitives"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "GeometryNodeCurveArc")
+ node_add_menu.add_node_type(layout, "GeometryNodeCurvePrimitiveBezierSegment")
+ node_add_menu.add_node_type(layout, "GeometryNodeCurvePrimitiveCircle")
+ node_add_menu.add_node_type(layout, "GeometryNodeCurvePrimitiveLine")
+ node_add_menu.add_node_type(layout, "GeometryNodeCurveSpiral")
+ node_add_menu.add_node_type(layout, "GeometryNodeCurveQuadraticBezier")
+ node_add_menu.add_node_type(layout, "GeometryNodeCurvePrimitiveQuadrilateral")
+ node_add_menu.add_node_type(layout, "GeometryNodeCurveStar")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_geometry_node_curve_topology(Menu):
+ bl_idname = "NODE_MT_geometry_node_curve_topology"
+ bl_label = "Curve Topology"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "GeometryNodeOffsetPointInCurve")
+ node_add_menu.add_node_type(layout, "GeometryNodeCurveOfPoint")
+ node_add_menu.add_node_type(layout, "GeometryNodePointsOfCurve")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_geometry_node_GEO_GEOMETRY(Menu):
+ bl_idname = "NODE_MT_geometry_node_GEO_GEOMETRY"
+ bl_label = "Geometry"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "GeometryNodeBoundBox")
+ node_add_menu.add_node_type(layout, "GeometryNodeConvexHull")
+ node_add_menu.add_node_type(layout, "GeometryNodeDeleteGeometry")
+ node_add_menu.add_node_type(layout, "GeometryNodeDuplicateElements")
+ node_add_menu.add_node_type(layout, "GeometryNodeProximity")
+ node_add_menu.add_node_type(layout, "GeometryNodeGeometryToInstance")
+ node_add_menu.add_node_type(layout, "GeometryNodeJoinGeometry")
+ node_add_menu.add_node_type(layout, "GeometryNodeMergeByDistance")
+ node_add_menu.add_node_type(layout, "GeometryNodeRaycast")
+ node_add_menu.add_node_type(layout, "GeometryNodeSampleIndex")
+ node_add_menu.add_node_type(layout, "GeometryNodeSampleNearest")
+ node_add_menu.add_node_type(layout, "GeometryNodeSeparateComponents")
+ node_add_menu.add_node_type(layout, "GeometryNodeSeparateGeometry")
+ node_add_menu.add_node_type(layout, "GeometryNodeTransform")
+ layout.separator()
+ node_add_menu.add_node_type(layout, "GeometryNodeSetID")
+ node_add_menu.add_node_type(layout, "GeometryNodeSetPosition")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_geometry_node_GEO_INPUT(Menu):
+ bl_idname = "NODE_MT_geometry_node_GEO_INPUT"
+ bl_label = "Input"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "FunctionNodeInputBool")
+ node_add_menu.add_node_type(layout, "GeometryNodeCollectionInfo")
+ node_add_menu.add_node_type(layout, "FunctionNodeInputColor")
+ node_add_menu.add_node_type(layout, "FunctionNodeInputInt")
+ node_add_menu.add_node_type(layout, "GeometryNodeIsViewport")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputMaterial")
+ node_add_menu.add_node_type(layout, "GeometryNodeObjectInfo")
+ node_add_menu.add_node_type(layout, "GeometryNodeSelfObject")
+ node_add_menu.add_node_type(layout, "FunctionNodeInputString")
+ node_add_menu.add_node_type(layout, "ShaderNodeValue")
+ node_add_menu.add_node_type(layout, "FunctionNodeInputVector")
+ layout.separator()
+ node_add_menu.add_node_type(layout, "GeometryNodeInputID")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputIndex")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputNamedAttribute")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputNormal")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputPosition")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputRadius")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputSceneTime")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_geometry_node_GEO_INSTANCE(Menu):
+ bl_idname = "NODE_MT_geometry_node_GEO_INSTANCE"
+ bl_label = "Instances"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "GeometryNodeInstanceOnPoints")
+ node_add_menu.add_node_type(layout, "GeometryNodeInstancesToPoints")
+ node_add_menu.add_node_type(layout, "GeometryNodeRealizeInstances")
+ node_add_menu.add_node_type(layout, "GeometryNodeRotateInstances")
+ node_add_menu.add_node_type(layout, "GeometryNodeScaleInstances")
+ node_add_menu.add_node_type(layout, "GeometryNodeTranslateInstances")
+ layout.separator()
+ node_add_menu.add_node_type(layout, "GeometryNodeInputInstanceRotation")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputInstanceScale")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_geometry_node_GEO_MATERIAL(Menu):
+ bl_idname = "NODE_MT_geometry_node_GEO_MATERIAL"
+ bl_label = "Material"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "GeometryNodeReplaceMaterial")
+ layout.separator()
+ node_add_menu.add_node_type(layout, "GeometryNodeInputMaterialIndex")
+ node_add_menu.add_node_type(layout, "GeometryNodeMaterialSelection")
+ layout.separator()
+ node_add_menu.add_node_type(layout, "GeometryNodeSetMaterial")
+ node_add_menu.add_node_type(layout, "GeometryNodeSetMaterialIndex")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_geometry_node_GEO_MESH(Menu):
+ bl_idname = "NODE_MT_geometry_node_GEO_MESH"
+ bl_label = "Mesh"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "GeometryNodeDualMesh")
+ node_add_menu.add_node_type(layout, "GeometryNodeEdgePathsToCurves")
+ node_add_menu.add_node_type(layout, "GeometryNodeEdgePathsToSelection")
+ node_add_menu.add_node_type(layout, "GeometryNodeExtrudeMesh")
+ node_add_menu.add_node_type(layout, "GeometryNodeFlipFaces")
+ node_add_menu.add_node_type(layout, "GeometryNodeMeshBoolean")
+ node_add_menu.add_node_type(layout, "GeometryNodeMeshToCurve")
+ node_add_menu.add_node_type(layout, "GeometryNodeMeshToPoints")
+ node_add_menu.add_node_type(layout, "GeometryNodeMeshToVolume")
+ node_add_menu.add_node_type(layout, "GeometryNodeSampleNearestSurface")
+ node_add_menu.add_node_type(layout, "GeometryNodeSampleUVSurface")
+ node_add_menu.add_node_type(layout, "GeometryNodeScaleElements")
+ node_add_menu.add_node_type(layout, "GeometryNodeSplitEdges")
+ node_add_menu.add_node_type(layout, "GeometryNodeSubdivideMesh")
+ node_add_menu.add_node_type(layout, "GeometryNodeSubdivisionSurface")
+ node_add_menu.add_node_type(layout, "GeometryNodeTriangulate")
+ layout.separator()
+ node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeAngle")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeNeighbors")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeVertices")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceArea")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceNeighbors")
+ node_add_menu.add_node_type(layout, "GeometryNodeMeshFaceSetBoundaries")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceIsPlanar")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputShadeSmooth")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputMeshIsland")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputShortestEdgePaths")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputMeshVertexNeighbors")
+ layout.separator()
+ node_add_menu.add_node_type(layout, "GeometryNodeSetShadeSmooth")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_category_PRIMITIVES_MESH(Menu):
+ bl_idname = "NODE_MT_category_PRIMITIVES_MESH"
+ bl_label = "Mesh Primitives"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "GeometryNodeMeshCone")
+ node_add_menu.add_node_type(layout, "GeometryNodeMeshCube")
+ node_add_menu.add_node_type(layout, "GeometryNodeMeshCylinder")
+ node_add_menu.add_node_type(layout, "GeometryNodeMeshGrid")
+ node_add_menu.add_node_type(layout, "GeometryNodeMeshIcoSphere")
+ node_add_menu.add_node_type(layout, "GeometryNodeMeshCircle")
+ node_add_menu.add_node_type(layout, "GeometryNodeMeshLine")
+ node_add_menu.add_node_type(layout, "GeometryNodeMeshUVSphere")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_geometry_node_mesh_topology(Menu):
+ bl_idname = "NODE_MT_geometry_node_mesh_topology"
+ bl_label = "Mesh Topology"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "GeometryNodeCornersOfFace"),
+ node_add_menu.add_node_type(layout, "GeometryNodeCornersOfVertex"),
+ node_add_menu.add_node_type(layout, "GeometryNodeEdgesOfCorner"),
+ node_add_menu.add_node_type(layout, "GeometryNodeEdgesOfVertex"),
+ node_add_menu.add_node_type(layout, "GeometryNodeFaceOfCorner"),
+ node_add_menu.add_node_type(layout, "GeometryNodeOffsetCornerInFace"),
+ node_add_menu.add_node_type(layout, "GeometryNodeVertexOfCorner"),
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_category_GEO_OUTPUT(Menu):
+ bl_idname = "NODE_MT_category_GEO_OUTPUT"
+ bl_label = "Output"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "GeometryNodeViewer")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_category_GEO_POINT(Menu):
+ bl_idname = "NODE_MT_category_GEO_POINT"
+ bl_label = "Point"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "GeometryNodeDistributePointsInVolume")
+ node_add_menu.add_node_type(layout, "GeometryNodeDistributePointsOnFaces")
+ node_add_menu.add_node_type(layout, "GeometryNodePoints")
+ node_add_menu.add_node_type(layout, "GeometryNodePointsToVertices")
+ node_add_menu.add_node_type(layout, "GeometryNodePointsToVolume")
+ layout.separator()
+ node_add_menu.add_node_type(layout, "GeometryNodeSetPointRadius")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_category_GEO_TEXT(Menu):
+ bl_idname = "NODE_MT_category_GEO_TEXT"
+ bl_label = "Text"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "GeometryNodeStringJoin")
+ node_add_menu.add_node_type(layout, "FunctionNodeReplaceString")
+ node_add_menu.add_node_type(layout, "FunctionNodeSliceString")
+ node_add_menu.add_node_type(layout, "FunctionNodeStringLength")
+ node_add_menu.add_node_type(layout, "GeometryNodeStringToCurves")
+ node_add_menu.add_node_type(layout, "FunctionNodeValueToString")
+ layout.separator()
+ node_add_menu.add_node_type(layout, "FunctionNodeInputSpecialCharacters")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_category_GEO_TEXTURE(Menu):
+ bl_idname = "NODE_MT_category_GEO_TEXTURE"
+ bl_label = "Texture"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "ShaderNodeTexBrick")
+ node_add_menu.add_node_type(layout, "ShaderNodeTexChecker")
+ node_add_menu.add_node_type(layout, "ShaderNodeTexGradient")
+ node_add_menu.add_node_type(layout, "GeometryNodeImageTexture")
+ node_add_menu.add_node_type(layout, "ShaderNodeTexMagic")
+ node_add_menu.add_node_type(layout, "ShaderNodeTexMusgrave")
+ node_add_menu.add_node_type(layout, "ShaderNodeTexNoise")
+ node_add_menu.add_node_type(layout, "ShaderNodeTexVoronoi")
+ node_add_menu.add_node_type(layout, "ShaderNodeTexWave")
+ node_add_menu.add_node_type(layout, "ShaderNodeTexWhiteNoise")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_category_GEO_UTILITIES(Menu):
+ bl_idname = "NODE_MT_category_GEO_UTILITIES"
+ bl_label = "Utilities"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "GeometryNodeAccumulateField")
+ node_add_menu.add_node_type(layout, "FunctionNodeAlignEulerToVector")
+ node_add_menu.add_node_type(layout, "FunctionNodeBooleanMath")
+ node_add_menu.add_node_type(layout, "ShaderNodeClamp")
+ node_add_menu.add_node_type(layout, "FunctionNodeCompare")
+ node_add_menu.add_node_type(layout, "GeometryNodeFieldAtIndex")
+ node_add_menu.add_node_type(layout, "ShaderNodeFloatCurve")
+ node_add_menu.add_node_type(layout, "FunctionNodeFloatToInt")
+ node_add_menu.add_node_type(layout, "GeometryNodeFieldOnDomain")
+ node_add_menu.add_node_type(layout, "ShaderNodeMapRange")
+ node_add_menu.add_node_type(layout, "ShaderNodeMath")
+ node_add_menu.add_node_type(layout, "ShaderNodeMix")
+ node_add_menu.add_node_type(layout, "FunctionNodeRandomValue")
+ node_add_menu.add_node_type(layout, "FunctionNodeRotateEuler")
+ node_add_menu.add_node_type(layout, "GeometryNodeSwitch")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_category_GEO_UV(Menu):
+ bl_idname = "NODE_MT_category_GEO_UV"
+ bl_label = "UV"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "GeometryNodeUVPackIslands")
+ node_add_menu.add_node_type(layout, "GeometryNodeUVUnwrap")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_category_GEO_VECTOR(Menu):
+ bl_idname = "NODE_MT_category_GEO_VECTOR"
+ bl_label = "Vector"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "ShaderNodeCombineXYZ")
+ node_add_menu.add_node_type(layout, "ShaderNodeSeparateXYZ")
+ node_add_menu.add_node_type(layout, "ShaderNodeVectorCurve")
+ node_add_menu.add_node_type(layout, "ShaderNodeVectorMath")
+ node_add_menu.add_node_type(layout, "ShaderNodeVectorRotate")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_category_GEO_VOLUME(Menu):
+ bl_idname = "NODE_MT_category_GEO_VOLUME"
+ bl_label = "Volume"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "GeometryNodeVolumeCube")
+ node_add_menu.add_node_type(layout, "GeometryNodeVolumeToMesh")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_category_GEO_GROUP(Menu):
+ bl_idname = "NODE_MT_category_GEO_GROUP"
+ bl_label = "Group"
+
+ def draw(self, context):
+ layout = self.layout
+ node_add_menu.draw_node_group_add_menu(context, layout)
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_category_GEO_LAYOUT(Menu):
+ bl_idname = "NODE_MT_category_GEO_LAYOUT"
+ bl_label = "Layout"
+
+ def draw(self, _context):
+ layout = self.layout
+ node_add_menu.add_node_type(layout, "NodeFrame")
+ node_add_menu.add_node_type(layout, "NodeReroute")
+ node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
+
+
+class NODE_MT_geometry_node_add_all(Menu):
+ bl_idname = "NODE_MT_geometry_node_add_all"
+ bl_label = ""
+
+ def draw(self, _context):
+ layout = self.layout
+ layout.menu("NODE_MT_geometry_node_GEO_ATTRIBUTE")
+ layout.menu("NODE_MT_geometry_node_GEO_COLOR")
+ layout.menu("NODE_MT_geometry_node_GEO_CURVE")
+ layout.menu("NODE_MT_geometry_node_GEO_PRIMITIVES_CURVE")
+ layout.menu("NODE_MT_geometry_node_curve_topology")
+ layout.menu("NODE_MT_geometry_node_GEO_GEOMETRY")
+ layout.menu("NODE_MT_geometry_node_GEO_INPUT")
+ layout.menu("NODE_MT_geometry_node_GEO_INSTANCE")
+ layout.menu("NODE_MT_geometry_node_GEO_MATERIAL")
+ layout.menu("NODE_MT_geometry_node_GEO_MESH")
+ layout.menu("NODE_MT_category_PRIMITIVES_MESH")
+ layout.menu("NODE_MT_geometry_node_mesh_topology")
+ layout.menu("NODE_MT_category_GEO_OUTPUT")
+ layout.menu("NODE_MT_category_GEO_POINT")
+ layout.menu("NODE_MT_category_GEO_TEXT")
+ layout.menu("NODE_MT_category_GEO_TEXTURE")
+ layout.menu("NODE_MT_category_GEO_UTILITIES")
+ layout.menu("NODE_MT_category_GEO_UV")
+ layout.menu("NODE_MT_category_GEO_VECTOR")
+ layout.menu("NODE_MT_category_GEO_VOLUME")
+ layout.menu("NODE_MT_category_GEO_GROUP")
+ layout.menu("NODE_MT_category_GEO_LAYOUT")
+ node_add_menu.draw_root_assets(layout)
+
+
+classes = (
+ NODE_MT_geometry_node_add_all,
+ NODE_MT_geometry_node_GEO_ATTRIBUTE,
+ NODE_MT_geometry_node_GEO_COLOR,
+ NODE_MT_geometry_node_GEO_CURVE,
+ NODE_MT_geometry_node_GEO_PRIMITIVES_CURVE,
+ NODE_MT_geometry_node_curve_topology,
+ NODE_MT_geometry_node_GEO_GEOMETRY,
+ NODE_MT_geometry_node_GEO_INPUT,
+ NODE_MT_geometry_node_GEO_INSTANCE,
+ NODE_MT_geometry_node_GEO_MATERIAL,
+ NODE_MT_geometry_node_GEO_MESH,
+ NODE_MT_category_PRIMITIVES_MESH,
+ NODE_MT_geometry_node_mesh_topology,
+ NODE_MT_category_GEO_OUTPUT,
+ NODE_MT_category_GEO_POINT,
+ NODE_MT_category_GEO_TEXT,
+ NODE_MT_category_GEO_TEXTURE,
+ NODE_MT_category_GEO_UTILITIES,
+ NODE_MT_category_GEO_UV,
+ NODE_MT_category_GEO_VECTOR,
+ NODE_MT_category_GEO_VOLUME,
+ NODE_MT_category_GEO_GROUP,
+ NODE_MT_category_GEO_LAYOUT,
+)
+
+if __name__ == "__main__": # only for live edit.
+ from bpy.utils import register_class
+ for cls in classes:
+ register_class(cls)
diff --git a/release/scripts/startup/bl_ui/properties_data_curves.py b/release/scripts/startup/bl_ui/properties_data_curves.py
index ff0eabeb7d9..df80bdb4552 100644
--- a/release/scripts/startup/bl_ui/properties_data_curves.py
+++ b/release/scripts/startup/bl_ui/properties_data_curves.py
@@ -44,7 +44,13 @@ class DATA_PT_curves_surface(DataButtonsPanel, Panel):
layout.use_property_split = True
layout.prop(ob.data, "surface")
- layout.prop(ob.data, "surface_uv_map", text="UV Map")
+ has_surface = ob.data.surface is not None
+ if has_surface:
+ layout.prop_search(ob.data, "surface_uv_map", ob.data.surface.data, "uv_layers", text="UV Map")
+ else:
+ row = layout.row()
+ row.prop(ob.data, "surface_uv_map", text="UV Map")
+ row.enabled = has_surface
class CURVES_MT_add_attribute(Menu):
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index d878eea0cb9..a6b97fbdc85 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -503,11 +503,15 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel):
else:
col.operator("mesh.customdata_bevel_weight_vertex_add", icon='ADD')
- col = layout.column(heading="Store")
+ if me.has_crease_edge:
+ col.operator("mesh.customdata_crease_edge_clear", icon='X')
+ else:
+ col.operator("mesh.customdata_crease_edge_add", icon='ADD')
- col.enabled = obj is not None and obj.mode != 'EDIT'
- col.prop(me, "use_customdata_vertex_crease", text="Vertex Crease")
- col.prop(me, "use_customdata_edge_crease", text="Edge Crease")
+ if me.has_crease_vertex:
+ col.operator("mesh.customdata_crease_vertex_clear", icon='X')
+ else:
+ col.operator("mesh.customdata_crease_vertex_add", icon='ADD')
class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel):
@@ -582,7 +586,7 @@ class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel):
def draw_attribute_warnings(self, context, layout):
ob = context.object
- mesh = ob.data
+ mesh = context.mesh
unique_names = set()
colliding_names = []
@@ -591,8 +595,11 @@ class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel):
{"position": None, "shade_smooth": None, "normal": None, "crease": None},
mesh.attributes,
mesh.uv_layers,
- ob.vertex_groups,
+ None if ob is None else ob.vertex_groups,
):
+ if collection is None:
+ colliding_names.append("Cannot check for object vertex groups when pinning mesh")
+ continue
for name in collection.keys():
unique_names_len = len(unique_names)
unique_names.add(name)
diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
index 38522a1bf84..83bb0f7dd8c 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -51,11 +51,6 @@ class GreasePencilSculptAdvancedPanel:
tool = brush.gpencil_sculpt_tool
gp_settings = brush.gpencil_settings
- col = layout.column(heading="Auto-Masking", align=True)
- col.prop(gp_settings, "use_automasking_stroke", text="Stroke")
- col.prop(gp_settings, "use_automasking_layer", text="Layer")
- col.prop(gp_settings, "use_automasking_material", text="Material")
-
if tool in {'SMOOTH', 'RANDOMIZE'}:
col = layout.column(heading="Affect", align=True)
col.prop(gp_settings, "use_edit_position", text="Position")
diff --git a/release/scripts/startup/bl_ui/properties_output.py b/release/scripts/startup/bl_ui/properties_output.py
index bc7e8bb4347..61384f25afb 100644
--- a/release/scripts/startup/bl_ui/properties_output.py
+++ b/release/scripts/startup/bl_ui/properties_output.py
@@ -3,7 +3,10 @@ import bpy
from bpy.types import Menu, Panel, UIList
from bl_ui.utils import PresetPanel
-from bpy.app.translations import pgettext_tip as tip_
+from bpy.app.translations import (
+ contexts as i18n_contexts,
+ pgettext_tip as tip_,
+)
class RENDER_PT_format_presets(PresetPanel, Panel):
@@ -377,7 +380,14 @@ class RENDER_PT_encoding_video(RenderOutputButtonsPanel, Panel):
layout = self.layout
ffmpeg = context.scene.render.ffmpeg
- needs_codec = ffmpeg.format in {'AVI', 'QUICKTIME', 'MKV', 'OGG', 'MPEG4', 'WEBM'}
+ needs_codec = ffmpeg.format in {
+ 'AVI',
+ 'QUICKTIME',
+ 'MKV',
+ 'OGG',
+ 'MPEG4',
+ 'WEBM'
+ }
if needs_codec:
layout.prop(ffmpeg, "codec")
@@ -388,7 +398,12 @@ class RENDER_PT_encoding_video(RenderOutputButtonsPanel, Panel):
layout.prop(ffmpeg, "use_lossless_output")
# Output quality
- use_crf = needs_codec and ffmpeg.codec in {'H264', 'MPEG4', 'WEBM'}
+ use_crf = needs_codec and ffmpeg.codec in {
+ 'H264',
+ 'MPEG4',
+ 'WEBM',
+ 'AV1'
+ }
if use_crf:
layout.prop(ffmpeg, "constant_rate_factor")
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 9b1cf11f6e7..0e49a506e73 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -928,29 +928,80 @@ def brush_settings_advanced(layout, context, brush, popover=False):
use_frontface = False
if mode == 'SCULPT':
+ sculpt = context.tool_settings.sculpt
capabilities = brush.sculpt_capabilities
use_accumulate = capabilities.has_accumulate
use_frontface = True
col = layout.column(heading="Auto-Masking", align=True)
- # topology automasking
+ col = layout.column(align=True)
col.prop(brush, "use_automasking_topology", text="Topology")
-
- # face masks automasking
col.prop(brush, "use_automasking_face_sets", text="Face Sets")
- # boundary edges/face sets automasking
+ layout.separator()
+
+ col = layout.column(align=True)
col.prop(brush, "use_automasking_boundary_edges", text="Mesh Boundary")
col.prop(brush, "use_automasking_boundary_face_sets", text="Face Sets Boundary")
- col.prop(brush, "automasking_boundary_edges_propagation_steps")
+
+ if brush.use_automasking_boundary_edges or brush.use_automasking_boundary_face_sets:
+ col = layout.column()
+ col.use_property_split = False
+ split = col.split(factor=0.4)
+ col = split.column()
+ split.prop(brush, "automasking_boundary_edges_propagation_steps")
+
+ layout.separator()
+
+ col = layout.column(align=True)
+ row = col.row()
+ row.prop(brush, "use_automasking_cavity", text="Cavity")
+
+ is_cavity_active = brush.use_automasking_cavity or brush.use_automasking_cavity_inverted
+
+ if is_cavity_active:
+ row.operator("sculpt.mask_from_cavity", text="Create Mask")
+
+ col.prop(brush, "use_automasking_cavity_inverted", text="Cavity (inverted)")
+
+ if is_cavity_active:
+ col = layout.column(align=True)
+ col.prop(brush, "automasking_cavity_factor", text="Factor")
+ col.prop(brush, "automasking_cavity_blur_steps", text="Blur")
+
+ col = layout.column()
+ col.prop(brush, "use_automasking_custom_cavity_curve", text="Custom Curve")
+
+ if brush.use_automasking_custom_cavity_curve:
+ col.template_curve_mapping(brush, "automasking_cavity_curve")
+
+ layout.separator()
+
+ col = layout.column(align=True)
+ col.prop(brush, "use_automasking_view_normal", text="View Normal")
+
+ if brush.use_automasking_view_normal:
+ col.prop(brush, "use_automasking_view_occlusion", text="Occlusion")
+ subcol = col.column(align=True)
+ subcol.active = not brush.use_automasking_view_occlusion
+ subcol.prop(sculpt, "automasking_view_normal_limit", text="Limit")
+ subcol.prop(sculpt, "automasking_view_normal_falloff", text="Falloff")
+
+ col = layout.column()
+ col.prop(brush, "use_automasking_start_normal", text="Area Normal")
+
+ if brush.use_automasking_start_normal:
+ col = layout.column(align=True)
+ col.prop(sculpt, "automasking_start_normal_limit", text="Limit")
+ col.prop(sculpt, "automasking_start_normal_falloff", text="Falloff")
layout.separator()
# sculpt plane settings
if capabilities.has_sculpt_plane:
layout.prop(brush, "sculpt_plane")
- col = layout.column(heading="Use Original", align=True)
+ col = layout.column(heading="Original", align=True)
col.prop(brush, "use_original_normal", text="Normal")
col.prop(brush, "use_original_plane", text="Plane")
layout.separator()
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index 080c8ca5726..8567ddb9372 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -239,6 +239,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
class PARTICLE_PT_emission(ParticleButtonsPanel, Panel):
bl_label = "Emission"
+ bl_translation_context = i18n_contexts.id_particlesettings
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
@classmethod
@@ -1679,7 +1680,7 @@ class PARTICLE_PT_children_roughness(ParticleButtonsPanel, Panel):
if part.use_roughness_curve:
sub = col.column()
sub.template_curve_mapping(part, "roughness_curve")
- sub.prop(part, "roughness_1", text=iface_("Roughness", i18n_contexts.id_particlesettings))
+ sub.prop(part, "roughness_1", text="Roughness", text_ctxt=i18n_contexts.id_particlesettings)
sub.prop(part, "roughness_1_size", text="Size")
else:
sub = col.column(align=True)
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py
index c337e8018e6..54b3a20f966 100644
--- a/release/scripts/startup/bl_ui/space_clip.py
+++ b/release/scripts/startup/bl_ui/space_clip.py
@@ -2,7 +2,10 @@
import bpy
from bpy.types import Panel, Header, Menu, UIList
-from bpy.app.translations import pgettext_iface as iface_
+from bpy.app.translations import (
+ pgettext_iface as iface_,
+ contexts as i18n_contexts,
+)
from bl_ui.utils import PresetPanel
from bl_ui.properties_grease_pencil_common import (
AnnotationDrawingToolsPanel,
@@ -1751,6 +1754,7 @@ class CLIP_MT_marker_pie(Menu):
class CLIP_MT_tracking_pie(Menu):
# Tracking Operators
bl_label = "Tracking"
+ bl_translation_context = i18n_contexts.id_movieclip
@classmethod
def poll(cls, context):
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index a2e691c2d9f..f95650ccc23 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -318,6 +318,7 @@ class DOPESHEET_MT_view(Menu):
st = context.space_data
layout.prop(st, "show_region_ui")
+ layout.prop(st, "show_region_hud")
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 0b26f0b1203..fcbd7bb423d 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -402,7 +402,7 @@ class IMAGE_MT_uvs(Menu):
layout.menu("IMAGE_MT_uvs_mirror")
layout.menu("IMAGE_MT_uvs_snap")
- layout.prop_menu_enum(uv, "pixel_snap_mode")
+ layout.prop_menu_enum(uv, "pixel_round_mode")
layout.prop(uv, "lock_bounds")
layout.separator()
@@ -537,10 +537,12 @@ class IMAGE_MT_pivot_pie(Menu):
layout = self.layout
pie = layout.menu_pie()
- pie.prop_enum(context.space_data, "pivot_point", value='CENTER')
- pie.prop_enum(context.space_data, "pivot_point", value='CURSOR')
- pie.prop_enum(context.space_data, "pivot_point", value='INDIVIDUAL_ORIGINS')
- pie.prop_enum(context.space_data, "pivot_point", value='MEDIAN')
+ sima = context.space_data
+
+ pie.prop_enum(sima, "pivot_point", value='CENTER')
+ pie.prop_enum(sima, "pivot_point", value='CURSOR')
+ pie.prop_enum(sima, "pivot_point", value='INDIVIDUAL_ORIGINS')
+ pie.prop_enum(sima, "pivot_point", value='MEDIAN')
class IMAGE_MT_uvs_snap_pie(Menu):
@@ -1526,25 +1528,23 @@ class IMAGE_PT_overlay_guides(Panel):
layout.active = overlay.show_overlays
row = layout.row()
- row_el = row.column()
- row_el.prop(overlay, "show_grid_background", text="Grid")
+ row.prop(overlay, "show_grid_background", text="Grid")
if overlay.show_grid_background:
- layout.use_property_split = True
- col = layout.column(align=False, heading="Fixed Subdivisions")
- col.use_property_decorate = False
+ sub = row.row()
+ sub.prop(uvedit, "show_grid_over_image", text="Over Image")
+ sub.active = sima.image is not None
- row = col.row(align=True)
- sub = row.row(align=True)
- sub.prop(uvedit, "use_custom_grid", text="")
- sub = sub.row(align=True)
- sub.active = uvedit.use_custom_grid
- sub.prop(uvedit, "custom_grid_subdivisions", text="")
+ layout.row().prop(uvedit, "grid_shape_source", expand=True)
+
+ layout.use_property_split = True
+ layout.use_property_decorate = False
row = layout.row()
- row.use_property_split = True
- row.use_property_decorate = False
- row.prop(uvedit, "tile_grid_shape", text="Tiles")
+ row.prop(uvedit, "custom_grid_subdivisions", text="Fixed Subdivisions")
+ row.active = uvedit.grid_shape_source == 'FIXED'
+
+ layout.prop(uvedit, "tile_grid_shape", text="Tiles")
class IMAGE_PT_overlay_uv_edit(Panel):
diff --git a/release/scripts/startup/bl_ui/space_nla.py b/release/scripts/startup/bl_ui/space_nla.py
index 5157a215f34..b43434d9988 100644
--- a/release/scripts/startup/bl_ui/space_nla.py
+++ b/release/scripts/startup/bl_ui/space_nla.py
@@ -88,6 +88,7 @@ class NLA_MT_view(Menu):
st = context.space_data
layout.prop(st, "show_region_ui")
+ layout.prop(st, "show_region_hud")
layout.separator()
layout.prop(st, "use_realtime_update")
@@ -309,6 +310,11 @@ class NLA_MT_context_menu(Menu):
layout.separator()
+ layout.operator("nla.meta_add")
+ layout.operator("nla.meta_remove")
+
+ layout.separator()
+
layout.operator("nla.swap")
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index 118928ef9c6..593c6400529 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -219,10 +219,14 @@ class NODE_MT_add(bpy.types.Menu):
import nodeitems_utils
layout = self.layout
-
layout.operator_context = 'INVOKE_DEFAULT'
- if nodeitems_utils.has_node_categories(context):
+ snode = context.space_data
+ if snode.tree_type == 'GeometryNodeTree':
+ props = layout.operator("node.add_search", text="Search...", icon='VIEWZOOM')
+ layout.separator()
+ layout.menu_contents("NODE_MT_geometry_node_add_all")
+ elif nodeitems_utils.has_node_categories(context):
props = layout.operator("node.add_search", text="Search...", icon='VIEWZOOM')
props.use_transform = True
@@ -314,6 +318,7 @@ class NODE_MT_node(Menu):
layout.operator("node.clipboard_copy", text="Copy")
layout.operator("node.clipboard_paste", text="Paste")
layout.operator("node.duplicate_move")
+ layout.operator("node.duplicate_move_linked")
layout.operator("node.delete")
layout.operator("node.delete_reconnect")
diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py
index 2b60158e3ae..8420d830257 100644
--- a/release/scripts/startup/bl_ui/space_outliner.py
+++ b/release/scripts/startup/bl_ui/space_outliner.py
@@ -54,7 +54,7 @@ class OUTLINER_HT_header(Header):
icon='FILTER',
)
- if display_mode in {'LIBRARIES' 'ORPHAN_DATA'}:
+ if display_mode in {'LIBRARIES', 'ORPHAN_DATA'}:
row.prop(space, "use_filter_id_type", text="", icon='FILTER')
sub = row.row(align=True)
sub.active = space.use_filter_id_type
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index a99df1164a0..e703cf7f9c6 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -683,7 +683,7 @@ class SEQUENCER_MT_add(Menu):
elif bpy_data_movieclips_len > 0:
layout.operator_menu_enum("sequencer.movieclip_strip_add", "clip", text="Clip", icon='TRACKER')
else:
- layout.menu("SEQUENCER_MT_add_empty", text="Clip", icon='TRACKER')
+ layout.menu("SEQUENCER_MT_add_empty", text="Clip", text_ctxt=i18n_contexts.id_movieclip, icon='TRACKER')
del bpy_data_movieclips_len
bpy_data_masks_len = len(bpy.data.masks)
diff --git a/release/scripts/startup/bl_ui/space_spreadsheet.py b/release/scripts/startup/bl_ui/space_spreadsheet.py
index 741ad544d67..846582b0142 100644
--- a/release/scripts/startup/bl_ui/space_spreadsheet.py
+++ b/release/scripts/startup/bl_ui/space_spreadsheet.py
@@ -11,34 +11,37 @@ class SPREADSHEET_HT_header(bpy.types.Header):
space = context.space_data
layout.template_header()
+ viewer_path = space.viewer_path.path
- if len(space.context_path) == 0:
- self.draw_without_context_path(layout)
+ if len(viewer_path) == 0:
+ self.draw_without_viewer_path(layout)
return
- root_context = space.context_path[0]
- if root_context.type != 'OBJECT':
- self.draw_without_context_path(layout)
+ root_context = viewer_path[0]
+ if root_context.type != 'ID':
+ self.draw_without_viewer_path(layout)
return
- obj = root_context.object
+ if not isinstance(root_context.id, bpy.types.Object):
+ self.draw_without_viewer_path(layout)
+ return
+ obj = root_context.id
if obj is None:
- self.draw_without_context_path(layout)
+ self.draw_without_viewer_path(layout)
return
layout.prop(space, "object_eval_state", text="")
- context_path = space.context_path
if space.object_eval_state == 'ORIGINAL':
# Only show first context.
- context_path = context_path[:1]
- if space.display_context_path_collapsed:
- self.draw_collapsed_context_path(context, layout, context_path)
+ viewer_path = viewer_path[:1]
+ if space.display_viewer_path_collapsed:
+ self.draw_collapsed_viewer_path(context, layout, viewer_path)
else:
- self.draw_full_context_path(context, layout, context_path)
+ self.draw_full_viewer_path(context, layout, viewer_path)
pin_icon = 'PINNED' if space.is_pinned else 'UNPINNED'
layout.operator("spreadsheet.toggle_pin", text="", icon=pin_icon, emboss=False)
- if space.object_eval_state == 'VIEWER_NODE' and len(context_path) < 3:
+ if space.object_eval_state == 'VIEWER_NODE' and len(viewer_path) < 3:
layout.label(text="No active viewer node", icon='INFO')
layout.separator_spacer()
@@ -49,50 +52,52 @@ class SPREADSHEET_HT_header(bpy.types.Header):
sub.prop(space, "show_only_selected", text="")
row.prop(space, "use_filter", toggle=True, icon='FILTER', icon_only=True)
- def draw_without_context_path(self, layout):
+ def draw_without_viewer_path(self, layout):
layout.label(text="No active context")
- def draw_full_context_path(self, context, layout, context_path):
+ def draw_full_viewer_path(self, context, layout, viewer_path):
space = context.space_data
row = layout.row()
- for ctx in context_path[:-1]:
+ for ctx in viewer_path[:-1]:
subrow = row.row(align=True)
self.draw_spreadsheet_context(subrow, ctx)
- self.draw_spreadsheet_context_path_icon(subrow, space)
+ self.draw_spreadsheet_viewer_path_icon(subrow, space)
- self.draw_spreadsheet_context(row, context_path[-1])
+ self.draw_spreadsheet_context(row, viewer_path[-1])
- def draw_collapsed_context_path(self, context, layout, context_path):
+ def draw_collapsed_viewer_path(self, context, layout, viewer_path):
space = context.space_data
row = layout.row(align=True)
- self.draw_spreadsheet_context(row, context_path[0])
- if len(context_path) == 1:
+ self.draw_spreadsheet_context(row, viewer_path[0])
+ if len(viewer_path) == 1:
return
- self.draw_spreadsheet_context_path_icon(row, space)
- if len(context_path) > 2:
- self.draw_spreadsheet_context_path_icon(row, space, icon='DOT')
- self.draw_spreadsheet_context_path_icon(row, space)
- self.draw_spreadsheet_context(row, context_path[-1])
+ self.draw_spreadsheet_viewer_path_icon(row, space)
+ if len(viewer_path) > 2:
+ self.draw_spreadsheet_viewer_path_icon(row, space, icon='DOT')
+ self.draw_spreadsheet_viewer_path_icon(row, space)
+ self.draw_spreadsheet_context(row, viewer_path[-1])
def draw_spreadsheet_context(self, layout, ctx):
- if ctx.type == 'OBJECT':
- if ctx.object is None:
- layout.label(text="<no object>", icon='OBJECT_DATA')
+ if ctx.type == 'ID':
+ if ctx.id is not None and isinstance(ctx.id, bpy.types.Object):
+ layout.label(text=ctx.id.name, icon='OBJECT_DATA')
else:
- layout.label(text=ctx.object.name, icon='OBJECT_DATA')
+ layout.label(text="Invalid id")
elif ctx.type == 'MODIFIER':
layout.label(text=ctx.modifier_name, icon='MODIFIER')
elif ctx.type == 'NODE':
layout.label(text=ctx.node_name, icon='NODE')
- def draw_spreadsheet_context_path_icon(self, layout, space, icon='RIGHTARROW_THIN'):
- layout.prop(space, "display_context_path_collapsed", icon_only=True, emboss=False, icon=icon)
+ def draw_spreadsheet_viewer_path_icon(self, layout, space, icon='RIGHTARROW_THIN'):
+ layout.prop(space, "display_viewer_path_collapsed", icon_only=True, emboss=False, icon=icon)
def selection_filter_available(self, space):
- root_context = space.context_path[0]
- if root_context.type != 'OBJECT':
+ root_context = space.viewer_path.path[0]
+ if root_context.type != 'ID':
+ return False
+ if not isinstance(root_context.id, bpy.types.Object):
return False
- obj = root_context.object
+ obj = root_context.id
if obj is None:
return False
if obj.type == 'MESH':
diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py
index d948ea09a74..3c04e71269d 100644
--- a/release/scripts/startup/bl_ui/space_time.py
+++ b/release/scripts/startup/bl_ui/space_time.py
@@ -120,6 +120,10 @@ class TIME_MT_view(Menu):
scene = context.scene
st = context.space_data
+ layout.prop(st, "show_region_hud")
+
+ layout.separator()
+
layout.prop(st, "show_seconds")
layout.prop(st, "show_locked_time")
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py
index 39dfdd0eecb..81acc0837aa 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_common.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py
@@ -232,7 +232,7 @@ class ToolSelectPanelHelper:
def _icon_value_from_icon_handle(icon_name):
import os
if icon_name is not None:
- assert(type(icon_name) is str)
+ assert type(icon_name) is str
icon_value = _icon_cache.get(icon_name)
if icon_value is None:
dirname = bpy.utils.system_resource('DATAFILES', path="icons")
diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py
index da089ea23b0..3320e1e24a7 100644
--- a/release/scripts/startup/bl_ui/space_topbar.py
+++ b/release/scripts/startup/bl_ui/space_topbar.py
@@ -2,7 +2,10 @@
import bpy
from bpy.types import Header, Menu, Panel
-from bpy.app.translations import pgettext_iface as iface_
+from bpy.app.translations import (
+ pgettext_iface as iface_,
+ contexts as i18n_contexts,
+)
class TOPBAR_HT_upper_bar(Header):
@@ -269,7 +272,7 @@ class TOPBAR_MT_file(Menu):
layout = self.layout
layout.operator_context = 'INVOKE_AREA'
- layout.menu("TOPBAR_MT_file_new", text="New", icon='FILE_NEW')
+ layout.menu("TOPBAR_MT_file_new", text="New", text_ctxt=i18n_contexts.id_windowmanager, icon='FILE_NEW')
layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER')
layout.menu("TOPBAR_MT_file_open_recent")
layout.operator("wm.revert_mainfile")
@@ -408,9 +411,16 @@ class TOPBAR_MT_file_defaults(Menu):
app_template, has_ext=False))
layout.operator("wm.save_homefile")
- props = layout.operator("wm.read_factory_settings")
if app_template:
+ display_name = bpy.path.display_name(iface_(app_template))
+ props = layout.operator("wm.read_factory_settings", text="Load Factory Blender Settings")
+ props.app_template = app_template
+ props = layout.operator("wm.read_factory_settings", text="Load Factory %s Settings" % display_name)
props.app_template = app_template
+ props.use_factory_startup_app_template_only = True
+ del display_name
+ else:
+ layout.operator("wm.read_factory_settings")
# Include technical operators here which would otherwise have no way for users to access.
@@ -724,7 +734,7 @@ class TOPBAR_MT_file_context_menu(Menu):
layout = self.layout
layout.operator_context = 'INVOKE_AREA'
- layout.menu("TOPBAR_MT_file_new", text="New", icon='FILE_NEW')
+ layout.menu("TOPBAR_MT_file_new", text="New", text_ctxt=i18n_contexts.id_windowmanager, icon='FILE_NEW')
layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER')
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 475ca8e9223..820a0e5ec60 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -109,7 +109,16 @@ class USERPREF_MT_save_load(Menu):
sub_revert.operator("wm.read_userpref", text="Revert to Saved Preferences")
layout.operator_context = 'INVOKE_AREA'
- layout.operator("wm.read_factory_userpref", text="Load Factory Preferences")
+
+ app_template = prefs.app_template
+ if app_template:
+ display_name = bpy.path.display_name(iface_(app_template))
+ layout.operator("wm.read_factory_userpref", text="Load Factory Blender Preferences")
+ props = layout.operator("wm.read_factory_userpref", text="Load Factory %s Preferences" % display_name)
+ props.use_factory_startup_app_template_only = True
+ del display_name
+ else:
+ layout.operator("wm.read_factory_userpref", text="Load Factory Preferences")
class USERPREF_PT_save_preferences(Panel):
@@ -388,17 +397,18 @@ class USERPREF_PT_edit_objects_duplicate_data(EditingPanel, CenterAlignMixIn, Pa
# col.prop(edit, "use_duplicate_fcurve", text="F-Curve") # Not implemented.
col.prop(edit, "use_duplicate_curves", text="Curves")
col.prop(edit, "use_duplicate_grease_pencil", text="Grease Pencil")
+ col.prop(edit, "use_duplicate_lattice", text="Lattice")
col = flow.column()
- col.prop(edit, "use_duplicate_lattice", text="Lattice")
col.prop(edit, "use_duplicate_light", text="Light")
col.prop(edit, "use_duplicate_lightprobe", text="Light Probe")
col.prop(edit, "use_duplicate_material", text="Material")
col.prop(edit, "use_duplicate_mesh", text="Mesh")
col.prop(edit, "use_duplicate_metaball", text="Metaball")
+ col.prop(edit, "use_duplicate_node_tree", text="Node Tree")
+ col.prop(edit, "use_duplicate_particle", text="Particle")
col = flow.column()
- col.prop(edit, "use_duplicate_particle", text="Particle")
if hasattr(edit, "use_duplicate_pointcloud"):
col.prop(edit, "use_duplicate_pointcloud", text="Point Cloud")
col.prop(edit, "use_duplicate_speaker", text="Speaker")
@@ -1533,6 +1543,23 @@ class USERPREF_PT_input_mouse(InputPanel, CenterAlignMixIn, Panel):
flow.prop(inputs, "move_threshold")
+class USERPREF_PT_input_touchpad(InputPanel, CenterAlignMixIn, Panel):
+ bl_label = "Touchpad"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ import sys
+ return sys.platform[:3] == "win" or sys.platform == "darwin"
+
+ def draw_centered(self, context, layout):
+ prefs = context.preferences
+ inputs = prefs.inputs
+
+ col = layout.column()
+ col.prop(inputs, "use_multitouch_gestures")
+
+
class USERPREF_PT_input_tablet(InputPanel, CenterAlignMixIn, Panel):
bl_label = "Tablet"
@@ -2410,6 +2437,7 @@ classes = (
USERPREF_PT_input_keyboard,
USERPREF_PT_input_mouse,
USERPREF_PT_input_tablet,
+ USERPREF_PT_input_touchpad,
USERPREF_PT_input_ndof,
USERPREF_PT_navigation_orbit,
USERPREF_PT_navigation_zoom,
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index a687f3c937f..947f9056df7 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -108,7 +108,7 @@ class VIEW3D_HT_tool_header(Header):
brush = context.tool_settings.gpencil_sculpt_paint.brush
if brush:
tool = brush.gpencil_sculpt_tool
- if tool != 'CLONE':
+ if tool in {'SMOOTH', 'RANDOMIZE'}:
layout.popover("VIEW3D_PT_tools_grease_pencil_sculpt_brush_popover")
layout.popover("VIEW3D_PT_tools_grease_pencil_sculpt_appearance")
elif tool_mode == 'WEIGHT_GPENCIL':
@@ -837,13 +837,23 @@ class VIEW3D_HT_header(Header):
panel="VIEW3D_PT_gpencil_guide",
text="Guides",
)
-
- layout.separator_spacer()
+ if object_mode == 'SCULPT_GPENCIL':
+ layout.popover(
+ panel="VIEW3D_PT_gpencil_sculpt_automasking",
+ text="",
+ icon="MOD_MASK"
+ )
+ elif object_mode == 'SCULPT':
+ layout.popover(
+ panel="VIEW3D_PT_sculpt_automasking",
+ text="",
+ icon="MOD_MASK"
+ )
else:
# Transform settings depending on tool header visibility
VIEW3D_HT_header.draw_xform_template(layout, context)
- layout.separator_spacer()
+ layout.separator_spacer()
# Viewport Settings
layout.popover(
@@ -1216,6 +1226,7 @@ class VIEW3D_MT_view(Menu):
layout.operator("view3d.view_all").center = False
layout.operator("view3d.view_persportho", text="Perspective/Orthographic")
layout.menu("VIEW3D_MT_view_local")
+ layout.prop(view, "show_viewer", text="Viewer Node")
layout.separator()
@@ -3011,6 +3022,7 @@ class VIEW3D_MT_brush_paint_modes(Menu):
layout.prop(brush, "use_paint_vertex", text="Vertex Paint")
layout.prop(brush, "use_paint_weight", text="Weight Paint")
layout.prop(brush, "use_paint_image", text="Texture Paint")
+ layout.prop(brush, "use_paint_sculpt_curves", text="Sculpt Curves")
class VIEW3D_MT_paint_vertex(Menu):
@@ -3113,21 +3125,33 @@ class VIEW3D_MT_paint_weight_lock(Menu):
op = layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All")
op.action, op.mask = 'LOCK', 'ALL'
- op = layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock All")
- op.action, op.mask = 'UNLOCK', 'ALL'
- op = layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock Selected")
+
+ op = layout.operator("object.vertex_group_lock", text="Lock Selected")
op.action, op.mask = 'LOCK', 'SELECTED'
- op = layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock Selected")
- op.action, op.mask = 'UNLOCK', 'SELECTED'
- op = layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock Unselected")
+
+ op = layout.operator("object.vertex_group_lock", text="Lock Unselected")
op.action, op.mask = 'LOCK', 'UNSELECTED'
- op = layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock Unselected")
- op.action, op.mask = 'UNLOCK', 'UNSELECTED'
+
op = layout.operator("object.vertex_group_lock", text="Lock Only Selected")
op.action, op.mask = 'LOCK', 'INVERT_UNSELECTED'
+
op = layout.operator("object.vertex_group_lock", text="Lock Only Unselected")
op.action, op.mask = 'UNLOCK', 'INVERT_UNSELECTED'
- op = layout.operator("object.vertex_group_lock", text="Invert Locks")
+
+ layout.separator()
+
+ op = layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock All")
+ op.action, op.mask = 'UNLOCK', 'ALL'
+
+ op = layout.operator("object.vertex_group_lock", text="Unlock Selected")
+ op.action, op.mask = 'UNLOCK', 'SELECTED'
+
+ op = layout.operator("object.vertex_group_lock", text="Unlock Unselected")
+ op.action, op.mask = 'UNLOCK', 'UNSELECTED'
+
+ layout.separator()
+
+ op = layout.operator("object.vertex_group_lock", icon='ARROW_LEFTRIGHT', text="Invert Locks")
op.action, op.mask = 'INVERT', 'ALL'
@@ -3297,7 +3321,8 @@ class VIEW3D_MT_mask(Menu):
layout.separator()
- props = layout.operator("sculpt.dirty_mask", text='Dirty Mask')
+ props = layout.operator("sculpt.mask_from_cavity", text="Mask From Cavity")
+ props.use_automask_settings = False
layout.separator()
@@ -3354,8 +3379,7 @@ class VIEW3D_MT_face_sets(Menu):
op = layout.operator("sculpt.face_set_change_visibility", text='Invert Visible Face Sets')
op.mode = 'INVERT'
- op = layout.operator("sculpt.face_set_change_visibility", text='Show All Face Sets')
- op.mode = 'SHOW_ALL'
+ op = layout.operator("sculpt.reveal_all", text='Show All Face Sets')
layout.separator()
@@ -5493,6 +5517,26 @@ class VIEW3D_MT_sculpt_automasking_pie(Menu):
pie.prop(sculpt, "use_automasking_face_sets", text="Face Sets")
pie.prop(sculpt, "use_automasking_boundary_edges", text="Mesh Boundary")
pie.prop(sculpt, "use_automasking_boundary_face_sets", text="Face Sets Boundary")
+ pie.prop(sculpt, "use_automasking_cavity", text="Cavity")
+ pie.prop(sculpt, "use_automasking_cavity_inverted", text="Cavity (Inverted)")
+ pie.prop(sculpt, "use_automasking_start_normal", text="Area Normal")
+ pie.prop(sculpt, "use_automasking_view_normal", text="View Normal")
+
+
+class VIEW3D_MT_sculpt_gpencil_automasking_pie(Menu):
+ bl_label = "Automasking"
+
+ def draw(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+
+ tool_settings = context.tool_settings
+
+ pie.prop(tool_settings.gpencil_sculpt, "use_automasking_stroke", text="Stroke")
+ pie.prop(tool_settings.gpencil_sculpt, "use_automasking_layer_stroke", text="Layer")
+ pie.prop(tool_settings.gpencil_sculpt, "use_automasking_material_stroke", text="Material")
+ pie.prop(tool_settings.gpencil_sculpt, "use_automasking_layer_active", text="Active Layer")
+ pie.prop(tool_settings.gpencil_sculpt, "use_automasking_material_active", text="Active Material")
class VIEW3D_MT_sculpt_face_sets_edit_pie(Menu):
@@ -5512,8 +5556,7 @@ class VIEW3D_MT_sculpt_face_sets_edit_pie(Menu):
op = pie.operator("sculpt.face_set_change_visibility", text='Invert Visible')
op.mode = 'INVERT'
- op = pie.operator("sculpt.face_set_change_visibility", text='Show All')
- op.mode = 'SHOW_ALL'
+ op = pie.operator("sculpt.reveal_all", text='Show All')
class VIEW3D_MT_wpaint_vgroup_lock_pie(Menu):
@@ -6347,6 +6390,13 @@ class VIEW3D_PT_overlay_geometry(Panel):
sub.prop(overlay, "wireframe_opacity", text="Opacity")
row = col.row(align=True)
+ row.active = view.show_viewer
+ row.prop(overlay, "show_viewer_attribute", text="")
+ subrow = row.row(align=True)
+ subrow.active = overlay.show_viewer_attribute
+ subrow.prop(overlay, "viewer_attribute_opacity", text="Viewer Node")
+
+ row = col.row(align=True)
# These properties should be always available in the UI for all modes
# other than Object.
@@ -7437,6 +7487,27 @@ def draw_gpencil_material_active(context, layout):
row.prop(ma, "name", text="")
+class VIEW3D_PT_gpencil_sculpt_automasking(Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'HEADER'
+ bl_label = "Auto-masking"
+ bl_ui_units_x = 10
+
+ def draw(self, context):
+ layout = self.layout
+
+ tool_settings = context.scene.tool_settings
+ layout.label(text="Auto-masking")
+
+ col = layout.column(align=True)
+ col.prop(tool_settings.gpencil_sculpt, "use_automasking_stroke", text="Stroke")
+ col.prop(tool_settings.gpencil_sculpt, "use_automasking_layer_stroke", text="Layer")
+ col.prop(tool_settings.gpencil_sculpt, "use_automasking_material_stroke", text="Material")
+ col.separator()
+ col.prop(tool_settings.gpencil_sculpt, "use_automasking_layer_active", text="Active Layer")
+ col.prop(tool_settings.gpencil_sculpt, "use_automasking_material_active", text="Active Material")
+
+
class VIEW3D_PT_gpencil_sculpt_context_menu(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'WINDOW'
@@ -7669,6 +7740,77 @@ class VIEW3D_PT_paint_weight_context_menu(Panel):
)
+class VIEW3D_PT_sculpt_automasking(Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'HEADER'
+ bl_label = "Auto-Masking"
+ bl_ui_units_x = 10
+
+ def draw(self, context):
+ layout = self.layout
+
+ tool_settings = context.tool_settings
+ sculpt = tool_settings.sculpt
+ layout.label(text="Auto-Masking")
+
+ col = layout.column(align=True)
+ col.prop(sculpt, "use_automasking_topology", text="Topology")
+ col.prop(sculpt, "use_automasking_face_sets", text="Face Sets")
+
+ col.separator()
+
+ col = layout.column(align=True)
+ col.prop(sculpt, "use_automasking_boundary_edges", text="Mesh Boundary")
+ col.prop(sculpt, "use_automasking_boundary_face_sets", text="Face Sets Boundary")
+
+ if sculpt.use_automasking_boundary_edges or sculpt.use_automasking_boundary_face_sets:
+ col.prop(sculpt.brush, "automasking_boundary_edges_propagation_steps")
+
+ col.separator()
+
+ col = layout.column(align=True)
+ row = col.row()
+ row.prop(sculpt, "use_automasking_cavity", text="Cavity")
+
+ is_cavity_active = sculpt.use_automasking_cavity or sculpt.use_automasking_cavity_inverted
+
+ if is_cavity_active:
+ row.operator("sculpt.mask_from_cavity", text="Create Mask")
+
+ col.prop(sculpt, "use_automasking_cavity_inverted", text="Cavity (inverted)")
+
+ if is_cavity_active:
+ col = layout.column(align=True)
+ col.prop(sculpt, "automasking_cavity_factor", text="Factor")
+ col.prop(sculpt, "automasking_cavity_blur_steps", text="Blur")
+
+ col = layout.column()
+ col.prop(sculpt, "use_automasking_custom_cavity_curve", text="Custom Curve")
+
+ if sculpt.use_automasking_custom_cavity_curve:
+ col.template_curve_mapping(sculpt, "automasking_cavity_curve")
+
+ col.separator()
+
+ col = layout.column(align=True)
+ col.prop(sculpt, "use_automasking_view_normal", text="View Normal")
+
+ if sculpt.use_automasking_view_normal:
+ col.prop(sculpt, "use_automasking_view_occlusion", text="Occlusion")
+ subcol = col.column(align=True)
+ subcol.active = not sculpt.use_automasking_view_occlusion
+ subcol.prop(sculpt, "automasking_view_normal_limit", text="Limit")
+ subcol.prop(sculpt, "automasking_view_normal_falloff", text="Falloff")
+
+ col = layout.column()
+ col.prop(sculpt, "use_automasking_start_normal", text="Area Normal")
+
+ if sculpt.use_automasking_start_normal:
+ col = layout.column(align=True)
+ col.prop(sculpt, "automasking_start_normal_limit", text="Limit")
+ col.prop(sculpt, "automasking_start_normal_falloff", text="Falloff")
+
+
class VIEW3D_PT_sculpt_context_menu(Panel):
# Only for popover, these are dummy values.
bl_space_type = 'VIEW_3D'
@@ -8002,6 +8144,7 @@ classes = (
VIEW3D_MT_proportional_editing_falloff_pie,
VIEW3D_MT_sculpt_mask_edit_pie,
VIEW3D_MT_sculpt_automasking_pie,
+ VIEW3D_MT_sculpt_gpencil_automasking_pie,
VIEW3D_MT_wpaint_vgroup_lock_pie,
VIEW3D_MT_sculpt_face_sets_edit_pie,
VIEW3D_MT_sculpt_curves,
@@ -8016,6 +8159,7 @@ classes = (
VIEW3D_PT_annotation_onion,
VIEW3D_PT_gpencil_multi_frame,
VIEW3D_PT_gpencil_curve_edit,
+ VIEW3D_PT_gpencil_sculpt_automasking,
VIEW3D_PT_quad_view,
VIEW3D_PT_view3d_stereo,
VIEW3D_PT_shading,
@@ -8059,6 +8203,7 @@ classes = (
VIEW3D_PT_gpencil_sculpt_context_menu,
VIEW3D_PT_gpencil_weight_context_menu,
VIEW3D_PT_gpencil_draw_context_menu,
+ VIEW3D_PT_sculpt_automasking,
VIEW3D_PT_sculpt_context_menu,
TOPBAR_PT_gpencil_materials,
TOPBAR_PT_gpencil_vertexcolor,
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index d15be4a9d3f..111fb0d8bae 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-or-later
-from bpy.types import Menu, Panel, UIList
+from bpy.types import Menu, Panel, UIList, WindowManager
from bl_ui.properties_grease_pencil_common import (
GreasePencilSculptAdvancedPanel,
GreasePencilDisplayPanel,
@@ -52,6 +52,8 @@ class VIEW3D_MT_brush_context_menu(Menu):
elif context.sculpt_object:
layout.prop_menu_enum(brush, "sculpt_tool")
layout.operator("brush.reset")
+ elif context.tool_settings.curves_sculpt:
+ layout.prop_menu_enum(brush, "curves_sculpt_tool")
class VIEW3D_MT_brush_gpencil_context_menu(Menu):
@@ -81,22 +83,6 @@ class VIEW3D_MT_brush_gpencil_context_menu(Menu):
layout.operator("gpencil.brush_reset_all")
-class VIEW3D_MT_brush_context_menu_paint_modes(Menu):
- bl_label = "Enabled Modes"
-
- def draw(self, context):
- layout = self.layout
-
- settings = UnifiedPaintPanel.paint_settings(context)
- brush = settings.brush
-
- layout.prop(brush, "use_paint_sculpt", text="Sculpt")
- layout.prop(brush, "use_paint_uv_sculpt", text="UV Sculpt")
- layout.prop(brush, "use_paint_vertex", text="Vertex Paint")
- layout.prop(brush, "use_paint_weight", text="Weight Paint")
- layout.prop(brush, "use_paint_image", text="Texture Paint")
-
-
class View3DPanel:
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
@@ -278,7 +264,7 @@ class TEXTURE_UL_texpaintslots(UIList):
# mat = data
if self.layout_type in {'DEFAULT', 'COMPACT'}:
- layout.prop(item, "name", text="", emboss=False, icon_value=item.icon_value)
+ layout.label(text=item.name, icon_value=item.icon_value)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="")
@@ -964,14 +950,6 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
col.prop(sculpt, "use_sculpt_delay_updates")
col.prop(sculpt, "use_deform_only")
- col.separator()
-
- col = layout.column(heading="Auto-Masking", align=True)
- col.prop(sculpt, "use_automasking_topology", text="Topology")
- col.prop(sculpt, "use_automasking_face_sets", text="Face Sets")
- col.prop(sculpt, "use_automasking_boundary_edges", text="Mesh Boundary")
- col.prop(sculpt, "use_automasking_boundary_face_sets", text="Face Sets Boundary")
-
class VIEW3D_PT_sculpt_options_gravity(Panel, View3DPaintPanel):
bl_context = ".sculpt_mode" # dot on purpose (access from topbar)
@@ -1606,19 +1584,6 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel):
row.prop(gp_settings, "fill_layer_mode", text="Layers")
col.separator()
- row = col.row(align=True)
- row.prop(gp_settings, "extend_stroke_factor")
- row.prop(
- gp_settings,
- "show_fill_extend",
- icon='HIDE_OFF' if gp_settings.show_fill_extend else 'HIDE_ON',
- text="",
- )
-
- col.separator()
- col.prop(gp_settings, "fill_leak", text="Leak Size")
-
- col.separator()
col.prop(gp_settings, "fill_simplify_level", text="Simplify")
if gp_settings.fill_draw_mode != 'STROKE':
col = layout.column(align=False, heading="Ignore Transparent")
@@ -1878,6 +1843,39 @@ class VIEW3D_PT_tools_grease_pencil_brush_paint_falloff(GreasePencilBrushFalloff
return (settings and settings.brush and settings.brush.curve and gptool == 'TINT')
+class VIEW3D_PT_tools_grease_pencil_brush_gap_closure(View3DPanel, Panel):
+ bl_context = ".greasepencil_paint"
+ bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_advanced'
+ bl_label = "Gap Closure"
+ bl_category = "Tool"
+
+ @classmethod
+ def poll(cls, context):
+ brush = context.tool_settings.gpencil_paint.brush
+ return brush is not None and brush.gpencil_tool == 'FILL'
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ tool_settings = context.tool_settings
+ brush = tool_settings.gpencil_paint.brush
+ gp_settings = brush.gpencil_settings
+
+ col = layout.column()
+
+ col.prop(gp_settings, "extend_stroke_factor", text="Size")
+ row = col.row(align=True)
+ row.prop(gp_settings, "fill_extend_mode", text="Mode")
+ row = col.row(align=True)
+ row.prop(gp_settings, "show_fill_extend", text="Visual Aids")
+
+ if gp_settings.fill_extend_mode == 'EXTEND':
+ row = col.row(align=True)
+ row.prop(gp_settings, "use_collide_strokes")
+
+
# Grease Pencil stroke sculpting tools
class GreasePencilSculptPanel:
bl_context = ".greasepencil_sculpt"
@@ -1917,7 +1915,7 @@ class VIEW3D_PT_tools_grease_pencil_sculpt_select(Panel, View3DPanel, GreasePenc
if brush is not None:
col.prop(brush, "use_custom_icon", toggle=True, icon='FILE_IMAGE', text="")
- if(brush.use_custom_icon):
+ if (brush.use_custom_icon):
layout.row().prop(brush, "icon_filepath", text="")
@@ -1966,7 +1964,7 @@ class VIEW3D_PT_tools_grease_pencil_sculpt_brush_advanced(GreasePencilSculptAdva
return False
tool = brush.gpencil_sculpt_tool
- return tool != 'CLONE'
+ return tool in {'SMOOTH', 'RANDOMIZE'}
class VIEW3D_PT_tools_grease_pencil_sculpt_brush_popover(GreasePencilSculptAdvancedPanel, View3DPanel, Panel):
@@ -1984,7 +1982,7 @@ class VIEW3D_PT_tools_grease_pencil_sculpt_brush_popover(GreasePencilSculptAdvan
return False
tool = brush.gpencil_sculpt_tool
- return tool != 'CLONE'
+ return tool in {'SMOOTH', 'RANDOMIZE'}
# Grease Pencil weight painting tools
@@ -2026,7 +2024,7 @@ class VIEW3D_PT_tools_grease_pencil_weight_paint_select(View3DPanel, Panel, Grea
if brush is not None:
col.prop(brush, "use_custom_icon", toggle=True, icon='FILE_IMAGE', text="")
- if(brush.use_custom_icon):
+ if (brush.use_custom_icon):
layout.row().prop(brush, "icon_filepath", text="")
@@ -2101,7 +2099,7 @@ class VIEW3D_PT_tools_grease_pencil_vertex_paint_select(View3DPanel, Panel, Grea
if brush is not None:
col.prop(brush, "use_custom_icon", toggle=True, icon='FILE_IMAGE', text="")
- if(brush.use_custom_icon):
+ if (brush.use_custom_icon):
layout.row().prop(brush, "icon_filepath", text="")
@@ -2361,7 +2359,6 @@ class VIEW3D_PT_gpencil_brush_presets(Panel, PresetPanel):
classes = (
VIEW3D_MT_brush_context_menu,
VIEW3D_MT_brush_gpencil_context_menu,
- VIEW3D_MT_brush_context_menu_paint_modes,
VIEW3D_PT_tools_object_options,
VIEW3D_PT_tools_object_options_transform,
VIEW3D_PT_tools_meshedit_options,
@@ -2430,6 +2427,7 @@ classes = (
VIEW3D_PT_tools_grease_pencil_brush_post_processing,
VIEW3D_PT_tools_grease_pencil_brush_random,
VIEW3D_PT_tools_grease_pencil_brush_stabilizer,
+ VIEW3D_PT_tools_grease_pencil_brush_gap_closure,
VIEW3D_PT_tools_grease_pencil_paint_appearance,
VIEW3D_PT_tools_grease_pencil_sculpt_select,
VIEW3D_PT_tools_grease_pencil_sculpt_settings,
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index a6609eb80fc..d1946b2f01d 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -40,21 +40,14 @@ class TextureNodeCategory(SortedNodeCategory):
context.space_data.tree_type == 'TextureNodeTree')
-class GeometryNodeCategory(SortedNodeCategory):
- @classmethod
- def poll(cls, context):
- return (context.space_data.type == 'NODE_EDITOR' and
- context.space_data.tree_type == 'GeometryNodeTree')
-
-
-# menu entry for node group tools
+# Menu entry for node group tools.
def group_tools_draw(_self, layout, _context):
layout.operator("node.group_make")
layout.operator("node.group_ungroup")
layout.separator()
-# maps node tree type to group node type
+# Maps node tree type to group node type.
node_tree_group_type = {
'CompositorNodeTree': 'CompositorNodeGroup',
'ShaderNodeTree': 'ShaderNodeGroup',
@@ -63,192 +56,6 @@ node_tree_group_type = {
}
-# Custom Menu for Geometry Node Curves.
-def curve_node_items(context):
- if context is None:
- return
- space = context.space_data
- if not space:
- return
- yield NodeItem("GeometryNodeCurveLength")
- yield NodeItem("GeometryNodeCurveToMesh")
- yield NodeItem("GeometryNodeCurveToPoints")
- yield NodeItem("GeometryNodeDeformCurvesOnSurface")
- yield NodeItem("GeometryNodeFillCurve")
- yield NodeItem("GeometryNodeFilletCurve")
- yield NodeItem("GeometryNodeResampleCurve")
- yield NodeItem("GeometryNodeReverseCurve")
- yield NodeItem("GeometryNodeSampleCurve")
- yield NodeItem("GeometryNodeSubdivideCurve")
- yield NodeItem("GeometryNodeTrimCurve")
- yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
- yield NodeItem("GeometryNodeInputCurveHandlePositions")
- yield NodeItem("GeometryNodeInputTangent")
- yield NodeItem("GeometryNodeInputCurveTilt")
- yield NodeItem("GeometryNodeCurveEndpointSelection")
- yield NodeItem("GeometryNodeCurveHandleTypeSelection")
- yield NodeItem("GeometryNodeInputSplineCyclic")
- yield NodeItem("GeometryNodeSplineLength")
- yield NodeItem("GeometryNodeSplineParameter")
- yield NodeItem("GeometryNodeInputSplineResolution")
- yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
- yield NodeItem("GeometryNodeSetCurveRadius")
- yield NodeItem("GeometryNodeSetCurveTilt")
- yield NodeItem("GeometryNodeSetCurveHandlePositions")
- yield NodeItem("GeometryNodeCurveSetHandles")
- yield NodeItem("GeometryNodeSetSplineCyclic")
- yield NodeItem("GeometryNodeSetSplineResolution")
- yield NodeItem("GeometryNodeCurveSplineType")
-
-
-# Custom Menu for Geometry Node Mesh.
-def mesh_node_items(context):
- if context is None:
- return
- space = context.space_data
- if not space:
- return
- yield NodeItem("GeometryNodeDualMesh")
- yield NodeItem("GeometryNodeEdgePathsToCurves")
- yield NodeItem("GeometryNodeEdgePathsToSelection")
- yield NodeItem("GeometryNodeExtrudeMesh")
- yield NodeItem("GeometryNodeFlipFaces")
- yield NodeItem("GeometryNodeMeshBoolean")
- yield NodeItem("GeometryNodeMeshToCurve")
- yield NodeItem("GeometryNodeMeshToPoints")
- yield NodeItem("GeometryNodeMeshToVolume")
- yield NodeItem("GeometryNodeScaleElements")
- yield NodeItem("GeometryNodeSplitEdges")
- yield NodeItem("GeometryNodeSubdivideMesh")
- yield NodeItem("GeometryNodeSubdivisionSurface")
- yield NodeItem("GeometryNodeTriangulate")
- yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
- yield NodeItem("GeometryNodeInputMeshEdgeAngle")
- yield NodeItem("GeometryNodeInputMeshEdgeNeighbors")
- yield NodeItem("GeometryNodeInputMeshEdgeVertices")
- yield NodeItem("GeometryNodeInputMeshFaceArea")
- yield NodeItem("GeometryNodeInputMeshFaceNeighbors")
- yield NodeItem("GeometryNodeInputMeshFaceIsPlanar")
- yield NodeItem("GeometryNodeInputShadeSmooth")
- yield NodeItem("GeometryNodeInputMeshIsland")
- yield NodeItem("GeometryNodeInputShortestEdgePaths")
- yield NodeItem("GeometryNodeInputMeshVertexNeighbors")
- yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
- yield NodeItem("GeometryNodeSetShadeSmooth")
-
-
-# Custom Menu for Geometry Nodes "Geometry" category.
-def geometry_node_items(context):
- if context is None:
- return
- space = context.space_data
- if not space:
- return
- yield NodeItem("GeometryNodeBoundBox")
- yield NodeItem("GeometryNodeConvexHull")
- yield NodeItem("GeometryNodeDeleteGeometry")
- yield NodeItem("GeometryNodeDuplicateElements")
- yield NodeItem("GeometryNodeProximity")
- yield NodeItem("GeometryNodeGeometryToInstance")
- yield NodeItem("GeometryNodeJoinGeometry")
- yield NodeItem("GeometryNodeMergeByDistance")
- yield NodeItem("GeometryNodeRaycast")
- yield NodeItem("GeometryNodeSeparateComponents")
- yield NodeItem("GeometryNodeSeparateGeometry")
- yield NodeItem("GeometryNodeTransform")
- yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
- yield NodeItem("GeometryNodeSetID")
- yield NodeItem("GeometryNodeSetPosition")
-
-
-# Custom Menu for UV Nodes.
-def uv_node_items(context):
- if context is None:
- return
- space = context.space_data
- if not space:
- return
- yield NodeItem("GeometryNodeUVPackIslands")
- yield NodeItem("GeometryNodeUVUnwrap")
-
-
-# Custom Menu for Geometry Node Input Nodes.
-def geometry_input_node_items(context):
- if context is None:
- return
- space = context.space_data
- if not space:
- return
- yield NodeItem("FunctionNodeInputBool")
- yield NodeItem("GeometryNodeCollectionInfo")
- yield NodeItem("FunctionNodeInputColor")
- yield NodeItem("FunctionNodeInputInt")
- yield NodeItem("GeometryNodeIsViewport")
- yield NodeItem("GeometryNodeInputMaterial")
- yield NodeItem("GeometryNodeObjectInfo")
- yield NodeItem("FunctionNodeInputString")
- yield NodeItem("ShaderNodeValue")
- yield NodeItem("FunctionNodeInputVector")
- yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
- yield NodeItem("GeometryNodeInputID")
- yield NodeItem("GeometryNodeInputIndex")
- yield NodeItem("GeometryNodeInputNamedAttribute")
- yield NodeItem("GeometryNodeInputNormal")
- yield NodeItem("GeometryNodeInputPosition")
- yield NodeItem("GeometryNodeInputRadius")
- yield NodeItem("GeometryNodeInputSceneTime")
-
-
-# Custom Menu for Geometry Node Instance Nodes.
-def geometry_instance_node_items(context):
- if context is None:
- return
- space = context.space_data
- if not space:
- return
- yield NodeItem("GeometryNodeInstanceOnPoints")
- yield NodeItem("GeometryNodeInstancesToPoints")
- yield NodeItem("GeometryNodeRealizeInstances")
- yield NodeItem("GeometryNodeRotateInstances")
- yield NodeItem("GeometryNodeScaleInstances")
- yield NodeItem("GeometryNodeTranslateInstances")
- yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
- yield NodeItem("GeometryNodeInputInstanceRotation")
- yield NodeItem("GeometryNodeInputInstanceScale")
-
-
-# Custom Menu for Material Nodes.
-def geometry_material_node_items(context):
- if context is None:
- return
- space = context.space_data
- if not space:
- return
- yield NodeItem("GeometryNodeReplaceMaterial")
- yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
- yield NodeItem("GeometryNodeInputMaterialIndex")
- yield NodeItem("GeometryNodeMaterialSelection")
- yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
- yield NodeItem("GeometryNodeSetMaterial")
- yield NodeItem("GeometryNodeSetMaterialIndex")
-
-
-# Custom Menu for Geometry Node Points.
-def point_node_items(context):
- if context is None:
- return
- space = context.space_data
- if not space:
- return
- yield NodeItem("GeometryNodeDistributePointsOnFaces")
- yield NodeItem("GeometryNodePoints")
- yield NodeItem("GeometryNodePointsToVertices")
- yield NodeItem("GeometryNodePointsToVolume")
- yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
- yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
- yield NodeItem("GeometryNodeSetPointRadius")
-
-
# Generic node group items generator for shader, compositor, geometry and texture node groups.
def node_group_items(context):
if context is None:
@@ -259,8 +66,9 @@ def node_group_items(context):
yield NodeItemCustom(draw=group_tools_draw)
- yield NodeItem("NodeGroupInput", poll=group_input_output_item_poll)
- yield NodeItem("NodeGroupOutput", poll=group_input_output_item_poll)
+ if group_input_output_item_poll(context):
+ yield NodeItem("NodeGroupInput")
+ yield NodeItem("NodeGroupOutput")
ntree = space.edit_tree
if not ntree:
@@ -424,6 +232,7 @@ shader_node_categories = [
NodeItem("ShaderNodeTexWhiteNoise"),
]),
ShaderNodeCategory("SH_NEW_OP_COLOR", "Color", items=[
+ NodeItem("ShaderNodeMix", label="Mix Color", settings={"data_type": "'RGBA'"}),
NodeItem("ShaderNodeRGBCurve"),
NodeItem("ShaderNodeInvert"),
NodeItem("ShaderNodeLightFalloff"),
@@ -640,122 +449,17 @@ texture_node_categories = [
]),
]
-geometry_node_categories = [
- # Geometry Nodes
- GeometryNodeCategory("GEO_ATTRIBUTE", "Attribute", items=[
- NodeItem("GeometryNodeCaptureAttribute"),
- NodeItem("GeometryNodeAttributeDomainSize"),
- NodeItem("GeometryNodeAttributeStatistic"),
- NodeItem("GeometryNodeAttributeTransfer"),
- NodeItem("GeometryNodeRemoveAttribute"),
- NodeItem("GeometryNodeStoreNamedAttribute"),
- ]),
- GeometryNodeCategory("GEO_COLOR", "Color", items=[
- NodeItem("ShaderNodeRGBCurve"),
- NodeItem("ShaderNodeValToRGB"),
- NodeItem("FunctionNodeSeparateColor"),
- NodeItem("FunctionNodeCombineColor"),
- ]),
- GeometryNodeCategory("GEO_CURVE", "Curve", items=curve_node_items),
- GeometryNodeCategory("GEO_PRIMITIVES_CURVE", "Curve Primitives", items=[
- NodeItem("GeometryNodeCurvePrimitiveLine"),
- NodeItem("GeometryNodeCurvePrimitiveCircle"),
- NodeItem("GeometryNodeCurveStar"),
- NodeItem("GeometryNodeCurveSpiral"),
- NodeItem("GeometryNodeCurveArc"),
- NodeItem("GeometryNodeCurveQuadraticBezier"),
- NodeItem("GeometryNodeCurvePrimitiveQuadrilateral"),
- NodeItem("GeometryNodeCurvePrimitiveBezierSegment"),
- ]),
- GeometryNodeCategory("GEO_GEOMETRY", "Geometry", items=geometry_node_items),
- GeometryNodeCategory("GEO_INPUT", "Input", items=geometry_input_node_items),
- GeometryNodeCategory("GEO_INSTANCE", "Instances", items=geometry_instance_node_items),
- GeometryNodeCategory("GEO_MATERIAL", "Material", items=geometry_material_node_items),
- GeometryNodeCategory("GEO_MESH", "Mesh", items=mesh_node_items),
- GeometryNodeCategory("GEO_PRIMITIVES_MESH", "Mesh Primitives", items=[
- NodeItem("GeometryNodeMeshCircle"),
- NodeItem("GeometryNodeMeshCone"),
- NodeItem("GeometryNodeMeshCube"),
- NodeItem("GeometryNodeMeshCylinder"),
- NodeItem("GeometryNodeMeshGrid"),
- NodeItem("GeometryNodeMeshIcoSphere"),
- NodeItem("GeometryNodeMeshLine"),
- NodeItem("GeometryNodeMeshUVSphere"),
- ]),
- GeometryNodeCategory("GEO_OUTPUT", "Output", items=[
- NodeItem("GeometryNodeViewer"),
- ]),
- GeometryNodeCategory("GEO_POINT", "Point", items=point_node_items),
- GeometryNodeCategory("GEO_TEXT", "Text", items=[
- NodeItem("FunctionNodeStringLength"),
- NodeItem("FunctionNodeSliceString"),
- NodeItem("FunctionNodeValueToString"),
- NodeItem("GeometryNodeStringJoin"),
- NodeItem("FunctionNodeInputSpecialCharacters"),
- NodeItem("GeometryNodeStringToCurves"),
- NodeItem("FunctionNodeReplaceString"),
- ]),
- GeometryNodeCategory("GEO_TEXTURE", "Texture", items=[
- NodeItem("ShaderNodeTexBrick"),
- NodeItem("ShaderNodeTexChecker"),
- NodeItem("ShaderNodeTexGradient"),
- NodeItem("ShaderNodeTexMagic"),
- NodeItem("ShaderNodeTexMusgrave"),
- NodeItem("ShaderNodeTexNoise"),
- NodeItem("ShaderNodeTexVoronoi"),
- NodeItem("ShaderNodeTexWave"),
- NodeItem("ShaderNodeTexWhiteNoise"),
- NodeItem("GeometryNodeImageTexture"),
- ]),
- GeometryNodeCategory("GEO_UTILITIES", "Utilities", items=[
- NodeItem("GeometryNodeAccumulateField"),
- NodeItem("GeometryNodeFieldAtIndex"),
- NodeItem("GeometryNodeFieldOnDomain"),
- NodeItem("ShaderNodeMapRange"),
- NodeItem("ShaderNodeFloatCurve"),
- NodeItem("ShaderNodeClamp"),
- NodeItem("ShaderNodeMath"),
- NodeItem("FunctionNodeBooleanMath"),
- NodeItem("FunctionNodeRotateEuler"),
- NodeItem("FunctionNodeCompare"),
- NodeItem("ShaderNodeMix"),
- NodeItem("FunctionNodeFloatToInt"),
- NodeItem("GeometryNodeSwitch"),
- NodeItem("FunctionNodeRandomValue"),
- NodeItem("FunctionNodeAlignEulerToVector"),
- ]),
- GeometryNodeCategory("GEO_UV", "UV", items=uv_node_items),
- GeometryNodeCategory("GEO_VECTOR", "Vector", items=[
- NodeItem("ShaderNodeVectorCurve"),
- NodeItem("ShaderNodeSeparateXYZ"),
- NodeItem("ShaderNodeCombineXYZ"),
- NodeItem("ShaderNodeVectorMath"),
- NodeItem("ShaderNodeVectorRotate"),
- ]),
- GeometryNodeCategory("GEO_VOLUME", "Volume", items=[
- NodeItem("GeometryNodeVolumeCube"),
- NodeItem("GeometryNodeVolumeToMesh"),
- ]),
- GeometryNodeCategory("GEO_GROUP", "Group", items=node_group_items),
- GeometryNodeCategory("GEO_LAYOUT", "Layout", items=[
- NodeItem("NodeFrame"),
- NodeItem("NodeReroute"),
- ]),
-]
-
def register():
nodeitems_utils.register_node_categories('SHADER', shader_node_categories)
nodeitems_utils.register_node_categories('COMPOSITING', compositor_node_categories)
nodeitems_utils.register_node_categories('TEXTURE', texture_node_categories)
- nodeitems_utils.register_node_categories('GEOMETRY', geometry_node_categories)
def unregister():
nodeitems_utils.unregister_node_categories('SHADER')
nodeitems_utils.unregister_node_categories('COMPOSITING')
nodeitems_utils.unregister_node_categories('TEXTURE')
- nodeitems_utils.unregister_node_categories('GEOMETRY')
if __name__ == "__main__":
diff --git a/release/scripts/templates_py/custom_nodes.py b/release/scripts/templates_py/custom_nodes.py
index fba94e23d0d..fd2dfe91b39 100644
--- a/release/scripts/templates_py/custom_nodes.py
+++ b/release/scripts/templates_py/custom_nodes.py
@@ -61,7 +61,7 @@ class MyCustomTreeNode:
# Derived from the Node base type.
-class MyCustomNode(Node, MyCustomTreeNode):
+class MyCustomNode(MyCustomTreeNode, Node):
# === Basics ===
# Description string
'''A custom node'''
diff --git a/release/scripts/templates_py/operator_modal_draw.py b/release/scripts/templates_py/operator_modal_draw.py
index 78edf874791..77371a75605 100644
--- a/release/scripts/templates_py/operator_modal_draw.py
+++ b/release/scripts/templates_py/operator_modal_draw.py
@@ -19,7 +19,6 @@ def draw_callback_px(self, context):
gpu.state.blend_set('ALPHA')
gpu.state.line_width_set(2.0)
batch = batch_for_shader(shader, 'LINE_STRIP', {"pos": self.mouse_path})
- shader.bind()
shader.uniform_float("color", (0.0, 0.0, 0.0, 0.5))
batch.draw(shader)
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt
index 28c15d9224c..4dd596ad93a 100644
--- a/source/blender/CMakeLists.txt
+++ b/source/blender/CMakeLists.txt
@@ -82,6 +82,7 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_view2d_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_view3d_enums.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_view3d_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_viewer_path_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_volume_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_windowmanager_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_workspace_types.h
diff --git a/source/blender/blendthumb/src/blender_thumbnailer.cc b/source/blender/blendthumb/src/blender_thumbnailer.cc
index da0aef3d0e1..93a3d1530fc 100644
--- a/source/blender/blendthumb/src/blender_thumbnailer.cc
+++ b/source/blender/blendthumb/src/blender_thumbnailer.cc
@@ -95,5 +95,5 @@ int main(int argc, char *argv[])
eThumbStatus ret = extract_png_from_blend_file(argv[1], argv[2]);
- return (int)ret;
+ return int(ret);
}
diff --git a/source/blender/blendthumb/src/blendthumb_extract.cc b/source/blender/blendthumb/src/blendthumb_extract.cc
index fff1242f2ce..9a3e1cb73cc 100644
--- a/source/blender/blendthumb/src/blendthumb_extract.cc
+++ b/source/blender/blendthumb/src/blendthumb_extract.cc
@@ -103,7 +103,7 @@ static bool file_seek(FileReader *file, size_t len)
blender::Array<char> dummy_data(dummy_data_size);
while (len > 0) {
const size_t len_chunk = std::min(len, dummy_data_size);
- if ((size_t)file->read(file, dummy_data.data(), len_chunk) != len_chunk) {
+ if (size_t(file->read(file, dummy_data.data(), len_chunk)) != len_chunk) {
return false;
}
len -= len_chunk;
@@ -137,8 +137,7 @@ static eThumbStatus blendthumb_extract_from_file_impl(FileReader *file,
/* Verify that image dimensions and data size make sense. */
size_t data_size = block_size - sizeof(shape);
- const uint64_t expected_size = static_cast<uint64_t>(thumb->width) *
- static_cast<uint64_t>(thumb->height) * 4;
+ const uint64_t expected_size = uint64_t(thumb->width) * uint64_t(thumb->height) * 4;
if (thumb->width < 0 || thumb->height < 0 || data_size != expected_size) {
return BT_INVALID_THUMB;
}
diff --git a/source/blender/blendthumb/src/blendthumb_png.cc b/source/blender/blendthumb/src/blendthumb_png.cc
index 64326c9abb1..17c0492af42 100644
--- a/source/blender/blendthumb/src/blendthumb_png.cc
+++ b/source/blender/blendthumb/src/blendthumb_png.cc
@@ -61,7 +61,7 @@ static blender::Vector<uint8_t> filtered_rows_from_thumb(const Thumbnail *thumb)
static std::optional<blender::Vector<uint8_t>> zlib_compress(const blender::Vector<uint8_t> &data)
{
- unsigned long uncompressed_size = data.size();
+ ulong uncompressed_size = data.size();
uLongf compressed_size = compressBound(uncompressed_size);
blender::Vector<uint8_t> compressed(compressed_size, 0x00);
@@ -110,7 +110,7 @@ std::optional<blender::Vector<uint8_t>> blendthumb_create_png_data_from_thumb(
0x00, /* Filter method. */
0x00, /* Interlace method. */
});
- BLI_assert((size_t)ihdr_data.size() == ihdr_data_final_size);
+ BLI_assert(size_t(ihdr_data.size()) == ihdr_data_final_size);
}
/* Join it all together to create a PNG image. */
@@ -135,7 +135,7 @@ std::optional<blender::Vector<uint8_t>> blendthumb_create_png_data_from_thumb(
png_chunk_create(png_buf, MAKE_ID('I', 'D', 'A', 'T'), image_data);
png_chunk_create(png_buf, MAKE_ID('I', 'E', 'N', 'D'), {});
- BLI_assert((size_t)png_buf.size() == png_buf_final_size);
+ BLI_assert(size_t(png_buf.size()) == png_buf_final_size);
}
return png_buf;
diff --git a/source/blender/blendthumb/src/blendthumb_win32.cc b/source/blender/blendthumb/src/blendthumb_win32.cc
index 287710934e2..206309b6caf 100644
--- a/source/blender/blendthumb/src/blendthumb_win32.cc
+++ b/source/blender/blendthumb/src/blendthumb_win32.cc
@@ -110,7 +110,7 @@ static ssize_t stream_read(FileReader *reader, void *buffer, size_t size)
stream->_pStream->Read(buffer, size, &readsize);
stream->reader.offset += readsize;
- return (ssize_t)readsize;
+ return ssize_t(readsize);
}
static off64_t stream_seek(FileReader *reader, off64_t offset, int whence)
@@ -171,11 +171,11 @@ IFACEMETHODIMP CBlendThumb::GetThumbnail(UINT cx, HBITMAP *phbmp, WTS_ALPHATYPE
}
*pdwAlpha = WTSAT_ARGB;
- /* Scale down the thumbnail if required. */
- if ((unsigned)thumb.width > cx || (unsigned)thumb.height > cx) {
- float scale = 1.0f / (std::max(thumb.width, thumb.height) / (float)cx);
- LONG NewWidth = (LONG)(thumb.width * scale);
- LONG NewHeight = (LONG)(thumb.height * scale);
+ /* Scale up the thumbnail if required. */
+ if (uint(thumb.width) < cx && uint(thumb.height) < cx) {
+ float scale = 1.0f / (std::max(thumb.width, thumb.height) / float(cx));
+ LONG NewWidth = LONG(thumb.width * scale);
+ LONG NewHeight = LONG(thumb.height * scale);
IWICImagingFactory *pImgFac;
hr = CoCreateInstance(
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index d3226a8f609..01b6d1d8942 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -69,7 +69,7 @@ void BLF_metrics_attach(int fontid, unsigned char *mem, int mem_size);
void BLF_aspect(int fontid, float x, float y, float z);
void BLF_position(int fontid, float x, float y, float z);
-void BLF_size(int fontid, float size, int dpi);
+void BLF_size(int fontid, float size);
/* Goal: small but useful color API. */
@@ -118,10 +118,7 @@ int BLF_draw_mono(int fontid, const char *str, size_t str_len, int cwidth) ATTR_
typedef bool (*BLF_GlyphBoundsFn)(const char *str,
size_t str_step_ofs,
- const struct rcti *glyph_step_bounds,
- int glyph_advance_x,
- const struct rcti *glyph_bounds,
- const int glyph_bearing[2],
+ const struct rcti *bounds,
void *user_data);
/**
@@ -132,12 +129,6 @@ typedef bool (*BLF_GlyphBoundsFn)(const char *str,
*
* \note The font position, clipping, matrix and rotation are not applied.
*/
-void BLF_boundbox_foreach_glyph_ex(int fontid,
- const char *str,
- size_t str_len,
- BLF_GlyphBoundsFn user_fn,
- void *user_data,
- struct ResultBLF *r_info) ATTR_NONNULL(2);
void BLF_boundbox_foreach_glyph(int fontid,
const char *str,
size_t str_len,
@@ -145,6 +136,22 @@ void BLF_boundbox_foreach_glyph(int fontid,
void *user_data) ATTR_NONNULL(2);
/**
+ * Get the byte offset within a string, selected by mouse at a horizontal location.
+ */
+size_t BLF_str_offset_from_cursor_position(int fontid,
+ const char *str,
+ size_t str_len,
+ int location_x);
+
+/**
+ * Return bounds of the glyph rect at the string offset.
+ */
+bool BLF_str_offset_to_glyph_bounds(int fontid,
+ const char *str,
+ size_t str_offset,
+ struct rcti *glyph_bounds);
+
+/**
* Get the string byte offset that fits within a given width.
*/
size_t BLF_width_to_strlen(
@@ -290,20 +297,11 @@ void BLF_dir_free(char **dirs, int count) ATTR_NONNULL();
*
* \note called from a thread, so it bypasses the normal BLF_* api (which isn't thread-safe).
*/
-void BLF_thumb_preview(const char *filepath,
- const char **draw_str,
- const char **i18n_draw_str,
- unsigned char draw_str_lines,
- const float font_color[4],
- int font_size,
- unsigned char *buf,
- int w,
- int h,
- int channels) ATTR_NONNULL();
+bool BLF_thumb_preview(const char *filename, unsigned char *buf, int w, int h, int channels)
+ ATTR_NONNULL();
/* blf_default.c */
-void BLF_default_dpi(int dpi);
void BLF_default_size(float size);
void BLF_default_set(int fontid);
/**
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 9d9cc51ebcc..d4f5be617fd 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -63,8 +63,6 @@ int BLF_init(void)
global_font[i] = NULL;
}
- BLF_default_dpi(72);
-
return blf_font_init();
}
@@ -100,7 +98,7 @@ static int blf_search(const char *name)
{
for (int i = 0; i < BLF_MAX_FONT; i++) {
const FontBLF *font = global_font[i];
- if (font && (STREQ(font->name, name))) {
+ if (font && STREQ(font->name, name)) {
return i;
}
}
@@ -119,7 +117,7 @@ static int blf_search_available(void)
return -1;
}
-bool BLF_has_glyph(int fontid, unsigned int unicode)
+bool BLF_has_glyph(int fontid, uint unicode)
{
FontBLF *font = blf_get(fontid);
if (font) {
@@ -164,6 +162,14 @@ int BLF_load_unique(const char *name)
}
FontBLF *font = blf_font_new(name, filepath);
+
+ /* XXX: Temporarily disable kerning in our main font. Kerning had been accidentally removed from
+ * our font in 3.1. In 3.4 we disable kerning here in the new version to keep spacing the same
+ * (T101506). Enable again later with change of font, placement, or rendering - Harley. */
+ if (font && BLI_str_endswith(filepath, BLF_DEFAULT_PROPORTIONAL_FONT)) {
+ font->face_flags &= ~FT_FACE_FLAG_KERNING;
+ }
+
MEM_freeN(filepath);
if (!font) {
@@ -176,7 +182,7 @@ int BLF_load_unique(const char *name)
return i;
}
-void BLF_metrics_attach(int fontid, unsigned char *mem, int mem_size)
+void BLF_metrics_attach(int fontid, uchar *mem, int mem_size)
{
FontBLF *font = blf_get(fontid);
@@ -185,7 +191,7 @@ void BLF_metrics_attach(int fontid, unsigned char *mem, int mem_size)
}
}
-int BLF_load_mem(const char *name, const unsigned char *mem, int mem_size)
+int BLF_load_mem(const char *name, const uchar *mem, int mem_size)
{
int i = blf_search(name);
if (i >= 0) {
@@ -195,7 +201,7 @@ int BLF_load_mem(const char *name, const unsigned char *mem, int mem_size)
return BLF_load_mem_unique(name, mem, mem_size);
}
-int BLF_load_mem_unique(const char *name, const unsigned char *mem, int mem_size)
+int BLF_load_mem_unique(const char *name, const uchar *mem, int mem_size)
{
/*
* Don't search in the cache, make a new object font!
@@ -228,7 +234,7 @@ void BLF_unload(const char *name)
for (int i = 0; i < BLF_MAX_FONT; i++) {
FontBLF *font = global_font[i];
- if (font && (STREQ(font->name, name))) {
+ if (font && STREQ(font->name, name)) {
BLI_assert(font->reference_count > 0);
font->reference_count--;
@@ -361,12 +367,12 @@ void BLF_position(int fontid, float x, float y, float z)
}
}
-void BLF_size(int fontid, float size, int dpi)
+void BLF_size(int fontid, float size)
{
FontBLF *font = blf_get(fontid);
if (font) {
- blf_font_size(font, size, dpi);
+ blf_font_size(font, size);
}
}
@@ -381,7 +387,7 @@ void BLF_blur(int fontid, int size)
}
#endif
-void BLF_color4ubv(int fontid, const unsigned char rgba[4])
+void BLF_color4ubv(int fontid, const uchar rgba[4])
{
FontBLF *font = blf_get(fontid);
@@ -393,7 +399,7 @@ void BLF_color4ubv(int fontid, const unsigned char rgba[4])
}
}
-void BLF_color3ubv_alpha(int fontid, const unsigned char rgb[3], unsigned char alpha)
+void BLF_color3ubv_alpha(int fontid, const uchar rgb[3], uchar alpha)
{
FontBLF *font = blf_get(fontid);
@@ -405,13 +411,12 @@ void BLF_color3ubv_alpha(int fontid, const unsigned char rgb[3], unsigned char a
}
}
-void BLF_color3ubv(int fontid, const unsigned char rgb[3])
+void BLF_color3ubv(int fontid, const uchar rgb[3])
{
BLF_color3ubv_alpha(fontid, rgb, 255);
}
-void BLF_color4ub(
- int fontid, unsigned char r, unsigned char g, unsigned char b, unsigned char alpha)
+void BLF_color4ub(int fontid, uchar r, uchar g, uchar b, uchar alpha)
{
FontBLF *font = blf_get(fontid);
@@ -423,7 +428,7 @@ void BLF_color4ub(
}
}
-void BLF_color3ub(int fontid, unsigned char r, unsigned char g, unsigned char b)
+void BLF_color3ub(int fontid, uchar r, uchar g, uchar b)
{
FontBLF *font = blf_get(fontid);
@@ -566,32 +571,45 @@ int BLF_draw_mono(int fontid, const char *str, const size_t str_len, int cwidth)
return columns;
}
-void BLF_boundbox_foreach_glyph_ex(int fontid,
- const char *str,
- size_t str_len,
- BLF_GlyphBoundsFn user_fn,
- void *user_data,
- struct ResultBLF *r_info)
+void BLF_boundbox_foreach_glyph(
+ int fontid, const char *str, size_t str_len, BLF_GlyphBoundsFn user_fn, void *user_data)
{
FontBLF *font = blf_get(fontid);
- BLF_RESULT_CHECK_INIT(r_info);
-
if (font) {
if (font->flags & BLF_WORD_WRAP) {
/* TODO: word-wrap support. */
BLI_assert(0);
}
else {
- blf_font_boundbox_foreach_glyph(font, str, str_len, user_fn, user_data, r_info);
+ blf_font_boundbox_foreach_glyph(font, str, str_len, user_fn, user_data);
}
}
}
-void BLF_boundbox_foreach_glyph(
- int fontid, const char *str, const size_t str_len, BLF_GlyphBoundsFn user_fn, void *user_data)
+size_t BLF_str_offset_from_cursor_position(int fontid,
+ const char *str,
+ size_t str_len,
+ int location_x)
{
- BLF_boundbox_foreach_glyph_ex(fontid, str, str_len, user_fn, user_data, NULL);
+ FontBLF *font = blf_get(fontid);
+ if (font) {
+ return blf_str_offset_from_cursor_position(font, str, str_len, location_x);
+ }
+ return 0;
+}
+
+bool BLF_str_offset_to_glyph_bounds(int fontid,
+ const char *str,
+ size_t str_offset,
+ rcti *glyph_bounds)
+{
+ FontBLF *font = blf_get(fontid);
+ if (font) {
+ blf_str_offset_to_glyph_bounds(font, str, str_offset, glyph_bounds);
+ return true;
+ }
+ return false;
}
size_t BLF_width_to_strlen(
@@ -816,7 +834,7 @@ void BLF_shadow_offset(int fontid, int x, int y)
void BLF_buffer(int fontid,
float *fbuf,
- unsigned char *cbuf,
+ uchar *cbuf,
int w,
int h,
int nch,
@@ -912,7 +930,6 @@ void BLF_state_print(int fontid)
printf("fontid %d %p\n", fontid, (void *)font);
printf(" name: '%s'\n", font->name);
printf(" size: %f\n", font->size);
- printf(" dpi: %u\n", font->dpi);
printf(" pos: %d %d %d\n", UNPACK3(font->pos));
printf(" aspect: (%d) %.6f %.6f %.6f\n",
(font->flags & BLF_ROTATION) != 0,
diff --git a/source/blender/blenfont/intern/blf_default.c b/source/blender/blenfont/intern/blf_default.c
index a1f1b84636f..738683284e3 100644
--- a/source/blender/blenfont/intern/blf_default.c
+++ b/source/blender/blenfont/intern/blf_default.c
@@ -20,15 +20,9 @@
/* Default size and dpi, for BLF_draw_default. */
static int global_font_default = -1;
-static int global_font_dpi = 72;
/* Keep in sync with `UI_DEFAULT_TEXT_POINTS` */
static float global_font_size = 11.0f;
-void BLF_default_dpi(int dpi)
-{
- global_font_dpi = dpi;
-}
-
void BLF_default_size(float size)
{
global_font_size = size;
@@ -51,7 +45,7 @@ int BLF_set_default(void)
{
ASSERT_DEFAULT_SET;
- BLF_size(global_font_default, global_font_size, global_font_dpi);
+ BLF_size(global_font_default, global_font_size * U.dpi_fac);
return global_font_default;
}
@@ -59,7 +53,7 @@ int BLF_set_default(void)
void BLF_draw_default(float x, float y, float z, const char *str, const size_t str_len)
{
ASSERT_DEFAULT_SET;
- BLF_size(global_font_default, global_font_size, global_font_dpi);
+ BLF_size(global_font_default, global_font_size * U.dpi_fac);
BLF_position(global_font_default, x, y, z);
BLF_draw(global_font_default, str, str_len);
}
diff --git a/source/blender/blenfont/intern/blf_dir.c b/source/blender/blenfont/intern/blf_dir.c
index 8534a8c583f..395d981cb0b 100644
--- a/source/blender/blenfont/intern/blf_dir.c
+++ b/source/blender/blenfont/intern/blf_dir.c
@@ -115,7 +115,7 @@ char *blf_dir_search(const char *file)
char *s = NULL;
for (dir = global_font_dir.first; dir; dir = dir->next) {
- BLI_join_dirfile(full_path, sizeof(full_path), dir->path, file);
+ BLI_path_join(full_path, sizeof(full_path), dir->path, file);
if (BLI_exists(full_path)) {
s = BLI_strdup(full_path);
break;
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index b96c01e704d..2c877ecb41d 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -33,6 +33,7 @@
#include "BLI_path_util.h"
#include "BLI_rect.h"
#include "BLI_string.h"
+#include "BLI_string_cursor_utf8.h"
#include "BLI_string_utf8.h"
#include "BLI_threads.h"
@@ -377,7 +378,7 @@ BLI_INLINE ft_pix blf_kerning(FontBLF *font, const GlyphBLF *g_prev, const Glyph
FT_Vector delta = {KERNING_ENTRY_UNSET};
/* Get unscaled kerning value from our cache if ASCII. */
- if ((g_prev->c < KERNING_CACHE_TABLE_SIZE) && (g->c < GLYPH_ASCII_TABLE_SIZE)) {
+ if ((g_prev->c < KERNING_CACHE_TABLE_SIZE) && (g->c < KERNING_CACHE_TABLE_SIZE)) {
delta.x = font->kerning_cache->ascii_table[g->c][g_prev->c];
}
@@ -388,7 +389,7 @@ BLI_INLINE ft_pix blf_kerning(FontBLF *font, const GlyphBLF *g_prev, const Glyph
}
/* If ASCII we save this value to our cache for quicker access next time. */
- if ((g_prev->c < KERNING_CACHE_TABLE_SIZE) && (g->c < GLYPH_ASCII_TABLE_SIZE)) {
+ if ((g_prev->c < KERNING_CACHE_TABLE_SIZE) && (g->c < KERNING_CACHE_TABLE_SIZE)) {
font->kerning_cache->ascii_table[g->c][g_prev->c] = (int)delta.x;
}
@@ -497,6 +498,115 @@ int blf_font_draw_mono(FontBLF *font, const char *str, const size_t str_len, int
/** \name Text Drawing: Buffer
* \{ */
+/**
+ * Draw glyph `g` into `buf_info` pixels.
+ */
+static void blf_glyph_draw_buffer(FontBufInfoBLF *buf_info,
+ GlyphBLF *g,
+ const ft_pix pen_x,
+ const ft_pix pen_y_basis)
+{
+ const int chx = ft_pix_to_int(pen_x + ft_pix_from_int(g->pos[0]));
+ const int chy = ft_pix_to_int(pen_y_basis + ft_pix_from_int(g->dims[1]));
+
+ ft_pix pen_y = (g->pitch < 0) ? (pen_y_basis + ft_pix_from_int(g->dims[1] - g->pos[1])) :
+ (pen_y_basis - ft_pix_from_int(g->dims[1] - g->pos[1]));
+
+ if ((chx + g->dims[0]) < 0 || /* Out of bounds: left. */
+ chx >= buf_info->dims[0] || /* Out of bounds: right. */
+ (ft_pix_to_int(pen_y) + g->dims[1]) < 0 || /* Out of bounds: bottom. */
+ ft_pix_to_int(pen_y) >= buf_info->dims[1] /* Out of bounds: top. */
+ ) {
+ return;
+ }
+
+ /* Don't draw beyond the buffer bounds. */
+ int width_clip = g->dims[0];
+ int height_clip = g->dims[1];
+ int yb_start = g->pitch < 0 ? 0 : g->dims[1] - 1;
+
+ if (width_clip + chx > buf_info->dims[0]) {
+ width_clip -= chx + width_clip - buf_info->dims[0];
+ }
+ if (height_clip + ft_pix_to_int(pen_y) > buf_info->dims[1]) {
+ height_clip -= ft_pix_to_int(pen_y) + height_clip - buf_info->dims[1];
+ }
+
+ /* Clip drawing below the image. */
+ if (pen_y < 0) {
+ yb_start += (g->pitch < 0) ? -ft_pix_to_int(pen_y) : ft_pix_to_int(pen_y);
+ height_clip += ft_pix_to_int(pen_y);
+ pen_y = 0;
+ }
+
+ /* Avoid conversions in the pixel writing loop. */
+ const int pen_y_px = ft_pix_to_int(pen_y);
+
+ const float *b_col_float = buf_info->col_float;
+ const uchar *b_col_char = buf_info->col_char;
+
+ if (buf_info->fbuf) {
+ int yb = yb_start;
+ for (int y = ((chy >= 0) ? 0 : -chy); y < height_clip; y++) {
+ for (int x = ((chx >= 0) ? 0 : -chx); x < width_clip; x++) {
+ const char a_byte = *(g->bitmap + x + (yb * g->pitch));
+ if (a_byte) {
+ const float a = (a_byte / 255.0f) * b_col_float[3];
+ const size_t buf_ofs = (((size_t)(chx + x) +
+ ((size_t)(pen_y_px + y) * (size_t)buf_info->dims[0])) *
+ (size_t)buf_info->ch);
+ float *fbuf = buf_info->fbuf + buf_ofs;
+
+ float font_pixel[4];
+ font_pixel[0] = b_col_float[0] * a;
+ font_pixel[1] = b_col_float[1] * a;
+ font_pixel[2] = b_col_float[2] * a;
+ font_pixel[3] = a;
+ blend_color_mix_float(fbuf, fbuf, font_pixel);
+ }
+ }
+
+ if (g->pitch < 0) {
+ yb++;
+ }
+ else {
+ yb--;
+ }
+ }
+ }
+
+ if (buf_info->cbuf) {
+ int yb = yb_start;
+ for (int y = ((chy >= 0) ? 0 : -chy); y < height_clip; y++) {
+ for (int x = ((chx >= 0) ? 0 : -chx); x < width_clip; x++) {
+ const char a_byte = *(g->bitmap + x + (yb * g->pitch));
+
+ if (a_byte) {
+ const float a = (a_byte / 255.0f) * b_col_float[3];
+ const size_t buf_ofs = (((size_t)(chx + x) +
+ ((size_t)(pen_y_px + y) * (size_t)buf_info->dims[0])) *
+ (size_t)buf_info->ch);
+ uchar *cbuf = buf_info->cbuf + buf_ofs;
+
+ uchar font_pixel[4];
+ font_pixel[0] = b_col_char[0];
+ font_pixel[1] = b_col_char[1];
+ font_pixel[2] = b_col_char[2];
+ font_pixel[3] = unit_float_to_uchar_clamp(a);
+ blend_color_mix_byte(cbuf, cbuf, font_pixel);
+ }
+ }
+
+ if (g->pitch < 0) {
+ yb++;
+ }
+ else {
+ yb--;
+ }
+ }
+ }
+}
+
/* Sanity checks are done by BLF_draw_buffer() */
static void blf_font_draw_buffer_ex(FontBLF *font,
GlyphCacheBLF *gc,
@@ -512,10 +622,6 @@ static void blf_font_draw_buffer_ex(FontBLF *font,
/* buffer specific vars */
FontBufInfoBLF *buf_info = &font->buf_info;
- const float *b_col_float = buf_info->col_float;
- const uchar *b_col_char = buf_info->col_char;
- int chx, chy;
- int y, x;
/* another buffer specific call for color conversion */
@@ -527,101 +633,7 @@ static void blf_font_draw_buffer_ex(FontBLF *font,
}
pen_x += blf_kerning(font, g_prev, g);
- chx = ft_pix_to_int(pen_x + ft_pix_from_int(g->pos[0]));
- chy = ft_pix_to_int(pen_y_basis + ft_pix_from_int(g->dims[1]));
-
- if (g->pitch < 0) {
- pen_y = pen_y_basis + ft_pix_from_int(g->dims[1] - g->pos[1]);
- }
- else {
- pen_y = pen_y_basis - ft_pix_from_int(g->dims[1] - g->pos[1]);
- }
-
- if ((chx + g->dims[0]) >= 0 && chx < buf_info->dims[0] &&
- (ft_pix_to_int(pen_y) + g->dims[1]) >= 0 && ft_pix_to_int(pen_y) < buf_info->dims[1]) {
- /* don't draw beyond the buffer bounds */
- int width_clip = g->dims[0];
- int height_clip = g->dims[1];
- int yb_start = g->pitch < 0 ? 0 : g->dims[1] - 1;
-
- if (width_clip + chx > buf_info->dims[0]) {
- width_clip -= chx + width_clip - buf_info->dims[0];
- }
- if (height_clip + ft_pix_to_int(pen_y) > buf_info->dims[1]) {
- height_clip -= ft_pix_to_int(pen_y) + height_clip - buf_info->dims[1];
- }
-
- /* drawing below the image? */
- if (pen_y < 0) {
- yb_start += (g->pitch < 0) ? -ft_pix_to_int(pen_y) : ft_pix_to_int(pen_y);
- height_clip += ft_pix_to_int(pen_y);
- pen_y = 0;
- }
-
- /* Avoid conversions in the pixel writing loop. */
- const int pen_y_px = ft_pix_to_int(pen_y);
-
- if (buf_info->fbuf) {
- int yb = yb_start;
- for (y = ((chy >= 0) ? 0 : -chy); y < height_clip; y++) {
- for (x = ((chx >= 0) ? 0 : -chx); x < width_clip; x++) {
- const char a_byte = *(g->bitmap + x + (yb * g->pitch));
- if (a_byte) {
- const float a = (a_byte / 255.0f) * b_col_float[3];
- const size_t buf_ofs = (((size_t)(chx + x) +
- ((size_t)(pen_y_px + y) * (size_t)buf_info->dims[0])) *
- (size_t)buf_info->ch);
- float *fbuf = buf_info->fbuf + buf_ofs;
-
- float font_pixel[4];
- font_pixel[0] = b_col_float[0] * a;
- font_pixel[1] = b_col_float[1] * a;
- font_pixel[2] = b_col_float[2] * a;
- font_pixel[3] = a;
- blend_color_mix_float(fbuf, fbuf, font_pixel);
- }
- }
-
- if (g->pitch < 0) {
- yb++;
- }
- else {
- yb--;
- }
- }
- }
-
- if (buf_info->cbuf) {
- int yb = yb_start;
- for (y = ((chy >= 0) ? 0 : -chy); y < height_clip; y++) {
- for (x = ((chx >= 0) ? 0 : -chx); x < width_clip; x++) {
- const char a_byte = *(g->bitmap + x + (yb * g->pitch));
-
- if (a_byte) {
- const float a = (a_byte / 255.0f) * b_col_float[3];
- const size_t buf_ofs = (((size_t)(chx + x) +
- ((size_t)(pen_y_px + y) * (size_t)buf_info->dims[0])) *
- (size_t)buf_info->ch);
- uchar *cbuf = buf_info->cbuf + buf_ofs;
-
- uchar font_pixel[4];
- font_pixel[0] = b_col_char[0];
- font_pixel[1] = b_col_char[1];
- font_pixel[2] = b_col_char[2];
- font_pixel[3] = unit_float_to_uchar_clamp(a);
- blend_color_mix_byte(cbuf, cbuf, font_pixel);
- }
- }
-
- if (g->pitch < 0) {
- yb++;
- }
- else {
- yb--;
- }
- }
- }
- }
+ blf_glyph_draw_buffer(buf_info, g, pen_x, pen_y_basis);
pen_x = ft_pix_round_advance(pen_x, g->advance_x);
g_prev = g;
@@ -901,25 +913,23 @@ float blf_font_fixed_width(FontBLF *font)
return width;
}
-static void blf_font_boundbox_foreach_glyph_ex(FontBLF *font,
- GlyphCacheBLF *gc,
- const char *str,
- const size_t str_len,
- BLF_GlyphBoundsFn user_fn,
- void *user_data,
- struct ResultBLF *r_info,
- ft_pix pen_y)
+void blf_font_boundbox_foreach_glyph(FontBLF *font,
+ const char *str,
+ const size_t str_len,
+ BLF_GlyphBoundsFn user_fn,
+ void *user_data)
{
GlyphBLF *g, *g_prev = NULL;
ft_pix pen_x = 0;
size_t i = 0, i_curr;
- rcti gbox_px;
if (str_len == 0 || str[0] == 0) {
/* early output. */
return;
}
+ GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
+
while ((i < str_len) && str[i]) {
i_curr = i;
g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i);
@@ -928,44 +938,95 @@ static void blf_font_boundbox_foreach_glyph_ex(FontBLF *font,
continue;
}
pen_x += blf_kerning(font, g_prev, g);
- const ft_pix pen_x_next = ft_pix_round_advance(pen_x, g->advance_x);
-
- gbox_px.xmin = ft_pix_to_int_floor(pen_x);
- gbox_px.xmax = ft_pix_to_int_ceil(pen_x_next);
- gbox_px.ymin = ft_pix_to_int_floor(pen_y);
- gbox_px.ymax = gbox_px.ymin - g->dims[1];
- const int advance_x_px = gbox_px.xmax - gbox_px.xmin;
-
- pen_x = pen_x_next;
- rcti box_px;
- box_px.xmin = ft_pix_to_int_floor(g->box_xmin);
- box_px.xmax = ft_pix_to_int_ceil(g->box_xmax);
- box_px.ymin = ft_pix_to_int_floor(g->box_ymin);
- box_px.ymax = ft_pix_to_int_ceil(g->box_ymax);
+ rcti bounds;
+ bounds.xmin = ft_pix_to_int_floor(pen_x) + ft_pix_to_int_floor(g->box_xmin);
+ bounds.xmax = ft_pix_to_int_floor(pen_x) + ft_pix_to_int_ceil(g->box_xmax);
+ bounds.ymin = ft_pix_to_int_floor(g->box_ymin);
+ bounds.ymax = ft_pix_to_int_ceil(g->box_ymax);
- if (user_fn(str, i_curr, &gbox_px, advance_x_px, &box_px, g->pos, user_data) == false) {
+ if (user_fn(str, i_curr, &bounds, user_data) == false) {
break;
}
-
+ pen_x = ft_pix_round_advance(pen_x, g->advance_x);
g_prev = g;
}
- if (r_info) {
- r_info->lines = 1;
- r_info->width = ft_pix_to_int(pen_x);
+ blf_glyph_cache_release(font);
+}
+
+typedef struct CursorPositionForeachGlyph_Data {
+ /** Horizontal position to test. */
+ int location_x;
+ /** Write the character offset here. */
+ size_t r_offset;
+} CursorPositionForeachGlyph_Data;
+
+static bool blf_cursor_position_foreach_glyph(const char *UNUSED(str),
+ const size_t str_step_ofs,
+ const rcti *bounds,
+ void *user_data)
+{
+ CursorPositionForeachGlyph_Data *data = user_data;
+ if (data->location_x < (bounds->xmin + bounds->xmax) / 2) {
+ data->r_offset = str_step_ofs;
+ return false;
}
+ return true;
}
-void blf_font_boundbox_foreach_glyph(FontBLF *font,
- const char *str,
- const size_t str_len,
- BLF_GlyphBoundsFn user_fn,
- void *user_data,
- struct ResultBLF *r_info)
+
+size_t blf_str_offset_from_cursor_position(struct FontBLF *font,
+ const char *str,
+ size_t str_len,
+ int location_x)
{
- GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
- blf_font_boundbox_foreach_glyph_ex(font, gc, str, str_len, user_fn, user_data, r_info, 0);
- blf_glyph_cache_release(font);
+ CursorPositionForeachGlyph_Data data = {
+ .location_x = location_x,
+ .r_offset = (size_t)-1,
+ };
+ blf_font_boundbox_foreach_glyph(font, str, str_len, blf_cursor_position_foreach_glyph, &data);
+
+ if (data.r_offset == (size_t)-1) {
+ /* We are to the right of the string, so return position of null terminator. */
+ data.r_offset = BLI_strnlen(str, str_len);
+ }
+ else if (BLI_str_utf8_char_width(&str[data.r_offset]) < 1) {
+ /* This is a combining character (or invalid), so move to previous visible valid char. */
+ BLI_str_cursor_step_prev_utf8(str, str_len, (int *)&data.r_offset);
+ }
+
+ return data.r_offset;
+}
+
+typedef struct StrOffsetToGlyphBounds_Data {
+ size_t str_offset;
+ rcti bounds;
+} StrOffsetToGlyphBounds_Data;
+
+static bool blf_str_offset_foreach_glyph(const char *UNUSED(str),
+ const size_t str_step_ofs,
+ const rcti *bounds,
+ void *user_data)
+{
+ StrOffsetToGlyphBounds_Data *data = user_data;
+ if (data->str_offset == str_step_ofs) {
+ data->bounds = *bounds;
+ return false;
+ }
+ return true;
+}
+
+void blf_str_offset_to_glyph_bounds(struct FontBLF *font,
+ const char *str,
+ size_t str_offset,
+ rcti *glyph_bounds)
+{
+ StrOffsetToGlyphBounds_Data data = {
+ .str_offset = str_offset,
+ .bounds = {0},
+ };
+ blf_font_boundbox_foreach_glyph(font, str, str_offset + 1, blf_str_offset_foreach_glyph, &data);
+ *glyph_bounds = data.bounds;
}
/** \} */
@@ -1146,38 +1207,6 @@ void blf_font_draw_buffer__wrap(FontBLF *font,
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Text Evaluation: Count Missing Characters
- * \{ */
-
-int blf_font_count_missing_chars(FontBLF *font,
- const char *str,
- const size_t str_len,
- int *r_tot_chars)
-{
- int missing = 0;
- size_t i = 0;
-
- *r_tot_chars = 0;
- while (i < str_len) {
- uint c;
-
- if ((c = str[i]) < GLYPH_ASCII_TABLE_SIZE) {
- i++;
- }
- else {
- c = BLI_str_utf8_as_unicode_step(str, str_len, &i);
- if (blf_get_char_index(font, c) == 0) {
- missing++;
- }
- }
- (*r_tot_chars)++;
- }
- return missing;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Font Query: Attributes
* \{ */
@@ -1300,7 +1329,6 @@ static void blf_font_fill(FontBLF *font)
font->clip_rec.ymin = 0;
font->clip_rec.ymax = 0;
font->flags = 0;
- font->dpi = 0;
font->size = 0;
BLI_listbase_clear(&font->cache);
font->kerning_cache = NULL;
@@ -1346,7 +1374,9 @@ bool blf_ensure_face(FontBLF *font)
if (font->mem) {
err = FT_New_Memory_Face(font->ft_lib, font->mem, (FT_Long)font->mem_size, 0, &font->face);
}
- font->face->generic.data = font;
+ if (!err) {
+ font->face->generic.data = font;
+ }
BLI_mutex_unlock(&ft_lib_mutex);
}
@@ -1611,8 +1641,8 @@ void blf_ensure_size(FontBLF *font)
scaler.width = 0;
scaler.height = round_fl_to_uint(font->size * 64.0f);
scaler.pixel = 0;
- scaler.x_res = font->dpi;
- scaler.y_res = font->dpi;
+ scaler.x_res = BLF_DPI;
+ scaler.y_res = BLF_DPI;
if (FTC_Manager_LookupSize(ftc_manager, &scaler, &font->ft_size) == FT_Err_Ok) {
font->ft_size->generic.data = (void *)font;
font->ft_size->generic.finalizer = blf_size_finalizer;
@@ -1622,7 +1652,7 @@ void blf_ensure_size(FontBLF *font)
BLI_assert_unreachable();
}
-bool blf_font_size(FontBLF *font, float size, uint dpi)
+bool blf_font_size(FontBLF *font, float size)
{
if (!blf_ensure_face(font)) {
return false;
@@ -1633,15 +1663,15 @@ bool blf_font_size(FontBLF *font, float size, uint dpi)
/* Adjust our new size to be on even 64ths. */
size = (float)ft_size / 64.0f;
- if (font->size != size || font->dpi != dpi) {
+ if (font->size != size) {
if (font->flags & BLF_CACHED) {
FTC_ScalerRec scaler = {0};
scaler.face_id = font;
scaler.width = 0;
scaler.height = ft_size;
scaler.pixel = 0;
- scaler.x_res = dpi;
- scaler.y_res = dpi;
+ scaler.x_res = BLF_DPI;
+ scaler.y_res = BLF_DPI;
if (FTC_Manager_LookupSize(ftc_manager, &scaler, &font->ft_size) != FT_Err_Ok) {
return false;
}
@@ -1649,7 +1679,7 @@ bool blf_font_size(FontBLF *font, float size, uint dpi)
font->ft_size->generic.finalizer = blf_size_finalizer;
}
else {
- if (FT_Set_Char_Size(font->face, 0, ft_size, dpi, dpi) != FT_Err_Ok) {
+ if (FT_Set_Char_Size(font->face, 0, ft_size, BLF_DPI, BLF_DPI) != FT_Err_Ok) {
return false;
}
font->ft_size = font->face->size;
@@ -1657,7 +1687,6 @@ bool blf_font_size(FontBLF *font, float size, uint dpi)
}
font->size = size;
- font->dpi = dpi;
return true;
}
diff --git a/source/blender/blenfont/intern/blf_font_default.c b/source/blender/blenfont/intern/blf_font_default.c
index d35692f6eae..63b1cf34db5 100644
--- a/source/blender/blenfont/intern/blf_font_default.c
+++ b/source/blender/blenfont/intern/blf_font_default.c
@@ -32,7 +32,7 @@ static int blf_load_font_default(const char *filename, const bool unique)
}
char filepath[FILE_MAX];
- BLI_join_dirfile(filepath, sizeof(filepath), dir, filename);
+ BLI_path_join(filepath, sizeof(filepath), dir, filename);
return (unique) ? BLF_load_unique(filepath) : BLF_load(filepath);
}
diff --git a/source/blender/blenfont/intern/blf_font_win32_compat.c b/source/blender/blenfont/intern/blf_font_win32_compat.c
index 17213275c74..4bb2a010dd9 100644
--- a/source/blender/blenfont/intern/blf_font_win32_compat.c
+++ b/source/blender/blenfont/intern/blf_font_win32_compat.c
@@ -39,10 +39,7 @@ static void ft_ansi_stream_close(FT_Stream stream)
MEM_freeN(stream);
}
-static unsigned long ft_ansi_stream_io(FT_Stream stream,
- unsigned long offset,
- unsigned char *buffer,
- unsigned long count)
+static ulong ft_ansi_stream_io(FT_Stream stream, ulong offset, uchar *buffer, ulong count)
{
FILE *file;
if (!count && offset > stream->size) {
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index c08d52307b7..b60ca3da1ea 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -54,7 +54,7 @@
*/
static FT_Fixed to_16dot16(double val)
{
- return (FT_Fixed)(lround(val * 65536.0));
+ return (FT_Fixed)lround(val * 65536.0);
}
/** \} */
@@ -63,11 +63,11 @@ static FT_Fixed to_16dot16(double val)
/** \name Glyph Cache
* \{ */
-static GlyphCacheBLF *blf_glyph_cache_find(const FontBLF *font, const float size, uint dpi)
+static GlyphCacheBLF *blf_glyph_cache_find(const FontBLF *font, const float size)
{
GlyphCacheBLF *gc = (GlyphCacheBLF *)font->cache.first;
while (gc) {
- if (gc->size == size && gc->dpi == dpi && (gc->bold == ((font->flags & BLF_BOLD) != 0)) &&
+ if (gc->size == size && (gc->bold == ((font->flags & BLF_BOLD) != 0)) &&
(gc->italic == ((font->flags & BLF_ITALIC) != 0)) &&
(gc->char_weight == font->char_weight) && (gc->char_slant == font->char_slant) &&
(gc->char_width == font->char_width) && (gc->char_spacing == font->char_spacing)) {
@@ -85,7 +85,6 @@ static GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
gc->next = NULL;
gc->prev = NULL;
gc->size = font->size;
- gc->dpi = font->dpi;
gc->bold = ((font->flags & BLF_BOLD) != 0);
gc->italic = ((font->flags & BLF_ITALIC) != 0);
gc->char_weight = font->char_weight;
@@ -122,7 +121,7 @@ GlyphCacheBLF *blf_glyph_cache_acquire(FontBLF *font)
{
BLI_mutex_lock(&font->glyph_cache_mutex);
- GlyphCacheBLF *gc = blf_glyph_cache_find(font, font->size, font->dpi);
+ GlyphCacheBLF *gc = blf_glyph_cache_find(font, font->size);
if (!gc) {
gc = blf_glyph_cache_new(font);
@@ -967,7 +966,7 @@ static FT_GlyphSlot blf_glyph_render(FontBLF *settings_font,
int fixed_width)
{
if (glyph_font != settings_font) {
- blf_font_size(glyph_font, settings_font->size, settings_font->dpi);
+ blf_font_size(glyph_font, settings_font->size);
}
blf_ensure_size(glyph_font);
diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h
index 39d3af22562..2f3f7b52233 100644
--- a/source/blender/blenfont/intern/blf_internal.h
+++ b/source/blender/blenfont/intern/blf_internal.h
@@ -25,6 +25,13 @@ struct rcti;
/* Maximum number of bytes to use for cached data nodes. 0 is default of 200,000. */
#define BLF_CACHE_BYTES 400000
+/* We assume square pixels at a fixed DPI of 72, scaling only the size. Therefore
+ * font size = points = pixels, i.e. a size of 20 will result in a 20-pixel EM square.
+ * Although we could use the actual monitor DPI instead, we would then have to scale
+ * the size to cancel that out. Other libraries like Skia use this same fixed value.
+ */
+#define BLF_DPI 72
+
extern struct FontBLF *global_font[BLF_MAX_FONT];
void blf_batch_draw_begin(struct FontBLF *font);
@@ -70,7 +77,7 @@ void blf_font_attach_from_mem(struct FontBLF *font, const unsigned char *mem, si
/**
* Change font's output size. Returns true if successful in changing the size.
*/
-bool blf_font_size(struct FontBLF *font, float size, unsigned int dpi);
+bool blf_font_size(struct FontBLF *font, float size);
void blf_font_draw(struct FontBLF *font,
const char *str,
@@ -134,18 +141,19 @@ void blf_font_boundbox_foreach_glyph(struct FontBLF *font,
size_t str_len,
bool (*user_fn)(const char *str,
size_t str_step_ofs,
- const struct rcti *glyph_step_bounds,
- int glyph_advance_x,
- const struct rcti *glyph_bounds,
- const int glyph_bearing[2],
+ const struct rcti *bounds,
void *user_data),
- void *user_data,
- struct ResultBLF *r_info);
+ void *user_data);
+
+size_t blf_str_offset_from_cursor_position(struct FontBLF *font,
+ const char *str,
+ size_t str_len,
+ int location_x);
-int blf_font_count_missing_chars(struct FontBLF *font,
- const char *str,
- size_t str_len,
- int *r_tot_chars);
+void blf_str_offset_to_glyph_bounds(struct FontBLF *font,
+ const char *str,
+ size_t str_offset,
+ struct rcti *glyph_bounds);
void blf_font_free(struct FontBLF *font);
diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index d64bd9c5452..cc4be9f7f0e 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -142,9 +142,6 @@ typedef struct GlyphCacheBLF {
/** Font size. */
float size;
- /** DPI. */
- unsigned int dpi;
-
float char_weight;
float char_slant;
float char_width;
@@ -300,9 +297,6 @@ typedef struct FontBLF {
/** The width to wrap the text, see #BLF_WORD_WRAP. */
int wrap_width;
- /** Font DPI (default 72). */
- unsigned int dpi;
-
/** Font size. */
float size;
diff --git a/source/blender/blenfont/intern/blf_thumbs.c b/source/blender/blenfont/intern/blf_thumbs.c
index bafa927a440..8a640ac86a7 100644
--- a/source/blender/blenfont/intern/blf_thumbs.c
+++ b/source/blender/blenfont/intern/blf_thumbs.c
@@ -8,16 +8,20 @@
* Isolate since this needs to be called by #ImBuf code (bad level call).
*/
-#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#include <ft2build.h>
#include FT_FREETYPE_H
+#include FT_ADVANCES_H /* For FT_Get_Advance */
+#include FT_TRUETYPE_IDS_H /* Code-point coverage constants. */
+#include FT_TRUETYPE_TABLES_H /* For TT_OS2 */
#include "BLI_listbase.h"
+#include "BLI_math_bits.h"
#include "BLI_rect.h"
+#include "BLI_string.h"
+#include "BLI_string_utf8.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
@@ -25,90 +29,379 @@
#include "blf_internal_types.h"
#include "BLF_api.h"
-#include "BLT_translation.h"
#include "BLI_strict_flags.h"
-void BLF_thumb_preview(const char *filepath,
- const char **draw_str,
- const char **i18n_draw_str,
- const uchar draw_str_lines,
- const float font_color[4],
- const int font_size,
- uchar *buf,
- const int w,
- const int h,
- const int channels)
+/* Maximum length of text sample in char32_t, including NULL terminator. */
+#define BLF_SAMPLE_LEN 5
+
+typedef struct UnicodeSample {
+ char32_t sample[BLF_SAMPLE_LEN];
+ int field; /* ‘OS/2’ table ulUnicodeRangeX field (1-4). */
+ FT_ULong mask; /* ‘OS/2’ table ulUnicodeRangeX bit mask. */
+} UnicodeSample;
+
+/* The seemingly arbitrary order that follows is to help quickly find the most-likely designed
+ * intent of the font. Many feature-specific fonts contain Latin, Greek, & Coptic characters so
+ * those need to be checked last. */
+static const UnicodeSample unicode_samples[] = {
+ /* Chinese, Japanese, Korean, ordered specific to general. */
+ {U"\ud55c\uad6d\uc5b4", 2, TT_UCR_HANGUL}, /* 한국어 */
+ {U"\u3042\u30a2\u4e9c", 2, TT_UCR_HIRAGANA}, /* あア亜 */
+ {U"\u30a2\u30a4\u4e9c", 2, TT_UCR_KATAKANA}, /* アイ亜 */
+ {U"\u1956\u195b\u1966", 3, TT_UCR_TAI_LE}, /* ᥖᥛᥦ */
+ {U"\u3105\u3106\u3107", 2, TT_UCR_BOPOMOFO}, /* ㄅㄆㄇ */
+ {U"\ua840\ua841\ua85d", 2, TT_UCR_PHAGSPA}, /* ꡀꡁꡝ */
+ {U"\u5e03\u4e01\u4f53", 2, TT_UCR_CJK_UNIFIED_IDEOGRAPHS}, /* 布丁体 */
+ /* Languages in the BMP with a coverage bit. */
+ {U"\u05d0\u05da\u05e4", 1, TT_UCR_HEBREW},
+ {U"\ua500\ua502\ua549", 1, TT_UCR_VAI},
+ {U"\ufee6\ufef4\ufeb3", 1, TT_UCR_ARABIC},
+ {U"\u07C1\u07C2\u07C3", 1, TT_UCR_NKO},
+ {U"\u0905\u093f\u092a", 1, TT_UCR_DEVANAGARI},
+ {U"\u0986\u0987\u098c", 1, TT_UCR_BENGALI},
+ {U"\u0a05\u0a16\u0a30", 1, TT_UCR_GURMUKHI},
+ {U"\u0aaa\u0aaf\u0ab8", 1, TT_UCR_GUJARATI},
+ {U"\u0b2a\u0b30\u0b37", 1, TT_UCR_ORIYA},
+ {U"\u0b85\u0b88\u0b8f", 1, TT_UCR_TAMIL},
+ {U"\u0c05\u0c0c\u0c36", 1, TT_UCR_TELUGU},
+ {U"\u0c85\u0c87\u0c8e", 1, TT_UCR_KANNADA},
+ {U"\u0d05\u0d09\u0d3d", 1, TT_UCR_MALAYALAM},
+ {U"\u0e05\u0e06\u0e07", 1, TT_UCR_THAI},
+ {U"\u0e81\u0e82\u0e84", 1, TT_UCR_LAO},
+ {U"\u10a0\u10a1\u10a2", 1, TT_UCR_GEORGIAN},
+ {U"\u1B05\u1B07\u1B09", 1, TT_UCR_BALINESE},
+ {U"\u0f00\u0f04\u0f08", 3, TT_UCR_TIBETAN},
+ {U"\u0710\u0717\u071c", 3, TT_UCR_SYRIAC},
+ {U"\u0784\u0783\u0798", 3, TT_UCR_THAANA},
+ {U"\u0d85\u0d89\u0daf", 3, TT_UCR_SINHALA},
+ {U"\u1000\u1001\u1014", 3, TT_UCR_MYANMAR},
+ {U"\u1202\u1207\u1250", 3, TT_UCR_ETHIOPIC},
+ {U"\u13a3\u13a4\u13a8", 3, TT_UCR_CHEROKEE},
+ {U"\u1401\u144d\u156e", 3, TT_UCR_CANADIAN_ABORIGINAL_SYLLABICS},
+ {U"\u1681\u1687\u168b", 3, TT_UCR_OGHAM},
+ {U"\u16A0\u16A4\u16AA", 3, TT_UCR_RUNIC},
+ {U"\u1780\u1781\u1783", 3, TT_UCR_KHMER},
+ {U"\u1820\u1826\u1845", 3, TT_UCR_MONGOLIAN},
+ {U"\ua188\ua320\ua4bf", 3, TT_UCR_YI},
+ {U"\u1900\u1901\u1902", 3, TT_UCR_LIMBU},
+ {U"\u1950\u1951\u1952", 3, TT_UCR_TAI_LE},
+ {U"\u1980\u1982\u1986", 3, (FT_ULong)TT_UCR_NEW_TAI_LUE},
+ {U"\u1A00\u1A01\u1A02", 4, TT_UCR_BUGINESE},
+ {U"\u2c01\u2c05\u2c0c", 4, TT_UCR_GLAGOLITIC},
+ {U"\u2d31\u2d33\u2d37", 4, TT_UCR_TIFINAGH},
+ {U"\u2d31\u2d33\u2d37", 4, TT_UCR_YIJING},
+ {U"\u1B83\u1B84\u1B88", 4, TT_UCR_SUNDANESE},
+ {U"\u1C00\u1C01\u1C02", 4, TT_UCR_LEPCHA},
+ {U"\u1C50\u1C51\u1C52", 4, TT_UCR_OL_CHIKI},
+ {U"\uA800\uA801\uA805", 4, TT_UCR_SYLOTI_NAGRI},
+ {U"\uA882\uA88a\uA892", 4, TT_UCR_SAURASHTRA},
+ {U"\uA901\uA902\uA904", 4, TT_UCR_KAYAH_LI},
+ {U"\uA930\uA932\uA943", 4, TT_UCR_REJANG},
+ {U"\uaa00\uaa02\uaa05", 4, TT_UCR_CHAM},
+ /* Indexed languages in the Supplementary Multilingual Plane. */
+ {U"\U00010000\U00010001\U00010002", 4, TT_UCR_LINEAR_B},
+ {U"\U00010300\U00010301\U00010302", 3, TT_UCR_OLD_ITALIC},
+ {U"\U00010330\U00010331\U00010332", 3, TT_UCR_GOTHIC},
+ {U"\U00010380\U00010381\U00010382", 4, TT_UCR_UGARITIC},
+ {U"\U000103A0\U000103A1\U000103A2", 4, TT_UCR_OLD_PERSIAN},
+ {U"\U00010400\U00010401\U00010402", 3, TT_UCR_DESERET},
+ {U"\U00010450\U00010451\U00010452", 4, TT_UCR_SHAVIAN},
+ {U"\U00010480\U00010481\U00010482", 4, TT_UCR_OSMANYA},
+ {U"\U00010800\U00010803\U00010805", 4, TT_UCR_CYPRIOT_SYLLABARY},
+ {U"\U00010900\U00010901\U00010902", 2, TT_UCR_PHOENICIAN},
+ {U"\U00010A10\U00010A11\U00010A12", 4, TT_UCR_KHAROSHTHI},
+ {U"\U00012000\U00012001\U00012002", 4, TT_UCR_CUNEIFORM},
+ /* Philippine languages use a single OS2 coverage bit. */
+ {U"\u1700\u1701\u1702", 3, TT_UCR_PHILIPPINE}, /* Tagalog */
+ {U"\u1720\u1721\u1722", 3, TT_UCR_PHILIPPINE}, /* Hanunoo */
+ {U"\u1740\u1741\u1742", 3, TT_UCR_PHILIPPINE}, /* Buhid */
+ {U"\u1760\u1761\u1762", 3, TT_UCR_PHILIPPINE}, /* Tagbanwa */
+ /* Anatolian languages use a single OS2 coverage bit. */
+ {U"\U000102A3\U000102A8\U000102CB", 4, TT_UCR_OLD_ANATOLIAN}, /* Carian */
+ {U"\U00010280\U00010281\U00010282", 4, TT_UCR_OLD_ANATOLIAN}, /* Lycian */
+ {U"\U00010920\U00010921\U00010922", 4, TT_UCR_OLD_ANATOLIAN}, /* Lydian */
+ /* Symbol blocks. */
+ {U"\U0001f600\U0001f638", 0, 0}, /* Emoticons 😀😸 */
+ {U"\uf021\uf022\uf023", 0, 0}, /* MS Symbols */
+ {U"\u280f\u2815\u283f", 3, TT_UCR_BRAILLE},
+ {U"\U0001D11e\U0001D161\U0001D130", 3, TT_UCR_MUSICAL_SYMBOLS},
+ {U"\u2700\u2708\u2709", 2, TT_UCR_DINGBATS},
+ {U"\u2600\u2601\u2602", 2, TT_UCR_MISCELLANEOUS_SYMBOLS},
+ {U"\ue000\ue001\ue002", 2, TT_UCR_PRIVATE_USE},
+ {U"\ue702\ue703\ue704", 2, TT_UCR_PRIVATE_USE},
+ {U"\U000F0001\U000F0002\U000F0003", 2, TT_UCR_PRIVATE_USE_SUPPLEMENTARY},
+ /* Languages in the Supplementary Multilingual Plane. */
+ {U"\U00010350\U00010352\U00010353", 2, TT_UCR_NON_PLANE_0}, /* Old Permic */
+ {U"\U000104B0\U000104B6\U000104B8", 2, TT_UCR_NON_PLANE_0}, /* Osage */
+ {U"\U00010500\U00010501\U00010502", 2, TT_UCR_NON_PLANE_0}, /* Elbasan */
+ {U"\U00010530\U00010531\U00010532", 2, TT_UCR_NON_PLANE_0}, /* Caucasian Albanian */
+ {U"\U00010600\U00010601\U00010602", 2, TT_UCR_NON_PLANE_0}, /* Linear A */
+ {U"\U00010840\U00010841\U00010842", 2, TT_UCR_NON_PLANE_0}, /* Imperial Aramaic */
+ {U"\U00010860\U00010861\U00010862", 2, TT_UCR_NON_PLANE_0}, /* Palmyrene */
+ {U"\U00010880\U00010881\U00010882", 2, TT_UCR_NON_PLANE_0}, /* Nabataean */
+ {U"\U000108E0\U000108E3\U000108E4", 2, TT_UCR_NON_PLANE_0}, /* Hatran */
+ {U"\U00010980\U00010983\U00010989", 2, TT_UCR_NON_PLANE_0}, /* Meroitic Hieroglyphs */
+ {U"\U000109A0\U000109A1\U000109A2", 2, TT_UCR_NON_PLANE_0}, /* Meroitic Cursive */
+ {U"\U00010A60\U00010A61\U00010A62", 2, TT_UCR_NON_PLANE_0}, /* Old South Arabian */
+ {U"\U00010A80\U00010A81\U00010A82", 2, TT_UCR_NON_PLANE_0}, /* Old North Arabian */
+ {U"\U00010ac0\U00010ac3\U00010ac6", 2, TT_UCR_NON_PLANE_0}, /* Manichaean */
+ {U"\U00010B00\U00010B04\U00010B08", 2, TT_UCR_NON_PLANE_0}, /* Avestan */
+ {U"\U00010B40\U00010B41\U00010B42", 2, TT_UCR_NON_PLANE_0}, /* Inscriptional Parthian */
+ {U"\U00010B60\U00010B61\U00010B62", 2, TT_UCR_NON_PLANE_0}, /* Inscriptional Pahlavi */
+ {U"\U00010B80\U00010B84\U00010B87", 2, TT_UCR_NON_PLANE_0}, /* Psalter Pahlavi */
+ {U"\U00010C00\U00010C01\U00010C02", 2, TT_UCR_NON_PLANE_0}, /* Old Turkic */
+ {U"\U00010C80\U00010C81\U00010C82", 2, TT_UCR_NON_PLANE_0}, /* Old Hungarian */
+ {U"\U00010D00\U00010D07\U00010D0D", 2, TT_UCR_NON_PLANE_0}, /* Hanifi Rohingya */
+ {U"\U00010E80\U00010E81\U00010E82", 2, TT_UCR_NON_PLANE_0}, /* Yezidi */
+ {U"\U00010F00\U00010F01\U00010F02", 2, TT_UCR_NON_PLANE_0}, /* Old Sogdian */
+ {U"\U00010F30\U00010F32\U00010F34", 2, TT_UCR_NON_PLANE_0}, /* Sogdian */
+ {U"\U00010F70\U00010F71\U00010F72", 2, TT_UCR_NON_PLANE_0}, /* Old Uyghur */
+ {U"\U00010FB0\U00010FB1\U00010FB2", 2, TT_UCR_NON_PLANE_0}, /* Chorasmian */
+ {U"\U00010FE0\U00010FE1\U00010FE2", 2, TT_UCR_NON_PLANE_0}, /* Elymaic */
+ {U"\U00011003\U00011004\U00011005", 2, TT_UCR_NON_PLANE_0}, /* Brahmi */
+ {U"\U00011083\U00011085\U00011087", 2, TT_UCR_NON_PLANE_0}, /* Kaithi */
+ {U"\U000110D0\U000110D1\U000110D2", 2, TT_UCR_NON_PLANE_0}, /* Sora Sompeng */
+ {U"\U00011103\U00011104\U00011105", 2, TT_UCR_NON_PLANE_0}, /* Chakma */
+ {U"\U00011150\U00011151\U00011152", 2, TT_UCR_NON_PLANE_0}, /* Mahajani */
+ {U"\U00011183\U00011185\U0001118b", 2, TT_UCR_NON_PLANE_0}, /* Sharada */
+ {U"\U00011200\U00011201\U00011202", 2, TT_UCR_NON_PLANE_0}, /* Khojki */
+ {U"\U00011280\U00011281\U00011282", 2, TT_UCR_NON_PLANE_0}, /* Multani */
+ {U"\U000112B0\U000112B2\U000112B4", 2, TT_UCR_NON_PLANE_0}, /* Khudawadi */
+ {U"\U00011305\U00011309\U0001130b", 2, TT_UCR_NON_PLANE_0}, /* Grantha */
+ {U"\U00011400\U00011404\U00011409", 2, TT_UCR_NON_PLANE_0}, /* Newa */
+ {U"\U00011480\U00011481\U00011482", 2, TT_UCR_NON_PLANE_0}, /* Tirhuta */
+ {U"\U00011580\U00011582\U00011589", 2, TT_UCR_NON_PLANE_0}, /* Siddham */
+ {U"\U00011600\U00011604\U00011609", 2, TT_UCR_NON_PLANE_0}, /* Modi */
+ {U"\U00011680\U00011682\U0001168A", 2, TT_UCR_NON_PLANE_0}, /* Takri */
+ {U"\U00011700\U00011701\U00011702", 2, TT_UCR_NON_PLANE_0}, /* Ahom */
+ {U"\U00011800\U00011801\U00011802", 2, TT_UCR_NON_PLANE_0}, /* Dogri */
+ {U"\U000118A0\U000118A1\U000118AA", 2, TT_UCR_NON_PLANE_0}, /* Warang Citi */
+ {U"\U00011900\U00011901\U00011902", 2, TT_UCR_NON_PLANE_0}, /* Dives Akuru */
+ {U"\U00011A00\U00011A10\U00011A15", 2, TT_UCR_NON_PLANE_0}, /* Zanabazar Square */
+ {U"\U00011A50\U00011A5C\U00011A6B", 2, TT_UCR_NON_PLANE_0}, /* Soyombo */
+ {U"\U00011AC0\U00011AC1\U00011AC2", 2, TT_UCR_NON_PLANE_0}, /* Pau Cin Hau */
+ {U"\U00011C00\U00011C01\U00011C02", 2, TT_UCR_NON_PLANE_0}, /* Bhaiksuki */
+ {U"\U00011C70\U00011C71\U00011C72", 2, TT_UCR_NON_PLANE_0}, /* Marchen */
+ {U"\U00011D00\U00011D02\U00011D08", 2, TT_UCR_NON_PLANE_0}, /* Masaram Gondi */
+ {U"\U00011D60\U00011D62\U00011D6c", 2, TT_UCR_NON_PLANE_0}, /* Gunjala Gondi */
+ {U"\U00011FC1\U00011FC2\U00011FC8", 2, TT_UCR_NON_PLANE_0}, /* Tamil Supplement */
+ {U"\U00012F90\U00012F91\U00012F92", 2, TT_UCR_NON_PLANE_0}, /* Cypro-Minoan */
+ {U"\U00013000\U00013076\U0001307f", 2, TT_UCR_NON_PLANE_0}, /* Egyptian Hieroglyphs */
+ {U"\U00014400\U00014409\U00014447", 2, TT_UCR_NON_PLANE_0}, /* Anatolian Hieroglyphs */
+ {U"\U00016A40\U00016A41\U00016A42", 2, TT_UCR_NON_PLANE_0}, /* Mro */
+ {U"\U00016A70\U00016A71\U00016A72", 2, TT_UCR_NON_PLANE_0}, /* Tangsa */
+ {U"\U00016AD0\U00016AD2\U00016ADA", 2, TT_UCR_NON_PLANE_0}, /* Bassa Vah */
+ {U"\U00016B00\U00016B01\U00016B02", 2, TT_UCR_NON_PLANE_0}, /* Pahawh Hmong */
+ {U"\U00016F01\U00016F05\U00016F09", 2, TT_UCR_NON_PLANE_0}, /* Miao */
+ {U"\U0001BC19\U0001BC1f\U0001BC0e", 2, TT_UCR_NON_PLANE_0}, /* Duployan */
+ {U"\U0001D2E0\U0001D2E6\U0001D2f3", 2, TT_UCR_NON_PLANE_0}, /* Mayan Numerals */
+ {U"\U0001E800\U0001E80A\U0001E80F", 2, TT_UCR_NON_PLANE_0}, /* Mende Kikakui */
+ {U"\U0001E900\U0001E902\U0001E907", 2, TT_UCR_NON_PLANE_0}, /* Adlam */
+ {U"\U0001E2C0\U0001E2C2\U0001E2C7", 2, TT_UCR_NON_PLANE_0}, /* Wancho */
+ {U"\U0001EC71\U0001EC72\U0001EC73", 2, TT_UCR_NON_PLANE_0}, /* Indic Siyaq Numbers */
+ /* Basic Multilingual Plane but are not indexed with an OS2 coverage bit. */
+ {U"\u0638\u0630\u0633", 0, 0}, /* Urdu */
+ {U"\u0800\u0801\u0802", 0, 0}, /* Samaritan */
+ {U"\u0841\u0842\u084c", 0, 0}, /* Mandaic */
+ {U"\u1A20\u1A21\u1A22", 0, 0}, /* Tai Tham */
+ {U"\u1BC0\u1BC1\u1BC2", 0, 0}, /* Batak */
+ {U"\uA4EF\uA4E8\uA4ED", 0, 0}, /* Lisu */
+ {U"\uA6A0\uA6A1\uA6A2", 0, 0}, /* Bamum */
+ {U"\ua983\ua984\ua98d", 0, 0}, /* Javanese */
+ {U"\uaa80\uaa81\uaa82", 0, 0}, /* Tai Viet */
+ {U"\uABC0\uABC1\uABC2", 0, 0}, /* Meetei Mayek */
+ /* Near the end since many fonts contain these. */
+ {U"\u03e2\u03e4\u03e8", 1, TT_UCR_COPTIC},
+ {U"\u1f08\u03a6\u03a8", 1, TT_UCR_GREEK},
+ {U"\u0518\u0409\u040f", 1, TT_UCR_CYRILLIC},
+ {U"\u0533\u0537\u0539", 1, TT_UCR_ARMENIAN},
+};
+
+static const char32_t *blf_get_sample_text(FT_Face face)
{
- const uint dpi = 72;
- const int font_size_min = 6;
- int font_size_curr;
- /* shrink 1/th each line */
- int font_shrink = 4;
+ /* First check for fonts with MS Symbol character map. */
+ if (face->charmap->encoding == FT_ENCODING_MS_SYMBOL) {
+ /* Many of these have characters starting from F020. */
+ if (FT_Get_Char_Index(face, U'\uf041') != 0) {
+ return U"\uf041\uf044\uf048";
+ }
+ if (FT_Get_Char_Index(face, U'\uf030') != 0) {
+ return U"\uf030\uf031\uf032";
+ }
+ return U"ADH";
+ }
- /* While viewing thumbnails in font directories this function can be called simultaneously from a
- * greater number of threads than we want the FreeType cache to keep open at a time. Therefore
- * pass own FT_Library to font creation so that it is not managed by the FreeType cache system.
- */
+ const char32_t *def = U"Aabg";
+ const char32_t *sample = def;
- FT_Library ft_library = NULL;
- if (FT_Init_FreeType(&ft_library) != FT_Err_Ok) {
- return;
+ /* Fonts too old to have a Unicode character map. */
+ if (face->charmap->encoding != FT_ENCODING_UNICODE) {
+ return def;
}
- FontBLF *font = blf_font_new_ex("thumb_font", filepath, NULL, 0, ft_library);
- if (!font) {
- printf("Info: Can't load font '%s', no preview possible\n", filepath);
- FT_Done_FreeType(ft_library);
- return;
+ /* TrueType table with bits to quickly test most Unicode block coverage. */
+ TT_OS2 *os2_table = (TT_OS2 *)FT_Get_Sfnt_Table(face, FT_SFNT_OS2);
+ if (!os2_table) {
+ return def;
+ }
+
+ /* Detect "Last resort" fonts. They have everything, except the last 5 bits. */
+ if (os2_table->ulUnicodeRange1 == 0xffffffffU && os2_table->ulUnicodeRange2 == 0xffffffffU &&
+ os2_table->ulUnicodeRange3 == 0xffffffffU && os2_table->ulUnicodeRange4 >= 0x7FFFFFFU) {
+ return U"\xE000\xFFFF";
+ }
+
+ int language_count = count_bits_i((uint)os2_table->ulUnicodeRange1) +
+ count_bits_i((uint)os2_table->ulUnicodeRange2) +
+ count_bits_i((uint)os2_table->ulUnicodeRange3) +
+ count_bits_i((uint)os2_table->ulUnicodeRange4);
+
+ for (uint i = 0; i < ARRAY_SIZE(unicode_samples); ++i) {
+ const UnicodeSample *s = &unicode_samples[i];
+ if (os2_table && s->field && s->mask) {
+ /* OS/2 Table contains 4 contiguous integers of script coverage bit flags. */
+ const FT_ULong *unicode_range = &os2_table->ulUnicodeRange1;
+ const int index = (s->field - 1);
+ BLI_assert(index < 4);
+ if (!(unicode_range[index] & s->mask)) {
+ continue;
+ }
+ }
+ if (FT_Get_Char_Index(face, s->sample[0]) != 0) {
+ sample = s->sample;
+ break;
+ }
}
- /* Would be done via the BLF API, but we're not using a fontid here */
- font->buf_info.cbuf = buf;
- font->buf_info.ch = channels;
- font->buf_info.dims[0] = w;
- font->buf_info.dims[1] = h;
+ bool has_latin = (os2_table && (os2_table->ulUnicodeRange1 & TT_UCR_BASIC_LATIN) &&
+ (FT_Get_Char_Index(face, U'A') != 0));
+ bool has_cjk = (os2_table && (os2_table->ulUnicodeRange2 & TT_UCR_CJK_UNIFIED_IDEOGRAPHS));
- /* Always create the image with a white font,
- * the caller can theme how it likes */
- memcpy(font->buf_info.col_init, font_color, sizeof(font->buf_info.col_init));
- font->pos[1] = h;
+ if (has_latin && ((has_cjk && language_count > 40) || (!has_cjk && language_count > 5))) {
+ return def;
+ }
- font_size_curr = font_size;
+ return sample;
+}
- blf_draw_buffer__start(font);
+bool BLF_thumb_preview(const char *filename, uchar *buf, int w, int h, int UNUSED(channels))
+{
+ /* Use own FT_Library and direct FreeType calls as this is called from multiple threads. */
+ FT_Library ft_lib = NULL;
+ if (FT_Init_FreeType(&ft_lib) != FT_Err_Ok) {
+ return false;
+ }
- for (int i = 0; i < draw_str_lines; i++) {
- const char *draw_str_i18n = i18n_draw_str[i] != NULL ? i18n_draw_str[i] : draw_str[i];
- const size_t draw_str_i18n_len = strlen(draw_str_i18n);
- int draw_str_i18_count = 0;
+ FT_Face face;
+ if (FT_New_Face(ft_lib, filename, 0, &face) != FT_Err_Ok) {
+ FT_Done_FreeType(ft_lib);
+ return false;
+ }
- CLAMP_MIN(font_size_curr, font_size_min);
- if (!blf_font_size(font, (float)font_size_curr, dpi)) {
- break;
+ if (!(face->face_flags & FT_FACE_FLAG_SCALABLE)) {
+ return false;
+ }
+
+ FT_Error err = FT_Select_Charmap(face, FT_ENCODING_UNICODE);
+ if (err) {
+ err = FT_Select_Charmap(face, FT_ENCODING_MS_SYMBOL);
+ }
+ if (err) {
+ err = FT_Select_Charmap(face, FT_ENCODING_APPLE_ROMAN);
+ }
+ if (err && face->num_charmaps > 0) {
+ err = FT_Select_Charmap(face, face->charmaps[0]->encoding);
+ }
+ if (err != FT_Err_Ok) {
+ FT_Done_Face(face);
+ FT_Done_FreeType(ft_lib);
+ return false;
+ }
+
+ const char32_t *codepoints = blf_get_sample_text(face);
+ uint glyph_ids[BLF_SAMPLE_LEN] = {0};
+
+ /* A large initial font size for measuring. Nothing will be rendered this size. */
+ if (FT_Set_Char_Size(face, w * 64, 0, 72, 72) != FT_Err_Ok) {
+ FT_Done_Face(face);
+ FT_Done_FreeType(ft_lib);
+ return false;
+ }
+
+ /* Approximate length of the sample. Uses only advances, ignores bearings. */
+ int width = 0;
+ for (uint i = 0; i < BLF_SAMPLE_LEN && codepoints[i]; i++) {
+ glyph_ids[i] = FT_Get_Char_Index(face, codepoints[i]);
+ /* If sample glyph is not found, use another. */
+ if (!glyph_ids[i]) {
+ glyph_ids[i] = (uint)(face->num_glyphs / (BLF_SAMPLE_LEN + 1)) * (i + 1);
}
+ /* Get advance without loading the glyph. */
+ FT_Fixed advance;
+ FT_Get_Advance(face, glyph_ids[i], FT_LOAD_NO_HINTING, &advance);
+ /* Advance is returned in 16.16 format, so divide by 65536 for pixels. */
+ width += (int)(advance >> 16);
+ }
+
+ int height = ft_pix_to_int((ft_pix)face->size->metrics.ascender -
+ (ft_pix)face->size->metrics.descender);
+ width = MAX2(width, height);
+
+ /* Fill up to 96% horizontally or vertically. */
+ float font_size = MIN3((float)w,
+ ((float)w * 0.96f / (float)width * (float)w),
+ (float)h * 0.96f / (float)height * (float)h);
- /* decrease font size each time */
- font_size_curr -= (font_size_curr / font_shrink);
- font_shrink += 1;
+ if (font_size < 1 || FT_Set_Char_Size(face, (int)(font_size * 64.0f), 0, 72, 72) != FT_Err_Ok) {
+ /* Sizing can fail, but very rarely. */
+ FT_Done_Face(face);
+ FT_Done_FreeType(ft_lib);
+ return false;
+ }
+
+ /* Horizontally center, line up baselines vertically. */
+ int left = (int)(((float)w - ((float)width * (font_size / (float)w))) / 2.0f);
+ int top = (int)((float)h * 0.7f);
+
+ /* Print out to buffer. */
- font->pos[1] -= (int)((float)blf_font_ascender(font) * 1.1f);
+ FT_Pos advance_x = 0;
+ int glyph_count = 0; /* How many are successfully loaded and rendered. */
- /* We fallback to default english strings in case not enough chars are available in current
- * font for given translated string (useful in non-Latin i18n context, like Chinese,
- * since many fonts will then show nothing but ugly 'missing char' in their preview).
- * Does not handle all cases, but much better than nothing.
- */
- if (blf_font_count_missing_chars(font, draw_str_i18n, draw_str_i18n_len, &draw_str_i18_count) >
- (draw_str_i18_count / 2)) {
- blf_font_draw_buffer(font, draw_str[i], strlen(draw_str[i]), NULL);
+ for (int i = 0; i < BLF_SAMPLE_LEN && glyph_ids[i]; i++) {
+ if (FT_Load_Glyph(face, glyph_ids[i], FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING) !=
+ FT_Err_Ok) {
+ break;
}
- else {
- blf_font_draw_buffer(font, draw_str_i18n, draw_str_i18n_len, NULL);
+
+ if (FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL) != FT_Err_Ok ||
+ face->glyph->format != FT_GLYPH_FORMAT_BITMAP) {
+ break;
}
+
+ glyph_count++;
+
+ for (int y = 0; y < (int)face->glyph->bitmap.rows; y++) {
+ int dest_row = (h - y - 1 + (int)face->glyph->bitmap_top - top);
+ if (dest_row >= 0 && dest_row < h) {
+ for (int x = 0; x < (int)face->glyph->bitmap.width; x++) {
+ int dest_col = (x + ft_pix_to_int((ft_pix)advance_x) + face->glyph->bitmap_left + left);
+ if (dest_col >= 0 && dest_col < w) {
+ uchar *source = &face->glyph->bitmap.buffer[y * (int)face->glyph->bitmap.width + x];
+ uchar *dest = &buf[dest_row * w * 4 + (dest_col * 4 + 3)];
+ *dest = (uchar)MIN2(((uint)*dest + (uint)*source), 255u);
+ }
+ }
+ }
+ }
+
+ advance_x += face->glyph->advance.x;
}
- blf_draw_buffer__end();
- blf_font_free(font);
- FT_Done_FreeType(ft_library);
+ FT_Done_Face(face);
+ FT_Done_FreeType(ft_lib);
+
+ /* Return success if we printed at least one glyph. */
+ return glyph_count > 0;
}
diff --git a/source/blender/blenfont/intern/blf_util.c b/source/blender/blenfont/intern/blf_util.c
index 09ddb56e53b..2243da4df18 100644
--- a/source/blender/blenfont/intern/blf_util.c
+++ b/source/blender/blenfont/intern/blf_util.c
@@ -15,7 +15,7 @@
#include "blf_internal.h"
-unsigned int blf_next_p2(unsigned int x)
+uint blf_next_p2(uint x)
{
x -= 1;
x |= (x >> 16);
@@ -27,9 +27,9 @@ unsigned int blf_next_p2(unsigned int x)
return x;
}
-unsigned int blf_hash(unsigned int val)
+uint blf_hash(uint val)
{
- unsigned int key;
+ uint key;
key = val;
key += ~(key << 16);
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index da1e45ababd..cb9c4256e33 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -104,9 +104,6 @@ struct DerivedMesh {
int num_alloc;
} looptris;
- /* use for converting to BMesh which doesn't store bevel weight and edge crease by default */
- char cd_flag;
-
short tangent_mask; /* which tangent layers are calculated */
/** Loop tessellation cache (WARNING! Only call inside threading-protected code!) */
diff --git a/source/blender/blenkernel/BKE_appdir.h b/source/blender/blenkernel/BKE_appdir.h
index 0f00ab9c321..a67c6c27b47 100644
--- a/source/blender/blenkernel/BKE_appdir.h
+++ b/source/blender/blenkernel/BKE_appdir.h
@@ -90,7 +90,10 @@ const char *BKE_appdir_folder_id_user_notest(int folder_id,
* Returns the path of the top-level version-specific local, user or system directory.
* If check_is_dir, then the result will be NULL if the directory doesn't exist.
*/
-const char *BKE_appdir_folder_id_version(int folder_id, int version, bool check_is_dir);
+const char *BKE_appdir_resource_path_id_with_version(int folder_id,
+ bool check_is_dir,
+ int version);
+const char *BKE_appdir_resource_path_id(int folder_id, bool check_is_dir);
/**
* Check if this is an install with user files kept together
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index ee0f41937e2..eff05e471aa 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -34,9 +34,9 @@ typedef struct EditBone {
/** User-Defined Properties on this Bone */
struct IDProperty *prop;
/**
- * Editbones have a one-way link (i.e. children refer
+ * Edit-bones have a one-way link (i.e. children refer
* to parents. This is converted to a two-way link for
- * normal bones when leaving editmode.
+ * normal bones when leaving edit-mode.
*/
struct EditBone *parent;
/** (64 == MAXBONENAME) */
diff --git a/source/blender/blenkernel/BKE_asset.h b/source/blender/blenkernel/BKE_asset.h
index 81b520a1db0..bcbe19c0f3e 100644
--- a/source/blender/blenkernel/BKE_asset.h
+++ b/source/blender/blenkernel/BKE_asset.h
@@ -23,6 +23,9 @@ struct ID;
struct IDProperty;
struct PreviewImage;
+/** C handle for #bke::AssetRepresentation. */
+typedef struct AssetRepresentation AssetRepresentation;
+
typedef void (*PreSaveFn)(void *asset_ptr, struct AssetMetaData *asset_data);
typedef struct AssetTypeInfo {
@@ -68,6 +71,22 @@ struct PreviewImage *BKE_asset_metadata_preview_get_from_id(const struct AssetMe
void BKE_asset_metadata_write(struct BlendWriter *writer, struct AssetMetaData *asset_data);
void BKE_asset_metadata_read(struct BlendDataReader *reader, struct AssetMetaData *asset_data);
+const char *BKE_asset_representation_name_get(const AssetRepresentation *asset)
+ ATTR_WARN_UNUSED_RESULT;
+AssetMetaData *BKE_asset_representation_metadata_get(const AssetRepresentation *asset)
+ ATTR_WARN_UNUSED_RESULT;
+bool BKE_asset_representation_is_local_id(const AssetRepresentation *asset)
+ ATTR_WARN_UNUSED_RESULT;
+
#ifdef __cplusplus
}
#endif
+
+#ifdef __cplusplus
+
+# include <memory>
+
+[[nodiscard]] std::unique_ptr<AssetMetaData> BKE_asset_metadata_move_to_unique_ptr(
+ AssetMetaData *asset_data);
+
+#endif
diff --git a/source/blender/blenkernel/BKE_asset_catalog.hh b/source/blender/blenkernel/BKE_asset_catalog.hh
index caed12d4fdf..73c2e00c4c4 100644
--- a/source/blender/blenkernel/BKE_asset_catalog.hh
+++ b/source/blender/blenkernel/BKE_asset_catalog.hh
@@ -307,7 +307,7 @@ class AssetCatalogTreeItem {
/** Iterate over children calling \a callback for each of them, but do not recurse into their
* children. */
- void foreach_child(const ItemIterFn callback);
+ void foreach_child(ItemIterFn callback);
protected:
/** Child tree items, ordered by their names. */
@@ -345,10 +345,15 @@ class AssetCatalogTree {
/** Ensure an item representing \a path is in the tree, adding it if necessary. */
void insert_item(const AssetCatalog &catalog);
- void foreach_item(const AssetCatalogTreeItem::ItemIterFn callback);
+ void foreach_item(ItemIterFn callback);
/** Iterate over root items calling \a callback for each of them, but do not recurse into their
* children. */
- void foreach_root_item(const ItemIterFn callback);
+ void foreach_root_item(ItemIterFn callback);
+
+ bool is_empty() const;
+
+ AssetCatalogTreeItem *find_item(const AssetCatalogPath &path);
+ AssetCatalogTreeItem *find_root_item(const AssetCatalogPath &path);
protected:
/** Child tree items, ordered by their names. */
diff --git a/source/blender/blenkernel/BKE_asset_catalog_path.hh b/source/blender/blenkernel/BKE_asset_catalog_path.hh
index 135906dd064..93ab0389daf 100644
--- a/source/blender/blenkernel/BKE_asset_catalog_path.hh
+++ b/source/blender/blenkernel/BKE_asset_catalog_path.hh
@@ -49,7 +49,7 @@ class AssetCatalogPath {
AssetCatalogPath() = default;
AssetCatalogPath(StringRef path);
- AssetCatalogPath(const std::string &path);
+ AssetCatalogPath(std::string path);
AssetCatalogPath(const char *path);
AssetCatalogPath(const AssetCatalogPath &other_path) = default;
AssetCatalogPath(AssetCatalogPath &&other_path) noexcept;
diff --git a/source/blender/blenkernel/BKE_asset_library.h b/source/blender/blenkernel/BKE_asset_library.h
index 824bc24203d..fc648ff6976 100644
--- a/source/blender/blenkernel/BKE_asset_library.h
+++ b/source/blender/blenkernel/BKE_asset_library.h
@@ -6,6 +6,7 @@
#pragma once
+struct IDRemapper;
struct Main;
#ifdef __cplusplus
@@ -24,41 +25,6 @@ typedef struct AssetLibrary AssetLibrary;
*/
struct AssetLibrary *BKE_asset_library_load(const char *library_path);
-/**
- * Try to find an appropriate location for an asset library root from a file or directory path.
- * Does not check if \a input_path exists.
- *
- * The design is made to find an appropriate asset library path from a .blend file path, but
- * technically works with any file or directory as \a input_path.
- * Design is:
- * * If \a input_path lies within a known asset library path (i.e. an asset library registered in
- * the Preferences), return the asset library path.
- * * Otherwise, if \a input_path has a parent path, return the parent path (e.g. to use the
- * directory a .blend file is in as asset library root).
- * * If \a input_path is empty or doesn't have a parent path (e.g. because a .blend wasn't saved
- * yet), there is no suitable path. The caller has to decide how to handle this case.
- *
- * \param r_library_path: The returned asset library path with a trailing slash, or an empty string
- * if no suitable path is found. Assumed to be a buffer of at least
- * #FILE_MAXDIR bytes.
- *
- * \return True if the function could find a valid, that is, a non-empty path to return in \a
- * r_library_path.
- */
-bool BKE_asset_library_find_suitable_root_path_from_path(
- const char *input_path, char r_library_path[768 /* FILE_MAXDIR */]);
-/**
- * Uses the current location on disk of the file represented by \a bmain as input to
- * #BKE_asset_library_find_suitable_root_path_from_path(). Refer to it for a design
- * description.
- *
- * \return True if the function could find a valid, that is, a non-empty path to return in \a
- * r_library_path. If \a bmain wasn't saved into a file yet, the return value will be
- * false.
- */
-bool BKE_asset_library_find_suitable_root_path_from_main(
- const struct Main *bmain, char r_library_path[768 /* FILE_MAXDIR */]);
-
/** Look up the asset's catalog and copy its simple name into #asset_data. */
void BKE_asset_library_refresh_catalog_simplename(struct AssetLibrary *asset_library,
struct AssetMetaData *asset_data);
@@ -66,6 +32,10 @@ void BKE_asset_library_refresh_catalog_simplename(struct AssetLibrary *asset_lib
/** Return whether any loaded AssetLibrary has unsaved changes to its catalogs. */
bool BKE_asset_library_has_any_unsaved_catalogs(void);
+/** An asset library can include local IDs (IDs in the current file). Their pointers need to be
+ * remapped on change (or assets removed as IDs gets removed). */
+void BKE_asset_library_remap_ids(struct IDRemapper *mappings);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_asset_library.hh b/source/blender/blenkernel/BKE_asset_library.hh
index e0a39e3aee8..f69847bd1ed 100644
--- a/source/blender/blenkernel/BKE_asset_library.hh
+++ b/source/blender/blenkernel/BKE_asset_library.hh
@@ -10,6 +10,11 @@
# error This is a C++-only header file. Use BKE_asset_library.h instead.
#endif
+#include "DNA_asset_types.h"
+
+#include "BLI_string_ref.hh"
+#include "BLI_vector.hh"
+
#include "BKE_asset_library.h"
#include "BKE_asset_catalog.hh"
@@ -17,11 +22,18 @@
#include <memory>
+struct AssetLibraryReference;
+struct Main;
+
namespace blender::bke {
+class AssetRepresentation;
+
/**
* AssetLibrary provides access to an asset library's data.
- * For now this is only for catalogs, later this can be expanded to indexes/caches/more.
+ *
+ * The asset library contains catalogs and storage for asset representations. It could be extended
+ * to also include asset indexes and more.
*/
struct AssetLibrary {
/* Controlled by #ED_asset_catalogs_set_save_catalogs_when_file_is_saved,
@@ -33,30 +45,101 @@ struct AssetLibrary {
AssetLibrary();
~AssetLibrary();
- void load(StringRefNull library_root_directory);
+ void load_catalogs(StringRefNull library_root_directory);
/** Load catalogs that have changed on disk. */
void refresh();
/**
+ * Create a representation of an asset to be considered part of this library. Once the
+ * representation is not needed anymore, it must be freed using #remove_asset(), or there will be
+ * leaking that's only cleared when the library storage is destructed (typically on exit or
+ * loading a different file).
+ */
+ AssetRepresentation &add_external_asset(StringRef name, std::unique_ptr<AssetMetaData> metadata);
+ AssetRepresentation &add_local_id_asset(ID &id);
+ /** Remove an asset from the library that was added using #add_external_asset() or
+ * #add_local_id_asset().
+ * \return True on success, false if the asset couldn't be found inside the library. */
+ bool remove_asset(AssetRepresentation &asset);
+
+ /**
* Update `catalog_simple_name` by looking up the asset's catalog by its ID.
*
* No-op if the catalog cannot be found. This could be the kind of "the
* catalog definition file is corrupt/lost" scenario that the simple name is
* meant to help recover from. */
- void refresh_catalog_simplename(struct AssetMetaData *asset_data);
+ void refresh_catalog_simplename(AssetMetaData *asset_data);
void on_blend_save_handler_register();
void on_blend_save_handler_unregister();
- void on_blend_save_post(struct Main *, struct PointerRNA **pointers, int num_pointers);
+ void on_blend_save_post(Main *bmain, PointerRNA **pointers, int num_pointers);
+
+ void remap_ids(struct IDRemapper &mappings);
private:
bCallbackFuncStore on_save_callback_store_{};
+
+ /** Storage for assets (better said their representations) that are considered to be part of this
+ * library. Assets are not automatically loaded into this when loading an asset library. Assets
+ * have to be loaded externally and added to this storage via #add_external_asset() or
+ * #add_local_id_asset(). So this really is arbitrary storage as far as #AssetLibrary is
+ * concerned (allowing the API user to manage partial library storage and partial loading, so
+ * only relevant parts of a library are kept in memory).
+ *
+ * For now, multiple parts of Blender just keep adding their own assets to this storage. E.g.
+ * multiple asset browsers might load multiple representations for the same asset into this.
+ * Currently there is just no way to properly identify assets, or keep track of which assets are
+ * already in memory and which not. Neither do we keep track of how many parts of Blender are
+ * using an asset or an asset library, which is needed to know when assets can be freed.
+ */
+ Vector<std::unique_ptr<AssetRepresentation>> asset_storage_;
+
+ std::optional<int> find_asset_index(const AssetRepresentation &asset);
};
+Vector<AssetLibraryReference> all_valid_asset_library_refs();
+
} // namespace blender::bke
+blender::bke::AssetLibrary *BKE_asset_library_load(const Main *bmain,
+ const AssetLibraryReference &library_reference);
+
+/**
+ * Try to find an appropriate location for an asset library root from a file or directory path.
+ * Does not check if \a input_path exists.
+ *
+ * The design is made to find an appropriate asset library path from a .blend file path, but
+ * technically works with any file or directory as \a input_path.
+ * Design is:
+ * * If \a input_path lies within a known asset library path (i.e. an asset library registered in
+ * the Preferences), return the asset library path.
+ * * Otherwise, if \a input_path has a parent path, return the parent path (e.g. to use the
+ * directory a .blend file is in as asset library root).
+ * * If \a input_path is empty or doesn't have a parent path (e.g. because a .blend wasn't saved
+ * yet), there is no suitable path. The caller has to decide how to handle this case.
+ *
+ * \param r_library_path: The returned asset library path with a trailing slash, or an empty string
+ * if no suitable path is found. Assumed to be a buffer of at least
+ * #FILE_MAXDIR bytes.
+ *
+ * \return True if the function could find a valid, that is, a non-empty path to return in \a
+ * r_library_path.
+ */
+std::string BKE_asset_library_find_suitable_root_path_from_path(blender::StringRefNull input_path);
+
+/**
+ * Uses the current location on disk of the file represented by \a bmain as input to
+ * #BKE_asset_library_find_suitable_root_path_from_path(). Refer to it for a design
+ * description.
+ *
+ * \return True if the function could find a valid, that is, a non-empty path to return in \a
+ * r_library_path. If \a bmain wasn't saved into a file yet, the return value will be
+ * false.
+ */
+std::string BKE_asset_library_find_suitable_root_path_from_main(const struct Main *bmain);
+
blender::bke::AssetCatalogService *BKE_asset_library_get_catalog_service(
const ::AssetLibrary *library);
blender::bke::AssetCatalogTree *BKE_asset_library_get_catalog_tree(const ::AssetLibrary *library);
diff --git a/source/blender/blenkernel/BKE_asset_representation.hh b/source/blender/blenkernel/BKE_asset_representation.hh
new file mode 100644
index 00000000000..edaa5a203ba
--- /dev/null
+++ b/source/blender/blenkernel/BKE_asset_representation.hh
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup bke
+ */
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include "BLI_string_ref.hh"
+
+struct AssetMetaData;
+struct ID;
+
+namespace blender::bke {
+
+/**
+ * \brief Abstraction to reference an asset, with necessary data for display & interaction.
+ *
+ * https://wiki.blender.org/wiki/Source/Architecture/Asset_System/Back_End#Asset_Representation
+ */
+class AssetRepresentation {
+ friend struct AssetLibrary;
+
+ struct ExternalAsset {
+ std::string name;
+ std::unique_ptr<AssetMetaData> metadata_ = nullptr;
+ };
+
+ /** Indicate if this is a local or external asset, and as such, which of the union members below
+ * should be used. */
+ const bool is_local_id_ = false;
+
+ union {
+ ExternalAsset external_asset_;
+ ID *local_asset_id_ = nullptr; /* Non-owning. */
+ };
+
+ public:
+ /** Constructs an asset representation for an external ID. The asset will not be editable. */
+ explicit AssetRepresentation(StringRef name, std::unique_ptr<AssetMetaData> metadata);
+ /** Constructs an asset representation for an ID stored in the current file. This makes the asset
+ * local and fully editable. */
+ explicit AssetRepresentation(ID &id);
+ AssetRepresentation(AssetRepresentation &&other);
+ /* Non-copyable type. */
+ AssetRepresentation(const AssetRepresentation &other) = delete;
+ ~AssetRepresentation();
+
+ /* Non-move-assignable type. Move construction is fine, but treat the "identity" (e.g. local vs
+ * external asset) of an asset representation as immutable. */
+ AssetRepresentation &operator=(AssetRepresentation &&other) = delete;
+ /* Non-copyable type. */
+ AssetRepresentation &operator=(const AssetRepresentation &other) = delete;
+
+ StringRefNull get_name() const;
+ AssetMetaData &get_metadata() const;
+ /** Returns if this asset is stored inside this current file, and as such fully editable. */
+ bool is_local_id() const;
+};
+
+} // namespace blender::bke
diff --git a/source/blender/blenkernel/BKE_attribute.hh b/source/blender/blenkernel/BKE_attribute.hh
index 21d91af55d5..a4f9d73c31e 100644
--- a/source/blender/blenkernel/BKE_attribute.hh
+++ b/source/blender/blenkernel/BKE_attribute.hh
@@ -16,6 +16,10 @@
struct Mesh;
struct PointCloud;
+namespace blender::fn {
+class MultiFunction;
+class GField;
+} // namespace blender::fn
namespace blender::bke {
@@ -163,6 +167,27 @@ template<typename T> struct AttributeReader {
};
/**
+ * A utility to make sure attribute values are valid, for attributes like "material_index" which
+ * can only be positive, or attributes that represent enum options. This is usually only necessary
+ * when writing attributes from an untrusted/arbitrary user input.
+ */
+struct AttributeValidator {
+ /**
+ * Single input, single output function that corrects attribute values if necessary.
+ */
+ const fn::MultiFunction *function;
+
+ operator bool() const
+ {
+ return this->function != nullptr;
+ }
+ /**
+ * Return a field that creates corrected attribute values.
+ */
+ fn::GField validate_field_if_necessary(const fn::GField &field) const;
+};
+
+/**
* Result when looking up an attribute from some geometry with read and write access. After writing
* to the attribute, the #finish method has to be called. This may invalidate caches based on this
* attribute.
@@ -239,7 +264,9 @@ template<typename T> struct SpanAttributeWriter {
*/
void finish()
{
- this->span.save();
+ if (this->span.varray()) {
+ this->span.save();
+ }
if (this->tag_modified_fn) {
this->tag_modified_fn();
}
@@ -314,7 +341,9 @@ struct GSpanAttributeWriter {
void finish()
{
- this->span.save();
+ if (this->span.varray()) {
+ this->span.save();
+ }
if (this->tag_modified_fn) {
this->tag_modified_fn();
}
@@ -343,7 +372,7 @@ struct AttributeAccessorFunctions {
eAttrDomain to_domain);
bool (*for_all)(const void *owner,
FunctionRef<bool(const AttributeIDRef &, const AttributeMetaData &)> fn);
-
+ AttributeValidator (*lookup_validator)(const void *owner, const AttributeIDRef &attribute_id);
GAttributeWriter (*lookup_for_write)(void *owner, const AttributeIDRef &attribute_id);
bool (*remove)(void *owner, const AttributeIDRef &attribute_id);
bool (*add)(void *owner,
@@ -498,6 +527,14 @@ class AttributeAccessor {
}
/**
+ * Same as the generic version above, but should be used when the type is known at compile time.
+ */
+ AttributeValidator lookup_validator(const AttributeIDRef &attribute_id) const
+ {
+ return fn_->lookup_validator(owner_, attribute_id);
+ }
+
+ /**
* Interpolate data from one domain to another.
*/
GVArray adapt_domain(const GVArray &varray,
@@ -659,6 +696,8 @@ class MutableAttributeAccessor : public AttributeAccessor {
* The "only" in the name indicates that the caller should not read existing values from the
* span. If the attribute is not stored as span internally, the existing values won't be copied
* over to the span.
+ *
+ * For trivial types, the values in a newly created attribute will not be initialized.
*/
GSpanAttributeWriter lookup_or_add_for_write_only_span(const AttributeIDRef &attribute_id,
const eAttrDomain domain,
@@ -671,7 +710,9 @@ class MutableAttributeAccessor : public AttributeAccessor {
SpanAttributeWriter<T> lookup_or_add_for_write_only_span(const AttributeIDRef &attribute_id,
const eAttrDomain domain)
{
- AttributeWriter<T> attribute = this->lookup_or_add_for_write<T>(attribute_id, domain);
+ AttributeWriter<T> attribute = this->lookup_or_add_for_write<T>(
+ attribute_id, domain, AttributeInitConstruct());
+
if (attribute) {
return SpanAttributeWriter<T>{std::move(attribute), false};
}
@@ -710,6 +751,19 @@ Vector<AttributeTransferData> retrieve_attributes_for_transfer(
eAttrDomainMask domain_mask,
const Set<std::string> &skip = {});
+/**
+ * Copy attributes for the domain based on the elementwise mask.
+ *
+ * \param mask_indices: Indexed elements to copy from the source data-block.
+ * \param domain: Attribute domain to transfer.
+ * \param skip: Named attributes to ignore/skip.
+ */
+void copy_attribute_domain(AttributeAccessor src_attributes,
+ MutableAttributeAccessor dst_attributes,
+ IndexMask selection,
+ eAttrDomain domain,
+ const Set<std::string> &skip = {});
+
bool allow_procedural_attribute_access(StringRef attribute_name);
extern const char *no_procedural_access_message;
@@ -739,7 +793,9 @@ class CustomDataAttributes {
~CustomDataAttributes();
CustomDataAttributes(const CustomDataAttributes &other);
CustomDataAttributes(CustomDataAttributes &&other);
+
CustomDataAttributes &operator=(const CustomDataAttributes &other);
+ CustomDataAttributes &operator=(CustomDataAttributes &&other);
void reallocate(int size);
diff --git a/source/blender/blenkernel/BKE_attribute_math.hh b/source/blender/blenkernel/BKE_attribute_math.hh
index 770937688d7..5c0e5f428a4 100644
--- a/source/blender/blenkernel/BKE_attribute_math.hh
+++ b/source/blender/blenkernel/BKE_attribute_math.hh
@@ -46,6 +46,58 @@ inline void convert_to_static_type(const eCustomDataType data_type, const Func &
}
/* -------------------------------------------------------------------- */
+/** \name Mix two values of the same type.
+ *
+ * This is just basic linear interpolation.
+ * \{ */
+
+template<typename T> T mix2(float factor, const T &a, const T &b);
+
+template<> inline bool mix2(const float factor, const bool &a, const bool &b)
+{
+ return ((1.0f - factor) * a + factor * b) >= 0.5f;
+}
+
+template<> inline int8_t mix2(const float factor, const int8_t &a, const int8_t &b)
+{
+ return int8_t(std::round((1.0f - factor) * a + factor * b));
+}
+
+template<> inline int mix2(const float factor, const int &a, const int &b)
+{
+ return int(std::round((1.0f - factor) * a + factor * b));
+}
+
+template<> inline float mix2(const float factor, const float &a, const float &b)
+{
+ return (1.0f - factor) * a + factor * b;
+}
+
+template<> inline float2 mix2(const float factor, const float2 &a, const float2 &b)
+{
+ return math::interpolate(a, b, factor);
+}
+
+template<> inline float3 mix2(const float factor, const float3 &a, const float3 &b)
+{
+ return math::interpolate(a, b, factor);
+}
+
+template<>
+inline ColorGeometry4f mix2(const float factor, const ColorGeometry4f &a, const ColorGeometry4f &b)
+{
+ return math::interpolate(a, b, factor);
+}
+
+template<>
+inline ColorGeometry4b mix2(const float factor, const ColorGeometry4b &a, const ColorGeometry4b &b)
+{
+ return math::interpolate(a, b, factor);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Mix three values of the same type.
*
* This is typically used to interpolate values within a triangle.
@@ -56,7 +108,7 @@ template<typename T> T mix3(const float3 &weights, const T &v0, const T &v1, con
template<>
inline int8_t mix3(const float3 &weights, const int8_t &v0, const int8_t &v1, const int8_t &v2)
{
- return static_cast<int8_t>(std::round(weights.x * v0 + weights.y * v1 + weights.z * v2));
+ return int8_t(std::round(weights.x * v0 + weights.y * v1 + weights.z * v2));
}
template<> inline bool mix3(const float3 &weights, const bool &v0, const bool &v1, const bool &v2)
@@ -66,7 +118,7 @@ template<> inline bool mix3(const float3 &weights, const bool &v0, const bool &v
template<> inline int mix3(const float3 &weights, const int &v0, const int &v1, const int &v2)
{
- return static_cast<int>(std::round(weights.x * v0 + weights.y * v1 + weights.z * v2));
+ return int(std::round(weights.x * v0 + weights.y * v1 + weights.z * v2));
}
template<>
@@ -108,62 +160,88 @@ inline ColorGeometry4b mix3(const float3 &weights,
const float4 v1_f{&v1.r};
const float4 v2_f{&v2.r};
const float4 mixed = v0_f * weights[0] + v1_f * weights[1] + v2_f * weights[2];
- return ColorGeometry4b{static_cast<uint8_t>(mixed[0]),
- static_cast<uint8_t>(mixed[1]),
- static_cast<uint8_t>(mixed[2]),
- static_cast<uint8_t>(mixed[3])};
+ return ColorGeometry4b{
+ uint8_t(mixed[0]), uint8_t(mixed[1]), uint8_t(mixed[2]), uint8_t(mixed[3])};
}
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Mix two values of the same type.
+/** \name Mix four values of the same type.
*
- * This is just basic linear interpolation.
* \{ */
-template<typename T> T mix2(float factor, const T &a, const T &b);
+template<typename T>
+T mix4(const float4 &weights, const T &v0, const T &v1, const T &v2, const T &v3);
-template<> inline bool mix2(const float factor, const bool &a, const bool &b)
+template<>
+inline int8_t mix4(
+ const float4 &weights, const int8_t &v0, const int8_t &v1, const int8_t &v2, const int8_t &v3)
{
- return ((1.0f - factor) * a + factor * b) >= 0.5f;
+ return int8_t(std::round(weights.x * v0 + weights.y * v1 + weights.z * v2 + weights.w * v3));
}
-template<> inline int8_t mix2(const float factor, const int8_t &a, const int8_t &b)
+template<>
+inline bool mix4(
+ const float4 &weights, const bool &v0, const bool &v1, const bool &v2, const bool &v3)
{
- return static_cast<int8_t>(std::round((1.0f - factor) * a + factor * b));
+ return (weights.x * v0 + weights.y * v1 + weights.z * v2 + weights.w * v3) >= 0.5f;
}
-template<> inline int mix2(const float factor, const int &a, const int &b)
+template<>
+inline int mix4(const float4 &weights, const int &v0, const int &v1, const int &v2, const int &v3)
{
- return static_cast<int>(std::round((1.0f - factor) * a + factor * b));
+ return int(std::round(weights.x * v0 + weights.y * v1 + weights.z * v2 + weights.w * v3));
}
-template<> inline float mix2(const float factor, const float &a, const float &b)
+template<>
+inline float mix4(
+ const float4 &weights, const float &v0, const float &v1, const float &v2, const float &v3)
{
- return (1.0f - factor) * a + factor * b;
+ return weights.x * v0 + weights.y * v1 + weights.z * v2 + weights.w * v3;
}
-template<> inline float2 mix2(const float factor, const float2 &a, const float2 &b)
+template<>
+inline float2 mix4(
+ const float4 &weights, const float2 &v0, const float2 &v1, const float2 &v2, const float2 &v3)
{
- return math::interpolate(a, b, factor);
+ return weights.x * v0 + weights.y * v1 + weights.z * v2 + weights.w * v3;
}
-template<> inline float3 mix2(const float factor, const float3 &a, const float3 &b)
+template<>
+inline float3 mix4(
+ const float4 &weights, const float3 &v0, const float3 &v1, const float3 &v2, const float3 &v3)
{
- return math::interpolate(a, b, factor);
+ return weights.x * v0 + weights.y * v1 + weights.z * v2 + weights.w * v3;
}
template<>
-inline ColorGeometry4f mix2(const float factor, const ColorGeometry4f &a, const ColorGeometry4f &b)
+inline ColorGeometry4f mix4(const float4 &weights,
+ const ColorGeometry4f &v0,
+ const ColorGeometry4f &v1,
+ const ColorGeometry4f &v2,
+ const ColorGeometry4f &v3)
{
- return math::interpolate(a, b, factor);
+ ColorGeometry4f result;
+ interp_v4_v4v4v4v4(result, v0, v1, v2, v3, weights);
+ return result;
}
template<>
-inline ColorGeometry4b mix2(const float factor, const ColorGeometry4b &a, const ColorGeometry4b &b)
+inline ColorGeometry4b mix4(const float4 &weights,
+ const ColorGeometry4b &v0,
+ const ColorGeometry4b &v1,
+ const ColorGeometry4b &v2,
+ const ColorGeometry4b &v3)
{
- return math::interpolate(a, b, factor);
+ const float4 v0_f{&v0.r};
+ const float4 v1_f{&v1.r};
+ const float4 v2_f{&v2.r};
+ const float4 v3_f{&v3.r};
+ float4 mixed;
+ interp_v4_v4v4v4v4(mixed, v0_f, v1_f, v2_f, v3_f, weights);
+ return ColorGeometry4b{
+ uint8_t(mixed[0]), uint8_t(mixed[1]), uint8_t(mixed[2]), uint8_t(mixed[3])};
}
/** \} */
@@ -439,7 +517,7 @@ template<> struct DefaultMixerStruct<ColorGeometry4b> {
template<> struct DefaultMixerStruct<int> {
static int double_to_int(const double &value)
{
- return static_cast<int>(std::round(value));
+ return int(std::round(value));
}
/* Store interpolated ints in a double temporarily, so that weights are handled correctly. It
* uses double instead of float so that it is accurate for all 32 bit integers. */
@@ -458,7 +536,7 @@ template<> struct DefaultMixerStruct<bool> {
template<> struct DefaultMixerStruct<int8_t> {
static int8_t float_to_int8_t(const float &value)
{
- return static_cast<int8_t>(std::round(value));
+ return int8_t(std::round(value));
}
/* Store interpolated 8 bit integers in a float temporarily to increase accuracy. */
using type = SimpleMixerWithAccumulationType<int8_t, float, float_to_int8_t>;
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index b42073eeb9a..acb67b30174 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -11,6 +11,9 @@
extern "C" {
#endif
+#include "BLI_compiler_attrs.h"
+
+struct Main;
struct UserDef;
/**
@@ -21,13 +24,24 @@ void BKE_blender_free(void);
void BKE_blender_globals_init(void);
void BKE_blender_globals_clear(void);
+/** Replace current global Main by the given one, freeing existing one. */
+void BKE_blender_globals_main_replace(struct Main *bmain);
+/**
+ * Replace current global Main by the given one, returning the old one.
+ *
+ * \warning Advanced, risky workaround addressing the issue that current RNA is not able to process
+ * correctly non-G_MAIN data, use with (a lot of) care.
+ */
+struct Main *BKE_blender_globals_main_swap(struct Main *new_gmain);
+
void BKE_blender_userdef_data_swap(struct UserDef *userdef_a, struct UserDef *userdef_b);
void BKE_blender_userdef_data_set(struct UserDef *userdef);
void BKE_blender_userdef_data_set_and_free(struct UserDef *userdef);
/**
- * Write U from userdef.
* This function defines which settings a template will override for the user preferences.
+ *
+ * \note the order of `userdef_a` & `userdef_b` isn't important as values are simply swapped.
*/
void BKE_blender_userdef_app_template_data_swap(struct UserDef *userdef_a,
struct UserDef *userdef_b);
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index ee9c7a964d9..4bffa5492b5 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -17,7 +17,7 @@ extern "C" {
*/
/* Blender major and minor version. */
-#define BLENDER_VERSION 304
+#define BLENDER_VERSION 305
/* Blender patch version for bugfix releases. */
#define BLENDER_VERSION_PATCH 0
/** Blender release cycle stage: alpha/beta/rc/release. */
@@ -30,8 +30,8 @@ extern "C" {
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file
* was written with too new a version. */
-#define BLENDER_FILE_MIN_VERSION 300
-#define BLENDER_FILE_MIN_SUBVERSION 43
+#define BLENDER_FILE_MIN_VERSION 304
+#define BLENDER_FILE_MIN_SUBVERSION 3
/** User readable version string. */
const char *BKE_blender_version_string(void);
diff --git a/source/blender/blenkernel/BKE_bpath.h b/source/blender/blenkernel/BKE_bpath.h
index ea6049e87da..5b1dea0833a 100644
--- a/source/blender/blenkernel/BKE_bpath.h
+++ b/source/blender/blenkernel/BKE_bpath.h
@@ -12,6 +12,8 @@
#pragma once
+#include "BLI_utildefines.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -53,14 +55,18 @@ typedef enum eBPathForeachFlag {
* This is needed for directory manipulation callbacks which might otherwise modify the same
* directory multiple times. */
BKE_BPATH_FOREACH_PATH_SKIP_MULTIFILE = (1 << 8),
- /** Reload data (when the path is edited).
- * \note Only used by Image IDType currently. */
+ /**
+ * Reload data (when the path is edited).
+ * \note Only used by Image #IDType currently.
+ */
BKE_BPATH_FOREACH_PATH_RELOAD_EDITED = (1 << 9),
} eBPathForeachFlag;
+ENUM_OPERATORS(eBPathForeachFlag, BKE_BPATH_FOREACH_PATH_RELOAD_EDITED)
struct BPathForeachPathData;
-/** Callback used to iterate over an ID's file paths.
+/**
+ * Callback used to iterate over an ID's file paths.
*
* \note `path`s parameters should be considered as having a maximal `FILE_MAX` string length.
*
@@ -142,8 +148,9 @@ bool BKE_bpath_foreach_path_allocated_process(struct BPathForeachPathData *bpath
/** Check for missing files. */
void BKE_bpath_missing_files_check(struct Main *bmain, struct ReportList *reports);
-/** Recursively search into given search directory, for all file paths of all IDs in given \a
- * bmain, and replace existing paths as needed.
+/**
+ * Recursively search into given search directory, for all file paths of all IDs in given
+ * \a bmain, and replace existing paths as needed.
*
* \note The search will happen into the whole search directory tree recursively (with a limit of
* MAX_DIR_RECURSE), if several files are found matching a searched filename, the biggest one will
@@ -153,7 +160,7 @@ void BKE_bpath_missing_files_check(struct Main *bmain, struct ReportList *report
* \param searchpath: The root directory in which the new filepaths should be searched for.
* \param find_all: If `true`, also search for files which current path is still valid, if `false`
* skip those still valid paths.
- * */
+ */
void BKE_bpath_missing_files_find(struct Main *bmain,
const char *searchpath,
struct ReportList *reports,
@@ -175,23 +182,28 @@ void BKE_bpath_absolute_convert(struct Main *bmain,
const char *basedir,
struct ReportList *reports);
-/** Temp backup of paths from all IDs in given \a bmain.
+/**
+ * Temp backup of paths from all IDs in given \a bmain.
*
- * \return An opaque handle to pass to #BKE_bpath_list_restore and #BKE_bpath_list_free.
+ * \return An opaque handle to pass to #BKE_bpath_list_restore and #BKE_bpath_list_free.
*/
void *BKE_bpath_list_backup(struct Main *bmain, eBPathForeachFlag flag);
-/** Restore the temp backup of paths from \a path_list_handle into all IDs in given \a bmain.
+/**
+ * Restore the temp backup of paths from \a path_list_handle into all IDs in given \a bmain.
*
* \note This function assumes that the data in given Main did not change (no
* addition/deletion/re-ordering of IDs, or their file paths) since the call to
- * #BKE_bpath_list_backup that generated the given \a path_list_handle. */
+ * #BKE_bpath_list_backup that generated the given \a path_list_handle.
+ */
void BKE_bpath_list_restore(struct Main *bmain, eBPathForeachFlag flag, void *path_list_handle);
-/** Free the temp backup of paths in \a path_list_handle.
+/**
+ * Free the temp backup of paths in \a path_list_handle.
*
* \note This function assumes that the path list has already been restored with a call to
- * #BKE_bpath_list_restore, and is therefore empty. */
+ * #BKE_bpath_list_restore, and is therefore empty.
+ */
void BKE_bpath_list_free(void *path_list_handle);
/** \} */
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index 4d728002c87..a763b3d12c2 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -18,7 +18,9 @@ extern "C" {
struct Brush;
struct ImBuf;
struct ImagePool;
+struct Object;
struct Main;
+struct MTex;
struct Scene;
struct ToolSettings;
struct UnifiedPaintSettings;
@@ -109,6 +111,7 @@ float BKE_brush_curve_strength(const struct Brush *br, float p, float len);
*/
float BKE_brush_sample_tex_3d(const struct Scene *scene,
const struct Brush *br,
+ const struct MTex *mtex,
const float point[3],
float rgba[4],
int thread,
@@ -120,6 +123,24 @@ float BKE_brush_sample_masktex(const struct Scene *scene,
struct ImagePool *pool);
/**
+ * Get the mask texture for this given object mode.
+ *
+ * This is preferred above using mtex/mask_mtex attributes directly as due to legacy these
+ * attributes got switched in sculpt mode.
+ */
+const struct MTex *BKE_brush_mask_texture_get(const struct Brush *brush,
+ const eObjectMode object_mode);
+
+/**
+ * Get the color texture for this given object mode.
+ *
+ * This is preferred above using mtex/mask_mtex attributes directly as due to legacy these
+ * attributes got switched in sculpt mode.
+ */
+const struct MTex *BKE_brush_color_texture_get(const struct Brush *brush,
+ const eObjectMode object_mode);
+
+/**
* Radial control.
*/
struct ImBuf *BKE_brush_gen_radial_control_imbuf(struct Brush *br,
diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h
index d22abd235df..a0a6ac58c58 100644
--- a/source/blender/blenkernel/BKE_bvhutils.h
+++ b/source/blender/blenkernel/BKE_bvhutils.h
@@ -11,6 +11,10 @@
#include "BLI_threads.h"
#ifdef __cplusplus
+# include <mutex>
+#endif
+
+#ifdef __cplusplus
extern "C" {
#endif
@@ -196,6 +200,8 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
BVHCacheType bvh_cache_type,
int tree_type);
+#ifdef __cplusplus
+
/**
* Builds or queries a BVH-cache for the cache BVH-tree of the request type.
*/
@@ -204,7 +210,9 @@ BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
int tree_type,
BVHCacheType bvh_cache_type,
struct BVHCache **bvh_cache_p,
- ThreadMutex *mesh_eval_mutex);
+ std::mutex *mesh_eval_mutex);
+
+#endif
/**
* Frees data allocated by a call to `bvhtree_from_editmesh_*`.
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index f5ffd1190b1..2ef81b754cc 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -218,7 +218,7 @@ int cloth_bvh_collision(struct Depsgraph *depsgraph,
/* -------------------------------------------------------------------- */
/* cloth.c */
-/* Needed for modifier.c */
+/* Needed for modifier.cc */
/** Frees all. */
void cloth_free_modifier_extern(struct ClothModifierData *clmd);
/** Frees all. */
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index 4346c2a3d23..dd7866d83e5 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -216,7 +216,8 @@ struct ListBase BKE_collection_object_cache_get(struct Collection *collection);
ListBase BKE_collection_object_cache_instanced_get(struct Collection *collection);
void BKE_collection_object_cache_free(struct Collection *collection);
-struct Base *BKE_collection_or_layer_objects(const struct ViewLayer *view_layer,
+struct Base *BKE_collection_or_layer_objects(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct Collection *collection);
/* Editing. */
@@ -239,7 +240,8 @@ const char *BKE_collection_ui_name_get(struct Collection *collection);
* Select all the objects in this Collection (and its nested collections) for this ViewLayer.
* Return true if any object was selected.
*/
-bool BKE_collection_objects_select(struct ViewLayer *view_layer,
+bool BKE_collection_objects_select(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct Collection *collection,
bool deselect);
diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h
index b93babaaefa..c390d0a8802 100644
--- a/source/blender/blenkernel/BKE_collision.h
+++ b/source/blender/blenkernel/BKE_collision.h
@@ -17,6 +17,7 @@ struct Depsgraph;
struct MVert;
struct MVertTri;
struct Object;
+struct Scene;
////////////////////////////////////////
// used for collisions in collision.c
@@ -84,7 +85,7 @@ typedef struct FaceCollPair {
/////////////////////////////////////////////////
/////////////////////////////////////////////////
-// used in modifier.c from collision.c
+// used in modifier.cc from collision.c
/////////////////////////////////////////////////
struct BVHTree *bvhtree_build_from_mvert(const struct MVert *mvert,
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 19824cf3a5c..ad3790581da 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -286,7 +286,7 @@ bool CTX_data_dir(const char *member);
CTX_DATA_BEGIN (C, Type, instance, member) \
Type_id instance_id = (Type_id)ctx_link->ptr.owner_id;
-int ctx_data_list_count(const bContext *C, int (*func)(const bContext *, ListBase *));
+int ctx_data_list_count(const bContext *C, bool (*func)(const bContext *, ListBase *));
#define CTX_DATA_COUNT(C, member) ctx_data_list_count(C, CTX_data_##member)
@@ -317,22 +317,22 @@ void CTX_data_main_set(bContext *C, struct Main *bmain);
void CTX_data_scene_set(bContext *C, struct Scene *scene);
/* Only Outliner currently! */
-int CTX_data_selected_ids(const bContext *C, ListBase *list);
+bool CTX_data_selected_ids(const bContext *C, ListBase *list);
-int CTX_data_selected_editable_objects(const bContext *C, ListBase *list);
-int CTX_data_selected_editable_bases(const bContext *C, ListBase *list);
+bool CTX_data_selected_editable_objects(const bContext *C, ListBase *list);
+bool CTX_data_selected_editable_bases(const bContext *C, ListBase *list);
-int CTX_data_editable_objects(const bContext *C, ListBase *list);
-int CTX_data_editable_bases(const bContext *C, ListBase *list);
+bool CTX_data_editable_objects(const bContext *C, ListBase *list);
+bool CTX_data_editable_bases(const bContext *C, ListBase *list);
-int CTX_data_selected_objects(const bContext *C, ListBase *list);
-int CTX_data_selected_bases(const bContext *C, ListBase *list);
+bool CTX_data_selected_objects(const bContext *C, ListBase *list);
+bool CTX_data_selected_bases(const bContext *C, ListBase *list);
-int CTX_data_visible_objects(const bContext *C, ListBase *list);
-int CTX_data_visible_bases(const bContext *C, ListBase *list);
+bool CTX_data_visible_objects(const bContext *C, ListBase *list);
+bool CTX_data_visible_bases(const bContext *C, ListBase *list);
-int CTX_data_selectable_objects(const bContext *C, ListBase *list);
-int CTX_data_selectable_bases(const bContext *C, ListBase *list);
+bool CTX_data_selectable_objects(const bContext *C, ListBase *list);
+bool CTX_data_selectable_bases(const bContext *C, ListBase *list);
struct Object *CTX_data_active_object(const bContext *C);
struct Base *CTX_data_active_base(const bContext *C);
@@ -346,25 +346,25 @@ struct Mask *CTX_data_edit_mask(const bContext *C);
struct CacheFile *CTX_data_edit_cachefile(const bContext *C);
-int CTX_data_selected_nodes(const bContext *C, ListBase *list);
+bool CTX_data_selected_nodes(const bContext *C, ListBase *list);
struct EditBone *CTX_data_active_bone(const bContext *C);
-int CTX_data_selected_bones(const bContext *C, ListBase *list);
-int CTX_data_selected_editable_bones(const bContext *C, ListBase *list);
-int CTX_data_visible_bones(const bContext *C, ListBase *list);
-int CTX_data_editable_bones(const bContext *C, ListBase *list);
+bool CTX_data_selected_bones(const bContext *C, ListBase *list);
+bool CTX_data_selected_editable_bones(const bContext *C, ListBase *list);
+bool CTX_data_visible_bones(const bContext *C, ListBase *list);
+bool CTX_data_editable_bones(const bContext *C, ListBase *list);
struct bPoseChannel *CTX_data_active_pose_bone(const bContext *C);
-int CTX_data_selected_pose_bones(const bContext *C, ListBase *list);
-int CTX_data_selected_pose_bones_from_active_object(const bContext *C, ListBase *list);
-int CTX_data_visible_pose_bones(const bContext *C, ListBase *list);
+bool CTX_data_selected_pose_bones(const bContext *C, ListBase *list);
+bool CTX_data_selected_pose_bones_from_active_object(const bContext *C, ListBase *list);
+bool CTX_data_visible_pose_bones(const bContext *C, ListBase *list);
struct bGPdata *CTX_data_gpencil_data(const bContext *C);
struct bGPDlayer *CTX_data_active_gpencil_layer(const bContext *C);
struct bGPDframe *CTX_data_active_gpencil_frame(const bContext *C);
-int CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list);
-int CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list);
-int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list);
+bool CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list);
+bool CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list);
+bool CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list);
const struct AssetLibraryReference *CTX_wm_asset_library_ref(const bContext *C);
struct AssetHandle CTX_wm_asset_handle(const bContext *C, bool *r_is_valid);
diff --git a/source/blender/blenkernel/BKE_cryptomatte.hh b/source/blender/blenkernel/BKE_cryptomatte.hh
index dd08f7b5c4f..b24968c5c70 100644
--- a/source/blender/blenkernel/BKE_cryptomatte.hh
+++ b/source/blender/blenkernel/BKE_cryptomatte.hh
@@ -79,8 +79,8 @@ struct CryptomatteHash {
{
uint32_t mantissa = hash & ((1 << 23) - 1);
uint32_t exponent = (hash >> 23) & ((1 << 8) - 1);
- exponent = MAX2(exponent, (uint32_t)1);
- exponent = MIN2(exponent, (uint32_t)254);
+ exponent = MAX2(exponent, uint32_t(1));
+ exponent = MIN2(exponent, uint32_t(254));
exponent = exponent << 23;
uint32_t sign = (hash >> 31);
sign = sign << 31;
diff --git a/source/blender/blenkernel/BKE_curves.h b/source/blender/blenkernel/BKE_curves.h
index c3302c6d2aa..71a0562e1df 100644
--- a/source/blender/blenkernel/BKE_curves.h
+++ b/source/blender/blenkernel/BKE_curves.h
@@ -25,7 +25,7 @@ void *BKE_curves_add(struct Main *bmain, const char *name);
struct BoundBox *BKE_curves_boundbox_get(struct Object *ob);
-bool BKE_curves_customdata_required(const struct Curves *curves, const char *name);
+bool BKE_curves_attribute_required(const struct Curves *curves, const char *name);
/* Depsgraph */
diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh
index 4b0fc293b54..a479dcb574d 100644
--- a/source/blender/blenkernel/BKE_curves.hh
+++ b/source/blender/blenkernel/BKE_curves.hh
@@ -11,6 +11,7 @@
#include <mutex>
+#include "BLI_cache_mutex.hh"
#include "BLI_float3x3.hh"
#include "BLI_float4x4.hh"
#include "BLI_generic_virtual_array.hh"
@@ -22,6 +23,7 @@
#include "BLI_virtual_array.hh"
#include "BKE_attribute.hh"
+#include "BKE_attribute_math.hh"
namespace blender::bke {
@@ -79,17 +81,14 @@ class CurvesGeometryRuntime {
*/
mutable Vector<int> evaluated_offsets_cache;
mutable Vector<int> bezier_evaluated_offsets;
- mutable std::mutex offsets_cache_mutex;
- mutable bool offsets_cache_dirty = true;
+ mutable CacheMutex offsets_cache_mutex;
mutable Vector<curves::nurbs::BasisCache> nurbs_basis_cache;
- mutable std::mutex nurbs_basis_cache_mutex;
- mutable bool nurbs_basis_cache_dirty = true;
+ mutable CacheMutex nurbs_basis_cache_mutex;
/** Cache of evaluated positions. */
mutable Vector<float3> evaluated_position_cache;
- mutable std::mutex position_cache_mutex;
- mutable bool position_cache_dirty = true;
+ mutable CacheMutex position_cache_mutex;
/**
* The evaluated positions result, using a separate span in case all curves are poly curves,
* in which case a separate array of evaluated positions is unnecessary.
@@ -102,18 +101,15 @@ class CurvesGeometryRuntime {
* make slicing this array for a curve fast, an extra float is stored for every curve.
*/
mutable Vector<float> evaluated_length_cache;
- mutable std::mutex length_cache_mutex;
- mutable bool length_cache_dirty = true;
+ mutable CacheMutex length_cache_mutex;
/** Direction of the curve at each evaluated point. */
mutable Vector<float3> evaluated_tangent_cache;
- mutable std::mutex tangent_cache_mutex;
- mutable bool tangent_cache_dirty = true;
+ mutable CacheMutex tangent_cache_mutex;
/** Normal direction vectors for each evaluated point. */
mutable Vector<float3> evaluated_normal_cache;
- mutable std::mutex normal_cache_mutex;
- mutable bool normal_cache_dirty = true;
+ mutable CacheMutex normal_cache_mutex;
};
/**
@@ -162,6 +158,11 @@ class CurvesGeometry : public ::CurvesGeometry {
IndexRange curves_range() const;
/**
+ * Number of control points in the indexed curve.
+ */
+ int points_num_for_curve(const int index) const;
+
+ /**
* The index of the first point in every curve. The size of this span is one larger than the
* number of curves. Consider using #points_for_curve rather than using the offsets directly.
*/
@@ -202,6 +203,8 @@ class CurvesGeometry : public ::CurvesGeometry {
IndexMask selection,
Vector<int64_t> &r_indices) const;
+ Array<int> point_to_curve_map() const;
+
Span<float3> positions() const;
MutableSpan<float3> positions_for_write();
@@ -212,7 +215,7 @@ class CurvesGeometry : public ::CurvesGeometry {
/**
* How many evaluated points to create for each segment when evaluating Bezier,
- * Catmull Rom, and NURBS curves. On the curve domain.
+ * Catmull Rom, and NURBS curves. On the curve domain. Values must be one or greater.
*/
VArray<int> resolution() const;
/** Mutable access to curve resolution. Call #tag_topology_changed after changes. */
@@ -532,6 +535,16 @@ bool segment_is_vector(Span<int8_t> handle_types_left,
int segment_index);
/**
+ * True if the Bezier curve contains polygonal segments of HandleType::BEZIER_HANDLE_VECTOR.
+ *
+ * \param num_curve_points: Number of points in the curve.
+ * \param evaluated_size: Number of evaluated points in the curve.
+ * \param cyclic: If curve is cyclic.
+ * \param resolution: Curve resolution.
+ */
+bool has_vector_handles(int num_curve_points, int64_t evaluated_size, bool cyclic, int resolution);
+
+/**
* Return true if the curve's last cyclic segment has a vector type.
* This only makes a difference in the shape of cyclic curves.
*/
@@ -693,6 +706,29 @@ void interpolate_to_evaluated(const GSpan src,
const Span<int> evaluated_offsets,
GMutableSpan dst);
+void calculate_basis(const float parameter, float4 &r_weights);
+
+/**
+ * Interpolate the control point values for the given parameter on the piecewise segment.
+ * \param a: Value associated with the first control point influencing the segment.
+ * \param d: Value associated with the fourth control point.
+ * \param parameter: Parameter in range [0, 1] to compute the interpolation for.
+ */
+template<typename T>
+T interpolate(const T &a, const T &b, const T &c, const T &d, const float parameter)
+{
+ BLI_assert(0.0f <= parameter && parameter <= 1.0f);
+ float4 n;
+ calculate_basis(parameter, n);
+ if constexpr (is_same_any_v<T, float, float2, float3>) {
+ /* Save multiplications by adjusting weights after mix. */
+ return 0.5f * attribute_math::mix4<T>(n, a, b, c, d);
+ }
+ else {
+ return attribute_math::mix4<T>(n * 0.5f, a, b, c, d);
+ }
+}
+
} // namespace catmull_rom
/** \} */
@@ -807,6 +843,16 @@ inline IndexRange CurvesGeometry::curves_range() const
return IndexRange(this->curves_num());
}
+inline int CurvesGeometry::points_num_for_curve(const int index) const
+{
+ BLI_assert(this->curve_num > 0);
+ BLI_assert(this->curve_num > index);
+ BLI_assert(this->curve_offsets != nullptr);
+ const int offset = this->curve_offsets[index];
+ const int offset_next = this->curve_offsets[index + 1];
+ return offset_next - offset;
+}
+
inline bool CurvesGeometry::is_single_type(const CurveType type) const
{
return this->curve_type_counts()[type] == this->curves_num();
@@ -833,6 +879,7 @@ inline IndexRange CurvesGeometry::points_for_curve(const int index) const
{
/* Offsets are not allocated when there are no curves. */
BLI_assert(this->curve_num > 0);
+ BLI_assert(this->curve_num > index);
BLI_assert(this->curve_offsets != nullptr);
const int offset = this->curve_offsets[index];
const int offset_next = this->curve_offsets[index + 1];
@@ -857,13 +904,13 @@ inline int CurvesGeometry::evaluated_points_num() const
inline IndexRange CurvesGeometry::evaluated_points_for_curve(int index) const
{
- BLI_assert(!this->runtime->offsets_cache_dirty);
+ BLI_assert(this->runtime->offsets_cache_mutex.is_cached());
return offsets_to_range(this->runtime->evaluated_offsets_cache.as_span(), index);
}
inline IndexRange CurvesGeometry::evaluated_points_for_curves(const IndexRange curves) const
{
- BLI_assert(!this->runtime->offsets_cache_dirty);
+ BLI_assert(this->runtime->offsets_cache_mutex.is_cached());
BLI_assert(this->curve_num > 0);
const int offset = this->runtime->evaluated_offsets_cache[curves.start()];
const int offset_next = this->runtime->evaluated_offsets_cache[curves.one_after_last()];
@@ -888,7 +935,7 @@ inline IndexRange CurvesGeometry::lengths_range_for_curve(const int curve_index,
inline Span<float> CurvesGeometry::evaluated_lengths_for_curve(const int curve_index,
const bool cyclic) const
{
- BLI_assert(!this->runtime->length_cache_dirty);
+ BLI_assert(this->runtime->length_cache_mutex.is_cached());
const IndexRange range = this->lengths_range_for_curve(curve_index, cyclic);
return this->runtime->evaluated_length_cache.as_span().slice(range);
}
@@ -905,11 +952,13 @@ inline float CurvesGeometry::evaluated_length_total_for_curve(const int curve_in
/** \} */
+namespace curves {
+
/* -------------------------------------------------------------------- */
/** \name Bezier Inline Methods
* \{ */
-namespace curves::bezier {
+namespace bezier {
inline bool point_is_sharp(const Span<int8_t> handle_types_left,
const Span<int8_t> handle_types_right,
@@ -929,14 +978,24 @@ inline bool segment_is_vector(const int8_t left, const int8_t right)
return segment_is_vector(HandleType(left), HandleType(right));
}
+inline bool has_vector_handles(const int num_curve_points,
+ const int64_t evaluated_size,
+ const bool cyclic,
+ const int resolution)
+{
+ return evaluated_size - !cyclic != int64_t(segments_num(num_curve_points, cyclic)) * resolution;
+}
+
inline float3 calculate_vector_handle(const float3 &point, const float3 &next_point)
{
return math::interpolate(point, next_point, 1.0f / 3.0f);
}
+} // namespace bezier
+
/** \} */
-} // namespace curves::bezier
+} // namespace curves
struct CurvesSurfaceTransforms {
float4x4 curves_to_world;
diff --git a/source/blender/blenkernel/BKE_curves_utils.hh b/source/blender/blenkernel/BKE_curves_utils.hh
index 0fbd33002e1..1e06cb2d4c7 100644
--- a/source/blender/blenkernel/BKE_curves_utils.hh
+++ b/source/blender/blenkernel/BKE_curves_utils.hh
@@ -11,9 +11,458 @@
#include "BLI_function_ref.hh"
#include "BLI_generic_pointer.hh"
+#include "BLI_index_range.hh"
namespace blender::bke::curves {
+/* -------------------------------------------------------------------- */
+/** \name Utility Structs
+ * \{ */
+
+/**
+ * Reference to a piecewise segment on a spline curve.
+ */
+struct CurveSegment {
+ /**
+ * Index of the previous control/evaluated point on the curve. First point on the segment.
+ */
+ int index;
+ /**
+ * Index of the next control/evaluated point on the curve. Last point on the curve segment.
+ * Should be 0 for looped segments.
+ */
+ int next_index;
+};
+
+/**
+ * Reference to a point on a piecewise curve (spline).
+ *
+ * Tracks indices of the neighboring control/evaluated point pair associated with the segment
+ * in which the point resides. Referenced point within the segment is defined by a
+ * normalized parameter in the range [0, 1].
+ */
+struct CurvePoint : public CurveSegment {
+ /**
+ * Normalized parameter in the range [0, 1] defining the point on the piecewise segment.
+ * Note that the curve point representation is not unique at segment endpoints.
+ */
+ float parameter;
+
+ /**
+ * True if the parameter is an integer and references a control/evaluated point.
+ */
+ inline bool is_controlpoint() const;
+
+ /*
+ * Compare if the points are equal.
+ */
+ inline bool operator==(const CurvePoint &other) const;
+ inline bool operator!=(const CurvePoint &other) const;
+
+ /**
+ * Compare if 'this' point comes before 'other'. Loop segment for cyclical curves counts
+ * as the first (least) segment.
+ */
+ inline bool operator<(const CurvePoint &other) const;
+};
+
+/**
+ * Cyclical index range. Allows iteration over a plain 'IndexRange' interval on form [start, end)
+ * while also supporting treating the underlying array as a cyclic array where the last index is
+ * followed by the first index in the 'cyclical' range. The cyclical index range can then be
+ * considered a combination of the intervals separated by the last index of the underlying array,
+ * namely [start, range_size) and [0, end) where start/end is the indices iterated between and
+ * range_size is the size of the underlying array. To cycle the underlying array the interval
+ * [0, range_size) can be iterated over an arbitrary amount of times in between.
+ */
+class IndexRangeCyclic {
+ /* Index to the start and end of the iterated range.
+ */
+ int start_ = 0;
+ int end_ = 0;
+ /* Size of the underlying iterable range.
+ */
+ int range_size_ = 0;
+ /* Number of times the range end is passed when the range is iterated.
+ */
+ int cycles_ = 0;
+
+ public:
+ constexpr IndexRangeCyclic() = default;
+ ~IndexRangeCyclic() = default;
+
+ constexpr IndexRangeCyclic(const int start,
+ const int end,
+ const int iterable_range_size,
+ const int cycles)
+ : start_(start), end_(end), range_size_(iterable_range_size), cycles_(cycles)
+ {
+ }
+
+ /**
+ * Create an iterator over the cyclical interval [start_index, end_index).
+ */
+ constexpr IndexRangeCyclic(const int start, const int end, const int iterable_range_size)
+ : start_(start),
+ end_(end == iterable_range_size ? 0 : end),
+ range_size_(iterable_range_size),
+ cycles_(end < start)
+ {
+ }
+
+ /**
+ * Create a cyclical iterator of the specified size.
+ *
+ * \param start_point: Point on the curve that define the starting point of the interval.
+ * \param iterator_size: Number of elements to iterate (size of the iterated cyclical range).
+ * \param iterable_range_size: Size of the underlying range (superset to the cyclical range).
+ */
+ static IndexRangeCyclic get_range_from_size(const int start_index,
+ const int iterator_size,
+ const int iterable_range_size)
+ {
+ BLI_assert(start_index >= 0);
+ BLI_assert(iterator_size >= 0);
+ BLI_assert(iterable_range_size > 0);
+ const int num_until_loop = iterable_range_size - start_index;
+ if (iterator_size < num_until_loop) {
+ return IndexRangeCyclic(start_index, start_index + iterator_size, iterable_range_size, 0);
+ }
+
+ const int num_remaining = iterator_size - num_until_loop;
+ const int num_full_cycles = num_remaining /
+ iterable_range_size; /* Integer division (rounded down). */
+ const int end_index = num_remaining - num_full_cycles * iterable_range_size;
+ return IndexRangeCyclic(start_index, end_index, iterable_range_size, num_full_cycles + 1);
+ }
+
+ /**
+ * Create a cyclical iterator for all control points within the interval [start_point, end_point]
+ * including any control point at the start or end point.
+ *
+ * \param start_point: Point on the curve that define the starting point of the interval.
+ * \param end_point: Point on the curve that define the end point of the interval (included).
+ * \param iterable_range_size: Size of the underlying range (superset to the cyclical range).
+ */
+ static IndexRangeCyclic get_range_between_endpoints(const CurvePoint start_point,
+ const CurvePoint end_point,
+ const int iterable_range_size)
+ {
+ BLI_assert(iterable_range_size > 0);
+ const int start_index = start_point.parameter == 0.0 ? start_point.index :
+ start_point.next_index;
+ int end_index = end_point.parameter == 0.0 ? end_point.index : end_point.next_index;
+ int cycles;
+
+ if (end_point.is_controlpoint()) {
+ BLI_assert(end_index < iterable_range_size);
+ ++end_index;
+ if (end_index == iterable_range_size) {
+ end_index = 0;
+ }
+ /* end_point < start_point but parameter is irrelevant (end_point is controlpoint), and loop
+ * when equal due to increment. */
+ cycles = end_index <= start_index;
+ }
+ else {
+ cycles = end_point < start_point || end_index < start_index;
+ }
+ return IndexRangeCyclic(start_index, end_index, iterable_range_size, cycles);
+ }
+
+ /**
+ * Next index within the iterable range.
+ */
+ template<typename IndexT> constexpr IndexT next_index(const IndexT index, const bool cyclic)
+ {
+ static_assert((is_same_any_v<IndexT, int, int>), "Expected signed integer type.");
+ const IndexT next_index = index + 1;
+ if (next_index == this->size_range()) {
+ return cyclic ? 0 : index;
+ }
+ return next_index;
+ }
+
+ /**
+ * Previous index within the iterable range.
+ */
+ template<typename IndexT> constexpr IndexT previous_index(const IndexT index, const bool cyclic)
+ {
+ static_assert((is_same_any_v<IndexT, int, int64_t>), "Expected signed integer type.");
+ const IndexT prev_index = index - 1;
+ if (prev_index < 0) {
+ return cyclic ? this->size_range() - 1 : 0;
+ }
+ return prev_index;
+ }
+
+ /**
+ * Increment the range by adding `n` loops to the range. This invokes undefined behavior when n
+ * is negative.
+ */
+ constexpr IndexRangeCyclic push_loop(const int n = 1) const
+ {
+ return {this->start_, this->end_, this->range_size_, this->cycles_ + n};
+ }
+
+ /**
+ * Increment the range by adding the given number of indices to the beginning of the iterated
+ * range. This invokes undefined behavior when n is negative.
+ */
+ constexpr IndexRangeCyclic push_front(const int n = 1) const
+ {
+ BLI_assert(n >= 0);
+ int new_start = this->start_ - n;
+ int num_cycles = this->cycles_;
+ if (new_start < 0) {
+ const int new_cycles = n / this->size_range(); /* Integer division (floor) */
+ const int remainder = new_start + this->size_range() * new_cycles;
+ const bool underflow = remainder < 0;
+ new_start = remainder + (underflow ? this->size_range() : 0);
+ num_cycles += new_cycles + int(underflow);
+ }
+ BLI_assert(num_cycles >= 0);
+ BLI_assert(num_cycles > 0 ||
+ (new_start <= this->end_ || (this->end_ == 0 && new_start < this->size_range())));
+ return {new_start, this->end_, this->range_size_, num_cycles};
+ }
+
+ /**
+ * Increment the range by adding the given number of indices to the end of the iterated range.
+ * This invokes undefined behavior when n is negative.
+ */
+ constexpr IndexRangeCyclic push_back(const int n = 1) const
+ {
+ BLI_assert(n >= 0);
+ int new_end = this->end_ + n;
+ int num_cycles = this->cycles_;
+ if (this->size_range() <= new_end) {
+ const int new_cycles = n / this->size_range(); /* Integer division (floor) */
+ const int remainder = new_end - this->size_range() * new_cycles;
+ const bool overflow = remainder >= this->size_range();
+ new_end = remainder - (overflow ? this->size_range() : 0);
+ num_cycles += new_cycles + int(overflow);
+ }
+ BLI_assert(num_cycles >= 0);
+ BLI_assert(num_cycles > 0 || (this->start_ <= new_end || new_end == 0));
+ return {this->start_, new_end, this->range_size_, num_cycles};
+ }
+
+ /**
+ * Returns a new range with n indices removed from the beginning of the range.
+ * This invokes undefined behavior.
+ */
+ constexpr IndexRangeCyclic drop_front(const int n = 1) const
+ {
+ BLI_assert(n >= 0);
+ int new_start = this->start_ + n;
+ int num_cycles = this->cycles_;
+ if (this->size_range() <= new_start) {
+ const int dropped_cycles = n / this->size_range(); /* Integer division (floor) */
+ const int remainder = new_start - this->size_range() * dropped_cycles;
+ const bool overflow = remainder >= this->size_range();
+ new_start = remainder - (overflow ? this->size_range() : 0);
+ num_cycles -= dropped_cycles + int(overflow);
+ }
+ BLI_assert(num_cycles >= 0);
+ BLI_assert(num_cycles > 0 ||
+ (new_start <= this->end_ || (this->end_ == 0 && new_start < this->size_range())));
+ return {new_start, this->end_, this->range_size_, num_cycles};
+ }
+
+ /**
+ * Returns a new range with n indices removed from the end of the range.
+ * This invokes undefined behavior when n is negative or n is larger then the underlying range.
+ */
+ constexpr IndexRangeCyclic drop_back(const int n = 1) const
+ {
+ BLI_assert(n >= 0);
+ int new_end = this->end_ - n;
+ int num_cycles = this->cycles_;
+ if (0 >= new_end) {
+ const int dropped_cycles = n / this->size_range(); /* Integer division (floor) */
+ const int remainder = new_end + this->size_range() * dropped_cycles;
+ const bool underflow = remainder < 0;
+ new_end = remainder + (underflow ? this->size_range() : 0);
+ num_cycles -= dropped_cycles + int(underflow);
+ }
+ BLI_assert(num_cycles >= 0);
+ BLI_assert(num_cycles > 0 || (this->start_ <= new_end || new_end == 0));
+ return {this->start_, new_end, this->range_size_, num_cycles};
+ }
+
+ /**
+ * Get the index range for the curve buffer.
+ */
+ constexpr IndexRange curve_range() const
+ {
+ return IndexRange(0, this->size_range());
+ }
+
+ /**
+ * Range between the first element up to the end of the range.
+ */
+ constexpr IndexRange range_before_loop() const
+ {
+ return IndexRange(this->start_, this->size_before_loop());
+ }
+
+ /**
+ * Range between the first element in the iterable range up to the last element in the range.
+ */
+ constexpr IndexRange range_after_loop() const
+ {
+ return IndexRange(0, this->size_after_loop());
+ }
+
+ /**
+ * Number of elements in the underlying iterable range.
+ */
+ constexpr int size_range() const
+ {
+ return this->range_size_;
+ }
+
+ /**
+ * Number of elements between the first element in the range up to the last element in the curve.
+ */
+ constexpr int size_before_loop() const
+ {
+ return this->range_size_ - this->start_;
+ }
+
+ /**
+ * Number of elements between the first element in the iterable range up to the last element in
+ * the range.
+ */
+ constexpr int size_after_loop() const
+ {
+ return this->end_;
+ }
+
+ /**
+ * Number of elements iterated by the cyclical index range.
+ */
+ constexpr int size() const
+ {
+ if (this->cycles_ > 0) {
+ return this->size_before_loop() + this->end_ + (this->cycles_ - 1) * this->range_size_;
+ }
+ else {
+ return int(this->end_ - this->start_);
+ }
+ }
+
+ /**
+ * Return the number of times the iterator will cycle before ending.
+ */
+ constexpr int cycles() const
+ {
+ return this->cycles_;
+ }
+
+ constexpr int first() const
+ {
+ return this->start_;
+ }
+
+ constexpr int last() const
+ {
+ BLI_assert(this->size() > 0);
+ return int(this->end_ - 1);
+ }
+
+ constexpr int one_after_last() const
+ {
+ return this->end_;
+ }
+
+ constexpr bool operator==(const IndexRangeCyclic &other) const
+ {
+ return this->start_ == other.start_ && this->end_ == other.end_ &&
+ this->cycles_ == other.cycles_ && this->range_size_ == other.range_size_;
+ }
+ constexpr bool operator!=(const IndexRangeCyclic &other) const
+ {
+ return !this->operator==(other);
+ }
+
+ struct CyclicIterator; /* Forward declaration */
+
+ constexpr CyclicIterator begin() const
+ {
+ return CyclicIterator(this->range_size_, this->start_, 0);
+ }
+
+ constexpr CyclicIterator end() const
+ {
+ return CyclicIterator(this->range_size_, this->end_, this->cycles_);
+ }
+
+ struct CyclicIterator {
+ int index_, range_end_, cycles_;
+
+ constexpr CyclicIterator(const int range_end, const int index, const int cycles)
+ : index_(index), range_end_(range_end), cycles_(cycles)
+ {
+ BLI_assert(0 <= index && index <= range_end);
+ }
+
+ constexpr CyclicIterator(const CyclicIterator &copy)
+ : index_(copy.index_), range_end_(copy.range_end_), cycles_(copy.cycles_)
+ {
+ }
+ ~CyclicIterator() = default;
+
+ constexpr CyclicIterator &operator=(const CyclicIterator &copy)
+ {
+ if (this == &copy) {
+ return *this;
+ }
+ this->index_ = copy.index_;
+ this->range_end_ = copy.range_end_;
+ this->cycles_ = copy.cycles_;
+ return *this;
+ }
+ constexpr CyclicIterator &operator++()
+ {
+ this->index_++;
+ if (this->index_ == this->range_end_) {
+ this->index_ = 0;
+ this->cycles_++;
+ }
+ return *this;
+ }
+
+ void increment(const int n)
+ {
+ for (int i = 0; i < n; i++) {
+ ++*this;
+ }
+ }
+
+ constexpr const int &operator*() const
+ {
+ return this->index_;
+ }
+
+ constexpr bool operator==(const CyclicIterator &other) const
+ {
+ return this->index_ == other.index_ && this->cycles_ == other.cycles_;
+ }
+ constexpr bool operator!=(const CyclicIterator &other) const
+ {
+ return !this->operator==(other);
+ }
+ };
+};
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Utility Functions
+ * \{ */
+
/**
* Copy the provided point attribute values between all curves in the #curve_ranges index
* ranges, assuming that all curves have the same number of control points in #src_curves
@@ -34,8 +483,8 @@ void copy_point_data(const CurvesGeometry &src_curves,
template<typename T>
void copy_point_data(const CurvesGeometry &src_curves,
const CurvesGeometry &dst_curves,
- const IndexMask src_curve_selection,
- const Span<T> src,
+ IndexMask src_curve_selection,
+ Span<T> src,
MutableSpan<T> dst)
{
copy_point_data(src_curves, dst_curves, src_curve_selection, GSpan(src), GMutableSpan(dst));
@@ -48,13 +497,27 @@ void fill_points(const CurvesGeometry &curves,
template<typename T>
void fill_points(const CurvesGeometry &curves,
- const IndexMask curve_selection,
+ IndexMask curve_selection,
const T &value,
MutableSpan<T> dst)
{
fill_points(curves, curve_selection, &value, dst);
}
+void fill_points(const CurvesGeometry &curves,
+ Span<IndexRange> curve_ranges,
+ GPointer value,
+ GMutableSpan dst);
+
+template<typename T>
+void fill_points(const CurvesGeometry &curves,
+ Span<IndexRange> curve_ranges,
+ const T &value,
+ MutableSpan<T> dst)
+{
+ fill_points(curves, curve_ranges, &value, dst);
+}
+
/**
* Copy only the information on the point domain, but not the offsets or any point attributes,
* meant for operations that change the number of points but not the number of curves.
@@ -88,4 +551,40 @@ void foreach_curve_by_type(const VArray<int8_t> &types,
FunctionRef<void(IndexMask)> bezier_fn,
FunctionRef<void(IndexMask)> nurbs_fn);
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name #CurvePoint Inline Methods
+ * \{ */
+
+inline bool CurvePoint::is_controlpoint() const
+{
+ return parameter == 0.0 || parameter == 1.0;
+}
+
+inline bool CurvePoint::operator==(const CurvePoint &other) const
+{
+ return (parameter == other.parameter && index == other.index) ||
+ (parameter == 1.0 && other.parameter == 0.0 && next_index == other.index) ||
+ (parameter == 0.0 && other.parameter == 1.0 && index == other.next_index);
+}
+inline bool CurvePoint::operator!=(const CurvePoint &other) const
+{
+ return !this->operator==(other);
+}
+
+inline bool CurvePoint::operator<(const CurvePoint &other) const
+{
+ if (index == other.index) {
+ return parameter < other.parameter;
+ }
+ else {
+ /* Use next index for cyclic comparison due to loop segment < first segment. */
+ return next_index < other.next_index &&
+ !(next_index == other.index && parameter == 1.0 && other.parameter == 0.0);
+ }
+}
+
+/** \} */
+
} // namespace blender::bke::curves
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 24fa5f0e87a..1cdd3c02d8d 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -137,7 +137,7 @@ void CustomData_data_add(int type, void *data1, const void *data2);
/**
* Initializes a CustomData object with the same layer setup as source.
- * mask is a bitfield where `(mask & (1 << (layer type)))` indicates
+ * mask is a bit-field where `(mask & (1 << (layer type)))` indicates
* if a layer should be copied or not. alloctype must be one of the above.
*/
void CustomData_copy(const struct CustomData *source,
@@ -146,15 +146,6 @@ void CustomData_copy(const struct CustomData *source,
eCDAllocType alloctype,
int totelem);
-/**
- * Like #CustomData_copy but skips copying layers that are stored as flags on #BMesh.
- */
-void CustomData_copy_mesh_to_bmesh(const struct CustomData *source,
- struct CustomData *dest,
- eCustomDataMask mask,
- eCDAllocType alloctype,
- int totelem);
-
/* BMESH_TODO, not really a public function but readfile.c needs it */
void CustomData_update_typemap(struct CustomData *data);
@@ -169,15 +160,6 @@ bool CustomData_merge(const struct CustomData *source,
int totelem);
/**
- * Like #CustomData_copy but skips copying layers that are stored as flags on #BMesh.
- */
-bool CustomData_merge_mesh_to_bmesh(const struct CustomData *source,
- struct CustomData *dest,
- eCustomDataMask mask,
- eCDAllocType alloctype,
- int totelem);
-
-/**
* Reallocate custom data to a new element count. If the new size is larger, the new values use
* the #CD_CONSTRUCT behavior, so trivial types must be initialized by the caller. After being
* resized, the #CustomData does not contain any referenced layers.
@@ -197,6 +179,14 @@ bool CustomData_bmesh_merge(const struct CustomData *source,
char htype);
/**
+ * Remove layers that aren't stored in BMesh or are stored as flags on BMesh.
+ * The `layers` array of the returned #CustomData must be freed, but may be null.
+ * Used during conversion of #Mesh data to #BMesh storage format.
+ */
+CustomData CustomData_shallow_copy_remove_non_bmesh_attributes(const CustomData *src,
+ eCustomDataMask mask);
+
+/**
* NULL's all members and resets the #CustomData.typemap.
*/
void CustomData_reset(struct CustomData *data);
@@ -457,12 +447,6 @@ const char *CustomData_get_active_layer_name(const struct CustomData *data, int
*/
const char *CustomData_get_render_layer_name(const struct CustomData *data, int type);
-/**
- * Copies the data from source to the data element at index in the first layer of type
- * no effect if there is no layer of type.
- */
-void CustomData_set(const struct CustomData *data, int index, int type, const void *source);
-
void CustomData_bmesh_set(const struct CustomData *data,
void *block,
int type,
@@ -470,18 +454,6 @@ void CustomData_bmesh_set(const struct CustomData *data,
void CustomData_bmesh_set_n(
struct CustomData *data, void *block, int type, int n, const void *source);
-/**
- * Sets the data of the block at physical layer n.
- * no real type checking is performed.
- */
-void CustomData_bmesh_set_layer_n(struct CustomData *data, void *block, int n, const void *source);
-
-/**
- * Set the pointer of to the first layer of type. the old data is not freed.
- * returns the value of `ptr` if the layer is found, NULL otherwise.
- */
-void *CustomData_set_layer(const struct CustomData *data, int type, void *ptr);
-void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, void *ptr);
/**
* Sets the nth layer of type as active.
@@ -580,7 +552,6 @@ bool CustomData_verify_versions(struct CustomData *data, int index);
/* BMesh specific custom-data stuff. */
-void CustomData_bmesh_update_active_layers(struct CustomData *fdata, struct CustomData *ldata);
void CustomData_bmesh_init_pool(struct CustomData *data, int totelem, char htype);
/**
@@ -590,7 +561,6 @@ void CustomData_bmesh_init_pool(struct CustomData *data, int totelem, char htype
* \return True if some errors were found.
*/
bool CustomData_layer_validate(struct CustomDataLayer *layer, uint totitems, bool do_fixes);
-void CustomData_layers__print(struct CustomData *data);
/* External file storage */
@@ -634,8 +604,7 @@ enum {
CD_SHAPEKEY, /* Not available as real CD layer in non-bmesh context. */
/* Edges. */
- CD_FAKE_SEAM = CD_FAKE | 100, /* UV seam flag for edges. */
- CD_FAKE_CREASE = CD_FAKE | CD_CREASE, /* *sigh*. */
+ CD_FAKE_SEAM = CD_FAKE | 100, /* UV seam flag for edges. */
/* Multiple types of mesh elements... */
CD_FAKE_UV = CD_FAKE |
@@ -740,6 +709,8 @@ void CustomData_blend_write(BlendWriter *writer,
void CustomData_blend_read(struct BlendDataReader *reader, struct CustomData *data, int count);
+size_t CustomData_get_elem_size(struct CustomDataLayer *layer);
+
#ifndef NDEBUG
struct DynStr;
/** Use to inspect mesh data when debugging. */
diff --git a/source/blender/blenkernel/BKE_duplilist.h b/source/blender/blenkernel/BKE_duplilist.h
index 0648cdde529..a0732bf39cf 100644
--- a/source/blender/blenkernel/BKE_duplilist.h
+++ b/source/blender/blenkernel/BKE_duplilist.h
@@ -16,6 +16,9 @@ struct ListBase;
struct Object;
struct ParticleSystem;
struct Scene;
+struct ViewLayer;
+struct ViewerPath;
+struct GeometrySet;
/* ---------------------------------------------------- */
/* Dupli-Geometry */
@@ -26,6 +29,13 @@ struct Scene;
struct ListBase *object_duplilist(struct Depsgraph *depsgraph,
struct Scene *sce,
struct Object *ob);
+/**
+ * \return a #ListBase of #DupliObject for the preview geometry referenced by the #ViewerPath.
+ */
+struct ListBase *object_duplilist_preview(struct Depsgraph *depsgraph,
+ struct Scene *scene,
+ struct Object *ob,
+ const struct ViewerPath *viewer_path);
void free_object_duplilist(struct ListBase *lb);
typedef struct DupliObject {
@@ -39,6 +49,10 @@ typedef struct DupliObject {
short type; /* from Object.transflag */
char no_draw;
+ /* If this dupli object is belongs to a preview, this is non-null. */
+ const struct GeometrySet *preview_base_geometry;
+ /* Index of the top-level instance this dupli is part of or -1 when unused. */
+ int preview_instance_index;
/* Persistent identifier for a dupli object, for inter-frame matching of
* objects with motion blur, or inter-update matching for syncing. */
@@ -47,10 +61,40 @@ typedef struct DupliObject {
/* Particle this dupli was generated from. */
struct ParticleSystem *particle_system;
+ /* Geometry set stack for instance attributes; for each level lists the
+ * geometry set and instance index within it.
+ *
+ * Only non-null entries are stored, ordered from innermost to outermost.
+ * To save memory, these arrays are allocated smaller than persistent_id,
+ * assuming that not every entry will be associated with a GeometrySet; any
+ * size between 1 and MAX_DUPLI_RECUR can be used without issues.
+ */
+ int instance_idx[4];
+ const struct GeometrySet *instance_data[4];
+
/* Random ID for shading */
unsigned int random_id;
} DupliObject;
+/**
+ * Look up the RGBA value of a uniform shader attribute.
+ * \return true if the attribute was found; if not, r_value is also set to zero.
+ */
+bool BKE_object_dupli_find_rgba_attribute(struct Object *ob,
+ struct DupliObject *dupli,
+ struct Object *dupli_parent,
+ const char *name,
+ float r_value[4]);
+
+/**
+ * Look up the RGBA value of a view layer/scene/world shader attribute.
+ * \return true if the attribute was found; if not, r_value is also set to zero.
+ */
+bool BKE_view_layer_find_rgba_attribute(struct Scene *scene,
+ struct ViewLayer *layer,
+ const char *name,
+ float r_value[4]);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_dynamicpaint.h b/source/blender/blenkernel/BKE_dynamicpaint.h
index 109d3e6d977..431bc11b07f 100644
--- a/source/blender/blenkernel/BKE_dynamicpaint.h
+++ b/source/blender/blenkernel/BKE_dynamicpaint.h
@@ -119,7 +119,7 @@ struct DynamicPaintSurface *get_activeSurface(struct DynamicPaintCanvasSettings
int dynamicPaint_createUVSurface(struct Scene *scene,
struct DynamicPaintSurface *surface,
float *progress,
- short *do_update);
+ bool *do_update);
/**
* Calculate a single frame and included sub-frames for surface.
*/
diff --git a/source/blender/blenkernel/BKE_editmesh.h b/source/blender/blenkernel/BKE_editmesh.h
index 5916e7e83fb..dbfc9fd0799 100644
--- a/source/blender/blenkernel/BKE_editmesh.h
+++ b/source/blender/blenkernel/BKE_editmesh.h
@@ -69,7 +69,7 @@ typedef struct BMEditMesh {
} BMEditMesh;
-/* editmesh.c */
+/* editmesh.cc */
void BKE_editmesh_looptri_calc_ex(BMEditMesh *em,
const struct BMeshCalcTessellation_Params *params);
diff --git a/source/blender/blenkernel/BKE_editmesh_cache.h b/source/blender/blenkernel/BKE_editmesh_cache.h
index 2640356ccf6..454a07be4e3 100644
--- a/source/blender/blenkernel/BKE_editmesh_cache.h
+++ b/source/blender/blenkernel/BKE_editmesh_cache.h
@@ -11,15 +11,25 @@ extern "C" {
#endif
struct BMEditMesh;
-struct EditMeshData;
-void BKE_editmesh_cache_ensure_poly_normals(struct BMEditMesh *em, struct EditMeshData *emd);
-void BKE_editmesh_cache_ensure_vert_normals(struct BMEditMesh *em, struct EditMeshData *emd);
+typedef struct EditMeshData {
+ /** when set, \a vertexNos, polyNos are lazy initialized */
+ const float (*vertexCos)[3];
-void BKE_editmesh_cache_ensure_poly_centers(struct BMEditMesh *em, struct EditMeshData *emd);
+ /** lazy initialize (when \a vertexCos is set) */
+ float const (*vertexNos)[3];
+ float const (*polyNos)[3];
+ /** also lazy init but don't depend on \a vertexCos */
+ const float (*polyCos)[3];
+} EditMeshData;
+
+void BKE_editmesh_cache_ensure_poly_normals(struct BMEditMesh *em, EditMeshData *emd);
+void BKE_editmesh_cache_ensure_vert_normals(struct BMEditMesh *em, EditMeshData *emd);
+
+void BKE_editmesh_cache_ensure_poly_centers(struct BMEditMesh *em, EditMeshData *emd);
bool BKE_editmesh_cache_calc_minmax(struct BMEditMesh *em,
- struct EditMeshData *emd,
+ EditMeshData *emd,
float min[3],
float max[3]);
diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h
index 113f9ac3b4c..3226455a183 100644
--- a/source/blender/blenkernel/BKE_effect.h
+++ b/source/blender/blenkernel/BKE_effect.h
@@ -103,6 +103,7 @@ void BKE_partdeflect_free(struct PartDeflect *pd);
* lookup of effectors during evaluation.
*/
struct ListBase *BKE_effector_relations_create(struct Depsgraph *depsgraph,
+ const struct Scene *scene,
struct ViewLayer *view_layer,
struct Collection *collection);
void BKE_effector_relations_free(struct ListBase *lb);
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index c5788c07336..cbdf37e14bd 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -106,7 +106,7 @@ typedef enum eFMI_Action_Types {
/* Flags for the requirements of a FModifier Type */
typedef enum eFMI_Requirement_Flags {
- /* modifier requires original data-points (kindof beats the purpose of a modifier stack?) */
+ /* modifier requires original data-points (kind of beats the purpose of a modifier stack?) */
FMI_REQUIRES_ORIGINAL_DATA = (1 << 0),
/* modifier doesn't require on any preceding data (i.e. it will generate a curve).
* Use in conjunction with FMI_TYPE_GENRATE_CURVE
@@ -431,6 +431,11 @@ bool BKE_fcurve_is_keyframable(struct FCurve *fcu);
bool BKE_fcurve_is_protected(struct FCurve *fcu);
/**
+ * Are any of the keyframe control points selected on the F-Curve?
+ */
+bool BKE_fcurve_has_selected_control_points(const struct FCurve *fcu);
+
+/**
* Checks if the F-Curve has a Cycles modifier with simple settings
* that warrant transition smoothing.
*/
diff --git a/source/blender/blenkernel/BKE_geometry_fields.hh b/source/blender/blenkernel/BKE_geometry_fields.hh
index 62aac5a4120..7b493ea5ca9 100644
--- a/source/blender/blenkernel/BKE_geometry_fields.hh
+++ b/source/blender/blenkernel/BKE_geometry_fields.hh
@@ -75,14 +75,14 @@ class PointCloudFieldContext : public fn::FieldContext {
class InstancesFieldContext : public fn::FieldContext {
private:
- const InstancesComponent &instances_;
+ const Instances &instances_;
public:
- InstancesFieldContext(const InstancesComponent &instances) : instances_(instances)
+ InstancesFieldContext(const Instances &instances) : instances_(instances)
{
}
- const InstancesComponent &instances() const
+ const Instances &instances() const
{
return instances_;
}
@@ -128,13 +128,13 @@ class GeometryFieldContext : public fn::FieldContext {
const Mesh *mesh() const;
const CurvesGeometry *curves() const;
const PointCloud *pointcloud() const;
- const InstancesComponent *instances() const;
+ const Instances *instances() const;
private:
GeometryFieldContext(const Mesh &mesh, eAttrDomain domain);
GeometryFieldContext(const CurvesGeometry &curves, eAttrDomain domain);
GeometryFieldContext(const PointCloud &points);
- GeometryFieldContext(const InstancesComponent &instances);
+ GeometryFieldContext(const Instances &instances);
};
class GeometryFieldInput : public fn::FieldInput {
@@ -145,6 +145,7 @@ class GeometryFieldInput : public fn::FieldInput {
ResourceScope &scope) const override;
virtual GVArray get_varray_for_context(const GeometryFieldContext &context,
IndexMask mask) const = 0;
+ virtual std::optional<eAttrDomain> preferred_domain(const GeometryComponent &component) const;
};
class MeshFieldInput : public fn::FieldInput {
@@ -156,6 +157,7 @@ class MeshFieldInput : public fn::FieldInput {
virtual GVArray get_varray_for_context(const Mesh &mesh,
eAttrDomain domain,
IndexMask mask) const = 0;
+ virtual std::optional<eAttrDomain> preferred_domain(const Mesh &mesh) const;
};
class CurvesFieldInput : public fn::FieldInput {
@@ -167,6 +169,7 @@ class CurvesFieldInput : public fn::FieldInput {
virtual GVArray get_varray_for_context(const CurvesGeometry &curves,
eAttrDomain domain,
IndexMask mask) const = 0;
+ virtual std::optional<eAttrDomain> preferred_domain(const CurvesGeometry &curves) const;
};
class PointCloudFieldInput : public fn::FieldInput {
@@ -184,8 +187,7 @@ class InstancesFieldInput : public fn::FieldInput {
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask mask,
ResourceScope &scope) const override;
- virtual GVArray get_varray_for_context(const InstancesComponent &instances,
- IndexMask mask) const = 0;
+ virtual GVArray get_varray_for_context(const Instances &instances, IndexMask mask) const = 0;
};
class AttributeFieldInput : public GeometryFieldInput {
@@ -218,6 +220,7 @@ class AttributeFieldInput : public GeometryFieldInput {
uint64_t hash() const override;
bool is_equal_to(const fn::FieldNode &other) const override;
+ std::optional<eAttrDomain> preferred_domain(const GeometryComponent &component) const override;
};
class IDAttributeFieldInput : public GeometryFieldInput {
@@ -292,6 +295,7 @@ class AnonymousAttributeFieldInput : public GeometryFieldInput {
uint64_t hash() const override;
bool is_equal_to(const fn::FieldNode &other) const override;
+ std::optional<eAttrDomain> preferred_domain(const GeometryComponent &component) const override;
};
class CurveLengthFieldInput final : public CurvesFieldInput {
@@ -302,6 +306,19 @@ class CurveLengthFieldInput final : public CurvesFieldInput {
IndexMask mask) const final;
uint64_t hash() const override;
bool is_equal_to(const fn::FieldNode &other) const override;
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry &curves) const final;
};
+bool try_capture_field_on_geometry(GeometryComponent &component,
+ const AttributeIDRef &attribute_id,
+ const eAttrDomain domain,
+ const fn::GField &field);
+
+/**
+ * Try to find the geometry domain that the field should be evaluated on. If it is not obvious
+ * which domain is correct, none is returned.
+ */
+std::optional<eAttrDomain> try_detect_field_domain(const GeometryComponent &component,
+ const fn::GField &field);
+
} // namespace blender::bke
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index a5c4d5e1365..b488806c8e7 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -26,7 +26,6 @@
struct Curves;
struct Collection;
struct Curve;
-struct CurveEval;
struct Mesh;
struct Object;
struct PointCloud;
@@ -44,6 +43,7 @@ enum class GeometryOwnershipType {
namespace blender::bke {
class ComponentAttributeProviders;
class CurvesEditHints;
+class Instances;
} // namespace blender::bke
class GeometryComponent;
@@ -247,6 +247,12 @@ struct GeometrySet {
*/
static GeometrySet create_with_curves(
Curves *curves, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
+ /**
+ * Create a new geometry set that only contains the given instances.
+ */
+ static GeometrySet create_with_instances(
+ blender::bke::Instances *instances,
+ GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
/* Utility methods for access. */
/**
@@ -295,6 +301,10 @@ struct GeometrySet {
*/
const Curves *get_curves_for_read() const;
/**
+ * Returns read-only instances or null.
+ */
+ const blender::bke::Instances *get_instances_for_read() const;
+ /**
* Returns read-only curve edit hints or null.
*/
const blender::bke::CurvesEditHints *get_curve_edit_hints_for_read() const;
@@ -316,6 +326,10 @@ struct GeometrySet {
*/
Curves *get_curves_for_write();
/**
+ * Returns mutable instances or null. No ownership is transferred.
+ */
+ blender::bke::Instances *get_instances_for_write();
+ /**
* Returns mutable curve edit hints or null.
*/
blender::bke::CurvesEditHints *get_curve_edit_hints_for_write();
@@ -340,6 +354,11 @@ struct GeometrySet {
*/
void replace_curves(Curves *curves,
GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
+ /**
+ * Clear the existing instances and replace them with the given one.
+ */
+ void replace_instances(blender::bke::Instances *instances,
+ GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
private:
/**
@@ -465,46 +484,7 @@ class PointCloudComponent : public GeometryComponent {
};
/**
- * Legacy runtime-only curves type.
- * These curves are stored differently than other geometry components, because the data structure
- * used here does not correspond exactly to the #Curve DNA data structure. A #CurveEval is stored
- * here instead, though the component does give access to a #Curve for interfacing with render
- * engines and other areas of Blender that expect to use a data-block with an #ID.
- */
-class CurveComponentLegacy : public GeometryComponent {
- private:
- CurveEval *curve_ = nullptr;
- GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned;
-
- public:
- CurveComponentLegacy();
- ~CurveComponentLegacy();
- GeometryComponent *copy() const override;
-
- void clear();
- bool has_curve() const;
- /**
- * Clear the component and replace it with the new curve.
- */
- void replace(CurveEval *curve, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
- CurveEval *release();
-
- const CurveEval *get_for_read() const;
- CurveEval *get_for_write();
-
- bool is_empty() const final;
-
- bool owns_direct_data() const override;
- void ensure_owns_direct_data() override;
-
- std::optional<blender::bke::AttributeAccessor> attributes() const final;
- std::optional<blender::bke::MutableAttributeAccessor> attributes_for_write() final;
-
- static constexpr inline GeometryComponentType static_type = GEO_COMPONENT_TYPE_CURVE;
-};
-
-/**
- * A geometry component that stores a group of curves, corresponding the #Curves data-block type
+ * A geometry component that stores a group of curves, corresponding the #Curves data-block
* and the #CurvesGeometry type. Attributes are stored on the control point domain and the
* curve domain.
*/
@@ -514,10 +494,9 @@ class CurveComponent : public GeometryComponent {
GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned;
/**
- * Curve data necessary to hold the draw cache for rendering, consistent over multiple redraws.
- * This is necessary because Blender assumes that objects evaluate to an object data type, and
- * we use #CurveEval rather than #Curve here. It also allows us to mostly reuse the same
- * batch cache implementation.
+ * Because rendering #Curves isn't fully working yet, we must provide a #Curve for the render
+ * engine and depsgraph object iterator in some cases. This allows using the old curve rendering
+ * even when the new curve data structure is used.
*/
mutable Curve *curve_for_render_ = nullptr;
mutable std::mutex curve_for_render_mutex_;
@@ -556,244 +535,35 @@ class CurveComponent : public GeometryComponent {
};
/**
- * Holds a reference to conceptually unique geometry or a pointer to object/collection data
- * that is instanced with a transform in #InstancesComponent.
- */
-class InstanceReference {
- public:
- enum class Type {
- /**
- * An empty instance. This allows an `InstanceReference` to be default constructed without
- * being in an invalid state. There might also be other use cases that we haven't explored much
- * yet (such as changing the instance later on, and "disabling" some instances).
- */
- None,
- Object,
- Collection,
- GeometrySet,
- };
-
- private:
- Type type_ = Type::None;
- /** Depending on the type this is either null, an Object or Collection pointer. */
- void *data_ = nullptr;
- std::unique_ptr<GeometrySet> geometry_set_;
-
- public:
- InstanceReference() = default;
-
- InstanceReference(Object &object) : type_(Type::Object), data_(&object)
- {
- }
-
- InstanceReference(Collection &collection) : type_(Type::Collection), data_(&collection)
- {
- }
-
- InstanceReference(GeometrySet geometry_set)
- : type_(Type::GeometrySet),
- geometry_set_(std::make_unique<GeometrySet>(std::move(geometry_set)))
- {
- }
-
- InstanceReference(const InstanceReference &other) : type_(other.type_), data_(other.data_)
- {
- if (other.geometry_set_) {
- geometry_set_ = std::make_unique<GeometrySet>(*other.geometry_set_);
- }
- }
-
- InstanceReference(InstanceReference &&other)
- : type_(other.type_), data_(other.data_), geometry_set_(std::move(other.geometry_set_))
- {
- other.type_ = Type::None;
- other.data_ = nullptr;
- }
-
- InstanceReference &operator=(const InstanceReference &other)
- {
- if (this == &other) {
- return *this;
- }
- this->~InstanceReference();
- new (this) InstanceReference(other);
- return *this;
- }
-
- InstanceReference &operator=(InstanceReference &&other)
- {
- if (this == &other) {
- return *this;
- }
- this->~InstanceReference();
- new (this) InstanceReference(std::move(other));
- return *this;
- }
-
- Type type() const
- {
- return type_;
- }
-
- Object &object() const
- {
- BLI_assert(type_ == Type::Object);
- return *(Object *)data_;
- }
-
- Collection &collection() const
- {
- BLI_assert(type_ == Type::Collection);
- return *(Collection *)data_;
- }
-
- const GeometrySet &geometry_set() const
- {
- BLI_assert(type_ == Type::GeometrySet);
- return *geometry_set_;
- }
-
- bool owns_direct_data() const
- {
- if (type_ != Type::GeometrySet) {
- /* The object and collection instances are not direct data. */
- return true;
- }
- return geometry_set_->owns_direct_data();
- }
-
- void ensure_owns_direct_data()
- {
- if (type_ != Type::GeometrySet) {
- return;
- }
- geometry_set_->ensure_owns_direct_data();
- }
-
- uint64_t hash() const
- {
- return blender::get_default_hash_2(data_, geometry_set_.get());
- }
-
- friend bool operator==(const InstanceReference &a, const InstanceReference &b)
- {
- return a.data_ == b.data_ && a.geometry_set_.get() == b.geometry_set_.get();
- }
-};
-
-/**
- * A geometry component that stores instances. The instance data can be any type described by
- * #InstanceReference. Geometry instances can even contain instances themselves, for nested
- * instancing. Each instance has an index into an array of unique instance data, and a transform.
- * The component can also store generic attributes for each instance.
- *
- * The component works differently from other geometry components in that it stores
- * data about instancing directly, rather than owning a pointer to a separate data structure.
- *
- * This component is not responsible for handling the interface to a render engine, or other
- * areas that work with all visible geometry, that is handled by the dependency graph iterator
- * (see `DEG_depsgraph_query.h`).
+ * A geometry component that stores #Instances.
*/
class InstancesComponent : public GeometryComponent {
private:
- /**
- * Indexed set containing information about the data that is instanced.
- * Actual instances store an index ("handle") into this set.
- */
- blender::VectorSet<InstanceReference> references_;
-
- /** Index into `references_`. Determines what data is instanced. */
- blender::Vector<int> instance_reference_handles_;
- /** Transformation of the instances. */
- blender::Vector<blender::float4x4> instance_transforms_;
-
- /* These almost unique ids are generated based on the `id` attribute, which might not contain
- * unique ids at all. They are *almost* unique, because under certain very unlikely
- * circumstances, they are not unique. Code using these ids should not crash when they are not
- * unique but can generally expect them to be unique. */
- mutable std::mutex almost_unique_ids_mutex_;
- mutable blender::Array<int> almost_unique_ids_;
-
- blender::bke::CustomDataAttributes attributes_;
+ blender::bke::Instances *instances_ = nullptr;
+ GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned;
public:
InstancesComponent();
- ~InstancesComponent() = default;
+ ~InstancesComponent();
GeometryComponent *copy() const override;
void clear();
- void reserve(int min_capacity);
- /**
- * Resize the transform, handles, and attributes to the specified capacity.
- *
- * \note This function should be used carefully, only when it's guaranteed
- * that the data will be filled.
- */
- void resize(int capacity);
-
- /**
- * Returns a handle for the given reference.
- * If the reference exists already, the handle of the existing reference is returned.
- * Otherwise a new handle is added.
- */
- int add_reference(const InstanceReference &reference);
- /**
- * Add a reference to the instance reference with an index specified by the #instance_handle
- * argument. For adding many instances, using #resize and accessing the transform array directly
- * is preferred.
- */
- void add_instance(int instance_handle, const blender::float4x4 &transform);
-
- blender::Span<InstanceReference> references() const;
- void remove_unused_references();
-
- /**
- * If references have a collection or object type, convert them into geometry instances
- * recursively. After that, the geometry sets can be edited. There may still be instances of
- * other types of they can't be converted to geometry sets.
- */
- void ensure_geometry_instances();
- /**
- * With write access to the instances component, the data in the instanced geometry sets can be
- * changed. This is a function on the component rather than each reference to ensure `const`
- * correctness for that reason.
- */
- GeometrySet &geometry_set_from_reference(int reference_index);
-
- blender::Span<int> instance_reference_handles() const;
- blender::MutableSpan<int> instance_reference_handles();
- blender::MutableSpan<blender::float4x4> instance_transforms();
- blender::Span<blender::float4x4> instance_transforms() const;
+ const blender::bke::Instances *get_for_read() const;
+ blender::bke::Instances *get_for_write();
- int instances_num() const;
- int references_num() const;
-
- /**
- * Remove the indices that are not contained in the mask input, and remove unused instance
- * references afterwards.
- */
- void remove_instances(const blender::IndexMask mask);
-
- blender::Span<int> almost_unique_ids() const;
-
- blender::bke::CustomDataAttributes &instance_attributes();
- const blender::bke::CustomDataAttributes &instance_attributes() const;
-
- std::optional<blender::bke::AttributeAccessor> attributes() const final;
- std::optional<blender::bke::MutableAttributeAccessor> attributes_for_write() final;
-
- void foreach_referenced_geometry(
- blender::FunctionRef<void(const GeometrySet &geometry_set)> callback) const;
+ void replace(blender::bke::Instances *instances,
+ GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
bool is_empty() const final;
bool owns_direct_data() const override;
void ensure_owns_direct_data() override;
- static constexpr inline GeometryComponentType static_type = GEO_COMPONENT_TYPE_INSTANCES;
+ std::optional<blender::bke::AttributeAccessor> attributes() const final;
+ std::optional<blender::bke::MutableAttributeAccessor> attributes_for_write() final;
- private:
+ static constexpr inline GeometryComponentType static_type = GEO_COMPONENT_TYPE_INSTANCES;
};
/**
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 96b6f7a53b0..f3acb7d3746 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -80,7 +80,7 @@ typedef struct Global {
* * -1: Disable faster motion paths computation (since 08/2018).
* * 1 - 30: EEVEE debug/stats values (01/2018).
* * 31: Enable the Select Debug Engine. Only available with #WITH_DRAW_DEBUG (08/2021).
- * * 101: Enable UI debug drawing of fullscreen area's corner widget (10/2014).
+ * * 101: Enable UI debug drawing of full-screen area's corner widget (10/2014).
* * 102: Enable extra items in string search UI (05/2022).
* * 666: Use quicker batch delete for outliners' delete hierarchy (01/2019).
* * 777: Enable UI node panel's sockets polling (11/2011).
@@ -189,15 +189,16 @@ enum {
* assigned to ID datablocks */
G_DEBUG_DEPSGRAPH = (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_EVAL | G_DEBUG_DEPSGRAPH_TAG |
G_DEBUG_DEPSGRAPH_TIME | G_DEBUG_DEPSGRAPH_UUID),
- G_DEBUG_SIMDATA = (1 << 15), /* sim debug data display */
- G_DEBUG_GPU = (1 << 16), /* gpu debug */
- G_DEBUG_IO = (1 << 17), /* IO Debugging (for Collada, ...). */
- G_DEBUG_GPU_FORCE_WORKAROUNDS = (1 << 18), /* force gpu workarounds bypassing detections. */
- G_DEBUG_XR = (1 << 19), /* XR/OpenXR messages */
- G_DEBUG_XR_TIME = (1 << 20), /* XR/OpenXR timing messages */
-
- G_DEBUG_GHOST = (1 << 21), /* Debug GHOST module. */
- G_DEBUG_WINTAB = (1 << 22), /* Debug Wintab. */
+ G_DEBUG_SIMDATA = (1 << 15), /* sim debug data display */
+ G_DEBUG_GPU = (1 << 16), /* gpu debug */
+ G_DEBUG_IO = (1 << 17), /* IO Debugging (for Collada, ...). */
+ G_DEBUG_GPU_FORCE_WORKAROUNDS = (1 << 18), /* force gpu workarounds bypassing detections. */
+ G_DEBUG_GPU_FORCE_DISABLE_SSBO = (1 << 19), /* force disabling usage of SSBO's */
+ G_DEBUG_XR = (1 << 20), /* XR/OpenXR messages */
+ G_DEBUG_XR_TIME = (1 << 21), /* XR/OpenXR timing messages */
+
+ G_DEBUG_GHOST = (1 << 22), /* Debug GHOST module. */
+ G_DEBUG_WINTAB = (1 << 23), /* Debug Wintab. */
};
#define G_DEBUG_ALL \
diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h
index b9219814c08..976961f27ae 100644
--- a/source/blender/blenkernel/BKE_gpencil_geom.h
+++ b/source/blender/blenkernel/BKE_gpencil_geom.h
@@ -332,8 +332,12 @@ bool BKE_gpencil_stroke_stretch(struct bGPDstroke *gps,
* \param gps: Target stroke.
* \param index_from: the index of the first point to be used in the trimmed result.
* \param index_to: the index of the last point to be used in the trimmed result.
+ * \param keep_point: Keep strokes with one point. False remove the single points strokes
*/
-bool BKE_gpencil_stroke_trim_points(struct bGPDstroke *gps, int index_from, int index_to);
+bool BKE_gpencil_stroke_trim_points(struct bGPDstroke *gps,
+ int index_from,
+ int index_to,
+ const bool keep_point);
/**
* Split the given stroke into several new strokes, partitioning
* it based on whether the stroke points have a particular flag
diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h
index 8d9351806c4..10d17c7f4c8 100644
--- a/source/blender/blenkernel/BKE_icons.h
+++ b/source/blender/blenkernel/BKE_icons.h
@@ -20,6 +20,8 @@ extern "C" {
#include "BLI_compiler_attrs.h"
+#include "DNA_ID_enums.h"
+
typedef void (*DrawInfoFreeFP)(void *drawinfo);
enum {
@@ -77,8 +79,6 @@ struct PreviewImage;
struct StudioLight;
struct bGPDlayer;
-enum eIconSizes;
-
void BKE_icons_init(int first_dyn_id);
/**
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index e9b075aeb49..9ac4b4e4619 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -328,7 +328,7 @@ typedef enum eIDPropertyUIDataType {
IDP_UI_DATA_TYPE_UNSUPPORTED = -1,
/** IDP_INT or IDP_ARRAY with subtype IDP_INT. */
IDP_UI_DATA_TYPE_INT = 0,
- /** IDP_FLOAT and IDP_DOUBLE or IDP_ARRAY properties with a float or double subtypes. */
+ /** IDP_FLOAT and IDP_DOUBLE or IDP_ARRAY properties with a float or double sub-types. */
IDP_UI_DATA_TYPE_FLOAT = 1,
/** IDP_STRING properties. */
IDP_UI_DATA_TYPE_STRING = 2,
diff --git a/source/blender/blenkernel/BKE_idprop.hh b/source/blender/blenkernel/BKE_idprop.hh
index 6a42ab1669f..ce11a56ad5f 100644
--- a/source/blender/blenkernel/BKE_idprop.hh
+++ b/source/blender/blenkernel/BKE_idprop.hh
@@ -46,10 +46,10 @@ std::unique_ptr<IDProperty, IDPropertyDeleter> create(StringRefNull prop_name,
const StringRefNull value);
/** \brief Allocate a new IDProperty of type IDP_ID, set its name and value. */
-std::unique_ptr<IDProperty, IDPropertyDeleter> create(StringRefNull prop_name, ID *id);
+std::unique_ptr<IDProperty, IDPropertyDeleter> create(StringRefNull prop_name, ID *value);
/**
- * \brief Allocate a new IDProperty of type IDP_ARRAY and subtype IDP_INT.
+ * \brief Allocate a new IDProperty of type IDP_ARRAY and sub-type IDP_INT.
*
* \param values: The values will be copied into the IDProperty.
*/
@@ -57,14 +57,14 @@ std::unique_ptr<IDProperty, IDPropertyDeleter> create(StringRefNull prop_name,
Span<int32_t> values);
/**
- * \brief Allocate a new IDProperty of type IDP_ARRAY and subtype IDP_FLOAT.
+ * \brief Allocate a new IDProperty of type IDP_ARRAY and sub-type IDP_FLOAT.
*
* \param values: The values will be copied into the IDProperty.
*/
std::unique_ptr<IDProperty, IDPropertyDeleter> create(StringRefNull prop_name, Span<float> values);
/**
- * \brief Allocate a new IDProperty of type IDP_ARRAY and subtype IDP_DOUBLE.
+ * \brief Allocate a new IDProperty of type IDP_ARRAY and sub-type IDP_DOUBLE.
*
* \param values: The values will be copied into the IDProperty.
*/
diff --git a/source/blender/blenkernel/BKE_image_format.h b/source/blender/blenkernel/BKE_image_format.h
index 8f71e1f4648..e3254c59ca4 100644
--- a/source/blender/blenkernel/BKE_image_format.h
+++ b/source/blender/blenkernel/BKE_image_format.h
@@ -52,7 +52,7 @@ int BKE_image_path_ensure_ext_from_imtype(char *string, char imtype);
#define IMA_CHAN_FLAG_BW 1
#define IMA_CHAN_FLAG_RGB 2
-#define IMA_CHAN_FLAG_ALPHA 4
+#define IMA_CHAN_FLAG_RGBA 4
char BKE_ftype_to_imtype(int ftype, const struct ImbFormatOptions *options);
int BKE_imtype_to_ftype(char imtype, struct ImbFormatOptions *r_options);
diff --git a/source/blender/blenkernel/BKE_image_partial_update.hh b/source/blender/blenkernel/BKE_image_partial_update.hh
index 6611efe7a61..b9b748880bb 100644
--- a/source/blender/blenkernel/BKE_image_partial_update.hh
+++ b/source/blender/blenkernel/BKE_image_partial_update.hh
@@ -122,11 +122,11 @@ class AbstractTileData {
*/
class NoTileData : AbstractTileData {
public:
- NoTileData(Image *UNUSED(image), ImageUser *UNUSED(image_user))
+ NoTileData(Image * /*image*/, ImageUser * /*image_user*/)
{
}
- void init_data(TileNumber UNUSED(new_tile_number)) override
+ void init_data(TileNumber /*new_tile_number*/) override
{
}
diff --git a/source/blender/blenkernel/BKE_instances.hh b/source/blender/blenkernel/BKE_instances.hh
new file mode 100644
index 00000000000..f17ebba0dfa
--- /dev/null
+++ b/source/blender/blenkernel/BKE_instances.hh
@@ -0,0 +1,270 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+/** \file
+ * \ingroup bke
+ *
+ * #Instances is a container for geometry instances. It fulfills some key requirements:
+ * - Support nested instances.
+ * - Support instance attributes.
+ * - Support referencing different kinds of instances (objects, collections, geometry sets).
+ * - Support efficiently iterating over the instanced geometries, i.e. without have to iterate over
+ * all instances.
+ *
+ * #Instances has an ordered set of #InstanceReference. An #InstanceReference contains information
+ * about a particular instanced geometry. Each #InstanceReference has a handle (integer index)
+ * which is then stored per instance. Many instances can use the same #InstanceReference.
+ */
+
+#include <mutex>
+
+#include "BLI_float4x4.hh"
+#include "BLI_vector.hh"
+#include "BLI_vector_set.hh"
+
+#include "BKE_attribute.hh"
+
+struct GeometrySet;
+struct Object;
+struct Collection;
+
+namespace blender::bke {
+
+/**
+ * Holds a reference to conceptually unique geometry or a pointer to object/collection data
+ * that is instanced with a transform in #Instances.
+ */
+class InstanceReference {
+ public:
+ enum class Type {
+ /**
+ * An empty instance. This allows an `InstanceReference` to be default constructed without
+ * being in an invalid state. There might also be other use cases that we haven't explored
+ * much yet (such as changing the instance later on, and "disabling" some instances).
+ */
+ None,
+ Object,
+ Collection,
+ GeometrySet,
+ };
+
+ private:
+ Type type_ = Type::None;
+ /** Depending on the type this is either null, an Object or Collection pointer. */
+ void *data_ = nullptr;
+ std::unique_ptr<GeometrySet> geometry_set_;
+
+ public:
+ InstanceReference() = default;
+ InstanceReference(Object &object);
+ InstanceReference(Collection &collection);
+ InstanceReference(GeometrySet geometry_set);
+
+ InstanceReference(const InstanceReference &other);
+ InstanceReference(InstanceReference &&other);
+
+ InstanceReference &operator=(const InstanceReference &other);
+ InstanceReference &operator=(InstanceReference &&other);
+
+ Type type() const;
+ Object &object() const;
+ Collection &collection() const;
+ const GeometrySet &geometry_set() const;
+
+ bool owns_direct_data() const;
+ void ensure_owns_direct_data();
+
+ uint64_t hash() const;
+ friend bool operator==(const InstanceReference &a, const InstanceReference &b);
+};
+
+class Instances {
+ private:
+ /**
+ * Indexed set containing information about the data that is instanced.
+ * Actual instances store an index ("handle") into this set.
+ */
+ blender::VectorSet<InstanceReference> references_;
+
+ /** Indices into `references_`. Determines what data is instanced. */
+ blender::Vector<int> reference_handles_;
+ /** Transformation of the instances. */
+ blender::Vector<blender::float4x4> transforms_;
+
+ /* These almost unique ids are generated based on the `id` attribute, which might not contain
+ * unique ids at all. They are *almost* unique, because under certain very unlikely
+ * circumstances, they are not unique. Code using these ids should not crash when they are not
+ * unique but can generally expect them to be unique. */
+ mutable std::mutex almost_unique_ids_mutex_;
+ mutable blender::Array<int> almost_unique_ids_;
+
+ CustomDataAttributes attributes_;
+
+ public:
+ Instances() = default;
+ Instances(const Instances &other);
+
+ void reserve(int min_capacity);
+ /**
+ * Resize the transform, handles, and attributes to the specified capacity.
+ *
+ * \note This function should be used carefully, only when it's guaranteed
+ * that the data will be filled.
+ */
+ void resize(int capacity);
+
+ /**
+ * Returns a handle for the given reference.
+ * If the reference exists already, the handle of the existing reference is returned.
+ * Otherwise a new handle is added.
+ */
+ int add_reference(const InstanceReference &reference);
+ /**
+ * Add a reference to the instance reference with an index specified by the #instance_handle
+ * argument. For adding many instances, using #resize and accessing the transform array
+ * directly is preferred.
+ */
+ void add_instance(int instance_handle, const blender::float4x4 &transform);
+
+ blender::Span<InstanceReference> references() const;
+ void remove_unused_references();
+
+ /**
+ * If references have a collection or object type, convert them into geometry instances
+ * recursively. After that, the geometry sets can be edited. There may still be instances of
+ * other types of they can't be converted to geometry sets.
+ */
+ void ensure_geometry_instances();
+ /**
+ * With write access to the instances component, the data in the instanced geometry sets can be
+ * changed. This is a function on the component rather than each reference to ensure `const`
+ * correctness for that reason.
+ */
+ GeometrySet &geometry_set_from_reference(int reference_index);
+
+ blender::Span<int> reference_handles() const;
+ blender::MutableSpan<int> reference_handles();
+ blender::MutableSpan<blender::float4x4> transforms();
+ blender::Span<blender::float4x4> transforms() const;
+
+ int instances_num() const;
+ int references_num() const;
+
+ /**
+ * Remove the indices that are not contained in the mask input, and remove unused instance
+ * references afterwards.
+ */
+ void remove(const blender::IndexMask mask);
+ /**
+ * Get an id for every instance. These can be used for e.g. motion blur.
+ */
+ blender::Span<int> almost_unique_ids() const;
+
+ blender::bke::AttributeAccessor attributes() const;
+ blender::bke::MutableAttributeAccessor attributes_for_write();
+
+ CustomDataAttributes &custom_data_attributes();
+ const CustomDataAttributes &custom_data_attributes() const;
+
+ void foreach_referenced_geometry(
+ blender::FunctionRef<void(const GeometrySet &geometry_set)> callback) const;
+
+ bool owns_direct_data() const;
+ void ensure_owns_direct_data();
+};
+
+/* -------------------------------------------------------------------- */
+/** \name #InstanceReference Inline Methods
+ * \{ */
+
+inline InstanceReference::InstanceReference(Object &object) : type_(Type::Object), data_(&object)
+{
+}
+
+inline InstanceReference::InstanceReference(Collection &collection)
+ : type_(Type::Collection), data_(&collection)
+{
+}
+
+inline InstanceReference::InstanceReference(const InstanceReference &other)
+ : type_(other.type_), data_(other.data_)
+{
+ if (other.geometry_set_) {
+ geometry_set_ = std::make_unique<GeometrySet>(*other.geometry_set_);
+ }
+}
+
+inline InstanceReference::InstanceReference(InstanceReference &&other)
+ : type_(other.type_), data_(other.data_), geometry_set_(std::move(other.geometry_set_))
+{
+ other.type_ = Type::None;
+ other.data_ = nullptr;
+}
+
+inline InstanceReference &InstanceReference::operator=(const InstanceReference &other)
+{
+ if (this == &other) {
+ return *this;
+ }
+ this->~InstanceReference();
+ new (this) InstanceReference(other);
+ return *this;
+}
+
+inline InstanceReference &InstanceReference::operator=(InstanceReference &&other)
+{
+ if (this == &other) {
+ return *this;
+ }
+ this->~InstanceReference();
+ new (this) InstanceReference(std::move(other));
+ return *this;
+}
+
+inline InstanceReference::Type InstanceReference::type() const
+{
+ return type_;
+}
+
+inline Object &InstanceReference::object() const
+{
+ BLI_assert(type_ == Type::Object);
+ return *(Object *)data_;
+}
+
+inline Collection &InstanceReference::collection() const
+{
+ BLI_assert(type_ == Type::Collection);
+ return *(Collection *)data_;
+}
+
+inline const GeometrySet &InstanceReference::geometry_set() const
+{
+ BLI_assert(type_ == Type::GeometrySet);
+ return *geometry_set_;
+}
+
+inline CustomDataAttributes &Instances::custom_data_attributes()
+{
+ return attributes_;
+}
+
+inline const CustomDataAttributes &Instances::custom_data_attributes() const
+{
+ return attributes_;
+}
+
+inline uint64_t InstanceReference::hash() const
+{
+ return blender::get_default_hash_2(data_, geometry_set_.get());
+}
+
+inline bool operator==(const InstanceReference &a, const InstanceReference &b)
+{
+ return a.data_ == b.data_ && a.geometry_set_.get() == b.geometry_set_.get();
+}
+
+/** \} */
+
+} // namespace blender::bke
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index 45a72e8d7a3..6cae56b775f 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -22,7 +22,7 @@ extern "C" {
#endif
/**
- * Free (or release) any data used by this shapekey (does not free the key itself).
+ * Free (or release) any data used by this shape-key (does not free the key itself).
*/
void BKE_key_free_data(struct Key *key);
void BKE_key_free_nolib(struct Key *key);
@@ -167,9 +167,9 @@ void BKE_keyblock_update_from_offset(const struct Object *ob,
* Move shape key from org_index to new_index. Safe, clamps index to valid range,
* updates reference keys, the object's active shape index,
* the 'frame' value in case of absolute keys, etc.
- * Note indices are expected in real values (not 'fake' shapenr +1 ones).
+ * Note indices are expected in real values (not *fake* `shapenr +1` ones).
*
- * \param org_index: if < 0, current object's active shape will be used as skey to move.
+ * \param org_index: if < 0, current object's active shape will be used as shape-key to move.
* \return true if something was done, else false.
*/
bool BKE_keyblock_move(struct Object *ob, int org_index, int new_index);
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 8bc89c56450..88a340b11a7 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -78,7 +78,9 @@ void BKE_view_layer_free_ex(struct ViewLayer *view_layer, bool do_id_user);
/**
* Tag all the selected objects of a render-layer.
*/
-void BKE_view_layer_selected_objects_tag(struct ViewLayer *view_layer, int tag);
+void BKE_view_layer_selected_objects_tag(const struct Scene *scene,
+ struct ViewLayer *view_layer,
+ int tag);
/**
* Fallback for when a Scene has no camera to use.
@@ -87,14 +89,14 @@ void BKE_view_layer_selected_objects_tag(struct ViewLayer *view_layer, int tag);
* If rendering you pass the scene active layer, when viewing in the viewport
* you want to get #ViewLayer from context.
*/
-struct Object *BKE_view_layer_camera_find(struct ViewLayer *view_layer);
+struct Object *BKE_view_layer_camera_find(const struct Scene *scene, struct ViewLayer *view_layer);
/**
* Find the #ViewLayer a #LayerCollection belongs to.
*/
struct ViewLayer *BKE_view_layer_find_from_collection(const struct Scene *scene,
struct LayerCollection *lc);
struct Base *BKE_view_layer_base_find(struct ViewLayer *view_layer, struct Object *ob);
-void BKE_view_layer_base_deselect_all(struct ViewLayer *view_layer);
+void BKE_view_layer_base_deselect_all(const struct Scene *scene, struct ViewLayer *view_layer);
void BKE_view_layer_base_select_and_set_active(struct ViewLayer *view_layer, struct Base *selbase);
@@ -161,7 +163,9 @@ void BKE_scene_collection_sync(const struct Scene *scene);
* and on file loaded in case linked data changed or went missing.
*/
void BKE_layer_collection_sync(const struct Scene *scene, struct ViewLayer *view_layer);
-void BKE_layer_collection_local_sync(struct ViewLayer *view_layer, const struct View3D *v3d);
+void BKE_layer_collection_local_sync(const struct Scene *scene,
+ struct ViewLayer *view_layer,
+ const struct View3D *v3d);
/**
* Sync the local collection for all the 3D Viewports.
*/
@@ -192,10 +196,12 @@ bool BKE_scene_has_object(struct Scene *scene, struct Object *ob);
* It also select the objects that are in nested collections.
* \note Recursive.
*/
-bool BKE_layer_collection_objects_select(struct ViewLayer *view_layer,
+bool BKE_layer_collection_objects_select(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct LayerCollection *lc,
bool deselect);
-bool BKE_layer_collection_has_selected_objects(struct ViewLayer *view_layer,
+bool BKE_layer_collection_has_selected_objects(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct LayerCollection *lc);
bool BKE_layer_collection_has_layer_collection(struct LayerCollection *lc_parent,
struct LayerCollection *lc_child);
@@ -226,7 +232,8 @@ void BKE_layer_collection_isolate_global(struct Scene *scene,
*
* Same as #BKE_layer_collection_isolate_local but for a viewport
*/
-void BKE_layer_collection_isolate_local(struct ViewLayer *view_layer,
+void BKE_layer_collection_isolate_local(const struct Scene *scene,
+ struct ViewLayer *view_layer,
const struct View3D *v3d,
struct LayerCollection *lc,
bool extend);
@@ -235,7 +242,8 @@ void BKE_layer_collection_isolate_local(struct ViewLayer *view_layer,
* Don't change the collection children enable/disable state,
* but it may change it for the collection itself.
*/
-void BKE_layer_collection_set_visible(struct ViewLayer *view_layer,
+void BKE_layer_collection_set_visible(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct LayerCollection *lc,
bool visible,
bool hierarchy);
@@ -256,7 +264,9 @@ void BKE_layer_eval_view_layer_indexed(struct Depsgraph *depsgraph,
/* .blend file I/O */
-void BKE_view_layer_blend_write(struct BlendWriter *writer, struct ViewLayer *view_layer);
+void BKE_view_layer_blend_write(struct BlendWriter *writer,
+ const struct Scene *scene,
+ struct ViewLayer *view_layer);
void BKE_view_layer_blend_read_data(struct BlendDataReader *reader, struct ViewLayer *view_layer);
void BKE_view_layer_blend_read_lib(struct BlendLibReader *reader,
struct Library *lib,
@@ -352,7 +362,8 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter);
} \
((void)0)
-#define FOREACH_BASE_IN_MODE_BEGIN(_view_layer, _v3d, _object_type, _object_mode, _instance) \
+#define FOREACH_BASE_IN_MODE_BEGIN( \
+ _scene, _view_layer, _v3d, _object_type, _object_mode, _instance) \
{ \
struct ObjectsInModeIteratorData data_; \
memset(&data_, 0, sizeof(data_)); \
@@ -360,7 +371,8 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter);
data_.object_type = _object_type; \
data_.view_layer = _view_layer; \
data_.v3d = _v3d; \
- data_.base_active = _view_layer->basact; \
+ BKE_view_layer_synced_ensure(_scene, _view_layer); \
+ data_.base_active = BKE_view_layer_active_base_get(_view_layer); \
ITER_BEGIN (BKE_view_layer_bases_in_mode_iterator_begin, \
BKE_view_layer_bases_in_mode_iterator_next, \
BKE_view_layer_bases_in_mode_iterator_end, \
@@ -373,21 +385,22 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter);
} \
((void)0)
-#define FOREACH_BASE_IN_EDIT_MODE_BEGIN(_view_layer, _v3d, _instance) \
- FOREACH_BASE_IN_MODE_BEGIN (_view_layer, _v3d, -1, OB_MODE_EDIT, _instance)
+#define FOREACH_BASE_IN_EDIT_MODE_BEGIN(_scene, _view_layer, _v3d, _instance) \
+ FOREACH_BASE_IN_MODE_BEGIN (_scene, _view_layer, _v3d, -1, OB_MODE_EDIT, _instance)
#define FOREACH_BASE_IN_EDIT_MODE_END FOREACH_BASE_IN_MODE_END
-#define FOREACH_OBJECT_IN_MODE_BEGIN(_view_layer, _v3d, _object_type, _object_mode, _instance) \
- FOREACH_BASE_IN_MODE_BEGIN (_view_layer, _v3d, _object_type, _object_mode, _base) { \
+#define FOREACH_OBJECT_IN_MODE_BEGIN( \
+ _scene, _view_layer, _v3d, _object_type, _object_mode, _instance) \
+ FOREACH_BASE_IN_MODE_BEGIN (_scene, _view_layer, _v3d, _object_type, _object_mode, _base) { \
Object *_instance = _base->object;
#define FOREACH_OBJECT_IN_MODE_END \
} \
FOREACH_BASE_IN_MODE_END
-#define FOREACH_OBJECT_IN_EDIT_MODE_BEGIN(_view_layer, _v3d, _instance) \
- FOREACH_BASE_IN_EDIT_MODE_BEGIN (_view_layer, _v3d, _base) { \
+#define FOREACH_OBJECT_IN_EDIT_MODE_BEGIN(_scene, _view_layer, _v3d, _instance) \
+ FOREACH_BASE_IN_EDIT_MODE_BEGIN (_scene, _view_layer, _v3d, _base) { \
Object *_instance = _base->object;
#define FOREACH_OBJECT_IN_EDIT_MODE_END \
@@ -404,11 +417,12 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter);
#define FOREACH_SELECTED_BASE_END ITER_END
-#define FOREACH_VISIBLE_BASE_BEGIN(_view_layer, _v3d, _instance) \
+#define FOREACH_VISIBLE_BASE_BEGIN(_scene, _view_layer, _v3d, _instance) \
{ \
struct ObjectsVisibleIteratorData data_ = {NULL}; \
data_.view_layer = _view_layer; \
data_.v3d = _v3d; \
+ BKE_view_layer_synced_ensure(_scene, _view_layer); \
ITER_BEGIN (BKE_view_layer_visible_bases_iterator_begin, \
BKE_view_layer_visible_bases_iterator_next, \
BKE_view_layer_visible_bases_iterator_end, \
@@ -421,11 +435,13 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter);
} \
((void)0)
-#define FOREACH_OBJECT_BEGIN(view_layer, _instance) \
+#define FOREACH_OBJECT_BEGIN(scene, view_layer, _instance) \
{ \
Object *_instance; \
Base *_base; \
- for (_base = (Base *)(view_layer)->object_bases.first; _base; _base = _base->next) { \
+ BKE_view_layer_synced_ensure(scene, view_layer); \
+ for (_base = (Base *)BKE_view_layer_object_bases_get(view_layer)->first; _base; \
+ _base = _base->next) { \
_instance = _base->object;
#define FOREACH_OBJECT_END \
@@ -494,7 +510,8 @@ struct Object **BKE_view_layer_array_selected_objects_params(
* Returns NULL with it finds multiple other selected objects
* as behavior in this case would be random from the user perspective.
*/
-struct Object *BKE_view_layer_non_active_selected_object(struct ViewLayer *view_layer,
+struct Object *BKE_view_layer_non_active_selected_object(const struct Scene *scene,
+ struct ViewLayer *view_layer,
const struct View3D *v3d);
#define BKE_view_layer_array_selected_objects(view_layer, v3d, r_len, ...) \
@@ -510,12 +527,14 @@ struct ObjectsInModeParams {
};
struct Base **BKE_view_layer_array_from_bases_in_mode_params(
+ const struct Scene *scene,
struct ViewLayer *view_layer,
const struct View3D *v3d,
uint *r_len,
const struct ObjectsInModeParams *params);
struct Object **BKE_view_layer_array_from_objects_in_mode_params(
+ const struct Scene *scene,
struct ViewLayer *view_layer,
const struct View3D *v3d,
uint *len,
@@ -526,26 +545,49 @@ bool BKE_view_layer_filter_edit_mesh_has_edges(const struct Object *ob, void *us
/* Utility functions that wrap common arguments (add more as needed). */
-struct Object **BKE_view_layer_array_from_objects_in_edit_mode(struct ViewLayer *view_layer,
+struct Object **BKE_view_layer_array_from_objects_in_edit_mode(const struct Scene *scene,
+ struct ViewLayer *view_layer,
const struct View3D *v3d,
uint *r_len);
-struct Base **BKE_view_layer_array_from_bases_in_edit_mode(struct ViewLayer *view_layer,
+struct Base **BKE_view_layer_array_from_bases_in_edit_mode(const struct Scene *scene,
+ struct ViewLayer *view_layer,
const struct View3D *v3d,
uint *r_len);
struct Object **BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- struct ViewLayer *view_layer, const struct View3D *v3d, uint *r_len);
+ const struct Scene *scene,
+ struct ViewLayer *view_layer,
+ const struct View3D *v3d,
+ uint *r_len);
struct Base **BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- struct ViewLayer *view_layer, const struct View3D *v3d, uint *r_len);
+ const struct Scene *scene,
+ struct ViewLayer *view_layer,
+ const struct View3D *v3d,
+ uint *r_len);
struct Object **BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- struct ViewLayer *view_layer, const struct View3D *v3d, uint *r_len);
-struct Object **BKE_view_layer_array_from_objects_in_mode_unique_data(struct ViewLayer *view_layer,
+ const struct Scene *scene,
+ struct ViewLayer *view_layer,
+ const struct View3D *v3d,
+ uint *r_len);
+struct Object **BKE_view_layer_array_from_objects_in_mode_unique_data(const struct Scene *scene,
+ struct ViewLayer *view_layer,
const struct View3D *v3d,
uint *r_len,
eObjectMode mode);
struct Object *BKE_view_layer_active_object_get(const struct ViewLayer *view_layer);
struct Object *BKE_view_layer_edit_object_get(const struct ViewLayer *view_layer);
+struct ListBase *BKE_view_layer_object_bases_get(struct ViewLayer *view_layer);
+struct Base *BKE_view_layer_active_base_get(struct ViewLayer *view_layer);
+
+struct LayerCollection *BKE_view_layer_active_collection_get(struct ViewLayer *view_layer);
+
+void BKE_view_layer_need_resync_tag(struct ViewLayer *view_layer);
+void BKE_view_layer_synced_ensure(const struct Scene *scene, struct ViewLayer *view_layer);
+
+void BKE_scene_view_layers_synced_ensure(const struct Scene *scene);
+void BKE_main_view_layers_synced_ensure(const struct Main *bmain);
+
struct ViewLayerAOV *BKE_view_layer_add_aov(struct ViewLayer *view_layer);
void BKE_view_layer_remove_aov(struct ViewLayer *view_layer, struct ViewLayerAOV *aov);
void BKE_view_layer_set_active_aov(struct ViewLayer *view_layer, struct ViewLayerAOV *aov);
diff --git a/source/blender/blenkernel/BKE_lib_id.h b/source/blender/blenkernel/BKE_lib_id.h
index e5b013ce201..aa3bdb502f8 100644
--- a/source/blender/blenkernel/BKE_lib_id.h
+++ b/source/blender/blenkernel/BKE_lib_id.h
@@ -77,19 +77,19 @@ void BKE_libblock_runtime_reset_remapping_status(struct ID *id) ATTR_NONNULL(1);
/* *** ID's session_uuid management. *** */
/**
- * When an ID's uuid is of that value, it is unset/invalid (e.g. for runtime IDs, etc.).
+ * When an ID's UUID is of that value, it is unset/invalid (e.g. for runtime IDs, etc.).
*/
#define MAIN_ID_SESSION_UUID_UNSET 0
/**
- * Generate a session-wise uuid for the given \a id.
+ * Generate a session-wise UUID for the given \a id.
*
* \note "session-wise" here means while editing a given .blend file. Once a new .blend file is
- * loaded or created, undo history is cleared/reset, and so is the uuid counter.
+ * loaded or created, undo history is cleared/reset, and so is the UUID counter.
*/
void BKE_lib_libblock_session_uuid_ensure(struct ID *id);
/**
- * Re-generate a new session-wise uuid for the given \a id.
+ * Re-generate a new session-wise UUID for the given \a id.
*
* \warning This has a few very specific use-cases, no other usage is expected currently:
* - To handle UI-related data-blocks that are kept across new file reading, when we do keep
@@ -117,14 +117,14 @@ void *BKE_id_new_nomain(short type, const char *name);
*/
enum {
/* *** Generic options (should be handled by all ID types copying, ID creation, etc.). *** */
- /** Create datablock outside of any main database -
+ /** Create data-block outside of any main database -
* similar to 'localize' functions of materials etc. */
LIB_ID_CREATE_NO_MAIN = 1 << 0,
- /** Do not affect user refcount of datablocks used by new one
- * (which also gets zero usercount then).
+ /** Do not affect user refcount of data-blocks used by new one
+ * (which also gets zero user-count then).
* Implies LIB_ID_CREATE_NO_MAIN. */
LIB_ID_CREATE_NO_USER_REFCOUNT = 1 << 1,
- /** Assume given 'newid' already points to allocated memory for whole datablock
+ /** Assume given 'newid' already points to allocated memory for whole data-block
* (ID + data) - USE WITH CAUTION!
* Implies LIB_ID_CREATE_NO_MAIN. */
LIB_ID_CREATE_NO_ALLOCATE = 1 << 2,
@@ -150,7 +150,7 @@ enum {
LIB_ID_COPY_NO_PREVIEW = 1 << 17,
/** Copy runtime data caches. */
LIB_ID_COPY_CACHES = 1 << 18,
- /** Don't copy id->adt, used by ID data-block localization routines. */
+ /** Don't copy `id->adt`, used by ID data-block localization routines. */
LIB_ID_COPY_NO_ANIMDATA = 1 << 19,
/** Mesh: Reference CD data layers instead of doing real copy - USE WITH CAUTION! */
LIB_ID_COPY_CD_REFERENCE = 1 << 20,
@@ -239,12 +239,12 @@ enum {
/** Do not try to remove freed ID from given Main (passed Main may be NULL). */
LIB_ID_FREE_NO_MAIN = 1 << 0,
/**
- * Do not affect user refcount of datablocks used by freed one.
+ * Do not affect user refcount of data-blocks used by freed one.
* Implies LIB_ID_FREE_NO_MAIN.
*/
LIB_ID_FREE_NO_USER_REFCOUNT = 1 << 1,
/**
- * Assume freed ID datablock memory is managed elsewhere, do not free it
+ * Assume freed ID data-block memory is managed elsewhere, do not free it
* (still calls relevant ID type's freeing function though) - USE WITH CAUTION!
* Implies LIB_ID_FREE_NO_MAIN.
*/
@@ -254,7 +254,7 @@ enum {
LIB_ID_FREE_NO_DEG_TAG = 1 << 8,
/** Do not attempt to remove freed ID from UI data/notifiers/... */
LIB_ID_FREE_NO_UI_USER = 1 << 9,
- /** Do not remove freed ID's name from a potential runtime namemap. */
+ /** Do not remove freed ID's name from a potential runtime name-map. */
LIB_ID_FREE_NO_NAMEMAP_REMOVE = 1 << 10,
};
@@ -283,7 +283,7 @@ void BKE_libblock_free_data_py(struct ID *id);
* \param idv: Pointer to ID to be freed.
* \param flag: Set of \a LIB_ID_FREE_... flags controlling/overriding usual freeing process,
* 0 to get default safe behavior.
- * \param use_flag_from_idtag: Still use freeing info flags from given #ID datablock,
+ * \param use_flag_from_idtag: Still use freeing info flags from given #ID data-block,
* even if some overriding ones are passed in \a flag parameter.
*/
void BKE_id_free_ex(struct Main *bmain, void *idv, int flag, bool use_flag_from_idtag);
@@ -300,7 +300,7 @@ void BKE_id_free(struct Main *bmain, void *idv);
/**
* Not really a freeing function by itself,
- * it decrements usercount of given id, and only frees it if it reaches 0.
+ * it decrements user-count of given id, and only frees it if it reaches 0.
*/
void BKE_id_free_us(struct Main *bmain, void *idv) ATTR_NONNULL();
@@ -316,12 +316,12 @@ void BKE_id_delete(struct Main *bmain, void *idv) ATTR_NONNULL();
*
* \warning Considered experimental for now, seems to be working OK but this is
* risky code in a complicated area.
- * \return Number of deleted datablocks.
+ * \return Number of deleted data-blocks.
*/
size_t BKE_id_multi_tagged_delete(struct Main *bmain) ATTR_NONNULL();
/**
- * Add a 'NO_MAIN' data-block to given main (also sets usercounts of its IDs if needed).
+ * Add a 'NO_MAIN' data-block to given main (also sets user-counts of its IDs if needed).
*/
void BKE_libblock_management_main_add(struct Main *bmain, void *idv);
/** Remove a data-block from given main (set it to 'NO_MAIN' status). */
diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h
index 8542c02fab5..963e2d09b17 100644
--- a/source/blender/blenkernel/BKE_lib_override.h
+++ b/source/blender/blenkernel/BKE_lib_override.h
@@ -117,7 +117,7 @@ struct ID *BKE_lib_override_library_create_from_id(struct Main *bmain,
/**
* Create overridden local copies of all tagged data-blocks in given Main.
*
- * \note Set `id->newid` of overridden libs with newly created overrides,
+ * \note Set `id->newid` of overridden libraries with newly created overrides,
* caller is responsible to clean those pointers before/after usage as needed.
*
* \note By default, it will only remap newly created local overriding data-blocks between
diff --git a/source/blender/blenkernel/BKE_lib_remap.h b/source/blender/blenkernel/BKE_lib_remap.h
index 37b626fb4da..a17ef8c7c5d 100644
--- a/source/blender/blenkernel/BKE_lib_remap.h
+++ b/source/blender/blenkernel/BKE_lib_remap.h
@@ -180,12 +180,12 @@ typedef enum IDRemapperApplyResult {
typedef enum IDRemapperApplyOptions {
/**
- * Update the user count of the old and new ID datablock.
+ * Update the user count of the old and new ID data-block.
*
* For remapping the old ID users will be decremented and the new ID users will be
* incremented. When un-assigning the old ID users will be decremented.
*
- * NOTE: Currently unused by main remapping code, since usercount is handled by
+ * NOTE: Currently unused by main remapping code, since user-count is handled by
* `foreach_libblock_remap_callback_apply` there, depending on whether the remapped pointer does
* use it or not. Need for rare cases in UI handling though (see e.g. `image_id_remap` in
* `space_image.c`).
@@ -193,14 +193,14 @@ typedef enum IDRemapperApplyOptions {
ID_REMAP_APPLY_UPDATE_REFCOUNT = (1 << 0),
/**
- * Make sure that the new ID datablock will have a 'real' user.
+ * Make sure that the new ID data-block will have a 'real' user.
*
* NOTE: See Note for #ID_REMAP_APPLY_UPDATE_REFCOUNT above.
*/
ID_REMAP_APPLY_ENSURE_REAL = (1 << 1),
/**
- * Unassign in stead of remap when the new ID datablock would become id_self.
+ * Unassign in stead of remap when the new ID data-block would become id_self.
*
* To use this option 'BKE_id_remapper_apply_ex' must be used with a not-null id_self parameter.
*/
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index 4d26ed11f1b..7c3a64f1cad 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -113,28 +113,38 @@ typedef struct Main {
char filepath[1024]; /* 1024 = FILE_MAX */
short versionfile, subversionfile; /* see BLENDER_FILE_VERSION, BLENDER_FILE_SUBVERSION */
short minversionfile, minsubversionfile;
- uint64_t build_commit_timestamp; /* commit's timestamp from buildinfo */
- char build_hash[16]; /* hash from buildinfo */
+ /** Commit timestamp from `buildinfo`. */
+ uint64_t build_commit_timestamp;
+ /** Commit Hash from `buildinfo`. */
+ char build_hash[16];
/** Indicate the #Main.filepath (file) is the recovered one. */
- char recovered;
+ bool recovered;
/** All current ID's exist in the last memfile undo step. */
- char is_memfile_undo_written;
+ bool is_memfile_undo_written;
/**
* An ID needs its data to be flushed back.
* use "needs_flush_to_id" in edit data to flag data which needs updating.
*/
- char is_memfile_undo_flush_needed;
+ bool is_memfile_undo_flush_needed;
/**
* Indicates that next memfile undo step should not allow reusing old bmain when re-read, but
* instead do a complete full re-read/update from stored memfile.
*/
- char use_memfile_full_barrier;
+ bool use_memfile_full_barrier;
/**
* When linking, disallow creation of new data-blocks.
* Make sure we don't do this by accident, see T76738.
*/
- char is_locked_for_linking;
+ bool is_locked_for_linking;
+
+ /**
+ * True if this main is the 'GMAIN' of current Blender.
+ *
+ * \note There should always be only one global main, all others generated temporarily for
+ * various data management process must have this property set to false..
+ */
+ bool is_global_main;
BlendThumbnail *blen_thumb;
@@ -200,6 +210,12 @@ typedef struct Main {
struct MainLock *lock;
} Main;
+/**
+ * Create a new Main data-base.
+ *
+ * \note Always generate a non-global Main, use #BKE_blender_globals_main_replace to put a newly
+ * created one in `G_MAIN`.
+ */
struct Main *BKE_main_new(void);
void BKE_main_free(struct Main *mainvar);
diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h
index 7d265ceb102..beed524df4c 100644
--- a/source/blender/blenkernel/BKE_mball.h
+++ b/source/blender/blenkernel/BKE_mball.h
@@ -68,7 +68,7 @@ struct BoundBox *BKE_mball_boundbox_get(struct Object *ob);
* `MBall`, `MBall.001`, `MBall.002`, etc). The most important is to copy properties to the base
* meta-ball, because this meta-ball influences polygonization of meta-balls.
*/
-void BKE_mball_properties_copy(struct Main *bmain, struct MetaBall *active_metaball);
+void BKE_mball_properties_copy(struct Main *bmain, struct MetaBall *metaball_src);
bool BKE_mball_minmax_ex(
const struct MetaBall *mb, float min[3], float max[3], const float obmat[4][4], short flag);
@@ -88,7 +88,7 @@ void BKE_mball_translate(struct MetaBall *mb, const float offset[3]);
*/
struct MetaElem *BKE_mball_element_add(struct MetaBall *mb, int type);
-/* *** select funcs *** */
+/* *** Select functions *** */
int BKE_mball_select_count(const struct MetaBall *mb);
int BKE_mball_select_count_multi(struct Base **bases, int bases_len);
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index ef57c9a2e0e..8f6786d4113 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -106,7 +106,7 @@ void BKE_mesh_ensure_default_orig_index_customdata_no_check(struct Mesh *mesh);
* Find the index of the loop in 'poly' which references vertex,
* returns -1 if not found
*/
-int poly_find_loop_from_vert(const struct MPoly *poly, const struct MLoop *loopstart, uint vert);
+int poly_find_loop_from_vert(const struct MPoly *poly, const struct MLoop *loopstart, int vert);
/**
* 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
@@ -114,8 +114,8 @@ int poly_find_loop_from_vert(const struct MPoly *poly, const struct MLoop *loops
*/
int poly_get_adj_loops_from_vert(const struct MPoly *poly,
const struct MLoop *mloop,
- unsigned int vert,
- unsigned int r_adj[2]);
+ int vert,
+ int r_adj[2]);
/**
* Return the index of the edge vert that is not equal to \a v. If
@@ -307,8 +307,6 @@ void BKE_mesh_translate(struct Mesh *me, const float offset[3], bool do_keys);
void BKE_mesh_tessface_clear(struct Mesh *mesh);
-void BKE_mesh_do_versions_cd_flag_init(struct Mesh *mesh);
-
void BKE_mesh_mselect_clear(struct Mesh *me);
void BKE_mesh_mselect_validate(struct Mesh *me);
/**
@@ -490,7 +488,7 @@ void BKE_mesh_calc_normals(struct Mesh *me);
* Called after calculating all modifiers.
*/
void BKE_mesh_ensure_normals_for_display(struct Mesh *mesh);
-void BKE_mesh_calc_normals_looptri(struct MVert *mverts,
+void BKE_mesh_calc_normals_looptri(const struct MVert *mverts,
int numVerts,
const struct MLoop *mloop,
const struct MLoopTri *looptri,
@@ -870,16 +868,7 @@ void BKE_mesh_merge_customdata_for_apply_modifier(struct Mesh *me);
*/
void BKE_mesh_flush_hidden_from_verts(struct Mesh *me);
void BKE_mesh_flush_hidden_from_polys(struct Mesh *me);
-/**
- * simple poly -> vert/edge selection.
- */
-void BKE_mesh_flush_select_from_polys_ex(struct MVert *mvert,
- int totvert,
- const struct MLoop *mloop,
- struct MEdge *medge,
- int totedge,
- const struct MPoly *mpoly,
- int totpoly);
+
void BKE_mesh_flush_select_from_polys(struct Mesh *me);
void BKE_mesh_flush_select_from_verts(struct Mesh *me);
@@ -983,11 +972,6 @@ void BKE_mesh_strip_loose_faces(struct Mesh *me);
void BKE_mesh_strip_loose_polysloops(struct Mesh *me);
void BKE_mesh_strip_loose_edges(struct Mesh *me);
-/**
- * If the mesh is from a very old blender version,
- * convert #MFace.edcode to edge #ME_EDGEDRAW.
- */
-void BKE_mesh_calc_edges_legacy(struct Mesh *me, bool use_old);
void BKE_mesh_calc_edges_loose(struct Mesh *mesh);
/**
* Calculate edges from polygons.
@@ -1148,7 +1132,11 @@ inline blender::MutableSpan<MLoop> Mesh::loops_for_write()
inline blender::Span<MDeformVert> Mesh::deform_verts() const
{
- return {BKE_mesh_deform_verts(this), this->totvert};
+ const MDeformVert *dverts = BKE_mesh_deform_verts(this);
+ if (!dverts) {
+ return {};
+ }
+ return {dverts, this->totvert};
}
inline blender::MutableSpan<MDeformVert> Mesh::deform_verts_for_write()
{
diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.h b/source/blender/blenkernel/BKE_mesh_legacy_convert.h
index e67aec0b9ce..5eae7bf3b22 100644
--- a/source/blender/blenkernel/BKE_mesh_legacy_convert.h
+++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.h
@@ -10,6 +10,11 @@
#include "BLI_utildefines.h"
#ifdef __cplusplus
+# include "BLI_span.hh"
+# include "DNA_customdata_types.h"
+#endif
+
+#ifdef __cplusplus
extern "C" {
#endif
@@ -17,6 +22,27 @@ struct CustomData;
struct Mesh;
struct MFace;
+#ifdef __cplusplus
+
+/**
+ * Move face sets to the legacy type from a generic type.
+ */
+void BKE_mesh_legacy_face_set_from_generic(
+ Mesh *mesh, blender::MutableSpan<CustomDataLayer> poly_layers_to_write);
+/**
+ * Copy face sets to the generic data type from the legacy type.
+ */
+void BKE_mesh_legacy_face_set_to_generic(struct Mesh *mesh);
+
+/**
+ * Copy edge creases from a separate layer into edges.
+ */
+void BKE_mesh_legacy_edge_crease_from_layers(struct Mesh *mesh);
+/**
+ * Copy edge creases from edges to a separate layer.
+ */
+void BKE_mesh_legacy_edge_crease_to_layers(struct Mesh *mesh);
+
/**
* Copy bevel weights from separate layers into vertices and edges.
*/
@@ -37,6 +63,16 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(struct Mesh *mesh);
void BKE_mesh_legacy_convert_flags_to_hide_layers(struct Mesh *mesh);
/**
+ * Convert the selected element attributes to the old flag format for writing.
+ */
+void BKE_mesh_legacy_convert_selection_layers_to_flags(struct Mesh *mesh);
+/**
+ * Convert the old selection flags (#SELECT/#ME_FACE_SEL) to the selected element attribute for
+ * reading. Only add the attributes when there are any elements in each domain selected.
+ */
+void BKE_mesh_legacy_convert_flags_to_selection_layers(struct Mesh *mesh);
+
+/**
* Move material indices from a generic attribute to #MPoly.
*/
void BKE_mesh_legacy_convert_material_indices_to_mpoly(struct Mesh *mesh);
@@ -46,6 +82,8 @@ void BKE_mesh_legacy_convert_material_indices_to_mpoly(struct Mesh *mesh);
*/
void BKE_mesh_legacy_convert_mpoly_to_material_indices(struct Mesh *mesh);
+#endif
+
/**
* Recreate #MFace Tessellation.
*
@@ -57,8 +95,6 @@ void BKE_mesh_tessface_calc(struct Mesh *mesh);
void BKE_mesh_tessface_ensure(struct Mesh *mesh);
-void BKE_mesh_add_mface_layers(struct CustomData *fdata, struct CustomData *ldata, int total);
-
/**
* Rotates the vertices of a face in case v[2] or v[3] (vertex index) is = 0.
* this is necessary to make the if #MFace.v4 check for quads work.
@@ -85,6 +121,13 @@ void BKE_mesh_convert_mfaces_to_mpolys(struct Mesh *mesh);
*/
void BKE_mesh_do_versions_convert_mfaces_to_mpolys(struct Mesh *mesh);
+/**
+ * Convert legacy #MFace.edcode to edge #ME_EDGEDRAW.
+ */
+void BKE_mesh_calc_edges_legacy(struct Mesh *me, bool use_old);
+
+void BKE_mesh_do_versions_cd_flag_init(struct Mesh *mesh);
+
/* Inlines */
/* NOTE(@sybren): Instead of -1 that function uses ORIGINDEX_NONE as defined in BKE_customdata.h,
diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h
index cf9763d50a4..705158bec0b 100644
--- a/source/blender/blenkernel/BKE_mesh_mapping.h
+++ b/source/blender/blenkernel/BKE_mesh_mapping.h
@@ -7,6 +7,10 @@
*/
#ifdef __cplusplus
+# include "BLI_array.hh"
+#endif
+
+#ifdef __cplusplus
extern "C" {
#endif
@@ -59,6 +63,10 @@ typedef struct UvElement {
* If islands are calculated, it also stores UvElements
* belonging to the same uv island in sequence and
* the number of uvs per island.
+ *
+ * \note in C++, #head_table and #unique_index_table would
+ * be `mutable`, as they are created on demand, and never
+ * changed after creation.
*/
typedef struct UvElementMap {
/** UvElement Storage. */
@@ -74,6 +82,9 @@ typedef struct UvElementMap {
/** If Non-NULL, pointer to local head of each unique UV. */
struct UvElement **head_table;
+ /** If Non-NULL, pointer to index of each unique UV. */
+ int *unique_index_table;
+
/** Number of islands, or zero if not calculated. */
int total_islands;
/** Array of starting index in #storage where each island begins. */
@@ -93,6 +104,7 @@ typedef struct MeshElemMap {
/* mapping */
UvVertMap *BKE_mesh_uv_vert_map_create(const struct MPoly *mpoly,
const bool *hide_poly,
+ const bool *select_poly,
const struct MLoop *mloop,
const struct MLoopUV *mloopuv,
unsigned int totpoly,
@@ -329,3 +341,19 @@ int *BKE_mesh_calc_smoothgroups(const struct MEdge *medge,
#ifdef __cplusplus
}
#endif
+
+#ifdef __cplusplus
+namespace blender::bke::mesh_topology {
+
+Array<int> build_loop_to_poly_map(Span<MPoly> polys, int loops_num);
+
+Array<Vector<int>> build_vert_to_edge_map(Span<MEdge> edges, int verts_num);
+Array<Vector<int>> build_vert_to_loop_map(Span<MLoop> loops, int verts_num);
+
+inline int previous_poly_loop(const MPoly &poly, int loop_i)
+{
+ return loop_i - 1 + (loop_i == poly.loopstart) * poly.totloop;
+}
+
+} // namespace blender::bke::mesh_topology
+#endif
diff --git a/source/blender/blenkernel/BKE_mesh_runtime.h b/source/blender/blenkernel/BKE_mesh_runtime.h
index dfefe125a51..27e04c1a4de 100644
--- a/source/blender/blenkernel/BKE_mesh_runtime.h
+++ b/source/blender/blenkernel/BKE_mesh_runtime.h
@@ -9,6 +9,7 @@
*/
//#include "BKE_customdata.h" /* for eCustomDataMask */
+#include "BKE_mesh_types.h"
#ifdef __cplusplus
extern "C" {
@@ -26,21 +27,10 @@ struct Object;
struct Scene;
/**
- * \brief Initialize the runtime of the given mesh.
- *
- * Function expects that the runtime is already cleared.
- */
-void BKE_mesh_runtime_init_data(struct Mesh *mesh);
-/**
* \brief Free all data (and mutexes) inside the runtime of the given mesh.
*/
void BKE_mesh_runtime_free_data(struct Mesh *mesh);
-/**
- * Clear all pointers which we don't want to be shared on copying the datablock.
- * However, keep all the flags which defines what the mesh is (for example, that
- * it's deformed only, or that its custom data layers are out of date.)
- */
-void BKE_mesh_runtime_reset_on_copy(struct Mesh *mesh, int flag);
+
int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh);
void BKE_mesh_runtime_looptri_recalc(struct Mesh *mesh);
/**
@@ -66,6 +56,11 @@ void BKE_mesh_runtime_verttri_from_looptri(struct MVertTri *r_verttri,
const struct MLoopTri *looptri,
int looptri_num);
+/** \note Only used for access in C. */
+bool BKE_mesh_is_deformed_only(const struct Mesh *mesh);
+/** \note Only used for access in C. */
+eMeshWrapperType BKE_mesh_wrapper_type(const struct Mesh *mesh);
+
/* NOTE: the functions below are defined in DerivedMesh.cc, and are intended to be moved
* to a more suitable location when that file is removed.
* They should also be renamed to use conventions from BKE, not old DerivedMesh.cc.
diff --git a/source/blender/blenkernel/BKE_mesh_types.h b/source/blender/blenkernel/BKE_mesh_types.h
index 0b879c1dfe9..80f61086052 100644
--- a/source/blender/blenkernel/BKE_mesh_types.h
+++ b/source/blender/blenkernel/BKE_mesh_types.h
@@ -1,11 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2020 Blender Foundation. All rights reserved. */
+
#pragma once
/** \file
* \ingroup bke
*/
+#ifdef __cplusplus
+
+# include <mutex>
+
+# include "BLI_span.hh"
+
+# include "DNA_customdata_types.h"
+
+# include "MEM_guardedalloc.h"
+
+struct BVHCache;
+struct EditMeshData;
+struct MLoopTri;
+struct ShrinkwrapBoundaryData;
+struct SubdivCCG;
+struct SubsurfRuntimeData;
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef enum eMeshBatchDirtyMode {
BKE_MESH_BATCH_DIRTY_ALL = 0,
BKE_MESH_BATCH_DIRTY_SELECT,
@@ -14,3 +38,125 @@ typedef enum eMeshBatchDirtyMode {
BKE_MESH_BATCH_DIRTY_UVEDIT_ALL,
BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT,
} eMeshBatchDirtyMode;
+
+/** #MeshRuntime.wrapper_type */
+typedef enum eMeshWrapperType {
+ /** Use mesh data (#Mesh.mvert, #Mesh.medge, #Mesh.mloop, #Mesh.mpoly). */
+ ME_WRAPPER_TYPE_MDATA = 0,
+ /** Use edit-mesh data (#Mesh.edit_mesh, #MeshRuntime.edit_data). */
+ ME_WRAPPER_TYPE_BMESH = 1,
+ /** Use subdivision mesh data (#MeshRuntime.mesh_eval). */
+ ME_WRAPPER_TYPE_SUBD = 2,
+} eMeshWrapperType;
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef __cplusplus
+
+namespace blender::bke {
+
+/**
+ * \warning Typical access is done via #Mesh::looptris().
+ */
+struct MLoopTri_Store {
+ /* WARNING! swapping between array (ready-to-be-used data) and array_wip
+ * (where data is actually computed)
+ * shall always be protected by same lock as one used for looptris computing. */
+ MLoopTri *array = nullptr;
+ MLoopTri *array_wip = nullptr;
+ int len = 0;
+ int len_alloc = 0;
+};
+
+struct MeshRuntime {
+ /* Evaluated mesh for objects which do not have effective modifiers.
+ * This mesh is used as a result of modifier stack evaluation.
+ * Since modifier stack evaluation is threaded on object level we need some synchronization. */
+ Mesh *mesh_eval = nullptr;
+ std::mutex eval_mutex;
+
+ /* A separate mutex is needed for normal calculation, because sometimes
+ * the normals are needed while #eval_mutex is already locked. */
+ std::mutex normals_mutex;
+
+ /** Needed to ensure some thread-safety during render data pre-processing. */
+ std::mutex render_mutex;
+
+ /** Lazily initialized SoA data from the #edit_mesh field in #Mesh. */
+ EditMeshData *edit_data = nullptr;
+
+ /**
+ * Data used to efficiently draw the mesh in the viewport, especially useful when
+ * the same mesh is used in many objects or instances. See `draw_cache_impl_mesh.cc`.
+ */
+ void *batch_cache = nullptr;
+
+ /** Cache for derived triangulation of the mesh. */
+ MLoopTri_Store looptris;
+
+ /** Cache for BVH trees generated for the mesh. Defined in 'BKE_bvhutil.c' */
+ BVHCache *bvh_cache = nullptr;
+
+ /** Cache of non-manifold boundary data for Shrink-wrap Target Project. */
+ ShrinkwrapBoundaryData *shrinkwrap_data = nullptr;
+
+ /** Needed in case we need to lazily initialize the mesh. */
+ CustomData_MeshMasks cd_mask_extra = {};
+
+ SubdivCCG *subdiv_ccg = nullptr;
+ int subdiv_ccg_tot_level = 0;
+
+ /** Set by modifier stack if only deformed from original. */
+ bool deformed_only = false;
+ /**
+ * Copied from edit-mesh (hint, draw with edit-mesh data when true).
+ *
+ * Modifiers that edit the mesh data in-place must set this to false
+ * (most #eModifierTypeType_NonGeometrical modifiers). Otherwise the edit-mesh
+ * data will be used for drawing, missing changes from modifiers. See T79517.
+ */
+ bool is_original_bmesh = false;
+
+ /** #eMeshWrapperType and others. */
+ eMeshWrapperType wrapper_type = ME_WRAPPER_TYPE_MDATA;
+ /**
+ * A type mask from wrapper_type,
+ * in case there are differences in finalizing logic between types.
+ */
+ eMeshWrapperType wrapper_type_finalize = ME_WRAPPER_TYPE_MDATA;
+
+ /**
+ * Settings for lazily evaluating the subdivision on the CPU if needed. These are
+ * set in the modifier when GPU subdivision can be performed, and owned by the by
+ * the modifier in the object.
+ */
+ SubsurfRuntimeData *subsurf_runtime_data = nullptr;
+
+ /**
+ * Caches for lazily computed vertex and polygon normals. These are stored here rather than in
+ * #CustomData because they can be calculated on a `const` mesh, and adding custom data layers on
+ * a `const` mesh is not thread-safe.
+ */
+ bool vert_normals_dirty = false;
+ bool poly_normals_dirty = false;
+ float (*vert_normals)[3] = nullptr;
+ float (*poly_normals)[3] = nullptr;
+
+ /**
+ * A #BLI_bitmap containing tags for the center vertices of subdivided polygons, set by the
+ * subdivision surface modifier and used by drawing code instead of polygon center face dots.
+ */
+ uint32_t *subsurf_face_dot_tags = nullptr;
+
+ MeshRuntime() = default;
+ /** \warning This does not free all data currently. See #BKE_mesh_runtime_free_data. */
+ ~MeshRuntime() = default;
+
+ MEM_CXX_CLASS_ALLOC_FUNCS("MeshRuntime")
+};
+
+} // namespace blender::bke
+
+#endif
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index cda1fd01e44..ce2f9e878f8 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -127,6 +127,7 @@ typedef enum ModifierApplyFlag {
* See `OBJECT_OT_modifier_apply` operator. */
MOD_APPLY_TO_BASE_MESH = 1 << 4,
} ModifierApplyFlag;
+ENUM_OPERATORS(ModifierApplyFlag, MOD_APPLY_TO_BASE_MESH);
typedef struct ModifierUpdateDepsgraphContext {
struct Scene *scene;
@@ -265,9 +266,7 @@ typedef struct ModifierTypeInfo {
*
* This function is optional.
*/
- void (*requiredDataMask)(struct Object *ob,
- struct ModifierData *md,
- struct CustomData_MeshMasks *r_cddata_masks);
+ void (*requiredDataMask)(struct ModifierData *md, struct CustomData_MeshMasks *r_cddata_masks);
/**
* Free internal modifier data variables, this function should
@@ -521,7 +520,6 @@ typedef struct CDMaskLink {
* final_datamask is required at the end of the stack.
*/
struct CDMaskLink *BKE_modifier_calc_data_masks(const struct Scene *scene,
- struct Object *ob,
struct ModifierData *md,
struct CustomData_MeshMasks *final_datamask,
int required_mode,
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h
index dfa330ff508..53dfaf953ea 100644
--- a/source/blender/blenkernel/BKE_multires.h
+++ b/source/blender/blenkernel/BKE_multires.h
@@ -8,7 +8,7 @@
*/
#include "BKE_subsurf.h"
-#include "BLI_compiler_compat.h"
+#include "BLI_utildefines.h"
#ifdef __cplusplus
extern "C" {
@@ -53,12 +53,13 @@ void multires_modifier_update_hidden(struct DerivedMesh *dm);
*/
void multiresModifier_set_levels_from_disps(struct MultiresModifierData *mmd, struct Object *ob);
-typedef enum {
+typedef enum MultiresFlags {
MULTIRES_USE_LOCAL_MMD = 1,
MULTIRES_USE_RENDER_PARAMS = 2,
MULTIRES_ALLOC_PAINT_MASK = 4,
MULTIRES_IGNORE_SIMPLIFY = 8,
} MultiresFlags;
+ENUM_OPERATORS(MultiresFlags, MULTIRES_IGNORE_SIMPLIFY);
struct DerivedMesh *multires_make_derived_from_derived(struct DerivedMesh *dm,
struct MultiresModifierData *mmd,
diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h
index 2613f4286f0..2913beee759 100644
--- a/source/blender/blenkernel/BKE_nla.h
+++ b/source/blender/blenkernel/BKE_nla.h
@@ -7,7 +7,7 @@
* \ingroup bke
*/
-/* temp constant defined for these funcs only... */
+/** Temp constant defined for these functions only. */
#define NLASTRIP_MIN_LEN_THRESH 0.1f
#ifdef __cplusplus
@@ -246,6 +246,24 @@ float BKE_nlastrip_compute_frame_from_previous_strip(struct NlaStrip *strip);
*/
float BKE_nlastrip_compute_frame_to_next_strip(struct NlaStrip *strip);
+/**
+ * Returns the next strip in this strip's NLA track, or a null pointer.
+ *
+ * \param strip: The strip to find the next trip from.
+ * \param check_transitions: Whether or not to skip transitions.
+ * \return The next strip in the track, or NULL if none are present.
+ */
+struct NlaStrip *BKE_nlastrip_next_in_track(struct NlaStrip *strip, bool skip_transitions);
+
+/**
+ * Returns the previous strip in this strip's NLA track, or a null pointer.
+ *
+ * \param strip: The strip to find the previous trip from.
+ * \param check_transitions: Whether or not to skip transitions.
+ * \return The previous strip in the track, or NULL if none are present.
+ */
+struct NlaStrip *BKE_nlastrip_prev_in_track(struct NlaStrip *strip, bool skip_transitions);
+
/* ............ */
/**
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 55bf24f943e..4d883f9e31e 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -477,7 +477,7 @@ struct bNodeTree *ntreeAddTreeEmbedded(struct Main *bmain,
const char *name,
const char *idname);
-/* copy/free funcs, need to manage ID users */
+/* Copy/free functions, need to manage ID users. */
/**
* Free (or release) any data used by this node-tree.
@@ -572,6 +572,11 @@ struct bNodeSocket *ntreeInsertSocketInterface(struct bNodeTree *ntree,
struct bNodeSocket *ntreeAddSocketInterfaceFromSocket(struct bNodeTree *ntree,
struct bNode *from_node,
struct bNodeSocket *from_sock);
+struct bNodeSocket *ntreeAddSocketInterfaceFromSocketWithName(struct bNodeTree *ntree,
+ struct bNode *from_node,
+ struct bNodeSocket *from_sock,
+ const char *idname,
+ const char *name);
struct bNodeSocket *ntreeInsertSocketInterfaceFromSocket(struct bNodeTree *ntree,
struct bNodeSocket *next_sock,
struct bNode *from_node,
@@ -792,6 +797,12 @@ void nodeChainIterBackwards(const bNodeTree *ntree,
*/
void nodeParentsIter(bNode *node, bool (*callback)(bNode *, void *), void *userdata);
+/**
+ * A dangling reroute node is a reroute node that does *not* have a "data source", i.e. no
+ * non-reroute node is connected to its input.
+ */
+bool nodeIsDanglingReroute(const struct bNodeTree *ntree, const struct bNode *node);
+
struct bNodeLink *nodeFindLink(struct bNodeTree *ntree,
const struct bNodeSocket *from,
const struct bNodeSocket *to);
@@ -960,8 +971,8 @@ void nodeLabel(const struct bNodeTree *ntree, const struct bNode *node, char *la
*/
const char *nodeSocketLabel(const struct bNodeSocket *sock);
-bool nodeGroupPoll(struct bNodeTree *nodetree,
- struct bNodeTree *grouptree,
+bool nodeGroupPoll(const struct bNodeTree *nodetree,
+ const struct bNodeTree *grouptree,
const char **r_disabled_hint);
/**
@@ -977,8 +988,6 @@ void node_type_socket_templates(struct bNodeType *ntype,
struct bNodeSocketTemplate *outputs);
void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth);
void node_type_size_preset(struct bNodeType *ntype, eNodeSizePreset size);
-void node_type_init(struct bNodeType *ntype,
- void (*initfunc)(struct bNodeTree *ntree, struct bNode *node));
/**
* \warning Nodes defining a storage type _must_ allocate this for new nodes.
* Otherwise nodes will reload as undefined (T46619).
@@ -989,17 +998,6 @@ void node_type_storage(struct bNodeType *ntype,
void (*copyfunc)(struct bNodeTree *dest_ntree,
struct bNode *dest_node,
const struct bNode *src_node));
-void node_type_update(struct bNodeType *ntype,
- void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node));
-void node_type_group_update(struct bNodeType *ntype,
- void (*group_update_func)(struct bNodeTree *ntree,
- struct bNode *node));
-
-void node_type_exec(struct bNodeType *ntype,
- NodeInitExecFunction init_exec_fn,
- NodeFreeExecFunction free_exec_fn,
- NodeExecFunction exec_fn);
-void node_type_gpu(struct bNodeType *ntype, NodeGPUExecFunction gpu_fn);
/** \} */
@@ -1007,7 +1005,7 @@ void node_type_gpu(struct bNodeType *ntype, NodeGPUExecFunction gpu_fn);
/** \name Node Generic Functions
* \{ */
-bool BKE_node_is_connected_to_output(struct bNodeTree *ntree, struct bNode *node);
+bool BKE_node_is_connected_to_output(const struct bNodeTree *ntree, const struct bNode *node);
/* ************** COMMON NODES *************** */
@@ -1022,8 +1020,6 @@ bool BKE_node_is_connected_to_output(struct bNodeTree *ntree, struct bNode *node
#define NODE_GROUP_OUTPUT 8
#define NODE_CUSTOM_GROUP 9
-void BKE_node_tree_unlink_id(ID *id, struct bNodeTree *ntree);
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -1480,7 +1476,7 @@ struct TexResult;
#define GEO_NODE_ROTATE_INSTANCES 1122
#define GEO_NODE_SPLIT_EDGES 1123
#define GEO_NODE_MESH_TO_CURVE 1124
-#define GEO_NODE_TRANSFER_ATTRIBUTE 1125
+#define GEO_NODE_TRANSFER_ATTRIBUTE_DEPRECATED 1125
#define GEO_NODE_SUBDIVISION_SURFACE 1126
#define GEO_NODE_CURVE_ENDPOINT_SELECTION 1127
#define GEO_NODE_RAYCAST 1128
@@ -1525,6 +1521,24 @@ struct TexResult;
#define GEO_NODE_INPUT_SHORTEST_EDGE_PATHS 1168
#define GEO_NODE_EDGE_PATHS_TO_CURVES 1169
#define GEO_NODE_EDGE_PATHS_TO_SELECTION 1170
+#define GEO_NODE_MESH_FACE_SET_BOUNDARIES 1171
+#define GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME 1172
+#define GEO_NODE_SELF_OBJECT 1173
+#define GEO_NODE_SAMPLE_INDEX 1174
+#define GEO_NODE_SAMPLE_NEAREST 1175
+#define GEO_NODE_SAMPLE_NEAREST_SURFACE 1176
+#define GEO_NODE_OFFSET_POINT_IN_CURVE 1177
+#define GEO_NODE_CURVE_TOPOLOGY_CURVE_OF_POINT 1178
+#define GEO_NODE_CURVE_TOPOLOGY_POINTS_OF_CURVE 1179
+#define GEO_NODE_MESH_TOPOLOGY_OFFSET_CORNER_IN_FACE 1180
+#define GEO_NODE_MESH_TOPOLOGY_CORNERS_OF_FACE 1181
+#define GEO_NODE_MESH_TOPOLOGY_CORNERS_OF_VERTEX 1182
+#define GEO_NODE_MESH_TOPOLOGY_EDGES_OF_CORNER 1183
+#define GEO_NODE_MESH_TOPOLOGY_EDGES_OF_VERTEX 1184
+#define GEO_NODE_MESH_TOPOLOGY_FACE_OF_CORNER 1185
+#define GEO_NODE_MESH_TOPOLOGY_VERTEX_OF_CORNER 1186
+#define GEO_NODE_SAMPLE_UV_SURFACE 1187
+#define GEO_NODE_SET_CURVE_NORMAL 1188
/** \} */
diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh
index 194820aa4ba..65c801a087b 100644
--- a/source/blender/blenkernel/BKE_node_runtime.hh
+++ b/source/blender/blenkernel/BKE_node_runtime.hh
@@ -81,7 +81,7 @@ class bNodeTreeRuntime : NonCopyable, NonMovable {
Vector<bNode *> toposort_left_to_right;
Vector<bNode *> toposort_right_to_left;
Vector<bNode *> group_nodes;
- bool has_link_cycle = false;
+ bool has_available_link_cycle = false;
bool has_undefined_nodes_or_sockets = false;
bNode *group_output_node = nullptr;
};
@@ -152,18 +152,17 @@ class bNodeRuntime : NonCopyable, NonMovable {
Map<StringRefNull, bNodeSocket *> inputs_by_identifier;
Map<StringRefNull, bNodeSocket *> outputs_by_identifier;
int index_in_tree = -1;
- bool has_linked_inputs = false;
- bool has_linked_outputs = false;
+ bool has_available_linked_inputs = false;
+ bool has_available_linked_outputs = false;
bNodeTree *owner_tree = nullptr;
};
namespace node_tree_runtime {
/**
- * Is executed when the depsgraph determines that something in the node group changed that will
- * affect the output.
+ * Is executed when the node tree changed in the depsgraph.
*/
-void handle_node_tree_output_changed(bNodeTree &tree_cow);
+void preprocess_geometry_node_tree_for_evaluation(bNodeTree &tree_cow);
class AllowUsingOutdatedInfo : NonCopyable, NonMovable {
private:
@@ -270,10 +269,10 @@ inline blender::Span<bNode *> bNodeTree::group_nodes()
return this->runtime->group_nodes;
}
-inline bool bNodeTree::has_link_cycle() const
+inline bool bNodeTree::has_available_link_cycle() const
{
BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this));
- return this->runtime->has_link_cycle;
+ return this->runtime->has_available_link_cycle;
}
inline bool bNodeTree::has_undefined_nodes_or_sockets() const
@@ -456,6 +455,11 @@ inline bool bNodeLink::is_muted() const
return this->flag & NODE_LINK_MUTED;
}
+inline bool bNodeLink::is_available() const
+{
+ return this->fromsock->is_available() && this->tosock->is_available();
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index e0fb6c5e834..cfad8c5cfdb 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -175,9 +175,10 @@ struct Object *BKE_object_add_only_object(struct Main *bmain,
* \note Creates minimum required data, but without vertices etc.
*/
struct Object *BKE_object_add(struct Main *bmain,
+ struct Scene *scene,
struct ViewLayer *view_layer,
int type,
- const char *name) ATTR_NONNULL(1, 2) ATTR_RETURNS_NONNULL;
+ const char *name) ATTR_NONNULL(1, 2, 3) ATTR_RETURNS_NONNULL;
/**
* Add a new object, using another one as a reference
*
@@ -200,6 +201,7 @@ struct Object *BKE_object_add_from(struct Main *bmain,
* assigning it to the object.
*/
struct Object *BKE_object_add_for_data(struct Main *bmain,
+ const struct Scene *scene,
struct ViewLayer *view_layer,
int type,
const char *name,
@@ -281,40 +283,57 @@ void BKE_object_apply_parent_inverse(struct Object *ob);
void BKE_object_matrix_local_get(struct Object *ob, float r_mat[4][4]);
bool BKE_object_pose_context_check(const struct Object *ob);
+
struct Object *BKE_object_pose_armature_get(struct Object *ob);
+/**
+ * A version of #BKE_object_pose_armature_get with an additional check.
+ * When `ob` isn't an armature: only return the referenced pose object
+ * when the active object is in weight paint mode.
+ *
+ * \note Some callers need to check that pose bones are selectable
+ * which isn't the case when the object using the armature isn't in weight-paint mode.
+ */
+struct Object *BKE_object_pose_armature_get_with_wpaint_check(struct Object *ob);
struct Object *BKE_object_pose_armature_get_visible(struct Object *ob,
+ const struct Scene *scene,
struct ViewLayer *view_layer,
struct View3D *v3d);
/**
* Access pose array with special check to get pose object when in weight paint mode.
*/
-struct Object **BKE_object_pose_array_get_ex(struct ViewLayer *view_layer,
+struct Object **BKE_object_pose_array_get_ex(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct View3D *v3d,
unsigned int *r_objects_len,
bool unique);
-struct Object **BKE_object_pose_array_get_unique(struct ViewLayer *view_layer,
+struct Object **BKE_object_pose_array_get_unique(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct View3D *v3d,
unsigned int *r_objects_len);
-struct Object **BKE_object_pose_array_get(struct ViewLayer *view_layer,
+struct Object **BKE_object_pose_array_get(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct View3D *v3d,
unsigned int *r_objects_len);
-struct Base **BKE_object_pose_base_array_get_ex(struct ViewLayer *view_layer,
+struct Base **BKE_object_pose_base_array_get_ex(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct View3D *v3d,
unsigned int *r_bases_len,
bool unique);
-struct Base **BKE_object_pose_base_array_get_unique(struct ViewLayer *view_layer,
+struct Base **BKE_object_pose_base_array_get_unique(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct View3D *v3d,
unsigned int *r_bases_len);
-struct Base **BKE_object_pose_base_array_get(struct ViewLayer *view_layer,
+struct Base **BKE_object_pose_base_array_get(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct View3D *v3d,
unsigned int *r_bases_len);
void BKE_object_get_parent_matrix(struct Object *ob, struct Object *par, float r_parentmat[4][4]);
/**
- * Compute object world transform and store it in `ob->obmat`.
+ * Compute object world transform and store it in `ob->object_to_world`.
*/
void BKE_object_where_is_calc(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
void BKE_object_where_is_calc_ex(struct Depsgraph *depsgraph,
@@ -612,7 +631,8 @@ typedef enum eObjectSet {
* If #OB_SET_VISIBLE or#OB_SET_SELECTED are collected,
* then also add related objects according to the given \a includeFilter.
*/
-struct LinkNode *BKE_object_relational_superset(struct ViewLayer *view_layer,
+struct LinkNode *BKE_object_relational_superset(const struct Scene *scene,
+ struct ViewLayer *view_layer,
eObjectSet objectSet,
eObRelationTypes includeFilter);
/**
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index eef91bacc2f..9fc4aa5307d 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -8,7 +8,9 @@
*/
#include "BLI_bitmap.h"
+#include "BLI_compiler_compat.h"
#include "BLI_utildefines.h"
+
#include "DNA_brush_enums.h"
#include "DNA_object_enums.h"
@@ -50,6 +52,7 @@ struct Palette;
struct PaletteColor;
struct Scene;
struct StrokeCache;
+struct Sculpt;
struct SubdivCCG;
struct Tex;
struct ToolSettings;
@@ -369,6 +372,7 @@ typedef struct SculptClothSimulation {
float (*acceleration)[3];
float (*pos)[3];
float (*init_pos)[3];
+ float (*init_no)[3];
float (*softbody_pos)[3];
float (*prev_pos)[3];
float (*last_iteration_pos)[3];
@@ -415,7 +419,6 @@ typedef struct SculptBoundaryPreviewEdge {
typedef struct SculptBoundary {
/* Vertex indices of the active boundary. */
PBVHVertRef *verts;
- int *verts_i;
int verts_capacity;
int verts_num;
@@ -485,6 +488,77 @@ typedef struct SculptFakeNeighbors {
/* Session data (mode-specific) */
+/* Custom Temporary Attributes */
+
+typedef struct SculptAttributeParams {
+ /* Allocate a flat array outside the CustomData system. Cannot be combined with permanent. */
+ int simple_array : 1;
+
+ /* Do not mark CustomData layer as temporary. Cannot be combined with simple_array. Doesn't
+ * work with PBVH_GRIDS.
+ */
+ int permanent : 1; /* Cannot be combined with simple_array. */
+ int stroke_only : 1; /* Release layer at end of struct */
+} SculptAttributeParams;
+
+typedef struct SculptAttribute {
+ /* Domain, data type and name */
+ eAttrDomain domain;
+ eCustomDataType proptype;
+ char name[MAX_CUSTOMDATA_LAYER_NAME];
+
+ /* Source layer on mesh/bmesh, if any. */
+ struct CustomDataLayer *layer;
+
+ /* Data stored as flat array. */
+ void *data;
+ int elem_size, elem_num;
+ bool data_for_bmesh; /* Temporary data store as array outside of bmesh. */
+
+ /* Data stored per BMesh element. */
+ int bmesh_cd_offset;
+
+ /* Sculpt usage */
+ SculptAttributeParams params;
+
+ /* Used to keep track of which preallocated SculptAttribute instances
+ * inside of SculptSession.temp_attribute are used.
+ */
+ bool used;
+} SculptAttribute;
+
+#define SCULPT_MAX_ATTRIBUTES 64
+
+/* Get a standard attribute name. Key must match up with a member
+ * of SculptAttributePointers.
+ */
+
+#define SCULPT_ATTRIBUTE_NAME(key) \
+ (offsetof(SculptAttributePointers, key) >= 0 ? /* Spellcheck name. */ \
+ (".sculpt_" #key) /* Make name. */ \
+ : \
+ "You misspelled the layer name key")
+
+/* Convenience pointers for standard sculpt attributes. */
+
+typedef struct SculptAttributePointers {
+ /* Persistent base. */
+ SculptAttribute *persistent_co;
+ SculptAttribute *persistent_no;
+ SculptAttribute *persistent_disp;
+
+ /* Precomputed auto-mask factor indexed by vertex, owned by the auto-masking system and
+ * initialized in #SCULPT_automasking_cache_init when needed. */
+ SculptAttribute *automasking_factor;
+ SculptAttribute *automasking_occlusion; /* CD_PROP_INT8. */
+ SculptAttribute *automasking_stroke_id;
+ SculptAttribute *automasking_cavity;
+
+ /* BMesh */
+ SculptAttribute *dyntopo_node_id_vertex;
+ SculptAttribute *dyntopo_node_id_face;
+} SculptAttributePointers;
+
typedef struct SculptSession {
/* Mesh data (not copied) can come either directly from a Mesh, or from a MultiresDM */
struct { /* Special handling for multires meshes */
@@ -529,18 +603,20 @@ typedef struct SculptSession {
/* Mesh Face Sets */
/* Total number of polys of the base mesh. */
int totfaces;
- /* Face sets store its visibility in the sign of the integer, using the absolute value as the
- * Face Set ID. Positive IDs are visible, negative IDs are hidden.
- * The 0 ID is not used by the tools or the visibility system, it is just used when creating new
+
+ /* The 0 ID is not used by the tools or the visibility system, it is just used when creating new
* geometry (the trim tool, for example) to detect which geometry was just added, so it can be
* assigned a valid Face Set after creation. Tools are not intended to run with Face Sets IDs set
* to 0. */
int *face_sets;
+ /**
+ * A reference to the ".hide_poly" attribute, to store whether (base) polygons are hidden.
+ * May be null.
+ */
+ bool *hide_poly;
/* BMesh for dynamic topology sculpting */
struct BMesh *bm;
- 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;
@@ -572,7 +648,8 @@ typedef struct SculptSession {
int active_face_index;
int active_grid_index;
- /* When active, the cursor draws with faded colors, indicating that there is an action enabled.
+ /* When active, the cursor draws with faded colors, indicating that there is an action
+ * enabled.
*/
bool draw_faded_cursor;
float cursor_radius;
@@ -581,8 +658,10 @@ typedef struct SculptSession {
float cursor_sampled_normal[3];
float cursor_view_normal[3];
- /* For Sculpt trimming gesture tools, initial ray-cast data from the position of the mouse when
- * the gesture starts (intersection with the surface and if they ray hit the surface or not). */
+ /* For Sculpt trimming gesture tools, initial ray-cast data from the position of the mouse
+ * when
+ * the gesture starts (intersection with the surface and if they ray hit the surface or not).
+ */
float gesture_initial_location[3];
float gesture_initial_normal[3];
bool gesture_initial_hit;
@@ -603,10 +682,6 @@ typedef struct SculptSession {
/* Boundary Brush Preview */
SculptBoundary *boundary_preview;
- /* Mesh State Persistence */
- /* This is freed with the PBVH, so it is always in sync with the mesh. */
- SculptPersistentBase *persistent_base;
-
SculptVertexInfo vertex_info;
SculptFakeNeighbors fake_neighbors;
@@ -652,6 +727,14 @@ typedef struct SculptSession {
*/
char needs_flush_to_id;
+ /* This is a fixed-size array so we can pass pointers to its elements
+ * to client code. This is important to keep bmesh offsets up to date.
+ */
+ struct SculptAttribute temp_attributes[SCULPT_MAX_ATTRIBUTES];
+
+ /* Convenience #SculptAttribute pointers. */
+ SculptAttributePointers attrs;
+
/**
* Some tools follows the shading chosen by the last used tool canvas.
* When not set the viewport shading color would be used.
@@ -660,11 +743,16 @@ typedef struct SculptSession {
*/
bool sticky_shading_color;
+ uchar stroke_id;
+
/**
* Last used painting canvas key.
*/
char *last_paint_canvas_key;
+ float last_normal[3];
+ int last_automasking_settings_hash;
+ uchar last_automask_stroke_id;
} SculptSession;
void BKE_sculptsession_free(struct Object *ob);
@@ -672,6 +760,75 @@ void BKE_sculptsession_free_deformMats(struct SculptSession *ss);
void BKE_sculptsession_free_vwpaint_data(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);
+int BKE_sculptsession_vertex_count(const SculptSession *ss);
+
+/* Ensure an attribute layer exists. */
+SculptAttribute *BKE_sculpt_attribute_ensure(struct Object *ob,
+ eAttrDomain domain,
+ eCustomDataType proptype,
+ const char *name,
+ const SculptAttributeParams *params);
+
+/* Returns nullptr if attribute does not exist. */
+SculptAttribute *BKE_sculpt_attribute_get(struct Object *ob,
+ eAttrDomain domain,
+ eCustomDataType proptype,
+ const char *name);
+
+bool BKE_sculpt_attribute_exists(struct Object *ob,
+ eAttrDomain domain,
+ eCustomDataType proptype,
+ const char *name);
+
+bool BKE_sculpt_attribute_destroy(struct Object *ob, SculptAttribute *attr);
+
+/* Destroy all attributes and pseudo-attributes created by sculpt mode. */
+void BKE_sculpt_attribute_destroy_temporary_all(struct Object *ob);
+
+/* Destroy attributes that were marked as stroke only in SculptAttributeParams. */
+void BKE_sculpt_attributes_destroy_temporary_stroke(struct Object *ob);
+
+BLI_INLINE void *BKE_sculpt_vertex_attr_get(const PBVHVertRef vertex, const SculptAttribute *attr)
+{
+ if (attr->data) {
+ char *p = (char *)attr->data;
+ int idx = (int)vertex.i;
+
+ if (attr->data_for_bmesh) {
+ BMElem *v = (BMElem *)vertex.i;
+ idx = v->head.index;
+ }
+
+ return p + attr->elem_size * (int)idx;
+ }
+ else {
+ BMElem *v = (BMElem *)vertex.i;
+ return BM_ELEM_CD_GET_VOID_P(v, attr->bmesh_cd_offset);
+ }
+
+ return NULL;
+}
+
+BLI_INLINE void *BKE_sculpt_face_attr_get(const PBVHFaceRef vertex, const SculptAttribute *attr)
+{
+ if (attr->data) {
+ char *p = (char *)attr->data;
+ int idx = (int)vertex.i;
+
+ if (attr->data_for_bmesh) {
+ BMElem *v = (BMElem *)vertex.i;
+ idx = v->head.index;
+ }
+
+ return p + attr->elem_size * (int)idx;
+ }
+ else {
+ BMElem *v = (BMElem *)vertex.i;
+ return BM_ELEM_CD_GET_VOID_P(v, attr->bmesh_cd_offset);
+ }
+
+ return NULL;
+}
/**
* Create new color layer on object if it doesn't have one and if experimental feature set has
@@ -697,44 +854,39 @@ void BKE_sculpt_update_object_after_eval(struct Depsgraph *depsgraph, struct Obj
struct MultiresModifierData *BKE_sculpt_multires_active(const struct Scene *scene,
struct Object *ob);
int *BKE_sculpt_face_sets_ensure(struct Mesh *mesh);
-int BKE_sculpt_mask_layers_ensure(struct Object *ob, struct MultiresModifierData *mmd);
-void BKE_sculpt_toolsettings_data_ensure(struct Scene *scene);
-
-struct PBVH *BKE_sculpt_object_pbvh_ensure(struct Depsgraph *depsgraph, struct Object *ob);
-
-void BKE_sculpt_bvh_update_from_ccg(struct PBVH *pbvh, struct SubdivCCG *subdiv_ccg);
-
/**
- * This ensure that all elements in the mesh (both vertices and grids) have their visibility
- * updated according to the face sets.
+ * Create the attribute used to store face visibility and retrieve its data.
+ * Note that changes to the face visibility have to be propagated to other domains
+ * (see #SCULPT_visibility_sync_all_from_faces).
*/
-void BKE_sculpt_sync_face_set_visibility(struct Mesh *mesh, struct SubdivCCG *subdiv_ccg);
+bool *BKE_sculpt_hide_poly_ensure(struct Mesh *mesh);
/**
- * Individual function to sync the Face Set visibility to mesh and grids.
+ * Ensures a mask layer exists. If depsgraph and bmain are non-null,
+ * a mask doesn't exist and the object has a multi-resolution modifier
+ * then the scene depsgraph will be evaluated to update the runtime
+ * subdivision data.
+ *
+ * \note always call *before* #BKE_sculpt_update_object_for_edit.
*/
-void BKE_sculpt_sync_face_sets_visibility_to_base_mesh(struct Mesh *mesh);
-void BKE_sculpt_sync_face_sets_visibility_to_grids(struct Mesh *mesh,
- struct SubdivCCG *subdiv_ccg);
+int BKE_sculpt_mask_layers_ensure(struct Depsgraph *depsgraph,
+ struct Main *bmain,
+ struct Object *ob,
+ struct MultiresModifierData *mmd);
+void BKE_sculpt_toolsettings_data_ensure(struct Scene *scene);
-/**
- * If a face set layer exists, initialize its visibility (sign) from the mesh's hidden values.
- */
-void BKE_sculpt_face_sets_update_from_base_mesh_visibility(struct Mesh *mesh);
+struct PBVH *BKE_sculpt_object_pbvh_ensure(struct Depsgraph *depsgraph, struct Object *ob);
-/**
- * Makes sculpt data consistent with other data on the mesh.
- *
- * \note IDs are expected to be original ones here, and calling code should ensure it updates its
- * depsgraph properly after calling this function if it needs up-to-date evaluated data.
- */
-void BKE_sculpt_ensure_orig_mesh_data(struct Object *object);
+void BKE_sculpt_bvh_update_from_ccg(struct PBVH *pbvh, struct SubdivCCG *subdiv_ccg);
+
+void BKE_sculpt_ensure_orig_mesh_data(struct Scene *scene, struct Object *object);
+void BKE_sculpt_sync_face_visibility_to_grids(struct Mesh *mesh, struct SubdivCCG *subdiv_ccg);
/**
* Test if PBVH can be used directly for drawing, which is faster than
* drawing the mesh and all updates that come with it.
*/
-bool BKE_sculptsession_use_pbvh_draw(const struct Object *ob, const struct View3D *v3d);
+bool BKE_sculptsession_use_pbvh_draw(const struct Object *ob, const struct RegionView3D *rv3d);
enum {
SCULPT_MASK_LAYER_CALC_VERT = (1 << 0),
@@ -770,6 +922,8 @@ bool BKE_paint_canvas_image_get(struct PaintModeSettings *settings,
struct ImageUser **r_image_user);
int BKE_paint_canvas_uvmap_layer_index_get(const struct PaintModeSettings *settings,
struct Object *ob);
+void BKE_sculpt_check_cavity_curves(struct Sculpt *sd);
+struct CurveMapping *BKE_sculpt_default_cavity_curve(void);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index a797aef73f6..05b9aca7544 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -291,7 +291,11 @@ void psys_set_current_num(struct Object *ob, int index);
/* UNUSED */
// struct Object *psys_find_object(struct Scene *scene, struct ParticleSystem *psys);
-struct LatticeDeformData *psys_create_lattice_deform_data(struct ParticleSimulationData *sim);
+/**
+ * Initialize/free data for particle simulation evaluation.
+ */
+void psys_sim_data_init(struct ParticleSimulationData *sim);
+void psys_sim_data_free(struct ParticleSimulationData *sim);
/**
* For a given evaluated particle system get its original.
@@ -416,7 +420,7 @@ void psys_get_particle_on_path(struct ParticleSimulationData *sim,
struct ParticleKey *state,
bool vel);
/**
- * Gets particle's state at a time.
+ * Gets particle's state at a time. Must call psys_sim_data_init before this.
* \return true if particle exists and can be seen and false if not.
*/
bool psys_get_particle_state(struct ParticleSimulationData *sim,
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 403f3a31ba0..b375d69b61c 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -16,6 +16,7 @@
/* For embedding CCGKey in iterator. */
#include "BKE_attribute.h"
#include "BKE_ccg.h"
+#include "DNA_customdata_types.h"
#ifdef __cplusplus
extern "C" {
@@ -27,7 +28,6 @@ struct CCGElem;
struct CCGKey;
struct CustomData;
struct DMFlagMat;
-struct GPU_PBVH_Buffers;
struct IsectRayPrecalc;
struct MLoop;
struct MLoopTri;
@@ -36,7 +36,9 @@ struct MVert;
struct Mesh;
struct MeshElemMap;
struct PBVH;
+struct PBVHBatches;
struct PBVHNode;
+struct PBVH_GPU_Args;
struct SubdivCCG;
struct TaskParallelSettings;
struct Image;
@@ -98,6 +100,12 @@ typedef struct PBVHPixelsNode {
void *node_data;
} PBVHPixelsNode;
+typedef struct PBVHAttrReq {
+ char name[MAX_CUSTOMDATA_LAYER_NAME];
+ eAttrDomain domain;
+ eCustomDataType type;
+} PBVHAttrReq;
+
typedef enum {
PBVH_Leaf = 1 << 0,
@@ -117,6 +125,7 @@ typedef enum {
PBVH_UpdateTopology = 1 << 13,
PBVH_UpdateColor = 1 << 14,
PBVH_RebuildPixels = 1 << 15,
+ PBVH_TopologyUpdated = 1 << 16, /* Used internally by pbvh_bmesh.c */
} PBVHNodeFlags;
@@ -230,7 +239,7 @@ typedef void (*BKE_pbvh_SearchNearestCallback)(PBVHNode *node, void *data, float
/* Building */
-PBVH *BKE_pbvh_new(void);
+PBVH *BKE_pbvh_new(PBVHType type);
/**
* Do a full rebuild with on Mesh data structure.
*
@@ -257,7 +266,9 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
struct CCGKey *key,
void **gridfaces,
struct DMFlagMat *flagmats,
- unsigned int **grid_hidden);
+ unsigned int **grid_hidden,
+ struct Mesh *me,
+ struct SubdivCCG *subdiv_ccg);
/**
* Build a PBVH from a BMesh.
*/
@@ -268,6 +279,8 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
int cd_vert_node_offset,
int cd_face_node_offset);
+void BKE_pbvh_update_bmesh_offsets(PBVH *pbvh, int cd_vert_node_offset, int cd_face_node_offset);
+
void BKE_pbvh_build_pixels(PBVH *pbvh,
struct Mesh *mesh,
struct Image *image,
@@ -346,9 +359,13 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
bool update_only_visible,
PBVHFrustumPlanes *update_frustum,
PBVHFrustumPlanes *draw_frustum,
- void (*draw_fn)(void *user_data, struct GPU_PBVH_Buffers *buffers),
+ void (*draw_fn)(void *user_data,
+ struct PBVHBatches *batches,
+ struct PBVH_GPU_Args *args),
void *user_data,
- bool full_render);
+ bool full_render,
+ PBVHAttrReq *attrs,
+ int attrs_num);
void BKE_pbvh_draw_debug_cb(PBVH *pbvh,
void (*draw_fn)(PBVHNode *node,
@@ -380,8 +397,6 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
int totgrid,
int gridsize);
-void BKE_pbvh_sync_face_sets_to_grids(PBVH *pbvh);
-
/**
* Multi-res level, only valid for type == #PBVH_GRIDS.
*/
@@ -472,7 +487,10 @@ struct GSet *BKE_pbvh_bmesh_node_faces(PBVHNode *node);
*
* Skips triangles that are hidden.
*/
-void BKE_pbvh_bmesh_node_save_orig(struct BMesh *bm, PBVHNode *node);
+void BKE_pbvh_bmesh_node_save_orig(struct BMesh *bm,
+ struct BMLog *log,
+ PBVHNode *node,
+ bool use_original);
void BKE_pbvh_bmesh_after_stroke(PBVH *pbvh);
/* Update Bounding Box/Redraw and clear flags. */
@@ -487,10 +505,17 @@ void BKE_pbvh_grids_update(PBVH *pbvh,
struct CCGElem **grids,
void **gridfaces,
struct DMFlagMat *flagmats,
- unsigned int **grid_hidden);
+ unsigned int **grid_hidden,
+ struct CCGKey *key);
void BKE_pbvh_subdiv_cgg_set(PBVH *pbvh, struct SubdivCCG *subdiv_ccg);
void BKE_pbvh_face_sets_set(PBVH *pbvh, int *face_sets);
+/**
+ * If an operation causes the hide status stored in the mesh to change, this must be called
+ * to update the references to those attributes, since they are only added when necessary.
+ */
+void BKE_pbvh_update_hide_attributes_from_mesh(PBVH *pbvh);
+
void BKE_pbvh_face_sets_color_set(PBVH *pbvh, int seed, int color_default);
void BKE_pbvh_respect_hide_set(PBVH *pbvh, bool respect_hide);
@@ -645,7 +670,8 @@ void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot);
void BKE_pbvh_node_get_bm_orco_data(PBVHNode *node,
int (**r_orco_tris)[3],
int *r_orco_tris_num,
- float (**r_orco_coords)[3]);
+ float (**r_orco_coords)[3],
+ struct BMVert ***r_orco_verts);
/**
* \note doing a full search on all vertices here seems expensive,
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index 48402123365..4331a25c112 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -285,7 +285,7 @@ void BKE_ptcache_ids_from_object(struct ListBase *lb,
struct Scene *scene,
int duplis);
-/****************** Query funcs ****************************/
+/****************** Query functions ****************************/
/**
* Check whether object has a point cache.
@@ -293,6 +293,7 @@ void BKE_ptcache_ids_from_object(struct ListBase *lb,
bool BKE_ptcache_object_has(struct Scene *scene, struct Object *ob, int duplis);
/************ ID specific functions ************************/
+
void BKE_ptcache_id_clear(PTCacheID *id, int mode, unsigned int cfra);
bool BKE_ptcache_id_exist(PTCacheID *id, int cfra);
int BKE_ptcache_id_reset(struct Scene *scene, PTCacheID *id, int mode);
diff --git a/source/blender/blenkernel/BKE_pointcloud.h b/source/blender/blenkernel/BKE_pointcloud.h
index 62a1824d844..d6367ac5a61 100644
--- a/source/blender/blenkernel/BKE_pointcloud.h
+++ b/source/blender/blenkernel/BKE_pointcloud.h
@@ -25,11 +25,14 @@ extern const char *POINTCLOUD_ATTR_RADIUS;
void *BKE_pointcloud_add(struct Main *bmain, const char *name);
void *BKE_pointcloud_add_default(struct Main *bmain, const char *name);
struct PointCloud *BKE_pointcloud_new_nomain(int totpoint);
+void BKE_pointcloud_nomain_to_pointcloud(struct PointCloud *pointcloud_src,
+ struct PointCloud *pointcloud_dst,
+ bool take_ownership);
struct BoundBox *BKE_pointcloud_boundbox_get(struct Object *ob);
bool BKE_pointcloud_minmax(const struct PointCloud *pointcloud, float r_min[3], float r_max[3]);
-bool BKE_pointcloud_customdata_required(const struct PointCloud *pointcloud, const char *name);
+bool BKE_pointcloud_attribute_required(const struct PointCloud *pointcloud, const char *name);
/* Dependency Graph */
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 61fc883fe7f..c6ccd4493fe 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -97,7 +97,7 @@ int BKE_scene_base_iter_next(struct Depsgraph *depsgraph,
struct Base **base,
struct Object **ob);
-void BKE_scene_base_flag_to_objects(struct ViewLayer *view_layer);
+void BKE_scene_base_flag_to_objects(const struct Scene *scene, struct ViewLayer *view_layer);
/**
* Synchronize object base flags
*
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 3691ab677b7..a86953f35cc 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -108,12 +108,29 @@ typedef struct SpaceType {
void (*space_subtype_set)(struct ScrArea *area, int value);
void (*space_subtype_item_extend)(struct bContext *C, EnumPropertyItem **item, int *totitem);
+ /**
+ * Update pointers for all structs directly owned by this space.
+ */
+ void (*blend_read_data)(struct BlendDataReader *reader, struct SpaceLink *space_link);
+
+ /**
+ * Update pointers to other id data blocks.
+ */
+ void (*blend_read_lib)(struct BlendLibReader *reader,
+ struct ID *parent_id,
+ struct SpaceLink *space_link);
+
+ /**
+ * Write all structs that should be saved in a .blend file.
+ */
+ void (*blend_write)(struct BlendWriter *writer, struct SpaceLink *space_link);
+
/* region type definitions */
ListBase regiontypes;
/* read and write... */
- /* default keymaps to add */
+ /** Default key-maps to add. */
int keymapflag;
} SpaceType;
@@ -368,6 +385,7 @@ typedef struct MenuType {
bool (*poll)(const struct bContext *C, struct MenuType *mt);
/* draw entirely, view changes should be handled here */
void (*draw)(const struct bContext *C, struct Menu *menu);
+ void (*listener)(const wmRegionListenerParams *params);
/* RNA integration */
ExtensionRNA rna_ext;
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index 11c37a74a54..f0bb530e32b 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -170,7 +170,7 @@ int BKE_sound_scene_playing(struct Scene *scene);
void BKE_sound_free_waveform(struct bSound *sound);
-void BKE_sound_read_waveform(struct Main *bmain, struct bSound *sound, short *stop);
+void BKE_sound_read_waveform(struct Main *bmain, struct bSound *sound, bool *stop);
void BKE_sound_update_scene(struct Depsgraph *depsgraph, struct Scene *scene);
diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh
deleted file mode 100644
index 27542aa3586..00000000000
--- a/source/blender/blenkernel/BKE_spline.hh
+++ /dev/null
@@ -1,688 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#pragma once
-
-/** \file
- * \ingroup bke
- */
-
-#include <mutex>
-
-#include "DNA_curves_types.h"
-
-#include "BLI_float4x4.hh"
-#include "BLI_generic_virtual_array.hh"
-#include "BLI_math_vec_types.hh"
-#include "BLI_vector.hh"
-
-#include "BKE_attribute.hh"
-#include "BKE_attribute_math.hh"
-
-struct Curve;
-struct Curves;
-struct ListBase;
-
-class Spline;
-using SplinePtr = std::unique_ptr<Spline>;
-
-/**
- * A spline is an abstraction of a single branch-less curve section, its evaluation methods,
- * and data. The spline data itself is just control points and a set of attributes by the set
- * of "evaluated" data is often used instead. Conceptually, the derived vs. original data is
- * an essential distinction. Derived data is usually calculated lazily and cached on the spline.
- *
- * Any derived class of Spline has to manage two things:
- * 1. Interpolating arbitrary attribute data from the control points to evaluated points.
- * 2. Evaluating the positions based on the stored control point data.
- *
- * Beyond that, everything is the base class's responsibility, with minor exceptions. Further
- * evaluation happens in a layer on top of the evaluated points generated by the derived types.
- *
- * There are a few methods to evaluate a spline:
- * 1. #evaluated_positions and #interpolate_to_evaluated give data for the initial
- * evaluated points, depending on the resolution.
- * 2. #lookup_evaluated_factor and #lookup_evaluated_factor are meant for one-off lookups
- * along the length of a curve.
- * 3. #sample_uniform_index_factors returns an array that stores uniform-length samples
- * along the spline which can be used to interpolate data from method 1.
- *
- * Commonly used evaluated data is stored in caches on the spline itself so that operations on
- * splines don't need to worry about taking ownership of evaluated data when they don't need to.
- */
-class Spline {
- public:
- NormalMode normal_mode = NORMAL_MODE_MINIMUM_TWIST;
-
- blender::bke::CustomDataAttributes attributes;
-
- protected:
- CurveType type_;
- bool is_cyclic_ = false;
-
- /** Direction of the spline at each evaluated point. */
- mutable blender::Vector<blender::float3> evaluated_tangents_cache_;
- mutable std::mutex tangent_cache_mutex_;
- mutable bool tangent_cache_dirty_ = true;
-
- /** Normal direction vectors for each evaluated point. */
- mutable blender::Vector<blender::float3> evaluated_normals_cache_;
- mutable std::mutex normal_cache_mutex_;
- mutable bool normal_cache_dirty_ = true;
-
- /** Accumulated lengths along the evaluated points. */
- mutable blender::Vector<float> evaluated_lengths_cache_;
- mutable std::mutex length_cache_mutex_;
- mutable bool length_cache_dirty_ = true;
-
- public:
- virtual ~Spline() = default;
- Spline(const CurveType type) : type_(type)
- {
- }
- Spline(Spline &other) : attributes(other.attributes), type_(other.type_)
- {
- copy_base_settings(other, *this);
- }
-
- /**
- * Return a new spline with the same data, settings, and attributes.
- */
- SplinePtr copy() const;
- /**
- * Return a new spline with the same type and settings like "cyclic", but without any data.
- */
- SplinePtr copy_only_settings() const;
- /**
- * The same as #copy, but skips copying dynamic attributes to the new spline.
- */
- SplinePtr copy_without_attributes() const;
- static void copy_base_settings(const Spline &src, Spline &dst);
-
- CurveType type() const;
-
- /** Return the number of control points. */
- virtual int size() const = 0;
- int segments_num() const;
- bool is_cyclic() const;
- void set_cyclic(bool value);
-
- virtual void resize(int size) = 0;
- virtual blender::MutableSpan<blender::float3> positions() = 0;
- virtual blender::Span<blender::float3> positions() const = 0;
- virtual blender::MutableSpan<float> radii() = 0;
- virtual blender::Span<float> radii() const = 0;
- virtual blender::MutableSpan<float> tilts() = 0;
- virtual blender::Span<float> tilts() const = 0;
-
- virtual void translate(const blender::float3 &translation);
- virtual void transform(const blender::float4x4 &matrix);
-
- /**
- * Change the direction of the spline (switch the start and end) without changing its shape.
- */
- void reverse();
-
- /**
- * Mark all caches for re-computation. This must be called after any operation that would
- * change the generated positions, tangents, normals, mapping, etc. of the evaluated points.
- */
- virtual void mark_cache_invalid() = 0;
- virtual int evaluated_points_num() const = 0;
- int evaluated_edges_num() const;
-
- float length() const;
-
- virtual blender::Span<blender::float3> evaluated_positions() const = 0;
-
- /**
- * Return non-owning access to the cache of accumulated lengths along the spline. Each item is
- * the length of the subsequent segment, i.e. the first value is the length of the first segment
- * rather than 0. This calculation is rather trivial, and only depends on the evaluated
- * positions. However, the results are used often, and it is necessarily single threaded, so it
- * is cached.
- */
- blender::Span<float> evaluated_lengths() const;
- /**
- * Return non-owning access to the direction of the curve at each evaluated point.
- */
- blender::Span<blender::float3> evaluated_tangents() const;
- /**
- * Return non-owning access to the direction vectors perpendicular to the tangents at every
- * evaluated point. The method used to generate the normal vectors depends on Spline.normal_mode.
- */
- blender::Span<blender::float3> evaluated_normals() const;
-
- void bounds_min_max(blender::float3 &min, blender::float3 &max, bool use_evaluated) const;
-
- struct LookupResult {
- /**
- * The index of the evaluated point before the result location. In other words, the index of
- * the edge that the result lies on. If the sampled factor/length is the very end of the
- * spline, this will be the second to last index, if it's the very beginning, this will be 0.
- */
- int evaluated_index;
- /**
- * The index of the evaluated point after the result location, accounting for wrapping when
- * the spline is cyclic. If the sampled factor/length is the very end of the spline, this will
- * be the last index (#evaluated_points_num - 1).
- */
- int next_evaluated_index;
- /**
- * The portion of the way from the evaluated point at #evaluated_index to the next point.
- * If the sampled factor/length is the very end of the spline, this will be the 1.0f
- */
- float factor;
- };
- /**
- * Find the position on the evaluated spline at the given portion of the total length.
- * The return value is the indices of the two neighboring points at that location and the
- * factor between them, which can be used to look up any attribute on the evaluated points.
- * \note This does not support extrapolation.
- */
- LookupResult lookup_evaluated_factor(float factor) const;
- /**
- * The same as #lookup_evaluated_factor, but looks up a length directly instead of
- * a portion of the total.
- */
- LookupResult lookup_evaluated_length(float length) const;
-
- /**
- * Return an array of evenly spaced samples along the length of the spline. The samples are
- * indices and factors to the next index encoded in floats. The logic for converting from the
- * float values to interpolation data is in #lookup_data_from_index_factor.
- */
- blender::Array<float> sample_uniform_index_factors(int samples_num) const;
- LookupResult lookup_data_from_index_factor(float index_factor) const;
-
- /**
- * Sample any input data with a value for each evaluated point (already interpolated to evaluated
- * points) to arbitrary parameters in between the evaluated points. The interpolation is quite
- * simple, but this handles the cyclic and end point special cases.
- */
- void sample_with_index_factors(const blender::GVArray &src,
- blender::Span<float> index_factors,
- blender::GMutableSpan dst) const;
- template<typename T>
- void sample_with_index_factors(const blender::VArray<T> &src,
- blender::Span<float> index_factors,
- blender::MutableSpan<T> dst) const
- {
- this->sample_with_index_factors(
- blender::GVArray(src), index_factors, blender::GMutableSpan(dst));
- }
- template<typename T>
- void sample_with_index_factors(blender::Span<T> src,
- blender::Span<float> index_factors,
- blender::MutableSpan<T> dst) const
- {
- this->sample_with_index_factors(blender::VArray<T>::ForSpan(src), index_factors, dst);
- }
-
- /**
- * Interpolate a virtual array of data with the size of the number of control points to the
- * evaluated points. For poly splines, the lifetime of the returned virtual array must not
- * exceed the lifetime of the input data.
- */
- virtual blender::GVArray interpolate_to_evaluated(const blender::GVArray &src) const = 0;
- blender::GVArray interpolate_to_evaluated(blender::GSpan data) const;
- template<typename T> blender::VArray<T> interpolate_to_evaluated(blender::Span<T> data) const
- {
- return this->interpolate_to_evaluated(blender::GSpan(data)).typed<T>();
- }
-
- protected:
- virtual void correct_end_tangents() const = 0;
- virtual void copy_settings(Spline &dst) const = 0;
- virtual void copy_data(Spline &dst) const = 0;
- virtual void reverse_impl() = 0;
-};
-
-/**
- * A Bezier spline is made up of a many curve segments, possibly achieving continuity of curvature
- * by constraining the alignment of curve handles. Evaluation stores the positions and a map of
- * factors and indices in a list of floats, which is then used to interpolate any other data.
- */
-class BezierSpline final : public Spline {
- blender::Vector<blender::float3> positions_;
- blender::Vector<float> radii_;
- blender::Vector<float> tilts_;
- int resolution_;
-
- blender::Vector<int8_t> handle_types_left_;
- blender::Vector<int8_t> handle_types_right_;
-
- /* These are mutable to allow lazy recalculation of #Auto and #Vector handle positions. */
- mutable blender::Vector<blender::float3> handle_positions_left_;
- mutable blender::Vector<blender::float3> handle_positions_right_;
-
- mutable std::mutex auto_handle_mutex_;
- mutable bool auto_handles_dirty_ = true;
-
- /** Start index in evaluated points array for every control point. */
- mutable blender::Vector<int> offset_cache_;
- mutable std::mutex offset_cache_mutex_;
- mutable bool offset_cache_dirty_ = true;
-
- /** Cache of evaluated positions. */
- mutable blender::Vector<blender::float3> evaluated_position_cache_;
- mutable std::mutex position_cache_mutex_;
- mutable bool position_cache_dirty_ = true;
-
- /** Cache of "index factors" based calculated from the evaluated positions. */
- mutable blender::Vector<float> evaluated_mapping_cache_;
- mutable std::mutex mapping_cache_mutex_;
- mutable bool mapping_cache_dirty_ = true;
-
- public:
- BezierSpline() : Spline(CURVE_TYPE_BEZIER)
- {
- }
- BezierSpline(const BezierSpline &other)
- : Spline((Spline &)other),
- positions_(other.positions_),
- radii_(other.radii_),
- tilts_(other.tilts_),
- resolution_(other.resolution_),
- handle_types_left_(other.handle_types_left_),
- handle_types_right_(other.handle_types_right_),
- handle_positions_left_(other.handle_positions_left_),
- handle_positions_right_(other.handle_positions_right_)
- {
- }
-
- int size() const final;
- int resolution() const;
- void set_resolution(int value);
-
- void resize(int size) final;
- blender::MutableSpan<blender::float3> positions() final;
- blender::Span<blender::float3> positions() const final;
- blender::MutableSpan<float> radii() final;
- blender::Span<float> radii() const final;
- blender::MutableSpan<float> tilts() final;
- blender::Span<float> tilts() const final;
- blender::Span<int8_t> handle_types_left() const;
- blender::MutableSpan<int8_t> handle_types_left();
- blender::Span<blender::float3> handle_positions_left() const;
- /**
- * Get writable access to the handle position.
- *
- * \param write_only: pass true for an uninitialized spline, this prevents accessing
- * uninitialized memory while auto-generating handles.
- */
- blender::MutableSpan<blender::float3> handle_positions_left(bool write_only = false);
- blender::Span<int8_t> handle_types_right() const;
- blender::MutableSpan<int8_t> handle_types_right();
- blender::Span<blender::float3> handle_positions_right() const;
- /**
- * Get writable access to the handle position.
- *
- * \param write_only: pass true for an uninitialized spline, this prevents accessing
- * uninitialized memory while auto-generating handles.
- */
- blender::MutableSpan<blender::float3> handle_positions_right(bool write_only = false);
- /**
- * Recalculate all #Auto and #Vector handles with positions automatically
- * derived from the neighboring control points.
- */
- void ensure_auto_handles() const;
-
- void translate(const blender::float3 &translation) override;
- void transform(const blender::float4x4 &matrix) override;
-
- /**
- * Set positions for the right handle of the control point, ensuring that
- * aligned handles stay aligned. Has no effect for auto and vector type handles.
- */
- void set_handle_position_right(int index, const blender::float3 &value);
- /**
- * Set positions for the left handle of the control point, ensuring that
- * aligned handles stay aligned. Has no effect for auto and vector type handles.
- */
- void set_handle_position_left(int index, const blender::float3 &value);
-
- bool point_is_sharp(int index) const;
-
- void mark_cache_invalid() final;
- int evaluated_points_num() const final;
-
- /**
- * Returns access to a cache of offsets into the evaluated point array for each control point.
- * While most control point edges generate the number of edges specified by the resolution,
- * vector segments only generate one edge.
- *
- * \note The length of the result is one greater than the number of points, so that the last item
- * is the total number of evaluated points. This is useful to avoid recalculating the size of the
- * last segment everywhere.
- */
- blender::Span<int> control_point_offsets() const;
- /**
- * Returns non-owning access to an array of values containing the information necessary to
- * interpolate values from the original control points to evaluated points. The control point
- * index is the integer part of each value, and the factor used for interpolating to the next
- * control point is the remaining fractional part.
- */
- blender::Span<float> evaluated_mappings() const;
- blender::Span<blender::float3> evaluated_positions() const final;
- struct InterpolationData {
- int control_point_index;
- int next_control_point_index;
- /**
- * Linear interpolation weight between the two indices, from 0 to 1.
- * Higher means closer to next control point.
- */
- float factor;
- };
- /**
- * Convert the data encoded in #evaulated_mappings into its parts-- the information necessary
- * to interpolate data from control points to evaluated points between them. The next control
- * point index result will not overflow the size of the control point vectors.
- */
- InterpolationData interpolation_data_from_index_factor(float index_factor) const;
-
- virtual blender::GVArray interpolate_to_evaluated(const blender::GVArray &src) const override;
-
- void evaluate_segment(int index,
- int next_index,
- blender::MutableSpan<blender::float3> positions) const;
- /**
- * \warning This functional assumes that the spline has more than one point.
- */
- bool segment_is_vector(int start_index) const;
-
- /** See comment and diagram for #calculate_segment_insertion. */
- struct InsertResult {
- blender::float3 handle_prev;
- blender::float3 left_handle;
- blender::float3 position;
- blender::float3 right_handle;
- blender::float3 handle_next;
- };
- /**
- * De Casteljau Bezier subdivision.
- * \param index: The index of the segment's start control point.
- * \param next_index: The index of the control point at the end of the segment. Could be 0,
- * if the spline is cyclic.
- * \param parameter: The factor along the segment, between 0 and 1. Note that this is used
- * directly by the calculation, it doesn't correspond to a portion of the evaluated length.
- *
- * <pre>
- * handle_prev handle_next
- * x----------------x
- * / \
- * / x---O---x \
- * / result \
- * / \
- * O O
- * point_prev point_next
- * </pre>
- */
- InsertResult calculate_segment_insertion(int index, int next_index, float parameter);
-
- private:
- /**
- * If the spline is not cyclic, the direction for the first and last points is just the
- * direction formed by the corresponding handles and control points. In the unlikely situation
- * that the handles define a zero direction, fallback to using the direction defined by the
- * first and last evaluated segments already calculated in #Spline::evaluated_tangents().
- */
- void correct_end_tangents() const final;
- void copy_settings(Spline &dst) const final;
- void copy_data(Spline &dst) const final;
-
- protected:
- void reverse_impl() override;
-};
-
-/**
- * Data for Non-Uniform Rational B-Splines. The mapping from control points to evaluated points is
- * influenced by a vector of knots, weights for each point, and the order of the spline. Every
- * mapping of data to evaluated points is handled the same way, but the positions are cached in
- * the spline.
- */
-class NURBSpline final : public Spline {
- public:
- /** Method used to recalculate the knots vector when points are added or removed. */
- KnotsMode knots_mode;
-
- struct BasisCache {
- /**
- * For each evaluated point, the weight for all control points that influences it.
- * The vector's size is the evaluated point count multiplied by the spline's order.
- */
- blender::Vector<float> weights;
- /**
- * An offset for the start of #weights: the first control point index with a non-zero weight.
- */
- blender::Vector<int> start_indices;
- };
-
- private:
- blender::Vector<blender::float3> positions_;
- blender::Vector<float> radii_;
- blender::Vector<float> tilts_;
- blender::Vector<float> weights_;
- int resolution_;
- /**
- * Defines the number of nearby control points that influence a given evaluated point. Higher
- * orders give smoother results. The number of control points must be greater than or equal to
- * this value.
- */
- uint8_t order_;
-
- /**
- * Determines where and how the control points affect the evaluated points. The length should
- * always be the value returned by #knots_num(), and each value should be greater than or equal
- * to the previous. Only invalidated when a point is added or removed.
- */
- mutable blender::Vector<float> knots_;
- mutable std::mutex knots_mutex_;
- mutable bool knots_dirty_ = true;
-
- /** Cache of control point influences on each evaluated point. */
- mutable BasisCache basis_cache_;
- mutable std::mutex basis_cache_mutex_;
- mutable bool basis_cache_dirty_ = true;
-
- /**
- * Cache of position data calculated from the basis cache. Though it is interpolated
- * in the same way as any other attribute, it is stored to save unnecessary recalculation.
- */
- mutable blender::Vector<blender::float3> evaluated_position_cache_;
- mutable std::mutex position_cache_mutex_;
- mutable bool position_cache_dirty_ = true;
-
- public:
- NURBSpline() : Spline(CURVE_TYPE_NURBS)
- {
- }
- NURBSpline(const NURBSpline &other)
- : Spline((Spline &)other),
- knots_mode(other.knots_mode),
- positions_(other.positions_),
- radii_(other.radii_),
- tilts_(other.tilts_),
- weights_(other.weights_),
- resolution_(other.resolution_),
- order_(other.order_)
- {
- }
-
- int size() const final;
- int resolution() const;
- void set_resolution(int value);
- uint8_t order() const;
- void set_order(uint8_t value);
-
- bool check_valid_num_and_order() const;
- int knots_num() const;
-
- void resize(int size) final;
- blender::MutableSpan<blender::float3> positions() final;
- blender::Span<blender::float3> positions() const final;
- blender::MutableSpan<float> radii() final;
- blender::Span<float> radii() const final;
- blender::MutableSpan<float> tilts() final;
- blender::Span<float> tilts() const final;
- blender::Span<float> knots() const;
-
- blender::MutableSpan<float> weights();
- blender::Span<float> weights() const;
-
- void mark_cache_invalid() final;
- int evaluated_points_num() const final;
-
- blender::Span<blender::float3> evaluated_positions() const final;
-
- blender::GVArray interpolate_to_evaluated(const blender::GVArray &src) const final;
-
- protected:
- void correct_end_tangents() const final;
- void copy_settings(Spline &dst) const final;
- void copy_data(Spline &dst) const final;
- void reverse_impl() override;
-
- void calculate_knots() const;
- const BasisCache &calculate_basis_cache() const;
-};
-
-/**
- * A Poly spline is like a Bezier spline with a resolution of one. The main reason to distinguish
- * the two is for reduced complexity and increased performance, since interpolating data to control
- * points does not change it.
- *
- * Poly spline code is very simple, since it doesn't do anything that the base #Spline doesn't
- * handle. Mostly it just worries about storing the data used by the base class.
- */
-class PolySpline final : public Spline {
- blender::Vector<blender::float3> positions_;
- blender::Vector<float> radii_;
- blender::Vector<float> tilts_;
-
- public:
- PolySpline() : Spline(CURVE_TYPE_POLY)
- {
- }
- PolySpline(const PolySpline &other)
- : Spline((Spline &)other),
- positions_(other.positions_),
- radii_(other.radii_),
- tilts_(other.tilts_)
- {
- }
-
- int size() const final;
-
- void resize(int size) final;
- blender::MutableSpan<blender::float3> positions() final;
- blender::Span<blender::float3> positions() const final;
- blender::MutableSpan<float> radii() final;
- blender::Span<float> radii() const final;
- blender::MutableSpan<float> tilts() final;
- blender::Span<float> tilts() const final;
-
- void mark_cache_invalid() final;
- int evaluated_points_num() const final;
-
- blender::Span<blender::float3> evaluated_positions() const final;
-
- /**
- * Poly spline interpolation from control points to evaluated points is a special case, since
- * the result data is the same as the input data. This function returns a #GVArray that points to
- * the original data. Therefore the lifetime of the returned virtual array must not be longer
- * than the source data.
- */
- blender::GVArray interpolate_to_evaluated(const blender::GVArray &src) const final;
-
- protected:
- void correct_end_tangents() const final;
- void copy_settings(Spline &dst) const final;
- void copy_data(Spline &dst) const final;
- void reverse_impl() override;
-};
-
-/**
- * A collection of #Spline objects with the same attribute types and names. Most data and
- * functionality is in splines, but this contains some helpers for working with them as a group.
- *
- * \note A #CurveEval corresponds to the #Curve object data. The name is different for clarity,
- * since more of the data is stored in the splines, but also just to be different than the name in
- * DNA.
- */
-struct CurveEval {
- private:
- blender::Vector<SplinePtr> splines_;
-
- public:
- blender::bke::CustomDataAttributes attributes;
-
- CurveEval() = default;
- CurveEval(const CurveEval &other) : attributes(other.attributes)
- {
- for (const SplinePtr &spline : other.splines()) {
- this->add_spline(spline->copy());
- }
- }
-
- blender::Span<SplinePtr> splines() const;
- blender::MutableSpan<SplinePtr> splines();
- /**
- * \return True if the curve contains a spline with the given type.
- *
- * \note If you are looping over all of the splines in the same scope anyway,
- * it's better to avoid calling this function, in case there are many splines.
- */
- bool has_spline_with_type(const CurveType type) const;
-
- void resize(int size);
- /**
- * \warning Call #reallocate on the spline's attributes after adding all splines.
- */
- void add_spline(SplinePtr spline);
- void add_splines(blender::MutableSpan<SplinePtr> splines);
- void remove_splines(blender::IndexMask mask);
-
- void translate(const blender::float3 &translation);
- void transform(const blender::float4x4 &matrix);
- bool bounds_min_max(blender::float3 &min, blender::float3 &max, bool use_evaluated) const;
-
- blender::bke::MutableAttributeAccessor attributes_for_write();
-
- /**
- * Return the start indices for each of the curve spline's control points, if they were part
- * of a flattened array. This can be used to facilitate parallelism by avoiding the need to
- * accumulate an offset while doing more complex calculations.
- *
- * \note The result is one longer than the spline count; the last element is the total size.
- */
- blender::Array<int> control_point_offsets() const;
- /**
- * Exactly like #control_point_offsets, but uses the number of evaluated points instead.
- */
- blender::Array<int> evaluated_point_offsets() const;
- /**
- * Return the accumulated length at the start of every spline in the curve.
- * \note The result is one longer than the spline count; the last element is the total length.
- */
- blender::Array<float> accumulated_spline_lengths() const;
-
- float total_length() const;
- int total_control_point_num() const;
-
- void mark_cache_invalid();
-
- /**
- * Check the invariants that curve control point attributes should always uphold, necessary
- * because attributes are stored on splines rather than in a flat array on the curve:
- * - The same set of attributes exists on every spline.
- * - Attributes with the same name have the same type on every spline.
- * - Attributes are in the same order on every spline.
- */
- void assert_valid_point_attributes() const;
-};
-
-std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &curve,
- const ListBase &nurbs_list);
-std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve);
-std::unique_ptr<CurveEval> curves_to_curve_eval(const Curves &curves);
-Curves *curve_eval_to_curves(const CurveEval &curve_eval);
diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h
index 486c9430279..5a6e8cbb64a 100644
--- a/source/blender/blenkernel/BKE_subdiv.h
+++ b/source/blender/blenkernel/BKE_subdiv.h
@@ -307,7 +307,6 @@ BLI_INLINE void BKE_subdiv_rotate_grid_to_quad(
/* Convert Blender edge crease value to OpenSubdiv sharpness. */
BLI_INLINE float BKE_subdiv_crease_to_sharpness_f(float edge_crease);
-BLI_INLINE float BKE_subdiv_crease_to_sharpness_char(char edge_crease);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_subdiv_ccg.h b/source/blender/blenkernel/BKE_subdiv_ccg.h
index b30b707759c..ced7ff2aa71 100644
--- a/source/blender/blenkernel/BKE_subdiv_ccg.h
+++ b/source/blender/blenkernel/BKE_subdiv_ccg.h
@@ -325,6 +325,7 @@ const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG *subdiv_ccg);
const int *BKE_subdiv_ccg_start_face_grid_index_get(const SubdivCCG *subdiv_ccg);
void BKE_subdiv_ccg_grid_hidden_ensure(SubdivCCG *subdiv_ccg, int grid_index);
+void BKE_subdiv_ccg_grid_hidden_free(SubdivCCG *subdiv_ccg, int grid_index);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h
index f32a78c3015..557a71fd06b 100644
--- a/source/blender/blenkernel/BKE_subsurf.h
+++ b/source/blender/blenkernel/BKE_subsurf.h
@@ -11,6 +11,7 @@
/* Thread sync primitives used directly. */
#include "BLI_threads.h"
+#include "BLI_utildefines.h"
#ifdef __cplusplus
extern "C" {
@@ -32,7 +33,7 @@ struct SubsurfModifierData;
/**************************** External *****************************/
-typedef enum {
+typedef enum SubsurfFlags {
SUBSURF_USE_RENDER_PARAMS = 1,
SUBSURF_IS_FINAL_CALC = 2,
SUBSURF_FOR_EDIT_MODE = 4,
@@ -41,6 +42,7 @@ typedef enum {
SUBSURF_USE_GPU_BACKEND = 32,
SUBSURF_IGNORE_SIMPLIFY = 64,
} SubsurfFlags;
+ENUM_OPERATORS(SubsurfFlags, SUBSURF_IGNORE_SIMPLIFY);
struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm,
struct SubsurfModifierData *smd,
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index 89f30ce8ef8..70c1049b5d7 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -657,8 +657,8 @@ void BKE_tracking_reconstruction_context_free(struct MovieReconstructContext *co
* callback in libmv side and passing to an interface.
*/
void BKE_tracking_reconstruction_solve(struct MovieReconstructContext *context,
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress,
char *stats_message,
int message_size);
diff --git a/source/blender/blenkernel/BKE_undo_system.h b/source/blender/blenkernel/BKE_undo_system.h
index f3a929dc5b9..5d1a27f8ba0 100644
--- a/source/blender/blenkernel/BKE_undo_system.h
+++ b/source/blender/blenkernel/BKE_undo_system.h
@@ -75,7 +75,7 @@ typedef struct UndoStep {
/** Some situations require the global state to be stored, edge cases when exiting modes. */
bool use_memfile_step;
/** When this is true, undo/memfile read code is allowed to re-use old data-blocks for unchanged
- * IDs, and existing depsgraphes. This has to be forbidden in some cases (like renamed IDs). */
+ * IDs, and existing depsgraphs. This has to be forbidden in some cases (like renamed IDs). */
bool use_old_bmain_data;
/** For use by undo systems that accumulate changes (mesh-sculpt & image-painting). */
bool is_applied;
diff --git a/source/blender/blenkernel/BKE_viewer_path.h b/source/blender/blenkernel/BKE_viewer_path.h
new file mode 100644
index 00000000000..dfba289531f
--- /dev/null
+++ b/source/blender/blenkernel/BKE_viewer_path.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+/**
+ * A #ViewerPath is a path to data that is viewed/debugged by the user. It is a list of
+ * #ViewerPathElem.
+ *
+ * This is only used for geometry nodes currently. When the user activates a viewer node the
+ * corresponding path contains the following elements:
+ * - Object the viewer is activated on.
+ * - Modifier that contains the corresponding geometry node group.
+ * - Node tree path in case the viewer node is in a nested node group.
+ * - Viewer node name.
+ *
+ * The entire path is necessary (instead of just the combination of node group and viewer name),
+ * because the same node group may be used in many different places.
+ *
+ * This file contains basic functions for creating/deleting a #ViewerPath. For more use-case
+ * specific functions look in `ED_viewer_path.hh`.
+ */
+
+#include "DNA_viewer_path_types.h"
+
+struct BlendWriter;
+struct BlendDataReader;
+struct BlendLibReader;
+struct LibraryForeachIDData;
+struct Library;
+struct IDRemapper;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void BKE_viewer_path_init(ViewerPath *viewer_path);
+void BKE_viewer_path_clear(ViewerPath *viewer_path);
+void BKE_viewer_path_copy(ViewerPath *dst, const ViewerPath *src);
+bool BKE_viewer_path_equal(const ViewerPath *a, const ViewerPath *b);
+void BKE_viewer_path_blend_write(struct BlendWriter *writer, const ViewerPath *viewer_path);
+void BKE_viewer_path_blend_read_data(struct BlendDataReader *reader, ViewerPath *viewer_path);
+void BKE_viewer_path_blend_read_lib(struct BlendLibReader *reader,
+ struct Library *lib,
+ ViewerPath *viewer_path);
+void BKE_viewer_path_foreach_id(struct LibraryForeachIDData *data, ViewerPath *viewer_path);
+void BKE_viewer_path_id_remap(ViewerPath *viewer_path, const struct IDRemapper *mappings);
+
+ViewerPathElem *BKE_viewer_path_elem_new(ViewerPathElemType type);
+IDViewerPathElem *BKE_viewer_path_elem_new_id(void);
+ModifierViewerPathElem *BKE_viewer_path_elem_new_modifier(void);
+NodeViewerPathElem *BKE_viewer_path_elem_new_node(void);
+ViewerPathElem *BKE_viewer_path_elem_copy(const ViewerPathElem *src);
+bool BKE_viewer_path_elem_equal(const ViewerPathElem *a, const ViewerPathElem *b);
+void BKE_viewer_path_elem_free(ViewerPathElem *elem);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/blenkernel/BKE_writeffmpeg.h b/source/blender/blenkernel/BKE_writeffmpeg.h
index 736f7548bb4..cfe246eb470 100644
--- a/source/blender/blenkernel/BKE_writeffmpeg.h
+++ b/source/blender/blenkernel/BKE_writeffmpeg.h
@@ -27,6 +27,7 @@ enum {
FFMPEG_OGG = 10,
FFMPEG_INVALID = 11,
FFMPEG_WEBM = 12,
+ FFMPEG_AV1 = 13,
};
enum {
@@ -38,6 +39,7 @@ enum {
FFMPEG_PRESET_H264 = 5,
FFMPEG_PRESET_THEORA = 6,
FFMPEG_PRESET_XVID = 7,
+ FFMPEG_PRESET_AV1 = 8,
};
struct RenderData;
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 2f1e1897f8d..462ccc19601 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -75,6 +75,7 @@ set(SRC
intern/asset_catalog_path.cc
intern/asset_library.cc
intern/asset_library_service.cc
+ intern/asset_representation.cc
intern/attribute.cc
intern/attribute_access.cc
intern/attribute_math.cc
@@ -110,7 +111,6 @@ set(SRC
intern/curve_convert.c
intern/curve_decimate.c
intern/curve_deform.c
- intern/curve_eval.cc
intern/curve_legacy_convert.cc
intern/curve_nurbs.cc
intern/curve_poly.cc
@@ -126,7 +126,7 @@ set(SRC
intern/displist.cc
intern/dynamicpaint.c
intern/editlattice.c
- intern/editmesh.c
+ intern/editmesh.cc
intern/editmesh_bvh.c
intern/editmesh_cache.cc
intern/editmesh_tangent.cc
@@ -137,7 +137,6 @@ set(SRC
intern/fluid.c
intern/fmodifier.c
intern/freestyle.c
- intern/geometry_component_curve.cc
intern/geometry_component_curves.cc
intern/geometry_component_edit_data.cc
intern/geometry_component_instances.cc
@@ -165,6 +164,7 @@ set(SRC
intern/image_gpu.cc
intern/image_partial_update.cc
intern/image_save.cc
+ intern/instances.cc
intern/ipo.c
intern/kelvinlet.c
intern/key.c
@@ -193,7 +193,7 @@ set(SRC
intern/mask_rasterize.c
intern/material.c
intern/mball.cc
- intern/mball_tessellate.c
+ intern/mball_tessellate.cc
intern/mesh.cc
intern/mesh_boolean_convert.cc
intern/mesh_calc_edges.cc
@@ -201,9 +201,9 @@ set(SRC
intern/mesh_debug.cc
intern/mesh_evaluate.cc
intern/mesh_fair.cc
- intern/mesh_iterators.c
+ intern/mesh_iterators.cc
intern/mesh_legacy_convert.cc
- intern/mesh_mapping.c
+ intern/mesh_mapping.cc
intern/mesh_merge.c
intern/mesh_merge_customdata.cc
intern/mesh_mirror.c
@@ -216,9 +216,9 @@ set(SRC
intern/mesh_tessellate.cc
intern/mesh_validate.cc
intern/mesh_wrapper.cc
- intern/modifier.c
+ intern/modifier.cc
intern/movieclip.c
- intern/multires.c
+ intern/multires.cc
intern/multires_reshape.c
intern/multires_reshape_apply_base.c
intern/multires_reshape_ccg.c
@@ -237,7 +237,7 @@ set(SRC
intern/object_deform.c
intern/object_dupli.cc
intern/object_facemap.c
- intern/object_update.c
+ intern/object_update.cc
intern/ocean.c
intern/ocean_spectrum.c
intern/outliner_treehash.cc
@@ -261,18 +261,14 @@ set(SRC
intern/scene.cc
intern/screen.c
intern/shader_fx.c
- intern/shrinkwrap.c
+ intern/shrinkwrap.cc
intern/simulation.cc
intern/softbody.c
intern/sound.c
intern/speaker.c
- intern/spline_base.cc
- intern/spline_bezier.cc
- intern/spline_nurbs.cc
- intern/spline_poly.cc
intern/studiolight.c
intern/subdiv.c
- intern/subdiv_ccg.c
+ intern/subdiv_ccg.cc
intern/subdiv_ccg_mask.c
intern/subdiv_ccg_material.c
intern/subdiv_converter.c
@@ -283,7 +279,7 @@ set(SRC
intern/subdiv_eval.c
intern/subdiv_foreach.c
intern/subdiv_mesh.cc
- intern/subdiv_modifier.c
+ intern/subdiv_modifier.cc
intern/subdiv_stats.c
intern/subdiv_topology.c
intern/subsurf_ccg.c
@@ -303,10 +299,11 @@ set(SRC
intern/unit.c
intern/vfont.c
intern/vfontdata_freetype.c
+ intern/viewer_path.cc
intern/volume.cc
intern/volume_render.cc
intern/volume_to_mesh.cc
- intern/workspace.c
+ intern/workspace.cc
intern/world.c
intern/writeavi.c
@@ -328,6 +325,7 @@ set(SRC
BKE_asset_catalog_path.hh
BKE_asset_library.h
BKE_asset_library.hh
+ BKE_asset_representation.hh
BKE_attribute.h
BKE_attribute.hh
BKE_attribute_math.hh
@@ -403,6 +401,7 @@ set(SRC
BKE_image_partial_update.hh
BKE_image_save.h
BKE_image_wrappers.hh
+ BKE_instances.hh
BKE_ipo.h
BKE_kelvinlet.h
BKE_key.h
@@ -469,7 +468,6 @@ set(SRC
BKE_softbody.h
BKE_sound.h
BKE_speaker.h
- BKE_spline.hh
BKE_studiolight.h
BKE_subdiv.h
BKE_subdiv_ccg.h
@@ -489,6 +487,7 @@ set(SRC
BKE_unit.h
BKE_vfont.h
BKE_vfontdata.h
+ BKE_viewer_path.h
BKE_volume.h
BKE_volume_render.h
BKE_volume_to_mesh.hh
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h
index 863a0a2eb91..218f2c58470 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf.h
@@ -6,6 +6,10 @@
* \ingroup bke
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef void *CCGMeshHDL;
typedef void *CCGVertHDL;
typedef void *CCGEdgeHDL;
@@ -215,3 +219,7 @@ void ccgEdgeIterator_next(CCGEdgeIterator *ei);
CCGFace *ccgFaceIterator_getCurrent(CCGFaceIterator *fi);
int ccgFaceIterator_isStopped(CCGFaceIterator *fi);
void ccgFaceIterator_next(CCGFaceIterator *fi);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc
index d7db0ad765c..bfdfc447baf 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.cc
+++ b/source/blender/blenkernel/intern/DerivedMesh.cc
@@ -35,6 +35,7 @@
#include "BKE_colorband.h"
#include "BKE_deform.h"
#include "BKE_editmesh.h"
+#include "BKE_editmesh_cache.h"
#include "BKE_geometry_set.hh"
#include "BKE_geometry_set_instances.hh"
#include "BKE_key.h"
@@ -188,7 +189,7 @@ void DM_init_funcs(DerivedMesh *dm)
dm->getLoopTriArray = dm_getLoopTriArray;
- /* subtypes handle getting actual data */
+ /* Sub-types handle getting actual data. */
dm->getNumLoopTri = dm_getNumLoopTri;
dm->getVertDataArray = DM_get_vert_data_layer;
@@ -240,8 +241,6 @@ void DM_from_template(DerivedMesh *dm,
CustomData_copy(&source->loopData, &dm->loopData, mask->lmask, CD_SET_DEFAULT, numLoops);
CustomData_copy(&source->polyData, &dm->polyData, mask->pmask, CD_SET_DEFAULT, numPolys);
- dm->cd_flag = source->cd_flag;
-
dm->type = type;
dm->numVertData = numVerts;
dm->numEdgeData = numEdges;
@@ -281,8 +280,8 @@ bool DM_release(DerivedMesh *dm)
void DM_ensure_looptri_data(DerivedMesh *dm)
{
- const unsigned int totpoly = dm->numPolyData;
- const unsigned int totloop = dm->numLoopData;
+ const uint totpoly = dm->numPolyData;
+ const uint totloop = dm->numLoopData;
const int looptris_num = poly_to_tri_count(totpoly, totloop);
BLI_assert(dm->looptris.array_wip == nullptr);
@@ -539,7 +538,7 @@ static void mesh_calc_modifier_final_normals(const Mesh *mesh_input,
(final_datamask->lmask & CD_MASK_NORMAL) != 0);
/* Needed as `final_datamask` is not preserved outside modifier stack evaluation. */
- SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime.subsurf_runtime_data;
+ SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime->subsurf_runtime_data;
if (subsurf_runtime_data) {
subsurf_runtime_data->calc_loop_normals = calc_loop_normals;
}
@@ -587,11 +586,12 @@ static void mesh_calc_finalize(const Mesh *mesh_input, Mesh *mesh_eval)
void BKE_mesh_wrapper_deferred_finalize_mdata(Mesh *me_eval,
const CustomData_MeshMasks *cd_mask_finalize)
{
- if (me_eval->runtime.wrapper_type_finalize & (1 << ME_WRAPPER_TYPE_BMESH)) {
+ if (me_eval->runtime->wrapper_type_finalize & (1 << ME_WRAPPER_TYPE_BMESH)) {
editbmesh_calc_modifier_final_normals(me_eval, cd_mask_finalize);
- me_eval->runtime.wrapper_type_finalize &= ~(1 << ME_WRAPPER_TYPE_BMESH);
+ me_eval->runtime->wrapper_type_finalize = eMeshWrapperType(
+ me_eval->runtime->wrapper_type_finalize & ~(1 << ME_WRAPPER_TYPE_BMESH));
}
- BLI_assert(me_eval->runtime.wrapper_type_finalize == 0);
+ BLI_assert(me_eval->runtime->wrapper_type_finalize == 0);
}
/**
@@ -731,7 +731,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
* subdividing them is expensive. */
CustomData_MeshMasks final_datamask = *dataMask;
CDMaskLink *datamasks = BKE_modifier_calc_data_masks(
- scene, ob, md, &final_datamask, required_mode, previewmd, &previewmask);
+ scene, md, &final_datamask, required_mode, previewmd, &previewmask);
CDMaskLink *md_datamask = datamasks;
/* XXX Always copying POLYINDEX, else tessellated data are no more valid! */
CustomData_MeshMasks append_mask = CD_MASK_BAREMESH_ORIGINDEX;
@@ -747,7 +747,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
MutableAttributeAccessor attributes = mesh_final->attributes_for_write();
SpanAttributeWriter<float3> rest_positions =
attributes.lookup_or_add_for_write_only_span<float3>("rest_position", ATTR_DOMAIN_POINT);
- if (rest_positions) {
+ if (rest_positions && attributes.domain_size(ATTR_DOMAIN_POINT) > 0) {
attributes.lookup<float3>("position").materialize(rest_positions.span);
rest_positions.finish();
}
@@ -852,7 +852,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
/* Add orco mesh as layer if needed by this modifier. */
if (mesh_final && mesh_orco && mti->requiredDataMask) {
CustomData_MeshMasks mask = {0};
- mti->requiredDataMask(ob, md, &mask);
+ mti->requiredDataMask(md, &mask);
if (mask.vmask & CD_MASK_ORCO) {
add_orco_mesh(ob, nullptr, mesh_final, mesh_orco, CD_ORCO);
}
@@ -1003,7 +1003,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
temp_cddata_masks.pmask = CD_MASK_ORIGINDEX;
if (mti->requiredDataMask != nullptr) {
- mti->requiredDataMask(ob, md, &temp_cddata_masks);
+ mti->requiredDataMask(md, &temp_cddata_masks);
}
CustomData_MeshMasks_update(&temp_cddata_masks, &nextmask);
mesh_set_only_copy(mesh_orco, &temp_cddata_masks);
@@ -1054,7 +1054,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
append_mask.lmask |= CD_MASK_PREVIEW_MLOOPCOL;
}
- mesh_final->runtime.deformed_only = false;
+ mesh_final->runtime->deformed_only = false;
}
isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform);
@@ -1121,10 +1121,9 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
mesh_calc_finalize(mesh_input, mesh_final);
}
else {
- Mesh_Runtime *runtime = &mesh_input->runtime;
+ blender::bke::MeshRuntime *runtime = mesh_input->runtime;
if (runtime->mesh_eval == nullptr) {
- BLI_assert(runtime->eval_mutex != nullptr);
- BLI_mutex_lock((ThreadMutex *)runtime->eval_mutex);
+ std::lock_guard lock{mesh_input->runtime->eval_mutex};
if (runtime->mesh_eval == nullptr) {
/* Not yet finalized by any instance, do it now
* Isolate since computing normals is multithreaded and we are holding a lock. */
@@ -1140,7 +1139,6 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
/* Already finalized by another instance, reuse. */
mesh_final = runtime->mesh_eval;
}
- BLI_mutex_unlock((ThreadMutex *)runtime->eval_mutex);
}
else if (!mesh_has_modifier_final_normals(mesh_input, &final_datamask, runtime->mesh_eval)) {
/* Modifier stack was (re-)evaluated with a request for additional normals
@@ -1209,7 +1207,7 @@ static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final,
const bool calc_loop_normals = ((mesh_final->flag & ME_AUTOSMOOTH) != 0 ||
(final_datamask->lmask & CD_MASK_NORMAL) != 0);
- SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime.subsurf_runtime_data;
+ SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime->subsurf_runtime_data;
if (subsurf_runtime_data) {
subsurf_runtime_data->calc_loop_normals = calc_loop_normals;
}
@@ -1236,9 +1234,10 @@ static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final,
static void editbmesh_calc_modifier_final_normals_or_defer(
Mesh *mesh_final, const CustomData_MeshMasks *final_datamask)
{
- if (mesh_final->runtime.wrapper_type != ME_WRAPPER_TYPE_MDATA) {
+ if (mesh_final->runtime->wrapper_type != ME_WRAPPER_TYPE_MDATA) {
/* Generated at draw time. */
- mesh_final->runtime.wrapper_type_finalize = (1 << mesh_final->runtime.wrapper_type);
+ mesh_final->runtime->wrapper_type_finalize = eMeshWrapperType(
+ 1 << mesh_final->runtime->wrapper_type);
return;
}
@@ -1298,7 +1297,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
* subdividing them is expensive. */
CustomData_MeshMasks final_datamask = *dataMask;
CDMaskLink *datamasks = BKE_modifier_calc_data_masks(
- scene, ob, md, &final_datamask, required_mode, nullptr, nullptr);
+ scene, md, &final_datamask, required_mode, nullptr, nullptr);
CDMaskLink *md_datamask = datamasks;
CustomData_MeshMasks append_mask = CD_MASK_BAREMESH;
@@ -1328,7 +1327,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
/* Add an orco mesh as layer if needed by this modifier. */
if (mesh_final && mesh_orco && mti->requiredDataMask) {
CustomData_MeshMasks mask = {0};
- mti->requiredDataMask(ob, md, &mask);
+ mti->requiredDataMask(md, &mask);
if (mask.vmask & CD_MASK_ORCO) {
add_orco_mesh(ob, em_input, mesh_final, mesh_orco, CD_ORCO);
}
@@ -1452,7 +1451,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
deformed_verts = nullptr;
}
}
- mesh_final->runtime.deformed_only = false;
+ mesh_final->runtime->deformed_only = false;
}
if (r_cage && i == cageIndex) {
@@ -1471,7 +1470,8 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
if (!BKE_mesh_runtime_ensure_edit_data(me_orig)) {
BKE_mesh_runtime_reset_edit_data(me_orig);
}
- me_orig->runtime.edit_data->vertexCos = (const float(*)[3])MEM_dupallocN(deformed_verts);
+ me_orig->runtime->edit_data->vertexCos = (const float(*)[3])MEM_dupallocN(
+ deformed_verts);
}
mesh_cage = BKE_mesh_wrapper_from_editmesh_with_coords(
em_input,
@@ -1585,7 +1585,7 @@ static void mesh_build_data(struct Depsgraph *depsgraph,
* object's runtime: this could cause access freed data on depsgraph destruction (mesh who owns
* the final result might be freed prior to object). */
Mesh *mesh = (Mesh *)ob->data;
- const bool is_mesh_eval_owned = (mesh_eval != mesh->runtime.mesh_eval);
+ const bool is_mesh_eval_owned = (mesh_eval != mesh->runtime->mesh_eval);
BKE_object_eval_assign_data(ob, &mesh_eval->id, is_mesh_eval_owned);
/* Add the final mesh as a non-owning component to the geometry set. */
@@ -1645,9 +1645,15 @@ static void editbmesh_build_data(struct Depsgraph *depsgraph,
}
}
- const bool is_mesh_eval_owned = (me_final != mesh->runtime.mesh_eval);
+ const bool is_mesh_eval_owned = (me_final != mesh->runtime->mesh_eval);
BKE_object_eval_assign_data(obedit, &me_final->id, is_mesh_eval_owned);
+ /* Make sure that drivers can target shapekey properties.
+ * Note that this causes a potential inconsistency, as the shapekey may have a
+ * different topology than the evaluated mesh. */
+ BLI_assert(mesh->key == nullptr || DEG_is_evaluated_id(&mesh->key->id));
+ me_final->key = mesh->key;
+
obedit->runtime.editmesh_eval_cage = me_cage;
obedit->runtime.geometry_set_eval = non_mesh_components;
@@ -1662,6 +1668,7 @@ static void object_get_datamask(const Depsgraph *depsgraph,
CustomData_MeshMasks *r_mask,
bool *r_need_mapping)
{
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
DEG_get_customdata_mask_for_object(depsgraph, ob, r_mask);
@@ -1676,8 +1683,11 @@ static void object_get_datamask(const Depsgraph *depsgraph,
return;
}
- Object *actob = view_layer->basact ? DEG_get_original_object(view_layer->basact->object) :
- nullptr;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *actob = BKE_view_layer_active_object_get(view_layer);
+ if (actob) {
+ actob = DEG_get_original_object(actob);
+ }
if (DEG_get_original_object(ob) == actob) {
bool editing = BKE_paint_select_face_test(actob);
@@ -1897,7 +1907,7 @@ struct MappedUserData {
static void make_vertexcos__mapFunc(void *userData,
int index,
const float co[3],
- const float UNUSED(no[3]))
+ const float /*no*/[3])
{
MappedUserData *mappedData = (MappedUserData *)userData;
@@ -1912,7 +1922,7 @@ static void make_vertexcos__mapFunc(void *userData,
void mesh_get_mapped_verts_coords(Mesh *me_eval, float (*r_cos)[3], const int totcos)
{
- if (me_eval->runtime.deformed_only == false) {
+ if (me_eval->runtime->deformed_only == false) {
MappedUserData userData;
memset(r_cos, 0, sizeof(*r_cos) * totcos);
userData.vertexcos = r_cos;
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index e0ae1d88760..8f6bd812d8e 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -113,7 +113,7 @@ static void action_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src,
BLI_addtail(&action_dst->curves, fcurve_dst);
- /* Fix group links (kindof bad list-in-list search, but this is the most reliable way). */
+ /* Fix group links (kind of bad list-in-list search, but this is the most reliable way). */
for (group_dst = action_dst->groups.first, group_src = action_src->groups.first;
group_dst && group_src;
group_dst = group_dst->next, group_src = group_src->next) {
@@ -1738,7 +1738,7 @@ void what_does_obaction(Object *ob,
BKE_object_workob_clear(workob);
/* init workob */
- copy_m4_m4(workob->obmat, ob->obmat);
+ copy_m4_m4(workob->object_to_world, ob->object_to_world);
copy_m4_m4(workob->parentinv, ob->parentinv);
copy_m4_m4(workob->constinv, ob->constinv);
workob->parent = ob->parent;
diff --git a/source/blender/blenkernel/intern/anim_data.c b/source/blender/blenkernel/intern/anim_data.c
index b5b00e031b2..9b68c19c6e2 100644
--- a/source/blender/blenkernel/intern/anim_data.c
+++ b/source/blender/blenkernel/intern/anim_data.c
@@ -136,7 +136,7 @@ bool BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act)
return false;
}
- /* Reduce usercount for current action. */
+ /* Reduce user-count for current action. */
if (adt->action) {
id_us_min((ID *)adt->action);
}
@@ -287,11 +287,11 @@ AnimData *BKE_animdata_copy(Main *bmain, AnimData *adt, const int flag)
/* make a copy of action - at worst, user has to delete copies... */
if (do_action) {
- /* Recursive copy of 'real' IDs is a bit hairy. Even if do not want to deal with usercount
- * when copying ID's data itself, we still need to do so with sub-IDs, since those will not be
- * handled by later 'update usercounts of used IDs' code as used e.g. at end of
- * BKE_id_copy_ex().
- * So in case we do copy the ID and its sub-IDs in bmain, silence the 'no usercount' flag for
+ /* Recursive copy of 'real' IDs is a bit hairy. Even if do not want to deal with user-count
+ * when copying ID's data itself, we still need to do so with sub-IDs, since those will not be
+ * handled by later 'update user-counts of used IDs' code as used e.g. at end of
+ * #BKE_id_copy_ex().
+ * So in case we do copy the ID and its sub-IDs in bmain, silence the 'no user-count' flag for
* the sub-IDs copying.
* NOTE: This is a bit weak, as usually when it comes to recursive ID copy. Should work for
* now, but we may have to revisit this at some point and add a proper extra flag to deal with
@@ -659,6 +659,8 @@ void BKE_animdata_transfer_by_basepath(Main *bmain, ID *srcID, ID *dstID, ListBa
srcAdt, dstAdt, basepath_change->src_basepath, basepath_change->dst_basepath);
}
}
+ /* Tag source action because list of fcurves changed. */
+ DEG_id_tag_update(&srcAdt->action->id, ID_RECALC_COPY_ON_WRITE);
}
/* Path Validation -------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 85ce647fcab..928626ecc7b 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -3198,7 +3198,7 @@ static void animsys_create_action_track_strip(const AnimData *adt,
* (which making new strips doesn't do due to the troublesome nature of that). */
calc_action_range(r_action_strip->act, &r_action_strip->actstart, &r_action_strip->actend, 1);
r_action_strip->start = r_action_strip->actstart;
- r_action_strip->end = (IS_EQF(r_action_strip->actstart, r_action_strip->actend)) ?
+ r_action_strip->end = IS_EQF(r_action_strip->actstart, r_action_strip->actend) ?
(r_action_strip->actstart + 1.0f) :
(r_action_strip->actend);
diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c
index 96ac81fdb63..b3990b2b7fc 100644
--- a/source/blender/blenkernel/intern/appdir.c
+++ b/source/blender/blenkernel/intern/appdir.c
@@ -191,7 +191,7 @@ bool BKE_appdir_folder_documents(char *dir)
char try_documents_path[FILE_MAXDIR];
/* Own attempt at getting a valid Documents path. */
- BLI_path_join(try_documents_path, sizeof(try_documents_path), home_path, N_("Documents"), NULL);
+ BLI_path_join(try_documents_path, sizeof(try_documents_path), home_path, N_("Documents"));
if (!BLI_is_dir(try_documents_path)) {
return false;
}
@@ -214,11 +214,11 @@ bool BKE_appdir_folder_caches(char *r_path, const size_t path_len)
#ifdef WIN32
BLI_path_join(
- r_path, path_len, caches_root_path, "Blender Foundation", "Blender", "Cache", SEP_STR, NULL);
+ r_path, path_len, caches_root_path, "Blender Foundation", "Blender", "Cache", SEP_STR);
#elif defined(__APPLE__)
- BLI_path_join(r_path, path_len, caches_root_path, "Blender", SEP_STR, NULL);
+ BLI_path_join(r_path, path_len, caches_root_path, "Blender", SEP_STR);
#else /* __linux__ */
- BLI_path_join(r_path, path_len, caches_root_path, "blender", SEP_STR, NULL);
+ BLI_path_join(r_path, path_len, caches_root_path, "blender", SEP_STR);
#endif
return true;
@@ -237,7 +237,7 @@ bool BKE_appdir_font_folder_default(char *dir)
}
#elif defined(__APPLE__)
STRNCPY(test_dir, BLI_expand_tilde("~/Library/Fonts/"));
- BLI_path_slash_ensure(test_dir);
+ BLI_path_slash_ensure(test_dir, sizeof(test_dir));
#else
STRNCPY(test_dir, "/usr/share/fonts");
#endif
@@ -281,7 +281,9 @@ static bool test_path(char *targetpath,
/* Only the last argument should be NULL. */
BLI_assert(!(folder_name == NULL && (subfolder_name != NULL)));
- BLI_path_join(targetpath, targetpath_len, path_base, folder_name, subfolder_name, NULL);
+ const char *path_array[] = {path_base, folder_name, subfolder_name};
+ const int path_array_num = (folder_name ? (subfolder_name ? 3 : 2) : 1);
+ BLI_path_join_array(targetpath, targetpath_len, path_array, path_array_num);
if (check_is_dir == false) {
CLOG_INFO(&LOG, 3, "using without test: '%s'", targetpath);
return true;
@@ -365,7 +367,9 @@ static bool get_path_local_ex(char *targetpath,
STR_OR_FALLBACK(subfolder_name));
if (folder_name) { /* `subfolder_name` may be NULL. */
- BLI_path_join(relfolder, sizeof(relfolder), folder_name, subfolder_name, NULL);
+ const char *path_array[] = {folder_name, subfolder_name};
+ const int path_array_num = subfolder_name ? 2 : 1;
+ BLI_path_join_array(relfolder, sizeof(relfolder), path_array, path_array_num);
}
else {
relfolder[0] = '\0';
@@ -379,8 +383,7 @@ static bool get_path_local_ex(char *targetpath,
* we must move the blender_version dir with contents to Resources.
* Add 4 + 9 for the temporary `/../` path & `Resources`. */
char osx_resourses[FILE_MAX + 4 + 9];
- BLI_path_join(
- osx_resourses, sizeof(osx_resourses), g_app.program_dirname, "..", "Resources", NULL);
+ BLI_path_join(osx_resourses, sizeof(osx_resourses), g_app.program_dirname, "..", "Resources");
/* Remove the '/../' added above. */
BLI_path_normalize(NULL, osx_resourses);
path_base = osx_resourses;
@@ -460,18 +463,22 @@ static bool get_path_user_ex(char *targetpath,
const bool check_is_dir)
{
char user_path[FILE_MAX];
- const char *user_base_path;
- /* for portable install, user path is always local */
- if (BKE_appdir_app_is_portable_install()) {
- return get_path_local_ex(
- targetpath, targetpath_len, folder_name, subfolder_name, version, check_is_dir);
+ if (test_env_path(user_path, "BLENDER_USER_RESOURCES", check_is_dir)) {
+ /* Pass. */
}
- user_path[0] = '\0';
+ else {
+ /* for portable install, user path is always local */
+ if (BKE_appdir_app_is_portable_install()) {
+ return get_path_local_ex(
+ targetpath, targetpath_len, folder_name, subfolder_name, version, check_is_dir);
+ }
+ user_path[0] = '\0';
- user_base_path = GHOST_getUserDir(version, blender_version_decimal(version));
- if (user_base_path) {
- BLI_strncpy(user_path, user_base_path, FILE_MAX);
+ const char *user_base_path = GHOST_getUserDir(version, blender_version_decimal(version));
+ if (user_base_path) {
+ BLI_strncpy(user_path, user_base_path, FILE_MAX);
+ }
}
if (!user_path[0]) {
@@ -518,20 +525,26 @@ static bool get_path_system_ex(char *targetpath,
const bool check_is_dir)
{
char system_path[FILE_MAX];
- const char *system_base_path;
char relfolder[FILE_MAX];
if (folder_name) { /* `subfolder_name` may be NULL. */
- BLI_path_join(relfolder, sizeof(relfolder), folder_name, subfolder_name, NULL);
+ const char *path_array[] = {folder_name, subfolder_name};
+ const int path_array_num = subfolder_name ? 2 : 1;
+ BLI_path_join_array(relfolder, sizeof(relfolder), path_array, path_array_num);
}
else {
relfolder[0] = '\0';
}
- system_path[0] = '\0';
- system_base_path = GHOST_getSystemDir(version, blender_version_decimal(version));
- if (system_base_path) {
- BLI_strncpy(system_path, system_base_path, FILE_MAX);
+ if (test_env_path(system_path, "BLENDER_SYSTEM_RESOURCES", check_is_dir)) {
+ /* Pass. */
+ }
+ else {
+ system_path[0] = '\0';
+ const char *system_base_path = GHOST_getSystemDir(version, blender_version_decimal(version));
+ if (system_base_path) {
+ BLI_strncpy(system_path, system_base_path, FILE_MAX);
+ }
}
if (!system_path[0]) {
@@ -752,9 +765,9 @@ const char *BKE_appdir_folder_id_create(const int folder_id, const char *subfold
return path;
}
-const char *BKE_appdir_folder_id_version(const int folder_id,
- const int version,
- const bool check_is_dir)
+const char *BKE_appdir_resource_path_id_with_version(const int folder_id,
+ const bool check_is_dir,
+ const int version)
{
static char path[FILE_MAX] = "";
bool ok;
@@ -777,6 +790,11 @@ const char *BKE_appdir_folder_id_version(const int folder_id,
return ok ? path : NULL;
}
+const char *BKE_appdir_resource_path_id(const int folder_id, const bool check_is_dir)
+{
+ return BKE_appdir_resource_path_id_with_version(folder_id, check_is_dir, BLENDER_VERSION);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -888,7 +906,7 @@ void BKE_appdir_program_path_init(const char *argv0)
const char *BKE_appdir_program_path(void)
{
-#ifndef WITH_PYTHON_MODULE /* Default's to empty when building as as Python module. */
+#ifndef WITH_PYTHON_MODULE /* Default's to empty when building as a Python module. */
BLI_assert(g_app.program_filepath[0]);
#endif
return g_app.program_filepath;
@@ -936,7 +954,7 @@ bool BKE_appdir_program_python_search(char *fullpath,
if (python_bin_dir) {
for (int i = 0; i < ARRAY_SIZE(python_names); i++) {
- BLI_join_dirfile(fullpath, fullpath_len, python_bin_dir, python_names[i]);
+ BLI_path_join(fullpath, fullpath_len, python_bin_dir, python_names[i]);
if (
#ifdef _WIN32
@@ -1005,7 +1023,7 @@ bool BKE_appdir_app_template_id_search(const char *app_template, char *path, siz
{
for (int i = 0; i < ARRAY_SIZE(app_template_directory_id); i++) {
char subdir[FILE_MAX];
- BLI_join_dirfile(subdir, sizeof(subdir), app_template_directory_search[i], app_template);
+ BLI_path_join(subdir, sizeof(subdir), app_template_directory_search[i], app_template);
if (BKE_appdir_folder_id_ex(app_template_directory_id[i], subdir, path, path_len)) {
return true;
}
@@ -1028,8 +1046,7 @@ bool BKE_appdir_app_template_has_userpref(const char *app_template)
}
char userpref_path[FILE_MAX];
- BLI_path_join(
- userpref_path, sizeof(userpref_path), app_template_path, BLENDER_USERPREF_FILE, NULL);
+ BLI_path_join(userpref_path, sizeof(userpref_path), app_template_path, BLENDER_USERPREF_FILE);
return BLI_exists(userpref_path);
}
@@ -1076,13 +1093,13 @@ void BKE_appdir_app_templates(ListBase *templates)
* \param userdir: Directory specified in user preferences (may be NULL).
* note that by default this is an empty string, only use when non-empty.
*/
-static void where_is_temp(char *tempdir, const size_t tempdir_len, const char *userdir)
+static void where_is_temp(char *tempdir, const size_t tempdir_maxlen, const char *userdir)
{
tempdir[0] = '\0';
if (userdir && BLI_is_dir(userdir)) {
- BLI_strncpy(tempdir, userdir, tempdir_len);
+ BLI_strncpy(tempdir, userdir, tempdir_maxlen);
}
if (tempdir[0] == '\0') {
@@ -1099,23 +1116,23 @@ static void where_is_temp(char *tempdir, const size_t tempdir_len, const char *u
for (int i = 0; i < ARRAY_SIZE(env_vars); i++) {
const char *tmp = BLI_getenv(env_vars[i]);
if (tmp && (tmp[0] != '\0') && BLI_is_dir(tmp)) {
- BLI_strncpy(tempdir, tmp, tempdir_len);
+ BLI_strncpy(tempdir, tmp, tempdir_maxlen);
break;
}
}
}
if (tempdir[0] == '\0') {
- BLI_strncpy(tempdir, "/tmp/", tempdir_len);
+ BLI_strncpy(tempdir, "/tmp/", tempdir_maxlen);
}
else {
/* add a trailing slash if needed */
- BLI_path_slash_ensure(tempdir);
+ BLI_path_slash_ensure(tempdir, tempdir_maxlen);
}
}
static void tempdir_session_create(char *tempdir_session,
- const size_t tempdir_session_len,
+ const size_t tempdir_session_maxlen,
const char *tempdir)
{
tempdir_session[0] = '\0';
@@ -1129,9 +1146,9 @@ static void tempdir_session_create(char *tempdir_session,
* #_mktemp_s also requires the last null character is included. */
const int tempdir_session_len_required = tempdir_len + session_name_len + 1;
- if (tempdir_session_len_required <= tempdir_session_len) {
+ if (tempdir_session_len_required <= tempdir_session_maxlen) {
/* No need to use path joining utility as we know the last character of #tempdir is a slash. */
- BLI_string_join(tempdir_session, tempdir_session_len, tempdir, session_name);
+ BLI_string_join(tempdir_session, tempdir_session_maxlen, tempdir, session_name);
#ifdef WIN32
const bool needs_create = (_mktemp_s(tempdir_session, tempdir_session_len_required) == 0);
#else
@@ -1141,7 +1158,7 @@ static void tempdir_session_create(char *tempdir_session,
BLI_dir_create_recursive(tempdir_session);
}
if (BLI_is_dir(tempdir_session)) {
- BLI_path_slash_ensure(tempdir_session);
+ BLI_path_slash_ensure(tempdir_session, tempdir_session_maxlen);
/* Success. */
return;
}
@@ -1151,7 +1168,7 @@ static void tempdir_session_create(char *tempdir_session,
"Could not generate a temp file name for '%s', falling back to '%s'",
tempdir_session,
tempdir);
- BLI_strncpy(tempdir_session, tempdir, tempdir_session_len);
+ BLI_strncpy(tempdir_session, tempdir, tempdir_session_maxlen);
}
void BKE_tempdir_init(const char *userdir)
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 0027f6dd707..e433c26cc54 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -97,7 +97,7 @@ static void armature_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src
Bone *bone_src, *bone_dst;
Bone *bone_dst_act = NULL;
- /* We never handle usercount here for own data. */
+ /* We never handle user-count here for own data. */
const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
armature_dst->bonehash = NULL;
@@ -698,7 +698,7 @@ void BKE_armature_refresh_layer_used(struct Depsgraph *depsgraph, struct bArmatu
bool bone_autoside_name(
char name[MAXBONENAME], int UNUSED(strip_number), short axis, float head, float tail)
{
- unsigned int len;
+ uint len;
char basename[MAXBONENAME] = "";
char extension[5] = "";
@@ -1596,7 +1596,7 @@ void BKE_armature_mat_world_to_pose(Object *ob, const float inmat[4][4], float o
}
/* Get inverse of (armature) object's matrix. */
- invert_m4_m4(obmat, ob->obmat);
+ invert_m4_m4(obmat, ob->object_to_world);
/* multiply given matrix by object's-inverse to find pose-space matrix */
mul_m4_m4m4(outmat, inmat, obmat);
@@ -2569,7 +2569,7 @@ void BKE_pose_where_is(struct Depsgraph *depsgraph, Scene *scene, Object *ob)
}
}
else {
- invert_m4_m4(ob->imat, ob->obmat); /* imat is needed */
+ invert_m4_m4(ob->world_to_object, ob->object_to_world); /* world_to_object is needed */
/* 1. clear flags */
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
@@ -2696,14 +2696,14 @@ void BKE_pchan_minmax(const Object *ob,
pchan->custom_translation[0],
pchan->custom_translation[1],
pchan->custom_translation[2]);
- mul_m4_series(mat, ob->obmat, tmp, rmat, smat);
+ mul_m4_series(mat, ob->object_to_world, tmp, rmat, smat);
BKE_boundbox_minmax(bb_custom, mat, r_min, r_max);
}
else {
float vec[3];
- mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_head);
+ mul_v3_m4v3(vec, ob->object_to_world, pchan_tx->pose_head);
minmax_v3v3_v3(r_min, r_max, vec);
- mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_tail);
+ mul_v3_m4v3(vec, ob->object_to_world, pchan_tx->pose_tail);
minmax_v3v3_v3(r_min, r_max, vec);
}
}
diff --git a/source/blender/blenkernel/intern/armature_deform.c b/source/blender/blenkernel/intern/armature_deform.c
index 84bb1af011a..64a3937c191 100644
--- a/source/blender/blenkernel/intern/armature_deform.c
+++ b/source/blender/blenkernel/intern/armature_deform.c
@@ -301,12 +301,22 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data,
}
/* check if there's any point in calculating for this vert */
- if (armature_weight == 0.0f) {
- return;
+ if (vert_coords_prev) {
+ if (prevco_weight == 1.0f) {
+ return;
+ }
+
+ /* get the coord we work on */
+ co = vert_coords_prev[i];
}
+ else {
+ if (armature_weight == 0.0f) {
+ return;
+ }
- /* get the coord we work on */
- co = vert_coords_prev ? vert_coords_prev[i] : vert_coords[i];
+ /* get the coord we work on */
+ co = vert_coords[i];
+ }
/* Apply the object's matrix */
mul_m4_v3(data->premat, co);
@@ -314,7 +324,7 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data,
if (use_dverts && dvert && dvert->totweight) { /* use weight groups ? */
const MDeformWeight *dw = dvert->dw;
int deformed = 0;
- unsigned int j;
+ uint j;
for (j = dvert->totweight; j != 0; j--, dw++) {
const uint index = dw->def_nr;
if (index < data->defbase_len && (pchan = data->pchan_from_defbase[index])) {
@@ -572,9 +582,9 @@ static void armature_deform_coords_impl(const Object *ob_arm,
};
float obinv[4][4];
- invert_m4_m4(obinv, ob_target->obmat);
+ invert_m4_m4(obinv, ob_target->object_to_world);
- mul_m4_m4m4(data.postmat, obinv, ob_arm->obmat);
+ mul_m4_m4m4(data.postmat, obinv, ob_arm->object_to_world);
invert_m4_m4(data.premat, data.postmat);
if (em_target != NULL) {
diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c
index 6d7aed239e7..5f749472b2d 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -249,11 +249,11 @@ static void apply_curve_transform(
* unless the option to allow curve to be positioned elsewhere is activated (i.e. no root).
*/
if ((ik_data->flag & CONSTRAINT_SPLINEIK_NO_ROOT) == 0) {
- mul_m4_v3(ik_data->tar->obmat, r_vec);
+ mul_m4_v3(ik_data->tar->object_to_world, r_vec);
}
/* Convert the position to pose-space. */
- mul_m4_v3(ob->imat, r_vec);
+ mul_m4_v3(ob->world_to_object, r_vec);
/* Set the new radius (it should be the average value). */
*r_radius = (radius + *r_radius) / 2;
@@ -818,8 +818,8 @@ void BKE_pose_eval_init(struct Depsgraph *depsgraph, Scene *UNUSED(scene), Objec
BLI_assert(object->pose != NULL);
BLI_assert((object->pose->flag & POSE_RECALC) == 0);
- /* imat is needed for solvers. */
- invert_m4_m4(object->imat, object->obmat);
+ /* world_to_object is needed for solvers. */
+ invert_m4_m4(object->world_to_object, object->object_to_world);
/* clear flags */
for (bPoseChannel *pchan = pose->chanbase.first; pchan != NULL; pchan = pchan->next) {
diff --git a/source/blender/blenkernel/intern/asset.cc b/source/blender/blenkernel/intern/asset.cc
index 9d9ed219cbb..7103e017847 100644
--- a/source/blender/blenkernel/intern/asset.cc
+++ b/source/blender/blenkernel/intern/asset.cc
@@ -27,21 +27,31 @@ using namespace blender;
AssetMetaData *BKE_asset_metadata_create()
{
- AssetMetaData *asset_data = (AssetMetaData *)MEM_callocN(sizeof(*asset_data), __func__);
- memcpy(asset_data, DNA_struct_default_get(AssetMetaData), sizeof(*asset_data));
- return asset_data;
+ const AssetMetaData *default_metadata = DNA_struct_default_get(AssetMetaData);
+ return MEM_new<AssetMetaData>(__func__, *default_metadata);
}
void BKE_asset_metadata_free(AssetMetaData **asset_data)
{
- if ((*asset_data)->properties) {
- IDP_FreeProperty((*asset_data)->properties);
+ (*asset_data)->~AssetMetaData();
+ MEM_SAFE_FREE(*asset_data);
+}
+
+AssetMetaData::~AssetMetaData()
+{
+ if (properties) {
+ IDP_FreeProperty(properties);
}
- MEM_SAFE_FREE((*asset_data)->author);
- MEM_SAFE_FREE((*asset_data)->description);
- BLI_freelistN(&(*asset_data)->tags);
+ MEM_SAFE_FREE(author);
+ MEM_SAFE_FREE(description);
+ BLI_freelistN(&tags);
+}
- MEM_SAFE_FREE(*asset_data);
+std::unique_ptr<AssetMetaData> BKE_asset_metadata_move_to_unique_ptr(AssetMetaData *asset_data)
+{
+ std::unique_ptr unique_asset_data = std::make_unique<AssetMetaData>(*asset_data);
+ *asset_data = *DNA_struct_default_get(AssetMetaData);
+ return unique_asset_data;
}
static AssetTag *asset_metadata_tag_add(AssetMetaData *asset_data, const char *const name)
@@ -143,7 +153,7 @@ IDProperty *BKE_asset_metadata_idprop_find(const AssetMetaData *asset_data, cons
/* Queries -------------------------------------------- */
-PreviewImage *BKE_asset_metadata_preview_get_from_id(const AssetMetaData *UNUSED(asset_data),
+PreviewImage *BKE_asset_metadata_preview_get_from_id(const AssetMetaData * /*asset_data*/,
const ID *id)
{
return BKE_previewimg_id_get(id);
diff --git a/source/blender/blenkernel/intern/asset_catalog.cc b/source/blender/blenkernel/intern/asset_catalog.cc
index f7b14cc3479..a9fe59eba64 100644
--- a/source/blender/blenkernel/intern/asset_catalog.cc
+++ b/source/blender/blenkernel/intern/asset_catalog.cc
@@ -9,6 +9,7 @@
#include "BKE_asset_catalog.hh"
#include "BKE_asset_library.h"
+#include "BKE_asset_library.hh"
#include "BLI_fileops.hh"
#include "BLI_path_util.h"
@@ -284,10 +285,10 @@ AssetCatalog *AssetCatalogService::create_catalog(const AssetCatalogPath &catalo
static std::string asset_definition_default_file_path_from_dir(StringRef asset_library_root)
{
char file_path[PATH_MAX];
- BLI_join_dirfile(file_path,
- sizeof(file_path),
- asset_library_root.data(),
- AssetCatalogService::DEFAULT_CATALOG_FILENAME.data());
+ BLI_path_join(file_path,
+ sizeof(file_path),
+ asset_library_root.data(),
+ AssetCatalogService::DEFAULT_CATALOG_FILENAME.data());
return file_path;
}
@@ -507,16 +508,14 @@ CatalogFilePath AssetCatalogService::find_suitable_cdf_path_for_writing(
"catalog definition file should be put");
/* Ask the asset library API for an appropriate location. */
- char suitable_root_path[PATH_MAX];
- const bool asset_lib_root_found = BKE_asset_library_find_suitable_root_path_from_path(
- blend_file_path.c_str(), suitable_root_path);
- if (asset_lib_root_found) {
+ const std::string suitable_root_path = BKE_asset_library_find_suitable_root_path_from_path(
+ blend_file_path);
+ if (!suitable_root_path.empty()) {
char asset_lib_cdf_path[PATH_MAX];
BLI_path_join(asset_lib_cdf_path,
sizeof(asset_lib_cdf_path),
- suitable_root_path,
- DEFAULT_CATALOG_FILENAME.c_str(),
- nullptr);
+ suitable_root_path.c_str(),
+ DEFAULT_CATALOG_FILENAME.c_str());
return asset_lib_cdf_path;
}
@@ -788,6 +787,41 @@ void AssetCatalogTree::foreach_root_item(const ItemIterFn callback)
}
}
+bool AssetCatalogTree::is_empty() const
+{
+ return root_items_.empty();
+}
+
+AssetCatalogTreeItem *AssetCatalogTree::find_item(const AssetCatalogPath &path)
+{
+ AssetCatalogTreeItem *result = nullptr;
+ this->foreach_item([&](AssetCatalogTreeItem &item) {
+ if (result) {
+ /* There is no way to stop iteration. */
+ return;
+ }
+ if (item.catalog_path() == path) {
+ result = &item;
+ }
+ });
+ return result;
+}
+
+AssetCatalogTreeItem *AssetCatalogTree::find_root_item(const AssetCatalogPath &path)
+{
+ AssetCatalogTreeItem *result = nullptr;
+ this->foreach_root_item([&](AssetCatalogTreeItem &item) {
+ if (result) {
+ /* There is no way to stop iteration. */
+ return;
+ }
+ if (item.catalog_path() == path) {
+ result = &item;
+ }
+ });
+ return result;
+}
+
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/asset_catalog_path.cc b/source/blender/blenkernel/intern/asset_catalog_path.cc
index 669adb7adf4..9c653c1a137 100644
--- a/source/blender/blenkernel/intern/asset_catalog_path.cc
+++ b/source/blender/blenkernel/intern/asset_catalog_path.cc
@@ -12,7 +12,7 @@ namespace blender::bke {
const char AssetCatalogPath::SEPARATOR = '/';
-AssetCatalogPath::AssetCatalogPath(const std::string &path) : path_(path)
+AssetCatalogPath::AssetCatalogPath(std::string path) : path_(std::move(path))
{
}
diff --git a/source/blender/blenkernel/intern/asset_catalog_test.cc b/source/blender/blenkernel/intern/asset_catalog_test.cc
index 81eb1786322..ee2dd652b61 100644
--- a/source/blender/blenkernel/intern/asset_catalog_test.cc
+++ b/source/blender/blenkernel/intern/asset_catalog_test.cc
@@ -98,7 +98,7 @@ class AssetCatalogTest : public testing::Test {
FAIL();
}
- asset_library_root_ = test_files_dir + "/" + "asset_library";
+ asset_library_root_ = test_files_dir + SEP_STR + "asset_library";
temp_library_path_ = "";
}
@@ -116,7 +116,7 @@ class AssetCatalogTest : public testing::Test {
{
BKE_tempdir_init("");
const CatalogFilePath tempdir = BKE_tempdir_session();
- temp_library_path_ = tempdir + "test-temporary-path/";
+ temp_library_path_ = tempdir + "test-temporary-path" + SEP_STR;
return temp_library_path_;
}
@@ -202,9 +202,10 @@ class AssetCatalogTest : public testing::Test {
void save_from_memory_into_existing_asset_lib(const bool should_top_level_cdf_exist)
{
const CatalogFilePath target_dir = create_temp_path(); /* Has trailing slash. */
- const CatalogFilePath original_cdf_file = asset_library_root_ + "/blender_assets.cats.txt";
- const CatalogFilePath registered_asset_lib = target_dir + "my_asset_library/";
- const CatalogFilePath asset_lib_subdir = registered_asset_lib + "subdir/";
+ const CatalogFilePath original_cdf_file = asset_library_root_ + SEP_STR +
+ "blender_assets.cats.txt";
+ const CatalogFilePath registered_asset_lib = target_dir + "my_asset_library" + SEP_STR;
+ const CatalogFilePath asset_lib_subdir = registered_asset_lib + "subdir" + SEP_STR;
CatalogFilePath cdf_toplevel = registered_asset_lib +
AssetCatalogService::DEFAULT_CATALOG_FILENAME;
CatalogFilePath cdf_in_subdir = asset_lib_subdir +
@@ -272,7 +273,7 @@ class AssetCatalogTest : public testing::Test {
TEST_F(AssetCatalogTest, load_single_file)
{
AssetCatalogService service(asset_library_root_);
- service.load_from_disk(asset_library_root_ + "/" + "blender_assets.cats.txt");
+ service.load_from_disk(asset_library_root_ + SEP_STR + "blender_assets.cats.txt");
/* Test getting a non-existent catalog ID. */
EXPECT_EQ(nullptr, service.find_catalog(BLI_uuid_generate_random()));
@@ -313,7 +314,7 @@ TEST_F(AssetCatalogTest, load_single_file)
TEST_F(AssetCatalogTest, load_catalog_path_backslashes)
{
AssetCatalogService service(asset_library_root_);
- service.load_from_disk(asset_library_root_ + "/" + "blender_assets.cats.txt");
+ service.load_from_disk(asset_library_root_ + SEP_STR + "blender_assets.cats.txt");
const AssetCatalog *found_by_id = service.find_catalog(UUID_POSES_ELLIE_BACKSLASHES);
ASSERT_NE(nullptr, found_by_id);
@@ -332,7 +333,7 @@ TEST_F(AssetCatalogTest, load_catalog_path_backslashes)
TEST_F(AssetCatalogTest, is_first_loaded_flag)
{
AssetCatalogService service(asset_library_root_);
- service.load_from_disk(asset_library_root_ + "/" + "blender_assets.cats.txt");
+ service.load_from_disk(asset_library_root_ + SEP_STR + "blender_assets.cats.txt");
AssetCatalog *new_cat = service.create_catalog("never/before/seen/path");
EXPECT_FALSE(new_cat->flags.is_first_loaded)
@@ -435,7 +436,7 @@ TEST_F(AssetCatalogTest, insert_item_into_tree)
TEST_F(AssetCatalogTest, load_single_file_into_tree)
{
AssetCatalogService service(asset_library_root_);
- service.load_from_disk(asset_library_root_ + "/" + "blender_assets.cats.txt");
+ service.load_from_disk(asset_library_root_ + SEP_STR + "blender_assets.cats.txt");
/* Contains not only paths from the CDF but also the missing parents (implicitly defined
* catalogs). */
@@ -476,7 +477,7 @@ TEST_F(AssetCatalogTest, foreach_in_tree)
}
AssetCatalogService service(asset_library_root_);
- service.load_from_disk(asset_library_root_ + "/" + "blender_assets.cats.txt");
+ service.load_from_disk(asset_library_root_ + SEP_STR + "blender_assets.cats.txt");
std::vector<AssetCatalogPath> expected_root_items{{"character", "path"}};
AssetCatalogTree *tree = service.get_catalog_tree();
@@ -499,7 +500,7 @@ TEST_F(AssetCatalogTest, foreach_in_tree)
TEST_F(AssetCatalogTest, find_catalog_by_path)
{
TestableAssetCatalogService service(asset_library_root_);
- service.load_from_disk(asset_library_root_ + "/" +
+ service.load_from_disk(asset_library_root_ + SEP_STR +
AssetCatalogService::DEFAULT_CATALOG_FILENAME);
AssetCatalog *catalog;
@@ -522,7 +523,7 @@ TEST_F(AssetCatalogTest, find_catalog_by_path)
TEST_F(AssetCatalogTest, write_single_file)
{
TestableAssetCatalogService service(asset_library_root_);
- service.load_from_disk(asset_library_root_ + "/" +
+ service.load_from_disk(asset_library_root_ + SEP_STR +
AssetCatalogService::DEFAULT_CATALOG_FILENAME);
const CatalogFilePath save_to_path = use_temp_path() +
@@ -550,7 +551,7 @@ TEST_F(AssetCatalogTest, write_single_file)
TEST_F(AssetCatalogTest, read_write_unicode_filepath)
{
TestableAssetCatalogService service(asset_library_root_);
- const CatalogFilePath load_from_path = asset_library_root_ + "/новый/" +
+ const CatalogFilePath load_from_path = asset_library_root_ + SEP_STR + "новый" + SEP_STR +
AssetCatalogService::DEFAULT_CATALOG_FILENAME;
service.load_from_disk(load_from_path);
@@ -588,8 +589,9 @@ TEST_F(AssetCatalogTest, on_blendfile_save__with_existing_cdf)
const CatalogFilePath top_level_dir = create_temp_path(); /* Has trailing slash. */
/* Create a copy of the CDF in SVN, so we can safely write to it. */
- const CatalogFilePath original_cdf_file = asset_library_root_ + "/blender_assets.cats.txt";
- const CatalogFilePath cdf_dirname = top_level_dir + "other_dir/";
+ const CatalogFilePath original_cdf_file = asset_library_root_ + SEP_STR +
+ "blender_assets.cats.txt";
+ const CatalogFilePath cdf_dirname = top_level_dir + "other_dir" + SEP_STR;
const CatalogFilePath cdf_filename = cdf_dirname + AssetCatalogService::DEFAULT_CATALOG_FILENAME;
ASSERT_TRUE(BLI_dir_create_recursive(cdf_dirname.c_str()));
ASSERT_EQ(0, BLI_copy(original_cdf_file.c_str(), cdf_filename.c_str()))
@@ -600,7 +602,7 @@ TEST_F(AssetCatalogTest, on_blendfile_save__with_existing_cdf)
service.load_from_disk();
const AssetCatalog *cat = service.create_catalog("some/catalog/path");
- const CatalogFilePath blendfilename = top_level_dir + "subdir/some_file.blend";
+ const CatalogFilePath blendfilename = top_level_dir + "subdir" + SEP_STR + "some_file.blend";
ASSERT_TRUE(service.write_to_disk(blendfilename));
EXPECT_EQ(cdf_filename, service.get_catalog_definition_file()->file_path);
@@ -650,7 +652,8 @@ TEST_F(AssetCatalogTest, on_blendfile_save__from_memory_into_empty_directory)
TEST_F(AssetCatalogTest, on_blendfile_save__from_memory_into_existing_cdf_and_merge)
{
const CatalogFilePath target_dir = create_temp_path(); /* Has trailing slash. */
- const CatalogFilePath original_cdf_file = asset_library_root_ + "/blender_assets.cats.txt";
+ const CatalogFilePath original_cdf_file = asset_library_root_ + SEP_STR +
+ "blender_assets.cats.txt";
CatalogFilePath writable_cdf_file = target_dir + AssetCatalogService::DEFAULT_CATALOG_FILENAME;
BLI_path_slash_native(writable_cdf_file.data());
ASSERT_EQ(0, BLI_copy(original_cdf_file.c_str(), writable_cdf_file.c_str()));
@@ -719,7 +722,7 @@ TEST_F(AssetCatalogTest, create_first_catalog_from_scratch)
service.write_to_disk(temp_lib_root + "phony.blend");
EXPECT_TRUE(BLI_is_dir(temp_lib_root.c_str()));
- const CatalogFilePath definition_file_path = temp_lib_root + "/" +
+ const CatalogFilePath definition_file_path = temp_lib_root + SEP_STR +
AssetCatalogService::DEFAULT_CATALOG_FILENAME;
EXPECT_TRUE(BLI_is_file(definition_file_path.c_str()));
@@ -739,7 +742,7 @@ TEST_F(AssetCatalogTest, create_catalog_after_loading_file)
/* Copy the asset catalog definition files to a separate location, so that we can test without
* overwriting the test file in SVN. */
- const CatalogFilePath default_catalog_path = asset_library_root_ + "/" +
+ const CatalogFilePath default_catalog_path = asset_library_root_ + SEP_STR +
AssetCatalogService::DEFAULT_CATALOG_FILENAME;
const CatalogFilePath writable_catalog_path = temp_lib_root +
AssetCatalogService::DEFAULT_CATALOG_FILENAME;
@@ -801,7 +804,7 @@ TEST_F(AssetCatalogTest, create_catalog_simple_name)
TEST_F(AssetCatalogTest, delete_catalog_leaf)
{
AssetCatalogService service(asset_library_root_);
- service.load_from_disk(asset_library_root_ + "/" + "blender_assets.cats.txt");
+ service.load_from_disk(asset_library_root_ + SEP_STR + "blender_assets.cats.txt");
/* Delete a leaf catalog, i.e. one that is not a parent of another catalog.
* This keeps this particular test easy. */
@@ -833,7 +836,7 @@ TEST_F(AssetCatalogTest, delete_catalog_leaf)
TEST_F(AssetCatalogTest, delete_catalog_parent_by_id)
{
TestableAssetCatalogService service(asset_library_root_);
- service.load_from_disk(asset_library_root_ + "/" + "blender_assets.cats.txt");
+ service.load_from_disk(asset_library_root_ + SEP_STR + "blender_assets.cats.txt");
/* Delete a parent catalog. */
service.delete_catalog_by_id_soft(UUID_POSES_RUZENA);
@@ -847,7 +850,7 @@ TEST_F(AssetCatalogTest, delete_catalog_parent_by_id)
TEST_F(AssetCatalogTest, delete_catalog_parent_by_path)
{
AssetCatalogService service(asset_library_root_);
- service.load_from_disk(asset_library_root_ + "/" + "blender_assets.cats.txt");
+ service.load_from_disk(asset_library_root_ + SEP_STR + "blender_assets.cats.txt");
/* Create an extra catalog with the to-be-deleted path, and one with a child of that.
* This creates some duplicates that are bound to occur in production asset libraries as well.
@@ -887,14 +890,14 @@ TEST_F(AssetCatalogTest, delete_catalog_parent_by_path)
TEST_F(AssetCatalogTest, delete_catalog_write_to_disk)
{
TestableAssetCatalogService service(asset_library_root_);
- service.load_from_disk(asset_library_root_ + "/" +
+ service.load_from_disk(asset_library_root_ + SEP_STR +
AssetCatalogService::DEFAULT_CATALOG_FILENAME);
service.delete_catalog_by_id_soft(UUID_POSES_ELLIE);
const CatalogFilePath save_to_path = use_temp_path();
AssetCatalogDefinitionFile *cdf = service.get_catalog_definition_file();
- cdf->write_to_disk(save_to_path + "/" + AssetCatalogService::DEFAULT_CATALOG_FILENAME);
+ cdf->write_to_disk(save_to_path + SEP_STR + AssetCatalogService::DEFAULT_CATALOG_FILENAME);
AssetCatalogService loaded_service(save_to_path);
loaded_service.load_from_disk();
@@ -911,7 +914,7 @@ TEST_F(AssetCatalogTest, delete_catalog_write_to_disk)
TEST_F(AssetCatalogTest, update_catalog_path)
{
AssetCatalogService service(asset_library_root_);
- service.load_from_disk(asset_library_root_ + "/" +
+ service.load_from_disk(asset_library_root_ + SEP_STR +
AssetCatalogService::DEFAULT_CATALOG_FILENAME);
const AssetCatalog *orig_cat = service.find_catalog(UUID_POSES_RUZENA);
@@ -940,7 +943,7 @@ TEST_F(AssetCatalogTest, update_catalog_path)
TEST_F(AssetCatalogTest, update_catalog_path_simple_name)
{
AssetCatalogService service(asset_library_root_);
- service.load_from_disk(asset_library_root_ + "/" +
+ service.load_from_disk(asset_library_root_ + SEP_STR +
AssetCatalogService::DEFAULT_CATALOG_FILENAME);
service.update_catalog_path(UUID_POSES_RUZENA, "charlib/Ružena");
@@ -956,7 +959,7 @@ TEST_F(AssetCatalogTest, update_catalog_path_simple_name)
TEST_F(AssetCatalogTest, update_catalog_path_longer_than_simplename)
{
AssetCatalogService service(asset_library_root_);
- service.load_from_disk(asset_library_root_ + "/" +
+ service.load_from_disk(asset_library_root_ + SEP_STR +
AssetCatalogService::DEFAULT_CATALOG_FILENAME);
const std::string new_path =
"this/is/a/very/long/path/that/exceeds/the/simple-name/length/of/assets";
@@ -978,7 +981,7 @@ TEST_F(AssetCatalogTest, update_catalog_path_longer_than_simplename)
TEST_F(AssetCatalogTest, update_catalog_path_add_slashes)
{
AssetCatalogService service(asset_library_root_);
- service.load_from_disk(asset_library_root_ + "/" +
+ service.load_from_disk(asset_library_root_ + SEP_STR +
AssetCatalogService::DEFAULT_CATALOG_FILENAME);
const AssetCatalog *orig_cat = service.find_catalog(UUID_POSES_RUZENA);
@@ -1019,8 +1022,10 @@ TEST_F(AssetCatalogTest, update_catalog_path_add_slashes)
TEST_F(AssetCatalogTest, merge_catalog_files)
{
const CatalogFilePath cdf_dir = create_temp_path();
- const CatalogFilePath original_cdf_file = asset_library_root_ + "/blender_assets.cats.txt";
- const CatalogFilePath modified_cdf_file = asset_library_root_ + "/modified_assets.cats.txt";
+ const CatalogFilePath original_cdf_file = asset_library_root_ + SEP_STR +
+ "blender_assets.cats.txt";
+ const CatalogFilePath modified_cdf_file = asset_library_root_ + SEP_STR +
+ "modified_assets.cats.txt";
const CatalogFilePath temp_cdf_file = cdf_dir + "blender_assets.cats.txt";
ASSERT_EQ(0, BLI_copy(original_cdf_file.c_str(), temp_cdf_file.c_str()));
@@ -1059,8 +1064,10 @@ TEST_F(AssetCatalogTest, merge_catalog_files)
TEST_F(AssetCatalogTest, refresh_catalogs_with_modification)
{
const CatalogFilePath cdf_dir = create_temp_path();
- const CatalogFilePath original_cdf_file = asset_library_root_ + "/blender_assets.cats.txt";
- const CatalogFilePath modified_cdf_file = asset_library_root_ + "/catalog_reload_test.cats.txt";
+ const CatalogFilePath original_cdf_file = asset_library_root_ + SEP_STR +
+ "blender_assets.cats.txt";
+ const CatalogFilePath modified_cdf_file = asset_library_root_ + SEP_STR +
+ "catalog_reload_test.cats.txt";
const CatalogFilePath temp_cdf_file = cdf_dir + "blender_assets.cats.txt";
ASSERT_EQ(0, BLI_copy(original_cdf_file.c_str(), temp_cdf_file.c_str()));
@@ -1131,8 +1138,9 @@ TEST_F(AssetCatalogTest, refresh_catalogs_with_modification)
TEST_F(AssetCatalogTest, backups)
{
const CatalogFilePath cdf_dir = create_temp_path();
- const CatalogFilePath original_cdf_file = asset_library_root_ + "/blender_assets.cats.txt";
- const CatalogFilePath writable_cdf_file = cdf_dir + "/blender_assets.cats.txt";
+ const CatalogFilePath original_cdf_file = asset_library_root_ + SEP_STR +
+ "blender_assets.cats.txt";
+ const CatalogFilePath writable_cdf_file = cdf_dir + SEP_STR + "blender_assets.cats.txt";
ASSERT_EQ(0, BLI_copy(original_cdf_file.c_str(), writable_cdf_file.c_str()));
/* Read a CDF, modify, and write it. */
diff --git a/source/blender/blenkernel/intern/asset_library.cc b/source/blender/blenkernel/intern/asset_library.cc
index 968873cbcbe..4dccee425c6 100644
--- a/source/blender/blenkernel/intern/asset_library.cc
+++ b/source/blender/blenkernel/intern/asset_library.cc
@@ -7,10 +7,14 @@
#include <memory>
#include "BKE_asset_library.hh"
+#include "BKE_asset_representation.hh"
+#include "BKE_lib_remap.h"
#include "BKE_main.h"
#include "BKE_preferences.h"
+#include "BLI_fileops.h"
#include "BLI_path_util.h"
+#include "BLI_set.hh"
#include "DNA_asset_types.h"
#include "DNA_userdef_types.h"
@@ -19,6 +23,13 @@
bool blender::bke::AssetLibrary::save_catalogs_when_file_is_saved = true;
+blender::bke::AssetLibrary *BKE_asset_library_load(const Main *bmain,
+ const AssetLibraryReference &library_reference)
+{
+ blender::bke::AssetLibraryService *service = blender::bke::AssetLibraryService::get();
+ return service->get_asset_library(bmain, library_reference);
+}
+
/**
* Loading an asset library at this point only means loading the catalogs. Later on this should
* invoke reading of asset representations too.
@@ -42,22 +53,22 @@ bool BKE_asset_library_has_any_unsaved_catalogs()
return service->has_any_unsaved_catalogs();
}
-bool BKE_asset_library_find_suitable_root_path_from_path(const char *input_path,
- char *r_library_path)
+std::string BKE_asset_library_find_suitable_root_path_from_path(
+ const blender::StringRefNull input_path)
{
if (bUserAssetLibrary *preferences_lib = BKE_preferences_asset_library_containing_path(
- &U, input_path)) {
- BLI_strncpy(r_library_path, preferences_lib->path, FILE_MAXDIR);
- return true;
+ &U, input_path.c_str())) {
+ return preferences_lib->path;
}
- BLI_split_dir_part(input_path, r_library_path, FILE_MAXDIR);
- return r_library_path[0] != '\0';
+ char buffer[FILE_MAXDIR];
+ BLI_split_dir_part(input_path.c_str(), buffer, FILE_MAXDIR);
+ return buffer;
}
-bool BKE_asset_library_find_suitable_root_path_from_main(const Main *bmain, char *r_library_path)
+std::string BKE_asset_library_find_suitable_root_path_from_main(const Main *bmain)
{
- return BKE_asset_library_find_suitable_root_path_from_path(bmain->filepath, r_library_path);
+ return BKE_asset_library_find_suitable_root_path_from_path(bmain->filepath);
}
blender::bke::AssetCatalogService *BKE_asset_library_get_catalog_service(
@@ -90,6 +101,13 @@ void BKE_asset_library_refresh_catalog_simplename(struct AssetLibrary *asset_lib
lib->refresh_catalog_simplename(asset_data);
}
+void BKE_asset_library_remap_ids(IDRemapper *mappings)
+{
+ blender::bke::AssetLibraryService *service = blender::bke::AssetLibraryService::get();
+ service->foreach_loaded_asset_library(
+ [mappings](blender::bke::AssetLibrary &library) { library.remap_ids(*mappings); });
+}
+
namespace blender::bke {
AssetLibrary::AssetLibrary() : catalog_service(std::make_unique<AssetCatalogService>())
@@ -103,7 +121,7 @@ AssetLibrary::~AssetLibrary()
}
}
-void AssetLibrary::load(StringRefNull library_root_directory)
+void AssetLibrary::load_catalogs(StringRefNull library_root_directory)
{
auto catalog_service = std::make_unique<AssetCatalogService>(library_root_directory);
catalog_service->load_from_disk();
@@ -115,6 +133,44 @@ void AssetLibrary::refresh()
this->catalog_service->reload_catalogs();
}
+AssetRepresentation &AssetLibrary::add_external_asset(StringRef name,
+ std::unique_ptr<AssetMetaData> metadata)
+{
+ asset_storage_.append(std::make_unique<AssetRepresentation>(name, std::move(metadata)));
+ return *asset_storage_.last();
+}
+
+AssetRepresentation &AssetLibrary::add_local_id_asset(ID &id)
+{
+ asset_storage_.append(std::make_unique<AssetRepresentation>(id));
+ return *asset_storage_.last();
+}
+
+std::optional<int> AssetLibrary::find_asset_index(const AssetRepresentation &asset)
+{
+ int index = 0;
+ /* Find index of asset. */
+ for (auto &asset_uptr : asset_storage_) {
+ if (&asset == asset_uptr.get()) {
+ return index;
+ }
+ index++;
+ }
+
+ return {};
+}
+
+bool AssetLibrary::remove_asset(AssetRepresentation &asset)
+{
+ std::optional<int> asset_index = find_asset_index(asset);
+ if (!asset_index) {
+ return false;
+ }
+
+ asset_storage_.remove_and_reorder(*asset_index);
+ return true;
+}
+
namespace {
void asset_library_on_save_post(struct Main *main,
struct PointerRNA **pointers,
@@ -158,6 +214,28 @@ void AssetLibrary::on_blend_save_post(struct Main *main,
}
}
+void AssetLibrary::remap_ids(IDRemapper &mappings)
+{
+ Set<AssetRepresentation *> removed_id_assets;
+
+ for (auto &asset_uptr : asset_storage_) {
+ if (!asset_uptr->is_local_id()) {
+ continue;
+ }
+
+ IDRemapperApplyResult result = BKE_id_remapper_apply(
+ &mappings, &asset_uptr->local_asset_id_, ID_REMAP_APPLY_DEFAULT);
+ if (result == ID_REMAP_RESULT_SOURCE_UNASSIGNED) {
+ removed_id_assets.add(asset_uptr.get());
+ }
+ }
+
+ /* Remove the assets from storage. */
+ for (AssetRepresentation *asset : removed_id_assets) {
+ remove_asset(*asset);
+ }
+}
+
void AssetLibrary::refresh_catalog_simplename(struct AssetMetaData *asset_data)
{
if (BLI_uuid_is_nil(asset_data->catalog_id)) {
@@ -172,4 +250,26 @@ void AssetLibrary::refresh_catalog_simplename(struct AssetMetaData *asset_data)
}
STRNCPY(asset_data->catalog_simple_name, catalog->simple_name.c_str());
}
+
+Vector<AssetLibraryReference> all_valid_asset_library_refs()
+{
+ Vector<AssetLibraryReference> result;
+ int i;
+ LISTBASE_FOREACH_INDEX (const bUserAssetLibrary *, asset_library, &U.asset_libraries, i) {
+ if (!BLI_is_dir(asset_library->path)) {
+ continue;
+ }
+ AssetLibraryReference library_ref{};
+ library_ref.custom_library_index = i;
+ library_ref.type = ASSET_LIBRARY_CUSTOM;
+ result.append(library_ref);
+ }
+
+ AssetLibraryReference library_ref{};
+ library_ref.custom_library_index = -1;
+ library_ref.type = ASSET_LIBRARY_LOCAL;
+ result.append(library_ref);
+ return result;
+}
+
} // namespace blender::bke
diff --git a/source/blender/blenkernel/intern/asset_library_service.cc b/source/blender/blenkernel/intern/asset_library_service.cc
index a6b2b7548a2..35441b9b795 100644
--- a/source/blender/blenkernel/intern/asset_library_service.cc
+++ b/source/blender/blenkernel/intern/asset_library_service.cc
@@ -6,12 +6,17 @@
#include "asset_library_service.hh"
+#include "BKE_asset_library.hh"
#include "BKE_blender.h"
+#include "BKE_preferences.h"
#include "BLI_fileops.h" /* For PATH_MAX (at least on Windows). */
#include "BLI_path_util.h"
#include "BLI_string_ref.hh"
+#include "DNA_asset_types.h"
+#include "DNA_userdef_types.h"
+
#include "CLG_log.h"
static CLG_LogRef LOG = {"bke.asset_service"};
@@ -38,13 +43,40 @@ void AssetLibraryService::destroy()
instance_.reset();
}
+AssetLibrary *AssetLibraryService::get_asset_library(
+ const Main *bmain, const AssetLibraryReference &library_reference)
+{
+ if (library_reference.type == ASSET_LIBRARY_LOCAL) {
+ /* For the "Current File" library we get the asset library root path based on main. */
+ std::string root_path = bmain ? BKE_asset_library_find_suitable_root_path_from_main(bmain) :
+ "";
+
+ if (root_path.empty()) {
+ /* File wasn't saved yet. */
+ return get_asset_library_current_file();
+ }
+
+ return get_asset_library_on_disk(root_path);
+ }
+ if (library_reference.type == ASSET_LIBRARY_CUSTOM) {
+ bUserAssetLibrary *user_library = BKE_preferences_asset_library_find_from_index(
+ &U, library_reference.custom_library_index);
+
+ if (user_library) {
+ return get_asset_library_on_disk(user_library->path);
+ }
+ }
+
+ return nullptr;
+}
+
namespace {
std::string normalize_directory_path(StringRefNull directory)
{
char dir_normalized[PATH_MAX];
STRNCPY(dir_normalized, directory.c_str());
- BLI_path_normalize_dir(nullptr, dir_normalized);
+ BLI_path_normalize_dir(nullptr, dir_normalized, sizeof(dir_normalized));
return std::string(dir_normalized);
}
} // namespace
@@ -68,7 +100,7 @@ AssetLibrary *AssetLibraryService::get_asset_library_on_disk(StringRefNull top_l
AssetLibrary *lib = lib_uptr.get();
lib->on_blend_save_handler_register();
- lib->load(top_dir_trailing_slash);
+ lib->load_catalogs(top_dir_trailing_slash);
on_disk_libraries_.add_new(top_dir_trailing_slash, std::move(lib_uptr));
CLOG_INFO(&LOG, 2, "get \"%s\" (loaded)", top_dir_trailing_slash.c_str());
@@ -144,4 +176,15 @@ bool AssetLibraryService::has_any_unsaved_catalogs() const
return false;
}
+void AssetLibraryService::foreach_loaded_asset_library(FunctionRef<void(AssetLibrary &)> fn) const
+{
+ if (current_file_library_) {
+ fn(*current_file_library_);
+ }
+
+ for (const auto &asset_lib_uptr : on_disk_libraries_.values()) {
+ fn(*asset_lib_uptr);
+ }
+}
+
} // namespace blender::bke
diff --git a/source/blender/blenkernel/intern/asset_library_service.hh b/source/blender/blenkernel/intern/asset_library_service.hh
index 277fb9db6cc..6caaea72875 100644
--- a/source/blender/blenkernel/intern/asset_library_service.hh
+++ b/source/blender/blenkernel/intern/asset_library_service.hh
@@ -12,10 +12,13 @@
#include "BKE_asset_library.hh"
+#include "BLI_function_ref.hh"
#include "BLI_map.hh"
#include <memory>
+struct AssetLibraryReference;
+
namespace blender::bke {
/**
@@ -44,6 +47,9 @@ class AssetLibraryService {
/** Destroy the AssetLibraryService singleton. It will be reallocated by #get() if necessary. */
static void destroy();
+ AssetLibrary *get_asset_library(const Main *bmain,
+ const AssetLibraryReference &library_reference);
+
/**
* Get the given asset library. Opens it (i.e. creates a new AssetLibrary instance) if necessary.
*/
@@ -55,11 +61,16 @@ class AssetLibraryService {
/** Returns whether there are any known asset libraries with unsaved catalog edits. */
bool has_any_unsaved_catalogs() const;
+ void foreach_loaded_asset_library(FunctionRef<void(AssetLibrary &)> fn) const;
+
protected:
static std::unique_ptr<AssetLibraryService> instance_;
/* Mapping absolute path of the library's top-level directory to the AssetLibrary instance. */
Map<std::string, AssetLibraryPtr> on_disk_libraries_;
+ /** Library without a known path, i.e. the "Current File" library if the file isn't saved yet. If
+ * the file was saved, a valid path for the library can be determined and #on_disk_libraries_
+ * above should be used. */
AssetLibraryPtr current_file_library_;
/* Handlers for managing the life cycle of the AssetLibraryService instance. */
diff --git a/source/blender/blenkernel/intern/asset_library_service_test.cc b/source/blender/blenkernel/intern/asset_library_service_test.cc
index de6180cb684..18fdcb80155 100644
--- a/source/blender/blenkernel/intern/asset_library_service_test.cc
+++ b/source/blender/blenkernel/intern/asset_library_service_test.cc
@@ -8,6 +8,9 @@
#include "BKE_appdir.h"
#include "BKE_callbacks.h"
+#include "BKE_main.h"
+
+#include "DNA_asset_types.h"
#include "CLG_log.h"
@@ -39,7 +42,7 @@ class AssetLibraryServiceTest : public testing::Test {
if (test_files_dir.empty()) {
FAIL();
}
- asset_library_root_ = test_files_dir + "/" + "asset_library";
+ asset_library_root_ = test_files_dir + SEP_STR + "asset_library";
temp_library_path_ = "";
}
@@ -59,7 +62,7 @@ class AssetLibraryServiceTest : public testing::Test {
{
BKE_tempdir_init("");
const CatalogFilePath tempdir = BKE_tempdir_session();
- temp_library_path_ = tempdir + "test-temporary-path/";
+ temp_library_path_ = tempdir + "test-temporary-path" + SEP_STR;
return temp_library_path_;
}
@@ -102,6 +105,26 @@ TEST_F(AssetLibraryServiceTest, library_pointers)
* cannot be reliably tested by just pointer comparison, though. */
}
+TEST_F(AssetLibraryServiceTest, library_from_reference)
+{
+ AssetLibraryService *service = AssetLibraryService::get();
+ AssetLibrary *const lib = service->get_asset_library_on_disk(asset_library_root_);
+ AssetLibrary *const curfile_lib = service->get_asset_library_current_file();
+
+ AssetLibraryReference ref{};
+ ref.type = ASSET_LIBRARY_LOCAL;
+ EXPECT_EQ(curfile_lib, service->get_asset_library(nullptr, ref))
+ << "Getting the local (current file) reference without a main saved on disk should return "
+ "the current file library";
+
+ Main dummy_main{};
+ std::string dummy_filepath = asset_library_root_ + SEP + "dummy.blend";
+ BLI_strncpy(dummy_main.filepath, dummy_filepath.c_str(), sizeof(dummy_main.filepath));
+ EXPECT_EQ(lib, service->get_asset_library(&dummy_main, ref))
+ << "Getting the local (current file) reference with a main saved on disk should return "
+ "the an asset library for this directory";
+}
+
TEST_F(AssetLibraryServiceTest, library_path_trailing_slashes)
{
AssetLibraryService *service = AssetLibraryService::get();
@@ -118,7 +141,7 @@ TEST_F(AssetLibraryServiceTest, library_path_trailing_slashes)
asset_lib_no_slash[strlen(asset_lib_no_slash) - 1] = '\0';
}
- BLI_path_slash_ensure(asset_lib_with_slash);
+ BLI_path_slash_ensure(asset_lib_with_slash, PATH_MAX);
AssetLibrary *const lib_no_slash = service->get_asset_library_on_disk(asset_lib_no_slash);
@@ -168,7 +191,8 @@ TEST_F(AssetLibraryServiceTest, has_any_unsaved_catalogs)
TEST_F(AssetLibraryServiceTest, has_any_unsaved_catalogs_after_write)
{
const CatalogFilePath writable_dir = create_temp_path(); /* Has trailing slash. */
- const CatalogFilePath original_cdf_file = asset_library_root_ + "/blender_assets.cats.txt";
+ const CatalogFilePath original_cdf_file = asset_library_root_ + SEP_STR +
+ "blender_assets.cats.txt";
CatalogFilePath writable_cdf_file = writable_dir + AssetCatalogService::DEFAULT_CATALOG_FILENAME;
BLI_path_slash_native(writable_cdf_file.data());
ASSERT_EQ(0, BLI_copy(original_cdf_file.c_str(), writable_cdf_file.c_str()));
diff --git a/source/blender/blenkernel/intern/asset_representation.cc b/source/blender/blenkernel/intern/asset_representation.cc
new file mode 100644
index 00000000000..bbaa634d5ad
--- /dev/null
+++ b/source/blender/blenkernel/intern/asset_representation.cc
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include <stdexcept>
+
+#include "DNA_ID.h"
+#include "DNA_asset_types.h"
+
+#include "BKE_asset.h"
+#include "BKE_asset_representation.hh"
+
+namespace blender::bke {
+
+AssetRepresentation::AssetRepresentation(StringRef name, std::unique_ptr<AssetMetaData> metadata)
+ : is_local_id_(false), external_asset_()
+{
+ external_asset_.name = name;
+ external_asset_.metadata_ = std::move(metadata);
+}
+
+AssetRepresentation::AssetRepresentation(ID &id) : is_local_id_(true), local_asset_id_(&id)
+{
+ if (!id.asset_data) {
+ throw std::invalid_argument("Passed ID is not an asset");
+ }
+}
+
+AssetRepresentation::AssetRepresentation(AssetRepresentation &&other)
+ : is_local_id_(other.is_local_id_)
+{
+ if (is_local_id_) {
+ local_asset_id_ = other.local_asset_id_;
+ other.local_asset_id_ = nullptr;
+ }
+ else {
+ external_asset_ = std::move(other.external_asset_);
+ }
+}
+
+AssetRepresentation::~AssetRepresentation()
+{
+ if (!is_local_id_) {
+ external_asset_.~ExternalAsset();
+ }
+}
+
+StringRefNull AssetRepresentation::get_name() const
+{
+ if (is_local_id_) {
+ return local_asset_id_->name + 2;
+ }
+
+ return external_asset_.name;
+}
+
+AssetMetaData &AssetRepresentation::get_metadata() const
+{
+ return is_local_id_ ? *local_asset_id_->asset_data : *external_asset_.metadata_;
+}
+
+bool AssetRepresentation::is_local_id() const
+{
+ return is_local_id_;
+}
+
+} // namespace blender::bke
+
+/* ---------------------------------------------------------------------- */
+/** \name C-API
+ * \{ */
+
+using namespace blender;
+
+const char *BKE_asset_representation_name_get(const AssetRepresentation *asset_handle)
+{
+ const bke::AssetRepresentation *asset = reinterpret_cast<const bke::AssetRepresentation *>(
+ asset_handle);
+ return asset->get_name().c_str();
+}
+
+AssetMetaData *BKE_asset_representation_metadata_get(const AssetRepresentation *asset_handle)
+{
+ const bke::AssetRepresentation *asset = reinterpret_cast<const bke::AssetRepresentation *>(
+ asset_handle);
+ return &asset->get_metadata();
+}
+
+bool BKE_asset_representation_is_local_id(const AssetRepresentation *asset_handle)
+{
+ const bke::AssetRepresentation *asset = reinterpret_cast<const bke::AssetRepresentation *>(
+ asset_handle);
+ return asset->is_local_id();
+}
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/asset_test.cc b/source/blender/blenkernel/intern/asset_test.cc
index fa8769862a8..5ff65054926 100644
--- a/source/blender/blenkernel/intern/asset_test.cc
+++ b/source/blender/blenkernel/intern/asset_test.cc
@@ -13,7 +13,7 @@ namespace blender::bke::tests {
TEST(AssetMetadataTest, set_catalog_id)
{
- AssetMetaData meta;
+ AssetMetaData meta{};
const bUUID uuid = BLI_uuid_generate_random();
/* Test trivial values. */
diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc
index f66a1f9ee93..1a54454bf9a 100644
--- a/source/blender/blenkernel/intern/attribute.cc
+++ b/source/blender/blenkernel/intern/attribute.cc
@@ -354,7 +354,7 @@ CustomDataLayer *BKE_id_attribute_search(ID *id,
get_domains(id, info);
for (eAttrDomain domain = ATTR_DOMAIN_POINT; domain < ATTR_DOMAIN_NUM;
- domain = static_cast<eAttrDomain>((static_cast<int>(domain)) + 1)) {
+ domain = static_cast<eAttrDomain>(int(domain) + 1)) {
if (!(domain_mask & ATTR_DOMAIN_AS_MASK(domain))) {
continue;
}
@@ -388,7 +388,7 @@ int BKE_id_attributes_length(const ID *id, eAttrDomainMask domain_mask, eCustomD
continue;
}
- if ((1 << (int)domain) & domain_mask) {
+ if ((1 << int(domain)) & domain_mask) {
length += CustomData_number_of_layers_typemask(customdata, mask);
}
}
@@ -452,12 +452,10 @@ int BKE_id_attribute_data_length(ID *id, CustomDataLayer *layer)
bool BKE_id_attribute_required(const ID *id, const char *name)
{
switch (GS(id->name)) {
- case ID_PT: {
- return BKE_pointcloud_customdata_required((const PointCloud *)id, name);
- }
- case ID_CV: {
- return BKE_curves_customdata_required((const Curves *)id, name);
- }
+ case ID_PT:
+ return BKE_pointcloud_attribute_required((const PointCloud *)id, name);
+ case ID_CV:
+ return BKE_curves_attribute_required((const Curves *)id, name);
default:
return false;
}
@@ -576,7 +574,7 @@ CustomDataLayer *BKE_id_attribute_from_index(ID *id,
for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) {
CustomData *customdata = info[domain].customdata;
- if (!customdata || !((1 << (int)domain) & domain_mask)) {
+ if (!customdata || !((1 << int(domain)) & domain_mask)) {
continue;
}
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 27c54a3d4a7..e5c43a3f90e 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -14,10 +14,13 @@
#include "DNA_meshdata_types.h"
#include "DNA_pointcloud_types.h"
+#include "BLI_array_utils.hh"
#include "BLI_color.hh"
#include "BLI_math_vec_types.hh"
#include "BLI_span.hh"
+#include "FN_field.hh"
+
#include "BLT_translation.h"
#include "CLG_log.h"
@@ -55,7 +58,8 @@ const char *no_procedural_access_message =
bool allow_procedural_attribute_access(StringRef attribute_name)
{
- return !attribute_name.startswith(".selection") && !attribute_name.startswith(".hide");
+ return !attribute_name.startswith(".sculpt") && !attribute_name.startswith(".select") &&
+ !attribute_name.startswith(".hide");
}
static int attribute_data_type_complexity(const eCustomDataType data_type)
@@ -243,11 +247,8 @@ static bool add_custom_data_layer_from_attribute_init(const AttributeIDRef &attr
}
case AttributeInit::Type::MoveArray: {
void *source_data = static_cast<const AttributeInitMoveArray &>(initializer).data;
- void *data = add_generic_custom_data_layer(
+ add_generic_custom_data_layer(
custom_data, data_type, CD_ASSIGN, source_data, domain_num, attribute_id);
- if (source_data != nullptr && data == nullptr) {
- MEM_freeN(source_data);
- }
break;
}
}
@@ -638,15 +639,26 @@ CustomDataAttributes::CustomDataAttributes(CustomDataAttributes &&other)
size_ = other.size_;
data = other.data;
CustomData_reset(&other.data);
+ other.size_ = 0;
}
CustomDataAttributes &CustomDataAttributes::operator=(const CustomDataAttributes &other)
{
- if (this != &other) {
- CustomData_copy(&other.data, &data, CD_MASK_ALL, CD_DUPLICATE, other.size_);
- size_ = other.size_;
+ if (this == &other) {
+ return *this;
}
+ this->~CustomDataAttributes();
+ new (this) CustomDataAttributes(other);
+ return *this;
+}
+CustomDataAttributes &CustomDataAttributes::operator=(CustomDataAttributes &&other)
+{
+ if (this == &other) {
+ return *this;
+ }
+ this->~CustomDataAttributes();
+ new (this) CustomDataAttributes(std::move(other));
return *this;
}
@@ -943,6 +955,15 @@ GSpanAttributeWriter MutableAttributeAccessor::lookup_or_add_for_write_only_span
return {};
}
+fn::GField AttributeValidator::validate_field_if_necessary(const fn::GField &field) const
+{
+ if (function) {
+ auto validate_op = fn::FieldOperation::Create(*function, {field});
+ return fn::GField(validate_op);
+ }
+ return field;
+}
+
Vector<AttributeTransferData> retrieve_attributes_for_transfer(
const bke::AttributeAccessor src_attributes,
bke::MutableAttributeAccessor dst_attributes,
@@ -974,6 +995,37 @@ Vector<AttributeTransferData> retrieve_attributes_for_transfer(
return attributes;
}
+void copy_attribute_domain(const AttributeAccessor src_attributes,
+ MutableAttributeAccessor dst_attributes,
+ const IndexMask selection,
+ const eAttrDomain domain,
+ const Set<std::string> &skip)
+{
+ src_attributes.for_all(
+ [&](const bke::AttributeIDRef &id, const bke::AttributeMetaData &meta_data) {
+ if (meta_data.domain != domain) {
+ return true;
+ }
+ if (id.is_named() && skip.contains(id.name())) {
+ return true;
+ }
+ if (!id.should_be_kept()) {
+ return true;
+ }
+
+ const GVArray src = src_attributes.lookup(id, meta_data.domain);
+ BLI_assert(src);
+
+ /* Copy attribute. */
+ GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span(
+ id, domain, meta_data.data_type);
+ array_utils::copy(src, selection, dst.span);
+ dst.finish();
+
+ return true;
+ });
+}
+
} // namespace blender::bke
/** \} */
diff --git a/source/blender/blenkernel/intern/attribute_access_intern.hh b/source/blender/blenkernel/intern/attribute_access_intern.hh
index 8050f45da94..33d415f1e0e 100644
--- a/source/blender/blenkernel/intern/attribute_access_intern.hh
+++ b/source/blender/blenkernel/intern/attribute_access_intern.hh
@@ -53,6 +53,7 @@ class BuiltinAttributeProvider {
const CreatableEnum createable_;
const WritableEnum writable_;
const DeletableEnum deletable_;
+ const AttributeValidator validator_;
public:
BuiltinAttributeProvider(std::string name,
@@ -60,13 +61,15 @@ class BuiltinAttributeProvider {
const eCustomDataType data_type,
const CreatableEnum createable,
const WritableEnum writable,
- const DeletableEnum deletable)
+ const DeletableEnum deletable,
+ AttributeValidator validator = {})
: name_(std::move(name)),
domain_(domain),
data_type_(data_type),
createable_(createable),
writable_(writable),
- deletable_(deletable)
+ deletable_(deletable),
+ validator_(validator)
{
}
@@ -90,6 +93,11 @@ class BuiltinAttributeProvider {
{
return data_type_;
}
+
+ AttributeValidator validator() const
+ {
+ return validator_;
+ }
};
/**
@@ -241,9 +249,15 @@ class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider {
const CustomDataAccessInfo custom_data_access,
const AsReadAttribute as_read_attribute,
const AsWriteAttribute as_write_attribute,
- const UpdateOnChange update_on_write)
- : BuiltinAttributeProvider(
- std::move(attribute_name), domain, attribute_type, creatable, writable, deletable),
+ const UpdateOnChange update_on_write,
+ const AttributeValidator validator = {})
+ : BuiltinAttributeProvider(std::move(attribute_name),
+ domain,
+ attribute_type,
+ creatable,
+ writable,
+ deletable,
+ validator),
stored_type_(stored_type),
custom_data_access_(custom_data_access),
as_read_attribute_(as_read_attribute),
@@ -320,7 +334,7 @@ class ComponentAttributeProviders {
namespace attribute_accessor_functions {
template<const ComponentAttributeProviders &providers>
-inline bool is_builtin(const void *UNUSED(owner), const AttributeIDRef &attribute_id)
+inline bool is_builtin(const void * /*owner*/, const AttributeIDRef &attribute_id)
{
if (!attribute_id.is_named()) {
return false;
@@ -379,6 +393,21 @@ inline bool for_all(const void *owner,
}
template<const ComponentAttributeProviders &providers>
+inline AttributeValidator lookup_validator(const void * /*owner*/,
+ const blender::bke::AttributeIDRef &attribute_id)
+{
+ if (!attribute_id.is_named()) {
+ return {};
+ }
+ const BuiltinAttributeProvider *provider =
+ providers.builtin_attribute_providers().lookup_default_as(attribute_id.name(), nullptr);
+ if (!provider) {
+ return {};
+ }
+ return provider->validator();
+}
+
+template<const ComponentAttributeProviders &providers>
inline bool contains(const void *owner, const blender::bke::AttributeIDRef &attribute_id)
{
bool found = false;
@@ -489,6 +518,7 @@ inline AttributeAccessorFunctions accessor_functions_for_providers()
lookup<providers>,
nullptr,
for_all<providers>,
+ lookup_validator<providers>,
lookup_for_write<providers>,
remove<providers>,
add<providers>};
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 947cdc0c8bf..3598201d906 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -59,11 +59,10 @@ void BKE_blender_free(void)
{
/* samples are in a global list..., also sets G_MAIN->sound->sample NULL */
- /* Needs to run before main free as wm is still referenced for icons preview jobs. */
+ /* Needs to run before main free as window-manager is still referenced for icons preview jobs. */
BKE_studiolight_free();
- BKE_main_free(G_MAIN);
- G_MAIN = NULL;
+ BKE_blender_globals_clear();
if (G.log.file != NULL) {
fclose(G.log.file);
@@ -146,7 +145,7 @@ void BKE_blender_globals_init(void)
U.savetime = 1;
- G_MAIN = BKE_main_new();
+ BKE_blender_globals_main_replace(BKE_main_new());
strcpy(G.ima, "//");
@@ -161,11 +160,34 @@ void BKE_blender_globals_init(void)
void BKE_blender_globals_clear(void)
{
+ if (G_MAIN == NULL) {
+ return;
+ }
+ BLI_assert(G_MAIN->is_global_main);
BKE_main_free(G_MAIN); /* free all lib data */
G_MAIN = NULL;
}
+void BKE_blender_globals_main_replace(Main *bmain)
+{
+ BLI_assert(!bmain->is_global_main);
+ BKE_blender_globals_clear();
+ bmain->is_global_main = true;
+ G_MAIN = bmain;
+}
+
+Main *BKE_blender_globals_main_swap(Main *new_gmain)
+{
+ Main *old_gmain = G_MAIN;
+ BLI_assert(old_gmain->is_global_main);
+ BLI_assert(!new_gmain->is_global_main);
+ new_gmain->is_global_main = true;
+ G_MAIN = new_gmain;
+ old_gmain->is_global_main = false;
+ return old_gmain;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/blender_copybuffer.c b/source/blender/blenkernel/intern/blender_copybuffer.c
index 4b507beb6b3..82df2714a71 100644
--- a/source/blender/blenkernel/intern/blender_copybuffer.c
+++ b/source/blender/blenkernel/intern/blender_copybuffer.c
@@ -150,7 +150,7 @@ int BKE_copybuffer_paste(bContext *C,
return 0;
}
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
copybuffer_append(lapp_context, bmain, reports);
diff --git a/source/blender/blenkernel/intern/blender_undo.c b/source/blender/blenkernel/intern/blender_undo.c
index a5096b4f9eb..f22dfc6054a 100644
--- a/source/blender/blenkernel/intern/blender_undo.c
+++ b/source/blender/blenkernel/intern/blender_undo.c
@@ -116,7 +116,7 @@ MemFileUndoData *BKE_memfile_undo_encode(Main *bmain, MemFileUndoData *mfu_prev)
counter = counter % U.undosteps;
BLI_snprintf(numstr, sizeof(numstr), "%d.blend", counter);
- BLI_join_dirfile(filepath, sizeof(filepath), BKE_tempdir_session(), numstr);
+ BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_session(), numstr);
/* success = */ /* UNUSED */ BLO_write_file(
bmain, filepath, fileflags, &(const struct BlendFileWriteParams){0}, NULL);
diff --git a/source/blender/blenkernel/intern/blender_user_menu.c b/source/blender/blenkernel/intern/blender_user_menu.c
index 86dd31576dd..9db8df52487 100644
--- a/source/blender/blenkernel/intern/blender_user_menu.c
+++ b/source/blender/blenkernel/intern/blender_user_menu.c
@@ -25,7 +25,7 @@
bUserMenu *BKE_blender_user_menu_find(ListBase *lb, char space_type, const char *context)
{
LISTBASE_FOREACH (bUserMenu *, um, lb) {
- if ((space_type == um->space_type) && (STREQ(context, um->context))) {
+ if ((space_type == um->space_type) && STREQ(context, um->context)) {
return um;
}
}
diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c
index d7f30c99397..8b0d3f2e92e 100644
--- a/source/blender/blenkernel/intern/blendfile.c
+++ b/source/blender/blenkernel/intern/blendfile.c
@@ -16,6 +16,7 @@
#include "DNA_screen_types.h"
#include "DNA_workspace_types.h"
+#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
@@ -61,7 +62,7 @@
#endif
/* -------------------------------------------------------------------- */
-/** \name High Level `.blend` file read/write.
+/** \name Blend File IO (High Level)
* \{ */
static bool blendfile_or_libraries_versions_atleast(Main *bmain,
@@ -185,7 +186,7 @@ static void setup_app_data(bContext *C,
clean_paths(bfd->main);
}
- /* XXX here the complex windowmanager matching */
+ /* The following code blocks performs complex window-manager matching. */
/* no load screens? */
if (mode != LOAD_UI) {
@@ -286,11 +287,8 @@ static void setup_app_data(bContext *C,
}
}
- /* free G_MAIN Main database */
- // CTX_wm_manager_set(C, NULL);
- BKE_blender_globals_clear();
-
- bmain = G_MAIN = bfd->main;
+ BKE_blender_globals_main_replace(bfd->main);
+ bmain = G_MAIN;
bfd->main = NULL;
CTX_data_main_set(C, bmain);
@@ -364,7 +362,7 @@ static void setup_app_data(bContext *C,
BKE_lib_override_library_main_hierarchy_root_ensure(bmain);
}
- bmain->recovered = 0;
+ bmain->recovered = false;
/* startup.blend or recovered startup */
if (is_startup) {
@@ -372,7 +370,7 @@ static void setup_app_data(bContext *C,
}
else if (recover) {
/* In case of autosave or quit.blend, use original filepath instead. */
- bmain->recovered = 1;
+ bmain->recovered = true;
STRNCPY(bmain->filepath, bfd->filepath);
}
@@ -559,6 +557,34 @@ void BKE_blendfile_read_make_empty(bContext *C)
FOREACH_MAIN_LISTBASE_END;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Blend File IO (Preferences)
+ *
+ * Application Templates
+ * =====================
+ *
+ * When using app-templates, both regular & app-template preferences are used.
+ * Note that "regular" preferences refers to the preferences used with no app-template is active.
+ *
+ * - Reading preferences is performed for both the app-template & regular preferences.
+ *
+ * The preferences are merged by using some from the app-template and other settings from the
+ * regular preferences (add-ons from the app-template for example are used),
+ * undo-memory uses the regular preferences (for e.g.).
+ *
+ * - Writing preferences is performed for both the app-template & regular preferences.
+ *
+ * Writing unmodified preference (#U) into the regular preferences
+ * would loose any settings the app-template overrides.
+ * To keep default settings the regular preferences is read, add-ons etc temporarily swapped
+ * into #U for writing, then swapped back out so as not to change the run-time preferences.
+ *
+ * \note The function #BKE_blender_userdef_app_template_data_swap determines which settings
+ * the app-template overrides.
+ * \{ */
+
UserDef *BKE_blendfile_userdef_read(const char *filepath, ReportList *reports)
{
BlendFileData *bfd;
@@ -683,10 +709,15 @@ bool BKE_blendfile_userdef_write(const char *filepath, ReportList *reports)
bool BKE_blendfile_userdef_write_app_template(const char *filepath, ReportList *reports)
{
- /* if it fails, overwrite is OK. */
- UserDef *userdef_default = BKE_blendfile_userdef_read(filepath, NULL);
+ /* Checking that `filepath` exists is not essential, it just avoids printing a warning that
+ * the file can't be found. In this case it's not an error - as the file is used if it exists,
+ * falling back to the defaults.
+ * If the preferences exists but file reading fails - the file can be assumed corrupt
+ * so overwriting the file is OK. */
+ UserDef *userdef_default = BLI_exists(filepath) ? BKE_blendfile_userdef_read(filepath, NULL) :
+ NULL;
if (userdef_default == NULL) {
- return BKE_blendfile_userdef_write(filepath, reports);
+ userdef_default = BKE_blendfile_userdef_from_defaults();
}
BKE_blender_userdef_app_template_data_swap(&U, userdef_default);
@@ -706,7 +737,7 @@ bool BKE_blendfile_userdef_write_all(ReportList *reports)
if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL))) {
bool ok_write;
- BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE, NULL);
+ BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE);
printf("Writing userprefs: '%s' ", filepath);
if (use_template_userpref) {
@@ -733,7 +764,7 @@ bool BKE_blendfile_userdef_write_all(ReportList *reports)
if (use_template_userpref) {
if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, U.app_template))) {
/* Also save app-template prefs */
- BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE, NULL);
+ BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE);
printf("Writing userprefs app-template: '%s' ", filepath);
if (BKE_blendfile_userdef_write(filepath, reports) != 0) {
@@ -756,6 +787,12 @@ bool BKE_blendfile_userdef_write_all(ReportList *reports)
return ok;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Blend File IO (WorkSpace)
+ * \{ */
+
WorkspaceConfigFileData *BKE_blendfile_workspace_config_read(const char *filepath,
const void *filebuf,
int filelength,
@@ -818,7 +855,7 @@ void BKE_blendfile_workspace_config_data_free(WorkspaceConfigFileData *workspace
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Partial `.blend` file save.
+/** \name Blend File Write (Partial)
* \{ */
void BKE_blendfile_write_partial_begin(Main *bmain_src)
diff --git a/source/blender/blenkernel/intern/blendfile_link_append.c b/source/blender/blenkernel/intern/blendfile_link_append.c
index d9ca1e74391..4dd225c09ec 100644
--- a/source/blender/blenkernel/intern/blendfile_link_append.c
+++ b/source/blender/blenkernel/intern/blendfile_link_append.c
@@ -61,7 +61,7 @@ static CLG_LogRef LOG = {"bke.blendfile_link_append"};
typedef struct BlendfileLinkAppendContextItem {
/** Name of the ID (without the heading two-chars IDcode). */
char *name;
- /** All libs (from BlendfileLinkAppendContext.libraries) to try to load this ID from. */
+ /** All libraries (from #BlendfileLinkAppendContext.libraries) to try to load this ID from. */
BLI_bitmap *libraries;
/** ID type. */
short idcode;
@@ -493,6 +493,7 @@ static void loose_data_instantiate_ensure_active_collection(
static void loose_data_instantiate_object_base_instance_init(Main *bmain,
Collection *collection,
Object *ob,
+ const Scene *scene,
ViewLayer *view_layer,
const View3D *v3d,
const int flag,
@@ -506,7 +507,7 @@ static void loose_data_instantiate_object_base_instance_init(Main *bmain,
}
BKE_collection_object_add(bmain, collection, ob);
-
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob);
if (v3d != NULL) {
@@ -686,8 +687,14 @@ static void loose_data_instantiate_collection_process(
/* TODO: why is it OK to make this active here but not in other situations?
* See other callers of #object_base_instance_init */
const bool set_active = set_selected;
- loose_data_instantiate_object_base_instance_init(
- bmain, active_collection, ob, view_layer, v3d, lapp_context->params->flag, set_active);
+ loose_data_instantiate_object_base_instance_init(bmain,
+ active_collection,
+ ob,
+ scene,
+ view_layer,
+ v3d,
+ lapp_context->params->flag,
+ set_active);
/* Assign the collection. */
ob->instance_collection = collection;
@@ -698,6 +705,7 @@ static void loose_data_instantiate_collection_process(
else {
/* Add collection as child of active collection. */
BKE_collection_child_add(bmain, active_collection, collection);
+ BKE_view_layer_synced_ensure(scene, view_layer);
if ((lapp_context->params->flag & FILE_AUTOSELECT) != 0) {
LISTBASE_FOREACH (CollectionObject *, coll_ob, &collection->gobject) {
@@ -717,6 +725,7 @@ static void loose_data_instantiate_object_process(LooseDataInstantiateContext *i
{
BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
Main *bmain = lapp_context->params->bmain;
+ const Scene *scene = lapp_context->params->context.scene;
ViewLayer *view_layer = lapp_context->params->context.view_layer;
const View3D *v3d = lapp_context->params->context.v3d;
@@ -762,6 +771,7 @@ static void loose_data_instantiate_object_process(LooseDataInstantiateContext *i
loose_data_instantiate_object_base_instance_init(bmain,
active_collection,
ob,
+ scene,
view_layer,
v3d,
lapp_context->params->flag,
@@ -809,6 +819,7 @@ static void loose_data_instantiate_obdata_process(LooseDataInstantiateContext *i
loose_data_instantiate_object_base_instance_init(bmain,
active_collection,
ob,
+ scene,
view_layer,
v3d,
lapp_context->params->flag,
@@ -1247,7 +1258,7 @@ void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *re
}
/* For each lib file, we try to link all items belonging to that lib,
- * and tag those successful to not try to load them again with the other libs. */
+ * and tag those successful to not try to load them again with the other libraries. */
for (item_idx = 0, itemlink = lapp_context->items.list; itemlink;
item_idx++, itemlink = itemlink->next) {
BlendfileLinkAppendContextItem *item = itemlink->link;
@@ -1261,7 +1272,7 @@ void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *re
mainl, &blo_handle, item->idcode, item->name, lapp_context->params);
if (new_id) {
- /* If the link is successful, clear item's libs 'todo' flags.
+ /* If the link is successful, clear item's libraries 'todo' flags.
* This avoids trying to link same item with other libraries to come. */
BLI_bitmap_set_all(item->libraries, false, lapp_context->num_libraries);
item->new_id = new_id;
@@ -1483,6 +1494,7 @@ void BKE_blendfile_library_relocate(BlendfileLinkAppendContext *lapp_context,
* code is wrong, we need to redo it here after adding them back to main. */
BKE_main_id_refcount_recompute(bmain, false);
+ BKE_layer_collection_resync_forbid();
/* Note that in reload case, we also want to replace indirect usages. */
const short remap_flags = ID_REMAP_SKIP_NEVER_NULL_USAGE |
(do_reload ? 0 : ID_REMAP_SKIP_INDIRECT_USAGE);
@@ -1512,6 +1524,8 @@ void BKE_blendfile_library_relocate(BlendfileLinkAppendContext *lapp_context,
id_us_plus_no_lib(&old_key->id);
}
}
+ BKE_layer_collection_resync_allow();
+ BKE_main_collection_sync_remap(bmain);
BKE_main_unlock(bmain);
@@ -1603,6 +1617,9 @@ void BKE_blendfile_library_relocate(BlendfileLinkAppendContext *lapp_context,
(id->tag & LIB_TAG_PRE_EXISTING) == 0) {
continue;
}
+ if ((id->override_library->reference->tag & LIB_TAG_MISSING) == 0) {
+ id->tag &= ~LIB_TAG_MISSING;
+ }
if ((id->override_library->reference->tag & LIB_TAG_PRE_EXISTING) == 0) {
BKE_lib_override_library_update(bmain, id);
}
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index 2e07b52c7bf..a0458f0f8d8 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -959,7 +959,7 @@ void boids_precalc_rules(ParticleSettings *part, float cfra)
if (flbr->ob && flbr->cfra != cfra) {
/* save object locations for velocity calculations */
copy_v3_v3(flbr->oloc, flbr->loc);
- copy_v3_v3(flbr->loc, flbr->ob->obmat[3]);
+ copy_v3_v3(flbr->loc, flbr->ob->object_to_world[3]);
flbr->cfra = cfra;
}
}
diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
index f639d03ae0f..6bf121675bc 100644
--- a/source/blender/blenkernel/intern/bpath.c
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -155,7 +155,7 @@ bool BKE_bpath_foreach_path_dirfile_fixed_process(BPathForeachPathData *bpath_da
char path_src[FILE_MAX];
char path_dst[FILE_MAX];
- BLI_join_dirfile(path_src, sizeof(path_src), path_dir, path_file);
+ BLI_path_join(path_src, sizeof(path_src), path_dir, path_file);
/* So that functions can access the old value. */
BLI_strncpy(path_dst, path_src, FILE_MAX);
@@ -279,7 +279,7 @@ static bool missing_files_find__recursive(const char *search_directory,
continue;
}
- BLI_join_dirfile(path, sizeof(path), search_directory, de->d_name);
+ BLI_path_join(path, sizeof(path), search_directory, de->d_name);
if (BLI_stat(path, &status) == -1) {
CLOG_WARN(&LOG, "Cannot get file status (`stat()`) of '%s'", path);
diff --git a/source/blender/blenkernel/intern/brush.cc b/source/blender/blenkernel/intern/brush.cc
index c206a04fecc..6f1435e90b8 100644
--- a/source/blender/blenkernel/intern/brush.cc
+++ b/source/blender/blenkernel/intern/brush.cc
@@ -56,7 +56,7 @@ static void brush_init_data(ID *id)
BKE_brush_curve_preset(brush, CURVE_PRESET_SMOOTH);
}
-static void brush_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
+static void brush_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int flag)
{
Brush *brush_dst = (Brush *)id_dst;
const Brush *brush_src = (const Brush *)id_src;
@@ -72,6 +72,8 @@ static void brush_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c
}
brush_dst->curve = BKE_curvemapping_copy(brush_src->curve);
+ brush_dst->automasking_cavity_curve = BKE_curvemapping_copy(brush_src->automasking_cavity_curve);
+
if (brush_src->gpencil_settings != nullptr) {
brush_dst->gpencil_settings = MEM_cnew(__func__, *(brush_src->gpencil_settings));
brush_dst->gpencil_settings->curve_sensitivity = BKE_curvemapping_copy(
@@ -109,6 +111,7 @@ static void brush_free_data(ID *id)
IMB_freeImBuf(brush->icon_imbuf);
}
BKE_curvemapping_free(brush->curve);
+ BKE_curvemapping_free(brush->automasking_cavity_curve);
if (brush->gpencil_settings != nullptr) {
BKE_curvemapping_free(brush->gpencil_settings->curve_sensitivity);
@@ -212,6 +215,10 @@ static void brush_blend_write(BlendWriter *writer, ID *id, const void *id_addres
BKE_curvemapping_blend_write(writer, brush->curve);
}
+ if (brush->automasking_cavity_curve) {
+ BKE_curvemapping_blend_write(writer, brush->automasking_cavity_curve);
+ }
+
if (brush->gpencil_settings) {
BLO_write_struct(writer, BrushGpencilSettings, brush->gpencil_settings);
@@ -267,6 +274,14 @@ static void brush_blend_read_data(BlendDataReader *reader, ID *id)
BKE_brush_curve_preset(brush, CURVE_PRESET_SHARP);
}
+ BLO_read_data_address(reader, &brush->automasking_cavity_curve);
+ if (brush->automasking_cavity_curve) {
+ BKE_curvemapping_blend_read(reader, brush->automasking_cavity_curve);
+ }
+ else {
+ brush->automasking_cavity_curve = BKE_sculpt_default_cavity_curve();
+ }
+
/* grease pencil */
BLO_read_data_address(reader, &brush->gpencil_settings);
if (brush->gpencil_settings != nullptr) {
@@ -982,7 +997,6 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
case GP_BRUSH_PRESET_FILL_AREA: {
brush->size = 5.0f;
- brush->gpencil_settings->fill_leak = 3;
brush->gpencil_settings->fill_threshold = 0.1f;
brush->gpencil_settings->fill_simplylvl = 1;
brush->gpencil_settings->fill_factor = 1.0f;
@@ -1960,19 +1974,37 @@ void BKE_brush_curve_preset(Brush *b, eCurveMappingPreset preset)
BKE_curvemapping_changed(cumap, false);
}
+const struct MTex *BKE_brush_mask_texture_get(const struct Brush *brush,
+ const eObjectMode object_mode)
+{
+ if (object_mode == OB_MODE_SCULPT) {
+ return &brush->mtex;
+ }
+ return &brush->mask_mtex;
+}
+
+const struct MTex *BKE_brush_color_texture_get(const struct Brush *brush,
+ const eObjectMode object_mode)
+{
+ if (object_mode == OB_MODE_SCULPT) {
+ return &brush->mask_mtex;
+ }
+ return &brush->mtex;
+}
+
float BKE_brush_sample_tex_3d(const Scene *scene,
const Brush *br,
+ const MTex *mtex,
const float point[3],
float rgba[4],
const int thread,
struct ImagePool *pool)
{
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
- const MTex *mtex = &br->mtex;
float intensity = 1.0;
bool hasrgb = false;
- if (!mtex->tex) {
+ if (mtex == nullptr || mtex->tex == nullptr) {
intensity = 1;
}
else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
@@ -2359,7 +2391,7 @@ void BKE_brush_scale_unprojected_radius(float *unprojected_radius,
float scale = new_brush_size;
/* avoid division by zero */
if (old_brush_size != 0) {
- scale /= (float)old_brush_size;
+ scale /= float(old_brush_size);
}
(*unprojected_radius) *= scale;
}
@@ -2373,7 +2405,7 @@ void BKE_brush_scale_size(int *r_brush_size,
if (old_unprojected_radius != 0) {
scale /= new_unprojected_radius;
}
- (*r_brush_size) = (int)((float)(*r_brush_size) * scale);
+ (*r_brush_size) = int(float(*r_brush_size) * scale);
}
void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2], float jitterpos[2])
diff --git a/source/blender/blenkernel/intern/bvhutils.cc b/source/blender/blenkernel/intern/bvhutils.cc
index 9bea8a0d6d3..afc3e525143 100644
--- a/source/blender/blenkernel/intern/bvhutils.cc
+++ b/source/blender/blenkernel/intern/bvhutils.cc
@@ -51,13 +51,13 @@ struct BVHCache {
* When the `r_locked` is filled and the tree could not be found the caches mutex will be
* locked. This mutex can be unlocked by calling `bvhcache_unlock`.
*
- * When `r_locked` is used the `mesh_eval_mutex` must contain the `Mesh_Runtime.eval_mutex`.
+ * When `r_locked` is used the `mesh_eval_mutex` must contain the `MeshRuntime.eval_mutex`.
*/
static bool bvhcache_find(BVHCache **bvh_cache_p,
BVHCacheType type,
BVHTree **r_tree,
bool *r_locked,
- ThreadMutex *mesh_eval_mutex)
+ std::mutex *mesh_eval_mutex)
{
bool do_lock = r_locked;
if (r_locked) {
@@ -69,11 +69,10 @@ static bool bvhcache_find(BVHCache **bvh_cache_p,
return false;
}
/* Lazy initialization of the bvh_cache using the `mesh_eval_mutex`. */
- BLI_mutex_lock(mesh_eval_mutex);
+ std::lock_guard lock{*mesh_eval_mutex};
if (*bvh_cache_p == nullptr) {
*bvh_cache_p = bvhcache_init();
}
- BLI_mutex_unlock(mesh_eval_mutex);
}
BVHCache *bvh_cache = *bvh_cache_p;
@@ -178,7 +177,7 @@ static void bvhtree_balance(BVHTree *tree, const bool isolate)
/* Math stuff for ray casting on mesh faces and for nearest surface */
float bvhtree_ray_tri_intersection(const BVHTreeRay *ray,
- const float UNUSED(m_dist),
+ const float /*m_dist*/,
const float v0[3],
const float v1[3],
const float v2[3])
@@ -1136,7 +1135,7 @@ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data,
static BLI_bitmap *loose_verts_map_get(const MEdge *medge,
int edges_num,
- const MVert *UNUSED(mvert),
+ const MVert * /*mvert*/,
int verts_num,
int *r_loose_vert_num)
{
@@ -1222,8 +1221,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
const BVHCacheType bvh_cache_type,
const int tree_type)
{
- BVHCache **bvh_cache_p = (BVHCache **)&mesh->runtime.bvh_cache;
- ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime.eval_mutex;
+ BVHCache **bvh_cache_p = (BVHCache **)&mesh->runtime->bvh_cache;
const MLoopTri *looptri = nullptr;
int looptri_len = 0;
@@ -1248,7 +1246,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
bool lock_started = false;
data->cached = bvhcache_find(
- bvh_cache_p, bvh_cache_type, &data->tree, &lock_started, mesh_eval_mutex);
+ bvh_cache_p, bvh_cache_type, &data->tree, &lock_started, &mesh->runtime->eval_mutex);
if (data->cached) {
BLI_assert(lock_started == false);
@@ -1352,7 +1350,7 @@ BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
const int tree_type,
const BVHCacheType bvh_cache_type,
BVHCache **bvh_cache_p,
- ThreadMutex *mesh_eval_mutex)
+ std::mutex *mesh_eval_mutex)
{
bool lock_started = false;
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 158e0bb776c..7c1193d80ab 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -72,7 +72,7 @@ static void camera_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src,
Camera *cam_dst = (Camera *)id_dst;
const Camera *cam_src = (const Camera *)id_src;
- /* We never handle usercount here for own data. */
+ /* We never handle user-count here for own data. */
const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
BLI_listbase_clear(&cam_dst->bg_images);
@@ -221,16 +221,16 @@ float BKE_camera_object_dof_distance(const Object *ob)
}
if (cam->dof.focus_object) {
float view_dir[3], dof_dir[3];
- normalize_v3_v3(view_dir, ob->obmat[2]);
+ normalize_v3_v3(view_dir, ob->object_to_world[2]);
bPoseChannel *pchan = BKE_pose_channel_find_name(cam->dof.focus_object->pose,
cam->dof.focus_subtarget);
if (pchan) {
float posemat[4][4];
- mul_m4_m4m4(posemat, cam->dof.focus_object->obmat, pchan->pose_mat);
- sub_v3_v3v3(dof_dir, ob->obmat[3], posemat[3]);
+ mul_m4_m4m4(posemat, cam->dof.focus_object->object_to_world, pchan->pose_mat);
+ sub_v3_v3v3(dof_dir, ob->object_to_world[3], posemat[3]);
}
else {
- sub_v3_v3v3(dof_dir, ob->obmat[3], cam->dof.focus_object->obmat[3]);
+ sub_v3_v3v3(dof_dir, ob->object_to_world[3], cam->dof.focus_object->object_to_world[3]);
}
return fabsf(dot_v3v3(view_dir, dof_dir));
}
@@ -350,7 +350,7 @@ void BKE_camera_params_from_view3d(CameraParams *params,
/* orthographic view */
float sensor_size = BKE_camera_sensor_size(
params->sensor_fit, params->sensor_x, params->sensor_y);
- /* Halve, otherwise too extreme low zbuffer quality. */
+ /* Halve, otherwise too extreme low Z-buffer quality. */
params->clip_end *= 0.5f;
params->clip_start = -params->clip_end;
@@ -401,7 +401,7 @@ void BKE_camera_params_compute_viewplane(
pixsize *= params->zoom;
/* compute view plane:
- * fully centered, zbuffer fills in jittered between -.5 and +.5 */
+ * Fully centered, Z-buffer fills in jittered between `-.5` and `+.5`. */
viewplane.xmin = -0.5f * (float)winx;
viewplane.ymin = -0.5f * params->ycor * (float)winy;
viewplane.xmax = 0.5f * (float)winx;
@@ -579,7 +579,7 @@ typedef struct CameraViewFrameData {
float dist_vals[CAMERA_VIEWFRAME_NUM_PLANES]; /* distance (signed) */
float camera_no[3];
float z_range[2];
- unsigned int tot;
+ uint tot;
bool do_zrange;
@@ -628,7 +628,7 @@ static void camera_frame_fit_data_init(const Scene *scene,
BKE_camera_params_compute_matrix(params);
/* initialize callback data */
- copy_m3_m4(data->camera_rotmat, (float(*)[4])ob->obmat);
+ copy_m3_m4(data->camera_rotmat, (float(*)[4])ob->object_to_world);
normalize_m3(data->camera_rotmat);
/* To transform a plane which is in its homogeneous representation (4d vector),
* we need the inverse of the transpose of the transform matrix... */
@@ -713,10 +713,8 @@ static bool camera_frame_fit_calc_from_data(CameraParams *params,
plane_from_point_normal_v3(plane_tx[i], co, data->plane_tx[i]);
}
- if ((!isect_plane_plane_v3(
- plane_tx[Y_MIN], plane_tx[Y_MAX], plane_isect_1, plane_isect_1_no)) ||
- (!isect_plane_plane_v3(
- plane_tx[Z_MIN], plane_tx[Z_MAX], plane_isect_2, plane_isect_2_no))) {
+ if (!isect_plane_plane_v3(plane_tx[Y_MIN], plane_tx[Y_MAX], plane_isect_1, plane_isect_1_no) ||
+ !isect_plane_plane_v3(plane_tx[Z_MIN], plane_tx[Z_MAX], plane_isect_2, plane_isect_2_no)) {
return false;
}
@@ -830,7 +828,7 @@ bool BKE_camera_view_frame_fit_to_coords(const Depsgraph *depsgraph,
static void camera_model_matrix(const Object *camera, float r_modelmat[4][4])
{
- copy_m4_m4(r_modelmat, camera->obmat);
+ copy_m4_m4(r_modelmat, camera->object_to_world);
}
static void camera_stereo3d_model_matrix(const Object *camera,
@@ -856,7 +854,7 @@ static void camera_stereo3d_model_matrix(const Object *camera,
}
float size[3];
- mat4_to_size(size, camera->obmat);
+ mat4_to_size(size, camera->object_to_world);
size_to_mat4(sizemat, size);
if (pivot == CAM_S3D_PIVOT_CENTER) {
@@ -896,7 +894,7 @@ static void camera_stereo3d_model_matrix(const Object *camera,
toeinmat[3][0] = interocular_distance * fac_signed;
/* transform */
- normalize_m4_m4(r_modelmat, camera->obmat);
+ normalize_m4_m4(r_modelmat, camera->object_to_world);
mul_m4_m4m4(r_modelmat, r_modelmat, toeinmat);
/* scale back to the original size */
@@ -904,7 +902,7 @@ static void camera_stereo3d_model_matrix(const Object *camera,
}
else { /* CAM_S3D_PIVOT_LEFT, CAM_S3D_PIVOT_RIGHT */
/* rotate perpendicular to the interocular line */
- normalize_m4_m4(r_modelmat, camera->obmat);
+ normalize_m4_m4(r_modelmat, camera->object_to_world);
mul_m4_m4m4(r_modelmat, r_modelmat, rotmat);
/* translate along the interocular line */
@@ -920,7 +918,7 @@ static void camera_stereo3d_model_matrix(const Object *camera,
}
}
else {
- normalize_m4_m4(r_modelmat, camera->obmat);
+ normalize_m4_m4(r_modelmat, camera->object_to_world);
/* translate - no rotation in CAM_S3D_OFFAXIS, CAM_S3D_PARALLEL */
translate_m4(r_modelmat, -interocular_distance * fac_signed, 0.0f, 0.0f);
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 0261b2d7674..41993764c0c 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -115,8 +115,8 @@ static void cdDM_getVertNo(DerivedMesh *dm, int index, float r_no[3])
static void cdDM_recalc_looptri(DerivedMesh *dm)
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
- const unsigned int totpoly = dm->numPolyData;
- const unsigned int totloop = dm->numLoopData;
+ const uint totpoly = dm->numPolyData;
+ const uint totloop = dm->numLoopData;
DM_ensure_looptri_data(dm);
BLI_assert(totpoly == 0 || cddm->dm.looptris.array_wip != NULL);
@@ -198,7 +198,7 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh,
DM_TYPE_CDDM,
mesh->totvert,
mesh->totedge,
- 0 /* mesh->totface */,
+ 0 /* `mesh->totface` */,
mesh->totloop,
mesh->totpoly);
@@ -206,7 +206,6 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh,
* but only if the original mesh had its deformed_only flag correctly set
* (which isn't generally the case). */
dm->deformedOnly = 1;
- dm->cd_flag = mesh->cd_flag;
CustomData_merge(&mesh->vdata, &dm->vertData, cddata_masks.vmask, alloctype, mesh->totvert);
CustomData_merge(&mesh->edata, &dm->edgeData, cddata_masks.emask, alloctype, mesh->totedge);
@@ -214,7 +213,7 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh,
&dm->faceData,
cddata_masks.fmask | CD_MASK_ORIGINDEX,
alloctype,
- 0 /* mesh->totface */);
+ 0 /* `mesh->totface` */);
CustomData_merge(&mesh->ldata, &dm->loopData, cddata_masks.lmask, alloctype, mesh->totloop);
CustomData_merge(&mesh->pdata, &dm->polyData, cddata_masks.pmask, alloctype, mesh->totpoly);
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index f3bda8b1c99..88ba50fe901 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -57,7 +57,7 @@ typedef struct BendSpringRef {
/******************************************************************************
*
- * External interface called by modifier.c clothModifier functions.
+ * External interface called by modifier.cc clothModifier functions.
*
******************************************************************************/
@@ -117,7 +117,7 @@ static BVHTree *bvhtree_build_from_cloth(ClothModifierData *clmd, float epsilon)
void bvhtree_update_from_cloth(ClothModifierData *clmd, bool moving, bool self)
{
- unsigned int i = 0;
+ uint i = 0;
Cloth *cloth = clmd->clothObject;
BVHTree *bvhtree;
ClothVertex *verts = cloth->verts;
@@ -252,7 +252,7 @@ static int do_step_cloth(
Cloth *cloth;
ListBase *effectors = NULL;
MVert *mvert;
- unsigned int i = 0;
+ uint i = 0;
int ret = 0;
bool vert_mass_changed = false;
@@ -269,7 +269,7 @@ static int do_step_cloth(
/* Get the current position. */
copy_v3_v3(verts->xconst, mvert[i].co);
- mul_m4_v3(ob->obmat, verts->xconst);
+ mul_m4_v3(ob->object_to_world, verts->xconst);
if (vert_mass_changed) {
verts->mass = clmd->sim_parms->mass;
@@ -576,16 +576,16 @@ void cloth_free_modifier_extern(ClothModifierData *clmd)
*/
static void cloth_to_object(Object *ob, ClothModifierData *clmd, float (*vertexCos)[3])
{
- unsigned int i = 0;
+ uint i = 0;
Cloth *cloth = clmd->clothObject;
if (clmd->clothObject) {
/* Inverse matrix is not up to date. */
- invert_m4_m4(ob->imat, ob->obmat);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
for (i = 0; i < cloth->mvert_num; i++) {
copy_v3_v3(vertexCos[i], cloth->verts[i].x);
- mul_m4_v3(ob->imat, vertexCos[i]); /* cloth is in global coords */
+ mul_m4_v3(ob->world_to_object, vertexCos[i]); /* cloth is in global coords */
}
}
}
@@ -763,11 +763,11 @@ static bool cloth_from_object(
if (first) {
copy_v3_v3(verts->x, mvert[i].co);
- mul_m4_v3(ob->obmat, verts->x);
+ mul_m4_v3(ob->object_to_world, verts->x);
if (shapekey_rest) {
copy_v3_v3(verts->xrest, shapekey_rest[i]);
- mul_m4_v3(ob->obmat, verts->xrest);
+ mul_m4_v3(ob->object_to_world, verts->xrest);
}
else {
copy_v3_v3(verts->xrest, verts->x);
@@ -825,8 +825,8 @@ static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mes
{
const MLoop *mloop = BKE_mesh_loops(mesh);
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh);
- const unsigned int mvert_num = mesh->totvert;
- const unsigned int looptri_num = mesh->runtime.looptris.len;
+ const uint mvert_num = mesh->totvert;
+ const uint looptri_num = BKE_mesh_runtime_looptri_len(mesh);
/* Allocate our vertices. */
clmd->clothObject->mvert_num = mvert_num;
@@ -884,7 +884,7 @@ BLI_INLINE void spring_verts_ordered_set(ClothSpring *spring, int v0, int v1)
}
}
-static void cloth_free_edgelist(LinkNodePair *edgelist, unsigned int mvert_num)
+static void cloth_free_edgelist(LinkNodePair *edgelist, uint mvert_num)
{
if (edgelist) {
for (uint i = 0; i < mvert_num; i++) {
@@ -1130,7 +1130,7 @@ static void cloth_update_springs(ClothModifierData *clmd)
* because implicit solver would need reset! */
/* Activate / Deactivate existing springs */
- if ((!(cloth->verts[spring->ij].flags & CLOTH_VERT_FLAG_PINNED)) &&
+ if (!(cloth->verts[spring->ij].flags & CLOTH_VERT_FLAG_PINNED) &&
(cloth->verts[spring->ij].goal > ALMOST_ZERO)) {
spring->flags &= ~CLOTH_SPRING_FLAG_DEACTIVATE;
}
@@ -1148,14 +1148,14 @@ static void cloth_update_springs(ClothModifierData *clmd)
/* Update rest verts, for dynamically deformable cloth */
static void cloth_update_verts(Object *ob, ClothModifierData *clmd, Mesh *mesh)
{
- unsigned int i = 0;
+ uint i = 0;
const MVert *mvert = BKE_mesh_verts(mesh);
ClothVertex *verts = clmd->clothObject->verts;
/* vertex count is already ensured to match */
for (i = 0; i < mesh->totvert; i++, verts++) {
copy_v3_v3(verts->xrest, mvert[i].co);
- mul_m4_v3(ob->obmat, verts->xrest);
+ mul_m4_v3(ob->object_to_world, verts->xrest);
}
}
@@ -1167,7 +1167,7 @@ static Mesh *cloth_make_rest_mesh(ClothModifierData *clmd, Mesh *mesh)
MVert *mvert = BKE_mesh_verts_for_write(mesh);
/* vertex count is already ensured to match */
- for (unsigned i = 0; i < mesh->totvert; i++, verts++) {
+ for (uint i = 0; i < mesh->totvert; i++, verts++) {
copy_v3_v3(mvert[i].co, verts->xrest);
}
BKE_mesh_tag_coords_changed(new_mesh);
@@ -1180,9 +1180,9 @@ static void cloth_update_spring_lengths(ClothModifierData *clmd, Mesh *mesh)
{
Cloth *cloth = clmd->clothObject;
LinkNode *search = cloth->springs;
- unsigned int struct_springs = 0;
- unsigned int i = 0;
- unsigned int mvert_num = (unsigned int)mesh->totvert;
+ uint struct_springs = 0;
+ uint i = 0;
+ uint mvert_num = (uint)mesh->totvert;
float shrink_factor;
clmd->sim_parms->avg_spring_len = 0.0f;
@@ -1373,12 +1373,12 @@ BLI_INLINE bool cloth_bend_set_poly_vert_array(int **poly, int len, const MLoop
}
static bool find_internal_spring_target_vertex(BVHTreeFromMesh *treedata,
- unsigned int v_idx,
+ uint v_idx,
RNG *rng,
float max_length,
float max_diversion,
bool check_normal,
- unsigned int *r_tar_v_idx)
+ uint *r_tar_v_idx)
{
float co[3], no[3], new_co[3];
float radius;
@@ -1415,7 +1415,7 @@ static bool find_internal_spring_target_vertex(BVHTreeFromMesh *treedata,
BLI_bvhtree_ray_cast(
treedata->tree, new_co, no, radius, &rayhit, treedata->raycast_callback, treedata);
- unsigned int vert_idx = -1;
+ uint vert_idx = -1;
const MLoop *mloop = treedata->loop;
const MLoopTri *lt = NULL;
@@ -1429,7 +1429,7 @@ static bool find_internal_spring_target_vertex(BVHTreeFromMesh *treedata,
lt = &treedata->looptri[rayhit.index];
for (int i = 0; i < 3; i++) {
- unsigned int tmp_vert_idx = mloop[lt->tri[i]].v;
+ uint tmp_vert_idx = mloop[lt->tri[i]].v;
if (tmp_vert_idx == v_idx) {
/* We managed to hit ourselves. */
return false;
@@ -1453,10 +1453,10 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
{
Cloth *cloth = clmd->clothObject;
ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL;
- unsigned int struct_springs = 0, shear_springs = 0, bend_springs = 0, struct_springs_real = 0;
- unsigned int mvert_num = (unsigned int)mesh->totvert;
- unsigned int numedges = (unsigned int)mesh->totedge;
- unsigned int numpolys = (unsigned int)mesh->totpoly;
+ uint struct_springs = 0, shear_springs = 0, bend_springs = 0, struct_springs_real = 0;
+ uint mvert_num = (uint)mesh->totvert;
+ uint numedges = (uint)mesh->totedge;
+ uint numpolys = (uint)mesh->totpoly;
float shrink_factor;
const MEdge *medge = BKE_mesh_edges(mesh);
const MPoly *mpoly = BKE_mesh_polys(mesh);
@@ -1499,7 +1499,7 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
if (use_internal_springs && numpolys > 0) {
BVHTreeFromMesh treedata = {NULL};
- unsigned int tar_v_idx;
+ uint tar_v_idx;
Mesh *tmp_mesh = NULL;
RNG *rng;
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 41ec120519b..751b5185e39 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -796,10 +796,10 @@ static void collection_object_cache_fill(ListBase *lb,
/* Only collection flags are checked here currently, object restrict flag is checked
* in FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN since it can be animated
* without updating the cache. */
- if (((child_restrict & COLLECTION_HIDE_VIEWPORT) == 0)) {
+ if ((child_restrict & COLLECTION_HIDE_VIEWPORT) == 0) {
base->flag |= BASE_ENABLED_VIEWPORT;
}
- if (((child_restrict & COLLECTION_HIDE_RENDER) == 0)) {
+ if ((child_restrict & COLLECTION_HIDE_RENDER) == 0) {
base->flag |= BASE_ENABLED_RENDER;
}
}
@@ -859,13 +859,15 @@ void BKE_collection_object_cache_free(Collection *collection)
collection_object_cache_free(collection);
}
-Base *BKE_collection_or_layer_objects(const ViewLayer *view_layer, Collection *collection)
+Base *BKE_collection_or_layer_objects(const Scene *scene,
+ ViewLayer *view_layer,
+ Collection *collection)
{
if (collection) {
return BKE_collection_object_cache_get(collection).first;
}
-
- return view_layer->object_bases.first;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ return BKE_view_layer_object_bases_get(view_layer)->first;
}
/** \} */
@@ -944,7 +946,7 @@ bool BKE_collection_has_object(Collection *collection, const Object *ob)
return false;
}
- return (BLI_findptr(&collection->gobject, ob, offsetof(CollectionObject, ob)));
+ return BLI_findptr(&collection->gobject, ob, offsetof(CollectionObject, ob));
}
bool BKE_collection_has_object_recursive(Collection *collection, Object *ob)
@@ -954,7 +956,7 @@ bool BKE_collection_has_object_recursive(Collection *collection, Object *ob)
}
const ListBase objects = BKE_collection_object_cache_get(collection);
- return (BLI_findptr(&objects, ob, offsetof(Base, object)));
+ return BLI_findptr(&objects, ob, offsetof(Base, object));
}
bool BKE_collection_has_object_recursive_instanced(Collection *collection, Object *ob)
@@ -964,7 +966,7 @@ bool BKE_collection_has_object_recursive_instanced(Collection *collection, Objec
}
const ListBase objects = BKE_collection_object_cache_instanced_get(collection);
- return (BLI_findptr(&objects, ob, offsetof(Base, object)));
+ return BLI_findptr(&objects, ob, offsetof(Base, object));
}
static Collection *collection_next_find(Main *bmain, Scene *scene, Collection *collection)
@@ -1749,7 +1751,10 @@ Collection *BKE_collection_from_index(Scene *scene, const int index)
return collection_from_index_recursive(master_collection, index, &index_current);
}
-static bool collection_objects_select(ViewLayer *view_layer, Collection *collection, bool deselect)
+static bool collection_objects_select(const Scene *scene,
+ ViewLayer *view_layer,
+ Collection *collection,
+ bool deselect)
{
bool changed = false;
@@ -1757,6 +1762,7 @@ static bool collection_objects_select(ViewLayer *view_layer, Collection *collect
return false;
}
+ BKE_view_layer_synced_ensure(scene, view_layer);
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
@@ -1777,7 +1783,7 @@ static bool collection_objects_select(ViewLayer *view_layer, Collection *collect
}
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
- if (collection_objects_select(view_layer, collection, deselect)) {
+ if (collection_objects_select(scene, view_layer, collection, deselect)) {
changed = true;
}
}
@@ -1785,16 +1791,19 @@ static bool collection_objects_select(ViewLayer *view_layer, Collection *collect
return changed;
}
-bool BKE_collection_objects_select(ViewLayer *view_layer, Collection *collection, bool deselect)
+bool BKE_collection_objects_select(const Scene *scene,
+ ViewLayer *view_layer,
+ Collection *collection,
+ bool deselect)
{
LayerCollection *layer_collection = BKE_layer_collection_first_from_scene_collection(view_layer,
collection);
if (layer_collection != NULL) {
- return BKE_layer_collection_objects_select(view_layer, layer_collection, deselect);
+ return BKE_layer_collection_objects_select(scene, view_layer, layer_collection, deselect);
}
- return collection_objects_select(view_layer, collection, deselect);
+ return collection_objects_select(scene, view_layer, collection, deselect);
}
/** \} */
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index ae99f0d17df..2acdc6543b5 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -67,7 +67,7 @@ void collision_move_object(CollisionModifierData *collmd,
const float prevstep,
const bool moving_bvh)
{
- unsigned int i = 0;
+ uint i = 0;
/* the collider doesn't move this frame */
if (collmd->is_static) {
@@ -1216,10 +1216,7 @@ static void hair_collision(void *__restrict userdata,
}
}
-static void add_collision_object(ListBase *relations,
- Object *ob,
- int level,
- unsigned int modifier_type)
+static void add_collision_object(ListBase *relations, Object *ob, int level, uint modifier_type)
{
/* only get objects with collision modifier */
ModifierData *cmd = BKE_modifiers_findby_type(ob, modifier_type);
@@ -1246,10 +1243,11 @@ static void add_collision_object(ListBase *relations,
ListBase *BKE_collision_relations_create(Depsgraph *depsgraph,
Collection *collection,
- unsigned int modifier_type)
+ uint modifier_type)
{
+ const Scene *scene = DEG_get_input_scene(depsgraph);
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
- Base *base = BKE_collection_or_layer_objects(view_layer, collection);
+ Base *base = BKE_collection_or_layer_objects(scene, view_layer, collection);
const bool for_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
const int base_flag = (for_render) ? BASE_ENABLED_RENDER : BASE_ENABLED_VIEWPORT;
@@ -1275,8 +1273,8 @@ void BKE_collision_relations_free(ListBase *relations)
Object **BKE_collision_objects_create(Depsgraph *depsgraph,
Object *self,
Collection *collection,
- unsigned int *numcollobj,
- unsigned int modifier_type)
+ uint *numcollobj,
+ uint modifier_type)
{
ListBase *relations = DEG_get_collision_relations(depsgraph, collection, modifier_type);
@@ -1548,7 +1546,7 @@ int cloth_bvh_collision(
ClothVertex *verts = NULL;
int ret = 0, ret2 = 0;
Object **collobjs = NULL;
- unsigned int numcollobj = 0;
+ uint numcollobj = 0;
uint *coll_counts_obj = NULL;
BVHTreeOverlap **overlap_obj = NULL;
uint coll_count_self = 0;
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index e4c46703f8a..837eb892056 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -1098,8 +1098,8 @@ void BKE_curvemapping_evaluate_premulRGBF(const CurveMapping *cumap,
}
void BKE_curvemapping_evaluate_premulRGB(const CurveMapping *cumap,
- unsigned char vecout_byte[3],
- const unsigned char vecin_byte[3])
+ uchar vecout_byte[3],
+ const uchar vecin_byte[3])
{
float vecin[3], vecout[3];
@@ -1368,7 +1368,7 @@ void BKE_histogram_update_sample_line(Histogram *hist,
{
int i, x, y;
const float *fp;
- unsigned char *cp;
+ uchar *cp;
int x1 = roundf(hist->co[0][0] * ibuf->x);
int x2 = roundf(hist->co[1][0] * ibuf->x);
@@ -1432,7 +1432,7 @@ void BKE_histogram_update_sample_line(Histogram *hist,
hist->data_a[i] = rgba[3];
}
else if (ibuf->rect) {
- cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x);
+ cp = (uchar *)(ibuf->rect + y * ibuf->x + x);
hist->data_luma[i] = (float)IMB_colormanagement_get_luminance_byte(cp) / 255.0f;
hist->data_r[i] = (float)cp[0] / 255.0f;
hist->data_g[i] = (float)cp[1] / 255.0f;
@@ -1452,16 +1452,16 @@ typedef struct ScopesUpdateData {
Scopes *scopes;
const ImBuf *ibuf;
struct ColormanageProcessor *cm_processor;
- const unsigned char *display_buffer;
+ const uchar *display_buffer;
const int ycc_mode;
} ScopesUpdateData;
typedef struct ScopesUpdateDataChunk {
- unsigned int bin_lum[256];
- unsigned int bin_r[256];
- unsigned int bin_g[256];
- unsigned int bin_b[256];
- unsigned int bin_a[256];
+ uint bin_lum[256];
+ uint bin_r[256];
+ uint bin_g[256];
+ uint bin_b[256];
+ uint bin_a[256];
float min[3], max[3];
} ScopesUpdateDataChunk;
@@ -1474,20 +1474,20 @@ static void scopes_update_cb(void *__restrict userdata,
Scopes *scopes = data->scopes;
const ImBuf *ibuf = data->ibuf;
struct ColormanageProcessor *cm_processor = data->cm_processor;
- const unsigned char *display_buffer = data->display_buffer;
+ const uchar *display_buffer = data->display_buffer;
const int ycc_mode = data->ycc_mode;
ScopesUpdateDataChunk *data_chunk = tls->userdata_chunk;
- unsigned int *bin_lum = data_chunk->bin_lum;
- unsigned int *bin_r = data_chunk->bin_r;
- unsigned int *bin_g = data_chunk->bin_g;
- unsigned int *bin_b = data_chunk->bin_b;
- unsigned int *bin_a = data_chunk->bin_a;
+ uint *bin_lum = data_chunk->bin_lum;
+ uint *bin_r = data_chunk->bin_r;
+ uint *bin_g = data_chunk->bin_g;
+ uint *bin_b = data_chunk->bin_b;
+ uint *bin_a = data_chunk->bin_a;
float *min = data_chunk->min;
float *max = data_chunk->max;
const float *rf = NULL;
- const unsigned char *rc = NULL;
+ const uchar *rc = NULL;
const int rows_per_sample_line = ibuf->y / scopes->sample_lines;
const int savedlines = y / rows_per_sample_line;
const bool do_sample_line = (savedlines < scopes->sample_lines) &&
@@ -1571,16 +1571,16 @@ static void scopes_update_reduce(const void *__restrict UNUSED(userdata),
ScopesUpdateDataChunk *join_chunk = chunk_join;
const ScopesUpdateDataChunk *data_chunk = chunk;
- unsigned int *bin_lum = join_chunk->bin_lum;
- unsigned int *bin_r = join_chunk->bin_r;
- unsigned int *bin_g = join_chunk->bin_g;
- unsigned int *bin_b = join_chunk->bin_b;
- unsigned int *bin_a = join_chunk->bin_a;
- const unsigned int *bin_lum_c = data_chunk->bin_lum;
- const unsigned int *bin_r_c = data_chunk->bin_r;
- const unsigned int *bin_g_c = data_chunk->bin_g;
- const unsigned int *bin_b_c = data_chunk->bin_b;
- const unsigned int *bin_a_c = data_chunk->bin_a;
+ uint *bin_lum = join_chunk->bin_lum;
+ uint *bin_r = join_chunk->bin_r;
+ uint *bin_g = join_chunk->bin_g;
+ uint *bin_b = join_chunk->bin_b;
+ uint *bin_a = join_chunk->bin_a;
+ const uint *bin_lum_c = data_chunk->bin_lum;
+ const uint *bin_r_c = data_chunk->bin_r;
+ const uint *bin_g_c = data_chunk->bin_g;
+ const uint *bin_b_c = data_chunk->bin_b;
+ const uint *bin_a_c = data_chunk->bin_a;
const float *min = data_chunk->min;
const float *max = data_chunk->max;
@@ -1609,9 +1609,9 @@ void BKE_scopes_update(Scopes *scopes,
const ColorManagedDisplaySettings *display_settings)
{
int a;
- unsigned int nl, na, nr, ng, nb;
+ uint nl, na, nr, ng, nb;
double divl, diva, divr, divg, divb;
- const unsigned char *display_buffer = NULL;
+ const uchar *display_buffer = NULL;
int ycc_mode = -1;
void *cache_handle = NULL;
struct ColormanageProcessor *cm_processor = NULL;
@@ -1629,7 +1629,7 @@ void BKE_scopes_update(Scopes *scopes,
}
/* hmmmm */
- if (!(ELEM(ibuf->channels, 3, 4))) {
+ if (!ELEM(ibuf->channels, 3, 4)) {
return;
}
@@ -1696,7 +1696,7 @@ void BKE_scopes_update(Scopes *scopes,
cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
}
else {
- display_buffer = (const unsigned char *)IMB_display_buffer_acquire(
+ display_buffer = (const uchar *)IMB_display_buffer_acquire(
ibuf, view_settings, display_settings, &cache_handle);
}
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index bcc3db48947..bcc4ad0cb55 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -149,7 +149,7 @@ bConstraintOb *BKE_constraints_make_evalob(
/* Quats/Axis-Angle, so Eulers should just use default order */
cob->rotOrder = EULER_ORDER_DEFAULT;
}
- copy_m4_m4(cob->matrix, ob->obmat);
+ copy_m4_m4(cob->matrix, ob->object_to_world);
}
else {
unit_m4(cob->matrix);
@@ -175,7 +175,7 @@ bConstraintOb *BKE_constraints_make_evalob(
}
/* matrix in world-space */
- mul_m4_m4m4(cob->matrix, ob->obmat, cob->pchan->pose_mat);
+ mul_m4_m4m4(cob->matrix, ob->object_to_world, cob->pchan->pose_mat);
}
else {
unit_m4(cob->matrix);
@@ -216,7 +216,7 @@ void BKE_constraints_clear_evalob(bConstraintOb *cob)
/* cob->ob might not exist! */
if (cob->ob) {
/* copy new ob-matrix back to owner */
- copy_m4_m4(cob->ob->obmat, cob->matrix);
+ copy_m4_m4(cob->ob->object_to_world, cob->matrix);
/* copy inverse of delta back to owner */
invert_m4_m4(cob->ob->constinv, delta);
@@ -227,7 +227,7 @@ void BKE_constraints_clear_evalob(bConstraintOb *cob)
/* cob->ob or cob->pchan might not exist */
if (cob->ob && cob->pchan) {
/* copy new pose-matrix back to owner */
- mul_m4_m4m4(cob->pchan->pose_mat, cob->ob->imat, cob->matrix);
+ mul_m4_m4m4(cob->pchan->pose_mat, cob->ob->world_to_object, cob->matrix);
/* copy inverse of delta back to owner */
invert_m4_m4(cob->pchan->constinv, delta);
@@ -276,7 +276,7 @@ void BKE_constraint_mat_convertspace(Object *ob,
}
else {
/* World to pose. */
- invert_m4_m4(imat, ob->obmat);
+ invert_m4_m4(imat, ob->object_to_world);
mul_m4_m4m4(mat, imat, mat);
/* Use pose-space as stepping stone for other spaces. */
@@ -319,7 +319,7 @@ void BKE_constraint_mat_convertspace(Object *ob,
}
else {
/* Pose to world. */
- mul_m4_m4m4(mat, ob->obmat, mat);
+ mul_m4_m4m4(mat, ob->object_to_world, mat);
/* Use world-space as stepping stone for other spaces. */
if (to != CONSTRAINT_SPACE_WORLD) {
/* Call self with slightly different values. */
@@ -429,7 +429,7 @@ void BKE_constraint_mat_convertspace(Object *ob,
/* Check if object has a parent. */
if (ob->parent) {
/* 'subtract' parent's effects from owner. */
- mul_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv);
+ mul_m4_m4m4(diff_mat, ob->parent->object_to_world, ob->parentinv);
invert_m4_m4_safe(imat, diff_mat);
mul_m4_m4m4(mat, imat, mat);
}
@@ -465,7 +465,7 @@ void BKE_constraint_mat_convertspace(Object *ob,
/* check that object has a parent - otherwise this won't work */
if (ob->parent) {
/* 'add' parent's effect back to owner */
- mul_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv);
+ mul_m4_m4m4(diff_mat, ob->parent->object_to_world, ob->parentinv);
mul_m4_m4m4(mat, diff_mat, mat);
}
else {
@@ -518,7 +518,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
const int defgroup = BKE_object_defgroup_name_index(ob, substring);
/* initialize target matrix using target matrix */
- copy_m4_m4(mat, ob->obmat);
+ copy_m4_m4(mat, ob->object_to_world);
/* get index of vertex group */
if (defgroup == -1) {
@@ -584,7 +584,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
* calc_gizmo_stats, V3D_ORIENT_NORMAL case */
/* We need the transpose of the inverse for a normal. */
- copy_m3_m4(imat, ob->obmat);
+ copy_m3_m4(imat, ob->object_to_world);
invert_m3_m3(tmat, imat);
transpose_m3(tmat);
@@ -605,7 +605,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
normalize_m4(mat);
/* apply the average coordinate as the new location */
- mul_v3_m4v3(mat[3], ob->obmat, vec);
+ mul_v3_m4v3(mat[3], ob->object_to_world, vec);
}
/* function that sets the given matrix based on given vertex group in lattice */
@@ -627,7 +627,7 @@ static void contarget_get_lattice_mat(Object *ob, const char *substring, float m
const int defgroup = BKE_object_defgroup_name_index(ob, substring);
/* initialize target matrix using target matrix */
- copy_m4_m4(mat, ob->obmat);
+ copy_m4_m4(mat, ob->object_to_world);
/* get index of vertex group */
if (defgroup == -1) {
@@ -661,11 +661,11 @@ static void contarget_get_lattice_mat(Object *ob, const char *substring, float m
}
}
- /* find average location, then multiply by ob->obmat to find world-space location */
+ /* find average location, then multiply by ob->object_to_world to find world-space location */
if (grouped) {
mul_v3_fl(vec, 1.0f / grouped);
}
- mul_v3_m4v3(tvec, ob->obmat, vec);
+ mul_v3_m4v3(tvec, ob->object_to_world, vec);
/* copy new location to matrix */
copy_v3_v3(mat[3], tvec);
@@ -684,7 +684,7 @@ static void constraint_target_to_mat4(Object *ob,
{
/* Case OBJECT */
if (substring[0] == '\0') {
- copy_m4_m4(mat, ob->obmat);
+ copy_m4_m4(mat, ob->object_to_world);
BKE_constraint_mat_convertspace(ob, NULL, cob, mat, from, to, false);
}
/* Case VERTEXGROUP */
@@ -719,7 +719,7 @@ static void constraint_target_to_mat4(Object *ob,
if (headtail < 0.000001f && !(is_bbone && full_bbone)) {
/* skip length interpolation if set to head */
- mul_m4_m4m4(mat, ob->obmat, pchan->pose_mat);
+ mul_m4_m4m4(mat, ob->object_to_world, pchan->pose_mat);
}
else if (is_bbone && pchan->bone->segments == pchan->runtime.bbone_segments) {
/* use point along bbone */
@@ -745,7 +745,7 @@ static void constraint_target_to_mat4(Object *ob,
mul_v3_m4v3(tempmat[3], pchan->pose_mat, loc);
}
- mul_m4_m4m4(mat, ob->obmat, tempmat);
+ mul_m4_m4m4(mat, ob->object_to_world, tempmat);
}
else {
float tempmat[4][4], loc[3];
@@ -757,11 +757,11 @@ static void constraint_target_to_mat4(Object *ob,
copy_m4_m4(tempmat, pchan->pose_mat);
copy_v3_v3(tempmat[3], loc);
- mul_m4_m4m4(mat, ob->obmat, tempmat);
+ mul_m4_m4m4(mat, ob->object_to_world, tempmat);
}
}
else {
- copy_m4_m4(mat, ob->obmat);
+ copy_m4_m4(mat, ob->object_to_world);
}
/* convert matrix space as required */
@@ -1069,7 +1069,7 @@ static void childof_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
if (data->flag & CHILDOF_SET_INVERSE) {
invert_m4_m4(data->invmat, parmat);
if (cob->pchan != NULL) {
- mul_m4_series(data->invmat, data->invmat, cob->ob->obmat);
+ mul_m4_series(data->invmat, data->invmat, cob->ob->object_to_world);
}
copy_m4_m4(inverse_matrix, data->invmat);
@@ -1283,9 +1283,8 @@ static void trackto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
cob->matrix[2][1] = 0;
cob->matrix[2][2] = size[2];
- /* targetmat[2] instead of ownermat[2] is passed to vectomat
- * for backwards compatibility it seems... (Aligorith)
- */
+ /* NOTE(@joshualung): `targetmat[2]` instead of `ownermat[2]` is passed to #vectomat
+ * for backwards compatibility it seems. */
sub_v3_v3v3(vec, cob->matrix[3], ct->matrix[3]);
vectomat(
vec, ct->matrix[2], (short)data->reserved1, (short)data->reserved2, data->flags, totmat);
@@ -1389,8 +1388,8 @@ static void kinematic_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
else {
float vec[3];
/* move grabtarget into world space */
- mul_v3_m4v3(vec, ob->obmat, data->grabtarget);
- copy_m4_m4(ct->matrix, ob->obmat);
+ mul_v3_m4v3(vec, ob->object_to_world, data->grabtarget);
+ copy_m4_m4(ct->matrix, ob->object_to_world);
copy_v3_v3(ct->matrix[3], vec);
}
}
@@ -1529,7 +1528,7 @@ static void followpath_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
copy_v3_v3(totmat[3], vec);
- mul_m4_m4m4(ct->matrix, ct->tar->obmat, totmat);
+ mul_m4_m4m4(ct->matrix, ct->tar->object_to_world, totmat);
}
}
}
@@ -2558,7 +2557,7 @@ static void armdef_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
bPoseChannel *pchan = BKE_pose_channel_find_name(ct->tar->pose, ct->subtarget);
if (pchan != NULL) {
- mul_m4_m4m4(ct->matrix, ct->tar->obmat, pchan->pose_mat);
+ mul_m4_m4m4(ct->matrix, ct->tar->object_to_world, pchan->pose_mat);
return;
}
}
@@ -2614,7 +2613,7 @@ static void armdef_accumulate_bone(bConstraintTarget *ct,
float weight = ct->weight;
/* Our object's location in target pose space. */
- invert_m4_m4(iobmat, ct->tar->obmat);
+ invert_m4_m4(iobmat, ct->tar->object_to_world);
mul_v3_m4v3(co, iobmat, wco);
/* Multiply by the envelope weight when appropriate. */
@@ -2645,7 +2644,7 @@ static void armdef_accumulate_bone(bConstraintTarget *ct,
mul_m4_m4m4(basemat, bone->arm_mat, b_bone_rest_mats[index].mat);
}
- armdef_accumulate_matrix(ct->tar->obmat,
+ armdef_accumulate_matrix(ct->tar->object_to_world,
iobmat,
basemat,
b_bone_mats[index + 1].mat,
@@ -2658,7 +2657,7 @@ static void armdef_accumulate_bone(bConstraintTarget *ct,
mul_m4_m4m4(basemat, bone->arm_mat, b_bone_rest_mats[index + 1].mat);
}
- armdef_accumulate_matrix(ct->tar->obmat,
+ armdef_accumulate_matrix(ct->tar->object_to_world,
iobmat,
basemat,
b_bone_mats[index + 2].mat,
@@ -2668,8 +2667,13 @@ static void armdef_accumulate_bone(bConstraintTarget *ct,
}
else {
/* Simple bone. This requires DEG_OPCODE_BONE_DONE dependency due to chan_mat. */
- armdef_accumulate_matrix(
- ct->tar->obmat, iobmat, bone->arm_mat, pchan->chan_mat, weight, r_sum_mat, r_sum_dq);
+ armdef_accumulate_matrix(ct->tar->object_to_world,
+ iobmat,
+ bone->arm_mat,
+ pchan->chan_mat,
+ weight,
+ r_sum_mat,
+ r_sum_dq);
}
/* Accumulate the weight. */
@@ -2695,7 +2699,7 @@ static void armdef_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targ
/* For constraints on bones, use the rest position to bind b-bone segments
* and envelopes, to allow safely changing the bone location as if parented. */
copy_v3_v3(input_co, cob->pchan->bone->arm_head);
- mul_m4_v3(cob->ob->obmat, input_co);
+ mul_m4_v3(cob->ob->object_to_world, input_co);
}
else {
copy_v3_v3(input_co, cob->matrix[3]);
@@ -2856,7 +2860,7 @@ static void actcon_get_tarmat(struct Depsgraph *depsgraph,
axis = data->type - 20;
}
- BLI_assert((unsigned int)axis < 3);
+ BLI_assert((uint)axis < 3);
/* Target defines the animation */
s = (vec[axis] - data->min) / (data->max - data->min);
@@ -3928,7 +3932,7 @@ static void clampto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
unit_m4(totmat);
copy_v3_v3(totmat[3], vec);
- mul_m4_m4m4(targetMatrix, ct->tar->obmat, totmat);
+ mul_m4_m4m4(targetMatrix, ct->tar->object_to_world, totmat);
}
}
@@ -4228,7 +4232,7 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
if (BKE_shrinkwrap_init_tree(
&tree, target_eval, scon->shrinkType, scon->shrinkMode, do_track_normal)) {
- BLI_space_transform_from_matrices(&transform, cob->matrix, ct->tar->obmat);
+ BLI_space_transform_from_matrices(&transform, cob->matrix, ct->tar->object_to_world);
switch (scon->shrinkType) {
case MOD_SHRINKWRAP_NEAREST_SURFACE:
@@ -4903,7 +4907,7 @@ static void followtrack_evaluate_using_3d_position_object(FollowTrackContext *co
/* Object matrix of the camera. */
float camera_obmat[4][4];
- copy_m4_m4(camera_obmat, camera_object->obmat);
+ copy_m4_m4(camera_obmat, camera_object->object_to_world);
/* Calculate inverted matrix of the solved camera at the current time. */
float reconstructed_camera_mat[4][4];
@@ -5055,10 +5059,10 @@ static void followtrack_project_to_depth_object_if_needed(FollowTrackContext *co
}
float depth_object_mat_inv[4][4];
- invert_m4_m4(depth_object_mat_inv, depth_object->obmat);
+ invert_m4_m4(depth_object_mat_inv, depth_object->object_to_world);
float ray_start[3], ray_end[3];
- mul_v3_m4v3(ray_start, depth_object_mat_inv, context->camera_object->obmat[3]);
+ mul_v3_m4v3(ray_start, depth_object_mat_inv, context->camera_object->object_to_world[3]);
mul_v3_m4v3(ray_end, depth_object_mat_inv, cob->matrix[3]);
float ray_direction[3];
@@ -5081,7 +5085,7 @@ static void followtrack_project_to_depth_object_if_needed(FollowTrackContext *co
&tree_data);
if (result != -1) {
- mul_v3_m4v3(cob->matrix[3], depth_object->obmat, hit.co);
+ mul_v3_m4v3(cob->matrix[3], depth_object->object_to_world, hit.co);
}
free_bvhtree_from_mesh(&tree_data);
@@ -5129,9 +5133,9 @@ static void followtrack_evaluate_using_2d_position(FollowTrackContext *context,
}
float disp[3];
- mul_v3_m4v3(disp, camera_object->obmat, vec);
+ mul_v3_m4v3(disp, camera_object->object_to_world, vec);
- copy_m4_m4(rmat, camera_object->obmat);
+ copy_m4_m4(rmat, camera_object->object_to_world);
zero_v3(rmat[3]);
mul_m4_m4m4(cob->matrix, cob->matrix, rmat);
@@ -5153,10 +5157,10 @@ static void followtrack_evaluate_using_2d_position(FollowTrackContext *context,
}
float disp[3];
- mul_v3_m4v3(disp, camera_object->obmat, vec);
+ mul_v3_m4v3(disp, camera_object->object_to_world, vec);
/* apply camera rotation so Z-axis would be co-linear */
- copy_m4_m4(rmat, camera_object->obmat);
+ copy_m4_m4(rmat, camera_object->object_to_world);
zero_v3(rmat[3]);
mul_m4_m4m4(cob->matrix, cob->matrix, rmat);
@@ -5304,7 +5308,7 @@ static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat);
invert_m4_m4(imat, mat);
- mul_m4_m4m4(parmat, camob->obmat, imat);
+ mul_m4_m4m4(parmat, camob->object_to_world, imat);
copy_m4_m4(obmat, cob->matrix);
@@ -5651,7 +5655,7 @@ bool BKE_constraint_apply_for_object(Depsgraph *depsgraph,
BLI_freelinkN(&single_con, new_con);
/* Apply transform from matrix. */
- BKE_object_apply_mat4(ob, ob_eval->obmat, true, true);
+ BKE_object_apply_mat4(ob, ob_eval->object_to_world, true, true);
return true;
}
@@ -5932,12 +5936,12 @@ static void constraint_copy_data_ex(bConstraint *dst,
cti->copy_data(dst, src);
}
- /* Fix usercounts for all referenced data that need it. */
+ /* Fix user-counts for all referenced data that need it. */
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
con_invoke_id_looper(cti, dst, con_fix_copied_refs_cb, NULL);
}
- /* for proxies we don't want to make extern */
+ /* For proxies we don't want to make external. */
if (do_extern) {
/* go over used ID-links for this constraint to ensure that they are valid for proxies */
con_invoke_id_looper(cti, dst, con_extern_cb, NULL);
@@ -6238,7 +6242,7 @@ void BKE_constraint_target_matrix_get(struct Depsgraph *depsgraph,
cob->ob = (Object *)ownerdata;
cob->pchan = NULL;
if (cob->ob) {
- copy_m4_m4(cob->matrix, cob->ob->obmat);
+ copy_m4_m4(cob->matrix, cob->ob->object_to_world);
copy_m4_m4(cob->startmat, cob->matrix);
}
else {
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 6a68d589e25..7a6ec7d3c20 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -393,37 +393,37 @@ static void *ctx_data_pointer_get(const bContext *C, const char *member)
return NULL;
}
-static int ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer)
+static bool ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer)
{
/* if context is NULL, pointer must be NULL too and that is a valid return */
if (C == NULL) {
*pointer = NULL;
- return 1;
+ return true;
}
bContextDataResult result;
if (ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
*pointer = result.ptr.data;
- return 1;
+ return true;
}
*pointer = NULL;
- return 0;
+ return false;
}
-static int ctx_data_collection_get(const bContext *C, const char *member, ListBase *list)
+static bool ctx_data_collection_get(const bContext *C, const char *member, ListBase *list)
{
bContextDataResult result;
if (ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
BLI_assert(result.type == CTX_DATA_TYPE_COLLECTION);
*list = result.list;
- return 1;
+ return true;
}
BLI_listbase_clear(list);
- return 0;
+ return false;
}
static int ctx_data_base_collection_get(const bContext *C, const char *member, ListBase *list)
@@ -440,6 +440,7 @@ static int ctx_data_base_collection_get(const bContext *C, const char *member, L
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
bool ok = false;
@@ -633,7 +634,7 @@ ListBase CTX_data_dir_get(const bContext *C)
bool CTX_data_equals(const char *member, const char *str)
{
- return (STREQ(member, str));
+ return STREQ(member, str);
}
bool CTX_data_dir(const char *member)
@@ -680,7 +681,7 @@ void CTX_data_list_add_ptr(bContextDataResult *result, const PointerRNA *ptr)
BLI_addtail(&result->list, link);
}
-int ctx_data_list_count(const bContext *C, int (*func)(const bContext *, ListBase *))
+int ctx_data_list_count(const bContext *C, bool (*func)(const bContext *, ListBase *))
{
ListBase list;
@@ -1299,62 +1300,62 @@ ToolSettings *CTX_data_tool_settings(const bContext *C)
return NULL;
}
-int CTX_data_selected_ids(const bContext *C, ListBase *list)
+bool CTX_data_selected_ids(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "selected_ids", list);
}
-int CTX_data_selected_nodes(const bContext *C, ListBase *list)
+bool CTX_data_selected_nodes(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "selected_nodes", list);
}
-int CTX_data_selected_editable_objects(const bContext *C, ListBase *list)
+bool CTX_data_selected_editable_objects(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "selected_editable_objects", list);
}
-int CTX_data_selected_editable_bases(const bContext *C, ListBase *list)
+bool CTX_data_selected_editable_bases(const bContext *C, ListBase *list)
{
return ctx_data_base_collection_get(C, "selected_editable_objects", list);
}
-int CTX_data_editable_objects(const bContext *C, ListBase *list)
+bool CTX_data_editable_objects(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "editable_objects", list);
}
-int CTX_data_editable_bases(const bContext *C, ListBase *list)
+bool CTX_data_editable_bases(const bContext *C, ListBase *list)
{
return ctx_data_base_collection_get(C, "editable_objects", list);
}
-int CTX_data_selected_objects(const bContext *C, ListBase *list)
+bool CTX_data_selected_objects(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "selected_objects", list);
}
-int CTX_data_selected_bases(const bContext *C, ListBase *list)
+bool CTX_data_selected_bases(const bContext *C, ListBase *list)
{
return ctx_data_base_collection_get(C, "selected_objects", list);
}
-int CTX_data_visible_objects(const bContext *C, ListBase *list)
+bool CTX_data_visible_objects(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "visible_objects", list);
}
-int CTX_data_visible_bases(const bContext *C, ListBase *list)
+bool CTX_data_visible_bases(const bContext *C, ListBase *list)
{
return ctx_data_base_collection_get(C, "visible_objects", list);
}
-int CTX_data_selectable_objects(const bContext *C, ListBase *list)
+bool CTX_data_selectable_objects(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "selectable_objects", list);
}
-int CTX_data_selectable_bases(const bContext *C, ListBase *list)
+bool CTX_data_selectable_bases(const bContext *C, ListBase *list)
{
return ctx_data_base_collection_get(C, "selectable_objects", list);
}
@@ -1371,8 +1372,9 @@ struct Base *CTX_data_active_base(const bContext *C)
if (ob == NULL) {
return NULL;
}
-
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
return BKE_view_layer_base_find(view_layer, ob);
}
@@ -1411,22 +1413,22 @@ struct CacheFile *CTX_data_edit_cachefile(const bContext *C)
return ctx_data_pointer_get(C, "edit_cachefile");
}
-int CTX_data_selected_bones(const bContext *C, ListBase *list)
+bool CTX_data_selected_bones(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "selected_bones", list);
}
-int CTX_data_selected_editable_bones(const bContext *C, ListBase *list)
+bool CTX_data_selected_editable_bones(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "selected_editable_bones", list);
}
-int CTX_data_visible_bones(const bContext *C, ListBase *list)
+bool CTX_data_visible_bones(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "visible_bones", list);
}
-int CTX_data_editable_bones(const bContext *C, ListBase *list)
+bool CTX_data_editable_bones(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "editable_bones", list);
}
@@ -1436,17 +1438,17 @@ struct bPoseChannel *CTX_data_active_pose_bone(const bContext *C)
return ctx_data_pointer_get(C, "active_pose_bone");
}
-int CTX_data_selected_pose_bones(const bContext *C, ListBase *list)
+bool CTX_data_selected_pose_bones(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "selected_pose_bones", list);
}
-int CTX_data_selected_pose_bones_from_active_object(const bContext *C, ListBase *list)
+bool CTX_data_selected_pose_bones_from_active_object(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "selected_pose_bones_from_active_object", list);
}
-int CTX_data_visible_pose_bones(const bContext *C, ListBase *list)
+bool CTX_data_visible_pose_bones(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "visible_pose_bones", list);
}
@@ -1466,17 +1468,17 @@ bGPDframe *CTX_data_active_gpencil_frame(const bContext *C)
return ctx_data_pointer_get(C, "active_gpencil_frame");
}
-int CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list)
+bool CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "visible_gpencil_layers", list);
}
-int CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list)
+bool CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "editable_gpencil_layers", list);
}
-int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list)
+bool CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "editable_gpencil_strokes", list);
}
@@ -1502,7 +1504,7 @@ AssetHandle CTX_wm_asset_handle(const bContext *C, bool *r_is_valid)
* require returning a non-owning pointer, which we don't have in the Asset Browser (yet). */
FileDirEntry *file =
(FileDirEntry *)CTX_data_pointer_get_type(C, "active_file", &RNA_FileSelectEntry).data;
- if (file && file->asset_data) {
+ if (file && file->asset) {
*r_is_valid = true;
return (AssetHandle){.file_data = file};
}
diff --git a/source/blender/blenkernel/intern/crazyspace.cc b/source/blender/blenkernel/intern/crazyspace.cc
index 7f1179d0804..f83c321c4ae 100644
--- a/source/blender/blenkernel/intern/crazyspace.cc
+++ b/source/blender/blenkernel/intern/crazyspace.cc
@@ -70,47 +70,48 @@ static void set_crazy_vertex_quat(float r_quat[4],
sub_qt_qtqt(r_quat, q2, q1);
}
-static bool modifiers_disable_subsurf_temporary(struct Scene *scene, Object *ob)
+static bool modifiers_disable_subsurf_temporary(Object *ob, const int cageIndex)
{
- bool disabled = false;
- int cageIndex = BKE_modifiers_get_cage_index(scene, ob, nullptr, true);
+ bool changed = false;
ModifierData *md = static_cast<ModifierData *>(ob->modifiers.first);
for (int i = 0; md && i <= cageIndex; i++, md = md->next) {
if (md->type == eModifierType_Subsurf) {
md->mode ^= eModifierMode_DisableTemporary;
- disabled = true;
+ changed = true;
}
}
- return disabled;
+ return changed;
}
float (*BKE_crazyspace_get_mapped_editverts(struct Depsgraph *depsgraph, Object *obedit))[3]
{
- Scene *scene = DEG_get_input_scene(depsgraph);
Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
Object *obedit_eval = DEG_get_evaluated_object(depsgraph, obedit);
- Mesh *mesh_eval = static_cast<Mesh *>(obedit_eval->data);
- BMEditMesh *editmesh_eval = mesh_eval->edit_mesh;
+ const int cageIndex = BKE_modifiers_get_cage_index(scene_eval, obedit_eval, nullptr, true);
- /* disable subsurf temporal, get mapped cos, and enable it */
- if (modifiers_disable_subsurf_temporary(scene_eval, obedit_eval)) {
- /* Need to make new derived-mesh. */
+ /* Disable subsurf temporal, get mapped cos, and enable it. */
+ if (modifiers_disable_subsurf_temporary(obedit_eval, cageIndex)) {
+ /* Need to make new cage.
+ * TODO: Avoid losing original evaluated geometry. */
makeDerivedMesh(depsgraph, scene_eval, obedit_eval, &CD_MASK_BAREMESH);
}
- /* now get the cage */
- Mesh *mesh_eval_cage = editbmesh_get_eval_cage_from_orig(
- depsgraph, scene, obedit, &CD_MASK_BAREMESH);
+ /* Now get the cage. */
+ BMEditMesh *em_eval = BKE_editmesh_from_object(obedit_eval);
+ Mesh *mesh_eval_cage = editbmesh_get_eval_cage(
+ depsgraph, scene_eval, obedit_eval, em_eval, &CD_MASK_BAREMESH);
- const int nverts = editmesh_eval->bm->totvert;
+ const int nverts = em_eval->bm->totvert;
float(*vertexcos)[3] = static_cast<float(*)[3]>(
MEM_mallocN(sizeof(*vertexcos) * nverts, "vertexcos map"));
mesh_get_mapped_verts_coords(mesh_eval_cage, vertexcos, nverts);
- /* set back the flag, no new cage needs to be built, transform does it */
- modifiers_disable_subsurf_temporary(scene_eval, obedit_eval);
+ /* Set back the flag, and ensure new cage needs to be built. */
+ if (modifiers_disable_subsurf_temporary(obedit_eval, cageIndex)) {
+ DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
+ }
return vertexcos;
}
@@ -268,7 +269,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra
const int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
CustomData_MeshMasks cd_mask_extra = CD_MASK_BAREMESH;
CDMaskLink *datamasks = BKE_modifier_calc_data_masks(
- scene, ob, md, &cd_mask_extra, required_mode, nullptr, nullptr);
+ scene, md, &cd_mask_extra, required_mode, nullptr, nullptr);
cd_mask_extra = datamasks->mask;
BLI_linklist_free((LinkNode *)datamasks, nullptr);
diff --git a/source/blender/blenkernel/intern/cryptomatte.cc b/source/blender/blenkernel/intern/cryptomatte.cc
index 72204f6624e..7c2e45d2f84 100644
--- a/source/blender/blenkernel/intern/cryptomatte.cc
+++ b/source/blender/blenkernel/intern/cryptomatte.cc
@@ -311,7 +311,7 @@ static std::string cryptomatte_determine_name(const ViewLayer *view_layer,
static uint32_t cryptomatte_determine_identifier(const blender::StringRef name)
{
- return BLI_hash_mm3(reinterpret_cast<const unsigned char *>(name.data()), name.size(), 0);
+ return BLI_hash_mm3(reinterpret_cast<const uchar *>(name.data()), name.size(), 0);
}
static void add_render_result_meta_data(RenderResult *render_result,
@@ -464,7 +464,7 @@ static std::string to_manifest(const CryptomatteLayer *layer)
else {
manifest << ",";
}
- manifest << quoted(item.key) << ":\"" << (item.value.hex_encoded()) << "\"";
+ manifest << quoted(item.key) << ":\"" << item.value.hex_encoded() << "\"";
}
manifest << "}";
return manifest.str();
@@ -580,7 +580,7 @@ blender::StringRef CryptomatteStampDataCallbackData::extract_layer_hash(blender:
void CryptomatteStampDataCallbackData::extract_layer_names(void *_data,
const char *propname,
char *propvalue,
- int UNUSED(len))
+ int /*len*/)
{
CryptomatteStampDataCallbackData *data = static_cast<CryptomatteStampDataCallbackData *>(_data);
@@ -598,7 +598,7 @@ void CryptomatteStampDataCallbackData::extract_layer_names(void *_data,
void CryptomatteStampDataCallbackData::extract_layer_manifest(void *_data,
const char *propname,
char *propvalue,
- int UNUSED(len))
+ int /*len*/)
{
CryptomatteStampDataCallbackData *data = static_cast<CryptomatteStampDataCallbackData *>(_data);
diff --git a/source/blender/blenkernel/intern/cryptomatte_test.cc b/source/blender/blenkernel/intern/cryptomatte_test.cc
index bb09b276645..8d360677599 100644
--- a/source/blender/blenkernel/intern/cryptomatte_test.cc
+++ b/source/blender/blenkernel/intern/cryptomatte_test.cc
@@ -88,10 +88,10 @@ TEST(cryptomatte, extract_layer_hash_from_metadata_key)
"cryptomatte/"));
}
-static void validate_cryptomatte_session_from_stamp_data(void *UNUSED(data),
+static void validate_cryptomatte_session_from_stamp_data(void * /*data*/,
const char *propname,
char *propvalue,
- int UNUSED(len))
+ int /*len*/)
{
blender::StringRefNull prop_name(propname);
if (!prop_name.startswith("cryptomatte/")) {
diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc
index aebdb8cc690..28961461819 100644
--- a/source/blender/blenkernel/intern/curve.cc
+++ b/source/blender/blenkernel/intern/curve.cc
@@ -395,7 +395,7 @@ void BKE_curve_init(Curve *cu, const short curve_type)
cu->flag |= CU_FRONT | CU_BACK;
cu->vfont = cu->vfontb = cu->vfonti = cu->vfontbi = BKE_vfont_builtin_get();
cu->vfont->id.us += 4;
- cu->str = (char *)MEM_malloc_arrayN(12, sizeof(unsigned char), "str");
+ cu->str = (char *)MEM_malloc_arrayN(12, sizeof(uchar), "str");
BLI_strncpy(cu->str, "Text", 12);
cu->len = cu->len_char32 = cu->pos = 4;
cu->strinfo = (CharInfo *)MEM_calloc_arrayN(12, sizeof(CharInfo), "strinfo new");
@@ -1056,7 +1056,7 @@ BPoint *BKE_nurb_bpoint_get_prev(Nurb *nu, BPoint *bp)
return bp_prev;
}
-void BKE_nurb_bezt_calc_normal(struct Nurb *UNUSED(nu), BezTriple *bezt, float r_normal[3])
+void BKE_nurb_bezt_calc_normal(struct Nurb * /*nu*/, BezTriple *bezt, float r_normal[3])
{
/* calculate the axis matrix from the spline */
float dir_prev[3], dir_next[3];
@@ -1499,7 +1499,7 @@ void BKE_nurb_makeFaces(const Nurb *nu, float *coord_array, int rowstride, int r
}
u += ustep;
if (rowstride != 0) {
- in = (float *)(((unsigned char *)in) + (rowstride - 3 * totv * sizeof(*in)));
+ in = (float *)(((uchar *)in) + (rowstride - 3 * totv * sizeof(*in)));
}
}
@@ -1647,35 +1647,34 @@ void BKE_nurb_makeCurve(const Nurb *nu,
MEM_freeN(basisu);
}
-unsigned int BKE_curve_calc_coords_axis_len(const unsigned int bezt_array_len,
- const unsigned int resolu,
- const bool is_cyclic,
- const bool use_cyclic_duplicate_endpoint)
+uint BKE_curve_calc_coords_axis_len(const uint bezt_array_len,
+ const uint resolu,
+ const bool is_cyclic,
+ const bool use_cyclic_duplicate_endpoint)
{
- const unsigned int segments = bezt_array_len - (is_cyclic ? 0 : 1);
- const unsigned int points_len = (segments * resolu) +
- (is_cyclic ? (use_cyclic_duplicate_endpoint) : 1);
+ const uint segments = bezt_array_len - (is_cyclic ? 0 : 1);
+ const uint points_len = (segments * resolu) + (is_cyclic ? (use_cyclic_duplicate_endpoint) : 1);
return points_len;
}
void BKE_curve_calc_coords_axis(const BezTriple *bezt_array,
- const unsigned int bezt_array_len,
- const unsigned int resolu,
+ const uint bezt_array_len,
+ const uint resolu,
const bool is_cyclic,
const bool use_cyclic_duplicate_endpoint,
/* array params */
- const unsigned int axis,
- const unsigned int stride,
+ const uint axis,
+ const uint stride,
float *r_points)
{
- const unsigned int points_len = BKE_curve_calc_coords_axis_len(
+ const uint points_len = BKE_curve_calc_coords_axis_len(
bezt_array_len, resolu, is_cyclic, use_cyclic_duplicate_endpoint);
float *r_points_offset = r_points;
- const unsigned int resolu_stride = resolu * stride;
- const unsigned int bezt_array_last = bezt_array_len - 1;
+ const uint resolu_stride = resolu * stride;
+ const uint bezt_array_last = bezt_array_len - 1;
- for (unsigned int i = 0; i < bezt_array_last; i++) {
+ for (uint i = 0; i < bezt_array_last; i++) {
const BezTriple *bezt_curr = &bezt_array[i];
const BezTriple *bezt_next = &bezt_array[i + 1];
BKE_curve_forward_diff_bezier(bezt_curr->vec[1][axis],
@@ -1683,7 +1682,7 @@ void BKE_curve_calc_coords_axis(const BezTriple *bezt_array,
bezt_next->vec[0][axis],
bezt_next->vec[1][axis],
r_points_offset,
- (int)resolu,
+ int(resolu),
stride);
r_points_offset = (float *)POINTER_OFFSET(r_points_offset, resolu_stride);
}
@@ -1696,7 +1695,7 @@ void BKE_curve_calc_coords_axis(const BezTriple *bezt_array,
bezt_next->vec[0][axis],
bezt_next->vec[1][axis],
r_points_offset,
- (int)resolu,
+ int(resolu),
stride);
r_points_offset = (float *)POINTER_OFFSET(r_points_offset, resolu_stride);
if (use_cyclic_duplicate_endpoint) {
@@ -1720,7 +1719,7 @@ void BKE_curve_forward_diff_bezier(
float rt0, rt1, rt2, rt3, f;
int a;
- f = (float)it;
+ f = float(it);
rt0 = q0;
rt1 = 3.0f * (q1 - q0) / f;
f *= f;
@@ -1748,7 +1747,7 @@ void BKE_curve_forward_diff_tangent_bezier(
float rt0, rt1, rt2, f;
int a;
- f = 1.0f / (float)it;
+ f = 1.0f / float(it);
rt0 = 3.0f * (q1 - q0);
rt1 = f * (3.0f * (q3 - q0) + 9.0f * (q1 - q2));
@@ -1779,7 +1778,7 @@ static void forward_diff_bezier_cotangent(const float p0[3],
*
* This could also be optimized like BKE_curve_forward_diff_bezier */
for (int a = 0; a <= it; a++) {
- float t = (float)a / (float)it;
+ float t = float(a) / float(it);
for (int i = 0; i < 3; i++) {
p[i] = (-6.0f * t + 6.0f) * p0[i] + (18.0f * t - 12.0f) * p1[i] +
@@ -1936,7 +1935,7 @@ static void calc_bevel_sin_cos(
t02 = M_PI_2;
}
else {
- t02 = (saacos(t02)) / 2.0f;
+ t02 = saacos(t02) / 2.0f;
}
t02 = sinf(t02);
@@ -2006,7 +2005,7 @@ static void tilt_bezpart(const BezTriple *prevbezt,
}
fac = 0.0;
- dfac = 1.0f / (float)resolu;
+ dfac = 1.0f / float(resolu);
for (a = 0; a < resolu; a++, fac += dfac) {
if (tilt_array) {
@@ -2247,7 +2246,7 @@ static void minimum_twist_between_two_points(BevPoint *current_point, BevPoint *
static void make_bevel_list_3D_minimum_twist(BevList *bl)
{
- BevPoint *bevp2, *bevp1, *bevp0; /* standard for all make_bevel_list_3D_* funcs */
+ BevPoint *bevp2, *bevp1, *bevp0; /* Standard for all make_bevel_list_3D_* functions. */
int nr;
float q[4];
@@ -2329,7 +2328,7 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl)
nr = bl->nr;
while (nr--) {
- ang_fac = angle * (1.0f - ((float)nr / bl->nr)); /* also works */
+ ang_fac = angle * (1.0f - (float(nr) / bl->nr)); /* also works */
axis_angle_to_quat(q, bevp1->dir, ang_fac);
mul_qt_qtqt(bevp1->quat, q, bevp1->quat);
@@ -2358,7 +2357,7 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl)
static void make_bevel_list_3D_tangent(BevList *bl)
{
- BevPoint *bevp2, *bevp1, *bevp0; /* standard for all make_bevel_list_3D_* funcs */
+ BevPoint *bevp2, *bevp1, *bevp0; /* Standard for all make_bevel_list_3D_* functions. */
int nr;
float bevp0_tan[3];
@@ -2516,7 +2515,7 @@ static void make_bevel_list_2D(BevList *bl)
/* first */
bevp = bl->bevpoints;
- angle = atan2f(bevp->dir[0], bevp->dir[1]) - (float)M_PI_2;
+ angle = atan2f(bevp->dir[0], bevp->dir[1]) - float(M_PI_2);
bevp->sina = sinf(angle);
bevp->cosa = cosf(angle);
vec_to_quat(bevp->quat, bevp->dir, 5, 1);
@@ -2524,7 +2523,7 @@ static void make_bevel_list_2D(BevList *bl)
/* last */
bevp = bl->bevpoints;
bevp += (bl->nr - 1);
- angle = atan2f(bevp->dir[0], bevp->dir[1]) - (float)M_PI_2;
+ angle = atan2f(bevp->dir[0], bevp->dir[1]) - float(M_PI_2);
bevp->sina = sinf(angle);
bevp->cosa = cosf(angle);
vec_to_quat(bevp->quat, bevp->dir, 5, 1);
@@ -3086,7 +3085,7 @@ void BKE_curve_bevelList_make(Object *ob, const ListBase *nurbs, const bool for_
make_bevel_list_segment_3D(bl);
}
else {
- make_bevel_list_3D(bl, (int)(resolu * cu->twist_smooth), cu->twist_mode);
+ make_bevel_list_3D(bl, int(resolu * cu->twist_smooth), cu->twist_mode);
}
}
}
@@ -4086,12 +4085,12 @@ void BKE_nurb_bezt_handle_test(BezTriple *bezt,
}
if (bezt->h1 == HD_VECT) {
- if ((!(flag & SEL_F1)) != (!(flag & SEL_F2))) {
+ if (!(flag & SEL_F1) != !(flag & SEL_F2)) {
bezt->h1 = HD_FREE;
}
}
if (bezt->h2 == HD_VECT) {
- if ((!(flag & SEL_F3)) != (!(flag & SEL_F2))) {
+ if (!(flag & SEL_F3) != !(flag & SEL_F2)) {
bezt->h2 = HD_FREE;
}
}
@@ -5102,7 +5101,7 @@ bool BKE_curve_minmax(Curve *cu, bool use_radius, float min[3], float max[3])
{
ListBase *nurb_lb = BKE_curve_nurbs_get(cu);
ListBase temp_nurb_lb = {nullptr, nullptr};
- const bool is_font = (BLI_listbase_is_empty(nurb_lb)) && (cu->len != 0);
+ const bool is_font = BLI_listbase_is_empty(nurb_lb) && (cu->len != 0);
/* For font curves we generate temp list of splines.
*
* This is likely to be fine, this function is not supposed to be called
@@ -5154,7 +5153,7 @@ bool BKE_curve_center_median(Curve *cu, float cent[3])
}
if (total) {
- mul_v3_fl(cent, 1.0f / (float)total);
+ mul_v3_fl(cent, 1.0f / float(total));
}
return (total != 0);
@@ -5390,10 +5389,10 @@ bool BKE_curve_material_index_validate(Curve *cu)
return false;
}
-void BKE_curve_material_remap(Curve *cu, const unsigned int *remap, unsigned int remap_len)
+void BKE_curve_material_remap(Curve *cu, const uint *remap, uint remap_len)
{
const int curvetype = BKE_curve_type_get(cu);
- const short remap_len_short = (short)remap_len;
+ const short remap_len_short = short(remap_len);
#define MAT_NR_REMAP(n) \
if (n < remap_len_short) { \
diff --git a/source/blender/blenkernel/intern/curve_bezier.cc b/source/blender/blenkernel/intern/curve_bezier.cc
index 59b09384698..3aa87be3787 100644
--- a/source/blender/blenkernel/intern/curve_bezier.cc
+++ b/source/blender/blenkernel/intern/curve_bezier.cc
@@ -210,7 +210,7 @@ void evaluate_segment(const float3 &point_0,
MutableSpan<float3> result)
{
BLI_assert(result.size() > 0);
- const float inv_len = 1.0f / static_cast<float>(result.size());
+ const float inv_len = 1.0f / float(result.size());
const float inv_len_squared = inv_len * inv_len;
const float inv_len_cubed = inv_len_squared * inv_len;
diff --git a/source/blender/blenkernel/intern/curve_catmull_rom.cc b/source/blender/blenkernel/intern/curve_catmull_rom.cc
index 952d59edcf9..b5f1a7cc450 100644
--- a/source/blender/blenkernel/intern/curve_catmull_rom.cc
+++ b/source/blender/blenkernel/intern/curve_catmull_rom.cc
@@ -17,16 +17,14 @@ int calculate_evaluated_num(const int points_num, const bool cyclic, const int r
}
/* Adapted from Cycles #catmull_rom_basis_eval function. */
-template<typename T>
-static T calculate_basis(const T &a, const T &b, const T &c, const T &d, const float parameter)
+void calculate_basis(const float parameter, float4 &r_weights)
{
const float t = parameter;
const float s = 1.0f - parameter;
- const float n0 = -t * s * s;
- const float n1 = 2.0f + t * t * (3.0f * t - 5.0f);
- const float n2 = 2.0f + s * s * (3.0f * s - 5.0f);
- const float n3 = -s * t * t;
- return 0.5f * (a * n0 + b * n1 + c * n2 + d * n3);
+ r_weights[0] = -t * s * s;
+ r_weights[1] = 2.0f + t * t * (3.0f * t - 5.0f);
+ r_weights[2] = 2.0f + s * s * (3.0f * s - 5.0f);
+ r_weights[3] = -s * t * t;
}
template<typename T>
@@ -35,7 +33,7 @@ static void evaluate_segment(const T &a, const T &b, const T &c, const T &d, Mut
const float step = 1.0f / dst.size();
dst.first() = b;
for (const int i : dst.index_range().drop_front(1)) {
- dst[i] = calculate_basis<T>(a, b, c, d, i * step);
+ dst[i] = interpolate<T>(a, b, c, d, i * step);
}
}
@@ -141,11 +139,7 @@ void interpolate_to_evaluated(const GSpan src,
{
attribute_math::convert_to_static_type(src.type(), [&](auto dummy) {
using T = decltype(dummy);
- /* TODO: Use DefaultMixer or other generic mixing in the basis evaluation function to simplify
- * supporting more types. */
- if constexpr (is_same_any_v<T, float, float2, float3, float4, int8_t, int, int64_t>) {
- interpolate_to_evaluated(src.typed<T>(), cyclic, resolution, dst.typed<T>());
- }
+ interpolate_to_evaluated(src.typed<T>(), cyclic, resolution, dst.typed<T>());
});
}
@@ -156,11 +150,7 @@ void interpolate_to_evaluated(const GSpan src,
{
attribute_math::convert_to_static_type(src.type(), [&](auto dummy) {
using T = decltype(dummy);
- /* TODO: Use DefaultMixer or other generic mixing in the basis evaluation function to simplify
- * supporting more types. */
- if constexpr (is_same_any_v<T, float, float2, float3, float4, int8_t, int, int64_t>) {
- interpolate_to_evaluated(src.typed<T>(), cyclic, evaluated_offsets, dst.typed<T>());
- }
+ interpolate_to_evaluated(src.typed<T>(), cyclic, evaluated_offsets, dst.typed<T>());
});
}
diff --git a/source/blender/blenkernel/intern/curve_deform.c b/source/blender/blenkernel/intern/curve_deform.c
index fb082fccc0b..066d8494451 100644
--- a/source/blender/blenkernel/intern/curve_deform.c
+++ b/source/blender/blenkernel/intern/curve_deform.c
@@ -44,8 +44,8 @@ typedef struct {
static void init_curve_deform(const Object *ob_curve, const Object *ob_target, CurveDeform *cd)
{
float imat[4][4];
- invert_m4_m4(imat, ob_target->obmat);
- mul_m4_m4m4(cd->objectspace, imat, ob_curve->obmat);
+ invert_m4_m4(imat, ob_target->object_to_world);
+ mul_m4_m4m4(cd->objectspace, imat, ob_curve->object_to_world);
invert_m4_m4(cd->curvespace, cd->objectspace);
copy_m3_m4(cd->objectspace3, cd->objectspace);
cd->no_rot_axis = 0;
@@ -160,7 +160,7 @@ static bool calc_curve_deform(
/* Zero the axis which is not used,
* the big block of text above now applies to these 3 lines.
* The `upflag` argument may be a dummy, set so no rotation is done. */
- quat_apply_track(quat, axis, (ELEM(axis, 0, 2)) ? 1 : 0);
+ quat_apply_track(quat, axis, ELEM(axis, 0, 2) ? 1 : 0);
vec_apply_track(cent, axis);
cent[index] = 0.0f;
diff --git a/source/blender/blenkernel/intern/curve_eval.cc b/source/blender/blenkernel/intern/curve_eval.cc
deleted file mode 100644
index 3bee82fadab..00000000000
--- a/source/blender/blenkernel/intern/curve_eval.cc
+++ /dev/null
@@ -1,587 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_array.hh"
-#include "BLI_index_range.hh"
-#include "BLI_listbase.h"
-#include "BLI_map.hh"
-#include "BLI_span.hh"
-#include "BLI_string_ref.hh"
-#include "BLI_task.hh"
-#include "BLI_vector.hh"
-
-#include "DNA_curve_types.h"
-
-#include "BKE_anonymous_attribute.hh"
-#include "BKE_curve.h"
-#include "BKE_curves.hh"
-#include "BKE_geometry_set.hh"
-#include "BKE_spline.hh"
-
-using blender::Array;
-using blender::float3;
-using blender::float4x4;
-using blender::GVArray;
-using blender::GVArraySpan;
-using blender::IndexRange;
-using blender::Map;
-using blender::MutableSpan;
-using blender::Span;
-using blender::StringRefNull;
-using blender::VArray;
-using blender::VArraySpan;
-using blender::Vector;
-using blender::bke::AttributeIDRef;
-using blender::bke::AttributeMetaData;
-
-blender::Span<SplinePtr> CurveEval::splines() const
-{
- return splines_;
-}
-
-blender::MutableSpan<SplinePtr> CurveEval::splines()
-{
- return splines_;
-}
-
-bool CurveEval::has_spline_with_type(const CurveType type) const
-{
- for (const SplinePtr &spline : this->splines()) {
- if (spline->type() == type) {
- return true;
- }
- }
- return false;
-}
-
-void CurveEval::resize(const int size)
-{
- splines_.resize(size);
- attributes.reallocate(size);
-}
-
-void CurveEval::add_spline(SplinePtr spline)
-{
- splines_.append(std::move(spline));
-}
-
-void CurveEval::add_splines(MutableSpan<SplinePtr> splines)
-{
- for (SplinePtr &spline : splines) {
- this->add_spline(std::move(spline));
- }
-}
-
-void CurveEval::remove_splines(blender::IndexMask mask)
-{
- for (int i = mask.size() - 1; i >= 0; i--) {
- splines_.remove_and_reorder(mask.indices()[i]);
- }
-}
-
-void CurveEval::translate(const float3 &translation)
-{
- for (SplinePtr &spline : this->splines()) {
- spline->translate(translation);
- spline->mark_cache_invalid();
- }
-}
-
-void CurveEval::transform(const float4x4 &matrix)
-{
- for (SplinePtr &spline : this->splines()) {
- spline->transform(matrix);
- }
-}
-
-bool CurveEval::bounds_min_max(float3 &min, float3 &max, const bool use_evaluated) const
-{
- bool have_minmax = false;
- for (const SplinePtr &spline : this->splines()) {
- if (spline->size()) {
- spline->bounds_min_max(min, max, use_evaluated);
- have_minmax = true;
- }
- }
-
- return have_minmax;
-}
-
-float CurveEval::total_length() const
-{
- float length = 0.0f;
- for (const SplinePtr &spline : this->splines()) {
- length += spline->length();
- }
- return length;
-}
-
-int CurveEval::total_control_point_num() const
-{
- int count = 0;
- for (const SplinePtr &spline : this->splines()) {
- count += spline->size();
- }
- return count;
-}
-
-blender::Array<int> CurveEval::control_point_offsets() const
-{
- Array<int> offsets(splines_.size() + 1);
- int offset = 0;
- for (const int i : splines_.index_range()) {
- offsets[i] = offset;
- offset += splines_[i]->size();
- }
- offsets.last() = offset;
- return offsets;
-}
-
-blender::Array<int> CurveEval::evaluated_point_offsets() const
-{
- Array<int> offsets(splines_.size() + 1);
- int offset = 0;
- for (const int i : splines_.index_range()) {
- offsets[i] = offset;
- offset += splines_[i]->evaluated_points_num();
- }
- offsets.last() = offset;
- return offsets;
-}
-
-blender::Array<float> CurveEval::accumulated_spline_lengths() const
-{
- Array<float> spline_lengths(splines_.size() + 1);
- float spline_length = 0.0f;
- for (const int i : splines_.index_range()) {
- spline_lengths[i] = spline_length;
- spline_length += splines_[i]->length();
- }
- spline_lengths.last() = spline_length;
- return spline_lengths;
-}
-
-void CurveEval::mark_cache_invalid()
-{
- for (SplinePtr &spline : splines_) {
- spline->mark_cache_invalid();
- }
-}
-
-static HandleType handle_type_from_dna_bezt(const eBezTriple_Handle dna_handle_type)
-{
- switch (dna_handle_type) {
- case HD_FREE:
- return BEZIER_HANDLE_FREE;
- case HD_AUTO:
- return BEZIER_HANDLE_AUTO;
- case HD_VECT:
- return BEZIER_HANDLE_VECTOR;
- case HD_ALIGN:
- return BEZIER_HANDLE_ALIGN;
- case HD_AUTO_ANIM:
- return BEZIER_HANDLE_AUTO;
- case HD_ALIGN_DOUBLESIDE:
- return BEZIER_HANDLE_ALIGN;
- }
- BLI_assert_unreachable();
- return BEZIER_HANDLE_AUTO;
-}
-
-static NormalMode normal_mode_from_dna_curve(const int twist_mode)
-{
- switch (twist_mode) {
- case CU_TWIST_Z_UP:
- case CU_TWIST_TANGENT:
- return NORMAL_MODE_Z_UP;
- case CU_TWIST_MINIMUM:
- return NORMAL_MODE_MINIMUM_TWIST;
- }
- BLI_assert_unreachable();
- return NORMAL_MODE_MINIMUM_TWIST;
-}
-
-static KnotsMode knots_mode_from_dna_nurb(const short flag)
-{
- switch (flag & (CU_NURB_ENDPOINT | CU_NURB_BEZIER)) {
- case CU_NURB_ENDPOINT:
- return NURBS_KNOT_MODE_ENDPOINT;
- case CU_NURB_BEZIER:
- return NURBS_KNOT_MODE_BEZIER;
- case CU_NURB_ENDPOINT | CU_NURB_BEZIER:
- return NURBS_KNOT_MODE_ENDPOINT_BEZIER;
- default:
- return NURBS_KNOT_MODE_NORMAL;
- }
-
- BLI_assert_unreachable();
- return NURBS_KNOT_MODE_NORMAL;
-}
-
-static SplinePtr spline_from_dna_bezier(const Nurb &nurb)
-{
- std::unique_ptr<BezierSpline> spline = std::make_unique<BezierSpline>();
- spline->set_resolution(nurb.resolu);
- spline->set_cyclic(nurb.flagu & CU_NURB_CYCLIC);
-
- Span<const BezTriple> src_points{nurb.bezt, nurb.pntsu};
- spline->resize(src_points.size());
- MutableSpan<float3> positions = spline->positions();
- MutableSpan<float3> handle_positions_left = spline->handle_positions_left(true);
- MutableSpan<float3> handle_positions_right = spline->handle_positions_right(true);
- MutableSpan<int8_t> handle_types_left = spline->handle_types_left();
- MutableSpan<int8_t> handle_types_right = spline->handle_types_right();
- MutableSpan<float> radii = spline->radii();
- MutableSpan<float> tilts = spline->tilts();
-
- blender::threading::parallel_for(src_points.index_range(), 2048, [&](IndexRange range) {
- for (const int i : range) {
- const BezTriple &bezt = src_points[i];
- positions[i] = bezt.vec[1];
- handle_positions_left[i] = bezt.vec[0];
- handle_types_left[i] = handle_type_from_dna_bezt((eBezTriple_Handle)bezt.h1);
- handle_positions_right[i] = bezt.vec[2];
- handle_types_right[i] = handle_type_from_dna_bezt((eBezTriple_Handle)bezt.h2);
- radii[i] = bezt.radius;
- tilts[i] = bezt.tilt;
- }
- });
-
- return spline;
-}
-
-static SplinePtr spline_from_dna_nurbs(const Nurb &nurb)
-{
- std::unique_ptr<NURBSpline> spline = std::make_unique<NURBSpline>();
- spline->set_resolution(nurb.resolu);
- spline->set_cyclic(nurb.flagu & CU_NURB_CYCLIC);
- spline->set_order(nurb.orderu);
- spline->knots_mode = knots_mode_from_dna_nurb(nurb.flagu);
-
- Span<const BPoint> src_points{nurb.bp, nurb.pntsu};
- spline->resize(src_points.size());
- MutableSpan<float3> positions = spline->positions();
- MutableSpan<float> weights = spline->weights();
- MutableSpan<float> radii = spline->radii();
- MutableSpan<float> tilts = spline->tilts();
-
- blender::threading::parallel_for(src_points.index_range(), 2048, [&](IndexRange range) {
- for (const int i : range) {
- const BPoint &bp = src_points[i];
- positions[i] = bp.vec;
- weights[i] = bp.vec[3];
- radii[i] = bp.radius;
- tilts[i] = bp.tilt;
- }
- });
-
- return spline;
-}
-
-static SplinePtr spline_from_dna_poly(const Nurb &nurb)
-{
- std::unique_ptr<PolySpline> spline = std::make_unique<PolySpline>();
- spline->set_cyclic(nurb.flagu & CU_NURB_CYCLIC);
-
- Span<const BPoint> src_points{nurb.bp, nurb.pntsu};
- spline->resize(src_points.size());
- MutableSpan<float3> positions = spline->positions();
- MutableSpan<float> radii = spline->radii();
- MutableSpan<float> tilts = spline->tilts();
-
- blender::threading::parallel_for(src_points.index_range(), 2048, [&](IndexRange range) {
- for (const int i : range) {
- const BPoint &bp = src_points[i];
- positions[i] = bp.vec;
- radii[i] = bp.radius;
- tilts[i] = bp.tilt;
- }
- });
-
- return spline;
-}
-
-std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve,
- const ListBase &nurbs_list)
-{
- Vector<const Nurb *> nurbs(nurbs_list);
-
- std::unique_ptr<CurveEval> curve = std::make_unique<CurveEval>();
- curve->resize(nurbs.size());
- MutableSpan<SplinePtr> splines = curve->splines();
-
- blender::threading::parallel_for(nurbs.index_range(), 256, [&](IndexRange range) {
- for (const int i : range) {
- switch (nurbs[i]->type) {
- case CU_BEZIER:
- splines[i] = spline_from_dna_bezier(*nurbs[i]);
- break;
- case CU_NURBS:
- splines[i] = spline_from_dna_nurbs(*nurbs[i]);
- break;
- case CU_POLY:
- splines[i] = spline_from_dna_poly(*nurbs[i]);
- break;
- default:
- BLI_assert_unreachable();
- break;
- }
- }
- });
-
- /* Normal mode is stored separately in each spline to facilitate combining
- * splines from multiple curve objects, where the value may be different. */
- const NormalMode normal_mode = normal_mode_from_dna_curve(dna_curve.twist_mode);
- for (SplinePtr &spline : curve->splines()) {
- spline->normal_mode = normal_mode;
- }
-
- return curve;
-}
-
-std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve)
-{
- return curve_eval_from_dna_curve(dna_curve, *BKE_curve_nurbs_get_for_read(&dna_curve));
-}
-
-static void copy_attributes_between_components(
- const blender::bke::AttributeAccessor &src_attributes,
- blender::bke::MutableAttributeAccessor &dst_attributes,
- Span<std::string> skip)
-{
- src_attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
- if (id.is_named() && skip.contains(id.name())) {
- return true;
- }
-
- GVArray src_attribute = src_attributes.lookup(id, meta_data.domain, meta_data.data_type);
- if (!src_attribute) {
- return true;
- }
- GVArraySpan src_attribute_data{src_attribute};
-
- blender::bke::GAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write(
- id, meta_data.domain, meta_data.data_type);
- if (!dst_attribute) {
- return true;
- }
- dst_attribute.varray.set_all(src_attribute_data.data());
- dst_attribute.finish();
- return true;
- });
-}
-
-std::unique_ptr<CurveEval> curves_to_curve_eval(const Curves &curves_id)
-{
- CurveComponent src_component;
- src_component.replace(&const_cast<Curves &>(curves_id), GeometryOwnershipType::ReadOnly);
- const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap(
- curves_id.geometry);
- const blender::bke::AttributeAccessor src_attributes = curves.attributes();
-
- VArray<int> resolution = curves.resolution();
- VArray<int8_t> normal_mode = curves.normal_mode();
-
- VArraySpan<float> nurbs_weights{
- src_attributes.lookup_or_default<float>("nurbs_weight", ATTR_DOMAIN_POINT, 1.0f)};
- VArraySpan<int8_t> nurbs_orders{
- src_attributes.lookup_or_default<int8_t>("nurbs_order", ATTR_DOMAIN_CURVE, 4)};
- VArraySpan<int8_t> nurbs_knots_modes{
- src_attributes.lookup_or_default<int8_t>("knots_mode", ATTR_DOMAIN_CURVE, 0)};
-
- VArraySpan<int8_t> handle_types_right{
- src_attributes.lookup_or_default<int8_t>("handle_type_right", ATTR_DOMAIN_POINT, 0)};
- VArraySpan<int8_t> handle_types_left{
- src_attributes.lookup_or_default<int8_t>("handle_type_left", ATTR_DOMAIN_POINT, 0)};
-
- /* Create splines with the correct size and type. */
- VArray<int8_t> curve_types = curves.curve_types();
- std::unique_ptr<CurveEval> curve_eval = std::make_unique<CurveEval>();
- for (const int curve_index : curve_types.index_range()) {
- const IndexRange points = curves.points_for_curve(curve_index);
-
- std::unique_ptr<Spline> spline;
- /* #CurveEval does not support catmull rom curves, so convert those to poly splines. */
- switch (std::max<int8_t>(1, curve_types[curve_index])) {
- case CURVE_TYPE_POLY: {
- spline = std::make_unique<PolySpline>();
- spline->resize(points.size());
- break;
- }
- case CURVE_TYPE_BEZIER: {
- std::unique_ptr<BezierSpline> bezier_spline = std::make_unique<BezierSpline>();
- bezier_spline->resize(points.size());
- bezier_spline->set_resolution(resolution[curve_index]);
- bezier_spline->handle_types_left().copy_from(handle_types_left.slice(points));
- bezier_spline->handle_types_right().copy_from(handle_types_right.slice(points));
-
- spline = std::move(bezier_spline);
- break;
- }
- case CURVE_TYPE_NURBS: {
- std::unique_ptr<NURBSpline> nurb_spline = std::make_unique<NURBSpline>();
- nurb_spline->resize(points.size());
- nurb_spline->set_resolution(resolution[curve_index]);
- nurb_spline->weights().copy_from(nurbs_weights.slice(points));
- nurb_spline->set_order(nurbs_orders[curve_index]);
- nurb_spline->knots_mode = static_cast<KnotsMode>(nurbs_knots_modes[curve_index]);
-
- spline = std::move(nurb_spline);
- break;
- }
- case CURVE_TYPE_CATMULL_ROM:
- /* Not supported yet. */
- BLI_assert_unreachable();
- continue;
- }
- spline->positions().fill(float3(0));
- spline->tilts().fill(0.0f);
- spline->radii().fill(1.0f);
- spline->normal_mode = static_cast<NormalMode>(normal_mode[curve_index]);
- curve_eval->add_spline(std::move(spline));
- }
-
- curve_eval->attributes.reallocate(curve_eval->splines().size());
-
- CurveComponentLegacy dst_component;
- dst_component.replace(curve_eval.get(), GeometryOwnershipType::Editable);
- blender::bke::MutableAttributeAccessor dst_attributes = *dst_component.attributes_for_write();
-
- copy_attributes_between_components(src_attributes,
- dst_attributes,
- {"curve_type",
- "resolution",
- "normal_mode",
- "nurbs_weight",
- "nurbs_order",
- "knots_mode",
- "handle_type_right",
- "handle_type_left"});
-
- return curve_eval;
-}
-
-Curves *curve_eval_to_curves(const CurveEval &curve_eval)
-{
- Curves *curves_id = blender::bke::curves_new_nomain(curve_eval.total_control_point_num(),
- curve_eval.splines().size());
- CurveComponent dst_component;
- dst_component.replace(curves_id, GeometryOwnershipType::Editable);
- blender::bke::MutableAttributeAccessor dst_attributes = *dst_component.attributes_for_write();
-
- blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap(curves_id->geometry);
- curves.offsets_for_write().copy_from(curve_eval.control_point_offsets());
- MutableSpan<int8_t> curve_types = curves.curve_types_for_write();
-
- blender::bke::SpanAttributeWriter<int8_t> normal_mode =
- dst_attributes.lookup_or_add_for_write_only_span<int8_t>("normal_mode", ATTR_DOMAIN_CURVE);
- blender::bke::SpanAttributeWriter<float> nurbs_weight;
- blender::bke::SpanAttributeWriter<int8_t> nurbs_order;
- blender::bke::SpanAttributeWriter<int8_t> nurbs_knots_mode;
- if (curve_eval.has_spline_with_type(CURVE_TYPE_NURBS)) {
- nurbs_weight = dst_attributes.lookup_or_add_for_write_only_span<float>("nurbs_weight",
- ATTR_DOMAIN_POINT);
- nurbs_order = dst_attributes.lookup_or_add_for_write_only_span<int8_t>("nurbs_order",
- ATTR_DOMAIN_CURVE);
- nurbs_knots_mode = dst_attributes.lookup_or_add_for_write_only_span<int8_t>("knots_mode",
- ATTR_DOMAIN_CURVE);
- }
- blender::bke::SpanAttributeWriter<int8_t> handle_type_right;
- blender::bke::SpanAttributeWriter<int8_t> handle_type_left;
- if (curve_eval.has_spline_with_type(CURVE_TYPE_BEZIER)) {
- handle_type_right = dst_attributes.lookup_or_add_for_write_only_span<int8_t>(
- "handle_type_right", ATTR_DOMAIN_POINT);
- handle_type_left = dst_attributes.lookup_or_add_for_write_only_span<int8_t>("handle_type_left",
- ATTR_DOMAIN_POINT);
- }
-
- for (const int curve_index : curve_eval.splines().index_range()) {
- const Spline &spline = *curve_eval.splines()[curve_index];
- curve_types[curve_index] = curve_eval.splines()[curve_index]->type();
- normal_mode.span[curve_index] = curve_eval.splines()[curve_index]->normal_mode;
- const IndexRange points = curves.points_for_curve(curve_index);
-
- switch (spline.type()) {
- case CURVE_TYPE_POLY:
- break;
- case CURVE_TYPE_BEZIER: {
- const BezierSpline &src = static_cast<const BezierSpline &>(spline);
- handle_type_right.span.slice(points).copy_from(src.handle_types_right());
- handle_type_left.span.slice(points).copy_from(src.handle_types_left());
- break;
- }
- case CURVE_TYPE_NURBS: {
- const NURBSpline &src = static_cast<const NURBSpline &>(spline);
- nurbs_knots_mode.span[curve_index] = static_cast<int8_t>(src.knots_mode);
- nurbs_order.span[curve_index] = src.order();
- nurbs_weight.span.slice(points).copy_from(src.weights());
- break;
- }
- case CURVE_TYPE_CATMULL_ROM: {
- BLI_assert_unreachable();
- break;
- }
- }
- }
-
- curves.update_curve_types();
-
- normal_mode.finish();
- nurbs_weight.finish();
- nurbs_order.finish();
- nurbs_knots_mode.finish();
- handle_type_right.finish();
- handle_type_left.finish();
-
- CurveComponentLegacy src_component;
- src_component.replace(&const_cast<CurveEval &>(curve_eval), GeometryOwnershipType::ReadOnly);
- const blender::bke::AttributeAccessor src_attributes = *src_component.attributes();
-
- copy_attributes_between_components(src_attributes, dst_attributes, {});
-
- return curves_id;
-}
-
-void CurveEval::assert_valid_point_attributes() const
-{
-#ifdef DEBUG
- if (splines_.size() == 0) {
- return;
- }
- const int layer_len = splines_.first()->attributes.data.totlayer;
-
- Array<AttributeIDRef> ids_in_order(layer_len);
- Array<AttributeMetaData> meta_data_in_order(layer_len);
-
- {
- int i = 0;
- splines_.first()->attributes.foreach_attribute(
- [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
- ids_in_order[i] = attribute_id;
- meta_data_in_order[i] = meta_data;
- i++;
- return true;
- },
- ATTR_DOMAIN_POINT);
- }
-
- for (const SplinePtr &spline : splines_) {
- /* All splines should have the same number of attributes. */
- BLI_assert(spline->attributes.data.totlayer == layer_len);
-
- int i = 0;
- spline->attributes.foreach_attribute(
- [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
- /* Attribute names and IDs should have the same order and exist on all splines. */
- BLI_assert(attribute_id == ids_in_order[i]);
-
- /* Attributes with the same ID different splines should all have the same type. */
- BLI_assert(meta_data == meta_data_in_order[i]);
-
- i++;
- return true;
- },
- ATTR_DOMAIN_POINT);
- }
-
-#endif
-}
diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc
index b9fea2a27b8..3a86068d8e8 100644
--- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc
+++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc
@@ -71,7 +71,7 @@ static void fill_mesh_topology(const int vert_offset,
MEdge &edge = edges[profile_edge_offset + i_ring];
edge.v1 = ring_vert_offset + i_profile;
edge.v2 = next_ring_vert_offset + i_profile;
- edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
+ edge.flag = ME_EDGEDRAW;
}
}
@@ -87,7 +87,7 @@ static void fill_mesh_topology(const int vert_offset,
MEdge &edge = edges[ring_edge_offset + i_profile];
edge.v1 = ring_vert_offset + i_profile;
edge.v2 = ring_vert_offset + i_next_profile;
- edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
+ edge.flag = ME_EDGEDRAW;
}
}
@@ -332,7 +332,8 @@ static eAttrDomain get_attribute_domain_for_mesh(const AttributeAccessor &mesh_a
static bool should_add_attribute_to_mesh(const AttributeAccessor &curve_attributes,
const AttributeAccessor &mesh_attributes,
- const AttributeIDRef &id)
+ const AttributeIDRef &id,
+ const AttributeMetaData &meta_data)
{
/* The position attribute has special non-generic evaluation. */
@@ -346,6 +347,9 @@ static bool should_add_attribute_to_mesh(const AttributeAccessor &curve_attribut
if (!id.should_be_kept()) {
return false;
}
+ if (meta_data.data_type == CD_PROP_STRING) {
+ return false;
+ }
return true;
}
@@ -714,7 +718,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
MutableAttributeAccessor mesh_attributes = mesh->attributes_for_write();
main_attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
- if (!should_add_attribute_to_mesh(main_attributes, mesh_attributes, id)) {
+ if (!should_add_attribute_to_mesh(main_attributes, mesh_attributes, id, meta_data)) {
return true;
}
main_attributes_set.add_new(id);
@@ -751,7 +755,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
if (main_attributes.contains(id)) {
return true;
}
- if (!should_add_attribute_to_mesh(profile_attributes, mesh_attributes, id)) {
+ if (!should_add_attribute_to_mesh(profile_attributes, mesh_attributes, id, meta_data)) {
return true;
}
const eAttrDomain src_domain = meta_data.domain;
diff --git a/source/blender/blenkernel/intern/curveprofile.cc b/source/blender/blenkernel/intern/curveprofile.cc
index 2f3fc2e95d8..db0cf16d467 100644
--- a/source/blender/blenkernel/intern/curveprofile.cc
+++ b/source/blender/blenkernel/intern/curveprofile.cc
@@ -207,7 +207,7 @@ bool BKE_curveprofile_remove_point(CurveProfile *profile, CurveProfilePoint *poi
CurveProfilePoint *new_path = (CurveProfilePoint *)MEM_mallocN(
sizeof(CurveProfilePoint) * profile->path_len, __func__);
- int i_delete = (int)(point - profile->path);
+ int i_delete = int(point - profile->path);
BLI_assert(i_delete > 0);
/* Copy the before and after the deleted point. */
@@ -379,8 +379,8 @@ static void curveprofile_build_supports(CurveProfile *profile)
point_init(&profile->path[0], 1.0f, 0.0f, 0, HD_VECT, HD_VECT);
point_init(&profile->path[1], 1.0f, 0.5f, 0, HD_VECT, HD_VECT);
for (int i = 1; i < n - 2; i++) {
- const float x = 1.0f - (0.5f * (1.0f - cosf((float)((i / (float)(n - 3))) * M_PI_2)));
- const float y = 0.5f + 0.5f * sinf((float)((i / (float)(n - 3)) * M_PI_2));
+ const float x = 1.0f - (0.5f * (1.0f - cosf(float(i / float(n - 3)) * M_PI_2)));
+ const float y = 0.5f + 0.5f * sinf(float((i / float(n - 3)) * M_PI_2));
point_init(&profile->path[i], x, y, 0, HD_AUTO, HD_AUTO);
}
point_init(&profile->path[n - 2], 0.5f, 1.0f, 0, HD_VECT, HD_VECT);
@@ -408,8 +408,8 @@ static void curveprofile_build_steps(CurveProfile *profile)
for (int i = 0; i < n; i++) {
int step_x = (i + 1) / 2;
int step_y = i / 2;
- const float x = 1.0f - ((float)(2 * step_x) / n_steps_x);
- const float y = (float)(2 * step_y) / n_steps_y;
+ const float x = 1.0f - (float(2 * step_x) / n_steps_x);
+ const float y = float(2 * step_y) / n_steps_y;
point_init(&profile->path[i], x, y, 0, HD_VECT, HD_VECT);
}
}
@@ -1048,13 +1048,13 @@ void BKE_curveprofile_evaluate_length_portion(const CurveProfile *profile,
#ifdef DEBUG_CURVEPROFILE_EVALUATE
printf("CURVEPROFILE EVALUATE\n");
- printf(" length portion input: %f\n", (double)length_portion);
- printf(" requested path length: %f\n", (double)requested_length);
- printf(" distance to next point: %f\n", (double)distance_to_next_point);
- printf(" length travelled: %f\n", (double)length_travelled);
- printf(" lerp-factor: %f\n", (double)lerp_factor);
- printf(" ith point (%f, %f)\n", (double)profile->path[i].x, (double)profile->path[i].y);
- printf(" next point(%f, %f)\n", (double)profile->path[i + 1].x, (double)profile->path[i + 1].y);
+ printf(" length portion input: %f\n", double(length_portion));
+ printf(" requested path length: %f\n", double(requested_length));
+ printf(" distance to next point: %f\n", double(distance_to_next_point));
+ printf(" length travelled: %f\n", double(length_travelled));
+ printf(" lerp-factor: %f\n", double(lerp_factor));
+ printf(" ith point (%f, %f)\n", double(profile->path[i].x), double(profile->path[i].y));
+ printf(" next point(%f, %f)\n", double(profile->path[i + 1].x), double(profile->path[i + 1].y));
#endif
*x_out = interpf(profile->table[i].x, profile->table[i + 1].x, lerp_factor);
diff --git a/source/blender/blenkernel/intern/curves.cc b/source/blender/blenkernel/intern/curves.cc
index e729fed050b..61755a5be9b 100644
--- a/source/blender/blenkernel/intern/curves.cc
+++ b/source/blender/blenkernel/intern/curves.cc
@@ -63,7 +63,7 @@ static void curves_init_data(ID *id)
new (&curves->geometry) blender::bke::CurvesGeometry();
}
-static void curves_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
+static void curves_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int flag)
{
using namespace blender;
@@ -263,7 +263,7 @@ BoundBox *BKE_curves_boundbox_get(Object *ob)
return ob->runtime.bb;
}
-bool BKE_curves_customdata_required(const Curves *UNUSED(curves), const char *name)
+bool BKE_curves_attribute_required(const Curves * /*curves*/, const char *name)
{
return STREQ(name, ATTR_POSITION);
}
@@ -287,7 +287,10 @@ static void curves_evaluate_modifiers(struct Depsgraph *depsgraph,
{
/* Modifier evaluation modes. */
const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
- const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
+ int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
+ if (BKE_object_is_in_editmode(object)) {
+ required_mode = (ModifierMode)(int(required_mode) | eModifierMode_Editmode);
+ }
ModifierApplyFlag apply_flag = use_render ? MOD_APPLY_RENDER : MOD_APPLY_USECACHE;
const ModifierEvalContext mectx = {depsgraph, object, apply_flag};
@@ -409,11 +412,11 @@ void curves_copy_parameters(const Curves &src, Curves &dst)
CurvesSurfaceTransforms::CurvesSurfaceTransforms(const Object &curves_ob, const Object *surface_ob)
{
- this->curves_to_world = curves_ob.obmat;
+ this->curves_to_world = curves_ob.object_to_world;
this->world_to_curves = this->curves_to_world.inverted();
if (surface_ob != nullptr) {
- this->surface_to_world = surface_ob->obmat;
+ this->surface_to_world = surface_ob->object_to_world;
this->world_to_surface = this->surface_to_world.inverted();
this->surface_to_curves = this->world_to_curves * this->surface_to_world;
this->curves_to_surface = this->world_to_surface * this->curves_to_world;
diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc
index 06789e34ad4..43bdb8e7b8c 100644
--- a/source/blender/blenkernel/intern/curves_geometry.cc
+++ b/source/blender/blenkernel/intern/curves_geometry.cc
@@ -9,6 +9,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_array_utils.hh"
#include "BLI_bounds.hh"
#include "BLI_index_mask_ops.hh"
#include "BLI_length_parameterize.hh"
@@ -510,17 +511,7 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves,
void CurvesGeometry::ensure_evaluated_offsets() const
{
- if (!this->runtime->offsets_cache_dirty) {
- return;
- }
-
- /* A double checked lock. */
- std::scoped_lock lock{this->runtime->offsets_cache_mutex};
- if (!this->runtime->offsets_cache_dirty) {
- return;
- }
-
- threading::isolate_task([&]() {
+ this->runtime->offsets_cache_mutex.ensure([&]() {
this->runtime->evaluated_offsets_cache.resize(this->curves_num() + 1);
if (this->has_curve_with_type(CURVE_TYPE_BEZIER)) {
@@ -533,8 +524,6 @@ void CurvesGeometry::ensure_evaluated_offsets() const
calculate_evaluated_offsets(
*this, this->runtime->evaluated_offsets_cache, this->runtime->bezier_evaluated_offsets);
});
-
- this->runtime->offsets_cache_dirty = false;
}
Span<int> CurvesGeometry::evaluated_offsets() const
@@ -557,19 +546,18 @@ IndexMask CurvesGeometry::indices_for_curve_type(const CurveType type,
this->curve_types(), this->curve_type_counts(), type, selection, r_indices);
}
-void CurvesGeometry::ensure_nurbs_basis_cache() const
+Array<int> CurvesGeometry::point_to_curve_map() const
{
- if (!this->runtime->nurbs_basis_cache_dirty) {
- return;
- }
-
- /* A double checked lock. */
- std::scoped_lock lock{this->runtime->nurbs_basis_cache_mutex};
- if (!this->runtime->nurbs_basis_cache_dirty) {
- return;
+ Array<int> map(this->points_num());
+ for (const int i : this->curves_range()) {
+ map.as_mutable_span().slice(this->points_for_curve(i)).fill(i);
}
+ return map;
+}
- threading::isolate_task([&]() {
+void CurvesGeometry::ensure_nurbs_basis_cache() const
+{
+ this->runtime->nurbs_basis_cache_mutex.ensure([&]() {
Vector<int64_t> nurbs_indices;
const IndexMask nurbs_mask = this->indices_for_curve_type(CURVE_TYPE_NURBS, nurbs_indices);
if (nurbs_mask.is_empty()) {
@@ -609,23 +597,11 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const
}
});
});
-
- this->runtime->nurbs_basis_cache_dirty = false;
}
Span<float3> CurvesGeometry::evaluated_positions() const
{
- if (!this->runtime->position_cache_dirty) {
- return this->runtime->evaluated_positions_span;
- }
-
- /* A double checked lock. */
- std::scoped_lock lock{this->runtime->position_cache_mutex};
- if (!this->runtime->position_cache_dirty) {
- return this->runtime->evaluated_positions_span;
- }
-
- threading::isolate_task([&]() {
+ this->runtime->position_cache_mutex.ensure([&]() {
if (this->is_single_type(CURVE_TYPE_POLY)) {
this->runtime->evaluated_positions_span = this->positions();
this->runtime->evaluated_position_cache.clear_and_make_inline();
@@ -689,24 +665,12 @@ Span<float3> CurvesGeometry::evaluated_positions() const
}
});
});
-
- this->runtime->position_cache_dirty = false;
return this->runtime->evaluated_positions_span;
}
Span<float3> CurvesGeometry::evaluated_tangents() const
{
- if (!this->runtime->tangent_cache_dirty) {
- return this->runtime->evaluated_tangent_cache;
- }
-
- /* A double checked lock. */
- std::scoped_lock lock{this->runtime->tangent_cache_mutex};
- if (!this->runtime->tangent_cache_dirty) {
- return this->runtime->evaluated_tangent_cache;
- }
-
- threading::isolate_task([&]() {
+ this->runtime->tangent_cache_mutex.ensure([&]() {
const Span<float3> evaluated_positions = this->evaluated_positions();
const VArray<bool> cyclic = this->cyclic();
@@ -722,9 +686,9 @@ Span<float3> CurvesGeometry::evaluated_tangents() const
}
});
- /* Correct the first and last tangents of non-cyclic Bezier curves so that they align with the
- * inner handles. This is a separate loop to avoid the cost when Bezier type curves are not
- * used. */
+ /* Correct the first and last tangents of non-cyclic Bezier curves so that they align with
+ * the inner handles. This is a separate loop to avoid the cost when Bezier type curves are
+ * not used. */
Vector<int64_t> bezier_indices;
const IndexMask bezier_mask = this->indices_for_curve_type(CURVE_TYPE_BEZIER, bezier_indices);
if (!bezier_mask.is_empty()) {
@@ -755,8 +719,6 @@ Span<float3> CurvesGeometry::evaluated_tangents() const
});
}
});
-
- this->runtime->tangent_cache_dirty = false;
return this->runtime->evaluated_tangent_cache;
}
@@ -771,17 +733,7 @@ static void rotate_directions_around_axes(MutableSpan<float3> directions,
Span<float3> CurvesGeometry::evaluated_normals() const
{
- if (!this->runtime->normal_cache_dirty) {
- return this->runtime->evaluated_normal_cache;
- }
-
- /* A double checked lock. */
- std::scoped_lock lock{this->runtime->normal_cache_mutex};
- if (!this->runtime->normal_cache_dirty) {
- return this->runtime->evaluated_normal_cache;
- }
-
- threading::isolate_task([&]() {
+ this->runtime->normal_cache_mutex.ensure([&]() {
const Span<float3> evaluated_tangents = this->evaluated_tangents();
const VArray<bool> cyclic = this->cyclic();
const VArray<int8_t> normal_mode = this->normal_mode();
@@ -832,8 +784,6 @@ Span<float3> CurvesGeometry::evaluated_normals() const
}
});
});
-
- this->runtime->normal_cache_dirty = false;
return this->runtime->evaluated_normal_cache;
}
@@ -841,8 +791,8 @@ void CurvesGeometry::interpolate_to_evaluated(const int curve_index,
const GSpan src,
GMutableSpan dst) const
{
- BLI_assert(!this->runtime->offsets_cache_dirty);
- BLI_assert(!this->runtime->nurbs_basis_cache_dirty);
+ BLI_assert(this->runtime->offsets_cache_mutex.is_cached());
+ BLI_assert(this->runtime->nurbs_basis_cache_mutex.is_cached());
const IndexRange points = this->points_for_curve(curve_index);
BLI_assert(src.size() == points.size());
BLI_assert(dst.size() == this->evaluated_points_for_curve(curve_index).size());
@@ -871,8 +821,8 @@ void CurvesGeometry::interpolate_to_evaluated(const int curve_index,
void CurvesGeometry::interpolate_to_evaluated(const GSpan src, GMutableSpan dst) const
{
- BLI_assert(!this->runtime->offsets_cache_dirty);
- BLI_assert(!this->runtime->nurbs_basis_cache_dirty);
+ BLI_assert(this->runtime->offsets_cache_mutex.is_cached());
+ BLI_assert(this->runtime->nurbs_basis_cache_mutex.is_cached());
const VArray<int8_t> types = this->curve_types();
const VArray<int> resolution = this->resolution();
const VArray<bool> cyclic = this->cyclic();
@@ -913,17 +863,7 @@ void CurvesGeometry::interpolate_to_evaluated(const GSpan src, GMutableSpan dst)
void CurvesGeometry::ensure_evaluated_lengths() const
{
- if (!this->runtime->length_cache_dirty) {
- return;
- }
-
- /* A double checked lock. */
- std::scoped_lock lock{this->runtime->length_cache_mutex};
- if (!this->runtime->length_cache_dirty) {
- return;
- }
-
- threading::isolate_task([&]() {
+ this->runtime->length_cache_mutex.ensure([&]() {
/* Use an extra length value for the final cyclic segment for a consistent size
* (see comment on #evaluated_length_cache). */
const int total_num = this->evaluated_points_num() + this->curves_num();
@@ -944,8 +884,6 @@ void CurvesGeometry::ensure_evaluated_lengths() const
}
});
});
-
- this->runtime->length_cache_dirty = false;
}
void CurvesGeometry::ensure_can_interpolate_to_evaluated() const
@@ -976,23 +914,23 @@ void CurvesGeometry::resize(const int points_num, const int curves_num)
void CurvesGeometry::tag_positions_changed()
{
- this->runtime->position_cache_dirty = true;
- this->runtime->tangent_cache_dirty = true;
- this->runtime->normal_cache_dirty = true;
- this->runtime->length_cache_dirty = true;
+ this->runtime->position_cache_mutex.tag_dirty();
+ this->runtime->tangent_cache_mutex.tag_dirty();
+ this->runtime->normal_cache_mutex.tag_dirty();
+ this->runtime->length_cache_mutex.tag_dirty();
}
void CurvesGeometry::tag_topology_changed()
{
- this->runtime->position_cache_dirty = true;
- this->runtime->tangent_cache_dirty = true;
- this->runtime->normal_cache_dirty = true;
- this->runtime->offsets_cache_dirty = true;
- this->runtime->nurbs_basis_cache_dirty = true;
- this->runtime->length_cache_dirty = true;
+ this->runtime->position_cache_mutex.tag_dirty();
+ this->runtime->tangent_cache_mutex.tag_dirty();
+ this->runtime->normal_cache_mutex.tag_dirty();
+ this->runtime->offsets_cache_mutex.tag_dirty();
+ this->runtime->nurbs_basis_cache_mutex.tag_dirty();
+ this->runtime->length_cache_mutex.tag_dirty();
}
void CurvesGeometry::tag_normals_changed()
{
- this->runtime->normal_cache_dirty = true;
+ this->runtime->normal_cache_mutex.tag_dirty();
}
static void translate_positions(MutableSpan<float3> positions, const float3 &translation)
@@ -1102,21 +1040,11 @@ static void copy_between_buffers(const CPPType &type,
src_range.size());
}
-template<typename T>
-static void copy_with_map(const Span<T> src, const Span<int> map, MutableSpan<T> dst)
-{
- threading::parallel_for(map.index_range(), 1024, [&](const IndexRange range) {
- for (const int i : range) {
- dst[i] = src[map[i]];
- }
- });
-}
-
static void copy_with_map(const GSpan src, const Span<int> map, GMutableSpan dst)
{
attribute_math::convert_to_static_type(src.type(), [&](auto dummy) {
using T = decltype(dummy);
- copy_with_map(src.typed<T>(), map, dst.typed<T>());
+ array_utils::gather(src.typed<T>(), map, dst.typed<T>());
});
}
@@ -1224,6 +1152,10 @@ static CurvesGeometry copy_with_removed_points(const CurvesGeometry &curves,
attribute.dst.finish();
}
+ if (new_curves.curves_num() != curves.curves_num()) {
+ new_curves.remove_attributes_based_on_types();
+ }
+
return new_curves;
}
@@ -1329,6 +1261,8 @@ static CurvesGeometry copy_with_removed_curves(const CurvesGeometry &curves,
attribute.dst.finish();
}
+ new_curves.remove_attributes_based_on_types();
+
return new_curves;
}
@@ -1393,6 +1327,9 @@ void CurvesGeometry::reverse_curves(const IndexMask curves_to_reverse)
if (meta_data.domain != ATTR_DOMAIN_POINT) {
return true;
}
+ if (meta_data.data_type == CD_PROP_STRING) {
+ return true;
+ }
if (id.is_named() && bezier_handle_names.contains(id.name())) {
return true;
}
@@ -1558,6 +1495,11 @@ GVArray CurvesGeometry::adapt_domain(const GVArray &varray,
if (from == to) {
return varray;
}
+ if (varray.is_single()) {
+ BUFFER_FOR_CPP_TYPE_VALUE(varray.type(), value);
+ varray.get_internal_single(value);
+ return GVArray::ForSingle(varray.type(), this->attributes().domain_size(to), value);
+ }
if (from == ATTR_DOMAIN_POINT && to == ATTR_DOMAIN_CURVE) {
return adapt_curve_domain_point_to_curve(*this, varray);
diff --git a/source/blender/blenkernel/intern/curves_utils.cc b/source/blender/blenkernel/intern/curves_utils.cc
index d98832e796c..f5a69a995a3 100644
--- a/source/blender/blenkernel/intern/curves_utils.cc
+++ b/source/blender/blenkernel/intern/curves_utils.cc
@@ -84,6 +84,21 @@ void fill_points(const CurvesGeometry &curves,
});
}
+void fill_points(const CurvesGeometry &curves,
+ Span<IndexRange> curve_ranges,
+ GPointer value,
+ GMutableSpan dst)
+{
+ BLI_assert(*value.type() == dst.type());
+ const CPPType &type = dst.type();
+ threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange range) {
+ for (const IndexRange range : curve_ranges.slice(range)) {
+ const IndexRange points = curves.points_for_curves(range);
+ type.fill_assign_n(value.get(), dst.slice(points).data(), points.size());
+ }
+ });
+}
+
bke::CurvesGeometry copy_only_curve_domain(const bke::CurvesGeometry &src_curves)
{
bke::CurvesGeometry dst_curves(0, src_curves.curves_num());
diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc
index 82a1a2aa8f6..84aa2207400 100644
--- a/source/blender/blenkernel/intern/customdata.cc
+++ b/source/blender/blenkernel/intern/customdata.cc
@@ -19,6 +19,7 @@
#include "BLI_bitmap.h"
#include "BLI_color.hh"
+#include "BLI_cpp_type_make.hh"
#include "BLI_endian_switch.h"
#include "BLI_index_range.hh"
#include "BLI_math.h"
@@ -232,7 +233,7 @@ static void layerFree_mdeformvert(void *data, const int count, const int size)
static void layerInterp_mdeformvert(const void **sources,
const float *weights,
- const float *UNUSED(sub_weights),
+ const float * /*sub_weights*/,
const int count,
void *dest)
{
@@ -331,7 +332,7 @@ static void layerConstruct_mdeformvert(void *data, const int count)
static void layerInterp_normal(const void **sources,
const float *weights,
- const float *UNUSED(sub_weights),
+ const float * /*sub_weights*/,
const int count,
void *dest)
{
@@ -472,7 +473,7 @@ static void layerCopy_propFloat(const void *source, void *dest, const int count)
static void layerInterp_propFloat(const void **sources,
const float *weights,
- const float *UNUSED(sub_weights),
+ const float * /*sub_weights*/,
const int count,
void *dest)
{
@@ -510,7 +511,7 @@ static bool layerValidate_propFloat(void *data, const uint totitems, const bool
static void layerInterp_propInt(const void **sources,
const float *weights,
- const float *UNUSED(sub_weights),
+ const float * /*sub_weights*/,
const int count,
void *dest)
{
@@ -520,7 +521,7 @@ static void layerInterp_propInt(const void **sources,
const float src = *static_cast<const int *>(sources[i]);
result += src * weight;
}
- const int rounded_result = static_cast<int>(round(result));
+ const int rounded_result = int(round(result));
*static_cast<int *>(dest) = rounded_result;
}
@@ -646,7 +647,7 @@ static void layerCopy_mdisps(const void *source, void *dest, const int count)
for (int i = 0; i < count; i++) {
if (s[i].disps) {
d[i].disps = static_cast<float(*)[3]>(MEM_dupallocN(s[i].disps));
- d[i].hidden = static_cast<unsigned int *>(MEM_dupallocN(s[i].hidden));
+ d[i].hidden = static_cast<uint *>(MEM_dupallocN(s[i].hidden));
}
else {
d[i].disps = nullptr;
@@ -659,7 +660,7 @@ static void layerCopy_mdisps(const void *source, void *dest, const int count)
}
}
-static void layerFree_mdisps(void *data, const int count, const int UNUSED(size))
+static void layerFree_mdisps(void *data, const int count, const int /*size*/)
{
MDisps *d = static_cast<MDisps *>(data);
@@ -714,7 +715,7 @@ static bool layerWrite_mdisps(CDataFile *cdf, const void *data, const int count)
return true;
}
-static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), const void *data, const int count)
+static size_t layerFilesize_mdisps(CDataFile * /*cdf*/, const void *data, const int count)
{
const MDisps *d = static_cast<const MDisps *>(data);
size_t size = 0;
@@ -733,7 +734,7 @@ static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), const void *data, con
* \{ */
/* copy just zeros in this case */
-static void layerCopy_bmesh_elem_py_ptr(const void *UNUSED(source), void *dest, const int count)
+static void layerCopy_bmesh_elem_py_ptr(const void * /*source*/, void *dest, const int count)
{
const int size = sizeof(void *);
@@ -744,7 +745,7 @@ static void layerCopy_bmesh_elem_py_ptr(const void *UNUSED(source), void *dest,
}
#ifndef WITH_PYTHON
-void bpy_bm_generic_invalidate(struct BPy_BMGeneric *UNUSED(self))
+void bpy_bm_generic_invalidate(struct BPy_BMGeneric * /*self*/)
{
/* dummy */
}
@@ -768,7 +769,7 @@ static void layerFree_bmesh_elem_py_ptr(void *data, const int count, const int s
static void layerInterp_paint_mask(const void **sources,
const float *weights,
- const float *UNUSED(sub_weights),
+ const float * /*sub_weights*/,
int count,
void *dest)
{
@@ -804,7 +805,7 @@ static void layerCopy_grid_paint_mask(const void *source, void *dest, const int
}
}
-static void layerFree_grid_paint_mask(void *data, const int count, const int UNUSED(size))
+static void layerFree_grid_paint_mask(void *data, const int count, const int /*size*/)
{
GridPaintMask *gpm = static_cast<GridPaintMask *>(data);
@@ -832,7 +833,7 @@ static void layerCopyValue_mloopcol(const void *source,
{
const MLoopCol *m1 = static_cast<const MLoopCol *>(source);
MLoopCol *m2 = static_cast<MLoopCol *>(dest);
- unsigned char tmp_col[4];
+ uchar tmp_col[4];
if (ELEM(mixmode,
CDT_MIX_NOMIX,
@@ -841,7 +842,7 @@ static void layerCopyValue_mloopcol(const void *source,
/* Modes that do a full copy or nothing. */
if (ELEM(mixmode, CDT_MIX_REPLACE_ABOVE_THRESHOLD, CDT_MIX_REPLACE_BELOW_THRESHOLD)) {
/* TODO: Check for a real valid way to get 'factor' value of our dest color? */
- const float f = ((float)m2->r + (float)m2->g + (float)m2->b) / 3.0f;
+ const float f = (float(m2->r) + float(m2->g) + float(m2->b)) / 3.0f;
if (mixmode == CDT_MIX_REPLACE_ABOVE_THRESHOLD && f < mixfactor) {
return; /* Do Nothing! */
}
@@ -855,8 +856,8 @@ static void layerCopyValue_mloopcol(const void *source,
m2->a = m1->a;
}
else { /* Modes that support 'real' mix factor. */
- unsigned char src[4] = {m1->r, m1->g, m1->b, m1->a};
- unsigned char dst[4] = {m2->r, m2->g, m2->b, m2->a};
+ uchar src[4] = {m1->r, m1->g, m1->b, m1->a};
+ uchar dst[4] = {m2->r, m2->g, m2->b, m2->a};
if (mixmode == CDT_MIX_MIX) {
blend_color_mix_byte(tmp_col, dst, src);
@@ -876,10 +877,10 @@ static void layerCopyValue_mloopcol(const void *source,
blend_color_interpolate_byte(dst, dst, tmp_col, mixfactor);
- m2->r = (char)dst[0];
- m2->g = (char)dst[1];
- m2->b = (char)dst[2];
- m2->a = (char)dst[3];
+ m2->r = char(dst[0]);
+ m2->g = char(dst[1]);
+ m2->b = char(dst[2]);
+ m2->a = char(dst[3]);
}
}
@@ -901,10 +902,10 @@ static void layerMultiply_mloopcol(void *data, const float fac)
{
MLoopCol *m = static_cast<MLoopCol *>(data);
- m->r = (float)m->r * fac;
- m->g = (float)m->g * fac;
- m->b = (float)m->b * fac;
- m->a = (float)m->a * fac;
+ m->r = float(m->r) * fac;
+ m->g = float(m->g) * fac;
+ m->b = float(m->b) * fac;
+ m->a = float(m->a) * fac;
}
static void layerAdd_mloopcol(void *data1, const void *data2)
@@ -977,7 +978,7 @@ static void layerDefault_mloopcol(void *data, const int count)
static void layerInterp_mloopcol(const void **sources,
const float *weights,
- const float *UNUSED(sub_weights),
+ const float * /*sub_weights*/,
int count,
void *dest)
{
@@ -1075,7 +1076,7 @@ static void layerAdd_mloopuv(void *data1, const void *data2)
static void layerInterp_mloopuv(const void **sources,
const float *weights,
- const float *UNUSED(sub_weights),
+ const float * /*sub_weights*/,
int count,
void *dest)
{
@@ -1118,8 +1119,8 @@ static bool layerValidate_mloopuv(void *data, const uint totitems, const bool do
/* origspace is almost exact copy of mloopuv's, keep in sync */
static void layerCopyValue_mloop_origspace(const void *source,
void *dest,
- const int UNUSED(mixmode),
- const float UNUSED(mixfactor))
+ const int /*mixmode*/,
+ const float /*mixfactor*/)
{
const OrigSpaceLoop *luv1 = static_cast<const OrigSpaceLoop *>(source);
OrigSpaceLoop *luv2 = static_cast<OrigSpaceLoop *>(dest);
@@ -1169,7 +1170,7 @@ static void layerAdd_mloop_origspace(void *data1, const void *data2)
static void layerInterp_mloop_origspace(const void **sources,
const float *weights,
- const float *UNUSED(sub_weights),
+ const float * /*sub_weights*/,
int count,
void *dest)
{
@@ -1267,7 +1268,7 @@ static void layerDefault_origindex(void *data, const int count)
static void layerInterp_bweight(const void **sources,
const float *weights,
- const float *UNUSED(sub_weights),
+ const float * /*sub_weights*/,
int count,
void *dest)
{
@@ -1290,7 +1291,7 @@ static void layerInterp_bweight(const void **sources,
static void layerInterp_shapekey(const void **sources,
const float *weights,
- const float *UNUSED(sub_weights),
+ const float * /*sub_weights*/,
int count,
void *dest)
{
@@ -1335,7 +1336,7 @@ static void layerCopy_mvert_skin(const void *source, void *dest, const int count
static void layerInterp_mvert_skin(const void **sources,
const float *weights,
- const float *UNUSED(sub_weights),
+ const float * /*sub_weights*/,
int count,
void *dest)
{
@@ -1498,7 +1499,7 @@ static void layerDefault_propcol(void *data, const int count)
static void layerInterp_propcol(const void **sources,
const float *weights,
- const float *UNUSED(sub_weights),
+ const float * /*sub_weights*/,
int count,
void *dest)
{
@@ -1520,7 +1521,7 @@ static void layerInterp_propcol(const void **sources,
static void layerInterp_propfloat3(const void **sources,
const float *weights,
- const float *UNUSED(sub_weights),
+ const float * /*sub_weights*/,
int count,
void *dest)
{
@@ -1573,7 +1574,7 @@ static bool layerValidate_propfloat3(void *data, const uint totitems, const bool
static void layerInterp_propfloat2(const void **sources,
const float *weights,
- const float *UNUSED(sub_weights),
+ const float * /*sub_weights*/,
int count,
void *dest)
{
@@ -1624,7 +1625,7 @@ static bool layerValidate_propfloat2(void *data, const uint totitems, const bool
static void layerInterp_propbool(const void **sources,
const float *weights,
- const float *UNUSED(sub_weights),
+ const float * /*sub_weights*/,
int count,
void *dest)
{
@@ -1869,9 +1870,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* 29: CD_BWEIGHT */
{sizeof(MFloatProperty), "MFloatProperty", 1, nullptr, nullptr, nullptr, layerInterp_bweight},
/* 30: CD_CREASE */
- /* NOTE: we do not interpolate crease data as it should be either inherited for subdivided
- * edges, or for vertex creases, only present on the original vertex. */
- {sizeof(float), "", 0, N_("SubSurfCrease"), nullptr, nullptr, nullptr},
+ {sizeof(float), "", 0, nullptr, nullptr, nullptr, layerInterp_propFloat},
/* 31: CD_ORIGSPACE_MLOOP */
{sizeof(OrigSpaceLoop),
"OrigSpaceLoop",
@@ -1967,7 +1966,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(short[4][3]), "", 0, nullptr, nullptr, nullptr, nullptr, layerSwap_flnor, nullptr},
/* 41: CD_CUSTOMLOOPNORMAL */
{sizeof(short[2]), "vec2s", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
- /* 42: CD_SCULPT_FACE_SETS */
+ /* 42: CD_SCULPT_FACE_SETS */ /* DEPRECATED */
{sizeof(int), "", 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
/* 43: CD_LOCATION */
{sizeof(float[3]), "vec3f", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
@@ -2124,11 +2123,11 @@ const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX = {
const CustomData_MeshMasks CD_MASK_MESH = {
/* vmask */ (CD_MASK_MVERT | CD_MASK_MDEFORMVERT | CD_MASK_MVERT_SKIN | CD_MASK_PAINT_MASK |
CD_MASK_PROP_ALL | CD_MASK_CREASE | CD_MASK_BWEIGHT),
- /* emask */ (CD_MASK_MEDGE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL | CD_MASK_BWEIGHT),
+ /* emask */
+ (CD_MASK_MEDGE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL | CD_MASK_BWEIGHT | CD_MASK_CREASE),
/* fmask */ 0,
/* pmask */
- (CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL |
- CD_MASK_SCULPT_FACE_SETS),
+ (CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL),
/* lmask */
(CD_MASK_MLOOP | CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_CUSTOMLOOPNORMAL |
CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL),
@@ -2137,11 +2136,12 @@ const CustomData_MeshMasks CD_MASK_DERIVEDMESH = {
/* vmask */ (CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | CD_MASK_SHAPEKEY | CD_MASK_MVERT_SKIN |
CD_MASK_PAINT_MASK | CD_MASK_ORCO | CD_MASK_CLOTH_ORCO | CD_MASK_PROP_ALL |
CD_MASK_CREASE | CD_MASK_BWEIGHT),
- /* emask */ (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_BWEIGHT | CD_MASK_PROP_ALL),
+ /* emask */
+ (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_BWEIGHT | CD_MASK_PROP_ALL |
+ CD_MASK_CREASE),
/* fmask */ (CD_MASK_ORIGINDEX | CD_MASK_ORIGSPACE | CD_MASK_PREVIEW_MCOL | CD_MASK_TANGENT),
/* pmask */
- (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL |
- CD_MASK_SCULPT_FACE_SETS),
+ (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL),
/* lmask */
(CD_MASK_MLOOPUV | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_PREVIEW_MLOOPCOL |
CD_MASK_ORIGSPACE_MLOOP | CD_MASK_PROP_ALL), /* XXX MISSING CD_MASK_MLOOPTANGENT ? */
@@ -2152,7 +2152,7 @@ const CustomData_MeshMasks CD_MASK_BMESH = {
/* emask */ (CD_MASK_BWEIGHT | CD_MASK_CREASE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL),
/* fmask */ 0,
/* pmask */
- (CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL | CD_MASK_SCULPT_FACE_SETS),
+ (CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL),
/* lmask */
(CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK |
CD_MASK_PROP_ALL),
@@ -2171,7 +2171,7 @@ const CustomData_MeshMasks CD_MASK_EVERYTHING = {
CD_MASK_PROP_ALL),
/* pmask */
(CD_MASK_MPOLY | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_FACEMAP |
- CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL | CD_MASK_SCULPT_FACE_SETS),
+ CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL),
/* lmask */
(CD_MASK_MLOOP | CD_MASK_BM_ELEM_PYPTR | CD_MASK_MDISPS | CD_MASK_NORMAL | CD_MASK_MLOOPUV |
CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_MLOOPTANGENT | CD_MASK_PREVIEW_MLOOPCOL |
@@ -2373,19 +2373,31 @@ bool CustomData_merge(const CustomData *source,
static bool attribute_stored_in_bmesh_flag(const StringRef name)
{
- return ELEM(name, ".hide_vert", ".hide_edge", ".hide_poly", "material_index");
+ return ELEM(name,
+ ".hide_vert",
+ ".hide_edge",
+ ".hide_poly",
+ ".select_vert",
+ ".select_edge",
+ ".select_poly",
+ "material_index");
}
-static CustomData shallow_copy_remove_non_bmesh_attributes(const CustomData &src)
+CustomData CustomData_shallow_copy_remove_non_bmesh_attributes(const CustomData *src,
+ const eCustomDataMask mask)
{
Vector<CustomDataLayer> dst_layers;
- for (const CustomDataLayer &layer : Span<CustomDataLayer>{src.layers, src.totlayer}) {
- if (!attribute_stored_in_bmesh_flag(layer.name)) {
- dst_layers.append(layer);
+ for (const CustomDataLayer &layer : Span<CustomDataLayer>{src->layers, src->totlayer}) {
+ if (attribute_stored_in_bmesh_flag(layer.name)) {
+ continue;
}
+ if (!(mask & CD_TYPE_AS_MASK(layer.type))) {
+ continue;
+ }
+ dst_layers.append(layer);
}
- CustomData dst = src;
+ CustomData dst = *src;
dst.layers = static_cast<CustomDataLayer *>(
MEM_calloc_arrayN(dst_layers.size(), sizeof(CustomDataLayer), __func__));
dst.totlayer = dst_layers.size();
@@ -2396,18 +2408,6 @@ static CustomData shallow_copy_remove_non_bmesh_attributes(const CustomData &src
return dst;
}
-bool CustomData_merge_mesh_to_bmesh(const CustomData *source,
- CustomData *dest,
- const eCustomDataMask mask,
- const eCDAllocType alloctype,
- const int totelem)
-{
- CustomData source_copy = shallow_copy_remove_non_bmesh_attributes(*source);
- const bool result = CustomData_merge(&source_copy, dest, mask, alloctype, totelem);
- MEM_SAFE_FREE(source_copy.layers);
- return result;
-}
-
void CustomData_realloc(CustomData *data, const int old_size, const int new_size)
{
BLI_assert(new_size >= 0);
@@ -2457,17 +2457,6 @@ void CustomData_copy(const CustomData *source,
CustomData_merge(source, dest, mask, alloctype, totelem);
}
-void CustomData_copy_mesh_to_bmesh(const CustomData *source,
- CustomData *dest,
- const eCustomDataMask mask,
- const eCDAllocType alloctype,
- const int totelem)
-{
- CustomData source_copy = shallow_copy_remove_non_bmesh_attributes(*source);
- CustomData_copy(&source_copy, dest, mask, alloctype, totelem);
- MEM_SAFE_FREE(source_copy.layers);
-}
-
static void customData_free_layer__internal(CustomDataLayer *layer, const int totelem)
{
const LayerTypeInfo *typeInfo;
@@ -2810,10 +2799,6 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
int flag = 0;
- if (!typeInfo->defaultname && CustomData_has_layer(data, type)) {
- return &data->layers[CustomData_get_layer_index(data, type)];
- }
-
void *newlayerdata = nullptr;
switch (alloctype) {
case CD_SET_DEFAULT:
@@ -2866,6 +2851,21 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
break;
}
+ /* Some layer types only support a single layer. */
+ const bool reuse_existing_layer = !typeInfo->defaultname && CustomData_has_layer(data, type);
+ if (reuse_existing_layer) {
+ CustomDataLayer &layer = data->layers[CustomData_get_layer_index(data, type)];
+ if (layer.data != nullptr) {
+ if (typeInfo->free) {
+ typeInfo->free(layer.data, totelem, typeInfo->size);
+ }
+ MEM_SAFE_FREE(layer.data);
+ }
+ layer.data = newlayerdata;
+ layer.flag = flag;
+ return &layer;
+ }
+
int index = data->totlayer;
if (index >= data->maxlayer) {
if (!customData_resize(data, CUSTOMDATA_GROW)) {
@@ -3113,7 +3113,7 @@ static void *customData_duplicate_referenced_layer_index(CustomData *data,
if (typeInfo->copy) {
void *dst_data = MEM_malloc_arrayN(
- (size_t)totelem, typeInfo->size, "CD duplicate ref layer");
+ size_t(totelem), typeInfo->size, "CD duplicate ref layer");
typeInfo->copy(layer->data, dst_data, totelem);
layer->data = dst_data;
}
@@ -3129,7 +3129,6 @@ static void *customData_duplicate_referenced_layer_index(CustomData *data,
void *CustomData_duplicate_referenced_layer(CustomData *data, const int type, const int totelem)
{
- /* get the layer index of the first layer of type */
int layer_index = CustomData_get_active_layer_index(data, type);
return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
@@ -3158,7 +3157,7 @@ void *CustomData_duplicate_referenced_layer_named(CustomData *data,
}
void *CustomData_duplicate_referenced_layer_anonymous(CustomData *data,
- const int UNUSED(type),
+ const int /*type*/,
const AnonymousAttributeID *anonymous_id,
const int totelem)
{
@@ -3181,7 +3180,6 @@ void CustomData_duplicate_referenced_layers(CustomData *data, const int totelem)
bool CustomData_is_referenced_layer(CustomData *data, const int type)
{
- /* get the layer index of the first layer of type */
int layer_index = CustomData_get_active_layer_index(data, type);
if (layer_index == -1) {
return false;
@@ -3244,7 +3242,7 @@ void CustomData_copy_elements(const int type,
typeInfo->copy(src_data_ofs, dst_data_ofs, count);
}
else {
- memcpy(dst_data_ofs, src_data_ofs, (size_t)count * typeInfo->size);
+ memcpy(dst_data_ofs, src_data_ofs, size_t(count) * typeInfo->size);
}
}
@@ -3263,8 +3261,8 @@ void CustomData_copy_data_layer(const CustomData *source,
typeInfo = layerType_getInfo(source->layers[src_layer_index].type);
- const size_t src_offset = (size_t)src_index * typeInfo->size;
- const size_t dst_offset = (size_t)dst_index * typeInfo->size;
+ const size_t src_offset = size_t(src_index) * typeInfo->size;
+ const size_t dst_offset = size_t(dst_index) * typeInfo->size;
if (!count || !src_data || !dst_data) {
if (count && !(src_data == nullptr && dst_data == nullptr)) {
@@ -3284,7 +3282,7 @@ void CustomData_copy_data_layer(const CustomData *source,
else {
memcpy(POINTER_OFFSET(dst_data, dst_offset),
POINTER_OFFSET(src_data, src_offset),
- (size_t)count * typeInfo->size);
+ size_t(count) * typeInfo->size);
}
}
@@ -3373,7 +3371,7 @@ void CustomData_free_elem(CustomData *data, const int index, const int count)
const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type);
if (typeInfo->free) {
- size_t offset = (size_t)index * typeInfo->size;
+ size_t offset = size_t(index) * typeInfo->size;
typeInfo->free(POINTER_OFFSET(data->layers[i].data, offset), count, typeInfo->size);
}
@@ -3409,7 +3407,7 @@ void CustomData_interp(const CustomData *source,
if (weights == nullptr) {
default_weights = (count > SOURCE_BUF_SIZE) ?
static_cast<float *>(
- MEM_mallocN(sizeof(*weights) * (size_t)count, __func__)) :
+ MEM_mallocN(sizeof(*weights) * size_t(count), __func__)) :
default_weights_buf;
copy_vn_fl(default_weights, count, 1.0f / count);
weights = default_weights;
@@ -3440,7 +3438,7 @@ void CustomData_interp(const CustomData *source,
void *src_data = source->layers[src_i].data;
for (int j = 0; j < count; j++) {
- sources[j] = POINTER_OFFSET(src_data, (size_t)src_indices[j] * typeInfo->size);
+ sources[j] = POINTER_OFFSET(src_data, size_t(src_indices[j]) * typeInfo->size);
}
typeInfo->interp(
@@ -3448,7 +3446,7 @@ void CustomData_interp(const CustomData *source,
weights,
sub_weights,
count,
- POINTER_OFFSET(dest->layers[dest_i].data, (size_t)dest_index * typeInfo->size));
+ POINTER_OFFSET(dest->layers[dest_i].data, size_t(dest_index) * typeInfo->size));
/* if there are multiple source & dest layers of the same type,
* we don't want to copy all source layers to the same dest, so
@@ -3472,7 +3470,7 @@ void CustomData_swap_corners(CustomData *data, const int index, const int *corne
const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type);
if (typeInfo->swap) {
- const size_t offset = (size_t)index * typeInfo->size;
+ const size_t offset = size_t(index) * typeInfo->size;
typeInfo->swap(POINTER_OFFSET(data->layers[i].data, offset), corner_indices);
}
@@ -3509,36 +3507,26 @@ void CustomData_swap(CustomData *data, const int index_a, const int index_b)
void *CustomData_get(const CustomData *data, const int index, const int type)
{
BLI_assert(index >= 0);
-
- /* get the layer index of the active layer of type */
- int layer_index = CustomData_get_active_layer_index(data, type);
- if (layer_index == -1) {
+ void *layer_data = CustomData_get_layer(data, type);
+ if (!layer_data) {
return nullptr;
}
-
- /* get the offset of the desired element */
- const size_t offset = (size_t)index * layerType_getInfo(type)->size;
-
- return POINTER_OFFSET(data->layers[layer_index].data, offset);
+ return POINTER_OFFSET(layer_data, size_t(index) * layerType_getInfo(type)->size);
}
void *CustomData_get_n(const CustomData *data, const int type, const int index, const int n)
{
- BLI_assert(index >= 0 && n >= 0);
-
- /* get the layer index of the first layer of type */
- int layer_index = data->typemap[type];
- if (layer_index == -1) {
+ BLI_assert(index >= 0);
+ void *layer_data = CustomData_get_layer_n(data, type, n);
+ if (!layer_data) {
return nullptr;
}
- const size_t offset = (size_t)index * layerType_getInfo(type)->size;
- return POINTER_OFFSET(data->layers[layer_index + n].data, offset);
+ return POINTER_OFFSET(layer_data, size_t(index) * layerType_getInfo(type)->size);
}
void *CustomData_get_layer(const CustomData *data, const int type)
{
- /* get the layer index of the active layer of type */
int layer_index = CustomData_get_active_layer_index(data, type);
if (layer_index == -1) {
return nullptr;
@@ -3549,7 +3537,6 @@ void *CustomData_get_layer(const CustomData *data, const int type)
void *CustomData_get_layer_n(const CustomData *data, const int type, const int n)
{
- /* get the layer index of the active layer of type */
int layer_index = CustomData_get_layer_index_n(data, type, n);
if (layer_index == -1) {
return nullptr;
@@ -3570,7 +3557,6 @@ void *CustomData_get_layer_named(const CustomData *data, const int type, const c
int CustomData_get_offset(const CustomData *data, const int type)
{
- /* get the layer index of the active layer of type */
int layer_index = CustomData_get_active_layer_index(data, type);
if (layer_index == -1) {
return -1;
@@ -3581,7 +3567,6 @@ int CustomData_get_offset(const CustomData *data, const int type)
int CustomData_get_n_offset(const CustomData *data, const int type, const int n)
{
- /* get the layer index of the active layer of type */
int layer_index = CustomData_get_layer_index_n(data, type, n);
if (layer_index == -1) {
return -1;
@@ -3602,7 +3587,6 @@ int CustomData_get_offset_named(const CustomData *data, int type, const char *na
bool CustomData_set_layer_name(CustomData *data, const int type, const int n, const char *name)
{
- /* get the layer index of the first layer of type */
const int layer_index = CustomData_get_layer_index_n(data, type, n);
if ((layer_index == -1) || !name) {
@@ -3621,85 +3605,8 @@ const char *CustomData_get_layer_name(const CustomData *data, const int type, co
return (layer_index == -1) ? nullptr : data->layers[layer_index].name;
}
-void *CustomData_set_layer(const CustomData *data, const int type, void *ptr)
-{
- /* get the layer index of the first layer of type */
- int layer_index = CustomData_get_active_layer_index(data, type);
-
- if (layer_index == -1) {
- return nullptr;
- }
-
- data->layers[layer_index].data = ptr;
-
- return ptr;
-}
-
-void *CustomData_set_layer_n(const CustomData *data, const int type, const int n, void *ptr)
-{
- /* get the layer index of the first layer of type */
- int layer_index = CustomData_get_layer_index_n(data, type, n);
- if (layer_index == -1) {
- return nullptr;
- }
-
- data->layers[layer_index].data = ptr;
-
- return ptr;
-}
-
-void CustomData_set(const CustomData *data, const int index, const int type, const void *source)
-{
- void *dest = CustomData_get(data, index, type);
- const LayerTypeInfo *typeInfo = layerType_getInfo(type);
-
- if (!dest) {
- return;
- }
-
- if (typeInfo->copy) {
- typeInfo->copy(source, dest, 1);
- }
- else {
- memcpy(dest, source, typeInfo->size);
- }
-}
-
/* BMesh functions */
-void CustomData_bmesh_update_active_layers(CustomData *fdata, CustomData *ldata)
-{
- int act;
-
- if (CustomData_has_layer(ldata, CD_MLOOPUV)) {
- act = CustomData_get_active_layer(ldata, CD_MLOOPUV);
- CustomData_set_layer_active(fdata, CD_MTFACE, act);
-
- act = CustomData_get_render_layer(ldata, CD_MLOOPUV);
- CustomData_set_layer_render(fdata, CD_MTFACE, act);
-
- act = CustomData_get_clone_layer(ldata, CD_MLOOPUV);
- CustomData_set_layer_clone(fdata, CD_MTFACE, act);
-
- act = CustomData_get_stencil_layer(ldata, CD_MLOOPUV);
- CustomData_set_layer_stencil(fdata, CD_MTFACE, act);
- }
-
- if (CustomData_has_layer(ldata, CD_PROP_BYTE_COLOR)) {
- act = CustomData_get_active_layer(ldata, CD_PROP_BYTE_COLOR);
- CustomData_set_layer_active(fdata, CD_MCOL, act);
-
- act = CustomData_get_render_layer(ldata, CD_PROP_BYTE_COLOR);
- CustomData_set_layer_render(fdata, CD_MCOL, act);
-
- act = CustomData_get_clone_layer(ldata, CD_PROP_BYTE_COLOR);
- CustomData_set_layer_clone(fdata, CD_MCOL, act);
-
- act = CustomData_get_stencil_layer(ldata, CD_PROP_BYTE_COLOR);
- CustomData_set_layer_stencil(fdata, CD_MCOL, act);
- }
-}
-
void CustomData_bmesh_init_pool(CustomData *data, const int totelem, const char htype)
{
int chunksize;
@@ -3999,7 +3906,6 @@ void CustomData_bmesh_copy_data(const CustomData *source,
void *CustomData_bmesh_get(const CustomData *data, void *block, const int type)
{
- /* get the layer index of the first layer of type */
int layer_index = CustomData_get_active_layer_index(data, type);
if (layer_index == -1) {
return nullptr;
@@ -4010,7 +3916,6 @@ void *CustomData_bmesh_get(const CustomData *data, void *block, const int type)
void *CustomData_bmesh_get_n(const CustomData *data, void *block, const int type, const int n)
{
- /* get the layer index of the first layer of type */
int layer_index = CustomData_get_layer_index(data, type);
if (layer_index == -1) {
return nullptr;
@@ -4214,23 +4119,6 @@ void CustomData_bmesh_set_n(
}
}
-void CustomData_bmesh_set_layer_n(CustomData *data, void *block, const int n, const void *source)
-{
- void *dest = CustomData_bmesh_get_layer_n(data, block, n);
- const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
-
- if (!dest) {
- return;
- }
-
- if (typeInfo->copy) {
- typeInfo->copy(source, dest, 1);
- }
- else {
- memcpy(dest, source, typeInfo->size);
- }
-}
-
void CustomData_bmesh_interp_n(CustomData *data,
const void **src_blocks_ofs,
const float *weights,
@@ -4272,7 +4160,7 @@ void CustomData_bmesh_interp(CustomData *data,
float *default_weights = nullptr;
if (weights == nullptr) {
default_weights = (count > SOURCE_BUF_SIZE) ?
- (float *)MEM_mallocN(sizeof(*weights) * (size_t)count, __func__) :
+ (float *)MEM_mallocN(sizeof(*weights) * size_t(count), __func__) :
default_weights_buf;
copy_vn_fl(default_weights, count, 1.0f / count);
weights = default_weights;
@@ -4335,7 +4223,7 @@ void CustomData_to_bmesh_block(const CustomData *source,
void *dest_data = POINTER_OFFSET(*dest_block, offset);
const LayerTypeInfo *typeInfo = layerType_getInfo(dest->layers[dest_i].type);
- const size_t src_offset = (size_t)src_index * typeInfo->size;
+ const size_t src_offset = size_t(src_index) * typeInfo->size;
if (typeInfo->copy) {
typeInfo->copy(POINTER_OFFSET(src_data, src_offset), dest_data, 1);
@@ -4387,7 +4275,7 @@ void CustomData_from_bmesh_block(const CustomData *source,
int offset = source->layers[src_i].offset;
const void *src_data = POINTER_OFFSET(src_block, offset);
void *dst_data = POINTER_OFFSET(dest->layers[dest_i].data,
- (size_t)dest_index * typeInfo->size);
+ size_t(dest_index) * typeInfo->size);
if (typeInfo->copy) {
typeInfo->copy(src_data, dst_data, 1);
@@ -4653,30 +4541,6 @@ bool CustomData_layer_validate(CustomDataLayer *layer, const uint totitems, cons
return false;
}
-void CustomData_layers__print(CustomData *data)
-{
- printf("{\n");
-
- int i;
- const CustomDataLayer *layer;
- for (i = 0, layer = data->layers; i < data->totlayer; i++, layer++) {
- const char *name = CustomData_layertype_name(layer->type);
- const int size = CustomData_sizeof(layer->type);
- const char *structname;
- int structnum;
- CustomData_file_write_info(layer->type, &structname, &structnum);
- printf(" dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n",
- name,
- structname,
- layer->type,
- (const void *)layer->data,
- size,
- (int)(MEM_allocN_len(layer->data) / size));
- }
-
- printf("}\n");
-}
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -4691,10 +4555,7 @@ static void customdata_external_filename(char filepath[FILE_MAX],
BLI_path_abs(filepath, ID_BLEND_PATH_FROM_GLOBAL(id));
}
-void CustomData_external_reload(CustomData *data,
- ID *UNUSED(id),
- eCustomDataMask mask,
- int totelem)
+void CustomData_external_reload(CustomData *data, ID * /*id*/, eCustomDataMask mask, int totelem)
{
for (int i = 0; i < data->totlayer; i++) {
CustomDataLayer *layer = &data->layers[i];
@@ -4888,11 +4749,8 @@ void CustomData_external_write(
cdf_free(cdf);
}
-void CustomData_external_add(CustomData *data,
- ID *UNUSED(id),
- const int type,
- const int UNUSED(totelem),
- const char *filepath)
+void CustomData_external_add(
+ CustomData *data, ID * /*id*/, const int type, const int /*totelem*/, const char *filepath)
{
CustomDataExternal *external = data->external;
@@ -4992,13 +4850,13 @@ static bool check_bit_flag(const void *data, const size_t data_size, const uint6
{
switch (data_size) {
case 1:
- return ((*((uint8_t *)data) & ((uint8_t)flag)) != 0);
+ return ((*((uint8_t *)data) & uint8_t(flag)) != 0);
case 2:
- return ((*((uint16_t *)data) & ((uint16_t)flag)) != 0);
+ return ((*((uint16_t *)data) & uint16_t(flag)) != 0);
case 4:
- return ((*((uint32_t *)data) & ((uint32_t)flag)) != 0);
+ return ((*((uint32_t *)data) & uint32_t(flag)) != 0);
case 8:
- return ((*((uint64_t *)data) & ((uint64_t)flag)) != 0);
+ return ((*((uint64_t *)data) & uint64_t(flag)) != 0);
default:
// CLOG_ERROR(&LOG, "Unknown flags-container size (%zu)", datasize);
return false;
@@ -5041,7 +4899,7 @@ static void customdata_data_transfer_interp_generic(const CustomDataTransferLaye
else {
const LayerTypeInfo *type_info = layerType_getInfo(data_type);
- data_size = (size_t)type_info->size;
+ data_size = size_t(type_info->size);
interp_cd = type_info->interp;
copy_cd = type_info->copy;
}
@@ -5194,7 +5052,7 @@ void CustomData_data_transfer(const MeshPairRemap *me_remap,
const LayerTypeInfo *type_info = layerType_getInfo(data_type);
/* NOTE: we can use 'fake' CDLayers for crease :/. */
- data_size = (size_t)type_info->size;
+ data_size = size_t(type_info->size);
data_step = laymap->elem_size ? laymap->elem_size : data_size;
data_offset = laymap->data_offset;
}
@@ -5213,13 +5071,13 @@ void CustomData_data_transfer(const MeshPairRemap *me_remap,
if (tmp_data_src) {
if (UNLIKELY(sources_num > tmp_buff_size)) {
- tmp_buff_size = (size_t)sources_num;
+ tmp_buff_size = size_t(sources_num);
tmp_data_src = (const void **)MEM_reallocN((void *)tmp_data_src,
sizeof(*tmp_data_src) * tmp_buff_size);
}
for (int j = 0; j < sources_num; j++) {
- const size_t src_idx = (size_t)mapit->indices_src[j];
+ const size_t src_idx = size_t(mapit->indices_src[j]);
tmp_data_src[j] = POINTER_OFFSET(data_src, (data_step * src_idx) + data_offset);
}
}
@@ -5360,7 +5218,7 @@ static void blend_read_mdisps(BlendDataReader *reader,
* overwritten with the correct value in
* bm_corners_to_loops() */
float gridsize = sqrtf(mdisps[i].totdisp);
- mdisps[i].level = (int)(logf(gridsize - 1.0f) / (float)M_LN2) + 1;
+ mdisps[i].level = int(logf(gridsize - 1.0f) / float(M_LN2)) + 1;
}
if (BLO_read_requires_endian_switch(reader) && (mdisps[i].disps)) {
@@ -5508,6 +5366,8 @@ const blender::CPPType *custom_data_type_to_cpp_type(const eCustomDataType type)
return &CPPType::get<int8_t>();
case CD_PROP_BYTE_COLOR:
return &CPPType::get<ColorGeometry4b>();
+ case CD_PROP_STRING:
+ return &CPPType::get<MStringProperty>();
default:
return nullptr;
}
@@ -5540,9 +5400,19 @@ eCustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type)
if (type.is<ColorGeometry4b>()) {
return CD_PROP_BYTE_COLOR;
}
+ if (type.is<MStringProperty>()) {
+ return CD_PROP_STRING;
+ }
return static_cast<eCustomDataType>(-1);
}
/** \} */
} // namespace blender::bke
+
+size_t CustomData_get_elem_size(CustomDataLayer *layer)
+{
+ return LAYERTYPEINFO[layer->type].size;
+}
+
+BLI_CPP_TYPE_MAKE(MStringProperty, MStringProperty, CPPTypeFlags::None);
diff --git a/source/blender/blenkernel/intern/customdata_file.c b/source/blender/blenkernel/intern/customdata_file.c
index cbfaf2831d1..85e88996c0a 100644
--- a/source/blender/blenkernel/intern/customdata_file.c
+++ b/source/blender/blenkernel/intern/customdata_file.c
@@ -310,7 +310,7 @@ bool cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay)
return (BLI_fseek(cdf->readf, offset, SEEK_SET) == 0);
}
-bool cdf_read_data(CDataFile *cdf, unsigned int size, void *data)
+bool cdf_read_data(CDataFile *cdf, uint size, void *data)
{
/* read data */
if (!fread(data, size, 1, cdf->readf)) {
@@ -384,7 +384,7 @@ bool cdf_write_layer(CDataFile *UNUSED(cdf), CDataFileLayer *UNUSED(blay))
return true;
}
-bool cdf_write_data(CDataFile *cdf, unsigned int size, void *data)
+bool cdf_write_data(CDataFile *cdf, uint size, void *data)
{
/* write data */
if (!fwrite(data, size, 1, cdf->writef)) {
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index 6c7715c625e..e6afca11b40 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -199,7 +199,7 @@ int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type)
case DT_TYPE_SEAM:
return CD_FAKE_SEAM;
case DT_TYPE_CREASE:
- return CD_FAKE_CREASE;
+ return CD_CREASE;
case DT_TYPE_BWEIGHT_EDGE:
return CD_BWEIGHT;
case DT_TYPE_FREESTYLE_EDGE:
@@ -374,8 +374,8 @@ float data_transfer_interp_float_do(const int mix_mode,
{
float val_ret;
- if (((mix_mode == CDT_MIX_REPLACE_ABOVE_THRESHOLD && (val_dst < mix_factor)) ||
- (mix_mode == CDT_MIX_REPLACE_BELOW_THRESHOLD && (val_dst > mix_factor)))) {
+ if ((mix_mode == CDT_MIX_REPLACE_ABOVE_THRESHOLD && (val_dst < mix_factor)) ||
+ (mix_mode == CDT_MIX_REPLACE_BELOW_THRESHOLD && (val_dst > mix_factor))) {
return val_dst; /* Do not affect destination. */
}
@@ -403,31 +403,6 @@ float data_transfer_interp_float_do(const int mix_mode,
return interpf(val_ret, val_dst, mix_factor);
}
-static void data_transfer_interp_char(const CustomDataTransferLayerMap *laymap,
- void *dest,
- const void **sources,
- const float *weights,
- const int count,
- const float mix_factor)
-{
- const char **data_src = (const char **)sources;
- char *data_dst = (char *)dest;
-
- const int mix_mode = laymap->mix_mode;
- float val_src = 0.0f;
- const float val_dst = (float)(*data_dst) / 255.0f;
-
- for (int i = count; i--;) {
- val_src += ((float)(*data_src[i]) / 255.0f) * weights[i];
- }
-
- val_src = data_transfer_interp_float_do(mix_mode, val_dst, val_src, mix_factor);
-
- CLAMP(val_src, 0.0f, 1.0f);
-
- *data_dst = (char)(val_src * 255.0f);
-}
-
/* Helpers to match sources and destinations data layers
* (also handles 'conversions' in CD_FAKE cases). */
@@ -981,39 +956,6 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
}
return true;
}
- if (cddata_type == CD_FAKE_CREASE) {
- const size_t elem_size = sizeof(*((MEdge *)NULL));
- const size_t data_size = sizeof(((MEdge *)NULL)->crease);
- const size_t data_offset = offsetof(MEdge, crease);
- const uint64_t data_flag = 0;
-
- if (!(me_src->cd_flag & ME_CDFLAG_EDGE_CREASE)) {
- if (use_delete) {
- me_dst->cd_flag &= ~ME_CDFLAG_EDGE_CREASE;
- }
- return true;
- }
- me_dst->cd_flag |= ME_CDFLAG_EDGE_CREASE;
- if (r_map) {
- data_transfer_layersmapping_add_item(r_map,
- cddata_type,
- mix_mode,
- mix_factor,
- mix_weights,
- BKE_mesh_edges(me_src),
- BKE_mesh_edges_for_write(me_dst),
- me_src->totedge,
- me_dst->totedge,
- elem_size,
- data_size,
- data_offset,
- data_flag,
- data_transfer_interp_char,
- interp_data);
- }
- return true;
- }
-
if (r_map && ELEM(cddata_type, CD_FAKE_SHARP, CD_FAKE_SEAM)) {
const size_t elem_size = sizeof(*((MEdge *)NULL));
const size_t data_size = sizeof(((MEdge *)NULL)->flag);
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 7940d65b1bb..b5c3147b0f1 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -271,7 +271,7 @@ void BKE_defvert_normalize(MDeformVert *dvert)
}
else {
MDeformWeight *dw;
- unsigned int i;
+ uint i;
float tot_weight = 0.0f;
for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
@@ -309,7 +309,7 @@ void BKE_defvert_normalize_lock_single(MDeformVert *dvert,
else {
MDeformWeight *dw_lock = NULL;
MDeformWeight *dw;
- unsigned int i;
+ uint i;
float tot_weight = 0.0f;
float lock_iweight = 1.0f;
@@ -363,7 +363,7 @@ void BKE_defvert_normalize_lock_map(MDeformVert *dvert,
}
else {
MDeformWeight *dw;
- unsigned int i;
+ uint i;
float tot_weight = 0.0f;
float lock_iweight = 0.0f;
@@ -752,7 +752,7 @@ MDeformWeight *BKE_defvert_find_index(const MDeformVert *dvert, const int defgro
{
if (dvert && defgroup >= 0) {
MDeformWeight *dw = dvert->dw;
- unsigned int i;
+ uint i;
for (i = dvert->totweight; i != 0; i--, dw++) {
if (dw->def_nr == defgroup) {
@@ -865,7 +865,7 @@ int BKE_defvert_find_shared(const MDeformVert *dvert_a, const MDeformVert *dvert
{
if (dvert_a->totweight && dvert_b->totweight) {
MDeformWeight *dw = dvert_a->dw;
- unsigned int i;
+ uint i;
for (i = dvert_a->totweight; i != 0; i--, dw++) {
if (dw->weight > 0.0f && BKE_defvert_find_weight(dvert_b, dw->def_nr) > 0.0f) {
diff --git a/source/blender/blenkernel/intern/displist.cc b/source/blender/blenkernel/intern/displist.cc
index b87d675496c..2e285170b93 100644
--- a/source/blender/blenkernel/intern/displist.cc
+++ b/source/blender/blenkernel/intern/displist.cc
@@ -503,7 +503,7 @@ static float displist_calc_taper(Depsgraph *depsgraph,
float BKE_displist_calc_taper(
Depsgraph *depsgraph, const Scene *scene, Object *taperobj, int cur, int tot)
{
- const float fac = ((float)cur) / (float)(tot - 1);
+ const float fac = float(cur) / float(tot - 1);
return displist_calc_taper(depsgraph, scene, taperobj, fac);
}
@@ -518,7 +518,7 @@ static ModifierData *curve_get_tessellate_point(const Scene *scene,
ModifierMode required_mode = for_render ? eModifierMode_Render : eModifierMode_Realtime;
if (editmode) {
- required_mode = (ModifierMode)((int)required_mode | eModifierMode_Editmode);
+ required_mode = (ModifierMode)(int(required_mode) | eModifierMode_Editmode);
}
ModifierData *pretessellatePoint = nullptr;
@@ -532,6 +532,12 @@ static ModifierData *curve_get_tessellate_point(const Scene *scene,
return pretessellatePoint;
}
+ if (md->type == eModifierType_Smooth) {
+ /* Smooth modifier works with mesh edges explicitly
+ * (so needs tessellation, thus cannot work on control points). */
+ md->mode &= ~eModifierMode_ApplyOnSpline;
+ return pretessellatePoint;
+ }
if (ELEM(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
pretessellatePoint = md;
@@ -562,7 +568,7 @@ void BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
ModifierMode required_mode = for_render ? eModifierMode_Render : eModifierMode_Realtime;
if (editmode) {
- required_mode = (ModifierMode)((int)required_mode | eModifierMode_Editmode);
+ required_mode = (ModifierMode)(int(required_mode) | eModifierMode_Editmode);
}
ModifierApplyFlag apply_flag = (ModifierApplyFlag)0;
@@ -634,7 +640,7 @@ void BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
/**
* \return True if the deformed curve control point data should be implicitly
- * converted directly to a mesh, or false if it can be left as curve data via #CurveEval.
+ * converted directly to a mesh, or false if it can be left as curve data via the #Curves type.
*/
static bool do_curve_implicit_mesh_conversion(const Curve *curve,
ModifierData *first_modifier,
@@ -689,7 +695,7 @@ static GeometrySet curve_calc_modifiers_post(Depsgraph *depsgraph,
ModifierApplyFlag apply_flag = for_render ? MOD_APPLY_RENDER : (ModifierApplyFlag)0;
ModifierMode required_mode = for_render ? eModifierMode_Render : eModifierMode_Realtime;
if (editmode) {
- required_mode = (ModifierMode)((int)required_mode | eModifierMode_Editmode);
+ required_mode = (ModifierMode)(int(required_mode) | eModifierMode_Editmode);
}
const ModifierEvalContext mectx_deform = {
@@ -970,13 +976,13 @@ static void calc_bevfac_segment_mapping(
int bevcount = 0, nr = bl->nr;
float bev_fl = bevfac * (bl->nr - 1);
- *r_bev = (int)bev_fl;
+ *r_bev = int(bev_fl);
while (bevcount < nr - 1) {
float normlen = *seglen / spline_length;
if (normsum + normlen > bevfac) {
bev_fl = bevcount + (bevfac - normsum) / normlen * *segbevcount;
- *r_bev = (int)bev_fl;
+ *r_bev = int(bev_fl);
*r_blend = bev_fl - *r_bev;
break;
}
@@ -1046,7 +1052,7 @@ static void calc_bevfac_mapping(const Curve *cu,
switch (cu->bevfac1_mapping) {
case CU_BEVFAC_MAP_RESOLU: {
const float start_fl = cu->bevfac1 * (bl->nr - 1);
- *r_start = (int)start_fl;
+ *r_start = int(start_fl);
*r_firstblend = 1.0f - (start_fl - (*r_start));
break;
}
@@ -1065,7 +1071,7 @@ static void calc_bevfac_mapping(const Curve *cu,
switch (cu->bevfac2_mapping) {
case CU_BEVFAC_MAP_RESOLU: {
const float end_fl = cu->bevfac2 * (bl->nr - 1);
- end = (int)end_fl;
+ end = int(end_fl);
*r_steps = 2 + end - *r_start;
*r_lastblend = end_fl - end;
@@ -1238,12 +1244,12 @@ static GeometrySet evaluate_curve_type_object(Depsgraph *depsgraph,
taper_factor = 1.0f;
}
else {
- taper_factor = ((float)a - (1.0f - first_blend)) / len;
+ taper_factor = (float(a) - (1.0f - first_blend)) / len;
}
}
else {
float len = bl->nr - 1;
- taper_factor = (float)i / len;
+ taper_factor = float(i) / len;
if (a == 0) {
taper_factor += (1.0f - first_blend) / len;
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 9d46c381d7a..e0ae3f42be6 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -121,7 +121,7 @@ BLI_INLINE void value_dissolve(float *r_value,
const float scale,
const bool is_log)
{
- *r_value = (is_log) ? (*r_value) * (powf(MIN_WETNESS, 1.0f / (1.2f * time / scale))) :
+ *r_value = (is_log) ? (*r_value) * powf(MIN_WETNESS, 1.0f / (1.2f * time / scale)) :
(*r_value) - 1.0f / time * scale;
}
@@ -212,13 +212,13 @@ typedef struct PaintBakeData {
typedef struct PaintUVPoint {
/* Pixel / mesh data */
/** tri index on domain derived mesh */
- unsigned int tri_index;
- unsigned int pixel_index;
+ uint tri_index;
+ uint pixel_index;
/* vertex indexes */
- unsigned int v1, v2, v3;
+ uint v1, v2, v3;
/** If this pixel isn't uv mapped to any face, but its neighboring pixel is. */
- unsigned int neighbor_pixel;
+ uint neighbor_pixel;
} PaintUVPoint;
typedef struct ImgSeqFormatData {
@@ -514,7 +514,7 @@ static void scene_setSubframe(Scene *scene, float subframe)
static int surface_getBrushFlags(DynamicPaintSurface *surface, Depsgraph *depsgraph)
{
- unsigned int numobjects;
+ uint numobjects;
Object **objects = BKE_collision_objects_create(
depsgraph, NULL, surface->brush_group, &numobjects, eModifierType_DynamicPaint);
@@ -1496,7 +1496,7 @@ static void dynamic_paint_set_init_color_tex_to_vcol_cb(
for (int j = 3; j--;) {
TexResult texres = {0};
- const unsigned int vert = mloop[mlooptri[i].tri[j]].v;
+ const uint vert = mloop[mlooptri[i].tri[j]].v;
/* remap to [-1.0, 1.0] */
uv[0] = mloopuv[mlooptri[i].tri[j]].uv[0] * 2.0f - 1.0f;
@@ -1569,7 +1569,7 @@ static void dynamic_paint_set_init_color_vcol_to_imseq_cb(
/* collect color values */
for (int j = 3; j--;) {
- rgba_uchar_to_float(colors[j], (const unsigned char *)&mloopcol[mlooptri[tri_idx].tri[j]].r);
+ rgba_uchar_to_float(colors[j], (const uchar *)&mloopcol[mlooptri[tri_idx].tri[j]].r);
}
/* interpolate final color */
@@ -1669,7 +1669,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
}
for (int i = 0; i < totloop; i++) {
- rgba_uchar_to_float(pPoint[mloop[i].v].color, (const unsigned char *)&col[i].r);
+ rgba_uchar_to_float(pPoint[mloop[i].v].color, (const uchar *)&col[i].r);
}
}
else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
@@ -1698,7 +1698,7 @@ void dynamicPaint_clearSurface(const Scene *scene, DynamicPaintSurface *surface)
{
PaintSurfaceData *sData = surface->data;
if (sData && sData->type_data) {
- unsigned int data_size;
+ uint data_size;
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
data_size = sizeof(PaintPoint);
@@ -1762,7 +1762,7 @@ bool dynamicPaint_resetSurface(const Scene *scene, DynamicPaintSurface *surface)
static bool dynamicPaint_checkSurfaceData(const Scene *scene, DynamicPaintSurface *surface)
{
if (!surface->data ||
- ((dynamicPaint_surfaceNumOfPoints(surface) != surface->data->total_points))) {
+ (dynamicPaint_surfaceNumOfPoints(surface) != surface->data->total_points)) {
return dynamicPaint_resetSurface(scene, surface);
}
return true;
@@ -1862,7 +1862,7 @@ static void dynamic_paint_apply_surface_vpaint_cb(void *__restrict userdata,
/* save layer data to output layer */
/* apply color */
if (mloopcol) {
- rgba_float_to_uchar((unsigned char *)&mloopcol[l_index].r, fcolor[v_index]);
+ rgba_float_to_uchar((uchar *)&mloopcol[l_index].r, fcolor[v_index]);
}
/* apply wetness */
if (mloopcol_wet) {
@@ -2512,7 +2512,7 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa
const MLoopTri *mlooptri = data->mlooptri;
const MLoopUV *mloopuv = data->mloopuv;
- const unsigned int *loop_idx = mlooptri[tri_index].tri;
+ const uint *loop_idx = mlooptri[tri_index].tri;
/* Enumerate all edges of the triangle, rotating the vertex list accordingly. */
for (int edge_idx = 0; edge_idx < 3; edge_idx++) {
@@ -2566,7 +2566,7 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa
continue;
}
- const unsigned int *other_loop_idx = mlooptri[lt_index].tri;
+ const uint *other_loop_idx = mlooptri[lt_index].tri;
/* Check edges for match, looping in the same order as the outer loop. */
for (int j = 0; j < 3; j++) {
@@ -2790,7 +2790,7 @@ static bool dynamicPaint_symmetrizeAdjData(PaintAdjData *ed, int active_points)
int dynamicPaint_createUVSurface(Scene *scene,
DynamicPaintSurface *surface,
float *progress,
- short *do_update)
+ bool *do_update)
{
/* Antialias jitter point relative coords */
const int aa_samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1;
@@ -3783,7 +3783,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph,
numOfVerts_p = mesh_p->totvert;
mvert_p = BKE_mesh_verts_for_write(mesh_p);
- copy_m4_m4(prev_obmat, ob->obmat);
+ copy_m4_m4(prev_obmat, ob->object_to_world);
/* current frame mesh */
scene->r.cfra = cur_fra;
@@ -3816,7 +3816,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph,
.brush_vel = *brushVel,
.mvert_p = mvert_p,
.mvert_c = mvert_c,
- .obmat = ob->obmat,
+ .obmat = ob->object_to_world,
.prev_obmat = prev_obmat,
.timescale = timescale,
};
@@ -3856,7 +3856,7 @@ static void dynamicPaint_brushObjectCalculateVelocity(
SUBFRAME_RECURSION,
BKE_scene_ctime_get(scene),
eModifierType_DynamicPaint);
- copy_m4_m4(prev_obmat, ob->obmat);
+ copy_m4_m4(prev_obmat, ob->object_to_world);
/* current frame mesh */
scene->r.cfra = cur_fra;
@@ -3871,7 +3871,7 @@ static void dynamicPaint_brushObjectCalculateVelocity(
/* calculate speed */
mul_m4_v3(prev_obmat, prev_loc);
- mul_m4_v3(ob->obmat, cur_loc);
+ mul_m4_v3(ob->object_to_world, cur_loc);
sub_v3_v3v3(brushVel->v, cur_loc, prev_loc);
mul_v3_fl(brushVel->v, 1.0f / timescale);
@@ -4279,14 +4279,14 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph,
* (Faster than transforming per surface point
* coordinates and normals to object space) */
for (ii = 0; ii < numOfVerts; ii++) {
- mul_m4_v3(brushOb->obmat, mvert[ii].co);
+ mul_m4_v3(brushOb->object_to_world, mvert[ii].co);
boundInsert(&mesh_bb, mvert[ii].co);
/* for proximity project calculate average normal */
if (brush->flags & MOD_DPAINT_PROX_PROJECT && brush->collision != MOD_DPAINT_COL_VOLUME) {
float nor[3];
copy_v3_v3(nor, vert_normals[ii]);
- mul_mat3_m4_v3(brushOb->obmat, nor);
+ mul_mat3_m4_v3(brushOb->object_to_world, nor);
normalize_v3(nor);
add_v3_v3(avg_brushNor, nor);
@@ -5339,12 +5339,12 @@ static void dynamic_paint_effect_drip_cb(void *__restrict userdata,
float dir_factor, a_factor;
const float speed_scale = eff_scale * force[index * 4 + 3] / bNeighs[n_idx].dist;
- const unsigned int n_trgt = (unsigned int)n_target[n_idx];
+ const uint n_trgt = (uint)n_target[n_idx];
/* Sort of spinlock, but only for given ePoint.
* Since the odds a same ePoint is modified at the same time by several threads is very low,
* this is much more efficient than a global spin lock. */
- const unsigned int epointlock_idx = n_trgt / 8;
+ const uint epointlock_idx = n_trgt / 8;
const uint8_t epointlock_bitmask = 1 << (n_trgt & 7); /* 7 == 0b111 */
while (atomic_fetch_and_or_uint8(&point_locks[epointlock_idx], epointlock_bitmask) &
epointlock_bitmask) {
@@ -5391,7 +5391,7 @@ static void dynamic_paint_effect_drip_cb(void *__restrict userdata,
}
{
- const unsigned int ppointlock_idx = index / 8;
+ const uint ppointlock_idx = index / 8;
const uint8_t ppointlock_bitmask = 1 << (index & 7); /* 7 == 0b111 */
while (atomic_fetch_and_or_uint8(&point_locks[ppointlock_idx], ppointlock_bitmask) &
ppointlock_bitmask) {
@@ -5870,7 +5870,7 @@ static bool dynamicPaint_surfaceHasMoved(DynamicPaintSurface *surface, Object *o
}
/* matrix comparison */
- if (!equals_m4m4(bData->prev_obmat, ob->obmat)) {
+ if (!equals_m4m4(bData->prev_obmat, ob->object_to_world)) {
return true;
}
@@ -5957,7 +5957,7 @@ static void dynamic_paint_generate_bake_data_cb(void *__restrict userdata,
mul_v3_v3v3(scaled_nor, temp_nor, ob->scale);
bData->bNormal[index].normal_scale = len_v3(scaled_nor);
}
- mul_mat3_m4_v3(ob->obmat, temp_nor);
+ mul_mat3_m4_v3(ob->object_to_world, temp_nor);
normalize_v3(temp_nor);
negate_v3_v3(bData->bNormal[index].invNorm, temp_nor);
}
@@ -5995,7 +5995,7 @@ static void dynamic_paint_generate_bake_data_cb(void *__restrict userdata,
mul_v3_v3v3(scaled_nor, temp_nor, ob->scale);
bData->bNormal[index].normal_scale = len_v3(scaled_nor);
}
- mul_mat3_m4_v3(ob->obmat, temp_nor);
+ mul_mat3_m4_v3(ob->object_to_world, temp_nor);
normalize_v3(temp_nor);
negate_v3_v3(bData->bNormal[index].invNorm, temp_nor);
}
@@ -6063,10 +6063,8 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface,
/* Init bdata */
bData->bNormal = (struct PaintBakeNormal *)MEM_mallocN(
sData->total_points * sizeof(struct PaintBakeNormal), "Dynamic Paint step data");
- bData->s_pos = MEM_mallocN(sData->total_points * sizeof(unsigned int),
- "Dynamic Paint bData s_pos");
- bData->s_num = MEM_mallocN(sData->total_points * sizeof(unsigned int),
- "Dynamic Paint bData s_num");
+ bData->s_pos = MEM_mallocN(sData->total_points * sizeof(uint), "Dynamic Paint bData s_pos");
+ bData->s_num = MEM_mallocN(sData->total_points * sizeof(uint), "Dynamic Paint bData s_num");
bData->realCoord = (struct Vec3f *)MEM_mallocN(surface_totalSamples(surface) * sizeof(Vec3f),
"Dynamic Paint point coords");
bData->prev_verts = MEM_mallocN(canvasNumOfVerts * sizeof(MVert),
@@ -6115,7 +6113,7 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface,
bData->mesh_bounds.valid = false;
for (index = 0; index < canvasNumOfVerts; index++) {
copy_v3_v3(canvas_verts[index].v, mvert[index].co);
- mul_m4_v3(ob->obmat, canvas_verts[index].v);
+ mul_m4_v3(ob->object_to_world, canvas_verts[index].v);
boundInsert(&bData->mesh_bounds, canvas_verts[index].v);
}
@@ -6145,7 +6143,7 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface,
dynamicPaint_prepareAdjacencyData(surface, false);
/* Copy current frame vertices to check against in next frame */
- copy_m4_m4(bData->prev_obmat, ob->obmat);
+ copy_m4_m4(bData->prev_obmat, ob->object_to_world);
memcpy(bData->prev_verts, mvert, canvasNumOfVerts * sizeof(MVert));
bData->clear = 0;
@@ -6189,7 +6187,7 @@ static int dynamicPaint_doStep(Depsgraph *depsgraph,
* Loop through surface's target paint objects and do painting
*/
{
- unsigned int numobjects;
+ uint numobjects;
Object **objects = BKE_collision_objects_create(
depsgraph, NULL, surface->brush_group, &numobjects, eModifierType_DynamicPaint);
diff --git a/source/blender/blenkernel/intern/editmesh.c b/source/blender/blenkernel/intern/editmesh.cc
index a952da6fa52..b586b4110f2 100644
--- a/source/blender/blenkernel/intern/editmesh.c
+++ b/source/blender/blenkernel/intern/editmesh.cc
@@ -28,14 +28,14 @@
BMEditMesh *BKE_editmesh_create(BMesh *bm)
{
- BMEditMesh *em = MEM_callocN(sizeof(BMEditMesh), __func__);
+ BMEditMesh *em = MEM_cnew<BMEditMesh>(__func__);
em->bm = bm;
return em;
}
BMEditMesh *BKE_editmesh_copy(BMEditMesh *em)
{
- BMEditMesh *em_copy = MEM_callocN(sizeof(BMEditMesh), __func__);
+ BMEditMesh *em_copy = MEM_cnew<BMEditMesh>(__func__);
*em_copy = *em;
em_copy->bm = BM_mesh_copy(em->bm);
@@ -46,7 +46,7 @@ BMEditMesh *BKE_editmesh_copy(BMEditMesh *em)
* it in the case of errors in an operation. For performance reasons,
* in that case it makes more sense to do the
* tessellation only when/if that copy ends up getting used. */
- em_copy->looptris = NULL;
+ em_copy->looptris = nullptr;
/* Copy various settings. */
em_copy->selectmode = em->selectmode;
@@ -59,7 +59,7 @@ BMEditMesh *BKE_editmesh_from_object(Object *ob)
{
BLI_assert(ob->type == OB_MESH);
/* sanity check */
-#if 0 /* disable in mutlti-object edit. */
+#if 0 /* disable in multi-object edit. */
# ifndef NDEBUG
if (((Mesh *)ob->data)->edit_mesh) {
BLI_assert(((Mesh *)ob->data)->edit_mesh->ob == ob);
@@ -70,7 +70,7 @@ BMEditMesh *BKE_editmesh_from_object(Object *ob)
}
static void editmesh_tessface_calc_intern(BMEditMesh *em,
- const struct BMeshCalcTessellation_Params *params)
+ const BMeshCalcTessellation_Params *params)
{
/* allocating space before calculating the tessellation */
@@ -85,9 +85,9 @@ static void editmesh_tessface_calc_intern(BMEditMesh *em,
BMLoop *(*looptris)[3];
- /* this means no reallocs for quad dominant models, for */
- if ((em->looptris != NULL) &&
- /* (*em->tottri >= looptris_tot)) */
+ /* This means no reallocations for quad dominant models. */
+ if ((em->looptris != nullptr) &&
+ // (*em->tottri >= looptris_tot))
/* Check against allocated size in case we over allocated a little. */
((looptris_tot_prev_alloc >= looptris_tot) &&
(looptris_tot_prev_alloc <= looptris_tot * 2))) {
@@ -97,7 +97,8 @@ static void editmesh_tessface_calc_intern(BMEditMesh *em,
if (em->looptris) {
MEM_freeN(em->looptris);
}
- looptris = MEM_mallocN(sizeof(*looptris) * looptris_tot, __func__);
+ looptris = static_cast<BMLoop *(*)[3]>(
+ MEM_mallocN(sizeof(*looptris) * looptris_tot, __func__));
}
em->looptris = looptris;
@@ -107,8 +108,7 @@ static void editmesh_tessface_calc_intern(BMEditMesh *em,
BM_mesh_calc_tessellation_ex(em->bm, em->looptris, params);
}
-void BKE_editmesh_looptri_calc_ex(BMEditMesh *em,
- const struct BMeshCalcTessellation_Params *params)
+void BKE_editmesh_looptri_calc_ex(BMEditMesh *em, const BMeshCalcTessellation_Params *params)
{
editmesh_tessface_calc_intern(em, params);
@@ -126,56 +126,46 @@ void BKE_editmesh_looptri_calc_ex(BMEditMesh *em,
void BKE_editmesh_looptri_calc(BMEditMesh *em)
{
- BKE_editmesh_looptri_calc_ex(em,
- &(const struct BMeshCalcTessellation_Params){
- .face_normals = false,
- });
+ BMeshCalcTessellation_Params params{};
+ params.face_normals = false;
+ BKE_editmesh_looptri_calc_ex(em, &params);
}
void BKE_editmesh_looptri_and_normals_calc(BMEditMesh *em)
{
- BKE_editmesh_looptri_calc_ex(em,
- &(const struct BMeshCalcTessellation_Params){
- .face_normals = true,
- });
- BM_mesh_normals_update_ex(em->bm,
- &(const struct BMeshNormalsUpdate_Params){
- .face_normals = false,
- });
+ BMeshCalcTessellation_Params looptri_params{};
+ looptri_params.face_normals = true;
+ BKE_editmesh_looptri_calc_ex(em, &looptri_params);
+ BMeshNormalsUpdate_Params normals_params{};
+ normals_params.face_normals = false;
+ BM_mesh_normals_update_ex(em->bm, &normals_params);
}
void BKE_editmesh_looptri_calc_with_partial_ex(BMEditMesh *em,
- struct BMPartialUpdate *bmpinfo,
- const struct BMeshCalcTessellation_Params *params)
+ BMPartialUpdate *bmpinfo,
+ const BMeshCalcTessellation_Params *params)
{
BLI_assert(em->tottri == poly_to_tri_count(em->bm->totface, em->bm->totloop));
- BLI_assert(em->looptris != NULL);
+ BLI_assert(em->looptris != nullptr);
BM_mesh_calc_tessellation_with_partial_ex(em->bm, em->looptris, bmpinfo, params);
}
-void BKE_editmesh_looptri_calc_with_partial(BMEditMesh *em, struct BMPartialUpdate *bmpinfo)
+void BKE_editmesh_looptri_calc_with_partial(BMEditMesh *em, BMPartialUpdate *bmpinfo)
{
- BKE_editmesh_looptri_calc_with_partial_ex(em,
- bmpinfo,
- &(const struct BMeshCalcTessellation_Params){
- .face_normals = false,
- });
+ BMeshCalcTessellation_Params looptri_params{};
+ looptri_params.face_normals = false;
+ BKE_editmesh_looptri_calc_with_partial_ex(em, bmpinfo, &looptri_params);
}
-void BKE_editmesh_looptri_and_normals_calc_with_partial(BMEditMesh *em,
- struct BMPartialUpdate *bmpinfo)
+void BKE_editmesh_looptri_and_normals_calc_with_partial(BMEditMesh *em, BMPartialUpdate *bmpinfo)
{
- BKE_editmesh_looptri_calc_with_partial_ex(em,
- bmpinfo,
- &(const struct BMeshCalcTessellation_Params){
- .face_normals = true,
- });
- BM_mesh_normals_update_with_partial_ex(em->bm,
- bmpinfo,
- &(const struct BMeshNormalsUpdate_Params){
- .face_normals = false,
- });
+ BMeshCalcTessellation_Params looptri_params{};
+ looptri_params.face_normals = true;
+ BKE_editmesh_looptri_calc_with_partial_ex(em, bmpinfo, &looptri_params);
+ BMeshNormalsUpdate_Params normals_params{};
+ normals_params.face_normals = false;
+ BM_mesh_normals_update_with_partial_ex(em->bm, bmpinfo, &normals_params);
}
void BKE_editmesh_free_data(BMEditMesh *em)
@@ -199,30 +189,28 @@ struct CageUserData {
static void cage_mapped_verts_callback(void *userData,
int index,
const float co[3],
- const float UNUSED(no[3]))
+ const float /*no*/[3])
{
- struct CageUserData *data = userData;
+ CageUserData *data = static_cast<CageUserData *>(userData);
- if ((index >= 0 && index < data->totvert) && (!BLI_BITMAP_TEST(data->visit_bitmap, index))) {
+ if ((index >= 0 && index < data->totvert) && !BLI_BITMAP_TEST(data->visit_bitmap, index)) {
BLI_BITMAP_ENABLE(data->visit_bitmap, index);
copy_v3_v3(data->cos_cage[index], co);
}
}
-float (*BKE_editmesh_vert_coords_alloc(struct Depsgraph *depsgraph,
- BMEditMesh *em,
- struct Scene *scene,
- Object *ob,
- int *r_vert_len))[3]
+float (*BKE_editmesh_vert_coords_alloc(
+ Depsgraph *depsgraph, BMEditMesh *em, Scene *scene, Object *ob, int *r_vert_len))[3]
{
Mesh *cage = editbmesh_get_eval_cage(depsgraph, scene, ob, em, &CD_MASK_BAREMESH);
- float(*cos_cage)[3] = MEM_callocN(sizeof(*cos_cage) * em->bm->totvert, "bmbvh cos_cage");
+ float(*cos_cage)[3] = static_cast<float(*)[3]>(
+ MEM_callocN(sizeof(*cos_cage) * em->bm->totvert, __func__));
/* When initializing cage verts, we only want the first cage coordinate for each vertex,
* so that e.g. mirror or array use original vertex coordinates and not mirrored or duplicate. */
BLI_bitmap *visit_bitmap = BLI_BITMAP_NEW(em->bm->totvert, __func__);
- struct CageUserData data;
+ CageUserData data;
data.totvert = em->bm->totvert;
data.cos_cage = cos_cage;
data.visit_bitmap = visit_bitmap;
@@ -238,27 +226,27 @@ float (*BKE_editmesh_vert_coords_alloc(struct Depsgraph *depsgraph,
return cos_cage;
}
-const float (*BKE_editmesh_vert_coords_when_deformed(struct Depsgraph *depsgraph,
+const float (*BKE_editmesh_vert_coords_when_deformed(Depsgraph *depsgraph,
BMEditMesh *em,
- struct Scene *scene,
+ Scene *scene,
Object *ob,
int *r_vert_len,
bool *r_is_alloc))[3]
{
- const float(*coords)[3] = NULL;
+ const float(*coords)[3] = nullptr;
*r_is_alloc = false;
- Mesh *me = ob->data;
+ Mesh *me = static_cast<Mesh *>(ob->data);
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object_eval);
- if ((me->runtime.edit_data != NULL) && (me->runtime.edit_data->vertexCos != NULL)) {
+ if ((me->runtime->edit_data != nullptr) && (me->runtime->edit_data->vertexCos != nullptr)) {
/* Deformed, and we have deformed coords already. */
- coords = me->runtime.edit_data->vertexCos;
+ coords = me->runtime->edit_data->vertexCos;
}
- else if ((editmesh_eval_final != NULL) &&
- (editmesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH)) {
- /* If this is an edit-mesh type, leave NULL as we can use the vertex coords. */
+ else if ((editmesh_eval_final != nullptr) &&
+ (editmesh_eval_final->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH)) {
+ /* If this is an edit-mesh type, leave nullptr as we can use the vertex coords. */
}
else {
/* Constructive modifiers have been used, we need to allocate coordinates. */
@@ -302,16 +290,16 @@ void BKE_editmesh_ensure_autosmooth(BMEditMesh *em, Mesh *me)
}
}
-BoundBox *BKE_editmesh_cage_boundbox_get(struct Object *object, BMEditMesh *UNUSED(em))
+BoundBox *BKE_editmesh_cage_boundbox_get(Object *object, BMEditMesh * /*em*/)
{
- if (object->runtime.editmesh_bb_cage == NULL) {
+ if (object->runtime.editmesh_bb_cage == nullptr) {
float min[3], max[3];
INIT_MINMAX(min, max);
if (object->runtime.editmesh_eval_cage) {
BKE_mesh_wrapper_minmax(object->runtime.editmesh_eval_cage, min, max);
}
- object->runtime.editmesh_bb_cage = MEM_callocN(sizeof(BoundBox), "BMEditMesh.bb_cage");
+ object->runtime.editmesh_bb_cage = MEM_cnew<BoundBox>("BMEditMesh.bb_cage");
BKE_boundbox_init_from_minmax(object->runtime.editmesh_bb_cage, min, max);
}
diff --git a/source/blender/blenkernel/intern/editmesh_bvh.c b/source/blender/blenkernel/intern/editmesh_bvh.c
index edf3539681c..5e58a049135 100644
--- a/source/blender/blenkernel/intern/editmesh_bvh.c
+++ b/source/blender/blenkernel/intern/editmesh_bvh.c
@@ -551,7 +551,7 @@ static bool bmbvh_overlap_cb(void *userdata, int index_a, int index_b, int UNUSE
BVHTreeOverlap *BKE_bmbvh_overlap(const BMBVHTree *bmtree_a,
const BMBVHTree *bmtree_b,
- unsigned int *r_overlap_tot)
+ uint *r_overlap_tot)
{
struct BMBVHTree_OverlapData data;
@@ -572,7 +572,7 @@ static bool bmbvh_overlap_self_cb(void *userdata, int index_a, int index_b, int
return false;
}
-BVHTreeOverlap *BKE_bmbvh_overlap_self(const BMBVHTree *bmtree, unsigned int *r_overlap_tot)
+BVHTreeOverlap *BKE_bmbvh_overlap_self(const BMBVHTree *bmtree, uint *r_overlap_tot)
{
struct BMBVHTree_OverlapData data;
diff --git a/source/blender/blenkernel/intern/editmesh_tangent.cc b/source/blender/blenkernel/intern/editmesh_tangent.cc
index a65532d083d..12799afd2f7 100644
--- a/source/blender/blenkernel/intern/editmesh_tangent.cc
+++ b/source/blender/blenkernel/intern/editmesh_tangent.cc
@@ -33,9 +33,9 @@ struct SGLSLEditMeshToTangent {
uint GetNumFaces()
{
#ifdef USE_LOOPTRI_DETECT_QUADS
- return (uint)num_face_as_quad_map;
+ return uint(num_face_as_quad_map);
#else
- return (uint)numTessFaces;
+ return uint(numTessFaces);
#endif
}
@@ -94,12 +94,10 @@ struct SGLSLEditMeshToTangent {
const float *uv = (const float *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
return mikk::float3(uv[0], uv[1], 1.0f);
}
- else {
- const float *orco_p = orco[BM_elem_index_get(l->v)];
- float u, v;
- map_to_sphere(&u, &v, orco_p[0], orco_p[1], orco_p[2]);
- return mikk::float3(u, v, 1.0f);
- }
+ const float *orco_p = orco[BM_elem_index_get(l->v)];
+ float u, v;
+ map_to_sphere(&u, &v, orco_p[0], orco_p[1], orco_p[2]);
+ return mikk::float3(u, v, 1.0f);
}
mikk::float3 GetNormal(const uint face_num, const uint vert_index)
@@ -108,17 +106,13 @@ struct SGLSLEditMeshToTangent {
if (precomputedLoopNormals) {
return mikk::float3(precomputedLoopNormals[BM_elem_index_get(l)]);
}
- else if (BM_elem_flag_test(l->f, BM_ELEM_SMOOTH) == 0) { /* flat */
+ if (BM_elem_flag_test(l->f, BM_ELEM_SMOOTH) == 0) { /* flat */
if (precomputedFaceNormals) {
return mikk::float3(precomputedFaceNormals[BM_elem_index_get(l->f)]);
}
- else {
- return mikk::float3(l->f->no);
- }
- }
- else {
- return mikk::float3(l->v->no);
+ return mikk::float3(l->f->no);
}
+ return mikk::float3(l->v->no);
}
void SetTangentSpace(const uint face_num,
@@ -147,7 +141,7 @@ struct SGLSLEditMeshToTangent {
#endif
};
-static void emDM_calc_loop_tangents_thread(TaskPool *__restrict UNUSED(pool), void *taskdata)
+static void emDM_calc_loop_tangents_thread(TaskPool *__restrict /*pool*/, void *taskdata)
{
SGLSLEditMeshToTangent *mesh_data = static_cast<SGLSLEditMeshToTangent *>(taskdata);
@@ -194,21 +188,21 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
for (int i = 0; i < tangent_names_len; i++) {
if (tangent_names[i][0]) {
BKE_mesh_add_loop_tangent_named_layer_for_uv(
- &bm->ldata, loopdata_out, (int)loopdata_out_len, tangent_names[i]);
+ &bm->ldata, loopdata_out, int(loopdata_out_len), tangent_names[i]);
}
}
if ((tangent_mask & DM_TANGENT_MASK_ORCO) &&
CustomData_get_named_layer_index(loopdata_out, CD_TANGENT, "") == -1) {
CustomData_add_layer_named(
- loopdata_out, CD_TANGENT, CD_SET_DEFAULT, nullptr, (int)loopdata_out_len, "");
+ loopdata_out, CD_TANGENT, CD_SET_DEFAULT, nullptr, int(loopdata_out_len), "");
}
if (calc_act && act_uv_name[0]) {
BKE_mesh_add_loop_tangent_named_layer_for_uv(
- &bm->ldata, loopdata_out, (int)loopdata_out_len, act_uv_name);
+ &bm->ldata, loopdata_out, int(loopdata_out_len), act_uv_name);
}
if (calc_ren && ren_uv_name[0]) {
BKE_mesh_add_loop_tangent_named_layer_for_uv(
- &bm->ldata, loopdata_out, (int)loopdata_out_len, ren_uv_name);
+ &bm->ldata, loopdata_out, int(loopdata_out_len), ren_uv_name);
}
int totface = em->tottri;
#ifdef USE_LOOPTRI_DETECT_QUADS
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index f6a2975bea8..c2ae4efbde8 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -79,7 +79,7 @@ PartDeflect *BKE_partdeflect_new(int type)
pd->pdef_sbift = 0.2f;
pd->pdef_sboft = 0.02f;
pd->pdef_cfrict = 5.0f;
- pd->seed = ((uint)(ceil(PIL_check_seconds_timer())) + 1) % 128;
+ pd->seed = ((uint)ceil(PIL_check_seconds_timer()) + 1) % 128;
pd->f_strength = 1.0f;
pd->f_damp = 1.0f;
@@ -154,8 +154,8 @@ static void precalculate_effector(struct Depsgraph *depsgraph, EffectorCache *ef
if (eff->ob->runtime.curve_cache->anim_path_accum_length) {
BKE_where_on_path(
eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius, NULL);
- mul_m4_v3(eff->ob->obmat, eff->guide_loc);
- mul_mat3_m4_v3(eff->ob->obmat, eff->guide_dir);
+ mul_m4_v3(eff->ob->object_to_world, eff->guide_loc);
+ mul_mat3_m4_v3(eff->ob->object_to_world, eff->guide_dir);
}
}
}
@@ -207,10 +207,11 @@ static void add_effector_evaluation(ListBase **effectors,
}
ListBase *BKE_effector_relations_create(Depsgraph *depsgraph,
+ const Scene *scene,
ViewLayer *view_layer,
Collection *collection)
{
- Base *base = BKE_collection_or_layer_objects(view_layer, collection);
+ Base *base = BKE_collection_or_layer_objects(scene, view_layer, collection);
const bool for_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
const int base_flag = (for_render) ? BASE_ENABLED_RENDER : BASE_ENABLED_VIEWPORT;
@@ -706,8 +707,8 @@ bool get_effector_data(EffectorCache *eff,
copy_v3_v3(efd->loc, verts[*efd->index].co);
copy_v3_v3(efd->nor, vert_normals[*efd->index]);
- mul_m4_v3(eff->ob->obmat, efd->loc);
- mul_mat3_m4_v3(eff->ob->obmat, efd->nor);
+ mul_m4_v3(eff->ob->object_to_world, efd->loc);
+ mul_mat3_m4_v3(eff->ob->object_to_world, efd->nor);
normalize_v3(efd->nor);
@@ -759,23 +760,23 @@ bool get_effector_data(EffectorCache *eff,
const Object *ob = eff->ob;
/* Use z-axis as normal. */
- normalize_v3_v3(efd->nor, ob->obmat[2]);
+ normalize_v3_v3(efd->nor, ob->object_to_world[2]);
if (eff->pd && ELEM(eff->pd->shape, PFIELD_SHAPE_PLANE, PFIELD_SHAPE_LINE)) {
float temp[3], translate[3];
- sub_v3_v3v3(temp, point->loc, ob->obmat[3]);
+ sub_v3_v3v3(temp, point->loc, ob->object_to_world[3]);
project_v3_v3v3(translate, temp, efd->nor);
/* for vortex the shape chooses between old / new force */
if (eff->pd->forcefield == PFIELD_VORTEX || eff->pd->shape == PFIELD_SHAPE_LINE) {
- add_v3_v3v3(efd->loc, ob->obmat[3], translate);
+ add_v3_v3v3(efd->loc, ob->object_to_world[3], translate);
}
else { /* normally efd->loc is closest point on effector xy-plane */
sub_v3_v3v3(efd->loc, point->loc, translate);
}
}
else {
- copy_v3_v3(efd->loc, ob->obmat[3]);
+ copy_v3_v3(efd->loc, ob->object_to_world[3]);
}
zero_v3(efd->vel);
@@ -800,8 +801,8 @@ bool get_effector_data(EffectorCache *eff,
}
else {
/* for some effectors we need the object center every time */
- sub_v3_v3v3(efd->vec_to_point2, point->loc, eff->ob->obmat[3]);
- normalize_v3_v3(efd->nor2, eff->ob->obmat[2]);
+ sub_v3_v3v3(efd->vec_to_point2, point->loc, eff->ob->object_to_world[3]);
+ normalize_v3_v3(efd->nor2, eff->ob->object_to_world[2]);
}
}
@@ -874,7 +875,7 @@ static void do_texture_effector(EffectorCache *eff,
copy_v3_v3(tex_co, point->loc);
if (eff->pd->flag & PFIELD_TEX_OBJECT) {
- mul_m4_v3(eff->ob->imat, tex_co);
+ mul_m4_v3(eff->ob->world_to_object, tex_co);
if (eff->pd->flag & PFIELD_TEX_2D) {
tex_co[2] = 0.0f;
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index f5876e48241..d248faaab00 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -965,6 +965,18 @@ bool BKE_fcurve_is_protected(FCurve *fcu)
return ((fcu->flag & FCURVE_PROTECTED) || ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)));
}
+bool BKE_fcurve_has_selected_control_points(const FCurve *fcu)
+{
+ int i;
+ BezTriple *bezt;
+ for (bezt = fcu->bezt, i = 0; i < fcu->totvert; ++i, ++bezt) {
+ if ((bezt->f2 & SELECT) != 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
bool BKE_fcurve_is_keyframable(FCurve *fcu)
{
/* F-Curve's keyframes must be "usable" (i.e. visible + have an effect on final result) */
@@ -1308,7 +1320,7 @@ void BKE_fcurve_handles_recalc(FCurve *fcu)
void testhandles_fcurve(FCurve *fcu, eBezTriple_Flag sel_flag, const bool use_handle)
{
BezTriple *bezt;
- unsigned int a;
+ uint a;
/* Only beztriples have handles (bpoints don't though). */
if (ELEM(NULL, fcu, fcu->bezt)) {
@@ -1368,7 +1380,7 @@ void sort_time_fcurve(FCurve *fcu)
bool test_time_fcurve(FCurve *fcu)
{
- unsigned int a;
+ uint a;
/* Sanity checks. */
if (fcu == NULL) {
@@ -1778,7 +1790,7 @@ static float fcurve_eval_keyframes_interpolate(FCurve *fcu, BezTriple *bezts, fl
{
const float eps = 1.e-8f;
BezTriple *bezt, *prevbezt;
- unsigned int a;
+ uint a;
/* Evaltime occurs somewhere in the middle of the curve. */
bool exact = false;
@@ -2382,7 +2394,7 @@ void BKE_fcurve_blend_write(BlendWriter *writer, ListBase *fcurves)
void BKE_fcurve_blend_read_data(BlendDataReader *reader, ListBase *fcurves)
{
- /* link F-Curve data to F-Curve again (non ID-libs) */
+ /* Link F-Curve data to F-Curve again (non ID-libraries). */
LISTBASE_FOREACH (FCurve *, fcu, fcurves) {
/* curve data */
BLO_read_data_address(reader, &fcu->bezt);
diff --git a/source/blender/blenkernel/intern/fcurve_driver.c b/source/blender/blenkernel/intern/fcurve_driver.c
index aa33bef998f..3d1439b5530 100644
--- a/source/blender/blenkernel/intern/fcurve_driver.c
+++ b/source/blender/blenkernel/intern/fcurve_driver.c
@@ -321,7 +321,7 @@ static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar)
}
else {
/* Object. */
- mat[i] = ob->obmat;
+ mat[i] = ob->object_to_world;
}
}
@@ -333,7 +333,7 @@ static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar)
invert_qt_normalized(q1);
mul_qt_qtqt(quat, q1, q2);
- angle = 2.0f * (saacos(quat[0]));
+ angle = 2.0f * saacos(quat[0]);
angle = fabsf(angle);
return (angle > (float)M_PI) ? (float)((2.0f * (float)M_PI) - angle) : (float)(angle);
@@ -399,7 +399,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
else {
/* Convert to world-space. */
copy_v3_v3(tmp_loc, pchan->pose_head);
- mul_m4_v3(ob->obmat, tmp_loc);
+ mul_m4_v3(ob->object_to_world, tmp_loc);
}
}
else {
@@ -410,7 +410,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
float mat[4][4];
/* Extract transform just like how the constraints do it! */
- copy_m4_m4(mat, ob->obmat);
+ copy_m4_m4(mat, ob->object_to_world);
BKE_constraint_mat_convertspace(
ob, NULL, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
@@ -424,7 +424,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
}
else {
/* World-space. */
- copy_v3_v3(tmp_loc, ob->obmat[3]);
+ copy_v3_v3(tmp_loc, ob->object_to_world[3]);
}
}
@@ -500,7 +500,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
}
else {
/* World-space matrix. */
- mul_m4_m4m4(mat, ob->obmat, pchan->pose_mat);
+ mul_m4_m4m4(mat, ob->object_to_world, pchan->pose_mat);
}
}
else {
@@ -514,7 +514,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
/* Just like how the constraints do it! */
- copy_m4_m4(mat, ob->obmat);
+ copy_m4_m4(mat, ob->object_to_world);
BKE_constraint_mat_convertspace(
ob, NULL, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
}
@@ -525,7 +525,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
}
else {
/* World-space matrix - just the good-old one. */
- copy_m4_m4(mat, ob->obmat);
+ copy_m4_m4(mat, ob->object_to_world);
}
}
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index a81274c9bd7..c72f498cd5a 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -27,6 +27,7 @@
#include "BKE_effect.h"
#include "BKE_fluid.h"
#include "BKE_global.h"
+#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_modifier.h"
#include "BKE_pointcache.h"
@@ -79,7 +80,7 @@
/** Max value for phi initialization */
#define PHI_MAX 9999.0f
-static void BKE_fluid_modifier_reset_ex(struct FluidModifierData *fmd, bool need_lock);
+static void fluid_modifier_reset_ex(struct FluidModifierData *fmd, bool need_lock);
#ifdef WITH_FLUID
// #define DEBUG_PRINT
@@ -326,17 +327,17 @@ void BKE_fluid_cache_free(FluidDomainSettings *fds, Object *ob, int cache_map)
if (cache_map & FLUID_DOMAIN_OUTDATED_DATA) {
flags &= ~(FLUID_DOMAIN_BAKING_DATA | FLUID_DOMAIN_BAKED_DATA | FLUID_DOMAIN_OUTDATED_DATA);
- BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_CONFIG, NULL);
+ BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_CONFIG);
BLI_path_abs(temp_dir, relbase);
if (BLI_exists(temp_dir)) {
BLI_delete(temp_dir, true, true);
}
- BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_DATA, NULL);
+ BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_DATA);
BLI_path_abs(temp_dir, relbase);
if (BLI_exists(temp_dir)) {
BLI_delete(temp_dir, true, true);
}
- BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, NULL);
+ BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT);
BLI_path_abs(temp_dir, relbase);
if (BLI_exists(temp_dir)) {
BLI_delete(temp_dir, true, true);
@@ -345,7 +346,7 @@ void BKE_fluid_cache_free(FluidDomainSettings *fds, Object *ob, int cache_map)
}
if (cache_map & FLUID_DOMAIN_OUTDATED_NOISE) {
flags &= ~(FLUID_DOMAIN_BAKING_NOISE | FLUID_DOMAIN_BAKED_NOISE | FLUID_DOMAIN_OUTDATED_NOISE);
- BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE, NULL);
+ BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE);
BLI_path_abs(temp_dir, relbase);
if (BLI_exists(temp_dir)) {
BLI_delete(temp_dir, true, true);
@@ -354,7 +355,7 @@ void BKE_fluid_cache_free(FluidDomainSettings *fds, Object *ob, int cache_map)
}
if (cache_map & FLUID_DOMAIN_OUTDATED_MESH) {
flags &= ~(FLUID_DOMAIN_BAKING_MESH | FLUID_DOMAIN_BAKED_MESH | FLUID_DOMAIN_OUTDATED_MESH);
- BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_MESH, NULL);
+ BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_MESH);
BLI_path_abs(temp_dir, relbase);
if (BLI_exists(temp_dir)) {
BLI_delete(temp_dir, true, true);
@@ -364,8 +365,7 @@ void BKE_fluid_cache_free(FluidDomainSettings *fds, Object *ob, int cache_map)
if (cache_map & FLUID_DOMAIN_OUTDATED_PARTICLES) {
flags &= ~(FLUID_DOMAIN_BAKING_PARTICLES | FLUID_DOMAIN_BAKED_PARTICLES |
FLUID_DOMAIN_OUTDATED_PARTICLES);
- BLI_path_join(
- temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_PARTICLES, NULL);
+ BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_PARTICLES);
BLI_path_abs(temp_dir, relbase);
if (BLI_exists(temp_dir)) {
BLI_delete(temp_dir, true, true);
@@ -374,7 +374,7 @@ void BKE_fluid_cache_free(FluidDomainSettings *fds, Object *ob, int cache_map)
}
if (cache_map & FLUID_DOMAIN_OUTDATED_GUIDE) {
flags &= ~(FLUID_DOMAIN_BAKING_GUIDE | FLUID_DOMAIN_BAKED_GUIDE | FLUID_DOMAIN_OUTDATED_GUIDE);
- BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_GUIDE, NULL);
+ BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_GUIDE);
BLI_path_abs(temp_dir, relbase);
if (BLI_exists(temp_dir)) {
BLI_delete(temp_dir, true, true);
@@ -433,7 +433,7 @@ static void manta_set_domain_from_mesh(FluidDomainSettings *fds,
copy_v3_v3(fds->global_size, size);
copy_v3_v3(fds->dp0, min);
- invert_m4_m4(fds->imat, ob->obmat);
+ invert_m4_m4(fds->imat, ob->object_to_world);
/* Prevent crash when initializing a plane as domain. */
if (!init_resolution || (size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) ||
@@ -481,7 +481,7 @@ static void update_final_gravity(FluidDomainSettings *fds, Scene *scene)
mul_v3_fl(fds->gravity_final, fds->effector_weights->global_gravity);
}
-static bool BKE_fluid_modifier_init(
+static bool fluid_modifier_init(
FluidModifierData *fmd, Depsgraph *depsgraph, Object *ob, Scene *scene, Mesh *me)
{
int scene_framenr = (int)DEG_get_ctime(depsgraph);
@@ -498,8 +498,8 @@ static bool BKE_fluid_modifier_init(
zero_v3(fds->shift_f);
add_v3_fl(fds->shift_f, 0.5f);
zero_v3(fds->prev_loc);
- mul_m4_v3(ob->obmat, fds->prev_loc);
- copy_m4_m4(fds->obmat, ob->obmat);
+ mul_m4_v3(ob->object_to_world, fds->prev_loc);
+ copy_m4_m4(fds->obmat, ob->object_to_world);
/* Set resolutions. */
if (fmd->domain->type == FLUID_DOMAIN_TYPE_GAS &&
@@ -543,7 +543,9 @@ static bool BKE_fluid_modifier_init(
}
/* Forward declarations. */
-static void manta_smoke_calc_transparency(FluidDomainSettings *fds, ViewLayer *view_layer);
+static void manta_smoke_calc_transparency(FluidDomainSettings *fds,
+ Scene *scene,
+ ViewLayer *view_layer);
static float calc_voxel_transp(
float *result, const float *input, int res[3], int *pixel, float *t_ray, float correct);
static void update_distances(int index,
@@ -553,21 +555,22 @@ static void update_distances(int index,
float surface_thickness,
bool use_plane_init);
-static int get_light(ViewLayer *view_layer, float *light)
+static int get_light(Scene *scene, ViewLayer *view_layer, float *light)
{
int found_light = 0;
/* Try to find a lamp, preferably local. */
- LISTBASE_FOREACH (Base *, base_tmp, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base_tmp, BKE_view_layer_object_bases_get(view_layer)) {
if (base_tmp->object->type == OB_LAMP) {
Light *la = base_tmp->object->data;
if (la->type == LA_LOCAL) {
- copy_v3_v3(light, base_tmp->object->obmat[3]);
+ copy_v3_v3(light, base_tmp->object->object_to_world[3]);
return 1;
}
if (!found_light) {
- copy_v3_v3(light, base_tmp->object->obmat[3]);
+ copy_v3_v3(light, base_tmp->object->object_to_world[3]);
found_light = 1;
}
}
@@ -994,7 +997,6 @@ static void obstacles_from_mesh(Object *coll_ob,
float dt)
{
if (fes->mesh) {
- Mesh *me = NULL;
const MLoopTri *looptri;
BVHTreeFromMesh tree_data = {NULL};
int numverts, i;
@@ -1002,13 +1004,11 @@ static void obstacles_from_mesh(Object *coll_ob,
float *vert_vel = NULL;
bool has_velocity = false;
- me = BKE_mesh_copy_for_eval(fes->mesh, true);
+ Mesh *me = BKE_mesh_copy_for_eval(fes->mesh, false);
+ MVert *verts = BKE_mesh_verts_for_write(me);
int min[3], max[3], res[3];
- /* Duplicate vertices to modify. */
- MVert *verts = MEM_dupallocN(BKE_mesh_verts(me));
-
const MLoop *mloop = BKE_mesh_loops(me);
looptri = BKE_mesh_runtime_looptri_ensure(me);
numverts = me->totvert;
@@ -1036,7 +1036,7 @@ static void obstacles_from_mesh(Object *coll_ob,
float co[3];
/* Vertex position. */
- mul_m4_v3(coll_ob->obmat, verts[i].co);
+ mul_m4_v3(coll_ob->object_to_world, verts[i].co);
manta_pos_to_cell(fds, verts[i].co);
/* Vertex velocity. */
@@ -1093,7 +1093,6 @@ static void obstacles_from_mesh(Object *coll_ob,
if (vert_vel) {
MEM_freeN(vert_vel);
}
- MEM_SAFE_FREE(verts);
BKE_id_free(NULL, me);
}
}
@@ -1533,18 +1532,8 @@ static void emit_from_particles(Object *flow_ob,
sim.scene = scene;
sim.ob = flow_ob;
sim.psys = psys;
- sim.psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
- /* prepare curvemapping tables */
- if ((psys->part->child_flag & PART_CHILD_USE_CLUMP_CURVE) && psys->part->clumpcurve) {
- BKE_curvemapping_changed_all(psys->part->clumpcurve);
- }
- if ((psys->part->child_flag & PART_CHILD_USE_ROUGH_CURVE) && psys->part->roughcurve) {
- BKE_curvemapping_changed_all(psys->part->roughcurve);
- }
- if ((psys->part->child_flag & PART_CHILD_USE_TWIST_CURVE) && psys->part->twistcurve) {
- BKE_curvemapping_changed_all(psys->part->twistcurve);
- }
+ psys_sim_data_init(&sim);
/* initialize particle cache */
if (psys->part->type == PART_HAIR) {
@@ -1685,6 +1674,8 @@ static void emit_from_particles(Object *flow_ob,
if (particle_vel) {
MEM_freeN(particle_vel);
}
+
+ psys_sim_data_free(&sim);
}
}
@@ -2070,10 +2061,8 @@ static void emit_from_mesh(
/* Copy mesh for thread safety as we modify it.
* Main issue is its VertArray being modified, then replaced and freed. */
- Mesh *me = BKE_mesh_copy_for_eval(ffs->mesh, true);
-
- /* Duplicate vertices to modify. */
- MVert *verts = MEM_dupallocN(BKE_mesh_verts(me));
+ Mesh *me = BKE_mesh_copy_for_eval(ffs->mesh, false);
+ MVert *verts = BKE_mesh_verts_for_write(me);
const MLoop *mloop = BKE_mesh_loops(me);
const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me);
@@ -2098,14 +2087,15 @@ static void emit_from_mesh(
/* Transform mesh vertices to domain grid space for fast lookups.
* This is valid because the mesh is copied above. */
- float(*vert_normals)[3] = MEM_dupallocN(BKE_mesh_vertex_normals_ensure(me));
+ BKE_mesh_vertex_normals_ensure(me);
+ float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(me);
for (i = 0; i < numverts; i++) {
/* Vertex position. */
- mul_m4_v3(flow_ob->obmat, verts[i].co);
+ mul_m4_v3(flow_ob->object_to_world, verts[i].co);
manta_pos_to_cell(fds, verts[i].co);
/* Vertex normal. */
- mul_mat3_m4_v3(flow_ob->obmat, vert_normals[i]);
+ mul_mat3_m4_v3(flow_ob->object_to_world, vert_normals[i]);
mul_mat3_m4_v3(fds->imat, vert_normals[i]);
normalize_v3(vert_normals[i]);
@@ -2123,7 +2113,7 @@ static void emit_from_mesh(
/* Calculate emission map bounds. */
bb_boundInsert(bb, verts[i].co);
}
- mul_m4_v3(flow_ob->obmat, flow_center);
+ mul_m4_v3(flow_ob->object_to_world, flow_center);
manta_pos_to_cell(fds, flow_center);
/* Set emission map.
@@ -2174,8 +2164,6 @@ static void emit_from_mesh(
if (vert_vel) {
MEM_freeN(vert_vel);
}
- MEM_SAFE_FREE(verts);
- MEM_SAFE_FREE(vert_normals);
BKE_id_free(NULL, me);
}
}
@@ -2195,7 +2183,7 @@ static void adaptive_domain_adjust(
float frame_shift_f[3];
float ob_loc[3] = {0};
- mul_m4_v3(ob->obmat, ob_loc);
+ mul_m4_v3(ob->object_to_world, ob_loc);
sub_v3_v3v3(frame_shift_f, ob_loc, fds->prev_loc);
copy_v3_v3(fds->prev_loc, ob_loc);
@@ -2207,9 +2195,9 @@ static void adaptive_domain_adjust(
/* add to total shift */
add_v3_v3(fds->shift_f, frame_shift_f);
/* convert to integer */
- total_shift[0] = (int)(floorf(fds->shift_f[0]));
- total_shift[1] = (int)(floorf(fds->shift_f[1]));
- total_shift[2] = (int)(floorf(fds->shift_f[2]));
+ total_shift[0] = (int)floorf(fds->shift_f[0]);
+ total_shift[1] = (int)floorf(fds->shift_f[1]);
+ total_shift[2] = (int)floorf(fds->shift_f[2]);
int temp_shift[3];
copy_v3_v3_int(temp_shift, fds->shift);
sub_v3_v3v3_int(new_shift, total_shift, fds->shift);
@@ -3499,12 +3487,12 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje
/* Calculate required shift to match domain's global position
* it was originally simulated at (if object moves without manta step). */
- invert_m4_m4(ob->imat, ob->obmat);
- mul_m4_v3(ob->obmat, ob_loc);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
+ mul_m4_v3(ob->object_to_world, ob_loc);
mul_m4_v3(fds->obmat, ob_cache_loc);
sub_v3_v3v3(fds->obj_shift_f, ob_cache_loc, ob_loc);
/* Convert shift to local space and apply to vertices. */
- mul_mat3_m4_v3(ob->imat, fds->obj_shift_f);
+ mul_mat3_m4_v3(ob->world_to_object, fds->obj_shift_f);
/* Apply shift to vertices. */
for (int i = 0; i < num_verts; i++) {
add_v3_v3(mverts[i].co, fds->obj_shift_f);
@@ -3529,8 +3517,8 @@ static int manta_step(
bool mode_replay = (mode == FLUID_DOMAIN_CACHE_REPLAY);
/* Update object state. */
- invert_m4_m4(fds->imat, ob->obmat);
- copy_m4_m4(fds->obmat, ob->obmat);
+ invert_m4_m4(fds->imat, ob->object_to_world);
+ copy_m4_m4(fds->obmat, ob->object_to_world);
/* Gas domain might use adaptive domain. */
if (fds->type == FLUID_DOMAIN_TYPE_GAS) {
@@ -3596,7 +3584,8 @@ static int manta_step(
/* Compute shadow grid for gas simulations. Make sure to skip if bake job was canceled early. */
if (fds->type == FLUID_DOMAIN_TYPE_GAS && result) {
- manta_smoke_calc_transparency(fds, DEG_get_evaluated_view_layer(depsgraph));
+ manta_smoke_calc_transparency(
+ fds, DEG_get_evaluated_scene(depsgraph), DEG_get_evaluated_view_layer(depsgraph));
}
BLI_mutex_unlock(&object_update_lock);
@@ -3617,15 +3606,15 @@ static void manta_guiding(
BLI_mutex_unlock(&object_update_lock);
}
-static void BKE_fluid_modifier_processFlow(FluidModifierData *fmd,
- Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
- Mesh *me,
- const int scene_framenr)
+static void fluid_modifier_processFlow(FluidModifierData *fmd,
+ Depsgraph *depsgraph,
+ Scene *scene,
+ Object *ob,
+ Mesh *me,
+ const int scene_framenr)
{
if (scene_framenr >= fmd->time) {
- BKE_fluid_modifier_init(fmd, depsgraph, ob, scene, me);
+ fluid_modifier_init(fmd, depsgraph, ob, scene, me);
}
if (fmd->flow) {
@@ -3640,19 +3629,19 @@ static void BKE_fluid_modifier_processFlow(FluidModifierData *fmd,
}
else if (scene_framenr < fmd->time) {
fmd->time = scene_framenr;
- BKE_fluid_modifier_reset_ex(fmd, false);
+ fluid_modifier_reset_ex(fmd, false);
}
}
-static void BKE_fluid_modifier_processEffector(FluidModifierData *fmd,
- Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
- Mesh *me,
- const int scene_framenr)
+static void fluid_modifier_processEffector(FluidModifierData *fmd,
+ Depsgraph *depsgraph,
+ Scene *scene,
+ Object *ob,
+ Mesh *me,
+ const int scene_framenr)
{
if (scene_framenr >= fmd->time) {
- BKE_fluid_modifier_init(fmd, depsgraph, ob, scene, me);
+ fluid_modifier_init(fmd, depsgraph, ob, scene, me);
}
if (fmd->effector) {
@@ -3667,16 +3656,16 @@ static void BKE_fluid_modifier_processEffector(FluidModifierData *fmd,
}
else if (scene_framenr < fmd->time) {
fmd->time = scene_framenr;
- BKE_fluid_modifier_reset_ex(fmd, false);
+ fluid_modifier_reset_ex(fmd, false);
}
}
-static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
- Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
- Mesh *me,
- const int scene_framenr)
+static void fluid_modifier_processDomain(FluidModifierData *fmd,
+ Depsgraph *depsgraph,
+ Scene *scene,
+ Object *ob,
+ Mesh *me,
+ const int scene_framenr)
{
FluidDomainSettings *fds = fmd->domain;
Object *guide_parent = NULL;
@@ -3722,7 +3711,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
/* Reset fluid if no fluid present. Also resets active fields. */
if (!fds->fluid) {
- BKE_fluid_modifier_reset_ex(fmd, false);
+ fluid_modifier_reset_ex(fmd, false);
}
/* Ensure cache directory is not relative. */
@@ -3750,12 +3739,12 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
if (pid.cache->flag & PTCACHE_OUTDATED) {
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
BKE_fluid_cache_free_all(fds, ob);
- BKE_fluid_modifier_reset_ex(fmd, false);
+ fluid_modifier_reset_ex(fmd, false);
}
}
/* Fluid domain init must not fail in order to continue modifier evaluation. */
- if (!fds->fluid && !BKE_fluid_modifier_init(fmd, depsgraph, ob, scene, me)) {
+ if (!fds->fluid && !fluid_modifier_init(fmd, depsgraph, ob, scene, me)) {
CLOG_ERROR(&LOG, "Fluid initialization failed. Should not happen!");
return;
}
@@ -4083,19 +4072,19 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
fmd->time = scene_framenr;
}
-static void BKE_fluid_modifier_process(
+static void fluid_modifier_process(
FluidModifierData *fmd, Depsgraph *depsgraph, Scene *scene, Object *ob, Mesh *me)
{
const int scene_framenr = (int)DEG_get_ctime(depsgraph);
if (fmd->type & MOD_FLUID_TYPE_FLOW) {
- BKE_fluid_modifier_processFlow(fmd, depsgraph, scene, ob, me, scene_framenr);
+ fluid_modifier_processFlow(fmd, depsgraph, scene, ob, me, scene_framenr);
}
else if (fmd->type & MOD_FLUID_TYPE_EFFEC) {
- BKE_fluid_modifier_processEffector(fmd, depsgraph, scene, ob, me, scene_framenr);
+ fluid_modifier_processEffector(fmd, depsgraph, scene, ob, me, scene_framenr);
}
else if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
- BKE_fluid_modifier_processDomain(fmd, depsgraph, scene, ob, me, scene_framenr);
+ fluid_modifier_processDomain(fmd, depsgraph, scene, ob, me, scene_framenr);
}
}
@@ -4113,7 +4102,7 @@ struct Mesh *BKE_fluid_modifier_do(
BLI_rw_mutex_lock(fmd->domain->fluid_mutex, THREAD_LOCK_WRITE);
}
- BKE_fluid_modifier_process(fmd, depsgraph, scene, ob, me);
+ fluid_modifier_process(fmd, depsgraph, scene, ob, me);
if ((fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain) {
BLI_rw_mutex_unlock(fmd->domain->fluid_mutex);
@@ -4295,7 +4284,9 @@ static void bresenham_linie_3D(int x1,
cb(result, input, res, pixel, t_ray, correct);
}
-static void manta_smoke_calc_transparency(FluidDomainSettings *fds, ViewLayer *view_layer)
+static void manta_smoke_calc_transparency(FluidDomainSettings *fds,
+ Scene *scene,
+ ViewLayer *view_layer)
{
float bv[6] = {0};
float light[3];
@@ -4304,7 +4295,7 @@ static void manta_smoke_calc_transparency(FluidDomainSettings *fds, ViewLayer *v
float *shadow = manta_smoke_get_shadow(fds->fluid);
float correct = -7.0f * fds->dx;
- if (!get_light(view_layer, light)) {
+ if (!get_light(scene, view_layer, light)) {
return;
}
@@ -4686,7 +4677,7 @@ void BKE_fluid_fields_sanitize(FluidDomainSettings *settings)
* Use for versioning, even when fluids are disabled.
* \{ */
-static void BKE_fluid_modifier_freeDomain(FluidModifierData *fmd)
+static void fluid_modifier_freeDomain(FluidModifierData *fmd)
{
if (fmd->domain) {
if (fmd->domain->fluid) {
@@ -4715,7 +4706,7 @@ static void BKE_fluid_modifier_freeDomain(FluidModifierData *fmd)
}
}
-static void BKE_fluid_modifier_freeFlow(FluidModifierData *fmd)
+static void fluid_modifier_freeFlow(FluidModifierData *fmd)
{
if (fmd->flow) {
if (fmd->flow->mesh) {
@@ -4732,7 +4723,7 @@ static void BKE_fluid_modifier_freeFlow(FluidModifierData *fmd)
}
}
-static void BKE_fluid_modifier_freeEffector(FluidModifierData *fmd)
+static void fluid_modifier_freeEffector(FluidModifierData *fmd)
{
if (fmd->effector) {
if (fmd->effector->mesh) {
@@ -4749,7 +4740,7 @@ static void BKE_fluid_modifier_freeEffector(FluidModifierData *fmd)
}
}
-static void BKE_fluid_modifier_reset_ex(struct FluidModifierData *fmd, bool need_lock)
+static void fluid_modifier_reset_ex(struct FluidModifierData *fmd, bool need_lock)
{
if (!fmd) {
return;
@@ -4789,7 +4780,7 @@ static void BKE_fluid_modifier_reset_ex(struct FluidModifierData *fmd, bool need
void BKE_fluid_modifier_reset(struct FluidModifierData *fmd)
{
- BKE_fluid_modifier_reset_ex(fmd, true);
+ fluid_modifier_reset_ex(fmd, true);
}
void BKE_fluid_modifier_free(FluidModifierData *fmd)
@@ -4798,9 +4789,9 @@ void BKE_fluid_modifier_free(FluidModifierData *fmd)
return;
}
- BKE_fluid_modifier_freeDomain(fmd);
- BKE_fluid_modifier_freeFlow(fmd);
- BKE_fluid_modifier_freeEffector(fmd);
+ fluid_modifier_freeDomain(fmd);
+ fluid_modifier_freeFlow(fmd);
+ fluid_modifier_freeEffector(fmd);
}
void BKE_fluid_modifier_create_type_data(struct FluidModifierData *fmd)
@@ -4811,7 +4802,7 @@ void BKE_fluid_modifier_create_type_data(struct FluidModifierData *fmd)
if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
if (fmd->domain) {
- BKE_fluid_modifier_freeDomain(fmd);
+ fluid_modifier_freeDomain(fmd);
}
fmd->domain = DNA_struct_default_alloc(FluidDomainSettings);
@@ -4843,7 +4834,7 @@ void BKE_fluid_modifier_create_type_data(struct FluidModifierData *fmd)
}
else if (fmd->type & MOD_FLUID_TYPE_FLOW) {
if (fmd->flow) {
- BKE_fluid_modifier_freeFlow(fmd);
+ fluid_modifier_freeFlow(fmd);
}
fmd->flow = DNA_struct_default_alloc(FluidFlowSettings);
@@ -4851,7 +4842,7 @@ void BKE_fluid_modifier_create_type_data(struct FluidModifierData *fmd)
}
else if (fmd->type & MOD_FLUID_TYPE_EFFEC) {
if (fmd->effector) {
- BKE_fluid_modifier_freeEffector(fmd);
+ fluid_modifier_freeEffector(fmd);
}
fmd->effector = DNA_struct_default_alloc(FluidEffectorSettings);
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index 11c3dfc18dc..551bab75d4b 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -203,7 +203,7 @@ static void fcm_generator_evaluate(
case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* Factorized polynomial */
{
float value = 1.0f, *cp = NULL;
- unsigned int i;
+ uint i;
/* For each coefficient pair,
* solve for that bracket before accumulating in value by multiplying. */
diff --git a/source/blender/blenkernel/intern/freestyle.c b/source/blender/blenkernel/intern/freestyle.c
index a0649930dfc..28d0d1719d7 100644
--- a/source/blender/blenkernel/intern/freestyle.c
+++ b/source/blender/blenkernel/intern/freestyle.c
@@ -183,7 +183,7 @@ FreestyleLineSet *BKE_freestyle_lineset_add(struct Main *bmain,
BLI_strncpy(lineset->name, name, sizeof(lineset->name));
}
else if (lineset_index > 0) {
- sprintf(lineset->name, "LineSet %i", lineset_index + 1);
+ BLI_snprintf(lineset->name, sizeof(lineset->name), "LineSet %i", lineset_index + 1);
}
else {
strcpy(lineset->name, "LineSet");
diff --git a/source/blender/blenkernel/intern/geometry_component_curve.cc b/source/blender/blenkernel/intern/geometry_component_curve.cc
deleted file mode 100644
index 8e482e4c691..00000000000
--- a/source/blender/blenkernel/intern/geometry_component_curve.cc
+++ /dev/null
@@ -1,1464 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_task.hh"
-
-#include "DNA_ID_enums.h"
-#include "DNA_curve_types.h"
-
-#include "BKE_attribute_math.hh"
-#include "BKE_curve.h"
-#include "BKE_geometry_set.hh"
-#include "BKE_lib_id.h"
-#include "BKE_spline.hh"
-
-#include "attribute_access_intern.hh"
-
-using blender::GMutableSpan;
-using blender::GSpan;
-using blender::GVArray;
-using blender::GVArraySpan;
-
-/* -------------------------------------------------------------------- */
-/** \name Geometry Component Implementation
- * \{ */
-
-CurveComponentLegacy::CurveComponentLegacy() : GeometryComponent(GEO_COMPONENT_TYPE_CURVE)
-{
-}
-
-CurveComponentLegacy::~CurveComponentLegacy()
-{
- this->clear();
-}
-
-GeometryComponent *CurveComponentLegacy::copy() const
-{
- CurveComponentLegacy *new_component = new CurveComponentLegacy();
- if (curve_ != nullptr) {
- new_component->curve_ = new CurveEval(*curve_);
- new_component->ownership_ = GeometryOwnershipType::Owned;
- }
- return new_component;
-}
-
-void CurveComponentLegacy::clear()
-{
- BLI_assert(this->is_mutable());
- if (curve_ != nullptr) {
- if (ownership_ == GeometryOwnershipType::Owned) {
- delete curve_;
- }
- curve_ = nullptr;
- }
-}
-
-bool CurveComponentLegacy::has_curve() const
-{
- return curve_ != nullptr;
-}
-
-void CurveComponentLegacy::replace(CurveEval *curve, GeometryOwnershipType ownership)
-{
- BLI_assert(this->is_mutable());
- this->clear();
- curve_ = curve;
- ownership_ = ownership;
-}
-
-CurveEval *CurveComponentLegacy::release()
-{
- BLI_assert(this->is_mutable());
- CurveEval *curve = curve_;
- curve_ = nullptr;
- return curve;
-}
-
-const CurveEval *CurveComponentLegacy::get_for_read() const
-{
- return curve_;
-}
-
-CurveEval *CurveComponentLegacy::get_for_write()
-{
- BLI_assert(this->is_mutable());
- if (ownership_ == GeometryOwnershipType::ReadOnly) {
- curve_ = new CurveEval(*curve_);
- ownership_ = GeometryOwnershipType::Owned;
- }
- return curve_;
-}
-
-bool CurveComponentLegacy::is_empty() const
-{
- return curve_ == nullptr;
-}
-
-bool CurveComponentLegacy::owns_direct_data() const
-{
- return ownership_ == GeometryOwnershipType::Owned;
-}
-
-void CurveComponentLegacy::ensure_owns_direct_data()
-{
- BLI_assert(this->is_mutable());
- if (ownership_ != GeometryOwnershipType::Owned) {
- curve_ = new CurveEval(*curve_);
- ownership_ = GeometryOwnershipType::Owned;
- }
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Attribute Access Helper Functions
- * \{ */
-
-namespace blender::bke {
-
-namespace {
-struct PointIndices {
- int spline_index;
- int point_index;
-};
-} // namespace
-static PointIndices lookup_point_indices(Span<int> offsets, const int index)
-{
- const int spline_index = std::upper_bound(offsets.begin(), offsets.end(), index) -
- offsets.begin() - 1;
- const int index_in_spline = index - offsets[spline_index];
- return {spline_index, index_in_spline};
-}
-
-/**
- * Mix together all of a spline's control point values.
- *
- * \note Theoretically this interpolation does not need to compute all values at once.
- * However, doing that makes the implementation simpler, and this can be optimized in the future if
- * only some values are required.
- */
-template<typename T>
-static void adapt_curve_domain_point_to_spline_impl(const CurveEval &curve,
- const VArray<T> &old_values,
- MutableSpan<T> r_values)
-{
- const int splines_len = curve.splines().size();
- Array<int> offsets = curve.control_point_offsets();
- BLI_assert(r_values.size() == splines_len);
- attribute_math::DefaultMixer<T> mixer(r_values);
-
- for (const int i_spline : IndexRange(splines_len)) {
- const int spline_offset = offsets[i_spline];
- const int spline_point_len = offsets[i_spline + 1] - spline_offset;
- for (const int i_point : IndexRange(spline_point_len)) {
- const T value = old_values[spline_offset + i_point];
- mixer.mix_in(i_spline, value);
- }
- }
-
- mixer.finalize();
-}
-
-/**
- * A spline is selected if all of its control points were selected.
- *
- * \note Theoretically this interpolation does not need to compute all values at once.
- * However, doing that makes the implementation simpler, and this can be optimized in the future if
- * only some values are required.
- */
-template<>
-void adapt_curve_domain_point_to_spline_impl(const CurveEval &curve,
- const VArray<bool> &old_values,
- MutableSpan<bool> r_values)
-{
- const int splines_len = curve.splines().size();
- Array<int> offsets = curve.control_point_offsets();
- BLI_assert(r_values.size() == splines_len);
-
- r_values.fill(true);
-
- for (const int i_spline : IndexRange(splines_len)) {
- const int spline_offset = offsets[i_spline];
- const int spline_point_len = offsets[i_spline + 1] - spline_offset;
-
- for (const int i_point : IndexRange(spline_point_len)) {
- if (!old_values[spline_offset + i_point]) {
- r_values[i_spline] = false;
- break;
- }
- }
- }
-}
-
-static GVArray adapt_curve_domain_point_to_spline(const CurveEval &curve, GVArray varray)
-{
- GVArray new_varray;
- attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
- using T = decltype(dummy);
- if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
- Array<T> values(curve.splines().size());
- adapt_curve_domain_point_to_spline_impl<T>(curve, varray.typed<T>(), values);
- new_varray = VArray<T>::ForContainer(std::move(values));
- }
- });
- return new_varray;
-}
-
-/**
- * A virtual array implementation for the conversion of spline attributes to control point
- * attributes. The goal is to avoid copying the spline value for every one of its control points
- * unless it is necessary (in that case the materialize functions will be called).
- */
-template<typename T> class VArray_For_SplineToPoint final : public VArrayImpl<T> {
- GVArray original_varray_;
- /* Store existing data materialized if it was not already a span. This is expected
- * to be worth it because a single spline's value will likely be accessed many times. */
- VArraySpan<T> original_data_;
- Array<int> offsets_;
-
- public:
- VArray_For_SplineToPoint(GVArray original_varray, Array<int> offsets)
- : VArrayImpl<T>(offsets.last()),
- original_varray_(std::move(original_varray)),
- original_data_(original_varray_.typed<T>()),
- offsets_(std::move(offsets))
- {
- }
-
- T get(const int64_t index) const final
- {
- const PointIndices indices = lookup_point_indices(offsets_, index);
- return original_data_[indices.spline_index];
- }
-
- void materialize(const IndexMask mask, MutableSpan<T> r_span) const final
- {
- const int total_num = offsets_.last();
- if (mask.is_range() && mask.as_range() == IndexRange(total_num)) {
- for (const int spline_index : original_data_.index_range()) {
- const int offset = offsets_[spline_index];
- const int next_offset = offsets_[spline_index + 1];
- r_span.slice(offset, next_offset - offset).fill(original_data_[spline_index]);
- }
- }
- else {
- int spline_index = 0;
- for (const int dst_index : mask) {
- while (offsets_[spline_index] < dst_index) {
- spline_index++;
- }
- r_span[dst_index] = original_data_[spline_index];
- }
- }
- }
-
- void materialize_to_uninitialized(const IndexMask mask, MutableSpan<T> r_span) const final
- {
- T *dst = r_span.data();
- const int total_num = offsets_.last();
- if (mask.is_range() && mask.as_range() == IndexRange(total_num)) {
- for (const int spline_index : original_data_.index_range()) {
- const int offset = offsets_[spline_index];
- const int next_offset = offsets_[spline_index + 1];
- uninitialized_fill_n(dst + offset, next_offset - offset, original_data_[spline_index]);
- }
- }
- else {
- int spline_index = 0;
- for (const int dst_index : mask) {
- while (offsets_[spline_index] < dst_index) {
- spline_index++;
- }
- new (dst + dst_index) T(original_data_[spline_index]);
- }
- }
- }
-};
-
-static GVArray adapt_curve_domain_spline_to_point(const CurveEval &curve, GVArray varray)
-{
- GVArray new_varray;
- attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
- using T = decltype(dummy);
-
- Array<int> offsets = curve.control_point_offsets();
- new_varray = VArray<T>::template For<VArray_For_SplineToPoint<T>>(std::move(varray),
- std::move(offsets));
- });
- return new_varray;
-}
-
-} // namespace blender::bke
-
-static GVArray adapt_curve_attribute_domain(const CurveEval &curve,
- const GVArray &varray,
- const eAttrDomain from_domain,
- const eAttrDomain to_domain)
-{
- if (!varray) {
- return {};
- }
- if (varray.is_empty()) {
- return {};
- }
- if (from_domain == to_domain) {
- return varray;
- }
-
- if (from_domain == ATTR_DOMAIN_POINT && to_domain == ATTR_DOMAIN_CURVE) {
- return blender::bke::adapt_curve_domain_point_to_spline(curve, std::move(varray));
- }
- if (from_domain == ATTR_DOMAIN_CURVE && to_domain == ATTR_DOMAIN_POINT) {
- return blender::bke::adapt_curve_domain_spline_to_point(curve, std::move(varray));
- }
-
- return {};
-}
-
-/** \} */
-
-namespace blender::bke {
-
-/* -------------------------------------------------------------------- */
-/** \name Builtin Spline Attributes
- *
- * Attributes with a value for every spline, stored contiguously or in every spline separately.
- * \{ */
-
-class BuiltinSplineAttributeProvider final : public BuiltinAttributeProvider {
- using AsReadAttribute = GVArray (*)(const CurveEval &data);
- using AsWriteAttribute = GVMutableArray (*)(CurveEval &data);
- const AsReadAttribute as_read_attribute_;
- const AsWriteAttribute as_write_attribute_;
-
- public:
- BuiltinSplineAttributeProvider(std::string attribute_name,
- const eCustomDataType attribute_type,
- const WritableEnum writable,
- const AsReadAttribute as_read_attribute,
- const AsWriteAttribute as_write_attribute)
- : BuiltinAttributeProvider(std::move(attribute_name),
- ATTR_DOMAIN_CURVE,
- attribute_type,
- BuiltinAttributeProvider::NonCreatable,
- writable,
- BuiltinAttributeProvider::NonDeletable),
- as_read_attribute_(as_read_attribute),
- as_write_attribute_(as_write_attribute)
- {
- }
-
- GVArray try_get_for_read(const void *owner) const final
- {
- const CurveEval *curve = static_cast<const CurveEval *>(owner);
- if (curve == nullptr) {
- return {};
- }
- return as_read_attribute_(*curve);
- }
-
- GAttributeWriter try_get_for_write(void *owner) const final
- {
- if (writable_ != Writable) {
- return {};
- }
- CurveEval *curve = static_cast<CurveEval *>(owner);
- if (curve == nullptr) {
- return {};
- }
- return {as_write_attribute_(*curve), domain_};
- }
-
- bool try_delete(void *UNUSED(owner)) const final
- {
- return false;
- }
-
- bool try_create(void *UNUSED(owner), const AttributeInit &UNUSED(initializer)) const final
- {
- return false;
- }
-
- bool exists(const void *owner) const final
- {
- const CurveEval *curve = static_cast<const CurveEval *>(owner);
- return !curve->splines().is_empty();
- }
-};
-
-static int get_spline_resolution(const SplinePtr &spline)
-{
- if (const BezierSpline *bezier_spline = dynamic_cast<const BezierSpline *>(spline.get())) {
- return bezier_spline->resolution();
- }
- if (const NURBSpline *nurb_spline = dynamic_cast<const NURBSpline *>(spline.get())) {
- return nurb_spline->resolution();
- }
- return 1;
-}
-
-static void set_spline_resolution(SplinePtr &spline, const int resolution)
-{
- if (BezierSpline *bezier_spline = dynamic_cast<BezierSpline *>(spline.get())) {
- bezier_spline->set_resolution(std::max(resolution, 1));
- }
- if (NURBSpline *nurb_spline = dynamic_cast<NURBSpline *>(spline.get())) {
- nurb_spline->set_resolution(std::max(resolution, 1));
- }
-}
-
-static GVArray make_resolution_read_attribute(const CurveEval &curve)
-{
- return VArray<int>::ForDerivedSpan<SplinePtr, get_spline_resolution>(curve.splines());
-}
-
-static GVMutableArray make_resolution_write_attribute(CurveEval &curve)
-{
- return VMutableArray<int>::
- ForDerivedSpan<SplinePtr, get_spline_resolution, set_spline_resolution>(curve.splines());
-}
-
-static bool get_cyclic_value(const SplinePtr &spline)
-{
- return spline->is_cyclic();
-}
-
-static void set_cyclic_value(SplinePtr &spline, const bool value)
-{
- if (spline->is_cyclic() != value) {
- spline->set_cyclic(value);
- spline->mark_cache_invalid();
- }
-}
-
-static GVArray make_cyclic_read_attribute(const CurveEval &curve)
-{
- return VArray<bool>::ForDerivedSpan<SplinePtr, get_cyclic_value>(curve.splines());
-}
-
-static GVMutableArray make_cyclic_write_attribute(CurveEval &curve)
-{
- return VMutableArray<bool>::ForDerivedSpan<SplinePtr, get_cyclic_value, set_cyclic_value>(
- curve.splines());
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Builtin Control Point Attributes
- *
- * Attributes with a value for every control point. Most of the complexity here is due to the fact
- * that we must provide access to the attribute data as if it was a contiguous array when it is
- * really stored separately on each spline. That will be inherently rather slow, but these virtual
- * array implementations try to make it workable in common situations.
- * \{ */
-
-/**
- * Individual spans in \a data may be empty if that spline contains no data for the attribute.
- */
-template<typename T>
-static void point_attribute_materialize(Span<Span<T>> data,
- Span<int> offsets,
- const IndexMask mask,
- MutableSpan<T> r_span)
-{
- const int total_num = offsets.last();
- if (mask.is_range() && mask.as_range() == IndexRange(total_num)) {
- for (const int spline_index : data.index_range()) {
- const int offset = offsets[spline_index];
- const int next_offset = offsets[spline_index + 1];
-
- Span<T> src = data[spline_index];
- MutableSpan<T> dst = r_span.slice(offset, next_offset - offset);
- if (src.is_empty()) {
- dst.fill(T());
- }
- else {
- dst.copy_from(src);
- }
- }
- }
- else {
- int spline_index = 0;
- for (const int dst_index : mask) {
- /* Skip splines that don't have any control points in the mask. */
- while (dst_index >= offsets[spline_index + 1]) {
- spline_index++;
- }
-
- const int index_in_spline = dst_index - offsets[spline_index];
- Span<T> src = data[spline_index];
- if (src.is_empty()) {
- r_span[dst_index] = T();
- }
- else {
- r_span[dst_index] = src[index_in_spline];
- }
- }
- }
-}
-
-/**
- * Individual spans in \a data may be empty if that spline contains no data for the attribute.
- */
-template<typename T>
-static void point_attribute_materialize_to_uninitialized(Span<Span<T>> data,
- Span<int> offsets,
- const IndexMask mask,
- MutableSpan<T> r_span)
-{
- T *dst = r_span.data();
- const int total_num = offsets.last();
- if (mask.is_range() && mask.as_range() == IndexRange(total_num)) {
- for (const int spline_index : data.index_range()) {
- const int offset = offsets[spline_index];
- const int next_offset = offsets[spline_index + 1];
-
- Span<T> src = data[spline_index];
- if (src.is_empty()) {
- uninitialized_fill_n(dst + offset, next_offset - offset, T());
- }
- else {
- uninitialized_copy_n(src.data(), next_offset - offset, dst + offset);
- }
- }
- }
- else {
- int spline_index = 0;
- for (const int dst_index : mask) {
- /* Skip splines that don't have any control points in the mask. */
- while (dst_index >= offsets[spline_index + 1]) {
- spline_index++;
- }
-
- const int index_in_spline = dst_index - offsets[spline_index];
- Span<T> src = data[spline_index];
- if (src.is_empty()) {
- new (dst + dst_index) T();
- }
- else {
- new (dst + dst_index) T(src[index_in_spline]);
- }
- }
- }
-}
-
-static GVArray varray_from_initializer(const AttributeInit &initializer,
- const eCustomDataType data_type,
- const Span<SplinePtr> splines)
-{
- switch (initializer.type) {
- case AttributeInit::Type::Construct:
- case AttributeInit::Type::DefaultValue:
- /* This function shouldn't be called in this case, since there
- * is no need to copy anything to the new custom data array. */
- BLI_assert_unreachable();
- return {};
- case AttributeInit::Type::VArray:
- return static_cast<const AttributeInitVArray &>(initializer).varray;
- case AttributeInit::Type::MoveArray:
- int total_num = 0;
- for (const SplinePtr &spline : splines) {
- total_num += spline->size();
- }
- return GVArray::ForSpan(GSpan(*bke::custom_data_type_to_cpp_type(data_type),
- static_cast<const AttributeInitMoveArray &>(initializer).data,
- total_num));
- }
- BLI_assert_unreachable();
- return {};
-}
-
-static bool create_point_attribute(CurveEval *curve,
- const AttributeIDRef &attribute_id,
- const AttributeInit &initializer,
- const eCustomDataType data_type)
-{
- if (curve == nullptr || curve->splines().size() == 0) {
- return false;
- }
-
- MutableSpan<SplinePtr> splines = curve->splines();
-
- /* First check the one case that allows us to avoid copying the input data. */
- if (splines.size() == 1 && initializer.type == AttributeInit::Type::MoveArray) {
- void *source_data = static_cast<const AttributeInitMoveArray &>(initializer).data;
- if (!splines.first()->attributes.create_by_move(attribute_id, data_type, source_data)) {
- MEM_freeN(source_data);
- return false;
- }
- return true;
- }
-
- /* Otherwise just create a custom data layer on each of the splines. */
- for (const int i : splines.index_range()) {
- if (!splines[i]->attributes.create(attribute_id, data_type)) {
- /* If attribute creation fails on one of the splines, we cannot leave the custom data
- * layers in the previous splines around, so delete them before returning. However,
- * this is not an expected case. */
- BLI_assert_unreachable();
- return false;
- }
- }
-
- /* With a default initializer type, we can keep the values at their initial values. */
- if (ELEM(initializer.type, AttributeInit::Type::DefaultValue, AttributeInit::Type::Construct)) {
- return true;
- }
-
- GAttributeWriter write_attribute = curve->attributes_for_write().lookup_for_write(attribute_id);
- /* We just created the attribute, it should exist. */
- BLI_assert(write_attribute);
-
- GVArray source_varray = varray_from_initializer(initializer, data_type, splines);
- /* TODO: When we can call a variant of #set_all with a virtual array argument,
- * this theoretically unnecessary materialize step could be removed. */
- GVArraySpan source_VArraySpan{source_varray};
- write_attribute.varray.set_all(source_VArraySpan.data());
- write_attribute.finish();
-
- if (initializer.type == AttributeInit::Type::MoveArray) {
- MEM_freeN(static_cast<const AttributeInitMoveArray &>(initializer).data);
- }
-
- return true;
-}
-
-static bool remove_point_attribute(CurveEval *curve, const AttributeIDRef &attribute_id)
-{
- if (curve == nullptr) {
- return false;
- }
-
- /* Reuse the boolean for all splines; we expect all splines to have the same attributes. */
- bool layer_freed = false;
- for (SplinePtr &spline : curve->splines()) {
- layer_freed = spline->attributes.remove(attribute_id);
- }
- return layer_freed;
-}
-
-/**
- * Mutable virtual array for any control point data accessed with spans and an offset array.
- */
-template<typename T> class VArrayImpl_For_SplinePoints final : public VMutableArrayImpl<T> {
- private:
- Array<MutableSpan<T>> data_;
- Array<int> offsets_;
-
- public:
- VArrayImpl_For_SplinePoints(Array<MutableSpan<T>> data, Array<int> offsets)
- : VMutableArrayImpl<T>(offsets.last()), data_(std::move(data)), offsets_(std::move(offsets))
- {
- }
-
- T get(const int64_t index) const final
- {
- const PointIndices indices = lookup_point_indices(offsets_, index);
- return data_[indices.spline_index][indices.point_index];
- }
-
- void set(const int64_t index, T value) final
- {
- const PointIndices indices = lookup_point_indices(offsets_, index);
- data_[indices.spline_index][indices.point_index] = value;
- }
-
- void set_all(Span<T> src) final
- {
- for (const int spline_index : data_.index_range()) {
- const int offset = offsets_[spline_index];
- const int next_offsets = offsets_[spline_index + 1];
- data_[spline_index].copy_from(src.slice(offset, next_offsets - offset));
- }
- }
-
- void materialize(const IndexMask mask, MutableSpan<T> r_span) const final
- {
- point_attribute_materialize({(Span<T> *)data_.data(), data_.size()}, offsets_, mask, r_span);
- }
-
- void materialize_to_uninitialized(const IndexMask mask, MutableSpan<T> r_span) const final
- {
- point_attribute_materialize_to_uninitialized(
- {(Span<T> *)data_.data(), data_.size()}, offsets_, mask, r_span);
- }
-};
-
-template<typename T> VArray<T> point_data_varray(Array<MutableSpan<T>> spans, Array<int> offsets)
-{
- return VArray<T>::template For<VArrayImpl_For_SplinePoints<T>>(std::move(spans),
- std::move(offsets));
-}
-
-template<typename T>
-VMutableArray<T> point_data_varray_mutable(Array<MutableSpan<T>> spans, Array<int> offsets)
-{
- return VMutableArray<T>::template For<VArrayImpl_For_SplinePoints<T>>(std::move(spans),
- std::move(offsets));
-}
-
-/**
- * Virtual array implementation specifically for control point positions. This is only needed for
- * Bezier splines, where adjusting the position also requires adjusting handle positions depending
- * on handle types. We pay a small price for this when other spline types are mixed with Bezier.
- *
- * \note There is no need to check the handle type to avoid changing auto handles, since
- * retrieving write access to the position data will mark them for recomputation anyway.
- */
-class VArrayImpl_For_SplinePosition final : public VMutableArrayImpl<float3> {
- private:
- MutableSpan<SplinePtr> splines_;
- Array<int> offsets_;
-
- public:
- VArrayImpl_For_SplinePosition(MutableSpan<SplinePtr> splines, Array<int> offsets)
- : VMutableArrayImpl<float3>(offsets.last()), splines_(splines), offsets_(std::move(offsets))
- {
- }
-
- float3 get(const int64_t index) const final
- {
- const PointIndices indices = lookup_point_indices(offsets_, index);
- return splines_[indices.spline_index]->positions()[indices.point_index];
- }
-
- void set(const int64_t index, float3 value) final
- {
- const PointIndices indices = lookup_point_indices(offsets_, index);
- Spline &spline = *splines_[indices.spline_index];
- spline.positions()[indices.point_index] = value;
- }
-
- void set_all(Span<float3> src) final
- {
- for (const int spline_index : splines_.index_range()) {
- Spline &spline = *splines_[spline_index];
- const int offset = offsets_[spline_index];
- const int next_offset = offsets_[spline_index + 1];
- spline.positions().copy_from(src.slice(offset, next_offset - offset));
- }
- }
-
- /** Utility so we can pass positions to the materialize functions above. */
- Array<Span<float3>> get_position_spans() const
- {
- Array<Span<float3>> spans(splines_.size());
- for (const int i : spans.index_range()) {
- spans[i] = splines_[i]->positions();
- }
- return spans;
- }
-
- void materialize(const IndexMask mask, MutableSpan<float3> r_span) const final
- {
- Array<Span<float3>> spans = this->get_position_spans();
- point_attribute_materialize(spans.as_span(), offsets_, mask, r_span);
- }
-
- void materialize_to_uninitialized(const IndexMask mask, MutableSpan<float3> r_span) const final
- {
- Array<Span<float3>> spans = this->get_position_spans();
- point_attribute_materialize_to_uninitialized(spans.as_span(), offsets_, mask, r_span);
- }
-};
-
-class VArrayImpl_For_BezierHandles final : public VMutableArrayImpl<float3> {
- private:
- MutableSpan<SplinePtr> splines_;
- Array<int> offsets_;
- bool is_right_;
-
- public:
- VArrayImpl_For_BezierHandles(MutableSpan<SplinePtr> splines,
- Array<int> offsets,
- const bool is_right)
- : VMutableArrayImpl<float3>(offsets.last()),
- splines_(splines),
- offsets_(std::move(offsets)),
- is_right_(is_right)
- {
- }
-
- float3 get(const int64_t index) const final
- {
- const PointIndices indices = lookup_point_indices(offsets_, index);
- const Spline &spline = *splines_[indices.spline_index];
- if (spline.type() == CURVE_TYPE_BEZIER) {
- const BezierSpline &bezier_spline = static_cast<const BezierSpline &>(spline);
- return is_right_ ? bezier_spline.handle_positions_right()[indices.point_index] :
- bezier_spline.handle_positions_left()[indices.point_index];
- }
- return float3(0);
- }
-
- void set(const int64_t index, float3 value) final
- {
- const PointIndices indices = lookup_point_indices(offsets_, index);
- Spline &spline = *splines_[indices.spline_index];
- if (spline.type() == CURVE_TYPE_BEZIER) {
- BezierSpline &bezier_spline = static_cast<BezierSpline &>(spline);
- if (is_right_) {
- bezier_spline.handle_positions_right()[indices.point_index] = value;
- }
- else {
- bezier_spline.handle_positions_left()[indices.point_index] = value;
- }
- bezier_spline.mark_cache_invalid();
- }
- }
-
- void set_all(Span<float3> src) final
- {
- for (const int spline_index : splines_.index_range()) {
- Spline &spline = *splines_[spline_index];
- if (spline.type() == CURVE_TYPE_BEZIER) {
- const int offset = offsets_[spline_index];
-
- BezierSpline &bezier_spline = static_cast<BezierSpline &>(spline);
- if (is_right_) {
- for (const int i : IndexRange(bezier_spline.size())) {
- bezier_spline.handle_positions_right()[i] = src[offset + i];
- }
- }
- else {
- for (const int i : IndexRange(bezier_spline.size())) {
- bezier_spline.handle_positions_left()[i] = src[offset + i];
- }
- }
- bezier_spline.mark_cache_invalid();
- }
- }
- }
-
- void materialize(const IndexMask mask, MutableSpan<float3> r_span) const final
- {
- Array<Span<float3>> spans = get_handle_spans(splines_, is_right_);
- point_attribute_materialize(spans.as_span(), offsets_, mask, r_span);
- }
-
- void materialize_to_uninitialized(const IndexMask mask, MutableSpan<float3> r_span) const final
- {
- Array<Span<float3>> spans = get_handle_spans(splines_, is_right_);
- point_attribute_materialize_to_uninitialized(spans.as_span(), offsets_, mask, r_span);
- }
-
- /**
- * Utility so we can pass handle positions to the materialize functions above.
- *
- * \note This relies on the ability of the materialize implementations to
- * handle empty spans, since only Bezier splines have handles.
- */
- static Array<Span<float3>> get_handle_spans(Span<SplinePtr> splines, const bool is_right)
- {
- Array<Span<float3>> spans(splines.size());
- for (const int i : spans.index_range()) {
- if (splines[i]->type() == CURVE_TYPE_BEZIER) {
- BezierSpline &bezier_spline = static_cast<BezierSpline &>(*splines[i]);
- spans[i] = is_right ? bezier_spline.handle_positions_right() :
- bezier_spline.handle_positions_left();
- }
- else {
- spans[i] = {};
- }
- }
- return spans;
- }
-};
-
-/**
- * Provider for any builtin control point attribute that doesn't need
- * special handling like access to other arrays in the spline.
- */
-template<typename T> class BuiltinPointAttributeProvider : public BuiltinAttributeProvider {
- protected:
- using GetSpan = Span<T> (*)(const Spline &spline);
- using GetMutableSpan = MutableSpan<T> (*)(Spline &spline);
- using UpdateOnWrite = void (*)(Spline &spline);
- const GetSpan get_span_;
- const GetMutableSpan get_mutable_span_;
- const UpdateOnWrite update_on_write_;
- bool stored_in_custom_data_;
-
- public:
- BuiltinPointAttributeProvider(std::string attribute_name,
- const CreatableEnum creatable,
- const DeletableEnum deletable,
- const GetSpan get_span,
- const GetMutableSpan get_mutable_span,
- const UpdateOnWrite update_on_write,
- const bool stored_in_custom_data)
- : BuiltinAttributeProvider(std::move(attribute_name),
- ATTR_DOMAIN_POINT,
- bke::cpp_type_to_custom_data_type(CPPType::get<T>()),
- creatable,
- WritableEnum::Writable,
- deletable),
- get_span_(get_span),
- get_mutable_span_(get_mutable_span),
- update_on_write_(update_on_write),
- stored_in_custom_data_(stored_in_custom_data)
- {
- }
-
- GVArray try_get_for_read(const void *owner) const override
- {
- const CurveEval *curve = static_cast<const CurveEval *>(owner);
- if (curve == nullptr) {
- return {};
- }
-
- if (!this->exists(owner)) {
- return {};
- }
-
- Span<SplinePtr> splines = curve->splines();
- if (splines.size() == 1) {
- return GVArray::ForSpan(get_span_(*splines.first()));
- }
-
- Array<int> offsets = curve->control_point_offsets();
- Array<MutableSpan<T>> spans(splines.size());
- for (const int i : splines.index_range()) {
- Span<T> span = get_span_(*splines[i]);
- /* Use const-cast because the underlying virtual array implementation is shared between const
- * and non const data. */
- spans[i] = MutableSpan<T>(const_cast<T *>(span.data()), span.size());
- }
-
- return point_data_varray(spans, offsets);
- }
-
- GAttributeWriter try_get_for_write(void *owner) const override
- {
- CurveEval *curve = static_cast<CurveEval *>(owner);
- if (curve == nullptr) {
- return {};
- }
-
- if (!this->exists(owner)) {
- return {};
- }
-
- std::function<void()> tag_modified_fn;
- if (update_on_write_ != nullptr) {
- tag_modified_fn = [curve, update = update_on_write_]() {
- for (SplinePtr &spline : curve->splines()) {
- update(*spline);
- }
- };
- }
-
- MutableSpan<SplinePtr> splines = curve->splines();
- if (splines.size() == 1) {
- return {GVMutableArray::ForSpan(get_mutable_span_(*splines.first())),
- domain_,
- std::move(tag_modified_fn)};
- }
-
- Array<int> offsets = curve->control_point_offsets();
- Array<MutableSpan<T>> spans(splines.size());
- for (const int i : splines.index_range()) {
- spans[i] = get_mutable_span_(*splines[i]);
- }
-
- return {point_data_varray_mutable(spans, offsets), domain_, tag_modified_fn};
- }
-
- bool try_delete(void *owner) const final
- {
- if (deletable_ == DeletableEnum::NonDeletable) {
- return false;
- }
- CurveEval *curve = static_cast<CurveEval *>(owner);
- return remove_point_attribute(curve, name_);
- }
-
- bool try_create(void *owner, const AttributeInit &initializer) const final
- {
- if (createable_ == CreatableEnum::NonCreatable) {
- return false;
- }
- CurveEval *curve = static_cast<CurveEval *>(owner);
- return create_point_attribute(curve, name_, initializer, CD_PROP_INT32);
- }
-
- bool exists(const void *owner) const final
- {
- const CurveEval *curve = static_cast<const CurveEval *>(owner);
- if (curve == nullptr) {
- return false;
- }
-
- Span<SplinePtr> splines = curve->splines();
- if (splines.size() == 0) {
- return false;
- }
-
- if (stored_in_custom_data_) {
- if (!curve->splines().first()->attributes.get_for_read(name_)) {
- return false;
- }
- }
-
- bool has_point = false;
- for (const SplinePtr &spline : curve->splines()) {
- if (spline->size() != 0) {
- has_point = true;
- break;
- }
- }
-
- if (!has_point) {
- return false;
- }
-
- return true;
- }
-};
-
-/**
- * Special attribute provider for the position attribute. Keeping this separate means we don't
- * need to make #BuiltinPointAttributeProvider overly generic, and the special handling for the
- * positions is more clear.
- */
-class PositionAttributeProvider final : public BuiltinPointAttributeProvider<float3> {
- public:
- PositionAttributeProvider()
- : BuiltinPointAttributeProvider(
- "position",
- BuiltinAttributeProvider::NonCreatable,
- BuiltinAttributeProvider::NonDeletable,
- [](const Spline &spline) { return spline.positions(); },
- [](Spline &spline) { return spline.positions(); },
- [](Spline &spline) { spline.mark_cache_invalid(); },
- false)
- {
- }
-
- GAttributeWriter try_get_for_write(void *owner) const final
- {
- CurveEval *curve = static_cast<CurveEval *>(owner);
- if (curve == nullptr) {
- return {};
- }
-
- /* Use the regular position virtual array when there aren't any Bezier splines
- * to avoid the overhead of checking the spline type for every point. */
- if (!curve->has_spline_with_type(CURVE_TYPE_BEZIER)) {
- return BuiltinPointAttributeProvider<float3>::try_get_for_write(owner);
- }
-
- auto tag_modified_fn = [curve]() {
- /* Changing the positions requires recalculation of cached evaluated data in many cases.
- * This could set more specific flags in the future to avoid unnecessary recomputation. */
- curve->mark_cache_invalid();
- };
-
- Array<int> offsets = curve->control_point_offsets();
- return {VMutableArray<float3>::For<VArrayImpl_For_SplinePosition>(curve->splines(),
- std::move(offsets)),
- domain_,
- tag_modified_fn};
- }
-};
-
-class BezierHandleAttributeProvider : public BuiltinAttributeProvider {
- private:
- bool is_right_;
-
- public:
- BezierHandleAttributeProvider(const bool is_right)
- : BuiltinAttributeProvider(is_right ? "handle_right" : "handle_left",
- ATTR_DOMAIN_POINT,
- CD_PROP_FLOAT3,
- BuiltinAttributeProvider::NonCreatable,
- BuiltinAttributeProvider::Writable,
- BuiltinAttributeProvider::NonDeletable),
- is_right_(is_right)
- {
- }
-
- GVArray try_get_for_read(const void *owner) const override
- {
- const CurveEval *curve = static_cast<const CurveEval *>(owner);
- if (curve == nullptr) {
- return {};
- }
-
- if (!curve->has_spline_with_type(CURVE_TYPE_BEZIER)) {
- return {};
- }
-
- Array<int> offsets = curve->control_point_offsets();
- /* Use const-cast because the underlying virtual array implementation is shared between const
- * and non const data. */
- return VArray<float3>::For<VArrayImpl_For_BezierHandles>(
- const_cast<CurveEval *>(curve)->splines(), std::move(offsets), is_right_);
- }
-
- GAttributeWriter try_get_for_write(void *owner) const override
- {
- CurveEval *curve = static_cast<CurveEval *>(owner);
- if (curve == nullptr) {
- return {};
- }
-
- if (!curve->has_spline_with_type(CURVE_TYPE_BEZIER)) {
- return {};
- }
-
- auto tag_modified_fn = [curve]() { curve->mark_cache_invalid(); };
-
- Array<int> offsets = curve->control_point_offsets();
- return {VMutableArray<float3>::For<VArrayImpl_For_BezierHandles>(
- curve->splines(), std::move(offsets), is_right_),
- domain_,
- tag_modified_fn};
- }
-
- bool try_delete(void *UNUSED(owner)) const final
- {
- return false;
- }
-
- bool try_create(void *UNUSED(owner), const AttributeInit &UNUSED(initializer)) const final
- {
- return false;
- }
-
- bool exists(const void *owner) const final
- {
- const CurveEval *curve = static_cast<const CurveEval *>(owner);
- if (curve == nullptr) {
- return false;
- }
-
- CurveComponentLegacy component;
- component.replace(const_cast<CurveEval *>(curve), GeometryOwnershipType::ReadOnly);
-
- return curve->has_spline_with_type(CURVE_TYPE_BEZIER) && !curve->splines().is_empty();
- }
-};
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Dynamic Control Point Attributes
- *
- * The dynamic control point attribute implementation is very similar to the builtin attribute
- * implementation-- it uses the same virtual array types. In order to work, this code depends on
- * the fact that all a curve's splines will have the same attributes and they all have the same
- * type.
- * \{ */
-
-class DynamicPointAttributeProvider final : public DynamicAttributesProvider {
- private:
- static constexpr uint64_t supported_types_mask = CD_MASK_PROP_FLOAT | CD_MASK_PROP_FLOAT2 |
- CD_MASK_PROP_FLOAT3 | CD_MASK_PROP_INT32 |
- CD_MASK_PROP_COLOR | CD_MASK_PROP_BOOL |
- CD_MASK_PROP_INT8;
-
- public:
- GAttributeReader try_get_for_read(const void *owner,
- const AttributeIDRef &attribute_id) const final
- {
- const CurveEval *curve = static_cast<const CurveEval *>(owner);
- if (curve == nullptr || curve->splines().size() == 0) {
- return {};
- }
-
- Span<SplinePtr> splines = curve->splines();
- Vector<GSpan> spans; /* GSpan has no default constructor. */
- spans.reserve(splines.size());
- std::optional<GSpan> first_span = splines[0]->attributes.get_for_read(attribute_id);
- if (!first_span) {
- return {};
- }
- spans.append(*first_span);
- for (const int i : IndexRange(1, splines.size() - 1)) {
- std::optional<GSpan> span = splines[i]->attributes.get_for_read(attribute_id);
- if (!span) {
- /* All splines should have the same set of data layers. It would be possible to recover
- * here and return partial data instead, but that would add a lot of complexity for a
- * situation we don't even expect to encounter. */
- BLI_assert_unreachable();
- return {};
- }
- if (span->type() != spans.last().type()) {
- /* Data layer types on separate splines do not match. */
- BLI_assert_unreachable();
- return {};
- }
- spans.append(*span);
- }
-
- /* First check for the simpler situation when we can return a simpler span virtual array. */
- if (spans.size() == 1) {
- return {GVArray::ForSpan(spans.first()), ATTR_DOMAIN_POINT};
- }
-
- GAttributeReader attribute = {};
- Array<int> offsets = curve->control_point_offsets();
- attribute_math::convert_to_static_type(spans[0].type(), [&](auto dummy) {
- using T = decltype(dummy);
- Array<MutableSpan<T>> data(splines.size());
- for (const int i : splines.index_range()) {
- Span<T> span = spans[i].typed<T>();
- /* Use const-cast because the underlying virtual array implementation is shared between
- * const and non const data. */
- data[i] = MutableSpan<T>(const_cast<T *>(span.data()), span.size());
- BLI_assert(data[i].data() != nullptr);
- }
- attribute = {point_data_varray(data, offsets), ATTR_DOMAIN_POINT};
- });
- return attribute;
- }
-
- /* This function is almost the same as #try_get_for_read, but without const. */
- GAttributeWriter try_get_for_write(void *owner, const AttributeIDRef &attribute_id) const final
- {
- CurveEval *curve = static_cast<CurveEval *>(owner);
- if (curve == nullptr || curve->splines().size() == 0) {
- return {};
- }
-
- MutableSpan<SplinePtr> splines = curve->splines();
- Vector<GMutableSpan> spans; /* GMutableSpan has no default constructor. */
- spans.reserve(splines.size());
- std::optional<GMutableSpan> first_span = splines[0]->attributes.get_for_write(attribute_id);
- if (!first_span) {
- return {};
- }
- spans.append(*first_span);
- for (const int i : IndexRange(1, splines.size() - 1)) {
- std::optional<GMutableSpan> span = splines[i]->attributes.get_for_write(attribute_id);
- if (!span) {
- /* All splines should have the same set of data layers. It would be possible to recover
- * here and return partial data instead, but that would add a lot of complexity for a
- * situation we don't even expect to encounter. */
- BLI_assert_unreachable();
- return {};
- }
- if (span->type() != spans.last().type()) {
- /* Data layer types on separate splines do not match. */
- BLI_assert_unreachable();
- return {};
- }
- spans.append(*span);
- }
-
- /* First check for the simpler situation when we can return a simpler span virtual array. */
- if (spans.size() == 1) {
- return {GVMutableArray::ForSpan(spans.first()), ATTR_DOMAIN_POINT};
- }
-
- GAttributeWriter attribute = {};
- Array<int> offsets = curve->control_point_offsets();
- attribute_math::convert_to_static_type(spans[0].type(), [&](auto dummy) {
- using T = decltype(dummy);
- Array<MutableSpan<T>> data(splines.size());
- for (const int i : splines.index_range()) {
- data[i] = spans[i].typed<T>();
- BLI_assert(data[i].data() != nullptr);
- }
- attribute = {point_data_varray_mutable(data, offsets), ATTR_DOMAIN_POINT};
- });
- return attribute;
- }
-
- bool try_delete(void *owner, const AttributeIDRef &attribute_id) const final
- {
- CurveEval *curve = static_cast<CurveEval *>(owner);
- return remove_point_attribute(curve, attribute_id);
- }
-
- bool try_create(void *owner,
- const AttributeIDRef &attribute_id,
- const eAttrDomain domain,
- const eCustomDataType data_type,
- const AttributeInit &initializer) const final
- {
- BLI_assert(this->type_is_supported(data_type));
- if (domain != ATTR_DOMAIN_POINT) {
- return false;
- }
- CurveEval *curve = static_cast<CurveEval *>(owner);
- return create_point_attribute(curve, attribute_id, initializer, data_type);
- }
-
- bool foreach_attribute(const void *owner, const AttributeForeachCallback callback) const final
- {
- const CurveEval *curve = static_cast<const CurveEval *>(owner);
- if (curve == nullptr || curve->splines().size() == 0) {
- return false;
- }
-
- Span<SplinePtr> splines = curve->splines();
-
- /* In a debug build, check that all corresponding custom data layers have the same type. */
- curve->assert_valid_point_attributes();
-
- /* Use the first spline as a representative for all the others. */
- splines.first()->attributes.foreach_attribute(callback, ATTR_DOMAIN_POINT);
-
- return true;
- }
-
- void foreach_domain(const FunctionRef<void(eAttrDomain)> callback) const final
- {
- callback(ATTR_DOMAIN_POINT);
- }
-
- bool type_is_supported(eCustomDataType data_type) const
- {
- return ((1ULL << data_type) & supported_types_mask) != 0;
- }
-};
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Attribute Provider Declaration
- * \{ */
-
-/**
- * In this function all the attribute providers for a curve component are created.
- * Most data in this function is statically allocated, because it does not change over time.
- */
-static ComponentAttributeProviders create_attribute_providers_for_curve()
-{
- static BuiltinSplineAttributeProvider resolution("resolution",
- CD_PROP_INT32,
- BuiltinAttributeProvider::Writable,
- make_resolution_read_attribute,
- make_resolution_write_attribute);
-
- static BuiltinSplineAttributeProvider cyclic("cyclic",
- CD_PROP_BOOL,
- BuiltinAttributeProvider::Writable,
- make_cyclic_read_attribute,
- make_cyclic_write_attribute);
-
- static CustomDataAccessInfo spline_custom_data_access = {
- [](void *owner) -> CustomData * {
- CurveEval *curve = static_cast<CurveEval *>(owner);
- return curve ? &curve->attributes.data : nullptr;
- },
- [](const void *owner) -> const CustomData * {
- const CurveEval *curve = static_cast<const CurveEval *>(owner);
- return curve ? &curve->attributes.data : nullptr;
- },
- [](const void *owner) -> int {
- const CurveEval *curve = static_cast<const CurveEval *>(owner);
- return curve->splines().size();
- }};
-
- static CustomDataAttributeProvider spline_custom_data(ATTR_DOMAIN_CURVE,
- spline_custom_data_access);
-
- static PositionAttributeProvider position;
- static BezierHandleAttributeProvider handles_start(false);
- static BezierHandleAttributeProvider handles_end(true);
-
- static BuiltinPointAttributeProvider<int> id(
- "id",
- BuiltinAttributeProvider::Creatable,
- BuiltinAttributeProvider::Deletable,
- [](const Spline &spline) {
- std::optional<GSpan> span = spline.attributes.get_for_read("id");
- return span ? span->typed<int>() : Span<int>();
- },
- [](Spline &spline) {
- std::optional<GMutableSpan> span = spline.attributes.get_for_write("id");
- return span ? span->typed<int>() : MutableSpan<int>();
- },
- {},
- true);
-
- static BuiltinPointAttributeProvider<float> radius(
- "radius",
- BuiltinAttributeProvider::NonCreatable,
- BuiltinAttributeProvider::NonDeletable,
- [](const Spline &spline) { return spline.radii(); },
- [](Spline &spline) { return spline.radii(); },
- nullptr,
- false);
-
- static BuiltinPointAttributeProvider<float> tilt(
- "tilt",
- BuiltinAttributeProvider::NonCreatable,
- BuiltinAttributeProvider::NonDeletable,
- [](const Spline &spline) { return spline.tilts(); },
- [](Spline &spline) { return spline.tilts(); },
- [](Spline &spline) { spline.mark_cache_invalid(); },
- false);
-
- static DynamicPointAttributeProvider point_custom_data;
-
- return ComponentAttributeProviders(
- {&position, &id, &radius, &tilt, &handles_start, &handles_end, &resolution, &cyclic},
- {&spline_custom_data, &point_custom_data});
-}
-
-/** \} */
-
-static AttributeAccessorFunctions get_curve_accessor_functions()
-{
- static const ComponentAttributeProviders providers = create_attribute_providers_for_curve();
- AttributeAccessorFunctions fn =
- attribute_accessor_functions::accessor_functions_for_providers<providers>();
- fn.domain_size = [](const void *owner, const eAttrDomain domain) -> int {
- if (owner == nullptr) {
- return 0;
- }
- const CurveEval &curve_eval = *static_cast<const CurveEval *>(owner);
- switch (domain) {
- case ATTR_DOMAIN_POINT:
- return curve_eval.total_control_point_num();
- case ATTR_DOMAIN_CURVE:
- return curve_eval.splines().size();
- default:
- return 0;
- }
- };
- fn.domain_supported = [](const void *UNUSED(owner), const eAttrDomain domain) {
- return ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CURVE);
- };
- fn.adapt_domain = [](const void *owner,
- const blender::GVArray &varray,
- const eAttrDomain from_domain,
- const eAttrDomain to_domain) -> GVArray {
- if (owner == nullptr) {
- return {};
- }
- const CurveEval &curve_eval = *static_cast<const CurveEval *>(owner);
- return adapt_curve_attribute_domain(curve_eval, varray, from_domain, to_domain);
- };
- return fn;
-}
-
-static const AttributeAccessorFunctions &get_curve_accessor_functions_ref()
-{
- static const AttributeAccessorFunctions fn = get_curve_accessor_functions();
- return fn;
-}
-
-} // namespace blender::bke
-
-std::optional<blender::bke::AttributeAccessor> CurveComponentLegacy::attributes() const
-{
- return blender::bke::AttributeAccessor(curve_, blender::bke::get_curve_accessor_functions_ref());
-}
-
-std::optional<blender::bke::MutableAttributeAccessor> CurveComponentLegacy::attributes_for_write()
-{
- CurveEval *curve = this->get_for_write();
- return blender::bke::MutableAttributeAccessor(curve,
- blender::bke::get_curve_accessor_functions_ref());
-}
-
-blender::bke::MutableAttributeAccessor CurveEval::attributes_for_write()
-{
- return blender::bke::MutableAttributeAccessor(this,
- blender::bke::get_curve_accessor_functions_ref());
-}
diff --git a/source/blender/blenkernel/intern/geometry_component_curves.cc b/source/blender/blenkernel/intern/geometry_component_curves.cc
index 83a35534c01..fff9004bc16 100644
--- a/source/blender/blenkernel/intern/geometry_component_curves.cc
+++ b/source/blender/blenkernel/intern/geometry_component_curves.cc
@@ -12,6 +12,8 @@
#include "BKE_geometry_set.hh"
#include "BKE_lib_id.h"
+#include "FN_multi_function_builder.hh"
+
#include "attribute_access_intern.hh"
using blender::GVArray;
@@ -264,7 +266,7 @@ CurveLengthFieldInput::CurveLengthFieldInput()
GVArray CurveLengthFieldInput::get_varray_for_context(const CurvesGeometry &curves,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const
+ const IndexMask /*mask*/) const
{
return construct_curve_length_gvarray(curves, domain);
}
@@ -280,6 +282,12 @@ bool CurveLengthFieldInput::is_equal_to(const fn::FieldNode &other) const
return dynamic_cast<const CurveLengthFieldInput *>(&other) != nullptr;
}
+std::optional<eAttrDomain> CurveLengthFieldInput::preferred_domain(
+ const bke::CurvesGeometry & /*curves*/) const
+{
+ return ATTR_DOMAIN_CURVE;
+}
+
/** \} */
} // namespace blender::bke
@@ -426,6 +434,12 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
make_array_write_attribute<float3>,
tag_component_positions_changed);
+ static const fn::CustomMF_SI_SO<int8_t, int8_t> handle_type_clamp{
+ "Handle Type Validate",
+ [](int8_t value) {
+ return std::clamp<int8_t>(value, BEZIER_HANDLE_FREE, BEZIER_HANDLE_ALIGN);
+ },
+ fn::CustomMF_presets::AllSpanOrSingle()};
static BuiltinCustomDataLayerProvider handle_type_right("handle_type_right",
ATTR_DOMAIN_POINT,
CD_PROP_INT8,
@@ -436,7 +450,8 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
point_access,
make_array_read_attribute<int8_t>,
make_array_write_attribute<int8_t>,
- tag_component_topology_changed);
+ tag_component_topology_changed,
+ AttributeValidator{&handle_type_clamp});
static BuiltinCustomDataLayerProvider handle_type_left("handle_type_left",
ATTR_DOMAIN_POINT,
@@ -448,7 +463,8 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
point_access,
make_array_read_attribute<int8_t>,
make_array_write_attribute<int8_t>,
- tag_component_topology_changed);
+ tag_component_topology_changed,
+ AttributeValidator{&handle_type_clamp});
static BuiltinCustomDataLayerProvider nurbs_weight("nurbs_weight",
ATTR_DOMAIN_POINT,
@@ -462,6 +478,10 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
make_array_write_attribute<float>,
tag_component_positions_changed);
+ static const fn::CustomMF_SI_SO<int8_t, int8_t> nurbs_order_clamp{
+ "NURBS Order Validate",
+ [](int8_t value) { return std::max<int8_t>(value, 0); },
+ fn::CustomMF_presets::AllSpanOrSingle()};
static BuiltinCustomDataLayerProvider nurbs_order("nurbs_order",
ATTR_DOMAIN_CURVE,
CD_PROP_INT8,
@@ -472,8 +492,15 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
curve_access,
make_array_read_attribute<int8_t>,
make_array_write_attribute<int8_t>,
- tag_component_topology_changed);
+ tag_component_topology_changed,
+ AttributeValidator{&nurbs_order_clamp});
+ static const fn::CustomMF_SI_SO<int8_t, int8_t> normal_mode_clamp{
+ "Normal Mode Validate",
+ [](int8_t value) {
+ return std::clamp<int8_t>(value, NORMAL_MODE_MINIMUM_TWIST, NORMAL_MODE_Z_UP);
+ },
+ fn::CustomMF_presets::AllSpanOrSingle()};
static BuiltinCustomDataLayerProvider normal_mode("normal_mode",
ATTR_DOMAIN_CURVE,
CD_PROP_INT8,
@@ -484,8 +511,15 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
curve_access,
make_array_read_attribute<int8_t>,
make_array_write_attribute<int8_t>,
- tag_component_normals_changed);
+ tag_component_normals_changed,
+ AttributeValidator{&normal_mode_clamp});
+ static const fn::CustomMF_SI_SO<int8_t, int8_t> knots_mode_clamp{
+ "Knots Mode Validate",
+ [](int8_t value) {
+ return std::clamp<int8_t>(value, NURBS_KNOT_MODE_NORMAL, NURBS_KNOT_MODE_ENDPOINT_BEZIER);
+ },
+ fn::CustomMF_presets::AllSpanOrSingle()};
static BuiltinCustomDataLayerProvider nurbs_knots_mode("knots_mode",
ATTR_DOMAIN_CURVE,
CD_PROP_INT8,
@@ -496,8 +530,15 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
curve_access,
make_array_read_attribute<int8_t>,
make_array_write_attribute<int8_t>,
- tag_component_topology_changed);
+ tag_component_topology_changed,
+ AttributeValidator{&knots_mode_clamp});
+ static const fn::CustomMF_SI_SO<int8_t, int8_t> curve_type_clamp{
+ "Curve Type Validate",
+ [](int8_t value) {
+ return std::clamp<int8_t>(value, CURVE_TYPE_CATMULL_ROM, CURVE_TYPES_NUM);
+ },
+ fn::CustomMF_presets::AllSpanOrSingle()};
static BuiltinCustomDataLayerProvider curve_type("curve_type",
ATTR_DOMAIN_CURVE,
CD_PROP_INT8,
@@ -508,8 +549,13 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
curve_access,
make_array_read_attribute<int8_t>,
make_array_write_attribute<int8_t>,
- tag_component_curve_types_changed);
+ tag_component_curve_types_changed,
+ AttributeValidator{&curve_type_clamp});
+ static const fn::CustomMF_SI_SO<int, int> resolution_clamp{
+ "Resolution Validate",
+ [](int value) { return std::max<int>(value, 1); },
+ fn::CustomMF_presets::AllSpanOrSingle()};
static BuiltinCustomDataLayerProvider resolution("resolution",
ATTR_DOMAIN_CURVE,
CD_PROP_INT32,
@@ -520,7 +566,8 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
curve_access,
make_array_read_attribute<int>,
make_array_write_attribute<int>,
- tag_component_topology_changed);
+ tag_component_topology_changed,
+ AttributeValidator{&resolution_clamp});
static BuiltinCustomDataLayerProvider cyclic("cyclic",
ATTR_DOMAIN_CURVE,
@@ -576,7 +623,7 @@ static AttributeAccessorFunctions get_curves_accessor_functions()
return 0;
}
};
- fn.domain_supported = [](const void *UNUSED(owner), const eAttrDomain domain) {
+ fn.domain_supported = [](const void * /*owner*/, const eAttrDomain domain) {
return ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CURVE);
};
fn.adapt_domain = [](const void *owner,
diff --git a/source/blender/blenkernel/intern/geometry_component_instances.cc b/source/blender/blenkernel/intern/geometry_component_instances.cc
index 3a065c3576b..be1d9524509 100644
--- a/source/blender/blenkernel/intern/geometry_component_instances.cc
+++ b/source/blender/blenkernel/intern/geometry_component_instances.cc
@@ -16,6 +16,7 @@
#include "BKE_attribute_math.hh"
#include "BKE_geometry_set.hh"
#include "BKE_geometry_set_instances.hh"
+#include "BKE_instances.hh"
#include "attribute_access_intern.hh"
@@ -29,8 +30,8 @@ using blender::MutableSpan;
using blender::Set;
using blender::Span;
using blender::VectorSet;
-
-BLI_CPP_TYPE_MAKE(InstanceReference, InstanceReference, CPPTypeFlags::None)
+using blender::bke::InstanceReference;
+using blender::bke::Instances;
/* -------------------------------------------------------------------- */
/** \name Geometry Component Implementation
@@ -40,339 +41,76 @@ InstancesComponent::InstancesComponent() : GeometryComponent(GEO_COMPONENT_TYPE_
{
}
-GeometryComponent *InstancesComponent::copy() const
-{
- InstancesComponent *new_component = new InstancesComponent();
- new_component->instance_reference_handles_ = instance_reference_handles_;
- new_component->instance_transforms_ = instance_transforms_;
- new_component->references_ = references_;
- new_component->attributes_ = attributes_;
- return new_component;
-}
-
-void InstancesComponent::reserve(int min_capacity)
+InstancesComponent::~InstancesComponent()
{
- instance_reference_handles_.reserve(min_capacity);
- instance_transforms_.reserve(min_capacity);
- attributes_.reallocate(min_capacity);
+ this->clear();
}
-void InstancesComponent::resize(int capacity)
+GeometryComponent *InstancesComponent::copy() const
{
- instance_reference_handles_.resize(capacity);
- instance_transforms_.resize(capacity);
- attributes_.reallocate(capacity);
+ InstancesComponent *new_component = new InstancesComponent();
+ if (instances_ != nullptr) {
+ new_component->instances_ = new Instances(*instances_);
+ new_component->ownership_ = GeometryOwnershipType::Owned;
+ }
+ return new_component;
}
void InstancesComponent::clear()
{
- instance_reference_handles_.clear();
- instance_transforms_.clear();
- attributes_.clear();
- references_.clear();
-}
-
-void InstancesComponent::add_instance(const int instance_handle, const float4x4 &transform)
-{
- BLI_assert(instance_handle >= 0);
- BLI_assert(instance_handle < references_.size());
- instance_reference_handles_.append(instance_handle);
- instance_transforms_.append(transform);
- attributes_.reallocate(this->instances_num());
-}
-
-blender::Span<int> InstancesComponent::instance_reference_handles() const
-{
- return instance_reference_handles_;
-}
-
-blender::MutableSpan<int> InstancesComponent::instance_reference_handles()
-{
- return instance_reference_handles_;
-}
-
-blender::MutableSpan<blender::float4x4> InstancesComponent::instance_transforms()
-{
- return instance_transforms_;
-}
-blender::Span<blender::float4x4> InstancesComponent::instance_transforms() const
-{
- return instance_transforms_;
-}
-
-GeometrySet &InstancesComponent::geometry_set_from_reference(const int reference_index)
-{
- /* If this assert fails, it means #ensure_geometry_instances must be called first or that the
- * reference can't be converted to a geometry set. */
- BLI_assert(references_[reference_index].type() == InstanceReference::Type::GeometrySet);
-
- /* The const cast is okay because the instance's hash in the set
- * is not changed by adjusting the data inside the geometry set. */
- return const_cast<GeometrySet &>(references_[reference_index].geometry_set());
-}
-
-int InstancesComponent::add_reference(const InstanceReference &reference)
-{
- return references_.index_of_or_add_as(reference);
-}
-
-blender::Span<InstanceReference> InstancesComponent::references() const
-{
- return references_;
-}
-
-template<typename T>
-static void copy_data_based_on_mask(Span<T> src, MutableSpan<T> dst, IndexMask mask)
-{
- BLI_assert(src.data() != dst.data());
- using namespace blender;
- threading::parallel_for(mask.index_range(), 1024, [&](IndexRange range) {
- for (const int i : range) {
- dst[i] = src[mask[i]];
- }
- });
-}
-
-void InstancesComponent::remove_instances(const IndexMask mask)
-{
- using namespace blender;
- if (mask.is_range() && mask.as_range().start() == 0) {
- /* Deleting from the end of the array can be much faster since no data has to be shifted. */
- this->resize(mask.size());
- this->remove_unused_references();
- return;
+ BLI_assert(this->is_mutable());
+ if (ownership_ == GeometryOwnershipType::Owned) {
+ delete instances_;
}
-
- Vector<int> new_handles(mask.size());
- copy_data_based_on_mask<int>(this->instance_reference_handles(), new_handles, mask);
- instance_reference_handles_ = std::move(new_handles);
- Vector<float4x4> new_transforms(mask.size());
- copy_data_based_on_mask<float4x4>(this->instance_transforms(), new_transforms, mask);
- instance_transforms_ = std::move(new_transforms);
-
- const bke::CustomDataAttributes &src_attributes = attributes_;
-
- bke::CustomDataAttributes dst_attributes;
- dst_attributes.reallocate(mask.size());
-
- src_attributes.foreach_attribute(
- [&](const bke::AttributeIDRef &id, const bke::AttributeMetaData &meta_data) {
- if (!id.should_be_kept()) {
- return true;
- }
-
- GSpan src = *src_attributes.get_for_read(id);
- dst_attributes.create(id, meta_data.data_type);
- GMutableSpan dst = *dst_attributes.get_for_write(id);
-
- attribute_math::convert_to_static_type(src.type(), [&](auto dummy) {
- using T = decltype(dummy);
- copy_data_based_on_mask<T>(src.typed<T>(), dst.typed<T>(), mask);
- });
- return true;
- },
- ATTR_DOMAIN_INSTANCE);
-
- attributes_ = std::move(dst_attributes);
- this->remove_unused_references();
+ instances_ = nullptr;
}
-void InstancesComponent::remove_unused_references()
+bool InstancesComponent::is_empty() const
{
- using namespace blender;
- using namespace blender::bke;
-
- const int tot_instances = this->instances_num();
- const int tot_references_before = references_.size();
-
- if (tot_instances == 0) {
- /* If there are no instances, no reference is needed. */
- references_.clear();
- return;
- }
- if (tot_references_before == 1) {
- /* There is only one reference and at least one instance. So the only existing reference is
- * used. Nothing to do here. */
- return;
- }
-
- Array<bool> usage_by_handle(tot_references_before, false);
- std::mutex mutex;
-
- /* Loop over all instances to see which references are used. */
- threading::parallel_for(IndexRange(tot_instances), 1000, [&](IndexRange range) {
- /* Use local counter to avoid lock contention. */
- Array<bool> local_usage_by_handle(tot_references_before, false);
-
- for (const int i : range) {
- const int handle = instance_reference_handles_[i];
- BLI_assert(handle >= 0 && handle < tot_references_before);
- local_usage_by_handle[handle] = true;
- }
-
- std::lock_guard lock{mutex};
- for (const int i : IndexRange(tot_references_before)) {
- usage_by_handle[i] |= local_usage_by_handle[i];
- }
- });
-
- if (!usage_by_handle.as_span().contains(false)) {
- /* All references are used. */
- return;
- }
-
- /* Create new references and a mapping for the handles. */
- Vector<int> handle_mapping;
- VectorSet<InstanceReference> new_references;
- int next_new_handle = 0;
- bool handles_have_to_be_updated = false;
- for (const int old_handle : IndexRange(tot_references_before)) {
- if (!usage_by_handle[old_handle]) {
- /* Add some dummy value. It won't be read again. */
- handle_mapping.append(-1);
- }
- else {
- const InstanceReference &reference = references_[old_handle];
- handle_mapping.append(next_new_handle);
- new_references.add_new(reference);
- if (old_handle != next_new_handle) {
- handles_have_to_be_updated = true;
- }
- next_new_handle++;
+ if (instances_ != nullptr) {
+ if (instances_->instances_num() > 0) {
+ return false;
}
}
- references_ = new_references;
-
- if (!handles_have_to_be_updated) {
- /* All remaining handles are the same as before, so they don't have to be updated. This happens
- * when unused handles are only at the end. */
- return;
- }
-
- /* Update handles of instances. */
- threading::parallel_for(IndexRange(tot_instances), 1000, [&](IndexRange range) {
- for (const int i : range) {
- instance_reference_handles_[i] = handle_mapping[instance_reference_handles_[i]];
- }
- });
-}
-
-int InstancesComponent::instances_num() const
-{
- return instance_transforms_.size();
-}
-
-int InstancesComponent::references_num() const
-{
- return references_.size();
-}
-
-bool InstancesComponent::is_empty() const
-{
- return this->instance_reference_handles_.size() == 0;
+ return true;
}
bool InstancesComponent::owns_direct_data() const
{
- for (const InstanceReference &reference : references_) {
- if (!reference.owns_direct_data()) {
- return false;
- }
+ if (instances_ != nullptr) {
+ return instances_->owns_direct_data();
}
return true;
}
void InstancesComponent::ensure_owns_direct_data()
{
- BLI_assert(this->is_mutable());
- for (const InstanceReference &const_reference : references_) {
- /* Const cast is fine because we are not changing anything that would change the hash of the
- * reference. */
- InstanceReference &reference = const_cast<InstanceReference &>(const_reference);
- reference.ensure_owns_direct_data();
+ if (instances_ != nullptr) {
+ instances_->ensure_owns_direct_data();
}
}
-static blender::Array<int> generate_unique_instance_ids(Span<int> original_ids)
+const blender::bke::Instances *InstancesComponent::get_for_read() const
{
- using namespace blender;
- Array<int> unique_ids(original_ids.size());
-
- Set<int> used_unique_ids;
- used_unique_ids.reserve(original_ids.size());
- Vector<int> instances_with_id_collision;
- for (const int instance_index : original_ids.index_range()) {
- const int original_id = original_ids[instance_index];
- if (used_unique_ids.add(original_id)) {
- /* The original id has not been used by another instance yet. */
- unique_ids[instance_index] = original_id;
- }
- else {
- /* The original id of this instance collided with a previous instance, it needs to be looked
- * at again in a second pass. Don't generate a new random id here, because this might collide
- * with other existing ids. */
- instances_with_id_collision.append(instance_index);
- }
- }
-
- Map<int, RandomNumberGenerator> generator_by_original_id;
- for (const int instance_index : instances_with_id_collision) {
- const int original_id = original_ids[instance_index];
- RandomNumberGenerator &rng = generator_by_original_id.lookup_or_add_cb(original_id, [&]() {
- RandomNumberGenerator rng;
- rng.seed_random(original_id);
- return rng;
- });
-
- const int max_iteration = 100;
- for (int iteration = 0;; iteration++) {
- /* Try generating random numbers until an unused one has been found. */
- const int random_id = rng.get_int32();
- if (used_unique_ids.add(random_id)) {
- /* This random id is not used by another instance. */
- unique_ids[instance_index] = random_id;
- break;
- }
- if (iteration == max_iteration) {
- /* It seems to be very unlikely that we ever run into this case (assuming there are less
- * than 2^30 instances). However, if that happens, it's better to use an id that is not
- * unique than to be stuck in an infinite loop. */
- unique_ids[instance_index] = original_id;
- break;
- }
- }
- }
-
- return unique_ids;
+ return instances_;
}
-blender::Span<int> InstancesComponent::almost_unique_ids() const
+blender::bke::Instances *InstancesComponent::get_for_write()
{
- std::lock_guard lock(almost_unique_ids_mutex_);
- std::optional<GSpan> instance_ids_gspan = attributes_.get_for_read("id");
- if (instance_ids_gspan) {
- Span<int> instance_ids = instance_ids_gspan->typed<int>();
- if (almost_unique_ids_.size() != instance_ids.size()) {
- almost_unique_ids_ = generate_unique_instance_ids(instance_ids);
- }
- }
- else {
- almost_unique_ids_.reinitialize(this->instances_num());
- for (const int i : almost_unique_ids_.index_range()) {
- almost_unique_ids_[i] = i;
- }
+ BLI_assert(this->is_mutable());
+ if (ownership_ == GeometryOwnershipType::ReadOnly) {
+ instances_ = new Instances(*instances_);
+ ownership_ = GeometryOwnershipType::Owned;
}
- return almost_unique_ids_;
+ return instances_;
}
-blender::bke::CustomDataAttributes &InstancesComponent::instance_attributes()
+void InstancesComponent::replace(Instances *instances, GeometryOwnershipType ownership)
{
- return this->attributes_;
-}
-
-const blender::bke::CustomDataAttributes &InstancesComponent::instance_attributes() const
-{
- return this->attributes_;
+ BLI_assert(this->is_mutable());
+ this->clear();
+ instances_ = instances;
+ ownership_ = ownership;
}
namespace blender::bke {
@@ -397,33 +135,38 @@ class InstancePositionAttributeProvider final : public BuiltinAttributeProvider
GVArray try_get_for_read(const void *owner) const final
{
- const InstancesComponent &instances_component = *static_cast<const InstancesComponent *>(
- owner);
- Span<float4x4> transforms = instances_component.instance_transforms();
+ const Instances *instances = static_cast<const Instances *>(owner);
+ if (instances == nullptr) {
+ return {};
+ }
+ Span<float4x4> transforms = instances->transforms();
return VArray<float3>::ForDerivedSpan<float4x4, get_transform_position>(transforms);
}
GAttributeWriter try_get_for_write(void *owner) const final
{
- InstancesComponent &instances_component = *static_cast<InstancesComponent *>(owner);
- MutableSpan<float4x4> transforms = instances_component.instance_transforms();
+ Instances *instances = static_cast<Instances *>(owner);
+ if (instances == nullptr) {
+ return {};
+ }
+ MutableSpan<float4x4> transforms = instances->transforms();
return {VMutableArray<float3>::ForDerivedSpan<float4x4,
get_transform_position,
set_transform_position>(transforms),
domain_};
}
- bool try_delete(void *UNUSED(owner)) const final
+ bool try_delete(void * /*owner*/) const final
{
return false;
}
- bool try_create(void *UNUSED(owner), const AttributeInit &UNUSED(initializer)) const final
+ bool try_create(void * /*owner*/, const AttributeInit & /*initializer*/) const final
{
return false;
}
- bool exists(const void *UNUSED(owner)) const final
+ bool exists(const void * /*owner*/) const final
{
return true;
}
@@ -434,16 +177,16 @@ static ComponentAttributeProviders create_attribute_providers_for_instances()
static InstancePositionAttributeProvider position;
static CustomDataAccessInfo instance_custom_data_access = {
[](void *owner) -> CustomData * {
- InstancesComponent &inst = *static_cast<InstancesComponent *>(owner);
- return &inst.instance_attributes().data;
+ Instances *instances = static_cast<Instances *>(owner);
+ return &instances->custom_data_attributes().data;
},
[](const void *owner) -> const CustomData * {
- const InstancesComponent &inst = *static_cast<const InstancesComponent *>(owner);
- return &inst.instance_attributes().data;
+ const Instances *instances = static_cast<const Instances *>(owner);
+ return &instances->custom_data_attributes().data;
},
[](const void *owner) -> int {
- const InstancesComponent &inst = *static_cast<const InstancesComponent *>(owner);
- return inst.instances_num();
+ const Instances *instances = static_cast<const Instances *>(owner);
+ return instances->instances_num();
}};
/**
@@ -479,18 +222,18 @@ static AttributeAccessorFunctions get_instances_accessor_functions()
if (owner == nullptr) {
return 0;
}
- const InstancesComponent &instances = *static_cast<const InstancesComponent *>(owner);
+ const Instances *instances = static_cast<const Instances *>(owner);
switch (domain) {
case ATTR_DOMAIN_INSTANCE:
- return instances.instances_num();
+ return instances->instances_num();
default:
return 0;
}
};
- fn.domain_supported = [](const void *UNUSED(owner), const eAttrDomain domain) {
+ fn.domain_supported = [](const void * /*owner*/, const eAttrDomain domain) {
return domain == ATTR_DOMAIN_INSTANCE;
};
- fn.adapt_domain = [](const void *UNUSED(owner),
+ fn.adapt_domain = [](const void * /*owner*/,
const blender::GVArray &varray,
const eAttrDomain from_domain,
const eAttrDomain to_domain) {
@@ -508,18 +251,30 @@ static const AttributeAccessorFunctions &get_instances_accessor_functions_ref()
return fn;
}
+blender::bke::AttributeAccessor Instances::attributes() const
+{
+ return blender::bke::AttributeAccessor(this,
+ blender::bke::get_instances_accessor_functions_ref());
+}
+
+blender::bke::MutableAttributeAccessor Instances::attributes_for_write()
+{
+ return blender::bke::MutableAttributeAccessor(
+ this, blender::bke::get_instances_accessor_functions_ref());
+}
+
} // namespace blender::bke
std::optional<blender::bke::AttributeAccessor> InstancesComponent::attributes() const
{
- return blender::bke::AttributeAccessor(this,
+ return blender::bke::AttributeAccessor(instances_,
blender::bke::get_instances_accessor_functions_ref());
}
std::optional<blender::bke::MutableAttributeAccessor> InstancesComponent::attributes_for_write()
{
return blender::bke::MutableAttributeAccessor(
- this, blender::bke::get_instances_accessor_functions_ref());
+ instances_, blender::bke::get_instances_accessor_functions_ref());
}
/** \} */
diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc
index 715c7d6c743..d148d59a48b 100644
--- a/source/blender/blenkernel/intern/geometry_component_mesh.cc
+++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc
@@ -13,6 +13,9 @@
#include "BKE_geometry_set.hh"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
+
+#include "FN_multi_function_builder.hh"
#include "attribute_access_intern.hh"
@@ -211,27 +214,30 @@ void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh,
}
/* Deselect loose vertices without corners that are still selected from the 'true' default. */
- for (const int vert_index : IndexRange(mesh.totvert)) {
- if (loose_verts[vert_index]) {
- r_values[vert_index] = false;
+ /* The record fact says that the value is true.
+ *Writing to the array from different threads is okay because each thread sets the same value. */
+ threading::parallel_for(loose_verts.index_range(), 2048, [&](const IndexRange range) {
+ for (const int vert_index : range) {
+ if (loose_verts[vert_index]) {
+ r_values[vert_index] = false;
+ }
}
- }
+ });
}
static GVArray adapt_mesh_domain_corner_to_point(const Mesh &mesh, const GVArray &varray)
{
- GVArray new_varray;
+ GArray<> values(varray.type(), mesh.totvert);
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
/* We compute all interpolated values at once, because for this interpolation, one has to
* iterate over all loops anyway. */
- Array<T> values(mesh.totvert);
- adapt_mesh_domain_corner_to_point_impl<T>(mesh, varray.typed<T>(), values);
- new_varray = VArray<T>::ForContainer(std::move(values));
+ adapt_mesh_domain_corner_to_point_impl<T>(
+ mesh, varray.typed<T>(), values.as_mutable_span().typed<T>());
}
});
- return new_varray;
+ return GVArray::ForGArray(std::move(values));
}
/**
@@ -366,16 +372,15 @@ void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh,
static GVArray adapt_mesh_domain_corner_to_edge(const Mesh &mesh, const GVArray &varray)
{
- GVArray new_varray;
+ GArray<> values(varray.type(), mesh.totedge);
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
- Array<T> values(mesh.totedge);
- adapt_mesh_domain_corner_to_edge_impl<T>(mesh, varray.typed<T>(), values);
- new_varray = VArray<T>::ForContainer(std::move(values));
+ adapt_mesh_domain_corner_to_edge_impl<T>(
+ mesh, varray.typed<T>(), values.as_mutable_span().typed<T>());
}
});
- return new_varray;
+ return GVArray::ForGArray(std::move(values));
}
template<typename T>
@@ -413,30 +418,29 @@ void adapt_mesh_domain_face_to_point_impl(const Mesh &mesh,
const Span<MLoop> loops = mesh.loops();
r_values.fill(false);
- for (const int poly_index : polys.index_range()) {
- const MPoly &poly = polys[poly_index];
- if (old_values[poly_index]) {
- for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
- const MLoop &loop = loops[loop_index];
- const int vert_index = loop.v;
- r_values[vert_index] = true;
+ threading::parallel_for(polys.index_range(), 2048, [&](const IndexRange range) {
+ for (const int poly_index : range) {
+ if (old_values[poly_index]) {
+ const MPoly &poly = polys[poly_index];
+ for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
+ r_values[loop.v] = true;
+ }
}
}
- }
+ });
}
static GVArray adapt_mesh_domain_face_to_point(const Mesh &mesh, const GVArray &varray)
{
- GVArray new_varray;
+ GArray<> values(varray.type(), mesh.totvert);
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
- Array<T> values(mesh.totvert);
- adapt_mesh_domain_face_to_point_impl<T>(mesh, varray.typed<T>(), values);
- new_varray = VArray<T>::ForContainer(std::move(values));
+ adapt_mesh_domain_face_to_point_impl<T>(
+ mesh, varray.typed<T>(), values.as_mutable_span().typed<T>());
}
});
- return new_varray;
+ return GVArray::ForGArray(std::move(values));
}
/* Each corner's value is simply a copy of the value at its face. */
@@ -459,16 +463,15 @@ void adapt_mesh_domain_face_to_corner_impl(const Mesh &mesh,
static GVArray adapt_mesh_domain_face_to_corner(const Mesh &mesh, const GVArray &varray)
{
- GVArray new_varray;
+ GArray<> values(varray.type(), mesh.totloop);
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
- Array<T> values(mesh.totloop);
- adapt_mesh_domain_face_to_corner_impl<T>(mesh, varray.typed<T>(), values);
- new_varray = VArray<T>::ForContainer(std::move(values));
+ adapt_mesh_domain_face_to_corner_impl<T>(
+ mesh, varray.typed<T>(), values.as_mutable_span().typed<T>());
}
});
- return new_varray;
+ return GVArray::ForGArray(std::move(values));
}
template<typename T>
@@ -504,30 +507,29 @@ void adapt_mesh_domain_face_to_edge_impl(const Mesh &mesh,
const Span<MLoop> loops = mesh.loops();
r_values.fill(false);
- for (const int poly_index : polys.index_range()) {
- const MPoly &poly = polys[poly_index];
- if (old_values[poly_index]) {
- for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
- const MLoop &loop = loops[loop_index];
- const int edge_index = loop.e;
- r_values[edge_index] = true;
+ threading::parallel_for(polys.index_range(), 2048, [&](const IndexRange range) {
+ for (const int poly_index : range) {
+ if (old_values[poly_index]) {
+ const MPoly &poly = polys[poly_index];
+ for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
+ r_values[loop.e] = true;
+ }
}
}
- }
+ });
}
static GVArray adapt_mesh_domain_face_to_edge(const Mesh &mesh, const GVArray &varray)
{
- GVArray new_varray;
+ GArray<> values(varray.type(), mesh.totedge);
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
- Array<T> values(mesh.totedge);
- adapt_mesh_domain_face_to_edge_impl<T>(mesh, varray.typed<T>(), values);
- new_varray = VArray<T>::ForContainer(std::move(values));
+ adapt_mesh_domain_face_to_edge_impl<T>(
+ mesh, varray.typed<T>(), values.as_mutable_span().typed<T>());
}
});
- return new_varray;
+ return GVArray::ForGArray(std::move(values));
}
static GVArray adapt_mesh_domain_point_to_face(const Mesh &mesh, const GVArray &varray)
@@ -622,7 +624,7 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh,
/* For every corner, mix the values from the adjacent edges on the face. */
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
- const int loop_index_prev = loop_index - 1 + (loop_index == poly.loopstart) * poly.totloop;
+ const int loop_index_prev = mesh_topology::previous_poly_loop(poly, loop_index);
const MLoop &loop = loops[loop_index];
const MLoop &loop_prev = loops[loop_index_prev];
mixer.mix_in(loop_index, old_values[loop.e]);
@@ -645,31 +647,32 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh,
r_values.fill(false);
- for (const int poly_index : polys.index_range()) {
- const MPoly &poly = polys[poly_index];
- for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
- const int loop_index_prev = loop_index - 1 + (loop_index == poly.loopstart) * poly.totloop;
- const MLoop &loop = loops[loop_index];
- const MLoop &loop_prev = loops[loop_index_prev];
- if (old_values[loop.e] && old_values[loop_prev.e]) {
- r_values[loop_index] = true;
+ threading::parallel_for(polys.index_range(), 2048, [&](const IndexRange range) {
+ for (const int poly_index : range) {
+ const MPoly &poly = polys[poly_index];
+ for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
+ const int loop_index_prev = mesh_topology::previous_poly_loop(poly, loop_index);
+ const MLoop &loop = loops[loop_index];
+ const MLoop &loop_prev = loops[loop_index_prev];
+ if (old_values[loop.e] && old_values[loop_prev.e]) {
+ r_values[loop_index] = true;
+ }
}
}
- }
+ });
}
static GVArray adapt_mesh_domain_edge_to_corner(const Mesh &mesh, const GVArray &varray)
{
- GVArray new_varray;
+ GArray<> values(varray.type(), mesh.totloop);
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
- Array<T> values(mesh.totloop);
- adapt_mesh_domain_edge_to_corner_impl<T>(mesh, varray.typed<T>(), values);
- new_varray = VArray<T>::ForContainer(std::move(values));
+ adapt_mesh_domain_edge_to_corner_impl<T>(
+ mesh, varray.typed<T>(), values.as_mutable_span().typed<T>());
}
});
- return new_varray;
+ return GVArray::ForGArray(std::move(values));
}
template<typename T>
@@ -701,28 +704,31 @@ void adapt_mesh_domain_edge_to_point_impl(const Mesh &mesh,
BLI_assert(r_values.size() == mesh.totvert);
const Span<MEdge> edges = mesh.edges();
+ /* Multiple threads can write to the same index here, but they are only
+ * writing true, and writing to single bytes is expected to be threadsafe. */
r_values.fill(false);
- for (const int edge_index : edges.index_range()) {
- const MEdge &edge = edges[edge_index];
- if (old_values[edge_index]) {
- r_values[edge.v1] = true;
- r_values[edge.v2] = true;
+ threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
+ for (const int edge_index : range) {
+ if (old_values[edge_index]) {
+ const MEdge &edge = edges[edge_index];
+ r_values[edge.v1] = true;
+ r_values[edge.v2] = true;
+ }
}
- }
+ });
}
static GVArray adapt_mesh_domain_edge_to_point(const Mesh &mesh, const GVArray &varray)
{
- GVArray new_varray;
+ GArray<> values(varray.type(), mesh.totvert);
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
- Array<T> values(mesh.totvert);
- adapt_mesh_domain_edge_to_point_impl<T>(mesh, varray.typed<T>(), values);
- new_varray = VArray<T>::ForContainer(std::move(values));
+ adapt_mesh_domain_edge_to_point_impl<T>(
+ mesh, varray.typed<T>(), values.as_mutable_span().typed<T>());
}
});
- return new_varray;
+ return GVArray::ForGArray(std::move(values));
}
static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &varray)
@@ -770,6 +776,30 @@ static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &v
} // namespace blender::bke
+static bool can_simple_adapt_for_single(const eAttrDomain from_domain, const eAttrDomain to_domain)
+{
+ /* For some domain combinations, a single value will always map directly. For others, there may
+ * be loose elements on the result domain that should have the default value rather than the
+ * single value from the source. */
+ switch (from_domain) {
+ case ATTR_DOMAIN_POINT:
+ /* All other domains are always connected to points. */
+ return true;
+ case ATTR_DOMAIN_EDGE:
+ /* There may be loose vertices not connected to edges. */
+ return ELEM(to_domain, ATTR_DOMAIN_FACE, ATTR_DOMAIN_CORNER);
+ case ATTR_DOMAIN_FACE:
+ /* There may be loose vertices or edges not connected to faces. */
+ return to_domain == ATTR_DOMAIN_CORNER;
+ case ATTR_DOMAIN_CORNER:
+ /* Only faces are always connected to corners. */
+ return to_domain == ATTR_DOMAIN_FACE;
+ default:
+ BLI_assert_unreachable();
+ return false;
+ }
+}
+
static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
const blender::GVArray &varray,
const eAttrDomain from_domain,
@@ -784,6 +814,14 @@ static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
if (from_domain == to_domain) {
return varray;
}
+ if (varray.is_single()) {
+ if (can_simple_adapt_for_single(from_domain, to_domain)) {
+ BUFFER_FOR_CPP_TYPE_VALUE(varray.type(), value);
+ varray.get_internal_single(value);
+ return blender::GVArray::ForSingle(
+ varray.type(), mesh.attributes().domain_size(to_domain), value);
+ }
+ }
switch (from_domain) {
case ATTR_DOMAIN_CORNER: {
@@ -902,14 +940,14 @@ static void set_loop_uv(MLoopUV &uv, float2 co)
copy_v2_v2(uv.uv, co);
}
-static float get_crease(const MEdge &edge)
+static float get_crease(const float &crease)
{
- return edge.crease / 255.0f;
+ return crease;
}
-static void set_crease(MEdge &edge, float value)
+static void set_crease(float &crease, const float value)
{
- edge.crease = round_fl_to_uchar_clamp(value * 255.0f);
+ crease = std::clamp(value, 0.0f, 1.0f);
}
class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl<float> {
@@ -1130,17 +1168,17 @@ class NormalAttributeProvider final : public BuiltinAttributeProvider {
return VArray<float3>::ForSpan({(float3 *)BKE_mesh_poly_normals_ensure(mesh), mesh->totpoly});
}
- GAttributeWriter try_get_for_write(void *UNUSED(owner)) const final
+ GAttributeWriter try_get_for_write(void * /*owner*/) const final
{
return {};
}
- bool try_delete(void *UNUSED(owner)) const final
+ bool try_delete(void * /*owner*/) const final
{
return false;
}
- bool try_create(void *UNUSED(owner), const AttributeInit &UNUSED(initializer)) const final
+ bool try_create(void * /*owner*/, const AttributeInit & /*initializer*/) const final
{
return false;
}
@@ -1217,6 +1255,13 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
make_array_write_attribute<int>,
nullptr);
+ static const fn::CustomMF_SI_SO<int, int> material_index_clamp{
+ "Material Index Validate",
+ [](int value) {
+ /* Use #short for the maximum since many areas still use that type for indices. */
+ return std::clamp<int>(value, 0, std::numeric_limits<short>::max());
+ },
+ fn::CustomMF_presets::AllSpanOrSingle()};
static BuiltinCustomDataLayerProvider material_index("material_index",
ATTR_DOMAIN_FACE,
CD_PROP_INT32,
@@ -1227,7 +1272,8 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
face_access,
make_array_read_attribute<int>,
make_array_write_attribute<int>,
- nullptr);
+ nullptr,
+ AttributeValidator{&material_index_clamp});
static BuiltinCustomDataLayerProvider shade_smooth(
"shade_smooth",
@@ -1246,13 +1292,13 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
"crease",
ATTR_DOMAIN_EDGE,
CD_PROP_FLOAT,
- CD_MEDGE,
- BuiltinAttributeProvider::NonCreatable,
+ CD_CREASE,
+ BuiltinAttributeProvider::Creatable,
BuiltinAttributeProvider::Writable,
- BuiltinAttributeProvider::NonDeletable,
+ BuiltinAttributeProvider::Deletable,
edge_access,
- make_derived_read_attribute<MEdge, float, get_crease>,
- make_derived_write_attribute<MEdge, float, get_crease, set_crease>,
+ make_array_read_attribute<float>,
+ make_derived_write_attribute<float, float, get_crease, set_crease>,
nullptr);
static NamedLegacyCustomDataProvider uvs(
@@ -1302,7 +1348,7 @@ static AttributeAccessorFunctions get_mesh_accessor_functions()
return 0;
}
};
- fn.domain_supported = [](const void *UNUSED(owner), const eAttrDomain domain) {
+ fn.domain_supported = [](const void * /*owner*/, const eAttrDomain domain) {
return ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE, ATTR_DOMAIN_FACE, ATTR_DOMAIN_CORNER);
};
fn.adapt_domain = [](const void *owner,
diff --git a/source/blender/blenkernel/intern/geometry_component_pointcloud.cc b/source/blender/blenkernel/intern/geometry_component_pointcloud.cc
index 6980b561bc3..34cc99d2f92 100644
--- a/source/blender/blenkernel/intern/geometry_component_pointcloud.cc
+++ b/source/blender/blenkernel/intern/geometry_component_pointcloud.cc
@@ -180,10 +180,10 @@ static AttributeAccessorFunctions get_pointcloud_accessor_functions()
return 0;
}
};
- fn.domain_supported = [](const void *UNUSED(owner), const eAttrDomain domain) {
+ fn.domain_supported = [](const void * /*owner*/, const eAttrDomain domain) {
return domain == ATTR_DOMAIN_POINT;
};
- fn.adapt_domain = [](const void *UNUSED(owner),
+ fn.adapt_domain = [](const void * /*owner*/,
const blender::GVArray &varray,
const eAttrDomain from_domain,
const eAttrDomain to_domain) {
diff --git a/source/blender/blenkernel/intern/geometry_fields.cc b/source/blender/blenkernel/intern/geometry_fields.cc
index 56e9e9dcdff..82ffda57398 100644
--- a/source/blender/blenkernel/intern/geometry_fields.cc
+++ b/source/blender/blenkernel/intern/geometry_fields.cc
@@ -4,6 +4,7 @@
#include "BKE_curves.hh"
#include "BKE_geometry_fields.hh"
#include "BKE_geometry_set.hh"
+#include "BKE_instances.hh"
#include "BKE_mesh.h"
#include "BKE_pointcloud.h"
#include "BKE_type_conversions.hh"
@@ -64,7 +65,7 @@ GeometryFieldContext::GeometryFieldContext(const GeometryComponent &component,
case GEO_COMPONENT_TYPE_INSTANCES: {
const InstancesComponent &instances_component = static_cast<const InstancesComponent &>(
component);
- geometry_ = &instances_component;
+ geometry_ = instances_component.get_for_read();
break;
}
case GEO_COMPONENT_TYPE_VOLUME:
@@ -86,7 +87,7 @@ GeometryFieldContext::GeometryFieldContext(const PointCloud &points)
: geometry_(&points), type_(GEO_COMPONENT_TYPE_POINT_CLOUD), domain_(ATTR_DOMAIN_POINT)
{
}
-GeometryFieldContext::GeometryFieldContext(const InstancesComponent &instances)
+GeometryFieldContext::GeometryFieldContext(const Instances &instances)
: geometry_(&instances), type_(GEO_COMPONENT_TYPE_INSTANCES), domain_(ATTR_DOMAIN_INSTANCE)
{
}
@@ -102,7 +103,7 @@ std::optional<AttributeAccessor> GeometryFieldContext::attributes() const
if (const PointCloud *pointcloud = this->pointcloud()) {
return pointcloud->attributes();
}
- if (const InstancesComponent *instances = this->instances()) {
+ if (const Instances *instances = this->instances()) {
return instances->attributes();
}
return {};
@@ -124,11 +125,10 @@ const PointCloud *GeometryFieldContext::pointcloud() const
static_cast<const PointCloud *>(geometry_) :
nullptr;
}
-const InstancesComponent *GeometryFieldContext::instances() const
+const Instances *GeometryFieldContext::instances() const
{
- return this->type() == GEO_COMPONENT_TYPE_INSTANCES ?
- static_cast<const InstancesComponent *>(geometry_) :
- nullptr;
+ return this->type() == GEO_COMPONENT_TYPE_INSTANCES ? static_cast<const Instances *>(geometry_) :
+ nullptr;
}
GVArray GeometryFieldInput::get_varray_for_context(const fn::FieldContext &context,
@@ -157,6 +157,12 @@ GVArray GeometryFieldInput::get_varray_for_context(const fn::FieldContext &conte
return {};
}
+std::optional<eAttrDomain> GeometryFieldInput::preferred_domain(
+ const GeometryComponent & /*component*/) const
+{
+ return std::nullopt;
+}
+
GVArray MeshFieldInput::get_varray_for_context(const fn::FieldContext &context,
const IndexMask mask,
ResourceScope & /*scope*/) const
@@ -173,6 +179,11 @@ GVArray MeshFieldInput::get_varray_for_context(const fn::FieldContext &context,
return {};
}
+std::optional<eAttrDomain> MeshFieldInput::preferred_domain(const Mesh & /*mesh*/) const
+{
+ return std::nullopt;
+}
+
GVArray CurvesFieldInput::get_varray_for_context(const fn::FieldContext &context,
IndexMask mask,
ResourceScope & /*scope*/) const
@@ -190,6 +201,12 @@ GVArray CurvesFieldInput::get_varray_for_context(const fn::FieldContext &context
return {};
}
+std::optional<eAttrDomain> CurvesFieldInput::preferred_domain(
+ const CurvesGeometry & /*curves*/) const
+{
+ return std::nullopt;
+}
+
GVArray PointCloudFieldInput::get_varray_for_context(const fn::FieldContext &context,
IndexMask mask,
ResourceScope & /*scope*/) const
@@ -213,7 +230,7 @@ GVArray InstancesFieldInput::get_varray_for_context(const fn::FieldContext &cont
{
if (const GeometryFieldContext *geometry_context = dynamic_cast<const GeometryFieldContext *>(
&context)) {
- if (const InstancesComponent *instances = geometry_context->instances()) {
+ if (const Instances *instances = geometry_context->instances()) {
return this->get_varray_for_context(*instances, mask);
}
}
@@ -225,7 +242,7 @@ GVArray InstancesFieldInput::get_varray_for_context(const fn::FieldContext &cont
}
GVArray AttributeFieldInput::get_varray_for_context(const GeometryFieldContext &context,
- IndexMask UNUSED(mask)) const
+ const IndexMask /*mask*/) const
{
const eCustomDataType data_type = cpp_type_to_custom_data_type(*type_);
if (auto attributes = context.attributes()) {
@@ -254,6 +271,20 @@ bool AttributeFieldInput::is_equal_to(const fn::FieldNode &other) const
return false;
}
+std::optional<eAttrDomain> AttributeFieldInput::preferred_domain(
+ const GeometryComponent &component) const
+{
+ const std::optional<AttributeAccessor> attributes = component.attributes();
+ if (!attributes.has_value()) {
+ return std::nullopt;
+ }
+ const std::optional<AttributeMetaData> meta_data = attributes->lookup_meta_data(name_);
+ if (!meta_data.has_value()) {
+ return std::nullopt;
+ }
+ return meta_data->domain;
+}
+
static StringRef get_random_id_attribute_name(const eAttrDomain domain)
{
switch (domain) {
@@ -325,6 +356,21 @@ bool AnonymousAttributeFieldInput::is_equal_to(const fn::FieldNode &other) const
return false;
}
+std::optional<eAttrDomain> AnonymousAttributeFieldInput::preferred_domain(
+ const GeometryComponent &component) const
+{
+ const std::optional<AttributeAccessor> attributes = component.attributes();
+ if (!attributes.has_value()) {
+ return std::nullopt;
+ }
+ const std::optional<AttributeMetaData> meta_data = attributes->lookup_meta_data(
+ anonymous_id_.get());
+ if (!meta_data.has_value()) {
+ return std::nullopt;
+ }
+ return meta_data->domain;
+}
+
} // namespace blender::bke
/* -------------------------------------------------------------------- */
@@ -360,6 +406,134 @@ bool NormalFieldInput::is_equal_to(const fn::FieldNode &other) const
return dynamic_cast<const NormalFieldInput *>(&other) != nullptr;
}
+bool try_capture_field_on_geometry(GeometryComponent &component,
+ const AttributeIDRef &attribute_id,
+ const eAttrDomain domain,
+ const fn::GField &field)
+{
+ MutableAttributeAccessor attributes = *component.attributes_for_write();
+ const int domain_size = attributes.domain_size(domain);
+ const CPPType &type = field.cpp_type();
+ const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(type);
+
+ if (domain_size == 0) {
+ return attributes.add(attribute_id, domain, data_type, AttributeInitConstruct{});
+ }
+
+ bke::GeometryFieldContext field_context{component, domain};
+ const IndexMask mask{IndexMask(domain_size)};
+ const bke::AttributeValidator validator = attributes.lookup_validator(attribute_id);
+
+ /* Could avoid allocating a new buffer if:
+ * - We are writing to an attribute that exists already with the correct domain and type.
+ * - The field does not depend on that attribute (we can't easily check for that yet). */
+ void *buffer = MEM_mallocN(type.size() * domain_size, __func__);
+
+ fn::FieldEvaluator evaluator{field_context, &mask};
+ evaluator.add_with_destination(validator.validate_field_if_necessary(field),
+ GMutableSpan{type, buffer, domain_size});
+ evaluator.evaluate();
+
+ if (GAttributeWriter attribute = attributes.lookup_for_write(attribute_id)) {
+ if (attribute.domain == domain && attribute.varray.type() == type) {
+ attribute.varray.set_all(buffer);
+ attribute.finish();
+ type.destruct_n(buffer, domain_size);
+ MEM_freeN(buffer);
+ return true;
+ }
+ }
+ attributes.remove(attribute_id);
+ if (attributes.add(attribute_id, domain, data_type, bke::AttributeInitMoveArray{buffer})) {
+ return true;
+ }
+
+ /* If the name corresponds to a builtin attribute, removing the attribute might fail if
+ * it's required, and adding the attribute might fail if the domain or type is incorrect. */
+ type.destruct_n(buffer, domain_size);
+ MEM_freeN(buffer);
+ return false;
+}
+
+std::optional<eAttrDomain> try_detect_field_domain(const GeometryComponent &component,
+ const fn::GField &field)
+{
+ const GeometryComponentType component_type = component.type();
+ if (component_type == GEO_COMPONENT_TYPE_POINT_CLOUD) {
+ return ATTR_DOMAIN_POINT;
+ }
+ if (component_type == GEO_COMPONENT_TYPE_INSTANCES) {
+ return ATTR_DOMAIN_INSTANCE;
+ }
+ const std::shared_ptr<const fn::FieldInputs> &field_inputs = field.node().field_inputs();
+ if (!field_inputs) {
+ return std::nullopt;
+ }
+ std::optional<eAttrDomain> output_domain;
+ auto handle_domain = [&](const std::optional<eAttrDomain> domain) {
+ if (!domain.has_value()) {
+ return false;
+ }
+ if (output_domain.has_value()) {
+ if (*output_domain != *domain) {
+ return false;
+ }
+ return true;
+ }
+ output_domain = domain;
+ return true;
+ };
+ if (component_type == GEO_COMPONENT_TYPE_MESH) {
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ const Mesh *mesh = mesh_component.get_for_read();
+ if (mesh == nullptr) {
+ return std::nullopt;
+ }
+ for (const fn::FieldInput &field_input : field_inputs->deduplicated_nodes) {
+ if (const auto *geometry_field_input = dynamic_cast<const GeometryFieldInput *>(
+ &field_input)) {
+ if (!handle_domain(geometry_field_input->preferred_domain(component))) {
+ return std::nullopt;
+ }
+ }
+ else if (const auto *mesh_field_input = dynamic_cast<const MeshFieldInput *>(&field_input)) {
+ if (!handle_domain(mesh_field_input->preferred_domain(*mesh))) {
+ return std::nullopt;
+ }
+ }
+ else {
+ return std::nullopt;
+ }
+ }
+ }
+ if (component_type == GEO_COMPONENT_TYPE_CURVE) {
+ const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
+ const Curves *curves = curve_component.get_for_read();
+ if (curves == nullptr) {
+ return std::nullopt;
+ }
+ for (const fn::FieldInput &field_input : field_inputs->deduplicated_nodes) {
+ if (const auto *geometry_field_input = dynamic_cast<const GeometryFieldInput *>(
+ &field_input)) {
+ if (!handle_domain(geometry_field_input->preferred_domain(component))) {
+ return std::nullopt;
+ }
+ }
+ else if (const auto *curves_field_input = dynamic_cast<const CurvesFieldInput *>(
+ &field_input)) {
+ if (!handle_domain(
+ curves_field_input->preferred_domain(CurvesGeometry::wrap(curves->geometry)))) {
+ return std::nullopt;
+ }
+ }
+ else {
+ return std::nullopt;
+ }
+ }
+ }
+ return output_domain;
+}
+
} // namespace blender::bke
/** \} */
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc
index 46ff8141504..ee4c398c3d6 100644
--- a/source/blender/blenkernel/intern/geometry_set.cc
+++ b/source/blender/blenkernel/intern/geometry_set.cc
@@ -9,6 +9,7 @@
#include "BKE_attribute.h"
#include "BKE_curves.hh"
#include "BKE_geometry_set.hh"
+#include "BKE_instances.hh"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh_wrapper.h"
@@ -31,6 +32,8 @@ using blender::MutableSpan;
using blender::Span;
using blender::StringRef;
using blender::Vector;
+using blender::bke::InstanceReference;
+using blender::bke::Instances;
/* -------------------------------------------------------------------- */
/** \name Geometry Component
@@ -256,8 +259,7 @@ std::ostream &operator<<(std::ostream &stream, const GeometrySet &geometry_set)
parts.append(std::to_string(BKE_volume_num_grids(volume)) + " volume grids");
}
if (geometry_set.has_instances()) {
- parts.append(std::to_string(
- geometry_set.get_component_for_read<InstancesComponent>()->instances_num()) +
+ parts.append(std::to_string(geometry_set.get_instances_for_read()->instances_num()) +
" instances");
}
if (geometry_set.get_curve_edit_hints_for_read()) {
@@ -338,6 +340,12 @@ const Curves *GeometrySet::get_curves_for_read() const
return (component == nullptr) ? nullptr : component->get_for_read();
}
+const Instances *GeometrySet::get_instances_for_read() const
+{
+ const InstancesComponent *component = this->get_component_for_read<InstancesComponent>();
+ return (component == nullptr) ? nullptr : component->get_for_read();
+}
+
const blender::bke::CurvesEditHints *GeometrySet::get_curve_edit_hints_for_read() const
{
const GeometryComponentEditData *component =
@@ -354,7 +362,8 @@ bool GeometrySet::has_pointcloud() const
bool GeometrySet::has_instances() const
{
const InstancesComponent *component = this->get_component_for_read<InstancesComponent>();
- return component != nullptr && component->instances_num() >= 1;
+ return component != nullptr && component->get_for_read() != nullptr &&
+ component->get_for_read()->instances_num() >= 1;
}
bool GeometrySet::has_volume() const
@@ -428,6 +437,14 @@ GeometrySet GeometrySet::create_with_curves(Curves *curves, GeometryOwnershipTyp
return geometry_set;
}
+GeometrySet GeometrySet::create_with_instances(Instances *instances,
+ GeometryOwnershipType ownership)
+{
+ GeometrySet geometry_set;
+ geometry_set.replace_instances(instances, ownership);
+ return geometry_set;
+}
+
void GeometrySet::replace_mesh(Mesh *mesh, GeometryOwnershipType ownership)
{
if (mesh == nullptr) {
@@ -456,6 +473,20 @@ void GeometrySet::replace_curves(Curves *curves, GeometryOwnershipType ownership
component.replace(curves, ownership);
}
+void GeometrySet::replace_instances(Instances *instances, GeometryOwnershipType ownership)
+{
+ if (instances == nullptr) {
+ this->remove<InstancesComponent>();
+ return;
+ }
+ if (instances == this->get_instances_for_read()) {
+ return;
+ }
+ this->remove<InstancesComponent>();
+ InstancesComponent &component = this->get_component_for_write<InstancesComponent>();
+ component.replace(instances, ownership);
+}
+
void GeometrySet::replace_pointcloud(PointCloud *pointcloud, GeometryOwnershipType ownership)
{
if (pointcloud == nullptr) {
@@ -508,6 +539,12 @@ Curves *GeometrySet::get_curves_for_write()
return component == nullptr ? nullptr : component->get_for_write();
}
+Instances *GeometrySet::get_instances_for_write()
+{
+ InstancesComponent *component = this->get_component_ptr<InstancesComponent>();
+ return component == nullptr ? nullptr : component->get_for_write();
+}
+
blender::bke::CurvesEditHints *GeometrySet::get_curve_edit_hints_for_write()
{
if (!this->has<GeometryComponentEditData>()) {
@@ -539,7 +576,7 @@ void GeometrySet::attribute_foreach(const Span<GeometryComponentType> component_
}
}
if (include_instances && this->has_instances()) {
- const InstancesComponent &instances = *this->get_component_for_read<InstancesComponent>();
+ const Instances &instances = *this->get_instances_for_read();
instances.foreach_referenced_geometry([&](const GeometrySet &instance_geometry_set) {
instance_geometry_set.attribute_foreach(component_types, include_instances, callback);
});
@@ -570,7 +607,10 @@ void GeometrySet::gather_attributes_for_propagation(
return;
}
}
-
+ if (meta_data.data_type == CD_PROP_STRING) {
+ /* Propagating string attributes is not supported yet. */
+ return;
+ }
if (!attribute_id.should_be_kept()) {
return;
}
@@ -611,7 +651,7 @@ static void gather_component_types_recursive(const GeometrySet &geometry_set,
if (!include_instances) {
return;
}
- const InstancesComponent *instances = geometry_set.get_component_for_read<InstancesComponent>();
+ const blender::bke::Instances *instances = geometry_set.get_instances_for_read();
if (instances == nullptr) {
return;
}
@@ -638,12 +678,11 @@ static void gather_mutable_geometry_sets(GeometrySet &geometry_set,
}
/* In the future this can be improved by deduplicating instance references across different
* instances. */
- InstancesComponent &instances_component =
- geometry_set.get_component_for_write<InstancesComponent>();
- instances_component.ensure_geometry_instances();
- for (const int handle : instances_component.references().index_range()) {
- if (instances_component.references()[handle].type() == InstanceReference::Type::GeometrySet) {
- GeometrySet &instance_geometry = instances_component.geometry_set_from_reference(handle);
+ Instances &instances = *geometry_set.get_instances_for_write();
+ instances.ensure_geometry_instances();
+ for (const int handle : instances.references().index_range()) {
+ if (instances.references()[handle].type() == InstanceReference::Type::GeometrySet) {
+ GeometrySet &instance_geometry = instances.geometry_set_from_reference(handle);
gather_mutable_geometry_sets(instance_geometry, r_geometry_sets);
}
}
diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc
index df48a99f706..2b36020b4e7 100644
--- a/source/blender/blenkernel/intern/geometry_set_instances.cc
+++ b/source/blender/blenkernel/intern/geometry_set_instances.cc
@@ -2,6 +2,7 @@
#include "BKE_collection.h"
#include "BKE_geometry_set_instances.hh"
+#include "BKE_instances.hh"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh_wrapper.h"
@@ -13,7 +14,6 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "DNA_pointcloud_types.h"
namespace blender::bke {
@@ -63,12 +63,11 @@ GeometrySet object_get_evaluated_geometry_set(const Object &object)
return geometry_set;
}
if (object.type == OB_EMPTY && object.instance_collection != nullptr) {
- GeometrySet geometry_set;
Collection &collection = *object.instance_collection;
- InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
- const int handle = instances.add_reference(collection);
- instances.add_instance(handle, float4x4::identity());
- return geometry_set;
+ std::unique_ptr<Instances> instances = std::make_unique<Instances>();
+ const int handle = instances->add_reference(collection);
+ instances->add_instance(handle, float4x4::identity());
+ return GeometrySet::create_with_instances(instances.release());
}
/* Return by value since there is not always an existing geometry set owned elsewhere to use. */
@@ -99,7 +98,7 @@ static void geometry_set_collect_recursive_collection(const Collection &collecti
LISTBASE_FOREACH (const CollectionObject *, collection_object, &collection.gobject) {
BLI_assert(collection_object->ob != nullptr);
const Object &object = *collection_object->ob;
- const float4x4 object_transform = transform * object.obmat;
+ const float4x4 object_transform = transform * object.object_to_world;
geometry_set_collect_recursive_object(object, object_transform, r_sets);
}
LISTBASE_FOREACH (const CollectionChild *, collection_child, &collection.children) {
@@ -116,12 +115,11 @@ static void geometry_set_collect_recursive(const GeometrySet &geometry_set,
r_sets.append({geometry_set, {transform}});
if (geometry_set.has_instances()) {
- const InstancesComponent &instances_component =
- *geometry_set.get_component_for_read<InstancesComponent>();
+ const Instances &instances = *geometry_set.get_instances_for_read();
- Span<float4x4> transforms = instances_component.instance_transforms();
- Span<int> handles = instances_component.instance_reference_handles();
- Span<InstanceReference> references = instances_component.references();
+ Span<float4x4> transforms = instances.transforms();
+ Span<int> handles = instances.reference_handles();
+ Span<InstanceReference> references = instances.references();
for (const int i : transforms.index_range()) {
const InstanceReference &reference = references[handles[i]];
const float4x4 instance_transform = transform * transforms[i];
@@ -157,9 +155,7 @@ void geometry_set_gather_instances(const GeometrySet &geometry_set,
geometry_set_collect_recursive(geometry_set, float4x4::identity(), r_instance_groups);
}
-} // namespace blender::bke
-
-void InstancesComponent::foreach_referenced_geometry(
+void Instances::foreach_referenced_geometry(
blender::FunctionRef<void(const GeometrySet &geometry_set)> callback) const
{
using namespace blender::bke;
@@ -192,7 +188,7 @@ void InstancesComponent::foreach_referenced_geometry(
}
}
-void InstancesComponent::ensure_geometry_instances()
+void Instances::ensure_geometry_instances()
{
using namespace blender;
using namespace blender::bke;
@@ -212,9 +208,7 @@ void InstancesComponent::ensure_geometry_instances()
const Object &object = reference.object();
GeometrySet object_geometry_set = object_get_evaluated_geometry_set(object);
if (object_geometry_set.has_instances()) {
- InstancesComponent &component =
- object_geometry_set.get_component_for_write<InstancesComponent>();
- component.ensure_geometry_instances();
+ object_geometry_set.get_instances_for_write()->ensure_geometry_instances();
}
new_references.add_new(std::move(object_geometry_set));
break;
@@ -222,22 +216,22 @@ void InstancesComponent::ensure_geometry_instances()
case InstanceReference::Type::Collection: {
/* Create a new reference that contains a geometry set that contains all objects from the
* collection as instances. */
- GeometrySet collection_geometry_set;
- InstancesComponent &component =
- collection_geometry_set.get_component_for_write<InstancesComponent>();
+ std::unique_ptr<Instances> instances = std::make_unique<Instances>();
Collection &collection = reference.collection();
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (&collection, object) {
- const int handle = component.add_reference(*object);
- component.add_instance(handle, object->obmat);
- float4x4 &transform = component.instance_transforms().last();
+ const int handle = instances->add_reference(*object);
+ instances->add_instance(handle, object->object_to_world);
+ float4x4 &transform = instances->transforms().last();
sub_v3_v3(transform.values[3], collection.instance_offset);
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
- component.ensure_geometry_instances();
- new_references.add_new(std::move(collection_geometry_set));
+ instances->ensure_geometry_instances();
+ new_references.add_new(GeometrySet::create_with_instances(instances.release()));
break;
}
}
}
references_ = std::move(new_references);
}
+
+} // namespace blender::bke
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index f6082d886d9..5409bf61274 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -83,8 +83,8 @@ static void greasepencil_copy_data(Main *UNUSED(bmain),
/* Apply local layer transform to all frames. Calc the active frame is not enough
* because onion skin can use more frames. This is more slow but required here. */
if (gpl_dst->actframe != NULL) {
- bool transformed = ((!is_zero_v3(gpl_dst->location)) || (!is_zero_v3(gpl_dst->rotation)) ||
- (!is_one_v3(gpl_dst->scale)));
+ bool transformed = (!is_zero_v3(gpl_dst->location) || !is_zero_v3(gpl_dst->rotation) ||
+ !is_one_v3(gpl_dst->scale));
if (transformed) {
loc_eul_size_to_mat4(
gpl_dst->layer_mat, gpl_dst->location, gpl_dst->rotation, gpl_dst->scale);
@@ -1953,9 +1953,7 @@ bool BKE_gpencil_material_index_used(bGPdata *gpd, int index)
return false;
}
-void BKE_gpencil_material_remap(struct bGPdata *gpd,
- const unsigned int *remap,
- unsigned int remap_len)
+void BKE_gpencil_material_remap(struct bGPdata *gpd, const uint *remap, uint remap_len)
{
const short remap_len_short = (short)remap_len;
@@ -2015,7 +2013,7 @@ bool BKE_gpencil_merge_materials_table_get(Object *ob,
/* Read secondary material to compare with primary material. */
ma_secondary = BKE_gpencil_material(ob, idx_secondary + 1);
if ((ma_secondary == NULL) ||
- (BLI_ghash_haskey(r_mat_table, POINTER_FROM_INT(idx_secondary)))) {
+ BLI_ghash_haskey(r_mat_table, POINTER_FROM_INT(idx_secondary))) {
continue;
}
gp_style_primary = ma_primary->gp_style;
@@ -2065,17 +2063,17 @@ bool BKE_gpencil_merge_materials_table_get(Object *ob,
rgb_to_hsv_compat_v(col, f_hsv_b);
/* Check stroke and fill color. */
- if ((!compare_ff(s_hsv_a[0], s_hsv_b[0], hue_threshold)) ||
- (!compare_ff(s_hsv_a[1], s_hsv_b[1], sat_threshold)) ||
- (!compare_ff(s_hsv_a[2], s_hsv_b[2], val_threshold)) ||
- (!compare_ff(f_hsv_a[0], f_hsv_b[0], hue_threshold)) ||
- (!compare_ff(f_hsv_a[1], f_hsv_b[1], sat_threshold)) ||
- (!compare_ff(f_hsv_a[2], f_hsv_b[2], val_threshold)) ||
- (!compare_ff(gp_style_primary->stroke_rgba[3],
- gp_style_secondary->stroke_rgba[3],
- val_threshold)) ||
- (!compare_ff(
- gp_style_primary->fill_rgba[3], gp_style_secondary->fill_rgba[3], val_threshold))) {
+ if (!compare_ff(s_hsv_a[0], s_hsv_b[0], hue_threshold) ||
+ !compare_ff(s_hsv_a[1], s_hsv_b[1], sat_threshold) ||
+ !compare_ff(s_hsv_a[2], s_hsv_b[2], val_threshold) ||
+ !compare_ff(f_hsv_a[0], f_hsv_b[0], hue_threshold) ||
+ !compare_ff(f_hsv_a[1], f_hsv_b[1], sat_threshold) ||
+ !compare_ff(f_hsv_a[2], f_hsv_b[2], val_threshold) ||
+ !compare_ff(gp_style_primary->stroke_rgba[3],
+ gp_style_secondary->stroke_rgba[3],
+ val_threshold) ||
+ !compare_ff(
+ gp_style_primary->fill_rgba[3], gp_style_secondary->fill_rgba[3], val_threshold)) {
continue;
}
@@ -2339,7 +2337,7 @@ bool BKE_gpencil_from_image(
static bool gpencil_is_layer_mask(ViewLayer *view_layer, bGPdata *gpd, bGPDlayer *gpl_mask)
{
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- if ((gpl->viewlayername[0] != '\0') && (!STREQ(view_layer->name, gpl->viewlayername))) {
+ if ((gpl->viewlayername[0] != '\0') && !STREQ(view_layer->name, gpl->viewlayername)) {
continue;
}
@@ -2414,7 +2412,7 @@ void BKE_gpencil_visible_stroke_advanced_iter(ViewLayer *view_layer,
int cfra)
{
bGPdata *gpd = (bGPdata *)ob->data;
- const bool is_multiedit = (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd) && (!GPENCIL_PLAY_ON(gpd)));
+ const bool is_multiedit = (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd) && !GPENCIL_PLAY_ON(gpd));
const bool is_onion = do_onion && ((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0);
const bool is_drawing = (gpd->runtime.sbuffer_used > 0);
@@ -2446,7 +2444,7 @@ void BKE_gpencil_visible_stroke_advanced_iter(ViewLayer *view_layer,
* generate renders, putting only selected GP layers for each View Layer.
* This is used only in final render and never in Viewport. */
if ((view_layer != NULL) && (gpl->viewlayername[0] != '\0') &&
- (!STREQ(view_layer->name, gpl->viewlayername))) {
+ !STREQ(view_layer->name, gpl->viewlayername)) {
/* Do not skip masks when rendering the view-layer so that it can still be used to clip
* other layers. Instead set their opacity to zero. */
if (gpencil_is_layer_mask(view_layer, gpd, gpl)) {
@@ -2693,7 +2691,7 @@ void BKE_gpencil_layer_transform_matrix_get(const Depsgraph *depsgraph,
/* if not layer parented, try with object parented */
if (obparent_eval == NULL) {
if ((ob_eval != NULL) && (ob_eval->type == OB_GPENCIL)) {
- copy_m4_m4(diff_mat, ob_eval->obmat);
+ copy_m4_m4(diff_mat, ob_eval->object_to_world);
mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
return;
}
@@ -2703,8 +2701,8 @@ void BKE_gpencil_layer_transform_matrix_get(const Depsgraph *depsgraph,
}
if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
- mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
- add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
+ mul_m4_m4m4(diff_mat, obparent_eval->object_to_world, gpl->inverse);
+ add_v3_v3(diff_mat[3], ob_eval->object_to_world[3]);
mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
return;
}
@@ -2712,14 +2710,14 @@ void BKE_gpencil_layer_transform_matrix_get(const Depsgraph *depsgraph,
bPoseChannel *pchan = BKE_pose_channel_find_name(obparent_eval->pose, gpl->parsubstr);
if (pchan) {
float tmp_mat[4][4];
- mul_m4_m4m4(tmp_mat, obparent_eval->obmat, pchan->pose_mat);
+ mul_m4_m4m4(tmp_mat, obparent_eval->object_to_world, pchan->pose_mat);
mul_m4_m4m4(diff_mat, tmp_mat, gpl->inverse);
- add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
+ add_v3_v3(diff_mat[3], ob_eval->object_to_world[3]);
}
else {
/* if bone not found use object (armature) */
- mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
- add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
+ mul_m4_m4m4(diff_mat, obparent_eval->object_to_world, gpl->inverse);
+ add_v3_v3(diff_mat[3], ob_eval->object_to_world[3]);
}
mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
return;
@@ -2773,12 +2771,12 @@ void BKE_gpencil_update_layer_transforms(const Depsgraph *depsgraph, Object *ob)
Object *ob_parent = DEG_get_evaluated_object(depsgraph, gpl->parent);
/* calculate new matrix */
if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
- mul_m4_m4m4(cur_mat, ob->imat, ob_parent->obmat);
+ mul_m4_m4m4(cur_mat, ob->world_to_object, ob_parent->object_to_world);
}
else if (gpl->partype == PARBONE) {
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_parent->pose, gpl->parsubstr);
if (pchan != NULL) {
- mul_m4_series(cur_mat, ob->imat, ob_parent->obmat, pchan->pose_mat);
+ mul_m4_series(cur_mat, ob->world_to_object, ob_parent->object_to_world, pchan->pose_mat);
}
else {
unit_m4(cur_mat);
@@ -2787,11 +2785,14 @@ void BKE_gpencil_update_layer_transforms(const Depsgraph *depsgraph, Object *ob)
changed = !equals_m4m4(gpl->inverse, cur_mat);
}
- /* Calc local layer transform. */
- bool transformed = ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) ||
- (!is_one_v3(gpl->scale)));
+ /* Calc local layer transform. Early out if we have non-animated zero transforms. */
+ bool transformed = (!is_zero_v3(gpl->location) || !is_zero_v3(gpl->rotation) ||
+ !is_one_v3(gpl->scale));
+ float tmp_mat[4][4];
+ loc_eul_size_to_mat4(tmp_mat, gpl->location, gpl->rotation, gpl->scale);
+ transformed |= !equals_m4m4(gpl->layer_mat, tmp_mat);
if (transformed) {
- loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ copy_m4_m4(gpl->layer_mat, tmp_mat);
}
/* Continue if no transformations are applied to this layer. */
@@ -2833,7 +2834,7 @@ int BKE_gpencil_material_find_index_by_name_prefix(Object *ob, const char *name_
for (int i = 0; i < ob->totcol; i++) {
Material *ma = BKE_object_material_get(ob, i + 1);
if ((ma != NULL) && (ma->gp_style != NULL) &&
- (STREQLEN(ma->id.name + 2, name_prefix, name_prefix_len))) {
+ STREQLEN(ma->id.name + 2, name_prefix, name_prefix_len)) {
return i;
}
}
diff --git a/source/blender/blenkernel/intern/gpencil_curve.c b/source/blender/blenkernel/intern/gpencil_curve.c
index bf224a9613e..a0a579e6d65 100644
--- a/source/blender/blenkernel/intern/gpencil_curve.c
+++ b/source/blender/blenkernel/intern/gpencil_curve.c
@@ -645,10 +645,10 @@ bGPDcurve *BKE_gpencil_stroke_editcurve_generate(bGPDstroke *gps,
}
float *r_cubic_array = NULL;
- unsigned int r_cubic_array_len = 0;
- unsigned int *r_cubic_orig_index = NULL;
- unsigned int *r_corners_index_array = NULL;
- unsigned int r_corners_index_len = 0;
+ uint r_cubic_array_len = 0;
+ uint *r_cubic_orig_index = NULL;
+ uint *r_corners_index_array = NULL;
+ uint r_corners_index_len = 0;
int r = curve_fit_cubic_to_points_refit_fl(points,
gps->totpoints,
POINT_DIM,
@@ -992,7 +992,7 @@ static float *gpencil_stroke_points_from_editcurve_fixed_resolu(bGPDcurve_point
float(*r_points)[9] = MEM_callocN((stride * points_len * (is_cyclic ? 2 : 1)), __func__);
float *points_offset = &r_points[0][0];
- for (unsigned int i = 0; i < array_last; i++) {
+ for (uint i = 0; i < array_last; i++) {
bGPDcurve_point *cpt_curr = &curve_point_array[i];
bGPDcurve_point *cpt_next = &curve_point_array[i + 1];
diff --git a/source/blender/blenkernel/intern/gpencil_geom.cc b/source/blender/blenkernel/intern/gpencil_geom.cc
index 4d0db4d5386..9297663b157 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.cc
+++ b/source/blender/blenkernel/intern/gpencil_geom.cc
@@ -746,7 +746,7 @@ bool BKE_gpencil_stroke_stretch(bGPDstroke *gps,
* `curvature = delta angle/delta arclength = len_v3(total_angle) / overshoot_length` */
float curvature = normalize_v3(total_angle) / overshoot_length;
/* Compensate for the weights powf(added_len, segment_influence). */
- curvature /= powf(overshoot_length / fminf(overshoot_parameter, (float)j), segment_influence);
+ curvature /= powf(overshoot_length / fminf(overshoot_parameter, float(j)), segment_influence);
if (invert_curvature) {
curvature = -curvature;
}
@@ -789,7 +789,10 @@ bool BKE_gpencil_stroke_stretch(bGPDstroke *gps,
/** \name Stroke Trim
* \{ */
-bool BKE_gpencil_stroke_trim_points(bGPDstroke *gps, const int index_from, const int index_to)
+bool BKE_gpencil_stroke_trim_points(bGPDstroke *gps,
+ const int index_from,
+ const int index_to,
+ const bool keep_point)
{
bGPDspoint *pt = gps->points, *new_pt;
MDeformVert *dv, *new_dv;
@@ -800,7 +803,7 @@ bool BKE_gpencil_stroke_trim_points(bGPDstroke *gps, const int index_from, const
return false;
}
- if (new_count == 1) {
+ if ((!keep_point) && (new_count == 1)) {
if (gps->dvert) {
BKE_gpencil_free_stroke_weights(gps);
MEM_freeN(gps->dvert);
@@ -894,7 +897,7 @@ bool BKE_gpencil_stroke_split(bGPdata *gpd,
/* Trim the original stroke into a shorter one.
* Keep the end point. */
- BKE_gpencil_stroke_trim_points(gps, 0, old_count);
+ BKE_gpencil_stroke_trim_points(gps, 0, old_count, false);
BKE_gpencil_stroke_geometry_update(gpd, gps);
return true;
}
@@ -917,7 +920,7 @@ bool BKE_gpencil_stroke_shrink(bGPDstroke *gps, const float dist, const short mo
if (gps->totpoints == 1) {
second_last = &pt[1];
if (len_v3v3(&second_last->x, &pt->x) < dist) {
- BKE_gpencil_stroke_trim_points(gps, 0, 0);
+ BKE_gpencil_stroke_trim_points(gps, 0, 0, false);
return true;
}
}
@@ -969,7 +972,7 @@ bool BKE_gpencil_stroke_shrink(bGPDstroke *gps, const float dist, const short mo
index_start = index_end = 0; /* no length left to cut */
}
- BKE_gpencil_stroke_trim_points(gps, index_start, index_end);
+ BKE_gpencil_stroke_trim_points(gps, index_start, index_end, false);
if (gps->totpoints == 0) {
return false;
@@ -1044,14 +1047,14 @@ bool BKE_gpencil_stroke_smooth_point(bGPDstroke *gps,
(iterations * iterations) / 4 + 2 * iterations + 12;
double w = keep_shape ? 2.0 : 1.0;
double w2 = keep_shape ?
- (1.0 / M_SQRT3) * exp((2 * iterations * iterations) / (double)(n_half * 3)) :
+ (1.0 / M_SQRT3) * exp((2 * iterations * iterations) / double(n_half * 3)) :
0.0;
double total_w = 0.0;
for (int step = iterations; step > 0; step--) {
int before = point_index - step;
int after = point_index + step;
- float w_before = (float)(w - w2);
- float w_after = (float)(w - w2);
+ float w_before = float(w - w2);
+ float w_after = float(w - w2);
if (is_cyclic) {
before = (before % gps->totpoints + gps->totpoints) % gps->totpoints;
@@ -1060,13 +1063,13 @@ bool BKE_gpencil_stroke_smooth_point(bGPDstroke *gps,
else {
if (before < 0) {
if (!smooth_caps) {
- w_before *= -before / (float)point_index;
+ w_before *= -before / float(point_index);
}
before = 0;
}
if (after > gps->totpoints - 1) {
if (!smooth_caps) {
- w_after *= (after - (gps->totpoints - 1)) / (float)(gps->totpoints - 1 - point_index);
+ w_after *= (after - (gps->totpoints - 1)) / float(gps->totpoints - 1 - point_index);
}
after = gps->totpoints - 1;
}
@@ -1081,14 +1084,14 @@ bool BKE_gpencil_stroke_smooth_point(bGPDstroke *gps,
total_w += w_before;
total_w += w_after;
- w *= (n_half + step) / (double)(n_half + 1 - step);
- w2 *= (n_half * 3 + step) / (double)(n_half * 3 + 1 - step);
+ w *= (n_half + step) / double(n_half + 1 - step);
+ w2 *= (n_half * 3 + step) / double(n_half * 3 + 1 - step);
}
total_w += w - w2;
/* The accumulated weight total_w should be
* ~sqrt(M_PI * n_half) * exp((iterations * iterations) / n_half) < 100
* here, but sometimes not quite. */
- mul_v3_fl(sco, (float)(1.0 / total_w));
+ mul_v3_fl(sco, float(1.0 / total_w));
/* Shift back to global coordinates. */
add_v3_v3(sco, &pt->x);
@@ -1123,8 +1126,8 @@ bool BKE_gpencil_stroke_smooth_strength(
for (int step = iterations; step > 0; step--) {
int before = point_index - step;
int after = point_index + step;
- float w_before = (float)w;
- float w_after = (float)w;
+ float w_before = float(w);
+ float w_after = float(w);
if (is_cyclic) {
before = (before % gps->totpoints + gps->totpoints) % gps->totpoints;
@@ -1142,7 +1145,7 @@ bool BKE_gpencil_stroke_smooth_strength(
total_w += w_before;
total_w += w_after;
- w *= (n_half + step) / (double)(n_half + 1 - step);
+ w *= (n_half + step) / double(n_half + 1 - step);
}
total_w += w;
/* The accumulated weight total_w should be
@@ -1181,8 +1184,8 @@ bool BKE_gpencil_stroke_smooth_thickness(
for (int step = iterations; step > 0; step--) {
int before = point_index - step;
int after = point_index + step;
- float w_before = (float)w;
- float w_after = (float)w;
+ float w_before = float(w);
+ float w_after = float(w);
if (is_cyclic) {
before = (before % gps->totpoints + gps->totpoints) % gps->totpoints;
@@ -1200,7 +1203,7 @@ bool BKE_gpencil_stroke_smooth_thickness(
total_w += w_before;
total_w += w_after;
- w *= (n_half + step) / (double)(n_half + 1 - step);
+ w *= (n_half + step) / double(n_half + 1 - step);
}
total_w += w;
/* The accumulated weight total_w should be
@@ -1251,8 +1254,8 @@ bool BKE_gpencil_stroke_smooth_uv(struct bGPDstroke *gps,
for (int step = iterations; step > 0; step--) {
int before = point_index - step;
int after = point_index + step;
- float w_before = (float)w;
- float w_after = (float)w;
+ float w_before = float(w);
+ float w_after = float(w);
if (is_cyclic) {
before = (before % gps->totpoints + gps->totpoints) % gps->totpoints;
@@ -1260,11 +1263,11 @@ bool BKE_gpencil_stroke_smooth_uv(struct bGPDstroke *gps,
}
else {
if (before < 0) {
- w_before *= -before / (float)point_index;
+ w_before *= -before / float(point_index);
before = 0;
}
if (after > gps->totpoints - 1) {
- w_after *= (after - (gps->totpoints - 1)) / (float)(gps->totpoints - 1 - point_index);
+ w_after *= (after - (gps->totpoints - 1)) / float(gps->totpoints - 1 - point_index);
after = gps->totpoints - 1;
}
}
@@ -1278,7 +1281,7 @@ bool BKE_gpencil_stroke_smooth_uv(struct bGPDstroke *gps,
total_w += w_before;
total_w += w_after;
- w *= (n_half + step) / (double)(n_half + 1 - step);
+ w *= (n_half + step) / double(n_half + 1 - step);
}
total_w += w;
/* The accumulated weight total_w should be
@@ -1353,7 +1356,7 @@ void BKE_gpencil_stroke_2d_flat(const bGPDspoint *points,
const bGPDspoint *pt0 = &points[0];
const bGPDspoint *pt1 = &points[1];
- const bGPDspoint *pt3 = &points[(int)(totpoints * 0.75)];
+ const bGPDspoint *pt3 = &points[int(totpoints * 0.75)];
float locx[3];
float locy[3];
@@ -1430,7 +1433,7 @@ void BKE_gpencil_stroke_2d_flat_ref(const bGPDspoint *ref_points,
const bGPDspoint *pt0 = &ref_points[0];
const bGPDspoint *pt1 = &ref_points[1];
- const bGPDspoint *pt3 = &ref_points[(int)(ref_totpoints * 0.75)];
+ const bGPDspoint *pt3 = &ref_points[int(ref_totpoints * 0.75)];
float locx[3];
float locy[3];
@@ -1499,7 +1502,7 @@ void BKE_gpencil_stroke_2d_flat_ref(const bGPDspoint *ref_points,
}
/* Concave (-1), Convex (1), or Auto-detect (0)? */
- *r_direction = (int)locy[2];
+ *r_direction = int(locy[2]);
}
/* Calc texture coordinates using flat projected points. */
@@ -1564,7 +1567,7 @@ void BKE_gpencil_stroke_fill_triangulate(bGPDstroke *gps)
/* convert to 2d and triangulate */
BKE_gpencil_stroke_2d_flat(gps->points, gps->totpoints, points2d, &direction);
- BLI_polyfill_calc(points2d, (uint)gps->totpoints, direction, tmp_triangles);
+ BLI_polyfill_calc(points2d, uint(gps->totpoints), direction, tmp_triangles);
/* calc texture coordinates automatically */
float minv[2];
@@ -1844,7 +1847,7 @@ bool BKE_gpencil_stroke_close(bGPDstroke *gps)
pt2 = &gps->points[0];
bGPDspoint *pt = &gps->points[old_tot];
for (int i = 1; i < tot_newpoints + 1; i++, pt++) {
- float step = (tot_newpoints > 1) ? ((float)i / (float)tot_newpoints) : 0.99f;
+ float step = (tot_newpoints > 1) ? (float(i) / float(tot_newpoints)) : 0.99f;
/* Clamp last point to be near, but not on top of first point. */
if ((tot_newpoints > 1) && (i == tot_newpoints)) {
step *= 0.99f;
@@ -1856,6 +1859,10 @@ bool BKE_gpencil_stroke_close(bGPDstroke *gps)
pt->strength = interpf(pt2->strength, pt1->strength, step);
pt->flag = 0;
interp_v4_v4v4(pt->vert_color, pt1->vert_color, pt2->vert_color, step);
+ /* Set point as selected. */
+ if (gps->flag & GP_STROKE_SELECT) {
+ pt->flag |= GP_SPOINT_SELECT;
+ }
/* Set weights. */
if (gps->dvert != nullptr) {
@@ -1988,7 +1995,7 @@ void BKE_gpencil_stroke_normal(const bGPDstroke *gps, float r_normal[3])
const bGPDspoint *pt0 = &points[0];
const bGPDspoint *pt1 = &points[1];
- const bGPDspoint *pt3 = &points[(int)(totpoints * 0.75)];
+ const bGPDspoint *pt3 = &points[int(totpoints * 0.75)];
float vec1[3];
float vec2[3];
@@ -2629,7 +2636,7 @@ static int gpencil_material_find_index_by_name(Object *ob, const char *name)
{
for (int i = 0; i < ob->totcol; i++) {
Material *ma = BKE_object_material_get(ob, i + 1);
- if ((ma != nullptr) && (ma->gp_style != nullptr) && (STREQ(ma->id.name + 2, name))) {
+ if ((ma != nullptr) && (ma->gp_style != nullptr) && STREQ(ma->id.name + 2, name)) {
return i;
}
}
@@ -3117,7 +3124,7 @@ bGPDstroke *BKE_gpencil_stroke_delete_tagged_points(bGPdata *gpd,
bGPDstroke *new_stroke = nullptr;
bGPDstroke *gps_first = nullptr;
- const bool is_cyclic = (bool)(gps->flag & GP_STROKE_CYCLIC);
+ const bool is_cyclic = bool(gps->flag & GP_STROKE_CYCLIC);
/* First Pass: Identify start/end of islands */
bGPDspoint *pt = gps->points;
@@ -3210,7 +3217,7 @@ bGPDstroke *BKE_gpencil_stroke_delete_tagged_points(bGPdata *gpd,
float delta = gps->points[island->start_idx].time;
int j;
- new_stroke->inittime += (double)delta;
+ new_stroke->inittime += double(delta);
pts = new_stroke->points;
for (j = 0; j < new_stroke->totpoints; j++, pts++) {
@@ -3502,7 +3509,7 @@ void BKE_gpencil_stroke_join(bGPDstroke *gps_a,
/* Ratio to apply in the points to keep the same thickness in the joined stroke using the
* destination stroke thickness. */
const float ratio = (fit_thickness && gps_a->thickness > 0.0f) ?
- (float)gps_b->thickness / (float)gps_a->thickness :
+ float(gps_b->thickness) / float(gps_a->thickness) :
1.0f;
/* 3rd: add all points */
@@ -3558,8 +3565,8 @@ void BKE_gpencil_stroke_start_set(bGPDstroke *gps, int start_idx)
}
bGPDstroke *gps_b = BKE_gpencil_stroke_duplicate(gps, true, false);
- BKE_gpencil_stroke_trim_points(gps_b, 0, start_idx - 1);
- BKE_gpencil_stroke_trim_points(gps, start_idx, gps->totpoints - 1);
+ BKE_gpencil_stroke_trim_points(gps_b, 0, start_idx - 1, true);
+ BKE_gpencil_stroke_trim_points(gps, start_idx, gps->totpoints - 1, true);
/* Join both strokes. */
BKE_gpencil_stroke_join(gps, gps_b, false, false, false, false);
@@ -3861,9 +3868,9 @@ static int generate_arc_from_point_to_point(ListBase *list,
/* Number of points is 2^(n+1) + 1 on half a circle (n=subdivisions)
* so we multiply by (angle / pi) to get the right amount of
* points to insert. */
- int num_points = (int)(((1 << (subdivisions + 1)) - 1) * (angle / M_PI));
+ int num_points = int(((1 << (subdivisions + 1)) - 1) * (angle / M_PI));
if (num_points > 0) {
- float angle_incr = angle / (float)num_points;
+ float angle_incr = angle / float(num_points);
float vec_p[3];
float vec_t[3];
@@ -3918,7 +3925,7 @@ static int generate_semi_circle_from_point_to_point(ListBase *list,
}
float vec_p[3];
- float angle_incr = M_PI / ((float)num_points - 1);
+ float angle_incr = M_PI / (float(num_points) - 1);
tPerimeterPoint *last_point = from;
for (int i = 1; i < num_points; i++) {
@@ -4324,7 +4331,7 @@ float BKE_gpencil_stroke_average_pressure_get(bGPDstroke *gps)
tot += pt->pressure;
}
- return tot / (float)gps->totpoints;
+ return tot / float(gps->totpoints);
}
bool BKE_gpencil_stroke_is_pressure_constant(bGPDstroke *gps)
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index 33f84aff545..1ad7aeed41c 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -677,7 +677,7 @@ static void copy_frame_to_eval_cb(bGPDlayer *gpl,
* - When the frame is the layer's active frame (already handled in
* gpencil_copy_visible_frames_to_eval).
*/
- if (gpf == NULL || gpf == gpl->actframe) {
+ if (ELEM(gpf, NULL, gpl->actframe)) {
return;
}
@@ -720,7 +720,14 @@ void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *o
do_parent = true;
break;
}
- if ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) || (!is_one_v3(gpl->scale))) {
+
+ /* Only do layer transformations for non-zero or animated transforms. */
+ bool transformed = (!is_zero_v3(gpl->location) || !is_zero_v3(gpl->rotation) ||
+ !is_one_v3(gpl->scale));
+ float tmp_mat[4][4];
+ loc_eul_size_to_mat4(tmp_mat, gpl->location, gpl->rotation, gpl->scale);
+ transformed |= !equals_m4m4(gpl->layer_mat, tmp_mat);
+ if (transformed) {
do_transform = true;
break;
}
@@ -745,7 +752,7 @@ void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *o
const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd_orig);
const bool do_modifiers = (bool)((!is_multiedit) && (!is_curve_edit) &&
(ob_orig->greasepencil_modifiers.first != NULL) &&
- (!GPENCIL_SIMPLIFY_MODIF(scene)));
+ !GPENCIL_SIMPLIFY_MODIF(scene));
if ((!do_modifiers) && (!do_parent) && (!do_transform)) {
BLI_assert(ob->data != NULL);
return;
@@ -775,7 +782,7 @@ void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
const bool is_multiedit = (bool)(GPENCIL_MULTIEDIT_SESSIONS_ON(gpd) && !is_render);
const bool do_modifiers = (bool)((!is_multiedit) && (!is_curve_edit) &&
(ob->greasepencil_modifiers.first != NULL) &&
- (!GPENCIL_SIMPLIFY_MODIF(scene)));
+ !GPENCIL_SIMPLIFY_MODIF(scene));
if (!do_modifiers) {
return;
}
@@ -897,6 +904,11 @@ void BKE_gpencil_modifier_blend_write(BlendWriter *writer, ListBase *modbase)
BLO_write_struct_array(
writer, DashGpencilModifierSegment, gpmd->segments_len, gpmd->segments);
}
+ else if (md->type == eGpencilModifierType_Time) {
+ TimeGpencilModifierData *gpmd = (TimeGpencilModifierData *)md;
+ BLO_write_struct_array(
+ writer, TimeGpencilModifierSegment, gpmd->segments_len, gpmd->segments);
+ }
}
}
@@ -930,7 +942,7 @@ void BKE_gpencil_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb)
BLO_read_data_address(reader, &gpmd->curve_intensity);
if (gpmd->curve_intensity) {
BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
- /* initialize the curve. Maybe this could be moved to modififer logic */
+ /* Initialize the curve. Maybe this could be moved to modifier logic. */
BKE_curvemapping_init(gpmd->curve_intensity);
}
}
@@ -983,6 +995,13 @@ void BKE_gpencil_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb)
gpmd->segments[i].dmd = gpmd;
}
}
+ else if (md->type == eGpencilModifierType_Time) {
+ TimeGpencilModifierData *gpmd = (TimeGpencilModifierData *)md;
+ BLO_read_data_address(reader, &gpmd->segments);
+ for (int i = 0; i < gpmd->segments_len; i++) {
+ gpmd->segments[i].gpmd = gpmd;
+ }
+ }
if (md->type == eGpencilModifierType_Shrinkwrap) {
ShrinkwrapGpencilModifierData *gpmd = (ShrinkwrapGpencilModifierData *)md;
gpmd->cache_data = NULL;
diff --git a/source/blender/blenkernel/intern/icons.cc b/source/blender/blenkernel/intern/icons.cc
index f59f5352aad..7fd0515b52c 100644
--- a/source/blender/blenkernel/intern/icons.cc
+++ b/source/blender/blenkernel/intern/icons.cc
@@ -479,7 +479,7 @@ PreviewImage *BKE_previewimg_cached_thumbnail_read(const char *name,
if (prv && force_update) {
const char *prv_deferred_data = (char *)PRV_DEFERRED_DATA(prv);
- if (((int)prv_deferred_data[0] == source) && STREQ(&prv_deferred_data[1], filepath)) {
+ if ((int(prv_deferred_data[0]) == source) && STREQ(&prv_deferred_data[1], filepath)) {
/* If same filepath, no need to re-allocate preview, just clear it up. */
BKE_previewimg_clear(prv);
}
@@ -530,7 +530,7 @@ void BKE_previewimg_ensure(PreviewImage *prv, const int size)
thumb = IMB_thumb_manage(filepath, THB_LARGE, (ThumbSource)source);
if (thumb) {
- /* PreviewImage assumes premultiplied alhpa... */
+ /* #PreviewImage assumes pre-multiplied alpha. */
IMB_premultiply_alpha(thumb);
if (do_preview) {
@@ -566,9 +566,9 @@ void BKE_previewimg_ensure(PreviewImage *prv, const int size)
ImBuf *BKE_previewimg_to_imbuf(PreviewImage *prv, const int size)
{
- const unsigned int w = prv->w[size];
- const unsigned int h = prv->h[size];
- const unsigned int *rect = prv->rect[size];
+ const uint w = prv->w[size];
+ const uint h = prv->h[size];
+ const uint *rect = prv->rect[size];
ImBuf *ima = nullptr;
@@ -971,8 +971,8 @@ struct Icon_Geom *BKE_icon_geom_from_memory(uchar *data, size_t data_len)
p += 4;
struct Icon_Geom *geom = (struct Icon_Geom *)MEM_mallocN(sizeof(*geom), __func__);
- geom->coords_range[0] = (int)*p++;
- geom->coords_range[1] = (int)*p++;
+ geom->coords_range[0] = int(*p++);
+ geom->coords_range[1] = int(*p++);
/* x, y ignored for now */
p += 2;
diff --git a/source/blender/blenkernel/intern/icons_rasterize.c b/source/blender/blenkernel/intern/icons_rasterize.c
index 00dbdcfa1e5..56854c1318e 100644
--- a/source/blender/blenkernel/intern/icons_rasterize.c
+++ b/source/blender/blenkernel/intern/icons_rasterize.c
@@ -67,9 +67,7 @@ static void tri_fill_smooth(int x, int x_end, int y, void *user_data)
}
}
-ImBuf *BKE_icon_geom_rasterize(const struct Icon_Geom *geom,
- const unsigned int size_x,
- const unsigned int size_y)
+ImBuf *BKE_icon_geom_rasterize(const struct Icon_Geom *geom, const uint size_x, const uint size_y)
{
const int coords_len = geom->coords_len;
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 98c317c547b..f876caf9d91 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -829,8 +829,8 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is
case IDP_DOUBLE:
return (IDP_Double(prop1) == IDP_Double(prop2));
case IDP_STRING: {
- return (((prop1->len == prop2->len) &&
- STREQLEN(IDP_String(prop1), IDP_String(prop2), (size_t)prop1->len)));
+ return ((prop1->len == prop2->len) &&
+ STREQLEN(IDP_String(prop1), IDP_String(prop2), (size_t)prop1->len));
}
case IDP_ARRAY:
if (prop1->len == prop2->len && prop1->subtype == prop2->subtype) {
diff --git a/source/blender/blenkernel/intern/idprop_create.cc b/source/blender/blenkernel/intern/idprop_create.cc
index 24f59d5e49e..8a6e5cdcc50 100644
--- a/source/blender/blenkernel/intern/idprop_create.cc
+++ b/source/blender/blenkernel/intern/idprop_create.cc
@@ -79,7 +79,7 @@ static void array_values_set(IDProperty *property,
template<
/** C-Primitive type of the array. Can be int32_t, float, double. */
typename PrimitiveType,
- /** Subtype of the ID_ARRAY. Must match PrimitiveType. */
+ /** Sub-type of the #ID_ARRAY. Must match #PrimitiveType. */
eIDPropertyType id_property_subtype>
std::unique_ptr<IDProperty, IDPropertyDeleter> create_array(StringRefNull prop_name,
Span<PrimitiveType> values)
diff --git a/source/blender/blenkernel/intern/idprop_serialize.cc b/source/blender/blenkernel/intern/idprop_serialize.cc
index 9e5733e5a2b..8381b0a1755 100644
--- a/source/blender/blenkernel/intern/idprop_serialize.cc
+++ b/source/blender/blenkernel/intern/idprop_serialize.cc
@@ -665,7 +665,7 @@ class IDPUnknownSerializer : public IDPropertySerializer {
}
std::shared_ptr<DictionaryValue> idprop_to_dictionary(
- const struct IDProperty *UNUSED(id_property)) const override
+ const struct IDProperty * /*id_property*/) const override
{
BLI_assert_unreachable();
return nullptr;
@@ -677,7 +677,7 @@ class IDPUnknownSerializer : public IDPropertySerializer {
}
std::unique_ptr<IDProperty, IDPropertyDeleter> entry_to_idprop(
- DictionaryEntryParser &UNUSED(entry_reader)) const override
+ DictionaryEntryParser & /*entry_reader*/) const override
{
return nullptr;
}
diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc
index 75cf10f88aa..75e3e22afa7 100644
--- a/source/blender/blenkernel/intern/image.cc
+++ b/source/blender/blenkernel/intern/image.cc
@@ -153,7 +153,7 @@ static void image_init_data(ID *id)
}
}
-static void image_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
+static void image_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int flag)
{
Image *image_dst = (Image *)id_dst;
const Image *image_src = (const Image *)id_src;
@@ -256,7 +256,7 @@ static void image_foreach_cache(ID *id,
function_callback(id, &key, (void **)&image->rr, 0, user_data);
LISTBASE_FOREACH (RenderSlot *, slot, &image->renderslots) {
- key.offset_in_ID = (size_t)BLI_ghashutil_strhash_p(slot->name);
+ key.offset_in_ID = size_t(BLI_ghashutil_strhash_p(slot->name));
function_callback(id, &key, (void **)&slot->render, 0, user_data);
}
}
@@ -297,7 +297,7 @@ static void image_foreach_path(ID *id, BPathForeachPathData *bpath_data)
/* Put the filepath back together using the new directory and the original file name. */
char new_dir[FILE_MAXDIR];
BLI_split_dir_part(temp_path, new_dir, sizeof(new_dir));
- BLI_join_dirfile(ima->filepath, sizeof(ima->filepath), new_dir, orig_file);
+ BLI_path_join(ima->filepath, sizeof(ima->filepath), new_dir, orig_file);
}
}
else {
@@ -410,7 +410,7 @@ static void image_blend_read_data(BlendDataReader *reader, ID *id)
image_runtime_reset(ima);
}
-static void image_blend_read_lib(BlendLibReader *UNUSED(reader), ID *id)
+static void image_blend_read_lib(BlendLibReader * /*reader*/, ID *id)
{
Image *ima = (Image *)id;
/* Images have some kind of 'main' cache, when null we should also clear all others. */
@@ -484,7 +484,7 @@ struct ImageCacheKey {
int index;
};
-static unsigned int imagecache_hashhash(const void *key_v)
+static uint imagecache_hashhash(const void *key_v)
{
const ImageCacheKey *key = static_cast<const ImageCacheKey *>(key_v);
return key->index;
@@ -846,8 +846,8 @@ int BKE_image_get_tile_from_pos(Image *ima, const float uv[2], float r_uv[2], fl
return 0;
}
- int ix = (int)uv[0];
- int iy = (int)uv[1];
+ int ix = int(uv[0]);
+ int iy = int(uv[1]);
int tile_number = 1001 + 10 * iy + ix;
if (BKE_image_get_tile(ima, tile_number) == nullptr) {
@@ -867,8 +867,8 @@ void BKE_image_get_tile_uv(const Image *ima, const int tile_number, float r_uv[2
}
else {
const int tile_index = tile_number - 1001;
- r_uv[0] = static_cast<float>(tile_index % 10);
- r_uv[1] = static_cast<float>(tile_index / 10);
+ r_uv[0] = float(tile_index % 10);
+ r_uv[1] = float(tile_index / 10);
}
}
@@ -1080,7 +1080,7 @@ struct ImageFillData {
short gen_type;
uint width;
uint height;
- unsigned char *rect;
+ uchar *rect;
float *rect_float;
float fill_color[4];
};
@@ -1093,7 +1093,7 @@ static void image_buf_fill_isolated(void *usersata_v)
const uint width = usersata->width;
const uint height = usersata->height;
- unsigned char *rect = usersata->rect;
+ uchar *rect = usersata->rect;
float *rect_float = usersata->rect_float;
switch (gen_type) {
@@ -1112,7 +1112,7 @@ static void image_buf_fill_isolated(void *usersata_v)
static ImBuf *add_ibuf_for_tile(Image *ima, ImageTile *tile)
{
ImBuf *ibuf;
- unsigned char *rect = nullptr;
+ uchar *rect = nullptr;
float *rect_float = nullptr;
float fill_color[4];
@@ -1152,7 +1152,7 @@ static ImBuf *add_ibuf_for_tile(Image *ima, ImageTile *tile)
}
if (ibuf != nullptr) {
- rect = (unsigned char *)ibuf->rect;
+ rect = (uchar *)ibuf->rect;
IMB_colormanagement_assign_rect_colorspace(ibuf, ima->colorspace_settings.name);
}
@@ -1183,8 +1183,8 @@ static ImBuf *add_ibuf_for_tile(Image *ima, ImageTile *tile)
}
Image *BKE_image_add_generated(Main *bmain,
- unsigned int width,
- unsigned int height,
+ uint width,
+ uint height,
const char *name,
int depth,
int floatbuf,
@@ -1534,19 +1534,19 @@ void BKE_image_print_memlist(Main *bmain)
totsize += image_mem_size(ima);
}
- printf("\ntotal image memory len: %.3f MB\n", (double)totsize / (double)(1024 * 1024));
+ printf("\ntotal image memory len: %.3f MB\n", double(totsize) / double(1024 * 1024));
for (ima = static_cast<Image *>(bmain->images.first); ima;
ima = static_cast<Image *>(ima->id.next)) {
size = image_mem_size(ima);
if (size) {
- printf("%s len: %.3f MB\n", ima->id.name + 2, (double)size / (double)(1024 * 1024));
+ printf("%s len: %.3f MB\n", ima->id.name + 2, double(size) / double(1024 * 1024));
}
}
}
-static bool imagecache_check_dirty(ImBuf *ibuf, void *UNUSED(userkey), void *UNUSED(userdata))
+static bool imagecache_check_dirty(ImBuf *ibuf, void * /*userkey*/, void * /*userdata*/)
{
if (ibuf == nullptr) {
return false;
@@ -1595,7 +1595,7 @@ void BKE_image_free_all_textures(Main *bmain)
#endif
}
-static bool imagecache_check_free_anim(ImBuf *ibuf, void *UNUSED(userkey), void *userdata)
+static bool imagecache_check_free_anim(ImBuf *ibuf, void * /*userkey*/, void *userdata)
{
if (ibuf == nullptr) {
return true;
@@ -1943,7 +1943,7 @@ static void stampdata_from_template(StampData *stamp_data,
void BKE_image_stamp_buf(Scene *scene,
Object *camera,
const StampData *stamp_data_template,
- unsigned char *rect,
+ uchar *rect,
float *rectf,
int width,
int height,
@@ -1967,7 +1967,7 @@ void BKE_image_stamp_buf(Scene *scene,
* for now though this is only used for renders which use scene settings */
#define TEXT_SIZE_CHECK(str, w, h) \
- ((str[0]) && ((void)(h = h_fixed), (w = (int)BLF_width(mono, str, sizeof(str)))))
+ ((str[0]) && ((void)(h = h_fixed), (w = int(BLF_width(mono, str, sizeof(str))))))
/* must enable BLF_WORD_WRAP before using */
#define TEXT_SIZE_CHECK_WORD_WRAP(str, w, h) \
@@ -1999,7 +1999,7 @@ void BKE_image_stamp_buf(Scene *scene,
}
/* set before return */
- BLF_size(mono, scene->r.stamp_font_id, 72);
+ BLF_size(mono, scene->r.stamp_font_id);
BLF_wordwrap(mono, width - (BUFF_MARGIN_X * 2));
BLF_buffer(mono, rectf, rect, width, height, channels, display);
@@ -2470,7 +2470,7 @@ void BKE_stamp_data_free(StampData *stamp_data)
}
/* wrap for callback only */
-static void metadata_set_field(void *data, const char *propname, char *propvalue, int UNUSED(len))
+static void metadata_set_field(void *data, const char *propname, char *propvalue, int /*len*/)
{
/* We know it is an ImBuf* because that's what we pass to BKE_stamp_info_callback. */
ImBuf *imbuf = static_cast<ImBuf *>(data);
@@ -2524,7 +2524,7 @@ bool BKE_imbuf_alpha_test(ImBuf *ibuf)
}
}
else if (ibuf->rect) {
- unsigned char *buf = (unsigned char *)ibuf->rect;
+ uchar *buf = (uchar *)ibuf->rect;
for (tot = ibuf->x * ibuf->y; tot--; buf += 4) {
if (buf[3] != 255) {
return true;
@@ -2662,7 +2662,7 @@ Image *BKE_image_ensure_viewer(Main *bmain, int type, const char *name)
ima = image_alloc(bmain, name, IMA_SRC_VIEWER, type);
}
- /* Happens on reload, imagewindow cannot be image user when hidden. */
+ /* Happens on reload, image-window cannot be image user when hidden. */
if (ima->id.us == 0) {
id_us_ensure_real(&ima->id);
}
@@ -2986,7 +2986,7 @@ static void image_free_tile(Image *ima, ImageTile *tile)
for (int i = 0; i < TEXTARGET_COUNT; i++) {
/* Only two textures depends on all tiles, so if this is a secondary tile we can keep the other
* two. */
- if (tile != ima->tiles.first && !(ELEM(i, TEXTARGET_2D_ARRAY, TEXTARGET_TILE_MAPPING))) {
+ if (tile != ima->tiles.first && !ELEM(i, TEXTARGET_2D_ARRAY, TEXTARGET_TILE_MAPPING)) {
continue;
}
@@ -3082,16 +3082,10 @@ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal)
/* Free all but the first tile. */
image_remove_all_tiles(ima);
- /* If the remaining tile is generated, we need to again ensure that we
- * wouldn't continue to use the old filepath.
- *
- * Otherwise, if this used to be a UDIM image, get the concrete filepath associated
+ /* If this used to be a UDIM image, get the concrete filepath associated
* with the remaining tile and use that as the new filepath. */
ImageTile *base_tile = BKE_image_get_tile(ima, 0);
- if ((base_tile->gen_flag & IMA_GEN_TILE) != 0) {
- ima->filepath[0] = '\0';
- }
- else if (BKE_image_is_filename_tokenized(ima->filepath)) {
+ if (BKE_image_is_filename_tokenized(ima->filepath)) {
const bool was_relative = BLI_path_is_rel(ima->filepath);
eUDIM_TILE_FORMAT tile_format;
@@ -3183,10 +3177,14 @@ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal)
* left. */
image_remove_all_tiles(ima);
- int remaining_tile_number = ((ImageTile *)ima->tiles.first)->tile_number;
+ ImageTile *base_tile = BKE_image_get_tile(ima, 0);
+ int remaining_tile_number = base_tile->tile_number;
bool needs_final_cleanup = true;
- /* Add in all the new tiles. */
+ /* Add in all the new tiles. As the image is proven to be on disk at this point, remove
+ * the generation flag from the remaining tile in case this was previously a generated
+ * image. */
+ base_tile->gen_flag &= ~IMA_GEN_TILE;
LISTBASE_FOREACH (LinkData *, new_tile, &new_tiles) {
int new_tile_number = POINTER_AS_INT(new_tile->data);
BKE_image_add_tile(ima, new_tile_number, nullptr);
@@ -3202,6 +3200,11 @@ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal)
}
BLI_freelistN(&new_tiles);
}
+ else if (ima->filepath[0] != '\0') {
+ /* If the filepath is set at this point remove the generation flag. */
+ ImageTile *base_tile = BKE_image_get_tile(ima, 0);
+ base_tile->gen_flag &= ~IMA_GEN_TILE;
+ }
if (iuser) {
image_tag_reload(ima, nullptr, iuser, ima);
@@ -3331,7 +3334,7 @@ bool BKE_image_get_tile_info(char *filepath, ListBase *tiles, int *r_tile_start,
MEM_SAFE_FREE(udim_pattern);
if (all_valid_udim && min_udim <= IMA_UDIM_MAX) {
- BLI_join_dirfile(filepath, FILE_MAX, dirname, filename);
+ BLI_path_join(filepath, FILE_MAX, dirname, filename);
*r_tile_start = min_udim;
*r_tile_range = max_udim - min_udim + 1;
@@ -3607,12 +3610,12 @@ void BKE_image_set_filepath_from_tile_number(char *filepath,
}
if (tile_format == UDIM_TILE_FORMAT_UDIM) {
- sprintf(filepath, pattern, tile_number);
+ BLI_sprintf(filepath, pattern, tile_number);
}
else if (tile_format == UDIM_TILE_FORMAT_UVTILE) {
int u = ((tile_number - 1001) % 10);
int v = ((tile_number - 1001) / 10);
- sprintf(filepath, pattern, u + 1, v + 1);
+ BLI_sprintf(filepath, pattern, u + 1, v + 1);
}
}
@@ -3876,7 +3879,7 @@ static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
#endif /* WITH_OPENEXR */
/** Common stuff to do with images after loading. */
-static void image_init_after_load(Image *ima, ImageUser *iuser, ImBuf *UNUSED(ibuf))
+static void image_init_after_load(Image *ima, ImageUser *iuser, ImBuf * /*ibuf*/)
{
/* Preview is null when it has never been used as an icon before.
* Never handle previews/icons outside of main thread. */
@@ -4101,7 +4104,7 @@ static ImBuf *load_image_single(Image *ima,
LISTBASE_FOREACH (ImagePackedFile *, imapf, &ima->packedfiles) {
if (imapf->view == view_id && imapf->tile_number == tile_number) {
if (imapf->packedfile) {
- ibuf = IMB_ibImageFromMemory((unsigned char *)imapf->packedfile->data,
+ ibuf = IMB_ibImageFromMemory((uchar *)imapf->packedfile->data,
imapf->packedfile->size,
flag,
ima->colorspace_settings.name,
@@ -4291,7 +4294,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc
Render *re;
RenderView *rv;
float *rectf, *rectz;
- unsigned int *rect;
+ uint *rect;
float dither;
int channels, layer, pass;
ImBuf *ibuf;
@@ -4350,12 +4353,12 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc
/* this gives active layer, composite or sequence result */
if (rv == nullptr) {
- rect = (unsigned int *)rres.rect32;
+ rect = (uint *)rres.rect32;
rectf = rres.rectf;
rectz = rres.rectz;
}
else {
- rect = (unsigned int *)rv->rect32;
+ rect = (uint *)rv->rect32;
rectf = rv->rectf;
rectz = rv->rectz;
}
@@ -5024,7 +5027,7 @@ void BKE_image_user_frame_calc(Image *ima, ImageUser *iuser, int cfra)
/* goes over all ImageUsers, and sets frame numbers if auto-refresh is set */
static void image_editors_update_frame(Image *ima,
- ID *UNUSED(iuser_id),
+ ID * /*iuser_id*/,
ImageUser *iuser,
void *customdata)
{
@@ -5046,8 +5049,8 @@ void BKE_image_editors_update_frame(const Main *bmain, int cfra)
}
static void image_user_id_has_animation(Image *ima,
- ID *UNUSED(iuser_id),
- ImageUser *UNUSED(iuser),
+ ID * /*iuser_id*/,
+ ImageUser * /*iuser*/,
void *customdata)
{
if (ima && BKE_image_is_animated(ima)) {
@@ -5066,7 +5069,7 @@ bool BKE_image_user_id_has_animation(ID *id)
}
static void image_user_id_eval_animation(Image *ima,
- ID *UNUSED(iduser_id),
+ ID * /*iduser_id*/,
ImageUser *iuser,
void *customdata)
{
@@ -5120,7 +5123,7 @@ void BKE_image_user_file_path_ex(const Main *bmain,
if (ELEM(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_TILED)) {
char head[FILE_MAX], tail[FILE_MAX];
- unsigned short numlen;
+ ushort numlen;
int index;
if (ima->source == IMA_SRC_SEQUENCE) {
@@ -5148,7 +5151,7 @@ bool BKE_image_has_alpha(Image *image)
const int planes = (ibuf ? ibuf->planes : 0);
BKE_image_release_ibuf(image, ibuf, lock);
- if (planes == 32 || planes == 16) {
+ if (ELEM(planes, 32, 16)) {
return true;
}
@@ -5187,8 +5190,8 @@ void BKE_image_get_size_fl(Image *image, ImageUser *iuser, float r_size[2])
int width, height;
BKE_image_get_size(image, iuser, &width, &height);
- r_size[0] = (float)width;
- r_size[1] = (float)height;
+ r_size[0] = float(width);
+ r_size[1] = float(height);
}
void BKE_image_get_aspect(Image *image, float *r_aspx, float *r_aspy)
@@ -5204,13 +5207,13 @@ void BKE_image_get_aspect(Image *image, float *r_aspx, float *r_aspy)
}
}
-unsigned char *BKE_image_get_pixels_for_frame(struct Image *image, int frame, int tile)
+uchar *BKE_image_get_pixels_for_frame(struct Image *image, int frame, int tile)
{
ImageUser iuser;
BKE_imageuser_default(&iuser);
void *lock;
ImBuf *ibuf;
- unsigned char *pixels = nullptr;
+ uchar *pixels = nullptr;
iuser.framenr = frame;
iuser.tile = tile;
@@ -5218,10 +5221,10 @@ unsigned char *BKE_image_get_pixels_for_frame(struct Image *image, int frame, in
ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
if (ibuf) {
- pixels = (unsigned char *)ibuf->rect;
+ pixels = (uchar *)ibuf->rect;
if (pixels) {
- pixels = static_cast<unsigned char *>(MEM_dupallocN(pixels));
+ pixels = static_cast<uchar *>(MEM_dupallocN(pixels));
}
BKE_image_release_ibuf(image, ibuf, lock);
@@ -5330,7 +5333,7 @@ bool BKE_image_is_dirty(Image *image)
return BKE_image_is_dirty_writable(image, nullptr);
}
-void BKE_image_mark_dirty(Image *UNUSED(image), ImBuf *ibuf)
+void BKE_image_mark_dirty(Image * /*image*/, ImBuf *ibuf)
{
ibuf->userflags |= IB_BITMAPDIRTY;
}
@@ -5567,15 +5570,14 @@ bool BKE_image_remove_renderslot(Image *ima, ImageUser *iuser, int slot)
next_last_slot = current_slot;
}
- if (!iuser) {
+ if (iuser == nullptr || iuser->scene == nullptr) {
return false;
}
Render *re = RE_GetSceneRender(iuser->scene);
- if (!re) {
- return false;
+ if (re != nullptr) {
+ RE_SwapResult(re, &current_last_slot->render);
+ RE_SwapResult(re, &next_last_slot->render);
}
- RE_SwapResult(re, &current_last_slot->render);
- RE_SwapResult(re, &next_last_slot->render);
current_last_slot = next_last_slot;
}
diff --git a/source/blender/blenkernel/intern/image_format.cc b/source/blender/blenkernel/intern/image_format.cc
index 57763e1670f..5b861eff166 100644
--- a/source/blender/blenkernel/intern/image_format.cc
+++ b/source/blender/blenkernel/intern/image_format.cc
@@ -201,6 +201,7 @@ bool BKE_imtype_is_movie(const char imtype)
case R_IMF_IMTYPE_H264:
case R_IMF_IMTYPE_THEORA:
case R_IMF_IMTYPE_XVID:
+ case R_IMF_IMTYPE_AV1:
return true;
}
return false;
@@ -272,7 +273,7 @@ char BKE_imtype_valid_channels(const char imtype, bool write_file)
case R_IMF_IMTYPE_JP2:
case R_IMF_IMTYPE_DPX:
case R_IMF_IMTYPE_WEBP:
- chan_flag |= IMA_CHAN_FLAG_ALPHA;
+ chan_flag |= IMA_CHAN_FLAG_RGBA;
break;
}
@@ -433,7 +434,8 @@ static bool do_add_image_extension(char *string,
R_IMF_IMTYPE_FFMPEG,
R_IMF_IMTYPE_H264,
R_IMF_IMTYPE_THEORA,
- R_IMF_IMTYPE_XVID)) {
+ R_IMF_IMTYPE_XVID,
+ R_IMF_IMTYPE_AV1)) {
if (!BLI_path_extension_check(string, extension_test = ".png")) {
extension = extension_test;
}
@@ -520,7 +522,7 @@ static bool do_add_image_extension(char *string,
}
#endif
else { // R_IMF_IMTYPE_AVIRAW, R_IMF_IMTYPE_AVIJPEG, R_IMF_IMTYPE_JPEG90 etc
- if (!(BLI_path_extension_check_n(string, extension_test = ".jpg", ".jpeg", nullptr))) {
+ if (!BLI_path_extension_check_n(string, extension_test = ".jpg", ".jpeg", nullptr)) {
extension = extension_test;
}
}
@@ -627,7 +629,8 @@ void BKE_image_format_to_imbuf(ImBuf *ibuf, const ImageFormatData *imf)
R_IMF_IMTYPE_FFMPEG,
R_IMF_IMTYPE_H264,
R_IMF_IMTYPE_THEORA,
- R_IMF_IMTYPE_XVID)) {
+ R_IMF_IMTYPE_XVID,
+ R_IMF_IMTYPE_AV1)) {
ibuf->ftype = IMB_FTYPE_PNG;
if (imtype == R_IMF_IMTYPE_PNG) {
diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c
index 5a299582890..aef64247346 100644
--- a/source/blender/blenkernel/intern/image_gen.c
+++ b/source/blender/blenkernel/intern/image_gen.c
@@ -19,14 +19,14 @@
#include "BLF_api.h"
typedef struct FillColorThreadData {
- unsigned char *rect;
+ uchar *rect;
float *rect_float;
int width;
float color[4];
} FillColorThreadData;
static void image_buf_fill_color_slice(
- unsigned char *rect, float *rect_float, int width, int height, const float color[4])
+ uchar *rect, float *rect_float, int width, int height, const float color[4])
{
int x, y;
@@ -41,7 +41,7 @@ static void image_buf_fill_color_slice(
}
if (rect) {
- unsigned char ccol[4];
+ uchar ccol[4];
rgba_float_to_uchar(ccol, color);
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
@@ -60,13 +60,13 @@ static void image_buf_fill_color_thread_do(void *data_v, int scanline)
FillColorThreadData *data = (FillColorThreadData *)data_v;
const int num_scanlines = 1;
size_t offset = ((size_t)scanline) * data->width * 4;
- unsigned char *rect = (data->rect != NULL) ? (data->rect + offset) : NULL;
+ uchar *rect = (data->rect != NULL) ? (data->rect + offset) : NULL;
float *rect_float = (data->rect_float != NULL) ? (data->rect_float + offset) : NULL;
image_buf_fill_color_slice(rect, rect_float, data->width, num_scanlines, data->color);
}
void BKE_image_buf_fill_color(
- unsigned char *rect, float *rect_float, int width, int height, const float color[4])
+ uchar *rect, float *rect_float, int width, int height, const float color[4])
{
if (((size_t)width) * height < 64 * 64) {
image_buf_fill_color_slice(rect, rect_float, width, height, color);
@@ -82,7 +82,7 @@ void BKE_image_buf_fill_color(
}
static void image_buf_fill_checker_slice(
- unsigned char *rect, float *rect_float, int width, int height, int offset)
+ uchar *rect, float *rect_float, int width, int height, int offset)
{
/* these two passes could be combined into one, but it's more readable and
* easy to tweak like this, speed isn't really that much of an issue in this situation... */
@@ -90,7 +90,7 @@ static void image_buf_fill_checker_slice(
int checkerwidth = 32;
int x, y;
- unsigned char *rect_orig = rect;
+ uchar *rect_orig = rect;
float *rect_float_orig = rect_float;
float hsv[3] = {0.0f, 0.9f, 0.9f};
@@ -178,7 +178,7 @@ static void image_buf_fill_checker_slice(
}
typedef struct FillCheckerThreadData {
- unsigned char *rect;
+ uchar *rect;
float *rect_float;
int width;
} FillCheckerThreadData;
@@ -188,12 +188,12 @@ static void image_buf_fill_checker_thread_do(void *data_v, int scanline)
FillCheckerThreadData *data = (FillCheckerThreadData *)data_v;
size_t offset = ((size_t)scanline) * data->width * 4;
const int num_scanlines = 1;
- unsigned char *rect = (data->rect != NULL) ? (data->rect + offset) : NULL;
+ uchar *rect = (data->rect != NULL) ? (data->rect + offset) : NULL;
float *rect_float = (data->rect_float != NULL) ? (data->rect_float + offset) : NULL;
image_buf_fill_checker_slice(rect, rect_float, data->width, num_scanlines, scanline);
}
-void BKE_image_buf_fill_checker(unsigned char *rect, float *rect_float, int width, int height)
+void BKE_image_buf_fill_checker(uchar *rect, float *rect_float, int width, int height)
{
if (((size_t)width) * height < 64 * 64) {
image_buf_fill_checker_slice(rect, rect_float, width, height, 0);
@@ -214,7 +214,7 @@ void BKE_image_buf_fill_checker(unsigned char *rect, float *rect_float, int widt
((real + (char)(add * 255.0f)) <= 255) ? (real + (char)(add * 255.0f)) : 255
static void checker_board_color_fill(
- unsigned char *rect, float *rect_float, int width, int height, int offset, int total_height)
+ uchar *rect, float *rect_float, int width, int height, int offset, int total_height)
{
int hue_step, y, x;
float hsv[3], rgb[3];
@@ -255,13 +255,8 @@ static void checker_board_color_fill(
}
}
-static void checker_board_color_tint(unsigned char *rect,
- float *rect_float,
- int width,
- int height,
- int size,
- float blend,
- int offset)
+static void checker_board_color_tint(
+ uchar *rect, float *rect_float, int width, int height, int size, float blend, int offset)
{
int x, y;
float blend_half = blend * 0.5f;
@@ -310,7 +305,7 @@ static void checker_board_color_tint(unsigned char *rect,
}
static void checker_board_grid_fill(
- unsigned char *rect, float *rect_float, int width, int height, float blend, int offset)
+ uchar *rect, float *rect_float, int width, int height, float blend, int offset)
{
int x, y;
for (y = offset; y < height + offset; y++) {
@@ -348,14 +343,14 @@ static void checker_board_grid_fill(
/* defined in image.c */
static void checker_board_text(
- unsigned char *rect, float *rect_float, int width, int height, int step, int outline)
+ uchar *rect, float *rect_float, int width, int height, int step, int outline)
{
int x, y;
int pen_x, pen_y;
char text[3] = {'A', '1', '\0'};
const int mono = blf_mono_font_render;
- BLF_size(mono, 54.0f, 72); /* hard coded size! */
+ BLF_size(mono, 54.0f); /* hard coded size! */
/* OCIO_TODO: using NULL as display will assume using sRGB display
* this is correct since currently generated images are assumed to be in sRGB space,
@@ -415,7 +410,7 @@ static void checker_board_text(
}
static void checker_board_color_prepare_slice(
- unsigned char *rect, float *rect_float, int width, int height, int offset, int total_height)
+ uchar *rect, float *rect_float, int width, int height, int offset, int total_height)
{
checker_board_color_fill(rect, rect_float, width, height, offset, total_height);
checker_board_color_tint(rect, rect_float, width, height, 1, 0.03f, offset);
@@ -426,7 +421,7 @@ static void checker_board_color_prepare_slice(
}
typedef struct FillCheckerColorThreadData {
- unsigned char *rect;
+ uchar *rect;
float *rect_float;
int width, height;
} FillCheckerColorThreadData;
@@ -436,16 +431,13 @@ static void checker_board_color_prepare_thread_do(void *data_v, int scanline)
FillCheckerColorThreadData *data = (FillCheckerColorThreadData *)data_v;
const int num_scanlines = 1;
size_t offset = ((size_t)data->width) * scanline * 4;
- unsigned char *rect = (data->rect != NULL) ? (data->rect + offset) : NULL;
+ uchar *rect = (data->rect != NULL) ? (data->rect + offset) : NULL;
float *rect_float = (data->rect_float != NULL) ? (data->rect_float + offset) : NULL;
checker_board_color_prepare_slice(
rect, rect_float, data->width, num_scanlines, scanline, data->height);
}
-void BKE_image_buf_fill_checker_color(unsigned char *rect,
- float *rect_float,
- int width,
- int height)
+void BKE_image_buf_fill_checker_color(uchar *rect, float *rect_float, int width, int height)
{
if (((size_t)width) * height < 64 * 64) {
checker_board_color_prepare_slice(rect, rect_float, width, height, 0, height);
diff --git a/source/blender/blenkernel/intern/image_gpu.cc b/source/blender/blenkernel/intern/image_gpu.cc
index 08fdd715512..6893a50638a 100644
--- a/source/blender/blenkernel/intern/image_gpu.cc
+++ b/source/blender/blenkernel/intern/image_gpu.cc
@@ -551,7 +551,7 @@ void BKE_image_free_anim_gputextures(Main *bmain)
void BKE_image_free_old_gputextures(Main *bmain)
{
static int lasttime = 0;
- int ctime = (int)PIL_check_seconds_timer();
+ int ctime = int(PIL_check_seconds_timer());
/*
* Run garbage collector once for every collecting period of time
@@ -602,8 +602,8 @@ static ImBuf *update_do_scale(uchar *rect,
int full_h)
{
/* Partial update with scaling. */
- float xratio = limit_w / (float)full_w;
- float yratio = limit_h / (float)full_h;
+ float xratio = limit_w / float(full_w);
+ float yratio = limit_h / float(full_h);
int part_w = *w, part_h = *h;
@@ -611,8 +611,8 @@ static ImBuf *update_do_scale(uchar *rect,
* losing 1 pixel due to rounding errors in x,y. */
*x *= xratio;
*y *= yratio;
- *w = (int)ceil(xratio * (*w));
- *h = (int)ceil(yratio * (*h));
+ *w = int(ceil(xratio * (*w)));
+ *h = int(ceil(yratio * (*h)));
/* ...but take back if we are over the limit! */
if (*x + *w > limit_w) {
diff --git a/source/blender/blenkernel/intern/image_save.cc b/source/blender/blenkernel/intern/image_save.cc
index 6f62ee123cb..003211e6288 100644
--- a/source/blender/blenkernel/intern/image_save.cc
+++ b/source/blender/blenkernel/intern/image_save.cc
@@ -175,12 +175,12 @@ bool BKE_image_save_options_init(ImageSaveOptions *opts,
BLI_strncpy(opts->filepath, G.ima, sizeof(opts->filepath));
}
else {
- BLI_path_join(opts->filepath, sizeof(opts->filepath), "//", DATA_("untitled"), nullptr);
+ BLI_path_join(opts->filepath, sizeof(opts->filepath), "//", DATA_("untitled"));
BLI_path_abs(opts->filepath, BKE_main_blendfile_path(bmain));
}
}
else {
- BLI_path_join(opts->filepath, sizeof(opts->filepath), "//", ima->id.name + 2, nullptr);
+ BLI_path_join(opts->filepath, sizeof(opts->filepath), "//", ima->id.name + 2);
BLI_path_make_safe(opts->filepath);
BLI_path_abs(opts->filepath, is_prev_save ? G.ima : BKE_main_blendfile_path(bmain));
}
@@ -473,7 +473,7 @@ static bool image_save_single(ReportList *reports,
}
/* individual multiview images */
else if (imf->views_format == R_IMF_VIEWS_INDIVIDUAL) {
- unsigned char planes = ibuf->planes;
+ uchar planes = ibuf->planes;
const int totviews = (rr ? BLI_listbase_count(&rr->views) : BLI_listbase_count(&ima->views));
if (!is_exr_rr) {
@@ -543,7 +543,7 @@ static bool image_save_single(ReportList *reports,
else {
ImBuf *ibuf_stereo[2] = {nullptr};
- unsigned char planes = ibuf->planes;
+ uchar planes = ibuf->planes;
const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
/* we need to get the specific per-view buffers */
@@ -724,6 +724,7 @@ bool BKE_image_render_write_exr(ReportList *reports,
const bool half_float = (imf && imf->depth == R_IMF_CHAN_DEPTH_16);
const bool multi_layer = !(imf && imf->imtype == R_IMF_IMTYPE_OPENEXR);
const bool write_z = !multi_layer && (imf && (imf->flag & R_IMF_FLAG_ZBUF));
+ const int channels = (!multi_layer && imf && imf->planes == R_IMF_PLANES_RGB) ? 3 : 4;
Vector<float *> tmp_output_rects;
/* Write first layer if not multilayer and no layer was specified. */
@@ -767,9 +768,10 @@ bool BKE_image_render_write_exr(ReportList *reports,
rview->rectf, rr->rectx, rr->recty, 4, imf, tmp_output_rects) :
rview->rectf;
- for (int a = 0; a < 4; a++) {
+ for (int a = 0; a < channels; a++) {
char passname[EXR_PASS_MAXNAME];
char layname[EXR_PASS_MAXNAME];
+ /* "A" is not used if only "RGB" channels are output. */
const char *chan_id = "RGBA";
if (multi_layer) {
@@ -798,8 +800,10 @@ bool BKE_image_render_write_exr(ReportList *reports,
LISTBASE_FOREACH (RenderLayer *, rl, &rr->layers) {
/* Skip other render layers if requested. */
if (!multi_layer && nr != layer) {
+ nr++;
continue;
}
+ nr++;
LISTBASE_FOREACH (RenderPass *, rp, &rl->passes) {
/* Skip non-RGBA and Z passes if not using multi layer. */
@@ -820,7 +824,7 @@ bool BKE_image_render_write_exr(ReportList *reports,
/* We only store RGBA passes as half float, for
* others precision loss can be problematic. */
- const bool pass_RGBA = (STR_ELEM(rp->chan_id, "RGB", "RGBA", "R", "G", "B", "A"));
+ const bool pass_RGBA = STR_ELEM(rp->chan_id, "RGB", "RGBA", "R", "G", "B", "A");
const bool pass_half_float = half_float && pass_RGBA;
/* Color-space conversion only happens on RGBA passes. */
@@ -830,8 +834,8 @@ bool BKE_image_render_write_exr(ReportList *reports,
rp->rect, rr->rectx, rr->recty, rp->channels, imf, tmp_output_rects) :
rp->rect;
- for (int a = 0; a < rp->channels; a++) {
- /* Save Combined as RGBA if single layer save. */
+ for (int a = 0; a < std::min(channels, rp->channels); a++) {
+ /* Save Combined as RGBA or RGB if single layer save. */
char passname[EXR_PASS_MAXNAME];
char layname[EXR_PASS_MAXNAME];
@@ -964,6 +968,7 @@ bool BKE_image_render_write(ReportList *reports,
/* optional preview images for exr */
if (ok && (image_format.flag & R_IMF_FLAG_PREVIEW_JPG)) {
image_format.imtype = R_IMF_IMTYPE_JPEG90;
+ image_format.depth = R_IMF_CHAN_DEPTH_8;
if (BLI_path_extension_check(filepath, ".exr")) {
filepath[strlen(filepath) - 4] = 0;
@@ -1021,6 +1026,7 @@ bool BKE_image_render_write(ReportList *reports,
/* optional preview images for exr */
if (ok && is_exr_rr && (image_format.flag & R_IMF_FLAG_PREVIEW_JPG)) {
image_format.imtype = R_IMF_IMTYPE_JPEG90;
+ image_format.depth = R_IMF_CHAN_DEPTH_8;
if (BLI_path_extension_check(filepath, ".exr")) {
filepath[strlen(filepath) - 4] = 0;
diff --git a/source/blender/blenkernel/intern/instances.cc b/source/blender/blenkernel/intern/instances.cc
new file mode 100644
index 00000000000..4675562e927
--- /dev/null
+++ b/source/blender/blenkernel/intern/instances.cc
@@ -0,0 +1,337 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BLI_array_utils.hh"
+#include "BLI_cpp_type_make.hh"
+#include "BLI_rand.hh"
+#include "BLI_task.hh"
+
+#include "BKE_attribute_math.hh"
+#include "BKE_geometry_set.hh"
+#include "BKE_instances.hh"
+
+BLI_CPP_TYPE_MAKE(InstanceReference, blender::bke::InstanceReference, CPPTypeFlags::None)
+
+namespace blender::bke {
+
+InstanceReference::InstanceReference(GeometrySet geometry_set)
+ : type_(Type::GeometrySet),
+ geometry_set_(std::make_unique<GeometrySet>(std::move(geometry_set)))
+{
+}
+
+void InstanceReference::ensure_owns_direct_data()
+{
+ if (type_ != Type::GeometrySet) {
+ return;
+ }
+ geometry_set_->ensure_owns_direct_data();
+}
+
+bool InstanceReference::owns_direct_data() const
+{
+ if (type_ != Type::GeometrySet) {
+ /* The object and collection instances are not direct data. */
+ return true;
+ }
+ return geometry_set_->owns_direct_data();
+}
+
+Instances::Instances(const Instances &other)
+ : references_(other.references_),
+ reference_handles_(other.reference_handles_),
+ transforms_(other.transforms_),
+ almost_unique_ids_(other.almost_unique_ids_),
+ attributes_(other.attributes_)
+{
+}
+
+void Instances::reserve(int min_capacity)
+{
+ reference_handles_.reserve(min_capacity);
+ transforms_.reserve(min_capacity);
+ attributes_.reallocate(min_capacity);
+}
+
+void Instances::resize(int capacity)
+{
+ reference_handles_.resize(capacity);
+ transforms_.resize(capacity);
+ attributes_.reallocate(capacity);
+}
+
+void Instances::add_instance(const int instance_handle, const float4x4 &transform)
+{
+ BLI_assert(instance_handle >= 0);
+ BLI_assert(instance_handle < references_.size());
+ reference_handles_.append(instance_handle);
+ transforms_.append(transform);
+ attributes_.reallocate(this->instances_num());
+}
+
+blender::Span<int> Instances::reference_handles() const
+{
+ return reference_handles_;
+}
+
+blender::MutableSpan<int> Instances::reference_handles()
+{
+ return reference_handles_;
+}
+
+blender::MutableSpan<blender::float4x4> Instances::transforms()
+{
+ return transforms_;
+}
+blender::Span<blender::float4x4> Instances::transforms() const
+{
+ return transforms_;
+}
+
+GeometrySet &Instances::geometry_set_from_reference(const int reference_index)
+{
+ /* If this assert fails, it means #ensure_geometry_instances must be called first or that the
+ * reference can't be converted to a geometry set. */
+ BLI_assert(references_[reference_index].type() == InstanceReference::Type::GeometrySet);
+
+ /* The const cast is okay because the instance's hash in the set
+ * is not changed by adjusting the data inside the geometry set. */
+ return const_cast<GeometrySet &>(references_[reference_index].geometry_set());
+}
+
+int Instances::add_reference(const InstanceReference &reference)
+{
+ return references_.index_of_or_add_as(reference);
+}
+
+blender::Span<InstanceReference> Instances::references() const
+{
+ return references_;
+}
+
+void Instances::remove(const IndexMask mask)
+{
+ using namespace blender;
+ if (mask.is_range() && mask.as_range().start() == 0) {
+ /* Deleting from the end of the array can be much faster since no data has to be shifted. */
+ this->resize(mask.size());
+ this->remove_unused_references();
+ return;
+ }
+
+ const Span<int> old_handles = this->reference_handles();
+ Vector<int> new_handles(mask.size());
+ array_utils::gather(old_handles, mask.indices(), new_handles.as_mutable_span());
+ reference_handles_ = std::move(new_handles);
+
+ const Span<float4x4> old_tansforms = this->transforms();
+ Vector<float4x4> new_transforms(mask.size());
+ array_utils::gather(old_tansforms, mask.indices(), new_transforms.as_mutable_span());
+ transforms_ = std::move(new_transforms);
+
+ const bke::CustomDataAttributes &src_attributes = attributes_;
+
+ bke::CustomDataAttributes dst_attributes;
+ dst_attributes.reallocate(mask.size());
+
+ src_attributes.foreach_attribute(
+ [&](const bke::AttributeIDRef &id, const bke::AttributeMetaData &meta_data) {
+ if (!id.should_be_kept()) {
+ return true;
+ }
+
+ GSpan src = *src_attributes.get_for_read(id);
+ dst_attributes.create(id, meta_data.data_type);
+ GMutableSpan dst = *dst_attributes.get_for_write(id);
+ array_utils::gather(src, mask.indices(), dst);
+
+ return true;
+ },
+ ATTR_DOMAIN_INSTANCE);
+
+ attributes_ = std::move(dst_attributes);
+ this->remove_unused_references();
+}
+
+void Instances::remove_unused_references()
+{
+ using namespace blender;
+ using namespace blender::bke;
+
+ const int tot_instances = this->instances_num();
+ const int tot_references_before = references_.size();
+
+ if (tot_instances == 0) {
+ /* If there are no instances, no reference is needed. */
+ references_.clear();
+ return;
+ }
+ if (tot_references_before == 1) {
+ /* There is only one reference and at least one instance. So the only existing reference is
+ * used. Nothing to do here. */
+ return;
+ }
+
+ Array<bool> usage_by_handle(tot_references_before, false);
+ std::mutex mutex;
+
+ /* Loop over all instances to see which references are used. */
+ threading::parallel_for(IndexRange(tot_instances), 1000, [&](IndexRange range) {
+ /* Use local counter to avoid lock contention. */
+ Array<bool> local_usage_by_handle(tot_references_before, false);
+
+ for (const int i : range) {
+ const int handle = reference_handles_[i];
+ BLI_assert(handle >= 0 && handle < tot_references_before);
+ local_usage_by_handle[handle] = true;
+ }
+
+ std::lock_guard lock{mutex};
+ for (const int i : IndexRange(tot_references_before)) {
+ usage_by_handle[i] |= local_usage_by_handle[i];
+ }
+ });
+
+ if (!usage_by_handle.as_span().contains(false)) {
+ /* All references are used. */
+ return;
+ }
+
+ /* Create new references and a mapping for the handles. */
+ Vector<int> handle_mapping;
+ VectorSet<InstanceReference> new_references;
+ int next_new_handle = 0;
+ bool handles_have_to_be_updated = false;
+ for (const int old_handle : IndexRange(tot_references_before)) {
+ if (!usage_by_handle[old_handle]) {
+ /* Add some dummy value. It won't be read again. */
+ handle_mapping.append(-1);
+ }
+ else {
+ const InstanceReference &reference = references_[old_handle];
+ handle_mapping.append(next_new_handle);
+ new_references.add_new(reference);
+ if (old_handle != next_new_handle) {
+ handles_have_to_be_updated = true;
+ }
+ next_new_handle++;
+ }
+ }
+ references_ = new_references;
+
+ if (!handles_have_to_be_updated) {
+ /* All remaining handles are the same as before, so they don't have to be updated. This happens
+ * when unused handles are only at the end. */
+ return;
+ }
+
+ /* Update handles of instances. */
+ threading::parallel_for(IndexRange(tot_instances), 1000, [&](IndexRange range) {
+ for (const int i : range) {
+ reference_handles_[i] = handle_mapping[reference_handles_[i]];
+ }
+ });
+}
+
+int Instances::instances_num() const
+{
+ return transforms_.size();
+}
+
+int Instances::references_num() const
+{
+ return references_.size();
+}
+
+bool Instances::owns_direct_data() const
+{
+ for (const InstanceReference &reference : references_) {
+ if (!reference.owns_direct_data()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void Instances::ensure_owns_direct_data()
+{
+ for (const InstanceReference &const_reference : references_) {
+ /* `const` cast is fine because we are not changing anything that would change the hash of the
+ * reference. */
+ InstanceReference &reference = const_cast<InstanceReference &>(const_reference);
+ reference.ensure_owns_direct_data();
+ }
+}
+
+static blender::Array<int> generate_unique_instance_ids(Span<int> original_ids)
+{
+ using namespace blender;
+ Array<int> unique_ids(original_ids.size());
+
+ Set<int> used_unique_ids;
+ used_unique_ids.reserve(original_ids.size());
+ Vector<int> instances_with_id_collision;
+ for (const int instance_index : original_ids.index_range()) {
+ const int original_id = original_ids[instance_index];
+ if (used_unique_ids.add(original_id)) {
+ /* The original id has not been used by another instance yet. */
+ unique_ids[instance_index] = original_id;
+ }
+ else {
+ /* The original id of this instance collided with a previous instance, it needs to be looked
+ * at again in a second pass. Don't generate a new random id here, because this might collide
+ * with other existing ids. */
+ instances_with_id_collision.append(instance_index);
+ }
+ }
+
+ Map<int, RandomNumberGenerator> generator_by_original_id;
+ for (const int instance_index : instances_with_id_collision) {
+ const int original_id = original_ids[instance_index];
+ RandomNumberGenerator &rng = generator_by_original_id.lookup_or_add_cb(original_id, [&]() {
+ RandomNumberGenerator rng;
+ rng.seed_random(original_id);
+ return rng;
+ });
+
+ const int max_iteration = 100;
+ for (int iteration = 0;; iteration++) {
+ /* Try generating random numbers until an unused one has been found. */
+ const int random_id = rng.get_int32();
+ if (used_unique_ids.add(random_id)) {
+ /* This random id is not used by another instance. */
+ unique_ids[instance_index] = random_id;
+ break;
+ }
+ if (iteration == max_iteration) {
+ /* It seems to be very unlikely that we ever run into this case (assuming there are less
+ * than 2^30 instances). However, if that happens, it's better to use an id that is not
+ * unique than to be stuck in an infinite loop. */
+ unique_ids[instance_index] = original_id;
+ break;
+ }
+ }
+ }
+
+ return unique_ids;
+}
+
+blender::Span<int> Instances::almost_unique_ids() const
+{
+ std::lock_guard lock(almost_unique_ids_mutex_);
+ std::optional<GSpan> instance_ids_gspan = attributes_.get_for_read("id");
+ if (instance_ids_gspan) {
+ Span<int> instance_ids = instance_ids_gspan->typed<int>();
+ if (almost_unique_ids_.size() != instance_ids.size()) {
+ almost_unique_ids_ = generate_unique_instance_ids(instance_ids);
+ }
+ }
+ else {
+ almost_unique_ids_.reinitialize(this->instances_num());
+ for (const int i : almost_unique_ids_.index_range()) {
+ almost_unique_ids_[i] = i;
+ }
+ }
+ return almost_unique_ids_;
+}
+
+} // namespace blender::bke
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 22c0007cbc0..a21033a8b91 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -1147,7 +1147,7 @@ static char *get_rna_access(ID *id,
/* 'buf' _must_ be initialized in this block */
/* append preceding bits to path */
- /* NOTE: strings are not escapted and they should be! */
+ /* NOTE: strings are not escaped and they should be! */
if ((actname && actname[0]) && (constname && constname[0])) {
/* Constraint in Pose-Channel */
char actname_esc[sizeof(((bActionChannel *)NULL)->name) * 2];
@@ -1492,7 +1492,7 @@ static void icu_to_fcurves(ID *id,
* 3) filter the keyframes for the flag of interest
*/
for (b = 0; b < totbits; b++, abp++) {
- unsigned int i = 0;
+ uint i = 0;
/* make a copy of existing base-data if not the last curve */
if (b < (totbits - 1)) {
@@ -1542,7 +1542,7 @@ static void icu_to_fcurves(ID *id,
}
/* correct values, by checking if the flag of interest is set */
- if (((int)(dst->vec[1][1])) & (abp->bit)) {
+ if ((int)(dst->vec[1][1]) & (abp->bit)) {
dst->vec[0][1] = dst->vec[1][1] = dst->vec[2][1] = 1.0f;
}
else {
@@ -1562,7 +1562,7 @@ static void icu_to_fcurves(ID *id,
}
}
else {
- unsigned int i = 0;
+ uint i = 0;
/* get rna-path
* - we will need to set the 'disabled' flag if no path is able to be made (for now)
@@ -2142,7 +2142,7 @@ void do_versions_ipos_to_animato(Main *bmain)
if (ob->action) {
action_to_animdata(id, ob->action);
- /* only decrease usercount if this Action isn't now being used by AnimData */
+ /* Only decrease user-count if this Action isn't now being used by AnimData. */
if (ob->action != adt->action) {
id_us_min(&ob->action->id);
ob->action = NULL;
@@ -2246,7 +2246,7 @@ void do_versions_ipos_to_animato(Main *bmain)
/* Add AnimData block */
AnimData *adt = BKE_animdata_ensure_id(id);
- /* Convert Shapekey data... */
+ /* Convert Shape-key data... */
ipo_to_animdata(bmain, id, key->ipo, NULL, NULL, NULL);
if (adt->action) {
diff --git a/source/blender/blenkernel/intern/kelvinlet.c b/source/blender/blenkernel/intern/kelvinlet.c
index 73a84f06ad8..4ccd848b9d7 100644
--- a/source/blender/blenkernel/intern/kelvinlet.c
+++ b/source/blender/blenkernel/intern/kelvinlet.c
@@ -154,7 +154,7 @@ static void kelvinlet_scale(float disp[3],
sub_v3_v3v3(radius_vertex, vertex_co, location);
const float radius = len_v3(radius_vertex);
const float radius_e = sqrtf(pow2f(radius) + pow2f(p->radius_scaled[0]));
- const float u = (2.0f * p->b - p->a) * ((1.0f / pow3f(radius_e))) +
+ const float u = (2.0f * p->b - p->a) * (1.0f / pow3f(radius_e)) +
((3.0f * pow2f(p->radius_scaled[0])) / (2.0f * pow5f(radius_e)));
const float fade = u * p->c;
mul_v3_v3fl(disp, radius_vertex, fade * p->f);
@@ -181,7 +181,7 @@ static void kelvinlet_twist(float disp[3],
sub_v3_v3v3(radius_vertex, vertex_co, location);
const float radius = len_v3(radius_vertex);
const float radius_e = sqrtf(pow2f(radius) + pow2f(p->radius_scaled[0]));
- const float u = -p->a * ((1.0f / pow3f(radius_e))) +
+ const float u = -p->a * (1.0f / pow3f(radius_e)) +
((3.0f * pow2f(p->radius_scaled[0])) / (2.0f * pow5f(radius_e)));
const float fade = u * p->c;
cross_v3_v3v3(q_r, normal, radius_vertex);
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index e0959182fa4..0adf162b4eb 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -245,7 +245,7 @@ int BKE_lattice_index_flip(
void BKE_lattice_bitmap_from_flag(
Lattice *lt, BLI_bitmap *bitmap, const uint8_t flag, const bool clear, const bool respecthide)
{
- const unsigned int tot = lt->pntsu * lt->pntsv * lt->pntsw;
+ const uint tot = lt->pntsu * lt->pntsv * lt->pntsw;
BPoint *bp;
bp = lt->def;
@@ -355,10 +355,10 @@ void BKE_lattice_resize(Lattice *lt, int uNew, int vNew, int wNew, Object *ltOb)
BKE_displist_free(&ltOb->runtime.curve_cache->disp);
}
- copy_m4_m4(mat, ltOb->obmat);
- unit_m4(ltOb->obmat);
+ copy_m4_m4(mat, ltOb->object_to_world);
+ unit_m4(ltOb->object_to_world);
BKE_lattice_deform_coords(ltOb, NULL, vert_coords, uNew * vNew * wNew, 0, NULL, 1.0f);
- copy_m4_m4(ltOb->obmat, mat);
+ copy_m4_m4(ltOb->object_to_world, mat);
lt->typeu = typeu;
lt->typev = typev;
diff --git a/source/blender/blenkernel/intern/lattice_deform.c b/source/blender/blenkernel/intern/lattice_deform.c
index 3a1c42b9178..892889aa426 100644
--- a/source/blender/blenkernel/intern/lattice_deform.c
+++ b/source/blender/blenkernel/intern/lattice_deform.c
@@ -79,15 +79,15 @@ LatticeDeformData *BKE_lattice_deform_data_create(const Object *oblatt, const Ob
/* for example with a particle system: (ob == NULL) */
if (ob == NULL) {
/* In deform-space, calc matrix. */
- invert_m4_m4(latmat, oblatt->obmat);
+ invert_m4_m4(latmat, oblatt->object_to_world);
/* back: put in deform array */
invert_m4_m4(imat, latmat);
}
else {
/* In deform-space, calc matrix. */
- invert_m4_m4(imat, oblatt->obmat);
- mul_m4_m4m4(latmat, imat, ob->obmat);
+ invert_m4_m4(imat, oblatt->object_to_world);
+ mul_m4_m4m4(latmat, imat, ob->object_to_world);
/* back: put in deform array. */
invert_m4_m4(imat, latmat);
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 2b49da6dbe9..5b54f16661c 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -284,9 +284,10 @@ void BKE_view_layer_free_ex(ViewLayer *view_layer, const bool do_id_user)
MEM_freeN(view_layer);
}
-void BKE_view_layer_selected_objects_tag(ViewLayer *view_layer, const int tag)
+void BKE_view_layer_selected_objects_tag(const Scene *scene, ViewLayer *view_layer, const int tag)
{
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if ((base->flag & BASE_SELECTED) != 0) {
base->object->flag |= tag;
}
@@ -309,9 +310,10 @@ static bool find_scene_collection_in_scene_collections(ListBase *lb, const Layer
return false;
}
-Object *BKE_view_layer_camera_find(ViewLayer *view_layer)
+Object *BKE_view_layer_camera_find(const Scene *scene, ViewLayer *view_layer)
{
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (base->object->type == OB_CAMERA) {
return base->object;
}
@@ -379,6 +381,8 @@ static void view_layer_bases_hash_create(ViewLayer *view_layer, const bool do_ba
Base *BKE_view_layer_base_find(ViewLayer *view_layer, Object *ob)
{
+ BLI_assert_msg((view_layer->flag & VIEW_LAYER_OUT_OF_SYNC) == 0,
+ "View layer out of sync, invoke BKE_view_layer_synced_ensure.");
if (!view_layer->object_bases_hash) {
view_layer_bases_hash_create(view_layer, false);
}
@@ -386,11 +390,10 @@ Base *BKE_view_layer_base_find(ViewLayer *view_layer, Object *ob)
return BLI_ghash_lookup(view_layer->object_bases_hash, ob);
}
-void BKE_view_layer_base_deselect_all(ViewLayer *view_layer)
+void BKE_view_layer_base_deselect_all(const Scene *scene, ViewLayer *view_layer)
{
- Base *base;
-
- for (base = view_layer->object_bases.first; base; base = base->next) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
base->flag &= ~BASE_SELECTED;
}
}
@@ -502,7 +505,9 @@ void BKE_view_layer_copy_data(Scene *scene_dst,
/* Copy layer collections and object bases. */
/* Inline 'BLI_duplicatelist' and update the active base. */
BLI_listbase_clear(&view_layer_dst->object_bases);
- LISTBASE_FOREACH (Base *, base_src, &view_layer_src->object_bases) {
+ BLI_assert_msg((view_layer_src->flag & VIEW_LAYER_OUT_OF_SYNC) == 0,
+ "View Layer Object Base out of sync, invoke BKE_view_layer_synced_ensure.");
+ LISTBASE_FOREACH (const Base *, base_src, &view_layer_src->object_bases) {
Base *base_dst = MEM_dupallocN(base_src);
BLI_addtail(&view_layer_dst->object_bases, base_dst);
if (view_layer_src->basact == base_src) {
@@ -609,7 +614,7 @@ static bool layer_collection_hidden(ViewLayer *view_layer, LayerCollection *lc)
return true;
}
- /* Check visiblilty restriction flags */
+ /* Check visibility restriction flags */
if (lc->flag & LAYER_COLLECTION_HIDE || lc->collection->flag & COLLECTION_HIDE_VIEWPORT) {
return true;
}
@@ -957,6 +962,36 @@ static void layer_collection_resync_unused_layers_free(ViewLayer *view_layer,
}
}
+void BKE_view_layer_need_resync_tag(struct ViewLayer *view_layer)
+{
+ view_layer->flag |= VIEW_LAYER_OUT_OF_SYNC;
+}
+
+void BKE_view_layer_synced_ensure(const Scene *scene, struct ViewLayer *view_layer)
+{
+ if (view_layer->flag & VIEW_LAYER_OUT_OF_SYNC) {
+ BKE_layer_collection_sync(scene, view_layer);
+ view_layer->flag &= ~VIEW_LAYER_OUT_OF_SYNC;
+ }
+}
+
+void BKE_scene_view_layers_synced_ensure(const Scene *scene)
+{
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ }
+}
+
+void BKE_main_view_layers_synced_ensure(const Main *bmain)
+{
+ for (const Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
+ BKE_scene_view_layers_synced_ensure(scene);
+ }
+
+ /* NOTE: This is not (yet?) covered by the dirty tag and differed re-sync system */
+ BKE_layer_collection_local_sync_all(bmain);
+}
+
static void layer_collection_objects_sync(ViewLayer *view_layer,
LayerCollection *layer,
ListBase *r_lb_new_object_bases,
@@ -1004,7 +1039,7 @@ static void layer_collection_objects_sync(ViewLayer *view_layer,
if ((layer_restrict & LAYER_COLLECTION_HIDE) == 0) {
base->flag_from_collection |= BASE_ENABLED_AND_VISIBLE_IN_DEFAULT_VIEWPORT;
}
- if (((collection_restrict & COLLECTION_HIDE_SELECT) == 0)) {
+ if ((collection_restrict & COLLECTION_HIDE_SELECT) == 0) {
base->flag_from_collection |= BASE_SELECTABLE;
}
}
@@ -1014,7 +1049,7 @@ static void layer_collection_objects_sync(ViewLayer *view_layer,
}
/* Holdout and indirect only */
- if ((layer->flag & LAYER_COLLECTION_HOLDOUT) || (base->object->visibility_flag & OB_HOLDOUT)) {
+ if ((layer->flag & LAYER_COLLECTION_HOLDOUT)) {
base->flag_from_collection |= BASE_HOLDOUT;
}
if (layer->flag & LAYER_COLLECTION_INDIRECT_ONLY) {
@@ -1050,8 +1085,14 @@ static void layer_collection_sync(ViewLayer *view_layer,
BLI_assert(layer_resync->is_used);
+ uint64_t skipped_children = 0;
LISTBASE_FOREACH (CollectionChild *, child, &layer_resync->collection->children) {
Collection *child_collection = child->collection;
+ /* Collection relations may not have rebuild yet. */
+ if (child_collection == NULL) {
+ skipped_children++;
+ continue;
+ }
LayerCollectionResync *child_layer_resync = layer_collection_resync_find(layer_resync,
child_collection);
@@ -1156,7 +1197,7 @@ static void layer_collection_sync(ViewLayer *view_layer,
/* Replace layer collection list with new one. */
layer_resync->layer->layer_collections = new_lb_layer;
- BLI_assert(BLI_listbase_count(&layer_resync->collection->children) ==
+ BLI_assert(BLI_listbase_count(&layer_resync->collection->children) - skipped_children ==
BLI_listbase_count(&new_lb_layer));
/* Update bases etc. for objects. */
@@ -1342,7 +1383,7 @@ void BKE_scene_collection_sync(const Scene *scene)
}
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
- BKE_layer_collection_sync(scene, view_layer);
+ BKE_view_layer_need_resync_tag(view_layer);
}
}
@@ -1408,7 +1449,10 @@ void BKE_main_collection_sync_remap(const Main *bmain)
/** \name Object Selection
* \{ */
-bool BKE_layer_collection_objects_select(ViewLayer *view_layer, LayerCollection *lc, bool deselect)
+bool BKE_layer_collection_objects_select(const Scene *scene,
+ ViewLayer *view_layer,
+ LayerCollection *lc,
+ bool deselect)
{
if (lc->collection->flag & COLLECTION_HIDE_SELECT) {
return false;
@@ -1417,6 +1461,7 @@ bool BKE_layer_collection_objects_select(ViewLayer *view_layer, LayerCollection
bool changed = false;
if (!(lc->flag & LAYER_COLLECTION_EXCLUDE)) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
LISTBASE_FOREACH (CollectionObject *, cob, &lc->collection->gobject) {
Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
@@ -1438,19 +1483,22 @@ bool BKE_layer_collection_objects_select(ViewLayer *view_layer, LayerCollection
}
LISTBASE_FOREACH (LayerCollection *, iter, &lc->layer_collections) {
- changed |= BKE_layer_collection_objects_select(view_layer, iter, deselect);
+ changed |= BKE_layer_collection_objects_select(scene, view_layer, iter, deselect);
}
return changed;
}
-bool BKE_layer_collection_has_selected_objects(ViewLayer *view_layer, LayerCollection *lc)
+bool BKE_layer_collection_has_selected_objects(const Scene *scene,
+ ViewLayer *view_layer,
+ LayerCollection *lc)
{
if (lc->collection->flag & COLLECTION_HIDE_SELECT) {
return false;
}
if (!(lc->flag & LAYER_COLLECTION_EXCLUDE)) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
LISTBASE_FOREACH (CollectionObject *, cob, &lc->collection->gobject) {
Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
@@ -1462,7 +1510,7 @@ bool BKE_layer_collection_has_selected_objects(ViewLayer *view_layer, LayerColle
}
LISTBASE_FOREACH (LayerCollection *, iter, &lc->layer_collections) {
- if (BKE_layer_collection_has_selected_objects(view_layer, iter)) {
+ if (BKE_layer_collection_has_selected_objects(scene, view_layer, iter)) {
return true;
}
}
@@ -1495,7 +1543,8 @@ void BKE_base_set_visible(Scene *scene, ViewLayer *view_layer, Base *base, bool
{
if (!extend) {
/* Make only one base visible. */
- LISTBASE_FOREACH (Base *, other, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, other, BKE_view_layer_object_bases_get(view_layer)) {
other->flag |= BASE_HIDDEN;
}
@@ -1506,7 +1555,7 @@ void BKE_base_set_visible(Scene *scene, ViewLayer *view_layer, Base *base, bool
base->flag ^= BASE_HIDDEN;
}
- BKE_layer_collection_sync(scene, view_layer);
+ BKE_view_layer_need_resync_tag(view_layer);
}
bool BKE_base_is_visible(const View3D *v3d, const Base *base)
@@ -1585,7 +1634,7 @@ static void layer_collection_flag_unset_recursive(LayerCollection *lc, const int
}
}
-void BKE_layer_collection_isolate_global(Scene *scene,
+void BKE_layer_collection_isolate_global(Scene *UNUSED(scene),
ViewLayer *view_layer,
LayerCollection *lc,
bool extend)
@@ -1630,7 +1679,7 @@ void BKE_layer_collection_isolate_global(Scene *scene,
BKE_layer_collection_activate(view_layer, lc);
}
- BKE_layer_collection_sync(scene, view_layer);
+ BKE_view_layer_need_resync_tag(view_layer);
}
static void layer_collection_local_visibility_set_recursive(LayerCollection *layer_collection,
@@ -1651,9 +1700,10 @@ static void layer_collection_local_visibility_unset_recursive(LayerCollection *l
}
}
-static void layer_collection_local_sync(ViewLayer *view_layer,
+static void layer_collection_local_sync(const Scene *scene,
+ ViewLayer *view_layer,
LayerCollection *layer_collection,
- const unsigned short local_collections_uuid,
+ const ushort local_collections_uuid,
bool visible)
{
if ((layer_collection->local_collections_bits & local_collections_uuid) == 0) {
@@ -1666,6 +1716,7 @@ static void layer_collection_local_sync(ViewLayer *view_layer,
continue;
}
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
base->local_collections_bits |= local_collections_uuid;
}
@@ -1673,26 +1724,27 @@ static void layer_collection_local_sync(ViewLayer *view_layer,
LISTBASE_FOREACH (LayerCollection *, child, &layer_collection->layer_collections) {
if ((child->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
- layer_collection_local_sync(view_layer, child, local_collections_uuid, visible);
+ layer_collection_local_sync(scene, view_layer, child, local_collections_uuid, visible);
}
}
}
-void BKE_layer_collection_local_sync(ViewLayer *view_layer, const View3D *v3d)
+void BKE_layer_collection_local_sync(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
{
if (no_resync) {
return;
}
- const unsigned short local_collections_uuid = v3d->local_collections_uuid;
+ const ushort local_collections_uuid = v3d->local_collections_uuid;
/* Reset flags and set the bases visible by default. */
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
base->local_collections_bits &= ~local_collections_uuid;
}
LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) {
- layer_collection_local_sync(view_layer, layer_collection, local_collections_uuid, true);
+ layer_collection_local_sync(scene, view_layer, layer_collection, local_collections_uuid, true);
}
}
@@ -1711,7 +1763,7 @@ void BKE_layer_collection_local_sync_all(const Main *bmain)
}
View3D *v3d = area->spacedata.first;
if (v3d->flag & V3D_LOCAL_COLLECTIONS) {
- BKE_layer_collection_local_sync(view_layer, v3d);
+ BKE_layer_collection_local_sync(scene, view_layer, v3d);
}
}
}
@@ -1719,10 +1771,8 @@ void BKE_layer_collection_local_sync_all(const Main *bmain)
}
}
-void BKE_layer_collection_isolate_local(ViewLayer *view_layer,
- const View3D *v3d,
- LayerCollection *lc,
- bool extend)
+void BKE_layer_collection_isolate_local(
+ const Scene *scene, ViewLayer *view_layer, const View3D *v3d, LayerCollection *lc, bool extend)
{
LayerCollection *lc_master = view_layer->layer_collections.first;
bool hide_it = extend && ((v3d->local_collections_uuid & lc->local_collections_bits) != 0);
@@ -1762,36 +1812,43 @@ void BKE_layer_collection_isolate_local(ViewLayer *view_layer,
layer_collection_local_visibility_set_recursive(lc, v3d->local_collections_uuid);
}
- BKE_layer_collection_local_sync(view_layer, v3d);
+ BKE_layer_collection_local_sync(scene, view_layer, v3d);
}
-static void layer_collection_bases_show_recursive(ViewLayer *view_layer, LayerCollection *lc)
+static void layer_collection_bases_show_recursive(const Scene *scene,
+ ViewLayer *view_layer,
+ LayerCollection *lc)
{
if ((lc->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
LISTBASE_FOREACH (CollectionObject *, cob, &lc->collection->gobject) {
Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
base->flag &= ~BASE_HIDDEN;
}
}
LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc->layer_collections) {
- layer_collection_bases_show_recursive(view_layer, lc_iter);
+ layer_collection_bases_show_recursive(scene, view_layer, lc_iter);
}
}
-static void layer_collection_bases_hide_recursive(ViewLayer *view_layer, LayerCollection *lc)
+static void layer_collection_bases_hide_recursive(const Scene *scene,
+ ViewLayer *view_layer,
+ LayerCollection *lc)
{
if ((lc->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
LISTBASE_FOREACH (CollectionObject *, cob, &lc->collection->gobject) {
Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
base->flag |= BASE_HIDDEN;
}
}
LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc->layer_collections) {
- layer_collection_bases_hide_recursive(view_layer, lc_iter);
+ layer_collection_bases_hide_recursive(scene, view_layer, lc_iter);
}
}
-void BKE_layer_collection_set_visible(ViewLayer *view_layer,
+void BKE_layer_collection_set_visible(const Scene *scene,
+ ViewLayer *view_layer,
LayerCollection *lc,
const bool visible,
const bool hierarchy)
@@ -1799,11 +1856,11 @@ void BKE_layer_collection_set_visible(ViewLayer *view_layer,
if (hierarchy) {
if (visible) {
layer_collection_flag_unset_recursive(lc, LAYER_COLLECTION_HIDE);
- layer_collection_bases_show_recursive(view_layer, lc);
+ layer_collection_bases_show_recursive(scene, view_layer, lc);
}
else {
layer_collection_flag_set_recursive(lc, LAYER_COLLECTION_HIDE);
- layer_collection_bases_hide_recursive(view_layer, lc);
+ layer_collection_bases_hide_recursive(scene, view_layer, lc);
}
}
else {
@@ -1898,6 +1955,7 @@ bool BKE_view_layer_has_collection(const ViewLayer *view_layer, const Collection
bool BKE_scene_has_object(Scene *scene, Object *ob)
{
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob);
if (base) {
return true;
@@ -1937,7 +1995,7 @@ static void object_bases_iterator_begin(BLI_Iterator *iter, void *data_in_v, con
ObjectsVisibleIteratorData *data_in = data_in_v;
ViewLayer *view_layer = data_in->view_layer;
const View3D *v3d = data_in->v3d;
- Base *base = view_layer->object_bases.first;
+ Base *base = BKE_view_layer_object_bases_get(view_layer)->first;
/* when there are no objects */
if (base == NULL) {
@@ -2236,18 +2294,19 @@ void BKE_base_eval_flags(Base *base)
}
static void layer_eval_view_layer(struct Depsgraph *depsgraph,
- struct Scene *UNUSED(scene),
+ struct Scene *scene,
ViewLayer *view_layer)
{
DEG_debug_print_eval(depsgraph, __func__, view_layer->name, view_layer);
/* Create array of bases, for fast index-based lookup. */
- const int num_object_bases = BLI_listbase_count(&view_layer->object_bases);
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ const int num_object_bases = BLI_listbase_count(BKE_view_layer_object_bases_get(view_layer));
MEM_SAFE_FREE(view_layer->object_bases_array);
view_layer->object_bases_array = MEM_malloc_arrayN(
num_object_bases, sizeof(Base *), "view_layer->object_bases_array");
int base_index = 0;
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
view_layer->object_bases_array[base_index++] = base;
}
}
@@ -2277,10 +2336,11 @@ static void write_layer_collections(BlendWriter *writer, ListBase *lb)
}
}
-void BKE_view_layer_blend_write(BlendWriter *writer, ViewLayer *view_layer)
+void BKE_view_layer_blend_write(BlendWriter *writer, const Scene *scene, ViewLayer *view_layer)
{
+ BKE_view_layer_synced_ensure(scene, view_layer);
BLO_write_struct(writer, ViewLayer, view_layer);
- BLO_write_struct_list(writer, Base, &view_layer->object_bases);
+ BLO_write_struct_list(writer, Base, BKE_view_layer_object_bases_get(view_layer));
if (view_layer->id_properties) {
IDP_BlendWrite(writer, view_layer->id_properties);
diff --git a/source/blender/blenkernel/intern/layer_utils.c b/source/blender/blenkernel/intern/layer_utils.c
index 3e41479c22c..23067d1a4e3 100644
--- a/source/blender/blenkernel/intern/layer_utils.c
+++ b/source/blender/blenkernel/intern/layer_utils.c
@@ -84,13 +84,14 @@ Object **BKE_view_layer_array_selected_objects_params(
/** \name Objects in Mode Array
* \{ */
-Base **BKE_view_layer_array_from_bases_in_mode_params(ViewLayer *view_layer,
+Base **BKE_view_layer_array_from_bases_in_mode_params(const Scene *scene,
+ ViewLayer *view_layer,
const View3D *v3d,
uint *r_len,
const struct ObjectsInModeParams *params)
{
if (params->no_dup_data) {
- FOREACH_BASE_IN_MODE_BEGIN (view_layer, v3d, -1, params->object_mode, base_iter) {
+ FOREACH_BASE_IN_MODE_BEGIN (scene, view_layer, v3d, -1, params->object_mode, base_iter) {
ID *id = base_iter->object->data;
if (id) {
id->tag |= LIB_TAG_DOIT;
@@ -102,7 +103,7 @@ Base **BKE_view_layer_array_from_bases_in_mode_params(ViewLayer *view_layer,
Base **base_array = NULL;
BLI_array_declare(base_array);
- FOREACH_BASE_IN_MODE_BEGIN (view_layer, v3d, -1, params->object_mode, base_iter) {
+ FOREACH_BASE_IN_MODE_BEGIN (scene, view_layer, v3d, -1, params->object_mode, base_iter) {
if (params->filter_fn) {
if (!params->filter_fn(base_iter->object, params->filter_userdata)) {
continue;
@@ -134,13 +135,14 @@ Base **BKE_view_layer_array_from_bases_in_mode_params(ViewLayer *view_layer,
return base_array;
}
-Object **BKE_view_layer_array_from_objects_in_mode_params(ViewLayer *view_layer,
+Object **BKE_view_layer_array_from_objects_in_mode_params(const Scene *scene,
+ ViewLayer *view_layer,
const View3D *v3d,
uint *r_len,
const struct ObjectsInModeParams *params)
{
Base **base_array = BKE_view_layer_array_from_bases_in_mode_params(
- view_layer, v3d, r_len, params);
+ scene, view_layer, v3d, r_len, params);
if (base_array != NULL) {
for (uint i = 0; i < *r_len; i++) {
((Object **)base_array)[i] = base_array[i]->object;
@@ -149,55 +151,60 @@ Object **BKE_view_layer_array_from_objects_in_mode_params(ViewLayer *view_layer,
return (Object **)base_array;
}
-struct Object **BKE_view_layer_array_from_objects_in_edit_mode(ViewLayer *view_layer,
+struct Object **BKE_view_layer_array_from_objects_in_edit_mode(const Scene *scene,
+ ViewLayer *view_layer,
const View3D *v3d,
uint *r_len)
{
struct ObjectsInModeParams params = {0};
params.object_mode = OB_MODE_EDIT;
- return BKE_view_layer_array_from_objects_in_mode_params(view_layer, v3d, r_len, &params);
+ return BKE_view_layer_array_from_objects_in_mode_params(scene, view_layer, v3d, r_len, &params);
}
-struct Base **BKE_view_layer_array_from_bases_in_edit_mode(ViewLayer *view_layer,
+struct Base **BKE_view_layer_array_from_bases_in_edit_mode(const Scene *scene,
+ ViewLayer *view_layer,
const View3D *v3d,
uint *r_len)
{
struct ObjectsInModeParams params = {0};
params.object_mode = OB_MODE_EDIT;
- return BKE_view_layer_array_from_bases_in_mode_params(view_layer, v3d, r_len, &params);
+ return BKE_view_layer_array_from_bases_in_mode_params(scene, view_layer, v3d, r_len, &params);
}
-struct Object **BKE_view_layer_array_from_objects_in_edit_mode_unique_data(ViewLayer *view_layer,
+struct Object **BKE_view_layer_array_from_objects_in_edit_mode_unique_data(const Scene *scene,
+ ViewLayer *view_layer,
const View3D *v3d,
uint *r_len)
{
struct ObjectsInModeParams params = {0};
params.object_mode = OB_MODE_EDIT;
params.no_dup_data = true;
- return BKE_view_layer_array_from_objects_in_mode_params(view_layer, v3d, r_len, &params);
+ return BKE_view_layer_array_from_objects_in_mode_params(scene, view_layer, v3d, r_len, &params);
}
-struct Base **BKE_view_layer_array_from_bases_in_edit_mode_unique_data(ViewLayer *view_layer,
+struct Base **BKE_view_layer_array_from_bases_in_edit_mode_unique_data(const Scene *scene,
+ ViewLayer *view_layer,
const View3D *v3d,
uint *r_len)
{
struct ObjectsInModeParams params = {0};
params.object_mode = OB_MODE_EDIT;
params.no_dup_data = true;
- return BKE_view_layer_array_from_bases_in_mode_params(view_layer, v3d, r_len, &params);
+ return BKE_view_layer_array_from_bases_in_mode_params(scene, view_layer, v3d, r_len, &params);
}
struct Object **BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- ViewLayer *view_layer, const View3D *v3d, uint *r_len)
+ const Scene *scene, ViewLayer *view_layer, const View3D *v3d, uint *r_len)
{
struct ObjectsInModeParams params = {0};
params.object_mode = OB_MODE_EDIT;
params.no_dup_data = true;
params.filter_fn = BKE_view_layer_filter_edit_mesh_has_uvs;
- return BKE_view_layer_array_from_objects_in_mode_params(view_layer, v3d, r_len, &params);
+ return BKE_view_layer_array_from_objects_in_mode_params(scene, view_layer, v3d, r_len, &params);
}
-struct Object **BKE_view_layer_array_from_objects_in_mode_unique_data(ViewLayer *view_layer,
+struct Object **BKE_view_layer_array_from_objects_in_mode_unique_data(const Scene *scene,
+ ViewLayer *view_layer,
const View3D *v3d,
uint *r_len,
const eObjectMode mode)
@@ -205,7 +212,28 @@ struct Object **BKE_view_layer_array_from_objects_in_mode_unique_data(ViewLayer
struct ObjectsInModeParams params = {0};
params.object_mode = mode;
params.no_dup_data = true;
- return BKE_view_layer_array_from_objects_in_mode_params(view_layer, v3d, r_len, &params);
+ return BKE_view_layer_array_from_objects_in_mode_params(scene, view_layer, v3d, r_len, &params);
+}
+
+ListBase *BKE_view_layer_object_bases_get(ViewLayer *view_layer)
+{
+ BLI_assert_msg((view_layer->flag & VIEW_LAYER_OUT_OF_SYNC) == 0,
+ "Object Bases out of sync, invoke BKE_view_layer_synced_ensure.");
+ return &view_layer->object_bases;
+}
+
+Base *BKE_view_layer_active_base_get(ViewLayer *view_layer)
+{
+ BLI_assert_msg((view_layer->flag & VIEW_LAYER_OUT_OF_SYNC) == 0,
+ "Active Base out of sync, invoke BKE_view_layer_synced_ensure.");
+ return view_layer->basact;
+}
+
+LayerCollection *BKE_view_layer_active_collection_get(ViewLayer *view_layer)
+{
+ BLI_assert_msg((view_layer->flag & VIEW_LAYER_OUT_OF_SYNC) == 0,
+ "Active Collection out of sync, invoke BKE_view_layer_synced_ensure.");
+ return view_layer->active_collection;
}
/** \} */
@@ -242,9 +270,11 @@ bool BKE_view_layer_filter_edit_mesh_has_edges(const Object *ob, void *UNUSED(us
return false;
}
-Object *BKE_view_layer_non_active_selected_object(struct ViewLayer *view_layer,
+Object *BKE_view_layer_non_active_selected_object(const struct Scene *scene,
+ struct ViewLayer *view_layer,
const struct View3D *v3d)
{
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob_active = BKE_view_layer_active_object_get(view_layer);
Object *ob_result = NULL;
FOREACH_SELECTED_OBJECT_BEGIN (view_layer, v3d, ob_iter) {
@@ -272,7 +302,8 @@ Object *BKE_view_layer_non_active_selected_object(struct ViewLayer *view_layer,
Object *BKE_view_layer_active_object_get(const ViewLayer *view_layer)
{
- return view_layer->basact ? view_layer->basact->object : NULL;
+ Base *base = BKE_view_layer_active_base_get((ViewLayer *)view_layer);
+ return base ? base->object : NULL;
}
Object *BKE_view_layer_edit_object_get(const ViewLayer *view_layer)
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index 8faa260ab8b..f60234a684d 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -416,7 +416,7 @@ static int lib_id_expand_local_cb(LibraryIDLinkCallbackData *cb_data)
/* Can happen that we get un-linkable ID here, e.g. with shape-key referring to itself
* (through drivers)...
* Just skip it, shape key can only be either indirectly linked, or fully local, period.
- * And let's curse one more time that stupid useless shapekey ID type! */
+ * And let's curse one more time that stupid useless shape-key ID type! */
if (*id_pointer && *id_pointer != id_self &&
BKE_idtype_idcode_is_linkable(GS((*id_pointer)->name))) {
id_lib_extern(*id_pointer);
@@ -566,7 +566,7 @@ struct IDCopyLibManagementData {
int flag;
};
-/* Increases usercount as required, and remap self ID pointers. */
+/** Increases user-count as required, and remap self ID pointers. */
static int id_copy_libmanagement_cb(LibraryIDLinkCallbackData *cb_data)
{
ID **id_pointer = cb_data->id_pointer;
@@ -1289,7 +1289,7 @@ void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int ori
new_id->flag = (new_id->flag & ~copy_idflag_mask) | (id->flag & copy_idflag_mask);
- /* We do not want any handling of usercount in code duplicating the data here, we do that all
+ /* We do not want any handling of user-count in code duplicating the data here, we do that all
* at once in id_copy_libmanagement_cb() at the end. */
const int copy_data_flag = orig_flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
@@ -1566,7 +1566,7 @@ void BKE_main_id_refcount_recompute(struct Main *bmain, const bool do_linked_onl
}
FOREACH_MAIN_ID_END;
- /* Go over whole Main database to re-generate proper usercounts... */
+ /* Go over whole Main database to re-generate proper user-counts. */
FOREACH_MAIN_ID_BEGIN (bmain, id) {
BKE_library_foreach_ID_link(bmain,
id,
@@ -1612,7 +1612,7 @@ static void library_make_local_copying_check(ID *id,
if (!BLI_gset_haskey(done_ids, from_id)) {
if (BLI_gset_haskey(loop_tags, from_id)) {
/* We are in a 'dependency loop' of IDs, this does not say us anything, skip it.
- * Note that this is the situation that can lead to archipelagoes of linked data-blocks
+ * Note that this is the situation that can lead to archipelagos of linked data-blocks
* (since all of them have non-local users, they would all be duplicated,
* leading to a loop of unused linked data-blocks that cannot be freed since they all use
* each other...). */
diff --git a/source/blender/blenkernel/intern/lib_id_delete.c b/source/blender/blenkernel/intern/lib_id_delete.c
index 8d5699d7d49..92b34b9e1af 100644
--- a/source/blender/blenkernel/intern/lib_id_delete.c
+++ b/source/blender/blenkernel/intern/lib_id_delete.c
@@ -16,17 +16,19 @@
#include "BLI_utildefines.h"
+#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BKE_anim_data.h"
#include "BKE_asset.h"
+#include "BKE_asset_library.h"
#include "BKE_idprop.h"
#include "BKE_idtype.h"
#include "BKE_key.h"
+#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_lib_override.h"
#include "BKE_lib_remap.h"
-#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_main_namemap.h"
@@ -136,16 +138,16 @@ void BKE_id_free_ex(Main *bmain, void *idv, int flag, const bool use_flag_from_i
BKE_main_lock(bmain);
}
+ struct IDRemapper *remapper = BKE_id_remapper_create();
+ BKE_id_remapper_add(remapper, id, NULL);
+
if ((flag & LIB_ID_FREE_NO_UI_USER) == 0) {
if (free_notifier_reference_cb) {
free_notifier_reference_cb(id);
}
if (remap_editor_id_reference_cb) {
- struct IDRemapper *remapper = BKE_id_remapper_create();
- BKE_id_remapper_add(remapper, id, NULL);
remap_editor_id_reference_cb(remapper);
- BKE_id_remapper_free(remapper);
}
}
@@ -157,6 +159,9 @@ void BKE_id_free_ex(Main *bmain, void *idv, int flag, const bool use_flag_from_i
}
}
+ BKE_asset_library_remap_ids(remapper);
+ BKE_id_remapper_free(remapper);
+
BKE_libblock_free_data(id, (flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0);
if ((flag & LIB_ID_FREE_NO_MAIN) == 0) {
@@ -202,7 +207,6 @@ static size_t id_delete(Main *bmain, const bool do_tagged_deletion)
{
const int tag = LIB_TAG_DOIT;
ListBase *lbarray[INDEX_ID_MAX];
- Link dummy_link = {0};
int base_count, i;
/* Used by batch tagged deletion, when we call BKE_id_free then, id is no more in Main database,
@@ -217,6 +221,9 @@ static size_t id_delete(Main *bmain, const bool do_tagged_deletion)
BKE_main_lock(bmain);
if (do_tagged_deletion) {
+ struct IDRemapper *id_remapper = BKE_id_remapper_create();
+ BKE_layer_collection_resync_forbid();
+
/* Main idea of batch deletion is to remove all IDs to be deleted from Main database.
* This means that we won't have to loop over all deleted IDs to remove usages
* of other deleted IDs.
@@ -227,7 +234,6 @@ static size_t id_delete(Main *bmain, const bool do_tagged_deletion)
bool keep_looping = true;
while (keep_looping) {
ID *id, *id_next;
- ID *last_remapped_id = tagged_deleted_ids.last;
keep_looping = false;
/* First tag and remove from Main all datablocks directly from target lib.
@@ -243,6 +249,7 @@ static size_t id_delete(Main *bmain, const bool do_tagged_deletion)
BLI_remlink(lb, id);
BKE_main_namemap_remove_name(bmain, id, id->name + 2);
BLI_addtail(&tagged_deleted_ids, id);
+ BKE_id_remapper_add(id_remapper, id, NULL);
/* Do not tag as no_main now, we want to unlink it first (lower-level ID management
* code has some specific handling of 'no main' IDs that would be a problem in that
* case). */
@@ -251,44 +258,53 @@ static size_t id_delete(Main *bmain, const bool do_tagged_deletion)
}
}
}
- if (last_remapped_id == NULL) {
- dummy_link.next = tagged_deleted_ids.first;
- last_remapped_id = (ID *)(&dummy_link);
- }
- for (id = last_remapped_id->next; id; id = id->next) {
- /* Will tag 'never NULL' users of this ID too.
- *
- * NOTE: #BKE_libblock_unlink() cannot be used here, since it would ignore indirect
- * links, this can lead to nasty crashing here in second, actual deleting loop.
- * Also, this will also flag users of deleted data that cannot be unlinked
- * (object using deleted obdata, etc.), so that they also get deleted. */
- BKE_libblock_remap_locked(bmain,
- id,
- NULL,
- (ID_REMAP_FLAG_NEVER_NULL_USAGE |
- ID_REMAP_FORCE_NEVER_NULL_USAGE |
- ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS));
- /* Since we removed ID from Main,
- * we also need to unlink its own other IDs usages ourself. */
- BKE_libblock_relink_ex(
- bmain,
- id,
- NULL,
- NULL,
- (ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS | ID_REMAP_SKIP_USER_CLEAR));
- }
+
+ /* Will tag 'never NULL' users of this ID too.
+ *
+ * NOTE: #BKE_libblock_unlink() cannot be used here, since it would ignore indirect
+ * links, this can lead to nasty crashing here in second, actual deleting loop.
+ * Also, this will also flag users of deleted data that cannot be unlinked
+ * (object using deleted obdata, etc.), so that they also get deleted. */
+ BKE_libblock_remap_multiple_locked(bmain,
+ id_remapper,
+ ID_REMAP_FLAG_NEVER_NULL_USAGE |
+ ID_REMAP_FORCE_NEVER_NULL_USAGE |
+ ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS);
+ BKE_id_remapper_clear(id_remapper);
}
+ /* Since we removed IDs from Main, their own other IDs usages need to be removed 'manually'. */
+ LinkNode *cleanup_ids = NULL;
+ for (ID *id = tagged_deleted_ids.first; id; id = id->next) {
+ BLI_linklist_prepend(&cleanup_ids, id);
+ }
+ BKE_libblock_relink_multiple(bmain,
+ cleanup_ids,
+ ID_REMAP_TYPE_CLEANUP,
+ id_remapper,
+ ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS |
+ ID_REMAP_SKIP_USER_CLEAR);
+
+ BKE_id_remapper_free(id_remapper);
+ BLI_linklist_free(cleanup_ids, NULL);
+
+ BKE_layer_collection_resync_allow();
+ BKE_main_collection_sync_remap(bmain);
+
/* Now we can safely mark that ID as not being in Main database anymore. */
- /* NOTE: This needs to be done in a separate loop than above, otherwise some usercounts of
- * deleted IDs may not be properly decreased by the remappings (since `NO_MAIN` ID usercounts
+ /* NOTE: This needs to be done in a separate loop than above, otherwise some user-counts of
+ * deleted IDs may not be properly decreased by the remappings (since `NO_MAIN` ID user-counts
* is never affected). */
for (ID *id = tagged_deleted_ids.first; id; id = id->next) {
id->tag |= LIB_TAG_NO_MAIN;
+ /* User-count needs to be reset artificially, since some usages may not be cleared in batch
+ * deletion (typically, if one deleted ID uses another deleted ID, this may not be cleared by
+ * remapping code, depending on order in which these are handled). */
+ id->us = ID_FAKE_USERS(id);
}
}
else {
- /* First tag all datablocks directly from target lib.
+ /* First tag all data-blocks directly from target lib.
* Note that we go forward here, since we want to check dependencies before users
* (e.g. meshes before objects).
* Avoids to have to loop twice. */
diff --git a/source/blender/blenkernel/intern/lib_id_remapper.cc b/source/blender/blenkernel/intern/lib_id_remapper.cc
index 98ac9110a48..cedbab5aa18 100644
--- a/source/blender/blenkernel/intern/lib_id_remapper.cc
+++ b/source/blender/blenkernel/intern/lib_id_remapper.cc
@@ -221,7 +221,7 @@ const char *BKE_id_remapper_result_string(const IDRemapperApplyResult result)
return "";
}
-static void id_remapper_print_item_cb(ID *old_id, ID *new_id, void *UNUSED(user_data))
+static void id_remapper_print_item_cb(ID *old_id, ID *new_id, void * /*user_data*/)
{
if (old_id != nullptr && new_id != nullptr) {
printf("Remap %s(%p) to %s(%p)\n", old_id->name, old_id, new_id->name, new_id);
diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc
index 0200b534ace..07eb4741b1f 100644
--- a/source/blender/blenkernel/intern/lib_override.cc
+++ b/source/blender/blenkernel/intern/lib_override.cc
@@ -23,6 +23,7 @@
#include "BKE_anim_data.h"
#include "BKE_armature.h"
+#include "BKE_blender.h"
#include "BKE_collection.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
@@ -494,8 +495,8 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain,
if (id_hierarchy_root != nullptr) {
/* If the hierarchy root is given, it must be a valid existing override (used during partial
* resync process mainly). */
- BLI_assert((ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root) &&
- id_hierarchy_root->override_library->reference->lib == id_root_reference->lib));
+ BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root) &&
+ id_hierarchy_root->override_library->reference->lib == id_root_reference->lib);
if (!do_no_main) {
/* When processing within Main, set existing overrides in given hierarchy as 'newid' of their
@@ -507,8 +508,8 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain,
if (!ELEM(id_hierarchy_root_reference, nullptr, id_root_reference)) {
/* If the reference hierarchy root is given, it must be from the same library as the reference
* root, and also tagged for override. */
- BLI_assert((id_hierarchy_root_reference->lib == id_root_reference->lib &&
- (id_hierarchy_root_reference->tag & LIB_TAG_DOIT) != 0));
+ BLI_assert(id_hierarchy_root_reference->lib == id_root_reference->lib &&
+ (id_hierarchy_root_reference->tag & LIB_TAG_DOIT) != 0);
}
const Library *reference_library = id_root_reference->lib;
@@ -1210,6 +1211,9 @@ static void lib_override_library_create_post_process(Main *bmain,
const Object *old_active_object,
const bool is_resync)
{
+ /* If there is an old active object, there should also always be a given view layer. */
+ BLI_assert(old_active_object == nullptr || view_layer != nullptr);
+
/* NOTE: We only care about local IDs here, if a linked object is not instantiated in any way we
* do not do anything about it. */
@@ -1269,6 +1273,13 @@ static void lib_override_library_create_post_process(Main *bmain,
}
}
+ if (view_layer != nullptr) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ }
+ else {
+ BKE_scene_view_layers_synced_ensure(scene);
+ }
+
/* We need to ensure all new overrides of objects are properly instantiated. */
Collection *default_instantiating_collection = residual_storage;
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
@@ -1378,7 +1389,13 @@ bool BKE_lib_override_library_create(Main *bmain,
id_hierarchy_root_reference = id_root_reference;
}
- const Object *old_active_object = BKE_view_layer_active_object_get(view_layer);
+ /* While in theory it _should_ be enough to ensure sync of given view-layer (if any), or at least
+ * of given scene, think for now it's better to get a fully synced Main at this point, this code
+ * may do some very wide remapping/data access in some cases. */
+ BKE_main_view_layers_synced_ensure(bmain);
+ const Object *old_active_object = (view_layer != nullptr) ?
+ BKE_view_layer_active_object_get(view_layer) :
+ nullptr;
const bool success = lib_override_library_create_do(bmain,
scene,
@@ -1716,6 +1733,7 @@ static bool lib_override_library_resync(Main *bmain,
ID *id_root_reference = id_root->override_library->reference;
ID *id;
+ BKE_view_layer_synced_ensure(scene, view_layer);
const Object *old_active_object = BKE_view_layer_active_object_get(view_layer);
if (id_root_reference->tag & LIB_TAG_MISSING) {
@@ -1843,8 +1861,8 @@ static bool lib_override_library_resync(Main *bmain,
}
}
if (reference_id == nullptr) {
- /* Can happen e.g. when there is a local override of a shapekey, but the matching linked
- * obdata (mesh etc.) does not have any shapekey anymore. */
+ /* Can happen e.g. when there is a local override of a shape-key, but the matching linked
+ * obdata (mesh etc.) does not have any shape-key anymore. */
continue;
}
BLI_assert(GS(reference_id->name) == GS(id->name));
@@ -2696,7 +2714,8 @@ void BKE_lib_override_library_main_resync(Main *bmain,
/* Hide the collection from viewport and render. */
override_resync_residual_storage->flag |= COLLECTION_HIDE_VIEWPORT | COLLECTION_HIDE_RENDER;
}
-
+ /* BKE_collection_add above could have tagged the view_layer out of sync. */
+ BKE_view_layer_synced_ensure(scene, view_layer);
const Object *old_active_object = BKE_view_layer_active_object_get(view_layer);
/* Necessary to improve performances, and prevent layers matching override sub-collections to be
@@ -3127,7 +3146,7 @@ bool BKE_lib_override_library_property_operation_operands_validate(
return true;
}
-void BKE_lib_override_library_validate(Main *UNUSED(bmain), ID *id, ReportList *reports)
+void BKE_lib_override_library_validate(Main * /*bmain*/, ID *id, ReportList *reports)
{
if (id->override_library == nullptr) {
return;
@@ -3811,9 +3830,8 @@ void BKE_lib_override_library_main_update(Main *bmain)
/* This temporary swap of G_MAIN is rather ugly,
* but necessary to avoid asserts checks in some RNA assignment functions,
- * since those always use on G_MAIN when they need access to a Main database. */
- Main *orig_gmain = G_MAIN;
- G_MAIN = bmain;
+ * since those always use G_MAIN when they need access to a Main database. */
+ Main *orig_gmain = BKE_blender_globals_main_swap(bmain);
BLI_assert(BKE_main_namemap_validate(bmain));
@@ -3826,7 +3844,9 @@ void BKE_lib_override_library_main_update(Main *bmain)
BLI_assert(BKE_main_namemap_validate(bmain));
- G_MAIN = orig_gmain;
+ Main *tmp_gmain = BKE_blender_globals_main_swap(orig_gmain);
+ BLI_assert(tmp_gmain == bmain);
+ UNUSED_VARS_NDEBUG(tmp_gmain);
}
bool BKE_lib_override_library_id_is_user_deletable(Main *bmain, ID *id)
@@ -3934,8 +3954,8 @@ ID *BKE_lib_override_library_operations_store_start(Main *bmain,
return storage_id;
}
-void BKE_lib_override_library_operations_store_end(
- OverrideLibraryStorage *UNUSED(override_storage), ID *local)
+void BKE_lib_override_library_operations_store_end(OverrideLibraryStorage * /*override_storage*/,
+ ID *local)
{
BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(local));
@@ -3947,7 +3967,7 @@ void BKE_lib_override_library_operations_store_end(
void BKE_lib_override_library_operations_store_finalize(OverrideLibraryStorage *override_storage)
{
/* We cannot just call BKE_main_free(override_storage), not until we have option to make
- * 'ghost' copies of IDs without increasing usercount of used data-blocks. */
+ * 'ghost' copies of IDs without increasing user-count of used data-blocks. */
ID *id;
FOREACH_MAIN_ID_BEGIN (override_storage, id) {
diff --git a/source/blender/blenkernel/intern/lib_remap.c b/source/blender/blenkernel/intern/lib_remap.c
index 28b0337d9a2..addb7b0988c 100644
--- a/source/blender/blenkernel/intern/lib_remap.c
+++ b/source/blender/blenkernel/intern/lib_remap.c
@@ -183,7 +183,7 @@ static int foreach_libblock_remap_callback(LibraryIDLinkCallbackData *cb_data)
/* Better remap to NULL than not remapping at all,
* then we can handle it as a regular remap-to-NULL case. */
- if ((cb_flag & IDWALK_CB_NEVER_SELF)) {
+ if (cb_flag & IDWALK_CB_NEVER_SELF) {
id_remapper_options |= ID_REMAP_APPLY_UNMAP_WHEN_REMAPPING_TO_SELF;
}
@@ -817,7 +817,7 @@ void BKE_libblock_relink_ex(
Main *bmain, void *idv, void *old_idv, void *new_idv, const short remap_flags)
{
- /* Should be able to replace all _relink() funcs (constraints, rigidbody, etc.) ? */
+ /* Should be able to replace all _relink() functions (constraints, rigidbody, etc.) ? */
ID *id = idv;
ID *old_id = old_idv;
diff --git a/source/blender/blenkernel/intern/main.c b/source/blender/blenkernel/intern/main.c
index 239aacf28d6..3e8ff957d53 100644
--- a/source/blender/blenkernel/intern/main.c
+++ b/source/blender/blenkernel/intern/main.c
@@ -29,11 +29,12 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-Main *BKE_main_new(void)
+Main *BKE_main_new()
{
Main *bmain = MEM_callocN(sizeof(Main), "new main");
bmain->lock = MEM_mallocN(sizeof(SpinLock), "main lock");
BLI_spin_init((SpinLock *)bmain->lock);
+ bmain->is_global_main = false;
return bmain;
}
diff --git a/source/blender/blenkernel/intern/main_idmap.c b/source/blender/blenkernel/intern/main_idmap.c
index a01dbd14e65..24c1da782fe 100644
--- a/source/blender/blenkernel/intern/main_idmap.c
+++ b/source/blender/blenkernel/intern/main_idmap.c
@@ -184,10 +184,10 @@ struct Main *BKE_main_idmap_main_get(struct IDNameLib_Map *id_map)
return id_map->bmain;
}
-static unsigned int idkey_hash(const void *ptr)
+static uint idkey_hash(const void *ptr)
{
const struct IDNameLib_Key *idkey = ptr;
- unsigned int key = BLI_ghashutil_strhash(idkey->name);
+ uint key = BLI_ghashutil_strhash(idkey->name);
if (idkey->lib) {
key ^= BLI_ghashutil_ptrhash(idkey->lib);
}
diff --git a/source/blender/blenkernel/intern/main_namemap.cc b/source/blender/blenkernel/intern/main_namemap.cc
index a600afb4ed1..5a8f90ea10a 100644
--- a/source/blender/blenkernel/intern/main_namemap.cc
+++ b/source/blender/blenkernel/intern/main_namemap.cc
@@ -62,7 +62,7 @@ static bool id_name_final_build(char *name, char *base_name, size_t base_name_le
/* Code above may have generated invalid utf-8 string, due to raw truncation.
* Ensure we get a valid one now. */
- base_name_len -= (size_t)BLI_str_utf8_invalid_strip(base_name, base_name_len);
+ base_name_len -= size_t(BLI_str_utf8_invalid_strip(base_name, base_name_len));
/* Also truncate orig name, and start the whole check again. */
name[base_name_len] = '\0';
@@ -97,7 +97,7 @@ struct UniqueName_Key {
* one larger.
*/
struct UniqueName_Value {
- static constexpr unsigned max_exact_tracking = 1024;
+ static constexpr uint max_exact_tracking = 1024;
BLI_BITMAP_DECLARE(mask, max_exact_tracking);
int max_value = 0;
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 25268785d42..d877620855f 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -308,7 +308,7 @@ BezTriple *BKE_mask_spline_point_next_bezt(MaskSpline *spline,
return NULL;
}
- return &((point + 1))->bezt;
+ return &(point + 1)->bezt;
}
MaskSplinePoint *BKE_mask_spline_point_array(MaskSpline *spline)
@@ -1579,7 +1579,7 @@ void BKE_mask_parent_init(MaskParent *parent)
parent->id_type = ID_MC;
}
-/* *** own animation/shapekey implementation ***
+/* *** own animation/shape-key implementation ***
* BKE_mask_layer_shape_XXX */
int BKE_mask_layer_shape_totvert(MaskLayer *masklay)
diff --git a/source/blender/blenkernel/intern/mask_evaluate.c b/source/blender/blenkernel/intern/mask_evaluate.c
index 3425510c8b9..e76c7894f9f 100644
--- a/source/blender/blenkernel/intern/mask_evaluate.c
+++ b/source/blender/blenkernel/intern/mask_evaluate.c
@@ -24,10 +24,10 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
-unsigned int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height)
+uint BKE_mask_spline_resolution(MaskSpline *spline, int width, int height)
{
float max_segment = 0.01f;
- unsigned int i, resol = 1;
+ uint i, resol = 1;
if (width != 0 && height != 0) {
max_segment = 1.0f / (float)max_ii(width, height);
@@ -37,7 +37,7 @@ unsigned int BKE_mask_spline_resolution(MaskSpline *spline, int width, int heigh
MaskSplinePoint *point = &spline->points[i];
BezTriple *bezt_curr, *bezt_next;
float a, b, c, len;
- unsigned int cur_resol;
+ uint cur_resol;
bezt_curr = &point->bezt;
bezt_next = BKE_mask_spline_point_next_bezt(spline, spline->points, point);
@@ -63,10 +63,10 @@ unsigned int BKE_mask_spline_resolution(MaskSpline *spline, int width, int heigh
return CLAMPIS(resol, 1, MASK_RESOL_MAX);
}
-unsigned int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height)
+uint BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height)
{
const float max_segment = 0.005;
- unsigned int resol = BKE_mask_spline_resolution(spline, width, height);
+ uint resol = BKE_mask_spline_resolution(spline, width, height);
float max_jump = 0.0f;
/* avoid checking the featrher if we already hit the maximum value */
@@ -102,7 +102,7 @@ unsigned int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, i
return CLAMPIS(resol, 1, MASK_RESOL_MAX);
}
-int BKE_mask_spline_differentiate_calc_total(const MaskSpline *spline, const unsigned int resol)
+int BKE_mask_spline_differentiate_calc_total(const MaskSpline *spline, const uint resol)
{
if (spline->flag & MASK_SPLINE_CYCLIC) {
return spline->tot_point * resol;
@@ -112,8 +112,8 @@ int BKE_mask_spline_differentiate_calc_total(const MaskSpline *spline, const uns
}
float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline,
- const unsigned int resol,
- unsigned int *r_tot_diff_point))[2]
+ const uint resol,
+ uint *r_tot_diff_point))[2]
{
MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
@@ -176,7 +176,7 @@ float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline,
}
float (*BKE_mask_spline_differentiate(
- MaskSpline *spline, int width, int height, unsigned int *r_tot_diff_point))[2]
+ MaskSpline *spline, int width, int height, uint *r_tot_diff_point))[2]
{
uint resol = BKE_mask_spline_resolution(spline, width, height);
@@ -316,7 +316,7 @@ static void feather_bucket_get_diagonal(FeatherEdgesBucket *buckets,
void BKE_mask_spline_feather_collapse_inner_loops(MaskSpline *spline,
float (*feather_points)[2],
- const unsigned int tot_feather_point)
+ const uint tot_feather_point)
{
#define BUCKET_INDEX(co) feather_bucket_index_from_coord(co, min, bucket_scale, buckets_per_side)
@@ -340,7 +340,7 @@ void BKE_mask_spline_feather_collapse_inner_loops(MaskSpline *spline,
INIT_MINMAX2(min, max);
for (uint i = 0; i < tot_feather_point; i++) {
- unsigned int next = i + 1;
+ uint next = i + 1;
float delta;
minmax_v2v2_v2(min, max, feather_points[i]);
@@ -489,11 +489,11 @@ void BKE_mask_spline_feather_collapse_inner_loops(MaskSpline *spline,
}
/** only called from #BKE_mask_spline_feather_differentiated_points_with_resolution() ! */
-static float (*mask_spline_feather_differentiated_points_with_resolution__even(
- MaskSpline *spline,
- const unsigned int resol,
- const bool do_feather_isect,
- unsigned int *r_tot_feather_point))[2]
+static float (
+ *mask_spline_feather_differentiated_points_with_resolution__even(MaskSpline *spline,
+ const uint resol,
+ const bool do_feather_isect,
+ uint *r_tot_feather_point))[2]
{
MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
MaskSplinePoint *point_curr, *point_prev;
@@ -565,9 +565,9 @@ static float (*mask_spline_feather_differentiated_points_with_resolution__even(
/** only called from #BKE_mask_spline_feather_differentiated_points_with_resolution() ! */
static float (*mask_spline_feather_differentiated_points_with_resolution__double(
MaskSpline *spline,
- const unsigned int resol,
+ const uint resol,
const bool do_feather_isect,
- unsigned int *r_tot_feather_point))[2]
+ uint *r_tot_feather_point))[2]
{
MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
@@ -704,11 +704,11 @@ static float (*mask_spline_feather_differentiated_points_with_resolution__double
return feather;
}
-float (*BKE_mask_spline_feather_differentiated_points_with_resolution(
- MaskSpline *spline,
- const unsigned int resol,
- const bool do_feather_isect,
- unsigned int *r_tot_feather_point))[2]
+float (
+ *BKE_mask_spline_feather_differentiated_points_with_resolution(MaskSpline *spline,
+ const uint resol,
+ const bool do_feather_isect,
+ uint *r_tot_feather_point))[2]
{
switch (spline->offset_mode) {
case MASK_SPLINE_OFFSET_EVEN:
@@ -768,14 +768,11 @@ float (*BKE_mask_spline_feather_points(MaskSpline *spline, int *r_tot_feather_po
return feather;
}
-float *BKE_mask_point_segment_feather_diff(MaskSpline *spline,
- MaskSplinePoint *point,
- int width,
- int height,
- unsigned int *r_tot_feather_point)
+float *BKE_mask_point_segment_feather_diff(
+ MaskSpline *spline, MaskSplinePoint *point, int width, int height, uint *r_tot_feather_point)
{
float *feather, *fp;
- unsigned int resol = BKE_mask_spline_feather_resolution(spline, width, height);
+ uint resol = BKE_mask_spline_feather_resolution(spline, width, height);
feather = fp = MEM_callocN(2 * resol * sizeof(float), "mask point spline feather diff points");
@@ -796,11 +793,8 @@ float *BKE_mask_point_segment_feather_diff(MaskSpline *spline,
return feather;
}
-float *BKE_mask_point_segment_diff(MaskSpline *spline,
- MaskSplinePoint *point,
- int width,
- int height,
- unsigned int *r_tot_diff_point)
+float *BKE_mask_point_segment_diff(
+ MaskSpline *spline, MaskSplinePoint *point, int width, int height, uint *r_tot_diff_point)
{
MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 84aabbc7a9b..adc0eb5f78c 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -83,17 +83,17 @@
#define BUCKET_PIXELS_PER_CELL 4
#define SF_EDGE_IS_BOUNDARY 0xff
-#define SF_KEYINDEX_TEMP_ID ((unsigned int)-1)
+#define SF_KEYINDEX_TEMP_ID ((uint)-1)
-#define TRI_TERMINATOR_ID ((unsigned int)-1)
-#define TRI_VERT ((unsigned int)-1)
+#define TRI_TERMINATOR_ID ((uint)-1)
+#define TRI_VERT ((uint)-1)
/* for debugging add... */
#ifndef NDEBUG
// printf("%u %u %u %u\n", _t[0], _t[1], _t[2], _t[3]);
# define FACE_ASSERT(face, vert_max) \
{ \
- unsigned int *_t = face; \
+ uint *_t = face; \
BLI_assert(_t[0] < vert_max); \
BLI_assert(_t[1] < vert_max); \
BLI_assert(_t[2] < vert_max); \
@@ -127,9 +127,7 @@ static void rotate_point_v2(
r_p[1] = p_new[1] + cent[1];
}
-BLI_INLINE unsigned int clampis_uint(const unsigned int v,
- const unsigned int min,
- const unsigned int max)
+BLI_INLINE uint clampis_uint(const uint v, const uint min, const uint max)
{
return v < min ? min : (v > max ? max : v);
}
@@ -156,19 +154,19 @@ static ScanFillVert *scanfill_vert_add_v2_with_depth(ScanFillContext *sf_ctx,
/* internal use only */
typedef struct MaskRasterLayer {
/* geometry */
- unsigned int face_tot;
- unsigned int (*face_array)[4]; /* access coords tri/quad */
- float (*face_coords)[3]; /* xy, z 0-1 (1.0 == filled) */
+ uint face_tot;
+ uint (*face_array)[4]; /* access coords tri/quad */
+ float (*face_coords)[3]; /* xy, z 0-1 (1.0 == filled) */
/* 2d bounds (to quickly skip bucket lookup) */
rctf bounds;
/* buckets */
- unsigned int **buckets_face;
+ uint **buckets_face;
/* cache divide and subtract */
float buckets_xy_scalar[2]; /* (1.0 / (buckets_width + FLT_EPSILON)) * buckets_x */
- unsigned int buckets_x;
- unsigned int buckets_y;
+ uint buckets_x;
+ uint buckets_y;
/* copied direct from #MaskLayer.--- */
/* blending options */
@@ -181,12 +179,12 @@ typedef struct MaskRasterLayer {
typedef struct MaskRasterSplineInfo {
/* body of the spline */
- unsigned int vertex_offset;
- unsigned int vertex_total;
+ uint vertex_offset;
+ uint vertex_total;
/* capping for non-filled, non cyclic splines */
- unsigned int vertex_total_cap_head;
- unsigned int vertex_total_cap_tail;
+ uint vertex_total_cap_head;
+ uint vertex_total_cap_tail;
bool is_cyclic;
} MaskRasterSplineInfo;
@@ -196,7 +194,7 @@ typedef struct MaskRasterSplineInfo {
*/
struct MaskRasterHandle {
MaskRasterLayer *layers;
- unsigned int layers_tot;
+ uint layers_tot;
/* 2d bounds (to quickly skip bucket lookup) */
rctf bounds;
@@ -217,7 +215,7 @@ MaskRasterHandle *BKE_maskrasterize_handle_new(void)
void BKE_maskrasterize_handle_free(MaskRasterHandle *mr_handle)
{
- const unsigned int layers_tot = mr_handle->layers_tot;
+ const uint layers_tot = mr_handle->layers_tot;
MaskRasterLayer *layer = mr_handle->layers;
for (uint i = 0; i < layers_tot; i++, layer++) {
@@ -231,10 +229,10 @@ void BKE_maskrasterize_handle_free(MaskRasterHandle *mr_handle)
}
if (layer->buckets_face) {
- const unsigned int bucket_tot = layer->buckets_x * layer->buckets_y;
- unsigned int bucket_index;
+ const uint bucket_tot = layer->buckets_x * layer->buckets_y;
+ uint bucket_index;
for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) {
- unsigned int *face_index = layer->buckets_face[bucket_index];
+ uint *face_index = layer->buckets_face[bucket_index];
if (face_index) {
MEM_freeN(face_index);
}
@@ -250,15 +248,15 @@ void BKE_maskrasterize_handle_free(MaskRasterHandle *mr_handle)
static void maskrasterize_spline_differentiate_point_outset(float (*diff_feather_points)[2],
float (*diff_points)[2],
- const unsigned int tot_diff_point,
+ const uint tot_diff_point,
const float ofs,
const bool do_test)
{
- unsigned int k_prev = tot_diff_point - 2;
- unsigned int k_curr = tot_diff_point - 1;
- unsigned int k_next = 0;
+ uint k_prev = tot_diff_point - 2;
+ uint k_curr = tot_diff_point - 1;
+ uint k_next = 0;
- unsigned int k;
+ uint k;
float d_prev[2];
float d_next[2];
@@ -320,14 +318,14 @@ static void maskrasterize_spline_differentiate_point_outset(float (*diff_feather
* are to any of the triangle edges.
*/
static bool layer_bucket_isect_test(const MaskRasterLayer *layer,
- unsigned int face_index,
- const unsigned int bucket_x,
- const unsigned int bucket_y,
+ uint face_index,
+ const uint bucket_x,
+ const uint bucket_y,
const float bucket_size_x,
const float bucket_size_y,
const float bucket_max_rad_squared)
{
- unsigned int *face = layer->face_array[face_index];
+ uint *face = layer->face_array[face_index];
float(*cos)[3] = layer->face_coords;
const float xmin = layer->bounds.xmin + (bucket_size_x * (float)bucket_x);
@@ -403,8 +401,8 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size)
const float bucket_dim_x = BLI_rctf_size_x(&layer->bounds);
const float bucket_dim_y = BLI_rctf_size_y(&layer->bounds);
- layer->buckets_x = (unsigned int)((bucket_dim_x / pixel_size) / (float)BUCKET_PIXELS_PER_CELL);
- layer->buckets_y = (unsigned int)((bucket_dim_y / pixel_size) / (float)BUCKET_PIXELS_PER_CELL);
+ layer->buckets_x = (uint)((bucket_dim_x / pixel_size) / (float)BUCKET_PIXELS_PER_CELL);
+ layer->buckets_y = (uint)((bucket_dim_y / pixel_size) / (float)BUCKET_PIXELS_PER_CELL);
// printf("bucket size %ux%u\n", layer->buckets_x, layer->buckets_y);
@@ -422,14 +420,14 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size)
FLT_EPSILON;
const float bucket_max_rad_squared = bucket_max_rad * bucket_max_rad;
- unsigned int *face = &layer->face_array[0][0];
+ uint *face = &layer->face_array[0][0];
float(*cos)[3] = layer->face_coords;
- const unsigned int bucket_tot = layer->buckets_x * layer->buckets_y;
+ const uint bucket_tot = layer->buckets_x * layer->buckets_y;
LinkNode **bucketstore = MEM_callocN(bucket_tot * sizeof(LinkNode *), __func__);
- unsigned int *bucketstore_tot = MEM_callocN(bucket_tot * sizeof(unsigned int), __func__);
+ uint *bucketstore_tot = MEM_callocN(bucket_tot * sizeof(uint), __func__);
- unsigned int face_index;
+ uint face_index;
for (face_index = 0; face_index < layer->face_tot; face_index++, face += 4) {
float xmin;
@@ -468,17 +466,13 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size)
CLAMP(ymax, 0.0f, 1.0f);
{
- unsigned int xi_min = (unsigned int)((xmin - layer->bounds.xmin) *
- layer->buckets_xy_scalar[0]);
- unsigned int xi_max = (unsigned int)((xmax - layer->bounds.xmin) *
- layer->buckets_xy_scalar[0]);
- unsigned int yi_min = (unsigned int)((ymin - layer->bounds.ymin) *
- layer->buckets_xy_scalar[1]);
- unsigned int yi_max = (unsigned int)((ymax - layer->bounds.ymin) *
- layer->buckets_xy_scalar[1]);
+ uint xi_min = (uint)((xmin - layer->bounds.xmin) * layer->buckets_xy_scalar[0]);
+ uint xi_max = (uint)((xmax - layer->bounds.xmin) * layer->buckets_xy_scalar[0]);
+ uint yi_min = (uint)((ymin - layer->bounds.ymin) * layer->buckets_xy_scalar[1]);
+ uint yi_max = (uint)((ymax - layer->bounds.ymin) * layer->buckets_xy_scalar[1]);
void *face_index_void = POINTER_FROM_UINT(face_index);
- unsigned int xi, yi;
+ uint xi, yi;
/* this should _almost_ never happen but since it can in extreme cases,
* we have to clamp the values or we overrun the buffer and crash */
@@ -496,10 +490,10 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size)
}
for (yi = yi_min; yi <= yi_max; yi++) {
- unsigned int bucket_index = (layer->buckets_x * yi) + xi_min;
+ uint bucket_index = (layer->buckets_x * yi) + xi_min;
for (xi = xi_min; xi <= xi_max; xi++, bucket_index++) {
/* correct but do in outer loop */
- // unsigned int bucket_index = (layer->buckets_x * yi) + xi;
+ // uint bucket_index = (layer->buckets_x * yi) + xi;
BLI_assert(xi < layer->buckets_x);
BLI_assert(yi < layer->buckets_y);
@@ -527,14 +521,13 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size)
}
if (1) {
- /* now convert linknodes into arrays for faster per pixel access */
- unsigned int **buckets_face = MEM_mallocN(bucket_tot * sizeof(*buckets_face), __func__);
- unsigned int bucket_index;
+ /* Now convert link-nodes into arrays for faster per pixel access. */
+ uint **buckets_face = MEM_mallocN(bucket_tot * sizeof(*buckets_face), __func__);
+ uint bucket_index;
for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) {
if (bucketstore_tot[bucket_index]) {
- unsigned int *bucket = MEM_mallocN(
- (bucketstore_tot[bucket_index] + 1) * sizeof(unsigned int), __func__);
+ uint *bucket = MEM_mallocN((bucketstore_tot[bucket_index] + 1) * sizeof(uint), __func__);
LinkNode *bucket_node;
buckets_face[bucket_index] = bucket;
@@ -577,10 +570,10 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
const float zvec[3] = {0.0f, 0.0f, -1.0f};
MaskLayer *masklay;
- unsigned int masklay_index;
+ uint masklay_index;
MemArena *sf_arena;
- mr_handle->layers_tot = (unsigned int)BLI_listbase_count(&mask->masklayers);
+ mr_handle->layers_tot = (uint)BLI_listbase_count(&mask->masklayers);
mr_handle->layers = MEM_mallocN(sizeof(MaskRasterLayer) * mr_handle->layers_tot,
"MaskRasterLayer");
BLI_rctf_init_minmax(&mr_handle->bounds);
@@ -591,9 +584,9 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
masklay = masklay->next, masklay_index++) {
/* we need to store vertex ranges for open splines for filling */
- unsigned int tot_splines;
+ uint tot_splines;
MaskRasterSplineInfo *open_spline_ranges;
- unsigned int open_spline_index = 0;
+ uint open_spline_index = 0;
MaskSpline *spline;
@@ -603,12 +596,12 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
ScanFillVert *sf_vert_next = NULL;
ScanFillFace *sf_tri;
- unsigned int sf_vert_tot = 0;
- unsigned int tot_feather_quads = 0;
+ uint sf_vert_tot = 0;
+ uint tot_feather_quads = 0;
#ifdef USE_SCANFILL_EDGE_WORKAROUND
- unsigned int tot_boundary_used = 0;
- unsigned int tot_boundary_found = 0;
+ uint tot_boundary_used = 0;
+ uint tot_boundary_found = 0;
#endif
if (masklay->visibility_flag & MASK_HIDE_RENDER) {
@@ -618,7 +611,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
continue;
}
- tot_splines = (unsigned int)BLI_listbase_count(&masklay->splines);
+ tot_splines = (uint)BLI_listbase_count(&masklay->splines);
open_spline_ranges = MEM_callocN(sizeof(*open_spline_ranges) * tot_splines, __func__);
BLI_scanfill_begin_arena(&sf_ctx, sf_arena);
@@ -628,15 +621,15 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
const bool is_fill = (spline->flag & MASK_SPLINE_NOFILL) == 0;
float(*diff_points)[2];
- unsigned int tot_diff_point;
+ uint tot_diff_point;
float(*diff_feather_points)[2];
float(*diff_feather_points_flip)[2];
- unsigned int tot_diff_feather_points;
+ uint tot_diff_feather_points;
- const unsigned int resol_a = BKE_mask_spline_resolution(spline, width, height) / 4;
- const unsigned int resol_b = BKE_mask_spline_feather_resolution(spline, width, height) / 4;
- const unsigned int resol = CLAMPIS(MAX2(resol_a, resol_b), 4, 512);
+ const uint resol_a = BKE_mask_spline_resolution(spline, width, height) / 4;
+ const uint resol_b = BKE_mask_spline_feather_resolution(spline, width, height) / 4;
+ const uint resol = CLAMPIS(MAX2(resol_a, resol_b), 4, 512);
diff_points = BKE_mask_spline_differentiate_with_resolution(spline, resol, &tot_diff_point);
@@ -652,7 +645,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
if (tot_diff_point > 3) {
ScanFillVert *sf_vert_prev;
- unsigned int j;
+ uint j;
sf_ctx.poly_nr++;
@@ -835,19 +828,18 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
const float *fp_cent;
const float *fp_turn;
- unsigned int k;
+ uint k;
fp_cent = diff_points[0];
fp_turn = diff_feather_points[0];
#define CALC_CAP_RESOL \
- clampis_uint( \
- (unsigned int)(len_v2v2(fp_cent, fp_turn) / (pixel_size * SPLINE_RESOL_CAP_PER_PIXEL)), \
- SPLINE_RESOL_CAP_MIN, \
- SPLINE_RESOL_CAP_MAX)
+ clampis_uint((uint)(len_v2v2(fp_cent, fp_turn) / (pixel_size * SPLINE_RESOL_CAP_PER_PIXEL)), \
+ SPLINE_RESOL_CAP_MIN, \
+ SPLINE_RESOL_CAP_MAX)
{
- const unsigned int vertex_total_cap = CALC_CAP_RESOL;
+ const uint vertex_total_cap = CALC_CAP_RESOL;
for (k = 1; k < vertex_total_cap; k++) {
const float angle = (float)k * (1.0f / (float)vertex_total_cap) * (float)M_PI;
@@ -868,7 +860,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
fp_turn = diff_feather_points[tot_diff_point - 1];
{
- const unsigned int vertex_total_cap = CALC_CAP_RESOL;
+ const uint vertex_total_cap = CALC_CAP_RESOL;
for (k = 1; k < vertex_total_cap; k++) {
const float angle = (float)k * (1.0f / (float)vertex_total_cap) * (float)M_PI;
@@ -905,11 +897,11 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
}
{
- unsigned int(*face_array)[4], *face; /* access coords */
- float(*face_coords)[3], *cos; /* xy, z 0-1 (1.0 == filled) */
- unsigned int sf_tri_tot;
+ uint(*face_array)[4], *face; /* access coords */
+ float(*face_coords)[3], *cos; /* xy, z 0-1 (1.0 == filled) */
+ uint sf_tri_tot;
rctf bounds;
- unsigned int face_index;
+ uint face_index;
int scanfill_flag = 0;
bool is_isect = false;
@@ -946,8 +938,8 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
if ((masklay->flag & MASK_LAYERFLAG_FILL_OVERLAP) &&
(is_isect = BLI_scanfill_calc_self_isect(
&sf_ctx, &isect_remvertbase, &isect_remedgebase))) {
- unsigned int sf_vert_tot_isect = (unsigned int)BLI_listbase_count(&sf_ctx.fillvertbase);
- unsigned int i = sf_vert_tot;
+ uint sf_vert_tot_isect = (uint)BLI_listbase_count(&sf_ctx.fillvertbase);
+ uint i = sf_vert_tot;
face_coords = MEM_reallocN(face_coords,
sizeof(float[3]) * (sf_vert_tot + sf_vert_tot_isect));
@@ -972,7 +964,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
scanfill_flag |= BLI_SCANFILL_CALC_HOLES;
}
- sf_tri_tot = (unsigned int)BLI_scanfill_calc_ex(&sf_ctx, scanfill_flag, zvec);
+ sf_tri_tot = (uint)BLI_scanfill_calc_ex(&sf_ctx, scanfill_flag, zvec);
if (is_isect) {
/* add removed data back, we only need edges for feather,
@@ -987,7 +979,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
face_index = 0;
/* faces */
- face = (unsigned int *)face_array;
+ face = (uint *)face_array;
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
*(face++) = sf_tri->v3->tmp.u;
*(face++) = sf_tri->v2->tmp.u;
@@ -1029,13 +1021,11 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
/* feather only splines */
while (open_spline_index > 0) {
- const unsigned int vertex_offset = open_spline_ranges[--open_spline_index].vertex_offset;
- unsigned int vertex_total = open_spline_ranges[open_spline_index].vertex_total;
- unsigned int vertex_total_cap_head =
- open_spline_ranges[open_spline_index].vertex_total_cap_head;
- unsigned int vertex_total_cap_tail =
- open_spline_ranges[open_spline_index].vertex_total_cap_tail;
- unsigned int k, j;
+ const uint vertex_offset = open_spline_ranges[--open_spline_index].vertex_offset;
+ uint vertex_total = open_spline_ranges[open_spline_index].vertex_total;
+ uint vertex_total_cap_head = open_spline_ranges[open_spline_index].vertex_total_cap_head;
+ uint vertex_total_cap_tail = open_spline_ranges[open_spline_index].vertex_total_cap_tail;
+ uint k, j;
j = vertex_offset;
@@ -1075,7 +1065,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
FACE_ASSERT(face - 4, sf_vert_tot);
}
else {
- unsigned int midvidx = vertex_offset;
+ uint midvidx = vertex_offset;
/***************
* cap end 'a' */
@@ -1196,7 +1186,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
// printf("tris %d, feather tris %d\n", sf_tri_tot, tot_feather_quads);
}
- /* add trianges */
+ /* Add triangles. */
BLI_scanfill_end_arena(&sf_ctx, sf_arena);
}
@@ -1229,7 +1219,7 @@ static float maskrasterize_layer_z_depth_quad(
return w[2] + w[3]; /* we can make this assumption for small speedup */
}
-static float maskrasterize_layer_isect(const unsigned int *face,
+static float maskrasterize_layer_isect(const uint *face,
float (*cos)[3],
const float dist_orig,
const float xy[2])
@@ -1288,22 +1278,21 @@ static float maskrasterize_layer_isect(const unsigned int *face,
return 1.0f;
}
-BLI_INLINE unsigned int layer_bucket_index_from_xy(MaskRasterLayer *layer, const float xy[2])
+BLI_INLINE uint layer_bucket_index_from_xy(MaskRasterLayer *layer, const float xy[2])
{
BLI_assert(BLI_rctf_isect_pt_v(&layer->bounds, xy));
- return ((unsigned int)((xy[0] - layer->bounds.xmin) * layer->buckets_xy_scalar[0])) +
- (((unsigned int)((xy[1] - layer->bounds.ymin) * layer->buckets_xy_scalar[1])) *
- layer->buckets_x);
+ return (uint)((xy[0] - layer->bounds.xmin) * layer->buckets_xy_scalar[0]) +
+ ((uint)((xy[1] - layer->bounds.ymin) * layer->buckets_xy_scalar[1]) * layer->buckets_x);
}
static float layer_bucket_depth_from_xy(MaskRasterLayer *layer, const float xy[2])
{
- unsigned int index = layer_bucket_index_from_xy(layer, xy);
- unsigned int *face_index = layer->buckets_face[index];
+ uint index = layer_bucket_index_from_xy(layer, xy);
+ uint *face_index = layer->buckets_face[index];
if (face_index) {
- unsigned int(*face_array)[4] = layer->face_array;
+ uint(*face_array)[4] = layer->face_array;
float(*cos)[3] = layer->face_coords;
float best_dist = 1.0f;
while (*face_index != TRI_TERMINATOR_ID) {
@@ -1330,7 +1319,7 @@ float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x
/* can't do this because some layers may invert */
/* if (BLI_rctf_isect_pt_v(&mr_handle->bounds, xy)) */
- const unsigned int layers_tot = mr_handle->layers_tot;
+ const uint layers_tot = mr_handle->layers_tot;
MaskRasterLayer *layer = mr_handle->layers;
/* return value */
@@ -1455,8 +1444,8 @@ static void maskrasterize_buffer_cb(void *__restrict userdata,
}
void BKE_maskrasterize_buffer(MaskRasterHandle *mr_handle,
- const unsigned int width,
- const unsigned int height,
+ const uint width,
+ const uint height,
/* Cannot be const, because it is assigned to non-const variable.
* NOLINTNEXTLINE: readability-non-const-parameter. */
float *buffer)
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 59a51436b7b..796ed4f8316 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -653,38 +653,29 @@ Material **BKE_object_material_get_p(Object *ob, short act)
/* if object cannot have material, (totcolp == NULL) */
totcolp = BKE_object_material_len_p(ob);
- if (totcolp == NULL || ob->totcol == 0) {
+ if (totcolp == NULL || *totcolp == 0) {
return NULL;
}
- /* return NULL for invalid 'act', can happen for mesh face indices */
- if (act > ob->totcol) {
- return NULL;
- }
- if (act <= 0) {
- if (act < 0) {
- CLOG_ERROR(&LOG, "Negative material index!");
- }
- return NULL;
- }
+ /* Clamp to number of slots if index is out of range, same convention as used for rendering. */
+ const int slot_index = clamp_i(act - 1, 0, *totcolp - 1);
- if (ob->matbits && ob->matbits[act - 1]) { /* in object */
- ma_p = &ob->mat[act - 1];
+ /* Fix inconsistency which may happen when library linked data reduces the number of
+ * slots but object was not updated. Ideally should be fixed elsewhere. */
+ if (*totcolp < ob->totcol) {
+ ob->totcol = *totcolp;
}
- else { /* in data */
-
- /* check for inconsistency */
- if (*totcolp < ob->totcol) {
- ob->totcol = *totcolp;
- }
- if (act > ob->totcol) {
- act = ob->totcol;
- }
+ if (slot_index < ob->totcol && ob->matbits && ob->matbits[slot_index]) {
+ /* Use object material slot. */
+ ma_p = &ob->mat[slot_index];
+ }
+ else {
+ /* Use data material slot. */
matarar = BKE_object_material_array_p(ob);
if (matarar && *matarar) {
- ma_p = &(*matarar)[act - 1];
+ ma_p = &(*matarar)[slot_index];
}
else {
ma_p = NULL;
@@ -717,17 +708,17 @@ static ID *get_evaluated_object_data_with_materials(Object *ob)
Material *BKE_object_material_get_eval(Object *ob, short act)
{
BLI_assert(DEG_is_evaluated_object(ob));
- const int slot_index = act - 1;
- if (slot_index < 0) {
- return NULL;
- }
ID *data = get_evaluated_object_data_with_materials(ob);
const short *tot_slots_data_ptr = BKE_id_material_len_p(data);
const int tot_slots_data = tot_slots_data_ptr ? *tot_slots_data_ptr : 0;
- if (slot_index >= tot_slots_data) {
+
+ if (tot_slots_data == 0) {
return NULL;
}
+
+ /* Clamp to number of slots if index is out of range, same convention as used for rendering. */
+ const int slot_index = clamp_i(act - 1, 0, tot_slots_data - 1);
const int tot_slots_object = ob->totcol;
Material ***materials_data_ptr = BKE_id_material_array_p(data);
@@ -900,9 +891,15 @@ void BKE_objects_materials_test_all(Main *bmain, ID *id)
}
BKE_main_lock(bmain);
+ int processed_objects = 0;
for (ob = bmain->objects.first; ob; ob = ob->id.next) {
if (ob->data == id) {
BKE_object_material_resize(bmain, ob, *totcol, false);
+ processed_objects++;
+ BLI_assert(processed_objects <= id->us && processed_objects > 0);
+ if (processed_objects == id->us) {
+ break;
+ }
}
}
BKE_main_unlock(bmain);
@@ -1063,7 +1060,7 @@ void BKE_object_material_assign_single_obdata(struct Main *bmain,
object_material_assign(bmain, ob, ma, act, BKE_MAT_ASSIGN_OBDATA, false);
}
-void BKE_object_material_remap(Object *ob, const unsigned int *remap)
+void BKE_object_material_remap(Object *ob, const uint *remap)
{
Material ***matar = BKE_object_material_array_p(ob);
const short *totcol_p = BKE_object_material_len_p(ob);
@@ -1444,7 +1441,7 @@ static bool fill_texpaint_slots_cb(bNode *node, void *userdata)
NodeTexImage *storage = (NodeTexImage *)node->storage;
slot->interp = storage->interpolation;
slot->image_user = &storage->iuser;
- /* for new renderer, we need to traverse the treeback in search of a UV node */
+ /* For new renderer, we need to traverse the tree back in search of a UV node. */
bNode *uvnode = nodetree_uv_node_recursive(node);
if (uvnode) {
@@ -1506,58 +1503,65 @@ static ePaintSlotFilter material_paint_slot_filter(const struct Object *ob)
void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma, const struct Object *ob)
{
- int count = 0;
-
if (!ma) {
return;
}
const ePaintSlotFilter slot_filter = material_paint_slot_filter(ob);
- /* COW needed when adding texture slot on an object with no materials. */
- DEG_id_tag_update(&ma->id, ID_RECALC_SHADING | ID_RECALC_COPY_ON_WRITE);
+ const TexPaintSlot *prev_texpaintslot = ma->texpaintslot;
+ const int prev_paint_active_slot = ma->paint_active_slot;
+ const int prev_paint_clone_slot = ma->paint_clone_slot;
+ const int prev_tot_slots = ma->tot_slots;
- if (ma->texpaintslot) {
- MEM_freeN(ma->texpaintslot);
- ma->tot_slots = 0;
- ma->texpaintslot = NULL;
- }
+ ma->texpaintslot = NULL;
+ ma->tot_slots = 0;
if (scene->toolsettings->imapaint.mode == IMAGEPAINT_MODE_IMAGE) {
ma->paint_active_slot = 0;
ma->paint_clone_slot = 0;
- return;
}
-
- if (!(ma->nodetree)) {
+ else if (!(ma->nodetree)) {
ma->paint_active_slot = 0;
ma->paint_clone_slot = 0;
- return;
}
+ else {
+ int count = count_texture_nodes_recursive(ma->nodetree, slot_filter);
- count = count_texture_nodes_recursive(ma->nodetree, slot_filter);
-
- if (count == 0) {
- ma->paint_active_slot = 0;
- ma->paint_clone_slot = 0;
- return;
- }
+ if (count == 0) {
+ ma->paint_active_slot = 0;
+ ma->paint_clone_slot = 0;
+ }
+ else {
+ ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots");
- ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots");
+ bNode *active_node = nodeGetActivePaintCanvas(ma->nodetree);
- bNode *active_node = nodeGetActivePaintCanvas(ma->nodetree);
+ fill_texpaint_slots_recursive(ma->nodetree, active_node, ob, ma, count, slot_filter);
- fill_texpaint_slots_recursive(ma->nodetree, active_node, ob, ma, count, slot_filter);
+ ma->tot_slots = count;
- ma->tot_slots = count;
+ if (ma->paint_active_slot >= count) {
+ ma->paint_active_slot = count - 1;
+ }
- if (ma->paint_active_slot >= count) {
- ma->paint_active_slot = count - 1;
+ if (ma->paint_clone_slot >= count) {
+ ma->paint_clone_slot = count - 1;
+ }
+ }
}
- if (ma->paint_clone_slot >= count) {
- ma->paint_clone_slot = count - 1;
+ /* COW needed when adding texture slot on an object with no materials.
+ * But do it only when slots actually change to avoid continuous depsgraph updates. */
+ if (ma->tot_slots != prev_tot_slots || ma->paint_active_slot != prev_paint_active_slot ||
+ ma->paint_clone_slot != prev_paint_clone_slot ||
+ (ma->texpaintslot && prev_texpaintslot &&
+ memcmp(ma->texpaintslot, prev_texpaintslot, sizeof(*ma->texpaintslot) * ma->tot_slots) !=
+ 0)) {
+ DEG_id_tag_update(&ma->id, ID_RECALC_SHADING | ID_RECALC_COPY_ON_WRITE);
}
+
+ MEM_SAFE_FREE(prev_texpaintslot);
}
void BKE_texpaint_slots_refresh_object(Scene *scene, struct Object *ob)
diff --git a/source/blender/blenkernel/intern/mball.cc b/source/blender/blenkernel/intern/mball.cc
index 09d286b0aa0..6b1394f65ab 100644
--- a/source/blender/blenkernel/intern/mball.cc
+++ b/source/blender/blenkernel/intern/mball.cc
@@ -42,6 +42,7 @@
#include "BKE_geometry_set.hh"
#include "BKE_idtype.h"
#include "BKE_lattice.h"
+#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_material.h"
@@ -64,10 +65,7 @@ static void metaball_init_data(ID *id)
MEMCPY_STRUCT_AFTER(metaball, DNA_struct_default_get(MetaBall), id);
}
-static void metaball_copy_data(Main *UNUSED(bmain),
- ID *id_dst,
- const ID *id_src,
- const int UNUSED(flag))
+static void metaball_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int /*flag*/)
{
MetaBall *metaball_dst = (MetaBall *)id_dst;
const MetaBall *metaball_src = (const MetaBall *)id_src;
@@ -299,7 +297,7 @@ bool BKE_mball_is_basis(const Object *ob)
/* Just a quick test. */
const int len = strlen(ob->id.name);
- return (!isdigit(ob->id.name[len - 1]));
+ return !isdigit(ob->id.name[len - 1]);
}
bool BKE_mball_is_same_group(const Object *ob1, const Object *ob2)
@@ -449,7 +447,8 @@ Object *BKE_mball_basis_find(Scene *scene, Object *object)
BLI_split_name_num(basisname, &basisnr, object->id.name + 2, '.');
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *ob = base->object;
if ((ob->type == OB_MBALL) && !(base->flag & BASE_FROM_DUPLI)) {
if (ob != bob) {
@@ -527,7 +526,7 @@ bool BKE_mball_center_median(const MetaBall *mb, float r_cent[3])
}
if (total) {
- mul_v3_fl(r_cent, 1.0f / (float)total);
+ mul_v3_fl(r_cent, 1.0f / float(total));
}
return (total != 0);
diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.cc
index 49963c333ec..f8a64a7cd8b 100644
--- a/source/blender/blenkernel/intern/mball_tessellate.c
+++ b/source/blender/blenkernel/intern/mball_tessellate.cc
@@ -5,12 +5,12 @@
* \ingroup bke
*/
-#include <ctype.h>
-#include <float.h>
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cctype>
+#include <cfloat>
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -46,44 +46,52 @@
/* Data types */
-typedef struct corner { /* corner of a cube */
- int i, j, k; /* (i, j, k) is index within lattice */
- float co[3], value; /* location and function value */
+/** Corner of a cube. */
+typedef struct corner {
+ int i, j, k; /* (i, j, k) is index within lattice */
+ float co[3], value; /* location and function value */
struct corner *next;
} CORNER;
-typedef struct cube { /* partitioning cell (cube) */
+/** Partitioning cell (cube). */
+typedef struct cube {
int i, j, k; /* lattice location of cube */
CORNER *corners[8]; /* eight corners */
} CUBE;
-typedef struct cubes { /* linked list of cubes acting as stack */
- CUBE cube; /* a single cube */
- struct cubes *next; /* remaining elements */
+/** Linked list of cubes acting as stack. */
+typedef struct cubes {
+ CUBE cube; /* a single cube */
+ struct cubes *next; /* remaining elements */
} CUBES;
-typedef struct centerlist { /* list of cube locations */
- int i, j, k; /* cube location */
- struct centerlist *next; /* remaining elements */
+/** List of cube locations. */
+typedef struct centerlist {
+ int i, j, k; /* cube location */
+ struct centerlist *next; /* remaining elements */
} CENTERLIST;
-typedef struct edgelist { /* list of edges */
+/** List of edges. */
+typedef struct edgelist {
int i1, j1, k1, i2, j2, k2; /* edge corner ids */
int vid; /* vertex id */
struct edgelist *next; /* remaining elements */
} EDGELIST;
-typedef struct intlist { /* list of integers */
- int i; /* an integer */
- struct intlist *next; /* remaining elements */
+/** List of integers. */
+typedef struct intlist {
+ int i; /* an integer */
+ struct intlist *next; /* remaining elements */
} INTLIST;
-typedef struct intlists { /* list of list of integers */
- INTLIST *list; /* a list of integers */
- struct intlists *next; /* remaining elements */
+/** List of list of integers. */
+typedef struct intlists {
+ INTLIST *list; /* a list of integers */
+ struct intlists *next; /* remaining elements */
} INTLISTS;
-typedef struct Box { /* an AABB with pointer to metalelem */
+/** An AABB with pointer to metal-elem. */
+typedef struct Box {
float min[3], max[3];
const MetaElem *ml;
} Box;
@@ -93,32 +101,33 @@ typedef struct MetaballBVHNode { /* BVH node */
struct MetaballBVHNode *child[2];
} MetaballBVHNode;
-typedef struct process { /* parameters, storage */
- float thresh, size; /* mball threshold, single cube size */
- float delta; /* small delta for calculating normals */
- unsigned int converge_res; /* converge procedure resolution (more = slower) */
+/** Parameters, storage. */
+typedef struct process {
+ float thresh, size; /* mball threshold, single cube size */
+ float delta; /* small delta for calculating normals */
+ uint converge_res; /* converge procedure resolution (more = slower) */
- MetaElem **mainb; /* array of all metaelems */
- unsigned int totelem, mem; /* number of metaelems */
+ MetaElem **mainb; /* array of all meta-elems. */
+ uint totelem, mem; /* number of meta-elems. */
MetaballBVHNode metaball_bvh; /* The simplest bvh */
- Box allbb; /* Bounding box of all metaelems */
+ Box allbb; /* Bounding box of all meta-elems */
MetaballBVHNode **bvh_queue; /* Queue used during bvh traversal */
- unsigned int bvh_queue_size;
+ uint bvh_queue_size;
CUBES *cubes; /* stack of cubes waiting for polygonization */
CENTERLIST **centers; /* cube center hash table */
CORNER **corners; /* corner value hash table */
EDGELIST **edges; /* edge and vertex id hash table */
- int (*indices)[4]; /* output indices */
- unsigned int totindex; /* size of memory allocated for indices */
- unsigned int curindex; /* number of currently added indices */
+ int (*indices)[4]; /* output indices */
+ uint totindex; /* size of memory allocated for indices */
+ uint curindex; /* number of currently added indices */
float (*co)[3], (*no)[3]; /* surface vertices - positions and normals */
- unsigned int totvertex; /* memory size */
- unsigned int curvertex; /* currently added vertices */
+ uint totvertex; /* memory size */
+ uint curvertex; /* currently added vertices */
/* memory allocation from common pool */
MemArena *pgn_elements;
@@ -155,13 +164,12 @@ static void make_box_from_metaelem(Box *r, const MetaElem *ml)
* where centroids of elements in the [start, i) segment lie "on the right side" of div,
* and elements in the [i, end) segment lie "on the left"
*/
-static unsigned int partition_mainb(
- MetaElem **mainb, unsigned int start, unsigned int end, unsigned int s, float div)
+static uint partition_mainb(MetaElem **mainb, uint start, uint end, uint s, float div)
{
- unsigned int i = start, j = end - 1;
+ uint i = start, j = end - 1;
div *= 2.0f;
- while (1) {
+ while (true) {
while (i < j && div > (mainb[i]->bb->vec[6][s] + mainb[i]->bb->vec[0][s])) {
i++;
}
@@ -188,13 +196,10 @@ static unsigned int partition_mainb(
/**
* Recursively builds a BVH, dividing elements along the middle of the longest axis of allbox.
*/
-static void build_bvh_spatial(PROCESS *process,
- MetaballBVHNode *node,
- unsigned int start,
- unsigned int end,
- const Box *allbox)
+static void build_bvh_spatial(
+ PROCESS *process, MetaballBVHNode *node, uint start, uint end, const Box *allbox)
{
- unsigned int part, j, s;
+ uint part, j, s;
float dim[3], div;
/* Maximum bvh queue size is number of nodes which are made, equals calls to this function. */
@@ -217,18 +222,19 @@ static void build_bvh_spatial(PROCESS *process,
part = partition_mainb(process->mainb, start, end, s, div);
make_box_from_metaelem(&node->bb[0], process->mainb[start]);
- node->child[0] = NULL;
+ node->child[0] = nullptr;
if (part > start + 1) {
for (j = start; j < part; j++) {
make_box_union(process->mainb[j]->bb, &node->bb[0], &node->bb[0]);
}
- node->child[0] = BLI_memarena_alloc(process->pgn_elements, sizeof(MetaballBVHNode));
+ node->child[0] = static_cast<MetaballBVHNode *>(
+ BLI_memarena_alloc(process->pgn_elements, sizeof(MetaballBVHNode)));
build_bvh_spatial(process, node->child[0], start, part, &node->bb[0]);
}
- node->child[1] = NULL;
+ node->child[1] = nullptr;
if (part < end) {
make_box_from_metaelem(&node->bb[1], process->mainb[part]);
@@ -237,7 +243,8 @@ static void build_bvh_spatial(PROCESS *process,
make_box_union(process->mainb[j]->bb, &node->bb[1], &node->bb[1]);
}
- node->child[1] = BLI_memarena_alloc(process->pgn_elements, sizeof(MetaballBVHNode));
+ node->child[1] = static_cast<MetaballBVHNode *>(
+ BLI_memarena_alloc(process->pgn_elements, sizeof(MetaballBVHNode)));
build_bvh_spatial(process, node->child[1], part, end, &node->bb[1]);
}
}
@@ -283,7 +290,7 @@ static void build_bvh_spatial(PROCESS *process,
#define HASHBIT (5)
/** Hash table size (32768). */
-#define HASHSIZE (size_t)(1 << (3 * HASHBIT))
+#define HASHSIZE size_t(1 << (3 * HASHBIT))
#define HASH(i, j, k) ((((((i)&31) << 5) | ((j)&31)) << 5) | ((k)&31))
@@ -401,7 +408,7 @@ static float densfunc(const MetaElem *ball, float x, float y, float z)
static float metaball(PROCESS *process, float x, float y, float z)
{
float dens = 0.0f;
- unsigned int front = 0, back = 0;
+ uint front = 0, back = 0;
MetaballBVHNode *node;
process->bvh_queue[front++] = &process->metaball_bvh;
@@ -436,7 +443,8 @@ static void make_face(PROCESS *process, int i1, int i2, int i3, int i4)
if (UNLIKELY(process->totindex == process->curindex)) {
process->totindex = process->totindex ? (process->totindex * 2) : MBALL_ARRAY_LEN_INIT;
- process->indices = MEM_reallocN(process->indices, sizeof(int[4]) * process->totindex);
+ process->indices = static_cast<int(*)[4]>(
+ MEM_reallocN(process->indices, sizeof(int[4]) * process->totindex));
}
int *cur = process->indices[process->curindex++];
@@ -453,12 +461,12 @@ static void make_face(PROCESS *process, int i1, int i2, int i3, int i4)
accumulate_vertex_normals_v3(process->no[i1],
process->no[i2],
process->no[i3],
- NULL,
+ nullptr,
n,
process->co[i1],
process->co[i2],
process->co[i3],
- NULL);
+ nullptr);
}
else {
normal_quad_v3(n, process->co[i1], process->co[i2], process->co[i3], process->co[i4]);
@@ -669,20 +677,20 @@ static CORNER *setcorner(PROCESS *process, int i, int j, int k)
index = HASH(i, j, k);
c = process->corners[index];
- for (; c != NULL; c = c->next) {
+ for (; c != nullptr; c = c->next) {
if (c->i == i && c->j == j && c->k == k) {
return c;
}
}
- c = BLI_memarena_alloc(process->pgn_elements, sizeof(CORNER));
+ c = static_cast<CORNER *>(BLI_memarena_alloc(process->pgn_elements, sizeof(CORNER)));
c->i = i;
- c->co[0] = ((float)i - 0.5f) * process->size;
+ c->co[0] = (float(i) - 0.5f) * process->size;
c->j = j;
- c->co[1] = ((float)j - 0.5f) * process->size;
+ c->co[1] = (float(j) - 0.5f) * process->size;
c->k = k;
- c->co[2] = ((float)k - 0.5f) * process->size;
+ c->co[2] = (float(k) - 0.5f) * process->size;
c->value = metaball(process, c->co[0], c->co[1], c->co[2]);
@@ -738,7 +746,7 @@ static int otherface(int edge, int face)
/**
* create the 256 entry table for cubical polygonization
*/
-static void makecubetable(void)
+static void makecubetable()
{
static bool is_done = false;
int i, e, c, done[12], pos[8];
@@ -757,20 +765,20 @@ static void makecubetable(void)
}
for (e = 0; e < 12; e++) {
if (!done[e] && (pos[corner1[e]] != pos[corner2[e]])) {
- INTLIST *ints = NULL;
- INTLISTS *lists = MEM_callocN(sizeof(INTLISTS), "mball_intlist");
+ INTLIST *ints = nullptr;
+ INTLISTS *lists = static_cast<INTLISTS *>(MEM_callocN(sizeof(INTLISTS), "mball_intlist"));
int start = e, edge = e;
/* get face that is to right of edge from pos to neg corner: */
int face = pos[corner1[e]] ? rightface[e] : leftface[e];
- while (1) {
+ while (true) {
edge = nextcwedge(edge, face);
done[edge] = 1;
if (pos[corner1[edge]] != pos[corner2[edge]]) {
INTLIST *tmp = ints;
- ints = MEM_callocN(sizeof(INTLIST), "mball_intlist");
+ ints = static_cast<INTLIST *>(MEM_callocN(sizeof(INTLIST), "mball_intlist"));
ints->i = edge;
ints->next = tmp; /* add edge to head of list */
@@ -834,7 +842,7 @@ void BKE_mball_cubeTable_free(void)
MEM_freeN(lists);
lists = nlists;
}
- cubetable[i] = NULL;
+ cubetable[i] = nullptr;
}
}
@@ -851,13 +859,13 @@ static int setcenter(PROCESS *process, CENTERLIST *table[], const int i, const i
index = HASH(i, j, k);
q = table[index];
- for (l = q; l != NULL; l = l->next) {
+ for (l = q; l != nullptr; l = l->next) {
if (l->i == i && l->j == j && l->k == k) {
return 1;
}
}
- newc = BLI_memarena_alloc(process->pgn_elements, sizeof(CENTERLIST));
+ newc = static_cast<CENTERLIST *>(BLI_memarena_alloc(process->pgn_elements, sizeof(CENTERLIST)));
newc->i = i;
newc->j = j;
newc->k = k;
@@ -887,7 +895,7 @@ static void setedge(PROCESS *process, int i1, int j1, int k1, int i2, int j2, in
k2 = t;
}
index = HASH(i1, j1, k1) + HASH(i2, j2, k2);
- newe = BLI_memarena_alloc(process->pgn_elements, sizeof(EDGELIST));
+ newe = static_cast<EDGELIST *>(BLI_memarena_alloc(process->pgn_elements, sizeof(EDGELIST)));
newe->i1 = i1;
newe->j1 = j1;
@@ -919,7 +927,7 @@ static int getedge(EDGELIST *table[], int i1, int j1, int k1, int i2, int j2, in
k2 = t;
}
q = table[HASH(i1, j1, k1) + HASH(i2, j2, k2)];
- for (; q != NULL; q = q->next) {
+ for (; q != nullptr; q = q->next) {
if (q->i1 == i1 && q->j1 == j1 && q->k1 == k1 && q->i2 == i2 && q->j2 == j2 && q->k2 == k2) {
return q->vid;
}
@@ -934,8 +942,10 @@ static void addtovertices(PROCESS *process, const float v[3], const float no[3])
{
if (UNLIKELY(process->curvertex == process->totvertex)) {
process->totvertex = process->totvertex ? process->totvertex * 2 : MBALL_ARRAY_LEN_INIT;
- process->co = MEM_reallocN(process->co, process->totvertex * sizeof(float[3]));
- process->no = MEM_reallocN(process->no, process->totvertex * sizeof(float[3]));
+ process->co = static_cast<float(*)[3]>(
+ MEM_reallocN(process->co, process->totvertex * sizeof(float[3])));
+ process->no = static_cast<float(*)[3]>(
+ MEM_reallocN(process->no, process->totvertex * sizeof(float[3])));
}
copy_v3_v3(process->co[process->curvertex], v);
@@ -984,7 +994,7 @@ static int vertid(PROCESS *process, const CORNER *c1, const CORNER *c2)
#endif
addtovertices(process, v, no); /* save vertex */
- vid = (int)process->curvertex - 1;
+ vid = int(process->curvertex) - 1;
setedge(process, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k, vid);
return vid;
@@ -1041,7 +1051,7 @@ static void add_cube(PROCESS *process, int i, int j, int k)
/* test if cube has been found before */
if (setcenter(process, process->centers, i, j, k) == 0) {
/* push cube on stack: */
- ncube = BLI_memarena_alloc(process->pgn_elements, sizeof(CUBES));
+ ncube = static_cast<CUBES *>(BLI_memarena_alloc(process->pgn_elements, sizeof(CUBES)));
ncube->next = process->cubes;
process->cubes = ncube;
@@ -1059,9 +1069,9 @@ static void add_cube(PROCESS *process, int i, int j, int k)
static void next_lattice(int r[3], const float pos[3], const float size)
{
- r[0] = (int)ceil((pos[0] / size) + 0.5f);
- r[1] = (int)ceil((pos[1] / size) + 0.5f);
- r[2] = (int)ceil((pos[2] / size) + 0.5f);
+ r[0] = int(ceil((pos[0] / size) + 0.5f));
+ r[1] = int(ceil((pos[1] / size) + 0.5f));
+ r[2] = int(ceil((pos[2] / size) + 0.5f));
}
static void prev_lattice(int r[3], const float pos[3], const float size)
{
@@ -1072,15 +1082,15 @@ static void prev_lattice(int r[3], const float pos[3], const float size)
}
static void closest_latice(int r[3], const float pos[3], const float size)
{
- r[0] = (int)floorf(pos[0] / size + 1.0f);
- r[1] = (int)floorf(pos[1] / size + 1.0f);
- r[2] = (int)floorf(pos[2] / size + 1.0f);
+ r[0] = int(floorf(pos[0] / size + 1.0f));
+ r[1] = int(floorf(pos[1] / size + 1.0f));
+ r[2] = int(floorf(pos[2] / size + 1.0f));
}
/**
* Find at most 26 cubes to start polygonization from.
*/
-static void find_first_points(PROCESS *process, const unsigned int em)
+static void find_first_points(PROCESS *process, const uint em)
{
const MetaElem *ml;
int center[3], lbn[3], rtf[3], it[3], dir[3], add[3];
@@ -1126,8 +1136,8 @@ static void find_first_points(PROCESS *process, const unsigned int em)
}
/**
- * The main polygonization proc.
- * Allocates memory, makes cubetable,
+ * The main polygonization processing function.
+ * Allocates memory, makes cube-table,
* finds starting surface points
* and processes cubes on the stack until none left.
*/
@@ -1135,11 +1145,14 @@ static void polygonize(PROCESS *process)
{
CUBE c;
- process->centers = MEM_callocN(HASHSIZE * sizeof(CENTERLIST *), "mbproc->centers");
- process->corners = MEM_callocN(HASHSIZE * sizeof(CORNER *), "mbproc->corners");
- process->edges = MEM_callocN(2 * HASHSIZE * sizeof(EDGELIST *), "mbproc->edges");
- process->bvh_queue = MEM_callocN(sizeof(MetaballBVHNode *) * process->bvh_queue_size,
- "Metaball BVH Queue");
+ process->centers = static_cast<CENTERLIST **>(
+ MEM_callocN(HASHSIZE * sizeof(CENTERLIST *), "mbproc->centers"));
+ process->corners = static_cast<CORNER **>(
+ MEM_callocN(HASHSIZE * sizeof(CORNER *), "mbproc->corners"));
+ process->edges = static_cast<EDGELIST **>(
+ MEM_callocN(2 * HASHSIZE * sizeof(EDGELIST *), "mbproc->edges"));
+ process->bvh_queue = static_cast<MetaballBVHNode **>(
+ MEM_callocN(sizeof(MetaballBVHNode *) * process->bvh_queue_size, "Metaball BVH Queue"));
makecubetable();
@@ -1147,7 +1160,7 @@ static void polygonize(PROCESS *process)
find_first_points(process, i);
}
- while (process->cubes != NULL) {
+ while (process->cubes != nullptr) {
c = process->cubes->cube;
process->cubes = process->cubes->next;
@@ -1168,41 +1181,42 @@ static void init_meta(Depsgraph *depsgraph, PROCESS *process, Scene *scene, Obje
MetaBall *mb;
const MetaElem *ml;
float obinv[4][4], obmat[4][4];
- unsigned int i;
+ uint i;
int obnr, zero_size = 0;
char obname[MAX_ID_NAME];
SceneBaseIter iter;
const eEvaluationMode deg_eval_mode = DEG_get_mode(depsgraph);
const short parenting_dupli_transflag = (OB_DUPLIFACES | OB_DUPLIVERTS);
- copy_m4_m4(obmat, ob->obmat); /* to cope with duplicators from BKE_scene_base_iter_next */
- invert_m4_m4(obinv, ob->obmat);
+ copy_m4_m4(obmat,
+ ob->object_to_world); /* to cope with duplicators from BKE_scene_base_iter_next */
+ invert_m4_m4(obinv, ob->object_to_world);
BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
/* make main array */
- BKE_scene_base_iter_next(depsgraph, &iter, &sce_iter, 0, NULL, NULL);
+ BKE_scene_base_iter_next(depsgraph, &iter, &sce_iter, 0, nullptr, nullptr);
while (BKE_scene_base_iter_next(depsgraph, &iter, &sce_iter, 1, &base, &bob)) {
if (bob->type == OB_MBALL) {
zero_size = 0;
- ml = NULL;
+ ml = nullptr;
/* If this metaball is the original that's used for duplication, only have it visible when
* the instancer is visible too. */
- if ((base->flag_legacy & OB_FROMDUPLI) == 0 && ob->parent != NULL &&
+ if ((base->flag_legacy & OB_FROMDUPLI) == 0 && ob->parent != nullptr &&
(ob->parent->transflag & parenting_dupli_transflag) != 0 &&
(BKE_object_visibility(ob->parent, deg_eval_mode) & OB_VISIBLE_SELF) == 0) {
continue;
}
if (bob == ob && (base->flag_legacy & OB_FROMDUPLI) == 0) {
- mb = ob->data;
+ mb = static_cast<MetaBall *>(ob->data);
if (mb->editelems) {
- ml = mb->editelems->first;
+ ml = static_cast<const MetaElem *>(mb->editelems->first);
}
else {
- ml = mb->elems.first;
+ ml = static_cast<const MetaElem *>(mb->elems.first);
}
}
else {
@@ -1211,26 +1225,26 @@ static void init_meta(Depsgraph *depsgraph, PROCESS *process, Scene *scene, Obje
BLI_split_name_num(name, &nr, bob->id.name + 2, '.');
if (STREQ(obname, name)) {
- mb = bob->data;
+ mb = static_cast<MetaBall *>(bob->data);
if (mb->editelems) {
- ml = mb->editelems->first;
+ ml = static_cast<const MetaElem *>(mb->editelems->first);
}
else {
- ml = mb->elems.first;
+ ml = static_cast<const MetaElem *>(mb->elems.first);
}
}
}
/* when metaball object has zero scale, then MetaElem to this MetaBall
* will not be put to mainb array */
- if (has_zero_axis_m4(bob->obmat)) {
+ if (has_zero_axis_m4(bob->object_to_world)) {
zero_size = 1;
}
else if (bob->parent) {
struct Object *pob = bob->parent;
while (pob) {
- if (has_zero_axis_m4(pob->obmat)) {
+ if (has_zero_axis_m4(pob->object_to_world)) {
zero_size = 1;
break;
}
@@ -1253,11 +1267,15 @@ static void init_meta(Depsgraph *depsgraph, PROCESS *process, Scene *scene, Obje
MetaElem *new_ml;
/* make a copy because of duplicates */
- new_ml = BLI_memarena_alloc(process->pgn_elements, sizeof(MetaElem));
+ new_ml = static_cast<MetaElem *>(
+ BLI_memarena_alloc(process->pgn_elements, sizeof(MetaElem)));
*(new_ml) = *ml;
- new_ml->bb = BLI_memarena_alloc(process->pgn_elements, sizeof(BoundBox));
- new_ml->mat = BLI_memarena_alloc(process->pgn_elements, sizeof(float[4][4]));
- new_ml->imat = BLI_memarena_alloc(process->pgn_elements, sizeof(float[4][4]));
+ new_ml->bb = static_cast<BoundBox *>(
+ BLI_memarena_alloc(process->pgn_elements, sizeof(BoundBox)));
+ new_ml->mat = static_cast<float *>(
+ BLI_memarena_alloc(process->pgn_elements, sizeof(float[4][4])));
+ new_ml->imat = static_cast<float *>(
+ BLI_memarena_alloc(process->pgn_elements, sizeof(float[4][4])));
/* too big stiffness seems only ugly due to linear interpolation
* no need to have possibility for too big stiffness */
@@ -1290,7 +1308,7 @@ static void init_meta(Depsgraph *depsgraph, PROCESS *process, Scene *scene, Obje
* rotation ->
* ml local space
*/
- mul_m4_series((float(*)[4])new_ml->mat, obinv, bob->obmat, pos, rot);
+ mul_m4_series((float(*)[4])new_ml->mat, obinv, bob->object_to_world, pos, rot);
/* ml local space -> basis object space */
invert_m4_m4((float(*)[4])new_ml->imat, (float(*)[4])new_ml->mat);
@@ -1333,25 +1351,26 @@ static void init_meta(Depsgraph *depsgraph, PROCESS *process, Scene *scene, Obje
copy_v3_fl3(new_ml->bb->vec[6], +expx, +expy, +expz); /* 6 */
copy_v3_fl3(new_ml->bb->vec[7], -expx, +expy, +expz); /* 7 */
- /* transformation of Metalem bb */
+ /* Transformation of meta-elem bounding-box. */
for (i = 0; i < 8; i++) {
mul_m4_v3((float(*)[4])new_ml->mat, new_ml->bb->vec[i]);
}
- /* find max and min of transformed bb */
+ /* Find max and min of transformed bounding-box. */
INIT_MINMAX(tempmin, tempmax);
for (i = 0; i < 8; i++) {
DO_MINMAX(new_ml->bb->vec[i], tempmin, tempmax);
}
- /* set only point 0 and 6 - AABB of Metaelem */
+ /* Set only point 0 and 6 - AABB of meta-elem. */
copy_v3_v3(new_ml->bb->vec[0], tempmin);
copy_v3_v3(new_ml->bb->vec[6], tempmax);
/* add new_ml to mainb[] */
if (UNLIKELY(process->totelem == process->mem)) {
process->mem = process->mem * 2 + 10;
- process->mainb = MEM_reallocN(process->mainb, sizeof(MetaElem *) * process->mem);
+ process->mainb = static_cast<MetaElem **>(
+ MEM_reallocN(process->mainb, sizeof(MetaElem *) * process->mem));
}
process->mainb[process->totelem++] = new_ml;
}
@@ -1361,7 +1380,7 @@ static void init_meta(Depsgraph *depsgraph, PROCESS *process, Scene *scene, Obje
}
}
- /* compute AABB of all Metaelems */
+ /* Compute AABB of all meta-elems. */
if (process->totelem > 0) {
copy_v3_v3(process->allbb.min, process->mainb[0]->bb->vec[0]);
copy_v3_v3(process->allbb.max, process->mainb[0]->bb->vec[6]);
@@ -1376,7 +1395,7 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
PROCESS process = {0};
const bool is_render = DEG_get_mode(depsgraph) == DAG_EVAL_RENDER;
- MetaBall *mb = ob->data;
+ MetaBall *mb = static_cast<MetaBall *>(ob->data);
process.thresh = mb->thresh;
@@ -1394,10 +1413,10 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
}
if (!is_render && (mb->flag == MB_UPDATE_NEVER)) {
- return NULL;
+ return nullptr;
}
if ((G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) && mb->flag == MB_UPDATE_FAST) {
- return NULL;
+ return nullptr;
}
if (is_render) {
@@ -1418,43 +1437,44 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
init_meta(depsgraph, &process, scene, ob);
if (process.totelem == 0) {
freepolygonize(&process);
- return NULL;
+ return nullptr;
}
build_bvh_spatial(&process, &process.metaball_bvh, 0, process.totelem, &process.allbb);
- /* Don't polygonize meta-balls with too high resolution (base mball too small)
- * NOTE: Eps was 0.0001f but this was giving problems for blood animation for
+ /* Don't polygonize meta-balls with too high resolution (base meta-ball too small).
+ * NOTE: Epsilon was 0.0001f but this was giving problems for blood animation for
* the open movie "Sintel", using 0.00001f. */
if (ob->scale[0] < 0.00001f * (process.allbb.max[0] - process.allbb.min[0]) ||
ob->scale[1] < 0.00001f * (process.allbb.max[1] - process.allbb.min[1]) ||
ob->scale[2] < 0.00001f * (process.allbb.max[2] - process.allbb.min[2])) {
freepolygonize(&process);
- return NULL;
+ return nullptr;
}
polygonize(&process);
if (process.curindex == 0) {
freepolygonize(&process);
- return NULL;
+ return nullptr;
}
freepolygonize(&process);
Mesh *mesh = (Mesh *)BKE_id_new_nomain(ID_ME, ((ID *)ob->data)->name + 2);
- mesh->totvert = (int)process.curvertex;
- MVert *mvert = CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CONSTRUCT, NULL, mesh->totvert);
+ mesh->totvert = int(process.curvertex);
+ MVert *mvert = static_cast<MVert *>(
+ CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CONSTRUCT, nullptr, mesh->totvert));
for (int i = 0; i < mesh->totvert; i++) {
copy_v3_v3(mvert[i].co, process.co[i]);
- mvert->flag = 0;
}
MEM_freeN(process.co);
- mesh->totpoly = (int)process.curindex;
- MPoly *mpoly = CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CONSTRUCT, NULL, mesh->totpoly);
- MLoop *mloop = CustomData_add_layer(
- &mesh->ldata, CD_MLOOP, CD_CONSTRUCT, NULL, mesh->totpoly * 4);
+ mesh->totpoly = int(process.curindex);
+ MPoly *mpoly = static_cast<MPoly *>(
+ CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CONSTRUCT, nullptr, mesh->totpoly));
+ MLoop *mloop = static_cast<MLoop *>(
+ CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CONSTRUCT, nullptr, mesh->totpoly * 4));
int loop_offset = 0;
for (int i = 0; i < mesh->totpoly; i++) {
@@ -1465,11 +1485,11 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
mpoly[i].totloop = count;
mpoly[i].flag = ME_SMOOTH;
- mloop[loop_offset].v = (uint32_t)indices[0];
- mloop[loop_offset + 1].v = (uint32_t)indices[1];
- mloop[loop_offset + 2].v = (uint32_t)indices[2];
+ mloop[loop_offset].v = uint32_t(indices[0]);
+ mloop[loop_offset + 1].v = uint32_t(indices[1]);
+ mloop[loop_offset + 2].v = uint32_t(indices[2]);
if (count == 4) {
- mloop[loop_offset + 3].v = (uint32_t)indices[3];
+ mloop[loop_offset + 3].v = uint32_t(indices[3]);
}
loop_offset += count;
@@ -1479,7 +1499,7 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
for (int i = 0; i < mesh->totvert; i++) {
normalize_v3(process.no[i]);
}
- mesh->runtime.vert_normals = process.no;
+ mesh->runtime->vert_normals = process.no;
BKE_mesh_vertex_normals_clear_dirty(mesh);
mesh->totloop = loop_offset;
diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc
index 8616b056d7f..2d613f24a0a 100644
--- a/source/blender/blenkernel/intern/mesh.cc
+++ b/source/blender/blenkernel/intern/mesh.cc
@@ -68,6 +68,7 @@ using blender::BitVector;
using blender::float3;
using blender::MutableSpan;
using blender::Span;
+using blender::StringRef;
using blender::VArray;
using blender::Vector;
@@ -88,7 +89,7 @@ static void mesh_init_data(ID *id)
CustomData_reset(&mesh->pdata);
CustomData_reset(&mesh->ldata);
- BKE_mesh_runtime_init_data(mesh);
+ mesh->runtime = new blender::bke::MeshRuntime();
/* A newly created mesh does not have normals, so tag them dirty. This will be cleared
* by #BKE_mesh_vertex_normals_clear_dirty or #BKE_mesh_poly_normals_ensure. */
@@ -102,14 +103,19 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
Mesh *mesh_dst = (Mesh *)id_dst;
const Mesh *mesh_src = (const Mesh *)id_src;
- BKE_mesh_runtime_reset_on_copy(mesh_dst, flag);
+ mesh_dst->runtime = new blender::bke::MeshRuntime();
+ mesh_dst->runtime->deformed_only = mesh_src->runtime->deformed_only;
+ mesh_dst->runtime->wrapper_type = mesh_src->runtime->wrapper_type;
+ mesh_dst->runtime->wrapper_type_finalize = mesh_src->runtime->wrapper_type_finalize;
+ mesh_dst->runtime->subsurf_runtime_data = mesh_src->runtime->subsurf_runtime_data;
+ mesh_dst->runtime->cd_mask_extra = mesh_src->runtime->cd_mask_extra;
/* Copy face dot tags, since meshes may be duplicated after a subsurf modifier
* or node, but we still need to be able to draw face center vertices. */
- mesh_dst->runtime.subsurf_face_dot_tags = static_cast<uint32_t *>(
- MEM_dupallocN(mesh_src->runtime.subsurf_face_dot_tags));
+ mesh_dst->runtime->subsurf_face_dot_tags = static_cast<uint32_t *>(
+ MEM_dupallocN(mesh_src->runtime->subsurf_face_dot_tags));
if ((mesh_src->id.tag & LIB_TAG_NO_MAIN) == 0) {
/* This is a direct copy of a main mesh, so for now it has the same topology. */
- mesh_dst->runtime.deformed_only = true;
+ mesh_dst->runtime->deformed_only = true;
}
/* This option is set for run-time meshes that have been copied from the current objects mode.
* Currently this is used for edit-mesh although it could be used for sculpt or other
@@ -120,7 +126,7 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
*
* While this could be the callers responsibility, keep here since it's
* highly unlikely we want to create a duplicate and not use it for drawing. */
- mesh_dst->runtime.is_original_bmesh = false;
+ mesh_dst->runtime->is_original_bmesh = false;
/* Only do tessface if we have no polys. */
const bool do_tessface = ((mesh_src->totface != 0) && (mesh_src->totpoly == 0));
@@ -148,8 +154,6 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
mesh_tessface_clear_intern(mesh_dst, false);
}
- mesh_dst->cd_flag = mesh_src->cd_flag;
-
mesh_dst->edit_mesh = nullptr;
mesh_dst->mselect = (MSelect *)MEM_dupallocN(mesh_dst->mselect);
@@ -195,6 +199,8 @@ static void mesh_free_data(ID *id)
BKE_mesh_runtime_free_data(mesh);
mesh_clear_geometry(mesh);
MEM_SAFE_FREE(mesh->mat);
+
+ delete mesh->runtime;
}
static void mesh_foreach_id(ID *id, LibraryForeachIDData *data)
@@ -230,7 +236,7 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
mesh->mface = nullptr;
mesh->totface = 0;
memset(&mesh->fdata, 0, sizeof(mesh->fdata));
- mesh->runtime = blender::dna::shallow_zero_initialize();
+ mesh->runtime = nullptr;
/* Do not store actual geometry data in case this is a library override ID. */
if (ID_IS_OVERRIDE_LIBRARY(mesh) && !is_undo) {
@@ -250,10 +256,19 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
Set<std::string> names_to_skip;
if (!BLO_write_is_undo(writer)) {
BKE_mesh_legacy_convert_hide_layers_to_flags(mesh);
+ BKE_mesh_legacy_convert_selection_layers_to_flags(mesh);
BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh);
BKE_mesh_legacy_bevel_weight_from_layers(mesh);
+ BKE_mesh_legacy_face_set_from_generic(mesh, poly_layers);
+ BKE_mesh_legacy_edge_crease_from_layers(mesh);
/* When converting to the old mesh format, don't save redundant attributes. */
- names_to_skip.add_multiple_new({".hide_vert", ".hide_edge", ".hide_poly", "material_index"});
+ names_to_skip.add_multiple_new({".hide_vert",
+ ".hide_edge",
+ ".hide_poly",
+ "material_index",
+ ".select_vert",
+ ".select_edge",
+ ".select_poly"});
/* Set deprecated mesh data pointers for forward compatibility. */
mesh->mvert = const_cast<MVert *>(mesh->verts().data());
@@ -331,8 +346,7 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
mesh->texflag &= ~ME_AUTOSPACE_EVALUATED;
mesh->edit_mesh = nullptr;
- mesh->runtime = blender::dna::shallow_zero_initialize();
- BKE_mesh_runtime_init_data(mesh);
+ mesh->runtime = new blender::bke::MeshRuntime();
/* happens with old files */
if (mesh->mselect == nullptr) {
@@ -346,12 +360,6 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
}
}
- if (!BLO_read_data_is_undo(reader)) {
- BKE_mesh_legacy_convert_flags_to_hide_layers(mesh);
- BKE_mesh_legacy_convert_mpoly_to_material_indices(mesh);
- BKE_mesh_legacy_bevel_weight_to_layers(mesh);
- }
-
/* We don't expect to load normals from files, since they are derived data. */
BKE_mesh_normals_tag_dirty(mesh);
BKE_mesh_assert_normals_dirty_or_calculated(mesh);
@@ -492,7 +500,7 @@ static int customdata_compare(
}
if (layer_count1 != layer_count2) {
- /* TODO(@HooglyBoogly): Reenable after tests are updated for material index refactor. */
+ /* TODO(@HooglyBoogly): Re-enable after tests are updated for material index refactor. */
// return MESHCMP_CDLAYERS_MISMATCH;
}
@@ -695,7 +703,6 @@ static int customdata_compare(
case CD_PROP_BOOL: {
const bool *l1_data = (bool *)l1->data;
const bool *l2_data = (bool *)l2->data;
-
for (int i = 0; i < total_length; i++) {
if (l1_data[i] != l2_data[i]) {
return MESHCMP_ATTRIBUTE_VALUE_MISMATCH;
@@ -1023,7 +1030,6 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
me_dst->totloop = loops_len;
me_dst->totpoly = polys_len;
- me_dst->cd_flag = me_src->cd_flag;
BKE_mesh_copy_parameters_for_eval(me_dst, me_src);
CustomData_copy(&me_src->vdata, &me_dst->vdata, mask.vmask, CD_SET_DEFAULT, verts_len);
@@ -1137,7 +1143,7 @@ static void ensure_orig_index_layer(CustomData &data, const int size)
void BKE_mesh_ensure_default_orig_index_customdata(Mesh *mesh)
{
- BLI_assert(mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA);
+ BLI_assert(mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_MDATA);
BKE_mesh_ensure_default_orig_index_customdata_no_check(mesh);
}
@@ -1396,7 +1402,7 @@ void BKE_mesh_material_remap(Mesh *me, const uint *remap, uint remap_len)
{
using namespace blender;
using namespace blender::bke;
- const short remap_len_short = (short)remap_len;
+ const short remap_len_short = short(remap_len);
#define MAT_NR_REMAP(n) \
if (n < remap_len_short) { \
@@ -1459,7 +1465,7 @@ void BKE_mesh_auto_smooth_flag_set(Mesh *me,
}
}
-int poly_find_loop_from_vert(const MPoly *poly, const MLoop *loopstart, uint vert)
+int poly_find_loop_from_vert(const MPoly *poly, const MLoop *loopstart, int vert)
{
for (int j = 0; j < poly->totloop; j++, loopstart++) {
if (loopstart->v == vert) {
@@ -1470,7 +1476,7 @@ int poly_find_loop_from_vert(const MPoly *poly, const MLoop *loopstart, uint ver
return -1;
}
-int poly_get_adj_loops_from_vert(const MPoly *poly, const MLoop *mloop, uint vert, uint r_adj[2])
+int poly_get_adj_loops_from_vert(const MPoly *poly, const MLoop *mloop, int vert, int r_adj[2])
{
int corner = poly_find_loop_from_vert(poly, &mloop[poly->loopstart], vert);
@@ -1602,38 +1608,6 @@ void BKE_mesh_tessface_clear(Mesh *mesh)
mesh_tessface_clear_intern(mesh, true);
}
-void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh)
-{
- if (UNLIKELY(mesh->cd_flag)) {
- return;
- }
-
- const Span<MVert> verts = mesh->verts();
- const Span<MEdge> edges = mesh->edges();
-
- for (const MVert &vert : verts) {
- if (vert.bweight != 0) {
- mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
- break;
- }
- }
-
- for (const MEdge &edge : edges) {
- if (edge.bweight != 0) {
- mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
- if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) {
- break;
- }
- }
- if (edge.crease != 0) {
- mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
- if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
- break;
- }
- }
- }
-}
-
/* -------------------------------------------------------------------- */
/* MSelect functions (currently used in weight paint mode) */
@@ -1645,39 +1619,46 @@ void BKE_mesh_mselect_clear(Mesh *me)
void BKE_mesh_mselect_validate(Mesh *me)
{
+ using namespace blender;
+ using namespace blender::bke;
MSelect *mselect_src, *mselect_dst;
int i_src, i_dst;
if (me->totselect == 0) {
return;
}
- const Span<MVert> verts = me->verts();
- const Span<MEdge> edges = me->edges();
- const Span<MPoly> polys = me->polys();
mselect_src = me->mselect;
mselect_dst = (MSelect *)MEM_malloc_arrayN(
(me->totselect), sizeof(MSelect), "Mesh selection history");
+ const AttributeAccessor attributes = me->attributes();
+ const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+ const VArray<bool> select_edge = attributes.lookup_or_default<bool>(
+ ".select_edge", ATTR_DOMAIN_EDGE, false);
+ const VArray<bool> select_poly = attributes.lookup_or_default<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE, false);
+
for (i_src = 0, i_dst = 0; i_src < me->totselect; i_src++) {
int index = mselect_src[i_src].index;
switch (mselect_src[i_src].type) {
case ME_VSEL: {
- if (verts[index].flag & SELECT) {
+ if (select_vert[index]) {
mselect_dst[i_dst] = mselect_src[i_src];
i_dst++;
}
break;
}
case ME_ESEL: {
- if (edges[index].flag & SELECT) {
+ if (select_edge[index]) {
mselect_dst[i_dst] = mselect_src[i_src];
i_dst++;
}
break;
}
case ME_FSEL: {
- if (polys[index].flag & SELECT) {
+ if (select_poly[index]) {
mselect_dst[i_dst] = mselect_src[i_src];
i_dst++;
}
@@ -1825,7 +1806,7 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh,
* only in case auto-smooth is enabled. */
const bool use_split_normals = (r_lnors_spacearr != nullptr) ||
((mesh->flag & ME_AUTOSMOOTH) != 0);
- const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : (float)M_PI;
+ const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : float(M_PI);
/* may be nullptr */
clnors = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
@@ -2099,8 +2080,8 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
}
/* Update normals manually to avoid recalculation after this operation. */
- mesh->runtime.vert_normals = (float(*)[3])MEM_reallocN(mesh->runtime.vert_normals,
- sizeof(float[3]) * mesh->totvert);
+ mesh->runtime->vert_normals = (float(*)[3])MEM_reallocN(mesh->runtime->vert_normals,
+ sizeof(float[3]) * mesh->totvert);
/* Perform actual split of vertices and edges. */
split_faces_split_new_verts(mesh, new_verts, num_new_verts);
@@ -2134,10 +2115,10 @@ void BKE_mesh_eval_geometry(Depsgraph *depsgraph, Mesh *mesh)
/* We are here because something did change in the mesh. This means we can not trust the existing
* evaluated mesh, and we don't know what parts of the mesh did change. So we simply delete the
* evaluated mesh and let objects to re-create it with updated settings. */
- if (mesh->runtime.mesh_eval != nullptr) {
- mesh->runtime.mesh_eval->edit_mesh = nullptr;
- BKE_id_free(nullptr, mesh->runtime.mesh_eval);
- mesh->runtime.mesh_eval = nullptr;
+ if (mesh->runtime->mesh_eval != nullptr) {
+ mesh->runtime->mesh_eval->edit_mesh = nullptr;
+ BKE_id_free(nullptr, mesh->runtime->mesh_eval);
+ mesh->runtime->mesh_eval = nullptr;
}
if (DEG_is_active(depsgraph)) {
Mesh *mesh_orig = (Mesh *)DEG_get_original_id(&mesh->id);
diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc
index 7a04e45fe00..360c7da2ae2 100644
--- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc
@@ -114,7 +114,7 @@ class MeshesToIMeshInfo {
* input `Mesh` that contained the `MVert` that it came from. */
int MeshesToIMeshInfo::input_mesh_for_imesh_vert(int imesh_v) const
{
- int n = static_cast<int>(mesh_vert_offset.size());
+ int n = int(mesh_vert_offset.size());
for (int i = 0; i < n - 1; ++i) {
if (imesh_v < mesh_vert_offset[i + 1]) {
return i;
@@ -127,7 +127,7 @@ int MeshesToIMeshInfo::input_mesh_for_imesh_vert(int imesh_v) const
* return the index of the input `Mesh` that contained the `MVert` that it came from. */
int MeshesToIMeshInfo::input_mesh_for_imesh_edge(int imesh_e) const
{
- int n = static_cast<int>(mesh_edge_offset.size());
+ int n = int(mesh_edge_offset.size());
for (int i = 0; i < n - 1; ++i) {
if (imesh_e < mesh_edge_offset[i + 1]) {
return i;
@@ -140,7 +140,7 @@ int MeshesToIMeshInfo::input_mesh_for_imesh_edge(int imesh_e) const
* input `Mesh` that contained the `MPoly` that it came from. */
int MeshesToIMeshInfo::input_mesh_for_imesh_face(int imesh_f) const
{
- int n = static_cast<int>(mesh_poly_offset.size());
+ int n = int(mesh_poly_offset.size());
for (int i = 0; i < n - 1; ++i) {
if (imesh_f < mesh_poly_offset[i + 1]) {
return i;
@@ -375,14 +375,10 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
* `mv` is in `dest_mesh` with index `mv_index`.
* The `orig_mv` vertex came from Mesh `orig_me` and had index `index_in_orig_me` there. */
static void copy_vert_attributes(Mesh *dest_mesh,
- MVert *mv,
- const MVert *orig_mv,
const Mesh *orig_me,
int mv_index,
int index_in_orig_me)
{
- mv->flag = orig_mv->flag;
-
/* For all layers in the orig mesh, copy the layer information. */
CustomData *target_cd = &dest_mesh->vdata;
const CustomData *source_cd = &orig_me->vdata;
@@ -449,7 +445,6 @@ static void copy_edge_attributes(Mesh *dest_mesh,
int medge_index,
int index_in_orig_me)
{
- medge->crease = orig_medge->crease;
medge->flag = orig_medge->flag;
CustomData *target_cd = &dest_mesh->edata;
const CustomData *source_cd = &orig_me->edata;
@@ -724,14 +719,14 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
MutableSpan<MVert> verts = result->verts_for_write();
for (int vi : im->vert_index_range()) {
const Vert *v = im->vert(vi);
- MVert *mv = &verts[vi];
- copy_v3fl_v3db(mv->co, v->co);
if (v->orig != NO_INDEX) {
const Mesh *orig_me;
int index_in_orig_me;
- const MVert *orig_mv = mim.input_mvert_for_orig_index(v->orig, &orig_me, &index_in_orig_me);
- copy_vert_attributes(result, mv, orig_mv, orig_me, vi, index_in_orig_me);
+ mim.input_mvert_for_orig_index(v->orig, &orig_me, &index_in_orig_me);
+ copy_vert_attributes(result, orig_me, vi, index_in_orig_me);
}
+ MVert *mv = &verts[vi];
+ copy_v3fl_v3db(mv->co, v->co);
}
/* Set the loopstart and totloop for each output poly,
@@ -836,7 +831,7 @@ Mesh *direct_mesh_boolean(Span<const Mesh *> meshes,
return mi;
}
}
- return static_cast<int>(mim.mesh_poly_offset.size()) - 1;
+ return int(mim.mesh_poly_offset.size()) - 1;
};
IMesh m_out = boolean_mesh(m_in,
static_cast<BoolOpType>(boolean_mode),
diff --git a/source/blender/blenkernel/intern/mesh_calc_edges.cc b/source/blender/blenkernel/intern/mesh_calc_edges.cc
index cc315130ad1..4a4c2ebcbb0 100644
--- a/source/blender/blenkernel/intern/mesh_calc_edges.cc
+++ b/source/blender/blenkernel/intern/mesh_calc_edges.cc
@@ -13,6 +13,7 @@
#include "BLI_threads.h"
#include "BLI_timeit.hh"
+#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
@@ -34,8 +35,7 @@ struct OrderedEdge {
}
}
- OrderedEdge(const uint v1, const uint v2)
- : OrderedEdge(static_cast<int>(v1), static_cast<int>(v2))
+ OrderedEdge(const uint v1, const uint v2) : OrderedEdge(int(v1), int(v2))
{
}
@@ -120,8 +120,7 @@ static void add_polygon_edges_to_hash_maps(Mesh *mesh,
}
static void serialize_and_initialize_deduplicated_edges(MutableSpan<EdgeMap> edge_maps,
- MutableSpan<MEdge> new_edges,
- short new_edge_flag)
+ MutableSpan<MEdge> new_edges)
{
/* All edges are distributed in the hash tables now. They have to be serialized into a single
* array below. To be able to parallelize this, we have to compute edge index offsets for each
@@ -147,7 +146,7 @@ static void serialize_and_initialize_deduplicated_edges(MutableSpan<EdgeMap> edg
/* Initialize new edge. */
new_edge.v1 = item.key.v_low;
new_edge.v2 = item.key.v_high;
- new_edge.flag = new_edge_flag;
+ new_edge.flag = ME_EDGEDRAW;
}
item.value.index = new_edge_index;
new_edge_index++;
@@ -217,7 +216,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select
* Each edge is assigned to one of the hash maps based on the lower bits of a hash value. */
const int parallel_maps = get_parallel_maps_count(mesh);
BLI_assert(is_power_of_2_i(parallel_maps));
- const uint32_t parallel_mask = static_cast<uint32_t>(parallel_maps) - 1;
+ const uint32_t parallel_mask = uint32_t(parallel_maps) - 1;
Array<EdgeMap> edge_maps(parallel_maps);
reserve_hash_maps(mesh, keep_existing_edges, edge_maps);
@@ -236,8 +235,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select
/* Create new edges. */
MutableSpan<MEdge> new_edges{
static_cast<MEdge *>(MEM_calloc_arrayN(new_totedge, sizeof(MEdge), __func__)), new_totedge};
- const short new_edge_flag = (ME_EDGEDRAW | ME_EDGERENDER) | (select_new_edges ? SELECT : 0);
- calc_edges::serialize_and_initialize_deduplicated_edges(edge_maps, new_edges, new_edge_flag);
+ calc_edges::serialize_and_initialize_deduplicated_edges(edge_maps, new_edges);
calc_edges::update_edge_indices_in_poly_loops(mesh, edge_maps, parallel_mask);
/* Free old CustomData and assign new one. */
@@ -246,6 +244,24 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select
CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_ASSIGN, new_edges.data(), new_totedge);
mesh->totedge = new_totedge;
+ if (select_new_edges) {
+ MutableAttributeAccessor attributes = mesh->attributes_for_write();
+ SpanAttributeWriter<bool> select_edge = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_edge", ATTR_DOMAIN_EDGE);
+ if (select_edge) {
+ int new_edge_index = 0;
+ for (const EdgeMap &edge_map : edge_maps) {
+ for (EdgeMap::Item item : edge_map.items()) {
+ if (item.value.original_edge == nullptr) {
+ select_edge.span[new_edge_index] = true;
+ }
+ new_edge_index++;
+ }
+ }
+ select_edge.finish();
+ }
+ }
+
/* Explicitly clear edge maps, because that way it can be parallelized. */
clear_hash_tables(edge_maps);
}
diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc
index e56df0e3fe3..2255038a991 100644
--- a/source/blender/blenkernel/intern/mesh_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_convert.cc
@@ -119,8 +119,7 @@ static void make_edges_mdata_extend(Mesh &mesh)
BLI_edgehashIterator_getKey(ehi, &medge->v1, &medge->v2);
BLI_edgehashIterator_setValue(ehi, POINTER_FROM_UINT(e_index));
- medge->crease = 0;
- medge->flag = ME_EDGEDRAW | ME_EDGERENDER;
+ medge->flag = ME_EDGEDRAW;
}
BLI_edgehashIterator_free(ehi);
@@ -224,7 +223,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
for (b = 1; b < dl->nr; b++) {
medge->v1 = startvert + ofs + b - 1;
medge->v2 = startvert + ofs + b;
- medge->flag = ME_LOOSEEDGE | ME_EDGERENDER | ME_EDGEDRAW;
+ medge->flag = ME_LOOSEEDGE | ME_EDGEDRAW;
medge++;
}
@@ -252,7 +251,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
else {
medge->v2 = startvert + ofs + b + 1;
}
- medge->flag = ME_LOOSEEDGE | ME_EDGERENDER | ME_EDGEDRAW;
+ medge->flag = ME_LOOSEEDGE | ME_EDGEDRAW;
medge++;
}
}
@@ -275,13 +274,13 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
mloop[0].v = startvert + index[0];
mloop[1].v = startvert + index[2];
mloop[2].v = startvert + index[1];
- mpoly->loopstart = (int)(mloop - loops.data());
+ mpoly->loopstart = int(mloop - loops.data());
mpoly->totloop = 3;
material_indices.span[mpoly - polys.data()] = dl->col;
if (mloopuv) {
for (int i = 0; i < 3; i++, mloopuv++) {
- mloopuv->uv[0] = (mloop[i].v - startvert) / (float)(dl->nr - 1);
+ mloopuv->uv[0] = (mloop[i].v - startvert) / float(dl->nr - 1);
mloopuv->uv[1] = 0.0f;
}
}
@@ -335,7 +334,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
mloop[1].v = p3;
mloop[2].v = p4;
mloop[3].v = p2;
- mpoly->loopstart = (int)(mloop - loops.data());
+ mpoly->loopstart = int(mloop - loops.data());
mpoly->totloop = 4;
material_indices.span[mpoly - polys.data()] = dl->col;
@@ -358,14 +357,14 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
/* find uv based on vertex index into grid array */
int v = mloop[i].v - startvert;
- mloopuv->uv[0] = (v / dl->nr) / (float)orco_sizev;
- mloopuv->uv[1] = (v % dl->nr) / (float)orco_sizeu;
+ mloopuv->uv[0] = (v / dl->nr) / float(orco_sizev);
+ mloopuv->uv[1] = (v % dl->nr) / float(orco_sizeu);
/* cyclic correction */
- if ((ELEM(i, 1, 2)) && mloopuv->uv[0] == 0.0f) {
+ if (ELEM(i, 1, 2) && mloopuv->uv[0] == 0.0f) {
mloopuv->uv[0] = 1.0f;
}
- if ((ELEM(i, 0, 1)) && mloopuv->uv[1] == 0.0f) {
+ if (ELEM(i, 0, 1) && mloopuv->uv[1] == 0.0f) {
mloopuv->uv[1] = 1.0f;
}
}
@@ -605,7 +604,7 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed
}
}
-void BKE_mesh_to_curve(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(scene), Object *ob)
+void BKE_mesh_to_curve(Main *bmain, Depsgraph *depsgraph, Scene * /*scene*/, Object *ob)
{
/* make new mesh data from the original copy */
Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
@@ -655,7 +654,7 @@ void BKE_pointcloud_from_mesh(Mesh *me, PointCloud *pointcloud)
point_positions.finish();
}
-void BKE_mesh_to_pointcloud(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(scene), Object *ob)
+void BKE_mesh_to_pointcloud(Main *bmain, Depsgraph *depsgraph, Scene * /*scene*/, Object *ob)
{
BLI_assert(ob->type == OB_MESH);
@@ -707,11 +706,11 @@ void BKE_mesh_edges_set_draw_render(Mesh *mesh)
{
MutableSpan<MEdge> edges = mesh->edges_for_write();
for (int i = 0; i < mesh->totedge; i++) {
- edges[i].flag |= ME_EDGEDRAW | ME_EDGERENDER;
+ edges[i].flag |= ME_EDGEDRAW;
}
}
-void BKE_pointcloud_to_mesh(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(scene), Object *ob)
+void BKE_pointcloud_to_mesh(Main *bmain, Depsgraph *depsgraph, Scene * /*scene*/, Object *ob)
{
BLI_assert(ob->type == OB_POINTCLOUD);
@@ -904,7 +903,7 @@ static Mesh *mesh_new_from_mesh(Object *object, Mesh *mesh)
{
/* While we could copy this into the new mesh,
* add the data to 'mesh' so future calls to this function don't need to re-convert the data. */
- if (mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
+ if (mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
BKE_mesh_wrapper_ensure_mdata(mesh);
}
else {
@@ -1134,11 +1133,11 @@ static void add_shapekey_layers(Mesh *mesh_dest, Mesh *mesh_src)
mesh_src->totvert,
kb->name,
kb->totelem);
- array = (float *)MEM_calloc_arrayN((size_t)mesh_src->totvert, sizeof(float[3]), __func__);
+ array = (float *)MEM_calloc_arrayN(size_t(mesh_src->totvert), sizeof(float[3]), __func__);
}
else {
- array = (float *)MEM_malloc_arrayN((size_t)mesh_src->totvert, sizeof(float[3]), __func__);
- memcpy(array, kb->data, sizeof(float[3]) * (size_t)mesh_src->totvert);
+ array = (float *)MEM_malloc_arrayN(size_t(mesh_src->totvert), sizeof(float[3]), __func__);
+ memcpy(array, kb->data, sizeof(float[3]) * size_t(mesh_src->totvert));
}
CustomData_add_layer_named(
@@ -1261,12 +1260,15 @@ static int find_object_active_key_uid(const Key &key, const Object &object)
return kb->uid;
}
-static void move_shapekey_layers_to_keyblocks(Mesh &mesh, Key &key_dst, const int actshape_uid)
+static void move_shapekey_layers_to_keyblocks(const Mesh &mesh,
+ CustomData &custom_data,
+ Key &key_dst,
+ const int actshape_uid)
{
using namespace blender::bke;
- for (const int i : IndexRange(CustomData_number_of_layers(&mesh.vdata, CD_SHAPEKEY))) {
- const int layer_index = CustomData_get_layer_index_n(&mesh.vdata, CD_SHAPEKEY, i);
- CustomDataLayer &layer = mesh.vdata.layers[layer_index];
+ for (const int i : IndexRange(CustomData_number_of_layers(&custom_data, CD_SHAPEKEY))) {
+ const int layer_index = CustomData_get_layer_index_n(&custom_data, CD_SHAPEKEY, i);
+ CustomDataLayer &layer = custom_data.layers[layer_index];
KeyBlock *kb = keyblock_ensure_from_uid(key_dst, layer.uid, layer.name);
MEM_SAFE_FREE(kb->data);
@@ -1287,10 +1289,10 @@ static void move_shapekey_layers_to_keyblocks(Mesh &mesh, Key &key_dst, const in
LISTBASE_FOREACH (KeyBlock *, kb, &key_dst.block) {
if (kb->totelem != mesh.totvert) {
MEM_SAFE_FREE(kb->data);
+ kb->totelem = mesh.totvert;
+ kb->data = MEM_cnew_array<float3>(kb->totelem, __func__);
+ CLOG_ERROR(&LOG, "Data for shape key '%s' on mesh missing from evaluated mesh ", kb->name);
}
- kb->totelem = mesh.totvert;
- kb->data = MEM_cnew_array<float3>(kb->totelem, __func__);
- CLOG_ERROR(&LOG, "Data for shape key '%s' on mesh missing from evaluated mesh ", kb->name);
}
}
@@ -1311,6 +1313,7 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
CustomData_duplicate_referenced_layers(&mesh_src->pdata, mesh_src->totpoly);
CustomData_duplicate_referenced_layers(&mesh_src->ldata, mesh_src->totloop);
+ const bool verts_num_changed = mesh_dst->totvert != mesh_src->totvert;
mesh_dst->totvert = mesh_src->totvert;
mesh_dst->totedge = mesh_src->totedge;
mesh_dst->totpoly = mesh_src->totpoly;
@@ -1328,7 +1331,6 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
BLI_listbase_clear(&mesh_src->vertex_group_names);
BKE_mesh_copy_parameters(mesh_dst, mesh_src);
- mesh_dst->cd_flag = mesh_src->cd_flag;
/* For original meshes, shape key data is stored in the #Key data-block, so it
* must be moved from the storage in #CustomData layers used for evaluation. */
@@ -1336,13 +1338,12 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
if (CustomData_has_layer(&mesh_src->vdata, CD_SHAPEKEY)) {
/* If no object, set to -1 so we don't mess up any shapekey layers. */
const int uid_active = ob ? find_object_active_key_uid(*key_dst, *ob) : -1;
- move_shapekey_layers_to_keyblocks(*mesh_src, *key_dst, uid_active);
+ move_shapekey_layers_to_keyblocks(*mesh_dst, mesh_src->vdata, *key_dst, uid_active);
}
- else if (mesh_src->totvert != mesh_dst->totvert) {
- CLOG_ERROR(&LOG, "Mesh in Main '%s' lost shape keys", mesh_src->id.name);
- if (mesh_src->key) {
- id_us_min(&mesh_src->key->id);
- }
+ else if (verts_num_changed) {
+ CLOG_WARN(&LOG, "Shape key data lost when replacing mesh '%s' in Main", mesh_src->id.name);
+ id_us_min(&mesh_dst->key->id);
+ mesh_dst->key = nullptr;
}
}
diff --git a/source/blender/blenkernel/intern/mesh_debug.cc b/source/blender/blenkernel/intern/mesh_debug.cc
index 8a9ce901923..6cf237a7c8c 100644
--- a/source/blender/blenkernel/intern/mesh_debug.cc
+++ b/source/blender/blenkernel/intern/mesh_debug.cc
@@ -27,21 +27,11 @@
# include "BLI_dynstr.h"
-static void mesh_debug_info_from_cd_flag(const Mesh *me, DynStr *dynstr)
-{
- BLI_dynstr_append(dynstr, "'cd_flag': {");
- if (me->cd_flag & ME_CDFLAG_EDGE_CREASE) {
- BLI_dynstr_append(dynstr, "'EDGE_CREASE', ");
- }
- BLI_dynstr_append(dynstr, "},\n");
-}
-
char *BKE_mesh_debug_info(const Mesh *me)
{
DynStr *dynstr = BLI_dynstr_new();
char *ret;
- const char *indent4 = " ";
const char *indent8 = " ";
BLI_dynstr_append(dynstr, "{\n");
@@ -51,9 +41,9 @@ char *BKE_mesh_debug_info(const Mesh *me)
BLI_dynstr_appendf(dynstr, " 'totface': %d,\n", me->totface);
BLI_dynstr_appendf(dynstr, " 'totpoly': %d,\n", me->totpoly);
- BLI_dynstr_appendf(dynstr, " 'runtime.deformed_only': %d,\n", me->runtime.deformed_only);
+ BLI_dynstr_appendf(dynstr, " 'runtime.deformed_only': %d,\n", me->runtime->deformed_only);
BLI_dynstr_appendf(
- dynstr, " 'runtime.is_original_bmesh': %d,\n", me->runtime.is_original_bmesh);
+ dynstr, " 'runtime->is_original_bmesh': %d,\n", me->runtime->is_original_bmesh);
BLI_dynstr_append(dynstr, " 'vert_layers': (\n");
CustomData_debug_info_from_layers(&me->vdata, indent8, dynstr);
@@ -75,9 +65,6 @@ char *BKE_mesh_debug_info(const Mesh *me)
CustomData_debug_info_from_layers(&me->fdata, indent8, dynstr);
BLI_dynstr_append(dynstr, " ),\n");
- BLI_dynstr_append(dynstr, indent4);
- mesh_debug_info_from_cd_flag(me, dynstr);
-
BLI_dynstr_append(dynstr, "}\n");
ret = BLI_dynstr_get_cstring(dynstr);
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc
index 938d7e42aa3..9a199c9c768 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.cc
+++ b/source/blender/blenkernel/intern/mesh_evaluate.cc
@@ -150,7 +150,7 @@ static void mesh_calc_ngon_center(const MPoly *mpoly,
const MVert *mvert,
float cent[3])
{
- const float w = 1.0f / (float)mpoly->totloop;
+ const float w = 1.0f / float(mpoly->totloop);
zero_v3(cent);
@@ -190,7 +190,7 @@ float BKE_mesh_calc_poly_area(const MPoly *mpoly, const MLoop *loopstart, const
}
const MLoop *l_iter = loopstart;
- float(*vertexcos)[3] = (float(*)[3])BLI_array_alloca(vertexcos, (size_t)mpoly->totloop);
+ float(*vertexcos)[3] = (float(*)[3])BLI_array_alloca(vertexcos, size_t(mpoly->totloop));
/* pack vertex cos into an array for area_poly_v3 */
for (int i = 0; i < mpoly->totloop; i++, l_iter++) {
@@ -198,7 +198,7 @@ float BKE_mesh_calc_poly_area(const MPoly *mpoly, const MLoop *loopstart, const
}
/* finally calculate the area */
- float area = area_poly_v3((const float(*)[3])vertexcos, (uint)mpoly->totloop);
+ float area = area_poly_v3((const float(*)[3])vertexcos, uint(mpoly->totloop));
return area;
}
@@ -221,7 +221,7 @@ float BKE_mesh_calc_poly_uv_area(const MPoly *mpoly, const MLoopUV *uv_array)
int i, l_iter = mpoly->loopstart;
float area;
- float(*vertexcos)[2] = (float(*)[2])BLI_array_alloca(vertexcos, (size_t)mpoly->totloop);
+ float(*vertexcos)[2] = (float(*)[2])BLI_array_alloca(vertexcos, size_t(mpoly->totloop));
/* pack vertex cos into an array for area_poly_v2 */
for (i = 0; i < mpoly->totloop; i++, l_iter++) {
@@ -229,7 +229,7 @@ float BKE_mesh_calc_poly_uv_area(const MPoly *mpoly, const MLoopUV *uv_array)
}
/* finally calculate the area */
- area = area_poly_v2(vertexcos, (uint)mpoly->totloop);
+ area = area_poly_v2(vertexcos, uint(mpoly->totloop));
return area;
}
@@ -407,7 +407,7 @@ bool BKE_mesh_center_median(const Mesh *me, float r_cent[3])
}
/* otherwise we get NAN for 0 verts */
if (me->totvert) {
- mul_v3_fl(r_cent, 1.0f / (float)me->totvert);
+ mul_v3_fl(r_cent, 1.0f / float(me->totvert));
}
return (me->totvert != 0);
}
@@ -428,7 +428,7 @@ bool BKE_mesh_center_median_from_polys(const Mesh *me, float r_cent[3])
}
/* otherwise we get NAN for 0 verts */
if (me->totpoly) {
- mul_v3_fl(r_cent, 1.0f / (float)tot);
+ mul_v3_fl(r_cent, 1.0f / float(tot));
}
return (me->totpoly != 0);
}
@@ -528,7 +528,7 @@ bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3])
* \{ */
static bool mesh_calc_center_centroid_ex(const MVert *mverts,
- int UNUSED(mverts_num),
+ int /*mverts_num*/,
const MLoopTri *looptri,
int looptri_num,
const MLoop *mloop,
@@ -638,7 +638,7 @@ void BKE_mesh_mdisp_flip(MDisps *md, const bool use_loop_mdisp_flip)
return;
}
- const int sides = (int)sqrt(md->totdisp);
+ const int sides = int(sqrt(md->totdisp));
float(*co)[3] = md->disps;
for (int x = 0; x < sides; x++) {
@@ -818,103 +818,88 @@ void BKE_mesh_flush_hidden_from_polys(Mesh *me)
hide_edge.finish();
}
-void BKE_mesh_flush_select_from_polys_ex(MVert *mvert,
- const int totvert,
- const MLoop *mloop,
- MEdge *medge,
- const int totedge,
- const MPoly *mpoly,
- const int totpoly)
+void BKE_mesh_flush_select_from_polys(Mesh *me)
{
- MVert *mv;
- MEdge *med;
- const MPoly *mp;
-
- int i = totvert;
- for (mv = mvert; i--; mv++) {
- mv->flag &= (char)~SELECT;
+ using namespace blender::bke;
+ MutableAttributeAccessor attributes = me->attributes_for_write();
+ const VArray<bool> select_poly = attributes.lookup_or_default<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE, false);
+ if (select_poly.is_single() && !select_poly.get_internal_single()) {
+ attributes.remove(".select_vert");
+ attributes.remove(".select_edge");
+ return;
}
+ SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT);
+ SpanAttributeWriter<bool> select_edge = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".select_edge", ATTR_DOMAIN_EDGE);
- i = totedge;
- for (med = medge; i--; med++) {
- med->flag &= ~SELECT;
- }
+ /* Use generic domain interpolation to read the polygon attribute on the other domains.
+ * Assume selected faces are not hidden and none of their vertices/edges are hidden. */
+ attributes.lookup_or_default<bool>(".select_poly", ATTR_DOMAIN_POINT, false)
+ .materialize(select_vert.span);
+ attributes.lookup_or_default<bool>(".select_poly", ATTR_DOMAIN_EDGE, false)
+ .materialize(select_edge.span);
- i = totpoly;
- for (mp = mpoly; i--; mp++) {
- /* Assume if its selected its not hidden and none of its verts/edges are hidden
- * (a common assumption). */
- if (mp->flag & ME_FACE_SEL) {
- const MLoop *ml;
- int j;
- j = mp->totloop;
- for (ml = &mloop[mp->loopstart]; j--; ml++) {
- mvert[ml->v].flag |= SELECT;
- medge[ml->e].flag |= SELECT;
- }
- }
- }
-}
-void BKE_mesh_flush_select_from_polys(Mesh *me)
-{
- BKE_mesh_flush_select_from_polys_ex(me->verts_for_write().data(),
- me->totvert,
- me->loops().data(),
- me->edges_for_write().data(),
- me->totedge,
- me->polys().data(),
- me->totpoly);
+ select_vert.finish();
+ select_edge.finish();
}
-static void mesh_flush_select_from_verts(const Span<MVert> verts,
+static void mesh_flush_select_from_verts(const Span<MEdge> edges,
+ const Span<MPoly> polys,
const Span<MLoop> loops,
const VArray<bool> &hide_edge,
const VArray<bool> &hide_poly,
- MutableSpan<MEdge> edges,
- MutableSpan<MPoly> polys)
+ const VArray<bool> &select_vert,
+ MutableSpan<bool> select_edge,
+ MutableSpan<bool> select_poly)
{
+ /* Select visible edges that have both of their vertices selected. */
for (const int i : edges.index_range()) {
if (!hide_edge[i]) {
- MEdge &edge = edges[i];
- if ((verts[edge.v1].flag & SELECT) && (verts[edge.v2].flag & SELECT)) {
- edge.flag |= SELECT;
- }
- else {
- edge.flag &= ~SELECT;
- }
+ const MEdge &edge = edges[i];
+ select_edge[i] = select_vert[edge.v1] && select_vert[edge.v2];
}
}
+ /* Select visible faces that have all of their vertices selected. */
for (const int i : polys.index_range()) {
- if (hide_poly[i]) {
- continue;
- }
- MPoly &poly = polys[i];
- bool all_verts_selected = true;
- for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
- if (!(verts[loop.v].flag & SELECT)) {
- all_verts_selected = false;
- }
- }
- if (all_verts_selected) {
- poly.flag |= ME_FACE_SEL;
- }
- else {
- poly.flag &= (char)~ME_FACE_SEL;
+ if (!hide_poly[i]) {
+ const MPoly &poly = polys[i];
+ const Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop);
+ select_poly[i] = std::all_of(poly_loops.begin(), poly_loops.end(), [&](const MLoop &loop) {
+ return select_vert[loop.v];
+ });
}
}
}
void BKE_mesh_flush_select_from_verts(Mesh *me)
{
- const blender::bke::AttributeAccessor attributes = me->attributes();
+ using namespace blender::bke;
+ MutableAttributeAccessor attributes = me->attributes_for_write();
+ const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+ if (select_vert.is_single() && !select_vert.get_internal_single()) {
+ attributes.remove(".select_edge");
+ attributes.remove(".select_poly");
+ return;
+ }
+ SpanAttributeWriter<bool> select_edge = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".select_edge", ATTR_DOMAIN_EDGE);
+ SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE);
mesh_flush_select_from_verts(
- me->verts(),
+ me->edges(),
+ me->polys(),
me->loops(),
attributes.lookup_or_default<bool>(".hide_edge", ATTR_DOMAIN_EDGE, false),
attributes.lookup_or_default<bool>(".hide_poly", ATTR_DOMAIN_FACE, false),
- me->edges_for_write(),
- me->polys_for_write());
+ select_vert,
+ select_edge.span,
+ select_poly.span);
+ select_edge.finish();
+ select_poly.finish();
}
/** \} */
@@ -937,9 +922,9 @@ void BKE_mesh_calc_relative_deform(const MPoly *mpoly,
const MPoly *mp;
int i;
- int *vert_accum = (int *)MEM_calloc_arrayN((size_t)totvert, sizeof(*vert_accum), __func__);
+ int *vert_accum = (int *)MEM_calloc_arrayN(size_t(totvert), sizeof(*vert_accum), __func__);
- memset(vert_cos_new, '\0', sizeof(*vert_cos_new) * (size_t)totvert);
+ memset(vert_cos_new, '\0', sizeof(*vert_cos_new) * size_t(totvert));
for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
const MLoop *loopstart = mloop + mp->loopstart;
@@ -967,7 +952,7 @@ void BKE_mesh_calc_relative_deform(const MPoly *mpoly,
for (i = 0; i < totvert; i++) {
if (vert_accum[i]) {
- mul_v3_fl(vert_cos_new[i], 1.0f / (float)vert_accum[i]);
+ mul_v3_fl(vert_cos_new[i], 1.0f / float(vert_accum[i]));
}
else {
copy_v3_v3(vert_cos_new[i], vert_cos_org[i]);
diff --git a/source/blender/blenkernel/intern/mesh_fair.cc b/source/blender/blenkernel/intern/mesh_fair.cc
index 41dcb3501cc..960e6c43103 100644
--- a/source/blender/blenkernel/intern/mesh_fair.cc
+++ b/source/blender/blenkernel/intern/mesh_fair.cc
@@ -26,6 +26,7 @@
#include "MEM_guardedalloc.h"
#include "eigen_capi.h"
+using blender::Array;
using blender::Map;
using blender::MutableSpan;
using blender::Span;
@@ -82,7 +83,7 @@ class FairingContext {
LoopWeight *loop_weight)
{
- fair_verts_ex(affected, (int)depth, vertex_weight, loop_weight);
+ fair_verts_ex(affected, int(depth), vertex_weight, loop_weight);
}
protected:
@@ -220,12 +221,7 @@ class MeshFairingContext : public FairingContext {
}
}
- loop_to_poly_map_.reserve(mesh->totloop);
- for (int i = 0; i < mesh->totpoly; i++) {
- for (int l = 0; l < mpoly_[i].totloop; l++) {
- loop_to_poly_map_[l + mpoly_[i].loopstart] = i;
- }
- }
+ loop_to_poly_map_ = blender::bke::mesh_topology::build_loop_to_poly_map(mpoly_, mloop_.size());
}
~MeshFairingContext() override
@@ -259,7 +255,7 @@ class MeshFairingContext : public FairingContext {
Span<MLoop> mloop_;
Span<MPoly> mpoly_;
Span<MEdge> medge_;
- Vector<int> loop_to_poly_map_;
+ Array<int> loop_to_poly_map_;
};
class BMeshFairingContext : public FairingContext {
@@ -444,7 +440,7 @@ class VoronoiVertexWeight : public VertexWeight {
class UniformLoopWeight : public LoopWeight {
public:
- float weight_at_index(const int UNUSED(index)) override
+ float weight_at_index(const int /*index*/) override
{
return 1.0f;
}
diff --git a/source/blender/blenkernel/intern/mesh_iterators.c b/source/blender/blenkernel/intern/mesh_iterators.cc
index d3a7f6cc72f..a99e9b2348d 100644
--- a/source/blender/blenkernel/intern/mesh_iterators.c
+++ b/source/blender/blenkernel/intern/mesh_iterators.cc
@@ -36,44 +36,44 @@ void BKE_mesh_foreach_mapped_vert(
void *userData,
MeshForeachFlag flag)
{
- if (mesh->edit_mesh != NULL && mesh->runtime.edit_data != NULL) {
+ if (mesh->edit_mesh != nullptr && mesh->runtime->edit_data != nullptr) {
BMEditMesh *em = mesh->edit_mesh;
BMesh *bm = em->bm;
BMIter iter;
BMVert *eve;
int i;
- if (mesh->runtime.edit_data->vertexCos != NULL) {
- const float(*vertexCos)[3] = mesh->runtime.edit_data->vertexCos;
+ if (mesh->runtime->edit_data->vertexCos != nullptr) {
+ const float(*vertexCos)[3] = mesh->runtime->edit_data->vertexCos;
const float(*vertexNos)[3];
if (flag & MESH_FOREACH_USE_NORMAL) {
- BKE_editmesh_cache_ensure_vert_normals(em, mesh->runtime.edit_data);
- vertexNos = mesh->runtime.edit_data->vertexNos;
+ BKE_editmesh_cache_ensure_vert_normals(em, mesh->runtime->edit_data);
+ vertexNos = mesh->runtime->edit_data->vertexNos;
}
else {
- vertexNos = NULL;
+ vertexNos = nullptr;
}
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
- const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? vertexNos[i] : NULL;
+ const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? vertexNos[i] : nullptr;
func(userData, i, vertexCos[i], no);
}
}
else {
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
- const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? eve->no : NULL;
+ const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? eve->no : nullptr;
func(userData, i, eve->co, no);
}
}
}
else {
const MVert *mv = BKE_mesh_verts(mesh);
- const int *index = CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX);
+ const int *index = static_cast<const int *>(CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX));
const float(*vert_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ?
BKE_mesh_vertex_normals_ensure(mesh) :
- NULL;
+ nullptr;
if (index) {
for (int i = 0; i < mesh->totvert; i++, mv++) {
- const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[i] : NULL;
+ const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[i] : nullptr;
const int orig = *index++;
if (orig == ORIGINDEX_NONE) {
continue;
@@ -83,7 +83,7 @@ void BKE_mesh_foreach_mapped_vert(
}
else {
for (int i = 0; i < mesh->totvert; i++, mv++) {
- const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[i] : NULL;
+ const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[i] : nullptr;
func(userData, i, mv->co, no);
}
}
@@ -96,14 +96,14 @@ void BKE_mesh_foreach_mapped_edge(
void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
void *userData)
{
- if (mesh->edit_mesh != NULL && mesh->runtime.edit_data) {
+ if (mesh->edit_mesh != nullptr && mesh->runtime->edit_data) {
BMEditMesh *em = mesh->edit_mesh;
BMesh *bm = em->bm;
BMIter iter;
BMEdge *eed;
int i;
- if (mesh->runtime.edit_data->vertexCos != NULL) {
- const float(*vertexCos)[3] = mesh->runtime.edit_data->vertexCos;
+ if (mesh->runtime->edit_data->vertexCos != nullptr) {
+ const float(*vertexCos)[3] = mesh->runtime->edit_data->vertexCos;
BM_mesh_elem_index_ensure(bm, BM_VERT);
BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
@@ -122,7 +122,7 @@ void BKE_mesh_foreach_mapped_edge(
else {
const MVert *mv = BKE_mesh_verts(mesh);
const MEdge *med = BKE_mesh_edges(mesh);
- const int *index = CustomData_get_layer(&mesh->edata, CD_ORIGINDEX);
+ const int *index = static_cast<const int *>(CustomData_get_layer(&mesh->edata, CD_ORIGINDEX));
if (index) {
for (int i = 0; i < mesh->totedge; i++, med++) {
@@ -151,21 +151,22 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh,
MeshForeachFlag flag)
{
- /* We can't use dm->getLoopDataLayout(dm) here,
- * we want to always access dm->loopData, EditDerivedBMesh would
- * return loop data from bmesh itself. */
- if (mesh->edit_mesh != NULL && mesh->runtime.edit_data) {
+ /* We can't use `dm->getLoopDataLayout(dm)` here,
+ * we want to always access `dm->loopData`, `EditDerivedBMesh` would
+ * return loop data from BMesh itself. */
+ if (mesh->edit_mesh != nullptr && mesh->runtime->edit_data) {
BMEditMesh *em = mesh->edit_mesh;
BMesh *bm = em->bm;
BMIter iter;
BMFace *efa;
- const float(*vertexCos)[3] = mesh->runtime.edit_data->vertexCos;
+ const float(*vertexCos)[3] = mesh->runtime->edit_data->vertexCos;
/* XXX: investigate using EditMesh data. */
const float(*lnors)[3] = (flag & MESH_FOREACH_USE_NORMAL) ?
- CustomData_get_layer(&mesh->ldata, CD_NORMAL) :
- NULL;
+ static_cast<const float(*)[3]>(
+ CustomData_get_layer(&mesh->ldata, CD_NORMAL)) :
+ nullptr;
int f_idx;
@@ -178,21 +179,24 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh,
do {
const BMVert *eve = l_iter->v;
const int v_idx = BM_elem_index_get(eve);
- const float *no = lnors ? *lnors++ : NULL;
+ const float *no = lnors ? *lnors++ : nullptr;
func(userData, v_idx, f_idx, vertexCos ? vertexCos[v_idx] : eve->co, no);
} while ((l_iter = l_iter->next) != l_first);
}
}
else {
const float(*lnors)[3] = (flag & MESH_FOREACH_USE_NORMAL) ?
- CustomData_get_layer(&mesh->ldata, CD_NORMAL) :
- NULL;
+ static_cast<const float(*)[3]>(
+ CustomData_get_layer(&mesh->ldata, CD_NORMAL)) :
+ nullptr;
const MVert *mv = BKE_mesh_verts(mesh);
const MLoop *ml = BKE_mesh_loops(mesh);
const MPoly *mp = BKE_mesh_polys(mesh);
- const int *v_index = CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX);
- const int *f_index = CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX);
+ const int *v_index = static_cast<const int *>(
+ CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX));
+ const int *f_index = static_cast<const int *>(
+ CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX));
int p_idx, i;
if (v_index || f_index) {
@@ -200,7 +204,7 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh,
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;
+ const float *no = lnors ? *lnors++ : nullptr;
if (ELEM(ORIGINDEX_NONE, v_idx, f_idx)) {
continue;
}
@@ -213,7 +217,7 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh,
for (i = 0; i < mp->totloop; i++, ml++) {
const int v_idx = ml->v;
const int f_idx = p_idx;
- const float *no = lnors ? *lnors++ : NULL;
+ const float *no = lnors ? *lnors++ : nullptr;
func(userData, v_idx, f_idx, mv[ml->v].co, no);
}
}
@@ -227,7 +231,7 @@ void BKE_mesh_foreach_mapped_face_center(
void *userData,
MeshForeachFlag flag)
{
- if (mesh->edit_mesh != NULL && mesh->runtime.edit_data != NULL) {
+ if (mesh->edit_mesh != nullptr && mesh->runtime->edit_data != nullptr) {
BMEditMesh *em = mesh->edit_mesh;
BMesh *bm = em->bm;
const float(*polyCos)[3];
@@ -236,15 +240,15 @@ void BKE_mesh_foreach_mapped_face_center(
BMIter iter;
int i;
- BKE_editmesh_cache_ensure_poly_centers(em, mesh->runtime.edit_data);
- polyCos = mesh->runtime.edit_data->polyCos; /* always set */
+ BKE_editmesh_cache_ensure_poly_centers(em, mesh->runtime->edit_data);
+ polyCos = mesh->runtime->edit_data->polyCos; /* always set */
if (flag & MESH_FOREACH_USE_NORMAL) {
- BKE_editmesh_cache_ensure_poly_normals(em, mesh->runtime.edit_data);
- polyNos = mesh->runtime.edit_data->polyNos; /* maybe NULL */
+ BKE_editmesh_cache_ensure_poly_normals(em, mesh->runtime->edit_data);
+ polyNos = mesh->runtime->edit_data->polyNos; /* maybe nullptr */
}
else {
- polyNos = NULL;
+ polyNos = nullptr;
}
if (polyNos) {
@@ -255,7 +259,7 @@ void BKE_mesh_foreach_mapped_face_center(
}
else {
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
- const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? efa->no : NULL;
+ const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? efa->no : nullptr;
func(userData, i, polyCos[i], no);
}
}
@@ -266,8 +270,8 @@ void BKE_mesh_foreach_mapped_face_center(
const MLoop *loops = BKE_mesh_loops(mesh);
const MLoop *ml;
float _no_buf[3];
- float *no = (flag & MESH_FOREACH_USE_NORMAL) ? _no_buf : NULL;
- const int *index = CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX);
+ float *no = (flag & MESH_FOREACH_USE_NORMAL) ? _no_buf : nullptr;
+ const int *index = static_cast<const int *>(CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX));
if (index) {
for (int i = 0; i < mesh->totpoly; i++, mp++) {
@@ -311,10 +315,10 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
const MVert *mv;
const float(*vert_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ?
BKE_mesh_vertex_normals_ensure(mesh) :
- NULL;
- const int *index = CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX);
- const BLI_bitmap *facedot_tags = mesh->runtime.subsurf_face_dot_tags;
- BLI_assert(facedot_tags != NULL);
+ nullptr;
+ const int *index = static_cast<const int *>(CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX));
+ const BLI_bitmap *facedot_tags = mesh->runtime->subsurf_face_dot_tags;
+ BLI_assert(facedot_tags != nullptr);
if (index) {
for (int i = 0; i < mesh->totpoly; i++, mp++) {
@@ -329,7 +333,7 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
func(userData,
orig,
mv->co,
- (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[ml->v] : NULL);
+ (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[ml->v] : nullptr);
}
}
}
@@ -340,7 +344,10 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
for (int j = 0; j < mp->totloop; j++, ml++) {
mv = &verts[ml->v];
if (BLI_BITMAP_TEST(facedot_tags, ml->v)) {
- func(userData, i, mv->co, (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[ml->v] : NULL);
+ func(userData,
+ i,
+ mv->co,
+ (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[ml->v] : nullptr);
}
}
}
@@ -349,15 +356,15 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
/* Helpers based on above foreach loopers> */
-typedef struct MappedVCosData {
+struct MappedVCosData {
float (*vertexcos)[3];
BLI_bitmap *vertex_visit;
-} MappedVCosData;
+};
static void get_vertexcos__mapFunc(void *user_data,
int index,
const float co[3],
- const float UNUSED(no[3]))
+ const float /*no*/[3])
{
MappedVCosData *mapped_vcos_data = (MappedVCosData *)user_data;
diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc
index 10fc8ff3195..23426f8c087 100644
--- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc
@@ -13,6 +13,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
#include "BLI_edgehash.h"
#include "BLI_math.h"
@@ -29,6 +30,258 @@
#include "BKE_multires.h"
/* -------------------------------------------------------------------- */
+/** \name Legacy Edge Calculation
+ * \{ */
+
+struct EdgeSort {
+ uint v1, v2;
+ char is_loose, is_draw;
+};
+
+/* edges have to be added with lowest index first for sorting */
+static void to_edgesort(struct EdgeSort *ed, uint v1, uint v2, char is_loose, short is_draw)
+{
+ if (v1 < v2) {
+ ed->v1 = v1;
+ ed->v2 = v2;
+ }
+ else {
+ ed->v1 = v2;
+ ed->v2 = v1;
+ }
+ ed->is_loose = is_loose;
+ ed->is_draw = is_draw;
+}
+
+static int vergedgesort(const void *v1, const void *v2)
+{
+ const struct EdgeSort *x1 = static_cast<const struct EdgeSort *>(v1);
+ const struct EdgeSort *x2 = static_cast<const struct EdgeSort *>(v2);
+
+ if (x1->v1 > x2->v1) {
+ return 1;
+ }
+ if (x1->v1 < x2->v1) {
+ return -1;
+ }
+ if (x1->v2 > x2->v2) {
+ return 1;
+ }
+ if (x1->v2 < x2->v2) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Create edges based on known verts and faces,
+ * this function is only used when loading very old blend files */
+static void mesh_calc_edges_mdata(const MVert * /*allvert*/,
+ const MFace *allface,
+ MLoop *allloop,
+ const MPoly *allpoly,
+ int /*totvert*/,
+ int totface,
+ int /*totloop*/,
+ int totpoly,
+ const bool use_old,
+ MEdge **r_medge,
+ int *r_totedge)
+{
+ const MPoly *mpoly;
+ const MFace *mface;
+ MEdge *medge, *med;
+ EdgeHash *hash;
+ struct EdgeSort *edsort, *ed;
+ int a, totedge = 0;
+ uint totedge_final = 0;
+ uint edge_index;
+
+ /* we put all edges in array, sort them, and detect doubles that way */
+
+ for (a = totface, mface = allface; a > 0; a--, mface++) {
+ if (mface->v4) {
+ totedge += 4;
+ }
+ else if (mface->v3) {
+ totedge += 3;
+ }
+ else {
+ totedge += 1;
+ }
+ }
+
+ if (totedge == 0) {
+ /* flag that mesh has edges */
+ (*r_medge) = (MEdge *)MEM_callocN(0, __func__);
+ (*r_totedge) = 0;
+ return;
+ }
+
+ ed = edsort = (EdgeSort *)MEM_mallocN(totedge * sizeof(struct EdgeSort), "EdgeSort");
+
+ for (a = totface, mface = allface; a > 0; a--, mface++) {
+ to_edgesort(ed++, mface->v1, mface->v2, !mface->v3, mface->edcode & ME_V1V2);
+ if (mface->v4) {
+ to_edgesort(ed++, mface->v2, mface->v3, 0, mface->edcode & ME_V2V3);
+ to_edgesort(ed++, mface->v3, mface->v4, 0, mface->edcode & ME_V3V4);
+ to_edgesort(ed++, mface->v4, mface->v1, 0, mface->edcode & ME_V4V1);
+ }
+ else if (mface->v3) {
+ to_edgesort(ed++, mface->v2, mface->v3, 0, mface->edcode & ME_V2V3);
+ to_edgesort(ed++, mface->v3, mface->v1, 0, mface->edcode & ME_V3V1);
+ }
+ }
+
+ qsort(edsort, totedge, sizeof(struct EdgeSort), vergedgesort);
+
+ /* count final amount */
+ for (a = totedge, ed = edsort; a > 1; a--, ed++) {
+ /* edge is unique when it differs from next edge, or is last */
+ if (ed->v1 != (ed + 1)->v1 || ed->v2 != (ed + 1)->v2) {
+ totedge_final++;
+ }
+ }
+ totedge_final++;
+
+ medge = (MEdge *)MEM_callocN(sizeof(MEdge) * totedge_final, __func__);
+
+ for (a = totedge, med = medge, ed = edsort; a > 1; a--, ed++) {
+ /* edge is unique when it differs from next edge, or is last */
+ if (ed->v1 != (ed + 1)->v1 || ed->v2 != (ed + 1)->v2) {
+ med->v1 = ed->v1;
+ med->v2 = ed->v2;
+ if (use_old == false || ed->is_draw) {
+ med->flag = ME_EDGEDRAW;
+ }
+ if (ed->is_loose) {
+ med->flag |= ME_LOOSEEDGE;
+ }
+
+ /* order is swapped so extruding this edge as a surface won't flip face normals
+ * with cyclic curves */
+ if (ed->v1 + 1 != ed->v2) {
+ SWAP(uint, med->v1, med->v2);
+ }
+ med++;
+ }
+ else {
+ /* Equal edge, merge the draw-flag. */
+ (ed + 1)->is_draw |= ed->is_draw;
+ }
+ }
+ /* last edge */
+ med->v1 = ed->v1;
+ med->v2 = ed->v2;
+ med->flag = ME_EDGEDRAW;
+ if (ed->is_loose) {
+ med->flag |= ME_LOOSEEDGE;
+ }
+
+ MEM_freeN(edsort);
+
+ /* set edge members of mloops */
+ hash = BLI_edgehash_new_ex(__func__, totedge_final);
+ for (edge_index = 0, med = medge; edge_index < totedge_final; edge_index++, med++) {
+ BLI_edgehash_insert(hash, med->v1, med->v2, POINTER_FROM_UINT(edge_index));
+ }
+
+ mpoly = allpoly;
+ for (a = 0; a < totpoly; a++, mpoly++) {
+ MLoop *ml, *ml_next;
+ int i = mpoly->totloop;
+
+ ml_next = allloop + mpoly->loopstart; /* first loop */
+ ml = &ml_next[i - 1]; /* last loop */
+
+ while (i-- != 0) {
+ ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(hash, ml->v, ml_next->v));
+ ml = ml_next;
+ ml_next++;
+ }
+ }
+
+ BLI_edgehash_free(hash, nullptr);
+
+ *r_medge = medge;
+ *r_totedge = totedge_final;
+}
+
+void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old)
+{
+ using namespace blender;
+ MEdge *medge;
+ int totedge = 0;
+ const Span<MVert> verts = me->verts();
+ const Span<MPoly> polys = me->polys();
+ MutableSpan<MLoop> loops = me->loops_for_write();
+
+ mesh_calc_edges_mdata(verts.data(),
+ (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
+ loops.data(),
+ polys.data(),
+ verts.size(),
+ me->totface,
+ loops.size(),
+ polys.size(),
+ use_old,
+ &medge,
+ &totedge);
+
+ if (totedge == 0) {
+ /* flag that mesh has edges */
+ me->totedge = 0;
+ return;
+ }
+
+ medge = (MEdge *)CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, totedge);
+ me->totedge = totedge;
+
+ BKE_mesh_strip_loose_faces(me);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name CD Flag Initialization
+ * \{ */
+
+void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh)
+{
+ using namespace blender;
+ if (UNLIKELY(mesh->cd_flag)) {
+ return;
+ }
+
+ const Span<MVert> verts = mesh->verts();
+ const Span<MEdge> edges = mesh->edges();
+
+ for (const MVert &vert : verts) {
+ if (vert.bweight_legacy != 0) {
+ mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
+ break;
+ }
+ }
+
+ for (const MEdge &edge : edges) {
+ if (edge.bweight_legacy != 0) {
+ mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
+ if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) {
+ break;
+ }
+ }
+ if (edge.crease_legacy != 0) {
+ mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
+ break;
+ }
+ }
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name NGon Tessellation (NGon to MFace Conversion)
* \{ */
@@ -109,24 +362,24 @@ static void bm_corners_to_loops_ex(ID *id,
BLI_assert(fd->totdisp == 0);
}
else {
- const int side = (int)sqrtf((float)(fd->totdisp / corners));
+ const int side = int(sqrtf(float(fd->totdisp / corners)));
const int side_sq = side * side;
for (int i = 0; i < tot; i++, disps += side_sq, ld++) {
ld->totdisp = side_sq;
- ld->level = (int)(logf((float)side - 1.0f) / (float)M_LN2) + 1;
+ ld->level = int(logf(float(side) - 1.0f) / float(M_LN2)) + 1;
if (ld->disps) {
MEM_freeN(ld->disps);
}
ld->disps = (float(*)[3])MEM_malloc_arrayN(
- (size_t)side_sq, sizeof(float[3]), "converted loop mdisps");
+ size_t(side_sq), sizeof(float[3]), "converted loop mdisps");
if (fd->disps) {
- memcpy(ld->disps, disps, (size_t)side_sq * sizeof(float[3]));
+ memcpy(ld->disps, disps, size_t(side_sq) * sizeof(float[3]));
}
else {
- memset(ld->disps, 0, (size_t)side_sq * sizeof(float[3]));
+ memset(ld->disps, 0, size_t(side_sq) * sizeof(float[3]));
}
}
}
@@ -211,7 +464,7 @@ static void convert_mfaces_to_mpolys(ID *id,
CustomData_external_read(fdata, id, CD_MASK_MDISPS, totface_i);
}
- eh = BLI_edgehash_new_ex(__func__, (uint)totedge_i);
+ eh = BLI_edgehash_new_ex(__func__, uint(totedge_i));
/* build edge hash */
me = medge;
@@ -277,6 +530,115 @@ static void convert_mfaces_to_mpolys(ID *id,
#undef ME_FGON
}
+static void update_active_fdata_layers(CustomData *fdata, CustomData *ldata)
+{
+ int act;
+
+ if (CustomData_has_layer(ldata, CD_MLOOPUV)) {
+ act = CustomData_get_active_layer(ldata, CD_MLOOPUV);
+ CustomData_set_layer_active(fdata, CD_MTFACE, act);
+
+ act = CustomData_get_render_layer(ldata, CD_MLOOPUV);
+ CustomData_set_layer_render(fdata, CD_MTFACE, act);
+
+ act = CustomData_get_clone_layer(ldata, CD_MLOOPUV);
+ CustomData_set_layer_clone(fdata, CD_MTFACE, act);
+
+ act = CustomData_get_stencil_layer(ldata, CD_MLOOPUV);
+ CustomData_set_layer_stencil(fdata, CD_MTFACE, act);
+ }
+
+ if (CustomData_has_layer(ldata, CD_PROP_BYTE_COLOR)) {
+ act = CustomData_get_active_layer(ldata, CD_PROP_BYTE_COLOR);
+ CustomData_set_layer_active(fdata, CD_MCOL, act);
+
+ act = CustomData_get_render_layer(ldata, CD_PROP_BYTE_COLOR);
+ CustomData_set_layer_render(fdata, CD_MCOL, act);
+
+ act = CustomData_get_clone_layer(ldata, CD_PROP_BYTE_COLOR);
+ CustomData_set_layer_clone(fdata, CD_MCOL, act);
+
+ act = CustomData_get_stencil_layer(ldata, CD_PROP_BYTE_COLOR);
+ CustomData_set_layer_stencil(fdata, CD_MCOL, act);
+ }
+}
+
+#ifndef NDEBUG
+/**
+ * Debug check, used to assert when we expect layers to be in/out of sync.
+ *
+ * \param fallback: Use when there are no layers to handle,
+ * since callers may expect success or failure.
+ */
+static bool check_matching_legacy_layer_counts(CustomData *fdata, CustomData *ldata, bool fallback)
+{
+ int a_num = 0, b_num = 0;
+# define LAYER_CMP(l_a, t_a, l_b, t_b) \
+ ((a_num += CustomData_number_of_layers(l_a, t_a)) == \
+ (b_num += CustomData_number_of_layers(l_b, t_b)))
+
+ if (!LAYER_CMP(ldata, CD_MLOOPUV, fdata, CD_MTFACE)) {
+ return false;
+ }
+ if (!LAYER_CMP(ldata, CD_PROP_BYTE_COLOR, fdata, CD_MCOL)) {
+ return false;
+ }
+ if (!LAYER_CMP(ldata, CD_PREVIEW_MLOOPCOL, fdata, CD_PREVIEW_MCOL)) {
+ return false;
+ }
+ if (!LAYER_CMP(ldata, CD_ORIGSPACE_MLOOP, fdata, CD_ORIGSPACE)) {
+ return false;
+ }
+ if (!LAYER_CMP(ldata, CD_NORMAL, fdata, CD_TESSLOOPNORMAL)) {
+ return false;
+ }
+ if (!LAYER_CMP(ldata, CD_TANGENT, fdata, CD_TANGENT)) {
+ return false;
+ }
+
+# undef LAYER_CMP
+
+ /* if no layers are on either CustomData's,
+ * then there was nothing to do... */
+ return a_num ? true : fallback;
+}
+#endif
+
+static void add_mface_layers(CustomData *fdata, CustomData *ldata, int total)
+{
+ /* avoid accumulating extra layers */
+ BLI_assert(!check_matching_legacy_layer_counts(fdata, ldata, false));
+
+ for (int i = 0; i < ldata->totlayer; i++) {
+ if (ldata->layers[i].type == CD_MLOOPUV) {
+ CustomData_add_layer_named(
+ fdata, CD_MTFACE, CD_SET_DEFAULT, nullptr, total, ldata->layers[i].name);
+ }
+ if (ldata->layers[i].type == CD_PROP_BYTE_COLOR) {
+ CustomData_add_layer_named(
+ fdata, CD_MCOL, CD_SET_DEFAULT, nullptr, total, ldata->layers[i].name);
+ }
+ else if (ldata->layers[i].type == CD_PREVIEW_MLOOPCOL) {
+ CustomData_add_layer_named(
+ fdata, CD_PREVIEW_MCOL, CD_SET_DEFAULT, nullptr, total, ldata->layers[i].name);
+ }
+ else if (ldata->layers[i].type == CD_ORIGSPACE_MLOOP) {
+ CustomData_add_layer_named(
+ fdata, CD_ORIGSPACE, CD_SET_DEFAULT, nullptr, total, ldata->layers[i].name);
+ }
+ else if (ldata->layers[i].type == CD_NORMAL) {
+ CustomData_add_layer_named(
+ fdata, CD_TESSLOOPNORMAL, CD_SET_DEFAULT, nullptr, total, ldata->layers[i].name);
+ }
+ else if (ldata->layers[i].type == CD_TANGENT) {
+ CustomData_add_layer_named(
+ fdata, CD_TANGENT, CD_SET_DEFAULT, nullptr, total, ldata->layers[i].name);
+ }
+ }
+
+ update_active_fdata_layers(fdata, ldata);
+}
+
static void mesh_ensure_tessellation_customdata(Mesh *me)
{
if (UNLIKELY((me->totface != 0) && (me->totpoly == 0))) {
@@ -295,7 +657,7 @@ static void mesh_ensure_tessellation_customdata(Mesh *me)
if (tottex_tessface != tottex_original || totcol_tessface != totcol_original) {
BKE_mesh_tessface_clear(me);
- BKE_mesh_add_mface_layers(&me->fdata, &me->ldata, me->totface);
+ add_mface_layers(&me->fdata, &me->ldata, me->totface);
/* TODO: add some `--debug-mesh` option. */
if (G.debug & G_DEBUG) {
@@ -608,15 +970,15 @@ static int mesh_tessface_calc(CustomData *fdata,
* if all faces are triangles it will be correct, `quads == 2x` allocations. */
/* Take care since memory is _not_ zeroed so be sure to initialize each field. */
mface_to_poly_map = (int *)MEM_malloc_arrayN(
- (size_t)looptri_num, sizeof(*mface_to_poly_map), __func__);
- mface = (MFace *)MEM_malloc_arrayN((size_t)looptri_num, sizeof(*mface), __func__);
- lindices = (uint(*)[4])MEM_malloc_arrayN((size_t)looptri_num, sizeof(*lindices), __func__);
+ size_t(looptri_num), sizeof(*mface_to_poly_map), __func__);
+ mface = (MFace *)MEM_malloc_arrayN(size_t(looptri_num), sizeof(*mface), __func__);
+ lindices = (uint(*)[4])MEM_malloc_arrayN(size_t(looptri_num), sizeof(*lindices), __func__);
mface_index = 0;
mp = mpoly;
for (poly_index = 0; poly_index < totpoly; poly_index++, mp++) {
- const uint mp_loopstart = (uint)mp->loopstart;
- const uint mp_totloop = (uint)mp->totloop;
+ const uint mp_loopstart = uint(mp->loopstart);
+ const uint mp_totloop = uint(mp->totloop);
uint l1, l2, l3, l4;
uint *lidx;
if (mp_totloop < 3) {
@@ -700,8 +1062,8 @@ static int mesh_tessface_calc(CustomData *fdata,
arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
}
- tris = (uint(*)[3])BLI_memarena_alloc(arena, sizeof(*tris) * (size_t)totfilltri);
- projverts = (float(*)[2])BLI_memarena_alloc(arena, sizeof(*projverts) * (size_t)mp_totloop);
+ tris = (uint(*)[3])BLI_memarena_alloc(arena, sizeof(*tris) * size_t(totfilltri));
+ projverts = (float(*)[2])BLI_memarena_alloc(arena, sizeof(*projverts) * size_t(mp_totloop));
zero_v3(normal);
@@ -773,9 +1135,9 @@ static int mesh_tessface_calc(CustomData *fdata,
/* Not essential but without this we store over-allocated memory in the #CustomData layers. */
if (LIKELY(looptri_num != totface)) {
- mface = (MFace *)MEM_reallocN(mface, sizeof(*mface) * (size_t)totface);
+ mface = (MFace *)MEM_reallocN(mface, sizeof(*mface) * size_t(totface));
mface_to_poly_map = (int *)MEM_reallocN(mface_to_poly_map,
- sizeof(*mface_to_poly_map) * (size_t)totface);
+ sizeof(*mface_to_poly_map) * size_t(totface));
}
CustomData_add_layer(fdata, CD_MFACE, CD_ASSIGN, mface, totface);
@@ -783,7 +1145,7 @@ static int mesh_tessface_calc(CustomData *fdata,
/* #CD_ORIGINDEX will contain an array of indices from tessellation-faces to the polygons
* they are directly tessellated from. */
CustomData_add_layer(fdata, CD_ORIGINDEX, CD_ASSIGN, mface_to_poly_map, totface);
- BKE_mesh_add_mface_layers(fdata, ldata, totface);
+ add_mface_layers(fdata, ldata, totface);
/* NOTE: quad detection issue - fourth vertidx vs fourth loopidx:
* Polygons take care of their loops ordering, hence not of their vertices ordering.
@@ -839,80 +1201,34 @@ void BKE_mesh_tessface_ensure(struct Mesh *mesh)
}
}
-#ifndef NDEBUG
-/**
- * Debug check, used to assert when we expect layers to be in/out of sync.
- *
- * \param fallback: Use when there are no layers to handle,
- * since callers may expect success or failure.
- */
-static bool check_matching_legacy_layer_counts(CustomData *fdata, CustomData *ldata, bool fallback)
-{
- int a_num = 0, b_num = 0;
-# define LAYER_CMP(l_a, t_a, l_b, t_b) \
- ((a_num += CustomData_number_of_layers(l_a, t_a)) == \
- (b_num += CustomData_number_of_layers(l_b, t_b)))
-
- if (!LAYER_CMP(ldata, CD_MLOOPUV, fdata, CD_MTFACE)) {
- return false;
- }
- if (!LAYER_CMP(ldata, CD_PROP_BYTE_COLOR, fdata, CD_MCOL)) {
- return false;
- }
- if (!LAYER_CMP(ldata, CD_PREVIEW_MLOOPCOL, fdata, CD_PREVIEW_MCOL)) {
- return false;
- }
- if (!LAYER_CMP(ldata, CD_ORIGSPACE_MLOOP, fdata, CD_ORIGSPACE)) {
- return false;
- }
- if (!LAYER_CMP(ldata, CD_NORMAL, fdata, CD_TESSLOOPNORMAL)) {
- return false;
- }
- if (!LAYER_CMP(ldata, CD_TANGENT, fdata, CD_TANGENT)) {
- return false;
- }
+/** \} */
-# undef LAYER_CMP
+/* -------------------------------------------------------------------- */
+/** \name Face Set Conversion
+ * \{ */
- /* if no layers are on either CustomData's,
- * then there was nothing to do... */
- return a_num ? true : fallback;
+void BKE_mesh_legacy_face_set_from_generic(Mesh *mesh,
+ blender::MutableSpan<CustomDataLayer> poly_layers)
+{
+ using namespace blender;
+ for (CustomDataLayer &layer : poly_layers) {
+ if (StringRef(layer.name) == ".sculpt_face_set") {
+ layer.type = CD_SCULPT_FACE_SETS;
+ }
+ }
+ CustomData_update_typemap(&mesh->pdata);
}
-#endif
-void BKE_mesh_add_mface_layers(CustomData *fdata, CustomData *ldata, int total)
+void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh)
{
- /* avoid accumulating extra layers */
- BLI_assert(!check_matching_legacy_layer_counts(fdata, ldata, false));
-
- for (int i = 0; i < ldata->totlayer; i++) {
- if (ldata->layers[i].type == CD_MLOOPUV) {
- CustomData_add_layer_named(
- fdata, CD_MTFACE, CD_SET_DEFAULT, nullptr, total, ldata->layers[i].name);
- }
- if (ldata->layers[i].type == CD_PROP_BYTE_COLOR) {
- CustomData_add_layer_named(
- fdata, CD_MCOL, CD_SET_DEFAULT, nullptr, total, ldata->layers[i].name);
- }
- else if (ldata->layers[i].type == CD_PREVIEW_MLOOPCOL) {
- CustomData_add_layer_named(
- fdata, CD_PREVIEW_MCOL, CD_SET_DEFAULT, nullptr, total, ldata->layers[i].name);
- }
- else if (ldata->layers[i].type == CD_ORIGSPACE_MLOOP) {
- CustomData_add_layer_named(
- fdata, CD_ORIGSPACE, CD_SET_DEFAULT, nullptr, total, ldata->layers[i].name);
- }
- else if (ldata->layers[i].type == CD_NORMAL) {
- CustomData_add_layer_named(
- fdata, CD_TESSLOOPNORMAL, CD_SET_DEFAULT, nullptr, total, ldata->layers[i].name);
- }
- else if (ldata->layers[i].type == CD_TANGENT) {
- CustomData_add_layer_named(
- fdata, CD_TANGENT, CD_SET_DEFAULT, nullptr, total, ldata->layers[i].name);
+ using namespace blender;
+ for (CustomDataLayer &layer : MutableSpan(mesh->pdata.layers, mesh->pdata.totlayer)) {
+ if (layer.type == CD_SCULPT_FACE_SETS) {
+ BLI_strncpy(layer.name, ".sculpt_face_set", sizeof(layer.name));
+ layer.type = CD_PROP_INT32;
}
}
-
- CustomData_bmesh_update_active_layers(fdata, ldata);
+ CustomData_update_typemap(&mesh->pdata);
}
/** \} */
@@ -929,13 +1245,13 @@ void BKE_mesh_legacy_bevel_weight_from_layers(Mesh *mesh)
CustomData_get_layer(&mesh->vdata, CD_BWEIGHT))) {
mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
for (const int i : verts.index_range()) {
- verts[i].bweight = std::clamp(weights[i], 0.0f, 1.0f) * 255.0f;
+ verts[i].bweight_legacy = std::clamp(weights[i], 0.0f, 1.0f) * 255.0f;
}
}
else {
mesh->cd_flag &= ~ME_CDFLAG_VERT_BWEIGHT;
for (const int i : verts.index_range()) {
- verts[i].bweight = 0;
+ verts[i].bweight_legacy = 0;
}
}
MutableSpan<MEdge> edges = mesh->edges_for_write();
@@ -943,13 +1259,13 @@ void BKE_mesh_legacy_bevel_weight_from_layers(Mesh *mesh)
CustomData_get_layer(&mesh->edata, CD_BWEIGHT))) {
mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
for (const int i : edges.index_range()) {
- edges[i].bweight = std::clamp(weights[i], 0.0f, 1.0f) * 255.0f;
+ edges[i].bweight_legacy = std::clamp(weights[i], 0.0f, 1.0f) * 255.0f;
}
}
else {
mesh->cd_flag &= ~ME_CDFLAG_EDGE_BWEIGHT;
for (const int i : edges.index_range()) {
- edges[i].bweight = 0;
+ edges[i].bweight_legacy = 0;
}
}
}
@@ -962,7 +1278,7 @@ void BKE_mesh_legacy_bevel_weight_to_layers(Mesh *mesh)
float *weights = static_cast<float *>(
CustomData_add_layer(&mesh->vdata, CD_BWEIGHT, CD_CONSTRUCT, nullptr, verts.size()));
for (const int i : verts.index_range()) {
- weights[i] = verts[i].bweight / 255.0f;
+ weights[i] = verts[i].bweight_legacy / 255.0f;
}
}
@@ -971,7 +1287,45 @@ void BKE_mesh_legacy_bevel_weight_to_layers(Mesh *mesh)
float *weights = static_cast<float *>(
CustomData_add_layer(&mesh->edata, CD_BWEIGHT, CD_CONSTRUCT, nullptr, edges.size()));
for (const int i : edges.index_range()) {
- weights[i] = edges[i].bweight / 255.0f;
+ weights[i] = edges[i].bweight_legacy / 255.0f;
+ }
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Edge Crease Conversion
+ * \{ */
+
+void BKE_mesh_legacy_edge_crease_from_layers(Mesh *mesh)
+{
+ using namespace blender;
+ MutableSpan<MEdge> edges = mesh->edges_for_write();
+ if (const float *creases = static_cast<const float *>(
+ CustomData_get_layer(&mesh->edata, CD_CREASE))) {
+ mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ for (const int i : edges.index_range()) {
+ edges[i].crease_legacy = std::clamp(creases[i], 0.0f, 1.0f) * 255.0f;
+ }
+ }
+ else {
+ mesh->cd_flag &= ~ME_CDFLAG_EDGE_CREASE;
+ for (const int i : edges.index_range()) {
+ edges[i].crease_legacy = 0;
+ }
+ }
+}
+
+void BKE_mesh_legacy_edge_crease_to_layers(Mesh *mesh)
+{
+ using namespace blender;
+ const Span<MEdge> edges = mesh->edges();
+ if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) {
+ float *creases = static_cast<float *>(
+ CustomData_add_layer(&mesh->edata, CD_CREASE, CD_CONSTRUCT, nullptr, edges.size()));
+ for (const int i : edges.index_range()) {
+ creases[i] = edges[i].crease_legacy / 255.0f;
}
}
}
@@ -993,7 +1347,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh)
".hide_vert", ATTR_DOMAIN_POINT, false);
threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
- SET_FLAG_FROM_TEST(verts[i].flag, hide_vert[i], ME_HIDE);
+ SET_FLAG_FROM_TEST(verts[i].flag_legacy, hide_vert[i], ME_HIDE);
}
});
@@ -1023,13 +1377,14 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
MutableAttributeAccessor attributes = mesh->attributes_for_write();
const Span<MVert> verts = mesh->verts();
- if (std::any_of(
- verts.begin(), verts.end(), [](const MVert &vert) { return vert.flag & ME_HIDE; })) {
+ if (std::any_of(verts.begin(), verts.end(), [](const MVert &vert) {
+ return vert.flag_legacy & ME_HIDE;
+ })) {
SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_only_span<bool>(
".hide_vert", ATTR_DOMAIN_POINT);
threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
- hide_vert.span[i] = verts[i].flag & ME_HIDE;
+ hide_vert.span[i] = verts[i].flag_legacy & ME_HIDE;
}
});
hide_vert.finish();
@@ -1063,6 +1418,7 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
}
/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Material Index Conversion
* \{ */
@@ -1077,7 +1433,7 @@ void BKE_mesh_legacy_convert_material_indices_to_mpoly(Mesh *mesh)
"material_index", ATTR_DOMAIN_FACE, 0);
threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
- polys[i].mat_nr = material_indices[i];
+ polys[i].mat_nr_legacy = material_indices[i];
}
});
}
@@ -1089,12 +1445,12 @@ void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh)
MutableAttributeAccessor attributes = mesh->attributes_for_write();
const Span<MPoly> polys = mesh->polys();
if (std::any_of(
- polys.begin(), polys.end(), [](const MPoly &poly) { return poly.mat_nr != 0; })) {
+ polys.begin(), polys.end(), [](const MPoly &poly) { return poly.mat_nr_legacy != 0; })) {
SpanAttributeWriter<int> material_indices = attributes.lookup_or_add_for_write_only_span<int>(
"material_index", ATTR_DOMAIN_FACE);
threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
- material_indices.span[i] = polys[i].mat_nr;
+ material_indices.span[i] = polys[i].mat_nr_legacy;
}
});
material_indices.finish();
@@ -1102,3 +1458,90 @@ void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Selection Attribute and Legacy Flag Conversion
+ * \{ */
+
+void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh)
+{
+ using namespace blender;
+ using namespace blender::bke;
+ const AttributeAccessor attributes = mesh->attributes();
+
+ MutableSpan<MVert> verts = mesh->verts_for_write();
+ const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+ threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ SET_FLAG_FROM_TEST(verts[i].flag_legacy, select_vert[i], SELECT);
+ }
+ });
+
+ MutableSpan<MEdge> edges = mesh->edges_for_write();
+ const VArray<bool> select_edge = attributes.lookup_or_default<bool>(
+ ".select_edge", ATTR_DOMAIN_EDGE, false);
+ threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ SET_FLAG_FROM_TEST(edges[i].flag, select_edge[i], SELECT);
+ }
+ });
+
+ MutableSpan<MPoly> polys = mesh->polys_for_write();
+ const VArray<bool> select_poly = attributes.lookup_or_default<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE, false);
+ threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ SET_FLAG_FROM_TEST(polys[i].flag, select_poly[i], ME_FACE_SEL);
+ }
+ });
+}
+
+void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh)
+{
+ using namespace blender;
+ using namespace blender::bke;
+ MutableAttributeAccessor attributes = mesh->attributes_for_write();
+
+ const Span<MVert> verts = mesh->verts();
+ if (std::any_of(verts.begin(), verts.end(), [](const MVert &vert) {
+ return vert.flag_legacy & SELECT;
+ })) {
+ SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT);
+ threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ select_vert.span[i] = (verts[i].flag_legacy & SELECT) != 0;
+ }
+ });
+ select_vert.finish();
+ }
+
+ const Span<MEdge> edges = mesh->edges();
+ if (std::any_of(
+ edges.begin(), edges.end(), [](const MEdge &edge) { return edge.flag & SELECT; })) {
+ SpanAttributeWriter<bool> select_edge = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".select_edge", ATTR_DOMAIN_EDGE);
+ threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ select_edge.span[i] = (edges[i].flag & SELECT) != 0;
+ }
+ });
+ select_edge.finish();
+ }
+
+ const Span<MPoly> polys = mesh->polys();
+ if (std::any_of(
+ polys.begin(), polys.end(), [](const MPoly &poly) { return poly.flag & ME_FACE_SEL; })) {
+ SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE);
+ threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ select_poly.span[i] = (polys[i].flag & ME_FACE_SEL) != 0;
+ }
+ });
+ select_poly.finish();
+ }
+}
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.cc
index f57effd49f4..ed4ae94da7f 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.cc
@@ -12,9 +12,11 @@
#include "DNA_meshdata_types.h"
#include "DNA_vec_types.h"
+#include "BLI_array.hh"
#include "BLI_bitmap.h"
#include "BLI_buffer.h"
#include "BLI_math.h"
+#include "BLI_task.hh"
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
@@ -30,6 +32,7 @@
/* ngon version wip, based on BM_uv_vert_map_create */
UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly,
const bool *hide_poly,
+ const bool *select_poly,
const MLoop *mloop,
const MLoopUV *mloopuv,
uint totpoly,
@@ -44,7 +47,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly,
uint a;
int i, totuv, nverts;
- bool *winding = NULL;
+ bool *winding = nullptr;
BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, 32);
totuv = 0;
@@ -52,42 +55,42 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly,
/* generate UvMapVert array */
mp = mpoly;
for (a = 0; a < totpoly; a++, mp++) {
- if (!selected || (!(hide_poly && hide_poly[a]) && (mp->flag & ME_FACE_SEL))) {
+ if (!selected || (!(hide_poly && hide_poly[a]) && (select_poly && select_poly[a]))) {
totuv += mp->totloop;
}
}
if (totuv == 0) {
- return NULL;
+ return nullptr;
}
vmap = (UvVertMap *)MEM_callocN(sizeof(*vmap), "UvVertMap");
- buf = vmap->buf = (UvMapVert *)MEM_callocN(sizeof(*vmap->buf) * (size_t)totuv, "UvMapVert");
+ buf = vmap->buf = (UvMapVert *)MEM_callocN(sizeof(*vmap->buf) * size_t(totuv), "UvMapVert");
vmap->vert = (UvMapVert **)MEM_callocN(sizeof(*vmap->vert) * totvert, "UvMapVert*");
if (use_winding) {
- winding = MEM_callocN(sizeof(*winding) * totpoly, "winding");
+ winding = static_cast<bool *>(MEM_callocN(sizeof(*winding) * totpoly, "winding"));
}
if (!vmap->vert || !vmap->buf) {
BKE_mesh_uv_vert_map_free(vmap);
- return NULL;
+ return nullptr;
}
mp = mpoly;
for (a = 0; a < totpoly; a++, mp++) {
- if (!selected || (!(hide_poly && hide_poly[a]) && (mp->flag & ME_FACE_SEL))) {
- float(*tf_uv)[2] = NULL;
+ if (!selected || (!(hide_poly && hide_poly[a]) && (select_poly && select_poly[a]))) {
+ float(*tf_uv)[2] = nullptr;
if (use_winding) {
- tf_uv = (float(*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, (size_t)mp->totloop);
+ tf_uv = (float(*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, size_t(mp->totloop));
}
nverts = mp->totloop;
for (i = 0; i < nverts; i++) {
- buf->loop_of_poly_index = (unsigned short)i;
+ buf->loop_of_poly_index = ushort(i);
buf->poly_index = a;
- buf->separate = 0;
+ buf->separate = false;
buf->next = vmap->vert[mloop[mp->loopstart + i].v];
vmap->vert[mloop[mp->loopstart + i].v] = buf;
@@ -99,14 +102,14 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly,
}
if (use_winding) {
- winding[a] = cross_poly_v2(tf_uv, (uint)nverts) > 0;
+ winding[a] = cross_poly_v2(tf_uv, uint(nverts)) > 0;
}
}
}
/* sort individual uvs for each vert */
for (a = 0; a < totvert; a++) {
- UvMapVert *newvlist = NULL, *vlist = vmap->vert[a];
+ UvMapVert *newvlist = nullptr, *vlist = vmap->vert[a];
UvMapVert *iterv, *v, *lastv, *next;
const float *uv, *uv2;
float uvdiff[2];
@@ -118,7 +121,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly,
newvlist = v;
uv = mloopuv[mpoly[v->poly_index].loopstart + v->loop_of_poly_index].uv;
- lastv = NULL;
+ lastv = nullptr;
iterv = vlist;
while (iterv) {
@@ -145,7 +148,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly,
iterv = next;
}
- newvlist->separate = 1;
+ newvlist->separate = true;
}
vmap->vert[a] = newvlist;
@@ -194,11 +197,12 @@ static void mesh_vert_poly_or_loop_map_create(MeshElemMap **r_map,
int totloop,
const bool do_loops)
{
- MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * (size_t)totvert, __func__);
+ MeshElemMap *map = MEM_cnew_array<MeshElemMap>(size_t(totvert), __func__);
int *indices, *index_iter;
int i, j;
- indices = index_iter = MEM_mallocN(sizeof(int) * (size_t)totloop, __func__);
+ indices = static_cast<int *>(MEM_mallocN(sizeof(int) * size_t(totloop), __func__));
+ index_iter = indices;
/* Count number of polys for each vertex */
for (i = 0; i < totpoly; i++) {
@@ -258,15 +262,15 @@ void BKE_mesh_vert_loop_map_create(MeshElemMap **r_map,
void BKE_mesh_vert_looptri_map_create(MeshElemMap **r_map,
int **r_mem,
- const MVert *UNUSED(mvert),
+ const MVert * /*mvert*/,
const int totvert,
const MLoopTri *mlooptri,
const int totlooptri,
const MLoop *mloop,
- const int UNUSED(totloop))
+ const int /*totloop*/)
{
- MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * (size_t)totvert, __func__);
- int *indices = MEM_mallocN(sizeof(int) * (size_t)totlooptri * 3, __func__);
+ MeshElemMap *map = MEM_cnew_array<MeshElemMap>(size_t(totvert), __func__);
+ int *indices = static_cast<int *>(MEM_mallocN(sizeof(int) * size_t(totlooptri) * 3, __func__));
int *index_step;
const MLoopTri *mlt;
int i;
@@ -303,8 +307,8 @@ void BKE_mesh_vert_looptri_map_create(MeshElemMap **r_map,
void BKE_mesh_vert_edge_map_create(
MeshElemMap **r_map, int **r_mem, const MEdge *medge, int totvert, int totedge)
{
- MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * (size_t)totvert, "vert-edge map");
- int *indices = MEM_mallocN(sizeof(int[2]) * (size_t)totedge, "vert-edge map mem");
+ MeshElemMap *map = MEM_cnew_array<MeshElemMap>(size_t(totvert), __func__);
+ int *indices = static_cast<int *>(MEM_mallocN(sizeof(int[2]) * size_t(totedge), __func__));
int *i_pt = indices;
int i;
@@ -342,8 +346,8 @@ void BKE_mesh_vert_edge_map_create(
void BKE_mesh_vert_edge_vert_map_create(
MeshElemMap **r_map, int **r_mem, const MEdge *medge, int totvert, int totedge)
{
- MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * (size_t)totvert, "vert-edge map");
- int *indices = MEM_mallocN(sizeof(int[2]) * (size_t)totedge, "vert-edge map mem");
+ MeshElemMap *map = MEM_cnew_array<MeshElemMap>(size_t(totvert), __func__);
+ int *indices = static_cast<int *>(MEM_mallocN(sizeof(int[2]) * size_t(totedge), __func__));
int *i_pt = indices;
int i;
@@ -367,8 +371,8 @@ void BKE_mesh_vert_edge_vert_map_create(
for (i = 0; i < totedge; i++) {
const uint v[2] = {medge[i].v1, medge[i].v2};
- map[v[0]].indices[map[v[0]].count] = (int)v[1];
- map[v[1]].indices[map[v[1]].count] = (int)v[0];
+ map[v[0]].indices[map[v[0]].count] = int(v[1]);
+ map[v[1]].indices[map[v[1]].count] = int(v[0]);
map[v[0]].count++;
map[v[1]].count++;
@@ -380,15 +384,15 @@ void BKE_mesh_vert_edge_vert_map_create(
void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map,
int **r_mem,
- const MEdge *UNUSED(medge),
+ const MEdge * /*medge*/,
const int totedge,
const MPoly *mpoly,
const int totpoly,
const MLoop *mloop,
const int totloop)
{
- MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * (size_t)totedge, "edge-poly map");
- int *indices = MEM_mallocN(sizeof(int) * (size_t)totloop * 2, "edge-poly map mem");
+ MeshElemMap *map = MEM_cnew_array<MeshElemMap>(size_t(totedge), __func__);
+ int *indices = static_cast<int *>(MEM_mallocN(sizeof(int) * size_t(totloop) * 2, __func__));
int *index_step;
const MPoly *mp;
int i;
@@ -433,15 +437,15 @@ void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map,
void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map,
int **r_mem,
- const MEdge *UNUSED(medge),
+ const MEdge * /*medge*/,
const int totedge,
const MPoly *mpoly,
const int totpoly,
const MLoop *mloop,
const int totloop)
{
- MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * (size_t)totedge, "edge-poly map");
- int *indices = MEM_mallocN(sizeof(int) * (size_t)totloop, "edge-poly map mem");
+ MeshElemMap *map = MEM_cnew_array<MeshElemMap>(size_t(totedge), __func__);
+ int *indices = static_cast<int *>(MEM_mallocN(sizeof(int) * size_t(totloop), __func__));
int *index_step;
const MPoly *mp;
int i;
@@ -485,8 +489,8 @@ void BKE_mesh_origindex_map_create(MeshElemMap **r_map,
const int *final_origindex,
const int totfinal)
{
- MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * (size_t)totsource, "poly-tessface map");
- int *indices = MEM_mallocN(sizeof(int) * (size_t)totfinal, "poly-tessface map mem");
+ MeshElemMap *map = MEM_cnew_array<MeshElemMap>(size_t(totsource), __func__);
+ int *indices = static_cast<int *>(MEM_mallocN(sizeof(int) * size_t(totfinal), __func__));
int *index_step;
int i;
@@ -527,8 +531,8 @@ void BKE_mesh_origindex_map_create_looptri(MeshElemMap **r_map,
const MLoopTri *looptri,
const int looptri_num)
{
- MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * (size_t)mpoly_num, "poly-tessface map");
- int *indices = MEM_mallocN(sizeof(int) * (size_t)looptri_num, "poly-tessface map mem");
+ MeshElemMap *map = MEM_cnew_array<MeshElemMap>(size_t(mpoly_num), __func__);
+ int *indices = static_cast<int *>(MEM_mallocN(sizeof(int) * size_t(looptri_num), __func__));
int *index_step;
int i;
@@ -549,6 +553,41 @@ void BKE_mesh_origindex_map_create_looptri(MeshElemMap **r_map,
*r_mem = indices;
}
+namespace blender::bke::mesh_topology {
+
+Array<int> build_loop_to_poly_map(const Span<MPoly> polys, const int loops_num)
+{
+ Array<int> map(loops_num);
+ threading::parallel_for(polys.index_range(), 1024, [&](IndexRange range) {
+ for (const int64_t poly_i : range) {
+ const MPoly &poly = polys[poly_i];
+ map.as_mutable_span().slice(poly.loopstart, poly.totloop).fill(int(poly_i));
+ }
+ });
+ return map;
+}
+
+Array<Vector<int>> build_vert_to_edge_map(const Span<MEdge> edges, const int verts_num)
+{
+ Array<Vector<int>> map(verts_num);
+ for (const int64_t i : edges.index_range()) {
+ map[edges[i].v1].append(int(i));
+ map[edges[i].v2].append(int(i));
+ }
+ return map;
+}
+
+Array<Vector<int>> build_vert_to_loop_map(const Span<MLoop> loops, const int verts_num)
+{
+ Array<Vector<int>> map(verts_num);
+ for (const int64_t i : loops.index_range()) {
+ map[loops[i].v].append(int(i));
+ }
+ return map;
+}
+
+} // namespace blender::bke::mesh_topology
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -559,13 +598,13 @@ void BKE_mesh_origindex_map_create_looptri(MeshElemMap **r_map,
/**
* Callback deciding whether the given poly/loop/edge define an island boundary or not.
*/
-typedef bool (*MeshRemap_CheckIslandBoundary)(const struct MPoly *mpoly,
- const struct MLoop *mloop,
- const struct MEdge *medge,
- const int edge_user_count,
- const struct MPoly *mpoly_array,
- const struct MeshElemMap *edge_poly_map,
- void *user_data);
+using MeshRemap_CheckIslandBoundary = bool (*)(const MPoly *mpoly,
+ const MLoop *mloop,
+ const MEdge *medge,
+ const int edge_user_count,
+ const MPoly *mpoly_array,
+ const MeshElemMap *edge_poly_map,
+ void *user_data);
static void poly_edge_loop_islands_calc(const MEdge *medge,
const int totedge,
@@ -585,7 +624,7 @@ static void poly_edge_loop_islands_calc(const MEdge *medge,
int *poly_groups;
int *poly_stack;
- BLI_bitmap *edge_borders = NULL;
+ BLI_bitmap *edge_borders = nullptr;
int num_edgeborders = 0;
int poly_prev = 0;
@@ -598,13 +637,13 @@ static void poly_edge_loop_islands_calc(const MEdge *medge,
bool group_id_overflow = false;
/* map vars */
- int *edge_poly_mem = NULL;
+ int *edge_poly_mem = nullptr;
if (totpoly == 0) {
*r_totgroup = 0;
- *r_poly_groups = NULL;
+ *r_poly_groups = nullptr;
if (r_edge_borders) {
- *r_edge_borders = NULL;
+ *r_edge_borders = nullptr;
*r_totedgeborder = 0;
}
return;
@@ -620,8 +659,8 @@ static void poly_edge_loop_islands_calc(const MEdge *medge,
&edge_poly_map, &edge_poly_mem, medge, totedge, mpoly, totpoly, mloop, totloop);
}
- poly_groups = MEM_callocN(sizeof(int) * (size_t)totpoly, __func__);
- poly_stack = MEM_mallocN(sizeof(int) * (size_t)totpoly, __func__);
+ poly_groups = static_cast<int *>(MEM_callocN(sizeof(int) * size_t(totpoly), __func__));
+ poly_stack = static_cast<int *>(MEM_mallocN(sizeof(int) * size_t(totpoly), __func__));
while (true) {
int poly;
@@ -659,7 +698,7 @@ static void poly_edge_loop_islands_calc(const MEdge *medge,
mp = &mpoly[poly];
for (ml = &mloop[mp->loopstart], j = mp->totloop; j--; ml++) {
/* loop over poly users */
- const int me_idx = (int)ml->e;
+ const int me_idx = int(ml->e);
const MEdge *me = &medge[me_idx];
const MeshElemMap *map_ele = &edge_poly_map[me_idx];
const int *p = map_ele->indices;
@@ -763,12 +802,12 @@ static void poly_edge_loop_islands_calc(const MEdge *medge,
}
static bool poly_is_island_boundary_smooth_cb(const MPoly *mp,
- const MLoop *UNUSED(ml),
+ const MLoop * /*ml*/,
const MEdge *me,
const int edge_user_count,
const MPoly *mpoly_array,
const MeshElemMap *edge_poly_map,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
/* Edge is sharp if one of its polys is flat, or edge itself is sharp,
* or edge is not used by exactly two polygons. */
@@ -791,7 +830,7 @@ int *BKE_mesh_calc_smoothgroups(const MEdge *medge,
int *r_totgroup,
const bool use_bitflags)
{
- int *poly_groups = NULL;
+ int *poly_groups = nullptr;
poly_edge_loop_islands_calc(medge,
totedge,
@@ -799,14 +838,14 @@ int *BKE_mesh_calc_smoothgroups(const MEdge *medge,
totpoly,
mloop,
totloop,
- NULL,
+ nullptr,
use_bitflags,
poly_is_island_boundary_smooth_cb,
- NULL,
+ nullptr,
&poly_groups,
r_totgroup,
- NULL,
- NULL);
+ nullptr,
+ nullptr);
return poly_groups;
}
@@ -821,7 +860,7 @@ void BKE_mesh_loop_islands_init(MeshIslandStore *island_store,
{
MemArena *mem = island_store->mem;
- if (mem == NULL) {
+ if (mem == nullptr) {
mem = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
island_store->mem = mem;
}
@@ -834,31 +873,31 @@ void BKE_mesh_loop_islands_init(MeshIslandStore *island_store,
island_store->item_type = item_type;
island_store->items_to_islands_num = items_num;
- island_store->items_to_islands = BLI_memarena_alloc(
- mem, sizeof(*island_store->items_to_islands) * (size_t)items_num);
+ island_store->items_to_islands = static_cast<int *>(
+ BLI_memarena_alloc(mem, sizeof(*island_store->items_to_islands) * size_t(items_num)));
island_store->island_type = island_type;
island_store->islands_num_alloc = MISLAND_DEFAULT_BUFSIZE;
- island_store->islands = BLI_memarena_alloc(
- mem, sizeof(*island_store->islands) * island_store->islands_num_alloc);
+ island_store->islands = static_cast<MeshElemMap **>(
+ BLI_memarena_alloc(mem, sizeof(*island_store->islands) * island_store->islands_num_alloc));
island_store->innercut_type = innercut_type;
- island_store->innercuts = BLI_memarena_alloc(
- mem, sizeof(*island_store->innercuts) * island_store->islands_num_alloc);
+ island_store->innercuts = static_cast<MeshElemMap **>(
+ BLI_memarena_alloc(mem, sizeof(*island_store->innercuts) * island_store->islands_num_alloc));
}
void BKE_mesh_loop_islands_clear(MeshIslandStore *island_store)
{
island_store->item_type = MISLAND_TYPE_NONE;
island_store->items_to_islands_num = 0;
- island_store->items_to_islands = NULL;
+ island_store->items_to_islands = nullptr;
island_store->island_type = MISLAND_TYPE_NONE;
island_store->islands_num = 0;
- island_store->islands = NULL;
+ island_store->islands = nullptr;
island_store->innercut_type = MISLAND_TYPE_NONE;
- island_store->innercuts = NULL;
+ island_store->innercuts = nullptr;
if (island_store->mem) {
BLI_memarena_clear(island_store->mem);
@@ -871,7 +910,7 @@ void BKE_mesh_loop_islands_free(MeshIslandStore *island_store)
{
if (island_store->mem) {
BLI_memarena_free(island_store->mem);
- island_store->mem = NULL;
+ island_store->mem = nullptr;
}
}
@@ -887,7 +926,7 @@ void BKE_mesh_loop_islands_add(MeshIslandStore *island_store,
MeshElemMap *isld, *innrcut;
const int curr_island_idx = island_store->islands_num++;
- const size_t curr_num_islands = (size_t)island_store->islands_num;
+ const size_t curr_num_islands = size_t(island_store->islands_num);
int i = item_num;
while (i--) {
@@ -898,27 +937,32 @@ void BKE_mesh_loop_islands_add(MeshIslandStore *island_store,
MeshElemMap **islds, **innrcuts;
island_store->islands_num_alloc *= 2;
- islds = BLI_memarena_alloc(mem, sizeof(*islds) * island_store->islands_num_alloc);
+ islds = static_cast<MeshElemMap **>(
+ BLI_memarena_alloc(mem, sizeof(*islds) * island_store->islands_num_alloc));
memcpy(islds, island_store->islands, sizeof(*islds) * (curr_num_islands - 1));
island_store->islands = islds;
- innrcuts = BLI_memarena_alloc(mem, sizeof(*innrcuts) * island_store->islands_num_alloc);
+ innrcuts = static_cast<MeshElemMap **>(
+ BLI_memarena_alloc(mem, sizeof(*innrcuts) * island_store->islands_num_alloc));
memcpy(innrcuts, island_store->innercuts, sizeof(*innrcuts) * (curr_num_islands - 1));
island_store->innercuts = innrcuts;
}
- island_store->islands[curr_island_idx] = isld = BLI_memarena_alloc(mem, sizeof(*isld));
+ island_store->islands[curr_island_idx] = isld = static_cast<MeshElemMap *>(
+ BLI_memarena_alloc(mem, sizeof(*isld)));
isld->count = num_island_items;
- isld->indices = BLI_memarena_alloc(mem, sizeof(*isld->indices) * (size_t)num_island_items);
- memcpy(isld->indices, island_item_indices, sizeof(*isld->indices) * (size_t)num_island_items);
+ isld->indices = static_cast<int *>(
+ BLI_memarena_alloc(mem, sizeof(*isld->indices) * size_t(num_island_items)));
+ memcpy(isld->indices, island_item_indices, sizeof(*isld->indices) * size_t(num_island_items));
- island_store->innercuts[curr_island_idx] = innrcut = BLI_memarena_alloc(mem, sizeof(*innrcut));
+ island_store->innercuts[curr_island_idx] = innrcut = static_cast<MeshElemMap *>(
+ BLI_memarena_alloc(mem, sizeof(*innrcut)));
innrcut->count = num_innercut_items;
- innrcut->indices = BLI_memarena_alloc(mem,
- sizeof(*innrcut->indices) * (size_t)num_innercut_items);
+ innrcut->indices = static_cast<int *>(
+ BLI_memarena_alloc(mem, sizeof(*innrcut->indices) * size_t(num_innercut_items)));
memcpy(innrcut->indices,
innercut_item_indices,
- sizeof(*innrcut->indices) * (size_t)num_innercut_items);
+ sizeof(*innrcut->indices) * size_t(num_innercut_items));
}
/* TODO: I'm not sure edge seam flag is enough to define UV islands?
@@ -927,22 +971,23 @@ void BKE_mesh_loop_islands_add(MeshIslandStore *island_store,
* Would make things much more complex though,
* and each UVMap would then need its own mesh mapping, not sure we want that at all!
*/
-typedef struct MeshCheckIslandBoundaryUv {
+struct MeshCheckIslandBoundaryUv {
const MLoop *loops;
const MLoopUV *luvs;
const MeshElemMap *edge_loop_map;
-} MeshCheckIslandBoundaryUv;
+};
-static bool mesh_check_island_boundary_uv(const MPoly *UNUSED(mp),
+static bool mesh_check_island_boundary_uv(const MPoly * /*mp*/,
const MLoop *ml,
const MEdge *me,
- const int UNUSED(edge_user_count),
- const MPoly *UNUSED(mpoly_array),
- const MeshElemMap *UNUSED(edge_poly_map),
+ const int /*edge_user_count*/,
+ const MPoly * /*mpoly_array*/,
+ const MeshElemMap * /*edge_poly_map*/,
void *user_data)
{
if (user_data) {
- const MeshCheckIslandBoundaryUv *data = user_data;
+ const MeshCheckIslandBoundaryUv *data = static_cast<const MeshCheckIslandBoundaryUv *>(
+ user_data);
const MLoop *loops = data->loops;
const MLoopUV *luvs = data->luvs;
const MeshElemMap *edge_to_loops = &data->edge_loop_map[ml->e];
@@ -976,8 +1021,8 @@ static bool mesh_check_island_boundary_uv(const MPoly *UNUSED(mp),
return (me->flag & ME_SEAM) != 0;
}
-static bool mesh_calc_islands_loop_poly_uv(const MVert *UNUSED(verts),
- const int UNUSED(totvert),
+static bool mesh_calc_islands_loop_poly_uv(const MVert * /*verts*/,
+ const int /*totvert*/,
const MEdge *edges,
const int totedge,
const MPoly *polys,
@@ -987,7 +1032,7 @@ static bool mesh_calc_islands_loop_poly_uv(const MVert *UNUSED(verts),
const MLoopUV *luvs,
MeshIslandStore *r_island_store)
{
- int *poly_groups = NULL;
+ int *poly_groups = nullptr;
int num_poly_groups;
/* map vars */
@@ -1006,10 +1051,10 @@ static bool mesh_calc_islands_loop_poly_uv(const MVert *UNUSED(verts),
/* Those are used to detect 'inner cuts', i.e. edges that are borders,
* and yet have two or more polys of a same group using them
* (typical case: seam used to unwrap properly a cylinder). */
- BLI_bitmap *edge_borders = NULL;
+ BLI_bitmap *edge_borders = nullptr;
int num_edge_borders = 0;
- char *edge_border_count = NULL;
- int *edge_innercut_indices = NULL;
+ char *edge_border_count = nullptr;
+ int *edge_innercut_indices = nullptr;
int num_einnercuts = 0;
int grp_idx, p_idx, pl_idx, l_idx;
@@ -1038,7 +1083,7 @@ static bool mesh_calc_islands_loop_poly_uv(const MVert *UNUSED(verts),
edge_poly_map,
false,
mesh_check_island_boundary_uv,
- luvs ? &edge_boundary_check_data : NULL,
+ luvs ? &edge_boundary_check_data : nullptr,
&poly_groups,
&num_poly_groups,
&edge_borders,
@@ -1056,20 +1101,23 @@ static bool mesh_calc_islands_loop_poly_uv(const MVert *UNUSED(verts),
}
if (num_edge_borders) {
- edge_border_count = MEM_mallocN(sizeof(*edge_border_count) * (size_t)totedge, __func__);
- edge_innercut_indices = MEM_mallocN(sizeof(*edge_innercut_indices) * (size_t)num_edge_borders,
- __func__);
+ edge_border_count = static_cast<char *>(
+ MEM_mallocN(sizeof(*edge_border_count) * size_t(totedge), __func__));
+ edge_innercut_indices = static_cast<int *>(
+ MEM_mallocN(sizeof(*edge_innercut_indices) * size_t(num_edge_borders), __func__));
}
- poly_indices = MEM_mallocN(sizeof(*poly_indices) * (size_t)totpoly, __func__);
- loop_indices = MEM_mallocN(sizeof(*loop_indices) * (size_t)totloop, __func__);
+ poly_indices = static_cast<int *>(
+ MEM_mallocN(sizeof(*poly_indices) * size_t(totpoly), __func__));
+ loop_indices = static_cast<int *>(
+ MEM_mallocN(sizeof(*loop_indices) * size_t(totloop), __func__));
/* NOTE: here we ignore '0' invalid group - this should *never* happen in this case anyway? */
for (grp_idx = 1; grp_idx <= num_poly_groups; grp_idx++) {
num_pidx = num_lidx = 0;
if (num_edge_borders) {
num_einnercuts = 0;
- memset(edge_border_count, 0, sizeof(*edge_border_count) * (size_t)totedge);
+ memset(edge_border_count, 0, sizeof(*edge_border_count) * size_t(totedge));
}
for (p_idx = 0; p_idx < totpoly; p_idx++) {
@@ -1085,7 +1133,7 @@ static bool mesh_calc_islands_loop_poly_uv(const MVert *UNUSED(verts),
(edge_border_count[ml->e] < 2)) {
edge_border_count[ml->e]++;
if (edge_border_count[ml->e] == 2) {
- edge_innercut_indices[num_einnercuts++] = (int)ml->e;
+ edge_innercut_indices[num_einnercuts++] = int(ml->e);
}
}
}
@@ -1134,7 +1182,7 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const MVert *verts,
MeshIslandStore *r_island_store)
{
return mesh_calc_islands_loop_poly_uv(
- verts, totvert, edges, totedge, polys, totpoly, loops, totloop, NULL, r_island_store);
+ verts, totvert, edges, totedge, polys, totpoly, loops, totloop, nullptr, r_island_store);
}
bool BKE_mesh_calc_islands_loop_poly_uvmap(MVert *verts,
@@ -1148,7 +1196,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(MVert *verts,
const MLoopUV *luvs,
MeshIslandStore *r_island_store)
{
- BLI_assert(luvs != NULL);
+ BLI_assert(luvs != nullptr);
return mesh_calc_islands_loop_poly_uv(
verts, totvert, edges, totedge, polys, totpoly, loops, totloop, luvs, r_island_store);
}
diff --git a/source/blender/blenkernel/intern/mesh_merge_customdata.cc b/source/blender/blenkernel/intern/mesh_merge_customdata.cc
index f7936d8a4da..2c500f4d972 100644
--- a/source/blender/blenkernel/intern/mesh_merge_customdata.cc
+++ b/source/blender/blenkernel/intern/mesh_merge_customdata.cc
@@ -69,7 +69,7 @@ static void merge_uvs_for_vertex(const Span<int> loops_for_vert, Span<MLoopUV *>
BLI_assert(loops_merge.is_empty());
loops_merge.extend_unchecked(loops_for_vert);
while (loops_merge.size() > 1) {
- uint i_last = (uint)loops_merge.size() - 1;
+ uint i_last = uint(loops_merge.size()) - 1;
const float *uv_src = mloopuv[loops_merge[0]].uv;
for (uint i = 1; i <= i_last;) {
float *uv_dst = mloopuv[loops_merge[i]].uv;
diff --git a/source/blender/blenkernel/intern/mesh_mirror.c b/source/blender/blenkernel/intern/mesh_mirror.c
index 261bc3d150b..ce3fc5d99c8 100644
--- a/source/blender/blenkernel/intern/mesh_mirror.c
+++ b/source/blender/blenkernel/intern/mesh_mirror.c
@@ -152,8 +152,8 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
/* tmp is a transform from coords relative to the object's own origin,
* to coords relative to the mirror object origin */
- invert_m4_m4(tmp, mirror_ob->obmat);
- mul_m4_m4m4(tmp, tmp, ob->obmat);
+ invert_m4_m4(tmp, mirror_ob->object_to_world);
+ mul_m4_m4m4(tmp, tmp, ob->object_to_world);
/* itmp is the reverse transform back to origin-relative coordinates */
invert_m4_m4(itmp, tmp);
@@ -169,9 +169,9 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
/* Account for non-uniform scale in `ob`, see: T87592. */
float ob_scale[3] = {
- len_squared_v3(ob->obmat[0]),
- len_squared_v3(ob->obmat[1]),
- len_squared_v3(ob->obmat[2]),
+ len_squared_v3(ob->object_to_world[0]),
+ len_squared_v3(ob->object_to_world[1]),
+ len_squared_v3(ob->object_to_world[2]),
};
/* Scale to avoid precision loss with extreme values. */
const float ob_scale_max = max_fff(UNPACK3(ob_scale));
diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc
index 21dd39586ec..ebb5a72d137 100644
--- a/source/blender/blenkernel/intern/mesh_normals.cc
+++ b/source/blender/blenkernel/intern/mesh_normals.cc
@@ -95,72 +95,72 @@ static void add_v3_v3_atomic(float r[3], const float a[3])
void BKE_mesh_normals_tag_dirty(Mesh *mesh)
{
- mesh->runtime.vert_normals_dirty = true;
- mesh->runtime.poly_normals_dirty = true;
+ mesh->runtime->vert_normals_dirty = true;
+ mesh->runtime->poly_normals_dirty = true;
}
float (*BKE_mesh_vertex_normals_for_write(Mesh *mesh))[3]
{
- if (mesh->runtime.vert_normals == nullptr) {
- mesh->runtime.vert_normals = (float(*)[3])MEM_malloc_arrayN(
+ if (mesh->runtime->vert_normals == nullptr) {
+ mesh->runtime->vert_normals = (float(*)[3])MEM_malloc_arrayN(
mesh->totvert, sizeof(float[3]), __func__);
}
- BLI_assert(MEM_allocN_len(mesh->runtime.vert_normals) >= sizeof(float[3]) * mesh->totvert);
+ BLI_assert(MEM_allocN_len(mesh->runtime->vert_normals) >= sizeof(float[3]) * mesh->totvert);
- return mesh->runtime.vert_normals;
+ return mesh->runtime->vert_normals;
}
float (*BKE_mesh_poly_normals_for_write(Mesh *mesh))[3]
{
- if (mesh->runtime.poly_normals == nullptr) {
- mesh->runtime.poly_normals = (float(*)[3])MEM_malloc_arrayN(
+ if (mesh->runtime->poly_normals == nullptr) {
+ mesh->runtime->poly_normals = (float(*)[3])MEM_malloc_arrayN(
mesh->totpoly, sizeof(float[3]), __func__);
}
- BLI_assert(MEM_allocN_len(mesh->runtime.poly_normals) >= sizeof(float[3]) * mesh->totpoly);
+ BLI_assert(MEM_allocN_len(mesh->runtime->poly_normals) >= sizeof(float[3]) * mesh->totpoly);
- return mesh->runtime.poly_normals;
+ return mesh->runtime->poly_normals;
}
void BKE_mesh_vertex_normals_clear_dirty(Mesh *mesh)
{
- mesh->runtime.vert_normals_dirty = false;
+ mesh->runtime->vert_normals_dirty = false;
BKE_mesh_assert_normals_dirty_or_calculated(mesh);
}
void BKE_mesh_poly_normals_clear_dirty(Mesh *mesh)
{
- mesh->runtime.poly_normals_dirty = false;
+ mesh->runtime->poly_normals_dirty = false;
BKE_mesh_assert_normals_dirty_or_calculated(mesh);
}
bool BKE_mesh_vertex_normals_are_dirty(const Mesh *mesh)
{
- return mesh->runtime.vert_normals_dirty;
+ return mesh->runtime->vert_normals_dirty;
}
bool BKE_mesh_poly_normals_are_dirty(const Mesh *mesh)
{
- return mesh->runtime.poly_normals_dirty;
+ return mesh->runtime->poly_normals_dirty;
}
void BKE_mesh_clear_derived_normals(Mesh *mesh)
{
- MEM_SAFE_FREE(mesh->runtime.vert_normals);
- MEM_SAFE_FREE(mesh->runtime.poly_normals);
+ MEM_SAFE_FREE(mesh->runtime->vert_normals);
+ MEM_SAFE_FREE(mesh->runtime->poly_normals);
- mesh->runtime.vert_normals_dirty = true;
- mesh->runtime.poly_normals_dirty = true;
+ mesh->runtime->vert_normals_dirty = true;
+ mesh->runtime->poly_normals_dirty = true;
}
void BKE_mesh_assert_normals_dirty_or_calculated(const Mesh *mesh)
{
- if (!mesh->runtime.vert_normals_dirty) {
- BLI_assert(mesh->runtime.vert_normals || mesh->totvert == 0);
+ if (!mesh->runtime->vert_normals_dirty) {
+ BLI_assert(mesh->runtime->vert_normals || mesh->totvert == 0);
}
- if (!mesh->runtime.poly_normals_dirty) {
- BLI_assert(mesh->runtime.poly_normals || mesh->totpoly == 0);
+ if (!mesh->runtime->poly_normals_dirty) {
+ BLI_assert(mesh->runtime->poly_normals || mesh->totpoly == 0);
}
}
@@ -181,7 +181,7 @@ struct MeshCalcNormalsData_Poly {
static void mesh_calc_normals_poly_fn(void *__restrict userdata,
const int pidx,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
const MeshCalcNormalsData_Poly *data = (MeshCalcNormalsData_Poly *)userdata;
const MPoly *mp = &data->mpoly[pidx];
@@ -189,9 +189,9 @@ static void mesh_calc_normals_poly_fn(void *__restrict userdata,
}
void BKE_mesh_calc_normals_poly(const MVert *mvert,
- int UNUSED(mvert_len),
+ int /*mvert_len*/,
const MLoop *mloop,
- int UNUSED(mloop_len),
+ int /*mloop_len*/,
const MPoly *mpoly,
int mpoly_len,
float (*r_poly_normals)[3])
@@ -231,8 +231,9 @@ struct MeshCalcNormalsData_PolyAndVertex {
float (*vnors)[3];
};
-static void mesh_calc_normals_poly_and_vertex_accum_fn(
- void *__restrict userdata, const int pidx, const TaskParallelTLS *__restrict UNUSED(tls))
+static void mesh_calc_normals_poly_and_vertex_accum_fn(void *__restrict userdata,
+ const int pidx,
+ const TaskParallelTLS *__restrict /*tls*/)
{
const MeshCalcNormalsData_PolyAndVertex *data = (MeshCalcNormalsData_PolyAndVertex *)userdata;
const MPoly *mp = &data->mpoly[pidx];
@@ -294,7 +295,7 @@ static void mesh_calc_normals_poly_and_vertex_accum_fn(
}
static void mesh_calc_normals_poly_and_vertex_finalize_fn(
- void *__restrict userdata, const int vidx, const TaskParallelTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int vidx, const TaskParallelTLS *__restrict /*tls*/)
{
MeshCalcNormalsData_PolyAndVertex *data = (MeshCalcNormalsData_PolyAndVertex *)userdata;
@@ -310,7 +311,7 @@ static void mesh_calc_normals_poly_and_vertex_finalize_fn(
void BKE_mesh_calc_normals_poly_and_vertex(const MVert *mvert,
const int mvert_len,
const MLoop *mloop,
- const int UNUSED(mloop_len),
+ const int /*mloop_len*/,
const MPoly *mpoly,
const int mpoly_len,
float (*r_poly_normals)[3],
@@ -320,7 +321,7 @@ void BKE_mesh_calc_normals_poly_and_vertex(const MVert *mvert,
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = 1024;
- memset(r_vert_normals, 0, sizeof(*r_vert_normals) * (size_t)mvert_len);
+ memset(r_vert_normals, 0, sizeof(*r_vert_normals) * size_t(mvert_len));
MeshCalcNormalsData_PolyAndVertex data = {};
data.mpoly = mpoly;
@@ -347,20 +348,18 @@ void BKE_mesh_calc_normals_poly_and_vertex(const MVert *mvert,
const float (*BKE_mesh_vertex_normals_ensure(const Mesh *mesh))[3]
{
if (!BKE_mesh_vertex_normals_are_dirty(mesh)) {
- BLI_assert(mesh->runtime.vert_normals != nullptr || mesh->totvert == 0);
- return mesh->runtime.vert_normals;
+ BLI_assert(mesh->runtime->vert_normals != nullptr || mesh->totvert == 0);
+ return mesh->runtime->vert_normals;
}
if (mesh->totvert == 0) {
return nullptr;
}
- ThreadMutex *normals_mutex = (ThreadMutex *)mesh->runtime.normals_mutex;
- BLI_mutex_lock(normals_mutex);
+ std::lock_guard lock{mesh->runtime->normals_mutex};
if (!BKE_mesh_vertex_normals_are_dirty(mesh)) {
- BLI_assert(mesh->runtime.vert_normals != nullptr);
- BLI_mutex_unlock(normals_mutex);
- return mesh->runtime.vert_normals;
+ BLI_assert(mesh->runtime->vert_normals != nullptr);
+ return mesh->runtime->vert_normals;
}
float(*vert_normals)[3];
@@ -389,27 +388,24 @@ const float (*BKE_mesh_vertex_normals_ensure(const Mesh *mesh))[3]
BKE_mesh_poly_normals_clear_dirty(&mesh_mutable);
});
- BLI_mutex_unlock(normals_mutex);
return vert_normals;
}
const float (*BKE_mesh_poly_normals_ensure(const Mesh *mesh))[3]
{
if (!BKE_mesh_poly_normals_are_dirty(mesh)) {
- BLI_assert(mesh->runtime.poly_normals != nullptr || mesh->totpoly == 0);
- return mesh->runtime.poly_normals;
+ BLI_assert(mesh->runtime->poly_normals != nullptr || mesh->totpoly == 0);
+ return mesh->runtime->poly_normals;
}
if (mesh->totpoly == 0) {
return nullptr;
}
- ThreadMutex *normals_mutex = (ThreadMutex *)mesh->runtime.normals_mutex;
- BLI_mutex_lock(normals_mutex);
+ std::lock_guard lock{mesh->runtime->normals_mutex};
if (!BKE_mesh_poly_normals_are_dirty(mesh)) {
- BLI_assert(mesh->runtime.poly_normals != nullptr);
- BLI_mutex_unlock(normals_mutex);
- return mesh->runtime.poly_normals;
+ BLI_assert(mesh->runtime->poly_normals != nullptr);
+ return mesh->runtime->poly_normals;
}
float(*poly_normals)[3];
@@ -434,13 +430,12 @@ const float (*BKE_mesh_poly_normals_ensure(const Mesh *mesh))[3]
BKE_mesh_poly_normals_clear_dirty(&mesh_mutable);
});
- BLI_mutex_unlock(normals_mutex);
return poly_normals;
}
void BKE_mesh_ensure_normals_for_display(Mesh *mesh)
{
- switch ((eMeshWrapperType)mesh->runtime.wrapper_type) {
+ switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_SUBD:
case ME_WRAPPER_TYPE_MDATA:
BKE_mesh_vertex_normals_ensure(mesh);
@@ -448,7 +443,7 @@ void BKE_mesh_ensure_normals_for_display(Mesh *mesh)
break;
case ME_WRAPPER_TYPE_BMESH: {
struct BMEditMesh *em = mesh->edit_mesh;
- EditMeshData *emd = mesh->runtime.edit_data;
+ EditMeshData *emd = mesh->runtime->edit_data;
if (emd->vertexCos) {
BKE_editmesh_cache_ensure_vert_normals(em, emd);
BKE_editmesh_cache_ensure_poly_normals(em, emd);
@@ -469,17 +464,17 @@ void BKE_mesh_calc_normals(Mesh *mesh)
#endif
}
-void BKE_mesh_calc_normals_looptri(MVert *mverts,
+void BKE_mesh_calc_normals_looptri(const MVert *mverts,
int numVerts,
const MLoop *mloop,
const MLoopTri *looptri,
int looptri_num,
float (*r_tri_nors)[3])
{
- float(*tnorms)[3] = (float(*)[3])MEM_calloc_arrayN((size_t)numVerts, sizeof(*tnorms), "tnorms");
+ float(*tnorms)[3] = (float(*)[3])MEM_calloc_arrayN(size_t(numVerts), sizeof(*tnorms), "tnorms");
float(*fnors)[3] = (r_tri_nors) ? r_tri_nors :
(float(*)[3])MEM_calloc_arrayN(
- (size_t)looptri_num, sizeof(*fnors), "meshnormals");
+ size_t(looptri_num), sizeof(*fnors), "meshnormals");
if (!tnorms || !fnors) {
goto cleanup;
@@ -507,7 +502,7 @@ void BKE_mesh_calc_normals_looptri(MVert *mverts,
/* Following Mesh convention; we use vertex coordinate itself for normal in this case. */
for (int i = 0; i < numVerts; i++) {
- MVert *mv = &mverts[i];
+ const MVert *mv = &mverts[i];
float *no = tnorms[i];
if (UNLIKELY(normalize_v3(no) == 0.0f)) {
@@ -535,9 +530,9 @@ void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr,
}
mem = lnors_spacearr->mem;
lnors_spacearr->lspacearr = (MLoopNorSpace **)BLI_memarena_calloc(
- mem, sizeof(MLoopNorSpace *) * (size_t)numLoops);
+ mem, sizeof(MLoopNorSpace *) * size_t(numLoops));
lnors_spacearr->loops_pool = (LinkNode *)BLI_memarena_alloc(
- mem, sizeof(LinkNode) * (size_t)numLoops);
+ mem, sizeof(LinkNode) * size_t(numLoops));
lnors_spacearr->spaces_num = 0;
}
@@ -598,7 +593,7 @@ void BKE_lnor_space_define(MLoopNorSpace *lnor_space,
float vec_other[3],
BLI_Stack *edge_vectors)
{
- const float pi2 = (float)M_PI * 2.0f;
+ const float pi2 = float(M_PI) * 2.0f;
float tvec[3], dtp;
const float dtp_ref = dot_v3v3(vec_ref, lnor);
const float dtp_other = dot_v3v3(vec_other, lnor);
@@ -632,7 +627,7 @@ void BKE_lnor_space_define(MLoopNorSpace *lnor_space,
* a smooth vertex with only two edges and two faces (our Monkey's nose has that, e.g.).
*/
BLI_assert(count >= 2); /* This piece of code shall only be called for more than one loop. */
- lnor_space->ref_alpha = alpha / (float)count;
+ lnor_space->ref_alpha = alpha / float(count);
}
else {
lnor_space->ref_alpha = (saacosf(dot_v3v3(vec_ref, lnor)) +
@@ -690,13 +685,13 @@ void BKE_lnor_space_add_loop(MLoopNorSpaceArray *lnors_spacearr,
MINLINE float unit_short_to_float(const short val)
{
- return (float)val / (float)SHRT_MAX;
+ return float(val) / float(SHRT_MAX);
}
MINLINE short unit_float_to_short(const float val)
{
/* Rounding. */
- return (short)floorf(val * (float)SHRT_MAX + 0.5f);
+ return short(floorf(val * float(SHRT_MAX) + 0.5f));
}
void BKE_lnor_space_custom_data_to_normal(MLoopNorSpace *lnor_space,
@@ -712,7 +707,7 @@ void BKE_lnor_space_custom_data_to_normal(MLoopNorSpace *lnor_space,
{
/* TODO: Check whether using #sincosf() gives any noticeable benefit
* (could not even get it working under linux though)! */
- const float pi2 = (float)(M_PI * 2.0);
+ const float pi2 = float(M_PI * 2.0);
const float alphafac = unit_short_to_float(clnor_data[0]);
const float alpha = (alphafac > 0.0f ? lnor_space->ref_alpha : pi2 - lnor_space->ref_alpha) *
alphafac;
@@ -745,7 +740,7 @@ void BKE_lnor_space_custom_normal_to_data(MLoopNorSpace *lnor_space,
}
{
- const float pi2 = (float)(M_PI * 2.0);
+ const float pi2 = float(M_PI * 2.0);
const float cos_alpha = dot_v3v3(lnor_space->vec_lnor, custom_lnor);
float vec[3], cos_beta;
float alpha;
@@ -835,7 +830,7 @@ struct LoopSplitTaskDataCommon {
#define INDEX_UNSET INT_MIN
#define INDEX_INVALID -1
/* See comment about edge_to_loops below. */
-#define IS_EDGE_SHARP(_e2l) (ELEM((_e2l)[1], INDEX_UNSET, INDEX_INVALID))
+#define IS_EDGE_SHARP(_e2l) ELEM((_e2l)[1], INDEX_UNSET, INDEX_INVALID)
static void mesh_edges_sharp_tag(LoopSplitTaskDataCommon *data,
const bool check_angle,
@@ -945,7 +940,7 @@ static void mesh_edges_sharp_tag(LoopSplitTaskDataCommon *data,
}
void BKE_edges_sharp_from_angle_set(const struct MVert *mverts,
- const int UNUSED(numVerts),
+ const int /*numVerts*/,
struct MEdge *medges,
const int numEdges,
const struct MLoop *mloops,
@@ -955,17 +950,17 @@ void BKE_edges_sharp_from_angle_set(const struct MVert *mverts,
const int numPolys,
const float split_angle)
{
- if (split_angle >= (float)M_PI) {
+ if (split_angle >= float(M_PI)) {
/* Nothing to do! */
return;
}
/* Mapping edge -> loops. See BKE_mesh_normals_loop_split() for details. */
int(*edge_to_loops)[2] = (int(*)[2])MEM_calloc_arrayN(
- (size_t)numEdges, sizeof(*edge_to_loops), __func__);
+ size_t(numEdges), sizeof(*edge_to_loops), __func__);
/* Simple mapping from a loop to its polygon index. */
- int *loop_to_poly = (int *)MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__);
+ int *loop_to_poly = (int *)MEM_malloc_arrayN(size_t(numLoops), sizeof(*loop_to_poly), __func__);
LoopSplitTaskDataCommon common_data = {};
common_data.mverts = mverts;
@@ -1278,8 +1273,8 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli
}
while ((clnor = (short *)BLI_SMALLSTACK_POP(clnors))) {
// print_v2("org clnor", clnor);
- clnor[0] = (short)clnors_avg[0];
- clnor[1] = (short)clnors_avg[1];
+ clnor[0] = short(clnors_avg[0]);
+ clnor[1] = short(clnors_avg[1]);
}
// print_v2("new clnors", clnors_avg);
}
@@ -1606,7 +1601,7 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common
void BKE_mesh_normals_loop_split(const MVert *mverts,
const float (*vert_normals)[3],
- const int UNUSED(numVerts),
+ const int /*numVerts*/,
const MEdge *medges,
const int numEdges,
const MLoop *mloops,
@@ -1670,15 +1665,15 @@ void BKE_mesh_normals_loop_split(const MVert *mverts,
* to retrieve the real value later in code).
* Note also that loose edges always have both values set to 0! */
int(*edge_to_loops)[2] = (int(*)[2])MEM_calloc_arrayN(
- (size_t)numEdges, sizeof(*edge_to_loops), __func__);
+ size_t(numEdges), sizeof(*edge_to_loops), __func__);
/* Simple mapping from a loop to its polygon index. */
int *loop_to_poly = r_loop_to_poly ? r_loop_to_poly :
(int *)MEM_malloc_arrayN(
- (size_t)numLoops, sizeof(*loop_to_poly), __func__);
+ size_t(numLoops), sizeof(*loop_to_poly), __func__);
/* When using custom loop normals, disable the angle feature! */
- const bool check_angle = (split_angle < (float)M_PI) && (clnors_data == nullptr);
+ const bool check_angle = (split_angle < float(M_PI)) && (clnors_data == nullptr);
MLoopNorSpaceArray _lnors_spacearr = {nullptr};
@@ -1779,12 +1774,12 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
* So better to keep some simplicity here, and just call #BKE_mesh_normals_loop_split() twice! */
MLoopNorSpaceArray lnors_spacearr = {nullptr};
BitVector<> done_loops(numLoops, false);
- float(*lnors)[3] = (float(*)[3])MEM_calloc_arrayN((size_t)numLoops, sizeof(*lnors), __func__);
- int *loop_to_poly = (int *)MEM_malloc_arrayN((size_t)numLoops, sizeof(int), __func__);
+ float(*lnors)[3] = (float(*)[3])MEM_calloc_arrayN(size_t(numLoops), sizeof(*lnors), __func__);
+ int *loop_to_poly = (int *)MEM_malloc_arrayN(size_t(numLoops), sizeof(int), __func__);
/* In this case we always consider split nors as ON,
* and do not want to use angle to define smooth fans! */
const bool use_split_normals = true;
- const float split_angle = (float)M_PI;
+ const float split_angle = float(M_PI);
BLI_SMALLSTACK_DECLARE(clnors_data, short *);
@@ -1952,7 +1947,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
LinkNode *loops = lnors_spacearr.lspacearr[i]->loops;
if (lnors_spacearr.lspacearr[i]->flags & MLNOR_SPACE_IS_SINGLE) {
BLI_assert(POINTER_AS_INT(loops) == i);
- const int nidx = use_vertices ? (int)mloops[i].v : i;
+ const int nidx = use_vertices ? int(mloops[i].v) : i;
float *nor = r_custom_loopnors[nidx];
BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], nor, r_clnors_data[i]);
@@ -1966,7 +1961,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
zero_v3(avg_nor);
while (loops) {
const int lidx = POINTER_AS_INT(loops->link);
- const int nidx = use_vertices ? (int)mloops[lidx].v : lidx;
+ const int nidx = use_vertices ? int(mloops[lidx].v) : lidx;
float *nor = r_custom_loopnors[nidx];
avg_nor_count++;
@@ -1977,7 +1972,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
done_loops[lidx].reset();
}
- mul_v3_fl(avg_nor, 1.0f / (float)avg_nor_count);
+ mul_v3_fl(avg_nor, 1.0f / float(avg_nor_count));
BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], avg_nor, clnor_data_tmp);
while ((clnor_data = (short *)BLI_SMALLSTACK_POP(clnors_data))) {
@@ -2056,7 +2051,7 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const
clnors = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
if (clnors != nullptr) {
- memset(clnors, 0, sizeof(*clnors) * (size_t)numloops);
+ memset(clnors, 0, sizeof(*clnors) * size_t(numloops));
}
else {
clnors = (short(*)[2])CustomData_add_layer(
@@ -2099,7 +2094,7 @@ void BKE_mesh_normals_loop_to_vertex(const int numVerts,
float (*r_vert_clnors)[3])
{
int *vert_loops_count = (int *)MEM_calloc_arrayN(
- (size_t)numVerts, sizeof(*vert_loops_count), __func__);
+ size_t(numVerts), sizeof(*vert_loops_count), __func__);
copy_vn_fl((float *)r_vert_clnors, 3 * numVerts, 0.0f);
@@ -2113,7 +2108,7 @@ void BKE_mesh_normals_loop_to_vertex(const int numVerts,
}
for (i = 0; i < numVerts; i++) {
- mul_v3_fl(r_vert_clnors[i], 1.0f / (float)vert_loops_count[i]);
+ mul_v3_fl(r_vert_clnors[i], 1.0f / float(vert_loops_count[i]));
}
MEM_freeN(vert_loops_count);
diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c
index d63d064eb3c..90798ea593d 100644
--- a/source/blender/blenkernel/intern/mesh_remap.c
+++ b/source/blender/blenkernel/intern/mesh_remap.c
@@ -1050,7 +1050,7 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands,
const bool is_edge_innercut,
const int *poly_island_index_map,
float (*poly_centers)[3],
- unsigned char *poly_status)
+ uchar *poly_status)
{
int *poly_island_indices = BLI_array_alloca(poly_island_indices,
(size_t)edge_to_poly_map[edge_idx].count);
@@ -1114,7 +1114,7 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands,
BLI_bitmap *done_edges = BLI_BITMAP_NEW(numedges, __func__);
const int node_num = islands ? island_poly_map->count : numpolys;
- unsigned char *poly_status = MEM_callocN(sizeof(*poly_status) * (size_t)node_num, __func__);
+ uchar *poly_status = MEM_callocN(sizeof(*poly_status) * (size_t)node_num, __func__);
float(*poly_centers)[3];
int pidx_isld;
@@ -1529,7 +1529,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
BLI_bitmap *looptri_active;
looptri_src = BKE_mesh_runtime_looptri_ensure(me_src);
- num_looptri_src = me_src->runtime.looptris.len;
+ num_looptri_src = BKE_mesh_runtime_looptri_len(me_src);
looptri_active = BLI_BITMAP_NEW((size_t)num_looptri_src, __func__);
for (tindex = 0; tindex < num_trees; tindex++) {
diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc
index a77879fb573..0887e26148a 100644
--- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc
+++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc
@@ -19,11 +19,13 @@
#include "BLI_math_vec_types.hh"
#include "BLI_math_vector.h"
#include "BLI_span.hh"
+#include "BLI_task.hh"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_attribute.h"
+#include "BKE_attribute.hh"
#include "BKE_bvhutils.h"
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
@@ -193,8 +195,7 @@ static openvdb::FloatGrid::Ptr remesh_voxel_level_set_create(const Mesh *mesh,
{
const Span<MVert> verts = mesh->verts();
const Span<MLoop> loops = mesh->loops();
- Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh),
- BKE_mesh_runtime_looptri_len(mesh)};
+ const Span<MLoopTri> looptris = mesh->looptris();
std::vector<openvdb::Vec3s> points(mesh->totvert);
std::vector<openvdb::Vec3I> triangles(looptris.size());
@@ -302,60 +303,71 @@ void BKE_mesh_remesh_reproject_paint_mask(Mesh *target, const Mesh *source)
&target->vdata, CD_PAINT_MASK, CD_CONSTRUCT, nullptr, target->totvert);
}
- for (int i = 0; i < target->totvert; i++) {
- float from_co[3];
- BVHTreeNearest nearest;
- nearest.index = -1;
- nearest.dist_sq = FLT_MAX;
- copy_v3_v3(from_co, target_verts[i].co);
- BLI_bvhtree_find_nearest(bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree);
- if (nearest.index != -1) {
- target_mask[i] = source_mask[nearest.index];
+ blender::threading::parallel_for(IndexRange(target->totvert), 4096, [&](const IndexRange range) {
+ for (const int i : range) {
+ float from_co[3];
+ BVHTreeNearest nearest;
+ nearest.index = -1;
+ nearest.dist_sq = FLT_MAX;
+ copy_v3_v3(from_co, target_verts[i].co);
+ BLI_bvhtree_find_nearest(
+ bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree);
+ if (nearest.index != -1) {
+ target_mask[i] = source_mask[nearest.index];
+ }
}
- }
+ });
free_bvhtree_from_mesh(&bvhtree);
}
void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source)
{
+ using namespace blender;
+ using namespace blender::bke;
+ const AttributeAccessor src_attributes = source->attributes();
+ MutableAttributeAccessor dst_attributes = target->attributes_for_write();
const MPoly *target_polys = (const MPoly *)CustomData_get_layer(&target->pdata, CD_MPOLY);
const MVert *target_verts = (const MVert *)CustomData_get_layer(&target->vdata, CD_MVERT);
const MLoop *target_loops = (const MLoop *)CustomData_get_layer(&target->ldata, CD_MLOOP);
- const int *source_face_sets = (const int *)CustomData_get_layer(&source->pdata,
- CD_SCULPT_FACE_SETS);
- if (source_face_sets == nullptr) {
- return;
- }
- int *target_face_sets;
- if (CustomData_has_layer(&target->pdata, CD_SCULPT_FACE_SETS)) {
- target_face_sets = (int *)CustomData_get_layer(&target->pdata, CD_SCULPT_FACE_SETS);
+ const VArray<int> src_face_sets = src_attributes.lookup<int>(".sculpt_face_set",
+ ATTR_DOMAIN_FACE);
+ if (!src_face_sets) {
+ return;
}
- else {
- target_face_sets = (int *)CustomData_add_layer(
- &target->pdata, CD_SCULPT_FACE_SETS, CD_CONSTRUCT, nullptr, target->totpoly);
+ SpanAttributeWriter<int> dst_face_sets = dst_attributes.lookup_or_add_for_write_only_span<int>(
+ ".sculpt_face_set", ATTR_DOMAIN_FACE);
+ if (!dst_face_sets) {
+ return;
}
+ const VArraySpan<int> src(src_face_sets);
+ MutableSpan<int> dst = dst_face_sets.span;
+
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(source);
BVHTreeFromMesh bvhtree = {nullptr};
BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_LOOPTRI, 2);
- for (int i = 0; i < target->totpoly; i++) {
- float from_co[3];
- BVHTreeNearest nearest;
- nearest.index = -1;
- nearest.dist_sq = FLT_MAX;
- const MPoly *mpoly = &target_polys[i];
- BKE_mesh_calc_poly_center(mpoly, &target_loops[mpoly->loopstart], target_verts, from_co);
- BLI_bvhtree_find_nearest(bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree);
- if (nearest.index != -1) {
- target_face_sets[i] = source_face_sets[looptri[nearest.index].poly];
- }
- else {
- target_face_sets[i] = 1;
+ blender::threading::parallel_for(IndexRange(target->totpoly), 2048, [&](const IndexRange range) {
+ for (const int i : range) {
+ float from_co[3];
+ BVHTreeNearest nearest;
+ nearest.index = -1;
+ nearest.dist_sq = FLT_MAX;
+ const MPoly *mpoly = &target_polys[i];
+ BKE_mesh_calc_poly_center(mpoly, &target_loops[mpoly->loopstart], target_verts, from_co);
+ BLI_bvhtree_find_nearest(
+ bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree);
+ if (nearest.index != -1) {
+ dst[i] = src[looptri[nearest.index].poly];
+ }
+ else {
+ dst[i] = 1;
+ }
}
- }
+ });
free_bvhtree_from_mesh(&bvhtree);
+ dst_face_sets.finish();
}
void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source)
@@ -394,85 +406,87 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source)
MVert *target_verts = (MVert *)CustomData_get_layer(&target->vdata, CD_MVERT);
if (domain == ATTR_DOMAIN_POINT) {
- for (int i = 0; i < target->totvert; i++) {
- BVHTreeNearest nearest;
- nearest.index = -1;
- nearest.dist_sq = FLT_MAX;
- BLI_bvhtree_find_nearest(
- bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree);
-
- if (nearest.index != -1) {
- memcpy(POINTER_OFFSET(target_data, (size_t)i * data_size),
- POINTER_OFFSET(source_data, (size_t)nearest.index * data_size),
- data_size);
- }
- }
+ blender::threading::parallel_for(
+ IndexRange(target->totvert), 4096, [&](const IndexRange range) {
+ for (const int i : range) {
+ BVHTreeNearest nearest;
+ nearest.index = -1;
+ nearest.dist_sq = FLT_MAX;
+ BLI_bvhtree_find_nearest(
+ bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree);
+
+ if (nearest.index != -1) {
+ memcpy(POINTER_OFFSET(target_data, size_t(i) * data_size),
+ POINTER_OFFSET(source_data, size_t(nearest.index) * data_size),
+ data_size);
+ }
+ }
+ });
}
else {
/* Lazily init vertex -> loop maps. */
if (!source_lmap) {
- const MPoly *source_polys = (MPoly *)CustomData_get_layer(&source->pdata, CD_MPOLY);
- const MLoop *source_loops = (MLoop *)CustomData_get_layer(&source->ldata, CD_MLOOP);
- const MPoly *target_polys = (MPoly *)CustomData_get_layer(&target->pdata, CD_MPOLY);
- const MLoop *target_loops = (MLoop *)CustomData_get_layer(&target->ldata, CD_MLOOP);
-
BKE_mesh_vert_loop_map_create(&source_lmap,
&source_lmap_mem,
- source_polys,
- source_loops,
+ source->polys().data(),
+ source->loops().data(),
source->totvert,
source->totpoly,
source->totloop);
BKE_mesh_vert_loop_map_create(&target_lmap,
&target_lmap_mem,
- target_polys,
- target_loops,
+ target->polys().data(),
+ target->loops().data(),
target->totvert,
target->totpoly,
target->totloop);
}
- for (int i = 0; i < target->totvert; i++) {
- BVHTreeNearest nearest;
- nearest.index = -1;
- nearest.dist_sq = FLT_MAX;
- BLI_bvhtree_find_nearest(
- bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree);
-
- if (nearest.index == -1) {
- continue;
- }
-
- MeshElemMap *source_loops = source_lmap + nearest.index;
- MeshElemMap *target_loops = target_lmap + i;
-
- if (target_loops->count == 0 || source_loops->count == 0) {
- continue;
- }
-
- /*
- * Average color data for loops around the source vertex into
- * the first target loop around the target vertex
- */
-
- CustomData_interp(source_cdata,
- target_cdata,
- source_loops->indices,
- nullptr,
- nullptr,
- source_loops->count,
- target_loops->indices[0]);
-
- void *elem = POINTER_OFFSET(target_data, (size_t)target_loops->indices[0] * data_size);
-
- /* Copy to rest of target loops. */
- for (int j = 1; j < target_loops->count; j++) {
- memcpy(POINTER_OFFSET(target_data, (size_t)target_loops->indices[j] * data_size),
- elem,
- data_size);
- }
- }
+ blender::threading::parallel_for(
+ IndexRange(target->totvert), 2048, [&](const IndexRange range) {
+ for (const int i : range) {
+ BVHTreeNearest nearest;
+ nearest.index = -1;
+ nearest.dist_sq = FLT_MAX;
+ BLI_bvhtree_find_nearest(
+ bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree);
+
+ if (nearest.index == -1) {
+ continue;
+ }
+
+ MeshElemMap *source_loops = source_lmap + nearest.index;
+ MeshElemMap *target_loops = target_lmap + i;
+
+ if (target_loops->count == 0 || source_loops->count == 0) {
+ continue;
+ }
+
+ /*
+ * Average color data for loops around the source vertex into
+ * the first target loop around the target vertex
+ */
+
+ CustomData_interp(source_cdata,
+ target_cdata,
+ source_loops->indices,
+ nullptr,
+ nullptr,
+ source_loops->count,
+ target_loops->indices[0]);
+
+ void *elem = POINTER_OFFSET(target_data,
+ size_t(target_loops->indices[0]) * data_size);
+
+ /* Copy to rest of target loops. */
+ for (int j = 1; j < target_loops->count; j++) {
+ memcpy(POINTER_OFFSET(target_data, size_t(target_loops->indices[j]) * data_size),
+ elem,
+ data_size);
+ }
+ }
+ });
}
}
@@ -581,7 +595,7 @@ struct Mesh *BKE_mesh_remesh_voxel_fix_poles(const Mesh *mesh)
BMVert *vert = BM_edge_other_vert(ed, v);
add_v3_v3(co, vert->co);
}
- mul_v3_fl(co, 1.0f / (float)BM_vert_edge_count(v));
+ mul_v3_fl(co, 1.0f / float(BM_vert_edge_count(v)));
mid_v3_v3v3(v->co, v->co, co);
}
}
diff --git a/source/blender/blenkernel/intern/mesh_runtime.cc b/source/blender/blenkernel/intern/mesh_runtime.cc
index a66f2a714e7..e90a298ad8d 100644
--- a/source/blender/blenkernel/intern/mesh_runtime.cc
+++ b/source/blender/blenkernel/intern/mesh_runtime.cc
@@ -17,6 +17,7 @@
#include "BLI_task.hh"
#include "BKE_bvhutils.h"
+#include "BKE_editmesh_cache.h"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
@@ -30,81 +31,17 @@ using blender::Span;
/** \name Mesh Runtime Struct Utils
* \{ */
-/**
- * \brief Initialize the runtime mutexes of the given mesh.
- *
- * Any existing mutexes will be overridden.
- */
-static void mesh_runtime_init_mutexes(Mesh *mesh)
-{
- mesh->runtime.eval_mutex = MEM_new<ThreadMutex>("mesh runtime eval_mutex");
- BLI_mutex_init(static_cast<ThreadMutex *>(mesh->runtime.eval_mutex));
- mesh->runtime.normals_mutex = MEM_new<ThreadMutex>("mesh runtime normals_mutex");
- BLI_mutex_init(static_cast<ThreadMutex *>(mesh->runtime.normals_mutex));
- mesh->runtime.render_mutex = MEM_new<ThreadMutex>("mesh runtime render_mutex");
- BLI_mutex_init(static_cast<ThreadMutex *>(mesh->runtime.render_mutex));
-}
-
-/**
- * \brief free the mutexes of the given mesh runtime.
- */
-static void mesh_runtime_free_mutexes(Mesh *mesh)
-{
- if (mesh->runtime.eval_mutex != nullptr) {
- BLI_mutex_end(static_cast<ThreadMutex *>(mesh->runtime.eval_mutex));
- MEM_freeN(mesh->runtime.eval_mutex);
- mesh->runtime.eval_mutex = nullptr;
- }
- if (mesh->runtime.normals_mutex != nullptr) {
- BLI_mutex_end(static_cast<ThreadMutex *>(mesh->runtime.normals_mutex));
- MEM_freeN(mesh->runtime.normals_mutex);
- mesh->runtime.normals_mutex = nullptr;
- }
- if (mesh->runtime.render_mutex != nullptr) {
- BLI_mutex_end(static_cast<ThreadMutex *>(mesh->runtime.render_mutex));
- MEM_freeN(mesh->runtime.render_mutex);
- mesh->runtime.render_mutex = nullptr;
- }
-}
-
-void BKE_mesh_runtime_init_data(Mesh *mesh)
-{
- mesh_runtime_init_mutexes(mesh);
-}
-
void BKE_mesh_runtime_free_data(Mesh *mesh)
{
BKE_mesh_runtime_clear_cache(mesh);
- mesh_runtime_free_mutexes(mesh);
-}
-
-void BKE_mesh_runtime_reset_on_copy(Mesh *mesh, const int UNUSED(flag))
-{
- Mesh_Runtime *runtime = &mesh->runtime;
-
- runtime->mesh_eval = nullptr;
- runtime->edit_data = nullptr;
- runtime->batch_cache = nullptr;
- runtime->subdiv_ccg = nullptr;
- runtime->looptris = blender::dna::shallow_zero_initialize();
- runtime->bvh_cache = nullptr;
- runtime->shrinkwrap_data = nullptr;
- runtime->subsurf_face_dot_tags = nullptr;
-
- runtime->vert_normals_dirty = true;
- runtime->poly_normals_dirty = true;
- runtime->vert_normals = nullptr;
- runtime->poly_normals = nullptr;
-
- mesh_runtime_init_mutexes(mesh);
}
void BKE_mesh_runtime_clear_cache(Mesh *mesh)
{
- if (mesh->runtime.mesh_eval != nullptr) {
- mesh->runtime.mesh_eval->edit_mesh = nullptr;
- BKE_id_free(nullptr, mesh->runtime.mesh_eval);
- mesh->runtime.mesh_eval = nullptr;
+ if (mesh->runtime->mesh_eval != nullptr) {
+ mesh->runtime->mesh_eval->edit_mesh = nullptr;
+ BKE_id_free(nullptr, mesh->runtime->mesh_eval);
+ mesh->runtime->mesh_eval = nullptr;
}
BKE_mesh_runtime_clear_geometry(mesh);
BKE_mesh_batch_cache_free(mesh);
@@ -112,6 +49,13 @@ void BKE_mesh_runtime_clear_cache(Mesh *mesh)
BKE_mesh_clear_derived_normals(mesh);
}
+blender::Span<MLoopTri> Mesh::looptris() const
+{
+ const MLoopTri *looptris = BKE_mesh_runtime_looptri_ensure(this);
+ const int num_looptris = BKE_mesh_runtime_looptri_len(this);
+ return {looptris, num_looptris};
+}
+
/**
* Ensure the array is large enough
*
@@ -124,77 +68,85 @@ static void mesh_ensure_looptri_data(Mesh *mesh)
const uint totpoly = mesh->totpoly;
const int looptris_len = poly_to_tri_count(totpoly, mesh->totloop);
- BLI_assert(mesh->runtime.looptris.array_wip == nullptr);
+ BLI_assert(mesh->runtime->looptris.array_wip == nullptr);
- SWAP(MLoopTri *, mesh->runtime.looptris.array, mesh->runtime.looptris.array_wip);
+ SWAP(MLoopTri *, mesh->runtime->looptris.array, mesh->runtime->looptris.array_wip);
- if ((looptris_len > mesh->runtime.looptris.len_alloc) ||
- (looptris_len < mesh->runtime.looptris.len_alloc * 2) || (totpoly == 0)) {
- MEM_SAFE_FREE(mesh->runtime.looptris.array_wip);
- mesh->runtime.looptris.len_alloc = 0;
- mesh->runtime.looptris.len = 0;
+ if ((looptris_len > mesh->runtime->looptris.len_alloc) ||
+ (looptris_len < mesh->runtime->looptris.len_alloc * 2) || (totpoly == 0)) {
+ MEM_SAFE_FREE(mesh->runtime->looptris.array_wip);
+ mesh->runtime->looptris.len_alloc = 0;
+ mesh->runtime->looptris.len = 0;
}
if (totpoly) {
- if (mesh->runtime.looptris.array_wip == nullptr) {
- mesh->runtime.looptris.array_wip = static_cast<MLoopTri *>(
- MEM_malloc_arrayN(looptris_len, sizeof(*mesh->runtime.looptris.array_wip), __func__));
- mesh->runtime.looptris.len_alloc = looptris_len;
+ if (mesh->runtime->looptris.array_wip == nullptr) {
+ mesh->runtime->looptris.array_wip = static_cast<MLoopTri *>(
+ MEM_malloc_arrayN(looptris_len, sizeof(*mesh->runtime->looptris.array_wip), __func__));
+ mesh->runtime->looptris.len_alloc = looptris_len;
}
- mesh->runtime.looptris.len = looptris_len;
+ mesh->runtime->looptris.len = looptris_len;
}
}
void BKE_mesh_runtime_looptri_recalc(Mesh *mesh)
{
mesh_ensure_looptri_data(mesh);
- BLI_assert(mesh->totpoly == 0 || mesh->runtime.looptris.array_wip != nullptr);
+ BLI_assert(mesh->totpoly == 0 || mesh->runtime->looptris.array_wip != nullptr);
const Span<MVert> verts = mesh->verts();
const Span<MPoly> polys = mesh->polys();
const Span<MLoop> loops = mesh->loops();
- BKE_mesh_recalc_looptri(loops.data(),
- polys.data(),
- verts.data(),
- mesh->totloop,
- mesh->totpoly,
- mesh->runtime.looptris.array_wip);
-
- BLI_assert(mesh->runtime.looptris.array == nullptr);
- atomic_cas_ptr((void **)&mesh->runtime.looptris.array,
- mesh->runtime.looptris.array,
- mesh->runtime.looptris.array_wip);
- mesh->runtime.looptris.array_wip = nullptr;
+ if (!BKE_mesh_poly_normals_are_dirty(mesh)) {
+ BKE_mesh_recalc_looptri_with_normals(loops.data(),
+ polys.data(),
+ verts.data(),
+ mesh->totloop,
+ mesh->totpoly,
+ mesh->runtime->looptris.array_wip,
+ BKE_mesh_poly_normals_ensure(mesh));
+ }
+ else {
+ BKE_mesh_recalc_looptri(loops.data(),
+ polys.data(),
+ verts.data(),
+ mesh->totloop,
+ mesh->totpoly,
+ mesh->runtime->looptris.array_wip);
+ }
+
+ BLI_assert(mesh->runtime->looptris.array == nullptr);
+ atomic_cas_ptr((void **)&mesh->runtime->looptris.array,
+ mesh->runtime->looptris.array,
+ mesh->runtime->looptris.array_wip);
+ mesh->runtime->looptris.array_wip = nullptr;
}
int BKE_mesh_runtime_looptri_len(const Mesh *mesh)
{
/* This is a ported copy of `dm_getNumLoopTri(dm)`. */
const int looptri_len = poly_to_tri_count(mesh->totpoly, mesh->totloop);
- BLI_assert(ELEM(mesh->runtime.looptris.len, 0, looptri_len));
+ BLI_assert(ELEM(mesh->runtime->looptris.len, 0, looptri_len));
return looptri_len;
}
const MLoopTri *BKE_mesh_runtime_looptri_ensure(const Mesh *mesh)
{
- ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime.eval_mutex;
- BLI_mutex_lock(mesh_eval_mutex);
+ std::lock_guard lock{mesh->runtime->eval_mutex};
- MLoopTri *looptri = mesh->runtime.looptris.array;
+ MLoopTri *looptri = mesh->runtime->looptris.array;
if (looptri != nullptr) {
- BLI_assert(BKE_mesh_runtime_looptri_len(mesh) == mesh->runtime.looptris.len);
+ BLI_assert(BKE_mesh_runtime_looptri_len(mesh) == mesh->runtime->looptris.len);
}
else {
/* Must isolate multithreaded tasks while holding a mutex lock. */
blender::threading::isolate_task(
[&]() { BKE_mesh_runtime_looptri_recalc(const_cast<Mesh *>(mesh)); });
- looptri = mesh->runtime.looptris.array;
+ looptri = mesh->runtime->looptris.array;
}
- BLI_mutex_unlock(mesh_eval_mutex);
-
return looptri;
}
@@ -212,17 +164,17 @@ void BKE_mesh_runtime_verttri_from_looptri(MVertTri *r_verttri,
bool BKE_mesh_runtime_ensure_edit_data(struct Mesh *mesh)
{
- if (mesh->runtime.edit_data != nullptr) {
+ if (mesh->runtime->edit_data != nullptr) {
return false;
}
- mesh->runtime.edit_data = MEM_cnew<EditMeshData>(__func__);
+ mesh->runtime->edit_data = MEM_cnew<EditMeshData>(__func__);
return true;
}
bool BKE_mesh_runtime_reset_edit_data(Mesh *mesh)
{
- EditMeshData *edit_data = mesh->runtime.edit_data;
+ EditMeshData *edit_data = mesh->runtime->edit_data;
if (edit_data == nullptr) {
return false;
}
@@ -237,13 +189,13 @@ bool BKE_mesh_runtime_reset_edit_data(Mesh *mesh)
bool BKE_mesh_runtime_clear_edit_data(Mesh *mesh)
{
- if (mesh->runtime.edit_data == nullptr) {
+ if (mesh->runtime->edit_data == nullptr) {
return false;
}
BKE_mesh_runtime_reset_edit_data(mesh);
- MEM_freeN(mesh->runtime.edit_data);
- mesh->runtime.edit_data = nullptr;
+ MEM_freeN(mesh->runtime->edit_data);
+ mesh->runtime->edit_data = nullptr;
return true;
}
@@ -253,22 +205,22 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh)
BKE_mesh_tag_coords_changed(mesh);
/* TODO(sergey): Does this really belong here? */
- if (mesh->runtime.subdiv_ccg != nullptr) {
- BKE_subdiv_ccg_destroy(mesh->runtime.subdiv_ccg);
- mesh->runtime.subdiv_ccg = nullptr;
+ if (mesh->runtime->subdiv_ccg != nullptr) {
+ BKE_subdiv_ccg_destroy(mesh->runtime->subdiv_ccg);
+ mesh->runtime->subdiv_ccg = nullptr;
}
BKE_shrinkwrap_discard_boundary_data(mesh);
- MEM_SAFE_FREE(mesh->runtime.subsurf_face_dot_tags);
+ MEM_SAFE_FREE(mesh->runtime->subsurf_face_dot_tags);
}
void BKE_mesh_tag_coords_changed(Mesh *mesh)
{
BKE_mesh_normals_tag_dirty(mesh);
- MEM_SAFE_FREE(mesh->runtime.looptris.array);
- if (mesh->runtime.bvh_cache) {
- bvhcache_free(mesh->runtime.bvh_cache);
- mesh->runtime.bvh_cache = nullptr;
+ MEM_SAFE_FREE(mesh->runtime->looptris.array);
+ if (mesh->runtime->bvh_cache) {
+ bvhcache_free(mesh->runtime->bvh_cache);
+ mesh->runtime->bvh_cache = nullptr;
}
}
@@ -280,13 +232,23 @@ void BKE_mesh_tag_coords_changed_uniformly(Mesh *mesh)
BKE_mesh_tag_coords_changed(mesh);
/* The normals didn't change, since all verts moved by the same amount. */
if (!vert_normals_were_dirty) {
- BKE_mesh_poly_normals_clear_dirty(mesh);
+ BKE_mesh_vertex_normals_clear_dirty(mesh);
}
if (!poly_normals_were_dirty) {
- BKE_mesh_vertex_normals_clear_dirty(mesh);
+ BKE_mesh_poly_normals_clear_dirty(mesh);
}
}
+bool BKE_mesh_is_deformed_only(const Mesh *mesh)
+{
+ return mesh->runtime->deformed_only;
+}
+
+eMeshWrapperType BKE_mesh_wrapper_type(const struct Mesh *mesh)
+{
+ return mesh->runtime->wrapper_type;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -299,13 +261,13 @@ void (*BKE_mesh_batch_cache_free_cb)(Mesh *me) = nullptr;
void BKE_mesh_batch_cache_dirty_tag(Mesh *me, eMeshBatchDirtyMode mode)
{
- if (me->runtime.batch_cache) {
+ if (me->runtime->batch_cache) {
BKE_mesh_batch_cache_dirty_tag_cb(me, mode);
}
}
void BKE_mesh_batch_cache_free(Mesh *me)
{
- if (me->runtime.batch_cache) {
+ if (me->runtime->batch_cache) {
BKE_mesh_batch_cache_free_cb(me);
}
}
diff --git a/source/blender/blenkernel/intern/mesh_sample.cc b/source/blender/blenkernel/intern/mesh_sample.cc
index 1ddac19304d..ed7ae8113a7 100644
--- a/source/blender/blenkernel/intern/mesh_sample.cc
+++ b/source/blender/blenkernel/intern/mesh_sample.cc
@@ -22,8 +22,7 @@ BLI_NOINLINE static void sample_point_attribute(const Mesh &mesh,
const MutableSpan<T> dst)
{
const Span<MLoop> loops = mesh.loops();
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
- BKE_mesh_runtime_looptri_len(&mesh)};
+ const Span<MLoopTri> looptris = mesh.looptris();
for (const int i : mask) {
const int looptri_index = looptri_indices[i];
@@ -69,8 +68,7 @@ BLI_NOINLINE static void sample_corner_attribute(const Mesh &mesh,
const IndexMask mask,
const MutableSpan<T> dst)
{
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
- BKE_mesh_runtime_looptri_len(&mesh)};
+ const Span<MLoopTri> looptris = mesh.looptris();
for (const int i : mask) {
const int looptri_index = looptri_indices[i];
@@ -115,8 +113,7 @@ void sample_face_attribute(const Mesh &mesh,
const IndexMask mask,
const MutableSpan<T> dst)
{
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
- BKE_mesh_runtime_looptri_len(&mesh)};
+ const Span<MLoopTri> looptris = mesh.looptris();
for (const int i : mask) {
const int looptri_index = looptri_indices[i];
@@ -161,8 +158,7 @@ Span<float3> MeshAttributeInterpolator::ensure_barycentric_coords()
const Span<MVert> verts = mesh_->verts();
const Span<MLoop> loops = mesh_->loops();
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh_),
- BKE_mesh_runtime_looptri_len(mesh_)};
+ const Span<MLoopTri> looptris = mesh_->looptris();
for (const int i : mask_) {
const int looptri_index = looptri_indices_[i];
@@ -191,8 +187,7 @@ Span<float3> MeshAttributeInterpolator::ensure_nearest_weights()
const Span<MVert> verts = mesh_->verts();
const Span<MLoop> loops = mesh_->loops();
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh_),
- BKE_mesh_runtime_looptri_len(mesh_)};
+ const Span<MLoopTri> looptris = mesh_->looptris();
for (const int i : mask_) {
const int looptri_index = looptri_indices_[i];
@@ -265,8 +260,7 @@ int sample_surface_points_spherical(RandomNumberGenerator &rng,
{
const Span<MVert> verts = mesh.verts();
const Span<MLoop> loops = mesh.loops();
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
- BKE_mesh_runtime_looptri_len(&mesh)};
+ const Span<MLoopTri> looptris = mesh.looptris();
const float sample_radius_sq = pow2f(sample_radius);
const float sample_plane_area = M_PI * sample_radius_sq;
@@ -363,8 +357,7 @@ int sample_surface_points_projected(
{
const Span<MVert> verts = mesh.verts();
const Span<MLoop> loops = mesh.loops();
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
- BKE_mesh_runtime_looptri_len(&mesh)};
+ const Span<MLoopTri> looptris = mesh.looptris();
int point_count = 0;
for ([[maybe_unused]] const int _ : IndexRange(tries_num)) {
diff --git a/source/blender/blenkernel/intern/mesh_tangent.cc b/source/blender/blenkernel/intern/mesh_tangent.cc
index 8f9af5e9258..49ea23a1552 100644
--- a/source/blender/blenkernel/intern/mesh_tangent.cc
+++ b/source/blender/blenkernel/intern/mesh_tangent.cc
@@ -7,7 +7,7 @@
* Functions to evaluate mesh tangents.
*/
-#include <limits.h>
+#include <climits>
#include "MEM_guardedalloc.h"
@@ -36,34 +36,34 @@
struct BKEMeshToTangent {
uint GetNumFaces()
{
- return (uint)num_polys;
+ return uint(num_polys);
}
uint GetNumVerticesOfFace(const uint face_num)
{
- return (uint)mpolys[face_num].totloop;
+ return uint(mpolys[face_num].totloop);
}
mikk::float3 GetPosition(const uint face_num, const uint vert_num)
{
- const uint loop_idx = (uint)mpolys[face_num].loopstart + vert_num;
+ const uint loop_idx = uint(mpolys[face_num].loopstart) + vert_num;
return mikk::float3(mverts[mloops[loop_idx].v].co);
}
mikk::float3 GetTexCoord(const uint face_num, const uint vert_num)
{
- const float *uv = luvs[(uint)mpolys[face_num].loopstart + vert_num].uv;
+ const float *uv = luvs[uint(mpolys[face_num].loopstart) + vert_num].uv;
return mikk::float3(uv[0], uv[1], 1.0f);
}
mikk::float3 GetNormal(const uint face_num, const uint vert_num)
{
- return mikk::float3(lnors[(uint)mpolys[face_num].loopstart + vert_num]);
+ return mikk::float3(lnors[uint(mpolys[face_num].loopstart) + vert_num]);
}
void SetTangentSpace(const uint face_num, const uint vert_num, mikk::float3 T, bool orientation)
{
- float *p_res = tangents[(uint)mpolys[face_num].loopstart + vert_num];
+ float *p_res = tangents[uint(mpolys[face_num].loopstart) + vert_num];
copy_v4_fl4(p_res, T.x, T.y, T.z, orientation ? 1.0f : -1.0f);
}
@@ -77,12 +77,12 @@ struct BKEMeshToTangent {
};
void BKE_mesh_calc_loop_tangent_single_ex(const MVert *mverts,
- const int UNUSED(numVerts),
+ const int /*numVerts*/,
const MLoop *mloops,
float (*r_looptangent)[4],
const float (*loopnors)[3],
const MLoopUV *loopuvs,
- const int UNUSED(numLoops),
+ const int /*numLoops*/,
const MPoly *mpolys,
const int numPolys,
ReportList *reports)
@@ -166,9 +166,9 @@ struct SGLSLMeshToTangent {
uint GetNumFaces()
{
#ifdef USE_LOOPTRI_DETECT_QUADS
- return (uint)num_face_as_quad_map;
+ return uint(num_face_as_quad_map);
#else
- return (uint)numTessFaces;
+ return uint(numTessFaces);
#endif
}
@@ -196,7 +196,7 @@ struct SGLSLMeshToTangent {
lt = &looptri[face_as_quad_map[face_num]];
const MPoly *mp = &mpoly[lt->poly];
if (mp->totloop == 4) {
- return ((uint)mp->loopstart + vert_num);
+ return (uint(mp->loopstart) + vert_num);
}
/* fall through to regular triangle */
}
@@ -224,12 +224,10 @@ struct SGLSLMeshToTangent {
const float *uv = mloopuv[loop_index].uv;
return mikk::float3(uv[0], uv[1], 1.0f);
}
- else {
- const float *l_orco = orco[mloop[loop_index].v];
- float u, v;
- map_to_sphere(&u, &v, l_orco[0], l_orco[1], l_orco[2]);
- return mikk::float3(u, v, 1.0f);
- }
+ const float *l_orco = orco[mloop[loop_index].v];
+ float u, v;
+ map_to_sphere(&u, &v, l_orco[0], l_orco[1], l_orco[2]);
+ return mikk::float3(u, v, 1.0f);
}
mikk::float3 GetNormal(const uint face_num, const uint vert_num)
@@ -239,35 +237,31 @@ struct SGLSLMeshToTangent {
if (precomputedLoopNormals) {
return mikk::float3(precomputedLoopNormals[loop_index]);
}
- else if ((mpoly[lt->poly].flag & ME_SMOOTH) == 0) { /* flat */
+ if ((mpoly[lt->poly].flag & ME_SMOOTH) == 0) { /* flat */
if (precomputedFaceNormals) {
return mikk::float3(precomputedFaceNormals[lt->poly]);
}
- else {
#ifdef USE_LOOPTRI_DETECT_QUADS
- const MPoly *mp = &mpoly[lt->poly];
- float normal[3];
- if (mp->totloop == 4) {
- normal_quad_v3(normal,
- mvert[mloop[mp->loopstart + 0].v].co,
- mvert[mloop[mp->loopstart + 1].v].co,
- mvert[mloop[mp->loopstart + 2].v].co,
- mvert[mloop[mp->loopstart + 3].v].co);
- }
- else
+ const MPoly *mp = &mpoly[lt->poly];
+ float normal[3];
+ if (mp->totloop == 4) {
+ normal_quad_v3(normal,
+ mvert[mloop[mp->loopstart + 0].v].co,
+ mvert[mloop[mp->loopstart + 1].v].co,
+ mvert[mloop[mp->loopstart + 2].v].co,
+ mvert[mloop[mp->loopstart + 3].v].co);
+ }
+ else
#endif
- {
- normal_tri_v3(normal,
- mvert[mloop[lt->tri[0]].v].co,
- mvert[mloop[lt->tri[1]].v].co,
- mvert[mloop[lt->tri[2]].v].co);
- }
- return mikk::float3(normal);
+ {
+ normal_tri_v3(normal,
+ mvert[mloop[lt->tri[0]].v].co,
+ mvert[mloop[lt->tri[1]].v].co,
+ mvert[mloop[lt->tri[2]].v].co);
}
+ return mikk::float3(normal);
}
- else {
- return mikk::float3(vert_normals[mloop[loop_index].v]);
- }
+ return mikk::float3(vert_normals[mloop[loop_index].v]);
}
void SetTangentSpace(const uint face_num, const uint vert_num, mikk::float3 T, bool orientation)
@@ -298,7 +292,7 @@ struct SGLSLMeshToTangent {
#endif
};
-static void DM_calc_loop_tangents_thread(TaskPool *__restrict UNUSED(pool), void *taskdata)
+static void DM_calc_loop_tangents_thread(TaskPool *__restrict /*pool*/, void *taskdata)
{
SGLSLMeshToTangent *mesh_data = static_cast<SGLSLMeshToTangent *>(taskdata);
@@ -382,7 +376,7 @@ void BKE_mesh_calc_loop_tangent_step_0(const CustomData *loopData,
add = true;
}
if (add) {
- *rtangent_mask |= (short)(1 << n);
+ *rtangent_mask |= short(1 << n);
}
}
@@ -437,21 +431,21 @@ void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert,
for (int i = 0; i < tangent_names_len; i++) {
if (tangent_names[i][0]) {
BKE_mesh_add_loop_tangent_named_layer_for_uv(
- loopdata, loopdata_out, (int)loopdata_out_len, tangent_names[i]);
+ loopdata, loopdata_out, int(loopdata_out_len), tangent_names[i]);
}
}
if ((tangent_mask & DM_TANGENT_MASK_ORCO) &&
CustomData_get_named_layer_index(loopdata, CD_TANGENT, "") == -1) {
CustomData_add_layer_named(
- loopdata_out, CD_TANGENT, CD_SET_DEFAULT, nullptr, (int)loopdata_out_len, "");
+ loopdata_out, CD_TANGENT, CD_SET_DEFAULT, nullptr, int(loopdata_out_len), "");
}
if (calc_act && act_uv_name[0]) {
BKE_mesh_add_loop_tangent_named_layer_for_uv(
- loopdata, loopdata_out, (int)loopdata_out_len, act_uv_name);
+ loopdata, loopdata_out, int(loopdata_out_len), act_uv_name);
}
if (calc_ren && ren_uv_name[0]) {
BKE_mesh_add_loop_tangent_named_layer_for_uv(
- loopdata, loopdata_out, (int)loopdata_out_len, ren_uv_name);
+ loopdata, loopdata_out, int(loopdata_out_len), ren_uv_name);
}
#ifdef USE_LOOPTRI_DETECT_QUADS
@@ -465,7 +459,7 @@ void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert,
/* map fake face index to looptri */
face_as_quad_map = static_cast<int *>(MEM_mallocN(sizeof(int) * looptri_len, __func__));
int k, j;
- for (k = 0, j = 0; j < (int)looptri_len; k++, j++) {
+ for (k = 0, j = 0; j < int(looptri_len); k++, j++) {
face_as_quad_map[k] = j;
/* step over all quads */
if (mpoly[looptri[j].poly].totloop == 4) {
@@ -475,7 +469,7 @@ void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert,
num_face_as_quad_map = k;
}
else {
- num_face_as_quad_map = (int)looptri_len;
+ num_face_as_quad_map = int(looptri_len);
}
#endif
@@ -491,7 +485,7 @@ void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert,
int index = CustomData_get_layer_index_n(loopdata_out, CD_TANGENT, n);
BLI_assert(n < MAX_MTFACE);
SGLSLMeshToTangent *mesh2tangent = &data_array[n];
- mesh2tangent->numTessFaces = (int)looptri_len;
+ mesh2tangent->numTessFaces = int(looptri_len);
#ifdef USE_LOOPTRI_DETECT_QUADS
mesh2tangent->face_as_quad_map = face_as_quad_map;
mesh2tangent->num_face_as_quad_map = num_face_as_quad_map;
@@ -525,7 +519,7 @@ void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert,
int uv_start = CustomData_get_layer_index(loopdata, CD_MLOOPUV);
BLI_assert(uv_ind != -1 && uv_start != -1);
BLI_assert(uv_ind - uv_start < MAX_MTFACE);
- tangent_mask_curr |= (short)(1 << (uv_ind - uv_start));
+ tangent_mask_curr |= short(1 << (uv_ind - uv_start));
}
mesh2tangent->tangent = static_cast<float(*)[4]>(loopdata_out->layers[index].data);
@@ -576,17 +570,15 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval,
const char (*tangent_names)[MAX_NAME],
int tangent_names_len)
{
- BKE_mesh_runtime_looptri_ensure(me_eval);
-
/* TODO(@campbellbarton): store in Mesh.runtime to avoid recalculation. */
short tangent_mask = 0;
BKE_mesh_calc_loop_tangent_ex(
BKE_mesh_verts(me_eval),
BKE_mesh_polys(me_eval),
- (uint)me_eval->totpoly,
+ uint(me_eval->totpoly),
BKE_mesh_loops(me_eval),
- me_eval->runtime.looptris.array,
- (uint)me_eval->runtime.looptris.len,
+ BKE_mesh_runtime_looptri_ensure(me_eval),
+ uint(BKE_mesh_runtime_looptri_len(me_eval)),
&me_eval->ldata,
calc_active_tangent,
tangent_names,
@@ -598,7 +590,7 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval,
static_cast<const float(*)[3]>(CustomData_get_layer(&me_eval->vdata, CD_ORCO)),
/* result */
&me_eval->ldata,
- (uint)me_eval->totloop,
+ uint(me_eval->totloop),
&tangent_mask);
}
diff --git a/source/blender/blenkernel/intern/mesh_tessellate.cc b/source/blender/blenkernel/intern/mesh_tessellate.cc
index de4c60b28db..df83743634c 100644
--- a/source/blender/blenkernel/intern/mesh_tessellate.cc
+++ b/source/blender/blenkernel/intern/mesh_tessellate.cc
@@ -49,8 +49,8 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop,
const bool face_normal,
const float normal_precalc[3])
{
- const uint mp_loopstart = (uint)mpoly[poly_index].loopstart;
- const uint mp_totloop = (uint)mpoly[poly_index].totloop;
+ const uint mp_loopstart = uint(mpoly[poly_index].loopstart);
+ const uint mp_totloop = uint(mpoly[poly_index].totloop);
#define ML_TO_MLT(i1, i2, i3) \
{ \
@@ -125,9 +125,9 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop,
}
uint(*tris)[3] = static_cast<uint(*)[3]>(
- BLI_memarena_alloc(pf_arena, sizeof(*tris) * (size_t)totfilltri));
+ BLI_memarena_alloc(pf_arena, sizeof(*tris) * size_t(totfilltri)));
float(*projverts)[2] = static_cast<float(*)[2]>(
- BLI_memarena_alloc(pf_arena, sizeof(*projverts) * (size_t)mp_totloop));
+ BLI_memarena_alloc(pf_arena, sizeof(*projverts) * size_t(mp_totloop)));
ml = mloop + mp_loopstart;
for (uint j = 0; j < mp_totloop; j++, ml++) {
@@ -186,7 +186,7 @@ static void mesh_recalc_looptri__single_threaded(const MLoop *mloop,
uint tri_index = 0;
if (poly_normals != nullptr) {
- for (uint poly_index = 0; poly_index < (uint)totpoly; poly_index++, mp++) {
+ for (uint poly_index = 0; poly_index < uint(totpoly); poly_index++, mp++) {
mesh_calc_tessellation_for_face_with_normal(mloop,
mpoly,
mvert,
@@ -194,14 +194,14 @@ static void mesh_recalc_looptri__single_threaded(const MLoop *mloop,
&mlooptri[tri_index],
&pf_arena,
poly_normals[poly_index]);
- tri_index += (uint)(mp->totloop - 2);
+ tri_index += uint(mp->totloop - 2);
}
}
else {
- for (uint poly_index = 0; poly_index < (uint)totpoly; poly_index++, mp++) {
+ for (uint poly_index = 0; poly_index < uint(totpoly); poly_index++, mp++) {
mesh_calc_tessellation_for_face(
mloop, mpoly, mvert, poly_index, &mlooptri[tri_index], &pf_arena);
- tri_index += (uint)(mp->totloop - 2);
+ tri_index += uint(mp->totloop - 2);
}
}
@@ -209,7 +209,7 @@ static void mesh_recalc_looptri__single_threaded(const MLoop *mloop,
BLI_memarena_free(pf_arena);
pf_arena = nullptr;
}
- BLI_assert(tri_index == (uint)poly_to_tri_count(totpoly, totloop));
+ BLI_assert(tri_index == uint(poly_to_tri_count(totpoly, totloop)));
UNUSED_VARS_NDEBUG(totloop);
}
@@ -239,7 +239,7 @@ static void mesh_calc_tessellation_for_face_fn(void *__restrict userdata,
mesh_calc_tessellation_for_face_impl(data->mloop,
data->mpoly,
data->mvert,
- (uint)index,
+ uint(index),
&data->mlooptri[tri_index],
&tls_data->pf_arena,
false,
@@ -256,14 +256,14 @@ static void mesh_calc_tessellation_for_face_with_normal_fn(void *__restrict user
mesh_calc_tessellation_for_face_impl(data->mloop,
data->mpoly,
data->mvert,
- (uint)index,
+ uint(index),
&data->mlooptri[tri_index],
&tls_data->pf_arena,
true,
data->poly_normals[index]);
}
-static void mesh_calc_tessellation_for_face_free_fn(const void *__restrict UNUSED(userdata),
+static void mesh_calc_tessellation_for_face_free_fn(const void *__restrict /*userdata*/,
void *__restrict tls_v)
{
TessellationUserTLS *tls_data = static_cast<TessellationUserTLS *>(tls_v);
@@ -275,7 +275,7 @@ static void mesh_calc_tessellation_for_face_free_fn(const void *__restrict UNUSE
static void mesh_recalc_looptri__multi_threaded(const MLoop *mloop,
const MPoly *mpoly,
const MVert *mvert,
- int UNUSED(totloop),
+ int /*totloop*/,
int totpoly,
MLoopTri *mlooptri,
const float (*poly_normals)[3])
diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc
index 47de7245ccc..9cd3b6e9e9e 100644
--- a/source/blender/blenkernel/intern/mesh_validate.cc
+++ b/source/blender/blenkernel/intern/mesh_validate.cc
@@ -987,7 +987,7 @@ static bool mesh_validate_customdata(CustomData *data,
}
}
- PRINT_MSG("%s: Finished (is_valid=%d)\n\n", __func__, (int)!has_fixes);
+ PRINT_MSG("%s: Finished (is_valid=%d)\n\n", __func__, int(!has_fixes));
*r_change = has_fixes;
@@ -1315,216 +1315,6 @@ void BKE_mesh_strip_loose_edges(Mesh *me)
/** \name Mesh Edge Calculation
* \{ */
-/* make edges in a Mesh, for outside of editmode */
-
-struct EdgeSort {
- uint v1, v2;
- char is_loose, is_draw;
-};
-
-/* edges have to be added with lowest index first for sorting */
-static void to_edgesort(struct EdgeSort *ed, uint v1, uint v2, char is_loose, short is_draw)
-{
- if (v1 < v2) {
- ed->v1 = v1;
- ed->v2 = v2;
- }
- else {
- ed->v1 = v2;
- ed->v2 = v1;
- }
- ed->is_loose = is_loose;
- ed->is_draw = is_draw;
-}
-
-static int vergedgesort(const void *v1, const void *v2)
-{
- const struct EdgeSort *x1 = static_cast<const struct EdgeSort *>(v1);
- const struct EdgeSort *x2 = static_cast<const struct EdgeSort *>(v2);
-
- if (x1->v1 > x2->v1) {
- return 1;
- }
- if (x1->v1 < x2->v1) {
- return -1;
- }
- if (x1->v2 > x2->v2) {
- return 1;
- }
- if (x1->v2 < x2->v2) {
- return -1;
- }
-
- return 0;
-}
-
-/* Create edges based on known verts and faces,
- * this function is only used when loading very old blend files */
-
-static void mesh_calc_edges_mdata(const MVert *UNUSED(allvert),
- const MFace *allface,
- MLoop *allloop,
- const MPoly *allpoly,
- int UNUSED(totvert),
- int totface,
- int UNUSED(totloop),
- int totpoly,
- const bool use_old,
- MEdge **r_medge,
- int *r_totedge)
-{
- const MPoly *mpoly;
- const MFace *mface;
- MEdge *medge, *med;
- EdgeHash *hash;
- struct EdgeSort *edsort, *ed;
- int a, totedge = 0;
- uint totedge_final = 0;
- uint edge_index;
-
- /* we put all edges in array, sort them, and detect doubles that way */
-
- for (a = totface, mface = allface; a > 0; a--, mface++) {
- if (mface->v4) {
- totedge += 4;
- }
- else if (mface->v3) {
- totedge += 3;
- }
- else {
- totedge += 1;
- }
- }
-
- if (totedge == 0) {
- /* flag that mesh has edges */
- (*r_medge) = (MEdge *)MEM_callocN(0, __func__);
- (*r_totedge) = 0;
- return;
- }
-
- ed = edsort = (EdgeSort *)MEM_mallocN(totedge * sizeof(struct EdgeSort), "EdgeSort");
-
- for (a = totface, mface = allface; a > 0; a--, mface++) {
- to_edgesort(ed++, mface->v1, mface->v2, !mface->v3, mface->edcode & ME_V1V2);
- if (mface->v4) {
- to_edgesort(ed++, mface->v2, mface->v3, 0, mface->edcode & ME_V2V3);
- to_edgesort(ed++, mface->v3, mface->v4, 0, mface->edcode & ME_V3V4);
- to_edgesort(ed++, mface->v4, mface->v1, 0, mface->edcode & ME_V4V1);
- }
- else if (mface->v3) {
- to_edgesort(ed++, mface->v2, mface->v3, 0, mface->edcode & ME_V2V3);
- to_edgesort(ed++, mface->v3, mface->v1, 0, mface->edcode & ME_V3V1);
- }
- }
-
- qsort(edsort, totedge, sizeof(struct EdgeSort), vergedgesort);
-
- /* count final amount */
- for (a = totedge, ed = edsort; a > 1; a--, ed++) {
- /* edge is unique when it differs from next edge, or is last */
- if (ed->v1 != (ed + 1)->v1 || ed->v2 != (ed + 1)->v2) {
- totedge_final++;
- }
- }
- totedge_final++;
-
- medge = (MEdge *)MEM_callocN(sizeof(MEdge) * totedge_final, __func__);
-
- for (a = totedge, med = medge, ed = edsort; a > 1; a--, ed++) {
- /* edge is unique when it differs from next edge, or is last */
- if (ed->v1 != (ed + 1)->v1 || ed->v2 != (ed + 1)->v2) {
- med->v1 = ed->v1;
- med->v2 = ed->v2;
- if (use_old == false || ed->is_draw) {
- med->flag = ME_EDGEDRAW | ME_EDGERENDER;
- }
- if (ed->is_loose) {
- med->flag |= ME_LOOSEEDGE;
- }
-
- /* order is swapped so extruding this edge as a surface won't flip face normals
- * with cyclic curves */
- if (ed->v1 + 1 != ed->v2) {
- SWAP(uint, med->v1, med->v2);
- }
- med++;
- }
- else {
- /* Equal edge, merge the draw-flag. */
- (ed + 1)->is_draw |= ed->is_draw;
- }
- }
- /* last edge */
- med->v1 = ed->v1;
- med->v2 = ed->v2;
- med->flag = ME_EDGEDRAW;
- if (ed->is_loose) {
- med->flag |= ME_LOOSEEDGE;
- }
- med->flag |= ME_EDGERENDER;
-
- MEM_freeN(edsort);
-
- /* set edge members of mloops */
- hash = BLI_edgehash_new_ex(__func__, totedge_final);
- for (edge_index = 0, med = medge; edge_index < totedge_final; edge_index++, med++) {
- BLI_edgehash_insert(hash, med->v1, med->v2, POINTER_FROM_UINT(edge_index));
- }
-
- mpoly = allpoly;
- for (a = 0; a < totpoly; a++, mpoly++) {
- MLoop *ml, *ml_next;
- int i = mpoly->totloop;
-
- ml_next = allloop + mpoly->loopstart; /* first loop */
- ml = &ml_next[i - 1]; /* last loop */
-
- while (i-- != 0) {
- ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(hash, ml->v, ml_next->v));
- ml = ml_next;
- ml_next++;
- }
- }
-
- BLI_edgehash_free(hash, nullptr);
-
- *r_medge = medge;
- *r_totedge = totedge_final;
-}
-
-void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old)
-{
- MEdge *medge;
- int totedge = 0;
- const Span<MVert> verts = me->verts();
- const Span<MPoly> polys = me->polys();
- MutableSpan<MLoop> loops = me->loops_for_write();
-
- mesh_calc_edges_mdata(verts.data(),
- (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
- loops.data(),
- polys.data(),
- verts.size(),
- me->totface,
- loops.size(),
- polys.size(),
- use_old,
- &medge,
- &totedge);
-
- if (totedge == 0) {
- /* flag that mesh has edges */
- me->totedge = 0;
- return;
- }
-
- medge = (MEdge *)CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, totedge);
- me->totedge = totedge;
-
- BKE_mesh_strip_loose_faces(me);
-}
-
void BKE_mesh_calc_edges_loose(Mesh *mesh)
{
const Span<MLoop> loops = mesh->loops();
@@ -1579,7 +1369,7 @@ void BKE_mesh_calc_edges_tessface(Mesh *mesh)
BLI_edgesetIterator_step(ehi), i++, med++, index++) {
BLI_edgesetIterator_getKey(ehi, &med->v1, &med->v2);
- med->flag = ME_EDGEDRAW | ME_EDGERENDER;
+ med->flag = ME_EDGEDRAW;
*index = ORIGINDEX_NONE;
}
BLI_edgesetIterator_free(ehi);
diff --git a/source/blender/blenkernel/intern/mesh_wrapper.cc b/source/blender/blenkernel/intern/mesh_wrapper.cc
index 101fad2fce8..61a95fb4d0e 100644
--- a/source/blender/blenkernel/intern/mesh_wrapper.cc
+++ b/source/blender/blenkernel/intern/mesh_wrapper.cc
@@ -57,13 +57,13 @@ Mesh *BKE_mesh_wrapper_from_editmesh_with_coords(BMEditMesh *em,
BKE_mesh_copy_parameters_for_eval(me, me_settings);
BKE_mesh_runtime_ensure_edit_data(me);
- me->runtime.wrapper_type = ME_WRAPPER_TYPE_BMESH;
+ me->runtime->wrapper_type = ME_WRAPPER_TYPE_BMESH;
if (cd_mask_extra) {
- me->runtime.cd_mask_extra = *cd_mask_extra;
+ me->runtime->cd_mask_extra = *cd_mask_extra;
}
/* Use edit-mesh directly where possible. */
- me->runtime.is_original_bmesh = true;
+ me->runtime->is_original_bmesh = true;
me->edit_mesh = static_cast<BMEditMesh *>(MEM_dupallocN(em));
me->edit_mesh->is_shallow_copy = true;
@@ -81,7 +81,7 @@ Mesh *BKE_mesh_wrapper_from_editmesh_with_coords(BMEditMesh *em,
me->totloop = 0;
#endif
- EditMeshData *edit_data = me->runtime.edit_data;
+ EditMeshData *edit_data = me->runtime->edit_data;
edit_data->vertexCos = vert_coords;
return me;
}
@@ -95,17 +95,14 @@ Mesh *BKE_mesh_wrapper_from_editmesh(BMEditMesh *em,
void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
{
- ThreadMutex *mesh_eval_mutex = (ThreadMutex *)me->runtime.eval_mutex;
- BLI_mutex_lock(mesh_eval_mutex);
-
- if (me->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA) {
- BLI_mutex_unlock(mesh_eval_mutex);
+ std::lock_guard lock{me->runtime->eval_mutex};
+ if (me->runtime->wrapper_type == ME_WRAPPER_TYPE_MDATA) {
return;
}
/* Must isolate multithreaded tasks while holding a mutex lock. */
blender::threading::isolate_task([&]() {
- switch (static_cast<eMeshWrapperType>(me->runtime.wrapper_type)) {
+ switch (static_cast<eMeshWrapperType>(me->runtime->wrapper_type)) {
case ME_WRAPPER_TYPE_MDATA:
case ME_WRAPPER_TYPE_SUBD: {
break; /* Quiet warning. */
@@ -117,10 +114,10 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
me->totloop = 0;
BLI_assert(me->edit_mesh != nullptr);
- BLI_assert(me->runtime.edit_data != nullptr);
+ BLI_assert(me->runtime->edit_data != nullptr);
BMEditMesh *em = me->edit_mesh;
- BM_mesh_bm_to_me_for_eval(em->bm, me, &me->runtime.cd_mask_extra);
+ BM_mesh_bm_to_me_for_eval(em->bm, me, &me->runtime->cd_mask_extra);
/* Adding original index layers assumes that all BMesh mesh wrappers are created from
* original edit mode meshes (the only case where adding original indices makes sense).
@@ -132,32 +129,30 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
* harmful. */
BKE_mesh_ensure_default_orig_index_customdata_no_check(me);
- EditMeshData *edit_data = me->runtime.edit_data;
+ EditMeshData *edit_data = me->runtime->edit_data;
if (edit_data->vertexCos) {
BKE_mesh_vert_coords_apply(me, edit_data->vertexCos);
- me->runtime.is_original_bmesh = false;
+ me->runtime->is_original_bmesh = false;
}
break;
}
}
- if (me->runtime.wrapper_type_finalize) {
- BKE_mesh_wrapper_deferred_finalize_mdata(me, &me->runtime.cd_mask_extra);
+ if (me->runtime->wrapper_type_finalize) {
+ BKE_mesh_wrapper_deferred_finalize_mdata(me, &me->runtime->cd_mask_extra);
}
/* Keep type assignment last, so that read-only access only uses the mdata code paths after all
* the underlying data has been initialized. */
- me->runtime.wrapper_type = ME_WRAPPER_TYPE_MDATA;
+ me->runtime->wrapper_type = ME_WRAPPER_TYPE_MDATA;
});
-
- BLI_mutex_unlock(mesh_eval_mutex);
}
bool BKE_mesh_wrapper_minmax(const Mesh *me, float min[3], float max[3])
{
- switch ((eMeshWrapperType)me->runtime.wrapper_type) {
+ switch (me->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
- return BKE_editmesh_cache_calc_minmax(me->edit_mesh, me->runtime.edit_data, min, max);
+ return BKE_editmesh_cache_calc_minmax(me->edit_mesh, me->runtime->edit_data, min, max);
case ME_WRAPPER_TYPE_MDATA:
case ME_WRAPPER_TYPE_SUBD:
return BKE_mesh_minmax(me, min, max);
@@ -174,11 +169,11 @@ void BKE_mesh_wrapper_vert_coords_copy(const Mesh *me,
float (*vert_coords)[3],
int vert_coords_len)
{
- switch ((eMeshWrapperType)me->runtime.wrapper_type) {
+ switch (me->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH: {
BMesh *bm = me->edit_mesh->bm;
BLI_assert(vert_coords_len <= bm->totvert);
- EditMeshData *edit_data = me->runtime.edit_data;
+ EditMeshData *edit_data = me->runtime->edit_data;
if (edit_data->vertexCos != nullptr) {
for (int i = 0; i < vert_coords_len; i++) {
copy_v3_v3(vert_coords[i], edit_data->vertexCos[i]);
@@ -212,11 +207,11 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *me,
int vert_coords_len,
const float mat[4][4])
{
- switch ((eMeshWrapperType)me->runtime.wrapper_type) {
+ switch (me->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH: {
BMesh *bm = me->edit_mesh->bm;
BLI_assert(vert_coords_len == bm->totvert);
- EditMeshData *edit_data = me->runtime.edit_data;
+ EditMeshData *edit_data = me->runtime->edit_data;
if (edit_data->vertexCos != nullptr) {
for (int i = 0; i < vert_coords_len; i++) {
mul_v3_m4v3(vert_coords[i], mat, edit_data->vertexCos[i]);
@@ -253,7 +248,7 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *me,
int BKE_mesh_wrapper_vert_len(const Mesh *me)
{
- switch ((eMeshWrapperType)me->runtime.wrapper_type) {
+ switch (me->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
return me->edit_mesh->bm->totvert;
case ME_WRAPPER_TYPE_MDATA:
@@ -266,7 +261,7 @@ int BKE_mesh_wrapper_vert_len(const Mesh *me)
int BKE_mesh_wrapper_edge_len(const Mesh *me)
{
- switch ((eMeshWrapperType)me->runtime.wrapper_type) {
+ switch (me->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
return me->edit_mesh->bm->totedge;
case ME_WRAPPER_TYPE_MDATA:
@@ -279,7 +274,7 @@ int BKE_mesh_wrapper_edge_len(const Mesh *me)
int BKE_mesh_wrapper_loop_len(const Mesh *me)
{
- switch ((eMeshWrapperType)me->runtime.wrapper_type) {
+ switch (me->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
return me->edit_mesh->bm->totloop;
case ME_WRAPPER_TYPE_MDATA:
@@ -292,7 +287,7 @@ int BKE_mesh_wrapper_loop_len(const Mesh *me)
int BKE_mesh_wrapper_poly_len(const Mesh *me)
{
- switch ((eMeshWrapperType)me->runtime.wrapper_type) {
+ switch (me->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
return me->edit_mesh->bm->totface;
case ME_WRAPPER_TYPE_MDATA:
@@ -311,7 +306,7 @@ int BKE_mesh_wrapper_poly_len(const Mesh *me)
static Mesh *mesh_wrapper_ensure_subdivision(Mesh *me)
{
- SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)me->runtime.subsurf_runtime_data;
+ SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)me->runtime->subsurf_runtime_data;
if (runtime_data == nullptr || runtime_data->settings.level == 0) {
return me;
}
@@ -359,24 +354,22 @@ static Mesh *mesh_wrapper_ensure_subdivision(Mesh *me)
}
if (subdiv_mesh != me) {
- if (me->runtime.mesh_eval != nullptr) {
- BKE_id_free(nullptr, me->runtime.mesh_eval);
+ if (me->runtime->mesh_eval != nullptr) {
+ BKE_id_free(nullptr, me->runtime->mesh_eval);
}
- me->runtime.mesh_eval = subdiv_mesh;
- me->runtime.wrapper_type = ME_WRAPPER_TYPE_SUBD;
+ me->runtime->mesh_eval = subdiv_mesh;
+ me->runtime->wrapper_type = ME_WRAPPER_TYPE_SUBD;
}
- return me->runtime.mesh_eval;
+ return me->runtime->mesh_eval;
}
Mesh *BKE_mesh_wrapper_ensure_subdivision(Mesh *me)
{
- ThreadMutex *mesh_eval_mutex = (ThreadMutex *)me->runtime.eval_mutex;
- BLI_mutex_lock(mesh_eval_mutex);
+ std::lock_guard lock{me->runtime->eval_mutex};
- if (me->runtime.wrapper_type == ME_WRAPPER_TYPE_SUBD) {
- BLI_mutex_unlock(mesh_eval_mutex);
- return me->runtime.mesh_eval;
+ if (me->runtime->wrapper_type == ME_WRAPPER_TYPE_SUBD) {
+ return me->runtime->mesh_eval;
}
Mesh *result;
@@ -384,7 +377,6 @@ Mesh *BKE_mesh_wrapper_ensure_subdivision(Mesh *me)
/* Must isolate multithreaded tasks while holding a mutex lock. */
blender::threading::isolate_task([&]() { result = mesh_wrapper_ensure_subdivision(me); });
- BLI_mutex_unlock(mesh_eval_mutex);
return result;
}
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.cc
index 60d6b51594a..92a7c778b68 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.cc
@@ -10,12 +10,12 @@
/* Allow using deprecated functionality for .blend file I/O. */
#define DNA_DEPRECATED_ALLOW
-#include <float.h>
-#include <math.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cfloat>
+#include <cmath>
+#include <cstdarg>
+#include <cstddef>
+#include <cstdlib>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -73,7 +73,7 @@
#include "CLG_log.h"
static CLG_LogRef LOG = {"bke.modifier"};
-static ModifierTypeInfo *modifier_types[NUM_MODIFIER_TYPES] = {NULL};
+static ModifierTypeInfo *modifier_types[NUM_MODIFIER_TYPES] = {nullptr};
static VirtualModifierData virtualModifierCommonData;
void BKE_modifier_init(void)
@@ -113,7 +113,7 @@ const ModifierTypeInfo *BKE_modifier_get_info(ModifierType type)
return modifier_types[type];
}
- return NULL;
+ return nullptr;
}
void BKE_modifier_type_panel_id(ModifierType type, char *r_idname)
@@ -131,10 +131,10 @@ void BKE_modifier_panel_expand(ModifierData *md)
/***/
-static ModifierData *modifier_allocate_and_init(int type)
+static ModifierData *modifier_allocate_and_init(ModifierType type)
{
const ModifierTypeInfo *mti = BKE_modifier_get_info(type);
- ModifierData *md = MEM_callocN(mti->structSize, mti->structName);
+ ModifierData *md = static_cast<ModifierData *>(MEM_callocN(mti->structSize, mti->structName));
/* NOTE: this name must be made unique later. */
BLI_strncpy(md->name, DATA_(mti->name), sizeof(md->name));
@@ -158,31 +158,31 @@ static ModifierData *modifier_allocate_and_init(int type)
ModifierData *BKE_modifier_new(int type)
{
- ModifierData *md = modifier_allocate_and_init(type);
+ ModifierData *md = modifier_allocate_and_init(ModifierType(type));
BKE_modifier_session_uuid_generate(md);
return md;
}
-static void modifier_free_data_id_us_cb(void *UNUSED(userData),
- Object *UNUSED(ob),
+static void modifier_free_data_id_us_cb(void * /*userData*/,
+ Object * /*ob*/,
ID **idpoin,
int cb_flag)
{
ID *id = *idpoin;
- if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
+ if (id != nullptr && (cb_flag & IDWALK_CB_USER) != 0) {
id_us_min(id);
}
}
void BKE_modifier_free_ex(ModifierData *md, const int flag)
{
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
if (mti->foreachIDLink) {
- mti->foreachIDLink(md, NULL, modifier_free_data_id_us_cb, NULL);
+ mti->foreachIDLink(md, nullptr, modifier_free_data_id_us_cb, nullptr);
}
}
@@ -207,10 +207,10 @@ void BKE_modifier_remove_from_list(Object *ob, ModifierData *md)
if (md->flag & eModifierFlag_Active) {
/* Prefer the previous modifier but use the next if this modifier is the first in the list. */
- if (md->next != NULL) {
+ if (md->next != nullptr) {
BKE_object_modifier_set_active(ob, md->next);
}
- else if (md->prev != NULL) {
+ else if (md->prev != nullptr) {
BKE_object_modifier_set_active(ob, md->prev);
}
}
@@ -226,7 +226,7 @@ void BKE_modifier_session_uuid_generate(ModifierData *md)
bool BKE_modifier_unique_name(ListBase *modifiers, ModifierData *md)
{
if (modifiers && md) {
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
return BLI_uniquename(
modifiers, md, DATA_(mti->name), '.', offsetof(ModifierData, name), sizeof(md->name));
@@ -236,14 +236,14 @@ bool BKE_modifier_unique_name(ListBase *modifiers, ModifierData *md)
bool BKE_modifier_depends_ontime(Scene *scene, ModifierData *md)
{
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
return mti->dependsOnTime && mti->dependsOnTime(scene, md);
}
bool BKE_modifier_supports_mapping(ModifierData *md)
{
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
return (mti->type == eModifierTypeType_OnlyDeform ||
(mti->flags & eModifierTypeFlag_SupportsMapping));
@@ -251,9 +251,9 @@ bool BKE_modifier_supports_mapping(ModifierData *md)
bool BKE_modifier_is_preview(ModifierData *md)
{
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
- /* Constructive modifiers are highly likely to also modify data like vgroups or vcol! */
+ /* Constructive modifiers are highly likely to also modify data like vgroups or vertex-colors! */
if (!((mti->flags & eModifierTypeFlag_UsesPreview) ||
(mti->type == eModifierTypeType_Constructive))) {
return false;
@@ -273,12 +273,13 @@ ModifierData *BKE_modifiers_findby_type(const Object *ob, ModifierType type)
return md;
}
}
- return NULL;
+ return nullptr;
}
ModifierData *BKE_modifiers_findby_name(const Object *ob, const char *name)
{
- return BLI_findstring(&(ob->modifiers), name, offsetof(ModifierData, name));
+ return static_cast<ModifierData *>(
+ BLI_findstring(&(ob->modifiers), name, offsetof(ModifierData, name)));
}
ModifierData *BKE_modifiers_findby_session_uuid(const Object *ob, const SessionUUID *session_uuid)
@@ -288,7 +289,7 @@ ModifierData *BKE_modifiers_findby_session_uuid(const Object *ob, const SessionU
return md;
}
}
- return NULL;
+ return nullptr;
}
void BKE_modifiers_clear_errors(Object *ob)
@@ -296,7 +297,7 @@ void BKE_modifiers_clear_errors(Object *ob)
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
if (md->error) {
MEM_freeN(md->error);
- md->error = NULL;
+ md->error = nullptr;
}
}
}
@@ -304,7 +305,7 @@ void BKE_modifiers_clear_errors(Object *ob)
void BKE_modifiers_foreach_ID_link(Object *ob, IDWalkFunc walk, void *userData)
{
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
if (mti->foreachIDLink) {
mti->foreachIDLink(md, ob, walk, userData);
@@ -315,7 +316,7 @@ void BKE_modifiers_foreach_ID_link(Object *ob, IDWalkFunc walk, void *userData)
void BKE_modifiers_foreach_tex_link(Object *ob, TexWalkFunc walk, void *userData)
{
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
if (mti->foreachTexLink) {
mti->foreachTexLink(md, ob, walk, userData);
@@ -325,7 +326,7 @@ void BKE_modifiers_foreach_tex_link(Object *ob, TexWalkFunc walk, void *userData
ModifierData *BKE_modifier_copy_ex(const ModifierData *md, int flag)
{
- ModifierData *md_dst = modifier_allocate_and_init(md->type);
+ ModifierData *md_dst = modifier_allocate_and_init(ModifierType(md->type));
BLI_strncpy(md_dst->name, md->name, sizeof(md_dst->name));
BKE_modifier_copydata_ex(md, md_dst, flag);
@@ -335,12 +336,12 @@ ModifierData *BKE_modifier_copy_ex(const ModifierData *md, int flag)
void BKE_modifier_copydata_generic(const ModifierData *md_src,
ModifierData *md_dst,
- const int UNUSED(flag))
+ const int /*flag*/)
{
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md_src->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md_src->type));
- /* md_dst may have already be fully initialized with some extra allocated data,
- * we need to free it now to avoid memleak. */
+ /* `md_dst` may have already be fully initialized with some extra allocated data,
+ * we need to free it now to avoid a memory leak. */
if (mti->freeData) {
mti->freeData(md_dst);
}
@@ -349,26 +350,26 @@ void BKE_modifier_copydata_generic(const ModifierData *md_src,
const char *md_src_data = ((const char *)md_src) + data_size;
char *md_dst_data = ((char *)md_dst) + data_size;
BLI_assert(data_size <= (size_t)mti->structSize);
- memcpy(md_dst_data, md_src_data, (size_t)mti->structSize - data_size);
+ memcpy(md_dst_data, md_src_data, size_t(mti->structSize) - data_size);
/* Runtime fields are never to be preserved. */
- md_dst->runtime = NULL;
+ md_dst->runtime = nullptr;
}
-static void modifier_copy_data_id_us_cb(void *UNUSED(userData),
- Object *UNUSED(ob),
+static void modifier_copy_data_id_us_cb(void * /*userData*/,
+ Object * /*ob*/,
ID **idpoin,
int cb_flag)
{
ID *id = *idpoin;
- if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
+ if (id != nullptr && (cb_flag & IDWALK_CB_USER) != 0) {
id_us_plus(id);
}
}
void BKE_modifier_copydata_ex(const ModifierData *md, ModifierData *target, const int flag)
{
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
target->mode = md->mode;
target->flag = md->flag;
@@ -380,7 +381,7 @@ void BKE_modifier_copydata_ex(const ModifierData *md, ModifierData *target, cons
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
if (mti->foreachIDLink) {
- mti->foreachIDLink(target, NULL, modifier_copy_data_id_us_cb, NULL);
+ mti->foreachIDLink(target, nullptr, modifier_copy_data_id_us_cb, nullptr);
}
}
@@ -403,30 +404,30 @@ void BKE_modifier_copydata(const ModifierData *md, ModifierData *target)
bool BKE_modifier_supports_cage(struct Scene *scene, ModifierData *md)
{
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
- return ((!mti->isDisabled || !mti->isDisabled(scene, md, 0)) &&
+ return ((!mti->isDisabled || !mti->isDisabled(scene, md, false)) &&
(mti->flags & eModifierTypeFlag_SupportsEditmode) && BKE_modifier_supports_mapping(md));
}
bool BKE_modifier_couldbe_cage(struct Scene *scene, ModifierData *md)
{
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
return ((md->mode & eModifierMode_Realtime) && (md->mode & eModifierMode_Editmode) &&
- (!mti->isDisabled || !mti->isDisabled(scene, md, 0)) &&
+ (!mti->isDisabled || !mti->isDisabled(scene, md, false)) &&
BKE_modifier_supports_mapping(md));
}
bool BKE_modifier_is_same_topology(ModifierData *md)
{
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
return ELEM(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_NonGeometrical);
}
bool BKE_modifier_is_non_geometrical(ModifierData *md)
{
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
return (mti->type == eModifierTypeType_NonGeometrical);
}
@@ -450,7 +451,7 @@ void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *_for
#ifndef NDEBUG
if ((md->mode & eModifierMode_Virtual) == 0) {
/* Ensure correct object is passed in. */
- BLI_assert(BKE_modifier_get_original(ob, md) != NULL);
+ BLI_assert(BKE_modifier_get_original(ob, md) != nullptr);
}
#endif
@@ -484,7 +485,7 @@ void BKE_modifier_set_warning(const struct Object *ob,
#ifndef NDEBUG
if ((md->mode & eModifierMode_Virtual) == 0) {
/* Ensure correct object is passed in. */
- BLI_assert(BKE_modifier_get_original(ob, md) != NULL);
+ BLI_assert(BKE_modifier_get_original(ob, md) != nullptr);
}
#endif
@@ -499,7 +500,7 @@ int BKE_modifiers_get_cage_index(const Scene *scene,
VirtualModifierData virtualModifierData;
ModifierData *md = (is_virtual) ?
BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData) :
- ob->modifiers.first;
+ static_cast<ModifierData *>(ob->modifiers.first);
if (r_lastPossibleCageIndex) {
/* ensure the value is initialized */
@@ -509,10 +510,10 @@ int BKE_modifiers_get_cage_index(const Scene *scene,
/* Find the last modifier acting on the cage. */
int cageIndex = -1;
for (int i = 0; md; i++, md = md->next) {
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
bool supports_mapping;
- if (mti->isDisabled && mti->isDisabled(scene, md, 0)) {
+ if (mti->isDisabled && mti->isDisabled(scene, md, false)) {
continue;
}
if (!(mti->flags & eModifierTypeFlag_SupportsEditmode)) {
@@ -562,7 +563,7 @@ bool BKE_modifiers_is_cloth_enabled(Object *ob)
bool BKE_modifiers_is_modifier_enabled(Object *ob, int modifierType)
{
- ModifierData *md = BKE_modifiers_findby_type(ob, modifierType);
+ ModifierData *md = BKE_modifiers_findby_type(ob, ModifierType(modifierType));
return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
}
@@ -576,12 +577,12 @@ bool BKE_modifiers_is_particle_enabled(Object *ob)
bool BKE_modifier_is_enabled(const struct Scene *scene, ModifierData *md, int required_mode)
{
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
if ((md->mode & required_mode) != required_mode) {
return false;
}
- if (scene != NULL && mti->isDisabled &&
+ if (scene != nullptr && mti->isDisabled &&
mti->isDisabled(scene, md, required_mode == eModifierMode_Render)) {
return false;
}
@@ -599,26 +600,25 @@ bool BKE_modifier_is_enabled(const struct Scene *scene, ModifierData *md, int re
bool BKE_modifier_is_nonlocal_in_liboverride(const Object *ob, const ModifierData *md)
{
return (ID_IS_OVERRIDE_LIBRARY(ob) &&
- (md == NULL || (md->flag & eModifierFlag_OverrideLibrary_Local) == 0));
+ (md == nullptr || (md->flag & eModifierFlag_OverrideLibrary_Local) == 0));
}
CDMaskLink *BKE_modifier_calc_data_masks(const struct Scene *scene,
- Object *ob,
ModifierData *md,
CustomData_MeshMasks *final_datamask,
int required_mode,
ModifierData *previewmd,
const CustomData_MeshMasks *previewmask)
{
- CDMaskLink *dataMasks = NULL;
+ CDMaskLink *dataMasks = nullptr;
CDMaskLink *curr, *prev;
bool have_deform_modifier = false;
/* build a list of modifier data requirements in reverse order */
for (; md; md = md->next) {
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
- curr = MEM_callocN(sizeof(CDMaskLink), "CDMaskLink");
+ curr = MEM_cnew<CDMaskLink>(__func__);
if (BKE_modifier_is_enabled(scene, md, required_mode)) {
if (mti->type == eModifierTypeType_OnlyDeform) {
@@ -626,10 +626,10 @@ CDMaskLink *BKE_modifier_calc_data_masks(const struct Scene *scene,
}
if (mti->requiredDataMask) {
- mti->requiredDataMask(ob, md, &curr->mask);
+ mti->requiredDataMask(md, &curr->mask);
}
- if (previewmd == md && previewmask != NULL) {
+ if (previewmd == md && previewmask != nullptr) {
CustomData_MeshMasks_update(&curr->mask, previewmask);
}
}
@@ -655,7 +655,7 @@ CDMaskLink *BKE_modifier_calc_data_masks(const struct Scene *scene,
* note the list is currently in reverse order, so "masks that follow it"
* actually means "masks that precede it" at the moment
*/
- for (curr = dataMasks, prev = NULL; curr; prev = curr, curr = curr->next) {
+ for (curr = dataMasks, prev = nullptr; curr; prev = curr, curr = curr->next) {
if (prev) {
CustomData_MeshMasks_update(&curr->mask, &prev->mask);
}
@@ -674,7 +674,7 @@ ModifierData *BKE_modifier_get_last_preview(const struct Scene *scene,
ModifierData *md,
int required_mode)
{
- ModifierData *tmp_md = NULL;
+ ModifierData *tmp_md = nullptr;
if ((required_mode & ~eModifierMode_Editmode) != eModifierMode_Realtime) {
return tmp_md;
@@ -692,7 +692,7 @@ ModifierData *BKE_modifier_get_last_preview(const struct Scene *scene,
ModifierData *BKE_modifiers_get_virtual_modifierlist(const Object *ob,
VirtualModifierData *virtualModifierData)
{
- ModifierData *md = ob->modifiers.first;
+ ModifierData *md = static_cast<ModifierData *>(ob->modifiers.first);
*virtualModifierData = virtualModifierCommonData;
@@ -736,7 +736,7 @@ Object *BKE_modifiers_is_deformed_by_armature(Object *ob)
{
if (ob->type == OB_GPENCIL) {
GpencilVirtualModifierData gpencilvirtualModifierData;
- ArmatureGpencilModifierData *agmd = NULL;
+ ArmatureGpencilModifierData *agmd = nullptr;
GpencilModifierData *gmd = BKE_gpencil_modifiers_get_virtual_modifierlist(
ob, &gpencilvirtualModifierData);
@@ -756,7 +756,7 @@ Object *BKE_modifiers_is_deformed_by_armature(Object *ob)
}
else {
VirtualModifierData virtualModifierData;
- ArmatureModifierData *amd = NULL;
+ ArmatureModifierData *amd = nullptr;
ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
/* return the first selected armature, this lets us use multiple armatures */
@@ -774,14 +774,14 @@ Object *BKE_modifiers_is_deformed_by_armature(Object *ob)
}
}
- return NULL;
+ return nullptr;
}
Object *BKE_modifiers_is_deformed_by_meshdeform(Object *ob)
{
VirtualModifierData virtualModifierData;
ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
- MeshDeformModifierData *mdmd = NULL;
+ MeshDeformModifierData *mdmd = nullptr;
/* return the first selected armature, this lets us use multiple armatures */
for (; md; md = md->next) {
@@ -797,14 +797,14 @@ Object *BKE_modifiers_is_deformed_by_meshdeform(Object *ob)
return mdmd->object;
}
- return NULL;
+ return nullptr;
}
Object *BKE_modifiers_is_deformed_by_lattice(Object *ob)
{
VirtualModifierData virtualModifierData;
ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
- LatticeModifierData *lmd = NULL;
+ LatticeModifierData *lmd = nullptr;
/* return the first selected lattice, this lets us use multiple lattices */
for (; md; md = md->next) {
@@ -820,14 +820,14 @@ Object *BKE_modifiers_is_deformed_by_lattice(Object *ob)
return lmd->object;
}
- return NULL;
+ return nullptr;
}
Object *BKE_modifiers_is_deformed_by_curve(Object *ob)
{
VirtualModifierData virtualModifierData;
ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
- CurveModifierData *cmd = NULL;
+ CurveModifierData *cmd = nullptr;
/* return the first selected curve, this lets us use multiple curves */
for (; md; md = md->next) {
@@ -843,14 +843,14 @@ Object *BKE_modifiers_is_deformed_by_curve(Object *ob)
return cmd->object;
}
- return NULL;
+ return nullptr;
}
bool BKE_modifiers_uses_multires(Object *ob)
{
VirtualModifierData virtualModifierData;
ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
- MultiresModifierData *mmd = NULL;
+ MultiresModifierData *mmd = nullptr;
for (; md; md = md->next) {
if (md->type == eModifierType_Multires) {
@@ -882,8 +882,8 @@ bool BKE_modifiers_uses_armature(Object *ob, bArmature *arm)
bool BKE_modifier_is_correctable_deformed(ModifierData *md)
{
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
- return mti->deformMatricesEM != NULL;
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
+ return mti->deformMatricesEM != nullptr;
}
bool BKE_modifiers_is_correctable_deformed(const struct Scene *scene, Object *ob)
@@ -917,8 +917,6 @@ void BKE_modifier_free_temporary_data(ModifierData *md)
void BKE_modifiers_test_object(Object *ob)
{
- ModifierData *md;
-
/* just multires checked for now, since only multires
* modifies mesh data */
@@ -926,7 +924,7 @@ void BKE_modifiers_test_object(Object *ob)
return;
}
- for (md = ob->modifiers.first; md; md = md->next) {
+ LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
if (md->type == eModifierType_Multires) {
MultiresModifierData *mmd = (MultiresModifierData *)md;
@@ -957,7 +955,7 @@ const char *BKE_modifier_path_relbase_from_global(Object *ob)
void BKE_modifier_path_init(char *path, int path_maxlen, const char *name)
{
const char *blendfile_path = BKE_main_blendfile_path_from_global();
- BLI_join_dirfile(path, path_maxlen, blendfile_path[0] ? "//" : BKE_tempdir_session(), name);
+ BLI_path_join(path, path_maxlen, blendfile_path[0] ? "//" : BKE_tempdir_session(), name);
}
/**
@@ -965,9 +963,9 @@ void BKE_modifier_path_init(char *path, int path_maxlen, const char *name)
*/
static void modwrap_dependsOnNormals(Mesh *me)
{
- switch ((eMeshWrapperType)me->runtime.wrapper_type) {
+ switch (me->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH: {
- EditMeshData *edit_data = me->runtime.edit_data;
+ EditMeshData *edit_data = me->runtime->edit_data;
if (edit_data->vertexCos) {
/* Note that 'ensure' is acceptable here since these values aren't modified in-place.
* If that changes we'll need to recalculate. */
@@ -993,9 +991,9 @@ struct Mesh *BKE_modifier_modify_mesh(ModifierData *md,
const ModifierEvalContext *ctx,
struct Mesh *me)
{
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
- if (me->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
+ if (me->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
if ((mti->flags & eModifierTypeFlag_AcceptsBMesh) == 0) {
BKE_mesh_wrapper_ensure_mdata(me);
}
@@ -1013,7 +1011,7 @@ void BKE_modifier_deform_verts(ModifierData *md,
float (*vertexCos)[3],
int numVerts)
{
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
if (me && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
modwrap_dependsOnNormals(me);
}
@@ -1027,7 +1025,7 @@ void BKE_modifier_deform_vertsEM(ModifierData *md,
float (*vertexCos)[3],
int numVerts)
{
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
if (me && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
modwrap_dependsOnNormals(me);
}
@@ -1038,17 +1036,17 @@ void BKE_modifier_deform_vertsEM(ModifierData *md,
Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval)
{
- Mesh *me = NULL;
+ Mesh *me = nullptr;
if ((ob_eval->type == OB_MESH) && (ob_eval->mode & OB_MODE_EDIT)) {
/* In EditMode, evaluated mesh is stored in BMEditMesh, not the object... */
BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
/* 'em' might not exist yet in some cases, just after loading a .blend file, see T57878. */
- if (em != NULL) {
+ if (em != nullptr) {
me = BKE_object_get_editmesh_eval_final(ob_eval);
}
}
- if (me == NULL) {
+ if (me == nullptr) {
me = BKE_object_get_evaluated_mesh(ob_eval);
}
@@ -1084,7 +1082,7 @@ void BKE_modifier_check_uuids_unique_and_report(const Object *object)
continue;
}
- if (BLI_gset_lookup(used_uuids, session_uuid) != NULL) {
+ if (BLI_gset_lookup(used_uuids, session_uuid) != nullptr) {
printf("Modifier %s -> %s has duplicate UUID generated.\n", object->id.name + 2, md->name);
continue;
}
@@ -1092,23 +1090,23 @@ void BKE_modifier_check_uuids_unique_and_report(const Object *object)
BLI_gset_insert(used_uuids, (void *)session_uuid);
}
- BLI_gset_free(used_uuids, NULL);
+ BLI_gset_free(used_uuids, nullptr);
}
void BKE_modifier_blend_write(BlendWriter *writer, const ID *id_owner, ListBase *modbase)
{
- if (modbase == NULL) {
+ if (modbase == nullptr) {
return;
}
LISTBASE_FOREACH (ModifierData *, md, modbase) {
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
- if (mti == NULL) {
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
+ if (mti == nullptr) {
continue;
}
/* If the blendWrite callback is defined, it should handle the whole writing process. */
- if (mti->blendWrite != NULL) {
+ if (mti->blendWrite != nullptr) {
mti->blendWrite(writer, id_owner, md);
continue;
}
@@ -1145,7 +1143,7 @@ void BKE_modifier_blend_write(BlendWriter *writer, const ID *id_owner, ListBase
/* cleanup the fake pointcache */
BKE_ptcache_free_list(&fmd->domain->ptcaches[1]);
- fmd->domain->point_cache[1] = NULL;
+ fmd->domain->point_cache[1] = nullptr;
BLO_write_struct(writer, EffectorWeights, fmd->domain->effector_weights);
}
@@ -1231,8 +1229,8 @@ static ModifierData *modifier_replace_with_fluid(BlendDataReader *reader,
if (old_modifier_data->type == eModifierType_Fluidsim) {
FluidsimModifierData *old_fluidsim_modifier_data = (FluidsimModifierData *)old_modifier_data;
- FluidsimSettings *old_fluidsim_settings = BLO_read_get_new_data_address(
- reader, old_fluidsim_modifier_data->fss);
+ FluidsimSettings *old_fluidsim_settings = static_cast<FluidsimSettings *>(
+ BLO_read_get_new_data_address(reader, old_fluidsim_modifier_data->fss));
switch (old_fluidsim_settings->type) {
case OB_FLUIDSIM_ENABLE:
modifier_ensure_type(fluid_modifier_data, 0);
@@ -1296,10 +1294,10 @@ static ModifierData *modifier_replace_with_fluid(BlendDataReader *reader,
/* Replace modifier data in the stack. */
new_modifier_data->next = old_modifier_data->next;
new_modifier_data->prev = old_modifier_data->prev;
- if (new_modifier_data->prev != NULL) {
+ if (new_modifier_data->prev != nullptr) {
new_modifier_data->prev->next = new_modifier_data;
}
- if (new_modifier_data->next != NULL) {
+ if (new_modifier_data->next != nullptr) {
new_modifier_data->next->prev = new_modifier_data;
}
if (modifiers->first == old_modifier_data) {
@@ -1322,8 +1320,8 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
LISTBASE_FOREACH (ModifierData *, md, lb) {
BKE_modifier_session_uuid_generate(md);
- md->error = NULL;
- md->runtime = NULL;
+ md->error = nullptr;
+ md->runtime = nullptr;
/* Modifier data has been allocated as a part of data migration process and
* no reading of nested fields from file is needed. */
@@ -1350,10 +1348,10 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
is_allocated = true;
}
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
/* if modifiers disappear, or for upward compatibility */
- if (mti == NULL) {
+ if (mti == nullptr) {
md->type = eModifierType_None;
}
@@ -1363,8 +1361,8 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
else if (md->type == eModifierType_Cloth) {
ClothModifierData *clmd = (ClothModifierData *)md;
- clmd->clothObject = NULL;
- clmd->hairdata = NULL;
+ clmd->clothObject = nullptr;
+ clmd->hairdata = nullptr;
BLO_read_data_address(reader, &clmd->sim_parms);
BLO_read_data_address(reader, &clmd->coll_parms);
@@ -1381,40 +1379,40 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
BLO_read_data_address(reader, &clmd->sim_parms->effector_weights);
if (!clmd->sim_parms->effector_weights) {
- clmd->sim_parms->effector_weights = BKE_effector_add_weights(NULL);
+ clmd->sim_parms->effector_weights = BKE_effector_add_weights(nullptr);
}
}
- clmd->solver_result = NULL;
+ clmd->solver_result = nullptr;
}
else if (md->type == eModifierType_Fluid) {
FluidModifierData *fmd = (FluidModifierData *)md;
if (fmd->type == MOD_FLUID_TYPE_DOMAIN) {
- fmd->flow = NULL;
- fmd->effector = NULL;
+ fmd->flow = nullptr;
+ fmd->effector = nullptr;
BLO_read_data_address(reader, &fmd->domain);
fmd->domain->fmd = fmd;
- fmd->domain->fluid = NULL;
+ fmd->domain->fluid = nullptr;
fmd->domain->fluid_mutex = BLI_rw_mutex_alloc();
- fmd->domain->tex_density = NULL;
- fmd->domain->tex_color = NULL;
- fmd->domain->tex_shadow = NULL;
- fmd->domain->tex_flame = NULL;
- fmd->domain->tex_flame_coba = NULL;
- fmd->domain->tex_coba = NULL;
- fmd->domain->tex_field = NULL;
- fmd->domain->tex_velocity_x = NULL;
- fmd->domain->tex_velocity_y = NULL;
- fmd->domain->tex_velocity_z = NULL;
- fmd->domain->tex_wt = NULL;
+ fmd->domain->tex_density = nullptr;
+ fmd->domain->tex_color = nullptr;
+ fmd->domain->tex_shadow = nullptr;
+ fmd->domain->tex_flame = nullptr;
+ fmd->domain->tex_flame_coba = nullptr;
+ fmd->domain->tex_coba = nullptr;
+ fmd->domain->tex_field = nullptr;
+ fmd->domain->tex_velocity_x = nullptr;
+ fmd->domain->tex_velocity_y = nullptr;
+ fmd->domain->tex_velocity_z = nullptr;
+ fmd->domain->tex_wt = nullptr;
BLO_read_data_address(reader, &fmd->domain->coba);
BLO_read_data_address(reader, &fmd->domain->effector_weights);
if (!fmd->domain->effector_weights) {
- fmd->domain->effector_weights = BKE_effector_add_weights(NULL);
+ fmd->domain->effector_weights = BKE_effector_add_weights(nullptr);
}
BKE_ptcache_blend_read_data(
@@ -1423,7 +1421,8 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
/* Manta sim uses only one cache from now on, so store pointer convert */
if (fmd->domain->ptcaches[1].first || fmd->domain->point_cache[1]) {
if (fmd->domain->point_cache[1]) {
- PointCache *cache = BLO_read_get_new_data_address(reader, fmd->domain->point_cache[1]);
+ PointCache *cache = static_cast<PointCache *>(
+ BLO_read_get_new_data_address(reader, fmd->domain->point_cache[1]));
if (cache->flag & PTCACHE_FAKE_SMOKE) {
/* Manta-sim/smoke was already saved in "new format" and this cache is a fake one. */
}
@@ -1435,34 +1434,34 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
BKE_ptcache_free(cache);
}
BLI_listbase_clear(&fmd->domain->ptcaches[1]);
- fmd->domain->point_cache[1] = NULL;
+ fmd->domain->point_cache[1] = nullptr;
}
}
else if (fmd->type == MOD_FLUID_TYPE_FLOW) {
- fmd->domain = NULL;
- fmd->effector = NULL;
+ fmd->domain = nullptr;
+ fmd->effector = nullptr;
BLO_read_data_address(reader, &fmd->flow);
fmd->flow->fmd = fmd;
- fmd->flow->mesh = NULL;
- fmd->flow->verts_old = NULL;
+ fmd->flow->mesh = nullptr;
+ fmd->flow->verts_old = nullptr;
fmd->flow->numverts = 0;
BLO_read_data_address(reader, &fmd->flow->psys);
}
else if (fmd->type == MOD_FLUID_TYPE_EFFEC) {
- fmd->flow = NULL;
- fmd->domain = NULL;
+ fmd->flow = nullptr;
+ fmd->domain = nullptr;
BLO_read_data_address(reader, &fmd->effector);
if (fmd->effector) {
fmd->effector->fmd = fmd;
- fmd->effector->verts_old = NULL;
+ fmd->effector->verts_old = nullptr;
fmd->effector->numverts = 0;
- fmd->effector->mesh = NULL;
+ fmd->effector->mesh = nullptr;
}
else {
fmd->type = 0;
- fmd->flow = NULL;
- fmd->domain = NULL;
- fmd->effector = NULL;
+ fmd->flow = nullptr;
+ fmd->domain = nullptr;
+ fmd->effector = nullptr;
}
}
}
@@ -1479,12 +1478,12 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
LISTBASE_FOREACH (DynamicPaintSurface *, surface, &pmd->canvas->surfaces) {
surface->canvas = pmd->canvas;
- surface->data = NULL;
+ surface->data = nullptr;
BKE_ptcache_blend_read_data(reader, &(surface->ptcaches), &(surface->pointcache), 1);
BLO_read_data_address(reader, &surface->effector_weights);
- if (surface->effector_weights == NULL) {
- surface->effector_weights = BKE_effector_add_weights(NULL);
+ if (surface->effector_weights == nullptr) {
+ surface->effector_weights = BKE_effector_add_weights(nullptr);
}
}
}
@@ -1498,7 +1497,7 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
}
}
- if ((mti != NULL) && (mti->blendRead != NULL)) {
+ if ((mti != nullptr) && (mti->blendRead != nullptr)) {
mti->blendRead(reader, md);
}
}
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 46e05b39076..58c3ef3bba0 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -357,7 +357,7 @@ IDTypeInfo IDType_ID_MC = {
/*********************** movieclip buffer loaders *************************/
-static int sequence_guess_offset(const char *full_name, int head_len, unsigned short numlen)
+static int sequence_guess_offset(const char *full_name, int head_len, ushort numlen)
{
char num[FILE_MAX] = {0};
@@ -425,7 +425,7 @@ static int get_timecode(MovieClip *clip, int flag)
static void get_sequence_fname(const MovieClip *clip, const int framenr, char *name)
{
- unsigned short numlen;
+ ushort numlen;
char head[FILE_MAX], tail[FILE_MAX];
int offset;
@@ -647,7 +647,7 @@ static void movieclip_calc_length(MovieClip *clip)
}
}
else if (clip->source == MCLIP_SRC_SEQUENCE) {
- unsigned short numlen;
+ ushort numlen;
char name[FILE_MAX], head[FILE_MAX], tail[FILE_MAX];
BLI_path_sequence_decode(clip->filepath, head, tail, &numlen);
@@ -735,7 +735,7 @@ static int user_frame_to_cache_frame(MovieClip *clip, int framenr)
if (clip->source == MCLIP_SRC_SEQUENCE) {
if (clip->cache->sequence_offset == -1) {
- unsigned short numlen;
+ ushort numlen;
char head[FILE_MAX], tail[FILE_MAX];
BLI_path_sequence_decode(clip->filepath, head, tail, &numlen);
@@ -763,7 +763,7 @@ static void moviecache_keydata(void *userkey, int *framenr, int *proxy, int *ren
*render_flags = key->render_flag;
}
-static unsigned int moviecache_hashhash(const void *keyv)
+static uint moviecache_hashhash(const void *keyv)
{
const MovieClipImBufCacheKey *key = keyv;
int rval = key->framenr;
@@ -880,7 +880,7 @@ static bool put_imbuf_cache(
clip->cache->moviecache = moviecache;
clip->cache->sequence_offset = -1;
if (clip->source == MCLIP_SRC_SEQUENCE) {
- unsigned short numlen;
+ ushort numlen;
BLI_path_sequence_decode(clip->filepath, NULL, NULL, &numlen);
clip->cache->is_still_sequence = (numlen == 0);
}
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.cc
index 7dc7e6009d9..5ff9602650e 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.cc
@@ -43,8 +43,8 @@
#include "multires_reshape.h"
-#include <math.h>
-#include <string.h>
+#include <cmath>
+#include <cstring>
/* MULTIRES MODIFIER */
static const int multires_grid_tot[] = {
@@ -53,24 +53,24 @@ static const int multires_side_tot[] = {
0, 2, 3, 5, 9, 17, 33, 65, 129, 257, 513, 1025, 2049, 4097};
/* See multiresModifier_disp_run for description of each operation */
-typedef enum {
+enum DispOp {
APPLY_DISPLACEMENTS,
CALC_DISPLACEMENTS,
ADD_DISPLACEMENTS,
-} DispOp;
+};
static void multiresModifier_disp_run(
DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, CCGElem **oldGridData, int totlvl);
-/** Customdata */
+/** Custom-data. */
void multires_customdata_delete(Mesh *me)
{
if (me->edit_mesh) {
BMEditMesh *em = me->edit_mesh;
/* CustomData_external_remove is used here only to mark layer
- * as non-external for further free-ing, so zero element count
- * looks safer than em->totface */
+ * as non-external for further freeing, so zero element count
+ * looks safer than `em->bm->totface`. */
CustomData_external_remove(&em->bm->ldata, &me->id, CD_MDISPS, 0);
if (CustomData_has_layer(&em->bm->ldata, CD_MDISPS)) {
@@ -107,7 +107,7 @@ static BLI_bitmap *multires_mdisps_upsample_hidden(BLI_bitmap *lo_hidden,
/* fast case */
if (lo_level == hi_level) {
- return MEM_dupallocN(lo_hidden);
+ return static_cast<BLI_bitmap *>(MEM_dupallocN(lo_hidden));
}
subd = BLI_BITMAP_NEW(square_i(hi_gridsize), "MDisps.hidden upsample");
@@ -184,7 +184,7 @@ static BLI_bitmap *multires_mdisps_downsample_hidden(const BLI_bitmap *old_hidde
static void multires_output_hidden_to_ccgdm(CCGDerivedMesh *ccgdm, Mesh *me, int level)
{
const MPoly *polys = BKE_mesh_polys(me);
- const MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
+ const MDisps *mdisps = static_cast<const MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
BLI_bitmap **grid_hidden = ccgdm->gridHidden;
int *gridOffset;
int i, j;
@@ -217,7 +217,7 @@ static void multires_mdisps_subdivide_hidden(MDisps *md, int new_level)
return;
}
- subd = multires_mdisps_upsample_hidden(md->hidden, md->level, new_level, NULL);
+ subd = multires_mdisps_upsample_hidden(md->hidden, md->level, new_level, nullptr);
/* swap in the subdivided data */
MEM_freeN(md->hidden);
@@ -232,13 +232,12 @@ Mesh *BKE_multires_create_mesh(struct Depsgraph *depsgraph,
Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
Mesh *deformed_mesh = mesh_get_eval_deform(
depsgraph, scene_eval, object_eval, &CD_MASK_BAREMESH);
- ModifierEvalContext modifier_ctx = {
- .depsgraph = depsgraph,
- .object = object_eval,
- .flag = MOD_APPLY_USECACHE | MOD_APPLY_IGNORE_SIMPLIFY,
- };
+ ModifierEvalContext modifier_ctx{};
+ modifier_ctx.depsgraph = depsgraph;
+ modifier_ctx.object = object_eval;
+ modifier_ctx.flag = MOD_APPLY_USECACHE | MOD_APPLY_IGNORE_SIMPLIFY;
- const ModifierTypeInfo *mti = BKE_modifier_get_info(mmd->modifier.type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(mmd->modifier.type));
Mesh *result = mti->modifyMesh(&mmd->modifier, &modifier_ctx, deformed_mesh);
if (result == deformed_mesh) {
@@ -255,12 +254,12 @@ float (*BKE_multires_create_deformed_base_mesh_vert_coords(struct Depsgraph *dep
Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
- Object object_for_eval = *object_eval;
+ Object object_for_eval = blender::dna::shallow_copy(*object_eval);
object_for_eval.data = object->data;
- object_for_eval.sculpt = NULL;
+ object_for_eval.sculpt = nullptr;
const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
- ModifierEvalContext mesh_eval_context = {depsgraph, &object_for_eval, 0};
+ ModifierEvalContext mesh_eval_context = {depsgraph, &object_for_eval, ModifierApplyFlag(0)};
if (use_render) {
mesh_eval_context.flag |= MOD_APPLY_RENDER;
}
@@ -270,13 +269,13 @@ float (*BKE_multires_create_deformed_base_mesh_vert_coords(struct Depsgraph *dep
ModifierData *first_md = BKE_modifiers_get_virtual_modifierlist(&object_for_eval,
&virtual_modifier_data);
- Mesh *base_mesh = object->data;
+ Mesh *base_mesh = static_cast<Mesh *>(object->data);
int num_deformed_verts;
float(*deformed_verts)[3] = BKE_mesh_vert_coords_alloc(base_mesh, &num_deformed_verts);
- for (ModifierData *md = first_md; md != NULL; md = md->next) {
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ for (ModifierData *md = first_md; md != nullptr; md = md->next) {
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
if (md == &mmd->modifier) {
break;
@@ -294,7 +293,7 @@ float (*BKE_multires_create_deformed_base_mesh_vert_coords(struct Depsgraph *dep
md, &mesh_eval_context, base_mesh, deformed_verts, num_deformed_verts);
}
- if (r_num_deformed_verts != NULL) {
+ if (r_num_deformed_verts != nullptr) {
*r_num_deformed_verts = num_deformed_verts;
}
return deformed_verts;
@@ -312,16 +311,15 @@ MultiresModifierData *find_multires_modifier_before(Scene *scene, ModifierData *
}
}
- return NULL;
+ return nullptr;
}
MultiresModifierData *get_multires_modifier(Scene *scene, Object *ob, bool use_first)
{
- ModifierData *md;
- MultiresModifierData *mmd = NULL, *firstmmd = NULL;
+ MultiresModifierData *mmd = nullptr, *firstmmd = nullptr;
/* find first active multires modifier */
- for (md = ob->modifiers.first; md; md = md->next) {
+ LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
if (md->type == eModifierType_Multires) {
if (!firstmmd) {
firstmmd = (MultiresModifierData *)md;
@@ -350,8 +348,8 @@ int multires_get_level(const Scene *scene,
bool ignore_simplify)
{
if (render) {
- return (scene != NULL) ? get_render_subsurf_level(&scene->r, mmd->renderlvl, true) :
- mmd->renderlvl;
+ return (scene != nullptr) ? get_render_subsurf_level(&scene->r, mmd->renderlvl, true) :
+ mmd->renderlvl;
}
if (ob->mode == OB_MODE_SCULPT) {
return mmd->sculptlvl;
@@ -360,7 +358,7 @@ int multires_get_level(const Scene *scene,
return mmd->lvl;
}
- return (scene != NULL) ? get_render_subsurf_level(&scene->r, mmd->lvl, false) : mmd->lvl;
+ return (scene != nullptr) ? get_render_subsurf_level(&scene->r, mmd->lvl, false) : mmd->lvl;
}
void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl)
@@ -387,7 +385,7 @@ static void multires_ccg_mark_as_modified(SubdivCCG *subdiv_ccg, MultiresModifie
void multires_mark_as_modified(Depsgraph *depsgraph, Object *object, MultiresModifiedFlags flags)
{
- if (object == NULL) {
+ if (object == nullptr) {
return;
}
/* NOTE: CCG live inside of evaluated object.
@@ -398,9 +396,9 @@ void multires_mark_as_modified(Depsgraph *depsgraph, Object *object, MultiresMod
*
* In a longer term maybe special dependency graph tag can help sanitizing this a bit. */
Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
- Mesh *mesh = object_eval->data;
- SubdivCCG *subdiv_ccg = mesh->runtime.subdiv_ccg;
- if (subdiv_ccg == NULL) {
+ Mesh *mesh = static_cast<Mesh *>(object_eval->data);
+ SubdivCCG *subdiv_ccg = mesh->runtime->subdiv_ccg;
+ if (subdiv_ccg == nullptr) {
return;
}
multires_ccg_mark_as_modified(subdiv_ccg, flags);
@@ -408,18 +406,18 @@ void multires_mark_as_modified(Depsgraph *depsgraph, Object *object, MultiresMod
void multires_flush_sculpt_updates(Object *object)
{
- if (object == NULL || object->sculpt == NULL || object->sculpt->pbvh == NULL) {
+ if (object == nullptr || object->sculpt == nullptr || object->sculpt->pbvh == nullptr) {
return;
}
SculptSession *sculpt_session = object->sculpt;
if (BKE_pbvh_type(sculpt_session->pbvh) != PBVH_GRIDS || !sculpt_session->multires.active ||
- sculpt_session->multires.modifier == NULL) {
+ sculpt_session->multires.modifier == nullptr) {
return;
}
SubdivCCG *subdiv_ccg = sculpt_session->subdiv_ccg;
- if (subdiv_ccg == NULL) {
+ if (subdiv_ccg == nullptr) {
return;
}
@@ -427,7 +425,7 @@ void multires_flush_sculpt_updates(Object *object)
return;
}
- Mesh *mesh = object->data;
+ Mesh *mesh = static_cast<Mesh *>(object->data);
multiresModifier_reshapeFromCCG(
sculpt_session->multires.modifier->totlvl, mesh, sculpt_session->subdiv_ccg);
@@ -439,15 +437,15 @@ void multires_force_sculpt_rebuild(Object *object)
{
multires_flush_sculpt_updates(object);
- if (object == NULL || object->sculpt == NULL) {
+ if (object == nullptr || object->sculpt == nullptr) {
return;
}
SculptSession *ss = object->sculpt;
- if (ss->pbvh != NULL) {
+ if (ss->pbvh != nullptr) {
BKE_pbvh_free(ss->pbvh);
- object->sculpt->pbvh = NULL;
+ object->sculpt->pbvh = nullptr;
}
MEM_SAFE_FREE(ss->pmap);
@@ -466,15 +464,14 @@ void multires_force_external_reload(Object *object)
/* reset the multires levels to match the number of mdisps */
static int get_levels_from_disps(Object *ob)
{
- Mesh *me = ob->data;
+ Mesh *me = static_cast<Mesh *>(ob->data);
const MPoly *polys = BKE_mesh_polys(me);
- MDisps *mdisp, *md;
int i, j, totlvl = 0;
- mdisp = CustomData_get_layer(&me->ldata, CD_MDISPS);
+ const MDisps *mdisp = static_cast<const MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
for (i = 0; i < me->totpoly; i++) {
- md = mdisp + polys[i].loopstart;
+ const MDisps *md = mdisp + polys[i].loopstart;
for (j = 0; j < polys[i].totloop; j++, md++) {
if (md->totdisp == 0) {
@@ -504,14 +501,15 @@ static int get_levels_from_disps(Object *ob)
void multiresModifier_set_levels_from_disps(MultiresModifierData *mmd, Object *ob)
{
- Mesh *me = ob->data;
- MDisps *mdisp;
+ Mesh *me = static_cast<Mesh *>(ob->data);
+ const MDisps *mdisp;
if (me->edit_mesh) {
- mdisp = CustomData_get_layer(&me->edit_mesh->bm->ldata, CD_MDISPS);
+ mdisp = static_cast<const MDisps *>(
+ CustomData_get_layer(&me->edit_mesh->bm->ldata, CD_MDISPS));
}
else {
- mdisp = CustomData_get_layer(&me->ldata, CD_MDISPS);
+ mdisp = static_cast<const MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
}
if (mdisp) {
@@ -524,7 +522,7 @@ void multiresModifier_set_levels_from_disps(MultiresModifierData *mmd, Object *o
static void multires_set_tot_mdisps(Mesh *me, int lvl)
{
- MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
+ MDisps *mdisps = static_cast<MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
int i;
if (mdisps) {
@@ -542,7 +540,8 @@ static void multires_reallocate_mdisps(int totloop, MDisps *mdisps, int lvl)
/* reallocate displacements to be filled in */
for (i = 0; i < totloop; i++) {
int totdisp = multires_grid_tot[lvl];
- float(*disps)[3] = MEM_calloc_arrayN(totdisp, sizeof(float[3]), "multires disps");
+ float(*disps)[3] = static_cast<float(*)[3]>(
+ MEM_calloc_arrayN(totdisp, sizeof(float[3]), __func__));
if (mdisps[i].disps) {
MEM_freeN(mdisps[i].disps);
@@ -616,8 +615,8 @@ static void multires_grid_paint_mask_downsample(GridPaintMask *gpm, int level)
{
if (level < gpm->level) {
int gridsize = BKE_ccg_gridsize(level);
- float *data = MEM_calloc_arrayN(
- square_i(gridsize), sizeof(float), "multires_grid_paint_mask_downsample");
+ float *data = static_cast<float *>(
+ MEM_calloc_arrayN(square_i(gridsize), sizeof(float), __func__));
int x, y;
for (y = 0; y < gridsize; y++) {
@@ -642,8 +641,8 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
multires_set_tot_mdisps(me, mmd->totlvl);
multiresModifier_ensure_external_read(me, mmd);
- mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
- gpm = CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK);
+ mdisps = static_cast<MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
+ gpm = static_cast<GridPaintMask *>(CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK));
multires_force_sculpt_rebuild(ob);
@@ -661,9 +660,10 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
float(*disps)[3], (*ndisps)[3], (*hdisps)[3];
int totdisp = multires_grid_tot[lvl];
- disps = MEM_calloc_arrayN(totdisp, sizeof(float[3]), "multires disps");
+ disps = static_cast<float(*)[3]>(
+ MEM_calloc_arrayN(totdisp, sizeof(float[3]), "multires disps"));
- if (mdisp->disps != NULL) {
+ if (mdisp->disps != nullptr) {
ndisps = disps;
hdisps = mdisp->disps;
@@ -703,11 +703,10 @@ void multiresModifier_del_levels(MultiresModifierData *mmd,
Mesh *me = BKE_mesh_from_object(ob);
int lvl = multires_get_level(scene, ob, mmd, false, true);
int levels = mmd->totlvl - lvl;
- MDisps *mdisps;
multires_set_tot_mdisps(me, mmd->totlvl);
multiresModifier_ensure_external_read(me, mmd);
- mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
+ MDisps *mdisps = static_cast<MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
multires_force_sculpt_rebuild(ob);
@@ -724,9 +723,9 @@ static DerivedMesh *multires_dm_create_local(Scene *scene,
int lvl,
int totlvl,
bool alloc_paint_mask,
- int flags)
+ MultiresFlags flags)
{
- MultiresModifierData mmd = {{NULL}};
+ MultiresModifierData mmd = {{nullptr}};
mmd.lvl = lvl;
mmd.sculptlvl = lvl;
@@ -752,7 +751,7 @@ static DerivedMesh *subsurf_dm_create_local(Scene *scene,
bool for_render,
SubsurfFlags flags)
{
- SubsurfModifierData smd = {{NULL}};
+ SubsurfModifierData smd = {{nullptr}};
smd.levels = smd.renderLevels = lvl;
smd.quality = 3;
@@ -779,7 +778,7 @@ static DerivedMesh *subsurf_dm_create_local(Scene *scene,
flags |= SUBSURF_USE_RENDER_PARAMS;
}
- return subsurf_make_derived_from_derived(dm, &smd, scene, NULL, flags);
+ return subsurf_make_derived_from_derived(dm, &smd, scene, nullptr, flags);
}
static void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *grid, float t[3])
@@ -826,7 +825,7 @@ static void grid_tangent_matrix(float mat[3][3], const CCGKey *key, int x, int y
copy_v3_v3(mat[2], CCG_grid_elem_no(key, grid, x, y));
}
-typedef struct MultiresThreadedData {
+struct MultiresThreadedData {
DispOp op;
CCGElem **gridData, **subGridData;
CCGKey *key;
@@ -837,13 +836,13 @@ typedef struct MultiresThreadedData {
int *gridOffset;
int gridSize, dGridSize, dSkip;
float (*smat)[3];
-} MultiresThreadedData;
+};
static void multires_disp_run_cb(void *__restrict userdata,
const int pidx,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
- MultiresThreadedData *tdata = userdata;
+ MultiresThreadedData *tdata = static_cast<MultiresThreadedData *>(userdata);
DispOp op = tdata->op;
CCGElem **gridData = tdata->gridData;
@@ -861,11 +860,11 @@ static void multires_disp_run_cb(void *__restrict userdata,
int S, x, y, gIndex = gridOffset[pidx];
for (S = 0; S < numVerts; S++, gIndex++) {
- GridPaintMask *gpm = grid_paint_mask ? &grid_paint_mask[gIndex] : NULL;
+ GridPaintMask *gpm = grid_paint_mask ? &grid_paint_mask[gIndex] : nullptr;
MDisps *mdisp = &mdisps[mpoly[pidx].loopstart + S];
CCGElem *grid = gridData[gIndex];
CCGElem *subgrid = subGridData[gIndex];
- float(*dispgrid)[3] = NULL;
+ float(*dispgrid)[3] = nullptr;
dispgrid = mdisp->disps;
@@ -875,7 +874,8 @@ static void multires_disp_run_cb(void *__restrict userdata,
if (gpm->data) {
MEM_freeN(gpm->data);
}
- gpm->data = MEM_calloc_arrayN(key->grid_area, sizeof(float), "gpm.data");
+ gpm->data = static_cast<float *>(
+ MEM_calloc_arrayN(key->grid_area, sizeof(float), "gpm.data"));
}
for (y = 0; y < gridSize; y++) {
@@ -943,16 +943,16 @@ static void multiresModifier_disp_run(
CCGElem **gridData, **subGridData;
CCGKey key;
const MPoly *mpoly = BKE_mesh_polys(me);
- MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
- GridPaintMask *grid_paint_mask = NULL;
+ MDisps *mdisps = static_cast<MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
+ GridPaintMask *grid_paint_mask = nullptr;
int *gridOffset;
int i, gridSize, dGridSize, dSkip;
int totloop, totpoly;
/* this happens in the dm made by bmesh_mdisps_space_set */
if (dm2 && CustomData_has_layer(&dm2->loopData, CD_MDISPS)) {
- mpoly = CustomData_get_layer(&dm2->polyData, CD_MPOLY);
- mdisps = CustomData_get_layer(&dm2->loopData, CD_MDISPS);
+ mpoly = static_cast<const MPoly *>(CustomData_get_layer(&dm2->polyData, CD_MPOLY));
+ mdisps = static_cast<MDisps *>(CustomData_get_layer(&dm2->loopData, CD_MDISPS));
totloop = dm2->numLoopData;
totpoly = dm2->numPolyData;
}
@@ -963,7 +963,8 @@ static void multiresModifier_disp_run(
if (!mdisps) {
if (op == CALC_DISPLACEMENTS) {
- mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS, CD_SET_DEFAULT, NULL, me->totloop);
+ mdisps = static_cast<MDisps *>(
+ CustomData_add_layer(&me->ldata, CD_MDISPS, CD_SET_DEFAULT, nullptr, me->totloop));
}
else {
return;
@@ -982,12 +983,13 @@ static void multiresModifier_disp_run(
/* multires paint masks */
if (key.has_mask) {
- grid_paint_mask = CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK);
+ grid_paint_mask = static_cast<GridPaintMask *>(
+ CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK));
}
/* when adding new faces in edit mode, need to allocate disps */
for (i = 0; i < totloop; i++) {
- if (mdisps[i].disps == NULL) {
+ if (mdisps[i].disps == nullptr) {
multires_reallocate_mdisps(totloop, mdisps, totlvl);
break;
}
@@ -997,25 +999,24 @@ static void multiresModifier_disp_run(
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = CCG_TASK_LIMIT;
- MultiresThreadedData data = {
- .op = op,
- .gridData = gridData,
- .subGridData = subGridData,
- .key = &key,
- .mpoly = mpoly,
- .mdisps = mdisps,
- .grid_paint_mask = grid_paint_mask,
- .gridOffset = gridOffset,
- .gridSize = gridSize,
- .dGridSize = dGridSize,
- .dSkip = dSkip,
- };
+ MultiresThreadedData data{};
+ data.op = op;
+ data.gridData = gridData;
+ data.subGridData = subGridData;
+ data.key = &key;
+ data.mpoly = mpoly;
+ data.mdisps = mdisps;
+ data.grid_paint_mask = grid_paint_mask;
+ data.gridOffset = gridOffset;
+ data.gridSize = gridSize;
+ data.dGridSize = dGridSize;
+ data.dSkip = dSkip;
BLI_task_parallel_range(0, totpoly, &data, multires_disp_run_cb, &settings);
if (op == APPLY_DISPLACEMENTS) {
- ccgSubSurf_stitchFaces(ccgdm->ss, 0, NULL, 0);
- ccgSubSurf_updateNormals(ccgdm->ss, NULL, 0);
+ ccgSubSurf_stitchFaces(ccgdm->ss, 0, nullptr, 0);
+ ccgSubSurf_updateNormals(ccgdm->ss, nullptr, 0);
}
}
@@ -1028,11 +1029,11 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm, Scene *scene)
MultiresModifierData *mmd;
ob = ccgdm->multires.ob;
- me = ccgdm->multires.ob->data;
+ me = static_cast<Mesh *>(ccgdm->multires.ob->data);
mmd = ccgdm->multires.mmd;
multires_set_tot_mdisps(me, mmd->totlvl);
multiresModifier_ensure_external_read(me, mmd);
- mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
+ mdisps = static_cast<const MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
if (mdisps) {
int lvl = ccgdm->multires.lvl;
@@ -1080,13 +1081,15 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm, Scene *scene)
BLI_assert(highGridKey.elem_size == lowGridKey.elem_size);
- subGridData = MEM_calloc_arrayN(numGrids, sizeof(CCGElem *), "subGridData*");
- diffGrid = MEM_calloc_arrayN(lowGridKey.elem_size, lowGridSize * lowGridSize, "diff");
+ subGridData = static_cast<CCGElem **>(
+ MEM_calloc_arrayN(numGrids, sizeof(CCGElem *), "subGridData*"));
+ diffGrid = static_cast<CCGElem *>(
+ MEM_calloc_arrayN(lowGridKey.elem_size, lowGridSize * lowGridSize, "diff"));
for (i = 0; i < numGrids; i++) {
/* backup subsurf grids */
- subGridData[i] = MEM_calloc_arrayN(
- highGridKey.elem_size, highGridSize * highGridSize, "subGridData");
+ subGridData[i] = static_cast<CCGElem *>(
+ MEM_calloc_arrayN(highGridKey.elem_size, highGridSize * highGridSize, "subGridData"));
memcpy(
subGridData[i], highGridData[i], highGridKey.elem_size * highGridSize * highGridSize);
@@ -1105,11 +1108,11 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm, Scene *scene)
lowdm->release(lowdm);
/* subsurf higher levels again with difference of coordinates */
- ccgSubSurf_updateFromFaces(ss, lvl, NULL, 0);
- ccgSubSurf_updateLevels(ss, lvl, NULL, 0);
+ ccgSubSurf_updateFromFaces(ss, lvl, nullptr, 0);
+ ccgSubSurf_updateLevels(ss, lvl, nullptr, 0);
/* add to displacements */
- multiresModifier_disp_run(highdm, me, NULL, ADD_DISPLACEMENTS, subGridData, mmd->totlvl);
+ multiresModifier_disp_run(highdm, me, nullptr, ADD_DISPLACEMENTS, subGridData, mmd->totlvl);
/* free */
highdm->release(highdm);
@@ -1139,7 +1142,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm, Scene *scene)
cddm->release(cddm);
multiresModifier_disp_run(
- dm, me, NULL, CALC_DISPLACEMENTS, subdm->getGridData(subdm), mmd->totlvl);
+ dm, me, nullptr, CALC_DISPLACEMENTS, subdm->getGridData(subdm), mmd->totlvl);
subdm->release(subdm);
}
@@ -1150,8 +1153,8 @@ void multires_modifier_update_hidden(DerivedMesh *dm)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
BLI_bitmap **grid_hidden = ccgdm->gridHidden;
- Mesh *me = ccgdm->multires.ob->data;
- MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
+ Mesh *me = static_cast<Mesh *>(ccgdm->multires.ob->data);
+ MDisps *mdisps = static_cast<MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
int totlvl = ccgdm->multires.totlvl;
int lvl = ccgdm->multires.lvl;
@@ -1164,7 +1167,7 @@ void multires_modifier_update_hidden(DerivedMesh *dm)
if (!gh && md->hidden) {
MEM_freeN(md->hidden);
- md->hidden = NULL;
+ md->hidden = nullptr;
}
else if (gh) {
gh = multires_mdisps_upsample_hidden(gh, lvl, totlvl, md->hidden);
@@ -1180,16 +1183,16 @@ void multires_modifier_update_hidden(DerivedMesh *dm)
void multires_stitch_grids(Object *ob)
{
- if (ob == NULL) {
+ if (ob == nullptr) {
return;
}
SculptSession *sculpt_session = ob->sculpt;
- if (sculpt_session == NULL) {
+ if (sculpt_session == nullptr) {
return;
}
PBVH *pbvh = sculpt_session->pbvh;
SubdivCCG *subdiv_ccg = sculpt_session->subdiv_ccg;
- if (pbvh == NULL || subdiv_ccg == NULL) {
+ if (pbvh == nullptr || subdiv_ccg == nullptr) {
return;
}
BLI_assert(BKE_pbvh_type(pbvh) == PBVH_GRIDS);
@@ -1208,9 +1211,9 @@ void multires_stitch_grids(Object *ob)
DerivedMesh *multires_make_derived_from_derived(
DerivedMesh *dm, MultiresModifierData *mmd, Scene *scene, Object *ob, MultiresFlags flags)
{
- Mesh *me = ob->data;
+ Mesh *me = static_cast<Mesh *>(ob->data);
DerivedMesh *result;
- CCGDerivedMesh *ccgdm = NULL;
+ CCGDerivedMesh *ccgdm = nullptr;
CCGElem **gridData, **subGridData;
CCGKey key;
const bool render = (flags & MULTIRES_USE_RENDER_PARAMS) != 0;
@@ -1222,7 +1225,7 @@ DerivedMesh *multires_make_derived_from_derived(
return dm;
}
- const int subsurf_flags = ignore_simplify ? SUBSURF_IGNORE_SIMPLIFY : 0;
+ const SubsurfFlags subsurf_flags = ignore_simplify ? SUBSURF_IGNORE_SIMPLIFY : SubsurfFlags(0);
result = subsurf_dm_create_local(scene,
ob,
@@ -1243,7 +1246,7 @@ DerivedMesh *multires_make_derived_from_derived(
ccgdm->multires.local_mmd = 0;
ccgdm->multires.lvl = lvl;
ccgdm->multires.totlvl = mmd->totlvl;
- ccgdm->multires.modified_flags = 0;
+ ccgdm->multires.modified_flags = MultiresModifiedFlags(0);
}
numGrids = result->getNumGrids(result);
@@ -1251,10 +1254,12 @@ DerivedMesh *multires_make_derived_from_derived(
gridData = result->getGridData(result);
result->getGridKey(result, &key);
- subGridData = MEM_malloc_arrayN(numGrids, sizeof(CCGElem *), "subGridData*");
+ subGridData = static_cast<CCGElem **>(
+ MEM_malloc_arrayN(numGrids, sizeof(CCGElem *), "subGridData*"));
for (i = 0; i < numGrids; i++) {
- subGridData[i] = MEM_malloc_arrayN(key.elem_size, gridSize * gridSize, "subGridData");
+ subGridData[i] = static_cast<CCGElem *>(
+ MEM_malloc_arrayN(key.elem_size, gridSize * gridSize, "subGridData"));
memcpy(subGridData[i], gridData[i], key.elem_size * gridSize * gridSize);
}
@@ -1262,7 +1267,8 @@ DerivedMesh *multires_make_derived_from_derived(
multiresModifier_ensure_external_read(me, mmd);
/* Run displacement. */
- multiresModifier_disp_run(result, ob->data, dm, APPLY_DISPLACEMENTS, subGridData, mmd->totlvl);
+ multiresModifier_disp_run(
+ result, static_cast<Mesh *>(ob->data), dm, APPLY_DISPLACEMENTS, subGridData, mmd->totlvl);
/* copy hidden elements for this level */
if (ccgdm) {
@@ -1353,12 +1359,10 @@ static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst)
MultiresModifierData *mmd_dst = get_multires_modifier(scene, ob_dst, true);
if (!mmd_src) {
- /* object could have MDISP even when there is no multires modifier
- * this could lead to troubles due to i've got no idea how mdisp could be
- * up-sampled correct without modifier data.
- * just remove mdisps if no multires present (nazgul) */
-
- multires_customdata_delete(ob_src->data);
+ /* NOTE(@sergey): object could have MDISP even when there is no multires modifier
+ * this could lead to troubles due to I've got no idea how mdisp could be
+ * up-sampled correct without modifier data. Just remove mdisps if no multires present. */
+ multires_customdata_delete(static_cast<Mesh *>(ob_src->data));
}
if (mmd_src && mmd_dst) {
@@ -1369,7 +1373,7 @@ static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst)
static void multires_apply_uniform_scale(Object *object, const float scale)
{
Mesh *mesh = (Mesh *)object->data;
- MDisps *mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS);
+ MDisps *mdisps = static_cast<MDisps *>(CustomData_get_layer(&mesh->ldata, CD_MDISPS));
for (int i = 0; i < mesh->totloop; i++) {
MDisps *grid = &mdisps[i];
for (int j = 0; j < grid->totdisp; j++) {
@@ -1378,13 +1382,13 @@ static void multires_apply_uniform_scale(Object *object, const float scale)
}
}
-static void multires_apply_smat(struct Depsgraph *UNUSED(depsgraph),
+static void multires_apply_smat(struct Depsgraph * /*depsgraph*/,
Scene *scene,
Object *object,
const float smat[3][3])
{
const MultiresModifierData *mmd = get_multires_modifier(scene, object, true);
- if (mmd == NULL || mmd->totlvl == 0) {
+ if (mmd == nullptr || mmd->totlvl == 0) {
return;
}
/* Make sure layer present. */
@@ -1398,9 +1402,8 @@ static void multires_apply_smat(struct Depsgraph *UNUSED(depsgraph),
multires_apply_uniform_scale(object, scale);
}
else {
- /* TODO(sergey): This branch of code actually requires more work to
- * preserve all the details.
- */
+ /* TODO(@sergey): This branch of code actually requires more work to
+ * preserve all the details. */
const float scale = mat3_to_scale(smat);
multires_apply_uniform_scale(object, scale);
}
@@ -1450,11 +1453,11 @@ void multiresModifier_prepare_join(struct Depsgraph *depsgraph,
void multires_topology_changed(Mesh *me)
{
- MDisps *mdisp = NULL, *cur = NULL;
+ MDisps *mdisp = nullptr, *cur = nullptr;
int i, grid = 0;
CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
- mdisp = CustomData_get_layer(&me->ldata, CD_MDISPS);
+ mdisp = static_cast<MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
if (!mdisp) {
return;
@@ -1474,7 +1477,8 @@ void multires_topology_changed(Mesh *me)
if (!mdisp->totdisp || !mdisp->disps) {
if (grid) {
mdisp->totdisp = grid;
- mdisp->disps = MEM_calloc_arrayN(mdisp->totdisp, sizeof(float[3]), "mdisp topology");
+ mdisp->disps = static_cast<float(*)[3]>(
+ MEM_calloc_arrayN(mdisp->totdisp, sizeof(float[3]), "mdisp topology"));
}
continue;
@@ -1488,9 +1492,10 @@ void multires_ensure_external_read(struct Mesh *mesh, int top_level)
return;
}
- MDisps *mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS);
- if (mdisps == NULL) {
- mdisps = CustomData_add_layer(&mesh->ldata, CD_MDISPS, CD_SET_DEFAULT, NULL, mesh->totloop);
+ MDisps *mdisps = static_cast<MDisps *>(CustomData_get_layer(&mesh->ldata, CD_MDISPS));
+ if (mdisps == nullptr) {
+ mdisps = static_cast<MDisps *>(
+ CustomData_add_layer(&mesh->ldata, CD_MDISPS, CD_SET_DEFAULT, nullptr, mesh->totloop));
}
const int totloop = mesh->totloop;
@@ -1517,10 +1522,10 @@ void multiresModifier_ensure_external_read(struct Mesh *mesh, const MultiresModi
/***************** Multires interpolation stuff *****************/
-int mdisp_rot_face_to_crn(struct MVert *UNUSED(mvert),
+int mdisp_rot_face_to_crn(struct MVert * /*mvert*/,
struct MPoly *mpoly,
- struct MLoop *UNUSED(mloop),
- const struct MLoopTri *UNUSED(lt),
+ struct MLoop * /*mloop*/,
+ const struct MLoopTri * /*lt*/,
const int face_side,
const float u,
const float v,
@@ -1598,7 +1603,7 @@ int mdisp_rot_face_to_crn(struct MVert *UNUSED(mvert),
float mindist = FLT_MAX;
for (i = 0; i < mpoly->totloop; i++) {
- float len = len_v3v3(NULL, mvert[mloop[mpoly->loopstart + i].v].co);
+ float len = len_v3v3(nullptr, mvert[mloop[mpoly->loopstart + i].v].co);
if (len < mindist) {
mindist = len;
minS = i;
diff --git a/source/blender/blenkernel/intern/multires_reshape.h b/source/blender/blenkernel/intern/multires_reshape.h
index 5e2822ad5df..f27618b2145 100644
--- a/source/blender/blenkernel/intern/multires_reshape.h
+++ b/source/blender/blenkernel/intern/multires_reshape.h
@@ -101,6 +101,8 @@ typedef struct MultiresReshapeContext {
/* Vertex crease custom data layer, null if none is present. */
const float *cd_vertex_crease;
+ /* Edge crease custom data layer, null if none is present. */
+ const float *cd_edge_crease;
} MultiresReshapeContext;
/**
diff --git a/source/blender/blenkernel/intern/multires_reshape_smooth.c b/source/blender/blenkernel/intern/multires_reshape_smooth.c
index e887f543dc5..1463404069f 100644
--- a/source/blender/blenkernel/intern/multires_reshape_smooth.c
+++ b/source/blender/blenkernel/intern/multires_reshape_smooth.c
@@ -482,13 +482,14 @@ static bool is_crease_supported(const MultiresReshapeSmoothContext *reshape_smoo
/* Get crease which will be used for communication to OpenSubdiv topology.
* Note that simple subdivision treats all base edges as infinitely sharp. */
-static char get_effective_crease_char(const MultiresReshapeSmoothContext *reshape_smooth_context,
- const MEdge *base_edge)
+static float get_effective_crease(const MultiresReshapeSmoothContext *reshape_smooth_context,
+ const int base_edge_index)
{
if (!is_crease_supported(reshape_smooth_context)) {
return 255;
}
- return base_edge->crease;
+ const float *creases = reshape_smooth_context->reshape_context->cd_vertex_crease;
+ return creases ? creases[base_edge_index] : 0.0f;
}
static float get_effective_crease_float(const MultiresReshapeSmoothContext *reshape_smooth_context,
@@ -812,7 +813,6 @@ static void foreach_edge(const struct SubdivForeachContext *foreach_context,
const int subdiv_v2)
{
MultiresReshapeSmoothContext *reshape_smooth_context = foreach_context->user_data;
- const MultiresReshapeContext *reshape_context = reshape_smooth_context->reshape_context;
if (reshape_smooth_context->smoothing_type == MULTIRES_SUBDIVIDE_LINEAR) {
if (!is_loose) {
@@ -832,8 +832,7 @@ static void foreach_edge(const struct SubdivForeachContext *foreach_context,
return;
}
/* Edges without crease are to be ignored as well. */
- const MEdge *base_edge = &reshape_context->base_edges[coarse_edge_index];
- const char crease = get_effective_crease_char(reshape_smooth_context, base_edge);
+ const char crease = get_effective_crease(reshape_smooth_context, coarse_edge_index);
if (crease == 0) {
return;
}
@@ -846,7 +845,6 @@ static void geometry_init_loose_information(MultiresReshapeSmoothContext *reshap
const Mesh *base_mesh = reshape_context->base_mesh;
const MPoly *base_mpoly = reshape_context->base_polys;
const MLoop *base_mloop = reshape_context->base_loops;
- const MEdge *base_edge = reshape_context->base_edges;
reshape_smooth_context->non_loose_base_edge_map = BLI_BITMAP_NEW(base_mesh->totedge,
"non_loose_base_edge_map");
@@ -859,8 +857,8 @@ static void geometry_init_loose_information(MultiresReshapeSmoothContext *reshap
if (!BLI_BITMAP_TEST_BOOL(reshape_smooth_context->non_loose_base_edge_map, loop->e)) {
BLI_BITMAP_ENABLE(reshape_smooth_context->non_loose_base_edge_map, loop->e);
- const char crease = get_effective_crease_char(reshape_smooth_context, &base_edge[loop->e]);
- if (crease != 0) {
+ const float crease = get_effective_crease(reshape_smooth_context, loop->e);
+ if (crease > 0.0f) {
++num_used_edges;
}
}
diff --git a/source/blender/blenkernel/intern/multires_reshape_util.c b/source/blender/blenkernel/intern/multires_reshape_util.c
index 5b60394feda..4fc1217158c 100644
--- a/source/blender/blenkernel/intern/multires_reshape_util.c
+++ b/source/blender/blenkernel/intern/multires_reshape_util.c
@@ -206,6 +206,7 @@ bool multires_reshape_context_create_from_object(MultiresReshapeContext *reshape
reshape_context->top.grid_size = BKE_subdiv_grid_size_from_level(reshape_context->top.level);
reshape_context->cd_vertex_crease = CustomData_get_layer(&base_mesh->vdata, CD_CREASE);
+ reshape_context->cd_edge_crease = CustomData_get_layer(&base_mesh->edata, CD_CREASE);
context_init_commoon(reshape_context);
@@ -271,6 +272,8 @@ bool multires_reshape_context_create_from_subdiv(MultiresReshapeContext *reshape
reshape_context->base_edges = BKE_mesh_edges(base_mesh);
reshape_context->base_polys = BKE_mesh_polys(base_mesh);
reshape_context->base_loops = BKE_mesh_loops(base_mesh);
+ reshape_context->cd_vertex_crease = (const float *)CustomData_get_layer(&base_mesh->edata,
+ CD_CREASE);
reshape_context->subdiv = subdiv;
reshape_context->need_free_subdiv = false;
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index da508ff865c..c0aff204069 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -431,8 +431,7 @@ NlaStrip *BKE_nlastrip_new(bAction *act)
BKE_action_get_frame_range(strip->act, &strip->actstart, &strip->actend);
strip->start = strip->actstart;
- strip->end = (IS_EQF(strip->actstart, strip->actend)) ? (strip->actstart + 1.0f) :
- (strip->actend);
+ strip->end = IS_EQF(strip->actstart, strip->actend) ? (strip->actstart + 1.0f) : strip->actend;
/* strip should be referenced as-is */
strip->scale = 1.0f;
@@ -465,6 +464,7 @@ NlaStrip *BKE_nlastack_add_strip(AnimData *adt, bAction *act, const bool is_libo
*/
nlt = BKE_nlatrack_add(adt, NULL, is_liboverride);
BKE_nlatrack_add_strip(nlt, strip, is_liboverride);
+ BLI_strncpy(nlt->name, act->id.name + 2, sizeof(nlt->name));
}
/* automatically name it too */
@@ -1273,6 +1273,34 @@ float BKE_nlastrip_compute_frame_to_next_strip(NlaStrip *strip)
return limit_next;
}
+NlaStrip *BKE_nlastrip_next_in_track(struct NlaStrip *strip, bool skip_transitions)
+{
+ NlaStrip *next = strip->next;
+ while (next != NULL) {
+ if (skip_transitions && (next->type & NLASTRIP_TYPE_TRANSITION)) {
+ next = next->next;
+ }
+ else {
+ return next;
+ }
+ }
+ return NULL;
+}
+
+NlaStrip *BKE_nlastrip_prev_in_track(struct NlaStrip *strip, bool skip_transitions)
+{
+ NlaStrip *prev = strip->prev;
+ while (prev != NULL) {
+ if (skip_transitions && (prev->type & NLASTRIP_TYPE_TRANSITION)) {
+ prev = prev->prev;
+ }
+ else {
+ return prev;
+ }
+ }
+ return NULL;
+}
+
NlaStrip *BKE_nlastrip_find_active(NlaTrack *nlt)
{
if (nlt == NULL) {
@@ -1891,7 +1919,7 @@ bool BKE_nla_action_stash(AnimData *adt, const bool is_liboverride)
* NOTE: this must be done *after* adding the strip to the track, or else
* the strip locking will prevent the strip from getting added
*/
- nlt->flag = (NLATRACK_MUTED | NLATRACK_PROTECTED);
+ nlt->flag |= (NLATRACK_MUTED | NLATRACK_PROTECTED);
strip->flag &= ~(NLASTRIP_FLAG_SELECT | NLASTRIP_FLAG_ACTIVE);
/* also mark the strip for auto syncing the length, so that the strips accurately
@@ -2027,7 +2055,7 @@ bool BKE_nla_tweakmode_enter(AnimData *adt)
}
/* If block is already in tweak-mode, just leave, but we should report
- * that this block is in tweak-mode (as our returncode). */
+ * that this block is in tweak-mode (as our return-code). */
if (adt->flag & ADT_NLA_EDIT_ON) {
return true;
}
@@ -2072,7 +2100,7 @@ bool BKE_nla_tweakmode_enter(AnimData *adt)
/* handle AnimData level changes:
* - 'real' active action to temp storage (no need to change user-counts).
- * - Action of active strip set to be the 'active action', and have its usercount incremented.
+ * - Action of active strip set to be the 'active action', and have its user-count incremented.
* - Editing-flag for this AnimData block should also get turned on
* (for more efficient restoring).
* - Take note of the active strip for mapping-correction of keyframes
@@ -2136,7 +2164,8 @@ void BKE_nla_tweakmode_exit(AnimData *adt)
}
/* handle AnimData level changes:
- * - 'temporary' active action needs its usercount decreased, since we're removing this reference
+ * - 'temporary' active action needs its user-count decreased,
+ * since we're removing this reference
* - 'real' active action is restored from storage
* - storage pointer gets cleared (to avoid having bad notes hanging around)
* - editing-flag for this AnimData block should also get turned off
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index b82cf30416a..31fc8afea84 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -47,6 +47,7 @@
#include "BKE_anim_data.h"
#include "BKE_animsys.h"
+#include "BKE_asset.h"
#include "BKE_bpath.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
@@ -54,6 +55,7 @@
#include "BKE_global.h"
#include "BKE_icons.h"
#include "BKE_idprop.h"
+#include "BKE_idprop.hh"
#include "BKE_idtype.h"
#include "BKE_image_format.h"
#include "BKE_lib_id.h"
@@ -82,8 +84,6 @@
#include "BLO_read_write.h"
-#include "MOD_nodes.h"
-
#define NODE_DEFAULT_MAX_WIDTH 700
using blender::Array;
@@ -116,7 +116,7 @@ static void ntree_set_typeinfo(bNodeTree *ntree, bNodeTreeType *typeinfo);
static void node_socket_copy(bNodeSocket *sock_dst, const bNodeSocket *sock_src, const int flag);
static void free_localized_node_groups(bNodeTree *ntree);
static void node_free_node(bNodeTree *ntree, bNode *node);
-static void node_socket_interface_free(bNodeTree *UNUSED(ntree),
+static void node_socket_interface_free(bNodeTree * /*ntree*/,
bNodeSocket *sock,
const bool do_id_user);
@@ -127,12 +127,12 @@ static void ntree_init_data(ID *id)
ntree_set_typeinfo(ntree, nullptr);
}
-static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
+static void ntree_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int flag)
{
bNodeTree *ntree_dst = (bNodeTree *)id_dst;
const bNodeTree *ntree_src = (const bNodeTree *)id_src;
- /* We never handle usercount here for own data. */
+ /* We never handle user-count here for own data. */
const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
ntree_dst->runtime = MEM_new<bNodeTreeRuntime>(__func__);
@@ -372,7 +372,7 @@ static void node_foreach_cache(ID *id,
if (nodetree->type == NTREE_COMPOSIT) {
LISTBASE_FOREACH (bNode *, node, &nodetree->nodes) {
if (node->type == CMP_NODE_MOVIEDISTORTION) {
- key.offset_in_ID = (size_t)BLI_ghashutil_strhash_p(node->name);
+ key.offset_in_ID = size_t(BLI_ghashutil_strhash_p(node->name));
function_callback(id, &key, (void **)&node->storage, 0, user_data);
}
}
@@ -405,13 +405,13 @@ static void node_foreach_path(ID *id, BPathForeachPathData *bpath_data)
static ID **node_owner_pointer_get(ID *id)
{
if ((id->flag & LIB_EMBEDDED_DATA) == 0) {
- return NULL;
+ return nullptr;
}
/* TODO: Sort this NO_MAIN or not for embedded node trees. See T86119. */
// BLI_assert((id->tag & LIB_TAG_NO_MAIN) == 0);
bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
- BLI_assert(ntree->owner_id != NULL);
+ BLI_assert(ntree->owner_id != nullptr);
BLI_assert(ntreeFromID(ntree->owner_id) == ntree);
return &ntree->owner_id;
@@ -516,10 +516,6 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
write_node_socket(writer, sock);
}
- LISTBASE_FOREACH (bNodeLink *, link, &node->internal_links) {
- BLO_write_struct(writer, bNodeLink, link);
- }
-
if (node->storage) {
if (ELEM(ntree->type, NTREE_SHADER, NTREE_GEOMETRY) &&
ELEM(node->type, SH_NODE_CURVE_VEC, SH_NODE_CURVE_RGB, SH_NODE_CURVE_FLOAT)) {
@@ -660,7 +656,7 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
if (BLO_read_fileversion_get(reader) > 300) {
BLI_assert((ntree->id.flag & LIB_EMBEDDED_DATA) != 0 || owner_id == nullptr);
}
- BLI_assert(owner_id == NULL || owner_id->lib == ntree->id.lib);
+ BLI_assert(owner_id == nullptr || owner_id->lib == ntree->id.lib);
if (owner_id != nullptr && (ntree->id.flag & LIB_EMBEDDED_DATA) == 0) {
/* This is unfortunate, but currently a lot of existing files (including startup ones) have
* missing `LIB_EMBEDDED_DATA` flag.
@@ -703,13 +699,7 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
BLO_read_data_address(reader, &node->prop);
IDP_BlendDataRead(reader, &node->prop);
- BLO_read_list(reader, &node->internal_links);
- LISTBASE_FOREACH (bNodeLink *, link, &node->internal_links) {
- BLO_read_data_address(reader, &link->fromnode);
- BLO_read_data_address(reader, &link->fromsock);
- BLO_read_data_address(reader, &link->tonode);
- BLO_read_data_address(reader, &link->tosock);
- }
+ BLI_listbase_clear(&node->internal_links);
if (node->type == CMP_NODE_MOVIEDISTORTION) {
/* Do nothing, this is runtime cache and hence handled by generic code using
@@ -1026,6 +1016,33 @@ static void ntree_blend_read_expand(BlendExpander *expander, ID *id)
ntreeBlendReadExpand(expander, ntree);
}
+namespace blender::bke {
+
+static void node_tree_asset_pre_save(void *asset_ptr, struct AssetMetaData *asset_data)
+{
+ bNodeTree &node_tree = *static_cast<bNodeTree *>(asset_ptr);
+
+ BKE_asset_metadata_idprop_ensure(asset_data, idprop::create("type", node_tree.type).release());
+ auto inputs = idprop::create_group("inputs");
+ auto outputs = idprop::create_group("outputs");
+ LISTBASE_FOREACH (const bNodeSocket *, socket, &node_tree.inputs) {
+ auto property = idprop::create(socket->name, socket->typeinfo->idname);
+ IDP_AddToGroup(inputs.get(), property.release());
+ }
+ LISTBASE_FOREACH (const bNodeSocket *, socket, &node_tree.outputs) {
+ auto property = idprop::create(socket->name, socket->typeinfo->idname);
+ IDP_AddToGroup(outputs.get(), property.release());
+ }
+ BKE_asset_metadata_idprop_ensure(asset_data, inputs.release());
+ BKE_asset_metadata_idprop_ensure(asset_data, outputs.release());
+}
+
+} // namespace blender::bke
+
+static AssetTypeInfo AssetType_NT = {
+ /* pre_save_fn */ blender::bke::node_tree_asset_pre_save,
+};
+
IDTypeInfo IDType_ID_NT = {
/* id_code */ ID_NT,
/* id_filter */ FILTER_ID_NT,
@@ -1035,7 +1052,7 @@ IDTypeInfo IDType_ID_NT = {
/* name_plural */ "node_groups",
/* translation_context */ BLT_I18NCONTEXT_ID_NODETREE,
/* flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
- /* asset_type_info */ nullptr,
+ /* asset_type_info */ &AssetType_NT,
/* init_data */ ntree_init_data,
/* copy_data */ ntree_copy_data,
@@ -1388,8 +1405,8 @@ void nodeUnregisterType(bNodeType *nt)
bool nodeTypeUndefined(const bNode *node)
{
return (node->typeinfo == &NodeTypeUndefined) ||
- ((ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) && node->id &&
- ID_IS_LINKED(node->id) && (node->id->tag & LIB_TAG_MISSING));
+ (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id && ID_IS_LINKED(node->id) &&
+ (node->id->tag & LIB_TAG_MISSING));
}
GHashIterator *nodeTypeGetIterator()
@@ -1504,7 +1521,7 @@ static bool unique_identifier_check(void *arg, const char *identifier)
}
static bNodeSocket *make_socket(bNodeTree *ntree,
- bNode *UNUSED(node),
+ bNode * /*node*/,
int in_out,
ListBase *lb,
const char *idname,
@@ -1647,7 +1664,7 @@ static bool socket_id_user_decrement(bNodeSocket *sock)
}
void nodeModifySocketType(bNodeTree *ntree,
- bNode *UNUSED(node),
+ bNode * /*node*/,
bNodeSocket *sock,
const char *idname)
{
@@ -1866,7 +1883,7 @@ const char *nodeStaticSocketInterfaceType(int type, int subtype)
return nullptr;
}
-const char *nodeStaticSocketLabel(int type, int UNUSED(subtype))
+const char *nodeStaticSocketLabel(int type, int /*subtype*/)
{
switch (type) {
case SOCK_FLOAT:
@@ -2005,21 +2022,29 @@ bNode *nodeFindNodebyName(bNodeTree *ntree, const char *name)
bool nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **r_node, int *r_sockindex)
{
*r_node = nullptr;
+ if (!ntree->runtime->topology_cache_is_dirty) {
+ bNode *node = &sock->owner_node();
+ *r_node = node;
+ if (r_sockindex) {
+ ListBase *sockets = (sock->in_out == SOCK_IN) ? &node->inputs : &node->outputs;
+ *r_sockindex = BLI_findindex(sockets, sock);
+ }
+ return true;
+ }
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
ListBase *sockets = (sock->in_out == SOCK_IN) ? &node->inputs : &node->outputs;
- int index = 0;
- LISTBASE_FOREACH (bNodeSocket *, tsock, sockets) {
+ int i;
+ LISTBASE_FOREACH_INDEX (bNodeSocket *, tsock, sockets, i) {
if (sock == tsock) {
if (r_node != nullptr) {
*r_node = node;
}
if (r_sockindex != nullptr) {
- *r_sockindex = index;
+ *r_sockindex = i;
}
return true;
}
- index++;
}
}
return false;
@@ -2130,6 +2155,38 @@ void nodeParentsIter(bNode *node, bool (*callback)(bNode *, void *), void *userd
}
}
+bool nodeIsDanglingReroute(const bNodeTree *ntree, const bNode *node)
+{
+ ntree->ensure_topology_cache();
+ BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*ntree));
+ BLI_assert(!ntree->has_available_link_cycle());
+
+ const bNode *iter_node = node;
+ if (!iter_node->is_reroute()) {
+ return false;
+ }
+
+ while (true) {
+ const blender::Span<const bNodeLink *> links =
+ iter_node->input_socket(0).directly_linked_links();
+ BLI_assert(links.size() <= 1);
+ if (links.is_empty()) {
+ return true;
+ }
+ const bNodeLink &link = *links[0];
+ if (!link.is_available()) {
+ return false;
+ }
+ if (link.is_muted()) {
+ return false;
+ }
+ iter_node = link.fromnode;
+ if (!iter_node->is_reroute()) {
+ return false;
+ }
+ }
+}
+
/* ************** Add stuff ********** */
void nodeUniqueName(bNodeTree *ntree, bNode *node)
@@ -2149,7 +2206,7 @@ bNode *nodeAddNode(const struct bContext *C, bNodeTree *ntree, const char *idnam
BKE_ntree_update_tag_node_new(ntree, node);
- if (node->type == GEO_NODE_INPUT_SCENE_TIME) {
+ if (ELEM(node->type, GEO_NODE_INPUT_SCENE_TIME, GEO_NODE_SELF_OBJECT)) {
DEG_relations_tag_update(CTX_data_main(C));
}
@@ -2601,15 +2658,15 @@ static bNodeTree *ntreeAddTree_do(
bNodeTree *ntree = (bNodeTree *)BKE_libblock_alloc(bmain, ID_NT, name, flag);
BKE_libblock_init_empty(&ntree->id);
if (is_embedded) {
- BLI_assert(owner_id != NULL);
+ BLI_assert(owner_id != nullptr);
ntree->id.flag |= LIB_EMBEDDED_DATA;
ntree->owner_id = owner_id;
bNodeTree **ntree_owner_ptr = BKE_ntree_ptr_from_id(owner_id);
- BLI_assert(ntree_owner_ptr != NULL);
+ BLI_assert(ntree_owner_ptr != nullptr);
*ntree_owner_ptr = ntree;
}
else {
- BLI_assert(owner_id == NULL);
+ BLI_assert(owner_id == nullptr);
}
BLI_strncpy(ntree->idname, idname, sizeof(ntree->idname));
@@ -2623,7 +2680,7 @@ bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
return ntreeAddTree_do(bmain, nullptr, false, name, idname);
}
-bNodeTree *ntreeAddTreeEmbedded(Main *UNUSED(bmain),
+bNodeTree *ntreeAddTreeEmbedded(Main * /*bmain*/,
ID *owner_id,
const char *name,
const char *idname)
@@ -2687,8 +2744,8 @@ bNodePreview *BKE_node_preview_verify(bNodeInstanceHash *previews,
}
if (preview->rect == nullptr) {
- preview->rect = (unsigned char *)MEM_callocN(4 * xsize + xsize * ysize * sizeof(char[4]),
- "node preview rect");
+ preview->rect = (uchar *)MEM_callocN(4 * xsize + xsize * ysize * sizeof(char[4]),
+ "node preview rect");
preview->xsize = xsize;
preview->ysize = ysize;
}
@@ -2701,7 +2758,7 @@ bNodePreview *BKE_node_preview_copy(bNodePreview *preview)
{
bNodePreview *new_preview = (bNodePreview *)MEM_dupallocN(preview);
if (preview->rect) {
- new_preview->rect = (unsigned char *)MEM_dupallocN(preview->rect);
+ new_preview->rect = (uchar *)MEM_dupallocN(preview->rect);
}
return new_preview;
}
@@ -2992,7 +3049,7 @@ void nodeRemoveNode(Main *bmain, bNodeTree *ntree, bNode *node, bool do_id_user)
/* Also update relations for the scene time node, which causes a dependency
* on time that users expect to be removed when the node is removed. */
- if (node_has_id || node->type == GEO_NODE_INPUT_SCENE_TIME) {
+ if (node_has_id || ELEM(node->type, GEO_NODE_INPUT_SCENE_TIME, GEO_NODE_SELF_OBJECT)) {
if (bmain != nullptr) {
DEG_relations_tag_update(bmain);
}
@@ -3005,7 +3062,7 @@ void nodeRemoveNode(Main *bmain, bNodeTree *ntree, bNode *node, bool do_id_user)
node_free_node(ntree, node);
}
-static void node_socket_interface_free(bNodeTree *UNUSED(ntree),
+static void node_socket_interface_free(bNodeTree * /*ntree*/,
bNodeSocket *sock,
const bool do_id_user)
{
@@ -3085,7 +3142,7 @@ void ntreeSetOutput(bNodeTree *ntree)
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->typeinfo->nclass == NODE_CLASS_OUTPUT) {
/* we need a check for which output node should be tagged like this, below an exception */
- if (node->type == CMP_NODE_OUTPUT_FILE) {
+ if (ELEM(node->type, CMP_NODE_OUTPUT_FILE, GEO_NODE_VIEWER)) {
continue;
}
@@ -3096,8 +3153,8 @@ void ntreeSetOutput(bNodeTree *ntree)
if (ntree->type == NTREE_COMPOSIT) {
/* same type, exception for viewer */
if (tnode->type == node->type ||
- (ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER) &&
- ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER))) {
+ (ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) &&
+ ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))) {
if (tnode->flag & NODE_DO_OUTPUT) {
output++;
if (output > 1) {
@@ -3324,10 +3381,18 @@ struct bNodeSocket *ntreeAddSocketInterfaceFromSocket(bNodeTree *ntree,
bNode *from_node,
bNodeSocket *from_sock)
{
- bNodeSocket *iosock = ntreeAddSocketInterface(ntree,
- static_cast<eNodeSocketInOut>(from_sock->in_out),
- from_sock->idname,
- DATA_(from_sock->name));
+ return ntreeAddSocketInterfaceFromSocketWithName(
+ ntree, from_node, from_sock, from_sock->idname, from_sock->name);
+}
+
+struct bNodeSocket *ntreeAddSocketInterfaceFromSocketWithName(bNodeTree *ntree,
+ bNode *from_node,
+ bNodeSocket *from_sock,
+ const char *idname,
+ const char *name)
+{
+ bNodeSocket *iosock = ntreeAddSocketInterface(
+ ntree, static_cast<eNodeSocketInOut>(from_sock->in_out), idname, DATA_(name));
if (iosock) {
if (iosock->typeinfo->interface_from_socket) {
iosock->typeinfo->interface_from_socket(ntree, iosock, from_node, from_sock);
@@ -3371,12 +3436,12 @@ void ntreeRemoveSocketInterface(bNodeTree *ntree, bNodeSocket *sock)
static void ntree_interface_identifier_base(bNodeTree *ntree, char *base)
{
/* generate a valid RNA identifier */
- sprintf(base, "NodeTreeInterface_%s", ntree->id.name + 2);
+ BLI_sprintf(base, "NodeTreeInterface_%s", ntree->id.name + 2);
RNA_identifier_sanitize(base, false);
}
/* check if the identifier is already in use */
-static bool ntree_interface_unique_identifier_check(void *UNUSED(data), const char *identifier)
+static bool ntree_interface_unique_identifier_check(void * /*data*/, const char *identifier)
{
return (RNA_struct_find(identifier) != nullptr);
}
@@ -3397,8 +3462,8 @@ static void ntree_interface_identifier(bNodeTree *ntree,
BLI_uniquename_cb(
ntree_interface_unique_identifier_check, nullptr, base, '_', identifier, maxlen);
- sprintf(name, "Node Tree %s Interface", ntree->id.name + 2);
- sprintf(description, "Interface properties of node group %s", ntree->id.name + 2);
+ BLI_sprintf(name, "Node Tree %s Interface", ntree->id.name + 2);
+ BLI_sprintf(description, "Interface properties of node group %s", ntree->id.name + 2);
}
static void ntree_interface_type_create(bNodeTree *ntree)
@@ -3650,7 +3715,7 @@ void nodeSocketDeclarationsUpdate(bNode *node)
update_socket_declarations(&node->outputs, node->runtime->declaration->outputs());
}
-bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree *UNUSED(ntree), bNode *node)
+bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree * /*ntree*/, bNode *node)
{
if (node->runtime->declaration != nullptr) {
return false;
@@ -3870,15 +3935,15 @@ bNodeInstanceKey BKE_node_instance_key(bNodeInstanceKey parent_key,
return key;
}
-static unsigned int node_instance_hash_key(const void *key)
+static uint node_instance_hash_key(const void *key)
{
return ((const bNodeInstanceKey *)key)->value;
}
static bool node_instance_hash_key_cmp(const void *a, const void *b)
{
- unsigned int value_a = ((const bNodeInstanceKey *)a)->value;
- unsigned int value_b = ((const bNodeInstanceKey *)b)->value;
+ uint value_a = ((const bNodeInstanceKey *)a)->value;
+ uint value_b = ((const bNodeInstanceKey *)b)->value;
return (value_a != value_b);
}
@@ -3949,7 +4014,7 @@ void BKE_node_instance_hash_clear_tags(bNodeInstanceHash *hash)
}
}
-void BKE_node_instance_hash_tag(bNodeInstanceHash *UNUSED(hash), void *value)
+void BKE_node_instance_hash_tag(bNodeInstanceHash * /*hash*/, void *value)
{
bNodeInstanceHashEntry *entry = (bNodeInstanceHashEntry *)value;
entry->tag = 1;
@@ -4155,9 +4220,9 @@ static void node_type_base_defaults(bNodeType *ntype)
}
/* allow this node for any tree type */
-static bool node_poll_default(bNodeType *UNUSED(ntype),
- bNodeTree *UNUSED(ntree),
- const char **UNUSED(disabled_hint))
+static bool node_poll_default(bNodeType * /*ntype*/,
+ bNodeTree * /*ntree*/,
+ const char ** /*disabled_hint*/)
{
return true;
}
@@ -4281,12 +4346,6 @@ void node_type_socket_templates(struct bNodeType *ntype,
}
}
-void node_type_init(struct bNodeType *ntype,
- void (*initfunc)(struct bNodeTree *ntree, struct bNode *node))
-{
- ntype->initfunc = initfunc;
-}
-
void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth)
{
ntype->width = width;
@@ -4334,38 +4393,11 @@ void node_type_storage(bNodeType *ntype,
ntype->freefunc = freefunc;
}
-void node_type_update(struct bNodeType *ntype,
- void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
-{
- ntype->updatefunc = updatefunc;
-}
-
-void node_type_group_update(struct bNodeType *ntype,
- void (*group_update_func)(struct bNodeTree *ntree, struct bNode *node))
-{
- ntype->group_update_func = group_update_func;
-}
-
-void node_type_exec(struct bNodeType *ntype,
- NodeInitExecFunction init_exec_fn,
- NodeFreeExecFunction free_exec_fn,
- NodeExecFunction exec_fn)
-{
- ntype->init_exec_fn = init_exec_fn;
- ntype->free_exec_fn = free_exec_fn;
- ntype->exec_fn = exec_fn;
-}
-
-void node_type_gpu(struct bNodeType *ntype, NodeGPUExecFunction gpu_fn)
-{
- ntype->gpu_fn = gpu_fn;
-}
-
/* callbacks for undefined types */
-static bool node_undefined_poll(bNodeType *UNUSED(ntype),
- bNodeTree *UNUSED(nodetree),
- const char **UNUSED(r_disabled_hint))
+static bool node_undefined_poll(bNodeType * /*ntype*/,
+ bNodeTree * /*nodetree*/,
+ const char ** /*r_disabled_hint*/)
{
/* this type can not be added deliberately, it's just a placeholder */
return false;
@@ -4699,9 +4731,12 @@ static void registerGeometryNodes()
register_node_type_geo_curve_subdivide();
register_node_type_geo_curve_to_mesh();
register_node_type_geo_curve_to_points();
+ register_node_type_geo_curve_topology_curve_of_point();
+ register_node_type_geo_curve_topology_points_of_curve();
register_node_type_geo_curve_trim();
register_node_type_geo_deform_curves_on_surface();
register_node_type_geo_delete_geometry();
+ register_node_type_geo_distribute_points_in_volume();
register_node_type_geo_distribute_points_on_faces();
register_node_type_geo_dual_mesh();
register_node_type_geo_duplicate_elements();
@@ -4748,6 +4783,7 @@ static void registerGeometryNodes()
register_node_type_geo_material_replace();
register_node_type_geo_material_selection();
register_node_type_geo_merge_by_distance();
+ register_node_type_geo_mesh_face_set_boundaries();
register_node_type_geo_mesh_primitive_circle();
register_node_type_geo_mesh_primitive_cone();
register_node_type_geo_mesh_primitive_cube();
@@ -4760,7 +4796,15 @@ static void registerGeometryNodes()
register_node_type_geo_mesh_to_curve();
register_node_type_geo_mesh_to_points();
register_node_type_geo_mesh_to_volume();
+ register_node_type_geo_mesh_topology_offset_corner_in_face();
+ register_node_type_geo_mesh_topology_corners_of_face();
+ register_node_type_geo_mesh_topology_corners_of_vertex();
+ register_node_type_geo_mesh_topology_edges_of_corner();
+ register_node_type_geo_mesh_topology_edges_of_vertex();
+ register_node_type_geo_mesh_topology_face_of_corner();
+ register_node_type_geo_mesh_topology_vertex_of_corner();
register_node_type_geo_object_info();
+ register_node_type_geo_offset_point_in_curve();
register_node_type_geo_points_to_vertices();
register_node_type_geo_points_to_volume();
register_node_type_geo_points();
@@ -4769,11 +4813,17 @@ static void registerGeometryNodes()
register_node_type_geo_realize_instances();
register_node_type_geo_remove_attribute();
register_node_type_geo_rotate_instances();
+ register_node_type_geo_sample_index();
+ register_node_type_geo_sample_nearest_surface();
+ register_node_type_geo_sample_nearest();
+ register_node_type_geo_sample_uv_surface();
register_node_type_geo_scale_elements();
register_node_type_geo_scale_instances();
register_node_type_geo_separate_components();
register_node_type_geo_separate_geometry();
+ register_node_type_geo_self_object();
register_node_type_geo_set_curve_handles();
+ register_node_type_geo_set_curve_normal();
register_node_type_geo_set_curve_radius();
register_node_type_geo_set_curve_tilt();
register_node_type_geo_set_id();
@@ -4789,7 +4839,6 @@ static void registerGeometryNodes()
register_node_type_geo_string_to_curves();
register_node_type_geo_subdivision_surface();
register_node_type_geo_switch();
- register_node_type_geo_transfer_attribute();
register_node_type_geo_transform();
register_node_type_geo_translate_instances();
register_node_type_geo_triangulate();
diff --git a/source/blender/blenkernel/intern/node_runtime.cc b/source/blender/blenkernel/intern/node_runtime.cc
index 00b78284791..4fb0e423a33 100644
--- a/source/blender/blenkernel/intern/node_runtime.cc
+++ b/source/blender/blenkernel/intern/node_runtime.cc
@@ -14,16 +14,12 @@
namespace blender::bke::node_tree_runtime {
-void handle_node_tree_output_changed(bNodeTree &tree_cow)
+void preprocess_geometry_node_tree_for_evaluation(bNodeTree &tree_cow)
{
- if (tree_cow.type == NTREE_GEOMETRY) {
- /* Rebuild geometry nodes lazy function graph. */
- {
- std::lock_guard lock{tree_cow.runtime->geometry_nodes_lazy_function_graph_info_mutex};
- tree_cow.runtime->geometry_nodes_lazy_function_graph_info.reset();
- }
- blender::nodes::ensure_geometry_nodes_lazy_function_graph(tree_cow);
- }
+ BLI_assert(tree_cow.type == NTREE_GEOMETRY);
+ /* Rebuild geometry nodes lazy function graph. */
+ tree_cow.runtime->geometry_nodes_lazy_function_graph_info.reset();
+ blender::nodes::ensure_geometry_nodes_lazy_function_graph(tree_cow);
}
static void double_checked_lock(std::mutex &mutex, bool &data_is_dirty, FunctionRef<void()> fn)
@@ -127,15 +123,17 @@ static void update_directly_linked_links_and_sockets(const bNodeTree &ntree)
socket->runtime->directly_linked_links.clear();
socket->runtime->directly_linked_sockets.clear();
}
- node->runtime->has_linked_inputs = false;
- node->runtime->has_linked_outputs = false;
+ node->runtime->has_available_linked_inputs = false;
+ node->runtime->has_available_linked_outputs = false;
}
for (bNodeLink *link : tree_runtime.links) {
link->fromsock->runtime->directly_linked_links.append(link);
link->fromsock->runtime->directly_linked_sockets.append(link->tosock);
link->tosock->runtime->directly_linked_links.append(link);
- link->fromnode->runtime->has_linked_outputs = true;
- link->tonode->runtime->has_linked_inputs = true;
+ if (link->is_available()) {
+ link->fromnode->runtime->has_available_linked_outputs = true;
+ link->tonode->runtime->has_available_linked_inputs = true;
+ }
}
for (bNodeSocket *socket : tree_runtime.input_sockets) {
if (socket->flag & SOCK_MULTI_INPUT) {
@@ -172,7 +170,10 @@ static void find_logical_origins_for_socket_recursive(
links_to_check = links_to_check.take_front(1);
}
for (bNodeLink *link : links_to_check) {
- if (link->flag & NODE_LINK_MUTED) {
+ if (link->is_muted()) {
+ continue;
+ }
+ if (!link->is_available()) {
continue;
}
bNodeSocket &origin_socket = *link->fromsock;
@@ -289,14 +290,20 @@ static void toposort_from_start_node(const ToposortDirection direction,
break;
}
bNodeSocket &socket = *sockets[item.socket_index];
- const Span<bNodeSocket *> linked_sockets = socket.runtime->directly_linked_sockets;
- if (item.link_index == linked_sockets.size()) {
+ const Span<bNodeLink *> linked_links = socket.runtime->directly_linked_links;
+ if (item.link_index == linked_links.size()) {
/* All links connected to this socket have already been visited. */
item.socket_index++;
item.link_index = 0;
continue;
}
- bNodeSocket &linked_socket = *linked_sockets[item.link_index];
+ bNodeLink &link = *linked_links[item.link_index];
+ if (!link.is_available()) {
+ /* Ignore unavailable links. */
+ item.link_index++;
+ continue;
+ }
+ bNodeSocket &linked_socket = *socket.runtime->directly_linked_sockets[item.link_index];
bNode &linked_node = *linked_socket.runtime->owner_node;
ToposortNodeState &linked_node_state = node_states[linked_node.runtime->index_in_tree];
if (linked_node_state.is_done) {
@@ -341,8 +348,9 @@ static void update_toposort(const bNodeTree &ntree,
/* Ignore nodes that are done already. */
continue;
}
- if ((direction == ToposortDirection::LeftToRight) ? node->runtime->has_linked_outputs :
- node->runtime->has_linked_inputs) {
+ if ((direction == ToposortDirection::LeftToRight) ?
+ node->runtime->has_available_linked_outputs :
+ node->runtime->has_available_linked_inputs) {
/* Ignore non-start nodes. */
continue;
}
@@ -402,7 +410,7 @@ static void ensure_topology_cache(const bNodeTree &ntree)
update_toposort(ntree,
ToposortDirection::LeftToRight,
tree_runtime.toposort_left_to_right,
- tree_runtime.has_link_cycle);
+ tree_runtime.has_available_link_cycle);
},
[&]() {
bool dummy;
diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc
index b2caaa912d7..707bb83a3bc 100644
--- a/source/blender/blenkernel/intern/node_tree_update.cc
+++ b/source/blender/blenkernel/intern/node_tree_update.cc
@@ -1047,6 +1047,7 @@ class NodeTreeMainUpdater {
void update_individual_nodes(bNodeTree &ntree)
{
+ Vector<bNode *> group_inout_nodes;
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
nodeDeclarationEnsure(&ntree, node);
if (this->should_update_individual_node(ntree, *node)) {
@@ -1058,6 +1059,18 @@ class NodeTreeMainUpdater {
ntype.updatefunc(&ntree, node);
}
}
+ if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) {
+ group_inout_nodes.append(node);
+ }
+ }
+ /* The update function of group input/output nodes may add new interface sockets. When that
+ * happens, all the input/output nodes have to be updated again. In the future it would be
+ * better to move this functionality out of the node update function into the operator that's
+ * supposed to create the new interface socket. */
+ if (ntree.runtime->changed_flag & NTREE_CHANGED_INTERFACE) {
+ for (bNode *node : group_inout_nodes) {
+ node->typeinfo->updatefunc(&ntree, node);
+ }
}
}
@@ -1375,7 +1388,7 @@ class NodeTreeMainUpdater {
uint32_t get_combined_socket_topology_hash(const bNodeTree &tree,
Span<const bNodeSocket *> sockets)
{
- if (tree.has_link_cycle()) {
+ if (tree.has_available_link_cycle()) {
/* Return dummy value when the link has any cycles. The algorithm below could be improved to
* handle cycles more gracefully. */
return 0;
@@ -1389,12 +1402,17 @@ class NodeTreeMainUpdater {
}
Array<uint32_t> get_socket_topology_hashes(const bNodeTree &tree,
- Span<const bNodeSocket *> sockets)
+ const Span<const bNodeSocket *> sockets)
{
- BLI_assert(!tree.has_link_cycle());
+ BLI_assert(!tree.has_available_link_cycle());
Array<std::optional<uint32_t>> hash_by_socket_id(tree.all_sockets().size());
Stack<const bNodeSocket *> sockets_to_check = sockets;
+ auto get_socket_ptr_hash = [&](const bNodeSocket &socket) {
+ const uint64_t socket_ptr = uintptr_t(&socket);
+ return noise::hash(socket_ptr, socket_ptr >> 32);
+ };
+
while (!sockets_to_check.is_empty()) {
const bNodeSocket &socket = *sockets_to_check.peek();
const bNode &node = socket.owner_node();
@@ -1405,31 +1423,45 @@ class NodeTreeMainUpdater {
continue;
}
+ uint32_t socket_hash = 0;
if (socket.is_input()) {
/* For input sockets, first compute the hashes of all linked sockets. */
bool all_origins_computed = true;
- for (const bNodeSocket *origin_socket : socket.logically_linked_sockets()) {
- if (!hash_by_socket_id[origin_socket->index_in_tree()].has_value()) {
- sockets_to_check.push(origin_socket);
+ bool get_value_from_origin = false;
+ for (const bNodeLink *link : socket.directly_linked_links()) {
+ if (link->is_muted()) {
+ continue;
+ }
+ if (!link->is_available()) {
+ continue;
+ }
+ const bNodeSocket &origin_socket = *link->fromsock;
+ const std::optional<uint32_t> origin_hash =
+ hash_by_socket_id[origin_socket.index_in_tree()];
+ if (origin_hash.has_value()) {
+ if (get_value_from_origin || socket.type != origin_socket.type) {
+ socket_hash = noise::hash(socket_hash, *origin_hash);
+ }
+ else {
+ /* Copy the socket hash because the link did not change it. */
+ socket_hash = *origin_hash;
+ }
+ get_value_from_origin = true;
+ }
+ else {
+ sockets_to_check.push(&origin_socket);
all_origins_computed = false;
}
}
if (!all_origins_computed) {
continue;
}
- /* When the hashes for the linked sockets are ready, combine them into a hash for the input
- * socket. */
- const uint64_t socket_ptr = (uintptr_t)&socket;
- uint32_t socket_hash = noise::hash(socket_ptr, socket_ptr >> 32);
- for (const bNodeSocket *origin_socket : socket.logically_linked_sockets()) {
- const uint32_t origin_socket_hash = *hash_by_socket_id[origin_socket->index_in_tree()];
- socket_hash = noise::hash(socket_hash, origin_socket_hash);
+
+ if (!get_value_from_origin) {
+ socket_hash = get_socket_ptr_hash(socket);
}
- hash_by_socket_id[socket.index_in_tree()] = socket_hash;
- sockets_to_check.pop();
}
else {
- /* For output sockets, first compute the hashes of all available input sockets. */
bool all_available_inputs_computed = true;
for (const bNodeSocket *input_socket : node.input_sockets()) {
if (input_socket->is_available()) {
@@ -1442,29 +1474,48 @@ class NodeTreeMainUpdater {
if (!all_available_inputs_computed) {
continue;
}
- /* When all input socket hashes have been computed, combine them into a hash for the output
- * socket. */
- const uint64_t socket_ptr = (uintptr_t)&socket;
- uint32_t socket_hash = noise::hash(socket_ptr, socket_ptr >> 32);
- for (const bNodeSocket *input_socket : node.input_sockets()) {
- if (input_socket->is_available()) {
- const uint32_t input_socket_hash = *hash_by_socket_id[input_socket->index_in_tree()];
- socket_hash = noise::hash(socket_hash, input_socket_hash);
+ if (node.type == NODE_REROUTE) {
+ socket_hash = *hash_by_socket_id[node.input_socket(0).index_in_tree()];
+ }
+ else if (node.is_muted()) {
+ const bNodeSocket *internal_input = socket.internal_link_input();
+ if (internal_input == nullptr) {
+ socket_hash = get_socket_ptr_hash(socket);
+ }
+ else {
+ if (internal_input->type == socket.type) {
+ socket_hash = *hash_by_socket_id[internal_input->index_in_tree()];
+ }
+ else {
+ socket_hash = get_socket_ptr_hash(socket);
+ }
}
}
- /* The Image Texture node has a special case. The behavior of the color output changes
- * depending on whether the Alpha output is linked. */
- if (node.type == SH_NODE_TEX_IMAGE && socket.index() == 0) {
- BLI_assert(STREQ(socket.name, "Color"));
- const bNodeSocket &alpha_socket = node.output_socket(1);
- BLI_assert(STREQ(alpha_socket.name, "Alpha"));
- if (alpha_socket.is_directly_linked()) {
- socket_hash = noise::hash(socket_hash);
+ else {
+ socket_hash = get_socket_ptr_hash(socket);
+ for (const bNodeSocket *input_socket : node.input_sockets()) {
+ if (input_socket->is_available()) {
+ const uint32_t input_socket_hash = *hash_by_socket_id[input_socket->index_in_tree()];
+ socket_hash = noise::hash(socket_hash, input_socket_hash);
+ }
+ }
+
+ /* The Image Texture node has a special case. The behavior of the color output changes
+ * depending on whether the Alpha output is linked. */
+ if (node.type == SH_NODE_TEX_IMAGE && socket.index() == 0) {
+ BLI_assert(STREQ(socket.name, "Color"));
+ const bNodeSocket &alpha_socket = node.output_socket(1);
+ BLI_assert(STREQ(alpha_socket.name, "Alpha"));
+ if (alpha_socket.is_directly_linked()) {
+ socket_hash = noise::hash(socket_hash);
+ }
}
}
- hash_by_socket_id[socket.index_in_tree()] = socket_hash;
- sockets_to_check.pop();
}
+ hash_by_socket_id[socket.index_in_tree()] = socket_hash;
+ /* Check that nothing has been pushed in the meantime. */
+ BLI_assert(sockets_to_check.peek() == &socket);
+ sockets_to_check.pop();
}
/* Create output array. */
@@ -1505,7 +1556,7 @@ class NodeTreeMainUpdater {
}
}
if (socket.is_input()) {
- for (const bNodeSocket *origin_socket : socket.logically_linked_sockets()) {
+ for (const bNodeSocket *origin_socket : socket.directly_linked_sockets()) {
bool &pushed = pushed_by_socket_id[origin_socket->index_in_tree()];
if (!pushed) {
sockets_to_check.push(origin_socket);
@@ -1628,12 +1679,12 @@ void BKE_ntree_update_tag_link_removed(bNodeTree *ntree)
add_tree_tag(ntree, NTREE_CHANGED_LINK);
}
-void BKE_ntree_update_tag_link_added(bNodeTree *ntree, bNodeLink *UNUSED(link))
+void BKE_ntree_update_tag_link_added(bNodeTree *ntree, bNodeLink * /*link*/)
{
add_tree_tag(ntree, NTREE_CHANGED_LINK);
}
-void BKE_ntree_update_tag_link_mute(bNodeTree *ntree, bNodeLink *UNUSED(link))
+void BKE_ntree_update_tag_link_mute(bNodeTree *ntree, bNodeLink * /*link*/)
{
add_tree_tag(ntree, NTREE_CHANGED_LINK);
}
@@ -1666,7 +1717,7 @@ void BKE_ntree_update_tag_id_changed(Main *bmain, ID *id)
FOREACH_NODETREE_END;
}
-void BKE_ntree_update_tag_image_user_changed(bNodeTree *ntree, ImageUser *UNUSED(iuser))
+void BKE_ntree_update_tag_image_user_changed(bNodeTree *ntree, ImageUser * /*iuser*/)
{
/* Would have to search for the node that uses the image user for a more detailed tag. */
add_tree_tag(ntree, NTREE_CHANGED_ANY);
diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc
index e4d09fddb79..9085a54d86f 100644
--- a/source/blender/blenkernel/intern/object.cc
+++ b/source/blender/blenkernel/intern/object.cc
@@ -188,7 +188,7 @@ static void object_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const in
/* Do not copy runtime data. */
BKE_object_runtime_reset_on_copy(ob_dst, flag);
- /* We never handle usercount here for own data. */
+ /* We never handle user-count here for own data. */
const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
if (ob_src->totcol) {
@@ -245,7 +245,7 @@ static void object_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const in
BLI_listbase_clear(&ob_dst->modifiers);
BLI_listbase_clear(&ob_dst->greasepencil_modifiers);
- /* NOTE: Also takes care of softbody and particle systems copying. */
+ /* NOTE: Also takes care of soft-body and particle systems copying. */
BKE_object_modifier_stack_copy(ob_dst, ob_src, true, flag_subdata);
BLI_listbase_clear((ListBase *)&ob_dst->drawdata);
@@ -321,7 +321,7 @@ static void object_free_data(ID *id)
}
static void library_foreach_modifiersForeachIDLink(void *user_data,
- Object *UNUSED(object),
+ Object * /*object*/,
ID **id_pointer,
int cb_flag)
{
@@ -331,7 +331,7 @@ static void library_foreach_modifiersForeachIDLink(void *user_data,
}
static void library_foreach_gpencil_modifiersForeachIDLink(void *user_data,
- Object *UNUSED(object),
+ Object * /*object*/,
ID **id_pointer,
int cb_flag)
{
@@ -341,7 +341,7 @@ static void library_foreach_gpencil_modifiersForeachIDLink(void *user_data,
}
static void library_foreach_shaderfxForeachIDLink(void *user_data,
- Object *UNUSED(object),
+ Object * /*object*/,
ID **id_pointer,
int cb_flag)
{
@@ -350,7 +350,7 @@ static void library_foreach_shaderfxForeachIDLink(void *user_data,
data, BKE_lib_query_foreachid_process(data, id_pointer, cb_flag));
}
-static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con),
+static void library_foreach_constraintObjectLooper(bConstraint * /*con*/,
ID **id_pointer,
bool is_reference,
void *user_data)
@@ -361,7 +361,7 @@ static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con),
data, BKE_lib_query_foreachid_process(data, id_pointer, cb_flag));
}
-static void library_foreach_particlesystemsObjectLooper(ParticleSystem *UNUSED(psys),
+static void library_foreach_particlesystemsObjectLooper(ParticleSystem * /*psys*/,
ID **id_pointer,
void *user_data,
int cb_flag)
@@ -396,7 +396,7 @@ static void object_foreach_id(ID *id, LibraryForeachIDData *data)
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, object->mat[i], IDWALK_CB_USER);
}
- /* Note that ob->gpd is deprecated, so no need to handle it here. */
+ /* Note that `ob->gpd` is deprecated, so no need to handle it here. */
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, object->instance_collection, IDWALK_CB_USER);
if (object->pd) {
@@ -736,9 +736,9 @@ static void object_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_data_address(reader, &sb->shared);
if (sb->shared == nullptr) {
/* Link deprecated caches if they exist, so we can use them for versioning.
- * We should only do this when sb->shared == nullptr, because those pointers
+ * We should only do this when `sb->shared == nullptr`, because those pointers
* are always set (for compatibility with older Blenders). We mustn't link
- * the same pointcache twice. */
+ * the same point-cache twice. */
BKE_ptcache_blend_read_data(reader, &sb->ptcaches, &sb->pointcache, false);
}
else {
@@ -1017,9 +1017,9 @@ static void expand_constraint_channels(BlendExpander *expander, ListBase *chanba
}
static void expand_object_expandModifiers(void *userData,
- Object *UNUSED(ob),
+ Object * /*ob*/,
ID **idpoin,
- int UNUSED(cb_flag))
+ int /*cb_flag*/)
{
BlendExpander *expander = (BlendExpander *)userData;
BLO_expand(expander, *idpoin);
@@ -1141,7 +1141,7 @@ static void object_lib_override_apply_post(ID *id_dst, ID *id_src)
* This code is a workaround this to check all point-caches from both source and destination
* objects in parallel, and transfer those flags when it makes sense.
*
- * This allows to keep baked caches across liboverrides applies.
+ * This allows to keep baked caches across lib-overrides applies.
*
* NOTE: This is fairly hackish and weak, but so is the point-cache system as its whole. A more
* robust solution would be e.g. to have a specific RNA entry point to deal with such cases
@@ -1170,7 +1170,7 @@ static void object_lib_override_apply_post(ID *id_dst, ID *id_src)
point_cache_dst != nullptr;
point_cache_dst = point_cache_dst->next,
point_cache_src = (point_cache_src != nullptr) ? point_cache_src->next : nullptr) {
- /* Always force updating info about caches of applied liboverrides. */
+ /* Always force updating info about caches of applied lib-overrides. */
point_cache_dst->flag |= PTCACHE_FLAG_INFO_DIRTY;
if (point_cache_src == nullptr || !STREQ(point_cache_dst->name, point_cache_src->name)) {
continue;
@@ -1300,10 +1300,10 @@ void BKE_object_free_modifiers(Object *ob, const int flag)
while ((gp_md = (GpencilModifierData *)BLI_pophead(&ob->greasepencil_modifiers))) {
BKE_gpencil_modifier_free_ex(gp_md, flag);
}
- /* particle modifiers were freed, so free the particlesystems as well */
+ /* Particle modifiers were freed, so free the particle-systems as well. */
BKE_object_free_particlesystems(ob);
- /* same for softbody */
+ /* Same for soft-body */
BKE_object_free_softbody(ob);
/* modifiers may have stored data in the DM cache */
@@ -1330,14 +1330,14 @@ void BKE_object_modifier_hook_reset(Object *ob, HookModifierData *hmd)
/* Calculate the world-space matrix for the pose-channel target first,
* then carry on as usual. */
- mul_m4_m4m4(mat, hmd->object->obmat, pchan->pose_mat);
+ mul_m4_m4m4(mat, hmd->object->object_to_world, pchan->pose_mat);
invert_m4_m4(imat, mat);
- mul_m4_m4m4(hmd->parentinv, imat, ob->obmat);
+ mul_m4_m4m4(hmd->parentinv, imat, ob->object_to_world);
}
else {
- invert_m4_m4(hmd->object->imat, hmd->object->obmat);
- mul_m4_m4m4(hmd->parentinv, hmd->object->imat, ob->obmat);
+ invert_m4_m4(hmd->object->world_to_object, hmd->object->object_to_world);
+ mul_m4_m4m4(hmd->parentinv, hmd->object->world_to_object, ob->object_to_world);
}
}
}
@@ -1355,14 +1355,14 @@ void BKE_object_modifier_gpencil_hook_reset(Object *ob, HookGpencilModifierData
/* Calculate the world-space matrix for the pose-channel target first,
* then carry on as usual. */
- mul_m4_m4m4(mat, hmd->object->obmat, pchan->pose_mat);
+ mul_m4_m4m4(mat, hmd->object->object_to_world, pchan->pose_mat);
invert_m4_m4(imat, mat);
- mul_m4_m4m4(hmd->parentinv, imat, ob->obmat);
+ mul_m4_m4m4(hmd->parentinv, imat, ob->object_to_world);
}
else {
- invert_m4_m4(hmd->object->imat, hmd->object->obmat);
- mul_m4_m4m4(hmd->parentinv, hmd->object->imat, ob->obmat);
+ invert_m4_m4(hmd->object->world_to_object, hmd->object->object_to_world);
+ mul_m4_m4m4(hmd->parentinv, hmd->object->world_to_object, ob->object_to_world);
}
}
@@ -1402,15 +1402,15 @@ ModifierData *BKE_object_active_modifier(const Object *ob)
bool BKE_object_supports_modifiers(const Object *ob)
{
- return (ELEM(ob->type,
- OB_MESH,
- OB_CURVES,
- OB_CURVES_LEGACY,
- OB_SURF,
- OB_FONT,
- OB_LATTICE,
- OB_POINTCLOUD,
- OB_VOLUME));
+ return ELEM(ob->type,
+ OB_MESH,
+ OB_CURVES,
+ OB_CURVES_LEGACY,
+ OB_SURF,
+ OB_FONT,
+ OB_LATTICE,
+ OB_POINTCLOUD,
+ OB_VOLUME);
}
bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type)
@@ -1448,11 +1448,11 @@ static bool object_modifier_type_copy_check(ModifierType md_type)
}
/**
- * Find a `psys` matching given `psys_src` in `ob_dst` (i.e. sharing the same ParticleSettings ID),
- * or add one, and return valid `psys` from `ob_dst`.
+ * Find a `psys` matching given `psys_src` in `ob_dst`
+ * (i.e. sharing the same #ParticleSettings ID), or add one, and return valid `psys` from `ob_dst`.
*
* \note Order handling is fairly weak here. This code assumes that it is called **before** the
- * modifier using the psys is actually copied, and that this copied modifier will be added at the
+ * modifier using the `psys` is actually copied, and that this copied modifier will be added at the
* end of the stack. That way we can be sure that the particle modifier will be before the one
* using its particle system in the stack.
*/
@@ -1691,7 +1691,7 @@ static void object_update_from_subsurf_ccg(Object *object)
if (mesh_eval == nullptr) {
return;
}
- SubdivCCG *subdiv_ccg = mesh_eval->runtime.subdiv_ccg;
+ SubdivCCG *subdiv_ccg = mesh_eval->runtime->subdiv_ccg;
if (subdiv_ccg == nullptr) {
return;
}
@@ -1699,7 +1699,7 @@ static void object_update_from_subsurf_ccg(Object *object)
if (!subdiv_ccg->dirty.coords && !subdiv_ccg->dirty.hidden) {
return;
}
- const int tot_level = mesh_eval->runtime.subdiv_ccg_tot_level;
+ const int tot_level = mesh_eval->runtime->subdiv_ccg_tot_level;
Object *object_orig = DEG_get_original_object(object);
Mesh *mesh_orig = (Mesh *)object_orig->data;
multiresModifier_reshapeFromCCG(tot_level, mesh_orig, subdiv_ccg);
@@ -1902,6 +1902,7 @@ bool BKE_object_is_in_editmode(const Object *ob)
/* Grease Pencil object has no edit mode data. */
return GPENCIL_EDIT_MODE((bGPdata *)ob->data);
case OB_CURVES:
+ /* Curves object has no edit mode data. */
return ob->mode == OB_MODE_EDIT;
default:
return false;
@@ -2258,26 +2259,29 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
return ob;
}
-static Object *object_add_common(Main *bmain, ViewLayer *view_layer, int type, const char *name)
+static Object *object_add_common(
+ Main *bmain, const Scene *scene, ViewLayer *view_layer, int type, const char *name)
{
Object *ob = BKE_object_add_only_object(bmain, type, name);
ob->data = BKE_object_obdata_add_from_type(bmain, type, name);
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
DEG_id_tag_update_ex(
bmain, &ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
return ob;
}
-Object *BKE_object_add(Main *bmain, ViewLayer *view_layer, int type, const char *name)
+Object *BKE_object_add(
+ Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name)
{
- Object *ob = object_add_common(bmain, view_layer, type, name);
+ Object *ob = object_add_common(bmain, scene, view_layer, type, name);
LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer);
BKE_collection_viewlayer_object_add(bmain, view_layer, layer_collection->collection, ob);
/* NOTE: There is no way to be sure that #BKE_collection_viewlayer_object_add will actually
* manage to find a valid collection in given `view_layer` to add the new object to. */
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob);
if (base != nullptr) {
BKE_view_layer_base_select_and_set_active(view_layer, base);
@@ -2289,17 +2293,23 @@ Object *BKE_object_add(Main *bmain, ViewLayer *view_layer, int type, const char
Object *BKE_object_add_from(
Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name, Object *ob_src)
{
- Object *ob = object_add_common(bmain, view_layer, type, name);
+ Object *ob = object_add_common(bmain, scene, view_layer, type, name);
BKE_collection_object_add_from(bmain, scene, ob_src, ob);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob);
BKE_view_layer_base_select_and_set_active(view_layer, base);
return ob;
}
-Object *BKE_object_add_for_data(
- Main *bmain, ViewLayer *view_layer, int type, const char *name, ID *data, bool do_id_user)
+Object *BKE_object_add_for_data(Main *bmain,
+ const Scene *scene,
+ ViewLayer *view_layer,
+ int type,
+ const char *name,
+ ID *data,
+ bool do_id_user)
{
/* same as object_add_common, except we don't create new ob->data */
Object *ob = BKE_object_add_only_object(bmain, type, name);
@@ -2308,13 +2318,14 @@ Object *BKE_object_add_for_data(
id_us_plus(data);
}
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
DEG_id_tag_update_ex(
bmain, &ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer);
BKE_collection_object_add(bmain, layer_collection->collection, ob);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob);
BKE_view_layer_base_select_and_set_active(view_layer, base);
@@ -2474,8 +2485,8 @@ void BKE_object_copy_particlesystems(Object *ob_dst, const Object *ob_src, const
static void copy_object_pose(Object *obn, const Object *ob, const int flag)
{
- /* NOTE: need to clear obn->pose pointer first,
- * so that BKE_pose_copy_data works (otherwise there's a crash) */
+ /* NOTE: need to clear `obn->pose` pointer first,
+ * so that #BKE_pose_copy_data works (otherwise there's a crash) */
obn->pose = nullptr;
BKE_pose_copy_data_ex(&obn->pose, ob->pose, flag, true); /* true = copy constraints */
@@ -2530,10 +2541,36 @@ Object *BKE_object_pose_armature_get(Object *ob)
return nullptr;
}
-Object *BKE_object_pose_armature_get_visible(Object *ob, ViewLayer *view_layer, View3D *v3d)
+Object *BKE_object_pose_armature_get_with_wpaint_check(Object *ob)
+{
+ /* When not in weight paint mode. */
+ if (ob) {
+ switch (ob->type) {
+ case OB_MESH: {
+ if ((ob->mode & OB_MODE_WEIGHT_PAINT) == 0) {
+ return nullptr;
+ }
+ break;
+ }
+ case OB_GPENCIL: {
+ if ((ob->mode & OB_MODE_WEIGHT_GPENCIL) == 0) {
+ return nullptr;
+ }
+ break;
+ }
+ }
+ }
+ return BKE_object_pose_armature_get(ob);
+}
+
+Object *BKE_object_pose_armature_get_visible(Object *ob,
+ const Scene *scene,
+ ViewLayer *view_layer,
+ View3D *v3d)
{
Object *ob_armature = BKE_object_pose_armature_get(ob);
if (ob_armature) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob_armature);
if (base) {
if (BASE_VISIBLE(v3d, base)) {
@@ -2544,11 +2581,10 @@ Object *BKE_object_pose_armature_get_visible(Object *ob, ViewLayer *view_layer,
return nullptr;
}
-Object **BKE_object_pose_array_get_ex(ViewLayer *view_layer,
- View3D *v3d,
- uint *r_objects_len,
- bool unique)
+Object **BKE_object_pose_array_get_ex(
+ const Scene *scene, ViewLayer *view_layer, View3D *v3d, uint *r_objects_len, bool unique)
{
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob_active = BKE_view_layer_active_object_get(view_layer);
Object *ob_pose = BKE_object_pose_armature_get(ob_active);
Object **objects = nullptr;
@@ -2558,7 +2594,7 @@ Object **BKE_object_pose_array_get_ex(ViewLayer *view_layer,
ob_params.no_dup_data = unique;
objects = BKE_view_layer_array_from_objects_in_mode_params(
- view_layer, v3d, r_objects_len, &ob_params);
+ scene, view_layer, v3d, r_objects_len, &ob_params);
}
else if (ob_pose != nullptr) {
*r_objects_len = 1;
@@ -2571,21 +2607,26 @@ Object **BKE_object_pose_array_get_ex(ViewLayer *view_layer,
}
return objects;
}
-Object **BKE_object_pose_array_get_unique(ViewLayer *view_layer, View3D *v3d, uint *r_objects_len)
+Object **BKE_object_pose_array_get_unique(const Scene *scene,
+ ViewLayer *view_layer,
+ View3D *v3d,
+ uint *r_objects_len)
{
- return BKE_object_pose_array_get_ex(view_layer, v3d, r_objects_len, true);
+ return BKE_object_pose_array_get_ex(scene, view_layer, v3d, r_objects_len, true);
}
-Object **BKE_object_pose_array_get(ViewLayer *view_layer, View3D *v3d, uint *r_objects_len)
+Object **BKE_object_pose_array_get(const Scene *scene,
+ ViewLayer *view_layer,
+ View3D *v3d,
+ uint *r_objects_len)
{
- return BKE_object_pose_array_get_ex(view_layer, v3d, r_objects_len, false);
+ return BKE_object_pose_array_get_ex(scene, view_layer, v3d, r_objects_len, false);
}
-Base **BKE_object_pose_base_array_get_ex(ViewLayer *view_layer,
- View3D *v3d,
- uint *r_bases_len,
- bool unique)
+Base **BKE_object_pose_base_array_get_ex(
+ const Scene *scene, ViewLayer *view_layer, View3D *v3d, uint *r_bases_len, bool unique)
{
- Base *base_active = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base_active = BKE_view_layer_active_base_get(view_layer);
Object *ob_pose = base_active ? BKE_object_pose_armature_get(base_active->object) : nullptr;
Base *base_pose = nullptr;
Base **bases = nullptr;
@@ -2605,7 +2646,7 @@ Base **BKE_object_pose_base_array_get_ex(ViewLayer *view_layer,
ob_params.no_dup_data = unique;
bases = BKE_view_layer_array_from_bases_in_mode_params(
- view_layer, v3d, r_bases_len, &ob_params);
+ scene, view_layer, v3d, r_bases_len, &ob_params);
}
else if (base_pose != nullptr) {
*r_bases_len = 1;
@@ -2618,13 +2659,19 @@ Base **BKE_object_pose_base_array_get_ex(ViewLayer *view_layer,
}
return bases;
}
-Base **BKE_object_pose_base_array_get_unique(ViewLayer *view_layer, View3D *v3d, uint *r_bases_len)
+Base **BKE_object_pose_base_array_get_unique(const Scene *scene,
+ ViewLayer *view_layer,
+ View3D *v3d,
+ uint *r_bases_len)
{
- return BKE_object_pose_base_array_get_ex(view_layer, v3d, r_bases_len, true);
+ return BKE_object_pose_base_array_get_ex(scene, view_layer, v3d, r_bases_len, true);
}
-Base **BKE_object_pose_base_array_get(ViewLayer *view_layer, View3D *v3d, uint *r_bases_len)
+Base **BKE_object_pose_base_array_get(const Scene *scene,
+ ViewLayer *view_layer,
+ View3D *v3d,
+ uint *r_bases_len)
{
- return BKE_object_pose_base_array_get_ex(view_layer, v3d, r_bases_len, false);
+ return BKE_object_pose_base_array_get_ex(scene, view_layer, v3d, r_bases_len, false);
}
void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
@@ -2892,7 +2939,7 @@ void BKE_object_rot_to_mat3(const Object *ob, float mat[3][3], bool use_drot)
axis_angle_to_mat3(dmat, ob->drotAxis, ob->drotAngle);
}
else {
- /* quats are normalized before use to eliminate scaling issues */
+ /* Quaternions are normalized before use to eliminate scaling issues. */
float tquat[4];
normalize_qt_qt(tquat, ob->quat);
@@ -2928,7 +2975,7 @@ void BKE_object_mat3_to_rot(Object *ob, float mat[3][3], bool use_compat)
float quat[4];
float dquat[4];
- /* without drot we could apply 'mat' directly */
+ /* Without `drot` we could apply 'mat' directly. */
mat3_normalized_to_quat(quat, mat);
axis_angle_to_quat(dquat, ob->drotAxis, ob->drotAngle);
invert_qt_normalized(dquat);
@@ -2941,12 +2988,12 @@ void BKE_object_mat3_to_rot(Object *ob, float mat[3][3], bool use_compat)
float quat[4];
float dquat[4];
- /* without drot we could apply 'mat' directly */
+ /* Without `drot` we could apply 'mat' directly. */
mat3_normalized_to_quat(quat, mat);
eulO_to_quat(dquat, ob->drot, ob->rotmode);
invert_qt_normalized(dquat);
mul_qt_qtqt(quat, dquat, quat);
- /* end drot correction */
+ /* End `drot` correction. */
if (use_compat) {
quat_to_compatible_eulO(ob->rot, ob->rot, ob->rotmode, quat);
@@ -2988,7 +3035,7 @@ void BKE_object_tfm_protected_restore(Object *ob,
const ObjectTfmProtectedChannels *obtfm,
const short protectflag)
{
- unsigned int i;
+ uint i;
for (i = 0; i < 3; i++) {
if (protectflag & (OB_LOCK_LOCX << i)) {
@@ -3077,10 +3124,10 @@ void BKE_object_matrix_local_get(struct Object *ob, float r_mat[4][4])
BKE_object_get_parent_matrix(ob, ob->parent, par_imat);
invert_m4(par_imat);
- mul_m4_m4m4(r_mat, par_imat, ob->obmat);
+ mul_m4_m4m4(r_mat, par_imat, ob->object_to_world);
}
else {
- copy_m4_m4(r_mat, ob->obmat);
+ copy_m4_m4(r_mat, ob->object_to_world);
}
}
@@ -3107,12 +3154,11 @@ static bool ob_parcurve(Object *ob, Object *par, float r_mat[4][4])
return false;
}
- /* ctime is now a proper var setting of Curve which gets set by Animato like any other var
+ /* `ctime` is now a proper var setting of Curve which gets set by Animato like any other var
* that's animated, but this will only work if it actually is animated.
*
* We divide the curve-time calculated in the previous step by the length of the path,
- * to get a time factor, which then gets clamped to lie within 0.0 - 1.0 range.
- */
+ * to get a time factor, which then gets clamped to lie within 0.0 - 1.0 range. */
if (cu->pathlen) {
ctime = cu->ctime / cu->pathlen;
}
@@ -3195,7 +3241,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
int count = 0;
int numVerts = me_eval->totvert;
- if (em && me_eval->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
+ if (em && me_eval->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
numVerts = em->bm->totvert;
if (em->bm->elem_table_dirty & BM_VERT) {
#ifdef VPARENT_THREADING_HACK
@@ -3210,8 +3256,8 @@ static void give_parvert(Object *par, int nr, float vec[3])
#endif
}
if (nr < numVerts) {
- if (me_eval && me_eval->runtime.edit_data && me_eval->runtime.edit_data->vertexCos) {
- add_v3_v3(vec, me_eval->runtime.edit_data->vertexCos[nr]);
+ if (me_eval && me_eval->runtime->edit_data && me_eval->runtime->edit_data->vertexCos) {
+ add_v3_v3(vec, me_eval->runtime->edit_data->vertexCos[nr]);
}
else {
const BMVert *v = BM_vert_at_index(em->bm, nr);
@@ -3329,38 +3375,38 @@ void BKE_object_get_parent_matrix(Object *ob, Object *par, float r_parentmat[4][
case PAROBJECT: {
bool ok = false;
if (par->type == OB_CURVES_LEGACY) {
- if ((((Curve *)par->data)->flag & CU_PATH) && (ob_parcurve(ob, par, tmat))) {
+ if ((((Curve *)par->data)->flag & CU_PATH) && ob_parcurve(ob, par, tmat)) {
ok = true;
}
}
if (ok) {
- mul_m4_m4m4(r_parentmat, par->obmat, tmat);
+ mul_m4_m4m4(r_parentmat, par->object_to_world, tmat);
}
else {
- copy_m4_m4(r_parentmat, par->obmat);
+ copy_m4_m4(r_parentmat, par->object_to_world);
}
break;
}
case PARBONE:
ob_parbone(ob, par, tmat);
- mul_m4_m4m4(r_parentmat, par->obmat, tmat);
+ mul_m4_m4m4(r_parentmat, par->object_to_world, tmat);
break;
case PARVERT1:
unit_m4(r_parentmat);
give_parvert(par, ob->par1, vec);
- mul_v3_m4v3(r_parentmat[3], par->obmat, vec);
+ mul_v3_m4v3(r_parentmat[3], par->object_to_world, vec);
break;
case PARVERT3:
ob_parvert3(ob, par, tmat);
- mul_m4_m4m4(r_parentmat, par->obmat, tmat);
+ mul_m4_m4m4(r_parentmat, par->object_to_world, tmat);
break;
case PARSKEL:
- copy_m4_m4(r_parentmat, par->obmat);
+ copy_m4_m4(r_parentmat, par->object_to_world);
break;
}
}
@@ -3391,14 +3437,14 @@ static void solve_parenting(
mul_m4_m4m4(r_obmat, tmat, locmat);
if (r_originmat) {
- /* usable originmat */
+ /* Usable `r_originmat`. */
copy_m3_m4(r_originmat, tmat);
}
/* origin, for help line */
if (set_origin) {
if ((ob->partype & PARTYPE) == PARSKEL) {
- copy_v3_v3(ob->runtime.parent_display_origin, par->obmat[3]);
+ copy_v3_v3(ob->runtime.parent_display_origin, par->object_to_world[3]);
}
else {
copy_v3_v3(ob->runtime.parent_display_origin, totmat[3]);
@@ -3417,10 +3463,10 @@ static void object_where_is_calc_ex(Depsgraph *depsgraph,
Object *par = ob->parent;
/* calculate parent matrix */
- solve_parenting(ob, par, true, ob->obmat, r_originmat);
+ solve_parenting(ob, par, true, ob->object_to_world, r_originmat);
}
else {
- BKE_object_to_mat4(ob, ob->obmat);
+ BKE_object_to_mat4(ob, ob->object_to_world);
}
/* try to fall back to the scene rigid body world if none given */
@@ -3437,7 +3483,7 @@ static void object_where_is_calc_ex(Depsgraph *depsgraph,
}
/* set negative scale flag in object */
- if (is_negative_m4(ob->obmat)) {
+ if (is_negative_m4(ob->object_to_world)) {
ob->transflag |= OB_NEG_SCALE;
}
else {
@@ -3483,7 +3529,7 @@ void BKE_object_workob_calc_parent(Depsgraph *depsgraph, Scene *scene, Object *o
{
BKE_object_workob_clear(workob);
- unit_m4(workob->obmat);
+ unit_m4(workob->object_to_world);
unit_m4(workob->parentinv);
unit_m4(workob->constinv);
@@ -3575,7 +3621,7 @@ void BKE_object_apply_parent_inverse(struct Object *ob)
* `inv(parent) @ world = parentinv`
* `parentinv = inv(parent) @ world`
*
- * NOTE: If `ob->obmat` has shear, then this `parentinv` is insufficient because
+ * NOTE: If `ob->object_to_world` has shear, then this `parentinv` is insufficient because
* `parent @ parentinv => shearless result`
*
* Thus, local will have shear which cannot be decomposed into TRS:
@@ -3604,7 +3650,7 @@ void BKE_object_apply_parent_inverse(struct Object *ob)
copy_m4_m4(ob_local, ob->parentinv);
invert_m4(ob_local);
mul_m4_m4_post(ob_local, par_imat);
- mul_m4_m4_post(ob_local, ob->obmat);
+ mul_m4_m4_post(ob_local, ob->object_to_world);
/* Send use_compat=False so the rotation is predictable. */
BKE_object_apply_mat4(ob, ob_local, false, false);
@@ -3769,7 +3815,7 @@ void BKE_object_dimensions_get(Object *ob, float r_vec[3])
const BoundBox *bb = BKE_object_boundbox_get(ob);
if (bb) {
float3 scale;
- mat4_to_size(scale, ob->obmat);
+ mat4_to_size(scale, ob->object_to_world);
r_vec[0] = fabsf(scale[0]) * (bb->vec[4][0] - bb->vec[0][0]);
r_vec[1] = fabsf(scale[1]) * (bb->vec[2][1] - bb->vec[0][1]);
@@ -3826,19 +3872,19 @@ void BKE_object_minmax(Object *ob, float r_min[3], float r_max[3], const bool us
case OB_FONT:
case OB_SURF: {
const BoundBox bb = *BKE_curve_boundbox_get(ob);
- BKE_boundbox_minmax(&bb, ob->obmat, r_min, r_max);
+ BKE_boundbox_minmax(&bb, ob->object_to_world, r_min, r_max);
changed = true;
break;
}
case OB_MESH: {
const BoundBox bb = *BKE_mesh_boundbox_get(ob);
- BKE_boundbox_minmax(&bb, ob->obmat, r_min, r_max);
+ BKE_boundbox_minmax(&bb, ob->object_to_world, r_min, r_max);
changed = true;
break;
}
case OB_GPENCIL: {
const BoundBox bb = *BKE_gpencil_boundbox_get(ob);
- BKE_boundbox_minmax(&bb, ob->obmat, r_min, r_max);
+ BKE_boundbox_minmax(&bb, ob->object_to_world, r_min, r_max);
changed = true;
break;
}
@@ -3851,7 +3897,7 @@ void BKE_object_minmax(Object *ob, float r_min[3], float r_max[3], const bool us
for (v = 0; v < lt->pntsv; v++) {
for (u = 0; u < lt->pntsu; u++, bp++) {
float3 vec;
- mul_v3_m4v3(vec, ob->obmat, bp->vec);
+ mul_v3_m4v3(vec, ob->object_to_world, bp->vec);
minmax_v3v3_v3(r_min, r_max, vec);
}
}
@@ -3866,7 +3912,8 @@ void BKE_object_minmax(Object *ob, float r_min[3], float r_max[3], const bool us
case OB_MBALL: {
float ob_min[3], ob_max[3];
- changed = BKE_mball_minmax_ex((const MetaBall *)ob->data, ob_min, ob_max, ob->obmat, 0);
+ changed = BKE_mball_minmax_ex(
+ (const MetaBall *)ob->data, ob_min, ob_max, ob->object_to_world, 0);
if (changed) {
minmax_v3v3_v3(r_min, r_max, ob_min);
minmax_v3v3_v3(r_min, r_max, ob_max);
@@ -3875,20 +3922,20 @@ void BKE_object_minmax(Object *ob, float r_min[3], float r_max[3], const bool us
}
case OB_CURVES: {
const BoundBox bb = *BKE_curves_boundbox_get(ob);
- BKE_boundbox_minmax(&bb, ob->obmat, r_min, r_max);
+ BKE_boundbox_minmax(&bb, ob->object_to_world, r_min, r_max);
changed = true;
break;
}
case OB_POINTCLOUD: {
const BoundBox bb = *BKE_pointcloud_boundbox_get(ob);
- BKE_boundbox_minmax(&bb, ob->obmat, r_min, r_max);
+ BKE_boundbox_minmax(&bb, ob->object_to_world, r_min, r_max);
changed = true;
break;
}
case OB_VOLUME: {
const BoundBox bb = *BKE_volume_boundbox_get(ob);
- BKE_boundbox_minmax(&bb, ob->obmat, r_min, r_max);
+ BKE_boundbox_minmax(&bb, ob->object_to_world, r_min, r_max);
changed = true;
break;
}
@@ -3902,14 +3949,14 @@ void BKE_object_minmax(Object *ob, float r_min[3], float r_max[3], const bool us
size *= ob->empty_drawsize;
}
- minmax_v3v3_v3(r_min, r_max, ob->obmat[3]);
+ minmax_v3v3_v3(r_min, r_max, ob->object_to_world[3]);
float3 vec;
- copy_v3_v3(vec, ob->obmat[3]);
+ copy_v3_v3(vec, ob->object_to_world[3]);
add_v3_v3(vec, size);
minmax_v3v3_v3(r_min, r_max, vec);
- copy_v3_v3(vec, ob->obmat[3]);
+ copy_v3_v3(vec, ob->object_to_world[3]);
sub_v3_v3(vec, size);
minmax_v3v3_v3(r_min, r_max, vec);
}
@@ -3956,12 +4003,12 @@ bool BKE_object_empty_image_data_is_visible_in_view3d(const Object *ob, const Re
* however the issue with empty objects being visible when viewed from the side
* is only noticeable in orthographic views. */
float3 view_dir;
- sub_v3_v3v3(view_dir, rv3d->viewinv[3], ob->obmat[3]);
- dot = dot_v3v3(ob->obmat[2], view_dir);
+ sub_v3_v3v3(view_dir, rv3d->viewinv[3], ob->object_to_world[3]);
+ dot = dot_v3v3(ob->object_to_world[2], view_dir);
eps = 0.0f;
}
else {
- dot = dot_v3v3(ob->obmat[2], rv3d->viewinv[2]);
+ dot = dot_v3v3(ob->object_to_world[2], rv3d->viewinv[2]);
eps = 1e-5f;
}
if (visibility_flag & OB_EMPTY_IMAGE_HIDE_BACK) {
@@ -3978,7 +4025,7 @@ bool BKE_object_empty_image_data_is_visible_in_view3d(const Object *ob, const Re
if (visibility_flag & OB_EMPTY_IMAGE_HIDE_NON_AXIS_ALIGNED) {
float3 proj, ob_z_axis;
- normalize_v3_v3(ob_z_axis, ob->obmat[2]);
+ normalize_v3_v3(ob_z_axis, ob->object_to_world[2]);
project_plane_v3_v3v3(proj, ob_z_axis, rv3d->viewinv[2]);
const float proj_length_sq = len_squared_v3(proj);
if (proj_length_sq > 1e-5f) {
@@ -4072,7 +4119,7 @@ bool BKE_object_minmax_dupli(Depsgraph *depsgraph,
}
else {
Object temp_ob = blender::dna::shallow_copy(*dob->ob);
- /* Do not modify the original boundbox. */
+ /* Do not modify the original bounding-box. */
temp_ob.runtime.bb = nullptr;
BKE_object_replace_data_on_shallow_copy(&temp_ob, dob->ob_data);
const BoundBox *bb = BKE_object_boundbox_get(&temp_ob);
@@ -4103,8 +4150,8 @@ struct GPencilStrokePointIterData {
void *user_data;
};
-static void foreach_display_point_gpencil_stroke_fn(bGPDlayer *UNUSED(layer),
- bGPDframe *UNUSED(frame),
+static void foreach_display_point_gpencil_stroke_fn(bGPDlayer * /*layer*/,
+ bGPDframe * /*frame*/,
bGPDstroke *stroke,
void *thunk)
{
@@ -4125,7 +4172,7 @@ void BKE_object_foreach_display_point(Object *ob,
void (*func_cb)(const float[3], void *),
void *user_data)
{
- /* TODO: pointcloud and curves object support */
+ /* TODO: point-cloud and curves object support. */
const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
float3 co;
@@ -4164,12 +4211,13 @@ void BKE_scene_foreach_display_point(Depsgraph *depsgraph,
void (*func_cb)(const float[3], void *),
void *user_data)
{
- DEG_OBJECT_ITER_BEGIN (depsgraph,
- ob,
- DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE |
- DEG_ITER_OBJECT_FLAG_DUPLI) {
+ DEGObjectIterSettings deg_iter_settings{};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
if ((ob->base_flag & BASE_SELECTED) != 0) {
- BKE_object_foreach_display_point(ob, ob->obmat, func_cb, user_data);
+ BKE_object_foreach_display_point(ob, ob->object_to_world, func_cb, user_data);
}
}
DEG_OBJECT_ITER_END;
@@ -4212,10 +4260,10 @@ void *BKE_object_tfm_backup(Object *ob)
copy_v3_v3(obtfm->drotAxis, ob->drotAxis);
obtfm->rotAngle = ob->rotAngle;
obtfm->drotAngle = ob->drotAngle;
- copy_m4_m4(obtfm->obmat, ob->obmat);
+ copy_m4_m4(obtfm->obmat, ob->object_to_world);
copy_m4_m4(obtfm->parentinv, ob->parentinv);
copy_m4_m4(obtfm->constinv, ob->constinv);
- copy_m4_m4(obtfm->imat, ob->imat);
+ copy_m4_m4(obtfm->imat, ob->world_to_object);
return (void *)obtfm;
}
@@ -4235,10 +4283,10 @@ void BKE_object_tfm_restore(Object *ob, void *obtfm_pt)
copy_v3_v3(ob->drotAxis, obtfm->drotAxis);
ob->rotAngle = obtfm->rotAngle;
ob->drotAngle = obtfm->drotAngle;
- copy_m4_m4(ob->obmat, obtfm->obmat);
+ copy_m4_m4(ob->object_to_world, obtfm->obmat);
copy_m4_m4(ob->parentinv, obtfm->parentinv);
copy_m4_m4(ob->constinv, obtfm->constinv);
- copy_m4_m4(ob->imat, obtfm->imat);
+ copy_m4_m4(ob->world_to_object, obtfm->imat);
}
/** \} */
@@ -4274,7 +4322,7 @@ void BKE_object_handle_update_ex(Depsgraph *depsgraph,
* is evaluated on the rebuilt pose, otherwise we get incorrect poses
* on file load */
if (ob->pose == nullptr || (ob->pose->flag & POSE_RECALC)) {
- /* No need to pass bmain here, we assume we do not need to rebuild DEG from here... */
+ /* No need to pass `bmain` here, we assume we do not need to rebuild DEG from here. */
BKE_pose_rebuild(nullptr, ob, (bArmature *)ob->data, true);
}
}
@@ -5074,7 +5122,7 @@ void BKE_object_runtime_reset(Object *object)
memset(&object->runtime, 0, sizeof(object->runtime));
}
-void BKE_object_runtime_reset_on_copy(Object *object, const int UNUSED(flag))
+void BKE_object_runtime_reset_on_copy(Object *object, const int /*flag*/)
{
Object_Runtime *runtime = &object->runtime;
runtime->data_eval = nullptr;
@@ -5136,19 +5184,21 @@ static void obrel_list_add(LinkNode **links, Object *ob)
ob->id.tag |= LIB_TAG_DOIT;
}
-LinkNode *BKE_object_relational_superset(struct ViewLayer *view_layer,
+LinkNode *BKE_object_relational_superset(const Scene *scene,
+ struct ViewLayer *view_layer,
eObjectSet objectSet,
eObRelationTypes includeFilter)
{
LinkNode *links = nullptr;
/* Remove markers from all objects */
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
base->object->id.tag &= ~LIB_TAG_DOIT;
}
/* iterate over all selected and visible objects */
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (objectSet == OB_SET_ALL) {
/* as we get all anyways just add it */
Object *ob = base->object;
@@ -5184,7 +5234,7 @@ LinkNode *BKE_object_relational_superset(struct ViewLayer *view_layer,
/* child relationship */
if (includeFilter & (OB_REL_CHILDREN | OB_REL_CHILDREN_RECURSIVE)) {
- LISTBASE_FOREACH (Base *, local_base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, local_base, BKE_view_layer_object_bases_get(view_layer)) {
if (BASE_EDITABLE(((View3D *)nullptr), local_base)) {
Object *child = local_base->object;
@@ -5242,12 +5292,12 @@ void BKE_object_groups_clear(Main *bmain, Scene *scene, Object *ob)
KDTree_3d *BKE_object_as_kdtree(Object *ob, int *r_tot)
{
KDTree_3d *tree = nullptr;
- unsigned int tot = 0;
+ uint tot = 0;
switch (ob->type) {
case OB_MESH: {
Mesh *me = (Mesh *)ob->data;
- unsigned int i;
+ uint i;
Mesh *me_eval = ob->runtime.mesh_deform_eval ? ob->runtime.mesh_deform_eval :
BKE_object_get_evaluated_mesh(ob);
@@ -5264,7 +5314,7 @@ KDTree_3d *BKE_object_as_kdtree(Object *ob, int *r_tot)
for (i = 0; i < verts.size(); i++) {
if (index[i] != ORIGINDEX_NONE) {
float co[3];
- mul_v3_m4v3(co, ob->obmat, verts[i].co);
+ mul_v3_m4v3(co, ob->object_to_world, verts[i].co);
BLI_kdtree_3d_insert(tree, index[i], co);
tot++;
}
@@ -5278,7 +5328,7 @@ KDTree_3d *BKE_object_as_kdtree(Object *ob, int *r_tot)
for (i = 0; i < tot; i++) {
float co[3];
- mul_v3_m4v3(co, ob->obmat, verts[i].co);
+ mul_v3_m4v3(co, ob->object_to_world, verts[i].co);
BLI_kdtree_3d_insert(tree, i, co);
}
}
@@ -5290,7 +5340,7 @@ KDTree_3d *BKE_object_as_kdtree(Object *ob, int *r_tot)
case OB_SURF: {
/* TODO: take deformation into account */
Curve *cu = (Curve *)ob->data;
- unsigned int i, a;
+ uint i, a;
Nurb *nu;
@@ -5307,7 +5357,7 @@ KDTree_3d *BKE_object_as_kdtree(Object *ob, int *r_tot)
a = nu->pntsu;
while (a--) {
float co[3];
- mul_v3_m4v3(co, ob->obmat, bezt->vec[1]);
+ mul_v3_m4v3(co, ob->object_to_world, bezt->vec[1]);
BLI_kdtree_3d_insert(tree, i++, co);
bezt++;
}
@@ -5319,7 +5369,7 @@ KDTree_3d *BKE_object_as_kdtree(Object *ob, int *r_tot)
a = nu->pntsu * nu->pntsv;
while (a--) {
float co[3];
- mul_v3_m4v3(co, ob->obmat, bp->vec);
+ mul_v3_m4v3(co, ob->object_to_world, bp->vec);
BLI_kdtree_3d_insert(tree, i++, co);
bp++;
}
@@ -5334,7 +5384,7 @@ KDTree_3d *BKE_object_as_kdtree(Object *ob, int *r_tot)
/* TODO: take deformation into account */
Lattice *lt = (Lattice *)ob->data;
BPoint *bp;
- unsigned int i;
+ uint i;
tot = lt->pntsu * lt->pntsv * lt->pntsw;
tree = BLI_kdtree_3d_new(tot);
@@ -5342,7 +5392,7 @@ KDTree_3d *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);
+ mul_v3_m4v3(co, ob->object_to_world, bp->vec);
BLI_kdtree_3d_insert(tree, i++, co);
}
@@ -5423,9 +5473,8 @@ bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph,
depsgraph, scene, ob->track, false, recursion, frame, type);
}
- /* skip subframe if object is parented
- * to vertex of a dynamic paint canvas */
- if (no_update && (ELEM(ob->partype, PARVERT1, PARVERT3))) {
+ /* Skip sub-frame if object is parented to vertex of a dynamic paint canvas. */
+ if (no_update && ELEM(ob->partype, PARVERT1, PARVERT3)) {
return false;
}
@@ -5455,8 +5504,7 @@ bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph,
if (update_mesh) {
BKE_animsys_evaluate_animdata(
&ob->id, ob->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
- /* ignore cache clear during subframe updates
- * to not mess up cache validity */
+ /* Ignore cache clear during sub-frame updates to not mess up cache validity. */
object_cacheIgnoreClear(ob, 1);
BKE_object_handle_update(depsgraph, scene, ob);
object_cacheIgnoreClear(ob, 0);
diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c
index 1fe5d7aa0e7..c1fe10dca6b 100644
--- a/source/blender/blenkernel/intern/object_deform.c
+++ b/source/blender/blenkernel/intern/object_deform.c
@@ -163,14 +163,14 @@ bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_sele
}
else {
if (BKE_mesh_deform_verts(me)) {
- const MVert *mv;
+ const bool *select_vert = (const bool *)CustomData_get_layer_named(
+ &me->vdata, CD_PROP_BOOL, ".select_vert");
int i;
- mv = BKE_mesh_verts(me);
dv = BKE_mesh_deform_verts_for_write(me);
- for (i = 0; i < me->totvert; i++, mv++, dv++) {
- if (dv->dw && (!use_selection || (mv->flag & SELECT))) {
+ for (i = 0; i < me->totvert; i++, dv++) {
+ if (dv->dw && (!use_selection || (select_vert && select_vert[i]))) {
MDeformWeight *dw = BKE_defvert_find_index(dv, def_nr);
BKE_defvert_remove_group(dv, dw); /* dw can be NULL */
changed = true;
@@ -613,7 +613,7 @@ bool *BKE_object_defgroup_selected_get(Object *ob, int defbase_tot, int *r_dg_fl
{
bool *dg_selection = MEM_mallocN(defbase_tot * sizeof(bool), __func__);
bDeformGroup *defgroup;
- unsigned int i;
+ uint i;
Object *armob = BKE_object_pose_armature_get(ob);
(*r_dg_flags_sel_tot) = 0;
@@ -700,7 +700,7 @@ void BKE_object_defgroup_mirror_selection(struct Object *ob,
const ListBase *defbase = BKE_object_defgroup_list(ob);
bDeformGroup *defgroup;
- unsigned int i;
+ uint i;
int i_mirr;
for (i = 0, defgroup = defbase->first; i < defbase_tot && defgroup;
diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc
index 6db1c864918..5efd44c620b 100644
--- a/source/blender/blenkernel/intern/object_dupli.cc
+++ b/source/blender/blenkernel/intern/object_dupli.cc
@@ -24,8 +24,10 @@
#include "DNA_anim_types.h"
#include "DNA_collection_types.h"
+#include "DNA_curves_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_pointcloud_types.h"
#include "DNA_scene_types.h"
#include "DNA_vfont_types.h"
@@ -39,27 +41,39 @@
#include "BKE_geometry_set.hh"
#include "BKE_global.h"
#include "BKE_idprop.h"
+#include "BKE_instances.hh"
#include "BKE_lattice.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_mesh_iterators.h"
#include "BKE_mesh_runtime.h"
+#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_scene.h"
+#include "BKE_type_conversions.hh"
#include "BKE_vfont.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
#include "BLI_hash.h"
-#include "BLI_strict_flags.h"
+#include "DNA_world_types.h"
+
+#include "NOD_geometry_nodes_log.hh"
+#include "RNA_access.h"
+#include "RNA_path.h"
+#include "RNA_prototypes.h"
+#include "RNA_types.h"
using blender::Array;
using blender::float3;
using blender::float4x4;
using blender::Span;
using blender::Vector;
+using blender::bke::InstanceReference;
+using blender::bke::Instances;
+namespace geo_log = blender::nodes::geo_eval_log;
/* -------------------------------------------------------------------- */
/** \name Internal Duplicate Context
@@ -75,6 +89,15 @@ struct DupliContext {
Scene *scene;
Object *object;
float space_mat[4][4];
+ /**
+ * Index of the top-level instance that contains this context or -1 when unused.
+ * This is an index into the instances component of #preview_base_geometry.
+ */
+ int preview_instance_index;
+ /**
+ * Top level geometry set that is previewed.
+ */
+ const GeometrySet *preview_base_geometry;
/**
* A stack that contains all the "parent" objects of a particular instance when recursive
@@ -84,6 +107,8 @@ struct DupliContext {
Vector<Object *> *instance_stack;
int persistent_id[MAX_DUPLI_RECUR];
+ int64_t instance_idx[MAX_DUPLI_RECUR];
+ const GeometrySet *instance_data[MAX_DUPLI_RECUR];
int level;
const struct DupliGenerator *gen;
@@ -127,19 +152,26 @@ static void init_context(DupliContext *r_ctx,
r_ctx->gen = get_dupli_generator(r_ctx);
r_ctx->duplilist = nullptr;
+ r_ctx->preview_instance_index = -1;
+ r_ctx->preview_base_geometry = nullptr;
}
/**
* Create sub-context for recursive duplis.
*/
-static bool copy_dupli_context(
- DupliContext *r_ctx, const DupliContext *ctx, Object *ob, const float mat[4][4], int index)
+static bool copy_dupli_context(DupliContext *r_ctx,
+ const DupliContext *ctx,
+ Object *ob,
+ const float mat[4][4],
+ int index,
+ const GeometrySet *geometry = nullptr,
+ int64_t instance_index = 0)
{
*r_ctx = *ctx;
/* XXX annoying, previously was done by passing an ID* argument,
* this at least is more explicit. */
- if (ctx->gen->type == OB_DUPLICOLLECTION) {
+ if (ctx->gen && ctx->gen->type == OB_DUPLICOLLECTION) {
r_ctx->collection = ctx->object->instance_collection;
}
@@ -149,6 +181,8 @@ static bool copy_dupli_context(
mul_m4_m4m4(r_ctx->space_mat, (float(*)[4])ctx->space_mat, mat);
}
r_ctx->persistent_id[r_ctx->level] = index;
+ r_ctx->instance_idx[r_ctx->level] = instance_index;
+ r_ctx->instance_data[r_ctx->level] = geometry;
++r_ctx->level;
if (r_ctx->level == MAX_DUPLI_RECUR - 1) {
@@ -163,10 +197,16 @@ static bool copy_dupli_context(
/**
* Generate a dupli instance.
*
- * \param mat: is transform of the object relative to current context (including #Object.obmat).
+ * \param mat: is transform of the object relative to current context (including
+ * #Object.object_to_world).
*/
-static DupliObject *make_dupli(
- const DupliContext *ctx, Object *ob, const ID *object_data, const float mat[4][4], int index)
+static DupliObject *make_dupli(const DupliContext *ctx,
+ Object *ob,
+ const ID *object_data,
+ const float mat[4][4],
+ int index,
+ const GeometrySet *geometry = nullptr,
+ int64_t instance_index = 0)
{
DupliObject *dob;
int i;
@@ -183,7 +223,9 @@ static DupliObject *make_dupli(
dob->ob = ob;
dob->ob_data = const_cast<ID *>(object_data);
mul_m4_m4m4(dob->mat, (float(*)[4])ctx->space_mat, mat);
- dob->type = ctx->gen->type;
+ dob->type = ctx->gen == nullptr ? 0 : ctx->gen->type;
+ dob->preview_base_geometry = ctx->preview_base_geometry;
+ dob->preview_instance_index = ctx->preview_instance_index;
/* Set persistent id, which is an array with a persistent index for each level
* (particle number, vertex number, ..). by comparing this we can find the same
@@ -198,6 +240,23 @@ static DupliObject *make_dupli(
dob->persistent_id[i] = INT_MAX;
}
+ /* Store geometry set data for attribute lookup in innermost to outermost
+ * order, copying only non-null entries to save space. */
+ const int max_instance = sizeof(dob->instance_data) / sizeof(void *);
+ int next_instance = 0;
+ if (geometry != nullptr) {
+ dob->instance_idx[next_instance] = int(instance_index);
+ dob->instance_data[next_instance] = geometry;
+ next_instance++;
+ }
+ for (i = ctx->level - 1; i >= 0 && next_instance < max_instance; i--) {
+ if (ctx->instance_data[i] != nullptr) {
+ dob->instance_idx[next_instance] = int(ctx->instance_idx[i]);
+ dob->instance_data[next_instance] = ctx->instance_data[i];
+ next_instance++;
+ }
+ }
+
/* Meta-balls never draw in duplis, they are instead merged into one by the basis
* meta-ball outside of the group. this does mean that if that meta-ball is not in the
* scene, they will not show up at all, limitation that should be solved once. */
@@ -211,7 +270,7 @@ static DupliObject *make_dupli(
if (dob->persistent_id[0] != INT_MAX) {
for (i = 0; i < MAX_DUPLI_RECUR; i++) {
- dob->random_id = BLI_hash_int_2d(dob->random_id, (unsigned int)dob->persistent_id[i]);
+ dob->random_id = BLI_hash_int_2d(dob->random_id, uint(dob->persistent_id[i]));
}
}
else {
@@ -228,20 +287,24 @@ static DupliObject *make_dupli(
static DupliObject *make_dupli(const DupliContext *ctx,
Object *ob,
const float mat[4][4],
- int index)
+ int index,
+ const GeometrySet *geometry = nullptr,
+ int64_t instance_index = 0)
{
- return make_dupli(ctx, ob, static_cast<ID *>(ob->data), mat, index);
+ return make_dupli(ctx, ob, static_cast<ID *>(ob->data), mat, index, geometry, instance_index);
}
/**
* Recursive dupli-objects.
*
- * \param space_mat: is the local dupli-space (excluding dupli #Object.obmat).
+ * \param space_mat: is the local dupli-space (excluding dupli #Object.object_to_world).
*/
static void make_recursive_duplis(const DupliContext *ctx,
Object *ob,
const float space_mat[4][4],
- int index)
+ int index,
+ const GeometrySet *geometry = nullptr,
+ int64_t instance_index = 0)
{
if (ctx->instance_stack->contains(ob)) {
/* Avoid recursive instances. */
@@ -251,7 +314,7 @@ static void make_recursive_duplis(const DupliContext *ctx,
/* Simple preventing of too deep nested collections with #MAX_DUPLI_RECUR. */
if (ctx->level < MAX_DUPLI_RECUR) {
DupliContext rctx;
- if (!copy_dupli_context(&rctx, ctx, ob, space_mat, index)) {
+ if (!copy_dupli_context(&rctx, ctx, ob, space_mat, index, geometry, instance_index)) {
return;
}
if (rctx.gen) {
@@ -311,12 +374,13 @@ static void make_child_duplis(const DupliContext *ctx,
/* FIXME: using a mere counter to generate a 'persistent' dupli id is very weak. One possible
* better solution could be to use `session_uuid` of ID's instead? */
int persistent_dupli_id = 0;
+ DEGObjectIterSettings deg_iter_settings{};
+ deg_iter_settings.depsgraph = ctx->depsgraph;
/* NOTE: this set of flags ensure we only iterate over objects that have a base in either the
* current scene, or the set (background) scene. */
- int deg_objects_visibility_flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
- DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET;
-
- DEG_OBJECT_ITER_BEGIN (ctx->depsgraph, ob, deg_objects_visibility_flags) {
+ deg_iter_settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
if ((ob != ctx->obedit) && is_child(ob, parent)) {
DupliContext pctx;
if (copy_dupli_context(&pctx, ctx, ctx->object, nullptr, persistent_dupli_id)) {
@@ -363,8 +427,8 @@ static const Mesh *mesh_data_from_duplicator_object(Object *ob,
/* Note that this will only show deformation if #eModifierMode_OnCage is enabled.
* We could change this but it matches 2.7x behavior. */
me_eval = BKE_object_get_editmesh_eval_cage(ob);
- if ((me_eval == nullptr) || (me_eval->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH)) {
- EditMeshData *emd = me_eval ? me_eval->runtime.edit_data : nullptr;
+ if ((me_eval == nullptr) || (me_eval->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH)) {
+ EditMeshData *emd = me_eval ? me_eval->runtime->edit_data : nullptr;
/* Only assign edit-mesh in the case we can't use `me_eval`. */
*r_em = em;
@@ -405,8 +469,8 @@ static void make_duplis_collection(const DupliContext *ctx)
/* Combine collection offset and `obmat`. */
unit_m4(collection_mat);
sub_v3_v3(collection_mat[3], collection->instance_offset);
- mul_m4_m4m4(collection_mat, ob->obmat, collection_mat);
- /* Don't access 'ob->obmat' from now on. */
+ mul_m4_m4m4(collection_mat, ob->object_to_world, collection_mat);
+ /* Don't access 'ob->object_to_world' from now on. */
eEvaluationMode mode = DEG_get_mode(ctx->depsgraph);
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (collection, cob, mode) {
@@ -414,7 +478,7 @@ static void make_duplis_collection(const DupliContext *ctx)
float mat[4][4];
/* Collection dupli-offset, should apply after everything else. */
- mul_m4_m4m4(mat, collection_mat, cob->obmat);
+ mul_m4_m4m4(mat, collection_mat, cob->object_to_world);
make_dupli(ctx, cob, mat, _base_id);
@@ -521,11 +585,11 @@ static DupliObject *vertex_dupli(const DupliContext *ctx,
/* Make offset relative to inst_ob using relative child transform. */
mul_mat3_m4_v3(child_imat, obmat[3]);
/* Apply `obmat` _after_ the local vertex transform. */
- mul_m4_m4m4(obmat, inst_ob->obmat, obmat);
+ mul_m4_m4m4(obmat, inst_ob->object_to_world, obmat);
/* Space matrix is constructed by removing `obmat` transform,
* this yields the world-space transform for recursive duplis. */
- mul_m4_m4m4(space_mat, obmat, inst_ob->imat);
+ mul_m4_m4m4(space_mat, obmat, inst_ob->world_to_object);
DupliObject *dob = make_dupli(ctx, inst_ob, obmat, index);
@@ -545,10 +609,10 @@ static void make_child_duplis_verts_from_mesh(const DupliContext *ctx,
const MVert *mvert = vdd->mvert;
const int totvert = vdd->totvert;
- invert_m4_m4(inst_ob->imat, inst_ob->obmat);
+ invert_m4_m4(inst_ob->world_to_object, inst_ob->object_to_world);
/* Relative transform from parent to child space. */
float child_imat[4][4];
- mul_m4_m4m4(child_imat, inst_ob->imat, ctx->object->obmat);
+ mul_m4_m4m4(child_imat, inst_ob->world_to_object, ctx->object->object_to_world);
for (int i = 0; i < totvert; i++) {
DupliObject *dob = vertex_dupli(
@@ -567,10 +631,10 @@ static void make_child_duplis_verts_from_editmesh(const DupliContext *ctx,
BMEditMesh *em = vdd->em;
const bool use_rotation = vdd->params.use_rotation;
- invert_m4_m4(inst_ob->imat, inst_ob->obmat);
+ invert_m4_m4(inst_ob->world_to_object, inst_ob->object_to_world);
/* Relative transform from parent to child space. */
float child_imat[4][4];
- mul_m4_m4m4(child_imat, inst_ob->imat, ctx->object->obmat);
+ mul_m4_m4m4(child_imat, inst_ob->world_to_object, ctx->object->object_to_world);
BMVert *v;
BMIter iter;
@@ -648,7 +712,7 @@ static const DupliGenerator gen_dupli_verts = {
* \{ */
static Object *find_family_object(
- Main *bmain, const char *family, size_t family_len, unsigned int ch, GHash *family_gh)
+ Main *bmain, const char *family, size_t family_len, uint ch, GHash *family_gh)
{
void *ch_key = POINTER_FROM_UINT(ch);
@@ -695,7 +759,7 @@ static void make_duplis_font(const DupliContext *ctx)
return;
}
- copy_m4_m4(pmat, par->obmat);
+ copy_m4_m4(pmat, par->object_to_world);
/* In `par` the family name is stored, use this to find the other objects. */
@@ -726,7 +790,7 @@ static void make_duplis_font(const DupliContext *ctx)
/* XXX That G.main is *really* ugly, but not sure what to do here.
* Definitively don't think it would be safe to put back `Main *bmain` pointer
* in #DupliContext as done in 2.7x? */
- ob = find_family_object(G.main, cu->family, family_len, (unsigned int)text[a], family_gh);
+ ob = find_family_object(G.main, cu->family, family_len, uint(text[a]), family_gh);
if (is_eval_curve) {
/* Workaround for the above hack. */
@@ -740,7 +804,7 @@ static void make_duplis_font(const DupliContext *ctx)
mul_m4_v3(pmat, vec);
- copy_m4_m4(obmat, par->obmat);
+ copy_m4_m4(obmat, par->object_to_world);
if (UNLIKELY(ct->rot != 0.0f)) {
float rmat[4][4];
@@ -779,7 +843,8 @@ static const DupliGenerator gen_dupli_verts_font = {
static void make_duplis_geometry_set_impl(const DupliContext *ctx,
const GeometrySet &geometry_set,
const float parent_transform[4][4],
- bool geometry_set_is_instance)
+ bool geometry_set_is_instance,
+ bool use_new_curves_type)
{
int component_index = 0;
if (ctx->object->type != OB_MESH || geometry_set_is_instance) {
@@ -794,8 +859,15 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx,
}
if (!ELEM(ctx->object->type, OB_CURVES_LEGACY, OB_FONT, OB_CURVES) || geometry_set_is_instance) {
if (const CurveComponent *component = geometry_set.get_component_for_read<CurveComponent>()) {
- if (const Curve *curve = component->get_curve_for_render()) {
- make_dupli(ctx, ctx->object, &curve->id, parent_transform, component_index++);
+ if (use_new_curves_type) {
+ if (const Curves *curves = component->get_for_read()) {
+ make_dupli(ctx, ctx->object, &curves->id, parent_transform, component_index++);
+ }
+ }
+ else {
+ if (const Curve *curve = component->get_curve_for_render()) {
+ make_dupli(ctx, ctx->object, &curve->id, parent_transform, component_index++);
+ }
}
}
}
@@ -806,8 +878,8 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx,
}
const bool creates_duplis_for_components = component_index >= 1;
- const InstancesComponent *component = geometry_set.get_component_for_read<InstancesComponent>();
- if (component == nullptr) {
+ const Instances *instances = geometry_set.get_instances_for_read();
+ if (instances == nullptr) {
return;
}
@@ -822,26 +894,35 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx,
instances_ctx = &new_instances_ctx;
}
- Span<float4x4> instance_offset_matrices = component->instance_transforms();
- Span<int> instance_reference_handles = component->instance_reference_handles();
- Span<int> almost_unique_ids = component->almost_unique_ids();
- Span<InstanceReference> references = component->references();
+ Span<float4x4> instance_offset_matrices = instances->transforms();
+ Span<int> reference_handles = instances->reference_handles();
+ Span<int> almost_unique_ids = instances->almost_unique_ids();
+ Span<InstanceReference> references = instances->references();
for (int64_t i : instance_offset_matrices.index_range()) {
- const InstanceReference &reference = references[instance_reference_handles[i]];
+ const InstanceReference &reference = references[reference_handles[i]];
const int id = almost_unique_ids[i];
+ const DupliContext *ctx_for_instance = instances_ctx;
+ /* Set the #preview_instance_index when necessary. */
+ DupliContext tmp_ctx_for_instance;
+ if (instances_ctx->preview_base_geometry == &geometry_set) {
+ tmp_ctx_for_instance = *instances_ctx;
+ tmp_ctx_for_instance.preview_instance_index = i;
+ ctx_for_instance = &tmp_ctx_for_instance;
+ }
+
switch (reference.type()) {
case InstanceReference::Type::Object: {
Object &object = reference.object();
float matrix[4][4];
mul_m4_m4m4(matrix, parent_transform, instance_offset_matrices[i].values);
- make_dupli(instances_ctx, &object, matrix, id);
+ make_dupli(ctx_for_instance, &object, matrix, id, &geometry_set, i);
float space_matrix[4][4];
- mul_m4_m4m4(space_matrix, instance_offset_matrices[i].values, object.imat);
+ mul_m4_m4m4(space_matrix, instance_offset_matrices[i].values, object.world_to_object);
mul_m4_m4_pre(space_matrix, parent_transform);
- make_recursive_duplis(instances_ctx, &object, space_matrix, id);
+ make_recursive_duplis(ctx_for_instance, &object, space_matrix, id, &geometry_set, i);
break;
}
case InstanceReference::Type::Collection: {
@@ -853,19 +934,25 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx,
mul_m4_m4_pre(collection_matrix, parent_transform);
DupliContext sub_ctx;
- if (!copy_dupli_context(&sub_ctx, instances_ctx, instances_ctx->object, nullptr, id)) {
+ if (!copy_dupli_context(&sub_ctx,
+ ctx_for_instance,
+ ctx_for_instance->object,
+ nullptr,
+ id,
+ &geometry_set,
+ i)) {
break;
}
- eEvaluationMode mode = DEG_get_mode(instances_ctx->depsgraph);
+ eEvaluationMode mode = DEG_get_mode(ctx_for_instance->depsgraph);
int object_id = 0;
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (&collection, object, mode) {
- if (object == instances_ctx->object) {
+ if (object == ctx_for_instance->object) {
continue;
}
float instance_matrix[4][4];
- mul_m4_m4m4(instance_matrix, collection_matrix, object->obmat);
+ mul_m4_m4m4(instance_matrix, collection_matrix, object->object_to_world);
make_dupli(&sub_ctx, object, instance_matrix, object_id++);
make_recursive_duplis(&sub_ctx, object, collection_matrix, object_id++);
@@ -878,8 +965,15 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx,
mul_m4_m4m4(new_transform, parent_transform, instance_offset_matrices[i].values);
DupliContext sub_ctx;
- if (copy_dupli_context(&sub_ctx, instances_ctx, instances_ctx->object, nullptr, id)) {
- make_duplis_geometry_set_impl(&sub_ctx, reference.geometry_set(), new_transform, true);
+ if (copy_dupli_context(&sub_ctx,
+ ctx_for_instance,
+ ctx_for_instance->object,
+ nullptr,
+ id,
+ &geometry_set,
+ i)) {
+ make_duplis_geometry_set_impl(
+ &sub_ctx, reference.geometry_set(), new_transform, true, false);
}
break;
}
@@ -893,7 +987,7 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx,
static void make_duplis_geometry_set(const DupliContext *ctx)
{
const GeometrySet *geometry_set = ctx->object->runtime.geometry_set_eval;
- make_duplis_geometry_set_impl(ctx, *geometry_set, ctx->object->obmat, false);
+ make_duplis_geometry_set_impl(ctx, *geometry_set, ctx->object->object_to_world, false, false);
}
static const DupliGenerator gen_dupli_geometry_set = {
@@ -952,7 +1046,7 @@ static void get_dupliface_transform_from_coords(Span<float3> coords,
for (const float3 &coord : coords) {
location += coord;
}
- location *= 1.0f / (float)coords.size();
+ location *= 1.0f / float(coords.size());
/* Rotation. */
float quat[4];
@@ -963,7 +1057,7 @@ static void get_dupliface_transform_from_coords(Span<float3> coords,
/* Scale. */
float scale;
if (use_scale) {
- const float area = area_poly_v3((const float(*)[3])coords.data(), (uint)coords.size());
+ const float area = area_poly_v3((const float(*)[3])coords.data(), uint(coords.size()));
scale = sqrtf(area) * scale_fac;
}
else {
@@ -999,11 +1093,11 @@ static DupliObject *face_dupli(const DupliContext *ctx,
}
/* Apply `obmat` _after_ the local face transform. */
- mul_m4_m4m4(obmat, inst_ob->obmat, obmat);
+ mul_m4_m4m4(obmat, inst_ob->object_to_world, obmat);
/* Space matrix is constructed by removing `obmat` transform,
* this yields the world-space transform for recursive duplis. */
- mul_m4_m4m4(space_mat, obmat, inst_ob->imat);
+ mul_m4_m4m4(space_mat, obmat, inst_ob->world_to_object);
DupliObject *dob = make_dupli(ctx, inst_ob, obmat, index);
@@ -1083,9 +1177,9 @@ static void make_child_duplis_faces_from_mesh(const DupliContext *ctx,
float child_imat[4][4];
- invert_m4_m4(inst_ob->imat, inst_ob->obmat);
+ invert_m4_m4(inst_ob->world_to_object, inst_ob->object_to_world);
/* Relative transform from parent to child space. */
- mul_m4_m4m4(child_imat, inst_ob->imat, ctx->object->obmat);
+ mul_m4_m4m4(child_imat, inst_ob->world_to_object, ctx->object->object_to_world);
const float scale_fac = ctx->object->instance_faces_scale;
for (a = 0, mp = mpoly; a < totface; a++, mp++) {
@@ -1093,7 +1187,7 @@ static void make_child_duplis_faces_from_mesh(const DupliContext *ctx,
DupliObject *dob = face_dupli_from_mesh(
fdd->params.ctx, inst_ob, child_imat, a, use_scale, scale_fac, mp, loopstart, mvert);
- const float w = 1.0f / (float)mp->totloop;
+ const float w = 1.0f / float(mp->totloop);
if (orco) {
for (int j = 0; j < mp->totloop; j++) {
madd_v3_v3fl(dob->orco, orco[loopstart[j].v], w);
@@ -1123,9 +1217,9 @@ static void make_child_duplis_faces_from_editmesh(const DupliContext *ctx,
BLI_assert((vert_coords == nullptr) || (em->bm->elem_index_dirty & BM_VERT) == 0);
- invert_m4_m4(inst_ob->imat, inst_ob->obmat);
+ invert_m4_m4(inst_ob->world_to_object, inst_ob->object_to_world);
/* Relative transform from parent to child space. */
- mul_m4_m4m4(child_imat, inst_ob->imat, ctx->object->obmat);
+ mul_m4_m4m4(child_imat, inst_ob->world_to_object, ctx->object->object_to_world);
const float scale_fac = ctx->object->instance_faces_scale;
BM_ITER_MESH_INDEX (f, &iter, em->bm, BM_FACES_OF_MESH, a) {
@@ -1133,7 +1227,7 @@ static void make_child_duplis_faces_from_editmesh(const DupliContext *ctx,
fdd->params.ctx, inst_ob, child_imat, a, use_scale, scale_fac, f, vert_coords);
if (fdd->has_orco) {
- const float w = 1.0f / (float)f->len;
+ const float w = 1.0f / float(f->len);
BMLoop *l_first, *l_iter;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
@@ -1254,8 +1348,9 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
sim.ob = par;
sim.psys = psys;
sim.psmd = psys_get_modifier(par, psys);
- /* Make sure emitter `imat` is in global coordinates instead of render view coordinates. */
- invert_m4_m4(par->imat, par->obmat);
+ /* Make sure emitter `world_to_object` is in global coordinates instead of render view
+ * coordinates. */
+ invert_m4_m4(par->world_to_object, par->object_to_world);
/* First check for loops (particle system object used as dupli-object). */
if (part->ren_as == PART_DRAW_OB) {
@@ -1293,9 +1388,9 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
totpart = psys->totcached;
}
- RNG *rng = BLI_rng_new_srandom(31415926u + (unsigned int)psys->seed);
+ RNG *rng = BLI_rng_new_srandom(31415926u + uint(psys->seed));
- psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
+ psys_sim_data_init(&sim);
/* Gather list of objects or single object. */
int totcollection = 0;
@@ -1325,7 +1420,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
}
- oblist = (Object **)MEM_callocN((size_t)totcollection * sizeof(Object *),
+ oblist = (Object **)MEM_callocN(size_t(totcollection) * sizeof(Object *),
"dupcollection object list");
if (use_collection_count) {
@@ -1442,7 +1537,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
b = 0;
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (
part->instance_collection, object, mode) {
- copy_m4_m4(tmat, oblist[b]->obmat);
+ copy_m4_m4(tmat, oblist[b]->object_to_world);
/* Apply collection instance offset. */
sub_v3_v3(tmat[3], part->instance_collection->instance_offset);
@@ -1465,7 +1560,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
}
else {
float obmat[4][4];
- copy_m4_m4(obmat, ob->obmat);
+ copy_m4_m4(obmat, ob->object_to_world);
float vec[3];
copy_v3_v3(vec, obmat[3]);
@@ -1517,17 +1612,13 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
}
BLI_rng_free(rng);
+ psys_sim_data_free(&sim);
}
/* Clean up. */
if (oblist) {
MEM_freeN(oblist);
}
-
- if (psys->lattice_deform_data) {
- BKE_lattice_deform_data_destroy(psys->lattice_deform_data);
- psys->lattice_deform_data = nullptr;
- }
}
static void make_duplis_particles(const DupliContext *ctx)
@@ -1631,6 +1722,40 @@ ListBase *object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob)
return duplilist;
}
+ListBase *object_duplilist_preview(Depsgraph *depsgraph,
+ Scene *sce,
+ Object *ob_eval,
+ const ViewerPath *viewer_path)
+{
+ ListBase *duplilist = MEM_cnew<ListBase>("duplilist");
+ DupliContext ctx;
+ Vector<Object *> instance_stack;
+ instance_stack.append(ob_eval);
+ init_context(&ctx, depsgraph, sce, ob_eval, nullptr, instance_stack);
+ ctx.duplilist = duplilist;
+
+ Object *ob_orig = DEG_get_original_object(ob_eval);
+
+ LISTBASE_FOREACH (ModifierData *, md_orig, &ob_orig->modifiers) {
+ if (md_orig->type != eModifierType_Nodes) {
+ continue;
+ }
+ NodesModifierData *nmd_orig = reinterpret_cast<NodesModifierData *>(md_orig);
+ if (nmd_orig->runtime_eval_log == nullptr) {
+ continue;
+ }
+ geo_log::GeoModifierLog *log = static_cast<geo_log::GeoModifierLog *>(
+ nmd_orig->runtime_eval_log);
+ if (const geo_log::ViewerNodeLog *viewer_log = log->find_viewer_node_log_for_path(
+ *viewer_path)) {
+ ctx.preview_base_geometry = &viewer_log->geometry;
+ make_duplis_geometry_set_impl(
+ &ctx, viewer_log->geometry, ob_eval->object_to_world, true, ob_eval->type == OB_CURVES);
+ }
+ }
+ return duplilist;
+}
+
void free_object_duplilist(ListBase *lb)
{
BLI_freelistN(lb);
@@ -1638,3 +1763,186 @@ void free_object_duplilist(ListBase *lb)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Uniform attribute lookup
+ * \{ */
+
+/** Lookup instance attributes assigned via geometry nodes. */
+static bool find_geonode_attribute_rgba(const DupliObject *dupli,
+ const char *name,
+ float r_value[4])
+{
+ using namespace blender;
+
+ /* Loop over layers from innermost to outermost. */
+ for (const int i : IndexRange(sizeof(dupli->instance_data) / sizeof(void *))) {
+ /* Skip non-geonode layers. */
+ if (dupli->instance_data[i] == nullptr) {
+ continue;
+ }
+
+ const InstancesComponent *component =
+ dupli->instance_data[i]->get_component_for_read<InstancesComponent>();
+
+ if (component == nullptr) {
+ continue;
+ }
+
+ /* Attempt to look up the attribute. */
+ std::optional<bke::AttributeAccessor> attributes = component->attributes();
+ const VArray data = attributes->lookup<ColorGeometry4f>(name);
+
+ /* If the attribute was found and converted to float RGBA successfully, output it. */
+ if (data) {
+ copy_v4_v4(r_value, data[dupli->instance_idx[i]]);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/** Lookup an arbitrary RNA property and convert it to RGBA if possible. */
+static bool find_rna_property_rgba(PointerRNA *id_ptr, const char *name, float r_data[4])
+{
+ if (id_ptr->data == nullptr) {
+ return false;
+ }
+
+ /* First, check custom properties. */
+ IDProperty *group = RNA_struct_idprops(id_ptr, false);
+ PropertyRNA *prop = nullptr;
+
+ if (group && group->type == IDP_GROUP) {
+ prop = (PropertyRNA *)IDP_GetPropertyFromGroup(group, name);
+ }
+
+ /* If not found, do full path lookup. */
+ PointerRNA ptr;
+
+ if (prop != nullptr) {
+ ptr = *id_ptr;
+ }
+ else if (!RNA_path_resolve(id_ptr, name, &ptr, &prop)) {
+ return false;
+ }
+
+ if (prop == nullptr) {
+ return false;
+ }
+
+ /* Convert the value to RGBA if possible. */
+ PropertyType type = RNA_property_type(prop);
+ int array_len = RNA_property_array_length(&ptr, prop);
+
+ if (array_len == 0) {
+ float value;
+
+ if (type == PROP_FLOAT) {
+ value = RNA_property_float_get(&ptr, prop);
+ }
+ else if (type == PROP_INT) {
+ value = float(RNA_property_int_get(&ptr, prop));
+ }
+ else if (type == PROP_BOOLEAN) {
+ value = RNA_property_boolean_get(&ptr, prop) ? 1.0f : 0.0f;
+ }
+ else {
+ return false;
+ }
+
+ copy_v4_fl4(r_data, value, value, value, 1);
+ return true;
+ }
+
+ if (type == PROP_FLOAT && array_len <= 4) {
+ copy_v4_fl4(r_data, 0, 0, 0, 1);
+ RNA_property_float_get_array(&ptr, prop, r_data);
+ return true;
+ }
+
+ if (type == PROP_INT && array_len <= 4) {
+ int tmp[4] = {0, 0, 0, 1};
+ RNA_property_int_get_array(&ptr, prop, tmp);
+ for (int i = 0; i < 4; i++) {
+ r_data[i] = float(tmp[i]);
+ }
+ return true;
+ }
+
+ return false;
+}
+
+static bool find_rna_property_rgba(ID *id, const char *name, float r_data[4])
+{
+ PointerRNA ptr;
+ RNA_id_pointer_create(id, &ptr);
+ return find_rna_property_rgba(&ptr, name, r_data);
+}
+
+bool BKE_object_dupli_find_rgba_attribute(
+ Object *ob, DupliObject *dupli, Object *dupli_parent, const char *name, float r_value[4])
+{
+ /* Check the dupli particle system. */
+ if (dupli && dupli->particle_system) {
+ ParticleSettings *settings = dupli->particle_system->part;
+
+ if (find_rna_property_rgba(&settings->id, name, r_value)) {
+ return true;
+ }
+ }
+
+ /* Check geometry node dupli instance attributes. */
+ if (dupli && find_geonode_attribute_rgba(dupli, name, r_value)) {
+ return true;
+ }
+
+ /* Check the dupli parent object. */
+ if (dupli_parent && find_rna_property_rgba(&dupli_parent->id, name, r_value)) {
+ return true;
+ }
+
+ /* Check the main object. */
+ if (ob) {
+ if (find_rna_property_rgba(&ob->id, name, r_value)) {
+ return true;
+ }
+
+ /* Check the main object data (e.g. mesh). */
+ if (ob->data && find_rna_property_rgba((ID *)ob->data, name, r_value)) {
+ return true;
+ }
+ }
+
+ copy_v4_fl(r_value, 0.0f);
+ return false;
+}
+
+bool BKE_view_layer_find_rgba_attribute(struct Scene *scene,
+ struct ViewLayer *layer,
+ const char *name,
+ float r_value[4])
+{
+ if (layer) {
+ PointerRNA layer_ptr;
+ RNA_pointer_create(&scene->id, &RNA_ViewLayer, layer, &layer_ptr);
+
+ if (find_rna_property_rgba(&layer_ptr, name, r_value)) {
+ return true;
+ }
+ }
+
+ if (find_rna_property_rgba(&scene->id, name, r_value)) {
+ return true;
+ }
+
+ if (scene->world && find_rna_property_rgba(&scene->world->id, name, r_value)) {
+ return true;
+ }
+
+ copy_v4_fl(r_value, 0.0f);
+ return false;
+}
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.cc
index 91170060fee..106c9594718 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.cc
@@ -61,7 +61,7 @@ void BKE_object_eval_local_transform(Depsgraph *depsgraph, Object *ob)
DEG_debug_print_eval(depsgraph, __func__, ob->id.name, ob);
/* calculate local matrix */
- BKE_object_to_mat4(ob, ob->obmat);
+ BKE_object_to_mat4(ob, ob->object_to_world);
}
void BKE_object_eval_parent(Depsgraph *depsgraph, Object *ob)
@@ -78,18 +78,18 @@ void BKE_object_eval_parent(Depsgraph *depsgraph, Object *ob)
/* get local matrix (but don't calculate it, as that was done already!) */
/* XXX: redundant? */
- copy_m4_m4(locmat, ob->obmat);
+ copy_m4_m4(locmat, ob->object_to_world);
/* get parent effect matrix */
BKE_object_get_parent_matrix(ob, par, totmat);
/* total */
mul_m4_m4m4(tmat, totmat, ob->parentinv);
- mul_m4_m4m4(ob->obmat, tmat, locmat);
+ mul_m4_m4m4(ob->object_to_world, tmat, locmat);
/* origin, for help line */
if ((ob->partype & PARTYPE) == PARSKEL) {
- copy_v3_v3(ob->runtime.parent_display_origin, par->obmat[3]);
+ copy_v3_v3(ob->runtime.parent_display_origin, par->object_to_world[3]);
}
else {
copy_v3_v3(ob->runtime.parent_display_origin, totmat[3]);
@@ -111,7 +111,7 @@ void BKE_object_eval_constraints(Depsgraph *depsgraph, Scene *scene, Object *ob)
*
* Not sure why, this is from Joshua - sergey
*/
- cob = BKE_constraints_make_evalob(depsgraph, scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+ cob = BKE_constraints_make_evalob(depsgraph, scene, ob, nullptr, CONSTRAINT_OBTYPE_OBJECT);
BKE_constraints_solve(depsgraph, &ob->constraints, cob, ctime);
BKE_constraints_clear_evalob(cob);
}
@@ -121,9 +121,9 @@ void BKE_object_eval_transform_final(Depsgraph *depsgraph, Object *ob)
DEG_debug_print_eval(depsgraph, __func__, ob->id.name, ob);
/* Make sure inverse matrix is always up to date. This way users of it
* do not need to worry about recalculating it. */
- invert_m4_m4_safe(ob->imat, ob->obmat);
+ invert_m4_m4_safe(ob->world_to_object, ob->object_to_world);
/* Set negative scale flag in object. */
- if (is_negative_m4(ob->obmat)) {
+ if (is_negative_m4(ob->object_to_world)) {
ob->transflag |= OB_NEG_SCALE;
}
else {
@@ -141,9 +141,10 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
CustomData_MeshMasks cddata_masks = scene->customdata_mask;
CustomData_MeshMasks_update(&cddata_masks, &CD_MASK_BAREMESH);
/* Custom attributes should not be removed automatically. They might be used by the render
- * engine or scripts. They can still be removed explicitly using geometry nodes. */
- cddata_masks.vmask |= CD_MASK_PROP_ALL;
- cddata_masks.emask |= CD_MASK_PROP_ALL;
+ * engine or scripts. They can still be removed explicitly using geometry nodes.
+ * Crease can be be used in generic situations with geometry nodes as well. */
+ cddata_masks.vmask |= CD_MASK_PROP_ALL | CD_MASK_CREASE;
+ cddata_masks.emask |= CD_MASK_PROP_ALL | CD_MASK_CREASE;
cddata_masks.fmask |= CD_MASK_PROP_ALL;
cddata_masks.pmask |= CD_MASK_PROP_ALL;
cddata_masks.lmask |= CD_MASK_PROP_ALL;
@@ -204,7 +205,7 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
const bool use_render_params = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
ParticleSystem *tpsys, *psys;
ob->transflag &= ~OB_DUPLIPARTS;
- psys = ob->particlesystem.first;
+ psys = static_cast<ParticleSystem *>(ob->particlesystem.first);
while (psys) {
if (psys_check_enabled(ob, psys, use_render_params)) {
/* check use of dupli objects here */
@@ -239,9 +240,9 @@ static void object_sync_boundbox_to_original(Object *object_orig, Object *object
}
bb = BKE_object_boundbox_get(object_eval);
- if (bb != NULL) {
- if (object_orig->runtime.bb == NULL) {
- object_orig->runtime.bb = MEM_mallocN(sizeof(*object_orig->runtime.bb), __func__);
+ if (bb != nullptr) {
+ if (object_orig->runtime.bb == nullptr) {
+ object_orig->runtime.bb = MEM_new<BoundBox>(__func__);
}
*object_orig->runtime.bb = *bb;
}
@@ -256,19 +257,20 @@ void BKE_object_sync_to_original(Depsgraph *depsgraph, Object *object)
/* Base flags. */
object_orig->base_flag = object->base_flag;
/* Transformation flags. */
- copy_m4_m4(object_orig->obmat, object->obmat);
- copy_m4_m4(object_orig->imat, object->imat);
+ copy_m4_m4(object_orig->object_to_world, object->object_to_world);
+ copy_m4_m4(object_orig->world_to_object, object->world_to_object);
copy_m4_m4(object_orig->constinv, object->constinv);
object_orig->transflag = object->transflag;
object_orig->flag = object->flag;
/* Copy back error messages from modifiers. */
- for (ModifierData *md = object->modifiers.first, *md_orig = object_orig->modifiers.first;
- md != NULL && md_orig != NULL;
+ for (ModifierData *md = static_cast<ModifierData *>(object->modifiers.first),
+ *md_orig = static_cast<ModifierData *>(object_orig->modifiers.first);
+ md != nullptr && md_orig != nullptr;
md = md->next, md_orig = md_orig->next) {
BLI_assert(md->type == md_orig->type && STREQ(md->name, md_orig->name));
MEM_SAFE_FREE(md_orig->error);
- if (md->error != NULL) {
+ if (md->error != nullptr) {
md_orig->error = BLI_strdup(md->error);
}
}
@@ -276,7 +278,7 @@ void BKE_object_sync_to_original(Depsgraph *depsgraph, Object *object)
object_sync_boundbox_to_original(object_orig, object);
}
-void BKE_object_eval_uber_transform(Depsgraph *UNUSED(depsgraph), Object *UNUSED(object))
+void BKE_object_eval_uber_transform(Depsgraph * /*depsgraph*/, Object * /*object*/)
{
}
@@ -290,6 +292,8 @@ void BKE_object_batch_cache_dirty_tag(Object *ob)
BKE_lattice_batch_cache_dirty_tag((struct Lattice *)ob->data, BKE_LATTICE_BATCH_DIRTY_ALL);
break;
case OB_CURVES_LEGACY:
+ case OB_SURF:
+ case OB_FONT:
BKE_curve_batch_cache_dirty_tag((struct Curve *)ob->data, BKE_CURVE_BATCH_DIRTY_ALL);
break;
case OB_MBALL: {
@@ -337,7 +341,7 @@ void BKE_object_eval_transform_all(Depsgraph *depsgraph, Scene *scene, Object *o
{
/* This mimics full transform update chain from new depsgraph. */
BKE_object_eval_local_transform(depsgraph, object);
- if (object->parent != NULL) {
+ if (object->parent != nullptr) {
BKE_object_eval_parent(depsgraph, object);
}
if (!BLI_listbase_is_empty(&object->constraints)) {
@@ -371,13 +375,11 @@ void BKE_object_select_update(Depsgraph *depsgraph, Object *object)
DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
if (object->type == OB_MESH && !object->runtime.is_data_eval_owned) {
Mesh *mesh_input = (Mesh *)object->runtime.data_orig;
- Mesh_Runtime *mesh_runtime = &mesh_input->runtime;
- BLI_mutex_lock(mesh_runtime->eval_mutex);
- BKE_object_data_select_update(depsgraph, object->data);
- BLI_mutex_unlock(mesh_runtime->eval_mutex);
+ std::lock_guard lock{mesh_input->runtime->eval_mutex};
+ BKE_object_data_select_update(depsgraph, static_cast<ID *>(object->data));
}
else {
- BKE_object_data_select_update(depsgraph, object->data);
+ BKE_object_data_select_update(depsgraph, static_cast<ID *>(object->data));
}
}
@@ -390,9 +392,10 @@ void BKE_object_eval_eval_base_flags(Depsgraph *depsgraph,
{
/* TODO(sergey): Avoid list lookup. */
BLI_assert(view_layer_index >= 0);
- ViewLayer *view_layer = BLI_findlink(&scene->view_layers, view_layer_index);
- BLI_assert(view_layer != NULL);
- BLI_assert(view_layer->object_bases_array != NULL);
+ ViewLayer *view_layer = static_cast<ViewLayer *>(
+ BLI_findlink(&scene->view_layers, view_layer_index));
+ BLI_assert(view_layer != nullptr);
+ BLI_assert(view_layer->object_bases_array != nullptr);
BLI_assert(base_index >= 0);
BLI_assert(base_index < MEM_allocN_len(view_layer->object_bases_array) / sizeof(Base *));
Base *base = view_layer->object_bases_array[base_index];
@@ -424,7 +427,9 @@ void BKE_object_eval_eval_base_flags(Depsgraph *depsgraph,
object->runtime.local_collections_bits = base->local_collections_bits;
if (object->mode == OB_MODE_PARTICLE_EDIT) {
- for (ParticleSystem *psys = object->particlesystem.first; psys != NULL; psys = psys->next) {
+ for (ParticleSystem *psys = static_cast<ParticleSystem *>(object->particlesystem.first);
+ psys != nullptr;
+ psys = psys->next) {
BKE_particle_batch_cache_dirty_tag(psys, BKE_PARTICLE_BATCH_DIRTY_ALL);
}
}
@@ -432,8 +437,8 @@ void BKE_object_eval_eval_base_flags(Depsgraph *depsgraph,
/* Copy base flag back to the original view layer for editing. */
if (DEG_is_active(depsgraph) && (view_layer == DEG_get_evaluated_view_layer(depsgraph))) {
Base *base_orig = base->base_orig;
- BLI_assert(base_orig != NULL);
- BLI_assert(base_orig->object != NULL);
+ BLI_assert(base_orig != nullptr);
+ BLI_assert(base_orig->object != nullptr);
base_orig->flag = base->flag;
}
}
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index cd1f24fee37..bcf382b6022 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -55,8 +55,8 @@ static float gaussRand(RNG *rng)
float length2;
do {
- x = (float)(nextfr(rng, -1, 1));
- y = (float)(nextfr(rng, -1, 1));
+ x = (float)nextfr(rng, -1, 1);
+ y = (float)nextfr(rng, -1, 1);
length2 = x * x + y * y;
} while (length2 >= 1 || length2 == 0);
@@ -915,7 +915,7 @@ bool BKE_ocean_init(struct Ocean *o,
/* This ensures we get a value tied to the surface location, avoiding dramatic surface
* change with changing resolution.
* Explicitly cast to signed int first to ensure consistent behavior on all processors,
- * since behavior of float to unsigned int cast is undefined in C. */
+ * since behavior of `float` to `uint` cast is undefined in C. */
const int hash_x = o->_kx[i] * 360.0f;
const int hash_z = o->_kz[j] * 360.0f;
int new_seed = seed + BLI_hash_int_2d(hash_x, hash_z);
@@ -930,40 +930,37 @@ bool BKE_ocean_init(struct Ocean *o,
case MOD_OCEAN_SPECTRUM_JONSWAP:
mul_complex_f(o->_h0[i * o->_N + j],
r1r2,
- (float)(sqrt(BLI_ocean_spectrum_jonswap(o, o->_kx[i], o->_kz[j]) / 2.0f)));
- mul_complex_f(
- o->_h0_minus[i * o->_N + j],
- r1r2,
- (float)(sqrt(BLI_ocean_spectrum_jonswap(o, -o->_kx[i], -o->_kz[j]) / 2.0f)));
+ (float)sqrt(BLI_ocean_spectrum_jonswap(o, o->_kx[i], o->_kz[j]) / 2.0f));
+ mul_complex_f(o->_h0_minus[i * o->_N + j],
+ r1r2,
+ (float)sqrt(BLI_ocean_spectrum_jonswap(o, -o->_kx[i], -o->_kz[j]) / 2.0f));
break;
case MOD_OCEAN_SPECTRUM_TEXEL_MARSEN_ARSLOE:
mul_complex_f(
o->_h0[i * o->_N + j],
r1r2,
- (float)(sqrt(BLI_ocean_spectrum_texelmarsenarsloe(o, o->_kx[i], o->_kz[j]) / 2.0f)));
+ (float)sqrt(BLI_ocean_spectrum_texelmarsenarsloe(o, o->_kx[i], o->_kz[j]) / 2.0f));
mul_complex_f(
o->_h0_minus[i * o->_N + j],
r1r2,
- (float)(sqrt(BLI_ocean_spectrum_texelmarsenarsloe(o, -o->_kx[i], -o->_kz[j]) /
- 2.0f)));
+ (float)sqrt(BLI_ocean_spectrum_texelmarsenarsloe(o, -o->_kx[i], -o->_kz[j]) / 2.0f));
break;
case MOD_OCEAN_SPECTRUM_PIERSON_MOSKOWITZ:
mul_complex_f(
o->_h0[i * o->_N + j],
r1r2,
- (float)(sqrt(BLI_ocean_spectrum_piersonmoskowitz(o, o->_kx[i], o->_kz[j]) / 2.0f)));
+ (float)sqrt(BLI_ocean_spectrum_piersonmoskowitz(o, o->_kx[i], o->_kz[j]) / 2.0f));
mul_complex_f(
o->_h0_minus[i * o->_N + j],
r1r2,
- (float)(sqrt(BLI_ocean_spectrum_piersonmoskowitz(o, -o->_kx[i], -o->_kz[j]) /
- 2.0f)));
+ (float)sqrt(BLI_ocean_spectrum_piersonmoskowitz(o, -o->_kx[i], -o->_kz[j]) / 2.0f));
break;
default:
mul_complex_f(
- o->_h0[i * o->_N + j], r1r2, (float)(sqrt(Ph(o, o->_kx[i], o->_kz[j]) / 2.0f)));
+ o->_h0[i * o->_N + j], r1r2, (float)sqrt(Ph(o, o->_kx[i], o->_kz[j]) / 2.0f));
mul_complex_f(o->_h0_minus[i * o->_N + j],
r1r2,
- (float)(sqrt(Ph(o, -o->_kx[i], -o->_kz[j]) / 2.0f)));
+ (float)sqrt(Ph(o, -o->_kx[i], -o->_kz[j]) / 2.0f));
break;
}
}
@@ -1147,7 +1144,7 @@ static void cache_filename(
break;
}
- BLI_join_dirfile(cachepath, sizeof(cachepath), path, fname);
+ BLI_path_join(cachepath, sizeof(cachepath), path, fname);
BKE_image_path_from_imtype(
string, cachepath, relbase, frame, R_IMF_IMTYPE_OPENEXR, true, true, "");
diff --git a/source/blender/blenkernel/intern/outliner_treehash.cc b/source/blender/blenkernel/intern/outliner_treehash.cc
index 3f66f6bb745..9cca077509d 100644
--- a/source/blender/blenkernel/intern/outliner_treehash.cc
+++ b/source/blender/blenkernel/intern/outliner_treehash.cc
@@ -6,8 +6,8 @@
* Tree hash for the outliner space.
*/
-#include <stdlib.h>
-#include <string.h>
+#include <cstdlib>
+#include <cstring>
#include "BLI_mempool.h"
#include "BLI_utildefines.h"
@@ -34,7 +34,6 @@ class TseGroup {
* item is exponential and becomes critically slow when there are a lot of items in the group. */
int lastused_reset_count = -1;
- public:
void add_element(TreeStoreElem &elem);
void remove_element(TreeStoreElem &elem);
};
@@ -144,7 +143,7 @@ void TreeHash::remove_element(TreeStoreElem &elem)
TseGroup *TreeHash::lookup_group(const TreeStoreElemKey &key) const
{
- auto *group = elem_groups_.lookup_ptr(key);
+ const auto *group = elem_groups_.lookup_ptr(key);
if (group) {
return group->get();
}
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index 901b42ac0b2..0c9d9f5b048 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -545,7 +545,7 @@ static void unpack_generate_paths(const char *name,
break;
}
if (dir_name) {
- BLI_path_join(r_relpath, relpathlen, "//", dir_name, tempname, NULL);
+ BLI_path_join(r_relpath, relpathlen, "//", dir_name, tempname);
}
}
diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc
index 1a1bf285847..a39e53662aa 100644
--- a/source/blender/blenkernel/intern/paint.cc
+++ b/source/blender/blenkernel/intern/paint.cc
@@ -25,6 +25,7 @@
#include "BLI_hash.h"
#include "BLI_listbase.h"
#include "BLI_math_vector.h"
+#include "BLI_string_utf8.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
@@ -41,6 +42,7 @@
#include "BKE_idtype.h"
#include "BKE_image.h"
#include "BKE_key.h"
+#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_material.h"
@@ -52,6 +54,7 @@
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
+#include "BKE_scene.h"
#include "BKE_subdiv_ccg.h"
#include "BKE_subsurf.h"
@@ -64,6 +67,16 @@
#include "bmesh.h"
+static void sculpt_attribute_update_refs(Object *ob);
+static SculptAttribute *sculpt_attribute_ensure_ex(Object *ob,
+ eAttrDomain domain,
+ eCustomDataType proptype,
+ const char *name,
+ const SculptAttributeParams *params,
+ PBVHType pbvhtype,
+ bool flat_array_for_bmesh);
+void sculptsession_bmesh_add_layers(Object *ob);
+
using blender::MutableSpan;
using blender::Span;
@@ -77,10 +90,7 @@ static void palette_init_data(ID *id)
id_fake_user_set(&palette->id);
}
-static void palette_copy_data(Main *UNUSED(bmain),
- ID *id_dst,
- const ID *id_src,
- const int UNUSED(flag))
+static void palette_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int /*flag*/)
{
Palette *palette_dst = (Palette *)id_dst;
const Palette *palette_src = (const Palette *)id_src;
@@ -111,7 +121,7 @@ static void palette_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_list(reader, &palette->colors);
}
-static void palette_undo_preserve(BlendLibReader *UNUSED(reader), ID *id_new, ID *id_old)
+static void palette_undo_preserve(BlendLibReader * /*reader*/, ID *id_new, ID *id_old)
{
/* Whole Palette is preserved across undo-steps, and it has no extra pointer, simple. */
/* NOTE: We do not care about potential internal references to self here, Palette has none. */
@@ -151,10 +161,10 @@ IDTypeInfo IDType_ID_PAL = {
/* lib_override_apply_post */ nullptr,
};
-static void paint_curve_copy_data(Main *UNUSED(bmain),
+static void paint_curve_copy_data(Main * /*bmain*/,
ID *id_dst,
const ID *id_src,
- const int UNUSED(flag))
+ const int /*flag*/)
{
PaintCurve *paint_curve_dst = (PaintCurve *)id_dst;
const PaintCurve *paint_curve_src = (const PaintCurve *)id_src;
@@ -447,9 +457,11 @@ Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer)
{
if (sce && view_layer) {
ToolSettings *ts = sce->toolsettings;
+ BKE_view_layer_synced_ensure(sce, view_layer);
+ Object *actob = BKE_view_layer_active_object_get(view_layer);
- if (view_layer->basact && view_layer->basact->object) {
- switch (view_layer->basact->object->mode) {
+ if (actob) {
+ switch (actob->mode) {
case OB_MODE_SCULPT:
return &ts->sculpt->paint;
case OB_MODE_VERTEX_PAINT:
@@ -490,11 +502,8 @@ Paint *BKE_paint_get_active_from_context(const bContext *C)
if (sce && view_layer) {
ToolSettings *ts = sce->toolsettings;
- Object *obact = nullptr;
-
- if (view_layer->basact && view_layer->basact->object) {
- obact = view_layer->basact->object;
- }
+ BKE_view_layer_synced_ensure(sce, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
if ((sima = CTX_wm_space_image(C)) != nullptr) {
if (obact && obact->mode == OB_MODE_EDIT) {
@@ -524,11 +533,8 @@ ePaintMode BKE_paintmode_get_active_from_context(const bContext *C)
SpaceImage *sima;
if (sce && view_layer) {
- Object *obact = nullptr;
-
- if (view_layer->basact && view_layer->basact->object) {
- obact = view_layer->basact->object;
- }
+ BKE_view_layer_synced_ensure(sce, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
if ((sima = CTX_wm_space_image(C)) != nullptr) {
if (obact && obact->mode == OB_MODE_EDIT) {
@@ -1037,6 +1043,8 @@ eObjectMode BKE_paint_object_mode_from_paintmode(ePaintMode mode)
return OB_MODE_TEXTURE_PAINT;
case PAINT_MODE_SCULPT_UV:
return OB_MODE_EDIT;
+ case PAINT_MODE_SCULPT_CURVES:
+ return OB_MODE_SCULPT_CURVES;
case PAINT_MODE_INVALID:
default:
return OB_MODE_OBJECT;
@@ -1193,7 +1201,7 @@ void BKE_paint_stroke_get_average(Scene *scene, Object *ob, float stroke[3])
mul_v3_v3fl(stroke, ups->average_stroke_accum, fac);
}
else {
- copy_v3_v3(stroke, ob->obmat[3]);
+ copy_v3_v3(stroke, ob->object_to_world[3]);
}
}
@@ -1307,13 +1315,22 @@ void paint_update_brush_rake_rotation(UnifiedPaintSettings *ups, Brush *brush, f
}
}
+static bool paint_rake_rotation_active(const MTex &mtex)
+{
+ return mtex.tex && mtex.brush_angle_mode & MTEX_ANGLE_RAKE;
+}
+
+static bool paint_rake_rotation_active(const Brush &brush)
+{
+ return paint_rake_rotation_active(brush.mtex) || paint_rake_rotation_active(brush.mask_mtex);
+}
+
bool paint_calculate_rake_rotation(UnifiedPaintSettings *ups,
Brush *brush,
const float mouse_pos[2])
{
bool ok = false;
- if ((brush->mtex.brush_angle_mode & MTEX_ANGLE_RAKE) ||
- (brush->mask_mtex.brush_angle_mode & MTEX_ANGLE_RAKE)) {
+ if (paint_rake_rotation_active(*brush)) {
const float r = RAKE_THRESHHOLD;
float rotation;
@@ -1433,13 +1450,9 @@ static void sculptsession_free_pbvh(Object *object)
MEM_SAFE_FREE(ss->vemap);
MEM_SAFE_FREE(ss->vemap_mem);
- MEM_SAFE_FREE(ss->persistent_base);
-
MEM_SAFE_FREE(ss->preview_vert_list);
ss->preview_vert_count = 0;
- MEM_SAFE_FREE(ss->preview_vert_list);
-
MEM_SAFE_FREE(ss->vertex_info.connected_component);
MEM_SAFE_FREE(ss->vertex_info.boundary);
@@ -1473,6 +1486,8 @@ void BKE_sculptsession_free(Object *ob)
if (ob && ob->sculpt) {
SculptSession *ss = ob->sculpt;
+ BKE_sculpt_attribute_destroy_temporary_all(ob);
+
if (ss->bm) {
BKE_sculptsession_bm_to_me(ob, true);
BM_mesh_free(ss->bm);
@@ -1547,9 +1562,7 @@ static MultiresModifierData *sculpt_multires_modifier_get(const Scene *scene,
/* Multires can't work without displacement layer. */
return nullptr;
}
- else {
- need_mdisps = true;
- }
+ need_mdisps = true;
}
/* Weight paint operates on original vertices, and needs to treat multires as regular modifier
@@ -1631,6 +1644,21 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
return false;
}
+/* Helper function to keep persistent base attribute references up to
+ * date. This is a bit more tricky since they persist across strokes.
+ */
+static void sculpt_update_persistent_base(Object *ob)
+{
+ SculptSession *ss = ob->sculpt;
+
+ ss->attrs.persistent_co = BKE_sculpt_attribute_get(
+ ob, ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, SCULPT_ATTRIBUTE_NAME(persistent_co));
+ ss->attrs.persistent_no = BKE_sculpt_attribute_get(
+ ob, ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, SCULPT_ATTRIBUTE_NAME(persistent_no));
+ ss->attrs.persistent_disp = BKE_sculpt_attribute_get(
+ ob, ATTR_DOMAIN_POINT, CD_PROP_FLOAT, SCULPT_ATTRIBUTE_NAME(persistent_disp));
+}
+
static void sculpt_update_object(
Depsgraph *depsgraph, Object *ob, Object *ob_eval, bool need_pmap, bool is_paint_tool)
{
@@ -1709,13 +1737,16 @@ static void sculpt_update_object(
/* Sculpt Face Sets. */
if (use_face_sets) {
- ss->face_sets = static_cast<int *>(CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS));
+ ss->face_sets = static_cast<int *>(
+ CustomData_get_layer_named(&me->pdata, CD_PROP_INT32, ".sculpt_face_set"));
}
else {
ss->face_sets = nullptr;
}
- ss->subdiv_ccg = me_eval->runtime.subdiv_ccg;
+ ss->hide_poly = (bool *)CustomData_get_layer_named(&me->pdata, CD_PROP_BOOL, ".hide_poly");
+
+ ss->subdiv_ccg = me_eval->runtime->subdiv_ccg;
PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, ob);
BLI_assert(pbvh == ss->pbvh);
@@ -1723,9 +1754,13 @@ static void sculpt_update_object(
BKE_pbvh_subdiv_cgg_set(ss->pbvh, ss->subdiv_ccg);
BKE_pbvh_face_sets_set(ss->pbvh, ss->face_sets);
+ BKE_pbvh_update_hide_attributes_from_mesh(ss->pbvh);
BKE_pbvh_face_sets_color_set(ss->pbvh, me->face_sets_color_seed, me->face_sets_color_default);
+ sculpt_attribute_update_refs(ob);
+ sculpt_update_persistent_base(ob);
+
if (need_pmap && ob->type == OB_MESH && !ss->pmap) {
BKE_mesh_vert_poly_map_create(&ss->pmap,
&ss->pmap_mem,
@@ -1753,14 +1788,14 @@ static void sculpt_update_object(
/* If the fully evaluated mesh has the same topology as the deform-only version, use it.
* This matters because crazyspace evaluation is very restrictive and excludes even modifiers
* that simply recompute vertex weights (which can even include Geometry Nodes). */
- if (me_eval_deform->polys().data() == me_eval->polys().data() &&
- me_eval_deform->loops().data() == me_eval->loops().data() &&
+ if (me_eval_deform->totpoly == me_eval->totpoly &&
+ me_eval_deform->totloop == me_eval->totloop &&
me_eval_deform->totvert == me_eval->totvert) {
BKE_sculptsession_free_deformMats(ss);
BLI_assert(me_eval_deform->totvert == me->totvert);
- ss->deform_cos = BKE_mesh_vert_coords_alloc(me_eval, NULL);
+ ss->deform_cos = BKE_mesh_vert_coords_alloc(me_eval, nullptr);
BKE_pbvh_vert_coords_apply(ss->pbvh, ss->deform_cos, me->totvert);
used_me_eval = true;
@@ -1930,43 +1965,34 @@ int *BKE_sculpt_face_sets_ensure(Mesh *mesh)
{
using namespace blender;
using namespace blender::bke;
- if (CustomData_has_layer(&mesh->pdata, CD_SCULPT_FACE_SETS)) {
- return static_cast<int *>(CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS));
+ MutableAttributeAccessor attributes = mesh->attributes_for_write();
+ if (!attributes.contains(".sculpt_face_set")) {
+ SpanAttributeWriter<int> face_sets = attributes.lookup_or_add_for_write_only_span<int>(
+ ".sculpt_face_set", ATTR_DOMAIN_FACE);
+ face_sets.span.fill(1);
+ mesh->face_sets_color_default = 1;
+ face_sets.finish();
}
- const AttributeAccessor attributes = mesh->attributes_for_write();
- const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
- ".hide_poly", ATTR_DOMAIN_FACE, false);
-
- MutableSpan<int> face_sets = {
- static_cast<int *>(CustomData_add_layer(
- &mesh->pdata, CD_SCULPT_FACE_SETS, CD_CONSTRUCT, nullptr, mesh->totpoly)),
- mesh->totpoly};
-
- /* Initialize the new face sets with a default valid visible ID and set the default
- * color to render it white. */
- if (hide_poly.is_single() && !hide_poly.get_internal_single()) {
- face_sets.fill(1);
- }
- else {
- const int face_sets_default_visible_id = 1;
- const int face_sets_default_hidden_id = -2;
+ return static_cast<int *>(
+ CustomData_get_layer_named(&mesh->pdata, CD_PROP_INT32, ".sculpt_face_set"));
+}
- const VArraySpan<bool> hide_poly_span{hide_poly};
- for (const int i : face_sets.index_range()) {
- /* Assign a new hidden ID to hidden faces. This way we get at initial split in two Face Sets
- * between hidden and visible faces based on the previous mesh visibly from other mode that
- * can be useful in some cases. */
- face_sets[i] = hide_poly_span[i] ? face_sets_default_hidden_id :
- face_sets_default_visible_id;
- }
+bool *BKE_sculpt_hide_poly_ensure(Mesh *mesh)
+{
+ bool *hide_poly = static_cast<bool *>(
+ CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly"));
+ if (hide_poly != nullptr) {
+ return hide_poly;
}
-
- mesh->face_sets_color_default = 1;
- return face_sets.data();
+ return static_cast<bool *>(CustomData_add_layer_named(
+ &mesh->pdata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, mesh->totpoly, ".hide_poly"));
}
-int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
+int BKE_sculpt_mask_layers_ensure(Depsgraph *depsgraph,
+ Main *bmain,
+ Object *ob,
+ MultiresModifierData *mmd)
{
Mesh *me = static_cast<Mesh *>(ob->data);
const Span<MPoly> polys = me->polys();
@@ -2007,7 +2033,7 @@ int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
const MLoop *l = &loops[p->loopstart + j];
avg += paint_mask[l->v];
}
- avg /= (float)p->totloop;
+ avg /= float(p->totloop);
/* fill in multires mask corner */
for (j = 0; j < p->totloop; j++) {
@@ -2023,6 +2049,11 @@ int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
}
}
}
+ /* The evaluated multires CCG must be updated to contain the new data. */
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ if (depsgraph) {
+ BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
+ }
ret |= SCULPT_MASK_LAYER_CALC_LOOP;
}
@@ -2030,6 +2061,8 @@ int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
/* Create vertex paint mask layer if there isn't one already. */
if (!paint_mask) {
CustomData_add_layer(&me->vdata, CD_PAINT_MASK, CD_SET_DEFAULT, nullptr, me->totvert);
+ /* The evaluated mesh must be updated to contain the new data. */
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
ret |= SCULPT_MASK_LAYER_CALC_VERT;
}
@@ -2051,6 +2084,14 @@ void BKE_sculpt_toolsettings_data_ensure(Scene *scene)
sd->constant_detail = 3.0f;
}
+ if (!sd->automasking_start_normal_limit) {
+ sd->automasking_start_normal_limit = 20.0f / 180.0f * M_PI;
+ sd->automasking_start_normal_falloff = 0.25f;
+
+ sd->automasking_view_normal_limit = 90.0f / 180.0f * M_PI;
+ sd->automasking_view_normal_falloff = 0.25f;
+ }
+
/* Set sane default tiling offsets. */
if (!sd->paint.tile_offset[0]) {
sd->paint.tile_offset[0] = 1.0f;
@@ -2061,6 +2102,9 @@ void BKE_sculpt_toolsettings_data_ensure(Scene *scene)
if (!sd->paint.tile_offset[2]) {
sd->paint.tile_offset[2] = 1.0f;
}
+ if (!sd->automasking_cavity_curve || !sd->automasking_cavity_curve_op) {
+ BKE_sculpt_check_cavity_curves(sd);
+ }
}
static bool check_sculpt_object_deformed(Object *object, const bool for_construction)
@@ -2085,11 +2129,11 @@ static bool check_sculpt_object_deformed(Object *object, const bool for_construc
return deformed;
}
-void BKE_sculpt_face_sets_update_from_base_mesh_visibility(Mesh *mesh)
+void BKE_sculpt_sync_face_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
{
using namespace blender;
using namespace blender::bke;
- if (!CustomData_has_layer(&mesh->pdata, CD_SCULPT_FACE_SETS)) {
+ if (!subdiv_ccg) {
return;
}
@@ -2097,70 +2141,19 @@ void BKE_sculpt_face_sets_update_from_base_mesh_visibility(Mesh *mesh)
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
if (hide_poly.is_single() && !hide_poly.get_internal_single()) {
+ /* Nothing is hidden, so we can just remove all visibility bitmaps. */
+ for (const int i : IndexRange(subdiv_ccg->num_grids)) {
+ BKE_subdiv_ccg_grid_hidden_free(subdiv_ccg, i);
+ }
return;
}
- MutableSpan<int> face_sets{
- static_cast<int *>(CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS)), mesh->totpoly};
-
- for (const int i : hide_poly.index_range()) {
- face_sets[i] = hide_poly[i] ? -std::abs(face_sets[i]) : std::abs(face_sets[i]);
- }
-}
-
-static void set_hide_poly_from_face_sets(Mesh &mesh)
-{
- using namespace blender;
- using namespace blender::bke;
- if (!CustomData_has_layer(&mesh.pdata, CD_SCULPT_FACE_SETS)) {
- return;
- }
-
- const Span<int> face_sets{
- static_cast<const int *>(CustomData_get_layer(&mesh.pdata, CD_SCULPT_FACE_SETS)),
- mesh.totpoly};
-
- MutableAttributeAccessor attributes = mesh.attributes_for_write();
- if (std::all_of(
- face_sets.begin(), face_sets.end(), [&](const int value) { return value > 0; })) {
- attributes.remove(".hide_poly");
- return;
- }
-
- SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_only_span<bool>(
- ".hide_poly", ATTR_DOMAIN_FACE);
- if (!hide_poly) {
- return;
- }
- for (const int i : hide_poly.span.index_range()) {
- hide_poly.span[i] = face_sets[i] < 0;
- }
- hide_poly.finish();
-}
-
-void BKE_sculpt_sync_face_sets_visibility_to_base_mesh(Mesh *mesh)
-{
- set_hide_poly_from_face_sets(*mesh);
- BKE_mesh_flush_hidden_from_polys(mesh);
-}
-
-void BKE_sculpt_sync_face_sets_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
-{
- const int *face_sets = static_cast<const int *>(
- CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS));
- if (!face_sets) {
- return;
- }
-
- if (!subdiv_ccg) {
- return;
- }
-
+ const VArraySpan<bool> hide_poly_span(hide_poly);
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
for (int i = 0; i < mesh->totloop; i++) {
const int face_index = BKE_subdiv_ccg_grid_to_face_index(subdiv_ccg, i);
- const bool is_hidden = (face_sets[face_index] < 0);
+ const bool is_hidden = hide_poly_span[face_index];
/* Avoid creating and modifying the grid_hidden bitmap if the base mesh face is visible and
* there is not bitmap for the grid. This is because missing grid_hidden implies grid is fully
@@ -2176,50 +2169,18 @@ void BKE_sculpt_sync_face_sets_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv
}
}
-void BKE_sculpt_sync_face_set_visibility(Mesh *mesh, SubdivCCG *subdiv_ccg)
-{
- BKE_sculpt_face_sets_update_from_base_mesh_visibility(mesh);
- BKE_sculpt_sync_face_sets_visibility_to_base_mesh(mesh);
- BKE_sculpt_sync_face_sets_visibility_to_grids(mesh, subdiv_ccg);
-}
-
-void BKE_sculpt_ensure_orig_mesh_data(Object *object)
+static PBVH *build_pbvh_for_dynamic_topology(Object *ob)
{
- Mesh *mesh = BKE_mesh_from_object(object);
- BLI_assert(object->mode == OB_MODE_SCULPT);
-
- /* Copy the current mesh visibility to the Face Sets. */
- BKE_sculpt_face_sets_update_from_base_mesh_visibility(mesh);
+ PBVH *pbvh = ob->sculpt->pbvh = BKE_pbvh_new(PBVH_BMESH);
- /* Tessfaces aren't used and will become invalid. */
- BKE_mesh_tessface_clear(mesh);
+ sculptsession_bmesh_add_layers(ob);
- /* We always need to flush updates from depsgraph here, since at the very least
- * `BKE_sculpt_face_sets_update_from_base_mesh_visibility()` will have updated some data layer of
- * the mesh.
- *
- * All known potential sources of updates:
- * - Addition of, or changes to, the `CD_SCULPT_FACE_SETS` data layer
- * (`BKE_sculpt_face_sets_update_from_base_mesh_visibility`).
- * - Addition of a `CD_PAINT_MASK` data layer (`BKE_sculpt_mask_layers_ensure`).
- * - Object has any active modifier (modifier stack can be different in Sculpt mode).
- * - Multires:
- * + Differences of subdiv levels between sculpt and object modes
- * (`mmd->sculptlvl != mmd->lvl`).
- * + Addition of a `CD_GRID_PAINT_MASK` data layer (`BKE_sculpt_mask_layers_ensure`).
- */
- DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY);
-}
-
-static PBVH *build_pbvh_for_dynamic_topology(Object *ob)
-{
- PBVH *pbvh = BKE_pbvh_new();
BKE_pbvh_build_bmesh(pbvh,
ob->sculpt->bm,
ob->sculpt->bm_smooth_shading,
ob->sculpt->bm_log,
- ob->sculpt->cd_vert_node_offset,
- ob->sculpt->cd_face_node_offset);
+ ob->sculpt->attrs.dyntopo_node_id_vertex->bmesh_cd_offset,
+ ob->sculpt->attrs.dyntopo_node_id_face->bmesh_cd_offset);
pbvh_show_mask_set(pbvh, ob->sculpt->show_mask);
pbvh_show_face_sets_set(pbvh, false);
return pbvh;
@@ -2229,7 +2190,7 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
{
Mesh *me = BKE_object_get_original_mesh(ob);
const int looptris_num = poly_to_tri_count(me->totpoly, me->totloop);
- PBVH *pbvh = BKE_pbvh_new();
+ PBVH *pbvh = BKE_pbvh_new(PBVH_FACES);
BKE_pbvh_respect_hide_set(pbvh, respect_hide);
MutableSpan<MVert> verts = me->verts_for_write();
@@ -2242,8 +2203,6 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
BKE_mesh_recalc_looptri(
loops.data(), polys.data(), verts.data(), me->totloop, me->totpoly, looptri);
- BKE_sculpt_sync_face_set_visibility(me, nullptr);
-
BKE_pbvh_build_mesh(pbvh,
me,
polys.data(),
@@ -2274,11 +2233,11 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg, bool respect
{
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
- PBVH *pbvh = BKE_pbvh_new();
+ PBVH *pbvh = BKE_pbvh_new(PBVH_GRIDS);
BKE_pbvh_respect_hide_set(pbvh, respect_hide);
Mesh *base_mesh = BKE_mesh_from_object(ob);
- BKE_sculpt_sync_face_set_visibility(base_mesh, subdiv_ccg);
+ BKE_sculpt_sync_face_visibility_to_grids(base_mesh, subdiv_ccg);
BKE_pbvh_build_grids(pbvh,
subdiv_ccg->grids,
@@ -2286,7 +2245,9 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg, bool respect
&key,
(void **)subdiv_ccg->grid_faces,
subdiv_ccg->grid_flag_mats,
- subdiv_ccg->grid_hidden);
+ subdiv_ccg->grid_hidden,
+ base_mesh,
+ subdiv_ccg);
pbvh_show_mask_set(pbvh, ob->sculpt->show_mask);
pbvh_show_face_sets_set(pbvh, ob->sculpt->show_face_sets);
return pbvh;
@@ -2307,7 +2268,7 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
if (BKE_pbvh_type(pbvh) == PBVH_GRIDS) {
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
Mesh *mesh_eval = static_cast<Mesh *>(object_eval->data);
- SubdivCCG *subdiv_ccg = mesh_eval->runtime.subdiv_ccg;
+ SubdivCCG *subdiv_ccg = mesh_eval->runtime->subdiv_ccg;
if (subdiv_ccg != nullptr) {
BKE_sculpt_bvh_update_from_ccg(pbvh, subdiv_ccg);
}
@@ -2326,8 +2287,8 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
else {
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
Mesh *mesh_eval = static_cast<Mesh *>(object_eval->data);
- if (mesh_eval->runtime.subdiv_ccg != nullptr) {
- pbvh = build_pbvh_from_ccg(ob, mesh_eval->runtime.subdiv_ccg, respect_hide);
+ if (mesh_eval->runtime->subdiv_ccg != nullptr) {
+ pbvh = build_pbvh_from_ccg(ob, mesh_eval->runtime->subdiv_ccg, respect_hide);
}
else if (ob->type == OB_MESH) {
Mesh *me_eval_deform = object_eval->runtime.mesh_deform_eval;
@@ -2336,21 +2297,26 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
}
BKE_pbvh_pmap_set(pbvh, ob->sculpt->pmap);
-
ob->sculpt->pbvh = pbvh;
+
+ sculpt_attribute_update_refs(ob);
return pbvh;
}
void BKE_sculpt_bvh_update_from_ccg(PBVH *pbvh, SubdivCCG *subdiv_ccg)
{
+ CCGKey key;
+ BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
+
BKE_pbvh_grids_update(pbvh,
subdiv_ccg->grids,
(void **)subdiv_ccg->grid_faces,
subdiv_ccg->grid_flag_mats,
- subdiv_ccg->grid_hidden);
+ subdiv_ccg->grid_hidden,
+ &key);
}
-bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const View3D *UNUSED(v3d))
+bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const RegionView3D *rv3d)
{
SculptSession *ss = ob->sculpt;
if (ss == nullptr || ss->pbvh == nullptr || ss->mode_type != OB_MODE_SCULPT) {
@@ -2358,9 +2324,10 @@ bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const View3D *UNUSED(v3d)
}
if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
- /* Regular mesh only draws from PBVH without modifiers and shape keys. */
-
- return !(ss->shapekey_active || ss->deform_modifiers_active);
+ /* Regular mesh only draws from PBVH without modifiers and shape keys, or for
+ * external engines that do not have access to the PBVH like Eevee does. */
+ const bool external_engine = rv3d && rv3d->render_engine != nullptr;
+ return !(ss->shapekey_active || ss->deform_modifiers_active || external_engine);
}
/* Multires and dyntopo always draw directly from the PBVH. */
@@ -2372,10 +2339,10 @@ bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const View3D *UNUSED(v3d)
void BKE_paint_face_set_overlay_color_get(const int face_set, const int seed, uchar r_color[4])
{
float rgba[4];
- float random_mod_hue = GOLDEN_RATIO_CONJUGATE * (abs(face_set) + (seed % 10));
+ float random_mod_hue = GOLDEN_RATIO_CONJUGATE * (face_set + (seed % 10));
random_mod_hue = random_mod_hue - floorf(random_mod_hue);
- const float random_mod_sat = BLI_hash_int_01(abs(face_set) + seed + 1);
- const float random_mod_val = BLI_hash_int_01(abs(face_set) + seed + 2);
+ const float random_mod_sat = BLI_hash_int_01(face_set + seed + 1);
+ const float random_mod_val = BLI_hash_int_01(face_set + seed + 2);
hsv_to_rgb(random_mod_hue,
0.6f + (random_mod_sat * 0.25f),
1.0f - (random_mod_val * 0.35f),
@@ -2384,3 +2351,559 @@ void BKE_paint_face_set_overlay_color_get(const int face_set, const int seed, uc
&rgba[2]);
rgba_float_to_uchar(r_color, rgba);
}
+
+int BKE_sculptsession_vertex_count(const SculptSession *ss)
+{
+ switch (BKE_pbvh_type(ss->pbvh)) {
+ case PBVH_FACES:
+ return ss->totvert;
+ case PBVH_BMESH:
+ return BM_mesh_elem_count(ss->bm, BM_VERT);
+ case PBVH_GRIDS:
+ return BKE_pbvh_get_grid_num_verts(ss->pbvh);
+ }
+
+ return 0;
+}
+
+/** Returns pointer to a CustomData associated with a given domain, if
+ * one exists. If not nullptr is returned (this may happen with e.g.
+ * multires and ATTR_DOMAIN_POINT).
+ */
+static CustomData *sculpt_get_cdata(Object *ob, eAttrDomain domain)
+{
+ SculptSession *ss = ob->sculpt;
+
+ if (ss->bm) {
+ switch (domain) {
+ case ATTR_DOMAIN_POINT:
+ return &ss->bm->vdata;
+ case ATTR_DOMAIN_FACE:
+ return &ss->bm->pdata;
+ default:
+ BLI_assert_unreachable();
+ return nullptr;
+ }
+ }
+ else {
+ Mesh *me = BKE_object_get_original_mesh(ob);
+
+ switch (domain) {
+ case ATTR_DOMAIN_POINT:
+ /* Cannot get vertex domain for multires grids. */
+ if (ss->pbvh && BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
+ return nullptr;
+ }
+
+ return &me->vdata;
+ case ATTR_DOMAIN_FACE:
+ return &me->pdata;
+ default:
+ BLI_assert_unreachable();
+ return nullptr;
+ }
+ }
+}
+
+static int sculpt_attr_elem_count_get(Object *ob, eAttrDomain domain)
+{
+ SculptSession *ss = ob->sculpt;
+
+ switch (domain) {
+ case ATTR_DOMAIN_POINT:
+ return BKE_sculptsession_vertex_count(ss);
+ break;
+ case ATTR_DOMAIN_FACE:
+ return ss->totfaces;
+ break;
+ default:
+ BLI_assert_unreachable();
+ return 0;
+ }
+}
+
+static bool sculpt_attribute_create(SculptSession *ss,
+ Object *ob,
+ eAttrDomain domain,
+ eCustomDataType proptype,
+ const char *name,
+ SculptAttribute *out,
+ const SculptAttributeParams *params,
+ PBVHType pbvhtype,
+ bool flat_array_for_bmesh)
+{
+ Mesh *me = BKE_object_get_original_mesh(ob);
+
+ bool simple_array = params->simple_array;
+ bool permanent = params->permanent;
+
+ out->params = *params;
+ out->proptype = proptype;
+ out->domain = domain;
+ BLI_strncpy_utf8(out->name, name, sizeof(out->name));
+
+ /* Force non-CustomData simple_array mode if not PBVH_FACES. */
+ if (pbvhtype == PBVH_GRIDS || (pbvhtype == PBVH_BMESH && flat_array_for_bmesh)) {
+ if (permanent) {
+ printf(
+ "%s: error: tried to make permanent customdata in multires or bmesh mode; will make "
+ "local "
+ "array "
+ "instead.\n",
+ __func__);
+ permanent = (out->params.permanent = false);
+ }
+
+ simple_array = (out->params.simple_array = true);
+ }
+
+ BLI_assert(!(simple_array && permanent));
+
+ int totelem = sculpt_attr_elem_count_get(ob, domain);
+
+ if (simple_array) {
+ int elemsize = CustomData_sizeof(proptype);
+
+ out->data = MEM_calloc_arrayN(totelem, elemsize, __func__);
+
+ out->data_for_bmesh = ss->bm != nullptr;
+ out->bmesh_cd_offset = -1;
+ out->layer = nullptr;
+ out->elem_size = elemsize;
+ out->used = true;
+ out->elem_num = totelem;
+
+ return true;
+ }
+
+ switch (BKE_pbvh_type(ss->pbvh)) {
+ case PBVH_BMESH: {
+ CustomData *cdata = nullptr;
+ out->data_for_bmesh = true;
+
+ switch (domain) {
+ case ATTR_DOMAIN_POINT:
+ cdata = &ss->bm->vdata;
+ break;
+ case ATTR_DOMAIN_FACE:
+ cdata = &ss->bm->pdata;
+ break;
+ default:
+ out->used = false;
+ return false;
+ }
+
+ BLI_assert(CustomData_get_named_layer_index(cdata, proptype, name) == -1);
+
+ BM_data_layer_add_named(ss->bm, cdata, proptype, name);
+ int index = CustomData_get_named_layer_index(cdata, proptype, name);
+
+ if (!permanent) {
+ cdata->layers[index].flag |= CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY;
+ }
+
+ out->data = nullptr;
+ out->layer = cdata->layers + index;
+ out->bmesh_cd_offset = out->layer->offset;
+ out->elem_size = CustomData_sizeof(proptype);
+ break;
+ }
+ case PBVH_FACES: {
+ CustomData *cdata = nullptr;
+
+ out->data_for_bmesh = false;
+
+ switch (domain) {
+ case ATTR_DOMAIN_POINT:
+ cdata = &me->vdata;
+ break;
+ case ATTR_DOMAIN_FACE:
+ cdata = &me->pdata;
+ break;
+ default:
+ out->used = false;
+ return false;
+ }
+
+ BLI_assert(CustomData_get_named_layer_index(cdata, proptype, name) == -1);
+
+ CustomData_add_layer_named(cdata, proptype, CD_SET_DEFAULT, nullptr, totelem, name);
+ int index = CustomData_get_named_layer_index(cdata, proptype, name);
+
+ if (!permanent) {
+ cdata->layers[index].flag |= CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY;
+ }
+
+ out->data = nullptr;
+ out->layer = cdata->layers + index;
+ out->bmesh_cd_offset = -1;
+ out->data = out->layer->data;
+ out->elem_size = CustomData_get_elem_size(out->layer);
+
+ break;
+ }
+ case PBVH_GRIDS: {
+ /* GRIDS should have been handled as simple arrays. */
+ BLI_assert_unreachable();
+ break;
+ }
+ default:
+ BLI_assert_unreachable();
+ break;
+ }
+
+ out->used = true;
+ out->elem_num = totelem;
+
+ return true;
+}
+
+static bool sculpt_attr_update(Object *ob, SculptAttribute *attr)
+{
+ SculptSession *ss = ob->sculpt;
+ int elem_num = sculpt_attr_elem_count_get(ob, attr->domain);
+
+ bool bad = false;
+
+ if (attr->params.simple_array) {
+ bad = attr->elem_num != elem_num;
+
+ if (bad) {
+ MEM_SAFE_FREE(attr->data);
+ }
+ }
+ else {
+ CustomData *cdata = sculpt_get_cdata(ob, attr->domain);
+
+ if (cdata) {
+ int layer_index = CustomData_get_named_layer_index(cdata, attr->proptype, attr->name);
+ bad = layer_index == -1;
+
+ if (ss->bm) {
+ attr->bmesh_cd_offset = cdata->layers[layer_index].offset;
+ }
+ }
+ }
+
+ if (bad) {
+ sculpt_attribute_create(ss,
+ ob,
+ attr->domain,
+ attr->proptype,
+ attr->name,
+ attr,
+ &attr->params,
+ BKE_pbvh_type(ss->pbvh),
+ true);
+ }
+
+ return bad;
+}
+
+static SculptAttribute *sculpt_get_cached_layer(SculptSession *ss,
+ eAttrDomain domain,
+ eCustomDataType proptype,
+ const char *name)
+{
+ for (int i = 0; i < SCULPT_MAX_ATTRIBUTES; i++) {
+ SculptAttribute *attr = ss->temp_attributes + i;
+
+ if (attr->used && STREQ(attr->name, name) && attr->proptype == proptype &&
+ attr->domain == domain) {
+
+ return attr;
+ }
+ }
+
+ return nullptr;
+}
+
+bool BKE_sculpt_attribute_exists(Object *ob,
+ eAttrDomain domain,
+ eCustomDataType proptype,
+ const char *name)
+{
+ SculptSession *ss = ob->sculpt;
+ SculptAttribute *attr = sculpt_get_cached_layer(ss, domain, proptype, name);
+
+ if (attr) {
+ return true;
+ }
+
+ CustomData *cdata = sculpt_get_cdata(ob, domain);
+ return CustomData_get_named_layer_index(cdata, proptype, name) != -1;
+
+ return false;
+}
+
+static SculptAttribute *sculpt_alloc_attr(SculptSession *ss)
+{
+ for (int i = 0; i < SCULPT_MAX_ATTRIBUTES; i++) {
+ if (!ss->temp_attributes[i].used) {
+ memset((void *)(ss->temp_attributes + i), 0, sizeof(SculptAttribute));
+ ss->temp_attributes[i].used = true;
+
+ return ss->temp_attributes + i;
+ }
+ }
+
+ BLI_assert_unreachable();
+ return nullptr;
+}
+
+SculptAttribute *BKE_sculpt_attribute_get(struct Object *ob,
+ eAttrDomain domain,
+ eCustomDataType proptype,
+ const char *name)
+{
+ SculptSession *ss = ob->sculpt;
+
+ /* See if attribute is cached in ss->temp_attributes. */
+ SculptAttribute *attr = sculpt_get_cached_layer(ss, domain, proptype, name);
+
+ if (attr) {
+ if (sculpt_attr_update(ob, attr)) {
+ sculpt_attribute_update_refs(ob);
+ }
+
+ return attr;
+ }
+
+ /* Does attribute exist in CustomData layout? */
+ CustomData *cdata = sculpt_get_cdata(ob, domain);
+ if (cdata) {
+ int index = CustomData_get_named_layer_index(cdata, proptype, name);
+
+ if (index != -1) {
+ int totelem = 0;
+
+ switch (domain) {
+ case ATTR_DOMAIN_POINT:
+ totelem = BKE_sculptsession_vertex_count(ss);
+ break;
+ case ATTR_DOMAIN_FACE:
+ totelem = ss->totfaces;
+ break;
+ default:
+ BLI_assert_unreachable();
+ break;
+ }
+
+ attr = sculpt_alloc_attr(ss);
+
+ attr->used = true;
+ attr->domain = domain;
+ attr->proptype = proptype;
+ attr->data = cdata->layers[index].data;
+ attr->bmesh_cd_offset = cdata->layers[index].offset;
+ attr->elem_num = totelem;
+ attr->layer = cdata->layers + index;
+ attr->elem_size = CustomData_get_elem_size(attr->layer);
+
+ BLI_strncpy_utf8(attr->name, name, sizeof(attr->name));
+ return attr;
+ }
+ }
+
+ return nullptr;
+}
+
+static SculptAttribute *sculpt_attribute_ensure_ex(Object *ob,
+ eAttrDomain domain,
+ eCustomDataType proptype,
+ const char *name,
+ const SculptAttributeParams *params,
+ PBVHType pbvhtype,
+ bool flat_array_for_bmesh)
+{
+ SculptSession *ss = ob->sculpt;
+ SculptAttribute *attr = BKE_sculpt_attribute_get(ob, domain, proptype, name);
+
+ if (attr) {
+ return attr;
+ }
+
+ attr = sculpt_alloc_attr(ss);
+
+ /* Create attribute. */
+ sculpt_attribute_create(
+ ss, ob, domain, proptype, name, attr, params, pbvhtype, flat_array_for_bmesh);
+ sculpt_attribute_update_refs(ob);
+
+ return attr;
+}
+
+SculptAttribute *BKE_sculpt_attribute_ensure(Object *ob,
+ eAttrDomain domain,
+ eCustomDataType proptype,
+ const char *name,
+ const SculptAttributeParams *params)
+{
+ SculptAttributeParams temp_params = *params;
+
+ return sculpt_attribute_ensure_ex(
+ ob, domain, proptype, name, &temp_params, BKE_pbvh_type(ob->sculpt->pbvh), true);
+}
+
+static void sculptsession_bmesh_attr_update_internal(Object *ob)
+{
+ SculptSession *ss = ob->sculpt;
+
+ sculptsession_bmesh_add_layers(ob);
+
+ if (ss->pbvh) {
+ BKE_pbvh_update_bmesh_offsets(ss->pbvh,
+ ob->sculpt->attrs.dyntopo_node_id_vertex->bmesh_cd_offset,
+ ob->sculpt->attrs.dyntopo_node_id_face->bmesh_cd_offset);
+ }
+}
+
+void sculptsession_bmesh_add_layers(Object *ob)
+{
+ SculptSession *ss = ob->sculpt;
+ SculptAttributeParams params = {0};
+
+ ss->attrs.dyntopo_node_id_vertex = sculpt_attribute_ensure_ex(
+ ob,
+ ATTR_DOMAIN_POINT,
+ CD_PROP_INT32,
+ SCULPT_ATTRIBUTE_NAME(dyntopo_node_id_vertex),
+ &params,
+ PBVH_BMESH,
+ false);
+
+ ss->attrs.dyntopo_node_id_face = sculpt_attribute_ensure_ex(
+ ob,
+ ATTR_DOMAIN_FACE,
+ CD_PROP_INT32,
+ SCULPT_ATTRIBUTE_NAME(dyntopo_node_id_face),
+ &params,
+ PBVH_BMESH,
+ false);
+}
+
+void BKE_sculpt_attributes_destroy_temporary_stroke(Object *ob)
+{
+ SculptSession *ss = ob->sculpt;
+
+ for (int i = 0; i < SCULPT_MAX_ATTRIBUTES; i++) {
+ SculptAttribute *attr = ss->temp_attributes + i;
+
+ if (attr->params.stroke_only) {
+ BKE_sculpt_attribute_destroy(ob, attr);
+ }
+ }
+}
+
+static void sculpt_attribute_update_refs(Object *ob)
+{
+ SculptSession *ss = ob->sculpt;
+
+ /* run twice, in case sculpt_attr_update had to recreate a layer and
+ messed up the bmesh offsets. */
+ for (int i = 0; i < 2; i++) {
+ for (int j = 0; j < SCULPT_MAX_ATTRIBUTES; j++) {
+ SculptAttribute *attr = ss->temp_attributes + j;
+
+ if (attr->used) {
+ sculpt_attr_update(ob, attr);
+ }
+ }
+
+ if (ss->bm) {
+ sculptsession_bmesh_attr_update_internal(ob);
+ }
+ }
+
+ Mesh *me = BKE_object_get_original_mesh(ob);
+
+ if (ss->pbvh) {
+ BKE_pbvh_update_active_vcol(ss->pbvh, me);
+ }
+}
+
+void BKE_sculpt_attribute_destroy_temporary_all(Object *ob)
+{
+ SculptSession *ss = ob->sculpt;
+
+ for (int i = 0; i < SCULPT_MAX_ATTRIBUTES; i++) {
+ SculptAttribute *attr = ss->temp_attributes + i;
+
+ if (attr->used && !attr->params.permanent) {
+ BKE_sculpt_attribute_destroy(ob, attr);
+ }
+ }
+}
+
+bool BKE_sculpt_attribute_destroy(Object *ob, SculptAttribute *attr)
+{
+ SculptSession *ss = ob->sculpt;
+ eAttrDomain domain = attr->domain;
+
+ BLI_assert(attr->used);
+
+ /* Remove from convenience pointer struct. */
+ SculptAttribute **ptrs = (SculptAttribute **)&ss->attrs;
+ int ptrs_num = sizeof(ss->attrs) / sizeof(void *);
+
+ for (int i = 0; i < ptrs_num; i++) {
+ if (ptrs[i] == attr) {
+ ptrs[i] = nullptr;
+ }
+ }
+
+ /* Remove from internal temp_attributes array. */
+ for (int i = 0; i < SCULPT_MAX_ATTRIBUTES; i++) {
+ SculptAttribute *attr2 = ss->temp_attributes + i;
+
+ if (STREQ(attr2->name, attr->name) && attr2->domain == attr->domain &&
+ attr2->proptype == attr->proptype) {
+
+ attr2->used = false;
+ }
+ }
+
+ Mesh *me = BKE_object_get_original_mesh(ob);
+
+ if (attr->params.simple_array) {
+ MEM_SAFE_FREE(attr->data);
+ }
+ else if (ss->bm) {
+ CustomData *cdata = attr->domain == ATTR_DOMAIN_POINT ? &ss->bm->vdata : &ss->bm->pdata;
+
+ BM_data_layer_free_named(ss->bm, cdata, attr->name);
+ }
+ else {
+ CustomData *cdata = nullptr;
+ int totelem = 0;
+
+ switch (domain) {
+ case ATTR_DOMAIN_POINT:
+ cdata = ss->bm ? &ss->bm->vdata : &me->vdata;
+ totelem = ss->totvert;
+ break;
+ case ATTR_DOMAIN_FACE:
+ cdata = ss->bm ? &ss->bm->pdata : &me->pdata;
+ totelem = ss->totfaces;
+ break;
+ default:
+ BLI_assert_unreachable();
+ return false;
+ }
+
+ /* We may have been called after destroying ss->bm in which case attr->layer
+ * might be invalid.
+ */
+ int layer_i = CustomData_get_named_layer_index(cdata, attr->proptype, attr->name);
+ if (layer_i != 0) {
+ CustomData_free_layer(cdata, attr->proptype, totelem, layer_i);
+ }
+
+ sculpt_attribute_update_refs(ob);
+ }
+
+ attr->data = nullptr;
+ attr->used = false;
+
+ return true;
+}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index c894e507d35..6a277295efd 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -53,12 +53,14 @@
#include "BKE_idtype.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
+#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh_legacy_convert.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_particle.h"
@@ -506,8 +508,8 @@ IDTypeInfo IDType_ID_PA = {
.lib_override_apply_post = NULL,
};
-unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT];
-unsigned int PSYS_FRAND_SEED_MULTIPLIER[PSYS_FRAND_COUNT];
+uint PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT];
+uint PSYS_FRAND_SEED_MULTIPLIER[PSYS_FRAND_COUNT];
float PSYS_FRAND_BASE[PSYS_FRAND_COUNT];
void BKE_particle_init_rng(void)
@@ -515,8 +517,8 @@ void BKE_particle_init_rng(void)
RNG *rng = BLI_rng_new_srandom(5831); /* arbitrary */
for (int i = 0; i < PSYS_FRAND_COUNT; i++) {
PSYS_FRAND_BASE[i] = BLI_rng_get_float(rng);
- PSYS_FRAND_SEED_OFFSET[i] = (unsigned int)BLI_rng_get_int(rng);
- PSYS_FRAND_SEED_MULTIPLIER[i] = (unsigned int)BLI_rng_get_int(rng);
+ PSYS_FRAND_SEED_OFFSET[i] = (uint)BLI_rng_get_int(rng);
+ PSYS_FRAND_SEED_MULTIPLIER[i] = (uint)BLI_rng_get_int(rng);
}
BLI_rng_free(rng);
}
@@ -682,10 +684,13 @@ void psys_set_current_num(Object *ob, int index)
}
}
-struct LatticeDeformData *psys_create_lattice_deform_data(ParticleSimulationData *sim)
+void psys_sim_data_init(ParticleSimulationData *sim)
{
- struct LatticeDeformData *lattice_deform_data = NULL;
+ ParticleSystem *psys = sim->psys;
+ ParticleSettings *part = psys->part;
+ /* Prepare lattice deform. */
+ psys->lattice_deform_data = NULL;
if (psys_in_edit_mode(sim->depsgraph, sim->psys) == 0) {
Object *lattice = NULL;
ModifierData *md = (ModifierData *)psys_get_modifier(sim->ob, sim->psys);
@@ -697,19 +702,39 @@ struct LatticeDeformData *psys_create_lattice_deform_data(ParticleSimulationData
if (md->mode & mode) {
LatticeModifierData *lmd = (LatticeModifierData *)md;
lattice = lmd->object;
- sim->psys->lattice_strength = lmd->strength;
+ psys->lattice_strength = lmd->strength;
}
break;
}
}
if (lattice) {
- lattice_deform_data = BKE_lattice_deform_data_create(lattice, NULL);
+ psys->lattice_deform_data = BKE_lattice_deform_data_create(lattice, NULL);
}
}
- return lattice_deform_data;
+ /* Prepare curvemapping tables. */
+ if ((part->child_flag & PART_CHILD_USE_CLUMP_CURVE) && part->clumpcurve) {
+ BKE_curvemapping_init(part->clumpcurve);
+ }
+ if ((part->child_flag & PART_CHILD_USE_ROUGH_CURVE) && part->roughcurve) {
+ BKE_curvemapping_init(part->roughcurve);
+ }
+ if ((part->child_flag & PART_CHILD_USE_TWIST_CURVE) && part->twistcurve) {
+ BKE_curvemapping_init(part->twistcurve);
+ }
}
+
+void psys_sim_data_free(ParticleSimulationData *sim)
+{
+ ParticleSystem *psys = sim->psys;
+
+ if (psys->lattice_deform_data) {
+ BKE_lattice_deform_data_destroy(psys->lattice_deform_data);
+ psys->lattice_deform_data = NULL;
+ }
+}
+
void psys_disable_all(Object *ob)
{
ParticleSystem *psys = ob->particlesystem.first;
@@ -761,13 +786,15 @@ static PTCacheEdit *psys_orig_edit_get(ParticleSystem *psys)
bool psys_in_edit_mode(Depsgraph *depsgraph, const ParticleSystem *psys)
{
- const ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
- if (view_layer->basact == NULL) {
+ const Scene *scene = DEG_get_input_scene(depsgraph);
+ ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ const Object *object = BKE_view_layer_active_object_get(view_layer);
+ if (object == NULL) {
/* TODO(sergey): Needs double-check with multi-object edit. */
return false;
}
const bool use_render_params = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
- const Object *object = view_layer->basact->object;
if (object->mode != OB_MODE_PARTICLE_EDIT) {
return false;
}
@@ -1930,7 +1957,7 @@ int psys_particle_dm_face_lookup(Mesh *mesh_final,
index_mf_to_mpoly_deformed = CustomData_get_layer(&mesh_original->fdata, CD_ORIGINDEX);
}
else {
- BLI_assert(mesh_final->runtime.deformed_only);
+ BLI_assert(BKE_mesh_is_deformed_only(mesh_final));
index_mf_to_mpoly_deformed = index_mf_to_mpoly;
}
BLI_assert(index_mf_to_mpoly_deformed);
@@ -2020,7 +2047,7 @@ static int psys_map_index_on_dm(Mesh *mesh,
return 0;
}
- if (mesh->runtime.deformed_only || index_dmcache == DMCACHE_ISCHILD) {
+ if (BKE_mesh_is_deformed_only(mesh) || index_dmcache == DMCACHE_ISCHILD) {
/* for meshes that are either only deformed or for child particles, the
* index and fw do not require any mapping, so we can directly use it */
if (from == PART_FROM_VERT) {
@@ -2366,8 +2393,8 @@ void precalc_guides(ParticleSimulationData *sim, ListBase *effectors)
0,
0);
- mul_m4_v3(sim->ob->obmat, state.co);
- mul_mat3_m4_v3(sim->ob->obmat, state.vel);
+ mul_m4_v3(sim->ob->object_to_world, state.co);
+ mul_mat3_m4_v3(sim->ob->object_to_world, state.vel);
pd_point_from_particle(sim, pa, &state, &point);
@@ -2450,8 +2477,8 @@ bool do_guides(Depsgraph *depsgraph,
}
}
- mul_m4_v3(eff->ob->obmat, guidevec);
- mul_mat3_m4_v3(eff->ob->obmat, guidedir);
+ mul_m4_v3(eff->ob->object_to_world, guidevec);
+ mul_mat3_m4_v3(eff->ob->object_to_world, guidedir);
normalize_v3(guidedir);
@@ -2460,7 +2487,7 @@ bool do_guides(Depsgraph *depsgraph,
if (guidetime != 0.0f) {
/* curve direction */
cross_v3_v3v3(temp, eff->guide_dir, guidedir);
- angle = dot_v3v3(eff->guide_dir, guidedir) / (len_v3(eff->guide_dir));
+ angle = dot_v3v3(eff->guide_dir, guidedir) / len_v3(eff->guide_dir);
angle = saacos(angle);
axis_angle_to_quat(rot2, temp, angle);
mul_qt_v3(rot2, vec_to_point);
@@ -2780,7 +2807,7 @@ static bool psys_thread_context_init_path(ParticleThreadContext *ctx,
ctx->cfra = cfra;
ctx->editupdate = editupdate;
- psys->lattice_deform_data = psys_create_lattice_deform_data(&ctx->sim);
+ psys_sim_data_init(&ctx->sim);
/* cache all relevant vertex groups if they exist */
ctx->vg_length = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_LENGTH);
@@ -2952,7 +2979,7 @@ static void psys_thread_create_path(ParticleTask *task,
psys_particle_on_emitter(
ctx->sim.psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa->fuv, foffset, co, 0, 0, 0, orco);
- mul_m4_v3(ob->obmat, co);
+ mul_m4_v3(ob->object_to_world, co);
for (w = 0; w < 4; w++) {
sub_v3_v3v3(off1[w], co, key[w]->co);
@@ -2985,8 +3012,7 @@ static void psys_thread_create_path(ParticleTask *task,
* pa->num, pa->fuv,
* NULL);
*/
- cpa_num = (ELEM(pa->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND)) ? pa->num :
- pa->num_dmcache;
+ cpa_num = ELEM(pa->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND) ? pa->num : pa->num_dmcache;
/* XXX hack to avoid messed up particle num and subsequent crash (T40733) */
if (cpa_num > ctx->sim.psmd->mesh_final->totface) {
@@ -3337,7 +3363,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
cache = psys->pathcache = psys_alloc_path_cache_buffers(
&psys->pathcachebufs, totpart, segments + 1);
- psys->lattice_deform_data = psys_create_lattice_deform_data(sim);
+ psys_sim_data_init(sim);
ma = BKE_object_material_get(sim->ob, psys->part->omat);
if (ma && (psys->part->draw_col == PART_DRAW_COL_MAT)) {
copy_v3_v3(col, &ma->r);
@@ -3416,7 +3442,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
/* dynamic hair is in object space */
/* keyed and baked are already in global space */
if (hair_mesh) {
- mul_m4_v3(sim->ob->obmat, ca->co);
+ mul_m4_v3(sim->ob->object_to_world, ca->co);
}
else if (!keyed && !baked && !(psys->flag & PSYS_GLOBAL_HAIR)) {
mul_m4_v3(hairmat, ca->co);
@@ -3504,10 +3530,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
psys->totcached = totpart;
- if (psys->lattice_deform_data) {
- BKE_lattice_deform_data_destroy(psys->lattice_deform_data);
- psys->lattice_deform_data = NULL;
- }
+ psys_sim_data_free(sim);
if (vg_effector) {
MEM_freeN(vg_effector);
@@ -3847,7 +3870,7 @@ static void psys_face_mat(Object *ob, Mesh *mesh, ParticleData *pa, float mat[4]
MFace *mface;
const float(*orcodata)[3];
- int i = (ELEM(pa->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND)) ? pa->num : pa->num_dmcache;
+ int i = ELEM(pa->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND) ? pa->num : pa->num_dmcache;
if (i == -1 || i >= mesh->totface) {
unit_m4(mat);
return;
@@ -3926,7 +3949,7 @@ void psys_mat_hair_to_global(
psys_mat_hair_to_object(ob, mesh, from, pa, facemat);
- mul_m4_m4m4(hairmat, ob->obmat, facemat);
+ mul_m4_m4m4(hairmat, ob->object_to_world, facemat);
}
/************************************************/
@@ -4287,7 +4310,7 @@ static void get_cpa_texture(Mesh *mesh,
case TEXCO_OBJECT:
copy_v3_v3(texvec, par->state.co);
if (mtex->object) {
- mul_m4_v3(mtex->object->imat, texvec);
+ mul_m4_v3(mtex->object->world_to_object, texvec);
}
break;
case TEXCO_UV:
@@ -4375,7 +4398,7 @@ void psys_get_texture(
case TEXCO_OBJECT:
copy_v3_v3(texvec, pa->state.co);
if (mtex->object) {
- mul_m4_v3(mtex->object->imat, texvec);
+ mul_m4_v3(mtex->object->world_to_object, texvec);
}
break;
case TEXCO_UV:
@@ -4658,8 +4681,8 @@ void psys_get_particle_on_path(ParticleSimulationData *sim,
do_particle_interpolation(psys, p, pa, t, &pind, state);
if (pind.mesh) {
- mul_m4_v3(sim->ob->obmat, state->co);
- mul_mat3_m4_v3(sim->ob->obmat, state->vel);
+ mul_m4_v3(sim->ob->object_to_world, state->co);
+ mul_mat3_m4_v3(sim->ob->object_to_world, state->vel);
}
else if (!keyed && !cached && !(psys->flag & PSYS_GLOBAL_HAIR)) {
if ((pa->flag & PARS_REKEY) == 0) {
@@ -4682,7 +4705,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim,
}
}
else if (totchild) {
- // invert_m4_m4(imat, ob->obmat);
+ // invert_m4_m4(imat, ob->object_to_world);
/* interpolate childcache directly if it exists */
if (psys->childcache) {
@@ -4730,7 +4753,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim,
* positioning it accurately to the surface of the emitter. */
// copy_v3_v3(cpa_1st, co);
- // mul_m4_v3(ob->obmat, cpa_1st);
+ // mul_m4_v3(ob->object_to_world, cpa_1st);
pa = psys->particles + cpa->parent;
@@ -4864,6 +4887,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim,
}
}
}
+
bool psys_get_particle_state(ParticleSimulationData *sim,
int p,
ParticleKey *state,
@@ -5167,7 +5191,7 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim,
}
if (psys->part->rotmode == PART_ROT_VEL) {
- transpose_m3_m4(nmat, ob->imat);
+ transpose_m3_m4(nmat, ob->world_to_object);
mul_m3_v3(nmat, nor);
normalize_v3(nor);
@@ -5222,7 +5246,7 @@ void psys_apply_hair_lattice(Depsgraph *depsgraph, Scene *scene, Object *ob, Par
sim.psys = psys;
sim.psmd = psys_get_modifier(ob, psys);
- psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
+ psys_sim_data_init(&sim);
if (psys->lattice_deform_data) {
ParticleData *pa = psys->particles;
@@ -5243,12 +5267,11 @@ void psys_apply_hair_lattice(Depsgraph *depsgraph, Scene *scene, Object *ob, Par
}
}
- BKE_lattice_deform_data_destroy(psys->lattice_deform_data);
- psys->lattice_deform_data = NULL;
-
/* protect the applied shape */
psys->flag |= PSYS_EDITED;
}
+
+ psys_sim_data_free(&sim);
}
/* Draw Engine */
diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c
index a890812cfc4..6cc7dbc70d0 100644
--- a/source/blender/blenkernel/intern/particle_child.c
+++ b/source/blender/blenkernel/intern/particle_child.c
@@ -187,7 +187,7 @@ static void do_kink_spiral(ParticleThreadContext *ctx,
zero_v3(kink_base);
kink_base[part->kink_axis] = 1.0f;
- mul_mat3_m4_v3(ctx->sim.ob->obmat, kink_base);
+ mul_mat3_m4_v3(ctx->sim.ob->object_to_world, kink_base);
/* Fill in invariant part of modifier context. */
ParticleChildModifierContext modifier_ctx = {NULL};
@@ -873,7 +873,7 @@ void do_child_modifiers(const ParticleChildModifierContext *modifier_ctx,
part->kink_flat,
part->kink,
part->kink_axis,
- sim->ob->obmat,
+ sim->ob->object_to_world,
smooth_start);
}
}
diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c
index ed1d93647ce..0301b83a043 100644
--- a/source/blender/blenkernel/intern/particle_distribute.c
+++ b/source/blender/blenkernel/intern/particle_distribute.c
@@ -29,6 +29,7 @@
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh_legacy_convert.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_object.h"
#include "BKE_particle.h"
@@ -453,7 +454,7 @@ static int distribute_binary_search(const float *sum, int n, float value)
return low;
}
-/* the max number if calls to rng_* funcs within psys_thread_distribute_particle
+/* the max number if calls to rng_* functions within psys_thread_distribute_particle
* be sure to keep up to date if this changes */
#define PSYS_RND_DIST_SKIP 3
@@ -480,7 +481,7 @@ static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, i
* map to equal-colored parts of a texture */
for (int i = 0; i < ctx->mesh->totface; i++, mface++) {
if (ELEM(pa->num, mface->v1, mface->v2, mface->v3, mface->v4)) {
- unsigned int *vert = &mface->v1;
+ uint *vert = &mface->v1;
for (int j = 0; j < 4; j++, vert++) {
if (*vert == pa->num) {
@@ -899,7 +900,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
return 0;
}
- if (!final_mesh->runtime.deformed_only &&
+ if (!BKE_mesh_is_deformed_only(final_mesh) &&
!CustomData_get_layer(&final_mesh->fdata, CD_ORIGINDEX)) {
printf(
"Can't create particles with the current modifier stack, disable destructive modifiers\n");
@@ -1093,7 +1094,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
maxweight /= totarea;
}
else {
- float min = 1.0f / (float)(MIN2(totelem, totpart));
+ float min = 1.0f / (float)MIN2(totelem, totpart);
for (i = 0; i < totelem; i++) {
element_weight[i] = min;
}
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 9608676a153..d97a217a734 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -48,6 +48,7 @@
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_mesh_legacy_convert.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_particle.h"
#include "BKE_bvhutils.h"
@@ -319,7 +320,7 @@ void psys_calc_dmcache(Object *ob, Mesh *mesh_final, Mesh *mesh_original, Partic
PARTICLE_P;
/* CACHE LOCATIONS */
- if (!mesh_final->runtime.deformed_only) {
+ if (!BKE_mesh_is_deformed_only(mesh_final)) {
/* Will use later to speed up subsurf/evaluated mesh. */
LinkNode *node, *nodedmelem, **nodearray;
int totdmelem, totelem, i;
@@ -515,10 +516,7 @@ void psys_thread_context_free(ParticleThreadContext *ctx)
MEM_freeN(ctx->vg_twist);
}
- if (ctx->sim.psys->lattice_deform_data) {
- BKE_lattice_deform_data_destroy(ctx->sim.psys->lattice_deform_data);
- ctx->sim.psys->lattice_deform_data = NULL;
- }
+ psys_sim_data_free(&ctx->sim);
/* distribution */
if (ctx->jit) {
@@ -603,7 +601,7 @@ static void initialize_all_particles(ParticleSimulationData *sim)
* UNEXIST flag.
*/
const bool emit_from_volume_grid = (part->distr == PART_DISTR_GRID) &&
- (!ELEM(part->from, PART_FROM_VERT, PART_FROM_CHILD));
+ !ELEM(part->from, PART_FROM_VERT, PART_FROM_CHILD);
PARTICLE_P;
LOOP_PARTICLES
{
@@ -749,10 +747,10 @@ void psys_get_birth_coords(
/* particles live in global space so */
/* let's convert: */
/* -location */
- mul_m4_v3(ob->obmat, loc);
+ mul_m4_v3(ob->object_to_world, loc);
/* -normal */
- mul_mat3_m4_v3(ob->obmat, nor);
+ mul_mat3_m4_v3(ob->object_to_world, nor);
normalize_v3(nor);
/* -tangent */
@@ -770,7 +768,7 @@ void psys_get_birth_coords(
fac = -sinf((float)M_PI * (part->tanphase + phase));
madd_v3_v3fl(vtan, utan, fac);
- mul_mat3_m4_v3(ob->obmat, vtan);
+ mul_mat3_m4_v3(ob->object_to_world, vtan);
copy_v3_v3(utan, nor);
mul_v3_fl(utan, dot_v3v3(vtan, nor));
@@ -785,7 +783,7 @@ void psys_get_birth_coords(
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);
+ mul_mat3_m4_v3(ob->object_to_world, r_vel);
normalize_v3(r_vel);
}
@@ -795,7 +793,7 @@ void psys_get_birth_coords(
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);
+ mul_mat3_m4_v3(ob->object_to_world, r_ave);
normalize_v3(r_ave);
}
@@ -807,7 +805,7 @@ void psys_get_birth_coords(
r_rot[3] = 2.0f * (psys_frand(psys, p + 19) - 0.5f);
normalize_qt(r_rot);
- mat4_to_quat(rot, ob->obmat);
+ mat4_to_quat(rot, ob->object_to_world);
mul_qt_qtqt(r_rot, r_rot, rot);
}
@@ -821,7 +819,7 @@ void psys_get_birth_coords(
/* boids store direction in ave */
if (fabsf(nor[2]) == 1.0f) {
- sub_v3_v3v3(state->ave, loc, ob->obmat[3]);
+ sub_v3_v3v3(state->ave, loc, ob->object_to_world[3]);
normalize_v3(state->ave);
}
else {
@@ -867,15 +865,15 @@ void psys_get_birth_coords(
/* *emitter object orientation */
if (part->ob_vel[0] != 0.0f) {
- normalize_v3_v3(vec, ob->obmat[0]);
+ normalize_v3_v3(vec, ob->object_to_world[0]);
madd_v3_v3fl(vel, vec, part->ob_vel[0]);
}
if (part->ob_vel[1] != 0.0f) {
- normalize_v3_v3(vec, ob->obmat[1]);
+ normalize_v3_v3(vec, ob->object_to_world[1]);
madd_v3_v3fl(vel, vec, part->ob_vel[1]);
}
if (part->ob_vel[2] != 0.0f) {
- normalize_v3_v3(vec, ob->obmat[2]);
+ normalize_v3_v3(vec, ob->object_to_world[2]);
madd_v3_v3fl(vel, vec, part->ob_vel[2]);
}
@@ -923,7 +921,7 @@ void psys_get_birth_coords(
case PART_ROT_OB_X:
case PART_ROT_OB_Y:
case PART_ROT_OB_Z:
- copy_v3_v3(rot_vec, ob->obmat[part->rotmode - PART_ROT_OB_X]);
+ copy_v3_v3(rot_vec, ob->object_to_world[part->rotmode - PART_ROT_OB_X]);
use_global_space = false;
break;
default:
@@ -950,7 +948,7 @@ void psys_get_birth_coords(
float q_obmat[4];
float q_imat[4];
- mat4_to_quat(q_obmat, ob->obmat);
+ mat4_to_quat(q_obmat, ob->object_to_world);
invert_qt_qt_normalized(q_imat, q_obmat);
if (part->rotmode != PART_ROT_NOR_TAN) {
@@ -1638,7 +1636,7 @@ static void sph_springs_modify(ParticleSystem *psys, float dtime)
}
}
- /* Loop through springs backwaqrds - for efficient delete function */
+ /* Loop through springs backwards - for efficient delete function. */
for (i = psys->tot_fluidsprings - 1; i >= 0; i--) {
if (psys->fluid_springs[i].delete_flag) {
sph_spring_delete(psys, i);
@@ -3363,7 +3361,7 @@ static void hair_create_input_mesh(ParticleSimulationData *sim,
use_hair = psys_hair_use_simulation(pa, max_length);
psys_mat_hair_to_object(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat);
- mul_m4_m4m4(root_mat, sim->ob->obmat, hairmat);
+ mul_m4_m4m4(root_mat, sim->ob->object_to_world, hairmat);
normalize_m4(root_mat);
bending_stiffness = CLAMPIS(
@@ -3554,14 +3552,14 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra))
HairKey *key, *root;
PARTICLE_P;
- invert_m4_m4(ob->imat, ob->obmat);
-
- psys->lattice_deform_data = psys_create_lattice_deform_data(sim);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
if (psys->totpart == 0) {
return;
}
+ psys_sim_data_init(sim);
+
/* save new keys for elements if needed */
LOOP_PARTICLES
{
@@ -3576,7 +3574,7 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra))
/* convert from global to geometry space */
copy_v3_v3(key->co, pa->state.co);
- mul_m4_v3(ob->imat, key->co);
+ mul_m4_v3(ob->world_to_object, key->co);
if (pa->totkey) {
sub_v3_v3(key->co, root->co);
@@ -3595,6 +3593,8 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra))
zero_v3(root->co);
}
}
+
+ psys_sim_data_free(sim);
}
/* Code for an adaptive time step based on the Courant-Friedrichs-Lewy
@@ -4098,6 +4098,8 @@ static void cached_step(ParticleSimulationData *sim, float cfra, const bool use_
disp = psys_get_current_display_percentage(psys, use_render_params);
+ psys_sim_data_init(sim);
+
LOOP_PARTICLES
{
psys_get_texture(sim, pa, &ptex, PAMAP_SIZE, cfra);
@@ -4106,8 +4108,6 @@ static void cached_step(ParticleSimulationData *sim, float cfra, const bool use_
pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1);
}
- psys->lattice_deform_data = psys_create_lattice_deform_data(sim);
-
dietime = pa->dietime;
/* update alive status and push events */
@@ -4124,11 +4124,6 @@ static void cached_step(ParticleSimulationData *sim, float cfra, const bool use_
pa->alive = PARS_ALIVE;
}
- if (psys->lattice_deform_data) {
- BKE_lattice_deform_data_destroy(psys->lattice_deform_data);
- psys->lattice_deform_data = NULL;
- }
-
if (psys_frand(psys, p) > disp) {
pa->flag |= PARS_NO_DISP;
}
@@ -4136,6 +4131,8 @@ static void cached_step(ParticleSimulationData *sim, float cfra, const bool use_
pa->flag &= ~PARS_NO_DISP;
}
}
+
+ psys_sim_data_free(sim);
}
static bool particles_has_flip(short parttype)
@@ -4150,17 +4147,17 @@ static bool particles_has_tracer(short parttype)
static bool particles_has_spray(short parttype)
{
- return (ELEM(parttype, PART_FLUID_SPRAY, PART_FLUID_SPRAYFOAM, PART_FLUID_SPRAYFOAMBUBBLE));
+ return ELEM(parttype, PART_FLUID_SPRAY, PART_FLUID_SPRAYFOAM, PART_FLUID_SPRAYFOAMBUBBLE);
}
static bool particles_has_bubble(short parttype)
{
- return (ELEM(parttype, PART_FLUID_BUBBLE, PART_FLUID_FOAMBUBBLE, PART_FLUID_SPRAYFOAMBUBBLE));
+ return ELEM(parttype, PART_FLUID_BUBBLE, PART_FLUID_FOAMBUBBLE, PART_FLUID_SPRAYFOAMBUBBLE);
}
static bool particles_has_foam(short parttype)
{
- return (ELEM(parttype, PART_FLUID_FOAM, PART_FLUID_SPRAYFOAM, PART_FLUID_SPRAYFOAMBUBBLE));
+ return ELEM(parttype, PART_FLUID_FOAM, PART_FLUID_SPRAYFOAM, PART_FLUID_SPRAYFOAMBUBBLE);
}
static void particles_fluid_step(ParticleSimulationData *sim,
@@ -4379,7 +4376,7 @@ static void particles_fluid_step(ParticleSimulationData *sim,
mul_v3_v3(pa->state.co, scaleAbs);
/* Match domain scale. */
- mul_m4_v3(ob->obmat, pa->state.co);
+ mul_m4_v3(ob->object_to_world, pa->state.co);
/* Add origin offset to particle position. */
zero_v3(tmp);
@@ -4608,10 +4605,7 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_
update_children(sim, use_render_params);
/* cleanup */
- if (psys->lattice_deform_data) {
- BKE_lattice_deform_data_destroy(psys->lattice_deform_data);
- psys->lattice_deform_data = NULL;
- }
+ psys_sim_data_free(sim);
}
void psys_changed_type(Object *ob, ParticleSystem *psys)
@@ -4763,7 +4757,7 @@ void particle_system_update(struct Depsgraph *depsgraph,
float cfra;
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
- /* drawdata is outdated after ANY change */
+ /* Draw data is outdated after ANY change. */
if (psys->pdd) {
psys->pdd->flag &= ~PARTICLE_DRAW_DATA_UPDATED;
}
@@ -4962,7 +4956,7 @@ void particle_system_update(struct Depsgraph *depsgraph,
/* Save matrix for duplicators,
* at render-time the actual dupli-object's matrix is used so don't update! */
- invert_m4_m4(psys->imat, ob->obmat);
+ invert_m4_m4(psys->imat, ob->object_to_world);
BKE_particle_batch_cache_dirty_tag(psys, BKE_PARTICLE_BATCH_DIRTY_ALL);
}
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 2de5c718918..98e89b09060 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -25,9 +25,9 @@
#include "BKE_pbvh.h"
#include "BKE_subdiv_ccg.h"
-#include "PIL_time.h"
+#include "DRW_pbvh.h"
-#include "GPU_buffers.h"
+#include "PIL_time.h"
#include "bmesh.h"
@@ -39,8 +39,10 @@
#define LEAF_LIMIT 10000
-//#define PERFCNTRS
+/* Uncomment to test that faces are only assigned to one PBVHNode */
+//#define VALIDATE_UNIQUE_NODE_FACES
+//#define PERFCNTRS
#define STACK_FIXED_DEPTH 100
typedef struct PBVHStack {
@@ -234,8 +236,7 @@ void pbvh_grow_nodes(PBVH *pbvh, int totnode)
/* Add a vertex to the map, with a positive value for unique vertices and
* a negative value for additional vertices */
-static int map_insert_vert(
- PBVH *pbvh, GHash *map, unsigned int *face_verts, unsigned int *uniq_verts, int vertex)
+static int map_insert_vert(PBVH *pbvh, GHash *map, uint *face_verts, uint *uniq_verts, int vertex)
{
void *key, **value_p;
@@ -366,26 +367,6 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
return totquad;
}
-void BKE_pbvh_sync_face_sets_to_grids(PBVH *pbvh)
-{
- const int gridsize = pbvh->gridkey.grid_size;
- for (int i = 0; i < pbvh->totgrid; i++) {
- BLI_bitmap *gh = pbvh->grid_hidden[i];
- const int face_index = BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, i);
- if (!gh && pbvh->face_sets[face_index] < 0) {
- gh = pbvh->grid_hidden[i] = BLI_BITMAP_NEW(pbvh->gridkey.grid_area,
- "partialvis_update_grids");
- }
- if (gh) {
- for (int y = 0; y < gridsize; y++) {
- for (int x = 0; x < gridsize; x++) {
- BLI_BITMAP_SET(gh, y * gridsize + x, pbvh->face_sets[face_index] < 0);
- }
- }
- }
- }
-}
-
static void build_grid_leaf_node(PBVH *pbvh, PBVHNode *node)
{
int totquads = BKE_pbvh_count_grid_quads(
@@ -443,6 +424,56 @@ static bool leaf_needs_material_split(PBVH *pbvh, int offset, int count)
return false;
}
+static int adjust_partition_faces(PBVH *pbvh, int offset, int mid, int count)
+{
+ int poly = pbvh->looptri[pbvh->prim_indices[mid]].poly;
+
+ /* Scan backwards. */
+ while (mid > offset + 2) { /* First node should have at least 1 primitive */
+ if (pbvh->looptri[pbvh->prim_indices[mid - 1]].poly != poly) {
+ return mid;
+ }
+
+ mid--;
+ }
+
+ /* If that didn't work try scanning forward. */
+ while (mid < pbvh->totprim + count) {
+ if (pbvh->looptri[pbvh->prim_indices[mid]].poly != poly) {
+ break;
+ }
+
+ mid++;
+ }
+
+ return mid;
+}
+
+static int adjust_partition_grids(PBVH *pbvh, int offset, int mid, int count)
+{
+ int poly = BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, pbvh->prim_indices[mid]);
+
+ /* Scan backwards. */
+ while (mid > offset + 2) { /* First node should have at least 1 primitive */
+ if (BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, pbvh->prim_indices[mid - 1]) != poly) {
+ return mid;
+ }
+
+ mid--;
+ }
+
+ /* If that didn't work try scanning forward. */
+ while (mid < pbvh->totprim + count) {
+ if (BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, pbvh->prim_indices[mid]) != poly) {
+ break;
+ }
+
+ mid++;
+ }
+
+ return mid;
+}
+
/* Recursively build a node in the tree
*
* vb is the voxel box around all of the primitives contained in
@@ -499,6 +530,13 @@ static void build_sub(PBVH *pbvh, int node_index, BB *cb, BBC *prim_bbc, int off
end = partition_indices_material(pbvh, offset, offset + count - 1);
}
+ if (pbvh->header.type == PBVH_FACES) {
+ end = adjust_partition_faces(pbvh, offset, end, count);
+ }
+ else {
+ end = adjust_partition_grids(pbvh, offset, end, count);
+ }
+
/* Build children */
build_sub(pbvh, pbvh->nodes[node_index].children_offset, NULL, prim_bbc, offset, end - offset);
build_sub(pbvh,
@@ -534,6 +572,147 @@ static void pbvh_build(PBVH *pbvh, BB *cb, BBC *prim_bbc, int totprim)
build_sub(pbvh, 0, cb, prim_bbc, 0, totprim);
}
+static void pbvh_draw_args_init(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node)
+{
+ memset((void *)args, 0, sizeof(*args));
+
+ args->pbvh_type = pbvh->header.type;
+ args->mesh_verts_num = pbvh->totvert;
+ args->mesh_grids_num = pbvh->totgrid;
+ args->node = node;
+
+ BKE_pbvh_node_num_verts(pbvh, node, NULL, &args->node_verts_num);
+
+ args->grid_hidden = pbvh->grid_hidden;
+ args->face_sets_color_default = pbvh->face_sets_color_default;
+ args->face_sets_color_seed = pbvh->face_sets_color_seed;
+ args->mvert = pbvh->verts;
+ args->mloop = pbvh->mloop;
+ args->mpoly = pbvh->mpoly;
+ args->mlooptri = pbvh->looptri;
+
+ if (ELEM(pbvh->header.type, PBVH_FACES, PBVH_GRIDS)) {
+ args->hide_poly = pbvh->pdata ?
+ CustomData_get_layer_named(pbvh->pdata, CD_PROP_BOOL, ".hide_poly") :
+ NULL;
+ }
+
+ switch (pbvh->header.type) {
+ case PBVH_FACES:
+ args->mesh_faces_num = pbvh->mesh->totpoly;
+ args->vdata = pbvh->vdata;
+ args->ldata = pbvh->ldata;
+ args->pdata = pbvh->pdata;
+ args->totprim = node->totprim;
+ args->me = pbvh->mesh;
+ args->mpoly = pbvh->mpoly;
+ args->vert_normals = pbvh->vert_normals;
+
+ args->prim_indices = node->prim_indices;
+ args->face_sets = pbvh->face_sets;
+ break;
+ case PBVH_GRIDS:
+ args->vdata = pbvh->vdata;
+ args->ldata = pbvh->ldata;
+ args->pdata = pbvh->pdata;
+ args->ccg_key = pbvh->gridkey;
+ args->me = pbvh->mesh;
+ args->totprim = node->totprim;
+ args->grid_indices = node->prim_indices;
+ args->subdiv_ccg = pbvh->subdiv_ccg;
+ args->face_sets = pbvh->face_sets;
+ args->mpoly = pbvh->mpoly;
+
+ args->mesh_grids_num = pbvh->totgrid;
+ args->grids = pbvh->grids;
+ args->gridfaces = pbvh->gridfaces;
+ args->grid_flag_mats = pbvh->grid_flag_mats;
+ args->vert_normals = pbvh->vert_normals;
+
+ args->face_sets = pbvh->face_sets;
+ break;
+ case PBVH_BMESH:
+ args->bm = pbvh->header.bm;
+ args->vdata = &args->bm->vdata;
+ args->ldata = &args->bm->ldata;
+ args->pdata = &args->bm->pdata;
+ args->bm_faces = node->bm_faces;
+ args->bm_other_verts = node->bm_other_verts;
+ args->bm_unique_vert = node->bm_unique_verts;
+ args->totprim = BLI_gset_len(node->bm_faces);
+ args->cd_mask_layer = CustomData_get_offset(&pbvh->header.bm->vdata, CD_PAINT_MASK);
+
+ break;
+ }
+}
+
+#ifdef VALIDATE_UNIQUE_NODE_FACES
+static void pbvh_validate_node_prims(PBVH *pbvh)
+{
+ int totface = 0;
+
+ if (pbvh->header.type == PBVH_BMESH) {
+ return;
+ }
+
+ for (int i = 0; i < pbvh->totnode; i++) {
+ PBVHNode *node = pbvh->nodes + i;
+
+ if (!(node->flag & PBVH_Leaf)) {
+ continue;
+ }
+
+ for (int j = 0; j < node->totprim; j++) {
+ int poly;
+
+ if (pbvh->header.type == PBVH_FACES) {
+ poly = pbvh->looptri[node->prim_indices[j]].poly;
+ }
+ else {
+ poly = BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, node->prim_indices[j]);
+ }
+
+ totface = max_ii(totface, poly + 1);
+ }
+ }
+
+ int *facemap = (int *)MEM_malloc_arrayN(totface, sizeof(*facemap), __func__);
+
+ for (int i = 0; i < totface; i++) {
+ facemap[i] = -1;
+ }
+
+ for (int i = 0; i < pbvh->totnode; i++) {
+ PBVHNode *node = pbvh->nodes + i;
+
+ if (!(node->flag & PBVH_Leaf)) {
+ continue;
+ }
+
+ for (int j = 0; j < node->totprim; j++) {
+ int poly;
+
+ if (pbvh->header.type == PBVH_FACES) {
+ poly = pbvh->looptri[node->prim_indices[j]].poly;
+ }
+ else {
+ poly = BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, node->prim_indices[j]);
+ }
+
+ if (facemap[poly] != -1 && facemap[poly] != i) {
+ printf("%s: error: face spanned multiple nodes (old: %d new: %d)\n",
+ __func__,
+ facemap[poly],
+ i);
+ }
+
+ facemap[poly] = i;
+ }
+ }
+ MEM_SAFE_FREE(facemap);
+}
+#endif
+
void BKE_pbvh_build_mesh(PBVH *pbvh,
Mesh *mesh,
const MPoly *mpoly,
@@ -592,6 +771,32 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
BB_expand(&cb, bbc->bcentroid);
}
+ /* Ensure all primitives belonging to the same base face
+ * have the same bounds. This is needed to prevent them
+ * from being swapped away from each other inside the partition
+ * array.
+ */
+ for (int i = 0; i < looptri_num; i++) {
+ const MLoopTri *lt = &looptri[i];
+ int poly = lt->poly;
+ BBC *bbc = prim_bbc + i;
+ int j = i + 1;
+
+ while (j < looptri_num && looptri[j].poly == poly) {
+ BBC *bbc2 = prim_bbc + j;
+
+ BB_expand((BB *)bbc, bbc2->bmin);
+ BB_expand((BB *)bbc, bbc2->bmax);
+ j++;
+ }
+
+ j = i + 1;
+ while (j < looptri_num && looptri[j].poly == poly) {
+ prim_bbc[j] = prim_bbc[i];
+ j++;
+ }
+ }
+
if (looptri_num) {
pbvh_build(pbvh, &cb, prim_bbc, looptri_num);
}
@@ -602,6 +807,10 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
memset(pbvh->vert_bitmap, 0, sizeof(bool) * totvert);
BKE_pbvh_update_active_vcol(pbvh, mesh);
+
+#ifdef VALIDATE_UNIQUE_NODE_FACES
+ pbvh_validate_node_prims(pbvh);
+#endif
}
void BKE_pbvh_build_grids(PBVH *pbvh,
@@ -610,7 +819,9 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
CCGKey *key,
void **gridfaces,
DMFlagMat *flagmats,
- BLI_bitmap **grid_hidden)
+ BLI_bitmap **grid_hidden,
+ Mesh *me,
+ SubdivCCG *subdiv_ccg)
{
const int gridsize = key->grid_size;
@@ -621,8 +832,17 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
pbvh->totgrid = totgrid;
pbvh->gridkey = *key;
pbvh->grid_hidden = grid_hidden;
+ pbvh->subdiv_ccg = subdiv_ccg;
pbvh->leaf_limit = max_ii(LEAF_LIMIT / (gridsize * gridsize), 1);
+ /* We need the base mesh attribute layout for PBVH draw. */
+ pbvh->vdata = &me->vdata;
+ pbvh->ldata = &me->ldata;
+ pbvh->pdata = &me->pdata;
+
+ /* We also need the base mesh for PBVH draw. */
+ pbvh->mesh = me;
+
BB cb;
BB_reset(&cb);
@@ -644,18 +864,53 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
BB_expand(&cb, bbc->bcentroid);
}
+ /* Ensure all primitives belonging to the same base face
+ * have the same bounds. This is needed to prevent them
+ * from being swapped away from each other inside the partition
+ * array.
+ */
+ for (int i = 0; i < totgrid; i++) {
+ int poly = BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, i);
+
+ BBC *bbc = prim_bbc + i;
+ int j = i + 1;
+
+ while (j < totgrid && BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, j) == poly) {
+ BBC *bbc2 = prim_bbc + j;
+
+ BB_expand((BB *)bbc, bbc2->bmin);
+ BB_expand((BB *)bbc, bbc2->bmax);
+ j++;
+ }
+
+ j = i + 1;
+ while (j < totgrid && BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, j) == poly) {
+ prim_bbc[j] = prim_bbc[i];
+ j++;
+ }
+ }
+
if (totgrid) {
pbvh_build(pbvh, &cb, prim_bbc, totgrid);
}
MEM_freeN(prim_bbc);
+#ifdef VALIDATE_UNIQUE_NODE_FACES
+ pbvh_validate_node_prims(pbvh);
+#endif
}
-PBVH *BKE_pbvh_new(void)
+PBVH *BKE_pbvh_new(PBVHType type)
{
PBVH *pbvh = MEM_callocN(sizeof(PBVH), "pbvh");
pbvh->respect_hide = true;
pbvh->draw_cache_invalid = true;
+ pbvh->header.type = type;
+
+ /* Initialize this to true, instead of waiting for a draw engine
+ * to set it. Prevents a crash in draw manager instancing code.
+ */
+ pbvh->is_drawing = true;
return pbvh;
}
@@ -665,8 +920,8 @@ void BKE_pbvh_free(PBVH *pbvh)
PBVHNode *node = &pbvh->nodes[i];
if (node->flag & PBVH_Leaf) {
- if (node->draw_buffers) {
- GPU_pbvh_buffers_free(node->draw_buffers);
+ if (node->draw_batches) {
+ DRW_pbvh_node_free(node->draw_batches);
}
if (node->vert_indices) {
MEM_freeN((void *)node->vert_indices);
@@ -713,10 +968,6 @@ void BKE_pbvh_free(PBVH *pbvh)
MEM_SAFE_FREE(pbvh->vert_bitmap);
- if (pbvh->vbo_id) {
- GPU_pbvh_free_format(pbvh->vbo_id);
- }
-
MEM_freeN(pbvh);
}
@@ -1008,6 +1259,8 @@ typedef struct PBVHUpdateData {
float (*vnors)[3];
int flag;
bool show_sculpt_face_sets;
+ PBVHAttrReq *attrs;
+ int attrs_num;
} PBVHUpdateData;
static void pbvh_update_normals_clear_task_cb(void *__restrict userdata,
@@ -1042,7 +1295,7 @@ static void pbvh_update_normals_accum_task_cb(void *__restrict userdata,
float(*vnors)[3] = data->vnors;
if (node->flag & PBVH_UpdateNormals) {
- unsigned int mpoly_prev = UINT_MAX;
+ uint mpoly_prev = UINT_MAX;
float fn[3];
const int *faces = node->prim_indices;
@@ -1050,7 +1303,7 @@ static void pbvh_update_normals_accum_task_cb(void *__restrict userdata,
for (int i = 0; i < totface; i++) {
const MLoopTri *lt = &pbvh->looptri[faces[i]];
- const unsigned int vtri[3] = {
+ const uint vtri[3] = {
pbvh->mloop[lt->tri[0]].v,
pbvh->mloop[lt->tri[1]].v,
pbvh->mloop[lt->tri[2]].v,
@@ -1260,13 +1513,6 @@ void pbvh_update_BB_redraw(PBVH *pbvh, PBVHNode **nodes, int totnode, int flag)
BLI_task_parallel_range(0, totnode, &data, pbvh_update_BB_redraw_task_cb, &settings);
}
-static int pbvh_get_buffers_update_flags(PBVH *UNUSED(pbvh))
-{
- int update_flags = GPU_PBVH_BUFFERS_SHOW_VCOL | GPU_PBVH_BUFFERS_SHOW_MASK |
- GPU_PBVH_BUFFERS_SHOW_SCULPT_FACE_SETS;
- return update_flags;
-}
-
bool BKE_pbvh_get_color_layer(const Mesh *me, CustomDataLayer **r_layer, eAttrDomain *r_attr)
{
CustomDataLayer *layer = BKE_id_attributes_active_color_get((ID *)me);
@@ -1303,127 +1549,29 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
PBVHNode *node = data->nodes[n];
if (node->flag & PBVH_RebuildDrawBuffers) {
- switch (pbvh->header.type) {
- case PBVH_GRIDS: {
- bool smooth = node->totprim > 0 ?
- pbvh->grid_flag_mats[node->prim_indices[0]].flag & ME_SMOOTH :
- false;
+ PBVH_GPU_Args args;
+ pbvh_draw_args_init(pbvh, &args, node);
- node->draw_buffers = GPU_pbvh_grid_buffers_build(node->totprim, pbvh->grid_hidden, smooth);
- break;
- }
- case PBVH_FACES:
- node->draw_buffers = GPU_pbvh_mesh_buffers_build(
- pbvh->mesh, pbvh->looptri, node->prim_indices, node->totprim);
- break;
- case PBVH_BMESH:
- node->draw_buffers = GPU_pbvh_bmesh_buffers_build(pbvh->flags &
- PBVH_DYNTOPO_SMOOTH_SHADING);
- break;
- }
+ node->draw_batches = DRW_pbvh_node_create(&args);
}
if (node->flag & PBVH_UpdateDrawBuffers) {
node->debug_draw_gen++;
- const int update_flags = pbvh_get_buffers_update_flags(pbvh);
- switch (pbvh->header.type) {
- case PBVH_GRIDS:
- GPU_pbvh_grid_buffers_update(pbvh->vbo_id,
- node->draw_buffers,
- pbvh->subdiv_ccg,
- pbvh->grids,
- pbvh->grid_flag_mats,
- node->prim_indices,
- node->totprim,
- pbvh->face_sets,
- pbvh->face_sets_color_seed,
- pbvh->face_sets_color_default,
- &pbvh->gridkey,
- update_flags);
- break;
- case PBVH_FACES: {
- /* Pass vertices separately because they may be not be the same as the mesh's vertices,
- * and pass normals separately because they are managed by the PBVH. */
- GPU_pbvh_mesh_buffers_update(pbvh->vbo_id,
- node->draw_buffers,
- pbvh->mesh,
- pbvh->verts,
- CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK),
- CustomData_get_layer(pbvh->pdata, CD_SCULPT_FACE_SETS),
- pbvh->face_sets_color_seed,
- pbvh->face_sets_color_default,
- update_flags,
- pbvh->vert_normals);
- break;
- }
- case PBVH_BMESH:
- GPU_pbvh_bmesh_buffers_update(pbvh->vbo_id,
- node->draw_buffers,
- pbvh->header.bm,
- node->bm_faces,
- node->bm_unique_verts,
- node->bm_other_verts,
- update_flags);
- break;
- }
- }
-}
-
-void pbvh_free_draw_buffers(PBVH *pbvh, PBVHNode *node)
-{
- if (node->draw_buffers) {
- pbvh->draw_cache_invalid = true;
+ if (node->draw_batches) {
+ PBVH_GPU_Args args;
- GPU_pbvh_buffers_free(node->draw_buffers);
- node->draw_buffers = NULL;
+ pbvh_draw_args_init(pbvh, &args, node);
+ DRW_pbvh_node_update(node->draw_batches, &args);
+ }
}
}
-static void pbvh_check_draw_layout(PBVH *pbvh)
+void pbvh_free_draw_buffers(PBVH *UNUSED(pbvh), PBVHNode *node)
{
- const CustomData *vdata;
- const CustomData *ldata;
-
- if (!pbvh->vbo_id) {
- pbvh->vbo_id = GPU_pbvh_make_format();
- }
-
- switch (pbvh->header.type) {
- case PBVH_BMESH:
- if (!pbvh->header.bm) {
- /* BMesh hasn't been created yet */
- return;
- }
-
- vdata = &pbvh->header.bm->vdata;
- ldata = &pbvh->header.bm->ldata;
- break;
- case PBVH_FACES:
- vdata = pbvh->vdata;
- ldata = pbvh->ldata;
- break;
- case PBVH_GRIDS:
- ldata = vdata = NULL;
- break;
- }
-
- /* Rebuild all draw buffers if attribute layout changed.
- *
- * NOTE: The optimization where we only send active attributes
- * to the GPU in workbench mode is disabled due to bugs
- * (there's no guarantee there isn't another EEVEE viewport which would
- * free the draw buffers and corrupt the draw cache).
- */
- if (GPU_pbvh_attribute_names_update(pbvh->header.type, pbvh->vbo_id, vdata, ldata, false)) {
- /* attribute layout changed; force rebuild */
- for (int i = 0; i < pbvh->totnode; i++) {
- PBVHNode *node = pbvh->nodes + i;
-
- if (node->flag & PBVH_Leaf) {
- node->flag |= PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
- }
- }
+ if (node->draw_batches) {
+ DRW_pbvh_node_free(node->draw_batches);
+ node->draw_batches = NULL;
}
}
@@ -1431,10 +1579,6 @@ static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode,
{
const CustomData *vdata;
- if (!pbvh->vbo_id) {
- pbvh->vbo_id = GPU_pbvh_make_format();
- }
-
switch (pbvh->header.type) {
case PBVH_BMESH:
if (!pbvh->header.bm) {
@@ -1460,14 +1604,11 @@ static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode,
if (node->flag & PBVH_RebuildDrawBuffers) {
pbvh_free_draw_buffers(pbvh, node);
}
- else if ((node->flag & PBVH_UpdateDrawBuffers) && node->draw_buffers) {
- if (pbvh->header.type == PBVH_GRIDS) {
- GPU_pbvh_grid_buffers_update_free(
- node->draw_buffers, pbvh->grid_flag_mats, node->prim_indices);
- }
- else if (pbvh->header.type == PBVH_BMESH) {
- GPU_pbvh_bmesh_buffers_update_free(node->draw_buffers);
- }
+ else if ((node->flag & PBVH_UpdateDrawBuffers) && node->draw_batches) {
+ PBVH_GPU_Args args;
+
+ pbvh_draw_args_init(pbvh, &args, node);
+ DRW_pbvh_update_pre(node->draw_batches, &args);
}
}
}
@@ -1487,7 +1628,10 @@ static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode,
if (node->flag & PBVH_UpdateDrawBuffers) {
/* Flush buffers uses OpenGL, so not in parallel. */
- GPU_pbvh_buffers_update_flush(node->draw_buffers);
+
+ if (node->draw_batches) {
+ DRW_pbvh_node_gpu_flush(node->draw_batches);
+ }
}
node->flag &= ~(PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers);
@@ -2092,11 +2236,16 @@ void BKE_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *pro
void BKE_pbvh_node_get_bm_orco_data(PBVHNode *node,
int (**r_orco_tris)[3],
int *r_orco_tris_num,
- float (**r_orco_coords)[3])
+ float (**r_orco_coords)[3],
+ BMVert ***r_orco_verts)
{
*r_orco_tris = node->bm_ortri;
*r_orco_tris_num = node->bm_tot_ortri;
*r_orco_coords = node->bm_orco;
+
+ if (r_orco_verts) {
+ *r_orco_verts = node->bm_orvert;
+ }
}
bool BKE_pbvh_node_has_vert_with_normal_update_tag(PBVH *pbvh, PBVHNode *node)
@@ -2186,8 +2335,8 @@ bool ray_face_intersection_tri(const float ray_start[3],
float *depth)
{
float depth_test;
- if ((isect_ray_tri_watertight_v3(ray_start, isect_precalc, t0, t1, t2, &depth_test, NULL) &&
- (depth_test < *depth))) {
+ if (isect_ray_tri_watertight_v3(ray_start, isect_precalc, t0, t1, t2, &depth_test, NULL) &&
+ (depth_test < *depth)) {
*depth = depth_test;
return true;
}
@@ -2232,12 +2381,12 @@ bool ray_face_nearest_quad(const float ray_start[3],
float dist_sq_test;
float co[3], depth_test;
- if (((dist_sq_test = dist_squared_ray_to_tri_v3_fast(
- ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq)) {
+ if ((dist_sq_test = dist_squared_ray_to_tri_v3_fast(
+ ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq) {
*dist_sq = dist_sq_test;
*depth = depth_test;
- if (((dist_sq_test = dist_squared_ray_to_tri_v3_fast(
- ray_start, ray_normal, t0, t2, t3, co, &depth_test)) < *dist_sq)) {
+ if ((dist_sq_test = dist_squared_ray_to_tri_v3_fast(
+ ray_start, ray_normal, t0, t2, t3, co, &depth_test)) < *dist_sq) {
*dist_sq = dist_sq_test;
*depth = depth_test;
}
@@ -2258,8 +2407,8 @@ bool ray_face_nearest_tri(const float ray_start[3],
float dist_sq_test;
float co[3], depth_test;
- if (((dist_sq_test = dist_squared_ray_to_tri_v3_fast(
- ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq)) {
+ if ((dist_sq_test = dist_squared_ray_to_tri_v3_fast(
+ ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq) {
*dist_sq = dist_sq_test;
*depth = depth_test;
return true;
@@ -2829,6 +2978,8 @@ void BKE_pbvh_face_sets_color_set(PBVH *pbvh, int seed, int color_default)
typedef struct PBVHDrawSearchData {
PBVHFrustumPlanes *frustum;
int accum_update_flag;
+ PBVHAttrReq *attrs;
+ int attrs_num;
} PBVHDrawSearchData;
static bool pbvh_draw_search_cb(PBVHNode *node, void *data_v)
@@ -2846,9 +2997,11 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
bool update_only_visible,
PBVHFrustumPlanes *update_frustum,
PBVHFrustumPlanes *draw_frustum,
- void (*draw_fn)(void *user_data, GPU_PBVH_Buffers *buffers),
+ void (*draw_fn)(void *user_data, PBVHBatches *batches, PBVH_GPU_Args *args),
void *user_data,
- bool UNUSED(full_render))
+ bool UNUSED(full_render),
+ PBVHAttrReq *attrs,
+ int attrs_num)
{
PBVHNode **nodes;
int totnode;
@@ -2859,7 +3012,8 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
/* Search for nodes that need updates. */
if (update_only_visible) {
/* Get visible nodes with draw updates. */
- PBVHDrawSearchData data = {.frustum = update_frustum, .accum_update_flag = 0};
+ PBVHDrawSearchData data = {
+ .frustum = update_frustum, .accum_update_flag = 0, attrs, attrs_num};
BKE_pbvh_search_gather(pbvh, pbvh_draw_search_cb, &data, &nodes, &totnode);
update_flag = data.accum_update_flag;
}
@@ -2871,8 +3025,6 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
update_flag = PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers;
}
- pbvh_check_draw_layout(pbvh);
-
/* Update draw buffers. */
if (totnode != 0 && (update_flag & (PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers))) {
pbvh_update_draw_buffers(pbvh, nodes, totnode, update_flag);
@@ -2883,10 +3035,14 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
PBVHDrawSearchData draw_data = {.frustum = draw_frustum, .accum_update_flag = 0};
BKE_pbvh_search_gather(pbvh, pbvh_draw_search_cb, &draw_data, &nodes, &totnode);
+ PBVH_GPU_Args args;
+
for (int i = 0; i < totnode; i++) {
PBVHNode *node = nodes[i];
if (!(node->flag & PBVH_FullyHidden)) {
- draw_fn(user_data, node->draw_buffers);
+ pbvh_draw_args_init(pbvh, &args, node);
+
+ draw_fn(user_data, node->draw_batches, &args);
}
}
@@ -2908,9 +3064,14 @@ void BKE_pbvh_draw_debug_cb(PBVH *pbvh,
}
}
-void BKE_pbvh_grids_update(
- PBVH *pbvh, CCGElem **grids, void **gridfaces, DMFlagMat *flagmats, BLI_bitmap **grid_hidden)
+void BKE_pbvh_grids_update(PBVH *pbvh,
+ CCGElem **grids,
+ void **gridfaces,
+ DMFlagMat *flagmats,
+ BLI_bitmap **grid_hidden,
+ CCGKey *key)
{
+ pbvh->gridkey = *key;
pbvh->grids = grids;
pbvh->gridfaces = gridfaces;
@@ -3154,9 +3315,9 @@ bool pbvh_has_face_sets(PBVH *pbvh)
{
switch (pbvh->header.type) {
case PBVH_GRIDS:
- return (pbvh->pdata && CustomData_get_layer(pbvh->pdata, CD_SCULPT_FACE_SETS));
case PBVH_FACES:
- return (pbvh->pdata && CustomData_get_layer(pbvh->pdata, CD_SCULPT_FACE_SETS));
+ return pbvh->pdata &&
+ CustomData_get_layer_named(pbvh->pdata, CD_PROP_INT32, ".sculpt_face_set") != NULL;
case PBVH_BMESH:
return false;
}
@@ -3218,7 +3379,7 @@ const bool *BKE_pbvh_get_vert_hide(const PBVH *pbvh)
const bool *BKE_pbvh_get_poly_hide(const PBVH *pbvh)
{
- BLI_assert(pbvh->header.type == PBVH_FACES);
+ BLI_assert(ELEM(pbvh->header.type, PBVH_FACES, PBVH_GRIDS));
return pbvh->hide_poly;
}
@@ -3247,6 +3408,14 @@ void BKE_pbvh_face_sets_set(PBVH *pbvh, int *face_sets)
pbvh->face_sets = face_sets;
}
+void BKE_pbvh_update_hide_attributes_from_mesh(PBVH *pbvh)
+{
+ if (pbvh->header.type == PBVH_FACES) {
+ pbvh->hide_vert = CustomData_get_layer_named(&pbvh->mesh->vdata, CD_PROP_BOOL, ".hide_vert");
+ pbvh->hide_poly = CustomData_get_layer_named(&pbvh->mesh->pdata, CD_PROP_BOOL, ".hide_poly");
+ }
+}
+
void BKE_pbvh_respect_hide_set(PBVH *pbvh, bool respect_hide)
{
pbvh->respect_hide = respect_hide;
diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh.cc
index 70aeb10f087..03382de34db 100644
--- a/source/blender/blenkernel/intern/pbvh.cc
+++ b/source/blender/blenkernel/intern/pbvh.cc
@@ -29,8 +29,6 @@
#include "PIL_time.h"
-#include "GPU_buffers.h"
-
#include "bmesh.h"
#include "atomic_ops.h"
@@ -63,7 +61,7 @@ template<typename T> void to_float(const T &src, float dst[4]);
template<> void to_float(const MLoopCol &src, float dst[4])
{
- rgba_uchar_to_float(dst, reinterpret_cast<const unsigned char *>(&src));
+ rgba_uchar_to_float(dst, reinterpret_cast<const uchar *>(&src));
srgb_to_linearrgb_v3_v3(dst, dst);
}
template<> void to_float(const MPropCol &src, float dst[4])
@@ -78,7 +76,7 @@ template<> void from_float(const float src[4], MLoopCol &dst)
float temp[4];
linearrgb_to_srgb_v3_v3(temp, src);
temp[3] = src[3];
- rgba_float_to_uchar(reinterpret_cast<unsigned char *>(&dst), temp);
+ rgba_float_to_uchar(reinterpret_cast<uchar *>(&dst), temp);
}
template<> void from_float(const float src[4], MPropCol &dst)
{
@@ -112,7 +110,7 @@ static void pbvh_vertex_color_get(const PBVH &pbvh, PBVHVertRef vertex, float r_
}
if (count) {
- mul_v4_fl(r_color, 1.0f / (float)count);
+ mul_v4_fl(r_color, 1.0f / float(count));
}
}
else {
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index c4993684100..3b0f35263d3 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -17,7 +17,7 @@
#include "BKE_ccg.h"
#include "BKE_pbvh.h"
-#include "GPU_buffers.h"
+#include "DRW_pbvh.h"
#include "bmesh.h"
#include "pbvh_intern.h"
@@ -347,8 +347,8 @@ static void pbvh_bmesh_node_split(PBVH *pbvh, const BBC *bbc_array, int node_ind
n->bm_other_verts = NULL;
n->layer_disp = NULL;
- if (n->draw_buffers) {
- pbvh_free_draw_buffers(pbvh, n);
+ if (n->draw_batches) {
+ DRW_pbvh_node_free(n->draw_batches);
}
n->flag &= ~PBVH_Leaf;
@@ -493,7 +493,7 @@ static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
BLI_gset_insert(node->bm_unique_verts, v);
BM_ELEM_CD_SET_INT(v, pbvh->cd_vert_node_offset, node_index);
- node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
+ node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_TopologyUpdated;
/* Log the new vertex */
BM_log_vert_added(pbvh->bm_log, v, cd_vert_mask_offset);
@@ -519,7 +519,7 @@ static BMFace *pbvh_bmesh_face_create(
BM_ELEM_CD_SET_INT(f, pbvh->cd_face_node_offset, node_index);
/* mark node for update */
- node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals;
+ node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals | PBVH_TopologyUpdated;
node->flag &= ~PBVH_FullyHidden;
/* Log the new face */
@@ -594,7 +594,7 @@ static void pbvh_bmesh_vert_ownership_transfer(PBVH *pbvh, PBVHNode *new_owner,
{
PBVHNode *current_owner = pbvh_bmesh_node_from_vert(pbvh, v);
/* mark node for update */
- current_owner->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
+ current_owner->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_TopologyUpdated;
BLI_assert(current_owner != new_owner);
@@ -608,7 +608,7 @@ static void pbvh_bmesh_vert_ownership_transfer(PBVH *pbvh, PBVHNode *new_owner,
BLI_assert(!BLI_gset_haskey(new_owner->bm_other_verts, v));
/* mark node for update */
- new_owner->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
+ new_owner->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_TopologyUpdated;
}
static void pbvh_bmesh_vert_remove(PBVH *pbvh, BMVert *v)
@@ -631,7 +631,7 @@ static void pbvh_bmesh_vert_remove(PBVH *pbvh, BMVert *v)
f_node_index_prev = f_node_index;
PBVHNode *f_node = &pbvh->nodes[f_node_index];
- f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
+ f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_TopologyUpdated;
/* Remove current ownership */
BLI_gset_remove(f_node->bm_other_verts, v, NULL);
@@ -680,7 +680,7 @@ static void pbvh_bmesh_face_remove(PBVH *pbvh, BMFace *f)
BM_log_face_removed(pbvh->bm_log, f);
/* mark node for update */
- f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals;
+ f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals | PBVH_TopologyUpdated;
}
static void pbvh_bmesh_edge_loops(BLI_Buffer *buf, BMEdge *e)
@@ -701,14 +701,9 @@ static void pbvh_bmesh_edge_loops(BLI_Buffer *buf, BMEdge *e)
static void pbvh_bmesh_node_drop_orig(PBVHNode *node)
{
- if (node->bm_orco) {
- MEM_freeN(node->bm_orco);
- }
- if (node->bm_ortri) {
- MEM_freeN(node->bm_ortri);
- }
- node->bm_orco = NULL;
- node->bm_ortri = NULL;
+ MEM_SAFE_FREE(node->bm_orco);
+ MEM_SAFE_FREE(node->bm_ortri);
+ MEM_SAFE_FREE(node->bm_orvert);
node->bm_tot_ortri = 0;
}
@@ -730,7 +725,7 @@ typedef struct EdgeQueue {
const float *view_normal;
#ifdef USE_EDGEQUEUE_FRONTFACE
- unsigned int use_view_normal : 1;
+ uint use_view_normal : 1;
#endif
} EdgeQueue;
@@ -883,7 +878,7 @@ static void long_edge_queue_edge_add_recursive(
return;
}
- if ((l_edge->radial_next != l_edge)) {
+ if (l_edge->radial_next != l_edge) {
/* How much longer we need to be to consider for subdividing
* (avoids subdividing faces which are only *slightly* skinny) */
# define EVEN_EDGELEN_THRESHOLD 1.2f
@@ -1507,29 +1502,51 @@ bool pbvh_bmesh_node_raycast(PBVHNode *node,
bool hit = false;
float nearest_vertex_co[3] = {0.0f};
+ BLI_assert(!use_original || (BLI_gset_len(node->bm_faces) > 0 && node->bm_tot_ortri));
+
+ use_original = use_original && node->bm_tot_ortri;
+
+ GSetIterator gs_iter;
+
if (use_original && node->bm_tot_ortri) {
for (int i = 0; i < node->bm_tot_ortri; i++) {
- const int *t = node->bm_ortri[i];
- hit |= ray_face_intersection_tri(ray_start,
- isect_precalc,
- node->bm_orco[t[0]],
- node->bm_orco[t[1]],
- node->bm_orco[t[2]],
- depth);
+ float *cos[3];
+
+ cos[0] = node->bm_orco[node->bm_ortri[i][0]];
+ cos[1] = node->bm_orco[node->bm_ortri[i][1]];
+ cos[2] = node->bm_orco[node->bm_ortri[i][2]];
+
+ if (ray_face_intersection_tri(ray_start, isect_precalc, cos[0], cos[1], cos[2], depth)) {
+ hit = true;
+
+ if (r_face_normal) {
+ normal_tri_v3(r_face_normal, cos[0], cos[1], cos[2]);
+ }
+
+ if (r_active_vertex) {
+ float location[3] = {0.0f};
+ madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
+ for (int j = 0; j < 3; j++) {
+ if (len_squared_v3v3(location, cos[j]) <
+ len_squared_v3v3(location, nearest_vertex_co)) {
+ copy_v3_v3(nearest_vertex_co, cos[j]);
+ r_active_vertex->i = (intptr_t)node->bm_orvert[node->bm_ortri[i][j]];
+ }
+ }
+ }
+ }
}
}
else {
- GSetIterator gs_iter;
-
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];
BM_face_as_array_vert_tri(f, v_tri);
-
if (ray_face_intersection_tri(
ray_start, isect_precalc, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co, depth)) {
hit = true;
@@ -1863,6 +1880,12 @@ static void pbvh_bmesh_create_nodes_fast_recursive(
/***************************** Public API *****************************/
+void BKE_pbvh_update_bmesh_offsets(PBVH *pbvh, int cd_vert_node_offset, int cd_face_node_offset)
+{
+ pbvh->cd_vert_node_offset = cd_vert_node_offset;
+ pbvh->cd_face_node_offset = cd_face_node_offset;
+}
+
void BKE_pbvh_build_bmesh(PBVH *pbvh,
BMesh *bm,
bool smooth_shading,
@@ -1870,8 +1893,6 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
const int cd_vert_node_offset,
const int cd_face_node_offset)
{
- pbvh->cd_vert_node_offset = cd_vert_node_offset;
- pbvh->cd_face_node_offset = cd_face_node_offset;
pbvh->header.bm = bm;
BKE_pbvh_bmesh_detail_size_set(pbvh, 0.75);
@@ -1880,7 +1901,9 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
pbvh->bm_log = log;
/* TODO: choose leaf limit better */
- pbvh->leaf_limit = 100;
+ pbvh->leaf_limit = 400;
+
+ BKE_pbvh_update_bmesh_offsets(pbvh, cd_vert_node_offset, cd_face_node_offset);
if (smooth_shading) {
pbvh->flags |= PBVH_DYNTOPO_SMOOTH_SHADING;
@@ -1999,7 +2022,7 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
BLI_mempool_destroy(queue_pool);
}
- /* Unmark nodes */
+ /* Unmark nodes. */
for (int n = 0; n < pbvh->totnode; n++) {
PBVHNode *node = &pbvh->nodes[n];
@@ -2010,6 +2033,21 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
BLI_buffer_free(&edge_loops);
BLI_buffer_free(&deleted_faces);
+ /* Go over all changed nodes and check if anything needs to be updated. */
+ for (int n = 0; n < pbvh->totnode; n++) {
+ PBVHNode *node = &pbvh->nodes[n];
+
+ if (node->flag & PBVH_Leaf && node->flag & PBVH_TopologyUpdated) {
+ node->flag &= ~PBVH_TopologyUpdated;
+
+ if (node->bm_ortri) {
+ /* Reallocate original triangle data. */
+ pbvh_bmesh_node_drop_orig(node);
+ BKE_pbvh_bmesh_node_save_orig(pbvh->header.bm, pbvh->bm_log, node, true);
+ }
+ }
+ }
+
#ifdef USE_VERIFY
pbvh_bmesh_verify(pbvh);
#endif
@@ -2017,7 +2055,7 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
return modified;
}
-void BKE_pbvh_bmesh_node_save_orig(BMesh *bm, PBVHNode *node)
+void BKE_pbvh_bmesh_node_save_orig(BMesh *bm, BMLog *log, PBVHNode *node, bool use_original)
{
/* Skip if original coords/triangles are already saved */
if (node->bm_orco) {
@@ -2030,19 +2068,38 @@ void BKE_pbvh_bmesh_node_save_orig(BMesh *bm, PBVHNode *node)
node->bm_orco = MEM_mallocN(sizeof(*node->bm_orco) * totvert, __func__);
node->bm_ortri = MEM_mallocN(sizeof(*node->bm_ortri) * tottri, __func__);
+ node->bm_orvert = MEM_mallocN(sizeof(*node->bm_orvert) * totvert, __func__);
/* Copy out the vertices and assign a temporary index */
int i = 0;
GSetIterator gs_iter;
GSET_ITER (gs_iter, node->bm_unique_verts) {
BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
- copy_v3_v3(node->bm_orco[i], v->co);
+ const float *origco = BM_log_original_vert_co(log, v);
+
+ if (use_original && origco) {
+ copy_v3_v3(node->bm_orco[i], origco);
+ }
+ else {
+ copy_v3_v3(node->bm_orco[i], v->co);
+ }
+
+ node->bm_orvert[i] = v;
BM_elem_index_set(v, i); /* set_dirty! */
i++;
}
GSET_ITER (gs_iter, node->bm_other_verts) {
BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
- copy_v3_v3(node->bm_orco[i], v->co);
+ const float *origco = BM_log_original_vert_co(log, v);
+
+ if (use_original && origco) {
+ copy_v3_v3(node->bm_orco[i], BM_log_original_vert_co(log, v));
+ }
+ else {
+ copy_v3_v3(node->bm_orco[i], v->co);
+ }
+
+ node->bm_orvert[i] = v;
BM_elem_index_set(v, i); /* set_dirty! */
i++;
}
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index 8ab56839f9c..368a9ffa1ea 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -33,7 +33,7 @@ struct MeshElemMap;
* union'd structs */
struct PBVHNode {
/* Opaque handle for drawing code */
- struct GPU_PBVH_Buffers *draw_buffers;
+ struct PBVHBatches *draw_batches;
/* Voxel bounds */
BB vb;
@@ -96,7 +96,7 @@ struct PBVHNode {
/* Indicates whether this node is a leaf or not; also used for
* marking various updates that need to be applied. */
- PBVHNodeFlags flag : 16;
+ PBVHNodeFlags flag : 32;
/* Used for raycasting: how close bb is to the ray point. */
float tmin;
@@ -116,8 +116,11 @@ struct PBVHNode {
GSet *bm_faces;
GSet *bm_unique_verts;
GSet *bm_other_verts;
+
+ /* Deprecated. Stores original coordinates of triangles. */
float (*bm_orco)[3];
int (*bm_ortri)[3];
+ BMVert **bm_orvert;
int bm_tot_ortri;
/* Used to store the brush color during a stroke and composite it over the original color */
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index f733f3145ec..df616d4e087 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -114,7 +114,7 @@ struct EncodePixelsUserData {
static void do_encode_pixels(void *__restrict userdata,
const int n,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
EncodePixelsUserData *data = static_cast<EncodePixelsUserData *>(userdata);
Image *image = data->image;
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index ce04d781980..5622530ea41 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -103,14 +103,14 @@
static CLG_LogRef LOG = {"bke.pointcache"};
static int ptcache_data_size[] = {
- sizeof(unsigned int), /* BPHYS_DATA_INDEX */
- sizeof(float[3]), /* BPHYS_DATA_LOCATION */
- sizeof(float[3]), /* BPHYS_DATA_VELOCITY */
- sizeof(float[4]), /* BPHYS_DATA_ROTATION */
- sizeof(float[3]), /* BPHYS_DATA_AVELOCITY / BPHYS_DATA_XCONST */
- sizeof(float), /* BPHYS_DATA_SIZE */
- sizeof(float[3]), /* BPHYS_DATA_TIMES */
- sizeof(BoidData), /* case BPHYS_DATA_BOIDS */
+ sizeof(uint), /* BPHYS_DATA_INDEX */
+ sizeof(float[3]), /* BPHYS_DATA_LOCATION */
+ sizeof(float[3]), /* BPHYS_DATA_VELOCITY */
+ sizeof(float[4]), /* BPHYS_DATA_ROTATION */
+ sizeof(float[3]), /* BPHYS_DATA_AVELOCITY / BPHYS_DATA_XCONST */
+ sizeof(float), /* BPHYS_DATA_SIZE */
+ sizeof(float[3]), /* BPHYS_DATA_TIMES */
+ sizeof(BoidData), /* case BPHYS_DATA_BOIDS */
};
static int ptcache_extra_datasize[] = {
@@ -120,11 +120,11 @@ static int ptcache_extra_datasize[] = {
};
/* forward declarations */
-static int ptcache_file_compressed_read(PTCacheFile *pf, unsigned char *result, unsigned int len);
+static int ptcache_file_compressed_read(PTCacheFile *pf, uchar *result, uint len);
static int ptcache_file_compressed_write(
- PTCacheFile *pf, unsigned char *in, unsigned int in_len, unsigned char *out, int mode);
-static int ptcache_file_write(PTCacheFile *pf, const void *f, unsigned int tot, unsigned int size);
-static int ptcache_file_read(PTCacheFile *pf, void *f, unsigned int tot, unsigned int size);
+ PTCacheFile *pf, uchar *in, uint in_len, uchar *out, int mode);
+static int ptcache_file_write(PTCacheFile *pf, const void *f, uint tot, uint size);
+static int ptcache_file_read(PTCacheFile *pf, void *f, uint tot, uint size);
/* Common functions */
static int ptcache_basic_header_read(PTCacheFile *pf)
@@ -132,11 +132,11 @@ static int ptcache_basic_header_read(PTCacheFile *pf)
int error = 0;
/* Custom functions should read these basic elements too! */
- if (!error && !fread(&pf->totpoint, sizeof(unsigned int), 1, pf->fp)) {
+ if (!error && !fread(&pf->totpoint, sizeof(uint), 1, pf->fp)) {
error = 1;
}
- if (!error && !fread(&pf->data_types, sizeof(unsigned int), 1, pf->fp)) {
+ if (!error && !fread(&pf->data_types, sizeof(uint), 1, pf->fp)) {
error = 1;
}
@@ -145,20 +145,17 @@ static int ptcache_basic_header_read(PTCacheFile *pf)
static int ptcache_basic_header_write(PTCacheFile *pf)
{
/* Custom functions should write these basic elements too! */
- if (!fwrite(&pf->totpoint, sizeof(unsigned int), 1, pf->fp)) {
+ if (!fwrite(&pf->totpoint, sizeof(uint), 1, pf->fp)) {
return 0;
}
- if (!fwrite(&pf->data_types, sizeof(unsigned int), 1, pf->fp)) {
+ if (!fwrite(&pf->data_types, sizeof(uint), 1, pf->fp)) {
return 0;
}
return 1;
}
-static void ptcache_add_extra_data(PTCacheMem *pm,
- unsigned int type,
- unsigned int count,
- void *data)
+static void ptcache_add_extra_data(PTCacheMem *pm, uint type, uint count, void *data)
{
PTCacheExtra *extra = MEM_callocN(sizeof(PTCacheExtra), "Point cache: extra data descriptor");
@@ -683,8 +680,8 @@ static int ptcache_dynamicpaint_write(PTCacheFile *pf, void *dp_v)
if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) {
int total_points = surface->data->total_points;
- unsigned int in_len;
- unsigned char *out;
+ uint in_len;
+ uchar *out;
/* cache type */
ptcache_file_write(pf, &surface->type, 1, sizeof(int));
@@ -702,10 +699,10 @@ static int ptcache_dynamicpaint_write(PTCacheFile *pf, void *dp_v)
return 0;
}
- out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len), "pointcache_lzo_buffer");
+ out = (uchar *)MEM_callocN(LZO_OUT_LEN(in_len), "pointcache_lzo_buffer");
ptcache_file_compressed_write(
- pf, (unsigned char *)surface->data->type_data, in_len, out, cache_compress);
+ pf, (uchar *)surface->data->type_data, in_len, out, cache_compress);
MEM_freeN(out);
}
return 1;
@@ -723,7 +720,7 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v)
}
if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) {
- unsigned int data_len;
+ uint data_len;
int surface_type;
/* cache type */
@@ -748,7 +745,7 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v)
}
ptcache_file_compressed_read(
- pf, (unsigned char *)surface->data->type_data, data_len * surface->data->total_points);
+ pf, (uchar *)surface->data->type_data, data_len * surface->data->total_points);
}
return 1;
}
@@ -1320,7 +1317,7 @@ static int ptcache_path(PTCacheID *pid, char *dirname)
BLI_path_abs(dirname, blendfilename);
}
- return BLI_path_slash_ensure(dirname); /* new strlen() */
+ return BLI_path_slash_ensure(dirname, MAX_PTCACHE_FILE); /* new strlen() */
}
if ((blendfile_path[0] != '\0') || lib) {
char file[MAX_PTCACHE_PATH]; /* we don't want the dir, only the file */
@@ -1337,14 +1334,14 @@ static int ptcache_path(PTCacheID *pid, char *dirname)
BLI_snprintf(dirname, MAX_PTCACHE_PATH, "//" PTCACHE_PATH "%s", file);
BLI_path_abs(dirname, blendfilename);
- return BLI_path_slash_ensure(dirname); /* new strlen() */
+ return BLI_path_slash_ensure(dirname, MAX_PTCACHE_FILE); /* new strlen() */
}
/* use the temp path. this is weak but better than not using point cache at all */
/* temporary directory is assumed to exist and ALWAYS has a trailing slash */
BLI_snprintf(dirname, MAX_PTCACHE_PATH, "%s" PTCACHE_PATH, BKE_tempdir_session());
- return BLI_path_slash_ensure(dirname); /* new strlen() */
+ return BLI_path_slash_ensure(dirname, MAX_PTCACHE_FILE); /* new strlen() */
}
static size_t ptcache_filepath_ext_append(PTCacheID *pid,
@@ -1424,7 +1421,7 @@ static int ptcache_filepath(
idname = (pid->owner_id->name + 2);
/* convert chars to hex so they are always a valid filename */
while ('\0' != *idname) {
- BLI_snprintf(newname, MAX_PTCACHE_FILE - len, "%02X", (unsigned int)(*idname++));
+ BLI_snprintf(newname, MAX_PTCACHE_FILE - len, "%02X", (uint)(*idname++));
newname += 2;
len += 2;
}
@@ -1500,29 +1497,28 @@ static void ptcache_file_close(PTCacheFile *pf)
}
}
-static int ptcache_file_compressed_read(PTCacheFile *pf, unsigned char *result, unsigned int len)
+static int ptcache_file_compressed_read(PTCacheFile *pf, uchar *result, uint len)
{
int r = 0;
- unsigned char compressed = 0;
+ uchar compressed = 0;
size_t in_len;
#ifdef WITH_LZO
size_t out_len = len;
#endif
- unsigned char *in;
- unsigned char *props = MEM_callocN(sizeof(char[16]), "tmp");
+ uchar *in;
+ uchar *props = MEM_callocN(sizeof(char[16]), "tmp");
- ptcache_file_read(pf, &compressed, 1, sizeof(unsigned char));
+ ptcache_file_read(pf, &compressed, 1, sizeof(uchar));
if (compressed) {
- unsigned int size;
- ptcache_file_read(pf, &size, 1, sizeof(unsigned int));
+ uint size;
+ ptcache_file_read(pf, &size, 1, sizeof(uint));
in_len = (size_t)size;
if (in_len == 0) {
/* do nothing */
}
else {
- in = (unsigned char *)MEM_callocN(sizeof(unsigned char) * in_len,
- "pointcache_compressed_buffer");
- ptcache_file_read(pf, in, in_len, sizeof(unsigned char));
+ in = (uchar *)MEM_callocN(sizeof(uchar) * in_len, "pointcache_compressed_buffer");
+ ptcache_file_read(pf, in, in_len, sizeof(uchar));
#ifdef WITH_LZO
if (compressed == 1) {
r = lzo1x_decompress_safe(in, (lzo_uint)in_len, result, (lzo_uint *)&out_len, NULL);
@@ -1532,9 +1528,9 @@ static int ptcache_file_compressed_read(PTCacheFile *pf, unsigned char *result,
if (compressed == 2) {
size_t sizeOfIt;
size_t leni = in_len, leno = len;
- ptcache_file_read(pf, &size, 1, sizeof(unsigned int));
+ ptcache_file_read(pf, &size, 1, sizeof(uint));
sizeOfIt = (size_t)size;
- ptcache_file_read(pf, props, sizeOfIt, sizeof(unsigned char));
+ ptcache_file_read(pf, props, sizeOfIt, sizeof(uchar));
r = LzmaUncompress(result, &leno, in, &leni, props, sizeOfIt);
}
#endif
@@ -1542,7 +1538,7 @@ static int ptcache_file_compressed_read(PTCacheFile *pf, unsigned char *result,
}
}
else {
- ptcache_file_read(pf, result, len, sizeof(unsigned char));
+ ptcache_file_read(pf, result, len, sizeof(uchar));
}
MEM_freeN(props);
@@ -1550,12 +1546,12 @@ static int ptcache_file_compressed_read(PTCacheFile *pf, unsigned char *result,
return r;
}
static int ptcache_file_compressed_write(
- PTCacheFile *pf, unsigned char *in, unsigned int in_len, unsigned char *out, int mode)
+ PTCacheFile *pf, uchar *in, uint in_len, uchar *out, int mode)
{
int r = 0;
- unsigned char compressed = 0;
+ uchar compressed = 0;
size_t out_len = 0;
- unsigned char *props = MEM_callocN(sizeof(char[16]), "tmp");
+ uchar *props = MEM_callocN(sizeof(char[16]), "tmp");
size_t sizeOfIt = 5;
(void)mode; /* unused when building w/o compression */
@@ -1600,31 +1596,31 @@ static int ptcache_file_compressed_write(
}
#endif
- ptcache_file_write(pf, &compressed, 1, sizeof(unsigned char));
+ ptcache_file_write(pf, &compressed, 1, sizeof(uchar));
if (compressed) {
- unsigned int size = out_len;
- ptcache_file_write(pf, &size, 1, sizeof(unsigned int));
- ptcache_file_write(pf, out, out_len, sizeof(unsigned char));
+ uint size = out_len;
+ ptcache_file_write(pf, &size, 1, sizeof(uint));
+ ptcache_file_write(pf, out, out_len, sizeof(uchar));
}
else {
- ptcache_file_write(pf, in, in_len, sizeof(unsigned char));
+ ptcache_file_write(pf, in, in_len, sizeof(uchar));
}
if (compressed == 2) {
- unsigned int size = sizeOfIt;
- ptcache_file_write(pf, &sizeOfIt, 1, sizeof(unsigned int));
- ptcache_file_write(pf, props, size, sizeof(unsigned char));
+ uint size = sizeOfIt;
+ ptcache_file_write(pf, &sizeOfIt, 1, sizeof(uint));
+ ptcache_file_write(pf, props, size, sizeof(uchar));
}
MEM_freeN(props);
return r;
}
-static int ptcache_file_read(PTCacheFile *pf, void *f, unsigned int tot, unsigned int size)
+static int ptcache_file_read(PTCacheFile *pf, void *f, uint tot, uint size)
{
return (fread(f, size, tot, pf->fp) == tot);
}
-static int ptcache_file_write(PTCacheFile *pf, const void *f, unsigned int tot, unsigned int size)
+static int ptcache_file_write(PTCacheFile *pf, const void *f, uint tot, uint size)
{
return (fwrite(f, size, tot, pf->fp) == tot);
}
@@ -1656,7 +1652,7 @@ static int ptcache_file_data_write(PTCacheFile *pf)
}
static int ptcache_file_header_begin_read(PTCacheFile *pf)
{
- unsigned int typeflag = 0;
+ uint typeflag = 0;
int error = 0;
char bphysics[8];
@@ -1670,7 +1666,7 @@ static int ptcache_file_header_begin_read(PTCacheFile *pf)
error = 1;
}
- if (!error && !fread(&typeflag, sizeof(unsigned int), 1, pf->fp)) {
+ if (!error && !fread(&typeflag, sizeof(uint), 1, pf->fp)) {
error = 1;
}
@@ -1687,13 +1683,13 @@ static int ptcache_file_header_begin_read(PTCacheFile *pf)
static int ptcache_file_header_begin_write(PTCacheFile *pf)
{
const char *bphysics = "BPHYSICS";
- unsigned int typeflag = pf->type + pf->flag;
+ uint typeflag = pf->type + pf->flag;
if (fwrite(bphysics, sizeof(char), 8, pf->fp) != 8) {
return 0;
}
- if (!fwrite(&typeflag, sizeof(unsigned int), 1, pf->fp)) {
+ if (!fwrite(&typeflag, sizeof(uint), 1, pf->fp)) {
return 0;
}
@@ -1722,11 +1718,11 @@ static void ptcache_file_pointers_init(PTCacheFile *pf)
pf->cur[BPHYS_DATA_BOIDS] = (data_types & (1 << BPHYS_DATA_BOIDS)) ? &pf->data.boids : NULL;
}
-int BKE_ptcache_mem_index_find(PTCacheMem *pm, unsigned int index)
+int BKE_ptcache_mem_index_find(PTCacheMem *pm, uint index)
{
if (pm->totpoint > 0 && pm->data[BPHYS_DATA_INDEX]) {
- unsigned int *data = pm->data[BPHYS_DATA_INDEX];
- unsigned int mid, low = 0, high = pm->totpoint - 1;
+ uint *data = pm->data[BPHYS_DATA_INDEX];
+ uint mid, low = 0, high = pm->totpoint - 1;
if (index < *data || index > *(data + high)) {
return -1;
@@ -1868,7 +1864,7 @@ static int ptcache_old_elemsize(PTCacheID *pid)
return 0;
}
-static void ptcache_find_frames_around(PTCacheID *pid, unsigned int frame, int *fra1, int *fra2)
+static void ptcache_find_frames_around(PTCacheID *pid, uint frame, int *fra1, int *fra2)
{
if (pid->cache->flag & PTCACHE_DISK_CACHE) {
int cfra1 = frame, cfra2 = frame + 1;
@@ -1930,7 +1926,7 @@ static PTCacheMem *ptcache_disk_frame_to_mem(PTCacheID *pid, int cfra)
{
PTCacheFile *pf = ptcache_file_open(pid, PTCACHE_FILE_READ, cfra);
PTCacheMem *pm = NULL;
- unsigned int i, error = 0;
+ uint i, error = 0;
if (pf == NULL) {
return NULL;
@@ -1955,9 +1951,9 @@ static PTCacheMem *ptcache_disk_frame_to_mem(PTCacheID *pid, int cfra)
if (pf->flag & PTCACHE_TYPEFLAG_COMPRESS) {
for (i = 0; i < BPHYS_TOT_DATA; i++) {
- unsigned int out_len = pm->totpoint * ptcache_data_size[i];
+ uint out_len = pm->totpoint * ptcache_data_size[i];
if (pf->data_types & (1 << i)) {
- ptcache_file_compressed_read(pf, (unsigned char *)(pm->data[i]), out_len);
+ ptcache_file_compressed_read(pf, (uchar *)(pm->data[i]), out_len);
}
}
}
@@ -1978,22 +1974,21 @@ static PTCacheMem *ptcache_disk_frame_to_mem(PTCacheID *pid, int cfra)
}
if (!error && pf->flag & PTCACHE_TYPEFLAG_EXTRADATA) {
- unsigned int extratype = 0;
+ uint extratype = 0;
- while (ptcache_file_read(pf, &extratype, 1, sizeof(unsigned int))) {
+ while (ptcache_file_read(pf, &extratype, 1, sizeof(uint))) {
PTCacheExtra *extra = MEM_callocN(sizeof(PTCacheExtra), "Pointcache extradata");
extra->type = extratype;
- ptcache_file_read(pf, &extra->totdata, 1, sizeof(unsigned int));
+ ptcache_file_read(pf, &extra->totdata, 1, sizeof(uint));
extra->data = MEM_callocN(extra->totdata * ptcache_extra_datasize[extra->type],
"Pointcache extradata->data");
if (pf->flag & PTCACHE_TYPEFLAG_COMPRESS) {
- ptcache_file_compressed_read(pf,
- (unsigned char *)(extra->data),
- extra->totdata * ptcache_extra_datasize[extra->type]);
+ ptcache_file_compressed_read(
+ pf, (uchar *)(extra->data), extra->totdata * ptcache_extra_datasize[extra->type]);
}
else {
ptcache_file_read(pf, extra->data, extra->totdata, ptcache_extra_datasize[extra->type]);
@@ -2020,7 +2015,7 @@ static PTCacheMem *ptcache_disk_frame_to_mem(PTCacheID *pid, int cfra)
static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm)
{
PTCacheFile *pf = NULL;
- unsigned int i, error = 0;
+ uint i, error = 0;
BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_FRAME, pm->frame);
@@ -2054,11 +2049,10 @@ static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm)
if (pid->cache->compression) {
for (i = 0; i < BPHYS_TOT_DATA; i++) {
if (pm->data[i]) {
- unsigned int in_len = pm->totpoint * ptcache_data_size[i];
- unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len) * 4,
- "pointcache_lzo_buffer");
+ uint in_len = pm->totpoint * ptcache_data_size[i];
+ uchar *out = (uchar *)MEM_callocN(LZO_OUT_LEN(in_len) * 4, "pointcache_lzo_buffer");
ptcache_file_compressed_write(
- pf, (unsigned char *)(pm->data[i]), in_len, out, pid->cache->compression);
+ pf, (uchar *)(pm->data[i]), in_len, out, pid->cache->compression);
MEM_freeN(out);
}
}
@@ -2087,15 +2081,14 @@ static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm)
continue;
}
- ptcache_file_write(pf, &extra->type, 1, sizeof(unsigned int));
- ptcache_file_write(pf, &extra->totdata, 1, sizeof(unsigned int));
+ ptcache_file_write(pf, &extra->type, 1, sizeof(uint));
+ ptcache_file_write(pf, &extra->totdata, 1, sizeof(uint));
if (pid->cache->compression) {
- unsigned int in_len = extra->totdata * ptcache_extra_datasize[extra->type];
- unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len) * 4,
- "pointcache_lzo_buffer");
+ uint in_len = extra->totdata * ptcache_extra_datasize[extra->type];
+ uchar *out = (uchar *)MEM_callocN(LZO_OUT_LEN(in_len) * 4, "pointcache_lzo_buffer");
ptcache_file_compressed_write(
- pf, (unsigned char *)(extra->data), in_len, out, pid->cache->compression);
+ pf, (uchar *)(extra->data), in_len, out, pid->cache->compression);
MEM_freeN(out);
}
else {
@@ -2535,7 +2528,7 @@ static int ptcache_write_needed(PTCacheID *pid, int cfra, int *overwrite)
return 0;
}
-int BKE_ptcache_write(PTCacheID *pid, unsigned int cfra)
+int BKE_ptcache_write(PTCacheID *pid, uint cfra)
{
PointCache *cache = pid->cache;
if (!pid->totpoint) {
@@ -2587,10 +2580,10 @@ int BKE_ptcache_write(PTCacheID *pid, unsigned int cfra)
/* Clears & resets. */
-void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
+void BKE_ptcache_id_clear(PTCacheID *pid, int mode, uint cfra)
{
- unsigned int len; /* store the length of the string */
- unsigned int sta, end;
+ uint len; /* store the length of the string */
+ uint sta, end;
/* mode is same as fopen's modes */
DIR *dir;
@@ -2618,7 +2611,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
}
#endif
- /* clear all files in the temp dir with the prefix of the ID and the ".bphys" suffix */
+ /* Clear all files in the temp dir with the prefix of the ID and the `.bphys` suffix. */
switch (mode) {
case PTCACHE_CLEAR_ALL:
case PTCACHE_CLEAR_BEFORE:
@@ -2647,7 +2640,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
if (STREQLEN(filepath, de->d_name, len)) { /* Do we have the right prefix. */
if (mode == PTCACHE_CLEAR_ALL) {
pid->cache->last_exact = MIN2(pid->cache->startframe, 0);
- BLI_join_dirfile(path_full, sizeof(path_full), path, de->d_name);
+ BLI_path_join(path_full, sizeof(path_full), path, de->d_name);
BLI_delete(path_full, false, false);
}
else {
@@ -2657,7 +2650,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
if (frame != -1) {
if ((mode == PTCACHE_CLEAR_BEFORE && frame < cfra) ||
(mode == PTCACHE_CLEAR_AFTER && frame > cfra)) {
- BLI_join_dirfile(path_full, sizeof(path_full), path, de->d_name);
+ BLI_path_join(path_full, sizeof(path_full), path, de->d_name);
BLI_delete(path_full, false, false);
if (pid->cache->cached_frames && frame >= sta && frame <= end) {
pid->cache->cached_frames[frame - sta] = 0;
@@ -2782,7 +2775,7 @@ void BKE_ptcache_id_time(
/* time handling for point cache:
* - simulation time is scaled by result of bsystem_time
* - for offsetting time only time offset is taken into account, since
- * that's always the same and can't be animated. a timeoffset which
+ * that's always the same and can't be animated. a time-offset which
* varies over time is not simple to support.
* - field and motion blur offsets are currently ignored, proper solution
* is probably to interpolate results from two frames for that ..
@@ -2812,8 +2805,8 @@ void BKE_ptcache_id_time(
}
if (cache->cached_frames == NULL && cache->endframe > cache->startframe) {
- unsigned int sta = cache->startframe;
- unsigned int end = cache->endframe;
+ uint sta = cache->startframe;
+ uint end = cache->endframe;
cache->cached_frames_len = cache->endframe - cache->startframe + 1;
cache->cached_frames = MEM_callocN(sizeof(char) * cache->cached_frames_len,
@@ -2826,7 +2819,7 @@ void BKE_ptcache_id_time(
char path[MAX_PTCACHE_PATH];
char filepath[MAX_PTCACHE_FILE];
char ext[MAX_PTCACHE_PATH];
- unsigned int len; /* store the length of the string */
+ uint len; /* store the length of the string */
ptcache_path(pid, path);
@@ -3139,15 +3132,15 @@ static void ptcache_dt_to_str(char *str, double dtime)
{
if (dtime > 60.0) {
if (dtime > 3600.0) {
- sprintf(
+ BLI_sprintf(
str, "%ih %im %is", (int)(dtime / 3600), ((int)(dtime / 60)) % 60, ((int)dtime) % 60);
}
else {
- sprintf(str, "%im %is", ((int)(dtime / 60)) % 60, ((int)dtime) % 60);
+ BLI_sprintf(str, "%im %is", ((int)(dtime / 60)) % 60, ((int)dtime) % 60);
}
}
else {
- sprintf(str, "%is", ((int)dtime) % 60);
+ BLI_sprintf(str, "%is", ((int)dtime) % 60);
}
}
@@ -3531,7 +3524,7 @@ void BKE_ptcache_disk_cache_rename(PTCacheID *pid, const char *name_src, const c
const int frame = ptcache_frame_from_filename(de->d_name, ext);
if (frame != -1) {
- BLI_join_dirfile(old_path_full, sizeof(old_path_full), path, de->d_name);
+ BLI_path_join(old_path_full, sizeof(old_path_full), path, de->d_name);
ptcache_filepath(pid, new_path_full, frame, true, true);
BLI_rename(old_path_full, new_path_full);
}
diff --git a/source/blender/blenkernel/intern/pointcloud.cc b/source/blender/blenkernel/intern/pointcloud.cc
index b45e164b594..119daccce20 100644
--- a/source/blender/blenkernel/intern/pointcloud.cc
+++ b/source/blender/blenkernel/intern/pointcloud.cc
@@ -70,7 +70,7 @@ static void pointcloud_init_data(ID *id)
POINTCLOUD_ATTR_POSITION);
}
-static void pointcloud_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
+static void pointcloud_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int flag)
{
PointCloud *pointcloud_dst = (PointCloud *)id_dst;
const PointCloud *pointcloud_src = (const PointCloud *)id_src;
@@ -239,12 +239,6 @@ PointCloud *BKE_pointcloud_new_nomain(const int totpoint)
nullptr, ID_PT, BKE_idtype_idcode_to_name(ID_PT), LIB_ID_CREATE_LOCALIZE));
pointcloud_init_data(&pointcloud->id);
- CustomData_add_layer_named(&pointcloud->pdata,
- CD_PROP_FLOAT,
- CD_SET_DEFAULT,
- nullptr,
- pointcloud->totpoint,
- POINTCLOUD_ATTR_RADIUS);
CustomData_realloc(&pointcloud->pdata, 0, totpoint);
pointcloud->totpoint = totpoint;
@@ -252,6 +246,37 @@ PointCloud *BKE_pointcloud_new_nomain(const int totpoint)
return pointcloud;
}
+void BKE_pointcloud_nomain_to_pointcloud(PointCloud *pointcloud_src,
+ PointCloud *pointcloud_dst,
+ bool take_ownership)
+{
+ BLI_assert(pointcloud_src->id.tag & LIB_TAG_NO_MAIN);
+
+ eCDAllocType alloctype = CD_DUPLICATE;
+
+ if (take_ownership) {
+ bool has_any_referenced_layers = CustomData_has_referenced(&pointcloud_src->pdata);
+
+ if (!has_any_referenced_layers) {
+ alloctype = CD_ASSIGN;
+ }
+ }
+
+ CustomData_free(&pointcloud_dst->pdata, pointcloud_dst->totpoint);
+
+ const int totpoint = pointcloud_dst->totpoint = pointcloud_src->totpoint;
+ CustomData_copy(
+ &pointcloud_src->pdata, &pointcloud_dst->pdata, CD_MASK_ALL, alloctype, totpoint);
+
+ if (take_ownership) {
+ if (alloctype == CD_ASSIGN) {
+ /* Free the CustomData but keep the layers. */
+ CustomData_free_typemask(&pointcloud_src->pdata, pointcloud_src->totpoint, 0);
+ }
+ BKE_id_free(nullptr, pointcloud_src);
+ }
+}
+
static std::optional<blender::bounds::MinMaxResult<float3>> point_cloud_bounds(
const PointCloud &pointcloud)
{
@@ -308,7 +333,7 @@ BoundBox *BKE_pointcloud_boundbox_get(Object *ob)
return ob->runtime.bb;
}
-bool BKE_pointcloud_customdata_required(const PointCloud *UNUSED(pointcloud), const char *name)
+bool BKE_pointcloud_attribute_required(const PointCloud * /*pointcloud*/, const char *name)
{
return STREQ(name, POINTCLOUD_ATTR_POSITION);
}
diff --git a/source/blender/blenkernel/intern/preferences.c b/source/blender/blenkernel/intern/preferences.c
index b2e795901fb..dd76f9eddc1 100644
--- a/source/blender/blenkernel/intern/preferences.c
+++ b/source/blender/blenkernel/intern/preferences.c
@@ -115,8 +115,7 @@ void BKE_preferences_asset_library_default_add(UserDef *userdef)
userdef, DATA_(BKE_PREFS_ASSET_LIBRARY_DEFAULT_NAME), NULL);
/* Add new "Default" library under '[doc_path]/Blender/Assets'. */
- BLI_path_join(
- library->path, sizeof(library->path), documents_path, N_("Blender"), N_("Assets"), NULL);
+ BLI_path_join(library->path, sizeof(library->path), documents_path, N_("Blender"), N_("Assets"));
}
/** \} */
diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c
index 6d654730bca..ccec9c346a8 100644
--- a/source/blender/blenkernel/intern/report.c
+++ b/source/blender/blenkernel/intern/report.c
@@ -258,10 +258,20 @@ char *BKE_reports_string(ReportList *reports, eReportType level)
bool BKE_reports_print_test(const ReportList *reports, eReportType type)
{
+ if (reports == NULL) {
+ return true;
+ }
+ if (reports->flag & RPT_PRINT_HANDLED_BY_OWNER) {
+ return false;
+ }
/* In background mode always print otherwise there are cases the errors won't be displayed,
- * but still add to the report list since this is used for python exception handling. */
- return (G.background || (reports == NULL) ||
- ((reports->flag & RPT_PRINT) && (type >= reports->printlevel)));
+ * but still add to the report list since this is used for Python exception handling. */
+ if (G.background) {
+ return true;
+ }
+
+ /* Common case. */
+ return (reports->flag & RPT_PRINT) && (type >= reports->printlevel);
}
void BKE_reports_print(ReportList *reports, eReportType level)
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 86cccf1da69..5e91b23bce3 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -264,13 +264,13 @@ static RigidBodyCon *rigidbody_copy_constraint(const Object *ob, const int UNUSE
RigidBodyCon *rbcN = NULL;
if (ob->rigidbody_constraint) {
- /* just duplicate the whole struct first (to catch all the settings) */
+ /* Just duplicate the whole struct first (to catch all the settings). */
rbcN = MEM_dupallocN(ob->rigidbody_constraint);
- /* tag object as needing to be verified */
+ /* Tag object as needing to be verified. */
rbcN->flag |= RBC_FLAG_NEEDS_VALIDATE;
- /* clear out all the fields which need to be revalidated later */
+ /* Clear out all the fields which need to be re-validated later. */
rbcN->physics_constraint = NULL;
}
@@ -404,7 +404,7 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
const MVert *mvert = BKE_mesh_verts(mesh);
totvert = mesh->totvert;
looptri = BKE_mesh_runtime_looptri_ensure(mesh);
- tottri = mesh->runtime.looptris.len;
+ tottri = BKE_mesh_runtime_looptri_len(mesh);
const MLoop *mloop = BKE_mesh_loops(mesh);
/* sanity checking - potential case when no data will be present */
@@ -679,12 +679,12 @@ void BKE_rigidbody_calc_volume(Object *ob, float *r_vol)
const MVert *mvert = BKE_mesh_verts(mesh);
totvert = mesh->totvert;
lt = BKE_mesh_runtime_looptri_ensure(mesh);
- tottri = mesh->runtime.looptris.len;
+ tottri = BKE_mesh_runtime_looptri_len(mesh);
const MLoop *mloop = BKE_mesh_loops(mesh);
if (totvert > 0 && tottri > 0) {
BKE_mesh_calc_volume(mvert, totvert, lt, tottri, mloop, &volume, NULL);
- const float volume_scale = mat4_to_volume_scale(ob->obmat);
+ const float volume_scale = mat4_to_volume_scale(ob->object_to_world);
volume *= fabsf(volume_scale);
}
}
@@ -753,7 +753,7 @@ void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
const MVert *mvert = BKE_mesh_verts(mesh);
totvert = mesh->totvert;
looptri = BKE_mesh_runtime_looptri_ensure(mesh);
- tottri = mesh->runtime.looptris.len;
+ tottri = BKE_mesh_runtime_looptri_len(mesh);
const MLoop *mloop = BKE_mesh_loops(mesh);
if (totvert > 0 && tottri > 0) {
@@ -809,7 +809,7 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
return;
}
- mat4_to_loc_quat(loc, rot, ob->obmat);
+ mat4_to_loc_quat(loc, rot, ob->object_to_world);
rbo->shared->physics_object = RB_body_new(rbo->shared->physics_shape, loc, rot);
@@ -974,7 +974,7 @@ static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, b
rbc->physics_constraint = NULL;
}
- mat4_to_loc_quat(loc, rot, ob->obmat);
+ mat4_to_loc_quat(loc, rot, ob->object_to_world);
if (rb1 && rb2) {
switch (rbc->type) {
@@ -1266,7 +1266,7 @@ RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
rbo->mesh_source = RBO_MESH_DEFORM;
/* set initial transform */
- mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat);
+ mat4_to_loc_quat(rbo->pos, rbo->orn, ob->object_to_world);
/* flag cache as outdated */
BKE_rigidbody_cache_reset(rbw);
@@ -1545,7 +1545,7 @@ void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob, const bo
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
- /* Relying on usercount of the object should be OK, and it is much cheaper than looping in all
+ /* Relying on user-count of the object should be OK, and it is much cheaper than looping in all
* collections to check whether the object is already in another one... */
if (ID_REAL_USERS(&ob->id) == 1) {
/* Some users seems to find it funny to use a view-layer instancing collection
@@ -1664,7 +1664,9 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Object *ob, RigidBodyO
return;
}
+ const Scene *scene = DEG_get_input_scene(depsgraph);
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob);
const bool is_selected = base ? (base->flag & BASE_SELECTED) != 0 : false;
@@ -1687,7 +1689,7 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Object *ob, RigidBodyO
if (!(rbo->flag & RBO_FLAG_KINEMATIC)) {
/* update scale for all non kinematic objects */
float new_scale[3], old_scale[3];
- mat4_to_size(new_scale, ob->obmat);
+ mat4_to_size(new_scale, ob->object_to_world);
RB_body_get_scale(rbo->shared->physics_object, old_scale);
/* Avoid updating collision shape AABBs if scale didn't change. */
@@ -1884,7 +1886,7 @@ static ListBase rigidbody_create_substep_data(RigidBodyWorld *rbw)
copy_v4_v4(data->old_rot, rot);
copy_v3_v3(data->old_scale, scale);
- mat4_decompose(loc, rot, scale, ob->obmat);
+ mat4_decompose(loc, rot, scale, ob->object_to_world);
copy_v3_v3(data->new_pos, loc);
copy_v4_v4(data->new_rot, rot);
@@ -2008,7 +2010,9 @@ static void rigidbody_free_substep_data(ListBase *substep_targets)
}
static void rigidbody_update_simulation_post_step(Depsgraph *depsgraph, RigidBodyWorld *rbw)
{
+ const Scene *scene = DEG_get_input_scene(depsgraph);
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
+ BKE_view_layer_synced_ensure(scene, view_layer);
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, ob) {
Base *base = BKE_view_layer_base_find(view_layer, ob);
@@ -2051,15 +2055,15 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
quat_to_mat4(mat, rbo->orn);
copy_v3_v3(mat[3], rbo->pos);
- mat4_to_size(size, ob->obmat);
+ mat4_to_size(size, ob->object_to_world);
size_to_mat4(size_mat, size);
mul_m4_m4m4(mat, mat, size_mat);
- copy_m4_m4(ob->obmat, mat);
+ copy_m4_m4(ob->object_to_world, mat);
}
/* otherwise set rigid body transform to current obmat */
else {
- mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat);
+ mat4_to_loc_quat(rbo->pos, rbo->orn, ob->object_to_world);
}
}
@@ -2257,7 +2261,7 @@ void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime
/* write cache for current frame */
BKE_ptcache_validate(cache, (int)ctime);
- BKE_ptcache_write(&pid, (unsigned int)ctime);
+ BKE_ptcache_write(&pid, (uint)ctime);
rbw->ltime = ctime;
}
diff --git a/source/blender/blenkernel/intern/scene.cc b/source/blender/blenkernel/intern/scene.cc
index 9bb9ad9073f..c921cf603de 100644
--- a/source/blender/blenkernel/intern/scene.cc
+++ b/source/blender/blenkernel/intern/scene.cc
@@ -114,6 +114,32 @@
#include "bmesh.h"
+CurveMapping *BKE_sculpt_default_cavity_curve()
+
+{
+ CurveMapping *cumap = BKE_curvemapping_add(1, 0, 0, 1, 1);
+
+ cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+ cumap->preset = CURVE_PRESET_LINE;
+
+ BKE_curvemap_reset(cumap->cm, &cumap->clipr, cumap->preset, CURVEMAP_SLOPE_POSITIVE);
+ BKE_curvemapping_changed(cumap, false);
+ BKE_curvemapping_init(cumap);
+
+ return cumap;
+}
+
+void BKE_sculpt_check_cavity_curves(Sculpt *sd)
+{
+ if (!sd->automasking_cavity_curve) {
+ sd->automasking_cavity_curve = BKE_sculpt_default_cavity_curve();
+ }
+
+ if (!sd->automasking_cavity_curve_op) {
+ sd->automasking_cavity_curve_op = BKE_sculpt_default_cavity_curve();
+ }
+}
+
static void scene_init_data(ID *id)
{
Scene *scene = (Scene *)id;
@@ -137,7 +163,7 @@ static void scene_init_data(ID *id)
scene->toolsettings = DNA_struct_default_alloc(ToolSettings);
- scene->toolsettings->autokey_mode = (uchar)U.autokey_mode;
+ scene->toolsettings->autokey_mode = uchar(U.autokey_mode);
/* Grease pencil multi-frame falloff curve. */
scene->toolsettings->gp_sculpt.cur_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
@@ -156,11 +182,11 @@ static void scene_init_data(ID *id)
scene->unit.system = USER_UNIT_METRIC;
scene->unit.scale_length = 1.0f;
- scene->unit.length_unit = (uchar)BKE_unit_base_of_type_get(USER_UNIT_METRIC, B_UNIT_LENGTH);
- scene->unit.mass_unit = (uchar)BKE_unit_base_of_type_get(USER_UNIT_METRIC, B_UNIT_MASS);
- scene->unit.time_unit = (uchar)BKE_unit_base_of_type_get(USER_UNIT_METRIC, B_UNIT_TIME);
- scene->unit.temperature_unit = (uchar)BKE_unit_base_of_type_get(USER_UNIT_METRIC,
- B_UNIT_TEMPERATURE);
+ scene->unit.length_unit = uchar(BKE_unit_base_of_type_get(USER_UNIT_METRIC, B_UNIT_LENGTH));
+ scene->unit.mass_unit = uchar(BKE_unit_base_of_type_get(USER_UNIT_METRIC, B_UNIT_MASS));
+ scene->unit.time_unit = uchar(BKE_unit_base_of_type_get(USER_UNIT_METRIC, B_UNIT_TIME));
+ scene->unit.temperature_unit = uchar(
+ BKE_unit_base_of_type_get(USER_UNIT_METRIC, B_UNIT_TEMPERATURE));
/* Anti-Aliasing threshold. */
scene->grease_pencil_settings.smaa_threshold = 1.0f;
@@ -218,7 +244,7 @@ static void scene_init_data(ID *id)
/* Master Collection */
scene->master_collection = BKE_collection_master_add(scene);
- BKE_view_layer_add(scene, "ViewLayer", nullptr, VIEWLAYER_ADD_NEW);
+ BKE_view_layer_add(scene, DATA_("ViewLayer"), nullptr, VIEWLAYER_ADD_NEW);
}
static void scene_copy_markers(Scene *scene_dst, const Scene *scene_src, const int flag)
@@ -235,7 +261,7 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
{
Scene *scene_dst = (Scene *)id_dst;
const Scene *scene_src = (const Scene *)id_src;
- /* We never handle usercount here for own data. */
+ /* We never handle user-count here for own data. */
const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
/* We always need allocation of our private ID data. */
const int flag_private_id_data = flag & ~LIB_ID_CREATE_NO_ALLOCATE;
@@ -254,6 +280,9 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
}
/* View Layers */
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene_src->view_layers) {
+ BKE_view_layer_synced_ensure(scene_src, view_layer);
+ }
BLI_duplicatelist(&scene_dst->view_layers, &scene_src->view_layers);
for (ViewLayer *view_layer_src = static_cast<ViewLayer *>(scene_src->view_layers.first),
*view_layer_dst = static_cast<ViewLayer *>(scene_dst->view_layers.first);
@@ -431,7 +460,7 @@ static void scene_free_data(ID *id)
BLI_assert(scene->layer_properties == nullptr);
}
-static void scene_foreach_rigidbodyworldSceneLooper(struct RigidBodyWorld *UNUSED(rbw),
+static void scene_foreach_rigidbodyworldSceneLooper(struct RigidBodyWorld * /*rbw*/,
ID **id_pointer,
void *user_data,
int cb_flag)
@@ -745,7 +774,7 @@ static bool seq_foreach_member_id_cb(Sequence *seq, void *user_data)
{ \
CHECK_TYPE(&((_id_super)->id), ID *); \
BKE_lib_query_foreachid_process((_data), (ID **)&(_id_super), (_cb_flag)); \
- if (BKE_lib_query_foreachid_iter_stop((_data))) { \
+ if (BKE_lib_query_foreachid_iter_stop(_data)) { \
return false; \
} \
} \
@@ -803,8 +832,8 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data)
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, view_layer->mat_override, IDWALK_CB_USER);
-
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(
data, base->object, IDWALK_CB_NOP | IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE);
}
@@ -880,8 +909,8 @@ static bool seq_foreach_path_callback(Sequence *seq, void *user_data)
}
else if ((seq->type == SEQ_TYPE_IMAGE) && se) {
/* NOTE: An option not to loop over all strips could be useful? */
- unsigned int len = (unsigned int)MEM_allocN_len(se) / (unsigned int)sizeof(*se);
- unsigned int i;
+ uint len = uint(MEM_allocN_len(se)) / uint(sizeof(*se));
+ uint i;
if (bpath_data->flag & BKE_BPATH_FOREACH_PATH_SKIP_MULTIFILE) {
/* only operate on one path */
@@ -940,6 +969,13 @@ static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_addres
}
if (tos->sculpt) {
BLO_write_struct(writer, Sculpt, tos->sculpt);
+ if (tos->sculpt->automasking_cavity_curve) {
+ BKE_curvemapping_blend_write(writer, tos->sculpt->automasking_cavity_curve);
+ }
+ if (tos->sculpt->automasking_cavity_curve_op) {
+ BKE_curvemapping_blend_write(writer, tos->sculpt->automasking_cavity_curve_op);
+ }
+
BKE_paint_blend_write(writer, &tos->sculpt->paint);
}
if (tos->uvsculpt) {
@@ -1005,10 +1041,10 @@ static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_addres
if (sce->r.avicodecdata) {
BLO_write_struct(writer, AviCodecData, sce->r.avicodecdata);
if (sce->r.avicodecdata->lpFormat) {
- BLO_write_raw(writer, (size_t)sce->r.avicodecdata->cbFormat, sce->r.avicodecdata->lpFormat);
+ BLO_write_raw(writer, size_t(sce->r.avicodecdata->cbFormat), sce->r.avicodecdata->lpFormat);
}
if (sce->r.avicodecdata->lpParms) {
- BLO_write_raw(writer, (size_t)sce->r.avicodecdata->cbParms, sce->r.avicodecdata->lpParms);
+ BLO_write_raw(writer, size_t(sce->r.avicodecdata->cbParms), sce->r.avicodecdata->lpParms);
}
}
@@ -1056,7 +1092,7 @@ static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_addres
BKE_curvemapping_curves_blend_write(writer, &sce->r.mblur_shutter_curve);
LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
- BKE_view_layer_blend_write(writer, view_layer);
+ BKE_view_layer_blend_write(writer, sce, view_layer);
}
if (sce->master_collection) {
@@ -1153,6 +1189,24 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
sce->toolsettings->particle.object = nullptr;
sce->toolsettings->gp_sculpt.paintcursor = nullptr;
+ if (sce->toolsettings->sculpt) {
+ BLO_read_data_address(reader, &sce->toolsettings->sculpt->automasking_cavity_curve);
+ BLO_read_data_address(reader, &sce->toolsettings->sculpt->automasking_cavity_curve_op);
+
+ if (sce->toolsettings->sculpt->automasking_cavity_curve) {
+ BKE_curvemapping_blend_read(reader, sce->toolsettings->sculpt->automasking_cavity_curve);
+ BKE_curvemapping_init(sce->toolsettings->sculpt->automasking_cavity_curve);
+ }
+
+ if (sce->toolsettings->sculpt->automasking_cavity_curve_op) {
+ BKE_curvemapping_blend_read(reader,
+ sce->toolsettings->sculpt->automasking_cavity_curve_op);
+ BKE_curvemapping_init(sce->toolsettings->sculpt->automasking_cavity_curve_op);
+ }
+
+ BKE_sculpt_check_cavity_curves(sce->toolsettings->sculpt);
+ }
+
/* Relink grease pencil interpolation curves. */
BLO_read_data_address(reader, &sce->toolsettings->gp_interpolate.custom_ipo);
if (sce->toolsettings->gp_interpolate.custom_ipo) {
@@ -1207,8 +1261,8 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
intptr_t seqbase_offset;
intptr_t channels_offset;
- seqbase_offset = ((intptr_t) & (temp.seqbase)) - ((intptr_t)&temp);
- channels_offset = ((intptr_t) & (temp.channels)) - ((intptr_t)&temp);
+ seqbase_offset = intptr_t(&(temp).seqbase) - intptr_t(&temp);
+ channels_offset = intptr_t(&(temp).channels) - intptr_t(&temp);
/* seqbase root pointer */
if (ed->seqbasep == old_seqbasep) {
@@ -1228,7 +1282,7 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
}
/* Active channels root pointer. */
- if (ed->displayed_channels == old_displayed_channels || ed->displayed_channels == nullptr) {
+ if (ELEM(ed->displayed_channels, old_displayed_channels, nullptr)) {
ed->displayed_channels = &ed->channels;
}
else {
@@ -1263,7 +1317,7 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
}
}
- if (ms->old_channels == old_displayed_channels || ms->old_channels == nullptr) {
+ if (ELEM(ms->old_channels, old_displayed_channels, nullptr)) {
ms->old_channels = &ed->channels;
}
else {
@@ -1326,7 +1380,7 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
/* make sure simulation starts from the beginning after loading file */
if (rbw->pointcache) {
- rbw->ltime = (float)rbw->pointcache->startframe;
+ rbw->ltime = float(rbw->pointcache->startframe);
}
}
else {
@@ -1340,7 +1394,7 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
/* make sure simulation starts from the beginning after loading file */
if (rbw->shared->pointcache) {
- rbw->ltime = (float)rbw->shared->pointcache->startframe;
+ rbw->ltime = float(rbw->shared->pointcache->startframe);
}
}
rbw->objects = nullptr;
@@ -1640,7 +1694,7 @@ static void scene_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old)
}
}
-static void scene_lib_override_apply_post(ID *id_dst, ID *UNUSED(id_src))
+static void scene_lib_override_apply_post(ID *id_dst, ID * /*id_src*/)
{
Scene *scene = (Scene *)id_dst;
@@ -1740,6 +1794,18 @@ ToolSettings *BKE_toolsettings_copy(ToolSettings *toolsettings, const int flag)
if (ts->sculpt) {
ts->sculpt = static_cast<Sculpt *>(MEM_dupallocN(ts->sculpt));
BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint, flag);
+
+ if (ts->sculpt->automasking_cavity_curve) {
+ ts->sculpt->automasking_cavity_curve = BKE_curvemapping_copy(
+ ts->sculpt->automasking_cavity_curve);
+ BKE_curvemapping_init(ts->sculpt->automasking_cavity_curve);
+ }
+
+ if (ts->sculpt->automasking_cavity_curve_op) {
+ ts->sculpt->automasking_cavity_curve_op = BKE_curvemapping_copy(
+ ts->sculpt->automasking_cavity_curve_op);
+ BKE_curvemapping_init(ts->sculpt->automasking_cavity_curve_op);
+ }
}
if (ts->uvsculpt) {
ts->uvsculpt = static_cast<UvSculpt *>(MEM_dupallocN(ts->uvsculpt));
@@ -1797,6 +1863,13 @@ void BKE_toolsettings_free(ToolSettings *toolsettings)
MEM_freeN(toolsettings->wpaint);
}
if (toolsettings->sculpt) {
+ if (toolsettings->sculpt->automasking_cavity_curve) {
+ BKE_curvemapping_free(toolsettings->sculpt->automasking_cavity_curve);
+ }
+ if (toolsettings->sculpt->automasking_cavity_curve_op) {
+ BKE_curvemapping_free(toolsettings->sculpt->automasking_cavity_curve_op);
+ }
+
BKE_paint_free(&toolsettings->sculpt->paint);
MEM_freeN(toolsettings->sculpt);
}
@@ -2050,7 +2123,8 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
bool BKE_scene_object_find(Scene *scene, Object *ob)
{
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
- if (BLI_findptr(&view_layer->object_bases, ob, offsetof(Base, object))) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ if (BLI_findptr(BKE_view_layer_object_bases_get(view_layer), ob, offsetof(Base, object))) {
return true;
}
}
@@ -2060,7 +2134,8 @@ bool BKE_scene_object_find(Scene *scene, Object *ob)
Object *BKE_scene_object_find_by_name(const Scene *scene, const char *name)
{
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (STREQ(base->object->id.name + 2, name)) {
return base->object;
}
@@ -2081,7 +2156,8 @@ void BKE_scene_set_background(Main *bmain, Scene *scene)
/* copy layers and flags from bases to objects */
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
/* collection patch... */
BKE_scene_object_base_flag_sync_from_base(base);
}
@@ -2124,7 +2200,8 @@ int BKE_scene_base_iter_next(
if (iter->phase == F_START) {
ViewLayer *view_layer = (depsgraph) ? DEG_get_evaluated_view_layer(depsgraph) :
BKE_view_layer_context_active_PLACEHOLDER(*scene);
- *base = static_cast<Base *>(view_layer->object_bases.first);
+ BKE_view_layer_synced_ensure(*scene, view_layer);
+ *base = static_cast<Base *>(BKE_view_layer_object_bases_get(view_layer)->first);
if (*base) {
*ob = (*base)->object;
iter->phase = F_SCENE;
@@ -2134,8 +2211,10 @@ int BKE_scene_base_iter_next(
while ((*scene)->set) {
(*scene) = (*scene)->set;
ViewLayer *view_layer_set = BKE_view_layer_default_render(*scene);
- if (view_layer_set->object_bases.first) {
- *base = static_cast<Base *>(view_layer_set->object_bases.first);
+ BKE_view_layer_synced_ensure(*scene, view_layer_set);
+ ListBase *object_bases = BKE_view_layer_object_bases_get(view_layer_set);
+ if (object_bases->first) {
+ *base = static_cast<Base *>(object_bases->first);
*ob = (*base)->object;
iter->phase = F_SCENE;
break;
@@ -2155,8 +2234,10 @@ int BKE_scene_base_iter_next(
while ((*scene)->set) {
(*scene) = (*scene)->set;
ViewLayer *view_layer_set = BKE_view_layer_default_render(*scene);
- if (view_layer_set->object_bases.first) {
- *base = static_cast<Base *>(view_layer_set->object_bases.first);
+ BKE_view_layer_synced_ensure(*scene, view_layer_set);
+ ListBase *object_bases = BKE_view_layer_object_bases_get(view_layer_set);
+ if (object_bases->first) {
+ *base = static_cast<Base *>(object_bases->first);
*ob = (*base)->object;
break;
}
@@ -2197,13 +2278,13 @@ int BKE_scene_base_iter_next(
if (iter->dupli_refob != *ob) {
if (iter->dupli_refob) {
/* Restore previous object's real matrix. */
- copy_m4_m4(iter->dupli_refob->obmat, iter->omat);
+ copy_m4_m4(iter->dupli_refob->object_to_world, iter->omat);
}
/* Backup new object's real matrix. */
iter->dupli_refob = *ob;
- copy_m4_m4(iter->omat, iter->dupli_refob->obmat);
+ copy_m4_m4(iter->omat, iter->dupli_refob->object_to_world);
}
- copy_m4_m4((*ob)->obmat, iter->dupob->mat);
+ copy_m4_m4((*ob)->object_to_world, iter->dupob->mat);
iter->dupob = iter->dupob->next;
}
@@ -2213,7 +2294,7 @@ int BKE_scene_base_iter_next(
if (iter->dupli_refob) {
/* Restore last object's real matrix. */
- copy_m4_m4(iter->dupli_refob->obmat, iter->omat);
+ copy_m4_m4(iter->dupli_refob->object_to_world, iter->omat);
iter->dupli_refob = nullptr;
}
@@ -2253,7 +2334,7 @@ Object *BKE_scene_camera_switch_find(Scene *scene)
return nullptr;
}
- const int ctime = (int)BKE_scene_ctime_get(scene);
+ const int ctime = int(BKE_scene_ctime_get(scene));
int frame = -(MAXFRAME + 1);
int min_frame = MAXFRAME + 1;
Object *camera = nullptr;
@@ -2417,8 +2498,8 @@ float BKE_scene_frame_get(const Scene *scene)
void BKE_scene_frame_set(Scene *scene, float frame)
{
double intpart;
- scene->r.subframe = modf((double)frame, &intpart);
- scene->r.cfra = (int)intpart;
+ scene->r.subframe = modf(double(frame), &intpart);
+ scene->r.cfra = int(intpart);
}
/* -------------------------------------------------------------------- */
@@ -2505,7 +2586,9 @@ static bool check_rendered_viewport_visible(Main *bmain)
/* TODO(@campbellbarton): shouldn't we be able to use 'DEG_get_view_layer' here?
* Currently this is nullptr on load, so don't. */
-static void prepare_mesh_for_viewport_render(Main *bmain, const ViewLayer *view_layer)
+static void prepare_mesh_for_viewport_render(Main *bmain,
+ const Scene *scene,
+ ViewLayer *view_layer)
{
/* This is needed to prepare mesh to be used by the render
* engine from the viewport rendering. We do loading here
@@ -2515,7 +2598,7 @@ static void prepare_mesh_for_viewport_render(Main *bmain, const ViewLayer *view_
* This makes it so viewport render engine doesn't need to
* call loading of the edit data for the mesh objects.
*/
-
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
if (obedit) {
Mesh *mesh = static_cast<Mesh *>(obedit->data);
@@ -2557,7 +2640,7 @@ void BKE_scene_update_sound(Depsgraph *depsgraph, Main *bmain)
BKE_sound_update_scene(depsgraph, scene);
}
-void BKE_scene_update_tag_audio_volume(Depsgraph *UNUSED(depsgraph), Scene *scene)
+void BKE_scene_update_tag_audio_volume(Depsgraph * /*depsgraph*/, Scene *scene)
{
BLI_assert(DEG_is_evaluated_id(&scene->id));
/* The volume is actually updated in BKE_scene_update_sound(), from either
@@ -2592,7 +2675,7 @@ static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool on
/* Uncomment this to check if graph was properly tagged for update. */
// DEG_debug_graph_relations_validate(depsgraph, bmain, scene);
/* Flush editing data if needed. */
- prepare_mesh_for_viewport_render(bmain, view_layer);
+ prepare_mesh_for_viewport_render(bmain, scene, view_layer);
/* Update all objects: drivers, matrices, etc. flags set
* by depsgraph or manual, no layer check here, gets correct flushed. */
DEG_evaluate_on_refresh(depsgraph);
@@ -2792,10 +2875,10 @@ int get_render_child_particle_number(const RenderData *r, int child_num, bool fo
{
if (r->mode & R_SIMPLIFY) {
if (for_render) {
- return (int)(r->simplify_particles_render * child_num);
+ return int(r->simplify_particles_render * child_num);
}
- return (int)(r->simplify_particles * child_num);
+ return int(r->simplify_particles * child_num);
}
return child_num;
@@ -2810,8 +2893,10 @@ Base *_setlooper_base_step(Scene **sce_iter, ViewLayer *view_layer, Base *base)
if ((base == nullptr) && (view_layer != nullptr)) {
/* First time looping, return the scenes first base. */
/* For the first loop we should get the layer from workspace when available. */
- if (view_layer->object_bases.first) {
- return (Base *)view_layer->object_bases.first;
+ BKE_view_layer_synced_ensure(*sce_iter, view_layer);
+ ListBase *object_bases = BKE_view_layer_object_bases_get(view_layer);
+ if (object_bases->first) {
+ return static_cast<Base *>(object_bases->first);
}
/* No base on this scene layer. */
goto next_set;
@@ -2821,7 +2906,7 @@ Base *_setlooper_base_step(Scene **sce_iter, ViewLayer *view_layer, Base *base)
/* Reached the end, get the next base in the set. */
while ((*sce_iter = (*sce_iter)->set)) {
ViewLayer *view_layer_set = BKE_view_layer_default_render(*sce_iter);
- base = (Base *)view_layer_set->object_bases.first;
+ base = (Base *)BKE_view_layer_object_bases_get(view_layer_set)->first;
if (base) {
return base;
@@ -2880,13 +2965,11 @@ bool BKE_scene_uses_cycles_experimental_features(Scene *scene)
return RNA_enum_get(&cycles_ptr, "feature_set") == CYCLES_FEATURES_EXPERIMENTAL;
}
-void BKE_scene_base_flag_to_objects(ViewLayer *view_layer)
+void BKE_scene_base_flag_to_objects(const Scene *scene, ViewLayer *view_layer)
{
- Base *base = static_cast<Base *>(view_layer->object_bases.first);
-
- while (base) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
BKE_scene_object_base_flag_sync_from_base(base);
- base = base->next;
}
}
@@ -2987,7 +3070,7 @@ double BKE_scene_unit_scale(const UnitSettings *unit, const int unit_type, doubl
case B_UNIT_LENGTH:
case B_UNIT_VELOCITY:
case B_UNIT_ACCELERATION:
- return value * (double)unit->scale_length;
+ return value * double(unit->scale_length);
case B_UNIT_AREA:
case B_UNIT_POWER:
return value * pow(unit->scale_length, 2);
@@ -3305,10 +3388,10 @@ struct DepsgraphKey {
*/
};
-static unsigned int depsgraph_key_hash(const void *key_v)
+static uint depsgraph_key_hash(const void *key_v)
{
const DepsgraphKey *key = static_cast<const DepsgraphKey *>(key_v);
- unsigned int hash = BLI_ghashutil_ptrhash(key->view_layer);
+ uint hash = BLI_ghashutil_ptrhash(key->view_layer);
/* TODO(sergey): Include hash from other fields in the key. */
return hash;
}
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index c8bdf91b45e..ab7a1bcaa35 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -46,6 +46,7 @@
#include "BKE_lib_query.h"
#include "BKE_node.h"
#include "BKE_screen.h"
+#include "BKE_viewer_path.h"
#include "BKE_workspace.h"
#include "BLO_read_write.h"
@@ -97,6 +98,7 @@ void BKE_screen_foreach_id_screen_area(LibraryForeachIDData *data, ScrArea *area
if (v3d->localvd) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, v3d->localvd->camera, IDWALK_CB_NOP);
}
+ BKE_viewer_path_foreach_id(data, &v3d->viewer_path);
break;
}
case SPACE_GRAPH: {
@@ -197,12 +199,7 @@ void BKE_screen_foreach_id_screen_area(LibraryForeachIDData *data, ScrArea *area
}
case SPACE_SPREADSHEET: {
SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
- LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) {
- if (context->type == SPREADSHEET_CONTEXT_OBJECT) {
- BKE_LIB_FOREACHID_PROCESS_IDSUPER(
- data, ((SpreadsheetContextObject *)context)->object, IDWALK_CB_NOP);
- }
- }
+ BKE_viewer_path_foreach_id(data, &sspreadsheet->viewer_path);
break;
}
default:
@@ -305,9 +302,9 @@ IDTypeInfo IDType_ID_SCR = {
.lib_override_apply_post = NULL,
};
-/* ************ Spacetype/regiontype handling ************** */
+/* ************ Space-type/region-type handling ************** */
-/* keep global; this has to be accessible outside of windowmanager */
+/** Keep global; this has to be accessible outside of window-manager. */
static ListBase spacetypes = {NULL, NULL};
/* not SpaceType itself */
@@ -1123,59 +1120,6 @@ static void write_uilist(BlendWriter *writer, uiList *ui_list)
}
}
-static void write_space_outliner(BlendWriter *writer, const SpaceOutliner *space_outliner)
-{
- BLI_mempool *ts = space_outliner->treestore;
-
- if (ts) {
- const int elems = BLI_mempool_len(ts);
- /* linearize mempool to array */
- TreeStoreElem *data = elems ? BLI_mempool_as_arrayN(ts, "TreeStoreElem") : NULL;
-
- if (data) {
- BLO_write_struct(writer, SpaceOutliner, space_outliner);
-
- /* To store #TreeStore (instead of the mempool), two unique memory addresses are needed,
- * which can be used to identify the data on read:
- * 1) One for the #TreeStore data itself.
- * 2) One for the array of #TreeStoreElem's inside #TreeStore (#TreeStore.data).
- *
- * For 1) we just use the mempool's address (#SpaceOutliner::treestore).
- * For 2) we don't have such a direct choice. We can't just use the array's address from
- * above, since that may not be unique over all Outliners. So instead use an address relative
- * to 1).
- */
- /* TODO the mempool could be moved to #SpaceOutliner_Runtime so that #SpaceOutliner could
- * hold the #TreeStore directly. */
-
- /* Address relative to the tree-store, as noted above. */
- void *data_addr = (void *)POINTER_OFFSET(ts, sizeof(void *));
- /* There should be plenty of memory addresses within the mempool data that we can point into,
- * just double-check we don't potentially end up with a memory address that another DNA
- * struct might use. Assumes BLI_mempool uses the guarded allocator. */
- BLI_assert(MEM_allocN_len(ts) >= sizeof(void *) * 2);
-
- TreeStore ts_flat = {0};
- ts_flat.usedelem = elems;
- ts_flat.totelem = elems;
- ts_flat.data = data_addr;
-
- BLO_write_struct_at_address(writer, TreeStore, ts, &ts_flat);
- BLO_write_struct_array_at_address(writer, TreeStoreElem, elems, data_addr, data);
-
- MEM_freeN(data);
- }
- else {
- SpaceOutliner space_outliner_flat = *space_outliner;
- space_outliner_flat.treestore = NULL;
- BLO_write_struct_at_address(writer, SpaceOutliner, space_outliner, &space_outliner_flat);
- }
- }
- else {
- BLO_write_struct(writer, SpaceOutliner, space_outliner);
- }
-}
-
static void write_panel_list(BlendWriter *writer, ListBase *lb)
{
LISTBASE_FOREACH (Panel *, panel, lb) {
@@ -1208,146 +1152,9 @@ static void write_area(BlendWriter *writer, ScrArea *area)
write_region(writer, region, sl->spacetype);
}
- if (sl->spacetype == SPACE_VIEW3D) {
- View3D *v3d = (View3D *)sl;
- BLO_write_struct(writer, View3D, v3d);
-
- if (v3d->localvd) {
- BLO_write_struct(writer, View3D, v3d->localvd);
- }
-
- BKE_screen_view3d_shading_blend_write(writer, &v3d->shading);
- }
- else if (sl->spacetype == SPACE_GRAPH) {
- SpaceGraph *sipo = (SpaceGraph *)sl;
- ListBase tmpGhosts = sipo->runtime.ghost_curves;
-
- /* temporarily disable ghost curves when saving */
- BLI_listbase_clear(&sipo->runtime.ghost_curves);
-
- BLO_write_struct(writer, SpaceGraph, sl);
- if (sipo->ads) {
- BLO_write_struct(writer, bDopeSheet, sipo->ads);
- }
-
- /* reenable ghost curves */
- sipo->runtime.ghost_curves = tmpGhosts;
- }
- else if (sl->spacetype == SPACE_PROPERTIES) {
- BLO_write_struct(writer, SpaceProperties, sl);
- }
- else if (sl->spacetype == SPACE_FILE) {
- SpaceFile *sfile = (SpaceFile *)sl;
-
- BLO_write_struct(writer, SpaceFile, sl);
- if (sfile->params) {
- BLO_write_struct(writer, FileSelectParams, sfile->params);
- }
- if (sfile->asset_params) {
- BLO_write_struct(writer, FileAssetSelectParams, sfile->asset_params);
- }
- }
- else if (sl->spacetype == SPACE_SEQ) {
- BLO_write_struct(writer, SpaceSeq, sl);
- }
- else if (sl->spacetype == SPACE_OUTLINER) {
- SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
- write_space_outliner(writer, space_outliner);
- }
- else if (sl->spacetype == SPACE_IMAGE) {
- BLO_write_struct(writer, SpaceImage, sl);
- }
- else if (sl->spacetype == SPACE_TEXT) {
- BLO_write_struct(writer, SpaceText, sl);
- }
- else if (sl->spacetype == SPACE_SCRIPT) {
- SpaceScript *scr = (SpaceScript *)sl;
- scr->but_refs = NULL;
- BLO_write_struct(writer, SpaceScript, sl);
- }
- else if (sl->spacetype == SPACE_ACTION) {
- BLO_write_struct(writer, SpaceAction, sl);
- }
- else if (sl->spacetype == SPACE_NLA) {
- SpaceNla *snla = (SpaceNla *)sl;
-
- BLO_write_struct(writer, SpaceNla, snla);
- if (snla->ads) {
- BLO_write_struct(writer, bDopeSheet, snla->ads);
- }
- }
- else if (sl->spacetype == SPACE_NODE) {
- SpaceNode *snode = (SpaceNode *)sl;
- BLO_write_struct(writer, SpaceNode, snode);
-
- LISTBASE_FOREACH (bNodeTreePath *, path, &snode->treepath) {
- BLO_write_struct(writer, bNodeTreePath, path);
- }
- }
- else if (sl->spacetype == SPACE_CONSOLE) {
- SpaceConsole *con = (SpaceConsole *)sl;
-
- LISTBASE_FOREACH (ConsoleLine *, cl, &con->history) {
- /* 'len_alloc' is invalid on write, set from 'len' on read */
- BLO_write_struct(writer, ConsoleLine, cl);
- BLO_write_raw(writer, (size_t)cl->len + 1, cl->line);
- }
- BLO_write_struct(writer, SpaceConsole, sl);
- }
- else if (sl->spacetype == SPACE_TOPBAR) {
- BLO_write_struct(writer, SpaceTopBar, sl);
- }
- else if (sl->spacetype == SPACE_STATUSBAR) {
- BLO_write_struct(writer, SpaceStatusBar, sl);
- }
- else if (sl->spacetype == SPACE_USERPREF) {
- BLO_write_struct(writer, SpaceUserPref, sl);
- }
- else if (sl->spacetype == SPACE_CLIP) {
- BLO_write_struct(writer, SpaceClip, sl);
- }
- else if (sl->spacetype == SPACE_INFO) {
- BLO_write_struct(writer, SpaceInfo, sl);
- }
- else if (sl->spacetype == SPACE_SPREADSHEET) {
- BLO_write_struct(writer, SpaceSpreadsheet, sl);
- SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
-
- LISTBASE_FOREACH (SpreadsheetRowFilter *, row_filter, &sspreadsheet->row_filters) {
- BLO_write_struct(writer, SpreadsheetRowFilter, row_filter);
- BLO_write_string(writer, row_filter->value_string);
- }
-
- LISTBASE_FOREACH (SpreadsheetColumn *, column, &sspreadsheet->columns) {
- BLO_write_struct(writer, SpreadsheetColumn, column);
- BLO_write_struct(writer, SpreadsheetColumnID, column->id);
- BLO_write_string(writer, column->id->name);
- /* While the display name is technically runtime data, we write it here, otherwise the row
- * filters might not now their type if their region draws before the main region.
- * This would ideally be cleared here. */
- BLO_write_string(writer, column->display_name);
- }
- LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) {
- switch (context->type) {
- case SPREADSHEET_CONTEXT_OBJECT: {
- SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context;
- BLO_write_struct(writer, SpreadsheetContextObject, object_context);
- break;
- }
- case SPREADSHEET_CONTEXT_MODIFIER: {
- SpreadsheetContextModifier *modifier_context = (SpreadsheetContextModifier *)context;
- BLO_write_struct(writer, SpreadsheetContextModifier, modifier_context);
- BLO_write_string(writer, modifier_context->modifier_name);
- break;
- }
- case SPREADSHEET_CONTEXT_NODE: {
- SpreadsheetContextNode *node_context = (SpreadsheetContextNode *)context;
- BLO_write_struct(writer, SpreadsheetContextNode, node_context);
- BLO_write_string(writer, node_context->node_name);
- break;
- }
- }
- }
+ SpaceType *space_type = BKE_spacetype_from_id(sl->spacetype);
+ if (space_type && space_type->blend_write) {
+ space_type->blend_write(writer, sl);
}
else if (sl->spacetype == SPACE_ASSETS) {
BLO_write_struct(writer, SpaceAssets, sl);
@@ -1527,225 +1334,9 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
direct_link_region(reader, region, sl->spacetype);
}
- if (sl->spacetype == SPACE_VIEW3D) {
- View3D *v3d = (View3D *)sl;
-
- memset(&v3d->runtime, 0x0, sizeof(v3d->runtime));
-
- if (v3d->gpd) {
- BLO_read_data_address(reader, &v3d->gpd);
- BKE_gpencil_blend_read_data(reader, v3d->gpd);
- }
- BLO_read_data_address(reader, &v3d->localvd);
-
- /* render can be quite heavy, set to solid on load */
- if (v3d->shading.type == OB_RENDER) {
- v3d->shading.type = OB_SOLID;
- }
- v3d->shading.prev_type = OB_SOLID;
-
- BKE_screen_view3d_shading_blend_read_data(reader, &v3d->shading);
-
- BKE_screen_view3d_do_versions_250(v3d, &sl->regionbase);
- }
- else if (sl->spacetype == SPACE_GRAPH) {
- SpaceGraph *sipo = (SpaceGraph *)sl;
-
- BLO_read_data_address(reader, &sipo->ads);
- memset(&sipo->runtime, 0x0, sizeof(sipo->runtime));
- }
- else if (sl->spacetype == SPACE_NLA) {
- SpaceNla *snla = (SpaceNla *)sl;
-
- BLO_read_data_address(reader, &snla->ads);
- }
- else if (sl->spacetype == SPACE_OUTLINER) {
- SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
-
- /* use #BLO_read_get_new_data_address_no_us and do not free old memory avoiding double
- * frees and use of freed memory. this could happen because of a
- * bug fixed in revision 58959 where the treestore memory address
- * was not unique */
- TreeStore *ts = BLO_read_get_new_data_address_no_us(reader, space_outliner->treestore);
- space_outliner->treestore = NULL;
- if (ts) {
- TreeStoreElem *elems = BLO_read_get_new_data_address_no_us(reader, ts->data);
-
- space_outliner->treestore = BLI_mempool_create(
- sizeof(TreeStoreElem), ts->usedelem, 512, BLI_MEMPOOL_ALLOW_ITER);
- if (ts->usedelem && elems) {
- for (int i = 0; i < ts->usedelem; i++) {
- TreeStoreElem *new_elem = BLI_mempool_alloc(space_outliner->treestore);
- *new_elem = elems[i];
- }
- }
- /* we only saved what was used */
- space_outliner->storeflag |= SO_TREESTORE_CLEANUP; /* at first draw */
- }
- space_outliner->tree.first = space_outliner->tree.last = NULL;
- space_outliner->runtime = NULL;
- }
- else if (sl->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = (SpaceImage *)sl;
-
- sima->iuser.scene = NULL;
- sima->scopes.waveform_1 = NULL;
- sima->scopes.waveform_2 = NULL;
- sima->scopes.waveform_3 = NULL;
- sima->scopes.vecscope = NULL;
- sima->scopes.ok = 0;
-
- /* WARNING: gpencil data is no longer stored directly in sima after 2.5
- * so sacrifice a few old files for now to avoid crashes with new files!
- * committed: r28002 */
-#if 0
- sima->gpd = newdataadr(fd, sima->gpd);
- if (sima->gpd) {
- BKE_gpencil_blend_read_data(fd, sima->gpd);
- }
-#endif
- }
- else if (sl->spacetype == SPACE_NODE) {
- SpaceNode *snode = (SpaceNode *)sl;
-
- if (snode->gpd) {
- BLO_read_data_address(reader, &snode->gpd);
- BKE_gpencil_blend_read_data(reader, snode->gpd);
- }
-
- BLO_read_list(reader, &snode->treepath);
- snode->edittree = NULL;
- snode->runtime = NULL;
- }
- else if (sl->spacetype == SPACE_TEXT) {
- SpaceText *st = (SpaceText *)sl;
- memset(&st->runtime, 0x0, sizeof(st->runtime));
- }
- else if (sl->spacetype == SPACE_SEQ) {
- SpaceSeq *sseq = (SpaceSeq *)sl;
-
- /* grease pencil data is not a direct data and can't be linked from direct_link*
- * functions, it should be linked from lib_link* functions instead
- *
- * otherwise it'll lead to lost grease data on open because it'll likely be
- * read from file after all other users of grease pencil and newdataadr would
- * simple return NULL here (sergey)
- */
-#if 0
- if (sseq->gpd) {
- sseq->gpd = newdataadr(fd, sseq->gpd);
- BKE_gpencil_blend_read_data(fd, sseq->gpd);
- }
-#endif
- sseq->scopes.reference_ibuf = NULL;
- sseq->scopes.zebra_ibuf = NULL;
- sseq->scopes.waveform_ibuf = NULL;
- sseq->scopes.sep_waveform_ibuf = NULL;
- sseq->scopes.vector_ibuf = NULL;
- sseq->scopes.histogram_ibuf = NULL;
- memset(&sseq->runtime, 0x0, sizeof(sseq->runtime));
- }
- else if (sl->spacetype == SPACE_PROPERTIES) {
- SpaceProperties *sbuts = (SpaceProperties *)sl;
-
- sbuts->path = NULL;
- sbuts->texuser = NULL;
- sbuts->mainbo = sbuts->mainb;
- sbuts->mainbuser = sbuts->mainb;
- sbuts->runtime = NULL;
- }
- else if (sl->spacetype == SPACE_CONSOLE) {
- SpaceConsole *sconsole = (SpaceConsole *)sl;
-
- BLO_read_list(reader, &sconsole->scrollback);
- BLO_read_list(reader, &sconsole->history);
-
- /* Comma expressions, (e.g. expr1, expr2, expr3) evaluate each expression,
- * from left to right. the right-most expression sets the result of the comma
- * expression as a whole. */
- LISTBASE_FOREACH_MUTABLE (ConsoleLine *, cl, &sconsole->history) {
- BLO_read_data_address(reader, &cl->line);
- if (cl->line) {
- /* the allocted length is not written, so reset here */
- cl->len_alloc = cl->len + 1;
- }
- else {
- BLI_remlink(&sconsole->history, cl);
- MEM_freeN(cl);
- }
- }
- }
- else if (sl->spacetype == SPACE_FILE) {
- SpaceFile *sfile = (SpaceFile *)sl;
-
- /* this sort of info is probably irrelevant for reloading...
- * plus, it isn't saved to files yet!
- */
- sfile->folders_prev = sfile->folders_next = NULL;
- BLI_listbase_clear(&sfile->folder_histories);
- sfile->files = NULL;
- sfile->layout = NULL;
- sfile->op = NULL;
- sfile->previews_timer = NULL;
- sfile->tags = 0;
- sfile->runtime = NULL;
- BLO_read_data_address(reader, &sfile->params);
- BLO_read_data_address(reader, &sfile->asset_params);
- if (sfile->params) {
- sfile->params->rename_id = NULL;
- }
- if (sfile->asset_params) {
- sfile->asset_params->base_params.rename_id = NULL;
- }
- }
- else if (sl->spacetype == SPACE_ACTION) {
- SpaceAction *saction = (SpaceAction *)sl;
-
- memset(&saction->runtime, 0x0, sizeof(saction->runtime));
- }
- else if (sl->spacetype == SPACE_CLIP) {
- SpaceClip *sclip = (SpaceClip *)sl;
-
- sclip->scopes.track_search = NULL;
- sclip->scopes.track_preview = NULL;
- sclip->scopes.ok = 0;
- }
- else if (sl->spacetype == SPACE_SPREADSHEET) {
- SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
-
- sspreadsheet->runtime = NULL;
- BLO_read_list(reader, &sspreadsheet->row_filters);
- LISTBASE_FOREACH (SpreadsheetRowFilter *, row_filter, &sspreadsheet->row_filters) {
- BLO_read_data_address(reader, &row_filter->value_string);
- }
- BLO_read_list(reader, &sspreadsheet->columns);
- LISTBASE_FOREACH (SpreadsheetColumn *, column, &sspreadsheet->columns) {
- BLO_read_data_address(reader, &column->id);
- BLO_read_data_address(reader, &column->id->name);
- /* While the display name is technically runtime data, it is loaded here, otherwise the row
- * filters might not now their type if their region draws before the main region.
- * This would ideally be cleared here. */
- BLO_read_data_address(reader, &column->display_name);
- }
-
- BLO_read_list(reader, &sspreadsheet->context_path);
- LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) {
- switch (context->type) {
- case SPREADSHEET_CONTEXT_NODE: {
- SpreadsheetContextNode *node_context = (SpreadsheetContextNode *)context;
- BLO_read_data_address(reader, &node_context->node_name);
- break;
- }
- case SPREADSHEET_CONTEXT_MODIFIER: {
- SpreadsheetContextModifier *modifier_context = (SpreadsheetContextModifier *)context;
- BLO_read_data_address(reader, &modifier_context->modifier_name);
- break;
- }
- case SPREADSHEET_CONTEXT_OBJECT: {
- break;
- }
- }
- }
+ SpaceType *space_type = BKE_spacetype_from_id(sl->spacetype);
+ if (space_type && space_type->blend_read_data) {
+ space_type->blend_read_data(reader, sl);
}
}
@@ -1789,185 +1380,10 @@ void BKE_screen_area_blend_read_lib(BlendLibReader *reader, ID *parent_id, ScrAr
memset(&area->runtime, 0x0, sizeof(area->runtime));
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
- switch (sl->spacetype) {
- case SPACE_VIEW3D: {
- View3D *v3d = (View3D *)sl;
-
- BLO_read_id_address(reader, parent_id->lib, &v3d->camera);
- BLO_read_id_address(reader, parent_id->lib, &v3d->ob_center);
-
- if (v3d->localvd) {
- BLO_read_id_address(reader, parent_id->lib, &v3d->localvd->camera);
- }
- break;
- }
- case SPACE_GRAPH: {
- SpaceGraph *sipo = (SpaceGraph *)sl;
- bDopeSheet *ads = sipo->ads;
+ SpaceType *space_type = BKE_spacetype_from_id(sl->spacetype);
- if (ads) {
- BLO_read_id_address(reader, parent_id->lib, &ads->source);
- BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp);
- }
- break;
- }
- case SPACE_PROPERTIES: {
- SpaceProperties *sbuts = (SpaceProperties *)sl;
- BLO_read_id_address(reader, parent_id->lib, &sbuts->pinid);
- if (sbuts->pinid == NULL) {
- sbuts->flag &= ~SB_PIN_CONTEXT;
- }
- break;
- }
- case SPACE_FILE: {
- SpaceFile *sfile = (SpaceFile *)sl;
- sfile->tags |= FILE_TAG_REBUILD_MAIN_FILES;
- break;
- }
- case SPACE_ACTION: {
- SpaceAction *saction = (SpaceAction *)sl;
- bDopeSheet *ads = &saction->ads;
-
- if (ads) {
- BLO_read_id_address(reader, parent_id->lib, &ads->source);
- BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp);
- }
-
- BLO_read_id_address(reader, parent_id->lib, &saction->action);
- break;
- }
- case SPACE_IMAGE: {
- SpaceImage *sima = (SpaceImage *)sl;
-
- BLO_read_id_address(reader, parent_id->lib, &sima->image);
- BLO_read_id_address(reader, parent_id->lib, &sima->mask_info.mask);
-
- /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
- * so fingers crossed this works fine!
- */
- BLO_read_id_address(reader, parent_id->lib, &sima->gpd);
- break;
- }
- case SPACE_SEQ: {
- SpaceSeq *sseq = (SpaceSeq *)sl;
-
- /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
- * so fingers crossed this works fine!
- */
- BLO_read_id_address(reader, parent_id->lib, &sseq->gpd);
- break;
- }
- case SPACE_NLA: {
- SpaceNla *snla = (SpaceNla *)sl;
- bDopeSheet *ads = snla->ads;
-
- if (ads) {
- BLO_read_id_address(reader, parent_id->lib, &ads->source);
- BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp);
- }
- break;
- }
- case SPACE_TEXT: {
- SpaceText *st = (SpaceText *)sl;
-
- BLO_read_id_address(reader, parent_id->lib, &st->text);
- break;
- }
- case SPACE_SCRIPT: {
- SpaceScript *scpt = (SpaceScript *)sl;
- /*scpt->script = NULL; - 2.45 set to null, better re-run the script */
- if (scpt->script) {
- BLO_read_id_address(reader, parent_id->lib, &scpt->script);
- if (scpt->script) {
- SCRIPT_SET_NULL(scpt->script);
- }
- }
- break;
- }
- case SPACE_OUTLINER: {
- SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
-
- if (space_outliner->treestore) {
- TreeStoreElem *tselem;
- BLI_mempool_iter iter;
-
- BLI_mempool_iternew(space_outliner->treestore, &iter);
- while ((tselem = BLI_mempool_iterstep(&iter))) {
- BLO_read_id_address(reader, NULL, &tselem->id);
- }
- /* rebuild hash table, because it depends on ids too */
- space_outliner->storeflag |= SO_TREESTORE_REBUILD;
- }
- break;
- }
- case SPACE_NODE: {
- SpaceNode *snode = (SpaceNode *)sl;
-
- /* node tree can be stored locally in id too, link this first */
- BLO_read_id_address(reader, parent_id->lib, &snode->id);
- BLO_read_id_address(reader, parent_id->lib, &snode->from);
-
- bNodeTree *ntree = snode->id ? ntreeFromID(snode->id) : NULL;
- if (ntree) {
- snode->nodetree = ntree;
- }
- else {
- BLO_read_id_address(reader, parent_id->lib, &snode->nodetree);
- }
-
- bNodeTreePath *path;
- for (path = snode->treepath.first; path; path = path->next) {
- if (path == snode->treepath.first) {
- /* first nodetree in path is same as snode->nodetree */
- path->nodetree = snode->nodetree;
- }
- else {
- BLO_read_id_address(reader, parent_id->lib, &path->nodetree);
- }
-
- if (!path->nodetree) {
- break;
- }
- }
-
- /* remaining path entries are invalid, remove */
- bNodeTreePath *path_next;
- for (; path; path = path_next) {
- path_next = path->next;
-
- BLI_remlink(&snode->treepath, path);
- MEM_freeN(path);
- }
-
- /* edittree is just the last in the path,
- * set this directly since the path may have been shortened above */
- if (snode->treepath.last) {
- path = snode->treepath.last;
- snode->edittree = path->nodetree;
- }
- else {
- snode->edittree = NULL;
- }
- break;
- }
- case SPACE_CLIP: {
- SpaceClip *sclip = (SpaceClip *)sl;
- BLO_read_id_address(reader, parent_id->lib, &sclip->clip);
- BLO_read_id_address(reader, parent_id->lib, &sclip->mask_info.mask);
- break;
- }
- case SPACE_SPREADSHEET: {
- SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
- LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) {
- if (context->type == SPREADSHEET_CONTEXT_OBJECT) {
- BLO_read_id_address(
- reader, parent_id->lib, &((SpreadsheetContextObject *)context)->object);
- }
- }
- break;
- }
- default:
- break;
+ if (space_type && space_type->blend_read_lib) {
+ space_type->blend_read_lib(reader, parent_id, sl);
}
}
}
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.cc
index 4b4e3bdcfa6..65226a5db9d 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.cc
@@ -5,12 +5,12 @@
* \ingroup bke
*/
-#include <float.h>
-#include <math.h>
+#include <cfloat>
+#include <cmath>
+#include <cstdio>
+#include <cstring>
+#include <ctime>
#include <memory.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
#include "DNA_gpencil_modifier_types.h"
#include "DNA_mesh_types.h"
@@ -54,30 +54,31 @@
/* Util macros */
#define OUT_OF_MEMORY() ((void)printf("Shrinkwrap: Out of memory\n"))
-typedef struct ShrinkwrapCalcData {
+struct ShrinkwrapCalcData {
ShrinkwrapModifierData *smd; /* shrinkwrap modifier data */
- struct Object *ob; /* object we are applying shrinkwrap to */
+ Object *ob; /* object we are applying shrinkwrap to */
- struct MVert *vert; /* Array of verts being projected. */
+ MVert *vert; /* Array of verts being projected. */
const float (*vert_normals)[3];
- float (*vertexCos)[3]; /* vertexs being shrinkwraped */
+ /* Vertices being shrink-wrapped. */
+ float (*vertexCos)[3];
int numVerts;
- const struct MDeformVert *dvert; /* Pointer to mdeform array */
- int vgroup; /* Vertex group num */
- bool invert_vgroup; /* invert vertex group influence */
+ const MDeformVert *dvert; /* Pointer to mdeform array */
+ int vgroup; /* Vertex group num */
+ bool invert_vgroup; /* invert vertex group influence */
- struct Mesh *target; /* mesh we are shrinking to */
- struct SpaceTransform local2target; /* transform to move between local and target space */
- struct ShrinkwrapTreeData *tree; /* mesh BVH tree data */
+ Mesh *target; /* mesh we are shrinking to */
+ SpaceTransform local2target; /* transform to move between local and target space */
+ ShrinkwrapTreeData *tree; /* mesh BVH tree data */
- struct Object *aux_target;
+ Object *aux_target;
float keepDist; /* Distance to keep above target surface (units are in local space) */
-} ShrinkwrapCalcData;
+};
-typedef struct ShrinkwrapCalcCBData {
+struct ShrinkwrapCalcCBData {
ShrinkwrapCalcData *calc;
ShrinkwrapTreeData *tree;
@@ -85,7 +86,7 @@ typedef struct ShrinkwrapCalcCBData {
float *proj_axis;
SpaceTransform *local2aux;
-} ShrinkwrapCalcCBData;
+};
bool BKE_shrinkwrap_needs_normals(int shrinkType, int shrinkMode)
{
@@ -99,7 +100,7 @@ bool BKE_shrinkwrap_init_tree(
{
memset(data, 0, sizeof(*data));
- if (mesh == NULL) {
+ if (mesh == nullptr) {
return false;
}
@@ -118,7 +119,7 @@ bool BKE_shrinkwrap_init_tree(
if (shrinkType == MOD_SHRINKWRAP_NEAREST_VERTEX) {
data->bvh = BKE_bvhtree_from_mesh_get(&data->treeData, mesh, BVHTREE_FROM_VERTS, 2);
- return data->bvh != NULL;
+ return data->bvh != nullptr;
}
if (mesh->totpoly <= 0) {
@@ -127,19 +128,19 @@ bool BKE_shrinkwrap_init_tree(
data->bvh = BKE_bvhtree_from_mesh_get(&data->treeData, mesh, BVHTREE_FROM_LOOPTRI, 4);
- if (data->bvh == NULL) {
+ if (data->bvh == nullptr) {
return false;
}
if (force_normals || BKE_shrinkwrap_needs_normals(shrinkType, shrinkMode)) {
data->pnors = BKE_mesh_poly_normals_ensure(mesh);
if ((mesh->flag & ME_AUTOSMOOTH) != 0) {
- data->clnors = CustomData_get_layer(&mesh->ldata, CD_NORMAL);
+ data->clnors = static_cast<const float(*)[3]>(CustomData_get_layer(&mesh->ldata, CD_NORMAL));
}
}
if (shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) {
- data->boundary = mesh->runtime.shrinkwrap_data;
+ data->boundary = mesh->runtime->shrinkwrap_data;
}
return true;
@@ -150,11 +151,11 @@ void BKE_shrinkwrap_free_tree(ShrinkwrapTreeData *data)
free_bvhtree_from_mesh(&data->treeData);
}
-void BKE_shrinkwrap_discard_boundary_data(struct Mesh *mesh)
+void BKE_shrinkwrap_discard_boundary_data(Mesh *mesh)
{
- struct ShrinkwrapBoundaryData *data = mesh->runtime.shrinkwrap_data;
+ ShrinkwrapBoundaryData *data = mesh->runtime->shrinkwrap_data;
- if (data != NULL) {
+ if (data != nullptr) {
MEM_freeN((void *)data->edge_is_boundary);
MEM_freeN((void *)data->looptri_has_boundary);
MEM_freeN((void *)data->vert_boundary_id);
@@ -163,7 +164,7 @@ void BKE_shrinkwrap_discard_boundary_data(struct Mesh *mesh)
MEM_freeN(data);
}
- mesh->runtime.shrinkwrap_data = NULL;
+ mesh->runtime->shrinkwrap_data = nullptr;
}
/* Accumulate edge for average boundary edge direction. */
@@ -190,17 +191,18 @@ static void merge_vert_dir(ShrinkwrapBoundaryVertData *vdata,
status[index] = (status[index] == 0) ? side : -1;
}
-static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(struct Mesh *mesh)
+static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh)
{
const MVert *mvert = BKE_mesh_verts(mesh);
const MEdge *medge = BKE_mesh_edges(mesh);
const MLoop *mloop = BKE_mesh_loops(mesh);
/* Count faces per edge (up to 2). */
- char *edge_mode = MEM_calloc_arrayN((size_t)mesh->totedge, sizeof(char), __func__);
+ char *edge_mode = static_cast<char *>(
+ MEM_calloc_arrayN(size_t(mesh->totedge), sizeof(char), __func__));
for (int i = 0; i < mesh->totloop; i++) {
- unsigned int eidx = mloop[i].e;
+ uint eidx = mloop[i].e;
if (edge_mode[eidx] < 2) {
edge_mode[eidx]++;
@@ -210,7 +212,7 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(struct Mesh *mesh)
/* Build the boundary edge bitmask. */
BLI_bitmap *edge_is_boundary = BLI_BITMAP_NEW(mesh->totedge,
"ShrinkwrapBoundaryData::edge_is_boundary");
- unsigned int num_boundary_edges = 0;
+ uint num_boundary_edges = 0;
for (int i = 0; i < mesh->totedge; i++) {
edge_mode[i] = (edge_mode[i] == 1);
@@ -221,16 +223,15 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(struct Mesh *mesh)
}
}
- /* If no boundary, return NULL. */
+ /* If no boundary, return nullptr. */
if (num_boundary_edges == 0) {
MEM_freeN(edge_is_boundary);
MEM_freeN(edge_mode);
- return NULL;
+ return nullptr;
}
/* Allocate the data object. */
- ShrinkwrapBoundaryData *data = MEM_callocN(sizeof(ShrinkwrapBoundaryData),
- "ShrinkwrapBoundaryData");
+ ShrinkwrapBoundaryData *data = MEM_cnew<ShrinkwrapBoundaryData>(__func__);
data->edge_is_boundary = edge_is_boundary;
@@ -256,8 +257,8 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(struct Mesh *mesh)
data->looptri_has_boundary = looptri_has_boundary;
/* Find boundary vertices and build a mapping table for compact storage of data. */
- int *vert_boundary_id = MEM_calloc_arrayN(
- (size_t)mesh->totvert, sizeof(int), "ShrinkwrapBoundaryData::vert_boundary_id");
+ int *vert_boundary_id = static_cast<int *>(
+ MEM_calloc_arrayN(size_t(mesh->totvert), sizeof(int), __func__));
for (int i = 0; i < mesh->totedge; i++) {
if (edge_mode[i]) {
@@ -268,20 +269,21 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(struct Mesh *mesh)
}
}
- unsigned int num_boundary_verts = 0;
+ uint num_boundary_verts = 0;
for (int i = 0; i < mesh->totvert; i++) {
- vert_boundary_id[i] = (vert_boundary_id[i] != 0) ? (int)num_boundary_verts++ : -1;
+ vert_boundary_id[i] = (vert_boundary_id[i] != 0) ? int(num_boundary_verts++) : -1;
}
data->vert_boundary_id = vert_boundary_id;
data->num_boundary_verts = num_boundary_verts;
/* Compute average directions. */
- ShrinkwrapBoundaryVertData *boundary_verts = MEM_calloc_arrayN(
- num_boundary_verts, sizeof(*boundary_verts), "ShrinkwrapBoundaryData::boundary_verts");
+ ShrinkwrapBoundaryVertData *boundary_verts = static_cast<ShrinkwrapBoundaryVertData *>(
+ MEM_calloc_arrayN(num_boundary_verts, sizeof(*boundary_verts), __func__));
- signed char *vert_status = MEM_calloc_arrayN(num_boundary_verts, sizeof(char), __func__);
+ signed char *vert_status = static_cast<signed char *>(
+ MEM_calloc_arrayN(num_boundary_verts, sizeof(char), __func__));
for (int i = 0; i < mesh->totedge; i++) {
if (edge_mode[i]) {
@@ -321,28 +323,28 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(struct Mesh *mesh)
return data;
}
-void BKE_shrinkwrap_compute_boundary_data(struct Mesh *mesh)
+void BKE_shrinkwrap_compute_boundary_data(Mesh *mesh)
{
BKE_shrinkwrap_discard_boundary_data(mesh);
- mesh->runtime.shrinkwrap_data = shrinkwrap_build_boundary_data(mesh);
+ mesh->runtime->shrinkwrap_data = shrinkwrap_build_boundary_data(mesh);
}
/**
* Shrink-wrap to the nearest vertex
*
- * it builds a #BVHTree of vertices we can attach to and then
- * for each vertex performs a nearest vertex search on the tree
+ * it builds a BVH-tree of vertices we can attach to and then
+ * for each vertex performs a nearest vertex search on the tree.
*/
static void shrinkwrap_calc_nearest_vertex_cb_ex(void *__restrict userdata,
const int i,
const TaskParallelTLS *__restrict tls)
{
- ShrinkwrapCalcCBData *data = userdata;
+ ShrinkwrapCalcCBData *data = static_cast<ShrinkwrapCalcCBData *>(userdata);
ShrinkwrapCalcData *calc = data->calc;
BVHTreeFromMesh *treeData = &data->tree->treeData;
- BVHTreeNearest *nearest = tls->userdata_chunk;
+ BVHTreeNearest *nearest = static_cast<BVHTreeNearest *>(tls->userdata_chunk);
float *co = calc->vertexCos[i];
float tmp_co[3];
@@ -404,10 +406,9 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
- ShrinkwrapCalcCBData data = {
- .calc = calc,
- .tree = calc->tree,
- };
+ ShrinkwrapCalcCBData data{};
+ data.calc = calc;
+ data.tree = calc->tree;
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (calc->numVerts > BKE_MESH_OMP_LIMIT);
@@ -496,7 +497,7 @@ static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata,
const int i,
const TaskParallelTLS *__restrict tls)
{
- ShrinkwrapCalcCBData *data = userdata;
+ ShrinkwrapCalcCBData *data = static_cast<ShrinkwrapCalcCBData *>(userdata);
ShrinkwrapCalcData *calc = data->calc;
ShrinkwrapTreeData *tree = data->tree;
@@ -505,7 +506,7 @@ static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata,
float *proj_axis = data->proj_axis;
SpaceTransform *local2aux = data->local2aux;
- BVHTreeRayHit *hit = tls->userdata_chunk;
+ BVHTreeRayHit *hit = static_cast<BVHTreeRayHit *>(tls->userdata_chunk);
const float proj_limit_squared = calc->smd->projLimit * calc->smd->projLimit;
float *co = calc->vertexCos[i];
@@ -520,7 +521,7 @@ static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata,
return;
}
- if (calc->vert != NULL && calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) {
+ if (calc->vert != nullptr && calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) {
/* calc->vert contains verts from evaluated mesh. */
/* These coordinates are deformed by vertexCos only for normal projection
* (to get correct normals) for other cases calc->verts contains undeformed coordinates and
@@ -535,12 +536,12 @@ static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata,
hit->index = -1;
- /* TODO: we should use FLT_MAX here, but sweepsphere code isn't prepared for that */
+ /* TODO: we should use FLT_MAX here, but sweep-sphere code isn't prepared for that. */
hit->dist = BVH_RAYCAST_DIST_MAX;
bool is_aux = false;
- /* Project over positive direction of axis */
+ /* Project over positive direction of axis. */
if (calc->smd->shrinkOpts & MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR) {
if (aux_tree) {
if (BKE_shrinkwrap_project_normal(0, tmp_co, tmp_no, 0.0, local2aux, aux_tree, hit)) {
@@ -627,8 +628,8 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
BVHTreeRayHit hit;
/* auxiliary target */
- Mesh *auxMesh = NULL;
- ShrinkwrapTreeData *aux_tree = NULL;
+ Mesh *auxMesh = nullptr;
+ ShrinkwrapTreeData *aux_tree = nullptr;
ShrinkwrapTreeData aux_tree_stack;
SpaceTransform local2aux;
@@ -641,7 +642,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
/* Prepare data to retrieve the direction in which we should project each vertex */
if (calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) {
- if (calc->vert == NULL) {
+ if (calc->vert == nullptr) {
return;
}
}
@@ -680,13 +681,12 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
}
/* After successfully build the trees, start projection vertices. */
- ShrinkwrapCalcCBData data = {
- .calc = calc,
- .tree = calc->tree,
- .aux_tree = aux_tree,
- .proj_axis = proj_axis,
- .local2aux = &local2aux,
- };
+ ShrinkwrapCalcCBData data{};
+ data.calc = calc;
+ data.tree = calc->tree;
+ data.aux_tree = aux_tree;
+ data.proj_axis = proj_axis;
+ data.local2aux = &local2aux;
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (calc->numVerts > BKE_MESH_OMP_LIMIT);
@@ -717,7 +717,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
//#define TRACE_TARGET_PROJECT
-typedef struct TargetProjectTriData {
+struct TargetProjectTriData {
const float **vtri_co;
const float (*vtri_no)[3];
const float *point_co;
@@ -727,12 +727,12 @@ typedef struct TargetProjectTriData {
/* Current interpolated position and normal. */
float co_interp[3], no_interp[3];
-} TargetProjectTriData;
+};
/* Computes the deviation of the equation system from goal. */
static void target_project_tri_deviation(void *userdata, const float x[3], float r_delta[3])
{
- TargetProjectTriData *data = userdata;
+ TargetProjectTriData *data = static_cast<TargetProjectTriData *>(userdata);
const float w[3] = {x[0], x[1], 1.0f - x[0] - x[1]};
interp_v3_v3v3v3(data->co_interp, data->vtri_co[0], data->vtri_co[1], data->vtri_co[2], w);
@@ -745,7 +745,7 @@ static void target_project_tri_deviation(void *userdata, const float x[3], float
/* Computes the Jacobian matrix of the equation system. */
static void target_project_tri_jacobian(void *userdata, const float x[3], float r_jacobian[3][3])
{
- TargetProjectTriData *data = userdata;
+ TargetProjectTriData *data = static_cast<TargetProjectTriData *>(userdata);
madd_v3_v3v3fl(r_jacobian[0], data->c0_minus_c2, data->n0_minus_n2, x[2]);
madd_v3_v3v3fl(r_jacobian[1], data->c1_minus_c2, data->n1_minus_n2, x[2]);
@@ -771,7 +771,7 @@ static void target_project_tri_clamp(float x[3])
}
/* Correct the Newton's method step to keep the coordinates within the triangle. */
-static bool target_project_tri_correct(void *UNUSED(userdata),
+static bool target_project_tri_correct(void * /*userdata*/,
const float x[3],
float step[3],
float x_next[3])
@@ -792,11 +792,11 @@ static bool target_project_tri_correct(void *UNUSED(userdata),
float ldist = 1.0f - sum;
/* If already at the boundary, slide along it. */
- if (ldist < epsilon * (float)M_SQRT2) {
+ if (ldist < epsilon * float(M_SQRT2)) {
float step_len = len_v2(step);
/* Abort if the solution is clearly outside the domain. */
- if (step_len > epsilon && sstep > step_len * dir_epsilon * (float)M_SQRT2) {
+ if (step_len > epsilon && sstep > step_len * dir_epsilon * float(M_SQRT2)) {
return false;
}
@@ -867,11 +867,10 @@ static bool target_project_solve_point_tri(const float *vtri_co[3],
x[2] = (dot_v3v3(tmp, r_hit_no) < 0) ? -dist : dist;
/* Solve the equations iteratively. */
- TargetProjectTriData tri_data = {
- .vtri_co = vtri_co,
- .vtri_no = vtri_no,
- .point_co = point_co,
- };
+ TargetProjectTriData tri_data{};
+ tri_data.vtri_co = vtri_co;
+ tri_data.vtri_no = vtri_no;
+ tri_data.point_co = point_co;
sub_v3_v3v3(tri_data.n0_minus_n2, vtri_no[0], vtri_no[2]);
sub_v3_v3v3(tri_data.n1_minus_n2, vtri_no[1], vtri_no[2]);
@@ -988,7 +987,7 @@ static void target_project_edge(const ShrinkwrapTreeData *tree,
float hit_co[3], hit_no[3];
for (int i = (det > 0 ? 2 : 0); i >= 0; i -= 2) {
- float x = (-b + ((float)i - 1) * sdet) / (2 * a);
+ float x = (-b + (float(i) - 1) * sdet) / (2 * a);
if (x >= -epsilon && x <= 1.0f + epsilon) {
CLAMP(x, 0, 1);
@@ -1064,7 +1063,7 @@ static void mesh_looptri_target_project(void *userdata,
}
}
-void BKE_shrinkwrap_find_nearest_surface(struct ShrinkwrapTreeData *tree,
+void BKE_shrinkwrap_find_nearest_surface(ShrinkwrapTreeData *tree,
BVHTreeNearest *nearest,
float co[3],
int type)
@@ -1093,20 +1092,20 @@ void BKE_shrinkwrap_find_nearest_surface(struct ShrinkwrapTreeData *tree,
}
}
-/*
- * Shrinkwrap moving vertexs to the nearest surface point on the target
+/**
+ * Shrink-wrap moving vertices to the nearest surface point on the target.
*
- * it builds a BVHTree from the target mesh and then performs a
+ * It builds a #BVHTree from the target mesh and then performs a
* NN matches for each vertex
*/
static void shrinkwrap_calc_nearest_surface_point_cb_ex(void *__restrict userdata,
const int i,
const TaskParallelTLS *__restrict tls)
{
- ShrinkwrapCalcCBData *data = userdata;
+ ShrinkwrapCalcCBData *data = static_cast<ShrinkwrapCalcCBData *>(userdata);
ShrinkwrapCalcData *calc = data->calc;
- BVHTreeNearest *nearest = tls->userdata_chunk;
+ BVHTreeNearest *nearest = static_cast<BVHTreeNearest *>(tls->userdata_chunk);
float *co = calc->vertexCos[i];
float tmp_co[3];
@@ -1153,7 +1152,7 @@ static void shrinkwrap_calc_nearest_surface_point_cb_ex(void *__restrict userdat
/* Found the nearest vertex */
if (nearest->index != -1) {
BKE_shrinkwrap_snap_point_to_surface(data->tree,
- NULL,
+ nullptr,
calc->smd->shrinkMode,
nearest->index,
nearest->co,
@@ -1168,8 +1167,8 @@ static void shrinkwrap_calc_nearest_surface_point_cb_ex(void *__restrict userdat
}
}
-void BKE_shrinkwrap_compute_smooth_normal(const struct ShrinkwrapTreeData *tree,
- const struct SpaceTransform *transform,
+void BKE_shrinkwrap_compute_smooth_normal(const ShrinkwrapTreeData *tree,
+ const SpaceTransform *transform,
int looptri_idx,
const float hit_co[3],
const float hit_no[3],
@@ -1223,7 +1222,7 @@ void BKE_shrinkwrap_compute_smooth_normal(const struct ShrinkwrapTreeData *tree,
}
}
/* Use the polygon normal if flat. */
- else if (tree->pnors != NULL) {
+ else if (tree->pnors != nullptr) {
copy_v3_v3(r_no, tree->pnors[tri->poly]);
}
/* Finally fallback to the looptri normal. */
@@ -1286,8 +1285,8 @@ static void shrinkwrap_snap_with_side(float r_point_co[3],
}
}
-void BKE_shrinkwrap_snap_point_to_surface(const struct ShrinkwrapTreeData *tree,
- const struct SpaceTransform *transform,
+void BKE_shrinkwrap_snap_point_to_surface(const ShrinkwrapTreeData *tree,
+ const SpaceTransform *transform,
int mode,
int hit_idx,
const float hit_co[3],
@@ -1352,10 +1351,9 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
nearest.dist_sq = FLT_MAX;
/* Find the nearest vertex */
- ShrinkwrapCalcCBData data = {
- .calc = calc,
- .tree = calc->tree,
- };
+ ShrinkwrapCalcCBData data{};
+ data.calc = calc;
+ data.tree = calc->tree;
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (calc->numVerts > BKE_MESH_OMP_LIMIT);
@@ -1367,7 +1365,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd,
const ModifierEvalContext *ctx,
- struct Scene *scene,
+ Scene *scene,
Object *ob,
Mesh *mesh,
const MDeformVert *dvert,
@@ -1376,15 +1374,15 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd,
int numVerts)
{
- DerivedMesh *ss_mesh = NULL;
+ DerivedMesh *ss_mesh = nullptr;
ShrinkwrapCalcData calc = NULL_ShrinkwrapCalcData;
/* remove loop dependencies on derived meshes (TODO should this be done elsewhere?) */
if (smd->target == ob) {
- smd->target = NULL;
+ smd->target = nullptr;
}
if (smd->auxTarget == ob) {
- smd->auxTarget = NULL;
+ smd->auxTarget = nullptr;
}
/* Configure Shrinkwrap calc data */
@@ -1396,7 +1394,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd,
calc.vgroup = defgrp_index;
calc.invert_vgroup = (smd->shrinkOpts & MOD_SHRINKWRAP_INVERT_VGROUP) != 0;
- if (smd->target != NULL) {
+ if (smd->target != nullptr) {
Object *ob_target = DEG_get_evaluated_object(ctx->depsgraph, smd->target);
calc.target = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob_target);
@@ -1410,14 +1408,14 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd,
}
calc.aux_target = DEG_get_evaluated_object(ctx->depsgraph, smd->auxTarget);
- if (mesh != NULL && smd->shrinkType == MOD_SHRINKWRAP_PROJECT) {
- /* Setup arrays to get vertexs positions, normals and deform weights */
+ if (mesh != nullptr && smd->shrinkType == MOD_SHRINKWRAP_PROJECT) {
+ /* Setup arrays to get vertices position, normals and deform weights. */
calc.vert = BKE_mesh_verts_for_write(mesh);
calc.vert_normals = BKE_mesh_vertex_normals_ensure(mesh);
- /* Using vertexs positions/normals as if a subsurface was applied */
+ /* Using vertices positions/normals as if a subsurface was applied */
if (smd->subsurfLevels) {
- SubsurfModifierData ssmd = {{NULL}};
+ SubsurfModifierData ssmd = {{nullptr}};
ssmd.subdivType = ME_CC_SUBSURF; /* catmull clark */
ssmd.levels = smd->subsurfLevels; /* levels */
@@ -1425,10 +1423,14 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd,
DerivedMesh *dm = CDDM_from_mesh(mesh);
ss_mesh = subsurf_make_derived_from_derived(
- dm, &ssmd, scene, NULL, (ob->mode & OB_MODE_EDIT) ? SUBSURF_IN_EDIT_MODE : 0);
+ dm,
+ &ssmd,
+ scene,
+ nullptr,
+ (ob->mode & OB_MODE_EDIT) ? SUBSURF_IN_EDIT_MODE : SubsurfFlags(0));
if (ss_mesh) {
- calc.vert = ss_mesh->getVertDataArray(ss_mesh, CD_MVERT);
+ calc.vert = static_cast<MVert *>(ss_mesh->getVertDataArray(ss_mesh, CD_MVERT));
if (calc.vert) {
/* TRICKY: this code assumes subsurface will have the transformed original vertices
* in their original order at the end of the vert array. */
@@ -1437,8 +1439,8 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd,
}
/* Just to make sure we are not leaving any memory behind */
- BLI_assert(ssmd.emCache == NULL);
- BLI_assert(ssmd.mCache == NULL);
+ BLI_assert(ssmd.emCache == nullptr);
+ BLI_assert(ssmd.mCache == nullptr);
dm->release(dm);
}
@@ -1523,14 +1525,12 @@ void shrinkwrapGpencilModifier_deform(ShrinkwrapGpencilModifierData *mmd,
}
}
-void BKE_shrinkwrap_mesh_nearest_surface_deform(struct bContext *C,
- Object *ob_source,
- Object *ob_target)
+void BKE_shrinkwrap_mesh_nearest_surface_deform(bContext *C, Object *ob_source, Object *ob_target)
{
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
- struct Scene *sce = CTX_data_scene(C);
+ Scene *sce = CTX_data_scene(C);
ShrinkwrapModifierData ssmd = {{0}};
- ModifierEvalContext ctx = {depsgraph, ob_source, 0};
+ ModifierEvalContext ctx = {depsgraph, ob_source, ModifierApplyFlag(0)};
int totvert;
ssmd.target = ob_target;
@@ -1538,10 +1538,10 @@ void BKE_shrinkwrap_mesh_nearest_surface_deform(struct bContext *C,
ssmd.shrinkMode = MOD_SHRINKWRAP_ON_SURFACE;
ssmd.keepDist = 0.0f;
- Mesh *src_me = ob_source->data;
+ Mesh *src_me = static_cast<Mesh *>(ob_source->data);
float(*vertexCos)[3] = BKE_mesh_vert_coords_alloc(src_me, &totvert);
- shrinkwrapModifier_deform(&ssmd, &ctx, sce, ob_source, src_me, NULL, -1, vertexCos, totvert);
+ shrinkwrapModifier_deform(&ssmd, &ctx, sce, ob_source, src_me, nullptr, -1, vertexCos, totvert);
BKE_mesh_vert_coords_apply(src_me, vertexCos);
diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc
index 9d4d6a4e350..f399becfa89 100644
--- a/source/blender/blenkernel/intern/simulation.cc
+++ b/source/blender/blenkernel/intern/simulation.cc
@@ -167,8 +167,8 @@ void *BKE_simulation_add(Main *bmain, const char *name)
return simulation;
}
-void BKE_simulation_data_update(Depsgraph *UNUSED(depsgraph),
- Scene *UNUSED(scene),
- Simulation *UNUSED(simulation))
+void BKE_simulation_data_update(Depsgraph * /*depsgraph*/,
+ Scene * /*scene*/,
+ Simulation * /*simulation*/)
{
}
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index d1451353feb..efe423ccfc5 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -133,9 +133,9 @@ typedef struct SB_thread_context {
#define BSF_INTERSECT 1 /* edge intersects collider face */
-/* private definitions for bodypoint states */
-#define SBF_DOFUZZY 1 /* Bodypoint do fuzzy. */
-#define SBF_OUTOFCOLLISION 2 /* Bodypoint does not collide. */
+/* private definitions for body-point states */
+#define SBF_DOFUZZY 1 /* Body-point do fuzzy. */
+#define SBF_OUTOFCOLLISION 2 /* Body-point does not collide. */
#define BFF_INTERSECT 1 /* collider edge intrudes face. */
#define BFF_CLOSEVERT 2 /* collider vertex repulses face. */
@@ -318,7 +318,7 @@ static ccd_Mesh *ccd_mesh_make(Object *ob)
/* OBBs for idea1 */
pccd_M->mima = MEM_mallocN(sizeof(ccdf_minmax) * pccd_M->tri_num, "ccd_Mesh_Faces_mima");
- /* anyhoo we need to walk the list of faces and find OBB they live in */
+ /* Anyhow we need to walk the list of faces and find OBB they live in. */
for (i = 0, mima = pccd_M->mima, vt = pccd_M->tri; i < pccd_M->tri_num; i++, mima++, vt++) {
const float *v;
@@ -413,7 +413,7 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
pccd_M->bbmax[2] = max_ff(pccd_M->bbmax[2], v[2] + hull);
}
- /* anyhoo we need to walk the list of faces and find OBB they live in */
+ /* Anyhow we need to walk the list of faces and find OBB they live in. */
for (i = 0, mima = pccd_M->mima, vt = pccd_M->tri; i < pccd_M->tri_num; i++, mima++, vt++) {
const float *v;
@@ -510,7 +510,7 @@ static void ccd_build_deflector_hash(Depsgraph *depsgraph,
return;
}
- unsigned int numobjects;
+ uint numobjects;
Object **objects = BKE_collision_objects_create(
depsgraph, vertexowner, collection, &numobjects, eModifierType_Collision);
@@ -547,7 +547,7 @@ static void ccd_update_deflector_hash(Depsgraph *depsgraph,
return;
}
- unsigned int numobjects;
+ uint numobjects;
Object **objects = BKE_collision_objects_create(
depsgraph, vertexowner, collection, &numobjects, eModifierType_Collision);
@@ -750,10 +750,10 @@ static void build_bps_springlist(Object *ob)
}
/* scan for attached inner springs */
for (b = sb->totspring, bs = sb->bspring; b > 0; b--, bs++) {
- if (((sb->totpoint - a) == bs->v1)) {
+ if ((sb->totpoint - a) == bs->v1) {
add_bp_springlist(bp, sb->totspring - b);
}
- if (((sb->totpoint - a) == bs->v2)) {
+ if ((sb->totpoint - a) == bs->v2) {
add_bp_springlist(bp, sb->totspring - b);
}
} /* For springs. */
@@ -963,7 +963,7 @@ static void free_softbody_intern(SoftBody *sb)
*/
static int query_external_colliders(Depsgraph *depsgraph, Collection *collection)
{
- unsigned int numobjects;
+ uint numobjects;
Object **objects = BKE_collision_objects_create(
depsgraph, NULL, collection, &numobjects, eModifierType_Collision);
BKE_collision_objects_free(objects);
@@ -2644,7 +2644,7 @@ static void springs_from_mesh(Object *ob)
bp = ob->soft->bpoint;
for (a = 0; a < me->totvert; a++, bp++) {
copy_v3_v3(bp->origS, verts[a].co);
- mul_m4_v3(ob->obmat, bp->origS);
+ mul_m4_v3(ob->object_to_world, bp->origS);
}
}
/* recalculate spring length for meshes here */
@@ -2809,9 +2809,9 @@ static float globallen(float *v1, float *v2, Object *ob)
{
float p1[3], p2[3];
copy_v3_v3(p1, v1);
- mul_m4_v3(ob->obmat, p1);
+ mul_m4_v3(ob->object_to_world, p1);
copy_v3_v3(p2, v2);
- mul_m4_v3(ob->obmat, p2);
+ mul_m4_v3(ob->object_to_world, p2);
return len_v3v3(p1, p2);
}
@@ -3073,12 +3073,13 @@ static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts,
SB_estimate_transform(ob, sb->lcom, sb->lrot, sb->lscale);
}
/* Inverse matrix is not up to date. */
- invert_m4_m4(ob->imat, ob->obmat);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
for (a = 0; a < numVerts; a++, bp++) {
copy_v3_v3(vertexCos[a], bp->pos);
if (local == 0) {
- mul_m4_v3(ob->imat, vertexCos[a]); /* softbody is in global coords, baked optionally not */
+ mul_m4_v3(ob->world_to_object,
+ vertexCos[a]); /* softbody is in global coords, baked optionally not */
}
}
}
@@ -3223,7 +3224,7 @@ static void softbody_update_positions(Object *ob,
/* copy the position of the goals at desired end time */
copy_v3_v3(bp->origE, vertexCos[a]);
/* vertexCos came from local world, go global */
- mul_m4_v3(ob->obmat, bp->origE);
+ mul_m4_v3(ob->object_to_world, bp->origE);
/* just to be save give bp->origT a defined value
* will be calculated in interpolate_exciter() */
copy_v3_v3(bp->origT, bp->origE);
@@ -3279,7 +3280,7 @@ static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int
for (a = 0, bp = sb->bpoint; a < numVerts; a++, bp++) {
copy_v3_v3(bp->pos, vertexCos[a]);
- mul_m4_v3(ob->obmat, bp->pos); /* Yep, soft-body is global coords. */
+ mul_m4_v3(ob->object_to_world, bp->pos); /* Yep, soft-body is global coords. */
copy_v3_v3(bp->origS, bp->pos);
copy_v3_v3(bp->origE, bp->pos);
copy_v3_v3(bp->origT, bp->pos);
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index de1d0d3c30e..51a20cf1e35 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -556,7 +556,7 @@ static void sound_load_audio(Main *bmain, bSound *sound, bool free_waveform)
/* but we need a packed file then */
if (pf) {
- sound->handle = AUD_Sound_bufferFile((unsigned char *)pf->data, pf->size);
+ sound->handle = AUD_Sound_bufferFile((uchar *)pf->data, pf->size);
}
else {
/* or else load it from disk */
@@ -1025,7 +1025,7 @@ void BKE_sound_free_waveform(bSound *sound)
sound->tags &= ~SOUND_TAGS_WAVEFORM_NO_RELOAD;
}
-void BKE_sound_read_waveform(Main *bmain, bSound *sound, short *stop)
+void BKE_sound_read_waveform(Main *bmain, bSound *sound, bool *stop)
{
bool need_close_audio_handles = false;
if (sound->playback_handle == NULL) {
@@ -1041,8 +1041,11 @@ void BKE_sound_read_waveform(Main *bmain, bSound *sound, short *stop)
int length = info.length * SOUND_WAVE_SAMPLES_PER_SECOND;
waveform->data = MEM_mallocN(sizeof(float[3]) * length, "SoundWaveform.samples");
+ /* Ideally this would take a boolean argument. */
+ short stop_i16 = *stop;
waveform->length = AUD_readSound(
- sound->playback_handle, waveform->data, length, SOUND_WAVE_SAMPLES_PER_SECOND, stop);
+ sound->playback_handle, waveform->data, length, SOUND_WAVE_SAMPLES_PER_SECOND, &stop_i16);
+ *stop = stop_i16 != 0;
}
else {
/* Create an empty waveform here if the sound couldn't be
@@ -1129,9 +1132,9 @@ static void sound_update_base(Scene *scene, Object *object, void *new_set)
AUD_SequenceEntry_setConeAngleInner(strip->speaker_handle, speaker->cone_angle_inner);
AUD_SequenceEntry_setConeVolumeOuter(strip->speaker_handle, speaker->cone_volume_outer);
- mat4_to_quat(quat, object->obmat);
+ mat4_to_quat(quat, object->object_to_world);
AUD_SequenceEntry_setAnimationData(
- strip->speaker_handle, AUD_AP_LOCATION, scene->r.cfra, object->obmat[3], 1);
+ strip->speaker_handle, AUD_AP_LOCATION, scene->r.cfra, object->object_to_world[3], 1);
AUD_SequenceEntry_setAnimationData(
strip->speaker_handle, AUD_AP_ORIENTATION, scene->r.cfra, quat, 1);
AUD_SequenceEntry_setAnimationData(
@@ -1155,11 +1158,12 @@ void BKE_sound_update_scene(Depsgraph *depsgraph, Scene *scene)
/* cheap test to skip looping over all objects (no speakers is a common case) */
if (DEG_id_type_any_exists(depsgraph, ID_SPK)) {
- DEG_OBJECT_ITER_BEGIN (depsgraph,
- object,
- (DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
- DEG_ITER_OBJECT_FLAG_LINKED_INDIRECTLY |
- DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET)) {
+ DEGObjectIterSettings deg_iter_settings = {0};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_INDIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, object) {
sound_update_base(scene, object, new_set);
}
DEG_OBJECT_ITER_END;
@@ -1170,9 +1174,9 @@ void BKE_sound_update_scene(Depsgraph *depsgraph, Scene *scene)
}
if (scene->camera) {
- mat4_to_quat(quat, scene->camera->obmat);
+ mat4_to_quat(quat, scene->camera->object_to_world);
AUD_Sequence_setAnimationData(
- scene->sound_scene, AUD_AP_LOCATION, scene->r.cfra, scene->camera->obmat[3], 1);
+ scene->sound_scene, AUD_AP_LOCATION, scene->r.cfra, scene->camera->object_to_world[3], 1);
AUD_Sequence_setAnimationData(scene->sound_scene, AUD_AP_ORIENTATION, scene->r.cfra, quat, 1);
}
@@ -1380,7 +1384,7 @@ int BKE_sound_scene_playing(Scene *UNUSED(scene))
void BKE_sound_read_waveform(Main *bmain,
bSound *sound,
/* NOLINTNEXTLINE: readability-non-const-parameter. */
- short *stop)
+ bool *stop)
{
UNUSED_VARS(sound, stop, bmain);
}
diff --git a/source/blender/blenkernel/intern/spline_base.cc b/source/blender/blenkernel/intern/spline_base.cc
deleted file mode 100644
index a674bf7800a..00000000000
--- a/source/blender/blenkernel/intern/spline_base.cc
+++ /dev/null
@@ -1,526 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_array.hh"
-#include "BLI_generic_virtual_array.hh"
-#include "BLI_span.hh"
-#include "BLI_task.hh"
-#include "BLI_timeit.hh"
-
-#include "BKE_attribute_math.hh"
-#include "BKE_spline.hh"
-
-using blender::Array;
-using blender::float3;
-using blender::GMutableSpan;
-using blender::GSpan;
-using blender::GVArray;
-using blender::IndexRange;
-using blender::MutableSpan;
-using blender::Span;
-using blender::VArray;
-using blender::attribute_math::convert_to_static_type;
-using blender::bke::AttributeIDRef;
-using blender::bke::AttributeMetaData;
-
-CurveType Spline::type() const
-{
- return type_;
-}
-
-void Spline::copy_base_settings(const Spline &src, Spline &dst)
-{
- dst.normal_mode = src.normal_mode;
- dst.is_cyclic_ = src.is_cyclic_;
-}
-
-static SplinePtr create_spline(const CurveType type)
-{
- switch (type) {
- case CURVE_TYPE_POLY:
- return std::make_unique<PolySpline>();
- case CURVE_TYPE_BEZIER:
- return std::make_unique<BezierSpline>();
- case CURVE_TYPE_NURBS:
- return std::make_unique<NURBSpline>();
- case CURVE_TYPE_CATMULL_ROM:
- BLI_assert_unreachable();
- return {};
- }
- BLI_assert_unreachable();
- return {};
-}
-
-SplinePtr Spline::copy() const
-{
- SplinePtr dst = this->copy_without_attributes();
- dst->attributes = this->attributes;
- return dst;
-}
-
-SplinePtr Spline::copy_only_settings() const
-{
- SplinePtr dst = create_spline(type_);
- this->copy_base_settings(*this, *dst);
- this->copy_settings(*dst);
- return dst;
-}
-
-SplinePtr Spline::copy_without_attributes() const
-{
- SplinePtr dst = this->copy_only_settings();
- this->copy_data(*dst);
-
- /* Though the attributes storage is empty, it still needs to know the correct size. */
- dst->attributes.reallocate(dst->size());
- return dst;
-}
-
-void Spline::translate(const blender::float3 &translation)
-{
- for (float3 &position : this->positions()) {
- position += translation;
- }
- this->mark_cache_invalid();
-}
-
-void Spline::transform(const blender::float4x4 &matrix)
-{
- for (float3 &position : this->positions()) {
- position = matrix * position;
- }
- this->mark_cache_invalid();
-}
-
-void Spline::reverse()
-{
- this->positions().reverse();
- this->radii().reverse();
- this->tilts().reverse();
-
- this->attributes.foreach_attribute(
- [&](const AttributeIDRef &id, const AttributeMetaData &meta_data) {
- std::optional<blender::GMutableSpan> attribute = this->attributes.get_for_write(id);
- if (!attribute) {
- BLI_assert_unreachable();
- return false;
- }
- convert_to_static_type(meta_data.data_type, [&](auto dummy) {
- using T = decltype(dummy);
- attribute->typed<T>().reverse();
- });
- return true;
- },
- ATTR_DOMAIN_POINT);
-
- this->reverse_impl();
- this->mark_cache_invalid();
-}
-
-int Spline::evaluated_edges_num() const
-{
- const int eval_num = this->evaluated_points_num();
- if (eval_num < 2) {
- /* Two points are required for an edge. */
- return 0;
- }
-
- return this->is_cyclic_ ? eval_num : eval_num - 1;
-}
-
-float Spline::length() const
-{
- Span<float> lengths = this->evaluated_lengths();
- return lengths.is_empty() ? 0.0f : this->evaluated_lengths().last();
-}
-
-int Spline::segments_num() const
-{
- const int num = this->size();
-
- return is_cyclic_ ? num : num - 1;
-}
-
-bool Spline::is_cyclic() const
-{
- return is_cyclic_;
-}
-
-void Spline::set_cyclic(const bool value)
-{
- is_cyclic_ = value;
-}
-
-static void accumulate_lengths(Span<float3> positions,
- const bool is_cyclic,
- MutableSpan<float> lengths)
-{
- using namespace blender::math;
-
- float length = 0.0f;
- for (const int i : IndexRange(positions.size() - 1)) {
- length += distance(positions[i], positions[i + 1]);
- lengths[i] = length;
- }
- if (is_cyclic) {
- lengths.last() = length + distance(positions.last(), positions.first());
- }
-}
-
-Span<float> Spline::evaluated_lengths() const
-{
- if (!length_cache_dirty_) {
- return evaluated_lengths_cache_;
- }
-
- std::lock_guard lock{length_cache_mutex_};
- if (!length_cache_dirty_) {
- return evaluated_lengths_cache_;
- }
-
- const int total = evaluated_edges_num();
- evaluated_lengths_cache_.resize(total);
- if (total != 0) {
- Span<float3> positions = this->evaluated_positions();
- accumulate_lengths(positions, is_cyclic_, evaluated_lengths_cache_);
- }
-
- length_cache_dirty_ = false;
- return evaluated_lengths_cache_;
-}
-
-static float3 direction_bisect(const float3 &prev, const float3 &middle, const float3 &next)
-{
- using namespace blender::math;
-
- const float3 dir_prev = normalize(middle - prev);
- const float3 dir_next = normalize(next - middle);
-
- const float3 result = normalize(dir_prev + dir_next);
- if (UNLIKELY(is_zero(result))) {
- return float3(0.0f, 0.0f, 1.0f);
- }
- return result;
-}
-
-static void calculate_tangents(Span<float3> positions,
- const bool is_cyclic,
- MutableSpan<float3> tangents)
-{
- using namespace blender::math;
-
- if (positions.size() == 1) {
- tangents.first() = float3(0.0f, 0.0f, 1.0f);
- return;
- }
-
- for (const int i : IndexRange(1, positions.size() - 2)) {
- tangents[i] = direction_bisect(positions[i - 1], positions[i], positions[i + 1]);
- }
-
- if (is_cyclic) {
- const float3 &second_to_last = positions[positions.size() - 2];
- const float3 &last = positions.last();
- const float3 &first = positions.first();
- const float3 &second = positions[1];
- tangents.first() = direction_bisect(last, first, second);
- tangents.last() = direction_bisect(second_to_last, last, first);
- }
- else {
- tangents.first() = normalize(positions[1] - positions[0]);
- tangents.last() = normalize(positions.last() - positions[positions.size() - 2]);
- }
-}
-
-Span<float3> Spline::evaluated_tangents() const
-{
- if (!tangent_cache_dirty_) {
- return evaluated_tangents_cache_;
- }
-
- std::lock_guard lock{tangent_cache_mutex_};
- if (!tangent_cache_dirty_) {
- return evaluated_tangents_cache_;
- }
-
- const int eval_num = this->evaluated_points_num();
- evaluated_tangents_cache_.resize(eval_num);
-
- Span<float3> positions = this->evaluated_positions();
-
- calculate_tangents(positions, is_cyclic_, evaluated_tangents_cache_);
- this->correct_end_tangents();
-
- tangent_cache_dirty_ = false;
- return evaluated_tangents_cache_;
-}
-
-static float3 rotate_direction_around_axis(const float3 &direction,
- const float3 &axis,
- const float angle)
-{
- using namespace blender::math;
-
- BLI_ASSERT_UNIT_V3(direction);
- BLI_ASSERT_UNIT_V3(axis);
-
- const float3 axis_scaled = axis * dot(direction, axis);
- const float3 diff = direction - axis_scaled;
- const float3 cross = blender::math::cross(axis, diff);
-
- return axis_scaled + diff * std::cos(angle) + cross * std::sin(angle);
-}
-
-static void calculate_normals_z_up(Span<float3> tangents, MutableSpan<float3> r_normals)
-{
- using namespace blender::math;
-
- BLI_assert(r_normals.size() == tangents.size());
-
- /* Same as in `vec_to_quat`. */
- const float epsilon = 1e-4f;
- for (const int i : r_normals.index_range()) {
- const float3 &tangent = tangents[i];
- if (fabsf(tangent.x) + fabsf(tangent.y) < epsilon) {
- r_normals[i] = {1.0f, 0.0f, 0.0f};
- }
- else {
- r_normals[i] = normalize(float3(tangent.y, -tangent.x, 0.0f));
- }
- }
-}
-
-/**
- * Rotate the last normal in the same way the tangent has been rotated.
- */
-static float3 calculate_next_normal(const float3 &last_normal,
- const float3 &last_tangent,
- const float3 &current_tangent)
-{
- using namespace blender::math;
-
- if (is_zero(last_tangent) || is_zero(current_tangent)) {
- return last_normal;
- }
- const float angle = angle_normalized_v3v3(last_tangent, current_tangent);
- if (angle != 0.0) {
- const float3 axis = normalize(cross(last_tangent, current_tangent));
- return rotate_direction_around_axis(last_normal, axis, angle);
- }
- return last_normal;
-}
-
-static void calculate_normals_minimum(Span<float3> tangents,
- const bool cyclic,
- MutableSpan<float3> r_normals)
-{
- using namespace blender::math;
- BLI_assert(r_normals.size() == tangents.size());
-
- if (r_normals.is_empty()) {
- return;
- }
-
- const float epsilon = 1e-4f;
-
- /* Set initial normal. */
- const float3 &first_tangent = tangents[0];
- if (fabs(first_tangent.x) + fabs(first_tangent.y) < epsilon) {
- r_normals[0] = {1.0f, 0.0f, 0.0f};
- }
- else {
- r_normals[0] = normalize(float3(first_tangent.y, -first_tangent.x, 0.0f));
- }
-
- /* Forward normal with minimum twist along the entire spline. */
- for (const int i : IndexRange(1, r_normals.size() - 1)) {
- r_normals[i] = calculate_next_normal(r_normals[i - 1], tangents[i - 1], tangents[i]);
- }
-
- if (!cyclic) {
- return;
- }
-
- /* Compute how much the first normal deviates from the normal that has been forwarded along the
- * entire cyclic spline. */
- const float3 uncorrected_last_normal = calculate_next_normal(
- r_normals.last(), tangents.last(), tangents[0]);
- float correction_angle = angle_signed_on_axis_v3v3_v3(
- r_normals[0], uncorrected_last_normal, tangents[0]);
- if (correction_angle > M_PI) {
- correction_angle = correction_angle - 2 * M_PI;
- }
-
- /* Gradually apply correction by rotating all normals slightly. */
- const float angle_step = correction_angle / r_normals.size();
- for (const int i : r_normals.index_range()) {
- const float angle = angle_step * i;
- r_normals[i] = rotate_direction_around_axis(r_normals[i], tangents[i], angle);
- }
-}
-
-Span<float3> Spline::evaluated_normals() const
-{
- if (!normal_cache_dirty_) {
- return evaluated_normals_cache_;
- }
-
- std::lock_guard lock{normal_cache_mutex_};
- if (!normal_cache_dirty_) {
- return evaluated_normals_cache_;
- }
-
- const int eval_num = this->evaluated_points_num();
- evaluated_normals_cache_.resize(eval_num);
-
- Span<float3> tangents = this->evaluated_tangents();
- MutableSpan<float3> normals = evaluated_normals_cache_;
-
- /* Only Z up normals are supported at the moment. */
- switch (this->normal_mode) {
- case NORMAL_MODE_Z_UP: {
- calculate_normals_z_up(tangents, normals);
- break;
- }
- case NORMAL_MODE_MINIMUM_TWIST: {
- calculate_normals_minimum(tangents, is_cyclic_, normals);
- break;
- }
- }
-
- /* Rotate the generated normals with the interpolated tilt data. */
- VArray<float> tilts = this->interpolate_to_evaluated(this->tilts());
- for (const int i : normals.index_range()) {
- normals[i] = rotate_direction_around_axis(normals[i], tangents[i], tilts[i]);
- }
-
- normal_cache_dirty_ = false;
- return evaluated_normals_cache_;
-}
-
-Spline::LookupResult Spline::lookup_evaluated_factor(const float factor) const
-{
- return this->lookup_evaluated_length(this->length() * factor);
-}
-
-Spline::LookupResult Spline::lookup_evaluated_length(const float length) const
-{
- BLI_assert(length >= 0.0f && length <= this->length());
-
- Span<float> lengths = this->evaluated_lengths();
-
- const float *offset = std::lower_bound(lengths.begin(), lengths.end(), length);
- const int index = offset - lengths.begin();
- const int next_index = (index == this->evaluated_points_num() - 1) ? 0 : index + 1;
-
- const float previous_length = (index == 0) ? 0.0f : lengths[index - 1];
- const float length_in_segment = length - previous_length;
- const float segment_length = lengths[index] - previous_length;
- const float factor = segment_length == 0.0f ? 0.0f : length_in_segment / segment_length;
-
- return LookupResult{index, next_index, factor};
-}
-
-Array<float> Spline::sample_uniform_index_factors(const int samples_num) const
-{
- const Span<float> lengths = this->evaluated_lengths();
-
- BLI_assert(samples_num > 0);
- Array<float> samples(samples_num);
-
- samples[0] = 0.0f;
- if (samples_num == 1) {
- return samples;
- }
-
- const float total_length = this->length();
- const float sample_length = total_length / (samples_num - (is_cyclic_ ? 0 : 1));
-
- /* Store the length at the previous evaluated point in a variable so it can
- * start out at zero (the lengths array doesn't contain 0 for the first point). */
- float prev_length = 0.0f;
- int i_sample = 1;
- for (const int i_evaluated : IndexRange(this->evaluated_edges_num())) {
- const float length = lengths[i_evaluated];
-
- /* Add every sample that fits in this evaluated edge. */
- while ((sample_length * i_sample) < length && i_sample < samples_num) {
- const float factor = (sample_length * i_sample - prev_length) / (length - prev_length);
- samples[i_sample] = i_evaluated + factor;
- i_sample++;
- }
-
- prev_length = length;
- }
-
- /* Zero lengths or float inaccuracies can cause invalid values, or simply
- * skip some, so set the values that weren't completed in the main loop. */
- for (const int i : IndexRange(i_sample, samples_num - i_sample)) {
- samples[i] = float(samples_num);
- }
-
- if (!is_cyclic_) {
- /* In rare cases this can prevent overflow of the stored index. */
- samples.last() = lengths.size();
- }
-
- return samples;
-}
-
-Spline::LookupResult Spline::lookup_data_from_index_factor(const float index_factor) const
-{
- const int eval_num = this->evaluated_points_num();
-
- if (is_cyclic_) {
- if (index_factor < eval_num) {
- const int index = std::floor(index_factor);
- const int next_index = (index < eval_num - 1) ? index + 1 : 0;
- return LookupResult{index, next_index, index_factor - index};
- }
- return LookupResult{eval_num - 1, 0, 1.0f};
- }
-
- if (index_factor < eval_num - 1) {
- const int index = std::floor(index_factor);
- const int next_index = index + 1;
- return LookupResult{index, next_index, index_factor - index};
- }
- return LookupResult{eval_num - 2, eval_num - 1, 1.0f};
-}
-
-void Spline::bounds_min_max(float3 &min, float3 &max, const bool use_evaluated) const
-{
- Span<float3> positions = use_evaluated ? this->evaluated_positions() : this->positions();
- for (const float3 &position : positions) {
- minmax_v3v3_v3(min, max, position);
- }
-}
-
-GVArray Spline::interpolate_to_evaluated(GSpan data) const
-{
- return this->interpolate_to_evaluated(GVArray::ForSpan(data));
-}
-
-void Spline::sample_with_index_factors(const GVArray &src,
- Span<float> index_factors,
- GMutableSpan dst) const
-{
- BLI_assert(src.size() == this->evaluated_points_num());
-
- blender::attribute_math::convert_to_static_type(src.type(), [&](auto dummy) {
- using T = decltype(dummy);
- const VArray<T> src_typed = src.typed<T>();
- MutableSpan<T> dst_typed = dst.typed<T>();
- if (src.size() == 1) {
- dst_typed.fill(src_typed[0]);
- return;
- }
- blender::threading::parallel_for(dst_typed.index_range(), 1024, [&](IndexRange range) {
- for (const int i : range) {
- const LookupResult interp = this->lookup_data_from_index_factor(index_factors[i]);
- dst_typed[i] = blender::attribute_math::mix2(interp.factor,
- src_typed[interp.evaluated_index],
- src_typed[interp.next_evaluated_index]);
- }
- });
- });
-}
diff --git a/source/blender/blenkernel/intern/spline_bezier.cc b/source/blender/blenkernel/intern/spline_bezier.cc
deleted file mode 100644
index 80515d0ef37..00000000000
--- a/source/blender/blenkernel/intern/spline_bezier.cc
+++ /dev/null
@@ -1,646 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_array.hh"
-#include "BLI_span.hh"
-#include "BLI_task.hh"
-
-#include "BKE_spline.hh"
-
-using blender::Array;
-using blender::float3;
-using blender::GVArray;
-using blender::IndexRange;
-using blender::MutableSpan;
-using blender::Span;
-using blender::VArray;
-
-void BezierSpline::copy_settings(Spline &dst) const
-{
- BezierSpline &bezier = static_cast<BezierSpline &>(dst);
- bezier.resolution_ = resolution_;
-}
-
-void BezierSpline::copy_data(Spline &dst) const
-{
- BezierSpline &bezier = static_cast<BezierSpline &>(dst);
- bezier.positions_ = positions_;
- bezier.handle_types_left_ = handle_types_left_;
- bezier.handle_positions_left_ = handle_positions_left_;
- bezier.handle_types_right_ = handle_types_right_;
- bezier.handle_positions_right_ = handle_positions_right_;
- bezier.radii_ = radii_;
- bezier.tilts_ = tilts_;
-}
-
-int BezierSpline::size() const
-{
- const int size = positions_.size();
- BLI_assert(size == handle_types_left_.size());
- BLI_assert(size == handle_positions_left_.size());
- BLI_assert(size == handle_types_right_.size());
- BLI_assert(size == handle_positions_right_.size());
- BLI_assert(size == radii_.size());
- BLI_assert(size == tilts_.size());
- return size;
-}
-
-int BezierSpline::resolution() const
-{
- return resolution_;
-}
-
-void BezierSpline::set_resolution(const int value)
-{
- BLI_assert(value > 0);
- resolution_ = value;
- this->mark_cache_invalid();
-}
-
-void BezierSpline::resize(const int size)
-{
- handle_types_left_.resize(size);
- handle_positions_left_.resize(size);
- positions_.resize(size);
- handle_types_right_.resize(size);
- handle_positions_right_.resize(size);
- radii_.resize(size);
- tilts_.resize(size);
- this->mark_cache_invalid();
- attributes.reallocate(size);
-}
-
-MutableSpan<float3> BezierSpline::positions()
-{
- return positions_;
-}
-Span<float3> BezierSpline::positions() const
-{
- return positions_;
-}
-MutableSpan<float> BezierSpline::radii()
-{
- return radii_;
-}
-Span<float> BezierSpline::radii() const
-{
- return radii_;
-}
-MutableSpan<float> BezierSpline::tilts()
-{
- return tilts_;
-}
-Span<float> BezierSpline::tilts() const
-{
- return tilts_;
-}
-Span<int8_t> BezierSpline::handle_types_left() const
-{
- return handle_types_left_;
-}
-MutableSpan<int8_t> BezierSpline::handle_types_left()
-{
- return handle_types_left_;
-}
-Span<float3> BezierSpline::handle_positions_left() const
-{
- this->ensure_auto_handles();
- return handle_positions_left_;
-}
-MutableSpan<float3> BezierSpline::handle_positions_left(const bool write_only)
-{
- if (!write_only) {
- this->ensure_auto_handles();
- }
- return handle_positions_left_;
-}
-
-Span<int8_t> BezierSpline::handle_types_right() const
-{
- return handle_types_right_;
-}
-MutableSpan<int8_t> BezierSpline::handle_types_right()
-{
- return handle_types_right_;
-}
-Span<float3> BezierSpline::handle_positions_right() const
-{
- this->ensure_auto_handles();
- return handle_positions_right_;
-}
-MutableSpan<float3> BezierSpline::handle_positions_right(const bool write_only)
-{
- if (!write_only) {
- this->ensure_auto_handles();
- }
- return handle_positions_right_;
-}
-
-void BezierSpline::reverse_impl()
-{
- this->handle_positions_left().reverse();
- this->handle_positions_right().reverse();
- std::swap(this->handle_positions_left_, this->handle_positions_right_);
-
- this->handle_types_left().reverse();
- this->handle_types_right().reverse();
- std::swap(this->handle_types_left_, this->handle_types_right_);
-}
-
-static float3 previous_position(Span<float3> positions, const bool cyclic, const int i)
-{
- if (i == 0) {
- if (cyclic) {
- return positions[positions.size() - 1];
- }
- return 2.0f * positions[i] - positions[i + 1];
- }
- return positions[i - 1];
-}
-
-static float3 next_position(Span<float3> positions, const bool cyclic, const int i)
-{
- if (i == positions.size() - 1) {
- if (cyclic) {
- return positions[0];
- }
- return 2.0f * positions[i] - positions[i - 1];
- }
- return positions[i + 1];
-}
-
-void BezierSpline::ensure_auto_handles() const
-{
- if (!auto_handles_dirty_) {
- return;
- }
-
- std::lock_guard lock{auto_handle_mutex_};
- if (!auto_handles_dirty_) {
- return;
- }
-
- if (this->size() == 1) {
- auto_handles_dirty_ = false;
- return;
- }
-
- for (const int i : IndexRange(this->size())) {
- using namespace blender;
-
- if (ELEM(BEZIER_HANDLE_AUTO, handle_types_left_[i], handle_types_right_[i])) {
- const float3 prev_diff = positions_[i] - previous_position(positions_, is_cyclic_, i);
- const float3 next_diff = next_position(positions_, is_cyclic_, i) - positions_[i];
- float prev_len = math::length(prev_diff);
- float next_len = math::length(next_diff);
- if (prev_len == 0.0f) {
- prev_len = 1.0f;
- }
- if (next_len == 0.0f) {
- next_len = 1.0f;
- }
- const float3 dir = next_diff / next_len + prev_diff / prev_len;
-
- /* This magic number is unfortunate, but comes from elsewhere in Blender. */
- const float len = math::length(dir) * 2.5614f;
- if (len != 0.0f) {
- if (handle_types_left_[i] == BEZIER_HANDLE_AUTO) {
- const float prev_len_clamped = std::min(prev_len, next_len * 5.0f);
- handle_positions_left_[i] = positions_[i] + dir * -(prev_len_clamped / len);
- }
- if (handle_types_right_[i] == BEZIER_HANDLE_AUTO) {
- const float next_len_clamped = std::min(next_len, prev_len * 5.0f);
- handle_positions_right_[i] = positions_[i] + dir * (next_len_clamped / len);
- }
- }
- }
-
- if (handle_types_left_[i] == BEZIER_HANDLE_VECTOR) {
- const float3 prev = previous_position(positions_, is_cyclic_, i);
- handle_positions_left_[i] = math::interpolate(positions_[i], prev, 1.0f / 3.0f);
- }
-
- if (handle_types_right_[i] == BEZIER_HANDLE_VECTOR) {
- const float3 next = next_position(positions_, is_cyclic_, i);
- handle_positions_right_[i] = math::interpolate(positions_[i], next, 1.0f / 3.0f);
- }
- }
-
- auto_handles_dirty_ = false;
-}
-
-void BezierSpline::translate(const blender::float3 &translation)
-{
- for (float3 &position : this->positions()) {
- position += translation;
- }
- for (float3 &handle_position : this->handle_positions_left()) {
- handle_position += translation;
- }
- for (float3 &handle_position : this->handle_positions_right()) {
- handle_position += translation;
- }
- this->mark_cache_invalid();
-}
-
-void BezierSpline::transform(const blender::float4x4 &matrix)
-{
- for (float3 &position : this->positions()) {
- position = matrix * position;
- }
- for (float3 &handle_position : this->handle_positions_left()) {
- handle_position = matrix * handle_position;
- }
- for (float3 &handle_position : this->handle_positions_right()) {
- handle_position = matrix * handle_position;
- }
- this->mark_cache_invalid();
-}
-
-static void set_handle_position(const float3 &position,
- const HandleType type,
- const HandleType type_other,
- const float3 &new_value,
- float3 &handle,
- float3 &handle_other)
-{
- using namespace blender::math;
-
- /* Don't bother when the handle positions are calculated automatically anyway. */
- if (ELEM(type, BEZIER_HANDLE_AUTO, BEZIER_HANDLE_VECTOR)) {
- return;
- }
-
- handle = new_value;
- if (type_other == BEZIER_HANDLE_ALIGN) {
- /* Keep track of the old length of the opposite handle. */
- const float length = distance(handle_other, position);
- /* Set the other handle to directly opposite from the current handle. */
- const float3 dir = normalize(handle - position);
- handle_other = position - dir * length;
- }
-}
-
-void BezierSpline::set_handle_position_right(const int index, const blender::float3 &value)
-{
- set_handle_position(positions_[index],
- static_cast<HandleType>(handle_types_right_[index]),
- static_cast<HandleType>(handle_types_left_[index]),
- value,
- handle_positions_right_[index],
- handle_positions_left_[index]);
-}
-
-void BezierSpline::set_handle_position_left(const int index, const blender::float3 &value)
-{
- set_handle_position(positions_[index],
- static_cast<HandleType>(handle_types_right_[index]),
- static_cast<HandleType>(handle_types_left_[index]),
- value,
- handle_positions_left_[index],
- handle_positions_right_[index]);
-}
-
-bool BezierSpline::point_is_sharp(const int index) const
-{
- return ELEM(handle_types_left_[index], BEZIER_HANDLE_VECTOR, BEZIER_HANDLE_FREE) ||
- ELEM(handle_types_right_[index], BEZIER_HANDLE_VECTOR, BEZIER_HANDLE_FREE);
-}
-
-bool BezierSpline::segment_is_vector(const int index) const
-{
- /* Two control points are necessary to form a segment, that should be checked by the caller. */
- BLI_assert(this->size() > 1);
-
- if (index == this->size() - 1) {
- if (is_cyclic_) {
- return handle_types_right_.last() == BEZIER_HANDLE_VECTOR &&
- handle_types_left_.first() == BEZIER_HANDLE_VECTOR;
- }
- /* There is actually no segment in this case, but it's nice to avoid
- * having a special case for the last segment in calling code. */
- return true;
- }
- return handle_types_right_[index] == BEZIER_HANDLE_VECTOR &&
- handle_types_left_[index + 1] == BEZIER_HANDLE_VECTOR;
-}
-
-void BezierSpline::mark_cache_invalid()
-{
- offset_cache_dirty_ = true;
- position_cache_dirty_ = true;
- mapping_cache_dirty_ = true;
- tangent_cache_dirty_ = true;
- normal_cache_dirty_ = true;
- length_cache_dirty_ = true;
- auto_handles_dirty_ = true;
-}
-
-int BezierSpline::evaluated_points_num() const
-{
- BLI_assert(this->size() > 0);
- return this->control_point_offsets().last();
-}
-
-void BezierSpline::correct_end_tangents() const
-{
- using namespace blender::math;
- if (is_cyclic_) {
- return;
- }
-
- MutableSpan<float3> tangents(evaluated_tangents_cache_);
-
- if (handle_positions_right_.first() != positions_.first()) {
- tangents.first() = normalize(handle_positions_right_.first() - positions_.first());
- }
- if (handle_positions_left_.last() != positions_.last()) {
- tangents.last() = normalize(positions_.last() - handle_positions_left_.last());
- }
-}
-
-BezierSpline::InsertResult BezierSpline::calculate_segment_insertion(const int index,
- const int next_index,
- const float parameter)
-{
- using namespace blender::math;
-
- BLI_assert(parameter <= 1.0f && parameter >= 0.0f);
- BLI_assert(ELEM(next_index, 0, index + 1));
- const float3 &point_prev = positions_[index];
- const float3 &handle_prev = handle_positions_right_[index];
- const float3 &handle_next = handle_positions_left_[next_index];
- const float3 &point_next = positions_[next_index];
- const float3 center_point = interpolate(handle_prev, handle_next, parameter);
-
- BezierSpline::InsertResult result;
- result.handle_prev = interpolate(point_prev, handle_prev, parameter);
- result.handle_next = interpolate(handle_next, point_next, parameter);
- result.left_handle = interpolate(result.handle_prev, center_point, parameter);
- result.right_handle = interpolate(center_point, result.handle_next, parameter);
- result.position = interpolate(result.left_handle, result.right_handle, parameter);
- return result;
-}
-
-static void bezier_forward_difference_3d(const float3 &point_0,
- const float3 &point_1,
- const float3 &point_2,
- const float3 &point_3,
- MutableSpan<float3> result)
-{
- BLI_assert(result.size() > 0);
- const float inv_len = 1.0f / static_cast<float>(result.size());
- const float inv_len_squared = inv_len * inv_len;
- const float inv_len_cubed = inv_len_squared * inv_len;
-
- const float3 rt1 = 3.0f * (point_1 - point_0) * inv_len;
- const float3 rt2 = 3.0f * (point_0 - 2.0f * point_1 + point_2) * inv_len_squared;
- const float3 rt3 = (point_3 - point_0 + 3.0f * (point_1 - point_2)) * inv_len_cubed;
-
- float3 q0 = point_0;
- float3 q1 = rt1 + rt2 + rt3;
- float3 q2 = 2.0f * rt2 + 6.0f * rt3;
- float3 q3 = 6.0f * rt3;
- for (const int i : result.index_range()) {
- result[i] = q0;
- q0 += q1;
- q1 += q2;
- q2 += q3;
- }
-}
-
-void BezierSpline::evaluate_segment(const int index,
- const int next_index,
- MutableSpan<float3> positions) const
-{
- if (this->segment_is_vector(index)) {
- BLI_assert(positions.size() == 1);
- positions.first() = positions_[index];
- }
- else {
- bezier_forward_difference_3d(positions_[index],
- handle_positions_right_[index],
- handle_positions_left_[next_index],
- positions_[next_index],
- positions);
- }
-}
-
-Span<int> BezierSpline::control_point_offsets() const
-{
- if (!offset_cache_dirty_) {
- return offset_cache_;
- }
-
- std::lock_guard lock{offset_cache_mutex_};
- if (!offset_cache_dirty_) {
- return offset_cache_;
- }
-
- const int size = this->size();
- offset_cache_.resize(size + 1);
-
- MutableSpan<int> offsets = offset_cache_;
- if (size == 1) {
- offsets.first() = 0;
- offsets.last() = 1;
- }
- else {
- int offset = 0;
- for (const int i : IndexRange(size)) {
- offsets[i] = offset;
- offset += this->segment_is_vector(i) ? 1 : resolution_;
- }
- offsets.last() = offset;
- }
-
- offset_cache_dirty_ = false;
- return offsets;
-}
-
-static void calculate_mappings_linear_resolution(Span<int> offsets,
- const int size,
- const int resolution,
- const bool is_cyclic,
- MutableSpan<float> r_mappings)
-{
- const float first_segment_len_inv = 1.0f / offsets[1];
- for (const int i : IndexRange(0, offsets[1])) {
- r_mappings[i] = i * first_segment_len_inv;
- }
-
- const int grain_size = std::max(2048 / resolution, 1);
- blender::threading::parallel_for(IndexRange(1, size - 2), grain_size, [&](IndexRange range) {
- for (const int i_control_point : range) {
- const int segment_len = offsets[i_control_point + 1] - offsets[i_control_point];
- const float segment_len_inv = 1.0f / segment_len;
- for (const int i : IndexRange(segment_len)) {
- r_mappings[offsets[i_control_point] + i] = i_control_point + i * segment_len_inv;
- }
- }
- });
-
- if (is_cyclic) {
- const int last_segment_len = offsets[size] - offsets[size - 1];
- const float last_segment_len_inv = 1.0f / last_segment_len;
- for (const int i : IndexRange(last_segment_len)) {
- r_mappings[offsets[size - 1] + i] = size - 1 + i * last_segment_len_inv;
- }
- }
- else {
- r_mappings.last() = size - 1;
- }
-}
-
-Span<float> BezierSpline::evaluated_mappings() const
-{
- if (!mapping_cache_dirty_) {
- return evaluated_mapping_cache_;
- }
-
- std::lock_guard lock{mapping_cache_mutex_};
- if (!mapping_cache_dirty_) {
- return evaluated_mapping_cache_;
- }
-
- const int num = this->size();
- const int eval_num = this->evaluated_points_num();
- evaluated_mapping_cache_.resize(eval_num);
- MutableSpan<float> mappings = evaluated_mapping_cache_;
-
- if (eval_num == 1) {
- mappings.first() = 0.0f;
- mapping_cache_dirty_ = false;
- return mappings;
- }
-
- Span<int> offsets = this->control_point_offsets();
-
- blender::threading::isolate_task([&]() {
- /* Isolate the task, since this is function is multi-threaded and holds a lock. */
- calculate_mappings_linear_resolution(offsets, num, resolution_, is_cyclic_, mappings);
- });
-
- mapping_cache_dirty_ = false;
- return mappings;
-}
-
-Span<float3> BezierSpline::evaluated_positions() const
-{
- if (!position_cache_dirty_) {
- return evaluated_position_cache_;
- }
-
- std::lock_guard lock{position_cache_mutex_};
- if (!position_cache_dirty_) {
- return evaluated_position_cache_;
- }
-
- const int num = this->size();
- const int eval_num = this->evaluated_points_num();
- evaluated_position_cache_.resize(eval_num);
-
- MutableSpan<float3> positions = evaluated_position_cache_;
-
- if (num == 1) {
- /* Use a special case for single point splines to avoid checking in #evaluate_segment. */
- BLI_assert(eval_num == 1);
- positions.first() = positions_.first();
- position_cache_dirty_ = false;
- return positions;
- }
-
- this->ensure_auto_handles();
-
- Span<int> offsets = this->control_point_offsets();
-
- const int grain_size = std::max(512 / resolution_, 1);
- blender::threading::isolate_task([&]() {
- /* Isolate the task, since this is function is multi-threaded and holds a lock. */
- blender::threading::parallel_for(IndexRange(num - 1), grain_size, [&](IndexRange range) {
- for (const int i : range) {
- this->evaluate_segment(i, i + 1, positions.slice(offsets[i], offsets[i + 1] - offsets[i]));
- }
- });
- });
- if (is_cyclic_) {
- this->evaluate_segment(
- num - 1, 0, positions.slice(offsets[num - 1], offsets[num] - offsets[num - 1]));
- }
- else {
- /* Since evaluating the bezier segment doesn't add the final point,
- * it must be added manually in the non-cyclic case. */
- positions.last() = positions_.last();
- }
-
- position_cache_dirty_ = false;
- return positions;
-}
-
-BezierSpline::InterpolationData BezierSpline::interpolation_data_from_index_factor(
- const float index_factor) const
-{
- const int num = this->size();
-
- if (is_cyclic_) {
- if (index_factor < num) {
- const int index = std::floor(index_factor);
- const int next_index = (index < num - 1) ? index + 1 : 0;
- return InterpolationData{index, next_index, index_factor - index};
- }
- return InterpolationData{num - 1, 0, 1.0f};
- }
-
- if (index_factor < num - 1) {
- const int index = std::floor(index_factor);
- const int next_index = index + 1;
- return InterpolationData{index, next_index, index_factor - index};
- }
- return InterpolationData{num - 2, num - 1, 1.0f};
-}
-
-/* Use a spline argument to avoid adding this to the header. */
-template<typename T>
-static void interpolate_to_evaluated_impl(const BezierSpline &spline,
- const blender::VArray<T> &src,
- MutableSpan<T> dst)
-{
- BLI_assert(src.size() == spline.size());
- BLI_assert(dst.size() == spline.evaluated_points_num());
- Span<float> mappings = spline.evaluated_mappings();
-
- for (const int i : dst.index_range()) {
- BezierSpline::InterpolationData interp = spline.interpolation_data_from_index_factor(
- mappings[i]);
-
- const T &value = src[interp.control_point_index];
- const T &next_value = src[interp.next_control_point_index];
-
- dst[i] = blender::attribute_math::mix2(interp.factor, value, next_value);
- }
-}
-
-GVArray BezierSpline::interpolate_to_evaluated(const GVArray &src) const
-{
- BLI_assert(src.size() == this->size());
-
- if (src.is_single()) {
- return src;
- }
-
- const int eval_num = this->evaluated_points_num();
- if (eval_num == 1) {
- return src;
- }
-
- GVArray new_varray;
- blender::attribute_math::convert_to_static_type(src.type(), [&](auto dummy) {
- using T = decltype(dummy);
- if constexpr (!std::is_void_v<blender::attribute_math::DefaultMixer<T>>) {
- Array<T> values(eval_num);
- interpolate_to_evaluated_impl<T>(*this, src.typed<T>(), values);
- new_varray = VArray<T>::ForContainer(std::move(values));
- }
- });
-
- return new_varray;
-}
diff --git a/source/blender/blenkernel/intern/spline_nurbs.cc b/source/blender/blenkernel/intern/spline_nurbs.cc
deleted file mode 100644
index a7eeb82d854..00000000000
--- a/source/blender/blenkernel/intern/spline_nurbs.cc
+++ /dev/null
@@ -1,395 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_array.hh"
-#include "BLI_span.hh"
-#include "BLI_virtual_array.hh"
-
-#include "BKE_attribute_math.hh"
-#include "BKE_spline.hh"
-
-using blender::Array;
-using blender::float3;
-using blender::GVArray;
-using blender::IndexRange;
-using blender::MutableSpan;
-using blender::Span;
-using blender::VArray;
-
-void NURBSpline::copy_settings(Spline &dst) const
-{
- NURBSpline &nurbs = static_cast<NURBSpline &>(dst);
- nurbs.knots_mode = knots_mode;
- nurbs.resolution_ = resolution_;
- nurbs.order_ = order_;
-}
-
-void NURBSpline::copy_data(Spline &dst) const
-{
- NURBSpline &nurbs = static_cast<NURBSpline &>(dst);
- nurbs.positions_ = positions_;
- nurbs.weights_ = weights_;
- nurbs.knots_ = knots_;
- nurbs.knots_dirty_ = knots_dirty_;
- nurbs.radii_ = radii_;
- nurbs.tilts_ = tilts_;
-}
-
-int NURBSpline::size() const
-{
- const int size = positions_.size();
- BLI_assert(size == radii_.size());
- BLI_assert(size == tilts_.size());
- BLI_assert(size == weights_.size());
- return size;
-}
-
-int NURBSpline::resolution() const
-{
- return resolution_;
-}
-
-void NURBSpline::set_resolution(const int value)
-{
- BLI_assert(value > 0);
- resolution_ = value;
- this->mark_cache_invalid();
-}
-
-uint8_t NURBSpline::order() const
-{
- return order_;
-}
-
-void NURBSpline::set_order(const uint8_t value)
-{
- BLI_assert(value >= 2 && value <= 6);
- order_ = value;
- this->mark_cache_invalid();
-}
-
-void NURBSpline::resize(const int size)
-{
- positions_.resize(size);
- radii_.resize(size);
- tilts_.resize(size);
- weights_.resize(size);
- this->mark_cache_invalid();
- attributes.reallocate(size);
-}
-
-MutableSpan<float3> NURBSpline::positions()
-{
- return positions_;
-}
-Span<float3> NURBSpline::positions() const
-{
- return positions_;
-}
-MutableSpan<float> NURBSpline::radii()
-{
- return radii_;
-}
-Span<float> NURBSpline::radii() const
-{
- return radii_;
-}
-MutableSpan<float> NURBSpline::tilts()
-{
- return tilts_;
-}
-Span<float> NURBSpline::tilts() const
-{
- return tilts_;
-}
-MutableSpan<float> NURBSpline::weights()
-{
- return weights_;
-}
-Span<float> NURBSpline::weights() const
-{
- return weights_;
-}
-
-void NURBSpline::reverse_impl()
-{
- this->weights().reverse();
-}
-
-void NURBSpline::mark_cache_invalid()
-{
- basis_cache_dirty_ = true;
- position_cache_dirty_ = true;
- tangent_cache_dirty_ = true;
- normal_cache_dirty_ = true;
- length_cache_dirty_ = true;
-}
-
-int NURBSpline::evaluated_points_num() const
-{
- if (!this->check_valid_num_and_order()) {
- return 0;
- }
- return resolution_ * this->segments_num();
-}
-
-void NURBSpline::correct_end_tangents() const
-{
-}
-
-bool NURBSpline::check_valid_num_and_order() const
-{
- if (this->size() < order_) {
- return false;
- }
-
- if (ELEM(this->knots_mode, NURBS_KNOT_MODE_BEZIER, NURBS_KNOT_MODE_ENDPOINT_BEZIER)) {
- if (this->knots_mode == NURBS_KNOT_MODE_BEZIER && this->size() <= order_) {
- return false;
- }
- return (!is_cyclic_ || this->size() % (order_ - 1) == 0);
- }
-
- return true;
-}
-
-int NURBSpline::knots_num() const
-{
- const int num = this->size() + order_;
- return is_cyclic_ ? num + order_ - 1 : num;
-}
-
-void NURBSpline::calculate_knots() const
-{
- const KnotsMode mode = this->knots_mode;
- const int order = order_;
- const bool is_bezier = ELEM(mode, NURBS_KNOT_MODE_BEZIER, NURBS_KNOT_MODE_ENDPOINT_BEZIER);
- const bool is_end_point = ELEM(mode, NURBS_KNOT_MODE_ENDPOINT, NURBS_KNOT_MODE_ENDPOINT_BEZIER);
- /* Inner knots are always repeated once except on Bezier case. */
- const int repeat_inner = is_bezier ? order - 1 : 1;
- /* How many times to repeat 0.0 at the beginning of knot. */
- const int head = is_end_point ? (order - (is_cyclic_ ? 1 : 0)) :
- (is_bezier ? min_ii(2, repeat_inner) : 1);
- /* Number of knots replicating widths of the starting knots.
- * Covers both Cyclic and EndPoint cases. */
- const int tail = is_cyclic_ ? 2 * order - 1 : (is_end_point ? order : 0);
-
- knots_.resize(this->knots_num());
- MutableSpan<float> knots = knots_;
-
- int r = head;
- float current = 0.0f;
-
- const int offset = is_end_point && is_cyclic_ ? 1 : 0;
- if (offset) {
- knots[0] = current;
- current += 1.0f;
- }
-
- for (const int i : IndexRange(offset, knots.size() - offset - tail)) {
- knots[i] = current;
- r--;
- if (r == 0) {
- current += 1.0;
- r = repeat_inner;
- }
- }
-
- const int tail_index = knots.size() - tail;
- for (const int i : IndexRange(tail)) {
- knots[tail_index + i] = current + (knots[i] - knots[0]);
- }
-}
-
-Span<float> NURBSpline::knots() const
-{
- if (!knots_dirty_) {
- BLI_assert(knots_.size() == this->knots_num());
- return knots_;
- }
-
- std::lock_guard lock{knots_mutex_};
- if (!knots_dirty_) {
- BLI_assert(knots_.size() == this->knots_num());
- return knots_;
- }
-
- this->calculate_knots();
-
- knots_dirty_ = false;
-
- return knots_;
-}
-
-static void calculate_basis_for_point(const float parameter,
- const int num,
- const int degree,
- const Span<float> knots,
- MutableSpan<float> r_weights,
- int &r_start_index)
-{
- const int order = degree + 1;
-
- int start = 0;
- int end = 0;
- for (const int i : IndexRange(num + degree)) {
- const bool knots_equal = knots[i] == knots[i + 1];
- if (knots_equal || parameter < knots[i] || parameter > knots[i + 1]) {
- continue;
- }
-
- start = std::max(i - degree, 0);
- end = i;
- break;
- }
-
- Array<float, 12> buffer(order * 2, 0.0f);
-
- buffer[end - start] = 1.0f;
-
- for (const int i_order : IndexRange(2, degree)) {
- if (end + i_order >= knots.size()) {
- end = num + degree - i_order;
- }
- for (const int i : IndexRange(end - start + 1)) {
- const int knot_index = start + i;
-
- float new_basis = 0.0f;
- if (buffer[i] != 0.0f) {
- new_basis += ((parameter - knots[knot_index]) * buffer[i]) /
- (knots[knot_index + i_order - 1] - knots[knot_index]);
- }
-
- if (buffer[i + 1] != 0.0f) {
- new_basis += ((knots[knot_index + i_order] - parameter) * buffer[i + 1]) /
- (knots[knot_index + i_order] - knots[knot_index + 1]);
- }
-
- buffer[i] = new_basis;
- }
- }
-
- buffer.as_mutable_span().drop_front(end - start + 1).fill(0.0f);
- r_weights.copy_from(buffer.as_span().take_front(order));
- r_start_index = start;
-}
-
-const NURBSpline::BasisCache &NURBSpline::calculate_basis_cache() const
-{
- if (!basis_cache_dirty_) {
- return basis_cache_;
- }
-
- std::lock_guard lock{basis_cache_mutex_};
- if (!basis_cache_dirty_) {
- return basis_cache_;
- }
-
- const int num = this->size();
- const int eval_num = this->evaluated_points_num();
-
- const int order = this->order();
- const int degree = order - 1;
-
- basis_cache_.weights.resize(eval_num * order);
- basis_cache_.start_indices.resize(eval_num);
-
- if (eval_num == 0) {
- return basis_cache_;
- }
-
- MutableSpan<float> basis_weights(basis_cache_.weights);
- MutableSpan<int> basis_start_indices(basis_cache_.start_indices);
-
- const Span<float> control_weights = this->weights();
- const Span<float> knots = this->knots();
-
- const int last_control_point_index = is_cyclic_ ? num + degree : num;
-
- const float start = knots[degree];
- const float end = knots[last_control_point_index];
- const float step = (end - start) / this->evaluated_edges_num();
- for (const int i : IndexRange(eval_num)) {
- /* Clamp parameter due to floating point inaccuracy. */
- const float parameter = std::clamp(start + step * i, knots[0], knots[num + degree]);
-
- MutableSpan<float> point_weights = basis_weights.slice(i * order, order);
-
- calculate_basis_for_point(
- parameter, last_control_point_index, degree, knots, point_weights, basis_start_indices[i]);
-
- for (const int j : point_weights.index_range()) {
- const int point_index = (basis_start_indices[i] + j) % num;
- point_weights[j] *= control_weights[point_index];
- }
- }
-
- basis_cache_dirty_ = false;
- return basis_cache_;
-}
-
-template<typename T>
-void interpolate_to_evaluated_impl(const NURBSpline::BasisCache &basis_cache,
- const int order,
- const blender::VArray<T> &src,
- MutableSpan<T> dst)
-{
- const int num = src.size();
- blender::attribute_math::DefaultMixer<T> mixer(dst);
-
- for (const int i : dst.index_range()) {
- Span<float> point_weights = basis_cache.weights.as_span().slice(i * order, order);
- const int start_index = basis_cache.start_indices[i];
-
- for (const int j : point_weights.index_range()) {
- const int point_index = (start_index + j) % num;
- mixer.mix_in(i, src[point_index], point_weights[j]);
- }
- }
-
- mixer.finalize();
-}
-
-GVArray NURBSpline::interpolate_to_evaluated(const GVArray &src) const
-{
- BLI_assert(src.size() == this->size());
-
- if (src.is_single()) {
- return src;
- }
-
- const BasisCache &basis_cache = this->calculate_basis_cache();
-
- GVArray new_varray;
- blender::attribute_math::convert_to_static_type(src.type(), [&](auto dummy) {
- using T = decltype(dummy);
- if constexpr (!std::is_void_v<blender::attribute_math::DefaultMixer<T>>) {
- Array<T> values(this->evaluated_points_num());
- interpolate_to_evaluated_impl<T>(basis_cache, this->order(), src.typed<T>(), values);
- new_varray = VArray<T>::ForContainer(std::move(values));
- }
- });
-
- return new_varray;
-}
-
-Span<float3> NURBSpline::evaluated_positions() const
-{
- if (!position_cache_dirty_) {
- return evaluated_position_cache_;
- }
-
- std::lock_guard lock{position_cache_mutex_};
- if (!position_cache_dirty_) {
- return evaluated_position_cache_;
- }
-
- const int eval_num = this->evaluated_points_num();
- evaluated_position_cache_.resize(eval_num);
-
- /* TODO: Avoid copying the evaluated data from the temporary array. */
- VArray<float3> evaluated = Spline::interpolate_to_evaluated(positions_.as_span());
- evaluated.materialize(evaluated_position_cache_);
-
- position_cache_dirty_ = false;
- return evaluated_position_cache_;
-}
diff --git a/source/blender/blenkernel/intern/spline_poly.cc b/source/blender/blenkernel/intern/spline_poly.cc
deleted file mode 100644
index c3cc268c81c..00000000000
--- a/source/blender/blenkernel/intern/spline_poly.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_span.hh"
-#include "BLI_virtual_array.hh"
-
-#include "BKE_spline.hh"
-
-using blender::float3;
-using blender::GVArray;
-using blender::MutableSpan;
-using blender::Span;
-
-void PolySpline::copy_settings(Spline &UNUSED(dst)) const
-{
- /* Poly splines have no settings not covered by the base class. */
-}
-
-void PolySpline::copy_data(Spline &dst) const
-{
- PolySpline &poly = static_cast<PolySpline &>(dst);
- poly.positions_ = positions_;
- poly.radii_ = radii_;
- poly.tilts_ = tilts_;
-}
-
-int PolySpline::size() const
-{
- const int size = positions_.size();
- BLI_assert(size == radii_.size());
- BLI_assert(size == tilts_.size());
- return size;
-}
-
-void PolySpline::resize(const int size)
-{
- positions_.resize(size);
- radii_.resize(size);
- tilts_.resize(size);
- this->mark_cache_invalid();
- attributes.reallocate(size);
-}
-
-MutableSpan<float3> PolySpline::positions()
-{
- return positions_;
-}
-Span<float3> PolySpline::positions() const
-{
- return positions_;
-}
-MutableSpan<float> PolySpline::radii()
-{
- return radii_;
-}
-Span<float> PolySpline::radii() const
-{
- return radii_;
-}
-MutableSpan<float> PolySpline::tilts()
-{
- return tilts_;
-}
-Span<float> PolySpline::tilts() const
-{
- return tilts_;
-}
-
-void PolySpline::reverse_impl()
-{
-}
-
-void PolySpline::mark_cache_invalid()
-{
- tangent_cache_dirty_ = true;
- normal_cache_dirty_ = true;
- length_cache_dirty_ = true;
-}
-
-int PolySpline::evaluated_points_num() const
-{
- return this->size();
-}
-
-void PolySpline::correct_end_tangents() const
-{
-}
-
-Span<float3> PolySpline::evaluated_positions() const
-{
- return this->positions();
-}
-
-GVArray PolySpline::interpolate_to_evaluated(const GVArray &src) const
-{
- BLI_assert(src.size() == this->size());
- return src;
-}
diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c
index 64f998ea67f..daad983f0bf 100644
--- a/source/blender/blenkernel/intern/studiolight.c
+++ b/source/blender/blenkernel/intern/studiolight.c
@@ -217,8 +217,8 @@ static void studiolight_load_solid_light(StudioLight *sl)
#undef READ_IVAL
#undef READ_FVAL
-#define WRITE_FVAL(str, id, val) (BLI_dynstr_appendf(str, id " %f\n", val))
-#define WRITE_IVAL(str, id, val) (BLI_dynstr_appendf(str, id " %d\n", val))
+#define WRITE_FVAL(str, id, val) BLI_dynstr_appendf(str, id " %f\n", val)
+#define WRITE_IVAL(str, id, val) BLI_dynstr_appendf(str, id " %d\n", val)
#define WRITE_VEC3(str, id, val) \
do { \
@@ -273,7 +273,7 @@ static void direction_to_equirect(float r[2], const float dir[3])
static void equirect_to_direction(float r[3], float u, float v)
{
- float phi = (-(M_PI * 2)) * u + M_PI;
+ float phi = -(M_PI * 2) * u + M_PI;
float theta = -M_PI * v + M_PI;
float sin_theta = sinf(theta);
r[0] = sin_theta * cosf(phi);
@@ -342,9 +342,7 @@ static void *studiolight_multilayer_addlayer(void *base, const char *UNUSED(laye
/* Convert a multilayer pass to ImBuf channel 4 float buffer.
* NOTE: Parameter rect will become invalid. Do not use rect after calling this
* function */
-static float *studiolight_multilayer_convert_pass(ImBuf *ibuf,
- float *rect,
- const unsigned int channels)
+static float *studiolight_multilayer_convert_pass(ImBuf *ibuf, float *rect, const uint channels)
{
if (channels == 4) {
return rect;
diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.cc
index c956ef09af3..bf09be444b1 100644
--- a/source/blender/blenkernel/intern/subdiv_ccg.c
+++ b/source/blender/blenkernel/intern/subdiv_ccg.cc
@@ -38,7 +38,7 @@ static void subdiv_ccg_average_inner_face_grids(SubdivCCG *subdiv_ccg,
void subdiv_ccg_average_faces_boundaries_and_corners(SubdivCCG *subdiv_ccg,
CCGKey *key,
- struct CCGFace **effected_faces,
+ CCGFace **effected_faces,
int num_effected_faces);
/** \} */
@@ -126,20 +126,21 @@ static void subdiv_ccg_alloc_elements(SubdivCCG *subdiv_ccg, Subdiv *subdiv)
const int grid_area = grid_size * grid_size;
subdiv_ccg->grid_element_size = element_size;
subdiv_ccg->num_grids = num_grids;
- subdiv_ccg->grids = MEM_calloc_arrayN(num_grids, sizeof(CCGElem *), "subdiv ccg grids");
- subdiv_ccg->grids_storage = MEM_calloc_arrayN(
- num_grids, ((size_t)grid_area) * element_size, "subdiv ccg grids storage");
- const size_t grid_size_in_bytes = (size_t)grid_area * element_size;
+ subdiv_ccg->grids = static_cast<CCGElem **>(
+ MEM_calloc_arrayN(num_grids, sizeof(CCGElem *), "subdiv ccg grids"));
+ subdiv_ccg->grids_storage = static_cast<uchar *>(
+ MEM_calloc_arrayN(num_grids, size_t(grid_area) * element_size, "subdiv ccg grids storage"));
+ const size_t grid_size_in_bytes = size_t(grid_area) * element_size;
for (int grid_index = 0; grid_index < num_grids; grid_index++) {
const size_t grid_offset = grid_size_in_bytes * grid_index;
subdiv_ccg->grids[grid_index] = (CCGElem *)&subdiv_ccg->grids_storage[grid_offset];
}
/* Grid material flags. */
- subdiv_ccg->grid_flag_mats = MEM_calloc_arrayN(
- num_grids, sizeof(DMFlagMat), "ccg grid material flags");
+ subdiv_ccg->grid_flag_mats = static_cast<DMFlagMat *>(
+ MEM_calloc_arrayN(num_grids, sizeof(DMFlagMat), "ccg grid material flags"));
/* Grid hidden flags. */
- subdiv_ccg->grid_hidden = MEM_calloc_arrayN(
- num_grids, sizeof(BLI_bitmap *), "ccg grid material flags");
+ subdiv_ccg->grid_hidden = static_cast<BLI_bitmap **>(
+ MEM_calloc_arrayN(num_grids, sizeof(BLI_bitmap *), "ccg grid material flags"));
for (int grid_index = 0; grid_index < num_grids; grid_index++) {
subdiv_ccg->grid_hidden[grid_index] = BLI_BITMAP_NEW(grid_area, "ccg grid hidden");
}
@@ -147,9 +148,10 @@ static void subdiv_ccg_alloc_elements(SubdivCCG *subdiv_ccg, Subdiv *subdiv)
/* Allocate memory for faces. */
subdiv_ccg->num_faces = num_faces;
if (num_faces) {
- subdiv_ccg->faces = MEM_calloc_arrayN(num_faces, sizeof(SubdivCCGFace), "Subdiv CCG faces");
- subdiv_ccg->grid_faces = MEM_calloc_arrayN(
- num_grids, sizeof(SubdivCCGFace *), "Subdiv CCG grid faces");
+ subdiv_ccg->faces = static_cast<SubdivCCGFace *>(
+ MEM_calloc_arrayN(num_faces, sizeof(SubdivCCGFace), "Subdiv CCG faces"));
+ subdiv_ccg->grid_faces = static_cast<SubdivCCGFace **>(
+ MEM_calloc_arrayN(num_grids, sizeof(SubdivCCGFace *), "Subdiv CCG grid faces"));
}
}
@@ -159,23 +161,23 @@ static void subdiv_ccg_alloc_elements(SubdivCCG *subdiv_ccg, Subdiv *subdiv)
/** \name Grids evaluation
* \{ */
-typedef struct CCGEvalGridsData {
+struct CCGEvalGridsData {
SubdivCCG *subdiv_ccg;
Subdiv *subdiv;
int *face_ptex_offset;
SubdivCCGMaskEvaluator *mask_evaluator;
SubdivCCGMaterialFlagsEvaluator *material_flags_evaluator;
-} CCGEvalGridsData;
+};
static void subdiv_ccg_eval_grid_element_limit(CCGEvalGridsData *data,
const int ptex_face_index,
const float u,
const float v,
- unsigned char *element)
+ uchar *element)
{
Subdiv *subdiv = data->subdiv;
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
- if (subdiv->displacement_evaluator != NULL) {
+ if (subdiv->displacement_evaluator != nullptr) {
BKE_subdiv_eval_final_point(subdiv, ptex_face_index, u, v, (float *)element);
}
else if (subdiv_ccg->has_normal) {
@@ -195,14 +197,14 @@ static void subdiv_ccg_eval_grid_element_mask(CCGEvalGridsData *data,
const int ptex_face_index,
const float u,
const float v,
- unsigned char *element)
+ uchar *element)
{
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
if (!subdiv_ccg->has_mask) {
return;
}
float *mask_value_ptr = (float *)(element + subdiv_ccg->mask_offset);
- if (data->mask_evaluator != NULL) {
+ if (data->mask_evaluator != nullptr) {
*mask_value_ptr = data->mask_evaluator->eval_mask(data->mask_evaluator, ptex_face_index, u, v);
}
else {
@@ -214,7 +216,7 @@ static void subdiv_ccg_eval_grid_element(CCGEvalGridsData *data,
const int ptex_face_index,
const float u,
const float v,
- unsigned char *element)
+ uchar *element)
{
subdiv_ccg_eval_grid_element_limit(data, ptex_face_index, u, v, element);
subdiv_ccg_eval_grid_element_mask(data, ptex_face_index, u, v, element);
@@ -232,14 +234,14 @@ static void subdiv_ccg_eval_regular_grid(CCGEvalGridsData *data, const int face_
const SubdivCCGFace *face = &faces[face_index];
for (int corner = 0; corner < face->num_grids; corner++) {
const int grid_index = face->start_grid_index + corner;
- unsigned char *grid = (unsigned char *)subdiv_ccg->grids[grid_index];
+ uchar *grid = (uchar *)subdiv_ccg->grids[grid_index];
for (int y = 0; y < grid_size; y++) {
const float grid_v = y * grid_size_1_inv;
for (int x = 0; x < grid_size; x++) {
const float grid_u = x * grid_size_1_inv;
float u, v;
BKE_subdiv_rotate_grid_to_quad(corner, grid_u, grid_v, &u, &v);
- const size_t grid_element_index = (size_t)y * grid_size + x;
+ const size_t grid_element_index = size_t(y) * grid_size + x;
const size_t grid_element_offset = grid_element_index * element_size;
subdiv_ccg_eval_grid_element(data, ptex_face_index, u, v, &grid[grid_element_offset]);
}
@@ -264,12 +266,12 @@ static void subdiv_ccg_eval_special_grid(CCGEvalGridsData *data, const int face_
for (int corner = 0; corner < face->num_grids; corner++) {
const int grid_index = face->start_grid_index + corner;
const int ptex_face_index = data->face_ptex_offset[face_index] + corner;
- unsigned char *grid = (unsigned char *)subdiv_ccg->grids[grid_index];
+ uchar *grid = (uchar *)subdiv_ccg->grids[grid_index];
for (int y = 0; y < grid_size; y++) {
const float u = 1.0f - (y * grid_size_1_inv);
for (int x = 0; x < grid_size; x++) {
const float v = 1.0f - (x * grid_size_1_inv);
- const size_t grid_element_index = (size_t)y * grid_size + x;
+ const size_t grid_element_index = size_t(y) * grid_size + x;
const size_t grid_element_offset = grid_element_index * element_size;
subdiv_ccg_eval_grid_element(data, ptex_face_index, u, v, &grid[grid_element_offset]);
}
@@ -284,9 +286,9 @@ static void subdiv_ccg_eval_special_grid(CCGEvalGridsData *data, const int face_
static void subdiv_ccg_eval_grids_task(void *__restrict userdata_v,
const int face_index,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
- CCGEvalGridsData *data = userdata_v;
+ CCGEvalGridsData *data = static_cast<CCGEvalGridsData *>(userdata_v);
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
SubdivCCGFace *face = &subdiv_ccg->faces[face_index];
if (face->num_grids == 4) {
@@ -318,7 +320,7 @@ static bool subdiv_ccg_evaluate_grids(SubdivCCG *subdiv_ccg,
0, num_faces, &data, subdiv_ccg_eval_grids_task, &parallel_range_settings);
/* If displacement is used, need to calculate normals after all final
* coordinates are known. */
- if (subdiv->displacement_evaluator != NULL) {
+ if (subdiv->displacement_evaluator != nullptr) {
BKE_subdiv_ccg_recalc_normals(subdiv_ccg);
}
return true;
@@ -341,17 +343,17 @@ static void subdiv_ccg_init_faces(SubdivCCG *subdiv_ccg)
}
/* TODO(sergey): Consider making it generic enough to be fit into BLI. */
-typedef struct StaticOrHeapIntStorage {
+struct StaticOrHeapIntStorage {
int static_storage[64];
int static_storage_len;
int *heap_storage;
int heap_storage_len;
-} StaticOrHeapIntStorage;
+};
static void static_or_heap_storage_init(StaticOrHeapIntStorage *storage)
{
storage->static_storage_len = sizeof(storage->static_storage) / sizeof(*storage->static_storage);
- storage->heap_storage = NULL;
+ storage->heap_storage = nullptr;
storage->heap_storage_len = 0;
}
@@ -361,10 +363,11 @@ static int *static_or_heap_storage_get(StaticOrHeapIntStorage *storage, int heap
if (heap_len <= storage->static_storage_len) {
return storage->static_storage;
}
- /* Make sure heap ius big enough. */
+ /* Make sure heap is big enough. */
if (heap_len > storage->heap_storage_len) {
MEM_SAFE_FREE(storage->heap_storage);
- storage->heap_storage = MEM_malloc_arrayN(heap_len, sizeof(int), "int storage");
+ storage->heap_storage = static_cast<int *>(
+ MEM_malloc_arrayN(heap_len, sizeof(int), "int storage"));
storage->heap_storage_len = heap_len;
}
return storage->heap_storage;
@@ -378,13 +381,16 @@ static void static_or_heap_storage_free(StaticOrHeapIntStorage *storage)
static void subdiv_ccg_allocate_adjacent_edges(SubdivCCG *subdiv_ccg, const int num_edges)
{
subdiv_ccg->num_adjacent_edges = num_edges;
- subdiv_ccg->adjacent_edges = MEM_calloc_arrayN(
- subdiv_ccg->num_adjacent_edges, sizeof(*subdiv_ccg->adjacent_edges), "ccg adjacent edges");
+ subdiv_ccg->adjacent_edges = static_cast<SubdivCCGAdjacentEdge *>(MEM_calloc_arrayN(
+ subdiv_ccg->num_adjacent_edges, sizeof(*subdiv_ccg->adjacent_edges), "ccg adjacent edges"));
}
static SubdivCCGCoord subdiv_ccg_coord(int grid_index, int x, int y)
{
- SubdivCCGCoord coord = {.grid_index = grid_index, .x = x, .y = y};
+ SubdivCCGCoord coord{};
+ coord.grid_index = grid_index;
+ coord.x = x;
+ coord.y = y;
return coord;
}
@@ -403,11 +409,11 @@ static SubdivCCGCoord *subdiv_ccg_adjacent_edge_add_face(SubdivCCG *subdiv_ccg,
const int adjacent_face_index = adjacent_edge->num_adjacent_faces;
++adjacent_edge->num_adjacent_faces;
/* Allocate memory for the boundary elements. */
- adjacent_edge->boundary_coords = MEM_reallocN(adjacent_edge->boundary_coords,
- adjacent_edge->num_adjacent_faces *
- sizeof(*adjacent_edge->boundary_coords));
- adjacent_edge->boundary_coords[adjacent_face_index] = MEM_malloc_arrayN(
- grid_size * 2, sizeof(SubdivCCGCoord), "ccg adjacent boundary");
+ adjacent_edge->boundary_coords = static_cast<SubdivCCGCoord **>(
+ MEM_reallocN(adjacent_edge->boundary_coords,
+ adjacent_edge->num_adjacent_faces * sizeof(*adjacent_edge->boundary_coords)));
+ adjacent_edge->boundary_coords[adjacent_face_index] = static_cast<SubdivCCGCoord *>(
+ MEM_malloc_arrayN(grid_size * 2, sizeof(SubdivCCGCoord), "ccg adjacent boundary"));
return adjacent_edge->boundary_coords[adjacent_face_index];
}
@@ -487,9 +493,10 @@ static void subdiv_ccg_init_faces_edge_neighborhood(SubdivCCG *subdiv_ccg)
static void subdiv_ccg_allocate_adjacent_vertices(SubdivCCG *subdiv_ccg, const int num_vertices)
{
subdiv_ccg->num_adjacent_vertices = num_vertices;
- subdiv_ccg->adjacent_vertices = MEM_calloc_arrayN(subdiv_ccg->num_adjacent_vertices,
- sizeof(*subdiv_ccg->adjacent_vertices),
- "ccg adjacent vertices");
+ subdiv_ccg->adjacent_vertices = static_cast<SubdivCCGAdjacentVertex *>(
+ MEM_calloc_arrayN(subdiv_ccg->num_adjacent_vertices,
+ sizeof(*subdiv_ccg->adjacent_vertices),
+ "ccg adjacent vertices"));
}
/* Returns storage where corner elements are to be stored. This is a pointer
@@ -500,9 +507,9 @@ static SubdivCCGCoord *subdiv_ccg_adjacent_vertex_add_face(
const int adjacent_face_index = adjacent_vertex->num_adjacent_faces;
++adjacent_vertex->num_adjacent_faces;
/* Allocate memory for the boundary elements. */
- adjacent_vertex->corner_coords = MEM_reallocN(adjacent_vertex->corner_coords,
- adjacent_vertex->num_adjacent_faces *
- sizeof(*adjacent_vertex->corner_coords));
+ adjacent_vertex->corner_coords = static_cast<SubdivCCGCoord *>(
+ MEM_reallocN(adjacent_vertex->corner_coords,
+ adjacent_vertex->num_adjacent_faces * sizeof(*adjacent_vertex->corner_coords)));
return &adjacent_vertex->corner_coords[adjacent_face_index];
}
@@ -564,7 +571,7 @@ SubdivCCG *BKE_subdiv_to_ccg(Subdiv *subdiv,
SubdivCCGMaterialFlagsEvaluator *material_flags_evaluator)
{
BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_CCG);
- SubdivCCG *subdiv_ccg = MEM_callocN(sizeof(SubdivCCG), "subdiv ccg");
+ SubdivCCG *subdiv_ccg = MEM_cnew<SubdivCCG>(__func__);
subdiv_ccg->subdiv = subdiv;
subdiv_ccg->level = bitscan_forward_i(settings->resolution - 1);
subdiv_ccg->grid_size = BKE_subdiv_grid_size_from_level(subdiv_ccg->level);
@@ -575,7 +582,7 @@ SubdivCCG *BKE_subdiv_to_ccg(Subdiv *subdiv,
if (!subdiv_ccg_evaluate_grids(subdiv_ccg, subdiv, mask_evaluator, material_flags_evaluator)) {
BKE_subdiv_ccg_destroy(subdiv_ccg);
BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_CCG);
- return NULL;
+ return nullptr;
}
BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_CCG);
return subdiv_ccg;
@@ -588,9 +595,9 @@ Mesh *BKE_subdiv_to_ccg_mesh(Subdiv *subdiv,
/* Make sure evaluator is ready. */
BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_CCG);
if (!BKE_subdiv_eval_begin_from_mesh(
- subdiv, coarse_mesh, NULL, SUBDIV_EVALUATOR_TYPE_CPU, NULL)) {
+ subdiv, coarse_mesh, nullptr, SUBDIV_EVALUATOR_TYPE_CPU, nullptr)) {
if (coarse_mesh->totpoly) {
- return NULL;
+ return nullptr;
}
}
BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_CCG);
@@ -599,16 +606,16 @@ Mesh *BKE_subdiv_to_ccg_mesh(Subdiv *subdiv,
SubdivCCGMaterialFlagsEvaluator material_flags_evaluator;
BKE_subdiv_ccg_material_flags_init_from_mesh(&material_flags_evaluator, coarse_mesh);
SubdivCCG *subdiv_ccg = BKE_subdiv_to_ccg(
- subdiv, settings, has_mask ? &mask_evaluator : NULL, &material_flags_evaluator);
+ subdiv, settings, has_mask ? &mask_evaluator : nullptr, &material_flags_evaluator);
if (has_mask) {
mask_evaluator.free(&mask_evaluator);
}
material_flags_evaluator.free(&material_flags_evaluator);
- if (subdiv_ccg == NULL) {
- return NULL;
+ if (subdiv_ccg == nullptr) {
+ return nullptr;
}
Mesh *result = BKE_mesh_new_nomain_from_template(coarse_mesh, 0, 0, 0, 0, 0);
- result->runtime.subdiv_ccg = subdiv_ccg;
+ result->runtime->subdiv_ccg = subdiv_ccg;
return result;
}
@@ -620,13 +627,13 @@ void BKE_subdiv_ccg_destroy(SubdivCCG *subdiv_ccg)
MEM_SAFE_FREE(subdiv_ccg->edges);
MEM_SAFE_FREE(subdiv_ccg->vertices);
MEM_SAFE_FREE(subdiv_ccg->grid_flag_mats);
- if (subdiv_ccg->grid_hidden != NULL) {
+ if (subdiv_ccg->grid_hidden != nullptr) {
for (int grid_index = 0; grid_index < num_grids; grid_index++) {
MEM_SAFE_FREE(subdiv_ccg->grid_hidden[grid_index]);
}
MEM_SAFE_FREE(subdiv_ccg->grid_hidden);
}
- if (subdiv_ccg->subdiv != NULL) {
+ if (subdiv_ccg->subdiv != nullptr) {
BKE_subdiv_free(subdiv_ccg->subdiv);
}
MEM_SAFE_FREE(subdiv_ccg->faces);
@@ -676,14 +683,14 @@ void BKE_subdiv_ccg_key_top_level(CCGKey *key, const SubdivCCG *subdiv_ccg)
/** \name Normals
* \{ */
-typedef struct RecalcInnerNormalsData {
+struct RecalcInnerNormalsData {
SubdivCCG *subdiv_ccg;
CCGKey *key;
-} RecalcInnerNormalsData;
+};
-typedef struct RecalcInnerNormalsTLSData {
+struct RecalcInnerNormalsTLSData {
float (*face_normals)[3];
-} RecalcInnerNormalsTLSData;
+};
/* Evaluate high-res face normals, for faces which corresponds to grid elements
*
@@ -698,9 +705,9 @@ static void subdiv_ccg_recalc_inner_face_normals(SubdivCCG *subdiv_ccg,
const int grid_size = subdiv_ccg->grid_size;
const int grid_size_1 = grid_size - 1;
CCGElem *grid = subdiv_ccg->grids[grid_index];
- if (tls->face_normals == NULL) {
- tls->face_normals = MEM_malloc_arrayN(
- grid_size_1 * grid_size_1, sizeof(float[3]), "CCG TLS normals");
+ if (tls->face_normals == nullptr) {
+ tls->face_normals = static_cast<float(*)[3]>(
+ MEM_malloc_arrayN(grid_size_1 * grid_size_1, sizeof(float[3]), "CCG TLS normals"));
}
for (int y = 0; y < grid_size - 1; y++) {
for (int x = 0; x < grid_size - 1; x++) {
@@ -766,16 +773,16 @@ static void subdiv_ccg_recalc_inner_normal_task(void *__restrict userdata_v,
const int grid_index,
const TaskParallelTLS *__restrict tls_v)
{
- RecalcInnerNormalsData *data = userdata_v;
- RecalcInnerNormalsTLSData *tls = tls_v->userdata_chunk;
+ RecalcInnerNormalsData *data = static_cast<RecalcInnerNormalsData *>(userdata_v);
+ RecalcInnerNormalsTLSData *tls = static_cast<RecalcInnerNormalsTLSData *>(tls_v->userdata_chunk);
subdiv_ccg_recalc_inner_face_normals(data->subdiv_ccg, data->key, tls, grid_index);
subdiv_ccg_average_inner_face_normals(data->subdiv_ccg, data->key, tls, grid_index);
}
-static void subdiv_ccg_recalc_inner_normal_free(const void *__restrict UNUSED(userdata),
+static void subdiv_ccg_recalc_inner_normal_free(const void *__restrict /*userdata*/,
void *__restrict tls_v)
{
- RecalcInnerNormalsTLSData *tls = tls_v;
+ RecalcInnerNormalsTLSData *tls = static_cast<RecalcInnerNormalsTLSData *>(tls_v);
MEM_SAFE_FREE(tls->face_normals);
}
@@ -784,11 +791,10 @@ static void subdiv_ccg_recalc_inner_grid_normals(SubdivCCG *subdiv_ccg)
{
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
- RecalcInnerNormalsData data = {
- .subdiv_ccg = subdiv_ccg,
- .key = &key,
- };
- RecalcInnerNormalsTLSData tls_data = {NULL};
+ RecalcInnerNormalsData data{};
+ data.subdiv_ccg = subdiv_ccg;
+ data.key = &key;
+ RecalcInnerNormalsTLSData tls_data = {nullptr};
TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
parallel_range_settings.userdata_chunk = &tls_data;
@@ -811,20 +817,20 @@ void BKE_subdiv_ccg_recalc_normals(SubdivCCG *subdiv_ccg)
BKE_subdiv_ccg_average_grids(subdiv_ccg);
}
-typedef struct RecalcModifiedInnerNormalsData {
+struct RecalcModifiedInnerNormalsData {
SubdivCCG *subdiv_ccg;
CCGKey *key;
SubdivCCGFace **effected_ccg_faces;
-} RecalcModifiedInnerNormalsData;
+};
static void subdiv_ccg_recalc_modified_inner_normal_task(void *__restrict userdata_v,
const int face_index,
const TaskParallelTLS *__restrict tls_v)
{
- RecalcModifiedInnerNormalsData *data = userdata_v;
+ RecalcModifiedInnerNormalsData *data = static_cast<RecalcModifiedInnerNormalsData *>(userdata_v);
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
CCGKey *key = data->key;
- RecalcInnerNormalsTLSData *tls = tls_v->userdata_chunk;
+ RecalcInnerNormalsTLSData *tls = static_cast<RecalcInnerNormalsTLSData *>(tls_v->userdata_chunk);
SubdivCCGFace **faces = data->effected_ccg_faces;
SubdivCCGFace *face = faces[face_index];
const int num_face_grids = face->num_grids;
@@ -836,25 +842,24 @@ static void subdiv_ccg_recalc_modified_inner_normal_task(void *__restrict userda
subdiv_ccg_average_inner_face_grids(subdiv_ccg, key, face);
}
-static void subdiv_ccg_recalc_modified_inner_normal_free(const void *__restrict UNUSED(userdata),
+static void subdiv_ccg_recalc_modified_inner_normal_free(const void *__restrict /*userdata*/,
void *__restrict tls_v)
{
- RecalcInnerNormalsTLSData *tls = tls_v;
+ RecalcInnerNormalsTLSData *tls = static_cast<RecalcInnerNormalsTLSData *>(tls_v);
MEM_SAFE_FREE(tls->face_normals);
}
static void subdiv_ccg_recalc_modified_inner_grid_normals(SubdivCCG *subdiv_ccg,
- struct CCGFace **effected_faces,
+ CCGFace **effected_faces,
int num_effected_faces)
{
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
- RecalcModifiedInnerNormalsData data = {
- .subdiv_ccg = subdiv_ccg,
- .key = &key,
- .effected_ccg_faces = (SubdivCCGFace **)effected_faces,
- };
- RecalcInnerNormalsTLSData tls_data = {NULL};
+ RecalcModifiedInnerNormalsData data{};
+ data.subdiv_ccg = subdiv_ccg;
+ data.key = &key;
+ data.effected_ccg_faces = (SubdivCCGFace **)effected_faces;
+ RecalcInnerNormalsTLSData tls_data = {nullptr};
TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
parallel_range_settings.userdata_chunk = &tls_data;
@@ -868,7 +873,7 @@ static void subdiv_ccg_recalc_modified_inner_grid_normals(SubdivCCG *subdiv_ccg,
}
void BKE_subdiv_ccg_update_normals(SubdivCCG *subdiv_ccg,
- struct CCGFace **effected_faces,
+ CCGFace **effected_faces,
int num_effected_faces)
{
if (!subdiv_ccg->has_normal) {
@@ -894,10 +899,10 @@ void BKE_subdiv_ccg_update_normals(SubdivCCG *subdiv_ccg,
/** \name Boundary averaging/stitching
* \{ */
-typedef struct AverageInnerGridsData {
+struct AverageInnerGridsData {
SubdivCCG *subdiv_ccg;
CCGKey *key;
-} AverageInnerGridsData;
+};
static void average_grid_element_value_v3(float a[3], float b[3])
{
@@ -926,11 +931,11 @@ static void average_grid_element(SubdivCCG *subdiv_ccg,
}
/* Accumulator to hold data during averaging. */
-typedef struct GridElementAccumulator {
+struct GridElementAccumulator {
float co[3];
float no[3];
float mask;
-} GridElementAccumulator;
+};
static void element_accumulator_init(GridElementAccumulator *accumulator)
{
@@ -1011,9 +1016,9 @@ static void subdiv_ccg_average_inner_face_grids(SubdivCCG *subdiv_ccg,
static void subdiv_ccg_average_inner_grids_task(void *__restrict userdata_v,
const int face_index,
- const TaskParallelTLS *__restrict UNUSED(tls_v))
+ const TaskParallelTLS *__restrict /*tls_v*/)
{
- AverageInnerGridsData *data = userdata_v;
+ AverageInnerGridsData *data = static_cast<AverageInnerGridsData *>(userdata_v);
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
CCGKey *key = data->key;
SubdivCCGFace *faces = subdiv_ccg->faces;
@@ -1021,17 +1026,17 @@ static void subdiv_ccg_average_inner_grids_task(void *__restrict userdata_v,
subdiv_ccg_average_inner_face_grids(subdiv_ccg, key, face);
}
-typedef struct AverageGridsBoundariesData {
+struct AverageGridsBoundariesData {
SubdivCCG *subdiv_ccg;
CCGKey *key;
/* Optional lookup table. Maps task index to index in `subdiv_ccg->adjacent_vertices`. */
const int *adjacent_edge_index_map;
-} AverageGridsBoundariesData;
+};
-typedef struct AverageGridsBoundariesTLSData {
+struct AverageGridsBoundariesTLSData {
GridElementAccumulator *accumulators;
-} AverageGridsBoundariesTLSData;
+};
static void subdiv_ccg_average_grids_boundary(SubdivCCG *subdiv_ccg,
CCGKey *key,
@@ -1044,9 +1049,9 @@ static void subdiv_ccg_average_grids_boundary(SubdivCCG *subdiv_ccg,
/* Nothing to average with. */
return;
}
- if (tls->accumulators == NULL) {
- tls->accumulators = MEM_calloc_arrayN(
- grid_size2, sizeof(GridElementAccumulator), "average accumulators");
+ if (tls->accumulators == nullptr) {
+ tls->accumulators = static_cast<GridElementAccumulator *>(
+ MEM_calloc_arrayN(grid_size2, sizeof(GridElementAccumulator), "average accumulators"));
}
else {
for (int i = 1; i < grid_size2 - 1; i++) {
@@ -1077,32 +1082,33 @@ static void subdiv_ccg_average_grids_boundaries_task(void *__restrict userdata_v
const int n,
const TaskParallelTLS *__restrict tls_v)
{
- AverageGridsBoundariesData *data = userdata_v;
+ AverageGridsBoundariesData *data = static_cast<AverageGridsBoundariesData *>(userdata_v);
const int adjacent_edge_index = data->adjacent_edge_index_map ?
data->adjacent_edge_index_map[n] :
n;
- AverageGridsBoundariesTLSData *tls = tls_v->userdata_chunk;
+ AverageGridsBoundariesTLSData *tls = static_cast<AverageGridsBoundariesTLSData *>(
+ tls_v->userdata_chunk);
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
CCGKey *key = data->key;
SubdivCCGAdjacentEdge *adjacent_edge = &subdiv_ccg->adjacent_edges[adjacent_edge_index];
subdiv_ccg_average_grids_boundary(subdiv_ccg, key, adjacent_edge, tls);
}
-static void subdiv_ccg_average_grids_boundaries_free(const void *__restrict UNUSED(userdata),
+static void subdiv_ccg_average_grids_boundaries_free(const void *__restrict /*userdata*/,
void *__restrict tls_v)
{
- AverageGridsBoundariesTLSData *tls = tls_v;
+ AverageGridsBoundariesTLSData *tls = static_cast<AverageGridsBoundariesTLSData *>(tls_v);
MEM_SAFE_FREE(tls->accumulators);
}
-typedef struct AverageGridsCornerData {
+struct AverageGridsCornerData {
SubdivCCG *subdiv_ccg;
CCGKey *key;
/* Optional lookup table. Maps task range index to index in `subdiv_ccg->adjacent_vertices`. */
const int *adjacent_vert_index_map;
-} AverageGridsCornerData;
+};
static void subdiv_ccg_average_grids_corners(SubdivCCG *subdiv_ccg,
CCGKey *key,
@@ -1131,9 +1137,9 @@ static void subdiv_ccg_average_grids_corners(SubdivCCG *subdiv_ccg,
static void subdiv_ccg_average_grids_corners_task(void *__restrict userdata_v,
const int n,
- const TaskParallelTLS *__restrict UNUSED(tls_v))
+ const TaskParallelTLS *__restrict /*tls_v*/)
{
- AverageGridsCornerData *data = userdata_v;
+ AverageGridsCornerData *data = static_cast<AverageGridsCornerData *>(userdata_v);
const int adjacent_vertex_index = data->adjacent_vert_index_map ?
data->adjacent_vert_index_map[n] :
n;
@@ -1150,9 +1156,11 @@ static void subdiv_ccg_average_boundaries(SubdivCCG *subdiv_ccg,
{
TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
- AverageGridsBoundariesData boundaries_data = {
- .subdiv_ccg = subdiv_ccg, .key = key, .adjacent_edge_index_map = adjacent_edge_index_map};
- AverageGridsBoundariesTLSData tls_data = {NULL};
+ AverageGridsBoundariesData boundaries_data{};
+ boundaries_data.subdiv_ccg = subdiv_ccg;
+ boundaries_data.key = key;
+ boundaries_data.adjacent_edge_index_map = adjacent_edge_index_map;
+ AverageGridsBoundariesTLSData tls_data = {nullptr};
parallel_range_settings.userdata_chunk = &tls_data;
parallel_range_settings.userdata_chunk_size = sizeof(tls_data);
parallel_range_settings.func_free = subdiv_ccg_average_grids_boundaries_free;
@@ -1165,7 +1173,7 @@ static void subdiv_ccg_average_boundaries(SubdivCCG *subdiv_ccg,
static void subdiv_ccg_average_all_boundaries(SubdivCCG *subdiv_ccg, CCGKey *key)
{
- subdiv_ccg_average_boundaries(subdiv_ccg, key, NULL, subdiv_ccg->num_adjacent_edges);
+ subdiv_ccg_average_boundaries(subdiv_ccg, key, nullptr, subdiv_ccg->num_adjacent_edges);
}
static void subdiv_ccg_average_corners(SubdivCCG *subdiv_ccg,
@@ -1175,8 +1183,10 @@ static void subdiv_ccg_average_corners(SubdivCCG *subdiv_ccg,
{
TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
- AverageGridsCornerData corner_data = {
- .subdiv_ccg = subdiv_ccg, .key = key, .adjacent_vert_index_map = adjacent_vert_index_map};
+ AverageGridsCornerData corner_data{};
+ corner_data.subdiv_ccg = subdiv_ccg;
+ corner_data.key = key;
+ corner_data.adjacent_vert_index_map = adjacent_vert_index_map;
BLI_task_parallel_range(0,
num_adjacent_vertices,
&corner_data,
@@ -1185,7 +1195,7 @@ static void subdiv_ccg_average_corners(SubdivCCG *subdiv_ccg,
}
static void subdiv_ccg_average_all_corners(SubdivCCG *subdiv_ccg, CCGKey *key)
{
- subdiv_ccg_average_corners(subdiv_ccg, key, NULL, subdiv_ccg->num_adjacent_vertices);
+ subdiv_ccg_average_corners(subdiv_ccg, key, nullptr, subdiv_ccg->num_adjacent_vertices);
}
static void subdiv_ccg_average_all_boundaries_and_corners(SubdivCCG *subdiv_ccg, CCGKey *key)
@@ -1202,10 +1212,9 @@ void BKE_subdiv_ccg_average_grids(SubdivCCG *subdiv_ccg)
BLI_parallel_range_settings_defaults(&parallel_range_settings);
/* Average inner boundaries of grids (within one face), across faces
* from different face-corners. */
- AverageInnerGridsData inner_data = {
- .subdiv_ccg = subdiv_ccg,
- .key = &key,
- };
+ AverageInnerGridsData inner_data{};
+ inner_data.subdiv_ccg = subdiv_ccg;
+ inner_data.key = &key;
BLI_task_parallel_range(0,
subdiv_ccg->num_faces,
&inner_data,
@@ -1215,7 +1224,7 @@ void BKE_subdiv_ccg_average_grids(SubdivCCG *subdiv_ccg)
}
static void subdiv_ccg_affected_face_adjacency(SubdivCCG *subdiv_ccg,
- struct CCGFace **effected_faces,
+ CCGFace **effected_faces,
int num_effected_faces,
GSet *r_adjacent_vertices,
GSet *r_adjacent_edges)
@@ -1262,7 +1271,7 @@ static void subdiv_ccg_affected_face_adjacency(SubdivCCG *subdiv_ccg,
void subdiv_ccg_average_faces_boundaries_and_corners(SubdivCCG *subdiv_ccg,
CCGKey *key,
- struct CCGFace **effected_faces,
+ CCGFace **effected_faces,
int num_effected_faces)
{
GSet *adjacent_vertices = BLI_gset_ptr_new(__func__);
@@ -1284,7 +1293,8 @@ void subdiv_ccg_average_faces_boundaries_and_corners(SubdivCCG *subdiv_ccg,
adjacent_edge_index_map = static_or_heap_storage_get(&index_heap, BLI_gset_len(adjacent_edges));
GSET_ITER_INDEX (gi, adjacent_edges, i) {
- SubdivCCGAdjacentEdge *adjacent_edge = BLI_gsetIterator_getKey(&gi);
+ SubdivCCGAdjacentEdge *adjacent_edge = static_cast<SubdivCCGAdjacentEdge *>(
+ BLI_gsetIterator_getKey(&gi));
adjacent_edge_index_map[i] = adjacent_edge - subdiv_ccg->adjacent_edges;
}
subdiv_ccg_average_boundaries(
@@ -1295,48 +1305,47 @@ void subdiv_ccg_average_faces_boundaries_and_corners(SubdivCCG *subdiv_ccg,
adjacent_vertex_index_map = static_or_heap_storage_get(&index_heap,
BLI_gset_len(adjacent_vertices));
GSET_ITER_INDEX (gi, adjacent_vertices, i) {
- SubdivCCGAdjacentVertex *adjacent_vertex = BLI_gsetIterator_getKey(&gi);
+ SubdivCCGAdjacentVertex *adjacent_vertex = static_cast<SubdivCCGAdjacentVertex *>(
+ BLI_gsetIterator_getKey(&gi));
adjacent_vertex_index_map[i] = adjacent_vertex - subdiv_ccg->adjacent_vertices;
}
subdiv_ccg_average_corners(
subdiv_ccg, key, adjacent_vertex_index_map, BLI_gset_len(adjacent_vertices));
- BLI_gset_free(adjacent_vertices, NULL);
- BLI_gset_free(adjacent_edges, NULL);
+ BLI_gset_free(adjacent_vertices, nullptr);
+ BLI_gset_free(adjacent_edges, nullptr);
static_or_heap_storage_free(&index_heap);
}
-typedef struct StitchFacesInnerGridsData {
+struct StitchFacesInnerGridsData {
SubdivCCG *subdiv_ccg;
CCGKey *key;
- struct CCGFace **effected_ccg_faces;
-} StitchFacesInnerGridsData;
+ CCGFace **effected_ccg_faces;
+};
-static void subdiv_ccg_stitch_face_inner_grids_task(
- void *__restrict userdata_v,
- const int face_index,
- const TaskParallelTLS *__restrict UNUSED(tls_v))
+static void subdiv_ccg_stitch_face_inner_grids_task(void *__restrict userdata_v,
+ const int face_index,
+ const TaskParallelTLS *__restrict /*tls_v*/)
{
- StitchFacesInnerGridsData *data = userdata_v;
+ StitchFacesInnerGridsData *data = static_cast<StitchFacesInnerGridsData *>(userdata_v);
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
CCGKey *key = data->key;
- struct CCGFace **effected_ccg_faces = data->effected_ccg_faces;
- struct CCGFace *effected_ccg_face = effected_ccg_faces[face_index];
+ CCGFace **effected_ccg_faces = data->effected_ccg_faces;
+ CCGFace *effected_ccg_face = effected_ccg_faces[face_index];
SubdivCCGFace *face = (SubdivCCGFace *)effected_ccg_face;
subdiv_ccg_average_inner_face_grids(subdiv_ccg, key, face);
}
void BKE_subdiv_ccg_average_stitch_faces(SubdivCCG *subdiv_ccg,
- struct CCGFace **effected_faces,
+ CCGFace **effected_faces,
int num_effected_faces)
{
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
- StitchFacesInnerGridsData data = {
- .subdiv_ccg = subdiv_ccg,
- .key = &key,
- .effected_ccg_faces = effected_faces,
- };
+ StitchFacesInnerGridsData data{};
+ data.subdiv_ccg = subdiv_ccg;
+ data.key = &key;
+ data.effected_ccg_faces = effected_faces;
TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
BLI_task_parallel_range(0,
@@ -1402,8 +1411,8 @@ BLI_INLINE void subdiv_ccg_neighbors_init(SubdivCCGNeighbors *neighbors,
neighbors->coords = neighbors->coords_fixed;
}
else {
- neighbors->coords = MEM_mallocN(sizeof(*neighbors->coords) * size,
- "SubdivCCGNeighbors.coords");
+ neighbors->coords = static_cast<SubdivCCGCoord *>(
+ MEM_mallocN(sizeof(*neighbors->coords) * size, "SubdivCCGNeighbors.coords"));
}
}
@@ -1437,7 +1446,7 @@ BLI_INLINE bool is_inner_edge_grid_coordinate(const SubdivCCG *subdiv_ccg,
return false;
}
-BLI_INLINE SubdivCCGCoord coord_at_prev_row(const SubdivCCG *UNUSED(subdiv_ccg),
+BLI_INLINE SubdivCCGCoord coord_at_prev_row(const SubdivCCG * /*subdiv_ccg*/,
const SubdivCCGCoord *coord)
{
BLI_assert(coord->y > 0);
@@ -1455,7 +1464,7 @@ BLI_INLINE SubdivCCGCoord coord_at_next_row(const SubdivCCG *subdiv_ccg,
return result;
}
-BLI_INLINE SubdivCCGCoord coord_at_prev_col(const SubdivCCG *UNUSED(subdiv_ccg),
+BLI_INLINE SubdivCCGCoord coord_at_prev_col(const SubdivCCG * /*subdiv_ccg*/,
const SubdivCCGCoord *coord)
{
BLI_assert(coord->x > 0);
@@ -1698,7 +1707,7 @@ static int adjacent_edge_point_index_from_coord(const SubdivCCG *subdiv_ccg,
directional_edge_vertex_index = edge_vertices_indices[1];
}
- /* Flip the index if the edde points opposite direction. */
+ /* Flip the index if the edge points opposite direction. */
if (adjacent_vertex_index != directional_edge_vertex_index) {
const int num_edge_points = subdiv_ccg->grid_size * 2;
adjacent_edge_point_index = num_edge_points - adjacent_edge_point_index - 1;
@@ -1946,17 +1955,17 @@ int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG *subdiv_ccg, const int gri
const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG *subdiv_ccg)
{
- if (subdiv_ccg->cache_.start_face_grid_index == NULL) {
+ if (subdiv_ccg->cache_.start_face_grid_index == nullptr) {
const Subdiv *subdiv = subdiv_ccg->subdiv;
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
- if (topology_refiner == NULL) {
- return NULL;
+ if (topology_refiner == nullptr) {
+ return nullptr;
}
const int num_coarse_faces = topology_refiner->getNumFaces(topology_refiner);
- subdiv_ccg->cache_.start_face_grid_index = MEM_malloc_arrayN(
- num_coarse_faces, sizeof(int), "start_face_grid_index");
+ subdiv_ccg->cache_.start_face_grid_index = static_cast<int *>(
+ MEM_malloc_arrayN(num_coarse_faces, sizeof(int), "start_face_grid_index"));
int start_grid_index = 0;
for (int face_index = 0; face_index < num_coarse_faces; face_index++) {
@@ -2034,7 +2043,7 @@ SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const Subdi
void BKE_subdiv_ccg_grid_hidden_ensure(SubdivCCG *subdiv_ccg, int grid_index)
{
- if (subdiv_ccg->grid_hidden[grid_index] != NULL) {
+ if (subdiv_ccg->grid_hidden[grid_index] != nullptr) {
return;
}
@@ -2043,6 +2052,11 @@ void BKE_subdiv_ccg_grid_hidden_ensure(SubdivCCG *subdiv_ccg, int grid_index)
subdiv_ccg->grid_hidden[grid_index] = BLI_BITMAP_NEW(key.grid_area, __func__);
}
+void BKE_subdiv_ccg_grid_hidden_free(SubdivCCG *subdiv_ccg, int grid_index)
+{
+ MEM_SAFE_FREE(subdiv_ccg->grid_hidden[grid_index]);
+}
+
static void subdiv_ccg_coord_to_ptex_coord(const SubdivCCG *subdiv_ccg,
const SubdivCCGCoord *coord,
int *r_ptex_face_index,
diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c
index b13aec37c78..aabed2cea28 100644
--- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c
+++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c
@@ -41,6 +41,8 @@ typedef struct ConverterStorage {
/* CustomData layer for vertex sharpnesses. */
const float *cd_vertex_crease;
+ /* CustomData layer for edge sharpness. */
+ const float *cd_edge_crease;
/* Indexed by loop index, value denotes index of face-varying vertex
* which corresponds to the UV coordinate.
*/
@@ -157,12 +159,11 @@ static float get_edge_sharpness(const OpenSubdiv_Converter *converter, int manif
return 10.0f;
}
#endif
- if (!storage->settings.use_creases) {
+ if (!storage->settings.use_creases || storage->cd_edge_crease == NULL) {
return 0.0f;
}
const int edge_index = storage->manifold_edge_index_reverse[manifold_edge_index];
- const MEdge *medge = storage->edges;
- return BKE_subdiv_crease_to_sharpness_char(medge[edge_index].crease);
+ return BKE_subdiv_crease_to_sharpness_f(storage->cd_edge_crease[edge_index]);
}
static bool is_infinite_sharp_vertex(const OpenSubdiv_Converter *converter,
@@ -211,6 +212,7 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la
UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(
storage->polys,
(const bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly"),
+ (const bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".select_poly"),
storage->loops,
mloopuv,
num_poly,
@@ -398,6 +400,7 @@ static void init_user_data(OpenSubdiv_Converter *converter,
user_data->polys = BKE_mesh_polys(mesh);
user_data->loops = BKE_mesh_loops(mesh);
user_data->cd_vertex_crease = CustomData_get_layer(&mesh->vdata, CD_CREASE);
+ user_data->cd_edge_crease = CustomData_get_layer(&mesh->edata, CD_CREASE);
user_data->loop_uv_indices = NULL;
initialize_manifold_indices(user_data);
converter->user_data = user_data;
diff --git a/source/blender/blenkernel/intern/subdiv_mesh.cc b/source/blender/blenkernel/intern/subdiv_mesh.cc
index 44bdd6e6d06..e1c434f2b2e 100644
--- a/source/blender/blenkernel/intern/subdiv_mesh.cc
+++ b/source/blender/blenkernel/intern/subdiv_mesh.cc
@@ -222,7 +222,7 @@ static void vertex_interpolation_init(const SubdivMeshContext *ctx,
vertex_interpolation->vertex_data_storage_allocated = true;
/* Interpolate center of poly right away, it stays unchanged for all
* ptex faces. */
- const float weight = 1.0f / (float)coarse_poly->totloop;
+ const float weight = 1.0f / float(coarse_poly->totloop);
blender::Array<float, 32> weights(coarse_poly->totloop);
blender::Array<int, 32> indices(coarse_poly->totloop);
for (int i = 0; i < coarse_poly->totloop; i++) {
@@ -267,14 +267,13 @@ static void vertex_interpolation_from_corner(const SubdivMeshContext *ctx,
const int first_loop_index = loops_of_ptex.first_loop - coarse_mloop;
const int last_loop_index = loops_of_ptex.last_loop - coarse_mloop;
const int first_indices[2] = {
- static_cast<int>(coarse_mloop[first_loop_index].v),
- static_cast<int>(
- coarse_mloop[coarse_poly->loopstart +
+ int(coarse_mloop[first_loop_index].v),
+ int(coarse_mloop[coarse_poly->loopstart +
(first_loop_index - coarse_poly->loopstart + 1) % coarse_poly->totloop]
.v)};
const int last_indices[2] = {
- static_cast<int>(coarse_mloop[first_loop_index].v),
- static_cast<int>(coarse_mloop[last_loop_index].v),
+ int(coarse_mloop[first_loop_index].v),
+ int(coarse_mloop[last_loop_index].v),
};
CustomData_interp(vertex_data,
&vertex_interpolation->vertex_data_storage,
@@ -356,7 +355,7 @@ static void loop_interpolation_init(const SubdivMeshContext *ctx,
loop_interpolation->loop_data_storage_allocated = true;
/* Interpolate center of poly right away, it stays unchanged for all
* ptex faces. */
- const float weight = 1.0f / (float)coarse_poly->totloop;
+ const float weight = 1.0f / float(coarse_poly->totloop);
blender::Array<float, 32> weights(coarse_poly->totloop);
blender::Array<int, 32> indices(coarse_poly->totloop);
for (int i = 0; i < coarse_poly->totloop; i++) {
@@ -402,8 +401,8 @@ static void loop_interpolation_from_corner(const SubdivMeshContext *ctx,
(first_loop_index - base_loop_index + 1) % coarse_poly->totloop;
const int first_indices[2] = {first_loop_index, second_loop_index};
const int last_indices[2] = {
- static_cast<int>(loops_of_ptex.last_loop - coarse_mloop),
- static_cast<int>(loops_of_ptex.first_loop - coarse_mloop),
+ int(loops_of_ptex.last_loop - coarse_mloop),
+ int(loops_of_ptex.first_loop - coarse_mloop),
};
CustomData_interp(
loop_data, &loop_interpolation->loop_data_storage, first_indices, weights, nullptr, 2, 1);
@@ -515,21 +514,23 @@ static bool subdiv_mesh_topology_info(const SubdivForeachContext *foreach_contex
const int num_edges,
const int num_loops,
const int num_polygons,
- const int *UNUSED(subdiv_polygon_offset))
+ const int * /*subdiv_polygon_offset*/)
{
/* Multi-resolution grid data will be applied or become invalid after subdivision,
- * so don't try to preserve it and use memory. */
+ * so don't try to preserve it and use memory. Crease values should also not be interpolated. */
CustomData_MeshMasks mask = CD_MASK_EVERYTHING;
mask.lmask &= ~CD_MASK_MULTIRES_GRIDS;
+ mask.vmask &= ~CD_MASK_CREASE;
+ mask.emask &= ~CD_MASK_CREASE;
SubdivMeshContext *subdiv_context = static_cast<SubdivMeshContext *>(foreach_context->user_data);
subdiv_context->subdiv_mesh = BKE_mesh_new_nomain_from_template_ex(
subdiv_context->coarse_mesh, num_vertices, num_edges, 0, num_loops, num_polygons, mask);
subdiv_mesh_ctx_cache_custom_data_layers(subdiv_context);
subdiv_mesh_prepare_accumulator(subdiv_context, num_vertices);
- MEM_SAFE_FREE(subdiv_context->subdiv_mesh->runtime.subsurf_face_dot_tags);
- subdiv_context->subdiv_mesh->runtime.subsurf_face_dot_tags = BLI_BITMAP_NEW(num_vertices,
- __func__);
+ MEM_SAFE_FREE(subdiv_context->subdiv_mesh->runtime->subsurf_face_dot_tags);
+ subdiv_context->subdiv_mesh->runtime->subsurf_face_dot_tags = BLI_BITMAP_NEW(num_vertices,
+ __func__);
return true;
}
@@ -594,7 +595,7 @@ static void evaluate_vertex_and_apply_displacement_copy(const SubdivMeshContext
/* Evaluate undeformed texture coordinate. */
subdiv_vertex_orco_evaluate(ctx, ptex_face_index, u, v, subdiv_vertex_index);
/* Remove face-dot flag. This can happen if there is more than one subsurf modifier. */
- BLI_BITMAP_DISABLE(ctx->subdiv_mesh->runtime.subsurf_face_dot_tags, subdiv_vertex_index);
+ BLI_BITMAP_DISABLE(ctx->subdiv_mesh->runtime->subsurf_face_dot_tags, subdiv_vertex_index);
}
static void evaluate_vertex_and_apply_displacement_interpolate(
@@ -625,7 +626,7 @@ static void evaluate_vertex_and_apply_displacement_interpolate(
static void subdiv_mesh_vertex_displacement_every_corner_or_edge(
const SubdivForeachContext *foreach_context,
- void *UNUSED(tls),
+ void * /*tls*/,
const int ptex_face_index,
const float u,
const float v,
@@ -642,9 +643,9 @@ static void subdiv_mesh_vertex_displacement_every_corner(
const int ptex_face_index,
const float u,
const float v,
- const int UNUSED(coarse_vertex_index),
- const int UNUSED(coarse_poly_index),
- const int UNUSED(coarse_corner),
+ const int /*coarse_vertex_index*/,
+ const int /*coarse_poly_index*/,
+ const int /*coarse_corner*/,
const int subdiv_vertex_index)
{
subdiv_mesh_vertex_displacement_every_corner_or_edge(
@@ -656,9 +657,9 @@ static void subdiv_mesh_vertex_displacement_every_edge(const SubdivForeachContex
const int ptex_face_index,
const float u,
const float v,
- const int UNUSED(coarse_edge_index),
- const int UNUSED(coarse_poly_index),
- const int UNUSED(coarse_corner),
+ const int /*coarse_edge_index*/,
+ const int /*coarse_poly_index*/,
+ const int /*coarse_corner*/,
const int subdiv_vertex_index)
{
subdiv_mesh_vertex_displacement_every_corner_or_edge(
@@ -666,13 +667,13 @@ static void subdiv_mesh_vertex_displacement_every_edge(const SubdivForeachContex
}
static void subdiv_mesh_vertex_corner(const SubdivForeachContext *foreach_context,
- void *UNUSED(tls),
+ void * /*tls*/,
const int ptex_face_index,
const float u,
const float v,
const int coarse_vertex_index,
- const int UNUSED(coarse_poly_index),
- const int UNUSED(coarse_corner),
+ const int /*coarse_poly_index*/,
+ const int /*coarse_corner*/,
const int subdiv_vertex_index)
{
BLI_assert(coarse_vertex_index != ORIGINDEX_NONE);
@@ -716,7 +717,7 @@ static void subdiv_mesh_vertex_edge(const SubdivForeachContext *foreach_context,
const int ptex_face_index,
const float u,
const float v,
- const int UNUSED(coarse_edge_index),
+ const int /*coarse_edge_index*/,
const int coarse_poly_index,
const int coarse_corner,
const int subdiv_vertex_index)
@@ -752,7 +753,7 @@ static void subdiv_mesh_tag_center_vertex(const MPoly *coarse_poly,
Mesh *subdiv_mesh)
{
if (subdiv_mesh_is_center_vertex(coarse_poly, u, v)) {
- BLI_BITMAP_ENABLE(subdiv_mesh->runtime.subsurf_face_dot_tags, subdiv_vertex_index);
+ BLI_BITMAP_ENABLE(subdiv_mesh->runtime->subsurf_face_dot_tags, subdiv_vertex_index);
}
}
@@ -790,10 +791,10 @@ static void subdiv_copy_edge_data(SubdivMeshContext *ctx,
{
const int subdiv_edge_index = subdiv_edge - ctx->subdiv_edges;
if (coarse_edge == nullptr) {
- subdiv_edge->crease = 0;
+ /* TODO: Ensure crease layer isn't copied to result. */
subdiv_edge->flag = 0;
if (!ctx->settings->use_optimal_display) {
- subdiv_edge->flag |= ME_EDGERENDER;
+ subdiv_edge->flag |= ME_EDGEDRAW;
}
if (ctx->edge_origindex != nullptr) {
ctx->edge_origindex[subdiv_edge_index] = ORIGINDEX_NONE;
@@ -803,14 +804,14 @@ static void subdiv_copy_edge_data(SubdivMeshContext *ctx,
const int coarse_edge_index = coarse_edge - ctx->coarse_edges;
CustomData_copy_data(
&ctx->coarse_mesh->edata, &ctx->subdiv_mesh->edata, coarse_edge_index, subdiv_edge_index, 1);
- subdiv_edge->flag |= ME_EDGERENDER;
+ subdiv_edge->flag |= ME_EDGEDRAW;
}
static void subdiv_mesh_edge(const SubdivForeachContext *foreach_context,
- void *UNUSED(tls),
+ void * /*tls*/,
const int coarse_edge_index,
const int subdiv_edge_index,
- const bool UNUSED(is_loose),
+ const bool /*is_loose*/,
const int subdiv_v1,
const int subdiv_v2)
{
@@ -901,7 +902,7 @@ static void subdiv_mesh_loop(const SubdivForeachContext *foreach_context,
const int ptex_face_index,
const float u,
const float v,
- const int UNUSED(coarse_loop_index),
+ const int /*coarse_loop_index*/,
const int coarse_poly_index,
const int coarse_corner,
const int subdiv_loop_index,
@@ -937,7 +938,7 @@ static void subdiv_copy_poly_data(const SubdivMeshContext *ctx,
}
static void subdiv_mesh_poly(const SubdivForeachContext *foreach_context,
- void *UNUSED(tls),
+ void * /*tls*/,
const int coarse_poly_index,
const int subdiv_poly_index,
const int start_loop_index,
@@ -959,7 +960,7 @@ static void subdiv_mesh_poly(const SubdivForeachContext *foreach_context,
* \{ */
static void subdiv_mesh_vertex_loose(const SubdivForeachContext *foreach_context,
- void *UNUSED(tls),
+ void * /*tls*/,
const int coarse_vertex_index,
const int subdiv_vertex_index)
{
@@ -1083,8 +1084,7 @@ static void subdiv_mesh_vertex_of_loose_edge_interpolate(SubdivMeshContext *ctx,
BLI_assert(u > 0.0f);
BLI_assert(u < 1.0f);
const float interpolation_weights[2] = {1.0f - u, u};
- const int coarse_vertex_indices[2] = {static_cast<int>(coarse_edge->v1),
- static_cast<int>(coarse_edge->v2)};
+ const int coarse_vertex_indices[2] = {int(coarse_edge->v1), int(coarse_edge->v2)};
CustomData_interp(&coarse_mesh->vdata,
&subdiv_mesh->vdata,
coarse_vertex_indices,
@@ -1098,7 +1098,7 @@ static void subdiv_mesh_vertex_of_loose_edge_interpolate(SubdivMeshContext *ctx,
}
static void subdiv_mesh_vertex_of_loose_edge(const SubdivForeachContext *foreach_context,
- void *UNUSED(tls),
+ void * /*tls*/,
const int coarse_edge_index,
const float u,
const int subdiv_vertex_index)
@@ -1110,9 +1110,9 @@ static void subdiv_mesh_vertex_of_loose_edge(const SubdivForeachContext *foreach
/* Lazily initialize a vertex to edge map to avoid quadratic runtime when subdividing loose
* edges. Do this here to avoid the cost in common cases when there are no loose edges at all. */
- if (ctx->vert_to_edge_map == NULL) {
+ if (ctx->vert_to_edge_map == nullptr) {
std::lock_guard lock{ctx->vert_to_edge_map_mutex};
- if (ctx->vert_to_edge_map == NULL) {
+ if (ctx->vert_to_edge_map == nullptr) {
BKE_mesh_vert_edge_map_create(&ctx->vert_to_edge_map,
&ctx->vert_to_edge_buffer,
ctx->coarse_edges,
@@ -1135,8 +1135,6 @@ static void subdiv_mesh_vertex_of_loose_edge(const SubdivForeachContext *foreach
is_simple,
u,
subdiv_vertex->co);
- /* Reset flags and such. */
- subdiv_vertex->flag = 0;
}
/** \} */
@@ -1193,7 +1191,7 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv,
}
}
/* Initialize subdivision mesh creation context. */
- SubdivMeshContext subdiv_context = {0};
+ SubdivMeshContext subdiv_context{};
subdiv_context.settings = settings;
subdiv_context.coarse_mesh = coarse_mesh;
@@ -1208,7 +1206,7 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv,
BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY);
SubdivForeachContext foreach_context;
setup_foreach_callbacks(&subdiv_context, &foreach_context);
- SubdivMeshTLS tls = {0};
+ SubdivMeshTLS tls{};
foreach_context.user_data = &subdiv_context;
foreach_context.user_data_tls_size = sizeof(SubdivMeshTLS);
foreach_context.user_data_tls = &tls;
diff --git a/source/blender/blenkernel/intern/subdiv_modifier.c b/source/blender/blenkernel/intern/subdiv_modifier.cc
index 2271fd90bda..84b772db045 100644
--- a/source/blender/blenkernel/intern/subdiv_modifier.c
+++ b/source/blender/blenkernel/intern/subdiv_modifier.cc
@@ -11,6 +11,7 @@
#include "DNA_scene_types.h"
#include "DNA_userdef_types.h"
+#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_subdiv.h"
@@ -46,8 +47,8 @@ bool BKE_subsurf_modifier_runtime_init(SubsurfModifierData *smd, const bool use_
}
/* Allocate runtime data if it did not exist yet. */
- if (runtime_data == NULL) {
- runtime_data = MEM_callocN(sizeof(*runtime_data), "subsurf runtime");
+ if (runtime_data == nullptr) {
+ runtime_data = MEM_cnew<SubsurfRuntimeData>(__func__);
smd->modifier.runtime = runtime_data;
}
runtime_data->settings = settings;
@@ -58,7 +59,7 @@ static ModifierData *modifier_get_last_enabled_for_mode(const Scene *scene,
const Object *ob,
int required_mode)
{
- ModifierData *md = ob->modifiers.last;
+ ModifierData *md = static_cast<ModifierData *>(ob->modifiers.last);
while (md) {
if (BKE_modifier_is_enabled(scene, md, required_mode)) {
@@ -83,7 +84,7 @@ static bool subsurf_modifier_use_autosmooth_or_split_normals(const SubsurfModifi
return (mesh->flag & ME_AUTOSMOOTH) || BKE_subsurf_modifier_use_custom_loop_normals(smd, mesh);
}
-static bool is_subdivision_evaluation_possible_on_gpu(void)
+static bool is_subdivision_evaluation_possible_on_gpu()
{
/* Only OpenGL is supported for OpenSubdiv evaluation for now. */
if (GPU_backend_get_type() != GPU_BACKEND_OPENGL) {
@@ -143,11 +144,11 @@ bool BKE_subsurf_modifier_can_do_gpu_subdiv(const Scene *scene,
bool BKE_subsurf_modifier_has_gpu_subdiv(const Mesh *mesh)
{
- SubsurfRuntimeData *runtime_data = mesh->runtime.subsurf_runtime_data;
+ SubsurfRuntimeData *runtime_data = mesh->runtime->subsurf_runtime_data;
return runtime_data && runtime_data->has_gpu_subdiv;
}
-void (*BKE_subsurf_modifier_free_gpu_cache_cb)(Subdiv *subdiv) = NULL;
+void (*BKE_subsurf_modifier_free_gpu_cache_cb)(Subdiv *subdiv) = nullptr;
Subdiv *BKE_subsurf_modifier_subdiv_descriptor_ensure(SubsurfRuntimeData *runtime_data,
const Mesh *mesh,
@@ -155,7 +156,7 @@ Subdiv *BKE_subsurf_modifier_subdiv_descriptor_ensure(SubsurfRuntimeData *runtim
{
if (runtime_data->subdiv && runtime_data->set_by_draw_code != for_draw_code) {
BKE_subdiv_free(runtime_data->subdiv);
- runtime_data->subdiv = NULL;
+ runtime_data->subdiv = nullptr;
}
Subdiv *subdiv = BKE_subdiv_update_from_mesh(
runtime_data->subdiv, &runtime_data->settings, mesh);
@@ -170,5 +171,5 @@ int BKE_subsurf_modifier_eval_required_mode(bool is_final_render, bool is_edit_m
return eModifierMode_Render;
}
- return eModifierMode_Realtime | (is_edit_mode ? eModifierMode_Editmode : 0);
+ return eModifierMode_Realtime | (is_edit_mode ? int(eModifierMode_Editmode) : 0);
}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 0e5f9f30243..80fb637b76e 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -285,7 +285,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss,
* Also, initially intention is to treat merged vertices from mirror modifier as seams.
* This fixes a very old regression (2.49 was correct here) */
vmap = BKE_mesh_uv_vert_map_create(
- mpoly, NULL, mloop, mloopuv, totface, totvert, limit, false, true);
+ mpoly, NULL, NULL, mloop, mloopuv, totface, totvert, limit, false, true);
if (!vmap) {
return 0;
}
@@ -327,7 +327,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss,
int nverts = mp->totloop;
int j, j_next;
CCGFace *origf = ccgSubSurf_getFace(origss, POINTER_FROM_INT(i));
- /* unsigned int *fv = &mp->v1; */
+ /* uint *fv = &mp->v1; */
MLoop *ml = mloop + mp->loopstart;
#ifdef USE_DYNSIZE
@@ -340,8 +340,8 @@ static int ss_sync_from_uv(CCGSubSurf *ss,
get_face_uv_map_vert(vmap, mpoly, ml, i, fverts);
for (j = 0, j_next = nverts - 1; j < nverts; j_next = j++) {
- unsigned int v0 = POINTER_AS_UINT(fverts[j_next]);
- unsigned int v1 = POINTER_AS_UINT(fverts[j]);
+ uint v0 = POINTER_AS_UINT(fverts[j_next]);
+ uint v1 = POINTER_AS_UINT(fverts[j]);
if (BLI_edgeset_add(eset, v0, v1)) {
CCGEdge *e, *orige = ccgSubSurf_getFaceEdge(origf, j_next);
@@ -592,11 +592,12 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss,
me = medge;
index = (int *)dm->getEdgeDataArray(dm, CD_ORIGINDEX);
+ const float *creases = (const float *)dm->getEdgeDataArray(dm, CD_CREASE);
for (i = 0; i < totedge; i++, me++) {
CCGEdge *e;
float crease;
- crease = useFlatSubdiv ? creaseFactor : me->crease * creaseFactor / 255.0f;
+ crease = useFlatSubdiv ? creaseFactor : (creases ? creases[i] * creaseFactor : 0.0f);
ccgSubSurf_syncEdge(
ss, POINTER_FROM_INT(i), POINTER_FROM_UINT(me->v1), POINTER_FROM_UINT(me->v2), crease, &e);
@@ -879,7 +880,6 @@ static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float r_no[3])
BLI_INLINE void ccgDM_to_MVert(MVert *mv, const CCGKey *key, CCGElem *elem)
{
copy_v3_v3(mv->co, CCG_elem_co(key, elem));
- mv->flag = 0;
}
static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
@@ -892,7 +892,7 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
int totvert, totedge, totface;
int gridSize = ccgSubSurf_getGridSize(ss);
int edgeSize = ccgSubSurf_getEdgeSize(ss);
- unsigned int i = 0;
+ uint i = 0;
CCG_key_top_level(&key, ss);
@@ -949,7 +949,6 @@ BLI_INLINE void ccgDM_to_MEdge(MEdge *med, const int v1, const int v2, const sho
{
med->v1 = v1;
med->v2 = v2;
- med->crease = 0;
med->flag = flag;
}
@@ -961,9 +960,9 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
int totedge, totface;
int gridSize = ccgSubSurf_getGridSize(ss);
int edgeSize = ccgSubSurf_getEdgeSize(ss);
- unsigned int i = 0;
+ uint i = 0;
short *edgeFlags = ccgdm->edgeFlags;
- const short ed_interior_flag = ccgdm->drawInteriorEdges ? (ME_EDGEDRAW | ME_EDGERENDER) : 0;
+ const short ed_interior_flag = ccgdm->drawInteriorEdges ? ME_EDGEDRAW : 0;
totface = ccgSubSurf_getNumFaces(ss);
for (index = 0; index < totface; index++) {
@@ -1006,11 +1005,11 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
if (edgeFlags) {
if (edgeIdx != -1) {
- ed_flag |= ((edgeFlags[index] & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER);
+ ed_flag |= ((edgeFlags[index] & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW);
}
}
else {
- ed_flag |= ME_EDGEDRAW | ME_EDGERENDER;
+ ed_flag |= ME_EDGEDRAW;
}
for (x = 0; x < edgeSize - 1; x++) {
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 1444ba1e1c4..1a0c0716fcd 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -354,7 +354,7 @@ static void cleanup_textline(TextLine *tl)
* used for load and reload (unlike txt_insert_buf)
* assumes all fields are empty
*/
-static void text_from_buf(Text *text, const unsigned char *buffer, const int len)
+static void text_from_buf(Text *text, const uchar *buffer, const int len)
{
int i, llen, lines_count;
@@ -419,7 +419,7 @@ static void text_from_buf(Text *text, const unsigned char *buffer, const int len
bool BKE_text_reload(Text *text)
{
- unsigned char *buffer;
+ uchar *buffer;
size_t buffer_len;
char filepath_abs[FILE_MAX];
BLI_stat_t st;
@@ -459,7 +459,7 @@ Text *BKE_text_load_ex(Main *bmain,
const char *relbase,
const bool is_internal)
{
- unsigned char *buffer;
+ uchar *buffer;
size_t buffer_len;
Text *ta;
char filepath_abs[FILE_MAX];
@@ -896,8 +896,7 @@ void txt_move_left(Text *text, const bool sel)
(*charp) -= tabsize;
}
else {
- const char *prev = BLI_str_find_prev_char_utf8((*linep)->line + *charp, (*linep)->line);
- *charp = prev - (*linep)->line;
+ BLI_str_cursor_step_prev_utf8((*linep)->line, (*linep)->len, charp);
}
}
@@ -941,7 +940,7 @@ void txt_move_right(Text *text, const bool sel)
(*charp) += tabsize;
}
else {
- (*charp) += BLI_str_utf8_size((*linep)->line + *charp);
+ BLI_str_cursor_step_next_utf8((*linep)->line, (*linep)->len, charp);
}
}
@@ -1088,16 +1087,16 @@ void txt_move_eof(Text *text, const bool sel)
}
}
-void txt_move_toline(Text *text, unsigned int line, const bool sel)
+void txt_move_toline(Text *text, uint line, const bool sel)
{
txt_move_to(text, line, 0, sel);
}
-void txt_move_to(Text *text, unsigned int line, unsigned int ch, const bool sel)
+void txt_move_to(Text *text, uint line, uint ch, const bool sel)
{
TextLine **linep;
int *charp;
- unsigned int i;
+ uint i;
if (sel) {
txt_curs_sel(text, &linep, &charp);
@@ -1118,8 +1117,8 @@ void txt_move_to(Text *text, unsigned int line, unsigned int ch, const bool sel)
break;
}
}
- if (ch > (unsigned int)((*linep)->len)) {
- ch = (unsigned int)((*linep)->len);
+ if (ch > (uint)((*linep)->len)) {
+ ch = (uint)((*linep)->len);
}
*charp = ch;
@@ -1757,8 +1756,6 @@ void txt_duplicate_line(Text *text)
void txt_delete_char(Text *text)
{
- unsigned int c = '\n';
-
if (!text->curl) {
return;
}
@@ -1778,10 +1775,9 @@ void txt_delete_char(Text *text)
}
}
else { /* Just deleting a char */
- size_t c_len = text->curc;
- c = BLI_str_utf8_as_unicode_step(text->curl->line, text->curl->len, &c_len);
- c_len -= text->curc;
- UNUSED_VARS(c);
+ int pos = text->curc;
+ BLI_str_cursor_step_next_utf8(text->curl->line, text->curl->len, &pos);
+ size_t c_len = pos - text->curc;
memmove(text->curl->line + text->curc,
text->curl->line + text->curc + c_len,
@@ -1805,8 +1801,6 @@ void txt_delete_word(Text *text)
void txt_backspace_char(Text *text)
{
- unsigned int c = '\n';
-
if (!text->curl) {
return;
}
@@ -1828,13 +1822,9 @@ void txt_backspace_char(Text *text)
txt_pop_sel(text);
}
else { /* Just backspacing a char */
- const char *prev = BLI_str_find_prev_char_utf8(text->curl->line + text->curc,
- text->curl->line);
- size_t c_len = prev - text->curl->line;
- c = BLI_str_utf8_as_unicode_step(text->curl->line, text->curl->len, &c_len);
- c_len -= prev - text->curl->line;
-
- UNUSED_VARS(c);
+ int pos = text->curc;
+ BLI_str_cursor_step_prev_utf8(text->curl->line, text->curl->len, &pos);
+ size_t c_len = text->curc - pos;
/* source and destination overlap, don't use memcpy() */
memmove(text->curl->line + text->curc - c_len,
@@ -1873,7 +1863,7 @@ static void txt_convert_tab_to_spaces(Text *text)
txt_insert_buf(text, sb, strlen(sb));
}
-static bool txt_add_char_intern(Text *text, unsigned int add, bool replace_tabs)
+static bool txt_add_char_intern(Text *text, uint add, bool replace_tabs)
{
char *tmp, ch[BLI_UTF8_MAX];
size_t add_len;
@@ -1916,12 +1906,12 @@ static bool txt_add_char_intern(Text *text, unsigned int add, bool replace_tabs)
return 1;
}
-bool txt_add_char(Text *text, unsigned int add)
+bool txt_add_char(Text *text, uint add)
{
return txt_add_char_intern(text, add, (text->flags & TXT_TABSTOSPACES) != 0);
}
-bool txt_add_raw_char(Text *text, unsigned int add)
+bool txt_add_raw_char(Text *text, uint add)
{
return txt_add_char_intern(text, add, 0);
}
@@ -1932,9 +1922,9 @@ void txt_delete_selected(Text *text)
txt_make_dirty(text);
}
-bool txt_replace_char(Text *text, unsigned int add)
+bool txt_replace_char(Text *text, uint add)
{
- unsigned int del;
+ uint del;
size_t del_size = 0, add_size;
char ch[BLI_UTF8_MAX];
@@ -2361,12 +2351,12 @@ bool text_check_identifier_nodigit(const char ch)
}
#ifndef WITH_PYTHON
-int text_check_identifier_unicode(const unsigned int ch)
+int text_check_identifier_unicode(const uint ch)
{
- return (ch < 255 && text_check_identifier((unsigned int)ch));
+ return (ch < 255 && text_check_identifier((uint)ch));
}
-int text_check_identifier_nodigit_unicode(const unsigned int ch)
+int text_check_identifier_nodigit_unicode(const uint ch)
{
return (ch < 255 && text_check_identifier_nodigit((char)ch));
}
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index cd1af5a8de4..3748c6a053c 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -2396,21 +2396,21 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion,
else {
if (undistort) {
libmv_cameraIntrinsicsUndistortByte(distortion->intrinsics,
- (unsigned char *)ibuf->rect,
+ (uchar *)ibuf->rect,
ibuf->x,
ibuf->y,
overscan,
ibuf->channels,
- (unsigned char *)resibuf->rect);
+ (uchar *)resibuf->rect);
}
else {
libmv_cameraIntrinsicsDistortByte(distortion->intrinsics,
- (unsigned char *)ibuf->rect,
+ (uchar *)ibuf->rect,
ibuf->x,
ibuf->y,
overscan,
ibuf->channels,
- (unsigned char *)resibuf->rect);
+ (uchar *)resibuf->rect);
}
}
@@ -2660,9 +2660,9 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width,
if (from_anchor) {
for (int a = 0; a < 5; a++) {
src_pixel_x[a] += (double)((track->offset[0] * frame_width) -
- ((int)(track->offset[0] * frame_width)));
+ (int)(track->offset[0] * frame_width));
src_pixel_y[a] += (double)((track->offset[1] * frame_height) -
- ((int)(track->offset[1] * frame_height)));
+ (int)(track->offset[1] * frame_height));
/* when offset is negative, rounding happens in opposite direction */
if (track->offset[0] < 0.0f) {
@@ -2693,7 +2693,7 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width,
&warped_position_y);
}
else {
- libmv_samplePlanarPatchByte((unsigned char *)search_ibuf->rect,
+ libmv_samplePlanarPatchByte((uchar *)search_ibuf->rect,
search_ibuf->x,
search_ibuf->y,
4,
@@ -2702,7 +2702,7 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width,
num_samples_x,
num_samples_y,
mask,
- (unsigned char *)pattern_ibuf->rect,
+ (uchar *)pattern_ibuf->rect,
&warped_position_x,
&warped_position_y);
}
@@ -2868,7 +2868,7 @@ ImBuf *BKE_tracking_get_plane_imbuf(const ImBuf *frame_ibuf,
&warped_position_y);
}
else {
- libmv_samplePlanarPatchByte((unsigned char *)frame_ibuf->rect,
+ libmv_samplePlanarPatchByte((uchar *)frame_ibuf->rect,
frame_ibuf->x,
frame_ibuf->y,
4,
@@ -2877,7 +2877,7 @@ ImBuf *BKE_tracking_get_plane_imbuf(const ImBuf *frame_ibuf,
num_samples_x,
num_samples_y,
NULL,
- (unsigned char *)plane_ibuf->rect,
+ (uchar *)plane_ibuf->rect,
&warped_position_x,
&warped_position_y);
}
diff --git a/source/blender/blenkernel/intern/tracking_detect.c b/source/blender/blenkernel/intern/tracking_detect.c
index 540f880905d..910d02ef50a 100644
--- a/source/blender/blenkernel/intern/tracking_detect.c
+++ b/source/blender/blenkernel/intern/tracking_detect.c
@@ -121,7 +121,7 @@ static void run_configured_detector(MovieTracking *tracking,
features = libmv_detectFeaturesFloat(ibuf->rect_float, ibuf->x, ibuf->y, 4, options);
}
else if (ibuf->rect) {
- features = libmv_detectFeaturesByte((unsigned char *)ibuf->rect, ibuf->x, ibuf->y, 4, options);
+ features = libmv_detectFeaturesByte((uchar *)ibuf->rect, ibuf->x, ibuf->y, 4, options);
}
if (features != NULL) {
diff --git a/source/blender/blenkernel/intern/tracking_region_tracker.c b/source/blender/blenkernel/intern/tracking_region_tracker.c
index c89d44c4bf0..52df980554b 100644
--- a/source/blender/blenkernel/intern/tracking_region_tracker.c
+++ b/source/blender/blenkernel/intern/tracking_region_tracker.c
@@ -42,7 +42,7 @@ static void float_rgba_to_gray(const float *rgba,
}
}
-static void uint8_rgba_to_float_gray(const unsigned char *rgba,
+static void uint8_rgba_to_float_gray(const uchar *rgba,
float *gray,
int num_pixels,
float weight_red,
@@ -50,7 +50,7 @@ static void uint8_rgba_to_float_gray(const unsigned char *rgba,
float weight_blue)
{
for (int i = 0; i < num_pixels; i++) {
- const unsigned char *pixel = rgba + i * 4;
+ const uchar *pixel = rgba + i * 4;
gray[i] = (weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2]) / 255.0f;
}
@@ -86,7 +86,7 @@ static float *track_get_search_floatbuf(ImBuf *ibuf,
}
else {
uint8_rgba_to_float_gray(
- (unsigned char *)searchibuf->rect, gray_pixels, width * height, 0.2126f, 0.7152f, 0.0722f);
+ (uchar *)searchibuf->rect, gray_pixels, width * height, 0.2126f, 0.7152f, 0.0722f);
}
IMB_freeImBuf(searchibuf);
diff --git a/source/blender/blenkernel/intern/tracking_solver.c b/source/blender/blenkernel/intern/tracking_solver.c
index 11041b4c0fd..e784c39ba08 100644
--- a/source/blender/blenkernel/intern/tracking_solver.c
+++ b/source/blender/blenkernel/intern/tracking_solver.c
@@ -56,8 +56,8 @@ typedef struct MovieReconstructContext {
} MovieReconstructContext;
typedef struct ReconstructProgressData {
- short *stop;
- short *do_update;
+ bool *stop;
+ bool *do_update;
float *progress;
char *stats_message;
int message_size;
@@ -465,8 +465,8 @@ static void reconstructionOptionsFromContext(libmv_ReconstructionOptions *recons
}
void BKE_tracking_reconstruction_solve(MovieReconstructContext *context,
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress,
char *stats_message,
int message_size)
diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c
index e97aa49f4ca..aaf262d120b 100644
--- a/source/blender/blenkernel/intern/tracking_util.c
+++ b/source/blender/blenkernel/intern/tracking_util.c
@@ -723,7 +723,7 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
int dst_index = (dst_y * width + dst_x) * 4,
src_index = (src_y * orig_ibuf->x + src_x) * 4;
rgba_uchar_to_float(final_ibuf->rect_float + dst_index,
- (unsigned char *)orig_ibuf->rect + src_index);
+ (uchar *)orig_ibuf->rect + src_index);
}
}
}
diff --git a/source/blender/blenkernel/intern/type_conversions.cc b/source/blender/blenkernel/intern/type_conversions.cc
index a01f5d19088..ffc5442af2d 100644
--- a/source/blender/blenkernel/intern/type_conversions.cc
+++ b/source/blender/blenkernel/intern/type_conversions.cc
@@ -49,7 +49,7 @@ static float3 float_to_float3(const float &a)
}
static int32_t float_to_int(const float &a)
{
- return (int32_t)a;
+ return int32_t(a);
}
static bool float_to_bool(const float &a)
{
@@ -79,7 +79,7 @@ static float float2_to_float(const float2 &a)
}
static int float2_to_int(const float2 &a)
{
- return (int32_t)((a.x + a.y) / 2.0f);
+ return int32_t((a.x + a.y) / 2.0f);
}
static bool float2_to_bool(const float2 &a)
{
@@ -112,7 +112,7 @@ static float float3_to_float(const float3 &a)
}
static int float3_to_int(const float3 &a)
{
- return (int)((a.x + a.y + a.z) / 3.0f);
+ return int((a.x + a.y + a.z) / 3.0f);
}
static float2 float3_to_float2(const float3 &a)
{
@@ -138,19 +138,19 @@ static int8_t int_to_int8(const int32_t &a)
}
static float int_to_float(const int32_t &a)
{
- return (float)a;
+ return float(a);
}
static float2 int_to_float2(const int32_t &a)
{
- return float2((float)a);
+ return float2(float(a));
}
static float3 int_to_float3(const int32_t &a)
{
- return float3((float)a);
+ return float3(float(a));
}
static ColorGeometry4f int_to_color(const int32_t &a)
{
- return ColorGeometry4f((float)a, (float)a, (float)a, 1.0f);
+ return ColorGeometry4f(float(a), float(a), float(a), 1.0f);
}
static ColorGeometry4b int_to_byte_color(const int32_t &a)
{
@@ -163,23 +163,23 @@ static bool int8_to_bool(const int8_t &a)
}
static int int8_to_int(const int8_t &a)
{
- return static_cast<int>(a);
+ return int(a);
}
static float int8_to_float(const int8_t &a)
{
- return (float)a;
+ return float(a);
}
static float2 int8_to_float2(const int8_t &a)
{
- return float2((float)a);
+ return float2(float(a));
}
static float3 int8_to_float3(const int8_t &a)
{
- return float3((float)a);
+ return float3(float(a));
}
static ColorGeometry4f int8_to_color(const int8_t &a)
{
- return ColorGeometry4f((float)a, (float)a, (float)a, 1.0f);
+ return ColorGeometry4f(float(a), float(a), float(a), 1.0f);
}
static ColorGeometry4b int8_to_byte_color(const int8_t &a)
{
@@ -188,15 +188,15 @@ static ColorGeometry4b int8_to_byte_color(const int8_t &a)
static float bool_to_float(const bool &a)
{
- return (bool)a;
+ return bool(a);
}
static int8_t bool_to_int8(const bool &a)
{
- return static_cast<int8_t>(a);
+ return int8_t(a);
}
static int32_t bool_to_int(const bool &a)
{
- return (int32_t)a;
+ return int32_t(a);
}
static float2 bool_to_float2(const bool &a)
{
@@ -225,7 +225,7 @@ static float color_to_float(const ColorGeometry4f &a)
}
static int32_t color_to_int(const ColorGeometry4f &a)
{
- return (int)rgb_to_grayscale(a);
+ return int(rgb_to_grayscale(a));
}
static int8_t color_to_int8(const ColorGeometry4f &a)
{
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index 300ef0c646f..db2a6b658fa 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -299,7 +299,7 @@ static void undosys_stack_clear_all_last(UndoStack *ustack, UndoStep *us)
BLI_assert(us_iter != ustack->step_active);
undosys_step_free_and_unlink(ustack, us_iter);
undosys_stack_validate(ustack, is_not_empty);
- } while ((us != us_iter));
+ } while (us != us_iter);
}
}
@@ -320,7 +320,7 @@ static void undosys_stack_clear_all_first(UndoStack *ustack, UndoStep *us, UndoS
BLI_assert(us_iter != ustack->step_active);
undosys_step_free_and_unlink(ustack, us_iter);
undosys_stack_validate(ustack, is_not_empty);
- } while ((us != us_iter));
+ } while (us != us_iter);
}
}
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index f7ea4c81fbf..f5badfc9e94 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -715,7 +715,7 @@ static const char *unit_find_str(const char *str, const char *substr, bool case_
/* Weak unicode support!, so "µm" won't match up be replaced by "m"
* since non ascii utf8 values will NEVER return true */
isalpha_or_utf8(*BLI_str_find_prev_char_utf8(str_found, str)) == 0) {
- /* Next char cannot be alphanum. */
+ /* Next char cannot be alpha-numeric. */
int len_name = strlen(substr);
if (!isalpha_or_utf8(*(str_found + len_name))) {
diff --git a/source/blender/blenkernel/intern/vfont.c b/source/blender/blenkernel/intern/vfont.c
index 288493c9d65..9f48b9b9c4a 100644
--- a/source/blender/blenkernel/intern/vfont.c
+++ b/source/blender/blenkernel/intern/vfont.c
@@ -81,7 +81,7 @@ static void vfont_copy_data(Main *UNUSED(bmain),
{
VFont *vfont_dst = (VFont *)id_dst;
- /* We never handle usercount here for own data. */
+ /* We never handle user-count here for own data. */
const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
/* Just to be sure, should not have any value actually after reading time. */
@@ -423,7 +423,7 @@ VFont *BKE_vfont_builtin_get(void)
return BKE_vfont_load(G_MAIN, FO_BUILTIN_NAME);
}
-static VChar *find_vfont_char(VFontData *vfd, unsigned int character)
+static VChar *find_vfont_char(VFontData *vfd, uint character)
{
return BLI_ghash_lookup(vfd->characters, POINTER_FROM_UINT(character));
}
@@ -494,7 +494,7 @@ static void build_underline(Curve *cu,
void BKE_vfont_build_char(Curve *cu,
ListBase *nubase,
- unsigned int character,
+ uint character,
CharInfo *info,
float ofsx,
float ofsy,
@@ -1044,7 +1044,7 @@ static bool vfont_to_curve(Object *ob,
CLAMP_MIN(maxlen, lineinfo[lnr].x_min);
- if ((tb_scale.h != 0.0f) && ((-(yof - tb_scale.y)) > (tb_scale.h - linedist) - yof_scale)) {
+ if ((tb_scale.h != 0.0f) && (-(yof - tb_scale.y) > (tb_scale.h - linedist) - yof_scale)) {
if (cu->totbox > (curbox + 1)) {
maxlen = 0;
curbox++;
@@ -1175,7 +1175,7 @@ static bool vfont_to_curve(Object *ob,
}
}
for (i = 0; i <= slen; i++) {
- for (j = i; (!ELEM(mem[j], '\0', '\n')) && (chartransdata[j].dobreak == 0) && (j < slen);
+ for (j = i; !ELEM(mem[j], '\0', '\n') && (chartransdata[j].dobreak == 0) && (j < slen);
j++) {
/* do nothing */
}
@@ -1194,7 +1194,7 @@ static bool vfont_to_curve(Object *ob,
/* pass */
}
- if ((mem[j] != '\n') && ((chartransdata[j].dobreak != 0))) {
+ if ((mem[j] != '\n') && (chartransdata[j].dobreak != 0)) {
if (mem[i] == ' ') {
struct TempLineInfo *li;
@@ -1310,14 +1310,14 @@ static bool vfont_to_curve(Object *ob,
float timeofs, sizefac;
if (ob != NULL) {
- invert_m4_m4(imat, ob->obmat);
+ invert_m4_m4(imat, ob->object_to_world);
}
else {
unit_m4(imat);
}
copy_m3_m4(imat3, imat);
- copy_m3_m4(cmat, cu->textoncurve->obmat);
+ copy_m3_m4(cmat, cu->textoncurve->object_to_world);
mul_m3_m3m3(cmat, cmat, imat3);
sizefac = normalize_v3(cmat[0]) / font_size;
@@ -1505,7 +1505,7 @@ static bool vfont_to_curve(Object *ob,
ct = chartransdata;
for (i = 0; i < slen; i++) {
- unsigned int cha = (unsigned int)mem[i];
+ uint cha = (uint)mem[i];
info = &(custrinfo[i]);
if ((cu->overflow == CU_OVERFLOW_TRUNCATE) && (ob && ob->mode != OB_MODE_EDIT) &&
diff --git a/source/blender/blenkernel/intern/vfontdata_freetype.c b/source/blender/blenkernel/intern/vfontdata_freetype.c
index 79d9b64b0f6..9fe83ce7aa0 100644
--- a/source/blender/blenkernel/intern/vfontdata_freetype.c
+++ b/source/blender/blenkernel/intern/vfontdata_freetype.c
@@ -34,10 +34,6 @@
#include "DNA_packedFile_types.h"
#include "DNA_vfont_types.h"
-/* local variables */
-static FT_Library library;
-static FT_Error err;
-
static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd)
{
const float scale = vfd->scale;
@@ -60,7 +56,7 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *
*
* Get the FT Glyph index and load the Glyph */
glyph_index = FT_Get_Char_Index(face, charcode);
- err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP);
+ FT_Error err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP);
/* If loading succeeded, convert the FT glyph to the internal format */
if (!err) {
@@ -240,7 +236,7 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *
return NULL;
}
-static VChar *objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode)
+static VChar *objchr_to_ftvfontdata(FT_Library library, VFont *vfont, FT_ULong charcode)
{
VChar *che;
@@ -249,13 +245,13 @@ static VChar *objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode)
/* Load the font to memory */
if (vfont->temp_pf) {
- err = FT_New_Memory_Face(library, vfont->temp_pf->data, vfont->temp_pf->size, 0, &face);
+ FT_Error err = FT_New_Memory_Face(
+ library, vfont->temp_pf->data, vfont->temp_pf->size, 0, &face);
if (err) {
return NULL;
}
}
else {
- err = true;
return NULL;
}
@@ -266,33 +262,22 @@ static VChar *objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode)
return che;
}
-static VFontData *objfnt_to_ftvfontdata(PackedFile *pf)
+static FT_Face vfont_face_load_from_packed_file(FT_Library library, PackedFile *pf)
{
- /* Variables */
- FT_Face face;
- const FT_ULong charcode_reserve = 256;
- FT_ULong charcode = 0, lcode;
- FT_UInt glyph_index;
- VFontData *vfd;
-
- /* load the freetype font */
- err = FT_New_Memory_Face(library, pf->data, pf->size, 0, &face);
-
- if (err) {
+ FT_Face face = NULL;
+ FT_New_Memory_Face(library, pf->data, pf->size, 0, &face);
+ if (!face) {
return NULL;
}
- /* allocate blender font */
- vfd = MEM_callocN(sizeof(*vfd), "FTVFontData");
-
- /* Get the name. */
- if (face->family_name) {
- BLI_snprintf(vfd->name, sizeof(vfd->name), "%s %s", face->family_name, face->style_name);
- BLI_str_utf8_invalid_strip(vfd->name, strlen(vfd->name));
+ /* Font must contain vectors, not bitmaps. */
+ if (!(face->face_flags & FT_FACE_FLAG_SCALABLE)) {
+ FT_Done_Face(face);
+ return NULL;
}
/* Select a character map. */
- err = FT_Select_Charmap(face, FT_ENCODING_UNICODE);
+ FT_Error err = FT_Select_Charmap(face, FT_ENCODING_UNICODE);
if (err) {
err = FT_Select_Charmap(face, FT_ENCODING_APPLE_ROMAN);
}
@@ -301,12 +286,42 @@ static VFontData *objfnt_to_ftvfontdata(PackedFile *pf)
}
if (err) {
FT_Done_Face(face);
- MEM_freeN(vfd);
return NULL;
}
- /* Extract the first 256 character from TTF */
- lcode = charcode = FT_Get_First_Char(face, &glyph_index);
+ /* Test that we can load glyphs from this font. */
+ FT_UInt glyph_index = 0;
+ FT_Get_First_Char(face, &glyph_index);
+ if (!glyph_index ||
+ FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP) != FT_Err_Ok) {
+ FT_Done_Face(face);
+ return NULL;
+ }
+
+ return face;
+}
+
+VFontData *BKE_vfontdata_from_freetypefont(PackedFile *pf)
+{
+ FT_Library library = NULL;
+ if (FT_Init_FreeType(&library) != FT_Err_Ok) {
+ return NULL;
+ }
+
+ FT_Face face = vfont_face_load_from_packed_file(library, pf);
+ if (!face) {
+ FT_Done_FreeType(library);
+ return NULL;
+ }
+
+ /* allocate blender font */
+ VFontData *vfd = MEM_callocN(sizeof(*vfd), "FTVFontData");
+
+ /* Get the name. */
+ if (face->family_name) {
+ BLI_snprintf(vfd->name, sizeof(vfd->name), "%s %s", face->family_name, face->style_name);
+ BLI_str_utf8_invalid_strip(vfd->name, strlen(vfd->name));
+ }
/* Blender default BFont is not "complete". */
const bool complete_font = (face->ascender != 0) && (face->descender != 0) &&
@@ -335,67 +350,21 @@ static VFontData *objfnt_to_ftvfontdata(PackedFile *pf)
vfd->scale = 1.0f / 1000.0f;
}
- /* Load characters */
- vfd->characters = BLI_ghash_int_new_ex(__func__, charcode_reserve);
+ /* Load the first 256 glyphs. */
- while (charcode < charcode_reserve) {
- /* Generate the font data */
- freetypechar_to_vchar(face, charcode, vfd);
+ const FT_ULong preload_count = 256;
+ vfd->characters = BLI_ghash_int_new_ex(__func__, preload_count);
- /* Next glyph */
+ FT_ULong charcode = 0;
+ FT_UInt glyph_index;
+ for (int i = 0; i < preload_count; i++) {
charcode = FT_Get_Next_Char(face, charcode, &glyph_index);
-
- /* Check that we won't start infinite loop */
- if (charcode <= lcode) {
+ if (!charcode || !glyph_index) {
break;
}
- lcode = charcode;
- }
-
- return vfd;
-}
-
-static bool check_freetypefont(PackedFile *pf)
-{
- FT_Face face = NULL;
- FT_UInt glyph_index = 0;
- bool success = false;
-
- err = FT_New_Memory_Face(library, pf->data, pf->size, 0, &face);
- if (err) {
- return false;
- // XXX error("This is not a valid font");
- }
-
- FT_Get_First_Char(face, &glyph_index);
- if (glyph_index) {
- err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP);
- if (!err) {
- success = (face->glyph->format == ft_glyph_format_outline);
- }
- }
-
- FT_Done_Face(face);
-
- return success;
-}
-
-VFontData *BKE_vfontdata_from_freetypefont(PackedFile *pf)
-{
- VFontData *vfd = NULL;
-
- /* init Freetype */
- err = FT_Init_FreeType(&library);
- if (err) {
- /* XXX error("Failed to load the Freetype font library"); */
- return NULL;
- }
-
- if (check_freetypefont(pf)) {
- vfd = objfnt_to_ftvfontdata(pf);
+ freetypechar_to_vchar(face, charcode, vfd);
}
- /* free Freetype */
FT_Done_FreeType(library);
return vfd;
@@ -418,7 +387,7 @@ VFontData *BKE_vfontdata_copy(const VFontData *vfont_src, const int UNUSED(flag)
return vfont_dst;
}
-VChar *BKE_vfontdata_char_from_freetypefont(VFont *vfont, unsigned long character)
+VChar *BKE_vfontdata_char_from_freetypefont(VFont *vfont, ulong character)
{
VChar *che = NULL;
@@ -427,14 +396,15 @@ VChar *BKE_vfontdata_char_from_freetypefont(VFont *vfont, unsigned long characte
}
/* Init Freetype */
- err = FT_Init_FreeType(&library);
+ FT_Library library = NULL;
+ FT_Error err = FT_Init_FreeType(&library);
if (err) {
/* XXX error("Failed to load the Freetype font library"); */
return NULL;
}
/* Load the character */
- che = objchr_to_ftvfontdata(vfont, character);
+ che = objchr_to_ftvfontdata(library, vfont, character);
/* Free Freetype */
FT_Done_FreeType(library);
diff --git a/source/blender/blenkernel/intern/viewer_path.cc b/source/blender/blenkernel/intern/viewer_path.cc
new file mode 100644
index 00000000000..edc71787ac5
--- /dev/null
+++ b/source/blender/blenkernel/intern/viewer_path.cc
@@ -0,0 +1,270 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BKE_lib_query.h"
+#include "BKE_lib_remap.h"
+#include "BKE_viewer_path.h"
+
+#include "BLI_index_range.hh"
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_string_ref.hh"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLO_read_write.h"
+
+using blender::IndexRange;
+using blender::StringRef;
+
+void BKE_viewer_path_init(ViewerPath *viewer_path)
+{
+ BLI_listbase_clear(&viewer_path->path);
+}
+
+void BKE_viewer_path_clear(ViewerPath *viewer_path)
+{
+ LISTBASE_FOREACH_MUTABLE (ViewerPathElem *, elem, &viewer_path->path) {
+ BKE_viewer_path_elem_free(elem);
+ }
+ BLI_listbase_clear(&viewer_path->path);
+}
+
+void BKE_viewer_path_copy(ViewerPath *dst, const ViewerPath *src)
+{
+ BKE_viewer_path_init(dst);
+ LISTBASE_FOREACH (const ViewerPathElem *, src_elem, &src->path) {
+ ViewerPathElem *new_elem = BKE_viewer_path_elem_copy(src_elem);
+ BLI_addtail(&dst->path, new_elem);
+ }
+}
+
+bool BKE_viewer_path_equal(const ViewerPath *a, const ViewerPath *b)
+{
+ const ViewerPathElem *elem_a = static_cast<const ViewerPathElem *>(a->path.first);
+ const ViewerPathElem *elem_b = static_cast<const ViewerPathElem *>(b->path.first);
+
+ while (elem_a != nullptr && elem_b != nullptr) {
+ if (!BKE_viewer_path_elem_equal(elem_a, elem_b)) {
+ return false;
+ }
+ elem_a = elem_a->next;
+ elem_b = elem_b->next;
+ }
+ if (elem_a == nullptr && elem_b == nullptr) {
+ return true;
+ }
+ return false;
+}
+
+void BKE_viewer_path_blend_write(struct BlendWriter *writer, const ViewerPath *viewer_path)
+{
+ LISTBASE_FOREACH (ViewerPathElem *, elem, &viewer_path->path) {
+ switch (ViewerPathElemType(elem->type)) {
+ case VIEWER_PATH_ELEM_TYPE_ID: {
+ const auto *typed_elem = reinterpret_cast<IDViewerPathElem *>(elem);
+ BLO_write_struct(writer, IDViewerPathElem, typed_elem);
+ break;
+ }
+ case VIEWER_PATH_ELEM_TYPE_MODIFIER: {
+ const auto *typed_elem = reinterpret_cast<ModifierViewerPathElem *>(elem);
+ BLO_write_struct(writer, ModifierViewerPathElem, typed_elem);
+ BLO_write_string(writer, typed_elem->modifier_name);
+ break;
+ }
+ case VIEWER_PATH_ELEM_TYPE_NODE: {
+ const auto *typed_elem = reinterpret_cast<NodeViewerPathElem *>(elem);
+ BLO_write_struct(writer, NodeViewerPathElem, typed_elem);
+ BLO_write_string(writer, typed_elem->node_name);
+ break;
+ }
+ }
+ }
+}
+
+void BKE_viewer_path_blend_read_data(struct BlendDataReader *reader, ViewerPath *viewer_path)
+{
+ BLO_read_list(reader, &viewer_path->path);
+ LISTBASE_FOREACH (ViewerPathElem *, elem, &viewer_path->path) {
+ switch (ViewerPathElemType(elem->type)) {
+ case VIEWER_PATH_ELEM_TYPE_ID: {
+ break;
+ }
+ case VIEWER_PATH_ELEM_TYPE_MODIFIER: {
+ auto *typed_elem = reinterpret_cast<ModifierViewerPathElem *>(elem);
+ BLO_read_data_address(reader, &typed_elem->modifier_name);
+ break;
+ }
+ case VIEWER_PATH_ELEM_TYPE_NODE: {
+ auto *typed_elem = reinterpret_cast<NodeViewerPathElem *>(elem);
+ BLO_read_data_address(reader, &typed_elem->node_name);
+ break;
+ }
+ }
+ }
+}
+
+void BKE_viewer_path_blend_read_lib(BlendLibReader *reader, Library *lib, ViewerPath *viewer_path)
+{
+ LISTBASE_FOREACH (ViewerPathElem *, elem, &viewer_path->path) {
+ switch (ViewerPathElemType(elem->type)) {
+ case VIEWER_PATH_ELEM_TYPE_ID: {
+ auto *typed_elem = reinterpret_cast<IDViewerPathElem *>(elem);
+ BLO_read_id_address(reader, lib, &typed_elem->id);
+ break;
+ }
+ case VIEWER_PATH_ELEM_TYPE_MODIFIER:
+ case VIEWER_PATH_ELEM_TYPE_NODE: {
+ break;
+ }
+ }
+ }
+}
+
+void BKE_viewer_path_foreach_id(LibraryForeachIDData *data, ViewerPath *viewer_path)
+{
+ LISTBASE_FOREACH (ViewerPathElem *, elem, &viewer_path->path) {
+ switch (ViewerPathElemType(elem->type)) {
+ case VIEWER_PATH_ELEM_TYPE_ID: {
+ auto *typed_elem = reinterpret_cast<IDViewerPathElem *>(elem);
+ BKE_LIB_FOREACHID_PROCESS_ID(data, typed_elem->id, IDWALK_CB_NOP);
+ break;
+ }
+ case VIEWER_PATH_ELEM_TYPE_MODIFIER:
+ case VIEWER_PATH_ELEM_TYPE_NODE: {
+ break;
+ }
+ }
+ }
+}
+
+void BKE_viewer_path_id_remap(ViewerPath *viewer_path, const IDRemapper *mappings)
+{
+ LISTBASE_FOREACH (ViewerPathElem *, elem, &viewer_path->path) {
+ switch (ViewerPathElemType(elem->type)) {
+ case VIEWER_PATH_ELEM_TYPE_ID: {
+ auto *typed_elem = reinterpret_cast<IDViewerPathElem *>(elem);
+ BKE_id_remapper_apply(mappings, &typed_elem->id, ID_REMAP_APPLY_DEFAULT);
+ break;
+ }
+ case VIEWER_PATH_ELEM_TYPE_MODIFIER:
+ case VIEWER_PATH_ELEM_TYPE_NODE: {
+ break;
+ }
+ }
+ }
+}
+
+ViewerPathElem *BKE_viewer_path_elem_new(const ViewerPathElemType type)
+{
+ switch (type) {
+ case VIEWER_PATH_ELEM_TYPE_ID: {
+ IDViewerPathElem *elem = MEM_cnew<IDViewerPathElem>(__func__);
+ elem->base.type = type;
+ return &elem->base;
+ }
+ case VIEWER_PATH_ELEM_TYPE_MODIFIER: {
+ ModifierViewerPathElem *elem = MEM_cnew<ModifierViewerPathElem>(__func__);
+ elem->base.type = type;
+ return &elem->base;
+ }
+ case VIEWER_PATH_ELEM_TYPE_NODE: {
+ NodeViewerPathElem *elem = MEM_cnew<NodeViewerPathElem>(__func__);
+ elem->base.type = type;
+ return &elem->base;
+ }
+ }
+ BLI_assert_unreachable();
+ return nullptr;
+}
+
+IDViewerPathElem *BKE_viewer_path_elem_new_id()
+{
+ return reinterpret_cast<IDViewerPathElem *>(BKE_viewer_path_elem_new(VIEWER_PATH_ELEM_TYPE_ID));
+}
+
+ModifierViewerPathElem *BKE_viewer_path_elem_new_modifier()
+{
+ return reinterpret_cast<ModifierViewerPathElem *>(
+ BKE_viewer_path_elem_new(VIEWER_PATH_ELEM_TYPE_MODIFIER));
+}
+
+NodeViewerPathElem *BKE_viewer_path_elem_new_node()
+{
+ return reinterpret_cast<NodeViewerPathElem *>(
+ BKE_viewer_path_elem_new(VIEWER_PATH_ELEM_TYPE_NODE));
+}
+
+ViewerPathElem *BKE_viewer_path_elem_copy(const ViewerPathElem *src)
+{
+ ViewerPathElem *dst = BKE_viewer_path_elem_new(ViewerPathElemType(src->type));
+ switch (ViewerPathElemType(src->type)) {
+ case VIEWER_PATH_ELEM_TYPE_ID: {
+ const auto *old_elem = reinterpret_cast<const IDViewerPathElem *>(src);
+ auto *new_elem = reinterpret_cast<IDViewerPathElem *>(dst);
+ new_elem->id = old_elem->id;
+ break;
+ }
+ case VIEWER_PATH_ELEM_TYPE_MODIFIER: {
+ const auto *old_elem = reinterpret_cast<const ModifierViewerPathElem *>(src);
+ auto *new_elem = reinterpret_cast<ModifierViewerPathElem *>(dst);
+ if (old_elem->modifier_name != nullptr) {
+ new_elem->modifier_name = BLI_strdup(old_elem->modifier_name);
+ }
+ break;
+ }
+ case VIEWER_PATH_ELEM_TYPE_NODE: {
+ const auto *old_elem = reinterpret_cast<const NodeViewerPathElem *>(src);
+ auto *new_elem = reinterpret_cast<NodeViewerPathElem *>(dst);
+ if (old_elem->node_name != nullptr) {
+ new_elem->node_name = BLI_strdup(old_elem->node_name);
+ }
+ break;
+ }
+ }
+ return dst;
+}
+
+bool BKE_viewer_path_elem_equal(const ViewerPathElem *a, const ViewerPathElem *b)
+{
+ if (a->type != b->type) {
+ return false;
+ }
+ switch (ViewerPathElemType(a->type)) {
+ case VIEWER_PATH_ELEM_TYPE_ID: {
+ const auto *a_elem = reinterpret_cast<const IDViewerPathElem *>(a);
+ const auto *b_elem = reinterpret_cast<const IDViewerPathElem *>(b);
+ return a_elem->id == b_elem->id;
+ }
+ case VIEWER_PATH_ELEM_TYPE_MODIFIER: {
+ const auto *a_elem = reinterpret_cast<const ModifierViewerPathElem *>(a);
+ const auto *b_elem = reinterpret_cast<const ModifierViewerPathElem *>(b);
+ return StringRef(a_elem->modifier_name) == StringRef(b_elem->modifier_name);
+ }
+ case VIEWER_PATH_ELEM_TYPE_NODE: {
+ const auto *a_elem = reinterpret_cast<const NodeViewerPathElem *>(a);
+ const auto *b_elem = reinterpret_cast<const NodeViewerPathElem *>(b);
+ return StringRef(a_elem->node_name) == StringRef(b_elem->node_name);
+ }
+ }
+ return false;
+}
+
+void BKE_viewer_path_elem_free(ViewerPathElem *elem)
+{
+ switch (ViewerPathElemType(elem->type)) {
+ case VIEWER_PATH_ELEM_TYPE_ID: {
+ break;
+ }
+ case VIEWER_PATH_ELEM_TYPE_MODIFIER: {
+ auto *typed_elem = reinterpret_cast<ModifierViewerPathElem *>(elem);
+ MEM_SAFE_FREE(typed_elem->modifier_name);
+ break;
+ }
+ case VIEWER_PATH_ELEM_TYPE_NODE: {
+ auto *typed_elem = reinterpret_cast<NodeViewerPathElem *>(elem);
+ MEM_SAFE_FREE(typed_elem->node_name);
+ break;
+ }
+ }
+ MEM_freeN(elem);
+}
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 502d3ac6d40..e81657f9ef0 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -363,7 +363,7 @@ struct VolumeGrid {
is_loaded = false;
}
- void clear_reference(const char *UNUSED(volume_name))
+ void clear_reference(const char * /*volume_name*/)
{
/* Clear any reference to a grid in the file cache. */
local_grid = grid()->copyGridWithNewTree();
@@ -445,7 +445,7 @@ struct VolumeGrid {
* may actually be loaded by another user while this is false. But only after
* calling load() and is_loaded changes to true is it safe to access.
*
- * Const write access to this must be protected by `entry->mutex`.
+ * `const` write access to this must be protected by `entry->mutex`.
*/
mutable bool is_loaded;
};
@@ -480,7 +480,7 @@ struct VolumeGridVector : public std::list<VolumeGrid> {
metadata.reset();
}
- /* Mutex for file loading of grids list. Const write access to the fields after this must be
+ /* Mutex for file loading of grids list. `const` write access to the fields after this must be
* protected by locking with this mutex. */
mutable std::mutex mutex;
/* Absolute file path that grids have been loaded from. */
@@ -515,10 +515,7 @@ static void volume_init_data(ID *id)
BLI_strncpy(volume->velocity_grid, "velocity", sizeof(volume->velocity_grid));
}
-static void volume_copy_data(Main *UNUSED(bmain),
- ID *id_dst,
- const ID *id_src,
- const int UNUSED(flag))
+static void volume_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int /*flag*/)
{
Volume *volume_dst = (Volume *)id_dst;
const Volume *volume_src = (const Volume *)id_src;
@@ -1636,8 +1633,8 @@ bool BKE_volume_grid_bounds(openvdb::GridBase::ConstPtr grid, float3 &r_min, flo
openvdb::BBoxd bbox = grid->transform().indexToWorld(coordbbox);
- r_min = float3((float)bbox.min().x(), (float)bbox.min().y(), (float)bbox.min().z());
- r_max = float3((float)bbox.max().x(), (float)bbox.max().y(), (float)bbox.max().z());
+ r_min = float3(float(bbox.min().x()), float(bbox.min().y()), float(bbox.min().z()));
+ r_max = float3(float(bbox.max().x()), float(bbox.max().y()), float(bbox.max().z()));
return true;
}
@@ -1646,7 +1643,7 @@ openvdb::GridBase::ConstPtr BKE_volume_grid_shallow_transform(openvdb::GridBase:
const blender::float4x4 &transform)
{
openvdb::math::Transform::Ptr grid_transform = grid->transform().copy();
- grid_transform->postMult(openvdb::Mat4d(((float *)transform.values)));
+ grid_transform->postMult(openvdb::Mat4d((float *)transform.values));
/* Create a transformed grid. The underlying tree is shared. */
return grid->copyGridReplacingTransform(grid_transform);
diff --git a/source/blender/blenkernel/intern/volume_render.cc b/source/blender/blenkernel/intern/volume_render.cc
index e7620be6401..700bd63c9d4 100644
--- a/source/blender/blenkernel/intern/volume_render.cc
+++ b/source/blender/blenkernel/intern/volume_render.cc
@@ -102,9 +102,8 @@ bool BKE_volume_grid_dense_floats(const Volume *volume,
}
const openvdb::Vec3i resolution = bbox.dim().asVec3i();
- const int64_t num_voxels = static_cast<int64_t>(resolution[0]) *
- static_cast<int64_t>(resolution[1]) *
- static_cast<int64_t>(resolution[2]);
+ const int64_t num_voxels = int64_t(resolution[0]) * int64_t(resolution[1]) *
+ int64_t(resolution[2]);
const int channels = BKE_volume_grid_channels(volume_grid);
const int elem_size = sizeof(float) * channels;
float *voxels = static_cast<float *>(MEM_malloc_arrayN(num_voxels, elem_size, __func__));
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.cc
index f59be7f0111..6ffef5555fb 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.cc
@@ -4,9 +4,9 @@
* \ingroup bke
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include "BLI_listbase.h"
#include "BLI_string.h"
@@ -24,6 +24,7 @@
#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_scene.h"
+#include "BKE_viewer_path.h"
#include "BKE_workspace.h"
#include "DNA_object_types.h"
@@ -57,10 +58,11 @@ static void workspace_free_data(ID *id)
BLI_freelistN(&workspace->layouts);
while (!BLI_listbase_is_empty(&workspace->tools)) {
- BKE_workspace_tool_remove(workspace, workspace->tools.first);
+ BKE_workspace_tool_remove(workspace, static_cast<bToolRef *>(workspace->tools.first));
}
MEM_SAFE_FREE(workspace->status_text);
+ BKE_viewer_path_clear(&workspace->viewer_path);
}
static void workspace_foreach_id(ID *id, LibraryForeachIDData *data)
@@ -72,6 +74,8 @@ static void workspace_foreach_id(ID *id, LibraryForeachIDData *data)
LISTBASE_FOREACH (WorkSpaceLayout *, layout, &workspace->layouts) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, layout->screen, IDWALK_CB_USER);
}
+
+ BKE_viewer_path_foreach_id(data, &workspace->viewer_path);
}
static void workspace_blend_write(BlendWriter *writer, ID *id, const void *id_address)
@@ -89,6 +93,8 @@ static void workspace_blend_write(BlendWriter *writer, ID *id, const void *id_ad
IDP_BlendWrite(writer, tref->properties);
}
}
+
+ BKE_viewer_path_blend_write(writer, &workspace->viewer_path);
}
static void workspace_blend_read_data(BlendDataReader *reader, ID *id)
@@ -107,14 +113,16 @@ static void workspace_blend_read_data(BlendDataReader *reader, ID *id)
}
LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) {
- tref->runtime = NULL;
+ tref->runtime = nullptr;
BLO_read_data_address(reader, &tref->properties);
IDP_BlendDataRead(reader, &tref->properties);
}
- workspace->status_text = NULL;
+ workspace->status_text = nullptr;
id_us_ensure_real(&workspace->id);
+
+ BKE_viewer_path_blend_read_data(reader, &workspace->viewer_path);
}
static void workspace_blend_read_lib(BlendLibReader *reader, ID *id)
@@ -125,15 +133,15 @@ static void workspace_blend_read_lib(BlendLibReader *reader, ID *id)
/* Do not keep the scene reference when appending a workspace. Setting a scene for a workspace is
* a convenience feature, but the workspace should never truly depend on scene data. */
if (ID_IS_LINKED(id)) {
- workspace->pin_scene = NULL;
+ workspace->pin_scene = nullptr;
}
else {
- BLO_read_id_address(reader, NULL, &workspace->pin_scene);
+ BLO_read_id_address(reader, nullptr, &workspace->pin_scene);
}
/* Restore proper 'parent' pointers to relevant data, and clean up unused/invalid entries. */
LISTBASE_FOREACH_MUTABLE (WorkSpaceDataRelation *, relation, &workspace->hook_layout_relations) {
- relation->parent = NULL;
+ relation->parent = nullptr;
LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) {
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
if (win->winid == relation->parentid) {
@@ -141,7 +149,7 @@ static void workspace_blend_read_lib(BlendLibReader *reader, ID *id)
}
}
}
- if (relation->parent == NULL) {
+ if (relation->parent == nullptr) {
BLI_freelinkN(&workspace->hook_layout_relations, relation);
}
}
@@ -164,6 +172,8 @@ static void workspace_blend_read_lib(BlendLibReader *reader, ID *id)
BKE_workspace_layout_remove(bmain, workspace, layout);
}
}
+
+ BKE_viewer_path_blend_read_lib(reader, id->lib, &workspace->viewer_path);
}
static void workspace_blend_read_expand(BlendExpander *expander, ID *id)
@@ -176,33 +186,33 @@ static void workspace_blend_read_expand(BlendExpander *expander, ID *id)
}
IDTypeInfo IDType_ID_WS = {
- .id_code = ID_WS,
- .id_filter = FILTER_ID_WS,
- .main_listbase_index = INDEX_ID_WS,
- .struct_size = sizeof(WorkSpace),
- .name = "WorkSpace",
- .name_plural = "workspaces",
- .translation_context = BLT_I18NCONTEXT_ID_WORKSPACE,
- .flags = IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_ONLY_APPEND | IDTYPE_FLAGS_NO_ANIMDATA,
- .asset_type_info = NULL,
-
- .init_data = workspace_init_data,
- .copy_data = NULL,
- .free_data = workspace_free_data,
- .make_local = NULL,
- .foreach_id = workspace_foreach_id,
- .foreach_cache = NULL,
- .foreach_path = NULL,
- .owner_pointer_get = NULL,
-
- .blend_write = workspace_blend_write,
- .blend_read_data = workspace_blend_read_data,
- .blend_read_lib = workspace_blend_read_lib,
- .blend_read_expand = workspace_blend_read_expand,
-
- .blend_read_undo_preserve = NULL,
-
- .lib_override_apply_post = NULL,
+ /* id_code */ ID_WS,
+ /* id_filter */ FILTER_ID_WS,
+ /* main_listbase_index */ INDEX_ID_WS,
+ /* struct_size */ sizeof(WorkSpace),
+ /* name */ "WorkSpace",
+ /* name_plural */ "workspaces",
+ /* translation_context */ BLT_I18NCONTEXT_ID_WORKSPACE,
+ /* flags */ IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_ONLY_APPEND | IDTYPE_FLAGS_NO_ANIMDATA,
+ /* asset_type_info */ nullptr,
+
+ /* init_data */ workspace_init_data,
+ /* copy_data */ nullptr,
+ /* free_data */ workspace_free_data,
+ /* make_local */ nullptr,
+ /* foreach_id */ workspace_foreach_id,
+ /* foreach_cache */ nullptr,
+ /* foreach_path */ nullptr,
+ /* owner_pointer_get */ nullptr,
+
+ /* blend_write */ workspace_blend_write,
+ /* blend_read_data */ workspace_blend_read_data,
+ /* blend_read_lib */ workspace_blend_read_lib,
+ /* blend_read_expand */ workspace_blend_read_expand,
+
+ /* blend_read_undo_preserve */ nullptr,
+
+ /* lib_override_apply_post */ nullptr,
};
/* -------------------------------------------------------------------- */
@@ -230,7 +240,8 @@ static void workspace_layout_name_set(WorkSpace *workspace,
static WorkSpaceLayout *workspace_layout_find_exec(const WorkSpace *workspace,
const bScreen *screen)
{
- return BLI_findptr(&workspace->layouts, screen, offsetof(WorkSpaceLayout, screen));
+ return static_cast<WorkSpaceLayout *>(
+ BLI_findptr(&workspace->layouts, screen, offsetof(WorkSpaceLayout, screen)));
}
static void workspace_relation_add(ListBase *relation_list,
@@ -238,7 +249,7 @@ static void workspace_relation_add(ListBase *relation_list,
const int parentid,
void *data)
{
- WorkSpaceDataRelation *relation = MEM_callocN(sizeof(*relation), __func__);
+ WorkSpaceDataRelation *relation = MEM_cnew<WorkSpaceDataRelation>(__func__);
relation->parent = parent;
relation->parentid = parentid;
relation->value = data;
@@ -256,9 +267,9 @@ static void workspace_relation_ensure_updated(ListBase *relation_list,
const int parentid,
void *data)
{
- WorkSpaceDataRelation *relation = BLI_listbase_bytes_find(
- relation_list, &parentid, sizeof(parentid), offsetof(WorkSpaceDataRelation, parentid));
- if (relation != NULL) {
+ WorkSpaceDataRelation *relation = static_cast<WorkSpaceDataRelation *>(BLI_listbase_bytes_find(
+ relation_list, &parentid, sizeof(parentid), offsetof(WorkSpaceDataRelation, parentid)));
+ if (relation != nullptr) {
relation->parent = parent;
relation->value = data;
/* reinsert at the head of the list, so that more commonly used relations are found faster. */
@@ -274,13 +285,13 @@ static void workspace_relation_ensure_updated(ListBase *relation_list,
static void *workspace_relation_get_data_matching_parent(const ListBase *relation_list,
const void *parent)
{
- WorkSpaceDataRelation *relation = BLI_findptr(
- relation_list, parent, offsetof(WorkSpaceDataRelation, parent));
- if (relation != NULL) {
+ WorkSpaceDataRelation *relation = static_cast<WorkSpaceDataRelation *>(
+ BLI_findptr(relation_list, parent, offsetof(WorkSpaceDataRelation, parent)));
+ if (relation != nullptr) {
return relation->value;
}
- return NULL;
+ return nullptr;
}
/**
@@ -296,7 +307,8 @@ static bool UNUSED_FUNCTION(workspaces_is_screen_used)
#endif
(const Main *bmain, bScreen *screen)
{
- for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
+ for (WorkSpace *workspace = static_cast<WorkSpace *>(bmain->workspaces.first); workspace;
+ workspace = static_cast<WorkSpace *>(workspace->id.next)) {
if (workspace_layout_find_exec(workspace, screen)) {
return true;
}
@@ -313,14 +325,16 @@ static bool UNUSED_FUNCTION(workspaces_is_screen_used)
WorkSpace *BKE_workspace_add(Main *bmain, const char *name)
{
- WorkSpace *new_workspace = BKE_id_new(bmain, ID_WS, name);
+ WorkSpace *new_workspace = static_cast<WorkSpace *>(BKE_id_new(bmain, ID_WS, name));
id_us_ensure_real(&new_workspace->id);
return new_workspace;
}
void BKE_workspace_remove(Main *bmain, WorkSpace *workspace)
{
- for (WorkSpaceLayout *layout = workspace->layouts.first, *layout_next; layout;
+ for (WorkSpaceLayout *layout = static_cast<WorkSpaceLayout *>(workspace->layouts.first),
+ *layout_next;
+ layout;
layout = layout_next) {
layout_next = layout->next;
BKE_workspace_layout_remove(bmain, workspace, layout);
@@ -330,11 +344,13 @@ void BKE_workspace_remove(Main *bmain, WorkSpace *workspace)
WorkSpaceInstanceHook *BKE_workspace_instance_hook_create(const Main *bmain, const int winid)
{
- WorkSpaceInstanceHook *hook = MEM_callocN(sizeof(WorkSpaceInstanceHook), __func__);
+ WorkSpaceInstanceHook *hook = MEM_cnew<WorkSpaceInstanceHook>(__func__);
/* set an active screen-layout for each possible window/workspace combination */
- for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
- BKE_workspace_active_layout_set(hook, winid, workspace, workspace->layouts.first);
+ for (WorkSpace *workspace = static_cast<WorkSpace *>(bmain->workspaces.first); workspace;
+ workspace = static_cast<WorkSpace *>(workspace->id.next)) {
+ BKE_workspace_active_layout_set(
+ hook, winid, workspace, static_cast<WorkSpaceLayout *>(workspace->layouts.first));
}
return hook;
@@ -347,8 +363,11 @@ void BKE_workspace_instance_hook_free(const Main *bmain, WorkSpaceInstanceHook *
BLI_assert(!BLI_listbase_is_empty(&bmain->workspaces) || G.background);
/* Free relations for this hook */
- for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
- for (WorkSpaceDataRelation *relation = workspace->hook_layout_relations.first, *relation_next;
+ for (WorkSpace *workspace = static_cast<WorkSpace *>(bmain->workspaces.first); workspace;
+ workspace = static_cast<WorkSpace *>(workspace->id.next)) {
+ for (WorkSpaceDataRelation *relation = static_cast<WorkSpaceDataRelation *>(
+ workspace->hook_layout_relations.first),
+ *relation_next;
relation;
relation = relation_next) {
relation_next = relation->next;
@@ -366,7 +385,7 @@ WorkSpaceLayout *BKE_workspace_layout_add(Main *bmain,
bScreen *screen,
const char *name)
{
- WorkSpaceLayout *layout = MEM_callocN(sizeof(*layout), __func__);
+ WorkSpaceLayout *layout = MEM_cnew<WorkSpaceLayout>(__func__);
BLI_assert(!workspaces_is_screen_used(bmain, screen));
#ifndef DEBUG
@@ -393,7 +412,10 @@ void BKE_workspace_layout_remove(Main *bmain, WorkSpace *workspace, WorkSpaceLay
void BKE_workspace_relations_free(ListBase *relation_list)
{
- for (WorkSpaceDataRelation *relation = relation_list->first, *relation_next; relation;
+ for (WorkSpaceDataRelation *
+ relation = static_cast<WorkSpaceDataRelation *>(relation_list->first),
+ *relation_next;
+ relation;
relation = relation_next) {
relation_next = relation->next;
workspace_relation_remove(relation_list, relation);
@@ -420,7 +442,7 @@ WorkSpaceLayout *BKE_workspace_layout_find(const WorkSpace *workspace, const bSc
workspace->id.name + 2,
screen->id.name + 2);
- return NULL;
+ return nullptr;
}
WorkSpaceLayout *BKE_workspace_layout_find_global(const Main *bmain,
@@ -430,10 +452,11 @@ WorkSpaceLayout *BKE_workspace_layout_find_global(const Main *bmain,
WorkSpaceLayout *layout;
if (r_workspace) {
- *r_workspace = NULL;
+ *r_workspace = nullptr;
}
- for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
+ for (WorkSpace *workspace = static_cast<WorkSpace *>(bmain->workspaces.first); workspace;
+ workspace = static_cast<WorkSpace *>(workspace->id.next)) {
if ((layout = workspace_layout_find_exec(workspace, screen))) {
if (r_workspace) {
*r_workspace = workspace;
@@ -443,7 +466,7 @@ WorkSpaceLayout *BKE_workspace_layout_find_global(const Main *bmain,
}
}
- return NULL;
+ return nullptr;
}
WorkSpaceLayout *BKE_workspace_layout_iter_circular(const WorkSpace *workspace,
@@ -464,15 +487,15 @@ WorkSpaceLayout *BKE_workspace_layout_iter_circular(const WorkSpace *workspace,
LISTBASE_CIRCULAR_BACKWARD_END(WorkSpaceLayout *, &workspace->layouts, iter_layout, start);
}
else {
- LISTBASE_CIRCULAR_FORWARD_BEGIN (&workspace->layouts, iter_layout, start) {
+ LISTBASE_CIRCULAR_FORWARD_BEGIN (WorkSpaceLayout *, &workspace->layouts, iter_layout, start) {
if (!callback(iter_layout, arg)) {
return iter_layout;
}
}
- LISTBASE_CIRCULAR_FORWARD_END(&workspace->layouts, iter_layout, start);
+ LISTBASE_CIRCULAR_FORWARD_END(WorkSpaceLayout *, &workspace->layouts, iter_layout, start);
}
- return NULL;
+ return nullptr;
}
void BKE_workspace_tool_remove(struct WorkSpace *workspace, struct bToolRef *tref)
@@ -494,13 +517,13 @@ bool BKE_workspace_owner_id_check(const WorkSpace *workspace, const char *owner_
}
/* We could use hash lookup, for now this list is highly likely under < ~16 items. */
- return BLI_findstring(&workspace->owner_ids, owner_id, offsetof(wmOwnerID, name)) != NULL;
+ return BLI_findstring(&workspace->owner_ids, owner_id, offsetof(wmOwnerID, name)) != nullptr;
}
void BKE_workspace_id_tag_all_visible(Main *bmain, int tag)
{
BKE_main_id_tag_listbase(&bmain->workspaces, tag, false);
- wmWindowManager *wm = bmain->wm.first;
+ wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
workspace->id.tag |= tag;
@@ -523,14 +546,14 @@ void BKE_workspace_active_set(WorkSpaceInstanceHook *hook, WorkSpace *workspace)
* that optimization is possible and needed.
* This code can be called from places where we might have this equality, but still want to
* ensure/update the active layout below.
- * Known case where this is buggy and will crash later due to NULL active layout: reading
+ * Known case where this is buggy and will crash later due to nullptr active layout: reading
* a blend file, when the new read workspace ID happens to have the exact same memory address
* as when it was saved in the blend file (extremely unlikely, but possible). */
hook->active = workspace;
if (workspace) {
- WorkSpaceLayout *layout = workspace_relation_get_data_matching_parent(
- &workspace->hook_layout_relations, hook);
+ WorkSpaceLayout *layout = static_cast<WorkSpaceLayout *>(
+ workspace_relation_get_data_matching_parent(&workspace->hook_layout_relations, hook));
if (layout) {
hook->act_layout = layout;
}
@@ -551,7 +574,8 @@ WorkSpaceLayout *BKE_workspace_active_layout_for_workspace_get(const WorkSpaceIn
}
/* Inactive workspace */
- return workspace_relation_get_data_matching_parent(&workspace->hook_layout_relations, hook);
+ return static_cast<WorkSpaceLayout *>(
+ workspace_relation_get_data_matching_parent(&workspace->hook_layout_relations, hook));
}
void BKE_workspace_active_layout_set(WorkSpaceInstanceHook *hook,
diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c
index f4de82824c1..de2e196c163 100644
--- a/source/blender/blenkernel/intern/writeavi.c
+++ b/source/blender/blenkernel/intern/writeavi.c
@@ -122,7 +122,8 @@ bMovieHandle *BKE_movie_handle_get(const char imtype)
R_IMF_IMTYPE_FFMPEG,
R_IMF_IMTYPE_H264,
R_IMF_IMTYPE_XVID,
- R_IMF_IMTYPE_THEORA)) {
+ R_IMF_IMTYPE_THEORA,
+ R_IMF_IMTYPE_AV1)) {
mh.start_movie = BKE_ffmpeg_start;
mh.append_movie = BKE_ffmpeg_append;
mh.end_movie = BKE_ffmpeg_end;
@@ -237,7 +238,7 @@ static int append_avi(void *context_v,
const char *UNUSED(suffix),
ReportList *UNUSED(reports))
{
- unsigned int *rt1, *rt2, *rectot;
+ uint *rt1, *rt2, *rectot;
int x, y;
char *cp, rt;
AviMovie *avi = context_v;
@@ -249,7 +250,7 @@ static int append_avi(void *context_v,
/* note that libavi free's the buffer... stupid interface - zr */
rectot = MEM_mallocN(rectx * recty * sizeof(int), "rectot");
rt1 = rectot;
- rt2 = (unsigned int *)pixels + (recty - 1) * rectx;
+ rt2 = (uint *)pixels + (recty - 1) * rectx;
/* flip y and convert to abgr */
for (y = 0; y < recty; y++, rt1 += rectx, rt2 -= rectx) {
memcpy(rt1, rt2, rectx * sizeof(int));
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 883591e3e87..8d6dba440fd 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -141,19 +141,25 @@ static int write_audio_frame(FFMpegContext *context)
frame->pts = context->audio_time / av_q2d(c->time_base);
frame->nb_samples = context->audio_input_samples;
frame->format = c->sample_fmt;
+# ifdef FFMPEG_USE_OLD_CHANNEL_VARS
frame->channels = c->channels;
frame->channel_layout = c->channel_layout;
+ const int num_channels = c->channels;
+# else
+ av_channel_layout_copy(&frame->ch_layout, &c->ch_layout);
+ const int num_channels = c->ch_layout.nb_channels;
+# endif
if (context->audio_deinterleave) {
int channel, i;
uint8_t *temp;
- for (channel = 0; channel < c->channels; channel++) {
+ for (channel = 0; channel < num_channels; channel++) {
for (i = 0; i < frame->nb_samples; i++) {
memcpy(context->audio_deinterleave_buffer +
(i + channel * frame->nb_samples) * context->audio_sample_size,
context->audio_input_buffer +
- (c->channels * i + channel) * context->audio_sample_size,
+ (num_channels * i + channel) * context->audio_sample_size,
context->audio_sample_size);
}
}
@@ -164,10 +170,11 @@ static int write_audio_frame(FFMpegContext *context)
}
avcodec_fill_audio_frame(frame,
- c->channels,
+ num_channels,
c->sample_fmt,
context->audio_input_buffer,
- context->audio_input_samples * c->channels * context->audio_sample_size,
+ context->audio_input_samples * num_channels *
+ context->audio_sample_size,
1);
int success = 1;
@@ -299,6 +306,10 @@ static const char **get_file_extensions(int format)
static const char *rv[] = {".webm", NULL};
return rv;
}
+ case FFMPEG_AV1: {
+ static const char *rv[] = {".mp4", ".mkv", NULL};
+ return rv;
+ }
default:
return NULL;
}
@@ -425,7 +436,7 @@ static AVRational calc_time_base(uint den, double num, int codec_id)
/* Calculate the precision of the initial floating point number. */
if (num > 1.0) {
- const uint num_integer_bits = log2_floor_u((unsigned int)num);
+ const uint num_integer_bits = log2_floor_u((uint)num);
/* Formula for calculating the epsilon value: (power of two range) / (pow mantissa bits)
* For example, a float has 23 mantissa bits and the float value 3.5f as a pow2 range of
@@ -455,6 +466,204 @@ static AVRational calc_time_base(uint den, double num, int codec_id)
return time_base;
}
+static const AVCodec *get_av1_encoder(
+ FFMpegContext *context, RenderData *rd, AVDictionary **opts, int rectx, int recty)
+{
+ /* There are three possible encoders for AV1: libaom-av1, librav1e, and libsvtav1. librav1e tends
+ * to give the best compression quality while libsvtav1 tends to be the fastest encoder. One of
+ * each will be picked based on the preset setting, and if a particular encoder is not available,
+ * then use the default returned by FFMpeg. */
+ const AVCodec *codec = NULL;
+ switch (context->ffmpeg_preset) {
+ case FFM_PRESET_BEST:
+ /* Default to libaom-av1 for BEST preset due to it performing better than rav1e in terms of
+ * video quality (VMAF scores). Fallback to rav1e if libaom-av1 isn't available. */
+ codec = avcodec_find_encoder_by_name("libaom-av1");
+ if (!codec) {
+ codec = avcodec_find_encoder_by_name("librav1e");
+ }
+ break;
+ case FFM_PRESET_REALTIME:
+ codec = avcodec_find_encoder_by_name("libsvtav1");
+ break;
+ case FFM_PRESET_GOOD:
+ default:
+ codec = avcodec_find_encoder_by_name("libaom-av1");
+ break;
+ }
+
+ /* Use the default AV1 encoder if the specified encoder wasn't found. */
+ if (!codec) {
+ codec = avcodec_find_encoder(AV_CODEC_ID_AV1);
+ }
+
+ /* Apply AV1 encoder specific settings. */
+ if (codec) {
+ if (STREQ(codec->name, "librav1e")) {
+ /* Set "tiles" to 8 to enable multi-threaded encoding. */
+ if (rd->threads > 8) {
+ ffmpeg_dict_set_int(opts, "tiles", rd->threads);
+ }
+ else {
+ ffmpeg_dict_set_int(opts, "tiles", 8);
+ }
+
+ /* Use a reasonable speed setting based on preset. Speed ranges from 0-10.
+ * Must check context->ffmpeg_preset again in case this encoder was selected due to the
+ * absence of another. */
+ switch (context->ffmpeg_preset) {
+ case FFM_PRESET_BEST:
+ ffmpeg_dict_set_int(opts, "speed", 4);
+ break;
+ case FFM_PRESET_REALTIME:
+ ffmpeg_dict_set_int(opts, "speed", 10);
+ break;
+ case FFM_PRESET_GOOD:
+ default:
+ ffmpeg_dict_set_int(opts, "speed", 6);
+ break;
+ }
+ if (context->ffmpeg_crf >= 0) {
+ /* librav1e does not use -crf, but uses -qp in the range of 0-255. Calculates the roughly
+ * equivalent float, and truncates it to an integer. */
+ unsigned int qp_value = ((float)context->ffmpeg_crf) * 255.0F / 51.0F;
+ if (qp_value > 255) {
+ qp_value = 255;
+ }
+ ffmpeg_dict_set_int(opts, "qp", qp_value);
+ }
+ /* Set gop_size as rav1e's "--keyint". */
+ char buffer[64];
+ BLI_snprintf(buffer, sizeof(buffer), "keyint=%d", context->ffmpeg_gop_size);
+ av_dict_set(opts, "rav1e-params", buffer, 0);
+ }
+ else if (STREQ(codec->name, "libsvtav1")) {
+ /* Set preset value based on ffmpeg_preset.
+ * Must check context->ffmpeg_preset again in case this encoder was selected due to the
+ * absence of another. */
+ switch (context->ffmpeg_preset) {
+ case FFM_PRESET_REALTIME:
+ ffmpeg_dict_set_int(opts, "preset", 8);
+ break;
+ case FFM_PRESET_BEST:
+ ffmpeg_dict_set_int(opts, "preset", 3);
+ break;
+ case FFM_PRESET_GOOD:
+ default:
+ ffmpeg_dict_set_int(opts, "preset", 5);
+ break;
+ }
+ if (context->ffmpeg_crf >= 0) {
+ /* libsvtav1 does not support crf until FFmpeg builds since 2022-02-24, use qp as fallback.
+ */
+ ffmpeg_dict_set_int(opts, "qp", context->ffmpeg_crf);
+ }
+ }
+ else if (STREQ(codec->name, "libaom-av1")) {
+ /* Speed up libaom-av1 encoding by enabling multithreading and setting tiles. */
+ ffmpeg_dict_set_int(opts, "row-mt", 1);
+ const char *tiles_string = NULL;
+ bool tiles_string_is_dynamic = false;
+ if (rd->threads > 0) {
+ /* See if threads is a square. */
+ int threads_sqrt = sqrtf(rd->threads);
+ if (threads_sqrt < 4) {
+ /* Ensure a default minimum. */
+ threads_sqrt = 4;
+ }
+ if (is_power_of_2_i(threads_sqrt) && threads_sqrt * threads_sqrt == rd->threads) {
+ /* Is a square num, therefore just do "sqrt x sqrt" for tiles parameter. */
+ int digits = 0;
+ for (int t_sqrt_copy = threads_sqrt; t_sqrt_copy > 0; t_sqrt_copy /= 10) {
+ ++digits;
+ }
+ /* A char array need only an alignment of 1. */
+ char *tiles_string_mut = (char *)calloc(digits * 2 + 2, 1);
+ BLI_snprintf(tiles_string_mut, digits * 2 + 2, "%dx%d", threads_sqrt, threads_sqrt);
+ tiles_string_is_dynamic = true;
+ tiles_string = tiles_string_mut;
+ }
+ else {
+ /* Is not a square num, set greater side based on longer side, or use a square if both
+ sides are equal. */
+ int sqrt_p2 = power_of_2_min_i(threads_sqrt);
+ if (sqrt_p2 < 2) {
+ /* Ensure a default minimum. */
+ sqrt_p2 = 2;
+ }
+ int sqrt_p2_next = power_of_2_min_i((int)rd->threads / sqrt_p2);
+ if (sqrt_p2_next < 1) {
+ sqrt_p2_next = 1;
+ }
+ if (sqrt_p2 > sqrt_p2_next) {
+ /* Ensure sqrt_p2_next is greater or equal to sqrt_p2. */
+ int temp = sqrt_p2;
+ sqrt_p2 = sqrt_p2_next;
+ sqrt_p2_next = temp;
+ }
+ int combined_digits = 0;
+ for (int sqrt_p2_copy = sqrt_p2; sqrt_p2_copy > 0; sqrt_p2_copy /= 10) {
+ ++combined_digits;
+ }
+ for (int sqrt_p2_copy = sqrt_p2_next; sqrt_p2_copy > 0; sqrt_p2_copy /= 10) {
+ ++combined_digits;
+ }
+ /* A char array need only an alignment of 1. */
+ char *tiles_string_mut = (char *)calloc(combined_digits + 2, 1);
+ if (rectx > recty) {
+ BLI_snprintf(tiles_string_mut, combined_digits + 2, "%dx%d", sqrt_p2_next, sqrt_p2);
+ }
+ else if (rectx < recty) {
+ BLI_snprintf(tiles_string_mut, combined_digits + 2, "%dx%d", sqrt_p2, sqrt_p2_next);
+ }
+ else {
+ BLI_snprintf(tiles_string_mut, combined_digits + 2, "%dx%d", sqrt_p2, sqrt_p2);
+ }
+ tiles_string_is_dynamic = true;
+ tiles_string = tiles_string_mut;
+ }
+ }
+ else {
+ /* Thread count unknown, default to 8. */
+ if (rectx > recty) {
+ tiles_string = "4x2";
+ }
+ else if (rectx < recty) {
+ tiles_string = "2x4";
+ }
+ else {
+ tiles_string = "2x2";
+ }
+ }
+ av_dict_set(opts, "tiles", tiles_string, 0);
+ if (tiles_string_is_dynamic) {
+ free((void *)tiles_string);
+ }
+ /* libaom-av1 uses "cpu-used" instead of "preset" for defining compression quality.
+ * This value is in a range from 0-8. 0 and 8 are extremes, but we will allow 8.
+ * Must check context->ffmpeg_preset again in case this encoder was selected due to the
+ * absence of another. */
+ switch (context->ffmpeg_preset) {
+ case FFM_PRESET_REALTIME:
+ ffmpeg_dict_set_int(opts, "cpu-used", 8);
+ break;
+ case FFM_PRESET_BEST:
+ ffmpeg_dict_set_int(opts, "cpu-used", 4);
+ break;
+ case FFM_PRESET_GOOD:
+ default:
+ ffmpeg_dict_set_int(opts, "cpu-used", 6);
+ break;
+ }
+
+ /* CRF related settings is similar to H264 for libaom-av1, so we will rely on those settings
+ * applied later. */
+ }
+ }
+
+ return codec;
+}
+
/* prepare a video stream for the output file */
static AVStream *alloc_video_stream(FFMpegContext *context,
@@ -480,7 +689,14 @@ static AVStream *alloc_video_stream(FFMpegContext *context,
/* Set up the codec context */
- codec = avcodec_find_encoder(codec_id);
+ if (codec_id == AV_CODEC_ID_AV1) {
+ /* Use get_av1_encoder() to get the ideal (hopefully) encoder for AV1 based
+ * on given parameters, and also set up opts. */
+ codec = get_av1_encoder(context, rd, &opts, rectx, recty);
+ }
+ else {
+ codec = avcodec_find_encoder(codec_id);
+ }
if (!codec) {
fprintf(stderr, "Couldn't find valid video codec\n");
context->video_codec = NULL;
@@ -568,7 +784,9 @@ static AVStream *alloc_video_stream(FFMpegContext *context,
default:
printf("Unknown preset number %i, ignoring.\n", context->ffmpeg_preset);
}
- if (preset_name != NULL) {
+ /* "codec_id != AV_CODEC_ID_AV1" is required due to "preset" already being set by an AV1 codec.
+ */
+ if (preset_name != NULL && codec_id != AV_CODEC_ID_AV1) {
av_dict_set(&opts, "preset", preset_name, 0);
}
if (deadline_name != NULL) {
@@ -733,25 +951,34 @@ static AVStream *alloc_audio_stream(FFMpegContext *context,
c->sample_rate = rd->ffcodecdata.audio_mixrate;
c->bit_rate = context->ffmpeg_audio_bitrate * 1000;
c->sample_fmt = AV_SAMPLE_FMT_S16;
- c->channels = rd->ffcodecdata.audio_channels;
+ const int num_channels = rd->ffcodecdata.audio_channels;
+ int channel_layout_mask = 0;
switch (rd->ffcodecdata.audio_channels) {
case FFM_CHANNELS_MONO:
- c->channel_layout = AV_CH_LAYOUT_MONO;
+ channel_layout_mask = AV_CH_LAYOUT_MONO;
break;
case FFM_CHANNELS_STEREO:
- c->channel_layout = AV_CH_LAYOUT_STEREO;
+ channel_layout_mask = AV_CH_LAYOUT_STEREO;
break;
case FFM_CHANNELS_SURROUND4:
- c->channel_layout = AV_CH_LAYOUT_QUAD;
+ channel_layout_mask = AV_CH_LAYOUT_QUAD;
break;
case FFM_CHANNELS_SURROUND51:
- c->channel_layout = AV_CH_LAYOUT_5POINT1_BACK;
+ channel_layout_mask = AV_CH_LAYOUT_5POINT1_BACK;
break;
case FFM_CHANNELS_SURROUND71:
- c->channel_layout = AV_CH_LAYOUT_7POINT1;
+ channel_layout_mask = AV_CH_LAYOUT_7POINT1;
break;
}
+ BLI_assert(channel_layout_mask != 0);
+
+# ifdef FFMPEG_USE_OLD_CHANNEL_VARS
+ c->channels = num_channels;
+ c->channel_layout = channel_layout_mask;
+# else
+ av_channel_layout_from_mask(&c->ch_layout, channel_layout_mask);
+# endif
if (request_float_audio_buffer(codec_id)) {
/* mainly for AAC codec which is experimental */
@@ -806,7 +1033,7 @@ static AVStream *alloc_audio_stream(FFMpegContext *context,
return NULL;
}
- /* need to prevent floating point exception when using vorbis audio codec,
+ /* Need to prevent floating point exception when using VORBIS audio codec,
* initialize this value in the same way as it's done in FFmpeg itself (sergey) */
c->time_base.num = 1;
c->time_base.den = c->sample_rate;
@@ -816,7 +1043,7 @@ static AVStream *alloc_audio_stream(FFMpegContext *context,
* not sure if that is needed anymore, so let's try out if there are any
* complaints regarding some FFmpeg versions users might have. */
context->audio_input_samples = AV_INPUT_BUFFER_MIN_SIZE * 8 / c->bits_per_coded_sample /
- c->channels;
+ num_channels;
}
else {
context->audio_input_samples = c->frame_size;
@@ -826,11 +1053,11 @@ static AVStream *alloc_audio_stream(FFMpegContext *context,
context->audio_sample_size = av_get_bytes_per_sample(c->sample_fmt);
- context->audio_input_buffer = (uint8_t *)av_malloc(context->audio_input_samples * c->channels *
+ context->audio_input_buffer = (uint8_t *)av_malloc(context->audio_input_samples * num_channels *
context->audio_sample_size);
if (context->audio_deinterleave) {
context->audio_deinterleave_buffer = (uint8_t *)av_malloc(
- context->audio_input_samples * c->channels * context->audio_sample_size);
+ context->audio_input_samples * num_channels * context->audio_sample_size);
}
context->audio_time = 0.0f;
@@ -951,6 +1178,9 @@ static int start_ffmpeg_impl(FFMpegContext *context,
case FFMPEG_FLV:
video_codec = AV_CODEC_ID_FLV1;
break;
+ case FFMPEG_AV1:
+ video_codec = AV_CODEC_ID_AV1;
+ break;
default:
/* These containers are not restricted to any specific codec types.
* Currently we expect these to be .avi, .mov, .mkv, and .mp4.
@@ -1156,7 +1386,7 @@ static void ffmpeg_filepath_get(
if ((rd->ffcodecdata.flags & FFMPEG_AUTOSPLIT_OUTPUT) != 0) {
if (context) {
- sprintf(autosplit, "_%03d", context->ffmpeg_autosplit_count);
+ BLI_snprintf(autosplit, sizeof(autosplit), "_%03d", context->ffmpeg_autosplit_count);
}
}
@@ -1218,7 +1448,11 @@ int BKE_ffmpeg_start(void *context_v,
AVCodecContext *c = context->audio_codec;
AUD_DeviceSpecs specs;
+# ifdef FFMPEG_USE_OLD_CHANNEL_VARS
specs.channels = c->channels;
+# else
+ specs.channels = c->ch_layout.nb_channels;
+# endif
switch (av_get_packed_sample_fmt(c->sample_fmt)) {
case AV_SAMPLE_FMT_U8:
@@ -1282,7 +1516,7 @@ int BKE_ffmpeg_append(void *context_v,
PRINT("Writing frame %i, render width=%d, render height=%d\n", frame, rectx, recty);
if (context->video_stream) {
- avframe = generate_video_frame(context, (unsigned char *)pixels);
+ avframe = generate_video_frame(context, (uchar *)pixels);
success = (avframe && write_video_frame(context, avframe, reports));
# ifdef WITH_AUDASPACE
/* Add +1 frame because we want to encode audio up until the next video frame. */
@@ -1482,6 +1716,18 @@ void BKE_ffmpeg_preset_set(RenderData *rd, int preset)
rd->ffcodecdata.mux_packet_size = 2048;
rd->ffcodecdata.mux_rate = 10080000;
break;
+ case FFMPEG_PRESET_AV1:
+ rd->ffcodecdata.type = FFMPEG_AV1;
+ rd->ffcodecdata.codec = AV_CODEC_ID_AV1;
+ rd->ffcodecdata.video_bitrate = 6000;
+ rd->ffcodecdata.gop_size = is_ntsc ? 18 : 15;
+ rd->ffcodecdata.rc_max_rate = 9000;
+ rd->ffcodecdata.rc_min_rate = 0;
+ rd->ffcodecdata.rc_buffer_size = 224 * 8;
+ rd->ffcodecdata.mux_packet_size = 2048;
+ rd->ffcodecdata.mux_rate = 10080000;
+
+ break;
}
}
@@ -1521,6 +1767,12 @@ void BKE_ffmpeg_image_type_verify(RenderData *rd, const ImageFormatData *imf)
audio = 1;
}
}
+ else if (imf->imtype == R_IMF_IMTYPE_AV1) {
+ if (rd->ffcodecdata.codec != AV_CODEC_ID_AV1) {
+ BKE_ffmpeg_preset_set(rd, FFMPEG_PRESET_AV1);
+ audio = 1;
+ }
+ }
if (audio && rd->ffcodecdata.audio_codec < 0) {
rd->ffcodecdata.audio_codec = AV_CODEC_ID_NONE;
diff --git a/source/blender/blenlib/BLI_allocator.hh b/source/blender/blenlib/BLI_allocator.hh
index f19292fffd8..db3caf2eeb7 100644
--- a/source/blender/blenlib/BLI_allocator.hh
+++ b/source/blender/blenlib/BLI_allocator.hh
@@ -63,15 +63,14 @@ class RawAllocator {
};
public:
- void *allocate(size_t size, size_t alignment, const char *UNUSED(name))
+ void *allocate(size_t size, size_t alignment, const char * /*name*/)
{
- BLI_assert(is_power_of_2_i(static_cast<int>(alignment)));
+ BLI_assert(is_power_of_2_i(int(alignment)));
void *ptr = malloc(size + alignment + sizeof(MemHead));
void *used_ptr = reinterpret_cast<void *>(
- reinterpret_cast<uintptr_t>(POINTER_OFFSET(ptr, alignment + sizeof(MemHead))) &
- ~(static_cast<uintptr_t>(alignment) - 1));
- int offset = static_cast<int>((intptr_t)used_ptr - (intptr_t)ptr);
- BLI_assert(offset >= static_cast<int>(sizeof(MemHead)));
+ uintptr_t(POINTER_OFFSET(ptr, alignment + sizeof(MemHead))) & ~(uintptr_t(alignment) - 1));
+ int offset = int(intptr_t(used_ptr) - intptr_t(ptr));
+ BLI_assert(offset >= int(sizeof(MemHead)));
(static_cast<MemHead *>(used_ptr) - 1)->offset = offset;
return used_ptr;
}
diff --git a/source/blender/blenlib/BLI_any.hh b/source/blender/blenlib/BLI_any.hh
index f9b53436763..df67a090e92 100644
--- a/source/blender/blenlib/BLI_any.hh
+++ b/source/blender/blenlib/BLI_any.hh
@@ -42,12 +42,13 @@ template<typename ExtraInfo, typename T>
inline constexpr AnyTypeInfo<ExtraInfo> info_for_inline = {
is_trivially_copy_constructible_extended_v<T> ?
nullptr :
- +[](void *dst, const void *src) { new (dst) T(*(const T *)src); },
+ +[](void *dst, const void *src) { new (dst) T(*static_cast<const T *>(src)); },
is_trivially_move_constructible_extended_v<T> ?
nullptr :
- +[](void *dst, void *src) { new (dst) T(std::move(*(T *)src)); },
- is_trivially_destructible_extended_v<T> ? nullptr :
- +[](void *src) { std::destroy_at(((T *)src)); },
+ +[](void *dst, void *src) { new (dst) T(std::move(*static_cast<T *>(src))); },
+ is_trivially_destructible_extended_v<T> ?
+ nullptr :
+ +[](void *src) { std::destroy_at((static_cast<T *>(src))); },
nullptr,
ExtraInfo::template get<T>()};
diff --git a/source/blender/blenlib/BLI_array.hh b/source/blender/blenlib/BLI_array.hh
index 813277d9968..200381048c9 100644
--- a/source/blender/blenlib/BLI_array.hh
+++ b/source/blender/blenlib/BLI_array.hh
@@ -424,8 +424,7 @@ class Array {
T *allocate(int64_t size)
{
- return static_cast<T *>(
- allocator_.allocate(static_cast<size_t>(size) * sizeof(T), alignof(T), AT));
+ return static_cast<T *>(allocator_.allocate(size_t(size) * sizeof(T), alignof(T), AT));
}
void deallocate_if_not_inline(T *ptr)
diff --git a/source/blender/blenlib/BLI_array_utils.hh b/source/blender/blenlib/BLI_array_utils.hh
new file mode 100644
index 00000000000..264ac00e034
--- /dev/null
+++ b/source/blender/blenlib/BLI_array_utils.hh
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include "BLI_generic_span.hh"
+#include "BLI_generic_virtual_array.hh"
+#include "BLI_index_mask.hh"
+#include "BLI_task.hh"
+#include "BLI_virtual_array.hh"
+
+namespace blender::array_utils {
+
+/**
+ * Fill the destination span by copying masked values from the `src` array. Threaded based on
+ * grain-size.
+ */
+void copy(const GVArray &src, IndexMask selection, GMutableSpan dst, int64_t grain_size = 4096);
+
+/**
+ * Fill the destination span by copying values from the `src` array. Threaded based on
+ * grain-size.
+ */
+template<typename T>
+inline void copy(const Span<T> src,
+ const IndexMask selection,
+ MutableSpan<T> dst,
+ const int64_t grain_size = 4096)
+{
+ BLI_assert(src.size() == dst.size());
+ threading::parallel_for(selection.index_range(), grain_size, [&](const IndexRange range) {
+ for (const int64_t index : selection.slice(range)) {
+ dst[index] = src[index];
+ }
+ });
+}
+
+/**
+ * Fill the destination span by gathering indexed values from the `src` array.
+ */
+void gather(const GVArray &src, IndexMask indices, GMutableSpan dst, int64_t grain_size = 4096);
+
+/**
+ * Fill the destination span by gathering indexed values from the `src` array.
+ */
+void gather(GSpan src, IndexMask indices, GMutableSpan dst, int64_t grain_size = 4096);
+
+/**
+ * Fill the destination span by gathering indexed values from the `src` array.
+ */
+template<typename T>
+inline void gather(const VArray<T> &src,
+ const IndexMask indices,
+ MutableSpan<T> dst,
+ const int64_t grain_size = 4096)
+{
+ BLI_assert(indices.size() == dst.size());
+ threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) {
+ src.materialize_compressed_to_uninitialized(indices.slice(range), dst.slice(range).data());
+ });
+}
+
+/**
+ * Fill the destination span by gathering indexed values from the `src` array.
+ */
+template<typename T, typename IndexT>
+inline void gather(const Span<T> src,
+ const IndexMask indices,
+ MutableSpan<T> dst,
+ const int64_t grain_size = 4096)
+{
+ BLI_assert(indices.size() == dst.size());
+ threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) {
+ for (const int64_t i : range) {
+ dst[i] = src[indices[i]];
+ }
+ });
+}
+
+/**
+ * Fill the destination span by gathering indexed values from the `src` array.
+ */
+template<typename T, typename IndexT>
+inline void gather(const Span<T> src,
+ const Span<IndexT> indices,
+ MutableSpan<T> dst,
+ const int64_t grain_size = 4096)
+{
+ BLI_assert(indices.size() == dst.size());
+ threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) {
+ for (const int64_t i : range) {
+ dst[i] = src[indices[i]];
+ }
+ });
+}
+
+/**
+ * Fill the destination span by gathering indexed values from the `src` array.
+ */
+template<typename T, typename IndexT>
+inline void gather(const VArray<T> &src,
+ const Span<IndexT> indices,
+ MutableSpan<T> dst,
+ const int64_t grain_size = 4096)
+{
+ BLI_assert(indices.size() == dst.size());
+ devirtualize_varray(src, [&](const auto &src) {
+ threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) {
+ for (const int64_t i : range) {
+ dst[i] = src[indices[i]];
+ }
+ });
+ });
+}
+
+} // namespace blender::array_utils
diff --git a/source/blender/blenlib/BLI_assert.h b/source/blender/blenlib/BLI_assert.h
index 4a7fae6e98c..4292620e462 100644
--- a/source/blender/blenlib/BLI_assert.h
+++ b/source/blender/blenlib/BLI_assert.h
@@ -67,7 +67,7 @@ void _BLI_assert_unreachable_print(const char *file, int line, const char *funct
# define BLI_STATIC_ASSERT(a, msg) static_assert(a, msg);
#elif defined(_MSC_VER)
/* Visual Studio */
-# if (_MSC_VER > 1910) && !defined(__clang__)
+# if !defined(__clang__)
# define BLI_STATIC_ASSERT(a, msg) static_assert(a, msg);
# else
# define BLI_STATIC_ASSERT(a, msg) _STATIC_ASSERT(a);
diff --git a/source/blender/blenlib/BLI_bit_vector.hh b/source/blender/blenlib/BLI_bit_vector.hh
index 2cec190f84a..ca6c6b2cd2a 100644
--- a/source/blender/blenlib/BLI_bit_vector.hh
+++ b/source/blender/blenlib/BLI_bit_vector.hh
@@ -106,7 +106,7 @@ class MutableBitRef {
MutableBitRef(uint8_t *byte_ptr, const int64_t bit_index)
{
byte_ptr_ = byte_ptr + (bit_index >> 3);
- mask_ = 1 << static_cast<uint8_t>(bit_index & 7);
+ mask_ = 1 << uint8_t(bit_index & 7);
}
/**
@@ -211,7 +211,7 @@ class BitVector {
data_ = inline_buffer_;
size_in_bits_ = 0;
capacity_in_bits_ = BitsInInlineBuffer;
- uninitialized_fill_n(data_, BytesInInlineBuffer, static_cast<uint8_t>(0));
+ uninitialized_fill_n(data_, BytesInInlineBuffer, uint8_t(0));
}
BitVector(NoExceptConstructor, Allocator allocator = {}) noexcept : BitVector(allocator)
@@ -447,7 +447,7 @@ class BitVector {
/* Fill entire bytes at once. */
const int64_t start_fill_byte_index = aligned_ranges.aligned.start() / BitsPerByte;
const int64_t bytes_to_fill = aligned_ranges.aligned.size() / BitsPerByte;
- const uint8_t fill_value = value ? (uint8_t)0xff : (uint8_t)0x00;
+ const uint8_t fill_value = value ? uint8_t(0xff) : uint8_t(0x00);
initialized_fill_n(data_ + start_fill_byte_index, bytes_to_fill, fill_value);
/* Fill bits in the end that don't cover a full byte. */
@@ -505,7 +505,7 @@ class BitVector {
* uninitialized byte. */
uninitialized_fill_n(new_data + bytes_to_copy,
new_capacity_in_bytes - bytes_to_copy,
- (uint8_t)initial_value_for_new_bytes);
+ uint8_t(initial_value_for_new_bytes));
if (!this->is_inline()) {
allocator_.deallocate(data_);
diff --git a/source/blender/blenlib/BLI_cache_mutex.hh b/source/blender/blenlib/BLI_cache_mutex.hh
new file mode 100644
index 00000000000..8e2a0d1b1a5
--- /dev/null
+++ b/source/blender/blenlib/BLI_cache_mutex.hh
@@ -0,0 +1,106 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+/**
+ * A #CacheMutex is used to protect a lazily computed cache from being computed more than once.
+ * Using #CacheMutex instead of a "raw mutex" to protect a cache has some benefits:
+ * - Avoid common pitfalls like forgetting to use task isolation or a double checked lock.
+ * - Cleaner and less redundant code because the same locking patterns don't have to be repeated
+ * everywhere.
+ * - One can benefit from potential future improvements to #CacheMutex of which there are a few
+ * mentioned below.
+ *
+ * The data protected by #CacheMutex is not part of #CacheMutex. Instead, the #CacheMutex and its
+ * protected data should generally be placed next to each other.
+ *
+ * Each #CacheMutex protects exactly one cache, so multiple cache mutexes have to be used when a
+ * class has multiple caches. That is contrary to a "custom" solution using `std::mutex` where one
+ * mutex could protect multiple caches at the cost of higher lock contention.
+ *
+ * To make sure the cache is up to date, call `CacheMutex::ensure` and pass in the function that
+ * computes the cache.
+ *
+ * To tell the #CacheMutex that the cache is invalidated and to be re-evaluated upon next access
+ * use `CacheMutex::tag_dirty`.
+ *
+ * This example shows how one could implement a lazily computed average vertex position in an
+ * imaginary `Mesh` data structure:
+ *
+ * \code{.cpp}
+ * class Mesh {
+ * private:
+ * mutable CacheMutex average_position_cache_mutex_;
+ * mutable float3 average_position_cache_;
+ *
+ * public:
+ * const float3 &average_position() const
+ * {
+ * average_position_cache_mutex_.ensure([&]() {
+ * average_position_cache_ = actually_compute_average_position();
+ * });
+ * return average_position_cache_;
+ * }
+ *
+ * void tag_positions_changed()
+ * {
+ * average_position_cache_mutex_.tag_dirty();
+ * }
+ * };
+ * \endcode
+ *
+ * Possible future improvements:
+ * - Avoid task isolation when we know that the cache computation does not use threading.
+ * - Try to use a smaller mutex. The mutex does not have to be fair for this use case.
+ * - Try to join the cache computation instead of blocking if another thread is computing the cache
+ * already.
+ */
+
+#include <atomic>
+#include <mutex>
+
+#include "BLI_function_ref.hh"
+
+namespace blender {
+
+class CacheMutex {
+ private:
+ std::mutex mutex_;
+ std::atomic<bool> cache_valid_ = false;
+
+ public:
+ /**
+ * Make sure the cache exists and is up to date. This calls `compute_cache` once to update the
+ * cache (which is stored outside of this class) if it is dirty, otherwise it does nothing.
+ *
+ * This function is thread-safe under the assumption that the same parameters are passed from
+ * every thread.
+ */
+ void ensure(FunctionRef<void()> compute_cache);
+
+ /**
+ * Reset the cache. The next time #ensure is called, it will recompute that code.
+ */
+ void tag_dirty()
+ {
+ cache_valid_.store(false);
+ }
+
+ /**
+ * Return true if the cache currently does not exist or has been invalidated.
+ */
+ bool is_dirty() const
+ {
+ return !this->is_cached();
+ }
+
+ /**
+ * Return true if the cache exists and is valid.
+ */
+ bool is_cached() const
+ {
+ return cache_valid_.load(std::memory_order_relaxed);
+ }
+};
+
+} // namespace blender
diff --git a/source/blender/blenlib/BLI_color_mix.hh b/source/blender/blenlib/BLI_color_mix.hh
index 322da2bf112..55989669f70 100644
--- a/source/blender/blenlib/BLI_color_mix.hh
+++ b/source/blender/blenlib/BLI_color_mix.hh
@@ -76,7 +76,7 @@ struct FloatTraits {
static inline BlendType max(BlendType a, BlendType b)
{
- return min_ff(a, b);
+ return max_ff(a, b);
}
/* Discretizes in steps of 1.0 / range */
diff --git a/source/blender/blenlib/BLI_compiler_attrs.h b/source/blender/blenlib/BLI_compiler_attrs.h
index 99f0aa9f049..f0566e0b3e2 100644
--- a/source/blender/blenlib/BLI_compiler_attrs.h
+++ b/source/blender/blenlib/BLI_compiler_attrs.h
@@ -25,7 +25,7 @@
#endif
/* never returns NULL */
-#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 /* gcc4.9+ only */
+#ifdef __GNUC__
# define ATTR_RETURNS_NONNULL __attribute__((returns_nonnull))
#else
# define ATTR_RETURNS_NONNULL
@@ -39,14 +39,14 @@
#endif
/* hint to treat any non-null function return value cannot alias any other pointer */
-#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 403))
+#ifdef __GNUC__
# define ATTR_MALLOC __attribute__((malloc))
#else
# define ATTR_MALLOC
#endif
/* the function return value points to memory (2 args for 'size * tot') */
-#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 403))
+#if defined(__GNUC__) && !defined(__clang__)
# define ATTR_ALLOC_SIZE(args...) __attribute__((alloc_size(args)))
#else
# define ATTR_ALLOC_SIZE(...)
@@ -69,7 +69,7 @@
/* Use to suppress '-Wimplicit-fallthrough' (in place of 'break'). */
#ifndef ATTR_FALLTHROUGH
-# if defined(__GNUC__) && (__GNUC__ >= 7) /* gcc7.0+ only */
+# ifdef __GNUC__
# define ATTR_FALLTHROUGH __attribute__((fallthrough))
# else
# define ATTR_FALLTHROUGH ((void)0)
diff --git a/source/blender/blenlib/BLI_compute_context.hh b/source/blender/blenlib/BLI_compute_context.hh
index 7422467e400..e3e5b6f9e85 100644
--- a/source/blender/blenlib/BLI_compute_context.hh
+++ b/source/blender/blenlib/BLI_compute_context.hh
@@ -10,7 +10,7 @@
* can combine the logged value with a `ComputeContext`, which identifies the place where the value
* was computed.
*
- * This is not a trivial problem because e.g. just storing storing a pointer to the socket a value
+ * This is not a trivial problem because e.g. just storing a pointer to the socket a value
* belongs to is not enough. That's because the same socket may correspond to many different values
* when the socket is used in a node group that is used multiple times. In this case, not only does
* the socket have to be stored but also the entire nested node group path that led to the
diff --git a/source/blender/blenlib/BLI_convexhull_2d.h b/source/blender/blenlib/BLI_convexhull_2d.h
index 0b4c3d486fb..044c1da6925 100644
--- a/source/blender/blenlib/BLI_convexhull_2d.h
+++ b/source/blender/blenlib/BLI_convexhull_2d.h
@@ -11,43 +11,26 @@ extern "C" {
#endif
/**
- * A.M. Andrew's monotone chain 2D convex hull algorithm.
- *
- * \param points: An array of 2D points presorted by increasing x and y-coords.
- * \param n: The number of points in points.
- * \param r_points: An array of the convex hull vertex indices (max is n).
- * \returns the number of points in r_points.
- */
-int BLI_convexhull_2d_sorted(const float (*points)[2], int n, int r_points[]);
-/**
- * A.M. Andrew's monotone chain 2D convex hull algorithm.
+ * Extract 2D convex hull.
*
* \param points: An array of 2D points.
* \param n: The number of points in points.
* \param r_points: An array of the convex hull vertex indices (max is n).
- * _must_ be allocated as `n * 2` because of how its used internally,
- * even though the final result will be no more than \a n in size.
- * \returns the number of points in r_points.
- */
-int BLI_convexhull_2d(const float (*points)[2], int n, int r_points[]);
-
-/**
- * \return The best angle for fitting the convex hull to an axis aligned bounding box.
- *
- * Intended to be used with #BLI_convexhull_2d
+ * \return The number of indices in r_points.
*
- * \param points_hull: Ordered hull points
- * (result of #BLI_convexhull_2d mapped to a contiguous array).
+ * \note Performance is `O(n.log(n))`, same as `qsort`.
*
- * \note we could return the index of the best edge too if its needed.
*/
-float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned int n);
+int BLI_convexhull_2d(const float (*points)[2], int n, int r_points[/* n */]);
+
/**
- * Wrap #BLI_convexhull_aabb_fit_hull_2d and do the convex hull calculation.
+ * \return The best angle for fitting the points to an axis aligned bounding box.
+ *
+ * \note We could return the index of the best edge too if its needed.
*
- * \param points: arbitrary 2d points.
+ * \param points: Arbitrary 2d points.
*/
-float BLI_convexhull_aabb_fit_points_2d(const float (*points)[2], unsigned int n);
+float BLI_convexhull_aabb_fit_points_2d(const float (*points)[2], int n);
#ifdef __cplusplus
}
diff --git a/source/blender/blenlib/BLI_cpp_type.hh b/source/blender/blenlib/BLI_cpp_type.hh
index 8cf5ead1c7b..568ccbb5a64 100644
--- a/source/blender/blenlib/BLI_cpp_type.hh
+++ b/source/blender/blenlib/BLI_cpp_type.hh
@@ -297,7 +297,7 @@ class CPPType : NonCopyable, NonMovable {
*/
bool pointer_has_valid_alignment(const void *ptr) const
{
- return ((uintptr_t)ptr & alignment_mask_) == 0;
+ return (uintptr_t(ptr) & alignment_mask_) == 0;
}
bool pointer_can_point_to_instance(const void *ptr) const
diff --git a/source/blender/blenlib/BLI_cpp_type_make.hh b/source/blender/blenlib/BLI_cpp_type_make.hh
index b0dbbff7ca8..1f494624821 100644
--- a/source/blender/blenlib/BLI_cpp_type_make.hh
+++ b/source/blender/blenlib/BLI_cpp_type_make.hh
@@ -211,8 +211,8 @@ CPPType::CPPType(CPPTypeParam<T, Flags> /* unused */, StringRef debug_name)
using namespace cpp_type_util;
debug_name_ = debug_name;
- size_ = (int64_t)sizeof(T);
- alignment_ = (int64_t)alignof(T);
+ size_ = int64_t(sizeof(T));
+ alignment_ = int64_t(alignof(T));
is_trivial_ = std::is_trivial_v<T>;
is_trivially_destructible_ = std::is_trivially_destructible_v<T>;
if constexpr (std::is_default_constructible_v<T>) {
@@ -221,7 +221,7 @@ CPPType::CPPType(CPPTypeParam<T, Flags> /* unused */, StringRef debug_name)
value_initialize_ = value_initialize_cb<T>;
value_initialize_indices_ = value_initialize_indices_cb<T>;
static T default_value;
- default_value_ = (void *)&default_value;
+ default_value_ = &default_value;
}
if constexpr (std::is_destructible_v<T>) {
destruct_ = destruct_cb<T>;
@@ -271,7 +271,7 @@ CPPType::CPPType(CPPTypeParam<T, Flags> /* unused */, StringRef debug_name)
is_equal_ = is_equal_cb<T>;
}
- alignment_mask_ = (uintptr_t)alignment_ - (uintptr_t)1;
+ alignment_mask_ = uintptr_t(alignment_) - uintptr_t(1);
has_special_member_functions_ = (default_construct_ && copy_construct_ && copy_assign_ &&
move_construct_ && move_assign_ && destruct_);
}
diff --git a/source/blender/blenlib/BLI_dot_export.hh b/source/blender/blenlib/BLI_dot_export.hh
index b6decca0720..454f3c8412c 100644
--- a/source/blender/blenlib/BLI_dot_export.hh
+++ b/source/blender/blenlib/BLI_dot_export.hh
@@ -98,7 +98,7 @@ class Cluster {
std::string name() const
{
- return "cluster_" + std::to_string((uintptr_t)this);
+ return "cluster_" + std::to_string(uintptr_t(this));
}
void set_parent_cluster(Cluster *new_parent);
diff --git a/source/blender/blenlib/BLI_endian_switch_inline.h b/source/blender/blenlib/BLI_endian_switch_inline.h
index ce44348d4dd..32cb0f234f2 100644
--- a/source/blender/blenlib/BLI_endian_switch_inline.h
+++ b/source/blender/blenlib/BLI_endian_switch_inline.h
@@ -26,7 +26,7 @@ BLI_INLINE void BLI_endian_switch_int16(short *val)
}
BLI_INLINE void BLI_endian_switch_uint16(unsigned short *val)
{
-#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 408)) /* gcc4.8+ only */
+#ifdef __GNUC__
*val = __builtin_bswap16(*val);
#else
unsigned short tval = *val;
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index 063e60ecf03..0ff75ca16e5 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -101,6 +101,7 @@ typedef enum eFileAttributes {
FILE_ATTR_MOUNT_POINT = 1 << 14, /* Volume mounted as a folder. */
FILE_ATTR_HARDLINK = 1 << 15, /* Duplicated directory entry. */
} eFileAttributes;
+ENUM_OPERATORS(eFileAttributes, FILE_ATTR_HARDLINK);
#define FILE_ATTR_ANY_LINK \
(FILE_ATTR_ALIAS | FILE_ATTR_REPARSE_POINT | FILE_ATTR_SYMLINK | FILE_ATTR_JUNCTION_POINT | \
diff --git a/source/blender/blenlib/BLI_function_ref.hh b/source/blender/blenlib/BLI_function_ref.hh
index 9a38176c988..bc386322c5d 100644
--- a/source/blender/blenlib/BLI_function_ref.hh
+++ b/source/blender/blenlib/BLI_function_ref.hh
@@ -116,7 +116,7 @@ template<typename Ret, typename... Params> class FunctionRef<Ret(Params...)> {
!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Callable>>, FunctionRef>))>
FunctionRef(Callable &&callable)
: callback_(callback_fn<typename std::remove_reference_t<Callable>>),
- callable_(reinterpret_cast<intptr_t>(&callable))
+ callable_(intptr_t(&callable))
{
}
diff --git a/source/blender/blenlib/BLI_generic_array.hh b/source/blender/blenlib/BLI_generic_array.hh
index 4b917434264..03dc8814309 100644
--- a/source/blender/blenlib/BLI_generic_array.hh
+++ b/source/blender/blenlib/BLI_generic_array.hh
@@ -231,7 +231,9 @@ class GArray {
this->deallocate(new_data);
throw;
}
- this->deallocate(data_);
+ if (this->data_) {
+ this->deallocate(data_);
+ }
data_ = new_data;
}
@@ -243,7 +245,7 @@ class GArray {
{
const int64_t item_size = type_->size();
const int64_t alignment = type_->alignment();
- return allocator_.allocate(static_cast<size_t>(size) * item_size, alignment, AT);
+ return allocator_.allocate(size_t(size) * item_size, alignment, AT);
}
void deallocate(void *ptr)
diff --git a/source/blender/blenlib/BLI_generic_virtual_array.hh b/source/blender/blenlib/BLI_generic_virtual_array.hh
index 21549896f45..e8a27cea6d8 100644
--- a/source/blender/blenlib/BLI_generic_virtual_array.hh
+++ b/source/blender/blenlib/BLI_generic_virtual_array.hh
@@ -78,7 +78,7 @@ class GVMutableArrayImpl : public GVArrayImpl {
namespace detail {
struct GVArrayAnyExtraInfo {
const GVArrayImpl *(*get_varray)(const void *buffer) =
- [](const void *UNUSED(buffer)) -> const GVArrayImpl * { return nullptr; };
+ [](const void * /*buffer*/) -> const GVArrayImpl * { return nullptr; };
template<typename StorageT> static constexpr GVArrayAnyExtraInfo get();
};
@@ -315,7 +315,7 @@ template<typename T> class GVArrayImpl_For_VArray : public GVArrayImpl {
protected:
void get(const int64_t index, void *r_value) const override
{
- *(T *)r_value = varray_[index];
+ *static_cast<T *>(r_value) = varray_[index];
}
void get_to_uninitialized(const int64_t index, void *r_value) const override
@@ -325,22 +325,24 @@ template<typename T> class GVArrayImpl_For_VArray : public GVArrayImpl {
void materialize(const IndexMask mask, void *dst) const override
{
- varray_.materialize(mask, MutableSpan((T *)dst, mask.min_array_size()));
+ varray_.materialize(mask, MutableSpan(static_cast<T *>(dst), mask.min_array_size()));
}
void materialize_to_uninitialized(const IndexMask mask, void *dst) const override
{
- varray_.materialize_to_uninitialized(mask, MutableSpan((T *)dst, mask.min_array_size()));
+ varray_.materialize_to_uninitialized(
+ mask, MutableSpan(static_cast<T *>(dst), mask.min_array_size()));
}
void materialize_compressed(const IndexMask mask, void *dst) const override
{
- varray_.materialize_compressed(mask, MutableSpan((T *)dst, mask.size()));
+ varray_.materialize_compressed(mask, MutableSpan(static_cast<T *>(dst), mask.size()));
}
void materialize_compressed_to_uninitialized(const IndexMask mask, void *dst) const override
{
- varray_.materialize_compressed_to_uninitialized(mask, MutableSpan((T *)dst, mask.size()));
+ varray_.materialize_compressed_to_uninitialized(
+ mask, MutableSpan(static_cast<T *>(dst), mask.size()));
}
bool try_assign_VArray(void *varray) const override
@@ -422,7 +424,7 @@ template<typename T> class GVMutableArrayImpl_For_VMutableArray : public GVMutab
protected:
void get(const int64_t index, void *r_value) const override
{
- *(T *)r_value = varray_[index];
+ *static_cast<T *>(r_value) = varray_[index];
}
void get_to_uninitialized(const int64_t index, void *r_value) const override
@@ -443,40 +445,42 @@ template<typename T> class GVMutableArrayImpl_For_VMutableArray : public GVMutab
void set_by_relocate(const int64_t index, void *value) override
{
- T &value_ = *(T *)value;
+ T &value_ = *static_cast<T *>(value);
varray_.set(index, std::move(value_));
value_.~T();
}
void set_by_move(const int64_t index, void *value) override
{
- T &value_ = *(T *)value;
+ T &value_ = *static_cast<T *>(value);
varray_.set(index, std::move(value_));
}
void set_all(const void *src) override
{
- varray_.set_all(Span((T *)src, size_));
+ varray_.set_all(Span(static_cast<const T *>(src), size_));
}
void materialize(const IndexMask mask, void *dst) const override
{
- varray_.materialize(mask, MutableSpan((T *)dst, mask.min_array_size()));
+ varray_.materialize(mask, MutableSpan(static_cast<T *>(dst), mask.min_array_size()));
}
void materialize_to_uninitialized(const IndexMask mask, void *dst) const override
{
- varray_.materialize_to_uninitialized(mask, MutableSpan((T *)dst, mask.min_array_size()));
+ varray_.materialize_to_uninitialized(
+ mask, MutableSpan(static_cast<T *>(dst), mask.min_array_size()));
}
void materialize_compressed(const IndexMask mask, void *dst) const override
{
- varray_.materialize_compressed(mask, MutableSpan((T *)dst, mask.size()));
+ varray_.materialize_compressed(mask, MutableSpan(static_cast<T *>(dst), mask.size()));
}
void materialize_compressed_to_uninitialized(const IndexMask mask, void *dst) const override
{
- varray_.materialize_compressed_to_uninitialized(mask, MutableSpan((T *)dst, mask.size()));
+ varray_.materialize_compressed_to_uninitialized(
+ mask, MutableSpan(static_cast<T *>(dst), mask.size()));
}
bool try_assign_VArray(void *varray) const override
@@ -709,7 +713,7 @@ inline bool GVMutableArray::try_assign_VMutableArray(VMutableArray<T> &varray) c
inline GVMutableArrayImpl *GVMutableArray::get_impl() const
{
- return (GVMutableArrayImpl *)impl_;
+ return const_cast<GVMutableArrayImpl *>(static_cast<const GVMutableArrayImpl *>(impl_));
}
/** \} */
diff --git a/source/blender/blenlib/BLI_generic_virtual_vector_array.hh b/source/blender/blenlib/BLI_generic_virtual_vector_array.hh
index 364b1ab33c7..373d010d926 100644
--- a/source/blender/blenlib/BLI_generic_virtual_vector_array.hh
+++ b/source/blender/blenlib/BLI_generic_virtual_vector_array.hh
@@ -133,8 +133,8 @@ class GVVectorArray_For_SingleGSpan : public GVVectorArray {
}
protected:
- int64_t get_vector_size_impl(int64_t UNUSED(index)) const override;
- void get_vector_element_impl(int64_t UNUSED(index),
+ int64_t get_vector_size_impl(int64_t /*index*/) const override;
+ void get_vector_element_impl(int64_t /*index*/,
int64_t index_in_vector,
void *r_value) const override;
diff --git a/source/blender/blenlib/BLI_hash.hh b/source/blender/blenlib/BLI_hash.hh
index 25d7cd6aaf8..693d4a8a71c 100644
--- a/source/blender/blenlib/BLI_hash.hh
+++ b/source/blender/blenlib/BLI_hash.hh
@@ -85,7 +85,7 @@ template<typename T> struct DefaultHash {
{
if constexpr (std::is_enum_v<T>) {
/* For enums use the value as hash directly. */
- return (uint64_t)value;
+ return uint64_t(value);
}
else {
/* Try to call the `hash()` function on the value. */
@@ -119,7 +119,7 @@ template<typename T> struct DefaultHash<const T> {
template<> struct DefaultHash<TYPE> { \
uint64_t operator()(TYPE value) const \
{ \
- return static_cast<uint64_t>(value); \
+ return uint64_t(value); \
} \
}
@@ -158,7 +158,7 @@ template<> struct DefaultHash<double> {
template<> struct DefaultHash<bool> {
uint64_t operator()(bool value) const
{
- return static_cast<uint64_t>((value != false) * 1298191);
+ return uint64_t((value != false) * 1298191);
}
};
@@ -209,8 +209,8 @@ template<> struct DefaultHash<std::string_view> {
template<typename T> struct DefaultHash<T *> {
uint64_t operator()(const T *value) const
{
- uintptr_t ptr = reinterpret_cast<uintptr_t>(value);
- uint64_t hash = static_cast<uint64_t>(ptr >> 4);
+ uintptr_t ptr = uintptr_t(value);
+ uint64_t hash = uint64_t(ptr >> 4);
return hash;
}
};
diff --git a/source/blender/blenlib/BLI_hash_tables.hh b/source/blender/blenlib/BLI_hash_tables.hh
index 156fe481828..de65c58d4db 100644
--- a/source/blender/blenlib/BLI_hash_tables.hh
+++ b/source/blender/blenlib/BLI_hash_tables.hh
@@ -43,8 +43,7 @@ inline constexpr int64_t log2_floor_constexpr(const int64_t x)
inline constexpr int64_t log2_ceil_constexpr(const int64_t x)
{
BLI_assert(x >= 0);
- return (is_power_of_2_constexpr(static_cast<int>(x))) ? log2_floor_constexpr(x) :
- log2_floor_constexpr(x) + 1;
+ return (is_power_of_2_constexpr(int(x))) ? log2_floor_constexpr(x) : log2_floor_constexpr(x) + 1;
}
inline constexpr int64_t power_of_2_max_constexpr(const int64_t x)
@@ -71,17 +70,14 @@ inline constexpr int64_t ceil_division_by_fraction(const int64_t x,
const int64_t numerator,
const int64_t denominator)
{
- return static_cast<int64_t>(
- ceil_division(static_cast<uint64_t>(x) * static_cast<uint64_t>(denominator),
- static_cast<uint64_t>(numerator)));
+ return int64_t(ceil_division(uint64_t(x) * uint64_t(denominator), uint64_t(numerator)));
}
inline constexpr int64_t floor_multiplication_with_fraction(const int64_t x,
const int64_t numerator,
const int64_t denominator)
{
- return static_cast<int64_t>((static_cast<uint64_t>(x) * static_cast<uint64_t>(numerator) /
- static_cast<uint64_t>(denominator)));
+ return int64_t((uint64_t(x) * uint64_t(numerator) / uint64_t(denominator)));
}
inline constexpr int64_t total_slot_amount_for_usable_slots(
@@ -121,7 +117,7 @@ class LoadFactor {
int64_t *r_total_slots,
int64_t *r_usable_slots) const
{
- BLI_assert(is_power_of_2_i(static_cast<int>(min_total_slots)));
+ BLI_assert(is_power_of_2_i(int(min_total_slots)));
int64_t total_slots = this->compute_total_slots(min_usable_slots, numerator_, denominator_);
total_slots = std::max(total_slots, min_total_slots);
@@ -229,17 +225,17 @@ template<typename Pointer> struct PointerKeyInfo {
static bool is_empty(Pointer pointer)
{
- return (uintptr_t)pointer == UINTPTR_MAX;
+ return uintptr_t(pointer) == UINTPTR_MAX;
}
static bool is_removed(Pointer pointer)
{
- return (uintptr_t)pointer == UINTPTR_MAX - 1;
+ return uintptr_t(pointer) == UINTPTR_MAX - 1;
}
static bool is_not_empty_or_removed(Pointer pointer)
{
- return (uintptr_t)pointer < UINTPTR_MAX - 1;
+ return uintptr_t(pointer) < UINTPTR_MAX - 1;
}
};
diff --git a/source/blender/blenlib/BLI_index_range.hh b/source/blender/blenlib/BLI_index_range.hh
index a0f129c7324..c259282ca64 100644
--- a/source/blender/blenlib/BLI_index_range.hh
+++ b/source/blender/blenlib/BLI_index_range.hh
@@ -140,6 +140,10 @@ class IndexRange {
{
return (a.size_ == b.size_) && (a.start_ == b.start_ || a.size_ == 0);
}
+ constexpr friend bool operator!=(IndexRange a, IndexRange b)
+ {
+ return !(a == b);
+ }
/**
* Get the amount of numbers in the range.
@@ -248,6 +252,19 @@ class IndexRange {
}
/**
+ * Returns a new IndexRange that contains the intersection of the current one with the given
+ * range. Returns empty range if there are no overlapping indices. The returned range is always
+ * a valid slice of this range.
+ */
+ constexpr IndexRange intersect(IndexRange other) const
+ {
+ const int64_t old_end = start_ + size_;
+ const int64_t new_start = std::min(old_end, std::max(start_, other.start_));
+ const int64_t new_end = std::max(new_start, std::min(old_end, other.start_ + other.size_));
+ return IndexRange(new_start, new_end - new_start);
+ }
+
+ /**
* Returns a new IndexRange with n elements removed from the beginning of the range.
* This invokes undefined behavior when n is negative.
*/
diff --git a/source/blender/blenlib/BLI_lazy_threading.hh b/source/blender/blenlib/BLI_lazy_threading.hh
new file mode 100644
index 00000000000..4d04fe9e908
--- /dev/null
+++ b/source/blender/blenlib/BLI_lazy_threading.hh
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+/** \file
+ * \ingroup bli
+ *
+ * The goal of "lazy threading" is to avoid using threads unless one can reasonably assume that it
+ * is worth distributing work over multiple threads. Using threads can lead to worse overall
+ * performance by introducing inter-thread communication overhead. Keeping all work on a single
+ * thread reduces this overhead to zero and also makes better use of the CPU cache.
+ *
+ * Functions like #parallel_for also solve this to some degree by using a "grain size". When the
+ * number of individual tasks is too small, no multi-threading is used. This works very well when
+ * there are many homogeneous tasks that can be expected to take approximately the same time.
+ *
+ * The situation becomes more difficult when:
+ * - The individual tasks are not homogeneous, i.e. they take different amounts of time to compute.
+ * - It is practically impossible to guess how long each task will take in advance.
+ *
+ * Given those constraints, a single grain size cannot be determined. One could just schedule all
+ * tasks individually but that would create a lot of overhead when the tasks happen to be very
+ * small. While TBB will keep all tasks on a single thread if the other threads are busy, if they
+ * are idle they will start stealing the work even if that's not beneficial for overall
+ * performance.
+ *
+ * This file provides a simple API that allows a task scheduler to properly handle tasks whose size
+ * is not known in advance. The key idea is this:
+ *
+ * > By default, all work stays on a single thread. If an individual task notices that it is about
+ * > start a computation that will take a while, it notifies the task scheduler further up on the
+ * > stack. The scheduler then allows other threads to take over other tasks that were originally
+ * > meant for the current thread.
+ *
+ * This way, when all tasks are small, no threading overhead has to be paid for. Whenever there is
+ * a task that keeps the current thread busy for a while, the other tasks are moved to a separate
+ * thread so that they can be executed without waiting for the long computation to finish.
+ *
+ * Consequently, the earlier a task knows during it execution that it will take a while, the
+ * better. That's because if it is blocking anyway, it's more efficient to move the other tasks to
+ * another thread earlier.
+ *
+ * To make this work, three things have to be solved:
+ * 1. The task scheduler has to be able to start single-threaded and become multi-threaded after
+ * tasks have started executing. This has to be solved in the specific task scheduler.
+ * 2. There has to be a way for the currently running task to tell the task scheduler that it is
+ * about to perform a computation that will take a while and that it would be reasonable to move
+ * other tasks to other threads. This part is implemented in the API provided by this file.
+ * 3. Individual tasks have to decide when a computation is long enough to justify talking to the
+ * scheduler. This is always based on heuristics that have to be fine tuned over time. One could
+ * assume that this means adding new work-size checks to many parts in Blender, but that's
+ * actually not necessary, because these checks exist already in the form of grain sizes passed
+ * to e.g. #parallel_for. The assumption here is that when the task thinks the current work load
+ * is big enough to justify using threads, it's also big enough to justify using another thread
+ * for waiting tasks on the current thread.
+ */
+
+#include "BLI_function_ref.hh"
+
+namespace blender::lazy_threading {
+
+/**
+ * Tell task schedulers on the current thread that it is about to start a long computation
+ * and that other waiting tasks should better be moved to another thread if possible.
+ */
+void send_hint();
+
+/**
+ * Used by the task scheduler to receive hints from current tasks that they will take a while.
+ * This should only be allocated on the stack.
+ */
+class HintReceiver {
+ public:
+ /**
+ * The passed in function is called when a task signals that it will take a while.
+ * \note The function has to stay alive after the call to the constructor. So one must not pass a
+ * lambda directly into this constructor but store it in a separate variable on the stack first.
+ */
+ HintReceiver(FunctionRef<void()> fn);
+ ~HintReceiver();
+};
+
+/**
+ * Used to make sure that lazy-threading hints don't propagate through task isolation. This is
+ * necessary to avoid deadlocks when isolated regions are used together with e.g. task pools. For
+ * more info see the comment on #BLI_task_isolate.
+ */
+class ReceiverIsolation {
+ public:
+ ReceiverIsolation();
+ ~ReceiverIsolation();
+};
+
+} // namespace blender::lazy_threading
diff --git a/source/blender/blenlib/BLI_linear_allocator.hh b/source/blender/blenlib/BLI_linear_allocator.hh
index deb6ea3b5fd..a897845db45 100644
--- a/source/blender/blenlib/BLI_linear_allocator.hh
+++ b/source/blender/blenlib/BLI_linear_allocator.hh
@@ -161,7 +161,7 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
void *pointer_buffer = this->allocate(element_amount * sizeof(void *), alignof(void *));
void *elements_buffer = this->allocate(element_amount * element_size, element_alignment);
- MutableSpan<void *> pointers((void **)pointer_buffer, element_amount);
+ MutableSpan<void *> pointers(static_cast<void **>(pointer_buffer), element_amount);
void *next_element_buffer = elements_buffer;
for (int64_t i : IndexRange(element_amount)) {
pointers[i] = next_element_buffer;
@@ -207,8 +207,8 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
Span<char> buffer = unused_borrowed_buffers_[i];
if (buffer.size() >= min_allocation_size) {
unused_borrowed_buffers_.remove_and_reorder(i);
- current_begin_ = (uintptr_t)buffer.begin();
- current_end_ = (uintptr_t)buffer.end();
+ current_begin_ = uintptr_t(buffer.begin());
+ current_end_ = uintptr_t(buffer.end());
return;
}
}
@@ -226,7 +226,7 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
void *buffer = allocator_.allocate(size_in_bytes, min_alignment, __func__);
owned_buffers_.append(buffer);
- current_begin_ = (uintptr_t)buffer;
+ current_begin_ = uintptr_t(buffer);
current_end_ = current_begin_ + size_in_bytes;
}
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index 9322fa4c85b..6a41fce27b3 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -301,21 +301,22 @@ struct LinkData *BLI_genericNodeN(void *data);
*
* \code{.c}
*
- * LISTBASE_CIRCULAR_FORWARD_BEGIN(listbase, item, item_init)
+ * LISTBASE_CIRCULAR_FORWARD_BEGIN(type, listbase, item, item_init)
* {
* ...operate on marker...
* }
- * LISTBASE_CIRCULAR_FORWARD_END (listbase, item, item_init);
+ * LISTBASE_CIRCULAR_FORWARD_END (type, listbase, item, item_init);
*
* \endcode
*/
-#define LISTBASE_CIRCULAR_FORWARD_BEGIN(lb, lb_iter, lb_init) \
- if ((lb)->first && (lb_init || (lb_init = (lb)->first))) { \
- lb_iter = lb_init; \
+#define LISTBASE_CIRCULAR_FORWARD_BEGIN(type, lb, lb_iter, lb_init) \
+ if ((lb)->first && (lb_init || (lb_init = (type)(lb)->first))) { \
+ lb_iter = (type)(lb_init); \
do {
-#define LISTBASE_CIRCULAR_FORWARD_END(lb, lb_iter, lb_init) \
+#define LISTBASE_CIRCULAR_FORWARD_END(type, lb, lb_iter, lb_init) \
} \
- while ((lb_iter = (lb_iter)->next ? (lb_iter)->next : (lb)->first), (lb_iter != lb_init)) \
+ while ((lb_iter = (lb_iter)->next ? (type)(lb_iter)->next : (type)(lb)->first), \
+ (lb_iter != lb_init)) \
; \
} \
((void)0)
diff --git a/source/blender/blenlib/BLI_listbase_wrapper.hh b/source/blender/blenlib/BLI_listbase_wrapper.hh
index 2d631cb2441..a32243bc411 100644
--- a/source/blender/blenlib/BLI_listbase_wrapper.hh
+++ b/source/blender/blenlib/BLI_listbase_wrapper.hh
@@ -42,7 +42,7 @@ template<typename T> class ListBaseWrapper {
Iterator &operator++()
{
- /* Some types store next/prev using `void *`, so cast is necessary. */
+ /* Some types store `next/prev` using `void *`, so cast is necessary. */
current_ = static_cast<T *>(current_->next);
return *this;
}
diff --git a/source/blender/blenlib/BLI_map.hh b/source/blender/blenlib/BLI_map.hh
index 95d1e344894..6d281420c47 100644
--- a/source/blender/blenlib/BLI_map.hh
+++ b/source/blender/blenlib/BLI_map.hh
@@ -887,6 +887,25 @@ class Map {
}
/**
+ * Remove all key-value-pairs for that the given predicate is true.
+ *
+ * This is similar to std::erase_if.
+ */
+ template<typename Predicate> void remove_if(Predicate &&predicate)
+ {
+ for (Slot &slot : slots_) {
+ if (slot.is_occupied()) {
+ const Key &key = *slot.key();
+ Value &value = *slot.value();
+ if (predicate(MutableItem{key, value})) {
+ slot.remove();
+ removed_slots_++;
+ }
+ }
+ }
+ }
+
+ /**
* Print common statistics like size and collision count. This is useful for debugging purposes.
*/
void print_stats(StringRef name = "") const
@@ -943,7 +962,7 @@ class Map {
*/
int64_t size_in_bytes() const
{
- return static_cast<int64_t>(sizeof(Slot) * slots_.size());
+ return int64_t(sizeof(Slot) * slots_.size());
}
/**
@@ -987,7 +1006,7 @@ class Map {
max_load_factor_.compute_total_and_usable_slots(
SlotArray::inline_buffer_capacity(), min_usable_slots, &total_slots, &usable_slots);
BLI_assert(total_slots >= 1);
- const uint64_t new_slot_mask = static_cast<uint64_t>(total_slots) - 1;
+ const uint64_t new_slot_mask = uint64_t(total_slots) - 1;
/**
* Optimize the case when the map was empty beforehand. We can avoid some copies here.
@@ -1261,7 +1280,7 @@ template<typename Key, typename Value> class StdUnorderedMapWrapper {
public:
int64_t size() const
{
- return static_cast<int64_t>(map_.size());
+ return int64_t(map_.size());
}
bool is_empty() const
@@ -1295,7 +1314,7 @@ template<typename Key, typename Value> class StdUnorderedMapWrapper {
bool remove(const Key &key)
{
- return (bool)map_.erase(key);
+ return bool(map_.erase(key));
}
Value &lookup(const Key &key)
@@ -1313,7 +1332,7 @@ template<typename Key, typename Value> class StdUnorderedMapWrapper {
map_.clear();
}
- void print_stats(StringRef UNUSED(name) = "") const
+ void print_stats(StringRef /*name*/ = "") const
{
}
};
diff --git a/source/blender/blenlib/BLI_map_slots.hh b/source/blender/blenlib/BLI_map_slots.hh
index 6426216913f..eb2c1a7f5cf 100644
--- a/source/blender/blenlib/BLI_map_slots.hh
+++ b/source/blender/blenlib/BLI_map_slots.hh
@@ -169,7 +169,7 @@ template<typename Key, typename Value> class SimpleMapSlot {
* key. The hash can be used by other slot implementations to determine inequality faster.
*/
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t UNUSED(hash)) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t /*hash*/) const
{
if (state_ == Occupied) {
return is_equal(key, *key_buffer_);
@@ -194,7 +194,7 @@ template<typename Key, typename Value> class SimpleMapSlot {
* Change the state of this slot from empty/removed to occupied. The value is assumed to be
* constructed already.
*/
- template<typename ForwardKey> void occupy_no_value(ForwardKey &&key, uint64_t UNUSED(hash))
+ template<typename ForwardKey> void occupy_no_value(ForwardKey &&key, uint64_t /*hash*/)
{
BLI_assert(!this->is_occupied());
try {
@@ -295,7 +295,7 @@ template<typename Key, typename Value, typename KeyInfo> class IntrusiveMapSlot
}
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t UNUSED(hash)) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t /*hash*/) const
{
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
return is_equal(key, key_);
@@ -310,7 +310,7 @@ template<typename Key, typename Value, typename KeyInfo> class IntrusiveMapSlot
this->occupy_no_value(std::forward<ForwardKey>(key), hash);
}
- template<typename ForwardKey> void occupy_no_value(ForwardKey &&key, uint64_t UNUSED(hash))
+ template<typename ForwardKey> void occupy_no_value(ForwardKey &&key, uint64_t /*hash*/)
{
BLI_assert(!this->is_occupied());
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
diff --git a/source/blender/blenlib/BLI_math_inline.h b/source/blender/blenlib/BLI_math_inline.h
index bf91c9108a9..b190b022a88 100644
--- a/source/blender/blenlib/BLI_math_inline.h
+++ b/source/blender/blenlib/BLI_math_inline.h
@@ -28,8 +28,8 @@ extern "C" {
# define MALWAYS_INLINE
#endif
-/* gcc 4.6 (supports push/pop) */
-#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 406))
+/* Check for GCC push/pop pragma support. */
+#ifdef __GNUC__
# define BLI_MATH_GCC_WARN_PRAGMA 1
#endif
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index 19943614881..538474f58b6 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -367,6 +367,8 @@ void pseudoinverse_m4_m4(float inverse[4][4], const float mat[4][4], float epsil
void pseudoinverse_m3_m3(float inverse[3][3], const float mat[3][3], float epsilon);
bool has_zero_axis_m4(const float matrix[4][4]);
+/** Fix any zero scale axis adding a small bias orthogonal to the other valid axis. */
+void zero_axis_bias_m4(float mat[4][4]);
void invert_m4_m4_safe(float inverse[4][4], const float mat[4][4]);
@@ -622,7 +624,7 @@ void BLI_space_transform_apply_normal(const struct SpaceTransform *data, float n
void BLI_space_transform_invert_normal(const struct SpaceTransform *data, float no[3]);
#define BLI_SPACE_TRANSFORM_SETUP(data, local, target) \
- BLI_space_transform_from_matrices((data), (local)->obmat, (target)->obmat)
+ BLI_space_transform_from_matrices((data), (local)->object_to_world, (target)->object_to_world)
/** \} */
diff --git a/source/blender/blenlib/BLI_math_vec_types.hh b/source/blender/blenlib/BLI_math_vec_types.hh
index 7f20881dfa3..0387d0b0440 100644
--- a/source/blender/blenlib/BLI_math_vec_types.hh
+++ b/source/blender/blenlib/BLI_math_vec_types.hh
@@ -40,6 +40,21 @@ template<typename T> struct vec_struct_base<T, 4> {
T x, y, z, w;
};
+template<class Fn, size_t... I> void unroll_impl(Fn fn, std::index_sequence<I...> /*indices*/)
+{
+ (fn(I), ...);
+}
+
+/**
+ * Variadic templates are used to unroll loops manually. This helps GCC avoid branching during math
+ * operations and makes the code generation more explicit and predictable. Unrolling should always
+ * be worth it because the vector size is expected to be small.
+ */
+template<int N, class Fn> void unroll(Fn fn)
+{
+ unroll_impl(fn, std::make_index_sequence<N>());
+}
+
namespace math {
template<typename T> uint64_t vector_hash(const T &vec)
@@ -74,28 +89,28 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
explicit vec_base(uint value)
{
for (int i = 0; i < Size; i++) {
- (*this)[i] = static_cast<T>(value);
+ (*this)[i] = T(value);
}
}
explicit vec_base(int value)
{
for (int i = 0; i < Size; i++) {
- (*this)[i] = static_cast<T>(value);
+ (*this)[i] = T(value);
}
}
explicit vec_base(float value)
{
for (int i = 0; i < Size; i++) {
- (*this)[i] = static_cast<T>(value);
+ (*this)[i] = T(value);
}
}
explicit vec_base(double value)
{
for (int i = 0; i < Size; i++) {
- (*this)[i] = static_cast<T>(value);
+ (*this)[i] = T(value);
}
}
@@ -126,53 +141,42 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
/** Mixed scalar-vector constructors. */
template<typename U, BLI_ENABLE_IF_VEC(Size, == 3)>
- constexpr vec_base(const vec_base<U, 2> &xy, T z)
- : vec_base(static_cast<T>(xy.x), static_cast<T>(xy.y), z)
+ constexpr vec_base(const vec_base<U, 2> &xy, T z) : vec_base(T(xy.x), T(xy.y), z)
{
}
template<typename U, BLI_ENABLE_IF_VEC(Size, == 3)>
- constexpr vec_base(T x, const vec_base<U, 2> &yz)
- : vec_base(x, static_cast<T>(yz.x), static_cast<T>(yz.y))
+ constexpr vec_base(T x, const vec_base<U, 2> &yz) : vec_base(x, T(yz.x), T(yz.y))
{
}
template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)>
- vec_base(vec_base<U, 3> xyz, T w)
- : vec_base(
- static_cast<T>(xyz.x), static_cast<T>(xyz.y), static_cast<T>(xyz.z), static_cast<T>(w))
+ vec_base(vec_base<U, 3> xyz, T w) : vec_base(T(xyz.x), T(xyz.y), T(xyz.z), T(w))
{
}
template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)>
- vec_base(T x, vec_base<U, 3> yzw)
- : vec_base(
- static_cast<T>(x), static_cast<T>(yzw.x), static_cast<T>(yzw.y), static_cast<T>(yzw.z))
+ vec_base(T x, vec_base<U, 3> yzw) : vec_base(T(x), T(yzw.x), T(yzw.y), T(yzw.z))
{
}
template<typename U, typename V, BLI_ENABLE_IF_VEC(Size, == 4)>
- vec_base(vec_base<U, 2> xy, vec_base<V, 2> zw)
- : vec_base(
- static_cast<T>(xy.x), static_cast<T>(xy.y), static_cast<T>(zw.x), static_cast<T>(zw.y))
+ vec_base(vec_base<U, 2> xy, vec_base<V, 2> zw) : vec_base(T(xy.x), T(xy.y), T(zw.x), T(zw.y))
{
}
template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)>
- vec_base(vec_base<U, 2> xy, T z, T w)
- : vec_base(static_cast<T>(xy.x), static_cast<T>(xy.y), static_cast<T>(z), static_cast<T>(w))
+ vec_base(vec_base<U, 2> xy, T z, T w) : vec_base(T(xy.x), T(xy.y), T(z), T(w))
{
}
template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)>
- vec_base(T x, vec_base<U, 2> yz, T w)
- : vec_base(static_cast<T>(x), static_cast<T>(yz.x), static_cast<T>(yz.y), static_cast<T>(w))
+ vec_base(T x, vec_base<U, 2> yz, T w) : vec_base(T(x), T(yz.x), T(yz.y), T(w))
{
}
template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)>
- vec_base(T x, T y, vec_base<U, 2> zw)
- : vec_base(static_cast<T>(x), static_cast<T>(y), static_cast<T>(zw.x), static_cast<T>(zw.y))
+ vec_base(T x, T y, vec_base<U, 2> zw) : vec_base(T(x), T(y), T(zw.x), T(zw.y))
{
}
@@ -182,7 +186,7 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
explicit vec_base(const vec_base<U, OtherSize> &other)
{
for (int i = 0; i < Size; i++) {
- (*this)[i] = static_cast<T>(other[i]);
+ (*this)[i] = T(other[i]);
}
}
@@ -192,17 +196,13 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
vec_base(const T *ptr)
{
- for (int i = 0; i < Size; i++) {
- (*this)[i] = ptr[i];
- }
+ unroll<Size>([&](auto i) { (*this)[i] = ptr[i]; });
}
template<typename U, BLI_ENABLE_IF((std::is_convertible_v<U, T>))>
explicit vec_base(const U *ptr)
{
- for (int i = 0; i < Size; i++) {
- (*this)[i] = ptr[i];
- }
+ unroll<Size>([&](auto i) { (*this)[i] = ptr[i]; });
}
vec_base(const T (*ptr)[Size]) : vec_base(static_cast<const T *>(ptr[0]))
@@ -213,9 +213,7 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
template<typename U> explicit vec_base(const vec_base<U, Size> &vec)
{
- for (int i = 0; i < Size; i++) {
- (*this)[i] = static_cast<T>(vec[i]);
- }
+ unroll<Size>([&](auto i) { (*this)[i] = T(vec[i]); });
}
/** C-style pointer dereference. */
@@ -250,29 +248,20 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
#define BLI_INT_OP(_T) template<typename U = _T, BLI_ENABLE_IF((std::is_integral_v<U>))>
-#define BLI_VEC_OP_IMPL(_result, _i, _op) \
- vec_base _result; \
- for (int _i = 0; _i < Size; _i++) { \
- _op; \
- } \
- return _result;
-
-#define BLI_VEC_OP_IMPL_SELF(_i, _op) \
- for (int _i = 0; _i < Size; _i++) { \
- _op; \
- } \
- return *this;
-
/** Arithmetic operators. */
friend vec_base operator+(const vec_base &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] + b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] + b[i]; });
+ return result;
}
friend vec_base operator+(const vec_base &a, const T &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] + b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] + b; });
+ return result;
}
friend vec_base operator+(const T &a, const vec_base &b)
@@ -282,52 +271,69 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
vec_base &operator+=(const vec_base &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] += b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] += b[i]; });
+ return *this;
}
vec_base &operator+=(const T &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] += b);
+ vec_base result;
+ unroll<Size>([&](auto i) { (*this)[i] += b; });
+ return result;
}
friend vec_base operator-(const vec_base &a)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = -a[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = -a[i]; });
+ return result;
}
friend vec_base operator-(const vec_base &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] - b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] - b[i]; });
+ return result;
}
friend vec_base operator-(const vec_base &a, const T &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] - b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] - b; });
+ return result;
}
friend vec_base operator-(const T &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a - b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a - b[i]; });
+ return result;
}
vec_base &operator-=(const vec_base &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] -= b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] -= b[i]; });
+ return *this;
}
vec_base &operator-=(const T &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] -= b);
+ unroll<Size>([&](auto i) { (*this)[i] -= b; });
+ return *this;
}
friend vec_base operator*(const vec_base &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] * b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] * b[i]; });
+ return result;
}
template<typename FactorT> friend vec_base operator*(const vec_base &a, FactorT b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] * b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] * b; });
+ return result;
}
friend vec_base operator*(T a, const vec_base &b)
@@ -337,12 +343,14 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
vec_base &operator*=(T b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] *= b);
+ unroll<Size>([&](auto i) { (*this)[i] *= b; });
+ return *this;
}
vec_base &operator*=(const vec_base &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] *= b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] *= b[i]; });
+ return *this;
}
friend vec_base operator/(const vec_base &a, const vec_base &b)
@@ -350,13 +358,17 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
for (int i = 0; i < Size; i++) {
BLI_assert(b[i] != T(0));
}
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] / b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] / b[i]; });
+ return result;
}
friend vec_base operator/(const vec_base &a, T b)
{
BLI_assert(b != T(0));
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] / b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] / b; });
+ return result;
}
friend vec_base operator/(T a, const vec_base &b)
@@ -364,31 +376,39 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
for (int i = 0; i < Size; i++) {
BLI_assert(b[i] != T(0));
}
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a / b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a / b[i]; });
+ return result;
}
vec_base &operator/=(T b)
{
BLI_assert(b != T(0));
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] /= b);
+ unroll<Size>([&](auto i) { (*this)[i] /= b; });
+ return *this;
}
vec_base &operator/=(const vec_base &b)
{
BLI_assert(b != T(0));
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] /= b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] /= b[i]; });
+ return *this;
}
/** Binary operators. */
BLI_INT_OP(T) friend vec_base operator&(const vec_base &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] & b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] & b[i]; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator&(const vec_base &a, T b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] & b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] & b; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator&(T a, const vec_base &b)
@@ -398,22 +418,28 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
BLI_INT_OP(T) vec_base &operator&=(T b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] &= b);
+ unroll<Size>([&](auto i) { (*this)[i] &= b; });
+ return *this;
}
BLI_INT_OP(T) vec_base &operator&=(const vec_base &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] &= b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] &= b[i]; });
+ return *this;
}
BLI_INT_OP(T) friend vec_base operator|(const vec_base &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] | b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] | b[i]; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator|(const vec_base &a, T b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] | b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] | b; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator|(T a, const vec_base &b)
@@ -423,22 +449,28 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
BLI_INT_OP(T) vec_base &operator|=(T b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] |= b);
+ unroll<Size>([&](auto i) { (*this)[i] |= b; });
+ return *this;
}
BLI_INT_OP(T) vec_base &operator|=(const vec_base &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] |= b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] |= b[i]; });
+ return *this;
}
BLI_INT_OP(T) friend vec_base operator^(const vec_base &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] ^ b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] ^ b[i]; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator^(const vec_base &a, T b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] ^ b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] ^ b; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator^(T a, const vec_base &b)
@@ -448,59 +480,75 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
BLI_INT_OP(T) vec_base &operator^=(T b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] ^= b);
+ unroll<Size>([&](auto i) { (*this)[i] ^= b; });
+ return *this;
}
BLI_INT_OP(T) vec_base &operator^=(const vec_base &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] ^= b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] ^= b[i]; });
+ return *this;
}
BLI_INT_OP(T) friend vec_base operator~(const vec_base &a)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = ~a[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = ~a[i]; });
+ return result;
}
/** Bit-shift operators. */
BLI_INT_OP(T) friend vec_base operator<<(const vec_base &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] << b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] << b[i]; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator<<(const vec_base &a, T b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] << b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] << b; });
+ return result;
}
BLI_INT_OP(T) vec_base &operator<<=(T b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] <<= b);
+ unroll<Size>([&](auto i) { (*this)[i] <<= b; });
+ return *this;
}
BLI_INT_OP(T) vec_base &operator<<=(const vec_base &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] <<= b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] <<= b[i]; });
+ return *this;
}
BLI_INT_OP(T) friend vec_base operator>>(const vec_base &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] >> b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] >> b[i]; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator>>(const vec_base &a, T b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] >> b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] >> b; });
+ return result;
}
BLI_INT_OP(T) vec_base &operator>>=(T b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] >>= b);
+ unroll<Size>([&](auto i) { (*this)[i] >>= b; });
+ return *this;
}
BLI_INT_OP(T) vec_base &operator>>=(const vec_base &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] >>= b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] >>= b[i]; });
+ return *this;
}
/** Modulo operators. */
@@ -510,24 +558,28 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
for (int i = 0; i < Size; i++) {
BLI_assert(b[i] != T(0));
}
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] % b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] % b[i]; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator%(const vec_base &a, T b)
{
BLI_assert(b != 0);
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] % b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] % b; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator%(T a, const vec_base &b)
{
BLI_assert(b != T(0));
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a % b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a % b[i]; });
+ return result;
}
#undef BLI_INT_OP
-#undef BLI_VEC_OP_IMPL
-#undef BLI_VEC_OP_IMPL_SELF
/** Compare. */
@@ -567,6 +619,11 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
}
};
+using char3 = blender::vec_base<int8_t, 3>;
+
+using uchar3 = blender::vec_base<uint8_t, 3>;
+using uchar4 = blender::vec_base<uint8_t, 4>;
+
using int2 = vec_base<int32_t, 2>;
using int3 = vec_base<int32_t, 3>;
using int4 = vec_base<int32_t, 4>;
@@ -575,7 +632,11 @@ using uint2 = vec_base<uint32_t, 2>;
using uint3 = vec_base<uint32_t, 3>;
using uint4 = vec_base<uint32_t, 4>;
+using short3 = blender::vec_base<int16_t, 3>;
+
using ushort2 = vec_base<uint16_t, 2>;
+using ushort3 = blender::vec_base<uint16_t, 3>;
+using ushort4 = blender::vec_base<uint16_t, 4>;
using float2 = vec_base<float, 2>;
using float3 = vec_base<float, 3>;
diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh
index 384c4b49070..e8303aa858b 100644
--- a/source/blender/blenlib/BLI_math_vector.hh
+++ b/source/blender/blenlib/BLI_math_vector.hh
@@ -357,16 +357,16 @@ inline vec_base<T, 3> cross(const vec_base<T, 3> &a, const vec_base<T, 3> &b)
inline vec_base<float, 3> cross_high_precision(const vec_base<float, 3> &a,
const vec_base<float, 3> &b)
{
- return {(float)((double)a.y * b.z - (double)a.z * b.y),
- (float)((double)a.z * b.x - (double)a.x * b.z),
- (float)((double)a.x * b.y - (double)a.y * b.x)};
+ return {float(double(a.y) * double(b.z) - double(a.z) * double(b.y)),
+ float(double(a.z) * double(b.x) - double(a.x) * double(b.z)),
+ float(double(a.x) * double(b.y) - double(a.y) * double(b.x))};
}
template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, 3> cross_poly(Span<vec_base<T, 3>> poly)
{
/* Newell's Method. */
- int nv = static_cast<int>(poly.size());
+ int nv = int(poly.size());
if (nv < 3) {
return vec_base<T, 3>(0, 0, 0);
}
diff --git a/source/blender/blenlib/BLI_memory_utils.hh b/source/blender/blenlib/BLI_memory_utils.hh
index c2ad3ea761a..b6ffa6d8b4a 100644
--- a/source/blender/blenlib/BLI_memory_utils.hh
+++ b/source/blender/blenlib/BLI_memory_utils.hh
@@ -372,7 +372,7 @@ template<size_t Size, size_t Alignment> class AlignedBuffer {
*/
template<typename T, int64_t Size = 1> class TypedBuffer {
private:
- BLI_NO_UNIQUE_ADDRESS AlignedBuffer<sizeof(T) * (size_t)Size, alignof(T)> buffer_;
+ BLI_NO_UNIQUE_ADDRESS AlignedBuffer<sizeof(T) * size_t(Size), alignof(T)> buffer_;
public:
operator T *()
@@ -516,7 +516,7 @@ inline constexpr bool is_same_any_v = (std::is_same_v<T, Args> || ...);
*/
inline constexpr int64_t default_inline_buffer_capacity(size_t element_size)
{
- return (static_cast<int64_t>(element_size) < 100) ? 4 : 0;
+ return (int64_t(element_size) < 100) ? 4 : 0;
}
/**
diff --git a/source/blender/blenlib/BLI_mesh_intersect.hh b/source/blender/blenlib/BLI_mesh_intersect.hh
index 22ea83760aa..4ed1fe5f513 100644
--- a/source/blender/blenlib/BLI_mesh_intersect.hh
+++ b/source/blender/blenlib/BLI_mesh_intersect.hh
@@ -354,12 +354,12 @@ struct BoundingBox {
void combine(const double3 &p)
{
- min.x = min_ff(min.x, static_cast<float>(p.x));
- min.y = min_ff(min.y, static_cast<float>(p.y));
- min.z = min_ff(min.z, static_cast<float>(p.z));
- max.x = max_ff(max.x, static_cast<float>(p.x));
- max.y = max_ff(max.y, static_cast<float>(p.y));
- max.z = max_ff(max.z, static_cast<float>(p.z));
+ min.x = min_ff(min.x, float(p.x));
+ min.y = min_ff(min.y, float(p.y));
+ min.z = min_ff(min.z, float(p.z));
+ max.x = max_ff(max.x, float(p.x));
+ max.y = max_ff(max.y, float(p.y));
+ max.z = max_ff(max.z, float(p.z));
}
void combine(const BoundingBox &bb)
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index 136258e50f2..4ea059391b6 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -7,7 +7,9 @@
*/
#include "BLI_compiler_attrs.h"
+#include "BLI_compiler_compat.h"
#include "BLI_utildefines.h"
+#include "BLI_utildefines_variadic.h"
#ifdef __cplusplus
extern "C" {
@@ -66,20 +68,25 @@ const char *BLI_path_extension(const char *filepath) ATTR_NONNULL();
/**
* Append a filename to a dir, ensuring slash separates.
+ * \return The new length of `dst`.
*/
-void BLI_path_append(char *__restrict dst, size_t maxlen, const char *__restrict file)
+size_t BLI_path_append(char *__restrict dst, size_t maxlen, const char *__restrict file)
ATTR_NONNULL();
/**
- * Simple appending of filename to dir, does not check for valid path!
- * Puts result into `dst`, which may be same area as `dir`.
- *
- * \note Consider using #BLI_path_join for more general path joining
- * that de-duplicates separators and can handle an arbitrary number of paths.
+ * A version of #BLI_path_append that ensures a trailing slash if there is space in `dst`.
+ * \return The new length of `dst`.
+ */
+size_t BLI_path_append_dir(char *__restrict dst, size_t maxlen, const char *__restrict dir)
+ ATTR_NONNULL();
+
+/**
+ * See #BLI_path_join doc-string.
*/
-void BLI_join_dirfile(char *__restrict dst,
- size_t maxlen,
- const char *__restrict dir,
- const char *__restrict file) ATTR_NONNULL();
+size_t BLI_path_join_array(char *__restrict dst,
+ const size_t dst_len,
+ const char *path_array[],
+ const int path_array_num);
+
/**
* Join multiple strings into a path, ensuring only a single path separator between each,
* and trailing slash is kept.
@@ -95,8 +102,92 @@ void BLI_join_dirfile(char *__restrict dst,
* \note If you want a trailing slash, add `SEP_STR` as the last path argument,
* duplicate slashes will be cleaned up.
*/
-size_t BLI_path_join(char *__restrict dst, size_t dst_len, const char *path, ...)
- ATTR_NONNULL(1, 3) ATTR_SENTINEL(0);
+#define BLI_path_join(...) VA_NARGS_CALL_OVERLOAD(_BLI_path_join_, __VA_ARGS__)
+
+#define _BLI_PATH_JOIN_ARGS_1 char *__restrict dst, size_t dst_len, const char *a
+#define _BLI_PATH_JOIN_ARGS_2 _BLI_PATH_JOIN_ARGS_1, const char *b
+#define _BLI_PATH_JOIN_ARGS_3 _BLI_PATH_JOIN_ARGS_2, const char *c
+#define _BLI_PATH_JOIN_ARGS_4 _BLI_PATH_JOIN_ARGS_3, const char *d
+#define _BLI_PATH_JOIN_ARGS_5 _BLI_PATH_JOIN_ARGS_4, const char *e
+#define _BLI_PATH_JOIN_ARGS_6 _BLI_PATH_JOIN_ARGS_5, const char *f
+#define _BLI_PATH_JOIN_ARGS_7 _BLI_PATH_JOIN_ARGS_6, const char *g
+#define _BLI_PATH_JOIN_ARGS_8 _BLI_PATH_JOIN_ARGS_7, const char *h
+#define _BLI_PATH_JOIN_ARGS_9 _BLI_PATH_JOIN_ARGS_8, const char *i
+#define _BLI_PATH_JOIN_ARGS_10 _BLI_PATH_JOIN_ARGS_9, const char *j
+
+BLI_INLINE size_t _BLI_path_join_3(_BLI_PATH_JOIN_ARGS_1) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_4(_BLI_PATH_JOIN_ARGS_2) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_5(_BLI_PATH_JOIN_ARGS_3) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_6(_BLI_PATH_JOIN_ARGS_4) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_7(_BLI_PATH_JOIN_ARGS_5) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_8(_BLI_PATH_JOIN_ARGS_6) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_9(_BLI_PATH_JOIN_ARGS_7) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_10(_BLI_PATH_JOIN_ARGS_8) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_11(_BLI_PATH_JOIN_ARGS_9) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_12(_BLI_PATH_JOIN_ARGS_10) ATTR_NONNULL();
+
+BLI_INLINE size_t _BLI_path_join_3(_BLI_PATH_JOIN_ARGS_1)
+{
+ const char *path_array[] = {a};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_4(_BLI_PATH_JOIN_ARGS_2)
+{
+ const char *path_array[] = {a, b};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_5(_BLI_PATH_JOIN_ARGS_3)
+{
+ const char *path_array[] = {a, b, c};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_6(_BLI_PATH_JOIN_ARGS_4)
+{
+ const char *path_array[] = {a, b, c, d};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_7(_BLI_PATH_JOIN_ARGS_5)
+{
+ const char *path_array[] = {a, b, c, d, e};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_8(_BLI_PATH_JOIN_ARGS_6)
+{
+ const char *path_array[] = {a, b, c, d, e, f};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_9(_BLI_PATH_JOIN_ARGS_7)
+{
+ const char *path_array[] = {a, b, c, d, e, f, g};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_10(_BLI_PATH_JOIN_ARGS_8)
+{
+ const char *path_array[] = {a, b, c, d, e, f, g, h};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_11(_BLI_PATH_JOIN_ARGS_9)
+{
+ const char *path_array[] = {a, b, c, d, e, f, g, h, i};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_12(_BLI_PATH_JOIN_ARGS_10)
+{
+ const char *path_array[] = {a, b, c, d, e, f, g, h, i, j};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+
+#undef _BLI_PATH_JOIN_ARGS_1
+#undef _BLI_PATH_JOIN_ARGS_2
+#undef _BLI_PATH_JOIN_ARGS_3
+#undef _BLI_PATH_JOIN_ARGS_4
+#undef _BLI_PATH_JOIN_ARGS_5
+#undef _BLI_PATH_JOIN_ARGS_6
+#undef _BLI_PATH_JOIN_ARGS_7
+#undef _BLI_PATH_JOIN_ARGS_8
+#undef _BLI_PATH_JOIN_ARGS_9
+#undef _BLI_PATH_JOIN_ARGS_10
+
/**
* Like Python's `os.path.basename()`
*
@@ -106,12 +197,15 @@ size_t BLI_path_join(char *__restrict dst, size_t dst_len, const char *path, ...
const char *BLI_path_basename(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
/**
* Get an element of the path at an index, eg:
- * "/some/path/file.txt" where an index of:
- * - 0 or -3: "some"
- * - 1 or -2: "path"
- * - 2 or -1: "file.txt"
+ * `/some/path/file.txt` where an index of:
+ * - 0 or -3: `some`
+ * - 1 or -2: `path`
+ * - 2 or -1: `file.txt`
*
- * Ignores multiple slashes at any point in the path (including start/end).
+ * Ignored elements in the path:
+ * - Multiple slashes at any point in the path (including start/end).
+ * - Single '.' in the path: `/./` except for the beginning of the path
+ * where it's used to signify a $PWD relative path.
*/
bool BLI_path_name_at_index(const char *__restrict path,
int index,
@@ -134,7 +228,7 @@ const char *BLI_path_slash_rfind(const char *string) ATTR_NONNULL() ATTR_WARN_UN
* Appends a slash to string if there isn't one there already.
* Returns the new length of the string.
*/
-int BLI_path_slash_ensure(char *string) ATTR_NONNULL();
+int BLI_path_slash_ensure(char *string, size_t string_maxlen) ATTR_NONNULL(1);
/**
* Removes the last slash and everything after it to the end of string, if there is one.
*/
@@ -230,7 +324,7 @@ void BLI_path_normalize(const char *relabase, char *path) ATTR_NONNULL(2);
*
* \note Same as #BLI_path_normalize but adds a trailing slash.
*/
-void BLI_path_normalize_dir(const char *relabase, char *dir) ATTR_NONNULL(2);
+void BLI_path_normalize_dir(const char *relabase, char *dir, size_t dir_maxlen) ATTR_NONNULL(2);
/**
* Make given name safe to be used in paths.
@@ -273,6 +367,8 @@ bool BLI_path_make_safe(char *path) ATTR_NONNULL(1);
*
* Replaces path with the path of its parent directory, returning true if
* it was able to find a parent directory within the path.
+ *
+ * On success, the resulting path will always have a trailing slash.
*/
bool BLI_path_parent_dir(char *path) ATTR_NONNULL();
/**
@@ -365,8 +461,8 @@ void BLI_path_normalize_unc(char *path_16, int maxlen);
/**
* Appends a suffix to the string, fitting it before the extension
*
- * string = Foo.png, suffix = 123, separator = _
- * Foo.png -> Foo_123.png
+ * string = `Foo.png`, suffix = `123`, separator = `_`.
+ * `Foo.png` -> `Foo_123.png`.
*
* \param string: original (and final) string
* \param maxlen: Maximum length of string
diff --git a/source/blender/blenlib/BLI_probing_strategies.hh b/source/blender/blenlib/BLI_probing_strategies.hh
index 2c001270495..d11bed9208e 100644
--- a/source/blender/blenlib/BLI_probing_strategies.hh
+++ b/source/blender/blenlib/BLI_probing_strategies.hh
@@ -223,7 +223,7 @@ using DefaultProbingStrategy = PythonProbingStrategy<>;
int64_t linear_offset = 0; \
uint64_t current_hash = probing_strategy.get(); \
do { \
- int64_t R_SLOT_INDEX = static_cast<int64_t>((current_hash + static_cast<uint64_t>(linear_offset)) & MASK);
+ int64_t R_SLOT_INDEX = int64_t((current_hash + uint64_t(linear_offset)) & MASK);
#define SLOT_PROBING_END() \
} while (++linear_offset < probing_strategy.linear_steps()); \
diff --git a/source/blender/blenlib/BLI_rand.hh b/source/blender/blenlib/BLI_rand.hh
index 2c4484bd63f..e4f35bef217 100644
--- a/source/blender/blenlib/BLI_rand.hh
+++ b/source/blender/blenlib/BLI_rand.hh
@@ -29,7 +29,7 @@ class RandomNumberGenerator {
void seed(uint32_t seed)
{
constexpr uint64_t lowseed = 0x330E;
- x_ = (static_cast<uint64_t>(seed) << 16) | lowseed;
+ x_ = (uint64_t(seed) << 16) | lowseed;
}
/**
@@ -40,13 +40,13 @@ class RandomNumberGenerator {
uint32_t get_uint32()
{
this->step();
- return static_cast<uint32_t>(x_ >> 17);
+ return uint32_t(x_ >> 17);
}
int32_t get_int32()
{
this->step();
- return static_cast<int32_t>(x_ >> 17);
+ return int32_t(x_ >> 17);
}
/**
@@ -63,7 +63,7 @@ class RandomNumberGenerator {
*/
double get_double()
{
- return (double)this->get_int32() / 0x80000000;
+ return double(this->get_int32()) / 0x80000000;
}
/**
diff --git a/source/blender/blenlib/BLI_resource_scope.hh b/source/blender/blenlib/BLI_resource_scope.hh
index 9826b694e16..d3f6d5e3f13 100644
--- a/source/blender/blenlib/BLI_resource_scope.hh
+++ b/source/blender/blenlib/BLI_resource_scope.hh
@@ -128,7 +128,7 @@ template<typename Func> inline void ResourceScope::add_destruct_call(Func func)
{
void *buffer = allocator_.allocate(sizeof(Func), alignof(Func));
new (buffer) Func(std::move(func));
- this->add(buffer, [](void *data) { (*(Func *)data)(); });
+ this->add(buffer, [](void *data) { (*static_cast<Func *>(data))(); });
}
/**
diff --git a/source/blender/blenlib/BLI_set.hh b/source/blender/blenlib/BLI_set.hh
index a1b6ad9754e..8fb618edeb6 100644
--- a/source/blender/blenlib/BLI_set.hh
+++ b/source/blender/blenlib/BLI_set.hh
@@ -493,6 +493,24 @@ class Set {
}
/**
+ * Remove all values for which the given predicate is true.
+ *
+ * This is similar to std::erase_if.
+ */
+ template<typename Predicate> void remove_if(Predicate &&predicate)
+ {
+ for (Slot &slot : slots_) {
+ if (slot.is_occupied()) {
+ const Key &key = *slot.key();
+ if (predicate(key)) {
+ slot.remove();
+ removed_slots_++;
+ }
+ }
+ }
+ }
+
+ /**
* Print common statistics like size and collision count. This is useful for debugging purposes.
*/
void print_stats(StringRef name = "") const
@@ -626,7 +644,7 @@ class Set {
max_load_factor_.compute_total_and_usable_slots(
SlotArray::inline_buffer_capacity(), min_usable_slots, &total_slots, &usable_slots);
BLI_assert(total_slots >= 1);
- const uint64_t new_slot_mask = static_cast<uint64_t>(total_slots) - 1;
+ const uint64_t new_slot_mask = uint64_t(total_slots) - 1;
/**
* Optimize the case when the set was empty beforehand. We can avoid some copies here.
@@ -854,7 +872,7 @@ template<typename Key> class StdUnorderedSetWrapper {
public:
int64_t size() const
{
- return static_cast<int64_t>(set_.size());
+ return int64_t(set_.size());
}
bool is_empty() const
@@ -899,7 +917,7 @@ template<typename Key> class StdUnorderedSetWrapper {
bool remove(const Key &key)
{
- return (bool)set_.erase(key);
+ return bool(set_.erase(key));
}
void remove_contained(const Key &key)
diff --git a/source/blender/blenlib/BLI_set_slots.hh b/source/blender/blenlib/BLI_set_slots.hh
index 805c194ac90..8ef49e0a2d0 100644
--- a/source/blender/blenlib/BLI_set_slots.hh
+++ b/source/blender/blenlib/BLI_set_slots.hh
@@ -129,7 +129,7 @@ template<typename Key> class SimpleSetSlot {
* key. The hash is used by other slot implementations to determine inequality faster.
*/
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t UNUSED(hash)) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t /*hash*/) const
{
if (state_ == Occupied) {
return is_equal(key, *key_buffer_);
@@ -141,7 +141,7 @@ template<typename Key> class SimpleSetSlot {
* Change the state of this slot from empty/removed to occupied. The key has to be constructed
* by calling the constructor with the given key as parameter.
*/
- template<typename ForwardKey> void occupy(ForwardKey &&key, uint64_t UNUSED(hash))
+ template<typename ForwardKey> void occupy(ForwardKey &&key, uint64_t /*hash*/)
{
BLI_assert(!this->is_occupied());
new (&key_buffer_) Key(std::forward<ForwardKey>(key));
@@ -226,7 +226,7 @@ template<typename Key> class HashedSetSlot {
return state_ == Empty;
}
- template<typename Hash> uint64_t get_hash(const Hash &UNUSED(hash)) const
+ template<typename Hash> uint64_t get_hash(const Hash & /*hash*/) const
{
BLI_assert(this->is_occupied());
return hash_;
@@ -306,13 +306,13 @@ template<typename Key, typename KeyInfo> class IntrusiveSetSlot {
}
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint64_t UNUSED(hash)) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint64_t /*hash*/) const
{
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
return is_equal(key_, key);
}
- template<typename ForwardKey> void occupy(ForwardKey &&key, const uint64_t UNUSED(hash))
+ template<typename ForwardKey> void occupy(ForwardKey &&key, const uint64_t /*hash*/)
{
BLI_assert(!this->is_occupied());
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
diff --git a/source/blender/blenlib/BLI_span.hh b/source/blender/blenlib/BLI_span.hh
index 0f3fcea1270..adfccd8d6fe 100644
--- a/source/blender/blenlib/BLI_span.hh
+++ b/source/blender/blenlib/BLI_span.hh
@@ -112,13 +112,11 @@ template<typename T> class Span {
* Span<int> span = {1, 2, 3, 4};
* call_function_with_array(span);
*/
- constexpr Span(const std::initializer_list<T> &list)
- : Span(list.begin(), static_cast<int64_t>(list.size()))
+ constexpr Span(const std::initializer_list<T> &list) : Span(list.begin(), int64_t(list.size()))
{
}
- constexpr Span(const std::vector<T> &vector)
- : Span(vector.data(), static_cast<int64_t>(vector.size()))
+ constexpr Span(const std::vector<T> &vector) : Span(vector.data(), int64_t(vector.size()))
{
}
@@ -718,7 +716,7 @@ template<typename T> class MutableSpan {
{
BLI_assert((size_ * sizeof(T)) % sizeof(NewT) == 0);
int64_t new_size = size_ * sizeof(T) / sizeof(NewT);
- return MutableSpan<NewT>((NewT *)data_, new_size);
+ return MutableSpan<NewT>(reinterpret_cast<NewT *>(data_), new_size);
}
};
diff --git a/source/blender/blenlib/BLI_strict_flags.h b/source/blender/blenlib/BLI_strict_flags.h
index 8489871d5da..cc5b5dce363 100644
--- a/source/blender/blenlib/BLI_strict_flags.h
+++ b/source/blender/blenlib/BLI_strict_flags.h
@@ -9,16 +9,12 @@
*/
#ifdef __GNUC__
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 /* gcc4.6+ only */
+/* NOTE(@campbellbarton): CLANG behaves slightly differently to GCC,
+ * these can be enabled but do so carefully as they can introduce build-errors. */
+# if !defined(__clang__)
# pragma GCC diagnostic error "-Wsign-compare"
-# endif
-# if __GNUC__ >= 6 /* gcc6+ only */
# pragma GCC diagnostic error "-Wconversion"
-# endif
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 408
-/* gcc4.8+ only (behavior changed to ignore globals). */
# pragma GCC diagnostic error "-Wshadow"
-/* older gcc changed behavior with ternary */
# pragma GCC diagnostic error "-Wsign-conversion"
# endif
/* pedantic gives too many issues, developers can define this for own use */
diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h
index 15926e8f2d2..ed15e0871b9 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -206,6 +206,14 @@ char *BLI_sprintfN(const char *__restrict format, ...) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1, 2);
/**
+ * A wrapper around `::sprintf()` which does not generate security warnings.
+ *
+ * \note Use #BLI_snprintf for cases when the string size is known.
+ */
+int BLI_sprintf(char *__restrict str, const char *__restrict format, ...) ATTR_NONNULL(1, 2)
+ ATTR_PRINTF_FORMAT(2, 3);
+
+/**
* This roughly matches C and Python's string escaping with double quotes - `"`.
*
* Since every character may need escaping,
@@ -309,6 +317,28 @@ void BLI_str_format_byte_unit(char dst[15], long long int bytes, bool base_10) A
*/
void BLI_str_format_decimal_unit(char dst[7], int number_to_format) ATTR_NONNULL();
/**
+ * Format a count to up to 3 places (plus minus sign, plus '\0' terminator) string using long
+ * number names abbreviations. Used to produce a compact representation of large numbers as
+ * integers.
+ *
+ * It shows a lower bound instead of rounding the number.
+ *
+ * 1 -> 1
+ * 15 -> 15
+ * 155 -> 155
+ * 1555 -> 1K
+ * 15555 -> 15K
+ * 155555 -> .1M
+ * 1555555 -> 1M
+ * 15555555 -> 15M
+ * 155555555 -> .1B
+ * 1000000000 -> 1B
+ * ...
+ *
+ * Length of 5 is the maximum of the resulting string, for example, `-15K\0`.
+ */
+void BLI_str_format_integer_unit(char dst[5], int number_to_format) ATTR_NONNULL();
+/**
* Compare two strings without regard to case.
*
* \retval True if the strings are equal, false otherwise.
diff --git a/source/blender/blenlib/BLI_string_cursor_utf8.h b/source/blender/blenlib/BLI_string_cursor_utf8.h
index 70ba5da8e5a..9c0589b230a 100644
--- a/source/blender/blenlib/BLI_string_cursor_utf8.h
+++ b/source/blender/blenlib/BLI_string_cursor_utf8.h
@@ -25,6 +25,9 @@ typedef enum eStrCursorJumpDirection {
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);
+bool BLI_str_cursor_step_next_utf32(const char32_t *str, size_t maxlen, int *pos);
+bool BLI_str_cursor_step_prev_utf32(const char32_t *str, size_t maxlen, int *pos);
+
void BLI_str_cursor_step_utf8(const char *str,
size_t maxlen,
int *pos,
diff --git a/source/blender/blenlib/BLI_string_ref.hh b/source/blender/blenlib/BLI_string_ref.hh
index 3823bd02630..14dee54d730 100644
--- a/source/blender/blenlib/BLI_string_ref.hh
+++ b/source/blender/blenlib/BLI_string_ref.hh
@@ -178,12 +178,12 @@ constexpr StringRefBase::operator Span<char>() const
*/
inline StringRefBase::operator std::string() const
{
- return std::string(data_, static_cast<size_t>(size_));
+ return std::string(data_, size_t(size_));
}
constexpr StringRefBase::operator std::string_view() const
{
- return std::string_view(data_, static_cast<size_t>(size_));
+ return std::string_view(data_, size_t(size_));
}
constexpr const char *StringRefBase::begin() const
@@ -209,7 +209,7 @@ constexpr IndexRange StringRefBase::index_range() const
inline void StringRefBase::unsafe_copy(char *dst) const
{
if (size_ > 0) {
- memcpy(dst, data_, static_cast<size_t>(size_));
+ memcpy(dst, data_, size_t(size_));
}
dst[size_] = '\0';
}
@@ -308,86 +308,79 @@ constexpr int64_t index_or_npos_to_int64(size_t index)
if (index == std::string_view::npos) {
return StringRef::not_found;
}
- return static_cast<int64_t>(index);
+ return int64_t(index);
}
constexpr int64_t StringRefBase::find(char c, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(std::string_view(*this).find(c, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find(c, size_t(pos)));
}
constexpr int64_t StringRefBase::find(StringRef str, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(std::string_view(*this).find(str, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find(str, size_t(pos)));
}
constexpr int64_t StringRefBase::rfind(char c, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(std::string_view(*this).rfind(c, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).rfind(c, size_t(pos)));
}
constexpr int64_t StringRefBase::rfind(StringRef str, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(std::string_view(*this).rfind(str, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).rfind(str, size_t(pos)));
}
constexpr int64_t StringRefBase::find_first_of(StringRef chars, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(
- std::string_view(*this).find_first_of(chars, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find_first_of(chars, size_t(pos)));
}
constexpr int64_t StringRefBase::find_first_of(char c, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(
- std::string_view(*this).find_first_of(c, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find_first_of(c, size_t(pos)));
}
constexpr int64_t StringRefBase::find_last_of(StringRef chars, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(
- std::string_view(*this).find_last_of(chars, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find_last_of(chars, size_t(pos)));
}
constexpr int64_t StringRefBase::find_last_of(char c, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(std::string_view(*this).find_last_of(c, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find_last_of(c, size_t(pos)));
}
constexpr int64_t StringRefBase::find_first_not_of(StringRef chars, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(
- std::string_view(*this).find_first_not_of(chars, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find_first_not_of(chars, size_t(pos)));
}
constexpr int64_t StringRefBase::find_first_not_of(char c, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(
- std::string_view(*this).find_first_not_of(c, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find_first_not_of(c, size_t(pos)));
}
constexpr int64_t StringRefBase::find_last_not_of(StringRef chars, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(
- std::string_view(*this).find_last_not_of(chars, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find_last_not_of(chars, size_t(pos)));
}
constexpr int64_t StringRefBase::find_last_not_of(char c, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(
- std::string_view(*this).find_last_not_of(c, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find_last_not_of(c, size_t(pos)));
}
constexpr StringRef StringRefBase::trim() const
@@ -440,15 +433,14 @@ constexpr StringRefNull::StringRefNull() : StringRefBase("", 0)
constexpr StringRefNull::StringRefNull(const char *str, const int64_t size)
: StringRefBase(str, size)
{
- BLI_assert(static_cast<int64_t>(strlen(str)) == size);
+ BLI_assert(int64_t(strlen(str)) == size);
}
/**
* Construct a StringRefNull from a null terminated c-string. The pointer must not point to
* NULL.
*/
-inline StringRefNull::StringRefNull(const char *str)
- : StringRefBase(str, static_cast<int64_t>(strlen(str)))
+inline StringRefNull::StringRefNull(const char *str) : StringRefBase(str, int64_t(strlen(str)))
{
BLI_assert(str != nullptr);
BLI_assert(data_[size_] == '\0');
@@ -504,7 +496,7 @@ constexpr StringRef::StringRef(StringRefNull other) : StringRefBase(other.data()
* Create a StringRef from a null-terminated c-string.
*/
constexpr StringRef::StringRef(const char *str)
- : StringRefBase(str, str ? static_cast<int64_t>(std::char_traits<char>::length(str)) : 0)
+ : StringRefBase(str, str ? int64_t(std::char_traits<char>::length(str)) : 0)
{
}
@@ -560,7 +552,7 @@ constexpr char StringRef::operator[](int64_t index) const
* second point points to a smaller address than the first one.
*/
constexpr StringRef::StringRef(const char *begin, const char *one_after_end)
- : StringRefBase(begin, static_cast<int64_t>(one_after_end - begin))
+ : StringRefBase(begin, int64_t(one_after_end - begin))
{
BLI_assert(begin <= one_after_end);
}
@@ -570,12 +562,12 @@ constexpr StringRef::StringRef(const char *begin, const char *one_after_end)
* will point to uninitialized memory.
*/
inline StringRef::StringRef(const std::string &str)
- : StringRefBase(str.data(), static_cast<int64_t>(str.size()))
+ : StringRefBase(str.data(), int64_t(str.size()))
{
}
constexpr StringRef::StringRef(std::string_view view)
- : StringRefBase(view.data(), static_cast<int64_t>(view.size()))
+ : StringRefBase(view.data(), int64_t(view.size()))
{
}
@@ -593,7 +585,7 @@ inline std::ostream &operator<<(std::ostream &stream, StringRef ref)
inline std::ostream &operator<<(std::ostream &stream, StringRefNull ref)
{
- stream << std::string(ref.data(), (size_t)ref.size());
+ stream << std::string(ref.data(), size_t(ref.size()));
return stream;
}
@@ -619,7 +611,7 @@ constexpr bool operator==(StringRef a, StringRef b)
/* This also avoids passing null to the call below, which would results in an ASAN warning. */
return true;
}
- return STREQLEN(a.data(), b.data(), (size_t)a.size());
+ return STREQLEN(a.data(), b.data(), size_t(a.size()));
}
constexpr bool operator!=(StringRef a, StringRef b)
diff --git a/source/blender/blenlib/BLI_string_utils.h b/source/blender/blenlib/BLI_string_utils.h
index df82e94ae2e..936e892a9e2 100644
--- a/source/blender/blenlib/BLI_string_utils.h
+++ b/source/blender/blenlib/BLI_string_utils.h
@@ -48,33 +48,6 @@ void BLI_string_split_suffix(const char *string, char *r_body, char *r_suf, size
void BLI_string_split_prefix(const char *string, char *r_pre, char *r_body, size_t str_len);
/**
- * Join strings, return newly allocated string.
- */
-char *BLI_string_join_array(char *result,
- size_t result_len,
- const char *strings[],
- uint strings_len) ATTR_NONNULL();
-/**
- * A version of #BLI_string_join that takes a separator which can be any character including '\0'.
- */
-char *BLI_string_join_array_by_sep_char(char *result,
- size_t result_len,
- char sep,
- const char *strings[],
- uint strings_len) ATTR_NONNULL();
-
-/**
- * Join an array of strings into a newly allocated, null terminated string.
- */
-char *BLI_string_join_arrayN(const char *strings[], uint strings_len) ATTR_WARN_UNUSED_RESULT
- ATTR_NONNULL();
-/**
- * A version of #BLI_string_joinN that takes a separator which can be any character including '\0'.
- */
-char *BLI_string_join_array_by_sep_charN(char sep,
- const char *strings[],
- uint strings_len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-/**
* A version of #BLI_string_join_array_by_sep_charN that takes a table array.
* The new location of each string is written into this array.
*/
@@ -82,17 +55,7 @@ char *BLI_string_join_array_by_sep_char_with_tableN(char sep,
char *table[],
const char *strings[],
uint strings_len) ATTR_NONNULL();
-/**
- * Take multiple arguments, pass as (array, length).
- */
-#define BLI_string_join(result, result_len, ...) \
- BLI_string_join_array( \
- result, result_len, ((const char *[]){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__))
-#define BLI_string_joinN(...) \
- BLI_string_join_arrayN(((const char *[]){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__))
-#define BLI_string_join_by_sep_charN(sep, ...) \
- BLI_string_join_array_by_sep_charN( \
- sep, ((const char *[]){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__))
+
#define BLI_string_join_by_sep_char_with_tableN(sep, table, ...) \
BLI_string_join_array_by_sep_char_with_tableN( \
sep, table, ((const char *[]){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__))
@@ -149,6 +112,360 @@ bool BLI_uniquename(struct ListBase *list,
int name_offset,
size_t name_len);
+/* Expand array functions. */
+
+/* Intentionally no comma after `_BLI_STRING_ARGS_0` to allow it to be empty. */
+#define _BLI_STRING_ARGS_1 _BLI_STRING_ARGS_0 const char *a
+#define _BLI_STRING_ARGS_2 _BLI_STRING_ARGS_1, const char *b
+#define _BLI_STRING_ARGS_3 _BLI_STRING_ARGS_2, const char *c
+#define _BLI_STRING_ARGS_4 _BLI_STRING_ARGS_3, const char *d
+#define _BLI_STRING_ARGS_5 _BLI_STRING_ARGS_4, const char *e
+#define _BLI_STRING_ARGS_6 _BLI_STRING_ARGS_5, const char *f
+#define _BLI_STRING_ARGS_7 _BLI_STRING_ARGS_6, const char *g
+#define _BLI_STRING_ARGS_8 _BLI_STRING_ARGS_7, const char *h
+#define _BLI_STRING_ARGS_9 _BLI_STRING_ARGS_8, const char *i
+#define _BLI_STRING_ARGS_10 _BLI_STRING_ARGS_9, const char *j
+
+/* ------------------------------------------------------------------------- */
+/** \name Implement: `BLI_string_join(..)`
+ * \{ */
+
+#define _BLI_STRING_ARGS_0 char *__restrict dst, const size_t dst_len,
+
+/**
+ * Join strings, return the length of the resulting string.
+ */
+size_t BLI_string_join_array(char *result,
+ size_t result_len,
+ const char *strings[],
+ uint strings_len) ATTR_NONNULL();
+
+#define BLI_string_join(...) VA_NARGS_CALL_OVERLOAD(_BLI_string_join_, __VA_ARGS__)
+
+BLI_INLINE size_t _BLI_string_join_3(_BLI_STRING_ARGS_1) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_4(_BLI_STRING_ARGS_2) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_5(_BLI_STRING_ARGS_3) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_6(_BLI_STRING_ARGS_4) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_7(_BLI_STRING_ARGS_5) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_8(_BLI_STRING_ARGS_6) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_9(_BLI_STRING_ARGS_7) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_10(_BLI_STRING_ARGS_8) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_11(_BLI_STRING_ARGS_9) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_12(_BLI_STRING_ARGS_10) ATTR_NONNULL();
+
+BLI_INLINE size_t _BLI_string_join_3(_BLI_STRING_ARGS_1)
+{
+ const char *string_array[] = {a};
+ return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_4(_BLI_STRING_ARGS_2)
+{
+ const char *string_array[] = {a, b};
+ return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_5(_BLI_STRING_ARGS_3)
+{
+ const char *string_array[] = {a, b, c};
+ return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_6(_BLI_STRING_ARGS_4)
+{
+ const char *string_array[] = {a, b, c, d};
+ return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_7(_BLI_STRING_ARGS_5)
+{
+ const char *string_array[] = {a, b, c, d, e};
+ return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_8(_BLI_STRING_ARGS_6)
+{
+ const char *string_array[] = {a, b, c, d, e, f};
+ return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_9(_BLI_STRING_ARGS_7)
+{
+ const char *string_array[] = {a, b, c, d, e, f, g};
+ return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_10(_BLI_STRING_ARGS_8)
+{
+ const char *string_array[] = {a, b, c, d, e, f, g, h};
+ return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_11(_BLI_STRING_ARGS_9)
+{
+ const char *string_array[] = {a, b, c, d, e, f, g, h, i};
+ return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_12(_BLI_STRING_ARGS_10)
+{
+ const char *string_array[] = {a, b, c, d, e, f, g, h, i, j};
+ return BLI_string_join_array(dst, dst_len, string_array, ARRAY_SIZE(string_array));
+}
+
+#undef _BLI_STRING_ARGS_0
+
+/** \} */
+
+/* ------------------------------------------------------------------------- */
+/** \name Implement: `BLI_string_joinN(..)`
+ * \{ */
+
+/**
+ * Join an array of strings into a newly allocated, null terminated string.
+ */
+char *BLI_string_join_arrayN(const char *strings[], uint strings_len) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+
+#define BLI_string_joinN(...) VA_NARGS_CALL_OVERLOAD(_BLI_string_joinN_, __VA_ARGS__)
+
+#define _BLI_STRING_ARGS_0
+
+BLI_INLINE char *_BLI_string_joinN_1(_BLI_STRING_ARGS_1) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_joinN_2(_BLI_STRING_ARGS_2) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_joinN_3(_BLI_STRING_ARGS_3) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_joinN_4(_BLI_STRING_ARGS_4) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_joinN_5(_BLI_STRING_ARGS_5) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_joinN_6(_BLI_STRING_ARGS_6) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_joinN_7(_BLI_STRING_ARGS_7) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_joinN_8(_BLI_STRING_ARGS_8) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_joinN_9(_BLI_STRING_ARGS_9) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_joinN_10(_BLI_STRING_ARGS_10) ATTR_NONNULL();
+
+BLI_INLINE char *_BLI_string_joinN_1(_BLI_STRING_ARGS_1)
+{
+ const char *string_array[] = {a};
+ return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_joinN_2(_BLI_STRING_ARGS_2)
+{
+ const char *string_array[] = {a, b};
+ return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_joinN_3(_BLI_STRING_ARGS_3)
+{
+ const char *string_array[] = {a, b, c};
+ return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_joinN_4(_BLI_STRING_ARGS_4)
+{
+ const char *string_array[] = {a, b, c, d};
+ return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_joinN_5(_BLI_STRING_ARGS_5)
+{
+ const char *string_array[] = {a, b, c, d, e};
+ return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_joinN_6(_BLI_STRING_ARGS_6)
+{
+ const char *string_array[] = {a, b, c, d, e, f};
+ return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_joinN_7(_BLI_STRING_ARGS_7)
+{
+ const char *string_array[] = {a, b, c, d, e, f, g};
+ return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_joinN_8(_BLI_STRING_ARGS_8)
+{
+ const char *string_array[] = {a, b, c, d, e, f, g, h};
+ return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_joinN_9(_BLI_STRING_ARGS_9)
+{
+ const char *string_array[] = {a, b, c, d, e, f, g, h, i};
+ return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_joinN_10(_BLI_STRING_ARGS_10)
+{
+ const char *string_array[] = {a, b, c, d, e, f, g, h, i, j};
+ return BLI_string_join_arrayN(string_array, ARRAY_SIZE(string_array));
+}
+
+#undef _BLI_STRING_ARGS_0
+
+/** \} */
+
+/* ------------------------------------------------------------------------- */
+/** \name Implement: `BLI_string_join_by_sep_char(..)`
+ * \{ */
+
+/**
+ * A version of #BLI_string_join_array that takes a separator which can be any character
+ * including '\0'.
+ */
+size_t BLI_string_join_array_by_sep_char(char *result,
+ size_t result_len,
+ char sep,
+ const char *strings[],
+ uint strings_len) ATTR_NONNULL();
+
+#define BLI_string_join_by_sep_char(...) \
+ VA_NARGS_CALL_OVERLOAD(_BLI_string_join_by_sep_char_, __VA_ARGS__)
+
+#define _BLI_STRING_ARGS_0 char *__restrict dst, const size_t dst_len, const char sep,
+
+BLI_INLINE size_t _BLI_string_join_by_sep_char_4(_BLI_STRING_ARGS_1) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_by_sep_char_5(_BLI_STRING_ARGS_2) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_by_sep_char_6(_BLI_STRING_ARGS_3) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_by_sep_char_7(_BLI_STRING_ARGS_4) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_by_sep_char_8(_BLI_STRING_ARGS_5) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_by_sep_char_9(_BLI_STRING_ARGS_6) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_by_sep_char_10(_BLI_STRING_ARGS_7) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_by_sep_char_11(_BLI_STRING_ARGS_8) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_by_sep_char_12(_BLI_STRING_ARGS_9) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_string_join_by_sep_char_13(_BLI_STRING_ARGS_10) ATTR_NONNULL();
+
+BLI_INLINE size_t _BLI_string_join_by_sep_char_4(_BLI_STRING_ARGS_1)
+{
+ const char *string_array[] = {a};
+ return BLI_string_join_array_by_sep_char(
+ dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_by_sep_char_5(_BLI_STRING_ARGS_2)
+{
+ const char *string_array[] = {a, b};
+ return BLI_string_join_array_by_sep_char(
+ dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_by_sep_char_6(_BLI_STRING_ARGS_3)
+{
+ const char *string_array[] = {a, b, c};
+ return BLI_string_join_array_by_sep_char(
+ dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_by_sep_char_7(_BLI_STRING_ARGS_4)
+{
+ const char *string_array[] = {a, b, c, d};
+ return BLI_string_join_array_by_sep_char(
+ dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_by_sep_char_8(_BLI_STRING_ARGS_5)
+{
+ const char *string_array[] = {a, b, c, d, e};
+ return BLI_string_join_array_by_sep_char(
+ dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_by_sep_char_9(_BLI_STRING_ARGS_6)
+{
+ const char *string_array[] = {a, b, c, d, e, f};
+ return BLI_string_join_array_by_sep_char(
+ dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_by_sep_char_10(_BLI_STRING_ARGS_7)
+{
+ const char *string_array[] = {a, b, c, d, e, f, g};
+ return BLI_string_join_array_by_sep_char(
+ dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_by_sep_char_11(_BLI_STRING_ARGS_8)
+{
+ const char *string_array[] = {a, b, c, d, e, f, g, h};
+ return BLI_string_join_array_by_sep_char(
+ dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_by_sep_char_12(_BLI_STRING_ARGS_9)
+{
+ const char *string_array[] = {a, b, c, d, e, f, g, h, i};
+ return BLI_string_join_array_by_sep_char(
+ dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE size_t _BLI_string_join_by_sep_char_13(_BLI_STRING_ARGS_10)
+{
+ const char *string_array[] = {a, b, c, d, e, f, g, h, i, j};
+ return BLI_string_join_array_by_sep_char(
+ dst, dst_len, sep, string_array, ARRAY_SIZE(string_array));
+}
+
+#undef _BLI_STRING_ARGS_0
+
+/** \} */
+
+/* ------------------------------------------------------------------------- */
+/** \name Implement: `BLI_string_join_by_sep_charN(..)`
+ * \{ */
+
+/**
+ * A version of #BLI_string_join_by_sep_char that takes a separator which can be any character
+ * including '\0'.
+ */
+char *BLI_string_join_array_by_sep_charN(char sep,
+ const char *strings[],
+ uint strings_len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+
+#define BLI_string_join_by_sep_charN(...) \
+ VA_NARGS_CALL_OVERLOAD(_BLI_string_join_by_sep_charN_, __VA_ARGS__)
+
+#define _BLI_STRING_ARGS_0 const char sep,
+
+BLI_INLINE char *_BLI_string_join_by_sep_charN_2(_BLI_STRING_ARGS_1) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_join_by_sep_charN_3(_BLI_STRING_ARGS_2) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_join_by_sep_charN_4(_BLI_STRING_ARGS_3) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_join_by_sep_charN_5(_BLI_STRING_ARGS_4) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_join_by_sep_charN_6(_BLI_STRING_ARGS_5) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_join_by_sep_charN_7(_BLI_STRING_ARGS_6) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_join_by_sep_charN_8(_BLI_STRING_ARGS_7) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_join_by_sep_charN_9(_BLI_STRING_ARGS_8) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_join_by_sep_charN_10(_BLI_STRING_ARGS_9) ATTR_NONNULL();
+BLI_INLINE char *_BLI_string_join_by_sep_charN_11(_BLI_STRING_ARGS_10) ATTR_NONNULL();
+
+BLI_INLINE char *_BLI_string_join_by_sep_charN_2(_BLI_STRING_ARGS_1)
+{
+ const char *string_array[] = {a};
+ return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_join_by_sep_charN_3(_BLI_STRING_ARGS_2)
+{
+ const char *string_array[] = {a, b};
+ return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_join_by_sep_charN_4(_BLI_STRING_ARGS_3)
+{
+ const char *string_array[] = {a, b, c};
+ return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_join_by_sep_charN_5(_BLI_STRING_ARGS_4)
+{
+ const char *string_array[] = {a, b, c, d};
+ return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_join_by_sep_charN_6(_BLI_STRING_ARGS_5)
+{
+ const char *string_array[] = {a, b, c, d, e};
+ return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_join_by_sep_charN_7(_BLI_STRING_ARGS_6)
+{
+ const char *string_array[] = {a, b, c, d, e, f};
+ return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_join_by_sep_charN_8(_BLI_STRING_ARGS_7)
+{
+ const char *string_array[] = {a, b, c, d, e, f, g};
+ return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_join_by_sep_charN_9(_BLI_STRING_ARGS_8)
+{
+ const char *string_array[] = {a, b, c, d, e, f, g, h};
+ return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_join_by_sep_charN_10(_BLI_STRING_ARGS_9)
+{
+ const char *string_array[] = {a, b, c, d, e, f, g, h, i};
+ return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
+}
+BLI_INLINE char *_BLI_string_join_by_sep_charN_11(_BLI_STRING_ARGS_10)
+{
+ const char *string_array[] = {a, b, c, d, e, f, g, h, i, j};
+ return BLI_string_join_array_by_sep_charN(sep, string_array, ARRAY_SIZE(string_array));
+}
+
+/** \} */
+
+#undef _BLI_STRING_ARGS_0
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_task.hh b/source/blender/blenlib/BLI_task.hh
index 33a781d3749..e7d9a21439a 100644
--- a/source/blender/blenlib/BLI_task.hh
+++ b/source/blender/blenlib/BLI_task.hh
@@ -31,6 +31,7 @@
#endif
#include "BLI_index_range.hh"
+#include "BLI_lazy_threading.hh"
#include "BLI_utildefines.h"
namespace blender::threading {
@@ -56,6 +57,7 @@ void parallel_for(IndexRange range, int64_t grain_size, const Function &function
#ifdef WITH_TBB
/* Invoking tbb for small workloads has a large overhead. */
if (range.size() >= grain_size) {
+ lazy_threading::send_hint();
tbb::parallel_for(
tbb::blocked_range<int64_t>(range.first(), range.one_after_last(), grain_size),
[&](const tbb::blocked_range<int64_t> &subrange) {
@@ -78,6 +80,7 @@ Value parallel_reduce(IndexRange range,
{
#ifdef WITH_TBB
if (range.size() >= grain_size) {
+ lazy_threading::send_hint();
return tbb::parallel_reduce(
tbb::blocked_range<int64_t>(range.first(), range.one_after_last(), grain_size),
identity,
@@ -114,6 +117,7 @@ template<typename... Functions>
void parallel_invoke(const bool use_threading, Functions &&...functions)
{
if (use_threading) {
+ lazy_threading::send_hint();
parallel_invoke(std::forward<Functions>(functions)...);
}
else {
@@ -125,6 +129,7 @@ void parallel_invoke(const bool use_threading, Functions &&...functions)
template<typename Function> void isolate_task(const Function &function)
{
#ifdef WITH_TBB
+ lazy_threading::ReceiverIsolation isolation;
tbb::this_task_arena::isolate(function);
#else
function();
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index 7f9470a9111..98177876f87 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -589,7 +589,7 @@ extern "C" {
/** Performs `offsetof(typeof(data), member) + sizeof((data)->member)` for non-gcc compilers. */
#define OFFSETOF_STRUCT_AFTER(_struct, _member) \
- ((((const char *)&((_struct)->_member)) - ((const char *)(_struct))) + \
+ ((size_t)(((const char *)&((_struct)->_member)) - ((const char *)(_struct))) + \
sizeof((_struct)->_member))
/**
@@ -786,24 +786,23 @@ extern bool BLI_memory_is_zero(const void *arr, size_t arr_size);
extern "C++" { \
inline constexpr _enum_type operator|(_enum_type a, _enum_type b) \
{ \
- return static_cast<_enum_type>(static_cast<uint64_t>(a) | static_cast<uint64_t>(b)); \
+ return (_enum_type)(uint64_t(a) | uint64_t(b)); \
} \
inline constexpr _enum_type operator&(_enum_type a, _enum_type b) \
{ \
- return static_cast<_enum_type>(static_cast<uint64_t>(a) & static_cast<uint64_t>(b)); \
+ return (_enum_type)(uint64_t(a) & uint64_t(b)); \
} \
inline constexpr _enum_type operator~(_enum_type a) \
{ \
- return static_cast<_enum_type>(~static_cast<uint64_t>(a) & \
- (2 * static_cast<uint64_t>(_max_enum_value) - 1)); \
+ return (_enum_type)(~uint64_t(a) & (2 * uint64_t(_max_enum_value) - 1)); \
} \
inline _enum_type &operator|=(_enum_type &a, _enum_type b) \
{ \
- return a = static_cast<_enum_type>(static_cast<uint64_t>(a) | static_cast<uint64_t>(b)); \
+ return a = (_enum_type)(uint64_t(a) | uint64_t(b)); \
} \
inline _enum_type &operator&=(_enum_type &a, _enum_type b) \
{ \
- return a = static_cast<_enum_type>(static_cast<uint64_t>(a) & static_cast<uint64_t>(b)); \
+ return a = (_enum_type)(uint64_t(a) & uint64_t(b)); \
} \
} /* extern "C++" */
diff --git a/source/blender/blenlib/BLI_uvproject.h b/source/blender/blenlib/BLI_uvproject.h
index 75f39de6b7f..a94fd796121 100644
--- a/source/blender/blenlib/BLI_uvproject.h
+++ b/source/blender/blenlib/BLI_uvproject.h
@@ -15,7 +15,7 @@ struct ProjCameraInfo;
/**
* Create UV info from the camera, needs to be freed.
*
- * \param rotmat: can be `obedit->obmat` when uv project is used.
+ * \param rotmat: can be `obedit->object_to_world` when uv project is used.
* \param winx, winy: can be from `scene->r.xsch / ysch`.
*/
struct ProjCameraInfo *BLI_uvproject_camera_info(struct Object *ob,
diff --git a/source/blender/blenlib/BLI_vector.hh b/source/blender/blenlib/BLI_vector.hh
index 1f5f97d754d..cba58945546 100644
--- a/source/blender/blenlib/BLI_vector.hh
+++ b/source/blender/blenlib/BLI_vector.hh
@@ -96,8 +96,7 @@ class Vector {
*/
#ifndef NDEBUG
int64_t debug_size_;
-# define UPDATE_VECTOR_SIZE(ptr) \
- (ptr)->debug_size_ = static_cast<int64_t>((ptr)->end_ - (ptr)->begin_)
+# define UPDATE_VECTOR_SIZE(ptr) (ptr)->debug_size_ = int64_t((ptr)->end_ - (ptr)->begin_)
#else
# define UPDATE_VECTOR_SIZE(ptr) ((void)0)
#endif
@@ -244,7 +243,7 @@ class Vector {
/* Copy from inline buffer to newly allocated buffer. */
const int64_t capacity = size;
begin_ = static_cast<T *>(
- allocator_.allocate(sizeof(T) * static_cast<size_t>(capacity), alignof(T), AT));
+ allocator_.allocate(sizeof(T) * size_t(capacity), alignof(T), AT));
capacity_end_ = begin_ + capacity;
uninitialized_relocate_n(other.begin_, size, begin_);
end_ = begin_ + size;
@@ -693,7 +692,7 @@ class Vector {
*/
int64_t size() const
{
- const int64_t current_size = static_cast<int64_t>(end_ - begin_);
+ const int64_t current_size = int64_t(end_ - begin_);
BLI_assert(debug_size_ == current_size);
return current_size;
}
@@ -806,6 +805,17 @@ class Vector {
}
/**
+ * Remove all values for which the given predicate is true.
+ *
+ * This is similar to std::erase_if.
+ */
+ template<typename Predicate> void remove_if(Predicate &&predicate)
+ {
+ end_ = std::remove_if(this->begin(), this->end(), predicate);
+ UPDATE_VECTOR_SIZE(this);
+ }
+
+ /**
* Do a linear search to find the value in the vector.
* When found, return the first index, otherwise return -1.
*/
@@ -813,7 +823,7 @@ class Vector {
{
for (const T *current = begin_; current != end_; current++) {
if (*current == value) {
- return static_cast<int64_t>(current - begin_);
+ return int64_t(current - begin_);
}
}
return -1;
@@ -905,7 +915,7 @@ class Vector {
*/
int64_t capacity() const
{
- return static_cast<int64_t>(capacity_end_ - begin_);
+ return int64_t(capacity_end_ - begin_);
}
/**
@@ -975,7 +985,7 @@ class Vector {
const int64_t size = this->size();
T *new_array = static_cast<T *>(
- allocator_.allocate(static_cast<size_t>(new_capacity) * sizeof(T), alignof(T), AT));
+ allocator_.allocate(size_t(new_capacity) * sizeof(T), alignof(T), AT));
try {
uninitialized_relocate_n(begin_, size, new_array);
}
diff --git a/source/blender/blenlib/BLI_vector_adaptor.hh b/source/blender/blenlib/BLI_vector_adaptor.hh
deleted file mode 100644
index 82d731aacd8..00000000000
--- a/source/blender/blenlib/BLI_vector_adaptor.hh
+++ /dev/null
@@ -1,88 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#pragma once
-
-/** \file
- * \ingroup bli
- *
- * A `blender::VectorAdaptor` is a container with a fixed maximum size and does not own the
- * underlying memory. When an adaptor is constructed, you have to provide it with an uninitialized
- * array that will be filled when elements are added to the vector. The vector adaptor is not able
- * to grow. Therefore, it is undefined behavior to add more elements than fit into the provided
- * buffer.
- */
-
-#include "BLI_span.hh"
-
-namespace blender {
-
-template<typename T> class VectorAdaptor {
- private:
- T *begin_;
- T *end_;
- T *capacity_end_;
-
- public:
- VectorAdaptor() : begin_(nullptr), end_(nullptr), capacity_end_(nullptr)
- {
- }
-
- VectorAdaptor(T *data, int64_t capacity, int64_t size = 0)
- : begin_(data), end_(data + size), capacity_end_(data + capacity)
- {
- }
-
- VectorAdaptor(MutableSpan<T> span) : VectorAdaptor(span.data(), span.size(), 0)
- {
- }
-
- void append(const T &value)
- {
- BLI_assert(end_ < capacity_end_);
- new (end_) T(value);
- end_++;
- }
-
- void append(T &&value)
- {
- BLI_assert(end_ < capacity_end_);
- new (end_) T(std::move(value));
- end_++;
- }
-
- void append_n_times(const T &value, int64_t n)
- {
- BLI_assert(end_ + n <= capacity_end_);
- uninitialized_fill_n(end_, n, value);
- end_ += n;
- }
-
- void extend(Span<T> values)
- {
- BLI_assert(end_ + values.size() <= capacity_end_);
- uninitialized_copy_n(values.data(), values.size(), end_);
- end_ += values.size();
- }
-
- int64_t capacity() const
- {
- return capacity_end_ - begin_;
- }
-
- int64_t size() const
- {
- return end_ - begin_;
- }
-
- bool is_empty() const
- {
- return begin_ == end_;
- }
-
- bool is_full() const
- {
- return end_ == capacity_end_;
- }
-};
-
-} // namespace blender
diff --git a/source/blender/blenlib/BLI_vector_set.hh b/source/blender/blenlib/BLI_vector_set.hh
index 1a42e776d3d..d182e1f1678 100644
--- a/source/blender/blenlib/BLI_vector_set.hh
+++ b/source/blender/blenlib/BLI_vector_set.hh
@@ -349,6 +349,25 @@ class VectorSet {
}
/**
+ * Remove all values for which the given predicate is true. This may change the order of elements
+ * in the vector.
+ *
+ * This is similar to std::erase_if.
+ */
+ template<typename Predicate> void remove_if(Predicate &&predicate)
+ {
+ for (Slot &slot : slots_) {
+ if (slot.is_occupied()) {
+ const int64_t index = slot.index();
+ const Key &key = keys_[index];
+ if (predicate(key)) {
+ this->remove_key_internal(slot);
+ }
+ }
+ }
+ }
+
+ /**
* Delete and return a key from the set. This will remove the last element in the vector. The
* order of the remaining elements in the set is not changed.
*/
@@ -513,7 +532,7 @@ class VectorSet {
*/
int64_t size_in_bytes() const
{
- return static_cast<int64_t>(sizeof(Slot) * slots_.size() + sizeof(Key) * usable_slots_);
+ return int64_t(sizeof(Slot) * slots_.size() + sizeof(Key) * usable_slots_);
}
/**
@@ -557,7 +576,7 @@ class VectorSet {
max_load_factor_.compute_total_and_usable_slots(
SlotArray::inline_buffer_capacity(), min_usable_slots, &total_slots, &usable_slots);
BLI_assert(total_slots >= 1);
- const uint64_t new_slot_mask = static_cast<uint64_t>(total_slots) - 1;
+ const uint64_t new_slot_mask = uint64_t(total_slots) - 1;
/* Optimize the case when the set was empty beforehand. We can avoid some copies here. */
if (this->size() == 0) {
@@ -839,7 +858,7 @@ class VectorSet {
Key *allocate_keys_array(const int64_t size)
{
return static_cast<Key *>(
- slots_.allocator().allocate(sizeof(Key) * static_cast<size_t>(size), alignof(Key), AT));
+ slots_.allocator().allocate(sizeof(Key) * size_t(size), alignof(Key), AT));
}
void deallocate_keys_array(Key *keys)
diff --git a/source/blender/blenlib/BLI_vector_set_slots.hh b/source/blender/blenlib/BLI_vector_set_slots.hh
index 35dedd57705..cc7f5d1ff1e 100644
--- a/source/blender/blenlib/BLI_vector_set_slots.hh
+++ b/source/blender/blenlib/BLI_vector_set_slots.hh
@@ -73,7 +73,7 @@ template<typename Key> class SimpleVectorSetSlot {
template<typename ForwardKey, typename IsEqual>
bool contains(const ForwardKey &key,
const IsEqual &is_equal,
- uint64_t UNUSED(hash),
+ uint64_t /*hash*/,
const Key *keys) const
{
if (state_ >= 0) {
@@ -86,7 +86,7 @@ template<typename Key> class SimpleVectorSetSlot {
* Change the state of this slot from empty/removed to occupied. The hash can be used by other
* slot implementations.
*/
- void occupy(int64_t index, uint64_t UNUSED(hash))
+ void occupy(int64_t index, uint64_t /*hash*/)
{
BLI_assert(!this->is_occupied());
state_ = index;
diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh
index 19ee2334bd9..36f5065c022 100644
--- a/source/blender/blenlib/BLI_virtual_array.hh
+++ b/source/blender/blenlib/BLI_virtual_array.hh
@@ -155,7 +155,7 @@ template<typename T> class VArrayImpl {
* arrays in all cases.
* Return true when the virtual array was assigned and false when nothing was done.
*/
- virtual bool try_assign_GVArray(GVArray &UNUSED(varray)) const
+ virtual bool try_assign_GVArray(GVArray & /*varray*/) const
{
return false;
}
@@ -164,7 +164,7 @@ template<typename T> class VArrayImpl {
* Return true when the other virtual array should be considered to be the same, e.g. because it
* shares the same underlying memory.
*/
- virtual bool is_same(const VArrayImpl<T> &UNUSED(other)) const
+ virtual bool is_same(const VArrayImpl<T> & /*other*/) const
{
return false;
}
@@ -201,7 +201,7 @@ template<typename T> class VMutableArrayImpl : public VArrayImpl<T> {
/**
* Similar to #VArrayImpl::try_assign_GVArray but for mutable virtual arrays.
*/
- virtual bool try_assign_GVMutableArray(GVMutableArray &UNUSED(varray)) const
+ virtual bool try_assign_GVMutableArray(GVMutableArray & /*varray*/) const
{
return false;
}
@@ -324,7 +324,7 @@ class VArrayImpl_For_ArrayContainer : public VArrayImpl_For_Span<T> {
public:
VArrayImpl_For_ArrayContainer(Container container)
- : VArrayImpl_For_Span<T>((int64_t)container.size()), container_(std::move(container))
+ : VArrayImpl_For_Span<T>(int64_t(container.size())), container_(std::move(container))
{
this->data_ = const_cast<T *>(container_.data());
}
@@ -346,7 +346,7 @@ template<typename T> class VArrayImpl_For_Single final : public VArrayImpl<T> {
}
protected:
- T get(const int64_t UNUSED(index)) const override
+ T get(const int64_t /*index*/) const override
{
return value_;
}
diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h
index 7201e1bb4a1..34f1b1a68f1 100644
--- a/source/blender/blenlib/BLI_winstuff.h
+++ b/source/blender/blenlib/BLI_winstuff.h
@@ -48,11 +48,6 @@ extern "C" {
# define S_ISDIR(x) (((x)&_S_IFDIR) == _S_IFDIR)
#endif
-/* Defines for using ISO C++ conferment names. */
-#if !defined(_MSC_VER) || _MSC_VER < 1900
-# define snprintf _snprintf
-#endif
-
#if defined(_MSC_VER)
# define R_OK 4
# define W_OK 2
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 4a635e34205..693a4d98675 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -7,6 +7,7 @@ endif()
set(INC
.
+ ..
# ../blenkernel # don't add this back!
../makesdna
../../../intern/atomic
@@ -47,11 +48,13 @@ set(SRC
intern/array_store.c
intern/array_store_utils.c
intern/array_utils.c
+ intern/array_utils.cc
intern/astar.c
intern/bitmap.c
intern/bitmap_draw_2d.c
intern/boxpack_2d.c
intern/buffer.c
+ intern/cache_mutex.cc
intern/compute_context.cc
intern/convexhull_2d.c
intern/cpp_type.cc
@@ -83,6 +86,7 @@ set(SRC
intern/kdtree_3d.c
intern/kdtree_4d.c
intern/lasso_2d.c
+ intern/lazy_threading.cc
intern/length_parameterize.cc
intern/listbase.c
intern/math_base.c
@@ -164,16 +168,18 @@ set(SRC
BLI_array_store.h
BLI_array_store_utils.h
BLI_array_utils.h
+ BLI_array_utils.hh
BLI_asan.h
BLI_assert.h
BLI_astar.h
+ BLI_bit_vector.hh
BLI_bitmap.h
BLI_bitmap_draw_2d.h
- BLI_bit_vector.hh
BLI_blenlib.h
BLI_bounds.hh
BLI_boxpack_2d.h
BLI_buffer.h
+ BLI_cache_mutex.hh
BLI_color.hh
BLI_color_mix.hh
BLI_compiler_attrs.h
@@ -235,6 +241,7 @@ set(SRC
BLI_kdtree.h
BLI_kdtree_impl.h
BLI_lasso_2d.h
+ BLI_lazy_threading.hh
BLI_length_parameterize.hh
BLI_linear_allocator.hh
BLI_link_utils.h
@@ -329,7 +336,6 @@ set(SRC
BLI_uuid.h
BLI_uvproject.h
BLI_vector.hh
- BLI_vector_adaptor.hh
BLI_vector_set.hh
BLI_vector_set_slots.hh
BLI_virtual_array.hh
diff --git a/source/blender/blenlib/intern/BLI_args.c b/source/blender/blenlib/intern/BLI_args.c
index 61447ab1a9e..ceb7f7f0aba 100644
--- a/source/blender/blenlib/intern/BLI_args.c
+++ b/source/blender/blenlib/intern/BLI_args.c
@@ -57,7 +57,7 @@ static uint case_strhash(const void *ptr)
{
const char *s = ptr;
uint i = 0;
- unsigned char c;
+ uchar c;
while ((c = tolower(*s++))) {
i = i * 37 + c;
@@ -80,7 +80,7 @@ static bool keycmp(const void *a, const void *b)
if (ka->case_str == 1 || kb->case_str == 1) {
return (BLI_strcasecmp(ka->arg, kb->arg) != 0);
}
- return (!STREQ(ka->arg, kb->arg));
+ return !STREQ(ka->arg, kb->arg);
}
return BLI_ghashutil_intcmp((const void *)ka->pass, (const void *)kb->pass);
}
diff --git a/source/blender/blenlib/intern/BLI_filelist.c b/source/blender/blenlib/intern/BLI_filelist.c
index c6178ebb3a0..4bcb023691a 100644
--- a/source/blender/blenlib/intern/BLI_filelist.c
+++ b/source/blender/blenlib/intern/BLI_filelist.c
@@ -93,7 +93,7 @@ static int bli_compare(struct direntry *entry1, struct direntry *entry2)
return 1;
}
- return (BLI_strcasecmp_natural(entry1->relname, entry2->relname));
+ return BLI_strcasecmp_natural(entry1->relname, entry2->relname);
}
struct BuildDirCtx {
@@ -174,10 +174,10 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
struct direntry *file = &dir_ctx->files[dir_ctx->files_num];
while (dlink) {
char fullname[PATH_MAX];
+ BLI_path_join(fullname, sizeof(fullname), dirname, dlink->name);
memset(file, 0, sizeof(struct direntry));
file->relname = dlink->name;
- file->path = BLI_strdupcat(dirname, dlink->name);
- BLI_join_dirfile(fullname, sizeof(fullname), dirname, dlink->name);
+ file->path = BLI_strdup(fullname);
if (BLI_stat(fullname, &file->s) != -1) {
file->type = file->s.st_mode;
}
@@ -215,7 +215,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
}
}
-unsigned int BLI_filelist_dir_contents(const char *dirname, struct direntry **r_filelist)
+uint BLI_filelist_dir_contents(const char *dirname, struct direntry **r_filelist)
{
struct BuildDirCtx dir_ctx;
@@ -395,9 +395,9 @@ void BLI_filelist_entry_duplicate(struct direntry *dst, const struct direntry *s
void BLI_filelist_duplicate(struct direntry **dest_filelist,
struct direntry *const src_filelist,
- const unsigned int nrentries)
+ const uint nrentries)
{
- unsigned int i;
+ uint i;
*dest_filelist = MEM_mallocN(sizeof(**dest_filelist) * (size_t)(nrentries), __func__);
for (i = 0; i < nrentries; i++) {
@@ -417,9 +417,9 @@ void BLI_filelist_entry_free(struct direntry *entry)
}
}
-void BLI_filelist_free(struct direntry *filelist, const unsigned int nrentries)
+void BLI_filelist_free(struct direntry *filelist, const uint nrentries)
{
- unsigned int i;
+ uint i;
for (i = 0; i < nrentries; i++) {
BLI_filelist_entry_free(&filelist[i]);
}
diff --git a/source/blender/blenlib/intern/BLI_ghash_utils.c b/source/blender/blenlib/intern/BLI_ghash_utils.c
index e12e272832f..806d58df260 100644
--- a/source/blender/blenlib/intern/BLI_ghash_utils.c
+++ b/source/blender/blenlib/intern/BLI_ghash_utils.c
@@ -63,7 +63,7 @@ uint BLI_ghashutil_uinthash_v4(const uint key[4])
uint BLI_ghashutil_uinthash_v4_murmur(const uint key[4])
{
- return BLI_hash_mm2((const unsigned char *)key, sizeof(int[4]) /* sizeof(key) */, 0);
+ return BLI_hash_mm2((const uchar *)key, sizeof(int[4]) /* sizeof(key) */, 0);
}
bool BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b)
@@ -101,7 +101,7 @@ uint BLI_ghashutil_inthash_p_murmur(const void *ptr)
{
uintptr_t key = (uintptr_t)ptr;
- return BLI_hash_mm2((const unsigned char *)&key, sizeof(key), 0);
+ return BLI_hash_mm2((const uchar *)&key, sizeof(key), 0);
}
uint BLI_ghashutil_inthash_p_simple(const void *ptr)
@@ -143,7 +143,7 @@ uint BLI_ghashutil_strhash_p(const void *ptr)
}
uint BLI_ghashutil_strhash_p_murmur(const void *ptr)
{
- const unsigned char *key = ptr;
+ const uchar *key = ptr;
return BLI_hash_mm2(key, strlen((const char *)key) + 1, 0);
}
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index a43b725b6e3..de71147f015 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -58,7 +58,7 @@
/** \name Struct Definitions
* \{ */
-typedef unsigned char axis_t;
+typedef uchar axis_t;
typedef struct BVHNode {
struct BVHNode **children;
@@ -386,12 +386,12 @@ static void refit_kdop_hull(const BVHTree *tree, BVHNode *node, int start, int e
/* for all Axes. */
for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
newmin = node_bv[(2 * axis_iter)];
- if ((newmin < bv[(2 * axis_iter)])) {
+ if (newmin < bv[(2 * axis_iter)]) {
bv[(2 * axis_iter)] = newmin;
}
newmax = node_bv[(2 * axis_iter) + 1];
- if ((newmax > bv[(2 * axis_iter) + 1])) {
+ if (newmax > bv[(2 * axis_iter) + 1]) {
bv[(2 * axis_iter) + 1] = newmax;
}
}
diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c
index ada2d27f9b2..3c353a1c8c8 100644
--- a/source/blender/blenlib/intern/BLI_memarena.c
+++ b/source/blender/blenlib/intern/BLI_memarena.c
@@ -38,7 +38,7 @@ struct MemBuf {
};
struct MemArena {
- unsigned char *curbuf;
+ uchar *curbuf;
const char *name;
struct MemBuf *bufs;
@@ -53,7 +53,7 @@ static void memarena_buf_free_all(struct MemBuf *mb)
while (mb != NULL) {
struct MemBuf *mb_next = mb->next;
- /* Unpoison memory because MEM_freeN might overwrite it. */
+ /* Unpoison memory because #MEM_freeN might overwrite it. */
BLI_asan_unpoison(mb, (uint)MEM_allocN_len(mb));
MEM_freeN(mb);
@@ -106,9 +106,9 @@ void BLI_memarena_free(MemArena *ma)
/** Align alloc'ed memory (needed if `align > 8`). */
static void memarena_curbuf_align(MemArena *ma)
{
- unsigned char *tmp;
+ uchar *tmp;
- tmp = (unsigned char *)PADUP((intptr_t)ma->curbuf, (int)ma->align);
+ tmp = (uchar *)PADUP((intptr_t)ma->curbuf, (int)ma->align);
ma->cursize -= (size_t)(tmp - ma->curbuf);
ma->curbuf = tmp;
}
@@ -209,7 +209,7 @@ void BLI_memarena_merge(MemArena *ma_dst, MemArena *ma_src)
void BLI_memarena_clear(MemArena *ma)
{
if (ma->bufs) {
- unsigned char *curbuf_prev;
+ uchar *curbuf_prev;
size_t curbuf_used;
if (ma->bufs->next) {
diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c
index 9a8bda48c8d..65518427656 100644
--- a/source/blender/blenlib/intern/array_store.c
+++ b/source/blender/blenlib/intern/array_store.c
@@ -736,17 +736,17 @@ static void bchunk_list_fill_from_array(const BArrayInfo *info,
BLI_INLINE uint hash_data_single(const uchar p)
{
- return ((HASH_INIT << 5) + HASH_INIT) + (unsigned int)(*((signed char *)&p));
+ return ((HASH_INIT << 5) + HASH_INIT) + (uint)(*((signed char *)&p));
}
/* hash bytes, from BLI_ghashutil_strhash_n */
static uint hash_data(const uchar *key, size_t n)
{
const signed char *p;
- unsigned int h = HASH_INIT;
+ uint h = HASH_INIT;
for (p = (const signed char *)key; n--; p++) {
- h = ((h << 5) + h) + (unsigned int)*p;
+ h = (uint)((h << 5) + h) + (uint)*p;
}
return h;
@@ -805,7 +805,7 @@ static void hash_array_from_cref(const BArrayInfo *info,
static void hash_accum(hash_key *hash_array, const size_t hash_array_len, size_t iter_steps)
{
/* _very_ unlikely, can happen if you select a chunk-size of 1 for example. */
- if (UNLIKELY((iter_steps > hash_array_len))) {
+ if (UNLIKELY(iter_steps > hash_array_len)) {
iter_steps = hash_array_len;
}
@@ -1403,7 +1403,7 @@ BArrayStore *BLI_array_store_create(uint stride, uint chunk_count)
/* Triangle number, identifying now much read-ahead we need:
* https://en.wikipedia.org/wiki/Triangular_number (+ 1) */
bs->info.accum_read_ahead_len =
- (uint)((((bs->info.accum_steps * (bs->info.accum_steps + 1))) / 2) + 1);
+ (uint)(((bs->info.accum_steps * (bs->info.accum_steps + 1)) / 2) + 1);
bs->info.accum_read_ahead_bytes = bs->info.accum_read_ahead_len * stride;
#else
bs->info.accum_read_ahead_bytes = BCHUNK_HASH_LEN * stride;
diff --git a/source/blender/blenlib/intern/array_store_utils.c b/source/blender/blenlib/intern/array_store_utils.c
index 9ac8630204a..51b5ce0519f 100644
--- a/source/blender/blenlib/intern/array_store_utils.c
+++ b/source/blender/blenlib/intern/array_store_utils.c
@@ -27,9 +27,9 @@ BArrayStore *BLI_array_store_at_size_ensure(struct BArrayStore_AtSize *bs_stride
if ((*bs_p) == NULL) {
/* calculate best chunk-count to fit a power of two */
- unsigned int chunk_count = chunk_size;
+ uint chunk_count = chunk_size;
{
- unsigned int size = chunk_count * stride;
+ uint size = chunk_count * stride;
size = power_of_2_max_u(size);
size = MEM_SIZE_OPTIMAL(size);
chunk_count = size / stride;
diff --git a/source/blender/blenlib/intern/array_utils.cc b/source/blender/blenlib/intern/array_utils.cc
new file mode 100644
index 00000000000..2a231228dcb
--- /dev/null
+++ b/source/blender/blenlib/intern/array_utils.cc
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BLI_array_utils.hh"
+
+namespace blender::array_utils {
+
+void copy(const GVArray &src,
+ const IndexMask selection,
+ GMutableSpan dst,
+ const int64_t grain_size)
+{
+ BLI_assert(src.type() == dst.type());
+ BLI_assert(src.size() == dst.size());
+ threading::parallel_for(selection.index_range(), grain_size, [&](const IndexRange range) {
+ src.materialize_to_uninitialized(selection.slice(range), dst.data());
+ });
+}
+
+void gather(const GVArray &src,
+ const IndexMask indices,
+ GMutableSpan dst,
+ const int64_t grain_size)
+{
+ BLI_assert(src.type() == dst.type());
+ BLI_assert(indices.size() == dst.size());
+ threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) {
+ src.materialize_compressed_to_uninitialized(indices.slice(range), dst.slice(range).data());
+ });
+}
+
+void gather(const GSpan src, const IndexMask indices, GMutableSpan dst, const int64_t grain_size)
+{
+ gather(GVArray::ForSpan(src), indices, dst, grain_size);
+}
+
+} // namespace blender::array_utils
diff --git a/source/blender/blenlib/intern/boxpack_2d.c b/source/blender/blenlib/intern/boxpack_2d.c
index d55a4a8c9ff..309ae624305 100644
--- a/source/blender/blenlib/intern/boxpack_2d.c
+++ b/source/blender/blenlib/intern/boxpack_2d.c
@@ -491,7 +491,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const uint len, float *r_tot_x, float *r
* flag verts on one or both of the boxes
* as being used by checking the width or
* height of both boxes */
- if (vert->tlb && vert->trb && (ELEM(box, vert->tlb, vert->trb))) {
+ if (vert->tlb && vert->trb && ELEM(box, vert->tlb, vert->trb)) {
if (UNLIKELY(fabsf(vert->tlb->h - vert->trb->h) < EPSILON_MERGE)) {
#ifdef USE_MERGE
# define A (vert->trb->v[TL])
@@ -522,7 +522,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const uint len, float *r_tot_x, float *r
vert->tlb->v[TR]->free &= ~(TRF | BRF);
}
}
- else if (vert->blb && vert->brb && (ELEM(box, vert->blb, vert->brb))) {
+ else if (vert->blb && vert->brb && ELEM(box, vert->blb, vert->brb)) {
if (UNLIKELY(fabsf(vert->blb->h - vert->brb->h) < EPSILON_MERGE)) {
#ifdef USE_MERGE
# define A (vert->blb->v[BR])
@@ -554,7 +554,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const uint len, float *r_tot_x, float *r
}
}
/* Horizontal */
- if (vert->tlb && vert->blb && (ELEM(box, vert->tlb, vert->blb))) {
+ if (vert->tlb && vert->blb && ELEM(box, vert->tlb, vert->blb)) {
if (UNLIKELY(fabsf(vert->tlb->w - vert->blb->w) < EPSILON_MERGE)) {
#ifdef USE_MERGE
# define A (vert->blb->v[TL])
@@ -585,7 +585,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const uint len, float *r_tot_x, float *r
vert->tlb->v[BL]->free &= ~(BLF | BRF);
}
}
- else if (vert->trb && vert->brb && (ELEM(box, vert->trb, vert->brb))) {
+ else if (vert->trb && vert->brb && ELEM(box, vert->trb, vert->brb)) {
if (UNLIKELY(fabsf(vert->trb->w - vert->brb->w) < EPSILON_MERGE)) {
#ifdef USE_MERGE
diff --git a/source/blender/blenlib/intern/cache_mutex.cc b/source/blender/blenlib/intern/cache_mutex.cc
new file mode 100644
index 00000000000..db474b1ef87
--- /dev/null
+++ b/source/blender/blenlib/intern/cache_mutex.cc
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BLI_cache_mutex.hh"
+#include "BLI_task.hh"
+
+namespace blender {
+
+void CacheMutex::ensure(const FunctionRef<void()> compute_cache)
+{
+ if (cache_valid_.load(std::memory_order_acquire)) {
+ return;
+ }
+ std::scoped_lock lock{mutex_};
+ /* Double checked lock. */
+ if (cache_valid_.load(std::memory_order_relaxed)) {
+ return;
+ }
+ /* Use task isolation because a mutex is locked and the cache computation might use
+ * multi-threading. */
+ threading::isolate_task(compute_cache);
+
+ cache_valid_.store(true, std::memory_order_release);
+}
+
+} // namespace blender
diff --git a/source/blender/blenlib/intern/convexhull_2d.c b/source/blender/blenlib/intern/convexhull_2d.c
index 33d1a68a76e..9e3fb230d3c 100644
--- a/source/blender/blenlib/intern/convexhull_2d.c
+++ b/source/blender/blenlib/intern/convexhull_2d.c
@@ -39,8 +39,9 @@ static float is_left(const float p0[2], const float p1[2], const float p2[2])
return (p1[0] - p0[0]) * (p2[1] - p0[1]) - (p2[0] - p0[0]) * (p1[1] - p0[1]);
}
-int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points[])
+static int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points[])
{
+ BLI_assert(n >= 2); /* Doesn't handle trivial cases. */
/* the output array r_points[] will be used as the stack */
int bot = 0;
int top = -1; /* indices for bottom and top of the stack */
@@ -66,6 +67,7 @@ int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points
r_points[++top] = minmax;
}
r_points[++top] = minmin; /* add polygon endpoint */
+ BLI_assert(top + 1 <= n);
return top + 1;
}
@@ -122,16 +124,18 @@ int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points
}
if (points[i][0] == points[r_points[0]][0] && points[i][1] == points[r_points[0]][1]) {
+ BLI_assert(top + 1 <= n);
return top + 1; /* special case (mgomes) */
}
r_points[++top] = i; /* push points[i] onto stack */
}
- if (minmax != minmin) {
+ if (minmax != minmin && r_points[0] != minmin) {
r_points[++top] = minmin; /* push joining endpoint onto stack */
}
+ BLI_assert(top + 1 <= n);
return top + 1;
}
@@ -162,35 +166,38 @@ static int pointref_cmp_yx(const void *a_, const void *b_)
int BLI_convexhull_2d(const float (*points)[2], const int n, int r_points[])
{
+ BLI_assert(n >= 0);
+ if (n < 2) {
+ if (n == 1) {
+ r_points[0] = 0;
+ }
+ return n;
+ }
struct PointRef *points_ref = MEM_mallocN(sizeof(*points_ref) * (size_t)n, __func__);
float(*points_sort)[2] = MEM_mallocN(sizeof(*points_sort) * (size_t)n, __func__);
- int *points_map;
- int points_hull_num, i;
- for (i = 0; i < n; i++) {
+ for (int i = 0; i < n; i++) {
points_ref[i].pt = points[i];
}
- /* Sort the points by X, then by Y (required by the algorithm) */
+ /* Sort the points by X, then by Y. */
qsort(points_ref, (size_t)n, sizeof(struct PointRef), pointref_cmp_yx);
- for (i = 0; i < n; i++) {
+ for (int i = 0; i < n; i++) {
memcpy(points_sort[i], points_ref[i].pt, sizeof(float[2]));
}
- points_hull_num = BLI_convexhull_2d_sorted(points_sort, n, r_points);
+ int points_hull_num = BLI_convexhull_2d_sorted(points_sort, n, r_points);
- /* map back to the original index values */
- points_map = (int *)points_sort; /* abuse float array for temp storage */
- for (i = 0; i < points_hull_num; i++) {
- points_map[i] = (int)((const float(*)[2])points_ref[r_points[i]].pt - points);
+ /* Map back to the unsorted index values. */
+ for (int i = 0; i < points_hull_num; i++) {
+ r_points[i] = (int)((const float(*)[2])points_ref[r_points[i]].pt - points);
}
- memcpy(r_points, points_map, (size_t)points_hull_num * sizeof(*points_map));
-
MEM_freeN(points_ref);
MEM_freeN(points_sort);
+ BLI_assert(points_hull_num <= n);
return points_hull_num;
}
@@ -202,14 +209,13 @@ int BLI_convexhull_2d(const float (*points)[2], const int n, int r_points[])
/** \name Utility Convex-Hull Functions
* \{ */
-float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned int n)
+static float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], int n)
{
- unsigned int i, i_prev;
float area_best = FLT_MAX;
float dvec_best[2]; /* best angle, delay atan2 */
- i_prev = n - 1;
- for (i = 0; i < n; i++) {
+ int i_prev = n - 1;
+ for (int i = 0; i < n; i++) {
const float *ev_a = points_hull[i];
const float *ev_b = points_hull[i_prev];
float dvec[2]; /* 2d rotation matrix */
@@ -218,10 +224,9 @@ float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned in
if (normalize_v2(dvec) != 0.0f) {
/* rotation matrix */
float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX};
- unsigned int j;
float area;
- for (j = 0; j < n; j++) {
+ for (int j = 0; j < n; j++) {
float tvec[2];
mul_v2_v2_cw(tvec, dvec, points_hull[j]);
@@ -249,32 +254,24 @@ float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned in
return (area_best != FLT_MAX) ? atan2f(dvec_best[0], dvec_best[1]) : 0.0f;
}
-float BLI_convexhull_aabb_fit_points_2d(const float (*points)[2], unsigned int n)
+float BLI_convexhull_aabb_fit_points_2d(const float (*points)[2], int n)
{
- int *index_map;
- int points_hull_num;
+ BLI_assert(n >= 0);
+ float angle = 0.0f;
- float angle;
+ int *index_map = MEM_mallocN(sizeof(*index_map) * (size_t)n, __func__);
- index_map = MEM_mallocN(sizeof(*index_map) * n * 2, __func__);
+ int points_hull_num = BLI_convexhull_2d(points, n, index_map);
- points_hull_num = BLI_convexhull_2d(points, (int)n, index_map);
-
- if (points_hull_num) {
- float(*points_hull)[2];
- int j;
-
- points_hull = MEM_mallocN(sizeof(*points_hull) * (size_t)points_hull_num, __func__);
- for (j = 0; j < points_hull_num; j++) {
+ if (points_hull_num > 1) {
+ float(*points_hull)[2] = MEM_mallocN(sizeof(*points_hull) * (size_t)points_hull_num, __func__);
+ for (int j = 0; j < points_hull_num; j++) {
copy_v2_v2(points_hull[j], points[index_map[j]]);
}
- angle = BLI_convexhull_aabb_fit_hull_2d(points_hull, (unsigned int)points_hull_num);
+ angle = BLI_convexhull_aabb_fit_hull_2d(points_hull, points_hull_num);
MEM_freeN(points_hull);
}
- else {
- angle = 0.0f;
- }
MEM_freeN(index_map);
diff --git a/source/blender/blenlib/intern/delaunay_2d.cc b/source/blender/blenlib/intern/delaunay_2d.cc
index db6cb0824dc..afecf9ea838 100644
--- a/source/blender/blenlib/intern/delaunay_2d.cc
+++ b/source/blender/blenlib/intern/delaunay_2d.cc
@@ -45,7 +45,7 @@ template<> double math_abs<double>(const double v)
return fabs(v);
}
-template<typename T> double math_to_double(const T UNUSED(v))
+template<typename T> double math_to_double(const T /*v*/)
{
BLI_assert(false); /* Need implementation for other type. */
return 0.0;
@@ -520,10 +520,10 @@ template<typename T> void cdt_draw(const std::string &label, const CDTArrangemen
double height = maxy - miny;
double aspect = height / width;
int view_width = max_draw_width;
- int view_height = static_cast<int>(view_width * aspect);
+ int view_height = int(view_width * aspect);
if (view_height > max_draw_height) {
view_height = max_draw_height;
- view_width = static_cast<int>(view_height / aspect);
+ view_width = int(view_height / aspect);
}
double scale = view_width / width;
@@ -2645,7 +2645,7 @@ void prepare_cdt_for_output(CDT_state<T> *cdt_state, const CDT_output_type outpu
template<typename T>
CDT_result<T> get_cdt_output(CDT_state<T> *cdt_state,
- const CDT_input<T> UNUSED(input),
+ const CDT_input<T> /*input*/,
CDT_output_type output_type)
{
CDT_output_type oty = output_type;
@@ -2822,8 +2822,8 @@ extern "C" ::CDT_result *BLI_delaunay_2d_cdt_calc(const ::CDT_input *input,
in.edge = blender::Array<std::pair<int, int>>(input->edges_len);
in.face = blender::Array<blender::Vector<int>>(input->faces_len);
for (int v = 0; v < input->verts_len; ++v) {
- double x = static_cast<double>(input->vert_coords[v][0]);
- double y = static_cast<double>(input->vert_coords[v][1]);
+ double x = double(input->vert_coords[v][0]);
+ double y = double(input->vert_coords[v][1]);
in.vert[v] = blender::meshintersect::vec2<double>(x, y);
}
for (int e = 0; e < input->edges_len; ++e) {
@@ -2836,7 +2836,7 @@ extern "C" ::CDT_result *BLI_delaunay_2d_cdt_calc(const ::CDT_input *input,
in.face[f][j] = input->faces[fstart + j];
}
}
- in.epsilon = static_cast<double>(input->epsilon);
+ in.epsilon = double(input->epsilon);
in.need_ids = input->need_ids;
blender::meshintersect::CDT_result<double> res = blender::meshintersect::delaunay_2d_calc(
@@ -2903,8 +2903,8 @@ extern "C" ::CDT_result *BLI_delaunay_2d_cdt_calc(const ::CDT_input *input,
int v_orig_index = 0;
for (int v = 0; v < nv; ++v) {
- output->vert_coords[v][0] = static_cast<float>(res.vert[v][0]);
- output->vert_coords[v][1] = static_cast<float>(res.vert[v][1]);
+ output->vert_coords[v][0] = float(res.vert[v][0]);
+ output->vert_coords[v][1] = float(res.vert[v][1]);
if (input->need_ids) {
int this_start = v_orig_index;
output->verts_orig_start_table[v] = this_start;
diff --git a/source/blender/blenlib/intern/dot_export.cc b/source/blender/blenlib/intern/dot_export.cc
index 796fd6a934a..d577de9bc34 100644
--- a/source/blender/blenlib/intern/dot_export.cc
+++ b/source/blender/blenlib/intern/dot_export.cc
@@ -93,7 +93,7 @@ void Graph::set_random_cluster_bgcolors()
void Cluster::set_random_cluster_bgcolors()
{
- float hue = rand() / (float)RAND_MAX;
+ float hue = rand() / float(RAND_MAX);
float staturation = 0.3f;
float value = 0.8f;
this->attributes.set("bgcolor", color_attr_from_hsv(hue, staturation, value));
@@ -227,7 +227,7 @@ void Attributes::export__as_bracket_list(std::stringstream &ss) const
void Node::export__as_id(std::stringstream &ss) const
{
- ss << '"' << (uintptr_t)this << '"';
+ ss << '"' << uintptr_t(this) << '"';
}
void Node::export__as_declaration(std::stringstream &ss) const
diff --git a/source/blender/blenlib/intern/endian_switch.c b/source/blender/blenlib/intern/endian_switch.c
index 10d0bfb815b..c1a5b69fb23 100644
--- a/source/blender/blenlib/intern/endian_switch.c
+++ b/source/blender/blenlib/intern/endian_switch.c
@@ -18,7 +18,7 @@ void BLI_endian_switch_int16_array(short *val, const int size)
}
}
-void BLI_endian_switch_uint16_array(unsigned short *val, const int size)
+void BLI_endian_switch_uint16_array(ushort *val, const int size)
{
if (size > 0) {
int i = size;
@@ -38,7 +38,7 @@ void BLI_endian_switch_int32_array(int *val, const int size)
}
}
-void BLI_endian_switch_uint32_array(unsigned int *val, const int size)
+void BLI_endian_switch_uint32_array(uint *val, const int size)
{
if (size > 0) {
int i = size;
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index 3abd482d6b3..005de1f85b4 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -401,7 +401,7 @@ static bool delete_recursive(const char *dir)
/* dir listing produces dir path without trailing slash... */
BLI_strncpy(path, fl->path, sizeof(path));
- BLI_path_slash_ensure(path);
+ BLI_path_slash_ensure(path, sizeof(path));
if (delete_recursive(path)) {
err = true;
@@ -627,7 +627,7 @@ static void join_dirfile_alloc(char **dst, size_t *alloc_len, const char *dir, c
*alloc_len = len;
- BLI_join_dirfile(*dst, len + 1, dir, file);
+ BLI_path_join(*dst, len + 1, dir, file);
}
static char *strip_last_slash(const char *dir)
@@ -1184,7 +1184,7 @@ static const char *check_destination(const char *file, const char *to)
len = strlen(to) + strlen(filename) + 1;
path = MEM_callocN(len + 1, "check_destination path");
- BLI_join_dirfile(path, len + 1, to, filename);
+ BLI_path_join(path, len + 1, to, filename);
MEM_freeN(str);
diff --git a/source/blender/blenlib/intern/generic_virtual_array.cc b/source/blender/blenlib/intern/generic_virtual_array.cc
index f66b1e14fc6..b0623175dc7 100644
--- a/source/blender/blenlib/intern/generic_virtual_array.cc
+++ b/source/blender/blenlib/intern/generic_virtual_array.cc
@@ -51,7 +51,7 @@ CommonVArrayInfo GVArrayImpl::common_info() const
return {};
}
-bool GVArrayImpl::try_assign_VArray(void *UNUSED(varray)) const
+bool GVArrayImpl::try_assign_VArray(void * /*varray*/) const
{
return false;
}
@@ -102,7 +102,7 @@ void GVMutableArray::fill(const void *value)
}
}
-bool GVMutableArrayImpl::try_assign_VMutableArray(void *UNUSED(varray)) const
+bool GVMutableArrayImpl::try_assign_VMutableArray(void * /*varray*/) const
{
return false;
}
@@ -172,11 +172,11 @@ void GVArrayImpl_For_GSpan::materialize_compressed_to_uninitialized(const IndexM
/* Generic virtual array where each element has the same value. The value is not owned. */
-void GVArrayImpl_For_SingleValueRef::get(const int64_t UNUSED(index), void *r_value) const
+void GVArrayImpl_For_SingleValueRef::get(const int64_t /*index*/, void *r_value) const
{
type_->copy_assign(value_, r_value);
}
-void GVArrayImpl_For_SingleValueRef::get_to_uninitialized(const int64_t UNUSED(index),
+void GVArrayImpl_For_SingleValueRef::get_to_uninitialized(const int64_t /*index*/,
void *r_value) const
{
type_->copy_construct(value_, r_value);
@@ -261,11 +261,11 @@ template<int BufferSize> class GVArrayImpl_For_SmallTrivialSingleValue : public
}
private:
- void get(const int64_t UNUSED(index), void *r_value) const override
+ void get(const int64_t /*index*/, void *r_value) const override
{
this->copy_value_to(r_value);
}
- void get_to_uninitialized(const int64_t UNUSED(index), void *r_value) const override
+ void get_to_uninitialized(const int64_t /*index*/, void *r_value) const override
{
this->copy_value_to(r_value);
}
diff --git a/source/blender/blenlib/intern/generic_virtual_vector_array.cc b/source/blender/blenlib/intern/generic_virtual_vector_array.cc
index 8fd1fb50b72..5d6985e16c8 100644
--- a/source/blender/blenlib/intern/generic_virtual_vector_array.cc
+++ b/source/blender/blenlib/intern/generic_virtual_vector_array.cc
@@ -16,12 +16,12 @@ void GVArray_For_GVVectorArrayIndex::get_to_uninitialized(const int64_t index_in
vector_array_.get_vector_element(index_, index_in_vector, r_value);
}
-int64_t GVVectorArray_For_SingleGVArray::get_vector_size_impl(const int64_t UNUSED(index)) const
+int64_t GVVectorArray_For_SingleGVArray::get_vector_size_impl(const int64_t /*index*/) const
{
return varray_.size();
}
-void GVVectorArray_For_SingleGVArray::get_vector_element_impl(const int64_t UNUSED(index),
+void GVVectorArray_For_SingleGVArray::get_vector_element_impl(const int64_t /*index*/,
const int64_t index_in_vector,
void *r_value) const
{
@@ -33,12 +33,12 @@ bool GVVectorArray_For_SingleGVArray::is_single_vector_impl() const
return true;
}
-int64_t GVVectorArray_For_SingleGSpan::get_vector_size_impl(const int64_t UNUSED(index)) const
+int64_t GVVectorArray_For_SingleGSpan::get_vector_size_impl(const int64_t /*index*/) const
{
return span_.size();
}
-void GVVectorArray_For_SingleGSpan::get_vector_element_impl(const int64_t UNUSED(index),
+void GVVectorArray_For_SingleGSpan::get_vector_element_impl(const int64_t /*index*/,
const int64_t index_in_vector,
void *r_value) const
{
diff --git a/source/blender/blenlib/intern/hash_mm2a.c b/source/blender/blenlib/intern/hash_mm2a.c
index 8411b49ef38..d13c20e4edb 100644
--- a/source/blender/blenlib/intern/hash_mm2a.c
+++ b/source/blender/blenlib/intern/hash_mm2a.c
@@ -41,7 +41,7 @@
} \
(void)0
-static void mm2a_mix_tail(BLI_HashMurmur2A *mm2, const unsigned char **data, size_t *len)
+static void mm2a_mix_tail(BLI_HashMurmur2A *mm2, const uchar **data, size_t *len)
{
while (*len && ((*len < 4) || mm2->count)) {
mm2->tail |= (uint32_t)(**data) << (mm2->count * 8);
@@ -66,7 +66,7 @@ void BLI_hash_mm2a_init(BLI_HashMurmur2A *mm2, uint32_t seed)
mm2->size = 0;
}
-void BLI_hash_mm2a_add(BLI_HashMurmur2A *mm2, const unsigned char *data, size_t len)
+void BLI_hash_mm2a_add(BLI_HashMurmur2A *mm2, const uchar *data, size_t len)
{
mm2->size += (uint32_t)len;
@@ -83,7 +83,7 @@ void BLI_hash_mm2a_add(BLI_HashMurmur2A *mm2, const unsigned char *data, size_t
void BLI_hash_mm2a_add_int(BLI_HashMurmur2A *mm2, int data)
{
- BLI_hash_mm2a_add(mm2, (const unsigned char *)&data, sizeof(data));
+ BLI_hash_mm2a_add(mm2, (const uchar *)&data, sizeof(data));
}
uint32_t BLI_hash_mm2a_end(BLI_HashMurmur2A *mm2)
@@ -96,7 +96,7 @@ uint32_t BLI_hash_mm2a_end(BLI_HashMurmur2A *mm2)
return mm2->hash;
}
-uint32_t BLI_hash_mm2(const unsigned char *data, size_t len, uint32_t seed)
+uint32_t BLI_hash_mm2(const uchar *data, size_t len, uint32_t seed)
{
/* Initialize the hash to a 'random' value */
uint32_t h = seed ^ len;
diff --git a/source/blender/blenlib/intern/hash_mm3.c b/source/blender/blenlib/intern/hash_mm3.c
index cc1143bf55f..3c05ead5e62 100644
--- a/source/blender/blenlib/intern/hash_mm3.c
+++ b/source/blender/blenlib/intern/hash_mm3.c
@@ -69,7 +69,7 @@ BLI_INLINE uint64_t fmix64(uint64_t k)
return k;
}
-uint32_t BLI_hash_mm3(const unsigned char *data, size_t len, uint32_t seed)
+uint32_t BLI_hash_mm3(const uchar *data, size_t len, uint32_t seed)
{
const uint8_t *in_data = (const uint8_t *)data;
const int nblocks = len / 4;
diff --git a/source/blender/blenlib/intern/jitter_2d.c b/source/blender/blenlib/intern/jitter_2d.c
index 8fa0f2c1e15..4b86f3cfeef 100644
--- a/source/blender/blenlib/intern/jitter_2d.c
+++ b/source/blender/blenlib/intern/jitter_2d.c
@@ -70,7 +70,7 @@ void BLI_jitterate1(float (*jit1)[2], float (*jit2)[2], int num, float radius1)
jit2[i][0] = x;
jit2[i][1] = y;
}
- memcpy(jit1, jit2, 2 * (unsigned int)num * sizeof(float));
+ memcpy(jit1, jit2, 2 * (uint)num * sizeof(float));
}
void BLI_jitterate2(float (*jit1)[2], float (*jit2)[2], int num, float radius2)
@@ -120,7 +120,7 @@ void BLI_jitterate2(float (*jit1)[2], float (*jit2)[2], int num, float radius2)
jit2[i][0] = x;
jit2[i][1] = y;
}
- memcpy(jit1, jit2, (unsigned int)num * sizeof(float[2]));
+ memcpy(jit1, jit2, (uint)num * sizeof(float[2]));
}
void BLI_jitter_init(float (*jitarr)[2], int num)
@@ -138,12 +138,12 @@ void BLI_jitter_init(float (*jitarr)[2], int num)
number_fl = (float)num;
number_fl_sqrt = sqrtf(number_fl);
- jit2 = MEM_mallocN(12 + (unsigned int)num * sizeof(float[2]), "initjit");
+ jit2 = MEM_mallocN(12 + (uint)num * sizeof(float[2]), "initjit");
rad1 = 1.0f / number_fl_sqrt;
rad2 = 1.0f / number_fl;
rad3 = number_fl_sqrt / number_fl;
- rng = BLI_rng_new(31415926 + (unsigned int)num);
+ rng = BLI_rng_new(31415926 + (uint)num);
x = 0;
for (i = 0; i < num; i++) {
diff --git a/source/blender/blenlib/intern/kdtree_impl.h b/source/blender/blenlib/intern/kdtree_impl.h
index 6614f1bf964..f7993eb5adc 100644
--- a/source/blender/blenlib/intern/kdtree_impl.h
+++ b/source/blender/blenlib/intern/kdtree_impl.h
@@ -11,9 +11,9 @@
#include "BLI_strict_flags.h"
#include "BLI_utildefines.h"
-#define _CONCAT_AUX(MACRO_ARG1, MACRO_ARG2) MACRO_ARG1##MACRO_ARG2
-#define _CONCAT(MACRO_ARG1, MACRO_ARG2) _CONCAT_AUX(MACRO_ARG1, MACRO_ARG2)
-#define BLI_kdtree_nd_(id) _CONCAT(KDTREE_PREFIX_ID, _##id)
+#define _BLI_KDTREE_CONCAT_AUX(MACRO_ARG1, MACRO_ARG2) MACRO_ARG1##MACRO_ARG2
+#define _BLI_KDTREE_CONCAT(MACRO_ARG1, MACRO_ARG2) _BLI_KDTREE_CONCAT_AUX(MACRO_ARG1, MACRO_ARG2)
+#define BLI_kdtree_nd_(id) _BLI_KDTREE_CONCAT(KDTREE_PREFIX_ID, _##id)
typedef struct KDTreeNode_head {
uint left, right;
diff --git a/source/blender/blenlib/intern/lasso_2d.c b/source/blender/blenlib/intern/lasso_2d.c
index 13b0e416b76..4752864ea3a 100644
--- a/source/blender/blenlib/intern/lasso_2d.c
+++ b/source/blender/blenlib/intern/lasso_2d.c
@@ -12,9 +12,9 @@
#include "BLI_lasso_2d.h" /* own include */
-void BLI_lasso_boundbox(rcti *rect, const int mcoords[][2], const unsigned int mcoords_len)
+void BLI_lasso_boundbox(rcti *rect, const int mcoords[][2], const uint mcoords_len)
{
- unsigned int a;
+ uint a;
rect->xmin = rect->xmax = mcoords[0][0];
rect->ymin = rect->ymax = mcoords[0][1];
@@ -36,7 +36,7 @@ void BLI_lasso_boundbox(rcti *rect, const int mcoords[][2], const unsigned int m
}
bool BLI_lasso_is_point_inside(const int mcoords[][2],
- const unsigned int mcoords_len,
+ const uint mcoords_len,
const int sx,
const int sy,
const int error_value)
@@ -50,7 +50,7 @@ bool BLI_lasso_is_point_inside(const int mcoords[][2],
}
bool BLI_lasso_is_edge_inside(const int mcoords[][2],
- const unsigned int mcoords_len,
+ const uint mcoords_len,
int x0,
int y0,
int x1,
@@ -77,7 +77,7 @@ bool BLI_lasso_is_edge_inside(const int mcoords[][2],
if (isect_seg_seg_v2_int(mcoords[0], mcoords[mcoords_len - 1], v1, v2) > 0) {
return true;
}
- for (unsigned int a = 0; a < mcoords_len - 1; a++) {
+ for (uint a = 0; a < mcoords_len - 1; a++) {
if (isect_seg_seg_v2_int(mcoords[a], mcoords[a + 1], v1, v2) > 0) {
return true;
}
diff --git a/source/blender/blenlib/intern/lazy_threading.cc b/source/blender/blenlib/intern/lazy_threading.cc
new file mode 100644
index 00000000000..4f6d3a75ecc
--- /dev/null
+++ b/source/blender/blenlib/intern/lazy_threading.cc
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BLI_lazy_threading.hh"
+#include "BLI_stack.hh"
+#include "BLI_vector.hh"
+
+namespace blender::lazy_threading {
+
+/**
+ * This uses a "raw" stack and vector so that it can be destructed after Blender checks for memory
+ * leaks. A new list of receivers is created whenever an isolated region is entered to avoid
+ * deadlocks.
+ */
+using HintReceivers = RawStack<RawVector<FunctionRef<void()>, 0>, 0>;
+thread_local HintReceivers hint_receivers = []() {
+ HintReceivers receivers;
+ /* Make sure there is always at least one vector. */
+ receivers.push_as();
+ return receivers;
+}();
+
+void send_hint()
+{
+ for (const FunctionRef<void()> &fn : hint_receivers.peek()) {
+ fn();
+ }
+}
+
+HintReceiver::HintReceiver(const FunctionRef<void()> fn)
+{
+ hint_receivers.peek().append(fn);
+}
+
+HintReceiver::~HintReceiver()
+{
+ hint_receivers.peek().pop_last();
+}
+
+ReceiverIsolation::ReceiverIsolation()
+{
+ hint_receivers.push_as();
+}
+
+ReceiverIsolation::~ReceiverIsolation()
+{
+ BLI_assert(hint_receivers.peek().is_empty());
+ hint_receivers.pop();
+}
+
+} // namespace blender::lazy_threading
diff --git a/source/blender/blenlib/intern/list_sort_impl.h b/source/blender/blenlib/intern/list_sort_impl.h
index e1b93986f4a..7c38fc60b29 100644
--- a/source/blender/blenlib/intern/list_sort_impl.h
+++ b/source/blender/blenlib/intern/list_sort_impl.h
@@ -47,24 +47,25 @@
#endif
#ifdef SORT_IMPL_USE_THUNK
-# define THUNK_APPEND1(a, thunk) a, thunk
-# define THUNK_PREPEND2(thunk, a, b) thunk, a, b
+# define BLI_LIST_THUNK_APPEND1(a, thunk) a, thunk
+# define BLI_LIST_THUNK_PREPEND2(thunk, a, b) thunk, a, b
#else
-# define THUNK_APPEND1(a, thunk) a
-# define THUNK_PREPEND2(thunk, a, b) a, b
+# define BLI_LIST_THUNK_APPEND1(a, thunk) a
+# define BLI_LIST_THUNK_PREPEND2(thunk, a, b) a, b
#endif
-#define _CONCAT_AUX(MACRO_ARG1, MACRO_ARG2) MACRO_ARG1##MACRO_ARG2
-#define _CONCAT(MACRO_ARG1, MACRO_ARG2) _CONCAT_AUX(MACRO_ARG1, MACRO_ARG2)
-#define _SORT_PREFIX(id) _CONCAT(SORT_IMPL_FUNC, _##id)
+#define _BLI_LIST_SORT_CONCAT_AUX(MACRO_ARG1, MACRO_ARG2) MACRO_ARG1##MACRO_ARG2
+#define _BLI_LIST_SORT_CONCAT(MACRO_ARG1, MACRO_ARG2) \
+ _BLI_LIST_SORT_CONCAT_AUX(MACRO_ARG1, MACRO_ARG2)
+#define _BLI_LIST_SORT_PREFIX(id) _BLI_LIST_SORT_CONCAT(SORT_IMPL_FUNC, _##id)
/* local identifiers */
-#define SortInfo _SORT_PREFIX(SortInfo)
-#define CompareFn _SORT_PREFIX(CompareFn)
-#define init_sort_info _SORT_PREFIX(init_sort_info)
-#define merge_lists _SORT_PREFIX(merge_lists)
-#define sweep_up _SORT_PREFIX(sweep_up)
-#define insert_list _SORT_PREFIX(insert_list)
+#define SortInfo _BLI_LIST_SORT_PREFIX(SortInfo)
+#define CompareFn _BLI_LIST_SORT_PREFIX(CompareFn)
+#define init_sort_info _BLI_LIST_SORT_PREFIX(init_sort_info)
+#define merge_lists _BLI_LIST_SORT_PREFIX(merge_lists)
+#define sweep_up _BLI_LIST_SORT_PREFIX(sweep_up)
+#define insert_list _BLI_LIST_SORT_PREFIX(insert_list)
typedef int (*CompareFn)(
#ifdef SORT_IMPL_USE_THUNK
@@ -159,7 +160,7 @@ BLI_INLINE list_node *merge_lists(list_node *first,
list_node *list = NULL;
list_node **pos = &list;
while (first && second) {
- if (func(THUNK_PREPEND2(thunk, SORT_ARG(first), SORT_ARG(second))) > 0) {
+ if (func(BLI_LIST_THUNK_PREPEND2(thunk, SORT_ARG(first), SORT_ARG(second))) > 0) {
*pos = second;
second = second->next;
}
@@ -181,7 +182,7 @@ BLI_INLINE list_node *sweep_up(struct SortInfo *si, list_node *list, unsigned in
{
unsigned int i;
for (i = si->min_rank; i < upto; i++) {
- list = merge_lists(si->ranks[i], list, THUNK_APPEND1(si->func, si->thunk));
+ list = merge_lists(si->ranks[i], list, BLI_LIST_THUNK_APPEND1(si->func, si->thunk));
si->ranks[i] = NULL;
}
return list;
@@ -225,17 +226,19 @@ BLI_INLINE void insert_list(struct SortInfo *si, list_node *list, unsigned int r
// printf("Rank '%d' should not exceed " STRINGIFY(MAX_RANKS), rank);
rank = MAX_RANKS;
}
- list = merge_lists(sweep_up(si, NULL, si->n_ranks), list, THUNK_APPEND1(si->func, si->thunk));
+ list = merge_lists(
+ sweep_up(si, NULL, si->n_ranks), list, BLI_LIST_THUNK_APPEND1(si->func, si->thunk));
for (i = si->n_ranks; i < rank; i++) {
si->ranks[i] = NULL;
}
}
else {
if (rank) {
- list = merge_lists(sweep_up(si, NULL, rank), list, THUNK_APPEND1(si->func, si->thunk));
+ list = merge_lists(
+ sweep_up(si, NULL, rank), list, BLI_LIST_THUNK_APPEND1(si->func, si->thunk));
}
for (i = rank; i < si->n_ranks && si->ranks[i]; i++) {
- list = merge_lists(si->ranks[i], list, THUNK_APPEND1(si->func, si->thunk));
+ list = merge_lists(si->ranks[i], list, BLI_LIST_THUNK_APPEND1(si->func, si->thunk));
si->ranks[i] = NULL;
}
}
@@ -281,7 +284,7 @@ BLI_INLINE list_node *list_sort_do(list_node *list,
list_node *next = list->next;
list_node *tail = next->next;
- if (func(THUNK_PREPEND2(thunk, SORT_ARG(list), SORT_ARG(next))) > 0) {
+ if (func(BLI_LIST_THUNK_PREPEND2(thunk, SORT_ARG(list), SORT_ARG(next))) > 0) {
next->next = list;
next = list;
list = list->next;
@@ -296,8 +299,8 @@ BLI_INLINE list_node *list_sort_do(list_node *list,
return sweep_up(&si, list, si.n_ranks);
}
-#undef _CONCAT_AUX
-#undef _CONCAT
+#undef _BLI_LIST_SORT_CONCAT_AUX
+#undef _BLI_LIST_SORT_CONCAT
#undef _SORT_PREFIX
#undef SortInfo
@@ -310,6 +313,6 @@ BLI_INLINE list_node *list_sort_do(list_node *list,
#undef list_node
#undef list_sort_do
-#undef THUNK_APPEND1
-#undef THUNK_PREPEND2
+#undef BLI_LIST_THUNK_APPEND1
+#undef BLI_LIST_THUNK_PREPEND2
#undef SORT_ARG
diff --git a/source/blender/blenlib/intern/math_base.c b/source/blender/blenlib/intern/math_base.c
index 257153dc6fe..8a791030fce 100644
--- a/source/blender/blenlib/intern/math_base.c
+++ b/source/blender/blenlib/intern/math_base.c
@@ -65,7 +65,7 @@ float floor_power_of_10(float f)
{
BLI_assert(!(f < 0.0f));
if (f != 0.0f) {
- return 1.0f / (powf(10.0f, ceilf(log10f(1.0f / f))));
+ return 1.0f / powf(10.0f, ceilf(log10f(1.0f / f)));
}
return 0.0f;
}
@@ -74,7 +74,7 @@ float ceil_power_of_10(float f)
{
BLI_assert(!(f < 0.0f));
if (f != 0.0f) {
- return 1.0f / (powf(10.0f, floorf(log10f(1.0f / f))));
+ return 1.0f / powf(10.0f, floorf(log10f(1.0f / f)));
}
return 0.0f;
}
diff --git a/source/blender/blenlib/intern/math_boolean.cc b/source/blender/blenlib/intern/math_boolean.cc
index 132d5dfda65..e5352540dd6 100644
--- a/source/blender/blenlib/intern/math_boolean.cc
+++ b/source/blender/blenlib/intern/math_boolean.cc
@@ -193,7 +193,7 @@ static RobustInitCaller init_caller;
y = b - bvirt
#define Fast_Two_Sum(a, b, x, y) \
- x = (double)(a + b); \
+ x = double(a + b); \
Fast_Two_Sum_Tail(a, b, x, y)
#define Fast_Two_Diff_Tail(a, b, x, y) \
@@ -205,30 +205,30 @@ static RobustInitCaller init_caller;
Fast_Two_Diff_Tail(a, b, x, y)
#define Two_Sum_Tail(a, b, x, y) \
- bvirt = (double)(x - a); \
+ bvirt = double(x - a); \
avirt = x - bvirt; \
bround = b - bvirt; \
around = a - avirt; \
y = around + bround
#define Two_Sum(a, b, x, y) \
- x = (double)(a + b); \
+ x = double(a + b); \
Two_Sum_Tail(a, b, x, y)
#define Two_Diff_Tail(a, b, x, y) \
- bvirt = (double)(a - x); \
+ bvirt = double(a - x); \
avirt = x + bvirt; \
bround = bvirt - b; \
around = a - avirt; \
y = around + bround
#define Two_Diff(a, b, x, y) \
- x = (double)(a - b); \
+ x = double(a - b); \
Two_Diff_Tail(a, b, x, y)
#define Split(a, ahi, alo) \
- c = (double)(splitter * a); \
- abig = (double)(c - a); \
+ c = double(splitter * a); \
+ abig = double(c - a); \
ahi = c - abig; \
alo = a - ahi
@@ -241,11 +241,11 @@ static RobustInitCaller init_caller;
y = (alo * blo) - err3
#define Two_Product(a, b, x, y) \
- x = (double)(a * b); \
+ x = double(a * b); \
Two_Product_Tail(a, b, x, y)
#define Two_Product_Presplit(a, b, bhi, blo, x, y) \
- x = (double)(a * b); \
+ x = double(a * b); \
Split(a, ahi, alo); \
err1 = x - (ahi * bhi); \
err2 = err1 - (alo * bhi); \
@@ -266,7 +266,7 @@ static RobustInitCaller init_caller;
y = (alo * alo) - err3
#define Square(a, x, y) \
- x = (double)(a * a); \
+ x = double(a * a); \
Square_Tail(a, x, y)
#define Two_One_Sum(a1, a0, b, x2, x1, x0) \
@@ -647,10 +647,10 @@ static double orient2dadapt(const double *pa, const double *pb, const double *pc
INEXACT double _i, _j;
double _0;
- acx = (double)(pa[0] - pc[0]);
- bcx = (double)(pb[0] - pc[0]);
- acy = (double)(pa[1] - pc[1]);
- bcy = (double)(pb[1] - pc[1]);
+ acx = double(pa[0] - pc[0]);
+ bcx = double(pb[0] - pc[0]);
+ acy = double(pa[1] - pc[1]);
+ bcy = double(pb[1] - pc[1]);
Two_Product(acx, bcy, detleft, detlefttail);
Two_Product(acy, bcx, detright, detrighttail);
@@ -834,15 +834,15 @@ static double orient3dadapt(
INEXACT double _i, _j, _k;
double _0;
- adx = (double)(pa[0] - pd[0]);
- bdx = (double)(pb[0] - pd[0]);
- cdx = (double)(pc[0] - pd[0]);
- ady = (double)(pa[1] - pd[1]);
- bdy = (double)(pb[1] - pd[1]);
- cdy = (double)(pc[1] - pd[1]);
- adz = (double)(pa[2] - pd[2]);
- bdz = (double)(pb[2] - pd[2]);
- cdz = (double)(pc[2] - pd[2]);
+ adx = double(pa[0] - pd[0]);
+ bdx = double(pb[0] - pd[0]);
+ cdx = double(pc[0] - pd[0]);
+ ady = double(pa[1] - pd[1]);
+ bdy = double(pb[1] - pd[1]);
+ cdy = double(pc[1] - pd[1]);
+ adz = double(pa[2] - pd[2]);
+ bdz = double(pb[2] - pd[2]);
+ cdz = double(pc[2] - pd[2]);
Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
@@ -1358,12 +1358,12 @@ static double incircleadapt(
INEXACT double _i, _j;
double _0;
- adx = (double)(pa[0] - pd[0]);
- bdx = (double)(pb[0] - pd[0]);
- cdx = (double)(pc[0] - pd[0]);
- ady = (double)(pa[1] - pd[1]);
- bdy = (double)(pb[1] - pd[1]);
- cdy = (double)(pc[1] - pd[1]);
+ adx = double(pa[0] - pd[0]);
+ bdx = double(pb[0] - pd[0]);
+ cdx = double(pc[0] - pd[0]);
+ ady = double(pa[1] - pd[1]);
+ bdy = double(pb[1] - pd[1]);
+ cdy = double(pc[1] - pd[1]);
Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
@@ -2191,18 +2191,18 @@ static double insphereadapt(const double *pa,
INEXACT double _i, _j;
double _0;
- aex = (double)(pa[0] - pe[0]);
- bex = (double)(pb[0] - pe[0]);
- cex = (double)(pc[0] - pe[0]);
- dex = (double)(pd[0] - pe[0]);
- aey = (double)(pa[1] - pe[1]);
- bey = (double)(pb[1] - pe[1]);
- cey = (double)(pc[1] - pe[1]);
- dey = (double)(pd[1] - pe[1]);
- aez = (double)(pa[2] - pe[2]);
- bez = (double)(pb[2] - pe[2]);
- cez = (double)(pc[2] - pe[2]);
- dez = (double)(pd[2] - pe[2]);
+ aex = double(pa[0] - pe[0]);
+ bex = double(pb[0] - pe[0]);
+ cex = double(pc[0] - pe[0]);
+ dex = double(pd[0] - pe[0]);
+ aey = double(pa[1] - pe[1]);
+ bey = double(pb[1] - pe[1]);
+ cey = double(pc[1] - pe[1]);
+ dey = double(pd[1] - pe[1]);
+ aez = double(pa[2] - pe[2]);
+ bez = double(pb[2] - pe[2]);
+ cez = double(pc[2] - pe[2]);
+ dez = double(pd[2] - pe[2]);
Two_Product(aex, bey, aexbey1, aexbey0);
Two_Product(bex, aey, bexaey1, bexaey0);
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index bdcf52ec521..51860c1abdb 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -176,7 +176,7 @@ void ycc_to_rgb(float y, float cb, float cr, float *r_r, float *r_g, float *r_b,
void hex_to_rgb(const char *hexcol, float *r_r, float *r_g, float *r_b)
{
- unsigned int ri, gi, bi;
+ uint ri, gi, bi;
if (hexcol[0] == '#') {
hexcol++;
@@ -329,29 +329,29 @@ void hsv_clamp_v(float hsv[3], float v_max)
CLAMP(hsv[2], 0.0f, v_max);
}
-unsigned int hsv_to_cpack(float h, float s, float v)
+uint hsv_to_cpack(float h, float s, float v)
{
- unsigned int r, g, b;
+ uint r, g, b;
float rf, gf, bf;
- unsigned int col;
+ uint col;
hsv_to_rgb(h, s, v, &rf, &gf, &bf);
- r = (unsigned int)(rf * 255.0f);
- g = (unsigned int)(gf * 255.0f);
- b = (unsigned int)(bf * 255.0f);
+ r = (uint)(rf * 255.0f);
+ g = (uint)(gf * 255.0f);
+ b = (uint)(bf * 255.0f);
col = (r + (g * 256) + (b * 256 * 256));
return col;
}
-unsigned int rgb_to_cpack(float r, float g, float b)
+uint rgb_to_cpack(float r, float g, float b)
{
- unsigned int ir, ig, ib;
+ uint ir, ig, ib;
- ir = (unsigned int)floorf(255.0f * max_ff(r, 0.0f));
- ig = (unsigned int)floorf(255.0f * max_ff(g, 0.0f));
- ib = (unsigned int)floorf(255.0f * max_ff(b, 0.0f));
+ ir = (uint)floorf(255.0f * max_ff(r, 0.0f));
+ ig = (uint)floorf(255.0f * max_ff(g, 0.0f));
+ ib = (uint)floorf(255.0f * max_ff(b, 0.0f));
if (ir > 255) {
ir = 255;
@@ -366,21 +366,21 @@ unsigned int rgb_to_cpack(float r, float g, float b)
return (ir + (ig * 256) + (ib * 256 * 256));
}
-void cpack_to_rgb(unsigned int col, float *r_r, float *r_g, float *r_b)
+void cpack_to_rgb(uint col, float *r_r, float *r_g, float *r_b)
{
- *r_r = ((float)(((col)) & 0xFF)) * (1.0f / 255.0f);
- *r_g = ((float)(((col) >> 8) & 0xFF)) * (1.0f / 255.0f);
- *r_b = ((float)(((col) >> 16) & 0xFF)) * (1.0f / 255.0f);
+ *r_r = (float)(col & 0xFF) * (1.0f / 255.0f);
+ *r_g = (float)((col >> 8) & 0xFF) * (1.0f / 255.0f);
+ *r_b = (float)((col >> 16) & 0xFF) * (1.0f / 255.0f);
}
-void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3])
+void rgb_uchar_to_float(float r_col[3], const uchar col_ub[3])
{
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 r_col[4], const unsigned char col_ub[4])
+void rgba_uchar_to_float(float r_col[4], const uchar col_ub[4])
{
r_col[0] = ((float)col_ub[0]) * (1.0f / 255.0f);
r_col[1] = ((float)col_ub[1]) * (1.0f / 255.0f);
@@ -388,12 +388,12 @@ void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4])
r_col[3] = ((float)col_ub[3]) * (1.0f / 255.0f);
}
-void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3])
+void rgb_float_to_uchar(uchar r_col[3], const float col_f[3])
{
unit_float_to_uchar_clamp_v3(r_col, col_f);
}
-void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
+void rgba_float_to_uchar(uchar r_col[4], const float col_f[4])
{
unit_float_to_uchar_clamp_v4(r_col, col_f);
}
@@ -500,7 +500,7 @@ void rgb_float_set_hue_float_offset(float rgb[3], float hue_offset)
hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb + 1, rgb + 2);
}
-void rgb_byte_set_hue_float_offset(unsigned char rgb[3], float hue_offset)
+void rgb_byte_set_hue_float_offset(uchar rgb[3], float hue_offset)
{
float rgb_float[3];
@@ -515,13 +515,13 @@ void rgb_byte_set_hue_float_offset(unsigned char rgb[3], float hue_offset)
*/
float BLI_color_from_srgb_table[256];
-unsigned short BLI_color_to_srgb_table[0x10000];
+ushort BLI_color_to_srgb_table[0x10000];
-static unsigned short hipart(const float f)
+static ushort hipart(const float f)
{
union {
float f;
- unsigned short us[2];
+ ushort us[2];
} tmp;
tmp.f = f;
@@ -533,12 +533,12 @@ static unsigned short hipart(const float f)
#endif
}
-static float index_to_float(const unsigned short i)
+static float index_to_float(const ushort i)
{
union {
float f;
- unsigned short us[2];
+ ushort us[2];
} tmp;
/* positive and negative zeros, and all gradual underflow, turn into zero: */
@@ -567,7 +567,7 @@ static float index_to_float(const unsigned short i)
void BLI_init_srgb_conversion(void)
{
static bool initialized = false;
- unsigned int i, b;
+ uint i, b;
if (initialized) {
return;
@@ -576,12 +576,12 @@ void BLI_init_srgb_conversion(void)
/* Fill in the lookup table to convert floats to bytes: */
for (i = 0; i < 0x10000; i++) {
- float f = linearrgb_to_srgb(index_to_float((unsigned short)i)) * 255.0f;
+ float f = linearrgb_to_srgb(index_to_float((ushort)i)) * 255.0f;
if (f <= 0) {
BLI_color_to_srgb_table[i] = 0;
}
else if (f < 255) {
- BLI_color_to_srgb_table[i] = (unsigned short)(f * 0x100 + 0.5f);
+ BLI_color_to_srgb_table[i] = (ushort)(f * 0x100 + 0.5f);
}
else {
BLI_color_to_srgb_table[i] = 0xff00;
@@ -594,6 +594,6 @@ void BLI_init_srgb_conversion(void)
BLI_color_from_srgb_table[b] = f;
i = hipart(f);
/* replace entries so byte->float->byte does not change the data: */
- BLI_color_to_srgb_table[i] = (unsigned short)(b * 0x100);
+ BLI_color_to_srgb_table[i] = (ushort)(b * 0x100);
}
}
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 773aac95193..08152976f7d 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -68,7 +68,7 @@ float normal_quad_v3(
return normalize_v3(n);
}
-float normal_poly_v3(float n[3], const float verts[][3], unsigned int nr)
+float normal_poly_v3(float n[3], const float verts[][3], uint nr)
{
cross_poly_v3(n, verts, nr);
return normalize_v3(n);
@@ -122,14 +122,14 @@ float area_tri_signed_v3(const float v1[3],
return area;
}
-float area_poly_v3(const float verts[][3], unsigned int nr)
+float area_poly_v3(const float verts[][3], uint nr)
{
float n[3];
cross_poly_v3(n, verts, nr);
return len_v3(n) * 0.5f;
}
-float area_squared_poly_v3(const float verts[][3], unsigned int nr)
+float area_squared_poly_v3(const float verts[][3], uint nr)
{
float n[3];
@@ -138,9 +138,9 @@ float area_squared_poly_v3(const float verts[][3], unsigned int nr)
return len_squared_v3(n);
}
-float cross_poly_v2(const float verts[][2], unsigned int nr)
+float cross_poly_v2(const float verts[][2], uint nr)
{
- unsigned int a;
+ uint a;
float cross;
const float *co_curr, *co_prev;
@@ -157,11 +157,11 @@ float cross_poly_v2(const float verts[][2], unsigned int nr)
return cross;
}
-void cross_poly_v3(float n[3], const float verts[][3], unsigned int nr)
+void cross_poly_v3(float n[3], const float verts[][3], uint nr)
{
const float *v_prev = verts[nr - 1];
const float *v_curr = verts[0];
- unsigned int i;
+ uint i;
zero_v3(n);
@@ -171,17 +171,17 @@ void cross_poly_v3(float n[3], const float verts[][3], unsigned int nr)
}
}
-float area_poly_v2(const float verts[][2], unsigned int nr)
+float area_poly_v2(const float verts[][2], uint nr)
{
return fabsf(0.5f * cross_poly_v2(verts, nr));
}
-float area_poly_signed_v2(const float verts[][2], unsigned int nr)
+float area_poly_signed_v2(const float verts[][2], uint nr)
{
return (0.5f * cross_poly_v2(verts, nr));
}
-float area_squared_poly_v2(const float verts[][2], unsigned int nr)
+float area_squared_poly_v2(const float verts[][2], uint nr)
{
float area = area_poly_signed_v2(verts, nr);
return area * area;
@@ -527,7 +527,7 @@ float dist_signed_squared_to_corner_v3v3v3(const float p[3],
cross_v3_v3v3(axis, dir_a, dir_b);
- if ((len_squared_v3(axis) < FLT_EPSILON)) {
+ if (len_squared_v3(axis) < FLT_EPSILON) {
copy_v3_v3(axis, axis_ref);
}
else if (dot_v3v3(axis, axis_ref) < 0.0f) {
@@ -1458,12 +1458,12 @@ int isect_line_sphere_v2(const float l1[2],
bool isect_point_poly_v2(const float pt[2],
const float verts[][2],
- const unsigned int nr,
+ const uint nr,
const bool UNUSED(use_holes))
{
/* Keep in sync with #isect_point_poly_v2_int. */
- unsigned int i, j;
+ uint i, j;
bool isect = false;
for (i = 0, j = nr - 1; i < nr; j = i++) {
if (((verts[i][1] > pt[1]) != (verts[j][1] > pt[1])) &&
@@ -1477,12 +1477,12 @@ bool isect_point_poly_v2(const float pt[2],
}
bool isect_point_poly_v2_int(const int pt[2],
const int verts[][2],
- const unsigned int nr,
+ const uint nr,
const bool UNUSED(use_holes))
{
/* Keep in sync with #isect_point_poly_v2. */
- unsigned int i, j;
+ uint i, j;
bool isect = false;
for (i = 0, j = nr - 1; i < nr; j = i++) {
if (((verts[i][1] > pt[1]) != (verts[j][1] > pt[1])) &&
@@ -2208,7 +2208,7 @@ bool isect_planes_v3_fn(
int i_test;
for (i_test = 0; i_test < planes_len; i_test++) {
const float *np_test = planes[i_test];
- if (((dot_v3v3(np_test, co_test) + np_test[3]) > eps_isect)) {
+ if ((dot_v3v3(np_test, co_test) + np_test[3]) > eps_isect) {
/* For low epsilon values the point could intersect its own plane. */
if (!ELEM(i_test, i, j, k)) {
break;
@@ -2696,7 +2696,7 @@ bool isect_sweeping_sphere_tri_v3(const float p1[3],
z = x + y - (a * c - b * b);
if (z <= 0.0f && (x >= 0.0f && y >= 0.0f)) {
- //(((unsigned int)z)& ~(((unsigned int)x)|((unsigned int)y))) & 0x80000000) {
+ //(((uint)z)& ~(((uint)x)|((uint)y))) & 0x80000000) {
*r_lambda = t0;
copy_v3_v3(ipoint, point);
return true;
@@ -2748,7 +2748,7 @@ bool isect_sweeping_sphere_tri_v3(const float p1[3],
edotv = dot_v3v3(e1, vel);
edotbv = dot_v3v3(e1, bv);
- a = elen2 * (-dot_v3v3(vel, vel)) + edotv * edotv;
+ a = elen2 * -dot_v3v3(vel, vel) + edotv * edotv;
b = 2.0f * (elen2 * dot_v3v3(vel, bv) - edotv * edotbv);
c = elen2 * (radius2 - dot_v3v3(bv, bv)) + edotbv * edotbv;
@@ -2770,7 +2770,7 @@ bool isect_sweeping_sphere_tri_v3(const float p1[3],
edotv = dot_v3v3(e2, vel);
edotbv = dot_v3v3(e2, bv);
- a = elen2 * (-dot_v3v3(vel, vel)) + edotv * edotv;
+ a = elen2 * -dot_v3v3(vel, vel) + edotv * edotv;
b = 2.0f * (elen2 * dot_v3v3(vel, bv) - edotv * edotbv);
c = elen2 * (radius2 - dot_v3v3(bv, bv)) + edotbv * edotbv;
@@ -2797,7 +2797,7 @@ bool isect_sweeping_sphere_tri_v3(const float p1[3],
edotv = dot_v3v3(e3, vel);
edotbv = dot_v3v3(e3, bv);
- a = elen2 * (-dot_v3v3(vel, vel)) + edotv * edotv;
+ a = elen2 * -dot_v3v3(vel, vel) + edotv * edotv;
b = 2.0f * (elen2 * dot_v3v3(vel, bv) - edotv * edotbv);
c = elen2 * (radius2 - dot_v3v3(bv, bv)) + edotbv * edotbv;
@@ -5803,10 +5803,10 @@ bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2],
return (isect_seg_seg_v2(v1, v3, v2, v4) > 0);
}
-bool is_poly_convex_v2(const float verts[][2], unsigned int nr)
+bool is_poly_convex_v2(const float verts[][2], uint nr)
{
- unsigned int sign_flag = 0;
- unsigned int a;
+ uint sign_flag = 0;
+ uint a;
const float *co_curr, *co_prev;
float dir_curr[2], dir_prev[2];
diff --git a/source/blender/blenlib/intern/math_interp.c b/source/blender/blenlib/intern/math_interp.c
index 34fcb583232..29907924bd8 100644
--- a/source/blender/blenlib/intern/math_interp.c
+++ b/source/blender/blenlib/intern/math_interp.c
@@ -56,7 +56,7 @@ static void vector_from_float(const float *data, float vector[4], int components
}
}
-static void vector_from_byte(const unsigned char *data, float vector[4], int components)
+static void vector_from_byte(const uchar *data, float vector[4], int components)
{
if (components == 1) {
vector[0] = data[0];
@@ -75,9 +75,9 @@ static void vector_from_byte(const unsigned char *data, float vector[4], int com
}
/* BICUBIC INTERPOLATION */
-BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer,
+BLI_INLINE void bicubic_interpolation(const uchar *byte_buffer,
const float *float_buffer,
- unsigned char *byte_output,
+ uchar *byte_output,
float *float_output,
int width,
int height,
@@ -135,7 +135,7 @@ BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer,
vector_from_float(float_data, data, components);
}
else {
- const unsigned char *byte_data = byte_buffer + width * y1 * components + components * x1;
+ const uchar *byte_data = byte_buffer + width * y1 * components + components * x1;
vector_from_byte(byte_data, data, components);
}
@@ -174,7 +174,7 @@ BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer,
vector_from_float(float_data, data, components);
}
else {
- const unsigned char *byte_data = byte_buffer + width * y1 * components + components * x1;
+ const uchar *byte_data = byte_buffer + width * y1 * components + components * x1;
vector_from_byte(byte_data, data, components);
}
@@ -211,18 +211,18 @@ BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer,
}
else {
if (components == 1) {
- byte_output[0] = (unsigned char)(out[0] + 0.5f);
+ byte_output[0] = (uchar)(out[0] + 0.5f);
}
else if (components == 3) {
- byte_output[0] = (unsigned char)(out[0] + 0.5f);
- byte_output[1] = (unsigned char)(out[1] + 0.5f);
- byte_output[2] = (unsigned char)(out[2] + 0.5f);
+ byte_output[0] = (uchar)(out[0] + 0.5f);
+ byte_output[1] = (uchar)(out[1] + 0.5f);
+ byte_output[2] = (uchar)(out[2] + 0.5f);
}
else {
- byte_output[0] = (unsigned char)(out[0] + 0.5f);
- byte_output[1] = (unsigned char)(out[1] + 0.5f);
- byte_output[2] = (unsigned char)(out[2] + 0.5f);
- byte_output[3] = (unsigned char)(out[3] + 0.5f);
+ byte_output[0] = (uchar)(out[0] + 0.5f);
+ byte_output[1] = (uchar)(out[1] + 0.5f);
+ byte_output[2] = (uchar)(out[2] + 0.5f);
+ byte_output[3] = (uchar)(out[3] + 0.5f);
}
}
}
@@ -233,21 +233,16 @@ void BLI_bicubic_interpolation_fl(
bicubic_interpolation(NULL, buffer, NULL, output, width, height, components, u, v);
}
-void BLI_bicubic_interpolation_char(const unsigned char *buffer,
- unsigned char *output,
- int width,
- int height,
- int components,
- float u,
- float v)
+void BLI_bicubic_interpolation_char(
+ const uchar *buffer, uchar *output, int width, int height, int components, float u, float v)
{
bicubic_interpolation(buffer, NULL, output, NULL, width, height, components, u, v);
}
/* BILINEAR INTERPOLATION */
-BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer,
+BLI_INLINE void bilinear_interpolation(const uchar *byte_buffer,
const float *float_buffer,
- unsigned char *byte_output,
+ uchar *byte_output,
float *float_output,
int width,
int height,
@@ -351,8 +346,8 @@ BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer,
}
}
else {
- const unsigned char *row1, *row2, *row3, *row4;
- unsigned char empty[4] = {0, 0, 0, 0};
+ const uchar *row1, *row2, *row3, *row4;
+ uchar empty[4] = {0, 0, 0, 0};
/* pixel value must be already wrapped, however values at boundaries may flip */
if (wrap_x) {
@@ -418,26 +413,26 @@ BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer,
ma_mb = (1.0f - a) * (1.0f - b);
if (components == 1) {
- byte_output[0] = (unsigned char)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] +
- a_b * row4[0] + 0.5f);
+ byte_output[0] = (uchar)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0] +
+ 0.5f);
}
else if (components == 3) {
- byte_output[0] = (unsigned char)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] +
- a_b * row4[0] + 0.5f);
- byte_output[1] = (unsigned char)(ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] +
- a_b * row4[1] + 0.5f);
- byte_output[2] = (unsigned char)(ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] +
- a_b * row4[2] + 0.5f);
+ byte_output[0] = (uchar)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0] +
+ 0.5f);
+ byte_output[1] = (uchar)(ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1] +
+ 0.5f);
+ byte_output[2] = (uchar)(ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2] +
+ 0.5f);
}
else {
- byte_output[0] = (unsigned char)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] +
- a_b * row4[0] + 0.5f);
- byte_output[1] = (unsigned char)(ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] +
- a_b * row4[1] + 0.5f);
- byte_output[2] = (unsigned char)(ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] +
- a_b * row4[2] + 0.5f);
- byte_output[3] = (unsigned char)(ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] +
- a_b * row4[3] + 0.5f);
+ byte_output[0] = (uchar)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0] +
+ 0.5f);
+ byte_output[1] = (uchar)(ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1] +
+ 0.5f);
+ byte_output[2] = (uchar)(ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2] +
+ 0.5f);
+ byte_output[3] = (uchar)(ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] + a_b * row4[3] +
+ 0.5f);
}
}
}
@@ -449,13 +444,8 @@ void BLI_bilinear_interpolation_fl(
NULL, buffer, NULL, output, width, height, components, u, v, false, false);
}
-void BLI_bilinear_interpolation_char(const unsigned char *buffer,
- unsigned char *output,
- int width,
- int height,
- int components,
- float u,
- float v)
+void BLI_bilinear_interpolation_char(
+ const uchar *buffer, uchar *output, int width, int height, int components, float u, float v)
{
bilinear_interpolation(
buffer, NULL, output, NULL, width, height, components, u, v, false, false);
@@ -475,8 +465,8 @@ void BLI_bilinear_interpolation_wrap_fl(const float *buffer,
NULL, buffer, NULL, output, width, height, components, u, v, wrap_x, wrap_y);
}
-void BLI_bilinear_interpolation_wrap_char(const unsigned char *buffer,
- unsigned char *output,
+void BLI_bilinear_interpolation_wrap_char(const uchar *buffer,
+ uchar *output,
int width,
int height,
int components,
@@ -634,10 +624,10 @@ void BLI_ewa_filter(const int width,
U0 = uv[0] * (float)width;
V0 = uv[1] * (float)height;
- u1 = (int)(floorf(U0 - ue));
- u2 = (int)(ceilf(U0 + ue));
- v1 = (int)(floorf(V0 - ve));
- v2 = (int)(ceilf(V0 + ve));
+ u1 = (int)floorf(U0 - ue);
+ u2 = (int)ceilf(U0 + ue);
+ v1 = (int)floorf(V0 - ve);
+ v2 = (int)ceilf(V0 + ve);
/* sane clamping to avoid unnecessarily huge loops */
/* NOTE: if eccentricity gets clamped (see above),
@@ -679,7 +669,7 @@ void BLI_ewa_filter(const int width,
for (u = u1; u <= u2; u++) {
if (Q < (float)(EWA_MAXIDX + 1)) {
float tc[4];
- const float wt = EWA_WTS[(Q < 0.0f) ? 0 : (unsigned int)Q];
+ const float wt = EWA_WTS[(Q < 0.0f) ? 0 : (uint)Q];
read_pixel_cb(userdata, u, v, tc);
madd_v3_v3fl(result, tc, wt);
result[3] += use_alpha ? tc[3] * wt : 0.0f;
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index 221ae84e74d..d997eae26fb 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -3116,6 +3116,34 @@ bool has_zero_axis_m4(const float matrix[4][4])
len_squared_v3(matrix[2]) < FLT_EPSILON;
}
+void zero_axis_bias_m4(float mat[4][4])
+{
+ const bool axis_x_degenerate = len_squared_v3(mat[0]) < FLT_EPSILON;
+ const bool axis_y_degenerate = len_squared_v3(mat[1]) < FLT_EPSILON;
+ const bool axis_z_degenerate = len_squared_v3(mat[2]) < FLT_EPSILON;
+
+ /* X Axis. */
+ if (axis_x_degenerate && !axis_y_degenerate && !axis_z_degenerate) {
+ cross_v3_v3v3(mat[0], mat[1], mat[2]);
+ mul_v3_fl(mat[0], FLT_EPSILON);
+ return;
+ }
+
+ /* Y Axis. */
+ if (!axis_x_degenerate && axis_y_degenerate && !axis_z_degenerate) {
+ cross_v3_v3v3(mat[1], mat[2], mat[0]);
+ mul_v3_fl(mat[1], FLT_EPSILON);
+ return;
+ }
+
+ /* Z Axis. */
+ if (!axis_x_degenerate && !axis_y_degenerate && axis_z_degenerate) {
+ cross_v3_v3v3(mat[2], mat[0], mat[1]);
+ mul_v3_fl(mat[2], FLT_EPSILON);
+ return;
+ }
+}
+
void invert_m4_m4_safe(float inverse[4][4], const float mat[4][4])
{
if (!invert_m4_m4(inverse, mat)) {
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index ae068e3fb19..180412c4a14 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -275,64 +275,83 @@ void mat3_normalized_to_quat_fast(float q[4], const float mat[3][3])
/* Caller must ensure matrices aren't negative for valid results, see: T24291, T94231. */
BLI_assert(!is_negative_m3(mat));
- /* Check the trace of the matrix - bad precision if close to -1. */
- const float trace = mat[0][0] + mat[1][1] + mat[2][2];
-
- if (trace > 0) {
- float s = 2.0f * sqrtf(1.0f + trace);
-
- q[0] = 0.25f * s;
-
- s = 1.0f / s;
-
- q[1] = (mat[1][2] - mat[2][1]) * s;
- q[2] = (mat[2][0] - mat[0][2]) * s;
- q[3] = (mat[0][1] - mat[1][0]) * s;
- }
- else {
- /* Find the biggest diagonal element to choose the best formula.
- * Here trace should also be always >= 0, avoiding bad precision. */
- if (mat[0][0] > mat[1][1] && mat[0][0] > mat[2][2]) {
- float s = 2.0f * sqrtf(1.0f + mat[0][0] - mat[1][1] - mat[2][2]);
-
+ /* Method outlined by Mike Day, ref: https://math.stackexchange.com/a/3183435/220949
+ * with an additional `sqrtf(..)` for higher precision result.
+ * Removing the `sqrt` causes tests to fail unless the precision is set to 1e-6 or larger. */
+
+ if (mat[2][2] < 0.0f) {
+ if (mat[0][0] > mat[1][1]) {
+ const float trace = 1.0f + mat[0][0] - mat[1][1] - mat[2][2];
+ float s = 2.0f * sqrtf(trace);
+ if (mat[1][2] < mat[2][1]) {
+ /* Ensure W is non-negative for a canonical result. */
+ s = -s;
+ }
q[1] = 0.25f * s;
-
s = 1.0f / s;
-
q[0] = (mat[1][2] - mat[2][1]) * s;
- q[2] = (mat[1][0] + mat[0][1]) * s;
+ q[2] = (mat[0][1] + mat[1][0]) * s;
q[3] = (mat[2][0] + mat[0][2]) * s;
+ if (UNLIKELY((trace == 1.0f) && (q[0] == 0.0f && q[2] == 0.0f && q[3] == 0.0f))) {
+ /* Avoids the need to normalize the degenerate case. */
+ q[1] = 1.0f;
+ }
}
- else if (mat[1][1] > mat[2][2]) {
- float s = 2.0f * sqrtf(1.0f + mat[1][1] - mat[0][0] - mat[2][2]);
-
+ else {
+ const float trace = 1.0f - mat[0][0] + mat[1][1] - mat[2][2];
+ float s = 2.0f * sqrtf(trace);
+ if (mat[2][0] < mat[0][2]) {
+ /* Ensure W is non-negative for a canonical result. */
+ s = -s;
+ }
q[2] = 0.25f * s;
-
s = 1.0f / s;
-
q[0] = (mat[2][0] - mat[0][2]) * s;
- q[1] = (mat[1][0] + mat[0][1]) * s;
- q[3] = (mat[2][1] + mat[1][2]) * s;
+ q[1] = (mat[0][1] + mat[1][0]) * s;
+ q[3] = (mat[1][2] + mat[2][1]) * s;
+ if (UNLIKELY((trace == 1.0f) && (q[0] == 0.0f && q[1] == 0.0f && q[3] == 0.0f))) {
+ /* Avoids the need to normalize the degenerate case. */
+ q[2] = 1.0f;
+ }
}
- else {
- float s = 2.0f * sqrtf(1.0f + mat[2][2] - mat[0][0] - mat[1][1]);
-
+ }
+ else {
+ if (mat[0][0] < -mat[1][1]) {
+ const float trace = 1.0f - mat[0][0] - mat[1][1] + mat[2][2];
+ float s = 2.0f * sqrtf(trace);
+ if (mat[0][1] < mat[1][0]) {
+ /* Ensure W is non-negative for a canonical result. */
+ s = -s;
+ }
q[3] = 0.25f * s;
-
s = 1.0f / s;
-
q[0] = (mat[0][1] - mat[1][0]) * s;
q[1] = (mat[2][0] + mat[0][2]) * s;
- q[2] = (mat[2][1] + mat[1][2]) * s;
+ q[2] = (mat[1][2] + mat[2][1]) * s;
+ if (UNLIKELY((trace == 1.0f) && (q[0] == 0.0f && q[1] == 0.0f && q[2] == 0.0f))) {
+ /* Avoids the need to normalize the degenerate case. */
+ q[3] = 1.0f;
+ }
}
-
- /* Make sure W is non-negative for a canonical result. */
- if (q[0] < 0) {
- negate_v4(q);
+ else {
+ /* NOTE(@campbellbarton): A zero matrix will fall through to this block,
+ * needed so a zero scaled matrices to return a quaternion without rotation, see: T101848. */
+ const float trace = 1.0f + mat[0][0] + mat[1][1] + mat[2][2];
+ float s = 2.0f * sqrtf(trace);
+ q[0] = 0.25f * s;
+ s = 1.0f / s;
+ q[1] = (mat[1][2] - mat[2][1]) * s;
+ q[2] = (mat[2][0] - mat[0][2]) * s;
+ q[3] = (mat[0][1] - mat[1][0]) * s;
+ if (UNLIKELY((trace == 1.0f) && (q[1] == 0.0f && q[2] == 0.0f && q[3] == 0.0f))) {
+ /* Avoids the need to normalize the degenerate case. */
+ q[0] = 1.0f;
+ }
}
}
- normalize_qt(q);
+ BLI_assert(!(q[0] < 0.0f));
+ BLI_ASSERT_UNIT_QUAT(q);
}
static void mat3_normalized_to_quat_with_checks(float q[4], float mat[3][3])
@@ -1477,7 +1496,7 @@ void compatible_eul(float eul[3], const float oldrot[3])
const float pi_x2 = (2.0f * (float)M_PI);
float deul[3];
- unsigned int i;
+ uint i;
/* correct differences of about 360 degrees first */
for (i = 0; i < 3; i++) {
@@ -2178,8 +2197,8 @@ void quat_apply_track(float quat[4], short axis, short upflag)
* up axis is used X->Y, Y->X, Z->X, if this first up axis isn't used then rotate 90d
* the strange bit shift below just find the low axis {X:Y, Y:X, Z:X} */
if (upflag != (2 - axis) >> 1) {
- float q[4] = {sqrt_1_2, 0.0, 0.0, 0.0}; /* assign 90d rotation axis */
- q[axis + 1] = ((axis == 1)) ? sqrt_1_2 : -sqrt_1_2; /* flip non Y axis */
+ float q[4] = {sqrt_1_2, 0.0, 0.0, 0.0}; /* assign 90d rotation axis */
+ q[axis + 1] = (axis == 1) ? sqrt_1_2 : -sqrt_1_2; /* flip non Y axis */
mul_qt_qtqt(quat, quat, q);
}
}
@@ -2360,8 +2379,8 @@ bool mat3_from_axis_conversion(
value = ((src_forward << (0 * 3)) | (src_up << (1 * 3)) | (dst_forward << (2 * 3)) |
(dst_up << (3 * 3)));
- for (uint i = 0; i < (ARRAY_SIZE(_axis_convert_matrix)); i++) {
- for (uint j = 0; j < (ARRAY_SIZE(*_axis_convert_lut)); j++) {
+ for (uint i = 0; i < ARRAY_SIZE(_axis_convert_matrix); i++) {
+ for (uint j = 0; j < ARRAY_SIZE(*_axis_convert_lut); j++) {
if (_axis_convert_lut[i][j] == value) {
copy_m3_m3(r_mat, _axis_convert_matrix[i]);
return true;
diff --git a/source/blender/blenlib/intern/math_solvers.c b/source/blender/blenlib/intern/math_solvers.c
index b5650410a70..1196c0bed7f 100644
--- a/source/blender/blenlib/intern/math_solvers.c
+++ b/source/blender/blenlib/intern/math_solvers.c
@@ -45,7 +45,7 @@ bool BLI_tridiagonal_solve(
return false;
}
- size_t bytes = sizeof(double) * (unsigned)count;
+ size_t bytes = sizeof(double) * (uint)count;
double *c1 = (double *)MEM_mallocN(bytes * 2, "tridiagonal_c1d1");
double *d1 = c1 + count;
@@ -112,7 +112,7 @@ bool BLI_tridiagonal_solve_cyclic(
return BLI_tridiagonal_solve(a, b, c, d, r_x, count);
}
- size_t bytes = sizeof(float) * (unsigned)count;
+ size_t bytes = sizeof(float) * (uint)count;
float *tmp = (float *)MEM_mallocN(bytes * 2, "tridiagonal_ex");
float *b2 = tmp + count;
diff --git a/source/blender/blenlib/intern/math_vec.cc b/source/blender/blenlib/intern/math_vec.cc
index 99c873299fe..8d1f850d8e5 100644
--- a/source/blender/blenlib/intern/math_vec.cc
+++ b/source/blender/blenlib/intern/math_vec.cc
@@ -108,7 +108,7 @@ isect_result<mpq2> isect_seg_seg(const mpq2 &v1, const mpq2 &v2, const mpq2 &v3,
uint64_t hash_mpq_class(const mpq_class &value)
{
/* TODO: better/faster implementation of this. */
- return get_default_hash(static_cast<float>(value.get_d()));
+ return get_default_hash(float(value.get_d()));
}
#endif
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index 5dcdabaf760..f65a5acceae 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -499,7 +499,7 @@ float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const f
/* calculate the sign (reuse 'tproj') */
cross_v3_v3v3(tproj, v2_proj, v1_proj);
if (dot_v3v3(tproj, axis) < 0.0f) {
- angle = ((float)(M_PI * 2.0)) - angle;
+ angle = (float)(M_PI * 2.0) - angle;
}
return angle;
diff --git a/source/blender/blenlib/intern/mesh_boolean.cc b/source/blender/blenlib/intern/mesh_boolean.cc
index 0d8ad1da582..3efe62d2984 100644
--- a/source/blender/blenlib/intern/mesh_boolean.cc
+++ b/source/blender/blenlib/intern/mesh_boolean.cc
@@ -2527,7 +2527,7 @@ class InsideShapeTestData {
static void inside_shape_callback(void *userdata,
int index,
const BVHTreeRay *ray,
- BVHTreeRayHit *UNUSED(hit))
+ BVHTreeRayHit * /*hit*/)
{
const int dbg_level = 0;
if (dbg_level > 0) {
diff --git a/source/blender/blenlib/intern/mesh_intersect.cc b/source/blender/blenlib/intern/mesh_intersect.cc
index e8aa359fbe4..ee29662698a 100644
--- a/source/blender/blenlib/intern/mesh_intersect.cc
+++ b/source/blender/blenlib/intern/mesh_intersect.cc
@@ -829,13 +829,13 @@ struct BBPadData {
static void pad_face_bb_range_func(void *__restrict userdata,
const int iter,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
BBPadData *pad_data = static_cast<BBPadData *>(userdata);
(*pad_data->face_bounding_box)[iter].expand(pad_data->pad);
}
-static void calc_face_bb_reduce(const void *__restrict UNUSED(userdata),
+static void calc_face_bb_reduce(const void *__restrict /*userdata*/,
void *__restrict chunk_join,
void *__restrict chunk)
{
@@ -2032,10 +2032,10 @@ static Array<Face *> polyfill_triangulate_poly(Face *f, IMeshArena *arena)
}
/* Project along negative face normal so (x,y) can be used in 2d. */ float axis_mat[3][3];
float(*projverts)[2];
- unsigned int(*tris)[3];
+ uint(*tris)[3];
const int totfilltri = flen - 2;
/* Prepare projected vertices and array to receive triangles in tessellation. */
- tris = static_cast<unsigned int(*)[3]>(MEM_malloc_arrayN(totfilltri, sizeof(*tris), __func__));
+ tris = static_cast<uint(*)[3]>(MEM_malloc_arrayN(totfilltri, sizeof(*tris), __func__));
projverts = static_cast<float(*)[2]>(MEM_malloc_arrayN(flen, sizeof(*projverts), __func__));
axis_dominant_v3_to_m3_negate(axis_mat, no);
for (int j = 0; j < flen; ++j) {
@@ -2047,7 +2047,7 @@ static Array<Face *> polyfill_triangulate_poly(Face *f, IMeshArena *arena)
/* Put tessellation triangles into Face form. Record original edges where they exist. */
Array<Face *> ans(totfilltri);
for (int t = 0; t < totfilltri; ++t) {
- unsigned int *tri = tris[t];
+ uint *tri = tris[t];
int eo[3];
const Vert *v[3];
for (int k = 0; k < 3; k++) {
@@ -2419,7 +2419,7 @@ class TriOverlaps {
}
}
first_overlap_ = Array<int>(tm.face_size(), -1);
- for (int i = 0; i < static_cast<int>(overlap_num_); ++i) {
+ for (int i = 0; i < int(overlap_num_); ++i) {
int t = overlap_[i].indexA;
if (first_overlap_[t] == -1) {
first_overlap_[t] = i;
@@ -2451,7 +2451,7 @@ class TriOverlaps {
}
private:
- static bool only_different_shapes(void *userdata, int index_a, int index_b, int UNUSED(thread))
+ static bool only_different_shapes(void *userdata, int index_a, int index_b, int /*thread*/)
{
CBData *cbdata = static_cast<CBData *>(userdata);
return cbdata->tm.face(index_a)->orig != cbdata->tm.face(index_b)->orig;
@@ -2487,7 +2487,7 @@ static std::pair<int, int> canon_int_pair(int a, int b)
static void calc_overlap_itts_range_func(void *__restrict userdata,
const int iter,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
constexpr int dbg_level = 0;
OverlapIttsData *data = static_cast<OverlapIttsData *>(userdata);
@@ -2682,7 +2682,7 @@ static CDT_data calc_cluster_subdivided(const CoplanarClusterInfo &clinfo,
const IMesh &tm,
const TriOverlaps &ov,
const Map<std::pair<int, int>, ITT_value> &itt_map,
- IMeshArena *UNUSED(arena))
+ IMeshArena * /*arena*/)
{
constexpr int dbg_level = 0;
BLI_assert(c < clinfo.tot_cluster());
@@ -2889,7 +2889,7 @@ static void degenerate_range_func(void *__restrict userdata,
chunk_data->has_degenerate_tri |= is_degenerate;
}
-static void degenerate_reduce(const void *__restrict UNUSED(userdata),
+static void degenerate_reduce(const void *__restrict /*userdata*/,
void *__restrict chunk_join,
void *__restrict chunk)
{
@@ -2931,7 +2931,7 @@ static IMesh remove_degenerate_tris(const IMesh &tm_in)
IMesh trimesh_self_intersect(const IMesh &tm_in, IMeshArena *arena)
{
return trimesh_nary_intersect(
- tm_in, 1, [](int UNUSED(t)) { return 0; }, true, arena);
+ tm_in, 1, [](int /*t*/) { return 0; }, true, arena);
}
IMesh trimesh_nary_intersect(const IMesh &tm_in,
diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c
index 3ec7c3f9804..8da35e5ab56 100644
--- a/source/blender/blenlib/intern/noise.c
+++ b/source/blender/blenlib/intern/noise.c
@@ -115,8 +115,8 @@ static const float hashpntf[768] = {
0.713870, 0.555261, 0.951333,
};
-extern const unsigned char BLI_noise_hash_uchar_512[512]; /* Quiet warning. */
-const unsigned char BLI_noise_hash_uchar_512[512] = {
+extern const uchar BLI_noise_hash_uchar_512[512]; /* Quiet warning. */
+const uchar BLI_noise_hash_uchar_512[512] = {
0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE,
0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32,
0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7,
@@ -939,9 +939,9 @@ void BLI_noise_voronoi(float x, float y, float z, float *da, float *pa, float me
break;
}
- int xi = (int)(floor(x));
- int yi = (int)(floor(y));
- int zi = (int)(floor(z));
+ int xi = (int)floor(x);
+ int yi = (int)floor(y);
+ int zi = (int)floor(z);
da[0] = da[1] = da[2] = da[3] = 1e10f;
for (int xx = xi - 1; xx <= xi + 1; xx++) {
for (int yy = yi - 1; yy <= yi + 1; yy++) {
@@ -1112,10 +1112,10 @@ static float BLI_cellNoiseU(float x, float y, float z)
y = (y + 0.000001f) * 1.00001f;
z = (z + 0.000001f) * 1.00001f;
- int xi = (int)(floor(x));
- int yi = (int)(floor(y));
- int zi = (int)(floor(z));
- unsigned int n = xi + yi * 1301 + zi * 314159;
+ int xi = (int)floor(x);
+ int yi = (int)floor(y);
+ int zi = (int)floor(z);
+ uint n = xi + yi * 1301 + zi * 314159;
n ^= (n << 13);
return ((float)(n * (n * n * 15731 + 789221) + 1376312589) / 4294967296.0f);
}
@@ -1132,9 +1132,9 @@ void BLI_noise_cell_v3(float x, float y, float z, float r_ca[3])
y = (y + 0.000001f) * 1.00001f;
z = (z + 0.000001f) * 1.00001f;
- int xi = (int)(floor(x));
- int yi = (int)(floor(y));
- int zi = (int)(floor(z));
+ int xi = (int)floor(x);
+ int yi = (int)floor(y);
+ int zi = (int)floor(z);
const float *p = HASHPNT(xi, yi, zi);
r_ca[0] = p[0];
r_ca[1] = p[1];
@@ -1329,8 +1329,8 @@ float BLI_noise_mg_fbm(
float BLI_noise_mg_multi_fractal(
float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis)
{
- /* This one is in fact rather confusing,
- * there seem to be errors in the original source code (in all three versions of proc.text&mod),
+ /* This one is in fact rather confusing, there seem to be errors in the original source code
+ * (in all three versions of `proc.text & mod`),
* I modified it to something that made sense to me, so it might be wrong. */
float (*noisefunc)(float, float, float);
diff --git a/source/blender/blenlib/intern/noise.cc b/source/blender/blenlib/intern/noise.cc
index 8a073239b31..65a6f102a7b 100644
--- a/source/blender/blenlib/intern/noise.cc
+++ b/source/blender/blenlib/intern/noise.cc
@@ -150,7 +150,7 @@ uint32_t hash_float(float4 k)
BLI_INLINE float uint_to_float_01(uint32_t k)
{
- return static_cast<float>(k) / static_cast<float>(0xFFFFFFFFu);
+ return float(k) / float(0xFFFFFFFFu);
}
float hash_to_float(uint32_t kx)
@@ -379,7 +379,7 @@ BLI_INLINE float noise_grad(uint32_t hash, float x, float y, float z, float w)
BLI_INLINE float floor_fraction(float x, int &i)
{
- i = (int)x - ((x < 0) ? 1 : 0);
+ i = int(x) - ((x < 0) ? 1 : 0);
return x - i;
}
@@ -536,7 +536,7 @@ template<typename T> float perlin_fractal_template(T position, float octaves, fl
float maxamp = 0.0f;
float sum = 0.0f;
octaves = CLAMPIS(octaves, 0.0f, 15.0f);
- int n = static_cast<int>(octaves);
+ int n = int(octaves);
for (int i = 0; i <= n; i++) {
float t = perlin(fscale * position);
sum += t * amp;
@@ -729,7 +729,7 @@ float musgrave_fBm(const float co,
const float pwHL = std::pow(lacunarity, -H);
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; i < (int)octaves; i++) {
+ for (int i = 0; i < int(octaves); i++) {
value += perlin_signed(p) * pwr;
pwr *= pwHL;
p *= lacunarity;
@@ -754,7 +754,7 @@ float musgrave_multi_fractal(const float co,
const float pwHL = std::pow(lacunarity, -H);
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; i < (int)octaves; i++) {
+ for (int i = 0; i < int(octaves); i++) {
value *= (pwr * perlin_signed(p) + 1.0f);
pwr *= pwHL;
p *= lacunarity;
@@ -783,7 +783,7 @@ float musgrave_hetero_terrain(const float co,
float value = offset + perlin_signed(p);
p *= lacunarity;
- for (int i = 1; i < (int)octaves; i++) {
+ for (int i = 1; i < int(octaves); i++) {
float increment = (perlin_signed(p) + offset) * pwr * value;
value += increment;
pwr *= pwHL;
@@ -815,7 +815,7 @@ float musgrave_hybrid_multi_fractal(const float co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; (weight > 0.001f) && (i < (int)octaves); i++) {
+ for (int i = 0; (weight > 0.001f) && (i < int(octaves)); i++) {
if (weight > 1.0f) {
weight = 1.0f;
}
@@ -857,7 +857,7 @@ float musgrave_ridged_multi_fractal(const float co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; i < (int)octaves; i++) {
+ for (int i = 1; i < int(octaves); i++) {
p *= lacunarity;
weight = CLAMPIS(signal * gain, 0.0f, 1.0f);
signal = offset - std::abs(perlin_signed(p));
@@ -883,7 +883,7 @@ float musgrave_fBm(const float2 co,
const float pwHL = std::pow(lacunarity, -H);
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; i < (int)octaves; i++) {
+ for (int i = 0; i < int(octaves); i++) {
value += perlin_signed(p) * pwr;
pwr *= pwHL;
p *= lacunarity;
@@ -908,7 +908,7 @@ float musgrave_multi_fractal(const float2 co,
const float pwHL = std::pow(lacunarity, -H);
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; i < (int)octaves; i++) {
+ for (int i = 0; i < int(octaves); i++) {
value *= (pwr * perlin_signed(p) + 1.0f);
pwr *= pwHL;
p *= lacunarity;
@@ -938,7 +938,7 @@ float musgrave_hetero_terrain(const float2 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; i < (int)octaves; i++) {
+ for (int i = 1; i < int(octaves); i++) {
float increment = (perlin_signed(p) + offset) * pwr * value;
value += increment;
pwr *= pwHL;
@@ -970,7 +970,7 @@ float musgrave_hybrid_multi_fractal(const float2 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; (weight > 0.001f) && (i < (int)octaves); i++) {
+ for (int i = 0; (weight > 0.001f) && (i < int(octaves)); i++) {
if (weight > 1.0f) {
weight = 1.0f;
}
@@ -1012,7 +1012,7 @@ float musgrave_ridged_multi_fractal(const float2 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; i < (int)octaves; i++) {
+ for (int i = 1; i < int(octaves); i++) {
p *= lacunarity;
weight = CLAMPIS(signal * gain, 0.0f, 1.0f);
signal = offset - std::abs(perlin_signed(p));
@@ -1039,7 +1039,7 @@ float musgrave_fBm(const float3 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; i < (int)octaves; i++) {
+ for (int i = 0; i < int(octaves); i++) {
value += perlin_signed(p) * pwr;
pwr *= pwHL;
p *= lacunarity;
@@ -1065,7 +1065,7 @@ float musgrave_multi_fractal(const float3 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; i < (int)octaves; i++) {
+ for (int i = 0; i < int(octaves); i++) {
value *= (pwr * perlin_signed(p) + 1.0f);
pwr *= pwHL;
p *= lacunarity;
@@ -1095,7 +1095,7 @@ float musgrave_hetero_terrain(const float3 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; i < (int)octaves; i++) {
+ for (int i = 1; i < int(octaves); i++) {
float increment = (perlin_signed(p) + offset) * pwr * value;
value += increment;
pwr *= pwHL;
@@ -1127,7 +1127,7 @@ float musgrave_hybrid_multi_fractal(const float3 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; (weight > 0.001f) && (i < (int)octaves); i++) {
+ for (int i = 0; (weight > 0.001f) && (i < int(octaves)); i++) {
if (weight > 1.0f) {
weight = 1.0f;
}
@@ -1169,7 +1169,7 @@ float musgrave_ridged_multi_fractal(const float3 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; i < (int)octaves; i++) {
+ for (int i = 1; i < int(octaves); i++) {
p *= lacunarity;
weight = CLAMPIS(signal * gain, 0.0f, 1.0f);
signal = offset - std::abs(perlin_signed(p));
@@ -1196,7 +1196,7 @@ float musgrave_fBm(const float4 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; i < (int)octaves; i++) {
+ for (int i = 0; i < int(octaves); i++) {
value += perlin_signed(p) * pwr;
pwr *= pwHL;
p *= lacunarity;
@@ -1222,7 +1222,7 @@ float musgrave_multi_fractal(const float4 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; i < (int)octaves; i++) {
+ for (int i = 0; i < int(octaves); i++) {
value *= (pwr * perlin_signed(p) + 1.0f);
pwr *= pwHL;
p *= lacunarity;
@@ -1252,7 +1252,7 @@ float musgrave_hetero_terrain(const float4 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; i < (int)octaves; i++) {
+ for (int i = 1; i < int(octaves); i++) {
float increment = (perlin_signed(p) + offset) * pwr * value;
value += increment;
pwr *= pwHL;
@@ -1284,7 +1284,7 @@ float musgrave_hybrid_multi_fractal(const float4 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; (weight > 0.001f) && (i < (int)octaves); i++) {
+ for (int i = 0; (weight > 0.001f) && (i < int(octaves)); i++) {
if (weight > 1.0f) {
weight = 1.0f;
}
@@ -1326,7 +1326,7 @@ float musgrave_ridged_multi_fractal(const float4 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; i < (int)octaves; i++) {
+ for (int i = 1; i < int(octaves); i++) {
p *= lacunarity;
weight = CLAMPIS(signal * gain, 0.0f, 1.0f);
signal = offset - std::abs(perlin_signed(p));
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index c053c3907db..2376bd82b69 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -121,9 +121,9 @@ int BLI_path_sequence_decode(const char *string, char *head, char *tail, ushort
}
void BLI_path_sequence_encode(
- char *string, const char *head, const char *tail, unsigned short numlen, int pic)
+ char *string, const char *head, const char *tail, ushort numlen, int pic)
{
- sprintf(string, "%s%.*d%s", head, numlen, MAX2(0, pic), tail);
+ BLI_sprintf(string, "%s%.*d%s", head, numlen, MAX2(0, pic), tail);
}
static int BLI_path_unc_prefix_len(const char *path); /* defined below in same file */
@@ -153,6 +153,19 @@ void BLI_path_normalize(const char *relabase, char *path)
*/
#ifdef WIN32
+
+ while ((start = strstr(path, "\\.\\"))) {
+ eind = start + strlen("\\.\\") - 1;
+ memmove(start, eind, strlen(eind) + 1);
+ }
+
+ /* 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);
+ }
+
while ((start = strstr(path, "\\..\\"))) {
eind = start + strlen("\\..\\") - 1;
a = start - path - 1;
@@ -170,18 +183,18 @@ void BLI_path_normalize(const char *relabase, char *path)
}
}
- while ((start = strstr(path, "\\.\\"))) {
- eind = start + strlen("\\.\\") - 1;
+#else
+
+ while ((start = strstr(path, "/./"))) {
+ eind = start + (3 - 1) /* strlen("/./") - 1 */;
memmove(start, eind, strlen(eind) + 1);
}
- /* 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;
+ while ((start = strstr(path, "//"))) {
+ eind = start + (2 - 1) /* strlen("//") - 1 */;
memmove(start, eind, strlen(eind) + 1);
}
-#else
+
while ((start = strstr(path, "/../"))) {
a = start - path - 1;
if (a > 0) {
@@ -206,19 +219,10 @@ void BLI_path_normalize(const char *relabase, char *path)
}
}
- while ((start = strstr(path, "/./"))) {
- eind = start + (3 - 1) /* strlen("/./") - 1 */;
- memmove(start, eind, strlen(eind) + 1);
- }
-
- while ((start = strstr(path, "//"))) {
- eind = start + (2 - 1) /* strlen("//") - 1 */;
- memmove(start, eind, strlen(eind) + 1);
- }
#endif
}
-void BLI_path_normalize_dir(const char *relabase, char *dir)
+void BLI_path_normalize_dir(const char *relabase, char *dir, size_t dir_maxlen)
{
/* Would just create an unexpected "/" path, just early exit entirely. */
if (dir[0] == '\0') {
@@ -226,7 +230,7 @@ void BLI_path_normalize_dir(const char *relabase, char *dir)
}
BLI_path_normalize(relabase, dir);
- BLI_path_slash_ensure(dir);
+ BLI_path_slash_ensure(dir, dir_maxlen);
}
bool BLI_filename_make_safe_ex(char *fname, bool allow_tokens)
@@ -466,8 +470,8 @@ void BLI_path_rel(char *file, const char *relfile)
#ifdef WIN32
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 */
+ /* Fix missing volume name in relative base,
+ * can happen with old `recent-files.txt` files. */
BLI_windows_get_default_root_dir(temp);
ptemp = &temp[2];
if (!ELEM(relfile[0], '\\', '/')) {
@@ -616,24 +620,34 @@ bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char
}
BLI_strncpy(extension, string + a, sizeof(extension));
- sprintf(string + a, "%s%s%s", sep, suffix, extension);
+ BLI_sprintf(string + a, "%s%s%s", sep, suffix, extension);
return true;
}
bool BLI_path_parent_dir(char *path)
{
- const char parent_dir[] = {'.', '.', SEP, '\0'}; /* "../" or "..\\" */
- char tmp[FILE_MAX + 4];
-
- BLI_join_dirfile(tmp, sizeof(tmp), path, parent_dir);
- BLI_path_normalize(NULL, tmp); /* does all the work of normalizing the path for us */
-
- if (!BLI_path_extension_check(tmp, parent_dir)) {
- strcpy(path, tmp); /* We assume the parent directory is always shorter. */
- return true;
+ /* Use #BLI_path_name_at_index instead of checking if the strings ends with `parent_dir`
+ * to ensure the logic isn't confused by:
+ * - Directory names that happen to end with `..`.
+ * - When `path` is empty, the contents will be `../`
+ * which would cause checking for a tailing `/../` fail.
+ * Extracting the span of the final directory avoids both these issues. */
+ int tail_ofs = 0, tail_len = 0;
+ if (!BLI_path_name_at_index(path, -1, &tail_ofs, &tail_len)) {
+ return false;
+ }
+ if (tail_len == 1) {
+ /* Last path is ".", as normalize should remove this, it's safe to assume failure.
+ * This happens when the input a single period (possibly with slashes before or after). */
+ if (path[tail_ofs] == '.') {
+ return false;
+ }
}
- return false;
+ /* Input paths should already be normalized if `..` is part of the path. */
+ BLI_assert(!((tail_len == 2) && (path[tail_ofs] == '.') && (path[tail_ofs + 1] == '.')));
+ path[tail_ofs] = '\0';
+ return true;
}
bool BLI_path_parent_dir_until_exists(char *dir)
@@ -1025,7 +1039,7 @@ bool BLI_path_abs_from_cwd(char *path, const size_t maxlen)
if (BLI_current_working_dir(cwd, sizeof(cwd))) {
char origpath[FILE_MAX];
BLI_strncpy(origpath, path, FILE_MAX);
- BLI_join_dirfile(path, maxlen, cwd, origpath);
+ BLI_path_join(path, maxlen, cwd, origpath);
}
else {
printf("Could not get the current working directory - $PWD for an unknown reason.\n");
@@ -1347,7 +1361,7 @@ bool BLI_path_extension_ensure(char *path, size_t maxlen, const char *ext)
ssize_t a;
/* first check the extension is already there */
- if ((ext_len <= path_len) && (STREQ(path + (path_len - ext_len), ext))) {
+ if ((ext_len <= path_len) && STREQ(path + (path_len - ext_len), ext)) {
return true;
}
@@ -1431,73 +1445,50 @@ const char *BLI_path_extension(const char *filepath)
return extension;
}
-void BLI_path_append(char *__restrict dst, const size_t maxlen, const char *__restrict file)
+size_t BLI_path_append(char *__restrict dst, const size_t maxlen, const char *__restrict file)
{
size_t dirlen = BLI_strnlen(dst, maxlen);
- /* inline BLI_path_slash_ensure */
+ /* Inline #BLI_path_slash_ensure. */
if ((dirlen > 0) && (dst[dirlen - 1] != SEP)) {
dst[dirlen++] = SEP;
dst[dirlen] = '\0';
}
if (dirlen >= maxlen) {
- return; /* fills the path */
+ return dirlen; /* fills the path */
}
- BLI_strncpy(dst + dirlen, file, maxlen - dirlen);
+ return dirlen + BLI_strncpy_rlen(dst + dirlen, file, maxlen - dirlen);
}
-void BLI_join_dirfile(char *__restrict dst,
- const size_t maxlen,
- const char *__restrict dir,
- const char *__restrict file)
+size_t BLI_path_append_dir(char *__restrict dst, const size_t maxlen, const char *__restrict dir)
{
-#ifdef DEBUG_STRSIZE
- memset(dst, 0xff, sizeof(*dst) * maxlen);
-#endif
- size_t dirlen = BLI_strnlen(dir, maxlen);
-
- /* Arguments can't match. */
- BLI_assert(!ELEM(dst, dir, file));
-
- /* Files starting with a separator cause a double-slash which could later be interpreted
- * as a relative path where: `dir == "/"` and `file == "/file"` would result in "//file". */
- BLI_assert(file[0] != SEP);
-
- if (dirlen == maxlen) {
- memcpy(dst, dir, dirlen);
- dst[dirlen - 1] = '\0';
- return; /* dir fills the path */
- }
-
- memcpy(dst, dir, dirlen + 1);
-
- if (dirlen + 1 >= maxlen) {
- return; /* fills the path */
- }
-
- /* inline BLI_path_slash_ensure */
- if ((dirlen > 0) && !ELEM(dst[dirlen - 1], SEP, ALTSEP)) {
- dst[dirlen++] = SEP;
- dst[dirlen] = '\0';
- }
-
- if (dirlen >= maxlen) {
- return; /* fills the path */
+ size_t dirlen = BLI_path_append(dst, maxlen, dir);
+ if (dirlen + 1 < maxlen) {
+ /* Inline #BLI_path_slash_ensure. */
+ if ((dirlen > 0) && (dst[dirlen - 1] != SEP)) {
+ dst[dirlen++] = SEP;
+ dst[dirlen] = '\0';
+ }
}
-
- BLI_strncpy(dst + dirlen, file, maxlen - dirlen);
+ return dirlen;
}
-size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *path, ...)
+size_t BLI_path_join_array(char *__restrict dst,
+ const size_t dst_len,
+ const char *path_array[],
+ const int path_array_num)
{
+ BLI_assert(path_array_num > 0);
#ifdef DEBUG_STRSIZE
memset(dst, 0xff, sizeof(*dst) * dst_len);
#endif
if (UNLIKELY(dst_len == 0)) {
return 0;
}
+ const char *path = path_array[0];
+
const size_t dst_last = dst_len - 1;
size_t ofs = BLI_strncpy_rlen(dst, path, dst_len);
@@ -1505,37 +1496,58 @@ size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *pat
return ofs;
}
+#ifdef WIN32
+ /* Special case "//" for relative paths, don't use separator #SEP
+ * as this has a special meaning on both WIN32 & UNIX.
+ * Without this check joining `"//", "path"`. results in `"//\path"`. */
+ if (ofs != 0) {
+ size_t i;
+ for (i = 0; i < ofs; i++) {
+ if (dst[i] != '/') {
+ break;
+ }
+ }
+ if (i == ofs) {
+ /* All slashes, keep them as-is, and join the remaining path array. */
+ return path_array_num > 1 ?
+ BLI_path_join_array(
+ dst + ofs, dst_len - ofs, &path_array[1], path_array_num - 1) :
+ ofs;
+ }
+ }
+#endif
+
/* Remove trailing slashes, unless there are *only* trailing slashes
* (allow `//` or `//some_path` as the first argument). */
bool has_trailing_slash = false;
if (ofs != 0) {
size_t len = ofs;
- while ((len != 0) && ELEM(path[len - 1], SEP, ALTSEP)) {
+ while ((len != 0) && (path[len - 1] == SEP)) {
len -= 1;
}
+
if (len != 0) {
ofs = len;
}
has_trailing_slash = (path[len] != '\0');
}
- va_list args;
- va_start(args, path);
- while ((path = (const char *)va_arg(args, const char *))) {
+ for (int path_index = 1; path_index < path_array_num; path_index++) {
+ path = path_array[path_index];
has_trailing_slash = false;
const char *path_init = path;
- while (ELEM(path[0], SEP, ALTSEP)) {
+ while (path[0] == SEP) {
path++;
}
size_t len = strlen(path);
if (len != 0) {
- while ((len != 0) && ELEM(path[len - 1], SEP, ALTSEP)) {
+ while ((len != 0) && (path[len - 1] == SEP)) {
len -= 1;
}
if (len != 0) {
/* the very first path may have a slash at the end */
- if (ofs && !ELEM(dst[ofs - 1], SEP, ALTSEP)) {
+ if (ofs && (dst[ofs - 1] != SEP)) {
dst[ofs++] = SEP;
if (ofs == dst_last) {
break;
@@ -1556,10 +1568,9 @@ size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *pat
has_trailing_slash = (path_init != path);
}
}
- va_end(args);
if (has_trailing_slash) {
- if ((ofs != dst_last) && (ofs != 0) && (ELEM(dst[ofs - 1], SEP, ALTSEP) == 0)) {
+ if ((ofs != dst_last) && (ofs != 0) && (dst[ofs - 1] != SEP)) {
dst[ofs++] = SEP;
}
}
@@ -1576,53 +1587,64 @@ const char *BLI_path_basename(const char *path)
return filename ? filename + 1 : path;
}
-bool BLI_path_name_at_index(const char *__restrict path,
- const int index,
- int *__restrict r_offset,
- int *__restrict r_len)
+static bool path_name_at_index_forward(const char *__restrict path,
+ const int index,
+ int *__restrict r_offset,
+ int *__restrict r_len)
{
- if (index >= 0) {
- int index_step = 0;
- int prev = -1;
- int i = 0;
- while (true) {
- const char c = path[i];
- if (ELEM(c, SEP, ALTSEP, '\0')) {
- if (prev + 1 != i) {
- prev += 1;
+ BLI_assert(index >= 0);
+ int index_step = 0;
+ int prev = -1;
+ int i = 0;
+ while (true) {
+ const char c = path[i];
+ if (ELEM(c, SEP, '\0')) {
+ if (prev + 1 != i) {
+ prev += 1;
+ /* Skip '/./' (behave as if they don't exist). */
+ if (!((i - prev == 1) && (prev != 0) && (path[prev] == '.'))) {
if (index_step == index) {
*r_offset = prev;
*r_len = i - prev;
- // printf("!!! %d %d\n", start, end);
return true;
}
index_step += 1;
}
- if (c == '\0') {
- break;
- }
- prev = i;
}
- i += 1;
+ if (c == '\0') {
+ break;
+ }
+ prev = i;
}
- return false;
+ i += 1;
}
+ return false;
+}
- /* negative number, reverse where -1 is the last element */
+static bool path_name_at_index_backward(const char *__restrict path,
+ const int index,
+ int *__restrict r_offset,
+ int *__restrict r_len)
+{
+ /* Negative number, reverse where -1 is the last element. */
+ BLI_assert(index < 0);
int index_step = -1;
int prev = strlen(path);
int i = prev - 1;
while (true) {
const char c = i >= 0 ? path[i] : '\0';
- if (ELEM(c, SEP, ALTSEP, '\0')) {
+ if (ELEM(c, SEP, '\0')) {
if (prev - 1 != i) {
i += 1;
- if (index_step == index) {
- *r_offset = i;
- *r_len = prev - i;
- return true;
+ /* Skip '/./' (behave as if they don't exist). */
+ if (!((prev - i == 1) && (i != 0) && (path[i] == '.'))) {
+ if (index_step == index) {
+ *r_offset = i;
+ *r_len = prev - i;
+ return true;
+ }
+ index_step -= 1;
}
- index_step -= 1;
}
if (c == '\0') {
break;
@@ -1634,6 +1656,15 @@ bool BLI_path_name_at_index(const char *__restrict path,
return false;
}
+bool BLI_path_name_at_index(const char *__restrict path,
+ const int index,
+ int *__restrict r_offset,
+ int *__restrict r_len)
+{
+ return (index >= 0) ? path_name_at_index_forward(path, index, r_offset, r_len) :
+ path_name_at_index_backward(path, index, r_offset, r_len);
+}
+
bool BLI_path_contains(const char *container_path, const char *containee_path)
{
char container_native[PATH_MAX];
@@ -1662,7 +1693,7 @@ bool BLI_path_contains(const char *container_path, const char *containee_path)
/* Add a trailing slash to prevent same-prefix directories from matching.
* e.g. "/some/path" doesn't contain "/some/path_lib". */
- BLI_path_slash_ensure(container_native);
+ BLI_path_slash_ensure(container_native, sizeof(container_native));
return BLI_str_startswith(containee_native, container_native);
}
@@ -1697,13 +1728,17 @@ const char *BLI_path_slash_rfind(const char *string)
return (lfslash > lbslash) ? lfslash : lbslash;
}
-int BLI_path_slash_ensure(char *string)
+int BLI_path_slash_ensure(char *string, size_t string_maxlen)
{
int len = strlen(string);
+ BLI_assert(len < string_maxlen);
if (len == 0 || string[len - 1] != SEP) {
- string[len] = SEP;
- string[len + 1] = '\0';
- return len + 1;
+ /* Avoid unlikely buffer overflow. */
+ if (len + 1 < string_maxlen) {
+ string[len] = SEP;
+ string[len + 1] = '\0';
+ return len + 1;
+ }
}
return len;
}
diff --git a/source/blender/blenlib/intern/polyfill_2d.c b/source/blender/blenlib/intern/polyfill_2d.c
index eed87eda436..2b59de5b569 100644
--- a/source/blender/blenlib/intern/polyfill_2d.c
+++ b/source/blender/blenlib/intern/polyfill_2d.c
@@ -373,12 +373,12 @@ static bool kdtree2d_isect_tri_recursive(const struct KDTree2D *tree,
# define KDTREE2D_ISECT_TRI_RECURSE_NEG \
(((node->neg != KDNODE_UNSET) && (co[node->axis] >= bounds[node->axis].min)) && \
- (kdtree2d_isect_tri_recursive( \
- tree, tri_index, tri_coords, tri_center, bounds, &tree->nodes[node->neg])))
+ kdtree2d_isect_tri_recursive( \
+ tree, tri_index, tri_coords, tri_center, bounds, &tree->nodes[node->neg]))
# define KDTREE2D_ISECT_TRI_RECURSE_POS \
(((node->pos != KDNODE_UNSET) && (co[node->axis] <= bounds[node->axis].max)) && \
- (kdtree2d_isect_tri_recursive( \
- tree, tri_index, tri_coords, tri_center, bounds, &tree->nodes[node->pos])))
+ kdtree2d_isect_tri_recursive( \
+ tree, tri_index, tri_coords, tri_center, bounds, &tree->nodes[node->pos]))
if (tri_center[node->axis] > co[node->axis]) {
if (KDTREE2D_ISECT_TRI_RECURSE_POS) {
diff --git a/source/blender/blenlib/intern/rand.cc b/source/blender/blenlib/intern/rand.cc
index f6d91cdcc4f..2e9b15c623e 100644
--- a/source/blender/blenlib/intern/rand.cc
+++ b/source/blender/blenlib/intern/rand.cc
@@ -24,7 +24,7 @@
#include "BLI_strict_flags.h"
#include "BLI_sys_types.h"
-extern "C" unsigned char BLI_noise_hash_uchar_512[512]; /* noise.c */
+extern "C" uchar BLI_noise_hash_uchar_512[512]; /* noise.c */
#define hash BLI_noise_hash_uchar_512
/**
@@ -36,14 +36,14 @@ struct RNG {
MEM_CXX_CLASS_ALLOC_FUNCS("RNG")
};
-RNG *BLI_rng_new(unsigned int seed)
+RNG *BLI_rng_new(uint seed)
{
RNG *rng = new RNG();
rng->rng.seed(seed);
return rng;
}
-RNG *BLI_rng_new_srandom(unsigned int seed)
+RNG *BLI_rng_new_srandom(uint seed)
{
RNG *rng = new RNG();
rng->rng.seed_random(seed);
@@ -60,19 +60,19 @@ void BLI_rng_free(RNG *rng)
delete rng;
}
-void BLI_rng_seed(RNG *rng, unsigned int seed)
+void BLI_rng_seed(RNG *rng, uint seed)
{
rng->rng.seed(seed);
}
-void BLI_rng_srandom(RNG *rng, unsigned int seed)
+void BLI_rng_srandom(RNG *rng, uint seed)
{
rng->rng.seed_random(seed);
}
void BLI_rng_get_char_n(RNG *rng, char *bytes, size_t bytes_len)
{
- rng->rng.get_bytes(blender::MutableSpan(bytes, static_cast<int64_t>(bytes_len)));
+ rng->rng.get_bytes(blender::MutableSpan(bytes, int64_t(bytes_len)));
}
int BLI_rng_get_int(RNG *rng)
@@ -80,7 +80,7 @@ int BLI_rng_get_int(RNG *rng)
return rng->rng.get_int32();
}
-unsigned int BLI_rng_get_uint(RNG *rng)
+uint BLI_rng_get_uint(RNG *rng)
{
return rng->rng.get_uint32();
}
@@ -117,21 +117,21 @@ void BLI_rng_get_tri_sample_float_v3(
copy_v3_v3(r_pt, rng->rng.get_triangle_sample_3d(v1, v2, v3));
}
-void BLI_rng_shuffle_array(RNG *rng, void *data, unsigned int elem_size_i, unsigned int elem_num)
+void BLI_rng_shuffle_array(RNG *rng, void *data, uint elem_size_i, uint elem_num)
{
if (elem_num <= 1) {
return;
}
const uint elem_size = elem_size_i;
- unsigned int i = elem_num;
+ uint i = elem_num;
void *temp = malloc(elem_size);
while (i--) {
- const unsigned int j = BLI_rng_get_uint(rng) % elem_num;
+ const uint j = BLI_rng_get_uint(rng) % elem_num;
if (i != j) {
- void *iElem = (unsigned char *)data + i * elem_size_i;
- void *jElem = (unsigned char *)data + j * elem_size_i;
+ void *iElem = (uchar *)data + i * elem_size_i;
+ void *jElem = (uchar *)data + j * elem_size_i;
memcpy(temp, iElem, elem_size);
memcpy(iElem, jElem, elem_size);
memcpy(jElem, temp, elem_size);
@@ -141,15 +141,15 @@ void BLI_rng_shuffle_array(RNG *rng, void *data, unsigned int elem_size_i, unsig
free(temp);
}
-void BLI_rng_shuffle_bitmap(struct RNG *rng, BLI_bitmap *bitmap, unsigned int bits_num)
+void BLI_rng_shuffle_bitmap(struct RNG *rng, BLI_bitmap *bitmap, uint bits_num)
{
if (bits_num <= 1) {
return;
}
- unsigned int i = bits_num;
+ uint i = bits_num;
while (i--) {
- const unsigned int j = BLI_rng_get_uint(rng) % bits_num;
+ const uint j = BLI_rng_get_uint(rng) % bits_num;
if (i != j) {
const bool i_bit = BLI_BITMAP_TEST(bitmap, i);
const bool j_bit = BLI_BITMAP_TEST(bitmap, j);
@@ -161,12 +161,12 @@ void BLI_rng_shuffle_bitmap(struct RNG *rng, BLI_bitmap *bitmap, unsigned int bi
void BLI_rng_skip(RNG *rng, int n)
{
- rng->rng.skip((uint)n);
+ rng->rng.skip(uint(n));
}
/***/
-void BLI_array_frand(float *ar, int count, unsigned int seed)
+void BLI_array_frand(float *ar, int count, uint seed)
{
RNG rng;
@@ -177,7 +177,7 @@ void BLI_array_frand(float *ar, int count, unsigned int seed)
}
}
-float BLI_hash_frand(unsigned int seed)
+float BLI_hash_frand(uint seed)
{
RNG rng;
@@ -185,10 +185,7 @@ float BLI_hash_frand(unsigned int seed)
return BLI_rng_get_float(&rng);
}
-void BLI_array_randomize(void *data,
- unsigned int elem_size,
- unsigned int elem_num,
- unsigned int seed)
+void BLI_array_randomize(void *data, uint elem_size, uint elem_num, uint seed)
{
RNG rng;
@@ -196,7 +193,7 @@ void BLI_array_randomize(void *data,
BLI_rng_shuffle_array(&rng, data, elem_size, elem_num);
}
-void BLI_bitmap_randomize(BLI_bitmap *bitmap, unsigned int bits_num, unsigned int seed)
+void BLI_bitmap_randomize(BLI_bitmap *bitmap, uint bits_num, uint seed)
{
RNG rng;
@@ -208,7 +205,7 @@ void BLI_bitmap_randomize(BLI_bitmap *bitmap, unsigned int bits_num, unsigned in
static RNG rng_tab[BLENDER_MAX_THREADS];
-void BLI_thread_srandom(int thread, unsigned int seed)
+void BLI_thread_srandom(int thread, uint seed)
{
if (thread >= BLENDER_MAX_THREADS) {
thread = 0;
@@ -237,12 +234,12 @@ struct RNG_THREAD_ARRAY {
RNG_THREAD_ARRAY *BLI_rng_threaded_new()
{
- unsigned int i;
+ uint i;
RNG_THREAD_ARRAY *rngarr = (RNG_THREAD_ARRAY *)MEM_mallocN(sizeof(RNG_THREAD_ARRAY),
"random_array");
for (i = 0; i < BLENDER_MAX_THREADS; i++) {
- BLI_rng_srandom(&rngarr->rng_tab[i], (unsigned int)clock());
+ BLI_rng_srandom(&rngarr->rng_tab[i], uint(clock()));
}
return rngarr;
@@ -284,9 +281,9 @@ BLI_INLINE double halton_ex(double invprimes, double *offset)
return *offset;
}
-void BLI_halton_1d(unsigned int prime, double offset, int n, double *r)
+void BLI_halton_1d(uint prime, double offset, int n, double *r)
{
- const double invprime = 1.0 / (double)prime;
+ const double invprime = 1.0 / double(prime);
*r = 0.0;
@@ -295,9 +292,9 @@ void BLI_halton_1d(unsigned int prime, double offset, int n, double *r)
}
}
-void BLI_halton_2d(const unsigned int prime[2], double offset[2], int n, double *r)
+void BLI_halton_2d(const uint prime[2], double offset[2], int n, double *r)
{
- const double invprimes[2] = {1.0 / (double)prime[0], 1.0 / (double)prime[1]};
+ const double invprimes[2] = {1.0 / double(prime[0]), 1.0 / double(prime[1])};
r[0] = r[1] = 0.0;
@@ -308,10 +305,10 @@ void BLI_halton_2d(const unsigned int prime[2], double offset[2], int n, double
}
}
-void BLI_halton_3d(const unsigned int prime[3], double offset[3], int n, double *r)
+void BLI_halton_3d(const uint prime[3], double offset[3], int n, double *r)
{
const double invprimes[3] = {
- 1.0 / (double)prime[0], 1.0 / (double)prime[1], 1.0 / (double)prime[2]};
+ 1.0 / double(prime[0]), 1.0 / double(prime[1]), 1.0 / double(prime[2])};
r[0] = r[1] = r[2] = 0.0;
@@ -322,9 +319,9 @@ void BLI_halton_3d(const unsigned int prime[3], double offset[3], int n, double
}
}
-void BLI_halton_2d_sequence(const unsigned int prime[2], double offset[2], int n, double *r)
+void BLI_halton_2d_sequence(const uint prime[2], double offset[2], int n, double *r)
{
- const double invprimes[2] = {1.0 / (double)prime[0], 1.0 / (double)prime[1]};
+ const double invprimes[2] = {1.0 / double(prime[0]), 1.0 / double(prime[1])};
for (int s = 0; s < n; s++) {
for (int i = 0; i < 2; i++) {
@@ -335,7 +332,7 @@ void BLI_halton_2d_sequence(const unsigned int prime[2], double offset[2], int n
/* From "Sampling with Hammersley and Halton Points" TT Wong
* Appendix: Source Code 1 */
-BLI_INLINE double radical_inverse(unsigned int n)
+BLI_INLINE double radical_inverse(uint n)
{
double u = 0;
@@ -350,15 +347,15 @@ BLI_INLINE double radical_inverse(unsigned int n)
return u;
}
-void BLI_hammersley_1d(unsigned int n, double *r)
+void BLI_hammersley_1d(uint n, double *r)
{
*r = radical_inverse(n);
}
-void BLI_hammersley_2d_sequence(unsigned int n, double *r)
+void BLI_hammersley_2d_sequence(uint n, double *r)
{
- for (unsigned int s = 0; s < n; s++) {
- r[s * 2 + 0] = (double)(s + 0.5) / (double)n;
+ for (uint s = 0; s < n; s++) {
+ r[s * 2 + 0] = double(s + 0.5) / double(n);
r[s * 2 + 1] = radical_inverse(s);
}
}
@@ -380,12 +377,12 @@ int RandomNumberGenerator::round_probabilistic(float x)
BLI_assert(x >= 0.0f);
const float round_up_probability = fractf(x);
const bool round_up = round_up_probability > this->get_float();
- return (int)x + (int)round_up;
+ return int(x) + int(round_up);
}
float2 RandomNumberGenerator::get_unit_float2()
{
- float a = (float)(M_PI * 2.0) * this->get_float();
+ float a = float(M_PI * 2.0) * this->get_float();
return {cosf(a), sinf(a)};
}
@@ -394,7 +391,7 @@ float3 RandomNumberGenerator::get_unit_float3()
float z = (2.0f * this->get_float()) - 1.0f;
float r = 1.0f - z * z;
if (r > 0.0f) {
- float a = (float)(M_PI * 2.0) * this->get_float();
+ float a = float(M_PI * 2.0) * this->get_float();
r = sqrtf(r);
float x = r * cosf(a);
float y = r * sinf(a);
@@ -444,7 +441,7 @@ float3 RandomNumberGenerator::get_triangle_sample_3d(float3 v1, float3 v2, float
void RandomNumberGenerator::get_bytes(MutableSpan<char> r_bytes)
{
constexpr int64_t mask_bytes = 2;
- constexpr int64_t rand_stride = static_cast<int64_t>(sizeof(x_)) - mask_bytes;
+ constexpr int64_t rand_stride = int64_t(sizeof(x_)) - mask_bytes;
int64_t last_len = 0;
int64_t trim_len = r_bytes.size();
diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c
index 92fd7f5937b..4145125c1d7 100644
--- a/source/blender/blenlib/intern/scanfill.c
+++ b/source/blender/blenlib/intern/scanfill.c
@@ -33,9 +33,9 @@
/* local types */
typedef struct PolyFill {
- unsigned int edges, verts;
+ uint edges, verts;
float min_xy[2], max_xy[2];
- unsigned short nr;
+ ushort nr;
bool f;
} PolyFill;
@@ -44,7 +44,7 @@ typedef struct ScanFillVertLink {
ScanFillEdge *edge_first, *edge_last;
} ScanFillVertLink;
-/* local funcs */
+/* Local functions. */
#define SF_EPSILON 0.00003f
#define SF_EPSILON_SQ (SF_EPSILON * SF_EPSILON)
@@ -304,9 +304,7 @@ static bool addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed)
return true;
}
-static ScanFillVertLink *addedgetoscanlist(ScanFillVertLink *scdata,
- ScanFillEdge *eed,
- unsigned int len)
+static ScanFillVertLink *addedgetoscanlist(ScanFillVertLink *scdata, ScanFillEdge *eed, uint len)
{
/* inserts edge at correct location in ScanFillVertLink list */
/* returns sc when edge already exists */
@@ -428,10 +426,7 @@ static void testvertexnearedge(ScanFillContext *sf_ctx)
}
}
-static void splitlist(ScanFillContext *sf_ctx,
- ListBase *tempve,
- ListBase *temped,
- unsigned short nr)
+static void splitlist(ScanFillContext *sf_ctx, ListBase *tempve, ListBase *temped, ushort nr)
{
/* Everything is in temp-list, write only poly nr to fill-list. */
ScanFillVert *eve, *eve_next;
@@ -457,14 +452,14 @@ static void splitlist(ScanFillContext *sf_ctx,
}
}
-static unsigned int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
+static uint scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
{
ScanFillVertLink *scdata;
ScanFillVertLink *sc = NULL, *sc1;
ScanFillVert *eve, *v1, *v2, *v3;
ScanFillEdge *eed, *eed_next, *ed1, *ed2, *ed3;
- unsigned int a, b, verts, maxface, totface;
- const unsigned short nr = pf->nr;
+ uint a, b, verts, maxface, totface;
+ const ushort nr = pf->nr;
bool twoconnected = false;
/* PRINTS */
@@ -810,7 +805,7 @@ void BLI_scanfill_end_arena(ScanFillContext *sf_ctx, MemArena *arena)
BLI_listbase_clear(&sf_ctx->fillfacebase);
}
-unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float nor_proj[3])
+uint BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float nor_proj[3])
{
/*
* - fill works with its own lists, so create that first (no faces!)
@@ -825,8 +820,8 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
ScanFillEdge *eed, *eed_next;
PolyFill *pflist, *pf;
float *min_xy_p, *max_xy_p;
- unsigned int totfaces = 0; /* total faces added */
- unsigned short a, c, poly = 0;
+ uint totfaces = 0; /* total faces added */
+ ushort a, c, poly = 0;
bool ok;
float mat_2d[3][3];
@@ -895,7 +890,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
/* STEP 1: COUNT POLYS */
if (sf_ctx->poly_nr != SF_POLY_UNSET) {
- poly = (unsigned short)(sf_ctx->poly_nr + 1);
+ poly = (ushort)(sf_ctx->poly_nr + 1);
sf_ctx->poly_nr = SF_POLY_UNSET;
}
@@ -905,7 +900,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
/* get first vertex with no poly number */
if (eve->poly_nr == SF_POLY_UNSET) {
- unsigned int toggle = 0;
+ uint toggle = 0;
/* now a sort of select connected */
ok = true;
eve->poly_nr = poly;
@@ -962,7 +957,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
/* STEP 2: remove loose edges and strings of edges */
if (flag & BLI_SCANFILL_CALC_LOOSE) {
- unsigned int toggle = 0;
+ uint toggle = 0;
for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
if (eed->v1->edge_count++ > 250) {
break;
@@ -1069,7 +1064,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
* WATCH IT: ONLY WORKS WITH SORTED POLYS!!! */
if ((flag & BLI_SCANFILL_CALC_HOLES) && (poly > 1)) {
- unsigned short *polycache, *pc;
+ ushort *polycache, *pc;
/* so, sort first */
qsort(pflist, (size_t)poly, sizeof(PolyFill), vergpoly);
@@ -1086,7 +1081,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
polycache = pc = MEM_callocN(sizeof(*polycache) * (size_t)poly, "polycache");
pf = pflist;
for (a = 0; a < poly; a++, pf++) {
- for (c = (unsigned short)(a + 1); c < poly; c++) {
+ for (c = (ushort)(a + 1); c < poly; c++) {
/* if 'a' inside 'c': join (bbox too)
* Careful: 'a' can also be inside another poly.
@@ -1142,7 +1137,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
return totfaces;
}
-unsigned int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag)
+uint BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag)
{
return BLI_scanfill_calc_ex(sf_ctx, flag, NULL);
}
diff --git a/source/blender/blenlib/intern/scanfill_utils.c b/source/blender/blenlib/intern/scanfill_utils.c
index 1d2225a5b56..6bf3c4719f6 100644
--- a/source/blender/blenlib/intern/scanfill_utils.c
+++ b/source/blender/blenlib/intern/scanfill_utils.c
@@ -41,14 +41,14 @@ typedef struct ScanFillIsect {
#define EFLAG_SET(eed, val) \
{ \
CHECK_TYPE(eed, ScanFillEdge *); \
- (eed)->user_flag = (eed)->user_flag | (unsigned int)val; \
+ (eed)->user_flag = (eed)->user_flag | (uint)val; \
} \
(void)0
#if 0
# define EFLAG_CLEAR(eed, val) \
{ \
CHECK_TYPE(eed, ScanFillEdge *); \
- (eed)->user_flag = (eed)->user_flag & ~(unsigned int)val; \
+ (eed)->user_flag = (eed)->user_flag & ~(uint)val; \
} \
(void)0
#endif
@@ -56,14 +56,14 @@ typedef struct ScanFillIsect {
#define VFLAG_SET(eve, val) \
{ \
CHECK_TYPE(eve, ScanFillVert *); \
- (eve)->user_flag = (eve)->user_flag | (unsigned int)val; \
+ (eve)->user_flag = (eve)->user_flag | (uint)val; \
} \
(void)0
#if 0
# define VFLAG_CLEAR(eve, val) \
{ \
CHECK_TYPE(eve, ScanFillVert *); \
- (eve)->user_flags = (eve)->user_flag & ~(unsigned int)val; \
+ (eve)->user_flags = (eve)->user_flag & ~(uint)val; \
} \
(void)0
#endif
@@ -72,7 +72,7 @@ typedef struct ScanFillIsect {
void BLI_scanfill_obj_dump(ScanFillContext *sf_ctx)
{
FILE *f = fopen("test.obj", "w");
- unsigned int i = 1;
+ uint i = 1;
ScanFillVert *eve;
ScanFillEdge *eed;
@@ -130,7 +130,7 @@ static int edge_isect_ls_sort_cb(void *thunk, const void *def_a_ptr, const void
}
static ScanFillEdge *edge_step(PolyInfo *poly_info,
- const unsigned short poly_nr,
+ const ushort poly_nr,
ScanFillVert *v_prev,
ScanFillVert *v_curr,
ScanFillEdge *e_curr)
@@ -158,7 +158,7 @@ static ScanFillEdge *edge_step(PolyInfo *poly_info,
static bool scanfill_preprocess_self_isect(ScanFillContext *sf_ctx,
PolyInfo *poly_info,
- const unsigned short poly_nr,
+ const ushort poly_nr,
ListBase *filledgebase)
{
PolyInfo *pi = &poly_info[poly_nr];
@@ -359,8 +359,8 @@ bool BLI_scanfill_calc_self_isect(ScanFillContext *sf_ctx,
ListBase *remvertbase,
ListBase *remedgebase)
{
- const unsigned int poly_num = (unsigned int)sf_ctx->poly_nr + 1;
- unsigned int eed_index = 0;
+ const uint poly_num = (uint)sf_ctx->poly_nr + 1;
+ uint eed_index = 0;
int totvert_new = 0;
bool changed = false;
@@ -378,7 +378,7 @@ bool BLI_scanfill_calc_self_isect(ScanFillContext *sf_ctx,
poly_info->edge_last = sf_ctx->filledgebase.last;
}
else {
- unsigned short poly_nr;
+ ushort poly_nr;
ScanFillEdge *eed;
poly_nr = 0;
@@ -407,7 +407,7 @@ bool BLI_scanfill_calc_self_isect(ScanFillContext *sf_ctx,
/* self-intersect each polygon */
{
- unsigned short poly_nr;
+ ushort poly_nr;
for (poly_nr = 0; poly_nr < poly_num; poly_nr++) {
changed |= scanfill_preprocess_self_isect(sf_ctx, poly_info, poly_nr, remedgebase);
}
diff --git a/source/blender/blenlib/intern/stack.c b/source/blender/blenlib/intern/stack.c
index ff34cfe41cb..1a83e8cd86c 100644
--- a/source/blender/blenlib/intern/stack.c
+++ b/source/blender/blenlib/intern/stack.c
@@ -141,7 +141,7 @@ void BLI_stack_pop(BLI_Stack *stack, void *dst)
BLI_stack_discard(stack);
}
-void BLI_stack_pop_n(BLI_Stack *stack, void *dst, unsigned int n)
+void BLI_stack_pop_n(BLI_Stack *stack, void *dst, uint n)
{
BLI_assert(n <= BLI_stack_count(stack));
@@ -151,7 +151,7 @@ void BLI_stack_pop_n(BLI_Stack *stack, void *dst, unsigned int n)
}
}
-void BLI_stack_pop_n_reverse(BLI_Stack *stack, void *dst, unsigned int n)
+void BLI_stack_pop_n_reverse(BLI_Stack *stack, void *dst, uint n)
{
BLI_assert(n <= BLI_stack_count(stack));
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 4fa5ca0c088..c04fc41ab4d 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -259,7 +259,7 @@ eFileAttributes BLI_file_attributes(const char *path)
#ifndef __APPLE__
bool BLI_file_alias_target(const char *filepath,
/* This parameter can only be `const` on Linux since
- * redirections are not supported there.
+ * redirection is not supported there.
* NOLINTNEXTLINE: readability-non-const-parameter. */
char r_targetpath[/*FILE_MAXDIR*/])
{
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index 976b9a5cd02..3c3dcaf90f4 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -241,6 +241,17 @@ char *BLI_sprintfN(const char *__restrict format, ...)
return n;
}
+int BLI_sprintf(char *__restrict str, const char *__restrict format, ...)
+{
+ va_list arg;
+
+ va_start(arg, format);
+ const int result = vsprintf(str, format, arg);
+ va_end(arg);
+
+ return result;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -314,7 +325,7 @@ size_t BLI_str_unescape_ex(char *__restrict dst,
break;
}
char c = *src;
- if (UNLIKELY(c == '\\') && (str_unescape_pair(*(src + 1), &c))) {
+ if (UNLIKELY(c == '\\') && str_unescape_pair(*(src + 1), &c)) {
src++;
}
dst[len++] = c;
@@ -329,7 +340,7 @@ size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, const
size_t len = 0;
for (const char *src_end = src + src_maxncpy; (src < src_end) && *src; src++) {
char c = *src;
- if (UNLIKELY(c == '\\') && (str_unescape_pair(*(src + 1), &c))) {
+ if (UNLIKELY(c == '\\') && str_unescape_pair(*(src + 1), &c)) {
src++;
}
dst[len++] = c;
@@ -1114,17 +1125,17 @@ static size_t BLI_str_format_int_grouped_ex(char src[16], char dst[16], int num_
size_t BLI_str_format_int_grouped(char dst[16], int num)
{
char src[16];
- int num_len = sprintf(src, "%d", num);
+ const int num_len = BLI_snprintf(src, sizeof(src), "%d", num);
return BLI_str_format_int_grouped_ex(src, dst, num_len);
}
size_t BLI_str_format_uint64_grouped(char dst[16], uint64_t num)
{
- /* NOTE: Buffer to hold maximum unsigned int64, which is 1.8e+19. but
+ /* NOTE: Buffer to hold maximum `uint64`, which is 1.8e+19. but
* we also need space for commas and null-terminator. */
char src[27];
- int num_len = sprintf(src, "%" PRIu64 "", num);
+ const int num_len = BLI_snprintf(src, sizeof(src), "%" PRIu64 "", num);
return BLI_str_format_int_grouped_ex(src, dst, num_len);
}
@@ -1176,4 +1187,34 @@ void BLI_str_format_decimal_unit(char dst[7], int number_to_format)
BLI_snprintf(dst, dst_len, "%.*f%s", decimals, number_to_format_converted, units[order]);
}
+void BLI_str_format_integer_unit(char dst[5], const int number_to_format)
+{
+ float number_to_format_converted = number_to_format;
+ int order = 0;
+ const float base = 1000;
+ const char *units[] = {"", "K", "M", "B"};
+ const int units_num = ARRAY_SIZE(units);
+
+ while ((fabsf(number_to_format_converted) >= base) && ((order + 1) < units_num)) {
+ number_to_format_converted /= base;
+ order++;
+ }
+
+ const bool add_dot = (abs(number_to_format) > 99999) && fabsf(number_to_format_converted) > 99;
+
+ if (add_dot) {
+ number_to_format_converted /= 100;
+ order++;
+ }
+
+ const size_t dst_len = 5;
+ BLI_snprintf(dst,
+ dst_len,
+ "%s%s%d%s",
+ number_to_format < 0 ? "-" : "",
+ add_dot ? "." : "",
+ (int)floorf(fabsf(number_to_format_converted)),
+ units[order]);
+}
+
/** \} */
diff --git a/source/blender/blenlib/intern/string_cursor_utf8.c b/source/blender/blenlib/intern/string_cursor_utf8.c
index 7a23b4bb4ad..2405b134428 100644
--- a/source/blender/blenlib/intern/string_cursor_utf8.c
+++ b/source/blender/blenlib/intern/string_cursor_utf8.c
@@ -96,27 +96,35 @@ static eStrCursorDelimType cursor_delim_type_utf8(const char *ch_utf8,
return cursor_delim_type_unicode(uch);
}
+/* Keep in sync with BLI_str_cursor_step_next_utf32. */
bool BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, int *pos)
{
+ if ((*pos) >= (int)maxlen) {
+ return false;
+ }
const char *str_end = str + (maxlen + 1);
const char *str_pos = str + (*pos);
- const char *str_next = BLI_str_find_next_char_utf8(str_pos, str_end);
- if (str_next != str_end) {
- (*pos) += (str_next - str_pos);
- if ((*pos) > (int)maxlen) {
- (*pos) = (int)maxlen;
- }
- return true;
+ const char *str_next = str_pos;
+ do {
+ str_next = BLI_str_find_next_char_utf8(str_next, str_end);
+ } while (str_next < str_end && str_next[0] != 0 && BLI_str_utf8_char_width(str_next) < 1);
+ (*pos) += (str_next - str_pos);
+ if ((*pos) > (int)maxlen) {
+ (*pos) = (int)maxlen;
}
- return false;
+ return true;
}
-bool BLI_str_cursor_step_prev_utf8(const char *str, size_t UNUSED(maxlen), int *pos)
+/* Keep in sync with BLI_str_cursor_step_prev_utf32. */
+bool BLI_str_cursor_step_prev_utf8(const char *str, size_t maxlen, int *pos)
{
- if ((*pos) > 0) {
+ if ((*pos) > 0 && (*pos) <= maxlen) {
const char *str_pos = str + (*pos);
- const char *str_prev = BLI_str_find_prev_char_utf8(str_pos, str);
+ const char *str_prev = str_pos;
+ do {
+ str_prev = BLI_str_find_prev_char_utf8(str_prev, str);
+ } while (str_prev > str && BLI_str_utf8_char_width(str_prev) == 0);
(*pos) -= (str_pos - str_prev);
return true;
}
@@ -202,26 +210,29 @@ void BLI_str_cursor_step_utf8(const char *str,
}
}
-/* UTF32 version of BLI_str_cursor_step_utf8 (keep in sync!)
- * less complex since it doesn't need to do multi-byte stepping.
- */
-
-/* helper funcs so we can match BLI_str_cursor_step_utf8 */
-static bool cursor_step_next_utf32(const char32_t *UNUSED(str), size_t maxlen, int *pos)
+/* Keep in sync with BLI_str_cursor_step_next_utf8. */
+bool BLI_str_cursor_step_next_utf32(const char32_t *str, size_t maxlen, int *pos)
{
if ((*pos) >= (int)maxlen) {
return false;
}
- (*pos)++;
+ do {
+ (*pos)++;
+ } while (*pos < (int)maxlen && str[*pos] != 0 && BLI_wcwidth(str[*pos]) == 0);
+
return true;
}
-static bool cursor_step_prev_utf32(const char32_t *UNUSED(str), size_t UNUSED(maxlen), int *pos)
+/* Keep in sync with BLI_str_cursor_step_prev_utf8. */
+bool BLI_str_cursor_step_prev_utf32(const char32_t *str, size_t UNUSED(maxlen), int *pos)
{
if ((*pos) <= 0) {
return false;
}
- (*pos)--;
+ do {
+ (*pos)--;
+ } while (*pos > 0 && BLI_wcwidth(str[*pos]) == 0);
+
return true;
}
@@ -236,7 +247,7 @@ void BLI_str_cursor_step_utf32(const char32_t *str,
if (direction == STRCUR_DIR_NEXT) {
if (use_init_step) {
- cursor_step_next_utf32(str, maxlen, pos);
+ BLI_str_cursor_step_next_utf32(str, maxlen, pos);
}
else {
BLI_assert(jump == STRCUR_JUMP_DELIM);
@@ -250,7 +261,7 @@ void BLI_str_cursor_step_utf32(const char32_t *str,
* look at function cursor_delim_type_unicode() for complete
* list of special character, ctr -> */
while ((*pos) < maxlen) {
- if (cursor_step_next_utf32(str, maxlen, pos)) {
+ if (BLI_str_cursor_step_next_utf32(str, maxlen, pos)) {
if ((jump != STRCUR_JUMP_ALL) &&
(delim_type != cursor_delim_type_unicode((uint)str[*pos]))) {
break;
@@ -264,7 +275,7 @@ void BLI_str_cursor_step_utf32(const char32_t *str,
}
else if (direction == STRCUR_DIR_PREV) {
if (use_init_step) {
- cursor_step_prev_utf32(str, maxlen, pos);
+ BLI_str_cursor_step_prev_utf32(str, maxlen, pos);
}
else {
BLI_assert(jump == STRCUR_JUMP_DELIM);
@@ -279,7 +290,7 @@ void BLI_str_cursor_step_utf32(const char32_t *str,
* list of special character, ctr -> */
while ((*pos) > 0) {
const int pos_prev = *pos;
- if (cursor_step_prev_utf32(str, maxlen, pos)) {
+ if (BLI_str_cursor_step_prev_utf32(str, maxlen, pos)) {
if ((jump != STRCUR_JUMP_ALL) &&
(delim_type != cursor_delim_type_unicode((uint)str[*pos]))) {
/* left only: compensate for index/change in direction */
diff --git a/source/blender/blenlib/intern/string_search.cc b/source/blender/blenlib/intern/string_search.cc
index 31ea24eb494..f87304863c9 100644
--- a/source/blender/blenlib/intern/string_search.cc
+++ b/source/blender/blenlib/intern/string_search.cc
@@ -18,7 +18,7 @@ namespace blender::string_search {
static int64_t count_utf8_code_points(StringRef str)
{
- return static_cast<int64_t>(BLI_strnlen_utf8(str.data(), static_cast<size_t>(str.size())));
+ return int64_t(BLI_strnlen_utf8(str.data(), size_t(str.size())));
}
int damerau_levenshtein_distance(StringRef a, StringRef b)
@@ -205,7 +205,7 @@ static bool match_word_initials(StringRef query,
StringRef word = words[word_index];
/* Try to match the current character with the current word. */
- if (static_cast<int>(char_index) < word.size()) {
+ if (int(char_index) < word.size()) {
const uint32_t char_unicode = BLI_str_utf8_as_unicode_step(
word.data(), word.size(), &char_index);
if (query_unicode == char_unicode) {
@@ -345,7 +345,7 @@ void extract_normalized_words(StringRef str,
LinearAllocator<> &allocator,
Vector<StringRef, 64> &r_words)
{
- const uint32_t unicode_space = (uint32_t)' ';
+ const uint32_t unicode_space = uint32_t(' ');
const uint32_t unicode_right_triangle = UI_MENU_ARROW_SEP_UNICODE;
BLI_assert(unicode_space == BLI_str_utf8_as_unicode(" "));
@@ -358,7 +358,7 @@ void extract_normalized_words(StringRef str,
/* Make a copy of the string so that we can edit it. */
StringRef str_copy = allocator.copy_string(str);
char *mutable_copy = const_cast<char *>(str_copy.data());
- const size_t str_size_in_bytes = static_cast<size_t>(str.size());
+ const size_t str_size_in_bytes = size_t(str.size());
BLI_str_tolower_ascii(mutable_copy, str_size_in_bytes);
/* Iterate over all unicode code points to split individual words. */
@@ -371,8 +371,7 @@ void extract_normalized_words(StringRef str,
size -= offset;
if (is_separator(unicode)) {
if (is_in_word) {
- r_words.append(
- str_copy.substr(static_cast<int>(word_start), static_cast<int>(offset - word_start)));
+ r_words.append(str_copy.substr(int(word_start), int(offset - word_start)));
is_in_word = false;
}
}
@@ -386,7 +385,7 @@ void extract_normalized_words(StringRef str,
}
/* If the last word is not followed by a separator, it has to be handled separately. */
if (is_in_word) {
- r_words.append(str_copy.drop_prefix(static_cast<int>(word_start)));
+ r_words.append(str_copy.drop_prefix(int(word_start)));
}
}
@@ -419,7 +418,7 @@ void BLI_string_search_add(StringSearch *search,
StringRef str_ref{str};
string_search::extract_normalized_words(str_ref, search->allocator, words);
search->items.append({search->allocator.construct_array_copy(words.as_span()),
- (int)str_ref.size(),
+ int(str_ref.size()),
user_data,
weight});
}
@@ -458,7 +457,7 @@ int BLI_string_search_query(StringSearch *search, const char *query, void ***r_d
if (score == found_scores[0] && !query_str.is_empty()) {
/* Sort items with best score by length. Shorter items are more likely the ones you are
* looking for. This also ensures that exact matches will be at the top, even if the query is
- * a substring of another item. */
+ * a sub-string of another item. */
std::sort(indices.begin(), indices.end(), [&](int a, int b) {
return search->items[a].length < search->items[b].length;
});
@@ -472,7 +471,7 @@ int BLI_string_search_query(StringSearch *search, const char *query, void ***r_d
}
void **sorted_data = static_cast<void **>(
- MEM_malloc_arrayN(static_cast<size_t>(sorted_result_indices.size()), sizeof(void *), AT));
+ MEM_malloc_arrayN(size_t(sorted_result_indices.size()), sizeof(void *), AT));
for (const int i : sorted_result_indices.index_range()) {
const int result_index = sorted_result_indices[i];
SearchItem &item = search->items[result_index];
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index 17fb451e422..26facda7abf 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -55,11 +55,11 @@ ptrdiff_t BLI_str_utf8_invalid_byte(const char *str, size_t length)
* length is in bytes, since without knowing whether the string is valid
* it's hard to know how many characters there are! */
- const unsigned char *p, *perr, *pend = (const unsigned char *)str + length;
- unsigned char c;
+ const uchar *p, *perr, *pend = (const uchar *)str + length;
+ uchar c;
int ab;
- for (p = (const unsigned char *)str; p < pend; p++, length--) {
+ for (p = (const uchar *)str; p < pend; p++, length--) {
c = *p;
perr = p; /* Erroneous char is always the first of an invalid utf8 sequence... */
if (ELEM(c, 0xfe, 0xff, 0x00)) {
@@ -454,7 +454,7 @@ int BLI_str_utf8_size(const char *p)
/* NOTE: uses glib functions but not from GLIB. */
int mask = 0, len;
- const unsigned char c = (unsigned char)*p;
+ const uchar c = (uchar)*p;
UTF8_COMPUTE(c, mask, len, -1);
@@ -466,7 +466,7 @@ int BLI_str_utf8_size(const char *p)
int BLI_str_utf8_size_safe(const char *p)
{
int mask = 0, len;
- const unsigned char c = (unsigned char)*p;
+ const uchar c = (uchar)*p;
UTF8_COMPUTE(c, mask, len, 1);
@@ -482,7 +482,7 @@ uint BLI_str_utf8_as_unicode(const char *p)
int i, len;
uint mask = 0;
uint result;
- const unsigned char c = (unsigned char)*p;
+ const uchar c = (uchar)*p;
UTF8_COMPUTE(c, mask, len, -1);
if (UNLIKELY(len == -1)) {
@@ -500,7 +500,7 @@ uint BLI_str_utf8_as_unicode_step_or_error(const char *__restrict p,
int i, len;
uint mask = 0;
uint result;
- const unsigned char c = (unsigned char)*(p += *index);
+ const uchar c = (uchar) * (p += *index);
BLI_assert(*index < p_len);
BLI_assert(c != '\0');
diff --git a/source/blender/blenlib/intern/string_utils.c b/source/blender/blenlib/intern/string_utils.c
index 0b9baaff3e9..27734d2f429 100644
--- a/source/blender/blenlib/intern/string_utils.c
+++ b/source/blender/blenlib/intern/string_utils.c
@@ -344,10 +344,10 @@ bool BLI_uniquename(
*
* \{ */
-char *BLI_string_join_array(char *result,
- size_t result_len,
- const char *strings[],
- uint strings_len)
+size_t BLI_string_join_array(char *result,
+ size_t result_len,
+ const char *strings[],
+ uint strings_len)
{
char *c = result;
char *c_end = &result[result_len - 1];
@@ -358,10 +358,10 @@ char *BLI_string_join_array(char *result,
}
}
*c = '\0';
- return c;
+ return (size_t)(c - result);
}
-char *BLI_string_join_array_by_sep_char(
+size_t BLI_string_join_array_by_sep_char(
char *result, size_t result_len, char sep, const char *strings[], uint strings_len)
{
char *c = result;
@@ -378,7 +378,7 @@ char *BLI_string_join_array_by_sep_char(
}
}
*c = '\0';
- return c;
+ return (size_t)(c - result);
}
char *BLI_string_join_arrayN(const char *strings[], uint strings_len)
diff --git a/source/blender/blenlib/intern/system.c b/source/blender/blenlib/intern/system.c
index f7249e491d7..40a8fa24570 100644
--- a/source/blender/blenlib/intern/system.c
+++ b/source/blender/blenlib/intern/system.c
@@ -34,7 +34,7 @@ int BLI_cpu_support_sse2(void)
return 1;
#elif defined(__GNUC__) && defined(i386)
/* for GCC x86 we check cpuid */
- unsigned int d;
+ uint d;
__asm__(
"pushl %%ebx\n\t"
"cpuid\n\t"
@@ -44,7 +44,7 @@ int BLI_cpu_support_sse2(void)
return (d & 0x04000000) != 0;
#elif (defined(_MSC_VER) && defined(_M_IX86))
/* also check cpuid for MSVC x86 */
- unsigned int d;
+ uint d;
__asm {
xor eax, eax
inc eax
diff --git a/source/blender/blenlib/intern/task_graph.cc b/source/blender/blenlib/intern/task_graph.cc
index 6c1cc818d75..5bc84bf7573 100644
--- a/source/blender/blenlib/intern/task_graph.cc
+++ b/source/blender/blenlib/intern/task_graph.cc
@@ -75,7 +75,7 @@ struct TaskNode {
}
#ifdef WITH_TBB
- tbb::flow::continue_msg run(const tbb::flow::continue_msg UNUSED(input))
+ tbb::flow::continue_msg run(const tbb::flow::continue_msg /*input*/)
{
run_func(task_data);
return tbb::flow::continue_msg();
diff --git a/source/blender/blenlib/intern/task_iterator.c b/source/blender/blenlib/intern/task_iterator.c
index d5afbb2b117..99e966de975 100644
--- a/source/blender/blenlib/intern/task_iterator.c
+++ b/source/blender/blenlib/intern/task_iterator.c
@@ -26,10 +26,10 @@
* \{ */
/* Allows to avoid using malloc for userdata_chunk in tasks, when small enough. */
-#define MALLOCA(_size) ((_size) <= 8192) ? alloca((_size)) : MEM_mallocN((_size), __func__)
+#define MALLOCA(_size) ((_size) <= 8192) ? alloca(_size) : MEM_mallocN((_size), __func__)
#define MALLOCA_FREE(_mem, _size) \
if (((_mem) != NULL) && ((_size) > 8192)) { \
- MEM_freeN((_mem)); \
+ MEM_freeN(_mem); \
} \
((void)0)
diff --git a/source/blender/blenlib/intern/task_range.cc b/source/blender/blenlib/intern/task_range.cc
index 7e405529f03..20551aba93b 100644
--- a/source/blender/blenlib/intern/task_range.cc
+++ b/source/blender/blenlib/intern/task_range.cc
@@ -12,6 +12,7 @@
#include "DNA_listBase.h"
+#include "BLI_lazy_threading.hh"
#include "BLI_task.h"
#include "BLI_threads.h"
@@ -104,6 +105,8 @@ void BLI_task_parallel_range(const int start,
const size_t grainsize = MAX2(settings->min_iter_per_thread, 1);
const tbb::blocked_range<int> range(start, stop, grainsize);
+ blender::lazy_threading::send_hint();
+
if (settings->func_reduce) {
parallel_reduce(range, task);
if (settings->userdata_chunk) {
@@ -129,7 +132,7 @@ void BLI_task_parallel_range(const int start,
}
}
-int BLI_task_parallel_thread_id(const TaskParallelTLS *UNUSED(tls))
+int BLI_task_parallel_thread_id(const TaskParallelTLS * /*tls*/)
{
#ifdef WITH_TBB
/* Get a unique thread ID for texture nodes. In the future we should get rid
diff --git a/source/blender/blenlib/intern/task_scheduler.cc b/source/blender/blenlib/intern/task_scheduler.cc
index 1f7747453c1..5b056df78b4 100644
--- a/source/blender/blenlib/intern/task_scheduler.cc
+++ b/source/blender/blenlib/intern/task_scheduler.cc
@@ -8,6 +8,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_lazy_threading.hh"
#include "BLI_task.h"
#include "BLI_threads.h"
@@ -67,6 +68,7 @@ int BLI_task_scheduler_num_threads()
void BLI_task_isolate(void (*func)(void *userdata), void *userdata)
{
#ifdef WITH_TBB
+ blender::lazy_threading::ReceiverIsolation isolation;
tbb::this_task_arena::isolate([&] { func(userdata); });
#else
func(userdata);
diff --git a/source/blender/blenlib/intern/threads.cc b/source/blender/blenlib/intern/threads.cc
index 37fccf6f4fe..f99a27c2475 100644
--- a/source/blender/blenlib/intern/threads.cc
+++ b/source/blender/blenlib/intern/threads.cc
@@ -37,17 +37,6 @@
#include "atomic_ops.h"
-#if defined(__APPLE__) && defined(_OPENMP) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2) && \
- !defined(__clang__)
-# define USE_APPLE_OMP_FIX
-#endif
-
-#ifdef USE_APPLE_OMP_FIX
-/* ************** libgomp (Apple gcc 4.2.1) TLS bug workaround *************** */
-extern pthread_key_t gomp_tls_key;
-static void *thread_tls_data;
-#endif
-
/**
* Basic Thread Control API
* ========================
@@ -108,7 +97,7 @@ static pthread_mutex_t _colormanage_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _fftw_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _view3d_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_t mainid;
-static unsigned int thread_levels = 0; /* threads can be invoked inside threads */
+static uint thread_levels = 0; /* threads can be invoked inside threads */
static int threads_override_num = 0;
/* just a max for security reasons */
@@ -153,15 +142,7 @@ void BLI_threadpool_init(ListBase *threadbase, void *(*do_thread)(void *), int t
}
}
- unsigned int level = atomic_fetch_and_add_u(&thread_levels, 1);
- if (level == 0) {
-#ifdef USE_APPLE_OMP_FIX
- /* Workaround for Apple gcc 4.2.1 OMP vs background thread bug,
- * we copy GOMP thread local storage pointer to setting it again
- * inside the thread that we start. */
- thread_tls_data = pthread_getspecific(gomp_tls_key);
-#endif
- }
+ atomic_fetch_and_add_u(&thread_levels, 1);
}
int BLI_available_threads(ListBase *threadbase)
@@ -194,13 +175,6 @@ int BLI_threadpool_available_thread_index(ListBase *threadbase)
static void *tslot_thread_start(void *tslot_p)
{
ThreadSlot *tslot = (ThreadSlot *)tslot_p;
-
-#ifdef USE_APPLE_OMP_FIX
- /* Workaround for Apple gcc 4.2.1 OMP vs background thread bug,
- * set GOMP thread local storage pointer which was copied beforehand */
- pthread_setspecific(gomp_tls_key, thread_tls_data);
-#endif
-
return tslot->do_thread(tslot->callerdata);
}
@@ -293,7 +267,7 @@ int BLI_system_thread_count()
#ifdef WIN32
SYSTEM_INFO info;
GetSystemInfo(&info);
- t = (int)info.dwNumberOfProcessors;
+ t = int(info.dwNumberOfProcessors);
#else
# ifdef __APPLE__
int mib[2];
@@ -304,7 +278,7 @@ int BLI_system_thread_count()
len = sizeof(t);
sysctl(mib, 2, &t, &len, nullptr, 0);
# else
- t = (int)sysconf(_SC_NPROCESSORS_ONLN);
+ t = int(sysconf(_SC_NPROCESSORS_ONLN));
# endif
#endif
}
@@ -524,7 +498,7 @@ void BLI_rw_mutex_free(ThreadRWMutex *mutex)
struct TicketMutex {
pthread_cond_t cond;
pthread_mutex_t mutex;
- unsigned int queue_head, queue_tail;
+ uint queue_head, queue_tail;
};
TicketMutex *BLI_ticket_mutex_alloc()
@@ -547,7 +521,7 @@ void BLI_ticket_mutex_free(TicketMutex *ticket)
void BLI_ticket_mutex_lock(TicketMutex *ticket)
{
- unsigned int queue_me;
+ uint queue_me;
pthread_mutex_lock(&ticket->mutex);
queue_me = ticket->queue_tail++;
diff --git a/source/blender/blenlib/intern/timecode.c b/source/blender/blenlib/intern/timecode.c
index fc78b0ad98d..ecaa469984d 100644
--- a/source/blender/blenlib/intern/timecode.c
+++ b/source/blender/blenlib/intern/timecode.c
@@ -176,7 +176,7 @@ size_t BLI_timecode_string_from_time_simple(char *str,
const int hr = ((int)time_seconds) / (60 * 60);
const int min = (((int)time_seconds) / 60) % 60;
const int sec = ((int)time_seconds) % 60;
- const int hun = ((int)(fmod(time_seconds, 1.0) * 100));
+ const int hun = (int)(fmod(time_seconds, 1.0) * 100);
if (hr) {
rlen = BLI_snprintf_rlen(str, maxncpy, "%.2d:%.2d:%.2d.%.2d", hr, min, sec, hun);
diff --git a/source/blender/blenlib/intern/uuid.cc b/source/blender/blenlib/intern/uuid.cc
index 890a721a9d1..b845208f0da 100644
--- a/source/blender/blenlib/intern/uuid.cc
+++ b/source/blender/blenlib/intern/uuid.cc
@@ -5,6 +5,7 @@
*/
#include "BLI_assert.h"
+#include "BLI_string.h"
#include "BLI_uuid.h"
#include <cstdio>
@@ -85,19 +86,19 @@ bool BLI_uuid_equal(const bUUID uuid1, const bUUID uuid2)
void BLI_uuid_format(char *buffer, const bUUID uuid)
{
- std::sprintf(buffer,
- "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- uuid.time_low,
- uuid.time_mid,
- uuid.time_hi_and_version,
- uuid.clock_seq_hi_and_reserved,
- uuid.clock_seq_low,
- uuid.node[0],
- uuid.node[1],
- uuid.node[2],
- uuid.node[3],
- uuid.node[4],
- uuid.node[5]);
+ BLI_sprintf(buffer,
+ "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ uuid.time_low,
+ uuid.time_mid,
+ uuid.time_hi_and_version,
+ uuid.clock_seq_hi_and_reserved,
+ uuid.clock_seq_low,
+ uuid.node[0],
+ uuid.node[1],
+ uuid.node[2],
+ uuid.node[3],
+ uuid.node[4],
+ uuid.node[5]);
}
bool BLI_uuid_parse_string(bUUID *uuid, const char *buffer)
@@ -136,10 +137,10 @@ bUUID::bUUID(const std::initializer_list<uint32_t> field_values)
const auto *field_iter = field_values.begin();
this->time_low = *field_iter++;
- this->time_mid = static_cast<uint16_t>(*field_iter++);
- this->time_hi_and_version = static_cast<uint16_t>(*field_iter++);
- this->clock_seq_hi_and_reserved = static_cast<uint8_t>(*field_iter++);
- this->clock_seq_low = static_cast<uint8_t>(*field_iter++);
+ this->time_mid = uint16_t(*field_iter++);
+ this->time_hi_and_version = uint16_t(*field_iter++);
+ this->clock_seq_hi_and_reserved = uint8_t(*field_iter++);
+ this->clock_seq_low = uint8_t(*field_iter++);
std::copy(field_iter, field_values.end(), this->node);
}
diff --git a/source/blender/blenlib/intern/uvproject.c b/source/blender/blenlib/intern/uvproject.c
index 347166bd57d..0398bf0b3fe 100644
--- a/source/blender/blenlib/intern/uvproject.c
+++ b/source/blender/blenlib/intern/uvproject.c
@@ -129,7 +129,7 @@ ProjCameraInfo *BLI_uvproject_camera_info(Object *ob, float rotmat[4][4], float
uci.camsize = uci.do_persp ? tanf(uci.camangle) : camera->ortho_scale;
/* account for scaled cameras */
- copy_m4_m4(uci.caminv, ob->obmat);
+ copy_m4_m4(uci.caminv, ob->object_to_world);
normalize_m4(uci.caminv);
if (invert_m4(uci.caminv)) {
diff --git a/source/blender/blenlib/intern/winstuff.c b/source/blender/blenlib/intern/winstuff.c
index 7e2c5e8f1dd..3a574b60ae2 100644
--- a/source/blender/blenlib/intern/winstuff.c
+++ b/source/blender/blenlib/intern/winstuff.c
@@ -110,7 +110,7 @@ bool BLI_windows_register_blend_extension(const bool background)
&hkey,
&dwd);
if (lresult == ERROR_SUCCESS) {
- sprintf(buffer, "\"%s\" \"%%1\"", BlPath);
+ BLI_snprintf(buffer, sizeof(buffer), "\"%s\" \"%%1\"", BlPath);
lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
RegCloseKey(hkey);
}
@@ -129,7 +129,7 @@ bool BLI_windows_register_blend_extension(const bool background)
&hkey,
&dwd);
if (lresult == ERROR_SUCCESS) {
- sprintf(buffer, "\"%s\", 1", BlPath);
+ BLI_snprintf(buffer, sizeof(buffer), "\"%s\", 1", BlPath);
lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
RegCloseKey(hkey);
}
@@ -167,10 +167,12 @@ bool BLI_windows_register_blend_extension(const bool background)
RegCloseKey(root);
printf("success (%s)\n", usr_mode ? "user" : "system");
if (!background) {
- sprintf(MBox,
- "File extension registered for %s.",
- usr_mode ? "the current user. To register for all users, run as an administrator" :
- "all users");
+ BLI_snprintf(MBox,
+ sizeof(MBox),
+ "File extension registered for %s.",
+ usr_mode ?
+ "the current user. To register for all users, run as an administrator" :
+ "all users");
MessageBox(0, MBox, "Blender", MB_OK | MB_ICONINFORMATION);
}
return true;
diff --git a/source/blender/blenlib/tests/BLI_array_store_test.cc b/source/blender/blenlib/tests/BLI_array_store_test.cc
index 5d05e3be1f3..c52d439308f 100644
--- a/source/blender/blenlib/tests/BLI_array_store_test.cc
+++ b/source/blender/blenlib/tests/BLI_array_store_test.cc
@@ -168,7 +168,7 @@ static void testbuffer_list_state_from_data__stride_expand(ListBase *lb,
#define testbuffer_list_state_from_string_array(lb, data_array) \
{ \
- unsigned int i_ = 0; \
+ uint i_ = 0; \
const char *data; \
while ((data = data_array[i_++])) { \
testbuffer_list_state_from_data(lb, data, strlen(data)); \
@@ -224,7 +224,7 @@ static bool testbuffer_list_validate(const ListBase *lb)
return true;
}
-static void testbuffer_list_data_randomize(ListBase *lb, unsigned int random_seed)
+static void testbuffer_list_data_randomize(ListBase *lb, uint random_seed)
{
for (TestBuffer *tb = (TestBuffer *)lb->first; tb; tb = tb->next) {
BLI_array_randomize((void *)tb->data, 1, tb->data_len, random_seed++);
@@ -301,7 +301,7 @@ TEST(array_store, Nop)
TEST(array_store, NopState)
{
BArrayStore *bs = BLI_array_store_create(1, 32);
- const unsigned char data[] = "test";
+ const uchar data[] = "test";
BArrayState *state = BLI_array_store_state_add(bs, data, sizeof(data) - 1, nullptr);
EXPECT_EQ(BLI_array_store_state_size_get(state), sizeof(data) - 1);
BLI_array_store_state_remove(bs, state);
@@ -556,18 +556,15 @@ TEST(array_store, TextSentencesRandom_Stride128_Chunk6)
/* -------------------------------------------------------------------- */
/* Random Data Tests */
-static unsigned int rand_range_i(RNG *rng,
- unsigned int min_i,
- unsigned int max_i,
- unsigned int step)
+static uint rand_range_i(RNG *rng, uint min_i, uint max_i, uint step)
{
if (min_i == max_i) {
return min_i;
}
BLI_assert(min_i <= max_i);
BLI_assert(((min_i % step) == 0) && ((max_i % step) == 0));
- unsigned int range = (max_i - min_i);
- unsigned int value = BLI_rng_get_uint(rng) % range;
+ uint range = (max_i - min_i);
+ uint value = BLI_rng_get_uint(rng) % range;
value = (value / step) * step;
return min_i + value;
}
@@ -577,7 +574,7 @@ static void testbuffer_list_state_random_data(ListBase *lb,
const size_t data_min_len,
const size_t data_max_len,
- const unsigned int mutate,
+ const uint mutate,
RNG *rng)
{
size_t data_len = rand_range_i(rng, data_min_len, data_max_len + stride, stride);
@@ -607,12 +604,12 @@ static void testbuffer_list_state_random_data(ListBase *lb,
MUTATE_TOTAL,
};
- switch ((BLI_rng_get_uint(rng) % MUTATE_TOTAL)) {
+ switch (BLI_rng_get_uint(rng) % MUTATE_TOTAL) {
case MUTATE_NOP: {
break;
}
case MUTATE_ADD: {
- const unsigned int offset = rand_range_i(rng, 0, data_len, stride);
+ const uint offset = rand_range_i(rng, 0, data_len, stride);
if (data_len < data_max_len) {
data_len += stride;
data = (char *)MEM_reallocN((void *)data, data_len);
@@ -622,7 +619,7 @@ static void testbuffer_list_state_random_data(ListBase *lb,
break;
}
case MUTATE_REMOVE: {
- const unsigned int offset = rand_range_i(rng, 0, data_len, stride);
+ const uint offset = rand_range_i(rng, 0, data_len, stride);
if (data_len > data_min_len) {
memmove(&data[offset], &data[offset + stride], data_len - (offset + stride));
data_len -= stride;
@@ -638,7 +635,7 @@ static void testbuffer_list_state_random_data(ListBase *lb,
}
case MUTATE_RANDOMIZE: {
if (data_len > 0) {
- const unsigned int offset = rand_range_i(rng, 0, data_len - stride, stride);
+ const uint offset = rand_range_i(rng, 0, data_len - stride, stride);
BLI_rng_get_char_n(rng, &data[offset], stride);
}
break;
diff --git a/source/blender/blenlib/tests/BLI_cpp_type_test.cc b/source/blender/blenlib/tests/BLI_cpp_type_test.cc
index 6a59bedc649..5823d54f51b 100644
--- a/source/blender/blenlib/tests/BLI_cpp_type_test.cc
+++ b/source/blender/blenlib/tests/BLI_cpp_type_test.cc
@@ -63,7 +63,7 @@ struct TestType {
return stream;
}
- friend bool operator==(const TestType &UNUSED(a), const TestType &UNUSED(b))
+ friend bool operator==(const TestType & /*a*/, const TestType & /*b*/)
{
return false;
}
diff --git a/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc b/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
index 25ee523ebc0..ca99c678754 100644
--- a/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
+++ b/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
@@ -99,7 +99,7 @@ template<typename T> CDT_input<T> fill_input_from_string(const char *spec)
*/
static int get_orig_index(const Array<Vector<int>> &out_to_orig, int orig_index)
{
- int n = static_cast<int>(out_to_orig.size());
+ int n = int(out_to_orig.size());
for (int i = 0; i < n; ++i) {
for (int orig : out_to_orig[i]) {
if (orig == orig_index) {
@@ -110,7 +110,7 @@ static int get_orig_index(const Array<Vector<int>> &out_to_orig, int orig_index)
return -1;
}
-template<typename T> static double math_to_double(const T UNUSED(v))
+template<typename T> static double math_to_double(const T /*v*/)
{
BLI_assert(false); /* Need implementation for other type. */
return 0.0;
@@ -147,7 +147,7 @@ template<> double math_abs(const double v)
*/
template<typename T> int get_vertex_by_coord(const CDT_result<T> &out, double x, double y)
{
- int nv = static_cast<int>(out.vert.size());
+ int nv = int(out.vert.size());
for (int i = 0; i < nv; ++i) {
double vx = math_to_double(out.vert[i][0]);
double vy = math_to_double(out.vert[i][1]);
@@ -162,7 +162,7 @@ template<typename T> int get_vertex_by_coord(const CDT_result<T> &out, double x,
template<typename T>
int get_output_edge_index(const CDT_result<T> &out, int out_index_1, int out_index_2)
{
- int ne = static_cast<int>(out.edge.size());
+ int ne = int(out.edge.size());
for (int i = 0; i < ne; ++i) {
if ((out.edge[i].first == out_index_1 && out.edge[i].second == out_index_2) ||
(out.edge[i].first == out_index_2 && out.edge[i].second == out_index_1)) {
@@ -175,7 +175,7 @@ int get_output_edge_index(const CDT_result<T> &out, int out_index_1, int out_ind
template<typename T>
bool output_edge_has_input_id(const CDT_result<T> &out, int out_edge_index, int in_edge_index)
{
- return out_edge_index < static_cast<int>(out.edge_orig.size()) &&
+ return out_edge_index < int(out.edge_orig.size()) &&
out.edge_orig[out_edge_index].contains(in_edge_index);
}
@@ -184,8 +184,8 @@ bool output_edge_has_input_id(const CDT_result<T> &out, int out_edge_index, int
*/
template<typename T> int get_output_face_index(const CDT_result<T> &out, const Array<int> &poly)
{
- int nf = static_cast<int>(out.face.size());
- int npolyv = static_cast<int>(poly.size());
+ int nf = int(out.face.size());
+ int npolyv = int(poly.size());
for (int f = 0; f < nf; ++f) {
if (out.face[f].size() != poly.size()) {
continue;
@@ -218,7 +218,7 @@ int get_output_tri_index(const CDT_result<T> &out,
template<typename T>
bool output_face_has_input_id(const CDT_result<T> &out, int out_face_index, int in_face_index)
{
- return out_face_index < static_cast<int>(out.face_orig.size()) &&
+ return out_face_index < int(out.face_orig.size()) &&
out.face_orig[out_face_index].contains(in_face_index);
}
@@ -310,10 +310,10 @@ void graph_draw(const std::string &label,
double height = maxy - miny;
double aspect = height / width;
int view_width = max_draw_width;
- int view_height = static_cast<int>(view_width * aspect);
+ int view_height = int(view_width * aspect);
if (view_height > max_draw_height) {
view_height = max_draw_height;
- view_width = static_cast<int>(view_height / aspect);
+ view_width = int(view_height / aspect);
}
double scale = view_width / width;
diff --git a/source/blender/blenlib/tests/BLI_edgehash_test.cc b/source/blender/blenlib/tests/BLI_edgehash_test.cc
index 301fa226016..f6e987c7060 100644
--- a/source/blender/blenlib/tests/BLI_edgehash_test.cc
+++ b/source/blender/blenlib/tests/BLI_edgehash_test.cc
@@ -308,7 +308,7 @@ TEST(edgehash, StressTest)
std::vector<Edge> edges;
for (int i = 0; i < amount; i++) {
- edges.push_back({(uint)i, amount + (uint)std::rand() % 12345});
+ edges.push_back({uint(i), amount + uint(std::rand()) % 12345});
}
EdgeHash *eh = BLI_edgehash_new(__func__);
diff --git a/source/blender/blenlib/tests/BLI_exception_safety_test_utils.hh b/source/blender/blenlib/tests/BLI_exception_safety_test_utils.hh
index 63943e48f0e..367d8508a20 100644
--- a/source/blender/blenlib/tests/BLI_exception_safety_test_utils.hh
+++ b/source/blender/blenlib/tests/BLI_exception_safety_test_utils.hh
@@ -87,7 +87,7 @@ class ExceptionThrower {
uint64_t hash() const
{
- return static_cast<uint64_t>(value);
+ return uint64_t(value);
}
friend bool operator==(const ExceptionThrower &a, const ExceptionThrower &b)
diff --git a/source/blender/blenlib/tests/BLI_generic_array_test.cc b/source/blender/blenlib/tests/BLI_generic_array_test.cc
index 52bc7728a6a..8e32430eede 100644
--- a/source/blender/blenlib/tests/BLI_generic_array_test.cc
+++ b/source/blender/blenlib/tests/BLI_generic_array_test.cc
@@ -20,7 +20,7 @@ TEST(generic_array, TypeConstructor)
TEST(generic_array, MoveConstructor)
{
- GArray array_a(CPPType::get<int32_t>(), (int64_t)10);
+ GArray array_a(CPPType::get<int32_t>(), int64_t(10));
GMutableSpan span_a = array_a.as_mutable_span();
MutableSpan<int32_t> typed_span_a = span_a.typed<int32_t>();
typed_span_a.fill(42);
@@ -40,7 +40,7 @@ TEST(generic_array, MoveConstructor)
TEST(generic_array, CopyConstructor)
{
- GArray array_a(CPPType::get<int32_t>(), (int64_t)10);
+ GArray array_a(CPPType::get<int32_t>(), int64_t(10));
GMutableSpan span_a = array_a.as_mutable_span();
MutableSpan<int32_t> typed_span_a = span_a.typed<int32_t>();
typed_span_a.fill(42);
@@ -79,7 +79,7 @@ TEST(generic_array, BufferAndSizeConstructor)
TEST(generic_array, Reinitialize)
{
- GArray array(CPPType::get<int32_t>(), (int64_t)5);
+ GArray array(CPPType::get<int32_t>(), int64_t(5));
EXPECT_FALSE(array.data() == nullptr);
GMutableSpan span = array.as_mutable_span();
MutableSpan<int32_t> typed_span = span.typed<int32_t>();
@@ -106,7 +106,7 @@ TEST(generic_array, InContainer)
{
blender::Array<GArray<>> arrays;
for (GArray<> &array : arrays) {
- array = GArray(CPPType::get<int32_t>(), (int64_t)5);
+ array = GArray(CPPType::get<int32_t>(), int64_t(5));
array.as_mutable_span().typed<int32_t>().fill(55);
}
for (GArray<> &array : arrays) {
@@ -114,4 +114,13 @@ TEST(generic_array, InContainer)
}
}
+TEST(generic_array, ReinitEmpty)
+{
+ GArray<> array(CPPType::get<int>());
+ array.reinitialize(10);
+ array.as_mutable_span().typed<int>()[9] = 7;
+ EXPECT_EQ(array.size(), 10);
+ EXPECT_EQ(array.as_span().typed<int>()[9], 7);
+}
+
} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_ghash_test.cc b/source/blender/blenlib/tests/BLI_ghash_test.cc
index da5207cb3f8..5e763dc928f 100644
--- a/source/blender/blenlib/tests/BLI_ghash_test.cc
+++ b/source/blender/blenlib/tests/BLI_ghash_test.cc
@@ -34,10 +34,10 @@
/* NOTE: for pure-ghash testing, nature of the keys and data have absolutely no importance! So here
* we just use mere random integers stored in pointers. */
-static void init_keys(unsigned int keys[TESTCASE_SIZE], const int seed)
+static void init_keys(uint keys[TESTCASE_SIZE], const int seed)
{
RNG *rng = BLI_rng_new(seed);
- unsigned int *k;
+ uint *k;
int i;
for (i = 0, k = keys; i < TESTCASE_SIZE;) {
@@ -61,7 +61,7 @@ static void init_keys(unsigned int keys[TESTCASE_SIZE], const int seed)
TEST(ghash, InsertLookup)
{
GHash *ghash = BLI_ghash_new(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__);
- unsigned int keys[TESTCASE_SIZE], *k;
+ uint keys[TESTCASE_SIZE], *k;
int i;
init_keys(keys, 0);
@@ -85,7 +85,7 @@ TEST(ghash, InsertLookup)
TEST(ghash, InsertRemove)
{
GHash *ghash = BLI_ghash_new(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__);
- unsigned int keys[TESTCASE_SIZE], *k;
+ uint keys[TESTCASE_SIZE], *k;
int i, bkt_size;
init_keys(keys, 10);
@@ -112,7 +112,7 @@ TEST(ghash, InsertRemove)
TEST(ghash, InsertRemoveShrink)
{
GHash *ghash = BLI_ghash_new(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__);
- unsigned int keys[TESTCASE_SIZE], *k;
+ uint keys[TESTCASE_SIZE], *k;
int i, bkt_size;
BLI_ghash_flag_set(ghash, GHASH_FLAG_ALLOW_SHRINK);
@@ -141,7 +141,7 @@ TEST(ghash, Copy)
{
GHash *ghash = BLI_ghash_new(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__);
GHash *ghash_copy;
- unsigned int keys[TESTCASE_SIZE], *k;
+ uint keys[TESTCASE_SIZE], *k;
int i;
init_keys(keys, 30);
@@ -170,7 +170,7 @@ TEST(ghash, Copy)
TEST(ghash, Pop)
{
GHash *ghash = BLI_ghash_new(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__);
- unsigned int keys[TESTCASE_SIZE], *k;
+ uint keys[TESTCASE_SIZE], *k;
int i;
BLI_ghash_flag_set(ghash, GHASH_FLAG_ALLOW_SHRINK);
diff --git a/source/blender/blenlib/tests/BLI_hash_mm2a_test.cc b/source/blender/blenlib/tests/BLI_hash_mm2a_test.cc
index 99bb107840f..90f5aa6189f 100644
--- a/source/blender/blenlib/tests/BLI_hash_mm2a_test.cc
+++ b/source/blender/blenlib/tests/BLI_hash_mm2a_test.cc
@@ -16,7 +16,7 @@ TEST(hash_mm2a, MM2ABasic)
const char *data = "Blender";
BLI_hash_mm2a_init(&mm2, 0);
- BLI_hash_mm2a_add(&mm2, (const unsigned char *)data, strlen(data));
+ BLI_hash_mm2a_add(&mm2, (const uchar *)data, strlen(data));
#ifdef __LITTLE_ENDIAN__
EXPECT_EQ(BLI_hash_mm2a_end(&mm2), 1633988145);
#else
@@ -35,12 +35,12 @@ TEST(hash_mm2a, MM2AConcatenateStrings)
const char *data123 = "Blender is FaNtAsTiC";
BLI_hash_mm2a_init(&mm2, 0);
- BLI_hash_mm2a_add(&mm2, (const unsigned char *)data1, strlen(data1));
- BLI_hash_mm2a_add(&mm2, (const unsigned char *)data2, strlen(data2));
- BLI_hash_mm2a_add(&mm2, (const unsigned char *)data3, strlen(data3));
+ BLI_hash_mm2a_add(&mm2, (const uchar *)data1, strlen(data1));
+ BLI_hash_mm2a_add(&mm2, (const uchar *)data2, strlen(data2));
+ BLI_hash_mm2a_add(&mm2, (const uchar *)data3, strlen(data3));
hash = BLI_hash_mm2a_end(&mm2);
BLI_hash_mm2a_init(&mm2, 0);
- BLI_hash_mm2a_add(&mm2, (const unsigned char *)data123, strlen(data123));
+ BLI_hash_mm2a_add(&mm2, (const uchar *)data123, strlen(data123));
#ifdef __LITTLE_ENDIAN__
EXPECT_EQ(hash, 1545105348);
#else
@@ -63,7 +63,7 @@ TEST(hash_mm2a, MM2AIntegers)
BLI_hash_mm2a_add_int(&mm2, ints[3]);
hash = BLI_hash_mm2a_end(&mm2);
BLI_hash_mm2a_init(&mm2, 0);
- BLI_hash_mm2a_add(&mm2, (const unsigned char *)ints, sizeof(ints));
+ BLI_hash_mm2a_add(&mm2, (const uchar *)ints, sizeof(ints));
/* Yes, same hash here on little and big endian. */
#ifdef __LITTLE_ENDIAN__
EXPECT_EQ(hash, 405493096);
diff --git a/source/blender/blenlib/tests/BLI_heap_simple_test.cc b/source/blender/blenlib/tests/BLI_heap_simple_test.cc
index 818de67740b..96a5e42374e 100644
--- a/source/blender/blenlib/tests/BLI_heap_simple_test.cc
+++ b/source/blender/blenlib/tests/BLI_heap_simple_test.cc
@@ -18,7 +18,7 @@ static void range_fl(float *array_tar, const int size)
float *array_pt = array_tar + (size - 1);
int i = size;
while (i--) {
- *(array_pt--) = (float)i;
+ *(array_pt--) = float(i);
}
}
@@ -53,7 +53,7 @@ TEST(heap, SimpleRange)
const int items_total = SIZE;
HeapSimple *heap = BLI_heapsimple_new();
for (int in = 0; in < items_total; in++) {
- BLI_heapsimple_insert(heap, (float)in, POINTER_FROM_INT(in));
+ BLI_heapsimple_insert(heap, float(in), POINTER_FROM_INT(in));
}
for (int out_test = 0; out_test < items_total; out_test++) {
EXPECT_EQ(out_test, POINTER_AS_INT(BLI_heapsimple_pop_min(heap)));
@@ -67,7 +67,7 @@ TEST(heap, SimpleRangeReverse)
const int items_total = SIZE;
HeapSimple *heap = BLI_heapsimple_new();
for (int in = 0; in < items_total; in++) {
- BLI_heapsimple_insert(heap, (float)-in, POINTER_FROM_INT(-in));
+ BLI_heapsimple_insert(heap, float(-in), POINTER_FROM_INT(-in));
}
for (int out_test = items_total - 1; out_test >= 0; out_test--) {
EXPECT_EQ(-out_test, POINTER_AS_INT(BLI_heapsimple_pop_min(heap)));
@@ -97,7 +97,7 @@ static void random_heapsimple_helper(const int items_total, const int random_see
range_fl(values, items_total);
BLI_array_randomize(values, sizeof(float), items_total, random_seed);
for (int i = 0; i < items_total; i++) {
- BLI_heapsimple_insert(heap, values[i], POINTER_FROM_INT((int)values[i]));
+ BLI_heapsimple_insert(heap, values[i], POINTER_FROM_INT(int(values[i])));
}
for (int out_test = 0; out_test < items_total; out_test++) {
EXPECT_EQ(out_test, POINTER_AS_INT(BLI_heapsimple_pop_min(heap)));
diff --git a/source/blender/blenlib/tests/BLI_heap_test.cc b/source/blender/blenlib/tests/BLI_heap_test.cc
index 333a1530b6d..f2368ce4abf 100644
--- a/source/blender/blenlib/tests/BLI_heap_test.cc
+++ b/source/blender/blenlib/tests/BLI_heap_test.cc
@@ -17,7 +17,7 @@ static void range_fl(float *array_tar, const int size)
float *array_pt = array_tar + (size - 1);
int i = size;
while (i--) {
- *(array_pt--) = (float)i;
+ *(array_pt--) = float(i);
}
}
@@ -52,7 +52,7 @@ TEST(heap, Range)
const int items_total = SIZE;
Heap *heap = BLI_heap_new();
for (int in = 0; in < items_total; in++) {
- BLI_heap_insert(heap, (float)in, POINTER_FROM_INT(in));
+ BLI_heap_insert(heap, float(in), POINTER_FROM_INT(in));
}
for (int out_test = 0; out_test < items_total; out_test++) {
EXPECT_EQ(out_test, POINTER_AS_INT(BLI_heap_pop_min(heap)));
@@ -66,7 +66,7 @@ TEST(heap, RangeReverse)
const int items_total = SIZE;
Heap *heap = BLI_heap_new();
for (int in = 0; in < items_total; in++) {
- BLI_heap_insert(heap, (float)-in, POINTER_FROM_INT(-in));
+ BLI_heap_insert(heap, float(-in), POINTER_FROM_INT(-in));
}
for (int out_test = items_total - 1; out_test >= 0; out_test--) {
EXPECT_EQ(-out_test, POINTER_AS_INT(BLI_heap_pop_min(heap)));
@@ -81,7 +81,7 @@ TEST(heap, RangeRemove)
Heap *heap = BLI_heap_new();
HeapNode **nodes = (HeapNode **)MEM_mallocN(sizeof(HeapNode *) * items_total, __func__);
for (int in = 0; in < items_total; in++) {
- nodes[in] = BLI_heap_insert(heap, (float)in, POINTER_FROM_INT(in));
+ nodes[in] = BLI_heap_insert(heap, float(in), POINTER_FROM_INT(in));
}
for (int i = 0; i < items_total; i += 2) {
BLI_heap_remove(heap, nodes[i]);
@@ -116,7 +116,7 @@ static void random_heap_helper(const int items_total, const int random_seed)
range_fl(values, items_total);
BLI_array_randomize(values, sizeof(float), items_total, random_seed);
for (int i = 0; i < items_total; i++) {
- BLI_heap_insert(heap, values[i], POINTER_FROM_INT((int)values[i]));
+ BLI_heap_insert(heap, values[i], POINTER_FROM_INT(int(values[i])));
}
for (int out_test = 0; out_test < items_total; out_test++) {
EXPECT_EQ(out_test, POINTER_AS_INT(BLI_heap_pop_min(heap)));
@@ -145,10 +145,10 @@ TEST(heap, ReInsertSimple)
Heap *heap = BLI_heap_new();
HeapNode **nodes = (HeapNode **)MEM_mallocN(sizeof(HeapNode *) * items_total, __func__);
for (int in = 0; in < items_total; in++) {
- nodes[in] = BLI_heap_insert(heap, (float)in, POINTER_FROM_INT(in));
+ nodes[in] = BLI_heap_insert(heap, float(in), POINTER_FROM_INT(in));
}
for (int i = 0; i < items_total; i++) {
- BLI_heap_node_value_update(heap, nodes[i], (float)(items_total + i));
+ BLI_heap_node_value_update(heap, nodes[i], float(items_total + i));
}
for (int out_test = 0; out_test < items_total; out_test++) {
@@ -165,11 +165,11 @@ static void random_heap_reinsert_helper(const int items_total, const int random_
Heap *heap = BLI_heap_new();
HeapNode **nodes = (HeapNode **)MEM_mallocN(sizeof(HeapNode *) * items_total, __func__);
for (int in = 0; in < items_total; in++) {
- nodes[in] = BLI_heap_insert(heap, (float)in, POINTER_FROM_INT(in));
+ nodes[in] = BLI_heap_insert(heap, float(in), POINTER_FROM_INT(in));
}
BLI_array_randomize(nodes, sizeof(HeapNode *), items_total, random_seed);
for (int i = 0; i < items_total; i++) {
- BLI_heap_node_value_update(heap, nodes[i], (float)i);
+ BLI_heap_node_value_update(heap, nodes[i], float(i));
}
EXPECT_TRUE(BLI_heap_is_valid(heap));
@@ -177,7 +177,7 @@ static void random_heap_reinsert_helper(const int items_total, const int random_
HeapNode *node_top = BLI_heap_top(heap);
float out = BLI_heap_node_value(node_top);
EXPECT_EQ(out, BLI_heap_top_value(heap));
- EXPECT_EQ((float)out_test, out);
+ EXPECT_EQ(float(out_test), out);
BLI_heap_pop_min(heap);
}
EXPECT_TRUE(BLI_heap_is_empty(heap));
diff --git a/source/blender/blenlib/tests/BLI_index_range_test.cc b/source/blender/blenlib/tests/BLI_index_range_test.cc
index 955691b3430..8ec7ad85d9c 100644
--- a/source/blender/blenlib/tests/BLI_index_range_test.cc
+++ b/source/blender/blenlib/tests/BLI_index_range_test.cc
@@ -126,6 +126,17 @@ TEST(index_range, Slice)
EXPECT_EQ(slice.last(), 12);
}
+TEST(index_range, Intersect)
+{
+ IndexRange range = IndexRange(5, 15);
+ EXPECT_EQ(range.intersect(IndexRange(2, 2)), IndexRange(5, 0));
+ EXPECT_EQ(range.intersect(IndexRange(4, 2)), IndexRange(5, 1));
+ EXPECT_EQ(range.intersect(IndexRange(3, 20)), IndexRange(5, 15));
+ EXPECT_EQ(range.intersect(IndexRange(5, 15)), IndexRange(5, 15));
+ EXPECT_EQ(range.intersect(IndexRange(15, 10)), IndexRange(15, 5));
+ EXPECT_EQ(range.intersect(IndexRange(22, 2)), IndexRange(20, 0));
+}
+
TEST(index_range, SliceRange)
{
IndexRange range = IndexRange(5, 15);
diff --git a/source/blender/blenlib/tests/BLI_kdopbvh_test.cc b/source/blender/blenlib/tests/BLI_kdopbvh_test.cc
index 756219cd733..83eeabaea40 100644
--- a/source/blender/blenlib/tests/BLI_kdopbvh_test.cc
+++ b/source/blender/blenlib/tests/BLI_kdopbvh_test.cc
@@ -18,7 +18,7 @@ static void rng_v3_round(float *coords, int coords_len, struct RNG *rng, int rou
{
for (int i = 0; i < coords_len; i++) {
float f = BLI_rng_get_float(rng) * 2.0f - 1.0f;
- coords[i] = ((float)((int)(f * round)) / (float)round) * scale;
+ coords[i] = (float(int(f * round)) / float(round)) * scale;
}
}
@@ -90,7 +90,7 @@ static void find_nearest_points_test(
if (j != i) {
#if 0
const float dist = len_v3v3(points[i], points[j]);
- if (dist > (1.0f / (float)round)) {
+ if (dist > (1.0f / float(round))) {
printf("%.15f (%d %d)\n", dist, i, j);
print_v3_id(points[i]);
print_v3_id(points[j]);
diff --git a/source/blender/blenlib/tests/BLI_linear_allocator_test.cc b/source/blender/blenlib/tests/BLI_linear_allocator_test.cc
index b67683d0558..2ed1786f9e0 100644
--- a/source/blender/blenlib/tests/BLI_linear_allocator_test.cc
+++ b/source/blender/blenlib/tests/BLI_linear_allocator_test.cc
@@ -9,7 +9,7 @@ namespace blender::tests {
static bool is_aligned(void *ptr, uint alignment)
{
- BLI_assert(is_power_of_2_i(static_cast<int>(alignment)));
+ BLI_assert(is_power_of_2_i(int(alignment)));
return (POINTER_AS_UINT(ptr) & (alignment - 1)) == 0;
}
@@ -36,13 +36,13 @@ TEST(linear_allocator, PackedAllocation)
blender::AlignedBuffer<256, 32> buffer;
allocator.provide_buffer(buffer);
- uintptr_t ptr1 = (uintptr_t)allocator.allocate(10, 4); /* 0 - 10 */
- uintptr_t ptr2 = (uintptr_t)allocator.allocate(10, 4); /* 12 - 22 */
- uintptr_t ptr3 = (uintptr_t)allocator.allocate(8, 32); /* 32 - 40 */
- uintptr_t ptr4 = (uintptr_t)allocator.allocate(16, 8); /* 40 - 56 */
- uintptr_t ptr5 = (uintptr_t)allocator.allocate(1, 8); /* 56 - 57 */
- uintptr_t ptr6 = (uintptr_t)allocator.allocate(1, 4); /* 60 - 61 */
- uintptr_t ptr7 = (uintptr_t)allocator.allocate(1, 1); /* 61 - 62 */
+ uintptr_t ptr1 = uintptr_t(allocator.allocate(10, 4)); /* 0 - 10 */
+ uintptr_t ptr2 = uintptr_t(allocator.allocate(10, 4)); /* 12 - 22 */
+ uintptr_t ptr3 = uintptr_t(allocator.allocate(8, 32)); /* 32 - 40 */
+ uintptr_t ptr4 = uintptr_t(allocator.allocate(16, 8)); /* 40 - 56 */
+ uintptr_t ptr5 = uintptr_t(allocator.allocate(1, 8)); /* 56 - 57 */
+ uintptr_t ptr6 = uintptr_t(allocator.allocate(1, 4)); /* 60 - 61 */
+ uintptr_t ptr7 = uintptr_t(allocator.allocate(1, 1)); /* 61 - 62 */
EXPECT_EQ(ptr2 - ptr1, 12); /* 12 - 0 = 12 */
EXPECT_EQ(ptr3 - ptr2, 20); /* 32 - 12 = 20 */
@@ -130,7 +130,7 @@ TEST(linear_allocator, ManyAllocations)
RandomNumberGenerator rng;
for (int i = 0; i < 1000; i++) {
int size = rng.get_int32(10000);
- int alignment = 1 << (rng.get_int32(7));
+ int alignment = 1 << rng.get_int32(7);
void *buffer = allocator.allocate(size, alignment);
EXPECT_NE(buffer, nullptr);
}
diff --git a/source/blender/blenlib/tests/BLI_listbase_test.cc b/source/blender/blenlib/tests/BLI_listbase_test.cc
index aa2f885e39d..abdd4f90221 100644
--- a/source/blender/blenlib/tests/BLI_listbase_test.cc
+++ b/source/blender/blenlib/tests/BLI_listbase_test.cc
@@ -222,7 +222,7 @@ static bool testsort_listbase_array_str_cmp(ListBase *lb, char **arr, int arr_nu
link_step = (LinkData *)lb->first;
for (i = 0; i < arr_num; i++) {
- if (strcmp(arr[i], (char *)link_step->data) != 0) {
+ if (!STREQ(arr[i], (char *)link_step->data)) {
return false;
}
link_step = link_step->next;
@@ -241,7 +241,7 @@ static bool testsort_listbase_sort_is_stable(ListBase *lb, bool forward)
link_step = (LinkData *)lb->first;
while (link_step && link_step->next) {
- if (strcmp((const char *)link_step->data, (const char *)link_step->next->data) == 0) {
+ if (STREQ((const char *)link_step->data, (const char *)link_step->next->data)) {
if ((link_step < link_step->next) != forward) {
return false;
}
diff --git a/source/blender/blenlib/tests/BLI_map_test.cc b/source/blender/blenlib/tests/BLI_map_test.cc
index dbbd4843abc..69ae82d6f05 100644
--- a/source/blender/blenlib/tests/BLI_map_test.cc
+++ b/source/blender/blenlib/tests/BLI_map_test.cc
@@ -560,8 +560,8 @@ TEST(map, PopExceptions)
TEST(map, AddOrModifyExceptions)
{
Map<ExceptionThrower, ExceptionThrower> map;
- auto create_fn = [](ExceptionThrower *UNUSED(v)) { throw std::runtime_error(""); };
- auto modify_fn = [](ExceptionThrower *UNUSED(v)) {};
+ auto create_fn = [](ExceptionThrower * /*v*/) { throw std::runtime_error(""); };
+ auto modify_fn = [](ExceptionThrower * /*v*/) {};
EXPECT_ANY_THROW({ map.add_or_modify(3, create_fn, modify_fn); });
}
@@ -640,6 +640,24 @@ TEST(map, RemoveDuringIteration)
EXPECT_EQ(map.lookup(3), 3);
}
+TEST(map, RemoveIf)
+{
+ Map<int64_t, int64_t> map;
+ for (const int64_t i : IndexRange(100)) {
+ map.add(i * i, i);
+ }
+ map.remove_if([](auto item) { return item.key > 100; });
+ EXPECT_EQ(map.size(), 11);
+ for (const int64_t i : IndexRange(100)) {
+ if (i <= 10) {
+ EXPECT_EQ(map.lookup(i * i), i);
+ }
+ else {
+ EXPECT_FALSE(map.contains(i * i));
+ }
+ }
+}
+
TEST(map, LookupKey)
{
Map<std::string, int> map;
diff --git a/source/blender/blenlib/tests/BLI_math_color_test.cc b/source/blender/blenlib/tests/BLI_math_color_test.cc
index 4d928477870..0b6f9340379 100644
--- a/source/blender/blenlib/tests/BLI_math_color_test.cc
+++ b/source/blender/blenlib/tests/BLI_math_color_test.cc
@@ -68,7 +68,7 @@ TEST(math_color, LinearRGBTosRGBRoundtrip)
const int N = 50;
int i;
for (i = 0; i < N; ++i) {
- float orig_linear_color = (float)i / N;
+ float orig_linear_color = float(i) / N;
float srgb_color = linearrgb_to_srgb(orig_linear_color);
float linear_color = srgb_to_linearrgb(srgb_color);
EXPECT_NEAR(orig_linear_color, linear_color, 1e-5);
diff --git a/source/blender/blenlib/tests/BLI_math_rotation_test.cc b/source/blender/blenlib/tests/BLI_math_rotation_test.cc
index 460cfd2d36c..0c8ae38c386 100644
--- a/source/blender/blenlib/tests/BLI_math_rotation_test.cc
+++ b/source/blender/blenlib/tests/BLI_math_rotation_test.cc
@@ -3,6 +3,7 @@
#include "testing/testing.h"
#include "BLI_math_base.h"
+#include "BLI_math_matrix.h"
#include "BLI_math_rotation.h"
#include "BLI_math_rotation.hh"
#include "BLI_math_vector.hh"
@@ -138,6 +139,21 @@ TEST(math_rotation, quat_to_mat_to_quat_near_0001)
test_quat_to_mat_to_quat(0.30f, -0.030f, -0.30f, 0.95f);
}
+/* A zeroed matrix converted to a quaternion and back should not add rotation, see: T101848 */
+TEST(math_rotation, quat_to_mat_to_quat_zeroed_matrix)
+{
+ float matrix_zeroed[3][3] = {{0.0f}};
+ float matrix_result[3][3];
+ float matrix_unit[3][3];
+ float out_quat[4];
+
+ unit_m3(matrix_unit);
+ mat3_normalized_to_quat(out_quat, matrix_zeroed);
+ quat_to_mat3(matrix_result, out_quat);
+
+ EXPECT_M3_NEAR(matrix_unit, matrix_result, FLT_EPSILON);
+}
+
TEST(math_rotation, quat_split_swing_and_twist_negative)
{
const float input[4] = {-0.5f, 0, sqrtf(3) / 2, 0};
@@ -161,7 +177,7 @@ static void test_sin_cos_from_fraction_accuracy(const int range, const float exp
for (int i = 0; i < range; i++) {
float sin_cos_fl[2];
sin_cos_from_fraction(i, range, &sin_cos_fl[0], &sin_cos_fl[1]);
- const float phi = (float)(2.0 * M_PI) * ((float)i / (float)range);
+ const float phi = float(2.0 * M_PI) * (float(i) / float(range));
const float sin_cos_test_fl[2] = {sinf(phi), cosf(phi)};
EXPECT_V2_NEAR(sin_cos_fl, sin_cos_test_fl, expected_eps);
}
diff --git a/source/blender/blenlib/tests/BLI_memory_utils_test.cc b/source/blender/blenlib/tests/BLI_memory_utils_test.cc
index ab716e5d011..939ac6151b0 100644
--- a/source/blender/blenlib/tests/BLI_memory_utils_test.cc
+++ b/source/blender/blenlib/tests/BLI_memory_utils_test.cc
@@ -20,7 +20,7 @@ struct MyValue {
alive++;
}
- MyValue(const MyValue &UNUSED(other))
+ MyValue(const MyValue & /*other*/)
{
if (alive == 15) {
throw std::exception();
diff --git a/source/blender/blenlib/tests/BLI_mesh_boolean_test.cc b/source/blender/blenlib/tests/BLI_mesh_boolean_test.cc
index fabc2412828..ea324534d78 100644
--- a/source/blender/blenlib/tests/BLI_mesh_boolean_test.cc
+++ b/source/blender/blenlib/tests/BLI_mesh_boolean_test.cc
@@ -106,7 +106,7 @@ class IMeshBuilder {
}
};
-static int all_shape_zero(int UNUSED(t))
+static int all_shape_zero(int /*t*/)
{
return 0;
}
diff --git a/source/blender/blenlib/tests/BLI_mesh_intersect_test.cc b/source/blender/blenlib/tests/BLI_mesh_intersect_test.cc
index c155068b94a..67a5771593a 100644
--- a/source/blender/blenlib/tests/BLI_mesh_intersect_test.cc
+++ b/source/blender/blenlib/tests/BLI_mesh_intersect_test.cc
@@ -153,7 +153,7 @@ static int find_edge_pos_in_tri(const Vert *v0, const Vert *v1, const Face *f)
for (int pos : f->index_range()) {
int nextpos = f->next_pos(pos);
if (((*f)[pos] == v0 && (*f)[nextpos] == v1) || ((*f)[pos] == v1 && (*f)[nextpos] == v0)) {
- return static_cast<int>(pos);
+ return int(pos);
}
}
return -1;
diff --git a/source/blender/blenlib/tests/BLI_path_util_test.cc b/source/blender/blenlib/tests/BLI_path_util_test.cc
index 54afc3d975d..9d5422d62ff 100644
--- a/source/blender/blenlib/tests/BLI_path_util_test.cc
+++ b/source/blender/blenlib/tests/BLI_path_util_test.cc
@@ -9,69 +9,166 @@
#include "BLI_string.h"
/* -------------------------------------------------------------------- */
-/* tests */
+/** \name Local Utilities
+ * \{ */
-/* BLI_path_normalize */
-#ifndef _WIN32
-TEST(path_util, Clean)
+static void str_replace_char_with_relative_exception(char *str, char src, char dst)
{
- /* "/./" -> "/" */
- {
- char path[FILE_MAX] = "/a/./b/./c/./";
- BLI_path_normalize(nullptr, path);
- EXPECT_STREQ("/a/b/c/", path);
+ /* Always keep "//" or more leading slashes (special meaning). */
+ if (src == '/') {
+ if (str[0] == '/' && str[1] == '/') {
+ str += 2;
+ while (*str == '/') {
+ str++;
+ }
+ }
}
+ BLI_str_replace_char(str, src, dst);
+}
- {
- char path[FILE_MAX] = "/./././";
- BLI_path_normalize(nullptr, path);
- EXPECT_STREQ("/", path);
+static char *str_replace_char_strdup(const char *str, char src, char dst)
+{
+ if (str == nullptr) {
+ return nullptr;
}
+ char *str_dupe = strdup(str);
+ BLI_str_replace_char(str_dupe, src, dst);
+ return str_dupe;
+}
- {
- char path[FILE_MAX] = "/a/./././b/";
- BLI_path_normalize(nullptr, path);
- EXPECT_STREQ("/a/b/", path);
- }
+/** \} */
- /* "//" -> "/" */
- {
- char path[FILE_MAX] = "a////";
- BLI_path_normalize(nullptr, path);
- EXPECT_STREQ("a/", path);
- }
+/* -------------------------------------------------------------------- */
+/** \name Tests for: #BLI_path_normalize
+ * \{ */
- if (false) /* FIXME */
- {
- char path[FILE_MAX] = "./a////";
- BLI_path_normalize(nullptr, path);
- EXPECT_STREQ("./a/", path);
- }
+#define NORMALIZE_WITH_BASEDIR(input, input_base, output) \
+ { \
+ char path[FILE_MAX] = input; \
+ const char *input_base_test = input_base; \
+ if (SEP == '\\') { \
+ str_replace_char_with_relative_exception(path, '/', '\\'); \
+ input_base_test = str_replace_char_strdup(input_base_test, '/', '\\'); \
+ } \
+ BLI_path_normalize(input_base_test, path); \
+ if (SEP == '\\') { \
+ BLI_str_replace_char(path, '\\', '/'); \
+ if (input_base_test) { \
+ free((void *)input_base_test); \
+ } \
+ } \
+ EXPECT_STREQ(output, path); \
+ } \
+ ((void)0)
- /* "foo/bar/../" -> "foo/" */
- {
- char path[FILE_MAX] = "/a/b/c/../../../";
- BLI_path_normalize(nullptr, path);
- EXPECT_STREQ("/", path);
- }
+#define NORMALIZE(input, output) NORMALIZE_WITH_BASEDIR(input, nullptr, output)
- {
- char path[FILE_MAX] = "/a/../a/b/../b/c/../c/";
- BLI_path_normalize(nullptr, path);
- EXPECT_STREQ("/a/b/c/", path);
- }
+/* #BLI_path_normalize: "/./" -> "/" */
+TEST(path_util, Clean_Dot)
+{
+ NORMALIZE("/./", "/");
+ NORMALIZE("/a/./b/./c/./", "/a/b/c/");
+ NORMALIZE("/./././", "/");
+ NORMALIZE("/a/./././b/", "/a/b/");
+}
+/* #BLI_path_normalize: complex "/./" -> "/", "//" -> "/", "./path/../" -> "./". */
+TEST(path_util, Clean_Complex)
+{
+ NORMALIZE("/a/./b/./c/./.././.././", "/a/");
+ NORMALIZE("/a//.//b//.//c//.//..//.//..//.//", "/a/");
+}
+/* #BLI_path_normalize: "//" -> "/" */
+TEST(path_util, Clean_DoubleSlash)
+{
+ NORMALIZE("//", "//"); /* Exception, double forward slash. */
+ NORMALIZE(".//", "./");
+ NORMALIZE("a////", "a/");
+ NORMALIZE("./a////", "./a/");
+}
+/* #BLI_path_normalize: "foo/bar/../" -> "foo/" */
+TEST(path_util, Clean_Parent)
+{
+ NORMALIZE("/a/b/c/../../../", "/");
+ NORMALIZE("/a/../a/b/../b/c/../c/", "/a/b/c/");
+ NORMALIZE_WITH_BASEDIR("//../", "/a/b/c/", "/a/b/");
+}
- {
- char path[FILE_MAX] = "//../";
- BLI_path_normalize("/a/b/c/", path);
- EXPECT_STREQ("/a/b/", path);
- }
+#undef NORMALIZE_WITH_BASEDIR
+#undef NORMALIZE
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Tests for: #BLI_path_parent_dir
+ * \{ */
+
+#define PARENT_DIR(input, output) \
+ { \
+ char path[FILE_MAX] = input; \
+ if (SEP == '\\') { \
+ BLI_str_replace_char(path, '/', '\\'); \
+ } \
+ BLI_path_parent_dir(path); \
+ if (SEP == '\\') { \
+ BLI_str_replace_char(path, '\\', '/'); \
+ } \
+ EXPECT_STREQ(output, path); \
+ } \
+ ((void)0)
+
+TEST(path_util, ParentDir_Simple)
+{
+ PARENT_DIR("/a/b/", "/a/");
+ PARENT_DIR("/a/b", "/a/");
+ PARENT_DIR("/a", "/");
}
-#endif
+
+TEST(path_util, ParentDir_NOP)
+{
+ PARENT_DIR("/", "/");
+ PARENT_DIR("", "");
+ PARENT_DIR(".", ".");
+ PARENT_DIR("./", "./");
+ PARENT_DIR(".//", ".//");
+ PARENT_DIR("./.", "./.");
+}
+
+TEST(path_util, ParentDir_TrailingPeriod)
+{
+ /* Ensure trailing dots aren't confused with parent path. */
+ PARENT_DIR("/.../.../.../", "/.../.../");
+ PARENT_DIR("/.../.../...", "/.../.../");
+
+ PARENT_DIR("/a../b../c../", "/a../b../");
+ PARENT_DIR("/a../b../c..", "/a../b../");
+
+ PARENT_DIR("/a./b./c./", "/a./b./");
+ PARENT_DIR("/a./b./c.", "/a./b./");
+}
+
+TEST(path_util, ParentDir_Complex)
+{
+ PARENT_DIR("./a/", "./");
+ PARENT_DIR("./a", "./");
+ PARENT_DIR("../a/", "../");
+ PARENT_DIR("../a", "../");
+}
+
+#undef PARENT_DIR
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Tests for: #BLI_path_name_at_index
+ * \{ */
#define AT_INDEX(str_input, index_input, str_expect) \
{ \
char path[] = str_input; \
+ /* Test input assumes forward slash, support back-slash on WIN32. */ \
+ if (SEP == '\\') { \
+ BLI_str_replace_char(path, '/', '\\'); \
+ } \
const char *expect = str_expect; \
int index_output, len_output; \
const bool ret = BLI_path_name_at_index(path, index_input, &index_output, &len_output); \
@@ -87,7 +184,6 @@ TEST(path_util, Clean)
} \
((void)0)
-/* BLI_path_name_at_index */
TEST(path_util, NameAtIndex_Single)
{
AT_INDEX("/a", 0, "a");
@@ -163,24 +259,82 @@ TEST(path_util, NameAtIndex_MiscNeg)
AT_INDEX("/how/now/brown/cow/", 4, nullptr);
}
+#define TEST_STR "./a/./b/./c/."
+
+TEST(path_util, NameAtIndex_SingleDot)
+{
+ AT_INDEX(TEST_STR, 0, ".");
+ AT_INDEX(TEST_STR, 1, "a");
+ AT_INDEX(TEST_STR, 2, "b");
+ AT_INDEX(TEST_STR, 3, "c");
+ AT_INDEX(TEST_STR, 4, nullptr);
+}
+
+TEST(path_util, NameAtIndex_SingleDotNeg)
+{
+ AT_INDEX(TEST_STR, -5, nullptr);
+ AT_INDEX(TEST_STR, -4, ".");
+ AT_INDEX(TEST_STR, -3, "a");
+ AT_INDEX(TEST_STR, -2, "b");
+ AT_INDEX(TEST_STR, -1, "c");
+}
+
+#undef TEST_STR
+
+#define TEST_STR ".//a//.//b//.//c//.//"
+
+TEST(path_util, NameAtIndex_SingleDotDoubleSlash)
+{
+ AT_INDEX(TEST_STR, 0, ".");
+ AT_INDEX(TEST_STR, 1, "a");
+ AT_INDEX(TEST_STR, 2, "b");
+ AT_INDEX(TEST_STR, 3, "c");
+ AT_INDEX(TEST_STR, 4, nullptr);
+}
+
+TEST(path_util, NameAtIndex_SingleDotDoubleSlashNeg)
+{
+ AT_INDEX(TEST_STR, -5, nullptr);
+ AT_INDEX(TEST_STR, -4, ".");
+ AT_INDEX(TEST_STR, -3, "a");
+ AT_INDEX(TEST_STR, -2, "b");
+ AT_INDEX(TEST_STR, -1, "c");
+}
+
+#undef TEST_STR
+
+TEST(path_util, NameAtIndex_SingleDotSeries)
+{
+ AT_INDEX("abc/././/././xyz", 0, "abc");
+ AT_INDEX("abc/././/././xyz", 1, "xyz");
+ AT_INDEX("abc/././/././xyz", 2, nullptr);
+}
+
+TEST(path_util, NameAtIndex_SingleDotSeriesNeg)
+{
+ AT_INDEX("abc/././/././xyz", -3, nullptr);
+ AT_INDEX("abc/././/././xyz", -2, "abc");
+ AT_INDEX("abc/././/././xyz", -1, "xyz");
+}
+
TEST(path_util, NameAtIndex_MiscComplex)
{
AT_INDEX("how//now/brown/cow", 0, "how");
- AT_INDEX("//how///now\\/brown/cow", 1, "now");
- AT_INDEX("/how/now\\//brown\\/cow", 2, "brown");
- AT_INDEX("/how/now/brown/cow//\\", 3, "cow");
- AT_INDEX("/how/now/brown/\\cow", 4, nullptr);
- AT_INDEX("how/now/brown/\\cow\\", 4, nullptr);
+ AT_INDEX("//how///now//brown/cow", 1, "now");
+ AT_INDEX("/how/now///brown//cow", 2, "brown");
+ AT_INDEX("/how/now/brown/cow///", 3, "cow");
+ AT_INDEX("/how/now/brown//cow", 4, nullptr);
+ AT_INDEX("how/now/brown//cow/", 4, nullptr);
}
TEST(path_util, NameAtIndex_MiscComplexNeg)
{
AT_INDEX("how//now/brown/cow", -4, "how");
- AT_INDEX("//how///now\\/brown/cow", -3, "now");
- AT_INDEX("/how/now\\//brown\\/cow", -2, "brown");
- AT_INDEX("/how/now/brown/cow//\\", -1, "cow");
- AT_INDEX("/how/now/brown/\\cow", -5, nullptr);
- AT_INDEX("how/now/brown/\\cow\\", -5, nullptr);
+ AT_INDEX("//how///now//brown/cow", -3, "now");
+ AT_INDEX("/how/now///brown//cow", -2, "brown");
+ AT_INDEX("/how/now/brown/cow///", -1, "cow");
+ AT_INDEX("/how/now/brown//cow", -5, nullptr);
+ AT_INDEX("how/now/brown//cow/", -5, nullptr);
}
TEST(path_util, NameAtIndex_NoneComplex)
@@ -201,21 +355,59 @@ TEST(path_util, NameAtIndex_NoneComplexNeg)
#undef AT_INDEX
-#define JOIN(str_expect, out_size, ...) \
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Tests for: #BLI_path_join
+ * \{ */
+
+/* For systems with `/` path separator (non WIN32). */
+#define JOIN_FORWARD_SLASH(str_expect, out_size, ...) \
{ \
const char *expect = str_expect; \
char result[(out_size) + 1024]; \
- /* check we don't write past the last byte */ \
+ /* Check we don't write past the last byte. */ \
result[out_size] = '\0'; \
- BLI_path_join(result, out_size, __VA_ARGS__, NULL); \
- /* simplify expected string */ \
+ BLI_path_join(result, out_size, __VA_ARGS__); \
+ EXPECT_STREQ(result, expect); \
+ EXPECT_EQ(result[out_size], '\0'); \
+ } \
+ ((void)0)
+
+/* For systems with `\` path separator (WIN32).
+ * Perform additional manipulation to behave as if input arguments used `\` separators.
+ * Needed since #BLI_path_join uses native slashes. */
+#define JOIN_BACK_SLASH(str_expect, out_size, ...) \
+ { \
+ const char *expect = str_expect; \
+ char result[(out_size) + 1024]; \
+ const char *input_forward_slash[] = {__VA_ARGS__}; \
+ char *input_back_slash[ARRAY_SIZE(input_forward_slash)] = {nullptr}; \
+ for (int i = 0; i < ARRAY_SIZE(input_forward_slash); i++) { \
+ input_back_slash[i] = strdup(input_forward_slash[i]); \
+ BLI_str_replace_char(input_back_slash[i], '/', '\\'); \
+ } \
+ /* Check we don't write past the last byte. */ \
+ result[out_size] = '\0'; \
+ BLI_path_join_array(result, \
+ out_size, \
+ const_cast<const char **>(input_back_slash), \
+ ARRAY_SIZE(input_back_slash)); \
BLI_str_replace_char(result, '\\', '/'); \
EXPECT_STREQ(result, expect); \
EXPECT_EQ(result[out_size], '\0'); \
+ for (int i = 0; i < ARRAY_SIZE(input_forward_slash); i++) { \
+ free(input_back_slash[i]); \
+ } \
} \
((void)0)
-/* BLI_path_join */
+#ifdef WIN32
+# define JOIN JOIN_BACK_SLASH
+#else
+# define JOIN JOIN_FORWARD_SLASH
+#endif
+
TEST(path_util, JoinNop)
{
JOIN("", 100, "");
@@ -293,9 +485,9 @@ TEST(path_util, JoinTruncateLong)
TEST(path_util, JoinComplex)
{
- JOIN("/a/b/c/d/e/f/g/", 100, "/", "\\a/b", "//////c/d", "", "e\\\\", "f", "g//");
- JOIN("/aa/bb/cc/dd/ee/ff/gg/", 100, "/", "\\aa/bb", "//////cc/dd", "", "ee\\\\", "ff", "gg//");
- JOIN("1/2/3/", 100, "1", "////////", "", "2", "3\\");
+ JOIN("/a/b/c/d/e/f/g/", 100, "/", "a/b", "//////c/d", "", "e", "f", "g//");
+ JOIN("/aa/bb/cc/dd/ee/ff/gg/", 100, "/", "aa/bb", "//////cc/dd", "", "ee", "ff", "gg//");
+ JOIN("1/2/3/", 100, "1", "////////", "", "2", "3///");
}
TEST(path_util, JoinRelativePrefix)
@@ -306,8 +498,15 @@ TEST(path_util, JoinRelativePrefix)
}
#undef JOIN
+#undef JOIN_BACK_SLASH
+#undef JOIN_FORWARD_SLASH
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Tests for: #BLI_path_frame
+ * \{ */
-/* BLI_path_frame */
TEST(path_util, Frame)
{
bool ret;
@@ -384,7 +583,12 @@ TEST(path_util, Frame)
}
}
-/* BLI_split_dirfile */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Tests for: #BLI_split_dirfile
+ * \{ */
+
TEST(path_util, SplitDirfile)
{
{
@@ -440,6 +644,12 @@ TEST(path_util, SplitDirfile)
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Tests for: #BLI_path_frame_strip
+ * \{ */
+
#define PATH_FRAME_STRIP(input_path, expect_path, expect_ext) \
{ \
char path[FILE_MAX]; \
@@ -451,7 +661,6 @@ TEST(path_util, SplitDirfile)
} \
((void)0)
-/* BLI_path_frame_strip */
TEST(path_util, PathFrameStrip)
{
PATH_FRAME_STRIP("", "", "");
@@ -463,10 +672,16 @@ TEST(path_util, PathFrameStrip)
}
#undef PATH_FRAME_STRIP
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Tests for: #BLI_path_extension_check
+ * \{ */
+
#define PATH_EXTENSION_CHECK(input_path, input_ext, expect_ext) \
{ \
const bool ret = BLI_path_extension_check(input_path, input_ext); \
- if (strcmp(input_ext, expect_ext) == 0) { \
+ if (STREQ(input_ext, expect_ext)) { \
EXPECT_TRUE(ret); \
} \
else { \
@@ -475,7 +690,6 @@ TEST(path_util, PathFrameStrip)
} \
((void)0)
-/* BLI_path_extension_check */
TEST(path_util, PathExtensionCheck)
{
PATH_EXTENSION_CHECK("a/b/c.exe", ".exe", ".exe");
@@ -501,6 +715,12 @@ TEST(path_util, PathExtensionCheck)
}
#undef PATH_EXTENSION_CHECK
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Tests for: #BLI_path_frame_check_chars
+ * \{ */
+
#define PATH_FRAME_CHECK_CHARS(input_path, expect_hasChars) \
{ \
const bool ret = BLI_path_frame_check_chars(input_path); \
@@ -513,7 +733,6 @@ TEST(path_util, PathExtensionCheck)
} \
((void)0)
-/* BLI_path_frame_check_chars */
TEST(path_util, PathFrameCheckChars)
{
PATH_FRAME_CHECK_CHARS("a#", true);
@@ -533,6 +752,12 @@ TEST(path_util, PathFrameCheckChars)
}
#undef PATH_FRAME_CHECK_CHARS
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Tests for: #BLI_path_frame_range
+ * \{ */
+
#define PATH_FRAME_RANGE(input_path, sta, end, digits, expect_outpath) \
{ \
char path[FILE_MAX]; \
@@ -549,7 +774,6 @@ TEST(path_util, PathFrameCheckChars)
} \
((void)0)
-/* BLI_path_frame_range */
TEST(path_util, PathFrameRange)
{
int dummy = -1;
@@ -565,6 +789,12 @@ TEST(path_util, PathFrameRange)
}
#undef PATH_FRAME_RANGE
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Tests for: #BLI_path_frame_get
+ * \{ */
+
#define PATH_FRAME_GET(input_path, expect_frame, expect_numdigits, expect_pathisvalid) \
{ \
char path[FILE_MAX]; \
@@ -582,7 +812,6 @@ TEST(path_util, PathFrameRange)
} \
((void)0)
-/* BLI_path_frame_get */
TEST(path_util, PathFrameGet)
{
PATH_FRAME_GET("001.avi", 1, 3, true);
@@ -594,7 +823,12 @@ TEST(path_util, PathFrameGet)
}
#undef PATH_FRAME_GET
-/* BLI_path_extension */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Tests for: #BLI_path_extension
+ * \{ */
+
TEST(path_util, PathExtension)
{
EXPECT_EQ(nullptr, BLI_path_extension("some.def/file"));
@@ -608,62 +842,88 @@ TEST(path_util, PathExtension)
EXPECT_STREQ(".001", BLI_path_extension("Text.001"));
}
-/* BLI_path_rel. */
-#ifndef _WIN32
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Tests for: #BLI_path_rel
+ * \{ */
-# define PATH_REL(abs_path, ref_path, rel_path) \
- { \
- char path[FILE_MAX]; \
- BLI_strncpy(path, abs_path, sizeof(path)); \
- BLI_path_rel(path, ref_path); \
- EXPECT_STREQ(rel_path, path); \
+#define PATH_REL(abs_path, ref_path, rel_path) \
+ { \
+ char path[FILE_MAX]; \
+ const char *ref_path_test = ref_path; \
+ BLI_strncpy(path, abs_path, sizeof(path)); \
+ if (SEP == '\\') { \
+ BLI_str_replace_char(path, '/', '\\'); \
+ ref_path_test = str_replace_char_strdup(ref_path_test, '/', '\\'); \
+ } \
+ BLI_path_rel(path, ref_path_test); \
+ if (SEP == '\\') { \
+ BLI_str_replace_char(path, '\\', '/'); \
+ free((void *)ref_path_test); \
} \
- void(0)
+ EXPECT_STREQ(rel_path, path); \
+ } \
+ void(0)
-TEST(path_util, PathRelPath)
+#ifdef WIN32
+# define ABS_PREFIX "C:"
+#else
+# define ABS_PREFIX ""
+#endif
+
+TEST(path_util, PathRelPath_Simple)
{
- PATH_REL("/foo/bar/blender.blend", "/foo/bar/", "//blender.blend");
- PATH_REL("/foo/bar/blender.blend", "/foo/bar", "//bar/blender.blend");
+ PATH_REL(ABS_PREFIX "/foo/bar/blender.blend", ABS_PREFIX "/foo/bar/", "//blender.blend");
+}
- /* Check for potential buffer overflows. */
- {
- char abs_path_in[FILE_MAX];
- abs_path_in[0] = '/';
- for (int i = 1; i < FILE_MAX - 1; i++) {
- abs_path_in[i] = 'A';
- }
- abs_path_in[FILE_MAX - 1] = '\0';
- char abs_path_out[FILE_MAX];
- abs_path_out[0] = '/';
- abs_path_out[1] = '/';
- for (int i = 2; i < FILE_MAX - 1; i++) {
- abs_path_out[i] = 'A';
- }
- abs_path_out[FILE_MAX - 1] = '\0';
- PATH_REL(abs_path_in, "/", abs_path_out);
-
- const char *ref_path_in = "/foo/bar/";
- const size_t ref_path_in_len = strlen(ref_path_in);
- strcpy(abs_path_in, ref_path_in);
- for (int i = ref_path_in_len; i < FILE_MAX - 1; i++) {
- abs_path_in[i] = 'A';
- }
- abs_path_in[FILE_MAX - 1] = '\0';
- abs_path_out[0] = '/';
- abs_path_out[1] = '/';
- for (int i = 2; i < FILE_MAX - ((int)ref_path_in_len - 1); i++) {
- abs_path_out[i] = 'A';
- }
- abs_path_out[FILE_MAX - (ref_path_in_len - 1)] = '\0';
- PATH_REL(abs_path_in, ref_path_in, abs_path_out);
+TEST(path_util, PathRelPath_SimpleSubdir)
+{
+ PATH_REL(ABS_PREFIX "/foo/bar/blender.blend", ABS_PREFIX "/foo/bar", "//bar/blender.blend");
+}
+
+TEST(path_util, PathRelPath_BufferOverflowRoot)
+{
+ char abs_path_in[FILE_MAX];
+ const char *abs_prefix = ABS_PREFIX "/";
+ for (int i = STRNCPY_RLEN(abs_path_in, abs_prefix); i < FILE_MAX - 1; i++) {
+ abs_path_in[i] = 'A';
}
+ abs_path_in[FILE_MAX - 1] = '\0';
+ char abs_path_out[FILE_MAX];
+ for (int i = STRNCPY_RLEN(abs_path_out, "//"); i < FILE_MAX - 1; i++) {
+ abs_path_out[i] = 'A';
+ }
+ abs_path_out[FILE_MAX - std::max((strlen(abs_prefix) - 1), size_t(1))] = '\0';
+ PATH_REL(abs_path_in, abs_prefix, abs_path_out);
}
-# undef PATH_REL
+TEST(path_util, PathRelPath_BufferOverflowSubdir)
+{
+ char abs_path_in[FILE_MAX];
+ const char *ref_path_in = ABS_PREFIX "/foo/bar/";
+ const size_t ref_path_in_len = strlen(ref_path_in);
+ for (int i = STRNCPY_RLEN(abs_path_in, ref_path_in); i < FILE_MAX - 1; i++) {
+ abs_path_in[i] = 'A';
+ }
+ abs_path_in[FILE_MAX - 1] = '\0';
+ char abs_path_out[FILE_MAX];
+ for (int i = STRNCPY_RLEN(abs_path_out, "//"); i < FILE_MAX - (int(ref_path_in_len) - 1); i++) {
+ abs_path_out[i] = 'A';
+ }
+ abs_path_out[FILE_MAX - std::max((ref_path_in_len - 1), size_t(1))] = '\0';
+ PATH_REL(abs_path_in, ref_path_in, abs_path_out);
+}
-#endif
+#undef PATH_REL
+#undef ABS_PREFIX
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Tests for: #BLI_path_contains
+ * \{ */
-/* BLI_path_contains */
TEST(path_util, PathContains)
{
EXPECT_TRUE(BLI_path_contains("/some/path", "/some/path")) << "A path contains itself";
@@ -692,4 +952,6 @@ TEST(path_util, PathContains_Windows_case_insensitive)
EXPECT_TRUE(BLI_path_contains("C:\\some\\path", "c:\\SOME\\path\\inside"))
<< "On Windows path comparison should ignore case";
}
-#endif
+#endif /* WIN32 */
+
+/** \} */
diff --git a/source/blender/blenlib/tests/BLI_polyfill_2d_test.cc b/source/blender/blenlib/tests/BLI_polyfill_2d_test.cc
index db2fb1ba671..f3b66bedf88 100644
--- a/source/blender/blenlib/tests/BLI_polyfill_2d_test.cc
+++ b/source/blender/blenlib/tests/BLI_polyfill_2d_test.cc
@@ -29,20 +29,20 @@
static void polyfill_to_obj(const char *id,
const float poly[][2],
- const unsigned int poly_num,
- const unsigned int tris[][3],
- const unsigned int tris_num);
+ const uint poly_num,
+ const uint tris[][3],
+ const uint tris_num);
/* -------------------------------------------------------------------- */
/* test utility functions */
-#define TRI_ERROR_VALUE (unsigned int)-1
+#define TRI_ERROR_VALUE (uint) - 1
-static void test_valid_polyfill_prepare(unsigned int tris[][3], unsigned int tris_num)
+static void test_valid_polyfill_prepare(uint tris[][3], uint tris_num)
{
- unsigned int i;
+ uint i;
for (i = 0; i < tris_num; i++) {
- unsigned int j;
+ uint j;
for (j = 0; j < 3; j++) {
tris[i][j] = TRI_ERROR_VALUE;
}
@@ -57,14 +57,14 @@ static void test_valid_polyfill_prepare(unsigned int tris[][3], unsigned int tri
* - all verts used at least once.
*/
static void test_polyfill_simple(const float /*poly*/[][2],
- const unsigned int poly_num,
- const unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ const uint tris[][3],
+ const uint tris_num)
{
- unsigned int i;
+ uint i;
int *used_num = (int *)MEM_callocN(poly_num * sizeof(int), __func__);
for (i = 0; i < tris_num; i++) {
- unsigned int j;
+ uint j;
for (j = 0; j < 3; j++) {
EXPECT_NE(TRI_ERROR_VALUE, tris[i][j]);
used_num[tris[i][j]] += 1;
@@ -80,41 +80,41 @@ static void test_polyfill_simple(const float /*poly*/[][2],
}
static void test_polyfill_topology(const float /*poly*/[][2],
- const unsigned int poly_num,
- const unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ const uint tris[][3],
+ const uint tris_num)
{
EdgeHash *edgehash = BLI_edgehash_new(__func__);
EdgeHashIterator *ehi;
- unsigned int i;
+ uint i;
for (i = 0; i < tris_num; i++) {
- unsigned int j;
+ uint j;
for (j = 0; j < 3; j++) {
- const unsigned int v1 = tris[i][j];
- const unsigned int v2 = tris[i][(j + 1) % 3];
+ const uint v1 = tris[i][j];
+ const uint v2 = tris[i][(j + 1) % 3];
void **p = BLI_edgehash_lookup_p(edgehash, v1, v2);
if (p) {
- *p = (void *)((intptr_t)*p + (intptr_t)1);
+ *p = (void *)(intptr_t(*p) + intptr_t(1));
}
else {
- BLI_edgehash_insert(edgehash, v1, v2, (void *)(intptr_t)1);
+ BLI_edgehash_insert(edgehash, v1, v2, (void *)intptr_t(1));
}
}
}
EXPECT_EQ(BLI_edgehash_len(edgehash), poly_num + (poly_num - 3));
for (i = 0; i < poly_num; i++) {
- const unsigned int v1 = i;
- const unsigned int v2 = (i + 1) % poly_num;
+ const uint v1 = i;
+ const uint v2 = (i + 1) % poly_num;
void **p = BLI_edgehash_lookup_p(edgehash, v1, v2);
EXPECT_NE((void *)p, nullptr);
- EXPECT_EQ((intptr_t)*p, 1);
+ EXPECT_EQ(intptr_t(*p), 1);
}
for (ehi = BLI_edgehashIterator_new(edgehash), i = 0; BLI_edgehashIterator_isDone(ehi) == false;
BLI_edgehashIterator_step(ehi), i++) {
void **p = BLI_edgehashIterator_getValue_p(ehi);
- EXPECT_TRUE(ELEM((intptr_t)*p, 1, 2));
+ EXPECT_TRUE(ELEM(intptr_t(*p), 1, 2));
}
BLI_edgehashIterator_free(ehi);
@@ -125,12 +125,12 @@ static void test_polyfill_topology(const float /*poly*/[][2],
* Check all faces are flipped the same way
*/
static void test_polyfill_winding(const float poly[][2],
- const unsigned int /*poly_num*/,
- const unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint /*poly_num*/,
+ const uint tris[][3],
+ const uint tris_num)
{
- unsigned int i;
- unsigned int count[2] = {0, 0};
+ uint i;
+ uint count[2] = {0, 0};
for (i = 0; i < tris_num; i++) {
float winding_test = cross_tri_v2(poly[tris[i][0]], poly[tris[i][1]], poly[tris[i][2]]);
if (fabsf(winding_test) > FLT_EPSILON) {
@@ -144,11 +144,11 @@ static void test_polyfill_winding(const float poly[][2],
* Check the accumulated triangle area is close to the original area.
*/
static void test_polyfill_area(const float poly[][2],
- const unsigned int poly_num,
- const unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ const uint tris[][3],
+ const uint tris_num)
{
- unsigned int i;
+ uint i;
const float area_total = area_poly_v2(poly, poly_num);
float area_total_tris = 0.0f;
const float eps_abs = 0.00001f;
@@ -167,9 +167,9 @@ static void test_polyfill_area(const float poly[][2],
static void test_polyfill_template_check(const char *id,
bool is_degenerate,
const float poly[][2],
- const unsigned int poly_num,
- const unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ const uint tris[][3],
+ const uint tris_num)
{
test_polyfill_simple(poly, poly_num, tris, tris_num);
test_polyfill_topology(poly, poly_num, tris, tris_num);
@@ -184,9 +184,9 @@ static void test_polyfill_template_check(const char *id,
static void test_polyfill_template(const char *id,
bool is_degenerate,
const float poly[][2],
- const unsigned int poly_num,
- unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ uint tris[][3],
+ const uint tris_num)
{
test_valid_polyfill_prepare(tris, tris_num);
BLI_polyfill_calc(poly, poly_num, 0, tris);
@@ -213,9 +213,9 @@ static void test_polyfill_template(const char *id,
static void test_polyfill_template_flip_sign(const char *id,
bool is_degenerate,
const float poly[][2],
- const unsigned int poly_num,
- unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ uint tris[][3],
+ const uint tris_num)
{
float(*poly_copy)[2] = (float(*)[2])MEM_mallocN(sizeof(float[2]) * poly_num, id);
for (int flip_x = 0; flip_x < 2; flip_x++) {
@@ -236,19 +236,19 @@ static void test_polyfill_template_flip_sign(const char *id,
static void test_polyfill_template_main(const char *id,
bool is_degenerate,
const float poly[][2],
- const unsigned int poly_num,
- unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ uint tris[][3],
+ const uint tris_num)
{
/* overkill? - try at _every_ offset & reverse */
- unsigned int poly_reverse;
+ uint poly_reverse;
float(*poly_copy)[2] = (float(*)[2])MEM_mallocN(sizeof(float[2]) * poly_num, id);
float tmp[2];
memcpy(poly_copy, poly, sizeof(float[2]) * poly_num);
for (poly_reverse = 0; poly_reverse < 2; poly_reverse++) {
- unsigned int poly_cycle;
+ uint poly_cycle;
if (poly_reverse) {
BLI_array_reverse(poly_copy, poly_num);
@@ -271,9 +271,9 @@ static void test_polyfill_template_main(const char *id,
static void test_polyfill_template_main(const char *id,
bool is_degenerate,
const float poly[][2],
- const unsigned int poly_num,
- unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ uint tris[][3],
+ const uint tris_num)
{
test_polyfill_template_flip_sign(id, is_degenerate, poly, poly_num, tris, tris_num);
}
@@ -281,9 +281,9 @@ static void test_polyfill_template_main(const char *id,
#define TEST_POLYFILL_TEMPLATE_STATIC(poly, is_degenerate) \
{ \
- unsigned int tris[POLY_TRI_COUNT(ARRAY_SIZE(poly))][3]; \
- const unsigned int poly_num = ARRAY_SIZE(poly); \
- const unsigned int tris_num = ARRAY_SIZE(tris); \
+ uint tris[POLY_TRI_COUNT(ARRAY_SIZE(poly))][3]; \
+ const uint poly_num = ARRAY_SIZE(poly); \
+ const uint tris_num = ARRAY_SIZE(tris); \
const char *id = typeid(*this).name(); \
\
test_polyfill_template_main(id, is_degenerate, poly, poly_num, tris, tris_num); \
@@ -296,13 +296,13 @@ static void test_polyfill_template_main(const char *id,
#ifdef USE_OBJ_PREVIEW
static void polyfill_to_obj(const char *id,
const float poly[][2],
- const unsigned int poly_num,
- const unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ const uint tris[][3],
+ const uint tris_num)
{
char path[1024];
FILE *f;
- unsigned int i;
+ uint i;
BLI_snprintf(path, sizeof(path), "%s.obj", id);
@@ -324,9 +324,9 @@ static void polyfill_to_obj(const char *id,
#else
static void polyfill_to_obj(const char *id,
const float poly[][2],
- const unsigned int poly_num,
- const unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ const uint tris[][3],
+ const uint tris_num)
{
(void)id;
(void)poly, (void)poly_num;
diff --git a/source/blender/blenlib/tests/BLI_set_test.cc b/source/blender/blenlib/tests/BLI_set_test.cc
index 9dfa48b5822..79439eb9079 100644
--- a/source/blender/blenlib/tests/BLI_set_test.cc
+++ b/source/blender/blenlib/tests/BLI_set_test.cc
@@ -576,6 +576,19 @@ TEST(set, RemoveDuringIteration)
EXPECT_TRUE(set.contains(3));
}
+TEST(set, RemoveIf)
+{
+ Set<int64_t> set;
+ for (const int64_t i : IndexRange(100)) {
+ set.add(i * i);
+ }
+ set.remove_if([](const int64_t key) { return key > 100; });
+ EXPECT_EQ(set.size(), 11);
+ for (const int64_t i : IndexRange(100)) {
+ EXPECT_EQ(set.contains(i * i), i <= 10);
+ }
+}
+
/**
* Set this to 1 to activate the benchmark. It is disabled by default, because it prints a lot.
*/
diff --git a/source/blender/blenlib/tests/BLI_span_test.cc b/source/blender/blenlib/tests/BLI_span_test.cc
index 0bd34250deb..2dec84c4206 100644
--- a/source/blender/blenlib/tests/BLI_span_test.cc
+++ b/source/blender/blenlib/tests/BLI_span_test.cc
@@ -237,7 +237,7 @@ TEST(span, SizeInBytes)
{
std::array<int, 10> a{};
Span<int> a_span(a);
- EXPECT_EQ(a_span.size_in_bytes(), static_cast<int64_t>(sizeof(a)));
+ EXPECT_EQ(a_span.size_in_bytes(), int64_t(sizeof(a)));
EXPECT_EQ(a_span.size_in_bytes(), 40);
}
@@ -280,7 +280,7 @@ TEST(span, ContainsPtr)
EXPECT_TRUE(a_span.contains_ptr(&a[0] + 1));
EXPECT_TRUE(a_span.contains_ptr(&a[0] + 2));
EXPECT_FALSE(a_span.contains_ptr(&a[0] + 3));
- int *ptr_before = reinterpret_cast<int *>(reinterpret_cast<uintptr_t>(a.data()) - 1);
+ int *ptr_before = reinterpret_cast<int *>(uintptr_t(a.data()) - 1);
EXPECT_FALSE(a_span.contains_ptr(ptr_before));
EXPECT_FALSE(a_span.contains_ptr(&other));
}
diff --git a/source/blender/blenlib/tests/BLI_stack_cxx_test.cc b/source/blender/blenlib/tests/BLI_stack_cxx_test.cc
index 0707759666d..13d417d4374 100644
--- a/source/blender/blenlib/tests/BLI_stack_cxx_test.cc
+++ b/source/blender/blenlib/tests/BLI_stack_cxx_test.cc
@@ -118,19 +118,19 @@ TEST(stack, PushPopMany)
Stack<int> stack;
for (int i = 0; i < 1000; i++) {
stack.push(i);
- EXPECT_EQ(stack.size(), static_cast<unsigned int>(i + 1));
+ EXPECT_EQ(stack.size(), uint(i + 1));
}
for (int i = 999; i > 50; i--) {
EXPECT_EQ(stack.pop(), i);
- EXPECT_EQ(stack.size(), static_cast<unsigned int>(i));
+ EXPECT_EQ(stack.size(), uint(i));
}
for (int i = 51; i < 5000; i++) {
stack.push(i);
- EXPECT_EQ(stack.size(), static_cast<unsigned int>(i + 1));
+ EXPECT_EQ(stack.size(), uint(i + 1));
}
for (int i = 4999; i >= 0; i--) {
EXPECT_EQ(stack.pop(), i);
- EXPECT_EQ(stack.size(), static_cast<unsigned int>(i));
+ EXPECT_EQ(stack.size(), uint(i));
}
}
@@ -191,7 +191,7 @@ TEST(stack, OveralignedValues)
Stack<AlignedBuffer<1, 512>, 2> stack;
for (int i = 0; i < 100; i++) {
stack.push({});
- EXPECT_EQ((uintptr_t)&stack.peek() % 512, 0);
+ EXPECT_EQ(uintptr_t(&stack.peek()) % 512, 0);
}
}
diff --git a/source/blender/blenlib/tests/BLI_stack_test.cc b/source/blender/blenlib/tests/BLI_stack_test.cc
index 216c8bd6d55..5f361a78929 100644
--- a/source/blender/blenlib/tests/BLI_stack_test.cc
+++ b/source/blender/blenlib/tests/BLI_stack_test.cc
@@ -28,7 +28,7 @@ TEST(stack, Empty)
TEST(stack, One)
{
BLI_Stack *stack;
- unsigned int in = -1, out = 1;
+ uint in = -1, out = 1;
stack = BLI_stack_new(sizeof(in), __func__);
diff --git a/source/blender/blenlib/tests/BLI_string_ref_test.cc b/source/blender/blenlib/tests/BLI_string_ref_test.cc
index c3bb53f39d5..478b68a005e 100644
--- a/source/blender/blenlib/tests/BLI_string_ref_test.cc
+++ b/source/blender/blenlib/tests/BLI_string_ref_test.cc
@@ -357,7 +357,7 @@ TEST(string_ref, Constexpr)
constexpr StringRef sref("World");
BLI_STATIC_ASSERT(sref[2] == 'r', "");
BLI_STATIC_ASSERT(sref.size() == 5, "");
- std::array<int, static_cast<std::size_t>(sref.find_first_of('o'))> compiles = {1};
+ std::array<int, std::size_t(sref.find_first_of('o'))> compiles = {1};
EXPECT_EQ(compiles[0], 1);
}
} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_string_test.cc b/source/blender/blenlib/tests/BLI_string_test.cc
index eaaa65dd39f..d726fbccf20 100644
--- a/source/blender/blenlib/tests/BLI_string_test.cc
+++ b/source/blender/blenlib/tests/BLI_string_test.cc
@@ -174,7 +174,7 @@ TEST(string, StrPartitionEx)
/* BLI_str_partition_utf8 */
TEST(string, StrPartitionUtf8)
{
- const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
+ const uint delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
const char *sep, *suf;
size_t pre_len;
@@ -233,7 +233,7 @@ TEST(string, StrPartitionUtf8)
/* BLI_str_rpartition_utf8 */
TEST(string, StrRPartitionUtf8)
{
- const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
+ const uint delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
const char *sep, *suf;
size_t pre_len;
@@ -292,7 +292,7 @@ TEST(string, StrRPartitionUtf8)
/* BLI_str_partition_ex_utf8 */
TEST(string, StrPartitionExUtf8)
{
- const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
+ const uint delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
const char *sep, *suf;
size_t pre_len;
@@ -515,6 +515,103 @@ TEST(string, StrFormatDecimalUnits)
EXPECT_STREQ("-2.1B", size_str);
}
+/* BLI_str_format_integer_unit */
+TEST(string, StrFormatIntegerUnits)
+{
+ char size_str[7];
+ int size;
+
+ BLI_str_format_integer_unit(size_str, size = 0);
+ EXPECT_STREQ("0", size_str);
+ BLI_str_format_integer_unit(size_str, size = 1);
+ EXPECT_STREQ("1", size_str);
+ BLI_str_format_integer_unit(size_str, size = 10);
+ EXPECT_STREQ("10", size_str);
+ BLI_str_format_integer_unit(size_str, size = 15);
+ EXPECT_STREQ("15", size_str);
+ BLI_str_format_integer_unit(size_str, size = 100);
+ EXPECT_STREQ("100", size_str);
+ BLI_str_format_integer_unit(size_str, size = 155);
+ EXPECT_STREQ("155", size_str);
+ BLI_str_format_integer_unit(size_str, size = 1000);
+ EXPECT_STREQ("1K", size_str);
+ BLI_str_format_integer_unit(size_str, size = 1555);
+ EXPECT_STREQ("1K", size_str);
+ BLI_str_format_integer_unit(size_str, size = 10000);
+ EXPECT_STREQ("10K", size_str);
+ BLI_str_format_integer_unit(size_str, size = 15555);
+ EXPECT_STREQ("15K", size_str);
+ BLI_str_format_integer_unit(size_str, size = 100000);
+ EXPECT_STREQ(".1M", size_str);
+ BLI_str_format_integer_unit(size_str, size = 155555);
+ EXPECT_STREQ(".1M", size_str);
+ BLI_str_format_integer_unit(size_str, size = 1000000);
+ EXPECT_STREQ("1M", size_str);
+ BLI_str_format_integer_unit(size_str, size = 1555555);
+ EXPECT_STREQ("1M", size_str);
+ BLI_str_format_integer_unit(size_str, size = 2555555);
+ EXPECT_STREQ("2M", size_str);
+ BLI_str_format_integer_unit(size_str, size = 10000000);
+ EXPECT_STREQ("10M", size_str);
+ BLI_str_format_integer_unit(size_str, size = 15555555);
+ EXPECT_STREQ("15M", size_str);
+ BLI_str_format_integer_unit(size_str, size = 100000000);
+ EXPECT_STREQ(".1B", size_str);
+ BLI_str_format_integer_unit(size_str, size = 155555555);
+ EXPECT_STREQ(".1B", size_str);
+ BLI_str_format_integer_unit(size_str, size = 255555555);
+ EXPECT_STREQ(".2B", size_str);
+ BLI_str_format_integer_unit(size_str, size = 1000000000);
+ EXPECT_STREQ("1B", size_str);
+
+ /* Largest possible value. */
+ BLI_str_format_integer_unit(size_str, size = INT32_MAX);
+ EXPECT_STREQ("2B", size_str);
+
+ BLI_str_format_integer_unit(size_str, size = -0);
+ EXPECT_STREQ("0", size_str);
+ BLI_str_format_integer_unit(size_str, size = -1);
+ EXPECT_STREQ("-1", size_str);
+ BLI_str_format_integer_unit(size_str, size = -10);
+ EXPECT_STREQ("-10", size_str);
+ BLI_str_format_integer_unit(size_str, size = -15);
+ EXPECT_STREQ("-15", size_str);
+ BLI_str_format_integer_unit(size_str, size = -100);
+ EXPECT_STREQ("-100", size_str);
+ BLI_str_format_integer_unit(size_str, size = -155);
+ EXPECT_STREQ("-155", size_str);
+ BLI_str_format_integer_unit(size_str, size = -1000);
+ EXPECT_STREQ("-1K", size_str);
+ BLI_str_format_integer_unit(size_str, size = -1555);
+ EXPECT_STREQ("-1K", size_str);
+ BLI_str_format_integer_unit(size_str, size = -10000);
+ EXPECT_STREQ("-10K", size_str);
+ BLI_str_format_integer_unit(size_str, size = -15555);
+ EXPECT_STREQ("-15K", size_str);
+ BLI_str_format_integer_unit(size_str, size = -100000);
+ EXPECT_STREQ("-.1M", size_str);
+ BLI_str_format_integer_unit(size_str, size = -155555);
+ EXPECT_STREQ("-.1M", size_str);
+ BLI_str_format_integer_unit(size_str, size = -1000000);
+ EXPECT_STREQ("-1M", size_str);
+ BLI_str_format_integer_unit(size_str, size = -1555555);
+ EXPECT_STREQ("-1M", size_str);
+ BLI_str_format_integer_unit(size_str, size = -10000000);
+ EXPECT_STREQ("-10M", size_str);
+ BLI_str_format_integer_unit(size_str, size = -15555555);
+ EXPECT_STREQ("-15M", size_str);
+ BLI_str_format_integer_unit(size_str, size = -100000000);
+ EXPECT_STREQ("-.1B", size_str);
+ BLI_str_format_integer_unit(size_str, size = -155555555);
+ EXPECT_STREQ("-.1B", size_str);
+ BLI_str_format_integer_unit(size_str, size = -1000000000);
+ EXPECT_STREQ("-1B", size_str);
+
+ /* Smallest possible value. */
+ BLI_str_format_integer_unit(size_str, size = -INT32_MAX);
+ EXPECT_STREQ("-2B", size_str);
+}
+
struct WordInfo {
WordInfo() = default;
WordInfo(int start, int end) : start(start), end(end)
diff --git a/source/blender/blenlib/tests/BLI_string_utf8_test.cc b/source/blender/blenlib/tests/BLI_string_utf8_test.cc
index 2da439dad18..d66bade40ed 100644
--- a/source/blender/blenlib/tests/BLI_string_utf8_test.cc
+++ b/source/blender/blenlib/tests/BLI_string_utf8_test.cc
@@ -4,6 +4,7 @@
#include "BLI_rand.h"
#include "BLI_string.h"
+#include "BLI_string_cursor_utf8.h"
#include "BLI_string_utf8.h"
#include "BLI_utildefines.h"
@@ -274,7 +275,7 @@ TEST(string, Utf8InvalidBytes)
for (int i = 0; utf8_invalid_tests[i][0] != nullptr; i++) {
const char *tst = utf8_invalid_tests[i][0];
const char *tst_stripped = utf8_invalid_tests[i][1];
- const int errors_num = (int)utf8_invalid_tests[i][2][0];
+ const int errors_num = int(utf8_invalid_tests[i][2][0]);
char buff[80];
memcpy(buff, tst, sizeof(buff));
@@ -352,13 +353,13 @@ template<size_t Size> void utf8_as_char32_test_at_buffer_size()
/* Offset trailing bytes up and down in steps of 1, 2, 4 .. etc. */
if (Size > 1) {
for (int mul = 1; mul < 256; mul *= 2) {
- for (int ofs = 1; ofs < (int)Size; ofs++) {
- utf8_src[ofs] = (char)(i + (ofs * mul));
+ for (int ofs = 1; ofs < int(Size); ofs++) {
+ utf8_src[ofs] = char(i + (ofs * mul));
}
utf8_as_char32_test_compare<Size>(utf8_src);
- for (int ofs = 1; ofs < (int)Size; ofs++) {
- utf8_src[ofs] = (char)(i - (ofs * mul));
+ for (int ofs = 1; ofs < int(Size); ofs++) {
+ utf8_src[ofs] = char(i - (ofs * mul));
}
utf8_as_char32_test_compare<Size>(utf8_src);
}
@@ -393,3 +394,484 @@ TEST(string, Utf8AsUnicodeStep)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf32_empty
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf32Empty)
+{
+ const char32_t empty[] = U"";
+ const size_t len = 0;
+ int pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf32(empty, len, &pos));
+ pos = 1;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf32(empty, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf32_single
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf32Single)
+
+{
+ const char32_t single[] = U"0";
+ const size_t len = 1;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(single, len, &pos) && pos == 1);
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf32(single, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf32_simple
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf32Simple)
+{
+ const char32_t simple[] = U"012";
+ const size_t len = 3;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(simple, len, &pos) && pos == 1);
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(simple, len, &pos) && pos == 2);
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf32(simple, len - 1, &pos));
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(simple, len, &pos) && pos == 3);
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf32(simple, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf32_allcombining
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf32AllCombining)
+{
+ const char32_t allcombining[] = U"\u0300\u0300\u0300";
+ const size_t len = 3;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(allcombining, len, &pos) && pos == 3);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(allcombining, len, &pos) && pos == 3);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(allcombining, len, &pos) && pos == 3);
+ pos = 3;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf32(allcombining, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf32_complex
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf32Complex)
+{
+ /* Combining character, "A", two combining characters, "B".*/
+ const char32_t complex[] = U"\u0300\u0041\u0300\u0320\u0042";
+ const size_t len = 5;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(complex, len, &pos) && pos == 1);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(complex, len, &pos) && pos == 4);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(complex, len, &pos) && pos == 4);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(complex, len, &pos) && pos == 4);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(complex, len, &pos) && pos == 5);
+ pos = 5;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf32(complex, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf32_invalid
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf32Invalid)
+{
+ /* Latin1 "À", tab, carriage return, linefeed, separated by combining characters.*/
+ const char32_t invalid[] = U"\u00C0\u0300\u0009\u0300\u000D\u0300\u000A\u0300";
+ const size_t len = 8;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(invalid, len, &pos) && pos == 2);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(invalid, len, &pos) && pos == 2);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(invalid, len, &pos) && pos == 4);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(invalid, len, &pos) && pos == 4);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(invalid, len, &pos) && pos == 6);
+ pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(invalid, len, &pos) && pos == 6);
+ pos = 6;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(invalid, len, &pos) && pos == 8);
+ pos = 7;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(invalid, len, &pos) && pos == 8);
+ pos = 8;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf32(invalid, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf32_empty
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf32Empty)
+{
+ const char32_t emtpy[] = U"";
+ const size_t len = 0;
+ int pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf32(emtpy, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf32_single
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf32Single)
+{
+ const char32_t single[] = U"0";
+ const size_t len = 1;
+ int pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(single, len, &pos) && pos == 0);
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf32(single, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf32_simple
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf32Simple)
+{
+ const char32_t simple[] = U"012";
+ const size_t len = 3;
+ int pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(simple, len, &pos) && pos == 2);
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(simple, len, &pos) && pos == 1);
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(simple, len, &pos) && pos == 0);
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf32(simple, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf32_allcombining
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf32AllCombining)
+{
+ const char32_t allcombining[] = U"\u0300\u0300\u0300";
+ const size_t len = 3;
+ int pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(allcombining, len, &pos) && pos == 0);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(allcombining, len, &pos) && pos == 0);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(allcombining, len, &pos) && pos == 0);
+ pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf32(allcombining, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf32_complex
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf32Complex)
+{
+ /* Combining character, "A", two combining characters, "B".*/
+ const char32_t complex[] = U"\u0300\u0041\u0300\u0320\u0042";
+ const size_t len = 5;
+ int pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(complex, len, &pos) && pos == 4);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(complex, len, &pos) && pos == 1);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(complex, len, &pos) && pos == 1);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(complex, len, &pos) && pos == 1);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(complex, len, &pos) && pos == 0);
+ pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf32(complex, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf32_invalid
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf32Invalid)
+{
+ /* Latin1 "À", tab, carriage return, linefeed, separated by combining characters.*/
+ const char32_t invalid[] = U"\u00C0\u0300\u0009\u0300\u000D\u0300\u000A\u0300";
+ const size_t len = 8;
+ int pos = 8;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos) && pos == 6);
+ pos = 7;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos) && pos == 6);
+ pos = 6;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos) && pos == 4);
+ pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos) && pos == 4);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos) && pos == 2);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos) && pos == 2);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos) && pos == 0);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos) && pos == 0);
+ pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf8_empty
+ * \{ */
+TEST(string, StrCursorStepNextUtf8Empty)
+{
+ const char empty[] = "";
+ const size_t len = 0;
+ int pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf8(empty, len, &pos));
+ pos = 1;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf8(empty, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf8_single
+ * \{ */
+TEST(string, StrCursorStepNextUtf8Single)
+{
+ const char single[] = "0";
+ const size_t len = 1;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(single, len, &pos) && pos == 1);
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf8(single, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf8_simple
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf8Simple)
+{
+ const char simple[] = "012";
+ const size_t len = 3;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(simple, len, &pos) && pos == 1);
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(simple, len, &pos) && pos == 2);
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf8(simple, len - 1, &pos));
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(simple, len, &pos) && pos == 3);
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf8(simple, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf8_allcombining
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf8AllCombining)
+{
+ const char allcombining[] = "\xCC\x80\xCC\x80\xCC\x80";
+ const size_t len = 6;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(allcombining, len, &pos) && pos == 6);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(allcombining, len, &pos) && pos == 6);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(allcombining, len, &pos) && pos == 6);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(allcombining, len, &pos) && pos == 6);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(allcombining, len, &pos) && pos == 6);
+ pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(allcombining, len, &pos) && pos == 6);
+ pos = 6;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf8(allcombining, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf8_complex
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf8AllComplex)
+{
+ /* Combining character, "A", "©", two combining characters, "B".*/
+ const char complex[] = "\xCC\x80\x41\xC2\xA9\xCC\x80\xCC\xA0\x42";
+ const size_t len = 10;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 2);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 2);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 3);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 9);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 9);
+ pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 9);
+ pos = 6;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 9);
+ pos = 7;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 9);
+ pos = 8;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 9);
+ pos = 9;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 10);
+ pos = 10;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf8(complex, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf8_invalid
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf8Invalid)
+{
+ /* Latin1 "À", combining, tab, carriage return, linefeed, combining.*/
+ const char invalid[] = "\xC0\xCC\x80\x09\x0D\x0A\xCC\x80";
+ const size_t len = 8;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(invalid, len, &pos) && pos == 8);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(invalid, len, &pos) && pos == 8);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(invalid, len, &pos) && pos == 8);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(invalid, len, &pos) && pos == 8);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(invalid, len, &pos) && pos == 8);
+ pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(invalid, len, &pos) && pos == 8);
+ pos = 6;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(invalid, len, &pos) && pos == 8);
+ pos = 7;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(invalid, len, &pos) && pos == 8);
+ pos = 8;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf8(invalid, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf8_empty
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf8Empty)
+{
+ const char empty[] = "";
+ const size_t len = 0;
+ int pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf8(empty, len, &pos));
+ pos = 1;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf8(empty, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf8_single
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf8Single)
+{
+ const char single[] = "0";
+ const size_t len = 1;
+ int pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(single, len, &pos) && pos == 0);
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf8(single, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf8_single
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf8Simple)
+{
+ const char simple[] = "012";
+ const size_t len = 3;
+ int pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(simple, len, &pos) && pos == 2);
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(simple, len, &pos) && pos == 1);
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(simple, len, &pos) && pos == 0);
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf8(simple, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf8_allcombining
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf8AllCombining)
+{
+ const char allcombining[] = "\xCC\x80\xCC\x80\xCC\x80";
+ const size_t len = 6;
+ int pos = 6;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(allcombining, len, &pos) && pos == 0);
+ pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(allcombining, len, &pos) && pos == 0);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(allcombining, len, &pos) && pos == 0);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(allcombining, len, &pos) && pos == 0);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(allcombining, len, &pos) && pos == 0);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(allcombining, len, &pos) && pos == 0);
+ pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf8(allcombining, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf8_complex
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf8Complex)
+{
+ /* Combining character, "A", "©", two combining characters, "B".*/
+ const char complex[] = "\xCC\x80\x41\xC2\xA9\xCC\x80\xCC\xA0\x42";
+ const size_t len = 10;
+ int pos = 10;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 9);
+ pos = 9;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 3);
+ pos = 8;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 3);
+ pos = 7;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 3);
+ pos = 6;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 3);
+ pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 3);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 3);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 2);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 0);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 0);
+ pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf8(complex, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf8_invalid
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf8Invalid)
+{
+ /* Latin1 "À", combining, tab, carriage return, linefeed, combining.*/
+ const char invalid[] = "\xC0\xCC\x80\x09\x0D\x0A\xCC\x80";
+ const size_t len = 8;
+ int pos = 8;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos) && pos == 5);
+ pos = 7;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos) && pos == 5);
+ pos = 6;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos) && pos == 5);
+ pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos) && pos == 4);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos) && pos == 3);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos) && pos == 0);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos) && pos == 0);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos) && pos == 0);
+ pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos));
+}
+
+/** \} */
diff --git a/source/blender/blenlib/tests/BLI_task_test.cc b/source/blender/blenlib/tests/BLI_task_test.cc
index a933d45e7cd..63bb767466f 100644
--- a/source/blender/blenlib/tests/BLI_task_test.cc
+++ b/source/blender/blenlib/tests/BLI_task_test.cc
@@ -27,7 +27,7 @@ static void task_range_iter_func(void *userdata, int index, const TaskParallelTL
// printf("%d, %d, %d\n", index, data[index], *((int *)tls->userdata_chunk));
}
-static void task_range_iter_reduce_func(const void *__restrict UNUSED(userdata),
+static void task_range_iter_reduce_func(const void *__restrict /*userdata*/,
void *__restrict join_v,
void *__restrict userdata_chunk)
{
@@ -71,7 +71,7 @@ TEST(task, RangeIter)
static void task_mempool_iter_func(void *userdata,
MempoolIterData *item,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
int *data = (int *)item;
int *count = (int *)userdata;
@@ -147,7 +147,7 @@ using TaskMemPool_Chunk = struct TaskMemPool_Chunk {
ListBase *accumulate_items;
};
-static void task_mempool_iter_tls_func(void *UNUSED(userdata),
+static void task_mempool_iter_tls_func(void * /*userdata*/,
MempoolIterData *item,
const TaskParallelTLS *__restrict tls)
{
@@ -165,7 +165,7 @@ static void task_mempool_iter_tls_func(void *UNUSED(userdata),
BLI_addtail(task_data->accumulate_items, BLI_genericNodeN(data));
}
-static void task_mempool_iter_tls_reduce(const void *__restrict UNUSED(userdata),
+static void task_mempool_iter_tls_reduce(const void *__restrict /*userdata*/,
void *__restrict chunk_join,
void *__restrict chunk)
{
@@ -180,8 +180,7 @@ static void task_mempool_iter_tls_reduce(const void *__restrict UNUSED(userdata)
}
}
-static void task_mempool_iter_tls_free(const void *UNUSED(userdata),
- void *__restrict userdata_chunk)
+static void task_mempool_iter_tls_free(const void * /*userdata*/, void *__restrict userdata_chunk)
{
TaskMemPool_Chunk *task_data = (TaskMemPool_Chunk *)userdata_chunk;
MEM_freeN(task_data->accumulate_items);
@@ -240,7 +239,7 @@ TEST(task, MempoolIterTLS)
static void task_listbase_iter_func(void *userdata,
void *item,
int index,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
LinkData *data = (LinkData *)item;
int *count = (int *)userdata;
diff --git a/source/blender/blenlib/tests/BLI_vector_set_test.cc b/source/blender/blenlib/tests/BLI_vector_set_test.cc
index 34685c76e00..c3fbac1200a 100644
--- a/source/blender/blenlib/tests/BLI_vector_set_test.cc
+++ b/source/blender/blenlib/tests/BLI_vector_set_test.cc
@@ -128,6 +128,19 @@ TEST(vector_set, RemoveContained)
EXPECT_EQ(set.size(), 0);
}
+TEST(vector_set, RemoveIf)
+{
+ VectorSet<int64_t> set;
+ for (const int64_t i : IndexRange(100)) {
+ set.add(i * i);
+ }
+ set.remove_if([](const int64_t key) { return key % 2 == 0; });
+ EXPECT_EQ(set.size(), 50);
+ for (const int64_t i : IndexRange(100)) {
+ EXPECT_EQ(set.contains(i * i), i % 2 == 1);
+ }
+}
+
TEST(vector_set, AddMultipleTimes)
{
VectorSet<int> set;
diff --git a/source/blender/blenlib/tests/BLI_vector_test.cc b/source/blender/blenlib/tests/BLI_vector_test.cc
index 3a12fe14de3..29bf6c0cfb1 100644
--- a/source/blender/blenlib/tests/BLI_vector_test.cc
+++ b/source/blender/blenlib/tests/BLI_vector_test.cc
@@ -317,7 +317,7 @@ TEST(vector, BecomeLarge)
}
EXPECT_EQ(vec.size(), 100);
for (int i = 0; i < 100; i++) {
- EXPECT_EQ(vec[i], static_cast<int>(i * 5));
+ EXPECT_EQ(vec[i], int(i * 5));
}
}
@@ -416,7 +416,16 @@ TEST(vector, Remove)
vec.remove(1);
EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2}).begin()));
vec.remove(0);
- EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({}).begin()));
+ EXPECT_EQ(vec.begin(), vec.end());
+}
+
+TEST(vector, RemoveIf)
+{
+ Vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8};
+ vec.remove_if([](const int x) { return x % 2 == 0; });
+ const Vector<int> expected_vec = {1, 3, 5, 7};
+ EXPECT_EQ(vec.size(), expected_vec.size());
+ EXPECT_EQ_ARRAY(vec.data(), expected_vec.data(), size_t(vec.size()));
}
TEST(vector, ExtendSmallVector)
@@ -497,11 +506,11 @@ class TypeConstructMock {
{
}
- TypeConstructMock(const TypeConstructMock &UNUSED(other)) : copy_constructed(true)
+ TypeConstructMock(const TypeConstructMock & /*other*/) : copy_constructed(true)
{
}
- TypeConstructMock(TypeConstructMock &&UNUSED(other)) noexcept : move_constructed(true)
+ TypeConstructMock(TypeConstructMock && /*other*/) noexcept : move_constructed(true)
{
}
@@ -635,7 +644,7 @@ TEST(vector, OveralignedValues)
Vector<AlignedBuffer<1, 512>, 2> vec;
for (int i = 0; i < 100; i++) {
vec.append({});
- EXPECT_EQ((uintptr_t)&vec.last() % 512, 0);
+ EXPECT_EQ(uintptr_t(&vec.last()) % 512, 0);
}
}
diff --git a/source/blender/blenlib/tests/BLI_virtual_array_test.cc b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
index 14f5480f751..6d6580c52d4 100644
--- a/source/blender/blenlib/tests/BLI_virtual_array_test.cc
+++ b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
@@ -98,7 +98,7 @@ TEST(virtual_array, VectorSet)
TEST(virtual_array, Func)
{
- auto func = [](int64_t index) { return (int)(index * index); };
+ auto func = [](int64_t index) { return int(index * index); };
VArray<int> varray = VArray<int>::ForFunc(10, func);
EXPECT_EQ(varray.size(), 10);
EXPECT_EQ(varray[0], 0);
@@ -108,7 +108,7 @@ TEST(virtual_array, Func)
TEST(virtual_array, AsSpan)
{
- auto func = [](int64_t index) { return (int)(10 * index); };
+ auto func = [](int64_t index) { return int(10 * index); };
VArray<int> func_varray = VArray<int>::ForFunc(10, func);
VArraySpan span_varray{func_varray};
EXPECT_EQ(span_varray.size(), 10);
@@ -210,7 +210,7 @@ TEST(virtual_array, MaterializeCompressed)
EXPECT_EQ(compressed_array[2], 4);
}
{
- VArray<int> varray = VArray<int>::ForFunc(10, [](const int64_t i) { return (int)(i * i); });
+ VArray<int> varray = VArray<int>::ForFunc(10, [](const int64_t i) { return int(i * i); });
std::array<int, 3> compressed_array;
varray.materialize_compressed({5, 7, 8}, compressed_array);
EXPECT_EQ(compressed_array[0], 25);
diff --git a/source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc b/source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc
index 09bb1e7239f..efcf8dea922 100644
--- a/source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc
+++ b/source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc
@@ -177,12 +177,12 @@ TEST(ghash, TextMurmur2a)
/* Int: uniform 100M first integers. */
-static void int_ghash_tests(GHash *ghash, const char *id, const unsigned int count)
+static void int_ghash_tests(GHash *ghash, const char *id, const uint count)
{
printf("\n========== STARTING %s ==========\n", id);
{
- unsigned int i = count;
+ uint i = count;
TIMEIT_START(int_insert);
@@ -200,7 +200,7 @@ static void int_ghash_tests(GHash *ghash, const char *id, const unsigned int cou
PRINTF_GHASH_STATS(ghash);
{
- unsigned int i = count;
+ uint i = count;
TIMEIT_START(int_lookup);
@@ -266,13 +266,13 @@ TEST(ghash, IntMurmur2a100000000)
/* Int: random 50M integers. */
-static void randint_ghash_tests(GHash *ghash, const char *id, const unsigned int count)
+static void randint_ghash_tests(GHash *ghash, const char *id, const uint count)
{
printf("\n========== STARTING %s ==========\n", id);
- unsigned int *data = (unsigned int *)MEM_mallocN(sizeof(*data) * (size_t)count, __func__);
- unsigned int *dt;
- unsigned int i;
+ uint *data = (uint *)MEM_mallocN(sizeof(*data) * size_t(count), __func__);
+ uint *dt;
+ uint i;
{
RNG *rng = BLI_rng_new(1);
@@ -347,7 +347,7 @@ TEST(ghash, IntRandMurmur2a50000000)
}
#endif
-static unsigned int ghashutil_tests_nohash_p(const void *p)
+static uint ghashutil_tests_nohash_p(const void *p)
{
return POINTER_AS_UINT(p);
}
@@ -375,14 +375,14 @@ TEST(ghash, Int4NoHash50000000)
/* Int_v4: 20M of randomly-generated integer vectors. */
-static void int4_ghash_tests(GHash *ghash, const char *id, const unsigned int count)
+static void int4_ghash_tests(GHash *ghash, const char *id, const uint count)
{
printf("\n========== STARTING %s ==========\n", id);
- void *data_v = MEM_mallocN(sizeof(unsigned int[4]) * (size_t)count, __func__);
- unsigned int(*data)[4] = (unsigned int(*)[4])data_v;
- unsigned int(*dt)[4];
- unsigned int i, j;
+ void *data_v = MEM_mallocN(sizeof(uint[4]) * size_t(count), __func__);
+ uint(*data)[4] = (uint(*)[4])data_v;
+ uint(*dt)[4];
+ uint i, j;
{
RNG *rng = BLI_rng_new(1);
@@ -483,11 +483,11 @@ TEST(ghash, Int2NoHash50000000)
/* MultiSmall: create and manipulate a lot of very small ghash's
* (90% < 10 items, 9% < 100 items, 1% < 1000 items). */
-static void multi_small_ghash_tests_one(GHash *ghash, RNG *rng, const unsigned int count)
+static void multi_small_ghash_tests_one(GHash *ghash, RNG *rng, const uint count)
{
- unsigned int *data = (unsigned int *)MEM_mallocN(sizeof(*data) * (size_t)count, __func__);
- unsigned int *dt;
- unsigned int i;
+ uint *data = (uint *)MEM_mallocN(sizeof(*data) * size_t(count), __func__);
+ uint *dt;
+ uint i;
for (i = count, dt = data; i--; dt++) {
*dt = BLI_rng_get_uint(rng);
@@ -510,7 +510,7 @@ static void multi_small_ghash_tests_one(GHash *ghash, RNG *rng, const unsigned i
MEM_freeN(data);
}
-static void multi_small_ghash_tests(GHash *ghash, const char *id, const unsigned int count)
+static void multi_small_ghash_tests(GHash *ghash, const char *id, const uint count)
{
printf("\n========== STARTING %s ==========\n", id);
@@ -518,7 +518,7 @@ static void multi_small_ghash_tests(GHash *ghash, const char *id, const unsigned
TIMEIT_START(multi_small_ghash);
- unsigned int i = count;
+ uint i = count;
while (i--) {
const int count = 1 + (BLI_rng_get_int(rng) % TESTCASE_SIZE_SMALL) *
(!(i % 100) ? 100 : (!(i % 10) ? 10 : 1));
@@ -529,7 +529,7 @@ static void multi_small_ghash_tests(GHash *ghash, const char *id, const unsigned
TIMEIT_START(multi_small2_ghash);
- unsigned int i = count;
+ uint i = count;
while (i--) {
const int count = 1 + (BLI_rng_get_int(rng) % TESTCASE_SIZE_SMALL) / 2 *
(!(i % 100) ? 100 : (!(i % 10) ? 10 : 1));
diff --git a/source/blender/blenlib/tests/performance/BLI_task_performance_test.cc b/source/blender/blenlib/tests/performance/BLI_task_performance_test.cc
index a86e9b0b86d..68fdf4031ab 100644
--- a/source/blender/blenlib/tests/performance/BLI_task_performance_test.cc
+++ b/source/blender/blenlib/tests/performance/BLI_task_performance_test.cc
@@ -36,10 +36,10 @@ static uint gen_pseudo_random_number(uint num)
/* *** Parallel iterations over double-linked list items. *** */
-static void task_listbase_light_iter_func(void *UNUSED(userdata),
+static void task_listbase_light_iter_func(void * /*userdata*/,
void *item,
int index,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
LinkData *data = (LinkData *)item;
@@ -50,7 +50,7 @@ static void task_listbase_light_iter_func(void *UNUSED(userdata),
static void task_listbase_light_membarrier_iter_func(void *userdata,
void *item,
int index,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
LinkData *data = (LinkData *)item;
@@ -60,16 +60,16 @@ static void task_listbase_light_membarrier_iter_func(void *userdata,
atomic_sub_and_fetch_uint32((uint32_t *)count, 1);
}
-static void task_listbase_heavy_iter_func(void *UNUSED(userdata),
+static void task_listbase_heavy_iter_func(void * /*userdata*/,
void *item,
int index,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
LinkData *data = (LinkData *)item;
/* 'Random' number of iterations. */
- const uint num = gen_pseudo_random_number((uint)index);
+ const uint num = gen_pseudo_random_number(uint(index));
for (uint i = 0; i < num; i++) {
data->data = POINTER_FROM_INT(POINTER_AS_INT(data->data) + ((i % 2) ? -index : index));
@@ -79,14 +79,14 @@ static void task_listbase_heavy_iter_func(void *UNUSED(userdata),
static void task_listbase_heavy_membarrier_iter_func(void *userdata,
void *item,
int index,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
LinkData *data = (LinkData *)item;
int *count = (int *)userdata;
/* 'Random' number of iterations. */
- const uint num = gen_pseudo_random_number((uint)index);
+ const uint num = gen_pseudo_random_number(uint(index));
for (uint i = 0; i < num; i++) {
data->data = POINTER_FROM_INT(POINTER_AS_INT(data->data) + ((i % 2) ? -index : index));
diff --git a/source/blender/blenlib/tests/performance/CMakeLists.txt b/source/blender/blenlib/tests/performance/CMakeLists.txt
index c4f03255a11..aa26f796e0d 100644
--- a/source/blender/blenlib/tests/performance/CMakeLists.txt
+++ b/source/blender/blenlib/tests/performance/CMakeLists.txt
@@ -4,9 +4,13 @@
set(INC
.
..
+ ../..
+ ../../../makesdna
+ ../../../../../intern/atomic
+ ../../../../../intern/guardedalloc
)
include_directories(${INC})
-BLENDER_TEST_PERFORMANCE(BLI_ghash_performance "bf_blenlib")
-BLENDER_TEST_PERFORMANCE(BLI_task_performance "bf_blenlib")
+blender_test_performance(BLI_ghash_performance "bf_blenlib")
+blender_test_performance(BLI_task_performance "bf_blenlib")
diff --git a/source/blender/blenloader/BLO_blend_validate.h b/source/blender/blenloader/BLO_blend_validate.h
index 0ce40987adc..4594f730758 100644
--- a/source/blender/blenloader/BLO_blend_validate.h
+++ b/source/blender/blenloader/BLO_blend_validate.h
@@ -12,6 +12,10 @@
struct Main;
struct ReportList;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
* Check (but do *not* fix) that all linked data-blocks are still valid
* (i.e. pointing to the right library).
@@ -21,3 +25,7 @@ bool BLO_main_validate_libraries(struct Main *bmain, struct ReportList *reports)
* * Check (and fix if needed) that shape key's 'from' pointer is valid.
*/
bool BLO_main_validate_shapekeys(struct Main *bmain, struct ReportList *reports);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/blenloader/BLO_read_write.h b/source/blender/blenloader/BLO_read_write.h
index 7e2f5e4b0ae..6f39670a226 100644
--- a/source/blender/blenloader/BLO_read_write.h
+++ b/source/blender/blenloader/BLO_read_write.h
@@ -219,8 +219,8 @@ void *BLO_read_get_new_packed_address(BlendDataReader *reader, const void *old_a
typedef void (*BlendReadListFn)(BlendDataReader *reader, void *data);
/**
- * Updates all ->prev and ->next pointers of the list elements.
- * Updates the list->first and list->last pointers.
+ * Updates all `->prev` and `->next` pointers of the list elements.
+ * Updates the `list->first` and `list->last` pointers.
* When not NULL, calls the callback on every element.
*/
void BLO_read_list_cb(BlendDataReader *reader, struct ListBase *list, BlendReadListFn callback);
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 93040fa01ee..75a1956ce12 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -182,6 +182,11 @@ void BLO_blendfiledata_free(BlendFileData *bfd);
typedef struct BLODataBlockInfo {
char name[64]; /* MAX_NAME */
struct AssetMetaData *asset_data;
+ /* Optimization: Tag data-blocks for which we know there is no preview.
+ * Knowing this can be used to skip the (potentially expensive) preview loading process. If this
+ * is set to true it means we looked for a preview and couldn't find one. False may mean that
+ * either no preview was found, or that it wasn't looked for in the first place. */
+ bool no_preview_found;
} BLODataBlockInfo;
/**
diff --git a/source/blender/blenloader/BLO_undofile.h b/source/blender/blenloader/BLO_undofile.h
index 0584f95d85f..0dee167db53 100644
--- a/source/blender/blenloader/BLO_undofile.h
+++ b/source/blender/blenloader/BLO_undofile.h
@@ -61,6 +61,10 @@ typedef struct {
bool memchunk_identical;
} UndoReader;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Actually only used `writefile.c`. */
void BLO_memfile_write_init(MemFileWriteData *mem_data,
@@ -101,3 +105,7 @@ extern struct Main *BLO_memfile_main_get(struct MemFile *memfile,
extern bool BLO_memfile_write_file(struct MemFile *memfile, const char *filepath);
FileReader *BLO_memfile_new_filereader(MemFile *memfile, int undo_direction);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt
index f8bf97b17e9..86793d38b0b 100644
--- a/source/blender/blenloader/CMakeLists.txt
+++ b/source/blender/blenloader/CMakeLists.txt
@@ -33,24 +33,25 @@ set(INC_SYS
set(SRC
${CMAKE_SOURCE_DIR}/release/datafiles/userdef/userdef_default_theme.c
- intern/blend_validate.c
- intern/readblenentry.c
- intern/readfile.c
- intern/readfile_tempload.c
- intern/undofile.c
+ intern/blend_validate.cc
+ intern/readblenentry.cc
+ intern/readfile.cc
+ intern/readfile_tempload.cc
+ intern/undofile.cc
intern/versioning_250.c
intern/versioning_260.c
intern/versioning_270.c
intern/versioning_280.c
intern/versioning_290.c
- intern/versioning_300.c
+ intern/versioning_300.cc
+ intern/versioning_400.cc
intern/versioning_common.cc
intern/versioning_cycles.c
- intern/versioning_defaults.c
+ intern/versioning_defaults.cc
intern/versioning_dna.c
intern/versioning_legacy.c
intern/versioning_userdef.c
- intern/writefile.c
+ intern/writefile.cc
BLO_blend_defs.h
BLO_blend_validate.h
@@ -82,6 +83,17 @@ if(WITH_ALEMBIC)
add_definitions(-DWITH_ALEMBIC)
endif()
+if(WITH_TBB)
+ list(APPEND INC_SYS
+ ${TBB_INCLUDE_DIRS}
+ )
+ add_definitions(-DWITH_TBB)
+endif()
+
+if(WIN32)
+ add_definitions(-DNOMINMAX)
+endif()
+
blender_add_lib(bf_blenloader "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
# needed so writefile.c can use dna_type_offsets.h
diff --git a/source/blender/blenloader/intern/blend_validate.c b/source/blender/blenloader/intern/blend_validate.cc
index e1527201e22..7ac0a4fe1af 100644
--- a/source/blender/blenloader/intern/blend_validate.c
+++ b/source/blender/blenloader/intern/blend_validate.cc
@@ -9,7 +9,7 @@
* \note Does not *fix* anything, only reports found errors.
*/
-#include <string.h> /* for #strrchr #strncmp #strstr */
+#include <cstring> /* for #strrchr #strncmp #strstr */
#include "BLI_utildefines.h"
@@ -45,7 +45,8 @@ bool BLO_main_validate_libraries(Main *bmain, ReportList *reports)
ListBase *lbarray[INDEX_ID_MAX];
int i = set_listbasepointers(bmain, lbarray);
while (i--) {
- for (ID *id = lbarray[i]->first; id != NULL; id = id->next) {
+ for (ID *id = static_cast<ID *>(lbarray[i]->first); id != nullptr;
+ id = static_cast<ID *>(id->next)) {
if (ID_IS_LINKED(id)) {
is_valid = false;
BKE_reportf(reports,
@@ -57,18 +58,19 @@ bool BLO_main_validate_libraries(Main *bmain, ReportList *reports)
}
}
- for (Main *curmain = bmain->next; curmain != NULL; curmain = curmain->next) {
+ for (Main *curmain = bmain->next; curmain != nullptr; curmain = curmain->next) {
Library *curlib = curmain->curlib;
- if (curlib == NULL) {
- BKE_report(reports, RPT_ERROR, "Library database with NULL library data-block!");
+ if (curlib == nullptr) {
+ BKE_report(reports, RPT_ERROR, "Library database with null library data-block pointer!");
continue;
}
BKE_library_filepath_set(bmain, curlib, curlib->filepath);
- BlendFileReadReport bf_reports = {.reports = reports};
+ BlendFileReadReport bf_reports{};
+ bf_reports.reports = reports;
BlendHandle *bh = BLO_blendhandle_from_file(curlib->filepath_abs, &bf_reports);
- if (bh == NULL) {
+ if (bh == nullptr) {
BKE_reportf(reports,
RPT_ERROR,
"Library ID %s not found at expected path %s!",
@@ -79,8 +81,8 @@ bool BLO_main_validate_libraries(Main *bmain, ReportList *reports)
i = set_listbasepointers(curmain, lbarray);
while (i--) {
- ID *id = lbarray[i]->first;
- if (id == NULL) {
+ ID *id = static_cast<ID *>(lbarray[i]->first);
+ if (id == nullptr) {
continue;
}
@@ -96,12 +98,12 @@ bool BLO_main_validate_libraries(Main *bmain, ReportList *reports)
int totnames = 0;
LinkNode *names = BLO_blendhandle_get_datablock_names(bh, GS(id->name), false, &totnames);
- for (; id != NULL; id = id->next) {
+ for (; id != nullptr; id = static_cast<ID *>(id->next)) {
if (!ID_IS_LINKED(id)) {
is_valid = false;
BKE_reportf(reports,
RPT_ERROR,
- "ID %s has NULL lib pointer while being in library %s!",
+ "ID %s has null lib pointer while being in library %s!",
id->name,
curlib->filepath);
continue;
@@ -120,7 +122,7 @@ bool BLO_main_validate_libraries(Main *bmain, ReportList *reports)
}
}
- if (name == NULL) {
+ if (name == nullptr) {
is_valid = false;
BKE_reportf(reports,
RPT_ERROR,
@@ -163,7 +165,7 @@ bool BLO_main_validate_shapekeys(Main *bmain, ReportList *reports)
if (!ID_IS_LINKED(id)) {
/* We assume lib data is valid... */
Key *shapekey = BKE_key_from_id(id);
- if (shapekey != NULL && shapekey->from != id) {
+ if (shapekey != nullptr && shapekey->from != id) {
is_valid = false;
BKE_reportf(reports,
RPT_ERROR,
@@ -184,7 +186,7 @@ bool BLO_main_validate_shapekeys(Main *bmain, ReportList *reports)
/* NOTE: #BKE_id_delete also locks `bmain`, so we need to do this loop outside of the lock here.
*/
LISTBASE_FOREACH_MUTABLE (Key *, shapekey, &bmain->shapekeys) {
- if (shapekey->from != NULL) {
+ if (shapekey->from != nullptr) {
continue;
}
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.cc
index 1bfa3b0e2bb..ead796c0e28 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.cc
@@ -6,12 +6,11 @@
* `.blend` file reading entry point.
*/
-#include <stddef.h>
-
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cmath>
+#include <cstddef>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -70,7 +69,7 @@ void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp)
FileData *fd = (FileData *)bh;
BHead *bhead;
- fprintf(fp, "[\n");
+ fprintf(static_cast<FILE *>(fp), "[\n");
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
if (bhead->code == ENDB) {
break;
@@ -90,14 +89,14 @@ void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp)
buf[2] = buf[2] ? buf[2] : ' ';
buf[3] = buf[3] ? buf[3] : ' ';
- fprintf(fp,
+ fprintf(static_cast<FILE *>(fp),
"['%.4s', '%s', %d, %ld ],\n",
buf,
name,
bhead->nr,
(long int)(bhead->len + sizeof(BHead)));
}
- fprintf(fp, "]\n");
+ fprintf(static_cast<FILE *>(fp), "]\n");
}
LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh,
@@ -106,14 +105,14 @@ LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh,
int *r_tot_names)
{
FileData *fd = (FileData *)bh;
- LinkNode *names = NULL;
+ LinkNode *names = nullptr;
BHead *bhead;
int tot = 0;
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
if (bhead->code == ofblocktype) {
const char *idname = blo_bhead_id_name(fd, bhead);
- if (use_assets_only && blo_bhead_id_asset_data_address(fd, bhead) == NULL) {
+ if (use_assets_only && blo_bhead_id_asset_data_address(fd, bhead) == nullptr) {
continue;
}
@@ -135,24 +134,29 @@ LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh,
int *r_tot_info_items)
{
FileData *fd = (FileData *)bh;
- LinkNode *infos = NULL;
+ LinkNode *infos = nullptr;
BHead *bhead;
int tot = 0;
+ const int sdna_nr_preview_image = DNA_struct_find_nr(fd->filesdna, "PreviewImage");
+
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
if (bhead->code == ENDB) {
break;
}
if (bhead->code == ofblocktype) {
+ BHead *id_bhead = bhead;
+
const char *name = blo_bhead_id_name(fd, bhead) + 2;
AssetMetaData *asset_meta_data = blo_bhead_id_asset_data_address(fd, bhead);
- const bool is_asset = asset_meta_data != NULL;
+ const bool is_asset = asset_meta_data != nullptr;
const bool skip_datablock = use_assets_only && !is_asset;
if (skip_datablock) {
continue;
}
- struct BLODataBlockInfo *info = MEM_mallocN(sizeof(*info), __func__);
+ struct BLODataBlockInfo *info = static_cast<BLODataBlockInfo *>(
+ MEM_mallocN(sizeof(*info), __func__));
/* Lastly, read asset data from the following blocks. */
if (asset_meta_data) {
@@ -165,6 +169,17 @@ LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh,
STRNCPY(info->name, name);
info->asset_data = asset_meta_data;
+ bool has_preview = false;
+ /* See if we can find a preview in the data of this ID. */
+ for (BHead *data_bhead = blo_bhead_next(fd, id_bhead); data_bhead->code == DATA;
+ data_bhead = blo_bhead_next(fd, data_bhead)) {
+ if (data_bhead->SDNAnr == sdna_nr_preview_image) {
+ has_preview = true;
+ break;
+ }
+ }
+ info->no_preview_found = !has_preview;
+
BLI_linklist_prepend(&infos, info);
tot++;
}
@@ -186,7 +201,7 @@ LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh,
* bhead is consumed. the new bhead is returned by this function.
* \param result: the Preview Image where the preview rect will be stored.
* \param preview_from_file: The read PreviewImage where the bhead points to. The rects of this
- * \return PreviewImage or NULL when no preview Images have been found. Caller owns the returned
+ * \return PreviewImage or nullptr when no preview Images have been found. Caller owns the returned
*/
static BHead *blo_blendhandle_read_preview_rects(FileData *fd,
BHead *bhead,
@@ -199,15 +214,16 @@ static BHead *blo_blendhandle_read_preview_rects(FileData *fd,
bhead = blo_bhead_next(fd, bhead);
BLI_assert((preview_from_file->w[preview_index] * preview_from_file->h[preview_index] *
sizeof(uint)) == bhead->len);
- result->rect[preview_index] = BLO_library_read_struct(fd, bhead, "PreviewImage Icon Rect");
+ result->rect[preview_index] = static_cast<uint *>(
+ BLO_library_read_struct(fd, bhead, "PreviewImage Icon Rect"));
}
else {
/* This should not be needed, but can happen in 'broken' .blend files,
* better handle this gracefully than crashing. */
- BLI_assert(preview_from_file->rect[preview_index] == NULL &&
+ BLI_assert(preview_from_file->rect[preview_index] == nullptr &&
preview_from_file->w[preview_index] == 0 &&
preview_from_file->h[preview_index] == 0);
- result->rect[preview_index] = NULL;
+ result->rect[preview_index] = nullptr;
result->w[preview_index] = result->h[preview_index] = 0;
}
BKE_previewimg_finish(result, preview_index);
@@ -227,13 +243,14 @@ PreviewImage *BLO_blendhandle_get_preview_for_id(BlendHandle *bh,
for (BHead *bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
if (bhead->code == DATA) {
if (looking && bhead->SDNAnr == sdna_preview_image) {
- PreviewImage *preview_from_file = BLO_library_read_struct(fd, bhead, "PreviewImage");
+ PreviewImage *preview_from_file = static_cast<PreviewImage *>(
+ BLO_library_read_struct(fd, bhead, "PreviewImage"));
- if (preview_from_file == NULL) {
+ if (preview_from_file == nullptr) {
break;
}
- PreviewImage *result = MEM_dupallocN(preview_from_file);
+ PreviewImage *result = static_cast<PreviewImage *>(MEM_dupallocN(preview_from_file));
bhead = blo_blendhandle_read_preview_rects(fd, bhead, result, preview_from_file);
MEM_freeN(preview_from_file);
return result;
@@ -252,17 +269,17 @@ PreviewImage *BLO_blendhandle_get_preview_for_id(BlendHandle *bh,
}
}
- return NULL;
+ return nullptr;
}
LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *r_tot_prev)
{
FileData *fd = (FileData *)bh;
- LinkNode *previews = NULL;
+ LinkNode *previews = nullptr;
BHead *bhead;
int looking = 0;
- PreviewImage *prv = NULL;
- PreviewImage *new_prv = NULL;
+ PreviewImage *prv = nullptr;
+ PreviewImage *new_prv = nullptr;
int tot = 0;
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
@@ -279,7 +296,7 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *r_
case ID_SCE: /* fall through */
case ID_AC: /* fall through */
case ID_NT: /* fall through */
- new_prv = MEM_callocN(sizeof(PreviewImage), "newpreview");
+ new_prv = static_cast<PreviewImage *>(MEM_callocN(sizeof(PreviewImage), "newpreview"));
BLI_linklist_prepend(&previews, new_prv);
tot++;
looking = 1;
@@ -291,7 +308,7 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *r_
else if (bhead->code == DATA) {
if (looking) {
if (bhead->SDNAnr == DNA_struct_find_nr(fd->filesdna, "PreviewImage")) {
- prv = BLO_library_read_struct(fd, bhead, "PreviewImage");
+ prv = static_cast<PreviewImage *>(BLO_library_read_struct(fd, bhead, "PreviewImage"));
if (prv) {
memcpy(new_prv, prv, sizeof(PreviewImage));
@@ -306,8 +323,8 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *r_
}
else {
looking = 0;
- new_prv = NULL;
- prv = NULL;
+ new_prv = nullptr;
+ prv = nullptr;
}
}
@@ -319,7 +336,7 @@ LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh)
{
FileData *fd = (FileData *)bh;
GSet *gathered = BLI_gset_ptr_new("linkable_groups gh");
- LinkNode *names = NULL;
+ LinkNode *names = nullptr;
BHead *bhead;
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
@@ -337,7 +354,7 @@ LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh)
}
}
- BLI_gset_free(gathered, NULL);
+ BLI_gset_free(gathered, nullptr);
return names;
}
@@ -355,7 +372,7 @@ BlendFileData *BLO_read_from_file(const char *filepath,
eBLOReadSkip skip_flags,
BlendFileReadReport *reports)
{
- BlendFileData *bfd = NULL;
+ BlendFileData *bfd = nullptr;
FileData *fd;
fd = blo_filedata_from_file(filepath, reports);
@@ -373,9 +390,10 @@ BlendFileData *BLO_read_from_memory(const void *mem,
eBLOReadSkip skip_flags,
ReportList *reports)
{
- BlendFileData *bfd = NULL;
+ BlendFileData *bfd = nullptr;
FileData *fd;
- BlendFileReadReport bf_reports = {.reports = reports};
+ BlendFileReadReport bf_reports{};
+ bf_reports.reports = reports;
fd = blo_filedata_from_memory(mem, memsize, &bf_reports);
if (fd) {
@@ -393,14 +411,15 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain,
const struct BlendFileReadParams *params,
ReportList *reports)
{
- BlendFileData *bfd = NULL;
+ BlendFileData *bfd = nullptr;
FileData *fd;
ListBase old_mainlist;
- BlendFileReadReport bf_reports = {.reports = reports};
+ BlendFileReadReport bf_reports{};
+ bf_reports.reports = reports;
fd = blo_filedata_from_memfile(memfile, params, &bf_reports);
if (fd) {
- fd->skip_flags = params->skip_flags;
+ fd->skip_flags = eBLOReadSkip(params->skip_flags);
BLI_strncpy(fd->relabase, filepath, sizeof(fd->relabase));
/* separate libraries from old main */
@@ -411,7 +430,7 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain,
if ((params->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0) {
/* Build idmap of old main (we only care about local data here, so we can do that after
* split_main() call. */
- blo_make_old_idmap_from_main(fd, old_mainlist.first);
+ blo_make_old_idmap_from_main(fd, static_cast<Main *>(old_mainlist.first));
}
/* removed packed data from this trick - it's internal data that needs saves */
@@ -429,8 +448,8 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain,
* but oldmain itself shall *never* be 'transferred' to new mainlist! */
BLI_assert(old_mainlist.first == oldmain);
- /* That way, libs (aka mains) we did not reuse in new undone/redone state
- * will be cleared together with oldmain... */
+ /* That way, libraries (aka mains) we did not reuse in new undone/redone state
+ * will be cleared together with `oldmain`. */
blo_join_main(&old_mainlist);
blo_filedata_free(fd);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.cc
index bf2017b80f4..569798048f6 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.cc
@@ -5,13 +5,14 @@
* \ingroup blenloader
*/
-#include <ctype.h> /* for isdigit. */
+#include <cctype> /* for isdigit. */
+#include <cerrno>
+#include <climits>
+#include <cstdarg> /* for va_start/end. */
+#include <cstddef> /* for offsetof. */
+#include <cstdlib> /* for atoi. */
+#include <ctime> /* for gmtime. */
#include <fcntl.h> /* for open flags (O_BINARY, O_RDONLY). */
-#include <limits.h>
-#include <stdarg.h> /* for va_start/end. */
-#include <stddef.h> /* for offsetof. */
-#include <stdlib.h> /* for atoi. */
-#include <time.h> /* for gmtime. */
#include "BLI_utildefines.h"
#ifndef WIN32
@@ -73,6 +74,7 @@
#include "BKE_main.h" /* for Main */
#include "BKE_main_idmap.h"
#include "BKE_material.h"
+#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_node.h" /* for tree type defines */
#include "BKE_object.h"
@@ -101,8 +103,6 @@
#include "readfile.h"
-#include <errno.h>
-
/* Make preferences read-only. */
#define U (*((const UserDef *)&U))
@@ -180,7 +180,7 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname);
static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name);
static BHead *find_bhead_from_idname(FileData *fd, const char *idname);
-typedef struct BHeadN {
+struct BHeadN {
struct BHeadN *next, *prev;
#ifdef USE_BHEAD_READ_ON_DEMAND
/** Use to read the data from the file directly into memory as needed. */
@@ -190,9 +190,9 @@ typedef struct BHeadN {
#endif
bool is_memchunk_identical;
struct BHead bhead;
-} BHeadN;
+};
-#define BHEADN_FROM_BHEAD(bh) ((BHeadN *)POINTER_OFFSET(bh, -(int)offsetof(BHeadN, bhead)))
+#define BHEADN_FROM_BHEAD(bh) ((BHeadN *)POINTER_OFFSET(bh, -int(offsetof(BHeadN, bhead))))
/**
* We could change this in the future, for now it's simplest if only data is delayed
@@ -229,14 +229,14 @@ static const char *library_parent_filepath(Library *lib)
/** \name OldNewMap API
* \{ */
-typedef struct OldNew {
+struct OldNew {
const void *oldp;
void *newp;
/* `nr` is "user count" for data, and ID code for libdata. */
int nr;
-} OldNew;
+};
-typedef struct OldNewMap {
+struct OldNewMap {
/* Array that stores the actual entries. */
OldNew *entries;
int nentries;
@@ -244,7 +244,7 @@ typedef struct OldNewMap {
int32_t *map;
int capacity_exp;
-} OldNewMap;
+};
#define ENTRIES_CAPACITY(onm) (1ll << (onm)->capacity_exp)
#define MAP_CAPACITY(onm) (1ll << ((onm)->capacity_exp + 1))
@@ -299,7 +299,7 @@ static OldNew *oldnewmap_lookup_entry(const OldNewMap *onm, const void *addr)
}
}
else {
- return NULL;
+ return nullptr;
}
}
}
@@ -312,8 +312,9 @@ static void oldnewmap_clear_map(OldNewMap *onm)
static void oldnewmap_increase_size(OldNewMap *onm)
{
onm->capacity_exp++;
- onm->entries = MEM_reallocN(onm->entries, sizeof(*onm->entries) * ENTRIES_CAPACITY(onm));
- onm->map = MEM_reallocN(onm->map, sizeof(*onm->map) * MAP_CAPACITY(onm));
+ onm->entries = static_cast<OldNew *>(
+ MEM_reallocN(onm->entries, sizeof(*onm->entries) * ENTRIES_CAPACITY(onm)));
+ onm->map = static_cast<int32_t *>(MEM_reallocN(onm->map, sizeof(*onm->map) * MAP_CAPACITY(onm)));
oldnewmap_clear_map(onm);
for (int i = 0; i < onm->nentries; i++) {
oldnewmap_insert_index_in_map(onm, onm->entries[i].oldp, i);
@@ -327,15 +328,16 @@ static void oldnewmap_init_data(OldNewMap *onm, const int capacity_exp)
memset(onm, 0x0, sizeof(*onm));
onm->capacity_exp = capacity_exp;
- onm->entries = MEM_malloc_arrayN(
- ENTRIES_CAPACITY(onm), sizeof(*onm->entries), "OldNewMap.entries");
- onm->map = MEM_malloc_arrayN(MAP_CAPACITY(onm), sizeof(*onm->map), "OldNewMap.map");
+ onm->entries = static_cast<OldNew *>(
+ MEM_malloc_arrayN(ENTRIES_CAPACITY(onm), sizeof(*onm->entries), "OldNewMap.entries"));
+ onm->map = static_cast<int32_t *>(
+ MEM_malloc_arrayN(MAP_CAPACITY(onm), sizeof(*onm->map), "OldNewMap.map"));
oldnewmap_clear_map(onm);
}
-static OldNewMap *oldnewmap_new(void)
+static OldNewMap *oldnewmap_new()
{
- OldNewMap *onm = MEM_mallocN(sizeof(*onm), "OldNewMap");
+ OldNewMap *onm = static_cast<OldNewMap *>(MEM_mallocN(sizeof(*onm), "OldNewMap"));
oldnewmap_init_data(onm, DEFAULT_SIZE_EXP);
@@ -344,7 +346,7 @@ static OldNewMap *oldnewmap_new(void)
static void oldnewmap_insert(OldNewMap *onm, const void *oldaddr, void *newaddr, int nr)
{
- if (oldaddr == NULL || newaddr == NULL) {
+ if (oldaddr == nullptr || newaddr == nullptr) {
return;
}
@@ -372,8 +374,8 @@ void blo_do_versions_oldnewmap_insert(OldNewMap *onm, const void *oldaddr, void
static void *oldnewmap_lookup_and_inc(OldNewMap *onm, const void *addr, bool increase_users)
{
OldNew *entry = oldnewmap_lookup_entry(onm, addr);
- if (entry == NULL) {
- return NULL;
+ if (entry == nullptr) {
+ return nullptr;
}
if (increase_users) {
entry->nr++;
@@ -384,18 +386,18 @@ static void *oldnewmap_lookup_and_inc(OldNewMap *onm, const void *addr, bool inc
/* for libdata, OldNew.nr has ID code, no increment */
static void *oldnewmap_liblookup(OldNewMap *onm, const void *addr, const void *lib)
{
- if (addr == NULL) {
- return NULL;
+ if (addr == nullptr) {
+ return nullptr;
}
- ID *id = oldnewmap_lookup_and_inc(onm, addr, false);
- if (id == NULL) {
- return NULL;
+ ID *id = static_cast<ID *>(oldnewmap_lookup_and_inc(onm, addr, false));
+ if (id == nullptr) {
+ return nullptr;
}
if (!lib || id->lib) {
return id;
}
- return NULL;
+ return nullptr;
}
static void oldnewmap_clear(OldNewMap *onm)
@@ -405,7 +407,7 @@ static void oldnewmap_clear(OldNewMap *onm)
OldNew *entry = &onm->entries[i];
if (entry->nr == 0) {
MEM_freeN(entry->newp);
- entry->newp = NULL;
+ entry->newp = nullptr;
}
}
@@ -451,12 +453,12 @@ void blo_join_main(ListBase *mainlist)
{
Main *tojoin, *mainl;
- mainl = mainlist->first;
+ mainl = static_cast<Main *>(mainlist->first);
- if (mainl->id_map != NULL) {
+ if (mainl->id_map != nullptr) {
/* Cannot keep this since we add some IDs from joined mains. */
BKE_main_idmap_destroy(mainl->id_map);
- mainl->id_map = NULL;
+ mainl->id_map = nullptr;
}
while ((tojoin = mainl->next)) {
@@ -468,11 +470,11 @@ void blo_join_main(ListBase *mainlist)
static void split_libdata(ListBase *lb_src, Main **lib_main_array, const uint lib_main_array_len)
{
- for (ID *id = lb_src->first, *idnext; id; id = idnext) {
- idnext = id->next;
+ for (ID *id = static_cast<ID *>(lb_src->first), *idnext; id; id = idnext) {
+ idnext = static_cast<ID *>(id->next);
if (id->lib) {
- if (((uint)id->lib->temp_index < lib_main_array_len) &&
+ if ((uint(id->lib->temp_index) < lib_main_array_len) &&
/* this check should never fail, just in case 'id->lib' is a dangling pointer. */
(lib_main_array[id->lib->temp_index]->curlib == id->lib)) {
Main *mainvar = lib_main_array[id->lib->temp_index];
@@ -490,24 +492,26 @@ static void split_libdata(ListBase *lb_src, Main **lib_main_array, const uint li
void blo_split_main(ListBase *mainlist, Main *main)
{
mainlist->first = mainlist->last = main;
- main->next = NULL;
+ main->next = nullptr;
if (BLI_listbase_is_empty(&main->libraries)) {
return;
}
- if (main->id_map != NULL) {
+ if (main->id_map != nullptr) {
/* Cannot keep this since we remove some IDs from given main. */
BKE_main_idmap_destroy(main->id_map);
- main->id_map = NULL;
+ main->id_map = nullptr;
}
/* (Library.temp_index -> Main), lookup table */
const uint lib_main_array_len = BLI_listbase_count(&main->libraries);
- Main **lib_main_array = MEM_malloc_arrayN(lib_main_array_len, sizeof(*lib_main_array), __func__);
+ Main **lib_main_array = static_cast<Main **>(
+ MEM_malloc_arrayN(lib_main_array_len, sizeof(*lib_main_array), __func__));
int i = 0;
- for (Library *lib = main->libraries.first; lib; lib = lib->id.next, i++) {
+ for (Library *lib = static_cast<Library *>(main->libraries.first); lib;
+ lib = static_cast<Library *>(lib->id.next), i++) {
Main *libmain = BKE_main_new();
libmain->curlib = lib;
libmain->versionfile = lib->versionfile;
@@ -520,8 +524,8 @@ void blo_split_main(ListBase *mainlist, Main *main)
ListBase *lbarray[INDEX_ID_MAX];
i = set_listbasepointers(main, lbarray);
while (i--) {
- ID *id = lbarray[i]->first;
- if (id == NULL || GS(id->name) == ID_LI) {
+ ID *id = static_cast<ID *>(lbarray[i]->first);
+ if (id == nullptr || GS(id->name) == ID_LI) {
/* No ID_LI data-block should ever be linked anyway, but just in case, better be explicit. */
continue;
}
@@ -537,7 +541,7 @@ static void read_file_version(FileData *fd, Main *main)
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
if (bhead->code == GLOB) {
- FileGlobal *fg = read_struct(fd, bhead, "Global");
+ FileGlobal *fg = static_cast<FileGlobal *>(read_struct(fd, bhead, "Global"));
if (fg) {
main->subversionfile = fg->subversion;
main->minversionfile = fg->minversion;
@@ -586,7 +590,7 @@ static void read_file_bhead_idname_map_create(FileData *fd)
if (code_prev != bhead->code) {
code_prev = bhead->code;
is_link = blo_bhead_is_id_valid_type(bhead) ?
- BKE_idtype_idcode_is_linkable((short)code_prev) :
+ BKE_idtype_idcode_is_linkable(short(code_prev)) :
false;
}
@@ -595,7 +599,7 @@ static void read_file_bhead_idname_map_create(FileData *fd)
}
}
- BLI_assert(fd->bhead_idname_hash == NULL);
+ BLI_assert(fd->bhead_idname_hash == nullptr);
fd->bhead_idname_hash = BLI_ghash_str_new_ex(__func__, reserve);
@@ -603,7 +607,7 @@ static void read_file_bhead_idname_map_create(FileData *fd)
if (code_prev != bhead->code) {
code_prev = bhead->code;
is_link = blo_bhead_is_id_valid_type(bhead) ?
- BKE_idtype_idcode_is_linkable((short)code_prev) :
+ BKE_idtype_idcode_is_linkable(short(code_prev)) :
false;
}
@@ -628,7 +632,7 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab
// printf("blo_find_main: original in %s\n", filepath);
// printf("blo_find_main: converted to %s\n", name1);
- for (m = mainlist->first; m; m = m->next) {
+ for (m = static_cast<Main *>(mainlist->first); m; m = m->next) {
const char *libname = (m->curlib) ? m->curlib->filepath_abs : m->filepath;
if (BLI_path_cmp(name1, libname) == 0) {
@@ -644,7 +648,8 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab
/* Add library data-block itself to 'main' Main, since libraries are **never** linked data.
* Fixes bug where you could end with all ID_LI data-blocks having the same name... */
- lib = BKE_libblock_alloc(mainlist->first, ID_LI, BLI_path_basename(filepath), 0);
+ lib = static_cast<Library *>(BKE_libblock_alloc(
+ static_cast<Main *>(mainlist->first), ID_LI, BLI_path_basename(filepath), 0));
/* Important, consistency with main ID reading code from read_libblock(). */
lib->id.us = ID_FAKE_USERS(lib);
@@ -671,19 +676,19 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab
/** \name File Parsing
* \{ */
-typedef struct BlendDataReader {
+struct BlendDataReader {
FileData *fd;
-} BlendDataReader;
+};
-typedef struct BlendLibReader {
+struct BlendLibReader {
FileData *fd;
Main *main;
-} BlendLibReader;
+};
-typedef struct BlendExpander {
+struct BlendExpander {
FileData *fd;
Main *main;
-} BlendExpander;
+};
static void switch_endian_bh4(BHead4 *bhead)
{
@@ -732,7 +737,7 @@ static void bh4_from_bh8(BHead *bhead, BHead8 *bhead8, bool do_endian_swap)
/* this patch is to avoid `intptr_t` being read from not-eight aligned positions
* is necessary on any modern 64bit architecture) */
memcpy(&old, &bhead8->old, 8);
- bhead4->old = (int)(old >> 3);
+ bhead4->old = int(old >> 3);
bhead4->SDNAnr = bhead8->SDNAnr;
bhead4->nr = bhead8->nr;
@@ -755,7 +760,7 @@ static void bh8_from_bh4(BHead *bhead, BHead4 *bhead4)
static BHeadN *get_bhead(FileData *fd)
{
- BHeadN *new_bhead = NULL;
+ BHeadN *new_bhead = nullptr;
ssize_t readsize;
if (fd) {
@@ -832,11 +837,11 @@ static BHeadN *get_bhead(FileData *fd)
/* pass */
}
#ifdef USE_BHEAD_READ_ON_DEMAND
- else if (fd->file->seek != NULL && BHEAD_USE_READ_ON_DEMAND(&bhead)) {
+ else if (fd->file->seek != nullptr && BHEAD_USE_READ_ON_DEMAND(&bhead)) {
/* Delay reading bhead content. */
- new_bhead = MEM_mallocN(sizeof(BHeadN), "new_bhead");
+ new_bhead = static_cast<BHeadN *>(MEM_mallocN(sizeof(BHeadN), "new_bhead"));
if (new_bhead) {
- new_bhead->next = new_bhead->prev = NULL;
+ new_bhead->next = new_bhead->prev = nullptr;
new_bhead->file_offset = fd->file->offset;
new_bhead->has_data = false;
new_bhead->is_memchunk_identical = false;
@@ -845,7 +850,7 @@ static BHeadN *get_bhead(FileData *fd)
if (seek_new == -1) {
fd->is_eof = true;
MEM_freeN(new_bhead);
- new_bhead = NULL;
+ new_bhead = nullptr;
}
BLI_assert(fd->file->offset == seek_new);
}
@@ -855,9 +860,10 @@ static BHeadN *get_bhead(FileData *fd)
}
#endif
else {
- new_bhead = MEM_mallocN(sizeof(BHeadN) + (size_t)bhead.len, "new_bhead");
+ new_bhead = static_cast<BHeadN *>(
+ MEM_mallocN(sizeof(BHeadN) + size_t(bhead.len), "new_bhead"));
if (new_bhead) {
- new_bhead->next = new_bhead->prev = NULL;
+ new_bhead->next = new_bhead->prev = nullptr;
#ifdef USE_BHEAD_READ_ON_DEMAND
new_bhead->file_offset = 0; /* don't seek. */
new_bhead->has_data = true;
@@ -865,12 +871,12 @@ static BHeadN *get_bhead(FileData *fd)
new_bhead->is_memchunk_identical = false;
new_bhead->bhead = bhead;
- readsize = fd->file->read(fd->file, new_bhead + 1, (size_t)bhead.len);
+ readsize = fd->file->read(fd->file, new_bhead + 1, size_t(bhead.len));
if (readsize != bhead.len) {
fd->is_eof = true;
MEM_freeN(new_bhead);
- new_bhead = NULL;
+ new_bhead = nullptr;
}
if (fd->flags & FD_FLAGS_IS_MEMFILE) {
@@ -897,13 +903,13 @@ static BHeadN *get_bhead(FileData *fd)
BHead *blo_bhead_first(FileData *fd)
{
BHeadN *new_bhead;
- BHead *bhead = NULL;
+ BHead *bhead = nullptr;
/* Rewind the file
* Read in a new block if necessary
*/
- new_bhead = fd->bhead_list.first;
- if (new_bhead == NULL) {
+ new_bhead = static_cast<BHeadN *>(fd->bhead_list.first);
+ if (new_bhead == nullptr) {
new_bhead = get_bhead(fd);
}
@@ -914,18 +920,18 @@ BHead *blo_bhead_first(FileData *fd)
return bhead;
}
-BHead *blo_bhead_prev(FileData *UNUSED(fd), BHead *thisblock)
+BHead *blo_bhead_prev(FileData * /*fd*/, BHead *thisblock)
{
BHeadN *bheadn = BHEADN_FROM_BHEAD(thisblock);
BHeadN *prev = bheadn->prev;
- return (prev) ? &prev->bhead : NULL;
+ return (prev) ? &prev->bhead : nullptr;
}
BHead *blo_bhead_next(FileData *fd, BHead *thisblock)
{
- BHeadN *new_bhead = NULL;
- BHead *bhead = NULL;
+ BHeadN *new_bhead = nullptr;
+ BHead *bhead = nullptr;
if (thisblock) {
/* bhead is actually a sub part of BHeadN
@@ -934,7 +940,7 @@ BHead *blo_bhead_next(FileData *fd, BHead *thisblock)
/* get the next BHeadN. If it doesn't exist we read in the next one */
new_bhead = new_bhead->next;
- if (new_bhead == NULL) {
+ if (new_bhead == nullptr) {
new_bhead = get_bhead(fd);
}
}
@@ -959,7 +965,7 @@ static bool blo_bhead_read_data(FileData *fd, BHead *thisblock, void *buf)
success = false;
}
else {
- if (fd->file->read(fd->file, buf, (size_t)new_bhead->bhead.len) != new_bhead->bhead.len) {
+ if (fd->file->read(fd->file, buf, size_t(new_bhead->bhead.len)) != new_bhead->bhead.len) {
success = false;
}
if (fd->flags & FD_FLAGS_IS_MEMFILE) {
@@ -975,14 +981,15 @@ static bool blo_bhead_read_data(FileData *fd, BHead *thisblock, void *buf)
static BHead *blo_bhead_read_full(FileData *fd, BHead *thisblock)
{
BHeadN *new_bhead = BHEADN_FROM_BHEAD(thisblock);
- BHeadN *new_bhead_data = MEM_mallocN(sizeof(BHeadN) + new_bhead->bhead.len, "new_bhead");
+ BHeadN *new_bhead_data = static_cast<BHeadN *>(
+ MEM_mallocN(sizeof(BHeadN) + new_bhead->bhead.len, "new_bhead"));
new_bhead_data->bhead = new_bhead->bhead;
new_bhead_data->file_offset = new_bhead->file_offset;
new_bhead_data->has_data = true;
new_bhead_data->is_memchunk_identical = false;
if (!blo_bhead_read_data(fd, thisblock, new_bhead_data + 1)) {
MEM_freeN(new_bhead_data);
- return NULL;
+ return nullptr;
}
return &new_bhead_data->bhead;
}
@@ -998,7 +1005,7 @@ AssetMetaData *blo_bhead_id_asset_data_address(const FileData *fd, const BHead *
BLI_assert(blo_bhead_is_id_valid_type(bhead));
return (fd->id_asset_data_offset >= 0) ?
*(AssetMetaData **)POINTER_OFFSET(bhead, sizeof(*bhead) + fd->id_asset_data_offset) :
- NULL;
+ nullptr;
}
static void decode_blender_header(FileData *fd)
@@ -1058,7 +1065,7 @@ static bool read_file_dna(FileData *fd, const char **r_error_message)
}
/* We can't use read_global because this needs 'DNA1' to be decoded,
* however the first 4 chars are _always_ the subversion. */
- FileGlobal *fg = (void *)&bhead[1];
+ FileGlobal *fg = reinterpret_cast<FileGlobal *>(&bhead[1]);
BLI_STATIC_ASSERT(offsetof(FileGlobal, subvstr) == 0, "Must be first: subvstr")
char num[5];
memcpy(num, fg->subvstr, 4);
@@ -1098,14 +1105,14 @@ static bool read_file_dna(FileData *fd, const char **r_error_message)
static int *read_file_thumbnail(FileData *fd)
{
BHead *bhead;
- int *blend_thumb = NULL;
+ int *blend_thumb = nullptr;
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
if (bhead->code == TEST) {
const bool do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0;
int *data = (int *)(bhead + 1);
- if (bhead->len < (sizeof(int[2]))) {
+ if (bhead->len < sizeof(int[2])) {
break;
}
@@ -1143,9 +1150,9 @@ static int *read_file_thumbnail(FileData *fd)
static FileData *filedata_new(BlendFileReadReport *reports)
{
- BLI_assert(reports != NULL);
+ BLI_assert(reports != nullptr);
- FileData *fd = MEM_callocN(sizeof(FileData), "FileData");
+ FileData *fd = static_cast<FileData *>(MEM_callocN(sizeof(FileData), "FileData"));
fd->memsdna = DNA_sdna_current_get();
@@ -1163,19 +1170,19 @@ static FileData *blo_decode_and_check(FileData *fd, ReportList *reports)
decode_blender_header(fd);
if (fd->flags & FD_FLAGS_FILE_OK) {
- const char *error_message = NULL;
+ const char *error_message = nullptr;
if (read_file_dna(fd, &error_message) == false) {
BKE_reportf(
reports, RPT_ERROR, "Failed to read blend file '%s': %s", fd->relabase, error_message);
blo_filedata_free(fd);
- fd = NULL;
+ fd = nullptr;
}
}
else {
BKE_reportf(
reports, RPT_ERROR, "Failed to read blend file '%s', not a blend file", fd->relabase);
blo_filedata_free(fd);
- fd = NULL;
+ fd = nullptr;
}
return fd;
@@ -1187,11 +1194,11 @@ static FileData *blo_filedata_from_file_descriptor(const char *filepath,
{
char header[7];
FileReader *rawfile = BLI_filereader_new_file(filedes);
- FileReader *file = NULL;
+ FileReader *file = nullptr;
errno = 0;
/* If opening the file failed or we can't read the header, give up. */
- if (rawfile == NULL || rawfile->read(rawfile, header, sizeof(header)) != sizeof(header)) {
+ if (rawfile == nullptr || rawfile->read(rawfile, header, sizeof(header)) != sizeof(header)) {
BKE_reportf(reports->reports,
RPT_WARNING,
"Unable to read '%s': %s",
@@ -1203,7 +1210,7 @@ static FileData *blo_filedata_from_file_descriptor(const char *filepath,
else {
close(filedes);
}
- return NULL;
+ return nullptr;
}
/* Rewind the file after reading the header. */
@@ -1213,32 +1220,32 @@ static FileData *blo_filedata_from_file_descriptor(const char *filepath,
if (memcmp(header, "BLENDER", sizeof(header)) == 0) {
/* Try opening the file with memory-mapped IO. */
file = BLI_filereader_new_mmap(filedes);
- if (file == NULL) {
+ if (file == nullptr) {
/* mmap failed, so just keep using rawfile. */
file = rawfile;
- rawfile = NULL;
+ rawfile = nullptr;
}
}
else if (BLI_file_magic_is_gzip(header)) {
file = BLI_filereader_new_gzip(rawfile);
- if (file != NULL) {
- rawfile = NULL; /* The `Gzip` #FileReader takes ownership of `rawfile`. */
+ if (file != nullptr) {
+ rawfile = nullptr; /* The `Gzip` #FileReader takes ownership of `rawfile`. */
}
}
else if (BLI_file_magic_is_zstd(header)) {
file = BLI_filereader_new_zstd(rawfile);
- if (file != NULL) {
- rawfile = NULL; /* The `Zstd` #FileReader takes ownership of `rawfile`. */
+ if (file != nullptr) {
+ rawfile = nullptr; /* The `Zstd` #FileReader takes ownership of `rawfile`. */
}
}
/* Clean up `rawfile` if it wasn't taken over. */
- if (rawfile != NULL) {
+ if (rawfile != nullptr) {
rawfile->close(rawfile);
}
- if (file == NULL) {
+ if (file == nullptr) {
BKE_reportf(reports->reports, RPT_WARNING, "Unrecognized file format '%s'", filepath);
- return NULL;
+ return nullptr;
}
FileData *fd = filedata_new(reports);
@@ -1257,7 +1264,7 @@ static FileData *blo_filedata_from_file_open(const char *filepath, BlendFileRead
"Unable to open '%s': %s",
filepath,
errno ? strerror(errno) : TIP_("unknown error reading file"));
- return NULL;
+ return nullptr;
}
return blo_filedata_from_file_descriptor(filepath, reports, file);
}
@@ -1265,13 +1272,13 @@ static FileData *blo_filedata_from_file_open(const char *filepath, BlendFileRead
FileData *blo_filedata_from_file(const char *filepath, BlendFileReadReport *reports)
{
FileData *fd = blo_filedata_from_file_open(filepath, reports);
- if (fd != NULL) {
+ if (fd != nullptr) {
/* needed for library_append and read_libraries */
BLI_strncpy(fd->relabase, filepath, sizeof(fd->relabase));
return blo_decode_and_check(fd, reports->reports);
}
- return NULL;
+ return nullptr;
}
/**
@@ -1280,15 +1287,16 @@ FileData *blo_filedata_from_file(const char *filepath, BlendFileReadReport *repo
*/
static FileData *blo_filedata_from_file_minimal(const char *filepath)
{
- FileData *fd = blo_filedata_from_file_open(filepath, &(BlendFileReadReport){.reports = NULL});
- if (fd != NULL) {
+ BlendFileReadReport read_report{};
+ FileData *fd = blo_filedata_from_file_open(filepath, &read_report);
+ if (fd != nullptr) {
decode_blender_header(fd);
if (fd->flags & FD_FLAGS_FILE_OK) {
return fd;
}
blo_filedata_free(fd);
}
- return NULL;
+ return nullptr;
}
FileData *blo_filedata_from_memory(const void *mem, int memsize, BlendFileReadReport *reports)
@@ -1296,23 +1304,23 @@ FileData *blo_filedata_from_memory(const void *mem, int memsize, BlendFileReadRe
if (!mem || memsize < SIZEOFBLENDERHEADER) {
BKE_report(
reports->reports, RPT_WARNING, (mem) ? TIP_("Unable to read") : TIP_("Unable to open"));
- return NULL;
+ return nullptr;
}
FileReader *mem_file = BLI_filereader_new_memory(mem, memsize);
FileReader *file = mem_file;
- if (BLI_file_magic_is_gzip(mem)) {
+ if (BLI_file_magic_is_gzip(static_cast<const char *>(mem))) {
file = BLI_filereader_new_gzip(mem_file);
}
- else if (BLI_file_magic_is_zstd(mem)) {
+ else if (BLI_file_magic_is_zstd(static_cast<const char *>(mem))) {
file = BLI_filereader_new_zstd(mem_file);
}
- if (file == NULL) {
+ if (file == nullptr) {
/* Compression initialization failed. */
mem_file->close(mem_file);
- return NULL;
+ return nullptr;
}
FileData *fd = filedata_new(reports);
@@ -1322,12 +1330,12 @@ FileData *blo_filedata_from_memory(const void *mem, int memsize, BlendFileReadRe
}
FileData *blo_filedata_from_memfile(MemFile *memfile,
- const struct BlendFileReadParams *params,
+ const BlendFileReadParams *params,
BlendFileReadReport *reports)
{
if (!memfile) {
BKE_report(reports->reports, RPT_WARNING, "Unable to open blend <memory>");
- return NULL;
+ return nullptr;
}
FileData *fd = filedata_new(reports);
@@ -1348,7 +1356,7 @@ void blo_filedata_free(FileData *fd)
#else
/* Sanity check we're not keeping memory we don't need. */
LISTBASE_FOREACH_MUTABLE (BHeadN *, new_bhead, &fd->bhead_list) {
- if (fd->file->seek != NULL && BHEAD_USE_READ_ON_DEMAND(&new_bhead->bhead)) {
+ if (fd->file->seek != nullptr && BHEAD_USE_READ_ON_DEMAND(&new_bhead->bhead)) {
BLI_assert(new_bhead->has_data == 0);
}
MEM_freeN(new_bhead);
@@ -1378,7 +1386,7 @@ void blo_filedata_free(FileData *fd)
if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP)) {
oldnewmap_free(fd->libmap);
}
- if (fd->old_idmap != NULL) {
+ if (fd->old_idmap != nullptr) {
BKE_main_idmap_destroy(fd->old_idmap);
}
blo_cache_storage_end(fd);
@@ -1388,7 +1396,7 @@ void blo_filedata_free(FileData *fd)
#ifdef USE_GHASH_BHEAD
if (fd->bhead_idname_hash) {
- BLI_ghash_free(fd->bhead_idname_hash, NULL, NULL);
+ BLI_ghash_free(fd->bhead_idname_hash, nullptr, nullptr);
}
#endif
@@ -1404,7 +1412,7 @@ void blo_filedata_free(FileData *fd)
bool BLO_has_bfile_extension(const char *str)
{
- const char *ext_test[4] = {".blend", ".ble", ".blend.gz", NULL};
+ const char *ext_test[4] = {".blend", ".ble", ".blend.gz", nullptr};
return BLI_path_extension_check_array(str, ext_test);
}
@@ -1413,14 +1421,14 @@ bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, cha
/* We might get some data names with slashes,
* so we have to go up in path until we find blend file itself,
* then we know next path item is group, and everything else is data name. */
- char *slash = NULL, *prev_slash = NULL, c = '\0';
+ char *slash = nullptr, *prev_slash = nullptr, c = '\0';
r_dir[0] = '\0';
if (r_group) {
- *r_group = NULL;
+ *r_group = nullptr;
}
if (r_name) {
- *r_name = NULL;
+ *r_name = nullptr;
}
/* if path leads to an existing directory, we can be sure we're not (in) a library */
@@ -1471,18 +1479,18 @@ bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, cha
BlendThumbnail *BLO_thumbnail_from_file(const char *filepath)
{
FileData *fd;
- BlendThumbnail *data = NULL;
+ BlendThumbnail *data = nullptr;
int *fd_data;
fd = blo_filedata_from_file_minimal(filepath);
- fd_data = fd ? read_file_thumbnail(fd) : NULL;
+ fd_data = fd ? read_file_thumbnail(fd) : nullptr;
if (fd_data) {
const int width = fd_data[0];
const int height = fd_data[1];
if (BLEN_THUMB_MEMSIZE_IS_VALID(width, height)) {
const size_t data_size = BLEN_THUMB_MEMSIZE(width, height);
- data = MEM_mallocN(data_size, __func__);
+ data = static_cast<BlendThumbnail *>(MEM_mallocN(data_size, __func__));
if (data) {
BLI_assert((data_size - sizeof(*data)) ==
(BLEN_THUMB_MEMSIZE_FILE(width, height) - (sizeof(*fd_data) * 2)));
@@ -1543,15 +1551,17 @@ void *blo_do_versions_newlibadr(FileData *fd, const void *lib, const void *adr)
}
/* increases user number */
-static void change_link_placeholder_to_real_ID_pointer_fd(FileData *fd, const void *old, void *new)
+static void change_link_placeholder_to_real_ID_pointer_fd(FileData *fd,
+ const void *old,
+ void *newp)
{
for (int i = 0; i < fd->libmap->nentries; i++) {
OldNew *entry = &fd->libmap->entries[i];
if (old == entry->newp && entry->nr == ID_LINK_PLACEHOLDER) {
- entry->newp = new;
- if (new) {
- entry->nr = GS(((ID *)new)->name);
+ entry->newp = newp;
+ if (newp) {
+ entry->nr = GS(((ID *)newp)->name);
}
}
}
@@ -1560,7 +1570,7 @@ static void change_link_placeholder_to_real_ID_pointer_fd(FileData *fd, const vo
static void change_link_placeholder_to_real_ID_pointer(ListBase *mainlist,
FileData *basefd,
void *old,
- void *new)
+ void *newp)
{
LISTBASE_FOREACH (Main *, mainptr, mainlist) {
FileData *fd;
@@ -1573,7 +1583,7 @@ static void change_link_placeholder_to_real_ID_pointer(ListBase *mainlist,
}
if (fd) {
- change_link_placeholder_to_real_ID_pointer_fd(fd, old, new);
+ change_link_placeholder_to_real_ID_pointer_fd(fd, old, newp);
}
}
}
@@ -1635,32 +1645,32 @@ void blo_end_packed_pointer_map(FileData *fd, Main *oldmain)
/* used entries were restored, so we put them to zero */
for (int i = 0; i < fd->packedmap->nentries; i++, entry++) {
if (entry->nr > 0) {
- entry->newp = NULL;
+ entry->newp = nullptr;
}
}
LISTBASE_FOREACH (Image *, ima, &oldmain->images) {
- ima->packedfile = newpackedadr(fd, ima->packedfile);
+ ima->packedfile = static_cast<PackedFile *>(newpackedadr(fd, ima->packedfile));
LISTBASE_FOREACH (ImagePackedFile *, imapf, &ima->packedfiles) {
- imapf->packedfile = newpackedadr(fd, imapf->packedfile);
+ imapf->packedfile = static_cast<PackedFile *>(newpackedadr(fd, imapf->packedfile));
}
}
LISTBASE_FOREACH (VFont *, vfont, &oldmain->fonts) {
- vfont->packedfile = newpackedadr(fd, vfont->packedfile);
+ vfont->packedfile = static_cast<PackedFile *>(newpackedadr(fd, vfont->packedfile));
}
LISTBASE_FOREACH (bSound *, sound, &oldmain->sounds) {
- sound->packedfile = newpackedadr(fd, sound->packedfile);
+ sound->packedfile = static_cast<PackedFile *>(newpackedadr(fd, sound->packedfile));
}
LISTBASE_FOREACH (Library *, lib, &oldmain->libraries) {
- lib->packedfile = newpackedadr(fd, lib->packedfile);
+ lib->packedfile = static_cast<PackedFile *>(newpackedadr(fd, lib->packedfile));
}
LISTBASE_FOREACH (Volume *, volume, &oldmain->volumes) {
- volume->packedfile = newpackedadr(fd, volume->packedfile);
+ volume->packedfile = static_cast<PackedFile *>(newpackedadr(fd, volume->packedfile));
}
}
@@ -1682,36 +1692,37 @@ void blo_add_library_pointer_map(ListBase *old_mainlist, FileData *fd)
void blo_make_old_idmap_from_main(FileData *fd, Main *bmain)
{
- if (fd->old_idmap != NULL) {
+ if (fd->old_idmap != nullptr) {
BKE_main_idmap_destroy(fd->old_idmap);
}
- fd->old_idmap = BKE_main_idmap_create(bmain, false, NULL, MAIN_IDMAP_TYPE_UUID);
+ fd->old_idmap = BKE_main_idmap_create(bmain, false, nullptr, MAIN_IDMAP_TYPE_UUID);
}
-typedef struct BLOCacheStorage {
+struct BLOCacheStorage {
GHash *cache_map;
MemArena *memarena;
-} BLOCacheStorage;
+};
-typedef struct BLOCacheStorageValue {
+struct BLOCacheStorageValue {
void *cache_v;
uint new_usage_count;
-} BLOCacheStorageValue;
+};
/** Register a cache data entry to be preserved when reading some undo memfile. */
static void blo_cache_storage_entry_register(
- ID *id, const IDCacheKey *key, void **cache_p, uint UNUSED(flags), void *cache_storage_v)
+ ID *id, const IDCacheKey *key, void **cache_p, uint /*flags*/, void *cache_storage_v)
{
BLI_assert(key->id_session_uuid == id->session_uuid);
UNUSED_VARS_NDEBUG(id);
- BLOCacheStorage *cache_storage = cache_storage_v;
+ BLOCacheStorage *cache_storage = static_cast<BLOCacheStorage *>(cache_storage_v);
BLI_assert(!BLI_ghash_haskey(cache_storage->cache_map, key));
- IDCacheKey *storage_key = BLI_memarena_alloc(cache_storage->memarena, sizeof(*storage_key));
+ IDCacheKey *storage_key = static_cast<IDCacheKey *>(
+ BLI_memarena_alloc(cache_storage->memarena, sizeof(*storage_key)));
*storage_key = *key;
- BLOCacheStorageValue *storage_value = BLI_memarena_alloc(cache_storage->memarena,
- sizeof(*storage_value));
+ BLOCacheStorageValue *storage_value = static_cast<BLOCacheStorageValue *>(
+ BLI_memarena_alloc(cache_storage->memarena, sizeof(*storage_value)));
storage_value->cache_v = *cache_p;
storage_value->new_usage_count = 0;
BLI_ghash_insert(cache_storage->cache_map, storage_key, storage_value);
@@ -1719,23 +1730,24 @@ static void blo_cache_storage_entry_register(
/** Restore a cache data entry from old ID into new one, when reading some undo memfile. */
static void blo_cache_storage_entry_restore_in_new(
- ID *UNUSED(id), const IDCacheKey *key, void **cache_p, uint flags, void *cache_storage_v)
+ ID * /*id*/, const IDCacheKey *key, void **cache_p, uint flags, void *cache_storage_v)
{
- BLOCacheStorage *cache_storage = cache_storage_v;
+ BLOCacheStorage *cache_storage = static_cast<BLOCacheStorage *>(cache_storage_v);
- if (cache_storage == NULL) {
+ if (cache_storage == nullptr) {
/* In non-undo case, only clear the pointer if it is a purely runtime one.
* If it may be stored in a persistent way in the .blend file, direct_link code is responsible
* to properly deal with it. */
if ((flags & IDTYPE_CACHE_CB_FLAGS_PERSISTENT) == 0) {
- *cache_p = NULL;
+ *cache_p = nullptr;
}
return;
}
- BLOCacheStorageValue *storage_value = BLI_ghash_lookup(cache_storage->cache_map, key);
- if (storage_value == NULL) {
- *cache_p = NULL;
+ BLOCacheStorageValue *storage_value = static_cast<BLOCacheStorageValue *>(
+ BLI_ghash_lookup(cache_storage->cache_map, key));
+ if (storage_value == nullptr) {
+ *cache_p = nullptr;
return;
}
storage_value->new_usage_count++;
@@ -1743,23 +1755,21 @@ static void blo_cache_storage_entry_restore_in_new(
}
/** Clear as needed a cache data entry from old ID, when reading some undo memfile. */
-static void blo_cache_storage_entry_clear_in_old(ID *UNUSED(id),
- const IDCacheKey *key,
- void **cache_p,
- uint UNUSED(flags),
- void *cache_storage_v)
+static void blo_cache_storage_entry_clear_in_old(
+ ID * /*id*/, const IDCacheKey *key, void **cache_p, uint /*flags*/, void *cache_storage_v)
{
- BLOCacheStorage *cache_storage = cache_storage_v;
+ BLOCacheStorage *cache_storage = static_cast<BLOCacheStorage *>(cache_storage_v);
- BLOCacheStorageValue *storage_value = BLI_ghash_lookup(cache_storage->cache_map, key);
- if (storage_value == NULL) {
- *cache_p = NULL;
+ BLOCacheStorageValue *storage_value = static_cast<BLOCacheStorageValue *>(
+ BLI_ghash_lookup(cache_storage->cache_map, key));
+ if (storage_value == nullptr) {
+ *cache_p = nullptr;
return;
}
/* If that cache has been restored into some new ID, we want to remove it from old one, otherwise
* keep it there so that it gets properly freed together with its ID. */
if (storage_value->new_usage_count != 0) {
- *cache_p = NULL;
+ *cache_p = nullptr;
}
else {
BLI_assert(*cache_p == storage_value->cache_v);
@@ -1769,21 +1779,22 @@ static void blo_cache_storage_entry_clear_in_old(ID *UNUSED(id),
void blo_cache_storage_init(FileData *fd, Main *bmain)
{
if (fd->flags & FD_FLAGS_IS_MEMFILE) {
- BLI_assert(fd->cache_storage == NULL);
- fd->cache_storage = MEM_mallocN(sizeof(*fd->cache_storage), __func__);
+ BLI_assert(fd->cache_storage == nullptr);
+ fd->cache_storage = static_cast<BLOCacheStorage *>(
+ MEM_mallocN(sizeof(*fd->cache_storage), __func__));
fd->cache_storage->memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
fd->cache_storage->cache_map = BLI_ghash_new(
BKE_idtype_cache_key_hash, BKE_idtype_cache_key_cmp, __func__);
ListBase *lb;
FOREACH_MAIN_LISTBASE_BEGIN (bmain, lb) {
- ID *id = lb->first;
- if (id == NULL) {
+ ID *id = static_cast<ID *>(lb->first);
+ if (id == nullptr) {
continue;
}
const IDTypeInfo *type_info = BKE_idtype_get_info_from_id(id);
- if (type_info->foreach_cache == NULL) {
+ if (type_info->foreach_cache == nullptr) {
continue;
}
@@ -1798,22 +1809,22 @@ void blo_cache_storage_init(FileData *fd, Main *bmain)
FOREACH_MAIN_LISTBASE_END;
}
else {
- fd->cache_storage = NULL;
+ fd->cache_storage = nullptr;
}
}
void blo_cache_storage_old_bmain_clear(FileData *fd, Main *bmain_old)
{
- if (fd->cache_storage != NULL) {
+ if (fd->cache_storage != nullptr) {
ListBase *lb;
FOREACH_MAIN_LISTBASE_BEGIN (bmain_old, lb) {
- ID *id = lb->first;
- if (id == NULL) {
+ ID *id = static_cast<ID *>(lb->first);
+ if (id == nullptr) {
continue;
}
const IDTypeInfo *type_info = BKE_idtype_get_info_from_id(id);
- if (type_info->foreach_cache == NULL) {
+ if (type_info->foreach_cache == nullptr) {
continue;
}
@@ -1831,11 +1842,11 @@ void blo_cache_storage_old_bmain_clear(FileData *fd, Main *bmain_old)
void blo_cache_storage_end(FileData *fd)
{
- if (fd->cache_storage != NULL) {
- BLI_ghash_free(fd->cache_storage->cache_map, NULL, NULL);
+ if (fd->cache_storage != nullptr) {
+ BLI_ghash_free(fd->cache_storage->cache_map, nullptr, nullptr);
BLI_memarena_free(fd->cache_storage->memarena);
MEM_freeN(fd->cache_storage);
- fd->cache_storage = NULL;
+ fd->cache_storage = nullptr;
}
}
@@ -1845,7 +1856,7 @@ void blo_cache_storage_end(FileData *fd)
/** \name DNA Struct Loading
* \{ */
-static void switch_endian_structs(const struct SDNA *filesdna, BHead *bhead)
+static void switch_endian_structs(const SDNA *filesdna, BHead *bhead)
{
int blocksize, nblocks;
char *data;
@@ -1863,7 +1874,7 @@ static void switch_endian_structs(const struct SDNA *filesdna, BHead *bhead)
static void *read_struct(FileData *fd, BHead *bh, const char *blockname)
{
- void *temp = NULL;
+ void *temp = nullptr;
if (bh->len) {
#ifdef USE_BHEAD_READ_ON_DEMAND
@@ -1875,9 +1886,9 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname)
#ifdef USE_BHEAD_READ_ON_DEMAND
if (BHEADN_FROM_BHEAD(bh)->has_data == false) {
bh = blo_bhead_read_full(fd, bh);
- if (UNLIKELY(bh == NULL)) {
+ if (UNLIKELY(bh == nullptr)) {
fd->flags &= ~FD_FLAGS_FILE_OK;
- return NULL;
+ return nullptr;
}
}
#endif
@@ -1889,9 +1900,9 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname)
#ifdef USE_BHEAD_READ_ON_DEMAND
if (BHEADN_FROM_BHEAD(bh)->has_data == false) {
bh = blo_bhead_read_full(fd, bh);
- if (UNLIKELY(bh == NULL)) {
+ if (UNLIKELY(bh == nullptr)) {
fd->flags &= ~FD_FLAGS_FILE_OK;
- return NULL;
+ return nullptr;
}
}
#endif
@@ -1910,7 +1921,7 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname)
if (UNLIKELY(!blo_bhead_read_data(fd, bh, temp))) {
fd->flags &= ~FD_FLAGS_FILE_OK;
MEM_freeN(temp);
- temp = NULL;
+ temp = nullptr;
}
}
#else
@@ -1935,7 +1946,7 @@ static const void *peek_struct_undo(FileData *fd, BHead *bhead)
{
BLI_assert(fd->flags & FD_FLAGS_IS_MEMFILE);
UNUSED_VARS_NDEBUG(fd);
- return (bhead->len) ? (const void *)(bhead + 1) : NULL;
+ return (bhead->len) ? (const void *)(bhead + 1) : nullptr;
}
static void link_glob_list(FileData *fd, ListBase *lb) /* for glob data */
@@ -1952,14 +1963,14 @@ static void link_glob_list(FileData *fd, ListBase *lb) /* for glob data */
}
lb->first = poin;
- ln = lb->first;
- prev = NULL;
+ ln = static_cast<Link *>(lb->first);
+ prev = nullptr;
while (ln) {
poin = newdataadr(fd, ln->next);
if (ln->next) {
oldnewmap_insert(fd->globmap, ln->next, poin, 0);
}
- ln->next = poin;
+ ln->next = static_cast<Link *>(poin);
ln->prev = prev;
prev = ln;
ln = ln->next;
@@ -1980,14 +1991,14 @@ static void lib_link_id_embedded_id(BlendLibReader *reader, ID *id)
/* Handle 'private IDs'. */
bNodeTree *nodetree = ntreeFromID(id);
- if (nodetree != NULL) {
+ if (nodetree != nullptr) {
lib_link_id(reader, &nodetree->id);
ntreeBlendReadLib(reader, nodetree);
}
if (GS(id->name) == ID_SCE) {
Scene *scene = (Scene *)id;
- if (scene->master_collection != NULL) {
+ if (scene->master_collection != nullptr) {
lib_link_id(reader, &scene->master_collection->id);
BKE_collection_blend_read_lib(reader, scene->master_collection);
}
@@ -1996,12 +2007,12 @@ static void lib_link_id_embedded_id(BlendLibReader *reader, ID *id)
static void lib_link_id(BlendLibReader *reader, ID *id)
{
- /* NOTE: WM IDProperties are never written to file, hence they should always be NULL here. */
- BLI_assert((GS(id->name) != ID_WM) || id->properties == NULL);
+ /* NOTE: WM IDProperties are never written to file, hence they should always be nullptr here. */
+ BLI_assert((GS(id->name) != ID_WM) || id->properties == nullptr);
IDP_BlendReadLib(reader, id->lib, id->properties);
AnimData *adt = BKE_animdata_from_id(id);
- if (adt != NULL) {
+ if (adt != nullptr) {
BKE_animdata_blend_read_lib(reader, id, adt);
}
@@ -2016,7 +2027,8 @@ static void lib_link_id(BlendLibReader *reader, ID *id)
static void direct_link_id_override_property_operation_cb(BlendDataReader *reader, void *data)
{
- IDOverrideLibraryPropertyOperation *opop = data;
+ IDOverrideLibraryPropertyOperation *opop = static_cast<IDOverrideLibraryPropertyOperation *>(
+ data);
BLO_read_data_address(reader, &opop->subitem_reference_name);
BLO_read_data_address(reader, &opop->subitem_local_name);
@@ -2026,7 +2038,7 @@ static void direct_link_id_override_property_operation_cb(BlendDataReader *reade
static void direct_link_id_override_property_cb(BlendDataReader *reader, void *data)
{
- IDOverrideLibraryProperty *op = data;
+ IDOverrideLibraryProperty *op = static_cast<IDOverrideLibraryProperty *>(data);
BLO_read_data_address(reader, &op->rna_path);
@@ -2045,24 +2057,25 @@ static void direct_link_id_embedded_id(BlendDataReader *reader,
{
/* Handle 'private IDs'. */
bNodeTree **nodetree = BKE_ntree_ptr_from_id(id);
- if (nodetree != NULL && *nodetree != NULL) {
+ if (nodetree != nullptr && *nodetree != nullptr) {
BLO_read_data_address(reader, nodetree);
direct_link_id_common(reader,
current_library,
(ID *)*nodetree,
- id_old != NULL ? (ID *)ntreeFromID(id_old) : NULL,
+ id_old != nullptr ? (ID *)ntreeFromID(id_old) : nullptr,
0);
ntreeBlendReadData(reader, id, *nodetree);
}
if (GS(id->name) == ID_SCE) {
Scene *scene = (Scene *)id;
- if (scene->master_collection != NULL) {
+ if (scene->master_collection != nullptr) {
BLO_read_data_address(reader, &scene->master_collection);
direct_link_id_common(reader,
current_library,
&scene->master_collection->id,
- id_old != NULL ? &((Scene *)id_old)->master_collection->id : NULL,
+ id_old != nullptr ? &((Scene *)id_old)->master_collection->id :
+ nullptr,
0);
BKE_collection_blend_read_data(reader, scene->master_collection, &scene->id);
}
@@ -2090,7 +2103,7 @@ static int direct_link_id_restore_recalc(const FileData *fd,
* flush back changes to the original datablock. */
int recalc = id_target->recalc;
- if (id_current == NULL) {
+ if (id_current == nullptr) {
/* ID does not currently exist in the database, so also will not exist in
* the dependency graphs. That means it will be newly created and as a
* result also fully re-evaluated regardless of the recalc flag set here. */
@@ -2130,7 +2143,7 @@ static void direct_link_id_common(
BlendDataReader *reader, Library *current_library, ID *id, ID *id_old, const int tag)
{
if (!BLO_read_data_is_undo(reader)) {
- /* When actually reading a file, we do want to reset/re-generate session uuids.
+ /* When actually reading a file, we do want to reset/re-generate session UUIDS.
* In undo case, we want to re-use existing ones. */
id->session_uuid = MAIN_ID_SESSION_UUID_UNSET;
}
@@ -2142,15 +2155,15 @@ static void direct_link_id_common(
id->lib = current_library;
id->us = ID_FAKE_USERS(id);
id->icon_id = 0;
- id->newid = NULL; /* Needed because .blend may have been saved with crap value here... */
- id->orig_id = NULL;
- id->py_instance = NULL;
+ id->newid = nullptr; /* Needed because .blend may have been saved with crap value here... */
+ id->orig_id = nullptr;
+ id->py_instance = nullptr;
/* Initialize with provided tag. */
id->tag = tag;
if (ID_IS_LINKED(id)) {
- id->library_weak_reference = NULL;
+ id->library_weak_reference = nullptr;
}
else {
BLO_read_data_address(reader, &id->library_weak_reference);
@@ -2200,10 +2213,10 @@ static void direct_link_id_common(
if (id->override_library) {
BLO_read_data_address(reader, &id->override_library);
/* Work around file corruption on writing, see T86853. */
- if (id->override_library != NULL) {
+ if (id->override_library != nullptr) {
BLO_read_list_cb(
reader, &id->override_library->properties, direct_link_id_override_property_cb);
- id->override_library->runtime = NULL;
+ id->override_library->runtime = nullptr;
}
}
@@ -2244,14 +2257,14 @@ void blo_do_versions_key_uidgen(Key *key)
#ifdef USE_SETSCENE_CHECK
/**
- * A version of #BKE_scene_validate_setscene with special checks for linked libs.
+ * A version of #BKE_scene_validate_setscene with special checks for linked libraries.
*/
static bool scene_validate_setscene__liblink(Scene *sce, const int totscene)
{
Scene *sce_iter;
int a;
- if (sce->set == NULL) {
+ if (sce->set == nullptr) {
return true;
}
@@ -2269,7 +2282,7 @@ static bool scene_validate_setscene__liblink(Scene *sce, const int totscene)
}
if (a > totscene) {
- sce->set = NULL;
+ sce->set = nullptr;
return false;
}
}
@@ -2304,10 +2317,10 @@ static void lib_link_scenes_check_set(Main *bmain)
* \{ */
/* how to handle user count on pointer restore */
-typedef enum ePointerUserMode {
+enum ePointerUserMode {
USER_IGNORE = 0, /* ignore user count */
USER_REAL = 1, /* ensure at least one real user (fake user ignored) */
-} ePointerUserMode;
+};
static void restore_pointer_user(ID *id, ID *newid, ePointerUserMode user)
{
@@ -2343,7 +2356,7 @@ static void *restore_pointer_by_name_main(Main *mainp, ID *id, ePointerUserMode
return idn;
}
}
- return NULL;
+ return nullptr;
}
#endif
@@ -2357,7 +2370,7 @@ static void *restore_pointer_by_name_main(Main *mainp, ID *id, ePointerUserMode
* this could be made an optional argument (falling back to a full lookup),
* however at the moment it's always available.
*/
-static void *restore_pointer_by_name(struct IDNameLib_Map *id_map, ID *id, ePointerUserMode user)
+static void *restore_pointer_by_name(IDNameLib_Map *id_map, ID *id, ePointerUserMode user)
{
#ifdef USE_GHASH_RESTORE_POINTER
if (id) {
@@ -2368,24 +2381,24 @@ static void *restore_pointer_by_name(struct IDNameLib_Map *id_map, ID *id, ePoin
}
return idn;
}
- return NULL;
+ return nullptr;
#else
Main *mainp = BKE_main_idmap_main_get(id_map);
return restore_pointer_by_name_main(mainp, id, user);
#endif
}
-static void lib_link_seq_clipboard_pt_restore(ID *id, struct IDNameLib_Map *id_map)
+static void lib_link_seq_clipboard_pt_restore(ID *id, IDNameLib_Map *id_map)
{
if (id) {
/* clipboard must ensure this */
- BLI_assert(id->newid != NULL);
- id->newid = restore_pointer_by_name(id_map, id->newid, USER_REAL);
+ BLI_assert(id->newid != nullptr);
+ id->newid = static_cast<ID *>(restore_pointer_by_name(id_map, id->newid, USER_REAL));
}
}
static bool lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt)
{
- struct IDNameLib_Map *id_map = arg_pt;
+ IDNameLib_Map *id_map = static_cast<IDNameLib_Map *>(arg_pt);
lib_link_seq_clipboard_pt_restore((ID *)seq->scene, id_map);
lib_link_seq_clipboard_pt_restore((ID *)seq->scene_camera, id_map);
@@ -2395,7 +2408,7 @@ static bool lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt)
return true;
}
-static void lib_link_clipboard_restore(struct IDNameLib_Map *id_map)
+static void lib_link_clipboard_restore(IDNameLib_Map *id_map)
{
/* update IDs stored in sequencer clipboard */
SEQ_for_each_callback(&seqbase_clipboard, lib_link_seq_clipboard_cb, id_map);
@@ -2405,7 +2418,7 @@ static int lib_link_main_data_restore_cb(LibraryIDLinkCallbackData *cb_data)
{
const int cb_flag = cb_data->cb_flag;
ID **id_pointer = cb_data->id_pointer;
- if (cb_flag & IDWALK_CB_EMBEDDED || *id_pointer == NULL) {
+ if (cb_flag & IDWALK_CB_EMBEDDED || *id_pointer == nullptr) {
return IDWALK_RET_NOP;
}
@@ -2422,18 +2435,18 @@ static int lib_link_main_data_restore_cb(LibraryIDLinkCallbackData *cb_data)
}
}
- struct IDNameLib_Map *id_map = cb_data->user_data;
+ IDNameLib_Map *id_map = static_cast<IDNameLib_Map *>(cb_data->user_data);
- /* NOTE: Handling of usercount here is really bad, defining its own system...
+ /* NOTE: Handling of user-count here is really bad, defining its own system...
* Will have to be refactored at some point, but that is not top priority task for now.
* And all user-counts are properly recomputed at the end of the undo management code anyway. */
- *id_pointer = restore_pointer_by_name(
- id_map, *id_pointer, (cb_flag & IDWALK_CB_USER_ONE) ? USER_REAL : USER_IGNORE);
+ *id_pointer = static_cast<ID *>(restore_pointer_by_name(
+ id_map, *id_pointer, (cb_flag & IDWALK_CB_USER_ONE) ? USER_REAL : USER_IGNORE));
return IDWALK_RET_NOP;
}
-static void lib_link_main_data_restore(struct IDNameLib_Map *id_map, Main *newmain)
+static void lib_link_main_data_restore(IDNameLib_Map *id_map, Main *newmain)
{
ID *id;
FOREACH_MAIN_ID_BEGIN (newmain, id) {
@@ -2442,10 +2455,10 @@ static void lib_link_main_data_restore(struct IDNameLib_Map *id_map, Main *newma
FOREACH_MAIN_ID_END;
}
-static void lib_link_wm_xr_data_restore(struct IDNameLib_Map *id_map, wmXrData *xr_data)
+static void lib_link_wm_xr_data_restore(IDNameLib_Map *id_map, wmXrData *xr_data)
{
- xr_data->session_settings.base_pose_object = restore_pointer_by_name(
- id_map, (ID *)xr_data->session_settings.base_pose_object, USER_REAL);
+ xr_data->session_settings.base_pose_object = static_cast<Object *>(restore_pointer_by_name(
+ id_map, (ID *)xr_data->session_settings.base_pose_object, USER_REAL));
}
static void lib_link_window_scene_data_restore(wmWindow *win, Scene *scene, ViewLayer *view_layer)
@@ -2457,25 +2470,26 @@ static void lib_link_window_scene_data_restore(wmWindow *win, Scene *scene, View
if (sl->spacetype == SPACE_VIEW3D) {
View3D *v3d = (View3D *)sl;
- if (v3d->camera == NULL || v3d->scenelock) {
+ if (v3d->camera == nullptr || v3d->scenelock) {
v3d->camera = scene->camera;
}
if (v3d->localvd) {
- Base *base = NULL;
+ Base *base = nullptr;
v3d->localvd->camera = scene->camera;
/* Local-view can become invalid during undo/redo steps,
* so we exit it when no could be found. */
- for (base = view_layer->object_bases.first; base; base = base->next) {
+ for (base = static_cast<Base *>(view_layer->object_bases.first); base;
+ base = base->next) {
if (base->local_view_bits & v3d->local_view_uuid) {
break;
}
}
- if (base == NULL) {
+ if (base == nullptr) {
MEM_freeN(v3d->localvd);
- v3d->localvd = NULL;
+ v3d->localvd = nullptr;
v3d->local_view_uuid = 0;
/* Region-base storage is different depending if the space is active. */
@@ -2483,10 +2497,10 @@ static void lib_link_window_scene_data_restore(wmWindow *win, Scene *scene, View
&sl->regionbase;
LISTBASE_FOREACH (ARegion *, region, regionbase) {
if (region->regiontype == RGN_TYPE_WINDOW) {
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
if (rv3d->localvd) {
MEM_freeN(rv3d->localvd);
- rv3d->localvd = NULL;
+ rv3d->localvd = nullptr;
}
}
}
@@ -2497,7 +2511,18 @@ static void lib_link_window_scene_data_restore(wmWindow *win, Scene *scene, View
}
}
-static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map,
+static void lib_link_restore_viewer_path(IDNameLib_Map *id_map, ViewerPath *viewer_path)
+{
+ LISTBASE_FOREACH (ViewerPathElem *, elem, &viewer_path->path) {
+ if (elem->type == VIEWER_PATH_ELEM_TYPE_ID) {
+ IDViewerPathElem *typed_elem = reinterpret_cast<IDViewerPathElem *>(elem);
+ typed_elem->id = static_cast<ID *>(
+ restore_pointer_by_name(id_map, (ID *)typed_elem->id, USER_IGNORE));
+ }
+ }
+}
+
+static void lib_link_workspace_layout_restore(IDNameLib_Map *id_map,
Main *newmain,
WorkSpaceLayout *layout)
{
@@ -2510,19 +2535,24 @@ static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map,
if (sl->spacetype == SPACE_VIEW3D) {
View3D *v3d = (View3D *)sl;
- v3d->camera = restore_pointer_by_name(id_map, (ID *)v3d->camera, USER_REAL);
- v3d->ob_center = restore_pointer_by_name(id_map, (ID *)v3d->ob_center, USER_REAL);
+ v3d->camera = static_cast<Object *>(
+ restore_pointer_by_name(id_map, (ID *)v3d->camera, USER_REAL));
+ v3d->ob_center = static_cast<Object *>(
+ restore_pointer_by_name(id_map, (ID *)v3d->ob_center, USER_REAL));
+
+ lib_link_restore_viewer_path(id_map, &v3d->viewer_path);
}
else if (sl->spacetype == SPACE_GRAPH) {
SpaceGraph *sipo = (SpaceGraph *)sl;
bDopeSheet *ads = sipo->ads;
if (ads) {
- ads->source = restore_pointer_by_name(id_map, (ID *)ads->source, USER_REAL);
+ ads->source = static_cast<ID *>(
+ restore_pointer_by_name(id_map, (ID *)ads->source, USER_REAL));
if (ads->filter_grp) {
- ads->filter_grp = restore_pointer_by_name(
- id_map, (ID *)ads->filter_grp, USER_IGNORE);
+ ads->filter_grp = static_cast<Collection *>(
+ restore_pointer_by_name(id_map, (ID *)ads->filter_grp, USER_IGNORE));
}
}
@@ -2533,8 +2563,9 @@ static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map,
}
else if (sl->spacetype == SPACE_PROPERTIES) {
SpaceProperties *sbuts = (SpaceProperties *)sl;
- sbuts->pinid = restore_pointer_by_name(id_map, sbuts->pinid, USER_IGNORE);
- if (sbuts->pinid == NULL) {
+ sbuts->pinid = static_cast<ID *>(
+ restore_pointer_by_name(id_map, sbuts->pinid, USER_IGNORE));
+ if (sbuts->pinid == nullptr) {
sbuts->flag &= ~SB_PIN_CONTEXT;
}
@@ -2544,19 +2575,20 @@ static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map,
}
else if (sl->spacetype == SPACE_FILE) {
SpaceFile *sfile = (SpaceFile *)sl;
- sfile->op = NULL;
+ sfile->op = nullptr;
sfile->tags = FILE_TAG_REBUILD_MAIN_FILES;
}
else if (sl->spacetype == SPACE_ACTION) {
SpaceAction *saction = (SpaceAction *)sl;
- saction->action = restore_pointer_by_name(id_map, (ID *)saction->action, USER_REAL);
- saction->ads.source = restore_pointer_by_name(
- id_map, (ID *)saction->ads.source, USER_REAL);
+ saction->action = static_cast<bAction *>(
+ restore_pointer_by_name(id_map, (ID *)saction->action, USER_REAL));
+ saction->ads.source = static_cast<ID *>(
+ restore_pointer_by_name(id_map, (ID *)saction->ads.source, USER_REAL));
if (saction->ads.filter_grp) {
- saction->ads.filter_grp = restore_pointer_by_name(
- id_map, (ID *)saction->ads.filter_grp, USER_IGNORE);
+ saction->ads.filter_grp = static_cast<Collection *>(
+ restore_pointer_by_name(id_map, (ID *)saction->ads.filter_grp, USER_IGNORE));
}
/* force recalc of list of channels, potentially updating the active action
@@ -2567,11 +2599,12 @@ static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map,
else if (sl->spacetype == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)sl;
- sima->image = restore_pointer_by_name(id_map, (ID *)sima->image, USER_REAL);
+ sima->image = static_cast<Image *>(
+ restore_pointer_by_name(id_map, (ID *)sima->image, USER_REAL));
/* this will be freed, not worth attempting to find same scene,
* since it gets initialized later */
- sima->iuser.scene = NULL;
+ sima->iuser.scene = nullptr;
#if 0
/* Those are allocated and freed by space code, no need to handle them here. */
@@ -2585,9 +2618,10 @@ static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map,
/* 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(id_map, (ID *)sima->gpd, USER_REAL);
- sima->mask_info.mask = restore_pointer_by_name(
- id_map, (ID *)sima->mask_info.mask, USER_REAL);
+ sima->gpd = static_cast<bGPdata *>(
+ restore_pointer_by_name(id_map, (ID *)sima->gpd, USER_REAL));
+ sima->mask_info.mask = static_cast<Mask *>(
+ restore_pointer_by_name(id_map, (ID *)sima->mask_info.mask, USER_REAL));
}
else if (sl->spacetype == SPACE_SEQ) {
SpaceSeq *sseq = (SpaceSeq *)sl;
@@ -2595,35 +2629,39 @@ static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map,
/* 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(id_map, (ID *)sseq->gpd, USER_REAL);
+ sseq->gpd = static_cast<bGPdata *>(
+ restore_pointer_by_name(id_map, (ID *)sseq->gpd, USER_REAL));
}
else if (sl->spacetype == SPACE_NLA) {
SpaceNla *snla = (SpaceNla *)sl;
bDopeSheet *ads = snla->ads;
if (ads) {
- ads->source = restore_pointer_by_name(id_map, (ID *)ads->source, USER_REAL);
+ ads->source = static_cast<ID *>(
+ restore_pointer_by_name(id_map, (ID *)ads->source, USER_REAL));
if (ads->filter_grp) {
- ads->filter_grp = restore_pointer_by_name(
- id_map, (ID *)ads->filter_grp, USER_IGNORE);
+ ads->filter_grp = static_cast<Collection *>(
+ restore_pointer_by_name(id_map, (ID *)ads->filter_grp, USER_IGNORE));
}
}
}
else if (sl->spacetype == SPACE_TEXT) {
SpaceText *st = (SpaceText *)sl;
- st->text = restore_pointer_by_name(id_map, (ID *)st->text, USER_IGNORE);
- if (st->text == NULL) {
- st->text = newmain->texts.first;
+ st->text = static_cast<Text *>(
+ restore_pointer_by_name(id_map, (ID *)st->text, USER_IGNORE));
+ if (st->text == nullptr) {
+ st->text = static_cast<Text *>(newmain->texts.first);
}
}
else if (sl->spacetype == SPACE_SCRIPT) {
SpaceScript *scpt = (SpaceScript *)sl;
- scpt->script = restore_pointer_by_name(id_map, (ID *)scpt->script, USER_REAL);
+ scpt->script = static_cast<Script *>(
+ restore_pointer_by_name(id_map, (ID *)scpt->script, USER_REAL));
- // screen->script = NULL; /* 2.45 set to null, better re-run the script. */
+ // screen->script = nullptr; /* 2.45 set to null, better re-run the script. */
if (scpt->script) {
SCRIPT_SET_NULL(scpt->script);
}
@@ -2636,14 +2674,15 @@ static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map,
BLI_mempool_iter iter;
BLI_mempool_iternew(space_outliner->treestore, &iter);
- while ((tselem = BLI_mempool_iterstep(&iter))) {
+ while ((tselem = static_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) {
/* Do not try to restore pointers to drivers/sequence/etc.,
* can crash in undo case! */
if (TSE_IS_REAL_ID(tselem)) {
- tselem->id = restore_pointer_by_name(id_map, tselem->id, USER_IGNORE);
+ tselem->id = static_cast<ID *>(
+ restore_pointer_by_name(id_map, tselem->id, USER_IGNORE));
}
else {
- tselem->id = NULL;
+ tselem->id = nullptr;
}
}
/* rebuild hash table, because it depends on ids too */
@@ -2656,21 +2695,24 @@ static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map,
bNodeTree *ntree;
/* node tree can be stored locally in id too, link this first */
- snode->id = restore_pointer_by_name(id_map, snode->id, USER_REAL);
- snode->from = restore_pointer_by_name(id_map, snode->from, USER_IGNORE);
+ snode->id = static_cast<ID *>(restore_pointer_by_name(id_map, snode->id, USER_REAL));
+ snode->from = static_cast<ID *>(
+ restore_pointer_by_name(id_map, snode->from, USER_IGNORE));
- ntree = snode->id ? ntreeFromID(snode->id) : NULL;
- snode->nodetree = ntree ?
- ntree :
- restore_pointer_by_name(id_map, (ID *)snode->nodetree, USER_REAL);
+ ntree = snode->id ? ntreeFromID(snode->id) : nullptr;
+ snode->nodetree = ntree ? ntree :
+ static_cast<bNodeTree *>(restore_pointer_by_name(
+ id_map, (ID *)snode->nodetree, USER_REAL));
- for (path = snode->treepath.first; path; path = path->next) {
+ for (path = static_cast<bNodeTreePath *>(snode->treepath.first); path;
+ path = path->next) {
if (path == snode->treepath.first) {
/* first nodetree in path is same as snode->nodetree */
path->nodetree = snode->nodetree;
}
else {
- path->nodetree = restore_pointer_by_name(id_map, (ID *)path->nodetree, USER_REAL);
+ path->nodetree = static_cast<bNodeTree *>(
+ restore_pointer_by_name(id_map, (ID *)path->nodetree, USER_REAL));
}
if (!path->nodetree) {
@@ -2689,32 +2731,26 @@ static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map,
/* edittree is just the last in the path,
* set this directly since the path may have been shortened above */
if (snode->treepath.last) {
- path = snode->treepath.last;
+ path = static_cast<bNodeTreePath *>(snode->treepath.last);
snode->edittree = path->nodetree;
}
else {
- snode->edittree = NULL;
+ snode->edittree = nullptr;
}
}
else if (sl->spacetype == SPACE_CLIP) {
SpaceClip *sclip = (SpaceClip *)sl;
- sclip->clip = restore_pointer_by_name(id_map, (ID *)sclip->clip, USER_REAL);
- sclip->mask_info.mask = restore_pointer_by_name(
- id_map, (ID *)sclip->mask_info.mask, USER_REAL);
+ sclip->clip = static_cast<MovieClip *>(
+ restore_pointer_by_name(id_map, (ID *)sclip->clip, USER_REAL));
+ sclip->mask_info.mask = static_cast<Mask *>(
+ restore_pointer_by_name(id_map, (ID *)sclip->mask_info.mask, USER_REAL));
sclip->scopes.ok = 0;
}
else if (sl->spacetype == SPACE_SPREADSHEET) {
SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
-
- LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) {
- if (context->type == SPREADSHEET_CONTEXT_OBJECT) {
- SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context;
- object_context->object = restore_pointer_by_name(
- id_map, (ID *)object_context->object, USER_IGNORE);
- }
- }
+ lib_link_restore_viewer_path(id_map, &sspreadsheet->viewer_path);
}
}
}
@@ -2727,15 +2763,15 @@ void blo_lib_link_restore(Main *oldmain,
Scene *curscene,
ViewLayer *cur_view_layer)
{
- struct IDNameLib_Map *id_map = BKE_main_idmap_create(
- newmain, true, oldmain, MAIN_IDMAP_TYPE_NAME);
+ IDNameLib_Map *id_map = BKE_main_idmap_create(newmain, true, oldmain, MAIN_IDMAP_TYPE_NAME);
LISTBASE_FOREACH (WorkSpace *, workspace, &newmain->workspaces) {
LISTBASE_FOREACH (WorkSpaceLayout *, layout, &workspace->layouts) {
lib_link_workspace_layout_restore(id_map, newmain, layout);
}
- workspace->pin_scene = restore_pointer_by_name(
- id_map, (ID *)workspace->pin_scene, USER_IGNORE);
+ workspace->pin_scene = static_cast<Scene *>(
+ restore_pointer_by_name(id_map, (ID *)workspace->pin_scene, USER_IGNORE));
+ lib_link_restore_viewer_path(id_map, &workspace->viewer_path);
}
LISTBASE_FOREACH (wmWindow *, win, &curwm->windows) {
@@ -2743,14 +2779,16 @@ void blo_lib_link_restore(Main *oldmain,
ID *workspace_id = (ID *)workspace;
Scene *oldscene = win->scene;
- workspace = restore_pointer_by_name(id_map, workspace_id, USER_REAL);
+ workspace = static_cast<WorkSpace *>(restore_pointer_by_name(id_map, workspace_id, USER_REAL));
BKE_workspace_active_set(win->workspace_hook, workspace);
- win->scene = restore_pointer_by_name(id_map, (ID *)win->scene, USER_REAL);
- if (win->scene == NULL) {
+ win->scene = static_cast<Scene *>(
+ restore_pointer_by_name(id_map, (ID *)win->scene, USER_REAL));
+ if (win->scene == nullptr) {
win->scene = curscene;
}
- win->unpinned_scene = restore_pointer_by_name(id_map, (ID *)win->unpinned_scene, USER_IGNORE);
- if (BKE_view_layer_find(win->scene, win->view_layer_name) == NULL) {
+ win->unpinned_scene = static_cast<Scene *>(
+ restore_pointer_by_name(id_map, (ID *)win->unpinned_scene, USER_IGNORE));
+ if (BKE_view_layer_find(win->scene, win->view_layer_name) == nullptr) {
STRNCPY(win->view_layer_name, cur_view_layer->name);
}
BKE_workspace_active_set(win->workspace_hook, workspace);
@@ -2765,7 +2803,7 @@ void blo_lib_link_restore(Main *oldmain,
* potential local view, and needs window's scene pointer to be final... */
lib_link_window_scene_data_restore(win, win->scene, cur_view_layer);
- BLI_assert(win->screen == NULL);
+ BLI_assert(win->screen == nullptr);
}
lib_link_wm_xr_data_restore(id_map, &curwm->xr);
@@ -2795,7 +2833,7 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
Main *newmain;
/* check if the library was already read */
- for (newmain = fd->mainlist->first; newmain; newmain = newmain->next) {
+ for (newmain = static_cast<Main *>(fd->mainlist->first); newmain; newmain = newmain->next) {
if (newmain->curlib) {
if (BLI_path_cmp(newmain->curlib->filepath_abs, lib->filepath_abs) == 0) {
BLO_reportf_wrap(fd->reports,
@@ -2839,12 +2877,12 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
BLI_addtail(fd->mainlist, newmain);
newmain->curlib = lib;
- lib->parent = NULL;
+ lib->parent = nullptr;
id_us_ensure_real(&lib->id);
}
-static void lib_link_library(BlendLibReader *UNUSED(reader), Library *UNUSED(lib))
+static void lib_link_library(BlendLibReader * /*reader*/, Library * /*lib*/)
{
}
@@ -2853,7 +2891,7 @@ static void lib_link_library(BlendLibReader *UNUSED(reader), Library *UNUSED(lib
static void fix_relpaths_library(const char *basepath, Main *main)
{
/* #BLO_read_from_memory uses a blank file-path. */
- if (basepath == NULL || basepath[0] == '\0') {
+ if (basepath == nullptr || basepath[0] == '\0') {
LISTBASE_FOREACH (Library *, lib, &main->libraries) {
/* when loading a linked lib into a file which has not been saved,
* there is nothing we can be relative to, so instead we need to make
@@ -2868,7 +2906,7 @@ static void fix_relpaths_library(const char *basepath, Main *main)
else {
LISTBASE_FOREACH (Library *, lib, &main->libraries) {
/* Libraries store both relative and abs paths, recreate relative paths,
- * relative to the blend file since indirectly linked libs will be
+ * relative to the blend file since indirectly linked libraries will be
* relative to their direct linked library. */
if (BLI_path_is_rel(lib->filepath)) { /* if this is relative to begin with? */
BLI_strncpy(lib->filepath, lib->filepath_abs, sizeof(lib->filepath));
@@ -2887,7 +2925,7 @@ static void fix_relpaths_library(const char *basepath, Main *main)
static ID *create_placeholder(Main *mainvar, const short idcode, const char *idname, const int tag)
{
ListBase *lb = which_libbase(mainvar, idcode);
- ID *ph_id = BKE_libblock_alloc_notest(idcode);
+ ID *ph_id = static_cast<ID *>(BKE_libblock_alloc_notest(idcode));
*((short *)ph_id->name) = idcode;
BLI_strncpy(ph_id->name + 2, idname, sizeof(ph_id->name) - 2);
@@ -2898,9 +2936,9 @@ static ID *create_placeholder(Main *mainvar, const short idcode, const char *idn
ph_id->icon_id = 0;
BLI_addtail(lb, ph_id);
- id_sort_by_name(lb, ph_id, NULL);
+ id_sort_by_name(lb, ph_id, nullptr);
- if (mainvar->id_map != NULL) {
+ if (mainvar->id_map != nullptr) {
BKE_main_idmap_insert_id(mainvar->id_map, ph_id);
}
@@ -2916,8 +2954,8 @@ static void placeholders_ensure_valid(Main *bmain)
/* Placeholder ObData IDs won't have any material, we have to update their objects for that,
* otherwise the inconsistency between both will lead to crashes (especially in Eevee?). */
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
- ID *obdata = ob->data;
- if (obdata != NULL && obdata->tag & LIB_TAG_MISSING) {
+ ID *obdata = static_cast<ID *>(ob->data);
+ if (obdata != nullptr && obdata->tag & LIB_TAG_MISSING) {
BKE_object_materials_test(bmain, ob, obdata);
}
}
@@ -3024,7 +3062,7 @@ static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID *
}
const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
- if (id_type->blend_read_data != NULL) {
+ if (id_type->blend_read_data != nullptr) {
id_type->blend_read_data(&reader, id);
}
@@ -3045,7 +3083,7 @@ static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID *
}
/* try to restore (when undoing) or clear ID's cache pointers. */
- if (id_type->foreach_cache != NULL) {
+ if (id_type->foreach_cache != nullptr) {
BKE_idtype_id_foreach_cache(
id, blo_cache_storage_entry_restore_in_new, reader.fd->cache_storage);
}
@@ -3115,7 +3153,7 @@ static bool read_libblock_is_identical(FileData *fd, BHead *bhead)
/* For undo, restore matching library datablock from the old main. */
static bool read_libblock_undo_restore_library(FileData *fd, Main *main, const ID *id)
{
- /* In undo case, most libs and linked data should be kept as is from previous state
+ /* In undo case, most libraries and linked data should be kept as is from previous state
* (see BLO_read_from_memfile).
* However, some needed by the snapshot being read may have been removed in previous one,
* and would go missing.
@@ -3125,15 +3163,15 @@ static bool read_libblock_undo_restore_library(FileData *fd, Main *main, const I
* otherwise we have to do a full read of that bhead... */
CLOG_INFO(&LOG_UNDO, 2, "UNDO: restore library %s", id->name);
- Main *libmain = fd->old_mainlist->first;
+ Main *libmain = static_cast<Main *>(fd->old_mainlist->first);
/* Skip oldmain itself... */
for (libmain = libmain->next; libmain; libmain = libmain->next) {
if (libmain->curlib && STREQ(id->name, libmain->curlib->id.name)) {
- Main *oldmain = fd->old_mainlist->first;
+ Main *oldmain = static_cast<Main *>(fd->old_mainlist->first);
CLOG_INFO(&LOG_UNDO,
2,
" compare with %s -> match",
- libmain->curlib ? libmain->curlib->id.name : "<NULL>");
+ libmain->curlib ? libmain->curlib->id.name : "<nullptr>");
/* In case of a library, we need to re-add its main to fd->mainlist,
* because if we have later a missing ID_LINK_PLACEHOLDER,
* we need to get the correct lib it is linked to!
@@ -3148,7 +3186,7 @@ static bool read_libblock_undo_restore_library(FileData *fd, Main *main, const I
CLOG_INFO(&LOG_UNDO,
2,
" compare with %s -> NO match",
- libmain->curlib ? libmain->curlib->id.name : "<NULL>");
+ libmain->curlib ? libmain->curlib->id.name : "<nullptr>");
}
return false;
@@ -3160,12 +3198,12 @@ static bool read_libblock_undo_restore_linked(FileData *fd, Main *main, const ID
CLOG_INFO(&LOG_UNDO, 2, "UNDO: restore linked datablock %s", id->name);
ID *id_old = BKE_libblock_find_name(main, GS(id->name), id->name + 2);
- if (id_old != NULL) {
+ if (id_old != nullptr) {
CLOG_INFO(&LOG_UNDO,
2,
" from %s (%s): found",
- main->curlib ? main->curlib->id.name : "<NULL>",
- main->curlib ? main->curlib->filepath : "<NULL>");
+ main->curlib ? main->curlib->id.name : "<nullptr>",
+ main->curlib ? main->curlib->filepath : "<nullptr>");
/* Even though we found our linked ID, there is no guarantee its address
* is still the same. */
if (id_old != bhead->old) {
@@ -3180,17 +3218,17 @@ static bool read_libblock_undo_restore_linked(FileData *fd, Main *main, const ID
CLOG_INFO(&LOG_UNDO,
2,
" from %s (%s): NOT found",
- main->curlib ? main->curlib->id.name : "<NULL>",
- main->curlib ? main->curlib->filepath : "<NULL>");
+ main->curlib ? main->curlib->id.name : "<nullptr>",
+ main->curlib ? main->curlib->filepath : "<nullptr>");
return false;
}
/* For undo, restore unchanged datablock from old main. */
static void read_libblock_undo_restore_identical(
- FileData *fd, Main *main, const ID *UNUSED(id), ID *id_old, const int tag)
+ FileData *fd, Main *main, const ID * /*id*/, ID *id_old, const int tag)
{
BLI_assert((fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0);
- BLI_assert(id_old != NULL);
+ BLI_assert(id_old != nullptr);
/* Some tags need to be preserved here. */
id_old->tag = tag | (id_old->tag & LIB_TAG_EXTRAUSER);
@@ -3198,11 +3236,11 @@ static void read_libblock_undo_restore_identical(
id_old->us = ID_FAKE_USERS(id_old);
/* Do not reset id->icon_id here, memory allocated for it remains valid. */
/* Needed because .blend may have been saved with crap value here... */
- id_old->newid = NULL;
- id_old->orig_id = NULL;
+ id_old->newid = nullptr;
+ id_old->orig_id = nullptr;
const short idcode = GS(id_old->name);
- Main *old_bmain = fd->old_mainlist->first;
+ Main *old_bmain = static_cast<Main *>(fd->old_mainlist->first);
ListBase *old_lb = which_libbase(old_bmain, idcode);
ListBase *new_lb = which_libbase(main, idcode);
BLI_remlink(old_lb, id_old);
@@ -3229,11 +3267,11 @@ static void read_libblock_undo_restore_at_old_address(FileData *fd, Main *main,
* helps reducing further detected changes by the depsgraph (since unchanged IDs remain fully
* unchanged, even if they are using/pointing to a changed one). */
BLI_assert((fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0);
- BLI_assert(id_old != NULL);
+ BLI_assert(id_old != nullptr);
const short idcode = GS(id->name);
- Main *old_bmain = fd->old_mainlist->first;
+ Main *old_bmain = static_cast<Main *>(fd->old_mainlist->first);
ListBase *old_lb = which_libbase(old_bmain, idcode);
ListBase *new_lb = which_libbase(main, idcode);
BLI_remlink(old_lb, id_old);
@@ -3241,8 +3279,8 @@ static void read_libblock_undo_restore_at_old_address(FileData *fd, Main *main,
/* We do not need any remapping from this call here, since no ID pointer is valid in the data
* currently (they are all pointing to old addresses, and need to go through `lib_link`
- * process). So we can pass NULL for the Main pointer parameter. */
- BKE_lib_id_swap_full(NULL, id, id_old);
+ * process). So we can pass nullptr for the Main pointer parameter. */
+ BKE_lib_id_swap_full(nullptr, id, id_old);
/* Special temporary usage of this pointer, necessary for the `undo_preserve` call after
* lib-linking to restore some data that should never be affected by undo, e.g. the 3D cursor of
@@ -3257,7 +3295,7 @@ static bool read_libblock_undo_restore(
FileData *fd, Main *main, BHead *bhead, const int tag, ID **r_id_old)
{
/* Get pointer to memory of new ID that we will be reading. */
- const ID *id = peek_struct_undo(fd, bhead);
+ const ID *id = static_cast<const ID *>(peek_struct_undo(fd, bhead));
const short idcode = GS(id->name);
if (bhead->code == ID_LI) {
@@ -3280,19 +3318,19 @@ static bool read_libblock_undo_restore(
}
/* Restore local datablocks. */
- ID *id_old = NULL;
+ ID *id_old = nullptr;
const bool do_partial_undo = (fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0;
if (do_partial_undo && (bhead->code != ID_LINK_PLACEHOLDER)) {
/* This code should only ever be reached for local data-blocks. */
- BLI_assert(main->curlib == NULL);
+ BLI_assert(main->curlib == nullptr);
/* Find the 'current' existing ID we want to reuse instead of the one we
* would read from the undo memfile. */
- BLI_assert(fd->old_idmap != NULL);
+ BLI_assert(fd->old_idmap != nullptr);
id_old = BKE_main_idmap_lookup_uuid(fd->old_idmap, id->session_uuid);
}
- if (id_old != NULL && read_libblock_is_identical(fd, bhead)) {
+ if (id_old != nullptr && read_libblock_is_identical(fd, bhead)) {
/* Local datablock was unchanged, restore from the old main. */
CLOG_INFO(&LOG_UNDO,
2,
@@ -3316,7 +3354,7 @@ static bool read_libblock_undo_restore(
*r_id_old = id_old;
return true;
}
- if (id_old != NULL) {
+ if (id_old != nullptr) {
/* Local datablock was changed. Restore at the address of the old datablock. */
CLOG_INFO(&LOG_UNDO,
2,
@@ -3350,13 +3388,13 @@ static BHead *read_libblock(FileData *fd,
/* First attempt to restore existing datablocks for undo.
* When datablocks are changed but still exist, we restore them at the old
* address and inherit recalc flags for the dependency graph. */
- ID *id_old = NULL;
+ ID *id_old = nullptr;
if (fd->flags & FD_FLAGS_IS_MEMFILE) {
if (read_libblock_undo_restore(fd, main, bhead, tag, &id_old)) {
if (r_id) {
*r_id = id_old;
}
- if (main->id_map != NULL) {
+ if (main->id_map != nullptr) {
BKE_main_idmap_insert_id(main->id_map, id_old);
}
@@ -3365,10 +3403,10 @@ static BHead *read_libblock(FileData *fd,
}
/* Read libblock struct. */
- ID *id = read_struct(fd, bhead, "lib block");
- if (id == NULL) {
+ ID *id = static_cast<ID *>(read_struct(fd, bhead, "lib block"));
+ if (id == nullptr) {
if (r_id) {
- *r_id = NULL;
+ *r_id = nullptr;
}
return blo_bhead_next(fd, bhead);
}
@@ -3376,12 +3414,12 @@ static BHead *read_libblock(FileData *fd,
/* Determine ID type and add to main database list. */
const short idcode = GS(id->name);
ListBase *lb = which_libbase(main, idcode);
- if (lb == NULL) {
+ if (lb == nullptr) {
/* Unknown ID type. */
CLOG_WARN(&LOG, "Unknown id code '%c%c'", (idcode & 0xff), (idcode >> 8));
MEM_freeN(id);
if (r_id) {
- *r_id = NULL;
+ *r_id = nullptr;
}
return blo_bhead_next(fd, bhead);
}
@@ -3419,7 +3457,7 @@ static BHead *read_libblock(FileData *fd,
direct_link_id(fd, main, id_tag, id, id_old);
- if (main->id_map != NULL) {
+ if (main->id_map != nullptr) {
BKE_main_idmap_insert_id(main->id_map, id);
}
@@ -3439,19 +3477,19 @@ static BHead *read_libblock(FileData *fd,
* been added to the fd->libmap mapping, which in theory could lead to nice crashes...
* This should be properly solved at some point. */
BKE_id_free(main, id);
- if (r_id != NULL) {
- *r_id = NULL;
+ if (r_id != nullptr) {
+ *r_id = nullptr;
}
}
else if (id_old) {
/* For undo, store contents read into id at id_old. */
read_libblock_undo_restore_at_old_address(fd, main, id, id_old);
- if (main->id_map != NULL) {
+ if (main->id_map != nullptr) {
BKE_main_idmap_insert_id(main->id_map, id_old);
}
}
- else if (main->id_map != NULL) {
+ else if (main->id_map != nullptr) {
BKE_main_idmap_insert_id(main->id_map, id);
}
@@ -3489,7 +3527,7 @@ BHead *blo_read_asset_data_block(FileData *fd, BHead *bhead, AssetMetaData **r_a
/* also version info is written here */
static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
{
- FileGlobal *fg = read_struct(fd, bhead, "Global");
+ FileGlobal *fg = static_cast<FileGlobal *>(read_struct(fd, bhead, "Global"));
/* copy to bfd handle */
bfd->main->subversionfile = fg->subversion;
@@ -3536,11 +3574,12 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
/* NOTE: this has to be kept for reading older files... */
static void link_global(FileData *fd, BlendFileData *bfd)
{
- bfd->cur_view_layer = blo_read_get_new_globaldata_address(fd, bfd->cur_view_layer);
- bfd->curscreen = newlibadr(fd, NULL, bfd->curscreen);
- bfd->curscene = newlibadr(fd, NULL, bfd->curscene);
+ bfd->cur_view_layer = static_cast<ViewLayer *>(
+ blo_read_get_new_globaldata_address(fd, bfd->cur_view_layer));
+ bfd->curscreen = static_cast<bScreen *>(newlibadr(fd, nullptr, bfd->curscreen));
+ bfd->curscene = static_cast<Scene *>(newlibadr(fd, nullptr, bfd->curscene));
/* this happens in files older than 2.35 */
- if (bfd->curscene == NULL) {
+ if (bfd->curscene == nullptr) {
if (bfd->curscreen) {
bfd->curscene = bfd->curscreen->scene;
}
@@ -3553,11 +3592,11 @@ static void link_global(FileData *fd, BlendFileData *bfd)
/** \name Versioning
* \{ */
-static void do_versions_userdef(FileData *UNUSED(fd), BlendFileData *bfd)
+static void do_versions_userdef(FileData * /*fd*/, BlendFileData *bfd)
{
UserDef *user = bfd->user;
- if (user == NULL) {
+ if (user == nullptr) {
return;
}
@@ -3574,7 +3613,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
if (G.debug & G_DEBUG) {
char build_commit_datetime[32];
time_t temp_time = main->build_commit_timestamp;
- struct tm *tm = (temp_time) ? gmtime(&temp_time) : NULL;
+ struct tm *tm = (temp_time) ? gmtime(&temp_time) : nullptr;
if (LIKELY(tm)) {
strftime(build_commit_datetime, sizeof(build_commit_datetime), "%Y-%m-%d %H:%M", tm);
}
@@ -3599,6 +3638,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
blo_do_versions_280(fd, lib, main);
blo_do_versions_290(fd, lib, main);
blo_do_versions_300(fd, lib, main);
+ blo_do_versions_400(fd, lib, main);
blo_do_versions_cycles(fd, lib, main);
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
@@ -3669,7 +3709,7 @@ static void lib_link_all(FileData *fd, Main *bmain)
lib_link_id(&reader, id);
const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
- if (id_type->blend_read_lib != NULL) {
+ if (id_type->blend_read_lib != nullptr) {
id_type->blend_read_lib(&reader, id);
}
@@ -3681,7 +3721,7 @@ static void lib_link_all(FileData *fd, Main *bmain)
/* Some data that should be persistent, like the 3DCursor or the tool settings, are
* stored in IDs affected by undo, like Scene. So this requires some specific handling. */
- if (id_type->blend_read_undo_preserve != NULL && id->orig_id != NULL) {
+ if (id_type->blend_read_undo_preserve != nullptr && id->orig_id != nullptr) {
id_type->blend_read_undo_preserve(&reader, id, id->orig_id);
}
}
@@ -3689,7 +3729,7 @@ static void lib_link_all(FileData *fd, Main *bmain)
/* Cleanup `ID.orig_id`, this is now reserved for depsgraph/COW usage only. */
FOREACH_MAIN_ID_BEGIN (bmain, id) {
- id->orig_id = NULL;
+ id->orig_id = nullptr;
}
FOREACH_MAIN_ID_END;
@@ -3711,14 +3751,14 @@ static void lib_link_all(FileData *fd, Main *bmain)
static void after_liblink_merged_bmain_process(Main *bmain)
{
/* We only expect a merged Main here, not a split one. */
- BLI_assert((bmain->prev == NULL) && (bmain->next == NULL));
+ BLI_assert((bmain->prev == nullptr) && (bmain->next == nullptr));
/* Check for possible cycles in scenes' 'set' background property. */
lib_link_scenes_check_set(bmain);
/* We could integrate that to mesh/curve/lattice lib_link, but this is really cheap process,
* so simpler to just use it directly in this single call. */
- BLO_main_validate_shapekeys(bmain, NULL);
+ BLO_main_validate_shapekeys(bmain, nullptr);
/* We have to rebuild that runtime information *after* all data-blocks have been properly linked.
*/
@@ -3735,14 +3775,14 @@ static void direct_link_keymapitem(BlendDataReader *reader, wmKeyMapItem *kmi)
{
BLO_read_data_address(reader, &kmi->properties);
IDP_BlendDataRead(reader, &kmi->properties);
- kmi->ptr = NULL;
+ kmi->ptr = nullptr;
kmi->flag &= ~KMI_UPDATE;
}
static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
{
UserDef *user;
- bfd->user = user = read_struct(fd, bhead, "user def");
+ bfd->user = user = static_cast<UserDef *>(read_struct(fd, bhead, "user def"));
/* User struct has separate do-version handling */
user->versionfile = bfd->main->versionfile;
@@ -3763,8 +3803,8 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
BLO_read_list(reader, &user->asset_libraries);
LISTBASE_FOREACH (wmKeyMap *, keymap, &user->user_keymaps) {
- keymap->modal_items = NULL;
- keymap->poll = NULL;
+ keymap->modal_items = nullptr;
+ keymap->poll = nullptr;
keymap->flag &= ~KEYMAP_UPDATE;
BLO_read_list(reader, &keymap->diff_items);
@@ -3809,7 +3849,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
}
/* XXX */
- user->uifonts.first = user->uifonts.last = NULL;
+ user->uifonts.first = user->uifonts.last = nullptr;
BLO_read_list(reader, &user->uistyles);
@@ -3836,13 +3876,13 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
{
BHead *bhead = blo_bhead_first(fd);
BlendFileData *bfd;
- ListBase mainlist = {NULL, NULL};
+ ListBase mainlist = {nullptr, nullptr};
if (fd->flags & FD_FLAGS_IS_MEMFILE) {
CLOG_INFO(&LOG_UNDO, 2, "UNDO: read step");
}
- bfd = MEM_callocN(sizeof(BlendFileData), "blendfiledata");
+ bfd = static_cast<BlendFileData *>(MEM_callocN(sizeof(BlendFileData), "blendfiledata"));
bfd->main = BKE_main_new();
bfd->main->versionfile = fd->fileversion;
@@ -3866,7 +3906,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
const int height = data[1];
if (BLEN_THUMB_MEMSIZE_IS_VALID(width, height)) {
const size_t data_size = BLEN_THUMB_MEMSIZE(width, height);
- bfd->main->blen_thumb = MEM_mallocN(data_size, __func__);
+ bfd->main->blen_thumb = static_cast<BlendThumbnail *>(MEM_mallocN(data_size, __func__));
BLI_assert((data_size - sizeof(*bfd->main->blen_thumb)) ==
(BLEN_THUMB_MEMSIZE_FILE(width, height) - (sizeof(*data) * 2)));
@@ -3897,7 +3937,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
}
break;
case ENDB:
- bhead = NULL;
+ bhead = nullptr;
break;
case ID_LINK_PLACEHOLDER:
@@ -3909,8 +3949,8 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
* The library is the most recently loaded ID_LI block, according
* to the file format definition. So we can use the entry at the
* end of mainlist, added in direct_link_library. */
- Main *libmain = mainlist.last;
- bhead = read_libblock(fd, libmain, bhead, 0, true, NULL);
+ Main *libmain = static_cast<Main *>(mainlist.last);
+ bhead = read_libblock(fd, libmain, bhead, 0, true, nullptr);
}
break;
/* in 2.50+ files, the file identifier for screens is patched, forward compatibility */
@@ -3923,7 +3963,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
bhead = blo_bhead_next(fd, bhead);
}
else {
- bhead = read_libblock(fd, bfd->main, bhead, LIB_TAG_LOCAL, false, NULL);
+ bhead = read_libblock(fd, bfd->main, bhead, LIB_TAG_LOCAL, false, nullptr);
}
}
}
@@ -3931,7 +3971,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
/* do before read_libraries, but skip undo case */
if ((fd->flags & FD_FLAGS_IS_MEMFILE) == 0) {
if ((fd->skip_flags & BLO_READ_SKIP_DATA) == 0) {
- do_versions(fd, NULL, bfd->main);
+ do_versions(fd, nullptr, bfd->main);
}
if ((fd->skip_flags & BLO_READ_SKIP_USERDEF) == 0) {
@@ -4005,9 +4045,9 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
link_global(fd, bfd); /* as last */
}
- fd->mainlist = NULL; /* Safety, this is local variable, shall not be used afterward. */
+ fd->mainlist = nullptr; /* Safety, this is local variable, shall not be used afterward. */
- BLI_assert(bfd->main->id_map == NULL);
+ BLI_assert(bfd->main->id_map == nullptr);
return bfd;
}
@@ -4027,7 +4067,8 @@ struct BHeadSort {
static int verg_bheadsort(const void *v1, const void *v2)
{
- const struct BHeadSort *x1 = v1, *x2 = v2;
+ const BHeadSort *x1 = static_cast<const BHeadSort *>(v1),
+ *x2 = static_cast<const BHeadSort *>(v2);
if (x1->old > x2->old) {
return 1;
@@ -4041,7 +4082,7 @@ static int verg_bheadsort(const void *v1, const void *v2)
static void sort_bhead_old_map(FileData *fd)
{
BHead *bhead;
- struct BHeadSort *bhs;
+ BHeadSort *bhs;
int tot = 0;
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
@@ -4053,21 +4094,22 @@ static void sort_bhead_old_map(FileData *fd)
return;
}
- bhs = fd->bheadmap = MEM_malloc_arrayN(tot, sizeof(struct BHeadSort), "BHeadSort");
+ bhs = fd->bheadmap = static_cast<BHeadSort *>(
+ MEM_malloc_arrayN(tot, sizeof(BHeadSort), "BHeadSort"));
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead), bhs++) {
bhs->bhead = bhead;
bhs->old = bhead->old;
}
- qsort(fd->bheadmap, tot, sizeof(struct BHeadSort), verg_bheadsort);
+ qsort(fd->bheadmap, tot, sizeof(BHeadSort), verg_bheadsort);
}
static BHead *find_previous_lib(FileData *fd, BHead *bhead)
{
/* Skip library data-blocks in undo, see comment in read_libblock. */
if (fd->flags & FD_FLAGS_IS_MEMFILE) {
- return NULL;
+ return nullptr;
}
for (; bhead; bhead = blo_bhead_prev(fd, bhead)) {
@@ -4084,18 +4126,19 @@ static BHead *find_bhead(FileData *fd, void *old)
#if 0
BHead* bhead;
#endif
- struct BHeadSort *bhs, bhs_s;
+ BHeadSort *bhs, bhs_s;
if (!old) {
- return NULL;
+ return nullptr;
}
- if (fd->bheadmap == NULL) {
+ if (fd->bheadmap == nullptr) {
sort_bhead_old_map(fd);
}
bhs_s.old = old;
- bhs = bsearch(&bhs_s, fd->bheadmap, fd->tot_bheadmap, sizeof(struct BHeadSort), verg_bheadsort);
+ bhs = static_cast<BHeadSort *>(
+ bsearch(&bhs_s, fd->bheadmap, fd->tot_bheadmap, sizeof(BHeadSort), verg_bheadsort));
if (bhs) {
return bhs->bhead;
@@ -4109,7 +4152,7 @@ static BHead *find_bhead(FileData *fd, void *old)
}
#endif
- return NULL;
+ return nullptr;
}
static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name)
@@ -4121,7 +4164,7 @@ static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const
*((short *)idname_full) = idcode;
BLI_strncpy(idname_full + 2, name, sizeof(idname_full) - 2);
- return BLI_ghash_lookup(fd->bhead_idname_hash, idname_full);
+ return static_cast<BHead *>(BLI_ghash_lookup(fd->bhead_idname_hash, idname_full));
#else
BHead *bhead;
@@ -4138,14 +4181,14 @@ static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const
}
}
- return NULL;
+ return nullptr;
#endif
}
static BHead *find_bhead_from_idname(FileData *fd, const char *idname)
{
#ifdef USE_GHASH_BHEAD
- return BLI_ghash_lookup(fd->bhead_idname_hash, idname);
+ return static_cast<BHead *>(BLI_ghash_lookup(fd->bhead_idname_hash, idname));
#else
return find_bhead_from_code_name(fd, GS(idname), idname + 2);
#endif
@@ -4153,8 +4196,8 @@ static BHead *find_bhead_from_idname(FileData *fd, const char *idname)
static ID *is_yet_read(FileData *fd, Main *mainvar, BHead *bhead)
{
- if (mainvar->id_map == NULL) {
- mainvar->id_map = BKE_main_idmap_create(mainvar, false, NULL, MAIN_IDMAP_TYPE_NAME);
+ if (mainvar->id_map == nullptr) {
+ mainvar->id_map = BKE_main_idmap_create(mainvar, false, nullptr, MAIN_IDMAP_TYPE_NAME);
}
BLI_assert(BKE_main_idmap_main_get(mainvar->id_map) == mainvar);
@@ -4173,24 +4216,24 @@ static ID *is_yet_read(FileData *fd, Main *mainvar, BHead *bhead)
static void expand_doit_library(void *fdhandle, Main *mainvar, void *old)
{
- FileData *fd = fdhandle;
+ FileData *fd = static_cast<FileData *>(fdhandle);
BHead *bhead = find_bhead(fd, old);
- if (bhead == NULL) {
+ if (bhead == nullptr) {
return;
}
if (bhead->code == ID_LINK_PLACEHOLDER) {
/* Placeholder link to data-block in another library. */
BHead *bheadlib = find_previous_lib(fd, bhead);
- if (bheadlib == NULL) {
+ if (bheadlib == nullptr) {
return;
}
- Library *lib = read_struct(fd, bheadlib, "Library");
+ Library *lib = static_cast<Library *>(read_struct(fd, bheadlib, "Library"));
Main *libmain = blo_find_main(fd, lib->filepath, fd->relabase);
- if (libmain->curlib == NULL) {
+ if (libmain->curlib == nullptr) {
const char *idname = blo_bhead_id_name(fd, bhead);
BLO_reportf_wrap(fd->reports,
@@ -4203,12 +4246,12 @@ static void expand_doit_library(void *fdhandle, Main *mainvar, void *old)
ID *id = is_yet_read(fd, libmain, bhead);
- if (id == NULL) {
+ if (id == nullptr) {
/* ID has not been read yet, add placeholder to the main of the
* library it belongs to, so that it will be read later. */
read_libblock(fd, libmain, bhead, fd->id_tag_extra | LIB_TAG_INDIRECT, false, &id);
- BLI_assert(id != NULL);
- id_sort_by_name(which_libbase(libmain, GS(id->name)), id, id->prev);
+ BLI_assert(id != nullptr);
+ id_sort_by_name(which_libbase(libmain, GS(id->name)), id, static_cast<ID *>(id->prev));
/* commented because this can print way too much */
// if (G.debug & G_DEBUG) printf("expand_doit: other lib %s\n", lib->filepath);
@@ -4263,15 +4306,15 @@ static void expand_doit_library(void *fdhandle, Main *mainvar, void *old)
}
ID *id = is_yet_read(fd, mainvar, bhead);
- if (id == NULL) {
+ if (id == nullptr) {
read_libblock(fd,
mainvar,
bhead,
fd->id_tag_extra | LIB_TAG_NEED_EXPAND | LIB_TAG_INDIRECT,
false,
&id);
- BLI_assert(id != NULL);
- id_sort_by_name(which_libbase(mainvar, GS(id->name)), id, id->prev);
+ BLI_assert(id != nullptr);
+ id_sort_by_name(which_libbase(mainvar, GS(id->name)), id, static_cast<ID *>(id->prev));
}
else {
/* Convert any previously read weak link to regular link
@@ -4298,14 +4341,14 @@ static void expand_id_embedded_id(BlendExpander *expander, ID *id)
{
/* Handle 'private IDs'. */
bNodeTree *nodetree = ntreeFromID(id);
- if (nodetree != NULL) {
+ if (nodetree != nullptr) {
expand_id(expander, &nodetree->id);
ntreeBlendReadExpand(expander, nodetree);
}
if (GS(id->name) == ID_SCE) {
Scene *scene = (Scene *)id;
- if (scene->master_collection != NULL) {
+ if (scene->master_collection != nullptr) {
expand_id(expander, &scene->master_collection->id);
BKE_collection_blend_read_expand(expander, scene->master_collection);
}
@@ -4322,7 +4365,7 @@ static void expand_id(BlendExpander *expander, ID *id)
}
AnimData *adt = BKE_animdata_from_id(id);
- if (adt != NULL) {
+ if (adt != nullptr) {
BKE_animdata_blend_read_expand(expander, adt);
}
@@ -4337,7 +4380,7 @@ void BLO_main_expander(BLOExpandDoitCallback expand_doit_func)
void BLO_expand_main(void *fdhandle, Main *mainvar)
{
ListBase *lbarray[INDEX_ID_MAX];
- FileData *fd = fdhandle;
+ FileData *fd = static_cast<FileData *>(fdhandle);
ID *id;
int a;
bool do_it = true;
@@ -4349,20 +4392,20 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
a = set_listbasepointers(mainvar, lbarray);
while (a--) {
- id = lbarray[a]->first;
+ id = static_cast<ID *>(lbarray[a]->first);
while (id) {
if (id->tag & LIB_TAG_NEED_EXPAND) {
expand_id(&expander, id);
const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
- if (id_type->blend_read_expand != NULL) {
+ if (id_type->blend_read_expand != nullptr) {
id_type->blend_read_expand(&expander, id);
}
do_it = true;
id->tag &= ~LIB_TAG_NEED_EXPAND;
}
- id = id->next;
+ id = static_cast<ID *>(id->next);
}
}
}
@@ -4389,7 +4432,7 @@ static ID *link_named_part(
if (bhead) {
id = is_yet_read(fd, mainl, bhead);
- if (id == NULL) {
+ if (id == nullptr) {
/* not read yet */
const int tag = ((force_indirect ? LIB_TAG_INDIRECT : LIB_TAG_EXTERN) | fd->id_tag_extra);
read_libblock(fd, mainl, bhead, tag | LIB_TAG_NEED_EXPAND, false, &id);
@@ -4397,7 +4440,7 @@ static ID *link_named_part(
if (id) {
/* sort by name in list */
ListBase *lb = which_libbase(mainl, idcode);
- id_sort_by_name(lb, id, NULL);
+ id_sort_by_name(lb, id, nullptr);
}
}
else {
@@ -4417,11 +4460,11 @@ static ID *link_named_part(
mainl, idcode, name, force_indirect ? LIB_TAG_INDIRECT : LIB_TAG_EXTERN);
}
else {
- id = NULL;
+ id = nullptr;
}
- /* if we found the id but the id is NULL, this is really bad */
- BLI_assert(!((bhead != NULL) && (id == NULL)));
+ /* if we found the id but the id is nullptr, this is really bad */
+ BLI_assert(!((bhead != nullptr) && (id == nullptr)));
return id;
}
@@ -4430,7 +4473,7 @@ ID *BLO_library_link_named_part(Main *mainl,
BlendHandle **bh,
const short idcode,
const char *name,
- const struct LibraryLink_Params *params)
+ const LibraryLink_Params *params)
{
FileData *fd = (FileData *)(*bh);
return link_named_part(mainl, fd, idcode, name, params->flag);
@@ -4452,7 +4495,7 @@ static Main *library_link_begin(Main *mainvar,
(*fd)->id_tag_extra = id_tag_extra;
- (*fd)->mainlist = MEM_callocN(sizeof(ListBase), "FileData.mainlist");
+ (*fd)->mainlist = static_cast<ListBase *>(MEM_callocN(sizeof(ListBase), "FileData.mainlist"));
/* make mains */
blo_split_main((*fd)->mainlist, mainvar);
@@ -4470,8 +4513,8 @@ static Main *library_link_begin(Main *mainvar,
return mainl;
}
-void BLO_library_link_params_init(struct LibraryLink_Params *params,
- struct Main *bmain,
+void BLO_library_link_params_init(LibraryLink_Params *params,
+ Main *bmain,
const int flag,
const int id_tag_extra)
{
@@ -4481,17 +4524,17 @@ void BLO_library_link_params_init(struct LibraryLink_Params *params,
params->id_tag_extra = id_tag_extra;
}
-void BLO_library_link_params_init_with_context(struct LibraryLink_Params *params,
- struct Main *bmain,
+void BLO_library_link_params_init_with_context(LibraryLink_Params *params,
+ Main *bmain,
const int flag,
const int id_tag_extra,
/* Context arguments. */
- struct Scene *scene,
- struct ViewLayer *view_layer,
- const struct View3D *v3d)
+ Scene *scene,
+ ViewLayer *view_layer,
+ const View3D *v3d)
{
BLO_library_link_params_init(params, bmain, flag, id_tag_extra);
- if (scene != NULL) {
+ if (scene != nullptr) {
params->context.scene = scene;
params->context.view_layer = view_layer;
params->context.v3d = v3d;
@@ -4500,7 +4543,7 @@ void BLO_library_link_params_init_with_context(struct LibraryLink_Params *params
Main *BLO_library_link_begin(BlendHandle **bh,
const char *filepath,
- const struct LibraryLink_Params *params)
+ const LibraryLink_Params *params)
{
FileData *fd = (FileData *)(*bh);
return library_link_begin(params->bmain, &fd, filepath, params->id_tag_extra);
@@ -4535,8 +4578,8 @@ static void library_link_end(Main *mainl, FileData **fd, const int flag)
Main *mainvar;
Library *curlib;
- if (mainl->id_map == NULL) {
- mainl->id_map = BKE_main_idmap_create(mainl, false, NULL, MAIN_IDMAP_TYPE_NAME);
+ if (mainl->id_map == nullptr) {
+ mainl->id_map = BKE_main_idmap_create(mainl, false, nullptr, MAIN_IDMAP_TYPE_NAME);
}
/* expander now is callback function */
@@ -4545,7 +4588,7 @@ static void library_link_end(Main *mainl, FileData **fd, const int flag)
/* make main consistent */
BLO_expand_main(*fd, mainl);
- /* do this when expand found other libs */
+ /* Do this when expand found other libraries. */
read_libraries(*fd, (*fd)->mainlist);
curlib = mainl->curlib;
@@ -4560,8 +4603,8 @@ static void library_link_end(Main *mainl, FileData **fd, const int flag)
}
blo_join_main((*fd)->mainlist);
- mainvar = (*fd)->mainlist->first;
- mainl = NULL; /* blo_join_main free's mainl, can't use anymore */
+ mainvar = static_cast<Main *>((*fd)->mainlist->first);
+ mainl = nullptr; /* blo_join_main free's mainl, can't use anymore */
lib_link_all(*fd, mainvar);
after_liblink_merged_bmain_process(mainvar);
@@ -4589,7 +4632,7 @@ static void library_link_end(Main *mainl, FileData **fd, const int flag)
}
blo_join_main((*fd)->mainlist);
- mainvar = (*fd)->mainlist->first;
+ mainvar = static_cast<Main *>((*fd)->mainlist->first);
MEM_freeN((*fd)->mainlist);
/* This does not take into account old, deprecated data, so we also have to do it after
@@ -4618,11 +4661,11 @@ static void library_link_end(Main *mainl, FileData **fd, const int flag)
/* patch to prevent switch_endian happens twice */
if ((*fd)->flags & FD_FLAGS_SWITCH_ENDIAN) {
blo_filedata_free(*fd);
- *fd = NULL;
+ *fd = nullptr;
}
}
-void BLO_library_link_end(Main *mainl, BlendHandle **bh, const struct LibraryLink_Params *params)
+void BLO_library_link_end(Main *mainl, BlendHandle **bh, const LibraryLink_Params *params)
{
FileData *fd = (FileData *)(*bh);
library_link_end(mainl, &fd, params->flag);
@@ -4659,7 +4702,7 @@ static int has_linked_ids_to_read(Main *mainvar)
static void read_library_linked_id(
FileData *basefd, FileData *fd, Main *mainvar, ID *id, ID **r_id)
{
- BHead *bhead = NULL;
+ BHead *bhead = nullptr;
const bool is_valid = BKE_idtype_idcode_is_linkable(GS(id->name)) ||
((id->tag & LIB_TAG_EXTERN) == 0);
@@ -4698,7 +4741,8 @@ static void read_library_linked_id(
/* Generate a placeholder for this ID (simplified version of read_libblock actually...). */
if (r_id) {
- *r_id = is_valid ? create_placeholder(mainvar, GS(id->name), id->name + 2, id->tag) : NULL;
+ *r_id = is_valid ? create_placeholder(mainvar, GS(id->name), id->name + 2, id->tag) :
+ nullptr;
}
}
}
@@ -4714,14 +4758,14 @@ static void read_library_linked_ids(FileData *basefd,
int a = set_listbasepointers(mainvar, lbarray);
while (a--) {
- ID *id = lbarray[a]->first;
- ListBase pending_free_ids = {NULL};
+ ID *id = static_cast<ID *>(lbarray[a]->first);
+ ListBase pending_free_ids = {nullptr};
while (id) {
- ID *id_next = id->next;
+ ID *id_next = static_cast<ID *>(id->next);
if ((id->tag & LIB_TAG_ID_LINK_PLACEHOLDER) && !(id->flag & LIB_INDIRECT_WEAK_LINK)) {
BLI_remlink(lbarray[a], id);
- if (mainvar->id_map != NULL) {
+ if (mainvar->id_map != nullptr) {
BKE_main_idmap_remove_id(mainvar->id_map, id);
}
@@ -4729,14 +4773,14 @@ static void read_library_linked_ids(FileData *basefd,
* you have more than one linked ID of the same data-block from same
* library. This is absolutely horrible, hence we use a ghash to ensure
* we go back to a single linked data when loading the file. */
- ID **realid = NULL;
+ ID **realid = nullptr;
if (!BLI_ghash_ensure_p(loaded_ids, id->name, (void ***)&realid)) {
read_library_linked_id(basefd, fd, mainvar, id, realid);
}
- /* `realid` shall never be NULL - unless some source file/lib is broken
- * (known case: some directly linked shapekey from a missing lib...). */
- // BLI_assert(*realid != NULL);
+ /* `realid` shall never be nullptr - unless some source file/lib is broken
+ * (known case: some directly linked shape-key from a missing lib...). */
+ // BLI_assert(*realid != nullptr);
/* Now that we have a real ID, replace all pointers to placeholders in
* fd->libmap with pointers to the real data-blocks. We do this for all
@@ -4751,28 +4795,28 @@ static void read_library_linked_ids(FileData *basefd,
}
/* Clear GHash and free link placeholder IDs of the current type. */
- BLI_ghash_clear(loaded_ids, NULL, NULL);
+ BLI_ghash_clear(loaded_ids, nullptr, nullptr);
BLI_freelistN(&pending_free_ids);
}
- BLI_ghash_free(loaded_ids, NULL, NULL);
+ BLI_ghash_free(loaded_ids, nullptr, nullptr);
}
static void read_library_clear_weak_links(FileData *basefd, ListBase *mainlist, Main *mainvar)
{
/* Any remaining weak links at this point have been lost, silently drop
- * those by setting them to NULL pointers. */
+ * those by setting them to nullptr pointers. */
ListBase *lbarray[INDEX_ID_MAX];
int a = set_listbasepointers(mainvar, lbarray);
while (a--) {
- ID *id = lbarray[a]->first;
+ ID *id = static_cast<ID *>(lbarray[a]->first);
while (id) {
- ID *id_next = id->next;
+ ID *id_next = static_cast<ID *>(id->next);
if ((id->tag & LIB_TAG_ID_LINK_PLACEHOLDER) && (id->flag & LIB_INDIRECT_WEAK_LINK)) {
CLOG_INFO(&LOG, 3, "Dropping weak link to '%s'", id->name);
- change_link_placeholder_to_real_ID_pointer(mainlist, basefd, id, NULL);
+ change_link_placeholder_to_real_ID_pointer(mainlist, basefd, id, nullptr);
BLI_freelinkN(lbarray[a], id);
}
id = id_next;
@@ -4787,7 +4831,7 @@ static FileData *read_library_file_data(FileData *basefd,
{
FileData *fd = mainptr->curlib->filedata;
- if (fd != NULL) {
+ if (fd != nullptr) {
/* File already open. */
return fd;
}
@@ -4842,14 +4886,14 @@ static FileData *read_library_file_data(FileData *basefd,
#endif
}
else {
- mainptr->curlib->filedata = NULL;
+ mainptr->curlib->filedata = nullptr;
mainptr->curlib->id.tag |= LIB_TAG_MISSING;
/* Set lib version to current main one... Makes assert later happy. */
mainptr->versionfile = mainptr->curlib->versionfile = mainl->versionfile;
mainptr->subversionfile = mainptr->curlib->subversionfile = mainl->subversionfile;
}
- if (fd == NULL) {
+ if (fd == nullptr) {
BLO_reportf_wrap(
basefd->reports, RPT_INFO, TIP_("Cannot find lib '%s'"), mainptr->curlib->filepath_abs);
basefd->reports->count.missing_libraries++;
@@ -4860,7 +4904,7 @@ static FileData *read_library_file_data(FileData *basefd,
static void read_libraries(FileData *basefd, ListBase *mainlist)
{
- Main *mainl = mainlist->first;
+ Main *mainl = static_cast<Main *>(mainlist->first);
bool do_it = true;
/* Expander is now callback function. */
@@ -4893,8 +4937,8 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
if (fd) {
do_it = true;
- if (mainptr->id_map == NULL) {
- mainptr->id_map = BKE_main_idmap_create(mainptr, false, NULL, MAIN_IDMAP_TYPE_NAME);
+ if (mainptr->id_map == nullptr) {
+ mainptr->id_map = BKE_main_idmap_create(mainptr, false, nullptr, MAIN_IDMAP_TYPE_NAME);
}
}
@@ -4931,7 +4975,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
do_versions(mainptr->curlib->filedata, mainptr->curlib, main_newid);
}
else {
- do_versions(basefd, NULL, main_newid);
+ do_versions(basefd, nullptr, main_newid);
}
add_main_to_main(mainptr, main_newid);
@@ -4951,7 +4995,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
if (mainptr->curlib->filedata) {
blo_filedata_free(mainptr->curlib->filedata);
}
- mainptr->curlib->filedata = NULL;
+ mainptr->curlib->filedata = nullptr;
}
BKE_main_free(main_newid);
}
@@ -4973,7 +5017,7 @@ void *BLO_read_get_new_packed_address(BlendDataReader *reader, const void *old_a
ID *BLO_read_get_new_id_address(BlendLibReader *reader, Library *lib, ID *id)
{
- return newlibadr(reader->fd, lib, id);
+ return static_cast<ID *>(newlibadr(reader->fd, lib, id));
}
int BLO_read_fileversion_get(BlendDataReader *reader)
@@ -4993,14 +5037,14 @@ void BLO_read_list_cb(BlendDataReader *reader, ListBase *list, BlendReadListFn c
}
BLO_read_data_address(reader, &list->first);
- if (callback != NULL) {
+ if (callback != nullptr) {
callback(reader, list->first);
}
- Link *ln = list->first;
- Link *prev = NULL;
+ Link *ln = static_cast<Link *>(list->first);
+ Link *prev = nullptr;
while (ln) {
BLO_read_data_address(reader, &ln->next);
- if (ln->next != NULL && callback != NULL) {
+ if (ln->next != nullptr && callback != nullptr) {
callback(reader, ln->next);
}
ln->prev = prev;
@@ -5010,9 +5054,9 @@ void BLO_read_list_cb(BlendDataReader *reader, ListBase *list, BlendReadListFn c
list->last = prev;
}
-void BLO_read_list(BlendDataReader *reader, struct ListBase *list)
+void BLO_read_list(BlendDataReader *reader, ListBase *list)
{
- BLO_read_list_cb(reader, list, NULL);
+ BLO_read_list_cb(reader, list, nullptr);
}
void BLO_read_int32_array(BlendDataReader *reader, int array_size, int32_t **ptr_p)
@@ -5062,17 +5106,17 @@ static void convert_pointer_array_64_to_32(BlendDataReader *reader,
for (int i = 0; i < array_size; i++) {
uint64_t ptr = src[i];
BLI_endian_switch_uint64(&ptr);
- dst[i] = (uint32_t)(ptr >> 3);
+ dst[i] = uint32_t(ptr >> 3);
}
}
else {
for (int i = 0; i < array_size; i++) {
- dst[i] = (uint32_t)(src[i] >> 3);
+ dst[i] = uint32_t(src[i] >> 3);
}
}
}
-static void convert_pointer_array_32_to_64(BlendDataReader *UNUSED(reader),
+static void convert_pointer_array_32_to_64(BlendDataReader * /*reader*/,
uint array_size,
const uint32_t *src,
uint64_t *dst)
@@ -5088,8 +5132,8 @@ void BLO_read_pointer_array(BlendDataReader *reader, void **ptr_p)
FileData *fd = reader->fd;
void *orig_array = newdataadr(fd, *ptr_p);
- if (orig_array == NULL) {
- *ptr_p = NULL;
+ if (orig_array == nullptr) {
+ *ptr_p = nullptr;
return;
}
@@ -5099,7 +5143,7 @@ void BLO_read_pointer_array(BlendDataReader *reader, void **ptr_p)
/* Over-allocation is fine, but might be better to pass the length as parameter. */
int array_size = MEM_allocN_len(orig_array) / file_pointer_size;
- void *final_array = NULL;
+ void *final_array = nullptr;
if (file_pointer_size == current_pointer_size) {
/* No pointer conversion necessary. */
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index 4522adb2aef..a0f19512753 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -8,6 +8,8 @@
#pragma once
+#include <stdio.h> /* Include header using off_t before poisoning it below. */
+
#ifdef WIN32
# include "BLI_winstuff.h"
#endif
@@ -17,6 +19,10 @@
#include "DNA_space_types.h"
#include "DNA_windowmanager_types.h" /* for eReportType */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct BLI_mmap_file;
struct BLOCacheStorage;
struct IDNameLib_Map;
@@ -38,6 +44,7 @@ enum eFileDataFlag {
/* XXX Unused in practice (checked once but never set). */
FD_FLAGS_NOT_MY_LIBMAP = 1 << 5,
};
+ENUM_OPERATORS(eFileDataFlag, FD_FLAGS_NOT_MY_LIBMAP)
/* Disallow since it's 32bit on ms-windows. */
#ifdef __GNUC__
@@ -207,6 +214,7 @@ void blo_do_versions_270(struct FileData *fd, struct Library *lib, struct Main *
void blo_do_versions_280(struct FileData *fd, struct Library *lib, struct Main *bmain);
void blo_do_versions_290(struct FileData *fd, struct Library *lib, struct Main *bmain);
void blo_do_versions_300(struct FileData *fd, struct Library *lib, struct Main *bmain);
+void blo_do_versions_400(struct FileData *fd, struct Library *lib, struct Main *bmain);
void blo_do_versions_cycles(struct FileData *fd, struct Library *lib, struct Main *bmain);
void do_versions_after_linking_250(struct Main *bmain);
@@ -224,3 +232,7 @@ void do_versions_after_linking_cycles(struct Main *bmain);
* but better use that nasty hack in do_version than readfile itself.
*/
void *blo_read_get_new_globaldata_address(struct FileData *fd, const void *adr);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/blenloader/intern/readfile_tempload.c b/source/blender/blenloader/intern/readfile_tempload.cc
index d642dbb5012..933077924f5 100644
--- a/source/blender/blenloader/intern/readfile_tempload.c
+++ b/source/blender/blenloader/intern/readfile_tempload.cc
@@ -20,7 +20,8 @@ TempLibraryContext *BLO_library_temp_load_id(struct Main *real_main,
const char *idname,
struct ReportList *reports)
{
- TempLibraryContext *temp_lib_ctx = MEM_callocN(sizeof(*temp_lib_ctx), __func__);
+ TempLibraryContext *temp_lib_ctx = static_cast<TempLibraryContext *>(
+ MEM_callocN(sizeof(*temp_lib_ctx), __func__));
temp_lib_ctx->bmain_base = BKE_main_new();
temp_lib_ctx->bf_reports.reports = reports;
diff --git a/source/blender/blenloader/intern/undofile.c b/source/blender/blenloader/intern/undofile.cc
index b5c2a73c268..99d1ca336fe 100644
--- a/source/blender/blenloader/intern/undofile.c
+++ b/source/blender/blenloader/intern/undofile.cc
@@ -42,7 +42,7 @@ void BLO_memfile_free(MemFile *memfile)
{
MemFileChunk *chunk;
- while ((chunk = BLI_pophead(&memfile->chunks))) {
+ while ((chunk = static_cast<MemFileChunk *>(BLI_pophead(&memfile->chunks)))) {
if (chunk->is_identical == false) {
MEM_freeN((void *)chunk->buf);
}
@@ -59,7 +59,8 @@ void BLO_memfile_merge(MemFile *first, MemFile *second)
BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
/* First, detect all memchunks in second memfile that are not owned by it. */
- for (MemFileChunk *sc = second->chunks.first; sc != NULL; sc = sc->next) {
+ for (MemFileChunk *sc = static_cast<MemFileChunk *>(second->chunks.first); sc != nullptr;
+ sc = static_cast<MemFileChunk *>(sc->next)) {
if (sc->is_identical) {
BLI_ghash_insert(buffer_to_second_memchunk, (void *)sc->buf, sc);
}
@@ -67,10 +68,12 @@ void BLO_memfile_merge(MemFile *first, MemFile *second)
/* Now, check all chunks from first memfile (the one we are removing), and if a memchunk owned by
* it is also used by the second memfile, transfer the ownership. */
- for (MemFileChunk *fc = first->chunks.first; fc != NULL; fc = fc->next) {
+ for (MemFileChunk *fc = static_cast<MemFileChunk *>(first->chunks.first); fc != nullptr;
+ fc = static_cast<MemFileChunk *>(fc->next)) {
if (!fc->is_identical) {
- MemFileChunk *sc = BLI_ghash_lookup(buffer_to_second_memchunk, fc->buf);
- if (sc != NULL) {
+ MemFileChunk *sc = static_cast<MemFileChunk *>(
+ BLI_ghash_lookup(buffer_to_second_memchunk, fc->buf));
+ if (sc != nullptr) {
BLI_assert(sc->is_identical);
sc->is_identical = false;
fc->is_identical = true;
@@ -81,7 +84,7 @@ void BLO_memfile_merge(MemFile *first, MemFile *second)
}
}
- BLI_ghash_free(buffer_to_second_memchunk, NULL, NULL);
+ BLI_ghash_free(buffer_to_second_memchunk, nullptr, nullptr);
BLO_memfile_free(first);
}
@@ -99,14 +102,16 @@ void BLO_memfile_write_init(MemFileWriteData *mem_data,
{
mem_data->written_memfile = written_memfile;
mem_data->reference_memfile = reference_memfile;
- mem_data->reference_current_chunk = reference_memfile ? reference_memfile->chunks.first : NULL;
+ mem_data->reference_current_chunk = reference_memfile ? static_cast<MemFileChunk *>(
+ reference_memfile->chunks.first) :
+ nullptr;
/* If we have a reference memfile, we generate a mapping between the session_uuid's of the
* IDs stored in that previous undo step, and its first matching memchunk. This will allow
* us to easily find the existing undo memory storage of IDs even when some re-ordering in
* current Main data-base broke the order matching with the memchunks from previous step.
*/
- if (reference_memfile != NULL) {
+ if (reference_memfile != nullptr) {
mem_data->id_session_uuid_mapping = BLI_ghash_new(
BLI_ghashutil_inthash_p_simple, BLI_ghashutil_intcmp, __func__);
uint current_session_uuid = MAIN_ID_SESSION_UUID_UNSET;
@@ -129,8 +134,8 @@ void BLO_memfile_write_init(MemFileWriteData *mem_data,
void BLO_memfile_write_finalize(MemFileWriteData *mem_data)
{
- if (mem_data->id_session_uuid_mapping != NULL) {
- BLI_ghash_free(mem_data->id_session_uuid_mapping, NULL, NULL);
+ if (mem_data->id_session_uuid_mapping != nullptr) {
+ BLI_ghash_free(mem_data->id_session_uuid_mapping, nullptr, nullptr);
}
}
@@ -139,9 +144,10 @@ void BLO_memfile_chunk_add(MemFileWriteData *mem_data, const char *buf, size_t s
MemFile *memfile = mem_data->written_memfile;
MemFileChunk **compchunk_step = &mem_data->reference_current_chunk;
- MemFileChunk *curchunk = MEM_mallocN(sizeof(MemFileChunk), "MemFileChunk");
+ MemFileChunk *curchunk = static_cast<MemFileChunk *>(
+ MEM_mallocN(sizeof(MemFileChunk), "MemFileChunk"));
curchunk->size = size;
- curchunk->buf = NULL;
+ curchunk->buf = nullptr;
curchunk->is_identical = false;
/* This is unsafe in the sense that an app handler or other code that does not
* perform an undo push may make changes after the last undo push that
@@ -151,7 +157,7 @@ void BLO_memfile_chunk_add(MemFileWriteData *mem_data, const char *buf, size_t s
BLI_addtail(&memfile->chunks, curchunk);
/* we compare compchunk with buf */
- if (*compchunk_step != NULL) {
+ if (*compchunk_step != nullptr) {
MemFileChunk *compchunk = *compchunk_step;
if (compchunk->size == curchunk->size) {
if (memcmp(compchunk->buf, buf, size) == 0) {
@@ -160,12 +166,12 @@ void BLO_memfile_chunk_add(MemFileWriteData *mem_data, const char *buf, size_t s
compchunk->is_identical_future = true;
}
}
- *compchunk_step = compchunk->next;
+ *compchunk_step = static_cast<MemFileChunk *>(compchunk->next);
}
/* not equal... */
- if (curchunk->buf == NULL) {
- char *buf_new = MEM_mallocN(size, "Chunk buffer");
+ if (curchunk->buf == nullptr) {
+ char *buf_new = static_cast<char *>(MEM_mallocN(size, "Chunk buffer"));
memcpy(buf_new, buf, size);
curchunk->buf = buf_new;
memfile->size += size;
@@ -176,12 +182,10 @@ struct Main *BLO_memfile_main_get(struct MemFile *memfile,
struct Main *bmain,
struct Scene **r_scene)
{
- struct Main *bmain_undo = NULL;
- BlendFileData *bfd = BLO_read_from_memfile(bmain,
- BKE_main_blendfile_path(bmain),
- memfile,
- &(const struct BlendFileReadParams){0},
- NULL);
+ struct Main *bmain_undo = nullptr;
+ BlendFileReadParams read_params{};
+ BlendFileData *bfd = BLO_read_from_memfile(
+ bmain, BKE_main_blendfile_path(bmain), memfile, &read_params, nullptr);
if (bfd) {
bmain_undo = bfd->main;
@@ -226,11 +230,12 @@ bool BLO_memfile_write_file(struct MemFile *memfile, const char *filepath)
return false;
}
- for (chunk = memfile->chunks.first; chunk; chunk = chunk->next) {
+ for (chunk = static_cast<MemFileChunk *>(memfile->chunks.first); chunk;
+ chunk = static_cast<MemFileChunk *>(chunk->next)) {
#ifdef _WIN32
- if ((size_t)write(file, chunk->buf, (uint)chunk->size) != chunk->size)
+ if (size_t(write(file, chunk->buf, uint(chunk->size))) != chunk->size)
#else
- if ((size_t)write(file, chunk->buf, chunk->size) != chunk->size)
+ if (size_t(write(file, chunk->buf, chunk->size)) != chunk->size)
#endif
{
break;
@@ -255,7 +260,7 @@ static ssize_t undo_read(FileReader *reader, void *buffer, size_t size)
static size_t seek = SIZE_MAX; /* The current position. */
static size_t offset = 0; /* Size of previous chunks. */
- static MemFileChunk *chunk = NULL;
+ static MemFileChunk *chunk = nullptr;
size_t chunkoffset, readsize, totread;
undo->memchunk_identical = true;
@@ -264,19 +269,19 @@ static ssize_t undo_read(FileReader *reader, void *buffer, size_t size)
return 0;
}
- if (seek != (size_t)undo->reader.offset) {
- chunk = undo->memfile->chunks.first;
+ if (seek != size_t(undo->reader.offset)) {
+ chunk = static_cast<MemFileChunk *>(undo->memfile->chunks.first);
seek = 0;
while (chunk) {
- if (seek + chunk->size > (size_t)undo->reader.offset) {
+ if (seek + chunk->size > size_t(undo->reader.offset)) {
break;
}
seek += chunk->size;
- chunk = chunk->next;
+ chunk = static_cast<MemFileChunk *>(chunk->next);
}
offset = seek;
- seek = (size_t)undo->reader.offset;
+ seek = size_t(undo->reader.offset);
}
if (chunk) {
@@ -286,11 +291,11 @@ static ssize_t undo_read(FileReader *reader, void *buffer, size_t size)
/* First check if it's on the end if current chunk. */
if (seek - offset == chunk->size) {
offset += chunk->size;
- chunk = chunk->next;
+ chunk = static_cast<MemFileChunk *>(chunk->next);
}
/* Debug, should never happen. */
- if (chunk == NULL) {
+ if (chunk == nullptr) {
printf("illegal read, chunk zero\n");
return 0;
}
@@ -318,7 +323,7 @@ static ssize_t undo_read(FileReader *reader, void *buffer, size_t size)
chunk->is_identical_future;
} while (totread < size);
- return (ssize_t)totread;
+ return ssize_t(totread);
}
return 0;
@@ -331,13 +336,13 @@ static void undo_close(FileReader *reader)
FileReader *BLO_memfile_new_filereader(MemFile *memfile, int undo_direction)
{
- UndoReader *undo = MEM_callocN(sizeof(UndoReader), __func__);
+ UndoReader *undo = static_cast<UndoReader *>(MEM_callocN(sizeof(UndoReader), __func__));
undo->memfile = memfile;
undo->undo_direction = undo_direction;
undo->reader.read = undo_read;
- undo->reader.seek = NULL;
+ undo->reader.seek = nullptr;
undo->reader.close = undo_close;
return (FileReader *)undo;
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index 9e5ef41892a..0b543ad735b 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -630,7 +630,7 @@ static bool seq_sound_proxy_update_cb(Sequence *seq, void *user_data)
Main *bmain = (Main *)user_data;
if (seq->type == SEQ_TYPE_SOUND_HD) {
char str[FILE_MAX];
- BLI_join_dirfile(str, sizeof(str), seq->strip->dir, seq->strip->stripdata->name);
+ BLI_path_join(str, sizeof(str), seq->strip->dir, seq->strip->stripdata->name);
BLI_path_abs(str, BKE_main_blendfile_path(bmain));
seq->sound = BKE_sound_new_file(bmain, str);
}
@@ -2316,7 +2316,6 @@ static void lib_node_do_versions_group_indices(bNode *gnode)
/* deprecated */
sock->own_index = link->fromsock->own_index;
sock->to_index = 0;
- sock->groupsock = NULL;
}
}
}
@@ -2329,7 +2328,6 @@ static void lib_node_do_versions_group_indices(bNode *gnode)
/* deprecated */
sock->own_index = link->tosock->own_index;
sock->to_index = 0;
- sock->groupsock = NULL;
}
}
}
diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c
index e4a93762da4..47a1f7f7241 100644
--- a/source/blender/blenloader/intern/versioning_260.c
+++ b/source/blender/blenloader/intern/versioning_260.c
@@ -44,6 +44,7 @@
#include "BKE_image.h"
#include "BKE_main.h" /* for Main */
#include "BKE_mesh.h" /* for ME_ defines (patching) */
+#include "BKE_mesh_legacy_convert.h"
#include "BKE_modifier.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
@@ -279,10 +280,9 @@ static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNo
BLI_strncpy(filename, old_image->name, sizeof(filename));
}
- /* if z buffer is saved, change the image type to multilayer exr.
- * XXX this is slightly messy, Z buffer was ignored before for anything but EXR and IRIS ...
- * I'm just assuming here that IRIZ means IRIS with z buffer ...
- */
+ /* If Z buffer is saved, change the image type to multi-layer EXR.
+ * XXX: this is slightly messy, Z buffer was ignored before for anything but EXR and IRIS ...
+ * I'm just assuming here that IRIZ means IRIS with z buffer. */
if (old_data && ELEM(old_data->im_format.imtype, R_IMF_IMTYPE_IRIZ, R_IMF_IMTYPE_OPENEXR)) {
char sockpath[FILE_MAX];
@@ -392,9 +392,8 @@ static void do_versions_nodetree_file_output_layers_2_64_5(bNodeTree *ntree)
for (sock = node->inputs.first; sock; sock = sock->next) {
NodeImageMultiFileSocket *input = sock->storage;
- /* multilayer names are stored as separate strings now,
- * used the path string before, so copy it over.
- */
+ /* Multi-layer names are stored as separate strings now,
+ * used the path string before, so copy it over. */
BLI_strncpy(input->layer, input->path, sizeof(input->layer));
/* paths/layer names also have to be unique now, initial check */
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index e4dc8d006ae..1a8fec49516 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -53,6 +53,7 @@
#include "DNA_world_types.h"
#include "BKE_animsys.h"
+#include "BKE_blender.h"
#include "BKE_brush.h"
#include "BKE_cloth.h"
#include "BKE_collection.h"
@@ -512,12 +513,13 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene)
}
}
+ BKE_view_layer_synced_ensure(scene, view_layer);
/* for convenience set the same active object in all the layers */
if (scene->basact) {
view_layer->basact = BKE_view_layer_base_find(view_layer, scene->basact->object);
}
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if ((base->flag & BASE_SELECTABLE) && (base->object->flag & SELECT)) {
base->flag |= BASE_SELECTED;
}
@@ -537,13 +539,14 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene)
view_layer->flag &= ~VIEW_LAYER_RENDER;
}
+ BKE_view_layer_synced_ensure(scene, view_layer);
/* convert active base */
if (scene->basact) {
view_layer->basact = BKE_view_layer_base_find(view_layer, scene->basact->object);
}
/* convert selected bases */
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if ((base->flag & BASE_SELECTABLE) && (base->object->flag & SELECT)) {
base->flag |= BASE_SELECTED;
}
@@ -592,7 +595,7 @@ static void do_versions_fix_annotations(bGPdata *gpd)
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
- if ((gps->colorname[0] != '\0') && (STREQ(gps->colorname, palcolor->info))) {
+ if ((gps->colorname[0] != '\0') && STREQ(gps->colorname, palcolor->info)) {
/* copy color settings */
copy_v4_v4(gpl->color, palcolor->color);
}
@@ -1611,12 +1614,13 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports))
if (me->totface && !me->totpoly) {
/* temporarily switch main so that reading from
* external CustomData works */
- Main *gmain = G_MAIN;
- G_MAIN = bmain;
+ Main *orig_gmain = BKE_blender_globals_main_swap(bmain);
BKE_mesh_do_versions_convert_mfaces_to_mpolys(me);
- G_MAIN = gmain;
+ Main *tmp_gmain = BKE_blender_globals_main_swap(orig_gmain);
+ BLI_assert(tmp_gmain == bmain);
+ UNUSED_VARS_NDEBUG(tmp_gmain);
}
/* Deprecated, only kept for conversion. */
@@ -3375,7 +3379,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
SpaceImage *sima = (SpaceImage *)sl;
sima->flag &= ~(SI_FLAG_UNUSED_0 | SI_FLAG_UNUSED_1 | SI_FLAG_UNUSED_3 |
SI_FLAG_UNUSED_6 | SI_FLAG_UNUSED_7 | SI_FLAG_UNUSED_8 |
- SI_FLAG_UNUSED_17 | SI_CUSTOM_GRID | SI_FLAG_UNUSED_23 |
+ SI_FLAG_UNUSED_17 | SI_FLAG_UNUSED_18 | SI_FLAG_UNUSED_23 |
SI_FLAG_UNUSED_24);
break;
}
@@ -3383,7 +3387,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
View3D *v3d = (View3D *)sl;
v3d->flag &= ~(V3D_LOCAL_COLLECTIONS | V3D_FLAG_UNUSED_1 | V3D_FLAG_UNUSED_10 |
V3D_FLAG_UNUSED_12);
- v3d->flag2 &= ~(V3D_FLAG2_UNUSED_3 | V3D_FLAG2_UNUSED_6 | V3D_FLAG2_UNUSED_12 |
+ v3d->flag2 &= ~((1 << 3) | V3D_FLAG2_UNUSED_6 | V3D_FLAG2_UNUSED_12 |
V3D_FLAG2_UNUSED_13 | V3D_FLAG2_UNUSED_14 | V3D_FLAG2_UNUSED_15);
break;
}
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index b285e1829b7..b8161a9dc40 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -365,7 +365,6 @@ static void seq_update_meta_disp_range(Scene *scene)
/* Update meta strip endpoints. */
SEQ_time_left_handle_frame_set(scene, ms->parseq, ms->disp_range[0]);
SEQ_time_right_handle_frame_set(scene, ms->parseq, ms->disp_range[1]);
- SEQ_transform_fix_single_image_seq_offsets(scene, ms->parseq);
/* Recalculate effects using meta strip. */
LISTBASE_FOREACH (Sequence *, seq, ms->oldbasep) {
@@ -1611,8 +1610,8 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
- if ((!MAIN_VERSION_ATLEAST(bmain, 292, 14)) ||
- ((bmain->versionfile == 293) && (!MAIN_VERSION_ATLEAST(bmain, 293, 1)))) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 292, 14) ||
+ ((bmain->versionfile == 293) && !MAIN_VERSION_ATLEAST(bmain, 293, 1))) {
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
if (ntree->type != NTREE_GEOMETRY) {
continue;
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.cc
index 1692fd2d747..65094655cfe 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.cc
@@ -6,7 +6,7 @@
/* allow readfile to use deprecated functionality */
#define DNA_DEPRECATED_ALLOW
-#include <string.h>
+#include <cstring>
#include "CLG_log.h"
@@ -86,39 +86,40 @@ static IDProperty *idproperty_find_ui_container(IDProperty *idprop_group)
return prop;
}
}
- return NULL;
+ return nullptr;
}
static void version_idproperty_move_data_int(IDPropertyUIDataInt *ui_data,
const IDProperty *prop_ui_data)
{
IDProperty *min = IDP_GetPropertyFromGroup(prop_ui_data, "min");
- if (min != NULL) {
+ if (min != nullptr) {
ui_data->min = ui_data->soft_min = IDP_coerce_to_int_or_zero(min);
}
IDProperty *max = IDP_GetPropertyFromGroup(prop_ui_data, "max");
- if (max != NULL) {
+ if (max != nullptr) {
ui_data->max = ui_data->soft_max = IDP_coerce_to_int_or_zero(max);
}
IDProperty *soft_min = IDP_GetPropertyFromGroup(prop_ui_data, "soft_min");
- if (soft_min != NULL) {
+ if (soft_min != nullptr) {
ui_data->soft_min = IDP_coerce_to_int_or_zero(soft_min);
ui_data->soft_min = MIN2(ui_data->soft_min, ui_data->min);
}
IDProperty *soft_max = IDP_GetPropertyFromGroup(prop_ui_data, "soft_max");
- if (soft_max != NULL) {
+ if (soft_max != nullptr) {
ui_data->soft_max = IDP_coerce_to_int_or_zero(soft_max);
ui_data->soft_max = MAX2(ui_data->soft_max, ui_data->max);
}
IDProperty *step = IDP_GetPropertyFromGroup(prop_ui_data, "step");
- if (step != NULL) {
+ if (step != nullptr) {
ui_data->step = IDP_coerce_to_int_or_zero(soft_max);
}
IDProperty *default_value = IDP_GetPropertyFromGroup(prop_ui_data, "default");
- if (default_value != NULL) {
+ if (default_value != nullptr) {
if (default_value->type == IDP_ARRAY) {
if (default_value->subtype == IDP_INT) {
- ui_data->default_array = MEM_malloc_arrayN(default_value->len, sizeof(int), __func__);
+ ui_data->default_array = static_cast<int *>(
+ MEM_malloc_arrayN(default_value->len, sizeof(int), __func__));
memcpy(ui_data->default_array, IDP_Array(default_value), sizeof(int) * default_value->len);
ui_data->default_array_len = default_value->len;
}
@@ -133,45 +134,47 @@ static void version_idproperty_move_data_float(IDPropertyUIDataFloat *ui_data,
const IDProperty *prop_ui_data)
{
IDProperty *min = IDP_GetPropertyFromGroup(prop_ui_data, "min");
- if (min != NULL) {
+ if (min != nullptr) {
ui_data->min = ui_data->soft_min = IDP_coerce_to_double_or_zero(min);
}
IDProperty *max = IDP_GetPropertyFromGroup(prop_ui_data, "max");
- if (max != NULL) {
+ if (max != nullptr) {
ui_data->max = ui_data->soft_max = IDP_coerce_to_double_or_zero(max);
}
IDProperty *soft_min = IDP_GetPropertyFromGroup(prop_ui_data, "soft_min");
- if (soft_min != NULL) {
+ if (soft_min != nullptr) {
ui_data->soft_min = IDP_coerce_to_double_or_zero(soft_min);
ui_data->soft_min = MAX2(ui_data->soft_min, ui_data->min);
}
IDProperty *soft_max = IDP_GetPropertyFromGroup(prop_ui_data, "soft_max");
- if (soft_max != NULL) {
+ if (soft_max != nullptr) {
ui_data->soft_max = IDP_coerce_to_double_or_zero(soft_max);
ui_data->soft_max = MIN2(ui_data->soft_max, ui_data->max);
}
IDProperty *step = IDP_GetPropertyFromGroup(prop_ui_data, "step");
- if (step != NULL) {
+ if (step != nullptr) {
ui_data->step = IDP_coerce_to_float_or_zero(step);
}
IDProperty *precision = IDP_GetPropertyFromGroup(prop_ui_data, "precision");
- if (precision != NULL) {
+ if (precision != nullptr) {
ui_data->precision = IDP_coerce_to_int_or_zero(precision);
}
IDProperty *default_value = IDP_GetPropertyFromGroup(prop_ui_data, "default");
- if (default_value != NULL) {
+ if (default_value != nullptr) {
if (default_value->type == IDP_ARRAY) {
const int array_len = default_value->len;
ui_data->default_array_len = array_len;
if (default_value->subtype == IDP_FLOAT) {
- ui_data->default_array = MEM_malloc_arrayN(array_len, sizeof(double), __func__);
- const float *old_default_array = IDP_Array(default_value);
+ ui_data->default_array = static_cast<double *>(
+ MEM_malloc_arrayN(array_len, sizeof(double), __func__));
+ const float *old_default_array = static_cast<const float *>(IDP_Array(default_value));
for (int i = 0; i < ui_data->default_array_len; i++) {
- ui_data->default_array[i] = (double)old_default_array[i];
+ ui_data->default_array[i] = double(old_default_array[i]);
}
}
else if (default_value->subtype == IDP_DOUBLE) {
- ui_data->default_array = MEM_malloc_arrayN(array_len, sizeof(double), __func__);
+ ui_data->default_array = static_cast<double *>(
+ MEM_malloc_arrayN(array_len, sizeof(double), __func__));
memcpy(ui_data->default_array, IDP_Array(default_value), sizeof(double) * array_len);
}
}
@@ -185,25 +188,26 @@ static void version_idproperty_move_data_string(IDPropertyUIDataString *ui_data,
const IDProperty *prop_ui_data)
{
IDProperty *default_value = IDP_GetPropertyFromGroup(prop_ui_data, "default");
- if (default_value != NULL && default_value->type == IDP_STRING) {
+ if (default_value != nullptr && default_value->type == IDP_STRING) {
ui_data->default_value = BLI_strdup(IDP_String(default_value));
}
}
static void version_idproperty_ui_data(IDProperty *idprop_group)
{
- if (idprop_group == NULL) { /* NULL check here to reduce verbosity of calls to this function. */
+ if (idprop_group ==
+ nullptr) { /* nullptr check here to reduce verbosity of calls to this function. */
return;
}
IDProperty *ui_container = idproperty_find_ui_container(idprop_group);
- if (ui_container == NULL) {
+ if (ui_container == nullptr) {
return;
}
LISTBASE_FOREACH (IDProperty *, prop, &idprop_group->data.group) {
IDProperty *prop_ui_data = IDP_GetPropertyFromGroup(ui_container, prop->name);
- if (prop_ui_data == NULL) {
+ if (prop_ui_data == nullptr) {
continue;
}
@@ -214,7 +218,7 @@ static void version_idproperty_ui_data(IDProperty *idprop_group)
IDPropertyUIData *ui_data = IDP_ui_data_ensure(prop);
IDProperty *subtype = IDP_GetPropertyFromGroup(prop_ui_data, "subtype");
- if (subtype != NULL && subtype->type == IDP_STRING) {
+ if (subtype != nullptr && subtype->type == IDP_STRING) {
const char *subtype_string = IDP_String(subtype);
int result = PROP_NONE;
RNA_enum_value_from_id(rna_enum_property_subtype_items, subtype_string, &result);
@@ -222,7 +226,7 @@ static void version_idproperty_ui_data(IDProperty *idprop_group)
}
IDProperty *description = IDP_GetPropertyFromGroup(prop_ui_data, "description");
- if (description != NULL && description->type == IDP_STRING) {
+ if (description != nullptr && description->type == IDP_STRING) {
ui_data->description = BLI_strdup(IDP_String(description));
}
@@ -318,7 +322,7 @@ static void do_versions_idproperty_ui_data(Main *bmain)
}
/* Object post bones. */
- if (ob->type == OB_ARMATURE && ob->pose != NULL) {
+ if (ob->type == OB_ARMATURE && ob->pose != nullptr) {
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
version_idproperty_ui_data(pchan->prop);
}
@@ -327,7 +331,7 @@ static void do_versions_idproperty_ui_data(Main *bmain)
/* Sequences. */
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
- if (scene->ed != NULL) {
+ if (scene->ed != nullptr) {
do_versions_idproperty_seq_recursive(&scene->ed->seqbase);
}
}
@@ -343,7 +347,7 @@ static void sort_linked_ids(Main *bmain)
if (ID_IS_LINKED(id)) {
BLI_remlink(lb, id);
BLI_addtail(&temp_list, id);
- id_sort_by_name(&temp_list, id, NULL);
+ id_sort_by_name(&temp_list, id, nullptr);
}
}
BLI_movelisttolist(lb, &temp_list);
@@ -356,9 +360,9 @@ static void assert_sorted_ids(Main *bmain)
#ifndef NDEBUG
ListBase *lb;
FOREACH_MAIN_LISTBASE_BEGIN (bmain, lb) {
- ID *id_prev = NULL;
+ ID *id_prev = nullptr;
LISTBASE_FOREACH (ID *, id, lb) {
- if (id_prev == NULL) {
+ if (id_prev == nullptr) {
continue;
}
BLI_assert(id_prev->lib != id->lib || BLI_strcasecmp(id_prev->name, id->name) < 0);
@@ -399,7 +403,7 @@ static void do_versions_sequencer_speed_effect_recursive(Scene *scene, const Lis
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
if (seq->type == SEQ_TYPE_SPEED) {
SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
- const char *substr = NULL;
+ const char *substr = nullptr;
float globalSpeed = v->globalSpeed;
if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) {
if (globalSpeed == 1.0f) {
@@ -408,9 +412,9 @@ static void do_versions_sequencer_speed_effect_recursive(Scene *scene, const Lis
else {
v->speed_control_type = SEQ_SPEED_MULTIPLY;
v->speed_fader = globalSpeed *
- ((float)seq->seq1->len /
- max_ff((float)(SEQ_time_right_handle_frame_get(scene, seq->seq1) -
- seq->seq1->start),
+ (float(seq->seq1->len) /
+ max_ff(float(SEQ_time_right_handle_frame_get(scene, seq->seq1) -
+ seq->seq1->start),
1.0f));
}
}
@@ -426,14 +430,15 @@ static void do_versions_sequencer_speed_effect_recursive(Scene *scene, const Lis
}
else {
v->speed_control_type = SEQ_SPEED_FRAME_NUMBER;
- v->speed_fader_frame_number = (int)(seq->speed_fader * globalSpeed);
+ v->speed_fader_frame_number = int(seq->speed_fader * globalSpeed);
substr = "speed_frame_number";
}
v->flags &= ~(SEQ_SPEED_INTEGRATE | SEQ_SPEED_COMPRESS_IPO_Y);
if (substr || globalSpeed != 1.0f) {
- FCurve *fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL);
+ FCurve *fcu = id_data_find_fcurve(
+ &scene->id, seq, &RNA_Sequence, "speed_factor", 0, nullptr);
if (fcu) {
if (globalSpeed != 1.0f) {
for (int i = 0; i < fcu->totvert; i++) {
@@ -460,13 +465,13 @@ static void do_versions_sequencer_speed_effect_recursive(Scene *scene, const Lis
#undef SEQ_SPEED_COMPRESS_IPO_Y
}
-static bool do_versions_sequencer_color_tags(Sequence *seq, void *UNUSED(user_data))
+static bool do_versions_sequencer_color_tags(Sequence *seq, void * /*user_data*/)
{
seq->color_tag = SEQUENCE_COLOR_NONE;
return true;
}
-static bool do_versions_sequencer_color_balance_sop(Sequence *seq, void *UNUSED(user_data))
+static bool do_versions_sequencer_color_balance_sop(Sequence *seq, void * /*user_data*/)
{
LISTBASE_FOREACH (SequenceModifierData *, smd, &seq->modifiers) {
if (smd->type == seqModifierType_ColorBalance) {
@@ -489,7 +494,7 @@ static bNodeLink *find_connected_link(bNodeTree *ntree, bNodeSocket *in_socket)
return link;
}
}
- return NULL;
+ return nullptr;
}
static void add_realize_instances_before_socket(bNodeTree *ntree,
@@ -498,7 +503,7 @@ static void add_realize_instances_before_socket(bNodeTree *ntree,
{
BLI_assert(geometry_socket->type == SOCK_GEOMETRY);
bNodeLink *link = find_connected_link(ntree, geometry_socket);
- if (link == NULL) {
+ if (link == nullptr) {
return;
}
@@ -507,13 +512,17 @@ static void add_realize_instances_before_socket(bNodeTree *ntree,
return;
}
- bNode *realize_node = nodeAddStaticNode(NULL, ntree, GEO_NODE_REALIZE_INSTANCES);
+ bNode *realize_node = nodeAddStaticNode(nullptr, ntree, GEO_NODE_REALIZE_INSTANCES);
realize_node->parent = node->parent;
realize_node->locx = node->locx - 100;
realize_node->locy = node->locy;
- nodeAddLink(ntree, link->fromnode, link->fromsock, realize_node, realize_node->inputs.first);
+ nodeAddLink(ntree,
+ link->fromnode,
+ link->fromsock,
+ realize_node,
+ static_cast<bNodeSocket *>(realize_node->inputs.first));
link->fromnode = realize_node;
- link->fromsock = realize_node->outputs.first;
+ link->fromsock = static_cast<bNodeSocket *>(realize_node->outputs.first);
}
/**
@@ -537,7 +546,7 @@ static void version_geometry_nodes_add_realize_instance_nodes(bNodeTree *ntree)
GEO_NODE_REPLACE_MATERIAL,
GEO_NODE_SUBDIVIDE_MESH,
GEO_NODE_TRIANGULATE)) {
- bNodeSocket *geometry_socket = node->inputs.first;
+ bNodeSocket *geometry_socket = static_cast<bNodeSocket *>(node->inputs.first);
add_realize_instances_before_socket(ntree, node, geometry_socket);
}
/* Also realize instances for the profile input of the curve to mesh node. */
@@ -560,33 +569,65 @@ static bNodeTree *add_realize_node_tree(Main *bmain)
ntreeAddSocketInterface(node_tree, SOCK_IN, "NodeSocketGeometry", "Geometry");
ntreeAddSocketInterface(node_tree, SOCK_OUT, "NodeSocketGeometry", "Geometry");
- bNode *group_input = nodeAddStaticNode(NULL, node_tree, NODE_GROUP_INPUT);
+ bNode *group_input = nodeAddStaticNode(nullptr, node_tree, NODE_GROUP_INPUT);
group_input->locx = -400.0f;
- bNode *group_output = nodeAddStaticNode(NULL, node_tree, NODE_GROUP_OUTPUT);
+ bNode *group_output = nodeAddStaticNode(nullptr, node_tree, NODE_GROUP_OUTPUT);
group_output->locx = 500.0f;
group_output->flag |= NODE_DO_OUTPUT;
- bNode *join = nodeAddStaticNode(NULL, node_tree, GEO_NODE_JOIN_GEOMETRY);
+ bNode *join = nodeAddStaticNode(nullptr, node_tree, GEO_NODE_JOIN_GEOMETRY);
join->locx = group_output->locx - 175.0f;
join->locy = group_output->locy;
- bNode *conv = nodeAddStaticNode(NULL, node_tree, GEO_NODE_POINTS_TO_VERTICES);
+ bNode *conv = nodeAddStaticNode(nullptr, node_tree, GEO_NODE_POINTS_TO_VERTICES);
conv->locx = join->locx - 175.0f;
conv->locy = join->locy - 70.0;
- bNode *separate = nodeAddStaticNode(NULL, node_tree, GEO_NODE_SEPARATE_COMPONENTS);
+ bNode *separate = nodeAddStaticNode(nullptr, node_tree, GEO_NODE_SEPARATE_COMPONENTS);
separate->locx = join->locx - 350.0f;
separate->locy = join->locy + 50.0f;
- bNode *realize = nodeAddStaticNode(NULL, node_tree, GEO_NODE_REALIZE_INSTANCES);
+ bNode *realize = nodeAddStaticNode(nullptr, node_tree, GEO_NODE_REALIZE_INSTANCES);
realize->locx = separate->locx - 200.0f;
realize->locy = join->locy;
- nodeAddLink(node_tree, group_input, group_input->outputs.first, realize, realize->inputs.first);
- nodeAddLink(node_tree, realize, realize->outputs.first, separate, separate->inputs.first);
- nodeAddLink(node_tree, conv, conv->outputs.first, join, join->inputs.first);
- nodeAddLink(node_tree, separate, BLI_findlink(&separate->outputs, 3), join, join->inputs.first);
- nodeAddLink(node_tree, separate, BLI_findlink(&separate->outputs, 1), conv, conv->inputs.first);
- nodeAddLink(node_tree, separate, BLI_findlink(&separate->outputs, 2), join, join->inputs.first);
- nodeAddLink(node_tree, separate, separate->outputs.first, join, join->inputs.first);
- nodeAddLink(node_tree, join, join->outputs.first, group_output, group_output->inputs.first);
+ nodeAddLink(node_tree,
+ group_input,
+ static_cast<bNodeSocket *>(group_input->outputs.first),
+ realize,
+ static_cast<bNodeSocket *>(realize->inputs.first));
+ nodeAddLink(node_tree,
+ realize,
+ static_cast<bNodeSocket *>(realize->outputs.first),
+ separate,
+ static_cast<bNodeSocket *>(separate->inputs.first));
+ nodeAddLink(node_tree,
+ conv,
+ static_cast<bNodeSocket *>(conv->outputs.first),
+ join,
+ static_cast<bNodeSocket *>(join->inputs.first));
+ nodeAddLink(node_tree,
+ separate,
+ static_cast<bNodeSocket *>(BLI_findlink(&separate->outputs, 3)),
+ join,
+ static_cast<bNodeSocket *>(join->inputs.first));
+ nodeAddLink(node_tree,
+ separate,
+ static_cast<bNodeSocket *>(BLI_findlink(&separate->outputs, 1)),
+ conv,
+ static_cast<bNodeSocket *>(conv->inputs.first));
+ nodeAddLink(node_tree,
+ separate,
+ static_cast<bNodeSocket *>(BLI_findlink(&separate->outputs, 2)),
+ join,
+ static_cast<bNodeSocket *>(join->inputs.first));
+ nodeAddLink(node_tree,
+ separate,
+ static_cast<bNodeSocket *>(separate->outputs.first),
+ join,
+ static_cast<bNodeSocket *>(join->inputs.first));
+ nodeAddLink(node_tree,
+ join,
+ static_cast<bNodeSocket *>(join->outputs.first),
+ group_output,
+ static_cast<bNodeSocket *>(group_output->inputs.first));
LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
nodeSetSelected(node, false);
@@ -602,7 +643,7 @@ static void seq_speed_factor_fix_rna_path(Sequence *seq, ListBase *fcurves)
BLI_str_escape(name_esc, seq->name + 2, sizeof(name_esc));
char *path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].pitch", name_esc);
FCurve *fcu = BKE_fcurve_find(fcurves, path, 0);
- if (fcu != NULL) {
+ if (fcu != nullptr) {
MEM_freeN(fcu->rna_path);
fcu->rna_path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].speed_factor", name_esc);
}
@@ -611,7 +652,7 @@ static void seq_speed_factor_fix_rna_path(Sequence *seq, ListBase *fcurves)
static bool seq_speed_factor_set(Sequence *seq, void *user_data)
{
- const Scene *scene = user_data;
+ const Scene *scene = static_cast<const Scene *>(user_data);
if (seq->type == SEQ_TYPE_SOUND_RAM) {
/* Move `pitch` animation to `speed_factor` */
if (scene->adt && scene->adt->action) {
@@ -629,7 +670,148 @@ static bool seq_speed_factor_set(Sequence *seq, void *user_data)
return true;
}
-void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
+static void version_geometry_nodes_replace_transfer_attribute_node(bNodeTree *ntree)
+{
+ using namespace blender;
+ /* Otherwise `ntree->typeInfo` is null. */
+ ntreeSetTypes(nullptr, ntree);
+ LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) {
+ if (node->type != GEO_NODE_TRANSFER_ATTRIBUTE_DEPRECATED) {
+ continue;
+ }
+ bNodeSocket *old_geometry_socket = nodeFindSocket(node, SOCK_IN, "Source");
+ const NodeGeometryTransferAttribute *storage = (const NodeGeometryTransferAttribute *)
+ node->storage;
+ switch (storage->mode) {
+ case GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED: {
+ bNode *sample_nearest_surface = nodeAddStaticNode(
+ nullptr, ntree, GEO_NODE_SAMPLE_NEAREST_SURFACE);
+ sample_nearest_surface->parent = node->parent;
+ sample_nearest_surface->custom1 = storage->data_type;
+ sample_nearest_surface->locx = node->locx;
+ sample_nearest_surface->locy = node->locy;
+ static auto socket_remap = []() {
+ Map<std::string, std::string> map;
+ map.add_new("Attribute", "Value_Vector");
+ map.add_new("Attribute_001", "Value_Float");
+ map.add_new("Attribute_002", "Value_Color");
+ map.add_new("Attribute_003", "Value_Bool");
+ map.add_new("Attribute_004", "Value_Int");
+ map.add_new("Source", "Mesh");
+ map.add_new("Source Position", "Sample Position");
+ return map;
+ }();
+ node_tree_relink_with_socket_id_map(*ntree, *node, *sample_nearest_surface, socket_remap);
+ break;
+ }
+ case GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST: {
+ /* These domains weren't supported by the index transfer mode, but were selectable. */
+ const eAttrDomain domain = ELEM(storage->domain, ATTR_DOMAIN_INSTANCE, ATTR_DOMAIN_CURVE) ?
+ ATTR_DOMAIN_POINT :
+ eAttrDomain(storage->domain);
+
+ /* Use a sample index node to retrieve the data with this node's index output. */
+ bNode *sample_index = nodeAddStaticNode(nullptr, ntree, GEO_NODE_SAMPLE_INDEX);
+ NodeGeometrySampleIndex *sample_storage = static_cast<NodeGeometrySampleIndex *>(
+ sample_index->storage);
+ sample_storage->data_type = storage->data_type;
+ sample_storage->domain = domain;
+ sample_index->parent = node->parent;
+ sample_index->locx = node->locx + 25.0f;
+ sample_index->locy = node->locy;
+ if (old_geometry_socket->link) {
+ nodeAddLink(ntree,
+ old_geometry_socket->link->fromnode,
+ old_geometry_socket->link->fromsock,
+ sample_index,
+ nodeFindSocket(sample_index, SOCK_IN, "Geometry"));
+ }
+
+ bNode *sample_nearest = nodeAddStaticNode(nullptr, ntree, GEO_NODE_SAMPLE_NEAREST);
+ sample_nearest->parent = node->parent;
+ sample_nearest->custom1 = storage->data_type;
+ sample_nearest->custom2 = domain;
+ sample_nearest->locx = node->locx - 25.0f;
+ sample_nearest->locy = node->locy;
+ if (old_geometry_socket->link) {
+ nodeAddLink(ntree,
+ old_geometry_socket->link->fromnode,
+ old_geometry_socket->link->fromsock,
+ sample_nearest,
+ nodeFindSocket(sample_nearest, SOCK_IN, "Geometry"));
+ }
+ static auto sample_nearest_remap = []() {
+ Map<std::string, std::string> map;
+ map.add_new("Source Position", "Sample Position");
+ return map;
+ }();
+ node_tree_relink_with_socket_id_map(*ntree, *node, *sample_nearest, sample_nearest_remap);
+
+ static auto sample_index_remap = []() {
+ Map<std::string, std::string> map;
+ map.add_new("Attribute", "Value_Vector");
+ map.add_new("Attribute_001", "Value_Float");
+ map.add_new("Attribute_002", "Value_Color");
+ map.add_new("Attribute_003", "Value_Bool");
+ map.add_new("Attribute_004", "Value_Int");
+ map.add_new("Source Position", "Sample Position");
+ return map;
+ }();
+ node_tree_relink_with_socket_id_map(*ntree, *node, *sample_index, sample_index_remap);
+
+ nodeAddLink(ntree,
+ sample_nearest,
+ nodeFindSocket(sample_nearest, SOCK_OUT, "Index"),
+ sample_index,
+ nodeFindSocket(sample_index, SOCK_IN, "Index"));
+ break;
+ }
+ case GEO_NODE_ATTRIBUTE_TRANSFER_INDEX: {
+ bNode *sample_index = nodeAddStaticNode(nullptr, ntree, GEO_NODE_SAMPLE_INDEX);
+ NodeGeometrySampleIndex *sample_storage = static_cast<NodeGeometrySampleIndex *>(
+ sample_index->storage);
+ sample_storage->data_type = storage->data_type;
+ sample_storage->domain = storage->domain;
+ sample_storage->clamp = 1;
+ sample_index->parent = node->parent;
+ sample_index->locx = node->locx;
+ sample_index->locy = node->locy;
+ const bool index_was_linked = nodeFindSocket(node, SOCK_IN, "Index")->link != nullptr;
+ static auto socket_remap = []() {
+ Map<std::string, std::string> map;
+ map.add_new("Attribute", "Value_Vector");
+ map.add_new("Attribute_001", "Value_Float");
+ map.add_new("Attribute_002", "Value_Color");
+ map.add_new("Attribute_003", "Value_Bool");
+ map.add_new("Attribute_004", "Value_Int");
+ map.add_new("Source", "Geometry");
+ map.add_new("Index", "Index");
+ return map;
+ }();
+ node_tree_relink_with_socket_id_map(*ntree, *node, *sample_index, socket_remap);
+
+ if (!index_was_linked) {
+ /* Add an index input node, since the new node doesn't use an implicit input. */
+ bNode *index = nodeAddStaticNode(nullptr, ntree, GEO_NODE_INPUT_INDEX);
+ index->parent = node->parent;
+ index->locx = node->locx - 25.0f;
+ index->locy = node->locy - 25.0f;
+ nodeAddLink(ntree,
+ index,
+ nodeFindSocket(index, SOCK_OUT, "Index"),
+ sample_index,
+ nodeFindSocket(sample_index, SOCK_IN, "Index"));
+ }
+ break;
+ }
+ }
+ /* The storage must be freed manually because the node type isn't defined anymore. */
+ MEM_freeN(node->storage);
+ nodeRemoveNode(nullptr, ntree, node, false);
+ }
+}
+
+void do_versions_after_linking_300(Main *bmain, ReportList * /*reports*/)
{
if (MAIN_VERSION_ATLEAST(bmain, 300, 0) && !MAIN_VERSION_ATLEAST(bmain, 300, 1)) {
/* Set zero user text objects to have a fake user. */
@@ -655,7 +837,7 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
if (!MAIN_VERSION_ATLEAST(bmain, 300, 13)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
- if (scene->ed != NULL) {
+ if (scene->ed != nullptr) {
do_versions_sequencer_speed_effect_recursive(scene, &scene->ed->seqbase);
}
}
@@ -669,24 +851,24 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
ToolSettings *tool_settings = scene->toolsettings;
ImagePaintSettings *imapaint = &tool_settings->imapaint;
- if (imapaint->canvas != NULL &&
+ if (imapaint->canvas != nullptr &&
ELEM(imapaint->canvas->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)) {
- imapaint->canvas = NULL;
+ imapaint->canvas = nullptr;
}
- if (imapaint->stencil != NULL &&
+ if (imapaint->stencil != nullptr &&
ELEM(imapaint->stencil->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)) {
- imapaint->stencil = NULL;
+ imapaint->stencil = nullptr;
}
- if (imapaint->clone != NULL &&
+ if (imapaint->clone != nullptr &&
ELEM(imapaint->clone->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)) {
- imapaint->clone = NULL;
+ imapaint->clone = nullptr;
}
}
LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
- if (brush->clone.image != NULL &&
+ if (brush->clone.image != nullptr &&
ELEM(brush->clone.image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)) {
- brush->clone.image = NULL;
+ brush->clone.image = nullptr;
}
}
}
@@ -745,20 +927,20 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
if (!MAIN_VERSION_ATLEAST(bmain, 300, 35)) {
/* Add a new modifier to realize instances from previous modifiers.
* Previously that was done automatically by geometry nodes. */
- bNodeTree *realize_instances_node_tree = NULL;
+ bNodeTree *realize_instances_node_tree = nullptr;
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
LISTBASE_FOREACH_MUTABLE (ModifierData *, md, &ob->modifiers) {
if (md->type != eModifierType_Nodes) {
continue;
}
- if (md->next == NULL) {
+ if (md->next == nullptr) {
break;
}
if (md->next->type == eModifierType_Nodes) {
continue;
}
NodesModifierData *nmd = (NodesModifierData *)md;
- if (nmd->node_group == NULL) {
+ if (nmd->node_group == nullptr) {
continue;
}
@@ -766,7 +948,7 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
STRNCPY(new_nmd->modifier.name, "Realize Instances 2.93 Legacy");
BKE_modifier_unique_name(&ob->modifiers, &new_nmd->modifier);
BLI_insertlinkafter(&ob->modifiers, md, new_nmd);
- if (realize_instances_node_tree == NULL) {
+ if (realize_instances_node_tree == nullptr) {
realize_instances_node_tree = add_realize_node_tree(bmain);
}
new_nmd->node_group = realize_instances_node_tree;
@@ -779,7 +961,7 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
if (ntree->type == NTREE_GEOMETRY) {
LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) {
if (node->type == GEO_NODE_BOUNDING_BOX) {
- bNodeSocket *geometry_socket = node->inputs.first;
+ bNodeSocket *geometry_socket = static_cast<bNodeSocket *>(node->inputs.first);
add_realize_instances_before_socket(ntree, node, geometry_socket);
}
}
@@ -792,7 +974,7 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
ID *id;
FOREACH_MAIN_ID_BEGIN (bmain, id) {
AnimData *adt = BKE_animdata_from_id(id);
- if (adt == NULL) {
+ if (adt == nullptr) {
continue;
}
LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
@@ -825,7 +1007,7 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
if (!MAIN_VERSION_ATLEAST(bmain, 302, 14)) {
/* Sequencer channels region. */
- for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
if (sl->spacetype != SPACE_SEQ) {
@@ -843,7 +1025,7 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
ARegion *timeline_region = BKE_region_find_in_listbase_by_type(regionbase,
RGN_TYPE_WINDOW);
- if (timeline_region == NULL) {
+ if (timeline_region == nullptr) {
continue;
}
@@ -857,7 +1039,7 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
if (!MAIN_VERSION_ATLEAST(bmain, 303, 5)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
Editing *ed = SEQ_editing_get(scene);
- if (ed == NULL) {
+ if (ed == nullptr) {
continue;
}
SEQ_for_each_callback(&ed->seqbase, seq_speed_factor_set, scene);
@@ -882,7 +1064,7 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
const bool is_first_space = sl == area->spacedata.first;
ListBase *regionbase = is_first_space ? &area->regionbase : &sl->regionbase;
ARegion *region = BKE_region_find_in_listbase_by_type(regionbase, RGN_TYPE_UI);
- if (region == NULL) {
+ if (region == nullptr) {
continue;
}
@@ -892,6 +1074,16 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
}
}
+ if (!MAIN_VERSION_ATLEAST(bmain, 304, 1)) {
+ /* Split the transfer attribute node into multiple smaller nodes. */
+ FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
+ if (ntree->type == NTREE_GEOMETRY) {
+ version_geometry_nodes_replace_transfer_attribute_node(ntree);
+ }
+ }
+ FOREACH_NODETREE_END;
+ }
+
/**
* Versioning code until next subversion bump goes here.
*
@@ -937,7 +1129,7 @@ static bool replace_bbone_len_scale_rnapath(char **p_old_path, int *p_index)
{
char *old_path = *p_old_path;
- if (old_path == NULL) {
+ if (old_path == nullptr) {
return false;
}
@@ -977,7 +1169,7 @@ static void do_version_bbone_len_scale_fcurve_fix(FCurve *fcu)
if (fcu->driver) {
LISTBASE_FOREACH (DriverVar *, dvar, &fcu->driver->variables) {
DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
- replace_bbone_len_scale_rnapath(&dtar->rna_path, NULL);
+ replace_bbone_len_scale_rnapath(&dtar->rna_path, nullptr);
}
DRIVER_TARGETS_LOOPER_END;
}
@@ -987,9 +1179,9 @@ static void do_version_bbone_len_scale_fcurve_fix(FCurve *fcu)
replace_bbone_len_scale_rnapath(&fcu->rna_path, &fcu->array_index);
}
-static void do_version_bbone_len_scale_animdata_cb(ID *UNUSED(id),
+static void do_version_bbone_len_scale_animdata_cb(ID * /*id*/,
AnimData *adt,
- void *UNUSED(wrapper_data))
+ void * /*wrapper_data*/)
{
LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &adt->drivers) {
do_version_bbone_len_scale_fcurve_fix(fcu);
@@ -1016,7 +1208,7 @@ static void do_version_constraints_spline_ik_joint_bindings(ListBase *lb)
LISTBASE_FOREACH (bConstraint *, con, lb) {
if (con->type == CONSTRAINT_TYPE_SPLINEIK) {
bSplineIKConstraint *data = (bSplineIKConstraint *)con->data;
- if (data->points == NULL) {
+ if (data->points == nullptr) {
data->numpoints = 0;
}
}
@@ -1037,25 +1229,25 @@ static bNodeSocket *do_version_replace_float_size_with_vector(bNodeTree *ntree,
return new_socket;
}
-static bool seq_transform_origin_set(Sequence *seq, void *UNUSED(user_data))
+static bool seq_transform_origin_set(Sequence *seq, void * /*user_data*/)
{
StripTransform *transform = seq->strip->transform;
- if (seq->strip->transform != NULL) {
+ if (seq->strip->transform != nullptr) {
transform->origin[0] = transform->origin[1] = 0.5f;
}
return true;
}
-static bool seq_transform_filter_set(Sequence *seq, void *UNUSED(user_data))
+static bool seq_transform_filter_set(Sequence *seq, void * /*user_data*/)
{
StripTransform *transform = seq->strip->transform;
- if (seq->strip->transform != NULL) {
+ if (seq->strip->transform != nullptr) {
transform->filter = SEQ_TRANSFORM_FILTER_BILINEAR;
}
return true;
}
-static bool seq_meta_channels_ensure(Sequence *seq, void *UNUSED(user_data))
+static bool seq_meta_channels_ensure(Sequence *seq, void * /*user_data*/)
{
if (seq->type == SEQ_TYPE_META) {
SEQ_channels_ensure(&seq->channels);
@@ -1079,7 +1271,7 @@ static void do_version_subsurface_methods(bNode *node)
static void version_geometry_nodes_add_attribute_input_settings(NodesModifierData *nmd)
{
- if (nmd->settings.properties == NULL) {
+ if (nmd->settings.properties == nullptr) {
return;
}
/* Before versioning the properties, make sure it hasn't been done already. */
@@ -1239,7 +1431,7 @@ static void version_geometry_nodes_set_position_node_offset(bNodeTree *ntree)
/* The offset socket didn't exist in the file yet. */
return;
}
- bNodeSocket *old_offset_socket = BLI_findlink(&node->inputs, 3);
+ bNodeSocket *old_offset_socket = static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 3));
if (old_offset_socket->type == SOCK_VECTOR) {
/* Versioning happened already. */
return;
@@ -1257,7 +1449,8 @@ static void version_geometry_nodes_set_position_node_offset(bNodeTree *ntree)
if (!STREQ(link->tosock->identifier, "Position")) {
continue;
}
- bNodeSocket *old_offset_socket = BLI_findlink(&link->tonode->inputs, 3);
+ bNodeSocket *old_offset_socket = static_cast<bNodeSocket *>(
+ BLI_findlink(&link->tonode->inputs, 3));
/* This assumes that the offset is not linked to something else. That seems to be a reasonable
* assumption, because the node is probably only ever used in one or the other mode. */
const bool offset_enabled =
@@ -1273,7 +1466,7 @@ static void version_geometry_nodes_set_position_node_offset(bNodeTree *ntree)
if (node->type != GEO_NODE_SET_POSITION) {
continue;
}
- bNodeSocket *old_offset_socket = BLI_findlink(&node->inputs, 3);
+ bNodeSocket *old_offset_socket = static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 3));
nodeRemoveSocket(ntree, node, old_offset_socket);
}
}
@@ -1299,7 +1492,7 @@ static bool version_fix_seq_meta_range(Sequence *seq, void *user_data)
return true;
}
-static bool version_merge_still_offsets(Sequence *seq, void *UNUSED(user_data))
+static bool version_merge_still_offsets(Sequence *seq, void * /*user_data*/)
{
seq->startofs -= seq->startstill;
seq->endofs -= seq->endstill;
@@ -1325,14 +1518,16 @@ static void version_liboverride_rnacollections_insertion_object_constraints(
if (opop->operation != IDOVERRIDE_LIBRARY_OP_INSERT_AFTER) {
continue;
}
- bConstraint *constraint_anchor = BLI_listbase_string_or_index_find(constraints,
- opop->subitem_local_name,
- offsetof(bConstraint, name),
- opop->subitem_local_index);
- bConstraint *constraint_src = constraint_anchor != NULL ? constraint_anchor->next :
- constraints->first;
+ bConstraint *constraint_anchor = static_cast<bConstraint *>(
+ BLI_listbase_string_or_index_find(constraints,
+ opop->subitem_local_name,
+ offsetof(bConstraint, name),
+ opop->subitem_local_index));
+ bConstraint *constraint_src = constraint_anchor != nullptr ?
+ constraint_anchor->next :
+ static_cast<bConstraint *>(constraints->first);
- if (constraint_src == NULL) {
+ if (constraint_src == nullptr) {
/* Invalid case, just remove that override property operation. */
CLOG_ERROR(&LOG, "Could not find source constraint in stored override data");
BKE_lib_override_library_property_operation_delete(op, opop);
@@ -1352,18 +1547,21 @@ static void version_liboverride_rnacollections_insertion_object(Object *object)
IDOverrideLibraryProperty *op;
op = BKE_lib_override_library_property_find(liboverride, "modifiers");
- if (op != NULL) {
+ if (op != nullptr) {
LISTBASE_FOREACH_MUTABLE (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
if (opop->operation != IDOVERRIDE_LIBRARY_OP_INSERT_AFTER) {
continue;
}
- ModifierData *mod_anchor = BLI_listbase_string_or_index_find(&object->modifiers,
- opop->subitem_local_name,
- offsetof(ModifierData, name),
- opop->subitem_local_index);
- ModifierData *mod_src = mod_anchor != NULL ? mod_anchor->next : object->modifiers.first;
+ ModifierData *mod_anchor = static_cast<ModifierData *>(
+ BLI_listbase_string_or_index_find(&object->modifiers,
+ opop->subitem_local_name,
+ offsetof(ModifierData, name),
+ opop->subitem_local_index));
+ ModifierData *mod_src = mod_anchor != nullptr ?
+ mod_anchor->next :
+ static_cast<ModifierData *>(object->modifiers.first);
- if (mod_src == NULL) {
+ if (mod_src == nullptr) {
/* Invalid case, just remove that override property operation. */
CLOG_ERROR(&LOG, "Could not find source modifier in stored override data");
BKE_lib_override_library_property_operation_delete(op, opop);
@@ -1378,21 +1576,22 @@ static void version_liboverride_rnacollections_insertion_object(Object *object)
}
op = BKE_lib_override_library_property_find(liboverride, "grease_pencil_modifiers");
- if (op != NULL) {
+ if (op != nullptr) {
LISTBASE_FOREACH_MUTABLE (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
if (opop->operation != IDOVERRIDE_LIBRARY_OP_INSERT_AFTER) {
continue;
}
- GpencilModifierData *gp_mod_anchor = BLI_listbase_string_or_index_find(
- &object->greasepencil_modifiers,
- opop->subitem_local_name,
- offsetof(GpencilModifierData, name),
- opop->subitem_local_index);
- GpencilModifierData *gp_mod_src = gp_mod_anchor != NULL ?
+ GpencilModifierData *gp_mod_anchor = static_cast<GpencilModifierData *>(
+ BLI_listbase_string_or_index_find(&object->greasepencil_modifiers,
+ opop->subitem_local_name,
+ offsetof(GpencilModifierData, name),
+ opop->subitem_local_index));
+ GpencilModifierData *gp_mod_src = gp_mod_anchor != nullptr ?
gp_mod_anchor->next :
- object->greasepencil_modifiers.first;
+ static_cast<GpencilModifierData *>(
+ object->greasepencil_modifiers.first);
- if (gp_mod_src == NULL) {
+ if (gp_mod_src == nullptr) {
/* Invalid case, just remove that override property operation. */
CLOG_ERROR(&LOG, "Could not find source GP modifier in stored override data");
BKE_lib_override_library_property_operation_delete(op, opop);
@@ -1407,18 +1606,18 @@ static void version_liboverride_rnacollections_insertion_object(Object *object)
}
op = BKE_lib_override_library_property_find(liboverride, "constraints");
- if (op != NULL) {
+ if (op != nullptr) {
version_liboverride_rnacollections_insertion_object_constraints(&object->constraints, op);
}
- if (object->pose != NULL) {
+ if (object->pose != nullptr) {
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
char rna_path[26 + (sizeof(pchan->name) * 2) + 1];
char name_esc[sizeof(pchan->name) * 2];
BLI_str_escape(name_esc, pchan->name, sizeof(name_esc));
SNPRINTF(rna_path, "pose.bones[\"%s\"].constraints", name_esc);
op = BKE_lib_override_library_property_find(liboverride, rna_path);
- if (op != NULL) {
+ if (op != nullptr) {
version_liboverride_rnacollections_insertion_object_constraints(&pchan->constraints, op);
}
}
@@ -1428,7 +1627,7 @@ static void version_liboverride_rnacollections_insertion_object(Object *object)
static void version_liboverride_rnacollections_insertion_animdata(ID *id)
{
AnimData *anim_data = BKE_animdata_from_id(id);
- if (anim_data == NULL) {
+ if (anim_data == nullptr) {
return;
}
@@ -1436,7 +1635,7 @@ static void version_liboverride_rnacollections_insertion_animdata(ID *id)
IDOverrideLibraryProperty *op;
op = BKE_lib_override_library_property_find(liboverride, "animation_data.nla_tracks");
- if (op != NULL) {
+ if (op != nullptr) {
LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
if (opop->operation != IDOVERRIDE_LIBRARY_OP_INSERT_AFTER) {
continue;
@@ -1446,7 +1645,7 @@ static void version_liboverride_rnacollections_insertion_animdata(ID *id)
*
* This makes things simple here. */
opop->subitem_reference_name = opop->subitem_local_name;
- opop->subitem_local_name = NULL;
+ opop->subitem_local_name = nullptr;
opop->subitem_reference_index = opop->subitem_local_index;
opop->subitem_local_index++;
}
@@ -1709,7 +1908,7 @@ static void versioning_replace_legacy_mix_rgb_node(bNodeTree *ntree)
node->type = SH_NODE_MIX;
NodeShaderMix *data = (NodeShaderMix *)MEM_callocN(sizeof(NodeShaderMix), __func__);
data->blend_type = node->custom1;
- data->clamp_result = node->custom2;
+ data->clamp_result = (node->custom2 & SHD_MIXRGB_CLAMP) ? 1 : 0;
data->clamp_factor = 1;
data->data_type = SOCK_RGBA;
data->factor_mode = NODE_MIX_MODE_UNIFORM;
@@ -1735,16 +1934,16 @@ static void version_fix_image_format_copy(Main *bmain, ImageFormatData *format)
}
/* Remove any invalid curves with missing data. */
- if (format->view_settings.curve_mapping->cm[0].curve == NULL) {
+ if (format->view_settings.curve_mapping->cm[0].curve == nullptr) {
BKE_curvemapping_free(format->view_settings.curve_mapping);
- format->view_settings.curve_mapping = NULL;
+ format->view_settings.curve_mapping = nullptr;
format->view_settings.flag &= ~COLORMANAGE_VIEW_USE_CURVES;
}
}
}
/* NOLINTNEXTLINE: readability-function-size */
-void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
+void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
{
/* The #SCE_SNAP_SEQ flag has been removed in favor of the #SCE_SNAP which can be used for each
* snap_flag member individually. */
@@ -1778,7 +1977,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (!DNA_struct_elem_find(fd->filesdna, "bPoseChannel", "float", "custom_scale_xyz[3]")) {
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
- if (ob->pose == NULL) {
+ if (ob->pose == nullptr) {
continue;
}
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
@@ -1798,7 +1997,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
&sl->regionbase;
ARegion *new_sidebar = do_versions_add_region_if_not_found(
regionbase, RGN_TYPE_UI, "sidebar for spreadsheet", RGN_TYPE_FOOTER);
- if (new_sidebar != NULL) {
+ if (new_sidebar != nullptr) {
new_sidebar->alignment = RGN_ALIGN_RIGHT;
new_sidebar->flag |= RGN_FLAG_HIDDEN;
}
@@ -1864,7 +2063,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
- BKE_animdata_main_cb(bmain, do_version_bbone_len_scale_animdata_cb, NULL);
+ BKE_animdata_main_cb(bmain, do_version_bbone_len_scale_animdata_cb, nullptr);
}
}
@@ -1941,7 +2140,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 300, 8)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
- if (scene->master_collection != NULL) {
+ if (scene->master_collection != nullptr) {
BLI_strncpy(scene->master_collection->id.name + 2,
BKE_SCENE_COLLECTION_NAME,
sizeof(scene->master_collection->id.name) - 2);
@@ -1995,7 +2194,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (smd->bind_verts_num && smd->verts) {
smd->mesh_verts_num = smd->bind_verts_num;
- for (unsigned int i = 0; i < smd->bind_verts_num; i++) {
+ for (uint i = 0; i < smd->bind_verts_num; i++) {
smd->verts[i].vertex_idx = i;
}
}
@@ -2138,7 +2337,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 300, 19)) {
/* Disable Fade Inactive Overlay by default as it is redundant after introducing flash on
* mode transfer. */
- for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
if (sl->spacetype == SPACE_VIEW3D) {
@@ -2209,7 +2408,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
if (!MAIN_VERSION_ATLEAST(bmain, 300, 23)) {
- for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
if (sl->spacetype == SPACE_FILE) {
@@ -2253,8 +2452,8 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
SequencerToolSettings *sequencer_tool_settings = SEQ_tool_settings_ensure(scene);
sequencer_tool_settings->pivot_point = V3D_AROUND_CENTER_MEDIAN;
- if (scene->ed != NULL) {
- SEQ_for_each_callback(&scene->ed->seqbase, seq_transform_origin_set, NULL);
+ if (scene->ed != nullptr) {
+ SEQ_for_each_callback(&scene->ed->seqbase, seq_transform_origin_set, nullptr);
}
}
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
@@ -2353,11 +2552,6 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
break;
}
- case SPACE_IMAGE: {
- SpaceImage *sima = (SpaceImage *)sl;
- sima->custom_grid_subdiv = 10;
- break;
- }
}
}
}
@@ -2366,12 +2560,12 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 300, 31)) {
/* Swap header with the tool header so the regular header is always on the edge. */
- for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
&sl->regionbase;
- ARegion *region_tool = NULL, *region_head = NULL;
+ ARegion *region_tool = nullptr, *region_head = nullptr;
int region_tool_index = -1, region_head_index = -1, i;
LISTBASE_FOREACH_INDEX (ARegion *, region, regionbase, i) {
if (region->regiontype == RGN_TYPE_TOOL_HEADER) {
@@ -2392,8 +2586,8 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
/* Set strip color tags to SEQUENCE_COLOR_NONE. */
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
- if (scene->ed != NULL) {
- SEQ_for_each_callback(&scene->ed->seqbase, do_versions_sequencer_color_tags, NULL);
+ if (scene->ed != nullptr) {
+ SEQ_for_each_callback(&scene->ed->seqbase, do_versions_sequencer_color_tags, nullptr);
}
}
@@ -2411,14 +2605,15 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
/* Set defaults for new color balance modifier parameters. */
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
- if (scene->ed != NULL) {
- SEQ_for_each_callback(&scene->ed->seqbase, do_versions_sequencer_color_balance_sop, NULL);
+ if (scene->ed != nullptr) {
+ SEQ_for_each_callback(
+ &scene->ed->seqbase, do_versions_sequencer_color_balance_sop, nullptr);
}
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 300, 33)) {
- for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
switch (sl->spacetype) {
@@ -2528,7 +2723,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->type == GEO_NODE_VIEWER) {
- if (node->storage == NULL) {
+ if (node->storage == nullptr) {
NodeGeometryViewer *data = (NodeGeometryViewer *)MEM_callocN(
sizeof(NodeGeometryViewer), __func__);
data->data_type = CD_PROP_FLOAT;
@@ -2625,7 +2820,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
* It was possible to save .blend file with incorrect state of meta strip
* range. The root cause is expected to be fixed, but need to ensure files
* with invalid meta strip range are corrected. */
- if (ed != NULL) {
+ if (ed != nullptr) {
SEQ_for_each_callback(&ed->seqbase, version_fix_seq_meta_range, scene);
}
}
@@ -2663,7 +2858,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
/* Convert float compare into a more general compare node. */
if (node->type == FN_NODE_COMPARE) {
- if (node->storage == NULL) {
+ if (node->storage == nullptr) {
NodeFunctionCompare *data = (NodeFunctionCompare *)MEM_callocN(
sizeof(NodeFunctionCompare), __func__);
data->data_type = SOCK_FLOAT;
@@ -2707,8 +2902,8 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->type == SH_NODE_MAP_RANGE) {
- if (node->storage == NULL) {
- NodeMapRange *data = MEM_callocN(sizeof(NodeMapRange), __func__);
+ if (node->storage == nullptr) {
+ NodeMapRange *data = MEM_cnew<NodeMapRange>(__func__);
data->clamp = node->custom1;
data->data_type = CD_PROP_FLOAT;
data->interpolation_type = node->custom2;
@@ -2738,7 +2933,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
/* Initialize the bone wireframe opacity setting. */
if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "bone_wire_alpha")) {
- for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
if (sl->spacetype == SPACE_VIEW3D) {
@@ -2759,7 +2954,8 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
ntree, GEO_NODE_INPUT_MESH_EDGE_ANGLE, "Angle", "Unsigned Angle");
version_node_output_socket_name(
ntree, GEO_NODE_INPUT_MESH_ISLAND, "Index", "Island Index");
- version_node_input_socket_name(ntree, GEO_NODE_TRANSFER_ATTRIBUTE, "Target", "Source");
+ version_node_input_socket_name(
+ ntree, GEO_NODE_TRANSFER_ATTRIBUTE_DEPRECATED, "Target", "Source");
}
}
}
@@ -2781,8 +2977,8 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 302, 2)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
- if (scene->ed != NULL) {
- SEQ_for_each_callback(&scene->ed->seqbase, seq_transform_filter_set, NULL);
+ if (scene->ed != nullptr) {
+ SEQ_for_each_callback(&scene->ed->seqbase, seq_transform_filter_set, nullptr);
}
}
}
@@ -2796,7 +2992,8 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
ToolSettings *tool_settings = scene->toolsettings;
- tool_settings->snap_flag_seq = tool_settings->snap_flag & ~(SCE_SNAP | SCE_SNAP_SEQ);
+ tool_settings->snap_flag_seq = tool_settings->snap_flag &
+ ~(short(SCE_SNAP) | short(SCE_SNAP_SEQ));
if (tool_settings->snap_flag & SCE_SNAP_SEQ) {
tool_settings->snap_flag_seq |= SCE_SNAP;
tool_settings->snap_flag &= ~SCE_SNAP_SEQ;
@@ -2848,9 +3045,9 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
gpmd->factor *= 2.0f;
}
else {
- gpmd->step = 1 + (int)(gpmd->factor * max_ff(0.0f,
- min_ff(5.1f * sqrtf(gpmd->step) - 3.0f,
- gpmd->step + 2.0f)));
+ gpmd->step = 1 + int(gpmd->factor * max_ff(0.0f,
+ min_ff(5.1f * sqrtf(gpmd->step) - 3.0f,
+ gpmd->step + 2.0f)));
gpmd->factor = 1.0f;
}
}
@@ -2874,7 +3071,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
LISTBASE_FOREACH (Mesh *, me, &bmain->meshes) {
for (int step = 0; step < 2; step++) {
- CustomDataLayer *actlayer = NULL;
+ CustomDataLayer *actlayer = nullptr;
int vact1, vact2;
@@ -2933,14 +3130,14 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (brush->ob_mode != OB_MODE_SCULPT_CURVES) {
continue;
}
- if (brush->curves_sculpt_settings != NULL) {
+ if (brush->curves_sculpt_settings != nullptr) {
continue;
}
- brush->curves_sculpt_settings = MEM_callocN(sizeof(BrushCurvesSculptSettings), __func__);
+ brush->curves_sculpt_settings = MEM_cnew<BrushCurvesSculptSettings>(__func__);
brush->curves_sculpt_settings->add_amount = 1;
}
- for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
if (sl->spacetype == SPACE_OUTLINER) {
@@ -2954,7 +3151,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 302, 9)) {
/* Sequencer channels region. */
- for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
if (sl->spacetype != SPACE_SEQ) {
@@ -2979,7 +3176,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
ARegion *timeline_region = BKE_region_find_in_listbase_by_type(regionbase,
RGN_TYPE_WINDOW);
- if (timeline_region != NULL) {
+ if (timeline_region != nullptr) {
timeline_region->v2d.flag |= V2D_VIEWSYNC_AREA_VERTICAL;
}
}
@@ -2989,11 +3186,11 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
/* Initialize channels. */
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
Editing *ed = SEQ_editing_get(scene);
- if (ed == NULL) {
+ if (ed == nullptr) {
continue;
}
SEQ_channels_ensure(&ed->channels);
- SEQ_for_each_callback(&scene->ed->seqbase, seq_meta_channels_ensure, NULL);
+ SEQ_for_each_callback(&scene->ed->seqbase, seq_meta_channels_ensure, nullptr);
ed->displayed_channels = &ed->channels;
@@ -3008,7 +3205,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
if (!MAIN_VERSION_ATLEAST(bmain, 302, 10)) {
- for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
if (sl->spacetype != SPACE_FILE) {
@@ -3039,7 +3236,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
/* Rebuild active/render color attribute references. */
LISTBASE_FOREACH (Mesh *, me, &bmain->meshes) {
for (int step = 0; step < 2; step++) {
- CustomDataLayer *actlayer = NULL;
+ CustomDataLayer *actlayer = nullptr;
int vact1, vact2;
@@ -3108,9 +3305,8 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (ntree->type == NTREE_GEOMETRY) {
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->type == GEO_NODE_MERGE_BY_DISTANCE) {
- if (node->storage == NULL) {
- NodeGeometryMergeByDistance *data = MEM_callocN(sizeof(NodeGeometryMergeByDistance),
- __func__);
+ if (node->storage == nullptr) {
+ NodeGeometryMergeByDistance *data = MEM_cnew<NodeGeometryMergeByDistance>(__func__);
data->mode = GEO_NODE_MERGE_BY_DISTANCE_MODE_ALL;
node->storage = data;
}
@@ -3143,7 +3339,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
BrushCurvesSculptSettings *settings = brush->curves_sculpt_settings;
- if (settings == NULL) {
+ if (settings == nullptr) {
continue;
}
if (settings->curve_length == 0.0f) {
@@ -3152,6 +3348,14 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
+ if (!DNA_struct_elem_find(fd->filesdna, "Sculpt", "float", "automasking_cavity_factor")) {
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
+ if (scene->toolsettings && scene->toolsettings->sculpt) {
+ scene->toolsettings->sculpt->automasking_cavity_factor = 0.5f;
+ }
+ }
+ }
+
if (!MAIN_VERSION_ATLEAST(bmain, 302, 14)) {
/* Compensate for previously wrong squared distance. */
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
@@ -3177,7 +3381,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
/* UDIM Packing. */
if (!DNA_struct_elem_find(fd->filesdna, "ImagePackedFile", "int", "tile_number")) {
- for (Image *ima = bmain->images.first; ima; ima = ima->id.next) {
+ LISTBASE_FOREACH (Image *, ima, &bmain->images) {
int view;
LISTBASE_FOREACH_INDEX (ImagePackedFile *, imapf, &ima->packedfiles, view) {
imapf->view = view;
@@ -3189,8 +3393,8 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
/* Merge still offsets into start/end offsets. */
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
Editing *ed = SEQ_editing_get(scene);
- if (ed != NULL) {
- SEQ_for_each_callback(&ed->seqbase, version_merge_still_offsets, NULL);
+ if (ed != nullptr) {
+ SEQ_for_each_callback(&ed->seqbase, version_merge_still_offsets, nullptr);
}
}
@@ -3296,7 +3500,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 303, 5)) {
/* Fix for T98925 - remove channels region, that was initialized in incorrect editor types. */
- for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
if (ELEM(sl->spacetype, SPACE_ACTION, SPACE_CLIP, SPACE_GRAPH, SPACE_NLA, SPACE_SEQ)) {
@@ -3335,22 +3539,11 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
BKE_main_namemap_validate_and_fix(bmain);
}
- /**
- * Versioning code until next subversion bump goes here.
- *
- * \note Be sure to check when bumping the version:
- * - "versioning_userdef.c", #blo_do_versions_userdef
- * - "versioning_userdef.c", #do_versions_theme
- *
- * \note Keep this message at the bottom of the function.
- */
- {
- /* Keep this block, even when empty. */
-
+ if (!MAIN_VERSION_ATLEAST(bmain, 304, 1)) {
/* Image generation information transferred to tiles. */
if (!DNA_struct_elem_find(fd->filesdna, "ImageTile", "int", "gen_x")) {
- for (Image *ima = bmain->images.first; ima; ima = ima->id.next) {
- for (ImageTile *tile = ima->tiles.first; tile; tile = tile->next) {
+ LISTBASE_FOREACH (Image *, ima, &bmain->images) {
+ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
tile->gen_x = ima->gen_x;
tile->gen_y = ima->gen_y;
tile->gen_type = ima->gen_type;
@@ -3362,11 +3555,133 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
/* Convert mix rgb node to new mix node and add storage. */
- {
- FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
- versioning_replace_legacy_mix_rgb_node(ntree);
+ FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
+ versioning_replace_legacy_mix_rgb_node(ntree);
+ }
+ FOREACH_NODETREE_END;
+
+ /* Face sets no longer store whether the corresponding face is hidden. */
+ LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
+ int *face_sets = (int *)CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ if (face_sets) {
+ for (int i = 0; i < mesh->totpoly; i++) {
+ face_sets[i] = abs(face_sets[i]);
+ }
+ }
+ }
+
+ /* Custom grids in UV Editor have separate X and Y divisions. */
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ switch (sl->spacetype) {
+ case SPACE_IMAGE: {
+ SpaceImage *sima = (SpaceImage *)sl;
+ sima->custom_grid_subdiv[0] = 10;
+ sima->custom_grid_subdiv[1] = 10;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 304, 2)) {
+ /* Initialize brush curves sculpt settings. */
+ LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
+ brush->automasking_cavity_factor = 0.5f;
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 304, 3)) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+ v3d->flag2 |= V3D_SHOW_VIEWER;
+ v3d->overlay.flag |= V3D_OVERLAY_VIEWER_ATTRIBUTE;
+ v3d->overlay.viewer_attribute_opacity = 1.0f;
+ }
+ if (sl->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = (SpaceImage *)sl;
+ if (sima->flag & SI_FLAG_UNUSED_18) { /* Was #SI_CUSTOM_GRID. */
+ sima->grid_shape_source = SI_GRID_SHAPE_FIXED;
+ sima->flag &= ~SI_FLAG_UNUSED_18;
+ }
+ }
+ }
+ }
+ }
+
+ LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
+ if (ntree->type != NTREE_GEOMETRY) {
+ continue;
+ }
+ version_node_id(ntree, GEO_NODE_OFFSET_POINT_IN_CURVE, "GeometryNodeOffsetPointInCurve");
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 304, 4)) {
+ /* Update brush sculpt settings. */
+ LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
+ brush->automasking_cavity_factor = 1.0f;
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 304, 5)) {
+ /* Fix for T101622 - update flags of sequence editor regions that were not initialized
+ * properly. */
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
+ &sl->regionbase;
+ if (sl->spacetype == SPACE_SEQ) {
+ LISTBASE_FOREACH (ARegion *, region, regionbase) {
+ if (region->regiontype == RGN_TYPE_TOOLS) {
+ region->v2d.flag &= ~V2D_VIEWSYNC_AREA_VERTICAL;
+ }
+ if (region->regiontype == RGN_TYPE_CHANNELS) {
+ region->v2d.flag |= V2D_VIEWSYNC_AREA_VERTICAL;
+ }
+ }
+ }
+ }
}
- FOREACH_NODETREE_END;
}
}
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 304, 6)) {
+ LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
+ if (ntree->type != NTREE_GEOMETRY) {
+ continue;
+ }
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ if (node->type != GEO_NODE_SAMPLE_CURVE) {
+ continue;
+ }
+ static_cast<NodeGeometryCurveSample *>(node->storage)->use_all_curves = true;
+ static_cast<NodeGeometryCurveSample *>(node->storage)->data_type = CD_PROP_FLOAT;
+ bNodeSocket *curve_socket = nodeFindSocket(node, SOCK_IN, "Curve");
+ BLI_assert(curve_socket != nullptr);
+ STRNCPY(curve_socket->name, "Curves");
+ STRNCPY(curve_socket->identifier, "Curves");
+ }
+ }
+ }
+
+ /**
+ * Versioning code until next subversion bump goes here.
+ *
+ * \note Be sure to check when bumping the version:
+ * - "versioning_userdef.c", #blo_do_versions_userdef
+ * - "versioning_userdef.c", #do_versions_theme
+ *
+ * \note Keep this message at the bottom of the function.
+ */
+ {
+ /* Keep this block, even when empty. */
+ }
}
diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc
new file mode 100644
index 00000000000..2616bb890a3
--- /dev/null
+++ b/source/blender/blenloader/intern/versioning_400.cc
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup blenloader
+ */
+
+#define DNA_DEPRECATED_ALLOW
+
+#include "CLG_log.h"
+
+#include "BKE_main.h"
+#include "BKE_mesh_legacy_convert.h"
+
+#include "BLO_readfile.h"
+
+#include "readfile.h"
+
+#include "versioning_common.h"
+
+// static CLG_LogRef LOG = {"blo.readfile.doversion"};
+
+static void version_mesh_legacy_to_struct_of_array_format(Mesh &mesh)
+{
+ BKE_mesh_legacy_convert_flags_to_selection_layers(&mesh);
+ BKE_mesh_legacy_convert_flags_to_hide_layers(&mesh);
+ BKE_mesh_legacy_convert_mpoly_to_material_indices(&mesh);
+ BKE_mesh_legacy_bevel_weight_to_layers(&mesh);
+ BKE_mesh_legacy_face_set_to_generic(&mesh);
+ BKE_mesh_legacy_edge_crease_to_layers(&mesh);
+}
+
+void blo_do_versions_400(FileData * /*fd*/, Library * /*lib*/, Main *bmain)
+{
+ // if (!MAIN_VERSION_ATLEAST(bmain, 400, 0)) {
+ /* This is done here because we will continue to write with the old format until 4.0, so we need
+ * to convert even "current" files. Keep the check commented out for now so the versioning isn't
+ * turned off right after the 4.0 bump. */
+ LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
+ version_mesh_legacy_to_struct_of_array_format(*mesh);
+ }
+ // }
+
+ /**
+ * Versioning code until next subversion bump goes here.
+ *
+ * \note Be sure to check when bumping the version:
+ * - "versioning_userdef.c", #blo_do_versions_userdef
+ * - "versioning_userdef.c", #do_versions_theme
+ *
+ * \note Keep this message at the bottom of the function.
+ */
+ {
+ /* Keep this block, even when empty. */
+ }
+}
diff --git a/source/blender/blenloader/intern/versioning_common.cc b/source/blender/blenloader/intern/versioning_common.cc
index 823385727e1..56ada76eae6 100644
--- a/source/blender/blenloader/intern/versioning_common.cc
+++ b/source/blender/blenloader/intern/versioning_common.cc
@@ -12,6 +12,7 @@
#include "DNA_screen_types.h"
#include "BLI_listbase.h"
+#include "BLI_map.hh"
#include "BLI_string.h"
#include "BLI_string_ref.hh"
@@ -25,6 +26,7 @@
#include "versioning_common.h"
+using blender::Map;
using blender::StringRef;
ARegion *do_versions_add_region_if_not_found(ListBase *regionbase,
@@ -234,3 +236,30 @@ ARegion *do_versions_add_region(int regiontype, const char *name)
region->regiontype = regiontype;
return region;
}
+
+void node_tree_relink_with_socket_id_map(bNodeTree &ntree,
+ bNode &old_node,
+ bNode &new_node,
+ const Map<std::string, std::string> &map)
+{
+ LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree.links) {
+ if (link->tonode == &old_node) {
+ bNodeSocket *old_socket = link->tosock;
+ if (const std::string *new_identifier = map.lookup_ptr_as(old_socket->identifier)) {
+ bNodeSocket *new_socket = nodeFindSocket(&new_node, SOCK_IN, new_identifier->c_str());
+ link->tonode = &new_node;
+ link->tosock = new_socket;
+ old_socket->link = nullptr;
+ }
+ }
+ if (link->fromnode == &old_node) {
+ bNodeSocket *old_socket = link->fromsock;
+ if (const std::string *new_identifier = map.lookup_ptr_as(old_socket->identifier)) {
+ bNodeSocket *new_socket = nodeFindSocket(&new_node, SOCK_OUT, new_identifier->c_str());
+ link->fromnode = &new_node;
+ link->fromsock = new_socket;
+ old_socket->link = nullptr;
+ }
+ }
+ }
+}
diff --git a/source/blender/blenloader/intern/versioning_common.h b/source/blender/blenloader/intern/versioning_common.h
index c8c7dcc7cff..a8844d076b3 100644
--- a/source/blender/blenloader/intern/versioning_common.h
+++ b/source/blender/blenloader/intern/versioning_common.h
@@ -6,6 +6,10 @@
#pragma once
+#ifdef __cplusplus
+# include "BLI_map.hh"
+#endif
+
struct ARegion;
struct ListBase;
struct Main;
@@ -93,3 +97,10 @@ ARegion *do_versions_add_region(int regiontype, const char *name);
#ifdef __cplusplus
}
#endif
+
+#ifdef __cplusplus
+void node_tree_relink_with_socket_id_map(bNodeTree &ntree,
+ bNode &old_node,
+ bNode &new_node,
+ const blender::Map<std::string, std::string> &map);
+#endif
diff --git a/source/blender/blenloader/intern/versioning_cycles.c b/source/blender/blenloader/intern/versioning_cycles.c
index 51063f47ef9..0a9d40e161a 100644
--- a/source/blender/blenloader/intern/versioning_cycles.c
+++ b/source/blender/blenloader/intern/versioning_cycles.c
@@ -1194,7 +1194,7 @@ static void update_voronoi_node_square_distance(bNodeTree *ntree)
NodeTexVoronoi *tex = (NodeTexVoronoi *)node->storage;
bNodeSocket *sockDistance = nodeFindSocket(node, SOCK_OUT, "Distance");
if (tex->distance == SHD_VORONOI_EUCLIDEAN &&
- (ELEM(tex->feature, SHD_VORONOI_F1, SHD_VORONOI_F2)) && socket_is_used(sockDistance)) {
+ ELEM(tex->feature, SHD_VORONOI_F1, SHD_VORONOI_F2) && socket_is_used(sockDistance)) {
bNode *multiplyNode = nodeAddStaticNode(NULL, ntree, SH_NODE_MATH);
multiplyNode->custom1 = NODE_MATH_MULTIPLY;
multiplyNode->locx = node->locx + node->width + 20.0f;
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.cc
index 06903865381..da23e9cb49f 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.cc
@@ -15,6 +15,7 @@
#include "BLI_listbase.h"
#include "BLI_math.h"
+#include "BLI_math_vec_types.hh"
#include "BLI_string.h"
#include "BLI_system.h"
#include "BLI_utildefines.h"
@@ -36,6 +37,7 @@
#include "DNA_workspace_types.h"
#include "BKE_appdir.h"
+#include "BKE_attribute.hh"
#include "BKE_brush.h"
#include "BKE_colortools.h"
#include "BKE_curveprofile.h"
@@ -119,7 +121,7 @@ static void blo_update_defaults_screen(bScreen *screen,
if (area->spacetype == SPACE_IMAGE) {
if (STREQ(workspace_name, "UV Editing")) {
- SpaceImage *sima = area->spacedata.first;
+ SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
if (sima->mode == SI_MODE_VIEW) {
sima->mode = SI_MODE_UV;
}
@@ -127,7 +129,7 @@ static void blo_update_defaults_screen(bScreen *screen,
}
else if (area->spacetype == SPACE_ACTION) {
/* Show markers region, hide channels and collapse summary in timelines. */
- SpaceAction *saction = area->spacedata.first;
+ SpaceAction *saction = static_cast<SpaceAction *>(area->spacedata.first);
saction->flag |= SACTION_SHOW_MARKERS;
if (saction->mode == SACTCONT_TIMELINE) {
saction->ads.flag |= ADS_FLAG_SUMMARY_COLLAPSED;
@@ -148,15 +150,15 @@ static void blo_update_defaults_screen(bScreen *screen,
}
}
else if (area->spacetype == SPACE_GRAPH) {
- SpaceGraph *sipo = area->spacedata.first;
+ SpaceGraph *sipo = static_cast<SpaceGraph *>(area->spacedata.first);
sipo->flag |= SIPO_SHOW_MARKERS;
}
else if (area->spacetype == SPACE_NLA) {
- SpaceNla *snla = area->spacedata.first;
+ SpaceNla *snla = static_cast<SpaceNla *>(area->spacedata.first);
snla->flag |= SNLA_SHOW_MARKERS;
}
else if (area->spacetype == SPACE_SEQ) {
- SpaceSeq *seq = area->spacedata.first;
+ SpaceSeq *seq = static_cast<SpaceSeq *>(area->spacedata.first);
seq->flag |= SEQ_SHOW_MARKERS | SEQ_ZOOM_TO_FIT | SEQ_USE_PROXIES | SEQ_SHOW_OVERLAY;
seq->render_size = SEQ_RENDER_SIZE_PROXY_100;
seq->timeline_overlay.flag |= SEQ_TIMELINE_SHOW_STRIP_SOURCE | SEQ_TIMELINE_SHOW_STRIP_NAME |
@@ -166,12 +168,12 @@ static void blo_update_defaults_screen(bScreen *screen,
}
else if (area->spacetype == SPACE_TEXT) {
/* Show syntax and line numbers in Script workspace text editor. */
- SpaceText *stext = area->spacedata.first;
+ SpaceText *stext = static_cast<SpaceText *>(area->spacedata.first);
stext->showsyntax = true;
stext->showlinenrs = true;
}
else if (area->spacetype == SPACE_VIEW3D) {
- View3D *v3d = area->spacedata.first;
+ View3D *v3d = static_cast<View3D *>(area->spacedata.first);
/* Screen space cavity by default for faster performance. */
v3d->shading.cavity_type = V3D_SHADING_CAVITY_CURVATURE;
v3d->shading.flag |= V3D_SHADING_SPECULAR_HIGHLIGHT;
@@ -195,7 +197,7 @@ static void blo_update_defaults_screen(bScreen *screen,
v3d->overlay.normals_constant_screen_size = 7.0f;
}
else if (area->spacetype == SPACE_CLIP) {
- SpaceClip *sclip = area->spacedata.first;
+ SpaceClip *sclip = static_cast<SpaceClip *>(area->spacedata.first);
sclip->around = V3D_AROUND_CENTER_MEDIAN;
sclip->mask_info.blend_factor = 0.7f;
sclip->mask_info.draw_flag = MASK_DRAWFLAG_SPLINE;
@@ -206,7 +208,9 @@ static void blo_update_defaults_screen(bScreen *screen,
const bool hide_image_tool_header = STREQ(workspace_name, "Rendering");
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
- ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase;
+ ListBase *regionbase = (sl == static_cast<SpaceLink *>(area->spacedata.first)) ?
+ &area->regionbase :
+ &sl->regionbase;
LISTBASE_FOREACH (ARegion *, region, regionbase) {
if (region->regiontype == RGN_TYPE_TOOL_HEADER) {
@@ -226,12 +230,12 @@ static void blo_update_defaults_screen(bScreen *screen,
if (app_template && STREQ(app_template, "2D_Animation")) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
if (area->spacetype == SPACE_ACTION) {
- SpaceAction *saction = area->spacedata.first;
+ SpaceAction *saction = static_cast<SpaceAction *>(area->spacedata.first);
/* Enable Sliders. */
saction->flag |= SACTION_SLIDERS;
}
else if (area->spacetype == SPACE_VIEW3D) {
- View3D *v3d = area->spacedata.first;
+ View3D *v3d = static_cast<View3D *>(area->spacedata.first);
/* Set Material Color by default. */
v3d->shading.color_type = V3D_SHADING_MATERIAL_COLOR;
/* Enable Annotations. */
@@ -252,7 +256,7 @@ void BLO_update_defaults_workspace(WorkSpace *workspace, const char *app_templat
if (blo_is_builtin_template(app_template)) {
/* Clear all tools to use default options instead, ignore the tool saved in the file. */
while (!BLI_listbase_is_empty(&workspace->tools)) {
- BKE_workspace_tool_remove(workspace, workspace->tools.first);
+ BKE_workspace_tool_remove(workspace, static_cast<bToolRef *>(workspace->tools.first));
}
/* For 2D animation template. */
@@ -268,7 +272,7 @@ void BLO_update_defaults_workspace(WorkSpace *workspace, const char *app_templat
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (area->spacetype == SPACE_VIEW3D) {
- View3D *v3d = area->spacedata.first;
+ View3D *v3d = static_cast<View3D *>(area->spacedata.first);
v3d->shading.flag &= ~V3D_SHADING_CAVITY;
copy_v3_fl(v3d->shading.single_color, 1.0f);
STRNCPY(v3d->shading.matcap, "basic_1");
@@ -296,7 +300,8 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
}
/* Rename render layers. */
- BKE_view_layer_rename(bmain, scene, scene->view_layers.first, "ViewLayer");
+ BKE_view_layer_rename(
+ bmain, scene, static_cast<ViewLayer *>(scene->view_layers.first), "ViewLayer");
/* Disable Z pass by default. */
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
@@ -308,7 +313,7 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
scene->eevee.bloom_clamp = 0.0f;
scene->eevee.motion_blur_shutter = 0.5f;
- copy_v3_v3(scene->display.light_direction, (float[3]){M_SQRT1_3, M_SQRT1_3, M_SQRT1_3});
+ copy_v3_v3(scene->display.light_direction, blender::float3(M_SQRT1_3));
copy_v2_fl2(scene->safe_areas.title, 0.1f, 0.05f);
copy_v2_fl2(scene->safe_areas.action, 0.035f, 0.035f);
@@ -344,9 +349,9 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
}
/* Correct default startup UV's. */
- Mesh *me = BLI_findstring(&bmain->meshes, "Cube", offsetof(ID, name) + 2);
+ Mesh *me = static_cast<Mesh *>(BLI_findstring(&bmain->meshes, "Cube", offsetof(ID, name) + 2));
if (me && (me->totloop == 24) && CustomData_has_layer(&me->ldata, CD_MLOOPUV)) {
- MLoopUV *mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV);
+ MLoopUV *mloopuv = static_cast<MLoopUV *>(CustomData_get_layer(&me->ldata, CD_MLOOPUV));
const float uv_values[24][2] = {
{0.625, 0.50}, {0.875, 0.50}, {0.875, 0.75}, {0.625, 0.75}, {0.375, 0.75}, {0.625, 0.75},
{0.625, 1.00}, {0.375, 1.00}, {0.375, 0.00}, {0.625, 0.00}, {0.625, 0.25}, {0.375, 0.25},
@@ -373,7 +378,7 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
{
/* For all app templates. */
- for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
+ LISTBASE_FOREACH (WorkSpace *, workspace, &bmain->workspaces) {
BLO_update_defaults_workspace(workspace, app_template);
}
@@ -389,7 +394,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
do_versions_rename_id(bmain, ID_BR, "Draw Pen", "Pen");
/* Pen Soft brush. */
- brush = (Brush *)do_versions_rename_id(bmain, ID_BR, "Draw Soft", "Pencil Soft");
+ brush = reinterpret_cast<Brush *>(
+ do_versions_rename_id(bmain, ID_BR, "Draw Soft", "Pencil Soft"));
if (brush) {
brush->gpencil_settings->icon_id = GP_BRUSH_ICON_PEN;
}
@@ -407,7 +413,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
do_versions_rename_id(bmain, ID_BR, "Draw Block", "Marker Chisel");
/* Remove useless Fill Area.001 brush. */
- brush = BLI_findstring(&bmain->brushes, "Fill Area.001", offsetof(ID, name) + 2);
+ brush = static_cast<Brush *>(
+ BLI_findstring(&bmain->brushes, "Fill Area.001", offsetof(ID, name) + 2));
if (brush) {
BKE_id_delete(bmain, brush);
}
@@ -421,21 +428,24 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
do_versions_rename_id(bmain, ID_MA, "Black Dots", "Dots Stroke");
/* Dots Stroke. */
- ma = BLI_findstring(&bmain->materials, "Dots Stroke", offsetof(ID, name) + 2);
+ ma = static_cast<Material *>(
+ BLI_findstring(&bmain->materials, "Dots Stroke", offsetof(ID, name) + 2));
if (ma == NULL) {
ma = BKE_gpencil_material_add(bmain, "Dots Stroke");
}
ma->gp_style->mode = GP_MATERIAL_MODE_DOT;
/* Squares Stroke. */
- ma = BLI_findstring(&bmain->materials, "Squares Stroke", offsetof(ID, name) + 2);
+ ma = static_cast<Material *>(
+ BLI_findstring(&bmain->materials, "Squares Stroke", offsetof(ID, name) + 2));
if (ma == NULL) {
ma = BKE_gpencil_material_add(bmain, "Squares Stroke");
}
ma->gp_style->mode = GP_MATERIAL_MODE_SQUARE;
/* Change Solid Stroke settings. */
- ma = BLI_findstring(&bmain->materials, "Solid Stroke", offsetof(ID, name) + 2);
+ ma = static_cast<Material *>(
+ BLI_findstring(&bmain->materials, "Solid Stroke", offsetof(ID, name) + 2));
if (ma != NULL) {
ma->gp_style->mix_rgba[3] = 1.0f;
ma->gp_style->texture_offset[0] = -0.5f;
@@ -443,7 +453,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
/* Change Solid Fill settings. */
- ma = BLI_findstring(&bmain->materials, "Solid Fill", offsetof(ID, name) + 2);
+ ma = static_cast<Material *>(
+ BLI_findstring(&bmain->materials, "Solid Fill", offsetof(ID, name) + 2));
if (ma != NULL) {
ma->gp_style->flag &= ~GP_MATERIAL_STROKE_SHOW;
ma->gp_style->mix_rgba[3] = 1.0f;
@@ -451,14 +462,15 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
ma->gp_style->mix_factor = 0.5f;
}
- Object *ob = BLI_findstring(&bmain->objects, "Stroke", offsetof(ID, name) + 2);
+ Object *ob = static_cast<Object *>(
+ BLI_findstring(&bmain->objects, "Stroke", offsetof(ID, name) + 2));
if (ob && ob->type == OB_GPENCIL) {
ob->dtx |= OB_USE_GPENCIL_LIGHTS;
}
}
/* Reset all grease pencil brushes. */
- Scene *scene = bmain->scenes.first;
+ Scene *scene = static_cast<Scene *>(bmain->scenes.first);
BKE_brush_gpencil_paint_presets(bmain, scene->toolsettings, true);
BKE_brush_gpencil_sculpt_presets(bmain, scene->toolsettings, true);
BKE_brush_gpencil_vertex_presets(bmain, scene->toolsettings, true);
@@ -511,7 +523,7 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
/* Scenes */
- for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
blo_update_defaults_scene(bmain, scene);
if (app_template && STREQ(app_template, "Video_Editing")) {
@@ -537,7 +549,7 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
do_versions_rename_id(bmain, ID_LA, "Lamp", "Light");
if (app_template && STREQ(app_template, "2D_Animation")) {
- for (Object *object = bmain->objects.first; object; object = object->id.next) {
+ LISTBASE_FOREACH (Object *, object, &bmain->objects) {
if (object->type == OB_GPENCIL) {
/* Set grease pencil object in drawing mode */
bGPdata *gpd = (bGPdata *)object->data;
@@ -548,7 +560,7 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
}
- for (Mesh *mesh = bmain->meshes.first; mesh; mesh = mesh->id.next) {
+ LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
/* Match default for new meshes. */
mesh->smoothresh = DEG2RADF(30);
/* Match voxel remesher options for all existing meshes in templates. */
@@ -565,22 +577,23 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
CustomData_free_layers(&mesh->vdata, CD_PAINT_MASK, mesh->totvert);
CustomData_free_layers(&mesh->ldata, CD_GRID_PAINT_MASK, mesh->totloop);
}
+ mesh->attributes_for_write().remove(".sculpt_face_set");
}
- for (Camera *camera = bmain->cameras.first; camera; camera = camera->id.next) {
+ LISTBASE_FOREACH (Camera *, camera, &bmain->cameras) {
/* Initialize to a useful value. */
camera->dof.focus_distance = 10.0f;
camera->dof.aperture_fstop = 2.8f;
}
- for (Light *light = bmain->lights.first; light; light = light->id.next) {
+ LISTBASE_FOREACH (Light *, light, &bmain->lights) {
/* Fix lights defaults. */
light->clipsta = 0.05f;
light->att_dist = 40.0f;
}
/* Materials */
- for (Material *ma = bmain->materials.first; ma; ma = ma->id.next) {
+ LISTBASE_FOREACH (Material *, ma, &bmain->materials) {
/* Update default material to be a bit more rough. */
ma->roughness = 0.5f;
@@ -588,7 +601,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
LISTBASE_FOREACH (bNode *, node, &ma->nodetree->nodes) {
if (node->type == SH_NODE_BSDF_PRINCIPLED) {
bNodeSocket *roughness_socket = nodeFindSocket(node, SOCK_IN, "Roughness");
- bNodeSocketValueFloat *roughness_data = roughness_socket->default_value;
+ bNodeSocketValueFloat *roughness_data = static_cast<bNodeSocketValueFloat *>(
+ roughness_socket->default_value);
roughness_data->value = 0.5f;
node->custom2 = SHD_SUBSURFACE_RANDOM_WALK;
BKE_ntree_update_tag_node_property(ma->nodetree, node);
@@ -606,13 +620,14 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
/* Enable for UV sculpt (other brush types will be created as needed),
* without this the grab brush will be active but not selectable from the list. */
const char *brush_name = "Grab";
- Brush *brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+ Brush *brush = static_cast<Brush *>(
+ BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2));
if (brush) {
brush->ob_mode |= OB_MODE_EDIT;
}
}
- for (Brush *brush = bmain->brushes.first; brush; brush = brush->id.next) {
+ LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
brush->blur_kernel_radius = 2;
/* Use full strength for all non-sculpt brushes,
@@ -632,13 +647,15 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
Brush *brush;
brush_name = "Smear";
- brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+ brush = static_cast<Brush *>(
+ BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2));
if (brush) {
brush->spacing = 3.0;
}
brush_name = "Draw Sharp";
- brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+ brush = static_cast<Brush *>(
+ BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2));
if (!brush) {
brush = BKE_brush_add(bmain, brush_name, OB_MODE_SCULPT);
id_us_min(&brush->id);
@@ -646,7 +663,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
brush_name = "Elastic Deform";
- brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+ brush = static_cast<Brush *>(
+ BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2));
if (!brush) {
brush = BKE_brush_add(bmain, brush_name, OB_MODE_SCULPT);
id_us_min(&brush->id);
@@ -654,7 +672,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
brush_name = "Pose";
- brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+ brush = static_cast<Brush *>(
+ BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2));
if (!brush) {
brush = BKE_brush_add(bmain, brush_name, OB_MODE_SCULPT);
id_us_min(&brush->id);
@@ -662,7 +681,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
brush_name = "Multi-plane Scrape";
- brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+ brush = static_cast<Brush *>(
+ BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2));
if (!brush) {
brush = BKE_brush_add(bmain, brush_name, OB_MODE_SCULPT);
id_us_min(&brush->id);
@@ -670,7 +690,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
brush_name = "Clay Thumb";
- brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+ brush = static_cast<Brush *>(
+ BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2));
if (!brush) {
brush = BKE_brush_add(bmain, brush_name, OB_MODE_SCULPT);
id_us_min(&brush->id);
@@ -678,7 +699,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
brush_name = "Cloth";
- brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+ brush = static_cast<Brush *>(
+ BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2));
if (!brush) {
brush = BKE_brush_add(bmain, brush_name, OB_MODE_SCULPT);
id_us_min(&brush->id);
@@ -686,7 +708,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
brush_name = "Slide Relax";
- brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+ brush = static_cast<Brush *>(
+ BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2));
if (!brush) {
brush = BKE_brush_add(bmain, brush_name, OB_MODE_SCULPT);
id_us_min(&brush->id);
@@ -694,7 +717,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
brush_name = "Paint";
- brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+ brush = static_cast<Brush *>(
+ BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2));
if (!brush) {
brush = BKE_brush_add(bmain, brush_name, OB_MODE_SCULPT);
id_us_min(&brush->id);
@@ -702,7 +726,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
brush_name = "Smear";
- brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+ brush = static_cast<Brush *>(
+ BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2));
if (!brush) {
brush = BKE_brush_add(bmain, brush_name, OB_MODE_SCULPT);
id_us_min(&brush->id);
@@ -710,7 +735,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
brush_name = "Boundary";
- brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+ brush = static_cast<Brush *>(
+ BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2));
if (!brush) {
brush = BKE_brush_add(bmain, brush_name, OB_MODE_SCULPT);
id_us_min(&brush->id);
@@ -718,7 +744,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
brush_name = "Simplify";
- brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+ brush = static_cast<Brush *>(
+ BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2));
if (!brush) {
brush = BKE_brush_add(bmain, brush_name, OB_MODE_SCULPT);
id_us_min(&brush->id);
@@ -726,7 +753,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
brush_name = "Draw Face Sets";
- brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+ brush = static_cast<Brush *>(
+ BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2));
if (!brush) {
brush = BKE_brush_add(bmain, brush_name, OB_MODE_SCULPT);
id_us_min(&brush->id);
@@ -734,7 +762,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
brush_name = "Multires Displacement Eraser";
- brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+ brush = static_cast<Brush *>(
+ BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2));
if (!brush) {
brush = BKE_brush_add(bmain, brush_name, OB_MODE_SCULPT);
id_us_min(&brush->id);
@@ -742,7 +771,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
brush_name = "Multires Displacement Smear";
- brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+ brush = static_cast<Brush *>(
+ BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2));
if (!brush) {
brush = BKE_brush_add(bmain, brush_name, OB_MODE_SCULPT);
id_us_min(&brush->id);
@@ -750,7 +780,7 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
/* Use the same tool icon color in the brush cursor */
- for (brush = bmain->brushes.first; brush; brush = brush->id.next) {
+ LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
if (brush->ob_mode & OB_MODE_SCULPT) {
BLI_assert(brush->sculpt_tool != 0);
BKE_brush_sculpt_reset(brush);
diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c
index 94438acf4fa..8685db377d4 100644
--- a/source/blender/blenloader/intern/versioning_legacy.c
+++ b/source/blender/blenloader/intern/versioning_legacy.c
@@ -58,6 +58,7 @@
#include "BKE_lattice.h"
#include "BKE_main.h" /* for Main */
#include "BKE_mesh.h" /* for ME_ defines (patching) */
+#include "BKE_mesh_legacy_convert.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_particle.h"
@@ -2531,7 +2532,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
Object *ob;
for (ob = bmain->objects.first; ob; ob = ob->id.next) {
if (ob->pd) {
- ob->pd->seed = ((uint)(ceil(PIL_check_seconds_timer())) + 1) % 128;
+ ob->pd->seed = ((uint)ceil(PIL_check_seconds_timer()) + 1) % 128;
}
}
}
diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c
index 0f3916fb114..794a6d66ae3 100644
--- a/source/blender/blenloader/intern/versioning_userdef.c
+++ b/source/blender/blenloader/intern/versioning_userdef.c
@@ -538,7 +538,7 @@ void blo_do_versions_userdef(UserDef *userdef)
}
if (!USER_VERSION_ATLEAST(280, 44)) {
- userdef->uiflag &= ~(USER_UIFLAG_UNUSED_0 | USER_UIFLAG_UNUSED_1);
+ userdef->uiflag &= ~(USER_NO_MULTITOUCH_GESTURES | USER_UIFLAG_UNUSED_1);
userdef->uiflag2 &= ~(USER_UIFLAG2_UNUSED_0);
userdef->gp_settings &= ~(GP_PAINT_UNUSED_0);
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.cc
index 72337f98000..6e48b65eb25 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.cc
@@ -55,12 +55,13 @@
* - write #USER (#UserDef struct) if filename is `~/.config/blender/X.XX/config/startup.blend`.
*/
+#include <cerrno>
+#include <climits>
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include <fcntl.h>
-#include <limits.h>
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#ifdef WIN32
# include "BLI_winstuff.h"
@@ -116,8 +117,6 @@
#include "readfile.h"
-#include <errno.h>
-
#include <zstd.h>
/* Make preferences read-only. */
@@ -126,8 +125,8 @@
/* ********* my write, buffered writing with minimum size chunks ************ */
/* Use optimal allocation since blocks of this size are kept in memory for undo. */
-#define MEM_BUFFER_SIZE (MEM_SIZE_OPTIMAL(1 << 17)) /* 128kb */
-#define MEM_CHUNK_SIZE (MEM_SIZE_OPTIMAL(1 << 15)) /* ~32kb */
+#define MEM_BUFFER_SIZE MEM_SIZE_OPTIMAL(1 << 17) /* 128kb */
+#define MEM_CHUNK_SIZE MEM_SIZE_OPTIMAL(1 << 15) /* ~32kb */
#define ZSTD_BUFFER_SIZE (1 << 21) /* 2mb */
#define ZSTD_CHUNK_SIZE (1 << 20) /* 1mb */
@@ -143,19 +142,18 @@ static CLG_LogRef LOG = {"blo.writefile"};
/** \name Internal Write Wrapper's (Abstracts Compression)
* \{ */
-typedef enum {
+enum eWriteWrapType {
WW_WRAP_NONE = 1,
WW_WRAP_ZSTD,
-} eWriteWrapType;
+};
-typedef struct ZstdFrame {
+struct ZstdFrame {
struct ZstdFrame *next, *prev;
uint32_t compressed_size;
uint32_t uncompressed_size;
-} ZstdFrame;
+};
-typedef struct WriteWrap WriteWrap;
struct WriteWrap {
/* callbacks */
bool (*open)(WriteWrap *ww, const char *filepath);
@@ -207,17 +205,17 @@ static size_t ww_write_none(WriteWrap *ww, const char *buf, size_t buf_len)
/* zstd */
-typedef struct {
- struct ZstdWriteBlockTask *next, *prev;
+struct ZstdWriteBlockTask {
+ ZstdWriteBlockTask *next, *prev;
void *data;
size_t size;
int frame_number;
WriteWrap *ww;
-} ZstdWriteBlockTask;
+};
static void *zstd_write_task(void *userdata)
{
- ZstdWriteBlockTask *task = userdata;
+ ZstdWriteBlockTask *task = static_cast<ZstdWriteBlockTask *>(userdata);
WriteWrap *ww = task->ww;
size_t out_buf_len = ZSTD_compressBound(task->size);
@@ -237,8 +235,9 @@ static void *zstd_write_task(void *userdata)
ww->zstd.write_error = true;
}
else {
- if (ww_write_none(ww, out_buf, out_size) == out_size) {
- ZstdFrame *frameinfo = MEM_mallocN(sizeof(ZstdFrame), "zstd frameinfo");
+ if (ww_write_none(ww, static_cast<const char *>(out_buf), out_size) == out_size) {
+ ZstdFrame *frameinfo = static_cast<ZstdFrame *>(
+ MEM_mallocN(sizeof(ZstdFrame), "zstd frameinfo"));
frameinfo->uncompressed_size = task->size;
frameinfo->compressed_size = out_size;
BLI_addtail(&ww->zstd.frames, frameinfo);
@@ -254,7 +253,7 @@ static void *zstd_write_task(void *userdata)
BLI_condition_notify_all(&ww->zstd.condition);
MEM_freeN(out_buf);
- return NULL;
+ return nullptr;
}
static bool ww_open_zstd(WriteWrap *ww, const char *filepath)
@@ -333,7 +332,8 @@ static size_t ww_write_zstd(WriteWrap *ww, const char *buf, size_t buf_len)
return 0;
}
- ZstdWriteBlockTask *task = MEM_mallocN(sizeof(ZstdWriteBlockTask), __func__);
+ ZstdWriteBlockTask *task = static_cast<ZstdWriteBlockTask *>(
+ MEM_mallocN(sizeof(ZstdWriteBlockTask), __func__));
task->data = MEM_mallocN(buf_len, __func__);
memcpy(task->data, buf, buf_len);
task->size = buf_len;
@@ -347,7 +347,7 @@ static size_t ww_write_zstd(WriteWrap *ww, const char *buf, size_t buf_len)
* Otherwise, we wait for the earliest thread to finish.
* We look up the earliest thread while holding the mutex, but release it
* before joining the thread to prevent a deadlock. */
- ZstdWriteBlockTask *first_task = ww->zstd.tasks.first;
+ ZstdWriteBlockTask *first_task = static_cast<ZstdWriteBlockTask *>(ww->zstd.tasks.first);
BLI_mutex_unlock(&ww->zstd.mutex);
if (!BLI_available_threads(&ww->zstd.threadpool)) {
BLI_threadpool_remove(&ww->zstd.threadpool, first_task);
@@ -393,8 +393,8 @@ static void ww_handle_init(eWriteWrapType ww_type, WriteWrap *r_ww)
/** \name Write Data Type & Functions
* \{ */
-typedef struct {
- const struct SDNA *sdna;
+struct WriteData {
+ const SDNA *sdna;
struct {
/** Use for file and memory writing (size stored in max_size). */
@@ -424,25 +424,25 @@ typedef struct {
/**
* Wrap writing, so we can use zstd or
* other compression types later, see: G_FILE_COMPRESS
- * Will be NULL for UNDO.
+ * Will be nullptr for UNDO.
*/
WriteWrap *ww;
-} WriteData;
+};
-typedef struct BlendWriter {
+struct BlendWriter {
WriteData *wd;
-} BlendWriter;
+};
static WriteData *writedata_new(WriteWrap *ww)
{
- WriteData *wd = MEM_callocN(sizeof(*wd), "writedata");
+ WriteData *wd = static_cast<WriteData *>(MEM_callocN(sizeof(*wd), "writedata"));
wd->sdna = DNA_sdna_current_get();
wd->ww = ww;
- if ((ww == NULL) || (ww->use_buf)) {
- if (ww == NULL) {
+ if ((ww == nullptr) || (ww->use_buf)) {
+ if (ww == nullptr) {
wd->buffer.max_size = MEM_BUFFER_SIZE;
wd->buffer.chunk_size = MEM_CHUNK_SIZE;
}
@@ -450,7 +450,7 @@ static WriteData *writedata_new(WriteWrap *ww)
wd->buffer.max_size = ZSTD_BUFFER_SIZE;
wd->buffer.chunk_size = ZSTD_CHUNK_SIZE;
}
- wd->buffer.buf = MEM_mallocN(wd->buffer.max_size, "wd->buffer.buf");
+ wd->buffer.buf = static_cast<uchar *>(MEM_mallocN(wd->buffer.max_size, "wd->buffer.buf"));
}
return wd;
@@ -458,7 +458,7 @@ static WriteData *writedata_new(WriteWrap *ww)
static void writedata_do_write(WriteData *wd, const void *mem, size_t memlen)
{
- if ((wd == NULL) || wd->error || (mem == NULL) || memlen < 1) {
+ if ((wd == nullptr) || wd->error || (mem == nullptr) || memlen < 1) {
return;
}
@@ -473,10 +473,10 @@ static void writedata_do_write(WriteData *wd, const void *mem, size_t memlen)
/* memory based save */
if (wd->use_memfile) {
- BLO_memfile_chunk_add(&wd->mem, mem, memlen);
+ BLO_memfile_chunk_add(&wd->mem, static_cast<const char *>(mem), memlen);
}
else {
- if (wd->ww->write(wd->ww, mem, memlen) != memlen) {
+ if (wd->ww->write(wd->ww, static_cast<const char *>(mem), memlen) != memlen) {
wd->error = true;
}
}
@@ -519,7 +519,7 @@ static void mywrite(WriteData *wd, const void *adr, size_t len)
return;
}
- if (UNLIKELY(adr == NULL)) {
+ if (UNLIKELY(adr == nullptr)) {
BLI_assert(0);
return;
}
@@ -528,7 +528,7 @@ static void mywrite(WriteData *wd, const void *adr, size_t len)
wd->write_len += len;
#endif
- if (wd->buffer.buf == NULL) {
+ if (wd->buffer.buf == nullptr) {
writedata_do_write(wd, adr, len);
}
else {
@@ -565,15 +565,15 @@ static void mywrite(WriteData *wd, const void *adr, size_t len)
/**
* BeGiN initializer for mywrite
* \param ww: File write wrapper.
- * \param compare: Previous memory file (can be NULL).
- * \param current: The current memory file (can be NULL).
+ * \param compare: Previous memory file (can be nullptr).
+ * \param current: The current memory file (can be nullptr).
* \warning Talks to other functions with global parameters
*/
static WriteData *mywrite_begin(WriteWrap *ww, MemFile *compare, MemFile *current)
{
WriteData *wd = writedata_new(ww);
- if (current != NULL) {
+ if (current != nullptr) {
BLO_memfile_write_init(&wd->mem, current, compare);
wd->use_memfile = true;
}
@@ -617,15 +617,17 @@ static void mywrite_id_begin(WriteData *wd, ID *id)
/* If current next memchunk does not match the ID we are about to write, or is not the _first_
* one for said ID, try to find the correct memchunk in the mapping using ID's session_uuid. */
MemFileChunk *curr_memchunk = wd->mem.reference_current_chunk;
- MemFileChunk *prev_memchunk = curr_memchunk != NULL ? curr_memchunk->prev : NULL;
- if (wd->mem.id_session_uuid_mapping != NULL &&
- (curr_memchunk == NULL || curr_memchunk->id_session_uuid != id->session_uuid ||
- (prev_memchunk != NULL &&
+ MemFileChunk *prev_memchunk = curr_memchunk != nullptr ?
+ static_cast<MemFileChunk *>(curr_memchunk->prev) :
+ nullptr;
+ if (wd->mem.id_session_uuid_mapping != nullptr &&
+ (curr_memchunk == nullptr || curr_memchunk->id_session_uuid != id->session_uuid ||
+ (prev_memchunk != nullptr &&
(prev_memchunk->id_session_uuid == curr_memchunk->id_session_uuid)))) {
void *ref = BLI_ghash_lookup(wd->mem.id_session_uuid_mapping,
POINTER_FROM_UINT(id->session_uuid));
- if (ref != NULL) {
- wd->mem.reference_current_chunk = ref;
+ if (ref != nullptr) {
+ wd->mem.reference_current_chunk = static_cast<MemFileChunk *>(ref);
}
/* Else, no existing memchunk found, i.e. this is supposed to be a new ID. */
}
@@ -639,7 +641,7 @@ static void mywrite_id_begin(WriteData *wd, ID *id)
*
* Only does something when storing an undo step.
*/
-static void mywrite_id_end(WriteData *wd, ID *UNUSED(id))
+static void mywrite_id_end(WriteData *wd, ID * /*id*/)
{
if (wd->use_memfile) {
/* Very important to do it after every ID write now, otherwise we cannot know whether a
@@ -662,7 +664,7 @@ static void writestruct_at_address_nr(
BLI_assert(struct_nr > 0 && struct_nr < SDNA_TYPE_MAX);
- if (adr == NULL || data == NULL || nr == 0) {
+ if (adr == nullptr || data == nullptr || nr == 0) {
return;
}
@@ -681,7 +683,7 @@ static void writestruct_at_address_nr(
}
mywrite(wd, &bh, sizeof(BHead));
- mywrite(wd, data, (size_t)bh.len);
+ mywrite(wd, data, size_t(bh.len));
}
static void writestruct_nr(
@@ -695,7 +697,7 @@ static void writedata(WriteData *wd, int filecode, size_t len, const void *adr)
{
BHead bh;
- if (adr == NULL || len == 0) {
+ if (adr == nullptr || len == 0) {
return;
}
@@ -705,14 +707,14 @@ static void writedata(WriteData *wd, int filecode, size_t len, const void *adr)
}
/* align to 4 (writes uninitialized bytes in some cases) */
- len = (len + 3) & ~((size_t)3);
+ len = (len + 3) & ~size_t(3);
/* init BHead */
bh.code = filecode;
bh.old = adr;
bh.nr = 1;
bh.SDNAnr = 0;
- bh.len = (int)len;
+ bh.len = int(len);
mywrite(wd, &bh, sizeof(BHead));
mywrite(wd, adr, len);
@@ -721,7 +723,7 @@ static void writedata(WriteData *wd, int filecode, size_t len, const void *adr)
/* use this to force writing of lists in same order as reading (using link_list) */
static void writelist_nr(WriteData *wd, int filecode, const int struct_nr, const ListBase *lb)
{
- const Link *link = lb->first;
+ const Link *link = static_cast<Link *>(lb->first);
while (link) {
writestruct_nr(wd, filecode, struct_nr, 1, link);
@@ -777,42 +779,42 @@ static void current_screen_compat(Main *mainvar,
ViewLayer **r_view_layer)
{
wmWindowManager *wm;
- wmWindow *window = NULL;
+ wmWindow *window = nullptr;
/* find a global current screen in the first open window, to have
* a reasonable default for reading in older versions */
- wm = mainvar->wm.first;
+ wm = static_cast<wmWindowManager *>(mainvar->wm.first);
if (wm) {
if (use_active_win) {
/* write the active window into the file, needed for multi-window undo T43424 */
- for (window = wm->windows.first; window; window = window->next) {
+ for (window = static_cast<wmWindow *>(wm->windows.first); window; window = window->next) {
if (window->active) {
break;
}
}
/* fallback */
- if (window == NULL) {
- window = wm->windows.first;
+ if (window == nullptr) {
+ window = static_cast<wmWindow *>(wm->windows.first);
}
}
else {
- window = wm->windows.first;
+ window = static_cast<wmWindow *>(wm->windows.first);
}
}
- *r_screen = (window) ? BKE_workspace_active_screen_get(window->workspace_hook) : NULL;
- *r_scene = (window) ? window->scene : NULL;
+ *r_screen = (window) ? BKE_workspace_active_screen_get(window->workspace_hook) : nullptr;
+ *r_scene = (window) ? window->scene : nullptr;
*r_view_layer = (window && *r_scene) ? BKE_view_layer_find(*r_scene, window->view_layer_name) :
- NULL;
+ nullptr;
}
-typedef struct RenderInfo {
+struct RenderInfo {
int sfra;
int efra;
char scene_name[MAX_ID_NAME - 2];
-} RenderInfo;
+};
/**
* This was originally added for the historic render-daemon feature,
@@ -823,7 +825,7 @@ typedef struct RenderInfo {
static void write_renderinfo(WriteData *wd, Main *mainvar)
{
bScreen *curscreen;
- Scene *curscene = NULL;
+ Scene *curscene = nullptr;
ViewLayer *view_layer;
/* XXX in future, handle multiple windows with multiple screens? */
@@ -951,7 +953,7 @@ static void write_libraries(WriteData *wd, Main *main)
else {
found_one = false;
while (!found_one && tot--) {
- for (id = lbarray[tot]->first; id; id = id->next) {
+ for (id = static_cast<ID *>(lbarray[tot]->first); id; id = static_cast<ID *>(id->next)) {
if (id->us > 0 &&
((id->tag & LIB_TAG_EXTERN) ||
((id->tag & LIB_TAG_INDIRECT) && (id->flag & LIB_INDIRECT_WEAK_LINK)))) {
@@ -970,13 +972,13 @@ static void write_libraries(WriteData *wd, Main *main)
/* Not overridable. */
void *runtime_name_data = main->curlib->runtime.name_map;
- main->curlib->runtime.name_map = NULL;
+ main->curlib->runtime.name_map = nullptr;
BlendWriter writer = {wd};
writestruct(wd, ID_LI, Library, 1, main->curlib);
BKE_id_blend_write(&writer, &main->curlib->id);
- main->curlib->runtime.name_map = runtime_name_data;
+ main->curlib->runtime.name_map = static_cast<UniqueName_Map *>(runtime_name_data);
if (main->curlib->packedfile) {
BKE_packedfile_blend_write(&writer, main->curlib->packedfile);
@@ -987,7 +989,7 @@ static void write_libraries(WriteData *wd, Main *main)
/* Write link placeholders for all direct linked IDs. */
while (a--) {
- for (id = lbarray[a]->first; id; id = id->next) {
+ for (id = static_cast<ID *>(lbarray[a]->first); id; id = static_cast<ID *>(id->next)) {
if (id->us > 0 &&
((id->tag & LIB_TAG_EXTERN) ||
((id->tag & LIB_TAG_INDIRECT) && (id->flag & LIB_INDIRECT_WEAK_LINK)))) {
@@ -1008,6 +1010,11 @@ static void write_libraries(WriteData *wd, Main *main)
mywrite_flush(wd);
}
+#ifdef WITH_BUILDINFO
+extern "C" unsigned long build_commit_timestamp;
+extern "C" char build_hash[];
+#endif
+
/* context is usually defined by WM, two cases where no WM is available:
* - for forward compatibility, curscreen has to be saved
* - for undofile, curscene needs to be saved */
@@ -1024,7 +1031,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar)
memset(fg._pad, 0, sizeof(fg._pad));
memset(fg.filepath, 0, sizeof(fg.filepath));
memset(fg.build_hash, 0, sizeof(fg.build_hash));
- fg._pad1 = NULL;
+ fg._pad1 = nullptr;
current_screen_compat(mainvar, is_undo, &screen, &scene, &view_layer);
@@ -1041,20 +1048,16 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar)
if (fileflags & G_FILE_RECOVER_WRITE) {
STRNCPY(fg.filepath, mainvar->filepath);
}
- sprintf(subvstr, "%4d", BLENDER_FILE_SUBVERSION);
+ BLI_snprintf(subvstr, sizeof(subvstr), "%4d", BLENDER_FILE_SUBVERSION);
memcpy(fg.subvstr, subvstr, 4);
fg.subversion = BLENDER_FILE_SUBVERSION;
fg.minversion = BLENDER_FILE_MIN_VERSION;
fg.minsubversion = BLENDER_FILE_MIN_SUBVERSION;
#ifdef WITH_BUILDINFO
- {
- extern unsigned long build_commit_timestamp;
- extern char build_hash[];
- /* TODO(sergey): Add branch name to file as well? */
- fg.build_commit_timestamp = build_commit_timestamp;
- BLI_strncpy(fg.build_hash, build_hash, sizeof(fg.build_hash));
- }
+ /* TODO(sergey): Add branch name to file as well? */
+ fg.build_commit_timestamp = build_commit_timestamp;
+ BLI_strncpy(fg.build_hash, build_hash, sizeof(fg.build_hash));
#else
fg.build_commit_timestamp = 0;
BLI_strncpy(fg.build_hash, "unknown", sizeof(fg.build_hash));
@@ -1099,11 +1102,12 @@ static bool write_file_handle(Main *mainvar,
wd = mywrite_begin(ww, compare, current);
BlendWriter writer = {wd};
- sprintf(buf,
- "BLENDER%c%c%.3d",
- (sizeof(void *) == 8) ? '-' : '_',
- (ENDIAN_ORDER == B_ENDIAN) ? 'V' : 'v',
- BLENDER_FILE_VERSION);
+ BLI_snprintf(buf,
+ sizeof(buf),
+ "BLENDER%c%c%.3d",
+ (sizeof(void *) == 8) ? '-' : '_',
+ (ENDIAN_ORDER == B_ENDIAN) ? 'V' : 'v',
+ BLENDER_FILE_VERSION);
mywrite(wd, buf, 12);
@@ -1116,7 +1120,7 @@ static bool write_file_handle(Main *mainvar,
mywrite_flush(wd);
OverrideLibraryStorage *override_storage = wd->use_memfile ?
- NULL :
+ nullptr :
BKE_lib_override_library_operations_store_init();
#define ID_BUFFER_STATIC_SIZE 8192
@@ -1128,9 +1132,9 @@ static bool write_file_handle(Main *mainvar,
ListBase *lbarray[INDEX_ID_MAX];
int a = set_listbasepointers(bmain, lbarray);
while (a--) {
- ID *id = lbarray[a]->first;
+ ID *id = static_cast<ID *>(lbarray[a]->first);
- if (id == NULL || GS(id->name) == ID_LI) {
+ if (id == nullptr || GS(id->name) == ID_LI) {
continue; /* Libraries are handled separately below. */
}
@@ -1148,7 +1152,7 @@ static bool write_file_handle(Main *mainvar,
id_buffer = MEM_mallocN(idtype_struct_size, __func__);
}
- for (; id; id = id->next) {
+ for (; id; id = static_cast<ID *>(id->next)) {
/* We should never attempt to write non-regular IDs
* (i.e. all kind of temp/runtime ones). */
BLI_assert(
@@ -1156,13 +1160,13 @@ static bool write_file_handle(Main *mainvar,
/* We only write unused IDs in undo case.
* NOTE: All Scenes, WindowManagers and WorkSpaces should always be written to disk, so
- * their usercount should never be NULL currently. */
+ * their user-count should never be nullptr currently. */
if (id->us == 0 && !wd->use_memfile) {
BLI_assert(!ELEM(GS(id->name), ID_SCE, ID_WM, ID_WS));
continue;
}
- const bool do_override = !ELEM(override_storage, NULL, bmain) &&
+ const bool do_override = !ELEM(override_storage, nullptr, bmain) &&
ID_IS_OVERRIDE_LIBRARY_REAL(id);
if (do_override) {
@@ -1171,19 +1175,19 @@ static bool write_file_handle(Main *mainvar,
if (wd->use_memfile) {
/* Record the changes that happened up to this undo push in
- * recalc_up_to_undo_push, and clear recalc_after_undo_push again
+ * recalc_up_to_undo_push, and clear `recalc_after_undo_push` again
* to start accumulating for the next undo push. */
id->recalc_up_to_undo_push = id->recalc_after_undo_push;
id->recalc_after_undo_push = 0;
bNodeTree *nodetree = ntreeFromID(id);
- if (nodetree != NULL) {
+ if (nodetree != nullptr) {
nodetree->id.recalc_up_to_undo_push = nodetree->id.recalc_after_undo_push;
nodetree->id.recalc_after_undo_push = 0;
}
if (GS(id->name) == ID_SCE) {
Scene *scene = (Scene *)id;
- if (scene->master_collection != NULL) {
+ if (scene->master_collection != nullptr) {
scene->master_collection->id.recalc_up_to_undo_push =
scene->master_collection->id.recalc_after_undo_push;
scene->master_collection->id.recalc_after_undo_push = 0;
@@ -1202,18 +1206,18 @@ static bool write_file_handle(Main *mainvar,
/* Those listbase data change every time we add/remove an ID, and also often when
* renaming one (due to re-sorting). This avoids generating a lot of false 'is changed'
* detections between undo steps. */
- ((ID *)id_buffer)->prev = NULL;
- ((ID *)id_buffer)->next = NULL;
+ ((ID *)id_buffer)->prev = nullptr;
+ ((ID *)id_buffer)->next = nullptr;
/* Those runtime pointers should never be set during writing stage, but just in case clear
* them too. */
- ((ID *)id_buffer)->orig_id = NULL;
- ((ID *)id_buffer)->newid = NULL;
+ ((ID *)id_buffer)->orig_id = nullptr;
+ ((ID *)id_buffer)->newid = nullptr;
/* Even though in theory we could be able to preserve this python instance across undo even
* when we need to re-read the ID into its original address, this is currently cleared in
* #direct_link_id_common in `readfile.c` anyway, */
- ((ID *)id_buffer)->py_instance = NULL;
+ ((ID *)id_buffer)->py_instance = nullptr;
- if (id_type->blend_write != NULL) {
+ if (id_type->blend_write != nullptr) {
id_type->blend_write(&writer, (ID *)id_buffer, id);
}
@@ -1234,7 +1238,7 @@ static bool write_file_handle(Main *mainvar,
if (override_storage) {
BKE_lib_override_library_operations_store_finalize(override_storage);
- override_storage = NULL;
+ override_storage = nullptr;
}
/* Special handling, operating over split Mains... */
@@ -1251,7 +1255,7 @@ static bool write_file_handle(Main *mainvar,
*
* Note that we *borrow* the pointer to 'DNAstr',
* so writing each time uses the same address and doesn't cause unnecessary undo overhead. */
- writedata(wd, DNA1, (size_t)wd->sdna->data_len, wd->sdna->data);
+ writedata(wd, DNA1, size_t(wd->sdna->data_len), wd->sdna->data);
/* end of file */
memset(&bhead, 0, sizeof(BHead));
@@ -1331,11 +1335,11 @@ bool BLO_write_file(Main *mainvar,
const bool relbase_valid = (mainvar->filepath[0] != '\0');
/* path backup/restore */
- void *path_list_backup = NULL;
+ void *path_list_backup = nullptr;
const eBPathForeachFlag path_list_flag = (BKE_BPATH_FOREACH_PATH_SKIP_LINKED |
BKE_BPATH_FOREACH_PATH_SKIP_MULTIFILE);
- if (G.debug & G_DEBUG_IO && mainvar->lock != NULL) {
+ if (G.debug & G_DEBUG_IO && mainvar->lock != nullptr) {
BKE_report(reports, RPT_INFO, "Checking sanity of current .blend file *BEFORE* save to disk");
BLO_main_validate_libraries(mainvar, reports);
BLO_main_validate_shapekeys(mainvar, reports);
@@ -1375,13 +1379,13 @@ bool BLO_write_file(Main *mainvar,
/* Normalize the paths in case there is some subtle difference (so they can be compared). */
if (relbase_valid) {
BLI_split_dir_part(mainvar->filepath, dir_src, sizeof(dir_src));
- BLI_path_normalize(NULL, dir_src);
+ BLI_path_normalize(nullptr, dir_src);
}
else {
dir_src[0] = '\0';
}
BLI_split_dir_part(filepath, dir_dst, sizeof(dir_dst));
- BLI_path_normalize(NULL, dir_dst);
+ BLI_path_normalize(nullptr, dir_dst);
/* Only for relative, not relative-all, as this means making existing paths relative. */
if (remap_mode == BLO_WRITE_PATH_REMAP_RELATIVE) {
@@ -1415,16 +1419,16 @@ bool BLO_write_file(Main *mainvar,
case BLO_WRITE_PATH_REMAP_RELATIVE:
/* Saved, make relative paths relative to new location (if possible). */
BLI_assert(relbase_valid);
- BKE_bpath_relative_rebase(mainvar, dir_src, dir_dst, NULL);
+ BKE_bpath_relative_rebase(mainvar, dir_src, dir_dst, nullptr);
break;
case BLO_WRITE_PATH_REMAP_RELATIVE_ALL:
/* Make all relative (when requested or unsaved). */
- BKE_bpath_relative_convert(mainvar, dir_dst, NULL);
+ BKE_bpath_relative_convert(mainvar, dir_dst, nullptr);
break;
case BLO_WRITE_PATH_REMAP_ABSOLUTE:
/* Make all absolute (when requested or unsaved). */
BLI_assert(relbase_valid);
- BKE_bpath_absolute_convert(mainvar, dir_src, NULL);
+ BKE_bpath_absolute_convert(mainvar, dir_src, nullptr);
break;
case BLO_WRITE_PATH_REMAP_NONE:
BLI_assert_unreachable(); /* Unreachable. */
@@ -1436,7 +1440,8 @@ bool BLO_write_file(Main *mainvar,
}
/* actual file writing */
- const bool err = write_file_handle(mainvar, &ww, NULL, NULL, write_flags, use_userdef, thumb);
+ const bool err = write_file_handle(
+ mainvar, &ww, nullptr, nullptr, write_flags, use_userdef, thumb);
ww.close(&ww);
@@ -1467,7 +1472,7 @@ bool BLO_write_file(Main *mainvar,
return false;
}
- if (G.debug & G_DEBUG_IO && mainvar->lock != NULL) {
+ if (G.debug & G_DEBUG_IO && mainvar->lock != nullptr) {
BKE_report(reports, RPT_INFO, "Checking sanity of current .blend file *AFTER* save to disk");
BLO_main_validate_libraries(mainvar, reports);
}
@@ -1480,7 +1485,7 @@ bool BLO_write_file_mem(Main *mainvar, MemFile *compare, MemFile *current, int w
bool use_userdef = false;
const bool err = write_file_handle(
- mainvar, NULL, compare, current, write_flags, use_userdef, NULL);
+ mainvar, nullptr, compare, current, write_flags, use_userdef, nullptr);
return (err == 0);
}
@@ -1569,37 +1574,37 @@ int BLO_get_struct_id_by_name(BlendWriter *writer, const char *struct_name)
void BLO_write_int32_array(BlendWriter *writer, uint num, const int32_t *data_ptr)
{
- BLO_write_raw(writer, sizeof(int32_t) * (size_t)num, data_ptr);
+ BLO_write_raw(writer, sizeof(int32_t) * size_t(num), data_ptr);
}
void BLO_write_uint32_array(BlendWriter *writer, uint num, const uint32_t *data_ptr)
{
- BLO_write_raw(writer, sizeof(uint32_t) * (size_t)num, data_ptr);
+ BLO_write_raw(writer, sizeof(uint32_t) * size_t(num), data_ptr);
}
void BLO_write_float_array(BlendWriter *writer, uint num, const float *data_ptr)
{
- BLO_write_raw(writer, sizeof(float) * (size_t)num, data_ptr);
+ BLO_write_raw(writer, sizeof(float) * size_t(num), data_ptr);
}
void BLO_write_double_array(BlendWriter *writer, uint num, const double *data_ptr)
{
- BLO_write_raw(writer, sizeof(double) * (size_t)num, data_ptr);
+ BLO_write_raw(writer, sizeof(double) * size_t(num), data_ptr);
}
void BLO_write_pointer_array(BlendWriter *writer, uint num, const void *data_ptr)
{
- BLO_write_raw(writer, sizeof(void *) * (size_t)num, data_ptr);
+ BLO_write_raw(writer, sizeof(void *) * size_t(num), data_ptr);
}
void BLO_write_float3_array(BlendWriter *writer, uint num, const float *data_ptr)
{
- BLO_write_raw(writer, sizeof(float[3]) * (size_t)num, data_ptr);
+ BLO_write_raw(writer, sizeof(float[3]) * size_t(num), data_ptr);
}
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
{
- if (data_ptr != NULL) {
+ if (data_ptr != nullptr) {
BLO_write_raw(writer, strlen(data_ptr) + 1, data_ptr);
}
}
diff --git a/source/blender/blenloader/tests/blendfile_loading_base_test.cc b/source/blender/blenloader/tests/blendfile_loading_base_test.cc
index 7df0ce944e4..b657970d45f 100644
--- a/source/blender/blenloader/tests/blendfile_loading_base_test.cc
+++ b/source/blender/blenloader/tests/blendfile_loading_base_test.cc
@@ -11,6 +11,7 @@
#include "BKE_global.h"
#include "BKE_idtype.h"
#include "BKE_image.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_mball_tessellate.h"
#include "BKE_modifier.h"
@@ -116,7 +117,7 @@ bool BlendfileLoadingBaseTest::blendfile_load(const char *filepath)
}
char abspath[FILENAME_MAX];
- BLI_path_join(abspath, sizeof(abspath), test_assets_dir.c_str(), filepath, nullptr);
+ BLI_path_join(abspath, sizeof(abspath), test_assets_dir.c_str(), filepath);
BlendFileReadReport bf_reports = {nullptr};
bfile = BLO_read_from_file(abspath, BLO_READ_SKIP_NONE, &bf_reports);
@@ -125,6 +126,13 @@ bool BlendfileLoadingBaseTest::blendfile_load(const char *filepath)
<< test_assets_dir << "'";
return false;
}
+
+ /* Make sure that all view_layers in the file are synced. Depsgraph can make a copy of the whole
+ * scene, which will fail when one view layer isn't synced. */
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &bfile->curscene->view_layers) {
+ BKE_view_layer_synced_ensure(bfile->curscene, view_layer);
+ }
+
return true;
}
diff --git a/source/blender/blentranslation/BLT_translation.h b/source/blender/blentranslation/BLT_translation.h
index 129eba3de2f..a4554c4e0bd 100644
--- a/source/blender/blentranslation/BLT_translation.h
+++ b/source/blender/blentranslation/BLT_translation.h
@@ -74,7 +74,7 @@ const char *BLT_translate_do_new_dataname(const char *msgctxt, const char *msgid
#define BLT_I18NCONTEXT_UI_EVENTS "UI_Events_KeyMaps"
/* Mark the msgid applies to several elements
- * (needed in some cases, as english adjectives have no plural mark :( ). */
+ * (needed in some cases, as English adjectives have no plural mark :( ). */
#define BLT_I18NCONTEXT_PLURAL "Plural"
/* ID-types contexts. */
diff --git a/source/blender/blentranslation/intern/blt_lang.c b/source/blender/blentranslation/intern/blt_lang.c
index cb04b3ac0dc..b8523f289c7 100644
--- a/source/blender/blentranslation/intern/blt_lang.c
+++ b/source/blender/blentranslation/intern/blt_lang.c
@@ -72,7 +72,7 @@ static void fill_locales(void)
free_locales();
- BLI_join_dirfile(languages, FILE_MAX, languages_path, "languages");
+ BLI_path_join(languages, FILE_MAX, languages_path, "languages");
line = lines = BLI_file_read_as_lines(languages);
/* This whole "parsing" code is a bit weak, in that it expects strictly formatted input file...
@@ -263,7 +263,6 @@ void BLT_lang_set(const char *str)
#else
(void)str;
#endif
- IMB_thumb_clear_translations();
}
const char *BLT_lang_get(void)
diff --git a/source/blender/blentranslation/msgfmt/CMakeLists.txt b/source/blender/blentranslation/msgfmt/CMakeLists.txt
index 7b95bf210d7..dce3f0014f0 100644
--- a/source/blender/blentranslation/msgfmt/CMakeLists.txt
+++ b/source/blender/blentranslation/msgfmt/CMakeLists.txt
@@ -4,7 +4,7 @@
# -----------------------------------------------------------------------------
# Build msgfmt executable
-blender_include_dirs(
+set(INC
../../../../intern/guardedalloc
../../blenlib
)
@@ -13,21 +13,20 @@ set(SRC
msgfmt.c
)
+set(LIB
+ bf_blenlib
+ bf_intern_guardedalloc
+ ${ZLIB_LIBRARIES}
+ ${PLATFORM_LINKLIBS})
+
add_cc_flags_custom_test(msgfmt)
if(WIN32)
string(APPEND CMAKE_EXE_LINKER_FLAGS_DEBUG " /nodefaultlib:MSVCRT.lib")
+ list(APPEND LIB bf_intern_utfconv)
endif()
add_executable(msgfmt ${SRC})
setup_platform_linker_flags(msgfmt)
-
-target_link_libraries(msgfmt bf_blenlib)
-target_link_libraries(msgfmt bf_intern_guardedalloc)
-
-if(WIN32)
- target_link_libraries(msgfmt bf_intern_utfconv)
-endif()
-
-target_link_libraries(msgfmt ${ZLIB_LIBRARIES})
-target_link_libraries(msgfmt ${PLATFORM_LINKLIBS})
+blender_target_include_dirs(msgfmt ${INC})
+target_link_libraries(msgfmt ${LIB})
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index 0efa5f73ae4..77223ecd1c7 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -207,6 +207,22 @@ if(WITH_GMP)
)
endif()
+if(WITH_TBB)
+ add_definitions(-DWITH_TBB)
+ if(WIN32)
+ # TBB includes Windows.h which will define min/max macros
+ # that will collide with the stl versions.
+ add_definitions(-DNOMINMAX)
+ endif()
+ list(APPEND INC_SYS
+ ${TBB_INCLUDE_DIRS}
+ )
+
+ list(APPEND LIB
+ ${TBB_LIBRARIES}
+ )
+endif()
+
blender_add_lib(bf_bmesh "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
if(MSVC AND NOT MSVC_CLANG)
diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h
index 2833105e5a4..3956db0288a 100644
--- a/source/blender/bmesh/bmesh.h
+++ b/source/blender/bmesh/bmesh.h
@@ -148,7 +148,7 @@
*
* These conventions should be used throughout the bmesh module.
*
- * - `bmesh_kernel_*()` - Low level API, for primitive functions that others are built ontop of.
+ * - `bmesh_kernel_*()` - Low level API, for primitive functions that others are built on top of.
* - `bmesh_***()` - Low level API function.
* - `bm_***()` - 'static' functions, not a part of the API at all,
* but use prefix since they operate on BMesh data.
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index 757d006b04d..cff8eb5a2f7 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -21,8 +21,6 @@
#include "bmesh.h"
#include "intern/bmesh_private.h"
-#define SELECT 1
-
bool BM_verts_from_edges(BMVert **vert_arr, BMEdge **edge_arr, const int len)
{
int i, i_prev = len - 1;
@@ -507,42 +505,40 @@ void BM_mesh_copy_init_customdata_from_mesh_array(BMesh *bm_dst,
allocsize = &bm_mesh_allocsize_default;
}
- char cd_flag = 0;
-
for (int i = 0; i < me_src_array_len; i++) {
const Mesh *me_src = me_src_array[i];
+ CustomData mesh_vdata = CustomData_shallow_copy_remove_non_bmesh_attributes(
+ &me_src->vdata, CD_MASK_BMESH.vmask);
+ CustomData mesh_edata = CustomData_shallow_copy_remove_non_bmesh_attributes(
+ &me_src->edata, CD_MASK_BMESH.emask);
+ CustomData mesh_pdata = CustomData_shallow_copy_remove_non_bmesh_attributes(
+ &me_src->pdata, CD_MASK_BMESH.lmask);
+ CustomData mesh_ldata = CustomData_shallow_copy_remove_non_bmesh_attributes(
+ &me_src->ldata, CD_MASK_BMESH.pmask);
+
if (i == 0) {
- CustomData_copy_mesh_to_bmesh(
- &me_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0);
- CustomData_copy_mesh_to_bmesh(
- &me_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0);
- CustomData_copy_mesh_to_bmesh(
- &me_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0);
- CustomData_copy_mesh_to_bmesh(
- &me_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0);
+ CustomData_copy(&mesh_vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0);
+ CustomData_copy(&mesh_edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0);
+ CustomData_copy(&mesh_pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0);
+ CustomData_copy(&mesh_ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0);
}
else {
- CustomData_merge_mesh_to_bmesh(
- &me_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0);
- CustomData_merge_mesh_to_bmesh(
- &me_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0);
- CustomData_merge_mesh_to_bmesh(
- &me_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0);
- CustomData_merge_mesh_to_bmesh(
- &me_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0);
+ CustomData_merge(&mesh_vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0);
+ CustomData_merge(&mesh_edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0);
+ CustomData_merge(&mesh_pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0);
+ CustomData_merge(&mesh_ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0);
}
- cd_flag |= me_src->cd_flag;
+ MEM_SAFE_FREE(mesh_vdata.layers);
+ MEM_SAFE_FREE(mesh_edata.layers);
+ MEM_SAFE_FREE(mesh_pdata.layers);
+ MEM_SAFE_FREE(mesh_ldata.layers);
}
- cd_flag |= BM_mesh_cd_flag_from_bmesh(bm_dst);
-
CustomData_bmesh_init_pool(&bm_dst->vdata, allocsize->totvert, BM_VERT);
CustomData_bmesh_init_pool(&bm_dst->edata, allocsize->totedge, BM_EDGE);
CustomData_bmesh_init_pool(&bm_dst->ldata, allocsize->totloop, BM_LOOP);
CustomData_bmesh_init_pool(&bm_dst->pdata, allocsize->totface, BM_FACE);
-
- BM_mesh_cd_flag_apply(bm_dst, cd_flag);
}
void BM_mesh_copy_init_customdata_from_mesh(BMesh *bm_dst,
@@ -720,43 +716,27 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
return bm_new;
}
-char BM_vert_flag_from_mflag(const char mflag)
-{
- return ((mflag & SELECT) ? BM_ELEM_SELECT : 0);
-}
char BM_edge_flag_from_mflag(const short mflag)
{
- return (((mflag & SELECT) ? BM_ELEM_SELECT : 0) | ((mflag & ME_SEAM) ? BM_ELEM_SEAM : 0) |
- ((mflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0) |
+ return (((mflag & ME_SEAM) ? BM_ELEM_SEAM : 0) | ((mflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0) |
((mflag & ME_SHARP) == 0 ? BM_ELEM_SMOOTH : 0));
}
char BM_face_flag_from_mflag(const char mflag)
{
- return (((mflag & ME_FACE_SEL) ? BM_ELEM_SELECT : 0) |
- ((mflag & ME_SMOOTH) ? BM_ELEM_SMOOTH : 0));
-}
-
-char BM_vert_flag_to_mflag(BMVert *v)
-{
- const char hflag = v->head.hflag;
-
- return (((hflag & BM_ELEM_SELECT) ? SELECT : 0));
+ return ((mflag & ME_SMOOTH) ? BM_ELEM_SMOOTH : 0);
}
short BM_edge_flag_to_mflag(BMEdge *e)
{
const char hflag = e->head.hflag;
- return (((hflag & BM_ELEM_SELECT) ? SELECT : 0) | ((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) |
- ((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0) |
+ return (((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) | ((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0) |
((hflag & BM_ELEM_SMOOTH) == 0 ? ME_SHARP : 0) |
- (BM_edge_is_wire(e) ? ME_LOOSEEDGE : 0) | /* not typical */
- ME_EDGERENDER);
+ (BM_edge_is_wire(e) ? ME_LOOSEEDGE : 0));
}
char BM_face_flag_to_mflag(BMFace *f)
{
const char hflag = f->head.hflag;
- return (((hflag & BM_ELEM_SELECT) ? ME_FACE_SEL : 0) |
- ((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0));
+ return ((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0);
}
diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h
index 1851cf58d4e..225e15c90e9 100644
--- a/source/blender/bmesh/intern/bmesh_construct.h
+++ b/source/blender/bmesh/intern/bmesh_construct.h
@@ -169,8 +169,5 @@ BMesh *BM_mesh_copy(BMesh *bm_old);
char BM_face_flag_from_mflag(char mflag);
char BM_edge_flag_from_mflag(short mflag);
/* ME -> BM */
-char BM_vert_flag_from_mflag(char mflag);
char BM_face_flag_to_mflag(BMFace *f);
short BM_edge_flag_to_mflag(BMEdge *e);
-/* BM -> ME */
-char BM_vert_flag_to_mflag(BMVert *v);
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 4d84d558cd7..5fbbd087d7e 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -95,7 +95,7 @@ BMVert *BM_vert_create(BMesh *bm,
/* handles 'v->no' too */
BM_elem_attrs_copy(bm, bm, v_example, v);
- /* exception: don't copy the original shapekey index */
+ /* Exception: don't copy the original shape-key index. */
keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX);
if (keyi) {
*keyi = ORIGINDEX_NONE;
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index 64e6c63e9f0..a8a9390f525 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -288,7 +288,8 @@ static void bm_log_verts_restore(BMesh *bm, BMLog *log, GHash *verts)
static void bm_log_faces_restore(BMesh *bm, BMLog *log, GHash *faces)
{
GHashIterator gh_iter;
- const int cd_face_sets = CustomData_get_offset(&bm->pdata, CD_SCULPT_FACE_SETS);
+ const int cd_face_sets = CustomData_get_offset_named(
+ &bm->pdata, CD_PROP_INT32, ".sculpt_face_set");
GHASH_ITER (gh_iter, faces) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
@@ -1002,3 +1003,31 @@ void bm_log_print(const BMLog *log, const char *description)
}
}
#endif
+
+void BM_log_print_entry(BMesh *bm, BMLogEntry *entry)
+{
+ if (bm) {
+ printf("BM { totvert=%d totedge=%d totloop=%d totpoly=%d\n",
+ bm->totvert,
+ bm->totedge,
+ bm->totloop,
+ bm->totface);
+
+ if (!bm->totvert) {
+ printf("%s: Warning: empty bmesh\n", __func__);
+ }
+ }
+ else {
+ printf("BM { totvert=unknown totedge=unknown totloop=unknown totpoly=unknown\n");
+ }
+
+ printf("v | added: %d, removed: %d, modified: %d\n",
+ (int)BLI_ghash_len(entry->added_verts),
+ (int)BLI_ghash_len(entry->deleted_verts),
+ (int)BLI_ghash_len(entry->modified_verts));
+ printf("f | added: %d, removed: %d, modified: %d\n",
+ (int)BLI_ghash_len(entry->added_faces),
+ (int)BLI_ghash_len(entry->deleted_faces),
+ (int)BLI_ghash_len(entry->modified_faces));
+ printf("}\n");
+}
diff --git a/source/blender/bmesh/intern/bmesh_log.h b/source/blender/bmesh/intern/bmesh_log.h
index 5daa5dd9a68..8c9db9c66e7 100644
--- a/source/blender/bmesh/intern/bmesh_log.h
+++ b/source/blender/bmesh/intern/bmesh_log.h
@@ -22,7 +22,7 @@ BMLog *BM_log_create(BMesh *bm);
/**
* Allocate and initialize a new #BMLog using existing #BMLogEntries
*
- * The 'entry' should be the last entry in the BMLog. Its prev pointer
+ * The 'entry' should be the last entry in the #BMLog. Its `prev` pointer
* will be followed back to find the first entry.
*
* The unused IDs field of the log will be initialized by taking all
@@ -206,3 +206,5 @@ void BM_log_original_vert_data(BMLog *log, BMVert *v, const float **r_co, const
BMLogEntry *BM_log_current_entry(BMLog *log);
/** For internal use only (unit testing) */
struct RangeTreeUInt *BM_log_unused_ids(BMLog *log);
+
+void BM_log_print_entry(BMesh *bm, BMLogEntry *entry);
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index f348cd58085..a1c2815ab2f 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -1020,7 +1020,7 @@ static BMEditSelection *bm_select_history_create(BMHeader *ele)
return ese;
}
-/* --- macro wrapped funcs --- */
+/* --- Macro wrapped functions. --- */
bool _bm_select_history_check(BMesh *bm, const BMHeader *ele)
{
@@ -1075,7 +1075,7 @@ void _bm_select_history_store_after(BMesh *bm, BMEditSelection *ese_ref, BMHeade
BM_select_history_store_after_notest(bm, ese_ref, (BMElem *)ele);
}
}
-/* --- end macro wrapped funcs --- */
+/* --- End macro wrapped functions --- */
void BM_select_history_clear(BMesh *bm)
{
diff --git a/source/blender/bmesh/intern/bmesh_mesh.cc b/source/blender/bmesh/intern/bmesh_mesh.cc
index 4f42ce4a470..5c8f32b9bfa 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.cc
+++ b/source/blender/bmesh/intern/bmesh_mesh.cc
@@ -269,7 +269,7 @@ void BM_mesh_free(BMesh *bm)
MEM_freeN(bm);
}
-void bmesh_edit_begin(BMesh *UNUSED(bm), BMOpTypeFlag UNUSED(type_flag))
+void bmesh_edit_begin(BMesh * /*bm*/, BMOpTypeFlag /*type_flag*/)
{
/* Most operators seem to be using BMO_OPTYPE_FLAG_UNTAN_MULTIRES to change the MDisps to
* absolute space during mesh edits. With this enabled, changes to the topology
diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc
index 94440916603..d65cac08db8 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc
+++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc
@@ -110,57 +110,6 @@ using blender::MutableSpan;
using blender::Span;
using blender::StringRef;
-void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag)
-{
- const char cd_flag_all = BM_mesh_cd_flag_from_bmesh(bm) | cd_flag;
- BM_mesh_cd_flag_apply(bm, cd_flag_all);
- if (mesh) {
- mesh->cd_flag = cd_flag_all;
- }
-}
-
-void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag)
-{
- /* CustomData_bmesh_init_pool() must run first */
- BLI_assert(bm->vdata.totlayer == 0 || bm->vdata.pool != nullptr);
- BLI_assert(bm->edata.totlayer == 0 || bm->edata.pool != nullptr);
- BLI_assert(bm->pdata.totlayer == 0 || bm->pdata.pool != nullptr);
-
- if (cd_flag & ME_CDFLAG_VERT_CREASE) {
- if (!CustomData_has_layer(&bm->vdata, CD_CREASE)) {
- BM_data_layer_add(bm, &bm->vdata, CD_CREASE);
- }
- }
- else {
- if (CustomData_has_layer(&bm->vdata, CD_CREASE)) {
- BM_data_layer_free(bm, &bm->vdata, CD_CREASE);
- }
- }
-
- if (cd_flag & ME_CDFLAG_EDGE_CREASE) {
- if (!CustomData_has_layer(&bm->edata, CD_CREASE)) {
- BM_data_layer_add(bm, &bm->edata, CD_CREASE);
- }
- }
- else {
- if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
- BM_data_layer_free(bm, &bm->edata, CD_CREASE);
- }
- }
-}
-
-char BM_mesh_cd_flag_from_bmesh(BMesh *bm)
-{
- char cd_flag = 0;
- if (CustomData_has_layer(&bm->vdata, CD_CREASE)) {
- cd_flag |= ME_CDFLAG_VERT_CREASE;
- }
- if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
- cd_flag |= ME_CDFLAG_EDGE_CREASE;
- }
- return cd_flag;
-}
-
/* Static function for alloc (duplicate in modifiers_bmesh.c) */
static BMFace *bm_face_create_from_mpoly(BMesh &bm,
Span<MLoop> loops,
@@ -180,6 +129,10 @@ static BMFace *bm_face_create_from_mpoly(BMesh &bm,
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params)
{
+ if (!me) {
+ /* Sanity check. */
+ return;
+ }
const bool is_new = !(bm->totvert || (bm->vdata.totlayer || bm->edata.totlayer ||
bm->pdata.totlayer || bm->ldata.totlayer));
KeyBlock *actkey;
@@ -187,19 +140,35 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
CustomData_MeshMasks mask = CD_MASK_BMESH;
CustomData_MeshMasks_update(&mask, &params->cd_mask_extra);
- if (!me || !me->totvert) {
- if (me && is_new) { /* No verts? still copy custom-data layout. */
- CustomData_copy_mesh_to_bmesh(&me->vdata, &bm->vdata, mask.vmask, CD_CONSTRUCT, 0);
- CustomData_copy_mesh_to_bmesh(&me->edata, &bm->edata, mask.emask, CD_CONSTRUCT, 0);
- CustomData_copy_mesh_to_bmesh(&me->ldata, &bm->ldata, mask.lmask, CD_CONSTRUCT, 0);
- CustomData_copy_mesh_to_bmesh(&me->pdata, &bm->pdata, mask.pmask, CD_CONSTRUCT, 0);
+ CustomData mesh_vdata = CustomData_shallow_copy_remove_non_bmesh_attributes(&me->vdata,
+ mask.vmask);
+ CustomData mesh_edata = CustomData_shallow_copy_remove_non_bmesh_attributes(&me->edata,
+ mask.emask);
+ CustomData mesh_pdata = CustomData_shallow_copy_remove_non_bmesh_attributes(&me->pdata,
+ mask.pmask);
+ CustomData mesh_ldata = CustomData_shallow_copy_remove_non_bmesh_attributes(&me->ldata,
+ mask.lmask);
+ BLI_SCOPED_DEFER([&]() {
+ MEM_SAFE_FREE(mesh_vdata.layers);
+ MEM_SAFE_FREE(mesh_edata.layers);
+ MEM_SAFE_FREE(mesh_pdata.layers);
+ MEM_SAFE_FREE(mesh_ldata.layers);
+ });
+
+ if (me->totvert == 0) {
+ if (is_new) {
+ /* No verts? still copy custom-data layout. */
+ CustomData_copy(&mesh_vdata, &bm->vdata, mask.vmask, CD_CONSTRUCT, 0);
+ CustomData_copy(&mesh_edata, &bm->edata, mask.emask, CD_CONSTRUCT, 0);
+ CustomData_copy(&mesh_pdata, &bm->pdata, mask.pmask, CD_CONSTRUCT, 0);
+ CustomData_copy(&mesh_ldata, &bm->ldata, mask.lmask, CD_CONSTRUCT, 0);
CustomData_bmesh_init_pool(&bm->vdata, me->totvert, BM_VERT);
CustomData_bmesh_init_pool(&bm->edata, me->totedge, BM_EDGE);
CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP);
CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE);
}
- return; /* Sanity check. */
+ return;
}
const float(*vert_normals)[3] = nullptr;
@@ -208,16 +177,16 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
}
if (is_new) {
- CustomData_copy_mesh_to_bmesh(&me->vdata, &bm->vdata, mask.vmask, CD_SET_DEFAULT, 0);
- CustomData_copy_mesh_to_bmesh(&me->edata, &bm->edata, mask.emask, CD_SET_DEFAULT, 0);
- CustomData_copy_mesh_to_bmesh(&me->ldata, &bm->ldata, mask.lmask, CD_SET_DEFAULT, 0);
- CustomData_copy_mesh_to_bmesh(&me->pdata, &bm->pdata, mask.pmask, CD_SET_DEFAULT, 0);
+ CustomData_copy(&mesh_vdata, &bm->vdata, mask.vmask, CD_SET_DEFAULT, 0);
+ CustomData_copy(&mesh_edata, &bm->edata, mask.emask, CD_SET_DEFAULT, 0);
+ CustomData_copy(&mesh_pdata, &bm->pdata, mask.pmask, CD_SET_DEFAULT, 0);
+ CustomData_copy(&mesh_ldata, &bm->ldata, mask.lmask, CD_SET_DEFAULT, 0);
}
else {
- CustomData_bmesh_merge(&me->vdata, &bm->vdata, mask.vmask, CD_SET_DEFAULT, bm, BM_VERT);
- CustomData_bmesh_merge(&me->edata, &bm->edata, mask.emask, CD_SET_DEFAULT, bm, BM_EDGE);
- CustomData_bmesh_merge(&me->ldata, &bm->ldata, mask.lmask, CD_SET_DEFAULT, bm, BM_LOOP);
- CustomData_bmesh_merge(&me->pdata, &bm->pdata, mask.pmask, CD_SET_DEFAULT, bm, BM_FACE);
+ CustomData_bmesh_merge(&mesh_vdata, &bm->vdata, mask.vmask, CD_SET_DEFAULT, bm, BM_VERT);
+ CustomData_bmesh_merge(&mesh_edata, &bm->edata, mask.emask, CD_SET_DEFAULT, bm, BM_EDGE);
+ CustomData_bmesh_merge(&mesh_pdata, &bm->pdata, mask.pmask, CD_SET_DEFAULT, bm, BM_FACE);
+ CustomData_bmesh_merge(&mesh_ldata, &bm->ldata, mask.lmask, CD_SET_DEFAULT, bm, BM_LOOP);
}
/* -------------------------------------------------------------------- */
@@ -310,19 +279,21 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP);
CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE);
}
- BM_mesh_cd_flag_apply(bm, me->cd_flag | (is_new ? 0 : BM_mesh_cd_flag_from_bmesh(bm)));
/* Only copy these values over if the source mesh is flagged to be using them.
* Even if `bm` has these layers, they may have been added from another mesh, when `!is_new`. */
- const int cd_edge_crease_offset = (me->cd_flag & ME_CDFLAG_EDGE_CREASE) ?
- CustomData_get_offset(&bm->edata, CD_CREASE) :
- -1;
const int cd_shape_key_offset = tot_shape_keys ? CustomData_get_offset(&bm->vdata, CD_SHAPEKEY) :
-1;
const int cd_shape_keyindex_offset = is_new && (tot_shape_keys || params->add_key_index) ?
CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX) :
-1;
+ const bool *select_vert = (const bool *)CustomData_get_layer_named(
+ &me->vdata, CD_PROP_BOOL, ".select_vert");
+ const bool *select_edge = (const bool *)CustomData_get_layer_named(
+ &me->edata, CD_PROP_BOOL, ".select_edge");
+ const bool *select_poly = (const bool *)CustomData_get_layer_named(
+ &me->pdata, CD_PROP_BOOL, ".select_poly");
const bool *hide_vert = (const bool *)CustomData_get_layer_named(
&me->vdata, CD_PROP_BOOL, ".hide_vert");
const bool *hide_edge = (const bool *)CustomData_get_layer_named(
@@ -339,14 +310,10 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
bm, keyco ? keyco[i] : mvert[i].co, nullptr, BM_CREATE_SKIP_CD);
BM_elem_index_set(v, i); /* set_ok */
- /* Transfer flag. */
- v->head.hflag = BM_vert_flag_from_mflag(mvert[i].flag & ~SELECT);
if (hide_vert && hide_vert[i]) {
BM_elem_flag_enable(v, BM_ELEM_HIDDEN);
}
-
- /* This is necessary for selection counts to work properly. */
- if (mvert[i].flag & SELECT) {
+ if (select_vert && select_vert[i]) {
BM_vert_select_set(bm, v, true);
}
@@ -355,7 +322,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
}
/* Copy Custom Data */
- CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data, true);
+ CustomData_to_bmesh_block(&mesh_vdata, &bm->vdata, i, &v->head.data, true);
/* Set shape key original index. */
if (cd_shape_keyindex_offset != -1) {
@@ -382,22 +349,16 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
BM_elem_index_set(e, i); /* set_ok */
/* Transfer flags. */
- e->head.hflag = BM_edge_flag_from_mflag(medge[i].flag & ~SELECT);
+ e->head.hflag = BM_edge_flag_from_mflag(medge[i].flag);
if (hide_edge && hide_edge[i]) {
BM_elem_flag_enable(e, BM_ELEM_HIDDEN);
}
-
- /* This is necessary for selection counts to work properly. */
- if (medge[i].flag & SELECT) {
+ if (select_edge && select_edge[i]) {
BM_edge_select_set(bm, e, true);
}
/* Copy Custom Data */
- CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data, true);
-
- if (cd_edge_crease_offset != -1) {
- BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)medge[i].crease / 255.0f);
- }
+ CustomData_to_bmesh_block(&mesh_edata, &bm->edata, i, &e->head.data, true);
}
if (is_new) {
bm->elem_index_dirty &= ~BM_EDGE; /* Added in order, clear dirty flag. */
@@ -435,13 +396,11 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
BM_elem_index_set(f, bm->totface - 1); /* set_ok */
/* Transfer flag. */
- f->head.hflag = BM_face_flag_from_mflag(mpoly[i].flag & ~ME_FACE_SEL);
+ f->head.hflag = BM_face_flag_from_mflag(mpoly[i].flag);
if (hide_poly && hide_poly[i]) {
BM_elem_flag_enable(f, BM_ELEM_HIDDEN);
}
-
- /* This is necessary for selection counts to work properly. */
- if (mpoly[i].flag & ME_FACE_SEL) {
+ if (select_poly && select_poly[i]) {
BM_face_select_set(bm, f, true);
}
@@ -458,11 +417,11 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
BM_elem_index_set(l_iter, totloops++); /* set_ok */
/* Save index of corresponding #MLoop. */
- CustomData_to_bmesh_block(&me->ldata, &bm->ldata, j++, &l_iter->head.data, true);
+ CustomData_to_bmesh_block(&mesh_ldata, &bm->ldata, j++, &l_iter->head.data, true);
} while ((l_iter = l_iter->next) != l_first);
/* Copy Custom Data */
- CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data, true);
+ CustomData_to_bmesh_block(&mesh_pdata, &bm->pdata, i, &f->head.data, true);
if (params->calc_face_normal) {
BM_face_normal_update(f);
@@ -888,24 +847,31 @@ template<typename T, typename GetFn>
static void write_fn_to_attribute(blender::bke::MutableAttributeAccessor attributes,
const StringRef attribute_name,
const eAttrDomain domain,
- const bool do_write,
const GetFn &get_fn)
{
using namespace blender;
- if (do_write) {
- bke::SpanAttributeWriter<T> attribute = attributes.lookup_or_add_for_write_only_span<T>(
- attribute_name, domain);
- threading::parallel_for(attribute.span.index_range(), 4096, [&](IndexRange range) {
- for (const int i : range) {
- attribute.span[i] = get_fn(i);
- }
- });
- attribute.finish();
- }
- else {
- /* To avoid overhead, remove the hide attribute if possible. */
- attributes.remove(attribute_name);
- }
+ bke::SpanAttributeWriter<T> attribute = attributes.lookup_or_add_for_write_only_span<T>(
+ attribute_name, domain);
+ threading::parallel_for(attribute.span.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ attribute.span[i] = get_fn(i);
+ }
+ });
+ attribute.finish();
+}
+
+static void assert_bmesh_has_no_mesh_only_attributes(const BMesh &bm)
+{
+ (void)bm; /* Unused in the release builds. */
+
+ /* The "hide" attributes are stored as flags on #BMesh. */
+ BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".hide_vert") == nullptr);
+ BLI_assert(CustomData_get_layer_named(&bm.edata, CD_PROP_BOOL, ".hide_edge") == nullptr);
+ BLI_assert(CustomData_get_layer_named(&bm.pdata, CD_PROP_BOOL, ".hide_poly") == nullptr);
+ /* The "selection" attributes are stored as flags on #BMesh. */
+ BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".select_vert") == nullptr);
+ BLI_assert(CustomData_get_layer_named(&bm.edata, CD_PROP_BOOL, ".select_edge") == nullptr);
+ BLI_assert(CustomData_get_layer_named(&bm.pdata, CD_PROP_BOOL, ".select_poly") == nullptr);
}
static void convert_bmesh_hide_flags_to_mesh_attributes(BMesh &bm,
@@ -916,9 +882,7 @@ static void convert_bmesh_hide_flags_to_mesh_attributes(BMesh &bm,
{
using namespace blender;
/* The "hide" attributes are stored as flags on #BMesh. */
- BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".hide_vert") == nullptr);
- BLI_assert(CustomData_get_layer_named(&bm.edata, CD_PROP_BOOL, ".hide_edge") == nullptr);
- BLI_assert(CustomData_get_layer_named(&bm.pdata, CD_PROP_BOOL, ".hide_poly") == nullptr);
+ assert_bmesh_has_no_mesh_only_attributes(bm);
if (!(need_hide_vert || need_hide_edge || need_hide_poly)) {
return;
@@ -927,18 +891,52 @@ static void convert_bmesh_hide_flags_to_mesh_attributes(BMesh &bm,
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
BM_mesh_elem_table_ensure(&bm, BM_VERT | BM_EDGE | BM_FACE);
- write_fn_to_attribute<bool>(
- attributes, ".hide_vert", ATTR_DOMAIN_POINT, need_hide_vert, [&](const int i) {
- return BM_elem_flag_test(BM_vert_at_index(&bm, i), BM_ELEM_HIDDEN);
- });
- write_fn_to_attribute<bool>(
- attributes, ".hide_edge", ATTR_DOMAIN_EDGE, need_hide_edge, [&](const int i) {
- return BM_elem_flag_test(BM_edge_at_index(&bm, i), BM_ELEM_HIDDEN);
- });
- write_fn_to_attribute<bool>(
- attributes, ".hide_poly", ATTR_DOMAIN_FACE, need_hide_poly, [&](const int i) {
- return BM_elem_flag_test(BM_face_at_index(&bm, i), BM_ELEM_HIDDEN);
- });
+ if (need_hide_vert) {
+ write_fn_to_attribute<bool>(attributes, ".hide_vert", ATTR_DOMAIN_POINT, [&](const int i) {
+ return BM_elem_flag_test(BM_vert_at_index(&bm, i), BM_ELEM_HIDDEN);
+ });
+ }
+ if (need_hide_edge) {
+ write_fn_to_attribute<bool>(attributes, ".hide_edge", ATTR_DOMAIN_EDGE, [&](const int i) {
+ return BM_elem_flag_test(BM_edge_at_index(&bm, i), BM_ELEM_HIDDEN);
+ });
+ }
+ if (need_hide_poly) {
+ write_fn_to_attribute<bool>(attributes, ".hide_poly", ATTR_DOMAIN_FACE, [&](const int i) {
+ return BM_elem_flag_test(BM_face_at_index(&bm, i), BM_ELEM_HIDDEN);
+ });
+ }
+}
+
+static void convert_bmesh_selection_flags_to_mesh_attributes(BMesh &bm,
+ const bool need_select_vert,
+ const bool need_select_edge,
+ const bool need_select_poly,
+ Mesh &mesh)
+{
+ using namespace blender;
+ if (!(need_select_vert || need_select_edge || need_select_poly)) {
+ return;
+ }
+
+ bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
+ BM_mesh_elem_table_ensure(&bm, BM_VERT | BM_EDGE | BM_FACE);
+
+ if (need_select_vert) {
+ write_fn_to_attribute<bool>(attributes, ".select_vert", ATTR_DOMAIN_POINT, [&](const int i) {
+ return BM_elem_flag_test(BM_vert_at_index(&bm, i), BM_ELEM_SELECT);
+ });
+ }
+ if (need_select_edge) {
+ write_fn_to_attribute<bool>(attributes, ".select_edge", ATTR_DOMAIN_EDGE, [&](const int i) {
+ return BM_elem_flag_test(BM_edge_at_index(&bm, i), BM_ELEM_SELECT);
+ });
+ }
+ if (need_select_poly) {
+ write_fn_to_attribute<bool>(attributes, ".select_poly", ATTR_DOMAIN_FACE, [&](const int i) {
+ return BM_elem_flag_test(BM_face_at_index(&bm, i), BM_ELEM_SELECT);
+ });
+ }
}
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
@@ -949,7 +947,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
BMIter iter;
int i, j;
- const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX);
const int ototvert = me->totvert;
@@ -974,37 +971,24 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
{
CustomData_MeshMasks mask = CD_MASK_MESH;
CustomData_MeshMasks_update(&mask, &params->cd_mask_extra);
- CustomData_copy_mesh_to_bmesh(&bm->vdata, &me->vdata, mask.vmask, CD_SET_DEFAULT, me->totvert);
- CustomData_copy_mesh_to_bmesh(&bm->edata, &me->edata, mask.emask, CD_SET_DEFAULT, me->totedge);
- CustomData_copy_mesh_to_bmesh(&bm->ldata, &me->ldata, mask.lmask, CD_SET_DEFAULT, me->totloop);
- CustomData_copy_mesh_to_bmesh(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly);
+ CustomData_copy(&bm->vdata, &me->vdata, mask.vmask, CD_SET_DEFAULT, me->totvert);
+ CustomData_copy(&bm->edata, &me->edata, mask.emask, CD_SET_DEFAULT, me->totedge);
+ CustomData_copy(&bm->ldata, &me->ldata, mask.lmask, CD_SET_DEFAULT, me->totloop);
+ CustomData_copy(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly);
}
- MutableSpan<MVert> mvert;
- MutableSpan<MEdge> medge;
- MutableSpan<MPoly> mpoly;
- MutableSpan<MLoop> mloop;
- if (me->totvert > 0) {
- mvert = {static_cast<MVert *>(
- CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert)),
- me->totvert};
- }
- if (me->totedge > 0) {
- medge = {static_cast<MEdge *>(
- CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, me->totedge)),
- me->totedge};
- }
- if (me->totpoly > 0) {
- mpoly = {static_cast<MPoly *>(
- CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, me->totpoly)),
- me->totpoly};
- }
- if (me->totloop > 0) {
- mloop = {static_cast<MLoop *>(
- CustomData_add_layer(&me->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, me->totloop)),
- me->totloop};
- }
+ CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert);
+ CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, me->totedge);
+ CustomData_add_layer(&me->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, me->totloop);
+ CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, me->totpoly);
+ MutableSpan<MVert> mvert = me->verts_for_write();
+ MutableSpan<MEdge> medge = me->edges_for_write();
+ MutableSpan<MPoly> mpoly = me->polys_for_write();
+ MutableSpan<MLoop> mloop = me->loops_for_write();
+ bool need_select_vert = false;
+ bool need_select_edge = false;
+ bool need_select_poly = false;
bool need_hide_vert = false;
bool need_hide_edge = false;
bool need_hide_poly = false;
@@ -1014,16 +998,16 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
* different than the BMesh's. */
BKE_mesh_clear_derived_normals(me);
- me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
-
i = 0;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
copy_v3_v3(mvert[i].co, v->co);
- mvert[i].flag = BM_vert_flag_to_mflag(v);
if (BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
need_hide_vert = true;
}
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ need_select_vert = true;
+ }
BM_elem_index_set(v, i); /* set_inline */
@@ -1045,6 +1029,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
if (BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
need_hide_edge = true;
}
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ need_select_edge = true;
+ }
BM_elem_index_set(e, i); /* set_inline */
@@ -1053,10 +1040,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
bmesh_quick_edgedraw_flag(&medge[i], e);
- if (cd_edge_crease_offset != -1) {
- medge[i].crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_crease_offset);
- }
-
i++;
BM_CHECK_ELEMENT(e);
}
@@ -1075,6 +1058,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
need_hide_poly = true;
}
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ need_select_poly = true;
+ }
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
@@ -1103,10 +1089,10 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
if (need_material_index) {
BM_mesh_elem_table_ensure(bm, BM_FACE);
- write_fn_to_attribute<int>(
- me->attributes_for_write(), "material_index", ATTR_DOMAIN_FACE, true, [&](const int i) {
- return static_cast<int>(BM_face_at_index(bm, i)->mat_nr);
- });
+ write_fn_to_attribute<int>(me->attributes_for_write(),
+ "material_index",
+ ATTR_DOMAIN_FACE,
+ [&](const int i) { return int(BM_face_at_index(bm, i)->mat_nr); });
}
/* Patch hook indices and vertex parents. */
@@ -1175,6 +1161,8 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
convert_bmesh_hide_flags_to_mesh_attributes(
*bm, need_hide_vert, need_hide_edge, need_hide_poly, *me);
+ convert_bmesh_selection_flags_to_mesh_attributes(
+ *bm, need_select_vert, need_select_edge, need_select_poly, *me);
{
me->totselect = BLI_listbase_count(&(bm->selected));
@@ -1222,8 +1210,12 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
BKE_mesh_runtime_clear_geometry(me);
}
+/* NOTE: The function is called from multiple threads with the same input BMesh and different
+ * mesh objects. */
void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *cd_mask_extra)
{
+ using namespace blender;
+
/* Must be an empty mesh. */
BLI_assert(me->totvert == 0);
BLI_assert(cd_mask_extra == nullptr || (cd_mask_extra->vmask & CD_MASK_SHAPEKEY) == 0);
@@ -1260,21 +1252,18 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
MutableSpan<MPoly> mpoly = me->polys_for_write();
MutableSpan<MLoop> loops = me->loops_for_write();
MLoop *mloop = loops.data();
- unsigned int i, j;
-
- const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
-
- bool need_hide_vert = false;
- bool need_hide_edge = false;
- bool need_hide_poly = false;
- bool need_material_index = false;
+ uint i, j;
/* Clear normals on the mesh completely, since the original vertex and polygon count might be
* different than the BMesh's. */
BKE_mesh_clear_derived_normals(me);
- me->runtime.deformed_only = true;
+ me->runtime->deformed_only = true;
+ bke::MutableAttributeAccessor mesh_attributes = me->attributes_for_write();
+
+ bke::SpanAttributeWriter<bool> hide_vert_attribute;
+ bke::SpanAttributeWriter<bool> select_vert_attribute;
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
MVert *mv = &mvert[i];
@@ -1282,15 +1271,27 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
BM_elem_index_set(eve, i); /* set_inline */
- mv->flag = BM_vert_flag_to_mflag(eve);
if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- need_hide_vert = true;
+ if (!hide_vert_attribute) {
+ hide_vert_attribute = mesh_attributes.lookup_or_add_for_write_span<bool>(
+ ".hide_vert", ATTR_DOMAIN_POINT);
+ }
+ hide_vert_attribute.span[i] = true;
+ }
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ if (!select_vert_attribute) {
+ select_vert_attribute = mesh_attributes.lookup_or_add_for_write_span<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT);
+ }
+ select_vert_attribute.span[i] = true;
}
CustomData_from_bmesh_block(&bm->vdata, &me->vdata, eve->head.data, i);
}
bm->elem_index_dirty &= ~BM_VERT;
+ bke::SpanAttributeWriter<bool> hide_edge_attribute;
+ bke::SpanAttributeWriter<bool> select_edge_attribute;
BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
MEdge *med = &medge[i];
@@ -1301,7 +1302,18 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
med->flag = BM_edge_flag_to_mflag(eed);
if (BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- need_hide_edge = true;
+ if (!hide_edge_attribute) {
+ hide_edge_attribute = mesh_attributes.lookup_or_add_for_write_span<bool>(".hide_edge",
+ ATTR_DOMAIN_EDGE);
+ }
+ hide_edge_attribute.span[i] = true;
+ }
+ if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
+ if (!select_edge_attribute) {
+ select_edge_attribute = mesh_attributes.lookup_or_add_for_write_span<bool>(
+ ".select_edge", ATTR_DOMAIN_EDGE);
+ }
+ select_edge_attribute.span[i] = true;
}
/* Handle this differently to editmode switching,
@@ -1312,15 +1324,14 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
}
}
- if (cd_edge_crease_offset != -1) {
- med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset);
- }
-
CustomData_from_bmesh_block(&bm->edata, &me->edata, eed->head.data, i);
}
bm->elem_index_dirty &= ~BM_EDGE;
j = 0;
+ bke::SpanAttributeWriter<int> material_index_attribute;
+ bke::SpanAttributeWriter<bool> hide_poly_attribute;
+ bke::SpanAttributeWriter<bool> select_poly_attribute;
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
BMLoop *l_iter;
BMLoop *l_first;
@@ -1331,12 +1342,27 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
mp->totloop = efa->len;
mp->flag = BM_face_flag_to_mflag(efa);
if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
- need_hide_poly = true;
+ if (!hide_poly_attribute) {
+ hide_poly_attribute = mesh_attributes.lookup_or_add_for_write_span<bool>(".hide_poly",
+ ATTR_DOMAIN_FACE);
+ }
+ hide_poly_attribute.span[i] = true;
+ }
+ if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
+ if (!select_poly_attribute) {
+ select_poly_attribute = mesh_attributes.lookup_or_add_for_write_span<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE);
+ }
+ select_poly_attribute.span[i] = true;
}
mp->loopstart = j;
if (efa->mat_nr != 0) {
- need_material_index = true;
+ if (!material_index_attribute) {
+ material_index_attribute = mesh_attributes.lookup_or_add_for_write_span<int>(
+ "material_index", ATTR_DOMAIN_FACE);
+ }
+ material_index_attribute.span[i] = efa->mat_nr;
}
l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
@@ -1355,16 +1381,13 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
}
bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
- if (need_material_index) {
- BM_mesh_elem_table_ensure(bm, BM_FACE);
- write_fn_to_attribute<int>(
- me->attributes_for_write(), "material_index", ATTR_DOMAIN_FACE, true, [&](const int i) {
- return static_cast<int>(BM_face_at_index(bm, i)->mat_nr);
- });
- }
-
- convert_bmesh_hide_flags_to_mesh_attributes(
- *bm, need_hide_vert, need_hide_edge, need_hide_poly, *me);
+ assert_bmesh_has_no_mesh_only_attributes(*bm);
- me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
+ material_index_attribute.finish();
+ hide_vert_attribute.finish();
+ hide_edge_attribute.finish();
+ hide_poly_attribute.finish();
+ select_vert_attribute.finish();
+ select_edge_attribute.finish();
+ select_poly_attribute.finish();
}
diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.h b/source/blender/bmesh/intern/bmesh_mesh_convert.h
index a04136afc1d..3f8e9e3dfef 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_convert.h
+++ b/source/blender/bmesh/intern/bmesh_mesh_convert.h
@@ -13,10 +13,6 @@ struct CustomData_MeshMasks;
struct Main;
struct Mesh;
-void BM_mesh_cd_flag_ensure(BMesh *bm, struct Mesh *mesh, char cd_flag);
-void BM_mesh_cd_flag_apply(BMesh *bm, char cd_flag);
-char BM_mesh_cd_flag_from_bmesh(BMesh *bm);
-
struct BMeshFromMeshParams {
bool calc_face_normal;
bool calc_vert_normal;
diff --git a/source/blender/bmesh/intern/bmesh_mesh_normals.c b/source/blender/bmesh/intern/bmesh_mesh_normals.c
index cd89a550279..6705ac5acca 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_normals.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_normals.c
@@ -1780,7 +1780,7 @@ void BM_lnorspace_invalidate(BMesh *bm, const bool do_invalidate_all)
/* Note that we only handle unselected neighbor vertices here, main loop will take care of
* selected ones. */
- if ((!BM_elem_flag_test(l->prev->v, BM_ELEM_SELECT)) &&
+ if (!BM_elem_flag_test(l->prev->v, BM_ELEM_SELECT) &&
!BLI_BITMAP_TEST(done_verts, BM_elem_index_get(l->prev->v))) {
BMLoop *l_prev;
@@ -1791,7 +1791,7 @@ void BM_lnorspace_invalidate(BMesh *bm, const bool do_invalidate_all)
BLI_BITMAP_ENABLE(done_verts, BM_elem_index_get(l_prev->v));
}
- if ((!BM_elem_flag_test(l->next->v, BM_ELEM_SELECT)) &&
+ if (!BM_elem_flag_test(l->next->v, BM_ELEM_SELECT) &&
!BLI_BITMAP_TEST(done_verts, BM_elem_index_get(l->next->v))) {
BMLoop *l_next;
diff --git a/source/blender/bmesh/intern/bmesh_mesh_partial_update.c b/source/blender/bmesh/intern/bmesh_mesh_partial_update.c
index 757ca8f19b6..197af450f72 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_partial_update.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_partial_update.c
@@ -52,7 +52,7 @@
#define GROW(len_alloc) ((len_alloc) + ((len_alloc) - ((len_alloc) / 2)))
#define GROW_ARRAY(mem, len_alloc) \
{ \
- mem = MEM_reallocN(mem, (sizeof(*mem)) * ((len_alloc) = GROW(len_alloc))); \
+ mem = MEM_reallocN(mem, sizeof(*mem) * ((len_alloc) = GROW(len_alloc))); \
} \
((void)0)
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index 8b56e08c22b..a1842b598d5 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -62,7 +62,7 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v)
e = v->e;
do {
e = bmesh_disk_edge_next(e, v);
- if (!(BM_edge_share_face_check(e, v->e))) {
+ if (!BM_edge_share_face_check(e, v->e)) {
keepedge = e;
baseedge = v->e;
break;
@@ -192,7 +192,7 @@ BMFace *BM_face_split(BMesh *bm,
BLI_assert(!BM_loop_is_adjacent(l_a, l_b));
/* could be an assert */
- if (UNLIKELY(BM_loop_is_adjacent(l_a, l_b)) || UNLIKELY((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;
}
diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
index 29bd066f33c..81793ee9995 100644
--- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
+++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
@@ -1273,7 +1273,7 @@ bool BM_face_split_edgenet_connect_islands(BMesh *bm,
BMVert *v_other;
/* NOTE: remapping will _never_ map a vertex to an already mapped vertex. */
- while (UNLIKELY((v_other = bm_face_split_edgenet_partial_connect(bm, v_delimit, f)))) {
+ while (UNLIKELY(v_other = bm_face_split_edgenet_partial_connect(bm, v_delimit, f))) {
struct TempVertPair *tvp = BLI_memarena_alloc(mem_arena, sizeof(*tvp));
tvp->next = temp_vert_pairs.list;
tvp->v_orig = v_delimit;
diff --git a/source/blender/bmesh/intern/bmesh_query.c b/source/blender/bmesh/intern/bmesh_query.c
index 8bc16324971..643b5750d76 100644
--- a/source/blender/bmesh/intern/bmesh_query.c
+++ b/source/blender/bmesh/intern/bmesh_query.c
@@ -580,7 +580,7 @@ bool BM_vert_is_edge_pair_manifold(const BMVert *v)
const BMEdge *e = v->e;
if (e) {
BMEdge *e_other = BM_DISK_EDGE_NEXT(e, v);
- if (((e_other != e) && (BM_DISK_EDGE_NEXT(e_other, v) == e))) {
+ if ((e_other != e) && (BM_DISK_EDGE_NEXT(e_other, v) == e)) {
return BM_edge_is_manifold(e) && BM_edge_is_manifold(e_other);
}
}
diff --git a/source/blender/bmesh/intern/bmesh_query.h b/source/blender/bmesh/intern/bmesh_query.h
index 9d690395d72..c3a30df11d6 100644
--- a/source/blender/bmesh/intern/bmesh_query.h
+++ b/source/blender/bmesh/intern/bmesh_query.h
@@ -708,7 +708,7 @@ double BM_mesh_calc_volume(BMesh *bm, bool is_signed) ATTR_WARN_UNUSED_RESULT AT
* Calculate isolated groups of faces with optional filtering.
*
* \param bm: the BMesh.
- * \param r_groups_array: Array of ints to fill in, length of bm->totface
+ * \param r_groups_array: Array of integers to fill in, length of `bm->totface`
* (or when hflag_test is set, the number of flagged faces).
* \param r_group_index: index, length pairs into \a r_groups_array, size of return value
* int pairs: (array_start, array_length).
diff --git a/source/blender/bmesh/intern/bmesh_query_uv.cc b/source/blender/bmesh/intern/bmesh_query_uv.cc
index 5a725407c6b..0e2385ff4e2 100644
--- a/source/blender/bmesh/intern/bmesh_query_uv.cc
+++ b/source/blender/bmesh/intern/bmesh_query_uv.cc
@@ -65,7 +65,7 @@ void BM_face_uv_calc_center_median_weighted(const BMFace *f,
} while ((l_iter = l_iter->next) != l_first);
if (totw != 0.0f) {
- mul_v2_fl(r_cent, 1.0f / (float)totw);
+ mul_v2_fl(r_cent, 1.0f / float(totw));
}
/* Reverse aspect. */
r_cent[0] /= aspect[0];
@@ -85,7 +85,7 @@ void BM_face_uv_calc_center_median(const BMFace *f, const int cd_loop_uv_offset,
add_v2_v2(r_cent, luv->uv);
} while ((l_iter = l_iter->next) != l_first);
- mul_v2_fl(r_cent, 1.0f / (float)f->len);
+ mul_v2_fl(r_cent, 1.0f / float(f->len));
}
float BM_face_uv_calc_cross(const BMFace *f, const int cd_loop_uv_offset)
@@ -113,17 +113,6 @@ void BM_face_uv_minmax(const BMFace *f, float min[2], float max[2], const int cd
} while ((l_iter = l_iter->next) != l_first);
}
-void BM_face_uv_transform(BMFace *f, const float matrix[2][2], const int cd_loop_uv_offset)
-{
- BMLoop *l_iter;
- BMLoop *l_first;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- MLoopUV *luv = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
- mul_m2_v2(matrix, luv->uv);
- } while ((l_iter = l_iter->next) != l_first);
-}
-
bool BM_loop_uv_share_edge_check(BMLoop *l_a, BMLoop *l_b, const int cd_loop_uv_offset)
{
BLI_assert(l_a->e == l_b->e);
diff --git a/source/blender/bmesh/intern/bmesh_query_uv.h b/source/blender/bmesh/intern/bmesh_query_uv.h
index 2b0833f9185..6aa82653535 100644
--- a/source/blender/bmesh/intern/bmesh_query_uv.h
+++ b/source/blender/bmesh/intern/bmesh_query_uv.h
@@ -34,7 +34,6 @@ float BM_face_uv_calc_cross(const BMFace *f, int cd_loop_uv_offset) ATTR_WARN_UN
ATTR_NONNULL();
void BM_face_uv_minmax(const BMFace *f, float min[2], float max[2], int cd_loop_uv_offset);
-void BM_face_uv_transform(BMFace *f, const float matrix[2][2], int cd_loop_uv_offset);
bool BM_loop_uv_share_edge_check_with_limit(BMLoop *l_a,
BMLoop *l_b,
diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c
index bd12287e63e..ef9892669ed 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_impl.c
+++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c
@@ -1062,7 +1062,7 @@ static void *bmw_EdgeLoopWalker_step(BMWalker *walker)
l = NULL;
break;
}
- } while ((++i != i_opposite));
+ } while (++i != i_opposite);
}
else {
l = NULL;
diff --git a/source/blender/bmesh/operators/bmo_bridge.c b/source/blender/bmesh/operators/bmo_bridge.c
index 1a2c52a321f..b6520fb48b3 100644
--- a/source/blender/bmesh/operators/bmo_bridge.c
+++ b/source/blender/bmesh/operators/bmo_bridge.c
@@ -14,6 +14,13 @@
#include "intern/bmesh_operators_private.h" /* own include */
+/**
+ * TODO(@campbellbarton): Many connected edge loops can cause an error attempting
+ * to create faces with duplicate vertices. While this needs to be investigated,
+ * it's simple enough to check for this case, see: T102232.
+ */
+#define USE_DUPLICATE_FACE_VERT_CHECK
+
#define EDGE_MARK 4
#define EDGE_OUT 8
#define FACE_OUT 16
@@ -147,7 +154,7 @@ static void bridge_loop_pair(BMesh *bm,
}
if (use_merge) {
- BLI_assert((el_store_a_len == el_store_b_len));
+ BLI_assert(el_store_a_len == el_store_b_len);
}
if (el_store_a_len != el_store_b_len) {
@@ -386,61 +393,84 @@ static void bridge_loop_pair(BMesh *bm,
f_example = l_a ? l_a->f : (l_b ? l_b->f : NULL);
if (v_b != v_b_next) {
- BMVert *v_arr[4] = {v_b, v_b_next, v_a_next, v_a};
- f = BM_face_exists(v_arr, 4);
- if (f == NULL) {
- /* copy if loop data if its is missing on one ring */
- f = BM_face_create_verts(bm, v_arr, 4, NULL, BM_CREATE_NOP, true);
-
- l_iter = BM_FACE_FIRST_LOOP(f);
- if (l_b) {
- BM_elem_attrs_copy(bm, bm, l_b, l_iter);
- }
- l_iter = l_iter->next;
- if (l_b_next) {
- BM_elem_attrs_copy(bm, bm, l_b_next, l_iter);
- }
- l_iter = l_iter->next;
- if (l_a_next) {
- BM_elem_attrs_copy(bm, bm, l_a_next, l_iter);
- }
- l_iter = l_iter->next;
- if (l_a) {
- BM_elem_attrs_copy(bm, bm, l_a, l_iter);
+#ifdef USE_DUPLICATE_FACE_VERT_CHECK /* Only check for duplicates between loops. */
+ BLI_assert((v_b != v_b_next) && (v_a_next != v_a));
+ if (UNLIKELY(ELEM(v_b, v_a_next, v_a) || ELEM(v_b_next, v_a_next, v_a))) {
+ f = NULL;
+ }
+ else
+#endif
+ {
+ BMVert *v_arr[4] = {v_b, v_b_next, v_a_next, v_a};
+ f = BM_face_exists(v_arr, 4);
+ if (f == NULL) {
+ /* copy if loop data if its is missing on one ring */
+ f = BM_face_create_verts(bm, v_arr, 4, NULL, BM_CREATE_NOP, true);
+
+ l_iter = BM_FACE_FIRST_LOOP(f);
+ if (l_b) {
+ BM_elem_attrs_copy(bm, bm, l_b, l_iter);
+ }
+ l_iter = l_iter->next;
+ if (l_b_next) {
+ BM_elem_attrs_copy(bm, bm, l_b_next, l_iter);
+ }
+ l_iter = l_iter->next;
+ if (l_a_next) {
+ BM_elem_attrs_copy(bm, bm, l_a_next, l_iter);
+ }
+ l_iter = l_iter->next;
+ if (l_a) {
+ BM_elem_attrs_copy(bm, bm, l_a, l_iter);
+ }
}
}
}
else {
- BMVert *v_arr[3] = {v_b, v_a_next, v_a};
- f = BM_face_exists(v_arr, 3);
- if (f == NULL) {
- /* fan-fill a triangle */
- f = BM_face_create_verts(bm, v_arr, 3, NULL, BM_CREATE_NOP, true);
-
- l_iter = BM_FACE_FIRST_LOOP(f);
- if (l_b) {
- BM_elem_attrs_copy(bm, bm, l_b, l_iter);
- }
- l_iter = l_iter->next;
- if (l_a_next) {
- BM_elem_attrs_copy(bm, bm, l_a_next, l_iter);
- }
- l_iter = l_iter->next;
- if (l_a) {
- BM_elem_attrs_copy(bm, bm, l_a, l_iter);
+#ifdef USE_DUPLICATE_FACE_VERT_CHECK /* Only check for duplicates between loops. */
+ BLI_assert(v_a_next != v_a);
+ if (UNLIKELY(ELEM(v_b, v_a_next, v_a))) {
+ f = NULL;
+ }
+ else
+#endif
+ {
+ BMVert *v_arr[3] = {v_b, v_a_next, v_a};
+ f = BM_face_exists(v_arr, 3);
+ if (f == NULL) {
+ /* fan-fill a triangle */
+ f = BM_face_create_verts(bm, v_arr, 3, NULL, BM_CREATE_NOP, true);
+
+ l_iter = BM_FACE_FIRST_LOOP(f);
+ if (l_b) {
+ BM_elem_attrs_copy(bm, bm, l_b, l_iter);
+ }
+ l_iter = l_iter->next;
+ if (l_a_next) {
+ BM_elem_attrs_copy(bm, bm, l_a_next, l_iter);
+ }
+ l_iter = l_iter->next;
+ if (l_a) {
+ BM_elem_attrs_copy(bm, bm, l_a, l_iter);
+ }
}
}
}
- if (f_example && (f_example != f)) {
- BM_elem_attrs_copy(bm, bm, f_example, f);
- }
- BMO_face_flag_enable(bm, f, FACE_OUT);
- BM_elem_flag_enable(f, BM_ELEM_TAG);
+#ifdef USE_DUPLICATE_FACE_VERT_CHECK
+ if (f != NULL)
+#endif
+ {
+ if (f_example && (f_example != f)) {
+ BM_elem_attrs_copy(bm, bm, f_example, f);
+ }
+ BMO_face_flag_enable(bm, f, FACE_OUT);
+ BM_elem_flag_enable(f, BM_ELEM_TAG);
- /* tag all edges of the face, untag the loop edges after */
- if (use_edgeout) {
- bm_face_edges_tag_out(bm, f);
+ /* tag all edges of the face, untag the loop edges after */
+ if (use_edgeout) {
+ bm_face_edges_tag_out(bm, f);
+ }
}
if (el_a_next == el_a_first) {
diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c
index 42de425103e..59a12db9241 100644
--- a/source/blender/bmesh/operators/bmo_connect.c
+++ b/source/blender/bmesh/operators/bmo_connect.c
@@ -18,7 +18,7 @@
#define VERT_INPUT 1
#define EDGE_OUT 1
-/* Edge spans 2 VERT_INPUT's, its a nop,
+/* Edge spans 2 VERT_INPUT's, its a NOP,
* but include in "edges.out" */
#define EDGE_OUT_ADJ 2
diff --git a/source/blender/bmesh/operators/bmo_fill_edgeloop.c b/source/blender/bmesh/operators/bmo_fill_edgeloop.c
index 86d204ea6a7..56aecf5e5b2 100644
--- a/source/blender/bmesh/operators/bmo_fill_edgeloop.c
+++ b/source/blender/bmesh/operators/bmo_fill_edgeloop.c
@@ -114,7 +114,7 @@ void bmo_edgeloop_fill_exec(BMesh *bm, BMOperator *op)
v = BM_edge_other_vert(e_next, v);
e_prev = e_next;
i++;
- } while ((v != f_verts[0]));
+ } while (v != f_verts[0]);
if (!BM_face_exists(f_verts, i)) {
BMFace *f;
diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c
index 1da0108bd6a..2a6b5459d1c 100644
--- a/source/blender/bmesh/operators/bmo_inset.c
+++ b/source/blender/bmesh/operators/bmo_inset.c
@@ -721,7 +721,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
(use_boundary && BM_edge_is_boundary(e) && BM_elem_flag_test(e->l->f, BM_ELEM_TAG)) ||
/* tag if edge is an interior edge in between a tagged and untagged face */
- (bm_edge_is_mixed_face_tag(e->l))) {
+ bm_edge_is_mixed_face_tag(e->l)) {
/* tag */
BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c
index 1339efb3057..df749b591dc 100644
--- a/source/blender/bmesh/operators/bmo_join_triangles.c
+++ b/source/blender/bmesh/operators/bmo_join_triangles.c
@@ -22,7 +22,9 @@
#include "intern/bmesh_operators_private.h" /* own include */
-/* assumes edges are validated before reaching this poin */
+/**
+ * \note Assumes edges are validated before reaching this point.
+ */
static float quad_calc_error(const float v1[3],
const float v2[3],
const float v3[3],
@@ -41,11 +43,11 @@ static float quad_calc_error(const float v1[3],
normal_tri_v3(n1, v1, v2, v3);
normal_tri_v3(n2, v1, v3, v4);
- angle_a = (compare_v3v3(n1, n2, FLT_EPSILON)) ? 0.0f : angle_normalized_v3v3(n1, n2);
+ angle_a = compare_v3v3(n1, n2, FLT_EPSILON) ? 0.0f : angle_normalized_v3v3(n1, n2);
normal_tri_v3(n1, v2, v3, v4);
normal_tri_v3(n2, v4, v1, v2);
- angle_b = (compare_v3v3(n1, n2, FLT_EPSILON)) ? 0.0f : angle_normalized_v3v3(n1, n2);
+ angle_b = compare_v3v3(n1, n2, FLT_EPSILON) ? 0.0f : angle_normalized_v3v3(n1, n2);
diff = (angle_a + angle_b) / (float)(M_PI * 2);
@@ -164,15 +166,15 @@ static float bm_edge_is_delimit(const BMEdge *e, const struct DelimitData *delim
float angle;
#endif
- if ((delimit_data->do_seam) && (BM_elem_flag_test(e, BM_ELEM_SEAM))) {
+ if (delimit_data->do_seam && BM_elem_flag_test(e, BM_ELEM_SEAM)) {
goto fail;
}
- if ((delimit_data->do_sharp) && (BM_elem_flag_test(e, BM_ELEM_SMOOTH) == 0)) {
+ if (delimit_data->do_sharp && (BM_elem_flag_test(e, BM_ELEM_SMOOTH) == 0)) {
goto fail;
}
- if ((delimit_data->do_mat) && (f_a->mat_nr != f_b->mat_nr)) {
+ if (delimit_data->do_mat && (f_a->mat_nr != f_b->mat_nr)) {
goto fail;
}
diff --git a/source/blender/bmesh/operators/bmo_normals.c b/source/blender/bmesh/operators/bmo_normals.c
index 04eaa43c899..0d321e1de8d 100644
--- a/source/blender/bmesh/operators/bmo_normals.c
+++ b/source/blender/bmesh/operators/bmo_normals.c
@@ -3,7 +3,7 @@
/** \file
* \ingroup bmesh
*
- * normal recalculation.
+ * Functionality for flipping faces to make normals consistent.
*/
#include "MEM_guardedalloc.h"
@@ -47,7 +47,7 @@ static bool bmo_recalc_normal_loop_filter_cb(const BMLoop *l, void *UNUSED(user_
* +------------+
* </pre>
*
- * In the example above, the a\ face can point towards the \a center
+ * In the example above, the \a face can point towards the \a center
* which would end up flipping the normals inwards.
*
* To take these spikes into account, find the furthest face-loop-vertex.
diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c
index e3275555b86..bf04228efef 100644
--- a/source/blender/bmesh/operators/bmo_removedoubles.c
+++ b/source/blender/bmesh/operators/bmo_removedoubles.c
@@ -563,7 +563,7 @@ static void bmo_collapsecon_do_layer(BMesh *bm, const int layer, const short ofl
CustomData_data_multiply(type, &max, 0.5f);
CustomData_data_add(type, &min, &max);
- /* snap CD (uv, vcol) points to their centroid */
+ /* Snap custom-data (UV, vertex-colors) points to their centroid. */
while (!BLI_stack_is_empty(block_stack)) {
void *block;
BLI_stack_pop(block_stack, &block);
@@ -657,10 +657,10 @@ static void bmesh_find_doubles_common(BMesh *bm,
for (int i = 0; i < verts_len; i++) {
BMVert *v_check = verts[i];
if (duplicates[i] == -1) {
- /* nop (others can use as target) */
+ /* NOP (others can use as target). */
}
else if (duplicates[i] == i) {
- /* keep (others can use as target) */
+ /* Keep (others can use as target). */
}
else {
BMVert *v_other = verts[duplicates[i]];
diff --git a/source/blender/bmesh/operators/bmo_rotate_edges.c b/source/blender/bmesh/operators/bmo_rotate_edges.c
index 50d7014efcd..53efd47ec9a 100644
--- a/source/blender/bmesh/operators/bmo_rotate_edges.c
+++ b/source/blender/bmesh/operators/bmo_rotate_edges.c
@@ -66,7 +66,7 @@ static float bm_edge_rotate_is_boundary(const BMEdge *e)
do {
BMEdge *e_iter = l_iter->e;
const int e_iter_index = BM_elem_index_get(e_iter);
- if ((e_iter_index != -1)) {
+ if (e_iter_index != -1) {
if (count == 1) {
return false;
}
diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
index 08efe5383a8..575a88331da 100644
--- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c
+++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
@@ -223,7 +223,7 @@ static void init_laplacian_matrix(LaplacianSystem *sys)
sys->vweights[vi_prev] += w1 + w2;
sys->vweights[vi_curr] += w2 + w3;
sys->vweights[vi_next] += w1 + w3;
- } while (((void)(l_curr_index += 1), (l_iter = l_iter->next) != l_first));
+ } while ((void)(l_curr_index += 1), (l_iter = l_iter->next) != l_first);
}
}
@@ -293,7 +293,7 @@ static void fill_laplacian_matrix(LaplacianSystem *sys)
ok_prev = ok_curr;
ok_curr = ok_next;
- } while (((void)(l_curr_index += 1), (l_iter = l_iter->next) != l_first));
+ } while ((void)(l_curr_index += 1), (l_iter = l_iter->next) != l_first);
}
BM_ITER_MESH_INDEX (e, &eiter, sys->bm, BM_EDGES_OF_MESH, i) {
if (BM_elem_flag_test(e, BM_ELEM_SELECT) || !BM_edge_is_boundary(e)) {
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index d6c64809e13..6b2df40549d 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -86,7 +86,7 @@ typedef struct SubDPattern {
* split the edge only?
*/
-/* flags for all elements share a common bitfield space */
+/** Flags for all elements share a common bit-field space. */
#define SUBD_SPLIT 1
#define EDGE_PERCENT 2
@@ -966,7 +966,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
patterns[5] = NULL;
}
- /* add a temporary shapekey layer to store displacements on current geometry */
+ /* Add a temporary shape-key layer to store displacements on current geometry. */
BM_data_layer_add(bm, &bm->vdata, CD_SHAPEKEY);
bmo_subd_init_shape_info(bm, &params);
diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c
index 3d2f5947539..6f41da7bb43 100644
--- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c
+++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c
@@ -42,7 +42,8 @@
#define FACE_IN_STACK (1 << 2)
/* -------------------------------------------------------------------- */
-/* Specialized Utility Funcs */
+/** \name Specialized Utility Functions
+ * \{ */
#ifndef NDEBUG
static uint bm_verts_tag_count(BMesh *bm)
@@ -183,9 +184,13 @@ finally:
return has_overlap;
}
+/** \} */
+
/* -------------------------------------------------------------------- */
-/* Edge Loop Pairs */
-/* key (ordered loop pointers) */
+/** \name Edge Loop Pairs
+ *
+ * key (ordered loop pointers).
+ * \{ */
static GSet *bm_edgering_pair_calc(BMesh *bm, ListBase *eloops_rim)
{
/**
@@ -258,8 +263,11 @@ static GSet *bm_edgering_pair_calc(BMesh *bm, ListBase *eloops_rim)
return eloop_pair_gs;
}
+/** \} */
+
/* -------------------------------------------------------------------- */
-/* Subdivide an edge 'n' times and return an open edgeloop */
+/** \name Subdivide an edge 'n' times and return an open edgeloop
+ * \{ */
static void bm_edge_subdiv_as_loop(
BMesh *bm, ListBase *eloops, BMEdge *e, BMVert *v_a, const int cuts)
@@ -290,8 +298,11 @@ static void bm_edge_subdiv_as_loop(
BLI_addtail(eloops, eloop);
}
+/** \} */
+
/* -------------------------------------------------------------------- */
-/* LoopPair Cache (struct and util funcs) */
+/** \name Loop Pair Cache (struct and utilities functions)
+ * \{ */
/**
* Use for finding spline handle direction from surrounding faces.
@@ -510,8 +521,11 @@ static void bm_edgering_pair_store_free(LoopPairStore *lpair, const int interp_m
MEM_freeN(lpair);
}
+/** \} */
+
/* -------------------------------------------------------------------- */
-/* Interpolation Function */
+/** \name Interpolation Function
+ * \{ */
static void bm_edgering_pair_interpolate(BMesh *bm,
LoopPairStore *lpair,
@@ -1216,3 +1230,5 @@ cleanup:
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_OUT);
}
}
+
+/** \} */
diff --git a/source/blender/bmesh/tests/bmesh_core_test.cc b/source/blender/bmesh/tests/bmesh_core_test.cc
index 000e4cf92a2..a0f6ea2706b 100644
--- a/source/blender/bmesh/tests/bmesh_core_test.cc
+++ b/source/blender/bmesh/tests/bmesh_core_test.cc
@@ -24,7 +24,7 @@ TEST(bmesh_core, BMVertCreate)
EXPECT_EQ(bv1->co[1], 2.0f);
EXPECT_EQ(bv1->co[2], 0.0f);
EXPECT_TRUE(is_zero_v3(bv1->no));
- EXPECT_EQ(bv1->head.htype, (char)BM_VERT);
+ EXPECT_EQ(bv1->head.htype, char(BM_VERT));
EXPECT_EQ(bv1->head.hflag, 0);
EXPECT_EQ(bv1->head.api_flag, 0);
bv2 = BM_vert_create(bm, nullptr, nullptr, BM_CREATE_NOP);
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index aa2c93f7c5a..c45f9dbe49c 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -2058,7 +2058,7 @@ static void get_profile_point(BevelParams *bp, const Profile *pro, int i, int ns
}
else {
BLI_assert(is_power_of_2_i(nseg) && nseg <= bp->pro_spacing.seg_2);
- /* Find spacing between subsamples in prof_co_2. */
+ /* Find spacing between sub-samples in `prof_co_2`. */
int subsample_spacing = bp->pro_spacing.seg_2 / nseg;
copy_v3_v3(r_co, pro->prof_co_2 + 3 * i * subsample_spacing);
}
@@ -4697,7 +4697,7 @@ static VMesh *pipe_adj_vmesh(BevelParams *bp, BevVert *bv, BoundVert *vpipe)
* vertices to snap to the midline on the pipe, not just to one plane or the other. */
bool even = (ns % 2) == 0;
bool midline = even && k == half_ns &&
- ((i == 0 && j == half_ns) || (ELEM(i, ipipe1, ipipe2)));
+ ((i == 0 && j == half_ns) || ELEM(i, ipipe1, ipipe2));
snap_to_pipe_profile(vpipe, midline, mesh_vert(vm, i, j, k)->co);
}
}
@@ -4799,7 +4799,7 @@ static float projected_boundary_area(BevVert *bv, BMFace *f)
find_face_internal_boundverts(bv, f, unsnapped);
do {
float *co = v->nv.v->co;
- if (v == unsnapped[0] || v == unsnapped[1] || v == unsnapped[2]) {
+ if (ELEM(v, unsnapped[0], unsnapped[1], unsnapped[2])) {
mul_v2_m3v3(proj_co[i], axis_mat, co);
}
else {
@@ -4922,7 +4922,7 @@ static void build_center_ngon(BevelParams *bp, BMesh *bm, BevVert *bv, int mat_n
BLI_array_append(vv, mesh_vert(vm, i, ns2, ns2)->v);
if (frep) {
BLI_array_append(vf, frep);
- if (v == frep_unsnapped[0] || v == frep_unsnapped[1] || v == frep_unsnapped[2]) {
+ if (ELEM(v, frep_unsnapped[0], frep_unsnapped[1], frep_unsnapped[2])) {
BLI_array_append(ve, NULL);
}
else {
@@ -5299,7 +5299,7 @@ static void snap_edges_for_vmesh_vert(int i,
int previ = (i + n_bndv - 1) % n_bndv;
/* Make jj and kk be the j and k indices for this corner. */
int jj = corner < 2 ? j : j + 1;
- int kk = (corner == 0 || corner == 3) ? k : k + 1;
+ int kk = ELEM(corner, 0, 3) ? k : k + 1;
if (jj < ns2 && kk < ns2) {
; /* No snap. */
}
@@ -5376,7 +5376,7 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert
for (int i = 0; i < n_bndv; i++) {
for (int j = 0; j <= ns2; j++) {
for (int k = 0; k <= ns; k++) {
- if (j == 0 && (ELEM(k, 0, ns))) {
+ if (j == 0 && ELEM(k, 0, ns)) {
continue; /* Boundary corners already made. */
}
if (!is_canon(vm, i, j, k)) {
@@ -5765,7 +5765,7 @@ static BMFace *bevel_build_poly(BevelParams *bp, BMesh *bm, BevVert *bv)
BLI_array_append(bmverts, bndv->nv.v);
if (repface) {
BLI_array_append(bmfaces, repface);
- if (bndv == unsnapped[0] || bndv == unsnapped[1] || bndv == unsnapped[2]) {
+ if (ELEM(bndv, unsnapped[0], unsnapped[1], unsnapped[2])) {
BLI_array_append(bmedges, NULL);
}
else {
@@ -6285,7 +6285,7 @@ static void find_bevel_edge_order(BMesh *bm, BevVert *bv, BMEdge *first_bme)
BMLoop *l;
BM_ITER_ELEM (l, &iter, bme, BM_LOOPS_OF_EDGE) {
BMFace *f = l->f;
- if ((l->prev->e == bme2 || l->next->e == bme2)) {
+ if (l->prev->e == bme2 || l->next->e == bme2) {
if (!bestf || l->v == bv->v) {
bestf = f;
}
@@ -7083,7 +7083,7 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
}
}
- /* Fix UVs along end edge joints. A nop unless other side built already. */
+ /* Fix UVs along end edge joints. A NOP unless other side built already. */
/* TODO: If some seam, may want to do selective merge. */
if (!bv1->any_seam && bv1->vmesh->mesh_kind == M_NONE) {
bev_merge_end_uvs(bm, bv1, e1);
diff --git a/source/blender/bmesh/tools/bmesh_bisect_plane.c b/source/blender/bmesh/tools/bmesh_bisect_plane.c
index 3d7bacf7080..444f45277ca 100644
--- a/source/blender/bmesh/tools/bmesh_bisect_plane.c
+++ b/source/blender/bmesh/tools/bmesh_bisect_plane.c
@@ -170,7 +170,7 @@ static void bm_face_bisect_verts(
BLI_assert(BM_VERT_DIR(l_iter->v) == 0);
/* If both are -1 or 1, or both are zero: don't flip 'inside' var while walking. */
- BM_VERT_SKIP(l_iter->v) = (((BM_VERT_DIR(l_iter->prev->v) ^ BM_VERT_DIR(l_iter->next->v))) ==
+ BM_VERT_SKIP(l_iter->v) = ((BM_VERT_DIR(l_iter->prev->v) ^ BM_VERT_DIR(l_iter->next->v)) ==
0);
STACK_PUSH(vert_split_arr, l_iter->v);
@@ -463,7 +463,7 @@ void BM_mesh_bisect_plane(BMesh *bm,
}
vert_is_center_disable(v);
- BM_VERT_DIR(v) = plane_point_test_v3(plane, v->co, eps, &(BM_VERT_DIST(v)));
+ BM_VERT_DIR(v) = plane_point_test_v3(plane, v->co, eps, &BM_VERT_DIST(v));
if (BM_VERT_DIR(v) == 0) {
if (oflag_center) {
diff --git a/source/blender/bmesh/tools/bmesh_boolean.cc b/source/blender/bmesh/tools/bmesh_boolean.cc
index 216c73564c8..288a0d9ab74 100644
--- a/source/blender/bmesh/tools/bmesh_boolean.cc
+++ b/source/blender/bmesh/tools/bmesh_boolean.cc
@@ -187,7 +187,7 @@ static bool apply_mesh_output_to_bmesh(BMesh *bm, IMesh &m_out, bool keep_hidden
float co[3];
const double3 &d_co = vertp->co;
for (int i = 0; i < 3; ++i) {
- co[i] = static_cast<float>(d_co[i]);
+ co[i] = float(d_co[i]);
}
BMVert *bmv = BM_vert_create(bm, co, nullptr, BM_CREATE_NOP);
new_bmvs[v] = bmv;
@@ -466,16 +466,16 @@ bool BM_mesh_boolean_knife(BMesh *bm,
blender::meshintersect::BoolOpType::None);
}
#else
-bool BM_mesh_boolean(BMesh *UNUSED(bm),
+bool BM_mesh_boolean(BMesh * /*bm*/,
struct BMLoop *(*looptris)[3],
- const int UNUSED(looptris_tot),
+ const int /*looptris_tot*/,
int (*test_fn)(BMFace *, void *),
- void *UNUSED(user_data),
- const int UNUSED(nshapes),
- const bool UNUSED(use_self),
- const bool UNUSED(keep_hidden),
- const bool UNUSED(hole_tolerant),
- const int UNUSED(boolean_mode))
+ void * /*user_data*/,
+ const int /*nshapes*/,
+ const bool /*use_self*/,
+ const bool /*keep_hidden*/,
+ const bool /*hole_tolerant*/,
+ const int /*boolean_mode*/)
{
UNUSED_VARS(looptris, test_fn);
return false;
@@ -489,16 +489,16 @@ bool BM_mesh_boolean(BMesh *UNUSED(bm),
* TODO: need to ensure that "selected/non-selected" flag of original faces gets propagated
* to the intersection result faces.
*/
-bool BM_mesh_boolean_knife(BMesh *UNUSED(bm),
+bool BM_mesh_boolean_knife(BMesh * /*bm*/,
struct BMLoop *(*looptris)[3],
- const int UNUSED(looptris_tot),
+ const int /*looptris_tot*/,
int (*test_fn)(BMFace *, void *),
- void *UNUSED(user_data),
- const int UNUSED(nshapes),
- const bool UNUSED(use_self),
- const bool UNUSED(use_separate_all),
- const bool UNUSED(hole_tolerant),
- const bool UNUSED(keep_hidden))
+ void * /*user_data*/,
+ const int /*nshapes*/,
+ const bool /*use_self*/,
+ const bool /*use_separate_all*/,
+ const bool /*hole_tolerant*/,
+ const bool /*keep_hidden*/)
{
UNUSED_VARS(looptris, test_fn);
return false;
diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
index 81a392d38a5..1ea799f64e0 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
@@ -304,7 +304,7 @@ static void bm_decim_build_edge_cost_single(BMEdge *e,
const float e_weight = 2.0f - (vweights[BM_elem_index_get(e->v1)] +
vweights[BM_elem_index_get(e->v2)]);
if (e_weight) {
- cost += (BM_edge_calc_length(e) * ((e_weight * vweight_factor)));
+ cost += (BM_edge_calc_length(e) * (e_weight * vweight_factor));
}
}
@@ -618,9 +618,9 @@ static void bm_decim_triangulate_end(BMesh *bm, const int edges_tri_tot)
(BM_loop_is_manifold(l) && ((l)->v != (l)->radial_next->v) && \
(l_a_index == BM_elem_index_get(l)) && (l_a_index == BM_elem_index_get((l)->radial_next)))
- if ((l_a->f->len == 3 && l_b->f->len == 3) && (!CAN_LOOP_MERGE(l_a->next)) &&
- (!CAN_LOOP_MERGE(l_a->prev)) && (!CAN_LOOP_MERGE(l_b->next)) &&
- (!CAN_LOOP_MERGE(l_b->prev))) {
+ if ((l_a->f->len == 3 && l_b->f->len == 3) && !CAN_LOOP_MERGE(l_a->next) &&
+ !CAN_LOOP_MERGE(l_a->prev) && !CAN_LOOP_MERGE(l_b->next) &&
+ !CAN_LOOP_MERGE(l_b->prev)) {
BMVert *vquad[4] = {
e->v1,
BM_vert_in_edge(e, l_a->next->v) ? l_a->prev->v : l_a->next->v,
diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
index 41c995a52bf..8a11815bd4c 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
@@ -330,7 +330,7 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm,
}
while ((BLI_heap_is_empty(eheap) == false) &&
- (BLI_heap_node_value((enode_top = BLI_heap_top(eheap))) < angle_limit_cos_neg)) {
+ (BLI_heap_node_value(enode_top = BLI_heap_top(eheap)) < angle_limit_cos_neg)) {
BMFace *f_new = NULL;
BMEdge *e;
@@ -451,7 +451,7 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm,
}
while ((BLI_heap_is_empty(vheap) == false) &&
- (BLI_heap_node_value((vnode_top = BLI_heap_top(vheap))) < angle_limit)) {
+ (BLI_heap_node_value(vnode_top = BLI_heap_top(vheap)) < angle_limit)) {
BMEdge *e_new = NULL;
BMVert *v;
diff --git a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
index bd479bad945..02f0a25ea06 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
@@ -229,14 +229,15 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool
#ifdef USE_WALKER
/* Walk over selected elements starting at active */
- BMW_init(&walker,
- bm,
- BMW_CONNECTED_VERTEX,
- ELE_VERT_TAG,
- BMW_MASK_NOP,
- BMW_MASK_NOP,
- BMW_FLAG_NOP, /* don't use BMW_FLAG_TEST_HIDDEN here since we want to desel all */
- BMW_NIL_LAY);
+ BMW_init(
+ &walker,
+ bm,
+ BMW_CONNECTED_VERTEX,
+ ELE_VERT_TAG,
+ BMW_MASK_NOP,
+ BMW_MASK_NOP,
+ BMW_FLAG_NOP, /* don't use #BMW_FLAG_TEST_HIDDEN here since we want to deselect all. */
+ BMW_NIL_LAY);
BLI_assert(walker.order == BMW_BREADTH_FIRST);
for (v = BMW_begin(&walker, v_first); v != NULL; v = BMW_step(&walker)) {
diff --git a/source/blender/bmesh/tools/bmesh_edgenet.c b/source/blender/bmesh/tools/bmesh_edgenet.c
index 110017739b9..020f2613f7d 100644
--- a/source/blender/bmesh/tools/bmesh_edgenet.c
+++ b/source/blender/bmesh/tools/bmesh_edgenet.c
@@ -37,7 +37,7 @@ enum {
*/
static bool bm_edge_step_ok(BMEdge *e)
{
- return BM_elem_flag_test(e, BM_ELEM_TAG) && (ELEM(e->l, NULL, e->l->radial_next));
+ return BM_elem_flag_test(e, BM_ELEM_TAG) && ELEM(e->l, NULL, e->l->radial_next);
}
static int bm_edge_face(BMEdge *e)
diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.c b/source/blender/bmesh/tools/bmesh_edgesplit.c
index a703b5338ef..03ff6b39d0e 100644
--- a/source/blender/bmesh/tools/bmesh_edgesplit.c
+++ b/source/blender/bmesh/tools/bmesh_edgesplit.c
@@ -51,8 +51,8 @@ void BM_mesh_edgesplit(BMesh *bm,
*/
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
- if (UNLIKELY(((BM_elem_flag_test(e->v1, BM_ELEM_TAG) == false) &&
- (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == false)))) {
+ if (UNLIKELY((BM_elem_flag_test(e->v1, BM_ELEM_TAG) == false) &&
+ (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == false))) {
BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
}
diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c
index 8e1dfbebe47..a06efe8da96 100644
--- a/source/blender/bmesh/tools/bmesh_intersect.c
+++ b/source/blender/bmesh/tools/bmesh_intersect.c
@@ -1263,7 +1263,7 @@ bool BM_mesh_intersect(BMesh *bm,
/* only start on an edge-case */
/* pass */
}
- else if ((!BM_elem_flag_test(v_a, BM_ELEM_TAG)) && (!BM_elem_flag_test(v_b, BM_ELEM_TAG))) {
+ else if (!BM_elem_flag_test(v_a, BM_ELEM_TAG) && !BM_elem_flag_test(v_b, BM_ELEM_TAG)) {
/* simple case, single edge spans face */
BMVert **splice_pair;
BM_elem_flag_enable(e_pair[1], BM_ELEM_TAG);
@@ -1490,7 +1490,7 @@ bool BM_mesh_intersect(BMesh *bm,
(void)use_separate;
#endif /* USE_SEPARATE */
- if ((boolean_mode != BMESH_ISECT_BOOLEAN_NONE)) {
+ if (boolean_mode != BMESH_ISECT_BOOLEAN_NONE) {
BVHTree *tree_pair[2] = {tree_a, tree_b};
/* group vars */
diff --git a/source/blender/bmesh/tools/bmesh_path.c b/source/blender/bmesh/tools/bmesh_path.c
index 5f1003ad808..764ce323923 100644
--- a/source/blender/bmesh/tools/bmesh_path.c
+++ b/source/blender/bmesh/tools/bmesh_path.c
@@ -231,7 +231,7 @@ static void edgetag_add_adjacent(HeapSimple *heap,
BM_ITER_ELEM (v, &viter, e_a, BM_VERTS_OF_EDGE) {
/* Don't walk over previous vertex. */
- if ((edges_prev[e_a_index]) && (BM_vert_in_edge(edges_prev[e_a_index], v))) {
+ if ((edges_prev[e_a_index]) && BM_vert_in_edge(edges_prev[e_a_index], v)) {
continue;
}
diff --git a/source/blender/bmesh/tools/bmesh_path_region.c b/source/blender/bmesh/tools/bmesh_path_region.c
index 1e464108b84..a90bf87ebb0 100644
--- a/source/blender/bmesh/tools/bmesh_path_region.c
+++ b/source/blender/bmesh/tools/bmesh_path_region.c
@@ -228,7 +228,7 @@ static LinkNode *mesh_calc_path_region_elem(BMesh *bm,
/* Walk along the chain, fill in values until we reach a vertex with 3+ edges. */
{
BMEdge *e_chain = e;
- while (BM_vert_is_edge_pair_manifold(v_b) && ((depths[side][v_b_index] == -1))) {
+ while (BM_vert_is_edge_pair_manifold(v_b) && (depths[side][v_b_index] == -1)) {
depths[side][v_b_index] = pass;
BMEdge *e_chain_next = BM_DISK_EDGE_NEXT(e_chain, v_b);
diff --git a/source/blender/bmesh/tools/bmesh_path_uv.c b/source/blender/bmesh/tools/bmesh_path_uv.c
index 6531677fce6..ecc92fd09a4 100644
--- a/source/blender/bmesh/tools/bmesh_path_uv.c
+++ b/source/blender/bmesh/tools/bmesh_path_uv.c
@@ -354,7 +354,7 @@ struct LinkNode *BM_mesh_calc_path_uv_edge(BMesh *bm,
while (!BLI_heapsimple_is_empty(heap)) {
l = BLI_heapsimple_pop_min(heap);
- if ((l->e == l_dst->e) && (BM_loop_uv_share_edge_check(l, l_dst, params->cd_loop_uv_offset))) {
+ if ((l->e == l_dst->e) && BM_loop_uv_share_edge_check(l, l_dst, params->cd_loop_uv_offset)) {
break;
}
@@ -364,7 +364,7 @@ struct LinkNode *BM_mesh_calc_path_uv_edge(BMesh *bm,
}
}
- if ((l->e == l_dst->e) && (BM_loop_uv_share_edge_check(l, l_dst, params->cd_loop_uv_offset))) {
+ if ((l->e == l_dst->e) && BM_loop_uv_share_edge_check(l, l_dst, params->cd_loop_uv_offset)) {
do {
BLI_linklist_prepend(&path, l);
} while ((l = loops_prev[BM_elem_index_get(l)]));
diff --git a/source/blender/bmesh/tools/bmesh_region_match.c b/source/blender/bmesh/tools/bmesh_region_match.c
index d693755053c..8e971aeddb0 100644
--- a/source/blender/bmesh/tools/bmesh_region_match.c
+++ b/source/blender/bmesh/tools/bmesh_region_match.c
@@ -510,7 +510,7 @@ static void bm_uuidwalk_pass_add(UUIDWalk *uuidwalk,
do {
if (!BLI_ghash_haskey(uuidwalk->faces_uuid, l_iter_radial->f) &&
!BLI_gset_haskey(faces_step_next, l_iter_radial->f) &&
- (bm_uuidwalk_face_test(uuidwalk, l_iter_radial->f))) {
+ bm_uuidwalk_face_test(uuidwalk, l_iter_radial->f)) {
BLI_gset_insert(faces_step_next, l_iter_radial->f);
/* add to fstep */
diff --git a/source/blender/bmesh/tools/bmesh_wireframe.c b/source/blender/bmesh/tools/bmesh_wireframe.c
index 14ec45f14b0..bdc36559e05 100644
--- a/source/blender/bmesh/tools/bmesh_wireframe.c
+++ b/source/blender/bmesh/tools/bmesh_wireframe.c
@@ -175,7 +175,7 @@ void BM_mesh_wireframe(BMesh *bm,
BMVert **verts_neg = MEM_mallocN(sizeof(BMVert *) * totvert_orig, __func__);
BMVert **verts_pos = MEM_mallocN(sizeof(BMVert *) * totvert_orig, __func__);
- /* Will over-alloc, but makes for easy lookups by index to keep aligned. */
+ /* Will over-allocate, but makes for easy lookups by index to keep aligned. */
BMVert **verts_boundary = use_boundary ? MEM_mallocN(sizeof(BMVert *) * totvert_orig, __func__) :
NULL;
diff --git a/source/blender/compositor/intern/COM_CPUDevice.cc b/source/blender/compositor/intern/COM_CPUDevice.cc
index 93c0b233752..916c7e1a411 100644
--- a/source/blender/compositor/intern/COM_CPUDevice.cc
+++ b/source/blender/compositor/intern/COM_CPUDevice.cc
@@ -16,7 +16,7 @@ void CPUDevice::execute(WorkPackage *work_package)
{
switch (work_package->type) {
case eWorkPackageType::Tile: {
- const unsigned int chunk_number = work_package->chunk_number;
+ const uint chunk_number = work_package->chunk_number;
ExecutionGroup *execution_group = work_package->execution_group;
execution_group->get_output_operation()->execute_region(&work_package->rect, chunk_number);
diff --git a/source/blender/compositor/intern/COM_ChunkOrder.cc b/source/blender/compositor/intern/COM_ChunkOrder.cc
index 38298840bf0..acc19155049 100644
--- a/source/blender/compositor/intern/COM_ChunkOrder.cc
+++ b/source/blender/compositor/intern/COM_ChunkOrder.cc
@@ -7,7 +7,7 @@
namespace blender::compositor {
-void ChunkOrder::update_distance(ChunkOrderHotspot *hotspots, unsigned int len_hotspots)
+void ChunkOrder::update_distance(ChunkOrderHotspot *hotspots, uint len_hotspots)
{
double new_distance = DBL_MAX;
for (int index = 0; index < len_hotspots; index++) {
diff --git a/source/blender/compositor/intern/COM_ChunkOrder.h b/source/blender/compositor/intern/COM_ChunkOrder.h
index 927eab97ccd..ef65d90dd3a 100644
--- a/source/blender/compositor/intern/COM_ChunkOrder.h
+++ b/source/blender/compositor/intern/COM_ChunkOrder.h
@@ -7,20 +7,22 @@
# include "MEM_guardedalloc.h"
#endif
+#include "BLI_sys_types.h"
+
#include "COM_ChunkOrderHotspot.h"
namespace blender::compositor {
/** Helper to determine the order how chunks are prioritized during execution. */
struct ChunkOrder {
- unsigned int index = 0;
+ uint index = 0;
int x = 0;
int y = 0;
double distance = 0.0;
friend bool operator<(const ChunkOrder &a, const ChunkOrder &b);
- void update_distance(ChunkOrderHotspot *hotspots, unsigned int len_hotspots);
+ void update_distance(ChunkOrderHotspot *hotspots, uint len_hotspots);
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:ChunkOrderHotspot")
diff --git a/source/blender/compositor/intern/COM_ChunkOrderHotspot.cc b/source/blender/compositor/intern/COM_ChunkOrderHotspot.cc
index b9179c0a910..5b9d2fa2797 100644
--- a/source/blender/compositor/intern/COM_ChunkOrderHotspot.cc
+++ b/source/blender/compositor/intern/COM_ChunkOrderHotspot.cc
@@ -10,8 +10,8 @@ double ChunkOrderHotspot::calc_distance(int x, int y)
{
int dx = this->x - x;
int dy = this->y - y;
- double result = sqrt((double)(dx * dx + dy * dy));
- result += (double)this->addition;
+ double result = sqrt(double(dx * dx + dy * dy));
+ result += double(this->addition);
return result;
}
diff --git a/source/blender/compositor/intern/COM_Debug.cc b/source/blender/compositor/intern/COM_Debug.cc
index d0f0be590f6..a670af5eaca 100644
--- a/source/blender/compositor/intern/COM_Debug.cc
+++ b/source/blender/compositor/intern/COM_Debug.cc
@@ -305,7 +305,7 @@ bool DebugInfo::graphviz_system(const ExecutionSystem *system, char *str, int ma
for (NodeOperation *operation : group->operations_) {
- sprintf(strbuf, "_%p", group);
+ BLI_snprintf(strbuf, sizeof(strbuf), "_%p", group);
op_groups[operation].push_back(std::string(strbuf));
len += graphviz_operation(
@@ -428,7 +428,7 @@ void DebugInfo::graphviz(const ExecutionSystem *system, StringRefNull name)
else {
BLI_strncpy(basename, (name + ".dot").c_str(), sizeof(basename));
}
- BLI_join_dirfile(filepath, sizeof(filepath), BKE_tempdir_session(), basename);
+ BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_session(), basename);
file_index_++;
std::cout << "Writing compositor debug to: " << filepath << "\n";
diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cc b/source/blender/compositor/intern/COM_ExecutionGroup.cc
index 6f2d4faffb1..c9002b535ed 100644
--- a/source/blender/compositor/intern/COM_ExecutionGroup.cc
+++ b/source/blender/compositor/intern/COM_ExecutionGroup.cc
@@ -126,7 +126,7 @@ void ExecutionGroup::init_work_packages()
work_packages_.clear();
if (chunks_len_ != 0) {
work_packages_.resize(chunks_len_);
- for (unsigned int index = 0; index < chunks_len_; index++) {
+ for (uint index = 0; index < chunks_len_; index++) {
work_packages_[index].type = eWorkPackageType::Tile;
work_packages_[index].state = eWorkPackageState::NotScheduled;
work_packages_[index].execution_group = this;
@@ -138,7 +138,7 @@ void ExecutionGroup::init_work_packages()
void ExecutionGroup::init_read_buffer_operations()
{
- unsigned int max_offset = 0;
+ uint max_offset = 0;
for (NodeOperation *operation : operations_) {
if (operation->get_flags().is_read_buffer_operation) {
ReadBufferOperation *read_operation = static_cast<ReadBufferOperation *>(operation);
@@ -167,7 +167,7 @@ void ExecutionGroup::deinit_execution()
bTree_ = nullptr;
}
-void ExecutionGroup::determine_resolution(unsigned int resolution[2])
+void ExecutionGroup::determine_resolution(uint resolution[2])
{
NodeOperation *operation = this->get_output_operation();
resolution[0] = operation->get_width();
@@ -193,9 +193,9 @@ void ExecutionGroup::init_number_of_chunks()
}
}
-blender::Array<unsigned int> ExecutionGroup::get_execution_order() const
+blender::Array<uint> ExecutionGroup::get_execution_order() const
{
- blender::Array<unsigned int> chunk_order(chunks_len_);
+ blender::Array<uint> chunk_order(chunks_len_);
for (int chunk_index = 0; chunk_index < chunks_len_; chunk_index++) {
chunk_order[chunk_index] = chunk_index;
}
@@ -218,7 +218,7 @@ blender::Array<unsigned int> ExecutionGroup::get_execution_order() const
switch (order_type) {
case ChunkOrdering::Random: {
static blender::RandomNumberGenerator rng;
- blender::MutableSpan<unsigned int> span = chunk_order.as_mutable_span();
+ blender::MutableSpan<uint> span = chunk_order.as_mutable_span();
/* Shuffle twice to make it more random. */
rng.shuffle(span);
rng.shuffle(span);
@@ -243,12 +243,12 @@ blender::Array<unsigned int> ExecutionGroup::get_execution_order() const
break;
}
case ChunkOrdering::RuleOfThirds: {
- unsigned int tx = border_width / 6;
- unsigned int ty = border_height / 6;
- unsigned int mx = border_width / 2;
- unsigned int my = border_height / 2;
- unsigned int bx = mx + 2 * tx;
- unsigned int by = my + 2 * ty;
+ uint tx = border_width / 6;
+ uint ty = border_height / 6;
+ uint mx = border_width / 2;
+ uint my = border_height / 2;
+ uint bx = mx + 2 * tx;
+ uint by = my + 2 * ty;
float addition = chunks_len_ / COM_RULE_OF_THIRDS_DIVIDER;
ChunkOrderHotspot hotspots[9]{
@@ -300,21 +300,21 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
if (chunks_len_ == 0) {
return;
} /** \note Early break out. */
- unsigned int chunk_index;
+ uint chunk_index;
execution_start_time_ = PIL_check_seconds_timer();
chunks_finished_ = 0;
bTree_ = bTree;
- blender::Array<unsigned int> chunk_order = get_execution_order();
+ blender::Array<uint> chunk_order = get_execution_order();
DebugInfo::execution_group_started(this);
DebugInfo::graphviz(graph);
bool breaked = false;
bool finished = false;
- unsigned int start_index = 0;
+ uint start_index = 0;
const int max_number_evaluated = BLI_system_thread_count() * 2;
while (!finished && !breaked) {
@@ -399,7 +399,7 @@ void ExecutionGroup::finalize_chunk_execution(int chunk_number, MemoryBuffer **m
atomic_add_and_fetch_u(&chunks_finished_, 1);
if (memory_buffers) {
- for (unsigned int index = 0; index < max_read_buffer_offset_; index++) {
+ for (uint index = 0; index < max_read_buffer_offset_; index++) {
MemoryBuffer *buffer = memory_buffers[index];
if (buffer) {
if (buffer->is_temporarily()) {
@@ -424,8 +424,8 @@ void ExecutionGroup::finalize_chunk_execution(int chunk_number, MemoryBuffer **m
}
inline void ExecutionGroup::determine_chunk_rect(rcti *r_rect,
- const unsigned int x_chunk,
- const unsigned int y_chunk) const
+ const uint x_chunk,
+ const uint y_chunk) const
{
const int border_width = BLI_rcti_size_x(&viewer_border_);
const int border_height = BLI_rcti_size_y(&viewer_border_);
@@ -434,10 +434,10 @@ inline void ExecutionGroup::determine_chunk_rect(rcti *r_rect,
BLI_rcti_init(r_rect, viewer_border_.xmin, border_width, viewer_border_.ymin, border_height);
}
else {
- const unsigned int minx = x_chunk * chunk_size_ + viewer_border_.xmin;
- const unsigned int miny = y_chunk * chunk_size_ + viewer_border_.ymin;
- const unsigned int width = MIN2((unsigned int)viewer_border_.xmax, width_);
- const unsigned int height = MIN2((unsigned int)viewer_border_.ymax, height_);
+ const uint minx = x_chunk * chunk_size_ + viewer_border_.xmin;
+ const uint miny = y_chunk * chunk_size_ + viewer_border_.ymin;
+ const uint width = MIN2(uint(viewer_border_.xmax), width_);
+ const uint height = MIN2(uint(viewer_border_.ymax), height_);
BLI_rcti_init(r_rect,
MIN2(minx, width_),
MIN2(minx + chunk_size_, width),
@@ -446,10 +446,10 @@ inline void ExecutionGroup::determine_chunk_rect(rcti *r_rect,
}
}
-void ExecutionGroup::determine_chunk_rect(rcti *r_rect, const unsigned int chunk_number) const
+void ExecutionGroup::determine_chunk_rect(rcti *r_rect, const uint chunk_number) const
{
- const unsigned int y_chunk = chunk_number / x_chunks_len_;
- const unsigned int x_chunk = chunk_number - (y_chunk * x_chunks_len_);
+ const uint y_chunk = chunk_number / x_chunks_len_;
+ const uint x_chunk = chunk_number - (y_chunk * x_chunks_len_);
determine_chunk_rect(r_rect, x_chunk, y_chunk);
}
@@ -480,14 +480,14 @@ bool ExecutionGroup::schedule_area_when_possible(ExecutionSystem *graph, rcti *a
int maxx = min_ii(area->xmax - viewer_border_.xmin, viewer_border_.xmax - viewer_border_.xmin);
int miny = max_ii(area->ymin - viewer_border_.ymin, 0);
int maxy = min_ii(area->ymax - viewer_border_.ymin, viewer_border_.ymax - viewer_border_.ymin);
- int minxchunk = minx / (int)chunk_size_;
- int maxxchunk = (maxx + (int)chunk_size_ - 1) / (int)chunk_size_;
- int minychunk = miny / (int)chunk_size_;
- int maxychunk = (maxy + (int)chunk_size_ - 1) / (int)chunk_size_;
+ int minxchunk = minx / int(chunk_size_);
+ int maxxchunk = (maxx + int(chunk_size_) - 1) / int(chunk_size_);
+ int minychunk = miny / int(chunk_size_);
+ int maxychunk = (maxy + int(chunk_size_) - 1) / int(chunk_size_);
minxchunk = max_ii(minxchunk, 0);
minychunk = max_ii(minychunk, 0);
- maxxchunk = min_ii(maxxchunk, (int)x_chunks_len_);
- maxychunk = min_ii(maxychunk, (int)y_chunks_len_);
+ maxxchunk = min_ii(maxxchunk, int(x_chunks_len_));
+ maxychunk = min_ii(maxychunk, int(y_chunks_len_));
bool result = true;
for (indexx = minxchunk; indexx < maxxchunk; indexx++) {
@@ -501,7 +501,7 @@ bool ExecutionGroup::schedule_area_when_possible(ExecutionSystem *graph, rcti *a
return result;
}
-bool ExecutionGroup::schedule_chunk(unsigned int chunk_number)
+bool ExecutionGroup::schedule_chunk(uint chunk_number)
{
WorkPackage &work_package = work_packages_[chunk_number];
if (work_package.state == eWorkPackageState::NotScheduled) {
@@ -516,10 +516,10 @@ bool ExecutionGroup::schedule_chunk_when_possible(ExecutionSystem *graph,
const int chunk_x,
const int chunk_y)
{
- if (chunk_x < 0 || chunk_x >= (int)x_chunks_len_) {
+ if (chunk_x < 0 || chunk_x >= int(x_chunks_len_)) {
return true;
}
- if (chunk_y < 0 || chunk_y >= (int)y_chunks_len_) {
+ if (chunk_y < 0 || chunk_y >= int(y_chunks_len_)) {
return true;
}
diff --git a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc b/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc
index ceb52feb9b4..11e3c1507d9 100644
--- a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc
+++ b/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc
@@ -271,7 +271,7 @@ void FullFrameExecutionModel::update_progress_bar()
{
const bNodeTree *tree = context_.get_bnodetree();
if (tree) {
- const float progress = num_operations_finished_ / static_cast<float>(operations_.size());
+ const float progress = num_operations_finished_ / float(operations_.size());
tree->progress(tree->prh, progress);
char buf[128];
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cc b/source/blender/compositor/intern/COM_MemoryBuffer.cc
index ea2a85e8ea9..539e1179bc8 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.cc
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.cc
@@ -133,8 +133,8 @@ MemoryBuffer *MemoryBuffer::inflate() const
float MemoryBuffer::get_max_value() const
{
float result = buffer_[0];
- const unsigned int size = this->buffer_len();
- unsigned int i;
+ const uint size = this->buffer_len();
+ uint i;
const float *fp_src = buffer_;
@@ -266,7 +266,7 @@ void MemoryBuffer::copy_from(const uchar *src,
const float *row_end = to_elem + width * this->elem_stride;
while (to_elem < row_end) {
for (int i = 0; i < elem_size; i++) {
- to_elem[i] = ((float)from_elem[i]) * (1.0f / 255.0f);
+ to_elem[i] = float(from_elem[i]) * (1.0f / 255.0f);
}
to_elem += this->elem_stride;
from_elem += elem_stride;
@@ -427,7 +427,7 @@ void MemoryBuffer::read_elem_filtered(
const float deriv[2][2] = {{dx[0], dx[1]}, {dy[0], dy[1]}};
- float inv_width = 1.0f / (float)this->get_width(), inv_height = 1.0f / (float)this->get_height();
+ float inv_width = 1.0f / float(this->get_width()), inv_height = 1.0f / float(this->get_height());
/* TODO(sergey): Render pipeline uses normalized coordinates and derivatives,
* but compositor uses pixel space. For now let's just divide the values and
* switch compositor to normalized space for EWA later.
@@ -463,8 +463,8 @@ void MemoryBuffer::readEWA(float *result, const float uv[2], const float derivat
}
else {
BLI_assert(datatype_ == DataType::Color);
- float inv_width = 1.0f / (float)this->get_width(),
- inv_height = 1.0f / (float)this->get_height();
+ float inv_width = 1.0f / float(this->get_width()),
+ inv_height = 1.0f / float(this->get_height());
/* TODO(sergey): Render pipeline uses normalized coordinates and derivatives,
* but compositor uses pixel space. For now let's just divide the values and
* switch compositor to normalized space for EWA later.
diff --git a/source/blender/compositor/intern/COM_MemoryProxy.cc b/source/blender/compositor/intern/COM_MemoryProxy.cc
index 42d0f86843d..723e8b3ab9b 100644
--- a/source/blender/compositor/intern/COM_MemoryProxy.cc
+++ b/source/blender/compositor/intern/COM_MemoryProxy.cc
@@ -14,7 +14,7 @@ MemoryProxy::MemoryProxy(DataType datatype)
datatype_ = datatype;
}
-void MemoryProxy::allocate(unsigned int width, unsigned int height)
+void MemoryProxy::allocate(uint width, uint height)
{
rcti result;
result.xmin = 0;
diff --git a/source/blender/compositor/intern/COM_MetaData.cc b/source/blender/compositor/intern/COM_MetaData.cc
index 9ee3d7e5c22..94a0bc8706b 100644
--- a/source/blender/compositor/intern/COM_MetaData.cc
+++ b/source/blender/compositor/intern/COM_MetaData.cc
@@ -72,7 +72,7 @@ void MetaDataExtractCallbackData::set_cryptomatte_keys(blender::StringRef crypto
void MetaDataExtractCallbackData::extract_cryptomatte_meta_data(void *_data,
const char *propname,
char *propvalue,
- int UNUSED(len))
+ int /*len*/)
{
MetaDataExtractCallbackData *data = static_cast<MetaDataExtractCallbackData *>(_data);
blender::StringRefNull key(propname);
diff --git a/source/blender/compositor/intern/COM_MultiThreadedOperation.h b/source/blender/compositor/intern/COM_MultiThreadedOperation.h
index 9ec81fa834e..355081c374d 100644
--- a/source/blender/compositor/intern/COM_MultiThreadedOperation.h
+++ b/source/blender/compositor/intern/COM_MultiThreadedOperation.h
@@ -24,9 +24,9 @@ class MultiThreadedOperation : public NodeOperation {
/**
* Called before an update memory buffer pass is executed. Single-threaded calls.
*/
- virtual void update_memory_buffer_started(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
- Span<MemoryBuffer *> UNUSED(inputs))
+ virtual void update_memory_buffer_started(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
+ Span<MemoryBuffer *> /*inputs*/)
{
}
@@ -40,9 +40,9 @@ class MultiThreadedOperation : public NodeOperation {
/**
* Called after an update memory buffer pass is executed. Single-threaded calls.
*/
- virtual void update_memory_buffer_finished(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
- Span<MemoryBuffer *> UNUSED(inputs))
+ virtual void update_memory_buffer_finished(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
+ Span<MemoryBuffer *> /*inputs*/)
{
}
diff --git a/source/blender/compositor/intern/COM_Node.cc b/source/blender/compositor/intern/COM_Node.cc
index a71c7868518..c1a8740d8ea 100644
--- a/source/blender/compositor/intern/COM_Node.cc
+++ b/source/blender/compositor/intern/COM_Node.cc
@@ -53,10 +53,10 @@ Node::Node(bNode *editor_node, bool create_sockets)
Node::~Node()
{
while (!outputs_.is_empty()) {
- delete (outputs_.pop_last());
+ delete outputs_.pop_last();
}
while (!inputs_.is_empty()) {
- delete (inputs_.pop_last());
+ delete inputs_.pop_last();
}
}
@@ -81,12 +81,12 @@ void Node::add_output_socket(DataType datatype, bNodeSocket *bSocket)
outputs_.append(socket);
}
-NodeOutput *Node::get_output_socket(unsigned int index) const
+NodeOutput *Node::get_output_socket(uint index) const
{
return outputs_[index];
}
-NodeInput *Node::get_input_socket(unsigned int index) const
+NodeInput *Node::get_input_socket(uint index) const
{
return inputs_[index];
}
diff --git a/source/blender/compositor/intern/COM_NodeOperation.cc b/source/blender/compositor/intern/COM_NodeOperation.cc
index 3867b1d5c10..ab9b5ad1ad6 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.cc
+++ b/source/blender/compositor/intern/COM_NodeOperation.cc
@@ -84,12 +84,12 @@ std::optional<NodeOperationHash> NodeOperation::generate_hash()
return hash;
}
-NodeOperationOutput *NodeOperation::get_output_socket(unsigned int index)
+NodeOperationOutput *NodeOperation::get_output_socket(uint index)
{
return &outputs_[index];
}
-NodeOperationInput *NodeOperation::get_input_socket(unsigned int index)
+NodeOperationInput *NodeOperation::get_input_socket(uint index)
{
return &inputs_[index];
}
@@ -106,7 +106,7 @@ void NodeOperation::add_output_socket(DataType datatype)
void NodeOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
{
- unsigned int used_canvas_index = 0;
+ uint used_canvas_index = 0;
if (canvas_input_index_ == RESOLUTION_INPUT_ANY) {
for (NodeOperationInput &input : inputs_) {
rcti any_area = COM_AREA_NONE;
@@ -130,7 +130,7 @@ void NodeOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
rcti unused_area = COM_AREA_NONE;
const rcti &local_preferred_area = r_area;
- for (unsigned int index = 0; index < inputs_.size(); index++) {
+ for (uint index = 0; index < inputs_.size(); index++) {
if (index == used_canvas_index) {
continue;
}
@@ -141,7 +141,7 @@ void NodeOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
}
}
-void NodeOperation::set_canvas_input_index(unsigned int index)
+void NodeOperation::set_canvas_input_index(uint index)
{
this->canvas_input_index_ = index;
}
@@ -197,7 +197,7 @@ void NodeOperation::unset_canvas()
flags_.is_canvas_set = false;
}
-SocketReader *NodeOperation::get_input_socket_reader(unsigned int index)
+SocketReader *NodeOperation::get_input_socket_reader(uint index)
{
return this->get_input_socket(index)->get_reader();
}
diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h
index aa9e4329ab6..a00ac1352fe 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.h
+++ b/source/blender/compositor/intern/COM_NodeOperation.h
@@ -628,9 +628,9 @@ class NodeOperation {
/**
* Executes operation updating output memory buffer. Single-threaded calls.
*/
- virtual void update_memory_buffer(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
- Span<MemoryBuffer *> UNUSED(inputs))
+ virtual void update_memory_buffer(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
+ Span<MemoryBuffer *> /*inputs*/)
{
}
diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc
index 1fdec43eb3b..8212be5ec26 100644
--- a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc
+++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc
@@ -576,7 +576,7 @@ void NodeOperationBuilder::add_output_buffers(NodeOperation *operation,
/* try to find existing write buffer operation */
if (target->get_operation().get_flags().is_write_buffer_operation) {
BLI_assert(write_operation == nullptr); /* there should only be one write op connected */
- write_operation = (WriteBufferOperation *)(&target->get_operation());
+ write_operation = (WriteBufferOperation *)&target->get_operation();
}
else {
/* remove all links to other nodes */
diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.cc b/source/blender/compositor/intern/COM_OpenCLDevice.cc
index d951ebef172..188389b88c9 100644
--- a/source/blender/compositor/intern/COM_OpenCLDevice.cc
+++ b/source/blender/compositor/intern/COM_OpenCLDevice.cc
@@ -56,7 +56,7 @@ OpenCLDevice::~OpenCLDevice()
void OpenCLDevice::execute(WorkPackage *work_package)
{
- const unsigned int chunk_number = work_package->chunk_number;
+ const uint chunk_number = work_package->chunk_number;
ExecutionGroup *execution_group = work_package->execution_group;
MemoryBuffer **input_buffers = execution_group->get_input_buffers_opencl(chunk_number);
@@ -187,8 +187,8 @@ void OpenCLDevice::COM_cl_enqueue_range(cl_kernel kernel, MemoryBuffer *output_m
{
cl_int error;
const size_t size[] = {
- (size_t)output_memory_buffer->get_width(),
- (size_t)output_memory_buffer->get_height(),
+ size_t(output_memory_buffer->get_width()),
+ size_t(output_memory_buffer->get_height()),
};
error = clEnqueueNDRangeKernel(queue_, kernel, 2, nullptr, size, nullptr, 0, nullptr, nullptr);
diff --git a/source/blender/compositor/intern/COM_TiledExecutionModel.cc b/source/blender/compositor/intern/COM_TiledExecutionModel.cc
index cf8d3e9a084..54e8e8f315a 100644
--- a/source/blender/compositor/intern/COM_TiledExecutionModel.cc
+++ b/source/blender/compositor/intern/COM_TiledExecutionModel.cc
@@ -23,7 +23,7 @@ TiledExecutionModel::TiledExecutionModel(CompositorContext &context,
const bNodeTree *node_tree = context.get_bnodetree();
node_tree->stats_draw(node_tree->sdh, TIP_("Compositing | Determining resolution"));
- unsigned int resolution[2];
+ uint resolution[2];
for (ExecutionGroup *group : groups_) {
resolution[0] = 0;
resolution[1] = 0;
@@ -45,7 +45,7 @@ TiledExecutionModel::TiledExecutionModel(CompositorContext &context,
static void update_read_buffer_offset(Span<NodeOperation *> operations)
{
- unsigned int order = 0;
+ uint order = 0;
for (NodeOperation *operation : operations) {
if (operation->get_flags().is_read_buffer_operation) {
ReadBufferOperation *read_operation = (ReadBufferOperation *)operation;
diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cc b/source/blender/compositor/intern/COM_WorkScheduler.cc
index 1f93a3d9bfa..9067807d98c 100644
--- a/source/blender/compositor/intern/COM_WorkScheduler.cc
+++ b/source/blender/compositor/intern/COM_WorkScheduler.cc
@@ -185,7 +185,7 @@ static void opencl_initialize(const bool use_opencl)
cl_platform_id *platforms = (cl_platform_id *)MEM_mallocN(
sizeof(cl_platform_id) * number_of_platforms, __func__);
error = clGetPlatformIDs(number_of_platforms, platforms, nullptr);
- unsigned int index_platform;
+ uint index_platform;
for (index_platform = 0; index_platform < number_of_platforms; index_platform++) {
cl_platform_id platform = platforms[index_platform];
cl_uint number_of_devices = 0;
@@ -240,7 +240,7 @@ static void opencl_initialize(const bool use_opencl)
MEM_freeN(build_log);
}
else {
- unsigned int index_devices;
+ uint index_devices;
for (index_devices = 0; index_devices < number_of_devices; index_devices++) {
cl_device_id device = cldevices[index_devices];
cl_int vendorID = 0;
@@ -377,7 +377,7 @@ static void threading_model_queue_deinitialize()
/** \name Task Scheduling
* \{ */
-static void threading_model_task_execute(TaskPool *__restrict UNUSED(pool), void *task_data)
+static void threading_model_task_execute(TaskPool *__restrict /*pool*/, void *task_data)
{
WorkPackage *package = static_cast<WorkPackage *>(task_data);
CPUDevice device(BLI_task_parallel_thread_id(nullptr));
diff --git a/source/blender/compositor/intern/COM_compositor.cc b/source/blender/compositor/intern/COM_compositor.cc
index 519ad93bcaf..1ffc749ce64 100644
--- a/source/blender/compositor/intern/COM_compositor.cc
+++ b/source/blender/compositor/intern/COM_compositor.cc
@@ -25,15 +25,15 @@ static void compositor_init_node_previews(const RenderData *render_data, bNodeTr
/* We fit the aspect into COM_PREVIEW_SIZE x COM_PREVIEW_SIZE image to avoid
* insane preview resolution, which might even overflow preview dimensions. */
const float aspect = render_data->xsch > 0 ?
- (float)render_data->ysch / (float)render_data->xsch :
+ float(render_data->ysch) / float(render_data->xsch) :
1.0f;
int preview_width, preview_height;
if (aspect < 1.0f) {
preview_width = blender::compositor::COM_PREVIEW_SIZE;
- preview_height = (int)(blender::compositor::COM_PREVIEW_SIZE * aspect);
+ preview_height = int(blender::compositor::COM_PREVIEW_SIZE * aspect);
}
else {
- preview_width = (int)(blender::compositor::COM_PREVIEW_SIZE / aspect);
+ preview_width = int(blender::compositor::COM_PREVIEW_SIZE / aspect);
preview_height = blender::compositor::COM_PREVIEW_SIZE;
}
BKE_node_preview_init_tree(node_tree, preview_width, preview_height);
diff --git a/source/blender/compositor/nodes/COM_CombineColorNode.cc b/source/blender/compositor/nodes/COM_CombineColorNode.cc
index 36ff24cb9c3..7802a585c05 100644
--- a/source/blender/compositor/nodes/COM_CombineColorNode.cc
+++ b/source/blender/compositor/nodes/COM_CombineColorNode.cc
@@ -12,7 +12,7 @@ CombineColorNode::CombineColorNode(bNode *editor_node) : Node(editor_node)
}
void CombineColorNode::convert_to_operations(NodeConverter &converter,
- const CompositorContext &UNUSED(context)) const
+ const CompositorContext & /*context*/) const
{
NodeInput *input_rsocket = this->get_input_socket(0);
NodeInput *input_gsocket = this->get_input_socket(1);
diff --git a/source/blender/compositor/nodes/COM_CombineXYZNode.cc b/source/blender/compositor/nodes/COM_CombineXYZNode.cc
index 0b46f7ba0d4..dd09dabef02 100644
--- a/source/blender/compositor/nodes/COM_CombineXYZNode.cc
+++ b/source/blender/compositor/nodes/COM_CombineXYZNode.cc
@@ -12,7 +12,7 @@ CombineXYZNode::CombineXYZNode(bNode *editor_node) : Node(editor_node)
}
void CombineXYZNode::convert_to_operations(NodeConverter &converter,
- const CompositorContext &UNUSED(context)) const
+ const CompositorContext & /*context*/) const
{
NodeInput *input_x_socket = this->get_input_socket(0);
NodeInput *input_y_socket = this->get_input_socket(1);
diff --git a/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc b/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc
index 7d557de66e4..d26b649e30b 100644
--- a/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc
+++ b/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc
@@ -25,7 +25,7 @@ ConvertColorSpaceNode::ConvertColorSpaceNode(bNode *editorNode) : Node(editorNod
}
void ConvertColorSpaceNode::convert_to_operations(NodeConverter &converter,
- const CompositorContext &UNUSED(context)) const
+ const CompositorContext & /*context*/) const
{
const bNode *b_node = get_bnode();
diff --git a/source/blender/compositor/nodes/COM_CropNode.cc b/source/blender/compositor/nodes/COM_CropNode.cc
index 849fb80a8a8..80f345e8762 100644
--- a/source/blender/compositor/nodes/COM_CropNode.cc
+++ b/source/blender/compositor/nodes/COM_CropNode.cc
@@ -16,8 +16,8 @@ void CropNode::convert_to_operations(NodeConverter &converter,
{
const bNode *node = get_bnode();
NodeTwoXYs *crop_settings = (NodeTwoXYs *)node->storage;
- bool relative = (bool)node->custom2;
- bool crop_image = (bool)node->custom1;
+ bool relative = bool(node->custom2);
+ bool crop_image = bool(node->custom1);
CropBaseOperation *operation;
if (crop_image) {
operation = new CropImageOperation();
diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.cc b/source/blender/compositor/nodes/COM_CryptomatteNode.cc
index 42d699af01b..ee31fce0ea8 100644
--- a/source/blender/compositor/nodes/COM_CryptomatteNode.cc
+++ b/source/blender/compositor/nodes/COM_CryptomatteNode.cc
@@ -10,6 +10,7 @@
#include "COM_MultilayerImageOperation.h"
#include "COM_RenderLayersProg.h"
#include "COM_SetAlphaMultiplyOperation.h"
+#include "COM_SetAlphaReplaceOperation.h"
#include "COM_SetColorOperation.h"
namespace blender::compositor {
@@ -48,7 +49,7 @@ void CryptomatteBaseNode::convert_to_operations(NodeConverter &converter,
converter.map_output_socket(output_image_socket, apply_mask_operation->get_output_socket(0));
NodeOutput *output_pick_socket = this->get_output_socket(2);
- SetAlphaMultiplyOperation *extract_pick_operation = new SetAlphaMultiplyOperation();
+ SetAlphaReplaceOperation *extract_pick_operation = new SetAlphaReplaceOperation();
converter.add_operation(extract_pick_operation);
converter.add_input_value(extract_pick_operation->get_input_socket(1), 1.0f);
converter.add_link(cryptomatte_operation->get_output_socket(0),
@@ -240,8 +241,8 @@ CryptomatteOperation *CryptomatteNode::create_cryptomatte_operation(
CryptomatteOperation *CryptomatteLegacyNode::create_cryptomatte_operation(
NodeConverter &converter,
- const CompositorContext &UNUSED(context),
- const bNode &UNUSED(node),
+ const CompositorContext & /*context*/,
+ const bNode & /*node*/,
const NodeCryptomatte *cryptomatte_settings) const
{
const int num_inputs = inputs_.size() - 1;
diff --git a/source/blender/compositor/nodes/COM_MapUVNode.cc b/source/blender/compositor/nodes/COM_MapUVNode.cc
index ed9bff657f3..0ff86cabd4d 100644
--- a/source/blender/compositor/nodes/COM_MapUVNode.cc
+++ b/source/blender/compositor/nodes/COM_MapUVNode.cc
@@ -17,7 +17,7 @@ void MapUVNode::convert_to_operations(NodeConverter &converter,
const bNode *node = this->get_bnode();
MapUVOperation *operation = new MapUVOperation();
- operation->set_alpha((float)node->custom1);
+ operation->set_alpha(float(node->custom1));
operation->set_canvas_input_index(1);
converter.add_operation(operation);
diff --git a/source/blender/compositor/nodes/COM_MaskNode.cc b/source/blender/compositor/nodes/COM_MaskNode.cc
index f92e307328d..3c6812d606f 100644
--- a/source/blender/compositor/nodes/COM_MaskNode.cc
+++ b/source/blender/compositor/nodes/COM_MaskNode.cc
@@ -41,7 +41,7 @@ void MaskNode::convert_to_operations(NodeConverter &converter,
operation->set_mask(mask);
operation->set_framenumber(context.get_framenumber());
- operation->set_feather((bool)(editor_node->custom1 & CMP_NODEFLAG_MASK_NO_FEATHER) == 0);
+ operation->set_feather(bool(editor_node->custom1 & CMP_NODEFLAG_MASK_NO_FEATHER) == 0);
if ((editor_node->custom1 & CMP_NODEFLAG_MASK_MOTION_BLUR) && (editor_node->custom2 > 1) &&
(editor_node->custom3 > FLT_EPSILON)) {
diff --git a/source/blender/compositor/nodes/COM_OutputFileNode.cc b/source/blender/compositor/nodes/COM_OutputFileNode.cc
index c83bcf42efd..50989f73986 100644
--- a/source/blender/compositor/nodes/COM_OutputFileNode.cc
+++ b/source/blender/compositor/nodes/COM_OutputFileNode.cc
@@ -65,7 +65,7 @@ void OutputFileNode::convert_to_operations(NodeConverter &converter,
if (storage->format.imtype == R_IMF_IMTYPE_MULTILAYER) {
const bool use_half_float = (storage->format.depth == R_IMF_CHAN_DEPTH_16);
- /* single output operation for the multilayer file */
+ /* Single output operation for the multi-layer file. */
OutputOpenExrMultiLayerOperation *output_operation;
if (is_multiview && storage->format.views_format == R_IMF_VIEWS_MULTIVIEW) {
@@ -104,7 +104,7 @@ void OutputFileNode::convert_to_operations(NodeConverter &converter,
char path[FILE_MAX];
/* combine file path for the input */
- BLI_join_dirfile(path, FILE_MAX, storage->base_path, sockdata->path);
+ BLI_path_join(path, FILE_MAX, storage->base_path, sockdata->path);
NodeOperation *output_operation = nullptr;
diff --git a/source/blender/compositor/nodes/COM_SceneTimeNode.cc b/source/blender/compositor/nodes/COM_SceneTimeNode.cc
index edd6efdb67b..dd5784f03ee 100644
--- a/source/blender/compositor/nodes/COM_SceneTimeNode.cc
+++ b/source/blender/compositor/nodes/COM_SceneTimeNode.cc
@@ -20,7 +20,7 @@ void SceneTimeNode::convert_to_operations(NodeConverter &converter,
const int frameNumber = context.get_framenumber();
const Scene *scene = context.get_scene();
- const double frameRate = (((double)scene->r.frs_sec) / (double)scene->r.frs_sec_base);
+ const double frameRate = (double(scene->r.frs_sec) / double(scene->r.frs_sec_base));
SecondOperation->set_value(float(frameNumber / frameRate));
converter.add_operation(SecondOperation);
diff --git a/source/blender/compositor/nodes/COM_SeparateColorNode.cc b/source/blender/compositor/nodes/COM_SeparateColorNode.cc
index 28ebbb35e9a..6732396004f 100644
--- a/source/blender/compositor/nodes/COM_SeparateColorNode.cc
+++ b/source/blender/compositor/nodes/COM_SeparateColorNode.cc
@@ -12,7 +12,7 @@ SeparateColorNode::SeparateColorNode(bNode *editor_node) : Node(editor_node)
}
void SeparateColorNode::convert_to_operations(NodeConverter &converter,
- const CompositorContext &UNUSED(context)) const
+ const CompositorContext & /*context*/) const
{
NodeInput *image_socket = this->get_input_socket(0);
NodeOutput *output_rsocket = this->get_output_socket(0);
diff --git a/source/blender/compositor/nodes/COM_SeparateXYZNode.cc b/source/blender/compositor/nodes/COM_SeparateXYZNode.cc
index 4e7704dcdc8..7aa8de04c34 100644
--- a/source/blender/compositor/nodes/COM_SeparateXYZNode.cc
+++ b/source/blender/compositor/nodes/COM_SeparateXYZNode.cc
@@ -13,7 +13,7 @@ SeparateXYZNode::SeparateXYZNode(bNode *editor_node) : Node(editor_node)
}
void SeparateXYZNode::convert_to_operations(NodeConverter &converter,
- const CompositorContext &UNUSED(context)) const
+ const CompositorContext & /*context*/) const
{
NodeInput *vector_socket = this->get_input_socket(0);
NodeOutput *output_x_socket = this->get_output_socket(0);
diff --git a/source/blender/compositor/nodes/COM_TimeNode.cc b/source/blender/compositor/nodes/COM_TimeNode.cc
index 4f4f6f7bf8a..4004a5f718f 100644
--- a/source/blender/compositor/nodes/COM_TimeNode.cc
+++ b/source/blender/compositor/nodes/COM_TimeNode.cc
@@ -31,7 +31,7 @@ void TimeNode::convert_to_operations(NodeConverter &converter,
fac = 1.0f;
}
else if (node->custom1 < node->custom2) {
- fac = (context.get_framenumber() - node->custom1) / (float)(node->custom2 - node->custom1);
+ fac = (context.get_framenumber() - node->custom1) / float(node->custom2 - node->custom1);
}
BKE_curvemapping_init((CurveMapping *)node->storage);
diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.cc b/source/blender/compositor/operations/COM_AntiAliasOperation.cc
index 0c297c20eef..e0083b702e1 100644
--- a/source/blender/compositor/operations/COM_AntiAliasOperation.cc
+++ b/source/blender/compositor/operations/COM_AntiAliasOperation.cc
@@ -34,7 +34,7 @@ static int extrapolate9(float *E0,
do { \
*DST = *SRC; \
} while (0)
- if ((!PEQ(B, H)) && (!PEQ(D, F))) {
+ if (!PEQ(B, H) && !PEQ(D, F)) {
if (PEQ(D, B)) {
PCPY(E0, D);
}
@@ -144,12 +144,12 @@ void AntiAliasOperation::execute_pixel(float output[4], int x, int y, void *data
/* Some rounding magic to so make weighting correct with the
* original coefficients.
*/
- unsigned char result = ((3 * ninepix[0] + 5 * ninepix[1] + 3 * ninepix[2] + 5 * ninepix[3] +
- 6 * ninepix[4] + 5 * ninepix[5] + 3 * ninepix[6] + 5 * ninepix[7] +
- 3 * ninepix[8]) *
- 255.0f +
- 19.0f) /
- 38.0f;
+ uchar result = ((3 * ninepix[0] + 5 * ninepix[1] + 3 * ninepix[2] + 5 * ninepix[3] +
+ 6 * ninepix[4] + 5 * ninepix[5] + 3 * ninepix[6] + 5 * ninepix[7] +
+ 3 * ninepix[8]) *
+ 255.0f +
+ 19.0f) /
+ 38.0f;
output[0] = result / 255.0f;
}
else {
@@ -234,12 +234,12 @@ void AntiAliasOperation::update_memory_buffer_partial(MemoryBuffer *output,
&row_next[x_offset + input->elem_stride])) {
/* Some rounding magic to make weighting correct with the
* original coefficients. */
- unsigned char result = ((3 * ninepix[0] + 5 * ninepix[1] + 3 * ninepix[2] +
- 5 * ninepix[3] + 6 * ninepix[4] + 5 * ninepix[5] +
- 3 * ninepix[6] + 5 * ninepix[7] + 3 * ninepix[8]) *
- 255.0f +
- 19.0f) /
- 38.0f;
+ uchar result = ((3 * ninepix[0] + 5 * ninepix[1] + 3 * ninepix[2] + 5 * ninepix[3] +
+ 6 * ninepix[4] + 5 * ninepix[5] + 3 * ninepix[6] + 5 * ninepix[7] +
+ 3 * ninepix[8]) *
+ 255.0f +
+ 19.0f) /
+ 38.0f;
out[0] = result / 255.0f;
}
else {
diff --git a/source/blender/compositor/operations/COM_BilateralBlurOperation.cc b/source/blender/compositor/operations/COM_BilateralBlurOperation.cc
index 3711851e8f5..c808ec02690 100644
--- a/source/blender/compositor/operations/COM_BilateralBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_BilateralBlurOperation.cc
@@ -95,7 +95,7 @@ bool BilateralBlurOperation::determine_depending_area_of_interest(
return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output);
}
-void BilateralBlurOperation::get_area_of_interest(const int UNUSED(input_idx),
+void BilateralBlurOperation::get_area_of_interest(const int /*input_idx*/,
const rcti &output_area,
rcti &r_input_area)
{
diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.cc b/source/blender/compositor/operations/COM_BlurBaseOperation.cc
index b278997eced..53a5cebaf5d 100644
--- a/source/blender/compositor/operations/COM_BlurBaseOperation.cc
+++ b/source/blender/compositor/operations/COM_BlurBaseOperation.cc
@@ -71,7 +71,7 @@ float *BlurBaseOperation::make_gausstab(float rad, int size)
sum = 0.0f;
float fac = (rad > 0.0f ? 1.0f / rad : 0.0f);
for (i = -size; i <= size; i++) {
- val = RE_filter_value(data_.filtertype, (float)i * fac);
+ val = RE_filter_value(data_.filtertype, float(i) * fac);
sum += val;
gausstab[i + size] = val;
}
@@ -107,7 +107,7 @@ float *BlurBaseOperation::make_dist_fac_inverse(float rad, int size, int falloff
float fac = (rad > 0.0f ? 1.0f / rad : 0.0f);
for (i = -size; i <= size; i++) {
- val = 1.0f - fabsf((float)i * fac);
+ val = 1.0f - fabsf(float(i) * fac);
/* keep in sync with rna_enum_proportional_falloff_curve_only_items */
switch (falloff) {
diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.cc b/source/blender/compositor/operations/COM_BokehImageOperation.cc
index 42caa7aa3c0..b74ac9dac64 100644
--- a/source/blender/compositor/operations/COM_BokehImageOperation.cc
+++ b/source/blender/compositor/operations/COM_BokehImageOperation.cc
@@ -16,13 +16,13 @@ void BokehImageOperation::init_execution()
center_[1] = get_height() / 2;
inverse_rounding_ = 1.0f - data_->rounding;
circular_distance_ = get_width() / 2;
- flap_rad_ = (float)(M_PI * 2) / data_->flaps;
+ flap_rad_ = float(M_PI * 2) / data_->flaps;
flap_rad_add_ = data_->angle;
while (flap_rad_add_ < 0.0f) {
- flap_rad_add_ += (float)(M_PI * 2.0);
+ flap_rad_add_ += float(M_PI * 2.0);
}
- while (flap_rad_add_ > (float)M_PI) {
- flap_rad_add_ -= (float)(M_PI * 2.0);
+ while (flap_rad_add_ > float(M_PI)) {
+ flap_rad_add_ -= float(M_PI * 2.0);
}
}
void BokehImageOperation::detemine_start_point_of_flap(float r[2], int flap_number, float distance)
@@ -43,8 +43,8 @@ float BokehImageOperation::is_inside_bokeh(float distance, float x, float y)
point[1] = y;
const float distance_to_center = len_v2v2(point, center_);
- const float bearing = (atan2f(deltaX, deltaY) + (float)(M_PI * 2.0));
- int flap_number = (int)((bearing - flap_rad_add_) / flap_rad_);
+ const float bearing = (atan2f(deltaX, deltaY) + float(M_PI * 2.0));
+ int flap_number = int((bearing - flap_rad_add_) / flap_rad_);
detemine_start_point_of_flap(line_p1, flap_number, distance);
detemine_start_point_of_flap(line_p2, flap_number + 1, distance);
@@ -96,7 +96,7 @@ void BokehImageOperation::execute_pixel_sampled(float output[4],
void BokehImageOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
const float shift = data_->lensshift;
const float shift2 = shift / 2.0f;
diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.cc b/source/blender/compositor/operations/COM_BoxMaskOperation.cc
index 5b3e00afe31..85ac9434647 100644
--- a/source/blender/compositor/operations/COM_BoxMaskOperation.cc
+++ b/source/blender/compositor/operations/COM_BoxMaskOperation.cc
@@ -19,10 +19,10 @@ void BoxMaskOperation::init_execution()
{
input_mask_ = this->get_input_socket_reader(0);
input_value_ = this->get_input_socket_reader(1);
- const double rad = (double)data_->rotation;
+ const double rad = double(data_->rotation);
cosine_ = cos(rad);
sine_ = sin(rad);
- aspect_ratio_ = ((float)this->get_width()) / this->get_height();
+ aspect_ratio_ = float(this->get_width()) / this->get_height();
}
void BoxMaskOperation::execute_pixel_sampled(float output[4],
diff --git a/source/blender/compositor/operations/COM_BrightnessOperation.cc b/source/blender/compositor/operations/COM_BrightnessOperation.cc
index 764d5d64046..07d8035e615 100644
--- a/source/blender/compositor/operations/COM_BrightnessOperation.cc
+++ b/source/blender/compositor/operations/COM_BrightnessOperation.cc
@@ -47,7 +47,7 @@ void BrightnessOperation::execute_pixel_sampled(float output[4],
/*
* The algorithm is by Werner D. Streidt
* (http://visca.com/ffactory/archives/5-99/msg00021.html)
- * Extracted of OpenCV demhist.c
+ * Extracted of OpenCV `demhist.c`.
*/
if (contrast > 0) {
a = 1.0f - delta * 2.0f;
@@ -84,7 +84,7 @@ void BrightnessOperation::update_memory_buffer_partial(MemoryBuffer *output,
/*
* The algorithm is by Werner D. Streidt
* (http://visca.com/ffactory/archives/5-99/msg00021.html)
- * Extracted of OpenCV demhist.c
+ * Extracted of OpenCV `demhist.c`.
*/
float a, b;
if (contrast > 0) {
diff --git a/source/blender/compositor/operations/COM_CalculateMeanOperation.cc b/source/blender/compositor/operations/COM_CalculateMeanOperation.cc
index 4e5832a7d34..9dbeabafa5a 100644
--- a/source/blender/compositor/operations/COM_CalculateMeanOperation.cc
+++ b/source/blender/compositor/operations/COM_CalculateMeanOperation.cc
@@ -144,15 +144,15 @@ void CalculateMeanOperation::set_setting(int setting)
}
void CalculateMeanOperation::get_area_of_interest(int input_idx,
- const rcti &UNUSED(output_area),
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
BLI_assert(input_idx == 0);
r_input_area = get_input_operation(input_idx)->get_canvas();
}
-void CalculateMeanOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
+void CalculateMeanOperation::update_memory_buffer_started(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
if (!iscalculated_) {
@@ -164,7 +164,7 @@ void CalculateMeanOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(o
void CalculateMeanOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
output->fill(area, &result_);
}
diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cc b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cc
index 881b894d66d..709218297b7 100644
--- a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cc
+++ b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cc
@@ -74,15 +74,16 @@ void *CalculateStandardDeviationOperation::initialize_tile_data(rcti *rect)
}
}
}
- standard_deviation_ = sqrt(sum / (float)(pixels - 1));
+ standard_deviation_ = sqrt(sum / float(pixels - 1));
iscalculated_ = true;
}
unlock_mutex();
return nullptr;
}
-void CalculateStandardDeviationOperation::update_memory_buffer_started(
- MemoryBuffer *UNUSED(output), const rcti &UNUSED(area), Span<MemoryBuffer *> inputs)
+void CalculateStandardDeviationOperation::update_memory_buffer_started(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
+ Span<MemoryBuffer *> inputs)
{
if (!iscalculated_) {
const MemoryBuffer *input = inputs[0];
@@ -98,13 +99,13 @@ void CalculateStandardDeviationOperation::update_memory_buffer_started(
join.num_pixels += chunk.num_pixels;
});
standard_deviation_ = total.num_pixels <= 1 ? 0.0f :
- sqrt(total.sum / (float)(total.num_pixels - 1));
+ sqrt(total.sum / float(total.num_pixels - 1));
iscalculated_ = true;
}
}
void CalculateStandardDeviationOperation::update_memory_buffer_partial(
- MemoryBuffer *output, const rcti &area, Span<MemoryBuffer *> UNUSED(inputs))
+ MemoryBuffer *output, const rcti &area, Span<MemoryBuffer *> /*inputs*/)
{
output->fill(area, &standard_deviation_);
}
diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cc b/source/blender/compositor/operations/COM_CompositorOperation.cc
index c0cc3fa1ba4..1ff27607d09 100644
--- a/source/blender/compositor/operations/COM_CompositorOperation.cc
+++ b/source/blender/compositor/operations/COM_CompositorOperation.cc
@@ -113,7 +113,7 @@ void CompositorOperation::deinit_execution()
depth_input_ = nullptr;
}
-void CompositorOperation::execute_region(rcti *rect, unsigned int /*tile_number*/)
+void CompositorOperation::execute_region(rcti *rect, uint /*tile_number*/)
{
float color[8]; /* 7 is enough. */
float *buffer = output_buffer_;
@@ -197,7 +197,7 @@ void CompositorOperation::execute_region(rcti *rect, unsigned int /*tile_number*
}
}
-void CompositorOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output),
+void CompositorOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
@@ -213,7 +213,7 @@ void CompositorOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(outp
depth_buf.copy_from(inputs[2], area);
}
-void CompositorOperation::determine_canvas(const rcti &UNUSED(preferred_area), rcti &r_area)
+void CompositorOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area)
{
int width, height;
BKE_render_resolution(rd_, false, &width, &height);
diff --git a/source/blender/compositor/operations/COM_ConstantOperation.cc b/source/blender/compositor/operations/COM_ConstantOperation.cc
index 0977da5e37c..21c10f2b52a 100644
--- a/source/blender/compositor/operations/COM_ConstantOperation.cc
+++ b/source/blender/compositor/operations/COM_ConstantOperation.cc
@@ -19,7 +19,7 @@ bool ConstantOperation::can_get_constant_elem() const
void ConstantOperation::update_memory_buffer(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
BLI_assert(output->is_a_single_elem());
const float *constant = get_constant_elem();
diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc
index 89c1c7cb153..25d4b2d6a6c 100644
--- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc
+++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc
@@ -46,8 +46,8 @@ void ConvertDepthToRadiusOperation::init_execution()
}
inverse_focal_distance_ = 1.0f / focal_distance;
aspect_ = (this->get_width() > this->get_height()) ?
- (this->get_height() / (float)this->get_width()) :
- (this->get_width() / (float)this->get_height());
+ (this->get_height() / float(this->get_width())) :
+ (this->get_width() / float(this->get_height()));
aperture_ = 0.5f * (cam_lens_ / (aspect_ * cam_sensor)) / f_stop_;
const float minsz = MIN2(get_width(), get_height());
dof_sp_ = minsz / ((cam_sensor / 2.0f) /
diff --git a/source/blender/compositor/operations/COM_ConvertOperation.h b/source/blender/compositor/operations/COM_ConvertOperation.h
index 16d1e2e6bb5..ffd02ed5a2f 100644
--- a/source/blender/compositor/operations/COM_ConvertOperation.h
+++ b/source/blender/compositor/operations/COM_ConvertOperation.h
@@ -98,7 +98,7 @@ class ConvertVectorToValueOperation : public ConvertBaseOperation {
class ConvertRGBToYCCOperation : public ConvertBaseOperation {
private:
- /** YCbCr mode (Jpeg, ITU601, ITU709) */
+ /** YCbCr mode (JPEG, ITU601, ITU709) */
int mode_;
public:
@@ -116,7 +116,7 @@ class ConvertRGBToYCCOperation : public ConvertBaseOperation {
class ConvertYCCToRGBOperation : public ConvertBaseOperation {
private:
- /** YCbCr mode (Jpeg, ITU601, ITU709) */
+ /** YCbCr mode (JPEG, ITU601, ITU709) */
int mode_;
public:
diff --git a/source/blender/compositor/operations/COM_CryptomatteOperation.cc b/source/blender/compositor/operations/COM_CryptomatteOperation.cc
index 69218576237..71e892cb7f1 100644
--- a/source/blender/compositor/operations/COM_CryptomatteOperation.cc
+++ b/source/blender/compositor/operations/COM_CryptomatteOperation.cc
@@ -42,8 +42,8 @@ void CryptomatteOperation::execute_pixel(float output[4], int x, int y, void *da
::memcpy(&m3hash, &input[0], sizeof(uint32_t));
/* Since the red channel is likely to be out of display range,
* setting green and blue gives more meaningful images. */
- output[1] = ((float)(m3hash << 8) / (float)UINT32_MAX);
- output[2] = ((float)(m3hash << 16) / (float)UINT32_MAX);
+ output[1] = (float(m3hash << 8) / float(UINT32_MAX));
+ output[2] = (float(m3hash << 16) / float(UINT32_MAX));
}
for (float hash : object_index_) {
if (input[0] == hash) {
@@ -71,8 +71,8 @@ void CryptomatteOperation::update_memory_buffer_partial(MemoryBuffer *output,
::memcpy(&m3hash, &input[0], sizeof(uint32_t));
/* Since the red channel is likely to be out of display range,
* setting green and blue gives more meaningful images. */
- it.out[1] = ((float)(m3hash << 8) / (float)UINT32_MAX);
- it.out[2] = ((float)(m3hash << 16) / (float)UINT32_MAX);
+ it.out[1] = (float(m3hash << 8) / float(UINT32_MAX));
+ it.out[2] = (float(m3hash << 16) / float(UINT32_MAX));
}
for (const float hash : object_index_) {
if (input[0] == hash) {
diff --git a/source/blender/compositor/operations/COM_DenoiseOperation.cc b/source/blender/compositor/operations/COM_DenoiseOperation.cc
index 3f32eced0f8..5019c2bb158 100644
--- a/source/blender/compositor/operations/COM_DenoiseOperation.cc
+++ b/source/blender/compositor/operations/COM_DenoiseOperation.cc
@@ -89,7 +89,7 @@ class DenoiseFilter {
}
#else
- void init_and_lock_denoiser(MemoryBuffer *UNUSED(output))
+ void init_and_lock_denoiser(MemoryBuffer * /*output*/)
{
}
@@ -97,11 +97,11 @@ class DenoiseFilter {
{
}
- void set_image(const StringRef UNUSED(name), MemoryBuffer *UNUSED(buffer))
+ void set_image(const StringRef /*name*/, MemoryBuffer * /*buffer*/)
{
}
- template<typename T> void set(const StringRef UNUSED(option_name), T UNUSED(value))
+ template<typename T> void set(const StringRef /*option_name*/, T /*value*/)
{
}
@@ -132,8 +132,8 @@ bool DenoiseBaseOperation::determine_depending_area_of_interest(
return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output);
}
-void DenoiseBaseOperation::get_area_of_interest(const int UNUSED(input_idx),
- const rcti &UNUSED(output_area),
+void DenoiseBaseOperation::get_area_of_interest(const int /*input_idx*/,
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
r_input_area = this->get_canvas();
@@ -178,7 +178,7 @@ static bool are_guiding_passes_noise_free(const NodeDenoise *settings)
void DenoiseOperation::hash_output_params()
{
if (settings_) {
- hash_params((int)settings_->hdr, are_guiding_passes_noise_free(settings_));
+ hash_params(int(settings_->hdr), are_guiding_passes_noise_free(settings_));
}
}
@@ -251,7 +251,7 @@ void DenoiseOperation::generate_denoise(MemoryBuffer *output,
}
void DenoiseOperation::update_memory_buffer(MemoryBuffer *output,
- const rcti &UNUSED(area),
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
if (!output_rendered_) {
@@ -304,7 +304,7 @@ void DenoisePrefilterOperation::generate_denoise(MemoryBuffer *output, MemoryBuf
}
void DenoisePrefilterOperation::update_memory_buffer(MemoryBuffer *output,
- const rcti &UNUSED(area),
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
if (!output_rendered_) {
diff --git a/source/blender/compositor/operations/COM_DespeckleOperation.cc b/source/blender/compositor/operations/COM_DespeckleOperation.cc
index cfc437a6324..a0c82ad531c 100644
--- a/source/blender/compositor/operations/COM_DespeckleOperation.cc
+++ b/source/blender/compositor/operations/COM_DespeckleOperation.cc
@@ -99,7 +99,7 @@ void DespeckleOperation::execute_pixel(float output[4], int x, int y, void * /*d
input_operation_->read(in1, x3, y3, nullptr);
COLOR_ADD(TOT_DIV_CNR)
- mul_v4_fl(color_mid, 1.0f / (4.0f + (4.0f * (float)M_SQRT1_2)));
+ mul_v4_fl(color_mid, 1.0f / (4.0f + (4.0f * float(M_SQRT1_2))));
// mul_v4_fl(color_mid, 1.0f / w);
if ((w != 0.0f) && ((w / WTOT) > (threshold_neighbor_)) &&
@@ -214,7 +214,7 @@ void DespeckleOperation::update_memory_buffer_partial(MemoryBuffer *output,
in1 = image->get_elem(x3, y3);
COLOR_ADD(TOT_DIV_CNR)
- mul_v4_fl(color_mid, 1.0f / (4.0f + (4.0f * (float)M_SQRT1_2)));
+ mul_v4_fl(color_mid, 1.0f / (4.0f + (4.0f * float(M_SQRT1_2))));
// mul_v4_fl(color_mid, 1.0f / w);
if ((w != 0.0f) && ((w / WTOT) > (threshold_neighbor_)) &&
diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cc b/source/blender/compositor/operations/COM_DilateErodeOperation.cc
index a93571ebee4..9a2d5e09b33 100644
--- a/source/blender/compositor/operations/COM_DilateErodeOperation.cc
+++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cc
@@ -181,8 +181,8 @@ static float get_min_distance(DilateErodeThresholdOperation::PixelData &p)
* true. */
const TCompare compare;
float min_dist = p.distance;
- const float *row = p.elem + ((intptr_t)p.ymin - p.y) * p.row_stride +
- ((intptr_t)p.xmin - p.x) * p.elem_stride;
+ const float *row = p.elem + (intptr_t(p.ymin) - p.y) * p.row_stride +
+ (intptr_t(p.xmin) - p.x) * p.elem_stride;
for (int yi = p.ymin; yi < p.ymax; yi++) {
const float dy = yi - p.y;
const float dist_y = dy * dy;
@@ -410,8 +410,8 @@ static float get_distance_value(DilateDistanceOperation::PixelData &p, const flo
const TCompare compare;
const float min_dist = p.min_distance;
float value = start_value;
- const float *row = p.elem + ((intptr_t)p.ymin - p.y) * p.row_stride +
- ((intptr_t)p.xmin - p.x) * p.elem_stride;
+ const float *row = p.elem + (intptr_t(p.ymin) - p.y) * p.row_stride +
+ (intptr_t(p.xmin) - p.x) * p.elem_stride;
for (int yi = p.ymin; yi < p.ymax; yi++) {
const float dy = yi - p.y;
const float dist_y = dy * dy;
diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cc b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cc
index 37e05de33db..5e292fa12c2 100644
--- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cc
@@ -30,7 +30,7 @@ void DirectionalBlurOperation::init_execution()
const float height = get_height();
const float a = angle;
- const float itsc = 1.0f / powf(2.0f, (float)iterations);
+ const float itsc = 1.0f / powf(2.0f, float(iterations));
float D;
D = distance * sqrtf(width * width + height * height);
@@ -128,7 +128,7 @@ bool DirectionalBlurOperation::determine_depending_area_of_interest(
}
void DirectionalBlurOperation::get_area_of_interest(const int input_idx,
- const rcti &UNUSED(output_area),
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
BLI_assert(input_idx == 0);
diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.cc b/source/blender/compositor/operations/COM_DisplaceOperation.cc
index 198cca0482e..1aec8e12242 100644
--- a/source/blender/compositor/operations/COM_DisplaceOperation.cc
+++ b/source/blender/compositor/operations/COM_DisplaceOperation.cc
@@ -113,7 +113,7 @@ void DisplaceOperation::pixel_transform(const float xy[2], float r_uv[2], float
num++;
}
if (num > 0) {
- float numinv = 1.0f / (float)num;
+ float numinv = 1.0f / float(num);
r_deriv[0][0] *= numinv;
r_deriv[1][0] *= numinv;
}
@@ -130,7 +130,7 @@ void DisplaceOperation::pixel_transform(const float xy[2], float r_uv[2], float
num++;
}
if (num > 0) {
- float numinv = 1.0f / (float)num;
+ float numinv = 1.0f / float(num);
r_deriv[0][1] *= numinv;
r_deriv[1][1] *= numinv;
}
@@ -209,8 +209,8 @@ void DisplaceOperation::get_area_of_interest(const int input_idx,
}
}
-void DisplaceOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
+void DisplaceOperation::update_memory_buffer_started(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
MemoryBuffer *vector = inputs[1];
@@ -227,7 +227,7 @@ void DisplaceOperation::update_memory_buffer_partial(MemoryBuffer *output,
{
const MemoryBuffer *input_color = inputs[0];
for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
- const float xy[2] = {(float)it.x, (float)it.y};
+ const float xy[2] = {float(it.x), float(it.y)};
float uv[2];
float deriv[2][2];
diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cc b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cc
index ea156cd19db..e120dd5f41a 100644
--- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cc
+++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cc
@@ -8,18 +8,13 @@
namespace blender::compositor {
/* This part has been copied from the double edge mask. */
-static void do_adjacentKeepBorders(unsigned int t,
- unsigned int rw,
- const unsigned int *limask,
- const unsigned int *lomask,
- unsigned int *lres,
- float *res,
- unsigned int *rsize)
+static void do_adjacentKeepBorders(
+ uint t, uint rw, const uint *limask, const uint *lomask, uint *lres, float *res, uint *rsize)
{
int x;
- unsigned int isz = 0; /* Inner edge size. */
- unsigned int osz = 0; /* Outer edge size. */
- unsigned int gsz = 0; /* Gradient fill area size. */
+ uint isz = 0; /* Inner edge size. */
+ uint osz = 0; /* Outer edge size. */
+ uint gsz = 0; /* Gradient fill area size. */
/* Test the four corners */
/* Upper left corner. */
x = t - rw + 1;
@@ -178,18 +173,13 @@ static void do_adjacentKeepBorders(unsigned int t,
rsize[2] = gsz;
}
-static void do_adjacentBleedBorders(unsigned int t,
- unsigned int rw,
- const unsigned int *limask,
- const unsigned int *lomask,
- unsigned int *lres,
- float *res,
- unsigned int *rsize)
+static void do_adjacentBleedBorders(
+ uint t, uint rw, const uint *limask, const uint *lomask, uint *lres, float *res, uint *rsize)
{
int x;
- unsigned int isz = 0; /* Inner edge size. */
- unsigned int osz = 0; /* Outer edge size. */
- unsigned int gsz = 0; /* Gradient fill area size. */
+ uint isz = 0; /* Inner edge size. */
+ uint osz = 0; /* Outer edge size. */
+ uint gsz = 0; /* Gradient fill area size. */
/* Test the four corners */
/* Upper left corner. */
x = t - rw + 1;
@@ -403,18 +393,13 @@ static void do_adjacentBleedBorders(unsigned int t,
rsize[2] = gsz;
}
-static void do_allKeepBorders(unsigned int t,
- unsigned int rw,
- const unsigned int *limask,
- const unsigned int *lomask,
- unsigned int *lres,
- float *res,
- unsigned int *rsize)
+static void do_allKeepBorders(
+ uint t, uint rw, const uint *limask, const uint *lomask, uint *lres, float *res, uint *rsize)
{
int x;
- unsigned int isz = 0; /* Inner edge size. */
- unsigned int osz = 0; /* Outer edge size. */
- unsigned int gsz = 0; /* Gradient fill area size. */
+ uint isz = 0; /* Inner edge size. */
+ uint osz = 0; /* Outer edge size. */
+ uint gsz = 0; /* Gradient fill area size. */
/* Test the four corners. */
/* Upper left corner. */
x = t - rw + 1;
@@ -565,18 +550,13 @@ static void do_allKeepBorders(unsigned int t,
rsize[2] = gsz;
}
-static void do_allBleedBorders(unsigned int t,
- unsigned int rw,
- const unsigned int *limask,
- const unsigned int *lomask,
- unsigned int *lres,
- float *res,
- unsigned int *rsize)
+static void do_allBleedBorders(
+ uint t, uint rw, const uint *limask, const uint *lomask, uint *lres, float *res, uint *rsize)
{
int x;
- unsigned int isz = 0; /* Inner edge size. */
- unsigned int osz = 0; /* Outer edge size. */
- unsigned int gsz = 0; /* Gradient fill area size. */
+ uint isz = 0; /* Inner edge size. */
+ uint osz = 0; /* Outer edge size. */
+ uint gsz = 0; /* Gradient fill area size. */
/* Test the four corners */
/* Upper left corner. */
x = t - rw + 1;
@@ -782,16 +762,16 @@ static void do_allBleedBorders(unsigned int t,
rsize[2] = gsz;
}
-static void do_allEdgeDetection(unsigned int t,
- unsigned int rw,
- const unsigned int *limask,
- const unsigned int *lomask,
- unsigned int *lres,
+static void do_allEdgeDetection(uint t,
+ uint rw,
+ const uint *limask,
+ const uint *lomask,
+ uint *lres,
float *res,
- unsigned int *rsize,
- unsigned int in_isz,
- unsigned int in_osz,
- unsigned int in_gsz)
+ uint *rsize,
+ uint in_isz,
+ uint in_osz,
+ uint in_gsz)
{
int x; /* Pixel loop counter. */
int a; /* Pixel loop counter. */
@@ -812,7 +792,7 @@ static void do_allEdgeDetection(unsigned int t,
if (!limask[a]) { /* If the inner mask is empty. */
if (lomask[a]) { /* If the outer mask is full. */
/*
- * Next we test all 4 directions around the current pixel: next/prev/up/down
+ * Next we test all 4 directions around the current pixel: next/previous/up/down
* The test ensures that the outer mask is empty and that the inner mask
* is also empty. If both conditions are true for any one of the 4 adjacent pixels
* then the current pixel is counted as being a true outer edge pixel.
@@ -853,16 +833,16 @@ static void do_allEdgeDetection(unsigned int t,
rsize[2] = in_gsz;
}
-static void do_adjacentEdgeDetection(unsigned int t,
- unsigned int rw,
- const unsigned int *limask,
- const unsigned int *lomask,
- unsigned int *lres,
+static void do_adjacentEdgeDetection(uint t,
+ uint rw,
+ const uint *limask,
+ const uint *lomask,
+ uint *lres,
float *res,
- unsigned int *rsize,
- unsigned int in_isz,
- unsigned int in_osz,
- unsigned int in_gsz)
+ uint *rsize,
+ uint in_isz,
+ uint in_osz,
+ uint in_gsz)
{
int x; /* Pixel loop counter. */
int a; /* Pixel loop counter. */
@@ -882,7 +862,7 @@ static void do_adjacentEdgeDetection(unsigned int t,
if (!limask[a]) { /* If the inner mask is empty. */
if (lomask[a]) { /* If the outer mask is full. */
/*
- * Next we test all 4 directions around the current pixel: next/prev/up/down
+ * Next we test all 4 directions around the current pixel: next/previous/up/down
* The test ensures that the outer mask is empty and that the inner mask
* is also empty. If both conditions are true for any one of the 4 adjacent pixels
* then the current pixel is counted as being a true outer edge pixel.
@@ -925,30 +905,30 @@ static void do_adjacentEdgeDetection(unsigned int t,
rsize[2] = in_gsz;
}
-static void do_createEdgeLocationBuffer(unsigned int t,
- unsigned int rw,
- const unsigned int *lres,
+static void do_createEdgeLocationBuffer(uint t,
+ uint rw,
+ const uint *lres,
float *res,
- unsigned short *gbuf,
- unsigned int *inner_edge_offset,
- unsigned int *outer_edge_offset,
- unsigned int isz,
- unsigned int gsz)
+ ushort *gbuf,
+ uint *inner_edge_offset,
+ uint *outer_edge_offset,
+ uint isz,
+ uint gsz)
{
- int x; /* Pixel loop counter. */
- int a; /* Temporary pixel index buffer loop counter. */
- unsigned int ud; /* Unscaled edge distance. */
- unsigned int dmin; /* Minimum edge distance. */
+ int x; /* Pixel loop counter. */
+ int a; /* Temporary pixel index buffer loop counter. */
+ uint ud; /* Unscaled edge distance. */
+ uint dmin; /* Minimum edge distance. */
- unsigned int rsl; /* Long used for finding fast `1.0/sqrt`. */
- unsigned int gradient_fill_offset;
+ uint rsl; /* Long used for finding fast `1.0/sqrt`. */
+ uint gradient_fill_offset;
/* For looping inner edge pixel indexes, represents current position from offset. */
- unsigned int inner_accum = 0;
+ uint inner_accum = 0;
/* For looping outer edge pixel indexes, represents current position from offset. */
- unsigned int outer_accum = 0;
+ uint outer_accum = 0;
/* For looping gradient pixel indexes, represents current position from offset. */
- unsigned int gradient_accum = 0;
+ uint gradient_accum = 0;
/* Disable clang-format to prevent line-wrapping. */
/* clang-format off */
@@ -958,12 +938,12 @@ static void do_createEdgeLocationBuffer(unsigned int t,
* or outer edge.
*
* Allocation is done by requesting 4 bytes "sizeof(int)" per pixel, even
- * though gbuf[] is declared as (unsigned short *) (2 bytes) because we don't
+ * though gbuf[] is declared as `(ushort *)` (2 bytes) because we don't
* store the pixel indexes, we only store x,y location of pixel in buffer.
*
* This does make the assumption that x and y can fit in 16 unsigned bits
* so if Blender starts doing renders greater than 65536 in either direction
- * this will need to allocate gbuf[] as unsigned int *and allocate 8 bytes
+ * this will need to allocate gbuf[] as uint *and allocate 8 bytes
* per flagged pixel.
*
* In general, the buffer on-screen:
@@ -1028,20 +1008,20 @@ static void do_createEdgeLocationBuffer(unsigned int t,
for (rsl = 0; rsl < rw; rsl++) {
a = x + rsl;
if (lres[a] == 2) { /* It is a gradient pixel flagged by 2. */
- ud = gradient_accum << 1; /* Double the index to reach correct unsigned short location. */
+ ud = gradient_accum << 1; /* Double the index to reach correct ushort location. */
gbuf[ud] = dmin; /* Insert pixel's row into gradient pixel location buffer. */
gbuf[ud + 1] = rsl; /* Insert pixel's column into gradient pixel location buffer. */
gradient_accum++; /* Increment gradient index buffer pointer. */
}
else if (lres[a] == 3) { /* It is an outer edge pixel flagged by 3. */
- ud = outer_accum << 1; /* Double the index to reach correct unsigned short location. */
+ ud = outer_accum << 1; /* Double the index to reach correct ushort location. */
gbuf[ud] = dmin; /* Insert pixel's row into outer edge pixel location buffer. */
gbuf[ud + 1] = rsl; /* Insert pixel's column into outer edge pixel location buffer. */
outer_accum++; /* Increment outer edge index buffer pointer. */
res[a] = 0.0f; /* Set output pixel intensity now since it won't change later. */
}
else if (lres[a] == 4) { /* It is an inner edge pixel flagged by 4. */
- ud = inner_accum << 1; /* Double int index to reach correct unsigned short location. */
+ ud = inner_accum << 1; /* Double int index to reach correct ushort location. */
gbuf[ud] = dmin; /* Insert pixel's row into inner edge pixel location buffer. */
gbuf[ud + 1] = rsl; /* Insert pixel's column into inner edge pixel location buffer. */
inner_accum++; /* Increment inner edge index buffer pointer. */
@@ -1051,30 +1031,30 @@ static void do_createEdgeLocationBuffer(unsigned int t,
}
}
-static void do_fillGradientBuffer(unsigned int rw,
+static void do_fillGradientBuffer(uint rw,
float *res,
- const unsigned short *gbuf,
- unsigned int isz,
- unsigned int osz,
- unsigned int gsz,
- unsigned int inner_edge_offset,
- unsigned int outer_edge_offset)
+ const ushort *gbuf,
+ uint isz,
+ uint osz,
+ uint gsz,
+ uint inner_edge_offset,
+ uint outer_edge_offset)
{
int x; /* Pixel loop counter. */
int a; /* Temporary pixel index buffer loop counter. */
int fsz; /* Size of the frame. */
- unsigned int rsl; /* Long used for finding fast `1.0/sqrt`. */
+ uint rsl; /* Long used for finding fast `1.0/sqrt`. */
float rsf; /* Float used for finding fast `1.0/sqrt`. */
const float rsopf = 1.5f; /* Constant float used for finding fast `1.0/sqrt`. */
- unsigned int gradient_fill_offset;
- unsigned int t;
- unsigned int ud; /* Unscaled edge distance. */
- unsigned int dmin; /* Minimum edge distance. */
- float odist; /* Current outer edge distance. */
- float idist; /* Current inner edge distance. */
- int dx; /* X-delta (used for distance proportion calculation) */
- int dy; /* Y-delta (used for distance proportion calculation) */
+ uint gradient_fill_offset;
+ uint t;
+ uint ud; /* Unscaled edge distance. */
+ uint dmin; /* Minimum edge distance. */
+ float odist; /* Current outer edge distance. */
+ float idist; /* Current inner edge distance. */
+ int dx; /* X-delta (used for distance proportion calculation) */
+ int dy; /* Y-delta (used for distance proportion calculation) */
/*
* The general algorithm used to color each gradient pixel is:
@@ -1150,10 +1130,10 @@ static void do_fillGradientBuffer(unsigned int rw,
dmin = ud; /* Set a new minimum equal to the new lower value. */
}
}
- odist = (float)(dmin); /* Cast outer min to a float. */
+ odist = float(dmin); /* Cast outer min to a float. */
rsf = odist * 0.5f;
- rsl = *(unsigned int *)&odist; /* Use some peculiar properties of the way bits are stored. */
- rsl = 0x5f3759df - (rsl >> 1); /* In floats vs. unsigned ints to compute an approximate. */
+ rsl = *(uint *)&odist; /* Use some peculiar properties of the way bits are stored. */
+ rsl = 0x5f3759df - (rsl >> 1); /* In floats vs. uints to compute an approximate. */
odist = *(float *)&rsl; /* Reciprocal square root. */
odist = odist * (rsopf - (rsf * odist *
odist)); /* -- This line can be iterated for more accuracy. -- */
@@ -1171,9 +1151,9 @@ static void do_fillGradientBuffer(unsigned int rw,
}
/* Cast inner min to a float. */
- idist = (float)(dmin);
+ idist = float(dmin);
rsf = idist * 0.5f;
- rsl = *(unsigned int *)&idist;
+ rsl = *(uint *)&idist;
/* See notes above. */
rsl = 0x5f3759df - (rsl >> 1);
@@ -1195,24 +1175,22 @@ static void do_fillGradientBuffer(unsigned int rw,
void DoubleEdgeMaskOperation::do_double_edge_mask(float *imask, float *omask, float *res)
{
- unsigned int *lres; /* Pointer to output pixel buffer (for bit operations). */
- unsigned int *limask; /* Pointer to inner mask (for bit operations). */
- unsigned int *lomask; /* Pointer to outer mask (for bit operations). */
+ uint *lres; /* Pointer to output pixel buffer (for bit operations). */
+ uint *limask; /* Pointer to inner mask (for bit operations). */
+ uint *lomask; /* Pointer to outer mask (for bit operations). */
int rw; /* Pixel row width. */
int t; /* Total number of pixels in buffer - 1 (used for loop starts). */
int fsz; /* Size of the frame. */
- unsigned int isz = 0; /* Size (in pixels) of inside edge pixel index buffer. */
- unsigned int osz = 0; /* Size (in pixels) of outside edge pixel index buffer. */
- unsigned int gsz = 0; /* Size (in pixels) of gradient pixel index buffer. */
- unsigned int rsize[3]; /* Size storage to pass to helper functions. */
- unsigned int inner_edge_offset =
- 0; /* Offset into final buffer where inner edge pixel indexes start. */
- unsigned int outer_edge_offset =
- 0; /* Offset into final buffer where outer edge pixel indexes start. */
+ uint isz = 0; /* Size (in pixels) of inside edge pixel index buffer. */
+ uint osz = 0; /* Size (in pixels) of outside edge pixel index buffer. */
+ uint gsz = 0; /* Size (in pixels) of gradient pixel index buffer. */
+ uint rsize[3]; /* Size storage to pass to helper functions. */
+ uint inner_edge_offset = 0; /* Offset into final buffer where inner edge pixel indexes start. */
+ uint outer_edge_offset = 0; /* Offset into final buffer where outer edge pixel indexes start. */
- unsigned short *gbuf; /* Gradient/inner/outer pixel location index buffer. */
+ ushort *gbuf; /* Gradient/inner/outer pixel location index buffer. */
if (true) { /* If both input sockets have some data coming in... */
@@ -1223,9 +1201,9 @@ void DoubleEdgeMaskOperation::do_double_edge_mask(float *imask, float *omask, fl
sizeof(float) *
(t + 1)); /* Clear output buffer (not all pixels will be written later). */
- lres = (unsigned int *)res; /* Pointer to output buffer (for bit level ops).. */
- limask = (unsigned int *)imask; /* Pointer to input mask (for bit level ops).. */
- lomask = (unsigned int *)omask; /* Pointer to output mask (for bit level ops).. */
+ lres = (uint *)res; /* Pointer to output buffer (for bit level ops).. */
+ limask = (uint *)imask; /* Pointer to input mask (for bit level ops).. */
+ lomask = (uint *)omask; /* Pointer to output mask (for bit level ops).. */
/*
* The whole buffer is broken up into 4 parts. The four CORNERS, the FIRST and LAST rows, the
@@ -1291,7 +1269,7 @@ void DoubleEdgeMaskOperation::do_double_edge_mask(float *imask, float *omask, fl
/* Calculate size of pixel index buffer needed. */
fsz = gsz + isz + osz;
/* Allocate edge/gradient pixel index buffer. */
- gbuf = (unsigned short *)MEM_callocN(sizeof(unsigned short) * fsz * 2, "DEM");
+ gbuf = (ushort *)MEM_callocN(sizeof(ushort) * fsz * 2, "DEM");
do_createEdgeLocationBuffer(
t, rw, lres, res, gbuf, &inner_edge_offset, &outer_edge_offset, isz, gsz);
@@ -1376,15 +1354,15 @@ void DoubleEdgeMaskOperation::deinit_execution()
}
}
-void DoubleEdgeMaskOperation::get_area_of_interest(int UNUSED(input_idx),
- const rcti &UNUSED(output_area),
+void DoubleEdgeMaskOperation::get_area_of_interest(int /*input_idx*/,
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
r_input_area = this->get_canvas();
}
void DoubleEdgeMaskOperation::update_memory_buffer(MemoryBuffer *output,
- const rcti &UNUSED(area),
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
if (!is_output_rendered_) {
diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.cc b/source/blender/compositor/operations/COM_EllipseMaskOperation.cc
index 508e5ea5712..064163801ea 100644
--- a/source/blender/compositor/operations/COM_EllipseMaskOperation.cc
+++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.cc
@@ -19,10 +19,10 @@ void EllipseMaskOperation::init_execution()
{
input_mask_ = this->get_input_socket_reader(0);
input_value_ = this->get_input_socket_reader(1);
- const double rad = (double)data_->rotation;
+ const double rad = double(data_->rotation);
cosine_ = cos(rad);
sine_ = sin(rad);
- aspect_ratio_ = ((float)this->get_width()) / this->get_height();
+ aspect_ratio_ = float(this->get_width()) / this->get_height();
}
void EllipseMaskOperation::execute_pixel_sampled(float output[4],
diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc
index 725751d15af..7557d1bc4bd 100644
--- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc
@@ -102,18 +102,15 @@ void *FastGaussianBlurOperation::initialize_tile_data(rcti *rect)
return iirgaus_;
}
-void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src,
- float sigma,
- unsigned int chan,
- unsigned int xy)
+void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, uint chan, uint xy)
{
BLI_assert(!src->is_a_single_elem());
double q, q2, sc, cf[4], tsM[9], tsu[3], tsv[3];
double *X, *Y, *W;
- const unsigned int src_width = src->get_width();
- const unsigned int src_height = src->get_height();
- unsigned int x, y, src_dim_max;
- unsigned int i;
+ const uint src_width = src->get_width();
+ const uint src_height = src->get_height();
+ uint x, y, src_dim_max;
+ uint i;
float *buffer = src->get_buffer();
const uint8_t num_channels = src->get_num_channels();
@@ -194,7 +191,7 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src,
Y[L - 1] = cf[0] * W[L - 1] + cf[1] * tsv[0] + cf[2] * tsv[1] + cf[3] * tsv[2]; \
Y[L - 2] = cf[0] * W[L - 2] + cf[1] * Y[L - 1] + cf[2] * tsv[0] + cf[3] * tsv[1]; \
Y[L - 3] = cf[0] * W[L - 3] + cf[1] * Y[L - 2] + cf[2] * Y[L - 1] + cf[3] * tsv[0]; \
- /* 'i != UINT_MAX' is really 'i >= 0', but necessary for unsigned int wrapping */ \
+ /* `i != UINT_MAX` is really `i >= 0`, but necessary for `uint` wrapping. */ \
for (i = L - 4; i != UINT_MAX; i--) { \
Y[i] = cf[0] * W[i] + cf[1] * Y[i + 1] + cf[2] * Y[i + 2] + cf[3] * Y[i + 3]; \
} \
@@ -387,15 +384,15 @@ void *FastGaussianBlurValueOperation::initialize_tile_data(rcti *rect)
return iirgaus_;
}
-void FastGaussianBlurValueOperation::get_area_of_interest(const int UNUSED(input_idx),
- const rcti &UNUSED(output_area),
+void FastGaussianBlurValueOperation::get_area_of_interest(const int /*input_idx*/,
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
r_input_area = this->get_canvas();
}
-void FastGaussianBlurValueOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
+void FastGaussianBlurValueOperation::update_memory_buffer_started(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
if (iirgaus_ == nullptr) {
diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h
index 157d3c7f32f..0f7064c19a5 100644
--- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h
+++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h
@@ -31,9 +31,9 @@ class FastGaussianBlurOperation : public BlurBaseOperation {
void update_memory_buffer_started(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;
- void update_memory_buffer_partial(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
- Span<MemoryBuffer *> UNUSED(inputs)) override
+ void update_memory_buffer_partial(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
+ Span<MemoryBuffer *> /*inputs*/) override
{
}
};
diff --git a/source/blender/compositor/operations/COM_FlipOperation.cc b/source/blender/compositor/operations/COM_FlipOperation.cc
index 369f124622a..3d9d574b89d 100644
--- a/source/blender/compositor/operations/COM_FlipOperation.cc
+++ b/source/blender/compositor/operations/COM_FlipOperation.cc
@@ -26,8 +26,8 @@ void FlipOperation::deinit_execution()
void FlipOperation::execute_pixel_sampled(float output[4], float x, float y, PixelSampler sampler)
{
- float nx = flip_x_ ? ((int)this->get_width() - 1) - x : x;
- float ny = flip_y_ ? ((int)this->get_height() - 1) - y : y;
+ float nx = flip_x_ ? (int(this->get_width()) - 1) - x : x;
+ float ny = flip_y_ ? (int(this->get_height()) - 1) - y : y;
input_operation_->read_sampled(output, nx, ny, sampler);
}
@@ -39,7 +39,7 @@ bool FlipOperation::determine_depending_area_of_interest(rcti *input,
rcti new_input;
if (flip_x_) {
- const int w = (int)this->get_width() - 1;
+ const int w = int(this->get_width()) - 1;
new_input.xmax = (w - input->xmin) + 1;
new_input.xmin = (w - input->xmax) - 1;
}
@@ -48,7 +48,7 @@ bool FlipOperation::determine_depending_area_of_interest(rcti *input,
new_input.xmax = input->xmax;
}
if (flip_y_) {
- const int h = (int)this->get_height() - 1;
+ const int h = int(this->get_height()) - 1;
new_input.ymax = (h - input->ymin) + 1;
new_input.ymin = (h - input->ymax) - 1;
}
@@ -85,7 +85,7 @@ void FlipOperation::get_area_of_interest(const int input_idx,
BLI_assert(input_idx == 0);
UNUSED_VARS_NDEBUG(input_idx);
if (flip_x_) {
- const int w = (int)this->get_width() - 1;
+ const int w = int(this->get_width()) - 1;
r_input_area.xmax = (w - output_area.xmin) + 1;
r_input_area.xmin = (w - output_area.xmax) + 1;
}
@@ -94,7 +94,7 @@ void FlipOperation::get_area_of_interest(const int input_idx,
r_input_area.xmax = output_area.xmax;
}
if (flip_y_) {
- const int h = (int)this->get_height() - 1;
+ const int h = int(this->get_height()) - 1;
r_input_area.ymax = (h - output_area.ymin) + 1;
r_input_area.ymin = (h - output_area.ymax) + 1;
}
@@ -112,8 +112,8 @@ void FlipOperation::update_memory_buffer_partial(MemoryBuffer *output,
const int input_offset_x = input_img->get_rect().xmin;
const int input_offset_y = input_img->get_rect().ymin;
for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
- const int nx = flip_x_ ? ((int)this->get_width() - 1) - it.x : it.x;
- const int ny = flip_y_ ? ((int)this->get_height() - 1) - it.y : it.y;
+ const int nx = flip_x_ ? (int(this->get_width()) - 1) - it.x : it.x;
+ const int ny = flip_y_ ? (int(this->get_height()) - 1) - it.y : it.y;
input_img->read_elem(input_offset_x + nx, input_offset_y + ny, it.out);
}
}
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc b/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc
index f380abf42f0..75b2249b6a7 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc
+++ b/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc
@@ -114,7 +114,7 @@ void GaussianAlphaBlurBaseOperation::update_memory_buffer_partial(MemoryBuffer *
float distfacinv_max = 1.0f; /* 0 to 1 */
const int step = QualityStepHelper::get_step();
- const float *in = it.in(0) + ((intptr_t)coord_min - coord) * elem_stride;
+ const float *in = it.in(0) + (intptr_t(coord_min) - coord) * elem_stride;
const int in_stride = elem_stride * step;
int index = (coord_min - coord) + filtersize_;
const int index_end = index + (coord_max - coord_min);
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cc b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cc
index 49669d70177..4a589d45275 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cc
@@ -73,7 +73,7 @@ void GaussianAlphaXBlurOperation::execute_pixel(float output[4], int x, int y, v
/* *** this is the main part which is different to 'GaussianXBlurOperation' *** */
int step = get_step();
- int bufferindex = ((xmin - bufferstartx)) + ((ymin - bufferstarty) * bufferwidth);
+ int bufferindex = (xmin - bufferstartx) + ((ymin - bufferstarty) * bufferwidth);
/* gauss */
float alpha_accum = 0.0f;
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cc b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cc
index 0e73299f58e..e9ff756093c 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cc
@@ -86,7 +86,7 @@ void GaussianAlphaYBlurOperation::execute_pixel(float output[4], int x, int y, v
float distfacinv_max = 1.0f; /* 0 to 1 */
for (int ny = ymin; ny < ymax; ny += step) {
- int bufferindex = ((xmin - bufferstartx)) + ((ny - bufferstarty) * bufferwidth);
+ int bufferindex = (xmin - bufferstartx) + ((ny - bufferstarty) * bufferwidth);
const int index = (ny - y) + filtersize_;
float value = finv_test(buffer[bufferindex], do_invert);
diff --git a/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc b/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc
index 3c66f74f284..b2b10e77012 100644
--- a/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc
+++ b/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc
@@ -112,7 +112,7 @@ void GaussianBlurBaseOperation::update_memory_buffer_partial(MemoryBuffer *outpu
float multiplier_accum = 0.0f;
const int step = QualityStepHelper::get_step();
- const float *in = it.in(0) + ((intptr_t)coord_min - coord) * elem_stride;
+ const float *in = it.in(0) + (intptr_t(coord_min) - coord) * elem_stride;
const int in_stride = elem_stride * step;
int gauss_idx = (coord_min - coord) + filtersize_;
const int gauss_end = gauss_idx + (coord_max - coord_min);
diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc
index fa45034b00c..039e6a9bcc0 100644
--- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc
@@ -35,11 +35,11 @@ void GaussianBokehBlurOperation::init_data()
}
}
- radxf_ = size_ * (float)data_.sizex;
+ radxf_ = size_ * float(data_.sizex);
CLAMP(radxf_, 0.0f, width / 2.0f);
/* Vertical. */
- radyf_ = size_ * (float)data_.sizey;
+ radyf_ = size_ * float(data_.sizey);
CLAMP(radyf_, 0.0f, height / 2.0f);
radx_ = ceil(radxf_);
@@ -71,8 +71,8 @@ void GaussianBokehBlurOperation::update_gauss()
float facy = (radyf_ > 0.0f ? 1.0f / radyf_ : 0.0f);
for (int j = -rady_; j <= rady_; j++) {
for (int i = -radx_; i <= radx_; i++, dgauss++) {
- float fj = (float)j * facy;
- float fi = (float)i * facx;
+ float fj = float(j) * facy;
+ float fi = float(i) * facx;
float dist = sqrt(fj * fj + fi * fi);
*dgauss = RE_filter_value(data_.filtertype, dist);
@@ -105,10 +105,10 @@ void GaussianBokehBlurOperation::execute_pixel(float output[4], int x, int y, vo
const float width = this->get_width();
const float height = this->get_height();
- radxf_ = size_ * (float)data_.sizex;
+ radxf_ = size_ * float(data_.sizex);
CLAMP(radxf_, 0.0f, width / 2.0f);
- radyf_ = size_ * (float)data_.sizey;
+ radyf_ = size_ * float(data_.sizey);
CLAMP(radyf_, 0.0f, height / 2.0f);
radx_ = ceil(radxf_);
@@ -265,22 +265,22 @@ void GaussianBlurReferenceOperation::init_data()
if (data_.relative) {
switch (data_.aspect) {
case CMP_NODE_BLUR_ASPECT_NONE:
- data_.sizex = (int)(data_.percentx * 0.01f * data_.image_in_width);
- data_.sizey = (int)(data_.percenty * 0.01f * data_.image_in_height);
+ data_.sizex = int(data_.percentx * 0.01f * data_.image_in_width);
+ data_.sizey = int(data_.percenty * 0.01f * data_.image_in_height);
break;
case CMP_NODE_BLUR_ASPECT_Y:
- data_.sizex = (int)(data_.percentx * 0.01f * data_.image_in_width);
- data_.sizey = (int)(data_.percenty * 0.01f * data_.image_in_width);
+ data_.sizex = int(data_.percentx * 0.01f * data_.image_in_width);
+ data_.sizey = int(data_.percenty * 0.01f * data_.image_in_width);
break;
case CMP_NODE_BLUR_ASPECT_X:
- data_.sizex = (int)(data_.percentx * 0.01f * data_.image_in_height);
- data_.sizey = (int)(data_.percenty * 0.01f * data_.image_in_height);
+ data_.sizex = int(data_.percentx * 0.01f * data_.image_in_height);
+ data_.sizey = int(data_.percenty * 0.01f * data_.image_in_height);
break;
}
}
/* Horizontal. */
- filtersizex_ = (float)data_.sizex;
+ filtersizex_ = float(data_.sizex);
int imgx = get_width() / 2;
if (filtersizex_ > imgx) {
filtersizex_ = imgx;
@@ -288,10 +288,10 @@ void GaussianBlurReferenceOperation::init_data()
else if (filtersizex_ < 1) {
filtersizex_ = 1;
}
- radx_ = (float)filtersizex_;
+ radx_ = float(filtersizex_);
/* Vertical. */
- filtersizey_ = (float)data_.sizey;
+ filtersizey_ = float(data_.sizey);
int imgy = get_height() / 2;
if (filtersizey_ > imgy) {
filtersizey_ = imgy;
@@ -299,7 +299,7 @@ void GaussianBlurReferenceOperation::init_data()
else if (filtersizey_ < 1) {
filtersizey_ = 1;
}
- rady_ = (float)filtersizey_;
+ rady_ = float(filtersizey_);
}
void *GaussianBlurReferenceOperation::initialize_tile_data(rcti * /*rect*/)
@@ -340,8 +340,8 @@ void GaussianBlurReferenceOperation::execute_pixel(float output[4], int x, int y
float temp_size[4];
input_size_->read(temp_size, x, y, data);
float ref_size = temp_size[0];
- int refradx = (int)(ref_size * radx_);
- int refrady = (int)(ref_size * rady_);
+ int refradx = int(ref_size * radx_);
+ int refrady = int(ref_size * rady_);
if (refradx > filtersizex_) {
refradx = filtersizex_;
}
@@ -447,8 +447,8 @@ void GaussianBlurReferenceOperation::update_memory_buffer_partial(MemoryBuffer *
MemoryBuffer *size_input = inputs[SIZE_INPUT_INDEX];
for (BuffersIterator<float> it = output->iterate_with({size_input}, area); !it.is_end(); ++it) {
const float ref_size = *it.in(0);
- int ref_radx = (int)(ref_size * radx_);
- int ref_rady = (int)(ref_size * rady_);
+ int ref_radx = int(ref_size * radx_);
+ int ref_rady = int(ref_size * rady_);
if (ref_radx > filtersizex_) {
ref_radx = filtersizex_;
}
diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.cc b/source/blender/compositor/operations/COM_GlareBaseOperation.cc
index 13f55b5909c..93d3c2063ae 100644
--- a/source/blender/compositor/operations/COM_GlareBaseOperation.cc
+++ b/source/blender/compositor/operations/COM_GlareBaseOperation.cc
@@ -56,7 +56,7 @@ bool GlareBaseOperation::determine_depending_area_of_interest(rcti * /*input*/,
}
void GlareBaseOperation::get_area_of_interest(const int input_idx,
- const rcti &UNUSED(output_area),
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
BLI_assert(input_idx == 0);
@@ -68,7 +68,7 @@ void GlareBaseOperation::get_area_of_interest(const int input_idx,
}
void GlareBaseOperation::update_memory_buffer(MemoryBuffer *output,
- const rcti &UNUSED(area),
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
if (!is_output_rendered_) {
diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc
index ade3f11a8b3..4f7b1be9057 100644
--- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc
+++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc
@@ -12,9 +12,9 @@ namespace blender::compositor {
using fREAL = float;
/* Returns next highest power of 2 of x, as well its log2 in L2. */
-static unsigned int next_pow2(unsigned int x, unsigned int *L2)
+static uint next_pow2(uint x, uint *L2)
{
- unsigned int pw, x_notpow2 = x & (x - 1);
+ uint pw, x_notpow2 = x & (x - 1);
*L2 = 0;
while (x >>= 1) {
++(*L2);
@@ -31,7 +31,7 @@ static unsigned int next_pow2(unsigned int x, unsigned int *L2)
/* From FXT library by Joerg Arndt, faster in order bit-reversal
* use: `r = revbin_upd(r, h)` where `h = N>>1`. */
-static unsigned int revbin_upd(unsigned int r, unsigned int h)
+static uint revbin_upd(uint r, uint h)
{
while (!((r ^= h) & h)) {
h >>= 1;
@@ -39,14 +39,14 @@ static unsigned int revbin_upd(unsigned int r, unsigned int h)
return r;
}
//------------------------------------------------------------------------------
-static void FHT(fREAL *data, unsigned int M, unsigned int inverse)
+static void FHT(fREAL *data, uint M, uint inverse)
{
double tt, fc, dc, fs, ds, a = M_PI;
fREAL t1, t2;
int n2, bd, bl, istep, k, len = 1 << M, n = 1;
int i, j = 0;
- unsigned int Nh = len >> 1;
+ uint Nh = len >> 1;
for (i = 1; i < (len - 1); i++) {
j = revbin_upd(j, Nh);
if (j > i) {
@@ -75,8 +75,8 @@ static void FHT(fREAL *data, unsigned int M, unsigned int inverse)
fREAL *data_nbd = &data_n[bd];
fREAL *data_bd = &data[bd];
for (k = bl; k < len; k += istep) {
- t1 = fc * (double)data_n[k] + fs * (double)data_nbd[k];
- t2 = fs * (double)data_n[k] - fc * (double)data_nbd[k];
+ t1 = fc * double(data_n[k]) + fs * double(data_nbd[k]);
+ t2 = fs * double(data_n[k]) - fc * double(data_nbd[k]);
data_n[k] = data[k] - t1;
data_nbd[k] = data_bd[k] - t2;
data[k] += t1;
@@ -112,10 +112,9 @@ static void FHT(fREAL *data, unsigned int M, unsigned int inverse)
/* 2D Fast Hartley Transform, Mx/My -> log2 of width/height,
* nzp -> the row where zero pad data starts,
* inverse -> see above. */
-static void FHT2D(
- fREAL *data, unsigned int Mx, unsigned int My, unsigned int nzp, unsigned int inverse)
+static void FHT2D(fREAL *data, uint Mx, uint My, uint nzp, uint inverse)
{
- unsigned int i, j, Nx, Ny, maxy;
+ uint i, j, Nx, Ny, maxy;
Nx = 1 << Mx;
Ny = 1 << My;
@@ -130,13 +129,13 @@ static void FHT2D(
if (Nx == Ny) { /* Square. */
for (j = 0; j < Ny; j++) {
for (i = j + 1; i < Nx; i++) {
- unsigned int op = i + (j << Mx), np = j + (i << My);
+ uint op = i + (j << Mx), np = j + (i << My);
SWAP(fREAL, data[op], data[np]);
}
}
}
else { /* Rectangular. */
- unsigned int k, Nym = Ny - 1, stm = 1 << (Mx + My);
+ uint k, Nym = Ny - 1, stm = 1 << (Mx + My);
for (i = 0; stm > 0; i++) {
#define PRED(k) (((k & Nym) << Mx) + (k >> My))
for (j = PRED(i); j > i; j = PRED(j)) {
@@ -153,8 +152,8 @@ static void FHT2D(
}
}
- SWAP(unsigned int, Nx, Ny);
- SWAP(unsigned int, Mx, My);
+ SWAP(uint, Nx, Ny);
+ SWAP(uint, Mx, My);
/* Now columns == transposed rows. */
for (j = 0; j < Ny; j++) {
@@ -163,11 +162,11 @@ static void FHT2D(
/* Finalize. */
for (j = 0; j <= (Ny >> 1); j++) {
- unsigned int jm = (Ny - j) & (Ny - 1);
- unsigned int ji = j << Mx;
- unsigned int jmi = jm << Mx;
+ uint jm = (Ny - j) & (Ny - 1);
+ uint ji = j << Mx;
+ uint jmi = jm << Mx;
for (i = 0; i <= (Nx >> 1); i++) {
- unsigned int im = (Nx - i) & (Nx - 1);
+ uint im = (Nx - i) & (Nx - 1);
fREAL A = data[ji + i];
fREAL B = data[jmi + i];
fREAL C = data[ji + im];
@@ -184,13 +183,13 @@ static void FHT2D(
//------------------------------------------------------------------------------
/* 2D convolution calc, d1 *= d2, M/N - > log2 of width/height. */
-static void fht_convolve(fREAL *d1, const fREAL *d2, unsigned int M, unsigned int N)
+static void fht_convolve(fREAL *d1, const fREAL *d2, uint M, uint N)
{
fREAL a, b;
- unsigned int i, j, k, L, mj, mL;
- unsigned int m = 1 << M, n = 1 << N;
- unsigned int m2 = 1 << (M - 1), n2 = 1 << (N - 1);
- unsigned int mn2 = m << (N - 1);
+ uint i, j, k, L, mj, mL;
+ uint m = 1 << M, n = 1 << N;
+ uint m2 = 1 << (M - 1), n2 = 1 << (N - 1);
+ uint mn2 = m << (N - 1);
d1[0] *= d2[0];
d1[mn2] *= d2[mn2];
@@ -242,15 +241,15 @@ static void fht_convolve(fREAL *d1, const fREAL *d2, unsigned int M, unsigned in
static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
{
fREAL *data1, *data2, *fp;
- unsigned int w2, h2, hw, hh, log2_w, log2_h;
+ uint w2, h2, hw, hh, log2_w, log2_h;
fRGB wt, *colp;
int x, y, ch;
int xbl, ybl, nxb, nyb, xbsz, ybsz;
bool in2done = false;
- const unsigned int kernel_width = in2->get_width();
- const unsigned int kernel_height = in2->get_height();
- const unsigned int image_width = in1->get_width();
- const unsigned int image_height = in1->get_height();
+ const uint kernel_width = in2->get_width();
+ const uint kernel_height = in2->get_height();
+ const uint image_width = in1->get_width();
+ const uint image_height = in1->get_height();
float *kernel_buffer = in2->get_buffer();
float *image_buffer = in1->get_buffer();
@@ -361,14 +360,14 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
/* Data again transposed, so in order again. */
/* Overlap-add result. */
- for (y = 0; y < (int)h2; y++) {
+ for (y = 0; y < int(h2); y++) {
const int yy = ybl * ybsz + y - hh;
if ((yy < 0) || (yy >= image_height)) {
continue;
}
fp = &data2[y * w2];
colp = (fRGB *)&rdst->get_buffer()[yy * image_width * COM_DATA_TYPE_COLOR_CHANNELS];
- for (x = 0; x < (int)w2; x++) {
+ for (x = 0; x < int(w2); x++) {
const int xx = xbl * xbsz + x - hw;
if ((xx < 0) || (xx >= image_width)) {
continue;
@@ -397,7 +396,7 @@ void GlareFogGlowOperation::generate_glare(float *data,
float scale, u, v, r, w, d;
fRGB fcol;
MemoryBuffer *ckrn;
- unsigned int sz = 1 << settings->size;
+ uint sz = 1 << settings->size;
const float cs_r = 1.0f, cs_g = 1.0f, cs_b = 1.0f;
/* Temp. src image
@@ -406,12 +405,12 @@ void GlareFogGlowOperation::generate_glare(float *data,
BLI_rcti_init(&kernel_rect, 0, sz, 0, sz);
ckrn = new MemoryBuffer(DataType::Color, kernel_rect);
- scale = 0.25f * sqrtf((float)(sz * sz));
+ scale = 0.25f * sqrtf(float(sz * sz));
for (y = 0; y < sz; y++) {
- v = 2.0f * (y / (float)sz) - 1.0f;
+ v = 2.0f * (y / float(sz)) - 1.0f;
for (x = 0; x < sz; x++) {
- u = 2.0f * (x / (float)sz) - 1.0f;
+ u = 2.0f * (x / float(sz)) - 1.0f;
r = (u * u + v * v) * scale;
d = -sqrtf(sqrtf(sqrtf(r))) * 9.0f;
fcol[0] = expf(d * cs_r);
@@ -420,7 +419,7 @@ void GlareFogGlowOperation::generate_glare(float *data,
/* Linear window good enough here, visual result counts, not scientific analysis:
* `w = (1.0f-fabs(u))*(1.0f-fabs(v));`
* actually, Hanning window is ok, `cos^2` for some reason is slower. */
- w = (0.5f + 0.5f * cosf(u * (float)M_PI)) * (0.5f + 0.5f * cosf(v * (float)M_PI));
+ w = (0.5f + 0.5f * cosf(u * float(M_PI))) * (0.5f + 0.5f * cosf(v * float(M_PI)));
mul_v3_fl(fcol, w);
ckrn->write_pixel(x, y, fcol);
}
diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.cc b/source/blender/compositor/operations/COM_GlareGhostOperation.cc
index 13b7af2329e..5ba0901231d 100644
--- a/source/blender/compositor/operations/COM_GlareGhostOperation.cc
+++ b/source/blender/compositor/operations/COM_GlareGhostOperation.cc
@@ -23,7 +23,7 @@ void GlareGhostOperation::generate_glare(float *data,
const NodeGlare *settings)
{
const int qt = 1 << settings->quality;
- const float s1 = 4.0f / (float)qt, s2 = 2.0f * s1;
+ const float s1 = 4.0f / float(qt), s2 = 2.0f * s1;
int x, y, n, p, np;
fRGB c, tc, cm[64];
float sc, isc, u, v, sm, s, t, ofs, scalef[64];
@@ -79,7 +79,7 @@ void GlareGhostOperation::generate_glare(float *data,
if (y == 3) {
fRGB_rgbmult(cm[x], cmo, 1.0f, cmo);
}
- scalef[x] = 2.1f * (1.0f - (x + ofs) / (float)(settings->iter * 4));
+ scalef[x] = 2.1f * (1.0f - (x + ofs) / float(settings->iter * 4));
if (x & 1) {
scalef[x] = -0.99f / scalef[x];
}
@@ -88,9 +88,9 @@ void GlareGhostOperation::generate_glare(float *data,
sc = 2.13;
isc = -0.97;
for (y = 0; y < gbuf.get_height() && (!breaked); y++) {
- v = ((float)y + 0.5f) / (float)gbuf.get_height();
+ v = (float(y) + 0.5f) / float(gbuf.get_height());
for (x = 0; x < gbuf.get_width(); x++) {
- u = ((float)x + 0.5f) / (float)gbuf.get_width();
+ u = (float(x) + 0.5f) / float(gbuf.get_width());
s = (u - 0.5f) * sc + 0.5f;
t = (v - 0.5f) * sc + 0.5f;
tbuf1.read_bilinear(c, s * gbuf.get_width(), t * gbuf.get_height());
@@ -114,9 +114,9 @@ void GlareGhostOperation::generate_glare(float *data,
tbuf1.get_width() * tbuf1.get_height() * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float));
for (n = 1; n < settings->iter && (!breaked); n++) {
for (y = 0; y < gbuf.get_height() && (!breaked); y++) {
- v = ((float)y + 0.5f) / (float)gbuf.get_height();
+ v = (float(y) + 0.5f) / float(gbuf.get_height());
for (x = 0; x < gbuf.get_width(); x++) {
- u = ((float)x + 0.5f) / (float)gbuf.get_width();
+ u = (float(x) + 0.5f) / float(gbuf.get_width());
tc[0] = tc[1] = tc[2] = 0.0f;
for (p = 0; p < 4; p++) {
np = (n << 2) + p;
diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.cc b/source/blender/compositor/operations/COM_GlareStreaksOperation.cc
index e4f06eb0e50..c544e13cf34 100644
--- a/source/blender/compositor/operations/COM_GlareStreaksOperation.cc
+++ b/source/blender/compositor/operations/COM_GlareStreaksOperation.cc
@@ -10,9 +10,9 @@ void GlareStreaksOperation::generate_glare(float *data,
const NodeGlare *settings)
{
int x, y, n;
- unsigned int nump = 0;
+ uint nump = 0;
float c1[4], c2[4], c3[4], c4[4];
- float a, ang = DEG2RADF(360.0f) / (float)settings->streaks;
+ float a, ang = DEG2RADF(360.0f) / float(settings->streaks);
int size = input_tile->get_width() * input_tile->get_height();
int size4 = size * 4;
@@ -26,14 +26,14 @@ void GlareStreaksOperation::generate_glare(float *data,
for (a = 0.0f; a < DEG2RADF(360.0f) && (!breaked); a += ang) {
const float an = a + settings->angle_ofs;
- const float vx = cos((double)an), vy = sin((double)an);
+ const float vx = cos(double(an)), vy = sin(double(an));
for (n = 0; n < settings->iter && (!breaked); n++) {
- const float p4 = pow(4.0, (double)n);
+ const float p4 = pow(4.0, double(n));
const float vxp = vx * p4, vyp = vy * p4;
- const float wt = pow((double)settings->fade, (double)p4);
+ const float wt = pow(double(settings->fade), double(p4));
/* Color-modulation amount relative to current pass. */
- const float cmo = 1.0f - (float)pow((double)settings->colmod, (double)n + 1);
+ const float cmo = 1.0f - float(pow(double(settings->colmod), double(n) + 1));
float *tdstcol = tdst.get_buffer();
for (y = 0; y < tsrc.get_height() && (!breaked); y++) {
@@ -72,7 +72,7 @@ void GlareStreaksOperation::generate_glare(float *data,
}
float *sourcebuffer = tsrc.get_buffer();
- float factor = 1.0f / (float)(6 - settings->iter);
+ float factor = 1.0f / float(6 - settings->iter);
for (int i = 0; i < size4; i += 4) {
madd_v3_v3fl(&data[i], &sourcebuffer[i], factor);
data[i + 3] = 1.0f;
diff --git a/source/blender/compositor/operations/COM_ImageOperation.cc b/source/blender/compositor/operations/COM_ImageOperation.cc
index a9ab414670f..e1ac5e42be3 100644
--- a/source/blender/compositor/operations/COM_ImageOperation.cc
+++ b/source/blender/compositor/operations/COM_ImageOperation.cc
@@ -90,7 +90,7 @@ void BaseImageOperation::deinit_execution()
}
}
-void BaseImageOperation::determine_canvas(const rcti &UNUSED(preferred_area), rcti &r_area)
+void BaseImageOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area)
{
ImBuf *stackbuf = get_im_buf();
@@ -120,7 +120,7 @@ static void sample_image_at_location(
}
}
else {
- unsigned char byte_color[4];
+ uchar byte_color[4];
switch (sampler) {
case PixelSampler::Nearest:
nearest_interpolation_color(ibuf, byte_color, nullptr, x, y);
@@ -155,7 +155,7 @@ void ImageOperation::execute_pixel_sampled(float output[4], float x, float y, Pi
void ImageOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
output->copy_from(buffer_, area, true);
}
@@ -179,7 +179,7 @@ void ImageAlphaOperation::execute_pixel_sampled(float output[4],
void ImageAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
output->copy_from(buffer_, area, 3, COM_DATA_TYPE_VALUE_CHANNELS, 0);
}
@@ -205,7 +205,7 @@ void ImageDepthOperation::execute_pixel_sampled(float output[4],
void ImageDepthOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
if (depth_buffer_) {
output->copy_from(depth_buffer_, area);
diff --git a/source/blender/compositor/operations/COM_InpaintOperation.cc b/source/blender/compositor/operations/COM_InpaintOperation.cc
index 12533c26a53..a2e02e9f045 100644
--- a/source/blender/compositor/operations/COM_InpaintOperation.cc
+++ b/source/blender/compositor/operations/COM_InpaintOperation.cc
@@ -267,7 +267,7 @@ bool InpaintSimpleOperation::determine_depending_area_of_interest(
}
void InpaintSimpleOperation::get_area_of_interest(const int input_idx,
- const rcti &UNUSED(output_area),
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
BLI_assert(input_idx == 0);
diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.cc b/source/blender/compositor/operations/COM_KeyingBlurOperation.cc
index 71699f23a4b..a63789f06c3 100644
--- a/source/blender/compositor/operations/COM_KeyingBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.cc
@@ -48,7 +48,7 @@ void KeyingBlurOperation::execute_pixel(float output[4], int x, int y, void *dat
}
}
- average /= (float)count;
+ average /= float(count);
output[0] = average;
}
@@ -75,7 +75,7 @@ bool KeyingBlurOperation::determine_depending_area_of_interest(rcti *input,
return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output);
}
-void KeyingBlurOperation::get_area_of_interest(const int UNUSED(input_idx),
+void KeyingBlurOperation::get_area_of_interest(const int /*input_idx*/,
const rcti &output_area,
rcti &r_input_area)
{
diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.cc b/source/blender/compositor/operations/COM_KeyingClipOperation.cc
index bb951aaa938..2cbdfaa6a01 100644
--- a/source/blender/compositor/operations/COM_KeyingClipOperation.cc
+++ b/source/blender/compositor/operations/COM_KeyingClipOperation.cc
@@ -47,7 +47,7 @@ void KeyingClipOperation::execute_pixel(float output[4], int x, int y, void *dat
end_y = min_ff(y + delta - 1, buffer_height - 1);
int count = 0, total_count = (end_x - start_x + 1) * (end_y - start_y + 1) - 1;
- int threshold_count = ceil((float)total_count * 0.9f);
+ int threshold_count = ceil(float(total_count) * 0.9f);
if (delta == 0) {
ok = true;
@@ -147,7 +147,7 @@ void KeyingClipOperation::update_memory_buffer_partial(MemoryBuffer *output,
const int y_len = end_y - start_y;
const int total_count = x_len * y_len - 1;
- const int threshold_count = ceil((float)total_count * 0.9f);
+ const int threshold_count = ceil(float(total_count) * 0.9f);
bool ok = false;
if (delta == 0) {
ok = true;
diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cc b/source/blender/compositor/operations/COM_KeyingScreenOperation.cc
index 0db9b7e6a04..5c5bf5534a7 100644
--- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cc
+++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cc
@@ -150,11 +150,11 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::build_voronoi_t
add_v3_v3(site->color, &pattern_ibuf->rect_float[4 * j]);
}
else {
- unsigned char *rrgb = (unsigned char *)pattern_ibuf->rect;
+ uchar *rrgb = (uchar *)pattern_ibuf->rect;
- site->color[0] += srgb_to_linearrgb((float)rrgb[4 * j + 0] / 255.0f);
- site->color[1] += srgb_to_linearrgb((float)rrgb[4 * j + 1] / 255.0f);
- site->color[2] += srgb_to_linearrgb((float)rrgb[4 * j + 2] / 255.0f);
+ site->color[0] += srgb_to_linearrgb(float(rrgb[4 * j + 0]) / 255.0f);
+ site->color[1] += srgb_to_linearrgb(float(rrgb[4 * j + 1]) / 255.0f);
+ site->color[2] += srgb_to_linearrgb(float(rrgb[4 * j + 2]) / 255.0f);
}
}
@@ -204,11 +204,11 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::build_voronoi_t
minmax_v2v2_v2(min, max, b->co);
minmax_v2v2_v2(min, max, c->co);
- rect->xmin = (int)min[0];
- rect->ymin = (int)min[1];
+ rect->xmin = int(min[0]);
+ rect->ymin = int(min[1]);
- rect->xmax = (int)max[0] + 1;
- rect->ymax = (int)max[1] + 1;
+ rect->xmax = int(max[0]) + 1;
+ rect->ymax = int(max[1]) + 1;
}
}
@@ -311,7 +311,7 @@ void KeyingScreenOperation::execute_pixel(float output[4], int x, int y, void *d
TriangulationData *triangulation = cached_triangulation_;
TileData *tile_data = (TileData *)data;
int i;
- float co[2] = {(float)x, (float)y};
+ float co[2] = {float(x), float(y)};
for (i = 0; i < tile_data->triangles_total; i++) {
int triangle_idx = tile_data->triangles[i];
@@ -356,7 +356,7 @@ void KeyingScreenOperation::update_memory_buffer_partial(MemoryBuffer *output,
for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
copy_v4_v4(it.out, COM_COLOR_BLACK);
- const float co[2] = {(float)it.x, (float)it.y};
+ const float co[2] = {float(it.x), float(it.y)};
for (int i = 0; i < num_triangles; i++) {
const int triangle_idx = triangles[i];
const rcti *rect = &triangulation->triangles_AABB[triangle_idx];
diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cc b/source/blender/compositor/operations/COM_MapUVOperation.cc
index 40f91a04134..c300508268e 100644
--- a/source/blender/compositor/operations/COM_MapUVOperation.cc
+++ b/source/blender/compositor/operations/COM_MapUVOperation.cc
@@ -124,7 +124,7 @@ void MapUVOperation::pixel_transform(const float xy[2],
num++;
}
if (num > 0) {
- float numinv = 1.0f / (float)num;
+ float numinv = 1.0f / float(num);
r_deriv[0][0] *= numinv;
r_deriv[1][0] *= numinv;
}
@@ -141,7 +141,7 @@ void MapUVOperation::pixel_transform(const float xy[2],
num++;
}
if (num > 0) {
- float numinv = 1.0f / (float)num;
+ float numinv = 1.0f / float(num);
r_deriv[0][1] *= numinv;
r_deriv[1][1] *= numinv;
}
@@ -201,8 +201,8 @@ void MapUVOperation::get_area_of_interest(const int input_idx,
}
}
-void MapUVOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
+void MapUVOperation::update_memory_buffer_started(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
const MemoryBuffer *uv_input = inputs[UV_INPUT_INDEX];
@@ -217,7 +217,7 @@ void MapUVOperation::update_memory_buffer_partial(MemoryBuffer *output,
{
const MemoryBuffer *input_image = inputs[IMAGE_INPUT_INDEX];
for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
- float xy[2] = {(float)it.x, (float)it.y};
+ float xy[2] = {float(it.x), float(it.y)};
float uv[2];
float deriv[2][2];
float alpha;
diff --git a/source/blender/compositor/operations/COM_MaskOperation.cc b/source/blender/compositor/operations/COM_MaskOperation.cc
index 29d0c0c2b9c..53f59f831db 100644
--- a/source/blender/compositor/operations/COM_MaskOperation.cc
+++ b/source/blender/compositor/operations/COM_MaskOperation.cc
@@ -33,7 +33,7 @@ void MaskOperation::init_execution()
}
else {
/* make a throw away copy of the mask */
- const float frame = (float)frame_number_ - frame_shutter_;
+ const float frame = float(frame_number_) - frame_shutter_;
const float frame_step = (frame_shutter_ * 2.0f) / raster_mask_handle_tot_;
float frame_iter = frame;
@@ -52,7 +52,7 @@ void MaskOperation::init_execution()
}
}
- for (unsigned int i = 0; i < raster_mask_handle_tot_; i++) {
+ for (uint i = 0; i < raster_mask_handle_tot_; i++) {
raster_mask_handles_[i] = BKE_maskrasterize_handle_new();
/* re-eval frame info */
@@ -76,7 +76,7 @@ void MaskOperation::init_execution()
void MaskOperation::deinit_execution()
{
- for (unsigned int i = 0; i < raster_mask_handle_tot_; i++) {
+ for (uint i = 0; i < raster_mask_handle_tot_; i++) {
if (raster_mask_handles_[i]) {
BKE_maskrasterize_handle_free(raster_mask_handles_[i]);
raster_mask_handles_[i] = nullptr;
@@ -118,7 +118,7 @@ void MaskOperation::execute_pixel_sampled(float output[4],
/* In case loop below fails. */
output[0] = 0.0f;
- for (unsigned int i = 0; i < raster_mask_handle_tot_; i++) {
+ for (uint i = 0; i < raster_mask_handle_tot_; i++) {
if (raster_mask_handles_[i]) {
output[0] += BKE_maskrasterize_handle_sample(raster_mask_handles_[i], xy);
}
@@ -131,7 +131,7 @@ void MaskOperation::execute_pixel_sampled(float output[4],
void MaskOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
Vector<MaskRasterHandle *> handles = get_non_null_handles();
if (handles.size() == 0) {
diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cc b/source/blender/compositor/operations/COM_MovieClipOperation.cc
index b62d972e807..bbc762bf667 100644
--- a/source/blender/compositor/operations/COM_MovieClipOperation.cc
+++ b/source/blender/compositor/operations/COM_MovieClipOperation.cc
@@ -53,7 +53,7 @@ void MovieClipBaseOperation::deinit_execution()
}
}
-void MovieClipBaseOperation::determine_canvas(const rcti &UNUSED(preferred_area), rcti &r_area)
+void MovieClipBaseOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area)
{
r_area = COM_AREA_NONE;
if (movie_clip_) {
@@ -94,7 +94,7 @@ void MovieClipBaseOperation::execute_pixel_sampled(float output[4],
void MovieClipBaseOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
if (movie_clip_buffer_) {
output->copy_from(movie_clip_buffer_, area);
@@ -126,7 +126,7 @@ void MovieClipAlphaOperation::execute_pixel_sampled(float output[4],
void MovieClipAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
if (movie_clip_buffer_) {
output->copy_from(movie_clip_buffer_, area, 3, COM_DATA_TYPE_VALUE_CHANNELS, 0);
diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.cc b/source/blender/compositor/operations/COM_MovieDistortionOperation.cc
index ea3aad20792..b89a48f2a39 100644
--- a/source/blender/compositor/operations/COM_MovieDistortionOperation.cc
+++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.cc
@@ -81,10 +81,10 @@ void MovieDistortionOperation::execute_pixel_sampled(float output[4],
if (distortion_ != nullptr) {
/* float overscan = 0.0f; */
const float pixel_aspect = pixel_aspect_;
- const float w = (float)this->get_width() /* / (1 + overscan) */;
- const float h = (float)this->get_height() /* / (1 + overscan) */;
- const float aspx = w / (float)calibration_width_;
- const float aspy = h / (float)calibration_height_;
+ const float w = float(this->get_width()) /* / (1 + overscan) */;
+ const float h = float(this->get_height()) /* / (1 + overscan) */;
+ const float aspx = w / float(calibration_width_);
+ const float aspy = h / float(calibration_height_);
float in[2];
float out[2];
@@ -143,10 +143,10 @@ void MovieDistortionOperation::update_memory_buffer_partial(MemoryBuffer *output
/* `float overscan = 0.0f;` */
const float pixel_aspect = pixel_aspect_;
- const float w = (float)this->get_width() /* `/ (1 + overscan)` */;
- const float h = (float)this->get_height() /* `/ (1 + overscan)` */;
- const float aspx = w / (float)calibration_width_;
- const float aspy = h / (float)calibration_height_;
+ const float w = float(this->get_width()) /* `/ (1 + overscan)` */;
+ const float h = float(this->get_height()) /* `/ (1 + overscan)` */;
+ const float aspx = w / float(calibration_width_);
+ const float aspy = h / float(calibration_height_);
float xy[2];
float distorted_xy[2];
for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cc b/source/blender/compositor/operations/COM_MultilayerImageOperation.cc
index 11f80c16c2f..9a825939deb 100644
--- a/source/blender/compositor/operations/COM_MultilayerImageOperation.cc
+++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.cc
@@ -37,7 +37,7 @@ ImBuf *MultilayerBaseOperation::get_im_buf()
void MultilayerBaseOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
output->copy_from(buffer_, area);
}
@@ -93,8 +93,7 @@ void MultilayerColorOperation::execute_pixel_sampled(float output[4],
else {
int yi = y;
int xi = x;
- if (xi < 0 || yi < 0 || (unsigned int)xi >= this->get_width() ||
- (unsigned int)yi >= this->get_height()) {
+ if (xi < 0 || yi < 0 || uint(xi) >= this->get_width() || uint(yi) >= this->get_height()) {
zero_v4(output);
}
else {
@@ -116,8 +115,7 @@ void MultilayerValueOperation::execute_pixel_sampled(float output[4],
else {
int yi = y;
int xi = x;
- if (xi < 0 || yi < 0 || (unsigned int)xi >= this->get_width() ||
- (unsigned int)yi >= this->get_height()) {
+ if (xi < 0 || yi < 0 || uint(xi) >= this->get_width() || uint(yi) >= this->get_height()) {
output[0] = 0.0f;
}
else {
@@ -138,8 +136,7 @@ void MultilayerVectorOperation::execute_pixel_sampled(float output[4],
else {
int yi = y;
int xi = x;
- if (xi < 0 || yi < 0 || (unsigned int)xi >= this->get_width() ||
- (unsigned int)yi >= this->get_height()) {
+ if (xi < 0 || yi < 0 || uint(xi) >= this->get_width() || uint(yi) >= this->get_height()) {
output[0] = 0.0f;
}
else {
diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.cc b/source/blender/compositor/operations/COM_NormalizeOperation.cc
index 1131fc28439..b408964c35f 100644
--- a/source/blender/compositor/operations/COM_NormalizeOperation.cc
+++ b/source/blender/compositor/operations/COM_NormalizeOperation.cc
@@ -114,15 +114,15 @@ void NormalizeOperation::deinitialize_tile_data(rcti * /*rect*/, void * /*data*/
/* pass */
}
-void NormalizeOperation::get_area_of_interest(const int UNUSED(input_idx),
- const rcti &UNUSED(output_area),
+void NormalizeOperation::get_area_of_interest(const int /*input_idx*/,
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
r_input_area = get_input_operation(0)->get_canvas();
}
-void NormalizeOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
+void NormalizeOperation::update_memory_buffer_started(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
if (cached_instance_ == nullptr) {
diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc
index 760ed94f882..7650746e3ed 100644
--- a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc
+++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc
@@ -74,8 +74,8 @@ void *OutputOpenExrSingleLayerMultiViewOperation::get_handle(const char *filenam
void OutputOpenExrSingleLayerMultiViewOperation::deinit_execution()
{
- unsigned int width = this->get_width();
- unsigned int height = this->get_height();
+ uint width = this->get_width();
+ uint height = this->get_height();
if (width != 0 && height != 0) {
void *exrhandle;
@@ -132,8 +132,8 @@ OutputOpenExrMultiLayerMultiViewOperation::OutputOpenExrMultiLayerMultiViewOpera
void *OutputOpenExrMultiLayerMultiViewOperation::get_handle(const char *filename)
{
- unsigned int width = this->get_width();
- unsigned int height = this->get_height();
+ uint width = this->get_width();
+ uint height = this->get_height();
if (width != 0 && height != 0) {
@@ -158,7 +158,7 @@ void *OutputOpenExrMultiLayerMultiViewOperation::get_handle(const char *filename
IMB_exr_add_view(exrhandle, srv->name);
- for (unsigned int i = 0; i < layers_.size(); i++) {
+ for (uint i = 0; i < layers_.size(); i++) {
add_exr_channels(exrhandle,
layers_[i].name,
layers_[i].datatype,
@@ -189,8 +189,8 @@ void *OutputOpenExrMultiLayerMultiViewOperation::get_handle(const char *filename
void OutputOpenExrMultiLayerMultiViewOperation::deinit_execution()
{
- unsigned int width = this->get_width();
- unsigned int height = this->get_height();
+ uint width = this->get_width();
+ uint height = this->get_height();
if (width != 0 && height != 0) {
void *exrhandle;
@@ -207,7 +207,7 @@ void OutputOpenExrMultiLayerMultiViewOperation::deinit_execution()
exrhandle = this->get_handle(filename);
- for (unsigned int i = 0; i < layers_.size(); i++) {
+ for (uint i = 0; i < layers_.size(); i++) {
add_exr_channels(exrhandle,
layers_[i].name,
layers_[i].datatype,
@@ -217,7 +217,7 @@ void OutputOpenExrMultiLayerMultiViewOperation::deinit_execution()
layers_[i].output_buffer);
}
- for (unsigned int i = 0; i < layers_.size(); i++) {
+ for (uint i = 0; i < layers_.size(); i++) {
/* memory can only be freed after we write all views to the file */
layers_[i].output_buffer = nullptr;
layers_[i].image_input = nullptr;
@@ -228,7 +228,7 @@ void OutputOpenExrMultiLayerMultiViewOperation::deinit_execution()
IMB_exr_write_channels(exrhandle);
/* free buffer memory for all the views */
- for (unsigned int i = 0; i < layers_.size(); i++) {
+ for (uint i = 0; i < layers_.size(); i++) {
free_exr_channels(exrhandle, rd_, layers_[i].name, layers_[i].datatype);
}
@@ -284,8 +284,8 @@ void *OutputStereoOperation::get_handle(const char *filename)
void OutputStereoOperation::deinit_execution()
{
- unsigned int width = this->get_width();
- unsigned int height = this->get_height();
+ uint width = this->get_width();
+ uint height = this->get_height();
if (width != 0 && height != 0) {
void *exrhandle;
diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h
index e36999e5cf1..70773c1a559 100644
--- a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h
+++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h
@@ -31,7 +31,7 @@ class OutputOpenExrSingleLayerMultiViewOperation : public OutputSingleLayerOpera
void deinit_execution() override;
};
-/* Writes inputs into OpenEXR multilayer channels. */
+/** Writes inputs into OpenEXR multi-layer channels. */
class OutputOpenExrMultiLayerMultiViewOperation : public OutputOpenExrMultiLayerOperation {
private:
public:
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cc b/source/blender/compositor/operations/COM_OutputFileOperation.cc
index 1d22f3e8cd2..711ea787c41 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.cc
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.cc
@@ -150,7 +150,7 @@ int get_datatype_size(DataType datatype)
}
}
-static float *init_buffer(unsigned int width, unsigned int height, DataType datatype)
+static float *init_buffer(uint width, uint height, DataType datatype)
{
/* When initializing the tree during initial load the width and height can be zero. */
if (width != 0 && height != 0) {
@@ -165,7 +165,7 @@ static void write_buffer_rect(rcti *rect,
const bNodeTree *tree,
SocketReader *reader,
float *buffer,
- unsigned int width,
+ uint width,
DataType datatype)
{
float color[4];
@@ -242,7 +242,7 @@ void OutputSingleLayerOperation::init_execution()
output_buffer_ = init_buffer(this->get_width(), this->get_height(), datatype_);
}
-void OutputSingleLayerOperation::execute_region(rcti *rect, unsigned int /*tile_number*/)
+void OutputSingleLayerOperation::execute_region(rcti *rect, uint /*tile_number*/)
{
write_buffer_rect(rect, tree_, image_input_, output_buffer_, this->get_width(), datatype_);
}
@@ -287,7 +287,7 @@ void OutputSingleLayerOperation::deinit_execution()
image_input_ = nullptr;
}
-void OutputSingleLayerOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output),
+void OutputSingleLayerOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
@@ -369,7 +369,7 @@ StampData *OutputOpenExrMultiLayerOperation::create_stamp_data() const
void OutputOpenExrMultiLayerOperation::init_execution()
{
- for (unsigned int i = 0; i < layers_.size(); i++) {
+ for (uint i = 0; i < layers_.size(); i++) {
if (layers_[i].use_layer) {
SocketReader *reader = get_input_socket_reader(i);
layers_[i].image_input = reader;
@@ -379,9 +379,9 @@ void OutputOpenExrMultiLayerOperation::init_execution()
}
}
-void OutputOpenExrMultiLayerOperation::execute_region(rcti *rect, unsigned int /*tile_number*/)
+void OutputOpenExrMultiLayerOperation::execute_region(rcti *rect, uint /*tile_number*/)
{
- for (unsigned int i = 0; i < layers_.size(); i++) {
+ for (uint i = 0; i < layers_.size(); i++) {
OutputOpenExrLayer &layer = layers_[i];
if (layer.image_input) {
write_buffer_rect(
@@ -392,8 +392,8 @@ void OutputOpenExrMultiLayerOperation::execute_region(rcti *rect, unsigned int /
void OutputOpenExrMultiLayerOperation::deinit_execution()
{
- unsigned int width = this->get_width();
- unsigned int height = this->get_height();
+ uint width = this->get_width();
+ uint height = this->get_height();
if (width != 0 && height != 0) {
char filename[FILE_MAX];
const char *suffix;
@@ -410,7 +410,7 @@ void OutputOpenExrMultiLayerOperation::deinit_execution()
suffix);
BLI_make_existing_file(filename);
- for (unsigned int i = 0; i < layers_.size(); i++) {
+ for (uint i = 0; i < layers_.size(); i++) {
OutputOpenExrLayer &layer = layers_[i];
if (!layer.image_input) {
continue; /* skip unconnected sockets */
@@ -437,7 +437,7 @@ void OutputOpenExrMultiLayerOperation::deinit_execution()
}
IMB_exr_close(exrhandle);
- for (unsigned int i = 0; i < layers_.size(); i++) {
+ for (uint i = 0; i < layers_.size(); i++) {
if (layers_[i].output_buffer) {
MEM_freeN(layers_[i].output_buffer);
layers_[i].output_buffer = nullptr;
@@ -449,7 +449,7 @@ void OutputOpenExrMultiLayerOperation::deinit_execution()
}
}
-void OutputOpenExrMultiLayerOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output),
+void OutputOpenExrMultiLayerOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.h b/source/blender/compositor/operations/COM_OutputFileOperation.h
index df1d68838d9..716bede8035 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.h
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.h
@@ -71,7 +71,7 @@ struct OutputOpenExrLayer {
SocketReader *image_input;
};
-/* Writes inputs into OpenEXR multilayer channels. */
+/* Writes inputs into OpenEXR multi-layer channels. */
class OutputOpenExrMultiLayerOperation : public MultiThreadedOperation {
protected:
const Scene *scene_;
diff --git a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc
index 006f1f919ba..fcd37f2a179 100644
--- a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc
+++ b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc
@@ -195,8 +195,8 @@ void PlaneCornerPinMaskOperation::determine_canvas(const rcti &preferred_area, r
r_area = preferred_area;
}
-void PlaneCornerPinMaskOperation::get_area_of_interest(const int UNUSED(input_idx),
- const rcti &UNUSED(output_area),
+void PlaneCornerPinMaskOperation::get_area_of_interest(const int /*input_idx*/,
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
/* All corner inputs are used as constants. */
diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc
index 9c19f55e04f..59e924311e3 100644
--- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc
+++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc
@@ -82,7 +82,7 @@ void PlaneDistortWarpImageOperation::calculate_corners(const float corners[4][2]
}
float frame_corners[4][2] = {
- {0.0f, 0.0f}, {(float)width, 0.0f}, {(float)width, (float)height}, {0.0f, (float)height}};
+ {0.0f, 0.0f}, {float(width), 0.0f}, {float(width), float(height)}, {0.0f, float(height)}};
BKE_tracking_homography_between_two_quads(
sample_data->frame_space_corners, frame_corners, sample_data->perspective_matrix);
}
@@ -116,7 +116,7 @@ void PlaneDistortWarpImageOperation::execute_pixel_sampled(float output[4],
pixel_reader_->read_filtered(color, uv[0], uv[1], deriv[0], deriv[1]);
add_v4_v4(output, color);
}
- mul_v4_fl(output, 1.0f / (float)motion_blur_samples_);
+ mul_v4_fl(output, 1.0f / float(motion_blur_samples_));
}
}
@@ -143,7 +143,7 @@ void PlaneDistortWarpImageOperation::update_memory_buffer_partial(MemoryBuffer *
input_img->read_elem_filtered(uv[0], uv[1], deriv[0], deriv[1], color);
add_v4_v4(it.out, color);
}
- mul_v4_fl(it.out, 1.0f / (float)motion_blur_samples_);
+ mul_v4_fl(it.out, 1.0f / float(motion_blur_samples_));
}
}
}
@@ -258,7 +258,7 @@ void PlaneDistortMaskOperation::execute_pixel_sampled(float output[4],
inside_counter++;
}
}
- output[0] = (float)inside_counter / osa_;
+ output[0] = float(inside_counter) / osa_;
}
else {
for (int motion_sample = 0; motion_sample < motion_blur_samples_; motion_sample++) {
@@ -278,13 +278,13 @@ void PlaneDistortMaskOperation::execute_pixel_sampled(float output[4],
}
}
}
- output[0] = (float)inside_counter / (osa_ * motion_blur_samples_);
+ output[0] = float(inside_counter) / (osa_ * motion_blur_samples_);
}
}
void PlaneDistortMaskOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
int inside_count = 0;
@@ -292,7 +292,7 @@ void PlaneDistortMaskOperation::update_memory_buffer_partial(MemoryBuffer *outpu
MotionSample &sample = samples_[motion_sample];
inside_count += get_jitter_samples_inside_count(it.x, it.y, sample);
}
- *it.out = (float)inside_count / (osa_ * motion_blur_samples_);
+ *it.out = float(inside_count) / (osa_ * motion_blur_samples_);
}
}
diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.cc b/source/blender/compositor/operations/COM_PlaneTrackOperation.cc
index 7d515284737..f5922d54fc9 100644
--- a/source/blender/compositor/operations/COM_PlaneTrackOperation.cc
+++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.cc
@@ -28,7 +28,7 @@ void PlaneTrackCommon::read_and_calculate_corners(PlaneDistortBaseOperation *dis
distort_op->calculate_corners(corners, true, 0);
}
else {
- const float frame = (float)framenumber_ - distort_op->motion_blur_shutter_;
+ const float frame = float(framenumber_) - distort_op->motion_blur_shutter_;
const float frame_step = (distort_op->motion_blur_shutter_ * 2.0f) /
distort_op->motion_blur_samples_;
float frame_iter = frame;
diff --git a/source/blender/compositor/operations/COM_PreviewOperation.cc b/source/blender/compositor/operations/COM_PreviewOperation.cc
index dbc544896e3..2b9fc7ddc8c 100644
--- a/source/blender/compositor/operations/COM_PreviewOperation.cc
+++ b/source/blender/compositor/operations/COM_PreviewOperation.cc
@@ -10,8 +10,8 @@ namespace blender::compositor {
PreviewOperation::PreviewOperation(const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings,
- const unsigned int default_width,
- const unsigned int default_height)
+ const uint default_width,
+ const uint default_height)
{
this->add_input_socket(DataType::Color, ResizeMode::Align);
@@ -39,14 +39,13 @@ void PreviewOperation::init_execution()
{
input_ = get_input_socket_reader(0);
- if (this->get_width() == (unsigned int)preview_->xsize &&
- this->get_height() == (unsigned int)preview_->ysize) {
+ if (this->get_width() == uint(preview_->xsize) && this->get_height() == uint(preview_->ysize)) {
output_buffer_ = preview_->rect;
}
if (output_buffer_ == nullptr) {
- output_buffer_ = (unsigned char *)MEM_callocN(
- sizeof(unsigned char) * 4 * get_width() * get_height(), "PreviewOperation");
+ output_buffer_ = (uchar *)MEM_callocN(sizeof(uchar) * 4 * get_width() * get_height(),
+ "PreviewOperation");
if (preview_->rect) {
MEM_freeN(preview_->rect);
}
@@ -62,7 +61,7 @@ void PreviewOperation::deinit_execution()
input_ = nullptr;
}
-void PreviewOperation::execute_region(rcti *rect, unsigned int /*tile_number*/)
+void PreviewOperation::execute_region(rcti *rect, uint /*tile_number*/)
{
int offset;
float color[4];
@@ -102,7 +101,7 @@ bool PreviewOperation::determine_depending_area_of_interest(rcti *input,
return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output);
}
-void PreviewOperation::determine_canvas(const rcti &UNUSED(preferred_area), rcti &r_area)
+void PreviewOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area)
{
/* Use default preview resolution as preferred ensuring it has size so that
* generated inputs (which don't have resolution on their own) are displayed */
@@ -125,10 +124,10 @@ void PreviewOperation::determine_canvas(const rcti &UNUSED(preferred_area), rcti
divider_ = 0.0f;
if (width > 0 && height > 0) {
if (width > height) {
- divider_ = (float)COM_PREVIEW_SIZE / (width);
+ divider_ = float(COM_PREVIEW_SIZE) / (width);
}
else {
- divider_ = (float)COM_PREVIEW_SIZE / (height);
+ divider_ = float(COM_PREVIEW_SIZE) / (height);
}
}
width = width * divider_;
@@ -155,7 +154,7 @@ void PreviewOperation::get_area_of_interest(const int input_idx,
r_input_area.ymax = output_area.ymax / divider_;
}
-void PreviewOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output),
+void PreviewOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.cc b/source/blender/compositor/operations/COM_ReadBufferOperation.cc
index 81f046af1b9..224d2ea0f41 100644
--- a/source/blender/compositor/operations/COM_ReadBufferOperation.cc
+++ b/source/blender/compositor/operations/COM_ReadBufferOperation.cc
@@ -31,8 +31,7 @@ void ReadBufferOperation::determine_canvas(const rcti &preferred_area, rcti &r_a
/** \todo may not occur! But does with blur node. */
if (memory_proxy_->get_executor()) {
- uint resolution[2] = {static_cast<uint>(BLI_rcti_size_x(&r_area)),
- static_cast<uint>(BLI_rcti_size_y(&r_area))};
+ uint resolution[2] = {uint(BLI_rcti_size_x(&r_area)), uint(BLI_rcti_size_y(&r_area))};
memory_proxy_->get_executor()->set_resolution(resolution);
}
diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.cc b/source/blender/compositor/operations/COM_RenderLayersProg.cc
index 40f2187b27b..d95ee2a5e1a 100644
--- a/source/blender/compositor/operations/COM_RenderLayersProg.cc
+++ b/source/blender/compositor/operations/COM_RenderLayersProg.cc
@@ -52,7 +52,7 @@ void RenderLayersProg::init_execution()
void RenderLayersProg::do_interpolation(float output[4], float x, float y, PixelSampler sampler)
{
- unsigned int offset;
+ uint offset;
int width = this->get_width(), height = this->get_height();
int ix = x, iy = y;
@@ -169,7 +169,7 @@ void RenderLayersProg::deinit_execution()
}
}
-void RenderLayersProg::determine_canvas(const rcti &UNUSED(preferred_area), rcti &r_area)
+void RenderLayersProg::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area)
{
Scene *sce = this->get_scene();
Render *re = (sce) ? RE_GetSceneRender(sce) : nullptr;
@@ -235,7 +235,7 @@ std::unique_ptr<MetaData> RenderLayersProg::get_meta_data()
void RenderLayersProg::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
BLI_assert(output->get_num_channels() >= elementsize_);
if (layer_buffer_) {
@@ -266,7 +266,7 @@ void RenderLayersAOOperation::execute_pixel_sampled(float output[4],
void RenderLayersAOOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
BLI_assert(output->get_num_channels() == COM_DATA_TYPE_COLOR_CHANNELS);
BLI_assert(elementsize_ == COM_DATA_TYPE_COLOR_CHANNELS);
@@ -300,7 +300,7 @@ void RenderLayersAlphaProg::execute_pixel_sampled(float output[4],
void RenderLayersAlphaProg::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
BLI_assert(output->get_num_channels() == COM_DATA_TYPE_VALUE_CHANNELS);
BLI_assert(elementsize_ == COM_DATA_TYPE_COLOR_CHANNELS);
@@ -323,19 +323,19 @@ void RenderLayersDepthProg::execute_pixel_sampled(float output[4],
int iy = y;
float *input_buffer = this->get_input_buffer();
- if (input_buffer == nullptr || ix < 0 || iy < 0 || ix >= (int)this->get_width() ||
- iy >= (int)this->get_height()) {
+ if (input_buffer == nullptr || ix < 0 || iy < 0 || ix >= int(this->get_width()) ||
+ iy >= int(this->get_height())) {
output[0] = 10e10f;
}
else {
- unsigned int offset = (iy * this->get_width() + ix);
+ uint offset = (iy * this->get_width() + ix);
output[0] = input_buffer[offset];
}
}
void RenderLayersDepthProg::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
BLI_assert(output->get_num_channels() == COM_DATA_TYPE_VALUE_CHANNELS);
BLI_assert(elementsize_ == COM_DATA_TYPE_VALUE_CHANNELS);
diff --git a/source/blender/compositor/operations/COM_RotateOperation.cc b/source/blender/compositor/operations/COM_RotateOperation.cc
index 79f8cf5fc51..b0854cace52 100644
--- a/source/blender/compositor/operations/COM_RotateOperation.cc
+++ b/source/blender/compositor/operations/COM_RotateOperation.cc
@@ -143,7 +143,7 @@ inline void RotateOperation::ensure_degree()
double rad;
if (do_degree2_rad_conversion_) {
- rad = DEG2RAD((double)degree[0]);
+ rad = DEG2RAD(double(degree[0]));
}
else {
rad = degree[0];
diff --git a/source/blender/compositor/operations/COM_SMAAOperation.cc b/source/blender/compositor/operations/COM_SMAAOperation.cc
index 261426b31e2..8f4ed844b9f 100644
--- a/source/blender/compositor/operations/COM_SMAAOperation.cc
+++ b/source/blender/compositor/operations/COM_SMAAOperation.cc
@@ -65,7 +65,7 @@ static void sample_bilinear_vertical(T *reader, int x, int y, float yoffset, flo
{
float iy = floorf(yoffset);
float fy = yoffset - iy;
- y += (int)iy;
+ y += int(iy);
float color00[4], color01[4];
@@ -83,7 +83,7 @@ static void sample_bilinear_horizontal(T *reader, int x, int y, float xoffset, f
{
float ix = floorf(xoffset);
float fx = xoffset - ix;
- x += (int)ix;
+ x += int(ix);
float color00[4], color10[4];
@@ -113,12 +113,12 @@ static inline const float *areatex_sample_internal(const float *areatex, int x,
static void area(int d1, int d2, int e1, int e2, float weights[2])
{
/* The areas texture is compressed quadratically: */
- float x = (float)(SMAA_AREATEX_MAX_DISTANCE * e1) + sqrtf((float)d1);
- float y = (float)(SMAA_AREATEX_MAX_DISTANCE * e2) + sqrtf((float)d2);
+ float x = float(SMAA_AREATEX_MAX_DISTANCE * e1) + sqrtf(float(d1));
+ float y = float(SMAA_AREATEX_MAX_DISTANCE * e2) + sqrtf(float(d2));
float ix = floorf(x), iy = floorf(y);
float fx = x - ix, fy = y - iy;
- int X = (int)ix, Y = (int)iy;
+ int X = int(ix), Y = int(iy);
const float *weights00 = areatex_sample_internal(areatex, X + 0, Y + 0);
const float *weights10 = areatex_sample_internal(areatex, X + 1, Y + 0);
@@ -196,7 +196,7 @@ bool SMAAEdgeDetectionOperation::determine_depending_area_of_interest(
return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output);
}
-void SMAAEdgeDetectionOperation::get_area_of_interest(const int UNUSED(input_idx),
+void SMAAEdgeDetectionOperation::get_area_of_interest(const int /*input_idx*/,
const rcti &output_area,
rcti &r_input_area)
{
@@ -404,7 +404,7 @@ void SMAABlendingWeightCalculationOperation::init_execution()
void SMAABlendingWeightCalculationOperation::set_corner_rounding(float rounding)
{
/* UI values are between 0 and 1 for simplicity but algorithm expects values between 0 and 100 */
- corner_rounding_ = static_cast<int>(scalenorm(0, 100, rounding));
+ corner_rounding_ = int(scalenorm(0, 100, rounding));
}
void SMAABlendingWeightCalculationOperation::execute_pixel(float output[4],
@@ -505,14 +505,14 @@ void SMAABlendingWeightCalculationOperation::execute_pixel(float output[4],
}
void SMAABlendingWeightCalculationOperation::update_memory_buffer_started(
- MemoryBuffer *UNUSED(output), const rcti &UNUSED(out_area), Span<MemoryBuffer *> inputs)
+ MemoryBuffer * /*output*/, const rcti & /*out_area*/, Span<MemoryBuffer *> inputs)
{
const MemoryBuffer *image = inputs[0];
sample_image_fn_ = [=](int x, int y, float *out) { image->read_elem_checked(x, y, out); };
}
void SMAABlendingWeightCalculationOperation::update_memory_buffer_partial(
- MemoryBuffer *output, const rcti &out_area, Span<MemoryBuffer *> UNUSED(inputs))
+ MemoryBuffer *output, const rcti &out_area, Span<MemoryBuffer *> /*inputs*/)
{
for (BuffersIterator<float> it = output->iterate_with({}, out_area); !it.is_end(); ++it) {
const int x = it.x;
@@ -631,7 +631,7 @@ bool SMAABlendingWeightCalculationOperation::determine_depending_area_of_interes
return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output);
}
-void SMAABlendingWeightCalculationOperation::get_area_of_interest(const int UNUSED(input_idx),
+void SMAABlendingWeightCalculationOperation::get_area_of_interest(const int /*input_idx*/,
const rcti &output_area,
rcti &r_input_area)
{
@@ -1123,7 +1123,7 @@ bool SMAANeighborhoodBlendingOperation::determine_depending_area_of_interest(
return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output);
}
-void SMAANeighborhoodBlendingOperation::get_area_of_interest(const int UNUSED(input_idx),
+void SMAANeighborhoodBlendingOperation::get_area_of_interest(const int /*input_idx*/,
const rcti &output_area,
rcti &r_input_area)
{
diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cc b/source/blender/compositor/operations/COM_ScaleOperation.cc
index 2a2aff31893..cc914239caf 100644
--- a/source/blender/compositor/operations/COM_ScaleOperation.cc
+++ b/source/blender/compositor/operations/COM_ScaleOperation.cc
@@ -16,7 +16,7 @@ namespace blender::compositor {
BaseScaleOperation::BaseScaleOperation()
{
#ifdef USE_FORCE_BILINEAR
- sampler_ = (int)PixelSampler::Bilinear;
+ sampler_ = int(PixelSampler::Bilinear);
#else
sampler_ = -1;
#endif
@@ -372,8 +372,8 @@ void ScaleFixedSizeOperation::init_data(const rcti &input_canvas)
{
const int input_width = BLI_rcti_size_x(&input_canvas);
const int input_height = BLI_rcti_size_y(&input_canvas);
- rel_x_ = input_width / (float)new_width_;
- rel_y_ = input_height / (float)new_height_;
+ rel_x_ = input_width / float(new_width_);
+ rel_y_ = input_height / float(new_height_);
/* *** all the options below are for a fairly special case - camera framing *** */
if (offset_x_ != 0.0f || offset_y_ != 0.0f) {
diff --git a/source/blender/compositor/operations/COM_ScaleOperation.h b/source/blender/compositor/operations/COM_ScaleOperation.h
index 4cd50f3ead3..ba291342e96 100644
--- a/source/blender/compositor/operations/COM_ScaleOperation.h
+++ b/source/blender/compositor/operations/COM_ScaleOperation.h
@@ -112,12 +112,12 @@ class ScaleRelativeOperation : public ScaleOperation {
rcti *output) override;
void execute_pixel_sampled(float output[4], float x, float y, PixelSampler sampler) override;
- float get_relative_scale_x_factor(float UNUSED(width)) override
+ float get_relative_scale_x_factor(float /*width*/) override
{
return 1.0f;
}
- float get_relative_scale_y_factor(float UNUSED(height)) override
+ float get_relative_scale_y_factor(float /*height*/) override
{
return 1.0f;
}
diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc
index 0fc5589a3df..a62977c3280 100644
--- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc
+++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc
@@ -40,8 +40,8 @@ void ScreenLensDistortionOperation::set_dispersion(float dispersion)
void ScreenLensDistortionOperation::init_data()
{
- cx_ = 0.5f * (float)get_width();
- cy_ = 0.5f * (float)get_height();
+ cx_ = 0.5f * float(get_width());
+ cy_ = 0.5f * float(get_height());
switch (execution_model_) {
case eExecutionModel::FullFrame: {
@@ -72,8 +72,8 @@ void ScreenLensDistortionOperation::init_execution()
input_program_ = this->get_input_socket_reader(0);
this->init_mutex();
- uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX);
- rng_seed ^= (uint)POINTER_AS_INT(input_program_);
+ uint rng_seed = uint(PIL_check_seconds_timer_i() & UINT_MAX);
+ rng_seed ^= uint(POINTER_AS_INT(input_program_));
rng_ = BLI_rng_new(rng_seed);
}
@@ -147,8 +147,8 @@ void ScreenLensDistortionOperation::accumulate(const MemoryBuffer *buffer,
float color[4];
float dsf = len_v2v2(delta[a], delta[b]) + 1.0f;
- int ds = jitter_ ? (dsf < 4.0f ? 2 : (int)sqrtf(dsf)) : (int)dsf;
- float sd = 1.0f / (float)ds;
+ int ds = jitter_ ? (dsf < 4.0f ? 2 : int(sqrtf(dsf))) : int(dsf);
+ float sd = 1.0f / float(ds);
float k4 = k4_[a];
float dk4 = dk4_[a];
@@ -178,7 +178,7 @@ void ScreenLensDistortionOperation::accumulate(const MemoryBuffer *buffer,
void ScreenLensDistortionOperation::execute_pixel(float output[4], int x, int y, void *data)
{
MemoryBuffer *buffer = (MemoryBuffer *)data;
- float xy[2] = {(float)x, (float)y};
+ float xy[2] = {float(x), float(y)};
float uv[2];
get_uv(xy, uv);
float uv_dot = len_squared_v2(uv);
@@ -196,13 +196,13 @@ void ScreenLensDistortionOperation::execute_pixel(float output[4], int x, int y,
accumulate(buffer, 1, 2, uv_dot, uv, delta, sum, count);
if (count[0]) {
- output[0] = 2.0f * sum[0] / (float)count[0];
+ output[0] = 2.0f * sum[0] / float(count[0]);
}
if (count[1]) {
- output[1] = 2.0f * sum[1] / (float)count[1];
+ output[1] = 2.0f * sum[1] / float(count[1]);
}
if (count[2]) {
- output[2] = 2.0f * sum[2] / (float)count[2];
+ output[2] = 2.0f * sum[2] / float(count[2]);
}
/* set alpha */
@@ -384,7 +384,7 @@ void ScreenLensDistortionOperation::determine_canvas(const rcti &preferred_area,
}
void ScreenLensDistortionOperation::get_area_of_interest(const int input_idx,
- const rcti &UNUSED(output_area),
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
if (input_idx != 0) {
@@ -485,7 +485,7 @@ void ScreenLensDistortionOperation::update_memory_buffer_partial(MemoryBuffer *o
{
const MemoryBuffer *input_image = inputs[0];
for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
- float xy[2] = {(float)it.x, (float)it.y};
+ float xy[2] = {float(it.x), float(it.y)};
float uv[2];
get_uv(xy, uv);
const float uv_dot = len_squared_v2(uv);
@@ -505,13 +505,13 @@ void ScreenLensDistortionOperation::update_memory_buffer_partial(MemoryBuffer *o
accumulate(input_image, 1, 2, uv_dot, uv, delta, sum, count);
if (count[0]) {
- it.out[0] = 2.0f * sum[0] / (float)count[0];
+ it.out[0] = 2.0f * sum[0] / float(count[0]);
}
if (count[1]) {
- it.out[1] = 2.0f * sum[1] / (float)count[1];
+ it.out[1] = 2.0f * sum[1] / float(count[1]);
}
if (count[2]) {
- it.out[2] = 2.0f * sum[2] / (float)count[2];
+ it.out[2] = 2.0f * sum[2] / float(count[2]);
}
/* Set alpha. */
diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.cc b/source/blender/compositor/operations/COM_SunBeamsOperation.cc
index 1628c0fa1f8..94674c8fd6c 100644
--- a/source/blender/compositor/operations/COM_SunBeamsOperation.cc
+++ b/source/blender/compositor/operations/COM_SunBeamsOperation.cc
@@ -52,18 +52,18 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator {
static inline void buffer_to_sector(const float source[2], float x, float y, float &u, float &v)
{
- int x0 = (int)source[0];
- int y0 = (int)source[1];
- x -= (float)x0;
- y -= (float)y0;
+ int x0 = int(source[0]);
+ int y0 = int(source[1]);
+ x -= float(x0);
+ y -= float(y0);
u = x * fxu + y * fyu;
v = x * fxv + y * fyv;
}
static inline void sector_to_buffer(const float source[2], int u, int v, int &x, int &y)
{
- int x0 = (int)source[0];
- int y0 = (int)source[1];
+ int x0 = int(source[0]);
+ int y0 = int(source[1]);
x = x0 + u * fxu + v * fxv;
y = y0 + u * fyu + v * fyv;
}
@@ -95,7 +95,7 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator {
buffer_to_sector(source, co[0], co[1], pu, pv);
/* line angle */
- double tan_phi = pv / (double)pu;
+ double tan_phi = pv / double(pu);
double dr = sqrt(tan_phi * tan_phi + 1.0);
double cos_phi = 1.0 / dr;
@@ -105,13 +105,13 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator {
v = umin * tan_phi;
dv = tan_phi;
- int start = (int)floorf(umax);
- int end = (int)ceilf(umin);
+ int start = int(floorf(umax));
+ int end = int(ceilf(umin));
num = end - start;
- sector_to_buffer(source, end, (int)ceilf(v), x, y);
+ sector_to_buffer(source, end, int(ceilf(v)), x, y);
- falloff_factor = dist_max > dist_min ? dr / (double)(dist_max - dist_min) : 0.0f;
+ falloff_factor = dist_max > dist_min ? dr / double(dist_max - dist_min) : 0.0f;
float *iter = input->get_buffer() + input->get_coords_offset(x, y);
return iter;
@@ -139,7 +139,7 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator {
zero_v4(output);
- if ((int)(co[0] - source[0]) == 0 && (int)(co[1] - source[1]) == 0) {
+ if (int(co[0] - source[0]) == 0 && int(co[1] - source[1]) == 0) {
copy_v4_v4(output, input->get_elem(source[0], source[1]));
return;
}
@@ -154,7 +154,7 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator {
float v_local = v - floorf(v);
for (int i = 0; i < num; i++) {
- float weight = 1.0f - (float)i * falloff_factor;
+ float weight = 1.0f - float(i) * falloff_factor;
weight *= weight;
/* range check, use last valid color when running beyond the image border */
@@ -195,7 +195,7 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator {
/* normalize */
if (num > 0) {
- mul_v4_fl(output, 1.0f / (float)num);
+ mul_v4_fl(output, 1.0f / float(num));
}
}
};
@@ -288,14 +288,14 @@ void *SunBeamsOperation::initialize_tile_data(rcti * /*rect*/)
void SunBeamsOperation::execute_pixel(float output[4], int x, int y, void *data)
{
- const float co[2] = {(float)x, (float)y};
+ const float co[2] = {float(x), float(y)};
accumulate_line((MemoryBuffer *)data, output, co, source_px_, 0.0f, ray_length_px_);
}
static void calc_ray_shift(rcti *rect, float x, float y, const float source[2], float ray_length)
{
- float co[2] = {(float)x, (float)y};
+ float co[2] = {float(x), float(y)};
float dir[2], dist;
/* move (x,y) vector toward the source by ray_length distance */
@@ -304,7 +304,7 @@ static void calc_ray_shift(rcti *rect, float x, float y, const float source[2],
mul_v2_fl(dir, min_ff(dist, ray_length));
sub_v2_v2(co, dir);
- int ico[2] = {(int)co[0], (int)co[1]};
+ int ico[2] = {int(co[0]), int(co[1])};
BLI_rcti_do_minmax_v(rect, ico);
}
diff --git a/source/blender/compositor/operations/COM_TonemapOperation.cc b/source/blender/compositor/operations/COM_TonemapOperation.cc
index 714625e483d..6f560eafc67 100644
--- a/source/blender/compositor/operations/COM_TonemapOperation.cc
+++ b/source/blender/compositor/operations/COM_TonemapOperation.cc
@@ -120,11 +120,11 @@ void *TonemapOperation::initialize_tile_data(rcti *rect)
}
data->lav = Lav * sc;
mul_v3_v3fl(data->cav, cav, sc);
- maxl = log((double)maxl + 1e-5);
- minl = log((double)minl + 1e-5);
+ maxl = log(double(maxl) + 1e-5);
+ minl = log(double(minl) + 1e-5);
avl = lsum * sc;
data->auto_key = (maxl > minl) ? ((maxl - avl) / (maxl - minl)) : 1.0f;
- float al = exp((double)avl);
+ float al = exp(double(avl));
data->al = (al == 0.0f) ? 0.0f : (data_->key / al);
data->igm = (data_->gamma == 0.0f) ? 1 : (1.0f / data_->gamma);
cached_instance_ = data;
@@ -139,7 +139,7 @@ void TonemapOperation::deinitialize_tile_data(rcti * /*rect*/, void * /*data*/)
}
void TonemapOperation::get_area_of_interest(const int input_idx,
- const rcti &UNUSED(output_area),
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
BLI_assert(input_idx == 0);
@@ -170,8 +170,8 @@ static Luminance calc_area_luminance(const MemoryBuffer *input, const rcti &area
return lum;
}
-void TonemapOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
+void TonemapOperation::update_memory_buffer_started(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
if (cached_instance_ == nullptr) {
@@ -193,11 +193,11 @@ void TonemapOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output)
AvgLogLum *avg = new AvgLogLum();
avg->lav = lum.sum / lum.num_pixels;
mul_v3_v3fl(avg->cav, lum.color_sum, 1.0f / lum.num_pixels);
- const float max_log = log((double)lum.max + 1e-5);
- const float min_log = log((double)lum.min + 1e-5);
+ const float max_log = log(double(lum.max) + 1e-5);
+ const float min_log = log(double(lum.min) + 1e-5);
const float avg_log = lum.log_sum / lum.num_pixels;
avg->auto_key = (max_log > min_log) ? ((max_log - avg_log) / (max_log - min_log)) : 1.0f;
- const float al = exp((double)avg_log);
+ const float al = exp(double(avg_log));
avg->al = (al == 0.0f) ? 0.0f : (data_->key / al);
avg->igm = (data_->gamma == 0.0f) ? 1 : (1.0f / data_->gamma);
cached_instance_ = avg;
diff --git a/source/blender/compositor/operations/COM_TonemapOperation.h b/source/blender/compositor/operations/COM_TonemapOperation.h
index 8071470b3f4..4e68d432985 100644
--- a/source/blender/compositor/operations/COM_TonemapOperation.h
+++ b/source/blender/compositor/operations/COM_TonemapOperation.h
@@ -21,7 +21,7 @@ typedef struct AvgLogLum {
} AvgLogLum;
/**
- * \brief base class of tonemap, implementing the simple tonemap
+ * \brief base class of tone-map, implementing the simple tone-map
* \ingroup operation
*/
class TonemapOperation : public MultiThreadedOperation {
@@ -32,7 +32,7 @@ class TonemapOperation : public MultiThreadedOperation {
SocketReader *image_reader_;
/**
- * \brief settings of the Tonemap
+ * \brief settings of the Tone-map
*/
const NodeTonemap *data_;
diff --git a/source/blender/compositor/operations/COM_TransformOperation.cc b/source/blender/compositor/operations/COM_TransformOperation.cc
index 36a4899ef53..0db018a3dc0 100644
--- a/source/blender/compositor/operations/COM_TransformOperation.cc
+++ b/source/blender/compositor/operations/COM_TransformOperation.cc
@@ -38,7 +38,7 @@ void TransformOperation::init_data()
translate_factor_y_;
const float degree = get_input_operation(DEGREE_INPUT_INDEX)->get_constant_value_default(0.0f);
- const double rad = convert_degree_to_rad_ ? DEG2RAD((double)degree) : degree;
+ const double rad = convert_degree_to_rad_ ? DEG2RAD(double(degree)) : degree;
rotate_cosine_ = cos(rad);
rotate_sine_ = sin(rad);
diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc
index d4365af4860..bf6ee64c73f 100644
--- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc
@@ -61,7 +61,7 @@ void *VariableSizeBokehBlurOperation::initialize_tile_data(rcti *rect)
const float max_dim = MAX2(this->get_width(), this->get_height());
const float scalar = do_size_scale_ ? (max_dim / 100.0f) : 1.0f;
- data->max_blur_scalar = (int)(data->size->get_max_value(rect2) * scalar);
+ data->max_blur_scalar = int(data->size->get_max_value(rect2) * scalar);
CLAMP(data->max_blur_scalar, 1.0f, max_blur_);
return data;
}
@@ -106,8 +106,8 @@ void VariableSizeBokehBlurOperation::execute_pixel(float output[4], int x, int y
#else
int minx = MAX2(x - max_blur_scalar, 0);
int miny = MAX2(y - max_blur_scalar, 0);
- int maxx = MIN2(x + max_blur_scalar, (int)get_width());
- int maxy = MIN2(y + max_blur_scalar, (int)get_height());
+ int maxx = MIN2(x + max_blur_scalar, int(get_width()));
+ int maxy = MIN2(y + max_blur_scalar, int(get_height()));
#endif
{
input_size_buffer->read_no_check(temp_size, x, y);
@@ -134,10 +134,10 @@ void VariableSizeBokehBlurOperation::execute_pixel(float output[4], int x, int y
float dx = nx - x;
if (size > fabsf(dx) && size > fabsf(dy)) {
float uv[2] = {
- (float)(COM_BLUR_BOKEH_PIXELS / 2) +
- (dx / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1),
- (float)(COM_BLUR_BOKEH_PIXELS / 2) +
- (dy / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1),
+ float(COM_BLUR_BOKEH_PIXELS / 2) +
+ (dx / size) * float((COM_BLUR_BOKEH_PIXELS / 2) - 1),
+ float(COM_BLUR_BOKEH_PIXELS / 2) +
+ (dy / size) * float((COM_BLUR_BOKEH_PIXELS / 2) - 1),
};
input_bokeh_buffer->read(bokeh, uv[0], uv[1]);
madd_v4_v4v4(color_accum, bokeh, &input_program_float_buffer[offset_color_nx_ny]);
@@ -185,7 +185,7 @@ void VariableSizeBokehBlurOperation::execute_opencl(
const float max_dim = MAX2(get_width(), get_height());
cl_float scalar = do_size_scale_ ? (max_dim / 100.0f) : 1.0f;
- max_blur = (cl_int)min_ff(size_memory_buffer->get_max_value() * scalar, (float)max_blur_);
+ max_blur = (cl_int)min_ff(size_memory_buffer->get_max_value() * scalar, float(max_blur_));
device->COM_cl_attach_memory_buffer_to_kernel_parameter(
defocus_kernel, 0, -1, cl_mem_to_clean_up, input_memory_buffers, input_program_);
@@ -358,10 +358,10 @@ static void blur_pixel(int x, int y, PixelData &p)
/* XXX: There is no way to ensure bokeh input is an actual bokeh with #COM_BLUR_BOKEH_PIXELS
* size, anything may be connected. Use the real input size and remove asserts? */
- const float u = (float)(COM_BLUR_BOKEH_PIXELS / 2) +
- (dx / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1);
- const float v = (float)(COM_BLUR_BOKEH_PIXELS / 2) +
- (dy / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1);
+ const float u = float(COM_BLUR_BOKEH_PIXELS / 2) +
+ (dx / size) * float((COM_BLUR_BOKEH_PIXELS / 2) - 1);
+ const float v = float(COM_BLUR_BOKEH_PIXELS / 2) +
+ (dy / size) * float((COM_BLUR_BOKEH_PIXELS / 2) - 1);
float bokeh[4];
p.bokeh_input->read_elem_checked(u, v, bokeh);
madd_v4_v4v4(p.color_accum, bokeh, color);
@@ -390,7 +390,7 @@ void VariableSizeBokehBlurOperation::update_memory_buffer_partial(MemoryBuffer *
const float max_dim = MAX2(this->get_width(), this->get_height());
p.scalar = do_size_scale_ ? (max_dim / 100.0f) : 1.0f;
- p.max_blur_scalar = static_cast<int>(max_size * p.scalar);
+ p.max_blur_scalar = int(max_size * p.scalar);
CLAMP(p.max_blur_scalar, 1, max_blur_);
for (BuffersIterator<float> it = output->iterate_with({p.image_input, p.size_input}, area);
@@ -510,8 +510,8 @@ void InverseSearchRadiusOperation::deinit_execution()
input_radius_ = nullptr;
}
-void InverseSearchRadiusOperation::determine_resolution(unsigned int resolution[2],
- unsigned int preferred_resolution[2])
+void InverseSearchRadiusOperation::determine_resolution(uint resolution[2],
+ uint preferred_resolution[2])
{
NodeOperation::determine_resolution(resolution, preferred_resolution);
resolution[0] = resolution[0] / DIVIDER;
diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cc b/source/blender/compositor/operations/COM_VectorBlurOperation.cc
index 71c61a6e588..1330557c06f 100644
--- a/source/blender/compositor/operations/COM_VectorBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cc
@@ -103,8 +103,8 @@ bool VectorBlurOperation::determine_depending_area_of_interest(rcti * /*input*/,
return false;
}
-void VectorBlurOperation::get_area_of_interest(const int UNUSED(input_idx),
- const rcti &UNUSED(output_area),
+void VectorBlurOperation::get_area_of_interest(const int /*input_idx*/,
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
r_input_area = this->get_canvas();
@@ -190,7 +190,10 @@ struct ZSpan {
float clipcrop;
};
-/* each zbuffer has coordinates transformed to local rect coordinates, so we can simply clip */
+/**
+ * Each Z-buffer has coordinates transformed to local rectangle coordinates,
+ * so we can simply clip.
+ */
void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty, float clipcrop)
{
memset(zspan, 0, sizeof(ZSpan));
@@ -385,9 +388,9 @@ static void zbuf_fill_in_rgba(
xx1 = (x0 * v1[0] + y0 * v1[1]) / z0 + v1[2];
- zxd = -(double)x0 / (double)z0;
- zyd = -(double)y0 / (double)z0;
- zy0 = ((double)my2) * zyd + (double)xx1;
+ zxd = -double(x0) / double(z0);
+ zyd = -double(y0) / double(z0);
+ zy0 = double(my2) * zyd + double(xx1);
/* start-offset in rect */
rectx = zspan->rectx;
@@ -419,13 +422,13 @@ static void zbuf_fill_in_rgba(
}
if (sn2 >= sn1) {
- zverg = (double)sn1 * zxd + zy0;
+ zverg = double(sn1) * zxd + zy0;
rz = rectzofs + sn1;
rp = rectpofs + sn1;
x = sn2 - sn1;
while (x >= 0) {
- if (zverg < (double)*rz) {
+ if (zverg < double(*rz)) {
*rz = zverg;
*rp = *col;
}
@@ -528,7 +531,7 @@ void antialias_tagbuf(int xsize, int ysize, char *rectmove)
}
}
- /* last: pixels with 0 we fill in zbuffer, with 1 we skip for mask */
+ /* last: pixels with 0 we fill in Z-buffer, with 1 we skip for mask */
for (y = 2; y < ysize; y++) {
/* setup rows */
row1 = rectmove + (y - 2) * xsize;
@@ -590,15 +593,15 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
const float *dimg, *dz, *ro;
float *rectvz, *dvz, *dvec1, *dvec2, *dz1, *dz2, *rectz;
float *minvecbufrect = nullptr, *rectweight, *rw, *rectmax, *rm;
- float maxspeedsq = (float)nbd->maxspeed * nbd->maxspeed;
+ float maxspeedsq = float(nbd->maxspeed) * nbd->maxspeed;
int y, x, step, maxspeed = nbd->maxspeed, samples = nbd->samples;
int tsktsk = 0;
static int firsttime = 1;
char *rectmove, *dm;
zbuf_alloc_span(&zspan, xsize, ysize, 1.0f);
- zspan.zmulx = ((float)xsize) / 2.0f;
- zspan.zmuly = ((float)ysize) / 2.0f;
+ zspan.zmulx = float(xsize) / 2.0f;
+ zspan.zmuly = float(ysize) / 2.0f;
zspan.zofsx = 0.0f;
zspan.zofsy = 0.0f;
@@ -627,7 +630,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
/* Min speed? then copy speed-buffer to recalculate speed vectors. */
if (nbd->minspeed) {
- float minspeed = (float)nbd->minspeed;
+ float minspeed = float(nbd->minspeed);
float minspeedsq = minspeed * minspeed;
minvecbufrect = (float *)MEM_callocN(sizeof(float[4]) * xsize * ysize, "minspeed buf");
@@ -726,7 +729,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
if (maxspeed) {
float speedsq = dvz[0] * dvz[0] + dvz[1] * dvz[1];
if (speedsq > maxspeedsq) {
- speedsq = (float)maxspeed / sqrtf(speedsq);
+ speedsq = float(maxspeed) / sqrtf(speedsq);
dvz[0] *= speedsq;
dvz[1] *= speedsq;
}
@@ -757,7 +760,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
dm = rectmove;
dvec1 = vecbufrect;
for (x = xsize * ysize; x > 0; x--, dm++, dvec1 += 4) {
- if ((dvec1[0] != 0.0f || dvec1[1] != 0.0f || dvec1[2] != 0.0f || dvec1[3] != 0.0f)) {
+ if (dvec1[0] != 0.0f || dvec1[1] != 0.0f || dvec1[2] != 0.0f || dvec1[3] != 0.0f) {
*dm = 255;
}
}
@@ -776,7 +779,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
/* accumulate */
samples /= 2;
for (step = 1; step <= samples; step++) {
- float speedfac = 0.5f * nbd->fac * (float)step / (float)(samples + 1);
+ float speedfac = 0.5f * nbd->fac * float(step) / float(samples + 1);
int side;
for (side = 0; side < 2; side++) {
@@ -864,7 +867,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
col.alpha = 0.0f;
}
else {
- col.alpha = ((float)*dm) / 255.0f;
+ col.alpha = float(*dm) / 255.0f;
}
col.colpoin = dimg;
@@ -882,7 +885,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
* we don't know what is behind it so we don't do that. this hack
* overestimates the contribution of foreground pixels but looks a
* bit better without a sudden cutoff. */
- blendfac = ((samples - step) / (float)samples);
+ blendfac = ((samples - step) / float(samples));
/* Smooth-step to make it look a bit nicer as well. */
blendfac = 3.0f * pow(blendfac, 2.0f) - 2.0f * pow(blendfac, 3.0f);
diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cc b/source/blender/compositor/operations/COM_ViewerOperation.cc
index 3bd5fa4ad14..b4ff6878784 100644
--- a/source/blender/compositor/operations/COM_ViewerOperation.cc
+++ b/source/blender/compositor/operations/COM_ViewerOperation.cc
@@ -60,7 +60,7 @@ void ViewerOperation::deinit_execution()
output_buffer_ = nullptr;
}
-void ViewerOperation::execute_region(rcti *rect, unsigned int /*tile_number*/)
+void ViewerOperation::execute_region(rcti *rect, uint /*tile_number*/)
{
float *buffer = output_buffer_;
float *depthbuffer = depth_buffer_;
@@ -216,7 +216,7 @@ eCompositorPriority ViewerOperation::get_render_priority() const
return eCompositorPriority::Low;
}
-void ViewerOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output),
+void ViewerOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
@@ -264,7 +264,7 @@ void ViewerOperation::clear_display_buffer()
return;
}
- size_t buf_bytes = (size_t)ibuf_->y * ibuf_->x * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float);
+ size_t buf_bytes = size_t(ibuf_->y) * ibuf_->x * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float);
if (buf_bytes > 0) {
memset(output_buffer_, 0, buf_bytes);
rcti display_area;
diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cc b/source/blender/compositor/operations/COM_WriteBufferOperation.cc
index 9073c92b154..56261bfc660 100644
--- a/source/blender/compositor/operations/COM_WriteBufferOperation.cc
+++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cc
@@ -42,7 +42,7 @@ void WriteBufferOperation::deinit_execution()
memory_proxy_->free();
}
-void WriteBufferOperation::execute_region(rcti *rect, unsigned int /*tile_number*/)
+void WriteBufferOperation::execute_region(rcti *rect, uint /*tile_number*/)
{
MemoryBuffer *memory_buffer = memory_proxy_->get_buffer();
float *buffer = memory_buffer->get_buffer();
@@ -95,7 +95,7 @@ void WriteBufferOperation::execute_region(rcti *rect, unsigned int /*tile_number
void WriteBufferOperation::execute_opencl_region(OpenCLDevice *device,
rcti * /*rect*/,
- unsigned int /*chunk_number*/,
+ uint /*chunk_number*/,
MemoryBuffer **input_memory_buffers,
MemoryBuffer *output_buffer)
{
@@ -110,8 +110,8 @@ void WriteBufferOperation::execute_opencl_region(OpenCLDevice *device,
* NOTE: list of cl_mem will be filled by 2, and needs to be cleaned up by 4
*/
/* STEP 1 */
- const unsigned int output_buffer_width = output_buffer->get_width();
- const unsigned int output_buffer_height = output_buffer->get_height();
+ const uint output_buffer_width = output_buffer->get_width();
+ const uint output_buffer_height = output_buffer->get_height();
const cl_image_format *image_format = OpenCLDevice::determine_image_format(output_buffer);
diff --git a/source/blender/compositor/realtime_compositor/CMakeLists.txt b/source/blender/compositor/realtime_compositor/CMakeLists.txt
index 1f1333332f5..b4352248b5b 100644
--- a/source/blender/compositor/realtime_compositor/CMakeLists.txt
+++ b/source/blender/compositor/realtime_compositor/CMakeLists.txt
@@ -2,6 +2,8 @@
set(INC
.
+ algorithms
+ cached_resources
../../blenkernel
../../blenlib
../../gpu
@@ -9,6 +11,7 @@ set(INC
../../makesdna
../../makesrna
../../nodes
+ ../../render
../../gpu/intern
../../../../intern/guardedalloc
)
@@ -30,6 +33,7 @@ set(SRC
intern/shader_node.cc
intern/shader_operation.cc
intern/simple_operation.cc
+ intern/static_cache_manager.cc
intern/static_shader_manager.cc
intern/texture_pool.cc
intern/utilities.cc
@@ -50,17 +54,157 @@ set(SRC
COM_shader_node.hh
COM_shader_operation.hh
COM_simple_operation.hh
+ COM_static_cache_manager.hh
COM_static_shader_manager.hh
COM_texture_pool.hh
COM_utilities.hh
+
+ algorithms/intern/algorithm_parallel_reduction.cc
+
+ algorithms/COM_algorithm_parallel_reduction.hh
+
+ cached_resources/intern/morphological_distance_feather_weights.cc
+ cached_resources/intern/symmetric_blur_weights.cc
+ cached_resources/intern/symmetric_separable_blur_weights.cc
+
+ cached_resources/COM_cached_resource.hh
+ cached_resources/COM_morphological_distance_feather_weights.hh
+ cached_resources/COM_symmetric_blur_weights.hh
+ cached_resources/COM_symmetric_separable_blur_weights.hh
)
set(LIB
bf_gpu
bf_nodes
bf_imbuf
+ bf_render
bf_blenlib
bf_blenkernel
)
+set(GLSL_SRC
+ shaders/compositor_alpha_crop.glsl
+ shaders/compositor_bilateral_blur.glsl
+ shaders/compositor_blur.glsl
+ shaders/compositor_blur_variable_size.glsl
+ shaders/compositor_bokeh_image.glsl
+ shaders/compositor_box_mask.glsl
+ shaders/compositor_convert.glsl
+ shaders/compositor_despeckle.glsl
+ shaders/compositor_directional_blur.glsl
+ shaders/compositor_edge_filter.glsl
+ shaders/compositor_ellipse_mask.glsl
+ shaders/compositor_filter.glsl
+ shaders/compositor_flip.glsl
+ shaders/compositor_image_crop.glsl
+ shaders/compositor_morphological_distance.glsl
+ shaders/compositor_morphological_distance_feather.glsl
+ shaders/compositor_morphological_distance_threshold.glsl
+ shaders/compositor_morphological_step.glsl
+ shaders/compositor_normalize.glsl
+ shaders/compositor_parallel_reduction.glsl
+ shaders/compositor_projector_lens_distortion.glsl
+ shaders/compositor_realize_on_domain.glsl
+ shaders/compositor_screen_lens_distortion.glsl
+ shaders/compositor_set_alpha.glsl
+ shaders/compositor_split_viewer.glsl
+ shaders/compositor_symmetric_blur.glsl
+ shaders/compositor_symmetric_separable_blur.glsl
+ shaders/compositor_tone_map_photoreceptor.glsl
+ shaders/compositor_tone_map_simple.glsl
+
+ shaders/library/gpu_shader_compositor_alpha_over.glsl
+ shaders/library/gpu_shader_compositor_blur_common.glsl
+ shaders/library/gpu_shader_compositor_bright_contrast.glsl
+ shaders/library/gpu_shader_compositor_channel_matte.glsl
+ shaders/library/gpu_shader_compositor_chroma_matte.glsl
+ shaders/library/gpu_shader_compositor_color_balance.glsl
+ shaders/library/gpu_shader_compositor_color_correction.glsl
+ shaders/library/gpu_shader_compositor_color_matte.glsl
+ shaders/library/gpu_shader_compositor_color_spill.glsl
+ shaders/library/gpu_shader_compositor_color_to_luminance.glsl
+ shaders/library/gpu_shader_compositor_difference_matte.glsl
+ shaders/library/gpu_shader_compositor_distance_matte.glsl
+ shaders/library/gpu_shader_compositor_exposure.glsl
+ shaders/library/gpu_shader_compositor_gamma.glsl
+ shaders/library/gpu_shader_compositor_hue_correct.glsl
+ shaders/library/gpu_shader_compositor_hue_saturation_value.glsl
+ shaders/library/gpu_shader_compositor_invert.glsl
+ shaders/library/gpu_shader_compositor_luminance_matte.glsl
+ shaders/library/gpu_shader_compositor_main.glsl
+ shaders/library/gpu_shader_compositor_map_value.glsl
+ shaders/library/gpu_shader_compositor_normal.glsl
+ shaders/library/gpu_shader_compositor_posterize.glsl
+ shaders/library/gpu_shader_compositor_separate_combine.glsl
+ shaders/library/gpu_shader_compositor_set_alpha.glsl
+ shaders/library/gpu_shader_compositor_store_output.glsl
+ shaders/library/gpu_shader_compositor_texture_utilities.glsl
+ shaders/library/gpu_shader_compositor_type_conversion.glsl
+)
+
+set(GLSL_C)
+foreach(GLSL_FILE ${GLSL_SRC})
+ data_to_c_simple(${GLSL_FILE} GLSL_C)
+endforeach()
+
+blender_add_lib(bf_compositor_shaders "${GLSL_C}" "" "" "")
+
+list(APPEND LIB
+ bf_compositor_shaders
+)
+
+set(GLSL_SOURCE_CONTENT "")
+foreach(GLSL_FILE ${GLSL_SRC})
+ get_filename_component(GLSL_FILE_NAME ${GLSL_FILE} NAME)
+ string(REPLACE "." "_" GLSL_FILE_NAME_UNDERSCORES ${GLSL_FILE_NAME})
+ string(APPEND GLSL_SOURCE_CONTENT "SHADER_SOURCE\(datatoc_${GLSL_FILE_NAME_UNDERSCORES}, \"${GLSL_FILE_NAME}\", \"${GLSL_FILE}\"\)\n")
+endforeach()
+
+set(glsl_source_list_file "${CMAKE_CURRENT_BINARY_DIR}/glsl_compositor_source_list.h")
+file(GENERATE OUTPUT ${glsl_source_list_file} CONTENT "${GLSL_SOURCE_CONTENT}")
+list(APPEND SRC ${glsl_source_list_file})
+list(APPEND INC ${CMAKE_CURRENT_BINARY_DIR})
+
+target_include_directories(bf_compositor_shaders PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
+
+set(SRC_SHADER_CREATE_INFOS
+ shaders/infos/compositor_alpha_crop_info.hh
+ shaders/infos/compositor_bilateral_blur_info.hh
+ shaders/infos/compositor_blur_info.hh
+ shaders/infos/compositor_blur_variable_size_info.hh
+ shaders/infos/compositor_bokeh_image_info.hh
+ shaders/infos/compositor_box_mask_info.hh
+ shaders/infos/compositor_convert_info.hh
+ shaders/infos/compositor_despeckle_info.hh
+ shaders/infos/compositor_directional_blur_info.hh
+ shaders/infos/compositor_edge_filter_info.hh
+ shaders/infos/compositor_ellipse_mask_info.hh
+ shaders/infos/compositor_filter_info.hh
+ shaders/infos/compositor_flip_info.hh
+ shaders/infos/compositor_image_crop_info.hh
+ shaders/infos/compositor_morphological_distance_feather_info.hh
+ shaders/infos/compositor_morphological_distance_info.hh
+ shaders/infos/compositor_morphological_distance_threshold_info.hh
+ shaders/infos/compositor_morphological_step_info.hh
+ shaders/infos/compositor_normalize_info.hh
+ shaders/infos/compositor_parallel_reduction_info.hh
+ shaders/infos/compositor_projector_lens_distortion_info.hh
+ shaders/infos/compositor_realize_on_domain_info.hh
+ shaders/infos/compositor_screen_lens_distortion_info.hh
+ shaders/infos/compositor_set_alpha_info.hh
+ shaders/infos/compositor_split_viewer_info.hh
+ shaders/infos/compositor_symmetric_blur_info.hh
+ shaders/infos/compositor_symmetric_separable_blur_info.hh
+ shaders/infos/compositor_tone_map_photoreceptor_info.hh
+ shaders/infos/compositor_tone_map_simple_info.hh
+)
+
+set(SHADER_CREATE_INFOS_CONTENT "")
+foreach(DESCRIPTOR_FILE ${SRC_SHADER_CREATE_INFOS})
+ string(APPEND SHADER_CREATE_INFOS_CONTENT "#include \"${DESCRIPTOR_FILE}\"\n")
+endforeach()
+
+set(shader_create_info_list_file "${CMAKE_CURRENT_BINARY_DIR}/compositor_shader_create_info_list.hh")
+file(GENERATE OUTPUT ${shader_create_info_list_file} CONTENT "${SHADER_CREATE_INFOS_CONTENT}")
+
blender_add_lib(bf_realtime_compositor "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/compositor/realtime_compositor/COM_context.hh b/source/blender/compositor/realtime_compositor/COM_context.hh
index b5c8cea641f..80fb4f70ca4 100644
--- a/source/blender/compositor/realtime_compositor/COM_context.hh
+++ b/source/blender/compositor/realtime_compositor/COM_context.hh
@@ -9,6 +9,7 @@
#include "GPU_texture.h"
+#include "COM_static_cache_manager.hh"
#include "COM_static_shader_manager.hh"
#include "COM_texture_pool.hh"
@@ -22,14 +23,17 @@ namespace blender::realtime_compositor {
* providing input data like render passes and the active scene, as well as references to the data
* where the output of the evaluator will be written. The class also provides a reference to the
* texture pool which should be implemented by the caller and provided during construction.
- * Finally, the class have an instance of a static shader manager for convenient shader
- * acquisition. */
+ * Finally, the class have an instance of a static shader manager and a static resource manager
+ * for acquiring cached shaders and resources efficiently. */
class Context {
private:
/* A texture pool that can be used to allocate textures for the compositor efficiently. */
TexturePool &texture_pool_;
/* A static shader manager that can be used to acquire shaders for the compositor efficiently. */
StaticShaderManager shader_manager_;
+ /* A static cache manager that can be used to acquire cached resources for the compositor
+ * efficiently. */
+ StaticCacheManager cache_manager_;
public:
Context(TexturePool &texture_pool);
@@ -67,6 +71,9 @@ class Context {
/* Get a reference to the static shader manager of this context. */
StaticShaderManager &shader_manager();
+
+ /* Get a reference to the static cache manager of this context. */
+ StaticCacheManager &cache_manager();
};
} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/COM_conversion_operation.hh b/source/blender/compositor/realtime_compositor/COM_conversion_operation.hh
index 15e1d0722ea..310333aea5a 100644
--- a/source/blender/compositor/realtime_compositor/COM_conversion_operation.hh
+++ b/source/blender/compositor/realtime_compositor/COM_conversion_operation.hh
@@ -11,11 +11,13 @@
namespace blender::realtime_compositor {
-/* -------------------------------------------------------------------------------------------------
- * Conversion Operation
+/* -------------------------------------------------------------------- */
+/** \name Conversion Operation
*
* A simple operation that converts a result from a certain type to another. See the derived
- * classes for more details. */
+ * classes for more details.
+ * \{ */
+
class ConversionOperation : public SimpleOperation {
public:
using SimpleOperation::SimpleOperation;
@@ -37,13 +39,18 @@ class ConversionOperation : public SimpleOperation {
/* Get the shader the will be used for conversion. */
virtual GPUShader *get_conversion_shader() const = 0;
-};
-/* -------------------------------------------------------------------------------------------------
- * Convert Float To Vector Operation
+ /** \} */
+
+}; // namespace blender::realtime_compositorclassConversionOperation:publicSimpleOperation
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Float to Vector Operation
*
* Takes a float result and outputs a vector result. All three components of the output are filled
- * with the input float. */
+ * with the input float.
+ * \{ */
+
class ConvertFloatToVectorOperation : public ConversionOperation {
public:
ConvertFloatToVectorOperation(Context &context);
@@ -53,11 +60,15 @@ class ConvertFloatToVectorOperation : public ConversionOperation {
GPUShader *get_conversion_shader() const override;
};
-/* -------------------------------------------------------------------------------------------------
- * Convert Float To Color Operation
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Float to Color Operation
*
* Takes a float result and outputs a color result. All three color channels of the output are
- * filled with the input float and the alpha channel is set to 1. */
+ * filled with the input float and the alpha channel is set to 1.
+ * \{ */
+
class ConvertFloatToColorOperation : public ConversionOperation {
public:
ConvertFloatToColorOperation(Context &context);
@@ -67,11 +78,15 @@ class ConvertFloatToColorOperation : public ConversionOperation {
GPUShader *get_conversion_shader() const override;
};
-/* -------------------------------------------------------------------------------------------------
- * Convert Color To Float Operation
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Color to Float Operation
*
* Takes a color result and outputs a float result. The output is the average of the three color
- * channels, the alpha channel is ignored. */
+ * channels, the alpha channel is ignored.
+ * \{ */
+
class ConvertColorToFloatOperation : public ConversionOperation {
public:
ConvertColorToFloatOperation(Context &context);
@@ -81,11 +96,15 @@ class ConvertColorToFloatOperation : public ConversionOperation {
GPUShader *get_conversion_shader() const override;
};
-/* -------------------------------------------------------------------------------------------------
- * Convert Color To Vector Operation
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Color to Vector Operation
*
* Takes a color result and outputs a vector result. The output is a copy of the three color
- * channels to the three vector components. */
+ * channels to the three vector components.
+ * \{ */
+
class ConvertColorToVectorOperation : public ConversionOperation {
public:
ConvertColorToVectorOperation(Context &context);
@@ -95,11 +114,18 @@ class ConvertColorToVectorOperation : public ConversionOperation {
GPUShader *get_conversion_shader() const override;
};
-/* -------------------------------------------------------------------------------------------------
- * Convert Vector To Float Operation
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Vector to Float Operation
*
* Takes a vector result and outputs a float result. The output is the average of the three
- * components. */
+ * components.
+ * \{ */
+
+/*
+ *
+ * */
class ConvertVectorToFloatOperation : public ConversionOperation {
public:
ConvertVectorToFloatOperation(Context &context);
@@ -109,11 +135,15 @@ class ConvertVectorToFloatOperation : public ConversionOperation {
GPUShader *get_conversion_shader() const override;
};
-/* -------------------------------------------------------------------------------------------------
- * Convert Vector To Color Operation
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Vector to Color Operation
*
* Takes a vector result and outputs a color result. The output is a copy of the three vector
- * components to the three color channels with the alpha channel set to 1. */
+ * components to the three color channels with the alpha channel set to 1.
+ * \{ */
+
class ConvertVectorToColorOperation : public ConversionOperation {
public:
ConvertVectorToColorOperation(Context &context);
@@ -123,4 +153,6 @@ class ConvertVectorToColorOperation : public ConversionOperation {
GPUShader *get_conversion_shader() const override;
};
+/** \} */
+
} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/COM_domain.hh b/source/blender/compositor/realtime_compositor/COM_domain.hh
index 54d712f7578..99b40ae61cf 100644
--- a/source/blender/compositor/realtime_compositor/COM_domain.hh
+++ b/source/blender/compositor/realtime_compositor/COM_domain.hh
@@ -28,7 +28,7 @@ struct RealizationOptions {
* result involves projecting it on a different domain, which in turn, involves sampling the
* result at arbitrary locations, the interpolation identifies the method used for computing the
* value at those arbitrary locations. */
- Interpolation interpolation = Interpolation::Nearest;
+ Interpolation interpolation = Interpolation::Bilinear;
/* If true, the result will be repeated infinitely along the horizontal axis when realizing the
* result. If false, regions outside of bounds of the result along the horizontal axis will be
* filled with zeros. */
diff --git a/source/blender/compositor/realtime_compositor/COM_result.hh b/source/blender/compositor/realtime_compositor/COM_result.hh
index a16d68bb92d..f5ecc4c2112 100644
--- a/source/blender/compositor/realtime_compositor/COM_result.hh
+++ b/source/blender/compositor/realtime_compositor/COM_result.hh
@@ -14,7 +14,9 @@
namespace blender::realtime_compositor {
/* Possible data types that operations can operate on. They either represent the base type of the
- * result texture or a single value result. */
+ * result texture or a single value result. The color type represents an RGBA color. And the vector
+ * type represents a generic 4-component vector, which can encode two 2D vectors, one 3D vector
+ * with the last component ignored, or other dimensional data. */
enum class ResultType : uint8_t {
Float,
Vector,
@@ -85,7 +87,7 @@ class Result {
* is a texture. */
union {
float float_value_;
- float3 vector_value_;
+ float4 vector_value_;
float4 color_value_;
};
/* The domain of the result. This only matters if the result was a texture. See the discussion in
@@ -157,7 +159,7 @@ class Result {
/* If the result is a single value result of type vector, return its vector value. Otherwise, an
* uninitialized value is returned. */
- float3 get_vector_value() const;
+ float4 get_vector_value() const;
/* If the result is a single value result of type color, return its color value. Otherwise, an
* uninitialized value is returned. */
@@ -167,7 +169,7 @@ class Result {
float get_float_value_default(float default_value) const;
/* Same as get_vector_value but returns a default value if the result is not a single value. */
- float3 get_vector_value_default(const float3 &default_value) const;
+ float4 get_vector_value_default(const float4 &default_value) const;
/* Same as get_color_value but returns a default value if the result is not a single value. */
float4 get_color_value_default(const float4 &default_value) const;
@@ -178,7 +180,7 @@ class Result {
/* If the result is a single value result of type vector, set its vector value and upload it to
* the texture. Otherwise, an undefined behavior is invoked. */
- void set_vector_value(const float3 &value);
+ void set_vector_value(const float4 &value);
/* If the result is a single value result of type color, set its color value and upload it to the
* texture. Otherwise, an undefined behavior is invoked. */
diff --git a/source/blender/compositor/realtime_compositor/COM_scheduler.hh b/source/blender/compositor/realtime_compositor/COM_scheduler.hh
index 4f778b32145..9f3bc14ae17 100644
--- a/source/blender/compositor/realtime_compositor/COM_scheduler.hh
+++ b/source/blender/compositor/realtime_compositor/COM_scheduler.hh
@@ -16,6 +16,6 @@ using Schedule = VectorSet<DNode>;
/* Computes the execution schedule of the node tree. This is essentially a post-order depth first
* traversal of the node tree from the output node to the leaf input nodes, with informed order of
* traversal of dependencies based on a heuristic estimation of the number of needed buffers. */
-Schedule compute_schedule(DerivedNodeTree &tree);
+Schedule compute_schedule(const DerivedNodeTree &tree);
} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/COM_static_cache_manager.hh b/source/blender/compositor/realtime_compositor/COM_static_cache_manager.hh
new file mode 100644
index 00000000000..20fbb156879
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/COM_static_cache_manager.hh
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include <memory>
+
+#include "BLI_map.hh"
+#include "BLI_math_vec_types.hh"
+
+#include "COM_morphological_distance_feather_weights.hh"
+#include "COM_symmetric_blur_weights.hh"
+#include "COM_symmetric_separable_blur_weights.hh"
+
+namespace blender::realtime_compositor {
+
+/* -------------------------------------------------------------------------------------------------
+ * Static Cache Manager
+ *
+ * A static cache manager is a collection of cached resources that can be retrieved when needed and
+ * created if not already available. In particular, each cached resource type has its own Map in
+ * the class, where all instances of that cached resource type are stored and tracked. See the
+ * CachedResource class for more information.
+ *
+ * The manager deletes the cached resources that are no longer needed. A cached resource is said to
+ * be not needed when it was not used in the previous evaluation. This is done through the
+ * following mechanism:
+ *
+ * - Before every evaluation, do the following:
+ * 1. All resources whose CachedResource::needed flag is false are deleted.
+ * 2. The CachedResource::needed flag of all remaining resources is set to false.
+ * - During evaluation, when retrieving any cached resource, set its CachedResource::needed flag to
+ * true.
+ *
+ * In effect, any resource that was used in the previous evaluation but was not used in the current
+ * evaluation will be deleted before the next evaluation. This mechanism is implemented in the
+ * reset() method of the class, which should be called before every evaluation. */
+class StaticCacheManager {
+ private:
+ /* A map that stores all SymmetricBlurWeights cached resources. */
+ Map<SymmetricBlurWeightsKey, std::unique_ptr<SymmetricBlurWeights>> symmetric_blur_weights_;
+
+ /* A map that stores all SymmetricSeparableBlurWeights cached resources. */
+ Map<SymmetricSeparableBlurWeightsKey, std::unique_ptr<SymmetricSeparableBlurWeights>>
+ symmetric_separable_blur_weights_;
+
+ /* A map that stores all MorphologicalDistanceFeatherWeights cached resources. */
+ Map<MorphologicalDistanceFeatherWeightsKey, std::unique_ptr<MorphologicalDistanceFeatherWeights>>
+ morphological_distance_feather_weights_;
+
+ public:
+ /* Reset the cache manager by deleting the cached resources that are no longer needed because
+ * they weren't used in the last evaluation and prepare the remaining cached resources to track
+ * their needed status in the next evaluation. See the class description for more information.
+ * This should be called before every evaluation. */
+ void reset();
+
+ /* Check if there is an available SymmetricBlurWeights cached resource with the given parameters
+ * in the manager, if one exists, return it, otherwise, return a newly created one and add it to
+ * the manager. In both cases, tag the cached resource as needed to keep it cached for the next
+ * evaluation. */
+ SymmetricBlurWeights &get_symmetric_blur_weights(int type, float2 radius);
+
+ /* Check if there is an available SymmetricSeparableBlurWeights cached resource with the given
+ * parameters in the manager, if one exists, return it, otherwise, return a newly created one and
+ * add it to the manager. In both cases, tag the cached resource as needed to keep it cached for
+ * the next evaluation. */
+ SymmetricSeparableBlurWeights &get_symmetric_separable_blur_weights(int type, float radius);
+
+ /* Check if there is an available MorphologicalDistanceFeatherWeights cached resource with the
+ * given parameters in the manager, if one exists, return it, otherwise, return a newly created
+ * one and add it to the manager. In both cases, tag the cached resource as needed to keep it
+ * cached for the next evaluation. */
+ MorphologicalDistanceFeatherWeights &get_morphological_distance_feather_weights(int type,
+ int radius);
+};
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/COM_texture_pool.hh b/source/blender/compositor/realtime_compositor/COM_texture_pool.hh
index cc6641d288f..c68219b0279 100644
--- a/source/blender/compositor/realtime_compositor/COM_texture_pool.hh
+++ b/source/blender/compositor/realtime_compositor/COM_texture_pool.hh
@@ -60,8 +60,8 @@ class TexturePool {
/* Shorthand for acquire with GPU_RGBA16F format. */
GPUTexture *acquire_color(int2 size);
- /* Shorthand for acquire with GPU_RGBA16F format. Identical to acquire_color because vectors
- * are stored in RGBA textures, due to the limited support for RGB textures. */
+ /* Shorthand for acquire with GPU_RGBA16F format. Identical to acquire_color because vectors are
+ * 4D, and are thus stored in RGBA textures. */
GPUTexture *acquire_vector(int2 size);
/* Shorthand for acquire with GPU_R16F format. */
diff --git a/source/blender/compositor/realtime_compositor/COM_utilities.hh b/source/blender/compositor/realtime_compositor/COM_utilities.hh
index 25f9fd0c1b6..efd1bc2b6b0 100644
--- a/source/blender/compositor/realtime_compositor/COM_utilities.hh
+++ b/source/blender/compositor/realtime_compositor/COM_utilities.hh
@@ -17,7 +17,7 @@ namespace blender::realtime_compositor {
using namespace nodes::derived_node_tree_types;
/**
- Get the origin socket of the given node input. If the input is not linked, the socket itself is
+ * Get the origin socket of the given node input. If the input is not linked, the socket itself is
* returned. If the input is linked, the socket that is linked to it is returned, which could
* either be an input or an output. An input socket is returned when the given input is connected
* to an unlinked input of a group input node.
diff --git a/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_parallel_reduction.hh b/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_parallel_reduction.hh
new file mode 100644
index 00000000000..f6d479f9bbe
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_parallel_reduction.hh
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include "BLI_math_vec_types.hh"
+
+#include "GPU_texture.h"
+
+#include "COM_context.hh"
+
+namespace blender::realtime_compositor {
+
+/* --------------------------------------------------------------------
+ * Sum Reductions.
+ */
+
+/* Computes the sum of the red channel of all pixels in the given texture. */
+float sum_red(Context &context, GPUTexture *texture);
+
+/* Computes the sum of the green channel of all pixels in the given texture. */
+float sum_green(Context &context, GPUTexture *texture);
+
+/* Computes the sum of the blue channel of all pixels in the given texture. */
+float sum_blue(Context &context, GPUTexture *texture);
+
+/* Computes the sum of the luminance of all pixels in the given texture, using the given luminance
+ * coefficients to compute the luminance. */
+float sum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients);
+
+/* Computes the sum of the logarithm of the luminance of all pixels in the given texture, using the
+ * given luminance coefficients to compute the luminance. */
+float sum_log_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients);
+
+/* Computes the sum of the colors of all pixels in the given texture. */
+float4 sum_color(Context &context, GPUTexture *texture);
+
+/* --------------------------------------------------------------------
+ * Sum Of Squared Difference Reductions.
+ */
+
+/* Computes the sum of the squared difference between the red channel of all pixels in the given
+ * texture and the given subtrahend. This can be used to compute the standard deviation if the
+ * given subtrahend is the mean. */
+float sum_red_squared_difference(Context &context, GPUTexture *texture, float subtrahend);
+
+/* Computes the sum of the squared difference between the green channel of all pixels in the given
+ * texture and the given subtrahend. This can be used to compute the standard deviation if the
+ * given subtrahend is the mean. */
+float sum_green_squared_difference(Context &context, GPUTexture *texture, float subtrahend);
+
+/* Computes the sum of the squared difference between the blue channel of all pixels in the given
+ * texture and the given subtrahend. This can be used to compute the standard deviation if the
+ * given subtrahend is the mean. */
+float sum_blue_squared_difference(Context &context, GPUTexture *texture, float subtrahend);
+
+/* Computes the sum of the squared difference between the luminance of all pixels in the given
+ * texture and the given subtrahend, using the given luminance coefficients to compute the
+ * luminance. This can be used to compute the standard deviation if the given subtrahend is the
+ * mean. */
+float sum_luminance_squared_difference(Context &context,
+ GPUTexture *texture,
+ float3 luminance_coefficients,
+ float subtrahend);
+
+/* --------------------------------------------------------------------
+ * Maximum Reductions.
+ */
+
+/* Computes the maximum luminance of all pixels in the given texture, using the given luminance
+ * coefficients to compute the luminance. */
+float maximum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients);
+
+/* Computes the maximum float of all pixels in the given float texture, limited to the given range.
+ * Values outside of the given range are ignored. If non of the pixel values are in the range, the
+ * lower bound of the range is returned. For instance, if the given range is [-10, 10] and the
+ * image contains the values {2, 5, 11}, the maximum will be 5, since 11 is outside of the range.
+ * This is particularly useful for Z Depth normalization, since Z Depth can contain near infinite
+ * values, so enforcing an upper bound is beneficial. */
+float maximum_float_in_range(Context &context,
+ GPUTexture *texture,
+ float lower_bound,
+ float upper_bound);
+
+/* --------------------------------------------------------------------
+ * Minimum Reductions.
+ */
+
+/* Computes the minimum luminance of all pixels in the given texture, using the given luminance
+ * coefficients to compute the luminance. */
+float minimum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients);
+
+/* Computes the minimum float of all pixels in the given float texture, limited to the given range.
+ * Values outside of the given range are ignored. If non of the pixel values are in the range, the
+ * upper bound of the range is returned. For instance, if the given range is [-10, 10] and the
+ * image contains the values {-11, 2, 5}, the minimum will be 2, since -11 is outside of the range.
+ * This is particularly useful for Z Depth normalization, since Z Depth can contain near infinite
+ * values, so enforcing a lower bound is beneficial. */
+float minimum_float_in_range(Context &context,
+ GPUTexture *texture,
+ float lower_bound,
+ float upper_bound);
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc b/source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc
new file mode 100644
index 00000000000..9672431992d
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc
@@ -0,0 +1,309 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BLI_math_vec_types.hh"
+#include "BLI_math_vector.hh"
+
+#include "MEM_guardedalloc.h"
+
+#include "GPU_compute.h"
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "COM_context.hh"
+#include "COM_utilities.hh"
+
+#include "COM_algorithm_parallel_reduction.hh"
+
+namespace blender::realtime_compositor {
+
+/* Reduces the given texture into a single value and returns it. The return value should be freed
+ * by a call to MEM_freeN. The return value is either a pointer to a float, or a pointer to an
+ * array of floats that represents a vector. This depends on the given format, which should be
+ * compatible with the reduction shader.
+ *
+ * The given reduction shader should be bound when calling the function and the shader is expected
+ * to be derived from the compositor_parallel_reduction.glsl shader, see that file for more
+ * information. Also see the compositor_parallel_reduction_info.hh file for example shader
+ * definitions. */
+static float *parallel_reduction_dispatch(Context &context,
+ GPUTexture *texture,
+ GPUShader *shader,
+ eGPUTextureFormat format)
+{
+ GPU_shader_uniform_1b(shader, "is_initial_reduction", true);
+
+ GPUTexture *texture_to_reduce = texture;
+ int2 size_to_reduce = int2(GPU_texture_width(texture), GPU_texture_height(texture));
+
+ /* Dispatch the reduction shader until the texture reduces to a single pixel. */
+ while (size_to_reduce != int2(1)) {
+ const int2 reduced_size = math::divide_ceil(size_to_reduce, int2(16));
+ GPUTexture *reduced_texture = context.texture_pool().acquire(reduced_size, format);
+
+ GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH);
+ const int texture_image_unit = GPU_shader_get_texture_binding(shader, "input_tx");
+ GPU_texture_bind(texture_to_reduce, texture_image_unit);
+
+ const int image_unit = GPU_shader_get_texture_binding(shader, "output_img");
+ GPU_texture_image_bind(reduced_texture, image_unit);
+
+ GPU_compute_dispatch(shader, reduced_size.x, reduced_size.y, 1);
+
+ GPU_texture_image_unbind(reduced_texture);
+ GPU_texture_unbind(texture_to_reduce);
+
+ /* Release the input texture only if it is not the source texture, since the source texture is
+ * not acquired or owned by the function. */
+ if (texture_to_reduce != texture) {
+ context.texture_pool().release(texture_to_reduce);
+ }
+
+ texture_to_reduce = reduced_texture;
+ size_to_reduce = reduced_size;
+
+ GPU_shader_uniform_1b(shader, "is_initial_reduction", false);
+ }
+
+ GPU_memory_barrier(GPU_BARRIER_TEXTURE_UPDATE);
+ float *pixel = static_cast<float *>(GPU_texture_read(texture_to_reduce, GPU_DATA_FLOAT, 0));
+
+ /* Release the final texture only if it is not the source texture, since the source texture is
+ * not acquired or owned by the function. */
+ if (texture_to_reduce != texture) {
+ context.texture_pool().release(texture_to_reduce);
+ }
+
+ return pixel;
+}
+
+/* --------------------------------------------------------------------
+ * Sum Reductions.
+ */
+
+float sum_red(Context &context, GPUTexture *texture)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_red");
+ GPU_shader_bind(shader);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+float sum_green(Context &context, GPUTexture *texture)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_green");
+ GPU_shader_bind(shader);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+float sum_blue(Context &context, GPUTexture *texture)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_blue");
+ GPU_shader_bind(shader);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+float sum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_luminance");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+float sum_log_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_log_luminance");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+float4 sum_color(Context &context, GPUTexture *texture)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_color");
+ GPU_shader_bind(shader);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_RGBA32F);
+ const float4 sum = float4(reduced_value);
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+/* --------------------------------------------------------------------
+ * Sum Of Squared Difference Reductions.
+ */
+
+float sum_red_squared_difference(Context &context, GPUTexture *texture, float subtrahend)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_red_squared_difference");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_1f(shader, "subtrahend", subtrahend);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+float sum_green_squared_difference(Context &context, GPUTexture *texture, float subtrahend)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_green_squared_difference");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_1f(shader, "subtrahend", subtrahend);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+float sum_blue_squared_difference(Context &context, GPUTexture *texture, float subtrahend)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_blue_squared_difference");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_1f(shader, "subtrahend", subtrahend);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+float sum_luminance_squared_difference(Context &context,
+ GPUTexture *texture,
+ float3 luminance_coefficients,
+ float subtrahend)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_luminance_squared_difference");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
+ GPU_shader_uniform_1f(shader, "subtrahend", subtrahend);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+/* --------------------------------------------------------------------
+ * Maximum Reductions.
+ */
+
+float maximum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_maximum_luminance");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float maximum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return maximum;
+}
+
+float maximum_float_in_range(Context &context,
+ GPUTexture *texture,
+ float lower_bound,
+ float upper_bound)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_maximum_float_in_range");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_1f(shader, "lower_bound", lower_bound);
+ GPU_shader_uniform_1f(shader, "upper_bound", upper_bound);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float maximum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return maximum;
+}
+
+/* --------------------------------------------------------------------
+ * Minimum Reductions.
+ */
+
+float minimum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_minimum_luminance");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float minimum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return minimum;
+}
+
+float minimum_float_in_range(Context &context,
+ GPUTexture *texture,
+ float lower_bound,
+ float upper_bound)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_minimum_float_in_range");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_1f(shader, "lower_bound", lower_bound);
+ GPU_shader_uniform_1f(shader, "upper_bound", upper_bound);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float minimum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return minimum;
+}
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/cached_resources/COM_cached_resource.hh b/source/blender/compositor/realtime_compositor/cached_resources/COM_cached_resource.hh
new file mode 100644
index 00000000000..fe3158ef52d
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/cached_resources/COM_cached_resource.hh
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+namespace blender::realtime_compositor {
+
+/* -------------------------------------------------------------------------------------------------
+ * Cached Resource.
+ *
+ * A cached resource is any resource that can be cached across compositor evaluations and across
+ * multiple operations. Cached resources are managed by an instance of a StaticCacheManager and are
+ * freed when they are no longer needed, a state which is represented by the `needed` member in the
+ * class. For more information on the caching mechanism, see the StaticCacheManager class.
+ *
+ * To add a new cached resource:
+ *
+ * - Create a derived class from CachedResource to represent the resource.
+ * - Create a key class that can be used in a Map to identify the resource.
+ * - Add a new Map to StaticCacheManager mapping the key to the resource.
+ * - Reset the contents of the added map in StaticCacheManager::reset.
+ * - Add an appropriate getter method in StaticCacheManager.
+ *
+ * See the existing cached resources for reference. */
+class CachedResource {
+ public:
+ /* A flag that represents the needed status of the cached resource. See the StaticCacheManager
+ * class for more information on how this member is utilized in the caching mechanism. */
+ bool needed = true;
+};
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/cached_resources/COM_morphological_distance_feather_weights.hh b/source/blender/compositor/realtime_compositor/cached_resources/COM_morphological_distance_feather_weights.hh
new file mode 100644
index 00000000000..cd6827bdd6b
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/cached_resources/COM_morphological_distance_feather_weights.hh
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include <cstdint>
+
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "COM_cached_resource.hh"
+
+namespace blender::realtime_compositor {
+
+/* ------------------------------------------------------------------------------------------------
+ * Morphological Distance Feather Key.
+ */
+class MorphologicalDistanceFeatherWeightsKey {
+ public:
+ int type;
+ float radius;
+
+ MorphologicalDistanceFeatherWeightsKey(int type, float radius);
+
+ uint64_t hash() const;
+};
+
+bool operator==(const MorphologicalDistanceFeatherWeightsKey &a,
+ const MorphologicalDistanceFeatherWeightsKey &b);
+
+/* -------------------------------------------------------------------------------------------------
+ * Morphological Distance Feather Weights.
+ *
+ * A cached resource that computes and caches 1D GPU textures containing the weights of the
+ * separable Gaussian filter of the given radius as well as an inverse distance falloff of the
+ * given type and radius. The weights and falloffs are symmetric, because the Gaussian and falloff
+ * functions are all even functions. Consequently, only the positive half of the filter is computed
+ * and the shader takes that into consideration. */
+class MorphologicalDistanceFeatherWeights : public CachedResource {
+ private:
+ GPUTexture *weights_texture_ = nullptr;
+ GPUTexture *distance_falloffs_texture_ = nullptr;
+
+ public:
+ MorphologicalDistanceFeatherWeights(int type, int radius);
+
+ ~MorphologicalDistanceFeatherWeights();
+
+ void compute_weights(int radius);
+
+ void compute_distance_falloffs(int type, int radius);
+
+ void bind_weights_as_texture(GPUShader *shader, const char *texture_name) const;
+
+ void unbind_weights_as_texture() const;
+
+ void bind_distance_falloffs_as_texture(GPUShader *shader, const char *texture_name) const;
+
+ void unbind_distance_falloffs_as_texture() const;
+};
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_blur_weights.hh b/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_blur_weights.hh
new file mode 100644
index 00000000000..05d3c7c6f3e
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_blur_weights.hh
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include <cstdint>
+
+#include "BLI_math_vec_types.hh"
+
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "COM_cached_resource.hh"
+
+namespace blender::realtime_compositor {
+
+/* ------------------------------------------------------------------------------------------------
+ * Symmetric Blur Weights Key.
+ */
+class SymmetricBlurWeightsKey {
+ public:
+ int type;
+ float2 radius;
+
+ SymmetricBlurWeightsKey(int type, float2 radius);
+
+ uint64_t hash() const;
+};
+
+bool operator==(const SymmetricBlurWeightsKey &a, const SymmetricBlurWeightsKey &b);
+
+/* -------------------------------------------------------------------------------------------------
+ * Symmetric Blur Weights.
+ *
+ * A cached resource that computes and caches a 2D GPU texture containing the weights of the filter
+ * of the given type and radius. The filter is assumed to be symmetric, because the filter
+ * functions are evaluated on the normalized distance to the center. Consequently, only the upper
+ * right quadrant are computed and the shader takes that into consideration. */
+class SymmetricBlurWeights : public CachedResource {
+ private:
+ GPUTexture *texture_ = nullptr;
+
+ public:
+ SymmetricBlurWeights(int type, float2 radius);
+
+ ~SymmetricBlurWeights();
+
+ void bind_as_texture(GPUShader *shader, const char *texture_name) const;
+
+ void unbind_as_texture() const;
+};
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_separable_blur_weights.hh b/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_separable_blur_weights.hh
new file mode 100644
index 00000000000..85e75e4535d
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_separable_blur_weights.hh
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include <cstdint>
+
+#include "BLI_math_vec_types.hh"
+
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "COM_cached_resource.hh"
+
+namespace blender::realtime_compositor {
+
+/* ------------------------------------------------------------------------------------------------
+ * Symmetric Separable Blur Weights Key.
+ */
+class SymmetricSeparableBlurWeightsKey {
+ public:
+ int type;
+ float radius;
+
+ SymmetricSeparableBlurWeightsKey(int type, float radius);
+
+ uint64_t hash() const;
+};
+
+bool operator==(const SymmetricSeparableBlurWeightsKey &a,
+ const SymmetricSeparableBlurWeightsKey &b);
+
+/* -------------------------------------------------------------------------------------------------
+ * Symmetric Separable Blur Weights.
+ *
+ * A cached resource that computes and caches a 1D GPU texture containing the weights of the
+ * separable filter of the given type and radius. The filter is assumed to be symmetric, because
+ * the filter functions are all even functions. Consequently, only the positive half of the filter
+ * is computed and the shader takes that into consideration. */
+class SymmetricSeparableBlurWeights : public CachedResource {
+ private:
+ GPUTexture *texture_ = nullptr;
+
+ public:
+ SymmetricSeparableBlurWeights(int type, float radius);
+
+ ~SymmetricSeparableBlurWeights();
+
+ void bind_as_texture(GPUShader *shader, const char *texture_name) const;
+
+ void unbind_as_texture() const;
+};
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/cached_resources/intern/morphological_distance_feather_weights.cc b/source/blender/compositor/realtime_compositor/cached_resources/intern/morphological_distance_feather_weights.cc
new file mode 100644
index 00000000000..eac88b907b8
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/cached_resources/intern/morphological_distance_feather_weights.cc
@@ -0,0 +1,159 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <cmath>
+#include <cstdint>
+
+#include "BLI_array.hh"
+#include "BLI_hash.hh"
+#include "BLI_index_range.hh"
+
+#include "RE_pipeline.h"
+
+#include "DNA_scene_types.h"
+
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "COM_morphological_distance_feather_weights.hh"
+
+namespace blender::realtime_compositor {
+
+/* --------------------------------------------------------------------
+ * Morphological Distance Feather Weights Key.
+ */
+
+MorphologicalDistanceFeatherWeightsKey::MorphologicalDistanceFeatherWeightsKey(int type,
+ float radius)
+ : type(type), radius(radius)
+{
+}
+
+uint64_t MorphologicalDistanceFeatherWeightsKey::hash() const
+{
+ return get_default_hash_2(type, radius);
+}
+
+bool operator==(const MorphologicalDistanceFeatherWeightsKey &a,
+ const MorphologicalDistanceFeatherWeightsKey &b)
+{
+ return a.type == b.type && a.radius == b.radius;
+}
+
+/* --------------------------------------------------------------------
+ * Morphological Distance Feather Weights.
+ */
+
+MorphologicalDistanceFeatherWeights::MorphologicalDistanceFeatherWeights(int type, int radius)
+{
+ compute_weights(radius);
+ compute_distance_falloffs(type, radius);
+}
+
+MorphologicalDistanceFeatherWeights::~MorphologicalDistanceFeatherWeights()
+{
+ GPU_texture_free(weights_texture_);
+ GPU_texture_free(distance_falloffs_texture_);
+}
+
+void MorphologicalDistanceFeatherWeights::compute_weights(int radius)
+{
+ /* The size of filter is double the radius plus 1, but since the filter is symmetric, we only
+ * compute half of it and no doubling happens. We add 1 to make sure the filter size is always
+ * odd and there is a center weight. */
+ const int size = radius + 1;
+ Array<float> weights(size);
+
+ float sum = 0.0f;
+
+ /* First, compute the center weight. */
+ const float center_weight = RE_filter_value(R_FILTER_GAUSS, 0.0f);
+ weights[0] = center_weight;
+ sum += center_weight;
+
+ /* Second, compute the other weights in the positive direction, making sure to add double the
+ * weight to the sum of weights because the filter is symmetric and we only loop over half of
+ * it. Skip the center weight already computed by dropping the front index. */
+ const float scale = radius > 0.0f ? 1.0f / radius : 0.0f;
+ for (const int i : weights.index_range().drop_front(1)) {
+ const float weight = RE_filter_value(R_FILTER_GAUSS, i * scale);
+ weights[i] = weight;
+ sum += weight * 2.0f;
+ }
+
+ /* Finally, normalize the weights. */
+ for (const int i : weights.index_range()) {
+ weights[i] /= sum;
+ }
+
+ weights_texture_ = GPU_texture_create_1d("Weights", size, 1, GPU_R16F, weights.data());
+}
+
+/* Computes a falloff that is equal to 1 at an input of zero and decrease to zero at an input of 1,
+ * with the rate of decrease depending on the falloff type. */
+static float compute_distance_falloff(int type, float x)
+{
+ x = 1.0f - x;
+
+ switch (type) {
+ case PROP_SMOOTH:
+ return 3.0f * x * x - 2.0f * x * x * x;
+ case PROP_SPHERE:
+ return std::sqrt(2.0f * x - x * x);
+ case PROP_ROOT:
+ return std::sqrt(x);
+ case PROP_SHARP:
+ return x * x;
+ case PROP_INVSQUARE:
+ return x * (2.0f - x);
+ case PROP_LIN:
+ return x;
+ default:
+ BLI_assert_unreachable();
+ return x;
+ }
+}
+
+void MorphologicalDistanceFeatherWeights::compute_distance_falloffs(int type, int radius)
+{
+ /* The size of the distance falloffs is double the radius plus 1, but since the falloffs are
+ * symmetric, we only compute half of them and no doubling happens. We add 1 to make sure the
+ * falloffs size is always odd and there is a center falloff. */
+ const int size = radius + 1;
+ Array<float> falloffs(size);
+
+ /* Compute the distance falloffs in the positive direction only, because the falloffs are
+ * symmetric. */
+ const float scale = radius > 0.0f ? 1.0f / radius : 0.0f;
+ for (const int i : falloffs.index_range()) {
+ falloffs[i] = compute_distance_falloff(type, i * scale);
+ }
+
+ distance_falloffs_texture_ = GPU_texture_create_1d(
+ "Distance Factors", size, 1, GPU_R16F, falloffs.data());
+}
+
+void MorphologicalDistanceFeatherWeights::bind_weights_as_texture(GPUShader *shader,
+ const char *texture_name) const
+{
+ const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name);
+ GPU_texture_bind(weights_texture_, texture_image_unit);
+}
+
+void MorphologicalDistanceFeatherWeights::unbind_weights_as_texture() const
+{
+ GPU_texture_unbind(weights_texture_);
+}
+
+void MorphologicalDistanceFeatherWeights::bind_distance_falloffs_as_texture(
+ GPUShader *shader, const char *texture_name) const
+{
+ const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name);
+ GPU_texture_bind(distance_falloffs_texture_, texture_image_unit);
+}
+
+void MorphologicalDistanceFeatherWeights::unbind_distance_falloffs_as_texture() const
+{
+ GPU_texture_unbind(distance_falloffs_texture_);
+}
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc
new file mode 100644
index 00000000000..a22d32a8e18
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <cstdint>
+
+#include "BLI_array.hh"
+#include "BLI_hash.hh"
+#include "BLI_index_range.hh"
+#include "BLI_math_vec_types.hh"
+#include "BLI_math_vector.hh"
+
+#include "RE_pipeline.h"
+
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "COM_symmetric_blur_weights.hh"
+
+namespace blender::realtime_compositor {
+
+/* --------------------------------------------------------------------
+ * Symmetric Blur Weights Key.
+ */
+
+SymmetricBlurWeightsKey::SymmetricBlurWeightsKey(int type, float2 radius)
+ : type(type), radius(radius)
+{
+}
+
+uint64_t SymmetricBlurWeightsKey::hash() const
+{
+ return get_default_hash_3(type, radius.x, radius.y);
+}
+
+bool operator==(const SymmetricBlurWeightsKey &a, const SymmetricBlurWeightsKey &b)
+{
+ return a.type == b.type && a.radius == b.radius;
+}
+
+/* --------------------------------------------------------------------
+ * Symmetric Blur Weights.
+ */
+
+SymmetricBlurWeights::SymmetricBlurWeights(int type, float2 radius)
+{
+ /* The full size of filter is double the radius plus 1, but since the filter is symmetric, we
+ * only compute a single quadrant of it and so no doubling happens. We add 1 to make sure the
+ * filter size is always odd and there is a center weight. */
+ const float2 scale = math::safe_divide(float2(1.0f), radius);
+ const int2 size = int2(math::ceil(radius)) + int2(1);
+ Array<float> weights(size.x * size.y);
+
+ float sum = 0.0f;
+
+ /* First, compute the center weight. */
+ const float center_weight = RE_filter_value(type, 0.0f);
+ weights[0] = center_weight;
+ sum += center_weight;
+
+ /* Then, compute the weights along the positive x axis, making sure to add double the weight to
+ * the sum of weights because the filter is symmetric and we only loop over the positive half
+ * of the x axis. Skip the center weight already computed by dropping the front index. */
+ for (const int x : IndexRange(size.x).drop_front(1)) {
+ const float weight = RE_filter_value(type, x * scale.x);
+ weights[x] = weight;
+ sum += weight * 2.0f;
+ }
+
+ /* Then, compute the weights along the positive y axis, making sure to add double the weight to
+ * the sum of weights because the filter is symmetric and we only loop over the positive half
+ * of the y axis. Skip the center weight already computed by dropping the front index. */
+ for (const int y : IndexRange(size.y).drop_front(1)) {
+ const float weight = RE_filter_value(type, y * scale.y);
+ weights[size.x * y] = weight;
+ sum += weight * 2.0f;
+ }
+
+ /* Then, compute the other weights in the upper right quadrant, making sure to add quadruple
+ * the weight to the sum of weights because the filter is symmetric and we only loop over one
+ * quadrant of it. Skip the weights along the y and x axis already computed by dropping the
+ * front index. */
+ for (const int y : IndexRange(size.y).drop_front(1)) {
+ for (const int x : IndexRange(size.x).drop_front(1)) {
+ const float weight = RE_filter_value(type, math::length(float2(x, y) * scale));
+ weights[size.x * y + x] = weight;
+ sum += weight * 4.0f;
+ }
+ }
+
+ /* Finally, normalize the weights. */
+ for (const int y : IndexRange(size.y)) {
+ for (const int x : IndexRange(size.x)) {
+ weights[size.x * y + x] /= sum;
+ }
+ }
+
+ texture_ = GPU_texture_create_2d("Weights", size.x, size.y, 1, GPU_R16F, weights.data());
+}
+
+SymmetricBlurWeights::~SymmetricBlurWeights()
+{
+ GPU_texture_free(texture_);
+}
+
+void SymmetricBlurWeights::bind_as_texture(GPUShader *shader, const char *texture_name) const
+{
+ const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name);
+ GPU_texture_bind(texture_, texture_image_unit);
+}
+
+void SymmetricBlurWeights::unbind_as_texture() const
+{
+ GPU_texture_unbind(texture_);
+}
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_separable_blur_weights.cc b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_separable_blur_weights.cc
new file mode 100644
index 00000000000..b8c47d5a5d0
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_separable_blur_weights.cc
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <cstdint>
+
+#include "BLI_array.hh"
+#include "BLI_hash.hh"
+#include "BLI_index_range.hh"
+#include "BLI_math_base.hh"
+
+#include "RE_pipeline.h"
+
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "COM_symmetric_separable_blur_weights.hh"
+
+namespace blender::realtime_compositor {
+
+/* --------------------------------------------------------------------
+ * Symmetric Separable Blur Weights Key.
+ */
+
+SymmetricSeparableBlurWeightsKey::SymmetricSeparableBlurWeightsKey(int type, float radius)
+ : type(type), radius(radius)
+{
+}
+
+uint64_t SymmetricSeparableBlurWeightsKey::hash() const
+{
+ return get_default_hash_2(type, radius);
+}
+
+bool operator==(const SymmetricSeparableBlurWeightsKey &a,
+ const SymmetricSeparableBlurWeightsKey &b)
+{
+ return a.type == b.type && a.radius == b.radius;
+}
+
+/* --------------------------------------------------------------------
+ * Symmetric Separable Blur Weights.
+ */
+
+SymmetricSeparableBlurWeights::SymmetricSeparableBlurWeights(int type, float radius)
+{
+ /* The size of filter is double the radius plus 1, but since the filter is symmetric, we only
+ * compute half of it and no doubling happens. We add 1 to make sure the filter size is always
+ * odd and there is a center weight. */
+ const int size = math::ceil(radius) + 1;
+ Array<float> weights(size);
+
+ float sum = 0.0f;
+
+ /* First, compute the center weight. */
+ const float center_weight = RE_filter_value(type, 0.0f);
+ weights[0] = center_weight;
+ sum += center_weight;
+
+ /* Second, compute the other weights in the positive direction, making sure to add double the
+ * weight to the sum of weights because the filter is symmetric and we only loop over half of
+ * it. Skip the center weight already computed by dropping the front index. */
+ const float scale = radius > 0.0f ? 1.0f / radius : 0.0f;
+ for (const int i : weights.index_range().drop_front(1)) {
+ const float weight = RE_filter_value(type, i * scale);
+ weights[i] = weight;
+ sum += weight * 2.0f;
+ }
+
+ /* Finally, normalize the weights. */
+ for (const int i : weights.index_range()) {
+ weights[i] /= sum;
+ }
+
+ texture_ = GPU_texture_create_1d("Weights", size, 1, GPU_R16F, weights.data());
+}
+
+SymmetricSeparableBlurWeights::~SymmetricSeparableBlurWeights()
+{
+ GPU_texture_free(texture_);
+}
+
+void SymmetricSeparableBlurWeights::bind_as_texture(GPUShader *shader,
+ const char *texture_name) const
+{
+ const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name);
+ GPU_texture_bind(texture_, texture_image_unit);
+}
+
+void SymmetricSeparableBlurWeights::unbind_as_texture() const
+{
+ GPU_texture_unbind(texture_);
+}
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/intern/context.cc b/source/blender/compositor/realtime_compositor/intern/context.cc
index 64ac29af3d1..0b123a2c271 100644
--- a/source/blender/compositor/realtime_compositor/intern/context.cc
+++ b/source/blender/compositor/realtime_compositor/intern/context.cc
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "COM_context.hh"
+#include "COM_static_cache_manager.hh"
#include "COM_static_shader_manager.hh"
#include "COM_texture_pool.hh"
@@ -17,9 +18,8 @@ int Context::get_frame_number() const
float Context::get_time() const
{
- const float frame_number = static_cast<float>(get_frame_number());
- const float frame_rate = static_cast<float>(get_scene()->r.frs_sec) /
- static_cast<float>(get_scene()->r.frs_sec_base);
+ const float frame_number = float(get_frame_number());
+ const float frame_rate = float(get_scene()->r.frs_sec) / float(get_scene()->r.frs_sec_base);
return frame_number / frame_rate;
}
@@ -33,4 +33,9 @@ StaticShaderManager &Context::shader_manager()
return shader_manager_;
}
+StaticCacheManager &Context::cache_manager()
+{
+ return cache_manager_;
+}
+
} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc b/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc
index d6bf74ffbee..dd585aedec6 100644
--- a/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc
+++ b/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc
@@ -12,9 +12,9 @@
namespace blender::realtime_compositor {
-/* -------------------------------------------------------------------------------------------------
- * Conversion Operation.
- */
+/* -------------------------------------------------------------------- */
+/** \name Conversion Operation
+ * \{ */
void ConversionOperation::execute()
{
@@ -79,9 +79,11 @@ SimpleOperation *ConversionOperation::construct_if_needed(Context &context,
return nullptr;
}
-/* -------------------------------------------------------------------------------------------------
- * Convert Float To Vector Operation.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Float to Vector Operation
+ * \{ */
ConvertFloatToVectorOperation::ConvertFloatToVectorOperation(Context &context)
: ConversionOperation(context)
@@ -94,7 +96,7 @@ ConvertFloatToVectorOperation::ConvertFloatToVectorOperation(Context &context)
void ConvertFloatToVectorOperation::execute_single(const Result &input, Result &output)
{
- output.set_vector_value(float3(input.get_float_value()));
+ output.set_vector_value(float4(float3(input.get_float_value()), 0.0f));
}
GPUShader *ConvertFloatToVectorOperation::get_conversion_shader() const
@@ -102,9 +104,11 @@ GPUShader *ConvertFloatToVectorOperation::get_conversion_shader() const
return shader_manager().get("compositor_convert_float_to_vector");
}
-/* -------------------------------------------------------------------------------------------------
- * Convert Float To Color Operation.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Float to Color Operation
+ * \{ */
ConvertFloatToColorOperation::ConvertFloatToColorOperation(Context &context)
: ConversionOperation(context)
@@ -127,9 +131,11 @@ GPUShader *ConvertFloatToColorOperation::get_conversion_shader() const
return shader_manager().get("compositor_convert_float_to_color");
}
-/* -------------------------------------------------------------------------------------------------
- * Convert Color To Float Operation.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Color to Float Operation
+ * \{ */
ConvertColorToFloatOperation::ConvertColorToFloatOperation(Context &context)
: ConversionOperation(context)
@@ -151,9 +157,11 @@ GPUShader *ConvertColorToFloatOperation::get_conversion_shader() const
return shader_manager().get("compositor_convert_color_to_float");
}
-/* -------------------------------------------------------------------------------------------------
- * Convert Color To Vector Operation.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Color to Vector Operation
+ * \{ */
ConvertColorToVectorOperation::ConvertColorToVectorOperation(Context &context)
: ConversionOperation(context)
@@ -167,7 +175,7 @@ ConvertColorToVectorOperation::ConvertColorToVectorOperation(Context &context)
void ConvertColorToVectorOperation::execute_single(const Result &input, Result &output)
{
float4 color = input.get_color_value();
- output.set_vector_value(float3(color));
+ output.set_vector_value(float4(float3(color), 0.0f));
}
GPUShader *ConvertColorToVectorOperation::get_conversion_shader() const
@@ -175,9 +183,11 @@ GPUShader *ConvertColorToVectorOperation::get_conversion_shader() const
return shader_manager().get("compositor_convert_color_to_vector");
}
-/* -------------------------------------------------------------------------------------------------
- * Convert Vector To Float Operation.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Vector to Float Operation
+ * \{ */
ConvertVectorToFloatOperation::ConvertVectorToFloatOperation(Context &context)
: ConversionOperation(context)
@@ -190,7 +200,7 @@ ConvertVectorToFloatOperation::ConvertVectorToFloatOperation(Context &context)
void ConvertVectorToFloatOperation::execute_single(const Result &input, Result &output)
{
- float3 vector = input.get_vector_value();
+ float4 vector = input.get_vector_value();
output.set_float_value((vector[0] + vector[1] + vector[2]) / 3.0f);
}
@@ -199,9 +209,11 @@ GPUShader *ConvertVectorToFloatOperation::get_conversion_shader() const
return shader_manager().get("compositor_convert_vector_to_float");
}
-/* -------------------------------------------------------------------------------------------------
- * Convert Vector To Color Operation.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Vector to Color Operation
+ * \{ */
ConvertVectorToColorOperation::ConvertVectorToColorOperation(Context &context)
: ConversionOperation(context)
@@ -214,7 +226,7 @@ ConvertVectorToColorOperation::ConvertVectorToColorOperation(Context &context)
void ConvertVectorToColorOperation::execute_single(const Result &input, Result &output)
{
- output.set_color_value(float4(input.get_vector_value(), 1.0f));
+ output.set_color_value(float4(float3(input.get_vector_value()), 1.0f));
}
GPUShader *ConvertVectorToColorOperation::get_conversion_shader() const
@@ -222,4 +234,6 @@ GPUShader *ConvertVectorToColorOperation::get_conversion_shader() const
return shader_manager().get("compositor_convert_vector_to_color");
}
+/** \} */
+
} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/intern/evaluator.cc b/source/blender/compositor/realtime_compositor/intern/evaluator.cc
index 48457bec199..1cd7d4f8951 100644
--- a/source/blender/compositor/realtime_compositor/intern/evaluator.cc
+++ b/source/blender/compositor/realtime_compositor/intern/evaluator.cc
@@ -28,6 +28,7 @@ Evaluator::Evaluator(Context &context, bNodeTree &node_tree)
void Evaluator::evaluate()
{
+ context_.cache_manager().reset();
context_.texture_pool().reset();
if (!is_compiled_) {
diff --git a/source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc b/source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc
index b3cc86b5f79..99f7cd90557 100644
--- a/source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc
+++ b/source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc
@@ -38,7 +38,7 @@ void InputSingleValueOperation::execute()
break;
case ResultType::Vector:
result.set_vector_value(
- float3(bsocket->default_value_typed<bNodeSocketValueVector>()->value));
+ float4(float3(bsocket->default_value_typed<bNodeSocketValueVector>()->value), 0.0f));
break;
case ResultType::Color:
result.set_color_value(float4(bsocket->default_value_typed<bNodeSocketValueRGBA>()->value));
diff --git a/source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc b/source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc
index 817293c0fa6..e5c448d0e33 100644
--- a/source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc
+++ b/source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc
@@ -38,8 +38,8 @@ void RealizeOnDomainOperation::execute()
GPU_shader_bind(shader);
/* Transform the input space into the domain space. */
- const float3x3 local_transformation = input.domain().transformation *
- domain_.transformation.inverted();
+ const float3x3 local_transformation = domain_.transformation.inverted() *
+ input.domain().transformation;
/* Set the origin of the transformation to be the center of the domain. */
const float3x3 transformation = float3x3::from_origin_transformation(
diff --git a/source/blender/compositor/realtime_compositor/intern/result.cc b/source/blender/compositor/realtime_compositor/intern/result.cc
index 8059367d211..d89f1c86167 100644
--- a/source/blender/compositor/realtime_compositor/intern/result.cc
+++ b/source/blender/compositor/realtime_compositor/intern/result.cc
@@ -62,7 +62,7 @@ void Result::allocate_invalid()
set_float_value(0.0f);
break;
case ResultType::Vector:
- set_vector_value(float3(0.0f));
+ set_vector_value(float4(0.0f));
break;
case ResultType::Color:
set_color_value(float4(0.0f));
@@ -125,7 +125,7 @@ float Result::get_float_value() const
return float_value_;
}
-float3 Result::get_vector_value() const
+float4 Result::get_vector_value() const
{
return vector_value_;
}
@@ -143,7 +143,7 @@ float Result::get_float_value_default(float default_value) const
return default_value;
}
-float3 Result::get_vector_value_default(const float3 &default_value) const
+float4 Result::get_vector_value_default(const float4 &default_value) const
{
if (is_single_value()) {
return get_vector_value();
@@ -165,7 +165,7 @@ void Result::set_float_value(float value)
GPU_texture_update(texture_, GPU_DATA_FLOAT, &float_value_);
}
-void Result::set_vector_value(const float3 &value)
+void Result::set_vector_value(const float4 &value)
{
vector_value_ = value;
GPU_texture_update(texture_, GPU_DATA_FLOAT, vector_value_);
diff --git a/source/blender/compositor/realtime_compositor/intern/scheduler.cc b/source/blender/compositor/realtime_compositor/intern/scheduler.cc
index ac5cc55a73f..0d3cce7af39 100644
--- a/source/blender/compositor/realtime_compositor/intern/scheduler.cc
+++ b/source/blender/compositor/realtime_compositor/intern/scheduler.cc
@@ -8,6 +8,7 @@
#include "NOD_derived_node_tree.hh"
+#include "BKE_node.h"
#include "BKE_node_runtime.hh"
#include "COM_scheduler.hh"
@@ -17,36 +18,103 @@ namespace blender::realtime_compositor {
using namespace nodes::derived_node_tree_types;
-/* Compute the output node whose result should be computed. The output node is the node marked as
- * NODE_DO_OUTPUT. If multiple types of output nodes are marked, then the preference will be
- * CMP_NODE_COMPOSITE > CMP_NODE_VIEWER > CMP_NODE_SPLITVIEWER. If no output node exists, a null
- * node will be returned. */
-static DNode compute_output_node(DerivedNodeTree &tree)
+/* Find the active context from the given context and its descendants contexts. The active context
+ * is the one whose node instance key matches the active_viewer_key stored in the root node tree.
+ * The instance key of each context is computed by calling BKE_node_instance_key given the key of
+ * the parent as well as the group node making the context. */
+static const DTreeContext *find_active_context_recursive(const DTreeContext *context,
+ bNodeInstanceKey key)
{
- const bNodeTree &root_tree = tree.root_context().btree();
+ /* The instance key of the given context matches the active viewer instance key, so this is the
+ * active context, return it. */
+ if (key.value == context->derived_tree().root_context().btree().active_viewer_key.value) {
+ return context;
+ }
+
+ /* For each of the group nodes, compute their instance key and contexts and call this function
+ * recursively. */
+ for (const bNode *group_node : context->btree().group_nodes()) {
+ const bNodeInstanceKey child_key = BKE_node_instance_key(key, &context->btree(), group_node);
+ const DTreeContext *child_context = context->child_context(*group_node);
+ const DTreeContext *found_context = find_active_context_recursive(child_context, child_key);
+
+ /* If the found context is null, that means neither the child context nor one of its descendant
+ * contexts is active. */
+ if (!found_context) {
+ continue;
+ }
+
+ /* Otherwise, we have found our active context, return it. */
+ return found_context;
+ }
+
+ /* Neither the given context nor one of its descendant contexts is active, so return null. */
+ return nullptr;
+}
+
+/* Find the active context for the given node tree. The active context represents the node tree
+ * currently being edited. In most cases, that would be the top level node tree itself, but in the
+ * case where the user is editing the node tree of a node group, the active context would be a
+ * representation of the node tree of that node group. Note that the context also stores the group
+ * node that the user selected to edit the node tree, so the context fully represents a particular
+ * instance of the node group. */
+static const DTreeContext *find_active_context(const DerivedNodeTree &tree)
+{
+ /* The root context has an instance key of NODE_INSTANCE_KEY_BASE by definition. */
+ return find_active_context_recursive(&tree.root_context(), NODE_INSTANCE_KEY_BASE);
+}
+
+/* Return the output node which is marked as NODE_DO_OUTPUT. If multiple types of output nodes are
+ * marked, then the preference will be CMP_NODE_COMPOSITE > CMP_NODE_VIEWER > CMP_NODE_SPLITVIEWER.
+ * If no output node exists, a null node will be returned. */
+static DNode find_output_in_context(const DTreeContext *context)
+{
+ const bNodeTree &tree = context->btree();
- for (const bNode *node : root_tree.nodes_by_type("CompositorNodeComposite")) {
+ for (const bNode *node : tree.nodes_by_type("CompositorNodeComposite")) {
if (node->flag & NODE_DO_OUTPUT) {
- return DNode(&tree.root_context(), node);
+ return DNode(context, node);
}
}
- for (const bNode *node : root_tree.nodes_by_type("CompositorNodeViewer")) {
+ for (const bNode *node : tree.nodes_by_type("CompositorNodeViewer")) {
if (node->flag & NODE_DO_OUTPUT) {
- return DNode(&tree.root_context(), node);
+ return DNode(context, node);
}
}
- for (const bNode *node : root_tree.nodes_by_type("CompositorNodeSplitViewer")) {
+ for (const bNode *node : tree.nodes_by_type("CompositorNodeSplitViewer")) {
if (node->flag & NODE_DO_OUTPUT) {
- return DNode(&tree.root_context(), node);
+ return DNode(context, node);
}
}
- /* No output node found, return a null node. */
return DNode();
}
+/* Compute the output node whose result should be computed. This node is the output node that
+ * satisfies the requirements in the find_output_in_context function. First, the active context is
+ * searched for an output node, if non was found, the root context is search. For more information
+ * on what contexts mean here, see the find_active_context function. */
+static DNode compute_output_node(const DerivedNodeTree &tree)
+{
+ const DTreeContext *active_context = find_active_context(tree);
+
+ const DNode node = find_output_in_context(active_context);
+ if (node) {
+ return node;
+ }
+
+ /* If the active context is the root one and no output node was found, we consider this node tree
+ * to have no output node, even if one of the non-active descendants have an output node. */
+ if (active_context->is_root()) {
+ return DNode();
+ }
+
+ /* The active context doesn't have an output node, search in the root context as a fallback. */
+ return find_output_in_context(&tree.root_context());
+}
+
/* A type representing a mapping that associates each node with a heuristic estimation of the
* number of intermediate buffers needed to compute it and all of its dependencies. See the
* compute_number_of_needed_buffers function for more information. */
@@ -225,7 +293,7 @@ static NeededBuffers compute_number_of_needed_buffers(DNode output_node)
* doesn't always guarantee an optimal evaluation order, as the optimal evaluation order is very
* difficult to compute, however, this method works well in most cases. Moreover it assumes that
* all buffers will have roughly the same size, which may not always be the case. */
-Schedule compute_schedule(DerivedNodeTree &tree)
+Schedule compute_schedule(const DerivedNodeTree &tree)
{
Schedule schedule;
diff --git a/source/blender/compositor/realtime_compositor/intern/shader_operation.cc b/source/blender/compositor/realtime_compositor/intern/shader_operation.cc
index 8e52baf63ec..88efdae1872 100644
--- a/source/blender/compositor/realtime_compositor/intern/shader_operation.cc
+++ b/source/blender/compositor/realtime_compositor/intern/shader_operation.cc
@@ -273,7 +273,7 @@ static const char *get_store_function_name(ResultType type)
void ShaderOperation::populate_operation_result(DOutputSocket output_socket, GPUMaterial *material)
{
- const unsigned int output_id = output_sockets_to_output_identifiers_map_.size();
+ const uint output_id = output_sockets_to_output_identifiers_map_.size();
std::string output_identifier = "output" + std::to_string(output_id);
const ResultType result_type = get_node_socket_result_type(output_socket.bsocket());
diff --git a/source/blender/compositor/realtime_compositor/intern/static_cache_manager.cc b/source/blender/compositor/realtime_compositor/intern/static_cache_manager.cc
new file mode 100644
index 00000000000..da78412a815
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/intern/static_cache_manager.cc
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <memory>
+
+#include "BLI_math_vec_types.hh"
+
+#include "COM_morphological_distance_feather_weights.hh"
+#include "COM_symmetric_blur_weights.hh"
+#include "COM_symmetric_separable_blur_weights.hh"
+
+#include "COM_static_cache_manager.hh"
+
+namespace blender::realtime_compositor {
+
+/* --------------------------------------------------------------------
+ * Static Cache Manager.
+ */
+
+void StaticCacheManager::reset()
+{
+ /* First, delete all resources that are no longer needed. */
+ symmetric_blur_weights_.remove_if([](auto item) { return !item.value->needed; });
+ symmetric_separable_blur_weights_.remove_if([](auto item) { return !item.value->needed; });
+ morphological_distance_feather_weights_.remove_if([](auto item) { return !item.value->needed; });
+
+ /* Second, reset the needed status of the remaining resources to false to ready them to track
+ * their needed status for the next evaluation. */
+ for (auto &value : symmetric_blur_weights_.values()) {
+ value->needed = false;
+ }
+ for (auto &value : symmetric_separable_blur_weights_.values()) {
+ value->needed = false;
+ }
+ for (auto &value : morphological_distance_feather_weights_.values()) {
+ value->needed = false;
+ }
+}
+
+SymmetricBlurWeights &StaticCacheManager::get_symmetric_blur_weights(int type, float2 radius)
+{
+ const SymmetricBlurWeightsKey key(type, radius);
+
+ auto &weights = *symmetric_blur_weights_.lookup_or_add_cb(
+ key, [&]() { return std::make_unique<SymmetricBlurWeights>(type, radius); });
+
+ weights.needed = true;
+ return weights;
+}
+
+SymmetricSeparableBlurWeights &StaticCacheManager::get_symmetric_separable_blur_weights(
+ int type, float radius)
+{
+ const SymmetricSeparableBlurWeightsKey key(type, radius);
+
+ auto &weights = *symmetric_separable_blur_weights_.lookup_or_add_cb(
+ key, [&]() { return std::make_unique<SymmetricSeparableBlurWeights>(type, radius); });
+
+ weights.needed = true;
+ return weights;
+}
+
+MorphologicalDistanceFeatherWeights &StaticCacheManager::
+ get_morphological_distance_feather_weights(int type, int radius)
+{
+ const MorphologicalDistanceFeatherWeightsKey key(type, radius);
+
+ auto &weights = *morphological_distance_feather_weights_.lookup_or_add_cb(
+ key, [&]() { return std::make_unique<MorphologicalDistanceFeatherWeights>(type, radius); });
+
+ weights.needed = true;
+ return weights;
+}
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/intern/texture_pool.cc b/source/blender/compositor/realtime_compositor/intern/texture_pool.cc
index 1568970a030..4b476574d72 100644
--- a/source/blender/compositor/realtime_compositor/intern/texture_pool.cc
+++ b/source/blender/compositor/realtime_compositor/intern/texture_pool.cc
@@ -13,9 +13,9 @@
namespace blender::realtime_compositor {
-/* --------------------------------------------------------------------
- * Texture Pool Key.
- */
+/* -------------------------------------------------------------------- */
+/** \name Texture Pool Key
+ * \{ */
TexturePoolKey::TexturePoolKey(int2 size, eGPUTextureFormat format) : size(size), format(format)
{
@@ -37,9 +37,11 @@ bool operator==(const TexturePoolKey &a, const TexturePoolKey &b)
return a.size == b.size && a.format == b.format;
}
-/* --------------------------------------------------------------------
- * Texture Pool.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Texture Pool
+ * \{ */
GPUTexture *TexturePool::acquire(int2 size, eGPUTextureFormat format)
{
@@ -62,7 +64,7 @@ GPUTexture *TexturePool::acquire_color(int2 size)
GPUTexture *TexturePool::acquire_vector(int2 size)
{
- /* Vectors are stored in RGBA textures because RGB textures have limited support. */
+ /* Vectors are 4D, and are thus stored in RGBA textures. */
return acquire(size, GPU_RGBA16F);
}
@@ -81,4 +83,6 @@ void TexturePool::reset()
textures_.clear();
}
+/** \} */
+
} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/intern/utilities.cc b/source/blender/compositor/realtime_compositor/intern/utilities.cc
index 1a5823b8441..25472d6ed50 100644
--- a/source/blender/compositor/realtime_compositor/intern/utilities.cc
+++ b/source/blender/compositor/realtime_compositor/intern/utilities.cc
@@ -71,7 +71,7 @@ bool is_output_linked_to_node_conditioned(DOutputSocket output, FunctionRef<bool
{
bool condition_satisfied = false;
output.foreach_target_socket(
- [&](DInputSocket target, const TargetSocketPathInfo &UNUSED(path_info)) {
+ [&](DInputSocket target, const TargetSocketPathInfo & /*path_info*/) {
if (condition(target.node())) {
condition_satisfied = true;
return;
@@ -85,7 +85,7 @@ int number_of_inputs_linked_to_output_conditioned(DOutputSocket output,
{
int count = 0;
output.foreach_target_socket(
- [&](DInputSocket target, const TargetSocketPathInfo &UNUSED(path_info)) {
+ [&](DInputSocket target, const TargetSocketPathInfo & /*path_info*/) {
if (condition(target)) {
count++;
}
diff --git a/source/blender/gpu/shaders/compositor/compositor_alpha_crop.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_alpha_crop.glsl
index d55c8efd4c6..d55c8efd4c6 100644
--- a/source/blender/gpu/shaders/compositor/compositor_alpha_crop.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_alpha_crop.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_bilateral_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_bilateral_blur.glsl
index c7c5ada7a9f..c7c5ada7a9f 100644
--- a/source/blender/gpu/shaders/compositor/compositor_bilateral_blur.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_bilateral_blur.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_blur.glsl
index 4f981c84f59..c7ac620f99b 100644
--- a/source/blender/gpu/shaders/compositor/compositor_blur.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_blur.glsl
@@ -18,13 +18,24 @@ vec4 load_input(ivec2 texel)
}
/* Given the texel in the range [-radius, radius] in both axis, load the appropriate weight from
- * the weights texture, where the texel (0, 0) is considered the center of weights texture. */
+ * the weights texture, where the given texel (0, 0) corresponds the center of weights texture.
+ * Note that we load the weights texture inverted along both directions to maintain the shape of
+ * the weights if it was not symmetrical. To understand why inversion makes sense, consider a 1D
+ * weights texture whose right half is all ones and whose left half is all zeros. Further, consider
+ * that we are blurring a single white pixel on a black background. When computing the value of a
+ * pixel that is to the right of the white pixel, the white pixel will be in the left region of the
+ * search window, and consequently, without inversion, a zero will be sampled from the left side of
+ * the weights texture and result will be zero. However, what we expect is that pixels to the right
+ * of the white pixel will be white, that is, they should sample a weight of 1 from the right side
+ * of the weights texture, hence the need for inversion. */
vec4 load_weight(ivec2 texel)
{
- /* Add the radius to transform the texel into the range [0, radius * 2], then divide by the upper
- * bound plus one to transform the texel into the normalized range [0, 1] needed to sample the
- * weights sampler. Finally, also add 0.5 to sample at the center of the pixels. */
- return texture(weights_tx, (texel + vec2(radius + 0.5)) / (radius * 2 + 1));
+ /* Add the radius to transform the texel into the range [0, radius * 2], with an additional 0.5
+ * to sample at the center of the pixels, then divide by the upper bound plus one to transform
+ * the texel into the normalized range [0, 1] needed to sample the weights sampler. Finally,
+ * invert the textures coordinates by subtracting from 1 to maintain the shape of the weights as
+ * mentioned in the function description. */
+ return texture(weights_tx, 1.0 - ((texel + vec2(radius + 0.5)) / (radius * 2 + 1)));
}
void main()
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_blur_variable_size.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_blur_variable_size.glsl
new file mode 100644
index 00000000000..9383bbf9825
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_blur_variable_size.glsl
@@ -0,0 +1,71 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+/* Given the texel in the range [-radius, radius] in both axis, load the appropriate weight from
+ * the weights texture, where the given texel (0, 0) corresponds the center of weights texture.
+ * Note that we load the weights texture inverted along both directions to maintain the shape of
+ * the weights if it was not symmetrical. To understand why inversion makes sense, consider a 1D
+ * weights texture whose right half is all ones and whose left half is all zeros. Further, consider
+ * that we are blurring a single white pixel on a black background. When computing the value of a
+ * pixel that is to the right of the white pixel, the white pixel will be in the left region of the
+ * search window, and consequently, without inversion, a zero will be sampled from the left side of
+ * the weights texture and result will be zero. However, what we expect is that pixels to the right
+ * of the white pixel will be white, that is, they should sample a weight of 1 from the right side
+ * of the weights texture, hence the need for inversion. */
+vec4 load_weight(ivec2 texel, float radius)
+{
+ /* The center zero texel is always assigned a unit weight regardless of the corresponding weight
+ * in the weights texture. That's to guarantee that at last the center pixel will be accumulated
+ * even if the weights texture is zero at its center. */
+ if (texel == ivec2(0)) {
+ return vec4(1.0);
+ }
+
+ /* Add the radius to transform the texel into the range [0, radius * 2], with an additional 0.5
+ * to sample at the center of the pixels, then divide by the upper bound plus one to transform
+ * the texel into the normalized range [0, 1] needed to sample the weights sampler. Finally,
+ * invert the textures coordinates by subtracting from 1 to maintain the shape of the weights as
+ * mentioned in the function description. */
+ return texture(weights_tx, 1.0 - ((texel + vec2(radius + 0.5)) / (radius * 2 + 1)));
+}
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* The mask input is treated as a boolean. If it is zero, then no blurring happens for this
+ * pixel. Otherwise, the pixel is blurred normally and the mask value is irrelevant. */
+ float mask = texture_load(mask_tx, texel).x;
+ if (mask == 0.0) {
+ imageStore(output_img, texel, texture_load(input_tx, texel));
+ return;
+ }
+
+ float center_size = texture_load(size_tx, texel).x * base_size;
+
+ /* Go over the window of the given search radius and accumulate the colors multiplied by their
+ * respective weights as well as the weights themselves, but only if both the size of the center
+ * pixel and the size of the candidate pixel are less than both the x and y distances of the
+ * candidate pixel. */
+ vec4 accumulated_color = vec4(0.0);
+ vec4 accumulated_weight = vec4(0.0);
+ for (int y = -search_radius; y <= search_radius; y++) {
+ for (int x = -search_radius; x <= search_radius; x++) {
+ float candidate_size = texture_load(size_tx, texel + ivec2(x, y)).x * base_size;
+
+ /* Skip accumulation if either the x or y distances of the candidate pixel are larger than
+ * either the center or candidate pixel size. Note that the max and min functions here denote
+ * "either" in the aforementioned description. */
+ float size = min(center_size, candidate_size);
+ if (max(abs(x), abs(y)) > size) {
+ continue;
+ }
+
+ vec4 weight = load_weight(ivec2(x, y), size);
+ accumulated_color += texture_load(input_tx, texel + ivec2(x, y)) * weight;
+ accumulated_weight += weight;
+ }
+ }
+
+ imageStore(output_img, texel, safe_divide(accumulated_color, accumulated_weight));
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_bokeh_image.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_bokeh_image.glsl
index 6e98aa9fe17..6e98aa9fe17 100644
--- a/source/blender/gpu/shaders/compositor/compositor_bokeh_image.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_bokeh_image.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_box_mask.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_box_mask.glsl
index fad23f28fde..fad23f28fde 100644
--- a/source/blender/gpu/shaders/compositor/compositor_box_mask.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_box_mask.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_convert.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_convert.glsl
index 044fb057ca5..044fb057ca5 100644
--- a/source/blender/gpu/shaders/compositor/compositor_convert.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_convert.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_despeckle.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_despeckle.glsl
index e4743d69d17..e4743d69d17 100644
--- a/source/blender/gpu/shaders/compositor/compositor_despeckle.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_despeckle.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_directional_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_directional_blur.glsl
index 1805cb5a7f5..1805cb5a7f5 100644
--- a/source/blender/gpu/shaders/compositor/compositor_directional_blur.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_directional_blur.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_edge_filter.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_edge_filter.glsl
index 67e27c22602..67e27c22602 100644
--- a/source/blender/gpu/shaders/compositor/compositor_edge_filter.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_edge_filter.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_ellipse_mask.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_ellipse_mask.glsl
index 28f725067e0..28f725067e0 100644
--- a/source/blender/gpu/shaders/compositor/compositor_ellipse_mask.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_ellipse_mask.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_filter.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_filter.glsl
index e501c563dda..e501c563dda 100644
--- a/source/blender/gpu/shaders/compositor/compositor_filter.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_filter.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_flip.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_flip.glsl
index 919c454ee63..919c454ee63 100644
--- a/source/blender/gpu/shaders/compositor/compositor_flip.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_flip.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_image_crop.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_image_crop.glsl
index f20e033dee4..f20e033dee4 100644
--- a/source/blender/gpu/shaders/compositor/compositor_image_crop.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_image_crop.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_morphological_distance.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance.glsl
index 09f896b7a9d..09f896b7a9d 100644
--- a/source/blender/gpu/shaders/compositor/compositor_morphological_distance.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_morphological_distance_feather.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_feather.glsl
index acdd8a40342..acdd8a40342 100644
--- a/source/blender/gpu/shaders/compositor/compositor_morphological_distance_feather.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_feather.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_morphological_distance_threshold.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_threshold.glsl
index e6625e7419f..e6625e7419f 100644
--- a/source/blender/gpu/shaders/compositor/compositor_morphological_distance_threshold.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_threshold.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_morphological_step.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_step.glsl
index 6992bc2afa5..6992bc2afa5 100644
--- a/source/blender/gpu/shaders/compositor/compositor_morphological_step.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_step.glsl
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_normalize.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_normalize.glsl
new file mode 100644
index 00000000000..53dfeb01730
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_normalize.glsl
@@ -0,0 +1,10 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+ float value = texture_load(input_tx, texel).x;
+ float normalized_value = (value - minimum) * scale;
+ float clamped_value = clamp(normalized_value, 0.0, 1.0);
+ imageStore(output_img, texel, vec4(clamped_value));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_parallel_reduction.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_parallel_reduction.glsl
new file mode 100644
index 00000000000..f6f84aa24c1
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_parallel_reduction.glsl
@@ -0,0 +1,98 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+/* This shader reduces the given texture into a smaller texture of a size equal to the number of
+ * work groups. In particular, each work group reduces its contents into a single value and writes
+ * that value to a single pixel in the output image. The shader can be dispatched multiple times to
+ * eventually reduce the image into a single pixel.
+ *
+ * The shader works by loading the whole data of each work group into a linear array, then it
+ * reduces the second half of the array onto the first half of the array, then it reduces the
+ * second quarter of the array onto the first quarter or the array, and so on until only one
+ * element remains. The following figure illustrates the process for sum reduction on 8 elements.
+ *
+ * .---. .---. .---. .---. .---. .---. .---. .---.
+ * | 0 | | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | Original data.
+ * '---' '---' '---' '---' '---' '---' '---' '---'
+ * |.____|_____|_____|_____| | | |
+ * || |.____|_____|___________| | |
+ * || || |.____|_________________| |
+ * || || || |.______________________| <--First reduction. Stride = 4.
+ * || || || ||
+ * .---. .---. .---. .----.
+ * | 4 | | 6 | | 8 | | 10 | <--Data after first reduction.
+ * '---' '---' '---' '----'
+ * |.____|_____| |
+ * || |.__________| <--Second reduction. Stride = 2.
+ * || ||
+ * .----. .----.
+ * | 12 | | 16 | <--Data after second reduction.
+ * '----' '----'
+ * |.____|
+ * || <--Third reduction. Stride = 1.
+ * .----.
+ * | 28 |
+ * '----' <--Data after third reduction.
+ *
+ *
+ * The shader is generic enough to implement many types of reductions. This is done by using macros
+ * that the developer should define to implement a certain reduction operation. Those include,
+ * TYPE, IDENTITY, INITIALIZE, LOAD, and REDUCE. See the implementation below for more information
+ * as well as the compositor_parallel_reduction_info.hh for example reductions operations. */
+
+/* Doing the reduction in shared memory is faster, so create a shared array where the whole data
+ * of the work group will be loaded and reduced. The 2D structure of the work group is irrelevant
+ * for reduction, so we just load the data in a 1D array to simplify reduction. The developer is
+ * expected to define the TYPE macro to be a float or a vec4, depending on the type of data being
+ * reduced. */
+const uint reduction_size = gl_WorkGroupSize.x * gl_WorkGroupSize.y;
+shared TYPE reduction_data[reduction_size];
+
+void main()
+{
+ /* Load the data from the texture, while returning IDENTITY for out of bound coordinates. The
+ * developer is expected to define the IDENTITY macro to be a vec4 that does not affect the
+ * output of the reduction. For instance, sum reductions have an identity of vec4(0.0), while
+ * max value reductions have an identity of vec4(FLT_MIN). */
+ vec4 value = texture_load(input_tx, ivec2(gl_GlobalInvocationID.xy), IDENTITY);
+
+ /* Initialize the shared array given the previously loaded value. This step can be different
+ * depending on whether this is the initial reduction pass or a latter one. Indeed, the input
+ * texture for the initial reduction is the source texture itself, while the input texture to a
+ * latter reduction pass is an intermediate texture after one or more reductions have happened.
+ * This is significant because the data being reduced might be computed from the original data
+ * and different from it, for instance, when summing the luminance of an image, the original data
+ * is a vec4 color, while the reduced data is a float luminance value. So for the initial
+ * reduction pass, the luminance will be computed from the color, reduced, then stored into an
+ * intermediate float texture. On the other hand, for latter reduction passes, the luminance will
+ * be loaded directly and reduced without extra processing. So the developer is expected to
+ * define the INITIALIZE and LOAD macros to be expressions that derive the needed value from the
+ * loaded value for the initial reduction pass and latter ones respectively. */
+ reduction_data[gl_LocalInvocationIndex] = is_initial_reduction ? INITIALIZE(value) : LOAD(value);
+
+ /* Reduce the reduction data by half on every iteration until only one element remains. See the
+ * above figure for an intuitive understanding of the stride value. */
+ for (uint stride = reduction_size / 2; stride > 0; stride /= 2) {
+ barrier();
+
+ /* Only the threads up to the current stride should be active as can be seen in the diagram
+ * above. */
+ if (gl_LocalInvocationIndex >= stride) {
+ continue;
+ }
+
+ /* Reduce each two elements that are stride apart, writing the result to the element with the
+ * lower index, as can be seen in the diagram above. The developer is expected to define the
+ * REDUCE macro to be a commutative and associative binary operator suitable for parallel
+ * reduction. */
+ reduction_data[gl_LocalInvocationIndex] = REDUCE(
+ reduction_data[gl_LocalInvocationIndex], reduction_data[gl_LocalInvocationIndex + stride]);
+ }
+
+ /* Finally, the result of the reduction is available as the first element in the reduction data,
+ * write it to the pixel corresponding to the work group, making sure only the one thread writes
+ * it. */
+ barrier();
+ if (gl_LocalInvocationIndex == 0) {
+ imageStore(output_img, ivec2(gl_WorkGroupID.xy), vec4(reduction_data[0]));
+ }
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_projector_lens_distortion.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_projector_lens_distortion.glsl
index ab44dac93e6..ab44dac93e6 100644
--- a/source/blender/gpu/shaders/compositor/compositor_projector_lens_distortion.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_projector_lens_distortion.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_realize_on_domain.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_realize_on_domain.glsl
index b8561e5f059..b8561e5f059 100644
--- a/source/blender/gpu/shaders/compositor/compositor_realize_on_domain.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_realize_on_domain.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_screen_lens_distortion.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl
index dc572ea5aaf..dc572ea5aaf 100644
--- a/source/blender/gpu/shaders/compositor/compositor_screen_lens_distortion.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_set_alpha.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_set_alpha.glsl
index 7dd40581790..7dd40581790 100644
--- a/source/blender/gpu/shaders/compositor/compositor_set_alpha.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_set_alpha.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_split_viewer.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_split_viewer.glsl
index 866b9045da2..866b9045da2 100644
--- a/source/blender/gpu/shaders/compositor/compositor_split_viewer.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_split_viewer.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_symmetric_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur.glsl
index df08991a35c..df08991a35c 100644
--- a/source/blender/gpu/shaders/compositor/compositor_symmetric_blur.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur.glsl
diff --git a/source/blender/gpu/shaders/compositor/compositor_symmetric_separable_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_separable_blur.glsl
index ab0c7baa787..ab0c7baa787 100644
--- a/source/blender/gpu/shaders/compositor/compositor_symmetric_separable_blur.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_separable_blur.glsl
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_photoreceptor.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_photoreceptor.glsl
new file mode 100644
index 00000000000..167006585ca
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_photoreceptor.glsl
@@ -0,0 +1,22 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+/* Tone mapping based on equation (1) and the trilinear interpolation between equations (6) and (7)
+ * from Reinhard, Erik, and Kate Devlin. "Dynamic range reduction inspired by photoreceptor
+ * physiology." IEEE transactions on visualization and computer graphics 11.1 (2005): 13-24. */
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ vec4 input_color = texture_load(input_tx, texel);
+ float input_luminance = dot(input_color.rgb, luminance_coefficients);
+
+ /* Trilinear interpolation between equations (6) and (7) from Reinhard's 2005 paper. */
+ vec4 local_adaptation_level = mix(vec4(input_luminance), input_color, chromatic_adaptation);
+ vec4 adaptation_level = mix(global_adaptation_level, local_adaptation_level, light_adaptation);
+
+ /* Equation (1) from Reinhard's 2005 paper, assuming Vmax is 1. */
+ vec4 semi_saturation = pow(intensity * adaptation_level, vec4(contrast));
+ vec4 tone_mapped_color = input_color / (input_color + semi_saturation);
+
+ imageStore(output_img, texel, vec4(tone_mapped_color.rgb, input_color.a));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_simple.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_simple.glsl
new file mode 100644
index 00000000000..ce42d021dd1
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_simple.glsl
@@ -0,0 +1,26 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl)
+
+/* Tone mapping based on equation (3) from Reinhard, Erik, et al. "Photographic tone reproduction
+ * for digital images." Proceedings of the 29th annual conference on Computer graphics and
+ * interactive techniques. 2002. */
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ vec4 input_color = texture_load(input_tx, texel);
+
+ /* Equation (2) from Reinhard's 2002 paper. */
+ vec4 scaled_color = input_color * luminance_scale;
+
+ /* Equation (3) from Reinhard's 2002 paper, but with the 1 replaced with the blend factor for
+ * more flexibility. See ToneMapOperation::compute_luminance_scale_blend_factor. */
+ vec4 denominator = luminance_scale_blend_factor + scaled_color;
+ vec4 tone_mapped_color = safe_divide(scaled_color, denominator);
+
+ if (inverse_gamma != 0.0) {
+ tone_mapped_color = pow(max(tone_mapped_color, vec4(0.0)), vec4(inverse_gamma));
+ }
+
+ imageStore(output_img, texel, vec4(tone_mapped_color.rgb, input_color.a));
+}
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_alpha_crop_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_alpha_crop_info.hh
index 11f2f329cd8..11f2f329cd8 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_alpha_crop_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_alpha_crop_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_bilateral_blur_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_bilateral_blur_info.hh
index 301cd6acd9e..301cd6acd9e 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_bilateral_blur_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_bilateral_blur_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_blur_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_info.hh
index 36b772aa486..36b772aa486 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_blur_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_info.hh
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_variable_size_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_variable_size_info.hh
new file mode 100644
index 00000000000..05b6385fd1e
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_variable_size_info.hh
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_blur_variable_size)
+ .local_group_size(16, 16)
+ .push_constant(Type::FLOAT, "base_size")
+ .push_constant(Type::INT, "search_radius")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .sampler(1, ImageType::FLOAT_2D, "weights_tx")
+ .sampler(2, ImageType::FLOAT_2D, "size_tx")
+ .sampler(3, ImageType::FLOAT_2D, "mask_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_blur_variable_size.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_bokeh_image_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_bokeh_image_info.hh
index 3541de53070..3541de53070 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_bokeh_image_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_bokeh_image_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_box_mask_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_box_mask_info.hh
index ecb253bbab1..ecb253bbab1 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_box_mask_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_box_mask_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_convert_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_convert_info.hh
index 35e60056736..35e60056736 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_convert_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_convert_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_despeckle_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_despeckle_info.hh
index df86c3a8258..df86c3a8258 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_despeckle_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_despeckle_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_directional_blur_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_directional_blur_info.hh
index bb9199dcd26..bb9199dcd26 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_directional_blur_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_directional_blur_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_edge_filter_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_edge_filter_info.hh
index 916ec62bdba..916ec62bdba 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_edge_filter_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_edge_filter_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_ellipse_mask_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_ellipse_mask_info.hh
index 52db91c94e5..52db91c94e5 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_ellipse_mask_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_ellipse_mask_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_filter_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_filter_info.hh
index 9d565cf4b8a..9d565cf4b8a 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_filter_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_filter_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_flip_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_flip_info.hh
index db831518cb7..db831518cb7 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_flip_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_flip_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_image_crop_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_image_crop_info.hh
index e7736744c40..e7736744c40 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_image_crop_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_image_crop_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_morphological_distance_feather_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_feather_info.hh
index 9f17f60129d..9f17f60129d 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_morphological_distance_feather_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_feather_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_morphological_distance_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_info.hh
index fc960e119e5..fc960e119e5 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_morphological_distance_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_morphological_distance_threshold_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_threshold_info.hh
index b1d64f61b80..b1d64f61b80 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_morphological_distance_threshold_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_threshold_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_morphological_step_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_step_info.hh
index e97ffd9feea..e97ffd9feea 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_morphological_step_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_step_info.hh
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_normalize_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_normalize_info.hh
new file mode 100644
index 00000000000..02fdc424014
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_normalize_info.hh
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_normalize)
+ .local_group_size(16, 16)
+ .push_constant(Type::FLOAT, "minimum")
+ .push_constant(Type::FLOAT, "scale")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_normalize.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_parallel_reduction_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_parallel_reduction_info.hh
new file mode 100644
index 00000000000..e2252b14758
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_parallel_reduction_info.hh
@@ -0,0 +1,149 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_parallel_reduction_shared)
+ .local_group_size(16, 16)
+ .push_constant(Type::BOOL, "is_initial_reduction")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .compute_source("compositor_parallel_reduction.glsl");
+
+/* --------------------------------------------------------------------
+ * Sum Reductions.
+ */
+
+GPU_SHADER_CREATE_INFO(compositor_sum_shared)
+ .additional_info("compositor_parallel_reduction_shared")
+ .define("IDENTITY", "vec4(0.0)")
+ .define("REDUCE(lhs, rhs)", "lhs + rhs");
+
+GPU_SHADER_CREATE_INFO(compositor_sum_float_shared)
+ .additional_info("compositor_sum_shared")
+ .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("TYPE", "float")
+ .define("LOAD(value)", "value.x");
+
+GPU_SHADER_CREATE_INFO(compositor_sum_red)
+ .additional_info("compositor_sum_float_shared")
+ .define("INITIALIZE(value)", "value.r")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_sum_green)
+ .additional_info("compositor_sum_float_shared")
+ .define("INITIALIZE(value)", "value.g")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_sum_blue)
+ .additional_info("compositor_sum_float_shared")
+ .define("INITIALIZE(value)", "value.b")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_sum_luminance)
+ .additional_info("compositor_sum_float_shared")
+ .push_constant(Type::VEC3, "luminance_coefficients")
+ .define("INITIALIZE(value)", "dot(value.rgb, luminance_coefficients)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_sum_log_luminance)
+ .additional_info("compositor_sum_float_shared")
+ .push_constant(Type::VEC3, "luminance_coefficients")
+ .define("INITIALIZE(value)", "log(max(dot(value.rgb, luminance_coefficients), 1e-5))")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_sum_color)
+ .additional_info("compositor_sum_shared")
+ .image(0, GPU_RGBA32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("TYPE", "vec4")
+ .define("INITIALIZE(value)", "value")
+ .define("LOAD(value)", "value")
+ .do_static_compilation(true);
+
+/* --------------------------------------------------------------------
+ * Sum Of Squared Difference Reductions.
+ */
+
+GPU_SHADER_CREATE_INFO(compositor_sum_squared_difference_float_shared)
+ .additional_info("compositor_parallel_reduction_shared")
+ .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .push_constant(Type::FLOAT, "subtrahend")
+ .define("TYPE", "float")
+ .define("IDENTITY", "vec4(subtrahend)")
+ .define("LOAD(value)", "value.x")
+ .define("REDUCE(lhs, rhs)", "lhs + rhs");
+
+GPU_SHADER_CREATE_INFO(compositor_sum_red_squared_difference)
+ .additional_info("compositor_sum_squared_difference_float_shared")
+ .define("INITIALIZE(value)", "pow(value.r - subtrahend, 2.0)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_sum_green_squared_difference)
+ .additional_info("compositor_sum_squared_difference_float_shared")
+ .define("INITIALIZE(value)", "pow(value.g - subtrahend, 2.0)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_sum_blue_squared_difference)
+ .additional_info("compositor_sum_squared_difference_float_shared")
+ .define("INITIALIZE(value)", "pow(value.b - subtrahend, 2.0)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_sum_luminance_squared_difference)
+ .additional_info("compositor_sum_squared_difference_float_shared")
+ .push_constant(Type::VEC3, "luminance_coefficients")
+ .define("INITIALIZE(value)", "pow(dot(value.rgb, luminance_coefficients) - subtrahend, 2.0)")
+ .do_static_compilation(true);
+
+/* --------------------------------------------------------------------
+ * Maximum Reductions.
+ */
+
+GPU_SHADER_CREATE_INFO(compositor_maximum_luminance)
+ .additional_info("compositor_parallel_reduction_shared")
+ .typedef_source("common_math_lib.glsl")
+ .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .push_constant(Type::VEC3, "luminance_coefficients")
+ .define("TYPE", "float")
+ .define("IDENTITY", "vec4(FLT_MIN)")
+ .define("INITIALIZE(value)", "dot(value.rgb, luminance_coefficients)")
+ .define("LOAD(value)", "value.x")
+ .define("REDUCE(lhs, rhs)", "max(lhs, rhs)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_maximum_float_in_range)
+ .additional_info("compositor_parallel_reduction_shared")
+ .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .push_constant(Type::FLOAT, "lower_bound")
+ .push_constant(Type::FLOAT, "upper_bound")
+ .define("TYPE", "float")
+ .define("IDENTITY", "vec4(lower_bound)")
+ .define("INITIALIZE(v)", "((v.x <= upper_bound) && (v.x >= lower_bound)) ? v.x : lower_bound")
+ .define("LOAD(value)", "value.x")
+ .define("REDUCE(lhs, rhs)", "((rhs > lhs) && (rhs <= upper_bound)) ? rhs : lhs")
+ .do_static_compilation(true);
+
+/* --------------------------------------------------------------------
+ * Minimum Reductions.
+ */
+
+GPU_SHADER_CREATE_INFO(compositor_minimum_luminance)
+ .additional_info("compositor_parallel_reduction_shared")
+ .typedef_source("common_math_lib.glsl")
+ .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .push_constant(Type::VEC3, "luminance_coefficients")
+ .define("TYPE", "float")
+ .define("IDENTITY", "vec4(FLT_MAX)")
+ .define("INITIALIZE(value)", "dot(value.rgb, luminance_coefficients)")
+ .define("LOAD(value)", "value.x")
+ .define("REDUCE(lhs, rhs)", "min(lhs, rhs)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_minimum_float_in_range)
+ .additional_info("compositor_parallel_reduction_shared")
+ .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .push_constant(Type::FLOAT, "lower_bound")
+ .push_constant(Type::FLOAT, "upper_bound")
+ .define("TYPE", "float")
+ .define("IDENTITY", "vec4(upper_bound)")
+ .define("INITIALIZE(v)", "((v.x <= upper_bound) && (v.x >= lower_bound)) ? v.x : upper_bound")
+ .define("LOAD(value)", "value.x")
+ .define("REDUCE(lhs, rhs)", "((rhs < lhs) && (rhs >= lower_bound)) ? rhs : lhs")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_projector_lens_distortion_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_projector_lens_distortion_info.hh
index 98fe1731703..98fe1731703 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_projector_lens_distortion_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_projector_lens_distortion_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_realize_on_domain_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_realize_on_domain_info.hh
index 4528649ae98..4528649ae98 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_realize_on_domain_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_realize_on_domain_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_screen_lens_distortion_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_screen_lens_distortion_info.hh
index c42f2b328d4..c42f2b328d4 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_screen_lens_distortion_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_screen_lens_distortion_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_set_alpha_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_set_alpha_info.hh
index ca28194e921..ca28194e921 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_set_alpha_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_set_alpha_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_split_viewer_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_split_viewer_info.hh
index d5793b0ce59..d5793b0ce59 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_split_viewer_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_split_viewer_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_symmetric_blur_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_blur_info.hh
index 8ba2b4e04ef..8ba2b4e04ef 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_symmetric_blur_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_blur_info.hh
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_symmetric_separable_blur_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_separable_blur_info.hh
index 57247dba4b8..57247dba4b8 100644
--- a/source/blender/gpu/shaders/compositor/infos/compositor_symmetric_separable_blur_info.hh
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_separable_blur_info.hh
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_photoreceptor_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_photoreceptor_info.hh
new file mode 100644
index 00000000000..a460c9d58a6
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_photoreceptor_info.hh
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_tone_map_photoreceptor)
+ .local_group_size(16, 16)
+ .push_constant(Type::VEC4, "global_adaptation_level")
+ .push_constant(Type::FLOAT, "contrast")
+ .push_constant(Type::FLOAT, "intensity")
+ .push_constant(Type::FLOAT, "chromatic_adaptation")
+ .push_constant(Type::FLOAT, "light_adaptation")
+ .push_constant(Type::VEC3, "luminance_coefficients")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_tone_map_photoreceptor.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_simple_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_simple_info.hh
new file mode 100644
index 00000000000..2b220af9460
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_simple_info.hh
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_tone_map_simple)
+ .local_group_size(16, 16)
+ .push_constant(Type::FLOAT, "luminance_scale")
+ .push_constant(Type::FLOAT, "luminance_scale_blend_factor")
+ .push_constant(Type::FLOAT, "inverse_gamma")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_tone_map_simple.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_alpha_over.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_alpha_over.glsl
index 8e3e033147f..8e3e033147f 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_alpha_over.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_alpha_over.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_blur_common.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_blur_common.glsl
index e404c03bbb0..e404c03bbb0 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_blur_common.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_blur_common.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_bright_contrast.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_bright_contrast.glsl
index ce71b4fd8a4..ce71b4fd8a4 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_bright_contrast.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_bright_contrast.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_channel_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_channel_matte.glsl
index f2dcc9543f2..f2dcc9543f2 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_channel_matte.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_channel_matte.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_chroma_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_chroma_matte.glsl
index 5d6bea0c9db..5d6bea0c9db 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_chroma_matte.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_chroma_matte.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_balance.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_balance.glsl
index bffb94cdedb..bffb94cdedb 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_balance.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_balance.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_correction.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_correction.glsl
index 9b4858f03be..9b4858f03be 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_correction.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_correction.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_matte.glsl
index 038471bc1bc..038471bc1bc 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_matte.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_matte.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_spill.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_spill.glsl
index 0adad53ad80..0adad53ad80 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_spill.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_spill.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_to_luminance.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_to_luminance.glsl
index bcdd625bd4f..bcdd625bd4f 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_to_luminance.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_to_luminance.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_difference_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_difference_matte.glsl
index d769cadce3c..d769cadce3c 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_difference_matte.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_difference_matte.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_distance_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_distance_matte.glsl
index 9beed66826c..9beed66826c 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_distance_matte.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_distance_matte.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_exposure.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_exposure.glsl
index f246635a91e..f246635a91e 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_exposure.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_exposure.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_gamma.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_gamma.glsl
index 53070d4b0e2..53070d4b0e2 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_gamma.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_gamma.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_hue_correct.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_correct.glsl
index 99eb125cdf2..99eb125cdf2 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_hue_correct.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_correct.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_hue_saturation_value.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_saturation_value.glsl
index dd5eb33d318..dd5eb33d318 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_hue_saturation_value.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_saturation_value.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_invert.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_invert.glsl
index 59be746da7f..59be746da7f 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_invert.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_invert.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_luminance_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_luminance_matte.glsl
index 3647ac583fe..3647ac583fe 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_luminance_matte.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_luminance_matte.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_main.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_main.glsl
index 27624223dbc..27624223dbc 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_main.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_main.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_map_value.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_map_value.glsl
index 20874b4ef44..20874b4ef44 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_map_value.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_map_value.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_normal.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_normal.glsl
index a2e3b6c4aaa..a2e3b6c4aaa 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_normal.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_normal.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_posterize.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_posterize.glsl
index ee8ae234abe..ee8ae234abe 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_posterize.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_posterize.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_separate_combine.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_separate_combine.glsl
index d72d2260394..d72d2260394 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_separate_combine.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_separate_combine.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_set_alpha.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_set_alpha.glsl
index 95380d1ed0f..95380d1ed0f 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_set_alpha.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_set_alpha.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_store_output.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_store_output.glsl
index 7fba26907b5..7fba26907b5 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_store_output.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_store_output.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_texture_utilities.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl
index 128fc6aeaf5..128fc6aeaf5 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_texture_utilities.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_type_conversion.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_type_conversion.glsl
index 75c76fd7341..75c76fd7341 100644
--- a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_type_conversion.glsl
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_type_conversion.glsl
diff --git a/source/blender/compositor/tests/COM_BuffersIterator_test.cc b/source/blender/compositor/tests/COM_BuffersIterator_test.cc
index 03748760029..89febb38655 100644
--- a/source/blender/compositor/tests/COM_BuffersIterator_test.cc
+++ b/source/blender/compositor/tests/COM_BuffersIterator_test.cc
@@ -237,7 +237,7 @@ TEST_F(BuffersIteratorTest, OutputIteration)
{
set_inputs_enabled(false);
test_iteration(
- [](BuffersIterator<float> &it, const rcti &UNUSED(area)) {
+ [](BuffersIterator<float> &it, const rcti & /*area*/) {
EXPECT_EQ(it.get_num_inputs(), 0);
for (; !it.is_end(); ++it) {
const int dummy = it.y * BUFFER_WIDTH + it.x;
@@ -247,7 +247,7 @@ TEST_F(BuffersIteratorTest, OutputIteration)
it.out[3] = dummy + 4.0f;
}
},
- [](float *out, Span<const float *> UNUSED(ins), const int x, const int y) {
+ [](float *out, Span<const float *> /*ins*/, const int x, const int y) {
const int dummy = y * BUFFER_WIDTH + x;
EXPECT_NEAR(out[0], dummy + 1.0f, FLT_EPSILON);
EXPECT_NEAR(out[1], dummy + 2.0f, FLT_EPSILON);
@@ -260,7 +260,7 @@ TEST_F(BuffersIteratorTest, OutputAndInputsIteration)
{
set_inputs_enabled(true);
test_iteration(
- [](BuffersIterator<float> &it, const rcti &UNUSED(area)) {
+ [](BuffersIterator<float> &it, const rcti & /*area*/) {
EXPECT_EQ(it.get_num_inputs(), NUM_INPUTS);
for (; !it.is_end(); ++it) {
const float *in1 = it.in(0);
@@ -271,7 +271,7 @@ TEST_F(BuffersIteratorTest, OutputAndInputsIteration)
it.out[3] = in1[3] - in2[1];
}
},
- [](float *out, Span<const float *> ins, const int UNUSED(x), const int UNUSED(y)) {
+ [](float *out, Span<const float *> ins, const int /*x*/, const int /*y*/) {
const float *in1 = ins[0];
const float *in2 = ins[1];
EXPECT_NEAR(out[0], in1[0] + in2[0], FLT_EPSILON);
diff --git a/source/blender/datatoc/datatoc_icon.c b/source/blender/datatoc/datatoc_icon.c
index 780dea34b93..2a87cf62d3a 100644
--- a/source/blender/datatoc/datatoc_icon.c
+++ b/source/blender/datatoc/datatoc_icon.c
@@ -55,7 +55,7 @@ static bool path_test_extension(const char *str, const char *ext)
static void endian_switch_uint32(uint *val)
{
uint tval = *val;
- *val = ((tval >> 24)) | ((tval << 8) & 0x00ff0000) | ((tval >> 8) & 0x0000ff00) | ((tval << 24));
+ *val = (tval >> 24) | ((tval << 8) & 0x00ff0000) | ((tval >> 8) & 0x0000ff00) | (tval << 24);
}
static const char *path_slash_rfind(const char *string)
@@ -158,9 +158,8 @@ static bool write_png(const char *name, const uint *pixels, const int width, con
/* set the individual row-pointers to point at the correct offsets */
for (i = 0; i < height; i++) {
- row_pointers[height - 1 - i] = (png_bytep)(((const unsigned char *)pixels) +
- (i * width) * bytesperpixel *
- sizeof(unsigned char));
+ row_pointers[height - 1 - i] = (png_bytep)(((const uchar *)pixels) +
+ (i * width) * bytesperpixel * sizeof(uchar));
}
/* write out the entire image data in one call */
diff --git a/source/blender/datatoc/datatoc_icon.py b/source/blender/datatoc/datatoc_icon.py
index 7373df71318..84cef0457a6 100755
--- a/source/blender/datatoc/datatoc_icon.py
+++ b/source/blender/datatoc/datatoc_icon.py
@@ -75,8 +75,8 @@ def icon_merge(file_src, pixels_canvas, canvas_w, canvas_h):
orig_x, orig_y,
w_canvas_test, h_canvas_test) = head
- assert(w_canvas_test == canvas_w)
- assert(h_canvas_test == canvas_h)
+ assert w_canvas_test == canvas_w
+ assert h_canvas_test == canvas_h
for x in range(icon_w):
for y in range(icon_h):
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt
index e799c5ce32a..a394ea4a54a 100644
--- a/source/blender/depsgraph/CMakeLists.txt
+++ b/source/blender/depsgraph/CMakeLists.txt
@@ -26,6 +26,8 @@ set(SRC
intern/builder/deg_builder.cc
intern/builder/deg_builder_cache.cc
intern/builder/deg_builder_cycle.cc
+ intern/builder/deg_builder_key.cc
+ intern/builder/deg_builder_key.h
intern/builder/deg_builder_map.cc
intern/builder/deg_builder_nodes.cc
intern/builder/deg_builder_nodes_rig.cc
@@ -34,7 +36,6 @@ set(SRC
intern/builder/deg_builder_pchanmap.cc
intern/builder/deg_builder_relations.cc
intern/builder/deg_builder_relations_drivers.cc
- intern/builder/deg_builder_relations_keys.cc
intern/builder/deg_builder_relations_rig.cc
intern/builder/deg_builder_relations_scene.cc
intern/builder/deg_builder_relations_view_layer.cc
diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h
index a8b21e4c153..48a6a5cda74 100644
--- a/source/blender/depsgraph/DEG_depsgraph.h
+++ b/source/blender/depsgraph/DEG_depsgraph.h
@@ -221,6 +221,14 @@ bool DEG_is_active(const struct Depsgraph *depsgraph);
void DEG_make_active(struct Depsgraph *depsgraph);
void DEG_make_inactive(struct Depsgraph *depsgraph);
+/**
+ * Disable the visibility optimization making it so IDs which affect hidden objects or disabled
+ * modifiers are still evaluated.
+ *
+ * For example, this ensures that an object which is needed by a modifier is ignoring checks about
+ * whether the object is hidden or the modifier is disabled. */
+void DEG_disable_visibility_optimization(struct Depsgraph *depsgraph);
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/depsgraph/DEG_depsgraph_build.h b/source/blender/depsgraph/DEG_depsgraph_build.h
index 201a534f535..ffeb5e897ab 100644
--- a/source/blender/depsgraph/DEG_depsgraph_build.h
+++ b/source/blender/depsgraph/DEG_depsgraph_build.h
@@ -56,6 +56,9 @@ void DEG_graph_build_for_render_pipeline(struct Depsgraph *graph);
*/
void DEG_graph_build_for_compositor_preview(struct Depsgraph *graph, struct bNodeTree *nodetree);
+/**
+ * Builds the minimal dependency graph needed for evaluation of the given IDs.
+ */
void DEG_graph_build_from_ids(struct Depsgraph *graph, struct ID **ids, int num_ids);
/** Tag relations from the given graph for update. */
diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h
index 12663e74d24..4a9025641f9 100644
--- a/source/blender/depsgraph/DEG_depsgraph_query.h
+++ b/source/blender/depsgraph/DEG_depsgraph_query.h
@@ -10,6 +10,7 @@
#pragma once
#include "BLI_iterator.h"
+#include "BLI_utildefines.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
@@ -26,6 +27,7 @@ struct ListBase;
struct PointerRNA;
struct Scene;
struct ViewLayer;
+struct ViewerPath;
#ifdef __cplusplus
extern "C" {
@@ -132,15 +134,42 @@ bool DEG_is_fully_evaluated(const struct Depsgraph *depsgraph);
/** \name DEG object iterators
* \{ */
-enum {
+typedef enum DegIterFlag {
DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY = (1 << 0),
DEG_ITER_OBJECT_FLAG_LINKED_INDIRECTLY = (1 << 1),
DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET = (1 << 2),
DEG_ITER_OBJECT_FLAG_VISIBLE = (1 << 3),
DEG_ITER_OBJECT_FLAG_DUPLI = (1 << 4),
-};
+} DegIterFlag;
+ENUM_OPERATORS(DegIterFlag, DEG_ITER_OBJECT_FLAG_DUPLI)
+
+typedef struct DEGObjectIterSettings {
+ struct Depsgraph *depsgraph;
+ /**
+ * Bit-field of the #DegIterFlag.
+ *
+ * NOTE: Be careful with #DEG_ITER_OBJECT_FLAG_LINKED_INDIRECTLY objects.
+ * Although they are available they have no overrides (collection_properties)
+ * and will crash if you try to access it.
+ */
+ uint32_t flags;
+
+ /**
+ * When set, the final evaluated geometry of the corresponding object is omitted. Instead the
+ * geometry for the viewer path included in the iterator.
+ */
+ const struct ViewerPath *viewer_path;
+} DEGObjectIterSettings;
+
+/**
+ * Flags to to get objects for draw manager and final render.
+ */
+#define DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS \
+ DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | \
+ DEG_ITER_OBJECT_FLAG_VISIBLE | DEG_ITER_OBJECT_FLAG_DUPLI
typedef struct DEGObjectIterData {
+ DEGObjectIterSettings *settings;
struct Depsgraph *graph;
int flag;
@@ -148,6 +177,9 @@ typedef struct DEGObjectIterData {
eEvaluationMode eval_mode;
+ /** Object whose preview instead of evaluated geometry should be part of the iterator. */
+ struct Object *object_orig_with_preview;
+
struct Object *next_object;
/* **** Iteration over dupli-list. *** */
@@ -174,16 +206,12 @@ void DEG_iterator_objects_begin(struct BLI_Iterator *iter, DEGObjectIterData *da
void DEG_iterator_objects_next(struct BLI_Iterator *iter);
void DEG_iterator_objects_end(struct BLI_Iterator *iter);
-/**
- * NOTE: Be careful with DEG_ITER_OBJECT_FLAG_LINKED_INDIRECTLY objects.
- * Although they are available they have no overrides (collection_properties)
- * and will crash if you try to access it.
- */
-#define DEG_OBJECT_ITER_BEGIN(graph_, instance_, flag_) \
+#define DEG_OBJECT_ITER_BEGIN(settings_, instance_) \
{ \
DEGObjectIterData data_ = { \
- graph_, \
- flag_, \
+ (settings_), \
+ (settings_)->depsgraph, \
+ (int)(settings_)->flags, \
}; \
\
ITER_BEGIN (DEG_iterator_objects_begin, \
@@ -198,18 +226,6 @@ void DEG_iterator_objects_end(struct BLI_Iterator *iter);
} \
((void)0)
-/**
- * Depsgraph objects iterator for draw manager and final render
- */
-#define DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(graph_, instance_) \
- DEG_OBJECT_ITER_BEGIN (graph_, \
- instance_, \
- DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | \
- DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE | \
- DEG_ITER_OBJECT_FLAG_DUPLI)
-
-#define DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END DEG_OBJECT_ITER_END
-
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc
index 097c377ece4..16510d5f9a6 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder.cc
@@ -178,6 +178,9 @@ void deg_graph_build_finalize(Main *bmain, Depsgraph *graph)
if (GS(id_orig->name) == ID_OB) {
flag |= ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY;
}
+ if (GS(id_orig->name) == ID_NT) {
+ flag |= ID_RECALC_NTREE_OUTPUT;
+ }
}
/* Restore recalc flags from original ID, which could possibly contain recalc flags set by
* an operator and then were carried on by the undo system. */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cache.cc b/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
index 129e0093d11..a9f8d1f73d3 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
@@ -59,9 +59,9 @@ bool operator==(const AnimatedPropertyID &a, const AnimatedPropertyID &b)
uint64_t AnimatedPropertyID::hash() const
{
- uintptr_t ptr1 = (uintptr_t)data;
- uintptr_t ptr2 = (uintptr_t)property_rna;
- return static_cast<uint64_t>(((ptr1 >> 4) * 33) ^ (ptr2 >> 4));
+ uintptr_t ptr1 = uintptr_t(data);
+ uintptr_t ptr2 = uintptr_t(property_rna);
+ return uint64_t(((ptr1 >> 4) * 33) ^ (ptr2 >> 4));
}
namespace {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
index 8ba6c840a59..7f3c59f1522 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
@@ -60,7 +60,7 @@ struct CyclesSolverState {
inline void set_node_visited_state(Node *node, eCyclicCheckVisitedState state)
{
- node->custom_flags = (node->custom_flags & ~0x3) | (int)state;
+ node->custom_flags = (node->custom_flags & ~0x3) | int(state);
}
inline eCyclicCheckVisitedState get_node_visited_state(Node *node)
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc b/source/blender/depsgraph/intern/builder/deg_builder_key.cc
index 8506a97c408..741c415b5cd 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_key.cc
@@ -7,20 +7,26 @@
* Methods for constructing depsgraph
*/
-#include "intern/builder/deg_builder_relations.h"
+#include "intern/builder/deg_builder_key.h"
+
+#include "RNA_path.h"
namespace blender::deg {
-////////////////////////////////////////////////////////////////////////////////
-/* Time source. */
+/* -------------------------------------------------------------------- */
+/** \name Time source
+ * \{ */
string TimeSourceKey::identifier() const
{
return string("TimeSourceKey");
}
-////////////////////////////////////////////////////////////////////////////////
-// Component.
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Component
+ * \{ */
string ComponentKey::identifier() const
{
@@ -35,8 +41,11 @@ string ComponentKey::identifier() const
return result;
}
-////////////////////////////////////////////////////////////////////////////////
-// Operation.
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Operation
+ * \{ */
string OperationKey::identifier() const
{
@@ -51,8 +60,11 @@ string OperationKey::identifier() const
return result;
}
-////////////////////////////////////////////////////////////////////////////////
-// RNA path.
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name RNA path
+ * \{ */
RNAPathKey::RNAPathKey(ID *id, const char *path, RNAPointerSource source) : id(id), source(source)
{
@@ -79,4 +91,6 @@ string RNAPathKey::identifier() const
return string("RnaPathKey(") + "id: " + id_name + ", prop: '" + prop_name + "')";
}
+/** \} */
+
} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_key.h b/source/blender/depsgraph/intern/builder/deg_builder_key.h
new file mode 100644
index 00000000000..4f8b2dc9f8f
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/deg_builder_key.h
@@ -0,0 +1,201 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2013 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "intern/builder/deg_builder_rna.h"
+#include "intern/depsgraph_type.h"
+#include "intern/node/deg_node_component.h"
+#include "intern/node/deg_node_id.h"
+#include "intern/node/deg_node_operation.h"
+
+#include "DNA_ID.h"
+
+#include "RNA_access.h"
+#include "RNA_types.h"
+
+struct ID;
+struct PropertyRNA;
+
+namespace blender::deg {
+
+struct TimeSourceKey {
+ TimeSourceKey() = default;
+
+ string identifier() const;
+};
+
+struct ComponentKey {
+ ComponentKey() = default;
+
+ inline ComponentKey(const ID *id, NodeType type, const char *name = "")
+ : id(id), type(type), name(name)
+ {
+ }
+
+ string identifier() const;
+
+ const ID *id = nullptr;
+ NodeType type = NodeType::UNDEFINED;
+ const char *name = "";
+};
+
+struct OperationKey {
+ OperationKey() = default;
+
+ inline OperationKey(const ID *id, NodeType component_type, const char *name, int name_tag = -1)
+ : id(id),
+ component_type(component_type),
+ component_name(""),
+ opcode(OperationCode::OPERATION),
+ name(name),
+ name_tag(name_tag)
+ {
+ }
+
+ OperationKey(const ID *id,
+ NodeType component_type,
+ const char *component_name,
+ const char *name,
+ int name_tag)
+ : id(id),
+ component_type(component_type),
+ component_name(component_name),
+ opcode(OperationCode::OPERATION),
+ name(name),
+ name_tag(name_tag)
+ {
+ }
+
+ OperationKey(const ID *id, NodeType component_type, OperationCode opcode)
+ : id(id),
+ component_type(component_type),
+ component_name(""),
+ opcode(opcode),
+ name(""),
+ name_tag(-1)
+ {
+ }
+
+ OperationKey(const ID *id,
+ NodeType component_type,
+ const char *component_name,
+ OperationCode opcode)
+ : id(id),
+ component_type(component_type),
+ component_name(component_name),
+ opcode(opcode),
+ name(""),
+ name_tag(-1)
+ {
+ }
+
+ OperationKey(const ID *id,
+ NodeType component_type,
+ OperationCode opcode,
+ const char *name,
+ int name_tag = -1)
+ : id(id),
+ component_type(component_type),
+ component_name(""),
+ opcode(opcode),
+ name(name),
+ name_tag(name_tag)
+ {
+ }
+
+ OperationKey(const ID *id,
+ NodeType component_type,
+ const char *component_name,
+ OperationCode opcode,
+ const char *name,
+ int name_tag = -1)
+ : id(id),
+ component_type(component_type),
+ component_name(component_name),
+ opcode(opcode),
+ name(name),
+ name_tag(name_tag)
+ {
+ }
+
+ OperationKey(OperationKey &&other) noexcept = default;
+ OperationKey &operator=(OperationKey &&other) = default;
+
+ OperationKey(const OperationKey &other) = default;
+ OperationKey &operator=(const OperationKey &other) = default;
+
+ string identifier() const;
+
+ const ID *id = nullptr;
+ NodeType component_type = NodeType::UNDEFINED;
+ const char *component_name = "";
+ OperationCode opcode = OperationCode::OPERATION;
+ const char *name = "";
+ int name_tag = -1;
+};
+
+/* Similar to the the OperationKey but does not contain external references, which makes it
+ * suitable to identify operations even after the original database or graph was destroyed.
+ * The downside of this key over the OperationKey is that it performs string allocation upon
+ * the key construction. */
+struct PersistentOperationKey : public OperationKey {
+ /* Create the key which identifies the given operation node. */
+ PersistentOperationKey(const OperationNode *operation_node)
+ {
+ const ComponentNode *component_node = operation_node->owner;
+ const IDNode *id_node = component_node->owner;
+
+ /* Copy names over to our object, so that the key stays valid even after the `operation_node`
+ * is destroyed.*/
+ component_name_storage_ = component_node->name;
+ name_storage_ = operation_node->name;
+
+ /* Assign fields used by the OperationKey API. */
+ id = id_node->id_orig;
+ component_type = component_node->type;
+ component_name = component_name_storage_.c_str();
+ opcode = operation_node->opcode;
+ name = name_storage_.c_str();
+ name_tag = operation_node->name_tag;
+ }
+
+ PersistentOperationKey(PersistentOperationKey &&other) noexcept : OperationKey(other)
+ {
+ component_name_storage_ = std::move(other.component_name_storage_);
+ name_storage_ = std::move(other.name_storage_);
+
+ /* Re-assign pointers to the strings.
+ * This is needed because string content can actually change address if the string uses the
+ * small string optimization. */
+ component_name = component_name_storage_.c_str();
+ name = name_storage_.c_str();
+ }
+
+ PersistentOperationKey &operator=(PersistentOperationKey &&other) = delete;
+
+ PersistentOperationKey(const PersistentOperationKey &other) = delete;
+ PersistentOperationKey &operator=(const PersistentOperationKey &other) = delete;
+
+ private:
+ string component_name_storage_;
+ string name_storage_;
+};
+
+struct RNAPathKey {
+ RNAPathKey(ID *id, const char *path, RNAPointerSource source);
+ RNAPathKey(ID *id, const PointerRNA &ptr, PropertyRNA *prop, RNAPointerSource source);
+
+ string identifier() const;
+
+ ID *id;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ RNAPointerSource source;
+};
+
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 324197118d2..c84852788fd 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -104,6 +104,7 @@
#include "SEQ_sequencer.h"
#include "intern/builder/deg_builder.h"
+#include "intern/builder/deg_builder_key.h"
#include "intern/builder/deg_builder_rna.h"
#include "intern/depsgraph.h"
#include "intern/depsgraph_tag.h"
@@ -155,14 +156,12 @@ IDNode *DepsgraphNodeBuilder::add_id_node(ID *id)
IDComponentsMask previously_visible_components_mask = 0;
uint32_t previous_eval_flags = 0;
DEGCustomDataMeshMasks previous_customdata_masks;
- int id_invisible_recalc = 0;
IDInfo *id_info = id_info_hash_.lookup_default(id->session_uuid, nullptr);
if (id_info != nullptr) {
id_cow = id_info->id_cow;
previously_visible_components_mask = id_info->previously_visible_components_mask;
previous_eval_flags = id_info->previous_eval_flags;
previous_customdata_masks = id_info->previous_customdata_masks;
- id_invisible_recalc = id_info->id_invisible_recalc;
/* Tag ID info to not free the CoW ID pointer. */
id_info->id_cow = nullptr;
}
@@ -170,7 +169,6 @@ IDNode *DepsgraphNodeBuilder::add_id_node(ID *id)
id_node->previously_visible_components_mask = previously_visible_components_mask;
id_node->previous_eval_flags = previous_eval_flags;
id_node->previous_customdata_masks = previous_customdata_masks;
- id_node->id_invisible_recalc = id_invisible_recalc;
/* NOTE: Zero number of components indicates that ID node was just created. */
const bool is_newly_created = id_node->components.is_empty();
@@ -211,7 +209,7 @@ IDNode *DepsgraphNodeBuilder::add_id_node(ID *id)
return id_node;
}
-IDNode *DepsgraphNodeBuilder::find_id_node(ID *id)
+IDNode *DepsgraphNodeBuilder::find_id_node(const ID *id)
{
return graph_->find_id_node(id);
}
@@ -231,6 +229,17 @@ ComponentNode *DepsgraphNodeBuilder::add_component_node(ID *id,
return comp_node;
}
+ComponentNode *DepsgraphNodeBuilder::find_component_node(const ID *id,
+ const NodeType comp_type,
+ const char *comp_name)
+{
+ IDNode *id_node = find_id_node(id);
+ if (id_node == nullptr) {
+ return nullptr;
+ }
+ return id_node->find_component(comp_type, comp_name);
+}
+
OperationNode *DepsgraphNodeBuilder::add_operation_node(ComponentNode *comp_node,
OperationCode opcode,
const DepsEvalOperationCb &op,
@@ -314,23 +323,32 @@ bool DepsgraphNodeBuilder::has_operation_node(ID *id,
return find_operation_node(id, comp_type, comp_name, opcode, name, name_tag) != nullptr;
}
-OperationNode *DepsgraphNodeBuilder::find_operation_node(ID *id,
+OperationNode *DepsgraphNodeBuilder::find_operation_node(const ID *id,
NodeType comp_type,
const char *comp_name,
OperationCode opcode,
const char *name,
int name_tag)
{
- ComponentNode *comp_node = add_component_node(id, comp_type, comp_name);
+ ComponentNode *comp_node = find_component_node(id, comp_type, comp_name);
+ if (comp_node == nullptr) {
+ return nullptr;
+ }
return comp_node->find_operation(opcode, name, name_tag);
}
OperationNode *DepsgraphNodeBuilder::find_operation_node(
- ID *id, NodeType comp_type, OperationCode opcode, const char *name, int name_tag)
+ const ID *id, NodeType comp_type, OperationCode opcode, const char *name, int name_tag)
{
return find_operation_node(id, comp_type, "", opcode, name, name_tag);
}
+OperationNode *DepsgraphNodeBuilder::find_operation_node(const OperationKey &key)
+{
+ return find_operation_node(
+ key.id, key.component_type, key.component_name, key.opcode, key.name, key.name_tag);
+}
+
ID *DepsgraphNodeBuilder::get_cow_id(const ID *id_orig) const
{
return graph_->get_cow_id(id_orig);
@@ -369,23 +387,13 @@ void DepsgraphNodeBuilder::begin_build()
id_info->previously_visible_components_mask = id_node->visible_components_mask;
id_info->previous_eval_flags = id_node->eval_flags;
id_info->previous_customdata_masks = id_node->customdata_masks;
- id_info->id_invisible_recalc = id_node->id_invisible_recalc;
BLI_assert(!id_info_hash_.contains(id_node->id_orig_session_uuid));
id_info_hash_.add_new(id_node->id_orig_session_uuid, id_info);
id_node->id_cow = nullptr;
}
- for (OperationNode *op_node : graph_->entry_tags) {
- ComponentNode *comp_node = op_node->owner;
- IDNode *id_node = comp_node->owner;
-
- SavedEntryTag entry_tag;
- entry_tag.id_orig = id_node->id_orig;
- entry_tag.component_type = comp_node->type;
- entry_tag.opcode = op_node->opcode;
- entry_tag.name = op_node->name;
- entry_tag.name_tag = op_node->name_tag;
- saved_entry_tags_.append(entry_tag);
+ for (const OperationNode *op_node : graph_->entry_tags) {
+ saved_entry_tags_.append_as(op_node);
}
/* Make sure graph has no nodes left from previous state. */
@@ -445,6 +453,11 @@ static int foreach_id_cow_detect_need_for_update_callback(LibraryIDLinkCallbackD
if (id == nullptr) {
return IDWALK_RET_NOP;
}
+ if (!ID_TYPE_IS_COW(GS(id->name))) {
+ /* No need to go further if the id never had a cow copy in the depsgraph. This function is
+ * only concerned with keeping the mapping between original and COW ids intact. */
+ return IDWALK_RET_NOP;
+ }
DepsgraphNodeBuilder *builder = static_cast<DepsgraphNodeBuilder *>(cb_data->user_data);
ID *id_cow_self = cb_data->id_self;
@@ -503,23 +516,15 @@ void DepsgraphNodeBuilder::update_invalid_cow_pointers()
void DepsgraphNodeBuilder::tag_previously_tagged_nodes()
{
- for (const SavedEntryTag &entry_tag : saved_entry_tags_) {
- IDNode *id_node = find_id_node(entry_tag.id_orig);
- if (id_node == nullptr) {
- continue;
- }
- ComponentNode *comp_node = id_node->find_component(entry_tag.component_type);
- if (comp_node == nullptr) {
- continue;
- }
- OperationNode *op_node = comp_node->find_operation(
- entry_tag.opcode, entry_tag.name.c_str(), entry_tag.name_tag);
- if (op_node == nullptr) {
+ for (const OperationKey &operation_key : saved_entry_tags_) {
+ OperationNode *operation_node = find_operation_node(operation_key);
+ if (operation_node == nullptr) {
continue;
}
+
/* Since the tag is coming from a saved copy of entry tags, this means
* that originally node was explicitly tagged for user update. */
- op_node->tag_update(graph_, DEG_UPDATE_SOURCE_USER_EDIT);
+ operation_node->tag_update(graph_, DEG_UPDATE_SOURCE_USER_EDIT);
}
}
@@ -1745,14 +1750,19 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree)
/* Animation, */
build_animdata(&ntree->id);
/* Output update. */
- ID *id_cow = get_cow_id(&ntree->id);
- add_operation_node(&ntree->id,
- NodeType::NTREE_OUTPUT,
- OperationCode::NTREE_OUTPUT,
- [id_cow](::Depsgraph * /*depsgraph*/) {
- bNodeTree *ntree_cow = reinterpret_cast<bNodeTree *>(id_cow);
- bke::node_tree_runtime::handle_node_tree_output_changed(*ntree_cow);
- });
+ add_operation_node(&ntree->id, NodeType::NTREE_OUTPUT, OperationCode::NTREE_OUTPUT);
+ if (ntree->type == NTREE_GEOMETRY) {
+ ID *id_cow = get_cow_id(&ntree->id);
+ add_operation_node(&ntree->id,
+ NodeType::NTREE_GEOMETRY_PREPROCESS,
+ OperationCode::NTREE_GEOMETRY_PREPROCESS,
+ [id_cow](::Depsgraph * /*depsgraph*/) {
+ bNodeTree *ntree_cow = reinterpret_cast<bNodeTree *>(id_cow);
+ bke::node_tree_runtime::preprocess_geometry_node_tree_for_evaluation(
+ *ntree_cow);
+ });
+ }
+
/* nodetree's nodes... */
LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) {
build_idproperties(bnode->prop);
@@ -2129,9 +2139,10 @@ void DepsgraphNodeBuilder::build_scene_audio(Scene *scene)
});
}
-void DepsgraphNodeBuilder::build_scene_speakers(Scene * /*scene*/, ViewLayer *view_layer)
+void DepsgraphNodeBuilder::build_scene_speakers(Scene *scene, ViewLayer *view_layer)
{
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *object = base->object;
if (object->type != OB_SPEAKER || !need_pull_base_into_graph(base)) {
continue;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index 29cca0a8ddd..a8efe8fca9f 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -8,6 +8,7 @@
#pragma once
#include "intern/builder/deg_builder.h"
+#include "intern/builder/deg_builder_key.h"
#include "intern/builder/deg_builder_map.h"
#include "intern/depsgraph_type.h"
#include "intern/node/deg_node_id.h"
@@ -56,6 +57,7 @@ struct ComponentNode;
struct Depsgraph;
class DepsgraphBuilderCache;
struct IDNode;
+struct OperationKey;
struct OperationNode;
struct TimeSourceNode;
@@ -92,10 +94,11 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
int foreach_id_cow_detect_need_for_update_callback(ID *id_cow_self, ID *id_pointer);
IDNode *add_id_node(ID *id);
- IDNode *find_id_node(ID *id);
+ IDNode *find_id_node(const ID *id);
TimeSourceNode *add_time_source();
ComponentNode *add_component_node(ID *id, NodeType comp_type, const char *comp_name = "");
+ ComponentNode *find_component_node(const ID *id, NodeType comp_type, const char *comp_name = "");
OperationNode *add_operation_node(ComponentNode *comp_node,
OperationCode opcode,
@@ -137,15 +140,20 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
const char *name = "",
int name_tag = -1);
- OperationNode *find_operation_node(ID *id,
+ OperationNode *find_operation_node(const ID *id,
NodeType comp_type,
const char *comp_name,
OperationCode opcode,
const char *name = "",
int name_tag = -1);
- OperationNode *find_operation_node(
- ID *id, NodeType comp_type, OperationCode opcode, const char *name = "", int name_tag = -1);
+ OperationNode *find_operation_node(const ID *id,
+ NodeType comp_type,
+ OperationCode opcode,
+ const char *name = "",
+ int name_tag = -1);
+
+ OperationNode *find_operation_node(const OperationKey &key);
virtual void build_id(ID *id);
@@ -250,24 +258,14 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
IDComponentsMask previously_visible_components_mask;
/* Special evaluation flag mask from the previous depsgraph. */
uint32_t previous_eval_flags;
- /* Recalculation flags which were not evaluated for the ID in the previous depsgraph. */
- int id_invisible_recalc;
/* Mesh CustomData mask from the previous depsgraph. */
DEGCustomDataMeshMasks previous_customdata_masks;
};
protected:
- /* Allows to identify an operation which was tagged for update at the time
- * relations are being updated. We can not reuse operation node pointer
- * since it will change during dependency graph construction. */
- struct SavedEntryTag {
- ID *id_orig;
- NodeType component_type;
- OperationCode opcode;
- string name;
- int name_tag;
- };
- Vector<SavedEntryTag> saved_entry_tags_;
+ /* Entry tags from the previous state of the dependency graph.
+ * Stored before the graph is re-created so that they can be transferred over. */
+ Vector<PersistentOperationKey> saved_entry_tags_;
struct BuilderWalkUserData {
DepsgraphNodeBuilder *builder;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
index 5af9e7d4fe9..d7420b91db4 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
@@ -90,7 +90,8 @@ void DepsgraphNodeBuilder::build_view_layer(Scene *scene,
* but object is expected to be an original one. Hence we go into some
* tricks here iterating over the view layer. */
int base_index = 0;
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
/* object itself */
if (!need_pull_base_into_graph(base)) {
continue;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 313d4996dcf..b657d39df69 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -191,7 +191,7 @@ bool check_id_has_anim_component(ID *id)
if (adt == nullptr) {
return false;
}
- return (adt->action != nullptr) || (!BLI_listbase_is_empty(&adt->nla_tracks));
+ return (adt->action != nullptr) || !BLI_listbase_is_empty(&adt->nla_tracks);
}
bool check_id_has_driver_component(ID *id)
@@ -1723,6 +1723,11 @@ void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu)
if (GS(id_ptr->name) == ID_NT) {
ComponentKey ntree_output_key(id_ptr, NodeType::NTREE_OUTPUT);
add_relation(driver_key, ntree_output_key, "Drivers -> NTree Output");
+ if (reinterpret_cast<bNodeTree *>(id_ptr)->type == NTREE_GEOMETRY) {
+ OperationKey ntree_geo_preprocess_key(
+ id, NodeType::NTREE_GEOMETRY_PREPROCESS, OperationCode::NTREE_GEOMETRY_PREPROCESS);
+ add_relation(driver_key, ntree_geo_preprocess_key, "Drivers -> NTree Geo Preprocess");
+ }
}
}
@@ -2611,6 +2616,16 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
build_animdata(&ntree->id);
build_parameters(&ntree->id);
OperationKey ntree_output_key(&ntree->id, NodeType::NTREE_OUTPUT, OperationCode::NTREE_OUTPUT);
+ OperationKey ntree_geo_preprocess_key(
+ &ntree->id, NodeType::NTREE_GEOMETRY_PREPROCESS, OperationCode::NTREE_GEOMETRY_PREPROCESS);
+ if (ntree->type == NTREE_GEOMETRY) {
+ OperationKey ntree_cow_key(&ntree->id, NodeType::COPY_ON_WRITE, OperationCode::COPY_ON_WRITE);
+ add_relation(ntree_cow_key, ntree_geo_preprocess_key, "COW -> Preprocess");
+ add_relation(ntree_geo_preprocess_key,
+ ntree_output_key,
+ "Preprocess -> Output",
+ RELATION_FLAG_NO_FLUSH);
+ }
/* nodetree's nodes... */
LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) {
build_idproperties(bnode->prop);
@@ -2687,6 +2702,12 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
* the output). Currently, we lack the infrastructure to check for these cases efficiently.
* That can be added later. */
add_relation(group_output_key, ntree_output_key, "Group Node");
+ if (group_ntree->type == NTREE_GEOMETRY) {
+ OperationKey group_preprocess_key(&group_ntree->id,
+ NodeType::NTREE_GEOMETRY_PREPROCESS,
+ OperationCode::NTREE_GEOMETRY_PREPROCESS);
+ add_relation(group_preprocess_key, ntree_geo_preprocess_key, "Group Node Preprocess");
+ }
}
else {
BLI_assert_msg(0, "Unknown ID type used for node");
@@ -2703,6 +2724,9 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
if (check_id_has_anim_component(&ntree->id)) {
ComponentKey animation_key(&ntree->id, NodeType::ANIMATION);
add_relation(animation_key, ntree_output_key, "NTree Shading Parameters");
+ if (ntree->type == NTREE_GEOMETRY) {
+ add_relation(animation_key, ntree_geo_preprocess_key, "NTree Animation -> Preprocess");
+ }
}
}
@@ -3050,9 +3074,10 @@ void DepsgraphRelationBuilder::build_scene_audio(Scene *scene)
}
}
-void DepsgraphRelationBuilder::build_scene_speakers(Scene * /*scene*/, ViewLayer *view_layer)
+void DepsgraphRelationBuilder::build_scene_speakers(Scene *scene, ViewLayer *view_layer)
{
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *object = base->object;
if (object->type != OB_SPEAKER || !need_pull_base_into_graph(base)) {
continue;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index 7d3a0fd9217..901e4a1acbb 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -14,14 +14,13 @@
#include "DNA_ID.h"
-#include "RNA_access.h"
#include "RNA_path.h"
-#include "RNA_types.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "intern/builder/deg_builder.h"
+#include "intern/builder/deg_builder_key.h"
#include "intern/builder/deg_builder_map.h"
#include "intern/builder/deg_builder_rna.h"
#include "intern/builder/deg_builder_stack.h"
@@ -69,8 +68,6 @@ struct bNodeTree;
struct bPoseChannel;
struct bSound;
-struct PropertyRNA;
-
namespace blender::deg {
struct ComponentNode;
@@ -84,128 +81,6 @@ struct Relation;
struct RootPChanMap;
struct TimeSourceNode;
-struct TimeSourceKey {
- TimeSourceKey() = default;
-
- string identifier() const;
-};
-
-struct ComponentKey {
- ComponentKey() = default;
-
- inline ComponentKey(const ID *id, NodeType type, const char *name = "")
- : id(id), type(type), name(name)
- {
- }
-
- string identifier() const;
-
- const ID *id = nullptr;
- NodeType type = NodeType::UNDEFINED;
- const char *name = "";
-};
-
-struct OperationKey {
- OperationKey() = default;
-
- inline OperationKey(const ID *id, NodeType component_type, const char *name, int name_tag = -1)
- : id(id),
- component_type(component_type),
- component_name(""),
- opcode(OperationCode::OPERATION),
- name(name),
- name_tag(name_tag)
- {
- }
-
- OperationKey(const ID *id,
- NodeType component_type,
- const char *component_name,
- const char *name,
- int name_tag)
- : id(id),
- component_type(component_type),
- component_name(component_name),
- opcode(OperationCode::OPERATION),
- name(name),
- name_tag(name_tag)
- {
- }
-
- OperationKey(const ID *id, NodeType component_type, OperationCode opcode)
- : id(id),
- component_type(component_type),
- component_name(""),
- opcode(opcode),
- name(""),
- name_tag(-1)
- {
- }
-
- OperationKey(const ID *id,
- NodeType component_type,
- const char *component_name,
- OperationCode opcode)
- : id(id),
- component_type(component_type),
- component_name(component_name),
- opcode(opcode),
- name(""),
- name_tag(-1)
- {
- }
-
- OperationKey(const ID *id,
- NodeType component_type,
- OperationCode opcode,
- const char *name,
- int name_tag = -1)
- : id(id),
- component_type(component_type),
- component_name(""),
- opcode(opcode),
- name(name),
- name_tag(name_tag)
- {
- }
-
- OperationKey(const ID *id,
- NodeType component_type,
- const char *component_name,
- OperationCode opcode,
- const char *name,
- int name_tag = -1)
- : id(id),
- component_type(component_type),
- component_name(component_name),
- opcode(opcode),
- name(name),
- name_tag(name_tag)
- {
- }
-
- string identifier() const;
-
- const ID *id = nullptr;
- NodeType component_type = NodeType::UNDEFINED;
- const char *component_name = "";
- OperationCode opcode = OperationCode::OPERATION;
- const char *name = "";
- int name_tag = -1;
-};
-
-struct RNAPathKey {
- RNAPathKey(ID *id, const char *path, RNAPointerSource source);
- RNAPathKey(ID *id, const PointerRNA &ptr, PropertyRNA *prop, RNAPointerSource source);
-
- string identifier() const;
-
- ID *id;
- PointerRNA ptr;
- PropertyRNA *prop;
- RNAPointerSource source;
-};
-
class DepsgraphRelationBuilder : public DepsgraphBuilder {
public:
DepsgraphRelationBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
index d723e5beb75..938c0979de9 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
@@ -75,11 +75,12 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene,
{
/* Setup currently building context. */
scene_ = scene;
+ BKE_view_layer_synced_ensure(scene, view_layer);
/* Scene objects. */
/* NOTE: Nodes builder requires us to pass CoW base because it's being
* passed to the evaluation functions. During relations builder we only
* do nullptr-pointer check of the base, so it's fine to pass original one. */
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (need_pull_base_into_graph(base)) {
build_object_from_view_layer_base(base->object);
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
index d94746fb7fa..1a4356c4a92 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
@@ -138,8 +138,8 @@ bool RNANodeQuery::contains(const char *prop_identifier, const char *rna_path_co
return false;
}
- /* If substr != prop_identifier, it means that the substring is found further in prop_identifier,
- * and that thus index -1 is a valid memory location. */
+ /* If `substr != prop_identifier`, it means that the sub-string is found further in
+ * `prop_identifier`, and that thus index -1 is a valid memory location. */
const bool start_ok = substr == prop_identifier || substr[-1] == '.';
if (!start_ok) {
return false;
diff --git a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
index b8d0fb6c365..bd47cb77f56 100644
--- a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
+++ b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
@@ -408,6 +408,7 @@ static void deg_debug_graphviz_node(DotExportContext &ctx,
case NodeType::GENERIC_DATABLOCK:
case NodeType::VISIBILITY:
case NodeType::NTREE_OUTPUT:
+ case NodeType::NTREE_GEOMETRY_PREPROCESS:
case NodeType::SIMULATION: {
ComponentNode *comp_node = (ComponentNode *)node;
if (comp_node->operations.is_empty()) {
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index 316d0b615c6..4d7d537b450 100644
--- a/source/blender/depsgraph/intern/depsgraph.cc
+++ b/source/blender/depsgraph/intern/depsgraph.cc
@@ -58,6 +58,7 @@ Depsgraph::Depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluati
ctime(BKE_scene_ctime_get(scene)),
scene_cow(nullptr),
is_active(false),
+ use_visibility_optimization(true),
is_evaluating(false),
is_render_pipeline_depsgraph(false),
use_editors_update(false)
@@ -334,3 +335,9 @@ void DEG_make_inactive(struct Depsgraph *depsgraph)
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
deg_graph->is_active = false;
}
+
+void DEG_disable_visibility_optimization(struct Depsgraph *depsgraph)
+{
+ deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
+ deg_graph->use_visibility_optimization = false;
+} \ No newline at end of file
diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h
index 2f88199384d..042cb045c6f 100644
--- a/source/blender/depsgraph/intern/depsgraph.h
+++ b/source/blender/depsgraph/intern/depsgraph.h
@@ -147,6 +147,9 @@ struct Depsgraph {
* to read stuff from. */
bool is_active;
+ /* Optimize out evaluation of operations which affect hidden objects or disabled modifiers. */
+ bool use_visibility_optimization;
+
DepsgraphDebug debug;
bool is_evaluating;
diff --git a/source/blender/depsgraph/intern/depsgraph_debug.cc b/source/blender/depsgraph/intern/depsgraph_debug.cc
index ddad00bc0e8..2f528873f1d 100644
--- a/source/blender/depsgraph/intern/depsgraph_debug.cc
+++ b/source/blender/depsgraph/intern/depsgraph_debug.cc
@@ -171,7 +171,7 @@ bool DEG_debug_consistency_check(Depsgraph *graph)
node->identifier().c_str(),
node->num_links_pending,
num_links_pending);
- printf("Number of inlinks: %d\n", (int)node->inlinks.size());
+ printf("Number of inlinks: %d\n", int(node->inlinks.size()));
return false;
}
}
diff --git a/source/blender/depsgraph/intern/depsgraph_physics.cc b/source/blender/depsgraph/intern/depsgraph_physics.cc
index 5660d5eb1bd..d7d03ec3261 100644
--- a/source/blender/depsgraph/intern/depsgraph_physics.cc
+++ b/source/blender/depsgraph/intern/depsgraph_physics.cc
@@ -32,7 +32,7 @@ namespace deg = blender::deg;
/*************************** Evaluation Query API *****************************/
-static ePhysicsRelationType modifier_to_relation_type(unsigned int modifier_type)
+static ePhysicsRelationType modifier_to_relation_type(uint modifier_type)
{
switch (modifier_type) {
case eModifierType_Collision:
@@ -72,7 +72,7 @@ ListBase *DEG_get_effector_relations(const Depsgraph *graph, Collection *collect
ListBase *DEG_get_collision_relations(const Depsgraph *graph,
Collection *collection,
- unsigned int modifier_type)
+ uint modifier_type)
{
const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
const ePhysicsRelationType type = modifier_to_relation_type(modifier_type);
@@ -91,7 +91,7 @@ ListBase *DEG_get_collision_relations(const Depsgraph *graph,
void DEG_add_collision_relations(DepsNodeHandle *handle,
Object *object,
Collection *collection,
- unsigned int modifier_type,
+ uint modifier_type,
DEG_CollobjFilterFunction filter_function,
const char *name)
{
@@ -174,13 +174,11 @@ ListBase *build_effector_relations(Depsgraph *graph, Collection *collection)
ID *collection_id = object_id_safe(collection);
return hash->lookup_or_add_cb(collection_id, [&]() {
::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph *>(graph);
- return BKE_effector_relations_create(depsgraph, graph->view_layer, collection);
+ return BKE_effector_relations_create(depsgraph, graph->scene, graph->view_layer, collection);
});
}
-ListBase *build_collision_relations(Depsgraph *graph,
- Collection *collection,
- unsigned int modifier_type)
+ListBase *build_collision_relations(Depsgraph *graph, Collection *collection, uint modifier_type)
{
const ePhysicsRelationType type = modifier_to_relation_type(modifier_type);
Map<const ID *, ListBase *> *hash = graph->physics_relations[type];
diff --git a/source/blender/depsgraph/intern/depsgraph_query_foreach.cc b/source/blender/depsgraph/intern/depsgraph_query_foreach.cc
index 2839f0daed7..4f28210ba8f 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_foreach.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_foreach.cc
@@ -45,7 +45,7 @@ bool deg_foreach_needs_visit(const OperationNode *op_node, const int flags)
return true;
}
-void deg_foreach_dependent_operation(const Depsgraph *UNUSED(graph),
+void deg_foreach_dependent_operation(const Depsgraph * /*graph*/,
const IDNode *target_id_node,
eDepsObjectComponentType source_component_type,
int flags,
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index bcae5de1e1e..34df9a537e1 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -127,14 +127,11 @@ bool deg_object_hide_original(eEvaluationMode eval_mode, Object *ob, DupliObject
return false;
}
-void deg_iterator_duplis_init(DEGObjectIterData *data, Object *object)
+void deg_iterator_duplis_init(DEGObjectIterData *data, Object *object, ListBase *duplis)
{
- if ((data->flag & DEG_ITER_OBJECT_FLAG_DUPLI) &&
- ((object->transflag & OB_DUPLI) || object->runtime.geometry_set_eval != nullptr)) {
- data->dupli_parent = object;
- data->dupli_list = object_duplilist(data->graph, data->scene, object);
- data->dupli_object_next = (DupliObject *)data->dupli_list->first;
- }
+ data->dupli_parent = object;
+ data->dupli_list = duplis;
+ data->dupli_object_next = static_cast<DupliObject *>(duplis->first);
}
/* Returns false when iterator is exhausted. */
@@ -194,8 +191,8 @@ bool deg_iterator_duplis_step(DEGObjectIterData *data)
bool is_neg_scale = is_negative_m4(dob->mat);
SET_FLAG_FROM_TEST(data->temp_dupli_object.transflag, is_neg_scale, OB_NEG_SCALE);
- copy_m4_m4(data->temp_dupli_object.obmat, dob->mat);
- invert_m4_m4(data->temp_dupli_object.imat, data->temp_dupli_object.obmat);
+ copy_m4_m4(data->temp_dupli_object.object_to_world, dob->mat);
+ invert_m4_m4(data->temp_dupli_object.world_to_object, data->temp_dupli_object.object_to_world);
data->next_object = &data->temp_dupli_object;
BLI_assert(deg::deg_validate_copy_on_write_datablock(&data->temp_dupli_object.id));
return true;
@@ -250,7 +247,18 @@ bool deg_iterator_objects_step(DEGObjectIterData *data)
}
Object *object = (Object *)id_node->id_cow;
+ Object *object_orig = DEG_get_original_object(object);
BLI_assert(deg::deg_validate_copy_on_write_datablock(&object->id));
+ object->runtime.select_id = object_orig->runtime.select_id;
+
+ const bool use_preview = object_orig == data->object_orig_with_preview;
+ if (use_preview) {
+ ListBase *preview_duplis = object_duplilist_preview(
+ data->graph, data->scene, object, data->settings->viewer_path);
+ deg_iterator_duplis_init(data, object, preview_duplis);
+ data->id_node_index++;
+ return true;
+ }
int ob_visibility = OB_VISIBLE_ALL;
if (data->flag & DEG_ITER_OBJECT_FLAG_VISIBLE) {
@@ -261,9 +269,12 @@ bool deg_iterator_objects_step(DEGObjectIterData *data)
}
}
- object->runtime.select_id = DEG_get_original_object(object)->runtime.select_id;
if (ob_visibility & OB_VISIBLE_INSTANCES) {
- deg_iterator_duplis_init(data, object);
+ if ((data->flag & DEG_ITER_OBJECT_FLAG_DUPLI) &&
+ ((object->transflag & OB_DUPLI) || object->runtime.geometry_set_eval != nullptr)) {
+ ListBase *duplis = object_duplilist(data->graph, data->scene, object);
+ deg_iterator_duplis_init(data, object, duplis);
+ }
}
if (ob_visibility & (OB_VISIBLE_SELF | OB_VISIBLE_PARTICLES)) {
@@ -301,6 +312,22 @@ void DEG_iterator_objects_begin(BLI_Iterator *iter, DEGObjectIterData *data)
data->eval_mode = DEG_get_mode(depsgraph);
deg_invalidate_iterator_work_data(data);
+ /* Determine if the preview of any object should be in the iterator. */
+ const ViewerPath *viewer_path = data->settings->viewer_path;
+ if (viewer_path != nullptr) {
+ if (!BLI_listbase_is_empty(&viewer_path->path)) {
+ const ViewerPathElem *elem = static_cast<const ViewerPathElem *>(viewer_path->path.first);
+ if (elem->type == VIEWER_PATH_ELEM_TYPE_ID) {
+ const IDViewerPathElem *id_elem = reinterpret_cast<const IDViewerPathElem *>(elem);
+ if (id_elem->id != nullptr) {
+ if (GS(id_elem->id->name) == ID_OB) {
+ data->object_orig_with_preview = reinterpret_cast<Object *>(id_elem->id);
+ }
+ }
+ }
+ }
+ }
+
DEG_iterator_objects_next(iter);
}
@@ -408,6 +435,6 @@ void DEG_iterator_ids_next(BLI_Iterator *iter)
} while (iter->skip);
}
-void DEG_iterator_ids_end(BLI_Iterator *UNUSED(iter))
+void DEG_iterator_ids_end(BLI_Iterator * /*iter*/)
{
}
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index a8c8b4a6538..0c003cf23b2 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -235,7 +235,7 @@ void depsgraph_tag_to_component_opcode(const ID *id,
}
void id_tag_update_ntree_special(
- Main *bmain, Depsgraph *graph, ID *id, unsigned int flags, eUpdateSource update_source)
+ Main *bmain, Depsgraph *graph, ID *id, uint flags, eUpdateSource update_source)
{
bNodeTree *ntree = ntreeFromID(id);
if (ntree == nullptr) {
@@ -418,13 +418,13 @@ string stringify_append_bit(const string &str, IDRecalcFlag tag)
return result;
}
-string stringify_update_bitfield(unsigned int flags)
+string stringify_update_bitfield(uint flags)
{
if (flags == 0) {
return "LEGACY_0";
}
string result;
- unsigned int current_flag = flags;
+ uint current_flag = flags;
/* Special cases to avoid ALL flags form being split into
* individual bits. */
if ((current_flag & ID_RECALC_PSYS_ALL) == ID_RECALC_PSYS_ALL) {
@@ -460,7 +460,7 @@ int deg_recalc_flags_for_legacy_zero()
ID_RECALC_SOURCE | ID_RECALC_EDITORS);
}
-int deg_recalc_flags_effective(Depsgraph *graph, unsigned int flags)
+int deg_recalc_flags_effective(Depsgraph *graph, uint flags)
{
if (graph != nullptr) {
if (!graph->is_active) {
@@ -531,7 +531,7 @@ void graph_tag_ids_for_visible_update(Depsgraph *graph)
* No need bother with it to tag or anything. */
continue;
}
- unsigned int flags = 0;
+ uint flags = 0;
if (!deg::deg_copy_on_write_is_expanded(id_node->id_cow)) {
flags |= ID_RECALC_COPY_ON_WRITE;
if (do_time) {
@@ -625,7 +625,7 @@ NodeType geometry_tag_to_component(const ID *id)
return NodeType::UNDEFINED;
}
-void id_tag_update(Main *bmain, ID *id, unsigned int flags, eUpdateSource update_source)
+void id_tag_update(Main *bmain, ID *id, uint flags, eUpdateSource update_source)
{
graph_id_tag_update(bmain, nullptr, id, flags, update_source);
for (deg::Depsgraph *depsgraph : deg::get_all_registered_graphs(bmain)) {
@@ -638,7 +638,7 @@ void id_tag_update(Main *bmain, ID *id, unsigned int flags, eUpdateSource update
}
void graph_id_tag_update(
- Main *bmain, Depsgraph *graph, ID *id, unsigned int flags, eUpdateSource update_source)
+ Main *bmain, Depsgraph *graph, ID *id, uint flags, eUpdateSource update_source)
{
const int debug_flags = (graph != nullptr) ? DEG_debug_flags_get((::Depsgraph *)graph) : G.debug;
if (graph != nullptr && graph->is_evaluating) {
@@ -676,7 +676,7 @@ void graph_id_tag_update(
if (update_source == DEG_UPDATE_SOURCE_USER_EDIT) {
id->recalc |= deg_recalc_flags_effective(graph, flags);
}
- unsigned int current_flag = flags;
+ uint current_flag = flags;
while (current_flag != 0) {
IDRecalcFlag tag = (IDRecalcFlag)(1 << bitscan_forward_clear_uint(&current_flag));
graph_id_tag_update_single_flag(bmain, graph, id, id_node, tag, update_source);
@@ -770,12 +770,12 @@ const char *DEG_update_tag_as_string(IDRecalcFlag flag)
/* Data-Based Tagging. */
-void DEG_id_tag_update(ID *id, unsigned int flags)
+void DEG_id_tag_update(ID *id, uint flags)
{
DEG_id_tag_update_ex(G.main, id, flags);
}
-void DEG_id_tag_update_ex(Main *bmain, ID *id, unsigned int flags)
+void DEG_id_tag_update_ex(Main *bmain, ID *id, uint flags)
{
if (id == nullptr) {
/* Ideally should not happen, but old depsgraph allowed this. */
@@ -787,7 +787,7 @@ void DEG_id_tag_update_ex(Main *bmain, ID *id, unsigned int flags)
void DEG_graph_id_tag_update(struct Main *bmain,
struct Depsgraph *depsgraph,
struct ID *id,
- unsigned int flags)
+ uint flags)
{
deg::Depsgraph *graph = (deg::Depsgraph *)depsgraph;
deg::graph_id_tag_update(bmain, graph, id, flags, deg::DEG_UPDATE_SOURCE_USER_EDIT);
@@ -890,13 +890,6 @@ void DEG_ids_clear_recalc(Depsgraph *depsgraph, const bool backup)
}
/* Go over all ID nodes, clearing tags. */
for (deg::IDNode *id_node : deg_graph->id_nodes) {
- if (!id_node->is_enabled_on_eval) {
- id_node->id_invisible_recalc |= id_node->id_cow->recalc;
- }
- else {
- id_node->id_invisible_recalc = 0;
- }
-
if (backup) {
id_node->id_cow_recalc_backup |= id_node->id_cow->recalc;
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc
index cd0015ff717..5ca32d00ba5 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval.cc
@@ -12,6 +12,7 @@
#include "PIL_time.h"
#include "BLI_compiler_attrs.h"
+#include "BLI_function_ref.hh"
#include "BLI_gsqueue.h"
#include "BLI_task.h"
#include "BLI_utildefines.h"
@@ -52,16 +53,9 @@ struct DepsgraphEvalState;
void deg_task_run_func(TaskPool *pool, void *taskdata);
-template<typename ScheduleFunction, typename... ScheduleFunctionArgs>
void schedule_children(DepsgraphEvalState *state,
OperationNode *node,
- ScheduleFunction *schedule_function,
- ScheduleFunctionArgs... schedule_function_args);
-
-void schedule_node_to_pool(OperationNode *node, const int UNUSED(thread_id), TaskPool *pool)
-{
- BLI_task_pool_push(pool, deg_task_run_func, node, false, nullptr);
-}
+ FunctionRef<void(OperationNode *node)> schedule_fn);
/* Denotes which part of dependency graph is being evaluated. */
enum class EvaluationStage {
@@ -125,7 +119,9 @@ void deg_task_run_func(TaskPool *pool, void *taskdata)
evaluate_node(state, operation_node);
/* Schedule children. */
- schedule_children(state, operation_node, schedule_node_to_pool, pool);
+ schedule_children(state, operation_node, [&](OperationNode *node) {
+ BLI_task_pool_push(pool, deg_task_run_func, node, false, nullptr);
+ });
}
bool check_operation_node_visible(const DepsgraphEvalState *state, OperationNode *op_node)
@@ -241,12 +237,10 @@ bool need_evaluate_operation_at_stage(DepsgraphEvalState *state,
* dec_parents: Decrement pending parents count, true when child nodes are
* scheduled after a task has been completed.
*/
-template<typename ScheduleFunction, typename... ScheduleFunctionArgs>
void schedule_node(DepsgraphEvalState *state,
OperationNode *node,
bool dec_parents,
- ScheduleFunction *schedule_function,
- ScheduleFunctionArgs... schedule_function_args)
+ const FunctionRef<void(OperationNode *node)> schedule_fn)
{
/* No need to schedule nodes of invisible ID. */
if (!check_operation_node_visible(state, node)) {
@@ -273,34 +267,30 @@ void schedule_node(DepsgraphEvalState *state,
return;
}
/* Actually schedule the node. */
- bool is_scheduled = atomic_fetch_and_or_uint8((uint8_t *)&node->scheduled, (uint8_t) true);
+ bool is_scheduled = atomic_fetch_and_or_uint8((uint8_t *)&node->scheduled, uint8_t(true));
if (!is_scheduled) {
if (node->is_noop()) {
/* skip NOOP node, schedule children right away */
- schedule_children(state, node, schedule_function, schedule_function_args...);
+ schedule_children(state, node, schedule_fn);
}
else {
/* children are scheduled once this task is completed */
- schedule_function(node, 0, schedule_function_args...);
+ schedule_fn(node);
}
}
}
-template<typename ScheduleFunction, typename... ScheduleFunctionArgs>
void schedule_graph(DepsgraphEvalState *state,
- ScheduleFunction *schedule_function,
- ScheduleFunctionArgs... schedule_function_args)
+ const FunctionRef<void(OperationNode *node)> schedule_fn)
{
for (OperationNode *node : state->graph->operations) {
- schedule_node(state, node, false, schedule_function, schedule_function_args...);
+ schedule_node(state, node, false, schedule_fn);
}
}
-template<typename ScheduleFunction, typename... ScheduleFunctionArgs>
void schedule_children(DepsgraphEvalState *state,
OperationNode *node,
- ScheduleFunction *schedule_function,
- ScheduleFunctionArgs... schedule_function_args)
+ const FunctionRef<void(OperationNode *node)> schedule_fn)
{
for (Relation *rel : node->outlinks) {
OperationNode *child = (OperationNode *)rel->to;
@@ -309,21 +299,10 @@ void schedule_children(DepsgraphEvalState *state,
/* Happens when having cyclic dependencies. */
continue;
}
- schedule_node(state,
- child,
- (rel->flag & RELATION_FLAG_CYCLIC) == 0,
- schedule_function,
- schedule_function_args...);
+ schedule_node(state, child, (rel->flag & RELATION_FLAG_CYCLIC) == 0, schedule_fn);
}
}
-void schedule_node_to_queue(OperationNode *node,
- const int /*thread_id*/,
- GSQueue *evaluation_queue)
-{
- BLI_gsqueue_push(evaluation_queue, &node);
-}
-
/* Evaluate given stage of the dependency graph evaluation using multiple threads.
*
* NOTE: Will assign the `state->stage` to the given stage. */
@@ -335,7 +314,9 @@ void evaluate_graph_threaded_stage(DepsgraphEvalState *state,
calculate_pending_parents_if_needed(state);
- schedule_graph(state, schedule_node_to_pool, task_pool);
+ schedule_graph(state, [&](OperationNode *node) {
+ BLI_task_pool_push(task_pool, deg_task_run_func, node, false, nullptr);
+ });
BLI_task_pool_work_and_wait(task_pool);
}
@@ -351,14 +332,17 @@ void evaluate_graph_single_threaded_if_needed(DepsgraphEvalState *state)
state->stage = EvaluationStage::SINGLE_THREADED_WORKAROUND;
GSQueue *evaluation_queue = BLI_gsqueue_new(sizeof(OperationNode *));
- schedule_graph(state, schedule_node_to_queue, evaluation_queue);
+ auto schedule_node_to_queue = [&](OperationNode *node) {
+ BLI_gsqueue_push(evaluation_queue, &node);
+ };
+ schedule_graph(state, schedule_node_to_queue);
while (!BLI_gsqueue_is_empty(evaluation_queue)) {
OperationNode *operation_node;
BLI_gsqueue_pop(evaluation_queue, &operation_node);
evaluate_node(state, operation_node);
- schedule_children(state, operation_node, schedule_node_to_queue, evaluation_queue);
+ schedule_children(state, operation_node, schedule_node_to_queue);
}
BLI_gsqueue_free(evaluation_queue);
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index 058f57e5a61..4e07a7b173c 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -414,13 +414,16 @@ void scene_remove_all_bases(Scene *scene_cow)
/* Makes it so given view layer only has bases corresponding to enabled
* objects. */
-void view_layer_remove_disabled_bases(const Depsgraph *depsgraph, ViewLayer *view_layer)
+void view_layer_remove_disabled_bases(const Depsgraph *depsgraph,
+ const Scene *scene,
+ ViewLayer *view_layer)
{
if (view_layer == nullptr) {
return;
}
ListBase enabled_bases = {nullptr, nullptr};
- LISTBASE_FOREACH_MUTABLE (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH_MUTABLE (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
/* TODO(sergey): Would be cool to optimize this somehow, or make it so
* builder tags bases.
*
@@ -479,7 +482,7 @@ void scene_setup_view_layers_after_remap(const Depsgraph *depsgraph,
const ViewLayer *view_layer_orig = get_original_view_layer(depsgraph, id_node);
ViewLayer *view_layer_eval = reinterpret_cast<ViewLayer *>(scene_cow->view_layers.first);
view_layer_update_orig_base_pointers(view_layer_orig, view_layer_eval);
- view_layer_remove_disabled_bases(depsgraph, view_layer_eval);
+ view_layer_remove_disabled_bases(depsgraph, scene_cow, view_layer_eval);
/* TODO(sergey): Remove objects from collections as well.
* Not a HUGE deal for now, nobody is looking into those CURRENTLY.
* Still not an excuse to have those. */
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
index 3f42d1a80c1..62a9158928d 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
@@ -31,7 +31,6 @@
#include "intern/debug/deg_debug.h"
#include "intern/depsgraph.h"
#include "intern/depsgraph_relation.h"
-#include "intern/depsgraph_tag.h"
#include "intern/depsgraph_type.h"
#include "intern/depsgraph_update.h"
#include "intern/node/deg_node.h"
@@ -100,18 +99,6 @@ inline void flush_prepare(Depsgraph *graph)
inline void flush_schedule_entrypoints(Depsgraph *graph, FlushQueue *queue)
{
- /* Something changed in the scene, so re-tag IDs with flags which were previously ignored due to
- * ID being hidden. This will ensure the ID is properly evaluated when it becomes visible. */
- for (IDNode *node : graph->id_nodes) {
- if (node->id_invisible_recalc) {
- graph_id_tag_update(graph->bmain,
- graph,
- node->id_orig,
- node->id_invisible_recalc,
- DEG_UPDATE_SOURCE_VISIBILITY);
- }
- }
-
for (OperationNode *op_node : graph->entry_tags) {
queue->push_back(op_node);
op_node->scheduled = true;
@@ -248,7 +235,7 @@ void flush_editors_id_update(Depsgraph *graph, const DEGEditorUpdateContext *upd
EVAL,
"Accumulated recalc bits for %s: %u\n",
id_orig->name,
- (unsigned int)id_cow->recalc);
+ uint(id_cow->recalc));
/* Inform editors. Only if the data-block is being evaluated a second
* time, to distinguish between user edits and initial evaluation when
@@ -297,7 +284,7 @@ void invalidate_tagged_evaluated_transform(ID *id)
switch (id_type) {
case ID_OB: {
Object *object = (Object *)id;
- copy_vn_fl((float *)object->obmat, 16, NAN);
+ copy_vn_fl((float *)object->object_to_world, 16, NAN);
break;
}
default:
@@ -384,10 +371,6 @@ void deg_graph_flush_updates(Depsgraph *graph)
while (op_node != nullptr) {
/* Tag operation as required for update. */
op_node->flag |= DEPSOP_FLAG_NEEDS_UPDATE;
- /* Tag depsgraph visibility update when visibility operation is tagged for an update. */
- if (op_node->opcode == OperationCode::VISIBILITY) {
- graph->need_update_nodes_visibility = true;
- }
/* Inform corresponding ID and component nodes about the change. */
ComponentNode *comp_node = op_node->owner;
IDNode *id_node = comp_node->owner;
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.cc
index c5def69a70f..e3d7593eb3c 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.cc
@@ -19,7 +19,7 @@ GPencilBackup::GPencilBackup(const Depsgraph *depsgraph) : depsgraph(depsgraph)
{
}
-void GPencilBackup::init_from_gpencil(bGPdata *UNUSED(gpd))
+void GPencilBackup::init_from_gpencil(bGPdata * /*gpd*/)
{
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc b/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc
index 515c9a197d7..0ee4052eff3 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc
@@ -34,13 +34,11 @@ void deg_evaluate_object_node_visibility(::Depsgraph *depsgraph, IDNode *id_node
DEG_debug_print_eval(depsgraph, __func__, object->id.name, &object->id);
- bool is_enabled;
- if (graph->mode == DAG_EVAL_VIEWPORT) {
- is_enabled = (object->base_flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT);
- }
- else {
- is_enabled = (object->base_flag & BASE_ENABLED_RENDER);
- };
+ const int required_flags = (graph->mode == DAG_EVAL_VIEWPORT) ? BASE_ENABLED_VIEWPORT :
+ BASE_ENABLED_RENDER;
+
+ const bool is_enabled = !graph->use_visibility_optimization ||
+ object->base_flag & required_flags;
if (id_node->is_enabled_on_eval != is_enabled) {
id_node->is_enabled_on_eval = is_enabled;
@@ -76,7 +74,8 @@ void deg_evaluate_object_modifiers_mode_node_visibility(::Depsgraph *depsgraph,
"Modifier node in depsgraph is not found. Likely due to missing "
"DEG_relations_tag_update().");
- const bool modifier_enabled = modifier->mode & modifier_mode;
+ const bool modifier_enabled = !graph->use_visibility_optimization ||
+ (modifier->mode & modifier_mode);
const int mute_flag = modifier_enabled ? 0 : DEPSOP_FLAG_MUTE;
if ((modifier_node->flag & DEPSOP_FLAG_MUTE) != mute_flag) {
modifier_node->flag &= ~DEPSOP_FLAG_MUTE;
diff --git a/source/blender/depsgraph/intern/node/deg_node.cc b/source/blender/depsgraph/intern/node/deg_node.cc
index 7a515424e06..6303b22cac3 100644
--- a/source/blender/depsgraph/intern/node/deg_node.cc
+++ b/source/blender/depsgraph/intern/node/deg_node.cc
@@ -100,6 +100,8 @@ const char *nodeTypeAsString(NodeType type)
return "SIMULATION";
case NodeType::NTREE_OUTPUT:
return "NTREE_OUTPUT";
+ case NodeType::NTREE_GEOMETRY_PREPROCESS:
+ return "NTREE_GEOMETRY_PREPROCESS";
/* Total number of meaningful node types. */
case NodeType::NUM_TYPES:
@@ -158,6 +160,7 @@ eDepsSceneComponentType nodeTypeToSceneComponent(NodeType type)
case NodeType::CACHE:
case NodeType::SIMULATION:
case NodeType::NTREE_OUTPUT:
+ case NodeType::NTREE_GEOMETRY_PREPROCESS:
return DEG_SCENE_COMP_PARAMETERS;
case NodeType::VISIBILITY:
@@ -232,6 +235,7 @@ eDepsObjectComponentType nodeTypeToObjectComponent(NodeType type)
case NodeType::SYNCHRONIZATION:
case NodeType::SIMULATION:
case NodeType::NTREE_OUTPUT:
+ case NodeType::NTREE_GEOMETRY_PREPROCESS:
case NodeType::UNDEFINED:
case NodeType::NUM_TYPES:
return DEG_OB_COMP_PARAMETERS;
diff --git a/source/blender/depsgraph/intern/node/deg_node.h b/source/blender/depsgraph/intern/node/deg_node.h
index db912ee3a82..e31c1769a2a 100644
--- a/source/blender/depsgraph/intern/node/deg_node.h
+++ b/source/blender/depsgraph/intern/node/deg_node.h
@@ -130,6 +130,8 @@ enum class NodeType {
SIMULATION,
/* Node tree output component. */
NTREE_OUTPUT,
+ /* Preprocessing for geometry node trees before they can be evaluated. */
+ NTREE_GEOMETRY_PREPROCESS,
/* Total number of meaningful node types. */
NUM_TYPES,
diff --git a/source/blender/depsgraph/intern/node/deg_node_component.cc b/source/blender/depsgraph/intern/node/deg_node_component.cc
index f2d82e80fa6..718097b4ef8 100644
--- a/source/blender/depsgraph/intern/node/deg_node_component.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_component.cc
@@ -48,18 +48,18 @@ ComponentNode::OperationIDKey::OperationIDKey(OperationCode opcode, const char *
string ComponentNode::OperationIDKey::identifier() const
{
- const string codebuf = to_string(static_cast<int>(opcode));
+ const string codebuf = to_string(int(opcode));
return "OperationIDKey(" + codebuf + ", " + name + ")";
}
bool ComponentNode::OperationIDKey::operator==(const OperationIDKey &other) const
{
- return (opcode == other.opcode) && (STREQ(name, other.name)) && (name_tag == other.name_tag);
+ return (opcode == other.opcode) && STREQ(name, other.name) && (name_tag == other.name_tag);
}
uint64_t ComponentNode::OperationIDKey::hash() const
{
- const int opcode_as_int = static_cast<int>(opcode);
+ const int opcode_as_int = int(opcode);
return BLI_ghashutil_combine_hash(
name_tag,
BLI_ghashutil_combine_hash(BLI_ghashutil_uinthash(opcode_as_int),
@@ -90,10 +90,11 @@ ComponentNode::~ComponentNode()
string ComponentNode::identifier() const
{
- const string idname = this->owner->name;
- const string typebuf = "" + to_string(static_cast<int>(type)) + ")";
- return typebuf + name + " : " + idname +
- "( affects_visible_id: " + (affects_visible_id ? "true" : "false") + ")";
+ const string type_name = type_get_factory(type)->type_name();
+ const string name_part = name[0] ? (string(" '") + name + "'") : "";
+
+ return "[" + type_name + "]" + name_part + " : " +
+ "(affects_visible_id: " + (affects_visible_id ? "true" : "false") + ")";
}
OperationNode *ComponentNode::find_operation(OperationIDKey key) const
@@ -337,6 +338,7 @@ DEG_COMPONENT_NODE_DEFINE(GenericDatablock, GENERIC_DATABLOCK, 0);
DEG_COMPONENT_NODE_DEFINE(Visibility, VISIBILITY, 0);
DEG_COMPONENT_NODE_DEFINE(Simulation, SIMULATION, 0);
DEG_COMPONENT_NODE_DEFINE(NTreeOutput, NTREE_OUTPUT, ID_RECALC_NTREE_OUTPUT);
+DEG_COMPONENT_NODE_DEFINE(NTreeGeometryPreprocess, NTREE_GEOMETRY_PREPROCESS, 0);
/** \} */
@@ -371,6 +373,7 @@ void deg_register_component_depsnodes()
register_node_typeinfo(&DNTI_VISIBILITY);
register_node_typeinfo(&DNTI_SIMULATION);
register_node_typeinfo(&DNTI_NTREE_OUTPUT);
+ register_node_typeinfo(&DNTI_NTREE_GEOMETRY_PREPROCESS);
}
/** \} */
diff --git a/source/blender/depsgraph/intern/node/deg_node_component.h b/source/blender/depsgraph/intern/node/deg_node_component.h
index f7f38b88854..44c63822ca3 100644
--- a/source/blender/depsgraph/intern/node/deg_node_component.h
+++ b/source/blender/depsgraph/intern/node/deg_node_component.h
@@ -208,6 +208,7 @@ DEG_COMPONENT_NODE_DECLARE_GENERIC(GenericDatablock);
DEG_COMPONENT_NODE_DECLARE_NO_COW_TAG_ON_UPDATE(Visibility);
DEG_COMPONENT_NODE_DECLARE_GENERIC(Simulation);
DEG_COMPONENT_NODE_DECLARE_GENERIC(NTreeOutput);
+DEG_COMPONENT_NODE_DECLARE_GENERIC(NTreeGeometryPreprocess);
/* Bone Component */
struct BoneComponentNode : public ComponentNode {
diff --git a/source/blender/depsgraph/intern/node/deg_node_factory.cc b/source/blender/depsgraph/intern/node/deg_node_factory.cc
index bcdfdbec604..4c08d4ee7bb 100644
--- a/source/blender/depsgraph/intern/node/deg_node_factory.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_factory.cc
@@ -10,19 +10,19 @@
namespace blender::deg {
/* Global type registry */
-static DepsNodeFactory *node_typeinfo_registry[static_cast<int>(NodeType::NUM_TYPES)] = {nullptr};
+static DepsNodeFactory *node_typeinfo_registry[int(NodeType::NUM_TYPES)] = {nullptr};
void register_node_typeinfo(DepsNodeFactory *factory)
{
BLI_assert(factory != nullptr);
- const int type_as_int = static_cast<int>(factory->type());
+ const int type_as_int = int(factory->type());
node_typeinfo_registry[type_as_int] = factory;
}
DepsNodeFactory *type_get_factory(const NodeType type)
{
/* Look up type - at worst, it doesn't exist in table yet, and we fail. */
- const int type_as_int = static_cast<int>(type);
+ const int type_as_int = int(type);
return node_typeinfo_registry[type_as_int];
}
diff --git a/source/blender/depsgraph/intern/node/deg_node_factory_impl.h b/source/blender/depsgraph/intern/node/deg_node_factory_impl.h
index d9d0a1c1e3e..5059368120e 100644
--- a/source/blender/depsgraph/intern/node/deg_node_factory_impl.h
+++ b/source/blender/depsgraph/intern/node/deg_node_factory_impl.h
@@ -34,15 +34,8 @@ Node *DepsNodeFactoryImpl<ModeObjectType>::create_node(const ID *id,
const char *name) const
{
Node *node = new ModeObjectType();
- /* Populate base node settings. */
node->type = type();
- /* Set name if provided, or use default type name. */
- if (name[0] != '\0') {
- node->name = name;
- }
- else {
- node->name = type_name();
- }
+ node->name = name;
node->init(id, subdata);
return node;
}
diff --git a/source/blender/depsgraph/intern/node/deg_node_id.cc b/source/blender/depsgraph/intern/node/deg_node_id.cc
index 9a7d27808be..a37feb7b95d 100644
--- a/source/blender/depsgraph/intern/node/deg_node_id.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_id.cc
@@ -52,12 +52,12 @@ bool IDNode::ComponentIDKey::operator==(const ComponentIDKey &other) const
uint64_t IDNode::ComponentIDKey::hash() const
{
- const int type_as_int = static_cast<int>(type);
+ const int type_as_int = int(type);
return BLI_ghashutil_combine_hash(BLI_ghashutil_uinthash(type_as_int),
BLI_ghashutil_strhash_p(name));
}
-void IDNode::init(const ID *id, const char *UNUSED(subdata))
+void IDNode::init(const ID *id, const char * /*subdata*/)
{
BLI_assert(id != nullptr);
/* Store ID-pointer. */
@@ -75,7 +75,6 @@ void IDNode::init(const ID *id, const char *UNUSED(subdata))
has_base = false;
is_user_modified = false;
id_cow_recalc_backup = 0;
- id_invisible_recalc = 0;
visible_components_mask = 0;
previously_visible_components_mask = 0;
@@ -191,7 +190,7 @@ IDComponentsMask IDNode::get_visible_components_mask() const
IDComponentsMask result = 0;
for (ComponentNode *comp_node : components.values()) {
if (comp_node->possibly_affects_visible_id) {
- const int component_type_as_int = static_cast<int>(comp_node->type);
+ const int component_type_as_int = int(comp_node->type);
BLI_assert(component_type_as_int < 64);
result |= (1ULL << component_type_as_int);
}
diff --git a/source/blender/depsgraph/intern/node/deg_node_id.h b/source/blender/depsgraph/intern/node/deg_node_id.h
index e9bbc816907..7f0a656cb8d 100644
--- a/source/blender/depsgraph/intern/node/deg_node_id.h
+++ b/source/blender/depsgraph/intern/node/deg_node_id.h
@@ -123,9 +123,6 @@ struct IDNode : public Node {
/* Accumulate recalc flags from multiple update passes. */
int id_cow_recalc_backup;
- /* Flags which components were not evaluated due to ID being invisible. */
- int id_invisible_recalc;
-
IDComponentsMask visible_components_mask;
IDComponentsMask previously_visible_components_mask;
diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc
index 016af735fcf..d5401a6b0d1 100644
--- a/source/blender/depsgraph/intern/node/deg_node_operation.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc
@@ -173,6 +173,8 @@ const char *operationCodeAsString(OperationCode opcode)
/* Node Tree. */
case OperationCode::NTREE_OUTPUT:
return "NTREE_OUTPUT";
+ case OperationCode::NTREE_GEOMETRY_PREPROCESS:
+ return "NTREE_GEOMETRY_PREPROCESS";
/* Movie clip. */
case OperationCode::MOVIECLIP_EVAL:
return "MOVIECLIP_EVAL";
diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h
index cb3beb56556..b0685ac0351 100644
--- a/source/blender/depsgraph/intern/node/deg_node_operation.h
+++ b/source/blender/depsgraph/intern/node/deg_node_operation.h
@@ -165,6 +165,7 @@ enum class OperationCode {
/* Node Tree. ----------------------------------------------------------- */
NTREE_OUTPUT,
+ NTREE_GEOMETRY_PREPROCESS,
/* Batch caches. -------------------------------------------------------- */
GEOMETRY_SELECT_UPDATE,
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index e6b532ed25a..5902dc18165 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -24,6 +24,8 @@ set(INC
../render
../render/intern
../compositor/realtime_compositor
+ ../compositor/realtime_compositor/algorithms
+ ../compositor/realtime_compositor/cached_resources
../windowmanager
../../../intern/atomic
@@ -71,13 +73,13 @@ set(SRC
intern/draw_attributes.cc
intern/draw_cache_impl_curve.cc
intern/draw_cache_impl_curves.cc
- intern/draw_cache_impl_gpencil.c
+ intern/draw_cache_impl_gpencil.cc
intern/draw_cache_impl_lattice.c
intern/draw_cache_impl_mesh.cc
intern/draw_cache_impl_particles.c
intern/draw_cache_impl_pointcloud.cc
intern/draw_cache_impl_subdivision.cc
- intern/draw_cache_impl_volume.c
+ intern/draw_cache_impl_volume.cc
intern/draw_color_management.cc
intern/draw_command.cc
intern/draw_common.c
@@ -88,12 +90,14 @@ set(SRC
intern/draw_instance_data.c
intern/draw_manager.c
intern/draw_manager.cc
- intern/draw_manager_data.c
+ intern/draw_manager_data.cc
intern/draw_manager_exec.c
intern/draw_manager_profiling.c
intern/draw_manager_shader.c
- intern/draw_manager_text.c
+ intern/draw_manager_text.cc
intern/draw_manager_texture.c
+ intern/draw_pbvh.cc
+ intern/draw_pointcloud.cc
intern/draw_select_buffer.c
intern/draw_shader.cc
intern/draw_texture_pool.cc
@@ -176,35 +180,37 @@ set(SRC
engines/gpencil/gpencil_shader_fx.c
engines/select/select_draw_utils.c
engines/select/select_engine.c
- engines/overlay/overlay_antialiasing.c
- engines/overlay/overlay_armature.c
- engines/overlay/overlay_background.c
- engines/overlay/overlay_edit_curve.c
+ engines/overlay/overlay_antialiasing.cc
+ engines/overlay/overlay_armature.cc
+ engines/overlay/overlay_background.cc
+ engines/overlay/overlay_edit_curve.cc
engines/overlay/overlay_edit_curves.cc
- engines/overlay/overlay_edit_mesh.c
- engines/overlay/overlay_edit_text.c
- engines/overlay/overlay_edit_uv.c
- engines/overlay/overlay_engine.c
- engines/overlay/overlay_extra.c
- engines/overlay/overlay_facing.c
- engines/overlay/overlay_fade.c
- engines/overlay/overlay_gpencil.c
- engines/overlay/overlay_grid.c
- engines/overlay/overlay_image.c
- engines/overlay/overlay_lattice.c
- engines/overlay/overlay_metaball.c
- engines/overlay/overlay_mode_transfer.c
- engines/overlay/overlay_motion_path.c
- engines/overlay/overlay_outline.c
- engines/overlay/overlay_paint.c
- engines/overlay/overlay_particle.c
- engines/overlay/overlay_sculpt.c
+ engines/overlay/overlay_edit_mesh.cc
+ engines/overlay/overlay_edit_text.cc
+ engines/overlay/overlay_edit_uv.cc
+ engines/overlay/overlay_engine.cc
+ engines/overlay/overlay_extra.cc
+ engines/overlay/overlay_facing.cc
+ engines/overlay/overlay_fade.cc
+ engines/overlay/overlay_gpencil.cc
+ engines/overlay/overlay_grid.cc
+ engines/overlay/overlay_image.cc
+ engines/overlay/overlay_lattice.cc
+ engines/overlay/overlay_metaball.cc
+ engines/overlay/overlay_mode_transfer.cc
+ engines/overlay/overlay_motion_path.cc
+ engines/overlay/overlay_outline.cc
+ engines/overlay/overlay_paint.cc
+ engines/overlay/overlay_particle.cc
+ engines/overlay/overlay_sculpt.cc
engines/overlay/overlay_sculpt_curves.cc
- engines/overlay/overlay_shader.c
- engines/overlay/overlay_volume.c
- engines/overlay/overlay_wireframe.c
+ engines/overlay/overlay_shader.cc
+ engines/overlay/overlay_viewer_attribute.cc
+ engines/overlay/overlay_volume.cc
+ engines/overlay/overlay_wireframe.cc
DRW_engine.h
+ DRW_pbvh.h
DRW_select_buffer.h
intern/DRW_gpu_wrapper.hh
intern/DRW_render.h
@@ -229,6 +235,7 @@ set(SRC
intern/draw_manager_testing.h
intern/draw_manager_text.h
intern/draw_pass.hh
+ intern/draw_pbvh.h
intern/draw_resource.cc
intern/draw_resource.hh
intern/draw_shader.h
@@ -250,6 +257,7 @@ set(SRC
engines/eevee/eevee_lut.h
engines/eevee/eevee_private.h
engines/eevee_next/eevee_camera.hh
+ engines/eevee_next/eevee_cryptomatte.hh
engines/eevee_next/eevee_depth_of_field.hh
engines/eevee_next/eevee_engine.h
engines/eevee_next/eevee_film.hh
@@ -286,7 +294,7 @@ set(SRC
engines/select/select_engine.h
engines/select/select_private.h
engines/overlay/overlay_engine.h
- engines/overlay/overlay_private.h
+ engines/overlay/overlay_private.hh
)
set(LIB
@@ -388,7 +396,6 @@ set(GLSL_SRC
engines/eevee/shaders/volumetric_frag.glsl
engines/eevee/shaders/volumetric_geom.glsl
engines/eevee/shaders/volumetric_vert.glsl
- engines/eevee/shaders/volumetric_resolve_comp.glsl
engines/eevee/shaders/volumetric_resolve_frag.glsl
engines/eevee/shaders/volumetric_scatter_frag.glsl
engines/eevee/shaders/volumetric_integration_frag.glsl
@@ -486,7 +493,6 @@ set(GLSL_SRC
intern/shaders/common_debug_shape_lib.glsl
intern/shaders/common_fullscreen_vert.glsl
intern/shaders/common_fxaa_lib.glsl
- intern/shaders/common_globals_lib.glsl
intern/shaders/common_gpencil_lib.glsl
intern/shaders/common_hair_lib.glsl
intern/shaders/common_hair_refine_comp.glsl
@@ -556,6 +562,7 @@ set(GLSL_SRC
engines/overlay/shaders/overlay_armature_envelope_solid_vert.glsl
engines/overlay/shaders/overlay_armature_shape_outline_geom.glsl
engines/overlay/shaders/overlay_armature_shape_outline_vert.glsl
+ engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl
engines/overlay/shaders/overlay_armature_shape_solid_frag.glsl
engines/overlay/shaders/overlay_armature_shape_solid_vert.glsl
engines/overlay/shaders/overlay_armature_shape_wire_vert.glsl
@@ -573,6 +580,7 @@ set(GLSL_SRC
engines/overlay/shaders/overlay_depth_only_vert.glsl
engines/overlay/shaders/overlay_edit_curve_handle_geom.glsl
engines/overlay/shaders/overlay_edit_curve_handle_vert.glsl
+ engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl
engines/overlay/shaders/overlay_edit_curve_point_vert.glsl
engines/overlay/shaders/overlay_edit_curve_wire_vert.glsl
engines/overlay/shaders/overlay_edit_gpencil_canvas_vert.glsl
@@ -588,6 +596,7 @@ set(GLSL_SRC
engines/overlay/shaders/overlay_edit_mesh_normal_vert.glsl
engines/overlay/shaders/overlay_edit_mesh_skin_root_vert.glsl
engines/overlay/shaders/overlay_edit_mesh_vert.glsl
+ engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl
engines/overlay/shaders/overlay_edit_particle_point_vert.glsl
engines/overlay/shaders/overlay_edit_particle_strand_vert.glsl
engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl
@@ -620,6 +629,7 @@ set(GLSL_SRC
engines/overlay/shaders/overlay_motion_path_line_frag.glsl
engines/overlay/shaders/overlay_motion_path_line_geom.glsl
engines/overlay/shaders/overlay_motion_path_line_vert.glsl
+ engines/overlay/shaders/overlay_motion_path_line_vert_no_geom.glsl
engines/overlay/shaders/overlay_motion_path_point_vert.glsl
engines/overlay/shaders/overlay_outline_detect_frag.glsl
engines/overlay/shaders/overlay_outline_prepass_curves_vert.glsl
@@ -642,12 +652,18 @@ set(GLSL_SRC
engines/overlay/shaders/overlay_particle_vert.glsl
engines/overlay/shaders/overlay_point_varying_color_frag.glsl
engines/overlay/shaders/overlay_point_varying_color_varying_outline_aa_frag.glsl
+ engines/overlay/shaders/overlay_pointcloud_only_vert.glsl
engines/overlay/shaders/overlay_sculpt_curves_selection_frag.glsl
engines/overlay/shaders/overlay_sculpt_curves_selection_vert.glsl
engines/overlay/shaders/overlay_sculpt_mask_frag.glsl
engines/overlay/shaders/overlay_sculpt_mask_vert.glsl
engines/overlay/shaders/overlay_uniform_color_frag.glsl
engines/overlay/shaders/overlay_varying_color.glsl
+ engines/overlay/shaders/overlay_viewer_attribute_curve_vert.glsl
+ engines/overlay/shaders/overlay_viewer_attribute_curves_vert.glsl
+ engines/overlay/shaders/overlay_viewer_attribute_frag.glsl
+ engines/overlay/shaders/overlay_viewer_attribute_mesh_vert.glsl
+ engines/overlay/shaders/overlay_viewer_attribute_pointcloud_vert.glsl
engines/overlay/shaders/overlay_volume_gridlines_vert.glsl
engines/overlay/shaders/overlay_volume_velocity_vert.glsl
engines/overlay/shaders/overlay_wireframe_frag.glsl
@@ -718,6 +734,21 @@ if(WITH_GTESTS)
endif()
endif()
+if(WITH_TBB)
+ add_definitions(-DWITH_TBB)
+ if(WIN32)
+ # TBB includes Windows.h which will define min/max macros
+ # that will collide with the stl versions.
+ add_definitions(-DNOMINMAX)
+ endif()
+ list(APPEND INC_SYS
+ ${TBB_INCLUDE_DIRS}
+ )
+
+ list(APPEND LIB
+ ${TBB_LIBRARIES}
+ )
+endif()
blender_add_lib(bf_draw "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
@@ -743,3 +774,4 @@ if(WITH_GTESTS)
blender_add_test_lib(bf_draw_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
endif()
endif()
+
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index dec7a22aadb..8c5f1b70cc0 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -126,14 +126,10 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
void DRW_draw_depth_loop(struct Depsgraph *depsgraph,
struct ARegion *region,
struct View3D *v3d,
- struct GPUViewport *viewport);
-/**
- * Converted from #ED_view3d_draw_depth_gpencil (legacy drawing).
- */
-void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
- struct ARegion *region,
- struct View3D *v3d,
- struct GPUViewport *viewport);
+ struct GPUViewport *viewport,
+ const bool use_gpencil,
+ const bool use_basic,
+ const bool use_overlay);
/**
* Clears the Depth Buffer and draws only the specified object.
*/
diff --git a/source/blender/draw/DRW_pbvh.h b/source/blender/draw/DRW_pbvh.h
new file mode 100644
index 00000000000..ffd4b92d87b
--- /dev/null
+++ b/source/blender/draw/DRW_pbvh.h
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. */
+
+/** \file
+ * \ingroup draw
+ */
+
+#pragma once
+
+/* Needed for BKE_ccg.h. */
+#include "BLI_assert.h"
+#include "BLI_bitmap.h"
+
+#include "BKE_ccg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct GPUViewport;
+struct PBVHAttrReq;
+struct GPUBatch;
+struct PBVHNode;
+struct GSet;
+struct DMFlagMat;
+struct Object;
+struct Mesh;
+struct MLoopTri;
+struct CustomData;
+struct MVert;
+struct MEdge;
+struct MLoop;
+struct MPoly;
+struct SubdivCCG;
+struct BMesh;
+
+typedef struct PBVHBatches PBVHBatches;
+
+typedef struct PBVH_GPU_Args {
+ int pbvh_type;
+
+ struct BMesh *bm;
+ const struct Mesh *me;
+ const struct MVert *mvert;
+ const struct MLoop *mloop;
+ const struct MPoly *mpoly;
+ int mesh_verts_num, mesh_faces_num, mesh_grids_num;
+ struct CustomData *vdata, *ldata, *pdata;
+ const float (*vert_normals)[3];
+
+ int face_sets_color_seed, face_sets_color_default;
+ int *face_sets; /* for PBVH_FACES and PBVH_GRIDS */
+
+ struct SubdivCCG *subdiv_ccg;
+ const struct DMFlagMat *grid_flag_mats;
+ const int *grid_indices;
+ CCGKey ccg_key;
+ CCGElem **grids;
+ void **gridfaces;
+ BLI_bitmap **grid_hidden;
+
+ int *prim_indices;
+ int totprim;
+
+ bool *hide_poly;
+
+ int node_verts_num;
+
+ const struct MLoopTri *mlooptri;
+ struct PBVHNode *node;
+
+ /* BMesh. */
+ struct GSet *bm_unique_vert, *bm_other_verts, *bm_faces;
+ int cd_mask_layer;
+} PBVH_GPU_Args;
+
+typedef struct PBVHGPUFormat PBVHGPUFormat;
+
+void DRW_pbvh_node_update(PBVHBatches *batches, PBVH_GPU_Args *args);
+void DRW_pbvh_update_pre(PBVHBatches *batches, PBVH_GPU_Args *args);
+
+void DRW_pbvh_node_gpu_flush(PBVHBatches *batches);
+struct PBVHBatches *DRW_pbvh_node_create(PBVH_GPU_Args *args);
+void DRW_pbvh_node_free(PBVHBatches *batches);
+struct GPUBatch *DRW_pbvh_tris_get(PBVHBatches *batches,
+ struct PBVHAttrReq *attrs,
+ int attrs_num,
+ PBVH_GPU_Args *args,
+ int *r_prim_count);
+struct GPUBatch *DRW_pbvh_lines_get(struct PBVHBatches *batches,
+ struct PBVHAttrReq *attrs,
+ int attrs_num,
+ PBVH_GPU_Args *args,
+ int *r_prim_count);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c
index 975d9e299bf..05e62764bb1 100644
--- a/source/blender/draw/engines/basic/basic_engine.c
+++ b/source/blender/draw/engines/basic/basic_engine.c
@@ -85,8 +85,7 @@ static void basic_cache_init(void *vedata)
DRW_PASS_CREATE(psl->depth_pass[i], state | clip_state | infront_state);
stl->g_data->depth_shgrp[i] = grp = DRW_shgroup_create(sh, psl->depth_pass[i]);
- DRW_shgroup_uniform_vec2(grp, "sizeViewport", DRW_viewport_size_get(), 1);
- DRW_shgroup_uniform_vec2(grp, "sizeViewportInv", DRW_viewport_invert_size_get(), 1);
+ DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
sh = DRW_state_is_select() ?
BASIC_shaders_pointcloud_depth_conservative_sh_get(draw_ctx->sh_cfg) :
@@ -94,22 +93,22 @@ static void basic_cache_init(void *vedata)
DRW_PASS_CREATE(psl->depth_pass_pointcloud[i], state | clip_state | infront_state);
stl->g_data->depth_pointcloud_shgrp[i] = grp = DRW_shgroup_create(
sh, psl->depth_pass_pointcloud[i]);
- DRW_shgroup_uniform_vec2(grp, "sizeViewport", DRW_viewport_size_get(), 1);
- DRW_shgroup_uniform_vec2(grp, "sizeViewportInv", DRW_viewport_invert_size_get(), 1);
+ DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
stl->g_data->depth_hair_shgrp[i] = grp = DRW_shgroup_create(
BASIC_shaders_depth_sh_get(draw_ctx->sh_cfg), psl->depth_pass[i]);
+ DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
stl->g_data->depth_curves_shgrp[i] = grp = DRW_shgroup_create(
BASIC_shaders_curves_depth_sh_get(draw_ctx->sh_cfg), psl->depth_pass[i]);
+ DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
sh = DRW_state_is_select() ? BASIC_shaders_depth_conservative_sh_get(draw_ctx->sh_cfg) :
BASIC_shaders_depth_sh_get(draw_ctx->sh_cfg);
state |= DRW_STATE_CULL_BACK;
DRW_PASS_CREATE(psl->depth_pass_cull[i], state | clip_state | infront_state);
stl->g_data->depth_shgrp_cull[i] = grp = DRW_shgroup_create(sh, psl->depth_pass_cull[i]);
- DRW_shgroup_uniform_vec2(grp, "sizeViewport", DRW_viewport_size_get(), 1);
- DRW_shgroup_uniform_vec2(grp, "sizeViewportInv", DRW_viewport_invert_size_get(), 1);
+ DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
}
}
@@ -183,7 +182,7 @@ static void basic_cache_populate(void *vedata, Object *ob)
}
}
- const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) &&
+ const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->rv3d) &&
!DRW_state_is_image_render();
const bool do_cull = (draw_ctx->v3d &&
(draw_ctx->v3d->shading.flag & V3D_SHADING_BACKFACE_CULLING));
@@ -199,7 +198,7 @@ static void basic_cache_populate(void *vedata, Object *ob)
}
if (use_sculpt_pbvh) {
- DRW_shgroup_call_sculpt(shgrp, ob, false, false);
+ DRW_shgroup_call_sculpt(shgrp, ob, false, false, false, false, false);
}
else {
if (stl->g_data->use_material_slot_selection && BKE_object_supports_material_slots(ob)) {
diff --git a/source/blender/draw/engines/basic/shaders/basic_conservative_depth_geom.glsl b/source/blender/draw/engines/basic/shaders/basic_conservative_depth_geom.glsl
index d478f37691e..73b171e5cb6 100644
--- a/source/blender/draw/engines/basic/shaders/basic_conservative_depth_geom.glsl
+++ b/source/blender/draw/engines/basic/shaders/basic_conservative_depth_geom.glsl
@@ -11,7 +11,7 @@
void main()
{
- /* Compute plane normal in ndc space. */
+ /* Compute plane normal in NDC space. */
vec3 pos0 = gl_in[0].gl_Position.xyz / gl_in[0].gl_Position.w;
vec3 pos1 = gl_in[1].gl_Position.xyz / gl_in[1].gl_Position.w;
vec3 pos2 = gl_in[2].gl_Position.xyz / gl_in[2].gl_Position.w;
@@ -19,7 +19,7 @@ void main()
/* Compute NDC bound box. */
vec4 bbox = vec4(min(min(pos0.xy, pos1.xy), pos2.xy), max(max(pos0.xy, pos1.xy), pos2.xy));
/* Convert to pixel space. */
- bbox = (bbox * 0.5 + 0.5) * drw_view.viewport_size.xyxy;
+ bbox = (bbox * 0.5 + 0.5) * sizeViewport.xyxy;
/* Detect failure cases where triangles would produce no fragments. */
bvec2 is_subpixel = lessThan(bbox.zw - bbox.xy, vec2(1.0));
/* View aligned triangle. */
@@ -31,13 +31,13 @@ void main()
if (all(is_subpixel)) {
vec2 ofs = (i == 0) ? vec2(-1.0) : ((i == 1) ? vec2(2.0, -1.0) : vec2(-1.0, 2.0));
/* HACK: Fix cases where the triangle is too small make it cover at least one pixel. */
- gl_Position.xy += drw_view.viewport_size_inverse * gl_Position.w * ofs;
+ gl_Position.xy += sizeViewportInv * gl_Position.w * ofs;
}
- /* Test if the triangle is almost parralele with the view to avoid precision issues. */
+ /* Test if the triangle is almost parallel with the view to avoid precision issues. */
else if (any(is_subpixel) || is_coplanar) {
/* HACK: Fix cases where the triangle is Parallel to the view by deforming it slightly. */
vec2 ofs = (i == 0) ? vec2(-1.0) : ((i == 1) ? vec2(1.0, -1.0) : vec2(1.0));
- gl_Position.xy += drw_view.viewport_size_inverse * gl_Position.w * ofs;
+ gl_Position.xy += sizeViewportInv * gl_Position.w * ofs;
}
else {
/* Triangle expansion should happen here, but we decide to not implement it for
diff --git a/source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh b/source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh
index 561cef0e442..e275d208c7a 100644
--- a/source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh
+++ b/source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh
@@ -60,6 +60,6 @@ GPU_SHADER_CREATE_INFO(basic_curves)
GPU_SHADER_CREATE_INFO(basic_depth).fragment_source("basic_depth_frag.glsl");
-BASIC_OBTYPE_VARIATIONS(basic_depth, "basic_depth");
+BASIC_OBTYPE_VARIATIONS(basic_depth, "basic_depth", "draw_globals");
/** \} */
diff --git a/source/blender/draw/engines/compositor/compositor_engine.cc b/source/blender/draw/engines/compositor/compositor_engine.cc
index f36a59a4ce6..2c9e5182b01 100644
--- a/source/blender/draw/engines/compositor/compositor_engine.cc
+++ b/source/blender/draw/engines/compositor/compositor_engine.cc
@@ -60,7 +60,7 @@ class Context : public realtime_compositor::Context {
return DRW_viewport_texture_list_get()->color;
}
- GPUTexture *get_input_texture(int UNUSED(view_layer), eScenePassType UNUSED(pass_type)) override
+ GPUTexture *get_input_texture(int /*view_layer*/, eScenePassType /*pass_type*/) override
{
return get_output_texture();
}
diff --git a/source/blender/draw/engines/eevee/eevee_depth_of_field.c b/source/blender/draw/engines/eevee/eevee_depth_of_field.c
index 0d14a0c5f61..caa63b9c54c 100644
--- a/source/blender/draw/engines/eevee/eevee_depth_of_field.c
+++ b/source/blender/draw/engines/eevee/eevee_depth_of_field.c
@@ -189,7 +189,7 @@ int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata),
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
- Camera *cam = (camera != NULL) ? camera->data : NULL;
+ Camera *cam = (camera != NULL && camera->type == OB_CAMERA) ? camera->data : NULL;
if (cam && (cam->dof.flag & CAM_DOF_ENABLED)) {
RegionView3D *rv3d = draw_ctx->rv3d;
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index 5fa719facf4..0e1cc82797a 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -29,7 +29,7 @@ static struct {
#define SETUP_BUFFER(tex, fb, fb_color) \
{ \
- eGPUTextureFormat format = (DRW_state_is_scene_render()) ? GPU_RGBA32F : GPU_RGBA16F; \
+ eGPUTextureFormat format = DRW_state_is_scene_render() ? GPU_RGBA32F : GPU_RGBA16F; \
DRW_texture_ensure_fullscreen_2d(&tex, format, DRW_TEX_FILTER); \
GPU_framebuffer_ensure_config(&fb, \
{ \
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index 614ea0b0892..26a264c1716 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -142,7 +142,7 @@ typedef struct EEVEE_LightBake {
struct GPUTexture *dummy_layer_color;
int total, done; /* to compute progress */
- short *stop, *do_update;
+ bool *stop, *do_update;
float *progress;
/** For only handling the resources. */
@@ -591,23 +591,26 @@ static void eevee_lightbake_context_enable(EEVEE_LightBake *lbake)
if (GPU_use_main_context_workaround() && !BLI_thread_is_main()) {
GPU_context_main_lock();
DRW_opengl_context_enable();
+ GPU_render_begin();
return;
}
if (lbake->gl_context) {
DRW_opengl_render_context_enable(lbake->gl_context);
if (lbake->gpu_context == NULL) {
- lbake->gpu_context = GPU_context_create(NULL);
+ lbake->gpu_context = GPU_context_create(NULL, lbake->gl_context);
}
DRW_gpu_render_context_enable(lbake->gpu_context);
}
else {
DRW_opengl_context_enable();
}
+ GPU_render_begin();
}
static void eevee_lightbake_context_disable(EEVEE_LightBake *lbake)
{
+ GPU_render_end();
if (GPU_use_main_context_workaround() && !BLI_thread_is_main()) {
DRW_opengl_context_disable();
GPU_context_main_unlock();
@@ -636,7 +639,10 @@ static void eevee_lightbake_count_probes(EEVEE_LightBake *lbake)
/* At least one of each for the world */
lbake->grid_len = lbake->cube_len = lbake->total_irr_samples = 1;
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
+ DEGObjectIterSettings deg_iter_settings = {0};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
const int ob_visibility = BKE_object_visibility(ob, DAG_EVAL_RENDER);
if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
continue;
@@ -655,7 +661,7 @@ static void eevee_lightbake_count_probes(EEVEE_LightBake *lbake)
}
}
}
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
+ DEG_OBJECT_ITER_END;
}
static void eevee_lightbake_create_render_target(EEVEE_LightBake *lbake, int rt_res)
@@ -772,7 +778,7 @@ wmJob *EEVEE_lightbake_job_create(struct wmWindowManager *wm,
}
if (old_lbake->stop != NULL) {
- *old_lbake->stop = 1;
+ *old_lbake->stop = true;
}
BLI_mutex_unlock(old_lbake->mutex);
}
@@ -1279,7 +1285,10 @@ static void eevee_lightbake_gather_probes(EEVEE_LightBake *lbake)
/* Convert all lightprobes to tight UBO data from all lightprobes in the scene.
* This allows a large number of probe to be precomputed (even dupli ones). */
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
+ DEGObjectIterSettings deg_iter_settings = {0};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
const int ob_visibility = BKE_object_visibility(ob, DAG_EVAL_RENDER);
if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
continue;
@@ -1300,7 +1309,7 @@ static void eevee_lightbake_gather_probes(EEVEE_LightBake *lbake)
}
}
}
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
+ DEG_OBJECT_ITER_END;
SORT_PROBE(EEVEE_LightGrid,
lbake->grid_prb + 1,
@@ -1350,13 +1359,13 @@ static bool lightbake_do_sample(EEVEE_LightBake *lbake,
DRW_custom_pipeline(&draw_engine_eevee_type, depsgraph, render_callback, lbake);
lbake->done += 1;
*lbake->progress = lbake->done / (float)lbake->total;
- *lbake->do_update = 1;
+ *lbake->do_update = true;
eevee_lightbake_context_disable(lbake);
return true;
}
-void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float *progress)
+void EEVEE_lightbake_job(void *custom_data, bool *stop, bool *do_update, float *progress)
{
EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data;
Depsgraph *depsgraph = lbake->depsgraph;
@@ -1385,8 +1394,8 @@ void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float
/* Resource allocation can fail. Early exit in this case. */
if (lbake->lcache->flag & LIGHTCACHE_INVALID) {
- *lbake->stop = 1;
- *lbake->do_update = 1;
+ *lbake->stop = true;
+ *lbake->do_update = true;
lbake->lcache->flag &= ~LIGHTCACHE_BAKING;
eevee_lightbake_context_disable(lbake);
eevee_lightbake_delete_resources(lbake);
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.h b/source/blender/draw/engines/eevee/eevee_lightcache.h
index 4e94e1914a7..73961f1919d 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.h
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.h
@@ -42,7 +42,7 @@ void *EEVEE_lightbake_job_data_alloc(struct Main *bmain,
int frame);
void EEVEE_lightbake_job_data_free(void *custom_data);
void EEVEE_lightbake_update(void *custom_data);
-void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float *progress);
+void EEVEE_lightbake_job(void *custom_data, bool *stop, bool *do_update, float *progress);
/**
* This is to update the world irradiance and reflection contribution from
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index 94915180483..eb111610706 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -329,7 +329,6 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
DRW_shgroup_uniform_texture_ref(grp, "probeCubes", &lcache->cube_tx.tex);
DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_uniform_vec3(grp, "screen_vecs", DRW_viewport_screenvecs_get(), 2);
DRW_shgroup_uniform_float_copy(
grp, "sphere_size", scene_eval->eevee.gi_cubemap_draw_size * 0.5f);
/* TODO(fclem): get rid of those UBO. */
@@ -353,7 +352,6 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
DRW_shgroup_uniform_vec3(shgrp, "increment_x", egrid->increment_x, 1);
DRW_shgroup_uniform_vec3(shgrp, "increment_y", egrid->increment_y, 1);
DRW_shgroup_uniform_vec3(shgrp, "increment_z", egrid->increment_z, 1);
- DRW_shgroup_uniform_vec3(shgrp, "screen_vecs", DRW_viewport_screenvecs_get(), 2);
DRW_shgroup_uniform_texture_ref(shgrp, "irradianceGrid", &lcache->grid_tx.tex);
DRW_shgroup_uniform_float_copy(
shgrp, "sphere_size", scene_eval->eevee.gi_irradiance_draw_size * 0.5f);
@@ -405,7 +403,7 @@ static bool eevee_lightprobes_culling_test(Object *ob)
const float max[3] = {1.0f, 1.0f, 1.0f};
BKE_boundbox_init_from_minmax(&bbox, min, max);
- copy_m4_m4(tmp, ob->obmat);
+ copy_m4_m4(tmp, ob->object_to_world);
normalize_v3(tmp[2]);
mul_v3_fl(tmp[2], probe->distinf);
@@ -447,7 +445,7 @@ void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
/* Debug Display */
DRWCallBuffer *grp = vedata->stl->g_data->planar_display_shgrp;
if (grp && (probe->flag & LIGHTPROBE_FLAG_SHOW_DATA)) {
- DRW_buffer_add_entry(grp, &pinfo->num_planar, ob->obmat);
+ DRW_buffer_add_entry(grp, &pinfo->num_planar, ob->object_to_world);
}
pinfo->num_planar++;
@@ -490,30 +488,30 @@ void EEVEE_lightprobes_grid_data_from_object(Object *ob, EEVEE_LightGrid *egrid,
mul_v3_v3fl(half_cell_dim, cell_dim, 0.5f);
/* Matrix converting world space to cell ranges. */
- invert_m4_m4(egrid->mat, ob->obmat);
+ invert_m4_m4(egrid->mat, ob->object_to_world);
/* First cell. */
copy_v3_fl(egrid->corner, -1.0f);
add_v3_v3(egrid->corner, half_cell_dim);
- mul_m4_v3(ob->obmat, egrid->corner);
+ mul_m4_v3(ob->object_to_world, egrid->corner);
/* Opposite neighbor cell. */
copy_v3_fl3(egrid->increment_x, cell_dim[0], 0.0f, 0.0f);
add_v3_v3(egrid->increment_x, half_cell_dim);
add_v3_fl(egrid->increment_x, -1.0f);
- mul_m4_v3(ob->obmat, egrid->increment_x);
+ mul_m4_v3(ob->object_to_world, egrid->increment_x);
sub_v3_v3(egrid->increment_x, egrid->corner);
copy_v3_fl3(egrid->increment_y, 0.0f, cell_dim[1], 0.0f);
add_v3_v3(egrid->increment_y, half_cell_dim);
add_v3_fl(egrid->increment_y, -1.0f);
- mul_m4_v3(ob->obmat, egrid->increment_y);
+ mul_m4_v3(ob->object_to_world, egrid->increment_y);
sub_v3_v3(egrid->increment_y, egrid->corner);
copy_v3_fl3(egrid->increment_z, 0.0f, 0.0f, cell_dim[2]);
add_v3_v3(egrid->increment_z, half_cell_dim);
add_v3_fl(egrid->increment_z, -1.0f);
- mul_m4_v3(ob->obmat, egrid->increment_z);
+ mul_m4_v3(ob->object_to_world, egrid->increment_z);
sub_v3_v3(egrid->increment_z, egrid->corner);
/* Visibility bias */
@@ -529,7 +527,7 @@ void EEVEE_lightprobes_cube_data_from_object(Object *ob, EEVEE_LightProbe *eprob
LightProbe *probe = (LightProbe *)ob->data;
/* Update transforms */
- copy_v3_v3(eprobe->position, ob->obmat[3]);
+ copy_v3_v3(eprobe->position, ob->object_to_world[3]);
/* Attenuation */
eprobe->attenuation_type = probe->attenuation_type;
@@ -537,7 +535,7 @@ void EEVEE_lightprobes_cube_data_from_object(Object *ob, EEVEE_LightProbe *eprob
unit_m4(eprobe->attenuationmat);
scale_m4_fl(eprobe->attenuationmat, probe->distinf);
- mul_m4_m4m4(eprobe->attenuationmat, ob->obmat, eprobe->attenuationmat);
+ mul_m4_m4m4(eprobe->attenuationmat, ob->object_to_world, eprobe->attenuationmat);
invert_m4(eprobe->attenuationmat);
/* Parallax */
@@ -552,7 +550,7 @@ void EEVEE_lightprobes_cube_data_from_object(Object *ob, EEVEE_LightProbe *eprob
scale_m4_fl(eprobe->parallaxmat, probe->distinf);
}
- mul_m4_m4m4(eprobe->parallaxmat, ob->obmat, eprobe->parallaxmat);
+ mul_m4_m4m4(eprobe->parallaxmat, ob->object_to_world, eprobe->parallaxmat);
invert_m4(eprobe->parallaxmat);
}
@@ -568,8 +566,8 @@ void EEVEE_lightprobes_planar_data_from_object(Object *ob,
vis_test->cached = false;
/* Computing mtx : matrix that mirror position around object's XY plane. */
- normalize_m4_m4(normat, ob->obmat); /* object > world */
- invert_m4_m4(imat, normat); /* world > object */
+ normalize_m4_m4(normat, ob->object_to_world); /* object > world */
+ invert_m4_m4(imat, normat); /* world > object */
/* XY reflection plane */
imat[0][2] = -imat[0][2];
imat[1][2] = -imat[1][2];
@@ -578,38 +576,38 @@ void EEVEE_lightprobes_planar_data_from_object(Object *ob,
mul_m4_m4m4(eplanar->mtx, normat, imat); /* world > object > mirrored obj > world */
/* Compute clip plane equation / normal. */
- copy_v3_v3(eplanar->plane_equation, ob->obmat[2]);
+ copy_v3_v3(eplanar->plane_equation, ob->object_to_world[2]);
normalize_v3(eplanar->plane_equation); /* plane normal */
- eplanar->plane_equation[3] = -dot_v3v3(eplanar->plane_equation, ob->obmat[3]);
+ eplanar->plane_equation[3] = -dot_v3v3(eplanar->plane_equation, ob->object_to_world[3]);
eplanar->clipsta = probe->clipsta;
/* Compute XY clip planes. */
- normalize_v3_v3(eplanar->clip_vec_x, ob->obmat[0]);
- normalize_v3_v3(eplanar->clip_vec_y, ob->obmat[1]);
+ normalize_v3_v3(eplanar->clip_vec_x, ob->object_to_world[0]);
+ normalize_v3_v3(eplanar->clip_vec_y, ob->object_to_world[1]);
float vec[3] = {0.0f, 0.0f, 0.0f};
vec[0] = 1.0f;
vec[1] = 0.0f;
vec[2] = 0.0f;
- mul_m4_v3(ob->obmat, vec); /* Point on the edge */
+ mul_m4_v3(ob->object_to_world, vec); /* Point on the edge */
eplanar->clip_edge_x_pos = dot_v3v3(eplanar->clip_vec_x, vec);
vec[0] = 0.0f;
vec[1] = 1.0f;
vec[2] = 0.0f;
- mul_m4_v3(ob->obmat, vec); /* Point on the edge */
+ mul_m4_v3(ob->object_to_world, vec); /* Point on the edge */
eplanar->clip_edge_y_pos = dot_v3v3(eplanar->clip_vec_y, vec);
vec[0] = -1.0f;
vec[1] = 0.0f;
vec[2] = 0.0f;
- mul_m4_v3(ob->obmat, vec); /* Point on the edge */
+ mul_m4_v3(ob->object_to_world, vec); /* Point on the edge */
eplanar->clip_edge_x_neg = dot_v3v3(eplanar->clip_vec_x, vec);
vec[0] = 0.0f;
vec[1] = -1.0f;
vec[2] = 0.0f;
- mul_m4_v3(ob->obmat, vec); /* Point on the edge */
+ mul_m4_v3(ob->object_to_world, vec); /* Point on the edge */
eplanar->clip_edge_y_neg = dot_v3v3(eplanar->clip_vec_y, vec);
/* Facing factors */
@@ -796,6 +794,7 @@ static void render_reflections(void (*callback)(int face, EEVEE_BakeRenderData *
int ref_count)
{
EEVEE_StorageList *stl = user_data->vedata->stl;
+ EEVEE_ViewLayerData *sldata = user_data->sldata;
DRWView *main_view = stl->effects->taa_view;
DRWView **views = stl->g_data->planar_views;
/* Prepare views at the same time for faster culling. */
@@ -804,6 +803,8 @@ static void render_reflections(void (*callback)(int face, EEVEE_BakeRenderData *
}
for (int i = 0; i < ref_count; i++) {
+ copy_v4_v4(sldata->common_data.planar_clip_plane, planar_data[i].plane_equation);
+ sldata->common_data.planar_clip_plane[3] += planar_data[i].clipsta;
DRW_view_set_active(views[i]);
callback(i, user_data);
}
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 312305a31f7..f8250f9520d 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -132,7 +132,7 @@ static void eevee_light_setup(Object *ob, EEVEE_Light *evli)
const float light_threshold = draw_ctx->scene->eevee.light_threshold;
/* Position */
- copy_v3_v3(evli->position, ob->obmat[3]);
+ copy_v3_v3(evli->position, ob->object_to_world[3]);
/* Color */
copy_v3_v3(evli->color, &la->r);
@@ -153,7 +153,7 @@ static void eevee_light_setup(Object *ob, EEVEE_Light *evli)
evli->invsqrdist_volume = 1.0f / max_ff(1e-4f, square_f(att_radius_volume));
/* Vectors */
- normalize_m4_m4_ex(mat, ob->obmat, scale);
+ normalize_m4_m4_ex(mat, ob->object_to_world, scale);
copy_v3_v3(evli->forwardvec, mat[2]);
normalize_v3(evli->forwardvec);
negate_v3(evli->forwardvec);
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 94f29d64628..b134d7f6dc6 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -231,6 +231,13 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
eevee_init_noise_texture();
}
+ if (draw_ctx->rv3d) {
+ copy_v4_v4(sldata->common_data.camera_uv_scale, draw_ctx->rv3d->viewcamtexcofac);
+ }
+ else {
+ copy_v4_fl4(sldata->common_data.camera_uv_scale, 1.0f, 1.0f, 0.0f, 0.0f);
+ }
+
if (!DRW_state_is_image_render() && ((stl->effects->enabled_effects & EFFECT_TAA) == 0)) {
sldata->common_data.alpha_hash_offset = 0.0f;
sldata->common_data.alpha_hash_scale = 1.0f;
@@ -752,7 +759,8 @@ BLI_INLINE Material *eevee_object_material_get(Object *ob, int slot, bool holdou
BLI_INLINE EeveeMaterialCache eevee_material_cache_get(
EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob, int slot, bool is_hair)
{
- const bool holdout = (ob->base_flag & BASE_HOLDOUT) != 0;
+ const bool holdout = ((ob->base_flag & BASE_HOLDOUT) != 0) ||
+ ((ob->visibility_flag & OB_HOLDOUT) != 0);
EeveeMaterialCache matcache;
Material *ma = eevee_object_material_get(ob, slot, holdout);
switch (ma->blend_method) {
@@ -802,9 +810,13 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
- bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) &&
+ bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->rv3d) &&
!DRW_state_is_image_render();
+ if (ob->sculpt && ob->sculpt->pbvh) {
+ BKE_pbvh_is_drawing_set(ob->sculpt->pbvh, use_sculpt_pbvh);
+ }
+
/* First get materials for this mesh. */
if (ELEM(ob->type, OB_MESH, OB_SURF)) {
const int materials_len = DRW_cache_object_material_count_get(ob);
@@ -824,14 +836,17 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
if (use_sculpt_pbvh) {
struct DRWShadingGroup **shgrps_array = BLI_array_alloca(shgrps_array, materials_len);
+ struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
+ MATCACHE_AS_ARRAY(matcache, shading_gpumat, materials_len, gpumat_array);
+
MATCACHE_AS_ARRAY(matcache, shading_grp, materials_len, shgrps_array);
- DRW_shgroup_call_sculpt_with_materials(shgrps_array, materials_len, ob);
+ DRW_shgroup_call_sculpt_with_materials(shgrps_array, gpumat_array, materials_len, ob);
MATCACHE_AS_ARRAY(matcache, depth_grp, materials_len, shgrps_array);
- DRW_shgroup_call_sculpt_with_materials(shgrps_array, materials_len, ob);
+ DRW_shgroup_call_sculpt_with_materials(shgrps_array, gpumat_array, materials_len, ob);
MATCACHE_AS_ARRAY(matcache, shadow_grp, materials_len, shgrps_array);
- DRW_shgroup_call_sculpt_with_materials(shgrps_array, materials_len, ob);
+ DRW_shgroup_call_sculpt_with_materials(shgrps_array, gpumat_array, materials_len, ob);
}
else {
struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
@@ -909,17 +924,14 @@ void EEVEE_particle_hair_cache_populate(EEVEE_Data *vedata,
if (matcache.depth_grp) {
*matcache.depth_grp_p = DRW_shgroup_hair_create_sub(
ob, psys, md, matcache.depth_grp, NULL);
- DRW_shgroup_add_material_resources(*matcache.depth_grp_p, matcache.shading_gpumat);
}
if (matcache.shading_grp) {
*matcache.shading_grp_p = DRW_shgroup_hair_create_sub(
ob, psys, md, matcache.shading_grp, matcache.shading_gpumat);
- DRW_shgroup_add_material_resources(*matcache.shading_grp_p, matcache.shading_gpumat);
}
if (matcache.shadow_grp) {
*matcache.shadow_grp_p = DRW_shgroup_hair_create_sub(
ob, psys, md, matcache.shadow_grp, NULL);
- DRW_shgroup_add_material_resources(*matcache.shadow_grp_p, matcache.shading_gpumat);
*cast_shadow = true;
}
@@ -939,16 +951,13 @@ void EEVEE_object_curves_cache_populate(EEVEE_Data *vedata,
if (matcache.depth_grp) {
*matcache.depth_grp_p = DRW_shgroup_curves_create_sub(ob, matcache.depth_grp, NULL);
- DRW_shgroup_add_material_resources(*matcache.depth_grp_p, matcache.shading_gpumat);
}
if (matcache.shading_grp) {
*matcache.shading_grp_p = DRW_shgroup_curves_create_sub(
ob, matcache.shading_grp, matcache.shading_gpumat);
- DRW_shgroup_add_material_resources(*matcache.shading_grp_p, matcache.shading_gpumat);
}
if (matcache.shadow_grp) {
*matcache.shadow_grp_p = DRW_shgroup_curves_create_sub(ob, matcache.shadow_grp, NULL);
- DRW_shgroup_add_material_resources(*matcache.shadow_grp_p, matcache.shading_gpumat);
*cast_shadow = true;
}
diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c
index a3ca19c88e1..9f7fb1c154c 100644
--- a/source/blender/draw/engines/eevee/eevee_motion_blur.c
+++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c
@@ -292,7 +292,7 @@ void EEVEE_motion_blur_curves_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata)
int mb_step = effects->motion_blur_step;
/* Store transform. */
- copy_m4_m4(mb_data->obmat[mb_step], ob->obmat);
+ copy_m4_m4(mb_data->obmat[mb_step], ob->object_to_world);
EEVEE_HairMotionData *mb_curves = EEVEE_motion_blur_curves_data_get(mb_data);
@@ -362,7 +362,7 @@ void EEVEE_motion_blur_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata),
if (mb_data) {
int mb_step = effects->motion_blur_step;
/* Store transform. */
- copy_m4_m4(mb_data->obmat[mb_step], ob->obmat);
+ copy_m4_m4(mb_data->obmat[mb_step], ob->object_to_world);
EEVEE_GeometryMotionData *mb_geom = EEVEE_motion_blur_geometry_data_get(mb_data);
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 573c29b78a1..e9b27354965 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -815,7 +815,7 @@ typedef struct EEVEE_EffectsInfo {
struct GPUTexture *dof_reduce_input_color_tx;
/* Other */
float prev_persmat[4][4];
- /* Size used by all fullscreen buffers using mipmaps. */
+ /* Size used by all full-screen buffers using mipmaps. */
int hiz_size[2];
/* Lookdev */
int sphere_size;
@@ -837,7 +837,7 @@ typedef struct EEVEE_EffectsInfo {
struct GPUTexture *bloom_upsample[MAX_BLOOM_STEP - 1];
struct GPUTexture *unf_source_buffer; /* pointer copy */
struct GPUTexture *unf_base_buffer; /* pointer copy */
- /* Not alloced, just a copy of a *GPUtexture in EEVEE_TextureList. */
+ /* Not allocated, just a copy of a *GPUtexture in EEVEE_TextureList. */
struct GPUTexture *source_buffer; /* latest updated texture */
struct GPUFrameBuffer *target_buffer; /* next target to render to */
struct GPUTexture *final_tx; /* Final color to transform to display color space. */
@@ -895,14 +895,12 @@ typedef struct EEVEE_CommonUniformBuffer {
float prb_irradiance_smooth; /* float */
float prb_lod_cube_max; /* float */
/* Misc */
- int ray_type; /* int */
- float ray_depth; /* float */
- float alpha_hash_offset; /* float */
- float alpha_hash_scale; /* float */
- float pad7; /* float */
- float pad8; /* float */
- float pad9; /* float */
- float pad10; /* float */
+ int ray_type; /* int */
+ float ray_depth; /* float */
+ float alpha_hash_offset; /* float */
+ float alpha_hash_scale; /* float */
+ float camera_uv_scale[2], camera_uv_bias[2]; /* vec4 */
+ float planar_clip_plane[4]; /* vec4 */
} EEVEE_CommonUniformBuffer;
BLI_STATIC_ASSERT_ALIGN(EEVEE_CommonUniformBuffer, 16)
@@ -1261,7 +1259,6 @@ struct GPUShader *EEVEE_shaders_volumes_scatter_sh_get(void);
struct GPUShader *EEVEE_shaders_volumes_scatter_with_lights_sh_get(void);
struct GPUShader *EEVEE_shaders_volumes_integration_sh_get(void);
struct GPUShader *EEVEE_shaders_volumes_resolve_sh_get(bool accum);
-struct GPUShader *EEVEE_shaders_volumes_resolve_comp_sh_get(bool float_target);
struct GPUShader *EEVEE_shaders_volumes_accum_sh_get(void);
struct GPUShader *EEVEE_shaders_ggx_lut_sh_get(void);
struct GPUShader *EEVEE_shaders_ggx_refraction_lut_sh_get(void);
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index c3b909f5fb9..1d18056e175 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -157,8 +157,6 @@ void EEVEE_render_view_sync(EEVEE_Data *vedata, RenderEngine *engine, struct Dep
DRW_view_reset();
DRW_view_default_set(view);
DRW_view_set_active(view);
-
- DRW_view_camtexco_set(view, g_data->camtexcofac);
}
void EEVEE_render_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c
index a7290b3894e..04d1168a30d 100644
--- a/source/blender/draw/engines/eevee/eevee_shaders.c
+++ b/source/blender/draw/engines/eevee/eevee_shaders.c
@@ -133,7 +133,6 @@ static struct {
struct GPUShader *scatter_with_lights_sh;
struct GPUShader *volumetric_integration_sh;
struct GPUShader *volumetric_resolve_sh[2];
- struct GPUShader *volumetric_resolve_comp_sh[2];
struct GPUShader *volumetric_accum_sh;
/* Shader strings */
@@ -262,7 +261,6 @@ extern char datatoc_volumetric_frag_glsl[];
extern char datatoc_volumetric_geom_glsl[];
extern char datatoc_volumetric_integration_frag_glsl[];
extern char datatoc_volumetric_lib_glsl[];
-extern char datatoc_volumetric_resolve_comp_glsl[];
extern char datatoc_volumetric_resolve_frag_glsl[];
extern char datatoc_volumetric_scatter_frag_glsl[];
extern char datatoc_volumetric_vert_glsl[];
@@ -905,20 +903,6 @@ struct GPUShader *EEVEE_shaders_volumes_resolve_sh_get(bool accum)
return e_data.volumetric_resolve_sh[index];
}
-struct GPUShader *EEVEE_shaders_volumes_resolve_comp_sh_get(bool float_target)
-{
- const int index = (float_target ? 1 : 0);
- if (e_data.volumetric_resolve_comp_sh[index] == NULL) {
- e_data.volumetric_resolve_comp_sh[index] = DRW_shader_create_compute_with_shaderlib(
- datatoc_volumetric_resolve_comp_glsl,
- e_data.lib,
- float_target ? "#define TARGET_IMG_FLOAT\n" SHADER_DEFINES : SHADER_DEFINES,
- __func__);
- }
-
- return e_data.volumetric_resolve_comp_sh[index];
-}
-
struct GPUShader *EEVEE_shaders_volumes_accum_sh_get()
{
if (e_data.volumetric_accum_sh == NULL) {
diff --git a/source/blender/draw/engines/eevee/eevee_shadows.c b/source/blender/draw/engines/eevee/eevee_shadows.c
index 9e571b1d15b..1cf3c7c6da1 100644
--- a/source/blender/draw/engines/eevee/eevee_shadows.c
+++ b/source/blender/draw/engines/eevee/eevee_shadows.c
@@ -153,7 +153,7 @@ void EEVEE_shadows_caster_register(EEVEE_ViewLayerData *sldata, Object *ob)
for (int i = 0; i < 8; i++) {
float vec[3];
copy_v3_v3(vec, bb->vec[i]);
- mul_m4_v3(ob->obmat, vec);
+ mul_m4_v3(ob->object_to_world, vec);
minmax_v3v3_v3(min, max, vec);
}
diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c
index b2e5a0abe94..872696a8b7c 100644
--- a/source/blender/draw/engines/eevee/eevee_volumes.c
+++ b/source/blender/draw/engines/eevee/eevee_volumes.c
@@ -158,7 +158,7 @@ void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
if (DRW_view_is_persp_get(NULL)) {
float sample_distribution = scene_eval->eevee.volumetric_sample_distribution;
- sample_distribution = 4.0f * (max_ff(1.0f - sample_distribution, 1e-2f));
+ sample_distribution = 4.0f * max_ff(1.0f - sample_distribution, 1e-2f);
const float clip_start = DRW_view_near_distance_get(NULL);
/* Negate */
@@ -299,7 +299,7 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata,
}
float size[3];
- mat4_to_size(size, ob->obmat);
+ mat4_to_size(size, ob->object_to_world);
/* Check if any of the axes have 0 length. (see T69070) */
const float epsilon = 1e-8f;
if ((size[0] < epsilon) || (size[1] < epsilon) || (size[2] < epsilon)) {
@@ -396,37 +396,18 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
grp, NULL, USE_VOLUME_OPTI ? 1 : common_data->vol_tex_size[2]);
DRW_PASS_CREATE(psl->volumetric_resolve_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM);
- if (GPU_compute_shader_support() && GPU_shader_image_load_store_support()) {
- const bool use_float_target = DRW_state_is_image_render();
- grp = DRW_shgroup_create(EEVEE_shaders_volumes_resolve_comp_sh_get(use_float_target),
- psl->volumetric_resolve_ps);
- DRW_shgroup_uniform_texture_ref(grp, "inScattering", &txl->volume_scatter);
- DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
- DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
- DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
- DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
- DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
- DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
- DRW_shgroup_uniform_image_ref(grp, "target_img", &txl->color);
-
- const float *size = DRW_viewport_size_get();
- DRW_shgroup_call_compute(grp, size[0], size[1], 1);
- }
- else {
- grp = DRW_shgroup_create(EEVEE_shaders_volumes_resolve_sh_get(false),
- psl->volumetric_resolve_ps);
- DRW_shgroup_uniform_texture_ref(grp, "inScattering", &txl->volume_scatter);
- DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
- DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
- DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
- DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
- DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
- DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
+ grp = DRW_shgroup_create(EEVEE_shaders_volumes_resolve_sh_get(false),
+ psl->volumetric_resolve_ps);
+ DRW_shgroup_uniform_texture_ref(grp, "inScattering", &txl->volume_scatter);
+ DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
+ DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
+ DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
+ DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
+ DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
+ DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
- DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
- }
+ DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
}
}
@@ -565,16 +546,11 @@ void EEVEE_volumes_resolve(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda
}
/* Apply for opaque geometry. */
- if (GPU_compute_shader_support() && GPU_shader_image_load_store_support()) {
- DRW_draw_pass(psl->volumetric_resolve_ps);
- }
- else {
- GPU_framebuffer_bind(fbl->main_color_fb);
- DRW_draw_pass(psl->volumetric_resolve_ps);
+ GPU_framebuffer_bind(fbl->main_color_fb);
+ DRW_draw_pass(psl->volumetric_resolve_ps);
- /* Restore. */
- GPU_framebuffer_bind(fbl->main_fb);
- }
+ /* Restore. */
+ GPU_framebuffer_bind(fbl->main_fb);
}
}
diff --git a/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl b/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl
index c935eca6a39..c06f164c025 100644
--- a/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl
@@ -1,4 +1,6 @@
+#define COMMON_UNIFORMS_LIB
+
layout(std140) uniform common_block
{
mat4 pastViewProjectionMatrix;
@@ -42,10 +44,9 @@ layout(std140) uniform common_block
float rayDepth;
float alphaHashOffset;
float alphaHashScale;
- float pad6;
- float pad7;
- float pad8;
- float pad9;
+ /* Misc */
+ vec4 cameraUvScaleBias;
+ vec4 planarClipPlane;
};
/* rayType (keep in sync with ray_type) */
diff --git a/source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl b/source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl
index 90272400915..5af317b7398 100644
--- a/source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl
@@ -96,7 +96,7 @@ vec4 cubemap_seamless(sampler2DArray tex, vec4 cubevec, float lod)
/* Mix all colors to get the corner color. */
vec4 col3 = (col + col1 + col2) / 3.0;
- vec2 mix_fac = uv_border * 0.5;
+ vec2 mix_fac = saturate(uv_border * 0.5);
return mix(mix(col, col2, mix_fac.x), mix(col1, col3, mix_fac.x), mix_fac.y);
}
else if (any(border)) {
@@ -108,7 +108,7 @@ vec4 cubemap_seamless(sampler2DArray tex, vec4 cubevec, float lod)
uv = cubemap_face_coord(cubevec.xyz, face);
coord = vec3(uv, cubevec.w * 6.0 + face);
- float mix_fac = max(uv_border.x, uv_border.y) * 0.5;
+ float mix_fac = saturate(max(uv_border.x, uv_border.y) * 0.5);
return mix(col, textureLod(tex, coord, lod), mix_fac);
}
else {
diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_vert.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_vert.glsl
index 51a351babd3..5f04cdcebfa 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_vert.glsl
@@ -95,7 +95,11 @@ void main()
weights = dof_layer_weight(cocs) * dof_sample_weight(cocs);
/* Filter NaNs. */
- weights = select(weights, vec4(0.0), equal(cocs, vec4(0.0)));
+ for (int i = 0; i < 4; i++) {
+ if (isnan(weights[i]) || isinf(weights[i])) {
+ weights[i] = 0.0;
+ }
+ }
color1 = colors[0] * weights[0];
color2 = colors[1] * weights[1];
diff --git a/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl b/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl
index ed600a3be86..a6781a0debe 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl
@@ -47,7 +47,7 @@ HitData decode_hit_data(vec4 hit_data, float hit_depth)
return data;
}
-/* Blue noise categorised into 4 sets of samples.
+/* Blue noise categorized into 4 sets of samples.
* See "Stochastic all the things" presentation slide 32-37. */
const int resolve_samples_count = 9;
const vec2 resolve_sample_offsets[36] = vec2[36](
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl
index c9af2753baa..d1da9873228 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl
@@ -15,7 +15,6 @@ layout(std140) uniform probe_block
};
uniform float sphere_size;
-uniform vec3 screen_vecs[2];
flat out int pid;
out vec2 quadCoord;
@@ -36,9 +35,10 @@ void main()
quadCoord = pos[vert_id];
vec3 ws_location = probes_data[pid].position_type.xyz;
- vec3 screen_pos = screen_vecs[0] * quadCoord.x + screen_vecs[1] * quadCoord.y;
+ vec3 screen_pos = ViewMatrixInverse[0].xyz * quadCoord.x +
+ ViewMatrixInverse[1].xyz * quadCoord.y;
ws_location += screen_pos * sphere_size;
- gl_Position = ViewProjectionMatrix * vec4(ws_location, 1.0);
+ gl_Position = ProjectionMatrix * (ViewMatrix * vec4(ws_location, 1.0));
gl_Position.z += 0.0001; /* Small bias to let the icon draw without zfighting */
}
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl
index 6fefe1319bd..b22d63de29e 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl
@@ -8,7 +8,6 @@ uniform vec3 corner;
uniform vec3 increment_x;
uniform vec3 increment_y;
uniform vec3 increment_z;
-uniform vec3 screen_vecs[2];
flat out int cellOffset;
out vec2 quadCoord;
@@ -39,9 +38,10 @@ void main()
increment_z * ls_cell_location.z);
quadCoord = pos[vert_id];
- vec3 screen_pos = screen_vecs[0] * quadCoord.x + screen_vecs[1] * quadCoord.y;
+ vec3 screen_pos = ViewMatrixInverse[0].xyz * quadCoord.x +
+ ViewMatrixInverse[1].xyz * quadCoord.y;
ws_cell_location += screen_pos * sphere_size;
- gl_Position = ViewProjectionMatrix * vec4(ws_cell_location, 1.0);
+ gl_Position = ProjectionMatrix * (ViewMatrix * vec4(ws_cell_location, 1.0));
gl_Position.z += 0.0001; /* Small bias to let the icon draw without zfighting */
}
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
index e1035af37be..862d666ab5f 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
@@ -203,10 +203,10 @@ vec3 probe_evaluate_planar(int id, PlanarData pd, vec3 P, vec3 N, vec3 V, float
vec3 ref_pos = point_on_plane + proj_ref;
/* Reproject to find texture coords. */
- vec4 refco = ViewProjectionMatrix * vec4(ref_pos, 1.0);
+ vec4 refco = ProjectionMatrix * (ViewMatrix * vec4(ref_pos, 1.0));
refco.xy /= refco.w;
- /* TODO: If we support non-ssr planar reflection, we should blur them with gaussian
+ /* TODO: If we support non-SSR planar reflection, we should blur them with gaussian
* and chose the right mip depending on the cone footprint after projection */
/* NOTE: X is inverted here to compensate inverted drawing. */
vec3 radiance = textureLod(probePlanars, vec3(refco.xy * vec2(-0.5, 0.5) + 0.5, id), 0.0).rgb;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl
index 0a53abcb04a..fff3209bb8a 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl
@@ -10,7 +10,7 @@ out vec4 FragColor;
void main()
{
- vec4 refco = ViewProjectionMatrix * vec4(worldPosition, 1.0);
+ vec4 refco = ProjectionMatrix * (ViewMatrix * vec4(worldPosition, 1.0));
refco.xy /= refco.w;
FragColor = vec4(
textureLod(probePlanars, vec3(refco.xy * vec2(-0.5, 0.5) + 0.5, float(probeIdx)), 0.0).rgb,
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl
index 6759c060259..9c79fd4c939 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl
@@ -12,6 +12,6 @@ flat out int probeIdx;
void main()
{
worldPosition = (probe_mat * vec4(-pos.x, pos.y, 0.0, 1.0)).xyz;
- gl_Position = ViewProjectionMatrix * vec4(worldPosition, 1.0);
+ gl_Position = ProjectionMatrix * (ViewMatrix * vec4(worldPosition, 1.0));
probeIdx = probe_id;
}
diff --git a/source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl b/source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl
index ef96bcbaedb..9dab04006a8 100644
--- a/source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl
@@ -52,8 +52,8 @@ void main()
/* Use jittered projmatrix to be able to match exact sample depth (depth equal test).
* Note that currModelMatrix needs to also be equal to ModelMatrix for the samples to match. */
#ifndef HAIR
- gl_Position = ViewProjectionMatrix * vec4(currWorldPos, 1.0);
+ gl_Position = ProjectionMatrix * (ViewMatrix * vec4(currWorldPos, 1.0));
#else
- gl_Position = ViewProjectionMatrix * vec4(wpos, 1.0);
+ gl_Position = ProjectionMatrix * (ViewMatrix * vec4(wpos, 1.0));
#endif
}
diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
index 73c4b521b05..8bd60573078 100644
--- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
@@ -51,7 +51,8 @@ void raytrace_screenspace_ray_finalize(inout ScreenSpaceRay ray)
}
float ray_len_sqr = len_squared(ray.direction.xyz);
/* Make ray.direction cover one pixel. */
- bool is_more_vertical = abs(ray.direction.x) < abs(ray.direction.y);
+ bool is_more_vertical = abs(ray.direction.x / ssrPixelSize.x) <
+ abs(ray.direction.y / ssrPixelSize.y);
ray.direction /= (is_more_vertical) ? abs(ray.direction.y) : abs(ray.direction.x);
ray.direction *= (is_more_vertical) ? ssrPixelSize.y : ssrPixelSize.x;
/* Clip to segment's end. */
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
index 062a40f35c2..ccf6d6e2042 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
@@ -30,7 +30,7 @@ void main()
vec3 world_pos = pos;
#elif defined(POINTCLOUD_SHADER)
pointcloud_get_pos_and_radius(pointPosition, pointRadius);
- pointID = gl_VertexID;
+ pointID = pointcloud_get_point_id();
#else
vec3 world_pos = point_object_to_world(pos);
#endif
diff --git a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
index a563291bb90..3991f32b407 100644
--- a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
@@ -79,7 +79,7 @@ vec4 screen_space_refraction(vec3 vP, vec3 N, vec3 V, float ior, float roughness
/* Texel footprint */
vec2 texture_size = vec2(textureSize(refractColorBuffer, 0).xy) / hizUvScale.xy;
- float mip = clamp(log2(cone_footprint * max(texture_size.x, texture_size.y)), 0.0, 9.0);
+ float mip = log2(cone_footprint * max(texture_size.x, texture_size.y));
vec3 spec = textureLod(refractColorBuffer, hit_uvs * hizUvScale.xy, mip).xyz;
float mask = screen_border_mask(hit_uvs);
diff --git a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl
index 69762027643..13a6498938b 100644
--- a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl
@@ -1,6 +1,7 @@
/** This describe the entire interface of the shader. */
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#define SURFACE_INTERFACE \
vec3 worldPosition; \
@@ -176,13 +177,13 @@ vec3 coordinate_screen(vec3 P)
/* Unsupported. It would make the probe camera-dependent. */
window.xy = vec2(0.5);
-#elif defined(WORLD_BACKGROUND)
+#elif defined(WORLD_BACKGROUND) && defined(COMMON_UNIFORMS_LIB)
window.xy = project_point(ProjectionMatrix, viewPosition).xy * 0.5 + 0.5;
- window.xy = window.xy * CameraTexCoFactors.xy + CameraTexCoFactors.zw;
+ window.xy = window.xy * cameraUvScaleBias.xy + cameraUvScaleBias.zw;
-#else /* MESH */
- window.xy = project_point(ViewProjectionMatrix, P).xy * 0.5 + 0.5;
- window.xy = window.xy * CameraTexCoFactors.xy + CameraTexCoFactors.zw;
+#elif defined(COMMON_UNIFORMS_LIB) /* MESH */
+ window.xy = project_point(ProjectionMatrix, transform_point(ViewMatrix, P)).xy * 0.5 + 0.5;
+ window.xy = window.xy * cameraUvScaleBias.xy + cameraUvScaleBias.zw;
#endif
return window;
}
diff --git a/source/blender/draw/engines/eevee/shaders/surface_vert.glsl b/source/blender/draw/engines/eevee/shaders/surface_vert.glsl
index 54aad7891dc..7a22b2c53d7 100644
--- a/source/blender/draw/engines/eevee/shaders/surface_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/surface_vert.glsl
@@ -37,7 +37,7 @@ void main()
vec3 world_pos = pos;
#elif defined(POINTCLOUD_SHADER)
pointcloud_get_pos_and_radius(pointPosition, pointRadius);
- pointID = gl_VertexID;
+ pointID = pointcloud_get_point_id();
#else
vec3 world_pos = point_object_to_world(pos);
#endif
@@ -45,7 +45,7 @@ void main()
gl_Position = point_world_to_ndc(world_pos);
/* Used for planar reflections */
- gl_ClipDistance[0] = dot(vec4(world_pos, 1.0), clipPlanes[0]);
+ gl_ClipDistance[0] = dot(vec4(world_pos, 1.0), planarClipPlane);
#ifdef MESH_SHADER
worldPosition = world_pos;
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
index 9ed21fc0bf5..90c36801dd5 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
@@ -52,8 +52,8 @@ vec3 coordinate_camera(vec3 P)
vec3 coordinate_screen(vec3 P)
{
vec3 window = vec3(0.0);
- window.xy = project_point(ViewProjectionMatrix, P).xy * 0.5 + 0.5;
- window.xy = window.xy * CameraTexCoFactors.xy + CameraTexCoFactors.zw;
+ window.xy = project_point(ProjectionMatrix, transform_point(ViewMatrix, P)).xy * 0.5 + 0.5;
+ window.xy = window.xy * cameraUvScaleBias.xy + cameraUvScaleBias.zw;
return window;
}
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl
index 777e48fde34..07b817d1713 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl
@@ -117,7 +117,7 @@ vec3 light_volume_light_vector(LightData ld, vec3 P)
vec3 participating_media_extinction(vec3 wpos, sampler3D volume_extinction)
{
/* Waiting for proper volume shadowmaps and out of frustum shadow map. */
- vec3 ndc = project_point(ViewProjectionMatrix, wpos);
+ vec3 ndc = project_point(ProjectionMatrix, transform_point(ViewMatrix, wpos));
vec3 volume_co = ndc_to_volume(ndc * 0.5 + 0.5);
/* Let the texture be clamped to edge. This reduce visual glitches. */
@@ -147,12 +147,15 @@ vec3 light_volume_shadow(LightData ld, vec3 ray_wpos, vec4 l_vector, sampler3D v
if (ld.l_type == SUN) {
/* For sun light we scan the whole frustum. So we need to get the correct endpoints. */
- vec3 ndcP = project_point(ViewProjectionMatrix, ray_wpos);
- vec3 ndcL = project_point(ViewProjectionMatrix, ray_wpos + l_vector.xyz) - ndcP;
+ vec3 ndcP = project_point(ProjectionMatrix, transform_point(ViewMatrix, ray_wpos));
+ vec3 ndcL = project_point(ProjectionMatrix,
+ transform_point(ViewMatrix, ray_wpos + l_vector.xyz)) -
+ ndcP;
vec3 frustum_isect = ndcP + ndcL * line_unit_box_intersect_dist_safe(ndcP, ndcL);
- L = project_point(ViewProjectionMatrixInverse, frustum_isect) - ray_wpos;
+ vec4 L_hom = ViewMatrixInverse * (ProjectionMatrixInverse * vec4(frustum_isect, 1.0));
+ L = (L_hom.xyz / L_hom.w) - ray_wpos;
L /= volShadowSteps;
dd = length(L);
}
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_resolve_comp.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_resolve_comp.glsl
deleted file mode 100644
index 2b0139ff923..00000000000
--- a/source/blender/draw/engines/eevee/shaders/volumetric_resolve_comp.glsl
+++ /dev/null
@@ -1,38 +0,0 @@
-
-#pragma BLENDER_REQUIRE(volumetric_lib.glsl)
-
-/* Based on Frosbite Unified Volumetric.
- * https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
-
-/* Step 4 : Apply final integration on top of the scene color. */
-
-uniform sampler2D inSceneDepth;
-
-layout(local_size_x = 1, local_size_y = 1) in;
-
-#ifdef TARGET_IMG_FLOAT
-layout(binding = 0, rgba32f) uniform image2D target_img;
-#else
-layout(binding = 0, rgba16f) uniform image2D target_img;
-#endif
-
-void main()
-{
- ivec2 co = ivec2(gl_GlobalInvocationID.xy);
- vec2 uvs = co / vec2(textureSize(inSceneDepth, 0));
- float scene_depth = texture(inSceneDepth, uvs).r;
-
- vec3 transmittance, scattering;
- volumetric_resolve(uvs, scene_depth, transmittance, scattering);
-
- /* Approximate volume alpha by using a monochromatic transmittance
- * and adding it to the scene alpha. */
- float alpha = dot(transmittance, vec3(1.0 / 3.0));
-
- vec4 color0 = vec4(scattering, 1.0 - alpha);
- vec4 color1 = vec4(transmittance, alpha);
-
- vec4 color_in = imageLoad(target_img, co);
- vec4 color_out = color0 + color1 * color_in;
- imageStore(target_img, co, color_out);
-}
diff --git a/source/blender/draw/engines/eevee/shaders/world_vert.glsl b/source/blender/draw/engines/eevee/shaders/world_vert.glsl
index 29892a7ffb4..837dca4ad08 100644
--- a/source/blender/draw/engines/eevee/shaders/world_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/world_vert.glsl
@@ -17,7 +17,7 @@ void main()
gl_Position = vec4(pos, 1.0, 1.0);
viewPosition = project_point(ProjectionMatrixInverse, vec3(pos, 0.0));
- worldPosition = project_point(ViewProjectionMatrixInverse, vec3(pos, 0.0));
+ worldPosition = transform_point(ViewMatrixInverse, viewPosition);
/* Not usable. */
viewNormal = vec3(0.0);
worldNormal = vec3(0.0);
diff --git a/source/blender/draw/engines/eevee_next/eevee_camera.cc b/source/blender/draw/engines/eevee_next/eevee_camera.cc
index b9040f0f3ab..ad22219f0ae 100644
--- a/source/blender/draw/engines/eevee_next/eevee_camera.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_camera.cc
@@ -85,7 +85,9 @@ void Camera::sync()
DRW_view_winmat_get(inst_.drw_view, data.wininv.ptr(), true);
DRW_view_persmat_get(inst_.drw_view, data.persmat.ptr(), false);
DRW_view_persmat_get(inst_.drw_view, data.persinv.ptr(), true);
- DRW_view_camtexco_get(inst_.drw_view, data.uv_scale);
+ /* TODO(fclem): Derive from rv3d instead. */
+ data.uv_scale = float2(1.0f);
+ data.uv_bias = float2(0.0f);
}
else if (inst_.render) {
/* TODO(@fclem): Over-scan. */
@@ -106,6 +108,8 @@ void Camera::sync()
data.wininv = data.winmat.inverted();
data.persmat = data.winmat * data.viewmat;
data.persinv = data.persmat.inverted();
+ data.uv_scale = float2(1.0f);
+ data.uv_bias = float2(0.0f);
}
if (camera_eval) {
diff --git a/source/blender/draw/engines/eevee_next/eevee_camera.hh b/source/blender/draw/engines/eevee_next/eevee_camera.hh
index 49f9b14e11b..c1d65dbf31e 100644
--- a/source/blender/draw/engines/eevee_next/eevee_camera.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_camera.hh
@@ -13,7 +13,7 @@ namespace blender::eevee {
class Instance;
-static const float cubeface_mat[6][4][4] = {
+inline constexpr float cubeface_mat[6][4][4] = {
/* Pos X */
{{0.0f, 0.0f, -1.0f, 0.0f},
{0.0f, -1.0f, 0.0f, 0.0f},
@@ -99,7 +99,7 @@ class Camera {
BLI_assert(data_.initialized);
return data_;
}
- const GPUUniformBuf *ubo_get() const
+ GPUUniformBuf *ubo_get() const
{
return data_;
}
diff --git a/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc
index 340a587b1c1..db888df1973 100644
--- a/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. */
#include "BKE_cryptomatte.hh"
#include "GPU_material.h"
@@ -127,4 +129,4 @@ void Cryptomatte::store_metadata(RenderResult *render_result)
}
}
-} // namespace blender::eevee \ No newline at end of file
+} // namespace blender::eevee
diff --git a/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh
index 37f5edf4c6d..86ab3d97b4b 100644
--- a/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
- * Copyright 2021 Blender Foundation.
- */
+ * Copyright 2022 Blender Foundation. */
/** \file
* \ingroup eevee
diff --git a/source/blender/draw/engines/eevee_next/eevee_defines.hh b/source/blender/draw/engines/eevee_next/eevee_defines.hh
index 248dfae6df9..fca8737f661 100644
--- a/source/blender/draw/engines/eevee_next/eevee_defines.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_defines.hh
@@ -90,6 +90,8 @@
#define VELOCITY_CAMERA_CURR_BUF 4
#define VELOCITY_CAMERA_NEXT_BUF 5
+#define CAMERA_BUF_SLOT 6
+
/* Storage Buffers. */
#define LIGHT_CULL_BUF_SLOT 0
#define LIGHT_BUF_SLOT 1
diff --git a/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc b/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc
index bc0891ceb92..e4c4f6f3f6f 100644
--- a/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc
@@ -637,8 +637,8 @@ void DepthOfField::render(View &view,
/* Do not step over any unvisited tile. */
int max_multiplier = dilation_radius + 1;
- int ring_count = min_ii(DOF_DILATE_RING_COUNT, ceilf(remainder / (float)max_multiplier));
- int multiplier = min_ii(max_multiplier, floorf(remainder / (float)ring_count));
+ int ring_count = min_ii(DOF_DILATE_RING_COUNT, ceilf(remainder / float(max_multiplier)));
+ int multiplier = min_ii(max_multiplier, floorf(remainder / float(ring_count)));
dilation_radius += ring_count * multiplier;
diff --git a/source/blender/draw/engines/eevee_next/eevee_engine.cc b/source/blender/draw/engines/eevee_next/eevee_engine.cc
index 5ef198838c9..3ea6ea475d0 100644
--- a/source/blender/draw/engines/eevee_next/eevee_engine.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_engine.cc
@@ -143,7 +143,7 @@ static void eevee_instance_free(void *instance)
static void eevee_render_to_image(void *vedata,
struct RenderEngine *engine,
struct RenderLayer *layer,
- const struct rcti *UNUSED(rect))
+ const struct rcti * /*rect*/)
{
if (!GPU_shader_storage_buffer_objects_support()) {
return;
@@ -165,9 +165,7 @@ static void eevee_render_to_image(void *vedata,
instance->render_frame(layer, viewname);
EEVEE_Data *ved = static_cast<EEVEE_Data *>(vedata);
- if (ved->instance) {
- delete ved->instance;
- }
+ delete ved->instance;
ved->instance = instance;
}
diff --git a/source/blender/draw/engines/eevee_next/eevee_film.cc b/source/blender/draw/engines/eevee_next/eevee_film.cc
index b89746d99e2..82f948167dc 100644
--- a/source/blender/draw/engines/eevee_next/eevee_film.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_film.cc
@@ -5,7 +5,7 @@
/** \file
* \ingroup eevee
*
- * A film is a fullscreen buffer (usually at output extent)
+ * A film is a full-screen buffer (usually at output extent)
* that will be able to accumulate sample in any distorted camera_type
* using a pixel filter.
*
@@ -120,7 +120,7 @@ void Film::sync_mist()
const ::World *world = inst_.scene->world;
float mist_start = world ? world->miststa : cam.clip_near;
float mist_distance = world ? world->mistdist : fabsf(cam.clip_far - cam.clip_near);
- int mist_type = world ? world->mistype : (int)WO_MIST_LINEAR;
+ int mist_type = world ? world->mistype : int(WO_MIST_LINEAR);
switch (mist_type) {
case WO_MIST_QUADRATIC:
diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.cc b/source/blender/draw/engines/eevee_next/eevee_instance.cc
index 9cba3749d52..a0bdf70e254 100644
--- a/source/blender/draw/engines/eevee_next/eevee_instance.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_instance.cc
@@ -106,6 +106,8 @@ void Instance::begin_sync()
gpencil_engine_enabled = false;
+ scene_sync();
+
depth_of_field.sync();
motion_blur.sync();
hiz_buffer.sync();
@@ -115,6 +117,21 @@ void Instance::begin_sync()
film.sync();
}
+void Instance::scene_sync()
+{
+ SceneHandle &sc_handle = sync.sync_scene(scene);
+
+ sc_handle.reset_recalc_flag();
+
+ /* This refers specifically to the Scene camera that can be accessed
+ * via View Layer Attribute nodes, rather than the actual render camera. */
+ if (scene->camera != nullptr) {
+ ObjectHandle &ob_handle = sync.sync_object(scene->camera);
+
+ ob_handle.reset_recalc_flag();
+ }
+}
+
void Instance::object_sync(Object *ob)
{
const bool is_renderable_type = ELEM(ob->type, OB_CURVES, OB_GPENCIL, OB_MESH, OB_LAMP);
@@ -377,9 +394,9 @@ void Instance::update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view
}
}
- /* NOTE: Name channels lowercase rgba so that compression rules check in OpenEXR DWA code uses
- * loseless compression. Reportedly this naming is the only one which works good from the
- * interoperability point of view. Using xyzw naming is not portable. */
+ /* NOTE: Name channels lowercase `rgba` so that compression rules check in OpenEXR DWA code uses
+ * lossless compression. Reportedly this naming is the only one which works good from the
+ * interoperability point of view. Using `xyzw` naming is not portable. */
auto register_cryptomatte_passes = [&](eViewLayerCryptomatteFlags cryptomatte_layer,
eViewLayerEEVEEPassType eevee_pass) {
if (view_layer->cryptomatte_flag & cryptomatte_layer) {
diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.hh b/source/blender/draw/engines/eevee_next/eevee_instance.hh
index c8eecbd812d..bc610cd0642 100644
--- a/source/blender/draw/engines/eevee_next/eevee_instance.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_instance.hh
@@ -162,6 +162,7 @@ class Instance {
void render_sample();
void render_read_result(RenderLayer *render_layer, const char *view_name);
+ void scene_sync();
void mesh_sync(Object *ob, ObjectHandle &ob_handle);
void update_eval_members();
diff --git a/source/blender/draw/engines/eevee_next/eevee_light.cc b/source/blender/draw/engines/eevee_next/eevee_light.cc
index b60246fa3ab..aa8268dbaa7 100644
--- a/source/blender/draw/engines/eevee_next/eevee_light.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_light.cc
@@ -58,7 +58,7 @@ void Light::sync(/* ShadowModule &shadows , */ const Object *ob, float threshold
this->influence_radius_invsqr_volume = 1.0f / square_f(max_ff(influence_radius_volume, 1e-8f));
this->color = float3(&la->r) * la->energy;
- normalize_m4_m4_ex(this->object_mat.ptr(), ob->obmat, scale);
+ normalize_m4_m4_ex(this->object_mat.ptr(), ob->object_to_world, scale);
/* Make sure we have consistent handedness (in case of negatively scaled Z axis). */
float3 cross = math::cross(float3(this->_right), float3(this->_up));
if (math::dot(cross, float3(this->_back)) < 0.0f) {
@@ -154,8 +154,8 @@ float Light::attenuation_radius_get(const ::Light *la, float light_threshold, fl
void Light::shape_parameters_set(const ::Light *la, const float scale[3])
{
if (la->type == LA_AREA) {
- float area_size_y = (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE)) ? la->area_sizey :
- la->area_size;
+ float area_size_y = ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE) ? la->area_sizey :
+ la->area_size;
_area_size_x = max_ff(0.003f, la->area_size * scale[0] * 0.5f);
_area_size_y = max_ff(0.003f, area_size_y * scale[1] * 0.5f);
/* For volume point lighting. */
diff --git a/source/blender/draw/engines/eevee_next/eevee_material.cc b/source/blender/draw/engines/eevee_next/eevee_material.cc
index a92f96e8c70..d190a1f17a3 100644
--- a/source/blender/draw/engines/eevee_next/eevee_material.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_material.cc
@@ -164,7 +164,7 @@ MaterialPass MaterialModule::material_pass_get(Object *ob,
blender_mat->nodetree :
default_surface_ntree_.nodetree_get(blender_mat);
- MaterialPass matpass;
+ MaterialPass matpass = MaterialPass();
matpass.gpumat = inst_.shaders.material_shader_get(
blender_mat, ntree, pipeline_type, geometry_type, true);
@@ -187,6 +187,8 @@ MaterialPass MaterialModule::material_pass_get(Object *ob,
/* Returned material should be ready to be drawn. */
BLI_assert(GPU_material_status(matpass.gpumat) == GPU_MAT_SUCCESS);
+ inst_.manager->register_layer_attributes(matpass.gpumat);
+
if (GPU_material_recalc_flag_get(matpass.gpumat)) {
inst_.sampling.reset();
}
@@ -217,6 +219,9 @@ MaterialPass MaterialModule::material_pass_get(Object *ob,
matpass.sub_pass = &shader_sub->sub(GPU_material_get_name(matpass.gpumat));
matpass.sub_pass->material_set(*inst_.manager, matpass.gpumat);
}
+ else {
+ matpass.sub_pass = nullptr;
+ }
}
return matpass;
diff --git a/source/blender/draw/engines/eevee_next/eevee_material.hh b/source/blender/draw/engines/eevee_next/eevee_material.hh
index ad0c293926b..f4b1f60b456 100644
--- a/source/blender/draw/engines/eevee_next/eevee_material.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_material.hh
@@ -120,7 +120,7 @@ struct MaterialKey {
uint64_t hash() const
{
BLI_assert(options < sizeof(*mat));
- return (uint64_t)mat + options;
+ return uint64_t(mat) + options;
}
bool operator<(const MaterialKey &k) const
@@ -154,7 +154,7 @@ struct ShaderKey {
uint64_t hash() const
{
- return (uint64_t)shader + options;
+ return uint64_t(shader) + options;
}
bool operator<(const ShaderKey &k) const
diff --git a/source/blender/draw/engines/eevee_next/eevee_motion_blur.cc b/source/blender/draw/engines/eevee_next/eevee_motion_blur.cc
index f68abafa3d4..d6fc74730b2 100644
--- a/source/blender/draw/engines/eevee_next/eevee_motion_blur.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_motion_blur.cc
@@ -141,8 +141,8 @@ void MotionBlurModule::sync()
{
/* Create max velocity tiles. */
PassSimple::Sub &sub = motion_blur_ps_.sub("TilesFlatten");
- eShaderType shader = (inst_.is_viewport()) ? MOTION_BLUR_TILE_FLATTEN_VIEWPORT :
- MOTION_BLUR_TILE_FLATTEN_RENDER;
+ eShaderType shader = inst_.is_viewport() ? MOTION_BLUR_TILE_FLATTEN_VIEWPORT :
+ MOTION_BLUR_TILE_FLATTEN_RENDER;
sub.shader_set(inst_.shaders.static_shader_get(shader));
sub.bind_ubo("motion_blur_buf", data_);
sub.bind_texture("depth_tx", &render_buffers.depth_tx);
diff --git a/source/blender/draw/engines/eevee_next/eevee_pipeline.cc b/source/blender/draw/engines/eevee_next/eevee_pipeline.cc
index 33978518ffc..0242f732f27 100644
--- a/source/blender/draw/engines/eevee_next/eevee_pipeline.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_pipeline.cc
@@ -79,6 +79,8 @@ void ForwardPipeline::sync()
/* Textures. */
prepass_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
+ /* Uniform Buf. */
+ prepass_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
inst_.velocity.bind_resources(&prepass_ps_);
inst_.sampling.bind_resources(&prepass_ps_);
@@ -117,6 +119,8 @@ void ForwardPipeline::sync()
opaque_ps_.bind_ssbo(RBUFS_AOV_BUF_SLOT, &inst_.film.aovs_info);
/* Textures. */
opaque_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
+ /* Uniform Buf. */
+ opaque_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
inst_.lights.bind_resources(&opaque_ps_);
inst_.sampling.bind_resources(&opaque_ps_);
@@ -140,6 +144,8 @@ void ForwardPipeline::sync()
/* Textures. */
sub.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
+ /* Uniform Buf. */
+ opaque_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
inst_.lights.bind_resources(&sub);
inst_.sampling.bind_resources(&sub);
@@ -173,10 +179,10 @@ PassMain::Sub *ForwardPipeline::prepass_transparent_add(const Object *ob,
return nullptr;
}
DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
- if ((blender_mat->blend_flag & MA_BL_CULL_BACKFACE)) {
+ if (blender_mat->blend_flag & MA_BL_CULL_BACKFACE) {
state |= DRW_STATE_CULL_BACK;
}
- float sorting_value = math::dot(float3(ob->obmat[3]), camera_forward_);
+ float sorting_value = math::dot(float3(ob->object_to_world[3]), camera_forward_);
PassMain::Sub *pass = &transparent_ps_.sub(GPU_material_get_name(gpumat), sorting_value);
pass->state_set(state);
pass->material_set(*inst_.manager, gpumat);
@@ -188,10 +194,10 @@ PassMain::Sub *ForwardPipeline::material_transparent_add(const Object *ob,
GPUMaterial *gpumat)
{
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM | DRW_STATE_DEPTH_LESS_EQUAL;
- if ((blender_mat->blend_flag & MA_BL_CULL_BACKFACE)) {
+ if (blender_mat->blend_flag & MA_BL_CULL_BACKFACE) {
state |= DRW_STATE_CULL_BACK;
}
- float sorting_value = math::dot(float3(ob->obmat[3]), camera_forward_);
+ float sorting_value = math::dot(float3(ob->object_to_world[3]), camera_forward_);
PassMain::Sub *pass = &transparent_ps_.sub(GPU_material_get_name(gpumat), sorting_value);
pass->state_set(state);
pass->material_set(*inst_.manager, gpumat);
@@ -201,7 +207,7 @@ PassMain::Sub *ForwardPipeline::material_transparent_add(const Object *ob,
void ForwardPipeline::render(View &view,
Framebuffer &prepass_fb,
Framebuffer &combined_fb,
- GPUTexture *UNUSED(combined_tx))
+ GPUTexture * /*combined_tx*/)
{
UNUSED_VARS(view);
diff --git a/source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc b/source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc
index 8e36e1d071c..29a5484f438 100644
--- a/source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc
@@ -5,7 +5,7 @@
/** \file
* \ingroup eevee
*
- * A film is a fullscreen buffer (usually at output extent)
+ * A film is a full-screen buffer (usually at output extent)
* that will be able to accumulate sample in any distorted camera_type
* using a pixel filter.
*
@@ -43,10 +43,10 @@ void RenderBuffers::acquire(int2 extent)
bool do_vector_render_pass = (enabled_passes & EEVEE_RENDER_PASS_VECTOR) ||
(inst_.motion_blur.postfx_enabled() && !inst_.is_viewport());
uint32_t max_light_color_layer = max_ii(enabled_passes & EEVEE_RENDER_PASS_DIFFUSE_LIGHT ?
- (int)RENDER_PASS_LAYER_DIFFUSE_LIGHT :
+ int(RENDER_PASS_LAYER_DIFFUSE_LIGHT) :
-1,
enabled_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT ?
- (int)RENDER_PASS_LAYER_SPECULAR_LIGHT :
+ int(RENDER_PASS_LAYER_SPECULAR_LIGHT) :
-1) +
1;
/* Only RG16F when only doing only reprojection or motion blur. */
diff --git a/source/blender/draw/engines/eevee_next/eevee_sampling.cc b/source/blender/draw/engines/eevee_next/eevee_sampling.cc
index 76a0e98638b..521b6d603df 100644
--- a/source/blender/draw/engines/eevee_next/eevee_sampling.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_sampling.cc
@@ -215,8 +215,8 @@ void Sampling::dof_disk_sample_get(float *r_radius, float *r_theta) const
samples_passed += ring_sample_count;
}
- *r_radius = ring / (float)dof_ring_count_;
- *r_theta = 2.0f * M_PI * ring_sample / (float)ring_sample_count;
+ *r_radius = ring / float(dof_ring_count_);
+ *r_theta = 2.0f * M_PI * ring_sample / float(ring_sample_count);
}
/** \} */
@@ -233,7 +233,7 @@ void Sampling::cdf_from_curvemapping(const CurveMapping &curve, Vector<float> &c
cdf[0] = 0.0f;
/* Actual CDF evaluation. */
for (int u : IndexRange(cdf.size() - 1)) {
- float x = (float)(u + 1) / (float)(cdf.size() - 1);
+ float x = float(u + 1) / float(cdf.size() - 1);
cdf[u + 1] = cdf[u] + BKE_curvemapping_evaluateF(&curve, 0, x);
}
/* Normalize the CDF. */
@@ -249,14 +249,14 @@ void Sampling::cdf_from_curvemapping(const CurveMapping &curve, Vector<float> &c
void Sampling::cdf_invert(Vector<float> &cdf, Vector<float> &inverted_cdf)
{
for (int u : inverted_cdf.index_range()) {
- float x = (float)u / (float)(inverted_cdf.size() - 1);
+ float x = float(u) / float(inverted_cdf.size() - 1);
for (int i : cdf.index_range()) {
if (i == cdf.size() - 1) {
inverted_cdf[u] = 1.0f;
}
else if (cdf[i] >= x) {
float t = (x - cdf[i]) / (cdf[i + 1] - cdf[i]);
- inverted_cdf[u] = ((float)i + t) / (float)(cdf.size() - 1);
+ inverted_cdf[u] = (float(i) + t) / float(cdf.size() - 1);
break;
}
}
diff --git a/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh b/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh
index 8e96445d6b9..f6a96aaaff2 100644
--- a/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh
@@ -163,7 +163,7 @@ struct CameraData {
float4x4 viewinv;
float4x4 winmat;
float4x4 wininv;
- /** Camera UV scale and bias. Also known as `viewcamtexcofac`. */
+ /** Camera UV scale and bias. */
float2 uv_scale;
float2 uv_bias;
/** Panorama parameters. */
@@ -560,7 +560,7 @@ struct LightCullingData {
uint local_lights_len;
/** Items that are **NOT** processed by the 2.5D culling (i.e: Sun Lights). */
uint sun_lights_len;
- /** Number of items that passes the first culling test. */
+ /** Number of items that passes the first culling test. (local lights only) */
uint visible_count;
/** Extent of one square tile in pixels. */
float tile_size;
diff --git a/source/blender/draw/engines/eevee_next/eevee_sync.cc b/source/blender/draw/engines/eevee_next/eevee_sync.cc
index 09ea7c9ec3d..cbd735ec29c 100644
--- a/source/blender/draw/engines/eevee_next/eevee_sync.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_sync.cc
@@ -68,6 +68,20 @@ WorldHandle &SyncModule::sync_world(::World *world)
return eevee_dd;
}
+SceneHandle &SyncModule::sync_scene(::Scene *scene)
+{
+ DrawEngineType *owner = (DrawEngineType *)&DRW_engine_viewport_eevee_next_type;
+ struct DrawData *dd = DRW_drawdata_ensure(
+ (ID *)scene, owner, sizeof(eevee::SceneHandle), draw_data_init_cb, nullptr);
+ SceneHandle &eevee_dd = *reinterpret_cast<SceneHandle *>(dd);
+
+ const int recalc_flags = ID_RECALC_ALL;
+ if ((eevee_dd.recalc & recalc_flags) != 0) {
+ inst_.sampling.reset();
+ }
+ return eevee_dd;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -215,8 +229,8 @@ static void gpencil_drawcall_add(gpIterData &iter,
iter.vcount = v_first + v_count - iter.vfirst;
}
-static void gpencil_stroke_sync(bGPDlayer *UNUSED(gpl),
- bGPDframe *UNUSED(gpf),
+static void gpencil_stroke_sync(bGPDlayer * /*gpl*/,
+ bGPDframe * /*gpf*/,
bGPDstroke *gps,
void *thunk)
{
@@ -234,17 +248,17 @@ static void gpencil_stroke_sync(bGPDlayer *UNUSED(gpl),
return;
}
+ GPUBatch *geom = DRW_cache_gpencil_get(iter.ob, iter.cfra);
+
if (show_fill) {
- GPUBatch *geom = DRW_cache_gpencil_fills_get(iter.ob, iter.cfra);
int vfirst = gps->runtime.fill_start * 3;
int vcount = gps->tot_triangles * 3;
gpencil_drawcall_add(iter, geom, material, vfirst, vcount, false);
}
if (show_stroke) {
- GPUBatch *geom = DRW_cache_gpencil_strokes_get(iter.ob, iter.cfra);
/* Start one vert before to have gl_InstanceID > 0 (see shader). */
- int vfirst = gps->runtime.stroke_start - 1;
+ int vfirst = gps->runtime.stroke_start * 3;
/* Include "potential" cyclic vertex and start adj vertex (see shader). */
int vcount = gps->totpoints + 1 + 1;
gpencil_drawcall_add(iter, geom, material, vfirst, vcount, true);
diff --git a/source/blender/draw/engines/eevee_next/eevee_sync.hh b/source/blender/draw/engines/eevee_next/eevee_sync.hh
index ab883ce44c2..eda0342c4b6 100644
--- a/source/blender/draw/engines/eevee_next/eevee_sync.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_sync.hh
@@ -139,6 +139,15 @@ struct WorldHandle : public DrawData {
}
};
+struct SceneHandle : public DrawData {
+ void reset_recalc_flag()
+ {
+ if (recalc != 0) {
+ recalc = 0;
+ }
+ }
+};
+
class SyncModule {
private:
Instance &inst_;
@@ -149,6 +158,7 @@ class SyncModule {
ObjectHandle &sync_object(Object *ob);
WorldHandle &sync_world(::World *world);
+ SceneHandle &sync_scene(::Scene *scene);
void sync_mesh(Object *ob,
ObjectHandle &ob_handle,
diff --git a/source/blender/draw/engines/eevee_next/eevee_velocity.cc b/source/blender/draw/engines/eevee_next/eevee_velocity.cc
index 7af311a8ccc..52401c8003e 100644
--- a/source/blender/draw/engines/eevee_next/eevee_velocity.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_velocity.cc
@@ -51,8 +51,8 @@ void VelocityModule::init()
static void step_object_sync_render(void *velocity,
Object *ob,
- RenderEngine *UNUSED(engine),
- Depsgraph *UNUSED(depsgraph))
+ RenderEngine * /*engine*/,
+ Depsgraph * /*depsgraph*/)
{
ObjectKey object_key(ob);
/* NOTE: Dummy resource handle since this will not be used for drawing. */
@@ -106,16 +106,16 @@ bool VelocityModule::step_object_sync(Object *ob,
vel.obj.ofs[step_] = object_steps_usage[step_]++;
vel.obj.resource_id = resource_handle.resource_index();
vel.id = (ID *)ob->data;
- object_steps[step_]->get_or_resize(vel.obj.ofs[step_]) = ob->obmat;
+ object_steps[step_]->get_or_resize(vel.obj.ofs[step_]) = ob->object_to_world;
if (step_ == STEP_CURRENT) {
/* Replace invalid steps. Can happen if object was hidden in one of those steps. */
if (vel.obj.ofs[STEP_PREVIOUS] == -1) {
vel.obj.ofs[STEP_PREVIOUS] = object_steps_usage[STEP_PREVIOUS]++;
- object_steps[STEP_PREVIOUS]->get_or_resize(vel.obj.ofs[STEP_PREVIOUS]) = ob->obmat;
+ object_steps[STEP_PREVIOUS]->get_or_resize(vel.obj.ofs[STEP_PREVIOUS]) = ob->object_to_world;
}
if (vel.obj.ofs[STEP_NEXT] == -1) {
vel.obj.ofs[STEP_NEXT] = object_steps_usage[STEP_NEXT]++;
- object_steps[STEP_NEXT]->get_or_resize(vel.obj.ofs[STEP_NEXT]) = ob->obmat;
+ object_steps[STEP_NEXT]->get_or_resize(vel.obj.ofs[STEP_NEXT]) = ob->object_to_world;
}
}
@@ -226,11 +226,11 @@ void VelocityModule::step_swap()
for (VelocityObjectData &vel : velocity_map.values()) {
vel.obj.ofs[step_a] = vel.obj.ofs[step_b];
- vel.obj.ofs[step_b] = (uint)-1;
+ vel.obj.ofs[step_b] = uint(-1);
vel.geo.ofs[step_a] = vel.geo.ofs[step_b];
vel.geo.len[step_a] = vel.geo.len[step_b];
- vel.geo.ofs[step_b] = (uint)-1;
- vel.geo.len[step_b] = (uint)-1;
+ vel.geo.ofs[step_b] = uint(-1);
+ vel.geo.len[step_b] = uint(-1);
}
};
@@ -262,7 +262,7 @@ void VelocityModule::end_sync()
uint32_t max_resource_id_ = 0u;
for (Map<ObjectKey, VelocityObjectData>::Item item : velocity_map.items()) {
- if (item.value.obj.resource_id == (uint32_t)-1) {
+ if (item.value.obj.resource_id == uint32_t(-1)) {
deleted_obj.append(item.key);
}
else {
@@ -302,7 +302,7 @@ void VelocityModule::end_sync()
}
indirection_buf[vel.obj.resource_id] = vel;
/* Reset for next sync. */
- vel.obj.resource_id = (uint)-1;
+ vel.obj.resource_id = uint(-1);
}
object_steps[STEP_PREVIOUS]->push_update();
diff --git a/source/blender/draw/engines/eevee_next/eevee_view.cc b/source/blender/draw/engines/eevee_next/eevee_view.cc
index 48951c2bae7..3a4fb9d4c20 100644
--- a/source/blender/draw/engines/eevee_next/eevee_view.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_view.cc
@@ -39,7 +39,7 @@ void ShadingView::sync()
int2 render_extent = inst_.film.render_extent_get();
if (false /* inst_.camera.is_panoramic() */) {
- int64_t render_pixel_count = render_extent.x * (int64_t)render_extent.y;
+ int64_t render_pixel_count = render_extent.x * int64_t(render_extent.y);
/* Divide pixel count between the 6 views. Rendering to a square target. */
extent_[0] = extent_[1] = ceilf(sqrtf(1 + (render_pixel_count / 6)));
/* TODO(@fclem): Clip unused views here. */
diff --git a/source/blender/draw/engines/eevee_next/eevee_world.cc b/source/blender/draw/engines/eevee_next/eevee_world.cc
index 313c0bda42e..37f90570028 100644
--- a/source/blender/draw/engines/eevee_next/eevee_world.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_world.cc
@@ -87,6 +87,9 @@ void World::sync()
default_tree.nodetree_get(bl_world);
GPUMaterial *gpumat = inst_.shaders.world_shader_get(bl_world, ntree);
+
+ inst_.manager->register_layer_attributes(gpumat);
+
inst_.pipelines.world.sync(gpumat);
}
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl
index 6fe5fa01fa3..ea1b02e56b3 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl
@@ -17,7 +17,7 @@
vec3 attr_load_orco(vec4 orco)
{
/* We know when there is no orco layer when orco.w is 1.0 because it uses the generic vertex
- * attrib (which is [0,0,0,1]). */
+ * attribute (which is [0,0,0,1]). */
if (orco.w == 1.0) {
/* If the object does not have any deformation, the orco layer calculation is done on the fly
* using the orco_madd factors. */
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_accumulator_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_accumulator_lib.glsl
index 99a47c541e9..49a00b60abf 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_accumulator_lib.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_accumulator_lib.glsl
@@ -239,7 +239,7 @@ void dof_gather_accumulate_sample_ring(DofGatherData ring_data,
}
}
-/* FIXME(fclem) Seems to be wrong since it needs ringcount+1 as input for
+/* FIXME(fclem) Seems to be wrong since it needs `ringcount + 1` as input for
* slightfocus gather. */
/* This should be replaced by web_sample_count_get() but doing so is breaking other things. */
int dof_gather_total_sample_count(const int ring_count, const int ring_density)
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_reduce_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_reduce_comp.glsl
index a6426cd06e4..41a6fe466b9 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_reduce_comp.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_reduce_comp.glsl
@@ -82,7 +82,7 @@ void main()
{
ivec2 texel = min(ivec2(gl_GlobalInvocationID.xy), imageSize(inout_color_lod0_img) - 1);
uvec2 texel_local = gl_LocalInvocationID.xy;
- /* Increase readablility. */
+ /* Increase readability. */
#define LOCAL_INDEX texel_local.y][texel_local.x
#define LOCAL_OFFSET(x_, y_) texel_local.y + (y_)][texel_local.x + (x_)
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl
index 21b9a83abb9..8845434412e 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl
@@ -187,7 +187,7 @@ void film_cryptomatte_layer_accum_and_store(
if (pass_id == -1) {
return;
}
- /* x = hash, y = accumed weight. Only keep track of 4 highest weighted samples. */
+ /* x = hash, y = accumulated weight. Only keep track of 4 highest weighted samples. */
vec2 crypto_samples[4] = vec2[4](vec2(0.0), vec2(0.0), vec2(0.0), vec2(0.0));
for (int i = 0; i < film_buf.samples_len; i++) {
FilmSample src = film_sample_get(i, texel_film);
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl
index c60527162f7..87a5bf71c45 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl
@@ -16,29 +16,18 @@ void main()
float hardness;
vec2 thickness;
- gl_Position = gpencil_vertex(ma,
- ma1,
- ma2,
- ma3,
- pos,
- pos1,
- pos2,
- pos3,
- uv1,
- uv2,
- col1,
- col2,
- fcol1,
- vec4(drw_view.viewport_size, drw_view.viewport_size_inverse),
- interp.P,
- interp.N,
- g_color,
- strength,
- g_uvs,
- sspos,
- aspect,
- thickness,
- hardness);
+ gl_Position = gpencil_vertex(
+ /* TODO */
+ vec4(1024.0, 1024.0, 1.0 / 1024.0, 1.0 / 1024.0),
+ interp.P,
+ interp.N,
+ g_color,
+ strength,
+ g_uvs,
+ sspos,
+ aspect,
+ thickness,
+ hardness);
#ifdef MAT_VELOCITY
/* GPencil do not support deformation motion blur. */
vec3 lP_curr = transform_point(ModelMatrixInverse, interp.P);
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_hiz_update_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_hiz_update_comp.glsl
index 597bc73e2ad..479a6b590b0 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_hiz_update_comp.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_hiz_update_comp.glsl
@@ -6,11 +6,11 @@
* http://rastergrid.com/blog/2010/10/hierarchical-z-map-based-occlusion-culling/
*
* Major simplification has been made since we pad the buffer to always be
- * bigger than input to avoid mipmapping misalignement.
+ * bigger than input to avoid mipmapping misalignment.
*
* Start by copying the base level by quad loading the depth.
* Then each thread compute it's local depth for level 1.
- * After that we use shared variables to do inter thread comunication and
+ * After that we use shared variables to do inter thread communication and
* downsample to max level.
*/
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_debug_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_debug_frag.glsl
index eefc024d0b8..366a7dc9ba0 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_debug_frag.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_debug_frag.glsl
@@ -1,6 +1,6 @@
/**
- * Debug Shader outputing a gradient of orange - white - blue to mark culling hotspots.
+ * Debug Shader outputting a gradient of orange - white - blue to mark culling hotspots.
* Green pixels are error pixels that are missing lights from the culling pass (i.e: when culling
* pass is not conservative enough).
*/
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_light_iter_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_light_iter_lib.glsl
index 22a5f98e6c3..8daea3f52b9 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_light_iter_lib.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_light_iter_lib.glsl
@@ -47,7 +47,7 @@ int culling_z_to_zbin(float scale, float bias, float z)
/* Ensure all threads inside a subgroup get the same value to reduce VGPR usage. */ \
min_index = subgroupBroadcastFirst(subgroupMin(min_index)); \
max_index = subgroupBroadcastFirst(subgroupMax(max_index)); \
- /* Same as divide by 32 but avoid interger division. */ \
+ /* Same as divide by 32 but avoid integer division. */ \
uint word_min = min_index >> 5u; \
uint word_max = max_index >> 5u; \
for (uint word_idx = word_min; word_idx <= word_max; word_idx++) { \
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_light_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_light_lib.glsl
index 58608f6e1f0..144445801cf 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_light_lib.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_light_lib.glsl
@@ -84,7 +84,7 @@ float light_point_light(LightData ld, const bool is_directional, vec3 L, float d
**/
float d_sqr = sqr(dist);
float r_sqr = ld.radius_squared;
- /* Using reformulation that has better numerical percision. */
+ /* Using reformulation that has better numerical precision. */
float power = 2.0 / (d_sqr + r_sqr + dist * sqrt(d_sqr + r_sqr));
if (is_area_light(ld.type)) {
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl
index dd047709afd..4b53375575c 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl
@@ -344,8 +344,8 @@ vec3 coordinate_screen(vec3 P)
}
else {
/* TODO(fclem): Actual camera transform. */
- window.xy = project_point(ViewProjectionMatrix, P).xy * 0.5 + 0.5;
- window.xy = window.xy * CameraTexCoFactors.xy + CameraTexCoFactors.zw;
+ window.xy = project_point(ProjectionMatrix, transform_point(ViewMatrix, P)).xy * 0.5 + 0.5;
+ window.xy = window.xy * camera_buf.uv_scale + camera_buf.uv_bias;
}
return window;
}
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_sampling_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_sampling_lib.glsl
index 0eea4a5ff33..a54133167ac 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_sampling_lib.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_sampling_lib.glsl
@@ -41,7 +41,7 @@ vec3 sampling_rng_3D_get(const eSamplingDimension dimension)
/** \name Random Number Generators.
* \{ */
-/* Interlieved gradient noise by Jorge Jimenez
+/* Interleaved gradient noise by Jorge Jimenez
* http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare
* Seeding found by Epic Game. */
float interlieved_gradient_noise(vec2 pixel, float seed, float offset)
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_velocity_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_velocity_lib.glsl
index 8d02609fedc..a17aec8eae2 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_velocity_lib.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_velocity_lib.glsl
@@ -32,7 +32,7 @@ vec4 velocity_surface(vec3 P_prv, vec3 P, vec3 P_nxt)
next_uv = curr_uv;
}
/* NOTE: We output both vectors in the same direction so we can reuse the same vector
- * with rgrg swizzle in viewport. */
+ * with RGRG swizzle in viewport. */
vec4 motion = vec4(prev_uv - curr_uv, curr_uv - next_uv);
/* Convert NDC velocity to UV velocity */
motion *= 0.5;
@@ -54,7 +54,7 @@ vec4 velocity_background(vec3 vV)
vec2 curr_uv = project_point(camera_curr.winmat, V).xy;
vec2 next_uv = project_point(camera_next.winmat, V).xy;
/* NOTE: We output both vectors in the same direction so we can reuse the same vector
- * with rgrg swizzle in viewport. */
+ * with RGRG swizzle in viewport. */
vec4 motion = vec4(prev_uv - curr_uv, curr_uv - next_uv);
/* Convert NDC velocity to UV velocity */
motion *= 0.5;
diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_light_culling_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_light_culling_info.hh
index 41602426a1d..45232a8c551 100644
--- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_light_culling_info.hh
+++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_light_culling_info.hh
@@ -21,7 +21,7 @@ GPU_SHADER_CREATE_INFO(eevee_light_data)
GPU_SHADER_CREATE_INFO(eevee_light_culling_select)
.do_static_compilation(true)
- .additional_info("eevee_shared", "draw_view")
+ .additional_info("eevee_shared", "draw_view", "draw_view_culling")
.local_group_size(CULLING_SELECT_GROUP_SIZE)
.storage_buf(0, Qualifier::READ_WRITE, "LightCullingData", "light_cull_buf")
.storage_buf(1, Qualifier::READ, "LightData", "in_light_buf[]")
@@ -52,7 +52,7 @@ GPU_SHADER_CREATE_INFO(eevee_light_culling_zbin)
GPU_SHADER_CREATE_INFO(eevee_light_culling_tile)
.do_static_compilation(true)
- .additional_info("eevee_shared", "draw_view")
+ .additional_info("eevee_shared", "draw_view", "draw_view_culling")
.local_group_size(CULLING_TILE_GROUP_SIZE)
.storage_buf(0, Qualifier::READ, "LightCullingData", "light_cull_buf")
.storage_buf(1, Qualifier::READ, "LightData", "light_buf[]")
diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh
index 78d52d4b90e..7883bf01aeb 100644
--- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh
+++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh
@@ -20,6 +20,8 @@ GPU_SHADER_CREATE_INFO(eevee_sampling_data)
GPU_SHADER_CREATE_INFO(eevee_utility_texture)
.sampler(RBUFS_UTILITY_TEX_SLOT, ImageType::FLOAT_2D_ARRAY, "utility_tx");
+GPU_SHADER_CREATE_INFO(eevee_camera).uniform_buf(CAMERA_BUF_SLOT, "CameraData", "camera_buf");
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -112,10 +114,11 @@ GPU_SHADER_CREATE_INFO(eevee_surf_deferred)
// .image_out(5, Qualifier::WRITE, GPU_R11F_G11F_B10F, "gbuff_emission")
/* Render-passes. */
// .image_out(6, Qualifier::READ_WRITE, GPU_RGBA16F, "rpass_volume_light")
- /* TODO: AOVs maybe? */
.fragment_source("eevee_surf_deferred_frag.glsl")
- // .additional_info("eevee_aov_out", "eevee_sampling_data", "eevee_utility_texture")
- ;
+ .additional_info("eevee_camera",
+ "eevee_utility_texture",
+ "eevee_sampling_data",
+ "eevee_aov_out");
GPU_SHADER_CREATE_INFO(eevee_surf_forward)
.vertex_out(eevee_surf_iface)
@@ -127,6 +130,7 @@ GPU_SHADER_CREATE_INFO(eevee_surf_forward)
.fragment_source("eevee_surf_forward_frag.glsl")
.additional_info("eevee_cryptomatte_out",
"eevee_light_data",
+ "eevee_camera",
"eevee_utility_texture",
"eevee_sampling_data"
// "eevee_lightprobe_data",
@@ -141,7 +145,7 @@ GPU_SHADER_CREATE_INFO(eevee_surf_forward)
GPU_SHADER_CREATE_INFO(eevee_surf_depth)
.vertex_out(eevee_surf_iface)
.fragment_source("eevee_surf_depth_frag.glsl")
- .additional_info("eevee_sampling_data", "eevee_utility_texture");
+ .additional_info("eevee_sampling_data", "eevee_camera", "eevee_utility_texture");
GPU_SHADER_CREATE_INFO(eevee_surf_world)
.vertex_out(eevee_surf_iface)
@@ -151,6 +155,7 @@ GPU_SHADER_CREATE_INFO(eevee_surf_world)
.additional_info("eevee_aov_out",
"eevee_cryptomatte_out",
"eevee_render_pass_out",
+ "eevee_camera",
"eevee_utility_texture");
#undef image_out
diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
index ec44fdf42d5..06bf531cded 100644
--- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -39,9 +39,9 @@ GPENCIL_tObject *gpencil_object_cache_add(GPENCIL_PrivateData *pd, Object *ob)
tgp_ob->layers.first = tgp_ob->layers.last = NULL;
tgp_ob->vfx.first = tgp_ob->vfx.last = NULL;
- tgp_ob->camera_z = dot_v3v3(pd->camera_z_axis, ob->obmat[3]);
+ tgp_ob->camera_z = dot_v3v3(pd->camera_z_axis, ob->object_to_world[3]);
tgp_ob->is_drawmode3d = (gpd->draw_mode == GP_DRAWMODE_3D) || pd->draw_depth_only;
- tgp_ob->object_scale = mat4_to_scale(ob->obmat);
+ tgp_ob->object_scale = mat4_to_scale(ob->object_to_world);
/* Check if any material with holdout flag enabled. */
tgp_ob->do_mat_holdout = false;
@@ -49,7 +49,7 @@ GPENCIL_tObject *gpencil_object_cache_add(GPENCIL_PrivateData *pd, Object *ob)
for (int i = 0; i < tot_materials; i++) {
MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, i + 1);
if (((gp_style != NULL) && (gp_style->flag & GP_MATERIAL_IS_STROKE_HOLDOUT)) ||
- ((gp_style->flag & GP_MATERIAL_IS_FILL_HOLDOUT))) {
+ (gp_style->flag & GP_MATERIAL_IS_FILL_HOLDOUT)) {
tgp_ob->do_mat_holdout = true;
break;
}
@@ -71,7 +71,7 @@ GPENCIL_tObject *gpencil_object_cache_add(GPENCIL_PrivateData *pd, Object *ob)
add_v3_fl(size, 1e-8f);
rescale_m4(mat, size);
/* BBox space to World. */
- mul_m4_m4m4(mat, ob->obmat, mat);
+ mul_m4_m4m4(mat, ob->object_to_world, mat);
if (DRW_view_is_persp_get(NULL)) {
/* BBox center to camera vector. */
sub_v3_v3v3(tgp_ob->plane_normal, pd->camera_pos, mat[3]);
@@ -96,9 +96,9 @@ GPENCIL_tObject *gpencil_object_cache_add(GPENCIL_PrivateData *pd, Object *ob)
unit_m4(tgp_ob->plane_mat);
copy_v3_v3(tgp_ob->plane_mat[2], tgp_ob->plane_normal);
orthogonalize_m4(tgp_ob->plane_mat, 2);
- mul_mat3_m4_v3(ob->obmat, size);
+ mul_mat3_m4_v3(ob->object_to_world, size);
float radius = len_v3(size);
- mul_m4_v3(ob->obmat, center);
+ mul_m4_v3(ob->object_to_world, center);
rescale_m4(tgp_ob->plane_mat, (float[3]){radius, radius, radius});
copy_v3_v3(tgp_ob->plane_mat[3], center);
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_data.c b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
index e54ac99a888..1ebf3982a12 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_data.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
@@ -380,27 +380,27 @@ void gpencil_light_pool_populate(GPENCIL_LightPool *lightpool, Object *ob)
float(*mat)[4] = (float(*)[4])gp_light->right;
if (la->type == LA_SPOT) {
- copy_m4_m4(mat, ob->imat);
+ copy_m4_m4(mat, ob->world_to_object);
gp_light->type = GP_LIGHT_TYPE_SPOT;
gp_light->spot_size = cosf(la->spotsize * 0.5f);
gp_light->spot_blend = (1.0f - gp_light->spot_size) * la->spotblend;
}
else if (la->type == LA_AREA) {
/* Simulate area lights using a spot light. */
- normalize_m4_m4(mat, ob->obmat);
+ normalize_m4_m4(mat, ob->object_to_world);
invert_m4(mat);
gp_light->type = GP_LIGHT_TYPE_SPOT;
gp_light->spot_size = cosf(M_PI_2);
gp_light->spot_blend = (1.0f - gp_light->spot_size) * 1.0f;
}
else if (la->type == LA_SUN) {
- normalize_v3_v3(gp_light->forward, ob->obmat[2]);
+ normalize_v3_v3(gp_light->forward, ob->object_to_world[2]);
gp_light->type = GP_LIGHT_TYPE_SUN;
}
else {
gp_light->type = GP_LIGHT_TYPE_POINT;
}
- copy_v4_v4(gp_light->position, ob->obmat[3]);
+ copy_v4_v4(gp_light->position, ob->object_to_world[3]);
copy_v3_v3(gp_light->color, &la->r);
mul_v3_fl(gp_light->color, la->energy * light_power_get(la));
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 42c396a0d43..6a4312e572a 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -289,7 +289,7 @@ void GPENCIL_cache_init(void *ved)
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
}
- Camera *cam = (pd->camera != NULL) ? pd->camera->data : NULL;
+ Camera *cam = (pd->camera != NULL && pd->camera->type == OB_CAMERA) ? pd->camera->data : NULL;
/* Pseudo DOF setup. */
if (cam && (cam->dof.flag & CAM_DOF_ENABLED)) {
@@ -342,7 +342,6 @@ typedef struct gpIterPopulateData {
int stroke_index_offset;
/* Infos for call batching. */
struct GPUBatch *geom;
- bool instancing;
int vfirst, vcount;
} gpIterPopulateData;
@@ -352,12 +351,7 @@ static void gpencil_drawcall_flush(gpIterPopulateData *iter)
{
#if !DISABLE_BATCHING
if (iter->geom != NULL) {
- if (iter->instancing) {
- DRW_shgroup_call_instance_range(iter->grp, iter->ob, iter->geom, iter->vfirst, iter->vcount);
- }
- else {
- DRW_shgroup_call_range(iter->grp, iter->ob, iter->geom, iter->vfirst, iter->vcount);
- }
+ DRW_shgroup_call_range(iter->grp, iter->ob, iter->geom, iter->vfirst, iter->vcount);
}
#endif
@@ -367,25 +361,22 @@ static void gpencil_drawcall_flush(gpIterPopulateData *iter)
}
/* Group draw-calls that are consecutive and with the same type. Reduces GPU driver overhead. */
-static void gpencil_drawcall_add(
- gpIterPopulateData *iter, struct GPUBatch *geom, bool instancing, int v_first, int v_count)
+static void gpencil_drawcall_add(gpIterPopulateData *iter,
+ struct GPUBatch *geom,
+ int v_first,
+ int v_count)
{
#if DISABLE_BATCHING
- if (instancing) {
- DRW_shgroup_call_instance_range(iter->grp, iter->ob, geom, v_first, v_count);
- }
- else {
- DRW_shgroup_call_range(iter->grp, iter->ob, geom, v_first, v_count);
- }
+ DRW_shgroup_call_range(iter->grp, iter->ob, geom, v_first, v_count);
+ return;
#endif
int last = iter->vfirst + iter->vcount;
/* Interrupt draw-call grouping if the sequence is not consecutive. */
- if ((geom != iter->geom) || (v_first - last > 3)) {
+ if ((geom != iter->geom) || (v_first - last > 0)) {
gpencil_drawcall_flush(iter);
}
iter->geom = geom;
- iter->instancing = instancing;
if (iter->vfirst == -1) {
iter->vfirst = v_first;
}
@@ -459,6 +450,7 @@ static void gpencil_layer_cache_populate(bGPDlayer *gpl,
DRW_shgroup_uniform_texture(grp, "gpStrokeTexture", iter->tex_stroke);
DRW_shgroup_uniform_int_copy(grp, "gpMaterialOffset", iter->mat_ofs);
DRW_shgroup_uniform_float_copy(grp, "gpStrokeIndexOffset", iter->stroke_index_offset);
+ DRW_shgroup_uniform_vec2_copy(grp, "viewportSize", DRW_viewport_size_get());
}
static void gpencil_stroke_cache_populate(bGPDlayer *gpl,
@@ -515,22 +507,33 @@ static void gpencil_stroke_cache_populate(bGPDlayer *gpl,
bool do_sbuffer = (iter->do_sbuffer_call == DRAW_NOW);
+ GPUBatch *geom = do_sbuffer ? DRW_cache_gpencil_sbuffer_get(iter->ob, show_fill) :
+ DRW_cache_gpencil_get(iter->ob, iter->pd->cfra);
+ if (geom != iter->geom) {
+ gpencil_drawcall_flush(iter);
+
+ GPUVertBuf *position_tx = do_sbuffer ?
+ DRW_cache_gpencil_sbuffer_position_buffer_get(iter->ob,
+ show_fill) :
+ DRW_cache_gpencil_position_buffer_get(iter->ob, iter->pd->cfra);
+ GPUVertBuf *color_tx = do_sbuffer ?
+ DRW_cache_gpencil_sbuffer_color_buffer_get(iter->ob, show_fill) :
+ DRW_cache_gpencil_color_buffer_get(iter->ob, iter->pd->cfra);
+ DRW_shgroup_buffer_texture(iter->grp, "gp_pos_tx", position_tx);
+ DRW_shgroup_buffer_texture(iter->grp, "gp_col_tx", color_tx);
+ }
+
if (show_fill) {
- GPUBatch *geom = do_sbuffer ? DRW_cache_gpencil_sbuffer_fill_get(iter->ob) :
- DRW_cache_gpencil_fills_get(iter->ob, iter->pd->cfra);
int vfirst = gps->runtime.fill_start * 3;
int vcount = gps->tot_triangles * 3;
- gpencil_drawcall_add(iter, geom, false, vfirst, vcount);
+ gpencil_drawcall_add(iter, geom, vfirst, vcount);
}
if (show_stroke) {
- GPUBatch *geom = do_sbuffer ? DRW_cache_gpencil_sbuffer_stroke_get(iter->ob) :
- DRW_cache_gpencil_strokes_get(iter->ob, iter->pd->cfra);
- /* Start one vert before to have gl_InstanceID > 0 (see shader). */
- int vfirst = gps->runtime.stroke_start - 1;
- /* Include "potential" cyclic vertex and start adj vertex (see shader). */
- int vcount = gps->totpoints + 1 + 1;
- gpencil_drawcall_add(iter, geom, true, vfirst, vcount);
+ int vfirst = gps->runtime.stroke_start * 3;
+ bool is_cyclic = ((gps->flag & GP_STROKE_CYCLIC) != 0) && (gps->totpoints > 2);
+ int vcount = (gps->totpoints + (int)is_cyclic) * 2 * 3;
+ gpencil_drawcall_add(iter, geom, vfirst, vcount);
}
iter->stroke_index_last = gps->runtime.stroke_start + gps->totpoints + 1;
diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
index 7eb3569219d..9b1129e77be 100644
--- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
+++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
@@ -96,9 +96,9 @@ static void gpencil_vfx_blur(BlurShaderFxData *fx, Object *ob, gpIterVfxData *it
float winmat[4][4], persmat[4][4];
float blur_size[2] = {fx->radius[0], fx->radius[1]};
DRW_view_persmat_get(NULL, persmat, false);
- const float w = fabsf(mul_project_m4_v3_zfac(persmat, ob->obmat[3]));
+ const float w = fabsf(mul_project_m4_v3_zfac(persmat, ob->object_to_world[3]));
- if ((fx->flag & FX_BLUR_DOF_MODE)) {
+ if (fx->flag & FX_BLUR_DOF_MODE) {
/* Compute circle of confusion size. */
float coc = (iter->pd->dof_params[0] / -w) - iter->pd->dof_params[1];
copy_v2_fl(blur_size, fabsf(coc));
@@ -108,7 +108,7 @@ static void gpencil_vfx_blur(BlurShaderFxData *fx, Object *ob, gpIterVfxData *it
DRW_view_winmat_get(NULL, winmat, false);
const float *vp_size = DRW_viewport_size_get();
float world_pixel_scale = 1.0f / GPENCIL_PIXEL_FACTOR;
- float scale = mat4_to_scale(ob->obmat);
+ float scale = mat4_to_scale(ob->object_to_world);
float distance_factor = world_pixel_scale * scale * winmat[1][1] * vp_size[1] / w;
mul_v2_fl(blur_size, distance_factor);
}
@@ -175,11 +175,11 @@ static void gpencil_vfx_rim(RimShaderFxData *fx, Object *ob, gpIterVfxData *iter
const float *vp_size = DRW_viewport_size_get();
const float *vp_size_inv = DRW_viewport_invert_size_get();
- const float w = fabsf(mul_project_m4_v3_zfac(persmat, ob->obmat[3]));
+ const float w = fabsf(mul_project_m4_v3_zfac(persmat, ob->object_to_world[3]));
/* Modify by distance to camera and object scale. */
float world_pixel_scale = 1.0f / GPENCIL_PIXEL_FACTOR;
- float scale = mat4_to_scale(ob->obmat);
+ float scale = mat4_to_scale(ob->object_to_world);
float distance_factor = (world_pixel_scale * scale * winmat[1][1] * vp_size[1]) / w;
mul_v2_fl(offset, distance_factor);
mul_v2_v2(offset, vp_size_inv);
@@ -248,8 +248,8 @@ static void gpencil_vfx_pixelize(PixelShaderFxData *fx, Object *ob, gpIterVfxDat
mul_v2_v2(pixel_size, vp_size_inv);
/* Fixed pixelisation center from object center. */
- const float w = fabsf(mul_project_m4_v3_zfac(persmat, ob->obmat[3]));
- mul_v3_m4v3(ob_center, persmat, ob->obmat[3]);
+ const float w = fabsf(mul_project_m4_v3_zfac(persmat, ob->object_to_world[3]));
+ mul_v3_m4v3(ob_center, persmat, ob->object_to_world[3]);
mul_v3_fl(ob_center, 1.0f / w);
const bool use_antialiasing = ((fx->flag & FX_PIXEL_FILTER_NEAREST) == 0);
@@ -260,7 +260,7 @@ static void gpencil_vfx_pixelize(PixelShaderFxData *fx, Object *ob, gpIterVfxDat
/* Modify by distance to camera and object scale. */
float world_pixel_scale = 1.0f / GPENCIL_PIXEL_FACTOR;
- float scale = mat4_to_scale(ob->obmat);
+ float scale = mat4_to_scale(ob->object_to_world);
mul_v2_fl(pixel_size, (world_pixel_scale * scale * winmat[1][1] * vp_size[1]) / w);
/* Center to texel */
@@ -310,7 +310,9 @@ static void gpencil_vfx_shadow(ShadowShaderFxData *fx, Object *ob, gpIterVfxData
const float *vp_size_inv = DRW_viewport_invert_size_get();
const float ratio = vp_size_inv[1] / vp_size_inv[0];
- copy_v3_v3(rot_center, (use_obj_pivot && fx->object) ? fx->object->obmat[3] : ob->obmat[3]);
+ copy_v3_v3(rot_center,
+ (use_obj_pivot && fx->object) ? fx->object->object_to_world[3] :
+ ob->object_to_world[3]);
const float w = fabsf(mul_project_m4_v3_zfac(persmat, rot_center));
mul_v3_m4v3(rot_center, persmat, rot_center);
@@ -318,7 +320,7 @@ static void gpencil_vfx_shadow(ShadowShaderFxData *fx, Object *ob, gpIterVfxData
/* Modify by distance to camera and object scale. */
float world_pixel_scale = 1.0f / GPENCIL_PIXEL_FACTOR;
- float scale = mat4_to_scale(ob->obmat);
+ float scale = mat4_to_scale(ob->object_to_world);
float distance_factor = (world_pixel_scale * scale * winmat[1][1] * vp_size[1]) / w;
mul_v2_fl(offset, distance_factor);
mul_v2_v2(offset, vp_size_inv);
@@ -485,13 +487,13 @@ static void gpencil_vfx_wave(WaveShaderFxData *fx, Object *ob, gpIterVfxData *it
const float *vp_size = DRW_viewport_size_get();
const float *vp_size_inv = DRW_viewport_invert_size_get();
- const float w = fabsf(mul_project_m4_v3_zfac(persmat, ob->obmat[3]));
- mul_v3_m4v3(wave_center, persmat, ob->obmat[3]);
+ const float w = fabsf(mul_project_m4_v3_zfac(persmat, ob->object_to_world[3]));
+ mul_v3_m4v3(wave_center, persmat, ob->object_to_world[3]);
mul_v3_fl(wave_center, 1.0f / w);
/* Modify by distance to camera and object scale. */
float world_pixel_scale = 1.0f / GPENCIL_PIXEL_FACTOR;
- float scale = mat4_to_scale(ob->obmat);
+ float scale = mat4_to_scale(ob->object_to_world);
float distance_factor = (world_pixel_scale * scale * winmat[1][1] * vp_size[1]) / w;
wave_center[0] = wave_center[0] * 0.5f + 0.5f;
@@ -542,7 +544,7 @@ static void gpencil_vfx_swirl(SwirlShaderFxData *fx, Object *UNUSED(ob), gpIterV
DRW_view_persmat_get(NULL, persmat, false);
const float *vp_size = DRW_viewport_size_get();
- copy_v3_v3(swirl_center, fx->object->obmat[3]);
+ copy_v3_v3(swirl_center, fx->object->object_to_world[3]);
const float w = fabsf(mul_project_m4_v3_zfac(persmat, swirl_center));
mul_v3_m4v3(swirl_center, persmat, swirl_center);
@@ -550,7 +552,7 @@ static void gpencil_vfx_swirl(SwirlShaderFxData *fx, Object *UNUSED(ob), gpIterV
/* Modify by distance to camera and object scale. */
float world_pixel_scale = 1.0f / GPENCIL_PIXEL_FACTOR;
- float scale = mat4_to_scale(fx->object->obmat);
+ float scale = mat4_to_scale(fx->object->object_to_world);
float distance_factor = (world_pixel_scale * scale * winmat[1][1] * vp_size[1]) / w;
mul_v2_fl(swirl_center, 0.5f);
diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_shared.h b/source/blender/draw/engines/gpencil/gpencil_shader_shared.h
index 4c621e955b9..3f0f73e7c13 100644
--- a/source/blender/draw/engines/gpencil/gpencil_shader_shared.h
+++ b/source/blender/draw/engines/gpencil/gpencil_shader_shared.h
@@ -41,6 +41,9 @@ enum gpLightType {
GP_LIGHT_TYPE_AMBIENT = 3u,
};
+#define GP_IS_STROKE_VERTEX_BIT (1 << 30)
+#define GP_VERTEX_ID_SHIFT 2
+
/* Avoid compiler funkiness with enum types not being strongly typed in C. */
#ifndef GPU_SHADER
# define gpMaterialFlag uint
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
index 6671c16aa0b..642939136c8 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
@@ -1,92 +1,4 @@
-/* Must match C declaration. */
-struct gpMaterial {
- vec4 stroke_color;
- vec4 fill_color;
- vec4 fill_mix_color;
- vec4 fill_uv_rot_scale;
- vec4 fill_uv_offset;
- /* Put float/int at the end to avoid padding error */
- /* Some drivers are completely messing the alignment or the fetches here.
- * We are forced to pack these into vec4 otherwise we only get 0.0 as value. */
- vec4 gp_mat_packed_1;
- // float stroke_texture_mix;
- // float stroke_u_scale;
- // float fill_texture_mix;
- // int gp_flag;
- /* Please ensure 16 byte alignment (multiple of vec4). */
-};
-
-#define MATERIAL(m) materials[m + gpMaterialOffset]
-
-#define stroke_texture_mix gp_mat_packed_1.x
-#define stroke_u_scale gp_mat_packed_1.y
-#define fill_texture_mix gp_mat_packed_1.z
-#define GP_FLAG(m) floatBitsToInt(MATERIAL(m).gp_mat_packed_1.w)
-
-/* flag */
-#define GP_STROKE_ALIGNMENT_STROKE 1
-#define GP_STROKE_ALIGNMENT_OBJECT 2
-#define GP_STROKE_ALIGNMENT_FIXED 3
-#define GP_STROKE_ALIGNMENT 0x3
-#define GP_STROKE_OVERLAP (1 << 2)
-#define GP_STROKE_TEXTURE_USE (1 << 3)
-#define GP_STROKE_TEXTURE_STENCIL (1 << 4)
-#define GP_STROKE_TEXTURE_PREMUL (1 << 5)
-#define GP_STROKE_DOTS (1 << 6)
-#define GP_STROKE_HOLDOUT (1 << 7)
-#define GP_FILL_HOLDOUT (1 << 8)
-#define GP_FILL_TEXTURE_USE (1 << 10)
-#define GP_FILL_TEXTURE_PREMUL (1 << 11)
-#define GP_FILL_TEXTURE_CLIP (1 << 12)
-#define GP_FILL_GRADIENT_USE (1 << 13)
-#define GP_FILL_GRADIENT_RADIAL (1 << 14)
-/* High bits are used to pass material ID to fragment shader. */
-#define GP_MATID_SHIFT 16
-
-/* Multiline defines can crash blender with certain GPU drivers. */
-/* clang-format off */
-#define GP_FILL_FLAGS (GP_FILL_TEXTURE_USE | GP_FILL_TEXTURE_PREMUL | GP_FILL_TEXTURE_CLIP | GP_FILL_GRADIENT_USE | GP_FILL_GRADIENT_RADIAL | GP_FILL_HOLDOUT)
-/* clang-format on */
-
-#define GP_FLAG_TEST(flag, val) (((flag) & (val)) != 0)
-
-/* Must match C declaration. */
-struct gpLight {
- vec4 color_type;
- vec4 right;
- vec4 up;
- vec4 forward;
- vec4 position;
- /* Please ensure 16 byte alignment (multiple of vec4). */
-};
-
-#define spot_size right.w
-#define spot_blend up.w
-
-#define GP_LIGHT_TYPE_POINT 0.0
-#define GP_LIGHT_TYPE_SPOT 1.0
-#define GP_LIGHT_TYPE_SUN 2.0
-#define GP_LIGHT_TYPE_AMBIENT 3.0
-
-#ifdef GP_MATERIAL_BUFFER_LEN
-
-layout(std140) uniform gpMaterialBlock
-{
- gpMaterial materials[GP_MATERIAL_BUFFER_LEN];
-};
-
-#endif
-
-#ifdef GPENCIL_LIGHT_BUFFER_LEN
-
-layout(std140) uniform gpLightBlock
-{
- gpLight lights[GPENCIL_LIGHT_BUFFER_LEN];
-};
-
-#endif
-
/* Must match eGPLayerBlendModes */
#define MODE_REGULAR 0
#define MODE_HARDLIGHT 1
@@ -101,33 +13,33 @@ void blend_mode_output(
{
switch (blend_mode) {
case MODE_REGULAR:
- /* Reminder: Blending func is premult alpha blend (dst.rgba * (1 - src.a) + src.rgb). */
+ /* Reminder: Blending func is premult alpha blend `(dst.rgba * (1 - src.a) + src.rgb)`. */
color *= opacity;
frag_color = color;
frag_revealage = vec4(0.0, 0.0, 0.0, color.a);
break;
case MODE_MULTIPLY:
- /* Reminder: Blending func is multiply blend (dst.rgba * src.rgba). */
+ /* Reminder: Blending func is multiply blend `(dst.rgba * src.rgba)`. */
color.a *= opacity;
frag_revealage = frag_color = (1.0 - color.a) + color.a * color;
break;
case MODE_DIVIDE:
- /* Reminder: Blending func is multiply blend (dst.rgba * src.rgba). */
+ /* Reminder: Blending func is multiply blend `(dst.rgba * src.rgba)`. */
color.a *= opacity;
frag_revealage = frag_color = clamp(1.0 / max(vec4(1e-6), 1.0 - color * color.a), 0.0, 1e18);
break;
case MODE_HARDLIGHT: {
- /* Reminder: Blending func is multiply blend (dst.rgba * src.rgba). */
+ /* Reminder: Blending func is multiply blend `(dst.rgba * src.rgba)`. */
/**
* We need to separate the overlay equation into 2 term (one mul and one add).
* This is the standard overlay equation (per channel):
- * rtn = (src < 0.5) ? (2.0 * src * dst) : (1.0 - 2.0 * (1.0 - src) * (1.0 - dst));
+ * `rtn = (src < 0.5) ? (2.0 * src * dst) : (1.0 - 2.0 * (1.0 - src) * (1.0 - dst));`
* We rewrite the second branch like this:
- * rtn = 1 - 2 * (1 - src) * (1 - dst);
- * rtn = 1 - 2 (1 - dst + src * dst - src);
- * rtn = 1 - 2 (1 - dst * (1 - src) - src);
- * rtn = 1 - 2 + dst * (2 - 2 * src) + 2 * src;
- * rtn = (- 1 + 2 * src) + dst * (2 - 2 * src);
+ * `rtn = 1 - 2 * (1 - src) * (1 - dst);`
+ * `rtn = 1 - 2 (1 - dst + src * dst - src);`
+ * `rtn = 1 - 2 (1 - dst * (1 - src) - src);`
+ * `rtn = 1 - 2 + dst * (2 - 2 * src) + 2 * src;`
+ * `rtn = (- 1 + 2 * src) + dst * (2 - 2 * src);`
*/
color = mix(vec4(0.5), color, color.a * opacity);
vec4 s = step(-0.5, -color);
@@ -143,516 +55,9 @@ void blend_mode_output(
break;
case MODE_SUB:
case MODE_ADD:
- /* Reminder: Blending func is additive / subtractive blend (dst.rgba +/- src.rgba). */
+ /* Reminder: Blending func is additive / subtractive blend `(dst.rgba +/- src.rgba)`. */
frag_color = color * color.a * opacity;
frag_revealage = vec4(0.0);
break;
}
}
-
-#ifndef USE_GPU_SHADER_CREATE_INFO
-
-IN_OUT ShaderStageInterface
-{
- vec4 finalColorMul;
- vec4 finalColorAdd;
- vec3 finalPos;
- vec2 finalUvs;
- noperspective float strokeThickness;
- noperspective float unclampedThickness;
- noperspective float strokeHardeness;
- flat vec2 strokeAspect;
- flat vec2 strokePt1;
- flat vec2 strokePt2;
- flat int matFlag;
- flat float depth;
-};
-
-#endif
-
-#ifdef GPU_FRAGMENT_SHADER
-
-# define linearstep(p0, p1, v) (clamp(((v) - (p0)) / abs((p1) - (p0)), 0.0, 1.0))
-
-float stroke_round_cap_mask(vec2 p1, vec2 p2, vec2 aspect, float thickness, float hardfac)
-{
- /* We create our own uv space to avoid issues with triangulation and linear
- * interpolation artifacts. */
- vec2 line = p2.xy - p1.xy;
- vec2 pos = gl_FragCoord.xy - p1.xy;
- float line_len = length(line);
- float half_line_len = line_len * 0.5;
- /* Normalize */
- line = (line_len > 0.0) ? (line / line_len) : vec2(1.0, 0.0);
- /* Create a uv space that englobe the whole segment into a capsule. */
- vec2 uv_end;
- uv_end.x = max(abs(dot(line, pos) - half_line_len) - half_line_len, 0.0);
- uv_end.y = dot(vec2(-line.y, line.x), pos);
- /* Divide by stroke radius. */
- uv_end /= thickness;
- uv_end *= aspect;
-
- float dist = clamp(1.0 - length(uv_end) * 2.0, 0.0, 1.0);
- if (hardfac > 0.999) {
- return step(1e-8, dist);
- }
- else {
- /* Modulate the falloff profile */
- float hardness = 1.0 - hardfac;
- dist = pow(dist, mix(0.01, 10.0, hardness));
- return smoothstep(0.0, 1.0, dist);
- }
-}
-
-#endif
-
-uniform vec2 sizeViewport;
-uniform vec2 sizeViewportInv;
-
-/* Per Object */
-uniform bool strokeOrder3d;
-uniform int gpMaterialOffset;
-uniform float thicknessScale;
-uniform float thicknessWorldScale;
-#define thicknessIsScreenSpace (thicknessWorldScale < 0.0)
-
-#ifdef GPU_VERTEX_SHADER
-
-/* Per Layer */
-uniform float thicknessOffset;
-uniform float vertexColorOpacity;
-uniform vec4 layerTint;
-uniform float layerOpacity; /* Used for onion skin. */
-uniform float strokeIndexOffset = 0.0;
-
-/* All of these attributes are quad loaded the same way
- * as GL_LINES_ADJACENCY would feed a geometry shader:
- * - ma reference the previous adjacency point.
- * - ma1 reference the current line first point.
- * - ma2 reference the current line second point.
- * - ma3 reference the next adjacency point.
- * Note that we are rendering quad instances and not using any index buffer (except for fills).
- */
-/* x is material index, y is stroke_id, z is point_id, w is aspect & rotation & hardness packed. */
-in ivec4 ma;
-in ivec4 ma1;
-in ivec4 ma2;
-in ivec4 ma3;
-/* Position contains thickness in 4th component. */
-in vec4 pos; /* Prev adj vert */
-in vec4 pos1; /* Current edge */
-in vec4 pos2; /* Current edge */
-in vec4 pos3; /* Next adj vert */
-/* xy is UV for fills, z is U of stroke, w is strength. */
-in vec4 uv1;
-in vec4 uv2;
-in vec4 col1;
-in vec4 col2;
-in vec4 fcol1;
-/* WARNING: Max attribute count is actually 14 because OSX OpenGL implementation
- * considers gl_VertexID and gl_InstanceID as vertex attribute. (see T74536) */
-# define stroke_id1 ma1.y
-# define point_id1 ma1.z
-# define thickness1 pos1.w
-# define thickness2 pos2.w
-# define strength1 uv1.w
-# define strength2 uv2.w
-/* Packed! need to be decoded. */
-# define hardness1 ma1.w
-# define hardness2 ma2.w
-# define uvrot1 ma1.w
-# define aspect1 ma1.w
-
-vec2 decode_aspect(int packed_data)
-{
- float asp = float(uint(packed_data) & 0x1FFu) * (1.0 / 255.0);
- return (asp > 1.0) ? vec2(1.0, (asp - 1.0)) : vec2(asp, 1.0);
-}
-
-float decode_uvrot(int packed_data)
-{
- uint udata = uint(packed_data);
- float uvrot = 1e-8 + float((udata & 0x1FE00u) >> 9u) * (1.0 / 255.0);
- return ((udata & 0x20000u) != 0u) ? -uvrot : uvrot;
-}
-
-float decode_hardness(int packed_data)
-{
- return float((uint(packed_data) & 0x3FC0000u) >> 18u) * (1.0 / 255.0);
-}
-
-void discard_vert()
-{
- /* We set the vertex at the camera origin to generate 0 fragments. */
- gl_Position = vec4(0.0, 0.0, -3e36, 0.0);
-}
-
-vec2 project_to_screenspace(vec4 v)
-{
- return ((v.xy / v.w) * 0.5 + 0.5) * sizeViewport;
-}
-
-vec2 rotate_90deg(vec2 v)
-{
- /* Counter Clock-Wise. */
- return vec2(-v.y, v.x);
-}
-
-mat4 model_matrix_get()
-{
- return ModelMatrix;
-}
-
-vec3 transform_point(mat4 m, vec3 v)
-{
- return (m * vec4(v, 1.0)).xyz;
-}
-
-vec2 safe_normalize(vec2 v)
-{
- float len_sqr = dot(v, v);
- if (len_sqr > 0.0) {
- return v / sqrt(len_sqr);
- }
- else {
- return vec2(1.0, 0.0);
- }
-}
-
-vec2 safe_normalize_len(vec2 v, out float len)
-{
- len = sqrt(dot(v, v));
- if (len > 0.0) {
- return v / len;
- }
- else {
- return vec2(1.0, 0.0);
- }
-}
-
-float stroke_thickness_modulate(float thickness)
-{
- /* Modify stroke thickness by object and layer factors. */
- thickness *= thicknessScale;
- thickness += thicknessOffset;
- thickness = max(1.0, thickness);
-
- if (thicknessIsScreenSpace) {
- /* Multiply offset by view Z so that offset is constant in screenspace.
- * (e.i: does not change with the distance to camera) */
- thickness *= gl_Position.w;
- }
- else {
- /* World space point size. */
- thickness *= thicknessWorldScale * drw_view.winmat[1][1] * sizeViewport.y;
- }
- return thickness;
-}
-
-float clamp_small_stroke_thickness(float thickness)
-{
- /* To avoid aliasing artifacts, we clamp the line thickness and
- * reduce its opacity in the fragment shader. */
- float min_thickness = gl_Position.w * 1.3;
- thickness = max(min_thickness, thickness);
-
- return thickness;
-}
-
-# ifdef GP_MATERIAL_BUFFER_LEN
-void color_output(vec4 stroke_col, vec4 vert_col, float vert_strength, float mix_tex)
-{
- /* Mix stroke with other colors. */
- vec4 mixed_col = stroke_col;
- mixed_col.rgb = mix(mixed_col.rgb, vert_col.rgb, vert_col.a * vertexColorOpacity);
- mixed_col.rgb = mix(mixed_col.rgb, layerTint.rgb, layerTint.a);
- mixed_col.a *= vert_strength * layerOpacity;
- /**
- * This is what the fragment shader looks like.
- * out = col * finalColorMul + col.a * finalColorAdd.
- * finalColorMul is how much of the texture color to keep.
- * finalColorAdd is how much of the mixed color to add.
- * Note that we never add alpha. This is to keep the texture act as a stencil.
- * We do however, modulate the alpha (reduce it).
- */
- /* We add the mixed color. This is 100% mix (no texture visible). */
- finalColorMul = vec4(mixed_col.aaa, mixed_col.a);
- finalColorAdd = vec4(mixed_col.rgb * mixed_col.a, 0.0);
- /* Then we blend according to the texture mix factor.
- * Note that we keep the alpha modulation. */
- finalColorMul.rgb *= mix_tex;
- finalColorAdd.rgb *= 1.0 - mix_tex;
-}
-# endif
-
-void stroke_vertex()
-{
- int m = ma1.x;
- bool is_dot = false;
- bool is_squares = false;
-
-# ifdef GP_MATERIAL_BUFFER_LEN
- if (m != -1) {
- is_dot = GP_FLAG_TEST(GP_FLAG(m), GP_STROKE_ALIGNMENT);
- is_squares = !GP_FLAG_TEST(GP_FLAG(m), GP_STROKE_DOTS);
- }
-# endif
-
- /* Special Case. Stroke with single vert are rendered as dots. Do not discard them. */
- if (!is_dot && ma.x == -1 && ma2.x == -1) {
- is_dot = true;
- is_squares = false;
- }
-
- /* Endpoints, we discard the vertices. */
- if (ma1.x == -1 || (!is_dot && ma2.x == -1)) {
- discard_vert();
- return;
- }
-
- mat4 model_mat = model_matrix_get();
-
- /* Avoid using a vertex attribute for quad positioning. */
- float x = float(gl_VertexID & 1) * 2.0 - 1.0; /* [-1..1] */
- float y = float(gl_VertexID & 2) - 1.0; /* [-1..1] */
-
- bool use_curr = is_dot || (x == -1.0);
-
- vec3 wpos_adj = transform_point(model_mat, (use_curr) ? pos.xyz : pos3.xyz);
- vec3 wpos1 = transform_point(model_mat, pos1.xyz);
- vec3 wpos2 = transform_point(model_mat, pos2.xyz);
-
- vec4 ndc_adj = point_world_to_ndc(wpos_adj);
- vec4 ndc1 = point_world_to_ndc(wpos1);
- vec4 ndc2 = point_world_to_ndc(wpos2);
-
- gl_Position = (use_curr) ? ndc1 : ndc2;
- finalPos = (use_curr) ? wpos1 : wpos2;
-
- vec2 ss_adj = project_to_screenspace(ndc_adj);
- vec2 ss1 = project_to_screenspace(ndc1);
- vec2 ss2 = project_to_screenspace(ndc2);
- /* Screenspace Lines tangents. */
- float line_len;
- vec2 line = safe_normalize_len(ss2 - ss1, line_len);
- vec2 line_adj = safe_normalize((use_curr) ? (ss1 - ss_adj) : (ss_adj - ss2));
-
- float thickness = abs((use_curr) ? thickness1 : thickness2);
- thickness = stroke_thickness_modulate(thickness);
- float clampedThickness = clamp_small_stroke_thickness(thickness);
-
- finalUvs = vec2(x, y) * 0.5 + 0.5;
- strokeHardeness = decode_hardness(use_curr ? hardness1 : hardness2);
-
- if (is_dot) {
-# ifdef GP_MATERIAL_BUFFER_LEN
- int alignement = GP_FLAG(m) & GP_STROKE_ALIGNMENT;
- /* For one point strokes use object alignment. */
- if (ma.x == -1 && ma2.x == -1 && alignement == GP_STROKE_ALIGNMENT_STROKE) {
- alignement = GP_STROKE_ALIGNMENT_OBJECT;
- }
-# endif
-
- vec2 x_axis;
-# ifdef GP_MATERIAL_BUFFER_LEN
- if (alignement == GP_STROKE_ALIGNMENT_STROKE) {
- x_axis = (ma2.x == -1) ? line_adj : line;
- }
- else if (alignement == GP_STROKE_ALIGNMENT_FIXED) {
- /* Default for no-material drawing. */
- x_axis = vec2(1.0, 0.0);
- }
- else
-# endif
- { /* GP_STROKE_ALIGNMENT_OBJECT */
- vec4 ndc_x = point_world_to_ndc(wpos1 + model_mat[0].xyz);
- vec2 ss_x = project_to_screenspace(ndc_x);
- x_axis = safe_normalize(ss_x - ss1);
- }
-
- /* Rotation: Encoded as Cos + Sin sign. */
- float uv_rot = decode_uvrot(uvrot1);
- float rot_sin = sqrt(max(0.0, 1.0 - uv_rot * uv_rot)) * sign(uv_rot);
- float rot_cos = abs(uv_rot);
- x_axis = mat2(rot_cos, -rot_sin, rot_sin, rot_cos) * x_axis;
-
-# ifdef GP_MATERIAL_BUFFER_LEN
- if (is_dot) {
- float alignment_cos = MATERIAL(m).fill_uv_offset.z;
- float alignment_sin = MATERIAL(m).fill_uv_offset.w;
- x_axis = mat2(alignment_cos, -alignment_sin, alignment_sin, alignment_cos) * x_axis;
- }
-# endif
-
- vec2 y_axis = rotate_90deg(x_axis);
-
- strokeAspect = decode_aspect(aspect1);
-
- x *= strokeAspect.x;
- y *= strokeAspect.y;
-
- /* Invert for vertex shader. */
- strokeAspect = 1.0 / strokeAspect;
-
- gl_Position.xy += (x * x_axis + y * y_axis) * sizeViewportInv.xy * clampedThickness;
-
- strokePt1 = ss1;
- strokePt2 = ss1 + x_axis * 0.5;
- strokeThickness = (is_squares) ? 1e18 : (clampedThickness / gl_Position.w);
- unclampedThickness = (is_squares) ? 1e18 : (thickness / gl_Position.w);
- }
- else {
- bool is_stroke_start = (ma.x == -1 && x == -1);
- bool is_stroke_end = (ma3.x == -1 && x == 1);
-
- /* Mitter tangent vector. */
- vec2 miter_tan = safe_normalize(line_adj + line);
- float miter_dot = dot(miter_tan, line_adj);
- /* Break corners after a certain angle to avoid really thick corners. */
- const float miter_limit = 0.5; /* cos(60°) */
- bool miter_break = (miter_dot < miter_limit);
- miter_tan = (miter_break || is_stroke_start || is_stroke_end) ? line : (miter_tan / miter_dot);
-
- vec2 miter = rotate_90deg(miter_tan);
-
- strokePt1.xy = ss1;
- strokePt2.xy = ss2;
- strokeThickness = clampedThickness / gl_Position.w;
- unclampedThickness = thickness / gl_Position.w;
- strokeAspect = vec2(1.0);
-
- vec2 screen_ofs = miter * y;
-
- /* Reminder: we packed the cap flag into the sign of strength and thickness sign. */
- if ((is_stroke_start && strength1 > 0.0) || (is_stroke_end && thickness1 > 0.0) ||
- (miter_break && !is_stroke_start && !is_stroke_end)) {
- screen_ofs += line * x;
- }
-
- gl_Position.xy += screen_ofs * sizeViewportInv.xy * clampedThickness;
-
- finalUvs.x = (use_curr) ? uv1.z : uv2.z;
-# ifdef GP_MATERIAL_BUFFER_LEN
- finalUvs.x *= MATERIAL(m).stroke_u_scale;
-# endif
- }
-
-# ifdef GP_MATERIAL_BUFFER_LEN
- vec4 vert_col = (use_curr) ? col1 : col2;
- float vert_strength = abs((use_curr) ? strength1 : strength2);
- vec4 stroke_col = MATERIAL(m).stroke_color;
- float mix_tex = MATERIAL(m).stroke_texture_mix;
-
- /* Special case: We don't use vertex color if material Holdout. */
- if (GP_FLAG_TEST(GP_FLAG(m), GP_STROKE_HOLDOUT)) {
- vert_col = vec4(0.0);
- }
-
- color_output(stroke_col, vert_col, vert_strength, mix_tex);
-
- matFlag = GP_FLAG(m) & ~GP_FILL_FLAGS;
-# endif
-
- if (strokeOrder3d) {
- /* Use the fragment depth (see fragment shader). */
- depth = -1.0;
- }
-# ifdef GP_MATERIAL_BUFFER_LEN
- else if (GP_FLAG_TEST(GP_FLAG(m), GP_STROKE_OVERLAP)) {
- /* Use the index of the point as depth.
- * This means the stroke can overlap itself. */
- depth = (point_id1 + strokeIndexOffset + 1.0) * 0.0000002;
- }
-# endif
- else {
- /* Use the index of first point of the stroke as depth.
- * We render using a greater depth test this means the stroke
- * cannot overlap itself.
- * We offset by one so that the fill can be overlapped by its stroke.
- * The offset is ok since we pad the strokes data because of adjacency infos. */
- depth = (stroke_id1 + strokeIndexOffset + 1.0) * 0.0000002;
- }
-}
-
-void fill_vertex()
-{
- mat4 model_mat = model_matrix_get();
-
- vec3 wpos = transform_point(model_mat, pos1.xyz);
- gl_Position = point_world_to_ndc(wpos);
- finalPos = wpos;
-
-# ifdef GP_MATERIAL_BUFFER_LEN
- int m = ma1.x;
-
- vec4 fill_col = MATERIAL(m).fill_color;
- float mix_tex = MATERIAL(m).fill_texture_mix;
-
- /* Special case: We don't modulate alpha in gradient mode. */
- if (GP_FLAG_TEST(GP_FLAG(m), GP_FILL_GRADIENT_USE)) {
- fill_col.a = 1.0;
- }
-
- /* Decode fill opacity. */
- vec4 fcol_decode = vec4(fcol1.rgb, floor(fcol1.a / 10.0));
- float fill_opacity = fcol1.a - (fcol_decode.a * 10);
- fcol_decode.a /= 10000.0;
-
- /* Special case: We don't use vertex color if material Holdout. */
- if (GP_FLAG_TEST(GP_FLAG(m), GP_FILL_HOLDOUT)) {
- fcol_decode = vec4(0.0);
- }
-
- /* Apply opacity. */
- fill_col.a *= fill_opacity;
- /* If factor is > 1 force opacity. */
- if (fill_opacity > 1.0) {
- fill_col.a += fill_opacity - 1.0;
- }
-
- fill_col.a = clamp(fill_col.a, 0.0, 1.0);
-
- color_output(fill_col, fcol_decode, 1.0, mix_tex);
-
- matFlag = GP_FLAG(m) & GP_FILL_FLAGS;
- matFlag |= m << GP_MATID_SHIFT;
-
- vec2 loc = MATERIAL(m).fill_uv_offset.xy;
- mat2x2 rot_scale = mat2x2(MATERIAL(m).fill_uv_rot_scale.xy, MATERIAL(m).fill_uv_rot_scale.zw);
- finalUvs = rot_scale * uv1.xy + loc;
-# endif
-
- strokeHardeness = 1.0;
- strokeThickness = 1e18;
- unclampedThickness = 1e20;
- strokeAspect = vec2(1.0);
- strokePt1 = strokePt2 = vec2(0.0);
-
- if (strokeOrder3d) {
- /* Use the fragment depth (see fragment shader). */
- depth = -1.0;
- /* We still offset the fills a little to avoid overlaps */
- gl_Position.z += 0.000002;
- }
- else {
- /* Use the index of first point of the stroke as depth. */
- depth = (stroke_id1 + strokeIndexOffset) * 0.0000002;
- }
-}
-
-void gpencil_vertex()
-{
- /* Trick to detect if a drawcall is stroke or fill.
- * This does mean that we need to draw an empty stroke segment before starting
- * to draw the real stroke segments. */
- bool is_fill = (gl_InstanceID == 0);
-
- if (!is_fill) {
- stroke_vertex();
- }
- else {
- fill_vertex();
- }
-}
-
-#endif
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_depth_merge_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_depth_merge_vert.glsl
index 2fca8b69183..07e14fd7bef 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_depth_merge_vert.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_depth_merge_vert.glsl
@@ -5,5 +5,5 @@ void main()
int v = gl_VertexID % 3;
float x = -1.0 + float((v & 1) << 2);
float y = -1.0 + float((v & 2) << 1);
- gl_Position = drw_view.persmat * (model_matrix * vec4(x, y, 0.0, 1.0));
+ gl_Position = drw_view.winmat * (drw_view.viewmat * (model_matrix * vec4(x, y, 0.0, 1.0)));
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_vert.glsl
index b0ee059cb9d..2e7544cea29 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_vert.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_vert.glsl
@@ -31,23 +31,11 @@ void main()
vec4 vert_color;
vec3 vert_N;
+ ivec4 ma1 = floatBitsToInt(texelFetch(gp_pos_tx, gpencil_stroke_point_id() * 3 + 1));
gpMaterial gp_mat = materials[ma1.x + gpMaterialOffset];
gpMaterialFlag gp_flag = floatBitsToUint(gp_mat._flag);
- gl_Position = gpencil_vertex(ma,
- ma1,
- ma2,
- ma3,
- pos,
- pos1,
- pos2,
- pos3,
- uv1,
- uv2,
- col1,
- col2,
- fcol1,
- vec4(drw_view.viewport_size, drw_view.viewport_size_inverse),
+ gl_Position = gpencil_vertex(vec4(viewportSize, 1.0 / viewportSize),
gp_flag,
gp_mat._alignment_rot,
gp_interp.pos,
@@ -60,7 +48,7 @@ void main()
gp_interp.thickness,
gp_interp.hardness);
- if (GPENCIL_IS_STROKE_VERTEX) {
+ if (gpencil_is_stroke_vertex()) {
if (!flag_test(gp_flag, GP_STROKE_ALIGNMENT)) {
gp_interp.uv.x *= gp_mat._stroke_u_scale;
}
@@ -83,7 +71,7 @@ void main()
/* Use the index of the point as depth.
* This means the stroke can overlap itself. */
float point_index = float(ma1.z);
- gp_interp.depth = (point_index + gpStrokeIndexOffset + 1.0) * 0.0000002;
+ gp_interp.depth = (point_index + gpStrokeIndexOffset + 2.0) * 0.0000002;
}
else {
/* Use the index of first point of the stroke as depth.
@@ -92,10 +80,13 @@ void main()
* We offset by one so that the fill can be overlapped by its stroke.
* The offset is ok since we pad the strokes data because of adjacency infos. */
float stroke_index = float(ma1.y);
- gp_interp.depth = (stroke_index + gpStrokeIndexOffset + 1.0) * 0.0000002;
+ gp_interp.depth = (stroke_index + gpStrokeIndexOffset + 2.0) * 0.0000002;
}
}
else {
+ int stroke_point_id = gpencil_stroke_point_id();
+ vec4 uv1 = texelFetch(gp_pos_tx, stroke_point_id * 3 + 2);
+ vec4 fcol1 = texelFetch(gp_col_tx, stroke_point_id * 2 + 1);
vec4 fill_col = gp_mat.fill_color;
/* Special case: We don't modulate alpha in gradient mode. */
@@ -137,7 +128,7 @@ void main()
else {
/* Use the index of first point of the stroke as depth. */
float stroke_index = float(ma1.y);
- gp_interp.depth = (stroke_index + gpStrokeIndexOffset) * 0.0000002;
+ gp_interp.depth = (stroke_index + gpStrokeIndexOffset + 1.0) * 0.0000002;
}
}
}
diff --git a/source/blender/draw/engines/gpencil/shaders/infos/gpencil_info.hh b/source/blender/draw/engines/gpencil/shaders/infos/gpencil_info.hh
index 1db98d13c4a..da2776254e6 100644
--- a/source/blender/draw/engines/gpencil/shaders/infos/gpencil_info.hh
+++ b/source/blender/draw/engines/gpencil/shaders/infos/gpencil_info.hh
@@ -22,12 +22,13 @@ GPU_SHADER_CREATE_INFO(gpencil_geometry)
.do_static_compilation(true)
.define("GP_LIGHT")
.typedef_source("gpencil_defines.h")
- .sampler(0, ImageType::FLOAT_2D, "gpFillTexture")
- .sampler(1, ImageType::FLOAT_2D, "gpStrokeTexture")
- .sampler(2, ImageType::DEPTH_2D, "gpSceneDepthTexture")
- .sampler(3, ImageType::FLOAT_2D, "gpMaskTexture")
- .uniform_buf(2, "gpMaterial", "materials[GPENCIL_MATERIAL_BUFFER_LEN]", Frequency::BATCH)
+ .sampler(2, ImageType::FLOAT_2D, "gpFillTexture")
+ .sampler(3, ImageType::FLOAT_2D, "gpStrokeTexture")
+ .sampler(4, ImageType::DEPTH_2D, "gpSceneDepthTexture")
+ .sampler(5, ImageType::FLOAT_2D, "gpMaskTexture")
+ .uniform_buf(4, "gpMaterial", "materials[GPENCIL_MATERIAL_BUFFER_LEN]", Frequency::BATCH)
.uniform_buf(3, "gpLight", "lights[GPENCIL_LIGHT_BUFFER_LEN]", Frequency::BATCH)
+ .push_constant(Type::VEC2, "viewportSize")
/* Per Object */
.push_constant(Type::VEC3, "gpNormal")
.push_constant(Type::BOOL, "gpStrokeOrder3d")
@@ -47,7 +48,7 @@ GPU_SHADER_CREATE_INFO(gpencil_geometry)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Fullscreen shaders
+/** \name Full-Screen Shaders
* \{ */
GPU_SHADER_CREATE_INFO(gpencil_layer_blend)
diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh
index a1cd110e1d8..8913b7469ed 100644
--- a/source/blender/draw/engines/image/image_drawing_mode.hh
+++ b/source/blender/draw/engines/image/image_drawing_mode.hh
@@ -243,8 +243,8 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
do_partial_update_float_buffer(tile_buffer, iterator);
}
- const float tile_width = static_cast<float>(iterator.tile_data.tile_buffer->x);
- const float tile_height = static_cast<float>(iterator.tile_data.tile_buffer->y);
+ const float tile_width = float(iterator.tile_data.tile_buffer->x);
+ const float tile_height = float(iterator.tile_data.tile_buffer->y);
for (int i = 0; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) {
const TextureInfo &info = instance_data.texture_infos[i];
@@ -260,23 +260,20 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
const float texture_height = GPU_texture_height(texture);
/* TODO: early bound check. */
ImageTileWrapper tile_accessor(iterator.tile_data.tile);
- float tile_offset_x = static_cast<float>(tile_accessor.get_tile_x_offset());
- float tile_offset_y = static_cast<float>(tile_accessor.get_tile_y_offset());
+ float tile_offset_x = float(tile_accessor.get_tile_x_offset());
+ float tile_offset_y = float(tile_accessor.get_tile_y_offset());
rcti *changed_region_in_texel_space = &iterator.changed_region.region;
rctf changed_region_in_uv_space;
- BLI_rctf_init(&changed_region_in_uv_space,
- static_cast<float>(changed_region_in_texel_space->xmin) /
- static_cast<float>(iterator.tile_data.tile_buffer->x) +
- tile_offset_x,
- static_cast<float>(changed_region_in_texel_space->xmax) /
- static_cast<float>(iterator.tile_data.tile_buffer->x) +
- tile_offset_x,
- static_cast<float>(changed_region_in_texel_space->ymin) /
- static_cast<float>(iterator.tile_data.tile_buffer->y) +
- tile_offset_y,
- static_cast<float>(changed_region_in_texel_space->ymax) /
- static_cast<float>(iterator.tile_data.tile_buffer->y) +
- tile_offset_y);
+ BLI_rctf_init(
+ &changed_region_in_uv_space,
+ float(changed_region_in_texel_space->xmin) / float(iterator.tile_data.tile_buffer->x) +
+ tile_offset_x,
+ float(changed_region_in_texel_space->xmax) / float(iterator.tile_data.tile_buffer->x) +
+ tile_offset_x,
+ float(changed_region_in_texel_space->ymin) / float(iterator.tile_data.tile_buffer->y) +
+ tile_offset_y,
+ float(changed_region_in_texel_space->ymax) / float(iterator.tile_data.tile_buffer->y) +
+ tile_offset_y);
rctf changed_overlapping_region_in_uv_space;
const bool region_overlap = BLI_rctf_isect(&info.clipping_uv_bounds,
&changed_region_in_uv_space,
@@ -335,6 +332,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
offset++;
}
}
+ IMB_gpu_clamp_half_float(&extracted_buffer);
GPU_texture_update_sub(texture,
GPU_DATA_FLOAT,
@@ -391,6 +389,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
}
BKE_image_release_ibuf(image, tile_buffer, lock);
}
+ IMB_gpu_clamp_half_float(&texture_buffer);
GPU_texture_update(info.texture, GPU_DATA_FLOAT, texture_buffer.rect_float);
imb_freerectImbuf_all(&texture_buffer);
}
@@ -423,8 +422,8 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
* transformation. */
float uv_to_texel[4][4];
copy_m4_m4(uv_to_texel, instance_data.ss_to_texture);
- float scale[3] = {static_cast<float>(texture_width) / static_cast<float>(tile_buffer.x),
- static_cast<float>(texture_height) / static_cast<float>(tile_buffer.y),
+ float scale[3] = {float(texture_width) / float(tile_buffer.x),
+ float(texture_height) / float(tile_buffer.y),
1.0f};
rescale_m4(uv_to_texel, scale);
uv_to_texel[3][0] += image_tile.get_tile_x_offset() /
diff --git a/source/blender/draw/engines/image/image_engine.cc b/source/blender/draw/engines/image/image_engine.cc
index a1a1de328f4..a2aef98a2b6 100644
--- a/source/blender/draw/engines/image/image_engine.cc
+++ b/source/blender/draw/engines/image/image_engine.cc
@@ -150,7 +150,7 @@ static void IMAGE_cache_init(void *vedata)
image_engine.cache_populate();
}
-static void IMAGE_cache_populate(void *UNUSED(vedata), Object *UNUSED(ob))
+static void IMAGE_cache_populate(void * /*vedata*/, Object * /*ob*/)
{
/* Function intentional left empty. `cache_populate` is required to be implemented. */
}
diff --git a/source/blender/draw/engines/image/image_space_image.hh b/source/blender/draw/engines/image/image_space_image.hh
index 40aa117514c..7609cac8194 100644
--- a/source/blender/draw/engines/image/image_space_image.hh
+++ b/source/blender/draw/engines/image/image_space_image.hh
@@ -19,7 +19,7 @@ class SpaceImageAccessor : public AbstractSpaceAccessor {
{
}
- Image *get_image(Main *UNUSED(bmain)) override
+ Image *get_image(Main * /*bmain*/) override
{
return ED_space_image(sima);
}
@@ -29,12 +29,12 @@ class SpaceImageAccessor : public AbstractSpaceAccessor {
return &sima->iuser;
}
- ImBuf *acquire_image_buffer(Image *UNUSED(image), void **lock) override
+ ImBuf *acquire_image_buffer(Image * /*image*/, void **lock) override
{
return ED_space_image_acquire_buffer(sima, lock, 0);
}
- void release_buffer(Image *UNUSED(image), ImBuf *image_buffer, void *lock) override
+ void release_buffer(Image * /*image*/, ImBuf *image_buffer, void *lock) override
{
ED_space_image_release_buffer(sima, image_buffer, lock);
}
diff --git a/source/blender/draw/engines/overlay/overlay_antialiasing.c b/source/blender/draw/engines/overlay/overlay_antialiasing.cc
index 780915b7fc4..2eefdce403c 100644
--- a/source/blender/draw/engines/overlay/overlay_antialiasing.c
+++ b/source/blender/draw/engines/overlay/overlay_antialiasing.cc
@@ -34,8 +34,8 @@
* - Works without geometry shader.
* - Can inflate line thickness.
* - Coverage is very close to perfect and can even be filtered (Blackman-Harris, gaussian).
- * - Wires can "bleed" / overlap non-line objects since the filter is in screenspace.
- * - Only uses one additional lightweight fullscreen buffer (compared to MSAA/SMAA).
+ * - Wires can "bleed" / overlap non-line objects since the filter is in screen-space.
+ * - Only uses one additional lightweight full-screen buffer (compared to MSAA/SMAA).
* - No convergence time (compared to TAA).
*/
@@ -43,7 +43,7 @@
#include "ED_screen.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
{
@@ -53,9 +53,10 @@ void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
/* Small texture which will have very small impact on render-time. */
- if (txl->dummy_depth_tx == NULL) {
+ if (txl->dummy_depth_tx == nullptr) {
const float pixel[1] = {1.0f};
- txl->dummy_depth_tx = DRW_texture_create_2d(1, 1, GPU_DEPTH_COMPONENT24, 0, pixel);
+ txl->dummy_depth_tx = DRW_texture_create_2d(
+ 1, 1, GPU_DEPTH_COMPONENT24, DRWTextureFlag(0), pixel);
}
if (!DRW_state_is_fbo()) {
@@ -67,12 +68,12 @@ void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
pd->antialiasing.enabled = need_wire_expansion ||
((U.gpu_flag & USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE) != 0);
- GPUTexture *color_tex = NULL;
- GPUTexture *line_tex = NULL;
+ GPUTexture *color_tex = nullptr;
+ GPUTexture *line_tex = nullptr;
if (pd->antialiasing.enabled) {
DRW_texture_ensure_fullscreen_2d(&txl->overlay_color_tx, GPU_SRGB8_A8, DRW_TEX_FILTER);
- DRW_texture_ensure_fullscreen_2d(&txl->overlay_line_tx, GPU_RGBA8, 0);
+ DRW_texture_ensure_fullscreen_2d(&txl->overlay_line_tx, GPU_RGBA8, DRWTextureFlag(0));
color_tex = txl->overlay_color_tx;
line_tex = txl->overlay_line_tx;
@@ -106,7 +107,7 @@ void OVERLAY_antialiasing_cache_init(OVERLAY_Data *vedata)
OVERLAY_PrivateData *pd = vedata->stl->pd;
OVERLAY_PassList *psl = vedata->psl;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- struct GPUShader *sh;
+ GPUShader *sh;
DRWShadingGroup *grp;
if (pd->antialiasing.enabled) {
@@ -123,7 +124,7 @@ void OVERLAY_antialiasing_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "depthTex", &dtxl->depth);
DRW_shgroup_uniform_texture_ref(grp, "colorTex", &txl->overlay_color_tx);
DRW_shgroup_uniform_texture_ref(grp, "lineTex", &txl->overlay_line_tx);
- DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+ DRW_shgroup_call_procedural_triangles(grp, nullptr, 1);
}
/* A bit out of place... not related to antialiasing. */
@@ -135,7 +136,7 @@ void OVERLAY_antialiasing_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "depthTex", &dtxl->depth);
DRW_shgroup_uniform_texture_ref(grp, "xrayDepthTex", &txl->temp_depth_tx);
DRW_shgroup_uniform_float_copy(grp, "opacity", 1.0f - pd->xray_opacity);
- DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+ DRW_shgroup_call_procedural_triangles(grp, nullptr, 1);
}
}
@@ -168,16 +169,16 @@ void OVERLAY_antialiasing_cache_finish(OVERLAY_Data *vedata)
GPU_ATTACHMENT_TEXTURE(txl->overlay_line_tx)});
}
- pd->antialiasing.do_depth_copy = !(psl->wireframe_ps == NULL ||
+ pd->antialiasing.do_depth_copy = !(psl->wireframe_ps == nullptr ||
DRW_pass_is_empty(psl->wireframe_ps)) ||
(pd->xray_enabled && pd->xray_opacity > 0.0f);
- pd->antialiasing.do_depth_infront_copy = !(psl->wireframe_xray_ps == NULL ||
+ pd->antialiasing.do_depth_infront_copy = !(psl->wireframe_xray_ps == nullptr ||
DRW_pass_is_empty(psl->wireframe_xray_ps));
const bool do_wireframe = pd->antialiasing.do_depth_copy ||
pd->antialiasing.do_depth_infront_copy;
if (pd->xray_enabled || do_wireframe) {
- DRW_texture_ensure_fullscreen_2d(&txl->temp_depth_tx, GPU_DEPTH24_STENCIL8, 0);
+ DRW_texture_ensure_fullscreen_2d(&txl->temp_depth_tx, GPU_DEPTH24_STENCIL8, DRWTextureFlag(0));
}
}
diff --git a/source/blender/draw/engines/overlay/overlay_armature.c b/source/blender/draw/engines/overlay/overlay_armature.cc
index df5ee6a18c0..8c9587e7a9a 100644
--- a/source/blender/draw/engines/overlay/overlay_armature.c
+++ b/source/blender/draw/engines/overlay/overlay_armature.cc
@@ -5,9 +5,9 @@
* \ingroup draw_engine
*/
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cmath>
+#include <cstdlib>
+#include <cstring>
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
@@ -37,7 +37,7 @@
#include "draw_common.h"
#include "draw_manager_text.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
#include "draw_cache_impl.h"
@@ -46,7 +46,7 @@
#define PT_DEFAULT_RAD 0.05f /* radius of the point batch. */
-typedef struct ArmatureDrawContext {
+struct ArmatureDrawContext {
/* Current armature object */
Object *ob;
/* bArmature *arm; */ /* TODO */
@@ -87,7 +87,7 @@ typedef struct ArmatureDrawContext {
bool show_relations;
const ThemeWireColor *bcolor; /* pchan color */
-} ArmatureDrawContext;
+};
bool OVERLAY_armature_is_pose_mode(Object *ob, const DRWContextState *draw_ctx)
{
@@ -100,7 +100,7 @@ bool OVERLAY_armature_is_pose_mode(Object *ob, const DRWContextState *draw_ctx)
}
/* Armature parent is also handled by pose mode engine. */
- if ((active_ob != NULL) && (draw_ctx->object_mode & OB_MODE_ALL_WEIGHT_PAINT)) {
+ if ((active_ob != nullptr) && (draw_ctx->object_mode & OB_MODE_ALL_WEIGHT_PAINT)) {
if (ob == draw_ctx->object_pose) {
return true;
}
@@ -123,7 +123,7 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
pd->armature.do_pose_xray = (pd->overlay.flag & V3D_OVERLAY_BONE_SELECT) != 0;
pd->armature.do_pose_fade_geom = pd->armature.do_pose_xray &&
((draw_ctx->object_mode & OB_MODE_WEIGHT_PAINT) == 0) &&
- draw_ctx->object_pose != NULL;
+ draw_ctx->object_pose != nullptr;
const float wire_alpha = pd->overlay.bone_wire_alpha;
const bool use_wire_alpha = (wire_alpha < 1.0f);
@@ -135,20 +135,22 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
DRW_PASS_CREATE(psl->armature_bone_select_ps, state | pd->clipping_state);
float alpha = pd->overlay.xray_alpha_bone;
- struct GPUShader *sh = OVERLAY_shader_uniform_color();
+ GPUShader *sh = OVERLAY_shader_uniform_color();
DRWShadingGroup *grp;
pd->armature_bone_select_act_grp = grp = DRW_shgroup_create(sh, psl->armature_bone_select_ps);
- DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){0.0f, 0.0f, 0.0f, alpha});
+ float4 color = {0.0f, 0.0f, 0.0f, alpha};
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", color);
pd->armature_bone_select_grp = grp = DRW_shgroup_create(sh, psl->armature_bone_select_ps);
- DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){0.0f, 0.0f, 0.0f, pow(alpha, 4)});
+ color = {0.0f, 0.0f, 0.0f, powf(alpha, 4)};
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", color);
}
for (int i = 0; i < 2; i++) {
- struct GPUShader *sh;
- struct GPUVertFormat *format;
- DRWShadingGroup *grp = NULL;
+ GPUShader *sh;
+ GPUVertFormat *format;
+ DRWShadingGroup *grp = nullptr;
OVERLAY_InstanceFormats *formats = OVERLAY_shader_instance_formats_get();
OVERLAY_ArmatureCallBuffers *cb = &pd->armature_call_buffers[i];
@@ -157,7 +159,8 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
cb->transp.custom_shapes_ghash = BLI_ghash_ptr_new(__func__);
DRWPass **p_armature_ps = &psl->armature_ps[i];
- DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT : 0;
+ DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT :
+ DRWState(0);
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WRITE_DEPTH;
DRW_PASS_CREATE(*p_armature_ps, state | pd->clipping_state | infront_state);
DRWPass *armature_ps = *p_armature_ps;
@@ -413,7 +416,7 @@ static float encode_2f_to_float(float a, float b)
{
CLAMP(a, 0.0f, 1.0f);
CLAMP(b, 0.0f, 2.0f); /* Can go up to 2. Needed for wire size. */
- return (float)((int)(a * 255) | ((int)(b * 255) << 8));
+ return float(int(a * 255) | (int(b * 255) << 8));
}
void OVERLAY_bone_instance_data_set_color_hint(BoneInstanceData *data, const float hint_color[4])
@@ -438,7 +441,7 @@ static void drw_shgroup_bone_octahedral(ArmatureDrawContext *ctx,
const float outline_color[4])
{
BoneInstanceData inst_data;
- mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, bone_mat);
+ mul_m4_m4m4(inst_data.mat, ctx->ob->object_to_world, bone_mat);
if (ctx->solid) {
OVERLAY_bone_instance_data_set_color(&inst_data, bone_color);
OVERLAY_bone_instance_data_set_color_hint(&inst_data, hint_color);
@@ -458,7 +461,7 @@ static void drw_shgroup_bone_box(ArmatureDrawContext *ctx,
const float outline_color[4])
{
BoneInstanceData inst_data;
- mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, bone_mat);
+ mul_m4_m4m4(inst_data.mat, ctx->ob->object_to_world, bone_mat);
if (ctx->solid) {
OVERLAY_bone_instance_data_set_color(&inst_data, bone_color);
OVERLAY_bone_instance_data_set_color_hint(&inst_data, hint_color);
@@ -476,9 +479,9 @@ static void drw_shgroup_bone_wire(ArmatureDrawContext *ctx,
const float color[4])
{
float head[3], tail[3];
- mul_v3_m4v3(head, ctx->ob->obmat, bone_mat[3]);
+ mul_v3_m4v3(head, ctx->ob->object_to_world, bone_mat[3]);
add_v3_v3v3(tail, bone_mat[3], bone_mat[1]);
- mul_m4_v3(ctx->ob->obmat, tail);
+ mul_m4_v3(ctx->ob->object_to_world, tail);
DRW_buffer_add_entry(ctx->wire, head, color);
DRW_buffer_add_entry(ctx->wire, tail, color);
@@ -493,9 +496,9 @@ static void drw_shgroup_bone_stick(ArmatureDrawContext *ctx,
const float col_tail[4])
{
float head[3], tail[3];
- mul_v3_m4v3(head, ctx->ob->obmat, bone_mat[3]);
+ mul_v3_m4v3(head, ctx->ob->object_to_world, bone_mat[3]);
add_v3_v3v3(tail, bone_mat[3], bone_mat[1]);
- mul_m4_v3(ctx->ob->obmat, tail);
+ mul_m4_v3(ctx->ob->object_to_world, tail);
DRW_buffer_add_entry(ctx->stick, head, tail, col_wire, col_bone, col_head, col_tail);
}
@@ -514,11 +517,11 @@ static void drw_shgroup_bone_envelope_distance(ArmatureDrawContext *ctx,
mul_m4_v4(bone_mat, head_sph);
mul_m4_v4(bone_mat, tail_sph);
mul_m4_v4(bone_mat, xaxis);
- mul_m4_v4(ctx->ob->obmat, head_sph);
- mul_m4_v4(ctx->ob->obmat, tail_sph);
- mul_m4_v4(ctx->ob->obmat, xaxis);
+ mul_m4_v4(ctx->ob->object_to_world, head_sph);
+ mul_m4_v4(ctx->ob->object_to_world, tail_sph);
+ mul_m4_v4(ctx->ob->object_to_world, xaxis);
sub_v3_v3(xaxis, head_sph);
- float obscale = mat4_to_scale(ctx->ob->obmat);
+ float obscale = mat4_to_scale(ctx->ob->object_to_world);
head_sph[3] = *radius_head * obscale;
head_sph[3] += *distance * obscale;
tail_sph[3] = *radius_tail * obscale;
@@ -541,10 +544,10 @@ static void drw_shgroup_bone_envelope(ArmatureDrawContext *ctx,
mul_m4_v4(bone_mat, head_sph);
mul_m4_v4(bone_mat, tail_sph);
mul_m4_v4(bone_mat, xaxis);
- mul_m4_v4(ctx->ob->obmat, head_sph);
- mul_m4_v4(ctx->ob->obmat, tail_sph);
- mul_m4_v4(ctx->ob->obmat, xaxis);
- float obscale = mat4_to_scale(ctx->ob->obmat);
+ mul_m4_v4(ctx->ob->object_to_world, head_sph);
+ mul_m4_v4(ctx->ob->object_to_world, tail_sph);
+ mul_m4_v4(ctx->ob->object_to_world, xaxis);
+ float obscale = mat4_to_scale(ctx->ob->object_to_world);
head_sph[3] = *radius_head * obscale;
tail_sph[3] = *radius_tail * obscale;
@@ -612,15 +615,16 @@ static void drw_shgroup_bone_envelope(ArmatureDrawContext *ctx,
/* Custom (geometry) */
-extern void drw_batch_cache_validate(Object *custom);
-extern void drw_batch_cache_generate_requested_delayed(Object *custom);
+extern "C" void drw_batch_cache_validate(Object *custom);
+extern "C" void drw_batch_cache_generate_requested_delayed(Object *custom);
BLI_INLINE DRWCallBuffer *custom_bone_instance_shgroup(ArmatureDrawContext *ctx,
DRWShadingGroup *grp,
- struct GPUBatch *custom_geom)
+ GPUBatch *custom_geom)
{
- DRWCallBuffer *buf = BLI_ghash_lookup(ctx->custom_shapes_ghash, custom_geom);
- if (buf == NULL) {
+ DRWCallBuffer *buf = static_cast<DRWCallBuffer *>(
+ BLI_ghash_lookup(ctx->custom_shapes_ghash, custom_geom));
+ if (buf == nullptr) {
OVERLAY_InstanceFormats *formats = OVERLAY_shader_instance_formats_get();
buf = DRW_shgroup_call_buffer_instance(grp, formats->instance_bone, custom_geom);
BLI_ghash_insert(ctx->custom_shapes_ghash, custom_geom, buf);
@@ -640,14 +644,14 @@ static void drw_shgroup_bone_custom_solid_mesh(ArmatureDrawContext *ctx,
* to assure batch cache is valid. */
DRW_mesh_batch_cache_validate(custom, mesh);
- struct GPUBatch *surf = DRW_mesh_batch_cache_get_surface(mesh);
- struct GPUBatch *edges = DRW_mesh_batch_cache_get_edge_detection(mesh, NULL);
- struct GPUBatch *ledges = DRW_mesh_batch_cache_get_loose_edges(mesh);
+ GPUBatch *surf = DRW_mesh_batch_cache_get_surface(mesh);
+ GPUBatch *edges = DRW_mesh_batch_cache_get_edge_detection(mesh, nullptr);
+ GPUBatch *ledges = DRW_mesh_batch_cache_get_loose_edges(mesh);
BoneInstanceData inst_data;
DRWCallBuffer *buf;
if (surf || edges || ledges) {
- mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, bone_mat);
+ mul_m4_m4m4(inst_data.mat, ctx->ob->object_to_world, bone_mat);
}
if (surf && ctx->custom_solid) {
@@ -684,11 +688,11 @@ static void drw_shgroup_bone_custom_mesh_wire(ArmatureDrawContext *ctx,
* to assure batch cache is valid. */
DRW_mesh_batch_cache_validate(custom, mesh);
- struct GPUBatch *geom = DRW_mesh_batch_cache_get_all_edges(mesh);
+ GPUBatch *geom = DRW_mesh_batch_cache_get_all_edges(mesh);
if (geom) {
DRWCallBuffer *buf = custom_bone_instance_shgroup(ctx, ctx->custom_wire, geom);
BoneInstanceData inst_data;
- mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, bone_mat);
+ mul_m4_m4m4(inst_data.mat, ctx->ob->object_to_world, bone_mat);
OVERLAY_bone_instance_data_set_color_hint(&inst_data, color);
OVERLAY_bone_instance_data_set_color(&inst_data, color);
DRW_buffer_add_entry_struct(buf, inst_data.mat);
@@ -710,7 +714,7 @@ static void drw_shgroup_custom_bone_curve(ArmatureDrawContext *ctx,
/* This only handles curves without any surface. The other curve types should have been converted
* to meshes and rendered in the mesh drawing function. */
- struct GPUBatch *ledges = NULL;
+ GPUBatch *ledges = nullptr;
if (custom->type == OB_FONT) {
ledges = DRW_cache_text_edge_wire_get(custom);
}
@@ -720,7 +724,7 @@ static void drw_shgroup_custom_bone_curve(ArmatureDrawContext *ctx,
if (ledges) {
BoneInstanceData inst_data;
- mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, bone_mat);
+ mul_m4_m4m4(inst_data.mat, ctx->ob->object_to_world, bone_mat);
DRWCallBuffer *buf = custom_bone_instance_shgroup(ctx, ctx->custom_wire, ledges);
OVERLAY_bone_instance_data_set_color_hint(&inst_data, outline_color);
@@ -744,14 +748,15 @@ static void drw_shgroup_bone_custom_solid(ArmatureDrawContext *ctx,
* other data type, but supporting all evaluated geometry components would require a much
* larger refactor of this area. */
Mesh *mesh = BKE_object_get_evaluated_mesh_no_subsurf(custom);
- if (mesh != NULL) {
+ if (mesh != nullptr) {
drw_shgroup_bone_custom_solid_mesh(
ctx, mesh, bone_mat, bone_color, hint_color, outline_color, custom);
return;
}
if (ELEM(custom->type, OB_CURVES_LEGACY, OB_FONT, OB_SURF)) {
- drw_shgroup_custom_bone_curve(ctx, custom->data, bone_mat, outline_color, custom);
+ drw_shgroup_custom_bone_curve(
+ ctx, static_cast<Curve *>(custom->data), bone_mat, outline_color, custom);
}
}
@@ -762,13 +767,14 @@ static void drw_shgroup_bone_custom_wire(ArmatureDrawContext *ctx,
{
/* See comments in #drw_shgroup_bone_custom_solid. */
Mesh *mesh = BKE_object_get_evaluated_mesh_no_subsurf(custom);
- if (mesh != NULL) {
+ if (mesh != nullptr) {
drw_shgroup_bone_custom_mesh_wire(ctx, mesh, bone_mat, color, custom);
return;
}
if (ELEM(custom->type, OB_CURVES_LEGACY, OB_FONT, OB_SURF)) {
- drw_shgroup_custom_bone_curve(ctx, custom->data, bone_mat, color, custom);
+ drw_shgroup_custom_bone_curve(
+ ctx, static_cast<Curve *>(custom->data), bone_mat, color, custom);
}
}
@@ -779,7 +785,7 @@ static void drw_shgroup_bone_custom_empty(ArmatureDrawContext *ctx,
{
const float final_color[4] = {color[0], color[1], color[2], 1.0f};
float mat[4][4];
- mul_m4_m4m4(mat, ctx->ob->obmat, bone_mat);
+ mul_m4_m4m4(mat, ctx->ob->object_to_world, bone_mat);
switch (custom->empty_drawtype) {
case OB_PLAINAXES:
@@ -805,7 +811,7 @@ static void drw_shgroup_bone_point(ArmatureDrawContext *ctx,
const float outline_color[4])
{
BoneInstanceData inst_data;
- mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, bone_mat);
+ mul_m4_m4m4(inst_data.mat, ctx->ob->object_to_world, bone_mat);
if (ctx->point_solid) {
OVERLAY_bone_instance_data_set_color(&inst_data, bone_color);
OVERLAY_bone_instance_data_set_color_hint(&inst_data, hint_color);
@@ -823,7 +829,7 @@ static void drw_shgroup_bone_axes(ArmatureDrawContext *ctx,
const float color[4])
{
float mat[4][4];
- mul_m4_m4m4(mat, ctx->ob->obmat, bone_mat);
+ mul_m4_m4m4(mat, ctx->ob->object_to_world, bone_mat);
/* Move to bone tail. */
add_v3_v3(mat[3], mat[1]);
OVERLAY_empty_shape(ctx->extras, mat, 0.25f, OB_ARROWS, color);
@@ -836,8 +842,8 @@ static void drw_shgroup_bone_relationship_lines_ex(ArmatureDrawContext *ctx,
const float color[4])
{
float s[3], e[3];
- mul_v3_m4v3(s, ctx->ob->obmat, start);
- mul_v3_m4v3(e, ctx->ob->obmat, end);
+ mul_v3_m4v3(s, ctx->ob->object_to_world, start);
+ mul_v3_m4v3(e, ctx->ob->object_to_world, end);
/* reverse order to have less stipple overlap */
OVERLAY_extra_line_dashed(ctx->extras, s, e, color);
}
@@ -890,14 +896,14 @@ enum {
/* This function sets the color-set for coloring a certain bone */
static void set_pchan_colorset(ArmatureDrawContext *ctx, Object *ob, bPoseChannel *pchan)
{
- bPose *pose = (ob) ? ob->pose : NULL;
- bArmature *arm = (ob) ? ob->data : NULL;
- bActionGroup *grp = NULL;
+ bPose *pose = (ob) ? ob->pose : nullptr;
+ bArmature *arm = (ob) ? static_cast<bArmature *>(ob->data) : nullptr;
+ bActionGroup *grp = nullptr;
short color_index = 0;
/* sanity check */
- if (ELEM(NULL, ob, arm, pose, pchan)) {
- ctx->bcolor = NULL;
+ if (ELEM(nullptr, ob, arm, pose, pchan)) {
+ ctx->bcolor = nullptr;
return;
}
@@ -914,7 +920,7 @@ static void set_pchan_colorset(ArmatureDrawContext *ctx, Object *ob, bPoseChanne
}
}
- /* bcolor is a pointer to the color set to use. If NULL, then the default
+ /* bcolor is a pointer to the color set to use. If nullptr, then the default
* color set (based on the theme colors for 3d-view) is used.
*/
if (color_index > 0) {
@@ -922,11 +928,11 @@ static void set_pchan_colorset(ArmatureDrawContext *ctx, Object *ob, bPoseChanne
ctx->bcolor = &btheme->tarm[(color_index - 1)];
}
else if (color_index == -1) {
- /* use the group's own custom color set (grp is always != NULL here) */
+ /* use the group's own custom color set (grp is always != nullptr here) */
ctx->bcolor = &grp->cs;
}
else {
- ctx->bcolor = NULL;
+ ctx->bcolor = nullptr;
}
}
@@ -935,11 +941,11 @@ static void cp_shade_color3ub(uchar cp[3], const int offset)
{
int r, g, b;
- r = offset + (int)cp[0];
+ r = offset + int(cp[0]);
CLAMP(r, 0, 255);
- g = offset + (int)cp[1];
+ g = offset + int(cp[1]);
CLAMP(g, 0, 255);
- b = offset + (int)cp[2];
+ b = offset + int(cp[2]);
CLAMP(b, 0, 255);
cp[0] = r;
@@ -1008,7 +1014,7 @@ static bool set_pchan_color(const ArmatureDrawContext *ctx,
return true;
}
case PCHAN_COLOR_CONSTS: {
- if ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) {
+ if ((bcolor == nullptr) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) {
if (constflag & PCHAN_HAS_TARGET) {
copy_v4_v4(fcolor, G_draw.block.color_bone_pose_target);
}
@@ -1047,7 +1053,7 @@ static void bone_locked_color_shade(float color[4])
}
static const float *get_bone_solid_color(const ArmatureDrawContext *ctx,
- const EditBone *UNUSED(eBone),
+ const EditBone * /*eBone*/,
const bPoseChannel *pchan,
const bArmature *arm,
const int boneflag,
@@ -1192,15 +1198,15 @@ static const float *get_bone_hint_color(const ArmatureDrawContext *ctx,
static void pchan_draw_data_init(bPoseChannel *pchan)
{
- if (pchan->draw_data != NULL) {
+ if (pchan->draw_data != nullptr) {
if (pchan->draw_data->bbone_matrix_len != pchan->bone->segments) {
MEM_SAFE_FREE(pchan->draw_data);
}
}
- if (pchan->draw_data == NULL) {
- pchan->draw_data = MEM_mallocN(
- sizeof(*pchan->draw_data) + sizeof(Mat4) * pchan->bone->segments, __func__);
+ if (pchan->draw_data == nullptr) {
+ pchan->draw_data = static_cast<bPoseChannelDrawData *>(
+ MEM_mallocN(sizeof(*pchan->draw_data) + sizeof(Mat4) * pchan->bone->segments, __func__));
pchan->draw_data->bbone_matrix_len = pchan->bone->segments;
}
}
@@ -1243,11 +1249,11 @@ static void edbo_compute_bbone_child(bArmature *arm)
{
EditBone *eBone;
- for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
- eBone->bbone_child = NULL;
+ for (eBone = static_cast<EditBone *>(arm->edbo->first); eBone; eBone = eBone->next) {
+ eBone->bbone_child = nullptr;
}
- for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
+ for (eBone = static_cast<EditBone *>(arm->edbo->first); eBone; eBone = eBone->next) {
if (eBone->parent && (eBone->flag & BONE_CONNECTED)) {
eBone->parent->bbone_child = eBone;
}
@@ -1274,7 +1280,7 @@ static void ebone_spline_preview(EditBone *ebone, const float result_array[MAX_B
prev = ebone->parent;
}
else {
- prev = NULL;
+ prev = nullptr;
}
}
else {
@@ -1398,7 +1404,8 @@ static void draw_bone_update_disp_matrix_bbone(EditBone *eBone, bPoseChannel *pc
bbone_segments = eBone->segments;
}
- size_to_mat4(s, (const float[3]){xwidth, length / bbone_segments, zwidth});
+ const float3 size_vec = {xwidth, length / bbone_segments, zwidth};
+ size_to_mat4(s, size_vec);
/* Compute BBones segment matrices... */
/* Note that we need this even for one-segment bones, because box drawing need specific weirdo
@@ -1471,8 +1478,8 @@ static void draw_axes(ArmatureDrawContext *ctx,
{
float final_col[4];
const float *col = (ctx->const_color) ? ctx->const_color :
- (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? G_draw.block.color_text_hi :
- G_draw.block.color_text;
+ (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? &G_draw.block.color_text_hi.x :
+ &G_draw.block.color_text.x;
copy_v4_v4(final_col, col);
/* Mix with axes color. */
final_col[3] = (ctx->const_color) ? 1.0 : (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? 0.1 : 0.65;
@@ -1483,7 +1490,8 @@ static void draw_axes(ArmatureDrawContext *ctx,
float axis_mat[4][4];
float length = pchan->bone->length;
copy_m4_m4(axis_mat, pchan->custom_tx ? pchan->custom_tx->pose_mat : pchan->pose_mat);
- rescale_m4(axis_mat, (float[3]){length, length, length});
+ const float3 length_vec = {length, length, length};
+ rescale_m4(axis_mat, length_vec);
translate_m4(axis_mat, 0.0, arm->axes_position - 1.0, 0.0);
drw_shgroup_bone_axes(ctx, axis_mat, final_col);
@@ -1509,8 +1517,8 @@ static void draw_points(ArmatureDrawContext *ctx,
copy_v4_v4(col_solid_root, G_draw.block.color_bone_solid);
copy_v4_v4(col_solid_tail, G_draw.block.color_bone_solid);
- copy_v4_v4(col_wire_root, (ctx->const_color) ? ctx->const_color : G_draw.block.color_vertex);
- copy_v4_v4(col_wire_tail, (ctx->const_color) ? ctx->const_color : G_draw.block.color_vertex);
+ copy_v4_v4(col_wire_root, (ctx->const_color) ? ctx->const_color : &G_draw.block.color_vertex.x);
+ copy_v4_v4(col_wire_tail, (ctx->const_color) ? ctx->const_color : &G_draw.block.color_vertex.x);
const bool is_envelope_draw = (arm->drawtype == ARM_ENVELOPE);
const float envelope_ignore = -1.0f;
@@ -1704,7 +1712,7 @@ static void draw_bone_line(ArmatureDrawContext *ctx,
const float *col_head = no_display;
const float *col_tail = col_bone;
- if (ctx->const_color != NULL) {
+ if (ctx->const_color != nullptr) {
col_wire = no_display; /* actually shrink the display. */
col_bone = col_head = col_tail = ctx->const_color;
}
@@ -1724,7 +1732,7 @@ static void draw_bone_line(ArmatureDrawContext *ctx,
(pchan->bone->parent && (boneflag & BONE_CONNECTED)))) {
if (eBone) {
- col_head = (eBone->flag & BONE_ROOTSEL) ? G_draw.block.color_vertex_select : col_bone;
+ col_head = (eBone->flag & BONE_ROOTSEL) ? &G_draw.block.color_vertex_select.x : col_bone;
}
else {
col_head = col_bone;
@@ -1773,7 +1781,7 @@ static void draw_bone_wire(ArmatureDrawContext *ctx,
if (pchan) {
Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix;
- BLI_assert(bbones_mat != NULL);
+ BLI_assert(bbones_mat != nullptr);
for (int i = pchan->bone->segments; i--; bbones_mat++) {
drw_shgroup_bone_wire(ctx, bbones_mat->mat, col_wire);
@@ -1813,7 +1821,7 @@ static void draw_bone_box(ArmatureDrawContext *ctx,
if (pchan) {
Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix;
- BLI_assert(bbones_mat != NULL);
+ BLI_assert(bbones_mat != nullptr);
for (int i = pchan->bone->segments; i--; bbones_mat++) {
drw_shgroup_bone_box(ctx, bbones_mat->mat, col_solid, col_hint, col_wire);
@@ -1874,7 +1882,7 @@ static void draw_bone_degrees_of_freedom(ArmatureDrawContext *ctx, bPoseChannel
float xminmax[2], zminmax[2];
float color[4];
- if (ctx->dof_sphere == NULL) {
+ if (ctx->dof_sphere == nullptr) {
return;
}
@@ -1901,7 +1909,7 @@ static void draw_bone_degrees_of_freedom(ArmatureDrawContext *ctx, bPoseChannel
mul_m4_m4m4(posetrans, posetrans, tmp);
/* into world space. */
- mul_m4_m4m4(inst_data.mat, ctx->ob->obmat, posetrans);
+ mul_m4_m4m4(inst_data.mat, ctx->ob->object_to_world, posetrans);
if ((pchan->ikflag & BONE_IK_XLIMIT) && (pchan->ikflag & BONE_IK_ZLIMIT)) {
bone_instance_data_set_angle_minmax(
@@ -1938,9 +1946,9 @@ static void pchan_draw_ik_lines(ArmatureDrawContext *ctx,
{
bConstraint *con;
bPoseChannel *parchan;
- float *line_start = NULL, *line_end = NULL;
+ float *line_start = nullptr, *line_end = nullptr;
- for (con = pchan->constraints.first; con; con = con->next) {
+ for (con = static_cast<bConstraint *>(pchan->constraints.first); con; con = con->next) {
if (con->enforce == 0.0f) {
continue;
}
@@ -2058,7 +2066,7 @@ static void draw_bone_name(ArmatureDrawContext *ctx,
bArmature *arm,
const int boneflag)
{
- struct DRWTextStore *dt = DRW_text_cache_ensure();
+ DRWTextStore *dt = DRW_text_cache_ensure();
uchar color[4];
float vec[3];
@@ -2071,7 +2079,7 @@ static void draw_bone_name(ArmatureDrawContext *ctx,
float *head = pchan ? pchan->pose_head : eBone->head;
float *tail = pchan ? pchan->pose_tail : eBone->tail;
mid_v3_v3v3(vec, head, tail);
- mul_m4_v3(ctx->ob->obmat, vec);
+ mul_m4_v3(ctx->ob->object_to_world, vec);
DRW_text_cache_add(dt,
vec,
@@ -2163,13 +2171,14 @@ static bool pchan_culling_test_envelope(const DRWView *view,
const Object *ob,
const bPoseChannel *pchan)
{
- const bArmature *arm = ob->data;
+ const bArmature *arm = static_cast<bArmature *>(ob->data);
BLI_assert(arm->drawtype == ARM_ENVELOPE);
UNUSED_VARS_NDEBUG(arm);
BoundSphere bsphere;
pchan_culling_calc_bsphere(ob, pchan, &bsphere);
bsphere.radius += max_ff(pchan->bone->rad_head, pchan->bone->rad_tail) *
- mat4_to_size_max_axis(ob->obmat) * mat4_to_size_max_axis(pchan->disp_mat);
+ mat4_to_size_max_axis(ob->object_to_world) *
+ mat4_to_size_max_axis(pchan->disp_mat);
return DRW_culling_sphere_test(view, &bsphere);
}
@@ -2177,16 +2186,16 @@ static bool pchan_culling_test_bbone(const DRWView *view,
const Object *ob,
const bPoseChannel *pchan)
{
- const bArmature *arm = ob->data;
+ const bArmature *arm = static_cast<bArmature *>(ob->data);
BLI_assert(arm->drawtype == ARM_B_BONE);
UNUSED_VARS_NDEBUG(arm);
- const float ob_scale = mat4_to_size_max_axis(ob->obmat);
+ const float ob_scale = mat4_to_size_max_axis(ob->object_to_world);
const Mat4 *bbones_mat = (const Mat4 *)pchan->draw_data->bbone_matrix;
for (int i = pchan->bone->segments; i--; bbones_mat++) {
BoundSphere bsphere;
float size[3];
mat4_to_size(size, bbones_mat->mat);
- mul_v3_m4v3(bsphere.center, ob->obmat, bbones_mat->mat[3]);
+ mul_v3_m4v3(bsphere.center, ob->object_to_world, bbones_mat->mat[3]);
bsphere.radius = len_v3(size) * ob_scale;
if (DRW_culling_sphere_test(view, &bsphere)) {
return true;
@@ -2224,15 +2233,16 @@ static void draw_armature_edit(ArmatureDrawContext *ctx)
* however the active bone isn't updated. Long term solution is an 'EditArmature' struct.
* for now we can draw from the original armature. See: T66773. */
// bArmature *arm = ob->data;
- bArmature *arm = ob_orig->data;
+ bArmature *arm = static_cast<bArmature *>(ob_orig->data);
edbo_compute_bbone_child(arm);
- for (eBone = arm->edbo->first, index = ob_orig->runtime.select_id; eBone;
+ for (eBone = static_cast<EditBone *>(arm->edbo->first), index = ob_orig->runtime.select_id;
+ eBone;
eBone = eBone->next, index += 0x10000) {
if (eBone->layer & arm->layer) {
if ((eBone->flag & BONE_HIDDEN_A) == 0) {
- const int select_id = is_select ? index : (uint)-1;
+ const int select_id = is_select ? index : uint(-1);
const short constflag = 0;
/* catch exception for bone with hidden parent */
@@ -2249,37 +2259,37 @@ static void draw_armature_edit(ArmatureDrawContext *ctx)
boneflag &= ~BONE_DRAW_LOCKED_WEIGHT;
if (!is_select) {
- draw_bone_relations(ctx, eBone, NULL, arm, boneflag, constflag);
+ draw_bone_relations(ctx, eBone, nullptr, arm, boneflag, constflag);
}
if (arm->drawtype == ARM_ENVELOPE) {
- draw_bone_update_disp_matrix_default(eBone, NULL);
- draw_bone_envelope(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
+ draw_bone_update_disp_matrix_default(eBone, nullptr);
+ draw_bone_envelope(ctx, eBone, nullptr, arm, boneflag, constflag, select_id);
}
else if (arm->drawtype == ARM_LINE) {
- draw_bone_update_disp_matrix_default(eBone, NULL);
- draw_bone_line(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
+ draw_bone_update_disp_matrix_default(eBone, nullptr);
+ draw_bone_line(ctx, eBone, nullptr, arm, boneflag, constflag, select_id);
}
else if (arm->drawtype == ARM_WIRE) {
- draw_bone_update_disp_matrix_bbone(eBone, NULL);
- draw_bone_wire(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
+ draw_bone_update_disp_matrix_bbone(eBone, nullptr);
+ draw_bone_wire(ctx, eBone, nullptr, arm, boneflag, constflag, select_id);
}
else if (arm->drawtype == ARM_B_BONE) {
- draw_bone_update_disp_matrix_bbone(eBone, NULL);
- draw_bone_box(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
+ draw_bone_update_disp_matrix_bbone(eBone, nullptr);
+ draw_bone_box(ctx, eBone, nullptr, arm, boneflag, constflag, select_id);
}
else {
- draw_bone_update_disp_matrix_default(eBone, NULL);
- draw_bone_octahedral(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
+ draw_bone_update_disp_matrix_default(eBone, nullptr);
+ draw_bone_octahedral(ctx, eBone, nullptr, arm, boneflag, constflag, select_id);
}
if (!is_select) {
if (show_text && (arm->flag & ARM_DRAWNAMES)) {
- draw_bone_name(ctx, eBone, NULL, arm, boneflag);
+ draw_bone_name(ctx, eBone, nullptr, arm, boneflag);
}
if (arm->flag & ARM_DRAWAXES) {
- draw_axes(ctx, eBone, NULL, arm);
+ draw_axes(ctx, eBone, nullptr, arm);
}
}
}
@@ -2292,13 +2302,13 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
Object *ob = ctx->ob;
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene = draw_ctx->scene;
- bArmature *arm = ob->data;
+ bArmature *arm = static_cast<bArmature *>(ob->data);
bPoseChannel *pchan;
int index = -1;
const bool show_text = DRW_state_show_text();
bool draw_locked_weights = false;
- /* We can't safely draw non-updated pose, might contain NULL bone pointers... */
+ /* We can't safely draw non-updated pose, might contain nullptr bone pointers... */
if (ob->pose->flag & POSE_RECALC) {
return;
}
@@ -2323,7 +2333,7 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
/* Allow selection when in weight-paint mode
* (selection code ensures this won't become active). */
((draw_ctx->object_mode & OB_MODE_ALL_WEIGHT_PAINT) &&
- (draw_ctx->object_pose != NULL))))) &&
+ (draw_ctx->object_pose != nullptr))))) &&
DRW_state_is_select();
if (is_pose_select) {
@@ -2334,10 +2344,11 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
/* In weight paint mode retrieve the vertex group lock status. */
if ((draw_ctx->object_mode & OB_MODE_ALL_WEIGHT_PAINT) && (draw_ctx->object_pose == ob) &&
- (draw_ctx->obact != NULL)) {
+ (draw_ctx->obact != nullptr)) {
draw_locked_weights = true;
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ for (pchan = static_cast<bPoseChannel *>(ob->pose->chanbase.first); pchan;
+ pchan = pchan->next) {
pchan->bone->flag &= ~BONE_DRAW_LOCKED_WEIGHT;
}
@@ -2355,9 +2366,10 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
}
}
- const DRWView *view = is_pose_select ? DRW_view_default_get() : NULL;
+ const DRWView *view = is_pose_select ? DRW_view_default_get() : nullptr;
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next, index += 0x10000) {
+ for (pchan = static_cast<bPoseChannel *>(ob->pose->chanbase.first); pchan;
+ pchan = pchan->next, index += 0x10000) {
Bone *bone = pchan->bone;
const bool bone_visible = (bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0;
@@ -2367,7 +2379,7 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
(arm->flag & ARM_POSEMODE) && (bone->flag & BONE_SELECTED) &&
((ob->base_flag & BASE_FROM_DUPLI) == 0) &&
(pchan->ikflag & (BONE_IK_XLIMIT | BONE_IK_ZLIMIT));
- const int select_id = is_pose_select ? index : (uint)-1;
+ const int select_id = is_pose_select ? index : uint(-1);
const short constflag = pchan->constflag;
pchan_draw_data_init(pchan);
@@ -2392,43 +2404,43 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
}
if (!is_pose_select) {
- draw_bone_relations(ctx, NULL, pchan, arm, boneflag, constflag);
+ draw_bone_relations(ctx, nullptr, pchan, arm, boneflag, constflag);
}
if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) {
draw_bone_update_disp_matrix_custom(pchan);
if (!is_pose_select || pchan_culling_test_custom(view, ob, pchan)) {
- draw_bone_custom_shape(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
+ draw_bone_custom_shape(ctx, nullptr, pchan, arm, boneflag, constflag, select_id);
}
}
else if (arm->drawtype == ARM_ENVELOPE) {
- draw_bone_update_disp_matrix_default(NULL, pchan);
+ draw_bone_update_disp_matrix_default(nullptr, pchan);
if (!is_pose_select || pchan_culling_test_envelope(view, ob, pchan)) {
- draw_bone_envelope(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
+ draw_bone_envelope(ctx, nullptr, pchan, arm, boneflag, constflag, select_id);
}
}
else if (arm->drawtype == ARM_LINE) {
- draw_bone_update_disp_matrix_default(NULL, pchan);
+ draw_bone_update_disp_matrix_default(nullptr, pchan);
if (!is_pose_select || pchan_culling_test_line(view, ob, pchan)) {
- draw_bone_line(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
+ draw_bone_line(ctx, nullptr, pchan, arm, boneflag, constflag, select_id);
}
}
else if (arm->drawtype == ARM_WIRE) {
- draw_bone_update_disp_matrix_bbone(NULL, pchan);
+ draw_bone_update_disp_matrix_bbone(nullptr, pchan);
if (!is_pose_select || pchan_culling_test_wire(view, ob, pchan)) {
- draw_bone_wire(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
+ draw_bone_wire(ctx, nullptr, pchan, arm, boneflag, constflag, select_id);
}
}
else if (arm->drawtype == ARM_B_BONE) {
- draw_bone_update_disp_matrix_bbone(NULL, pchan);
+ draw_bone_update_disp_matrix_bbone(nullptr, pchan);
if (!is_pose_select || pchan_culling_test_bbone(view, ob, pchan)) {
- draw_bone_box(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
+ draw_bone_box(ctx, nullptr, pchan, arm, boneflag, constflag, select_id);
}
}
else {
- draw_bone_update_disp_matrix_default(NULL, pchan);
+ draw_bone_update_disp_matrix_default(nullptr, pchan);
if (!is_pose_select || pchan_culling_test_octohedral(view, ob, pchan)) {
- draw_bone_octahedral(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
+ draw_bone_octahedral(ctx, nullptr, pchan, arm, boneflag, constflag, select_id);
}
}
@@ -2439,11 +2451,11 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
}
if (show_text && (arm->flag & ARM_DRAWNAMES)) {
- draw_bone_name(ctx, NULL, pchan, arm, boneflag);
+ draw_bone_name(ctx, nullptr, pchan, arm, boneflag);
}
if (arm->flag & ARM_DRAWAXES) {
- draw_axes(ctx, NULL, pchan, arm);
+ draw_axes(ctx, nullptr, pchan, arm);
}
}
}
@@ -2467,7 +2479,7 @@ static void armature_context_setup(ArmatureDrawContext *ctx,
const bool draw_as_wire = (ob->dt < OB_SOLID);
const bool is_filled = (!pd->armature.transparent && !draw_as_wire) || !is_object_mode;
const bool is_transparent = pd->armature.transparent || (draw_as_wire && !is_object_mode);
- bArmature *arm = ob->data;
+ bArmature *arm = static_cast<bArmature *>(ob->data);
OVERLAY_ArmatureCallBuffers *cbo = &pd->armature_call_buffers[is_xray];
OVERLAY_ArmatureCallBuffersInner *cb = is_transparent ? &cbo->transp : &cbo->solid;
@@ -2476,8 +2488,8 @@ static void armature_context_setup(ArmatureDrawContext *ctx,
switch (arm->drawtype) {
case ARM_ENVELOPE:
ctx->envelope_outline = cb->envelope_outline;
- ctx->envelope_solid = (is_filled) ? cb->envelope_fill : NULL;
- ctx->envelope_distance = (do_envelope_dist) ? cb->envelope_distance : NULL;
+ ctx->envelope_solid = (is_filled) ? cb->envelope_fill : nullptr;
+ ctx->envelope_distance = (do_envelope_dist) ? cb->envelope_distance : nullptr;
break;
case ARM_LINE:
ctx->stick = cb->stick;
@@ -2487,20 +2499,20 @@ static void armature_context_setup(ArmatureDrawContext *ctx,
break;
case ARM_B_BONE:
ctx->outline = cb->box_outline;
- ctx->solid = (is_filled) ? cb->box_fill : NULL;
+ ctx->solid = (is_filled) ? cb->box_fill : nullptr;
break;
case ARM_OCTA:
ctx->outline = cb->octa_outline;
- ctx->solid = (is_filled) ? cb->octa_fill : NULL;
+ ctx->solid = (is_filled) ? cb->octa_fill : nullptr;
break;
}
ctx->ob = ob;
ctx->extras = &pd->extra_call_buffers[is_xray];
ctx->dof_lines = cb->dof_lines;
ctx->dof_sphere = cb->dof_sphere;
- ctx->point_solid = (is_filled) ? cb->point_fill : NULL;
+ ctx->point_solid = (is_filled) ? cb->point_fill : nullptr;
ctx->point_outline = cb->point_outline;
- ctx->custom_solid = (is_filled) ? cb->custom_fill : NULL;
+ ctx->custom_solid = (is_filled) ? cb->custom_fill : nullptr;
ctx->custom_outline = cb->custom_outline;
ctx->custom_wire = cb->custom_wire;
ctx->custom_shapes_ghash = cb->custom_shapes_ghash;
@@ -2518,7 +2530,7 @@ void OVERLAY_edit_armature_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
ArmatureDrawContext arm_ctx;
- armature_context_setup(&arm_ctx, pd, ob, true, true, false, NULL);
+ armature_context_setup(&arm_ctx, pd, ob, true, true, false, nullptr);
draw_armature_edit(&arm_ctx);
}
@@ -2526,7 +2538,7 @@ void OVERLAY_pose_armature_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
ArmatureDrawContext arm_ctx;
- armature_context_setup(&arm_ctx, pd, ob, true, false, true, NULL);
+ armature_context_setup(&arm_ctx, pd, ob, true, false, true, nullptr);
draw_armature_pose(&arm_ctx);
}
@@ -2568,7 +2580,7 @@ void OVERLAY_pose_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
- struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
+ GPUBatch *geom = DRW_cache_object_surface_get(ob);
if (geom) {
if (POSE_is_driven_by_active_armature(ob)) {
DRW_shgroup_call(pd->armature_bone_select_act_grp, geom, ob);
@@ -2586,8 +2598,8 @@ void OVERLAY_armature_cache_finish(OVERLAY_Data *vedata)
for (int i = 0; i < 2; i++) {
if (pd->armature_call_buffers[i].solid.custom_shapes_ghash) {
/* TODO(fclem): Do not free it for each frame but reuse it. Avoiding alloc cost. */
- BLI_ghash_free(pd->armature_call_buffers[i].solid.custom_shapes_ghash, NULL, NULL);
- BLI_ghash_free(pd->armature_call_buffers[i].transp.custom_shapes_ghash, NULL, NULL);
+ BLI_ghash_free(pd->armature_call_buffers[i].solid.custom_shapes_ghash, nullptr, nullptr);
+ BLI_ghash_free(pd->armature_call_buffers[i].transp.custom_shapes_ghash, nullptr, nullptr);
}
}
}
@@ -2604,7 +2616,7 @@ void OVERLAY_armature_in_front_draw(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
- if (psl->armature_bone_select_ps == NULL || DRW_state_is_select()) {
+ if (psl->armature_bone_select_ps == nullptr || DRW_state_is_select()) {
DRW_draw_pass(psl->armature_transp_ps[1]);
DRW_draw_pass(psl->armature_ps[1]);
}
@@ -2615,7 +2627,7 @@ void OVERLAY_pose_draw(OVERLAY_Data *vedata)
OVERLAY_PassList *psl = vedata->psl;
OVERLAY_FramebufferList *fbl = vedata->fbl;
- if (psl->armature_bone_select_ps != NULL) {
+ if (psl->armature_bone_select_ps != nullptr) {
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_default_fb);
}
diff --git a/source/blender/draw/engines/overlay/overlay_background.c b/source/blender/draw/engines/overlay/overlay_background.cc
index 32bcd04e05b..2442efc033e 100644
--- a/source/blender/draw/engines/overlay/overlay_background.c
+++ b/source/blender/draw/engines/overlay/overlay_background.cc
@@ -10,7 +10,7 @@
#include "UI_resources.h"
#include "draw_manager_text.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_background_cache_init(OVERLAY_Data *vedata)
{
@@ -20,7 +20,7 @@ void OVERLAY_background_cache_init(OVERLAY_Data *vedata)
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene = draw_ctx->scene;
const RegionView3D *rv3d = draw_ctx->rv3d;
- const BoundBox *bb = rv3d ? rv3d->clipbb : NULL;
+ const BoundBox *bb = rv3d ? rv3d->clipbb : nullptr;
const View3D *v3d = draw_ctx->v3d;
bool draw_clipping_bounds = (pd->clipping_state != 0);
@@ -80,7 +80,7 @@ void OVERLAY_background_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_vec4_copy(grp, "colorOverride", color_override);
DRW_shgroup_uniform_int_copy(grp, "bgType", background_type);
- DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+ DRW_shgroup_call_procedural_triangles(grp, nullptr, 1);
}
if (draw_clipping_bounds) {
@@ -89,14 +89,14 @@ void OVERLAY_background_cache_init(OVERLAY_Data *vedata)
GPUShader *sh = OVERLAY_shader_clipbound();
DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->clipping_frustum_ps);
- DRW_shgroup_uniform_vec4_copy(grp, "color", G_draw.block.color_clipping_border);
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", G_draw.block.color_clipping_border);
DRW_shgroup_uniform_vec3(grp, "boundbox", &bb->vec[0][0], 8);
struct GPUBatch *cube = DRW_cache_cube_get();
- DRW_shgroup_call(grp, cube, NULL);
+ DRW_shgroup_call(grp, cube, nullptr);
}
else {
- psl->clipping_frustum_ps = NULL;
+ psl->clipping_frustum_ps = nullptr;
}
}
diff --git a/source/blender/draw/engines/overlay/overlay_edit_curve.c b/source/blender/draw/engines/overlay/overlay_edit_curve.cc
index 09e3c3410c3..b84eb9b3a43 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_curve.c
+++ b/source/blender/draw/engines/overlay/overlay_edit_curve.cc
@@ -9,7 +9,7 @@
#include "DNA_curve_types.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_edit_curve_cache_init(OVERLAY_Data *vedata)
{
@@ -65,7 +65,7 @@ void OVERLAY_edit_curve_cache_populate(OVERLAY_Data *vedata, Object *ob)
bool draw_normals = (pd->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_NORMALS) != 0;
bool do_xray = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
- Curve *cu = ob->data;
+ Curve *cu = static_cast<Curve *>(ob->data);
struct GPUBatch *geom;
geom = DRW_cache_curve_edge_wire_get(ob);
diff --git a/source/blender/draw/engines/overlay/overlay_edit_curves.cc b/source/blender/draw/engines/overlay/overlay_edit_curves.cc
index 02e40ea0304..dab44c655a5 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_curves.cc
+++ b/source/blender/draw/engines/overlay/overlay_edit_curves.cc
@@ -11,7 +11,7 @@
#include "draw_cache_impl.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_edit_curves_init(OVERLAY_Data *vedata)
{
diff --git a/source/blender/draw/engines/overlay/overlay_edit_mesh.c b/source/blender/draw/engines/overlay/overlay_edit_mesh.cc
index 4d65cbc04ff..4509fd53ed8 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_mesh.c
+++ b/source/blender/draw/engines/overlay/overlay_edit_mesh.cc
@@ -18,7 +18,7 @@
#include "draw_cache_impl.h"
#include "draw_manager_text.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
#define OVERLAY_EDIT_TEXT \
(V3D_OVERLAY_EDIT_EDGE_LEN | V3D_OVERLAY_EDIT_FACE_AREA | V3D_OVERLAY_EDIT_FACE_ANG | \
@@ -45,9 +45,9 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
OVERLAY_PassList *psl = vedata->psl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
OVERLAY_ShadingData *shdata = &pd->shdata;
- DRWShadingGroup *grp = NULL;
- GPUShader *sh = NULL;
- DRWState state = 0;
+ DRWShadingGroup *grp = nullptr;
+ GPUShader *sh = nullptr;
+ DRWState state = DRWState(0);
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
@@ -109,7 +109,7 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
{
/* Normals */
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL |
- (pd->edit_mesh.do_zbufclip ? DRW_STATE_BLEND_ALPHA : 0);
+ (pd->edit_mesh.do_zbufclip ? DRW_STATE_BLEND_ALPHA : DRWState(0));
DRW_PASS_CREATE(psl->edit_mesh_normals_ps, state | pd->clipping_state);
sh = OVERLAY_shader_edit_mesh_normal();
@@ -204,7 +204,7 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH);
}
else {
- pd->edit_mesh_facedots_grp[i] = NULL;
+ pd->edit_mesh_facedots_grp[i] = nullptr;
}
}
}
@@ -234,24 +234,24 @@ static void overlay_edit_mesh_add_ob_to_pass(OVERLAY_PrivateData *pd, Object *ob
pd->edit_mesh_faces_grp[in_front];
skin_roots_shgrp = pd->edit_mesh_skin_roots_grp[in_front];
- geom_edges = DRW_mesh_batch_cache_get_edit_edges(ob->data);
- geom_tris = DRW_mesh_batch_cache_get_edit_triangles(ob->data);
+ geom_edges = DRW_mesh_batch_cache_get_edit_edges(me);
+ geom_tris = DRW_mesh_batch_cache_get_edit_triangles(me);
DRW_shgroup_call_no_cull(edge_shgrp, geom_edges, ob);
DRW_shgroup_call_no_cull(face_shgrp, geom_tris, ob);
if (pd->edit_mesh.select_vert) {
- geom_verts = DRW_mesh_batch_cache_get_edit_vertices(ob->data);
+ geom_verts = DRW_mesh_batch_cache_get_edit_vertices(me);
DRW_shgroup_call_no_cull(vert_shgrp, geom_verts, ob);
if (has_skin_roots) {
circle = DRW_cache_circle_get();
- skin_roots = DRW_mesh_batch_cache_get_edit_skin_roots(ob->data);
+ skin_roots = DRW_mesh_batch_cache_get_edit_skin_roots(me);
DRW_shgroup_call_instances_with_attrs(skin_roots_shgrp, ob, circle, skin_roots);
}
}
if (fdot_shgrp) {
- geom_fcenter = DRW_mesh_batch_cache_get_edit_facedots(ob->data);
+ geom_fcenter = DRW_mesh_batch_cache_get_edit_facedots(me);
DRW_shgroup_call_no_cull(fdot_shgrp, geom_fcenter, ob);
}
}
@@ -259,7 +259,7 @@ static void overlay_edit_mesh_add_ob_to_pass(OVERLAY_PrivateData *pd, Object *ob
void OVERLAY_edit_mesh_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
- struct GPUBatch *geom = NULL;
+ struct GPUBatch *geom = nullptr;
bool draw_as_solid = (ob->dt > OB_WIRE);
bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
@@ -283,16 +283,17 @@ void OVERLAY_edit_mesh_cache_populate(OVERLAY_Data *vedata, Object *ob)
if (vnormals_do || lnormals_do || fnormals_do) {
struct GPUBatch *normal_geom = DRW_cache_normal_arrow_get();
+ Mesh *me = static_cast<Mesh *>(ob->data);
if (vnormals_do) {
- geom = DRW_mesh_batch_cache_get_edit_vnors(ob->data);
+ geom = DRW_mesh_batch_cache_get_edit_vnors(me);
DRW_shgroup_call_instances_with_attrs(pd->edit_mesh_normals_grp, ob, normal_geom, geom);
}
if (lnormals_do) {
- geom = DRW_mesh_batch_cache_get_edit_lnors(ob->data);
+ geom = DRW_mesh_batch_cache_get_edit_lnors(me);
DRW_shgroup_call_instances_with_attrs(pd->edit_mesh_normals_grp, ob, normal_geom, geom);
}
if (fnormals_do) {
- geom = DRW_mesh_batch_cache_get_edit_facedots(ob->data);
+ geom = DRW_mesh_batch_cache_get_edit_facedots(me);
DRW_shgroup_call_instances_with_attrs(pd->edit_mesh_normals_grp, ob, normal_geom, geom);
}
}
@@ -351,7 +352,7 @@ void OVERLAY_edit_mesh_draw(OVERLAY_Data *vedata)
DRW_view_set_active(pd->view_edit_faces_cage);
DRW_draw_pass(psl->edit_mesh_faces_cage_ps[NOT_IN_FRONT]);
- DRW_view_set_active(NULL);
+ DRW_view_set_active(nullptr);
GPU_framebuffer_bind(fbl->overlay_in_front_fb);
GPU_framebuffer_clear_depth(fbl->overlay_in_front_fb, 1.0f);
@@ -372,7 +373,7 @@ void OVERLAY_edit_mesh_draw(OVERLAY_Data *vedata)
}
if (!DRW_pass_is_empty(psl->edit_mesh_depth_ps[IN_FRONT])) {
- DRW_view_set_active(NULL);
+ DRW_view_set_active(nullptr);
DRW_draw_pass(psl->edit_mesh_depth_ps[IN_FRONT]);
}
diff --git a/source/blender/draw/engines/overlay/overlay_edit_text.c b/source/blender/draw/engines/overlay/overlay_edit_text.cc
index bd8720042f1..d1bca705ae6 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_text.c
+++ b/source/blender/draw/engines/overlay/overlay_edit_text.cc
@@ -13,7 +13,7 @@
#include "DNA_curve_types.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_edit_text_cache_init(OVERLAY_Data *vedata)
{
@@ -37,7 +37,7 @@ void OVERLAY_edit_text_cache_init(OVERLAY_Data *vedata)
sh = OVERLAY_shader_uniform_color();
pd->edit_text_wire_grp[i] = grp = DRW_shgroup_create(sh, psl->edit_text_wire_ps[i]);
- DRW_shgroup_uniform_vec4_copy(grp, "color", G_draw.block.color_wire);
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", G_draw.block.color_wire);
}
{
/* Cursor (text caret). */
@@ -45,14 +45,14 @@ void OVERLAY_edit_text_cache_init(OVERLAY_Data *vedata)
DRW_PASS_CREATE(psl->edit_text_cursor_ps, state | pd->clipping_state);
sh = OVERLAY_shader_uniform_color();
pd->edit_text_cursor_grp = grp = DRW_shgroup_create(sh, psl->edit_text_cursor_ps);
- DRW_shgroup_uniform_vec4(grp, "color", pd->edit_text.cursor_color, 1);
+ DRW_shgroup_uniform_vec4(grp, "ucolor", pd->edit_text.cursor_color, 1);
/* Selection boxes. */
state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA;
DRW_PASS_CREATE(psl->edit_text_selection_ps, state | pd->clipping_state);
sh = OVERLAY_shader_uniform_color();
pd->edit_text_selection_grp = grp = DRW_shgroup_create(sh, psl->edit_text_selection_ps);
- DRW_shgroup_uniform_vec4(grp, "color", pd->edit_text.selection_color, 1);
+ DRW_shgroup_uniform_vec4(grp, "ucolor", pd->edit_text.selection_color, 1);
/* Highlight text within selection boxes. */
state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA | DRW_STATE_DEPTH_GREATER_EQUAL |
@@ -83,7 +83,7 @@ static void v2_quad_corners_to_mat4(const float corners[4][2], float r_mat[4][4]
static void edit_text_cache_populate_select(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
- const Curve *cu = ob->data;
+ const Curve *cu = static_cast<Curve *>(ob->data);
EditFont *ef = cu->editfont;
float final_mat[4][4], box[4][2];
struct GPUBatch *geom = DRW_cache_quad_get();
@@ -119,7 +119,7 @@ static void edit_text_cache_populate_select(OVERLAY_Data *vedata, Object *ob)
add_v2_v2(box[3], &sb->x);
}
v2_quad_corners_to_mat4(box, final_mat);
- mul_m4_m4m4(final_mat, ob->obmat, final_mat);
+ mul_m4_m4m4(final_mat, ob->object_to_world, final_mat);
DRW_shgroup_call_obmat(pd->edit_text_selection_grp, geom, final_mat);
}
@@ -128,13 +128,13 @@ static void edit_text_cache_populate_select(OVERLAY_Data *vedata, Object *ob)
static void edit_text_cache_populate_cursor(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
- const Curve *cu = ob->data;
+ const Curve *cu = static_cast<Curve *>(ob->data);
EditFont *edit_font = cu->editfont;
float(*cursor)[2] = edit_font->textcurs;
float mat[4][4];
v2_quad_corners_to_mat4(cursor, mat);
- mul_m4_m4m4(mat, ob->obmat, mat);
+ mul_m4_m4m4(mat, ob->object_to_world, mat);
struct GPUBatch *geom = DRW_cache_quad_get();
DRW_shgroup_call_obmat(pd->edit_text_cursor_grp, geom, mat);
@@ -143,7 +143,7 @@ static void edit_text_cache_populate_cursor(OVERLAY_Data *vedata, Object *ob)
static void edit_text_cache_populate_boxes(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
- const Curve *cu = ob->data;
+ const Curve *cu = static_cast<Curve *>(ob->data);
for (int i = 0; i < cu->totbox; i++) {
TextBox *tb = &cu->tb[i];
@@ -162,7 +162,7 @@ static void edit_text_cache_populate_boxes(OVERLAY_Data *vedata, Object *ob)
vecs[3][1] -= tb->h;
for (int j = 0; j < 4; j++) {
- mul_v3_m4v3(vecs[j], ob->obmat, vecs[j]);
+ mul_v3_m4v3(vecs[j], ob->object_to_world, vecs[j]);
}
for (int j = 0; j < 4; j++) {
OVERLAY_extra_line_dashed(cb, vecs[j], vecs[(j + 1) % 4], color);
diff --git a/source/blender/draw/engines/overlay/overlay_edit_uv.c b/source/blender/draw/engines/overlay/overlay_edit_uv.cc
index adbe5e7155e..0fcbe5ab07d 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_uv.c
+++ b/source/blender/draw/engines/overlay/overlay_edit_uv.cc
@@ -31,16 +31,16 @@
#include "UI_interface.h"
#include "UI_resources.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
/* Forward declarations. */
static void overlay_edit_uv_cache_populate(OVERLAY_Data *vedata, Object *ob);
-typedef struct OVERLAY_StretchingAreaTotals {
+struct OVERLAY_StretchingAreaTotals {
void *next, *prev;
float *total_area;
float *total_area_uv;
-} OVERLAY_StretchingAreaTotals;
+};
static OVERLAY_UVLineStyle edit_uv_line_style_from_space_image(const SpaceImage *sima)
{
@@ -68,9 +68,9 @@ static OVERLAY_UVLineStyle edit_uv_line_style_from_space_image(const SpaceImage
static GPUTexture *edit_uv_mask_texture(
Mask *mask, const int width, const int height_, const float aspx, const float aspy)
{
- const int height = (float)height_ * (aspy / aspx);
+ const int height = float(height_) * (aspy / aspx);
MaskRasterHandle *handle;
- float *buffer = MEM_mallocN(sizeof(float) * height * width, __func__);
+ float *buffer = static_cast<float *>(MEM_mallocN(sizeof(float) * height * width, __func__));
/* Initialize rasterization handle. */
handle = BKE_maskrasterize_handle_new();
@@ -102,10 +102,12 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
Image *image = sima->image;
/* By design no image is an image type. This so editor shows UV's by default. */
- const bool is_image_type =
- (image == NULL) || ELEM(image->type, IMA_TYPE_IMAGE, IMA_TYPE_MULTILAYER, IMA_TYPE_UV_TEST);
+ const bool is_image_type = (image == nullptr) || ELEM(image->type,
+ IMA_TYPE_IMAGE,
+ IMA_TYPE_MULTILAYER,
+ IMA_TYPE_UV_TEST);
const bool is_uv_editor = sima->mode == SI_MODE_UV;
- const bool has_edit_object = (draw_ctx->object_edit) != NULL;
+ const bool has_edit_object = (draw_ctx->object_edit) != nullptr;
const bool is_paint_mode = sima->mode == SI_MODE_PAINT;
const bool is_view_mode = sima->mode == SI_MODE_VIEW;
const bool is_mask_mode = sima->mode == SI_MODE_MASK;
@@ -141,12 +143,13 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
((draw_ctx->object_mode & (OB_MODE_TEXTURE_PAINT)) != 0)) ||
(do_uv_overlay && (show_modified_uvs)));
- pd->edit_uv.do_mask_overlay = show_overlays && is_mask_mode && (sima->mask_info.mask != NULL) &&
+ pd->edit_uv.do_mask_overlay = show_overlays && is_mask_mode &&
+ (sima->mask_info.mask != nullptr) &&
((sima->mask_info.draw_flag & MASK_DRAWFLAG_OVERLAY) != 0);
- pd->edit_uv.mask_overlay_mode = sima->mask_info.overlay_mode;
+ pd->edit_uv.mask_overlay_mode = eMaskOverlayMode(sima->mask_info.overlay_mode);
pd->edit_uv.mask = sima->mask_info.mask ? (Mask *)DEG_get_evaluated_id(
draw_ctx->depsgraph, &sima->mask_info.mask->id) :
- NULL;
+ nullptr;
pd->edit_uv.do_uv_stretching_overlay = show_overlays && do_uvstretching_overlay;
pd->edit_uv.uv_opacity = sima->uv_opacity;
@@ -157,7 +160,7 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
pd->edit_uv.do_smooth_wire = ((U.gpu_flag & USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE) != 0);
pd->edit_uv.do_stencil_overlay = show_overlays && do_stencil_overlay;
- pd->edit_uv.draw_type = sima->dt_uvstretch;
+ pd->edit_uv.draw_type = eSpaceImage_UVDT_Stretch(sima->dt_uvstretch);
BLI_listbase_clear(&pd->edit_uv.totals);
pd->edit_uv.total_area_ratio = 0.0f;
@@ -298,23 +301,25 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
srgb_to_linearrgb_v4(selected_color, selected_color);
DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->edit_uv_tiled_image_borders_ps);
- DRW_shgroup_uniform_vec4_copy(grp, "color", theme_color);
- DRW_shgroup_uniform_vec3_copy(grp, "offset", (float[3]){0.0f, 0.0f, 0.0f});
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", theme_color);
+ const float3 offset = {0.0f, 0.0f, 0.0f};
+ DRW_shgroup_uniform_vec3_copy(grp, "offset", offset);
LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) {
const int tile_x = ((tile->tile_number - 1001) % 10);
const int tile_y = ((tile->tile_number - 1001) / 10);
- obmat[3][1] = (float)tile_y;
- obmat[3][0] = (float)tile_x;
+ obmat[3][1] = float(tile_y);
+ obmat[3][0] = float(tile_x);
DRW_shgroup_call_obmat(grp, geom, obmat);
}
/* Only mark active border when overlays are enabled. */
if (pd->edit_uv.do_tiled_image_overlay) {
/* Active tile border */
- ImageTile *active_tile = BLI_findlink(&image->tiles, image->active_tile_index);
+ ImageTile *active_tile = static_cast<ImageTile *>(
+ BLI_findlink(&image->tiles, image->active_tile_index));
if (active_tile) {
- obmat[3][0] = (float)((active_tile->tile_number - 1001) % 10);
- obmat[3][1] = (float)((active_tile->tile_number - 1001) / 10);
+ obmat[3][0] = float((active_tile->tile_number - 1001) % 10);
+ obmat[3][1] = float((active_tile->tile_number - 1001) / 10);
grp = DRW_shgroup_create(sh, psl->edit_uv_tiled_image_borders_ps);
DRW_shgroup_uniform_vec4_copy(grp, "color", selected_color);
DRW_shgroup_call_obmat(grp, geom, obmat);
@@ -323,7 +328,7 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
}
if (pd->edit_uv.do_tiled_image_overlay) {
- struct DRWTextStore *dt = DRW_text_cache_ensure();
+ DRWTextStore *dt = DRW_text_cache_ensure();
uchar color[4];
/* Color Management: Exception here as texts are drawn in sRGB space directly. */
UI_GetThemeColorShade4ubv(TH_BACK, 60, color);
@@ -331,7 +336,7 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) {
BLI_snprintf(text, 5, "%d", tile->tile_number);
float tile_location[3] = {
- ((tile->tile_number - 1001) % 10), ((tile->tile_number - 1001) / 10), 0.0f};
+ float((tile->tile_number - 1001) % 10), float((tile->tile_number - 1001) / 10), 0.0f};
DRW_text_cache_add(
dt, tile_location, text, strlen(text), 10, 10, DRW_TEXT_CACHE_GLOBALSPACE, color);
}
@@ -340,11 +345,12 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
if (pd->edit_uv.do_stencil_overlay) {
const Brush *brush = BKE_paint_brush(&ts->imapaint.paint);
Image *stencil_image = brush->clone.image;
- ImBuf *stencil_ibuf = BKE_image_acquire_ibuf(stencil_image, NULL, &pd->edit_uv.stencil_lock);
+ ImBuf *stencil_ibuf = BKE_image_acquire_ibuf(
+ stencil_image, nullptr, &pd->edit_uv.stencil_lock);
- if (stencil_ibuf == NULL) {
- pd->edit_uv.stencil_ibuf = NULL;
- pd->edit_uv.stencil_image = NULL;
+ if (stencil_ibuf == nullptr) {
+ pd->edit_uv.stencil_ibuf = nullptr;
+ pd->edit_uv.stencil_image = nullptr;
}
else {
DRW_PASS_CREATE(psl->edit_uv_stencil_ps,
@@ -355,16 +361,17 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->edit_uv_stencil_ps);
pd->edit_uv.stencil_ibuf = stencil_ibuf;
pd->edit_uv.stencil_image = stencil_image;
- GPUTexture *stencil_texture = BKE_image_get_gpu_texture(stencil_image, NULL, stencil_ibuf);
+ GPUTexture *stencil_texture = BKE_image_get_gpu_texture(
+ stencil_image, nullptr, stencil_ibuf);
DRW_shgroup_uniform_texture(grp, "imgTexture", stencil_texture);
DRW_shgroup_uniform_bool_copy(grp, "imgPremultiplied", true);
DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", true);
- DRW_shgroup_uniform_vec4_copy(
- grp, "color", (float[4]){1.0f, 1.0f, 1.0f, brush->clone.alpha});
+ const float4 color = {1.0f, 1.0f, 1.0f, brush->clone.alpha};
+ DRW_shgroup_uniform_vec4_copy(grp, "color", color);
float size_image[2];
- BKE_image_get_size_fl(image, NULL, size_image);
- float size_stencil_image[2] = {stencil_ibuf->x, stencil_ibuf->y};
+ BKE_image_get_size_fl(image, nullptr, size_image);
+ float size_stencil_image[2] = {float(stencil_ibuf->x), float(stencil_ibuf->y)};
float obmat[4][4];
unit_m4(obmat);
@@ -377,8 +384,8 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
}
}
else {
- pd->edit_uv.stencil_ibuf = NULL;
- pd->edit_uv.stencil_image = NULL;
+ pd->edit_uv.stencil_ibuf = nullptr;
+ pd->edit_uv.stencil_image = nullptr;
}
if (pd->edit_uv.do_mask_overlay) {
@@ -397,8 +404,9 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
pd->edit_uv.image_aspect[1]);
pd->edit_uv.mask_texture = mask_texture;
DRW_shgroup_uniform_texture(grp, "imgTexture", mask_texture);
- DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){1.0f, 1.0f, 1.0f, 1.0f});
- DRW_shgroup_call_obmat(grp, geom, NULL);
+ const float4 color = {1.0f, 1.0f, 1.0f, 1.0f};
+ DRW_shgroup_uniform_vec4_copy(grp, "color", color);
+ DRW_shgroup_call_obmat(grp, geom, nullptr);
}
/* HACK: When editing objects that share the same mesh we should only draw the
@@ -408,7 +416,7 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
draw_ctx->obact->type == OB_MESH) {
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_mode_unique_data(
- draw_ctx->view_layer, NULL, &objects_len, draw_ctx->object_mode);
+ draw_ctx->scene, draw_ctx->view_layer, nullptr, &objects_len, draw_ctx->object_mode);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *object_eval = DEG_get_evaluated_object(draw_ctx->depsgraph, objects[ob_index]);
DRW_mesh_batch_cache_validate(object_eval, (Mesh *)object_eval->data);
@@ -440,26 +448,26 @@ static void overlay_edit_uv_cache_populate(OVERLAY_Data *vedata, Object *ob)
if (has_active_edit_uvmap) {
if (pd->edit_uv.do_uv_overlay) {
- geom = DRW_mesh_batch_cache_get_edituv_edges(ob, ob->data);
+ geom = DRW_mesh_batch_cache_get_edituv_edges(ob, me);
if (geom) {
- DRW_shgroup_call_obmat(pd->edit_uv_edges_grp, geom, NULL);
+ DRW_shgroup_call_obmat(pd->edit_uv_edges_grp, geom, nullptr);
}
if (pd->edit_uv.do_verts) {
- geom = DRW_mesh_batch_cache_get_edituv_verts(ob, ob->data);
+ geom = DRW_mesh_batch_cache_get_edituv_verts(ob, me);
if (geom) {
- DRW_shgroup_call_obmat(pd->edit_uv_verts_grp, geom, NULL);
+ DRW_shgroup_call_obmat(pd->edit_uv_verts_grp, geom, nullptr);
}
}
if (pd->edit_uv.do_faces) {
- geom = DRW_mesh_batch_cache_get_edituv_faces(ob, ob->data);
+ geom = DRW_mesh_batch_cache_get_edituv_faces(ob, me);
if (geom) {
- DRW_shgroup_call_obmat(pd->edit_uv_faces_grp, geom, NULL);
+ DRW_shgroup_call_obmat(pd->edit_uv_faces_grp, geom, nullptr);
}
}
if (pd->edit_uv.do_face_dots) {
- geom = DRW_mesh_batch_cache_get_edituv_facedots(ob, ob->data);
+ geom = DRW_mesh_batch_cache_get_edituv_facedots(ob, me);
if (geom) {
- DRW_shgroup_call_obmat(pd->edit_uv_face_dots_grp, geom, NULL);
+ DRW_shgroup_call_obmat(pd->edit_uv_face_dots_grp, geom, nullptr);
}
}
}
@@ -469,23 +477,23 @@ static void overlay_edit_uv_cache_populate(OVERLAY_Data *vedata, Object *ob)
geom = DRW_mesh_batch_cache_get_edituv_faces_stretch_angle(ob, me);
}
else /* SI_UVDT_STRETCH_AREA */ {
- OVERLAY_StretchingAreaTotals *totals = MEM_mallocN(sizeof(OVERLAY_StretchingAreaTotals),
- __func__);
+ OVERLAY_StretchingAreaTotals *totals = static_cast<OVERLAY_StretchingAreaTotals *>(
+ MEM_mallocN(sizeof(OVERLAY_StretchingAreaTotals), __func__));
BLI_addtail(&pd->edit_uv.totals, totals);
geom = DRW_mesh_batch_cache_get_edituv_faces_stretch_area(
ob, me, &totals->total_area, &totals->total_area_uv);
}
if (geom) {
- DRW_shgroup_call_obmat(pd->edit_uv_stretching_grp, geom, NULL);
+ DRW_shgroup_call_obmat(pd->edit_uv_stretching_grp, geom, nullptr);
}
}
}
if (draw_shadows && (has_active_object_uvmap || has_active_edit_uvmap)) {
if (pd->edit_uv.do_uv_shadow_overlay) {
- geom = DRW_mesh_batch_cache_get_uv_edges(ob, ob->data);
+ geom = DRW_mesh_batch_cache_get_uv_edges(ob, me);
if (geom) {
- DRW_shgroup_call_obmat(pd->edit_uv_shadow_edges_grp, geom, NULL);
+ DRW_shgroup_call_obmat(pd->edit_uv_shadow_edges_grp, geom, nullptr);
}
}
}
@@ -530,8 +538,8 @@ static void OVERLAY_edit_uv_draw_finish(OVERLAY_Data *vedata)
if (pd->edit_uv.stencil_ibuf) {
BKE_image_release_ibuf(
pd->edit_uv.stencil_image, pd->edit_uv.stencil_ibuf, pd->edit_uv.stencil_lock);
- pd->edit_uv.stencil_image = NULL;
- pd->edit_uv.stencil_ibuf = NULL;
+ pd->edit_uv.stencil_image = nullptr;
+ pd->edit_uv.stencil_ibuf = nullptr;
}
DRW_TEXTURE_FREE_SAFE(pd->edit_uv.mask_texture);
@@ -550,7 +558,7 @@ void OVERLAY_edit_uv_draw(OVERLAY_Data *vedata)
/* Combined overlay renders in the default framebuffer and modifies the image in SRS.
* The alpha overlay renders in the overlay framebuffer. */
const bool is_combined_overlay = pd->edit_uv.mask_overlay_mode == MASK_OVERLAY_COMBINED;
- GPUFrameBuffer *previous_framebuffer = NULL;
+ GPUFrameBuffer *previous_framebuffer = nullptr;
if (is_combined_overlay) {
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
previous_framebuffer = GPU_framebuffer_active_get();
diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.cc
index 6e2da95e405..f1fdfe98fdc 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.c
+++ b/source/blender/draw/engines/overlay/overlay_engine.cc
@@ -16,13 +16,14 @@
#include "UI_interface.h"
+#include "BKE_duplilist.h"
#include "BKE_object.h"
#include "BKE_paint.h"
#include "DNA_space_types.h"
#include "overlay_engine.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
/* -------------------------------------------------------------------- */
/** \name Engine Callbacks
@@ -30,7 +31,7 @@
static void OVERLAY_engine_init(void *vedata)
{
- OVERLAY_Data *data = vedata;
+ OVERLAY_Data *data = static_cast<OVERLAY_Data *>(vedata);
OVERLAY_StorageList *stl = data->stl;
const DRWContextState *draw_ctx = DRW_context_state_get();
const RegionView3D *rv3d = draw_ctx->rv3d;
@@ -40,28 +41,29 @@ static void OVERLAY_engine_init(void *vedata)
if (!stl->pd) {
/* Allocate transient pointers. */
- stl->pd = MEM_callocN(sizeof(*stl->pd), __func__);
+ stl->pd = static_cast<OVERLAY_PrivateData *>(MEM_callocN(sizeof(*stl->pd), __func__));
}
/* Allocate instance. */
- if (data->instance == NULL) {
- data->instance = MEM_callocN(sizeof(*data->instance), __func__);
+ if (data->instance == nullptr) {
+ data->instance = static_cast<OVERLAY_Instance *>(
+ MEM_callocN(sizeof(*data->instance), __func__));
}
OVERLAY_PrivateData *pd = stl->pd;
- pd->space_type = v3d != NULL ? SPACE_VIEW3D : draw_ctx->space_data->spacetype;
+ pd->space_type = v3d != nullptr ? int(SPACE_VIEW3D) : draw_ctx->space_data->spacetype;
if (pd->space_type == SPACE_IMAGE) {
const SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
pd->hide_overlays = (sima->overlay.flag & SI_OVERLAY_SHOW_OVERLAYS) == 0;
- pd->clipping_state = 0;
+ pd->clipping_state = DRWState(0);
OVERLAY_grid_init(data);
OVERLAY_edit_uv_init(data);
return;
}
if (pd->space_type == SPACE_NODE) {
pd->hide_overlays = true;
- pd->clipping_state = 0;
+ pd->clipping_state = DRWState(0);
return;
}
@@ -101,98 +103,99 @@ static void OVERLAY_engine_init(void *vedata)
pd->use_in_front = (v3d->shading.type <= OB_SOLID) ||
BKE_scene_uses_blender_workbench(draw_ctx->scene);
pd->wireframe_mode = (v3d->shading.type == OB_WIRE);
- pd->clipping_state = RV3D_CLIPPING_ENABLED(v3d, rv3d) ? DRW_STATE_CLIP_PLANES : 0;
+ pd->clipping_state = RV3D_CLIPPING_ENABLED(v3d, rv3d) ? DRW_STATE_CLIP_PLANES : DRWState(0);
pd->xray_opacity = XRAY_ALPHA(v3d);
pd->xray_enabled = XRAY_ACTIVE(v3d);
pd->xray_enabled_and_not_wire = pd->xray_enabled && v3d->shading.type > OB_WIRE;
pd->clear_in_front = (v3d->shading.type != OB_SOLID);
pd->cfra = DEG_get_ctime(draw_ctx->depsgraph);
- OVERLAY_antialiasing_init(vedata);
+ OVERLAY_antialiasing_init(data);
switch (stl->pd->ctx_mode) {
case CTX_MODE_EDIT_MESH:
- OVERLAY_edit_mesh_init(vedata);
+ OVERLAY_edit_mesh_init(data);
break;
case CTX_MODE_EDIT_CURVES:
- OVERLAY_edit_curves_init(vedata);
+ OVERLAY_edit_curves_init(data);
break;
default:
/* Nothing to do. */
break;
}
- OVERLAY_facing_init(vedata);
- OVERLAY_grid_init(vedata);
- OVERLAY_image_init(vedata);
- OVERLAY_outline_init(vedata);
- OVERLAY_wireframe_init(vedata);
- OVERLAY_paint_init(vedata);
+ OVERLAY_facing_init(data);
+ OVERLAY_grid_init(data);
+ OVERLAY_image_init(data);
+ OVERLAY_outline_init(data);
+ OVERLAY_wireframe_init(data);
+ OVERLAY_paint_init(data);
}
static void OVERLAY_cache_init(void *vedata)
{
- OVERLAY_Data *data = vedata;
+ OVERLAY_Data *data = static_cast<OVERLAY_Data *>(vedata);
OVERLAY_StorageList *stl = data->stl;
OVERLAY_PrivateData *pd = stl->pd;
if (pd->space_type == SPACE_IMAGE) {
- OVERLAY_background_cache_init(vedata);
- OVERLAY_grid_cache_init(vedata);
- OVERLAY_edit_uv_cache_init(vedata);
+ OVERLAY_background_cache_init(data);
+ OVERLAY_grid_cache_init(data);
+ OVERLAY_edit_uv_cache_init(data);
return;
}
if (pd->space_type == SPACE_NODE) {
- OVERLAY_background_cache_init(vedata);
+ OVERLAY_background_cache_init(data);
return;
}
switch (pd->ctx_mode) {
- case CTX_MODE_EDIT_MESH:
- OVERLAY_edit_mesh_cache_init(vedata);
+ case CTX_MODE_EDIT_MESH: {
+ OVERLAY_edit_mesh_cache_init(data);
/* `pd->edit_mesh.flag` is valid after calling `OVERLAY_edit_mesh_cache_init`. */
const bool draw_edit_weights = (pd->edit_mesh.flag & V3D_OVERLAY_EDIT_WEIGHT);
if (draw_edit_weights) {
- OVERLAY_paint_cache_init(vedata);
+ OVERLAY_paint_cache_init(data);
}
break;
+ }
case CTX_MODE_EDIT_SURFACE:
case CTX_MODE_EDIT_CURVE:
- OVERLAY_edit_curve_cache_init(vedata);
+ OVERLAY_edit_curve_cache_init(data);
break;
case CTX_MODE_EDIT_TEXT:
- OVERLAY_edit_text_cache_init(vedata);
+ OVERLAY_edit_text_cache_init(data);
break;
case CTX_MODE_EDIT_ARMATURE:
break;
case CTX_MODE_EDIT_METABALL:
break;
case CTX_MODE_EDIT_LATTICE:
- OVERLAY_edit_lattice_cache_init(vedata);
+ OVERLAY_edit_lattice_cache_init(data);
break;
case CTX_MODE_PARTICLE:
- OVERLAY_edit_particle_cache_init(vedata);
+ OVERLAY_edit_particle_cache_init(data);
break;
case CTX_MODE_POSE:
case CTX_MODE_PAINT_WEIGHT:
case CTX_MODE_PAINT_VERTEX:
case CTX_MODE_PAINT_TEXTURE:
- OVERLAY_paint_cache_init(vedata);
+ OVERLAY_paint_cache_init(data);
break;
case CTX_MODE_SCULPT:
- OVERLAY_sculpt_cache_init(vedata);
+ OVERLAY_sculpt_cache_init(data);
break;
case CTX_MODE_EDIT_GPENCIL:
case CTX_MODE_PAINT_GPENCIL:
case CTX_MODE_SCULPT_GPENCIL:
case CTX_MODE_VERTEX_GPENCIL:
case CTX_MODE_WEIGHT_GPENCIL:
- OVERLAY_edit_gpencil_cache_init(vedata);
+ OVERLAY_edit_gpencil_cache_init(data);
break;
case CTX_MODE_EDIT_CURVES:
- OVERLAY_edit_curves_cache_init(vedata);
+ OVERLAY_edit_curves_cache_init(data);
break;
case CTX_MODE_SCULPT_CURVES:
- OVERLAY_sculpt_curves_cache_init(vedata);
+ OVERLAY_sculpt_curves_cache_init(data);
break;
case CTX_MODE_OBJECT:
break;
@@ -200,22 +203,23 @@ static void OVERLAY_cache_init(void *vedata)
BLI_assert_msg(0, "Draw mode invalid");
break;
}
- OVERLAY_antialiasing_cache_init(vedata);
- OVERLAY_armature_cache_init(vedata);
- OVERLAY_background_cache_init(vedata);
- OVERLAY_fade_cache_init(vedata);
- OVERLAY_mode_transfer_cache_init(vedata);
- OVERLAY_extra_cache_init(vedata);
- OVERLAY_facing_cache_init(vedata);
- OVERLAY_gpencil_cache_init(vedata);
- OVERLAY_grid_cache_init(vedata);
- OVERLAY_image_cache_init(vedata);
- OVERLAY_metaball_cache_init(vedata);
- OVERLAY_motion_path_cache_init(vedata);
- OVERLAY_outline_cache_init(vedata);
- OVERLAY_particle_cache_init(vedata);
- OVERLAY_wireframe_cache_init(vedata);
- OVERLAY_volume_cache_init(vedata);
+ OVERLAY_antialiasing_cache_init(data);
+ OVERLAY_armature_cache_init(data);
+ OVERLAY_viewer_attribute_cache_init(data);
+ OVERLAY_background_cache_init(data);
+ OVERLAY_fade_cache_init(data);
+ OVERLAY_mode_transfer_cache_init(data);
+ OVERLAY_extra_cache_init(data);
+ OVERLAY_facing_cache_init(data);
+ OVERLAY_gpencil_cache_init(data);
+ OVERLAY_grid_cache_init(data);
+ OVERLAY_image_cache_init(data);
+ OVERLAY_metaball_cache_init(data);
+ OVERLAY_motion_path_cache_init(data);
+ OVERLAY_outline_cache_init(data);
+ OVERLAY_particle_cache_init(data);
+ OVERLAY_wireframe_cache_init(data);
+ OVERLAY_volume_cache_init(data);
}
BLI_INLINE OVERLAY_DupliData *OVERLAY_duplidata_get(Object *ob, void *vedata, bool *do_init)
@@ -223,12 +227,13 @@ BLI_INLINE OVERLAY_DupliData *OVERLAY_duplidata_get(Object *ob, void *vedata, bo
OVERLAY_DupliData **dupli_data = (OVERLAY_DupliData **)DRW_duplidata_get(vedata);
*do_init = false;
if (!ELEM(ob->type, OB_MESH, OB_SURF, OB_LATTICE, OB_CURVES_LEGACY, OB_FONT)) {
- return NULL;
+ return nullptr;
}
if (dupli_data) {
- if (*dupli_data == NULL) {
- *dupli_data = MEM_callocN(sizeof(OVERLAY_DupliData), __func__);
+ if (*dupli_data == nullptr) {
+ *dupli_data = static_cast<OVERLAY_DupliData *>(
+ MEM_callocN(sizeof(OVERLAY_DupliData), __func__));
*do_init = true;
}
else if ((*dupli_data)->base_flag != ob->base_flag) {
@@ -237,7 +242,7 @@ BLI_INLINE OVERLAY_DupliData *OVERLAY_duplidata_get(Object *ob, void *vedata, bo
}
return *dupli_data;
}
- return NULL;
+ return nullptr;
}
static bool overlay_object_is_edit_mode(const OVERLAY_PrivateData *pd, const Object *ob)
@@ -289,7 +294,7 @@ static bool overlay_should_fade_object(Object *ob, Object *active_object)
static void OVERLAY_cache_populate(void *vedata, Object *ob)
{
- OVERLAY_Data *data = vedata;
+ OVERLAY_Data *data = static_cast<OVERLAY_Data *>(vedata);
OVERLAY_PrivateData *pd = data->stl->pd;
if (pd->space_type == SPACE_IMAGE) {
@@ -297,8 +302,12 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
}
const DRWContextState *draw_ctx = DRW_context_state_get();
+ DupliObject *dupli_object = DRW_object_get_dupli(ob);
+ Object *dupli_parent = DRW_object_get_dupli_parent(ob);
const bool is_select = DRW_state_is_select();
const bool renderable = DRW_object_is_renderable(ob);
+ const bool is_preview = dupli_object != nullptr &&
+ dupli_object->preview_base_geometry != nullptr;
const bool in_pose_mode = ob->type == OB_ARMATURE && OVERLAY_armature_is_pose_mode(ob, draw_ctx);
const bool in_edit_mode = overlay_object_is_edit_mode(pd, ob);
const bool is_instance = (ob->base_flag & BASE_FROM_DUPLI);
@@ -310,9 +319,10 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
(pd->ctx_mode == CTX_MODE_PARTICLE);
const bool in_paint_mode = (ob == draw_ctx->obact) &&
(draw_ctx->object_mode & OB_MODE_ALL_PAINT);
- const bool in_sculpt_curve_mode = (ob == draw_ctx->obact) &&
+ const bool in_sculpt_curve_mode = (ob == draw_ctx->obact ||
+ (is_preview && dupli_parent == draw_ctx->obact)) &&
(draw_ctx->object_mode & OB_MODE_SCULPT_CURVES);
- const bool in_sculpt_mode = (ob == draw_ctx->obact) && (ob->sculpt != NULL) &&
+ const bool in_sculpt_mode = (ob == draw_ctx->obact) && (ob->sculpt != nullptr) &&
(ob->sculpt->mode_type == OB_MODE_SCULPT);
const bool in_curves_sculpt_mode = (ob == draw_ctx->obact) &&
(ob->mode == OB_MODE_SCULPT_CURVES);
@@ -353,108 +363,114 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
OVERLAY_DupliData *dupli = OVERLAY_duplidata_get(ob, vedata, &do_init);
if (draw_fade) {
- OVERLAY_fade_cache_populate(vedata, ob);
+ OVERLAY_fade_cache_populate(data, ob);
}
if (draw_facing) {
- OVERLAY_facing_cache_populate(vedata, ob);
+ OVERLAY_facing_cache_populate(data, ob);
}
if (draw_mode_transfer) {
- OVERLAY_mode_transfer_cache_populate(vedata, ob);
+ OVERLAY_mode_transfer_cache_populate(data, ob);
}
if (draw_wires) {
- OVERLAY_wireframe_cache_populate(vedata, ob, dupli, do_init);
+ OVERLAY_wireframe_cache_populate(data, ob, dupli, do_init);
}
if (draw_outlines) {
- OVERLAY_outline_cache_populate(vedata, ob, dupli, do_init);
+ OVERLAY_outline_cache_populate(data, ob, dupli, do_init);
}
if (draw_bone_selection) {
- OVERLAY_pose_cache_populate(vedata, ob);
+ OVERLAY_pose_cache_populate(data, ob);
+ }
+
+ if (pd->overlay.flag & V3D_OVERLAY_VIEWER_ATTRIBUTE) {
+ if (is_preview) {
+ OVERLAY_viewer_attribute_cache_populate(data, ob);
+ }
}
if (ob->type == OB_VOLUME) {
- OVERLAY_volume_cache_populate(vedata, ob);
+ OVERLAY_volume_cache_populate(data, ob);
}
if (in_edit_mode && !pd->hide_overlays) {
switch (ob->type) {
case OB_MESH:
- OVERLAY_edit_mesh_cache_populate(vedata, ob);
+ OVERLAY_edit_mesh_cache_populate(data, ob);
if (draw_edit_weights) {
- OVERLAY_paint_weight_cache_populate(vedata, ob);
+ OVERLAY_paint_weight_cache_populate(data, ob);
}
break;
case OB_ARMATURE:
if (draw_bones) {
- OVERLAY_edit_armature_cache_populate(vedata, ob);
+ OVERLAY_edit_armature_cache_populate(data, ob);
}
break;
case OB_CURVES_LEGACY:
- OVERLAY_edit_curve_cache_populate(vedata, ob);
+ OVERLAY_edit_curve_cache_populate(data, ob);
break;
case OB_SURF:
- OVERLAY_edit_surf_cache_populate(vedata, ob);
+ OVERLAY_edit_surf_cache_populate(data, ob);
break;
case OB_LATTICE:
- OVERLAY_edit_lattice_cache_populate(vedata, ob);
+ OVERLAY_edit_lattice_cache_populate(data, ob);
break;
case OB_MBALL:
- OVERLAY_edit_metaball_cache_populate(vedata, ob);
+ OVERLAY_edit_metaball_cache_populate(data, ob);
break;
case OB_FONT:
- OVERLAY_edit_text_cache_populate(vedata, ob);
+ OVERLAY_edit_text_cache_populate(data, ob);
break;
case OB_CURVES:
- OVERLAY_edit_curves_cache_populate(vedata, ob);
+ OVERLAY_edit_curves_cache_populate(data, ob);
break;
}
}
else if (in_pose_mode && draw_bones) {
- OVERLAY_pose_armature_cache_populate(vedata, ob);
+ OVERLAY_pose_armature_cache_populate(data, ob);
}
else if (in_paint_mode && !pd->hide_overlays) {
switch (draw_ctx->object_mode) {
case OB_MODE_VERTEX_PAINT:
- OVERLAY_paint_vertex_cache_populate(vedata, ob);
+ OVERLAY_paint_vertex_cache_populate(data, ob);
break;
case OB_MODE_WEIGHT_PAINT:
- OVERLAY_paint_weight_cache_populate(vedata, ob);
+ OVERLAY_paint_weight_cache_populate(data, ob);
break;
case OB_MODE_TEXTURE_PAINT:
- OVERLAY_paint_texture_cache_populate(vedata, ob);
+ OVERLAY_paint_texture_cache_populate(data, ob);
break;
default:
break;
}
}
else if (in_particle_edit_mode) {
- OVERLAY_edit_particle_cache_populate(vedata, ob);
+ OVERLAY_edit_particle_cache_populate(data, ob);
}
if (in_sculpt_mode) {
- OVERLAY_sculpt_cache_populate(vedata, ob);
+ OVERLAY_sculpt_cache_populate(data, ob);
}
else if (in_curves_sculpt_mode) {
- OVERLAY_sculpt_curves_cache_populate(vedata, ob);
+ OVERLAY_sculpt_curves_cache_populate(data, ob);
}
if (draw_motion_paths) {
- OVERLAY_motion_path_cache_populate(vedata, ob);
+ OVERLAY_motion_path_cache_populate(data, ob);
}
if (!pd->hide_overlays) {
switch (ob->type) {
case OB_ARMATURE:
if (draw_bones && (is_select || (!in_edit_mode && !in_pose_mode))) {
- OVERLAY_armature_cache_populate(vedata, ob);
+ OVERLAY_armature_cache_populate(data, ob);
}
break;
case OB_MBALL:
if (!in_edit_mode) {
- OVERLAY_metaball_cache_populate(vedata, ob);
+ OVERLAY_metaball_cache_populate(data, ob);
}
break;
case OB_GPENCIL:
- OVERLAY_gpencil_cache_populate(vedata, ob);
+ OVERLAY_gpencil_cache_populate(data, ob);
break;
}
}
@@ -462,25 +478,25 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
if (draw_extras) {
switch (ob->type) {
case OB_EMPTY:
- OVERLAY_empty_cache_populate(vedata, ob);
+ OVERLAY_empty_cache_populate(data, ob);
break;
case OB_LAMP:
- OVERLAY_light_cache_populate(vedata, ob);
+ OVERLAY_light_cache_populate(data, ob);
break;
case OB_CAMERA:
- OVERLAY_camera_cache_populate(vedata, ob);
+ OVERLAY_camera_cache_populate(data, ob);
break;
case OB_SPEAKER:
- OVERLAY_speaker_cache_populate(vedata, ob);
+ OVERLAY_speaker_cache_populate(data, ob);
break;
case OB_LIGHTPROBE:
- OVERLAY_lightprobe_cache_populate(vedata, ob);
+ OVERLAY_lightprobe_cache_populate(data, ob);
break;
case OB_LATTICE: {
/* Unlike the other types above, lattices actually have a bounding box defined, so hide the
* lattice wires if only the bounding-box is requested. */
if (ob->dt > OB_BOUNDBOX) {
- OVERLAY_lattice_cache_populate(vedata, ob);
+ OVERLAY_lattice_cache_populate(data, ob);
}
break;
}
@@ -488,12 +504,12 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
}
if (!BLI_listbase_is_empty(&ob->particlesystem)) {
- OVERLAY_particle_cache_populate(vedata, ob);
+ OVERLAY_particle_cache_populate(data, ob);
}
/* Relationship, object center, bounding-box... etc. */
if (!pd->hide_overlays) {
- OVERLAY_extra_cache_populate(vedata, ob);
+ OVERLAY_extra_cache_populate(data, ob);
}
if (dupli) {
@@ -503,11 +519,11 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
static void OVERLAY_cache_finish(void *vedata)
{
- OVERLAY_Data *data = vedata;
+ OVERLAY_Data *data = static_cast<OVERLAY_Data *>(vedata);
OVERLAY_PrivateData *pd = data->stl->pd;
if (ELEM(pd->space_type, SPACE_IMAGE)) {
- OVERLAY_edit_uv_cache_finish(vedata);
+ OVERLAY_edit_uv_cache_finish(data);
return;
}
if (ELEM(pd->space_type, SPACE_NODE)) {
@@ -520,29 +536,30 @@ static void OVERLAY_cache_finish(void *vedata)
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- DRW_texture_ensure_fullscreen_2d(&dtxl->depth_in_front, GPU_DEPTH24_STENCIL8, 0);
+ DRW_texture_ensure_fullscreen_2d(
+ &dtxl->depth_in_front, GPU_DEPTH24_STENCIL8, DRWTextureFlag(0));
GPU_framebuffer_ensure_config(
&dfbl->in_front_fb,
{GPU_ATTACHMENT_TEXTURE(dtxl->depth_in_front), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
}
- OVERLAY_mode_transfer_cache_finish(vedata);
- OVERLAY_antialiasing_cache_finish(vedata);
- OVERLAY_armature_cache_finish(vedata);
- OVERLAY_image_cache_finish(vedata);
+ OVERLAY_mode_transfer_cache_finish(data);
+ OVERLAY_antialiasing_cache_finish(data);
+ OVERLAY_armature_cache_finish(data);
+ OVERLAY_image_cache_finish(data);
}
static void OVERLAY_draw_scene(void *vedata)
{
- OVERLAY_Data *data = vedata;
+ OVERLAY_Data *data = static_cast<OVERLAY_Data *>(vedata);
OVERLAY_PrivateData *pd = data->stl->pd;
OVERLAY_FramebufferList *fbl = data->fbl;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
/* Needs to be done first as it modifies the scene color and depth buffer. */
if (pd->space_type == SPACE_VIEW3D) {
- OVERLAY_image_scene_background_draw(vedata);
+ OVERLAY_image_scene_background_draw(data);
}
if (DRW_state_is_fbo()) {
@@ -569,45 +586,45 @@ static void OVERLAY_draw_scene(void *vedata)
return;
}
- OVERLAY_image_background_draw(vedata);
- OVERLAY_background_draw(vedata);
+ OVERLAY_image_background_draw(data);
+ OVERLAY_background_draw(data);
- OVERLAY_antialiasing_start(vedata);
+ OVERLAY_antialiasing_start(data);
- DRW_view_set_active(NULL);
+ DRW_view_set_active(nullptr);
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_color_only_fb);
}
- OVERLAY_outline_draw(vedata);
- OVERLAY_xray_depth_copy(vedata);
+ OVERLAY_outline_draw(data);
+ OVERLAY_xray_depth_copy(data);
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_default_fb);
}
- OVERLAY_image_draw(vedata);
- OVERLAY_fade_draw(vedata);
- OVERLAY_facing_draw(vedata);
- OVERLAY_mode_transfer_draw(vedata);
- OVERLAY_extra_blend_draw(vedata);
- OVERLAY_volume_draw(vedata);
+ OVERLAY_image_draw(data);
+ OVERLAY_fade_draw(data);
+ OVERLAY_facing_draw(data);
+ OVERLAY_mode_transfer_draw(data);
+ OVERLAY_extra_blend_draw(data);
+ OVERLAY_volume_draw(data);
/* These overlays are drawn here to avoid artifacts with wire-frame opacity. */
switch (pd->ctx_mode) {
case CTX_MODE_SCULPT:
- OVERLAY_sculpt_draw(vedata);
+ OVERLAY_sculpt_draw(data);
break;
case CTX_MODE_SCULPT_CURVES:
- OVERLAY_sculpt_curves_draw(vedata);
+ OVERLAY_sculpt_curves_draw(data);
break;
case CTX_MODE_EDIT_MESH:
case CTX_MODE_POSE:
case CTX_MODE_PAINT_WEIGHT:
case CTX_MODE_PAINT_VERTEX:
case CTX_MODE_PAINT_TEXTURE:
- OVERLAY_paint_draw(vedata);
+ OVERLAY_paint_draw(data);
break;
default:
break;
@@ -617,46 +634,49 @@ static void OVERLAY_draw_scene(void *vedata)
GPU_framebuffer_bind(fbl->overlay_line_fb);
}
- OVERLAY_wireframe_draw(vedata);
- OVERLAY_armature_draw(vedata);
- OVERLAY_particle_draw(vedata);
- OVERLAY_metaball_draw(vedata);
- OVERLAY_gpencil_draw(vedata);
- OVERLAY_extra_draw(vedata);
+ OVERLAY_wireframe_draw(data);
+ OVERLAY_armature_draw(data);
+ OVERLAY_particle_draw(data);
+ OVERLAY_metaball_draw(data);
+ OVERLAY_gpencil_draw(data);
+ OVERLAY_extra_draw(data);
+ if (pd->overlay.flag & V3D_OVERLAY_VIEWER_ATTRIBUTE) {
+ OVERLAY_viewer_attribute_draw(data);
+ }
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_color_only_fb);
}
- OVERLAY_xray_fade_draw(vedata);
- OVERLAY_grid_draw(vedata);
+ OVERLAY_xray_fade_draw(data);
+ OVERLAY_grid_draw(data);
- OVERLAY_xray_depth_infront_copy(vedata);
+ OVERLAY_xray_depth_infront_copy(data);
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_in_front_fb);
}
- OVERLAY_fade_infront_draw(vedata);
- OVERLAY_facing_infront_draw(vedata);
- OVERLAY_mode_transfer_infront_draw(vedata);
+ OVERLAY_fade_infront_draw(data);
+ OVERLAY_facing_infront_draw(data);
+ OVERLAY_mode_transfer_infront_draw(data);
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_line_in_front_fb);
}
- OVERLAY_wireframe_in_front_draw(vedata);
- OVERLAY_armature_in_front_draw(vedata);
- OVERLAY_extra_in_front_draw(vedata);
- OVERLAY_metaball_in_front_draw(vedata);
+ OVERLAY_wireframe_in_front_draw(data);
+ OVERLAY_armature_in_front_draw(data);
+ OVERLAY_extra_in_front_draw(data);
+ OVERLAY_metaball_in_front_draw(data);
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_color_only_fb);
}
- OVERLAY_image_in_front_draw(vedata);
- OVERLAY_motion_path_draw(vedata);
- OVERLAY_extra_centers_draw(vedata);
+ OVERLAY_image_in_front_draw(data);
+ OVERLAY_motion_path_draw(data);
+ OVERLAY_extra_centers_draw(data);
if (DRW_state_is_select() || DRW_state_is_depth()) {
/* Edit modes have their own selection code. */
@@ -667,44 +687,44 @@ static void OVERLAY_draw_scene(void *vedata)
switch (pd->ctx_mode) {
case CTX_MODE_EDIT_MESH:
- OVERLAY_edit_mesh_draw(vedata);
+ OVERLAY_edit_mesh_draw(data);
break;
case CTX_MODE_EDIT_SURFACE:
case CTX_MODE_EDIT_CURVE:
- OVERLAY_edit_curve_draw(vedata);
+ OVERLAY_edit_curve_draw(data);
break;
case CTX_MODE_EDIT_TEXT:
- OVERLAY_edit_text_draw(vedata);
+ OVERLAY_edit_text_draw(data);
break;
case CTX_MODE_EDIT_LATTICE:
- OVERLAY_edit_lattice_draw(vedata);
+ OVERLAY_edit_lattice_draw(data);
break;
case CTX_MODE_POSE:
- OVERLAY_pose_draw(vedata);
+ OVERLAY_pose_draw(data);
break;
case CTX_MODE_PARTICLE:
- OVERLAY_edit_particle_draw(vedata);
+ OVERLAY_edit_particle_draw(data);
break;
case CTX_MODE_EDIT_GPENCIL:
case CTX_MODE_PAINT_GPENCIL:
case CTX_MODE_SCULPT_GPENCIL:
case CTX_MODE_VERTEX_GPENCIL:
case CTX_MODE_WEIGHT_GPENCIL:
- OVERLAY_edit_gpencil_draw(vedata);
+ OVERLAY_edit_gpencil_draw(data);
break;
case CTX_MODE_SCULPT_CURVES:
break;
case CTX_MODE_EDIT_CURVES:
- OVERLAY_edit_curves_draw(vedata);
+ OVERLAY_edit_curves_draw(data);
break;
default:
break;
}
- OVERLAY_antialiasing_end(vedata);
+ OVERLAY_antialiasing_end(data);
}
-static void OVERLAY_engine_free(void)
+static void OVERLAY_engine_free()
{
OVERLAY_shader_free();
}
@@ -725,8 +745,8 @@ static void OVERLAY_instance_free(void *instance_)
static const DrawEngineDataSize overlay_data_size = DRW_VIEWPORT_DATA_SIZE(OVERLAY_Data);
DrawEngineType draw_engine_overlay_type = {
- NULL,
- NULL,
+ nullptr,
+ nullptr,
N_("Overlay"),
&overlay_data_size,
&OVERLAY_engine_init,
@@ -736,10 +756,10 @@ DrawEngineType draw_engine_overlay_type = {
&OVERLAY_cache_populate,
&OVERLAY_cache_finish,
&OVERLAY_draw_scene,
- NULL,
- NULL,
- NULL,
- NULL,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
};
/** \} */
diff --git a/source/blender/draw/engines/overlay/overlay_engine.h b/source/blender/draw/engines/overlay/overlay_engine.h
index 18ab7f1456e..a33ea17dc1e 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.h
+++ b/source/blender/draw/engines/overlay/overlay_engine.h
@@ -7,4 +7,12 @@
#pragma once
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern DrawEngineType draw_engine_overlay_type;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/draw/engines/overlay/overlay_extra.c b/source/blender/draw/engines/overlay/overlay_extra.cc
index 8211b2f0490..27afe49a17b 100644
--- a/source/blender/draw/engines/overlay/overlay_extra.c
+++ b/source/blender/draw/engines/overlay/overlay_extra.cc
@@ -38,7 +38,7 @@
#include "ED_view3d.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
#include "draw_common.h"
#include "draw_manager_text.h"
@@ -60,8 +60,8 @@ void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
DRW_PASS_CREATE(psl->extra_grid_ps, state | pd->clipping_state);
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
DRWShadingGroup *grp;
- struct GPUShader *sh = OVERLAY_shader_extra_grid();
- struct GPUTexture *tex = DRW_state_is_fbo() ? dtxl->depth : txl->dummy_depth_tx;
+ GPUShader *sh = OVERLAY_shader_extra_grid();
+ GPUTexture *tex = DRW_state_is_fbo() ? dtxl->depth : txl->dummy_depth_tx;
pd->extra_grid_grp = grp = DRW_shgroup_create(sh, psl->extra_grid_ps);
DRW_shgroup_uniform_texture(grp, "depthBuffer", tex);
@@ -71,15 +71,16 @@ void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
for (int i = 0; i < 2; i++) {
/* Non Meshes Pass (Camera, empties, lights ...) */
- struct GPUShader *sh;
- struct GPUVertFormat *format;
+ GPUShader *sh;
+ GPUVertFormat *format;
DRWShadingGroup *grp, *grp_sub;
OVERLAY_InstanceFormats *formats = OVERLAY_shader_instance_formats_get();
OVERLAY_ExtraCallBuffers *cb = &pd->extra_call_buffers[i];
DRWPass **p_extra_ps = &psl->extra_ps[i];
- DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT : 0;
+ DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT :
+ DRWState(0);
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
DRW_PASS_CREATE(*p_extra_ps, state | pd->clipping_state | infront_state);
@@ -194,23 +195,23 @@ void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
grp_sub = DRW_shgroup_create_sub(grp);
- DRW_shgroup_uniform_vec4_copy(grp_sub, "color", G_draw.block.color_active);
+ DRW_shgroup_uniform_vec4_copy(grp_sub, "ucolor", G_draw.block.color_active);
cb->center_active = BUF_POINT(grp_sub, format);
grp_sub = DRW_shgroup_create_sub(grp);
- DRW_shgroup_uniform_vec4_copy(grp_sub, "color", G_draw.block.color_select);
+ DRW_shgroup_uniform_vec4_copy(grp_sub, "ucolor", G_draw.block.color_select);
cb->center_selected = BUF_POINT(grp_sub, format);
grp_sub = DRW_shgroup_create_sub(grp);
- DRW_shgroup_uniform_vec4_copy(grp_sub, "color", G_draw.block.color_deselect);
+ DRW_shgroup_uniform_vec4_copy(grp_sub, "ucolor", G_draw.block.color_deselect);
cb->center_deselected = BUF_POINT(grp_sub, format);
grp_sub = DRW_shgroup_create_sub(grp);
- DRW_shgroup_uniform_vec4_copy(grp_sub, "color", G_draw.block.color_library_select);
+ DRW_shgroup_uniform_vec4_copy(grp_sub, "ucolor", G_draw.block.color_library_select);
cb->center_selected_lib = BUF_POINT(grp_sub, format);
grp_sub = DRW_shgroup_create_sub(grp);
- DRW_shgroup_uniform_vec4_copy(grp_sub, "color", G_draw.block.color_library);
+ DRW_shgroup_uniform_vec4_copy(grp_sub, "ucolor", G_draw.block.color_library);
cb->center_deselected_lib = BUF_POINT(grp_sub, format);
}
}
@@ -247,7 +248,7 @@ OVERLAY_ExtraCallBuffers *OVERLAY_extra_call_buffer_get(OVERLAY_Data *vedata, Ob
}
void OVERLAY_extra_loose_points(OVERLAY_ExtraCallBuffers *cb,
- struct GPUBatch *geom,
+ GPUBatch *geom,
const float mat[4][4],
const float color[4])
{
@@ -257,7 +258,7 @@ void OVERLAY_extra_loose_points(OVERLAY_ExtraCallBuffers *cb,
}
void OVERLAY_extra_wire(OVERLAY_ExtraCallBuffers *cb,
- struct GPUBatch *geom,
+ GPUBatch *geom,
const float mat[4][4],
const float color[4])
{
@@ -330,7 +331,7 @@ void OVERLAY_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
case OB_EMPTY_CONE:
case OB_ARROWS:
DRW_object_wire_theme_get(ob, view_layer, &color);
- OVERLAY_empty_shape(cb, ob->obmat, ob->empty_drawsize, ob->empty_drawtype, color);
+ OVERLAY_empty_shape(cb, ob->object_to_world, ob->empty_drawsize, ob->empty_drawtype, color);
break;
case OB_EMPTY_IMAGE:
OVERLAY_image_empty_cache_populate(vedata, ob);
@@ -352,7 +353,7 @@ static void OVERLAY_bounds(OVERLAY_ExtraCallBuffers *cb,
const BoundBox *bb = BKE_object_boundbox_get(ob);
BoundBox bb_local;
- if (bb == NULL) {
+ if (bb == nullptr) {
const float min[3] = {-1.0f, -1.0f, -1.0f}, max[3] = {1.0f, 1.0f, 1.0f};
BKE_boundbox_init_from_minmax(&bb_local, min, max);
bb = &bb_local;
@@ -371,7 +372,7 @@ static void OVERLAY_bounds(OVERLAY_ExtraCallBuffers *cb,
case OB_BOUND_BOX:
size_to_mat4(tmp, size);
copy_v3_v3(tmp[3], center);
- mul_m4_m4m4(tmp, ob->obmat, tmp);
+ mul_m4_m4m4(tmp, ob->object_to_world, tmp);
DRW_buffer_add_entry(cb->empty_cube, color, tmp);
break;
case OB_BOUND_SPHERE:
@@ -379,7 +380,7 @@ static void OVERLAY_bounds(OVERLAY_ExtraCallBuffers *cb,
size[1] = size[2] = size[0];
size_to_mat4(tmp, size);
copy_v3_v3(tmp[3], center);
- mul_m4_m4m4(tmp, ob->obmat, tmp);
+ mul_m4_m4m4(tmp, ob->object_to_world, tmp);
DRW_buffer_add_entry(cb->empty_sphere, color, tmp);
break;
case OB_BOUND_CYLINDER:
@@ -387,7 +388,7 @@ static void OVERLAY_bounds(OVERLAY_ExtraCallBuffers *cb,
size[1] = size[0];
size_to_mat4(tmp, size);
copy_v3_v3(tmp[3], center);
- mul_m4_m4m4(tmp, ob->obmat, tmp);
+ mul_m4_m4m4(tmp, ob->object_to_world, tmp);
DRW_buffer_add_entry(cb->empty_cylinder, color, tmp);
break;
case OB_BOUND_CONE:
@@ -398,7 +399,7 @@ static void OVERLAY_bounds(OVERLAY_ExtraCallBuffers *cb,
/* Cone batch has base at 0 and is pointing towards +Y. */
swap_v3_v3(tmp[1], tmp[2]);
tmp[3][2] -= size[2];
- mul_m4_m4m4(tmp, ob->obmat, tmp);
+ mul_m4_m4m4(tmp, ob->object_to_world, tmp);
DRW_buffer_add_entry(cb->empty_cone, color, tmp);
break;
case OB_BOUND_CAPSULE:
@@ -407,14 +408,14 @@ static void OVERLAY_bounds(OVERLAY_ExtraCallBuffers *cb,
scale_m4_fl(tmp, size[0]);
copy_v2_v2(tmp[3], center);
tmp[3][2] = center[2] + max_ff(0.0f, size[2] - size[0]);
- mul_m4_m4m4(final_mat, ob->obmat, tmp);
+ mul_m4_m4m4(final_mat, ob->object_to_world, tmp);
DRW_buffer_add_entry(cb->empty_capsule_cap, color, final_mat);
negate_v3(tmp[2]);
tmp[3][2] = center[2] - max_ff(0.0f, size[2] - size[0]);
- mul_m4_m4m4(final_mat, ob->obmat, tmp);
+ mul_m4_m4m4(final_mat, ob->object_to_world, tmp);
DRW_buffer_add_entry(cb->empty_capsule_cap, color, final_mat);
tmp[2][2] = max_ff(0.0f, size[2] * 2.0f - size[0] * 2.0f);
- mul_m4_m4m4(final_mat, ob->obmat, tmp);
+ mul_m4_m4m4(final_mat, ob->object_to_world, tmp);
DRW_buffer_add_entry(cb->empty_capsule_body, color, final_mat);
break;
}
@@ -443,17 +444,17 @@ static void OVERLAY_collision(OVERLAY_ExtraCallBuffers *cb, Object *ob, const fl
static void OVERLAY_texture_space(OVERLAY_ExtraCallBuffers *cb, Object *ob, const float *color)
{
- if (ob->data == NULL) {
+ if (ob->data == nullptr) {
return;
}
- ID *ob_data = ob->data;
- float *texcoloc = NULL;
- float *texcosize = NULL;
+ ID *ob_data = static_cast<ID *>(ob->data);
+ float *texcoloc = nullptr;
+ float *texcosize = nullptr;
switch (GS(ob_data->name)) {
case ID_ME:
- BKE_mesh_texspace_get_reference((Mesh *)ob_data, NULL, &texcoloc, &texcosize);
+ BKE_mesh_texspace_get_reference((Mesh *)ob_data, nullptr, &texcoloc, &texcosize);
break;
case ID_CU_LEGACY: {
Curve *cu = (Curve *)ob_data;
@@ -480,7 +481,7 @@ static void OVERLAY_texture_space(OVERLAY_ExtraCallBuffers *cb, Object *ob, cons
float mat[4][4];
- if (texcoloc != NULL && texcosize != NULL) {
+ if (texcoloc != nullptr && texcosize != nullptr) {
size_to_mat4(mat, texcosize);
copy_v3_v3(mat[3], texcoloc);
}
@@ -488,17 +489,17 @@ static void OVERLAY_texture_space(OVERLAY_ExtraCallBuffers *cb, Object *ob, cons
unit_m4(mat);
}
- mul_m4_m4m4(mat, ob->obmat, mat);
+ mul_m4_m4m4(mat, ob->object_to_world, mat);
DRW_buffer_add_entry(cb->empty_cube, color, mat);
}
static void OVERLAY_forcefield(OVERLAY_ExtraCallBuffers *cb, Object *ob, ViewLayer *view_layer)
{
- int theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
+ int theme_id = DRW_object_wire_theme_get(ob, view_layer, nullptr);
float *color = DRW_color_background_blend_get(theme_id);
PartDeflect *pd = ob->pd;
- Curve *cu = (ob->type == OB_CURVES_LEGACY) ? ob->data : NULL;
+ Curve *cu = (ob->type == OB_CURVES_LEGACY) ? static_cast<Curve *>(ob->data) : nullptr;
union {
float mat[4][4];
@@ -510,7 +511,7 @@ static void OVERLAY_forcefield(OVERLAY_ExtraCallBuffers *cb, Object *ob, ViewLay
};
} instdata;
- copy_m4_m4(instdata.mat, ob->obmat);
+ copy_m4_m4(instdata.mat, ob->object_to_world);
instdata.size_x = instdata.size_y = instdata.size_z = ob->empty_drawsize;
switch (pd->forcefield) {
@@ -529,17 +530,17 @@ static void OVERLAY_forcefield(OVERLAY_ExtraCallBuffers *cb, Object *ob, ViewLay
if (cu && (cu->flag & CU_PATH) && ob->runtime.curve_cache->anim_path_accum_length) {
instdata.size_x = instdata.size_y = instdata.size_z = pd->f_strength;
float pos[4];
- BKE_where_on_path(ob, 0.0f, pos, NULL, NULL, NULL, NULL);
- copy_v3_v3(instdata.pos, ob->obmat[3]);
+ BKE_where_on_path(ob, 0.0f, pos, nullptr, nullptr, nullptr, nullptr);
+ copy_v3_v3(instdata.pos, ob->object_to_world[3]);
translate_m4(instdata.mat, pos[0], pos[1], pos[2]);
DRW_buffer_add_entry(cb->field_curve, color, &instdata);
- BKE_where_on_path(ob, 1.0f, pos, NULL, NULL, NULL, NULL);
- copy_v3_v3(instdata.pos, ob->obmat[3]);
+ BKE_where_on_path(ob, 1.0f, pos, nullptr, nullptr, nullptr, nullptr);
+ copy_v3_v3(instdata.pos, ob->object_to_world[3]);
translate_m4(instdata.mat, pos[0], pos[1], pos[2]);
DRW_buffer_add_entry(cb->field_sphere_limit, color, &instdata);
/* Restore */
- copy_v3_v3(instdata.pos, ob->obmat[3]);
+ copy_v3_v3(instdata.pos, ob->object_to_world[3]);
}
break;
}
@@ -600,7 +601,7 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
const DRWContextState *draw_ctx = DRW_context_state_get();
ViewLayer *view_layer = draw_ctx->view_layer;
- Light *la = ob->data;
+ Light *la = static_cast<Light *>(ob->data);
float *color_p;
DRW_object_wire_theme_get(ob, view_layer, &color_p);
/* Remove the alpha. */
@@ -624,7 +625,7 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
};
} instdata;
- copy_m4_m4(instdata.mat, ob->obmat);
+ copy_m4_m4(instdata.mat, ob->object_to_world);
/* FIXME / TODO: clip_end has no meaning nowadays.
* In EEVEE, Only clip_sta is used shadow-mapping.
* Clip end is computed automatically based on light power.
@@ -644,7 +645,8 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
else if (la->type == LA_SPOT) {
/* Previous implementation was using the clipend distance as cone size.
* We cannot do this anymore so we use a fixed size of 10. (see T72871) */
- rescale_m4(instdata.mat, (float[3]){10.0f, 10.0f, 10.0f});
+ const float3 scale_vec = {10.0f, 10.0f, 10.0f};
+ rescale_m4(instdata.mat, scale_vec);
/* For cycles and eevee the spot attenuation is
* y = (1/(1 + x^2) - a)/((1 - a) b)
* We solve the case where spot attenuation y = 1 and y = 0
@@ -706,7 +708,7 @@ void OVERLAY_lightprobe_cache_populate(OVERLAY_Data *vedata, Object *ob)
};
} instdata;
- copy_m4_m4(instdata.mat, ob->obmat);
+ copy_m4_m4(instdata.mat, ob->object_to_world);
switch (prb->type) {
case LIGHTPROBE_TYPE_CUBE:
@@ -718,15 +720,15 @@ void OVERLAY_lightprobe_cache_populate(OVERLAY_Data *vedata, Object *ob)
if (show_influence) {
char shape = (prb->attenuation_type == LIGHTPROBE_SHAPE_BOX) ? OB_CUBE : OB_EMPTY_SPHERE;
float f = 1.0f - prb->falloff;
- OVERLAY_empty_shape(cb, ob->obmat, prb->distinf, shape, color_p);
- OVERLAY_empty_shape(cb, ob->obmat, prb->distinf * f, shape, color_p);
+ OVERLAY_empty_shape(cb, ob->object_to_world, prb->distinf, shape, color_p);
+ OVERLAY_empty_shape(cb, ob->object_to_world, prb->distinf * f, shape, color_p);
}
if (show_parallax) {
char shape = (prb->parallax_type == LIGHTPROBE_SHAPE_BOX) ? OB_CUBE : OB_EMPTY_SPHERE;
float dist = ((prb->flag & LIGHTPROBE_FLAG_CUSTOM_PARALLAX) != 0) ? prb->distpar :
prb->distinf;
- OVERLAY_empty_shape(cb, ob->obmat, dist, shape, color_p);
+ OVERLAY_empty_shape(cb, ob->object_to_world, dist, shape, color_p);
}
break;
case LIGHTPROBE_TYPE_GRID:
@@ -736,8 +738,8 @@ void OVERLAY_lightprobe_cache_populate(OVERLAY_Data *vedata, Object *ob)
if (show_influence) {
float f = 1.0f - prb->falloff;
- OVERLAY_empty_shape(cb, ob->obmat, 1.0 + prb->distinf, OB_CUBE, color_p);
- OVERLAY_empty_shape(cb, ob->obmat, 1.0 + prb->distinf * f, OB_CUBE, color_p);
+ OVERLAY_empty_shape(cb, ob->object_to_world, 1.0 + prb->distinf, OB_CUBE, color_p);
+ OVERLAY_empty_shape(cb, ob->object_to_world, 1.0 + prb->distinf * f, OB_CUBE, color_p);
}
/* Data dots */
@@ -756,7 +758,7 @@ void OVERLAY_lightprobe_cache_populate(OVERLAY_Data *vedata, Object *ob)
uint cell_count = prb->grid_resolution_x * prb->grid_resolution_y * prb->grid_resolution_z;
DRWShadingGroup *grp = DRW_shgroup_create_sub(vedata->stl->pd->extra_grid_grp);
DRW_shgroup_uniform_mat4_copy(grp, "gridModelMatrix", instdata.mat);
- DRW_shgroup_call_procedural_points(grp, NULL, cell_count);
+ DRW_shgroup_call_procedural_points(grp, nullptr, cell_count);
}
break;
case LIGHTPROBE_TYPE_PLANAR:
@@ -775,7 +777,7 @@ void OVERLAY_lightprobe_cache_populate(OVERLAY_Data *vedata, Object *ob)
zero_v3(instdata.mat[2]);
DRW_buffer_add_entry(cb->empty_cube, color_p, &instdata);
- normalize_m4_m4(instdata.mat, ob->obmat);
+ normalize_m4_m4(instdata.mat, ob->object_to_world);
OVERLAY_empty_shape(cb, instdata.mat, ob->empty_drawsize, OB_SINGLE_ARROW, color_p);
break;
}
@@ -795,7 +797,7 @@ void OVERLAY_speaker_cache_populate(OVERLAY_Data *vedata, Object *ob)
float *color_p;
DRW_object_wire_theme_get(ob, view_layer, &color_p);
- DRW_buffer_add_entry(cb->speaker, color_p, ob->obmat);
+ DRW_buffer_add_entry(cb->speaker, color_p, ob->object_to_world);
}
/** \} */
@@ -804,7 +806,7 @@ void OVERLAY_speaker_cache_populate(OVERLAY_Data *vedata, Object *ob)
/** \name Camera
* \{ */
-typedef union OVERLAY_CameraInstanceData {
+union OVERLAY_CameraInstanceData {
/* Pack render data into object matrix and object color. */
struct {
float color[4];
@@ -840,7 +842,7 @@ typedef union OVERLAY_CameraInstanceData {
float mist_end;
};
};
-} OVERLAY_CameraInstanceData;
+};
static void camera_view3d_reconstruction(
OVERLAY_ExtraCallBuffers *cb, Scene *scene, View3D *v3d, Object *ob, const float color[4])
@@ -849,7 +851,7 @@ static void camera_view3d_reconstruction(
const bool is_select = DRW_state_is_select();
MovieClip *clip = BKE_object_movieclip_get(scene, ob, false);
- if (clip == NULL) {
+ if (clip == nullptr) {
return;
}
@@ -888,7 +890,7 @@ static void camera_view3d_reconstruction(
float object_imat[4][4];
invert_m4_m4(object_imat, object_mat);
- mul_m4_m4m4(tracking_object_mat, ob->obmat, object_imat);
+ mul_m4_m4m4(tracking_object_mat, ob->object_to_world, object_imat);
}
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object);
@@ -944,7 +946,7 @@ static void camera_view3d_reconstruction(
}
if ((v3d->flag2 & V3D_SHOW_BUNDLENAME) && !is_select) {
- struct DRWTextStore *dt = DRW_text_cache_ensure();
+ DRWTextStore *dt = DRW_text_cache_ensure();
DRW_text_cache_add(dt,
bundle_mat[3],
@@ -985,7 +987,7 @@ static float camera_offaxis_shiftx_get(Scene *scene,
const OVERLAY_CameraInstanceData *instdata,
bool right_eye)
{
- Camera *cam = ob->data;
+ Camera *cam = static_cast<Camera *>(ob->data);
if (cam->stereo.convergence_mode == CAM_S3D_OFFAXIS) {
const char *viewnames[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
const float shiftx = BKE_camera_multiview_shift_x(&scene->r, ob, viewnames[right_eye]);
@@ -1007,7 +1009,7 @@ static void camera_stereoscopy_extra(OVERLAY_ExtraCallBuffers *cb,
const OVERLAY_CameraInstanceData *instdata)
{
OVERLAY_CameraInstanceData stereodata = *instdata;
- Camera *cam = ob->data;
+ Camera *cam = static_cast<Camera *>(ob->data);
const bool is_select = DRW_state_is_select();
const char *viewnames[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
@@ -1111,7 +1113,7 @@ void OVERLAY_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
Scene *scene = draw_ctx->scene;
RegionView3D *rv3d = draw_ctx->rv3d;
- Camera *cam = ob->data;
+ Camera *cam = static_cast<Camera *>(ob->data);
Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera);
const bool is_select = DRW_state_is_select();
const bool is_active = (ob == camera_object);
@@ -1130,14 +1132,17 @@ void OVERLAY_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
DRW_object_wire_theme_get(ob, view_layer, &color_p);
copy_v4_v4(instdata.color, color_p);
- normalize_m4_m4(instdata.mat, ob->obmat);
+ normalize_m4_m4(instdata.mat, ob->object_to_world);
/* BKE_camera_multiview_model_matrix already accounts for scale, don't do it here. */
if (is_selection_camera_stereo) {
copy_v3_fl(scale, 1.0f);
}
else {
- copy_v3_fl3(scale, len_v3(ob->obmat[0]), len_v3(ob->obmat[1]), len_v3(ob->obmat[2]));
+ copy_v3_fl3(scale,
+ len_v3(ob->object_to_world[0]),
+ len_v3(ob->object_to_world[1]),
+ len_v3(ob->object_to_world[2]));
/* Avoid division by 0. */
if (ELEM(0.0f, scale[0], scale[1], scale[2])) {
return;
@@ -1253,17 +1258,17 @@ static void OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers *cb,
if (ob->parent && (DRW_object_visibility_in_active_context(ob->parent) & OB_VISIBLE_SELF)) {
float *parent_pos = ob->runtime.parent_display_origin;
- OVERLAY_extra_line_dashed(cb, parent_pos, ob->obmat[3], relation_color);
+ OVERLAY_extra_line_dashed(cb, parent_pos, ob->object_to_world[3], relation_color);
}
/* Drawing the hook lines. */
- for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
+ for (ModifierData *md = static_cast<ModifierData *>(ob->modifiers.first); md; md = md->next) {
if (md->type == eModifierType_Hook) {
HookModifierData *hmd = (HookModifierData *)md;
float center[3];
- mul_v3_m4v3(center, ob->obmat, hmd->cent);
+ mul_v3_m4v3(center, ob->object_to_world, hmd->cent);
if (hmd->object) {
- OVERLAY_extra_line_dashed(cb, hmd->object->obmat[3], center, relation_color);
+ OVERLAY_extra_line_dashed(cb, hmd->object->object_to_world[3], center, relation_color);
}
OVERLAY_extra_point(cb, center, relation_color);
}
@@ -1273,10 +1278,12 @@ static void OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers *cb,
Object *rbc_ob1 = ob->rigidbody_constraint->ob1;
Object *rbc_ob2 = ob->rigidbody_constraint->ob2;
if (rbc_ob1 && (DRW_object_visibility_in_active_context(rbc_ob1) & OB_VISIBLE_SELF)) {
- OVERLAY_extra_line_dashed(cb, rbc_ob1->obmat[3], ob->obmat[3], relation_color);
+ OVERLAY_extra_line_dashed(
+ cb, rbc_ob1->object_to_world[3], ob->object_to_world[3], relation_color);
}
if (rbc_ob2 && (DRW_object_visibility_in_active_context(rbc_ob2) & OB_VISIBLE_SELF)) {
- OVERLAY_extra_line_dashed(cb, rbc_ob2->obmat[3], ob->obmat[3], relation_color);
+ OVERLAY_extra_line_dashed(
+ cb, rbc_ob2->object_to_world[3], ob->object_to_world[3], relation_color);
}
}
@@ -1286,14 +1293,14 @@ static void OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers *cb,
bConstraintOb *cob;
ListBase *list = &ob->constraints;
- cob = BKE_constraints_make_evalob(depsgraph, scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+ cob = BKE_constraints_make_evalob(depsgraph, scene, ob, nullptr, CONSTRAINT_OBTYPE_OBJECT);
- for (curcon = list->first; curcon; curcon = curcon->next) {
+ for (curcon = static_cast<bConstraint *>(list->first); curcon; curcon = curcon->next) {
if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_OBJECTSOLVER)) {
/* special case for object solver and follow track constraints because they don't fill
* constraint targets properly (design limitation -- scene is needed for their target
* but it can't be accessed from get_targets callback) */
- Object *camob = NULL;
+ Object *camob = nullptr;
if (curcon->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
bFollowTrackConstraint *data = (bFollowTrackConstraint *)curcon->data;
@@ -1305,19 +1312,20 @@ static void OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers *cb,
}
if (camob) {
- OVERLAY_extra_line_dashed(cb, camob->obmat[3], ob->obmat[3], constraint_color);
+ OVERLAY_extra_line_dashed(
+ cb, camob->object_to_world[3], ob->object_to_world[3], constraint_color);
}
}
else {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon);
- ListBase targets = {NULL, NULL};
+ ListBase targets = {nullptr, nullptr};
if ((curcon->ui_expand_flag & (1 << 0)) && BKE_constraint_targets_get(curcon, &targets)) {
bConstraintTarget *ct;
BKE_constraint_custom_object_space_init(cob, curcon);
- for (ct = targets.first; ct; ct = ct->next) {
+ for (ct = static_cast<bConstraintTarget *>(targets.first); ct; ct = ct->next) {
/* calculate target's matrix */
if (ct->flag & CONSTRAINT_TAR_CUSTOM_SPACE) {
copy_m4_m4(ct->matrix, cob->space_obj_world_matrix);
@@ -1328,14 +1336,14 @@ static void OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers *cb,
else {
unit_m4(ct->matrix);
}
- OVERLAY_extra_line_dashed(cb, ct->matrix[3], ob->obmat[3], constraint_color);
+ OVERLAY_extra_line_dashed(cb, ct->matrix[3], ob->object_to_world[3], constraint_color);
}
- BKE_constraint_targets_flush(curcon, &targets, 1);
+ BKE_constraint_targets_flush(curcon, &targets, true);
}
}
}
- /* NOTE: Don't use BKE_constraints_clear_evalob here as that will reset ob->constinv. */
+ /* NOTE: Don't use #BKE_constraints_clear_evalob here as that will reset `ob->constinv`. */
MEM_freeN(cob);
}
}
@@ -1385,7 +1393,7 @@ static void OVERLAY_volume_extra(OVERLAY_ExtraCallBuffers *cb,
copy_v3_v3(voxel_cubemat[3], min);
/* move small cube into the domain (otherwise its centered on vertex of domain object) */
translate_m4(voxel_cubemat, 1.0f, 1.0f, 1.0f);
- mul_m4_m4m4(voxel_cubemat, ob->obmat, voxel_cubemat);
+ mul_m4_m4m4(voxel_cubemat, ob->object_to_world, voxel_cubemat);
DRW_buffer_add_entry(cb->empty_cube, color, voxel_cubemat);
}
@@ -1394,7 +1402,7 @@ static void OVERLAY_volume_extra(OVERLAY_ExtraCallBuffers *cb,
if (fds->axis_slice_method == AXIS_SLICE_SINGLE) {
float viewinv[4][4];
- DRW_view_viewmat_get(NULL, viewinv, true);
+ DRW_view_viewmat_get(nullptr, viewinv, true);
const int axis = (fds->slice_axis == SLICE_AXIS_AUTO) ? axis_dominant_v3_single(viewinv[2]) :
fds->slice_axis - 1;
@@ -1485,32 +1493,33 @@ static void OVERLAY_volume_extra(OVERLAY_ExtraCallBuffers *cb,
static void OVERLAY_object_center(OVERLAY_ExtraCallBuffers *cb,
Object *ob,
OVERLAY_PrivateData *pd,
+ const Scene *scene,
ViewLayer *view_layer)
{
const bool is_library = ID_REAL_USERS(&ob->id) > 1 || ID_IS_LINKED(ob);
-
+ BKE_view_layer_synced_ensure(scene, view_layer);
if (ob == BKE_view_layer_active_object_get(view_layer)) {
- DRW_buffer_add_entry(cb->center_active, ob->obmat[3]);
+ DRW_buffer_add_entry(cb->center_active, ob->object_to_world[3]);
}
else if (ob->base_flag & BASE_SELECTED) {
DRWCallBuffer *cbuf = (is_library) ? cb->center_selected_lib : cb->center_selected;
- DRW_buffer_add_entry(cbuf, ob->obmat[3]);
+ DRW_buffer_add_entry(cbuf, ob->object_to_world[3]);
}
else if (pd->v3d_flag & V3D_DRAW_CENTERS) {
DRWCallBuffer *cbuf = (is_library) ? cb->center_deselected_lib : cb->center_deselected;
- DRW_buffer_add_entry(cbuf, ob->obmat[3]);
+ DRW_buffer_add_entry(cbuf, ob->object_to_world[3]);
}
}
static void OVERLAY_object_name(Object *ob, int theme_id)
{
- struct DRWTextStore *dt = DRW_text_cache_ensure();
+ DRWTextStore *dt = DRW_text_cache_ensure();
uchar color[4];
/* Color Management: Exception here as texts are drawn in sRGB space directly. */
UI_GetThemeColor4ubv(theme_id, color);
DRW_text_cache_add(dt,
- ob->obmat[3],
+ ob->object_to_world[3],
ob->id.name + 2,
strlen(ob->id.name + 2),
10,
@@ -1526,7 +1535,7 @@ void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob)
const DRWContextState *draw_ctx = DRW_context_state_get();
ViewLayer *view_layer = draw_ctx->view_layer;
Scene *scene = draw_ctx->scene;
- ModifierData *md = NULL;
+ ModifierData *md = nullptr;
const bool is_select_mode = DRW_state_is_select();
const bool is_paint_mode = (draw_ctx->object_mode &
@@ -1549,8 +1558,8 @@ void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob)
/* Don't show fluid domain overlay extras outside of cache range. */
const bool draw_volume = !from_dupli &&
(md = BKE_modifiers_findby_type(ob, eModifierType_Fluid)) &&
- (BKE_modifier_is_enabled(scene, md, eModifierMode_Realtime)) &&
- (((FluidModifierData *)md)->domain != NULL) &&
+ BKE_modifier_is_enabled(scene, md, eModifierMode_Realtime) &&
+ (((FluidModifierData *)md)->domain != nullptr) &&
(scene->r.cfra >=
(((FluidModifierData *)md)->domain->cache_frame_start)) &&
(scene->r.cfra <= (((FluidModifierData *)md)->domain->cache_frame_end));
@@ -1568,12 +1577,12 @@ void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob)
/* Helpers for when we're transforming origins. */
if (draw_xform) {
const float color_xform[4] = {0.15f, 0.15f, 0.15f, 0.7f};
- DRW_buffer_add_entry(cb->origin_xform, color_xform, ob->obmat);
+ DRW_buffer_add_entry(cb->origin_xform, color_xform, ob->object_to_world);
}
/* don't show object extras in set's */
if (!from_dupli) {
if (draw_obcenters) {
- OVERLAY_object_center(cb, ob, pd, view_layer);
+ OVERLAY_object_center(cb, ob, pd, scene, view_layer);
}
if (draw_relations) {
OVERLAY_relationship_lines(cb, draw_ctx->depsgraph, draw_ctx->scene, ob);
@@ -1584,11 +1593,11 @@ void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob)
if (draw_texspace) {
OVERLAY_texture_space(cb, ob, color);
}
- if (ob->rigidbody_object != NULL) {
+ if (ob->rigidbody_object != nullptr) {
OVERLAY_collision(cb, ob, color);
}
if (ob->dtx & OB_AXIS) {
- DRW_buffer_add_entry(cb->empty_axes, color, ob->obmat);
+ DRW_buffer_add_entry(cb->empty_axes, color, ob->object_to_world);
}
if (draw_volume) {
OVERLAY_volume_extra(cb, vedata, ob, md, scene, color);
diff --git a/source/blender/draw/engines/overlay/overlay_facing.c b/source/blender/draw/engines/overlay/overlay_facing.cc
index bf06600eb33..44dab0f0a42 100644
--- a/source/blender/draw/engines/overlay/overlay_facing.c
+++ b/source/blender/draw/engines/overlay/overlay_facing.cc
@@ -8,9 +8,9 @@
#include "BKE_paint.h"
#include "DRW_render.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
-void OVERLAY_facing_init(OVERLAY_Data *UNUSED(vedata))
+void OVERLAY_facing_init(OVERLAY_Data * /*vedata*/)
{
}
@@ -43,12 +43,12 @@ void OVERLAY_facing_cache_populate(OVERLAY_Data *vedata, Object *ob)
}
const DRWContextState *draw_ctx = DRW_context_state_get();
- const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) &&
+ const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->rv3d) &&
!DRW_state_is_image_render();
const bool is_xray = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
if (use_sculpt_pbvh) {
- DRW_shgroup_call_sculpt(pd->facing_grp[is_xray], ob, false, false);
+ DRW_shgroup_call_sculpt(pd->facing_grp[is_xray], ob, false, false, false, false, false);
}
else {
struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
diff --git a/source/blender/draw/engines/overlay/overlay_fade.c b/source/blender/draw/engines/overlay/overlay_fade.cc
index 056e02a04e1..b9523a4eac9 100644
--- a/source/blender/draw/engines/overlay/overlay_fade.c
+++ b/source/blender/draw/engines/overlay/overlay_fade.cc
@@ -10,9 +10,9 @@
#include "ED_view3d.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
-void OVERLAY_fade_init(OVERLAY_Data *UNUSED(vedata))
+void OVERLAY_fade_init(OVERLAY_Data * /*vedata*/)
{
}
@@ -36,7 +36,7 @@ void OVERLAY_fade_cache_init(OVERLAY_Data *vedata)
if (draw_ctx->v3d->shading.background_type == V3D_SHADING_BACKGROUND_THEME) {
srgb_to_linearrgb_v4(color, color);
}
- DRW_shgroup_uniform_vec4_copy(pd->fade_grp[i], "color", color);
+ DRW_shgroup_uniform_vec4_copy(pd->fade_grp[i], "ucolor", color);
}
if (!pd->use_in_front) {
@@ -53,12 +53,12 @@ void OVERLAY_fade_cache_populate(OVERLAY_Data *vedata, Object *ob)
}
const DRWContextState *draw_ctx = DRW_context_state_get();
- const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) &&
+ const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->rv3d) &&
!DRW_state_is_image_render();
const bool is_xray = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
if (use_sculpt_pbvh) {
- DRW_shgroup_call_sculpt(pd->fade_grp[is_xray], ob, false, false);
+ DRW_shgroup_call_sculpt(pd->fade_grp[is_xray], ob, false, false, false, false, false);
}
else {
struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
diff --git a/source/blender/draw/engines/overlay/overlay_gpencil.c b/source/blender/draw/engines/overlay/overlay_gpencil.cc
index 9531b0dd983..f5988d91e72 100644
--- a/source/blender/draw/engines/overlay/overlay_gpencil.c
+++ b/source/blender/draw/engines/overlay/overlay_gpencil.cc
@@ -17,7 +17,7 @@
#include "ED_view3d.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
#include "draw_common.h"
#include "draw_manager_text.h"
@@ -30,22 +30,22 @@ void OVERLAY_edit_gpencil_cache_init(OVERLAY_Data *vedata)
DRWShadingGroup *grp;
/* Default: Display nothing. */
- pd->edit_gpencil_points_grp = NULL;
- pd->edit_gpencil_wires_grp = NULL;
- psl->edit_gpencil_ps = NULL;
+ pd->edit_gpencil_points_grp = nullptr;
+ pd->edit_gpencil_wires_grp = nullptr;
+ psl->edit_gpencil_ps = nullptr;
- pd->edit_gpencil_curve_handle_grp = NULL;
- pd->edit_gpencil_curve_points_grp = NULL;
- psl->edit_gpencil_curve_ps = NULL;
+ pd->edit_gpencil_curve_handle_grp = nullptr;
+ pd->edit_gpencil_curve_points_grp = nullptr;
+ psl->edit_gpencil_curve_ps = nullptr;
const DRWContextState *draw_ctx = DRW_context_state_get();
View3D *v3d = draw_ctx->v3d;
Object *ob = draw_ctx->obact;
- bGPdata *gpd = ob ? (bGPdata *)ob->data : NULL;
+ bGPdata *gpd = ob ? (bGPdata *)ob->data : nullptr;
Scene *scene = draw_ctx->scene;
ToolSettings *ts = scene->toolsettings;
- if (gpd == NULL || ob->type != OB_GPENCIL) {
+ if (gpd == nullptr || ob->type != OB_GPENCIL) {
return;
}
@@ -96,7 +96,7 @@ void OVERLAY_edit_gpencil_cache_init(OVERLAY_Data *vedata)
(GPENCIL_EDIT_MODE(gpd) &&
(ts->gpencil_selectmode_edit != GP_SELECTMODE_STROKE));
- if ((!GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd)) &&
+ if (!GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd) &&
((!GPENCIL_VERTEX_MODE(gpd) && !GPENCIL_PAINT_MODE(gpd)) || use_vertex_mask)) {
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
DRW_STATE_BLEND_ALPHA;
@@ -169,14 +169,14 @@ void OVERLAY_edit_gpencil_cache_init(OVERLAY_Data *vedata)
sh = OVERLAY_shader_edit_gpencil_guide_point();
grp = DRW_shgroup_create(sh, psl->edit_gpencil_gizmos_ps);
- if (gpd->runtime.cp_points != NULL) {
+ if (gpd->runtime.cp_points != nullptr) {
for (int i = 0; i < gpd->runtime.tot_cp_points; i++) {
bGPDcontrolpoint *cp = &gpd->runtime.cp_points[i];
grp = DRW_shgroup_create_sub(grp);
DRW_shgroup_uniform_vec3_copy(grp, "pPosition", &cp->x);
DRW_shgroup_uniform_float_copy(grp, "pSize", cp->size * 0.8f * G_draw.block.size_pixel);
DRW_shgroup_uniform_vec4_copy(grp, "pColor", cp->color);
- DRW_shgroup_call_procedural_points(grp, NULL, 1);
+ DRW_shgroup_call_procedural_points(grp, nullptr, 1);
}
}
@@ -187,7 +187,7 @@ void OVERLAY_edit_gpencil_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_vec3_copy(grp, "pPosition", ts->gp_sculpt.guide.location);
}
else if (ts->gp_sculpt.guide.reference_point == GP_GUIDE_REF_OBJECT &&
- ts->gp_sculpt.guide.reference_object != NULL) {
+ ts->gp_sculpt.guide.reference_object != nullptr) {
UI_GetThemeColor4fv(TH_GIZMO_SECONDARY, color);
DRW_shgroup_uniform_vec3_copy(grp, "pPosition", ts->gp_sculpt.guide.reference_object->loc);
}
@@ -197,7 +197,7 @@ void OVERLAY_edit_gpencil_cache_init(OVERLAY_Data *vedata)
}
DRW_shgroup_uniform_vec4_copy(grp, "pColor", color);
DRW_shgroup_uniform_float_copy(grp, "pSize", 8.0f * G_draw.block.size_pixel);
- DRW_shgroup_call_procedural_points(grp, NULL, 1);
+ DRW_shgroup_call_procedural_points(grp, nullptr, 1);
}
}
}
@@ -210,12 +210,12 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
DRWShadingGroup *grp;
/* Default: Display nothing. */
- psl->gpencil_canvas_ps = NULL;
+ psl->gpencil_canvas_ps = nullptr;
const DRWContextState *draw_ctx = DRW_context_state_get();
View3D *v3d = draw_ctx->v3d;
Object *ob = draw_ctx->obact;
- bGPdata *gpd = ob ? (bGPdata *)ob->data : NULL;
+ bGPdata *gpd = ob ? (bGPdata *)ob->data : nullptr;
Scene *scene = draw_ctx->scene;
ToolSettings *ts = scene->toolsettings;
const View3DCursor *cursor = &scene->cursor;
@@ -223,7 +223,7 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
pd->edit_curve.show_handles = v3d->overlay.handle_display != CURVE_HANDLE_NONE;
pd->edit_curve.handle_display = v3d->overlay.handle_display;
- if (gpd == NULL || ob->type != OB_GPENCIL) {
+ if (gpd == nullptr || ob->type != OB_GPENCIL) {
return;
}
@@ -234,7 +234,7 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
const bool grid_xray = (v3d->gp_flag & V3D_GP_SHOW_GRID_XRAY);
if (show_grid && show_overlays) {
- const char *grid_unit = NULL;
+ const char *grid_unit = nullptr;
float mat[4][4];
float col_grid[4];
float size[2];
@@ -243,11 +243,11 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
copy_v3_v3(col_grid, gpd->grid.color);
col_grid[3] = max_ff(v3d->overlay.gpencil_grid_opacity, 0.01f);
- copy_m4_m4(mat, ob->obmat);
+ copy_m4_m4(mat, ob->object_to_world);
/* Rotate and scale except align to cursor. */
bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
- if (gpl != NULL) {
+ if (gpl != nullptr) {
if (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR) {
float matrot[3][3];
copy_m3_m4(matrot, gpl->layer_mat);
@@ -267,12 +267,14 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
case GP_LOCKAXIS_Z:
/* Default. */
break;
- case GP_LOCKAXIS_CURSOR:
- loc_eul_size_to_mat4(mat, cursor->location, cursor->rotation_euler, (float[3]){1, 1, 1});
+ case GP_LOCKAXIS_CURSOR: {
+ const float3 size_vec = {1.0f, 1.0f, 1.0f};
+ loc_eul_size_to_mat4(mat, cursor->location, cursor->rotation_euler, size_vec);
break;
+ }
case GP_LOCKAXIS_VIEW:
/* view aligned */
- DRW_view_viewmat_get(NULL, viewinv, true);
+ DRW_view_viewmat_get(nullptr, viewinv, true);
copy_v3_v3(mat[0], viewinv[0]);
copy_v3_v3(mat[1], viewinv[1]);
break;
@@ -284,15 +286,16 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
copy_v3_v3(mat[3], cursor->location);
}
else if (ts->gpencil_v3d_align & GP_PROJECT_VIEWSPACE) {
- copy_v3_v3(mat[3], ob->obmat[3]);
+ copy_v3_v3(mat[3], ob->object_to_world[3]);
}
translate_m4(mat, gpd->grid.offset[0], gpd->grid.offset[1], 0.0f);
mul_v2_v2fl(size, gpd->grid.scale, 2.0f * ED_scene_grid_scale(scene, &grid_unit));
- rescale_m4(mat, (float[3]){size[0], size[1], 0.0f});
+ const float3 scale_vec = {size[0], size[1], 0.0f};
+ rescale_m4(mat, scale_vec);
/* Apply layer loc transform, except cursor mode. */
- if ((gpl != NULL) && (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
+ if ((gpl != nullptr) && (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
add_v3_v3(mat[3], gpl->layer_mat[3]);
}
@@ -312,7 +315,7 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_vec3_copy(grp, "yAxis", mat[1]);
DRW_shgroup_uniform_vec3_copy(grp, "origin", mat[3]);
DRW_shgroup_uniform_int_copy(grp, "halfLineCount", line_count / 2);
- DRW_shgroup_call_procedural_lines(grp, NULL, line_count);
+ DRW_shgroup_call_procedural_lines(grp, nullptr, line_count);
}
}
@@ -361,19 +364,19 @@ static void OVERLAY_edit_gpencil_cache_populate(OVERLAY_Data *vedata, Object *ob
}
}
-static void overlay_gpencil_draw_stroke_color_name(bGPDlayer *UNUSED(gpl),
- bGPDframe *UNUSED(gpf),
+static void overlay_gpencil_draw_stroke_color_name(bGPDlayer * /*gpl*/,
+ bGPDframe * /*gpf*/,
bGPDstroke *gps,
void *thunk)
{
Object *ob = (Object *)thunk;
Material *ma = BKE_object_material_get_eval(ob, gps->mat_nr + 1);
- if (ma == NULL) {
+ if (ma == nullptr) {
return;
}
MaterialGPencilStyle *gp_style = ma->gp_style;
/* skip stroke if it doesn't have any valid data */
- if ((gps->points == NULL) || (gps->totpoints < 1) || (gp_style == NULL)) {
+ if ((gps->points == nullptr) || (gps->totpoints < 1) || (gp_style == nullptr)) {
return;
}
/* check if the color is visible */
@@ -389,12 +392,12 @@ static void overlay_gpencil_draw_stroke_color_name(bGPDlayer *UNUSED(gpl),
const DRWContextState *draw_ctx = DRW_context_state_get();
ViewLayer *view_layer = draw_ctx->view_layer;
- int theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
+ int theme_id = DRW_object_wire_theme_get(ob, view_layer, nullptr);
uchar color[4];
UI_GetThemeColor4ubv(theme_id, color);
float fpt[3];
- mul_v3_m4v3(fpt, ob->obmat, &pt->x);
+ mul_v3_m4v3(fpt, ob->object_to_world, &pt->x);
struct DRWTextStore *dt = DRW_text_cache_ensure();
DRW_text_cache_add(dt,
@@ -417,7 +420,7 @@ static void OVERLAY_gpencil_color_names(Object *ob)
int cfra = DEG_get_ctime(draw_ctx->depsgraph);
BKE_gpencil_visible_stroke_advanced_iter(
- NULL, ob, NULL, overlay_gpencil_draw_stroke_color_name, ob, false, cfra);
+ nullptr, ob, nullptr, overlay_gpencil_draw_stroke_color_name, ob, false, cfra);
}
void OVERLAY_gpencil_cache_populate(OVERLAY_Data *vedata, Object *ob)
@@ -426,7 +429,7 @@ void OVERLAY_gpencil_cache_populate(OVERLAY_Data *vedata, Object *ob)
View3D *v3d = draw_ctx->v3d;
bGPdata *gpd = (bGPdata *)ob->data;
- if (gpd == NULL) {
+ if (gpd == nullptr) {
return;
}
diff --git a/source/blender/draw/engines/overlay/overlay_grid.c b/source/blender/draw/engines/overlay/overlay_grid.cc
index e424f49455b..7c221e67691 100644
--- a/source/blender/draw/engines/overlay/overlay_grid.c
+++ b/source/blender/draw/engines/overlay/overlay_grid.cc
@@ -17,7 +17,7 @@
#include "UI_resources.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
BLI_STATIC_ASSERT(SI_GRID_STEPS_LEN == OVERLAY_GRID_STEPS_LEN, "")
@@ -31,10 +31,12 @@ void OVERLAY_grid_init(OVERLAY_Data *vedata)
float *zplane_axes = pd->grid.zplane_axes;
float grid_steps[SI_GRID_STEPS_LEN] = {
0.001f, 0.01f, 0.1f, 1.0f, 10.0f, 100.0f, 1000.0f, 10000.0f};
- OVERLAY_GridBits grid_flag = 0, zneg_flag = 0, zpos_flag = 0;
+ float grid_steps_y[SI_GRID_STEPS_LEN] = {0.0f}; /* When zero, use value from grid_steps. */
+ OVERLAY_GridBits grid_flag = OVERLAY_GridBits(0), zneg_flag = OVERLAY_GridBits(0),
+ zpos_flag = OVERLAY_GridBits(0);
grid->line_size = max_ff(0.0f, U.pixelsize - 1.0f) * 0.5f;
/* Default, nothing is drawn. */
- pd->grid.grid_flag = pd->grid.zneg_flag = pd->grid.zpos_flag = 0;
+ pd->grid.grid_flag = pd->grid.zneg_flag = pd->grid.zpos_flag = OVERLAY_GridBits(0);
if (pd->space_type == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
@@ -49,25 +51,30 @@ void OVERLAY_grid_init(OVERLAY_Data *vedata)
true;
if (background_enabled) {
grid_flag = GRID_BACK | PLANE_IMAGE;
+ if (sima->flag & SI_GRID_OVER_IMAGE) {
+ grid_flag = PLANE_IMAGE;
+ }
}
const bool draw_grid = is_uv_edit || !ED_space_image_has_buffer(sima);
if (background_enabled && draw_grid) {
grid_flag |= SHOW_GRID;
- if (is_uv_edit && (sima->flag & SI_CUSTOM_GRID) != 0) {
- grid_flag |= CUSTOM_GRID;
+ if (is_uv_edit) {
+ if (sima->grid_shape_source != SI_GRID_SHAPE_DYNAMIC) {
+ grid_flag |= CUSTOM_GRID;
+ }
}
}
grid->distance = 1.0f;
copy_v3_fl3(grid->size, 1.0f, 1.0f, 1.0f);
if (is_uv_edit) {
- grid->size[0] = (float)sima->tile_grid_shape[0];
- grid->size[1] = (float)sima->tile_grid_shape[1];
+ grid->size[0] = float(sima->tile_grid_shape[0]);
+ grid->size[1] = float(sima->tile_grid_shape[1]);
}
grid->zoom_factor = ED_space_image_zoom_level(v2d, SI_GRID_STEPS_LEN);
- ED_space_image_grid_steps(sima, grid_steps, SI_GRID_STEPS_LEN);
+ ED_space_image_grid_steps(sima, grid_steps, grid_steps_y, SI_GRID_STEPS_LEN);
}
else {
/* SPACE_VIEW3D */
@@ -88,10 +95,10 @@ void OVERLAY_grid_init(OVERLAY_Data *vedata)
float viewinv[4][4], wininv[4][4];
float viewmat[4][4], winmat[4][4];
- DRW_view_winmat_get(NULL, winmat, false);
- DRW_view_winmat_get(NULL, wininv, true);
- DRW_view_viewmat_get(NULL, viewmat, false);
- DRW_view_viewmat_get(NULL, viewinv, true);
+ DRW_view_winmat_get(nullptr, winmat, false);
+ DRW_view_winmat_get(nullptr, wininv, true);
+ DRW_view_viewmat_get(nullptr, viewmat, false);
+ DRW_view_viewmat_get(nullptr, viewinv, true);
/* If perspective view or non-axis aligned view. */
if (winmat[3][3] == 0.0f || rv3d->view == RV3D_VIEW_USER) {
@@ -117,9 +124,9 @@ void OVERLAY_grid_init(OVERLAY_Data *vedata)
}
}
- grid_axes[0] = (float)((grid_flag & (PLANE_XZ | PLANE_XY)) != 0);
- grid_axes[1] = (float)((grid_flag & (PLANE_YZ | PLANE_XY)) != 0);
- grid_axes[2] = (float)((grid_flag & (PLANE_YZ | PLANE_XZ)) != 0);
+ grid_axes[0] = float((grid_flag & (PLANE_XZ | PLANE_XY)) != 0);
+ grid_axes[1] = float((grid_flag & (PLANE_YZ | PLANE_XY)) != 0);
+ grid_axes[2] = float((grid_flag & (PLANE_YZ | PLANE_XZ)) != 0);
/* Z axis if needed */
if (((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) && show_axis_z) {
@@ -139,8 +146,8 @@ void OVERLAY_grid_init(OVERLAY_Data *vedata)
zneg_flag = zpos_flag;
- /* Persp : If camera is below floor plane, we switch clipping
- * Ortho : If eye vector is looking up, we switch clipping */
+ /* Perspective: If camera is below floor plane, we switch clipping.
+ * Orthographic: If eye vector is looking up, we switch clipping. */
if (((winmat[3][3] == 0.0f) && (campos[2] > 0.0f)) ||
((winmat[3][3] != 0.0f) && (zvec[2] < 0.0f))) {
zpos_flag |= CLIP_ZPOS;
@@ -151,9 +158,9 @@ void OVERLAY_grid_init(OVERLAY_Data *vedata)
zneg_flag |= CLIP_ZPOS;
}
- zplane_axes[0] = (float)((zpos_flag & (PLANE_XZ | PLANE_XY)) != 0);
- zplane_axes[1] = (float)((zpos_flag & (PLANE_YZ | PLANE_XY)) != 0);
- zplane_axes[2] = (float)((zpos_flag & (PLANE_YZ | PLANE_XZ)) != 0);
+ zplane_axes[0] = float((zpos_flag & (PLANE_XZ | PLANE_XY)) != 0);
+ zplane_axes[1] = float((zpos_flag & (PLANE_YZ | PLANE_XY)) != 0);
+ zplane_axes[2] = float((zpos_flag & (PLANE_YZ | PLANE_XZ)) != 0);
}
else {
zneg_flag = zpos_flag = CLIP_ZNEG | CLIP_ZPOS;
@@ -196,6 +203,7 @@ void OVERLAY_grid_init(OVERLAY_Data *vedata)
/* Convert to UBO alignment. */
for (int i = 0; i < SI_GRID_STEPS_LEN; i++) {
grid->steps[i][0] = grid_steps[i];
+ grid->steps[i][1] = (grid_steps_y[i] != 0.0f) ? grid_steps_y[i] : grid_steps[i];
}
pd->grid.grid_flag = grid_flag;
pd->grid.zneg_flag = zneg_flag;
@@ -211,13 +219,13 @@ void OVERLAY_grid_cache_init(OVERLAY_Data *ved)
OVERLAY_PassList *psl = ved->psl;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- psl->grid_ps = NULL;
+ psl->grid_ps = nullptr;
if ((pd->grid.grid_flag == 0 && pd->grid.zpos_flag == 0) || !DRW_state_is_fbo()) {
return;
}
- if (ved->instance->grid_ubo == NULL) {
+ if (ved->instance->grid_ubo == nullptr) {
ved->instance->grid_ubo = GPU_uniformbuf_create(sizeof(OVERLAY_GridData));
}
GPU_uniformbuf_update(ved->instance->grid_ubo, &pd->grid_data);
@@ -257,21 +265,21 @@ void OVERLAY_grid_cache_init(OVERLAY_Data *ved)
DRW_shgroup_uniform_int_copy(grp, "grid_flag", pd->grid.zneg_flag);
DRW_shgroup_uniform_vec3_copy(grp, "plane_axes", pd->grid.zplane_axes);
if (pd->grid.zneg_flag & SHOW_AXIS_Z) {
- DRW_shgroup_call(grp, geom, NULL);
+ DRW_shgroup_call(grp, geom, nullptr);
}
grp = DRW_shgroup_create_sub(grp);
DRW_shgroup_uniform_int_copy(grp, "grid_flag", pd->grid.grid_flag);
DRW_shgroup_uniform_vec3_copy(grp, "plane_axes", pd->grid.grid_axes);
if (pd->grid.grid_flag) {
- DRW_shgroup_call(grp, geom, NULL);
+ DRW_shgroup_call(grp, geom, nullptr);
}
grp = DRW_shgroup_create_sub(grp);
DRW_shgroup_uniform_int_copy(grp, "grid_flag", pd->grid.zpos_flag);
DRW_shgroup_uniform_vec3_copy(grp, "plane_axes", pd->grid.zplane_axes);
if (pd->grid.zpos_flag & SHOW_AXIS_Z) {
- DRW_shgroup_call(grp, geom, NULL);
+ DRW_shgroup_call(grp, geom, nullptr);
}
}
@@ -284,7 +292,7 @@ void OVERLAY_grid_cache_init(OVERLAY_Data *ved)
/* add wire border */
GPUShader *sh = OVERLAY_shader_grid_image();
DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->grid_ps);
- DRW_shgroup_uniform_vec4_copy(grp, "color", theme_color);
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", theme_color);
unit_m4(mat);
for (int x = 0; x < grid->size[0]; x++) {
mat[3][0] = x;
diff --git a/source/blender/draw/engines/overlay/overlay_image.c b/source/blender/draw/engines/overlay/overlay_image.cc
index 3e9c05bb59f..7b99bd6bd18 100644
--- a/source/blender/draw/engines/overlay/overlay_image.c
+++ b/source/blender/draw/engines/overlay/overlay_image.cc
@@ -23,7 +23,7 @@
#include "IMB_imbuf_types.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_image_init(OVERLAY_Data *vedata)
{
@@ -99,10 +99,10 @@ static eStereoViews camera_background_images_stereo_eye(const Scene *scene, cons
}
if (v3d->stereo3d_camera != STEREO_3D_ID) {
/* show only left or right camera */
- return v3d->stereo3d_camera;
+ return eStereoViews(v3d->stereo3d_camera);
}
- return v3d->multiview_eye;
+ return eStereoViews(v3d->multiview_eye);
}
static void camera_background_images_stereo_setup(const Scene *scene,
@@ -130,19 +130,19 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
void *lock;
Image *image = bgpic->ima;
ImageUser *iuser = &bgpic->iuser;
- MovieClip *clip = NULL;
- GPUTexture *tex = NULL;
+ MovieClip *clip = nullptr;
+ GPUTexture *tex = nullptr;
Scene *scene = draw_ctx->scene;
float aspect_x, aspect_y;
int width, height;
- int ctime = (int)DEG_get_ctime(draw_ctx->depsgraph);
+ int ctime = int(DEG_get_ctime(draw_ctx->depsgraph));
*r_use_alpha_premult = false;
*r_use_view_transform = false;
switch (bgpic->source) {
- case CAM_BGIMG_SOURCE_IMAGE:
- if (image == NULL) {
- return NULL;
+ case CAM_BGIMG_SOURCE_IMAGE: {
+ if (image == nullptr) {
+ return nullptr;
}
*r_use_alpha_premult = (image->alpha_mode == IMA_ALPHA_PREMUL);
*r_use_view_transform = (image->flag & IMA_VIEW_AS_RENDER) != 0;
@@ -150,33 +150,34 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
BKE_image_user_frame_calc(image, iuser, ctime);
if (image->source == IMA_SRC_SEQUENCE && !(iuser->flag & IMA_USER_FRAME_IN_RANGE)) {
/* Frame is out of range, don't show. */
- return NULL;
+ return nullptr;
}
camera_background_images_stereo_setup(scene, draw_ctx->v3d, image, iuser);
iuser->scene = draw_ctx->scene;
ImBuf *ibuf = BKE_image_acquire_ibuf(image, iuser, &lock);
- if (ibuf == NULL) {
+ if (ibuf == nullptr) {
BKE_image_release_ibuf(image, ibuf, lock);
- iuser->scene = NULL;
- return NULL;
+ iuser->scene = nullptr;
+ return nullptr;
}
width = ibuf->x;
height = ibuf->y;
tex = BKE_image_get_gpu_texture(image, iuser, ibuf);
BKE_image_release_ibuf(image, ibuf, lock);
- iuser->scene = NULL;
+ iuser->scene = nullptr;
- if (tex == NULL) {
- return NULL;
+ if (tex == nullptr) {
+ return nullptr;
}
aspect_x = bgpic->ima->aspx;
aspect_y = bgpic->ima->aspy;
break;
+ }
- case CAM_BGIMG_SOURCE_MOVIE:
+ case CAM_BGIMG_SOURCE_MOVIE: {
if (bgpic->flag & CAM_BGIMG_FLAG_CAMERACLIP) {
if (scene->camera) {
clip = BKE_object_movieclip_get(scene, scene->camera, true);
@@ -186,14 +187,14 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
clip = bgpic->clip;
}
- if (clip == NULL) {
- return NULL;
+ if (clip == nullptr) {
+ return nullptr;
}
BKE_movieclip_user_set_frame(&bgpic->cuser, ctime);
tex = BKE_movieclip_get_gpu_texture(clip, &bgpic->cuser);
- if (tex == NULL) {
- return NULL;
+ if (tex == nullptr) {
+ return nullptr;
}
aspect_x = clip->aspx;
@@ -205,10 +206,11 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
/* Save for freeing. */
BLI_addtail(&pd->bg_movie_clips, BLI_genericNodeN(clip));
break;
+ }
default:
/* Unsupported type. */
- return NULL;
+ return nullptr;
}
*r_aspect = (width * aspect_x) / (height * aspect_y);
@@ -219,7 +221,7 @@ static void OVERLAY_image_free_movieclips_textures(OVERLAY_Data *data)
{
/* Free Movie clip textures after rendering */
LinkData *link;
- while ((link = BLI_pophead(&data->stl->pd->bg_movie_clips))) {
+ while ((link = static_cast<LinkData *>(BLI_pophead(&data->stl->pd->bg_movie_clips)))) {
MovieClip *clip = (MovieClip *)link->data;
BKE_movieclip_free_gputexture(clip);
MEM_freeN(link);
@@ -299,7 +301,7 @@ void OVERLAY_image_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
const DRWContextState *draw_ctx = DRW_context_state_get();
const View3D *v3d = draw_ctx->v3d;
const Scene *scene = draw_ctx->scene;
- Camera *cam = ob->data;
+ Camera *cam = static_cast<Camera *>(ob->data);
const bool show_frame = BKE_object_empty_image_frame_is_visible_in_view3d(ob, draw_ctx->rv3d);
@@ -333,7 +335,7 @@ void OVERLAY_image_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
/* Alpha is clamped just below 1.0 to fix background images to interfere with foreground
* images. Without this a background image with 1.0 will be rendered on top of a transparent
* foreground image due to the different blending modes they use. */
- const float color_premult_alpha[4] = {1.0f, 1.0f, 1.0f, MIN2(bgpic->alpha, 0.999999)};
+ const float color_premult_alpha[4] = {1.0f, 1.0f, 1.0f, std::min(bgpic->alpha, 0.999999f)};
DRWPass *pass = is_foreground ? (use_view_transform ? psl->image_foreground_scene_ps :
psl->image_foreground_ps) :
@@ -347,7 +349,7 @@ void OVERLAY_image_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", true);
DRW_shgroup_uniform_bool_copy(grp, "isCameraBackground", true);
DRW_shgroup_uniform_bool_copy(grp, "depthSet", true);
- DRW_shgroup_uniform_vec4_copy(grp, "color", color_premult_alpha);
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", color_premult_alpha);
DRW_shgroup_call_obmat(grp, DRW_cache_quad_get(), mat);
}
}
@@ -358,8 +360,8 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
OVERLAY_PassList *psl = vedata->psl;
const DRWContextState *draw_ctx = DRW_context_state_get();
const RegionView3D *rv3d = draw_ctx->rv3d;
- GPUTexture *tex = NULL;
- Image *ima = ob->data;
+ GPUTexture *tex = nullptr;
+ Image *ima = static_cast<Image *>(ob->data);
float mat[4][4];
const bool show_frame = BKE_object_empty_image_frame_is_visible_in_view3d(ob, rv3d);
@@ -375,10 +377,10 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
/* Calling 'BKE_image_get_size' may free the texture. Get the size from 'tex' instead,
* see: T59347 */
int size[2] = {0};
- if (ima != NULL) {
+ if (ima != nullptr) {
ImageUser iuser = *ob->iuser;
camera_background_images_stereo_setup(draw_ctx->scene, draw_ctx->v3d, ima, &iuser);
- tex = BKE_image_get_gpu_texture(ima, &iuser, NULL);
+ tex = BKE_image_get_gpu_texture(ima, &iuser, nullptr);
if (tex) {
size[0] = GPU_texture_orig_width(tex);
size[1] = GPU_texture_orig_height(tex);
@@ -388,9 +390,9 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
CLAMP_MIN(size[1], 1);
float image_aspect[2];
- overlay_image_calc_aspect(ob->data, size, image_aspect);
+ overlay_image_calc_aspect(ima, size, image_aspect);
- copy_m4_m4(mat, ob->obmat);
+ copy_m4_m4(mat, ob->object_to_world);
mul_v3_fl(mat[0], image_aspect[0] * 0.5f * ob->empty_drawsize);
mul_v3_fl(mat[1], image_aspect[1] * 0.5f * ob->empty_drawsize);
madd_v3_v3fl(mat[3], mat[0], ob->ima_ofs[0] * 2.0f + 1.0f);
@@ -399,7 +401,7 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
/* Use the actual depth if we are doing depth tests to determine the distance to the object */
char depth_mode = DRW_state_is_depth() ? OB_EMPTY_IMAGE_DEPTH_DEFAULT : ob->empty_image_depth;
- DRWPass *pass = NULL;
+ DRWPass *pass = nullptr;
if ((ob->dtx & OB_DRAW_IN_FRONT) != 0) {
/* Object In Front overrides image empty depth mode. */
pass = psl->image_empties_front_ps;
@@ -433,7 +435,7 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", use_alpha_blend);
DRW_shgroup_uniform_bool_copy(grp, "isCameraBackground", false);
DRW_shgroup_uniform_bool_copy(grp, "depthSet", depth_mode != OB_EMPTY_IMAGE_DEPTH_DEFAULT);
- DRW_shgroup_uniform_vec4_copy(grp, "color", ob->color);
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", ob->color);
DRW_shgroup_call_obmat(grp, DRW_cache_quad_get(), mat);
}
}
@@ -479,7 +481,7 @@ void OVERLAY_image_draw(OVERLAY_Data *vedata)
DRW_draw_pass(psl->image_empties_ps);
DRW_draw_pass(psl->image_empties_blend_ps);
- DRW_view_set_active(NULL);
+ DRW_view_set_active(nullptr);
}
void OVERLAY_image_in_front_draw(OVERLAY_Data *vedata)
@@ -492,7 +494,7 @@ void OVERLAY_image_in_front_draw(OVERLAY_Data *vedata)
DRW_draw_pass(psl->image_empties_front_ps);
DRW_draw_pass(psl->image_foreground_ps);
- DRW_view_set_active(NULL);
+ DRW_view_set_active(nullptr);
OVERLAY_image_free_movieclips_textures(vedata);
}
diff --git a/source/blender/draw/engines/overlay/overlay_lattice.c b/source/blender/draw/engines/overlay/overlay_lattice.cc
index 2035a9a9d3b..72c3335d871 100644
--- a/source/blender/draw/engines/overlay/overlay_lattice.c
+++ b/source/blender/draw/engines/overlay/overlay_lattice.cc
@@ -7,7 +7,7 @@
#include "DRW_render.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_edit_lattice_cache_init(OVERLAY_Data *vedata)
{
@@ -52,7 +52,7 @@ void OVERLAY_lattice_cache_populate(OVERLAY_Data *vedata, Object *ob)
DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color);
struct GPUBatch *geom = DRW_cache_lattice_wire_get(ob, false);
- OVERLAY_extra_wire(cb, geom, ob->obmat, color);
+ OVERLAY_extra_wire(cb, geom, ob->object_to_world, color);
}
void OVERLAY_edit_lattice_draw(OVERLAY_Data *vedata)
diff --git a/source/blender/draw/engines/overlay/overlay_metaball.c b/source/blender/draw/engines/overlay/overlay_metaball.cc
index f024f5dfac8..dd0a862337e 100644
--- a/source/blender/draw/engines/overlay/overlay_metaball.c
+++ b/source/blender/draw/engines/overlay/overlay_metaball.cc
@@ -15,7 +15,7 @@
#include "ED_mball.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_metaball_cache_init(OVERLAY_Data *vedata)
{
@@ -27,7 +27,8 @@ void OVERLAY_metaball_cache_init(OVERLAY_Data *vedata)
#define BUF_INSTANCE DRW_shgroup_call_buffer_instance
for (int i = 0; i < 2; i++) {
- DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT : 0;
+ DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT :
+ DRWState(0);
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
DRW_PASS_CREATE(psl->metaball_ps[i], state | pd->clipping_state | infront_state);
@@ -44,10 +45,10 @@ static void metaball_instance_data_set(
BoneInstanceData *data, Object *ob, const float *pos, const float radius, const float color[4])
{
/* Bone point radius is 0.05. Compensate for that. */
- mul_v3_v3fl(data->mat[0], ob->obmat[0], radius / 0.05f);
- mul_v3_v3fl(data->mat[1], ob->obmat[1], radius / 0.05f);
- mul_v3_v3fl(data->mat[2], ob->obmat[2], radius / 0.05f);
- mul_v3_m4v3(data->mat[3], ob->obmat, pos);
+ mul_v3_v3fl(data->mat[0], ob->object_to_world[0], radius / 0.05f);
+ mul_v3_v3fl(data->mat[1], ob->object_to_world[1], radius / 0.05f);
+ mul_v3_v3fl(data->mat[2], ob->object_to_world[2], radius / 0.05f);
+ mul_v3_m4v3(data->mat[3], ob->object_to_world, pos);
/* WATCH: Reminder, alpha is wire-size. */
OVERLAY_bone_instance_data_set_color(data, color);
}
@@ -57,7 +58,7 @@ void OVERLAY_edit_metaball_cache_populate(OVERLAY_Data *vedata, Object *ob)
const bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
const bool is_select = DRW_state_is_select();
OVERLAY_PrivateData *pd = vedata->stl->pd;
- MetaBall *mb = ob->data;
+ MetaBall *mb = static_cast<MetaBall *>(ob->data);
const float *color;
const float *col_radius = G_draw.block.color_mball_radius;
@@ -73,7 +74,7 @@ void OVERLAY_edit_metaball_cache_populate(OVERLAY_Data *vedata, Object *ob)
LISTBASE_FOREACH (MetaElem *, ml, mb->editelems) {
const bool is_selected = (ml->flag & SELECT) != 0;
const bool is_scale_radius = (ml->flag & MB_SCALE_RAD) != 0;
- float stiffness_radius = ml->rad * atanf(ml->s) / (float)M_PI_2;
+ float stiffness_radius = ml->rad * atanf(ml->s) / float(M_PI_2);
BoneInstanceData instdata;
if (is_select) {
@@ -103,7 +104,7 @@ void OVERLAY_metaball_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
const bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
OVERLAY_PrivateData *pd = vedata->stl->pd;
- MetaBall *mb = ob->data;
+ MetaBall *mb = static_cast<MetaBall *>(ob->data);
const DRWContextState *draw_ctx = DRW_context_state_get();
float *color;
diff --git a/source/blender/draw/engines/overlay/overlay_mode_transfer.c b/source/blender/draw/engines/overlay/overlay_mode_transfer.cc
index e7b2008dee0..79ac92a187c 100644
--- a/source/blender/draw/engines/overlay/overlay_mode_transfer.c
+++ b/source/blender/draw/engines/overlay/overlay_mode_transfer.cc
@@ -13,7 +13,7 @@
#include "PIL_time.h"
#include "UI_resources.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_mode_transfer_cache_init(OVERLAY_Data *vedata)
{
@@ -85,7 +85,7 @@ void OVERLAY_mode_transfer_cache_populate(OVERLAY_Data *vedata, Object *ob)
}
const DRWContextState *draw_ctx = DRW_context_state_get();
- const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) &&
+ const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->rv3d) &&
!DRW_state_is_image_render();
const bool is_xray = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
@@ -100,7 +100,7 @@ void OVERLAY_mode_transfer_cache_populate(OVERLAY_Data *vedata, Object *ob)
UI_GetThemeColor3fv(TH_VERTEX_SELECT, color);
color[3] = mode_transfer_alpha_for_animation_time_get(animation_time);
srgb_to_linearrgb_v4(color, color);
- DRW_shgroup_uniform_vec4_copy(mode_transfer_grp[i], "color", color);
+ DRW_shgroup_uniform_vec4_copy(mode_transfer_grp[i], "ucolor", color);
}
if (!pd->use_in_front) {
@@ -110,7 +110,7 @@ void OVERLAY_mode_transfer_cache_populate(OVERLAY_Data *vedata, Object *ob)
pd->mode_transfer.any_animated = true;
if (use_sculpt_pbvh) {
- DRW_shgroup_call_sculpt(mode_transfer_grp[is_xray], ob, false, false);
+ DRW_shgroup_call_sculpt(mode_transfer_grp[is_xray], ob, false, false, false, false, false);
}
else {
struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
diff --git a/source/blender/draw/engines/overlay/overlay_motion_path.c b/source/blender/draw/engines/overlay/overlay_motion_path.cc
index 58825923f37..3f6954f821b 100644
--- a/source/blender/draw/engines/overlay/overlay_motion_path.c
+++ b/source/blender/draw/engines/overlay/overlay_motion_path.cc
@@ -20,7 +20,7 @@
#include "draw_manager_text.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_motion_path_cache_init(OVERLAY_Data *vedata)
{
@@ -63,7 +63,7 @@ static GPUVertBuf *mpath_vbo_get(bMotionPath *mpath)
static GPUBatch *mpath_batch_line_get(bMotionPath *mpath)
{
if (!mpath->batch_line) {
- mpath->batch_line = GPU_batch_create(GPU_PRIM_LINE_STRIP, mpath_vbo_get(mpath), NULL);
+ mpath->batch_line = GPU_batch_create(GPU_PRIM_LINE_STRIP, mpath_vbo_get(mpath), nullptr);
}
return mpath->batch_line;
}
@@ -71,7 +71,7 @@ static GPUBatch *mpath_batch_line_get(bMotionPath *mpath)
static GPUBatch *mpath_batch_points_get(bMotionPath *mpath)
{
if (!mpath->batch_points) {
- mpath->batch_points = GPU_batch_create(GPU_PRIM_POINTS, mpath_vbo_get(mpath), NULL);
+ mpath->batch_points = GPU_batch_create(GPU_PRIM_POINTS, mpath_vbo_get(mpath), nullptr);
}
return mpath->batch_points;
}
@@ -116,7 +116,7 @@ static void motion_path_cache(OVERLAY_Data *vedata,
const DRWContextState *draw_ctx = DRW_context_state_get();
struct DRWTextStore *dt = DRW_text_cache_ensure();
int txt_flag = DRW_TEXT_CACHE_GLOBALSPACE;
- int cfra = (int)DEG_get_ctime(draw_ctx->depsgraph);
+ int cfra = int(DEG_get_ctime(draw_ctx->depsgraph));
bool selected = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->base_flag & BASE_SELECTED);
bool show_keyframes = (avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) != 0;
bool show_keyframes_no = (avs->path_viewflag & MOTIONPATH_VIEW_KFNOS) != 0;
@@ -143,7 +143,7 @@ static void motion_path_cache(OVERLAY_Data *vedata,
DRW_shgroup_uniform_bool_copy(grp, "selected", selected);
DRW_shgroup_uniform_vec3_copy(grp, "customColor", color);
/* Only draw the required range. */
- DRW_shgroup_call_range(grp, NULL, mpath_batch_line_get(mpath), start_index, len);
+ DRW_shgroup_call_range(grp, nullptr, mpath_batch_line_get(mpath), start_index, len);
}
/* Draw points. */
@@ -155,7 +155,7 @@ static void motion_path_cache(OVERLAY_Data *vedata,
DRW_shgroup_uniform_bool_copy(grp, "showKeyFrames", show_keyframes);
DRW_shgroup_uniform_vec3_copy(grp, "customColor", color);
/* Only draw the required range. */
- DRW_shgroup_call_range(grp, NULL, mpath_batch_points_get(mpath), start_index, len);
+ DRW_shgroup_call_range(grp, nullptr, mpath_batch_points_get(mpath), start_index, len);
}
/* Draw frame numbers at each frame-step value. */
@@ -208,7 +208,7 @@ void OVERLAY_motion_path_cache_populate(OVERLAY_Data *vedata, Object *ob)
}
if (ob->mpath) {
- motion_path_cache(vedata, ob, NULL, &ob->avs, ob->mpath);
+ motion_path_cache(vedata, ob, nullptr, &ob->avs, ob->mpath);
}
}
diff --git a/source/blender/draw/engines/overlay/overlay_outline.c b/source/blender/draw/engines/overlay/overlay_outline.cc
index f2e2acc98a9..c2df665eba3 100644
--- a/source/blender/draw/engines/overlay/overlay_outline.c
+++ b/source/blender/draw/engines/overlay/overlay_outline.cc
@@ -16,14 +16,14 @@
#include "UI_resources.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
/* Returns the normal plane in NDC space. */
static void gpencil_depth_plane(Object *ob, float r_plane[4])
{
/* TODO: put that into private data. */
float viewinv[4][4];
- DRW_view_viewmat_get(NULL, viewinv, true);
+ DRW_view_viewmat_get(nullptr, viewinv, true);
float *camera_z_axis = viewinv[2];
float *camera_pos = viewinv[3];
@@ -43,11 +43,11 @@ static void gpencil_depth_plane(Object *ob, float r_plane[4])
add_v3_fl(size, 1e-8f);
rescale_m4(mat, size);
/* BBox space to World. */
- mul_m4_m4m4(mat, ob->obmat, mat);
+ mul_m4_m4m4(mat, ob->object_to_world, mat);
/* BBox center in world space. */
copy_v3_v3(center, mat[3]);
/* View Vector. */
- if (DRW_view_is_persp_get(NULL)) {
+ if (DRW_view_is_persp_get(nullptr)) {
/* BBox center to camera vector. */
sub_v3_v3v3(r_plane, camera_pos, mat[3]);
}
@@ -78,8 +78,8 @@ void OVERLAY_outline_init(OVERLAY_Data *vedata)
if (DRW_state_is_fbo()) {
/* TODO: only alloc if needed. */
- DRW_texture_ensure_fullscreen_2d(&txl->temp_depth_tx, GPU_DEPTH24_STENCIL8, 0);
- DRW_texture_ensure_fullscreen_2d(&txl->outlines_id_tx, GPU_R16UI, 0);
+ DRW_texture_ensure_fullscreen_2d(&txl->temp_depth_tx, GPU_DEPTH24_STENCIL8, DRWTextureFlag(0));
+ DRW_texture_ensure_fullscreen_2d(&txl->outlines_id_tx, GPU_R16UI, DRWTextureFlag(0));
GPU_framebuffer_ensure_config(
&fbl->outlines_prepass_fb,
@@ -109,7 +109,7 @@ void OVERLAY_outline_cache_init(OVERLAY_Data *vedata)
OVERLAY_TextureList *txl = vedata->txl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- DRWShadingGroup *grp = NULL;
+ DRWShadingGroup *grp = nullptr;
const float outline_width = UI_GetThemeValuef(TH_OUTLINE_WIDTH);
const bool do_expand = (U.pixelsize > 1.0) || (outline_width > 2.0f);
@@ -122,21 +122,26 @@ void OVERLAY_outline_cache_init(OVERLAY_Data *vedata)
pd->outlines_grp = grp = DRW_shgroup_create(sh_geom, psl->outlines_prepass_ps);
DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
+ DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
GPUShader *sh_geom_ptcloud = OVERLAY_shader_outline_prepass_pointcloud();
pd->outlines_ptcloud_grp = grp = DRW_shgroup_create(sh_geom_ptcloud, psl->outlines_prepass_ps);
DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
+ DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
GPUShader *sh_gpencil = OVERLAY_shader_outline_prepass_gpencil();
pd->outlines_gpencil_grp = grp = DRW_shgroup_create(sh_gpencil, psl->outlines_prepass_ps);
DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
DRW_shgroup_uniform_float_copy(grp, "gpStrokeIndexOffset", 0.0);
+ DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
GPUShader *sh_curves = OVERLAY_shader_outline_prepass_curves();
+
pd->outlines_curves_grp = grp = DRW_shgroup_create(sh_curves, psl->outlines_prepass_ps);
DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
+ DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
}
/* outlines_prepass_ps is still needed for selection of probes. */
@@ -161,21 +166,20 @@ void OVERLAY_outline_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "sceneDepth", &dtxl->depth);
DRW_shgroup_uniform_texture_ref(grp, "outlineDepth", &txl->temp_depth_tx);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
- DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+ DRW_shgroup_call_procedural_triangles(grp, nullptr, 1);
}
}
typedef struct iterData {
Object *ob;
DRWShadingGroup *stroke_grp;
- DRWShadingGroup *fill_grp;
int cfra;
float plane[4];
} iterData;
static void gpencil_layer_cache_populate(bGPDlayer *gpl,
- bGPDframe *UNUSED(gpf),
- bGPDstroke *UNUSED(gps),
+ bGPDframe * /*gpf*/,
+ bGPDstroke * /*gps*/,
void *thunk)
{
iterData *iter = (iterData *)thunk;
@@ -184,21 +188,26 @@ static void gpencil_layer_cache_populate(bGPDlayer *gpl,
const bool is_screenspace = (gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS) != 0;
const bool is_stroke_order_3d = (gpd->draw_mode == GP_DRAWMODE_3D);
- float object_scale = mat4_to_scale(iter->ob->obmat);
+ float object_scale = mat4_to_scale(iter->ob->object_to_world);
/* Negate thickness sign to tag that strokes are in screen space.
* Convert to world units (by default, 1 meter = 2000 pixels). */
float thickness_scale = (is_screenspace) ? -1.0f : (gpd->pixfactor / 2000.0f);
+ GPUVertBuf *position_tx = DRW_cache_gpencil_position_buffer_get(iter->ob, iter->cfra);
+ GPUVertBuf *color_tx = DRW_cache_gpencil_color_buffer_get(iter->ob, iter->cfra);
+
DRWShadingGroup *grp = iter->stroke_grp = DRW_shgroup_create_sub(iter->stroke_grp);
DRW_shgroup_uniform_bool_copy(grp, "gpStrokeOrder3d", is_stroke_order_3d);
DRW_shgroup_uniform_float_copy(grp, "gpThicknessScale", object_scale);
- DRW_shgroup_uniform_float_copy(grp, "gpThicknessOffset", (float)gpl->line_change);
+ DRW_shgroup_uniform_float_copy(grp, "gpThicknessOffset", float(gpl->line_change));
DRW_shgroup_uniform_float_copy(grp, "gpThicknessWorldScale", thickness_scale);
DRW_shgroup_uniform_vec4_copy(grp, "gpDepthPlane", iter->plane);
+ DRW_shgroup_buffer_texture(grp, "gp_pos_tx", position_tx);
+ DRW_shgroup_buffer_texture(grp, "gp_col_tx", color_tx);
}
-static void gpencil_stroke_cache_populate(bGPDlayer *UNUSED(gpl),
- bGPDframe *UNUSED(gpf),
+static void gpencil_stroke_cache_populate(bGPDlayer * /*gpl*/,
+ bGPDframe * /*gpf*/,
bGPDstroke *gps,
void *thunk)
{
@@ -215,20 +224,19 @@ static void gpencil_stroke_cache_populate(bGPDlayer *UNUSED(gpl),
return;
}
+ struct GPUBatch *geom = DRW_cache_gpencil_get(iter->ob, iter->cfra);
+
if (show_fill) {
- struct GPUBatch *geom = DRW_cache_gpencil_fills_get(iter->ob, iter->cfra);
int vfirst = gps->runtime.fill_start * 3;
int vcount = gps->tot_triangles * 3;
- DRW_shgroup_call_range(iter->fill_grp, iter->ob, geom, vfirst, vcount);
+ DRW_shgroup_call_range(iter->stroke_grp, iter->ob, geom, vfirst, vcount);
}
if (show_stroke) {
- struct GPUBatch *geom = DRW_cache_gpencil_strokes_get(iter->ob, iter->cfra);
- /* Start one vert before to have gl_InstanceID > 0 (see shader). */
- int vfirst = gps->runtime.stroke_start - 1;
- /* Include "potential" cyclic vertex and start adj vertex (see shader). */
- int vcount = gps->totpoints + 1 + 1;
- DRW_shgroup_call_instance_range(iter->stroke_grp, iter->ob, geom, vfirst, vcount);
+ int vfirst = gps->runtime.stroke_start * 3;
+ bool is_cyclic = ((gps->flag & GP_STROKE_CYCLIC) != 0) && (gps->totpoints > 2);
+ int vcount = (gps->totpoints + (int)is_cyclic) * 2 * 3;
+ DRW_shgroup_call_range(iter->stroke_grp, iter->ob, geom, vfirst, vcount);
}
}
@@ -240,18 +248,16 @@ static void OVERLAY_outline_gpencil(OVERLAY_PrivateData *pd, Object *ob)
return;
}
- iterData iter = {
- .ob = ob,
- .stroke_grp = pd->outlines_gpencil_grp,
- .fill_grp = DRW_shgroup_create_sub(pd->outlines_gpencil_grp),
- .cfra = pd->cfra,
- };
+ iterData iter{};
+ iter.ob = ob;
+ iter.stroke_grp = pd->outlines_gpencil_grp;
+ iter.cfra = pd->cfra;
if (gpd->draw_mode == GP_DRAWMODE_2D) {
gpencil_depth_plane(ob, iter.plane);
}
- BKE_gpencil_visible_stroke_advanced_iter(NULL,
+ BKE_gpencil_visible_stroke_advanced_iter(nullptr,
ob,
gpencil_layer_cache_populate,
gpencil_stroke_cache_populate,
@@ -263,7 +269,7 @@ static void OVERLAY_outline_gpencil(OVERLAY_PrivateData *pd, Object *ob)
static void OVERLAY_outline_volume(OVERLAY_PrivateData *pd, Object *ob)
{
struct GPUBatch *geom = DRW_cache_volume_selection_surface_get(ob);
- if (geom == NULL) {
+ if (geom == nullptr) {
return;
}
@@ -274,7 +280,19 @@ static void OVERLAY_outline_volume(OVERLAY_PrivateData *pd, Object *ob)
static void OVERLAY_outline_curves(OVERLAY_PrivateData *pd, Object *ob)
{
DRWShadingGroup *shgroup = pd->outlines_curves_grp;
- DRW_shgroup_curves_create_sub(ob, shgroup, NULL);
+ DRW_shgroup_curves_create_sub(ob, shgroup, nullptr);
+}
+
+static void OVERLAY_outline_pointcloud(OVERLAY_PrivateData *pd, Object *ob)
+{
+ if (pd->wireframe_mode) {
+ /* Looks bad in this case. Could be relaxed if we draw a
+ * wireframe of some sort in the future. */
+ return;
+ }
+
+ DRWShadingGroup *shgroup = pd->outlines_ptcloud_grp;
+ DRW_shgroup_pointcloud_create_sub(ob, shgroup, nullptr);
}
void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
@@ -285,7 +303,7 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
OVERLAY_PrivateData *pd = vedata->stl->pd;
const DRWContextState *draw_ctx = DRW_context_state_get();
struct GPUBatch *geom;
- DRWShadingGroup *shgroup = NULL;
+ DRWShadingGroup *shgroup = nullptr;
const bool draw_outline = ob->dt > OB_BOUNDBOX;
/* Early exit: outlines of bounding boxes are not drawn. */
@@ -308,9 +326,8 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
return;
}
- if (ob->type == OB_POINTCLOUD && pd->wireframe_mode) {
- /* Looks bad in this case. Could be relaxed if we draw a
- * wireframe of some sort in the future. */
+ if (ob->type == OB_POINTCLOUD) {
+ OVERLAY_outline_pointcloud(pd, ob);
return;
}
@@ -326,25 +343,19 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
DRW_object_axis_orthogonal_to_view(ob, flat_axis));
if (pd->xray_enabled_and_not_wire || is_flat_object_viewed_from_side) {
- geom = DRW_cache_object_edge_detection_get(ob, NULL);
+ geom = DRW_cache_object_edge_detection_get(ob, nullptr);
}
else {
geom = DRW_cache_object_surface_get(ob);
}
if (geom) {
- shgroup = (ob->type == OB_POINTCLOUD) ? pd->outlines_ptcloud_grp : pd->outlines_grp;
+ shgroup = pd->outlines_grp;
}
}
if (shgroup && geom) {
- if (ob->type == OB_POINTCLOUD) {
- /* Draw range to avoid drawcall batching messing up the instance attribute. */
- DRW_shgroup_call_instance_range(shgroup, ob, geom, 0, 0);
- }
- else {
- DRW_shgroup_call(shgroup, geom, ob);
- }
+ DRW_shgroup_call(shgroup, geom, ob);
}
if (init_dupli) {
@@ -359,7 +370,7 @@ void OVERLAY_outline_draw(OVERLAY_Data *vedata)
OVERLAY_PassList *psl = vedata->psl;
const float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- bool do_outlines = psl->outlines_prepass_ps != NULL &&
+ bool do_outlines = psl->outlines_prepass_ps != nullptr &&
!DRW_pass_is_empty(psl->outlines_prepass_ps);
if (DRW_state_is_fbo() && do_outlines) {
diff --git a/source/blender/draw/engines/overlay/overlay_paint.c b/source/blender/draw/engines/overlay/overlay_paint.cc
index c730c702a8d..b8f087a1460 100644
--- a/source/blender/draw/engines/overlay/overlay_paint.c
+++ b/source/blender/draw/engines/overlay/overlay_paint.cc
@@ -13,7 +13,7 @@
#include "DEG_depsgraph_query.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
/* Check if the given object is rendered (partially) transparent */
static bool paint_object_is_rendered_transparent(View3D *v3d, Object *ob)
@@ -31,7 +31,7 @@ static bool paint_object_is_rendered_transparent(View3D *v3d, Object *ob)
}
if (ob && ob->type == OB_MESH && ob->data &&
v3d->shading.color_type == V3D_SHADING_MATERIAL_COLOR) {
- Mesh *me = ob->data;
+ Mesh *me = static_cast<Mesh *>(ob->data);
for (int i = 0; i < me->totcol; i++) {
Material *mat = BKE_object_material_get_eval(ob, i + 1);
if (mat && mat->a < 1.0f) {
@@ -74,8 +74,8 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
const bool draw_contours = !is_edit_mode &&
(pd->overlay.wpaint_flag & V3D_OVERLAY_WPAINT_CONTOURS) != 0;
float opacity = 0.0f;
- pd->paint_depth_grp = NULL;
- psl->paint_depth_ps = NULL;
+ pd->paint_depth_grp = nullptr;
+ psl->paint_depth_ps = nullptr;
switch (pd->ctx_mode) {
case CTX_MODE_POSE:
@@ -130,14 +130,14 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
case CTX_MODE_PAINT_TEXTURE: {
const ImagePaintSettings *imapaint = &draw_ctx->scene->toolsettings->imapaint;
const bool mask_enabled = imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL &&
- imapaint->stencil != NULL;
+ imapaint->stencil != nullptr;
opacity = mask_enabled ? pd->overlay.texture_paint_mode_opacity : 0.0f;
if (opacity > 0.0f) {
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA;
DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state);
- GPUTexture *tex = BKE_image_get_gpu_texture(imapaint->stencil, NULL, NULL);
+ GPUTexture *tex = BKE_image_get_gpu_texture(imapaint->stencil, nullptr, nullptr);
const bool mask_premult = (imapaint->stencil->alpha_mode == IMA_ALPHA_PREMUL);
const bool mask_inverted = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) != 0;
@@ -158,8 +158,8 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
}
if (opacity <= 0.0f) {
- psl->paint_color_ps = NULL;
- pd->paint_surf_grp = NULL;
+ psl->paint_color_ps = nullptr;
+ pd->paint_surf_grp = nullptr;
}
{
@@ -167,7 +167,8 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
DRW_PASS_CREATE(psl->paint_overlay_ps, state | pd->clipping_state);
sh = OVERLAY_shader_paint_face();
pd->paint_face_grp = grp = DRW_shgroup_create(sh, psl->paint_overlay_ps);
- DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){1.0f, 1.0f, 1.0f, 0.2f});
+ const float4 color = {1.0f, 1.0f, 1.0f, 0.2f};
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", color);
DRW_shgroup_state_enable(grp, DRW_STATE_BLEND_ALPHA);
sh = OVERLAY_shader_paint_wire();
@@ -190,9 +191,9 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
void OVERLAY_paint_texture_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
- struct GPUBatch *geom = NULL;
+ struct GPUBatch *geom = nullptr;
- const Mesh *me_orig = DEG_get_original_object(ob)->data;
+ const Mesh *me_orig = static_cast<Mesh *>(DEG_get_original_object(ob)->data);
const bool use_face_sel = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
if (pd->paint_surf_grp) {
@@ -209,9 +210,9 @@ void OVERLAY_paint_texture_cache_populate(OVERLAY_Data *vedata, Object *ob)
void OVERLAY_paint_vertex_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
- struct GPUBatch *geom = NULL;
+ struct GPUBatch *geom = nullptr;
- const Mesh *me_orig = DEG_get_original_object(ob)->data;
+ const Mesh *me_orig = static_cast<Mesh *>(DEG_get_original_object(ob)->data);
const bool is_edit_mode = (pd->ctx_mode == CTX_MODE_EDIT_MESH);
const bool use_wire = !is_edit_mode && (pd->overlay.paint_flag & V3D_OVERLAY_PAINT_WIRE);
const bool use_face_sel = !is_edit_mode && (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL);
diff --git a/source/blender/draw/engines/overlay/overlay_particle.c b/source/blender/draw/engines/overlay/overlay_particle.cc
index b985bfb24bf..c9e3ccba008 100644
--- a/source/blender/draw/engines/overlay/overlay_particle.c
+++ b/source/blender/draw/engines/overlay/overlay_particle.cc
@@ -15,7 +15,7 @@
#include "ED_particle.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
/* -------------------------------------------------------------------- */
/** \name Edit Particles
@@ -64,7 +64,7 @@ void OVERLAY_edit_particle_cache_populate(OVERLAY_Data *vedata, Object *ob)
*/
Object *ob_orig = DEG_get_original_object(ob);
PTCacheEdit *edit = PE_create_current(draw_ctx->depsgraph, scene_orig, ob_orig);
- if (edit == NULL) {
+ if (edit == nullptr) {
/* Happens when trying to edit particles in EMITTER mode without
* having them cached.
*/
@@ -73,14 +73,14 @@ void OVERLAY_edit_particle_cache_populate(OVERLAY_Data *vedata, Object *ob)
/* NOTE: We need to pass evaluated particle system, which we need
* to find first.
*/
- ParticleSystem *psys = ob->particlesystem.first;
+ ParticleSystem *psys = static_cast<ParticleSystem *>(ob->particlesystem.first);
LISTBASE_FOREACH (ParticleSystem *, psys_orig, &ob_orig->particlesystem) {
if (PE_get_current_from_psys(psys_orig) == edit) {
break;
}
psys = psys->next;
}
- if (psys == NULL) {
+ if (psys == nullptr) {
printf("Error getting evaluated particle system for edit.\n");
return;
}
@@ -88,17 +88,17 @@ void OVERLAY_edit_particle_cache_populate(OVERLAY_Data *vedata, Object *ob)
struct GPUBatch *geom;
{
geom = DRW_cache_particles_get_edit_strands(ob, psys, edit, pd->edit_particle.use_weight);
- DRW_shgroup_call(pd->edit_particle_strand_grp, geom, NULL);
+ DRW_shgroup_call(pd->edit_particle_strand_grp, geom, nullptr);
}
if (pd->edit_particle.select_mode == SCE_SELECT_POINT) {
geom = DRW_cache_particles_get_edit_inner_points(ob, psys, edit);
- DRW_shgroup_call(pd->edit_particle_point_grp, geom, NULL);
+ DRW_shgroup_call(pd->edit_particle_point_grp, geom, nullptr);
}
if (ELEM(pd->edit_particle.select_mode, SCE_SELECT_POINT, SCE_SELECT_END)) {
geom = DRW_cache_particles_get_edit_tip_points(ob, psys, edit);
- DRW_shgroup_call(pd->edit_particle_point_grp, geom, NULL);
+ DRW_shgroup_call(pd->edit_particle_point_grp, geom, nullptr);
}
}
@@ -165,7 +165,7 @@ void OVERLAY_particle_cache_populate(OVERLAY_Data *vedata, Object *ob)
if (!ELEM(draw_as, PART_DRAW_NOT, PART_DRAW_OB, PART_DRAW_GR)) {
struct GPUBatch *geom = DRW_cache_particles_get_dots(ob, psys);
- struct GPUBatch *shape = NULL;
+ struct GPUBatch *shape = nullptr;
DRWShadingGroup *grp;
/* TODO(fclem): Here would be a good place for preemptive culling. */
@@ -173,7 +173,7 @@ void OVERLAY_particle_cache_populate(OVERLAY_Data *vedata, Object *ob)
/* NOTE(fclem): Is color even useful in our modern context? */
Material *ma = BKE_object_material_get_eval(ob, part->omat);
float color[4] = {0.6f, 0.6f, 0.6f, part->draw_size};
- if (ma != NULL) {
+ if (ma != nullptr) {
copy_v3_v3(color, &ma->r);
}
@@ -181,16 +181,16 @@ void OVERLAY_particle_cache_populate(OVERLAY_Data *vedata, Object *ob)
default:
case PART_DRAW_DOT:
grp = DRW_shgroup_create_sub(pd->particle_dots_grp);
- DRW_shgroup_uniform_vec4_copy(grp, "color", color);
- DRW_shgroup_call(grp, geom, NULL);
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", color);
+ DRW_shgroup_call(grp, geom, nullptr);
break;
case PART_DRAW_AXIS:
case PART_DRAW_CIRC:
case PART_DRAW_CROSS:
grp = DRW_shgroup_create_sub(pd->particle_shapes_grp);
- DRW_shgroup_uniform_vec4_copy(grp, "color", color);
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", color);
shape = DRW_cache_particles_get_prim(draw_as);
- DRW_shgroup_call_instances_with_attrs(grp, NULL, shape, geom);
+ DRW_shgroup_call_instances_with_attrs(grp, nullptr, shape, geom);
break;
}
}
diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.hh
index 0a783c44029..b1118e084a6 100644
--- a/source/blender/draw/engines/overlay/overlay_private.h
+++ b/source/blender/draw/engines/overlay/overlay_private.hh
@@ -61,6 +61,7 @@ typedef struct OVERLAY_PassList {
DRWPass *armature_ps[2];
DRWPass *armature_bone_select_ps;
DRWPass *armature_transp_ps[2];
+ DRWPass *attribute_ps;
DRWPass *background_ps;
DRWPass *clipping_frustum_ps;
DRWPass *edit_curve_wire_ps[2];
@@ -284,6 +285,12 @@ typedef struct OVERLAY_PrivateData {
DRWShadingGroup *pointcloud_dots_grp;
DRWShadingGroup *sculpt_mask_grp;
DRWShadingGroup *sculpt_curves_selection_grp;
+ DRWShadingGroup *viewer_attribute_curve_grp;
+ DRWShadingGroup *viewer_attribute_curves_grp;
+ DRWShadingGroup *viewer_attribute_mesh_grp;
+ DRWShadingGroup *viewer_attribute_pointcloud_grp;
+ DRWShadingGroup *viewer_attribute_instance_grp;
+ DRWShadingGroup *viewer_attribute_instance_pointcloud_grp;
DRWShadingGroup *volume_selection_surface_grp;
DRWShadingGroup *wires_grp[2][2]; /* With and without coloring. */
DRWShadingGroup *wires_all_grp[2][2]; /* With and without coloring. */
@@ -678,6 +685,10 @@ void OVERLAY_sculpt_curves_cache_init(OVERLAY_Data *vedata);
void OVERLAY_sculpt_curves_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_sculpt_curves_draw(OVERLAY_Data *vedata);
+void OVERLAY_viewer_attribute_cache_init(OVERLAY_Data *vedata);
+void OVERLAY_viewer_attribute_cache_populate(OVERLAY_Data *vedata, Object *object);
+void OVERLAY_viewer_attribute_draw(OVERLAY_Data *vedata);
+
void OVERLAY_wireframe_init(OVERLAY_Data *vedata);
void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata);
void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
@@ -745,6 +756,7 @@ GPUShader *OVERLAY_shader_image(void);
GPUShader *OVERLAY_shader_motion_path_line(void);
GPUShader *OVERLAY_shader_motion_path_vert(void);
GPUShader *OVERLAY_shader_uniform_color(void);
+GPUShader *OVERLAY_shader_uniform_color_pointcloud(void);
GPUShader *OVERLAY_shader_outline_prepass(bool use_wire);
GPUShader *OVERLAY_shader_outline_prepass_curves(void);
GPUShader *OVERLAY_shader_outline_prepass_gpencil(void);
@@ -761,6 +773,10 @@ GPUShader *OVERLAY_shader_particle_dot(void);
GPUShader *OVERLAY_shader_particle_shape(void);
GPUShader *OVERLAY_shader_sculpt_mask(void);
GPUShader *OVERLAY_shader_sculpt_curves_selection(void);
+GPUShader *OVERLAY_shader_viewer_attribute_curve(void);
+GPUShader *OVERLAY_shader_viewer_attribute_curves(void);
+GPUShader *OVERLAY_shader_viewer_attribute_mesh(void);
+GPUShader *OVERLAY_shader_viewer_attribute_pointcloud(void);
GPUShader *OVERLAY_shader_volume_velocity(bool use_needle, bool use_mac);
GPUShader *OVERLAY_shader_volume_gridlines(bool color_with_flags, bool color_range);
GPUShader *OVERLAY_shader_wireframe(bool custom_bias);
diff --git a/source/blender/draw/engines/overlay/overlay_sculpt.c b/source/blender/draw/engines/overlay/overlay_sculpt.cc
index 4a6477b3f6c..3377aa5394b 100644
--- a/source/blender/draw/engines/overlay/overlay_sculpt.c
+++ b/source/blender/draw/engines/overlay/overlay_sculpt.cc
@@ -8,7 +8,7 @@
#include "DRW_render.h"
#include "draw_cache_impl.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
@@ -37,7 +37,7 @@ void OVERLAY_sculpt_cache_populate(OVERLAY_Data *vedata, Object *ob)
struct GPUBatch *sculpt_overlays;
PBVH *pbvh = ob->sculpt->pbvh;
- const bool use_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d);
+ const bool use_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->rv3d);
if (!pbvh) {
/* It is possible to have SculptSession without PBVH. This happens, for example, when toggling
@@ -53,10 +53,10 @@ void OVERLAY_sculpt_cache_populate(OVERLAY_Data *vedata, Object *ob)
}
if (use_pbvh) {
- DRW_shgroup_call_sculpt(pd->sculpt_mask_grp, ob, false, true);
+ DRW_shgroup_call_sculpt(pd->sculpt_mask_grp, ob, false, true, true, false, false);
}
else {
- sculpt_overlays = DRW_mesh_batch_cache_get_sculpt_overlays(ob->data);
+ sculpt_overlays = DRW_mesh_batch_cache_get_sculpt_overlays(static_cast<Mesh *>(ob->data));
if (sculpt_overlays) {
DRW_shgroup_call(pd->sculpt_mask_grp, sculpt_overlays, ob);
}
diff --git a/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc b/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc
index b8021124f27..68de5dcd11d 100644
--- a/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc
+++ b/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc
@@ -8,7 +8,7 @@
#include "DRW_render.h"
#include "draw_cache_impl.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
#include "BKE_curves.hh"
@@ -64,7 +64,7 @@ void OVERLAY_sculpt_curves_cache_populate(OVERLAY_Data *vedata, Object *object)
".selection_curve_float";
bool is_point_domain;
- GPUTexture **texture = DRW_curves_texture_for_evaluated_attribute(
+ GPUVertBuf **texture = DRW_curves_texture_for_evaluated_attribute(
curves, name, &is_point_domain);
if (texture == nullptr) {
return;
@@ -78,7 +78,7 @@ void OVERLAY_sculpt_curves_cache_populate(OVERLAY_Data *vedata, Object *object)
}
DRW_shgroup_uniform_bool_copy(grp, "is_point_domain", is_point_domain);
- DRW_shgroup_uniform_texture(grp, "selection_tx", *texture);
+ DRW_shgroup_buffer_texture(grp, "selection_tx", *texture);
}
void OVERLAY_sculpt_curves_draw(OVERLAY_Data *vedata)
diff --git a/source/blender/draw/engines/overlay/overlay_shader.c b/source/blender/draw/engines/overlay/overlay_shader.cc
index 2373363ab9d..b7e5e8c56b7 100644
--- a/source/blender/draw/engines/overlay/overlay_shader.c
+++ b/source/blender/draw/engines/overlay/overlay_shader.cc
@@ -11,7 +11,7 @@
#include "UI_resources.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
typedef struct OVERLAY_Shaders {
GPUShader *antialiasing;
@@ -93,6 +93,11 @@ typedef struct OVERLAY_Shaders {
GPUShader *sculpt_mask;
GPUShader *sculpt_curves_selection;
GPUShader *uniform_color;
+ GPUShader *uniform_color_pointcloud;
+ GPUShader *viewer_attribute_mesh;
+ GPUShader *viewer_attribute_pointcloud;
+ GPUShader *viewer_attribute_curve;
+ GPUShader *viewer_attribute_curves;
GPUShader *volume_velocity_needle_sh;
GPUShader *volume_velocity_mac_sh;
GPUShader *volume_velocity_sh;
@@ -106,7 +111,7 @@ typedef struct OVERLAY_Shaders {
static struct {
OVERLAY_Shaders sh_data[GPU_SHADER_CFG_LEN];
-} e_data = {{{NULL}}};
+} e_data = {{{nullptr}}};
GPUShader *OVERLAY_shader_antialiasing(void)
{
@@ -162,7 +167,7 @@ GPUShader *OVERLAY_shader_edit_mesh_edge(bool use_flat_interp)
const DRWContextState *draw_ctx = DRW_context_state_get();
OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
GPUShader **sh = use_flat_interp ? &sh_data->edit_mesh_edge_flat : &sh_data->edit_mesh_edge;
- if (*sh == NULL) {
+ if (*sh == nullptr) {
*sh = GPU_shader_create_from_info_name(
draw_ctx->sh_cfg ?
(use_flat_interp ? "overlay_edit_mesh_edge_flat_clipped" :
@@ -486,7 +491,7 @@ GPUShader *OVERLAY_shader_extra_wire(bool use_object, bool is_select)
OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
GPUShader **sh = (is_select) ? &sh_data->extra_wire_select : &sh_data->extra_wire[use_object];
if (!*sh) {
- const char *info_name = NULL;
+ const char *info_name = nullptr;
if (draw_ctx->sh_cfg) {
if (is_select) {
info_name = "overlay_extra_wire_select_clipped";
@@ -818,6 +823,55 @@ GPUShader *OVERLAY_shader_sculpt_curves_selection(void)
return sh_data->sculpt_curves_selection;
}
+GPUShader *OVERLAY_shader_viewer_attribute_mesh(void)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
+ if (!sh_data->viewer_attribute_mesh) {
+ sh_data->viewer_attribute_mesh = GPU_shader_create_from_info_name(
+ draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED ? "overlay_viewer_attribute_mesh_clipped" :
+ "overlay_viewer_attribute_mesh");
+ }
+ return sh_data->viewer_attribute_mesh;
+}
+
+GPUShader *OVERLAY_shader_viewer_attribute_pointcloud(void)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
+ if (!sh_data->viewer_attribute_pointcloud) {
+ sh_data->viewer_attribute_pointcloud = GPU_shader_create_from_info_name(
+ draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED ?
+ "overlay_viewer_attribute_pointcloud_clipped" :
+ "overlay_viewer_attribute_pointcloud");
+ }
+ return sh_data->viewer_attribute_pointcloud;
+}
+
+GPUShader *OVERLAY_shader_viewer_attribute_curve(void)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
+ if (!sh_data->viewer_attribute_curve) {
+ sh_data->viewer_attribute_curve = GPU_shader_create_from_info_name(
+ draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED ? "overlay_viewer_attribute_curve_clipped" :
+ "overlay_viewer_attribute_curve");
+ }
+ return sh_data->viewer_attribute_curve;
+}
+
+GPUShader *OVERLAY_shader_viewer_attribute_curves(void)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
+ if (!sh_data->viewer_attribute_curves) {
+ sh_data->viewer_attribute_curves = GPU_shader_create_from_info_name(
+ draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED ? "overlay_viewer_attribute_curves_clipped" :
+ "overlay_viewer_attribute_curves");
+ }
+ return sh_data->viewer_attribute_curves;
+}
+
struct GPUShader *OVERLAY_shader_uniform_color(void)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -829,6 +883,18 @@ struct GPUShader *OVERLAY_shader_uniform_color(void)
return sh_data->uniform_color;
}
+struct GPUShader *OVERLAY_shader_uniform_color_pointcloud()
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
+ if (!sh_data->uniform_color_pointcloud) {
+ sh_data->uniform_color_pointcloud = GPU_shader_create_from_info_name(
+ draw_ctx->sh_cfg ? "overlay_uniform_color_pointcloud_clipped" :
+ "overlay_uniform_color_pointcloud");
+ }
+ return sh_data->uniform_color_pointcloud;
+}
+
struct GPUShader *OVERLAY_shader_volume_velocity(bool use_needle, bool use_mac)
{
OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
@@ -996,7 +1062,7 @@ GPUShader *OVERLAY_shader_edit_uv_tiled_image_borders_get(void)
/** \} */
-static OVERLAY_InstanceFormats g_formats = {NULL};
+static OVERLAY_InstanceFormats g_formats = {nullptr};
OVERLAY_InstanceFormats *OVERLAY_shader_instance_formats_get(void)
{
diff --git a/source/blender/draw/engines/overlay/overlay_shader_shared.h b/source/blender/draw/engines/overlay/overlay_shader_shared.h
index 339b6f02e1a..739e5be6c2f 100644
--- a/source/blender/draw/engines/overlay/overlay_shader_shared.h
+++ b/source/blender/draw/engines/overlay/overlay_shader_shared.h
@@ -38,6 +38,9 @@ enum OVERLAY_GridBits {
PLANE_IMAGE = (1u << 11u),
CUSTOM_GRID = (1u << 12u),
};
+#ifndef GPU_SHADER
+ENUM_OPERATORS(OVERLAY_GridBits, CUSTOM_GRID)
+#endif
/* Match: #SI_GRID_STEPS_LEN */
#define OVERLAY_GRID_STEPS_LEN 8
diff --git a/source/blender/draw/engines/overlay/overlay_viewer_attribute.cc b/source/blender/draw/engines/overlay/overlay_viewer_attribute.cc
new file mode 100644
index 00000000000..fd1657b3d59
--- /dev/null
+++ b/source/blender/draw/engines/overlay/overlay_viewer_attribute.cc
@@ -0,0 +1,181 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup draw_engine
+ */
+
+#include "DRW_render.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_pointcloud_types.h"
+
+#include "BLI_math_vector.hh"
+#include "BLI_span.hh"
+
+#include "GPU_batch.h"
+
+#include "BKE_attribute.hh"
+#include "BKE_curves.hh"
+#include "BKE_duplilist.h"
+#include "BKE_geometry_set.hh"
+
+#include "draw_cache_extract.hh"
+#include "draw_cache_impl.h"
+#include "overlay_private.hh"
+
+void OVERLAY_viewer_attribute_cache_init(OVERLAY_Data *vedata)
+{
+ OVERLAY_PassList *psl = vedata->psl;
+ OVERLAY_PrivateData *pd = vedata->stl->pd;
+
+ const DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL |
+ DRW_STATE_BLEND_ALPHA;
+ DRW_PASS_CREATE(psl->attribute_ps, state | pd->clipping_state);
+
+ GPUShader *mesh_sh = OVERLAY_shader_viewer_attribute_mesh();
+ GPUShader *pointcloud_sh = OVERLAY_shader_viewer_attribute_pointcloud();
+ GPUShader *curve_sh = OVERLAY_shader_viewer_attribute_curve();
+ GPUShader *curves_sh = OVERLAY_shader_viewer_attribute_curves();
+ GPUShader *uniform_sh = OVERLAY_shader_uniform_color();
+ GPUShader *uniform_pointcloud_sh = OVERLAY_shader_uniform_color_pointcloud();
+ pd->viewer_attribute_mesh_grp = DRW_shgroup_create(mesh_sh, psl->attribute_ps);
+ pd->viewer_attribute_pointcloud_grp = DRW_shgroup_create(pointcloud_sh, psl->attribute_ps);
+ pd->viewer_attribute_curve_grp = DRW_shgroup_create(curve_sh, psl->attribute_ps);
+ pd->viewer_attribute_curves_grp = DRW_shgroup_create(curves_sh, psl->attribute_ps);
+ pd->viewer_attribute_instance_grp = DRW_shgroup_create(uniform_sh, psl->attribute_ps);
+ pd->viewer_attribute_instance_pointcloud_grp = DRW_shgroup_create(uniform_pointcloud_sh,
+ psl->attribute_ps);
+}
+
+static void populate_cache_for_instance(Object &object,
+ OVERLAY_PrivateData &pd,
+ const DupliObject &dupli_object,
+ const float opacity)
+{
+ using namespace blender;
+ using namespace blender::bke;
+
+ const GeometrySet &base_geometry = *dupli_object.preview_base_geometry;
+ const InstancesComponent &instances =
+ *base_geometry.get_component_for_read<InstancesComponent>();
+ const AttributeAccessor instance_attributes = *instances.attributes();
+ const VArray attribute = instance_attributes.lookup<ColorGeometry4f>(".viewer");
+ if (!attribute) {
+ return;
+ }
+ ColorGeometry4f color = attribute.get(dupli_object.preview_instance_index);
+ color.a *= opacity;
+ switch (object.type) {
+ case OB_MESH: {
+ {
+ DRWShadingGroup *sub_grp = DRW_shgroup_create_sub(pd.viewer_attribute_instance_grp);
+ DRW_shgroup_uniform_vec4_copy(sub_grp, "ucolor", color);
+ GPUBatch *batch = DRW_cache_mesh_surface_get(&object);
+ DRW_shgroup_call(sub_grp, batch, &object);
+ }
+ if (GPUBatch *batch = DRW_cache_mesh_loose_edges_get(&object)) {
+ DRWShadingGroup *sub_grp = DRW_shgroup_create_sub(pd.viewer_attribute_instance_grp);
+ DRW_shgroup_uniform_vec4_copy(sub_grp, "ucolor", color);
+ DRW_shgroup_call(sub_grp, batch, &object);
+ }
+ break;
+ }
+ case OB_POINTCLOUD: {
+ DRWShadingGroup *sub_grp = DRW_shgroup_pointcloud_create_sub(
+ &object, pd.viewer_attribute_pointcloud_grp, nullptr);
+ DRW_shgroup_uniform_vec4_copy(sub_grp, "ucolor", color);
+ break;
+ }
+ case OB_CURVES_LEGACY: {
+ DRWShadingGroup *sub_grp = DRW_shgroup_create_sub(pd.viewer_attribute_instance_grp);
+ DRW_shgroup_uniform_vec4_copy(sub_grp, "ucolor", color);
+ GPUBatch *batch = DRW_cache_curve_edge_wire_get(&object);
+ DRW_shgroup_call_obmat(sub_grp, batch, object.object_to_world);
+ break;
+ }
+ case OB_CURVES: {
+ /* Not supported yet because instances of this type are currently drawn as legacy curves.
+ */
+ break;
+ }
+ }
+}
+
+static void populate_cache_for_geometry(Object &object,
+ OVERLAY_PrivateData &pd,
+ const float opacity)
+{
+ using namespace blender;
+ using namespace blender::bke;
+
+ switch (object.type) {
+ case OB_MESH: {
+ Mesh *mesh = static_cast<Mesh *>(object.data);
+ if (mesh->attributes().contains(".viewer")) {
+ GPUBatch *batch = DRW_cache_mesh_surface_viewer_attribute_get(&object);
+ DRW_shgroup_uniform_float_copy(pd.viewer_attribute_mesh_grp, "opacity", opacity);
+ DRW_shgroup_call(pd.viewer_attribute_mesh_grp, batch, &object);
+ }
+ break;
+ }
+ case OB_POINTCLOUD: {
+ PointCloud *pointcloud = static_cast<PointCloud *>(object.data);
+ if (pointcloud->attributes().contains(".viewer")) {
+ GPUVertBuf **vertbuf = DRW_pointcloud_evaluated_attribute(pointcloud, ".viewer");
+ DRWShadingGroup *grp = DRW_shgroup_pointcloud_create_sub(
+ &object, pd.viewer_attribute_pointcloud_grp, nullptr);
+ DRW_shgroup_uniform_float_copy(grp, "opacity", opacity);
+ DRW_shgroup_buffer_texture_ref(grp, "attribute_tx", vertbuf);
+ }
+ break;
+ }
+ case OB_CURVES_LEGACY: {
+ Curve *curve = static_cast<Curve *>(object.data);
+ const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curve->curve_eval->geometry);
+ if (curves.attributes().contains(".viewer")) {
+ GPUBatch *batch = DRW_cache_curve_edge_wire_viewer_attribute_get(&object);
+ DRW_shgroup_uniform_float_copy(pd.viewer_attribute_curve_grp, "opacity", opacity);
+ DRW_shgroup_call_obmat(pd.viewer_attribute_curve_grp, batch, object.object_to_world);
+ }
+ break;
+ }
+ case OB_CURVES: {
+ Curves *curves_id = static_cast<Curves *>(object.data);
+ const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry);
+ if (curves.attributes().contains(".viewer")) {
+ bool is_point_domain;
+ GPUVertBuf **texture = DRW_curves_texture_for_evaluated_attribute(
+ curves_id, ".viewer", &is_point_domain);
+ DRWShadingGroup *grp = DRW_shgroup_curves_create_sub(
+ &object, pd.viewer_attribute_curves_grp, nullptr);
+ DRW_shgroup_uniform_float_copy(pd.viewer_attribute_curves_grp, "opacity", opacity);
+ DRW_shgroup_uniform_bool_copy(grp, "is_point_domain", is_point_domain);
+ DRW_shgroup_buffer_texture(grp, "color_tx", *texture);
+ }
+ break;
+ }
+ }
+}
+
+void OVERLAY_viewer_attribute_cache_populate(OVERLAY_Data *vedata, Object *object)
+{
+ OVERLAY_PrivateData *pd = vedata->stl->pd;
+ const float opacity = vedata->stl->pd->overlay.viewer_attribute_opacity;
+ DupliObject *dupli_object = DRW_object_get_dupli(object);
+
+ if (dupli_object->preview_instance_index >= 0) {
+ const InstancesComponent &instances =
+ *dupli_object->preview_base_geometry->get_component_for_read<InstancesComponent>();
+ if (instances.attributes()->contains(".viewer")) {
+ populate_cache_for_instance(*object, *pd, *dupli_object, opacity);
+ return;
+ }
+ }
+ populate_cache_for_geometry(*object, *pd, opacity);
+}
+
+void OVERLAY_viewer_attribute_draw(OVERLAY_Data *vedata)
+{
+ OVERLAY_PassList *psl = vedata->psl;
+ DRW_draw_pass(psl->attribute_ps);
+}
diff --git a/source/blender/draw/engines/overlay/overlay_volume.c b/source/blender/draw/engines/overlay/overlay_volume.cc
index ee0d80734ab..daf76c394b3 100644
--- a/source/blender/draw/engines/overlay/overlay_volume.c
+++ b/source/blender/draw/engines/overlay/overlay_volume.cc
@@ -9,7 +9,7 @@
#include "DRW_render.h"
#include "GPU_shader.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_volume_cache_init(OVERLAY_Data *vedata)
{
@@ -25,8 +25,8 @@ void OVERLAY_volume_cache_init(OVERLAY_Data *vedata)
pd->volume_selection_surface_grp = grp;
}
else {
- psl->volume_ps = NULL;
- pd->volume_selection_surface_grp = NULL;
+ psl->volume_ps = nullptr;
+ pd->volume_selection_surface_grp = nullptr;
}
}
@@ -37,7 +37,7 @@ void OVERLAY_volume_cache_populate(OVERLAY_Data *vedata, Object *ob)
if (is_select) {
struct GPUBatch *geom = DRW_cache_volume_selection_surface_get(ob);
- if (geom != NULL) {
+ if (geom != nullptr) {
DRW_shgroup_call(pd->volume_selection_surface_grp, geom, ob);
}
}
diff --git a/source/blender/draw/engines/overlay/overlay_wireframe.c b/source/blender/draw/engines/overlay/overlay_wireframe.cc
index a5628559cfd..7053d0039cf 100644
--- a/source/blender/draw/engines/overlay/overlay_wireframe.c
+++ b/source/blender/draw/engines/overlay/overlay_wireframe.cc
@@ -27,7 +27,7 @@
#include "ED_view3d.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_wireframe_init(OVERLAY_Data *vedata)
{
@@ -43,7 +43,7 @@ void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata)
OVERLAY_TextureList *txl = vedata->txl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
const DRWContextState *draw_ctx = DRW_context_state_get();
- DRWShadingGroup *grp = NULL;
+ DRWShadingGroup *grp = nullptr;
View3DShading *shading = &draw_ctx->v3d->shading;
@@ -112,7 +112,7 @@ void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata)
pd->wires_hair_grp[1][use_coloring] = pd->wires_hair_grp[0][use_coloring];
}
pd->wires_sculpt_grp[1] = pd->wires_sculpt_grp[0];
- psl->wireframe_xray_ps = NULL;
+ psl->wireframe_xray_ps = nullptr;
}
}
@@ -125,26 +125,26 @@ static void wireframe_hair_cache_populate(OVERLAY_Data *vedata, Object *ob, Part
DupliObject *dupli_object = DRW_object_get_dupli(ob);
float dupli_mat[4][4];
- if ((dupli_parent != NULL) && (dupli_object != NULL)) {
+ if ((dupli_parent != nullptr) && (dupli_object != nullptr)) {
if (dupli_object->type & OB_DUPLICOLLECTION) {
unit_m4(dupli_mat);
Collection *collection = dupli_parent->instance_collection;
- if (collection != NULL) {
+ if (collection != nullptr) {
sub_v3_v3(dupli_mat[3], collection->instance_offset);
}
- mul_m4_m4m4(dupli_mat, dupli_parent->obmat, dupli_mat);
+ mul_m4_m4m4(dupli_mat, dupli_parent->object_to_world, dupli_mat);
}
else {
- copy_m4_m4(dupli_mat, dupli_object->ob->obmat);
+ copy_m4_m4(dupli_mat, dupli_object->ob->object_to_world);
invert_m4(dupli_mat);
- mul_m4_m4m4(dupli_mat, ob->obmat, dupli_mat);
+ mul_m4_m4m4(dupli_mat, ob->object_to_world, dupli_mat);
}
}
else {
unit_m4(dupli_mat);
}
- struct GPUBatch *hairs = DRW_cache_particles_get_hair(ob, psys, NULL);
+ struct GPUBatch *hairs = DRW_cache_particles_get_hair(ob, psys, nullptr);
const bool use_coloring = true;
DRWShadingGroup *shgrp = DRW_shgroup_create_sub(pd->wires_hair_grp[is_xray][use_coloring]);
@@ -167,7 +167,7 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
bool is_mesh_verts_only = false;
if (is_mesh) {
/* TODO: Should be its own function. */
- Mesh *me = ob->data;
+ Mesh *me = static_cast<Mesh *>(ob->data);
if (is_edit_mode) {
BLI_assert(me->edit_mesh);
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob);
@@ -184,7 +184,9 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
(ob->dtx & OB_DRAWWIRE) || (ob->dt == OB_WIRE));
if (use_wire && pd->wireframe_mode && ob->particlesystem.first) {
- for (ParticleSystem *psys = ob->particlesystem.first; psys != NULL; psys = psys->next) {
+ for (ParticleSystem *psys = static_cast<ParticleSystem *>(ob->particlesystem.first);
+ psys != nullptr;
+ psys = psys->next) {
if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
continue;
}
@@ -201,7 +203,7 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
float *color;
DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color);
- struct GPUBatch *geom = NULL;
+ struct GPUBatch *geom = nullptr;
switch (ob->type) {
case OB_CURVES_LEGACY:
geom = DRW_cache_curve_edge_wire_get(ob);
@@ -215,7 +217,7 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
}
if (geom) {
- OVERLAY_extra_wire(cb, geom, ob->obmat, color);
+ OVERLAY_extra_wire(cb, geom, ob->object_to_world, color);
}
}
@@ -228,12 +230,12 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
if (dupli->wire_shgrp == cb->extra_loose_points) {
float *color;
DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color);
- OVERLAY_extra_loose_points(cb, dupli->wire_geom, ob->obmat, color);
+ OVERLAY_extra_loose_points(cb, dupli->wire_geom, ob->object_to_world, color);
}
else if (dupli->wire_shgrp == cb->extra_wire) {
float *color;
DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color);
- OVERLAY_extra_wire(cb, dupli->wire_geom, ob->obmat, color);
+ OVERLAY_extra_wire(cb, dupli->wire_geom, ob->object_to_world, color);
}
else {
DRW_shgroup_call(dupli->wire_shgrp, dupli->wire_geom, ob);
@@ -251,7 +253,7 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
bool draw_as_points = true;
if (ob->type == OB_VOLUME) {
/* Volume object as points exception. */
- Volume *volume = ob->data;
+ Volume *volume = static_cast<Volume *>(ob->data);
draw_as_points = volume->display.wireframe_type == VOLUME_WIREFRAME_POINTS;
}
@@ -262,19 +264,19 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
struct GPUBatch *geom = DRW_cache_object_face_wireframe_get(ob);
if (geom) {
- OVERLAY_extra_loose_points(cb, geom, ob->obmat, color);
+ OVERLAY_extra_loose_points(cb, geom, ob->object_to_world, color);
}
return;
}
}
- DRWShadingGroup *shgrp = NULL;
- struct GPUBatch *geom = NULL;
+ DRWShadingGroup *shgrp = nullptr;
+ struct GPUBatch *geom = nullptr;
/* Don't do that in edit Mesh mode, unless there is a modifier preview. */
if (use_wire && (!is_mesh || (!is_edit_mode || has_edit_mesh_cage))) {
- const bool is_sculpt_mode = ((ob->mode & OB_MODE_SCULPT) != 0) && (ob->sculpt != NULL);
- const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) &&
+ const bool is_sculpt_mode = ((ob->mode & OB_MODE_SCULPT) != 0) && (ob->sculpt != nullptr);
+ const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->rv3d) &&
!DRW_state_is_image_render();
const bool is_instance = (ob->base_flag & BASE_FROM_DUPLI);
const bool instance_parent_in_edit_mode = is_instance ? DRW_object_is_in_edit_mode(
@@ -300,7 +302,7 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
DRW_shgroup_call_no_cull(shgrp, geom, ob);
}
else if (use_sculpt_pbvh) {
- DRW_shgroup_call_sculpt(shgrp, ob, true, false);
+ DRW_shgroup_call_sculpt(shgrp, ob, true, false, false, false, false);
}
else {
DRW_shgroup_call(shgrp, geom, ob);
@@ -316,14 +318,14 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
if (is_mesh_verts_only) {
geom = DRW_cache_mesh_all_verts_get(ob);
if (geom) {
- OVERLAY_extra_loose_points(cb, geom, ob->obmat, color);
+ OVERLAY_extra_loose_points(cb, geom, ob->object_to_world, color);
shgrp = cb->extra_loose_points;
}
}
else {
geom = DRW_cache_mesh_loose_edges_get(ob);
if (geom) {
- OVERLAY_extra_wire(cb, geom, ob->obmat, color);
+ OVERLAY_extra_wire(cb, geom, ob->object_to_world, color);
shgrp = cb->extra_wire;
}
}
@@ -343,7 +345,7 @@ void OVERLAY_wireframe_draw(OVERLAY_Data *data)
DRW_view_set_active(pd->view_wires);
DRW_draw_pass(psl->wireframe_ps);
- DRW_view_set_active(NULL);
+ DRW_view_set_active(nullptr);
}
void OVERLAY_wireframe_in_front_draw(OVERLAY_Data *data)
@@ -355,6 +357,6 @@ void OVERLAY_wireframe_in_front_draw(OVERLAY_Data *data)
DRW_view_set_active(pd->view_wires);
DRW_draw_pass(psl->wireframe_xray_ps);
- DRW_view_set_active(NULL);
+ DRW_view_set_active(nullptr);
}
}
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh
index 9f2acceed97..caa18ece122 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh
@@ -69,6 +69,11 @@ GPU_SHADER_INTERFACE_INFO(overlay_armature_shape_outline_iface, "geom_in")
.smooth(Type::VEC4, "vColSize")
.flat(Type::INT, "inverted");
+GPU_SHADER_INTERFACE_INFO(overlay_armature_shape_outline_no_geom_iface, "")
+ .flat(Type::VEC4, "finalColor")
+ .flat(Type::VEC2, "edgeStart")
+ .no_perspective(Type::VEC2, "edgePos");
+
GPU_SHADER_CREATE_INFO(overlay_armature_shape_outline)
.do_static_compilation(true)
.vertex_in(0, Type::VEC3, "pos")
@@ -84,10 +89,26 @@ GPU_SHADER_CREATE_INFO(overlay_armature_shape_outline)
.fragment_source("overlay_armature_wire_frag.glsl")
.additional_info("overlay_frag_output", "overlay_armature_common", "draw_globals");
+GPU_SHADER_CREATE_INFO(overlay_armature_shape_outline_no_geom)
+ // .do_static_compilation(true) /* TODO fix on GL */
+ .vertex_in(0, Type::VEC3, "pos")
+ .vertex_in(1, Type::VEC3, "snor")
+ /* Per instance. */
+ .vertex_in(2, Type::VEC4, "color")
+ .vertex_in(3, Type::MAT4, "inst_obmat")
+ .vertex_out(overlay_armature_shape_outline_no_geom_iface)
+ .vertex_source("overlay_armature_shape_outline_vert_no_geom.glsl")
+ .fragment_source("overlay_armature_wire_frag.glsl")
+ .additional_info("overlay_frag_output", "overlay_armature_common", "draw_globals");
+
GPU_SHADER_CREATE_INFO(overlay_armature_shape_outline_clipped)
.do_static_compilation(true)
.additional_info("overlay_armature_shape_outline", "drw_clipped");
+GPU_SHADER_CREATE_INFO(overlay_armature_shape_outline_clipped_no_geom)
+ // .do_static_compilation(true) /* TODO fix on GL */
+ .additional_info("overlay_armature_shape_outline_no_geom", "drw_clipped");
+
GPU_SHADER_INTERFACE_INFO(overlay_armature_shape_solid_iface, "")
.smooth(Type::VEC4, "finalColor")
.flat(Type::INT, "inverted");
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_background_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_background_info.hh
index 88a012c35c9..8bc15400248 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_background_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_background_info.hh
@@ -15,7 +15,7 @@ GPU_SHADER_CREATE_INFO(overlay_background)
GPU_SHADER_CREATE_INFO(overlay_clipbound)
.do_static_compilation(true)
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.push_constant(Type::VEC3, "boundbox", 8)
.vertex_source("overlay_clipbound_vert.glsl")
.fragment_out(0, Type::VEC4, "fragColor")
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh
index 9396a6d3f2f..40b7249a997 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh
@@ -22,6 +22,17 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_common)
.vertex_source("overlay_edit_mesh_vert.glsl")
.additional_info("draw_modelmat", "draw_globals");
+GPU_SHADER_CREATE_INFO(overlay_edit_mesh_common_no_geom)
+ .define("blender_srgb_to_framebuffer_space(a)", "a")
+ .sampler(0, ImageType::DEPTH_2D, "depthTex")
+ .fragment_out(0, Type::VEC4, "fragColor")
+ .push_constant(Type::BOOL, "selectFaces")
+ .push_constant(Type::BOOL, "selectEdges")
+ .push_constant(Type::FLOAT, "alpha")
+ .push_constant(Type::IVEC4, "dataMask")
+ .vertex_source("overlay_edit_mesh_vert_no_geom.glsl")
+ .additional_info("draw_modelmat", "draw_globals");
+
GPU_SHADER_INTERFACE_INFO(overlay_edit_mesh_vert_iface, "")
.smooth(Type::VEC4, "finalColor")
.smooth(Type::FLOAT, "vertexCrease");
@@ -61,11 +72,28 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge)
.fragment_source("overlay_edit_mesh_frag.glsl")
.additional_info("overlay_edit_mesh_common");
+/* The Non-Geometry shader variant passes directly to fragment. */
+GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_no_geom)
+ // .do_static_compilation(true) /* TODO fix on GL */
+ .define("EDGE")
+ .vertex_in(0, Type::VEC3, "pos")
+ .vertex_in(1, Type::UCHAR4, "data")
+ .vertex_in(2, Type::VEC3_101010I2, "vnor")
+ .push_constant(Type::BOOL, "do_smooth_wire")
+ .vertex_out(overlay_edit_mesh_edge_geom_iface)
+ .fragment_source("overlay_edit_mesh_frag.glsl")
+ .additional_info("overlay_edit_mesh_common_no_geom");
+
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat)
.do_static_compilation(true)
.define("FLAT")
.additional_info("overlay_edit_mesh_edge");
+GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat_no_geom)
+ // .do_static_compilation(true) /* TODO fix on GL */
+ .define("FLAT")
+ .additional_info("overlay_edit_mesh_edge_no_geom");
+
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_face)
.do_static_compilation(true)
.define("FACE")
@@ -136,10 +164,18 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_clipped)
.do_static_compilation(true)
.additional_info("overlay_edit_mesh_edge", "drw_clipped");
+GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_clipped_no_geom)
+ // .do_static_compilation(true) /* TODO fix on GL */
+ .additional_info("overlay_edit_mesh_edge_no_geom", "drw_clipped");
+
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat_clipped)
.do_static_compilation(true)
.additional_info("overlay_edit_mesh_edge_flat", "drw_clipped");
+GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat_clipped_no_geom)
+ // .do_static_compilation(true) /* TODO fix on GL */
+ .additional_info("overlay_edit_mesh_edge_flat_no_geom", "drw_clipped");
+
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_face_clipped)
.do_static_compilation(true)
.additional_info("overlay_edit_mesh_face", "drw_clipped");
@@ -242,7 +278,7 @@ GPU_SHADER_CREATE_INFO(overlay_edit_uv_verts)
GPU_SHADER_CREATE_INFO(overlay_edit_uv_tiled_image_borders)
.do_static_compilation(true)
.vertex_in(0, Type::VEC3, "pos")
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.fragment_out(0, Type::VEC4, "fragColor")
.vertex_source("overlay_edit_uv_tiled_image_borders_vert.glsl")
.fragment_source("overlay_uniform_color_frag.glsl")
@@ -258,7 +294,7 @@ GPU_SHADER_CREATE_INFO(overlay_edit_uv_stencil_image)
.sampler(0, ImageType::FLOAT_2D, "imgTexture")
.push_constant(Type::BOOL, "imgPremultiplied")
.push_constant(Type::BOOL, "imgAlphaBlend")
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.fragment_out(0, Type::VEC4, "fragColor")
.fragment_source("overlay_image_frag.glsl")
.additional_info("draw_mesh");
@@ -326,10 +362,29 @@ GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle)
.fragment_source("overlay_varying_color.glsl")
.additional_info("draw_mesh", "draw_globals");
+GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle_no_geom)
+ // .do_static_compilation(true) /* TODO fix on GL */
+ .typedef_source("overlay_shader_shared.h")
+ /* NOTE: Color already in Linear space. Which is what we want. */
+ .define("srgbTarget", "false")
+ .vertex_in(0, Type::VEC3, "pos")
+ .vertex_in(1, Type::INT, "data")
+ .vertex_out(overlay_edit_curve_handle_iface)
+ .push_constant(Type::BOOL, "showCurveHandles")
+ .push_constant(Type::INT, "curveHandleDisplay")
+ .fragment_out(0, Type::VEC4, "fragColor")
+ .vertex_source("overlay_edit_curve_handle_vert_no_geom.glsl")
+ .fragment_source("overlay_varying_color.glsl")
+ .additional_info("draw_mesh", "draw_globals");
+
GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle_clipped)
.do_static_compilation(true)
.additional_info("overlay_edit_curve_handle", "drw_clipped");
+GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle_clipped_no_geom)
+ // .do_static_compilation(true) /* TODO fix on GL */
+ .additional_info("overlay_edit_curve_handle_no_geom", "drw_clipped");
+
GPU_SHADER_CREATE_INFO(overlay_edit_curve_point)
.do_static_compilation(true)
.typedef_source("overlay_shader_shared.h")
@@ -526,14 +581,26 @@ GPU_SHADER_CREATE_INFO(overlay_depth_only_clipped)
GPU_SHADER_CREATE_INFO(overlay_uniform_color)
.do_static_compilation(true)
.vertex_in(0, Type::VEC3, "pos")
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.fragment_out(0, Type::VEC4, "fragColor")
.vertex_source("overlay_depth_only_vert.glsl")
.fragment_source("overlay_uniform_color_frag.glsl")
.additional_info("draw_mesh");
+GPU_SHADER_CREATE_INFO(overlay_uniform_color_pointcloud)
+ .do_static_compilation(true)
+ .push_constant(Type::VEC4, "ucolor")
+ .fragment_out(0, Type::VEC4, "fragColor")
+ .vertex_source("overlay_pointcloud_only_vert.glsl")
+ .fragment_source("overlay_uniform_color_frag.glsl")
+ .additional_info("draw_pointcloud");
+
GPU_SHADER_CREATE_INFO(overlay_uniform_color_clipped)
.do_static_compilation(true)
.additional_info("overlay_depth_only", "drw_clipped");
+GPU_SHADER_CREATE_INFO(overlay_uniform_color_pointcloud_clipped)
+ .do_static_compilation(true)
+ .additional_info("overlay_uniform_color_pointcloud", "drw_clipped");
+
/** \} */
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh
index 5b50bbcaa55..4874f251d67 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh
@@ -110,12 +110,12 @@ GPU_SHADER_CREATE_INFO(overlay_extra_wire)
GPU_SHADER_CREATE_INFO(overlay_extra_wire_select)
.do_static_compilation(true)
.define("SELECT_EDGES")
- .additional_info("overlay_extra_wire", "drw_clipped");
+ .additional_info("overlay_extra_wire");
GPU_SHADER_CREATE_INFO(overlay_extra_wire_object)
.do_static_compilation(true)
.define("OBJECT_WIRE")
- .additional_info("overlay_extra_wire", "drw_clipped");
+ .additional_info("overlay_extra_wire");
GPU_SHADER_CREATE_INFO(overlay_extra_wire_select_clipped)
.do_static_compilation(true)
@@ -145,7 +145,7 @@ GPU_SHADER_CREATE_INFO(overlay_extra_point)
/* TODO(fclem): Move the vertex shader to Overlay engine and remove this bypass. */
.define("blender_srgb_to_framebuffer_space(a)", "a")
.vertex_in(0, Type::VEC3, "pos")
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.vertex_out(overlay_extra_point_iface)
.fragment_out(0, Type::VEC4, "fragColor")
.vertex_source("overlay_extra_point_vert.glsl")
@@ -161,7 +161,7 @@ GPU_SHADER_INTERFACE_INFO(overlay_extra_loose_point_iface, "").smooth(Type::VEC4
GPU_SHADER_CREATE_INFO(overlay_extra_loose_point)
.do_static_compilation(true)
.vertex_in(0, Type::VEC3, "pos")
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.vertex_out(overlay_extra_loose_point_iface)
.fragment_out(0, Type::VEC4, "fragColor")
.fragment_out(1, Type::VEC4, "lineOutput")
@@ -183,6 +183,9 @@ GPU_SHADER_INTERFACE_INFO(overlay_motion_path_line_iface, "interp")
.flat(Type::VEC2, "ss_pos")
.smooth(Type::VEC4, "color");
+GPU_SHADER_INTERFACE_INFO(overlay_motion_path_line_no_geom_iface, "interp")
+ .smooth(Type::VEC4, "color");
+
GPU_SHADER_CREATE_INFO(overlay_motion_path_line)
.do_static_compilation(true)
.vertex_in(0, Type::VEC3, "pos")
@@ -199,10 +202,27 @@ GPU_SHADER_CREATE_INFO(overlay_motion_path_line)
.fragment_source("overlay_motion_path_line_frag.glsl")
.additional_info("draw_view", "draw_globals");
+GPU_SHADER_CREATE_INFO(overlay_motion_path_line_no_geom)
+ // .do_static_compilation(true) /* TODO fix on GL */
+ .vertex_in(0, Type::VEC3, "pos")
+ .push_constant(Type::IVEC4, "mpathLineSettings")
+ .push_constant(Type::BOOL, "selected")
+ .push_constant(Type::VEC3, "customColor")
+ .push_constant(Type::INT, "lineThickness") /* In pixels. */
+ .vertex_out(overlay_motion_path_line_no_geom_iface)
+ .fragment_out(0, Type::VEC4, "fragColor")
+ .vertex_source("overlay_motion_path_line_vert_no_geom.glsl")
+ .fragment_source("overlay_motion_path_line_frag.glsl")
+ .additional_info("draw_view", "draw_globals");
+
GPU_SHADER_CREATE_INFO(overlay_motion_path_line_clipped)
.do_static_compilation(true)
.additional_info("overlay_motion_path_line", "drw_clipped");
+GPU_SHADER_CREATE_INFO(overlay_motion_path_line_clipped_no_geom)
+ // .do_static_compilation(true) /* TODO fix on GL */
+ .additional_info("overlay_motion_path_line_no_geom", "drw_clipped");
+
GPU_SHADER_INTERFACE_INFO(overlay_motion_path_point_iface, "").flat(Type::VEC4, "finalColor");
GPU_SHADER_CREATE_INFO(overlay_motion_path_point)
@@ -237,7 +257,7 @@ GPU_SHADER_CREATE_INFO(overlay_image)
.push_constant(Type::BOOL, "isCameraBackground")
.push_constant(Type::BOOL, "imgPremultiplied")
.push_constant(Type::BOOL, "imgAlphaBlend")
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.vertex_in(0, Type::VEC3, "pos")
.vertex_out(overlay_image_iface)
.sampler(0, ImageType::FLOAT_2D, "imgTexture")
@@ -284,7 +304,7 @@ GPU_SHADER_INTERFACE_INFO(overlay_particle_iface, "").flat(Type::VEC4, "finalCol
GPU_SHADER_CREATE_INFO(overlay_particle)
.sampler(0, ImageType::FLOAT_1D, "weightTex")
- .push_constant(Type::VEC4, "color") /* Draw-size packed in alpha. */
+ .push_constant(Type::VEC4, "ucolor") /* Draw-size packed in alpha. */
.vertex_in(0, Type::VEC3, "part_pos")
.vertex_in(1, Type::VEC4, "part_rot")
.vertex_in(2, Type::FLOAT, "part_val")
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_grid_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_grid_info.hh
index a8f1281d53a..70175b7072f 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_grid_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_grid_info.hh
@@ -32,7 +32,7 @@ GPU_SHADER_CREATE_INFO(overlay_grid_background)
GPU_SHADER_CREATE_INFO(overlay_grid_image)
.do_static_compilation(true)
.vertex_in(0, Type::VEC3, "pos")
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.fragment_out(0, Type::VEC4, "fragColor")
.vertex_source("overlay_edit_uv_tiled_image_borders_vert.glsl")
.fragment_source("overlay_uniform_color_frag.glsl")
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_outline_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_outline_info.hh
index 288fb3b3cbd..abf9e873b29 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_outline_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_outline_info.hh
@@ -14,7 +14,7 @@ GPU_SHADER_CREATE_INFO(overlay_outline_prepass)
/* Using uint because 16bit uint can contain more ids than int. */
.fragment_out(0, Type::UINT, "out_object_id")
.fragment_source("overlay_outline_prepass_frag.glsl")
- .additional_info("draw_resource_handle");
+ .additional_info("draw_resource_handle", "draw_globals");
GPU_SHADER_CREATE_INFO(overlay_outline_prepass_mesh)
.do_static_compilation(true)
@@ -72,7 +72,7 @@ GPU_SHADER_CREATE_INFO(overlay_outline_prepass_gpencil)
/* Using uint because 16bit uint can contain more ids than int. */
.fragment_out(0, Type::UINT, "out_object_id")
.fragment_source("overlay_outline_prepass_gpencil_frag.glsl")
- .additional_info("draw_gpencil", "draw_resource_handle");
+ .additional_info("draw_gpencil", "draw_resource_handle", "draw_globals");
GPU_SHADER_CREATE_INFO(overlay_outline_prepass_gpencil_clipped)
.do_static_compilation(true)
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_paint_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_paint_info.hh
index 3083d5a463b..08b421de3e6 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_paint_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_paint_info.hh
@@ -12,7 +12,7 @@ GPU_SHADER_CREATE_INFO(overlay_paint_face)
.do_static_compilation(true)
.vertex_in(0, Type::VEC3, "pos")
.vertex_in(1, Type::VEC4, "nor") /* Select flag on the 4th component. */
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.fragment_out(0, Type::VEC4, "fragColor")
.vertex_source("overlay_paint_face_vert.glsl")
.fragment_source("overlay_uniform_color_frag.glsl")
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_viewer_attribute_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_viewer_attribute_info.hh
new file mode 100644
index 00000000000..6a0bd03f030
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_viewer_attribute_info.hh
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_INTERFACE_INFO(overlay_viewer_attribute_iface, "").smooth(Type::VEC4, "finalColor");
+
+GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_common).push_constant(Type::FLOAT, "opacity");
+
+GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_mesh)
+ .do_static_compilation(true)
+ .vertex_source("overlay_viewer_attribute_mesh_vert.glsl")
+ .fragment_source("overlay_viewer_attribute_frag.glsl")
+ .fragment_out(0, Type::VEC4, "out_color")
+ .fragment_out(1, Type::VEC4, "lineOutput")
+ .vertex_in(0, Type::VEC3, "pos")
+ .vertex_in(1, Type::VEC4, "attribute_value")
+ .vertex_out(overlay_viewer_attribute_iface)
+ .additional_info("overlay_viewer_attribute_common", "draw_mesh");
+
+GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_mesh_clipped)
+ .do_static_compilation(true)
+ .additional_info("overlay_viewer_attribute_mesh", "drw_clipped");
+
+GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_pointcloud)
+ .do_static_compilation(true)
+ .vertex_source("overlay_viewer_attribute_pointcloud_vert.glsl")
+ .fragment_source("overlay_viewer_attribute_frag.glsl")
+ .fragment_out(0, Type::VEC4, "out_color")
+ .fragment_out(1, Type::VEC4, "lineOutput")
+ .sampler(3, ImageType::FLOAT_BUFFER, "attribute_tx")
+ .vertex_out(overlay_viewer_attribute_iface)
+ .additional_info("overlay_viewer_attribute_common", "draw_pointcloud");
+
+GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_pointcloud_clipped)
+ .do_static_compilation(true)
+ .additional_info("overlay_viewer_attribute_pointcloud", "drw_clipped");
+
+GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_curve)
+ .do_static_compilation(true)
+ .vertex_source("overlay_viewer_attribute_curve_vert.glsl")
+ .fragment_source("overlay_viewer_attribute_frag.glsl")
+ .fragment_out(0, Type::VEC4, "out_color")
+ .fragment_out(1, Type::VEC4, "lineOutput")
+ .vertex_in(0, Type::VEC3, "pos")
+ .vertex_in(1, Type::VEC4, "attribute_value")
+ .vertex_out(overlay_viewer_attribute_iface)
+ .additional_info("overlay_viewer_attribute_common", "draw_modelmat", "draw_resource_id");
+
+GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_curve_clipped)
+ .do_static_compilation(true)
+ .additional_info("overlay_viewer_attribute_curve", "drw_clipped");
+
+GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_curves)
+ .do_static_compilation(true)
+ .vertex_source("overlay_viewer_attribute_curves_vert.glsl")
+ .fragment_source("overlay_viewer_attribute_frag.glsl")
+ .fragment_out(0, Type::VEC4, "out_color")
+ .fragment_out(1, Type::VEC4, "lineOutput")
+ .sampler(0, ImageType::FLOAT_BUFFER, "color_tx")
+ .push_constant(Type::BOOL, "is_point_domain")
+ .vertex_out(overlay_viewer_attribute_iface)
+ .additional_info("overlay_viewer_attribute_common", "draw_hair");
+
+GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_curves_clipped)
+ .do_static_compilation(true)
+ .additional_info("overlay_viewer_attribute_curves", "drw_clipped");
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl
index ca5a6aff2ca..c13698728ef 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl
@@ -137,7 +137,7 @@ void main()
vec2 ofs_dir = compute_dir(ss0, ss1, ss2);
/* Offset away from the center to avoid overlap with solid shape. */
- gl_Position.xy += ofs_dir * drw_view.viewport_size_inverse * gl_Position.w;
+ gl_Position.xy += ofs_dir * sizeViewportInv * gl_Position.w;
edgeStart = edgePos = proj(gl_Position);
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_solid_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_solid_vert.glsl
index 4d21ffd96b5..17aed643224 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_solid_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_solid_vert.glsl
@@ -38,5 +38,5 @@ void main()
view_clipping_distances(sp);
vec4 pos_4d = vec4(sp, 1.0);
- gl_Position = drw_view.persmat * pos_4d;
+ gl_Position = drw_view.winmat * (drw_view.viewmat * pos_4d);
}
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_geom.glsl
index b485b0a7807..65a2fcc1977 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_geom.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_geom.glsl
@@ -56,7 +56,7 @@ void main(void)
gl_Position = geom_in[1].pPos;
/* Offset away from the center to avoid overlap with solid shape. */
- gl_Position.xy += (edge_dir - perp) * drw_view.viewport_size_inverse * gl_Position.w;
+ gl_Position.xy += (edge_dir - perp) * sizeViewportInv * gl_Position.w;
/* Improve AA bleeding inside bone silhouette. */
gl_Position.z -= (is_persp) ? 1e-4 : 1e-6;
edgeStart = edgePos = ((gl_Position.xy / gl_Position.w) * 0.5 + 0.5) * sizeViewport;
@@ -65,7 +65,7 @@ void main(void)
gl_Position = geom_in[2].pPos;
/* Offset away from the center to avoid overlap with solid shape. */
- gl_Position.xy += (edge_dir + perp) * drw_view.viewport_size_inverse * gl_Position.w;
+ gl_Position.xy += (edge_dir + perp) * sizeViewportInv * gl_Position.w;
/* Improve AA bleeding inside bone silhouette. */
gl_Position.z -= (is_persp) ? 1e-4 : 1e-6;
edgeStart = edgePos = ((gl_Position.xy / gl_Position.w) * 0.5 + 0.5) * sizeViewport.xy;
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert.glsl
index 91eb6265192..bb45f213046 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert.glsl
@@ -25,8 +25,8 @@ void main()
* doing it per instance on CPU and sending it on via instance attribute. */
mat3 normal_mat = transpose(inverse(mat3(model_mat)));
/* TODO: FIX: there is still a problem with this vector
- * when the bone is scaled or in persp mode. But it's
- * barely visible at the outline corners. */
+ * when the bone is scaled or in perspective mode.
+ * But it's barely visible at the outline corners. */
geom_in.ssNor = normalize(normal_world_to_view(normal_mat * snor).xy);
geom_in.ssPos = proj(geom_in.pPos);
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl
new file mode 100644
index 00000000000..57c0ecb0b9b
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl
@@ -0,0 +1,178 @@
+
+#pragma USE_SSBO_VERTEX_FETCH(LineList, 2)
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+#define DISCARD_VERTEX \
+ gl_Position = finalColor = vec4(0.0); \
+ edgeStart = edgePos = vec2(0.0); \
+ return;
+
+/* Project to screen space. */
+vec2 proj(vec4 pos)
+{
+ return (0.5 * (pos.xy / pos.w) + 0.5) * sizeViewport.xy;
+}
+
+void do_vertex_shader(mat4 in_inst_obmat,
+ vec3 in_pos,
+ vec3 in_snor,
+ out vec4 out_pPos,
+ out vec3 out_vPos,
+ out vec2 out_ssPos,
+ out vec2 out_ssNor,
+ out vec4 out_vColSize,
+ out int out_inverted,
+ out vec4 out_wpos)
+{
+ vec4 bone_color, state_color;
+ mat4 model_mat = extract_matrix_packed_data(in_inst_obmat, state_color, bone_color);
+
+ vec4 worldPosition = model_mat * vec4(in_pos, 1.0);
+ vec4 viewpos = ViewMatrix * worldPosition;
+ out_wpos = worldPosition;
+ out_vPos = viewpos.xyz;
+ out_pPos = ProjectionMatrix * viewpos;
+
+ out_inverted = int(dot(cross(model_mat[0].xyz, model_mat[1].xyz), model_mat[2].xyz) < 0.0);
+
+ /* This is slow and run per vertex, but it's still faster than
+ * doing it per instance on CPU and sending it on via instance attribute. */
+ mat3 normal_mat = transpose(inverse(mat3(model_mat)));
+ /* TODO FIX: there is still a problem with this vector
+ * when the bone is scaled or in persp mode. But it's
+ * barely visible at the outline corners. */
+ out_ssNor = normalize(normal_world_to_view(normal_mat * in_snor).xy);
+
+ out_ssPos = proj(out_pPos);
+
+ out_vColSize = bone_color;
+}
+
+void main()
+{
+ /* Outputs a singular vertex as part of a LineList primitive, however, requires access to
+ * neighboring 4 vertices. */
+ /* Fetch verts from input type lines adjacency. */
+ int line_prim_id = (gl_VertexID / 2);
+ int line_vertex_id = gl_VertexID % 2;
+ int base_vertex_id = line_prim_id * 2;
+
+ /* IF Input Primitive Type == Lines_Adjacency, then indices are accessed as per GL specification:
+ * i.e. 4 indices per unique prim (Provoking vert 4i-2)
+ *
+ * IF Input Primitive Type == LineStrip_Adjacency, then indices are accessed using:
+ * - 2 indices per unique prim, plus 1 index at each end, such that the strided
+ * - 4-index block can be walked. */
+ vec3 in_pos[4];
+ in_pos[0] = vertex_fetch_attribute_raw(vertex_id_from_index_id(4 * line_prim_id), pos, vec3);
+ in_pos[1] = vertex_fetch_attribute_raw(vertex_id_from_index_id(4 * line_prim_id + 1), pos, vec3);
+ in_pos[2] = vertex_fetch_attribute_raw(vertex_id_from_index_id(4 * line_prim_id + 2), pos, vec3);
+ in_pos[3] = vertex_fetch_attribute_raw(vertex_id_from_index_id(4 * line_prim_id + 3), pos, vec3);
+
+ vec3 in_snor[4];
+ in_snor[0] = vertex_fetch_attribute_raw(vertex_id_from_index_id(4 * line_prim_id), snor, vec3);
+ in_snor[1] = vertex_fetch_attribute_raw(
+ vertex_id_from_index_id(4 * line_prim_id + 1), snor, vec3);
+ in_snor[2] = vertex_fetch_attribute_raw(
+ vertex_id_from_index_id(4 * line_prim_id + 2), snor, vec3);
+ in_snor[3] = vertex_fetch_attribute_raw(
+ vertex_id_from_index_id(4 * line_prim_id + 3), snor, vec3);
+
+ mat4 in_inst_obmat = vertex_fetch_attribute(gl_VertexID, inst_obmat, mat4);
+
+ /* Run original GL vertex shader implementation per vertex in adjacency list. */
+ vec4 pPos[4];
+ vec3 vPos[4];
+ vec2 ssPos[4];
+ vec2 ssNor[4];
+ vec4 vColSize[4];
+ int inverted[4];
+ vec4 wPos[4];
+
+ for (int v = 0; v < 4; v++) {
+ do_vertex_shader(in_inst_obmat,
+ in_pos[v],
+ in_snor[v],
+ pPos[v],
+ vPos[v],
+ ssPos[v],
+ ssNor[v],
+ vColSize[v],
+ inverted[v],
+ wPos[v]);
+ }
+
+ /* Geometry Shader equivalent to calculate vertex output position. */
+ finalColor = vec4(vColSize[0].rgb, 1.0);
+
+ bool is_persp = (ProjectionMatrix[3][3] == 0.0);
+
+ vec3 view_vec = (is_persp) ? normalize(vPos[1]) : vec3(0.0, 0.0, -1.0);
+ vec3 v10 = vPos[0] - vPos[1];
+ vec3 v12 = vPos[2] - vPos[1];
+ vec3 v13 = vPos[3] - vPos[1];
+
+ vec3 n0 = cross(v12, v10);
+ vec3 n3 = cross(v13, v12);
+
+ float fac0 = dot(view_vec, n0);
+ float fac3 = dot(view_vec, n3);
+
+ /* If one of the face is perpendicular to the view,
+ * consider it and outline edge. */
+ if (abs(fac0) > 1e-5 && abs(fac3) > 1e-5) {
+ /* If both adjacent verts are facing the camera the same way,
+ * then it isn't an outline edge. */
+ if (sign(fac0) == sign(fac3)) {
+ DISCARD_VERTEX
+ }
+ }
+
+ n0 = (inverted[0] == 1) ? -n0 : n0;
+ /* Don't outline if concave edge. */
+ if (dot(n0, v13) > 0.0001) {
+ DISCARD_VERTEX
+ }
+
+ vec2 perp = normalize(ssPos[2] - ssPos[1]);
+ vec2 edge_dir = vec2(-perp.y, perp.x);
+
+ vec2 hidden_point;
+ /* Take the farthest point to compute edge direction
+ * (avoid problems with point behind near plane).
+ * If the chosen point is parallel to the edge in screen space,
+ * choose the other point anyway.
+ * This fixes some issue with cubes in orthographic views.*/
+ if (vPos[0].z < vPos[3].z) {
+ hidden_point = (abs(fac0) > 1e-5) ? ssPos[0] : ssPos[3];
+ }
+ else {
+ hidden_point = (abs(fac3) > 1e-5) ? ssPos[3] : ssPos[0];
+ }
+ vec2 hidden_dir = normalize(hidden_point - ssPos[1]);
+
+ float fac = dot(-hidden_dir, edge_dir);
+ edge_dir *= (fac < 0.0) ? -1.0 : 1.0;
+
+ /* Output corresponding value based on which vertex this corresponds to in the
+ * original input primitive. */
+ if (line_vertex_id == 0) {
+ gl_Position = pPos[1];
+ /* Offset away from the center to avoid overlap with solid shape. */
+ gl_Position.xy += (edge_dir - perp) * sizeViewportInv * gl_Position.w;
+ /* Improve AA bleeding inside bone silhouette. */
+ gl_Position.z -= (is_persp) ? 1e-4 : 1e-6;
+ edgeStart = edgePos = ((gl_Position.xy / gl_Position.w) * 0.5 + 0.5) * sizeViewport.xy;
+ view_clipping_distances(wPos[1].xyz);
+ }
+ else {
+ gl_Position = pPos[2];
+ /* Offset away from the center to avoid overlap with solid shape. */
+ gl_Position.xy += (edge_dir + perp) * sizeViewportInv * gl_Position.w;
+ /* Improve AA bleeding inside bone silhouette. */
+ gl_Position.z -= (is_persp) ? 1e-4 : 1e-6;
+ edgeStart = edgePos = ((gl_Position.xy / gl_Position.w) * 0.5 + 0.5) * sizeViewport.xy;
+ view_clipping_distances(wPos[2].xyz);
+ }
+}
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_solid_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_solid_vert.glsl
index 68f7e75673f..2b5605c85d3 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_solid_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_solid_vert.glsl
@@ -25,7 +25,7 @@ void main()
finalColor.a = 1.0;
vec4 world_pos = model_mat * vec4(pos, 1.0);
- gl_Position = drw_view.persmat * world_pos;
+ gl_Position = drw_view.winmat * (drw_view.viewmat * world_pos);
view_clipping_distances(world_pos.xyz);
}
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_outline_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_outline_vert.glsl
index 4d79fab718f..ef9a0b7bdd6 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_outline_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_outline_vert.glsl
@@ -63,7 +63,7 @@ void main()
/* Offset away from the center to avoid overlap with solid shape. */
vec2 ofs_dir = normalize(proj(gl_Position) - proj(center));
- gl_Position.xy += ofs_dir * drw_view.viewport_size_inverse * gl_Position.w;
+ gl_Position.xy += ofs_dir * sizeViewportInv * gl_Position.w;
edgeStart = edgePos = proj(gl_Position);
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_armature_stick_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_stick_vert.glsl
index e7917a46312..c10a221ef08 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_armature_stick_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_stick_vert.glsl
@@ -64,7 +64,7 @@ void main()
if (finalInnerColor.a > 0.0) {
float stick_size = sizePixel * 5.0;
gl_Position = (is_head) ? p0 : p1;
- gl_Position.xy += stick_size * (vpos * drw_view.viewport_size_inverse);
+ gl_Position.xy += stick_size * (vpos * sizeViewportInv);
gl_Position.z += (is_bone) ? 0.0 : 1e-6; /* Avoid Z fighting of head/tails. */
view_clipping_distances((is_head ? boneStart_4d : boneEnd_4d).xyz);
}
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_background_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_background_frag.glsl
index b25dcae9fca..960986bebd5 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_background_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_background_frag.glsl
@@ -18,8 +18,8 @@ float dither(void)
void main()
{
/* The blend equation is:
- * resutl.rgb = SRC.rgb * (1 - DST.a) + DST.rgb * (SRC.a)
- * result.a = SRC.a * 0 + DST.a * SRC.a
+ * `result.rgb = SRC.rgb * (1 - DST.a) + DST.rgb * (SRC.a)`
+ * `result.a = SRC.a * 0 + DST.a * SRC.a`
* This removes the alpha channel and put the background behind reference images
* while masking the reference images by the render alpha.
*/
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_geom.glsl
index 7d92baea595..c1726f00d66 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_geom.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_geom.glsl
@@ -83,7 +83,7 @@ void main()
vec4(inner_color.rgb, 0.0);
vec2 v1_2 = (v2.xy / v2.w - v1.xy / v1.w);
- vec2 offset = sizeEdge * 4.0 * drw_view.viewport_size_inverse; /* 4.0 is eyeballed */
+ vec2 offset = sizeEdge * 4.0 * sizeViewportInv; /* 4.0 is eyeballed */
if (abs(v1_2.x * sizeViewport.x) < abs(v1_2.y * sizeViewport.y)) {
offset.y = 0.0;
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl
new file mode 100644
index 00000000000..8b4b7afb996
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl
@@ -0,0 +1,16 @@
+/* TODO(Metal): Implement correct SSBO implementation for geom shader workaround.
+ * Currently included as placeholder to unblock failing compilation in Metal. */
+
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+void main()
+{
+ GPU_INTEL_VERTEX_SHADER_WORKAROUND
+
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
+ vert.flag = data;
+
+ view_clipping_distances(world_pos);
+}
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_geom.glsl
index 82f957b2071..257058d7029 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_geom.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_geom.glsl
@@ -56,7 +56,7 @@ void main()
half_size += 0.5;
}
- vec3 edge_ofs = vec3(half_size * drw_view.viewport_size_inverse, 0.0);
+ vec3 edge_ofs = vec3(half_size * sizeViewportInv, 0.0);
bool horizontal = line.x > line.y;
edge_ofs = (horizontal) ? edge_ofs.zyz : edge_ofs.xzz;
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_skin_root_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_skin_root_vert.glsl
index 76a944c6987..ce1ee8ca448 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_skin_root_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_skin_root_vert.glsl
@@ -5,11 +5,11 @@
void main()
{
mat3 imat = mat3(ModelMatrixInverse);
- vec3 right = normalize(imat * screenVecs[0].xyz);
- vec3 up = normalize(imat * screenVecs[1].xyz);
+ vec3 right = normalize(imat * ViewMatrixInverse[0].xyz);
+ vec3 up = normalize(imat * ViewMatrixInverse[1].xyz);
vec3 screen_pos = (right * pos.x + up * pos.z) * size;
vec4 pos_4d = ModelMatrix * vec4(local_pos + screen_pos, 1.0);
- gl_Position = drw_view.persmat * pos_4d;
+ gl_Position = drw_view.winmat * (drw_view.viewmat * pos_4d);
/* Manual stipple: one segment out of 2 is transparent. */
finalColor = ((gl_VertexID & 1) == 0) ? colorSkinRoot : vec4(0.0);
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl
new file mode 100644
index 00000000000..fb18b95ccc5
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl
@@ -0,0 +1,208 @@
+
+#pragma USE_SSBO_VERTEX_FETCH(TriangleList, 6)
+
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(overlay_edit_mesh_common_lib.glsl)
+
+#define DISCARD_VERTEX \
+ gl_Position = geometry_out.finalColorOuter = geometry_out.finalColor = vec4(0.0); \
+ geometry_out.edgeCoord = 0.0; \
+ return;
+
+bool test_occlusion(vec4 pos)
+{
+ vec3 ndc = (pos.xyz / pos.w) * 0.5 + 0.5;
+ return ndc.z > texture(depthTex, ndc.xy).r;
+}
+
+vec3 non_linear_blend_color(vec3 col1, vec3 col2, float fac)
+{
+ col1 = pow(col1, vec3(1.0 / 2.2));
+ col2 = pow(col2, vec3(1.0 / 2.2));
+ vec3 col = mix(col1, col2, fac);
+ return pow(col, vec3(2.2));
+}
+
+vec3 vec3_1010102_Inorm_to_vec3(vec3 data)
+{
+ return data;
+}
+
+vec3 vec3_1010102_Inorm_to_vec3(int data)
+{
+ vec3 out_vec;
+ out_vec.x = float(clamp(data, -512, 511)) / 511.0f;
+ out_vec.y = float(clamp(data >> 10, -512, 511)) / 511.0f;
+ out_vec.z = float(clamp(data >> 20, -512, 511)) / 511.0f;
+ return out_vec;
+}
+
+void do_vertex(vec4 color, vec4 pos, float coord, vec2 offset)
+{
+ geometry_out.finalColor = color;
+ geometry_out.edgeCoord = coord;
+ gl_Position = pos;
+ /* Multiply offset by 2 because gl_Position range is [-1..1]. */
+ gl_Position.xy += offset * 2.0 * pos.w;
+}
+
+void main()
+{
+ /* Index of the quad primitive -- corresponds to one line prim. */
+ int quad_id = gl_VertexID / 6;
+
+ /* Determine vertex within the output 2-triangle quad (A, B, C)(A, C, D). */
+ int quad_vertex_id = gl_VertexID % 6;
+
+ /* Base index of the line primitive:
+ * IF PrimType == LineList: base_vertex_id = quad_id*2
+ * IF PrimType == LineStrip: base_vertex_id = quad_id
+ *
+ * Note: This is currently used as LineList.
+ *
+ * Note: Primitive Restart Will not work with this setup as-is. We should avoid using
+ * input primitive types which use restart indices. */
+ int base_vertex_id = quad_id * 2;
+
+ /* Fetch attribute values for self and neighboring vertex. */
+ vec3 in_pos0 = vertex_fetch_attribute(base_vertex_id, pos, vec3);
+ vec3 in_pos1 = vertex_fetch_attribute(base_vertex_id + 1, pos, vec3);
+ uchar4 in_data0 = vertex_fetch_attribute(base_vertex_id, data, uchar4);
+ uchar4 in_data1 = vertex_fetch_attribute(base_vertex_id + 1, data, uchar4);
+ vec3 in_vnor0 = vec3_1010102_Inorm_to_vec3(
+ vertex_fetch_attribute(base_vertex_id, vnor, vec3_1010102_Inorm));
+ vec3 in_vnor1 = vec3_1010102_Inorm_to_vec3(
+ vertex_fetch_attribute(base_vertex_id + 1, vnor, vec3_1010102_Inorm));
+
+ /* Calculate values for self and neighboring vertex. */
+ vec4 out_finalColor[2];
+ vec4 out_finalColorOuter[2];
+ int selectOveride[2];
+
+ vec3 world_pos0 = point_object_to_world(in_pos0);
+ vec3 world_pos1 = point_object_to_world(in_pos1);
+ vec4 out_pos0 = point_world_to_ndc(world_pos0);
+ vec4 out_pos1 = point_world_to_ndc(world_pos1);
+ ivec4 m_data0 = ivec4(in_data0) & dataMask;
+ ivec4 m_data1 = ivec4(in_data1) & dataMask;
+
+#if defined(EDGE)
+# ifdef FLAT
+ out_finalColor[0] = EDIT_MESH_edge_color_inner(m_data0.y);
+ out_finalColor[1] = EDIT_MESH_edge_color_inner(m_data1.y);
+ selectOveride[0] = 1;
+ selectOveride[1] = 1;
+# else
+ out_finalColor[0] = EDIT_MESH_edge_vertex_color(m_data0.y);
+ out_finalColor[1] = EDIT_MESH_edge_vertex_color(m_data1.y);
+ selectOveride[0] = (m_data0.y & EDGE_SELECTED);
+ selectOveride[1] = (m_data1.y & EDGE_SELECTED);
+# endif
+
+ float crease0 = float(m_data0.z) / 255.0;
+ float crease1 = float(m_data1.z) / 255.0;
+ float bweight0 = float(m_data0.w) / 255.0;
+ float bweight1 = float(m_data1.w) / 255.0;
+ out_finalColorOuter[0] = EDIT_MESH_edge_color_outer(m_data0.y, m_data0.x, crease0, bweight0);
+ out_finalColorOuter[1] = EDIT_MESH_edge_color_outer(m_data1.y, m_data1.x, crease1, bweight1);
+
+ if (out_finalColorOuter[0].a > 0.0) {
+ out_pos0.z -= 5e-7 * abs(out_pos0.w);
+ }
+ if (out_finalColorOuter[1].a > 0.0) {
+ out_pos1.z -= 5e-7 * abs(out_pos1.w);
+ }
+
+ /* Occlusion done in fragment shader. */
+ bool occluded0 = false;
+ bool occluded1 = false;
+#endif
+
+ out_finalColor[0].a *= (occluded0) ? alpha : 1.0;
+ out_finalColor[1].a *= (occluded1) ? alpha : 1.0;
+
+#if !defined(FACE)
+ /* Facing based color blend */
+ vec3 vpos0 = point_world_to_view(world_pos0);
+ vec3 view_normal0 = normalize(normal_object_to_view(in_vnor0) + 1e-4);
+ vec3 view_vec0 = (ProjectionMatrix[3][3] == 0.0) ? normalize(vpos0) : vec3(0.0, 0.0, 1.0);
+ float facing0 = dot(view_vec0, view_normal0);
+ facing0 = 1.0 - abs(facing0) * 0.2;
+
+ vec3 vpos1 = point_world_to_view(world_pos1);
+ vec3 view_normal1 = normalize(normal_object_to_view(in_vnor1) + 1e-4);
+ vec3 view_vec1 = (ProjectionMatrix[3][3] == 0.0) ? normalize(vpos1) : vec3(0.0, 0.0, 1.0);
+ float facing1 = dot(view_vec1, view_normal1);
+ facing1 = 1.0 - abs(facing1) * 0.2;
+
+ /* Do interpolation in a non-linear space to have a better visual result. */
+ out_finalColor[0].rgb = non_linear_blend_color(
+ colorEditMeshMiddle.rgb, out_finalColor[0].rgb, facing0);
+ out_finalColor[1].rgb = non_linear_blend_color(
+ colorEditMeshMiddle.rgb, out_finalColor[1].rgb, facing1);
+#endif
+
+ // -------- GEOM SHADER ALTERNATIVE ----------- //
+ vec2 ss_pos[2];
+
+ /* Clip line against near plane to avoid deformed lines. */
+ vec4 pos0 = out_pos0;
+ vec4 pos1 = out_pos1;
+ vec2 pz_ndc = vec2(pos0.z / pos0.w, pos1.z / pos1.w);
+ bvec2 clipped = lessThan(pz_ndc, vec2(-1.0));
+ if (all(clipped)) {
+ /* Totally clipped. */
+ DISCARD_VERTEX;
+ }
+
+ vec4 pos01 = pos0 - pos1;
+ float ofs = abs((pz_ndc.y + 1.0) / (pz_ndc.x - pz_ndc.y));
+ if (clipped.y) {
+ pos1 += pos01 * ofs;
+ }
+ else if (clipped.x) {
+ pos0 -= pos01 * (1.0 - ofs);
+ }
+
+ ss_pos[0] = pos0.xy / pos0.w;
+ ss_pos[1] = pos1.xy / pos1.w;
+
+ vec2 line = ss_pos[0] - ss_pos[1];
+ line = abs(line) * sizeViewport.xy;
+
+ geometry_out.finalColorOuter = out_finalColorOuter[0];
+ float half_size = sizeEdge;
+ /* Enlarge edge for flag display. */
+ half_size += (geometry_out.finalColorOuter.a > 0.0) ? max(sizeEdge, 1.0) : 0.0;
+
+#ifdef USE_SMOOTH_WIRE
+ /* Add 1 px for AA */
+ half_size += 0.5;
+#endif
+
+ vec3 edge_ofs = vec3(half_size * sizeViewportInv, 0.0);
+
+ bool horizontal = line.x > line.y;
+ edge_ofs = (horizontal) ? edge_ofs.zyz : edge_ofs.xzz;
+
+ vec4 final_color = (selectOveride[0] == 0) ? out_finalColor[1] : out_finalColor[0];
+
+ /* Output specific Vertex data depending on quad_vertex_id. */
+ if (quad_vertex_id == 0) {
+ view_clipping_distances(world_pos0);
+ do_vertex(out_finalColor[0], pos0, half_size, edge_ofs.xy);
+ }
+ else if (quad_vertex_id == 1 || quad_vertex_id == 3) {
+ view_clipping_distances(world_pos0);
+ do_vertex(out_finalColor[0], pos0, -half_size, -edge_ofs.xy);
+ }
+ else if (quad_vertex_id == 2 || quad_vertex_id == 5) {
+ view_clipping_distances(world_pos1);
+ do_vertex(final_color, pos1, half_size, edge_ofs.xy);
+ }
+ else if (quad_vertex_id == 4) {
+ view_clipping_distances(world_pos1);
+ do_vertex(final_color, pos1, -half_size, -edge_ofs.xy);
+ }
+}
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl
index a849cb5160a..c9dc90e4113 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl
@@ -4,8 +4,8 @@
* We want to know how much a pixel is covered by a line.
* We replace the square pixel with acircle of the same area and try to find the intersection area.
* The area we search is the circular segment. https://en.wikipedia.org/wiki/Circular_segment
- * The formula for the area uses inverse trig function and is quite complexe. Instead,
- * we approximate it by using the smoothstep function and a 1.05 factor to the disc radius.
+ * The formula for the area uses inverse trig function and is quite complex. Instead,
+ * we approximate it by using the smooth-step function and a 1.05 factor to the disc radius.
*/
#define M_1_SQRTPI 0.5641895835477563 /* 1/sqrt(pi) */
#define DISC_RADIUS (M_1_SQRTPI * 1.05)
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_geom.glsl
index 8b19f671139..8038c68476a 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_geom.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_geom.glsl
@@ -28,7 +28,7 @@ void main()
half_size += (lineStyle == OVERLAY_UV_LINE_STYLE_OUTLINE) ?
max(sizeEdge * (doSmoothWire ? 1.0 : 3.0), 1.0) :
0.0;
- /* Add 1 px for AA */
+ /* Add 1 PX for AA. */
if (doSmoothWire) {
half_size += 0.5;
}
@@ -36,7 +36,7 @@ void main()
vec2 line = ss_pos[0] - ss_pos[1];
vec2 line_dir = normalize(line);
vec2 line_perp = vec2(-line_dir.y, line_dir.x);
- vec2 edge_ofs = line_perp * drw_view.viewport_size_inverse * ceil(half_size);
+ vec2 edge_ofs = line_perp * sizeViewportInv * ceil(half_size);
float selectFac0 = geom_in[0].selectionFac;
float selectFac1 = geom_in[1].selectionFac;
#ifdef USE_EDGE_SELECT
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_vert.glsl
index 23f1a44c321..b7bcfbeb0d4 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_vert.glsl
@@ -5,8 +5,8 @@ void main()
vec3 world_pos = point_object_to_world(vec3(au, 0.0));
gl_Position = point_world_to_ndc(world_pos);
/* Snap vertices to the pixel grid to reduce artifacts. */
- vec2 half_viewport_res = drw_view.viewport_size * 0.5;
- vec2 half_pixel_offset = drw_view.viewport_size_inverse * 0.5;
+ vec2 half_viewport_res = sizeViewport * 0.5;
+ vec2 half_pixel_offset = sizeViewportInv * 0.5;
gl_Position.xy = floor(gl_Position.xy * half_viewport_res) / half_viewport_res +
half_pixel_offset;
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_extra_groundline_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_extra_groundline_vert.glsl
index ff7aae523e7..bc8ba710d3b 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_extra_groundline_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_extra_groundline_vert.glsl
@@ -7,7 +7,7 @@ void main()
finalColor = colorLight;
/* Relative to DPI scaling. Have constant screen size. */
- vec3 screen_pos = screenVecs[0].xyz * pos.x + screenVecs[1].xyz * pos.y;
+ vec3 screen_pos = ViewMatrixInverse[0].xyz * pos.x + ViewMatrixInverse[1].xyz * pos.y;
vec3 p = inst_pos;
p.z *= (pos.z == 0.0) ? 0.0 : 1.0;
float screen_size = mul_project_m4_v3_zfac(p) * sizePixel;
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_extra_point_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_extra_point_vert.glsl
index de999c241c0..179c3cb6d73 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_extra_point_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_extra_point_vert.glsl
@@ -16,7 +16,7 @@ void main()
radii[3] = radius - outline_width - 1.0;
radii /= sizeObjectCenter;
- fillColor = color;
+ fillColor = ucolor;
outlineColor = colorOutline;
view_clipping_distances(world_pos);
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_extra_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_extra_vert.glsl
index acaf04219c0..7b1e29525e9 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_extra_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_extra_vert.glsl
@@ -171,14 +171,14 @@ void main()
vec3 world_pos;
if ((vclass & VCLASS_SCREENSPACE) != 0) {
/* Relative to DPI scaling. Have constant screen size. */
- vec3 screen_pos = screenVecs[0].xyz * vpos.x + screenVecs[1].xyz * vpos.y;
+ vec3 screen_pos = ViewMatrixInverse[0].xyz * vpos.x + ViewMatrixInverse[1].xyz * vpos.y;
vec3 p = (obmat * vec4(vofs, 1.0)).xyz;
float screen_size = mul_project_m4_v3_zfac(p) * sizePixel;
world_pos = p + screen_pos * screen_size;
}
else if ((vclass & VCLASS_SCREENALIGNED) != 0) {
/* World sized, camera facing geometry. */
- vec3 screen_pos = screenVecs[0].xyz * vpos.x + screenVecs[1].xyz * vpos.y;
+ vec3 screen_pos = ViewMatrixInverse[0].xyz * vpos.x + ViewMatrixInverse[1].xyz * vpos.y;
world_pos = (obmat * vec4(vofs, 1.0)).xyz + screen_pos;
}
else {
@@ -218,8 +218,7 @@ void main()
/* HACK: to avoid losing sub-pixel object in selections, we add a bit of randomness to the
* wire to at least create one fragment that will pass the occlusion query. */
/* TODO(fclem): Limit this workaround to selection. It's not very noticeable but still... */
- gl_Position.xy += drw_view.viewport_size_inverse * gl_Position.w *
- ((gl_VertexID % 2 == 0) ? -1.0 : 1.0);
+ gl_Position.xy += sizeViewportInv * gl_Position.w * ((gl_VertexID % 2 == 0) ? -1.0 : 1.0);
#endif
view_clipping_distances(world_pos);
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_extra_wire_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_extra_wire_vert.glsl
index cd217021e8f..efa4e4706f3 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_extra_wire_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_extra_wire_vert.glsl
@@ -16,8 +16,7 @@ void main()
/* HACK: to avoid losing sub-pixel object in selections, we add a bit of randomness to the
* wire to at least create one fragment that will pass the occlusion query. */
/* TODO(fclem): Limit this workaround to selection. It's not very noticeable but still... */
- gl_Position.xy += drw_view.viewport_size_inverse * gl_Position.w *
- ((gl_VertexID % 2 == 0) ? -1.0 : 1.0);
+ gl_Position.xy += sizeViewportInv * gl_Position.w * ((gl_VertexID % 2 == 0) ? -1.0 : 1.0);
#endif
stipple_coord = stipple_start = screen_position(gl_Position);
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_grid_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_grid_frag.glsl
index 54a4231590e..b401c3e7b2e 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_grid_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_grid_frag.glsl
@@ -1,6 +1,6 @@
/**
* Infinite grid:
- * Draw antialiazed grid and axes of different sizes with smooth blending between Level of details.
+ * Draw antialiased grid and axes of different sizes with smooth blending between levels of detail.
* We draw multiple triangles to avoid float precision issues due to perspective interpolation.
**/
@@ -8,29 +8,33 @@
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
/**
- * We want to know how much a pixel is covered by a line.
- * We replace the square pixel with acircle of the same area and try to find the intersection area.
- * The area we search is the circular segment. https://en.wikipedia.org/wiki/Circular_segment
- * The formula for the area uses inverse trig function and is quite complexe. Instead,
- * we approximate it by using the smoothstep function and a 1.05 factor to the disc radius.
+ * We want to know how much of a pixel is covered by a line.
+ * Here, we imagine the square pixel is a circle with the same area and try to find the
+ * intersection area. The overlap area is a circular segment.
+ * https://en.wikipedia.org/wiki/Circular_segment The formula for the area uses inverse trig
+ * function and is quite complex. Instead, we approximate it by using the smoothstep function and
+ * a 1.05 factor to the disc radius.
+ *
+ * For an alternate approach, see:
+ * https://developer.nvidia.com/gpugems/gpugems2/part-iii-high-quality-rendering/chapter-22-fast-prefiltered-lines
*/
#define M_1_SQRTPI 0.5641895835477563 /* 1/sqrt(pi) */
#define DISC_RADIUS (M_1_SQRTPI * 1.05)
-#define GRID_LINE_SMOOTH_START (0.5 - DISC_RADIUS)
-#define GRID_LINE_SMOOTH_END (0.5 + DISC_RADIUS)
+#define GRID_LINE_SMOOTH_START (0.5 + DISC_RADIUS)
+#define GRID_LINE_SMOOTH_END (0.5 - DISC_RADIUS)
#define GRID_LINE_STEP(dist) smoothstep(GRID_LINE_SMOOTH_START, GRID_LINE_SMOOTH_END, dist)
-float get_grid(vec2 co, vec2 fwidthCos, float grid_scale)
+float get_grid(vec2 co, vec2 fwidthCos, vec2 grid_scale)
{
- float half_size = grid_scale / 2.0;
+ vec2 half_size = grid_scale / 2.0;
/* Triangular wave pattern, amplitude is [0, half_size]. */
- vec2 grid_domain = abs(mod(co + half_size, vec2(grid_scale)) - half_size);
+ vec2 grid_domain = abs(mod(co + half_size, grid_scale) - half_size);
/* Modulate by the absolute rate of change of the coordinates
* (make line have the same width under perspective). */
grid_domain /= fwidthCos;
/* Collapse waves. */
float line_dist = min(grid_domain.x, grid_domain.y);
- return 1.0 - GRID_LINE_STEP(line_dist - grid_buf.line_size);
+ return GRID_LINE_STEP(line_dist - grid_buf.line_size);
}
vec3 get_axes(vec3 co, vec3 fwidthCos, float line_size)
@@ -39,7 +43,7 @@ vec3 get_axes(vec3 co, vec3 fwidthCos, float line_size)
/* Modulate by the absolute rate of change of the coordinates
* (make line have the same width under perspective). */
axes_domain /= fwidthCos;
- return 1.0 - GRID_LINE_STEP(axes_domain - (line_size + grid_buf.line_size));
+ return GRID_LINE_STEP(axes_domain - (line_size + grid_buf.line_size));
}
#define linearstep(p0, p1, v) (clamp(((v) - (p0)) / abs((p1) - (p0)), 0.0, 1.0))
@@ -91,9 +95,9 @@ void main()
}
if (flag_test(grid_flag, SHOW_GRID)) {
- /* Using `max(dot(dFdxPos, screenVecs[0]), dot(dFdyPos, screenVecs[1]))`
+ /* Using `max(dot(dFdxPos, ViewMatrixInverse[0]), dot(dFdyPos, ViewMatrixInverse[1]))`
* would be more accurate, but not really necessary. */
- float grid_res = dot(dFdxPos, screenVecs[0].xyz);
+ float grid_res = dot(dFdxPos, ViewMatrixInverse[0].xyz);
/* The grid begins to appear when it comprises 4 pixels. */
grid_res *= 4;
@@ -106,49 +110,30 @@ void main()
grid_res = grid_buf.zoom_factor;
}
- /* From biggest to smallest. */
- vec4 scale;
-#define grid_step(a) grid_buf.steps[a].x
-#if 0 /* Inefficient. */
- int step_id = 0;
- scale[0] = 0.0;
- scale[1] = grid_step(0);
- while (scale[1] < grid_res && step_id != STEPS_LEN - 1) {
- scale[0] = scale[1];
- scale[1] = grid_step(++step_id);
- }
- scale[2] = grid_step(min(step_id + 1, STEPS_LEN - 1));
- scale[3] = grid_step(min(step_id + 2, STEPS_LEN - 1));
-#else
- /* For more efficiency, unroll the loop above. */
- if (grid_step(0) > grid_res) {
- scale = vec4(0.0, grid_step(0), grid_step(1), grid_step(2));
- }
- else if (grid_step(1) > grid_res) {
- scale = vec4(grid_step(0), grid_step(1), grid_step(2), grid_step(3));
- }
- else if (grid_step(2) > grid_res) {
- scale = vec4(grid_step(1), grid_step(2), grid_step(3), grid_step(4));
- }
- else if (grid_step(3) > grid_res) {
- scale = vec4(grid_step(2), grid_step(3), grid_step(4), grid_step(5));
- }
- else if (grid_step(4) > grid_res) {
- scale = vec4(grid_step(3), grid_step(4), grid_step(5), grid_step(6));
- }
- else if (grid_step(5) > grid_res) {
- scale = vec4(grid_step(4), grid_step(5), grid_step(6), grid_step(7));
- }
- else if (grid_step(6) > grid_res) {
- scale = vec4(grid_step(5), grid_step(6), grid_step(7), grid_step(7));
- }
- else {
- scale = vec4(grid_step(6), grid_step(7), grid_step(7), grid_step(7));
+/** Keep in sync with `SI_GRID_STEPS_LEN` in `DNA_space_types.h`. */
+#define STEPS_LEN 8
+ int step_id_x = STEPS_LEN - 1;
+ int step_id_y = STEPS_LEN - 1;
+
+ /* Loop backwards a compile-time-constant number of steps. */
+ for (int i = STEPS_LEN - 2; i >= 0; --i) {
+ step_id_x = (grid_res < grid_buf.steps[i].x) ? i : step_id_x; /* Branchless. */
+ step_id_y = (grid_res < grid_buf.steps[i].y) ? i : step_id_y;
}
-#endif
-#undef grid_step
- float blend = 1.0 - linearstep(scale[0], scale[1], grid_res);
+ /* From biggest to smallest. */
+ float scale0x = step_id_x > 0 ? grid_buf.steps[step_id_x - 1].x : 0.0;
+ float scaleAx = grid_buf.steps[step_id_x].x;
+ float scaleBx = grid_buf.steps[min(step_id_x + 1, STEPS_LEN - 1)].x;
+ float scaleCx = grid_buf.steps[min(step_id_x + 2, STEPS_LEN - 1)].x;
+
+ float scale0y = step_id_y > 0 ? grid_buf.steps[step_id_y - 1].y : 0.0;
+ float scaleAy = grid_buf.steps[step_id_y].y;
+ float scaleBy = grid_buf.steps[min(step_id_y + 1, STEPS_LEN - 1)].y;
+ float scaleCy = grid_buf.steps[min(step_id_y + 2, STEPS_LEN - 1)].y;
+
+ /* Subtract from 1.0 to fix blending when `scale0x == scaleAx`. */
+ float blend = 1.0 - linearstep(scale0x + scale0y, scaleAx + scaleAy, grid_res + grid_res);
blend = blend * blend * blend;
vec2 grid_pos, grid_fwidth;
@@ -165,9 +150,9 @@ void main()
grid_fwidth = fwidthPos.xy;
}
- float gridA = get_grid(grid_pos, grid_fwidth, scale[1]);
- float gridB = get_grid(grid_pos, grid_fwidth, scale[2]);
- float gridC = get_grid(grid_pos, grid_fwidth, scale[3]);
+ float gridA = get_grid(grid_pos, grid_fwidth, vec2(scaleAx, scaleAy));
+ float gridB = get_grid(grid_pos, grid_fwidth, vec2(scaleBx, scaleBy));
+ float gridC = get_grid(grid_pos, grid_fwidth, vec2(scaleCx, scaleCy));
out_color = colorGrid;
out_color.a *= gridA * blend;
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_grid_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_grid_vert.glsl
index b43b1eb4a52..6a027f94f49 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_grid_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_grid_vert.glsl
@@ -39,5 +39,5 @@ void main()
local_pos.z = clamp(local_pos.z, -1.0, 0.0);
}
- gl_Position = drw_view.persmat * vec4(real_pos, 1.0);
+ gl_Position = drw_view.winmat * (drw_view.viewmat * vec4(real_pos, 1.0));
}
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_image_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_image_frag.glsl
index e0339507e0f..1a9da98c1fa 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_image_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_image_frag.glsl
@@ -6,7 +6,7 @@ void main()
vec4 tex_color;
tex_color = texture_read_as_linearrgb(imgTexture, imgPremultiplied, uvs_clamped);
- fragColor = tex_color * color;
+ fragColor = tex_color * ucolor;
if (!imgAlphaBlend) {
/* Arbitrary discard anything below 5% opacity.
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_geom.glsl
index 25e13e7c212..32a38db140a 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_geom.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_geom.glsl
@@ -12,8 +12,7 @@ vec2 compute_dir(vec2 v0, vec2 v1)
void main(void)
{
vec2 t;
- vec2 edge_dir = compute_dir(interp_in[0].ss_pos, interp_in[1].ss_pos) *
- drw_view.viewport_size_inverse;
+ vec2 edge_dir = compute_dir(interp_in[0].ss_pos, interp_in[1].ss_pos) * sizeViewportInv;
bool is_persp = (drw_view.winmat[3][3] == 0.0);
float line_size = float(lineThickness) * sizePixel;
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert.glsl
index e6281f75b8f..50c24de0838 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert.glsl
@@ -18,7 +18,7 @@ vec2 proj(vec4 pos)
void main()
{
- gl_Position = drw_view.persmat * vec4(pos, 1.0);
+ gl_Position = drw_view.winmat * (drw_view.viewmat * vec4(pos, 1.0));
interp.ss_pos = proj(gl_Position);
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert_no_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert_no_geom.glsl
new file mode 100644
index 00000000000..abaa814a4dc
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert_no_geom.glsl
@@ -0,0 +1,160 @@
+
+#pragma USE_SSBO_VERTEX_FETCH(TriangleList, 6)
+
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+#define frameCurrent mpathLineSettings.x
+#define frameStart mpathLineSettings.y
+#define frameEnd mpathLineSettings.z
+#define cacheStart mpathLineSettings.w
+
+/* Project to screen space. */
+vec2 proj(vec4 pos)
+{
+ return (0.5 * (pos.xy / pos.w) + 0.5) * sizeViewport.xy;
+}
+
+#define SET_INTENSITY(A, B, C, min, max) \
+ (((1.0 - (float(C - B) / float(C - A))) * (max - min)) + min)
+
+vec2 compute_dir(vec2 v0, vec2 v1)
+{
+ vec2 dir = normalize(v1 - v0 + 1e-8);
+ dir = vec2(-dir.y, dir.x);
+ return dir;
+}
+
+void do_vertex_shader(vec4 pos, int vertex_id, out vec2 out_sspos, out vec4 out_finalcolour)
+{
+ out_sspos = proj(pos);
+ out_finalcolour = vec4(0.0);
+
+ int frame = vertex_id + cacheStart;
+ float intensity; /* how faint */
+ vec3 blend_base = (abs(frame - frameCurrent) == 0) ?
+ colorCurrentFrame.rgb :
+ colorBackground.rgb; /* "bleed" cframe color to ease color blending */
+ bool use_custom_color = customColor.x >= 0.0;
+ /* TODO: We might want something more consistent with custom color and standard colors. */
+ if (frame < frameCurrent) {
+ if (use_custom_color) {
+ /* Custom color: previous frames color is darker than current frame */
+ out_finalcolour.rgb = customColor * 0.25;
+ }
+ else {
+ /* black - before frameCurrent */
+ if (selected) {
+ intensity = SET_INTENSITY(frameStart, frame, frameCurrent, 0.25, 0.75);
+ }
+ else {
+ intensity = SET_INTENSITY(frameStart, frame, frameCurrent, 0.68, 0.92);
+ }
+ out_finalcolour.rgb = mix(colorWire.rgb, blend_base, intensity);
+ }
+ }
+ else if (frame > frameCurrent) {
+ if (use_custom_color) {
+ /* Custom color: next frames color is equal to user selected color */
+ out_finalcolour.rgb = customColor;
+ }
+ else {
+ /* blue - after frameCurrent */
+ if (selected) {
+ intensity = SET_INTENSITY(frameCurrent, frame, frameEnd, 0.25, 0.75);
+ }
+ else {
+ intensity = SET_INTENSITY(frameCurrent, frame, frameEnd, 0.68, 0.92);
+ }
+
+ out_finalcolour.rgb = mix(colorBonePose.rgb, blend_base, intensity);
+ }
+ }
+ else {
+ if (use_custom_color) {
+ /* Custom color: current frame color is slightly darker than user selected color */
+ out_finalcolour.rgb = customColor * 0.5;
+ }
+ else {
+ /* green - on frameCurrent */
+ if (selected) {
+ intensity = 0.92f;
+ }
+ else {
+ intensity = 0.75f;
+ }
+ out_finalcolour.rgb = mix(colorBackground.rgb, blend_base, intensity);
+ }
+ }
+ out_finalcolour.a = 1.0;
+}
+
+void main()
+{
+ /** Determine Output Primitive ID and relative vertex. */
+ /* Index of the quad primitive. We generate one quad for each input line. */
+ int quad_id = gl_VertexID / 6;
+
+ /* Determine vertex within the quad (A, B, C)(A, C, D). */
+ int quad_vertex_id = gl_VertexID % 6;
+ /* Base index of the line primitive:
+ * - IF PrimType == LineList: base_vertex_id = quad_id*2
+ * - IF PrimType == LineStrip: base_vertex_id = quad_id
+ *
+ * Note: Primitive is LineStrip for this shader. */
+ int base_vertex_id = quad_id;
+
+ /* Fetch attributes for self and neighboring vertex. */
+ vec3 in_pos0 = vertex_fetch_attribute(base_vertex_id, pos, vec3);
+ vec3 in_pos1 = vertex_fetch_attribute(base_vertex_id + 1, pos, vec3);
+
+ vec4 out_pos0 = drw_view.winmat * (drw_view.viewmat * vec4(in_pos0, 1.0));
+ vec4 out_pos1 = drw_view.winmat * (drw_view.viewmat * vec4(in_pos1, 1.0));
+
+ /* Final calculations required for Geometry Shader alternative.
+ * We need to calculate values for each vertex position to correctly determine the final output
+ * position. */
+ vec2 ssPos[2];
+ vec4 finalColor_geom[2];
+
+ do_vertex_shader(out_pos0, base_vertex_id, ssPos[0], finalColor_geom[0]);
+ do_vertex_shader(out_pos1, base_vertex_id + 1, ssPos[0], finalColor_geom[0]);
+
+ /* Geometry shader alternative -- Output is trianglelist consisting of 6 vertices.
+ * Each vertex shader invocation is one vertex in the output primitive, so outptut
+ * required ID. */
+ vec2 t;
+ vec2 edge_dir = compute_dir(ssPos[0], ssPos[1]) * sizeViewportInv;
+
+ bool is_persp = (ProjectionMatrix[3][3] == 0.0);
+ float line_size = float(lineThickness) * sizePixel;
+
+ if (quad_vertex_id == 0) {
+ view_clipping_distances(out_pos0.xyz);
+
+ interp.color = finalColor_geom[0];
+ t = edge_dir * (line_size * (is_persp ? out_pos0.w : 1.0));
+ gl_Position = out_pos0 + vec4(t, 0.0, 0.0);
+ }
+ else if (quad_vertex_id == 1 || quad_vertex_id == 3) {
+ view_clipping_distances(out_pos0.xyz);
+
+ interp.color = finalColor_geom[0];
+ t = edge_dir * (line_size * (is_persp ? out_pos0.w : 1.0));
+ gl_Position = out_pos0 - vec4(t, 0.0, 0.0);
+ }
+ else if (quad_vertex_id == 2 || quad_vertex_id == 5) {
+ view_clipping_distances(out_pos1.xyz);
+
+ interp.color = finalColor_geom[1];
+ t = edge_dir * (line_size * (is_persp ? out_pos1.w : 1.0));
+ gl_Position = out_pos1 + vec4(t, 0.0, 0.0);
+ }
+ else if (quad_vertex_id == 4) {
+ view_clipping_distances(out_pos1.xyz);
+
+ interp.color = finalColor_geom[1];
+ t = edge_dir * (line_size * (is_persp ? out_pos1.w : 1.0));
+ gl_Position = out_pos1 - vec4(t, 0.0, 0.0);
+ }
+}
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_motion_path_point_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_point_vert.glsl
index 70892954cd8..7305d00c052 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_motion_path_point_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_point_vert.glsl
@@ -9,7 +9,7 @@
void main()
{
- gl_Position = drw_view.persmat * vec4(pos, 1.0);
+ gl_Position = drw_view.winmat * (drw_view.viewmat * vec4(pos, 1.0));
gl_PointSize = float(pointSize + 2);
int frame = gl_VertexID + cacheStart;
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_outline_detect_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_outline_detect_frag.glsl
index 472a589f441..18914b0276f 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_outline_detect_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_outline_detect_frag.glsl
@@ -36,7 +36,7 @@ bvec4 gather_edges(vec2 uv, uint ref)
#ifdef GPU_ARB_texture_gather
ids = textureGather(outlineId, uv);
#else
- vec3 ofs = vec3(0.5, 0.5, -0.5) * drw_view.viewport_size_inverse.xyy;
+ vec3 ofs = vec3(0.5, 0.5, -0.5) * sizeViewportInv.xyy;
ids.x = textureLod(outlineId, uv - ofs.xz, 0.0).r;
ids.y = textureLod(outlineId, uv + ofs.xy, 0.0).r;
ids.z = textureLod(outlineId, uv + ofs.xz, 0.0).r;
@@ -161,8 +161,8 @@ void main()
uint ref = textureLod(outlineId, uvcoordsvar.xy, 0.0).r;
uint ref_col = ref;
- vec2 uvs = gl_FragCoord.xy * drw_view.viewport_size_inverse;
- vec3 ofs = vec3(drw_view.viewport_size_inverse.xy, 0.0);
+ vec2 uvs = gl_FragCoord.xy * sizeViewportInv;
+ vec3 ofs = vec3(sizeViewportInv.xy, 0.0);
vec2 depth_uv = uvs;
@@ -269,13 +269,13 @@ void main()
switch (edge_case) {
/* Straight lines. */
case YPOS:
- extra_edges = gather_edges(uvs + drw_view.viewport_size_inverse * vec2(2.5, 0.5), ref);
- extra_edges2 = gather_edges(uvs + drw_view.viewport_size_inverse * vec2(-2.5, 0.5), ref);
+ extra_edges = gather_edges(uvs + sizeViewportInv * vec2(2.5, 0.5), ref);
+ extra_edges2 = gather_edges(uvs + sizeViewportInv * vec2(-2.5, 0.5), ref);
straight_line_dir(extra_edges, extra_edges2, line_start, line_end);
break;
case YNEG:
- extra_edges = gather_edges(uvs + drw_view.viewport_size_inverse * vec2(-2.5, -0.5), ref);
- extra_edges2 = gather_edges(uvs + drw_view.viewport_size_inverse * vec2(2.5, -0.5), ref);
+ extra_edges = gather_edges(uvs + sizeViewportInv * vec2(-2.5, -0.5), ref);
+ extra_edges2 = gather_edges(uvs + sizeViewportInv * vec2(2.5, -0.5), ref);
extra_edges = rotate_180(extra_edges);
extra_edges2 = rotate_180(extra_edges2);
straight_line_dir(extra_edges, extra_edges2, line_start, line_end);
@@ -283,8 +283,8 @@ void main()
line_end = rotate_180(line_end);
break;
case XPOS:
- extra_edges = gather_edges(uvs + drw_view.viewport_size_inverse * vec2(0.5, 2.5), ref);
- extra_edges2 = gather_edges(uvs + drw_view.viewport_size_inverse * vec2(0.5, -2.5), ref);
+ extra_edges = gather_edges(uvs + sizeViewportInv * vec2(0.5, 2.5), ref);
+ extra_edges2 = gather_edges(uvs + sizeViewportInv * vec2(0.5, -2.5), ref);
extra_edges = rotate_90(extra_edges);
extra_edges2 = rotate_90(extra_edges2);
straight_line_dir(extra_edges, extra_edges2, line_start, line_end);
@@ -292,8 +292,8 @@ void main()
line_end = rotate_90(line_end);
break;
case XNEG:
- extra_edges = gather_edges(uvs + drw_view.viewport_size_inverse * vec2(-0.5, 2.5), ref);
- extra_edges2 = gather_edges(uvs + drw_view.viewport_size_inverse * vec2(-0.5, -2.5), ref);
+ extra_edges = gather_edges(uvs + sizeViewportInv * vec2(-0.5, 2.5), ref);
+ extra_edges2 = gather_edges(uvs + sizeViewportInv * vec2(-0.5, -2.5), ref);
extra_edges = rotate_270(extra_edges);
extra_edges2 = rotate_270(extra_edges2);
straight_line_dir(extra_edges, extra_edges2, line_start, line_end);
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_curves_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_curves_vert.glsl
index f9ec475d21f..27150d1cb3d 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_curves_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_curves_vert.glsl
@@ -45,8 +45,8 @@ void main()
vec3 world_pos;
if (hairThicknessRes > 1) {
/* Calculate the thickness, thicktime, worldpos taken into account the outline. */
- float outline_width = point_world_to_ndc(center_wpos).w * 1.25 *
- drw_view.viewport_size_inverse.y * drw_view.wininv[1][1];
+ float outline_width = point_world_to_ndc(center_wpos).w * 1.25 * sizeViewportInv.y *
+ drw_view.wininv[1][1];
thickness += outline_width;
float thick_time = float(gl_VertexID % hairThicknessRes) / float(hairThicknessRes - 1);
thick_time = thickness * (thick_time * 2.0 - 1.0);
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_gpencil_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_gpencil_frag.glsl
index 92be9ec3bcb..2b7c3f06769 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_gpencil_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_gpencil_frag.glsl
@@ -23,9 +23,9 @@ void main()
if (!gpStrokeOrder3d) {
/* Stroke order 2D. Project to gpDepthPlane. */
bool is_persp = drw_view.winmat[3][3] == 0.0;
- vec2 uvs = vec2(gl_FragCoord.xy) * drw_view.viewport_size_inverse;
+ vec2 uvs = vec2(gl_FragCoord.xy) * sizeViewportInv;
vec3 pos_ndc = vec3(uvs, gl_FragCoord.z) * 2.0 - 1.0;
- vec4 pos_world = drw_view.persinv * vec4(pos_ndc, 1.0);
+ vec4 pos_world = drw_view.viewinv * (drw_view.wininv * vec4(pos_ndc, 1.0));
vec3 pos = pos_world.xyz / pos_world.w;
vec3 ray_ori = pos;
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_gpencil_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_gpencil_vert.glsl
index 4b1470e5723..851e0884354 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_gpencil_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_gpencil_vert.glsl
@@ -34,20 +34,7 @@ void main()
float unused_strength;
vec2 unused_uv;
- gl_Position = gpencil_vertex(ma,
- ma1,
- ma2,
- ma3,
- pos,
- pos1,
- pos2,
- pos3,
- uv1,
- uv2,
- col1,
- col2,
- fcol1,
- vec4(drw_view.viewport_size, drw_view.viewport_size_inverse),
+ gl_Position = gpencil_vertex(vec4(sizeViewport, sizeViewportInv),
world_pos,
unused_N,
unused_color,
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_paint_point_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_paint_point_vert.glsl
index 8736b2a87db..7b7408964f2 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_paint_point_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_paint_point_vert.glsl
@@ -10,8 +10,8 @@ void main()
vec3 world_pos = point_object_to_world(pos);
gl_Position = point_world_to_ndc(world_pos);
- /* Add offset in Z to avoid zfighting and render selected wires on top. */
- /* TODO: scale this bias using znear and zfar range. */
+ /* Add offset in Z to avoid Z-fighting and render selected wires on top. */
+ /* TODO: scale this bias using Z-near and Z-far range. */
gl_Position.z -= (is_select ? 2e-4 : 1e-4);
if (is_hidden) {
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_paint_wire_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_paint_wire_vert.glsl
index 749cc92f082..f34133596b1 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_paint_wire_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_paint_wire_vert.glsl
@@ -10,8 +10,8 @@ void main()
vec3 world_pos = point_object_to_world(pos);
gl_Position = point_world_to_ndc(world_pos);
- /* Add offset in Z to avoid zfighting and render selected wires on top. */
- /* TODO: scale this bias using znear and zfar range. */
+ /* Add offset in Z to avoid Z-fighting and render selected wires on top. */
+ /* TODO: scale this bias using Z-near and Z-far range. */
gl_Position.z -= (is_select ? 2e-4 : 1e-4);
if (is_hidden) {
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_particle_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_particle_vert.glsl
index c48e7cce550..2c2d3199e45 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_particle_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_particle_vert.glsl
@@ -16,7 +16,7 @@ vec3 rotate(vec3 vec, vec4 quat)
void main()
{
/* Drawsize packed in alpha. */
- float draw_size = color.a;
+ float draw_size = ucolor.a;
vec3 world_pos = part_pos;
@@ -28,7 +28,7 @@ void main()
if ((vclass & VCLASS_SCREENALIGNED) != 0) {
/* World sized, camera facing geometry. */
- world_pos += (screenVecs[0].xyz * pos.x + screenVecs[1].xyz * pos.y) * draw_size;
+ world_pos += (ViewMatrixInverse[0].xyz * pos.x + ViewMatrixInverse[1].xyz * pos.y) * draw_size;
}
else {
world_pos += rotate(pos, part_rot) * draw_size;
@@ -43,7 +43,7 @@ void main()
finalColor = vec4(clamp(pos * 10000.0, 0.0, 1.0), 1.0);
}
else if (part_val < 0.0) {
- finalColor = vec4(color.rgb, 1.0);
+ finalColor = vec4(ucolor.rgb, 1.0);
}
else {
finalColor = vec4(texture(weightTex, part_val).rgb, 1.0);
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_pointcloud_only_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_pointcloud_only_vert.glsl
new file mode 100644
index 00000000000..8a7e81028d3
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_pointcloud_only_vert.glsl
@@ -0,0 +1,9 @@
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_pointcloud_lib.glsl)
+
+void main()
+{
+ vec3 world_pos = pointcloud_get_pos();
+ gl_Position = point_world_to_ndc(world_pos);
+}
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_uniform_color_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_uniform_color_frag.glsl
index e1a4a3602e3..2794481489c 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_uniform_color_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_uniform_color_frag.glsl
@@ -1,4 +1,4 @@
void main()
{
- fragColor = color;
+ fragColor = ucolor;
}
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_curve_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_curve_vert.glsl
new file mode 100644
index 00000000000..7c2c386b2f5
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_curve_vert.glsl
@@ -0,0 +1,9 @@
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+void main()
+{
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
+ finalColor = attribute_value;
+}
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_curves_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_curves_vert.glsl
new file mode 100644
index 00000000000..23d313e036f
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_curves_vert.glsl
@@ -0,0 +1,28 @@
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
+
+void main()
+{
+ bool is_persp = (ProjectionMatrix[3][3] == 0.0);
+ float time, thick_time, thickness;
+ vec3 world_pos, tan, binor;
+ hair_get_pos_tan_binor_time(is_persp,
+ ModelMatrixInverse,
+ ViewMatrixInverse[3].xyz,
+ ViewMatrixInverse[2].xyz,
+ world_pos,
+ tan,
+ binor,
+ time,
+ thickness,
+ thick_time);
+ gl_Position = point_world_to_ndc(world_pos);
+
+ if (is_point_domain) {
+ finalColor = texelFetch(color_tx, hair_get_base_id());
+ }
+ else {
+ finalColor = texelFetch(color_tx, hair_get_strand_id());
+ }
+}
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_frag.glsl
new file mode 100644
index 00000000000..e5752ada940
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_frag.glsl
@@ -0,0 +1,8 @@
+
+void main()
+{
+ out_color = finalColor;
+ out_color.a *= opacity;
+ /* Writing to this second texture is necessary to avoid undefined behavior. */
+ lineOutput = vec4(0.0);
+}
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_mesh_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_mesh_vert.glsl
new file mode 100644
index 00000000000..7c2c386b2f5
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_mesh_vert.glsl
@@ -0,0 +1,9 @@
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+void main()
+{
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
+ finalColor = attribute_value;
+}
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_pointcloud_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_pointcloud_vert.glsl
new file mode 100644
index 00000000000..e7b7cafd898
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_pointcloud_vert.glsl
@@ -0,0 +1,10 @@
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_pointcloud_lib.glsl)
+
+void main()
+{
+ vec3 world_pos = pointcloud_get_pos();
+ gl_Position = point_world_to_ndc(world_pos);
+ finalColor = pointcloud_get_customdata_vec4(attribute_tx);
+}
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_wireframe_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_wireframe_frag.glsl
index bc28d7a8a36..d3eb1a500ba 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_wireframe_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_wireframe_frag.glsl
@@ -17,10 +17,10 @@ void main()
vec2 dir = lineOutput.xy * 2.0 - 1.0;
bool dir_horiz = abs(dir.x) > abs(dir.y);
- vec2 uv = gl_FragCoord.xy * drw_view.viewport_size_inverse;
+ vec2 uv = gl_FragCoord.xy * sizeViewportInv;
float depth_occluder = texture(depthTex, uv).r;
float depth_min = depth_occluder;
- vec2 texel_uv_size = drw_view.viewport_size_inverse;
+ vec2 texel_uv_size = sizeViewportInv;
if (dir_horiz) {
depth_min = min(depth_min, texture(depthTex, uv + vec2(-texel_uv_size.x, 0.0)).r);
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_wireframe_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_wireframe_vert.glsl
index d189ab1b72c..7af2e0b3427 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_wireframe_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_wireframe_vert.glsl
@@ -96,7 +96,7 @@ void main()
wofs = normal_world_to_view(wofs);
/* Push vertex half a pixel (maximum) in normal direction. */
- gl_Position.xy += wofs.xy * drw_view.viewport_size_inverse * gl_Position.w;
+ gl_Position.xy += wofs.xy * sizeViewportInv * gl_Position.w;
/* Push the vertex towards the camera. Helps a bit. */
gl_Position.z -= facing_ratio * curvature * 1.0e-6 * gl_Position.w;
@@ -136,8 +136,7 @@ void main()
#ifdef SELECT_EDGES
/* HACK: to avoid losing sub-pixel object in selections, we add a bit of randomness to the
* wire to at least create one fragment that will pass the occlusion query. */
- gl_Position.xy += drw_view.viewport_size_inverse * gl_Position.w *
- ((gl_VertexID % 2 == 0) ? -1.0 : 1.0);
+ gl_Position.xy += sizeViewportInv * gl_Position.w * ((gl_VertexID % 2 == 0) ? -1.0 : 1.0);
#endif
view_clipping_distances(wpos);
diff --git a/source/blender/draw/engines/select/select_engine.c b/source/blender/draw/engines/select/select_engine.c
index 026a1f52ac1..07e2a42b808 100644
--- a/source/blender/draw/engines/select/select_engine.c
+++ b/source/blender/draw/engines/select/select_engine.c
@@ -205,7 +205,7 @@ static void select_cache_populate(void *vedata, Object *ob)
struct Mesh *me = ob->data;
if (e_data.context.select_mode & SCE_SELECT_FACE) {
struct GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
- DRW_shgroup_call_obmat(stl->g_data->shgrp_depth_only, geom_faces, ob->obmat);
+ DRW_shgroup_call_obmat(stl->g_data->shgrp_depth_only, geom_faces, ob->object_to_world);
}
else if (ob->dt >= OB_SOLID) {
#ifdef USE_CAGE_OCCLUSION
@@ -213,17 +213,17 @@ static void select_cache_populate(void *vedata, Object *ob)
#else
struct GPUBatch *geom_faces = DRW_mesh_batch_cache_get_surface(me);
#endif
- DRW_shgroup_call_obmat(stl->g_data->shgrp_depth_only, geom_faces, ob->obmat);
+ DRW_shgroup_call_obmat(stl->g_data->shgrp_depth_only, geom_faces, ob->object_to_world);
}
if (e_data.context.select_mode & SCE_SELECT_EDGE) {
struct GPUBatch *geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me);
- DRW_shgroup_call_obmat(stl->g_data->shgrp_depth_only, geom_edges, ob->obmat);
+ DRW_shgroup_call_obmat(stl->g_data->shgrp_depth_only, geom_edges, ob->object_to_world);
}
if (e_data.context.select_mode & SCE_SELECT_VERTEX) {
struct GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
- DRW_shgroup_call_obmat(stl->g_data->shgrp_depth_only, geom_verts, ob->obmat);
+ DRW_shgroup_call_obmat(stl->g_data->shgrp_depth_only, geom_verts, ob->object_to_world);
}
return;
}
@@ -231,7 +231,7 @@ static void select_cache_populate(void *vedata, Object *ob)
float min[3], max[3];
select_id_object_min_max(ob, min, max);
- if (DRW_culling_min_max_test(stl->g_data->view_subregion, ob->obmat, min, max)) {
+ if (DRW_culling_min_max_test(stl->g_data->view_subregion, ob->object_to_world, min, max)) {
if (sel_data == NULL) {
sel_data = (SELECTID_ObjectData *)DRW_drawdata_ensure(
&ob->id, &draw_engine_select_type, sizeof(SELECTID_ObjectData), NULL, NULL);
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
index 11d7c85d43a..2a3b5337451 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
@@ -89,7 +89,7 @@ void main()
texel = (texel - 0.5) / vec4(textureSize(sceneColorTex, 0).xyxy);
/* Using texelFetch can bypass the mip range setting on some platform.
- * Using texture Lod fix this issue. Note that we need to disable filtering to get the right
+ * Using texture LOD fixes this issue. Note that we need to disable filtering to get the right
* texel values. */
vec4 color1 = textureLod(sceneColorTex, texel.xy, 0.0);
vec4 color2 = textureLod(sceneColorTex, texel.zw, 0.0);
@@ -200,7 +200,7 @@ void main()
vec2 get_random_vector(float offset)
{
- /* Interlieved gradient noise by Jorge Jimenez
+ /* Interleaved gradient noise by Jorge Jimenez
* http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare */
float ign = fract(offset +
52.9829189 * fract(0.06711056 * gl_FragCoord.x + 0.00583715 * gl_FragCoord.y));
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl
index 213279b1913..cd5ac21688c 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl
@@ -6,7 +6,7 @@
#pragma BLENDER_REQUIRE(workbench_world_light_lib.glsl)
/* Special function only to be used with calculate_transparent_weight(). */
-float linear_zdepth(float depth, vec4 viewvecs[2], mat4 proj_mat)
+float linear_zdepth(float depth, mat4 proj_mat)
{
if (proj_mat[3][3] == 0.0) {
float d = 2.0 * depth - 1.0;
@@ -14,7 +14,8 @@ float linear_zdepth(float depth, vec4 viewvecs[2], mat4 proj_mat)
}
else {
/* Return depth from near plane. */
- return depth * viewvecs[1].z;
+ float z_delta = -2.0 / proj_mat[2][2];
+ return depth * z_delta;
}
}
@@ -24,7 +25,7 @@ float linear_zdepth(float depth, vec4 viewvecs[2], mat4 proj_mat)
*/
float calculate_transparent_weight(void)
{
- float z = linear_zdepth(gl_FragCoord.z, drw_view.viewvecs, drw_view.winmat);
+ float z = linear_zdepth(gl_FragCoord.z, drw_view.winmat);
#if 0
/* Eq 10 : Good for surfaces with varying opacity (like particles) */
float a = min(1.0, alpha * 10.0) + 0.01;
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
index afba3a0d784..133fe7f4b0f 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
@@ -30,7 +30,7 @@ vec4 sample_tricubic(sampler3D ima, vec3 co)
vec3 f = co - tc;
vec3 f2 = f * f;
vec3 f3 = f2 * f;
- /* Bspline coefs (optimized) */
+ /* Bspline coefficients (optimized). */
vec3 w3 = f3 / 6.0;
vec3 w0 = -w3 + f2 * 0.5 - f * 0.5 + 1.0 / 6.0;
vec3 w1 = f3 * 0.5 - f2 + 2.0 / 3.0;
diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c
index f7f156e5297..3ea0805b8f1 100644
--- a/source/blender/draw/engines/workbench/workbench_data.c
+++ b/source/blender/draw/engines/workbench/workbench_data.c
@@ -173,7 +173,7 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
if (!v3d || (v3d->shading.type == OB_RENDER && BKE_scene_uses_blender_workbench(scene))) {
short shading_flag = scene->display.shading.flag;
- if (XRAY_FLAG_ENABLED((&scene->display))) {
+ if (XRAY_FLAG_ENABLED(&scene->display)) {
/* Disable shading options that aren't supported in transparency mode. */
shading_flag &= ~(V3D_SHADING_SHADOW | V3D_SHADING_CAVITY | V3D_SHADING_DEPTH_OF_FIELD);
}
@@ -187,8 +187,8 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
wpd->shading = scene->display.shading;
wpd->shading.flag = shading_flag;
- if (XRAY_FLAG_ENABLED((&scene->display))) {
- wpd->shading.xray_alpha = XRAY_ALPHA((&scene->display));
+ if (XRAY_FLAG_ENABLED(&scene->display)) {
+ wpd->shading.xray_alpha = XRAY_ALPHA(&scene->display);
}
else {
wpd->shading.xray_alpha = 1.0f;
diff --git a/source/blender/draw/engines/workbench/workbench_effect_dof.c b/source/blender/draw/engines/workbench/workbench_effect_dof.c
index 58d49cf226e..a7247f4e9a6 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_dof.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_dof.c
@@ -128,7 +128,7 @@ void workbench_dof_engine_init(WORKBENCH_Data *vedata)
camera = wpd->cam_original_ob;
}
- Camera *cam = camera != NULL ? camera->data : NULL;
+ Camera *cam = camera != NULL && camera->type == OB_CAMERA ? camera->data : NULL;
if ((wpd->shading.flag & V3D_SHADING_DEPTH_OF_FIELD) == 0 || (cam == NULL) ||
((cam->dof.flag & CAM_DOF_ENABLED) == 0)) {
wpd->dof_enabled = false;
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index a0459a967f3..15a16539a26 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -14,6 +14,7 @@
#include "BLI_alloca.h"
#include "BKE_editmesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_paint.h"
@@ -26,9 +27,12 @@
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_node_types.h"
+#include "DNA_pointcloud_types.h"
#include "ED_paint.h"
+#include "GPU_context.h"
+
#include "workbench_engine.h"
#include "workbench_private.h"
@@ -36,6 +40,7 @@
void workbench_engine_init(void *ved)
{
+ GPU_render_begin();
WORKBENCH_Data *vedata = ved;
WORKBENCH_StorageList *stl = vedata->stl;
WORKBENCH_TextureList *txl = vedata->txl;
@@ -64,6 +69,7 @@ void workbench_engine_init(void *ved)
workbench_dof_engine_init(vedata);
workbench_antialiasing_engine_init(vedata);
workbench_volume_engine_init(vedata);
+ GPU_render_end();
}
void workbench_cache_init(void *ved)
@@ -98,7 +104,11 @@ static void workbench_cache_sculpt_populate(WORKBENCH_PrivateData *wpd,
const bool use_single_drawcall = !ELEM(color_type, V3D_SHADING_MATERIAL_COLOR);
if (use_single_drawcall) {
DRWShadingGroup *grp = workbench_material_setup(wpd, ob, ob->actcol, color_type, NULL);
- DRW_shgroup_call_sculpt(grp, ob, false, false);
+
+ bool use_color = color_type == V3D_SHADING_VERTEX_COLOR;
+ bool use_uv = color_type == V3D_SHADING_TEXTURE_COLOR;
+
+ DRW_shgroup_call_sculpt(grp, ob, false, false, false, use_color, use_uv);
}
else {
const int materials_len = DRW_cache_object_material_count_get(ob);
@@ -106,7 +116,7 @@ static void workbench_cache_sculpt_populate(WORKBENCH_PrivateData *wpd,
for (int i = 0; i < materials_len; i++) {
shgrps[i] = workbench_material_setup(wpd, ob, i + 1, color_type, NULL);
}
- DRW_shgroup_call_sculpt_with_materials(shgrps, materials_len, ob);
+ DRW_shgroup_call_sculpt_with_materials(shgrps, NULL, materials_len, ob);
}
}
@@ -223,7 +233,7 @@ static void workbench_cache_hair_populate(WORKBENCH_PrivateData *wpd,
static const CustomData *workbench_mesh_get_loop_custom_data(const Mesh *mesh)
{
- if (mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
+ if (BKE_mesh_wrapper_type(mesh) == ME_WRAPPER_TYPE_BMESH) {
BLI_assert(mesh->edit_mesh != NULL);
BLI_assert(mesh->edit_mesh->bm != NULL);
return &mesh->edit_mesh->bm->ldata;
@@ -233,7 +243,7 @@ static const CustomData *workbench_mesh_get_loop_custom_data(const Mesh *mesh)
static const CustomData *workbench_mesh_get_vert_custom_data(const Mesh *mesh)
{
- if (mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
+ if (BKE_mesh_wrapper_type(mesh) == ME_WRAPPER_TYPE_BMESH) {
BLI_assert(mesh->edit_mesh != NULL);
BLI_assert(mesh->edit_mesh->bm != NULL);
return &mesh->edit_mesh->bm->vdata;
@@ -257,7 +267,7 @@ static eV3DShadingColorType workbench_color_type_get(WORKBENCH_PrivateData *wpd,
const DRWContextState *draw_ctx = DRW_context_state_get();
const bool is_active = (ob == draw_ctx->obact);
- const bool is_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) &&
+ const bool is_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->rv3d) &&
!DRW_state_is_image_render();
const bool is_render = DRW_state_is_image_render() && (draw_ctx->v3d == NULL);
const bool is_texpaint_mode = is_active && (wpd->ctx_mode == CTX_MODE_PAINT_TEXTURE);
@@ -409,7 +419,7 @@ void workbench_cache_populate(void *ved, Object *ob)
return;
}
- if (ELEM(ob->type, OB_MESH, OB_POINTCLOUD)) {
+ if (ob->type == OB_MESH) {
bool use_sculpt_pbvh, use_texpaint_mode, draw_shadow, has_transp_mat = false;
eV3DShadingColorType color_type = workbench_color_type_get(
wpd, ob, &use_sculpt_pbvh, &use_texpaint_mode, &draw_shadow);
@@ -433,6 +443,12 @@ void workbench_cache_populate(void *ved, Object *ob)
DRWShadingGroup *grp = workbench_material_hair_setup(wpd, ob, CURVES_MATERIAL_NR, color_type);
DRW_shgroup_curves_create_sub(ob, grp, NULL);
}
+ else if (ob->type == OB_POINTCLOUD) {
+ int color_type = workbench_color_type_get(wpd, ob, NULL, NULL, NULL);
+ DRWShadingGroup *grp = workbench_material_ptcloud_setup(
+ wpd, ob, POINTCLOUD_MATERIAL_NR, color_type);
+ DRW_shgroup_pointcloud_create_sub(ob, grp, NULL);
+ }
else if (ob->type == OB_VOLUME) {
if (wpd->shading.type != OB_WIRE) {
int color_type = workbench_color_type_get(wpd, ob, NULL, NULL, NULL);
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index 4744c0db6ce..7c5e8313532 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -88,14 +88,14 @@ BLI_INLINE Material *workbench_object_material_get(Object *ob, int mat_nr)
BLI_INLINE void workbench_material_get_image(
Object *ob, int mat_nr, Image **r_image, ImageUser **r_iuser, eGPUSamplerState *r_sampler)
{
- bNode *node;
+ const bNode *node;
*r_sampler = 0;
ED_object_get_active_image(ob, mat_nr, r_image, r_iuser, &node, NULL);
if (node && *r_image) {
switch (node->type) {
case SH_NODE_TEX_IMAGE: {
- NodeTexImage *storage = node->storage;
+ const NodeTexImage *storage = node->storage;
const bool use_filter = (storage->interpolation != SHD_INTERP_CLOSEST);
const bool use_repeat = (storage->extension == SHD_IMAGE_EXTENSION_REPEAT);
const bool use_clip = (storage->extension == SHD_IMAGE_EXTENSION_CLIP);
@@ -105,7 +105,7 @@ BLI_INLINE void workbench_material_get_image(
break;
}
case SH_NODE_TEX_ENVIRONMENT: {
- NodeTexEnvironment *storage = node->storage;
+ const NodeTexEnvironment *storage = node->storage;
const bool use_filter = (storage->interpolation != SHD_INTERP_CLOSEST);
SET_FLAG_FROM_TEST(*r_sampler, use_filter, GPU_SAMPLER_FILTER);
break;
diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h
index 492bce1e571..4aedaf443b9 100644
--- a/source/blender/draw/engines/workbench/workbench_private.h
+++ b/source/blender/draw/engines/workbench/workbench_private.h
@@ -511,6 +511,11 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
#define workbench_image_hair_setup(wpd, ob, mat_nr, ima, iuser, interp) \
workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, interp, WORKBENCH_DATATYPE_HAIR)
+#define workbench_material_ptcloud_setup(wpd, ob, mat_nr, color_type) \
+ workbench_material_setup_ex(wpd, ob, mat_nr, color_type, WORKBENCH_DATATYPE_POINTCLOUD, 0)
+#define workbench_image_ptcloud_setup(wpd, ob, mat_nr, ima, iuser, interp) \
+ workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, interp, WORKBENCH_DATATYPE_POINTCLOUD)
+
/* workbench_data.c */
void workbench_private_data_alloc(WORKBENCH_StorageList *stl);
diff --git a/source/blender/draw/engines/workbench/workbench_shader.cc b/source/blender/draw/engines/workbench/workbench_shader.cc
index 9501e653d3b..acfe5adf728 100644
--- a/source/blender/draw/engines/workbench/workbench_shader.cc
+++ b/source/blender/draw/engines/workbench/workbench_shader.cc
@@ -194,7 +194,7 @@ GPUShader *workbench_shader_composite_get(WORKBENCH_PrivateData *wpd)
return *shader;
}
-GPUShader *workbench_shader_merge_infront_get(WORKBENCH_PrivateData *UNUSED(wpd))
+GPUShader *workbench_shader_merge_infront_get(WORKBENCH_PrivateData * /*wpd*/)
{
if (e_data.merge_infront_sh == nullptr) {
e_data.merge_infront_sh = GPU_shader_create_from_info_name("workbench_merge_infront");
@@ -202,7 +202,7 @@ GPUShader *workbench_shader_merge_infront_get(WORKBENCH_PrivateData *UNUSED(wpd)
return e_data.merge_infront_sh;
}
-GPUShader *workbench_shader_transparent_resolve_get(WORKBENCH_PrivateData *UNUSED(wpd))
+GPUShader *workbench_shader_transparent_resolve_get(WORKBENCH_PrivateData * /*wpd*/)
{
if (e_data.oit_resolve_sh == nullptr) {
e_data.oit_resolve_sh = GPU_shader_create_from_info_name("workbench_transparent_resolve");
diff --git a/source/blender/draw/engines/workbench/workbench_shadow.c b/source/blender/draw/engines/workbench/workbench_shadow.c
index 0b34e849049..211c0e27418 100644
--- a/source/blender/draw/engines/workbench/workbench_shadow.c
+++ b/source/blender/draw/engines/workbench/workbench_shadow.c
@@ -172,7 +172,7 @@ static const BoundBox *workbench_shadow_object_shadow_bbox_get(WORKBENCH_Private
{
if (oed->shadow_bbox_dirty || wpd->shadow_changed) {
float tmp_mat[4][4];
- mul_m4_m4m4(tmp_mat, wpd->shadow_inv, ob->obmat);
+ mul_m4_m4m4(tmp_mat, wpd->shadow_inv, ob->object_to_world);
/* Get AABB in shadow space. */
INIT_MINMAX(oed->shadow_min, oed->shadow_max);
@@ -307,7 +307,8 @@ void workbench_shadow_cache_populate(WORKBENCH_Data *data, Object *ob, const boo
NULL);
if (workbench_shadow_object_cast_visible_shadow(wpd, ob, engine_object_data)) {
- mul_v3_mat3_m4v3(engine_object_data->shadow_dir, ob->imat, wpd->shadow_direction_ws);
+ mul_v3_mat3_m4v3(
+ engine_object_data->shadow_dir, ob->world_to_object, wpd->shadow_direction_ws);
DRWShadingGroup *grp;
bool use_shadow_pass_technique = !workbench_shadow_camera_in_object_shadow(
diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c
index ce7773e7439..7c6df93f5a3 100644
--- a/source/blender/draw/engines/workbench/workbench_volume.c
+++ b/source/blender/draw/engines/workbench/workbench_volume.c
@@ -237,7 +237,7 @@ static void workbench_volume_object_cache_populate(WORKBENCH_Data *vedata,
/* Combined texture to object, and object to world transform. */
float texture_to_world[4][4];
- mul_m4_m4m4(texture_to_world, ob->obmat, grid->texture_to_object);
+ mul_m4_m4m4(texture_to_world, ob->object_to_world, grid->texture_to_object);
if (use_slice) {
float invviewmat[4][4];
@@ -291,7 +291,7 @@ static void workbench_volume_object_cache_populate(WORKBENCH_Data *vedata,
/* Compute density scale. */
const float density_scale = volume->display.density *
- BKE_volume_density_scale(volume, ob->obmat);
+ BKE_volume_density_scale(volume, ob->object_to_world);
DRW_shgroup_uniform_texture(grp, "densityTexture", grid->texture);
/* TODO: implement shadow texture, see manta_smoke_calc_transparency. */
diff --git a/source/blender/draw/intern/DRW_gpu_wrapper.hh b/source/blender/draw/intern/DRW_gpu_wrapper.hh
index 890cd588527..3be50d471e2 100644
--- a/source/blender/draw/intern/DRW_gpu_wrapper.hh
+++ b/source/blender/draw/intern/DRW_gpu_wrapper.hh
@@ -31,6 +31,10 @@
* discarding all data inside it.
* Data can be accessed using the [] operator.
*
+ * `draw::StorageVectorBuffer<T, len>`
+ * Same as `StorageArrayBuffer` but has a length counter and act like a `blender::Vector` you can
+ * clear and append to.
+ *
* `draw::StorageBuffer<T>`
* A storage buffer object class inheriting from T.
* Data can be accessed just like a normal T object.
@@ -313,8 +317,8 @@ class UniformBuffer : public T, public detail::UniformCommon<T, 1, false> {
template<
/** Type of the values stored in this uniform buffer. */
typename T,
- /** The number of values that can be stored in this uniform buffer. */
- int64_t len,
+ /** The number of values that can be stored in this storage buffer at creation. */
+ int64_t len = 16u / sizeof(T),
/** True if created on device and no memory host memory is allocated. */
bool device_only = false>
class StorageArrayBuffer : public detail::StorageCommon<T, len, device_only> {
@@ -357,6 +361,71 @@ class StorageArrayBuffer : public detail::StorageCommon<T, len, device_only> {
}
return this->data_[index];
}
+
+ int64_t size() const
+ {
+ return this->len_;
+ }
+};
+
+template<
+ /** Type of the values stored in this uniform buffer. */
+ typename T,
+ /** The number of values that can be stored in this storage buffer at creation. */
+ int64_t len = 16u / sizeof(T)>
+class StorageVectorBuffer : public StorageArrayBuffer<T, len, false> {
+ private:
+ /* Number of items, not the allocated length. */
+ int64_t item_len_ = 0;
+
+ public:
+ StorageVectorBuffer(const char *name = nullptr) : StorageArrayBuffer<T, len, false>(name){};
+ ~StorageVectorBuffer(){};
+
+ /**
+ * Set item count to zero but does not free memory or resize the buffer.
+ */
+ void clear()
+ {
+ item_len_ = 0;
+ }
+
+ /**
+ * Insert a new element at the end of the vector.
+ * This might cause a reallocation with the capacity is exceeded.
+ *
+ * This is similar to std::vector::push_back.
+ */
+ void append(const T &value)
+ {
+ this->append_as(value);
+ }
+ void append(T &&value)
+ {
+ this->append_as(std::move(value));
+ }
+ template<typename... ForwardT> void append_as(ForwardT &&...value)
+ {
+ if (item_len_ >= this->len_) {
+ size_t size = power_of_2_max_u(item_len_ + 1);
+ this->resize(size);
+ }
+ T *ptr = &this->data_[item_len_++];
+ new (ptr) T(std::forward<ForwardT>(value)...);
+ }
+
+ int64_t size() const
+ {
+ return item_len_;
+ }
+
+ bool is_empty() const
+ {
+ return this->size() == 0;
+ }
+
+ /* Avoid confusion with the other clear. */
+ void clear_to_zero() = delete;
};
template<
@@ -855,6 +924,35 @@ class TextureFromPool : public Texture, NonMovable {
GPUTexture *stencil_view() = delete;
};
+class TextureRef : public Texture {
+ public:
+ TextureRef() = default;
+
+ ~TextureRef()
+ {
+ this->tx_ = nullptr;
+ }
+
+ void wrap(GPUTexture *tex)
+ {
+ this->tx_ = tex;
+ }
+
+ /** Remove methods that are forbidden with this type of textures. */
+ bool ensure_1d(int, int, eGPUTextureFormat, float *) = delete;
+ bool ensure_1d_array(int, int, int, eGPUTextureFormat, float *) = delete;
+ bool ensure_2d(int, int, int, eGPUTextureFormat, float *) = delete;
+ bool ensure_2d_array(int, int, int, int, eGPUTextureFormat, float *) = delete;
+ bool ensure_3d(int, int, int, int, eGPUTextureFormat, float *) = delete;
+ bool ensure_cube(int, int, eGPUTextureFormat, float *) = delete;
+ bool ensure_cube_array(int, int, int, eGPUTextureFormat, float *) = delete;
+ void filter_mode(bool) = delete;
+ void free() = delete;
+ GPUTexture *mip_view(int) = delete;
+ GPUTexture *layer_view(int) = delete;
+ GPUTexture *stencil_view() = delete;
+};
+
/**
* Dummy type to bind texture as image.
* It is just a GPUTexture in disguise.
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index b49203d85f6..b9444c58191 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -207,10 +207,6 @@ struct GPUShader *DRW_shader_create_with_lib_ex(const char *vert,
const char *lib,
const char *defines,
const char *name);
-struct GPUShader *DRW_shader_create_compute_with_shaderlib(const char *comp,
- const DRWShaderLibrary *lib,
- const char *defines,
- const char *name);
struct GPUShader *DRW_shader_create_with_shaderlib_ex(const char *vert,
const char *geom,
const char *frag,
@@ -402,8 +398,18 @@ void DRW_shgroup_call_instances_with_attrs(DRWShadingGroup *shgroup,
struct GPUBatch *geom,
struct GPUBatch *inst_attributes);
-void DRW_shgroup_call_sculpt(DRWShadingGroup *sh, Object *ob, bool wire, bool mask);
-void DRW_shgroup_call_sculpt_with_materials(DRWShadingGroup **sh, int num_sh, Object *ob);
+void DRW_shgroup_call_sculpt(DRWShadingGroup *shgroup,
+ Object *ob,
+ bool use_wire,
+ bool use_mask,
+ bool use_fset,
+ bool use_color,
+ bool use_uv);
+
+void DRW_shgroup_call_sculpt_with_materials(DRWShadingGroup **shgroups,
+ struct GPUMaterial **gpumats,
+ int num_shgroups,
+ Object *ob);
DRWCallBuffer *DRW_shgroup_call_buffer(DRWShadingGroup *shgroup,
struct GPUVertFormat *format,
@@ -677,8 +683,6 @@ const DRWView *DRW_view_get_active(void);
* \note planes must be in world space.
*/
void DRW_view_clip_planes_set(DRWView *view, float (*planes)[4], int plane_len);
-void DRW_view_camtexco_set(DRWView *view, float texco[4]);
-void DRW_view_camtexco_get(const DRWView *view, float r_texco[4]);
/* For all getters, if view is NULL, default view is assumed. */
@@ -734,7 +738,6 @@ void DRW_culling_frustum_planes_get(const DRWView *view, float planes[6][4]);
const float *DRW_viewport_size_get(void);
const float *DRW_viewport_invert_size_get(void);
-const float *DRW_viewport_screenvecs_get(void);
const float *DRW_viewport_pixelsize_get(void);
struct DefaultFramebufferList *DRW_viewport_framebuffer_list_get(void);
@@ -938,6 +941,14 @@ typedef struct DRWContextState {
const DRWContextState *DRW_context_state_get(void);
+struct DRW_Attributes;
+struct DRW_MeshCDMask;
+
+void DRW_mesh_batch_cache_get_attributes(struct Object *object,
+ struct Mesh *me,
+ struct DRW_Attributes **r_attrs,
+ struct DRW_MeshCDMask **r_cd_needed);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/draw/intern/draw_attributes.cc b/source/blender/draw/intern/draw_attributes.cc
index 011d72e9e8f..cc7c9959850 100644
--- a/source/blender/draw/intern/draw_attributes.cc
+++ b/source/blender/draw/intern/draw_attributes.cc
@@ -44,13 +44,10 @@ void drw_attributes_clear(DRW_Attributes *attributes)
memset(attributes, 0, sizeof(DRW_Attributes));
}
-void drw_attributes_merge(DRW_Attributes *dst,
- const DRW_Attributes *src,
- ThreadMutex *render_mutex)
+void drw_attributes_merge(DRW_Attributes *dst, const DRW_Attributes *src, std::mutex &render_mutex)
{
- BLI_mutex_lock(render_mutex);
+ std::lock_guard lock{render_mutex};
drw_attributes_merge_requests(src, dst);
- BLI_mutex_unlock(render_mutex);
}
bool drw_attributes_overlap(const DRW_Attributes *a, const DRW_Attributes *b)
diff --git a/source/blender/draw/intern/draw_attributes.h b/source/blender/draw/intern/draw_attributes.h
index b577c6c4162..00621c711bf 100644
--- a/source/blender/draw/intern/draw_attributes.h
+++ b/source/blender/draw/intern/draw_attributes.h
@@ -9,6 +9,10 @@
#pragma once
+#ifdef __cplusplus
+# include <mutex>
+#endif
+
#include "DNA_customdata_types.h"
#include "DNA_meshdata_types.h"
@@ -16,6 +20,7 @@
#include "BLI_sys_types.h"
#include "BLI_threads.h"
+#include "BLI_utildefines.h"
#include "GPU_shader.h"
#include "GPU_vertex_format.h"
@@ -36,11 +41,30 @@ typedef struct DRW_Attributes {
int num_requests;
} DRW_Attributes;
+typedef struct DRW_MeshCDMask {
+ uint32_t uv : 8;
+ uint32_t tan : 8;
+ uint32_t orco : 1;
+ uint32_t tan_orco : 1;
+ uint32_t sculpt_overlays : 1;
+ /**
+ * Edit uv layer is from the base edit mesh as modifiers could remove it. (see T68857)
+ */
+ uint32_t edit_uv : 1;
+} DRW_MeshCDMask;
+
+/* Keep `DRW_MeshCDMask` struct within a `uint32_t`.
+ * bit-wise and atomic operations are used to compare and update the struct.
+ * See `mesh_cd_layers_type_*` functions. */
+BLI_STATIC_ASSERT(sizeof(DRW_MeshCDMask) <= sizeof(uint32_t), "DRW_MeshCDMask exceeds 32 bits")
+
void drw_attributes_clear(DRW_Attributes *attributes);
+#ifdef __cplusplus
void drw_attributes_merge(DRW_Attributes *dst,
const DRW_Attributes *src,
- ThreadMutex *render_mutex);
+ std::mutex &render_mutex);
+#endif
/* Return true if all requests in b are in a. */
bool drw_attributes_overlap(const DRW_Attributes *a, const DRW_Attributes *b);
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 6537490c06c..00ac2563c43 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -899,8 +899,6 @@ GPUBatch *DRW_cache_object_surface_get(Object *ob)
switch (ob->type) {
case OB_MESH:
return DRW_cache_mesh_surface_get(ob);
- case OB_POINTCLOUD:
- return DRW_cache_pointcloud_surface_get(ob);
default:
return NULL;
}
@@ -959,8 +957,6 @@ GPUBatch **DRW_cache_object_surface_material_get(struct Object *ob,
switch (ob->type) {
case OB_MESH:
return DRW_cache_mesh_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
- case OB_POINTCLOUD:
- return DRW_cache_pointcloud_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
default:
return NULL;
}
@@ -2423,7 +2419,7 @@ static float x_axis_name[4][2] = {
{-0.9f * S_X, 1.0f * S_Y},
{1.0f * S_X, -1.0f * S_Y},
};
-#define X_LEN (sizeof(x_axis_name) / (sizeof(float[2])))
+#define X_LEN (sizeof(x_axis_name) / sizeof(float[2]))
#undef S_X
#undef S_Y
@@ -2437,7 +2433,7 @@ static float y_axis_name[6][2] = {
{0.0f * S_X, -0.1f * S_Y},
{0.0f * S_X, -1.0f * S_Y},
};
-#define Y_LEN (sizeof(y_axis_name) / (sizeof(float[2])))
+#define Y_LEN (sizeof(y_axis_name) / sizeof(float[2]))
#undef S_X
#undef S_Y
@@ -2455,7 +2451,7 @@ static float z_axis_name[10][2] = {
{-1.00f * S_X, -1.00f * S_Y},
{1.00f * S_X, -1.00f * S_Y},
};
-#define Z_LEN (sizeof(z_axis_name) / (sizeof(float[2])))
+#define Z_LEN (sizeof(z_axis_name) / sizeof(float[2]))
#undef S_X
#undef S_Y
@@ -2482,7 +2478,7 @@ static float axis_marker[8][2] = {
{-S_X, 0.0f}
#endif
};
-#define MARKER_LEN (sizeof(axis_marker) / (sizeof(float[2])))
+#define MARKER_LEN (sizeof(axis_marker) / sizeof(float[2]))
#define MARKER_FILL_LAYER 6
#undef S_X
#undef S_Y
@@ -2889,6 +2885,12 @@ GPUBatch *DRW_cache_mesh_surface_mesh_analysis_get(Object *ob)
return DRW_mesh_batch_cache_get_edit_mesh_analysis(ob->data);
}
+GPUBatch *DRW_cache_mesh_surface_viewer_attribute_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+ return DRW_mesh_batch_cache_get_surface_viewer_attribute(ob->data);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -2902,6 +2904,13 @@ GPUBatch *DRW_cache_curve_edge_wire_get(Object *ob)
return DRW_curve_batch_cache_get_wire_edge(cu);
}
+GPUBatch *DRW_cache_curve_edge_wire_viewer_attribute_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_CURVES_LEGACY);
+ struct Curve *cu = ob->data;
+ return DRW_curve_batch_cache_get_wire_edge_viewer_attribute(cu);
+}
+
GPUBatch *DRW_cache_curve_edge_normal_get(Object *ob)
{
BLI_assert(ob->type == OB_CURVES_LEGACY);
@@ -2993,18 +3002,6 @@ GPUBatch *DRW_cache_lattice_vert_overlay_get(Object *ob)
/** \name PointCloud
* \{ */
-GPUBatch *DRW_cache_pointcloud_get_dots(Object *object)
-{
- BLI_assert(object->type == OB_POINTCLOUD);
- return DRW_pointcloud_batch_cache_get_dots(object);
-}
-
-GPUBatch *DRW_cache_pointcloud_surface_get(Object *object)
-{
- BLI_assert(object->type == OB_POINTCLOUD);
- return DRW_pointcloud_batch_cache_get_surface(object);
-}
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -3289,6 +3286,9 @@ void drw_batch_cache_generate_requested(Object *ob)
case OB_CURVES:
DRW_curves_batch_cache_create_requested(ob);
break;
+ case OB_POINTCLOUD:
+ DRW_pointcloud_batch_cache_create_requested(ob);
+ break;
/* TODO: all cases. */
default:
break;
@@ -3339,7 +3339,9 @@ void DRW_batch_cache_free_old(Object *ob, int ctime)
case OB_CURVES:
DRW_curves_batch_cache_free_old((Curves *)ob->data, ctime);
break;
- /* TODO: all cases. */
+ case OB_POINTCLOUD:
+ DRW_pointcloud_batch_cache_free_old((PointCloud *)ob->data, ctime);
+ break;
default:
break;
}
@@ -3369,7 +3371,7 @@ void DRW_cdlayer_attr_aliases_add(GPUVertFormat *format,
/* Active render layer name. */
if (is_active_render) {
- GPU_vertformat_alias_add(format, base_name);
+ GPU_vertformat_alias_add(format, cl->type == CD_MLOOPUV ? "a" : base_name);
}
/* Active display layer name. */
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index 4e8788ada08..772cf3b12a5 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -13,6 +13,7 @@ extern "C" {
struct GPUBatch;
struct GPUMaterial;
+struct GPUVertBuf;
struct ModifierData;
struct Object;
struct PTCacheEdit;
@@ -170,10 +171,12 @@ struct GPUBatch *DRW_cache_mesh_surface_sculptcolors_get(struct Object *ob);
struct GPUBatch *DRW_cache_mesh_surface_weights_get(struct Object *ob);
struct GPUBatch *DRW_cache_mesh_surface_mesh_analysis_get(struct Object *ob);
struct GPUBatch *DRW_cache_mesh_face_wireframe_get(struct Object *ob);
+struct GPUBatch *DRW_cache_mesh_surface_viewer_attribute_get(struct Object *ob);
/* Curve */
struct GPUBatch *DRW_cache_curve_edge_wire_get(struct Object *ob);
+struct GPUBatch *DRW_cache_curve_edge_wire_viewer_attribute_get(struct Object *ob);
/* edit-mode */
@@ -222,11 +225,6 @@ struct GPUBatch **DRW_cache_curves_surface_shaded_get(struct Object *ob,
struct GPUBatch *DRW_cache_curves_face_wireframe_get(struct Object *ob);
struct GPUBatch *DRW_cache_curves_edge_detection_get(struct Object *ob, bool *r_is_manifold);
-/* PointCloud */
-
-struct GPUBatch *DRW_cache_pointcloud_get_dots(struct Object *obj);
-struct GPUBatch *DRW_cache_pointcloud_surface_get(struct Object *obj);
-
/* Volume */
typedef struct DRWVolumeGrid {
@@ -254,14 +252,17 @@ struct GPUBatch *DRW_cache_volume_selection_surface_get(struct Object *ob);
/* GPencil */
-struct GPUBatch *DRW_cache_gpencil_strokes_get(struct Object *ob, int cfra);
-struct GPUBatch *DRW_cache_gpencil_fills_get(struct Object *ob, int cfra);
+struct GPUBatch *DRW_cache_gpencil_get(struct Object *ob, int cfra);
+struct GPUVertBuf *DRW_cache_gpencil_position_buffer_get(struct Object *ob, int cfra);
+struct GPUVertBuf *DRW_cache_gpencil_color_buffer_get(struct Object *ob, int cfra);
struct GPUBatch *DRW_cache_gpencil_edit_lines_get(struct Object *ob, int cfra);
struct GPUBatch *DRW_cache_gpencil_edit_points_get(struct Object *ob, int cfra);
struct GPUBatch *DRW_cache_gpencil_edit_curve_handles_get(struct Object *ob, int cfra);
struct GPUBatch *DRW_cache_gpencil_edit_curve_points_get(struct Object *ob, int cfra);
-struct GPUBatch *DRW_cache_gpencil_sbuffer_stroke_get(struct Object *ob);
-struct GPUBatch *DRW_cache_gpencil_sbuffer_fill_get(struct Object *ob);
+struct GPUBatch *DRW_cache_gpencil_sbuffer_get(struct Object *ob, bool show_fill);
+struct GPUVertBuf *DRW_cache_gpencil_sbuffer_position_buffer_get(struct Object *ob,
+ bool show_fill);
+struct GPUVertBuf *DRW_cache_gpencil_sbuffer_color_buffer_get(struct Object *ob, bool show_fill);
int DRW_gpencil_material_count_get(struct bGPdata *gpd);
struct GPUBatch *DRW_cache_gpencil_face_wireframe_get(struct Object *ob);
diff --git a/source/blender/draw/intern/draw_cache_extract.hh b/source/blender/draw/intern/draw_cache_extract.hh
index 203da22406c..4fe360eecd7 100644
--- a/source/blender/draw/intern/draw_cache_extract.hh
+++ b/source/blender/draw/intern/draw_cache_extract.hh
@@ -52,22 +52,6 @@ enum {
DRW_MESH_WEIGHT_STATE_LOCK_RELATIVE = (1 << 2),
};
-struct DRW_MeshCDMask {
- uint32_t uv : 8;
- uint32_t tan : 8;
- uint32_t orco : 1;
- uint32_t tan_orco : 1;
- uint32_t sculpt_overlays : 1;
- /**
- * Edit uv layer is from the base edit mesh as modifiers could remove it. (see T68857)
- */
- uint32_t edit_uv : 1;
-};
-/* Keep `DRW_MeshCDMask` struct within a `uint32_t`.
- * bit-wise and atomic operations are used to compare and update the struct.
- * See `mesh_cd_layers_type_*` functions. */
-BLI_STATIC_ASSERT(sizeof(DRW_MeshCDMask) <= sizeof(uint32_t), "DRW_MeshCDMask exceeds 32 bits")
-
enum eMRIterType {
MR_ITER_LOOPTRI = 1 << 0,
MR_ITER_POLY = 1 << 1,
@@ -130,6 +114,7 @@ struct MeshBufferList {
GPUVertBuf *poly_idx;
GPUVertBuf *fdot_idx;
GPUVertBuf *attr[GPU_MAX_ATTR];
+ GPUVertBuf *attr_viewer;
} vbo;
/* Index Buffers:
* Only need to be updated when topology changes. */
@@ -191,6 +176,7 @@ struct MeshBatchList {
/* Same as wire_loops but only has uvs. */
GPUBatch *wire_loops_uvs;
GPUBatch *sculpt_overlays;
+ GPUBatch *surface_viewer_attribute;
};
#define MBC_BATCH_LEN (sizeof(MeshBatchList) / sizeof(void *))
@@ -228,6 +214,7 @@ enum DRWBatchFlag {
MBC_WIRE_LOOPS = (1u << MBC_BATCH_INDEX(wire_loops)),
MBC_WIRE_LOOPS_UVS = (1u << MBC_BATCH_INDEX(wire_loops_uvs)),
MBC_SCULPT_OVERLAYS = (1u << MBC_BATCH_INDEX(sculpt_overlays)),
+ MBC_VIEWER_ATTRIBUTE_OVERLAY = (1u << MBC_BATCH_INDEX(surface_viewer_attribute)),
MBC_SURFACE_PER_MAT = (1u << MBC_BATCH_LEN),
};
ENUM_OPERATORS(DRWBatchFlag, MBC_SURFACE_PER_MAT);
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc
index b1d1631cb6d..f533904f355 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.cc
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc
@@ -110,7 +110,7 @@ class ExtractorRunDatas : public Vector<ExtractorRunData> {
uint iter_types_len() const
{
const eMRIterType iter_type = iter_types();
- uint bits = static_cast<uint>(iter_type);
+ uint bits = uint(iter_type);
return count_bits_i(bits);
}
@@ -204,7 +204,7 @@ BLI_INLINE void extract_init(const MeshRenderData *mr,
run_data.buffer = mesh_extract_buffer_get(extractor, mbuflist);
run_data.data_offset = data_offset;
extractor->init(mr, cache, run_data.buffer, POINTER_OFFSET(data_stack, data_offset));
- data_offset += (uint32_t)extractor->data_size;
+ data_offset += uint32_t(extractor->data_size);
}
}
@@ -640,6 +640,7 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
for (int i = 0; i < GPU_MAX_ATTR; i++) {
EXTRACT_ADD_REQUESTED(vbo, attr[i]);
}
+ EXTRACT_ADD_REQUESTED(vbo, attr_viewer);
EXTRACT_ADD_REQUESTED(ibo, tris);
if (DRW_ibo_requested(mbuflist->ibo.lines_loose)) {
@@ -685,7 +686,7 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
MeshRenderData *mr = mesh_render_data_create(
object, me, is_editmode, is_paint_mode, is_mode_active, obmat, do_final, do_uvedit, ts);
mr->use_hide = use_hide;
- mr->use_subsurf_fdots = mr->me && mr->me->runtime.subsurf_face_dot_tags != nullptr;
+ mr->use_subsurf_fdots = mr->me && mr->me->runtime->subsurf_face_dot_tags != nullptr;
mr->use_final_mesh = do_final;
#ifdef DEBUG_TIME
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
index eea19cbebf3..f606701ed09 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
+++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
@@ -18,6 +18,7 @@
#include "BKE_editmesh.h"
#include "BKE_editmesh_cache.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "GPU_batch.h"
@@ -329,28 +330,10 @@ void mesh_render_data_update_looptris(MeshRenderData *mr,
const eMRIterType iter_type,
const eMRDataType data_flag)
{
- Mesh *me = mr->me;
if (mr->extract_type != MR_EXTRACT_BMESH) {
/* Mesh */
if ((iter_type & MR_ITER_LOOPTRI) || (data_flag & MR_DATA_LOOPTRI)) {
- /* NOTE(@campbellbarton): It's possible to skip allocating tessellation,
- * the tessellation can be calculated as part of the iterator, see: P2188.
- * The overall advantage is small (around 1%), so keep this as-is. */
- mr->mlooptri = static_cast<MLoopTri *>(
- MEM_mallocN(sizeof(*mr->mlooptri) * mr->tri_len, "MR_DATATYPE_LOOPTRI"));
- if (mr->poly_normals != nullptr) {
- BKE_mesh_recalc_looptri_with_normals(mr->mloop,
- mr->mpoly,
- mr->mvert,
- me->totloop,
- me->totpoly,
- mr->mlooptri,
- mr->poly_normals);
- }
- else {
- BKE_mesh_recalc_looptri(
- mr->mloop, mr->mpoly, mr->mvert, me->totloop, me->totpoly, mr->mlooptri);
- }
+ mr->mlooptri = BKE_mesh_runtime_looptri_ensure(mr->me);
}
}
else {
@@ -366,7 +349,7 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_
{
Mesh *me = mr->me;
const bool is_auto_smooth = (me->flag & ME_AUTOSMOOTH) != 0;
- const float split_angle = is_auto_smooth ? me->smoothresh : (float)M_PI;
+ const float split_angle = is_auto_smooth ? me->smoothresh : float(M_PI);
if (mr->extract_type != MR_EXTRACT_BMESH) {
/* Mesh */
@@ -480,7 +463,7 @@ MeshRenderData *mesh_render_data_create(Object *object,
mr->bm = me->edit_mesh->bm;
mr->edit_bmesh = me->edit_mesh;
mr->me = (do_final) ? editmesh_eval_final : editmesh_eval_cage;
- mr->edit_data = is_mode_active ? mr->me->runtime.edit_data : nullptr;
+ mr->edit_data = is_mode_active ? mr->me->runtime->edit_data : nullptr;
if (mr->edit_data) {
EditMeshData *emd = mr->edit_data;
@@ -516,8 +499,8 @@ MeshRenderData *mesh_render_data_create(Object *object,
/* Use bmesh directly when the object is in edit mode unchanged by any modifiers.
* For non-final UVs, always use original bmesh since the UV editor does not support
* using the cage mesh with deformed coordinates. */
- if ((is_mode_active && mr->me->runtime.is_original_bmesh &&
- mr->me->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) ||
+ if ((is_mode_active && mr->me->runtime->is_original_bmesh &&
+ mr->me->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) ||
(do_uvedit && !do_final)) {
mr->extract_type = MR_EXTRACT_BMESH;
}
@@ -586,6 +569,13 @@ MeshRenderData *mesh_render_data_create(Object *object,
CustomData_get_layer_named(&me->edata, CD_PROP_BOOL, ".hide_edge"));
mr->hide_poly = static_cast<const bool *>(
CustomData_get_layer_named(&me->pdata, CD_PROP_BOOL, ".hide_poly"));
+
+ mr->select_vert = static_cast<const bool *>(
+ CustomData_get_layer_named(&me->vdata, CD_PROP_BOOL, ".select_vert"));
+ mr->select_edge = static_cast<const bool *>(
+ CustomData_get_layer_named(&me->edata, CD_PROP_BOOL, ".select_edge"));
+ mr->select_poly = static_cast<const bool *>(
+ CustomData_get_layer_named(&me->pdata, CD_PROP_BOOL, ".select_poly"));
}
else {
/* #BMesh */
@@ -605,7 +595,6 @@ MeshRenderData *mesh_render_data_create(Object *object,
void mesh_render_data_free(MeshRenderData *mr)
{
- MEM_SAFE_FREE(mr->mlooptri);
MEM_SAFE_FREE(mr->loop_normals);
/* Loose geometry are owned by #MeshBufferCache. */
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 7f7d0a7613f..5aa2203ca68 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -80,6 +80,7 @@ void DRW_batch_cache_free_old(struct Object *ob, int ctime);
*/
void DRW_mesh_batch_cache_free_old(struct Mesh *me, int ctime);
void DRW_curves_batch_cache_free_old(struct Curves *curves, int ctime);
+void DRW_pointcloud_batch_cache_free_old(struct PointCloud *pointcloud, int ctime);
/** \} */
@@ -100,6 +101,7 @@ void DRW_curve_batch_cache_create_requested(struct Object *ob, const struct Scen
int DRW_curve_material_count_get(struct Curve *cu);
struct GPUBatch *DRW_curve_batch_cache_get_wire_edge(struct Curve *cu);
+struct GPUBatch *DRW_curve_batch_cache_get_wire_edge_viewer_attribute(struct Curve *cu);
struct GPUBatch *DRW_curve_batch_cache_get_normal_edge(struct Curve *cu);
struct GPUBatch *DRW_curve_batch_cache_get_edit_edges(struct Curve *cu);
struct GPUBatch *DRW_curve_batch_cache_get_edit_verts(struct Curve *cu);
@@ -130,7 +132,7 @@ int DRW_curves_material_count_get(struct Curves *curves);
* \return A pointer to location where the texture will be
* stored, which will be filled by #DRW_shgroup_curves_create_sub.
*/
-struct GPUTexture **DRW_curves_texture_for_evaluated_attribute(struct Curves *curves,
+struct GPUVertBuf **DRW_curves_texture_for_evaluated_attribute(struct Curves *curves,
const char *name,
bool *r_is_point_domain);
@@ -146,11 +148,11 @@ void DRW_curves_batch_cache_create_requested(struct Object *ob);
int DRW_pointcloud_material_count_get(struct PointCloud *pointcloud);
+struct GPUVertBuf **DRW_pointcloud_evaluated_attribute(struct PointCloud *pointcloud,
+ const char *name);
struct GPUBatch *DRW_pointcloud_batch_cache_get_dots(struct Object *ob);
-struct GPUBatch *DRW_pointcloud_batch_cache_get_surface(struct Object *ob);
-struct GPUBatch **DRW_cache_pointcloud_surface_shaded_get(struct Object *ob,
- struct GPUMaterial **gpumat_array,
- uint gpumat_array_len);
+
+void DRW_pointcloud_batch_cache_create_requested(struct Object *ob);
/** \} */
@@ -189,6 +191,7 @@ struct GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(struct Object *object,
struct Mesh *me,
struct GPUMaterial **gpumat_array,
uint gpumat_array_len);
+
struct GPUBatch **DRW_mesh_batch_cache_get_surface_texpaint(struct Object *object,
struct Mesh *me);
struct GPUBatch *DRW_mesh_batch_cache_get_surface_texpaint_single(struct Object *object,
@@ -198,6 +201,7 @@ struct GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(struct Object *objec
struct GPUBatch *DRW_mesh_batch_cache_get_surface_sculpt(struct Object *object, struct Mesh *me);
struct GPUBatch *DRW_mesh_batch_cache_get_surface_weights(struct Mesh *me);
struct GPUBatch *DRW_mesh_batch_cache_get_sculpt_overlays(struct Mesh *me);
+struct GPUBatch *DRW_mesh_batch_cache_get_surface_viewer_attribute(struct Mesh *me);
/** \} */
@@ -275,8 +279,6 @@ struct GPUVertBuf *DRW_mesh_batch_cache_pos_vertbuf_get(struct Mesh *me);
int DRW_mesh_material_count_get(const struct Object *object, const struct Mesh *me);
-/* See 'common_globals_lib.glsl' for duplicate defines. */
-
/* Edit mesh bitflags (is this the right place?) */
enum {
VFLAG_VERT_ACTIVE = 1 << 0,
diff --git a/source/blender/draw/intern/draw_cache_impl_curve.cc b/source/blender/draw/intern/draw_cache_impl_curve.cc
index 695c348d8e2..6188b1e0544 100644
--- a/source/blender/draw/intern/draw_cache_impl_curve.cc
+++ b/source/blender/draw/intern/draw_cache_impl_curve.cc
@@ -10,6 +10,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_array.hh"
+#include "BLI_color.hh"
#include "BLI_listbase.h"
#include "BLI_math_vec_types.hh"
#include "BLI_math_vector.h"
@@ -38,6 +39,7 @@
#include "draw_cache_impl.h" /* own include */
using blender::Array;
+using blender::ColorGeometry4f;
using blender::float3;
using blender::IndexRange;
using blender::Span;
@@ -296,6 +298,7 @@ static int curve_render_data_normal_len_get(const CurveRenderData *rdata)
struct CurveBatchCache {
struct {
GPUVertBuf *curves_pos;
+ GPUVertBuf *attr_viewer;
} ordered;
struct {
@@ -314,6 +317,7 @@ struct CurveBatchCache {
struct {
GPUBatch *curves;
+ GPUBatch *curves_viewer_attribute;
/* control handles and vertices */
GPUBatch *edit_edges;
GPUBatch *edit_verts;
@@ -474,6 +478,31 @@ static void curve_create_curves_pos(CurveRenderData *rdata, GPUVertBuf *vbo_curv
GPU_vertbuf_attr_fill(vbo_curves_pos, attr_id.pos, positions.data());
}
+static void curve_create_attribute(CurveRenderData *rdata, GPUVertBuf *vbo_attr)
+{
+ if (rdata->curve_eval == nullptr) {
+ return;
+ }
+
+ static GPUVertFormat format = {0};
+ if (format.attr_len == 0) {
+ GPU_vertformat_attr_add(&format, "attribute_value", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ }
+
+ const int vert_len = curve_render_data_wire_verts_len_get(rdata);
+ GPU_vertbuf_init_with_format(vbo_attr, &format);
+ GPU_vertbuf_data_alloc(vbo_attr, vert_len);
+
+ const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap(
+ rdata->curve_eval->geometry);
+ curves.ensure_can_interpolate_to_evaluated();
+ const blender::VArraySpan<ColorGeometry4f> colors = curves.attributes().lookup<ColorGeometry4f>(
+ ".viewer", ATTR_DOMAIN_POINT);
+ ColorGeometry4f *vbo_data = static_cast<ColorGeometry4f *>(GPU_vertbuf_get_data(vbo_attr));
+ curves.interpolate_to_evaluated(colors,
+ blender::MutableSpan<ColorGeometry4f>{vbo_data, vert_len});
+}
+
static void curve_create_curves_lines(CurveRenderData *rdata, GPUIndexBuf *ibo_curve_lines)
{
if (rdata->curve_eval == nullptr) {
@@ -769,6 +798,12 @@ GPUBatch *DRW_curve_batch_cache_get_wire_edge(Curve *cu)
return DRW_batch_request(&cache->batch.curves);
}
+GPUBatch *DRW_curve_batch_cache_get_wire_edge_viewer_attribute(Curve *cu)
+{
+ CurveBatchCache *cache = curve_batch_cache_get(cu);
+ return DRW_batch_request(&cache->batch.curves_viewer_attribute);
+}
+
GPUBatch *DRW_curve_batch_cache_get_normal_edge(Curve *cu)
{
CurveBatchCache *cache = curve_batch_cache_get(cu);
@@ -810,6 +845,11 @@ void DRW_curve_batch_cache_create_requested(Object *ob, const struct Scene *scen
DRW_ibo_request(cache->batch.curves, &cache->ibo.curves_lines);
DRW_vbo_request(cache->batch.curves, &cache->ordered.curves_pos);
}
+ if (DRW_batch_requested(cache->batch.curves_viewer_attribute, GPU_PRIM_LINE_STRIP)) {
+ DRW_ibo_request(cache->batch.curves_viewer_attribute, &cache->ibo.curves_lines);
+ DRW_vbo_request(cache->batch.curves_viewer_attribute, &cache->ordered.curves_pos);
+ DRW_vbo_request(cache->batch.curves_viewer_attribute, &cache->ordered.attr_viewer);
+ }
/* Edit mode */
if (DRW_batch_requested(cache->batch.edit_edges, GPU_PRIM_LINES)) {
@@ -833,6 +873,8 @@ void DRW_curve_batch_cache_create_requested(Object *ob, const struct Scene *scen
/* Generate MeshRenderData flags */
int mr_flag = 0;
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.curves_pos, CU_DATATYPE_WIRE);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(
+ mr_flag, cache->ordered.attr_viewer, CU_DATATYPE_WIRE | CU_DATATYPE_OVERLAY);
DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.curves_lines, CU_DATATYPE_WIRE);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->edit.pos, CU_DATATYPE_OVERLAY);
@@ -851,6 +893,9 @@ void DRW_curve_batch_cache_create_requested(Object *ob, const struct Scene *scen
if (DRW_vbo_requested(cache->ordered.curves_pos)) {
curve_create_curves_pos(rdata, cache->ordered.curves_pos);
}
+ if (DRW_vbo_requested(cache->ordered.attr_viewer)) {
+ curve_create_attribute(rdata, cache->ordered.attr_viewer);
+ }
if (DRW_ibo_requested(cache->ibo.curves_lines)) {
curve_create_curves_lines(rdata, cache->ibo.curves_lines);
}
diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc
index 3bca17d9c56..0322d048fa5 100644
--- a/source/blender/draw/intern/draw_cache_impl_curves.cc
+++ b/source/blender/draw/intern/draw_cache_impl_curves.cc
@@ -14,9 +14,9 @@
#include "BLI_listbase.h"
#include "BLI_math_base.h"
#include "BLI_math_vec_types.hh"
-#include "BLI_math_vector.h"
#include "BLI_math_vector.hh"
#include "BLI_span.hh"
+#include "BLI_task.hh"
#include "BLI_utildefines.h"
#include "DNA_curves_types.h"
@@ -60,7 +60,7 @@ struct CurvesBatchCache {
* some locking would be necessary because multiple objects can use the same curves data with
* different materials, etc. This is a placeholder to make multi-threading easier in the future.
*/
- ThreadMutex render_mutex;
+ std::mutex render_mutex;
};
static bool curves_batch_cache_valid(const Curves &curves)
@@ -74,15 +74,13 @@ static void curves_batch_cache_init(Curves &curves)
CurvesBatchCache *cache = static_cast<CurvesBatchCache *>(curves.batch_cache);
if (!cache) {
- cache = MEM_cnew<CurvesBatchCache>(__func__);
+ cache = MEM_new<CurvesBatchCache>(__func__);
curves.batch_cache = cache;
}
else {
- memset(cache, 0, sizeof(*cache));
+ cache->curves_cache = {};
}
- BLI_mutex_init(&cache->render_mutex);
-
cache->is_dirty = false;
}
@@ -90,13 +88,11 @@ static void curves_discard_attributes(CurvesEvalCache &curves_cache)
{
for (const int i : IndexRange(GPU_MAX_ATTR)) {
GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_attributes_buf[i]);
- DRW_TEXTURE_FREE_SAFE(curves_cache.proc_attributes_tex[i]);
}
for (const int i : IndexRange(MAX_HAIR_SUBDIV)) {
for (const int j : IndexRange(GPU_MAX_ATTR)) {
GPU_VERTBUF_DISCARD_SAFE(curves_cache.final[i].attributes_buf[j]);
- DRW_TEXTURE_FREE_SAFE(curves_cache.final[i].attributes_tex[j]);
}
drw_attributes_clear(&curves_cache.final[i].attr_used);
@@ -108,17 +104,13 @@ static void curves_batch_cache_clear_data(CurvesEvalCache &curves_cache)
/* TODO: more granular update tagging. */
GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_point_buf);
GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_length_buf);
- DRW_TEXTURE_FREE_SAFE(curves_cache.point_tex);
- DRW_TEXTURE_FREE_SAFE(curves_cache.length_tex);
+ GPU_VERTBUF_DISCARD_SAFE(curves_cache.data_edit_points);
GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_strand_buf);
GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_strand_seg_buf);
- DRW_TEXTURE_FREE_SAFE(curves_cache.strand_tex);
- DRW_TEXTURE_FREE_SAFE(curves_cache.strand_seg_tex);
for (const int i : IndexRange(MAX_HAIR_SUBDIV)) {
GPU_VERTBUF_DISCARD_SAFE(curves_cache.final[i].proc_buf);
- DRW_TEXTURE_FREE_SAFE(curves_cache.final[i].proc_tex);
for (const int j : IndexRange(MAX_THICKRES)) {
GPU_BATCH_DISCARD_SAFE(curves_cache.final[i].proc_hairs[j]);
}
@@ -171,9 +163,8 @@ void DRW_curves_batch_cache_dirty_tag(Curves *curves, int mode)
void DRW_curves_batch_cache_free(Curves *curves)
{
curves_batch_cache_clear(*curves);
- CurvesBatchCache *cache = static_cast<CurvesBatchCache *>(curves->batch_cache);
- BLI_mutex_end(&cache->render_mutex);
- MEM_SAFE_FREE(curves->batch_cache);
+ MEM_delete(static_cast<CurvesBatchCache *>(curves->batch_cache));
+ curves->batch_cache = nullptr;
}
void DRW_curves_batch_cache_free_old(Curves *curves, int ctime)
@@ -225,43 +216,43 @@ static void curves_batch_cache_fill_segments_proc_pos(
MutableSpan<PositionAndParameter> posTime_data,
MutableSpan<float> hairLength_data)
{
+ using namespace blender;
/* TODO: use hair radius layer if available. */
- const int curve_num = curves_id.geometry.curve_num;
- const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap(
- curves_id.geometry);
- Span<float3> positions = curves.positions();
+ const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
+ const Span<float3> positions = curves.positions();
- for (const int i_curve : IndexRange(curve_num)) {
- const IndexRange points = curves.points_for_curve(i_curve);
+ threading::parallel_for(curves.curves_range(), 1024, [&](const IndexRange range) {
+ for (const int i_curve : range) {
+ const IndexRange points = curves.points_for_curve(i_curve);
- Span<float3> curve_positions = positions.slice(points);
- MutableSpan<PositionAndParameter> curve_posTime_data = posTime_data.slice(points);
+ Span<float3> curve_positions = positions.slice(points);
+ MutableSpan<PositionAndParameter> curve_posTime_data = posTime_data.slice(points);
- float total_len = 0.0f;
- for (const int i_point : curve_positions.index_range()) {
- if (i_point > 0) {
- total_len += blender::math::distance(curve_positions[i_point - 1],
- curve_positions[i_point]);
- }
- curve_posTime_data[i_point].position = curve_positions[i_point];
- curve_posTime_data[i_point].parameter = total_len;
- }
- hairLength_data[i_curve] = total_len;
-
- /* Assign length value. */
- if (total_len > 0.0f) {
- const float factor = 1.0f / total_len;
- /* Divide by total length to have a [0-1] number. */
+ float total_len = 0.0f;
for (const int i_point : curve_positions.index_range()) {
- curve_posTime_data[i_point].parameter *= factor;
+ if (i_point > 0) {
+ total_len += math::distance(curve_positions[i_point - 1], curve_positions[i_point]);
+ }
+ curve_posTime_data[i_point].position = curve_positions[i_point];
+ curve_posTime_data[i_point].parameter = total_len;
+ }
+ hairLength_data[i_curve] = total_len;
+
+ /* Assign length value. */
+ if (total_len > 0.0f) {
+ const float factor = 1.0f / total_len;
+ /* Divide by total length to have a [0-1] number. */
+ for (const int i_point : curve_positions.index_range()) {
+ curve_posTime_data[i_point].parameter *= factor;
+ }
}
}
- }
+ });
}
static void curves_batch_cache_ensure_procedural_pos(const Curves &curves,
CurvesEvalCache &cache,
- GPUMaterial *gpu_material)
+ GPUMaterial *UNUSED(gpu_material))
{
if (cache.proc_point_buf == nullptr || DRW_vbo_requested(cache.proc_point_buf)) {
/* Initialize vertex format. */
@@ -274,7 +265,7 @@ static void curves_batch_cache_ensure_procedural_pos(const Curves &curves,
GPU_vertbuf_data_alloc(cache.proc_point_buf, cache.point_len);
MutableSpan posTime_data{
- reinterpret_cast<PositionAndParameter *>(GPU_vertbuf_get_data(cache.proc_point_buf)),
+ static_cast<PositionAndParameter *>(GPU_vertbuf_get_data(cache.proc_point_buf)),
cache.point_len};
GPUVertFormat length_format = {0};
@@ -284,25 +275,47 @@ static void curves_batch_cache_ensure_procedural_pos(const Curves &curves,
&length_format, GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY);
GPU_vertbuf_data_alloc(cache.proc_length_buf, cache.strands_len);
- MutableSpan hairLength_data{
- reinterpret_cast<float *>(GPU_vertbuf_get_data(cache.proc_length_buf)), cache.strands_len};
+ MutableSpan hairLength_data{static_cast<float *>(GPU_vertbuf_get_data(cache.proc_length_buf)),
+ cache.strands_len};
curves_batch_cache_fill_segments_proc_pos(curves, posTime_data, hairLength_data);
-
- /* Create vbo immediately to bind to texture buffer. */
- GPU_vertbuf_use(cache.proc_point_buf);
- cache.point_tex = GPU_texture_create_from_vertbuf("hair_point", cache.proc_point_buf);
}
+}
- if (gpu_material && cache.proc_length_buf != nullptr && cache.length_tex) {
- ListBase gpu_attrs = GPU_material_attributes(gpu_material);
- LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &gpu_attrs) {
- if (attr->type == CD_HAIRLENGTH) {
- GPU_vertbuf_use(cache.proc_length_buf);
- cache.length_tex = GPU_texture_create_from_vertbuf("hair_length", cache.proc_length_buf);
- break;
+static void curves_batch_cache_ensure_data_edit_points(const Curves &curves_id,
+ CurvesEvalCache &cache)
+{
+ using namespace blender;
+ const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
+
+ static GPUVertFormat format_data = {0};
+ uint data = GPU_vertformat_attr_add(&format_data, "data", GPU_COMP_U8, 1, GPU_FETCH_INT);
+ GPU_vertbuf_init_with_format(cache.data_edit_points, &format_data);
+ GPU_vertbuf_data_alloc(cache.data_edit_points, curves.points_num());
+
+ VArray<float> selection;
+ switch (curves_id.selection_domain) {
+ case ATTR_DOMAIN_POINT:
+ selection = curves.selection_point_float();
+ for (const int point_i : selection.index_range()) {
+ uint8_t vflag = 0;
+ const float point_selection = selection[point_i];
+ SET_FLAG_FROM_TEST(vflag, (point_selection > 0.0f), VFLAG_VERT_SELECTED);
+ GPU_vertbuf_attr_set(cache.data_edit_points, data, point_i, &vflag);
}
- }
+ break;
+ case ATTR_DOMAIN_CURVE:
+ selection = curves.selection_curve_float();
+ for (const int curve_i : curves.curves_range()) {
+ uint8_t vflag = 0;
+ const float curve_selection = selection[curve_i];
+ SET_FLAG_FROM_TEST(vflag, (curve_selection > 0.0f), VFLAG_VERT_SELECTED);
+ const IndexRange points = curves.points_for_curve(curve_i);
+ for (const int point_i : points) {
+ GPU_vertbuf_attr_set(cache.data_edit_points, data, point_i, &vflag);
+ }
+ }
+ break;
}
}
@@ -318,7 +331,7 @@ static void curves_batch_cache_ensure_procedural_final_attr(CurvesEvalCache &cac
const GPUVertFormat *format,
const int subdiv,
const int index,
- const char *name)
+ const char *UNUSED(name))
{
CurvesEvalFinalCache &final_cache = cache.final[subdiv];
final_cache.attributes_buf[index] = GPU_vertbuf_create_with_format_ex(
@@ -328,12 +341,6 @@ static void curves_batch_cache_ensure_procedural_final_attr(CurvesEvalCache &cac
/* Those are points! not line segments. */
GPU_vertbuf_data_alloc(final_cache.attributes_buf[index],
final_cache.strands_res * cache.strands_len);
-
- /* Create vbo immediately to bind to texture buffer. */
- GPU_vertbuf_use(final_cache.attributes_buf[index]);
-
- final_cache.attributes_tex[index] = GPU_texture_create_from_vertbuf(
- name, final_cache.attributes_buf[index]);
}
static void curves_batch_ensure_attribute(const Curves &curves,
@@ -342,8 +349,8 @@ static void curves_batch_ensure_attribute(const Curves &curves,
const int subdiv,
const int index)
{
+ using namespace blender;
GPU_VERTBUF_DISCARD_SAFE(cache.proc_attributes_buf[index]);
- DRW_TEXTURE_FREE_SAFE(cache.proc_attributes_tex[index]);
char sampler_name[32];
drw_curves_get_attribute_sampler_name(request.attribute_name, sampler_name);
@@ -361,15 +368,15 @@ static void curves_batch_ensure_attribute(const Curves &curves,
request.domain == ATTR_DOMAIN_POINT ? curves.geometry.point_num :
curves.geometry.curve_num);
- const blender::bke::AttributeAccessor attributes =
- blender::bke::CurvesGeometry::wrap(curves.geometry).attributes();
+ const bke::AttributeAccessor attributes =
+ bke::CurvesGeometry::wrap(curves.geometry).attributes();
/* TODO(@kevindietrich): float4 is used for scalar attributes as the implicit conversion done
* by OpenGL to vec4 for a scalar `s` will produce a `vec4(s, 0, 0, 1)`. However, following
* the Blender convention, it should be `vec4(s, s, s, 1)`. This could be resolved using a
* similar texture state swizzle to map the attribute correctly as for volume attributes, so we
* can control the conversion ourselves. */
- blender::VArray<ColorGeometry4f> attribute = attributes.lookup_or_default<ColorGeometry4f>(
+ VArray<ColorGeometry4f> attribute = attributes.lookup_or_default<ColorGeometry4f>(
request.attribute_name, request.domain, {0.0f, 0.0f, 0.0f, 1.0f});
MutableSpan<ColorGeometry4f> vbo_span{
@@ -378,13 +385,9 @@ static void curves_batch_ensure_attribute(const Curves &curves,
attribute.materialize(vbo_span);
- GPU_vertbuf_use(attr_vbo);
- cache.proc_attributes_tex[index] = GPU_texture_create_from_vertbuf(sampler_name, attr_vbo);
-
/* Existing final data may have been for a different attribute (with a different name or domain),
* free the data. */
GPU_VERTBUF_DISCARD_SAFE(cache.final[subdiv].attributes_buf[index]);
- DRW_TEXTURE_FREE_SAFE(cache.final[subdiv].attributes_tex[index]);
/* Ensure final data for points. */
if (request.domain == ATTR_DOMAIN_POINT) {
@@ -430,19 +433,11 @@ static void curves_batch_cache_ensure_procedural_strand_data(Curves &curves,
GPU_vertbuf_attr_get_raw_data(cache.proc_strand_seg_buf, seg_id, &seg_step);
curves_batch_cache_fill_strands_data(curves, data_step, seg_step);
-
- /* Create vbo immediately to bind to texture buffer. */
- GPU_vertbuf_use(cache.proc_strand_buf);
- cache.strand_tex = GPU_texture_create_from_vertbuf("curves_strand", cache.proc_strand_buf);
-
- GPU_vertbuf_use(cache.proc_strand_seg_buf);
- cache.strand_seg_tex = GPU_texture_create_from_vertbuf("curves_strand_seg",
- cache.proc_strand_seg_buf);
}
static void curves_batch_cache_ensure_procedural_final_points(CurvesEvalCache &cache, int subdiv)
{
- /* Same format as point_tex. */
+ /* Same format as proc_point_buf. */
GPUVertFormat format = {0};
GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
@@ -453,12 +448,6 @@ static void curves_batch_cache_ensure_procedural_final_points(CurvesEvalCache &c
/* Those are points! not line segments. */
GPU_vertbuf_data_alloc(cache.final[subdiv].proc_buf,
cache.final[subdiv].strands_res * cache.strands_len);
-
- /* Create vbo immediately to bind to texture buffer. */
- GPU_vertbuf_use(cache.final[subdiv].proc_buf);
-
- cache.final[subdiv].proc_tex = GPU_texture_create_from_vertbuf("hair_proc",
- cache.final[subdiv].proc_buf);
}
static void curves_batch_cache_fill_segments_indices(const Curves &curves,
@@ -516,7 +505,6 @@ static bool curves_ensure_attributes(const Curves &curves,
GPUMaterial *gpu_material,
int subdiv)
{
- ThreadMutex *render_mutex = &cache.render_mutex;
const CustomData *cd_curve = &curves.geometry.curve_data;
const CustomData *cd_point = &curves.geometry.point_data;
CurvesEvalFinalCache &final_cache = cache.curves_cache.final[subdiv];
@@ -548,11 +536,10 @@ static bool curves_ensure_attributes(const Curves &curves,
/* Some new attributes have been added, free all and start over. */
for (const int i : IndexRange(GPU_MAX_ATTR)) {
GPU_VERTBUF_DISCARD_SAFE(cache.curves_cache.proc_attributes_buf[i]);
- DRW_TEXTURE_FREE_SAFE(cache.curves_cache.proc_attributes_tex[i]);
}
- drw_attributes_merge(&final_cache.attr_used, &attrs_needed, render_mutex);
+ drw_attributes_merge(&final_cache.attr_used, &attrs_needed, cache.render_mutex);
}
- drw_attributes_merge(&final_cache.attr_used_over_time, &attrs_needed, render_mutex);
+ drw_attributes_merge(&final_cache.attr_used_over_time, &attrs_needed, cache.render_mutex);
}
bool need_tf_update = false;
@@ -596,7 +583,7 @@ bool curves_ensure_procedural_data(Curves *curves,
}
/* Refreshed if active layer or custom data changes. */
- if ((*r_hair_cache)->strand_tex == nullptr) {
+ if ((*r_hair_cache)->proc_strand_buf == nullptr) {
curves_batch_cache_ensure_procedural_strand_data(*curves, cache.curves_cache);
}
@@ -651,10 +638,10 @@ static void request_attribute(Curves &curves, const char *name)
drw_attributes_add_request(
&attributes, name, type, CustomData_get_named_layer(&custom_data, type, name), domain);
- drw_attributes_merge(&final_cache.attr_used, &attributes, &cache.render_mutex);
+ drw_attributes_merge(&final_cache.attr_used, &attributes, cache.render_mutex);
}
-GPUTexture **DRW_curves_texture_for_evaluated_attribute(Curves *curves,
+GPUVertBuf **DRW_curves_texture_for_evaluated_attribute(Curves *curves,
const char *name,
bool *r_is_point_domain)
{
@@ -680,10 +667,10 @@ GPUTexture **DRW_curves_texture_for_evaluated_attribute(Curves *curves,
switch (final_cache.attr_used.requests[request_i].domain) {
case ATTR_DOMAIN_POINT:
*r_is_point_domain = true;
- return &final_cache.attributes_tex[request_i];
+ return &final_cache.attributes_buf[request_i];
case ATTR_DOMAIN_CURVE:
*r_is_point_domain = false;
- return &cache.curves_cache.proc_attributes_tex[request_i];
+ return &cache.curves_cache.proc_attributes_buf[request_i];
default:
BLI_assert_unreachable();
return nullptr;
@@ -697,9 +684,14 @@ void DRW_curves_batch_cache_create_requested(Object *ob)
if (DRW_batch_requested(cache.edit_points, GPU_PRIM_POINTS)) {
DRW_vbo_request(cache.edit_points, &cache.curves_cache.proc_point_buf);
+ DRW_vbo_request(cache.edit_points, &cache.curves_cache.data_edit_points);
}
if (DRW_vbo_requested(cache.curves_cache.proc_point_buf)) {
curves_batch_cache_ensure_procedural_pos(*curves, cache.curves_cache, nullptr);
}
+
+ if (DRW_vbo_requested(cache.curves_cache.data_edit_points)) {
+ curves_batch_cache_ensure_data_edit_points(*curves, cache.curves_cache);
+ }
}
diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.c b/source/blender/draw/intern/draw_cache_impl_gpencil.cc
index aecf4b2f004..6860fae744b 100644
--- a/source/blender/draw/intern/draw_cache_impl_gpencil.c
+++ b/source/blender/draw/intern/draw_cache_impl_gpencil.cc
@@ -23,12 +23,14 @@
#include "DEG_depsgraph_query.h"
#include "BLI_hash.h"
+#include "BLI_math_vec_types.hh"
#include "BLI_polyfill_2d.h"
#include "draw_cache.h"
#include "draw_cache_impl.h"
#include "../engines/gpencil/gpencil_defines.h"
+#include "../engines/gpencil/gpencil_shader_shared.h"
#define BEZIER_HANDLE (1 << 3)
#define COLOR_SHIFT 5
@@ -41,11 +43,13 @@ typedef struct GpencilBatchCache {
/** Instancing Data */
GPUVertBuf *vbo;
GPUVertBuf *vbo_col;
- /** Fill Topology */
+ /** Indices in material order, then stroke order with fill first.
+ * Strokes can be individually rendered using `gps->runtime.stroke_start` and
+ * `gps->runtime.fill_start`. */
GPUIndexBuf *ibo;
- /** Instancing Batches */
- GPUBatch *stroke_batch;
- GPUBatch *fill_batch;
+ /** Batches */
+ GPUBatch *geom_batch;
+ /** Stroke lines only */
GPUBatch *lines_batch;
/** Edit Mode */
@@ -97,7 +101,8 @@ static GpencilBatchCache *gpencil_batch_cache_init(Object *ob, int cfra)
GpencilBatchCache *cache = gpd->runtime.gpencil_cache;
if (!cache) {
- cache = gpd->runtime.gpencil_cache = MEM_callocN(sizeof(*cache), __func__);
+ cache = gpd->runtime.gpencil_cache = (GpencilBatchCache *)MEM_callocN(sizeof(*cache),
+ __func__);
}
else {
memset(cache, 0, sizeof(*cache));
@@ -116,8 +121,7 @@ static void gpencil_batch_cache_clear(GpencilBatchCache *cache)
}
GPU_BATCH_DISCARD_SAFE(cache->lines_batch);
- GPU_BATCH_DISCARD_SAFE(cache->fill_batch);
- GPU_BATCH_DISCARD_SAFE(cache->stroke_batch);
+ GPU_BATCH_DISCARD_SAFE(cache->geom_batch);
GPU_VERTBUF_DISCARD_SAFE(cache->vbo);
GPU_VERTBUF_DISCARD_SAFE(cache->vbo_col);
GPU_INDEXBUF_DISCARD_SAFE(cache->ibo);
@@ -172,9 +176,10 @@ void DRW_gpencil_batch_cache_free(bGPdata *gpd)
/* MUST match the format below. */
typedef struct gpStrokeVert {
- int32_t mat, stroke_id, point_id, packed_asp_hard_rot;
/** Position and thickness packed in the same attribute. */
float pos[3], thickness;
+ /** Material Index, Stroke Index, Point Index, Packed aspect + hardness + rotation. */
+ int32_t mat, stroke_id, point_id, packed_asp_hard_rot;
/** UV and strength packed in the same attribute. */
float uv_fill[2], u_stroke, strength;
} gpStrokeVert;
@@ -183,12 +188,9 @@ static GPUVertFormat *gpencil_stroke_format(void)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
- GPU_vertformat_attr_add(&format, "ma", GPU_COMP_I32, 4, GPU_FETCH_INT);
GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ GPU_vertformat_attr_add(&format, "ma", GPU_COMP_I32, 4, GPU_FETCH_INT);
GPU_vertformat_attr_add(&format, "uv", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- /* IMPORTANT: This means having only 4 attributes
- * to fit into GPU module limit of 16 attributes. */
- GPU_vertformat_multiload_enable(&format, 4);
}
return &format;
}
@@ -238,9 +240,6 @@ static GPUVertFormat *gpencil_color_format(void)
if (format.attr_len == 0) {
GPU_vertformat_attr_add(&format, "col", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
GPU_vertformat_attr_add(&format, "fcol", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- /* IMPORTANT: This means having only 4 attributes
- * to fit into GPU module limit of 16 attributes. */
- GPU_vertformat_multiload_enable(&format, 4);
}
return &format;
}
@@ -295,7 +294,8 @@ BLI_INLINE int32_t pack_rotation_aspect_hardness(float rot, float asp, float har
return packed;
}
-static void gpencil_buffer_add_point(gpStrokeVert *verts,
+static void gpencil_buffer_add_point(GPUIndexBufBuilder *ibo,
+ gpStrokeVert *verts,
gpColorVert *cols,
const bGPDstroke *gps,
const bGPDspoint *pt,
@@ -315,11 +315,11 @@ static void gpencil_buffer_add_point(gpStrokeVert *verts,
/* Encode fill opacity defined by opacity modifier in vertex color alpha. If
* no opacity modifier, the value will be always 1.0f. The opacity factor can be any
* value between 0.0f and 2.0f */
- col->fcol[3] = (((int)(col->fcol[3] * 10000.0f)) * 10.0f) + gps->fill_opacity_fac;
+ col->fcol[3] = ((int)(col->fcol[3] * 10000.0f) * 10.0f) + gps->fill_opacity_fac;
vert->strength = (round_cap0) ? pt->strength : -pt->strength;
vert->u_stroke = pt->uv_fac;
- vert->stroke_id = gps->runtime.stroke_start;
+ vert->stroke_id = gps->runtime.vertex_start;
vert->point_id = v;
vert->thickness = max_ff(0.0f, gps->thickness * pt->pressure) * (round_cap1 ? 1.0f : -1.0f);
/* Tag endpoint material to -1 so they get discarded by vertex shader. */
@@ -329,27 +329,36 @@ static void gpencil_buffer_add_point(gpStrokeVert *verts,
vert->packed_asp_hard_rot = pack_rotation_aspect_hardness(
pt->uv_rot, aspect_ratio, gps->hardeness);
+
+ if (!is_endpoint) {
+ /* Issue a Quad per point. */
+ /* The attribute loading uses a different shader and will undo this bit packing. */
+ int v_mat = (v << GP_VERTEX_ID_SHIFT) | GP_IS_STROKE_VERTEX_BIT;
+ GPU_indexbuf_add_tri_verts(ibo, v_mat + 0, v_mat + 1, v_mat + 2);
+ GPU_indexbuf_add_tri_verts(ibo, v_mat + 2, v_mat + 1, v_mat + 3);
+ }
}
-static void gpencil_buffer_add_stroke(gpStrokeVert *verts,
+static void gpencil_buffer_add_stroke(GPUIndexBufBuilder *ibo,
+ gpStrokeVert *verts,
gpColorVert *cols,
const bGPDstroke *gps)
{
const bGPDspoint *pts = gps->points;
int pts_len = gps->totpoints;
bool is_cyclic = gpencil_stroke_is_cyclic(gps);
- int v = gps->runtime.stroke_start;
+ int v = gps->runtime.vertex_start;
/* First point for adjacency (not drawn). */
int adj_idx = (is_cyclic) ? (pts_len - 1) : min_ii(pts_len - 1, 1);
- gpencil_buffer_add_point(verts, cols, gps, &pts[adj_idx], v++, true);
+ gpencil_buffer_add_point(ibo, verts, cols, gps, &pts[adj_idx], v++, true);
for (int i = 0; i < pts_len; i++) {
- gpencil_buffer_add_point(verts, cols, gps, &pts[i], v++, false);
+ gpencil_buffer_add_point(ibo, verts, cols, gps, &pts[i], v++, false);
}
/* Draw line to first point to complete the loop for cyclic strokes. */
if (is_cyclic) {
- gpencil_buffer_add_point(verts, cols, gps, &pts[0], v, false);
+ gpencil_buffer_add_point(ibo, verts, cols, gps, &pts[0], v, false);
/* UV factor needs to be adjusted for the last point to not be equal to the UV factor of the
* first point. It should be the factor of the last point plus the distance from the last point
* to the first.
@@ -360,16 +369,20 @@ static void gpencil_buffer_add_stroke(gpStrokeVert *verts,
}
/* Last adjacency point (not drawn). */
adj_idx = (is_cyclic) ? 1 : max_ii(0, pts_len - 2);
- gpencil_buffer_add_point(verts, cols, gps, &pts[adj_idx], v++, true);
+ gpencil_buffer_add_point(ibo, verts, cols, gps, &pts[adj_idx], v++, true);
}
static void gpencil_buffer_add_fill(GPUIndexBufBuilder *ibo, const bGPDstroke *gps)
{
int tri_len = gps->tot_triangles;
- int v = gps->runtime.stroke_start;
+ int v = gps->runtime.vertex_start + 1;
for (int i = 0; i < tri_len; i++) {
uint *tri = gps->triangles[i].verts;
- GPU_indexbuf_add_tri_verts(ibo, v + tri[0], v + tri[1], v + tri[2]);
+ /* The attribute loading uses a different shader and will undo this bit packing. */
+ GPU_indexbuf_add_tri_verts(ibo,
+ (v + tri[0]) << GP_VERTEX_ID_SHIFT,
+ (v + tri[1]) << GP_VERTEX_ID_SHIFT,
+ (v + tri[2]) << GP_VERTEX_ID_SHIFT);
}
}
@@ -379,10 +392,10 @@ static void gpencil_stroke_iter_cb(bGPDlayer *UNUSED(gpl),
void *thunk)
{
gpIterData *iter = (gpIterData *)thunk;
- gpencil_buffer_add_stroke(iter->verts, iter->cols, gps);
if (gps->tot_triangles > 0) {
gpencil_buffer_add_fill(&iter->ibo, gps);
}
+ gpencil_buffer_add_stroke(&iter->ibo, iter->verts, iter->cols, gps);
}
static void gpencil_object_verts_count_cb(bGPDlayer *UNUSED(gpl),
@@ -391,12 +404,15 @@ static void gpencil_object_verts_count_cb(bGPDlayer *UNUSED(gpl),
void *thunk)
{
gpIterData *iter = (gpIterData *)thunk;
-
- /* Store first index offset */
- gps->runtime.stroke_start = iter->vert_len;
+ int stroke_vert_len = gps->totpoints + gpencil_stroke_is_cyclic(gps);
+ gps->runtime.vertex_start = iter->vert_len;
+ /* Add additional padding at the start and end. */
+ iter->vert_len += 1 + stroke_vert_len + 1;
+ /* Store first index offset. */
gps->runtime.fill_start = iter->tri_len;
- iter->vert_len += gps->totpoints + 2 + gpencil_stroke_is_cyclic(gps);
iter->tri_len += gps->tot_triangles;
+ gps->runtime.stroke_start = iter->tri_len;
+ iter->tri_len += stroke_vert_len * 2;
}
static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache, int cfra)
@@ -406,7 +422,7 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache, int cfr
if (cache->vbo == NULL) {
/* Should be discarded together. */
BLI_assert(cache->vbo == NULL && cache->ibo == NULL);
- BLI_assert(cache->fill_batch == NULL && cache->stroke_batch == NULL);
+ BLI_assert(cache->geom_batch == NULL);
/* TODO/PERF: Could be changed to only do it if needed.
* For now it's simpler to assume we always need it
* since multiple viewport could or could not need it.
@@ -415,29 +431,29 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache, int cfr
bool do_onion = true;
/* First count how many vertices and triangles are needed for the whole object. */
- gpIterData iter = {
- .gpd = gpd,
- .verts = NULL,
- .ibo = {0},
- .vert_len = 1, /* Start at 1 for the gl_InstanceID trick to work (see vert shader). */
- .tri_len = 0,
- .curve_len = 0,
- };
+ gpIterData iter = {};
+ iter.gpd = gpd;
+ iter.verts = NULL;
+ iter.ibo = {0};
+ iter.vert_len = 0;
+ iter.tri_len = 0;
+ iter.curve_len = 0;
BKE_gpencil_visible_stroke_advanced_iter(
NULL, ob, NULL, gpencil_object_verts_count_cb, &iter, do_onion, cfra);
+ GPUUsageType vbo_flag = GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY;
/* Create VBOs. */
GPUVertFormat *format = gpencil_stroke_format();
GPUVertFormat *format_col = gpencil_color_format();
- cache->vbo = GPU_vertbuf_create_with_format(format);
- cache->vbo_col = GPU_vertbuf_create_with_format(format_col);
+ cache->vbo = GPU_vertbuf_create_with_format_ex(format, vbo_flag);
+ cache->vbo_col = GPU_vertbuf_create_with_format_ex(format_col, vbo_flag);
/* Add extra space at the end of the buffer because of quad load. */
GPU_vertbuf_data_alloc(cache->vbo, iter.vert_len + 2);
GPU_vertbuf_data_alloc(cache->vbo_col, iter.vert_len + 2);
iter.verts = (gpStrokeVert *)GPU_vertbuf_get_data(cache->vbo);
iter.cols = (gpColorVert *)GPU_vertbuf_get_data(cache->vbo_col);
/* Create IBO. */
- GPU_indexbuf_init(&iter.ibo, GPU_PRIM_TRIS, iter.tri_len, iter.vert_len);
+ GPU_indexbuf_init(&iter.ibo, GPU_PRIM_TRIS, iter.tri_len, 0xFFFFFFFFu);
/* Fill buffers with data. */
BKE_gpencil_visible_stroke_advanced_iter(
@@ -452,33 +468,39 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache, int cfr
/* Finish the IBO. */
cache->ibo = GPU_indexbuf_build(&iter.ibo);
-
/* Create the batches */
- cache->fill_batch = GPU_batch_create(GPU_PRIM_TRIS, cache->vbo, cache->ibo);
- GPU_batch_vertbuf_add(cache->fill_batch, cache->vbo_col);
- cache->stroke_batch = GPU_batch_create(GPU_PRIM_TRI_STRIP, gpencil_dummy_buffer_get(), NULL);
- GPU_batch_instbuf_add_ex(cache->stroke_batch, cache->vbo, 0);
- GPU_batch_instbuf_add_ex(cache->stroke_batch, cache->vbo_col, 0);
+ cache->geom_batch = GPU_batch_create(GPU_PRIM_TRIS, cache->vbo, cache->ibo);
+ /* Allow creation of buffer texture. */
+ GPU_vertbuf_use(cache->vbo);
+ GPU_vertbuf_use(cache->vbo_col);
gpd->flag &= ~GP_DATA_CACHE_IS_DIRTY;
cache->is_dirty = false;
}
}
-GPUBatch *DRW_cache_gpencil_strokes_get(Object *ob, int cfra)
+GPUBatch *DRW_cache_gpencil_get(Object *ob, int cfra)
+{
+ GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra);
+ gpencil_batches_ensure(ob, cache, cfra);
+
+ return cache->geom_batch;
+}
+
+GPUVertBuf *DRW_cache_gpencil_position_buffer_get(Object *ob, int cfra)
{
GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra);
gpencil_batches_ensure(ob, cache, cfra);
- return cache->stroke_batch;
+ return cache->vbo;
}
-GPUBatch *DRW_cache_gpencil_fills_get(Object *ob, int cfra)
+GPUVertBuf *DRW_cache_gpencil_color_buffer_get(Object *ob, int cfra)
{
GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra);
gpencil_batches_ensure(ob, cache, cfra);
- return cache->fill_batch;
+ return cache->vbo_col;
}
static void gpencil_lines_indices_cb(bGPDlayer *UNUSED(gpl),
@@ -489,7 +511,7 @@ static void gpencil_lines_indices_cb(bGPDlayer *UNUSED(gpl),
gpIterData *iter = (gpIterData *)thunk;
int pts_len = gps->totpoints + gpencil_stroke_is_cyclic(gps);
- int start = gps->runtime.stroke_start + 1;
+ int start = gps->runtime.vertex_start + 1;
int end = start + pts_len;
for (int i = start; i < end; i++) {
GPU_indexbuf_add_generic_vert(&iter->ibo, i);
@@ -508,10 +530,9 @@ GPUBatch *DRW_cache_gpencil_face_wireframe_get(Object *ob)
if (cache->lines_batch == NULL) {
GPUVertBuf *vbo = cache->vbo;
- gpIterData iter = {
- .gpd = ob->data,
- .ibo = {0},
- };
+ gpIterData iter = {};
+ iter.gpd = (bGPdata *)ob->data;
+ iter.ibo = {0};
uint vert_len = GPU_vertbuf_get_vertex_len(vbo);
GPU_indexbuf_init_ex(&iter.ibo, GPU_PRIM_LINE_STRIP, vert_len, vert_len);
@@ -540,7 +561,7 @@ bGPDstroke *DRW_cache_gpencil_sbuffer_stroke_data_get(Object *ob)
Brush *brush = gpd->runtime.sbuffer_brush;
/* Convert the sbuffer to a bGPDstroke. */
if (gpd->runtime.sbuffer_gps == NULL) {
- bGPDstroke *gps = MEM_callocN(sizeof(*gps), "bGPDstroke sbuffer");
+ bGPDstroke *gps = (bGPDstroke *)MEM_callocN(sizeof(*gps), "bGPDstroke sbuffer");
gps->totpoints = gpd->runtime.sbuffer_used;
gps->mat_nr = max_ii(0, gpd->runtime.matid - 1);
gps->flag = gpd->runtime.sbuffer_sflag;
@@ -553,7 +574,9 @@ bGPDstroke *DRW_cache_gpencil_sbuffer_stroke_data_get(Object *ob)
gps->tot_triangles = max_ii(0, gpd->runtime.sbuffer_used - 2);
gps->caps[0] = gps->caps[1] = GP_STROKE_CAP_ROUND;
- gps->runtime.stroke_start = 1; /* Add one for the adjacency index. */
+ gps->runtime.vertex_start = 0;
+ gps->runtime.fill_start = 0;
+ gps->runtime.stroke_start = 0;
copy_v4_v4(gps->vert_color_fill, gpd->runtime.vert_color_fill);
/* Caps. */
gps->caps[0] = gps->caps[1] = (short)brush->gpencil_settings->caps_type;
@@ -563,17 +586,17 @@ bGPDstroke *DRW_cache_gpencil_sbuffer_stroke_data_get(Object *ob)
return gpd->runtime.sbuffer_gps;
}
-static void gpencil_sbuffer_stroke_ensure(bGPdata *gpd, bool do_stroke, bool do_fill)
+static void gpencil_sbuffer_stroke_ensure(bGPdata *gpd, bool do_fill)
{
- tGPspoint *tpoints = gpd->runtime.sbuffer;
+ tGPspoint *tpoints = (tGPspoint *)gpd->runtime.sbuffer;
bGPDstroke *gps = gpd->runtime.sbuffer_gps;
int vert_len = gpd->runtime.sbuffer_used;
/* DRW_cache_gpencil_sbuffer_stroke_data_get need to have been called previously. */
BLI_assert(gps != NULL);
- if (do_stroke && (gpd->runtime.sbuffer_stroke_batch == NULL)) {
- gps->points = MEM_mallocN(vert_len * sizeof(*gps->points), __func__);
+ if (gpd->runtime.sbuffer_batch == NULL) {
+ gps->points = (bGPDspoint *)MEM_mallocN(vert_len * sizeof(*gps->points), __func__);
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
@@ -589,43 +612,32 @@ static void gpencil_sbuffer_stroke_ensure(bGPdata *gpd, bool do_stroke, bool do_
for (int i = 0; i < vert_len; i++) {
ED_gpencil_tpoint_to_point(region, origin, &tpoints[i], &gps->points[i]);
- mul_m4_v3(ob->imat, &gps->points[i].x);
+ mul_m4_v3(ob->world_to_object, &gps->points[i].x);
bGPDspoint *pt = &gps->points[i];
copy_v4_v4(pt->vert_color, tpoints[i].vert_color);
}
/* Calc uv data along the stroke. */
BKE_gpencil_stroke_uv_update(gps);
+ int tri_len = gps->tot_triangles + (gps->totpoints + gpencil_stroke_is_cyclic(gps)) * 2;
+ /* Create IBO. */
+ GPUIndexBufBuilder ibo_builder;
+ GPU_indexbuf_init(&ibo_builder, GPU_PRIM_TRIS, tri_len, 0xFFFFFFFFu);
/* Create VBO. */
+ GPUUsageType vbo_flag = GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY;
GPUVertFormat *format = gpencil_stroke_format();
GPUVertFormat *format_color = gpencil_color_format();
- GPUVertBuf *vbo = GPU_vertbuf_create_with_format(format);
- GPUVertBuf *vbo_col = GPU_vertbuf_create_with_format(format_color);
- /* Add extra space at the end (and start) of the buffer because of quad load and cyclic. */
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format_ex(format, vbo_flag);
+ GPUVertBuf *vbo_col = GPU_vertbuf_create_with_format_ex(format_color, vbo_flag);
+ /* Add extra space at the start and end the buffer because of quad load and cyclic. */
GPU_vertbuf_data_alloc(vbo, 1 + vert_len + 1 + 2);
GPU_vertbuf_data_alloc(vbo_col, 1 + vert_len + 1 + 2);
gpStrokeVert *verts = (gpStrokeVert *)GPU_vertbuf_get_data(vbo);
gpColorVert *cols = (gpColorVert *)GPU_vertbuf_get_data(vbo_col);
- /* Fill buffers with data. */
- gpencil_buffer_add_stroke(verts, cols, gps);
-
- GPUBatch *batch = GPU_batch_create(GPU_PRIM_TRI_STRIP, gpencil_dummy_buffer_get(), NULL);
- GPU_batch_instbuf_add_ex(batch, vbo, true);
- GPU_batch_instbuf_add_ex(batch, vbo_col, true);
-
- gpd->runtime.sbuffer_stroke_batch = batch;
-
- MEM_freeN(gps->points);
- }
-
- if (do_fill && (gpd->runtime.sbuffer_fill_batch == NULL)) {
- /* Create IBO. */
- GPUIndexBufBuilder ibo_builder;
- GPU_indexbuf_init(&ibo_builder, GPU_PRIM_TRIS, gps->tot_triangles, vert_len);
-
- if (gps->tot_triangles > 0) {
- float(*tpoints2d)[2] = MEM_mallocN(sizeof(*tpoints2d) * vert_len, __func__);
+ /* Create fill indices. */
+ if (do_fill && gps->tot_triangles > 0) {
+ float(*tpoints2d)[2] = (float(*)[2])MEM_mallocN(sizeof(*tpoints2d) * vert_len, __func__);
/* Triangulate in 2D. */
for (int i = 0; i < vert_len; i++) {
copy_v2_v2(tpoints2d[i], tpoints[i].m_xy);
@@ -633,51 +645,72 @@ static void gpencil_sbuffer_stroke_ensure(bGPdata *gpd, bool do_stroke, bool do_
/* Compute directly inside the IBO data buffer. */
/* OPTI: This is a bottleneck if the stroke is very long. */
BLI_polyfill_calc(tpoints2d, (uint)vert_len, 0, (uint(*)[3])ibo_builder.data);
- /* Add stroke start offset. */
+ /* Add stroke start offset and shift. */
for (int i = 0; i < gps->tot_triangles * 3; i++) {
- ibo_builder.data[i] += gps->runtime.stroke_start;
+ ibo_builder.data[i] = (ibo_builder.data[i] + 1) << GP_VERTEX_ID_SHIFT;
}
/* HACK since we didn't use the builder API to avoid another malloc and copy,
* we need to set the number of indices manually. */
ibo_builder.index_len = gps->tot_triangles * 3;
+ ibo_builder.index_min = 0;
+ /* For this case, do not allow index compaction to avoid yet another preprocessing step. */
+ ibo_builder.index_max = 0xFFFFFFFFu - 1u;
+
+ gps->runtime.stroke_start = gps->tot_triangles;
MEM_freeN(tpoints2d);
}
- GPUIndexBuf *ibo = GPU_indexbuf_build(&ibo_builder);
- GPUVertBuf *vbo = gpd->runtime.sbuffer_stroke_batch->inst[0];
- GPUVertBuf *vbo_col = gpd->runtime.sbuffer_stroke_batch->inst[1];
+ /* Fill buffers with data. */
+ gpencil_buffer_add_stroke(&ibo_builder, verts, cols, gps);
- GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, ibo, GPU_BATCH_OWNS_INDEX);
- GPU_batch_vertbuf_add(batch, vbo_col);
+ GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_TRIS,
+ gpencil_dummy_buffer_get(),
+ GPU_indexbuf_build(&ibo_builder),
+ GPU_BATCH_OWNS_INDEX);
- gpd->runtime.sbuffer_fill_batch = batch;
+ gpd->runtime.sbuffer_position_buf = vbo;
+ gpd->runtime.sbuffer_color_buf = vbo_col;
+ gpd->runtime.sbuffer_batch = batch;
+
+ MEM_freeN(gps->points);
}
}
-GPUBatch *DRW_cache_gpencil_sbuffer_stroke_get(Object *ob)
+GPUBatch *DRW_cache_gpencil_sbuffer_get(Object *ob, bool show_fill)
{
bGPdata *gpd = (bGPdata *)ob->data;
- gpencil_sbuffer_stroke_ensure(gpd, true, false);
+ /* Fill batch also need stroke batch to be created (vbo is shared). */
+ gpencil_sbuffer_stroke_ensure(gpd, show_fill);
- return gpd->runtime.sbuffer_stroke_batch;
+ return gpd->runtime.sbuffer_batch;
}
-GPUBatch *DRW_cache_gpencil_sbuffer_fill_get(Object *ob)
+GPUVertBuf *DRW_cache_gpencil_sbuffer_position_buffer_get(Object *ob, bool show_fill)
{
bGPdata *gpd = (bGPdata *)ob->data;
/* Fill batch also need stroke batch to be created (vbo is shared). */
- gpencil_sbuffer_stroke_ensure(gpd, true, true);
+ gpencil_sbuffer_stroke_ensure(gpd, show_fill);
- return gpd->runtime.sbuffer_fill_batch;
+ return gpd->runtime.sbuffer_position_buf;
+}
+
+GPUVertBuf *DRW_cache_gpencil_sbuffer_color_buffer_get(Object *ob, bool show_fill)
+{
+ bGPdata *gpd = (bGPdata *)ob->data;
+ /* Fill batch also need stroke batch to be created (vbo is shared). */
+ gpencil_sbuffer_stroke_ensure(gpd, show_fill);
+
+ return gpd->runtime.sbuffer_color_buf;
}
void DRW_cache_gpencil_sbuffer_clear(Object *ob)
{
bGPdata *gpd = (bGPdata *)ob->data;
MEM_SAFE_FREE(gpd->runtime.sbuffer_gps);
- GPU_BATCH_DISCARD_SAFE(gpd->runtime.sbuffer_fill_batch);
- GPU_BATCH_DISCARD_SAFE(gpd->runtime.sbuffer_stroke_batch);
+ GPU_BATCH_DISCARD_SAFE(gpd->runtime.sbuffer_batch);
+ GPU_VERTBUF_DISCARD_SAFE(gpd->runtime.sbuffer_position_buf);
+ GPU_VERTBUF_DISCARD_SAFE(gpd->runtime.sbuffer_color_buf);
}
/** \} */
@@ -728,7 +761,7 @@ static void gpencil_edit_stroke_iter_cb(bGPDlayer *gpl,
{
gpEditIterData *iter = (gpEditIterData *)thunk;
const int v_len = gps->totpoints;
- const int v = gps->runtime.stroke_start + 1;
+ const int v = gps->runtime.vertex_start + 1;
MDeformVert *dvert = ((iter->vgindex > -1) && gps->dvert) ? gps->dvert : NULL;
gpEditVert *vert_ptr = iter->verts + v;
@@ -743,9 +776,12 @@ static void gpencil_edit_stroke_iter_cb(bGPDlayer *gpl,
vert_ptr->weight = gpencil_point_edit_weight(dvert, i, iter->vgindex);
vert_ptr++;
}
- /* Draw line to first point to complete the loop for cyclic strokes. */
- vert_ptr->vflag = sflag | gpencil_point_edit_flag(layer_lock, &gps->points[0], 0, v_len);
- vert_ptr->weight = gpencil_point_edit_weight(dvert, 0, iter->vgindex);
+
+ if (gpencil_stroke_is_cyclic(gps)) {
+ /* Draw line to first point to complete the loop for cyclic strokes. */
+ vert_ptr->vflag = sflag | gpencil_point_edit_flag(layer_lock, &gps->points[0], 0, v_len);
+ vert_ptr->weight = gpencil_point_edit_weight(dvert, 0, iter->vgindex);
+ }
}
static void gpencil_edit_curve_stroke_count_cb(bGPDlayer *gpl,
@@ -876,14 +912,13 @@ static void gpencil_edit_batches_ensure(Object *ob, GpencilBatchCache *cache, in
/* Curve Handles and Points for Editing. */
if (cache->edit_curve_vbo == NULL) {
- gpIterData iterdata = {
- .gpd = gpd,
- .verts = NULL,
- .ibo = {0},
- .vert_len = 0,
- .tri_len = 0,
- .curve_len = 0,
- };
+ gpIterData iterdata = {};
+ iterdata.gpd = gpd;
+ iterdata.verts = NULL;
+ iterdata.ibo = {0};
+ iterdata.vert_len = 0;
+ iterdata.tri_len = 0;
+ iterdata.curve_len = 0;
/* Create VBO. */
GPUVertFormat *format = gpencil_edit_curve_format();
diff --git a/source/blender/draw/intern/draw_cache_impl_lattice.c b/source/blender/draw/intern/draw_cache_impl_lattice.c
index 0f12e78d60e..eb94f46fe50 100644
--- a/source/blender/draw/intern/draw_cache_impl_lattice.c
+++ b/source/blender/draw/intern/draw_cache_impl_lattice.c
@@ -231,7 +231,7 @@ static bool lattice_batch_cache_valid(Lattice *lt)
if ((cache->dims.u_len != lt->pntsu) || (cache->dims.v_len != lt->pntsv) ||
(cache->dims.w_len != lt->pntsw) ||
- ((cache->show_only_outside != ((lt->flag & LT_OUTSIDE) != 0)))) {
+ (cache->show_only_outside != ((lt->flag & LT_OUTSIDE) != 0))) {
return false;
}
@@ -367,11 +367,11 @@ static GPUIndexBuf *lattice_batch_cache_get_edges(LatticeRenderData *rdata,
#define LATT_INDEX(u, v, w) ((((w)*rdata->dims.v_len + (v)) * rdata->dims.u_len) + (u))
for (int w = 0; w < rdata->dims.w_len; w++) {
- int wxt = (ELEM(w, 0, rdata->dims.w_len - 1));
+ int wxt = ELEM(w, 0, rdata->dims.w_len - 1);
for (int v = 0; v < rdata->dims.v_len; v++) {
- int vxt = (ELEM(v, 0, rdata->dims.v_len - 1));
+ int vxt = ELEM(v, 0, rdata->dims.v_len - 1);
for (int u = 0; u < rdata->dims.u_len; u++) {
- int uxt = (ELEM(u, 0, rdata->dims.u_len - 1));
+ int uxt = ELEM(u, 0, rdata->dims.u_len - 1);
if (w && ((uxt || vxt) || !rdata->show_only_outside)) {
GPU_indexbuf_add_line_verts(&elb, LATT_INDEX(u, v, w - 1), LATT_INDEX(u, v, w));
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc
index c22382b3e09..031de3e4ef2 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.cc
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc
@@ -62,6 +62,7 @@
#include "draw_subdivision.h"
#include "draw_cache_impl.h" /* own include */
+#include "draw_manager.h"
#include "mesh_extractors/extract_mesh.hh"
@@ -104,7 +105,8 @@ static constexpr DRWBatchFlag batches_that_use_buffer(const int buffer_index)
MBC_EDIT_EDGES | MBC_EDIT_VNOR | MBC_EDIT_LNOR | MBC_EDIT_MESH_ANALYSIS |
MBC_EDIT_SELECTION_VERTS | MBC_EDIT_SELECTION_EDGES | MBC_EDIT_SELECTION_FACES |
MBC_ALL_VERTS | MBC_ALL_EDGES | MBC_LOOSE_EDGES | MBC_EDGE_DETECTION |
- MBC_WIRE_EDGES | MBC_WIRE_LOOPS | MBC_SCULPT_OVERLAYS | MBC_SURFACE_PER_MAT;
+ MBC_WIRE_EDGES | MBC_WIRE_LOOPS | MBC_SCULPT_OVERLAYS | MBC_VIEWER_ATTRIBUTE_OVERLAY |
+ MBC_SURFACE_PER_MAT;
case BUFFER_INDEX(vbo.lnor):
return MBC_SURFACE | MBC_EDIT_LNOR | MBC_WIRE_LOOPS | MBC_SURFACE_PER_MAT;
case BUFFER_INDEX(vbo.edge_fac):
@@ -166,9 +168,12 @@ static constexpr DRWBatchFlag batches_that_use_buffer(const int buffer_index)
case BUFFER_INDEX(vbo.attr[13]):
case BUFFER_INDEX(vbo.attr[14]):
return MBC_SURFACE | MBC_SURFACE_PER_MAT;
+ case BUFFER_INDEX(vbo.attr_viewer):
+ return MBC_VIEWER_ATTRIBUTE_OVERLAY;
case BUFFER_INDEX(ibo.tris):
return MBC_SURFACE | MBC_SURFACE_WEIGHTS | MBC_EDIT_TRIANGLES | MBC_EDIT_LNOR |
- MBC_EDIT_MESH_ANALYSIS | MBC_EDIT_SELECTION_FACES | MBC_SCULPT_OVERLAYS;
+ MBC_EDIT_MESH_ANALYSIS | MBC_EDIT_SELECTION_FACES | MBC_SCULPT_OVERLAYS |
+ MBC_VIEWER_ATTRIBUTE_OVERLAY;
case BUFFER_INDEX(ibo.lines):
return MBC_EDIT_EDGES | MBC_EDIT_SELECTION_EDGES | MBC_ALL_EDGES | MBC_WIRE_EDGES;
case BUFFER_INDEX(ibo.lines_loose):
@@ -236,7 +241,7 @@ BLI_INLINE void mesh_cd_layers_type_clear(DRW_MeshCDMask *a)
*((uint32_t *)a) = 0;
}
-static void mesh_cd_calc_edit_uv_layer(const Mesh *UNUSED(me), DRW_MeshCDMask *cd_used)
+static void mesh_cd_calc_edit_uv_layer(const Mesh * /*me*/, DRW_MeshCDMask *cd_used)
{
cd_used->edit_uv = 1;
}
@@ -549,22 +554,13 @@ BLI_INLINE void mesh_batch_cache_add_request(MeshBatchCache *cache, DRWBatchFlag
static bool mesh_batch_cache_valid(Object *object, Mesh *me)
{
- MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime.batch_cache);
+ MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime->batch_cache);
if (cache == nullptr) {
return false;
}
- if (object->sculpt && object->sculpt->pbvh) {
- if (cache->pbvh_is_drawing != BKE_pbvh_is_drawing(object->sculpt->pbvh)) {
- return false;
- }
-
- if (BKE_pbvh_is_drawing(object->sculpt->pbvh) &&
- BKE_pbvh_draw_cache_invalid(object->sculpt->pbvh)) {
- return false;
- }
- }
+ /* Note: PBVH draw data should not be checked here. */
if (cache->is_editmode != (me->edit_mesh != nullptr)) {
return false;
@@ -583,11 +579,11 @@ static bool mesh_batch_cache_valid(Object *object, Mesh *me)
static void mesh_batch_cache_init(Object *object, Mesh *me)
{
- MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime.batch_cache);
+ MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime->batch_cache);
if (!cache) {
- me->runtime.batch_cache = MEM_cnew<MeshBatchCache>(__func__);
- cache = static_cast<MeshBatchCache *>(me->runtime.batch_cache);
+ me->runtime->batch_cache = MEM_cnew<MeshBatchCache>(__func__);
+ cache = static_cast<MeshBatchCache *>(me->runtime->batch_cache);
}
else {
memset(cache, 0, sizeof(*cache));
@@ -629,7 +625,7 @@ void DRW_mesh_batch_cache_validate(Object *object, Mesh *me)
static MeshBatchCache *mesh_batch_cache_get(Mesh *me)
{
- return static_cast<MeshBatchCache *>(me->runtime.batch_cache);
+ return static_cast<MeshBatchCache *>(me->runtime->batch_cache);
}
static void mesh_batch_cache_check_vertex_group(MeshBatchCache *cache,
@@ -737,7 +733,7 @@ static void mesh_batch_cache_discard_uvedit_select(MeshBatchCache *cache)
void DRW_mesh_batch_cache_dirty_tag(Mesh *me, eMeshBatchDirtyMode mode)
{
- MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime.batch_cache);
+ MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime->batch_cache);
if (cache == nullptr) {
return;
}
@@ -825,7 +821,7 @@ static void mesh_batch_cache_free_subdiv_cache(MeshBatchCache *cache)
static void mesh_batch_cache_clear(Mesh *me)
{
- MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime.batch_cache);
+ MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime->batch_cache);
if (!cache) {
return;
}
@@ -857,7 +853,7 @@ static void mesh_batch_cache_clear(Mesh *me)
void DRW_mesh_batch_cache_free(Mesh *me)
{
mesh_batch_cache_clear(me);
- MEM_SAFE_FREE(me->runtime.batch_cache);
+ MEM_SAFE_FREE(me->runtime->batch_cache);
}
/** \} */
@@ -977,6 +973,27 @@ GPUBatch *DRW_mesh_batch_cache_get_edit_mesh_analysis(Mesh *me)
return DRW_batch_request(&cache->batch.edit_mesh_analysis);
}
+void DRW_mesh_get_attributes(Object *object,
+ Mesh *me,
+ struct GPUMaterial **gpumat_array,
+ int gpumat_array_len,
+ DRW_Attributes *r_attrs,
+ DRW_MeshCDMask *r_cd_needed)
+{
+ DRW_Attributes attrs_needed;
+ drw_attributes_clear(&attrs_needed);
+ DRW_MeshCDMask cd_needed = mesh_cd_calc_used_gpu_layers(
+ object, me, gpumat_array, gpumat_array_len, &attrs_needed);
+
+ if (r_attrs) {
+ *r_attrs = attrs_needed;
+ }
+
+ if (r_cd_needed) {
+ *r_cd_needed = cd_needed;
+ }
+}
+
GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(Object *object,
Mesh *me,
struct GPUMaterial **gpumat_array,
@@ -991,8 +1008,7 @@ GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(Object *object,
BLI_assert(gpumat_array_len == cache->mat_len);
mesh_cd_layers_type_merge(&cache->cd_needed, cd_needed);
- ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime.render_mutex;
- drw_attributes_merge(&cache->attr_needed, &attrs_needed, mesh_render_mutex);
+ drw_attributes_merge(&cache->attr_needed, &attrs_needed, me->runtime->render_mutex);
mesh_batch_cache_request_surface_batches(cache);
return cache->surface_per_mat;
}
@@ -1020,8 +1036,7 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(Object *object, Mesh *me)
DRW_Attributes attrs_needed{};
request_active_and_default_color_attributes(*object, *me, attrs_needed);
- ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime.render_mutex;
- drw_attributes_merge(&cache->attr_needed, &attrs_needed, mesh_render_mutex);
+ drw_attributes_merge(&cache->attr_needed, &attrs_needed, me->runtime->render_mutex);
mesh_batch_cache_request_surface_batches(cache);
return cache->batch.surface;
@@ -1034,8 +1049,7 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_sculpt(Object *object, Mesh *me)
DRW_Attributes attrs_needed{};
request_active_and_default_color_attributes(*object, *me, attrs_needed);
- ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime.render_mutex;
- drw_attributes_merge(&cache->attr_needed, &attrs_needed, mesh_render_mutex);
+ drw_attributes_merge(&cache->attr_needed, &attrs_needed, me->runtime->render_mutex);
mesh_batch_cache_request_surface_batches(cache);
return cache->batch.surface;
@@ -1057,6 +1071,16 @@ GPUBatch *DRW_mesh_batch_cache_get_sculpt_overlays(Mesh *me)
return cache->batch.sculpt_overlays;
}
+GPUBatch *DRW_mesh_batch_cache_get_surface_viewer_attribute(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ mesh_batch_cache_add_request(cache, MBC_VIEWER_ATTRIBUTE_OVERLAY);
+ DRW_batch_request(&cache->batch.surface_viewer_attribute);
+
+ return cache->batch.surface_viewer_attribute;
+}
+
/** \} */
/* ---------------------------------------------------------------------- */
@@ -1264,7 +1288,7 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_edges(Object *object, Mesh *me)
void DRW_mesh_batch_cache_free_old(Mesh *me, int ctime)
{
- MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime.batch_cache);
+ MeshBatchCache *cache = static_cast<MeshBatchCache *>(me->runtime->batch_cache);
if (cache == nullptr) {
return;
@@ -1366,8 +1390,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
}
};
#else
- auto assert_deps_valid = [&](DRWBatchFlag UNUSED(batch_flag),
- Span<int> UNUSED(used_buffer_indices)) {};
+ auto assert_deps_valid = [&](DRWBatchFlag /*batch_flag*/, Span<int> /*used_buffer_indices*/) {};
#endif
@@ -1411,8 +1434,6 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
}
}
- ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime.render_mutex;
-
/* Verify that all surface batches have needed attribute layers.
*/
/* TODO(fclem): We could be a bit smarter here and only do it per
@@ -1450,12 +1471,13 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
cache->batch_ready &= ~(MBC_SURFACE);
mesh_cd_layers_type_merge(&cache->cd_used, cache->cd_needed);
- drw_attributes_merge(&cache->attr_used, &cache->attr_needed, mesh_render_mutex);
+ drw_attributes_merge(&cache->attr_used, &cache->attr_needed, me->runtime->render_mutex);
}
mesh_cd_layers_type_merge(&cache->cd_used_over_time, cache->cd_needed);
mesh_cd_layers_type_clear(&cache->cd_needed);
- drw_attributes_merge(&cache->attr_used_over_time, &cache->attr_needed, mesh_render_mutex);
+ drw_attributes_merge(
+ &cache->attr_used_over_time, &cache->attr_needed, me->runtime->render_mutex);
drw_attributes_clear(&cache->attr_needed);
}
@@ -1502,7 +1524,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
const bool do_update_sculpt_normals = ob->sculpt && ob->sculpt->pbvh;
if (do_update_sculpt_normals) {
Mesh *mesh = static_cast<Mesh *>(ob->data);
- BKE_pbvh_update_normals(ob->sculpt->pbvh, mesh->runtime.subdiv_ccg);
+ BKE_pbvh_update_normals(ob->sculpt->pbvh, mesh->runtime->subdiv_ccg);
}
cache->batch_ready |= batch_requested;
@@ -1513,8 +1535,8 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob);
do_cage = editmesh_eval_final != editmesh_eval_cage;
- do_uvcage = !(editmesh_eval_final->runtime.is_original_bmesh &&
- editmesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH);
+ do_uvcage = !(editmesh_eval_final->runtime->is_original_bmesh &&
+ editmesh_eval_final->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH);
}
const bool do_subdivision = BKE_subsurf_modifier_has_gpu_subdiv(me);
@@ -1802,6 +1824,14 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
DRW_vbo_request(cache->batch.edituv_fdots, &mbuflist->vbo.fdots_uv);
DRW_vbo_request(cache->batch.edituv_fdots, &mbuflist->vbo.fdots_edituv_data);
}
+ assert_deps_valid(
+ MBC_VIEWER_ATTRIBUTE_OVERLAY,
+ {BUFFER_INDEX(ibo.tris), BUFFER_INDEX(vbo.pos_nor), BUFFER_INDEX(vbo.attr_viewer)});
+ if (DRW_batch_requested(cache->batch.surface_viewer_attribute, GPU_PRIM_TRIS)) {
+ DRW_ibo_request(cache->batch.surface_viewer_attribute, &mbuflist->ibo.tris);
+ DRW_vbo_request(cache->batch.surface_viewer_attribute, &mbuflist->vbo.pos_nor);
+ DRW_vbo_request(cache->batch.surface_viewer_attribute, &mbuflist->vbo.attr_viewer);
+ }
#ifdef DEBUG
auto assert_final_deps_valid = [&](const int buffer_index) {
@@ -1833,6 +1863,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
for (const int i : IndexRange(GPU_MAX_ATTR)) {
assert_final_deps_valid(BUFFER_INDEX(vbo.attr[i]));
}
+ assert_final_deps_valid(BUFFER_INDEX(vbo.attr_viewer));
assert_final_deps_valid(BUFFER_INDEX(ibo.tris));
assert_final_deps_valid(BUFFER_INDEX(ibo.lines));
@@ -1858,7 +1889,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
is_editmode,
is_paint_mode,
is_mode_active,
- ob->obmat,
+ ob->object_to_world,
false,
true,
scene,
@@ -1875,7 +1906,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
is_editmode,
is_paint_mode,
is_mode_active,
- ob->obmat,
+ ob->object_to_world,
false,
false,
scene,
@@ -1891,7 +1922,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
is_editmode,
is_paint_mode,
is_mode_active,
- ob->obmat,
+ ob->object_to_world,
true,
false,
do_cage,
@@ -1912,7 +1943,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
is_editmode,
is_paint_mode,
is_mode_active,
- ob->obmat,
+ ob->object_to_world,
true,
false,
scene,
diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c
index 9c1784b1de2..cddab74c46f 100644
--- a/source/blender/draw/intern/draw_cache_impl_particles.c
+++ b/source/blender/draw/intern/draw_cache_impl_particles.c
@@ -173,13 +173,9 @@ static void particle_batch_cache_clear_hair(ParticleHairCache *hair_cache)
/* TODO: more granular update tagging. */
GPU_VERTBUF_DISCARD_SAFE(hair_cache->proc_point_buf);
GPU_VERTBUF_DISCARD_SAFE(hair_cache->proc_length_buf);
- DRW_TEXTURE_FREE_SAFE(hair_cache->point_tex);
- DRW_TEXTURE_FREE_SAFE(hair_cache->length_tex);
GPU_VERTBUF_DISCARD_SAFE(hair_cache->proc_strand_buf);
GPU_VERTBUF_DISCARD_SAFE(hair_cache->proc_strand_seg_buf);
- DRW_TEXTURE_FREE_SAFE(hair_cache->strand_tex);
- DRW_TEXTURE_FREE_SAFE(hair_cache->strand_seg_tex);
for (int i = 0; i < MAX_MTFACE; i++) {
GPU_VERTBUF_DISCARD_SAFE(hair_cache->proc_uv_buf[i]);
@@ -192,7 +188,6 @@ static void particle_batch_cache_clear_hair(ParticleHairCache *hair_cache)
for (int i = 0; i < MAX_HAIR_SUBDIV; i++) {
GPU_VERTBUF_DISCARD_SAFE(hair_cache->final[i].proc_buf);
- DRW_TEXTURE_FREE_SAFE(hair_cache->final[i].proc_tex);
for (int j = 0; j < MAX_THICKRES; j++) {
GPU_BATCH_DISCARD_SAFE(hair_cache->final[i].proc_hairs[j]);
}
@@ -810,7 +805,7 @@ static int particle_batch_cache_fill_strands_data(ParticleSystem *psys,
static void particle_batch_cache_ensure_procedural_final_points(ParticleHairCache *cache,
int subdiv)
{
- /* Same format as point_tex. */
+ /* Same format as proc_point_buf. */
GPUVertFormat format = {0};
GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
@@ -823,12 +818,6 @@ static void particle_batch_cache_ensure_procedural_final_points(ParticleHairCach
/* Those are points! not line segments. */
GPU_vertbuf_data_alloc(cache->final[subdiv].proc_buf,
cache->final[subdiv].strands_res * cache->strands_len);
-
- /* Create vbo immediately to bind to texture buffer. */
- GPU_vertbuf_use(cache->final[subdiv].proc_buf);
-
- cache->final[subdiv].proc_tex = GPU_texture_create_from_vertbuf("part_proc",
- cache->final[subdiv].proc_buf);
}
static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit,
@@ -1034,14 +1023,6 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit
MEM_freeN(parent_mcol);
}
- /* Create vbo immediately to bind to texture buffer. */
- GPU_vertbuf_use(cache->proc_strand_buf);
- cache->strand_tex = GPU_texture_create_from_vertbuf("part_strand", cache->proc_strand_buf);
-
- GPU_vertbuf_use(cache->proc_strand_seg_buf);
- cache->strand_seg_tex = GPU_texture_create_from_vertbuf("part_strand_seg",
- cache->proc_strand_seg_buf);
-
for (int i = 0; i < cache->num_uv_layers; i++) {
GPU_vertbuf_use(cache->proc_uv_buf[i]);
cache->uv_tex[i] = GPU_texture_create_from_vertbuf("part_uv", cache->proc_uv_buf[i]);
@@ -1107,7 +1088,7 @@ static void particle_batch_cache_ensure_procedural_indices(PTCacheEdit *edit,
static void particle_batch_cache_ensure_procedural_pos(PTCacheEdit *edit,
ParticleSystem *psys,
ParticleHairCache *cache,
- GPUMaterial *gpu_material)
+ GPUMaterial *UNUSED(gpu_material))
{
if (cache->proc_point_buf == NULL) {
/* initialize vertex format */
@@ -1149,22 +1130,6 @@ static void particle_batch_cache_ensure_procedural_pos(PTCacheEdit *edit,
psys->childcache, child_count, &pos_step, &length_step);
}
}
-
- /* Create vbo immediately to bind to texture buffer. */
- GPU_vertbuf_use(cache->proc_point_buf);
- cache->point_tex = GPU_texture_create_from_vertbuf("part_point", cache->proc_point_buf);
- }
-
- /* Checking hair length separately, only allocating gpu memory when needed. */
- if (gpu_material && cache->proc_length_buf != NULL && cache->length_tex == NULL) {
- ListBase gpu_attrs = GPU_material_attributes(gpu_material);
- LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &gpu_attrs) {
- if (attr->type == CD_HAIRLENGTH) {
- GPU_vertbuf_use(cache->proc_length_buf);
- cache->length_tex = GPU_texture_create_from_vertbuf("hair_length", cache->proc_length_buf);
- break;
- }
- }
}
}
@@ -1381,7 +1346,7 @@ static void particle_batch_cache_ensure_pos(Object *object,
sim.ob = object;
sim.psys = psys;
sim.psmd = psys_get_modifier(object, psys);
- sim.psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
+ psys_sim_data_init(&sim);
GPU_VERTBUF_DISCARD_SAFE(point_cache->pos);
@@ -1427,6 +1392,8 @@ static void particle_batch_cache_ensure_pos(Object *object,
if (curr_point != psys->totpart) {
GPU_vertbuf_data_resize(point_cache->pos, curr_point);
}
+
+ psys_sim_data_free(&sim);
}
static void drw_particle_update_ptcache_edit(Object *object_eval,
@@ -1722,7 +1689,7 @@ bool particles_ensure_procedural_data(Object *object,
/* Refreshed on combing and simulation. */
if ((*r_hair_cache)->proc_point_buf == NULL ||
- (gpu_material && (*r_hair_cache)->length_tex == NULL)) {
+ (gpu_material && (*r_hair_cache)->proc_length_buf == NULL)) {
ensure_seg_pt_count(source.edit, source.psys, &cache->hair);
particle_batch_cache_ensure_procedural_pos(
source.edit, source.psys, &cache->hair, gpu_material);
@@ -1730,7 +1697,7 @@ bool particles_ensure_procedural_data(Object *object,
}
/* Refreshed if active layer or custom data changes. */
- if ((*r_hair_cache)->strand_tex == NULL) {
+ if ((*r_hair_cache)->proc_strand_buf == NULL) {
particle_batch_cache_ensure_procedural_strand_data(
source.edit, source.psys, source.md, &cache->hair);
}
diff --git a/source/blender/draw/intern/draw_cache_impl_pointcloud.cc b/source/blender/draw/intern/draw_cache_impl_pointcloud.cc
index a43b23c8969..ddbfe232361 100644
--- a/source/blender/draw/intern/draw_cache_impl_pointcloud.cc
+++ b/source/blender/draw/intern/draw_cache_impl_pointcloud.cc
@@ -7,7 +7,7 @@
* \brief PointCloud API for render engines
*/
-#include <string.h>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -23,28 +23,69 @@
#include "BKE_pointcloud.h"
#include "GPU_batch.h"
+#include "GPU_material.h"
-#include "draw_cache_impl.h" /* own include */
+#include "draw_attributes.h"
+#include "draw_cache_impl.h"
+#include "draw_cache_inline.h"
+#include "draw_pointcloud_private.hh" /* own include */
-/* ---------------------------------------------------------------------- */
-/* PointCloud GPUBatch Cache */
+using namespace blender;
-struct PointCloudBatchCache {
- GPUVertBuf *pos; /* Position and radius. */
- GPUVertBuf *geom; /* Instanced geometry for each point in the cloud (small sphere). */
- GPUIndexBuf *geom_indices;
+/** \} */
+/* -------------------------------------------------------------------- */
+/** \name GPUBatch cache management
+ * \{ */
+
+struct PointCloudEvalCache {
+ /* Dot primitive types. */
GPUBatch *dots;
+ /* Triangle primitive types. */
GPUBatch *surface;
GPUBatch **surface_per_mat;
- /* settings to determine if cache is invalid */
- bool is_dirty;
+ /* Triangles indices to draw the points. */
+ GPUIndexBuf *geom_indices;
+
+ /* Position and radius. */
+ GPUVertBuf *pos_rad;
+ /* Active attribute in 3D view. */
+ GPUVertBuf *attr_viewer;
+ /* Requested attributes */
+ GPUVertBuf *attributes_buf[GPU_MAX_ATTR];
+
+ /** Attributes currently being drawn or about to be drawn. */
+ DRW_Attributes attr_used;
+ /**
+ * Attributes that were used at some point. This is used for garbage collection, to remove
+ * attributes that are not used in shaders anymore due to user edits.
+ */
+ DRW_Attributes attr_used_over_time;
+
+ /**
+ * The last time in seconds that the `attr_used` and `attr_used_over_time` were exactly the same.
+ * If the delta between this time and the current scene time is greater than the timeout set in
+ * user preferences (`U.vbotimeout`) then garbage collection is performed.
+ */
+ int last_attr_matching_time;
int mat_len;
};
-/* GPUBatch cache management. */
+struct PointCloudBatchCache {
+ PointCloudEvalCache eval_cache;
+
+ /* settings to determine if cache is invalid */
+ bool is_dirty;
+
+ /**
+ * The draw cache extraction is currently not multi-threaded for multiple objects, but if it was,
+ * some locking would be necessary because multiple objects can use the same object data with
+ * different materials, etc. This is a placeholder to make multi-threading easier in the future.
+ */
+ std::mutex render_mutex;
+};
static PointCloudBatchCache *pointcloud_batch_cache_get(PointCloud &pointcloud)
{
@@ -58,7 +99,7 @@ static bool pointcloud_batch_cache_valid(PointCloud &pointcloud)
if (cache == nullptr) {
return false;
}
- if (cache->mat_len != DRW_pointcloud_material_count_get(&pointcloud)) {
+ if (cache->eval_cache.mat_len != DRW_pointcloud_material_count_get(&pointcloud)) {
return false;
}
return cache->is_dirty == false;
@@ -69,16 +110,16 @@ static void pointcloud_batch_cache_init(PointCloud &pointcloud)
PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud);
if (!cache) {
- cache = MEM_cnew<PointCloudBatchCache>(__func__);
+ cache = MEM_new<PointCloudBatchCache>(__func__);
pointcloud.batch_cache = cache;
}
else {
- memset(cache, 0, sizeof(*cache));
+ cache->eval_cache = {};
}
- cache->mat_len = DRW_pointcloud_material_count_get(&pointcloud);
- cache->surface_per_mat = static_cast<GPUBatch **>(
- MEM_callocN(sizeof(GPUBatch *) * cache->mat_len, __func__));
+ cache->eval_cache.mat_len = DRW_pointcloud_material_count_get(&pointcloud);
+ cache->eval_cache.surface_per_mat = static_cast<GPUBatch **>(
+ MEM_callocN(sizeof(GPUBatch *) * cache->eval_cache.mat_len, __func__));
cache->is_dirty = false;
}
@@ -98,6 +139,15 @@ void DRW_pointcloud_batch_cache_dirty_tag(PointCloud *pointcloud, int mode)
}
}
+static void pointcloud_discard_attributes(PointCloudBatchCache &cache)
+{
+ for (const int j : IndexRange(GPU_MAX_ATTR)) {
+ GPU_VERTBUF_DISCARD_SAFE(cache.eval_cache.attributes_buf[j]);
+ }
+
+ drw_attributes_clear(&cache.eval_cache.attr_used);
+}
+
static void pointcloud_batch_cache_clear(PointCloud &pointcloud)
{
PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud);
@@ -105,18 +155,20 @@ static void pointcloud_batch_cache_clear(PointCloud &pointcloud)
return;
}
- GPU_BATCH_DISCARD_SAFE(cache->dots);
- GPU_BATCH_DISCARD_SAFE(cache->surface);
- GPU_VERTBUF_DISCARD_SAFE(cache->pos);
- GPU_VERTBUF_DISCARD_SAFE(cache->geom);
- GPU_INDEXBUF_DISCARD_SAFE(cache->geom_indices);
+ GPU_BATCH_DISCARD_SAFE(cache->eval_cache.dots);
+ GPU_BATCH_DISCARD_SAFE(cache->eval_cache.surface);
+ GPU_VERTBUF_DISCARD_SAFE(cache->eval_cache.pos_rad);
+ GPU_VERTBUF_DISCARD_SAFE(cache->eval_cache.attr_viewer);
+ GPU_INDEXBUF_DISCARD_SAFE(cache->eval_cache.geom_indices);
- if (cache->surface_per_mat) {
- for (int i = 0; i < cache->mat_len; i++) {
- GPU_BATCH_DISCARD_SAFE(cache->surface_per_mat[i]);
+ if (cache->eval_cache.surface_per_mat) {
+ for (int i = 0; i < cache->eval_cache.mat_len; i++) {
+ GPU_BATCH_DISCARD_SAFE(cache->eval_cache.surface_per_mat[i]);
}
}
- MEM_SAFE_FREE(cache->surface_per_mat);
+ MEM_SAFE_FREE(cache->eval_cache.surface_per_mat);
+
+ pointcloud_discard_attributes(*cache);
}
void DRW_pointcloud_batch_cache_validate(PointCloud *pointcloud)
@@ -133,32 +185,86 @@ void DRW_pointcloud_batch_cache_free(PointCloud *pointcloud)
MEM_SAFE_FREE(pointcloud->batch_cache);
}
-static void pointcloud_batch_cache_ensure_pos(const PointCloud &pointcloud,
- PointCloudBatchCache &cache)
+void DRW_pointcloud_batch_cache_free_old(PointCloud *pointcloud, int ctime)
{
- using namespace blender;
- if (cache.pos != nullptr) {
+ PointCloudBatchCache *cache = pointcloud_batch_cache_get(*pointcloud);
+ if (!cache) {
return;
}
+ bool do_discard = false;
+
+ if (drw_attributes_overlap(&cache->eval_cache.attr_used_over_time,
+ &cache->eval_cache.attr_used)) {
+ cache->eval_cache.last_attr_matching_time = ctime;
+ }
+
+ if (ctime - cache->eval_cache.last_attr_matching_time > U.vbotimeout) {
+ do_discard = true;
+ }
+
+ drw_attributes_clear(&cache->eval_cache.attr_used_over_time);
+
+ if (do_discard) {
+ pointcloud_discard_attributes(*cache);
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name PointCloud extraction
+ * \{ */
+
+static const uint half_octahedron_tris[4][3] = {
+ {0, 1, 2},
+ {0, 2, 3},
+ {0, 3, 4},
+ {0, 4, 1},
+};
+
+static void pointcloud_extract_indices(const PointCloud &pointcloud, PointCloudBatchCache &cache)
+{
+ /** \note: Avoid modulo by non-power-of-two in shader. */
+ uint32_t vertid_max = pointcloud.totpoint * 32;
+ uint32_t index_len = pointcloud.totpoint * ARRAY_SIZE(half_octahedron_tris);
+
+ GPUIndexBufBuilder builder;
+ GPU_indexbuf_init(&builder, GPU_PRIM_TRIS, index_len, vertid_max);
+
+ for (int p = 0; p < pointcloud.totpoint; p++) {
+ for (int i = 0; i < ARRAY_SIZE(half_octahedron_tris); i++) {
+ GPU_indexbuf_add_tri_verts(&builder,
+ half_octahedron_tris[i][0] + p * 32,
+ half_octahedron_tris[i][1] + p * 32,
+ half_octahedron_tris[i][2] + p * 32);
+ }
+ }
+
+ GPU_indexbuf_build_in_place(&builder, cache.eval_cache.geom_indices);
+}
+
+static void pointcloud_extract_position_and_radius(const PointCloud &pointcloud,
+ PointCloudBatchCache &cache)
+{
+ using namespace blender;
+
const bke::AttributeAccessor attributes = pointcloud.attributes();
const VArraySpan<float3> positions = attributes.lookup<float3>("position", ATTR_DOMAIN_POINT);
const VArray<float> radii = attributes.lookup<float>("radius", ATTR_DOMAIN_POINT);
- /* From the opengl wiki:
- * Note that size does not have to exactly match the size used by the vertex shader. If the
- * vertex shader has fewer components than the attribute provides, then the extras are ignored.
- * If the vertex shader has more components than the array provides, the extras are given
- * values from the vector (0, 0, 0, 1) for the missing XYZW components. */
+ static GPUVertFormat format = {0};
+ if (format.attr_len == 0) {
+ GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ }
+
+ GPUUsageType usage_flag = GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY;
+ GPU_vertbuf_init_with_format_ex(cache.eval_cache.pos_rad, &format, usage_flag);
+
+ GPU_vertbuf_data_alloc(cache.eval_cache.pos_rad, positions.size());
+ MutableSpan<float4> vbo_data{
+ static_cast<float4 *>(GPU_vertbuf_get_data(cache.eval_cache.pos_rad)), pointcloud.totpoint};
if (radii) {
- static GPUVertFormat format = {0};
- if (format.attr_len == 0) {
- GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- }
- cache.pos = GPU_vertbuf_create_with_format(&format);
- GPU_vertbuf_data_alloc(cache.pos, positions.size());
const VArraySpan<float> radii_span(radii);
- MutableSpan<float4> vbo_data{static_cast<float4 *>(GPU_vertbuf_get_data(cache.pos)),
- pointcloud.totpoint};
threading::parallel_for(vbo_data.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
vbo_data[i].x = positions[i].x;
@@ -170,113 +276,183 @@ static void pointcloud_batch_cache_ensure_pos(const PointCloud &pointcloud,
});
}
else {
- static GPUVertFormat format = {0};
- static uint pos;
- if (format.attr_len == 0) {
- pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- }
- cache.pos = GPU_vertbuf_create_with_format(&format);
- GPU_vertbuf_data_alloc(cache.pos, positions.size());
- GPU_vertbuf_attr_fill(cache.pos, pos, positions.data());
+ threading::parallel_for(vbo_data.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ vbo_data[i].x = positions[i].x;
+ vbo_data[i].y = positions[i].y;
+ vbo_data[i].z = positions[i].z;
+ vbo_data[i].w = 1.0f;
+ }
+ });
}
}
-static const float half_octahedron_normals[5][3] = {
- {0.0f, 0.0f, 1.0f},
- {1.0f, 0.0f, 0.0f},
- {0.0f, 1.0f, 0.0f},
- {-1.0f, 0.0f, 0.0f},
- {0.0f, -1.0f, 0.0f},
-};
+static void pointcloud_extract_attribute(const PointCloud &pointcloud,
+ PointCloudBatchCache &cache,
+ const DRW_AttributeRequest &request,
+ int index)
+{
+ using namespace blender;
-static const uint half_octahedron_tris[4][3] = {
- {0, 1, 2},
- {0, 2, 3},
- {0, 3, 4},
- {0, 4, 1},
-};
+ GPUVertBuf *&attr_buf = cache.eval_cache.attributes_buf[index];
-static void pointcloud_batch_cache_ensure_geom(PointCloudBatchCache &cache)
-{
- if (cache.geom != nullptr) {
- return;
- }
+ const bke::AttributeAccessor attributes = pointcloud.attributes();
+
+ /* TODO(@kevindietrich): float4 is used for scalar attributes as the implicit conversion done
+ * by OpenGL to vec4 for a scalar `s` will produce a `vec4(s, 0, 0, 1)`. However, following
+ * the Blender convention, it should be `vec4(s, s, s, 1)`. This could be resolved using a
+ * similar texture state swizzle to map the attribute correctly as for volume attributes, so we
+ * can control the conversion ourselves. */
+ VArray<ColorGeometry4f> attribute = attributes.lookup_or_default<ColorGeometry4f>(
+ request.attribute_name, request.domain, {0.0f, 0.0f, 0.0f, 1.0f});
static GPUVertFormat format = {0};
- static uint pos;
if (format.attr_len == 0) {
- pos = GPU_vertformat_attr_add(&format, "pos_inst", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- GPU_vertformat_alias_add(&format, "nor");
+ GPU_vertformat_attr_add(&format, "attr", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
}
+ GPUUsageType usage_flag = GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY;
+ GPU_vertbuf_init_with_format_ex(attr_buf, &format, usage_flag);
+ GPU_vertbuf_data_alloc(attr_buf, pointcloud.totpoint);
- cache.geom = GPU_vertbuf_create_with_format(&format);
- GPU_vertbuf_data_alloc(cache.geom, ARRAY_SIZE(half_octahedron_normals));
-
- GPU_vertbuf_attr_fill(cache.geom, pos, half_octahedron_normals);
+ MutableSpan<ColorGeometry4f> vbo_data{
+ static_cast<ColorGeometry4f *>(GPU_vertbuf_get_data(attr_buf)), pointcloud.totpoint};
+ attribute.materialize(vbo_data);
+}
- GPUIndexBufBuilder builder;
- GPU_indexbuf_init(&builder,
- GPU_PRIM_TRIS,
- ARRAY_SIZE(half_octahedron_tris),
- ARRAY_SIZE(half_octahedron_normals));
+/** \} */
- for (int i = 0; i < ARRAY_SIZE(half_octahedron_tris); i++) {
- GPU_indexbuf_add_tri_verts(&builder, UNPACK3(half_octahedron_tris[i]));
- }
+/* -------------------------------------------------------------------- */
+/** \name Private API
+ * \{ */
- cache.geom_indices = GPU_indexbuf_build(&builder);
+GPUVertBuf *pointcloud_position_and_radius_get(PointCloud *pointcloud)
+{
+ PointCloudBatchCache *cache = pointcloud_batch_cache_get(*pointcloud);
+ DRW_vbo_request(nullptr, &cache->eval_cache.pos_rad);
+ return cache->eval_cache.pos_rad;
}
-GPUBatch *DRW_pointcloud_batch_cache_get_dots(Object *ob)
+GPUBatch **pointcloud_surface_shaded_get(PointCloud *pointcloud,
+ GPUMaterial **gpu_materials,
+ int mat_len)
{
- PointCloud &pointcloud = *static_cast<PointCloud *>(ob->data);
- PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud);
+ PointCloudBatchCache *cache = pointcloud_batch_cache_get(*pointcloud);
+ DRW_Attributes attrs_needed;
+ drw_attributes_clear(&attrs_needed);
+
+ for (GPUMaterial *gpu_material : Span<GPUMaterial *>(gpu_materials, mat_len)) {
+ ListBase gpu_attrs = GPU_material_attributes(gpu_material);
+ LISTBASE_FOREACH (GPUMaterialAttribute *, gpu_attr, &gpu_attrs) {
+ const char *name = gpu_attr->name;
+
+ int layer_index;
+ eCustomDataType type;
+ eAttrDomain domain = ATTR_DOMAIN_POINT;
+ if (!drw_custom_data_match_attribute(&pointcloud->pdata, name, &layer_index, &type)) {
+ continue;
+ }
+
+ drw_attributes_add_request(&attrs_needed, name, type, layer_index, domain);
+ }
+ }
- if (cache->dots == nullptr) {
- pointcloud_batch_cache_ensure_pos(pointcloud, *cache);
- cache->dots = GPU_batch_create(GPU_PRIM_POINTS, cache->pos, nullptr);
+ if (!drw_attributes_overlap(&cache->eval_cache.attr_used, &attrs_needed)) {
+ /* Some new attributes have been added, free all and start over. */
+ for (const int i : IndexRange(GPU_MAX_ATTR)) {
+ GPU_VERTBUF_DISCARD_SAFE(cache->eval_cache.attributes_buf[i]);
+ }
+ drw_attributes_merge(&cache->eval_cache.attr_used, &attrs_needed, cache->render_mutex);
}
+ drw_attributes_merge(&cache->eval_cache.attr_used_over_time, &attrs_needed, cache->render_mutex);
- return cache->dots;
+ DRW_batch_request(&cache->eval_cache.surface_per_mat[0]);
+ return cache->eval_cache.surface_per_mat;
}
-GPUBatch *DRW_pointcloud_batch_cache_get_surface(Object *ob)
+GPUBatch *pointcloud_surface_get(PointCloud *pointcloud)
{
- PointCloud &pointcloud = *static_cast<PointCloud *>(ob->data);
- PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud);
-
- if (cache->surface == nullptr) {
- pointcloud_batch_cache_ensure_pos(pointcloud, *cache);
- pointcloud_batch_cache_ensure_geom(*cache);
+ PointCloudBatchCache *cache = pointcloud_batch_cache_get(*pointcloud);
+ return DRW_batch_request(&cache->eval_cache.surface);
+}
- cache->surface = GPU_batch_create(GPU_PRIM_TRIS, cache->geom, cache->geom_indices);
- GPU_batch_instbuf_add_ex(cache->surface, cache->pos, false);
- }
+/** \} */
- return cache->surface;
-}
+/* -------------------------------------------------------------------- */
+/** \name API
+ * \{ */
-GPUBatch **DRW_cache_pointcloud_surface_shaded_get(Object *ob,
- struct GPUMaterial **UNUSED(gpumat_array),
- uint gpumat_array_len)
+GPUBatch *DRW_pointcloud_batch_cache_get_dots(Object *ob)
{
PointCloud &pointcloud = *static_cast<PointCloud *>(ob->data);
PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud);
- BLI_assert(cache->mat_len == gpumat_array_len);
- UNUSED_VARS(gpumat_array_len);
-
- if (cache->surface_per_mat[0] == nullptr) {
- pointcloud_batch_cache_ensure_pos(pointcloud, *cache);
- pointcloud_batch_cache_ensure_geom(*cache);
+ return DRW_batch_request(&cache->eval_cache.dots);
+}
- cache->surface_per_mat[0] = GPU_batch_create(GPU_PRIM_TRIS, cache->geom, cache->geom_indices);
- GPU_batch_instbuf_add_ex(cache->surface_per_mat[0], cache->pos, false);
+GPUVertBuf **DRW_pointcloud_evaluated_attribute(PointCloud *pointcloud, const char *name)
+{
+ PointCloudBatchCache &cache = *pointcloud_batch_cache_get(*pointcloud);
+
+ int layer_index;
+ eCustomDataType type;
+ eAttrDomain domain = ATTR_DOMAIN_POINT;
+ if (drw_custom_data_match_attribute(&pointcloud->pdata, name, &layer_index, &type)) {
+ DRW_Attributes attributes{};
+ drw_attributes_add_request(&attributes, name, type, layer_index, domain);
+ drw_attributes_merge(&cache.eval_cache.attr_used, &attributes, cache.render_mutex);
}
- return cache->surface_per_mat;
+ int request_i = -1;
+ for (const int i : IndexRange(cache.eval_cache.attr_used.num_requests)) {
+ if (STREQ(cache.eval_cache.attr_used.requests[i].attribute_name, name)) {
+ request_i = i;
+ break;
+ }
+ }
+ if (request_i == -1) {
+ return nullptr;
+ }
+ return &cache.eval_cache.attributes_buf[request_i];
}
int DRW_pointcloud_material_count_get(PointCloud *pointcloud)
{
return max_ii(1, pointcloud->totcol);
}
+
+void DRW_pointcloud_batch_cache_create_requested(Object *ob)
+{
+ PointCloud *pointcloud = static_cast<PointCloud *>(ob->data);
+ PointCloudBatchCache &cache = *pointcloud_batch_cache_get(*pointcloud);
+
+ if (DRW_batch_requested(cache.eval_cache.dots, GPU_PRIM_POINTS)) {
+ DRW_vbo_request(cache.eval_cache.dots, &cache.eval_cache.pos_rad);
+ }
+
+ if (DRW_batch_requested(cache.eval_cache.surface, GPU_PRIM_TRIS)) {
+ DRW_ibo_request(cache.eval_cache.surface, &cache.eval_cache.geom_indices);
+ DRW_vbo_request(cache.eval_cache.surface, &cache.eval_cache.pos_rad);
+ }
+ for (int i = 0; i < cache.eval_cache.mat_len; i++) {
+ if (DRW_batch_requested(cache.eval_cache.surface_per_mat[i], GPU_PRIM_TRIS)) {
+ /* TODO(fclem): Per material ranges. */
+ DRW_ibo_request(cache.eval_cache.surface_per_mat[i], &cache.eval_cache.geom_indices);
+ }
+ }
+ for (int j = 0; j < cache.eval_cache.attr_used.num_requests; j++) {
+ DRW_vbo_request(nullptr, &cache.eval_cache.attributes_buf[j]);
+
+ if (DRW_vbo_requested(cache.eval_cache.attributes_buf[j])) {
+ pointcloud_extract_attribute(*pointcloud, cache, cache.eval_cache.attr_used.requests[j], j);
+ }
+ }
+
+ if (DRW_ibo_requested(cache.eval_cache.geom_indices)) {
+ pointcloud_extract_indices(*pointcloud, cache);
+ }
+
+ if (DRW_vbo_requested(cache.eval_cache.pos_rad)) {
+ pointcloud_extract_position_and_radius(*pointcloud, cache);
+ }
+}
+
+/** \} */
diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc
index ab935809f96..6a9e6c126e9 100644
--- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc
+++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc
@@ -361,14 +361,14 @@ static GPUVertFormat *get_subdiv_vertex_format()
struct CompressedPatchCoord {
int ptex_face_index;
/* UV coordinate encoded as u << 16 | v, where u and v are quantized on 16-bits. */
- unsigned int encoded_uv;
+ uint encoded_uv;
};
MINLINE CompressedPatchCoord make_patch_coord(int ptex_face_index, float u, float v)
{
CompressedPatchCoord patch_coord = {
ptex_face_index,
- (static_cast<unsigned int>(u * 65535.0f) << 16) | static_cast<unsigned int>(v * 65535.0f),
+ (uint(u * 65535.0f) << 16) | uint(v * 65535.0f),
};
return patch_coord;
}
@@ -635,17 +635,9 @@ void draw_subdiv_cache_free(DRWSubdivCache *cache)
SUBDIV_COARSE_FACE_FLAG_ACTIVE | SUBDIV_COARSE_FACE_FLAG_HIDDEN) \
<< SUBDIV_COARSE_FACE_FLAG_OFFSET)
-static uint32_t compute_coarse_face_flag(BMFace *f, BMFace *efa_act)
+static uint32_t compute_coarse_face_flag_bm(BMFace *f, BMFace *efa_act)
{
- if (f == nullptr) {
- /* May happen during mapped extraction. */
- return 0;
- }
-
uint32_t flag = 0;
- if (BM_elem_flag_test(f, BM_ELEM_SMOOTH)) {
- flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH;
- }
if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
flag |= SUBDIV_COARSE_FACE_FLAG_SELECT;
}
@@ -655,8 +647,7 @@ static uint32_t compute_coarse_face_flag(BMFace *f, BMFace *efa_act)
if (f == efa_act) {
flag |= SUBDIV_COARSE_FACE_FLAG_ACTIVE;
}
- const int loopstart = BM_elem_index_get(f->l_first);
- return (uint)(loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
+ return flag;
}
static void draw_subdiv_cache_extra_coarse_face_data_bm(BMesh *bm,
@@ -668,7 +659,12 @@ static void draw_subdiv_cache_extra_coarse_face_data_bm(BMesh *bm,
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
const int index = BM_elem_index_get(f);
- flags_data[index] = compute_coarse_face_flag(f, efa_act);
+ uint32_t flag = compute_coarse_face_flag_bm(f, efa_act);
+ if (BM_elem_flag_test(f, BM_ELEM_SMOOTH)) {
+ flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH;
+ }
+ const int loopstart = BM_elem_index_get(f->l_first);
+ flags_data[index] = uint(loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
}
}
@@ -682,13 +678,13 @@ static void draw_subdiv_cache_extra_coarse_face_data_mesh(const MeshRenderData *
if ((polys[i].flag & ME_SMOOTH) != 0) {
flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH;
}
- if ((polys[i].flag & ME_FACE_SEL) != 0) {
+ if (mr->select_poly && mr->select_poly[i]) {
flag |= SUBDIV_COARSE_FACE_FLAG_SELECT;
}
if (mr->hide_poly && mr->hide_poly[i]) {
flag |= SUBDIV_COARSE_FACE_FLAG_HIDDEN;
}
- flags_data[i] = (uint)(polys[i].loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
+ flags_data[i] = uint(polys[i].loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
}
}
@@ -702,9 +698,16 @@ static void draw_subdiv_cache_extra_coarse_face_data_mapped(Mesh *mesh,
return;
}
- for (int i = 0; i < mesh->totpoly; i++) {
+ const Span<MPoly> polys = mesh->polys();
+ for (const int i : polys.index_range()) {
BMFace *f = bm_original_face_get(mr, i);
- flags_data[i] = compute_coarse_face_flag(f, mr->efa_act);
+ /* Selection and hiding from bmesh. */
+ uint32_t flag = (f) ? compute_coarse_face_flag_bm(f, mr->efa_act) : 0;
+ /* Smooth from mesh. */
+ if ((polys[i].flag & ME_SMOOTH) != 0) {
+ flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH;
+ }
+ flags_data[i] = uint(polys[i].loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
}
}
@@ -724,7 +727,7 @@ static void draw_subdiv_cache_update_extra_coarse_face_data(DRWSubdivCache *cach
mesh->totpoly);
}
- uint32_t *flags_data = (uint32_t *)(GPU_vertbuf_get_data(cache->extra_coarse_face_data));
+ uint32_t *flags_data = (uint32_t *)GPU_vertbuf_get_data(cache->extra_coarse_face_data);
if (mr->extract_type == MR_EXTRACT_BMESH) {
draw_subdiv_cache_extra_coarse_face_data_bm(cache->bm, mr->efa_act, flags_data);
@@ -825,10 +828,10 @@ static bool draw_subdiv_topology_info_cb(const SubdivForeachContext *foreach_con
/* Set topology information only if we have loops. */
if (num_loops != 0) {
- cache->num_subdiv_edges = (uint)num_edges;
- cache->num_subdiv_loops = (uint)num_loops;
- cache->num_subdiv_verts = (uint)num_verts;
- cache->num_subdiv_quads = (uint)num_polys;
+ cache->num_subdiv_edges = uint(num_edges);
+ cache->num_subdiv_loops = uint(num_loops);
+ cache->num_subdiv_verts = uint(num_verts);
+ cache->num_subdiv_quads = uint(num_polys);
cache->subdiv_polygon_offset = static_cast<int *>(MEM_dupallocN(subdiv_polygon_offset));
}
@@ -900,13 +903,13 @@ static bool draw_subdiv_topology_info_cb(const SubdivForeachContext *foreach_con
}
static void draw_subdiv_vertex_corner_cb(const SubdivForeachContext *foreach_context,
- void *UNUSED(tls),
- const int UNUSED(ptex_face_index),
- const float UNUSED(u),
- const float UNUSED(v),
+ void * /*tls*/,
+ const int /*ptex_face_index*/,
+ const float /*u*/,
+ const float /*v*/,
const int coarse_vertex_index,
- const int UNUSED(coarse_poly_index),
- const int UNUSED(coarse_corner),
+ const int /*coarse_poly_index*/,
+ const int /*coarse_corner*/,
const int subdiv_vertex_index)
{
BLI_assert(coarse_vertex_index != ORIGINDEX_NONE);
@@ -914,26 +917,26 @@ static void draw_subdiv_vertex_corner_cb(const SubdivForeachContext *foreach_con
ctx->vert_origindex_map[subdiv_vertex_index] = coarse_vertex_index;
}
-static void draw_subdiv_vertex_edge_cb(const SubdivForeachContext *UNUSED(foreach_context),
- void *UNUSED(tls_v),
- const int UNUSED(ptex_face_index),
- const float UNUSED(u),
- const float UNUSED(v),
- const int UNUSED(coarse_edge_index),
- const int UNUSED(coarse_poly_index),
- const int UNUSED(coarse_corner),
- const int UNUSED(subdiv_vertex_index))
+static void draw_subdiv_vertex_edge_cb(const SubdivForeachContext * /*foreach_context*/,
+ void * /*tls_v*/,
+ const int /*ptex_face_index*/,
+ const float /*u*/,
+ const float /*v*/,
+ const int /*coarse_edge_index*/,
+ const int /*coarse_poly_index*/,
+ const int /*coarse_corner*/,
+ const int /*subdiv_vertex_index*/)
{
/* Required if SubdivForeachContext.vertex_corner is also set. */
}
static void draw_subdiv_edge_cb(const SubdivForeachContext *foreach_context,
- void *UNUSED(tls),
+ void * /*tls*/,
const int coarse_edge_index,
const int subdiv_edge_index,
- const bool UNUSED(is_loose),
- const int UNUSED(subdiv_v1),
- const int UNUSED(subdiv_v2))
+ const bool /*is_loose*/,
+ const int /*subdiv_v1*/,
+ const int /*subdiv_v2*/)
{
DRWCacheBuildingContext *ctx = (DRWCacheBuildingContext *)(foreach_context->user_data);
@@ -953,13 +956,13 @@ static void draw_subdiv_edge_cb(const SubdivForeachContext *foreach_context,
}
static void draw_subdiv_loop_cb(const SubdivForeachContext *foreach_context,
- void *UNUSED(tls_v),
+ void * /*tls_v*/,
const int ptex_face_index,
const float u,
const float v,
- const int UNUSED(coarse_loop_index),
+ const int /*coarse_loop_index*/,
const int coarse_poly_index,
- const int UNUSED(coarse_corner),
+ const int /*coarse_corner*/,
const int subdiv_loop_index,
const int subdiv_vertex_index,
const int subdiv_edge_index)
@@ -1292,7 +1295,7 @@ static void drw_subdiv_compute_dispatch(const DRWSubdivCache *cache,
uint total_dispatch_size,
const bool has_sculpt_mask = false)
{
- const uint max_res_x = static_cast<uint>(GPU_max_work_group_count(0));
+ const uint max_res_x = uint(GPU_max_work_group_count(0));
const uint dispatch_size = get_dispatch_size(total_dispatch_size);
uint dispatch_rx = dispatch_size;
@@ -1315,7 +1318,7 @@ static void drw_subdiv_compute_dispatch(const DRWSubdivCache *cache,
/* X and Y dimensions may have different limits so the above computation may not be right, but
* even with the standard 64k minimum on all dimensions we still have a lot of room. Therefore,
* we presume it all fits. */
- BLI_assert(dispatch_ry < static_cast<uint>(GPU_max_work_group_count(1)));
+ BLI_assert(dispatch_ry < uint(GPU_max_work_group_count(1)));
draw_subdiv_ubo_update_and_bind(
cache, shader, src_offset, dst_offset, total_dispatch_size, has_sculpt_mask);
@@ -2033,7 +2036,7 @@ static bool draw_subdiv_create_requested_buffers(Object *ob,
const bool use_hide,
OpenSubdiv_EvaluatorCache *evaluator_cache)
{
- SubsurfRuntimeData *runtime_data = mesh->runtime.subsurf_runtime_data;
+ SubsurfRuntimeData *runtime_data = mesh->runtime->subsurf_runtime_data;
BLI_assert(runtime_data && runtime_data->has_gpu_subdiv);
if (runtime_data->settings.level == 0) {
@@ -2134,7 +2137,7 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac
const bool is_simple = subdiv_cache->subdiv->settings.is_simple;
const int resolution = subdiv_cache->resolution;
const int resolution_1 = resolution - 1;
- const float inv_resolution_1 = 1.0f / (float)resolution_1;
+ const float inv_resolution_1 = 1.0f / float(resolution_1);
const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
const int num_subdivided_edge = coarse_loose_edge_len *
@@ -2228,13 +2231,13 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac
blender::Span<DRWSubdivLooseEdge> draw_subdiv_cache_get_loose_edges(const DRWSubdivCache *cache)
{
- return {cache->loose_geom.edges, static_cast<int64_t>(cache->loose_geom.edge_len)};
+ return {cache->loose_geom.edges, int64_t(cache->loose_geom.edge_len)};
}
blender::Span<DRWSubdivLooseVertex> draw_subdiv_cache_get_loose_verts(const DRWSubdivCache *cache)
{
return {cache->loose_geom.verts + cache->loose_geom.edge_len * 2,
- static_cast<int64_t>(cache->loose_geom.vert_len)};
+ int64_t(cache->loose_geom.vert_len)};
}
static OpenSubdiv_EvaluatorCache *g_evaluator_cache = nullptr;
diff --git a/source/blender/draw/intern/draw_cache_impl_volume.c b/source/blender/draw/intern/draw_cache_impl_volume.cc
index 18a4c81514b..ac5e6fa05b9 100644
--- a/source/blender/draw/intern/draw_cache_impl_volume.c
+++ b/source/blender/draw/intern/draw_cache_impl_volume.cc
@@ -7,7 +7,7 @@
* \brief Volume API for render engines
*/
-#include <string.h>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -39,7 +39,7 @@ static void volume_batch_cache_clear(Volume *volume);
/* ---------------------------------------------------------------------- */
/* Volume GPUBatch Cache */
-typedef struct VolumeBatchCache {
+struct VolumeBatchCache {
/* 3D textures */
ListBase grids;
@@ -54,22 +54,22 @@ typedef struct VolumeBatchCache {
/* settings to determine if cache is invalid */
bool is_dirty;
-} VolumeBatchCache;
+};
/* GPUBatch cache management. */
static bool volume_batch_cache_valid(Volume *volume)
{
- VolumeBatchCache *cache = volume->batch_cache;
+ VolumeBatchCache *cache = static_cast<VolumeBatchCache *>(volume->batch_cache);
return (cache && cache->is_dirty == false);
}
static void volume_batch_cache_init(Volume *volume)
{
- VolumeBatchCache *cache = volume->batch_cache;
+ VolumeBatchCache *cache = static_cast<VolumeBatchCache *>(volume->batch_cache);
if (!cache) {
- cache = volume->batch_cache = MEM_callocN(sizeof(*cache), __func__);
+ volume->batch_cache = cache = MEM_cnew<VolumeBatchCache>(__func__);
}
else {
memset(cache, 0, sizeof(*cache));
@@ -89,13 +89,13 @@ void DRW_volume_batch_cache_validate(Volume *volume)
static VolumeBatchCache *volume_batch_cache_get(Volume *volume)
{
DRW_volume_batch_cache_validate(volume);
- return volume->batch_cache;
+ return static_cast<VolumeBatchCache *>(volume->batch_cache);
}
void DRW_volume_batch_cache_dirty_tag(Volume *volume, int mode)
{
- VolumeBatchCache *cache = volume->batch_cache;
- if (cache == NULL) {
+ VolumeBatchCache *cache = static_cast<VolumeBatchCache *>(volume->batch_cache);
+ if (cache == nullptr) {
return;
}
switch (mode) {
@@ -109,7 +109,7 @@ void DRW_volume_batch_cache_dirty_tag(Volume *volume, int mode)
static void volume_batch_cache_clear(Volume *volume)
{
- VolumeBatchCache *cache = volume->batch_cache;
+ VolumeBatchCache *cache = static_cast<VolumeBatchCache *>(volume->batch_cache);
if (!cache) {
return;
}
@@ -130,18 +130,18 @@ void DRW_volume_batch_cache_free(Volume *volume)
volume_batch_cache_clear(volume);
MEM_SAFE_FREE(volume->batch_cache);
}
-typedef struct VolumeWireframeUserData {
+struct VolumeWireframeUserData {
Volume *volume;
Scene *scene;
-} VolumeWireframeUserData;
+};
static void drw_volume_wireframe_cb(
void *userdata, const float (*verts)[3], const int (*edges)[2], int totvert, int totedge)
{
- VolumeWireframeUserData *data = userdata;
+ VolumeWireframeUserData *data = static_cast<VolumeWireframeUserData *>(userdata);
Scene *scene = data->scene;
Volume *volume = data->volume;
- VolumeBatchCache *cache = volume->batch_cache;
+ VolumeBatchCache *cache = static_cast<VolumeBatchCache *>(volume->batch_cache);
const bool do_hq_normals = (scene->r.perf_flag & SCE_PERF_HQ_NORMALS) != 0 ||
GPU_use_hq_normals_workaround();
@@ -181,7 +181,7 @@ static void drw_volume_wireframe_cb(
if (volume->display.wireframe_type == VOLUME_WIREFRAME_POINTS) {
/* Create batch. */
cache->face_wire.batch = GPU_batch_create(
- GPU_PRIM_POINTS, cache->face_wire.pos_nor_in_order, NULL);
+ GPU_PRIM_POINTS, cache->face_wire.pos_nor_in_order, nullptr);
}
else {
/* Create edge index buffer. */
@@ -203,15 +203,15 @@ static void drw_volume_wireframe_cb(
GPUBatch *DRW_volume_batch_cache_get_wireframes_face(Volume *volume)
{
if (volume->display.wireframe_type == VOLUME_WIREFRAME_NONE) {
- return NULL;
+ return nullptr;
}
VolumeBatchCache *cache = volume_batch_cache_get(volume);
- if (cache->face_wire.batch == NULL) {
+ if (cache->face_wire.batch == nullptr) {
const VolumeGrid *volume_grid = BKE_volume_grid_active_get_for_read(volume);
- if (volume_grid == NULL) {
- return NULL;
+ if (volume_grid == nullptr) {
+ return nullptr;
}
/* Create wireframe from OpenVDB tree. */
@@ -228,8 +228,8 @@ GPUBatch *DRW_volume_batch_cache_get_wireframes_face(Volume *volume)
static void drw_volume_selection_surface_cb(
void *userdata, float (*verts)[3], int (*tris)[3], int totvert, int tottris)
{
- Volume *volume = userdata;
- VolumeBatchCache *cache = volume->batch_cache;
+ Volume *volume = static_cast<Volume *>(userdata);
+ VolumeBatchCache *cache = static_cast<VolumeBatchCache *>(volume->batch_cache);
static GPUVertFormat format = {0};
static uint pos_id;
@@ -257,10 +257,10 @@ static void drw_volume_selection_surface_cb(
GPUBatch *DRW_volume_batch_cache_get_selection_surface(Volume *volume)
{
VolumeBatchCache *cache = volume_batch_cache_get(volume);
- if (cache->selection_surface == NULL) {
+ if (cache->selection_surface == nullptr) {
const VolumeGrid *volume_grid = BKE_volume_grid_active_get_for_read(volume);
- if (volume_grid == NULL) {
- return NULL;
+ if (volume_grid == nullptr) {
+ return nullptr;
}
BKE_volume_grid_selection_surface(
volume, volume_grid, drw_volume_selection_surface_cb, volume);
@@ -275,15 +275,14 @@ static DRWVolumeGrid *volume_grid_cache_get(const Volume *volume,
const char *name = BKE_volume_grid_name(grid);
/* Return cached grid. */
- DRWVolumeGrid *cache_grid;
- for (cache_grid = cache->grids.first; cache_grid; cache_grid = cache_grid->next) {
+ LISTBASE_FOREACH (DRWVolumeGrid *, cache_grid, &cache->grids) {
if (STREQ(cache_grid->name, name)) {
return cache_grid;
}
}
/* Allocate new grid. */
- cache_grid = MEM_callocN(sizeof(DRWVolumeGrid), __func__);
+ DRWVolumeGrid *cache_grid = MEM_cnew<DRWVolumeGrid>(__func__);
cache_grid->name = BLI_strdup(name);
BLI_addtail(&cache->grids, cache_grid);
@@ -316,7 +315,7 @@ static DRWVolumeGrid *volume_grid_cache_get(const Volume *volume,
dense_grid.voxels);
/* The texture can be null if the resolution along one axis is larger than
* GL_MAX_3D_TEXTURE_SIZE. */
- if (cache_grid->texture != NULL) {
+ if (cache_grid->texture != nullptr) {
GPU_texture_swizzle_set(cache_grid->texture, (channels == 3) ? "rgb1" : "rrr1");
GPU_texture_wrap_mode(cache_grid->texture, false, false);
BKE_volume_dense_float_grid_clear(&dense_grid);
@@ -339,7 +338,7 @@ DRWVolumeGrid *DRW_volume_batch_cache_get_grid(Volume *volume, const VolumeGrid
{
VolumeBatchCache *cache = volume_batch_cache_get(volume);
DRWVolumeGrid *grid = volume_grid_cache_get(volume, volume_grid, cache);
- return (grid->texture != NULL) ? grid : NULL;
+ return (grid->texture != nullptr) ? grid : nullptr;
}
int DRW_volume_material_count_get(Volume *volume)
diff --git a/source/blender/draw/intern/draw_command.cc b/source/blender/draw/intern/draw_command.cc
index ff69885b3b6..6e999815e8d 100644
--- a/source/blender/draw/intern/draw_command.cc
+++ b/source/blender/draw/intern/draw_command.cc
@@ -30,6 +30,11 @@ void ShaderBind::execute(RecordingState &state) const
}
}
+void FramebufferBind::execute() const
+{
+ GPU_framebuffer_bind(framebuffer);
+}
+
void ResourceBind::execute() const
{
if (slot == -1) {
@@ -90,7 +95,7 @@ void DrawMulti::execute(RecordingState &state) const
DrawMultiBuf::DrawGroupBuf &groups = multi_draw_buf->group_buf_;
uint group_index = this->group_first;
- while (group_index != (uint)-1) {
+ while (group_index != uint(-1)) {
const DrawGroup &group = groups[group_index];
if (group.vertex_len > 0) {
@@ -161,7 +166,10 @@ void StateSet::execute(RecordingState &recording_state) const
*/
BLI_assert(DST.state_lock == 0);
- if (!assign_if_different(recording_state.pipeline_state, new_state)) {
+ bool state_changed = assign_if_different(recording_state.pipeline_state, new_state);
+ bool clip_changed = assign_if_different(recording_state.clip_plane_count, clip_plane_count);
+
+ if (!state_changed && !clip_changed) {
return;
}
@@ -185,12 +193,7 @@ void StateSet::execute(RecordingState &recording_state) const
}
/* TODO: this should be part of shader state. */
- if (new_state & DRW_STATE_CLIP_PLANES) {
- GPU_clip_distances(recording_state.view_clip_plane_count);
- }
- else {
- GPU_clip_distances(0);
- }
+ GPU_clip_distances(recording_state.clip_plane_count);
if (new_state & DRW_STATE_IN_FRONT_SELECT) {
/* XXX `GPU_depth_range` is not a perfect solution
@@ -229,6 +232,11 @@ std::string ShaderBind::serialize() const
return std::string(".shader_bind(") + GPU_shader_get_name(shader) + ")";
}
+std::string FramebufferBind::serialize() const
+{
+ return std::string(".framebuffer_bind(") + GPU_framebuffer_get_name(framebuffer) + ")";
+}
+
std::string ResourceBind::serialize() const
{
switch (type) {
@@ -345,9 +353,9 @@ std::string PushConstant::serialize() const
std::string Draw::serialize() const
{
- std::string inst_len = (instance_len == (uint)-1) ? "from_batch" : std::to_string(instance_len);
- std::string vert_len = (vertex_len == (uint)-1) ? "from_batch" : std::to_string(vertex_len);
- std::string vert_first = (vertex_first == (uint)-1) ? "from_batch" :
+ std::string inst_len = (instance_len == uint(-1)) ? "from_batch" : std::to_string(instance_len);
+ std::string vert_len = (vertex_len == uint(-1)) ? "from_batch" : std::to_string(vertex_len);
+ std::string vert_first = (vertex_first == uint(-1)) ? "from_batch" :
std::to_string(vertex_first);
return std::string(".draw(inst_len=") + inst_len + ", vert_len=" + vert_len +
", vert_first=" + vert_first + ", res_id=" + std::to_string(handle.resource_index()) +
@@ -379,7 +387,7 @@ std::string DrawMulti::serialize(std::string line_prefix) const
uint group_len = 0;
uint group_index = this->group_first;
- while (group_index != (uint)-1) {
+ while (group_index != uint(-1)) {
const DrawGroup &grp = groups[group_index];
ss << std::endl << line_prefix << " .group(id=" << group_index << ", len=" << grp.len << ")";
@@ -505,7 +513,7 @@ void DrawCommandBuf::bind(RecordingState &state,
* instance to set the correct resource_id. Workaround is a storage_buf + gl_InstanceID. */
BLI_assert(batch_inst_len == 1);
- if (cmd.vertex_len == (uint)-1) {
+ if (cmd.vertex_len == uint(-1)) {
cmd.vertex_len = batch_vert_len;
}
diff --git a/source/blender/draw/intern/draw_command.hh b/source/blender/draw/intern/draw_command.hh
index 46a9199a267..12c9916ee6d 100644
--- a/source/blender/draw/intern/draw_command.hh
+++ b/source/blender/draw/intern/draw_command.hh
@@ -39,7 +39,7 @@ struct RecordingState {
bool front_facing = true;
bool inverted_view = false;
DRWState pipeline_state = DRW_STATE_NO_DRAW;
- int view_clip_plane_count = 0;
+ int clip_plane_count = 0;
/** Used for gl_BaseInstance workaround. */
GPUStorageBuf *resource_id_buf = nullptr;
@@ -88,6 +88,7 @@ enum class Type : uint8_t {
DispatchIndirect,
Draw,
DrawIndirect,
+ FramebufferBind,
PushConstant,
ResourceBind,
ShaderBind,
@@ -118,6 +119,13 @@ struct ShaderBind {
std::string serialize() const;
};
+struct FramebufferBind {
+ GPUFrameBuffer *framebuffer;
+
+ void execute() const;
+ std::string serialize() const;
+};
+
struct ResourceBind {
eGPUSamplerState sampler;
int slot;
@@ -317,6 +325,7 @@ struct Clear {
struct StateSet {
DRWState new_state;
+ int clip_plane_count;
void execute(RecordingState &state) const;
std::string serialize() const;
@@ -387,7 +396,7 @@ class DrawCommandBuf {
instance_len = instance_len != -1 ? instance_len : 1;
int64_t index = commands.append_and_get_index({});
- headers.append({Type::Draw, static_cast<uint>(index)});
+ headers.append({Type::Draw, uint(index)});
commands[index].draw = {batch, instance_len, vertex_len, vertex_first, handle};
}
@@ -473,10 +482,8 @@ class DrawMultiBuf {
uint vertex_first,
ResourceHandle handle)
{
- /* Unsupported for now. Use PassSimple. */
- BLI_assert(vertex_first == 0 || vertex_first == -1);
- BLI_assert(vertex_len == -1);
- UNUSED_VARS_NDEBUG(vertex_len, vertex_first);
+ /* Custom draw-calls cannot be batched and will produce one group per draw. */
+ const bool custom_group = ((vertex_first != 0 && vertex_first != -1) || vertex_len != -1);
instance_len = instance_len != -1 ? instance_len : 1;
@@ -489,12 +496,18 @@ class DrawMultiBuf {
DrawMulti &cmd = commands.last().draw_multi;
- uint &group_id = group_ids_.lookup_or_add(DrawGroupKey(cmd.uuid, batch), (uint)-1);
+ uint &group_id = group_ids_.lookup_or_add(DrawGroupKey(cmd.uuid, batch), uint(-1));
bool inverted = handle.has_inverted_handedness();
- if (group_id == (uint)-1) {
+ DrawPrototype &draw = prototype_buf_.get_or_resize(prototype_count_++);
+ draw.resource_handle = handle.raw;
+ draw.instance_len = instance_len;
+ draw.group_id = group_id;
+
+ if (group_id == uint(-1) || custom_group) {
uint new_group_id = group_count_++;
+ draw.group_id = new_group_id;
DrawGroup &group = group_buf_.get_or_resize(new_group_id);
group.next = cmd.group_first;
@@ -503,11 +516,16 @@ class DrawMultiBuf {
group.gpu_batch = batch;
group.front_proto_len = 0;
group.back_proto_len = 0;
+ group.vertex_len = vertex_len;
+ group.vertex_first = vertex_first;
+ /* Custom group are not to be registered in the group_ids_. */
+ if (!custom_group) {
+ group_id = new_group_id;
+ }
/* For serialization only. */
(inverted ? group.back_proto_len : group.front_proto_len)++;
/* Append to list. */
cmd.group_first = new_group_id;
- group_id = new_group_id;
}
else {
DrawGroup &group = group_buf_[group_id];
@@ -516,11 +534,6 @@ class DrawMultiBuf {
/* For serialization only. */
(inverted ? group.back_proto_len : group.front_proto_len)++;
}
-
- DrawPrototype &draw = prototype_buf_.get_or_resize(prototype_count_++);
- draw.group_id = group_id;
- draw.resource_handle = handle.raw;
- draw.instance_len = instance_len;
}
void bind(RecordingState &state,
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c
index de56b34df78..f951b702403 100644
--- a/source/blender/draw/intern/draw_common.c
+++ b/source/blender/draw/intern/draw_common.c
@@ -172,20 +172,14 @@ void DRW_globals_update(void)
/* M_SQRT2 to be at least the same size of the old square */
gb->size_vertex = U.pixelsize *
- (max_ff(1.0f, UI_GetThemeValuef(TH_VERTEX_SIZE) * (float)M_SQRT2 / 2.0f));
+ max_ff(1.0f, UI_GetThemeValuef(TH_VERTEX_SIZE) * (float)M_SQRT2 / 2.0f);
gb->size_vertex_gpencil = U.pixelsize * UI_GetThemeValuef(TH_GP_VERTEX_SIZE);
gb->size_face_dot = U.pixelsize * UI_GetThemeValuef(TH_FACEDOT_SIZE);
gb->size_edge = U.pixelsize * (1.0f / 2.0f); /* TODO: Theme. */
gb->size_edge_fix = U.pixelsize * (0.5f + 2.0f * (2.0f * (gb->size_edge * (float)M_SQRT1_2)));
- const float(*screen_vecs)[3] = (float(*)[3])DRW_viewport_screenvecs_get();
- for (int i = 0; i < 2; i++) {
- copy_v3_v3(gb->screen_vecs[i], screen_vecs[i]);
- }
-
gb->pixel_fac = *DRW_viewport_pixelsize_get();
- /* Deprecated, use drw_view.viewport_size instead */
copy_v2_v2(&gb->size_viewport[0], DRW_viewport_size_get());
copy_v2_v2(&gb->size_viewport[2], &gb->size_viewport[0]);
invert_v2(&gb->size_viewport[2]);
@@ -280,10 +274,11 @@ int DRW_object_wire_theme_get(Object *ob, ViewLayer *view_layer, float **r_color
{
const DRWContextState *draw_ctx = DRW_context_state_get();
const bool is_edit = (draw_ctx->object_mode & OB_MODE_EDIT) && (ob->mode & OB_MODE_EDIT);
- const bool active = view_layer->basact &&
- ((ob->base_flag & BASE_FROM_DUPLI) ?
- (DRW_object_get_dupli_parent(ob) == view_layer->basact->object) :
- (view_layer->basact->object == ob));
+ BKE_view_layer_synced_ensure(draw_ctx->scene, view_layer);
+ const Base *base = BKE_view_layer_active_base_get(view_layer);
+ const bool active = base && ((ob->base_flag & BASE_FROM_DUPLI) ?
+ (DRW_object_get_dupli_parent(ob) == base->object) :
+ (base->object == ob));
/* confusing logic here, there are 2 methods of setting the color
* 'colortab[colindex]' and 'theme_id', colindex overrides theme_id.
diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h
index d31c98e0dee..07d245e7dfe 100644
--- a/source/blender/draw/intern/draw_common.h
+++ b/source/blender/draw/intern/draw_common.h
@@ -88,6 +88,14 @@ void DRW_curves_ubos_pool_free(struct CurvesUniformBufPool *pool);
void DRW_curves_update(void);
void DRW_curves_free(void);
+/* draw_pointcloud.cc */
+
+struct DRWShadingGroup *DRW_shgroup_pointcloud_create_sub(struct Object *object,
+ struct DRWShadingGroup *shgrp_parent,
+ struct GPUMaterial *gpu_material);
+void DRW_pointcloud_init(void);
+void DRW_pointcloud_free(void);
+
/* draw_volume.cc */
/**
@@ -132,6 +140,7 @@ struct DRW_Global {
struct GPUTexture *weight_ramp;
struct GPUUniformBuf *view_ubo;
+ struct GPUUniformBuf *clipping_ubo;
};
extern struct DRW_Global G_draw;
diff --git a/source/blender/draw/intern/draw_common_shader_shared.h b/source/blender/draw/intern/draw_common_shader_shared.h
index 57cb7880ce6..9a5fce52c1e 100644
--- a/source/blender/draw/intern/draw_common_shader_shared.h
+++ b/source/blender/draw/intern/draw_common_shader_shared.h
@@ -124,8 +124,7 @@ struct GlobalsUboStorage {
float4 color_uv_shadow;
/* NOTE: Put all color before #UBO_LAST_COLOR. */
- float4 screen_vecs[2]; /* Padded as vec4. */
- float4 size_viewport; /* Packed as vec4. */
+ float4 size_viewport; /* Packed as vec4. */
/* Pack individual float at the end of the buffer to avoid alignment errors */
float size_pixel, pixel_fac;
@@ -228,8 +227,8 @@ BLI_STATIC_ASSERT_ALIGN(GlobalsUboStorage, 16)
# define colorFaceBack globalsBlock.color_face_back
# define colorFaceFront globalsBlock.color_face_front
# define colorUVShadow globalsBlock.color_uv_shadow
-# define screenVecs globalsBlock.screen_vecs
# define sizeViewport globalsBlock.size_viewport.xy
+# define sizeViewportInv globalsBlock.size_viewport.zw
# define sizePixel globalsBlock.size_pixel
# define pixelFac globalsBlock.pixel_fac
# define sizeObjectCenter globalsBlock.size_object_center
diff --git a/source/blender/draw/intern/draw_curves.cc b/source/blender/draw/intern/draw_curves.cc
index a61769e7a63..ee9ed4666e0 100644
--- a/source/blender/draw/intern/draw_curves.cc
+++ b/source/blender/draw/intern/draw_curves.cc
@@ -129,25 +129,25 @@ void DRW_curves_ubos_pool_free(CurvesUniformBufPool *pool)
static void drw_curves_cache_shgrp_attach_resources(DRWShadingGroup *shgrp,
CurvesEvalCache *cache,
- GPUTexture *tex,
+ GPUVertBuf *point_buf,
const int subdiv)
{
- DRW_shgroup_uniform_texture(shgrp, "hairPointBuffer", tex);
- DRW_shgroup_uniform_texture(shgrp, "hairStrandBuffer", cache->strand_tex);
- DRW_shgroup_uniform_texture(shgrp, "hairStrandSegBuffer", cache->strand_seg_tex);
+ DRW_shgroup_buffer_texture(shgrp, "hairPointBuffer", point_buf);
+ DRW_shgroup_buffer_texture(shgrp, "hairStrandBuffer", cache->proc_strand_buf);
+ DRW_shgroup_buffer_texture(shgrp, "hairStrandSegBuffer", cache->proc_strand_seg_buf);
DRW_shgroup_uniform_int(shgrp, "hairStrandsRes", &cache->final[subdiv].strands_res, 1);
}
static void drw_curves_cache_update_compute(CurvesEvalCache *cache,
const int subdiv,
const int strands_len,
- GPUVertBuf *buffer,
- GPUTexture *tex)
+ GPUVertBuf *output_buf,
+ GPUVertBuf *input_buf)
{
GPUShader *shader = curves_eval_shader_get(CURVES_EVAL_CATMULL_ROM);
DRWShadingGroup *shgrp = DRW_shgroup_create(shader, g_tf_pass);
- drw_curves_cache_shgrp_attach_resources(shgrp, cache, tex, subdiv);
- DRW_shgroup_vertex_buffer(shgrp, "posTime", buffer);
+ drw_curves_cache_shgrp_attach_resources(shgrp, cache, input_buf, subdiv);
+ DRW_shgroup_vertex_buffer(shgrp, "posTime", output_buf);
const int max_strands_per_call = GPU_max_work_group_count(0);
int strands_start = 0;
@@ -169,7 +169,7 @@ static void drw_curves_cache_update_compute(CurvesEvalCache *cache, const int su
}
drw_curves_cache_update_compute(
- cache, subdiv, strands_len, cache->final[subdiv].proc_buf, cache->point_tex);
+ cache, subdiv, strands_len, cache->final[subdiv].proc_buf, cache->proc_point_buf);
const DRW_Attributes &attrs = cache->final[subdiv].attr_used;
for (int i = 0; i < attrs.num_requests; i++) {
@@ -182,13 +182,13 @@ static void drw_curves_cache_update_compute(CurvesEvalCache *cache, const int su
subdiv,
strands_len,
cache->final[subdiv].attributes_buf[i],
- cache->proc_attributes_tex[i]);
+ cache->proc_attributes_buf[i]);
}
}
static void drw_curves_cache_update_transform_feedback(CurvesEvalCache *cache,
- GPUVertBuf *vbo,
- GPUTexture *tex,
+ GPUVertBuf *output_buf,
+ GPUVertBuf *input_buf,
const int subdiv,
const int final_points_len)
{
@@ -196,14 +196,14 @@ static void drw_curves_cache_update_transform_feedback(CurvesEvalCache *cache,
DRWShadingGroup *tf_shgrp = nullptr;
if (GPU_transform_feedback_support()) {
- tf_shgrp = DRW_shgroup_transform_feedback_create(tf_shader, g_tf_pass, vbo);
+ tf_shgrp = DRW_shgroup_transform_feedback_create(tf_shader, g_tf_pass, output_buf);
}
else {
tf_shgrp = DRW_shgroup_create(tf_shader, g_tf_pass);
CurvesEvalCall *pr_call = MEM_new<CurvesEvalCall>(__func__);
pr_call->next = g_tf_calls;
- pr_call->vbo = vbo;
+ pr_call->vbo = output_buf;
pr_call->shgrp = tf_shgrp;
pr_call->vert_len = final_points_len;
g_tf_calls = pr_call;
@@ -213,7 +213,7 @@ static void drw_curves_cache_update_transform_feedback(CurvesEvalCache *cache,
}
BLI_assert(tf_shgrp != nullptr);
- drw_curves_cache_shgrp_attach_resources(tf_shgrp, cache, tex, subdiv);
+ drw_curves_cache_shgrp_attach_resources(tf_shgrp, cache, input_buf, subdiv);
DRW_shgroup_call_procedural_points(tf_shgrp, nullptr, final_points_len);
}
@@ -225,7 +225,7 @@ static void drw_curves_cache_update_transform_feedback(CurvesEvalCache *cache, c
}
drw_curves_cache_update_transform_feedback(
- cache, cache->final[subdiv].proc_buf, cache->point_tex, subdiv, final_points_len);
+ cache, cache->final[subdiv].proc_buf, cache->proc_point_buf, subdiv, final_points_len);
const DRW_Attributes &attrs = cache->final[subdiv].attr_used;
for (int i = 0; i < attrs.num_requests; i++) {
@@ -236,7 +236,7 @@ static void drw_curves_cache_update_transform_feedback(CurvesEvalCache *cache, c
drw_curves_cache_update_transform_feedback(cache,
cache->final[subdiv].attributes_buf[i],
- cache->proc_attributes_tex[i],
+ cache->proc_attributes_buf[i],
subdiv,
final_points_len);
}
@@ -346,9 +346,9 @@ DRWShadingGroup *DRW_shgroup_curves_create_sub(Object *object,
1.0f);
}
- DRW_shgroup_uniform_texture(shgrp, "hairPointBuffer", curves_cache->final[subdiv].proc_tex);
- if (curves_cache->length_tex) {
- DRW_shgroup_uniform_texture(shgrp, "hairLen", curves_cache->length_tex);
+ DRW_shgroup_buffer_texture(shgrp, "hairPointBuffer", curves_cache->final[subdiv].proc_buf);
+ if (curves_cache->proc_length_buf) {
+ DRW_shgroup_buffer_texture(shgrp, "hairLen", curves_cache->proc_length_buf);
}
const DRW_Attributes &attrs = curves_cache->final[subdiv].attr_used;
@@ -359,18 +359,18 @@ DRWShadingGroup *DRW_shgroup_curves_create_sub(Object *object,
drw_curves_get_attribute_sampler_name(request.attribute_name, sampler_name);
if (request.domain == ATTR_DOMAIN_CURVE) {
- if (!curves_cache->proc_attributes_tex[i]) {
+ if (!curves_cache->proc_attributes_buf[i]) {
continue;
}
- DRW_shgroup_uniform_texture(shgrp, sampler_name, curves_cache->proc_attributes_tex[i]);
+ DRW_shgroup_buffer_texture(shgrp, sampler_name, curves_cache->proc_attributes_buf[i]);
}
else {
- if (!curves_cache->final[subdiv].attributes_tex[i]) {
+ if (!curves_cache->final[subdiv].attributes_buf[i]) {
continue;
}
- DRW_shgroup_uniform_texture(
- shgrp, sampler_name, curves_cache->final[subdiv].attributes_tex[i]);
+ DRW_shgroup_buffer_texture(
+ shgrp, sampler_name, curves_cache->final[subdiv].attributes_buf[i]);
}
/* Some attributes may not be used in the shader anymore and were not garbage collected yet, so
@@ -390,10 +390,15 @@ DRWShadingGroup *DRW_shgroup_curves_create_sub(Object *object,
DRW_shgroup_uniform_int(shgrp, "hairStrandsRes", &curves_cache->final[subdiv].strands_res, 1);
DRW_shgroup_uniform_int_copy(shgrp, "hairThicknessRes", thickness_res);
DRW_shgroup_uniform_float_copy(shgrp, "hairRadShape", hair_rad_shape);
- DRW_shgroup_uniform_mat4_copy(shgrp, "hairDupliMatrix", object->obmat);
+ DRW_shgroup_uniform_mat4_copy(shgrp, "hairDupliMatrix", object->object_to_world);
DRW_shgroup_uniform_float_copy(shgrp, "hairRadRoot", hair_rad_root);
DRW_shgroup_uniform_float_copy(shgrp, "hairRadTip", hair_rad_tip);
DRW_shgroup_uniform_bool_copy(shgrp, "hairCloseTip", hair_close_tip);
+ if (gpu_material) {
+ /* \note: This needs to happen before the drawcall to allow correct attribute extraction.
+ * (see T101896) */
+ DRW_shgroup_add_material_resources(shgrp, gpu_material);
+ }
/* TODO(fclem): Until we have a better way to cull the curves and render with orco, bypass
* culling test. */
GPUBatch *geom = curves_cache->final[subdiv].proc_hairs[thickness_res - 1];
diff --git a/source/blender/draw/intern/draw_curves_private.h b/source/blender/draw/intern/draw_curves_private.h
index 31122ed5248..715706fd7a6 100644
--- a/source/blender/draw/intern/draw_curves_private.h
+++ b/source/blender/draw/intern/draw_curves_private.h
@@ -34,7 +34,6 @@ typedef enum CurvesEvalShader {
typedef struct CurvesEvalFinalCache {
/* Output of the subdivision stage: vertex buffer sized to subdiv level. */
GPUVertBuf *proc_buf;
- GPUTexture *proc_tex;
/** Just contains a huge index buffer used to draw the final curves. */
GPUBatch *proc_hairs[MAX_THICKRES];
@@ -61,32 +60,29 @@ typedef struct CurvesEvalFinalCache {
/* Output of the subdivision stage: vertex buffers sized to subdiv level. This is only attributes
* on point domain. */
GPUVertBuf *attributes_buf[GPU_MAX_ATTR];
- GPUTexture *attributes_tex[GPU_MAX_ATTR];
} CurvesEvalFinalCache;
/* Curves procedural display: Evaluation is done on the GPU. */
typedef struct CurvesEvalCache {
/* Input control point positions combined with parameter data. */
GPUVertBuf *proc_point_buf;
- GPUTexture *point_tex;
+
+ /* Editmode data (such as selection flags) used by overlay_edit_curve_point.glsl */
+ GPUVertBuf *data_edit_points;
/** Info of control points strands (segment count and base index) */
GPUVertBuf *proc_strand_buf;
- GPUTexture *strand_tex;
/* Curve length data. */
GPUVertBuf *proc_length_buf;
- GPUTexture *length_tex;
GPUVertBuf *proc_strand_seg_buf;
- GPUTexture *strand_seg_tex;
CurvesEvalFinalCache final[MAX_HAIR_SUBDIV];
/* For point attributes, which need subdivision, these buffers contain the input data.
* For curve domain attributes, which do not need subdivision, these are the final data. */
GPUVertBuf *proc_attributes_buf[GPU_MAX_ATTR];
- GPUTexture *proc_attributes_tex[GPU_MAX_ATTR];
int strands_len;
int elems_len;
diff --git a/source/blender/draw/intern/draw_debug.cc b/source/blender/draw/intern/draw_debug.cc
index b0662a42ea0..55de779d85c 100644
--- a/source/blender/draw/intern/draw_debug.cc
+++ b/source/blender/draw/intern/draw_debug.cc
@@ -21,7 +21,7 @@
#include <iomanip>
-#ifdef DEBUG
+#if defined(DEBUG) || defined(WITH_DRAW_DEBUG)
# define DRAW_DEBUG
#else
/* Uncomment to forcibly enable debug draw in release mode. */
@@ -85,6 +85,9 @@ void DebugDraw::init()
gpu_draw_buf_.command.instance_first_array = 0;
gpu_draw_buf_used = false;
+ print_col_ = 0;
+ print_row_ = 0;
+
modelmat_reset();
}
@@ -316,8 +319,8 @@ template<> void DebugDraw::print_value<uint4>(const uint4 &value)
/* -------------------------------------------------------------------- */
/** \name Internals
*
- * IMPORTANT: All of these are copied from the shader libs (common_debug_draw_lib.glsl &
- * common_debug_print_lib.glsl). They need to be kept in sync to write the same data.
+ * IMPORTANT: All of these are copied from the shader libraries (`common_debug_draw_lib.glsl` &
+ * `common_debug_print_lib.glsl`). They need to be kept in sync to write the same data.
* \{ */
void DebugDraw::draw_line(float3 v1, float3 v2, uint color)
@@ -553,6 +556,9 @@ void DebugDraw::display_prints()
GPUShader *shader = DRW_shader_debug_print_display_get();
GPU_batch_set_shader(batch, shader);
int slot = GPU_shader_get_builtin_ssbo(shader, GPU_STORAGE_BUFFER_DEBUG_PRINT);
+ float f_viewport[4];
+ GPU_viewport_size_get_f(f_viewport);
+ GPU_shader_uniform_2fv(shader, "viewport_size", f_viewport);
if (gpu_print_buf_used) {
GPU_debug_group_begin("GPU");
diff --git a/source/blender/draw/intern/draw_defines.h b/source/blender/draw/intern/draw_defines.h
index 3df7e47cffb..57035717bd7 100644
--- a/source/blender/draw/intern/draw_defines.h
+++ b/source/blender/draw/intern/draw_defines.h
@@ -12,6 +12,10 @@
#pragma once
#define DRW_VIEW_UBO_SLOT 0
+#define DRW_VIEW_CULLING_UBO_SLOT 1
+#define DRW_CLIPPING_UBO_SLOT 2
+
+#define DRW_LAYER_ATTR_UBO_SLOT 3
#define DRW_RESOURCE_ID_SLOT 11
#define DRW_OBJ_MAT_SLOT 10
diff --git a/source/blender/draw/intern/draw_fluid.c b/source/blender/draw/intern/draw_fluid.c
index c34025ebe52..a14f6142cfb 100644
--- a/source/blender/draw/intern/draw_fluid.c
+++ b/source/blender/draw/intern/draw_fluid.c
@@ -208,7 +208,7 @@ static GPUTexture *create_volume_texture(const int dim[3],
}
else {
/* We need to resize the input. */
- int channels = (ELEM(texture_format, GPU_R8, GPU_R16F, GPU_R32F)) ? 1 : 4;
+ int channels = ELEM(texture_format, GPU_R8, GPU_R16F, GPU_R32F) ? 1 : 4;
float *rescaled_data = rescale_3d(dim, final_dim, channels, data);
if (rescaled_data) {
GPU_texture_update_sub(tex, GPU_DATA_FLOAT, rescaled_data, 0, 0, 0, UNPACK3(final_dim));
diff --git a/source/blender/draw/intern/draw_hair.cc b/source/blender/draw/intern/draw_hair.cc
index ceee1c7cb48..c5261f26f76 100644
--- a/source/blender/draw/intern/draw_hair.cc
+++ b/source/blender/draw/intern/draw_hair.cc
@@ -105,9 +105,9 @@ static void drw_hair_particle_cache_shgrp_attach_resources(DRWShadingGroup *shgr
ParticleHairCache *cache,
const int subdiv)
{
- DRW_shgroup_uniform_texture(shgrp, "hairPointBuffer", cache->point_tex);
- DRW_shgroup_uniform_texture(shgrp, "hairStrandBuffer", cache->strand_tex);
- DRW_shgroup_uniform_texture(shgrp, "hairStrandSegBuffer", cache->strand_seg_tex);
+ DRW_shgroup_buffer_texture(shgrp, "hairPointBuffer", cache->proc_point_buf);
+ DRW_shgroup_buffer_texture(shgrp, "hairStrandBuffer", cache->proc_strand_buf);
+ DRW_shgroup_buffer_texture(shgrp, "hairStrandSegBuffer", cache->proc_strand_seg_buf);
DRW_shgroup_uniform_int(shgrp, "hairStrandsRes", &cache->final[subdiv].strands_res, 1);
}
@@ -202,8 +202,8 @@ GPUVertBuf *DRW_hair_pos_buffer_get(Object *object, ParticleSystem *psys, Modifi
}
void DRW_hair_duplimat_get(Object *object,
- ParticleSystem *UNUSED(psys),
- ModifierData *UNUSED(md),
+ ParticleSystem * /*psys*/,
+ ModifierData * /*md*/,
float (*dupli_mat)[4])
{
Object *dupli_parent = DRW_object_get_dupli_parent(object);
@@ -216,12 +216,12 @@ void DRW_hair_duplimat_get(Object *object,
if (collection != nullptr) {
sub_v3_v3(dupli_mat[3], collection->instance_offset);
}
- mul_m4_m4m4(dupli_mat, dupli_parent->obmat, dupli_mat);
+ mul_m4_m4m4(dupli_mat, dupli_parent->object_to_world, dupli_mat);
}
else {
- copy_m4_m4(dupli_mat, dupli_object->ob->obmat);
+ copy_m4_m4(dupli_mat, dupli_object->ob->object_to_world);
invert_m4(dupli_mat);
- mul_m4_m4m4(dupli_mat, object->obmat, dupli_mat);
+ mul_m4_m4m4(dupli_mat, object->object_to_world, dupli_mat);
}
}
else {
@@ -280,9 +280,9 @@ DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object,
float hair_rad_tip = part->rad_tip * part->rad_scale * 0.5f;
bool hair_close_tip = (part->shape_flag & PART_SHAPE_CLOSE_TIP) != 0;
- DRW_shgroup_uniform_texture(shgrp, "hairPointBuffer", hair_cache->final[subdiv].proc_tex);
- if (hair_cache->length_tex) {
- DRW_shgroup_uniform_texture(shgrp, "l", hair_cache->length_tex);
+ DRW_shgroup_buffer_texture(shgrp, "hairPointBuffer", hair_cache->final[subdiv].proc_buf);
+ if (hair_cache->proc_length_buf) {
+ DRW_shgroup_buffer_texture(shgrp, "l", hair_cache->proc_length_buf);
}
DRW_shgroup_uniform_block(shgrp, "drw_curves", *g_dummy_curves_info);
@@ -293,6 +293,11 @@ DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object,
DRW_shgroup_uniform_float_copy(shgrp, "hairRadRoot", hair_rad_root);
DRW_shgroup_uniform_float_copy(shgrp, "hairRadTip", hair_rad_tip);
DRW_shgroup_uniform_bool_copy(shgrp, "hairCloseTip", hair_close_tip);
+ if (gpu_material) {
+ /* \note: This needs to happen before the drawcall to allow correct attribute extraction.
+ * (see T101896) */
+ DRW_shgroup_add_material_resources(shgrp, gpu_material);
+ }
/* TODO(fclem): Until we have a better way to cull the hair and render with orco, bypass
* culling test. */
GPUBatch *geom = hair_cache->final[subdiv].proc_hairs[thickness_res - 1];
diff --git a/source/blender/draw/intern/draw_hair_private.h b/source/blender/draw/intern/draw_hair_private.h
index c7e9e1e22de..a3019ab5aa5 100644
--- a/source/blender/draw/intern/draw_hair_private.h
+++ b/source/blender/draw/intern/draw_hair_private.h
@@ -29,7 +29,6 @@ struct ParticleSystem;
typedef struct ParticleHairFinalCache {
/* Output of the subdivision stage: vertex buff sized to subdiv level. */
GPUVertBuf *proc_buf;
- GPUTexture *proc_tex;
/* Just contains a huge index buffer used to draw the final hair. */
GPUBatch *proc_hairs[MAX_THICKRES];
@@ -44,18 +43,14 @@ typedef struct ParticleHairCache {
/* Hair Procedural display: Interpolation is done on the GPU. */
GPUVertBuf *proc_point_buf; /* Input control points */
- GPUTexture *point_tex;
/** Infos of control points strands (segment count and base index) */
GPUVertBuf *proc_strand_buf;
- GPUTexture *strand_tex;
/* Hair Length */
GPUVertBuf *proc_length_buf;
- GPUTexture *length_tex;
GPUVertBuf *proc_strand_seg_buf;
- GPUTexture *strand_seg_tex;
GPUVertBuf *proc_uv_buf[MAX_MTFACE];
GPUTexture *uv_tex[MAX_MTFACE];
diff --git a/source/blender/draw/intern/draw_instance_data.c b/source/blender/draw/intern/draw_instance_data.c
index ac2aea4524d..b44c1364af9 100644
--- a/source/blender/draw/intern/draw_instance_data.c
+++ b/source/blender/draw/intern/draw_instance_data.c
@@ -410,12 +410,12 @@ typedef struct DRWSparseUniformBuf {
BLI_bitmap *chunk_used;
int num_chunks;
- unsigned int item_size, chunk_size, chunk_bytes;
+ uint item_size, chunk_size, chunk_bytes;
} DRWSparseUniformBuf;
static void drw_sparse_uniform_buffer_init(DRWSparseUniformBuf *buffer,
- unsigned int item_size,
- unsigned int chunk_size)
+ uint item_size,
+ uint chunk_size)
{
buffer->chunk_buffers = NULL;
buffer->chunk_used = NULL;
@@ -426,7 +426,7 @@ static void drw_sparse_uniform_buffer_init(DRWSparseUniformBuf *buffer,
buffer->chunk_bytes = item_size * chunk_size;
}
-DRWSparseUniformBuf *DRW_sparse_uniform_buffer_new(unsigned int item_size, unsigned int chunk_size)
+DRWSparseUniformBuf *DRW_sparse_uniform_buffer_new(uint item_size, uint chunk_size)
{
DRWSparseUniformBuf *buf = MEM_mallocN(sizeof(DRWSparseUniformBuf), __func__);
drw_sparse_uniform_buffer_init(buf, item_size, chunk_size);
@@ -585,87 +585,18 @@ static DRWUniformAttrBuf *drw_uniform_attrs_pool_ensure(GHash *table,
return (DRWUniformAttrBuf *)*pval;
}
-/* This function mirrors lookup_property in cycles/blender/blender_object.cpp */
-static bool drw_uniform_property_lookup(ID *id, const char *name, float r_data[4])
-{
- PointerRNA ptr, id_ptr;
- PropertyRNA *prop;
-
- if (!id) {
- return false;
- }
-
- RNA_id_pointer_create(id, &id_ptr);
-
- if (!RNA_path_resolve(&id_ptr, name, &ptr, &prop)) {
- return false;
- }
-
- if (prop == NULL) {
- return false;
- }
-
- PropertyType type = RNA_property_type(prop);
- int arraylen = RNA_property_array_length(&ptr, prop);
-
- if (arraylen == 0) {
- float value;
-
- if (type == PROP_FLOAT) {
- value = RNA_property_float_get(&ptr, prop);
- }
- else if (type == PROP_INT) {
- value = RNA_property_int_get(&ptr, prop);
- }
- else {
- return false;
- }
-
- copy_v4_fl4(r_data, value, value, value, 1);
- return true;
- }
-
- if (type == PROP_FLOAT && arraylen <= 4) {
- copy_v4_fl4(r_data, 0, 0, 0, 1);
- RNA_property_float_get_array(&ptr, prop, r_data);
- return true;
- }
-
- return false;
-}
-
-/* This function mirrors lookup_instance_property in cycles/blender/blender_object.cpp */
static void drw_uniform_attribute_lookup(GPUUniformAttr *attr,
Object *ob,
Object *dupli_parent,
DupliObject *dupli_source,
float r_data[4])
{
- copy_v4_fl(r_data, 0);
-
/* If requesting instance data, check the parent particle system and object. */
if (attr->use_dupli) {
- if (dupli_source && dupli_source->particle_system) {
- ParticleSettings *settings = dupli_source->particle_system->part;
- if (drw_uniform_property_lookup((ID *)settings, attr->name_id_prop, r_data) ||
- drw_uniform_property_lookup((ID *)settings, attr->name, r_data)) {
- return;
- }
- }
- if (drw_uniform_property_lookup((ID *)dupli_parent, attr->name_id_prop, r_data) ||
- drw_uniform_property_lookup((ID *)dupli_parent, attr->name, r_data)) {
- return;
- }
+ BKE_object_dupli_find_rgba_attribute(ob, dupli_source, dupli_parent, attr->name, r_data);
}
-
- /* Check the object and mesh. */
- if (ob) {
- if (drw_uniform_property_lookup((ID *)ob, attr->name_id_prop, r_data) ||
- drw_uniform_property_lookup((ID *)ob, attr->name, r_data) ||
- drw_uniform_property_lookup((ID *)ob->data, attr->name_id_prop, r_data) ||
- drw_uniform_property_lookup((ID *)ob->data, attr->name, r_data)) {
- return;
- }
+ else {
+ BKE_object_dupli_find_rgba_attribute(ob, NULL, NULL, attr->name, r_data);
}
}
@@ -691,6 +622,62 @@ void drw_uniform_attrs_pool_update(GHash *table,
}
}
+GPUUniformBuf *drw_ensure_layer_attribute_buffer()
+{
+ DRWData *data = DST.vmempool;
+
+ if (data->vlattrs_ubo_ready && data->vlattrs_ubo != NULL) {
+ return data->vlattrs_ubo;
+ }
+
+ /* Allocate the buffer data. */
+ const int buf_size = DRW_RESOURCE_CHUNK_LEN;
+
+ if (data->vlattrs_buf == NULL) {
+ data->vlattrs_buf = MEM_calloc_arrayN(
+ buf_size, sizeof(LayerAttribute), "View Layer Attr Data");
+ }
+
+ /* Look up attributes.
+ *
+ * Mirrors code in draw_resource.cc and cycles/blender/shader.cpp.
+ */
+ LayerAttribute *buffer = data->vlattrs_buf;
+ int count = 0;
+
+ LISTBASE_FOREACH (GPULayerAttr *, attr, &data->vlattrs_name_list) {
+ float value[4];
+
+ if (BKE_view_layer_find_rgba_attribute(
+ DST.draw_ctx.scene, DST.draw_ctx.view_layer, attr->name, value)) {
+ LayerAttribute *item = &buffer[count++];
+
+ memcpy(item->data, value, sizeof(item->data));
+ item->hash_code = attr->hash_code;
+
+ /* Check if the buffer is full just in case. */
+ if (count >= buf_size) {
+ break;
+ }
+ }
+ }
+
+ buffer[0].buffer_length = count;
+
+ /* Update or create the UBO object. */
+ if (data->vlattrs_ubo != NULL) {
+ GPU_uniformbuf_update(data->vlattrs_ubo, buffer);
+ }
+ else {
+ data->vlattrs_ubo = GPU_uniformbuf_create_ex(
+ sizeof(*buffer) * buf_size, buffer, "View Layer Attributes");
+ }
+
+ data->vlattrs_ubo_ready = true;
+
+ return data->vlattrs_ubo;
+}
+
DRWSparseUniformBuf *DRW_uniform_attrs_pool_find_ubo(GHash *table,
const struct GPUUniformAttrList *key)
{
diff --git a/source/blender/draw/intern/draw_instance_data.h b/source/blender/draw/intern/draw_instance_data.h
index 9053544d98a..17978938ced 100644
--- a/source/blender/draw/intern/draw_instance_data.h
+++ b/source/blender/draw/intern/draw_instance_data.h
@@ -16,6 +16,10 @@
#define DRW_BUFFER_VERTS_CHUNK 128
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct GHash;
struct GPUUniformAttrList;
@@ -107,3 +111,7 @@ void DRW_uniform_attrs_pool_flush_all(struct GHash *table);
void DRW_uniform_attrs_pool_clear_all(struct GHash *table);
struct DRWSparseUniformBuf *DRW_uniform_attrs_pool_find_ubo(struct GHash *table,
const struct GPUUniformAttrList *key);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 8212b38e74d..4fcfec833eb 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -38,6 +38,7 @@
#include "BKE_pointcloud.h"
#include "BKE_screen.h"
#include "BKE_subdiv_modifier.h"
+#include "BKE_viewer_path.h"
#include "BKE_volume.h"
#include "DNA_camera_types.h"
@@ -297,11 +298,6 @@ const float *DRW_viewport_invert_size_get(void)
return DST.inv_size;
}
-const float *DRW_viewport_screenvecs_get(void)
-{
- return &DST.screenvecs[0][0];
-}
-
const float *DRW_viewport_pixelsize_get(void)
{
return &DST.pixsize;
@@ -382,6 +378,8 @@ DRWData *DRW_viewport_data_create(void)
drw_data->views = BLI_memblock_create(sizeof(DRWView));
drw_data->images = BLI_memblock_create(sizeof(GPUTexture *));
drw_data->obattrs_ubo_pool = DRW_uniform_attrs_pool_new();
+ drw_data->vlattrs_name_cache = BLI_ghash_new(
+ BLI_ghashutil_inthash_p_simple, BLI_ghashutil_intcmp, "View Layer Attribute names");
{
uint chunk_len = sizeof(DRWObjectMatrix) * DRW_RESOURCE_CHUNK_LEN;
drw_data->obmats = BLI_memblock_create_ex(sizeof(DRWObjectMatrix), chunk_len);
@@ -417,9 +415,24 @@ static void draw_texture_release(DRWData *drw_data)
}
}
+static void draw_prune_vlattrs(DRWData *drw_data)
+{
+ drw_data->vlattrs_ubo_ready = false;
+
+ /* Forget known attributes after they are unused for a few frames. */
+ LISTBASE_FOREACH_MUTABLE (GPULayerAttr *, attr, &drw_data->vlattrs_name_list) {
+ if (++attr->users > 10) {
+ BLI_ghash_remove(
+ drw_data->vlattrs_name_cache, POINTER_FROM_UINT(attr->hash_code), NULL, NULL);
+ BLI_freelinkN(&drw_data->vlattrs_name_list, attr);
+ }
+ }
+}
+
static void drw_viewport_data_reset(DRWData *drw_data)
{
draw_texture_release(drw_data);
+ draw_prune_vlattrs(drw_data);
BLI_memblock_clear(drw_data->commands, NULL);
BLI_memblock_clear(drw_data->commands_small, NULL);
@@ -455,6 +468,12 @@ void DRW_viewport_data_free(DRWData *drw_data)
BLI_memblock_destroy(drw_data->passes, NULL);
BLI_memblock_destroy(drw_data->images, NULL);
DRW_uniform_attrs_pool_free(drw_data->obattrs_ubo_pool);
+ BLI_ghash_free(drw_data->vlattrs_name_cache, NULL, NULL);
+ BLI_freelistN(&drw_data->vlattrs_name_list);
+ if (drw_data->vlattrs_ubo) {
+ GPU_uniformbuf_free(drw_data->vlattrs_ubo);
+ MEM_freeN(drw_data->vlattrs_buf);
+ }
DRW_instance_data_list_free(drw_data->idatalist);
DRW_texture_pool_free(drw_data->texture_pool);
for (int i = 0; i < 2; i++) {
@@ -560,12 +579,8 @@ static void drw_manager_init(DRWManager *dst, GPUViewport *viewport, const int s
draw_unit_state_create();
if (rv3d != NULL) {
- normalize_v3_v3(dst->screenvecs[0], rv3d->viewinv[0]);
- normalize_v3_v3(dst->screenvecs[1], rv3d->viewinv[1]);
-
dst->pixsize = rv3d->pixsize;
dst->view_default = DRW_view_create(rv3d->viewmat, rv3d->winmat, NULL, NULL, NULL);
- DRW_view_camtexco_set(dst->view_default, rv3d->viewcamtexcofac);
if (dst->draw_ctx.sh_cfg == GPU_SHADER_CFG_CLIPPED) {
int plane_len = (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXCLIP) ? 4 : 6;
@@ -594,9 +609,6 @@ static void drw_manager_init(DRWManager *dst, GPUViewport *viewport, const int s
dst->view_previous = NULL;
}
else {
- zero_v3(dst->screenvecs[0]);
- zero_v3(dst->screenvecs[1]);
-
dst->pixsize = 1.0f;
dst->view_default = NULL;
dst->view_active = NULL;
@@ -609,7 +621,12 @@ static void drw_manager_init(DRWManager *dst, GPUViewport *viewport, const int s
}
if (G_draw.view_ubo == NULL) {
- G_draw.view_ubo = GPU_uniformbuf_create_ex(sizeof(ViewInfos), NULL, "G_draw.view_ubo");
+ G_draw.view_ubo = GPU_uniformbuf_create_ex(sizeof(ViewMatrices), NULL, "G_draw.view_ubo");
+ }
+
+ if (G_draw.clipping_ubo == NULL) {
+ G_draw.clipping_ubo = GPU_uniformbuf_create_ex(
+ sizeof(float4) * 6, NULL, "G_draw.clipping_ubo");
}
if (dst->draw_list == NULL) {
@@ -817,6 +834,7 @@ static bool id_type_can_have_drawdata(const short id_type)
/* has DrawData */
case ID_OB:
case ID_WO:
+ case ID_SCE:
return true;
/* no DrawData */
@@ -969,10 +987,13 @@ void DRW_cache_free_old_batches(Main *bmain)
/* TODO(fclem): This is not optimal since it iter over all dupli instances.
* In this case only the source object should be tagged. */
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
+ DEGObjectIterSettings deg_iter_settings = {0};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
DRW_batch_cache_free_old(ob, ctime);
}
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
+ DEG_OBJECT_ITER_END;
}
}
}
@@ -1324,6 +1345,7 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
+ BKE_view_layer_synced_ensure(scene, view_layer);
DST.draw_ctx = (DRWContextState){
.region = region,
.rv3d = rv3d,
@@ -1377,6 +1399,7 @@ static void drw_notify_view_update_offscreen(struct Depsgraph *depsgraph,
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
+ BKE_view_layer_synced_ensure(scene, view_layer);
DST.draw_ctx = (DRWContextState){
.region = region,
.rv3d = rv3d,
@@ -1502,7 +1525,7 @@ void DRW_draw_callbacks_post_scene(void)
DRW_draw_region_info();
- /* annotations - temporary drawing buffer (screenspace) */
+ /* Annotations - temporary drawing buffer (screen-space). */
/* XXX: Or should we use a proper draw/overlay engine for this case? */
if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && (do_annotations)) {
GPU_depth_test(GPU_DEPTH_NONE);
@@ -1629,6 +1652,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
RegionView3D *rv3d = region->regiondata;
+ BKE_view_layer_synced_ensure(scene, view_layer);
DST.draw_ctx.evil_C = evil_C;
DST.draw_ctx = (DRWContextState){
.region = region,
@@ -1666,6 +1690,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
DRW_globals_update();
drw_debug_init();
+ DRW_pointcloud_init();
DRW_curves_init(DST.vmempool);
DRW_volume_init(DST.vmempool);
DRW_smoke_init(DST.vmempool);
@@ -1686,7 +1711,13 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
if (do_populate_loop) {
DST.dupli_origin = NULL;
DST.dupli_origin_data = NULL;
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
+ DEGObjectIterSettings deg_iter_settings = {0};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS;
+ if (v3d->flag2 & V3D_SHOW_VIEWER) {
+ deg_iter_settings.viewer_path = &v3d->viewer_path;
+ }
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
continue;
}
@@ -1698,7 +1729,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
drw_duplidata_load(ob);
drw_engines_cache_populate(ob);
}
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
+ DEG_OBJECT_ITER_END;
}
drw_duplidata_free();
@@ -1814,7 +1845,7 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph,
GPU_matrix_identity_set();
GPU_matrix_identity_projection_set();
const bool do_overlays = (v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 ||
- (ELEM(v3d->shading.type, OB_WIRE, OB_SOLID)) ||
+ ELEM(v3d->shading.type, OB_WIRE, OB_SOLID) ||
(ELEM(v3d->shading.type, OB_MATERIAL) &&
(v3d->shading.flag & V3D_SHADING_SCENE_WORLD) == 0) ||
(ELEM(v3d->shading.type, OB_RENDER) &&
@@ -1838,14 +1869,17 @@ bool DRW_render_check_grease_pencil(Depsgraph *depsgraph)
return false;
}
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
+ DEGObjectIterSettings deg_iter_settings = {0};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
if (ob->type == OB_GPENCIL) {
if (DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF) {
return true;
}
}
}
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
+ DEG_OBJECT_ITER_END;
return false;
}
@@ -1926,20 +1960,6 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph
DST.buffer_finish_called = false;
}
-/* Callback function for RE_engine_update_render_passes to ensure all
- * render passes are registered. */
-static void draw_render_result_ensure_pass_cb(void *user_data,
- struct Scene *UNUSED(scene),
- struct ViewLayer *view_layer,
- const char *name,
- int channels,
- const char *chanid,
- eNodeSocketDatatype UNUSED(type))
-{
- RenderEngine *engine = user_data;
- RE_engine_add_pass(engine, name, channels, chanid, view_layer->name);
-}
-
void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
@@ -1990,10 +2010,6 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
/* set default viewport */
GPU_viewport(0, 0, size[0], size[1]);
- /* Update the render passes. This needs to be done before acquiring the render result. */
- RE_engine_update_render_passes(
- engine, scene, view_layer, draw_render_result_ensure_pass_cb, engine);
-
/* Init render result. */
RenderResult *render_result = RE_engine_begin_result(engine,
0,
@@ -2038,6 +2054,7 @@ void DRW_render_object_iter(
void (*callback)(void *vedata, Object *ob, RenderEngine *engine, struct Depsgraph *depsgraph))
{
const DRWContextState *draw_ctx = DRW_context_state_get();
+ DRW_pointcloud_init();
DRW_curves_init(DST.vmempool);
DRW_volume_init(DST.vmempool);
DRW_smoke_init(DST.vmempool);
@@ -2048,7 +2065,10 @@ void DRW_render_object_iter(
0;
DST.dupli_origin = NULL;
DST.dupli_origin_data = NULL;
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
+ DEGObjectIterSettings deg_iter_settings = {0};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
if ((object_type_exclude_viewport & (1 << ob->type)) == 0) {
DST.dupli_parent = data_.dupli_parent;
DST.dupli_source = data_.dupli_object_current;
@@ -2064,7 +2084,7 @@ void DRW_render_object_iter(
}
}
}
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
+ DEG_OBJECT_ITER_END;
drw_duplidata_free();
drw_task_graph_deinit();
@@ -2095,6 +2115,7 @@ void DRW_custom_pipeline(DrawEngineType *draw_engine_type,
drw_manager_init(&DST, NULL, NULL);
+ DRW_pointcloud_init();
DRW_curves_init(DST.vmempool);
DRW_volume_init(DST.vmempool);
DRW_smoke_init(DST.vmempool);
@@ -2130,6 +2151,7 @@ void DRW_cache_restart(void)
DST.buffer_finish_called = false;
+ DRW_pointcloud_init();
DRW_curves_init(DST.vmempool);
DRW_volume_init(DST.vmempool);
DRW_smoke_init(DST.vmempool);
@@ -2143,6 +2165,7 @@ void DRW_draw_render_loop_2d_ex(struct Depsgraph *depsgraph,
Scene *scene = DEG_get_evaluated_scene(depsgraph);
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
+ BKE_view_layer_synced_ensure(scene, view_layer);
DST.draw_ctx.evil_C = evil_C;
DST.draw_ctx = (DRWContextState){
.region = region,
@@ -2191,10 +2214,13 @@ void DRW_draw_render_loop_2d_ex(struct Depsgraph *depsgraph,
/* Only iterate over objects when overlay uses object data. */
if (do_populate_loop) {
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
+ DEGObjectIterSettings deg_iter_settings = {0};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
drw_engines_cache_populate(ob);
}
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
+ DEG_OBJECT_ITER_END;
}
drw_engines_cache_finish();
@@ -2349,6 +2375,8 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
Scene *scene = DEG_get_evaluated_scene(depsgraph);
RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
+
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obact = BKE_view_layer_active_object_get(view_layer);
Object *obedit = use_obedit_skip ? NULL : OBEDIT_FROM_OBACT(obact);
#ifndef USE_GPU_SELECT
@@ -2449,6 +2477,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
/* Init engines */
drw_engines_init();
+ DRW_pointcloud_init();
DRW_curves_init(DST.vmempool);
DRW_volume_init(DST.vmempool);
DRW_smoke_init(DST.vmempool);
@@ -2458,7 +2487,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
drw_engines_world_update(scene);
if (use_obedit) {
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, object_type, object_mode, ob_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, object_type, object_mode, ob_iter) {
drw_engines_cache_populate(ob_iter);
}
FOREACH_OBJECT_IN_MODE_END;
@@ -2473,7 +2502,13 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
bool filter_exclude = false;
DST.dupli_origin = NULL;
DST.dupli_origin_data = NULL;
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
+ DEGObjectIterSettings deg_iter_settings = {0};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS;
+ if (v3d->flag2 & V3D_SHOW_VIEWER) {
+ deg_iter_settings.viewer_path = &v3d->viewer_path;
+ }
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
if (!BKE_object_is_visible_in_viewport(v3d, ob)) {
continue;
}
@@ -2509,7 +2544,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
drw_engines_cache_populate(ob);
}
}
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
+ DEG_OBJECT_ITER_END;
}
drw_duplidata_free();
@@ -2561,13 +2596,13 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
/**
* object mode select-loop, see: ED_view3d_draw_depth_loop (legacy drawing).
*/
-static void drw_draw_depth_loop_impl(struct Depsgraph *depsgraph,
- ARegion *region,
- View3D *v3d,
- GPUViewport *viewport,
- const bool use_gpencil,
- const bool use_basic,
- const bool use_overlay)
+void DRW_draw_depth_loop(struct Depsgraph *depsgraph,
+ ARegion *region,
+ View3D *v3d,
+ GPUViewport *viewport,
+ const bool use_gpencil,
+ const bool use_basic,
+ const bool use_overlay)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
@@ -2580,6 +2615,7 @@ static void drw_draw_depth_loop_impl(struct Depsgraph *depsgraph,
DST.options.is_depth = true;
/* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
+ BKE_view_layer_synced_ensure(scene, view_layer);
DST.draw_ctx = (DRWContextState){
.region = region,
.rv3d = rv3d,
@@ -2623,6 +2659,7 @@ static void drw_draw_depth_loop_impl(struct Depsgraph *depsgraph,
/* Init engines */
drw_engines_init();
+ DRW_pointcloud_init();
DRW_curves_init(DST.vmempool);
DRW_volume_init(DST.vmempool);
DRW_smoke_init(DST.vmempool);
@@ -2634,7 +2671,13 @@ static void drw_draw_depth_loop_impl(struct Depsgraph *depsgraph,
const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
DST.dupli_origin = NULL;
DST.dupli_origin_data = NULL;
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (DST.draw_ctx.depsgraph, ob) {
+ DEGObjectIterSettings deg_iter_settings = {0};
+ deg_iter_settings.depsgraph = DST.draw_ctx.depsgraph;
+ deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS;
+ if (v3d->flag2 & V3D_SHOW_VIEWER) {
+ deg_iter_settings.viewer_path = &v3d->viewer_path;
+ }
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
continue;
}
@@ -2646,7 +2689,7 @@ static void drw_draw_depth_loop_impl(struct Depsgraph *depsgraph,
drw_duplidata_load(ob);
drw_engines_cache_populate(ob);
}
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
+ DEG_OBJECT_ITER_END;
drw_duplidata_free();
drw_engines_cache_finish();
@@ -2676,23 +2719,6 @@ static void drw_draw_depth_loop_impl(struct Depsgraph *depsgraph,
drw_manager_exit(&DST);
}
-void DRW_draw_depth_loop(struct Depsgraph *depsgraph,
- ARegion *region,
- View3D *v3d,
- GPUViewport *viewport)
-{
- drw_draw_depth_loop_impl(
- depsgraph, region, v3d, viewport, false, true, DRW_state_draw_support());
-}
-
-void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
- ARegion *region,
- View3D *v3d,
- GPUViewport *viewport)
-{
- drw_draw_depth_loop_impl(depsgraph, region, v3d, viewport, true, false, false);
-}
-
void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d, const rcti *rect)
{
SELECTID_Context *sel_ctx = DRW_select_engine_context_get();
@@ -2713,6 +2739,7 @@ void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d, cons
drw_state_prepare_clean_for_draw(&DST);
/* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
+ BKE_view_layer_synced_ensure(scene, view_layer);
DST.draw_ctx = (DRWContextState){
.region = region,
.rv3d = region->regiondata,
@@ -2774,7 +2801,7 @@ void DRW_draw_depth_object(
GPU_matrix_projection_set(rv3d->winmat);
GPU_matrix_set(rv3d->viewmat);
- GPU_matrix_mul(object->obmat);
+ GPU_matrix_mul(object->object_to_world);
/* Setup frame-buffer. */
GPUTexture *depth_tx = GPU_viewport_depth_texture(viewport);
@@ -2794,11 +2821,11 @@ void DRW_draw_depth_object(
const bool use_clipping_planes = RV3D_CLIPPING_ENABLED(v3d, rv3d);
if (use_clipping_planes) {
GPU_clip_distances(6);
- ED_view3d_clipping_local(rv3d, object->obmat);
+ ED_view3d_clipping_local(rv3d, object->object_to_world);
for (int i = 0; i < 6; i++) {
copy_v4_v4(planes.world[i], rv3d->clip_local[i]);
}
- copy_m4_m4(planes.ModelMatrix, object->obmat);
+ copy_m4_m4(planes.ModelMatrix, object->object_to_world);
}
drw_batch_cache_validate(object);
@@ -3047,6 +3074,7 @@ void DRW_engines_free(void)
GPU_FRAMEBUFFER_FREE_SAFE(g_select_buffer.framebuffer_depth_only);
DRW_shaders_free();
+ DRW_pointcloud_free();
DRW_curves_free();
DRW_volume_free();
DRW_shape_cache_free();
@@ -3058,6 +3086,7 @@ void DRW_engines_free(void)
DRW_UBO_FREE_SAFE(G_draw.block_ubo);
DRW_UBO_FREE_SAFE(G_draw.view_ubo);
+ DRW_UBO_FREE_SAFE(G_draw.clipping_ubo);
DRW_TEXTURE_FREE_SAFE(G_draw.ramp);
DRW_TEXTURE_FREE_SAFE(G_draw.weight_ramp);
@@ -3074,6 +3103,8 @@ void DRW_render_context_enable(Render *render)
WM_init_opengl();
}
+ GPU_render_begin();
+
if (GPU_use_main_context_workaround()) {
GPU_context_main_lock();
DRW_opengl_context_enable();
@@ -3097,6 +3128,8 @@ void DRW_render_context_enable(Render *render)
void DRW_render_context_disable(Render *render)
{
+ GPU_render_end();
+
if (GPU_use_main_context_workaround()) {
DRW_opengl_context_disable();
GPU_context_main_unlock();
@@ -3131,7 +3164,7 @@ void DRW_opengl_context_create(void)
DST.gl_context = WM_opengl_context_create();
WM_opengl_context_activate(DST.gl_context);
/* Be sure to create gpu_context too. */
- DST.gpu_context = GPU_context_create(NULL);
+ DST.gpu_context = GPU_context_create(0, DST.gl_context);
/* So we activate the window's one afterwards. */
wm_window_reset_drawable();
}
diff --git a/source/blender/draw/intern/draw_manager.cc b/source/blender/draw/intern/draw_manager.cc
index 169d86b2ea1..c644cadd18c 100644
--- a/source/blender/draw/intern/draw_manager.cc
+++ b/source/blender/draw/intern/draw_manager.cc
@@ -35,6 +35,7 @@ void Manager::begin_sync()
}
acquired_textures.clear();
+ layer_attributes.clear();
#ifdef DEBUG
/* Detect uninitialized data. */
@@ -52,14 +53,46 @@ void Manager::begin_sync()
resource_handle(float4x4::identity());
}
+void Manager::sync_layer_attributes()
+{
+ /* Sort the attribute IDs - the shaders use binary search. */
+ Vector<uint32_t> id_list;
+
+ id_list.reserve(layer_attributes.size());
+
+ for (uint32_t id : layer_attributes.keys()) {
+ id_list.append(id);
+ }
+
+ std::sort(id_list.begin(), id_list.end());
+
+ /* Look up the attributes. */
+ int count = 0, size = layer_attributes_buf.end() - layer_attributes_buf.begin();
+
+ for (uint32_t id : id_list) {
+ if (layer_attributes_buf[count].sync(
+ DST.draw_ctx.scene, DST.draw_ctx.view_layer, layer_attributes.lookup(id))) {
+ /* Check if the buffer is full. */
+ if (++count == size) {
+ break;
+ }
+ }
+ }
+
+ layer_attributes_buf[0].buffer_length = count;
+}
+
void Manager::end_sync()
{
GPU_debug_group_begin("Manager.end_sync");
+ sync_layer_attributes();
+
matrix_buf.push_update();
bounds_buf.push_update();
infos_buf.push_update();
attributes_buf.push_update();
+ layer_attributes_buf.push_update();
attributes_buf_legacy.push_update();
/* Useful for debugging the following resource finalize. But will trigger the drawing of the GPU
@@ -100,6 +133,7 @@ void Manager::resource_bind()
GPU_storagebuf_bind(matrix_buf, DRW_OBJ_MAT_SLOT);
GPU_storagebuf_bind(infos_buf, DRW_OBJ_INFOS_SLOT);
GPU_storagebuf_bind(attributes_buf, DRW_OBJ_ATTR_SLOT);
+ GPU_uniformbuf_bind(layer_attributes_buf, DRW_LAYER_ATTR_UBO_SLOT);
/* 2 is the hardcoded location of the uniform attr UBO. */
/* TODO(@fclem): Remove this workaround. */
GPU_uniformbuf_bind(attributes_buf_legacy, 2);
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index 4f71e665390..52129049269 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -335,6 +335,7 @@ typedef enum {
DRW_UNIFORM_BLOCK_OBMATS,
DRW_UNIFORM_BLOCK_OBINFOS,
DRW_UNIFORM_BLOCK_OBATTRS,
+ DRW_UNIFORM_BLOCK_VLATTRS,
DRW_UNIFORM_RESOURCE_CHUNK,
DRW_UNIFORM_RESOURCE_ID,
/** Legacy / Fallback */
@@ -441,7 +442,12 @@ struct DRWView {
/** Parent view if this is a sub view. NULL otherwise. */
struct DRWView *parent;
- ViewInfos storage;
+ ViewMatrices storage;
+
+ float4 clip_planes[6];
+
+ float4x4 persmat;
+ float4x4 persinv;
/** Number of active clip planes. */
int clip_planes_len;
/** Does culling result needs to be updated. */
@@ -522,6 +528,11 @@ typedef struct DRWData {
struct GPUUniformBuf **matrices_ubo;
struct GPUUniformBuf **obinfos_ubo;
struct GHash *obattrs_ubo_pool;
+ struct GHash *vlattrs_name_cache;
+ struct ListBase vlattrs_name_list;
+ struct LayerAttribute *vlattrs_buf;
+ struct GPUUniformBuf *vlattrs_ubo;
+ bool vlattrs_ubo_ready;
uint ubo_len;
/** Per draw-call volume object data. */
void *volume_grids_ubos; /* VolumeUniformBufPool */
@@ -593,7 +604,6 @@ typedef struct DRWManager {
struct GPUFrameBuffer *default_framebuffer;
float size[2];
float inv_size[2];
- float screenvecs[2][3];
float pixsize;
struct {
@@ -620,7 +630,7 @@ typedef struct DRWManager {
uint primary_view_num;
/** TODO(@fclem): Remove this. Only here to support
* shaders without common_view_lib.glsl */
- ViewInfos view_storage_cpy;
+ ViewMatrices view_storage_cpy;
#ifdef USE_GPU_SELECT
uint select_id;
@@ -687,6 +697,8 @@ void drw_uniform_attrs_pool_update(struct GHash *table,
struct Object *dupli_parent,
struct DupliObject *dupli_source);
+GPUUniformBuf *drw_ensure_layer_attribute_buffer(void);
+
double *drw_engine_data_cache_time_get(GPUViewport *viewport);
void *drw_engine_data_engine_data_create(GPUViewport *viewport, void *engine_type);
void *drw_engine_data_engine_data_get(GPUViewport *viewport, void *engine_handle);
@@ -694,6 +706,16 @@ bool drw_engine_data_engines_data_validate(GPUViewport *viewport, void **engine_
void drw_engine_data_cache_release(GPUViewport *viewport);
void drw_engine_data_free(GPUViewport *viewport);
+struct DRW_Attributes;
+struct DRW_MeshCDMask;
+struct GPUMaterial;
+void DRW_mesh_get_attributes(struct Object *object,
+ struct Mesh *me,
+ struct GPUMaterial **gpumat_array,
+ int gpumat_array_len,
+ struct DRW_Attributes *r_attrs,
+ struct DRW_MeshCDMask *r_cd_needed);
+
void DRW_manager_begin_sync(void);
void DRW_manager_end_sync(void);
diff --git a/source/blender/draw/intern/draw_manager.hh b/source/blender/draw/intern/draw_manager.hh
index fbd3d28d3f4..0a865179cee 100644
--- a/source/blender/draw/intern/draw_manager.hh
+++ b/source/blender/draw/intern/draw_manager.hh
@@ -44,6 +44,7 @@ class Manager {
using ObjectBoundsBuf = StorageArrayBuffer<ObjectBounds, 128>;
using ObjectInfosBuf = StorageArrayBuffer<ObjectInfos, 128>;
using ObjectAttributeBuf = StorageArrayBuffer<ObjectAttribute, 128>;
+ using LayerAttributeBuf = UniformArrayBuffer<LayerAttribute, 512>;
/**
* TODO(@fclem): Remove once we get rid of old EEVEE code-base.
* `DRW_RESOURCE_CHUNK_LEN = 512`.
@@ -87,6 +88,16 @@ class Manager {
ObjectAttributeLegacyBuf attributes_buf_legacy;
/**
+ * Table of all View Layer attributes required by shaders, used to populate the buffer below.
+ */
+ Map<uint32_t, GPULayerAttr> layer_attributes;
+
+ /**
+ * Buffer of layer attribute values, indexed and sorted by the hash.
+ */
+ LayerAttributeBuf layer_attributes_buf;
+
+ /**
* List of textures coming from Image data-blocks.
* They need to be reference-counted in order to avoid being freed in another thread.
*/
@@ -131,6 +142,11 @@ class Manager {
Span<GPUMaterial *> materials);
/**
+ * Collect necessary View Layer attributes.
+ */
+ void register_layer_attributes(GPUMaterial *material);
+
+ /**
* Submit a pass for drawing. All resource reference will be dereferenced and commands will be
* sent to GPU.
*/
@@ -169,6 +185,9 @@ class Manager {
void debug_bind();
void resource_bind();
+
+ private:
+ void sync_layer_attributes();
};
inline ResourceHandle Manager::resource_handle(const ObjectRef ref)
@@ -229,6 +248,19 @@ inline void Manager::extract_object_attributes(ResourceHandle handle,
}
}
+inline void Manager::register_layer_attributes(GPUMaterial *material)
+{
+ const ListBase *attr_list = GPU_material_layer_attributes(material);
+
+ if (attr_list != nullptr) {
+ LISTBASE_FOREACH (const GPULayerAttr *, attr, attr_list) {
+ /** Since layer attributes are global to the whole render pass,
+ * this only collects a table of their names. */
+ layer_attributes.add(attr->hash_code, *attr);
+ }
+ }
+}
+
} // namespace blender::draw
/* TODO(@fclem): This is for testing. The manager should be passed to the engine through the
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.cc
index c75049508f9..29b1493ec5e 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.cc
@@ -5,7 +5,11 @@
* \ingroup draw
*/
+#include "DRW_pbvh.h"
+
+#include "draw_attributes.h"
#include "draw_manager.h"
+#include "draw_pbvh.h"
#include "BKE_curve.h"
#include "BKE_duplilist.h"
@@ -26,10 +30,11 @@
#include "DNA_meta_types.h"
#include "DNA_screen_types.h"
-#include "BLI_alloca.h"
+#include "BLI_array.hh"
#include "BLI_hash.h"
#include "BLI_link_utils.h"
#include "BLI_listbase.h"
+#include "BLI_math_bits.h"
#include "BLI_memblock.h"
#include "BLI_mempool.h"
@@ -37,7 +42,6 @@
# include "BLI_math_bits.h"
#endif
-#include "GPU_buffers.h"
#include "GPU_capabilities.h"
#include "GPU_material.h"
#include "GPU_uniform_buffer.h"
@@ -60,13 +64,13 @@
static void draw_call_sort(DRWCommand *array, DRWCommand *array_tmp, int array_len)
{
- /* Count unique batches. Tt's not really important if
+ /* Count unique batches. It's not really important if
* there is collisions. If there is a lot of different batches,
* the sorting benefit will be negligible.
* So at least sort fast! */
uchar idx[128] = {0};
/* Shift by 6 positions knowing each GPUBatch is > 64 bytes */
-#define KEY(a) ((((size_t)((a).draw.batch)) >> 6) % ARRAY_SIZE(idx))
+#define KEY(a) ((size_t((a).draw.batch) >> 6) % ARRAY_SIZE(idx))
BLI_assert(array_len <= ARRAY_SIZE(idx));
for (int i = 0; i < array_len; i++) {
@@ -98,9 +102,9 @@ void drw_resource_buffer_finish(DRWData *vmempool)
/* TODO: find a better system. currently a lot of obinfos UBO are going to be unused
* if not rendering with Eevee. */
- if (vmempool->matrices_ubo == NULL) {
- vmempool->matrices_ubo = MEM_callocN(list_size, __func__);
- vmempool->obinfos_ubo = MEM_callocN(list_size, __func__);
+ if (vmempool->matrices_ubo == nullptr) {
+ vmempool->matrices_ubo = static_cast<GPUUniformBuf **>(MEM_callocN(list_size, __func__));
+ vmempool->obinfos_ubo = static_cast<GPUUniformBuf **>(MEM_callocN(list_size, __func__));
vmempool->ubo_len = ubo_len;
}
@@ -111,8 +115,10 @@ void drw_resource_buffer_finish(DRWData *vmempool)
}
if (ubo_len != vmempool->ubo_len) {
- vmempool->matrices_ubo = MEM_recallocN(vmempool->matrices_ubo, list_size);
- vmempool->obinfos_ubo = MEM_recallocN(vmempool->obinfos_ubo, list_size);
+ vmempool->matrices_ubo = static_cast<GPUUniformBuf **>(
+ MEM_recallocN(vmempool->matrices_ubo, list_size));
+ vmempool->obinfos_ubo = static_cast<GPUUniformBuf **>(
+ MEM_recallocN(vmempool->obinfos_ubo, list_size));
vmempool->ubo_len = ubo_len;
}
@@ -120,7 +126,7 @@ void drw_resource_buffer_finish(DRWData *vmempool)
for (int i = 0; i < ubo_len; i++) {
void *data_obmat = BLI_memblock_elem_get(vmempool->obmats, i, 0);
void *data_infos = BLI_memblock_elem_get(vmempool->obinfos, i, 0);
- if (vmempool->matrices_ubo[i] == NULL) {
+ if (vmempool->matrices_ubo[i] == nullptr) {
vmempool->matrices_ubo[i] = GPU_uniformbuf_create(sizeof(DRWObjectMatrix) *
DRW_RESOURCE_CHUNK_LEN);
vmempool->obinfos_ubo[i] = GPU_uniformbuf_create(sizeof(DRWObjectInfos) *
@@ -133,11 +139,12 @@ void drw_resource_buffer_finish(DRWData *vmempool)
DRW_uniform_attrs_pool_flush_all(vmempool->obattrs_ubo_pool);
/* Aligned alloc to avoid unaligned memcpy. */
- DRWCommandChunk *chunk_tmp = MEM_mallocN_aligned(sizeof(DRWCommandChunk), 16, "tmp call chunk");
+ DRWCommandChunk *chunk_tmp = static_cast<DRWCommandChunk *>(
+ MEM_mallocN_aligned(sizeof(DRWCommandChunk), 16, __func__));
DRWCommandChunk *chunk;
BLI_memblock_iter iter;
BLI_memblock_iternew(vmempool->commands, &iter);
- while ((chunk = BLI_memblock_iterstep(&iter))) {
+ while ((chunk = static_cast<DRWCommandChunk *>(BLI_memblock_iterstep(&iter)))) {
bool sortable = true;
/* We can only sort chunks that contain #DRWCommandDraw only. */
for (int i = 0; i < ARRAY_SIZE(chunk->command_type) && sortable; i++) {
@@ -175,7 +182,7 @@ static void drw_shgroup_uniform_create_ex(DRWShadingGroup *shgroup,
DRWUniformChunk *unichunk = shgroup->uniforms;
/* Happens on first uniform or if chunk is full. */
if (!unichunk || unichunk->uniform_used == unichunk->uniform_len) {
- unichunk = BLI_memblock_alloc(DST.vmempool->uniforms);
+ unichunk = static_cast<DRWUniformChunk *>(BLI_memblock_alloc(DST.vmempool->uniforms));
unichunk->uniform_len = ARRAY_SIZE(shgroup->uniforms->uniforms);
unichunk->uniform_used = 0;
BLI_LINKS_PREPEND(shgroup->uniforms, unichunk);
@@ -239,7 +246,8 @@ static void drw_shgroup_uniform(DRWShadingGroup *shgroup,
DRW_UNIFORM_TEXTURE,
DRW_UNIFORM_TEXTURE_REF));
int location = GPU_shader_get_uniform(shgroup->shader, name);
- drw_shgroup_uniform_create_ex(shgroup, location, type, value, 0, length, arraysize);
+ drw_shgroup_uniform_create_ex(
+ shgroup, location, type, value, GPU_SAMPLER_DEFAULT, length, arraysize);
}
void DRW_shgroup_uniform_texture_ex(DRWShadingGroup *shgroup,
@@ -247,7 +255,7 @@ void DRW_shgroup_uniform_texture_ex(DRWShadingGroup *shgroup,
const GPUTexture *tex,
eGPUSamplerState sampler_state)
{
- BLI_assert(tex != NULL);
+ BLI_assert(tex != nullptr);
int loc = GPU_shader_get_texture_binding(shgroup->shader, name);
drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_TEXTURE, tex, sampler_state, 0, 1);
}
@@ -262,7 +270,7 @@ void DRW_shgroup_uniform_texture_ref_ex(DRWShadingGroup *shgroup,
GPUTexture **tex,
eGPUSamplerState sampler_state)
{
- BLI_assert(tex != NULL);
+ BLI_assert(tex != nullptr);
int loc = GPU_shader_get_texture_binding(shgroup->shader, name);
drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_TEXTURE_REF, tex, sampler_state, 0, 1);
}
@@ -274,23 +282,24 @@ void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name,
void DRW_shgroup_uniform_image(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
{
- BLI_assert(tex != NULL);
+ BLI_assert(tex != nullptr);
int loc = GPU_shader_get_texture_binding(shgroup->shader, name);
- drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_IMAGE, tex, 0, 0, 1);
+ drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_IMAGE, tex, GPU_SAMPLER_DEFAULT, 0, 1);
}
void DRW_shgroup_uniform_image_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
{
- BLI_assert(tex != NULL);
+ BLI_assert(tex != nullptr);
int loc = GPU_shader_get_texture_binding(shgroup->shader, name);
- drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_IMAGE_REF, tex, 0, 0, 1);
+ drw_shgroup_uniform_create_ex(
+ shgroup, loc, DRW_UNIFORM_IMAGE_REF, tex, GPU_SAMPLER_DEFAULT, 0, 1);
}
void DRW_shgroup_uniform_block_ex(DRWShadingGroup *shgroup,
const char *name,
const GPUUniformBuf *ubo DRW_DEBUG_FILE_LINE_ARGS)
{
- BLI_assert(ubo != NULL);
+ BLI_assert(ubo != nullptr);
int loc = GPU_shader_get_uniform_block_binding(shgroup->shader, name);
if (loc == -1) {
#ifdef DRW_UNUSED_RESOURCE_TRACKING
@@ -304,14 +313,14 @@ void DRW_shgroup_uniform_block_ex(DRWShadingGroup *shgroup,
#endif
return;
}
- drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_BLOCK, ubo, 0, 0, 1);
+ drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_BLOCK, ubo, GPU_SAMPLER_DEFAULT, 0, 1);
}
void DRW_shgroup_uniform_block_ref_ex(DRWShadingGroup *shgroup,
const char *name,
GPUUniformBuf **ubo DRW_DEBUG_FILE_LINE_ARGS)
{
- BLI_assert(ubo != NULL);
+ BLI_assert(ubo != nullptr);
int loc = GPU_shader_get_uniform_block_binding(shgroup->shader, name);
if (loc == -1) {
#ifdef DRW_UNUSED_RESOURCE_TRACKING
@@ -325,14 +334,15 @@ void DRW_shgroup_uniform_block_ref_ex(DRWShadingGroup *shgroup,
#endif
return;
}
- drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_BLOCK_REF, ubo, 0, 0, 1);
+ drw_shgroup_uniform_create_ex(
+ shgroup, loc, DRW_UNIFORM_BLOCK_REF, ubo, GPU_SAMPLER_DEFAULT, 0, 1);
}
void DRW_shgroup_storage_block_ex(DRWShadingGroup *shgroup,
const char *name,
const GPUStorageBuf *ssbo DRW_DEBUG_FILE_LINE_ARGS)
{
- BLI_assert(ssbo != NULL);
+ BLI_assert(ssbo != nullptr);
/* TODO(@fclem): Fix naming inconsistency. */
int loc = GPU_shader_get_ssbo(shgroup->shader, name);
if (loc == -1) {
@@ -347,14 +357,15 @@ void DRW_shgroup_storage_block_ex(DRWShadingGroup *shgroup,
#endif
return;
}
- drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_STORAGE_BLOCK, ssbo, 0, 0, 1);
+ drw_shgroup_uniform_create_ex(
+ shgroup, loc, DRW_UNIFORM_STORAGE_BLOCK, ssbo, GPU_SAMPLER_DEFAULT, 0, 1);
}
void DRW_shgroup_storage_block_ref_ex(DRWShadingGroup *shgroup,
const char *name,
GPUStorageBuf **ssbo DRW_DEBUG_FILE_LINE_ARGS)
{
- BLI_assert(ssbo != NULL);
+ BLI_assert(ssbo != nullptr);
/* TODO(@fclem): Fix naming inconsistency. */
int loc = GPU_shader_get_ssbo(shgroup->shader, name);
if (loc == -1) {
@@ -369,7 +380,8 @@ void DRW_shgroup_storage_block_ref_ex(DRWShadingGroup *shgroup,
#endif
return;
}
- drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_STORAGE_BLOCK_REF, ssbo, 0, 0, 1);
+ drw_shgroup_uniform_create_ex(
+ shgroup, loc, DRW_UNIFORM_STORAGE_BLOCK_REF, ssbo, GPU_SAMPLER_DEFAULT, 0, 1);
}
void DRW_shgroup_uniform_bool(DRWShadingGroup *shgroup,
@@ -518,7 +530,8 @@ void DRW_shgroup_uniform_mat4_copy(DRWShadingGroup *shgroup,
* and array-size used to determine the number of elements
* copied in draw_update_uniforms. */
for (int i = 0; i < 4; i++) {
- drw_shgroup_uniform_create_ex(shgroup, location, DRW_UNIFORM_FLOAT_COPY, &value[i], 0, 4, 4);
+ drw_shgroup_uniform_create_ex(
+ shgroup, location, DRW_UNIFORM_FLOAT_COPY, &value[i], GPU_SAMPLER_DEFAULT, 4, 4);
}
}
@@ -538,8 +551,13 @@ void DRW_shgroup_vertex_buffer_ex(DRWShadingGroup *shgroup,
#endif
return;
}
- drw_shgroup_uniform_create_ex(
- shgroup, location, DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE, vertex_buffer, 0, 0, 1);
+ drw_shgroup_uniform_create_ex(shgroup,
+ location,
+ DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE,
+ vertex_buffer,
+ GPU_SAMPLER_DEFAULT,
+ 0,
+ 1);
}
void DRW_shgroup_vertex_buffer_ref_ex(DRWShadingGroup *shgroup,
@@ -558,32 +576,47 @@ void DRW_shgroup_vertex_buffer_ref_ex(DRWShadingGroup *shgroup,
#endif
return;
}
- drw_shgroup_uniform_create_ex(
- shgroup, location, DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE_REF, vertex_buffer, 0, 0, 1);
+ drw_shgroup_uniform_create_ex(shgroup,
+ location,
+ DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE_REF,
+ vertex_buffer,
+ GPU_SAMPLER_DEFAULT,
+ 0,
+ 1);
}
void DRW_shgroup_buffer_texture(DRWShadingGroup *shgroup,
const char *name,
GPUVertBuf *vertex_buffer)
{
- int location = GPU_shader_get_ssbo(shgroup->shader, name);
+ int location = GPU_shader_get_texture_binding(shgroup->shader, name);
if (location == -1) {
return;
}
- drw_shgroup_uniform_create_ex(
- shgroup, location, DRW_UNIFORM_VERTEX_BUFFER_AS_TEXTURE, vertex_buffer, 0, 0, 1);
+ drw_shgroup_uniform_create_ex(shgroup,
+ location,
+ DRW_UNIFORM_VERTEX_BUFFER_AS_TEXTURE,
+ vertex_buffer,
+ GPU_SAMPLER_DEFAULT,
+ 0,
+ 1);
}
void DRW_shgroup_buffer_texture_ref(DRWShadingGroup *shgroup,
const char *name,
GPUVertBuf **vertex_buffer)
{
- int location = GPU_shader_get_ssbo(shgroup->shader, name);
+ int location = GPU_shader_get_texture_binding(shgroup->shader, name);
if (location == -1) {
return;
}
- drw_shgroup_uniform_create_ex(
- shgroup, location, DRW_UNIFORM_VERTEX_BUFFER_AS_TEXTURE_REF, vertex_buffer, 0, 0, 1);
+ drw_shgroup_uniform_create_ex(shgroup,
+ location,
+ DRW_UNIFORM_VERTEX_BUFFER_AS_TEXTURE_REF,
+ vertex_buffer,
+ GPU_SAMPLER_DEFAULT,
+ 0,
+ 1);
}
/** \} */
@@ -593,11 +626,11 @@ void DRW_shgroup_buffer_texture_ref(DRWShadingGroup *shgroup,
static void drw_call_calc_orco(Object *ob, float (*r_orcofacs)[4])
{
- ID *ob_data = (ob) ? ob->data : NULL;
+ ID *ob_data = (ob) ? static_cast<ID *>(ob->data) : nullptr;
float loc[3], size[3];
- float *texcoloc = NULL;
- float *texcosize = NULL;
- if (ob_data != NULL) {
+ float *texcoloc = nullptr;
+ float *texcosize = nullptr;
+ if (ob_data != nullptr) {
switch (GS(ob_data->name)) {
case ID_VO: {
BoundBox *bbox = BKE_volume_boundbox_get(ob);
@@ -608,7 +641,7 @@ static void drw_call_calc_orco(Object *ob, float (*r_orcofacs)[4])
break;
}
case ID_ME:
- BKE_mesh_texspace_get_reference((Mesh *)ob_data, NULL, &texcoloc, &texcosize);
+ BKE_mesh_texspace_get_reference((Mesh *)ob_data, nullptr, &texcoloc, &texcosize);
break;
case ID_CU_LEGACY: {
Curve *cu = (Curve *)ob_data;
@@ -628,7 +661,7 @@ static void drw_call_calc_orco(Object *ob, float (*r_orcofacs)[4])
}
}
- if ((texcoloc != NULL) && (texcosize != NULL)) {
+ if ((texcoloc != nullptr) && (texcosize != nullptr)) {
mul_v3_v3fl(r_orcofacs[1], texcosize, 2.0f);
invert_v3(r_orcofacs[1]);
sub_v3_v3v3(r_orcofacs[0], texcoloc, texcosize);
@@ -645,7 +678,7 @@ BLI_INLINE void drw_call_matrix_init(DRWObjectMatrix *ob_mats, Object *ob, float
{
copy_m4_m4(ob_mats->model, obmat);
if (ob) {
- copy_m4_m4(ob_mats->modelinverse, ob->imat);
+ copy_m4_m4(ob_mats->modelinverse, ob->world_to_object);
}
else {
/* WATCH: Can be costly. */
@@ -666,7 +699,7 @@ static void drw_call_obinfos_init(DRWObjectInfos *ob_infos, Object *ob)
/* TODO(fclem): this is rather costly to do at runtime. Maybe we can
* put it in ob->runtime and make depsgraph ensure it is up to date. */
BLI_hash_int_2d(BLI_hash_string(ob->id.name + 2), 0);
- ob_infos->ob_random = random * (1.0f / (float)0xFFFFFFFF);
+ ob_infos->ob_random = random * (1.0f / float(0xFFFFFFFF));
/* Object State. */
ob_infos->ob_flag = 1.0f; /* Required to have a correct sign */
ob_infos->ob_flag += (ob->base_flag & BASE_SELECTED) ? (1 << 1) : 0;
@@ -687,12 +720,12 @@ static void drw_call_obinfos_init(DRWObjectInfos *ob_infos, Object *ob)
static void drw_call_culling_init(DRWCullingState *cull, Object *ob)
{
const BoundBox *bbox;
- if (ob != NULL && (bbox = BKE_object_boundbox_get(ob))) {
+ if (ob != nullptr && (bbox = BKE_object_boundbox_get(ob))) {
float corner[3];
/* Get BoundSphere center and radius from the BoundBox. */
mid_v3_v3v3(cull->bsphere.center, bbox->vec[0], bbox->vec[6]);
- mul_v3_m4v3(corner, ob->obmat, bbox->vec[0]);
- mul_m4_v3(ob->obmat, cull->bsphere.center);
+ mul_v3_m4v3(corner, ob->object_to_world, bbox->vec[0]);
+ mul_m4_v3(ob->object_to_world, cull->bsphere.center);
cull->bsphere.radius = len_v3v3(cull->bsphere.center, corner);
/* Bypass test for very large objects (see T67319). */
@@ -705,16 +738,19 @@ static void drw_call_culling_init(DRWCullingState *cull, Object *ob)
cull->bsphere.radius = -1.0f;
}
/* Reset user data */
- cull->user_data = NULL;
+ cull->user_data = nullptr;
}
static DRWResourceHandle drw_resource_handle_new(float (*obmat)[4], Object *ob)
{
- DRWCullingState *culling = BLI_memblock_alloc(DST.vmempool->cullstates);
- DRWObjectMatrix *ob_mats = BLI_memblock_alloc(DST.vmempool->obmats);
+ DRWCullingState *culling = static_cast<DRWCullingState *>(
+ BLI_memblock_alloc(DST.vmempool->cullstates));
+ DRWObjectMatrix *ob_mats = static_cast<DRWObjectMatrix *>(
+ BLI_memblock_alloc(DST.vmempool->obmats));
/* FIXME Meh, not always needed but can be accessed after creation.
* Also it needs to have the same resource handle. */
- DRWObjectInfos *ob_infos = BLI_memblock_alloc(DST.vmempool->obinfos);
+ DRWObjectInfos *ob_infos = static_cast<DRWObjectInfos *>(
+ BLI_memblock_alloc(DST.vmempool->obinfos));
UNUSED_VARS(ob_infos);
DRWResourceHandle handle = DST.resource_handle;
@@ -731,7 +767,7 @@ static DRWResourceHandle drw_resource_handle_new(float (*obmat)[4], Object *ob)
return handle;
}
-uint32_t DRW_object_resource_id_get(Object *UNUSED(ob))
+uint32_t DRW_object_resource_id_get(Object * /*ob*/)
{
DRWResourceHandle handle = DST.ob_handle;
if (handle == 0) {
@@ -745,13 +781,13 @@ static DRWResourceHandle drw_resource_handle(DRWShadingGroup *shgroup,
float (*obmat)[4],
Object *ob)
{
- if (ob == NULL) {
- if (obmat == NULL) {
+ if (ob == nullptr) {
+ if (obmat == nullptr) {
DRWResourceHandle handle = 0;
return handle;
}
- return drw_resource_handle_new(obmat, NULL);
+ return drw_resource_handle_new(obmat, nullptr);
}
if (DST.ob_handle == 0) {
@@ -762,8 +798,8 @@ static DRWResourceHandle drw_resource_handle(DRWShadingGroup *shgroup,
if (shgroup->objectinfo) {
if (!DST.ob_state_obinfo_init) {
DST.ob_state_obinfo_init = true;
- DRWObjectInfos *ob_infos = DRW_memblock_elem_from_handle(DST.vmempool->obinfos,
- &DST.ob_handle);
+ DRWObjectInfos *ob_infos = static_cast<DRWObjectInfos *>(
+ DRW_memblock_elem_from_handle(DST.vmempool->obinfos, &DST.ob_handle));
drw_call_obinfos_init(ob_infos, ob);
}
@@ -783,20 +819,21 @@ static DRWResourceHandle drw_resource_handle(DRWShadingGroup *shgroup,
static void command_type_set(uint64_t *command_type_bits, int index, eDRWCommandType type)
{
- command_type_bits[index / 16] |= ((uint64_t)type) << ((index % 16) * 4);
+ command_type_bits[index / 16] |= uint64_t(type) << ((index % 16) * 4);
}
eDRWCommandType command_type_get(const uint64_t *command_type_bits, int index)
{
- return ((command_type_bits[index / 16] >> ((index % 16) * 4)) & 0xF);
+ return eDRWCommandType((command_type_bits[index / 16] >> ((index % 16) * 4)) & 0xF);
}
static void *drw_command_create(DRWShadingGroup *shgroup, eDRWCommandType type)
{
DRWCommandChunk *chunk = shgroup->cmd.last;
- if (chunk == NULL) {
- DRWCommandSmallChunk *smallchunk = BLI_memblock_alloc(DST.vmempool->commands_small);
+ if (chunk == nullptr) {
+ DRWCommandSmallChunk *smallchunk = static_cast<DRWCommandSmallChunk *>(
+ BLI_memblock_alloc(DST.vmempool->commands_small));
smallchunk->command_len = ARRAY_SIZE(smallchunk->commands);
smallchunk->command_used = 0;
smallchunk->command_type[0] = 0x0lu;
@@ -804,7 +841,7 @@ static void *drw_command_create(DRWShadingGroup *shgroup, eDRWCommandType type)
BLI_LINKS_APPEND(&shgroup->cmd, chunk);
}
else if (chunk->command_used == chunk->command_len) {
- chunk = BLI_memblock_alloc(DST.vmempool->commands);
+ chunk = static_cast<DRWCommandChunk *>(BLI_memblock_alloc(DST.vmempool->commands));
chunk->command_len = ARRAY_SIZE(chunk->commands);
chunk->command_used = 0;
memset(chunk->command_type, 0x0, sizeof(chunk->command_type));
@@ -818,7 +855,7 @@ static void *drw_command_create(DRWShadingGroup *shgroup, eDRWCommandType type)
static void drw_command_draw(DRWShadingGroup *shgroup, GPUBatch *batch, DRWResourceHandle handle)
{
- DRWCommandDraw *cmd = drw_command_create(shgroup, DRW_CMD_DRAW);
+ DRWCommandDraw *cmd = static_cast<DRWCommandDraw *>(drw_command_create(shgroup, DRW_CMD_DRAW));
cmd->batch = batch;
cmd->handle = handle;
}
@@ -826,7 +863,8 @@ static void drw_command_draw(DRWShadingGroup *shgroup, GPUBatch *batch, DRWResou
static void drw_command_draw_range(
DRWShadingGroup *shgroup, GPUBatch *batch, DRWResourceHandle handle, uint start, uint count)
{
- DRWCommandDrawRange *cmd = drw_command_create(shgroup, DRW_CMD_DRAW_RANGE);
+ DRWCommandDrawRange *cmd = static_cast<DRWCommandDrawRange *>(
+ drw_command_create(shgroup, DRW_CMD_DRAW_RANGE));
cmd->batch = batch;
cmd->handle = handle;
cmd->vert_first = start;
@@ -836,7 +874,8 @@ static void drw_command_draw_range(
static void drw_command_draw_instance(
DRWShadingGroup *shgroup, GPUBatch *batch, DRWResourceHandle handle, uint count, bool use_attr)
{
- DRWCommandDrawInstance *cmd = drw_command_create(shgroup, DRW_CMD_DRAW_INSTANCE);
+ DRWCommandDrawInstance *cmd = static_cast<DRWCommandDrawInstance *>(
+ drw_command_create(shgroup, DRW_CMD_DRAW_INSTANCE));
cmd->batch = batch;
cmd->handle = handle;
cmd->inst_count = count;
@@ -846,7 +885,8 @@ static void drw_command_draw_instance(
static void drw_command_draw_intance_range(
DRWShadingGroup *shgroup, GPUBatch *batch, DRWResourceHandle handle, uint start, uint count)
{
- DRWCommandDrawInstanceRange *cmd = drw_command_create(shgroup, DRW_CMD_DRAW_INSTANCE_RANGE);
+ DRWCommandDrawInstanceRange *cmd = static_cast<DRWCommandDrawInstanceRange *>(
+ drw_command_create(shgroup, DRW_CMD_DRAW_INSTANCE_RANGE));
cmd->batch = batch;
cmd->handle = handle;
cmd->inst_first = start;
@@ -858,7 +898,8 @@ static void drw_command_compute(DRWShadingGroup *shgroup,
int groups_y_len,
int groups_z_len)
{
- DRWCommandCompute *cmd = drw_command_create(shgroup, DRW_CMD_COMPUTE);
+ DRWCommandCompute *cmd = static_cast<DRWCommandCompute *>(
+ drw_command_create(shgroup, DRW_CMD_COMPUTE));
cmd->groups_x_len = groups_x_len;
cmd->groups_y_len = groups_y_len;
cmd->groups_z_len = groups_z_len;
@@ -866,19 +907,22 @@ static void drw_command_compute(DRWShadingGroup *shgroup,
static void drw_command_compute_ref(DRWShadingGroup *shgroup, int groups_ref[3])
{
- DRWCommandComputeRef *cmd = drw_command_create(shgroup, DRW_CMD_COMPUTE_REF);
+ DRWCommandComputeRef *cmd = static_cast<DRWCommandComputeRef *>(
+ drw_command_create(shgroup, DRW_CMD_COMPUTE_REF));
cmd->groups_ref = groups_ref;
}
static void drw_command_compute_indirect(DRWShadingGroup *shgroup, GPUStorageBuf *indirect_buf)
{
- DRWCommandComputeIndirect *cmd = drw_command_create(shgroup, DRW_CMD_COMPUTE_INDIRECT);
+ DRWCommandComputeIndirect *cmd = static_cast<DRWCommandComputeIndirect *>(
+ drw_command_create(shgroup, DRW_CMD_COMPUTE_INDIRECT));
cmd->indirect_buf = indirect_buf;
}
static void drw_command_barrier(DRWShadingGroup *shgroup, eGPUBarrier type)
{
- DRWCommandBarrier *cmd = drw_command_create(shgroup, DRW_CMD_BARRIER);
+ DRWCommandBarrier *cmd = static_cast<DRWCommandBarrier *>(
+ drw_command_create(shgroup, DRW_CMD_BARRIER));
cmd->type = type;
}
@@ -887,7 +931,8 @@ static void drw_command_draw_procedural(DRWShadingGroup *shgroup,
DRWResourceHandle handle,
uint vert_count)
{
- DRWCommandDrawProcedural *cmd = drw_command_create(shgroup, DRW_CMD_DRAW_PROCEDURAL);
+ DRWCommandDrawProcedural *cmd = static_cast<DRWCommandDrawProcedural *>(
+ drw_command_create(shgroup, DRW_CMD_DRAW_PROCEDURAL));
cmd->batch = batch;
cmd->handle = handle;
cmd->vert_count = vert_count;
@@ -898,7 +943,8 @@ static void drw_command_draw_indirect(DRWShadingGroup *shgroup,
DRWResourceHandle handle,
GPUStorageBuf *indirect_buf)
{
- DRWCommandDrawIndirect *cmd = drw_command_create(shgroup, DRW_CMD_DRAW_INDIRECT);
+ DRWCommandDrawIndirect *cmd = static_cast<DRWCommandDrawIndirect *>(
+ drw_command_create(shgroup, DRW_CMD_DRAW_INDIRECT));
cmd->batch = batch;
cmd->handle = handle;
cmd->indirect_buf = indirect_buf;
@@ -907,8 +953,9 @@ static void drw_command_draw_indirect(DRWShadingGroup *shgroup,
static void drw_command_set_select_id(DRWShadingGroup *shgroup, GPUVertBuf *buf, uint select_id)
{
/* Only one can be valid. */
- BLI_assert(buf == NULL || select_id == -1);
- DRWCommandSetSelectID *cmd = drw_command_create(shgroup, DRW_CMD_SELECTID);
+ BLI_assert(buf == nullptr || select_id == -1);
+ DRWCommandSetSelectID *cmd = static_cast<DRWCommandSetSelectID *>(
+ drw_command_create(shgroup, DRW_CMD_SELECTID));
cmd->select_buf = buf;
cmd->select_id = select_id;
}
@@ -921,7 +968,8 @@ static void drw_command_set_stencil_mask(DRWShadingGroup *shgroup,
BLI_assert(write_mask <= 0xFF);
BLI_assert(reference <= 0xFF);
BLI_assert(compare_mask <= 0xFF);
- DRWCommandSetStencil *cmd = drw_command_create(shgroup, DRW_CMD_STENCIL);
+ DRWCommandSetStencil *cmd = static_cast<DRWCommandSetStencil *>(
+ drw_command_create(shgroup, DRW_CMD_STENCIL));
cmd->write_mask = write_mask;
cmd->comp_mask = compare_mask;
cmd->ref = reference;
@@ -936,7 +984,8 @@ static void drw_command_clear(DRWShadingGroup *shgroup,
float depth,
uchar stencil)
{
- DRWCommandClear *cmd = drw_command_create(shgroup, DRW_CMD_CLEAR);
+ DRWCommandClear *cmd = static_cast<DRWCommandClear *>(
+ drw_command_create(shgroup, DRW_CMD_CLEAR));
cmd->clear_channels = channels;
cmd->r = r;
cmd->g = g;
@@ -951,7 +1000,8 @@ static void drw_command_set_mutable_state(DRWShadingGroup *shgroup,
DRWState disable)
{
/* TODO: Restrict what state can be changed. */
- DRWCommandSetMutableState *cmd = drw_command_create(shgroup, DRW_CMD_DRWSTATE);
+ DRWCommandSetMutableState *cmd = static_cast<DRWCommandSetMutableState *>(
+ drw_command_create(shgroup, DRW_CMD_DRWSTATE));
cmd->enable = enable;
cmd->disable = disable;
}
@@ -959,21 +1009,21 @@ static void drw_command_set_mutable_state(DRWShadingGroup *shgroup,
void DRW_shgroup_call_ex(DRWShadingGroup *shgroup,
Object *ob,
float (*obmat)[4],
- struct GPUBatch *geom,
+ GPUBatch *geom,
bool bypass_culling,
void *user_data)
{
- BLI_assert(geom != NULL);
+ BLI_assert(geom != nullptr);
if (G.f & G_FLAG_PICKSEL) {
- drw_command_set_select_id(shgroup, NULL, DST.select_id);
+ drw_command_set_select_id(shgroup, nullptr, DST.select_id);
}
- DRWResourceHandle handle = drw_resource_handle(shgroup, ob ? ob->obmat : obmat, ob);
+ DRWResourceHandle handle = drw_resource_handle(shgroup, ob ? ob->object_to_world : obmat, ob);
drw_command_draw(shgroup, geom, handle);
/* Culling data. */
if (user_data || bypass_culling) {
- DRWCullingState *culling = DRW_memblock_elem_from_handle(DST.vmempool->cullstates,
- &DST.ob_handle);
+ DRWCullingState *culling = static_cast<DRWCullingState *>(
+ DRW_memblock_elem_from_handle(DST.vmempool->cullstates, &DST.ob_handle));
if (user_data) {
culling->user_data = user_data;
@@ -986,24 +1036,24 @@ void DRW_shgroup_call_ex(DRWShadingGroup *shgroup,
}
void DRW_shgroup_call_range(
- DRWShadingGroup *shgroup, struct Object *ob, GPUBatch *geom, uint v_sta, uint v_num)
+ DRWShadingGroup *shgroup, Object *ob, GPUBatch *geom, uint v_sta, uint v_num)
{
- BLI_assert(geom != NULL);
+ BLI_assert(geom != nullptr);
if (G.f & G_FLAG_PICKSEL) {
- drw_command_set_select_id(shgroup, NULL, DST.select_id);
+ drw_command_set_select_id(shgroup, nullptr, DST.select_id);
}
- DRWResourceHandle handle = drw_resource_handle(shgroup, ob ? ob->obmat : NULL, ob);
+ DRWResourceHandle handle = drw_resource_handle(shgroup, ob ? ob->object_to_world : nullptr, ob);
drw_command_draw_range(shgroup, geom, handle, v_sta, v_num);
}
void DRW_shgroup_call_instance_range(
- DRWShadingGroup *shgroup, Object *ob, struct GPUBatch *geom, uint i_sta, uint i_num)
+ DRWShadingGroup *shgroup, Object *ob, GPUBatch *geom, uint i_sta, uint i_num)
{
- BLI_assert(geom != NULL);
+ BLI_assert(geom != nullptr);
if (G.f & G_FLAG_PICKSEL) {
- drw_command_set_select_id(shgroup, NULL, DST.select_id);
+ drw_command_set_select_id(shgroup, nullptr, DST.select_id);
}
- DRWResourceHandle handle = drw_resource_handle(shgroup, ob ? ob->obmat : NULL, ob);
+ DRWResourceHandle handle = drw_resource_handle(shgroup, ob ? ob->object_to_world : nullptr, ob);
drw_command_draw_intance_range(shgroup, geom, handle, i_sta, i_num);
}
@@ -1045,29 +1095,29 @@ static void drw_shgroup_call_procedural_add_ex(DRWShadingGroup *shgroup,
uint vert_count)
{
BLI_assert(vert_count > 0);
- BLI_assert(geom != NULL);
+ BLI_assert(geom != nullptr);
if (G.f & G_FLAG_PICKSEL) {
- drw_command_set_select_id(shgroup, NULL, DST.select_id);
+ drw_command_set_select_id(shgroup, nullptr, DST.select_id);
}
- DRWResourceHandle handle = drw_resource_handle(shgroup, ob ? ob->obmat : NULL, ob);
+ DRWResourceHandle handle = drw_resource_handle(shgroup, ob ? ob->object_to_world : nullptr, ob);
drw_command_draw_procedural(shgroup, geom, handle, vert_count);
}
void DRW_shgroup_call_procedural_points(DRWShadingGroup *shgroup, Object *ob, uint point_count)
{
- struct GPUBatch *geom = drw_cache_procedural_points_get();
+ GPUBatch *geom = drw_cache_procedural_points_get();
drw_shgroup_call_procedural_add_ex(shgroup, geom, ob, point_count);
}
void DRW_shgroup_call_procedural_lines(DRWShadingGroup *shgroup, Object *ob, uint line_count)
{
- struct GPUBatch *geom = drw_cache_procedural_lines_get();
+ GPUBatch *geom = drw_cache_procedural_lines_get();
drw_shgroup_call_procedural_add_ex(shgroup, geom, ob, line_count * 2);
}
void DRW_shgroup_call_procedural_triangles(DRWShadingGroup *shgroup, Object *ob, uint tri_count)
{
- struct GPUBatch *geom = drw_cache_procedural_triangles_get();
+ GPUBatch *geom = drw_cache_procedural_triangles_get();
drw_shgroup_call_procedural_add_ex(shgroup, geom, ob, tri_count * 3);
}
@@ -1076,7 +1126,7 @@ void DRW_shgroup_call_procedural_indirect(DRWShadingGroup *shgroup,
Object *ob,
GPUStorageBuf *indirect_buf)
{
- struct GPUBatch *geom = NULL;
+ GPUBatch *geom = nullptr;
switch (primitive_type) {
case GPU_PRIM_POINTS:
geom = drw_cache_procedural_points_get();
@@ -1097,43 +1147,40 @@ void DRW_shgroup_call_procedural_indirect(DRWShadingGroup *shgroup,
break;
}
if (G.f & G_FLAG_PICKSEL) {
- drw_command_set_select_id(shgroup, NULL, DST.select_id);
+ drw_command_set_select_id(shgroup, nullptr, DST.select_id);
}
- DRWResourceHandle handle = drw_resource_handle(shgroup, ob ? ob->obmat : NULL, ob);
+ DRWResourceHandle handle = drw_resource_handle(shgroup, ob ? ob->object_to_world : nullptr, ob);
drw_command_draw_indirect(shgroup, geom, handle, indirect_buf);
}
-void DRW_shgroup_call_instances(DRWShadingGroup *shgroup,
- Object *ob,
- struct GPUBatch *geom,
- uint count)
+void DRW_shgroup_call_instances(DRWShadingGroup *shgroup, Object *ob, GPUBatch *geom, uint count)
{
- BLI_assert(geom != NULL);
+ BLI_assert(geom != nullptr);
if (G.f & G_FLAG_PICKSEL) {
- drw_command_set_select_id(shgroup, NULL, DST.select_id);
+ drw_command_set_select_id(shgroup, nullptr, DST.select_id);
}
- DRWResourceHandle handle = drw_resource_handle(shgroup, ob ? ob->obmat : NULL, ob);
+ DRWResourceHandle handle = drw_resource_handle(shgroup, ob ? ob->object_to_world : nullptr, ob);
drw_command_draw_instance(shgroup, geom, handle, count, false);
}
void DRW_shgroup_call_instances_with_attrs(DRWShadingGroup *shgroup,
Object *ob,
- struct GPUBatch *geom,
- struct GPUBatch *inst_attributes)
+ GPUBatch *geom,
+ GPUBatch *inst_attributes)
{
- BLI_assert(geom != NULL);
- BLI_assert(inst_attributes != NULL);
+ BLI_assert(geom != nullptr);
+ BLI_assert(inst_attributes != nullptr);
if (G.f & G_FLAG_PICKSEL) {
- drw_command_set_select_id(shgroup, NULL, DST.select_id);
+ drw_command_set_select_id(shgroup, nullptr, DST.select_id);
}
- DRWResourceHandle handle = drw_resource_handle(shgroup, ob ? ob->obmat : NULL, ob);
+ DRWResourceHandle handle = drw_resource_handle(shgroup, ob ? ob->object_to_world : nullptr, ob);
GPUBatch *batch = DRW_temp_batch_instance_request(
- DST.vmempool->idatalist, NULL, inst_attributes, geom);
+ DST.vmempool->idatalist, nullptr, inst_attributes, geom);
drw_command_draw_instance(shgroup, batch, handle, 0, true);
}
#define SCULPT_DEBUG_BUFFERS (G.debug_value == 889)
-typedef struct DRWSculptCallbackData {
+struct DRWSculptCallbackData {
Object *ob;
DRWShadingGroup **shading_groups;
int num_shading_groups;
@@ -1144,7 +1191,9 @@ typedef struct DRWSculptCallbackData {
bool fast_mode; /* Set by draw manager. Do not init. */
int debug_node_nr;
-} DRWSculptCallbackData;
+ PBVHAttrReq *attrs;
+ int attrs_num;
+};
#define SCULPT_DEBUG_COLOR(id) (sculpt_debug_colors[id % 9])
static float sculpt_debug_colors[9][4] = {
@@ -1159,29 +1208,35 @@ static float sculpt_debug_colors[9][4] = {
{0.7f, 0.2f, 1.0f, 1.0f},
};
-static void sculpt_draw_cb(DRWSculptCallbackData *scd, GPU_PBVH_Buffers *buffers)
+static void sculpt_draw_cb(DRWSculptCallbackData *scd,
+ PBVHBatches *batches,
+ PBVH_GPU_Args *pbvh_draw_args)
{
- if (!buffers) {
+ if (!batches) {
return;
}
- /* Meh... use_mask is a bit misleading here. */
- if (scd->use_mask && !GPU_pbvh_buffers_has_overlays(buffers)) {
- return;
+ int primcount;
+ GPUBatch *geom;
+
+ if (!scd->use_wire) {
+ geom = DRW_pbvh_tris_get(batches, scd->attrs, scd->attrs_num, pbvh_draw_args, &primcount);
+ }
+ else {
+ geom = DRW_pbvh_lines_get(batches, scd->attrs, scd->attrs_num, pbvh_draw_args, &primcount);
}
- GPUBatch *geom = GPU_pbvh_buffers_batch_get(buffers, scd->fast_mode, scd->use_wire);
short index = 0;
if (scd->use_mats) {
- index = GPU_pbvh_buffers_material_index_get(buffers);
+ index = drw_pbvh_material_index_get(batches);
if (index >= scd->num_shading_groups) {
index = 0;
}
}
DRWShadingGroup *shgrp = scd->shading_groups[index];
- if (geom != NULL && shgrp != NULL) {
+ if (geom != nullptr && shgrp != nullptr) {
if (SCULPT_DEBUG_BUFFERS) {
/* Color each buffers in different colors. Only work in solid/Xray mode. */
shgrp = DRW_shgroup_create_sub(shgrp);
@@ -1228,7 +1283,7 @@ static void drw_sculpt_get_frustum_planes(Object *ob, float planes[6][4])
* 4x4 matrix is done by multiplying with the transpose inverse.
* The inverse cancels out here since we transform by inverse(obmat). */
float tmat[4][4];
- transpose_m4_m4(tmat, ob->obmat);
+ transpose_m4_m4(tmat, ob->object_to_world);
for (int i = 0; i < 6; i++) {
mul_m4_v4(tmat, planes[i]);
}
@@ -1237,7 +1292,7 @@ static void drw_sculpt_get_frustum_planes(Object *ob, float planes[6][4])
static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd)
{
/* PBVH should always exist for non-empty meshes, created by depsgraph eval. */
- PBVH *pbvh = (scd->ob->sculpt) ? scd->ob->sculpt->pbvh : NULL;
+ PBVH *pbvh = (scd->ob->sculpt) ? scd->ob->sculpt->pbvh : nullptr;
if (!pbvh) {
return;
}
@@ -1246,8 +1301,8 @@ static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd)
RegionView3D *rv3d = drwctx->rv3d;
const bool navigating = rv3d && (rv3d->rflag & RV3D_NAVIGATING);
- Paint *p = NULL;
- if (drwctx->evil_C != NULL) {
+ Paint *p = nullptr;
+ if (drwctx->evil_C != nullptr) {
p = BKE_paint_get_active_from_context(drwctx->evil_C);
}
@@ -1291,20 +1346,22 @@ static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd)
update_only_visible = true;
}
- Mesh *mesh = scd->ob->data;
- BKE_pbvh_update_normals(pbvh, mesh->runtime.subdiv_ccg);
+ Mesh *mesh = static_cast<Mesh *>(scd->ob->data);
+ BKE_pbvh_update_normals(pbvh, mesh->runtime->subdiv_ccg);
BKE_pbvh_draw_cb(pbvh,
update_only_visible,
&update_frustum,
&draw_frustum,
- (void (*)(void *, GPU_PBVH_Buffers *))sculpt_draw_cb,
+ (void (*)(void *, PBVHBatches *, PBVH_GPU_Args *))sculpt_draw_cb,
scd,
- scd->use_mats);
+ scd->use_mats,
+ scd->attrs,
+ scd->attrs_num);
if (SCULPT_DEBUG_BUFFERS) {
int debug_node_nr = 0;
- DRW_debug_modelmat(scd->ob->obmat);
+ DRW_debug_modelmat(scd->ob->object_to_world);
BKE_pbvh_draw_debug_cb(
pbvh,
(void (*)(PBVHNode * n, void *d, const float min[3], const float max[3], PBVHNodeFlags f))
@@ -1313,50 +1370,161 @@ static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd)
}
}
-void DRW_shgroup_call_sculpt(DRWShadingGroup *shgroup, Object *ob, bool use_wire, bool use_mask)
+void DRW_shgroup_call_sculpt(DRWShadingGroup *shgroup,
+ Object *ob,
+ bool use_wire,
+ bool use_mask,
+ bool use_fset,
+ bool use_color,
+ bool use_uv)
{
- DRWSculptCallbackData scd = {
- .ob = ob,
- .shading_groups = &shgroup,
- .num_shading_groups = 1,
- .use_wire = use_wire,
- .use_mats = false,
- .use_mask = use_mask,
- };
+ DRWSculptCallbackData scd{};
+ scd.ob = ob;
+ scd.shading_groups = &shgroup;
+ scd.num_shading_groups = 1;
+ scd.use_wire = use_wire;
+ scd.use_mats = false;
+ scd.use_mask = use_mask;
+
+ PBVHAttrReq attrs[16];
+ int attrs_num = 0;
+
+ memset(attrs, 0, sizeof(attrs));
+
+ /* NOTE: these are NOT #eCustomDataType, they are extended values, ASAN may warn about this. */
+ attrs[attrs_num++].type = (eCustomDataType)CD_PBVH_CO_TYPE;
+ attrs[attrs_num++].type = (eCustomDataType)CD_PBVH_NO_TYPE;
+
+ if (use_mask) {
+ attrs[attrs_num++].type = (eCustomDataType)CD_PBVH_MASK_TYPE;
+ }
+
+ if (use_fset) {
+ attrs[attrs_num++].type = (eCustomDataType)CD_PBVH_FSET_TYPE;
+ }
+
+ Mesh *me = BKE_object_get_original_mesh(ob);
+
+ if (use_color) {
+ CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me->id);
+
+ if (layer) {
+ eAttrDomain domain = BKE_id_attribute_domain(&me->id, layer);
+
+ attrs[attrs_num].type = eCustomDataType(layer->type);
+ attrs[attrs_num].domain = domain;
+
+ BLI_strncpy(attrs[attrs_num].name, layer->name, sizeof(attrs[attrs_num].name));
+ attrs_num++;
+ }
+ }
+
+ if (use_uv) {
+ int layer_i = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV);
+ if (layer_i != -1) {
+ CustomDataLayer *layer = me->ldata.layers + layer_i;
+
+ attrs[attrs_num].type = CD_MLOOPUV;
+ attrs[attrs_num].domain = ATTR_DOMAIN_CORNER;
+ BLI_strncpy(attrs[attrs_num].name, layer->name, sizeof(attrs[attrs_num].name));
+
+ attrs_num++;
+ }
+ }
+
+ scd.attrs = attrs;
+ scd.attrs_num = attrs_num;
+
drw_sculpt_generate_calls(&scd);
}
void DRW_shgroup_call_sculpt_with_materials(DRWShadingGroup **shgroups,
+ GPUMaterial **gpumats,
int num_shgroups,
Object *ob)
{
- DRWSculptCallbackData scd = {
- .ob = ob,
- .shading_groups = shgroups,
- .num_shading_groups = num_shgroups,
- .use_wire = false,
- .use_mats = true,
- .use_mask = false,
- };
+ DRW_Attributes draw_attrs;
+ DRW_MeshCDMask cd_needed;
+
+ if (gpumats) {
+ DRW_mesh_get_attributes(ob, (Mesh *)ob->data, gpumats, num_shgroups, &draw_attrs, &cd_needed);
+ }
+ else {
+ memset(&draw_attrs, 0, sizeof(draw_attrs));
+ memset(&cd_needed, 0, sizeof(cd_needed));
+ }
+
+ int attrs_num = 2 + draw_attrs.num_requests;
+
+ /* UV maps are not in attribute requests. */
+ attrs_num += count_bits_i(cd_needed.uv);
+
+ blender::Array<PBVHAttrReq, 16> attrs(attrs_num, PBVHAttrReq{});
+
+ int attrs_i = 0;
+
+ /* NOTE: these are NOT #eCustomDataType, they are extended values, ASAN may warn about this. */
+ attrs[attrs_i++].type = (eCustomDataType)CD_PBVH_CO_TYPE;
+ attrs[attrs_i++].type = (eCustomDataType)CD_PBVH_NO_TYPE;
+
+ for (int i = 0; i < draw_attrs.num_requests; i++) {
+ DRW_AttributeRequest *req = draw_attrs.requests + i;
+
+ attrs[attrs_i].type = req->cd_type;
+ attrs[attrs_i].domain = req->domain;
+ BLI_strncpy(attrs[attrs_i].name, req->attribute_name, sizeof(PBVHAttrReq::name));
+ attrs_i++;
+ }
+
+ /* UV maps are not in attribute requests. */
+ Mesh *me = (Mesh *)ob->data;
+
+ for (uint i = 0; i < 32; i++) {
+ if (cd_needed.uv & (1 << i)) {
+ int layer_i = CustomData_get_layer_index_n(&me->ldata, CD_MLOOPUV, i);
+ CustomDataLayer *layer = layer_i != -1 ? me->ldata.layers + layer_i : nullptr;
+
+ if (layer) {
+ attrs[attrs_i].type = CD_MLOOPUV;
+ attrs[attrs_i].domain = ATTR_DOMAIN_CORNER;
+ BLI_strncpy(attrs[attrs_i].name, layer->name, sizeof(PBVHAttrReq::name));
+ attrs_i++;
+ }
+ }
+ }
+
+ attrs_num = attrs_i;
+
+ DRWSculptCallbackData scd{};
+ scd.ob = ob;
+ scd.shading_groups = shgroups;
+ scd.num_shading_groups = num_shgroups;
+ scd.use_wire = false;
+ scd.use_mats = true;
+ scd.use_mask = false;
+ scd.attrs = attrs.data();
+ scd.attrs_num = attrs_num;
+
drw_sculpt_generate_calls(&scd);
}
static GPUVertFormat inst_select_format = {0};
DRWCallBuffer *DRW_shgroup_call_buffer(DRWShadingGroup *shgroup,
- struct GPUVertFormat *format,
+ GPUVertFormat *format,
GPUPrimType prim_type)
{
BLI_assert(ELEM(prim_type, GPU_PRIM_POINTS, GPU_PRIM_LINES, GPU_PRIM_TRI_FAN));
- BLI_assert(format != NULL);
+ BLI_assert(format != nullptr);
- DRWCallBuffer *callbuf = BLI_memblock_alloc(DST.vmempool->callbuffers);
+ DRWCallBuffer *callbuf = static_cast<DRWCallBuffer *>(
+ BLI_memblock_alloc(DST.vmempool->callbuffers));
callbuf->buf = DRW_temp_buffer_request(DST.vmempool->idatalist, format, &callbuf->count);
- callbuf->buf_select = NULL;
+ callbuf->buf_select = nullptr;
callbuf->count = 0;
if (G.f & G_FLAG_PICKSEL) {
- /* Not actually used for rendering but alloced in one chunk. */
+ /* Not actually used for rendering but allocated in one chunk. */
if (inst_select_format.attr_len == 0) {
GPU_vertformat_attr_add(&inst_select_format, "selectId", GPU_COMP_I32, 1, GPU_FETCH_INT);
}
@@ -1365,7 +1533,7 @@ DRWCallBuffer *DRW_shgroup_call_buffer(DRWShadingGroup *shgroup,
drw_command_set_select_id(shgroup, callbuf->buf_select, -1);
}
- DRWResourceHandle handle = drw_resource_handle(shgroup, NULL, NULL);
+ DRWResourceHandle handle = drw_resource_handle(shgroup, nullptr, nullptr);
GPUBatch *batch = DRW_temp_batch_request(DST.vmempool->idatalist, callbuf->buf, prim_type);
drw_command_draw(shgroup, batch, handle);
@@ -1373,19 +1541,20 @@ DRWCallBuffer *DRW_shgroup_call_buffer(DRWShadingGroup *shgroup,
}
DRWCallBuffer *DRW_shgroup_call_buffer_instance(DRWShadingGroup *shgroup,
- struct GPUVertFormat *format,
+ GPUVertFormat *format,
GPUBatch *geom)
{
- BLI_assert(geom != NULL);
- BLI_assert(format != NULL);
+ BLI_assert(geom != nullptr);
+ BLI_assert(format != nullptr);
- DRWCallBuffer *callbuf = BLI_memblock_alloc(DST.vmempool->callbuffers);
+ DRWCallBuffer *callbuf = static_cast<DRWCallBuffer *>(
+ BLI_memblock_alloc(DST.vmempool->callbuffers));
callbuf->buf = DRW_temp_buffer_request(DST.vmempool->idatalist, format, &callbuf->count);
- callbuf->buf_select = NULL;
+ callbuf->buf_select = nullptr;
callbuf->count = 0;
if (G.f & G_FLAG_PICKSEL) {
- /* Not actually used for rendering but alloced in one chunk. */
+ /* Not actually used for rendering but allocated in one chunk. */
if (inst_select_format.attr_len == 0) {
GPU_vertformat_attr_add(&inst_select_format, "selectId", GPU_COMP_I32, 1, GPU_FETCH_INT);
}
@@ -1394,9 +1563,9 @@ DRWCallBuffer *DRW_shgroup_call_buffer_instance(DRWShadingGroup *shgroup,
drw_command_set_select_id(shgroup, callbuf->buf_select, -1);
}
- DRWResourceHandle handle = drw_resource_handle(shgroup, NULL, NULL);
+ DRWResourceHandle handle = drw_resource_handle(shgroup, nullptr, nullptr);
GPUBatch *batch = DRW_temp_batch_instance_request(
- DST.vmempool->idatalist, callbuf->buf, NULL, geom);
+ DST.vmempool->idatalist, callbuf->buf, nullptr, geom);
drw_command_draw(shgroup, batch, handle);
return callbuf;
@@ -1457,9 +1626,10 @@ void DRW_buffer_add_entry_array(DRWCallBuffer *callbuf, const void *attr[], uint
static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader)
{
- shgroup->uniforms = NULL;
- shgroup->uniform_attrs = NULL;
+ shgroup->uniforms = nullptr;
+ shgroup->uniform_attrs = nullptr;
+ int clipping_ubo_location = GPU_shader_get_builtin_block(shader, GPU_UNIFORM_BLOCK_DRW_CLIPPING);
int view_ubo_location = GPU_shader_get_builtin_block(shader, GPU_UNIFORM_BLOCK_VIEW);
int model_ubo_location = GPU_shader_get_builtin_block(shader, GPU_UNIFORM_BLOCK_MODEL);
int info_ubo_location = GPU_shader_get_builtin_block(shader, GPU_UNIFORM_BLOCK_INFO);
@@ -1480,22 +1650,22 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader)
if (chunkid_location != -1) {
drw_shgroup_uniform_create_ex(
- shgroup, chunkid_location, DRW_UNIFORM_RESOURCE_CHUNK, NULL, 0, 0, 1);
+ shgroup, chunkid_location, DRW_UNIFORM_RESOURCE_CHUNK, nullptr, GPU_SAMPLER_DEFAULT, 0, 1);
}
if (resourceid_location != -1) {
drw_shgroup_uniform_create_ex(
- shgroup, resourceid_location, DRW_UNIFORM_RESOURCE_ID, NULL, 0, 0, 1);
+ shgroup, resourceid_location, DRW_UNIFORM_RESOURCE_ID, nullptr, GPU_SAMPLER_DEFAULT, 0, 1);
}
if (baseinst_location != -1) {
drw_shgroup_uniform_create_ex(
- shgroup, baseinst_location, DRW_UNIFORM_BASE_INSTANCE, NULL, 0, 0, 1);
+ shgroup, baseinst_location, DRW_UNIFORM_BASE_INSTANCE, nullptr, GPU_SAMPLER_DEFAULT, 0, 1);
}
if (model_ubo_location != -1) {
drw_shgroup_uniform_create_ex(
- shgroup, model_ubo_location, DRW_UNIFORM_BLOCK_OBMATS, NULL, 0, 0, 1);
+ shgroup, model_ubo_location, DRW_UNIFORM_BLOCK_OBMATS, nullptr, GPU_SAMPLER_DEFAULT, 0, 1);
}
else {
/* NOTE: This is only here to support old hardware fallback where uniform buffer is still
@@ -1503,17 +1673,23 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader)
int model = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODEL);
int modelinverse = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODEL_INV);
if (model != -1) {
- drw_shgroup_uniform_create_ex(shgroup, model, DRW_UNIFORM_MODEL_MATRIX, NULL, 0, 0, 1);
+ drw_shgroup_uniform_create_ex(
+ shgroup, model, DRW_UNIFORM_MODEL_MATRIX, nullptr, GPU_SAMPLER_DEFAULT, 0, 1);
}
if (modelinverse != -1) {
- drw_shgroup_uniform_create_ex(
- shgroup, modelinverse, DRW_UNIFORM_MODEL_MATRIX_INVERSE, NULL, 0, 0, 1);
+ drw_shgroup_uniform_create_ex(shgroup,
+ modelinverse,
+ DRW_UNIFORM_MODEL_MATRIX_INVERSE,
+ nullptr,
+ GPU_SAMPLER_DEFAULT,
+ 0,
+ 1);
}
}
if (info_ubo_location != -1) {
drw_shgroup_uniform_create_ex(
- shgroup, info_ubo_location, DRW_UNIFORM_BLOCK_OBINFOS, NULL, 0, 0, 1);
+ shgroup, info_ubo_location, DRW_UNIFORM_BLOCK_OBINFOS, nullptr, GPU_SAMPLER_DEFAULT, 0, 1);
/* Abusing this loc to tell shgroup we need the obinfos. */
shgroup->objectinfo = 1;
@@ -1524,27 +1700,46 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader)
if (view_ubo_location != -1) {
drw_shgroup_uniform_create_ex(
- shgroup, view_ubo_location, DRW_UNIFORM_BLOCK, G_draw.view_ubo, 0, 0, 1);
+ shgroup, view_ubo_location, DRW_UNIFORM_BLOCK, G_draw.view_ubo, GPU_SAMPLER_DEFAULT, 0, 1);
+ }
+
+ if (clipping_ubo_location) {
+ drw_shgroup_uniform_create_ex(shgroup,
+ clipping_ubo_location,
+ DRW_UNIFORM_BLOCK,
+ G_draw.clipping_ubo,
+ GPU_SAMPLER_DEFAULT,
+ 0,
+ 1);
}
#ifdef DEBUG
- int debug_print_location = GPU_shader_get_builtin_ssbo(shader, GPU_STORAGE_BUFFER_DEBUG_PRINT);
- if (debug_print_location != -1) {
- GPUStorageBuf *buf = drw_debug_gpu_print_buf_get();
- drw_shgroup_uniform_create_ex(
- shgroup, debug_print_location, DRW_UNIFORM_STORAGE_BLOCK, buf, 0, 0, 1);
+ /* TODO(Metal): Support Shader debug print.
+ * This is not currently supported by Metal Backend. */
+ if (GPU_backend_get_type() != GPU_BACKEND_METAL) {
+ int debug_print_location = GPU_shader_get_builtin_ssbo(shader, GPU_STORAGE_BUFFER_DEBUG_PRINT);
+ if (debug_print_location != -1) {
+ GPUStorageBuf *buf = drw_debug_gpu_print_buf_get();
+ drw_shgroup_uniform_create_ex(shgroup,
+ debug_print_location,
+ DRW_UNIFORM_STORAGE_BLOCK,
+ buf,
+ GPU_SAMPLER_DEFAULT,
+ 0,
+ 1);
# ifndef DISABLE_DEBUG_SHADER_PRINT_BARRIER
- /* Add a barrier to allow multiple shader writing to the same buffer. */
- DRW_shgroup_barrier(shgroup, GPU_BARRIER_SHADER_STORAGE);
+ /* Add a barrier to allow multiple shader writing to the same buffer. */
+ DRW_shgroup_barrier(shgroup, GPU_BARRIER_SHADER_STORAGE);
# endif
- }
+ }
- int debug_draw_location = GPU_shader_get_builtin_ssbo(shader, GPU_STORAGE_BUFFER_DEBUG_VERTS);
- if (debug_draw_location != -1) {
- GPUStorageBuf *buf = drw_debug_gpu_draw_buf_get();
- drw_shgroup_uniform_create_ex(
- shgroup, debug_draw_location, DRW_UNIFORM_STORAGE_BLOCK, buf, 0, 0, 1);
- /* NOTE(fclem): No barrier as ordering is not important. */
+ int debug_draw_location = GPU_shader_get_builtin_ssbo(shader, GPU_STORAGE_BUFFER_DEBUG_VERTS);
+ if (debug_draw_location != -1) {
+ GPUStorageBuf *buf = drw_debug_gpu_draw_buf_get();
+ drw_shgroup_uniform_create_ex(
+ shgroup, debug_draw_location, DRW_UNIFORM_STORAGE_BLOCK, buf, GPU_SAMPLER_DEFAULT, 0, 1);
+ /* NOTE(fclem): No barrier as ordering is not important. */
+ }
}
#endif
@@ -1562,15 +1757,16 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader)
BLI_assert(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MVP) == -1);
}
-static DRWShadingGroup *drw_shgroup_create_ex(struct GPUShader *shader, DRWPass *pass)
+static DRWShadingGroup *drw_shgroup_create_ex(GPUShader *shader, DRWPass *pass)
{
- DRWShadingGroup *shgroup = BLI_memblock_alloc(DST.vmempool->shgroups);
+ DRWShadingGroup *shgroup = static_cast<DRWShadingGroup *>(
+ BLI_memblock_alloc(DST.vmempool->shgroups));
BLI_LINKS_APPEND(&pass->shgroups, shgroup);
shgroup->shader = shader;
- shgroup->cmd.first = NULL;
- shgroup->cmd.last = NULL;
+ shgroup->cmd.first = nullptr;
+ shgroup->cmd.last = nullptr;
shgroup->pass_handle = pass->handle;
return shgroup;
@@ -1580,14 +1776,14 @@ static DRWShadingGroup *drw_shgroup_material_create_ex(GPUPass *gpupass, DRWPass
{
if (!gpupass) {
/* Shader compilation error */
- return NULL;
+ return nullptr;
}
GPUShader *sh = GPU_pass_shader_get(gpupass);
if (!sh) {
/* Shader not yet compiled */
- return NULL;
+ return nullptr;
}
DRWShadingGroup *grp = drw_shgroup_create_ex(sh, pass);
@@ -1601,12 +1797,12 @@ static void drw_shgroup_material_texture(DRWShadingGroup *grp,
{
DRW_shgroup_uniform_texture_ex(grp, name, gputex, state);
- GPUTexture **gputex_ref = BLI_memblock_alloc(DST.vmempool->images);
+ GPUTexture **gputex_ref = static_cast<GPUTexture **>(BLI_memblock_alloc(DST.vmempool->images));
*gputex_ref = gputex;
GPU_texture_ref(gputex);
}
-void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, struct GPUMaterial *material)
+void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, GPUMaterial *material)
{
ListBase textures = GPU_material_textures(material);
@@ -1615,41 +1811,57 @@ void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, struct GPUMaterial
if (tex->ima) {
/* Image */
GPUTexture *gputex;
- ImageUser *iuser = tex->iuser_available ? &tex->iuser : NULL;
+ ImageUser *iuser = tex->iuser_available ? &tex->iuser : nullptr;
if (tex->tiled_mapping_name[0]) {
- gputex = BKE_image_get_gpu_tiles(tex->ima, iuser, NULL);
- drw_shgroup_material_texture(grp, gputex, tex->sampler_name, tex->sampler_state);
- gputex = BKE_image_get_gpu_tilemap(tex->ima, iuser, NULL);
- drw_shgroup_material_texture(grp, gputex, tex->tiled_mapping_name, tex->sampler_state);
+ gputex = BKE_image_get_gpu_tiles(tex->ima, iuser, nullptr);
+ drw_shgroup_material_texture(
+ grp, gputex, tex->sampler_name, eGPUSamplerState(tex->sampler_state));
+ gputex = BKE_image_get_gpu_tilemap(tex->ima, iuser, nullptr);
+ drw_shgroup_material_texture(
+ grp, gputex, tex->tiled_mapping_name, eGPUSamplerState(tex->sampler_state));
}
else {
- gputex = BKE_image_get_gpu_texture(tex->ima, iuser, NULL);
- drw_shgroup_material_texture(grp, gputex, tex->sampler_name, tex->sampler_state);
+ gputex = BKE_image_get_gpu_texture(tex->ima, iuser, nullptr);
+ drw_shgroup_material_texture(
+ grp, gputex, tex->sampler_name, eGPUSamplerState(tex->sampler_state));
}
}
else if (tex->colorband) {
/* Color Ramp */
DRW_shgroup_uniform_texture(grp, tex->sampler_name, *tex->colorband);
}
+ else if (tex->sky) {
+ /* Sky */
+ DRW_shgroup_uniform_texture_ex(
+ grp, tex->sampler_name, *tex->sky, eGPUSamplerState(tex->sampler_state));
+ }
}
GPUUniformBuf *ubo = GPU_material_uniform_buffer_get(material);
- if (ubo != NULL) {
+ if (ubo != nullptr) {
DRW_shgroup_uniform_block(grp, GPU_UBO_BLOCK_NAME, ubo);
}
const GPUUniformAttrList *uattrs = GPU_material_uniform_attributes(material);
- if (uattrs != NULL) {
+ if (uattrs != nullptr) {
int loc = GPU_shader_get_uniform_block_binding(grp->shader, GPU_ATTRIBUTE_UBO_BLOCK_NAME);
- drw_shgroup_uniform_create_ex(grp, loc, DRW_UNIFORM_BLOCK_OBATTRS, uattrs, 0, 0, 1);
+ drw_shgroup_uniform_create_ex(
+ grp, loc, DRW_UNIFORM_BLOCK_OBATTRS, uattrs, GPU_SAMPLER_DEFAULT, 0, 1);
grp->uniform_attrs = uattrs;
}
+
+ if (GPU_material_layer_attributes(material) != NULL) {
+ int loc = GPU_shader_get_uniform_block_binding(grp->shader,
+ GPU_LAYER_ATTRIBUTE_UBO_BLOCK_NAME);
+ drw_shgroup_uniform_create_ex(
+ grp, loc, DRW_UNIFORM_BLOCK_VLATTRS, nullptr, GPU_SAMPLER_DEFAULT, 0, 1);
+ }
}
GPUVertFormat *DRW_shgroup_instance_format_array(const DRWInstanceAttrFormat attrs[],
int arraysize)
{
- GPUVertFormat *format = MEM_callocN(sizeof(GPUVertFormat), "GPUVertFormat");
+ GPUVertFormat *format = MEM_cnew<GPUVertFormat>(__func__);
for (int i = 0; i < arraysize; i++) {
GPU_vertformat_attr_add(format,
@@ -1661,7 +1873,7 @@ GPUVertFormat *DRW_shgroup_instance_format_array(const DRWInstanceAttrFormat att
return format;
}
-DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass)
+DRWShadingGroup *DRW_shgroup_material_create(GPUMaterial *material, DRWPass *pass)
{
GPUPass *gpupass = GPU_material_get_pass(material);
DRWShadingGroup *shgroup = drw_shgroup_material_create_ex(gpupass, pass);
@@ -1673,32 +1885,33 @@ DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPa
return shgroup;
}
-DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
+DRWShadingGroup *DRW_shgroup_create(GPUShader *shader, DRWPass *pass)
{
DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass);
drw_shgroup_init(shgroup, shader);
return shgroup;
}
-DRWShadingGroup *DRW_shgroup_transform_feedback_create(struct GPUShader *shader,
+DRWShadingGroup *DRW_shgroup_transform_feedback_create(GPUShader *shader,
DRWPass *pass,
GPUVertBuf *tf_target)
{
- BLI_assert(tf_target != NULL);
+ BLI_assert(tf_target != nullptr);
DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass);
drw_shgroup_init(shgroup, shader);
- drw_shgroup_uniform_create_ex(shgroup, 0, DRW_UNIFORM_TFEEDBACK_TARGET, tf_target, 0, 0, 1);
+ drw_shgroup_uniform_create_ex(
+ shgroup, 0, DRW_UNIFORM_TFEEDBACK_TARGET, tf_target, GPU_SAMPLER_DEFAULT, 0, 1);
return shgroup;
}
void DRW_shgroup_state_enable(DRWShadingGroup *shgroup, DRWState state)
{
- drw_command_set_mutable_state(shgroup, state, 0x0);
+ drw_command_set_mutable_state(shgroup, state, DRW_STATE_NO_DRAW);
}
void DRW_shgroup_state_disable(DRWShadingGroup *shgroup, DRWState state)
{
- drw_command_set_mutable_state(shgroup, 0x0, state);
+ drw_command_set_mutable_state(shgroup, DRW_STATE_NO_DRAW, state);
}
void DRW_shgroup_stencil_set(DRWShadingGroup *shgroup,
@@ -1741,15 +1954,16 @@ bool DRW_shgroup_is_empty(DRWShadingGroup *shgroup)
DRWShadingGroup *DRW_shgroup_create_sub(DRWShadingGroup *shgroup)
{
- DRWShadingGroup *shgroup_new = BLI_memblock_alloc(DST.vmempool->shgroups);
+ DRWShadingGroup *shgroup_new = static_cast<DRWShadingGroup *>(
+ BLI_memblock_alloc(DST.vmempool->shgroups));
*shgroup_new = *shgroup;
drw_shgroup_init(shgroup_new, shgroup_new->shader);
- shgroup_new->cmd.first = NULL;
- shgroup_new->cmd.last = NULL;
+ shgroup_new->cmd.first = nullptr;
+ shgroup_new->cmd.last = nullptr;
- DRWPass *parent_pass = DRW_memblock_elem_from_handle(DST.vmempool->passes,
- &shgroup->pass_handle);
+ DRWPass *parent_pass = static_cast<DRWPass *>(
+ DRW_memblock_elem_from_handle(DST.vmempool->passes, &shgroup->pass_handle));
BLI_LINKS_INSERT_AFTER(&parent_pass->shgroups, shgroup, shgroup_new);
@@ -1943,64 +2157,20 @@ static void draw_frustum_bound_sphere_calc(const BoundBox *bbox,
}
}
-static void draw_view_matrix_state_update(ViewInfos *storage,
+static void draw_view_matrix_state_update(DRWView *view,
const float viewmat[4][4],
const float winmat[4][4])
{
- copy_m4_m4(storage->viewmat, viewmat);
- invert_m4_m4(storage->viewinv, storage->viewmat);
-
- copy_m4_m4(storage->winmat, winmat);
- invert_m4_m4(storage->wininv, storage->winmat);
-
- mul_m4_m4m4(storage->persmat, winmat, viewmat);
- invert_m4_m4(storage->persinv, storage->persmat);
-
- const bool is_persp = (winmat[3][3] == 0.0f);
-
- /* Near clip distance. */
- storage->viewvecs[0][3] = (is_persp) ? -winmat[3][2] / (winmat[2][2] - 1.0f) :
- -(winmat[3][2] + 1.0f) / winmat[2][2];
-
- /* Far clip distance. */
- storage->viewvecs[1][3] = (is_persp) ? -winmat[3][2] / (winmat[2][2] + 1.0f) :
- -(winmat[3][2] - 1.0f) / winmat[2][2];
+ ViewMatrices *storage = &view->storage;
- /* view vectors for the corners of the view frustum.
- * Can be used to recreate the world space position easily */
- float view_vecs[4][3] = {
- {-1.0f, -1.0f, -1.0f},
- {1.0f, -1.0f, -1.0f},
- {-1.0f, 1.0f, -1.0f},
- {-1.0f, -1.0f, 1.0f},
- };
+ copy_m4_m4(storage->viewmat.values, viewmat);
+ invert_m4_m4(storage->viewinv.values, storage->viewmat.values);
- /* convert the view vectors to view space */
- for (int i = 0; i < 4; i++) {
- mul_project_m4_v3(storage->wininv, view_vecs[i]);
- /* normalized trick see:
- * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
- if (is_persp) {
- /* Divide XY by Z. */
- mul_v2_fl(view_vecs[i], 1.0f / view_vecs[i][2]);
- }
- }
+ copy_m4_m4(storage->winmat.values, winmat);
+ invert_m4_m4(storage->wininv.values, storage->winmat.values);
- /**
- * If ortho : view_vecs[0] is the near-bottom-left corner of the frustum and
- * view_vecs[1] is the vector going from the near-bottom-left corner to
- * the far-top-right corner.
- * If Persp : view_vecs[0].xy and view_vecs[1].xy are respectively the bottom-left corner
- * when Z = 1, and top-left corner if Z = 1.
- * view_vecs[0].z the near clip distance and view_vecs[1].z is the (signed)
- * distance from the near plane to the far clip plane.
- */
- copy_v3_v3(storage->viewvecs[0], view_vecs[0]);
-
- /* we need to store the differences */
- storage->viewvecs[1][0] = view_vecs[1][0] - view_vecs[0][0];
- storage->viewvecs[1][1] = view_vecs[2][1] - view_vecs[0][1];
- storage->viewvecs[1][2] = view_vecs[3][2] - view_vecs[0][2];
+ mul_m4_m4m4(view->persmat.values, winmat, viewmat);
+ invert_m4_m4(view->persinv.values, view->persmat.values);
}
DRWView *DRW_view_create(const float viewmat[4][4],
@@ -2009,7 +2179,7 @@ DRWView *DRW_view_create(const float viewmat[4][4],
const float (*culling_winmat)[4],
DRWCallVisibilityFn *visibility_fn)
{
- DRWView *view = BLI_memblock_alloc(DST.vmempool->views);
+ DRWView *view = static_cast<DRWView *>(BLI_memblock_alloc(DST.vmempool->views));
if (DST.primary_view_num < MAX_CULLED_VIEWS) {
view->culling_mask = 1u << DST.primary_view_num++;
@@ -2020,16 +2190,7 @@ DRWView *DRW_view_create(const float viewmat[4][4],
}
view->clip_planes_len = 0;
view->visibility_fn = visibility_fn;
- view->parent = NULL;
-
- copy_v4_fl4(view->storage.viewcamtexcofac, 1.0f, 1.0f, 0.0f, 0.0f);
-
- if (DST.draw_ctx.evil_C && DST.draw_ctx.region) {
- int region_origin[2] = {DST.draw_ctx.region->winrct.xmin, DST.draw_ctx.region->winrct.ymin};
- struct wmWindow *win = CTX_wm_window(DST.draw_ctx.evil_C);
- wm_cursor_position_get(win, &view->storage.mouse_pixel[0], &view->storage.mouse_pixel[1]);
- sub_v2_v2v2_int(view->storage.mouse_pixel, view->storage.mouse_pixel, region_origin);
- }
+ view->parent = nullptr;
DRW_view_update(view, viewmat, winmat, culling_viewmat, culling_winmat);
@@ -2042,11 +2203,11 @@ DRWView *DRW_view_create_sub(const DRWView *parent_view,
{
/* Search original parent. */
const DRWView *ori_view = parent_view;
- while (ori_view->parent != NULL) {
+ while (ori_view->parent != nullptr) {
ori_view = ori_view->parent;
}
- DRWView *view = BLI_memblock_alloc(DST.vmempool->views);
+ DRWView *view = static_cast<DRWView *>(BLI_memblock_alloc(DST.vmempool->views));
/* Perform copy. */
*view = *ori_view;
@@ -2063,12 +2224,12 @@ DRWView *DRW_view_create_sub(const DRWView *parent_view,
void DRW_view_update_sub(DRWView *view, const float viewmat[4][4], const float winmat[4][4])
{
- BLI_assert(view->parent != NULL);
+ BLI_assert(view->parent != nullptr);
view->is_dirty = true;
view->is_inverted = (is_negative_m4(viewmat) == is_negative_m4(winmat));
- draw_view_matrix_state_update(&view->storage, viewmat, winmat);
+ draw_view_matrix_state_update(view, viewmat, winmat);
}
void DRW_view_update(DRWView *view,
@@ -2080,12 +2241,12 @@ void DRW_view_update(DRWView *view,
/* DO NOT UPDATE THE DEFAULT VIEW.
* Create sub-views instead, or a copy. */
BLI_assert(view != DST.view_default);
- BLI_assert(view->parent == NULL);
+ BLI_assert(view->parent == nullptr);
view->is_dirty = true;
view->is_inverted = (is_negative_m4(viewmat) == is_negative_m4(winmat));
- draw_view_matrix_state_update(&view->storage, viewmat, winmat);
+ draw_view_matrix_state_update(view, viewmat, winmat);
/* Prepare frustum culling. */
@@ -2113,7 +2274,7 @@ void DRW_view_update(DRWView *view,
invert_m4_m4(wininv, winmat);
}
else {
- copy_m4_m4(wininv, view->storage.wininv);
+ copy_m4_m4(wininv, view->storage.wininv.values);
}
float viewinv[4][4];
@@ -2122,22 +2283,14 @@ void DRW_view_update(DRWView *view,
invert_m4_m4(viewinv, viewmat);
}
else {
- copy_m4_m4(viewinv, view->storage.viewinv);
+ copy_m4_m4(viewinv, view->storage.viewinv.values);
}
draw_frustum_boundbox_calc(viewinv, winmat, &view->frustum_corners);
- draw_frustum_culling_planes_calc(view->storage.persmat, view->frustum_planes);
+ draw_frustum_culling_planes_calc(view->persmat.values, view->frustum_planes);
draw_frustum_bound_sphere_calc(
&view->frustum_corners, viewinv, winmat, wininv, &view->frustum_bsphere);
- /* TODO(fclem): Deduplicate. */
- for (int i = 0; i < 8; i++) {
- copy_v3_v3(view->storage.frustum_corners[i], view->frustum_corners.vec[i]);
- }
- for (int i = 0; i < 6; i++) {
- copy_v4_v4(view->storage.frustum_planes[i], view->frustum_planes[i]);
- }
-
#ifdef DRW_DEBUG_CULLING
if (G.debug_value != 0) {
DRW_debug_sphere(
@@ -2154,14 +2307,14 @@ const DRWView *DRW_view_default_get(void)
void DRW_view_reset(void)
{
- DST.view_default = NULL;
- DST.view_active = NULL;
- DST.view_previous = NULL;
+ DST.view_default = nullptr;
+ DST.view_active = nullptr;
+ DST.view_previous = nullptr;
}
void DRW_view_default_set(const DRWView *view)
{
- BLI_assert(DST.view_default == NULL);
+ BLI_assert(DST.view_default == nullptr);
DST.view_default = (DRWView *)view;
}
@@ -2170,20 +2323,10 @@ void DRW_view_clip_planes_set(DRWView *view, float (*planes)[4], int plane_len)
BLI_assert(plane_len <= MAX_CLIP_PLANES);
view->clip_planes_len = plane_len;
if (plane_len > 0) {
- memcpy(view->storage.clip_planes, planes, sizeof(float[4]) * plane_len);
+ memcpy(view->clip_planes, planes, sizeof(float[4]) * plane_len);
}
}
-void DRW_view_camtexco_set(DRWView *view, float texco[4])
-{
- copy_v4_v4(view->storage.viewcamtexcofac, texco);
-}
-
-void DRW_view_camtexco_get(const DRWView *view, float r_texco[4])
-{
- copy_v4_v4(r_texco, view->storage.viewcamtexcofac);
-}
-
void DRW_view_frustum_corners_get(const DRWView *view, BoundBox *corners)
{
memcpy(corners, &view->frustum_corners, sizeof(view->frustum_corners));
@@ -2203,7 +2346,7 @@ bool DRW_view_is_persp_get(const DRWView *view)
float DRW_view_near_distance_get(const DRWView *view)
{
view = (view) ? view : DST.view_default;
- const float(*projmat)[4] = view->storage.winmat;
+ const float4x4 &projmat = view->storage.winmat;
if (DRW_view_is_persp_get(view)) {
return -projmat[3][2] / (projmat[2][2] - 1.0f);
@@ -2215,7 +2358,7 @@ float DRW_view_near_distance_get(const DRWView *view)
float DRW_view_far_distance_get(const DRWView *view)
{
view = (view) ? view : DST.view_default;
- const float(*projmat)[4] = view->storage.winmat;
+ const float4x4 &projmat = view->storage.winmat;
if (DRW_view_is_persp_get(view)) {
return -projmat[3][2] / (projmat[2][2] + 1.0f);
@@ -2227,22 +2370,21 @@ float DRW_view_far_distance_get(const DRWView *view)
void DRW_view_viewmat_get(const DRWView *view, float mat[4][4], bool inverse)
{
view = (view) ? view : DST.view_default;
- const ViewInfos *storage = &view->storage;
- copy_m4_m4(mat, (inverse) ? storage->viewinv : storage->viewmat);
+ const ViewMatrices *storage = &view->storage;
+ copy_m4_m4(mat, (inverse) ? storage->viewinv.values : storage->viewmat.values);
}
void DRW_view_winmat_get(const DRWView *view, float mat[4][4], bool inverse)
{
view = (view) ? view : DST.view_default;
- const ViewInfos *storage = &view->storage;
- copy_m4_m4(mat, (inverse) ? storage->wininv : storage->winmat);
+ const ViewMatrices *storage = &view->storage;
+ copy_m4_m4(mat, (inverse) ? storage->wininv.values : storage->winmat.values);
}
void DRW_view_persmat_get(const DRWView *view, float mat[4][4], bool inverse)
{
view = (view) ? view : DST.view_default;
- const ViewInfos *storage = &view->storage;
- copy_m4_m4(mat, (inverse) ? storage->persinv : storage->persmat);
+ copy_m4_m4(mat, (inverse) ? view->persinv.values : view->persmat.values);
}
/** \} */
@@ -2253,19 +2395,19 @@ void DRW_view_persmat_get(const DRWView *view, float mat[4][4], bool inverse)
DRWPass *DRW_pass_create(const char *name, DRWState state)
{
- DRWPass *pass = BLI_memblock_alloc(DST.vmempool->passes);
+ DRWPass *pass = static_cast<DRWPass *>(BLI_memblock_alloc(DST.vmempool->passes));
pass->state = state | DRW_STATE_PROGRAM_POINT_SIZE;
if (G.debug & G_DEBUG_GPU) {
BLI_strncpy(pass->name, name, MAX_PASS_NAME);
}
- pass->shgroups.first = NULL;
- pass->shgroups.last = NULL;
+ pass->shgroups.first = nullptr;
+ pass->shgroups.last = nullptr;
pass->handle = DST.pass_handle;
DRW_handle_increment(&DST.pass_handle);
- pass->original = NULL;
- pass->next = NULL;
+ pass->original = nullptr;
+ pass->next = nullptr;
return pass;
}
@@ -2281,7 +2423,7 @@ DRWPass *DRW_pass_create_instance(const char *name, DRWPass *original, DRWState
void DRW_pass_link(DRWPass *first, DRWPass *second)
{
BLI_assert(first != second);
- BLI_assert(first->next == NULL);
+ BLI_assert(first->next == nullptr);
first->next = second;
}
@@ -2340,7 +2482,7 @@ static int pass_shgroup_dist_sort(const void *a, const void *b)
void DRW_pass_sort_shgroup_z(DRWPass *pass)
{
- const float(*viewinv)[4] = DST.view_active->storage.viewinv;
+ const float4x4 &viewinv = DST.view_active->storage.viewinv;
if (!(pass->shgroups.first && pass->shgroups.first->next)) {
/* Nothing to sort */
@@ -2366,7 +2508,8 @@ void DRW_pass_sort_shgroup_z(DRWPass *pass)
* (see T76730 & D7729). */
// BLI_assert(handle != 0);
- DRWObjectMatrix *obmats = DRW_memblock_elem_from_handle(DST.vmempool->obmats, &handle);
+ DRWObjectMatrix *obmats = static_cast<DRWObjectMatrix *>(
+ DRW_memblock_elem_from_handle(DST.vmempool->obmats, &handle));
/* Compute distance to camera. */
float tmp[3];
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 0e39cc1d3b9..8b1b35b5f03 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -44,6 +44,7 @@ typedef struct DRWCommandsState {
int obmats_loc;
int obinfos_loc;
int obattrs_loc;
+ int vlattrs_loc;
int baseinst_loc;
int chunkid_loc;
int resourceid_loc;
@@ -682,6 +683,10 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup,
uni->uniform_attrs);
DRW_sparse_uniform_buffer_bind(state->obattrs_ubo, 0, uni->location);
break;
+ case DRW_UNIFORM_BLOCK_VLATTRS:
+ state->vlattrs_loc = uni->location;
+ GPU_uniformbuf_bind(drw_ensure_layer_attribute_buffer(), uni->location);
+ break;
case DRW_UNIFORM_RESOURCE_CHUNK:
state->chunkid_loc = uni->location;
GPU_shader_uniform_int(shgroup->shader, uni->location, 0);
@@ -960,6 +965,9 @@ static void draw_call_batching_finish(DRWShadingGroup *shgroup, DRWCommandsState
if (state->obattrs_loc != -1) {
DRW_sparse_uniform_buffer_unbind(state->obattrs_ubo, state->resource_chunk);
}
+ if (state->vlattrs_loc != -1) {
+ GPU_uniformbuf_unbind(DST.vmempool->vlattrs_ubo);
+ }
}
static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
@@ -970,6 +978,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
.obmats_loc = -1,
.obinfos_loc = -1,
.obattrs_loc = -1,
+ .vlattrs_loc = -1,
.baseinst_loc = -1,
.chunkid_loc = -1,
.resourceid_loc = -1,
@@ -1146,15 +1155,11 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
}
}
-static void drw_update_view(const float viewport_size[2])
+static void drw_update_view(void)
{
- ViewInfos *storage = &DST.view_active->storage;
- copy_v2_v2(storage->viewport_size, viewport_size);
- copy_v2_v2(storage->viewport_size_inverse, viewport_size);
- invert_v2(storage->viewport_size_inverse);
-
/* TODO(fclem): update a big UBO and only bind ranges here. */
GPU_uniformbuf_update(G_draw.view_ubo, &DST.view_active->storage);
+ GPU_uniformbuf_update(G_draw.clipping_ubo, &DST.view_active->clip_planes);
/* TODO: get rid of this. */
DST.view_storage_cpy = DST.view_active->storage;
@@ -1180,11 +1185,8 @@ static void drw_draw_pass_ex(DRWPass *pass,
BLI_assert(DST.buffer_finish_called &&
"DRW_render_instance_buffer_finish had not been called before drawing");
- float viewport[4];
- GPU_viewport_size_get_f(viewport);
- if (DST.view_previous != DST.view_active || DST.view_active->is_dirty ||
- !equals_v2v2(DST.view_active->storage.viewport_size, &viewport[2])) {
- drw_update_view(&viewport[2]);
+ if (DST.view_previous != DST.view_active || DST.view_active->is_dirty) {
+ drw_update_view();
DST.view_active->is_dirty = false;
DST.view_previous = DST.view_active;
}
diff --git a/source/blender/draw/intern/draw_manager_profiling.c b/source/blender/draw/intern/draw_manager_profiling.c
index d14f5c7f125..92cb3e008b9 100644
--- a/source/blender/draw/intern/draw_manager_profiling.c
+++ b/source/blender/draw/intern/draw_manager_profiling.c
@@ -225,15 +225,15 @@ void DRW_stats_draw(const rcti *rect)
/* ------------------------------------------ */
/* Label row */
char col_label[32];
- sprintf(col_label, "Engine");
+ BLI_snprintf(col_label, sizeof(col_label), "Engine");
draw_stat_5row(rect, u++, v, col_label, sizeof(col_label));
- sprintf(col_label, "Init");
+ BLI_snprintf(col_label, sizeof(col_label), "Init");
draw_stat_5row(rect, u++, v, col_label, sizeof(col_label));
- sprintf(col_label, "Background");
+ BLI_snprintf(col_label, sizeof(col_label), "Background");
draw_stat_5row(rect, u++, v, col_label, sizeof(col_label));
- sprintf(col_label, "Render");
+ BLI_snprintf(col_label, sizeof(col_label), "Render");
draw_stat_5row(rect, u++, v, col_label, sizeof(col_label));
- sprintf(col_label, "Total (w/o cache)");
+ BLI_snprintf(col_label, sizeof(col_label), "Total (w/o cache)");
draw_stat_5row(rect, u++, v, col_label, sizeof(col_label));
v++;
@@ -245,42 +245,45 @@ void DRW_stats_draw(const rcti *rect)
draw_stat_5row(rect, u++, v, engine->idname, sizeof(engine->idname));
init_tot_time += data->init_time;
- sprintf(time_to_txt, "%.2fms", data->init_time);
+ BLI_snprintf(time_to_txt, sizeof(time_to_txt), "%.2fms", data->init_time);
draw_stat_5row(rect, u++, v, time_to_txt, sizeof(time_to_txt));
background_tot_time += data->background_time;
- sprintf(time_to_txt, "%.2fms", data->background_time);
+ BLI_snprintf(time_to_txt, sizeof(time_to_txt), "%.2fms", data->background_time);
draw_stat_5row(rect, u++, v, time_to_txt, sizeof(time_to_txt));
render_tot_time += data->render_time;
- sprintf(time_to_txt, "%.2fms", data->render_time);
+ BLI_snprintf(time_to_txt, sizeof(time_to_txt), "%.2fms", data->render_time);
draw_stat_5row(rect, u++, v, time_to_txt, sizeof(time_to_txt));
tot_time += data->init_time + data->background_time + data->render_time;
- sprintf(time_to_txt, "%.2fms", data->init_time + data->background_time + data->render_time);
+ BLI_snprintf(time_to_txt,
+ sizeof(time_to_txt),
+ "%.2fms",
+ data->init_time + data->background_time + data->render_time);
draw_stat_5row(rect, u++, v, time_to_txt, sizeof(time_to_txt));
v++;
}
/* Totals row */
u = 0;
- sprintf(col_label, "Sub Total");
+ BLI_snprintf(col_label, sizeof(col_label), "Sub Total");
draw_stat_5row(rect, u++, v, col_label, sizeof(col_label));
- sprintf(time_to_txt, "%.2fms", init_tot_time);
+ BLI_snprintf(time_to_txt, sizeof(time_to_txt), "%.2fms", init_tot_time);
draw_stat_5row(rect, u++, v, time_to_txt, sizeof(time_to_txt));
- sprintf(time_to_txt, "%.2fms", background_tot_time);
+ BLI_snprintf(time_to_txt, sizeof(time_to_txt), "%.2fms", background_tot_time);
draw_stat_5row(rect, u++, v, time_to_txt, sizeof(time_to_txt));
- sprintf(time_to_txt, "%.2fms", render_tot_time);
+ BLI_snprintf(time_to_txt, sizeof(time_to_txt), "%.2fms", render_tot_time);
draw_stat_5row(rect, u++, v, time_to_txt, sizeof(time_to_txt));
- sprintf(time_to_txt, "%.2fms", tot_time);
+ BLI_snprintf(time_to_txt, sizeof(time_to_txt), "%.2fms", tot_time);
draw_stat_5row(rect, u++, v, time_to_txt, sizeof(time_to_txt));
v += 2;
u = 0;
double *cache_time = DRW_view_data_cache_time_get(DST.view_data_active);
- sprintf(col_label, "Cache Time");
+ BLI_snprintf(col_label, sizeof(col_label), "Cache Time");
draw_stat_5row(rect, u++, v, col_label, sizeof(col_label));
- sprintf(time_to_txt, "%.2fms", *cache_time);
+ BLI_snprintf(time_to_txt, sizeof(time_to_txt), "%.2fms", *cache_time);
draw_stat_5row(rect, u++, v, time_to_txt, sizeof(time_to_txt));
v += 2;
@@ -292,17 +295,18 @@ void DRW_stats_draw(const rcti *rect)
uint tex_mem = GPU_texture_memory_usage_get();
uint vbo_mem = GPU_vertbuf_get_memory_usage();
- sprintf(stat_string, "GPU Memory");
+ BLI_snprintf(stat_string, sizeof(stat_string), "GPU Memory");
draw_stat(rect, 0, v, stat_string, sizeof(stat_string));
- sprintf(stat_string, "%.2fMB", (double)(tex_mem + vbo_mem) / 1000000.0);
+ BLI_snprintf(
+ stat_string, sizeof(stat_string), "%.2fMB", (double)(tex_mem + vbo_mem) / 1000000.0);
draw_stat_5row(rect, 1, v++, stat_string, sizeof(stat_string));
- sprintf(stat_string, "Textures");
+ BLI_snprintf(stat_string, sizeof(stat_string), "Textures");
draw_stat(rect, 1, v, stat_string, sizeof(stat_string));
- sprintf(stat_string, "%.2fMB", (double)tex_mem / 1000000.0);
+ BLI_snprintf(stat_string, sizeof(stat_string), "%.2fMB", (double)tex_mem / 1000000.0);
draw_stat_5row(rect, 1, v++, stat_string, sizeof(stat_string));
- sprintf(stat_string, "Meshes");
+ BLI_snprintf(stat_string, sizeof(stat_string), "Meshes");
draw_stat(rect, 1, v, stat_string, sizeof(stat_string));
- sprintf(stat_string, "%.2fMB", (double)vbo_mem / 1000000.0);
+ BLI_snprintf(stat_string, sizeof(stat_string), "%.2fMB", (double)vbo_mem / 1000000.0);
draw_stat_5row(rect, 1, v++, stat_string, sizeof(stat_string));
v += 1;
diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c
index 1ada99093c6..85701a10f4b 100644
--- a/source/blender/draw/intern/draw_manager_shader.c
+++ b/source/blender/draw/intern/draw_manager_shader.c
@@ -51,6 +51,7 @@ extern char datatoc_common_fullscreen_vert_glsl[];
* \{ */
typedef struct DRWShaderCompiler {
+ /** Default compilation queue. */
ListBase queue; /* GPUMaterial */
SpinLock list_lock;
@@ -63,8 +64,8 @@ static void drw_deferred_shader_compilation_exec(
void *custom_data,
/* Cannot be const, this function implements wm_jobs_start_callback.
* NOLINTNEXTLINE: readability-non-const-parameter. */
- short *stop,
- short *UNUSED(do_update),
+ bool *stop,
+ bool *UNUSED(do_update),
float *UNUSED(progress))
{
GPU_render_begin();
@@ -109,6 +110,7 @@ static void drw_deferred_shader_compilation_exec(
MEM_freeN(link);
}
else {
+ /* No more materials to optimize, or shaders to compile. */
break;
}
@@ -216,7 +218,7 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
}
else {
comp->gl_context = WM_opengl_context_create();
- comp->gpu_context = GPU_context_create(NULL);
+ comp->gpu_context = GPU_context_create(NULL, comp->gl_context);
GPU_context_active_set(NULL);
WM_opengl_context_activate(DST.gl_context);
@@ -235,6 +237,42 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
WM_jobs_start(wm, wm_job);
}
+static void drw_register_shader_vlattrs(GPUMaterial *mat)
+{
+ const ListBase *attrs = GPU_material_layer_attributes(mat);
+
+ if (!attrs) {
+ return;
+ }
+
+ GHash *hash = DST.vmempool->vlattrs_name_cache;
+ ListBase *list = &DST.vmempool->vlattrs_name_list;
+
+ LISTBASE_FOREACH (GPULayerAttr *, attr, attrs) {
+ GPULayerAttr **p_val;
+
+ /* Add to the table and list if newly seen. */
+ if (!BLI_ghash_ensure_p(hash, POINTER_FROM_UINT(attr->hash_code), (void ***)&p_val)) {
+ DST.vmempool->vlattrs_ubo_ready = false;
+
+ GPULayerAttr *new_link = *p_val = MEM_dupallocN(attr);
+
+ /* Insert into the list ensuring sorted order. */
+ GPULayerAttr *link = list->first;
+
+ while (link && link->hash_code <= attr->hash_code) {
+ link = link->next;
+ }
+
+ new_link->prev = new_link->next = NULL;
+ BLI_insertlinkbefore(list, link, new_link);
+ }
+
+ /* Reset the unused frames counter. */
+ (*p_val)->users = 0;
+ }
+}
+
void DRW_deferred_shader_remove(GPUMaterial *mat)
{
LISTBASE_FOREACH (wmWindowManager *, wm, &G_MAIN->wm) {
@@ -243,6 +281,8 @@ void DRW_deferred_shader_remove(GPUMaterial *mat)
wm, wm, WM_JOB_TYPE_SHADER_COMPILATION);
if (comp != NULL) {
BLI_spin_lock(&comp->list_lock);
+
+ /* Search for compilation job in queue. */
LinkData *link = (LinkData *)BLI_findptr(&comp->queue, mat, offsetof(LinkData, data));
if (link) {
BLI_remlink(&comp->queue, link);
@@ -297,18 +337,6 @@ GPUShader *DRW_shader_create_with_lib_ex(const char *vert,
return sh;
}
-GPUShader *DRW_shader_create_compute_with_shaderlib(const char *comp,
- const DRWShaderLibrary *lib,
- const char *defines,
- const char *name)
-{
- char *comp_with_lib = DRW_shader_library_create_shader_string(lib, comp);
- GPUShader *sh = GPU_shader_create_compute(comp_with_lib, NULL, defines, name);
- MEM_SAFE_FREE(comp_with_lib);
-
- return sh;
-}
-
GPUShader *DRW_shader_create_with_shaderlib_ex(const char *vert,
const char *geom,
const char *frag,
@@ -390,6 +418,9 @@ GPUMaterial *DRW_shader_from_world(World *wo,
false,
callback,
thunk);
+
+ drw_register_shader_vlattrs(mat);
+
if (DRW_state_is_image_render()) {
/* Do not deferred if doing render. */
deferred = false;
@@ -419,6 +450,8 @@ GPUMaterial *DRW_shader_from_material(Material *ma,
callback,
thunk);
+ drw_register_shader_vlattrs(mat);
+
if (DRW_state_is_image_render()) {
/* Do not deferred if doing render. */
deferred = false;
diff --git a/source/blender/draw/intern/draw_manager_text.c b/source/blender/draw/intern/draw_manager_text.cc
index 203276e63ef..1244c46e166 100644
--- a/source/blender/draw/intern/draw_manager_text.c
+++ b/source/blender/draw/intern/draw_manager_text.cc
@@ -15,6 +15,7 @@
#include "BKE_editmesh.h"
#include "BKE_editmesh_cache.h"
#include "BKE_global.h"
+#include "BKE_mesh.h"
#include "BKE_unit.h"
#include "DNA_mesh_types.h"
@@ -38,7 +39,7 @@
#include "draw_manager_text.h"
#include "intern/bmesh_polygon.h"
-typedef struct ViewCachedString {
+struct ViewCachedString {
float vec[3];
union {
uchar ub[4];
@@ -51,20 +52,20 @@ typedef struct ViewCachedString {
/* str is allocated past the end */
char str[0];
-} ViewCachedString;
+};
-typedef struct DRWTextStore {
+struct DRWTextStore {
BLI_memiter *cache_strings;
-} DRWTextStore;
+};
DRWTextStore *DRW_text_cache_create(void)
{
- DRWTextStore *dt = MEM_callocN(sizeof(*dt), __func__);
+ DRWTextStore *dt = MEM_cnew<DRWTextStore>(__func__);
dt->cache_strings = BLI_memiter_create(1 << 14); /* 16kb */
return dt;
}
-void DRW_text_cache_destroy(struct DRWTextStore *dt)
+void DRW_text_cache_destroy(DRWTextStore *dt)
{
BLI_memiter_destroy(dt->cache_strings);
MEM_freeN(dt);
@@ -90,7 +91,8 @@ void DRW_text_cache_add(DRWTextStore *dt,
alloc_len = str_len + 1;
}
- vos = BLI_memiter_alloc(dt->cache_strings, sizeof(ViewCachedString) + alloc_len);
+ vos = static_cast<ViewCachedString *>(
+ BLI_memiter_alloc(dt->cache_strings, sizeof(ViewCachedString) + alloc_len));
copy_v3_v3(vos->vec, co);
copy_v4_v4_uchar(vos->col.ub, col);
@@ -125,10 +127,10 @@ static void drw_text_cache_draw_ex(DRWTextStore *dt, ARegion *region)
const uiStyle *style = UI_style_get();
- BLF_size(font_id, style->widget.points * U.pixelsize, U.dpi);
+ BLF_size(font_id, style->widget.points * U.dpi_fac);
BLI_memiter_iter_init(dt->cache_strings, &it);
- while ((vos = BLI_memiter_iter_step(&it))) {
+ while ((vos = static_cast<ViewCachedString *>(BLI_memiter_iter_step(&it)))) {
if (vos->sco[0] != IS_CLIPPED) {
if (col_pack_prev != vos->col.pack) {
BLF_color4ubv(font_id, vos->col.ub);
@@ -136,7 +138,7 @@ static void drw_text_cache_draw_ex(DRWTextStore *dt, ARegion *region)
}
BLF_position(
- font_id, (float)(vos->sco[0] + vos->xoffs), (float)(vos->sco[1] + vos->yoffs), 2.0f);
+ font_id, float(vos->sco[0] + vos->xoffs), float(vos->sco[1] + vos->yoffs), 2.0f);
BLF_draw(font_id,
(vos->flag & DRW_TEXT_CACHE_STRING_PTR) ? *((const char **)vos->str) : vos->str,
vos->str_len);
@@ -147,16 +149,16 @@ static void drw_text_cache_draw_ex(DRWTextStore *dt, ARegion *region)
GPU_matrix_projection_set(original_proj);
}
-void DRW_text_cache_draw(DRWTextStore *dt, ARegion *region, struct View3D *v3d)
+void DRW_text_cache_draw(DRWTextStore *dt, ARegion *region, View3D *v3d)
{
ViewCachedString *vos;
if (v3d) {
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
int tot = 0;
/* project first and test */
BLI_memiter_handle it;
BLI_memiter_iter_init(dt->cache_strings, &it);
- while ((vos = BLI_memiter_iter_step(&it))) {
+ while ((vos = static_cast<ViewCachedString *>(BLI_memiter_iter_step(&it)))) {
if (ED_view3d_project_short_ex(
region,
(vos->flag & DRW_TEXT_CACHE_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob,
@@ -192,10 +194,10 @@ void DRW_text_cache_draw(DRWTextStore *dt, ARegion *region, struct View3D *v3d)
BLI_memiter_iter_init(dt->cache_strings, &it);
View2D *v2d = &region->v2d;
float viewmat[4][4];
- rctf region_space = {0.0f, region->winx, 0.0f, region->winy};
+ rctf region_space = {0.0f, float(region->winx), 0.0f, float(region->winy)};
BLI_rctf_transform_calc_m4_pivot_min(&v2d->cur, &region_space, viewmat);
- while ((vos = BLI_memiter_iter_step(&it))) {
+ while ((vos = static_cast<ViewCachedString *>(BLI_memiter_iter_step(&it)))) {
float p[3];
copy_v3_v3(p, vos->vec);
mul_m4_v3(viewmat, p);
@@ -216,9 +218,9 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
/* Do not use ascii when using non-default unit system, some unit chars are utf8 (micro, square,
* etc.). See bug T36090.
*/
- struct DRWTextStore *dt = DRW_text_cache_ensure();
+ DRWTextStore *dt = DRW_text_cache_ensure();
const short txt_flag = DRW_TEXT_CACHE_GLOBALSPACE;
- Mesh *me = ob->data;
+ Mesh *me = static_cast<Mesh *>(ob->data);
BMEditMesh *em = me->edit_mesh;
float v1[3], v2[3], v3[3], vmid[3], fvec[3];
char numstr[32]; /* Stores the measurement display text here */
@@ -232,8 +234,9 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
float clip_planes[4][4];
/* allow for displaying shape keys and deform mods */
BMIter iter;
- const float(*vert_coords)[3] = (me->runtime.edit_data ? me->runtime.edit_data->vertexCos : NULL);
- const bool use_coords = (vert_coords != NULL);
+ const float(*vert_coords)[3] = (me->runtime->edit_data ? me->runtime->edit_data->vertexCos :
+ nullptr);
+ const bool use_coords = (vert_coords != nullptr);
/* when 2 or more edge-info options are enabled, space apart */
short edge_tex_count = 0;
@@ -246,7 +249,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_INDICES) && (em->selectmode & SCE_SELECT_EDGE)) {
edge_tex_count += 1;
}
- const short edge_tex_sep = (short)((edge_tex_count - 1) * 5.0f * U.dpi_fac);
+ const short edge_tex_sep = short((edge_tex_count - 1) * 5.0f * U.dpi_fac);
/* Make the precision of the display value proportionate to the grid-size. */
@@ -302,11 +305,11 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
if (clip_segment_v3_plane_n(v1, v2, clip_planes, 4, v1_clip, v2_clip)) {
mid_v3_v3v3(vmid, v1_clip, v2_clip);
- mul_m4_v3(ob->obmat, vmid);
+ mul_m4_v3(ob->object_to_world, vmid);
if (do_global) {
- mul_mat3_m4_v3(ob->obmat, v1);
- mul_mat3_m4_v3(ob->obmat, v2);
+ mul_mat3_m4_v3(ob->object_to_world, v1);
+ mul_mat3_m4_v3(ob->object_to_world, v2);
}
if (unit->system) {
@@ -334,11 +337,11 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGEANG, col);
- const float(*poly_normals)[3] = NULL;
+ const float(*poly_normals)[3] = nullptr;
if (use_coords) {
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
- BKE_editmesh_cache_ensure_poly_normals(em, me->runtime.edit_data);
- poly_normals = me->runtime.edit_data->polyNos;
+ BKE_editmesh_cache_ensure_poly_normals(em, me->runtime->edit_data);
+ poly_normals = me->runtime->edit_data->polyNos;
}
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
@@ -370,7 +373,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
float angle;
mid_v3_v3v3(vmid, v1_clip, v2_clip);
- mul_m4_v3(ob->obmat, vmid);
+ mul_m4_v3(ob->object_to_world, vmid);
if (use_coords) {
copy_v3_v3(no_a, poly_normals[BM_elem_index_get(l_a->f)]);
@@ -382,8 +385,8 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
}
if (do_global) {
- mul_mat3_m4_v3(ob->imat, no_a);
- mul_mat3_m4_v3(ob->imat, no_b);
+ mul_mat3_m4_v3(ob->world_to_object, no_a);
+ mul_mat3_m4_v3(ob->world_to_object, no_b);
normalize_v3(no_a);
normalize_v3(no_b);
}
@@ -410,7 +413,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col);
int i, n;
- BMFace *f = NULL;
+ BMFace *f = nullptr;
/* Alternative to using `poly_to_tri_count(i, BM_elem_index_get(f->l_first))`
* without having to add an extra loop. */
int looptri_index = 0;
@@ -440,22 +443,22 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
n += 3;
if (do_global) {
- mul_mat3_m4_v3(ob->obmat, v1);
- mul_mat3_m4_v3(ob->obmat, v2);
- mul_mat3_m4_v3(ob->obmat, v3);
+ mul_mat3_m4_v3(ob->object_to_world, v1);
+ mul_mat3_m4_v3(ob->object_to_world, v2);
+ mul_mat3_m4_v3(ob->object_to_world, v3);
}
area += area_tri_v3(v1, v2, v3);
}
- mul_v3_fl(vmid, 1.0f / (float)n);
- mul_m4_v3(ob->obmat, vmid);
+ mul_v3_fl(vmid, 1.0f / float(n));
+ mul_m4_v3(ob->object_to_world, vmid);
if (unit->system) {
numstr_len = BKE_unit_value_as_string(
numstr,
sizeof(numstr),
- (double)(area * unit->scale_length * unit->scale_length),
+ double(area * unit->scale_length * unit->scale_length),
3,
B_UNIT_AREA,
unit,
@@ -519,9 +522,9 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
copy_v3_v3(v2_local, v2);
if (do_global) {
- mul_mat3_m4_v3(ob->obmat, v1);
- mul_mat3_m4_v3(ob->obmat, v2);
- mul_mat3_m4_v3(ob->obmat, v3);
+ mul_mat3_m4_v3(ob->object_to_world, v1);
+ mul_mat3_m4_v3(ob->object_to_world, v2);
+ mul_mat3_m4_v3(ob->object_to_world, v3);
}
float angle = angle_v3v3v3(v1, v2, v3);
@@ -532,7 +535,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
(is_rad) ? angle : RAD2DEGF(angle),
(is_rad) ? "r" : "°");
interp_v3_v3v3(fvec, vmid, v2_local, 0.8f);
- mul_m4_v3(ob->obmat, fvec);
+ mul_m4_v3(ob->object_to_world, fvec);
DRW_text_cache_add(dt, fvec, numstr, numstr_len, 0, 0, txt_flag, col);
}
}
@@ -563,7 +566,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
copy_v3_v3(v1, v->co);
}
- mul_m4_v3(ob->obmat, v1);
+ mul_m4_v3(ob->object_to_world, v1);
numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i);
DRW_text_cache_add(dt, v1, numstr, numstr_len, 0, 0, txt_flag, col);
@@ -592,7 +595,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
if (clip_segment_v3_plane_n(v1, v2, clip_planes, 4, v1_clip, v2_clip)) {
mid_v3_v3v3(vmid, v1_clip, v2_clip);
- mul_m4_v3(ob->obmat, vmid);
+ mul_m4_v3(ob->object_to_world, vmid);
numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i);
DRW_text_cache_add(
@@ -626,7 +629,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
BM_face_calc_center_median(f, v1);
}
- mul_m4_v3(ob->obmat, v1);
+ mul_m4_v3(ob->object_to_world, v1);
numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i);
DRW_text_cache_add(dt, v1, numstr, numstr_len, 0, 0, txt_flag, col);
diff --git a/source/blender/draw/intern/draw_pass.hh b/source/blender/draw/intern/draw_pass.hh
index e1a0a6652ac..2c1fd16928e 100644
--- a/source/blender/draw/intern/draw_pass.hh
+++ b/source/blender/draw/intern/draw_pass.hh
@@ -14,8 +14,7 @@
* #Pass. Use many #PassSub along with a main #Pass to reduce the overhead and allow groupings of
* commands. \note The draw call order inside a batch of multiple draw with the exact same state is
* not guaranteed and is not even deterministic. Use a #PassSimple or #PassSortable if ordering is
- * needed. \note As of now, it is also quite limited in the type of draw command it can record
- * (no custom vertex count, no custom first vertex).
+ * needed. Custom vertex count and custom first vertex will effectively disable batching.
*
* `PassSimple`:
* Does not have the overhead of #PassMain but does not have the culling and batching optimization.
@@ -160,8 +159,10 @@ class PassBase {
*
* IMPORTANT: This does not set the stencil mask/reference values. Add a call to state_stencil()
* to ensure correct behavior of stencil aware draws.
+ *
+ * TODO(fclem): clip_plane_count should be part of shader state.
*/
- void state_set(DRWState state);
+ void state_set(DRWState state, int clip_plane_count = 0);
/**
* Clear the current frame-buffer.
@@ -174,9 +175,15 @@ class PassBase {
/**
* Reminders:
- * - (compare_mask & reference) is what is tested against (compare_mask & stencil_value)
+ * - `compare_mask & reference` is what is tested against `compare_mask & stencil_value`
* stencil_value being the value stored in the stencil buffer.
- * - (write-mask & reference) is what gets written if the test condition is fulfilled.
+ * - `write-mask & reference` is what gets written if the test condition is fulfilled.
+ *
+ * This will modify the stencil state until another call to this function.
+ * If not specified before any draw-call, these states will be undefined.
+ *
+ * For more information see:
+ * https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkStencilOpState.html
*/
void state_stencil(uint8_t write_mask, uint8_t reference, uint8_t compare_mask);
@@ -186,6 +193,12 @@ class PassBase {
void shader_set(GPUShader *shader);
/**
+ * Bind a framebuffer. This is equivalent to a deferred GPU_framebuffer_bind() call.
+ * \note Changes the global GPU state (outside of DRW).
+ */
+ void framebuffer_set(GPUFrameBuffer *framebuffer);
+
+ /**
* Bind a material shader along with its associated resources. Any following bind() or
* push_constant() call will use its interface.
* IMPORTANT: Assumes material is compiled and can be used (no compilation error).
@@ -403,7 +416,7 @@ class PassSortable : public PassMain {
{
int64_t index = sub_passes_.append_and_get_index(
PassBase(name, draw_commands_buf_, sub_passes_, shader_));
- headers_.append({Type::SubPass, static_cast<uint>(index)});
+ headers_.append({Type::SubPass, uint(index)});
sorting_values_.append(sorting_value);
return sub_passes_[index];
}
@@ -442,7 +455,7 @@ namespace detail {
template<class T> inline command::Undetermined &PassBase<T>::create_command(command::Type type)
{
int64_t index = commands_.append_and_get_index({});
- headers_.append({type, static_cast<uint>(index)});
+ headers_.append({type, uint(index)});
return commands_[index];
}
@@ -452,7 +465,7 @@ inline void PassBase<T>::clear(eGPUFrameBufferBits planes,
float depth,
uint8_t stencil)
{
- create_command(command::Type::Clear).clear = {(uint8_t)planes, stencil, depth, color};
+ create_command(command::Type::Clear).clear = {uint8_t(planes), stencil, depth, color};
}
template<class T> inline GPUBatch *PassBase<T>::procedural_batch_get(GPUPrimType primitive)
@@ -477,7 +490,7 @@ template<class T> inline PassBase<T> &PassBase<T>::sub(const char *name)
{
int64_t index = sub_passes_.append_and_get_index(
PassBase(name, draw_commands_buf_, sub_passes_, shader_));
- headers_.append({command::Type::SubPass, static_cast<uint>(index)});
+ headers_.append({command::Type::SubPass, uint(index)});
return sub_passes_[index];
}
@@ -720,15 +733,19 @@ template<class T> inline void PassBase<T>::barrier(eGPUBarrier type)
/** \name State Implementation
* \{ */
-template<class T> inline void PassBase<T>::state_set(DRWState state)
+template<class T> inline void PassBase<T>::state_set(DRWState state, int clip_plane_count)
{
- create_command(Type::StateSet).state_set = {state};
+ /** \note This is for compatibility with the old clip plane API. */
+ if (clip_plane_count > 0) {
+ state |= DRW_STATE_CLIP_PLANES;
+ }
+ create_command(Type::StateSet).state_set = {state, clip_plane_count};
}
template<class T>
inline void PassBase<T>::state_stencil(uint8_t write_mask, uint8_t reference, uint8_t compare_mask)
{
- create_command(Type::StencilSet).stencil_set = {write_mask, reference, compare_mask};
+ create_command(Type::StencilSet).stencil_set = {write_mask, compare_mask, reference};
}
template<class T> inline void PassBase<T>::shader_set(GPUShader *shader)
@@ -737,6 +754,11 @@ template<class T> inline void PassBase<T>::shader_set(GPUShader *shader)
create_command(Type::ShaderBind).shader_bind = {shader};
}
+template<class T> inline void PassBase<T>::framebuffer_set(GPUFrameBuffer *framebuffer)
+{
+ create_command(Type::FramebufferBind).framebuffer_bind = {framebuffer};
+}
+
template<class T> inline void PassBase<T>::material_set(Manager &manager, GPUMaterial *material)
{
GPUPass *gpupass = GPU_material_get_pass(material);
diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc
new file mode 100644
index 00000000000..6c504e63511
--- /dev/null
+++ b/source/blender/draw/intern/draw_pbvh.cc
@@ -0,0 +1,1301 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2005 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ *
+ * PBVH drawing.
+ * Embeds GPU meshes inside of PBVH nodes, used by mesh sculpt mode.
+ */
+
+#include <algorithm>
+#include <climits>
+#include <cstddef>
+#include <cstdlib>
+#include <cstring>
+#include <string>
+#include <vector>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_bitmap.h"
+#include "BLI_ghash.h"
+#include "BLI_index_range.hh"
+#include "BLI_map.hh"
+#include "BLI_math_color.h"
+#include "BLI_math_vec_types.hh"
+#include "BLI_utildefines.h"
+#include "BLI_vector.hh"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_DerivedMesh.h"
+#include "BKE_attribute.h"
+#include "BKE_ccg.h"
+#include "BKE_customdata.h"
+#include "BKE_mesh.h"
+#include "BKE_paint.h"
+#include "BKE_pbvh.h"
+#include "BKE_subdiv_ccg.h"
+
+#include "GPU_batch.h"
+
+#include "DRW_engine.h"
+#include "DRW_pbvh.h"
+
+#include "bmesh.h"
+#include "draw_pbvh.h"
+#include "gpu_private.h"
+
+#define MAX_PBVH_BATCH_KEY 512
+#define MAX_PBVH_VBOS 16
+
+using blender::char3;
+using blender::float2;
+using blender::float3;
+using blender::float4;
+using blender::IndexRange;
+using blender::Map;
+using blender::short3;
+using blender::uchar3;
+using blender::ushort3;
+using blender::ushort4;
+using blender::Vector;
+
+using string = std::string;
+
+struct PBVHVbo {
+ uint64_t type;
+ eAttrDomain domain;
+ string name;
+ GPUVertBuf *vert_buf = nullptr;
+ string key;
+
+ PBVHVbo(eAttrDomain _domain, uint64_t _type, string _name)
+ : type(_type), domain(_domain), name(_name)
+ {
+ }
+
+ void clear_data()
+ {
+ GPU_vertbuf_clear(vert_buf);
+ }
+
+ string build_key()
+ {
+ char buf[512];
+
+ BLI_snprintf(buf, sizeof(buf), "%d:%d:%s", int(type), int(domain), name.c_str());
+
+ key = string(buf);
+ return key;
+ }
+};
+
+struct PBVHBatch {
+ Vector<int> vbos;
+ string key;
+ GPUBatch *tris = nullptr, *lines = nullptr;
+ int tris_count = 0, lines_count = 0;
+
+ void sort_vbos(Vector<PBVHVbo> &master_vbos)
+ {
+ struct cmp {
+ Vector<PBVHVbo> &master_vbos;
+
+ cmp(Vector<PBVHVbo> &_master_vbos) : master_vbos(_master_vbos)
+ {
+ }
+
+ bool operator()(const int &a, const int &b)
+ {
+ return master_vbos[a].key < master_vbos[b].key;
+ }
+ };
+
+ std::sort(vbos.begin(), vbos.end(), cmp(master_vbos));
+ }
+
+ string build_key(Vector<PBVHVbo> &master_vbos)
+ {
+ key = "";
+
+ sort_vbos(master_vbos);
+
+ for (int vbo_i : vbos) {
+ key += master_vbos[vbo_i].key + ":";
+ }
+
+ return key;
+ }
+};
+
+static CustomData *get_cdata(eAttrDomain domain, PBVH_GPU_Args *args)
+{
+ switch (domain) {
+ case ATTR_DOMAIN_POINT:
+ return args->vdata;
+ case ATTR_DOMAIN_CORNER:
+ return args->ldata;
+ case ATTR_DOMAIN_FACE:
+ return args->pdata;
+ default:
+ return nullptr;
+ }
+}
+
+struct PBVHBatches {
+ Vector<PBVHVbo> vbos;
+ Map<string, PBVHBatch> batches;
+ GPUIndexBuf *tri_index = nullptr;
+ GPUIndexBuf *lines_index = nullptr;
+ int faces_count = 0; /* Used by PBVH_BMESH and PBVH_GRIDS */
+ int tris_count = 0, lines_count = 0;
+ bool needs_tri_index = false;
+
+ int material_index = 0;
+
+ int count_faces(PBVH_GPU_Args *args)
+ {
+ int count = 0;
+
+ switch (args->pbvh_type) {
+ case PBVH_FACES: {
+ for (int i = 0; i < args->totprim; i++) {
+ int face_index = args->mlooptri[args->prim_indices[i]].poly;
+
+ if (args->hide_poly && args->hide_poly[face_index]) {
+ continue;
+ }
+
+ count++;
+ }
+ break;
+ }
+ case PBVH_GRIDS: {
+ count = BKE_pbvh_count_grid_quads((BLI_bitmap **)args->grid_hidden,
+ args->grid_indices,
+ args->totprim,
+ args->ccg_key.grid_size);
+
+ break;
+ }
+ case PBVH_BMESH: {
+ GSET_FOREACH_BEGIN (BMFace *, f, args->bm_faces) {
+ if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ count++;
+ }
+ }
+ GSET_FOREACH_END();
+ }
+ }
+
+ return count;
+ }
+
+ PBVHBatches(PBVH_GPU_Args *args)
+ {
+ faces_count = count_faces(args);
+
+ if (args->pbvh_type == PBVH_BMESH) {
+ tris_count = faces_count;
+ }
+ }
+
+ ~PBVHBatches()
+ {
+ for (PBVHBatch &batch : batches.values()) {
+ GPU_BATCH_DISCARD_SAFE(batch.tris);
+ GPU_BATCH_DISCARD_SAFE(batch.lines);
+ }
+
+ for (PBVHVbo &vbo : vbos) {
+ GPU_vertbuf_discard(vbo.vert_buf);
+ }
+
+ GPU_INDEXBUF_DISCARD_SAFE(tri_index);
+ GPU_INDEXBUF_DISCARD_SAFE(lines_index);
+ }
+
+ string build_key(PBVHAttrReq *attrs, int attrs_num)
+ {
+ string key;
+ PBVHBatch batch;
+ Vector<PBVHVbo> vbos;
+
+ for (int i : IndexRange(attrs_num)) {
+ PBVHAttrReq *attr = attrs + i;
+
+ PBVHVbo vbo(attr->domain, attr->type, string(attr->name));
+ vbo.build_key();
+
+ vbos.append(vbo);
+ batch.vbos.append(i);
+ }
+
+ batch.build_key(vbos);
+ return batch.key;
+ }
+
+ bool has_vbo(eAttrDomain domain, int type, string name)
+ {
+ for (PBVHVbo &vbo : vbos) {
+ if (vbo.domain == domain && vbo.type == type && vbo.name == name) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ int get_vbo_index(PBVHVbo *vbo)
+ {
+ for (int i : IndexRange(vbos.size())) {
+ if (vbo == &vbos[i]) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ PBVHVbo *get_vbo(eAttrDomain domain, int type, string name)
+ {
+ for (PBVHVbo &vbo : vbos) {
+ if (vbo.domain == domain && vbo.type == type && vbo.name == name) {
+ return &vbo;
+ }
+ }
+
+ return nullptr;
+ }
+
+ bool has_batch(PBVHAttrReq *attrs, int attrs_num)
+ {
+ return batches.contains(build_key(attrs, attrs_num));
+ }
+
+ PBVHBatch &ensure_batch(PBVHAttrReq *attrs, int attrs_num, PBVH_GPU_Args *args)
+ {
+ if (!has_batch(attrs, attrs_num)) {
+ create_batch(attrs, attrs_num, args);
+ }
+
+ return batches.lookup(build_key(attrs, attrs_num));
+ }
+
+ void fill_vbo_normal_faces(
+ PBVHVbo & /*vbo*/,
+ PBVH_GPU_Args *args,
+ std::function<void(std::function<void(int, int, int, const MLoopTri *)> callback)>
+ foreach_faces,
+ GPUVertBufRaw *access)
+ {
+ float fno[3];
+ short no[3];
+ int last_poly = -1;
+ bool smooth = false;
+
+ foreach_faces([&](int /*buffer_i*/, int /*tri_i*/, int vertex_i, const MLoopTri *tri) {
+ const MPoly *mp = args->mpoly + tri->poly;
+
+ if (tri->poly != last_poly) {
+ last_poly = tri->poly;
+
+ if (!(mp->flag & ME_SMOOTH)) {
+ smooth = true;
+ BKE_mesh_calc_poly_normal(mp, args->mloop + mp->loopstart, args->mvert, fno);
+ normal_float_to_short_v3(no, fno);
+ }
+ else {
+ smooth = false;
+ }
+ }
+
+ if (!smooth) {
+ normal_float_to_short_v3(no, args->vert_normals[vertex_i]);
+ }
+
+ *static_cast<short3 *>(GPU_vertbuf_raw_step(access)) = no;
+ });
+ }
+
+ void fill_vbo_grids_intern(
+ PBVHVbo &vbo,
+ PBVH_GPU_Args *args,
+ std::function<
+ void(std::function<void(int x, int y, int grid_index, CCGElem *elems[4], int i)> func)>
+ foreach_grids)
+ {
+ uint vert_per_grid = square_i(args->ccg_key.grid_size - 1) * 4;
+ uint vert_count = args->totprim * vert_per_grid;
+
+ int existing_num = GPU_vertbuf_get_vertex_len(vbo.vert_buf);
+ void *existing_data = GPU_vertbuf_get_data(vbo.vert_buf);
+
+ if (existing_data == nullptr || existing_num != vert_count) {
+ /* Allocate buffer if not allocated yet or size changed. */
+ GPU_vertbuf_data_alloc(vbo.vert_buf, vert_count);
+ }
+
+ GPUVertBufRaw access;
+ GPU_vertbuf_attr_get_raw_data(vbo.vert_buf, 0, &access);
+
+ switch (vbo.type) {
+ case CD_PROP_COLOR:
+ case CD_PROP_BYTE_COLOR: {
+ /* TODO: Implement color support for multires similar to the mesh cache
+ * extractor code. For now just upload white.
+ */
+ const ushort4 white(USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX);
+
+ foreach_grids(
+ [&](int /*x*/, int /*y*/, int /*grid_index*/, CCGElem * /*elems*/[4], int /*i*/) {
+ *static_cast<ushort4 *>(GPU_vertbuf_raw_step(&access)) = white;
+ });
+ break;
+ }
+ case CD_PBVH_CO_TYPE:
+ foreach_grids([&](int /*x*/, int /*y*/, int /*grid_index*/, CCGElem *elems[4], int i) {
+ float *co = CCG_elem_co(&args->ccg_key, elems[i]);
+
+ *static_cast<float3 *>(GPU_vertbuf_raw_step(&access)) = co;
+ });
+ break;
+
+ case CD_PBVH_NO_TYPE:
+ foreach_grids([&](int /*x*/, int /*y*/, int grid_index, CCGElem *elems[4], int /*i*/) {
+ float3 no(0.0f, 0.0f, 0.0f);
+
+ const bool smooth = args->grid_flag_mats[grid_index].flag & ME_SMOOTH;
+
+ if (smooth) {
+ no = CCG_elem_no(&args->ccg_key, elems[0]);
+ }
+ else {
+ for (int j = 0; j < 4; j++) {
+ no += CCG_elem_no(&args->ccg_key, elems[j]);
+ }
+ }
+
+ normalize_v3(no);
+ short sno[3];
+
+ normal_float_to_short_v3(sno, no);
+
+ *static_cast<short3 *>(GPU_vertbuf_raw_step(&access)) = sno;
+ });
+ break;
+
+ case CD_PBVH_MASK_TYPE:
+ if (args->ccg_key.has_mask) {
+ foreach_grids([&](int /*x*/, int /*y*/, int /*grid_index*/, CCGElem *elems[4], int i) {
+ float *mask = CCG_elem_mask(&args->ccg_key, elems[i]);
+
+ *static_cast<uchar *>(GPU_vertbuf_raw_step(&access)) = uchar(*mask * 255.0f);
+ });
+ }
+ else {
+ foreach_grids(
+ [&](int /*x*/, int /*y*/, int /*grid_index*/, CCGElem * /*elems*/[4], int /*i*/) {
+ *static_cast<uchar *>(GPU_vertbuf_raw_step(&access)) = 0;
+ });
+ }
+ break;
+
+ case CD_PBVH_FSET_TYPE: {
+ int *face_sets = args->face_sets;
+
+ if (!face_sets) {
+ uchar white[3] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
+
+ foreach_grids(
+ [&](int /*x*/, int /*y*/, int /*grid_index*/, CCGElem * /*elems*/[4], int /*i*/) {
+ *static_cast<uchar3 *>(GPU_vertbuf_raw_step(&access)) = white;
+ });
+ }
+ else {
+ foreach_grids(
+ [&](int /*x*/, int /*y*/, int grid_index, CCGElem * /*elems*/[4], int /*i*/) {
+ uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
+
+ if (face_sets) {
+ const int face_index = BKE_subdiv_ccg_grid_to_face_index(args->subdiv_ccg,
+ grid_index);
+ const int fset = face_sets[face_index];
+
+ /* Skip for the default color Face Set to render it white. */
+ if (fset != args->face_sets_color_default) {
+ BKE_paint_face_set_overlay_color_get(
+ fset, args->face_sets_color_seed, face_set_color);
+ }
+ }
+
+ *static_cast<uchar3 *>(GPU_vertbuf_raw_step(&access)) = face_set_color;
+ });
+ }
+ break;
+ }
+ }
+ }
+
+ void fill_vbo_grids(PBVHVbo &vbo, PBVH_GPU_Args *args)
+ {
+ int gridsize = args->ccg_key.grid_size;
+
+ uint totgrid = args->totprim;
+
+ auto foreach_solid =
+ [&](std::function<void(int x, int y, int grid_index, CCGElem *elems[4], int i)> func) {
+ for (int i = 0; i < totgrid; i++) {
+ const int grid_index = args->grid_indices[i];
+
+ CCGElem *grid = args->grids[grid_index];
+
+ for (int y = 0; y < gridsize - 1; y++) {
+ for (int x = 0; x < gridsize - 1; x++) {
+ CCGElem *elems[4] = {
+ CCG_grid_elem(&args->ccg_key, grid, x, y),
+ CCG_grid_elem(&args->ccg_key, grid, x + 1, y),
+ CCG_grid_elem(&args->ccg_key, grid, x + 1, y + 1),
+ CCG_grid_elem(&args->ccg_key, grid, x, y + 1),
+ };
+
+ func(x, y, grid_index, elems, 0);
+ func(x + 1, y, grid_index, elems, 1);
+ func(x + 1, y + 1, grid_index, elems, 2);
+ func(x, y + 1, grid_index, elems, 3);
+ }
+ }
+ }
+ };
+
+ auto foreach_indexed =
+ [&](std::function<void(int x, int y, int grid_index, CCGElem *elems[4], int i)> func) {
+ for (int i = 0; i < totgrid; i++) {
+ const int grid_index = args->grid_indices[i];
+
+ CCGElem *grid = args->grids[grid_index];
+
+ for (int y = 0; y < gridsize; y++) {
+ for (int x = 0; x < gridsize; x++) {
+ CCGElem *elems[4] = {
+ CCG_grid_elem(&args->ccg_key, grid, x, y),
+ CCG_grid_elem(&args->ccg_key, grid, x + 1, y),
+ CCG_grid_elem(&args->ccg_key, grid, x + 1, y + 1),
+ CCG_grid_elem(&args->ccg_key, grid, x, y + 1),
+ };
+
+ func(x, y, grid_index, elems, 0);
+ }
+ }
+ }
+ };
+
+ if (needs_tri_index) {
+ fill_vbo_grids_intern(vbo, args, foreach_indexed);
+ }
+ else {
+ fill_vbo_grids_intern(vbo, args, foreach_solid);
+ }
+ }
+
+ void fill_vbo_faces(PBVHVbo &vbo, PBVH_GPU_Args *args)
+ {
+ auto foreach_faces =
+ [&](std::function<void(int buffer_i, int tri_i, int vertex_i, const MLoopTri *tri)> func) {
+ int buffer_i = 0;
+ const MLoop *mloop = args->mloop;
+
+ for (int i : IndexRange(args->totprim)) {
+ int face_index = args->mlooptri[args->prim_indices[i]].poly;
+
+ if (args->hide_poly && args->hide_poly[face_index]) {
+ continue;
+ }
+
+ const MLoopTri *tri = args->mlooptri + args->prim_indices[i];
+
+ for (int j : IndexRange(3)) {
+ func(buffer_i, j, mloop[tri->tri[j]].v, tri);
+ buffer_i++;
+ }
+ }
+ };
+
+ int totvert = 0;
+ foreach_faces([&totvert](int, int, int, const MLoopTri *) { totvert++; });
+
+ int existing_num = GPU_vertbuf_get_vertex_len(vbo.vert_buf);
+ void *existing_data = GPU_vertbuf_get_data(vbo.vert_buf);
+
+ if (existing_data == nullptr || existing_num != totvert) {
+ /* Allocate buffer if not allocated yet or size changed. */
+ GPU_vertbuf_data_alloc(vbo.vert_buf, totvert);
+ }
+
+ GPUVertBufRaw access;
+ GPU_vertbuf_attr_get_raw_data(vbo.vert_buf, 0, &access);
+
+ switch (vbo.type) {
+ case CD_PBVH_CO_TYPE:
+ foreach_faces(
+ [&](int /*buffer_i*/, int /*tri_i*/, int vertex_i, const MLoopTri * /*tri*/) {
+ *static_cast<float3 *>(GPU_vertbuf_raw_step(&access)) = args->mvert[vertex_i].co;
+ });
+ break;
+ case CD_PBVH_NO_TYPE:
+ fill_vbo_normal_faces(vbo, args, foreach_faces, &access);
+ break;
+ case CD_PBVH_MASK_TYPE: {
+ float *mask = static_cast<float *>(CustomData_get_layer(args->vdata, CD_PAINT_MASK));
+
+ if (mask) {
+ foreach_faces(
+ [&](int /*buffer_i*/, int /*tri_i*/, int vertex_i, const MLoopTri * /*tri*/) {
+ *static_cast<uchar *>(GPU_vertbuf_raw_step(&access)) = uchar(mask[vertex_i] *
+ 255.0f);
+ });
+ }
+ else {
+ foreach_faces(
+ [&](int /*buffer_i*/, int /*tri_i*/, int /*vertex_i*/, const MLoopTri * /*tri*/) {
+ *static_cast<uchar *>(GPU_vertbuf_raw_step(&access)) = 0;
+ });
+ }
+ break;
+ }
+ case CD_PBVH_FSET_TYPE: {
+ int *face_sets = static_cast<int *>(
+ CustomData_get_layer_named(args->pdata, CD_PROP_INT32, ".sculpt_face_set"));
+
+ if (face_sets) {
+ int last_poly = -1;
+ uchar fset_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
+
+ foreach_faces(
+ [&](int /*buffer_i*/, int /*tri_i*/, int /*vertex_i*/, const MLoopTri *tri) {
+ if (last_poly != tri->poly) {
+ last_poly = tri->poly;
+
+ const int fset = face_sets[tri->poly];
+
+ if (fset != args->face_sets_color_default) {
+ BKE_paint_face_set_overlay_color_get(
+ fset, args->face_sets_color_seed, fset_color);
+ }
+ else {
+ /* Skip for the default color face set to render it white. */
+ fset_color[0] = fset_color[1] = fset_color[2] = UCHAR_MAX;
+ }
+ }
+
+ *static_cast<uchar3 *>(GPU_vertbuf_raw_step(&access)) = fset_color;
+ });
+ }
+ else {
+ uchar fset_color[4] = {255, 255, 255, 255};
+
+ foreach_faces(
+ [&](int /*buffer_i*/, int /*tri_i*/, int /*vertex_i*/, const MLoopTri * /*tri*/) {
+ *static_cast<uchar3 *>(GPU_vertbuf_raw_step(&access)) = fset_color;
+ });
+ }
+
+ break;
+ }
+ case CD_MLOOPUV: {
+ MLoopUV *mloopuv = static_cast<MLoopUV *>(
+ CustomData_get_layer_named(args->ldata, CD_MLOOPUV, vbo.name.c_str()));
+
+ foreach_faces([&](int /*buffer_i*/, int tri_i, int /*vertex_i*/, const MLoopTri *tri) {
+ *static_cast<float2 *>(GPU_vertbuf_raw_step(&access)) = mloopuv[tri->tri[tri_i]].uv;
+ });
+ break;
+ }
+ case CD_PROP_COLOR:
+ if (vbo.domain == ATTR_DOMAIN_POINT) {
+ MPropCol *mpropcol = static_cast<MPropCol *>(
+ CustomData_get_layer_named(args->vdata, CD_PROP_COLOR, vbo.name.c_str()));
+
+ foreach_faces(
+ [&](int /*buffer_i*/, int /*tri_i*/, int vertex_i, const MLoopTri * /*tri*/) {
+ ushort color[4];
+ MPropCol *col = mpropcol + vertex_i;
+
+ color[0] = unit_float_to_ushort_clamp(col->color[0]);
+ color[1] = unit_float_to_ushort_clamp(col->color[1]);
+ color[2] = unit_float_to_ushort_clamp(col->color[2]);
+ color[3] = unit_float_to_ushort_clamp(col->color[3]);
+
+ *static_cast<ushort4 *>(GPU_vertbuf_raw_step(&access)) = color;
+ });
+ }
+ else if (vbo.domain == ATTR_DOMAIN_CORNER) {
+ MPropCol *mpropcol = static_cast<MPropCol *>(
+ CustomData_get_layer_named(args->ldata, CD_PROP_COLOR, vbo.name.c_str()));
+
+ foreach_faces([&](int /*buffer_i*/, int tri_i, int /*vertex_i*/, const MLoopTri *tri) {
+ ushort color[4];
+ MPropCol *col = mpropcol + tri->tri[tri_i];
+
+ color[0] = unit_float_to_ushort_clamp(col->color[0]);
+ color[1] = unit_float_to_ushort_clamp(col->color[1]);
+ color[2] = unit_float_to_ushort_clamp(col->color[2]);
+ color[3] = unit_float_to_ushort_clamp(col->color[3]);
+
+ *static_cast<ushort4 *>(GPU_vertbuf_raw_step(&access)) = color;
+ });
+ }
+ break;
+ case CD_PROP_BYTE_COLOR:
+ if (vbo.domain == ATTR_DOMAIN_POINT) {
+ MLoopCol *mbytecol = static_cast<MLoopCol *>(
+ CustomData_get_layer_named(args->vdata, CD_PROP_BYTE_COLOR, vbo.name.c_str()));
+
+ foreach_faces(
+ [&](int /*buffer_i*/, int /*tri_i*/, int vertex_i, const MLoopTri * /*tri*/) {
+ ushort color[4];
+ MLoopCol *col = mbytecol + vertex_i;
+
+ color[0] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[col->r]);
+ color[1] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[col->g]);
+ color[2] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[col->b]);
+ color[3] = col->a * 257;
+
+ *static_cast<ushort4 *>(GPU_vertbuf_raw_step(&access)) = color;
+ });
+ }
+ else if (vbo.domain == ATTR_DOMAIN_CORNER) {
+ MLoopCol *mbytecol = static_cast<MLoopCol *>(
+ CustomData_get_layer_named(args->ldata, CD_PROP_BYTE_COLOR, vbo.name.c_str()));
+
+ foreach_faces([&](int /*buffer_i*/, int tri_i, int /*vertex_i*/, const MLoopTri *tri) {
+ ushort color[4];
+ MLoopCol *col = mbytecol + tri->tri[tri_i];
+
+ color[0] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[col->r]);
+ color[1] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[col->g]);
+ color[2] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[col->b]);
+ color[3] = col->a * 257;
+
+ *static_cast<ushort4 *>(GPU_vertbuf_raw_step(&access)) = color;
+ });
+ }
+ break;
+ }
+ }
+
+ void gpu_flush()
+ {
+ for (PBVHVbo &vbo : vbos) {
+ if (vbo.vert_buf && GPU_vertbuf_get_data(vbo.vert_buf)) {
+ GPU_vertbuf_use(vbo.vert_buf);
+ }
+ }
+ }
+
+ void update(PBVH_GPU_Args *args)
+ {
+ check_index_buffers(args);
+
+ for (PBVHVbo &vbo : vbos) {
+ fill_vbo(vbo, args);
+ }
+ }
+
+ void fill_vbo_bmesh(PBVHVbo &vbo, PBVH_GPU_Args *args)
+ {
+ auto foreach_bmesh = [&](std::function<void(BMLoop * l)> callback) {
+ GSET_FOREACH_BEGIN (BMFace *, f, args->bm_faces) {
+ if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ continue;
+ }
+
+ BMLoop *l = f->l_first;
+ callback(l->prev);
+ callback(l);
+ callback(l->next);
+ }
+ GSET_FOREACH_END();
+ };
+
+ faces_count = tris_count = count_faces(args);
+
+ int existing_num = GPU_vertbuf_get_vertex_len(vbo.vert_buf);
+ void *existing_data = GPU_vertbuf_get_data(vbo.vert_buf);
+
+ int vert_count = tris_count * 3;
+
+ if (existing_data == nullptr || existing_num != vert_count) {
+ /* Allocate buffer if not allocated yet or size changed. */
+ GPU_vertbuf_data_alloc(vbo.vert_buf, vert_count);
+ }
+
+ GPUVertBufRaw access;
+ GPU_vertbuf_attr_get_raw_data(vbo.vert_buf, 0, &access);
+
+#if 0 /* Enable to fuzz GPU data (to check for over-allocation). */
+ existing_data = GPU_vertbuf_get_data(vbo.vert_buf);
+ uchar *c = static_cast<uchar *>(existing_data);
+ for (int i : IndexRange(vert_count * access.stride)) {
+ *c++ = i & 255;
+ }
+#endif
+
+ switch (vbo.type) {
+ case CD_PROP_COLOR:
+ case CD_PROP_BYTE_COLOR: {
+ ushort4 white = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
+
+ foreach_bmesh([&](BMLoop * /*l*/) {
+ *static_cast<ushort4 *>(GPU_vertbuf_raw_step(&access)) = white;
+ });
+ break;
+ }
+ case CD_PBVH_CO_TYPE:
+ foreach_bmesh(
+ [&](BMLoop *l) { *static_cast<float3 *>(GPU_vertbuf_raw_step(&access)) = l->v->co; });
+ break;
+
+ case CD_PBVH_NO_TYPE:
+ foreach_bmesh([&](BMLoop *l) {
+ short no[3];
+ bool smooth = BM_elem_flag_test(l->f, BM_ELEM_SMOOTH);
+
+ normal_float_to_short_v3(no, smooth ? l->v->no : l->f->no);
+ *static_cast<short3 *>(GPU_vertbuf_raw_step(&access)) = no;
+ });
+ break;
+
+ case CD_PBVH_MASK_TYPE: {
+ int cd_mask = args->cd_mask_layer;
+
+ if (cd_mask == -1) {
+ foreach_bmesh(
+ [&](BMLoop * /*l*/) { *static_cast<float *>(GPU_vertbuf_raw_step(&access)) = 0; });
+ }
+ else {
+ foreach_bmesh([&](BMLoop *l) {
+ float mask = BM_ELEM_CD_GET_FLOAT(l->v, cd_mask);
+
+ *static_cast<uchar *>(GPU_vertbuf_raw_step(&access)) = uchar(mask * 255.0f);
+ });
+ }
+ break;
+ }
+ case CD_PBVH_FSET_TYPE: {
+ uchar3 white(UCHAR_MAX, UCHAR_MAX, UCHAR_MAX);
+
+ foreach_bmesh([&](BMLoop * /*l*/) {
+ *static_cast<uchar3 *>(GPU_vertbuf_raw_step(&access)) = white;
+ });
+ }
+ }
+ }
+
+ void fill_vbo(PBVHVbo &vbo, PBVH_GPU_Args *args)
+ {
+ switch (args->pbvh_type) {
+ case PBVH_FACES:
+ fill_vbo_faces(vbo, args);
+ break;
+ case PBVH_GRIDS:
+ fill_vbo_grids(vbo, args);
+ break;
+ case PBVH_BMESH:
+ fill_vbo_bmesh(vbo, args);
+ break;
+ }
+ }
+
+ void create_vbo(eAttrDomain domain, const uint32_t type, string name, PBVH_GPU_Args *args)
+ {
+ PBVHVbo vbo(domain, type, name);
+ GPUVertFormat format;
+
+ bool need_aliases = !ELEM(
+ type, CD_PBVH_CO_TYPE, CD_PBVH_NO_TYPE, CD_PBVH_FSET_TYPE, CD_PBVH_MASK_TYPE);
+
+ GPU_vertformat_clear(&format);
+
+ switch (type) {
+ case CD_PBVH_CO_TYPE:
+ GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ break;
+ case CD_PROP_FLOAT3:
+ GPU_vertformat_attr_add(&format, "a", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ need_aliases = true;
+ break;
+ case CD_PBVH_NO_TYPE:
+ GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ break;
+ case CD_PROP_FLOAT2:
+ GPU_vertformat_attr_add(&format, "a", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ need_aliases = true;
+ break;
+ case CD_MLOOPUV:
+ GPU_vertformat_attr_add(&format, "uvs", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ need_aliases = true;
+ break;
+ case CD_PBVH_FSET_TYPE:
+ GPU_vertformat_attr_add(&format, "fset", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ break;
+ case CD_PBVH_MASK_TYPE:
+ GPU_vertformat_attr_add(&format, "msk", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ break;
+ case CD_PROP_FLOAT:
+ GPU_vertformat_attr_add(&format, "f", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ need_aliases = true;
+ break;
+ case CD_PROP_COLOR:
+ case CD_PROP_BYTE_COLOR: {
+ GPU_vertformat_attr_add(&format, "c", GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ need_aliases = true;
+ break;
+ }
+ default:
+ BLI_assert(0);
+ printf("%s: error\n", __func__);
+
+ break;
+ }
+
+ if (need_aliases) {
+ CustomData *cdata = get_cdata(domain, args);
+ int layer_i = cdata ? CustomData_get_named_layer_index(cdata, type, name.c_str()) : -1;
+ CustomDataLayer *layer = layer_i != -1 ? cdata->layers + layer_i : nullptr;
+
+ if (layer) {
+ bool is_render, is_active;
+ const char *prefix = "a";
+
+ if (ELEM(type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) {
+ Mesh query_mesh;
+
+ /* Check if we have args->me; if not use get_cdata to build something we
+ * can query for color attributes.
+ */
+ if (args->me) {
+ memcpy(static_cast<void *>(&query_mesh),
+ static_cast<const void *>(args->me),
+ sizeof(Mesh));
+ }
+ else {
+ BKE_id_attribute_copy_domains_temp(ID_ME,
+ get_cdata(ATTR_DOMAIN_POINT, args),
+ nullptr,
+ get_cdata(ATTR_DOMAIN_CORNER, args),
+ nullptr,
+ nullptr,
+ &query_mesh.id);
+ }
+
+ prefix = "c";
+
+ CustomDataLayer *render = BKE_id_attributes_render_color_get(&query_mesh.id);
+ CustomDataLayer *active = BKE_id_attributes_active_color_get(&query_mesh.id);
+
+ is_render = render && layer && STREQ(render->name, layer->name);
+ is_active = active && layer && STREQ(active->name, layer->name);
+ }
+ else {
+ switch (type) {
+ case CD_MLOOPUV:
+ prefix = "u";
+ break;
+ default:
+ break;
+ }
+
+ const char *active_name = CustomData_get_active_layer_name(cdata, type);
+ const char *render_name = CustomData_get_render_layer_name(cdata, type);
+
+ is_active = active_name && STREQ(layer->name, active_name);
+ is_render = render_name && STREQ(layer->name, render_name);
+ }
+
+ DRW_cdlayer_attr_aliases_add(&format, prefix, cdata, layer, is_render, is_active);
+ }
+ else {
+ printf("%s: error looking up attribute %s\n", __func__, name.c_str());
+ }
+ }
+
+ vbo.vert_buf = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_STATIC);
+ vbo.build_key();
+ fill_vbo(vbo, args);
+
+ vbos.append(vbo);
+ }
+
+ void update_pre(PBVH_GPU_Args *args)
+ {
+ if (args->pbvh_type == PBVH_BMESH) {
+ int count = count_faces(args);
+
+ if (faces_count != count) {
+ for (PBVHVbo &vbo : vbos) {
+ vbo.clear_data();
+ }
+
+ GPU_INDEXBUF_DISCARD_SAFE(tri_index);
+ GPU_INDEXBUF_DISCARD_SAFE(lines_index);
+
+ tri_index = lines_index = nullptr;
+ faces_count = tris_count = count;
+ }
+ }
+ }
+
+ void create_index_faces(PBVH_GPU_Args *args)
+ {
+ int *mat_index = static_cast<int *>(
+ CustomData_get_layer_named(args->pdata, CD_PROP_INT32, "material_index"));
+
+ if (mat_index && args->totprim) {
+ int poly_index = args->mlooptri[args->prim_indices[0]].poly;
+ material_index = mat_index[poly_index];
+ }
+
+ /* Calculate number of edges*/
+ int edge_count = 0;
+ for (int i = 0; i < args->totprim; i++) {
+ const MLoopTri *lt = args->mlooptri + args->prim_indices[i];
+
+ if (args->hide_poly && args->hide_poly[lt->poly]) {
+ continue;
+ }
+
+ int r_edges[3];
+ BKE_mesh_looptri_get_real_edges(args->me, lt, r_edges);
+
+ if (r_edges[0] != -1) {
+ edge_count++;
+ }
+ if (r_edges[1] != -1) {
+ edge_count++;
+ }
+ if (r_edges[2] != -1) {
+ edge_count++;
+ }
+ }
+
+ GPUIndexBufBuilder elb_lines;
+ GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, edge_count * 2, INT_MAX);
+
+ int vertex_i = 0;
+ for (int i = 0; i < args->totprim; i++) {
+ const MLoopTri *lt = args->mlooptri + args->prim_indices[i];
+
+ if (args->hide_poly && args->hide_poly[lt->poly]) {
+ continue;
+ }
+
+ int r_edges[3];
+ BKE_mesh_looptri_get_real_edges(args->me, lt, r_edges);
+
+ if (r_edges[0] != -1) {
+ GPU_indexbuf_add_line_verts(&elb_lines, vertex_i, vertex_i + 1);
+ }
+ if (r_edges[1] != -1) {
+ GPU_indexbuf_add_line_verts(&elb_lines, vertex_i + 1, vertex_i + 2);
+ }
+ if (r_edges[2] != -1) {
+ GPU_indexbuf_add_line_verts(&elb_lines, vertex_i + 2, vertex_i);
+ }
+
+ vertex_i += 3;
+ }
+
+ lines_index = GPU_indexbuf_build(&elb_lines);
+ }
+
+ void create_index_bmesh(PBVH_GPU_Args *args)
+ {
+ GPUIndexBufBuilder elb_lines;
+ GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tris_count * 3 * 2, INT_MAX);
+
+ int v_index = 0;
+ lines_count = 0;
+
+ GSET_FOREACH_BEGIN (BMFace *, f, args->bm_faces) {
+ if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ continue;
+ }
+
+ GPU_indexbuf_add_line_verts(&elb_lines, v_index, v_index + 1);
+ GPU_indexbuf_add_line_verts(&elb_lines, v_index + 1, v_index + 2);
+ GPU_indexbuf_add_line_verts(&elb_lines, v_index + 2, v_index);
+
+ lines_count += 3;
+ v_index += 3;
+ }
+ GSET_FOREACH_END();
+
+ lines_index = GPU_indexbuf_build(&elb_lines);
+ }
+
+ void create_index_grids(PBVH_GPU_Args *args)
+ {
+ int *mat_index = static_cast<int *>(
+ CustomData_get_layer_named(args->pdata, CD_PROP_INT32, "material_index"));
+
+ if (mat_index && args->totprim) {
+ int poly_index = BKE_subdiv_ccg_grid_to_face_index(args->subdiv_ccg, args->grid_indices[0]);
+ material_index = mat_index[poly_index];
+ }
+
+ needs_tri_index = true;
+ int gridsize = args->ccg_key.grid_size;
+ int totgrid = args->totprim;
+
+ for (int i : IndexRange(args->totprim)) {
+ int grid_index = args->grid_indices[i];
+ bool smooth = args->grid_flag_mats[grid_index].flag & ME_SMOOTH;
+ BLI_bitmap *gh = args->grid_hidden[grid_index];
+
+ for (int y = 0; y < gridsize - 1; y++) {
+ for (int x = 0; x < gridsize - 1; x++) {
+ if (gh && paint_is_grid_face_hidden(gh, gridsize, x, y)) {
+ /* Skip hidden faces by just setting smooth to true. */
+ smooth = true;
+ goto outer_loop_break;
+ }
+ }
+ }
+
+ outer_loop_break:
+
+ if (!smooth) {
+ needs_tri_index = false;
+ break;
+ }
+ }
+
+ GPUIndexBufBuilder elb, elb_lines;
+
+ CCGKey *key = &args->ccg_key;
+
+ uint visible_quad_len = BKE_pbvh_count_grid_quads(
+ (BLI_bitmap **)args->grid_hidden, args->grid_indices, totgrid, key->grid_size);
+
+ GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, 2 * visible_quad_len, INT_MAX);
+ GPU_indexbuf_init(
+ &elb_lines, GPU_PRIM_LINES, 2 * totgrid * gridsize * (gridsize - 1), INT_MAX);
+
+ if (needs_tri_index) {
+ uint offset = 0;
+ const uint grid_vert_len = gridsize * gridsize;
+ for (int i = 0; i < totgrid; i++, offset += grid_vert_len) {
+ uint v0, v1, v2, v3;
+ bool grid_visible = false;
+
+ BLI_bitmap *gh = args->grid_hidden[args->grid_indices[i]];
+
+ for (int j = 0; j < gridsize - 1; j++) {
+ for (int k = 0; k < gridsize - 1; k++) {
+ /* Skip hidden grid face */
+ if (gh && paint_is_grid_face_hidden(gh, gridsize, k, j)) {
+ continue;
+ }
+ /* Indices in a Clockwise QUAD disposition. */
+ v0 = offset + j * gridsize + k;
+ v1 = v0 + 1;
+ v2 = v1 + gridsize;
+ v3 = v2 - 1;
+
+ GPU_indexbuf_add_tri_verts(&elb, v0, v2, v1);
+ GPU_indexbuf_add_tri_verts(&elb, v0, v3, v2);
+
+ GPU_indexbuf_add_line_verts(&elb_lines, v0, v1);
+ GPU_indexbuf_add_line_verts(&elb_lines, v0, v3);
+
+ if (j + 2 == gridsize) {
+ GPU_indexbuf_add_line_verts(&elb_lines, v2, v3);
+ }
+ grid_visible = true;
+ }
+
+ if (grid_visible) {
+ GPU_indexbuf_add_line_verts(&elb_lines, v1, v2);
+ }
+ }
+ }
+ }
+ else {
+ uint offset = 0;
+ const uint grid_vert_len = square_uint(gridsize - 1) * 4;
+ for (int i = 0; i < totgrid; i++, offset += grid_vert_len) {
+ bool grid_visible = false;
+ BLI_bitmap *gh = args->grid_hidden[args->grid_indices[i]];
+
+ uint v0, v1, v2, v3;
+ for (int j = 0; j < gridsize - 1; j++) {
+ for (int k = 0; k < gridsize - 1; k++) {
+ /* Skip hidden grid face */
+ if (gh && paint_is_grid_face_hidden(gh, gridsize, k, j)) {
+ continue;
+ }
+ /* VBO data are in a Clockwise QUAD disposition. */
+ v0 = offset + (j * (gridsize - 1) + k) * 4;
+ v1 = v0 + 1;
+ v2 = v0 + 2;
+ v3 = v0 + 3;
+
+ GPU_indexbuf_add_tri_verts(&elb, v0, v2, v1);
+ GPU_indexbuf_add_tri_verts(&elb, v0, v3, v2);
+
+ GPU_indexbuf_add_line_verts(&elb_lines, v0, v1);
+ GPU_indexbuf_add_line_verts(&elb_lines, v0, v3);
+
+ if (j + 2 == gridsize) {
+ GPU_indexbuf_add_line_verts(&elb_lines, v2, v3);
+ }
+ grid_visible = true;
+ }
+
+ if (grid_visible) {
+ GPU_indexbuf_add_line_verts(&elb_lines, v1, v2);
+ }
+ }
+ }
+ }
+
+ tri_index = GPU_indexbuf_build(&elb);
+ lines_index = GPU_indexbuf_build(&elb_lines);
+ }
+
+ void create_index(PBVH_GPU_Args *args)
+ {
+ switch (args->pbvh_type) {
+ case PBVH_FACES:
+ create_index_faces(args);
+ break;
+ case PBVH_BMESH:
+ create_index_bmesh(args);
+ break;
+ case PBVH_GRIDS:
+ create_index_grids(args);
+ break;
+ }
+
+ for (PBVHBatch &batch : batches.values()) {
+ if (tri_index) {
+ GPU_batch_elembuf_set(batch.tris, tri_index, false);
+ }
+ else {
+ /* Still flag the batch as dirty even if we're using the default index layout. */
+ batch.tris->flag |= GPU_BATCH_DIRTY;
+ }
+
+ if (lines_index) {
+ GPU_batch_elembuf_set(batch.lines, lines_index, false);
+ }
+ }
+ }
+
+ void check_index_buffers(PBVH_GPU_Args *args)
+ {
+ if (!lines_index) {
+ create_index(args);
+ }
+ }
+
+ void create_batch(PBVHAttrReq *attrs, int attrs_num, PBVH_GPU_Args *args)
+ {
+ check_index_buffers(args);
+
+ PBVHBatch batch;
+
+ batch.tris = GPU_batch_create(GPU_PRIM_TRIS,
+ nullptr,
+ /* can be nullptr if buffer is empty */
+ tri_index);
+ batch.tris_count = tris_count;
+
+ if (lines_index) {
+ batch.lines = GPU_batch_create(GPU_PRIM_LINES, nullptr, lines_index);
+ batch.lines_count = lines_count;
+ }
+
+ for (int i : IndexRange(attrs_num)) {
+ PBVHAttrReq *attr = attrs + i;
+
+ if (!has_vbo(attr->domain, int(attr->type), attr->name)) {
+ create_vbo(attr->domain, uint32_t(attr->type), attr->name, args);
+ }
+
+ PBVHVbo *vbo = get_vbo(attr->domain, uint32_t(attr->type), attr->name);
+ int vbo_i = get_vbo_index(vbo);
+
+ batch.vbos.append(vbo_i);
+ GPU_batch_vertbuf_add_ex(batch.tris, vbo->vert_buf, false);
+
+ if (batch.lines) {
+ GPU_batch_vertbuf_add_ex(batch.lines, vbo->vert_buf, false);
+ }
+ }
+
+ batch.build_key(vbos);
+ batches.add(batch.key, batch);
+ }
+};
+
+void DRW_pbvh_node_update(PBVHBatches *batches, PBVH_GPU_Args *args)
+{
+ batches->update(args);
+}
+
+void DRW_pbvh_node_gpu_flush(PBVHBatches *batches)
+{
+ batches->gpu_flush();
+}
+
+PBVHBatches *DRW_pbvh_node_create(PBVH_GPU_Args *args)
+{
+ PBVHBatches *batches = new PBVHBatches(args);
+ return batches;
+}
+
+void DRW_pbvh_node_free(PBVHBatches *batches)
+{
+ delete batches;
+}
+
+GPUBatch *DRW_pbvh_tris_get(PBVHBatches *batches,
+ PBVHAttrReq *attrs,
+ int attrs_num,
+ PBVH_GPU_Args *args,
+ int *r_prim_count)
+{
+ PBVHBatch &batch = batches->ensure_batch(attrs, attrs_num, args);
+
+ *r_prim_count = batch.tris_count;
+
+ return batch.tris;
+}
+
+GPUBatch *DRW_pbvh_lines_get(PBVHBatches *batches,
+ PBVHAttrReq *attrs,
+ int attrs_num,
+ PBVH_GPU_Args *args,
+ int *r_prim_count)
+{
+ PBVHBatch &batch = batches->ensure_batch(attrs, attrs_num, args);
+
+ *r_prim_count = batch.lines_count;
+
+ return batch.lines;
+}
+
+void DRW_pbvh_update_pre(struct PBVHBatches *batches, struct PBVH_GPU_Args *args)
+{
+ batches->update_pre(args);
+}
+
+int drw_pbvh_material_index_get(struct PBVHBatches *batches)
+{
+ return batches->material_index;
+}
diff --git a/source/blender/draw/intern/draw_pbvh.h b/source/blender/draw/intern/draw_pbvh.h
new file mode 100644
index 00000000000..9e3401d864f
--- /dev/null
+++ b/source/blender/draw/intern/draw_pbvh.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include "DNA_customdata_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct PBVHBatches;
+
+enum {
+ CD_PBVH_CO_TYPE = CD_NUMTYPES,
+ CD_PBVH_NO_TYPE = CD_NUMTYPES + 1,
+ CD_PBVH_FSET_TYPE = CD_NUMTYPES + 2,
+ CD_PBVH_MASK_TYPE = CD_NUMTYPES + 3
+};
+
+int drw_pbvh_material_index_get(struct PBVHBatches *batches);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/draw/intern/draw_pointcloud.cc b/source/blender/draw/intern/draw_pointcloud.cc
new file mode 100644
index 00000000000..582dc690cee
--- /dev/null
+++ b/source/blender/draw/intern/draw_pointcloud.cc
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2017 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup draw
+ *
+ * \brief Contains procedural GPU hair drawing methods.
+ */
+
+#include "BLI_string_utils.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_customdata_types.h"
+#include "DNA_pointcloud_types.h"
+
+#include "BKE_curves.hh"
+#include "BKE_geometry_set.hh"
+
+#include "GPU_batch.h"
+#include "GPU_capabilities.h"
+#include "GPU_compute.h"
+#include "GPU_material.h"
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+#include "GPU_vertex_buffer.h"
+
+#include "DRW_gpu_wrapper.hh"
+#include "DRW_render.h"
+
+#include "draw_attributes.h"
+#include "draw_cache_impl.h"
+#include "draw_common.h"
+#include "draw_manager.h"
+#include "draw_pointcloud_private.hh"
+
+static GPUVertBuf *g_dummy_vbo = nullptr;
+
+void DRW_pointcloud_init()
+{
+ if (g_dummy_vbo == nullptr) {
+ /* initialize vertex format */
+ GPUVertFormat format = {0};
+ uint dummy_id = GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+
+ g_dummy_vbo = GPU_vertbuf_create_with_format_ex(
+ &format, GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY);
+
+ const float vert[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ GPU_vertbuf_data_alloc(g_dummy_vbo, 1);
+ GPU_vertbuf_attr_fill(g_dummy_vbo, dummy_id, vert);
+ }
+}
+
+DRWShadingGroup *DRW_shgroup_pointcloud_create_sub(Object *object,
+ DRWShadingGroup *shgrp_parent,
+ GPUMaterial *gpu_material)
+{
+ PointCloud &pointcloud = *static_cast<PointCloud *>(object->data);
+
+ DRWShadingGroup *shgrp = DRW_shgroup_create_sub(shgrp_parent);
+
+ /* Fix issue with certain driver not drawing anything if there is no texture bound to
+ * "ac", "au", "u" or "c". */
+ DRW_shgroup_buffer_texture(shgrp, "u", g_dummy_vbo);
+ DRW_shgroup_buffer_texture(shgrp, "au", g_dummy_vbo);
+ DRW_shgroup_buffer_texture(shgrp, "c", g_dummy_vbo);
+ DRW_shgroup_buffer_texture(shgrp, "ac", g_dummy_vbo);
+
+ GPUVertBuf *pos_rad_buf = pointcloud_position_and_radius_get(&pointcloud);
+ DRW_shgroup_buffer_texture(shgrp, "ptcloud_pos_rad_tx", pos_rad_buf);
+
+ if (gpu_material != nullptr) {
+
+ // const DRW_Attributes &attrs = cache->attr_used;
+ // for (int i = 0; i < attrs.num_requests; i++) {
+ // const DRW_AttributeRequest &request = attrs.requests[i];
+
+ // char sampler_name[32];
+ // /* \note reusing curve attribute function. */
+ // drw_curves_get_attribute_sampler_name(request.attribute_name, sampler_name);
+
+ // GPUTexture *attribute_buf = DRW_pointcloud_evaluated_attribute(&pointcloud);
+ // if (!cache->attributes_buf[i]) {
+ // continue;
+ // }
+ // DRW_shgroup_buffer_texture_ref(shgrp, sampler_name, attribute_buf);
+ // }
+
+ /* Only single material supported for now. */
+ GPUBatch **geom = pointcloud_surface_shaded_get(&pointcloud, &gpu_material, 1);
+ DRW_shgroup_call(shgrp, geom[0], object);
+ }
+ else {
+ GPUBatch *geom = pointcloud_surface_get(&pointcloud);
+ DRW_shgroup_call(shgrp, geom, object);
+ }
+ return shgrp;
+}
+
+void DRW_pointcloud_free()
+{
+ GPU_VERTBUF_DISCARD_SAFE(g_dummy_vbo);
+}
diff --git a/source/blender/draw/intern/draw_pointcloud_private.hh b/source/blender/draw/intern/draw_pointcloud_private.hh
new file mode 100644
index 00000000000..9422d7fbc99
--- /dev/null
+++ b/source/blender/draw/intern/draw_pointcloud_private.hh
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2021 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup draw
+ */
+
+#pragma once
+
+struct PointCloud;
+struct GPUBatch;
+struct GPUVertBuf;
+struct GPUMaterial;
+
+GPUVertBuf *pointcloud_position_and_radius_get(PointCloud *pointcloud);
+GPUBatch **pointcloud_surface_shaded_get(PointCloud *pointcloud,
+ GPUMaterial **gpu_materials,
+ int mat_len);
+GPUBatch *pointcloud_surface_get(PointCloud *pointcloud);
diff --git a/source/blender/draw/intern/draw_resource.cc b/source/blender/draw/intern/draw_resource.cc
index 689df4edb31..c1f83c3a5ae 100644
--- a/source/blender/draw/intern/draw_resource.cc
+++ b/source/blender/draw/intern/draw_resource.cc
@@ -19,58 +19,6 @@
* \{ */
/**
- * Extract object attribute from RNA property.
- * Returns true if the attribute was correctly extracted.
- * This function mirrors lookup_property in cycles/blender/blender_object.cpp
- */
-bool ObjectAttribute::id_property_lookup(ID *id, const char *name)
-{
- PointerRNA ptr, id_ptr;
- PropertyRNA *prop;
-
- if (id == nullptr) {
- return false;
- }
-
- RNA_id_pointer_create(id, &id_ptr);
-
- if (!RNA_path_resolve(&id_ptr, name, &ptr, &prop)) {
- return false;
- }
-
- if (prop == nullptr) {
- return false;
- }
-
- PropertyType type = RNA_property_type(prop);
- int array_len = RNA_property_array_length(&ptr, prop);
-
- if (array_len == 0) {
- float value;
-
- if (type == PROP_FLOAT) {
- value = RNA_property_float_get(&ptr, prop);
- }
- else if (type == PROP_INT) {
- value = RNA_property_int_get(&ptr, prop);
- }
- else {
- return false;
- }
-
- *reinterpret_cast<float4 *>(&data_x) = float4(value, value, value, 1.0f);
- return true;
- }
-
- if (type == PROP_FLOAT && array_len <= 4) {
- *reinterpret_cast<float4 *>(&data_x) = float4(0.0f, 0.0f, 0.0f, 1.0f);
- RNA_property_float_get_array(&ptr, prop, &data_x);
- return true;
- }
- return false;
-}
-
-/**
* Go through all possible source of the given object uniform attribute.
* Returns true if the attribute was correctly filled.
* This function mirrors lookup_instance_property in cycles/blender/blender_object.cpp
@@ -81,29 +29,25 @@ bool ObjectAttribute::sync(const blender::draw::ObjectRef &ref, const GPUUniform
/* If requesting instance data, check the parent particle system and object. */
if (attr.use_dupli) {
- if ((ref.dupli_object != nullptr) && (ref.dupli_object->particle_system != nullptr)) {
- ParticleSettings *settings = ref.dupli_object->particle_system->part;
- if (this->id_property_lookup((ID *)settings, attr.name_id_prop) ||
- this->id_property_lookup((ID *)settings, attr.name)) {
- return true;
- }
- }
- if (this->id_property_lookup((ID *)ref.dupli_parent, attr.name_id_prop) ||
- this->id_property_lookup((ID *)ref.dupli_parent, attr.name)) {
- return true;
- }
+ return BKE_object_dupli_find_rgba_attribute(
+ ref.object, ref.dupli_object, ref.dupli_parent, attr.name, &data_x);
}
-
- /* Check the object and mesh. */
- if (ref.object != nullptr) {
- if (this->id_property_lookup((ID *)ref.object, attr.name_id_prop) ||
- this->id_property_lookup((ID *)ref.object, attr.name) ||
- this->id_property_lookup((ID *)ref.object->data, attr.name_id_prop) ||
- this->id_property_lookup((ID *)ref.object->data, attr.name)) {
- return true;
- }
+ else {
+ return BKE_object_dupli_find_rgba_attribute(ref.object, nullptr, nullptr, attr.name, &data_x);
}
- return false;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name LayerAttributes
+ * \{ */
+
+bool LayerAttribute::sync(Scene *scene, ViewLayer *layer, const GPULayerAttr &attr)
+{
+ hash_code = attr.hash_code;
+
+ return BKE_view_layer_find_rgba_attribute(scene, layer, attr.name, &data.x);
}
/** \} */
diff --git a/source/blender/draw/intern/draw_resource.hh b/source/blender/draw/intern/draw_resource.hh
index 2df38e32ed2..b8a0dbb8fa9 100644
--- a/source/blender/draw/intern/draw_resource.hh
+++ b/source/blender/draw/intern/draw_resource.hh
@@ -31,8 +31,8 @@
inline void ObjectMatrices::sync(const Object &object)
{
- model = object.obmat;
- model_inverse = object.imat;
+ model = object.object_to_world;
+ model_inverse = object.world_to_object;
}
inline void ObjectMatrices::sync(const float4x4 &model_matrix)
diff --git a/source/blender/draw/intern/draw_shader.cc b/source/blender/draw/intern/draw_shader.cc
index 960348b4a94..dc08fa76335 100644
--- a/source/blender/draw/intern/draw_shader.cc
+++ b/source/blender/draw/intern/draw_shader.cc
@@ -32,13 +32,12 @@ static struct {
/** \name Hair refinement
* \{ */
-static GPUShader *hair_refine_shader_compute_create(ParticleRefineShader UNUSED(refinement))
+static GPUShader *hair_refine_shader_compute_create(ParticleRefineShader /*refinement*/)
{
return GPU_shader_create_from_info_name("draw_hair_refine_compute");
}
-static GPUShader *hair_refine_shader_transform_feedback_create(
- ParticleRefineShader UNUSED(refinement))
+static GPUShader *hair_refine_shader_transform_feedback_create(ParticleRefineShader /*refinement*/)
{
GPUShader *sh = nullptr;
@@ -58,7 +57,7 @@ static GPUShader *hair_refine_shader_transform_feedback_create(
}
static GPUShader *hair_refine_shader_transform_feedback_workaround_create(
- ParticleRefineShader UNUSED(refinement))
+ ParticleRefineShader /*refinement*/)
{
return GPU_shader_create_from_info_name("draw_hair_refine_transform_feedback_workaround");
}
diff --git a/source/blender/draw/intern/draw_shader_shared.h b/source/blender/draw/intern/draw_shader_shared.h
index bedbedcf438..75a7e28fa75 100644
--- a/source/blender/draw/intern/draw_shader_shared.h
+++ b/source/blender/draw/intern/draw_shader_shared.h
@@ -7,13 +7,15 @@
# include "GPU_shader_shared_utils.h"
# include "draw_defines.h"
-typedef struct ViewInfos ViewInfos;
+typedef struct ViewCullingData ViewCullingData;
+typedef struct ViewMatrices ViewMatrices;
typedef struct ObjectMatrices ObjectMatrices;
typedef struct ObjectInfos ObjectInfos;
typedef struct ObjectBounds ObjectBounds;
typedef struct VolumeInfos VolumeInfos;
typedef struct CurvesInfos CurvesInfos;
typedef struct ObjectAttribute ObjectAttribute;
+typedef struct LayerAttribute LayerAttribute;
typedef struct DrawCommand DrawCommand;
typedef struct DispatchCommand DispatchCommand;
typedef struct DRWDebugPrintBuffer DRWDebugPrintBuffer;
@@ -23,8 +25,10 @@ typedef struct DRWDebugDrawBuffer DRWDebugDrawBuffer;
# ifdef __cplusplus
/* C++ only forward declarations. */
struct Object;
+struct ViewLayer;
struct ID;
struct GPUUniformAttr;
+struct GPULayerAttr;
namespace blender::draw {
@@ -50,51 +54,30 @@ typedef enum eObjectInfoFlag eObjectInfoFlag;
* This should be kept in sync with `GPU_ATTR_MAX` */
#define DRW_ATTRIBUTE_PER_CURVES_MAX 15
-struct ViewInfos {
- /* View matrices */
- float4x4 persmat;
- float4x4 persinv;
+struct ViewCullingData {
+ /** \note vec3 array padded to vec4. */
+ /** Frustum corners. */
+ float4 corners[8];
+ float4 planes[6];
+ float4 bound_sphere;
+};
+BLI_STATIC_ASSERT_ALIGN(ViewCullingData, 16)
+
+struct ViewMatrices {
float4x4 viewmat;
float4x4 viewinv;
float4x4 winmat;
float4x4 wininv;
-
- float4 clip_planes[6];
- float4 viewvecs[2];
- /* Should not be here. Not view dependent (only main view). */
- float4 viewcamtexcofac;
-
- float2 viewport_size;
- float2 viewport_size_inverse;
-
- /** Frustum culling data. */
- /** \note vec3 array padded to vec4. */
- float4 frustum_corners[8];
- float4 frustum_planes[6];
- float4 frustum_bound_sphere;
-
- /** For debugging purpose */
- /* Mouse pixel. */
- int2 mouse_pixel;
-
- /** True if facing needs to be inverted. */
- bool1 is_inverted;
- int _pad0;
};
-BLI_STATIC_ASSERT_ALIGN(ViewInfos, 16)
+BLI_STATIC_ASSERT_ALIGN(ViewMatrices, 16)
/* Do not override old definitions if the shader uses this header but not shader info. */
#ifdef USE_GPU_SHADER_CREATE_INFO
/* TODO(@fclem): Mass rename. */
-# define ViewProjectionMatrix drw_view.persmat
-# define ViewProjectionMatrixInverse drw_view.persinv
# define ViewMatrix drw_view.viewmat
# define ViewMatrixInverse drw_view.viewinv
# define ProjectionMatrix drw_view.winmat
# define ProjectionMatrixInverse drw_view.wininv
-# define clipPlanes drw_view.clip_planes
-# define ViewVecs drw_view.viewvecs
-# define CameraTexCoFactors drw_view.viewcamtexcofac
#endif
/** \} */
@@ -205,7 +188,6 @@ struct ObjectAttribute {
#if !defined(GPU_SHADER) && defined(__cplusplus)
bool sync(const blender::draw::ObjectRef &ref, const GPUUniformAttr &attr);
- bool id_property_lookup(ID *id, const char *name);
#endif
};
#pragma pack(pop)
@@ -213,6 +195,20 @@ struct ObjectAttribute {
* C++ compiler gives us the same size. */
BLI_STATIC_ASSERT_ALIGN(ObjectAttribute, 20)
+#pragma pack(push, 4)
+struct LayerAttribute {
+ float4 data;
+ uint hash_code;
+ uint buffer_length; /* Only in the first record. */
+ uint _pad1, _pad2;
+
+#if !defined(GPU_SHADER) && defined(__cplusplus)
+ bool sync(Scene *scene, ViewLayer *layer, const GPULayerAttr &attr);
+#endif
+};
+#pragma pack(pop)
+BLI_STATIC_ASSERT_ALIGN(LayerAttribute, 32)
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/draw/intern/draw_view.cc b/source/blender/draw/intern/draw_view.cc
index cb0e1370c28..cf86558f80f 100644
--- a/source/blender/draw/intern/draw_view.cc
+++ b/source/blender/draw/intern/draw_view.cc
@@ -21,17 +21,11 @@ void View::sync(const float4x4 &view_mat, const float4x4 &win_mat)
data_.viewinv = view_mat.inverted();
data_.winmat = win_mat;
data_.wininv = win_mat.inverted();
- data_.persmat = data_.winmat * data_.viewmat;
- data_.persinv = data_.persmat.inverted();
- /* Should not be used anymore. */
- data_.viewcamtexcofac = float4(1.0f, 1.0f, 0.0f, 0.0f);
- data_.is_inverted = (is_negative_m4(view_mat.ptr()) == is_negative_m4(win_mat.ptr()));
+ is_inverted_ = (is_negative_m4(view_mat.ptr()) == is_negative_m4(win_mat.ptr()));
- update_view_vectors();
-
- BoundBox &bound_box = *reinterpret_cast<BoundBox *>(&data_.frustum_corners);
- BoundSphere &bound_sphere = *reinterpret_cast<BoundSphere *>(&data_.frustum_bound_sphere);
+ BoundBox &bound_box = *reinterpret_cast<BoundBox *>(&culling_.corners);
+ BoundSphere &bound_sphere = *reinterpret_cast<BoundSphere *>(&culling_.bound_sphere);
frustum_boundbox_calc(bound_box);
frustum_culling_planes_calc();
frustum_culling_sphere_calc(bound_box, bound_sphere);
@@ -83,17 +77,18 @@ void View::frustum_boundbox_calc(BoundBox &bbox)
void View::frustum_culling_planes_calc()
{
- planes_from_projmat(data_.persmat.ptr(),
- data_.frustum_planes[0],
- data_.frustum_planes[5],
- data_.frustum_planes[1],
- data_.frustum_planes[3],
- data_.frustum_planes[4],
- data_.frustum_planes[2]);
+ float4x4 persmat = data_.winmat * data_.viewmat;
+ planes_from_projmat(persmat.ptr(),
+ culling_.planes[0],
+ culling_.planes[5],
+ culling_.planes[1],
+ culling_.planes[3],
+ culling_.planes[4],
+ culling_.planes[2]);
/* Normalize. */
for (int p = 0; p < 6; p++) {
- data_.frustum_planes[p].w /= normalize_v3(data_.frustum_planes[p]);
+ culling_.planes[p].w /= normalize_v3(culling_.planes[p]);
}
}
@@ -208,97 +203,30 @@ void View::frustum_culling_sphere_calc(const BoundBox &bbox, BoundSphere &bspher
}
}
-void View::set_clip_planes(Span<float4> planes)
-{
- BLI_assert(planes.size() <= ARRAY_SIZE(data_.clip_planes));
- int i = 0;
- for (const auto &plane : planes) {
- data_.clip_planes[i++] = plane;
- }
-}
-
-void View::update_viewport_size()
-{
- float4 viewport;
- GPU_viewport_size_get_f(viewport);
- float2 viewport_size = float2(viewport.z, viewport.w);
- if (assign_if_different(data_.viewport_size, viewport_size)) {
- dirty_ = true;
- }
-}
-
-void View::update_view_vectors()
-{
- bool is_persp = data_.winmat[3][3] == 0.0f;
-
- /* Near clip distance. */
- data_.viewvecs[0][3] = (is_persp) ? -data_.winmat[3][2] / (data_.winmat[2][2] - 1.0f) :
- -(data_.winmat[3][2] + 1.0f) / data_.winmat[2][2];
-
- /* Far clip distance. */
- data_.viewvecs[1][3] = (is_persp) ? -data_.winmat[3][2] / (data_.winmat[2][2] + 1.0f) :
- -(data_.winmat[3][2] - 1.0f) / data_.winmat[2][2];
-
- /* View vectors for the corners of the view frustum.
- * Can be used to recreate the world space position easily */
- float3 view_vecs[4] = {
- {-1.0f, -1.0f, -1.0f},
- {1.0f, -1.0f, -1.0f},
- {-1.0f, 1.0f, -1.0f},
- {-1.0f, -1.0f, 1.0f},
- };
-
- /* Convert the view vectors to view space */
- for (int i = 0; i < 4; i++) {
- mul_project_m4_v3(data_.wininv.ptr(), view_vecs[i]);
- /* Normalized trick see:
- * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
- if (is_persp) {
- view_vecs[i].x /= view_vecs[i].z;
- view_vecs[i].y /= view_vecs[i].z;
- }
- }
-
- /**
- * - If orthographic:
- * `view_vecs[0]` is the near-bottom-left corner of the frustum and
- * `view_vecs[1]` is the vector going from the near-bottom-left corner to
- * the far-top-right corner.
- * - If perspective:
- * `view_vecs[0].xy` and `view_vecs[1].xy` are respectively the bottom-left corner
- * when `Z = 1`, and top-left corner if `Z = 1`.
- * `view_vecs[0].z` the near clip distance and `view_vecs[1].z` is the (signed)
- * distance from the near plane to the far clip plane.
- */
- copy_v3_v3(data_.viewvecs[0], view_vecs[0]);
-
- /* we need to store the differences */
- data_.viewvecs[1][0] = view_vecs[1][0] - view_vecs[0][0];
- data_.viewvecs[1][1] = view_vecs[2][1] - view_vecs[0][1];
- data_.viewvecs[1][2] = view_vecs[3][2] - view_vecs[0][2];
-}
-
void View::bind()
{
- update_viewport_size();
-
if (dirty_) {
dirty_ = false;
data_.push_update();
+ culling_.push_update();
}
GPU_uniformbuf_bind(data_, DRW_VIEW_UBO_SLOT);
+ GPU_uniformbuf_bind(culling_, DRW_VIEW_CULLING_UBO_SLOT);
}
void View::compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool debug_freeze)
{
if (debug_freeze && frozen_ == false) {
- data_freeze_ = static_cast<ViewInfos>(data_);
+ data_freeze_ = static_cast<ViewMatrices>(data_);
data_freeze_.push_update();
+ culling_freeze_ = static_cast<ViewCullingData>(culling_);
+ culling_freeze_.push_update();
}
#ifdef DEBUG
if (debug_freeze) {
- drw_debug_matrix_as_bbox(data_freeze_.persinv, float4(0, 1, 0, 1));
+ float4x4 persmat = data_freeze_.winmat * data_freeze_.viewmat;
+ drw_debug_matrix_as_bbox(persmat.inverted(), float4(0, 1, 0, 1));
}
#endif
frozen_ = debug_freeze;
diff --git a/source/blender/draw/intern/draw_view.hh b/source/blender/draw/intern/draw_view.hh
index 27e7a7a0028..94fb62508bb 100644
--- a/source/blender/draw/intern/draw_view.hh
+++ b/source/blender/draw/intern/draw_view.hh
@@ -25,14 +25,17 @@ class View {
friend Manager;
private:
- UniformBuffer<ViewInfos> data_;
+ UniformBuffer<ViewMatrices> data_;
+ UniformBuffer<ViewCullingData> culling_;
/** Frozen version of data_ used for debugging culling. */
- UniformBuffer<ViewInfos> data_freeze_;
+ UniformBuffer<ViewMatrices> data_freeze_;
+ UniformBuffer<ViewCullingData> culling_freeze_;
/** Result of the visibility computation. 1 bit per resource ID. */
VisibilityBuf visibility_buf_;
const char *debug_name_;
+ bool is_inverted_ = false;
bool do_visibility_ = true;
bool dirty_ = true;
bool frozen_ = false;
@@ -48,8 +51,6 @@ class View {
this->sync(view_mat, win_mat);
}
- void set_clip_planes(Span<float4> planes);
-
void sync(const float4x4 &view_mat, const float4x4 &win_mat);
bool is_persp() const
@@ -59,7 +60,7 @@ class View {
bool is_inverted() const
{
- return data_.is_inverted;
+ return is_inverted_;
}
float far_clip() const
@@ -78,12 +79,31 @@ class View {
return -(data_.winmat[3][2] + 1.0f) / data_.winmat[2][2];
}
+ const float4x4 &viewmat() const
+ {
+ return data_.viewmat;
+ }
+
+ const float4x4 &viewinv() const
+ {
+ return data_.viewinv;
+ }
+
+ const float4x4 &winmat() const
+ {
+ return data_.winmat;
+ }
+
+ const float4x4 &wininv() const
+ {
+ return data_.wininv;
+ }
+
private:
/** Called from draw manager. */
void bind();
void compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool debug_freeze);
- void update_view_vectors();
void update_viewport_size();
void frustum_boundbox_calc(BoundBox &bbox);
diff --git a/source/blender/draw/intern/draw_volume.cc b/source/blender/draw/intern/draw_volume.cc
index 8f4383a98d8..5c1ce7c3111 100644
--- a/source/blender/draw/intern/draw_volume.cc
+++ b/source/blender/draw/intern/draw_volume.cc
@@ -127,7 +127,7 @@ static DRWShadingGroup *drw_volume_object_grids_init(Object *ob,
grp = DRW_shgroup_create_sub(grp);
- volume_infos.density_scale = BKE_volume_density_scale(volume, ob->obmat);
+ volume_infos.density_scale = BKE_volume_density_scale(volume, ob->object_to_world);
volume_infos.color_mul = float4(1.0f);
volume_infos.temperature_mul = 1.0f;
volume_infos.temperature_bias = 0.0f;
@@ -184,7 +184,7 @@ static DRWShadingGroup *drw_volume_object_mesh_init(Scene *scene,
/* Smoke Simulation */
if ((md = BKE_modifiers_findby_type(ob, eModifierType_Fluid)) &&
- (BKE_modifier_is_enabled(scene, md, eModifierMode_Realtime)) &&
+ BKE_modifier_is_enabled(scene, md, eModifierMode_Realtime) &&
((FluidModifierData *)md)->domain != nullptr) {
FluidModifierData *fmd = (FluidModifierData *)md;
FluidDomainSettings *fds = fmd->domain;
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh
index 10b94291e35..c6230e2695e 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh
@@ -16,6 +16,8 @@
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
+#include "BKE_editmesh_cache.h"
+#include "BKE_mesh.h"
#include "draw_cache_extract.hh"
@@ -78,14 +80,17 @@ struct MeshRenderData {
BMEdge *eed_act;
BMFace *efa_act;
BMFace *efa_act_uv;
- /* Data created on-demand (usually not for #BMesh based data). */
- MLoopTri *mlooptri;
+ /* The triangulation of #Mesh polygons, owned by the mesh. */
+ const MLoopTri *mlooptri;
const int *material_indices;
const float (*vert_normals)[3];
const float (*poly_normals)[3];
const bool *hide_vert;
const bool *hide_edge;
const bool *hide_poly;
+ const bool *select_vert;
+ const bool *select_edge;
+ const bool *select_poly;
float (*loop_normals)[3];
int *lverts, *ledges;
@@ -113,7 +118,7 @@ BLI_INLINE const Mesh *editmesh_final_or_this(const Object *object, const Mesh *
BLI_INLINE const CustomData *mesh_cd_ldata_get_from_mesh(const Mesh *me)
{
- switch ((eMeshWrapperType)me->runtime.wrapper_type) {
+ switch (me->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_SUBD:
case ME_WRAPPER_TYPE_MDATA:
return &me->ldata;
@@ -129,7 +134,7 @@ BLI_INLINE const CustomData *mesh_cd_ldata_get_from_mesh(const Mesh *me)
BLI_INLINE const CustomData *mesh_cd_pdata_get_from_mesh(const Mesh *me)
{
- switch ((eMeshWrapperType)me->runtime.wrapper_type) {
+ switch (me->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_SUBD:
case ME_WRAPPER_TYPE_MDATA:
return &me->pdata;
@@ -145,7 +150,7 @@ BLI_INLINE const CustomData *mesh_cd_pdata_get_from_mesh(const Mesh *me)
BLI_INLINE const CustomData *mesh_cd_edata_get_from_mesh(const Mesh *me)
{
- switch ((eMeshWrapperType)me->runtime.wrapper_type) {
+ switch (me->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_SUBD:
case ME_WRAPPER_TYPE_MDATA:
return &me->edata;
@@ -161,7 +166,7 @@ BLI_INLINE const CustomData *mesh_cd_edata_get_from_mesh(const Mesh *me)
BLI_INLINE const CustomData *mesh_cd_vdata_get_from_mesh(const Mesh *me)
{
- switch ((eMeshWrapperType)me->runtime.wrapper_type) {
+ switch (me->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_SUBD:
case ME_WRAPPER_TYPE_MDATA:
return &me->vdata;
@@ -437,3 +442,4 @@ extern const MeshExtract extract_edge_idx;
extern const MeshExtract extract_vert_idx;
extern const MeshExtract extract_fdot_idx;
extern const MeshExtract extract_attr[GPU_MAX_ATTR];
+extern const MeshExtract extract_attr_viewer;
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc
index 2f2e59c8c3b..e40503a9707 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc
@@ -22,8 +22,8 @@ struct MeshExtract_EditUvElem_Data {
};
static void extract_edituv_tris_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(ibo),
+ MeshBatchCache * /*cache*/,
+ void * /*ibo*/,
void *tls_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(tls_data);
@@ -39,9 +39,9 @@ BLI_INLINE void edituv_tri_add(
}
}
-static void extract_edituv_tris_iter_looptri_bm(const MeshRenderData *UNUSED(mr),
+static void extract_edituv_tris_iter_looptri_bm(const MeshRenderData * /*mr*/,
BMLoop **elt,
- const int UNUSED(elt_index),
+ const int /*elt_index*/,
void *_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
@@ -55,7 +55,7 @@ static void extract_edituv_tris_iter_looptri_bm(const MeshRenderData *UNUSED(mr)
static void extract_edituv_tris_iter_looptri_mesh(const MeshRenderData *mr,
const MLoopTri *mlt,
- const int UNUSED(elt_index),
+ const int /*elt_index*/,
void *_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
@@ -66,8 +66,8 @@ static void extract_edituv_tris_iter_looptri_mesh(const MeshRenderData *mr,
edituv_tri_add(data, mp_hidden, mp_select, mlt->tri[0], mlt->tri[1], mlt->tri[2]);
}
-static void extract_edituv_tris_finish(const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
+static void extract_edituv_tris_finish(const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
void *buf,
void *_data)
{
@@ -78,8 +78,8 @@ static void extract_edituv_tris_finish(const MeshRenderData *UNUSED(mr),
static void extract_edituv_tris_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf),
+ MeshBatchCache * /*cache*/,
+ void * /*buf*/,
void *tls_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(tls_data);
@@ -90,8 +90,8 @@ static void extract_edituv_tris_init_subdiv(const DRWSubdivCache *subdiv_cache,
data->sync_selection = (mr->toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
}
-static void extract_edituv_tris_iter_subdiv_bm(const DRWSubdivCache *UNUSED(subdiv_cache),
- const MeshRenderData *UNUSED(mr),
+static void extract_edituv_tris_iter_subdiv_bm(const DRWSubdivCache * /*subdiv_cache*/,
+ const MeshRenderData * /*mr*/,
void *_data,
uint subdiv_quad_index,
const BMFace *coarse_quad)
@@ -114,7 +114,7 @@ static void extract_edituv_tris_iter_subdiv_bm(const DRWSubdivCache *UNUSED(subd
loop_idx + 3);
}
-static void extract_edituv_tris_iter_subdiv_mesh(const DRWSubdivCache *UNUSED(subdiv_cache),
+static void extract_edituv_tris_iter_subdiv_mesh(const DRWSubdivCache * /*subdiv_cache*/,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
@@ -131,9 +131,9 @@ static void extract_edituv_tris_iter_subdiv_mesh(const DRWSubdivCache *UNUSED(su
edituv_tri_add(data, mp_hidden, mp_select, loop_idx, loop_idx + 2, loop_idx + 3);
}
-static void extract_edituv_tris_finish_subdiv(const struct DRWSubdivCache *UNUSED(subdiv_cache),
- const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
+static void extract_edituv_tris_finish_subdiv(const struct DRWSubdivCache * /*subdiv_cache*/,
+ const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
void *buf,
void *_data)
{
@@ -167,8 +167,8 @@ constexpr MeshExtract create_extractor_edituv_tris()
* \{ */
static void extract_edituv_lines_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(ibo),
+ MeshBatchCache * /*cache*/,
+ void * /*ibo*/,
void *tls_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(tls_data);
@@ -184,9 +184,9 @@ BLI_INLINE void edituv_edge_add(
}
}
-static void extract_edituv_lines_iter_poly_bm(const MeshRenderData *UNUSED(mr),
+static void extract_edituv_lines_iter_poly_bm(const MeshRenderData * /*mr*/,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
@@ -220,7 +220,7 @@ static void extract_edituv_lines_iter_poly_mesh(const MeshRenderData *mr,
}
else {
mp_hidden = (mr->hide_poly) ? mr->hide_poly[mp_index] : false;
- mp_select = (mp->flag & ME_FACE_SEL) != 0;
+ mp_select = mr->select_poly && mr->select_poly[mp_index];
}
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
@@ -234,8 +234,8 @@ static void extract_edituv_lines_iter_poly_mesh(const MeshRenderData *mr,
}
}
-static void extract_edituv_lines_finish(const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
+static void extract_edituv_lines_finish(const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
void *buf,
void *_data)
{
@@ -246,8 +246,8 @@ static void extract_edituv_lines_finish(const MeshRenderData *UNUSED(mr),
static void extract_edituv_lines_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf),
+ MeshBatchCache * /*cache*/,
+ void * /*buf*/,
void *tls_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(tls_data);
@@ -291,16 +291,16 @@ static void extract_edituv_lines_iter_subdiv_mesh(const DRWSubdivCache *subdiv_c
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
int *subdiv_loop_edge_index = (int *)GPU_vertbuf_get_data(subdiv_cache->edges_orig_index);
-
+ const int coarse_poly_index = coarse_poly - mr->mpoly;
bool mp_hidden, mp_select;
if (mr->bm) {
- const BMFace *efa = bm_original_face_get(mr, coarse_poly - mr->mpoly);
+ const BMFace *efa = bm_original_face_get(mr, coarse_poly_index);
mp_hidden = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_HIDDEN) : true;
mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false;
}
else {
- mp_hidden = (mr->hide_poly) ? mr->hide_poly[coarse_poly - mr->mpoly] : false;
- mp_select = (coarse_poly->flag & ME_FACE_SEL) != 0;
+ mp_hidden = (mr->hide_poly) ? mr->hide_poly[coarse_poly_index] : false;
+ mp_select = mr->select_poly && mr->select_poly[coarse_poly_index];
}
uint start_loop_idx = subdiv_quad_index * 4;
@@ -318,9 +318,9 @@ static void extract_edituv_lines_iter_subdiv_mesh(const DRWSubdivCache *subdiv_c
}
}
-static void extract_edituv_lines_finish_subdiv(const struct DRWSubdivCache *UNUSED(subdiv_cache),
- const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
+static void extract_edituv_lines_finish_subdiv(const struct DRWSubdivCache * /*subdiv_cache*/,
+ const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
void *buf,
void *_data)
{
@@ -354,8 +354,8 @@ constexpr MeshExtract create_extractor_edituv_lines()
* \{ */
static void extract_edituv_points_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(ibo),
+ MeshBatchCache * /*cache*/,
+ void * /*ibo*/,
void *tls_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(tls_data);
@@ -373,9 +373,9 @@ BLI_INLINE void edituv_point_add(MeshExtract_EditUvElem_Data *data,
}
}
-static void extract_edituv_points_iter_poly_bm(const MeshRenderData *UNUSED(mr),
+static void extract_edituv_points_iter_poly_bm(const MeshRenderData * /*mr*/,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
@@ -410,8 +410,8 @@ static void extract_edituv_points_iter_poly_mesh(const MeshRenderData *mr,
}
}
-static void extract_edituv_points_finish(const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
+static void extract_edituv_points_finish(const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
void *buf,
void *_data)
{
@@ -422,8 +422,8 @@ static void extract_edituv_points_finish(const MeshRenderData *UNUSED(mr),
static void extract_edituv_points_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf),
+ MeshBatchCache * /*cache*/,
+ void * /*buf*/,
void *tls_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(tls_data);
@@ -433,7 +433,7 @@ static void extract_edituv_points_init_subdiv(const DRWSubdivCache *subdiv_cache
}
static void extract_edituv_points_iter_subdiv_bm(const DRWSubdivCache *subdiv_cache,
- const MeshRenderData *UNUSED(mr),
+ const MeshRenderData * /*mr*/,
void *_data,
uint subdiv_quad_index,
const BMFace *coarse_quad)
@@ -475,9 +475,9 @@ static void extract_edituv_points_iter_subdiv_mesh(const DRWSubdivCache *subdiv_
}
}
-static void extract_edituv_points_finish_subdiv(const struct DRWSubdivCache *UNUSED(subdiv_cache),
- const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
+static void extract_edituv_points_finish_subdiv(const struct DRWSubdivCache * /*subdiv_cache*/,
+ const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
void *buf,
void *_data)
{
@@ -511,8 +511,8 @@ constexpr MeshExtract create_extractor_edituv_points()
* \{ */
static void extract_edituv_fdots_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(ibo),
+ MeshBatchCache * /*cache*/,
+ void * /*ibo*/,
void *tls_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(tls_data);
@@ -533,7 +533,7 @@ BLI_INLINE void edituv_facedot_add(MeshExtract_EditUvElem_Data *data,
}
}
-static void extract_edituv_fdots_iter_poly_bm(const MeshRenderData *UNUSED(mr),
+static void extract_edituv_fdots_iter_poly_bm(const MeshRenderData * /*mr*/,
const BMFace *f,
const int f_index,
void *_data)
@@ -557,7 +557,7 @@ static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr,
const bool mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false;
if (mr->use_subsurf_fdots) {
- const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags;
+ const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags;
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
@@ -575,8 +575,8 @@ static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr,
}
}
-static void extract_edituv_fdots_finish(const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
+static void extract_edituv_fdots_finish(const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
void *buf,
void *_data)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc
index 8dc00617039..1b552b01d6b 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc
@@ -15,15 +15,15 @@ namespace blender::draw {
* \{ */
static void extract_fdots_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf),
+ MeshBatchCache * /*cache*/,
+ void * /*buf*/,
void *tls_data)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(tls_data);
GPU_indexbuf_init(elb, GPU_PRIM_POINTS, mr->poly_len, mr->poly_len);
}
-static void extract_fdots_iter_poly_bm(const MeshRenderData *UNUSED(mr),
+static void extract_fdots_iter_poly_bm(const MeshRenderData * /*mr*/,
const BMFace *f,
const int f_index,
void *_userdata)
@@ -46,7 +46,7 @@ static void extract_fdots_iter_poly_mesh(const MeshRenderData *mr,
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
if (mr->use_subsurf_fdots) {
- const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags;
+ const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags;
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
@@ -69,8 +69,8 @@ static void extract_fdots_iter_poly_mesh(const MeshRenderData *mr,
}
}
-static void extract_fdots_finish(const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
+static void extract_fdots_finish(const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
void *buf,
void *_userdata)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc
index 9c564c2cdda..56e8baaca22 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc
@@ -18,8 +18,8 @@ namespace blender::draw {
* \{ */
static void extract_lines_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf),
+ MeshBatchCache * /*cache*/,
+ void * /*buf*/,
void *tls_data)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(tls_data);
@@ -28,9 +28,9 @@ static void extract_lines_init(const MeshRenderData *mr,
elb, GPU_PRIM_LINES, mr->edge_len + mr->edge_loose_len, mr->loop_len + mr->loop_loose_len);
}
-static void extract_lines_iter_poly_bm(const MeshRenderData *UNUSED(mr),
+static void extract_lines_iter_poly_bm(const MeshRenderData * /*mr*/,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *data)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(data);
@@ -52,7 +52,7 @@ static void extract_lines_iter_poly_bm(const MeshRenderData *UNUSED(mr),
static void extract_lines_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *mp,
- const int UNUSED(mp_index),
+ const int /*mp_index*/,
void *data)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(data);
@@ -127,8 +127,8 @@ static void extract_lines_task_reduce(void *_userdata_to, void *_userdata_from)
GPU_indexbuf_join(elb_to, elb_from);
}
-static void extract_lines_finish(const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
+static void extract_lines_finish(const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
void *buf,
void *data)
{
@@ -138,10 +138,10 @@ static void extract_lines_finish(const MeshRenderData *UNUSED(mr),
}
static void extract_lines_init_subdiv(const DRWSubdivCache *subdiv_cache,
- const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
+ const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
void *buffer,
- void *UNUSED(data))
+ void * /*data*/)
{
const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buffer);
@@ -158,7 +158,7 @@ static void extract_lines_init_subdiv(const DRWSubdivCache *subdiv_cache,
static void extract_lines_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *buffer,
- void *UNUSED(data))
+ void * /*data*/)
{
const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
if (loose_geom.edge_len == 0) {
@@ -231,8 +231,7 @@ static void extract_lines_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
}
GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buffer);
- draw_subdiv_build_lines_loose_buffer(
- subdiv_cache, ibo, flags, static_cast<uint>(loose_geom.edge_len));
+ draw_subdiv_build_lines_loose_buffer(subdiv_cache, ibo, flags, uint(loose_geom.edge_len));
GPU_vertbuf_discard(flags);
}
@@ -285,10 +284,10 @@ static void extract_lines_with_lines_loose_finish(const MeshRenderData *mr,
}
static void extract_lines_with_lines_loose_finish_subdiv(const struct DRWSubdivCache *subdiv_cache,
- const MeshRenderData *UNUSED(mr),
+ const MeshRenderData * /*mr*/,
MeshBatchCache *cache,
- void *UNUSED(buf),
- void *UNUSED(_data))
+ void * /*buf*/,
+ void * /*_data*/)
{
/* Multiply by 2 because these are edges indices. */
const int start = subdiv_cache->num_subdiv_loops * 2;
@@ -327,18 +326,18 @@ constexpr MeshExtract create_extractor_lines_with_lines_loose()
static void extract_lines_loose_only_init(const MeshRenderData *mr,
MeshBatchCache *cache,
void *buf,
- void *UNUSED(tls_data))
+ void * /*tls_data*/)
{
BLI_assert(buf == cache->final.buff.ibo.lines_loose);
UNUSED_VARS_NDEBUG(buf);
extract_lines_loose_subbuffer(mr, cache);
}
-static void extract_lines_loose_only_init_subdiv(const DRWSubdivCache *UNUSED(subdiv_cache),
+static void extract_lines_loose_only_init_subdiv(const DRWSubdivCache * /*subdiv_cache*/,
const MeshRenderData *mr,
MeshBatchCache *cache,
void *buffer,
- void *UNUSED(data))
+ void * /*data*/)
{
BLI_assert(buffer == cache->final.buff.ibo.lines_loose);
UNUSED_VARS_NDEBUG(buffer);
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc
index d6c246c51a9..3124a35608d 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc
@@ -42,8 +42,8 @@ static void line_adjacency_data_init(MeshExtract_LineAdjacency_Data *data,
}
static void extract_lines_adjacency_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf),
+ MeshBatchCache * /*cache*/,
+ void * /*buf*/,
void *tls_data)
{
/* Similar to poly_to_tri_count().
@@ -71,7 +71,7 @@ BLI_INLINE void lines_adjacency_triangle(
if (!value_is_init || v_data == NO_EDGE) {
/* Save the winding order inside the sign bit. Because the
* Edge-hash sort the keys and we need to compare winding later. */
- int value = (int)l1 + 1; /* 0 cannot be signed so add one. */
+ int value = int(l1) + 1; /* 0 cannot be signed so add one. */
*pval = POINTER_FROM_INT((inv_indices) ? -value : value);
/* Store loop indices for remaining non-manifold edges. */
data->vert_to_loop[v2] = l2;
@@ -81,7 +81,7 @@ BLI_INLINE void lines_adjacency_triangle(
/* HACK Tag as not used. Prevent overhead of BLI_edgehash_remove. */
*pval = POINTER_FROM_INT(NO_EDGE);
bool inv_opposite = (v_data < 0);
- uint l_opposite = (uint)abs(v_data) - 1;
+ uint l_opposite = uint(abs(v_data)) - 1;
/* TODO: Make this part thread-safe. */
if (inv_opposite == inv_indices) {
/* Don't share edge if triangles have non matching winding. */
@@ -96,9 +96,9 @@ BLI_INLINE void lines_adjacency_triangle(
}
}
-static void extract_lines_adjacency_iter_looptri_bm(const MeshRenderData *UNUSED(mr),
+static void extract_lines_adjacency_iter_looptri_bm(const MeshRenderData * /*mr*/,
BMLoop **elt,
- const int UNUSED(elt_index),
+ const int /*elt_index*/,
void *_data)
{
MeshExtract_LineAdjacency_Data *data = static_cast<MeshExtract_LineAdjacency_Data *>(_data);
@@ -115,7 +115,7 @@ static void extract_lines_adjacency_iter_looptri_bm(const MeshRenderData *UNUSED
static void extract_lines_adjacency_iter_looptri_mesh(const MeshRenderData *mr,
const MLoopTri *mlt,
- const int UNUSED(elt_index),
+ const int /*elt_index*/,
void *_data)
{
MeshExtract_LineAdjacency_Data *data = static_cast<MeshExtract_LineAdjacency_Data *>(_data);
@@ -132,7 +132,7 @@ static void extract_lines_adjacency_iter_looptri_mesh(const MeshRenderData *mr,
data);
}
-static void extract_lines_adjacency_finish(const MeshRenderData *UNUSED(mr),
+static void extract_lines_adjacency_finish(const MeshRenderData * /*mr*/,
MeshBatchCache *cache,
void *buf,
void *_data)
@@ -146,7 +146,7 @@ static void extract_lines_adjacency_finish(const MeshRenderData *UNUSED(mr),
int v_data = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi));
if (v_data != NO_EDGE) {
BLI_edgehashIterator_getKey(ehi, &v2, &v3);
- l1 = (uint)abs(v_data) - 1;
+ l1 = uint(abs(v_data)) - 1;
if (v_data < 0) { /* `inv_opposite`. */
SWAP(uint, v2, v3);
}
@@ -166,9 +166,9 @@ static void extract_lines_adjacency_finish(const MeshRenderData *UNUSED(mr),
}
static void extract_lines_adjacency_init_subdiv(const DRWSubdivCache *subdiv_cache,
- const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf),
+ const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
+ void * /*buf*/,
void *_data)
{
MeshExtract_LineAdjacency_Data *data = static_cast<MeshExtract_LineAdjacency_Data *>(_data);
@@ -182,7 +182,7 @@ static void extract_lines_adjacency_init_subdiv(const DRWSubdivCache *subdiv_cac
}
static void extract_lines_adjacency_iter_subdiv(const DRWSubdivCache *subdiv_cache,
- const MeshRenderData *UNUSED(mr),
+ const MeshRenderData * /*mr*/,
void *_data,
uint subdiv_quad_index)
{
@@ -207,7 +207,7 @@ static void extract_lines_adjacency_iter_subdiv_bm(const DRWSubdivCache *subdiv_
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
- const BMFace *UNUSED(coarse_quad))
+ const BMFace * /*coarse_quad*/)
{
extract_lines_adjacency_iter_subdiv(subdiv_cache, mr, _data, subdiv_quad_index);
}
@@ -216,12 +216,12 @@ static void extract_lines_adjacency_iter_subdiv_mesh(const DRWSubdivCache *subdi
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
- const MPoly *UNUSED(coarse_quad))
+ const MPoly * /*coarse_quad*/)
{
extract_lines_adjacency_iter_subdiv(subdiv_cache, mr, _data, subdiv_quad_index);
}
-static void extract_lines_adjacency_finish_subdiv(const DRWSubdivCache *UNUSED(subdiv_cache),
+static void extract_lines_adjacency_finish_subdiv(const DRWSubdivCache * /*subdiv_cache*/,
const MeshRenderData *mr,
MeshBatchCache *cache,
void *buf,
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc
index 31e5c515129..572eb5b28f8 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc
@@ -26,8 +26,8 @@ struct MeshExtract_LinePaintMask_Data {
};
static void extract_lines_paint_mask_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(ibo),
+ MeshBatchCache * /*cache*/,
+ void * /*ibo*/,
void *tls_data)
{
MeshExtract_LinePaintMask_Data *data = static_cast<MeshExtract_LinePaintMask_Data *>(tls_data);
@@ -37,7 +37,7 @@ static void extract_lines_paint_mask_init(const MeshRenderData *mr,
static void extract_lines_paint_mask_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *mp,
- const int UNUSED(mp_index),
+ const int mp_index,
void *_data)
{
MeshExtract_LinePaintMask_Data *data = static_cast<MeshExtract_LinePaintMask_Data *>(_data);
@@ -52,7 +52,7 @@ static void extract_lines_paint_mask_iter_poly_mesh(const MeshRenderData *mr,
const int ml_index_last = mp->totloop + mp->loopstart - 1;
const int ml_index_other = (ml_index == ml_index_last) ? mp->loopstart : (ml_index + 1);
- if (mp->flag & ME_FACE_SEL) {
+ if (mr->select_poly && mr->select_poly[mp_index]) {
if (BLI_BITMAP_TEST_AND_SET_ATOMIC(data->select_map, e_index)) {
/* Hide edge as it has more than 2 selected loop. */
GPU_indexbuf_set_line_restart(&data->elb, e_index);
@@ -75,8 +75,8 @@ static void extract_lines_paint_mask_iter_poly_mesh(const MeshRenderData *mr,
}
}
-static void extract_lines_paint_mask_finish(const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
+static void extract_lines_paint_mask_finish(const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
void *buf,
void *_data)
{
@@ -88,8 +88,8 @@ static void extract_lines_paint_mask_finish(const MeshRenderData *UNUSED(mr),
static void extract_lines_paint_mask_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf),
+ MeshBatchCache * /*cache*/,
+ void * /*buf*/,
void *tls_data)
{
MeshExtract_LinePaintMask_Data *data = static_cast<MeshExtract_LinePaintMask_Data *>(tls_data);
@@ -110,11 +110,13 @@ static void extract_lines_paint_mask_iter_subdiv_mesh(const DRWSubdivCache *subd
int *subdiv_loop_edge_index = (int *)GPU_vertbuf_get_data(subdiv_cache->edges_orig_index);
int *subdiv_loop_subdiv_edge_index = subdiv_cache->subdiv_loop_subdiv_edge_index;
+ const int coarse_quad_index = coarse_quad - mr->mpoly;
+
uint start_loop_idx = subdiv_quad_index * 4;
uint end_loop_idx = (subdiv_quad_index + 1) * 4;
for (uint loop_idx = start_loop_idx; loop_idx < end_loop_idx; loop_idx++) {
- const uint coarse_edge_index = (uint)subdiv_loop_edge_index[loop_idx];
- const uint subdiv_edge_index = (uint)subdiv_loop_subdiv_edge_index[loop_idx];
+ const uint coarse_edge_index = uint(subdiv_loop_edge_index[loop_idx]);
+ const uint subdiv_edge_index = uint(subdiv_loop_subdiv_edge_index[loop_idx]);
if (coarse_edge_index == -1u) {
GPU_indexbuf_set_line_restart(&data->elb, subdiv_edge_index);
@@ -124,7 +126,7 @@ static void extract_lines_paint_mask_iter_subdiv_mesh(const DRWSubdivCache *subd
((mr->e_origindex) && (mr->e_origindex[coarse_edge_index] == ORIGINDEX_NONE)))) {
const uint ml_index_other = (loop_idx == (end_loop_idx - 1)) ? start_loop_idx :
loop_idx + 1;
- if (coarse_quad->flag & ME_FACE_SEL) {
+ if (mr->select_poly && mr->select_poly[coarse_quad_index]) {
if (BLI_BITMAP_TEST_AND_SET_ATOMIC(data->select_map, coarse_edge_index)) {
/* Hide edge as it has more than 2 selected loop. */
GPU_indexbuf_set_line_restart(&data->elb, subdiv_edge_index);
@@ -148,12 +150,11 @@ static void extract_lines_paint_mask_iter_subdiv_mesh(const DRWSubdivCache *subd
}
}
-static void extract_lines_paint_mask_finish_subdiv(
- const struct DRWSubdivCache *UNUSED(subdiv_cache),
- const MeshRenderData *mr,
- MeshBatchCache *cache,
- void *buf,
- void *_data)
+static void extract_lines_paint_mask_finish_subdiv(const struct DRWSubdivCache * /*subdiv_cache*/,
+ const MeshRenderData *mr,
+ MeshBatchCache *cache,
+ void *buf,
+ void *_data)
{
extract_lines_paint_mask_finish(mr, cache, buf, _data);
}
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc
index 48eeb86e5ee..e84f122d03e 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc
@@ -19,8 +19,8 @@ namespace blender::draw {
* \{ */
static void extract_points_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf),
+ MeshBatchCache * /*cache*/,
+ void * /*buf*/,
void *tls_data)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(tls_data);
@@ -53,9 +53,9 @@ BLI_INLINE void vert_set_mesh(GPUIndexBufBuilder *elb,
}
}
-static void extract_points_iter_poly_bm(const MeshRenderData *UNUSED(mr),
+static void extract_points_iter_poly_bm(const MeshRenderData * /*mr*/,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *_userdata)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
@@ -70,7 +70,7 @@ static void extract_points_iter_poly_bm(const MeshRenderData *UNUSED(mr),
static void extract_points_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *mp,
- const int UNUSED(mp_index),
+ const int /*mp_index*/,
void *_userdata)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
@@ -113,7 +113,7 @@ static void extract_points_iter_lvert_bm(const MeshRenderData *mr,
}
static void extract_points_iter_lvert_mesh(const MeshRenderData *mr,
- const MVert *UNUSED(mv),
+ const MVert * /*mv*/,
const int lvert_index,
void *_userdata)
{
@@ -129,8 +129,8 @@ static void extract_points_task_reduce(void *_userdata_to, void *_userdata_from)
GPU_indexbuf_join(elb_to, elb_from);
}
-static void extract_points_finish(const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
+static void extract_points_finish(const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
void *buf,
void *_userdata)
{
@@ -141,8 +141,8 @@ static void extract_points_finish(const MeshRenderData *UNUSED(mr),
static void extract_points_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(buffer),
+ MeshBatchCache * /*cache*/,
+ void * /*buffer*/,
void *data)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(data);
@@ -194,7 +194,7 @@ static void extract_points_iter_subdiv_bm(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
- const BMFace *UNUSED(coarse_quad))
+ const BMFace * /*coarse_quad*/)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
extract_points_iter_subdiv_common(elb, mr, subdiv_cache, subdiv_quad_index, true);
@@ -204,7 +204,7 @@ static void extract_points_iter_subdiv_mesh(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
- const MPoly *UNUSED(coarse_quad))
+ const MPoly * /*coarse_quad*/)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
extract_points_iter_subdiv_common(elb, mr, subdiv_cache, subdiv_quad_index, false);
@@ -212,7 +212,7 @@ static void extract_points_iter_subdiv_mesh(const DRWSubdivCache *subdiv_cache,
static void extract_points_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- void *UNUSED(buffer),
+ void * /*buffer*/,
void *data)
{
const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
@@ -281,9 +281,9 @@ static void extract_points_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
}
}
-static void extract_points_finish_subdiv(const DRWSubdivCache *UNUSED(subdiv_cache),
- const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
+static void extract_points_finish_subdiv(const DRWSubdivCache * /*subdiv_cache*/,
+ const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
void *buf,
void *_userdata)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
index 2e3e6c7b6b1..da3560389e4 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
@@ -25,8 +25,8 @@ static void extract_tris_mat_task_reduce(void *_userdata_to, void *_userdata_fro
* \{ */
static void extract_tris_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(ibo),
+ MeshBatchCache * /*cache*/,
+ void * /*ibo*/,
void *tls_data)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(tls_data);
@@ -110,10 +110,10 @@ static void extract_tris_finish(const MeshRenderData *mr,
}
static void extract_tris_init_subdiv(const DRWSubdivCache *subdiv_cache,
- const MeshRenderData *UNUSED(mr),
+ const MeshRenderData * /*mr*/,
MeshBatchCache *cache,
void *buffer,
- void *UNUSED(data))
+ void * /*data*/)
{
GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buffer);
/* Initialize the index buffer, it was already allocated, it will be filled on the device. */
@@ -157,15 +157,15 @@ constexpr MeshExtract create_extractor_tris()
* \{ */
static void extract_tris_single_mat_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(ibo),
+ MeshBatchCache * /*cache*/,
+ void * /*ibo*/,
void *tls_data)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(tls_data);
GPU_indexbuf_init(elb, GPU_PRIM_TRIS, mr->tri_len, mr->loop_len);
}
-static void extract_tris_single_mat_iter_looptri_bm(const MeshRenderData *UNUSED(mr),
+static void extract_tris_single_mat_iter_looptri_bm(const MeshRenderData * /*mr*/,
BMLoop **elt,
const int elt_index,
void *_data)
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc
index 64ade020418..1817591b6a3 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc
@@ -14,6 +14,8 @@
#include "BLI_string.h"
#include "BKE_attribute.h"
+#include "BKE_attribute.hh"
+#include "BKE_mesh.h"
#include "draw_attributes.h"
#include "draw_subdivision.h"
@@ -278,14 +280,14 @@ static void extract_attr_generic(const MeshRenderData *mr,
}
static void extract_attr_init(
- const MeshRenderData *mr, MeshBatchCache *cache, void *buf, void *UNUSED(tls_data), int index)
+ const MeshRenderData *mr, MeshBatchCache *cache, void *buf, void * /*tls_data*/, int index)
{
const DRW_Attributes *attrs_used = &cache->attr_used;
const DRW_AttributeRequest &request = attrs_used->requests[index];
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
- init_vbo_for_attribute(*mr, vbo, request, false, static_cast<uint32_t>(mr->loop_len));
+ init_vbo_for_attribute(*mr, vbo, request, false, uint32_t(mr->loop_len));
/* TODO(@kevindietrich): float3 is used for scalar attributes as the implicit conversion done by
* OpenGL to vec4 for a scalar `s` will produce a `vec4(s, 0, 0, 1)`. However, following the
@@ -325,7 +327,7 @@ static void extract_attr_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
MeshBatchCache *cache,
void *buffer,
- void *UNUSED(tls_data),
+ void * /*tls_data*/,
int index)
{
const DRW_Attributes *attrs_used = &cache->attr_used;
@@ -340,7 +342,7 @@ static void extract_attr_init_subdiv(const DRWSubdivCache *subdiv_cache,
GPUVertFormat coarse_format = {0};
GPU_vertformat_attr_add(&coarse_format, "data", GPU_COMP_F32, dimensions, GPU_FETCH_FLOAT);
GPU_vertbuf_init_with_format_ex(src_data, &coarse_format, GPU_USAGE_STATIC);
- GPU_vertbuf_data_alloc(src_data, static_cast<uint32_t>(coarse_mesh->totloop));
+ GPU_vertbuf_data_alloc(src_data, uint32_t(coarse_mesh->totloop));
switch (request.cd_type) {
case CD_PROP_BOOL:
@@ -379,7 +381,7 @@ static void extract_attr_init_subdiv(const DRWSubdivCache *subdiv_cache,
draw_subdiv_interp_custom_data(subdiv_cache,
src_data,
dst_buffer,
- static_cast<int>(dimensions),
+ int(dimensions),
0,
ELEM(request.cd_type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR));
@@ -432,6 +434,40 @@ constexpr MeshExtract create_extractor_attr(ExtractInitFn fn, ExtractInitSubdivF
return extractor;
}
+static void extract_mesh_attr_viewer_init(const MeshRenderData *mr,
+ MeshBatchCache * /*cache*/,
+ void *buf,
+ void * /*tls_data*/)
+{
+ GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
+ static GPUVertFormat format = {0};
+ if (format.attr_len == 0) {
+ GPU_vertformat_attr_add(&format, "attribute_value", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ }
+
+ GPU_vertbuf_init_with_format(vbo, &format);
+ GPU_vertbuf_data_alloc(vbo, mr->loop_len);
+ MutableSpan<ColorGeometry4f> attr{static_cast<ColorGeometry4f *>(GPU_vertbuf_get_data(vbo)),
+ mr->loop_len};
+
+ const StringRefNull attr_name = ".viewer";
+ const bke::AttributeAccessor attributes = mr->me->attributes();
+ attributes
+ .lookup_or_default<ColorGeometry4f>(attr_name, ATTR_DOMAIN_CORNER, {1.0f, 0.0f, 1.0f, 1.0f})
+ .materialize(attr);
+}
+
+constexpr MeshExtract create_extractor_attr_viewer()
+{
+ MeshExtract extractor = {nullptr};
+ extractor.init = extract_mesh_attr_viewer_init;
+ extractor.data_type = MR_DATA_NONE;
+ extractor.data_size = 0;
+ extractor.use_threading = false;
+ extractor.mesh_buffer_offset = offsetof(MeshBufferList, vbo.attr_viewer);
+ return extractor;
+}
+
/** \} */
} // namespace blender::draw
@@ -457,3 +493,5 @@ const MeshExtract extract_attr[GPU_MAX_ATTR] = {
CREATE_EXTRACTOR_ATTR(13),
CREATE_EXTRACTOR_ATTR(14),
};
+
+const MeshExtract extract_attr_viewer = blender::draw::create_extractor_attr_viewer();
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc
index 50c37f6397c..de1f5181ac5 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc
@@ -43,7 +43,7 @@ static float loop_edge_factor_get(const float f_no[3],
}
static void extract_edge_fac_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
void *tls_data)
{
@@ -66,7 +66,7 @@ static void extract_edge_fac_init(const MeshRenderData *mr,
* We could have a flag in the mesh instead or check the modifier stack. */
const MEdge *med = mr->medge;
for (int e_index = 0; e_index < mr->edge_len; e_index++, med++) {
- if ((med->flag & ME_EDGERENDER) == 0) {
+ if ((med->flag & ME_EDGEDRAW) == 0) {
data->use_edge_render = true;
break;
}
@@ -82,7 +82,7 @@ static void extract_edge_fac_init(const MeshRenderData *mr,
static void extract_edge_fac_iter_poly_bm(const MeshRenderData *mr,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *_data)
{
MeshExtract_EdgeFac_Data *data = static_cast<MeshExtract_EdgeFac_Data *>(_data);
@@ -118,7 +118,7 @@ static void extract_edge_fac_iter_poly_mesh(const MeshRenderData *mr,
if (data->use_edge_render) {
const MEdge *med = &mr->medge[ml->e];
- data->vbo_data[ml_index] = (med->flag & ME_EDGERENDER) ? 255 : 0;
+ data->vbo_data[ml_index] = (med->flag & ME_EDGEDRAW) ? 255 : 0;
}
else {
@@ -146,7 +146,7 @@ static void extract_edge_fac_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_edge_fac_iter_ledge_bm(const MeshRenderData *mr,
- const BMEdge *UNUSED(eed),
+ const BMEdge * /*eed*/,
const int ledge_index,
void *_data)
{
@@ -156,7 +156,7 @@ static void extract_edge_fac_iter_ledge_bm(const MeshRenderData *mr,
}
static void extract_edge_fac_iter_ledge_mesh(const MeshRenderData *mr,
- const MEdge *UNUSED(med),
+ const MEdge * /*med*/,
const int ledge_index,
void *_data)
{
@@ -167,7 +167,7 @@ static void extract_edge_fac_iter_ledge_mesh(const MeshRenderData *mr,
}
static void extract_edge_fac_finish(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
void *_data)
{
@@ -217,10 +217,10 @@ static GPUVertFormat *get_subdiv_edge_fac_format()
}
static void extract_edge_fac_init_subdiv(const DRWSubdivCache *subdiv_cache,
- const MeshRenderData *UNUSED(mr),
+ const MeshRenderData * /*mr*/,
MeshBatchCache *cache,
void *buffer,
- void *UNUSED(data))
+ void * /*data*/)
{
const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
GPUVertBuf *edge_idx = cache->final.buff.vbo.edge_idx;
@@ -252,9 +252,9 @@ static void extract_edge_fac_init_subdiv(const DRWSubdivCache *subdiv_cache,
}
static void extract_edge_fac_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
- const MeshRenderData *UNUSED(mr),
+ const MeshRenderData * /*mr*/,
void *buffer,
- void *UNUSED(data))
+ void * /*data*/)
{
const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
if (loose_geom.edge_len == 0) {
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc
index 27fd6546b8c..31dc2fdff6a 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc
@@ -60,14 +60,14 @@ static void mesh_render_data_edge_flag(const MeshRenderData *mr,
if (mr->edge_crease_ofs != -1) {
float crease = BM_ELEM_CD_GET_FLOAT(eed, mr->edge_crease_ofs);
if (crease > 0) {
- eattr->crease = (uchar)ceil(crease * 15.0f);
+ eattr->crease = uchar(ceil(crease * 15.0f));
}
}
/* Use a byte for value range */
if (mr->bweight_ofs != -1) {
float bweight = BM_ELEM_CD_GET_FLOAT(eed, mr->bweight_ofs);
if (bweight > 0) {
- eattr->bweight = (uchar)(bweight * 255.0f);
+ eattr->bweight = uchar(bweight * 255.0f);
}
}
#ifdef WITH_FREESTYLE
@@ -95,7 +95,7 @@ static void mesh_render_data_vert_flag(const MeshRenderData *mr,
if (mr->vert_crease_ofs != -1) {
float crease = BM_ELEM_CD_GET_FLOAT(eve, mr->vert_crease_ofs);
if (crease > 0) {
- eattr->crease |= (uchar)ceil(crease * 15.0f) << 4;
+ eattr->crease |= uchar(ceil(crease * 15.0f)) << 4;
}
}
}
@@ -112,7 +112,7 @@ static GPUVertFormat *get_edit_data_format()
}
static void extract_edit_data_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
void *tls_data)
{
@@ -126,7 +126,7 @@ static void extract_edit_data_init(const MeshRenderData *mr,
static void extract_edit_data_iter_poly_bm(const MeshRenderData *mr,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *_data)
{
EditLoopData *vbo_data = *(EditLoopData **)_data;
@@ -223,7 +223,7 @@ static void extract_edit_data_iter_lvert_bm(const MeshRenderData *mr,
}
static void extract_edit_data_iter_lvert_mesh(const MeshRenderData *mr,
- const MVert *UNUSED(mv),
+ const MVert * /*mv*/,
const int lvert_index,
void *_data)
{
@@ -240,8 +240,8 @@ static void extract_edit_data_iter_lvert_mesh(const MeshRenderData *mr,
}
static void extract_edit_data_init_subdiv(const DRWSubdivCache *subdiv_cache,
- const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
+ const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
void *buf,
void *data)
{
@@ -300,14 +300,14 @@ static void extract_edit_data_iter_subdiv_mesh(const DRWSubdivCache *subdiv_cach
uint subdiv_quad_index,
const MPoly *coarse_quad)
{
- const int coarse_quad_index = static_cast<int>(coarse_quad - mr->mpoly);
+ const int coarse_quad_index = int(coarse_quad - mr->mpoly);
BMFace *coarse_quad_bm = bm_original_face_get(mr, coarse_quad_index);
extract_edit_data_iter_subdiv_bm(subdiv_cache, mr, _data, subdiv_quad_index, coarse_quad_bm);
}
static void extract_edit_data_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- void *UNUSED(buffer),
+ void * /*buffer*/,
void *_data)
{
const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc
index 0b9043e3289..3ebf2daf1e9 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc
@@ -43,7 +43,7 @@ static void extract_edituv_data_init_common(const MeshRenderData *mr,
}
static void extract_edituv_data_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
void *tls_data)
{
@@ -54,7 +54,7 @@ static void extract_edituv_data_init(const MeshRenderData *mr,
static void extract_edituv_data_iter_poly_bm(const MeshRenderData *mr,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *_data)
{
BMLoop *l_iter, *l_first;
@@ -114,7 +114,7 @@ static void extract_edituv_data_iter_poly_mesh(const MeshRenderData *mr,
static void extract_edituv_data_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
void *tls_data)
{
@@ -174,7 +174,7 @@ static void extract_edituv_data_iter_subdiv_mesh(const DRWSubdivCache *subdiv_ca
uint subdiv_quad_index,
const MPoly *coarse_quad)
{
- const int coarse_quad_index = static_cast<int>(coarse_quad - mr->mpoly);
+ const int coarse_quad_index = int(coarse_quad - mr->mpoly);
BMFace *coarse_quad_bm = bm_original_face_get(mr, coarse_quad_index);
extract_edituv_data_iter_subdiv_bm(subdiv_cache, mr, _data, subdiv_quad_index, coarse_quad_bm);
}
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc
index e4714aabf34..492756f30bb 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc
@@ -52,7 +52,7 @@ static void compute_normalize_edge_vectors(float auv[2][2],
static short v2_to_short_angle(const float v[2])
{
- return atan2f(v[1], v[0]) * (float)M_1_PI * SHRT_MAX;
+ return atan2f(v[1], v[0]) * float(M_1_PI) * SHRT_MAX;
}
static void edituv_get_edituv_stretch_angle(float auv[2][2],
@@ -63,7 +63,7 @@ static void edituv_get_edituv_stretch_angle(float auv[2][2],
r_stretch->uv_angles[0] = v2_to_short_angle(auv[0]);
r_stretch->uv_angles[1] = v2_to_short_angle(auv[1]);
/* Compute 3D angle here. */
- r_stretch->angle = angle_normalized_v3v3(av[0], av[1]) * (float)M_1_PI * SHRT_MAX;
+ r_stretch->angle = angle_normalized_v3v3(av[0], av[1]) * float(M_1_PI) * SHRT_MAX;
#if 0 /* here for reference, this is done in shader now. */
float uvang = angle_normalized_v2v2(auv0, auv1);
@@ -74,7 +74,7 @@ static void edituv_get_edituv_stretch_angle(float auv[2][2],
}
static void extract_edituv_stretch_angle_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
void *tls_data)
{
@@ -104,7 +104,7 @@ static void extract_edituv_stretch_angle_init(const MeshRenderData *mr,
static void extract_edituv_stretch_angle_iter_poly_bm(const MeshRenderData *mr,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *_data)
{
MeshExtract_StretchAngle_Data *data = static_cast<MeshExtract_StretchAngle_Data *>(_data);
@@ -157,7 +157,7 @@ static void extract_edituv_stretch_angle_iter_poly_bm(const MeshRenderData *mr,
static void extract_edituv_stretch_angle_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *mp,
- const int UNUSED(mp_index),
+ const int /*mp_index*/,
void *_data)
{
MeshExtract_StretchAngle_Data *data = static_cast<MeshExtract_StretchAngle_Data *>(_data);
@@ -214,7 +214,7 @@ static void extract_edituv_stretch_angle_init_subdiv(const DRWSubdivCache *subdi
const MeshRenderData *mr,
MeshBatchCache *cache,
void *buffer,
- void *UNUSED(tls_data))
+ void * /*tls_data*/)
{
GPUVertBuf *refined_vbo = static_cast<GPUVertBuf *>(buffer);
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc
index 9679c0523f8..7c96fbd6a99 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc
@@ -20,9 +20,9 @@ namespace blender::draw {
* \{ */
static void extract_edituv_stretch_area_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
- void *UNUSED(tls_data))
+ void * /*tls_data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
static GPUVertFormat format = {0};
@@ -90,7 +90,7 @@ static void compute_area_ratio(const MeshRenderData *mr,
static void extract_edituv_stretch_area_finish(const MeshRenderData *mr,
MeshBatchCache *cache,
void *buf,
- void *UNUSED(data))
+ void * /*data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
float *area_ratio = static_cast<float *>(MEM_mallocN(sizeof(float) * mr->poly_len, __func__));
@@ -126,7 +126,7 @@ static void extract_edituv_stretch_area_init_subdiv(const DRWSubdivCache *subdiv
const MeshRenderData *mr,
MeshBatchCache *cache,
void *buffer,
- void *UNUSED(data))
+ void * /*data*/)
{
/* Initialize final buffer. */
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc
index 27d1975d67b..55ad2e67487 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc
@@ -21,7 +21,7 @@ struct MeshExtract_EditUVFdotData_Data {
};
static void extract_fdots_edituv_data_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
void *tls_data)
{
@@ -41,7 +41,7 @@ static void extract_fdots_edituv_data_init(const MeshRenderData *mr,
static void extract_fdots_edituv_data_iter_poly_bm(const MeshRenderData *mr,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *_data)
{
MeshExtract_EditUVFdotData_Data *data = static_cast<MeshExtract_EditUVFdotData_Data *>(_data);
@@ -51,7 +51,7 @@ static void extract_fdots_edituv_data_iter_poly_bm(const MeshRenderData *mr,
}
static void extract_fdots_edituv_data_iter_poly_mesh(const MeshRenderData *mr,
- const MPoly *UNUSED(mp),
+ const MPoly * /*mp*/,
const int mp_index,
void *_data)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_nor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_nor.cc
index c47cde63630..02e4b877562 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_nor.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_nor.cc
@@ -19,9 +19,9 @@ namespace blender::draw {
#define NOR_AND_FLAG_HIDDEN -2
static void extract_fdots_nor_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
- void *UNUSED(tls_data))
+ void * /*tls_data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
static GPUVertFormat format = {0};
@@ -34,9 +34,9 @@ static void extract_fdots_nor_init(const MeshRenderData *mr,
}
static void extract_fdots_nor_finish(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
- void *UNUSED(data))
+ void * /*data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
static float invalid_normal[3] = {0.0f, 0.0f, 0.0f};
@@ -99,9 +99,9 @@ constexpr MeshExtract create_extractor_fdots_nor()
* \{ */
static void extract_fdots_nor_hq_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
- void *UNUSED(tls_data))
+ void * /*tls_data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
static GPUVertFormat format = {0};
@@ -114,9 +114,9 @@ static void extract_fdots_nor_hq_init(const MeshRenderData *mr,
}
static void extract_fdots_nor_hq_finish(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
- void *UNUSED(data))
+ void * /*data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
static float invalid_normal[3] = {0.0f, 0.0f, 0.0f};
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc
index c391cb6ca5a..d43eb6117df 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc
@@ -36,7 +36,7 @@ static GPUVertFormat *get_fdots_nor_format_subdiv()
}
static void extract_fdots_pos_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
void *tls_data)
{
@@ -63,7 +63,7 @@ static void extract_fdots_pos_iter_poly_bm(const MeshRenderData *mr,
do {
add_v3_v3(co, bm_vert_co_get(mr, l_iter->v));
} while ((l_iter = l_iter->next) != l_first);
- mul_v3_fl(co, 1.0f / (float)f->len);
+ mul_v3_fl(co, 1.0f / float(f->len));
}
static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr,
@@ -77,7 +77,7 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr,
const MVert *mvert = mr->mvert;
const MLoop *mloop = mr->mloop;
- const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags;
+ const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags;
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
@@ -95,15 +95,15 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr,
}
if (!mr->use_subsurf_fdots) {
- mul_v3_fl(co, 1.0f / (float)mp->totloop);
+ mul_v3_fl(co, 1.0f / float(mp->totloop));
}
}
static void extract_fdots_init_subdiv(const DRWSubdivCache *subdiv_cache,
- const MeshRenderData *UNUSED(mr),
+ const MeshRenderData * /*mr*/,
MeshBatchCache *cache,
void *buffer,
- void *UNUSED(data))
+ void * /*data*/)
{
/* We "extract" positions, normals, and indices at once. */
GPUVertBuf *fdots_pos_vbo = static_cast<GPUVertBuf *>(buffer);
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc
index b0403cf7c4c..802f000cb43 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc
@@ -22,7 +22,7 @@ struct MeshExtract_FdotUV_Data {
};
static void extract_fdots_uv_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
void *tls_data)
{
@@ -53,16 +53,16 @@ static void extract_fdots_uv_init(const MeshRenderData *mr,
}
}
-static void extract_fdots_uv_iter_poly_bm(const MeshRenderData *UNUSED(mr),
+static void extract_fdots_uv_iter_poly_bm(const MeshRenderData * /*mr*/,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *_data)
{
MeshExtract_FdotUV_Data *data = static_cast<MeshExtract_FdotUV_Data *>(_data);
BMLoop *l_iter, *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- float w = 1.0f / (float)f->len;
+ float w = 1.0f / float(f->len);
const MLoopUV *luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, data->cd_ofs);
madd_v2_v2fl(data->vbo_data[BM_elem_index_get(f)], luv->uv, w);
} while ((l_iter = l_iter->next) != l_first);
@@ -74,7 +74,7 @@ static void extract_fdots_uv_iter_poly_mesh(const MeshRenderData *mr,
void *_data)
{
MeshExtract_FdotUV_Data *data = static_cast<MeshExtract_FdotUV_Data *>(_data);
- const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags;
+ const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags;
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
@@ -86,7 +86,7 @@ static void extract_fdots_uv_iter_poly_mesh(const MeshRenderData *mr,
}
}
else {
- float w = 1.0f / (float)mp->totloop;
+ float w = 1.0f / float(mp->totloop);
madd_v2_v2fl(data->vbo_data[mp_index], data->uv_data[ml_index].uv, w);
}
}
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc
index 01d07fa5f83..ff0d502ea1e 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc
@@ -16,7 +16,7 @@ namespace blender::draw {
* \{ */
static void extract_lnor_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
void *tls_data)
{
@@ -34,7 +34,7 @@ static void extract_lnor_init(const MeshRenderData *mr,
static void extract_lnor_iter_poly_bm(const MeshRenderData *mr,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *data)
{
BMLoop *l_iter, *l_first;
@@ -86,7 +86,7 @@ static void extract_lnor_iter_poly_mesh(const MeshRenderData *mr,
(mr->edit_bmesh && (mr->v_origindex) && mr->v_origindex[ml->v] == ORIGINDEX_NONE)) {
lnor_data->w = -1;
}
- else if (mp->flag & ME_FACE_SEL) {
+ else if (mr->select_poly && mr->select_poly[mp_index]) {
lnor_data->w = 1;
}
else {
@@ -106,10 +106,10 @@ static GPUVertFormat *get_subdiv_lnor_format()
}
static void extract_lnor_init_subdiv(const DRWSubdivCache *subdiv_cache,
- const MeshRenderData *UNUSED(mr),
+ const MeshRenderData * /*mr*/,
MeshBatchCache *cache,
void *buffer,
- void *UNUSED(data))
+ void * /*data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buffer);
GPUVertBuf *pos_nor = cache->final.buff.vbo.pos_nor;
@@ -143,7 +143,7 @@ struct gpuHQNor {
};
static void extract_lnor_hq_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
void *tls_data)
{
@@ -161,7 +161,7 @@ static void extract_lnor_hq_init(const MeshRenderData *mr,
static void extract_lnor_hq_iter_poly_bm(const MeshRenderData *mr,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *data)
{
BMLoop *l_iter, *l_first;
@@ -211,7 +211,7 @@ static void extract_lnor_hq_iter_poly_mesh(const MeshRenderData *mr,
(mr->edit_bmesh && (mr->v_origindex) && mr->v_origindex[ml->v] == ORIGINDEX_NONE)) {
lnor_data->w = -1;
}
- else if (mp->flag & ME_FACE_SEL) {
+ else if (mr->select_poly && mr->select_poly[mp_index]) {
lnor_data->w = 1;
}
else {
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc
index fe2a02b6b63..d0d97054448 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc
@@ -23,9 +23,9 @@ namespace blender::draw {
* \{ */
static void extract_mesh_analysis_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
- void *UNUSED(tls_data))
+ void * /*tls_data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
static GPUVertFormat format = {0};
@@ -67,8 +67,8 @@ BLI_INLINE float overhang_remap(float fac, float min, float max, float minmax_ir
static void statvis_calc_overhang(const MeshRenderData *mr, float *r_overhang)
{
const MeshStatVis *statvis = &mr->toolsettings->statvis;
- const float min = statvis->overhang_min / (float)M_PI;
- const float max = statvis->overhang_max / (float)M_PI;
+ const float min = statvis->overhang_min / float(M_PI);
+ const float max = statvis->overhang_max / float(M_PI);
const char axis = statvis->overhang_axis;
BMEditMesh *em = mr->edit_bmesh;
BMIter iter;
@@ -88,7 +88,7 @@ static void statvis_calc_overhang(const MeshRenderData *mr, float *r_overhang)
if (mr->extract_type == MR_EXTRACT_BMESH) {
int l_index = 0;
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- float fac = angle_normalized_v3v3(bm_face_no_get(mr, f), dir) / (float)M_PI;
+ float fac = angle_normalized_v3v3(bm_face_no_get(mr, f), dir) / float(M_PI);
fac = overhang_remap(fac, min, max, minmax_irange);
for (int i = 0; i < f->len; i++, l_index++) {
r_overhang[l_index] = fac;
@@ -98,7 +98,7 @@ static void statvis_calc_overhang(const MeshRenderData *mr, float *r_overhang)
else {
const MPoly *mp = mr->mpoly;
for (int mp_index = 0, l_index = 0; mp_index < mr->poly_len; mp_index++, mp++) {
- float fac = angle_normalized_v3v3(mr->poly_normals[mp_index], dir) / (float)M_PI;
+ float fac = angle_normalized_v3v3(mr->poly_normals[mp_index], dir) / float(M_PI);
fac = overhang_remap(fac, min, max, minmax_irange);
for (int i = 0; i < mp->totloop; i++, l_index++) {
r_overhang[l_index] = fac;
@@ -265,7 +265,7 @@ struct BVHTree_OverlapData {
float epsilon;
};
-static bool bvh_overlap_cb(void *userdata, int index_a, int index_b, int UNUSED(thread))
+static bool bvh_overlap_cb(void *userdata, int index_a, int index_b, int /*thread*/)
{
struct BVHTree_OverlapData *data = static_cast<struct BVHTree_OverlapData *>(userdata);
@@ -367,7 +367,7 @@ static void statvis_calc_intersect(const MeshRenderData *mr, float *r_intersect)
}
}
-BLI_INLINE float distort_remap(float fac, float min, float UNUSED(max), float minmax_irange)
+BLI_INLINE float distort_remap(float fac, float min, float /*max*/, float minmax_irange)
{
if (fac >= min) {
fac = (fac - min) * minmax_irange;
@@ -474,7 +474,7 @@ static void statvis_calc_distort(const MeshRenderData *mr, float *r_distort)
}
}
-BLI_INLINE float sharp_remap(float fac, float min, float UNUSED(max), float minmax_irange)
+BLI_INLINE float sharp_remap(float fac, float min, float /*max*/, float minmax_irange)
{
/* important not '>=' */
if (fac > min) {
@@ -588,9 +588,9 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp)
}
static void extract_analysis_iter_finish_mesh(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
- void *UNUSED(data))
+ void * /*data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
BLI_assert(mr->edit_bmesh);
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc
index 4fcbdb1fc7c..915495204d4 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc
@@ -19,7 +19,7 @@ struct MeshExtract_Orco_Data {
};
static void extract_orco_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
void *tls_data)
{
@@ -45,9 +45,9 @@ static void extract_orco_init(const MeshRenderData *mr,
BLI_assert(data->orco);
}
-static void extract_orco_iter_poly_bm(const MeshRenderData *UNUSED(mr),
+static void extract_orco_iter_poly_bm(const MeshRenderData * /*mr*/,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *data)
{
MeshExtract_Orco_Data *orco_data = (MeshExtract_Orco_Data *)data;
@@ -63,7 +63,7 @@ static void extract_orco_iter_poly_bm(const MeshRenderData *UNUSED(mr),
static void extract_orco_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *mp,
- const int UNUSED(mp_index),
+ const int /*mp_index*/,
void *data)
{
const MLoop *mloop = mr->mloop;
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
index a822845c688..30b4f808487 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
@@ -28,7 +28,7 @@ struct MeshExtract_PosNor_Data {
};
static void extract_pos_nor_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
void *tls_data)
{
@@ -66,7 +66,7 @@ static void extract_pos_nor_init(const MeshRenderData *mr,
static void extract_pos_nor_iter_poly_bm(const MeshRenderData *mr,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *_data)
{
MeshExtract_PosNor_Data *data = static_cast<MeshExtract_PosNor_Data *>(_data);
@@ -104,7 +104,7 @@ static void extract_pos_nor_iter_poly_mesh(const MeshRenderData *mr,
((mr->v_origindex) && (mr->v_origindex[ml->v] == ORIGINDEX_NONE))) {
vert->nor.w = -1;
}
- else if (mv->flag & SELECT) {
+ else if (mr->select_vert && mr->select_vert[ml->v]) {
vert->nor.w = 1;
}
else {
@@ -171,9 +171,9 @@ static void extract_pos_nor_iter_lvert_mesh(const MeshRenderData *mr,
vert->nor = data->normals[v_index].low;
}
-static void extract_pos_nor_finish(const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf),
+static void extract_pos_nor_finish(const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
+ void * /*buf*/,
void *_data)
{
MeshExtract_PosNor_Data *data = static_cast<MeshExtract_PosNor_Data *>(_data);
@@ -201,10 +201,10 @@ static GPUVertFormat *get_custom_normals_format()
}
static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache,
- const MeshRenderData *UNUSED(mr),
+ const MeshRenderData * /*mr*/,
MeshBatchCache *cache,
void *buffer,
- void *UNUSED(data))
+ void * /*data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buffer);
const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
@@ -282,9 +282,9 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache,
}
static void extract_pos_nor_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
- const MeshRenderData *UNUSED(mr),
+ const MeshRenderData * /*mr*/,
void *buffer,
- void *UNUSED(data))
+ void * /*data*/)
{
const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
if (loose_geom.loop_len == 0) {
@@ -373,7 +373,7 @@ struct MeshExtract_PosNorHQ_Data {
};
static void extract_pos_nor_hq_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
void *tls_data)
{
@@ -411,7 +411,7 @@ static void extract_pos_nor_hq_init(const MeshRenderData *mr,
static void extract_pos_nor_hq_iter_poly_bm(const MeshRenderData *mr,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *_data)
{
MeshExtract_PosNorHQ_Data *data = static_cast<MeshExtract_PosNorHQ_Data *>(_data);
@@ -429,7 +429,7 @@ static void extract_pos_nor_hq_iter_poly_bm(const MeshRenderData *mr,
static void extract_pos_nor_hq_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *mp,
- const int UNUSED(mp_index),
+ const int /*mp_index*/,
void *_data)
{
MeshExtract_PosNorHQ_Data *data = static_cast<MeshExtract_PosNorHQ_Data *>(_data);
@@ -451,7 +451,7 @@ static void extract_pos_nor_hq_iter_poly_mesh(const MeshRenderData *mr,
((mr->v_origindex) && (mr->v_origindex[ml->v] == ORIGINDEX_NONE))) {
vert->nor[3] = -1;
}
- else if (mv->flag & SELECT) {
+ else if (mr->select_vert && mr->select_vert[ml->v]) {
vert->nor[3] = 1;
}
else {
@@ -523,9 +523,9 @@ static void extract_pos_nor_hq_iter_lvert_mesh(const MeshRenderData *mr,
vert->nor[3] = 0;
}
-static void extract_pos_nor_hq_finish(const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf),
+static void extract_pos_nor_hq_finish(const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
+ void * /*buf*/,
void *_data)
{
MeshExtract_PosNorHQ_Data *data = static_cast<MeshExtract_PosNorHQ_Data *>(_data);
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc
index 6202fdd312d..34b8124f872 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc
@@ -32,9 +32,9 @@ static GPUVertFormat *get_sculpt_data_format()
}
static void extract_sculpt_data_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
- void *UNUSED(tls_data))
+ void * /*tls_data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
GPUVertFormat *format = get_sculpt_data_format();
@@ -44,7 +44,8 @@ static void extract_sculpt_data_init(const MeshRenderData *mr,
CustomData *cd_pdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->pdata : &mr->me->pdata;
const float *cd_mask = (const float *)CustomData_get_layer(cd_vdata, CD_PAINT_MASK);
- const int *cd_face_set = (const int *)CustomData_get_layer(cd_pdata, CD_SCULPT_FACE_SETS);
+ const int *cd_face_set = (const int *)CustomData_get_layer_named(
+ cd_pdata, CD_PROP_INT32, ".sculpt_face_set");
GPU_vertbuf_init_with_format(vbo, format);
GPU_vertbuf_data_alloc(vbo, mr->loop_len);
@@ -59,7 +60,7 @@ static void extract_sculpt_data_init(const MeshRenderData *mr,
if (mr->extract_type == MR_EXTRACT_BMESH) {
int cd_mask_ofs = CustomData_get_offset(cd_vdata, CD_PAINT_MASK);
- int cd_face_set_ofs = CustomData_get_offset(cd_pdata, CD_SCULPT_FACE_SETS);
+ int cd_face_set_ofs = CustomData_get_offset_named(cd_pdata, CD_PROP_INT32, ".sculpt_face_set");
BMIter f_iter;
BMFace *efa;
BM_ITER_MESH (efa, &f_iter, mr->bm, BM_FACES_OF_MESH) {
@@ -114,9 +115,9 @@ static void extract_sculpt_data_init(const MeshRenderData *mr,
static void extract_sculpt_data_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buffer,
- void *UNUSED(data))
+ void * /*data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buffer);
@@ -171,7 +172,8 @@ static void extract_sculpt_data_init_subdiv(const DRWSubdivCache *subdiv_cache,
};
gpuFaceSet *face_sets = (gpuFaceSet *)GPU_vertbuf_get_data(face_set_vbo);
- const int *cd_face_set = (const int *)CustomData_get_layer(cd_pdata, CD_SCULPT_FACE_SETS);
+ const int *cd_face_set = (const int *)CustomData_get_layer_named(
+ cd_pdata, CD_PROP_INT32, ".sculpt_face_set");
GPUVertFormat *format = get_sculpt_data_format();
GPU_vertbuf_init_build_on_device(vbo, format, subdiv_cache->num_subdiv_loops);
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc
index 9e0d171c9e4..5c196a67d0b 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc
@@ -14,7 +14,7 @@ namespace blender::draw {
/** \name Extract Selection Index
* \{ */
-static void extract_select_idx_init_impl(const MeshRenderData *UNUSED(mr),
+static void extract_select_idx_init_impl(const MeshRenderData * /*mr*/,
const int len,
void *buf,
void *tls_data)
@@ -30,7 +30,7 @@ static void extract_select_idx_init_impl(const MeshRenderData *UNUSED(mr),
}
static void extract_select_idx_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
void *tls_data)
{
@@ -42,7 +42,7 @@ static void extract_select_idx_init(const MeshRenderData *mr,
* index VBO's. We could upload the p/e/v_origindex as a buffer texture and sample it inside the
* shader to output original index. */
-static void extract_poly_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr),
+static void extract_poly_idx_iter_poly_bm(const MeshRenderData * /*mr*/,
const BMFace *f,
const int f_index,
void *data)
@@ -55,9 +55,9 @@ static void extract_poly_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr),
} while ((l_iter = l_iter->next) != l_first);
}
-static void extract_edge_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr),
+static void extract_edge_idx_iter_poly_bm(const MeshRenderData * /*mr*/,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *data)
{
BMLoop *l_iter, *l_first;
@@ -68,9 +68,9 @@ static void extract_edge_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr),
} while ((l_iter = l_iter->next) != l_first);
}
-static void extract_vert_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr),
+static void extract_vert_idx_iter_poly_bm(const MeshRenderData * /*mr*/,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *data)
{
BMLoop *l_iter, *l_first;
@@ -122,7 +122,7 @@ static void extract_poly_idx_iter_poly_mesh(const MeshRenderData *mr,
static void extract_edge_idx_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *mp,
- const int UNUSED(mp_index),
+ const int /*mp_index*/,
void *data)
{
const MLoop *mloop = mr->mloop;
@@ -135,7 +135,7 @@ static void extract_edge_idx_iter_poly_mesh(const MeshRenderData *mr,
static void extract_vert_idx_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *mp,
- const int UNUSED(mp_index),
+ const int /*mp_index*/,
void *data)
{
const MLoop *mloop = mr->mloop;
@@ -147,7 +147,7 @@ static void extract_vert_idx_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_edge_idx_iter_ledge_mesh(const MeshRenderData *mr,
- const MEdge *UNUSED(med),
+ const MEdge * /*med*/,
const int ledge_index,
void *data)
{
@@ -169,7 +169,7 @@ static void extract_vert_idx_iter_ledge_mesh(const MeshRenderData *mr,
}
static void extract_vert_idx_iter_lvert_mesh(const MeshRenderData *mr,
- const MVert *UNUSED(mv),
+ const MVert * /*mv*/,
const int lvert_index,
void *data)
{
@@ -182,9 +182,9 @@ static void extract_vert_idx_iter_lvert_mesh(const MeshRenderData *mr,
static void extract_vert_idx_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
- void *UNUSED(data))
+ void * /*data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
@@ -213,7 +213,7 @@ static void extract_vert_idx_init_subdiv(const DRWSubdivCache *subdiv_cache,
static void extract_vert_idx_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *buffer,
- void *UNUSED(data))
+ void * /*data*/)
{
const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
if (loose_geom.loop_len == 0) {
@@ -254,10 +254,10 @@ static void extract_vert_idx_loose_geom_subdiv(const DRWSubdivCache *subdiv_cach
}
static void extract_edge_idx_init_subdiv(const DRWSubdivCache *subdiv_cache,
- const MeshRenderData *UNUSED(mr),
- MeshBatchCache *UNUSED(cache),
+ const MeshRenderData * /*mr*/,
+ MeshBatchCache * /*cache*/,
void *buf,
- void *UNUSED(data))
+ void * /*data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
@@ -271,7 +271,7 @@ static void extract_edge_idx_init_subdiv(const DRWSubdivCache *subdiv_cache,
static void extract_edge_idx_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *buffer,
- void *UNUSED(data))
+ void * /*data*/)
{
const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
if (loose_geom.edge_len == 0) {
@@ -294,9 +294,9 @@ static void extract_edge_idx_loose_geom_subdiv(const DRWSubdivCache *subdiv_cach
static void extract_poly_idx_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
- void *UNUSED(data))
+ void * /*data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
draw_subdiv_init_origindex_buffer(
@@ -366,15 +366,15 @@ constexpr MeshExtract create_extractor_vert_idx()
}
static void extract_fdot_idx_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
void *tls_data)
{
extract_select_idx_init_impl(mr, mr->poly_len, buf, tls_data);
}
-static void extract_fdot_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr),
- const BMFace *UNUSED(f),
+static void extract_fdot_idx_iter_poly_bm(const MeshRenderData * /*mr*/,
+ const BMFace * /*f*/,
const int f_index,
void *data)
{
@@ -382,7 +382,7 @@ static void extract_fdot_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr),
}
static void extract_fdot_idx_iter_poly_mesh(const MeshRenderData *mr,
- const MPoly *UNUSED(mp),
+ const MPoly * /*mp*/,
const int mp_index,
void *data)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_skin_roots.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_skin_roots.cc
index f7655658bdd..e8feb4bebce 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_skin_roots.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_skin_roots.cc
@@ -19,9 +19,9 @@ struct SkinRootData {
};
static void extract_skin_roots_init(const MeshRenderData *mr,
- MeshBatchCache *UNUSED(cache),
+ MeshBatchCache * /*cache*/,
void *buf,
- void *UNUSED(tls_data))
+ void * /*tls_data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
/* Exclusively for edit mode. */
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc
index 049fa416523..6f0c98c684b 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc
@@ -237,7 +237,7 @@ static void extract_tan_ex_init(const MeshRenderData *mr,
static void extract_tan_init(const MeshRenderData *mr,
MeshBatchCache *cache,
void *buf,
- void *UNUSED(tls_data))
+ void * /*tls_data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
extract_tan_ex_init(mr, cache, vbo, false);
@@ -256,7 +256,7 @@ static void extract_tan_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
MeshBatchCache *cache,
void *buffer,
- void *UNUSED(data))
+ void * /*data*/)
{
GPUVertCompType comp_type = GPU_COMP_F32;
GPUVertFetchMode fetch_mode = GPU_FETCH_FLOAT;
@@ -302,7 +302,7 @@ static void extract_tan_init_subdiv(const DRWSubdivCache *subdiv_cache,
/* Ensure data is uploaded properly. */
GPU_vertbuf_tag_dirty(coarse_vbo);
/* Include stride in offset. */
- const int dst_offset = (int)subdiv_cache->num_subdiv_loops * 4 * pack_layer_index++;
+ const int dst_offset = int(subdiv_cache->num_subdiv_loops) * 4 * pack_layer_index++;
draw_subdiv_interp_custom_data(subdiv_cache, coarse_vbo, dst_buffer, 4, dst_offset, false);
}
if (use_orco_tan) {
@@ -317,7 +317,7 @@ static void extract_tan_init_subdiv(const DRWSubdivCache *subdiv_cache,
/* Ensure data is uploaded properly. */
GPU_vertbuf_tag_dirty(coarse_vbo);
/* Include stride in offset. */
- const int dst_offset = (int)subdiv_cache->num_subdiv_loops * 4 * pack_layer_index++;
+ const int dst_offset = int(subdiv_cache->num_subdiv_loops) * 4 * pack_layer_index++;
draw_subdiv_interp_custom_data(subdiv_cache, coarse_vbo, dst_buffer, 4, dst_offset, false);
}
@@ -346,7 +346,7 @@ constexpr MeshExtract create_extractor_tan()
static void extract_tan_hq_init(const MeshRenderData *mr,
MeshBatchCache *cache,
void *buf,
- void *UNUSED(tls_data))
+ void * /*tls_data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
extract_tan_ex_init(mr, cache, vbo, true);
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc
index 6606912850d..fe6e31af3c2 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc
@@ -74,7 +74,7 @@ static bool mesh_extract_uv_format_init(GPUVertFormat *format,
static void extract_uv_init(const MeshRenderData *mr,
MeshBatchCache *cache,
void *buf,
- void *UNUSED(tls_data))
+ void * /*tls_data*/)
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
GPUVertFormat format = {0};
@@ -119,10 +119,10 @@ static void extract_uv_init(const MeshRenderData *mr,
}
static void extract_uv_init_subdiv(const DRWSubdivCache *subdiv_cache,
- const MeshRenderData *UNUSED(mr),
+ const MeshRenderData * /*mr*/,
MeshBatchCache *cache,
void *buffer,
- void *UNUSED(data))
+ void * /*data*/)
{
Mesh *coarse_mesh = subdiv_cache->mesh;
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buffer);
@@ -146,7 +146,7 @@ static void extract_uv_init_subdiv(const DRWSubdivCache *subdiv_cache,
int pack_layer_index = 0;
for (int i = 0; i < MAX_MTFACE; i++) {
if (uv_layers & (1 << i)) {
- const int offset = (int)subdiv_cache->num_subdiv_loops * pack_layer_index++;
+ const int offset = int(subdiv_cache->num_subdiv_loops) * pack_layer_index++;
draw_subdiv_extract_uvs(subdiv_cache, vbo, i, offset);
}
}
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc
index 4db5a8c23a4..6ac498eae26 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc
@@ -111,9 +111,9 @@ static void extract_weights_init(const MeshRenderData *mr,
}
}
-static void extract_weights_iter_poly_bm(const MeshRenderData *UNUSED(mr),
+static void extract_weights_iter_poly_bm(const MeshRenderData * /*mr*/,
const BMFace *f,
- const int UNUSED(f_index),
+ const int /*f_index*/,
void *_data)
{
MeshExtract_Weight_Data *data = static_cast<MeshExtract_Weight_Data *>(_data);
@@ -134,7 +134,7 @@ static void extract_weights_iter_poly_bm(const MeshRenderData *UNUSED(mr),
static void extract_weights_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *mp,
- const int UNUSED(mp_index),
+ const int /*mp_index*/,
void *_data)
{
MeshExtract_Weight_Data *data = static_cast<MeshExtract_Weight_Data *>(_data);
diff --git a/source/blender/draw/intern/shaders/common_debug_print_lib.glsl b/source/blender/draw/intern/shaders/common_debug_print_lib.glsl
index 89d1729b52d..5dc8f490a79 100644
--- a/source/blender/draw/intern/shaders/common_debug_print_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_debug_print_lib.glsl
@@ -21,7 +21,7 @@
*
* NOTE: Floating point representation might not be very precise (see drw_print_value(float)).
*
- * IMPORTANT: Multipler drawcalls can write to the buffer in sequence (if they are from different
+ * IMPORTANT: Multiple drawcalls can write to the buffer in sequence (if they are from different
* shgroups). However, we add barriers to support this case and it might change the application
* behavior. Uncomment DISABLE_DEBUG_SHADER_drw_print_BARRIER to remove the barriers if that
* happens. But then you are limited to a single invocation output.
@@ -92,7 +92,7 @@ void drw_print_char4(uint data)
* it is referenced as an index for char4 and thus do not capture the right
* reference. I do not know if this is undefined behavior. As a matter of
* precaution, we implement all the append function separately. This behavior
- * was observed on both Mesa & amdgpu-pro.
+ * was observed on both MESA & AMDGPU-PRO.
*/
/* Using ascii char code. Expect char1 to be less or equal to 0xFF. Appends chars to the right. */
void drw_print_append_char(uint char1, inout uint char4)
diff --git a/source/blender/draw/intern/shaders/common_fxaa_lib.glsl b/source/blender/draw/intern/shaders/common_fxaa_lib.glsl
index 599d875c500..3d8667e88c8 100644
--- a/source/blender/draw/intern/shaders/common_fxaa_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_fxaa_lib.glsl
@@ -312,7 +312,7 @@ float FxaaLuma(vec4 rgba)
/*--------------------------------------------------------------------------*/
vec4 FxaaPixelShader(
/*
- * Use noperspective interpolation here (turn off perspective interpolation).
+ * Use no perspective interpolation here (turn off perspective interpolation).
* {xy} = center of pixel */
vec2 pos,
/*
diff --git a/source/blender/draw/intern/shaders/common_globals_lib.glsl b/source/blender/draw/intern/shaders/common_globals_lib.glsl
deleted file mode 100644
index a8931292064..00000000000
--- a/source/blender/draw/intern/shaders/common_globals_lib.glsl
+++ /dev/null
@@ -1,148 +0,0 @@
-#define COMMON_GLOBALS_LIB
-
-#ifdef USE_GPU_SHADER_CREATE_INFO
-# error Use draw_globals as additional_info instead of common_globals_lib.glsl
-#endif
-
-/* keep in sync with GlobalsUboStorage */
-layout(std140) uniform globalsBlock
-{
- vec4 colorWire;
- vec4 colorWireEdit;
- vec4 colorActive;
- vec4 colorSelect;
- vec4 colorLibrarySelect;
- vec4 colorLibrary;
- vec4 colorTransform;
- vec4 colorLight;
- vec4 colorSpeaker;
- vec4 colorCamera;
- vec4 colorCameraPath;
- vec4 colorEmpty;
- vec4 colorVertex;
- vec4 colorVertexSelect;
- vec4 colorVertexUnreferenced;
- vec4 colorVertexMissingData;
- vec4 colorEditMeshActive;
- vec4 colorEdgeSelect;
- vec4 colorEdgeSeam;
- vec4 colorEdgeSharp;
- vec4 colorEdgeCrease;
- vec4 colorEdgeBWeight;
- vec4 colorEdgeFaceSelect;
- vec4 colorEdgeFreestyle;
- vec4 colorFace;
- vec4 colorFaceSelect;
- vec4 colorFaceFreestyle;
- vec4 colorGpencilVertex;
- vec4 colorGpencilVertexSelect;
- vec4 colorNormal;
- vec4 colorVNormal;
- vec4 colorLNormal;
- vec4 colorFaceDot;
- vec4 colorSkinRoot;
- vec4 colorDeselect;
- vec4 colorOutline;
- vec4 colorLightNoAlpha;
-
- vec4 colorBackground;
- vec4 colorBackgroundGradient;
- vec4 colorCheckerPrimary;
- vec4 colorCheckerSecondary;
- vec4 colorClippingBorder;
- vec4 colorEditMeshMiddle;
-
- vec4 colorHandleFree;
- vec4 colorHandleAuto;
- vec4 colorHandleVect;
- vec4 colorHandleAlign;
- vec4 colorHandleAutoclamp;
- vec4 colorHandleSelFree;
- vec4 colorHandleSelAuto;
- vec4 colorHandleSelVect;
- vec4 colorHandleSelAlign;
- vec4 colorHandleSelAutoclamp;
- vec4 colorNurbUline;
- vec4 colorNurbVline;
- vec4 colorNurbSelUline;
- vec4 colorNurbSelVline;
- vec4 colorActiveSpline;
-
- vec4 colorBonePose;
- vec4 colorBonePoseActive;
- vec4 colorBonePoseActiveUnsel;
- vec4 colorBonePoseConstraint;
- vec4 colorBonePoseIK;
- vec4 colorBonePoseSplineIK;
- vec4 colorBonePoseTarget;
- vec4 colorBoneSolid;
- vec4 colorBoneLocked;
- vec4 colorBoneActive;
- vec4 colorBoneActiveUnsel;
- vec4 colorBoneSelect;
- vec4 colorBoneIKLine;
- vec4 colorBoneIKLineNoTarget;
- vec4 colorBoneIKLineSpline;
-
- vec4 colorText;
- vec4 colorTextHi;
-
- vec4 colorBundleSolid;
-
- vec4 colorMballRadius;
- vec4 colorMballRadiusSelect;
- vec4 colorMballStiffness;
- vec4 colorMballStiffnessSelect;
-
- vec4 colorCurrentFrame;
-
- vec4 colorGrid;
- vec4 colorGridEmphasis;
- vec4 colorGridAxisX;
- vec4 colorGridAxisY;
- vec4 colorGridAxisZ;
-
- vec4 colorFaceBack;
- vec4 colorFaceFront;
-
- vec4 colorUVShadow;
-
- vec4 screenVecs[2];
- vec4 sizeViewport; /* Inverted size in zw. */
-
- float sizePixel; /* This one is for DPI scaling. */
- float pixelFac; /* To use with mul_project_m4_v3_zfac() */
- float sizeObjectCenter;
- float sizeLightCenter;
- float sizeLightCircle;
- float sizeLightCircleShadow;
- float sizeVertex;
- float sizeEdge;
- float sizeEdgeFix;
- float sizeFaceDot;
- float sizeChecker;
- float sizeVertexGpencil;
-};
-
-#define sizeViewportInv (sizeViewport.zw)
-
-/* See: 'draw_cache_impl.h' for matching includes. */
-#define VERT_GPENCIL_BEZT_HANDLE (1 << 30)
-/* data[0] (1st byte flags) */
-#define FACE_ACTIVE (1 << 0)
-#define FACE_SELECTED (1 << 1)
-#define FACE_FREESTYLE (1 << 2)
-#define VERT_UV_SELECT (1 << 3)
-#define VERT_UV_PINNED (1 << 4)
-#define EDGE_UV_SELECT (1 << 5)
-#define FACE_UV_ACTIVE (1 << 6)
-#define FACE_UV_SELECT (1 << 7)
-/* data[1] (2st byte flags) */
-#define VERT_ACTIVE (1 << 0)
-#define VERT_SELECTED (1 << 1)
-#define VERT_SELECTED_BEZT_HANDLE (1 << 2)
-#define EDGE_ACTIVE (1 << 3)
-#define EDGE_SELECTED (1 << 4)
-#define EDGE_SEAM (1 << 5)
-#define EDGE_SHARP (1 << 6)
-#define EDGE_FREESTYLE (1 << 7)
diff --git a/source/blender/draw/intern/shaders/common_gpencil_lib.glsl b/source/blender/draw/intern/shaders/common_gpencil_lib.glsl
index 123c493b572..def841b07aa 100644
--- a/source/blender/draw/intern/shaders/common_gpencil_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_gpencil_lib.glsl
@@ -90,10 +90,15 @@ float gpencil_clamp_small_stroke_thickness(float thickness, vec4 ndc_pos)
#ifdef GPU_VERTEX_SHADER
-/* Trick to detect if a drawcall is stroke or fill.
- * This does mean that we need to draw an empty stroke segment before starting
- * to draw the real stroke segments. */
-# define GPENCIL_IS_STROKE_VERTEX (gl_InstanceID != 0)
+int gpencil_stroke_point_id()
+{
+ return (gl_VertexID & ~GP_IS_STROKE_VERTEX_BIT) >> GP_VERTEX_ID_SHIFT;
+}
+
+bool gpencil_is_stroke_vertex()
+{
+ return flag_test(gl_VertexID, GP_IS_STROKE_VERTEX_BIT);
+}
/**
* Returns value of gl_Position.
@@ -120,20 +125,7 @@ float gpencil_clamp_small_stroke_thickness(float thickness, vec4 ndc_pos)
* WARNING: Max attribute count is actually 14 because OSX OpenGL implementation
* considers gl_VertexID and gl_InstanceID as vertex attribute. (see T74536)
*/
-vec4 gpencil_vertex(ivec4 ma,
- ivec4 ma1,
- ivec4 ma2,
- ivec4 ma3,
- vec4 pos,
- vec4 pos1,
- vec4 pos2,
- vec4 pos3,
- vec4 uv1,
- vec4 uv2,
- vec4 col1,
- vec4 col2,
- vec4 fcol1,
- vec4 viewport_size,
+vec4 gpencil_vertex(vec4 viewport_size,
gpMaterialFlag material_flags,
vec2 alignment_rot,
/* World Position. */
@@ -155,6 +147,24 @@ vec4 gpencil_vertex(ivec4 ma,
/* Stroke hardness. */
out float out_hardness)
{
+ int stroke_point_id = (gl_VertexID & ~GP_IS_STROKE_VERTEX_BIT) >> GP_VERTEX_ID_SHIFT;
+
+ /* Attribute Loading. */
+ vec4 pos = texelFetch(gp_pos_tx, (stroke_point_id - 1) * 3 + 0);
+ vec4 pos1 = texelFetch(gp_pos_tx, (stroke_point_id + 0) * 3 + 0);
+ vec4 pos2 = texelFetch(gp_pos_tx, (stroke_point_id + 1) * 3 + 0);
+ vec4 pos3 = texelFetch(gp_pos_tx, (stroke_point_id + 2) * 3 + 0);
+ ivec4 ma = floatBitsToInt(texelFetch(gp_pos_tx, (stroke_point_id - 1) * 3 + 1));
+ ivec4 ma1 = floatBitsToInt(texelFetch(gp_pos_tx, (stroke_point_id + 0) * 3 + 1));
+ ivec4 ma2 = floatBitsToInt(texelFetch(gp_pos_tx, (stroke_point_id + 1) * 3 + 1));
+ ivec4 ma3 = floatBitsToInt(texelFetch(gp_pos_tx, (stroke_point_id + 2) * 3 + 1));
+ vec4 uv1 = texelFetch(gp_pos_tx, (stroke_point_id + 0) * 3 + 2);
+ vec4 uv2 = texelFetch(gp_pos_tx, (stroke_point_id + 1) * 3 + 2);
+
+ vec4 col1 = texelFetch(gp_col_tx, (stroke_point_id + 0) * 2 + 0);
+ vec4 col2 = texelFetch(gp_col_tx, (stroke_point_id + 1) * 2 + 0);
+ vec4 fcol1 = texelFetch(gp_col_tx, (stroke_point_id + 0) * 2 + 1);
+
# define thickness1 pos1.w
# define thickness2 pos2.w
# define strength1 uv1.w
@@ -167,7 +177,7 @@ vec4 gpencil_vertex(ivec4 ma,
vec4 out_ndc;
- if (GPENCIL_IS_STROKE_VERTEX) {
+ if (gpencil_is_stroke_vertex()) {
bool is_dot = flag_test(material_flags, GP_STROKE_ALIGNMENT);
bool is_squares = !flag_test(material_flags, GP_STROKE_DOTS);
@@ -177,13 +187,6 @@ vec4 gpencil_vertex(ivec4 ma,
is_squares = false;
}
- /* Endpoints, we discard the vertices. */
- if (ma1.x == -1 || (!is_dot && ma2.x == -1)) {
- /* We set the vertex at the camera origin to generate 0 fragments. */
- out_ndc = vec4(0.0, 0.0, -3e36, 0.0);
- return out_ndc;
- }
-
/* Avoid using a vertex attribute for quad positioning. */
float x = float(gl_VertexID & 1) * 2.0 - 1.0; /* [-1..1] */
float y = float(gl_VertexID & 2) - 1.0; /* [-1..1] */
@@ -336,8 +339,7 @@ vec4 gpencil_vertex(ivec4 ma,
out_N = safe_normalize(N);
/* Decode fill opacity. */
- out_color = vec4(fcol1.rgb, floor(fcol1.a / 10.0));
- out_color.a /= 10000.0;
+ out_color = vec4(fcol1.rgb, floor(fcol1.a / 10.0) / 10000.0);
/* We still offset the fills a little to avoid overlaps */
out_ndc.z += 0.000002;
@@ -355,20 +357,7 @@ vec4 gpencil_vertex(ivec4 ma,
return out_ndc;
}
-vec4 gpencil_vertex(ivec4 ma,
- ivec4 ma1,
- ivec4 ma2,
- ivec4 ma3,
- vec4 pos,
- vec4 pos1,
- vec4 pos2,
- vec4 pos3,
- vec4 uv1,
- vec4 uv2,
- vec4 col1,
- vec4 col2,
- vec4 fcol1,
- vec4 viewport_size,
+vec4 gpencil_vertex(vec4 viewport_size,
out vec3 out_P,
out vec3 out_N,
out vec4 out_color,
@@ -379,20 +368,7 @@ vec4 gpencil_vertex(ivec4 ma,
out vec2 out_thickness,
out float out_hardness)
{
- return gpencil_vertex(ma,
- ma1,
- ma2,
- ma3,
- pos,
- pos1,
- pos2,
- pos3,
- uv1,
- uv2,
- col1,
- col2,
- fcol1,
- viewport_size,
+ return gpencil_vertex(viewport_size,
0u,
vec2(1.0, 0.0),
out_P,
diff --git a/source/blender/draw/intern/shaders/common_intersect_lib.glsl b/source/blender/draw/intern/shaders/common_intersect_lib.glsl
index 83223f89277..d1416e220a4 100644
--- a/source/blender/draw/intern/shaders/common_intersect_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_intersect_lib.glsl
@@ -135,7 +135,7 @@ bool intersect_view(Pyramid pyramid)
for (int p = 0; p < 6; ++p) {
bool is_any_vertex_on_positive_side = false;
for (int v = 0; v < 5; ++v) {
- float test = dot(drw_view.frustum_planes[p], vec4(pyramid.corners[v], 1.0));
+ float test = dot(drw_view_culling.planes[p], vec4(pyramid.corners[v], 1.0));
if (test > 0.0) {
is_any_vertex_on_positive_side = true;
break;
@@ -157,7 +157,7 @@ bool intersect_view(Pyramid pyramid)
for (int p = 0; p < 5; ++p) {
bool is_any_vertex_on_positive_side = false;
for (int v = 0; v < 8; ++v) {
- float test = dot(i_pyramid.planes[p], vec4(drw_view.frustum_corners[v].xyz, 1.0));
+ float test = dot(i_pyramid.planes[p], vec4(drw_view_culling.corners[v].xyz, 1.0));
if (test > 0.0) {
is_any_vertex_on_positive_side = true;
break;
@@ -180,7 +180,7 @@ bool intersect_view(Box box)
for (int p = 0; p < 6; ++p) {
bool is_any_vertex_on_positive_side = false;
for (int v = 0; v < 8; ++v) {
- float test = dot(drw_view.frustum_planes[p], vec4(box.corners[v], 1.0));
+ float test = dot(drw_view_culling.planes[p], vec4(box.corners[v], 1.0));
if (test > 0.0) {
is_any_vertex_on_positive_side = true;
break;
@@ -202,7 +202,7 @@ bool intersect_view(Box box)
for (int p = 0; p < 6; ++p) {
bool is_any_vertex_on_positive_side = false;
for (int v = 0; v < 8; ++v) {
- float test = dot(i_box.planes[p], vec4(drw_view.frustum_corners[v].xyz, 1.0));
+ float test = dot(i_box.planes[p], vec4(drw_view_culling.corners[v].xyz, 1.0));
if (test > 0.0) {
is_any_vertex_on_positive_side = true;
break;
@@ -226,7 +226,7 @@ bool intersect_view(IsectBox i_box)
for (int p = 0; p < 6; ++p) {
bool is_any_vertex_on_positive_side = false;
for (int v = 0; v < 8; ++v) {
- float test = dot(drw_view.frustum_planes[p], vec4(i_box.corners[v], 1.0));
+ float test = dot(drw_view_culling.planes[p], vec4(i_box.corners[v], 1.0));
if (test > 0.0) {
is_any_vertex_on_positive_side = true;
break;
@@ -246,7 +246,7 @@ bool intersect_view(IsectBox i_box)
for (int p = 0; p < 6; ++p) {
bool is_any_vertex_on_positive_side = false;
for (int v = 0; v < 8; ++v) {
- float test = dot(i_box.planes[p], vec4(drw_view.frustum_corners[v].xyz, 1.0));
+ float test = dot(i_box.planes[p], vec4(drw_view_culling.corners[v].xyz, 1.0));
if (test > 0.0) {
is_any_vertex_on_positive_side = true;
break;
@@ -267,7 +267,7 @@ bool intersect_view(Sphere sphere)
bool intersects = true;
for (int p = 0; p < 6 && intersects; ++p) {
- float dist_to_plane = dot(drw_view.frustum_planes[p], vec4(sphere.center, 1.0));
+ float dist_to_plane = dot(drw_view_culling.planes[p], vec4(sphere.center, 1.0));
if (dist_to_plane < -sphere.radius) {
intersects = false;
}
diff --git a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl
index dd725ad327f..8725e036435 100644
--- a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl
@@ -2,16 +2,10 @@
/* NOTE: To be used with UNIFORM_RESOURCE_ID and INSTANCED_ATTR as define. */
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
-#ifndef DRW_SHADER_SHARED_H
-
-in vec4 pos; /* Position and radius. */
-
-/* ---- Instanced attribs ---- */
-
-in vec3 pos_inst;
-in vec3 nor;
-
-#endif
+int pointcloud_get_point_id()
+{
+ return gl_VertexID / 32;
+}
mat3 pointcloud_get_facing_matrix(vec3 p)
{
@@ -25,8 +19,10 @@ mat3 pointcloud_get_facing_matrix(vec3 p)
/* Returns world center position and radius. */
void pointcloud_get_pos_and_radius(out vec3 outpos, out float outradius)
{
- outpos = point_object_to_world(pos.xyz);
- outradius = dot(abs(mat3(ModelMatrix) * pos.www), vec3(1.0 / 3.0));
+ int id = pointcloud_get_point_id();
+ vec4 pos_rad = texelFetch(ptcloud_pos_rad_tx, id);
+ outpos = point_object_to_world(pos_rad.xyz);
+ outradius = dot(abs(mat3(ModelMatrix) * pos_rad.www), vec3(1.0 / 3.0));
}
/* Return world position and normal. */
@@ -38,15 +34,67 @@ void pointcloud_get_pos_and_nor(out vec3 outpos, out vec3 outnor)
mat3 facing_mat = pointcloud_get_facing_matrix(p);
+ /** \note: Avoid modulo by non-power-of-two in shader. See Index buffer setup. */
+ int vert_id = gl_VertexID % 32;
+ vec3 pos_inst = vec3(0.0);
+
+ switch (vert_id) {
+ case 0:
+ pos_inst.z = 1.0;
+ break;
+ case 1:
+ pos_inst.x = 1.0;
+ break;
+ case 2:
+ pos_inst.y = 1.0;
+ break;
+ case 3:
+ pos_inst.x = -1.0;
+ break;
+ case 4:
+ pos_inst.y = -1.0;
+ break;
+ }
+
/* TODO(fclem): remove multiplication here. Here only for keeping the size correct for now. */
radius *= 0.01;
- outpos = p + (facing_mat * pos_inst) * radius;
- outnor = facing_mat * nor;
+ outnor = facing_mat * pos_inst;
+ outpos = p + outnor * radius;
}
-vec3 pointcloud_get_pos(void)
+vec3 pointcloud_get_pos()
{
vec3 outpos, outnor;
pointcloud_get_pos_and_nor(outpos, outnor);
return outpos;
}
+
+float pointcloud_get_customdata_float(const samplerBuffer cd_buf)
+{
+ int id = pointcloud_get_point_id();
+ return texelFetch(cd_buf, id).r;
+}
+
+vec2 pointcloud_get_customdata_vec2(const samplerBuffer cd_buf)
+{
+ int id = pointcloud_get_point_id();
+ return texelFetch(cd_buf, id).rg;
+}
+
+vec3 pointcloud_get_customdata_vec3(const samplerBuffer cd_buf)
+{
+ int id = pointcloud_get_point_id();
+ return texelFetch(cd_buf, id).rgb;
+}
+
+vec4 pointcloud_get_customdata_vec4(const samplerBuffer cd_buf)
+{
+ int id = pointcloud_get_point_id();
+ return texelFetch(cd_buf, id).rgba;
+}
+
+vec2 pointcloud_get_barycentric(void)
+{
+ /* TODO: To be implemented. */
+ return vec2(0.0);
+}
diff --git a/source/blender/draw/intern/shaders/common_shape_lib.glsl b/source/blender/draw/intern/shaders/common_shape_lib.glsl
index f2c8bf0faaf..56722c417aa 100644
--- a/source/blender/draw/intern/shaders/common_shape_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_shape_lib.glsl
@@ -188,7 +188,7 @@ Frustum shape_frustum(vec3 corners[8])
/** \name Cone
* \{ */
-/* Cone at orign with no height. */
+/* Cone at origin with no height. */
struct Cone {
vec3 direction;
float angle_cos;
diff --git a/source/blender/draw/intern/shaders/common_smaa_lib.glsl b/source/blender/draw/intern/shaders/common_smaa_lib.glsl
index dbc4c998b34..0c040c9acfe 100644
--- a/source/blender/draw/intern/shaders/common_smaa_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_smaa_lib.glsl
@@ -588,15 +588,18 @@ SamplerState PointSampler
# else
# define mad(a, b, c) (a * b + c)
# endif
-# define float2 vec2
-# define float3 vec3
-# define float4 vec4
-# define int2 ivec2
-# define int3 ivec3
-# define int4 ivec4
-# define bool2 bvec2
-# define bool3 bvec3
-# define bool4 bvec4
+/* NOTE(Metal): Types already natively declared in MSL. */
+# ifndef GPU_METAL
+# define float2 vec2
+# define float3 vec3
+# define float4 vec4
+# define int2 ivec2
+# define int3 ivec3
+# define int4 ivec4
+# define bool2 bvec2
+# define bool3 bvec3
+# define bool4 bvec4
+# endif
#endif
/* clang-format off */
@@ -658,7 +661,14 @@ void SMAAMovc(bool4 cond, inout float4 variable, float4 value)
/**
* Edge Detection Vertex Shader
*/
+# ifdef GPU_METAL
+/* NOTE: Metal API requires explicit address space qualifiers for pointer types.
+ * Arrays in functions are passed as pointers, and thus require explicit address
+ * space. */
+void SMAAEdgeDetectionVS(float2 texcoord, thread float4 *offset)
+# else
void SMAAEdgeDetectionVS(float2 texcoord, out float4 offset[3])
+# endif
{
offset[0] = mad(SMAA_RT_METRICS.xyxy, float4(-1.0, 0.0, 0.0, -1.0), texcoord.xyxy);
offset[1] = mad(SMAA_RT_METRICS.xyxy, float4(1.0, 0.0, 0.0, 1.0), texcoord.xyxy);
@@ -668,7 +678,16 @@ void SMAAEdgeDetectionVS(float2 texcoord, out float4 offset[3])
/**
* Blend Weight Calculation Vertex Shader
*/
+# ifdef GPU_METAL
+/* NOTE: Metal API requires explicit address space qualifiers for pointer types.
+ * Arrays in functions are passed as pointers, and thus require explicit address
+ * space. */
+void SMAABlendingWeightCalculationVS(float2 texcoord,
+ thread float2 &pixcoord,
+ thread float4 *offset)
+# else
void SMAABlendingWeightCalculationVS(float2 texcoord, out float2 pixcoord, out float4 offset[3])
+# endif
{
pixcoord = texcoord * SMAA_RT_METRICS.zw;
diff --git a/source/blender/draw/intern/shaders/common_view_clipping_lib.glsl b/source/blender/draw/intern/shaders/common_view_clipping_lib.glsl
index d6dfa326511..4ff6a9a3778 100644
--- a/source/blender/draw/intern/shaders/common_view_clipping_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_view_clipping_lib.glsl
@@ -7,12 +7,12 @@ void view_clipping_distances(vec3 wpos)
{
# ifdef USE_WORLD_CLIP_PLANES
vec4 pos_4d = vec4(wpos, 1.0);
- gl_ClipDistance[0] = dot(drw_view.clip_planes[0], pos_4d);
- gl_ClipDistance[1] = dot(drw_view.clip_planes[1], pos_4d);
- gl_ClipDistance[2] = dot(drw_view.clip_planes[2], pos_4d);
- gl_ClipDistance[3] = dot(drw_view.clip_planes[3], pos_4d);
- gl_ClipDistance[4] = dot(drw_view.clip_planes[4], pos_4d);
- gl_ClipDistance[5] = dot(drw_view.clip_planes[5], pos_4d);
+ gl_ClipDistance[0] = dot(drw_clipping[0], pos_4d);
+ gl_ClipDistance[1] = dot(drw_clipping[1], pos_4d);
+ gl_ClipDistance[2] = dot(drw_clipping[2], pos_4d);
+ gl_ClipDistance[3] = dot(drw_clipping[3], pos_4d);
+ gl_ClipDistance[4] = dot(drw_clipping[4], pos_4d);
+ gl_ClipDistance[5] = dot(drw_clipping[5], pos_4d);
# endif
}
diff --git a/source/blender/draw/intern/shaders/common_view_lib.glsl b/source/blender/draw/intern/shaders/common_view_lib.glsl
index 6521476c3a7..90c1e0490b8 100644
--- a/source/blender/draw/intern/shaders/common_view_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_view_lib.glsl
@@ -11,22 +11,10 @@
/* keep in sync with DRWManager.view_data */
layout(std140) uniform viewBlock
{
- /* Same order as DRWViewportMatrixType */
- mat4 ViewProjectionMatrix;
- mat4 ViewProjectionMatrixInverse;
mat4 ViewMatrix;
mat4 ViewMatrixInverse;
mat4 ProjectionMatrix;
mat4 ProjectionMatrixInverse;
-
- vec4 clipPlanes[6];
-
- /* View frustum corners [NDC(-1.0, -1.0, -1.0) & NDC(1.0, 1.0, 1.0)].
- * Fourth components are near and far values. */
- vec4 ViewVecs[2];
-
- /* TODO: move it elsewhere. */
- vec4 CameraTexCoFactors;
};
#endif /* USE_GPU_SHADER_CREATE_INFO */
@@ -37,12 +25,10 @@ layout(std140) uniform viewBlock
# endif
#endif
-#define IS_DEBUG_MOUSE_FRAGMENT (ivec2(gl_FragCoord) == drw_view.mouse_pixel)
+/* Not supported anymore. TODO(fclem): Add back support. */
+// #define IS_DEBUG_MOUSE_FRAGMENT (ivec2(gl_FragCoord) == drw_view.mouse_pixel)
#define IS_FIRST_INVOCATION (gl_GlobalInvocationID == uvec3(0))
-#define ViewNear (ViewVecs[0].w)
-#define ViewFar (ViewVecs[1].w)
-
#define cameraForward ViewMatrixInverse[2].xyz
#define cameraPos ViewMatrixInverse[3].xyz
vec3 cameraVec(vec3 P)
@@ -51,18 +37,13 @@ vec3 cameraVec(vec3 P)
}
#define viewCameraVec(vP) ((ProjectionMatrix[3][3] == 0.0) ? normalize(-vP) : vec3(0.0, 0.0, 1.0))
-#ifdef world_clip_planes_calc_clip_distance
-# undef world_clip_planes_calc_clip_distance
-# define world_clip_planes_calc_clip_distance(p) \
- _world_clip_planes_calc_clip_distance(p, clipPlanes)
-#endif
-
#ifdef COMMON_GLOBALS_LIB
/* TODO move to overlay engine. */
float mul_project_m4_v3_zfac(in vec3 co)
{
- return pixelFac * ((ViewProjectionMatrix[0][3] * co.x) + (ViewProjectionMatrix[1][3] * co.y) +
- (ViewProjectionMatrix[2][3] * co.z) + ViewProjectionMatrix[3][3]);
+ vec3 vP = (ViewMatrix * vec4(co, 1.0)).xyz;
+ return pixelFac * ((ProjectionMatrix[0][3] * vP.x) + (ProjectionMatrix[1][3] * vP.y) +
+ (ProjectionMatrix[2][3] * vP.z) + ProjectionMatrix[3][3]);
}
#endif
@@ -93,7 +74,7 @@ vec4 pack_line_data(vec2 frag_co, vec2 edge_start, vec2 edge_pos)
edge /= len;
vec2 perp = vec2(-edge.y, edge.x);
float dist = dot(perp, frag_co - edge_start);
- /* Add 0.1 to diffenrentiate with cleared pixels. */
+ /* Add 0.1 to differentiate with cleared pixels. */
return vec4(perp * 0.5 + 0.5, dist * 0.25 + 0.5 + 0.1, 1.0);
}
else {
@@ -228,7 +209,7 @@ layout(std140) uniform modelBlock
# ifndef USE_GPU_SHADER_CREATE_INFO
/* Intel GPU seems to suffer performance impact when the model matrix is in UBO storage.
* So for now we just force using the legacy path. */
-/* Note that this is also a workaround of a problem on osx (amd or nvidia)
+/* Note that this is also a workaround of a problem on OSX (AMD or NVIDIA)
* and older amd driver on windows. */
uniform mat4 ModelMatrix;
uniform mat4 ModelMatrixInverse;
@@ -267,13 +248,14 @@ uniform mat4 ModelMatrixInverse;
#define normal_world_to_view(n) (mat3(ViewMatrix) * n)
#define normal_view_to_world(n) (mat3(ViewMatrixInverse) * n)
-#define point_object_to_ndc(p) (ViewProjectionMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0))
+#define point_object_to_ndc(p) \
+ (ProjectionMatrix * (ViewMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0)))
#define point_object_to_view(p) ((ViewMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0)).xyz)
#define point_object_to_world(p) ((ModelMatrix * vec4(p, 1.0)).xyz)
#define point_view_to_ndc(p) (ProjectionMatrix * vec4(p, 1.0))
#define point_view_to_object(p) ((ModelMatrixInverse * (ViewMatrixInverse * vec4(p, 1.0))).xyz)
#define point_view_to_world(p) ((ViewMatrixInverse * vec4(p, 1.0)).xyz)
-#define point_world_to_ndc(p) (ViewProjectionMatrix * vec4(p, 1.0))
+#define point_world_to_ndc(p) (ProjectionMatrix * (ViewMatrix * vec4(p, 1.0)))
#define point_world_to_object(p) ((ModelMatrixInverse * vec4(p, 1.0)).xyz)
#define point_world_to_view(p) ((ViewMatrix * vec4(p, 1.0)).xyz)
@@ -314,24 +296,26 @@ float buffer_depth(bool is_persp, float z, float zf, float zn)
float get_view_z_from_depth(float depth)
{
+ float d = 2.0 * depth - 1.0;
if (ProjectionMatrix[3][3] == 0.0) {
- float d = 2.0 * depth - 1.0;
- return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]);
+ d = -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]);
}
else {
- return ViewVecs[0].z + depth * ViewVecs[1].z;
+ d = (d - ProjectionMatrix[3][2]) / ProjectionMatrix[2][2];
}
+ return d;
}
float get_depth_from_view_z(float z)
{
+ float d;
if (ProjectionMatrix[3][3] == 0.0) {
- float d = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2];
- return d * 0.5 + 0.5;
+ d = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2];
}
else {
- return (z - ViewVecs[0].z) / ViewVecs[1].z;
+ d = ProjectionMatrix[2][2] * z + ProjectionMatrix[3][2];
}
+ return d * 0.5 + 0.5;
}
vec2 get_uvs_from_view(vec3 view)
@@ -342,12 +326,9 @@ vec2 get_uvs_from_view(vec3 view)
vec3 get_view_space_from_depth(vec2 uvcoords, float depth)
{
- if (ProjectionMatrix[3][3] == 0.0) {
- return vec3(ViewVecs[0].xy + uvcoords * ViewVecs[1].xy, 1.0) * get_view_z_from_depth(depth);
- }
- else {
- return ViewVecs[0].xyz + vec3(uvcoords, depth) * ViewVecs[1].xyz;
- }
+ vec3 ndc = vec3(uvcoords, depth) * 2.0 - 1.0;
+ vec4 p = ProjectionMatrixInverse * vec4(ndc, 1.0);
+ return p.xyz / p.w;
}
vec3 get_world_space_from_depth(vec2 uvcoords, float depth)
@@ -355,14 +336,18 @@ vec3 get_world_space_from_depth(vec2 uvcoords, float depth)
return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz;
}
-vec3 get_view_vector_from_screen_uv(vec2 uv)
+vec3 get_view_vector_from_screen_uv(vec2 uvcoords)
{
if (ProjectionMatrix[3][3] == 0.0) {
- return normalize(vec3(ViewVecs[0].xy + uv * ViewVecs[1].xy, 1.0));
- }
- else {
- return vec3(0.0, 0.0, 1.0);
+ vec2 ndc = vec2(uvcoords * 2.0 - 1.0);
+ /* This is the manual inversion of the ProjectionMatrix. */
+ vec3 vV = vec3((-ndc - ProjectionMatrix[2].xy) /
+ vec2(ProjectionMatrix[0][0], ProjectionMatrix[1][1]),
+ -ProjectionMatrix[2][2] - ProjectionMatrix[3][2]);
+ return normalize(vV);
}
+ /* Orthographic case. */
+ return vec3(0.0, 0.0, 1.0);
}
#endif /* COMMON_VIEW_LIB_GLSL */
diff --git a/source/blender/draw/intern/shaders/draw_debug_info.hh b/source/blender/draw/intern/shaders/draw_debug_info.hh
index ce450bb1210..4b5590824ba 100644
--- a/source/blender/draw/intern/shaders/draw_debug_info.hh
+++ b/source/blender/draw/intern/shaders/draw_debug_info.hh
@@ -21,6 +21,7 @@ GPU_SHADER_CREATE_INFO(draw_debug_print_display)
.storage_buf(7, Qualifier::READ, "uint", "drw_debug_print_buf[]")
.vertex_out(draw_debug_print_display_iface)
.fragment_out(0, Type::VEC4, "out_color")
+ .push_constant(Type::VEC2, "viewport_size")
.vertex_source("draw_debug_print_display_vert.glsl")
.fragment_source("draw_debug_print_display_frag.glsl")
.additional_info("draw_view");
diff --git a/source/blender/draw/intern/shaders/draw_debug_print_display_vert.glsl b/source/blender/draw/intern/shaders/draw_debug_print_display_vert.glsl
index cb379056e2b..57f293cc6e8 100644
--- a/source/blender/draw/intern/shaders/draw_debug_print_display_vert.glsl
+++ b/source/blender/draw/intern/shaders/draw_debug_print_display_vert.glsl
@@ -23,7 +23,6 @@ void main()
float char_size = 16.0;
/* Change anchor point to the top left. */
vec2 pos_on_screen = char_size * vec2(col, row) + char_size * 4;
- gl_Position = vec4(
- pos_on_screen * drw_view.viewport_size_inverse * vec2(2.0, -2.0) - vec2(1.0, -1.0), 0, 1);
+ gl_Position = vec4((pos_on_screen / viewport_size) * vec2(2.0, -2.0) - vec2(1.0, -1.0), 0, 1);
gl_PointSize = char_size;
}
diff --git a/source/blender/draw/intern/shaders/draw_object_infos_info.hh b/source/blender/draw/intern/shaders/draw_object_infos_info.hh
index 31fee018fbc..33634fb5fcb 100644
--- a/source/blender/draw/intern/shaders/draw_object_infos_info.hh
+++ b/source/blender/draw/intern/shaders/draw_object_infos_info.hh
@@ -13,11 +13,19 @@ GPU_SHADER_CREATE_INFO(draw_object_infos)
GPU_SHADER_CREATE_INFO(draw_volume_infos)
.typedef_source("draw_shader_shared.h")
- .uniform_buf(2, "VolumeInfos", "drw_volume", Frequency::BATCH);
+ .uniform_buf(3, "VolumeInfos", "drw_volume", Frequency::BATCH);
GPU_SHADER_CREATE_INFO(draw_curves_infos)
.typedef_source("draw_shader_shared.h")
- .uniform_buf(2, "CurvesInfos", "drw_curves", Frequency::BATCH);
+ .uniform_buf(3, "CurvesInfos", "drw_curves", Frequency::BATCH);
+
+GPU_SHADER_CREATE_INFO(draw_layer_attributes)
+ .typedef_source("draw_shader_shared.h")
+ .define("VLATTR_LIB")
+ .uniform_buf(DRW_LAYER_ATTR_UBO_SLOT,
+ "LayerAttribute",
+ "drw_layer_attrs[DRW_RESOURCE_CHUNK_LEN]",
+ Frequency::BATCH);
GPU_SHADER_CREATE_INFO(draw_object_infos_new)
.typedef_source("draw_shader_shared.h")
diff --git a/source/blender/draw/intern/shaders/draw_view_info.hh b/source/blender/draw/intern/shaders/draw_view_info.hh
index c522c607791..23892a39062 100644
--- a/source/blender/draw/intern/shaders/draw_view_info.hh
+++ b/source/blender/draw/intern/shaders/draw_view_info.hh
@@ -45,7 +45,11 @@ GPU_SHADER_CREATE_INFO(draw_resource_handle)
* \{ */
GPU_SHADER_CREATE_INFO(draw_view)
- .uniform_buf(DRW_VIEW_UBO_SLOT, "ViewInfos", "drw_view", Frequency::PASS)
+ .uniform_buf(DRW_VIEW_UBO_SLOT, "ViewMatrices", "drw_view", Frequency::PASS)
+ .typedef_source("draw_shader_shared.h");
+
+GPU_SHADER_CREATE_INFO(draw_view_culling)
+ .uniform_buf(DRW_VIEW_CULLING_UBO_SLOT, "ViewCullingData", "drw_view_culling")
.typedef_source("draw_shader_shared.h");
GPU_SHADER_CREATE_INFO(draw_modelmat)
@@ -71,7 +75,10 @@ GPU_SHADER_CREATE_INFO(draw_modelmat_instanced_attr)
/** \name Draw View
* \{ */
-GPU_SHADER_CREATE_INFO(drw_clipped).define("USE_WORLD_CLIP_PLANES");
+GPU_SHADER_CREATE_INFO(drw_clipped)
+ /* TODO(fclem): Move to engine side. */
+ .uniform_buf(DRW_CLIPPING_UBO_SLOT, "vec4", "drw_clipping[6]", Frequency::PASS)
+ .define("USE_WORLD_CLIP_PLANES");
/** \} */
@@ -105,9 +112,7 @@ GPU_SHADER_CREATE_INFO(draw_hair)
.additional_info("draw_modelmat", "draw_resource_id");
GPU_SHADER_CREATE_INFO(draw_pointcloud)
- .vertex_in(0, Type::VEC4, "pos")
- .vertex_in(1, Type::VEC3, "pos_inst")
- .vertex_in(2, Type::VEC3, "nor")
+ .sampler(0, ImageType::FLOAT_BUFFER, "ptcloud_pos_rad_tx", Frequency::BATCH)
.additional_info("draw_modelmat_instanced_attr", "draw_resource_id_uniform");
GPU_SHADER_CREATE_INFO(draw_volume).additional_info("draw_modelmat", "draw_resource_id_uniform");
@@ -115,26 +120,15 @@ GPU_SHADER_CREATE_INFO(draw_volume).additional_info("draw_modelmat", "draw_resou
GPU_SHADER_CREATE_INFO(draw_gpencil)
.typedef_source("gpencil_shader_shared.h")
.define("DRW_GPENCIL_INFO")
- .vertex_in(0, Type::IVEC4, "ma")
- .vertex_in(1, Type::IVEC4, "ma1")
- .vertex_in(2, Type::IVEC4, "ma2")
- .vertex_in(3, Type::IVEC4, "ma3")
- .vertex_in(4, Type::VEC4, "pos")
- .vertex_in(5, Type::VEC4, "pos1")
- .vertex_in(6, Type::VEC4, "pos2")
- .vertex_in(7, Type::VEC4, "pos3")
- .vertex_in(8, Type::VEC4, "uv1")
- .vertex_in(9, Type::VEC4, "uv2")
- .vertex_in(10, Type::VEC4, "col1")
- .vertex_in(11, Type::VEC4, "col2")
- .vertex_in(12, Type::VEC4, "fcol1")
+ .sampler(0, ImageType::FLOAT_BUFFER, "gp_pos_tx")
+ .sampler(1, ImageType::FLOAT_BUFFER, "gp_col_tx")
/* Per Object */
.push_constant(Type::FLOAT, "gpThicknessScale") /* TODO(fclem): Replace with object info. */
.push_constant(Type::FLOAT, "gpThicknessWorldScale") /* TODO(fclem): Same as above. */
.define("gpThicknessIsScreenSpace", "(gpThicknessWorldScale < 0.0)")
/* Per Layer */
.push_constant(Type::FLOAT, "gpThicknessOffset")
- .additional_info("draw_modelmat", "draw_resource_id_uniform", "draw_object_infos");
+ .additional_info("draw_modelmat", "draw_object_infos");
/** \} */
@@ -160,7 +154,7 @@ GPU_SHADER_CREATE_INFO(draw_visibility_compute)
.storage_buf(1, Qualifier::READ_WRITE, "uint", "visibility_buf[]")
.push_constant(Type::INT, "resource_len")
.compute_source("draw_visibility_comp.glsl")
- .additional_info("draw_view");
+ .additional_info("draw_view", "draw_view_culling");
GPU_SHADER_CREATE_INFO(draw_command_generate)
.do_static_compilation(true)
diff --git a/source/blender/draw/tests/draw_pass_test.cc b/source/blender/draw/tests/draw_pass_test.cc
index 394ca8bd3cf..95ab8fa2ef1 100644
--- a/source/blender/draw/tests/draw_pass_test.cc
+++ b/source/blender/draw/tests/draw_pass_test.cc
@@ -181,12 +181,19 @@ static void test_draw_pass_multi_draw()
pass.draw_procedural(GPU_PRIM_LINES, 1, -1, -1, {5});
pass.draw_procedural(GPU_PRIM_POINTS, 6, -1, -1, {5});
pass.draw_procedural(GPU_PRIM_TRIS, 3, -1, -1, {6});
+ /* Custom calls should use their own group and never be batched. */
+ pass.draw_procedural(GPU_PRIM_TRIS, 2, 2, 2, {7});
+ pass.draw_procedural(GPU_PRIM_TRIS, 2, 2, 2, {8});
std::string result = pass.serialize();
std::stringstream expected;
expected << ".test.multi_draw" << std::endl;
expected << " .shader_bind(gpu_shader_3D_image_color)" << std::endl;
expected << " .draw_multi(3)" << std::endl;
+ expected << " .group(id=4, len=2)" << std::endl;
+ expected << " .proto(instance_len=2, resource_id=8, front_face)" << std::endl;
+ expected << " .group(id=3, len=2)" << std::endl;
+ expected << " .proto(instance_len=2, resource_id=7, front_face)" << std::endl;
expected << " .group(id=2, len=1)" << std::endl;
expected << " .proto(instance_len=1, resource_id=5, front_face)" << std::endl;
expected << " .group(id=1, len=15)" << std::endl;
diff --git a/source/blender/draw/tests/shaders_test.cc b/source/blender/draw/tests/shaders_test.cc
index 892fd999fb5..f238c7e25b1 100644
--- a/source/blender/draw/tests/shaders_test.cc
+++ b/source/blender/draw/tests/shaders_test.cc
@@ -17,7 +17,7 @@
#include "engines/eevee/eevee_private.h"
#include "engines/gpencil/gpencil_engine.h"
#include "engines/image/image_private.hh"
-#include "engines/overlay/overlay_private.h"
+#include "engines/overlay/overlay_private.hh"
#include "engines/workbench/workbench_private.h"
#include "intern/draw_shader.h"
@@ -254,6 +254,7 @@ static void test_overlay_glsl_shaders()
EXPECT_NE(OVERLAY_shader_motion_path_line(), nullptr);
EXPECT_NE(OVERLAY_shader_motion_path_vert(), nullptr);
EXPECT_NE(OVERLAY_shader_uniform_color(), nullptr);
+ EXPECT_NE(OVERLAY_shader_uniform_color_pointcloud(), nullptr);
EXPECT_NE(OVERLAY_shader_outline_prepass(false), nullptr);
EXPECT_NE(OVERLAY_shader_outline_prepass(true), nullptr);
EXPECT_NE(OVERLAY_shader_outline_prepass_curves(), nullptr);
@@ -272,6 +273,10 @@ static void test_overlay_glsl_shaders()
EXPECT_NE(OVERLAY_shader_particle_shape(), nullptr);
EXPECT_NE(OVERLAY_shader_sculpt_mask(), nullptr);
EXPECT_NE(OVERLAY_shader_sculpt_curves_selection(), nullptr);
+ EXPECT_NE(OVERLAY_shader_viewer_attribute_curve(), nullptr);
+ EXPECT_NE(OVERLAY_shader_viewer_attribute_curves(), nullptr);
+ EXPECT_NE(OVERLAY_shader_viewer_attribute_mesh(), nullptr);
+ EXPECT_NE(OVERLAY_shader_viewer_attribute_pointcloud(), nullptr);
EXPECT_NE(OVERLAY_shader_volume_velocity(false, false), nullptr);
EXPECT_NE(OVERLAY_shader_volume_velocity(false, true), nullptr);
EXPECT_NE(OVERLAY_shader_volume_velocity(true, false), nullptr);
@@ -360,8 +365,6 @@ static void test_eevee_glsl_shaders_static()
EXPECT_NE(EEVEE_shaders_volumes_integration_sh_get(), nullptr);
EXPECT_NE(EEVEE_shaders_volumes_resolve_sh_get(false), nullptr);
EXPECT_NE(EEVEE_shaders_volumes_resolve_sh_get(true), nullptr);
- EXPECT_NE(EEVEE_shaders_volumes_resolve_comp_sh_get(false), nullptr);
- EXPECT_NE(EEVEE_shaders_volumes_resolve_comp_sh_get(true), nullptr);
EXPECT_NE(EEVEE_shaders_volumes_accum_sh_get(), nullptr);
EXPECT_NE(EEVEE_shaders_studiolight_probe_sh_get(), nullptr);
EXPECT_NE(EEVEE_shaders_studiolight_background_sh_get(), nullptr);
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index b7562073ee7..3a82143cfdf 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -85,7 +85,7 @@
#define ANIM_CHAN_NAME_SIZE 256
/* get the pointer used for some flag */
-#define GET_ACF_FLAG_PTR(ptr, type) ((*(type) = sizeof((ptr))), &(ptr))
+#define GET_ACF_FLAG_PTR(ptr, type) ((*(type) = sizeof(ptr)), &(ptr))
/* *********************************************** */
/* Generic Functions (Type independent) */
@@ -4937,7 +4937,7 @@ static void draw_setting_widget(bAnimContext *ac,
tooltip = TIP_("Grease Pencil layer is visible in the viewport");
}
else {
- tooltip = TIP_("Channels are visible in Graph Editor for editing");
+ tooltip = TIP_("Toggle visibility of Channels in Graph Editor for editing");
}
break;
@@ -4993,7 +4993,7 @@ static void draw_setting_widget(bAnimContext *ac,
}
else if (ale->type == ANIMTYPE_GPLAYER) {
tooltip = TIP_(
- "Shows all keyframes during animation playback and enabled all frames for editing "
+ "Show all keyframes during animation playback and enable all frames for editing "
"(uncheck to use only the current keyframe during animation playback and editing)");
}
else {
@@ -5353,8 +5353,8 @@ void ANIM_channel_draw_widgets(const bContext *C,
* and wouldn't be able to auto-keyframe.
* - Slider should start before the toggles (if they're visible)
* to keep a clean line down the side.
- * - Sliders are always drawn in Shapekey mode now. Prior to this
- * the SACTION_SLIDERS flag would be set when changing into Shapekey mode.
+ * - Sliders are always drawn in Shape-key mode now. Prior to this
+ * the SACTION_SLIDERS flag would be set when changing into shape-key mode.
*/
if (((draw_sliders) && ELEM(ale->type,
ANIMTYPE_FCURVE,
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 06a62b7a9de..e86e1f16e54 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -31,6 +31,7 @@
#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
+#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_mask.h"
#include "BKE_nla.h"
@@ -53,10 +54,9 @@
#include "WM_api.h"
#include "WM_types.h"
-/* ************************************************************************** */
-/* CHANNELS API - Exposed API */
-
-/* -------------------------- Selection ------------------------------------- */
+/* -------------------------------------------------------------------- */
+/** \name Public Channel Selection API
+ * \{ */
void ANIM_set_active_channel(bAnimContext *ac,
void *data,
@@ -462,7 +462,11 @@ void ANIM_anim_channels_select_toggle(bAnimContext *ac)
ANIM_animdata_freelist(&anim_data);
}
-/* ---------------------------- Graph Editor ------------------------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Public Graph Editor API
+ * \{ */
/* Copy a certain channel setting to parents of the modified channel. */
static void anim_flush_channel_setting_up(bAnimContext *ac,
@@ -626,7 +630,11 @@ void ANIM_flush_setting_anim_channels(bAnimContext *ac,
anim_flush_channel_setting_down(ac, setting, mode, match, matchLevel);
}
-/* -------------------------- F-Curves ------------------------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Public F-Curves API
+ * \{ */
void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *fcu)
{
@@ -698,10 +706,11 @@ bool ANIM_remove_empty_action_from_animdata(struct AnimData *adt)
return false;
}
-/* ************************************************************************** */
-/* OPERATORS */
+/** \} */
-/* ****************** Operator Utilities ********************************** */
+/* -------------------------------------------------------------------- */
+/** \name Operator Utilities
+ * \{ */
/* poll callback for being in an Animation Editor channels list region */
static bool animedit_poll_channels_active(bContext *C)
@@ -747,7 +756,11 @@ static bool animedit_poll_channels_nla_tweakmode_off(bContext *C)
return true;
}
-/* ****************** Rearrange Channels Operator ******************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Move (Rearrange) Channels Operator
+ * \{ */
/* constants for channel rearranging */
/* WARNING: don't change existing ones without modifying rearrange func accordingly */
@@ -1580,7 +1593,11 @@ static void ANIM_OT_channels_move(wmOperatorType *ot)
"");
}
-/* ******************** Group Channel Operator ************************ */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Group Channel Operator
+ * \{ */
static bool animchannels_grouping_poll(bContext *C)
{
@@ -1738,7 +1755,11 @@ static void ANIM_OT_channels_group(wmOperatorType *ot)
// RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
}
-/* ----------------------------------------------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Ungroup Channels Operator
+ * \{ */
static int animchannels_ungroup_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1804,7 +1825,11 @@ static void ANIM_OT_channels_ungroup(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ******************** Delete Channel Operator *********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Delete Channel Operator
+ * \{ */
static void tag_update_animation_element(bAnimListElem *ale)
{
@@ -1975,7 +2000,11 @@ static void ANIM_OT_channels_delete(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ********************** Set Flags Operator *********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Set/Toggle Channel Flags Operator Utilities
+ * \{ */
/* defines for setting animation-channel flags */
static const EnumPropertyItem prop_animchannel_setflag_types[] = {
@@ -2222,7 +2251,11 @@ static void ANIM_OT_channels_editable_toggle(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_HIDDEN); /* internal hack - don't expose */
}
-/* ********************** Expand Channels Operator *********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Expand Channels Operator
+ * \{ */
static int animchannels_expand_exec(bContext *C, wmOperator *op)
{
@@ -2267,7 +2300,11 @@ static void ANIM_OT_channels_expand(wmOperatorType *ot)
ot->srna, "all", 1, "All", "Expand all channels (not just selected ones)");
}
-/* ********************** Collapse Channels Operator *********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Collapse Channels Operator
+ * \{ */
static int animchannels_collapse_exec(bContext *C, wmOperator *op)
{
@@ -2312,17 +2349,22 @@ static void ANIM_OT_channels_collapse(wmOperatorType *ot)
ot->srna, "all", true, "All", "Collapse all channels (not just selected ones)");
}
-/* ************ Remove All "Empty" AnimData Blocks Operator ********* */
-/* We define "empty" AnimData blocks here as those which have all 3 of criteria:
- * 1) No active action OR that active actions are empty
- * Assuming that all legitimate entries will have an action,
- * and that empty actions
- * 2) No NLA Tracks + NLA Strips
- * Assuming that users haven't set up any of these as "placeholders"
- * for convenience sake, and that most that exist were either unintentional
- * or are no longer wanted
- * 3) No drivers
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Remove All "Empty" AnimData Blocks Operator
+ *
+ * We define "empty" AnimData blocks here as those which have all 3 of criteria:
+ *
+ * 1) No active action OR that active actions are empty
+ * Assuming that all legitimate entries will have an action,
+ * and that empty actions
+ * 2) No NLA Tracks + NLA Strips
+ * Assuming that users haven't set up any of these as "placeholders"
+ * for convenience sake, and that most that exist were either unintentional
+ * or are no longer wanted
+ * 3) No drivers
+ * \{ */
static int animchannels_clean_empty_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -2421,7 +2463,11 @@ static void ANIM_OT_channels_clean_empty(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ******************* Reenable Disabled Operator ******************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Re-enable Disabled Operator
+ * \{ */
static bool animchannels_enable_poll(bContext *C)
{
@@ -2488,7 +2534,7 @@ static void ANIM_OT_channels_fcurves_enable(wmOperatorType *ot)
/* identifiers */
ot->name = "Revive Disabled F-Curves";
ot->idname = "ANIM_OT_channels_fcurves_enable";
- ot->description = "Clears 'disabled' tag from all F-Curves to get broken F-Curves working again";
+ ot->description = "Clear 'disabled' tag from all F-Curves to get broken F-Curves working again";
/* api callbacks */
ot->exec = animchannels_enable_exec;
@@ -2498,7 +2544,11 @@ static void ANIM_OT_channels_fcurves_enable(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ****************** Select Filter Textbox Operator ******************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Filter Text-box Operator
+ * \{ */
/* XXX: make this generic? */
static bool animchannels_select_filter_poll(bContext *C)
@@ -2571,7 +2621,11 @@ static void ANIM_OT_channels_select_filter(wmOperatorType *ot)
ot->poll = animchannels_select_filter_poll;
}
-/* ********************** Select All Operator *********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select All Operator
+ * \{ */
static int animchannels_selectall_exec(bContext *C, wmOperator *op)
{
@@ -2626,7 +2680,11 @@ static void ANIM_OT_channels_select_all(wmOperatorType *ot)
WM_operator_properties_select_all(ot);
}
-/* ******************** Box Select Operator *********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Box Select Operator
+ * \{ */
static void box_select_anim_channels(bAnimContext *ac, rcti *rect, short selectmode)
{
@@ -2704,8 +2762,6 @@ static void box_select_anim_channels(bAnimContext *ac, rcti *rect, short selectm
ANIM_animdata_freelist(&anim_data);
}
-/* ------------------- */
-
static int animchannels_box_select_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
@@ -2764,8 +2820,13 @@ static void ANIM_OT_channels_select_box(wmOperatorType *ot)
WM_operator_properties_gesture_box_select(ot);
}
-/* ******************* Rename Operator ***************************** */
-/* Allow renaming some channels by clicking on them */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Rename Channel Operator
+ *
+ * Allow renaming some channels by clicking on them.
+ * \{ */
static bool rename_anim_channels(bAnimContext *ac, int channel_index)
{
@@ -2922,7 +2983,12 @@ static void ANIM_OT_channels_rename(wmOperatorType *ot)
ot->poll = animedit_poll_channels_active;
}
-/* ******************** Mouse-Click Operator *********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Channel Keyframes Operator (Internal Logic)
+ * \{ */
+
/* Handle selection changes due to clicking on channels. Settings will get caught by UI code... */
static int click_select_channel_scene(bAnimListElem *ale,
@@ -2953,6 +3019,7 @@ static int click_select_channel_object(bContext *C,
bAnimListElem *ale,
const short /* eEditKeyframes_Select or -1 */ selectmode)
{
+ Scene *scene = ac->scene;
ViewLayer *view_layer = ac->view_layer;
Base *base = (Base *)ale->data;
Object *ob = base->object;
@@ -2971,11 +3038,10 @@ static int click_select_channel_object(bContext *C,
}
}
else {
- Base *b;
-
/* deselect all */
+ BKE_view_layer_synced_ensure(scene, view_layer);
/* TODO: should this deselect all other types of channels too? */
- for (b = view_layer->object_bases.first; b; b = b->next) {
+ LISTBASE_FOREACH (Base *, b, BKE_view_layer_object_bases_get(view_layer)) {
ED_object_base_select(b, BA_DESELECT);
if (b->object->adt) {
b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE);
@@ -3365,9 +3431,13 @@ static int mouse_anim_channels(bContext *C,
return notifierFlags;
}
-/* ------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Channel Keyframes Operator
+ * \{ */
-/* handle clicking */
+/** Handle picking logic. */
static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
@@ -3553,8 +3623,11 @@ static void ANIM_OT_channel_select_keys(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
-/* ************************************************************************** */
-/* Operator Registration */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Operator Registration
+ * \{ */
void ED_operatortypes_animchannels(void)
{
@@ -3595,4 +3668,4 @@ void ED_keymap_animchannels(wmKeyConfig *keyconf)
WM_keymap_ensure(keyconf, "Animation Channels", 0, 0);
}
-/* ************************************************************************** */
+/** \} */
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c
index 06a0077df9b..329bc2b46eb 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -329,6 +329,121 @@ short ANIM_get_normalization_flags(bAnimContext *ac)
return 0;
}
+static void fcurve_scene_coord_range_get(Scene *scene,
+ FCurve *fcu,
+ float *r_min_coord,
+ float *r_max_coord)
+{
+ float min_coord = FLT_MAX;
+ float max_coord = -FLT_MAX;
+ const bool use_preview_only = PRVRANGEON;
+
+ if (fcu->bezt || fcu->fpt) {
+ int start = 0;
+ int end = fcu->totvert;
+
+ if (use_preview_only) {
+ start = scene->r.psfra;
+ end = min_ii(scene->r.pefra + 1, fcu->totvert);
+ }
+
+ if (fcu->bezt) {
+ const BezTriple *bezt = fcu->bezt + start;
+ for (int i = start; i < end; i++, bezt++) {
+
+ if (i == 0) {
+ /* We ignore extrapolation flags and handle here, and use the
+ * control point position only. so we normalize "interesting"
+ * part of the curve.
+ *
+ * Here we handle left extrapolation.
+ */
+ max_coord = max_ff(max_coord, bezt->vec[1][1]);
+ min_coord = min_ff(min_coord, bezt->vec[1][1]);
+ }
+ else {
+ const BezTriple *prev_bezt = bezt - 1;
+ if (!ELEM(prev_bezt->ipo, BEZT_IPO_BEZ, BEZT_IPO_BACK, BEZT_IPO_ELASTIC)) {
+ /* The points on the curve will lie inside the start and end points.
+ * Calculate min/max using both previous and current CV.
+ */
+ max_coord = max_ff(max_coord, bezt->vec[1][1]);
+ min_coord = min_ff(min_coord, bezt->vec[1][1]);
+ max_coord = max_ff(max_coord, prev_bezt->vec[1][1]);
+ min_coord = min_ff(min_coord, prev_bezt->vec[1][1]);
+ }
+ else {
+ const int resol = fcu->driver ?
+ 32 :
+ min_ii((int)(5.0f * len_v2v2(bezt->vec[1], prev_bezt->vec[1])),
+ 32);
+ if (resol < 2) {
+ max_coord = max_ff(max_coord, prev_bezt->vec[1][1]);
+ min_coord = min_ff(min_coord, prev_bezt->vec[1][1]);
+ }
+ else {
+ if (!ELEM(prev_bezt->ipo, BEZT_IPO_BACK, BEZT_IPO_ELASTIC)) {
+ /* Calculate min/max using bezier forward differencing. */
+ float data[120];
+ float v1[2], v2[2], v3[2], v4[2];
+
+ v1[0] = prev_bezt->vec[1][0];
+ v1[1] = prev_bezt->vec[1][1];
+ v2[0] = prev_bezt->vec[2][0];
+ v2[1] = prev_bezt->vec[2][1];
+
+ v3[0] = bezt->vec[0][0];
+ v3[1] = bezt->vec[0][1];
+ v4[0] = bezt->vec[1][0];
+ v4[1] = bezt->vec[1][1];
+
+ BKE_fcurve_correct_bezpart(v1, v2, v3, v4);
+
+ BKE_curve_forward_diff_bezier(
+ v1[0], v2[0], v3[0], v4[0], data, resol, sizeof(float[3]));
+ BKE_curve_forward_diff_bezier(
+ v1[1], v2[1], v3[1], v4[1], data + 1, resol, sizeof(float[3]));
+
+ for (int j = 0; j <= resol; ++j) {
+ const float *fp = &data[j * 3];
+ max_coord = max_ff(max_coord, fp[1]);
+ min_coord = min_ff(min_coord, fp[1]);
+ }
+ }
+ else {
+ /* Calculate min/max using full fcurve evaluation.
+ * [slower than bezier forward differencing but evaluates Back/Elastic
+ * interpolation as well]. */
+ float step_size = (bezt->vec[1][0] - prev_bezt->vec[1][0]) / resol;
+ for (int j = 0; j <= resol; j++) {
+ float eval_time = prev_bezt->vec[1][0] + step_size * j;
+ float eval_value = evaluate_fcurve_only_curve(fcu, eval_time);
+ max_coord = max_ff(max_coord, eval_value);
+ min_coord = min_ff(min_coord, eval_value);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (fcu->fpt) {
+ const FPoint *fpt = fcu->fpt + start;
+ for (int i = start; i < end; ++i, ++fpt) {
+ min_coord = min_ff(min_coord, fpt->vec[1]);
+ max_coord = max_ff(max_coord, fpt->vec[1]);
+ }
+ }
+ }
+
+ if (r_min_coord) {
+ *r_min_coord = min_coord;
+ }
+ if (r_max_coord) {
+ *r_max_coord = max_coord;
+ }
+}
+
static float normalization_factor_get(Scene *scene, FCurve *fcu, short flag, float *r_offset)
{
float factor = 1.0f, offset = 0.0f;
@@ -366,112 +481,23 @@ static float normalization_factor_get(Scene *scene, FCurve *fcu, short flag, flo
}
fcu->prev_norm_factor = 1.0f;
- if (fcu->bezt) {
- const bool use_preview_only = PRVRANGEON;
- const BezTriple *bezt;
- int i;
- float max_coord = -FLT_MAX;
- float min_coord = FLT_MAX;
- float range;
-
- if (fcu->totvert < 1) {
- return 1.0f;
- }
-
- for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
- if (use_preview_only && !IN_RANGE_INCL(bezt->vec[1][0], scene->r.psfra, scene->r.pefra)) {
- continue;
- }
-
- if (i == 0) {
- /* We ignore extrapolation flags and handle here, and use the
- * control point position only. so we normalize "interesting"
- * part of the curve.
- *
- * Here we handle left extrapolation.
- */
- max_coord = max_ff(max_coord, bezt->vec[1][1]);
- min_coord = min_ff(min_coord, bezt->vec[1][1]);
- }
- else {
- const BezTriple *prev_bezt = bezt - 1;
- if (!ELEM(prev_bezt->ipo, BEZT_IPO_BEZ, BEZT_IPO_BACK, BEZT_IPO_ELASTIC)) {
- /* The points on the curve will lie inside the start and end points.
- * Calculate min/max using both previous and current CV.
- */
- max_coord = max_ff(max_coord, bezt->vec[1][1]);
- min_coord = min_ff(min_coord, bezt->vec[1][1]);
- max_coord = max_ff(max_coord, prev_bezt->vec[1][1]);
- min_coord = min_ff(min_coord, prev_bezt->vec[1][1]);
- }
- else {
- const int resol = fcu->driver ?
- 32 :
- min_ii((int)(5.0f * len_v2v2(bezt->vec[1], prev_bezt->vec[1])),
- 32);
- if (resol < 2) {
- max_coord = max_ff(max_coord, prev_bezt->vec[1][1]);
- min_coord = min_ff(min_coord, prev_bezt->vec[1][1]);
- }
- else {
- if (!ELEM(prev_bezt->ipo, BEZT_IPO_BACK, BEZT_IPO_ELASTIC)) {
- /* Calculate min/max using bezier forward differencing. */
- float data[120];
- float v1[2], v2[2], v3[2], v4[2];
-
- v1[0] = prev_bezt->vec[1][0];
- v1[1] = prev_bezt->vec[1][1];
- v2[0] = prev_bezt->vec[2][0];
- v2[1] = prev_bezt->vec[2][1];
-
- v3[0] = bezt->vec[0][0];
- v3[1] = bezt->vec[0][1];
- v4[0] = bezt->vec[1][0];
- v4[1] = bezt->vec[1][1];
-
- BKE_fcurve_correct_bezpart(v1, v2, v3, v4);
-
- BKE_curve_forward_diff_bezier(
- v1[0], v2[0], v3[0], v4[0], data, resol, sizeof(float[3]));
- BKE_curve_forward_diff_bezier(
- v1[1], v2[1], v3[1], v4[1], data + 1, resol, sizeof(float[3]));
-
- for (int j = 0; j <= resol; ++j) {
- const float *fp = &data[j * 3];
- max_coord = max_ff(max_coord, fp[1]);
- min_coord = min_ff(min_coord, fp[1]);
- }
- }
- else {
- /* Calculate min/max using full fcurve evaluation.
- * [slower than bezier forward differencing but evaluates Back/Elastic interpolation
- * as well]. */
- float step_size = (bezt->vec[1][0] - prev_bezt->vec[1][0]) / resol;
- for (int j = 0; j <= resol; j++) {
- float eval_time = prev_bezt->vec[1][0] + step_size * j;
- float eval_value = evaluate_fcurve_only_curve(fcu, eval_time);
- max_coord = max_ff(max_coord, eval_value);
- min_coord = min_ff(min_coord, eval_value);
- }
- }
- }
- }
- }
- }
+ float max_coord = -FLT_MAX;
+ float min_coord = FLT_MAX;
+ fcurve_scene_coord_range_get(scene, fcu, &min_coord, &max_coord);
- if (max_coord > min_coord) {
- range = max_coord - min_coord;
- if (range > FLT_EPSILON) {
- factor = 2.0f / range;
- }
- offset = -min_coord - range / 2.0f;
- }
- else if (max_coord == min_coord) {
- factor = 1.0f;
- offset = -min_coord;
+ if (max_coord > min_coord) {
+ const float range = max_coord - min_coord;
+ if (range > FLT_EPSILON) {
+ factor = 2.0f / range;
}
+ offset = -min_coord - range / 2.0f;
+ }
+ else if (max_coord == min_coord) {
+ factor = 1.0f;
+ offset = -min_coord;
}
+
BLI_assert(factor != 0.0f);
if (r_offset) {
*r_offset = offset;
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 6dc11292a3a..3a04873588d 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -118,10 +118,12 @@ static void animedit_get_yscale_factor(bAnimContext *ac)
/* NOTE: there's a similar function in key.c #BKE_key_from_object. */
static Key *actedit_get_shapekeys(bAnimContext *ac)
{
+ Scene *scene = ac->scene;
ViewLayer *view_layer = ac->view_layer;
Object *ob;
Key *key;
+ BKE_view_layer_synced_ensure(scene, view_layer);
ob = BKE_view_layer_active_object_get(view_layer);
if (ob == NULL) {
return NULL;
@@ -393,12 +395,13 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
/* get useful default context settings from context */
ac->bmain = bmain;
ac->scene = scene;
+ ac->view_layer = CTX_data_view_layer(C);
if (scene) {
ac->markers = ED_context_get_markers(C);
+ BKE_view_layer_synced_ensure(ac->scene, ac->view_layer);
}
- ac->view_layer = CTX_data_view_layer(C);
ac->depsgraph = CTX_data_depsgraph_pointer(C);
- ac->obact = (ac->view_layer->basact) ? ac->view_layer->basact->object : NULL;
+ ac->obact = BKE_view_layer_active_object_get(ac->view_layer);
ac->area = area;
ac->region = region;
ac->sl = sl;
@@ -414,6 +417,11 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
return ANIM_animdata_context_getdata(ac);
}
+bool ANIM_animdata_can_have_greasepencil(const eAnimCont_Types type)
+{
+ return ELEM(type, ANIMCONT_GPENCIL, ANIMCONT_DOPESHEET, ANIMCONT_TIMELINE);
+}
+
/* ************************************************************ */
/* Blender Data <-- Filter --> Channels to be operated on */
@@ -1119,7 +1127,7 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id
/* Check for selected nodes. */
if (fcu->rna_path &&
- (BLI_str_quoted_substr(fcu->rna_path, "nodes[", node_name, sizeof(node_name)))) {
+ BLI_str_quoted_substr(fcu->rna_path, "nodes[", node_name, sizeof(node_name))) {
/* Get strip name, and check if this strip is selected. */
node = nodeFindNodebyName(ntree, node_name);
@@ -1338,7 +1346,7 @@ static size_t animfilter_fcurves(ListBase *anim_data,
* Back to step 2 :)
*/
for (fcu = first;
- ((fcu = animfilter_fcurve_next(ads, fcu, fcurve_type, filter_mode, owner, owner_id)));
+ (fcu = animfilter_fcurve_next(ads, fcu, fcurve_type, filter_mode, owner, owner_id));
fcu = fcu->next) {
if (UNLIKELY(fcurve_type == ANIMTYPE_NLACURVE)) {
/* NLA Control Curve - Basically the same as normal F-Curves,
@@ -1599,7 +1607,7 @@ static size_t animfilter_nla_controls(
/* add control curves from each NLA strip... */
/* NOTE: ANIMTYPE_FCURVES are created here, to avoid duplicating the code needed */
- BEGIN_ANIMFILTER_SUBCHANNELS (((adt->flag & ADT_NLA_SKEYS_COLLAPSED) == 0)) {
+ BEGIN_ANIMFILTER_SUBCHANNELS ((adt->flag & ADT_NLA_SKEYS_COLLAPSED) == 0) {
NlaTrack *nlt;
NlaStrip *strip;
@@ -1846,8 +1854,8 @@ static size_t animdata_filter_gpencil(bAnimContext *ac,
bDopeSheet *ads = ac->ads;
size_t items = 0;
+ Scene *scene = ac->scene;
ViewLayer *view_layer = (ViewLayer *)ac->view_layer;
- Base *base;
/* Include all annotation datablocks. */
if (((ads->filterflag & ADS_FILTER_ONLYSEL) == 0) ||
@@ -1859,7 +1867,8 @@ static size_t animdata_filter_gpencil(bAnimContext *ac,
}
}
/* Objects in the scene */
- for (base = view_layer->object_bases.first; base; base = base->next) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
/* Only consider this object if it has got some GP data (saving on all the other tests) */
if (base->object && (base->object->type == OB_GPENCIL)) {
Object *ob = base->object;
@@ -1888,7 +1897,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac,
}
/* check selection and object type filters */
- if ((ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & BASE_SELECTED))) {
+ if ((ads->filterflag & ADS_FILTER_ONLYSEL) && !(base->flag & BASE_SELECTED)) {
/* only selected should be shown */
continue;
}
@@ -3170,16 +3179,19 @@ static int ds_base_sorting_cmp(const void *base1_ptr, const void *base2_ptr)
/* Get a sorted list of all the bases - for inclusion in dopesheet (when drawing channels) */
static Base **animdata_filter_ds_sorted_bases(bDopeSheet *ads,
+ const Scene *scene,
ViewLayer *view_layer,
int filter_mode,
size_t *r_usable_bases)
{
/* Create an array with space for all the bases, but only containing the usable ones */
- size_t tot_bases = BLI_listbase_count(&view_layer->object_bases);
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ ListBase *object_bases = BKE_view_layer_object_bases_get(view_layer);
+ size_t tot_bases = BLI_listbase_count(object_bases);
size_t num_bases = 0;
Base **sorted_bases = MEM_mallocN(sizeof(Base *) * tot_bases, "Dopesheet Usable Sorted Bases");
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, object_bases) {
if (animdata_filter_base_is_ok(ads, base, OB_MODE_OBJECT, filter_mode)) {
sorted_bases[num_bases++] = base;
}
@@ -3249,14 +3261,17 @@ static size_t animdata_filter_dopesheet(bAnimContext *ac,
* - Don't do this if this behavior has been turned off (i.e. due to it being too slow)
* - Don't do this if there's just a single object
*/
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ ListBase *object_bases = BKE_view_layer_object_bases_get(view_layer);
if ((filter_mode & ANIMFILTER_LIST_CHANNELS) && !(ads->flag & ADS_FLAG_NO_DB_SORT) &&
- (view_layer->object_bases.first != view_layer->object_bases.last)) {
+ (object_bases->first != object_bases->last)) {
/* Filter list of bases (i.e. objects), sort them, then add their contents normally... */
/* TODO: Cache the old sorted order - if the set of bases hasn't changed, don't re-sort... */
Base **sorted_bases;
size_t num_bases;
- sorted_bases = animdata_filter_ds_sorted_bases(ads, view_layer, filter_mode, &num_bases);
+ sorted_bases = animdata_filter_ds_sorted_bases(
+ ads, scene, view_layer, filter_mode, &num_bases);
if (sorted_bases) {
/* Add the necessary channels for these bases... */
for (size_t i = 0; i < num_bases; i++) {
@@ -3275,7 +3290,7 @@ static size_t animdata_filter_dopesheet(bAnimContext *ac,
*/
Object *obact = BKE_view_layer_active_object_get(view_layer);
const eObjectMode object_mode = obact ? obact->mode : OB_MODE_OBJECT;
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, object_bases) {
if (animdata_filter_base_is_ok(ads, base, object_mode, filter_mode)) {
/* since we're still here, this object should be usable */
items += animdata_filter_dopesheet_ob(ac, anim_data, ads, base, filter_mode);
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index f1562fac7ee..94746837259 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -1110,7 +1110,7 @@ static void MARKER_OT_move(wmOperatorType *ot)
RNA_def_int(ot->srna, "frames", 0, INT_MIN, INT_MAX, "Frames", "", INT_MIN, INT_MAX);
PropertyRNA *prop = RNA_def_boolean(
ot->srna, "tweak", 0, "Tweak", "Operator has been activated using a click-drag event");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
}
/** \} */
@@ -1255,14 +1255,14 @@ static int select_timeline_marker_frame(ListBase *markers,
deselect_markers(markers);
}
- LISTBASE_CIRCULAR_FORWARD_BEGIN (markers, marker, marker_cycle_selected) {
+ LISTBASE_CIRCULAR_FORWARD_BEGIN (TimeMarker *, markers, marker, marker_cycle_selected) {
/* this way a not-extend select will always give 1 selected marker */
if (marker->frame == frame) {
marker->flag ^= SELECT;
break;
}
}
- LISTBASE_CIRCULAR_FORWARD_END(markers, marker, marker_cycle_selected);
+ LISTBASE_CIRCULAR_FORWARD_END(TimeMarker *, markers, marker, marker_cycle_selected);
}
return ret_val;
@@ -1281,7 +1281,7 @@ static void select_marker_camera_switch(
int sel = 0;
if (!extend) {
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
}
for (marker = markers->first; marker; marker = marker->next) {
@@ -1291,6 +1291,7 @@ static void select_marker_camera_switch(
}
}
+ BKE_view_layer_synced_ensure(scene, view_layer);
for (marker = markers->first; marker; marker = marker->next) {
if (marker->camera) {
if (marker->frame == cfra) {
@@ -1378,7 +1379,7 @@ static void MARKER_OT_select(wmOperatorType *ot)
ot->modal = WM_generic_select_modal;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_UNDO;
WM_operator_properties_generic_select(ot);
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection");
@@ -1478,7 +1479,7 @@ static void MARKER_OT_select_box(wmOperatorType *ot)
ot->poll = ed_markers_poll_markers_exist;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_UNDO;
/* properties */
WM_operator_properties_gesture_box(ot);
@@ -1602,8 +1603,8 @@ static void MARKER_OT_select_leftright(wmOperatorType *ot)
/* rna storage */
RNA_def_enum(
- ot->srna, "mode", prop_markers_select_leftright_modes, MARKERS_LRSEL_LEFT, "mode", "Mode");
- RNA_def_boolean(ot->srna, "extend", false, "extend", "Extend");
+ ot->srna, "mode", prop_markers_select_leftright_modes, MARKERS_LRSEL_LEFT, "Mode", "");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend Select", "");
}
/** \} */
diff --git a/source/blender/editors/animation/anim_motion_paths.c b/source/blender/editors/animation/anim_motion_paths.c
index 23c1d68b4d6..4a83bb4c800 100644
--- a/source/blender/editors/animation/anim_motion_paths.c
+++ b/source/blender/editors/animation/anim_motion_paths.c
@@ -161,11 +161,11 @@ static void motionpaths_calc_bake_targets(ListBase *targets, int cframe)
}
/* Result must be in world-space. */
- mul_m4_v3(ob_eval->obmat, mpv->co);
+ mul_m4_v3(ob_eval->object_to_world, mpv->co);
}
else {
/* World-space object location. */
- copy_v3_v3(mpv->co, ob_eval->obmat[3]);
+ copy_v3_v3(mpv->co, ob_eval->object_to_world[3]);
}
float mframe = (float)(cframe);
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index 63794caf5a7..f899e41149d 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -322,8 +322,8 @@ int ANIM_add_driver_with_target(ReportList *reports,
* then use the first one */
{
/* Use the shorter of the two (to avoid out of bounds access) */
- int dst_len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr, prop) : 1;
- int src_len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr2, prop2) : 1;
+ int dst_len = RNA_property_array_check(prop) ? RNA_property_array_length(&ptr, prop) : 1;
+ int src_len = RNA_property_array_check(prop) ? RNA_property_array_length(&ptr2, prop2) : 1;
int len = MIN2(dst_len, src_len);
@@ -347,7 +347,7 @@ int ANIM_add_driver_with_target(ReportList *reports,
case CREATEDRIVER_MAPPING_1_N: /* 1-N - Specified target index for all */
default: {
- int len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr, prop) : 1;
+ int len = RNA_property_array_check(prop) ? RNA_property_array_length(&ptr, prop) : 1;
for (int i = 0; i < len; i++) {
done_tot += add_driver_with_target(reports,
@@ -1126,7 +1126,7 @@ void ANIM_OT_driver_button_remove(wmOperatorType *ot)
ot->name = "Remove Driver";
ot->idname = "ANIM_OT_driver_button_remove";
ot->description =
- "Remove the driver(s) for the property(s) connected represented by the highlighted button";
+ "Remove the driver(s) for the connected property(s) represented by the highlighted button";
/* callbacks */
ot->exec = remove_driver_button_exec;
@@ -1163,7 +1163,7 @@ void ANIM_OT_driver_button_edit(wmOperatorType *ot)
ot->name = "Edit Driver";
ot->idname = "ANIM_OT_driver_button_edit";
ot->description =
- "Edit the drivers for the property connected represented by the highlighted button";
+ "Edit the drivers for the connected property represented by the highlighted button";
/* callbacks */
ot->exec = edit_driver_button_exec;
@@ -1257,7 +1257,7 @@ void ANIM_OT_paste_driver_button(wmOperatorType *ot)
/* identifiers */
ot->name = "Paste Driver";
ot->idname = "ANIM_OT_paste_driver_button";
- ot->description = "Paste the driver in the copy/paste buffer for the highlighted button";
+ ot->description = "Paste the driver in the clipboard to the highlighted button";
/* callbacks */
ot->exec = paste_driver_button_exec;
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index 786204a52ed..6df9dc1e86d 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -608,7 +608,7 @@ static AnimKeylistDrawListElem *ed_keylist_draw_list_add_elem(
return draw_elem;
}
-/* *************************** Channel Drawing Funcs *************************** */
+/* *************************** Channel Drawing Functions *************************** */
void draw_summary_channel(struct AnimKeylistDrawList *draw_list,
bAnimContext *ac,
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index 2a94c5db439..7bb104045c3 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -497,7 +497,7 @@ void ANIM_editkeyframes_refresh(bAnimContext *ac)
if (ked && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) { \
/* Only act on visible items, so check handle visibility state. */ \
const bool handles_visible = ((ked->iterflags & KEYFRAME_ITER_HANDLES_DEFAULT_INVISIBLE) ? \
- (BEZT_ISSEL_ANY(bezt)) : \
+ BEZT_ISSEL_ANY(bezt) : \
true); \
if (handles_visible) { \
if (check(0)) { \
@@ -809,7 +809,7 @@ void bezt_remap_times(KeyframeEditData *ked, BezTriple *bezt)
static short snap_bezier_nearest(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
if (bezt->f2 & SELECT) {
- bezt->vec[1][0] = (float)(floorf(bezt->vec[1][0] + 0.5f));
+ bezt->vec[1][0] = (float)floorf(bezt->vec[1][0] + 0.5f);
}
return 0;
}
@@ -1494,7 +1494,7 @@ static short select_bezier_add(KeyframeEditData *ked, BezTriple *bezt)
{
/* Only act on visible items, so check handle visibility state. */
const bool handles_visible = ked && ((ked->iterflags & KEYFRAME_ITER_HANDLES_DEFAULT_INVISIBLE) ?
- (BEZT_ISSEL_ANY(bezt)) :
+ BEZT_ISSEL_ANY(bezt) :
true);
/* if we've got info on what to select, use it, otherwise select all */
@@ -1520,7 +1520,7 @@ static short select_bezier_subtract(KeyframeEditData *ked, BezTriple *bezt)
{
/* Only act on visible items, so check handle visibility state. */
const bool handles_visible = ked && ((ked->iterflags & KEYFRAME_ITER_HANDLES_DEFAULT_INVISIBLE) ?
- (BEZT_ISSEL_ANY(bezt)) :
+ BEZT_ISSEL_ANY(bezt) :
true);
/* if we've got info on what to deselect, use it, otherwise deselect all */
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index 40f0ac59b01..fbe65d6917e 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -151,7 +151,7 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo
* if there is a considerable distance between the points, and also if the
* current is further away than the next one is to the previous.
*/
- if (beztn && (IS_EQT(cur[0], next[0], thresh)) && (IS_EQT(next[1], prev[1], thresh) == 0)) {
+ if (beztn && IS_EQT(cur[0], next[0], thresh) && (IS_EQT(next[1], prev[1], thresh) == 0)) {
/* only add if current is further away from previous */
if (cur[1] > next[1]) {
if (IS_EQT(cur[1], prev[1], thresh) == 0) {
@@ -654,8 +654,8 @@ void sample_fcurve(FCurve *fcu)
* keyframes while sampling will affect the outcome...
* - only start sampling+adding from index=1, so that we don't overwrite original keyframe
*/
- range = (int)(ceil(end->vec[1][0] - start->vec[1][0]));
- sfra = (int)(floor(start->vec[1][0]));
+ range = (int)ceil(end->vec[1][0] - start->vec[1][0]);
+ sfra = (int)floor(start->vec[1][0]);
if (range) {
value_cache = MEM_callocN(sizeof(TempFrameValCache) * range, "IcuFrameValCache");
diff --git a/source/blender/editors/animation/keyframes_keylist.cc b/source/blender/editors/animation/keyframes_keylist.cc
index da266dd4253..9b3cabb6c79 100644
--- a/source/blender/editors/animation/keyframes_keylist.cc
+++ b/source/blender/editors/animation/keyframes_keylist.cc
@@ -1110,7 +1110,7 @@ void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, AnimKeylist *keylist, con
}
}
-void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, AnimKeylist *keylist)
+void gpl_to_keylist(bDopeSheet * /*ads*/, bGPDlayer *gpl, AnimKeylist *keylist)
{
if (gpl && keylist) {
ED_keylist_reset_last_accessed(keylist);
@@ -1124,7 +1124,7 @@ void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, AnimKeylist *keylis
}
}
-void mask_to_keylist(bDopeSheet *UNUSED(ads), MaskLayer *masklay, AnimKeylist *keylist)
+void mask_to_keylist(bDopeSheet * /*ads*/, MaskLayer *masklay, AnimKeylist *keylist)
{
if (masklay && keylist) {
ED_keylist_reset_last_accessed(keylist);
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index acf53541843..96a9604a6f5 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -1044,12 +1044,12 @@ static float *visualkey_get_values(
Object *ob = ptr->data;
/* Loc code is specific... */
if (strstr(identifier, "location")) {
- copy_v3_v3(buffer, ob->obmat[3]);
+ copy_v3_v3(buffer, ob->object_to_world[3]);
*r_count = 3;
return buffer;
}
- copy_m4_m4(tmat, ob->obmat);
+ copy_m4_m4(tmat, ob->object_to_world);
rotmode = ob->rotmode;
}
else if (ptr->type == &RNA_PoseBone) {
@@ -1180,7 +1180,7 @@ static float *get_keyframe_values(ReportList *reports,
{
float *values;
- if ((flag & INSERTKEY_MATRIX) && (visualkey_can_use(&ptr, prop))) {
+ if ((flag & INSERTKEY_MATRIX) && visualkey_can_use(&ptr, prop)) {
/* visual-keying is only available for object and pchan datablocks, as
* it works by keyframing using a value extracted from the final matrix
* instead of using the kt system to extract a value.
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index e6bcb404bcb..3448ba1c017 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -120,7 +120,7 @@ void ANIM_OT_keying_set_add(wmOperatorType *ot)
/* identifiers */
ot->name = "Add Empty Keying Set";
ot->idname = "ANIM_OT_keying_set_add";
- ot->description = "Add a new (empty) Keying Set to the active Scene";
+ ot->description = "Add a new (empty) keying set to the active Scene";
/* callbacks */
ot->exec = add_default_keyingset_exec;
@@ -168,7 +168,7 @@ void ANIM_OT_keying_set_remove(wmOperatorType *ot)
/* identifiers */
ot->name = "Remove Active Keying Set";
ot->idname = "ANIM_OT_keying_set_remove";
- ot->description = "Remove the active Keying Set";
+ ot->description = "Remove the active keying set";
/* callbacks */
ot->exec = remove_active_keyingset_exec;
@@ -211,7 +211,7 @@ void ANIM_OT_keying_set_path_add(wmOperatorType *ot)
/* identifiers */
ot->name = "Add Empty Keying Set Path";
ot->idname = "ANIM_OT_keying_set_path_add";
- ot->description = "Add empty path to active Keying Set";
+ ot->description = "Add empty path to active keying set";
/* callbacks */
ot->exec = add_empty_ks_path_exec;
@@ -254,7 +254,7 @@ void ANIM_OT_keying_set_path_remove(wmOperatorType *ot)
/* identifiers */
ot->name = "Remove Active Keying Set Path";
ot->idname = "ANIM_OT_keying_set_path_remove";
- ot->description = "Remove active Path from active Keying Set";
+ ot->description = "Remove active Path from active keying set";
/* callbacks */
ot->exec = remove_active_ks_path_exec;
@@ -429,7 +429,7 @@ static int remove_keyingset_button_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
/* show warning */
- BKE_report(op->reports, RPT_INFO, "Property removed from Keying Set");
+ BKE_report(op->reports, RPT_INFO, "Property removed from keying set");
}
return (changed) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
@@ -491,7 +491,7 @@ void ANIM_OT_keying_set_active_set(wmOperatorType *ot)
/* identifiers */
ot->name = "Set Active Keying Set";
ot->idname = "ANIM_OT_keying_set_active_set";
- ot->description = "Select a new keying set as the active one";
+ ot->description = "Set a new active keying set";
/* callbacks */
ot->invoke = keyingset_active_menu_invoke;
@@ -589,7 +589,7 @@ void ANIM_keyingset_info_unregister(Main *bmain, KeyingSetInfo *ksi)
/* find relevant builtin KeyingSets which use this, and remove them */
/* TODO: this isn't done now, since unregister is really only used at the moment when we
- * reload the scripts, which kindof defeats the purpose of "builtin"? */
+ * reload the scripts, which kind of defeats the purpose of "builtin"? */
for (ks = builtin_keyingsets.first; ks; ks = ksn) {
ksn = ks->next;
@@ -888,7 +888,7 @@ bool ANIM_keyingset_context_ok_poll(bContext *C, KeyingSet *ks)
/* TODO: check for missing callbacks! */
/* check if it can be used in the current context */
- return (ksi->poll(ksi, C));
+ return ksi->poll(ksi, C);
}
return true;
diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c
index 2071f056f9e..806da5ee286 100644
--- a/source/blender/editors/armature/armature_add.c
+++ b/source/blender/editors/armature/armature_add.c
@@ -181,13 +181,13 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op))
const View3DCursor *curs = &scene->cursor;
copy_v3_v3(newbone->tail, curs->location);
- sub_v3_v3v3(newbone->tail, newbone->tail, obedit->obmat[3]);
+ sub_v3_v3v3(newbone->tail, newbone->tail, obedit->object_to_world[3]);
if (a == 1) {
newbone->tail[0] = -newbone->tail[0];
}
- copy_m3_m4(mat, obedit->obmat);
+ copy_m3_m4(mat, obedit->object_to_world);
invert_m3_m3(imat, mat);
mul_m3_v3(imat, newbone->tail);
@@ -541,7 +541,7 @@ static void updateDuplicateActionConstraintSettings(
}
BLI_freelistN(&ani_curves);
- /* Make deps graph aware of our changes */
+ /* Make depsgraph aware of our changes. */
DEG_id_tag_update(&act->id, ID_RECALC_ANIMATION_NO_FLUSH);
}
@@ -920,6 +920,7 @@ EditBone *duplicateEditBone(EditBone *cur_bone, const char *name, ListBase *edit
static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const bool do_flip_names = RNA_boolean_get(op->ptr, "do_flip_names");
@@ -930,7 +931,7 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
EditBone *ebone_iter;
/* The beginning of the duplicated bones in the edbo list */
@@ -1094,6 +1095,7 @@ static EditBone *get_symmetrized_bone(bArmature *arm, EditBone *bone)
*/
static int armature_symmetrize_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const int direction = RNA_enum_get(op->ptr, "direction");
const int axis = 0;
@@ -1105,7 +1107,7 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
bArmature *arm = obedit->data;
@@ -1349,13 +1351,14 @@ void ARMATURE_OT_symmetrize(wmOperatorType *ot)
/* if forked && mirror-edit: makes two bones with flipped names */
static int armature_extrude_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const bool forked = RNA_boolean_get(op->ptr, "forked");
bool changed_multi = false;
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
bArmature *arm = ob->data;
@@ -1566,8 +1569,8 @@ static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op)
copy_v3_v3(curs, CTX_data_scene(C)->cursor.location);
/* Get inverse point for head and orientation for tail */
- invert_m4_m4(obedit->imat, obedit->obmat);
- mul_m4_v3(obedit->imat, curs);
+ invert_m4_m4(obedit->world_to_object, obedit->object_to_world);
+ mul_m4_v3(obedit->world_to_object, curs);
if (rv3d && (U.flag & USER_ADD_VIEWALIGNED)) {
copy_m3_m4(obmat, rv3d->viewmat);
@@ -1576,7 +1579,7 @@ static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op)
unit_m3(obmat);
}
- copy_m3_m4(viewmat, obedit->obmat);
+ copy_m3_m4(viewmat, obedit->object_to_world);
mul_m3_m3m3(totmat, obmat, viewmat);
invert_m3_m3(imat, totmat);
diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c
index 3c445f46902..780e2fae00e 100644
--- a/source/blender/editors/armature/armature_edit.c
+++ b/source/blender/editors/armature/armature_edit.c
@@ -113,8 +113,8 @@ void ED_armature_origin_set(
/* Find the center-point. */
if (centermode == 2) {
copy_v3_v3(cent, cursor);
- invert_m4_m4(ob->imat, ob->obmat);
- mul_m4_v3(ob->imat, cent);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
+ mul_m4_v3(ob->world_to_object, cent);
}
else {
if (around == V3D_AROUND_CENTER_BOUNDS) {
@@ -154,7 +154,7 @@ void ED_armature_origin_set(
/* Adjust object location for new center-point. */
if (centermode && (is_editmode == false)) {
- mul_mat3_m4_v3(ob->obmat, cent); /* omit translation part */
+ mul_mat3_m4_v3(ob->object_to_world, cent); /* omit translation part */
add_v3_v3(ob->loc, cent);
}
}
@@ -254,6 +254,7 @@ static const EnumPropertyItem prop_calc_roll_types[] = {
static int armature_calc_roll_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob_active = CTX_data_edit_object(C);
int ret = OPERATOR_FINISHED;
@@ -267,7 +268,7 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
bArmature *arm = ob->data;
@@ -281,17 +282,16 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
axis_flip = true;
}
- copy_m3_m4(imat, ob->obmat);
+ copy_m3_m4(imat, ob->object_to_world);
invert_m3(imat);
if (type == CALC_ROLL_CURSOR) { /* Cursor */
- Scene *scene = CTX_data_scene(C);
float cursor_local[3];
const View3DCursor *cursor = &scene->cursor;
- invert_m4_m4(ob->imat, ob->obmat);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
copy_v3_v3(cursor_local, cursor->location);
- mul_m4_v3(ob->imat, cursor_local);
+ mul_m4_v3(ob->world_to_object, cursor_local);
/* cursor */
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
@@ -463,12 +463,13 @@ void ARMATURE_OT_calculate_roll(wmOperatorType *ot)
static int armature_roll_clear_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const float roll = RNA_float_get(op->ptr, "roll");
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
bArmature *arm = ob->data;
@@ -712,7 +713,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
Object *obedit = NULL;
{
ViewLayer *view_layer = CTX_data_view_layer(C);
- FOREACH_OBJECT_IN_EDIT_MODE_BEGIN (view_layer, v3d, ob_iter) {
+ FOREACH_OBJECT_IN_EDIT_MODE_BEGIN (scene, view_layer, v3d, ob_iter) {
if (ob_iter->data == arm) {
obedit = ob_iter;
}
@@ -729,8 +730,8 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
ebp = points.first;
/* Get points - cursor (tail) */
- invert_m4_m4(obedit->imat, obedit->obmat);
- mul_v3_m4v3(curs, obedit->imat, scene->cursor.location);
+ invert_m4_m4(obedit->world_to_object, obedit->object_to_world);
+ mul_v3_m4v3(curs, obedit->world_to_object, scene->cursor.location);
/* Create a bone */
newbone = add_points_bone(obedit, ebp->vec, curs);
@@ -766,8 +767,8 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
float dist_sq_a, dist_sq_b;
/* get cursor location */
- invert_m4_m4(obedit->imat, obedit->obmat);
- mul_v3_m4v3(curs, obedit->imat, scene->cursor.location);
+ invert_m4_m4(obedit->world_to_object, obedit->object_to_world);
+ mul_v3_m4v3(curs, obedit->world_to_object, scene->cursor.location);
/* get distances */
dist_sq_a = len_squared_v3v3(ebp_a->vec, curs);
@@ -884,10 +885,11 @@ static void armature_clear_swap_done_flags(bArmature *arm)
static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
@@ -1157,11 +1159,12 @@ void ARMATURE_OT_align(wmOperatorType *ot)
static int armature_split_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
bArmature *arm = ob->data;
@@ -1226,10 +1229,11 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
bArmature *arm = obedit->data;
@@ -1299,13 +1303,14 @@ static bool armature_dissolve_ebone_cb(const char *bone_name, void *arm_p)
static int armature_dissolve_selected_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
EditBone *ebone, *ebone_next;
bool changed_multi = false;
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
bArmature *arm = obedit->data;
@@ -1372,12 +1377,12 @@ static int armature_dissolve_selected_exec(bContext *C, wmOperator *UNUSED(op))
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
/* break connections for unseen bones */
if (((arm->layer & ebone->layer) &&
- ((ED_armature_ebone_selectflag_get(ebone) & (BONE_TIPSEL | BONE_SELECTED)))) == 0) {
+ (ED_armature_ebone_selectflag_get(ebone) & (BONE_TIPSEL | BONE_SELECTED))) == 0) {
ebone->temp.ebone = NULL;
}
if (((arm->layer & ebone->layer) &&
- ((ED_armature_ebone_selectflag_get(ebone) & (BONE_ROOTSEL | BONE_SELECTED)))) == 0) {
+ (ED_armature_ebone_selectflag_get(ebone) & (BONE_ROOTSEL | BONE_SELECTED))) == 0) {
if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
ebone->parent->temp.ebone = NULL;
}
@@ -1471,6 +1476,7 @@ void ARMATURE_OT_dissolve(wmOperatorType *ot)
static int armature_hide_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const int invert = RNA_boolean_get(op->ptr, "unselected") ? BONE_SELECTED : 0;
@@ -1481,7 +1487,7 @@ static int armature_hide_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
bArmature *arm = obedit->data;
@@ -1536,11 +1542,12 @@ void ARMATURE_OT_hide(wmOperatorType *ot)
static int armature_reveal_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const bool select = RNA_boolean_get(op->ptr, "select");
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
bArmature *arm = obedit->data;
diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c
index 4f329dbe449..26ec05cc503 100644
--- a/source/blender/editors/armature/armature_naming.c
+++ b/source/blender/editors/armature/armature_naming.c
@@ -429,6 +429,7 @@ void ED_armature_bones_flip_names(Main *bmain,
static int armature_flip_names_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob_active = CTX_data_edit_object(C);
@@ -436,7 +437,7 @@ static int armature_flip_names_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
bArmature *arm = ob->data;
@@ -516,6 +517,7 @@ void ARMATURE_OT_flip_names(wmOperatorType *ot)
static int armature_autoside_names_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Main *bmain = CTX_data_main(C);
char newname[MAXBONENAME];
@@ -524,7 +526,7 @@ static int armature_autoside_names_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
bArmature *arm = ob->data;
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index 0825d6968c6..fccf2964868 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -289,7 +289,7 @@ int ED_armature_join_objects_exec(bContext *C, wmOperator *op)
/* Inverse transform for all selected armatures in this object,
* See #object_join_exec for detailed comment on why the safe version is used. */
- invert_m4_m4_safe_ortho(oimat, ob_active->obmat);
+ invert_m4_m4_safe_ortho(oimat, ob_active->object_to_world);
/* Get edit-bones of active armature to add edit-bones to */
ED_armature_to_edit(arm);
@@ -321,7 +321,7 @@ int ED_armature_join_objects_exec(bContext *C, wmOperator *op)
// BASACT->flag &= ~OB_MODE_POSE;
/* Find the difference matrix */
- mul_m4_m4m4(mat, oimat, ob_iter->obmat);
+ mul_m4_m4m4(mat, oimat, ob_iter->object_to_world);
/* Copy bones and posechannels from the object to the edit armature */
for (pchan = opose->chanbase.first; pchan; pchan = pchann) {
@@ -610,7 +610,7 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &bases_len);
+ scene, view_layer, CTX_wm_view3d(C), &bases_len);
for (uint base_index = 0; base_index < bases_len; base_index++) {
Base *base_old = bases[base_index];
@@ -974,6 +974,7 @@ static void editbone_clear_parent(EditBone *ebone, int mode)
static int armature_parent_clear_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const int val = RNA_enum_get(op->ptr, "type");
@@ -984,7 +985,7 @@ static int armature_parent_clear_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
bArmature *arm = ob->data;
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index 479a2245b30..3ee0510ca7f 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -339,10 +339,11 @@ static void *ed_armature_pick_bone_impl(
Base **bases;
if (vc.obedit != NULL) {
- bases = BKE_view_layer_array_from_bases_in_edit_mode(vc.view_layer, vc.v3d, &bases_len);
+ bases = BKE_view_layer_array_from_bases_in_edit_mode(
+ vc.scene, vc.view_layer, vc.v3d, &bases_len);
}
else {
- bases = BKE_object_pose_base_array_get(vc.view_layer, vc.v3d, &bases_len);
+ bases = BKE_object_pose_base_array_get(vc.scene, vc.view_layer, vc.v3d, &bases_len);
}
void *bone = ed_armature_pick_bone_from_selectbuffer_impl(
@@ -494,10 +495,11 @@ static int armature_select_linked_exec(bContext *C, wmOperator *op)
const bool all_forks = RNA_boolean_get(op->ptr, "all_forks");
bool changed_multi = false;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
bArmature *arm = ob->data;
@@ -713,7 +715,7 @@ cache_end:
uint bases_len;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- vc->view_layer, vc->v3d, &bases_len);
+ vc->scene, vc->view_layer, vc->v3d, &bases_len);
/* See if there are any selected bones in this group */
if (hits > 0) {
@@ -930,7 +932,7 @@ bool ED_armature_edit_deselect_all_visible_multi(bContext *C)
ED_view3d_viewcontext_init(C, &vc, depsgraph);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- vc.view_layer, vc.v3d, &bases_len);
+ vc.scene, vc.view_layer, vc.v3d, &bases_len);
bool changed_multi = ED_armature_edit_deselect_all_multi_ex(bases, bases_len);
MEM_freeN(bases);
return changed_multi;
@@ -948,6 +950,7 @@ bool ED_armature_edit_select_pick_bone(bContext *C,
const int selmask,
const struct SelectPick_Params *params)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
bool changed = false;
@@ -969,7 +972,7 @@ bool ED_armature_edit_select_pick_bone(bContext *C,
/* Deselect everything. */
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- view_layer, v3d, &bases_len);
+ scene, view_layer, v3d, &bases_len);
ED_armature_edit_deselect_all_multi_ex(bases, bases_len);
MEM_freeN(bases);
changed = true;
@@ -1100,7 +1103,8 @@ bool ED_armature_edit_select_pick_bone(bContext *C,
arm->act_edbone = ebone;
}
- if (view_layer->basact != basact) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ if (BKE_view_layer_active_base_get(view_layer) != basact) {
ED_object_base_activate(C, basact);
}
@@ -1489,10 +1493,11 @@ static void armature_select_more_less(Object *ob, bool more)
static int armature_de_select_more_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
armature_select_more_less(ob, true);
@@ -1528,10 +1533,11 @@ void ARMATURE_OT_select_more(wmOperatorType *ot)
static int armature_de_select_less_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
armature_select_more_less(ob, false);
@@ -1595,13 +1601,14 @@ static const EnumPropertyItem prop_similar_types[] = {
static float bone_length_squared_worldspace_get(Object *ob, EditBone *ebone)
{
float v1[3], v2[3];
- mul_v3_mat3_m4v3(v1, ob->obmat, ebone->head);
- mul_v3_mat3_m4v3(v2, ob->obmat, ebone->tail);
+ mul_v3_mat3_m4v3(v1, ob->object_to_world, ebone->head);
+ mul_v3_mat3_m4v3(v2, ob->object_to_world, ebone->tail);
return len_squared_v3v3(v1, v2);
}
static void select_similar_length(bContext *C, const float thresh)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob_act = CTX_data_edit_object(C);
EditBone *ebone_act = CTX_data_active_bone(C);
@@ -1613,7 +1620,7 @@ static void select_similar_length(bContext *C, const float thresh)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
bArmature *arm = ob->data;
@@ -1643,8 +1650,8 @@ static void bone_direction_worldspace_get(Object *ob, EditBone *ebone, float *r_
copy_v3_v3(v1, ebone->head);
copy_v3_v3(v2, ebone->tail);
- mul_m4_v3(ob->obmat, v1);
- mul_m4_v3(ob->obmat, v2);
+ mul_m4_v3(ob->object_to_world, v1);
+ mul_m4_v3(ob->object_to_world, v2);
sub_v3_v3v3(r_dir, v1, v2);
normalize_v3(r_dir);
@@ -1652,6 +1659,7 @@ static void bone_direction_worldspace_get(Object *ob, EditBone *ebone, float *r_
static void select_similar_direction(bContext *C, const float thresh)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob_act = CTX_data_edit_object(C);
EditBone *ebone_act = CTX_data_active_bone(C);
@@ -1661,7 +1669,7 @@ static void select_similar_direction(bContext *C, const float thresh)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
bArmature *arm = ob->data;
@@ -1690,12 +1698,13 @@ static void select_similar_direction(bContext *C, const float thresh)
static void select_similar_layer(bContext *C)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
EditBone *ebone_act = CTX_data_active_bone(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
bArmature *arm = ob->data;
@@ -1720,6 +1729,7 @@ static void select_similar_layer(bContext *C)
static void select_similar_prefix(bContext *C)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
EditBone *ebone_act = CTX_data_active_bone(C);
@@ -1734,7 +1744,7 @@ static void select_similar_prefix(bContext *C)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
bArmature *arm = ob->data;
@@ -1762,6 +1772,7 @@ static void select_similar_prefix(bContext *C)
static void select_similar_suffix(bContext *C)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
EditBone *ebone_act = CTX_data_active_bone(C);
@@ -1776,7 +1787,7 @@ static void select_similar_suffix(bContext *C)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
bArmature *arm = ob->data;
@@ -2101,13 +2112,14 @@ void ARMATURE_OT_select_hierarchy(wmOperatorType *ot)
*/
static int armature_select_mirror_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const bool active_only = RNA_boolean_get(op->ptr, "only_active");
const bool extend = RNA_boolean_get(op->ptr, "extend");
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
bArmature *arm = ob->data;
@@ -2125,7 +2137,7 @@ static int armature_select_mirror_exec(bContext *C, wmOperator *op)
int flag_new = extend ? EBONE_PREV_FLAG_GET(ebone) : 0;
if ((ebone_mirror = ED_armature_ebone_get_mirrored(arm->edbo, ebone)) &&
- (EBONE_VISIBLE(arm, ebone_mirror))) {
+ EBONE_VISIBLE(arm, ebone_mirror)) {
const int flag_mirror = EBONE_PREV_FLAG_GET(ebone_mirror);
flag_new |= flag_mirror;
diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c
index e39cc157c19..3c9c8cf05b3 100644
--- a/source/blender/editors/armature/armature_skinning.c
+++ b/source/blender/editors/armature/armature_skinning.c
@@ -203,10 +203,13 @@ static void envelope_bone_weighting(Object *ob,
use_mask = true;
}
+ const bool *select_vert = (const bool *)CustomData_get_layer_named(
+ &mesh->vdata, CD_PROP_BOOL, ".select_vert");
+
/* for each vertex in the mesh */
- const MVert *mesh_verts = BKE_mesh_verts(mesh);
for (int i = 0; i < mesh->totvert; i++) {
- if (use_mask && !(mesh_verts[i].flag & SELECT)) {
+
+ if (use_mask && !(select_vert && select_vert[i])) {
continue;
}
@@ -362,8 +365,8 @@ static void add_verts_to_dgroups(ReportList *reports,
copy_v3_v3(tip[j], bone->arm_tail);
}
- mul_m4_v3(par->obmat, root[j]);
- mul_m4_v3(par->obmat, tip[j]);
+ mul_m4_v3(par->object_to_world, root[j]);
+ mul_m4_v3(par->object_to_world, tip[j]);
/* set selected */
if (wpmode) {
@@ -411,7 +414,7 @@ static void add_verts_to_dgroups(ReportList *reports,
if (!vertsfilled) {
copy_v3_v3(verts[i], mesh_verts[i].co);
}
- mul_m4_v3(ob->obmat, verts[i]);
+ mul_m4_v3(ob->object_to_world, verts[i]);
}
/* compute the weights based on gathered vertices and bones */
@@ -435,7 +438,7 @@ static void add_verts_to_dgroups(ReportList *reports,
root,
tip,
selected,
- mat4_to_scale(par->obmat));
+ mat4_to_scale(par->object_to_world));
}
/* only generated in some cases but can call anyway */
diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c
index 09174aa5e47..0465606e694 100644
--- a/source/blender/editors/armature/armature_utils.c
+++ b/source/blender/editors/armature/armature_utils.c
@@ -703,11 +703,11 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm)
newBone->inherit_scale_mode = eBone->inherit_scale_mode;
if (eBone == arm->act_edbone) {
- /* don't change active selection, this messes up separate which uses
- * editmode toggle and can separate active bone which is de-selected originally */
+ /* Don't change active selection, this messes up separate which uses
+ * edit-mode toggle and can separate active bone which is de-selected originally. */
- /* important, editbones can be active with only 1 point selected */
- /* newBone->flag |= BONE_SELECTED; */
+ /* important, edit-bones can be active with only 1 point selected */
+ /* `newBone->flag |= BONE_SELECTED;` */
arm->act_bone = newBone;
}
newBone->roll = 0.0f;
diff --git a/source/blender/editors/armature/editarmature_undo.c b/source/blender/editors/armature/editarmature_undo.c
index 3f084c08044..379ad4f5376 100644
--- a/source/blender/editors/armature/editarmature_undo.c
+++ b/source/blender/editors/armature/editarmature_undo.c
@@ -97,7 +97,9 @@ static void undoarm_free_data(UndoArmature *uarm)
static Object *editarm_object_from_context(bContext *C)
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
if (obedit && obedit->type == OB_ARMATURE) {
bArmature *arm = obedit->data;
@@ -139,9 +141,10 @@ static bool armature_undosys_step_encode(struct bContext *C, struct Main *bmain,
/* Important not to use the 3D view when getting objects because all objects
* outside of this list will be moved out of edit-mode when reading back undo steps. */
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
- Object **objects = ED_undo_editmode_objects_from_view_layer(view_layer, &objects_len);
+ Object **objects = ED_undo_editmode_objects_from_view_layer(scene, view_layer, &objects_len);
us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
us->elems_len = objects_len;
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 904e6213466..dfb9e8a79fa 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -669,17 +669,25 @@ void heat_bone_weighting(Object *ob,
/* (added selectedVerts content for vertex mask, they used to just equal 1) */
if (use_vert_sel) {
- for (a = 0, mp = polys; a < me->totpoly; mp++, a++) {
- for (j = 0, ml = loops + mp->loopstart; j < mp->totloop; j++, ml++) {
- mask[ml->v] = (mesh_verts[ml->v].flag & SELECT) != 0;
+ const bool *select_vert = (const bool *)CustomData_get_layer_named(
+ &me->vdata, CD_PROP_BOOL, ".select_vert");
+ if (select_vert) {
+ for (a = 0, mp = polys; a < me->totpoly; mp++, a++) {
+ for (j = 0, ml = loops + mp->loopstart; j < mp->totloop; j++, ml++) {
+ mask[ml->v] = select_vert[ml->v];
+ }
}
}
}
else if (use_face_sel) {
- for (a = 0, mp = polys; a < me->totpoly; mp++, a++) {
- if (mp->flag & ME_FACE_SEL) {
- for (j = 0, ml = loops + mp->loopstart; j < mp->totloop; j++, ml++) {
- mask[ml->v] = 1;
+ const bool *select_poly = (const bool *)CustomData_get_layer_named(
+ &me->pdata, CD_PROP_BOOL, ".select_poly");
+ if (select_poly) {
+ for (a = 0, mp = polys; a < me->totpoly; mp++, a++) {
+ if (select_poly[a]) {
+ for (j = 0, ml = loops + mp->loopstart; j < mp->totloop; j++, ml++) {
+ mask[ml->v] = 1;
+ }
}
}
}
@@ -1780,11 +1788,11 @@ void ED_mesh_deform_bind_callback(Object *object,
mmd_orig->bindcagecos = (float *)mdb.cagecos;
mmd_orig->verts_num = mdb.verts_num;
mmd_orig->cage_verts_num = mdb.cage_verts_num;
- copy_m4_m4(mmd_orig->bindmat, mmd_orig->object->obmat);
+ copy_m4_m4(mmd_orig->bindmat, mmd_orig->object->object_to_world);
/* transform bindcagecos to world space */
for (a = 0; a < mdb.cage_verts_num; a++) {
- mul_m4_v3(mmd_orig->object->obmat, mmd_orig->bindcagecos + a * 3);
+ mul_m4_v3(mmd_orig->object->object_to_world, mmd_orig->bindcagecos + a * 3);
}
/* free */
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index cec83ffa0f0..14cd731f142 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -499,11 +499,12 @@ void POSE_OT_paths_range_update(wmOperatorType *ot)
static int pose_flip_names_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
const bool do_strip_numbers = RNA_boolean_get(op->ptr, "do_strip_numbers");
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
bArmature *arm = ob->data;
ListBase bones_names = {NULL};
@@ -691,7 +692,7 @@ static int pose_armature_layers_showall_exec(bContext *C, wmOperator *op)
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 maxLayers = RNA_boolean_get(op->ptr, "all") ? 32 : 16;
/* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
bool layers[32] = {false};
@@ -856,9 +857,10 @@ static int pose_bone_layers_exec(bContext *C, wmOperator *op)
struct Main *bmain = CTX_data_main(C);
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C); /* This may be NULL in a lot of cases. */
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) {
bArmature *arm = ob_iter->data;
BKE_pose_ensure(bmain, ob_iter, arm, true);
}
@@ -952,6 +954,7 @@ static int armature_bone_layers_exec(bContext *C, wmOperator *op)
/* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
+ DEG_id_tag_update((ID *)ob->data, ID_RECALC_PARAMETERS);
return OPERATOR_FINISHED;
}
@@ -1001,9 +1004,11 @@ static int hide_pose_bone_fn(Object *ob, Bone *bone, void *ptr)
/* active object is armature in posemode, poll checked */
static int pose_hide_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len;
- Object **objects = BKE_object_pose_array_get_unique(view_layer, CTX_wm_view3d(C), &objects_len);
+ Object **objects = BKE_object_pose_array_get_unique(
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
bool changed_multi = false;
const int hide_select = !RNA_boolean_get(op->ptr, "unselected");
@@ -1066,9 +1071,11 @@ static int show_pose_bone_cb(Object *ob, Bone *bone, void *data)
/* active object is armature in posemode, poll checked */
static int pose_reveal_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len;
- Object **objects = BKE_object_pose_array_get_unique(view_layer, CTX_wm_view3d(C), &objects_len);
+ Object **objects = BKE_object_pose_array_get_unique(
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
bool changed_multi = false;
const bool select = RNA_boolean_get(op->ptr, "select");
void *select_p = POINTER_FROM_INT(select);
@@ -1118,7 +1125,7 @@ static int pose_flip_quats_exec(bContext *C, wmOperator *UNUSED(op))
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) {
bool changed = false;
/* loop through all selected pchans, flipping and keying (as needed) */
FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan) {
diff --git a/source/blender/editors/armature/pose_lib_2.c b/source/blender/editors/armature/pose_lib_2.c
index d866062cec0..e3189eacdd5 100644
--- a/source/blender/editors/armature/pose_lib_2.c
+++ b/source/blender/editors/armature/pose_lib_2.c
@@ -41,6 +41,7 @@
#include "ED_asset.h"
#include "ED_keyframing.h"
#include "ED_screen.h"
+#include "ED_util.h"
#include "armature_intern.h"
@@ -58,10 +59,8 @@ typedef struct PoseBlendData {
struct {
bool use_release_confirm;
- int drag_start_xy[2];
int init_event_type;
- bool cursor_wrap_enabled;
} release_confirm_info;
/* For temp-loading the Action from the pose library. */
@@ -78,6 +77,8 @@ typedef struct PoseBlendData {
Scene *scene; /* For auto-keying. */
ScrArea *area; /* For drawing status text. */
+ struct tSlider *slider; /* Slider UI and event handling. */
+
/** Info-text to print in header. */
char headerstr[UI_MAX_DRAW_STR];
} PoseBlendData;
@@ -146,22 +147,6 @@ static void poselib_blend_apply(bContext *C, wmOperator *op)
{
PoseBlendData *pbd = (PoseBlendData *)op->customdata;
- if (pbd->state == POSE_BLEND_BLENDING) {
- BLI_snprintf(pbd->headerstr,
- sizeof(pbd->headerstr),
- TIP_("PoseLib blending: \"%s\" at %3.0f%%"),
- pbd->act->id.name + 2,
- pbd->blend_factor * 100);
- ED_area_status_text(pbd->area, pbd->headerstr);
-
- ED_workspace_status_text(
- C, TIP_("Tab: show original pose; Horizontal mouse movement: change blend percentage"));
- }
- else {
- ED_area_status_text(pbd->area, TIP_("PoseLib showing original pose"));
- ED_workspace_status_text(C, TIP_("Tab: show blended pose"));
- }
-
if (!pbd->needs_redraw) {
return;
}
@@ -192,27 +177,16 @@ static void poselib_blend_set_factor(PoseBlendData *pbd, const float new_factor)
pbd->needs_redraw = true;
}
-static void poselib_slide_mouse_update_blendfactor(PoseBlendData *pbd, const wmEvent *event)
-{
- if (pbd->release_confirm_info.use_release_confirm) {
- /* Release confirm calculates factor based on where the dragging was started from. */
- const float range = 300 * U.pixelsize;
- const float new_factor = (event->xy[0] - pbd->release_confirm_info.drag_start_xy[0]) / range;
- poselib_blend_set_factor(pbd, new_factor);
- }
- else {
- const float new_factor = (event->xy[0] - pbd->area->v1->vec.x) / ((float)pbd->area->winx);
- poselib_blend_set_factor(pbd, new_factor);
- }
-}
-
/* Return operator return value. */
static int poselib_blend_handle_event(bContext *UNUSED(C), wmOperator *op, const wmEvent *event)
{
PoseBlendData *pbd = op->customdata;
+ ED_slider_modal(pbd->slider, event);
+ const float factor = ED_slider_factor_get(pbd->slider);
+ poselib_blend_set_factor(pbd, factor);
+
if (event->type == MOUSEMOVE) {
- poselib_slide_mouse_update_blendfactor(pbd, event);
return OPERATOR_RUNNING_MODAL;
}
@@ -257,18 +231,6 @@ static int poselib_blend_handle_event(bContext *UNUSED(C), wmOperator *op, const
return OPERATOR_RUNNING_MODAL;
}
-static void poselib_blend_cursor_update(bContext *C, wmOperator *op)
-{
- PoseBlendData *pbd = op->customdata;
-
- /* Ensure cursor-grab (continuous grabbing) is enabled when using release-confirm. */
- if (pbd->release_confirm_info.use_release_confirm &&
- !pbd->release_confirm_info.cursor_wrap_enabled) {
- WM_cursor_grab_enable(CTX_wm_window(C), WM_CURSOR_WRAP_XY, true, NULL);
- pbd->release_confirm_info.cursor_wrap_enabled = true;
- }
-}
-
/* ---------------------------- */
static Object *get_poselib_object(bContext *C)
@@ -363,11 +325,14 @@ static bool poselib_blend_init_data(bContext *C, wmOperator *op, const wmEvent *
pbd->release_confirm_info.use_release_confirm = (release_confirm_prop != NULL) &&
RNA_property_boolean_get(op->ptr,
release_confirm_prop);
+ pbd->slider = ED_slider_create(C);
+ ED_slider_init(pbd->slider, event);
+ ED_slider_factor_set(pbd->slider, pbd->blend_factor);
+ ED_slider_allow_overshoot_set(pbd->slider, false);
}
if (pbd->release_confirm_info.use_release_confirm) {
BLI_assert(event != NULL);
- copy_v2_v2_int(pbd->release_confirm_info.drag_start_xy, event->xy);
pbd->release_confirm_info.init_event_type = WM_userdef_event_type_from_keymap_type(
event->type);
}
@@ -391,6 +356,10 @@ static void poselib_blend_cleanup(bContext *C, wmOperator *op)
ED_area_status_text(pbd->area, NULL);
ED_workspace_status_text(C, NULL);
+ if (pbd->slider) {
+ ED_slider_destroy(C, pbd->slider);
+ }
+
/* This signals the depsgraph to unlock and reevaluate the pose on the next evaluation. */
bPose *pose = pbd->ob->pose;
pose->flag |= POSE_DO_UNLOCK;
@@ -417,11 +386,6 @@ static void poselib_blend_cleanup(bContext *C, wmOperator *op)
break;
}
- if (pbd->release_confirm_info.cursor_wrap_enabled) {
- WM_cursor_grab_disable(win, pbd->release_confirm_info.drag_start_xy);
- pbd->release_confirm_info.cursor_wrap_enabled = false;
- }
-
DEG_id_tag_update(&pbd->ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, pbd->ob);
/* Update mouse-hover highlights. */
@@ -442,9 +406,6 @@ static void poselib_blend_free(wmOperator *op)
}
poselib_tempload_exit(pbd);
- /* Must have been dealt with before! */
- BLI_assert(pbd->release_confirm_info.cursor_wrap_enabled == false);
-
/* Free temp data for operator */
ED_pose_backup_free(pbd->pose_backup);
pbd->pose_backup = NULL;
@@ -460,6 +421,9 @@ static int poselib_blend_exit(bContext *C, wmOperator *op)
poselib_blend_cleanup(C, op);
poselib_blend_free(op);
+ wmWindow *win = CTX_wm_window(C);
+ WM_cursor_modal_restore(win);
+
if (exit_state == POSE_BLEND_CANCEL) {
return OPERATOR_CANCELLED;
}
@@ -479,14 +443,28 @@ static int poselib_blend_modal(bContext *C, wmOperator *op, const wmEvent *event
{
const int operator_result = poselib_blend_handle_event(C, op, event);
- poselib_blend_cursor_update(C, op);
-
const PoseBlendData *pbd = op->customdata;
if (ELEM(pbd->state, POSE_BLEND_CONFIRM, POSE_BLEND_CANCEL)) {
return poselib_blend_exit(C, op);
}
if (pbd->needs_redraw) {
+ char status_string[UI_MAX_DRAW_STR];
+ char slider_string[UI_MAX_DRAW_STR];
+ char tab_string[50];
+
+ ED_slider_status_string_get(pbd->slider, slider_string, sizeof(slider_string));
+
+ if (pbd->state == POSE_BLEND_BLENDING) {
+ strcpy(tab_string, TIP_("[Tab] - Show original pose"));
+ }
+ else {
+ strcpy(tab_string, TIP_("[Tab] - Show blended pose"));
+ }
+
+ BLI_snprintf(status_string, sizeof(status_string), "%s | %s", tab_string, slider_string);
+ ED_workspace_status_text(C, status_string);
+
poselib_blend_apply(C, op);
}
@@ -501,6 +479,9 @@ static int poselib_blend_invoke(bContext *C, wmOperator *op, const wmEvent *even
return OPERATOR_CANCELLED;
}
+ wmWindow *win = CTX_wm_window(C);
+ WM_cursor_modal_set(win, WM_CURSOR_EW_SCROLL);
+
/* Do initial apply to have something to look at. */
poselib_blend_apply(C, op);
@@ -594,7 +575,7 @@ void POSELIB_OT_blend_pose_asset(wmOperatorType *ot)
ot->poll = poselib_blend_poll;
/* Flags: */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR_X;
/* Properties: */
prop = RNA_def_float_factor(ot->srna,
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 55dc664b756..e75d748653b 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -121,7 +121,8 @@ void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select)
}
}
-bool ED_armature_pose_select_pick_bone(ViewLayer *view_layer,
+bool ED_armature_pose_select_pick_bone(const Scene *scene,
+ ViewLayer *view_layer,
View3D *v3d,
Object *ob,
Bone *bone,
@@ -144,7 +145,7 @@ bool ED_armature_pose_select_pick_bone(ViewLayer *view_layer,
/* Deselect everything. */
/* Don't use 'BKE_object_pose_base_array_get_unique'
* because we may be selecting from object mode. */
- FOREACH_VISIBLE_BASE_BEGIN (view_layer, v3d, base_iter) {
+ FOREACH_VISIBLE_BASE_BEGIN (scene, view_layer, v3d, base_iter) {
Object *ob_iter = base_iter->object;
if ((ob_iter->type == OB_ARMATURE) && (ob_iter->mode & OB_MODE_POSE)) {
if (ED_pose_deselect_all(ob_iter, SEL_DESELECT, true)) {
@@ -158,6 +159,7 @@ bool ED_armature_pose_select_pick_bone(ViewLayer *view_layer,
}
if (found) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob_act = BKE_view_layer_active_object_get(view_layer);
BLI_assert(BKE_view_layer_edit_object_get(view_layer) == NULL);
@@ -243,7 +245,8 @@ bool ED_armature_pose_select_pick_bone(ViewLayer *view_layer,
return changed || found;
}
-bool ED_armature_pose_select_pick_with_buffer(ViewLayer *view_layer,
+bool ED_armature_pose_select_pick_with_buffer(const Scene *scene,
+ ViewLayer *view_layer,
View3D *v3d,
Base *base,
const struct GPUSelectResult *buffer,
@@ -263,12 +266,15 @@ bool ED_armature_pose_select_pick_with_buffer(ViewLayer *view_layer,
nearBone = ED_armature_pick_bone_from_selectbuffer(
&base, 1, buffer, hits, 1, do_nearest, &base_dummy);
- return ED_armature_pose_select_pick_bone(view_layer, v3d, ob, nearBone, params);
+ return ED_armature_pose_select_pick_bone(scene, view_layer, v3d, ob, nearBone, params);
}
-void ED_armature_pose_select_in_wpaint_mode(ViewLayer *view_layer, Base *base_select)
+void ED_armature_pose_select_in_wpaint_mode(const Scene *scene,
+ ViewLayer *view_layer,
+ Base *base_select)
{
BLI_assert(base_select && (base_select->object->type == OB_ARMATURE));
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob_active = BKE_view_layer_active_object_get(view_layer);
BLI_assert(ob_active && (ob_active->mode & OB_MODE_ALL_WEIGHT_PAINT));
@@ -401,7 +407,8 @@ bool ED_pose_deselect_all_multi(bContext *C, int select_mode, const bool ignore_
ED_view3d_viewcontext_init(C, &vc, depsgraph);
uint bases_len = 0;
- Base **bases = BKE_object_pose_base_array_get_unique(vc.view_layer, vc.v3d, &bases_len);
+ Base **bases = BKE_object_pose_base_array_get_unique(
+ vc.scene, vc.view_layer, vc.v3d, &bases_len);
bool changed_multi = ED_pose_deselect_all_multi_ex(
bases, bases_len, select_mode, ignore_visibility);
MEM_freeN(bases);
@@ -844,6 +851,7 @@ typedef enum ePose_SelectSame_Mode {
static bool pose_select_same_group(bContext *C, bool extend)
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
bool *group_flags_array;
bool *group_flags = NULL;
@@ -853,7 +861,8 @@ static bool pose_select_same_group(bContext *C, bool extend)
uint ob_index;
uint objects_len = 0;
- Object **objects = BKE_object_pose_array_get_unique(view_layer, CTX_wm_view3d(C), &objects_len);
+ Object **objects = BKE_object_pose_array_get_unique(
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = BKE_object_pose_armature_get(objects[ob_index]);
@@ -947,6 +956,7 @@ static bool pose_select_same_group(bContext *C, bool extend)
static bool pose_select_same_layer(bContext *C, bool extend)
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
int *layers_array, *layers = NULL;
Object *ob_prev = NULL;
@@ -954,7 +964,8 @@ static bool pose_select_same_layer(bContext *C, bool extend)
bool changed = false;
uint objects_len = 0;
- Object **objects = BKE_object_pose_array_get_unique(view_layer, CTX_wm_view3d(C), &objects_len);
+ Object **objects = BKE_object_pose_array_get_unique(
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
@@ -1032,6 +1043,7 @@ cleanup:
static bool pose_select_same_keyingset(bContext *C, ReportList *reports, bool extend)
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
bool changed_multi = false;
KeyingSet *ks = ANIM_scene_get_active_keyingset(CTX_data_scene(C));
@@ -1068,7 +1080,8 @@ static bool pose_select_same_keyingset(bContext *C, ReportList *reports, bool ex
}
uint objects_len = 0;
- Object **objects = BKE_object_pose_array_get_unique(view_layer, CTX_wm_view3d(C), &objects_len);
+ Object **objects = BKE_object_pose_array_get_unique(
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = BKE_object_pose_armature_get(objects[ob_index]);
@@ -1196,6 +1209,7 @@ void POSE_OT_select_grouped(wmOperatorType *ot)
*/
static int pose_select_mirror_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob_active = CTX_data_active_object(C);
@@ -1204,7 +1218,8 @@ static int pose_select_mirror_exec(bContext *C, wmOperator *op)
const bool extend = RNA_boolean_get(op->ptr, "extend");
uint objects_len = 0;
- Object **objects = BKE_object_pose_array_get_unique(view_layer, CTX_wm_view3d(C), &objects_len);
+ Object **objects = BKE_object_pose_array_get_unique(
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
@@ -1222,7 +1237,7 @@ static int pose_select_mirror_exec(bContext *C, wmOperator *op)
int flag_new = extend ? PBONE_PREV_FLAG_GET(pchan) : 0;
if ((pchan_mirror = BKE_pose_channel_get_mirrored(ob->pose, pchan->name)) &&
- (PBONE_VISIBLE(arm, pchan_mirror->bone))) {
+ PBONE_VISIBLE(arm, pchan_mirror->bone)) {
const int flag_mirror = PBONE_PREV_FLAG_GET(pchan_mirror);
flag_new |= flag_mirror;
diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c
index 5e0ef9217c7..14b3451bd80 100644
--- a/source/blender/editors/armature/pose_slide.c
+++ b/source/blender/editors/armature/pose_slide.c
@@ -232,8 +232,11 @@ static int pose_slide_init(bContext *C, wmOperator *op, ePoseSlide_Modes mode)
* and set the relevant transform flags. */
poseAnim_mapping_get(C, &pso->pfLinks);
- Object **objects = BKE_view_layer_array_from_objects_in_mode_unique_data(
- CTX_data_view_layer(C), CTX_wm_view3d(C), &pso->objects_len, OB_MODE_POSE);
+ Object **objects = BKE_view_layer_array_from_objects_in_mode_unique_data(CTX_data_scene(C),
+ CTX_data_view_layer(C),
+ CTX_wm_view3d(C),
+ &pso->objects_len,
+ OB_MODE_POSE);
pso->ob_data_array = MEM_callocN(pso->objects_len * sizeof(tPoseSlideObject),
"pose slide objects data");
@@ -2081,7 +2084,7 @@ static int pose_propagate_exec(bContext *C, wmOperator *op)
}
/* Updates + notifiers. */
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
poseAnim_mapping_refresh(C, scene, ob);
}
FOREACH_OBJECT_IN_MODE_END;
diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c
index cfc6b0b6b6e..51071815823 100644
--- a/source/blender/editors/armature/pose_transform.c
+++ b/source/blender/editors/armature/pose_transform.c
@@ -77,10 +77,10 @@ static void applyarmature_fix_boneparents(const bContext *C, Scene *scene, Objec
/* 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->object_to_world, false, false);
BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
- invert_m4_m4(ob->parentinv, workob.obmat);
+ invert_m4_m4(ob->parentinv, workob.object_to_world);
}
}
}
@@ -361,7 +361,7 @@ static void applyarmature_reset_constraints(bPose *pose, const bool use_selected
}
}
-/* set the current pose as the restpose */
+/* Set the current pose as the rest-pose. */
static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
@@ -404,10 +404,10 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
}
}
- /* Get editbones of active armature to alter */
+ /* Get edit-bones of active armature to alter. */
ED_armature_to_edit(arm);
- /* get pose of active object and move it out of posemode */
+ /* Get pose of active object and move it out of pose-mode. */
pose = ob->pose;
if (use_selected) {
@@ -429,11 +429,11 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
}
}
- /* convert editbones back to bones, and then free the edit-data */
+ /* Convert edit-bones back to bones, and then free the edit-data. */
ED_armature_from_edit(bmain, arm);
ED_armature_edit_free(arm);
- /* flush positions of posebones */
+ /* Flush positions of pose-bones. */
BKE_pose_where_is(depsgraph, scene, ob);
/* fix parenting of objects which are bone-parented */
@@ -491,13 +491,14 @@ void POSE_OT_armature_apply(wmOperatorType *ot)
/* set the current pose as the restpose */
static int pose_visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
/* Needed to ensure #bPoseChannel.pose_mat are up to date. */
CTX_data_ensure_evaluated_depsgraph(C);
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
const bArmature *arm = ob->data;
int chanbase_len = BLI_listbase_count(&ob->pose->chanbase);
@@ -787,7 +788,7 @@ static int pose_copy_exec(bContext *C, wmOperator *op)
* existing on its own.
*/
BKE_copybuffer_copy_tag_ID(&ob_copy.id);
- BLI_join_dirfile(str, sizeof(str), BKE_tempdir_base(), "copybuffer_pose.blend");
+ BLI_path_join(str, sizeof(str), BKE_tempdir_base(), "copybuffer_pose.blend");
BKE_copybuffer_copy_end(temp_bmain, str, op->reports);
/* We clear the lists so no datablocks gets freed,
* This is required because objects in temp bmain shares same pointers
@@ -843,7 +844,7 @@ static int pose_paste_exec(bContext *C, wmOperator *op)
Main *tmp_bmain = BKE_main_new();
STRNCPY(tmp_bmain->filepath, BKE_main_blendfile_path_from_global());
- BLI_join_dirfile(str, sizeof(str), BKE_tempdir_base(), "copybuffer_pose.blend");
+ BLI_path_join(str, sizeof(str), BKE_tempdir_base(), "copybuffer_pose.blend");
if (!BKE_copybuffer_read(tmp_bmain, str, op->reports, FILTER_ID_OB)) {
BKE_report(op->reports, RPT_ERROR, "Copy buffer is empty");
BKE_main_free(tmp_bmain);
@@ -1115,7 +1116,7 @@ static void pchan_clear_rot(bPoseChannel *pchan)
}
/* Clear also Bendy Bone stuff - Roll is obvious,
- * but Curve X/Y stuff is also kindof rotational in nature... */
+ * but Curve X/Y stuff is also kind of rotational in nature... */
pchan->roll1 = 0.0f;
pchan->roll2 = 0.0f;
@@ -1168,7 +1169,7 @@ static int pose_clear_transform_generic_exec(bContext *C,
/* only clear relevant transforms for selected bones */
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) {
/* XXX: UGLY HACK (for auto-key + clear transforms). */
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob_iter);
ListBase dsources = {NULL, NULL};
@@ -1347,7 +1348,7 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
depsgraph, (float)scene->r.cfra);
const bool only_select = RNA_boolean_get(op->ptr, "only_selected");
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
if ((ob->adt) && (ob->adt->action)) {
/* XXX: this is just like this to avoid contaminating anything else;
* just pose values should change, so this should be fine
diff --git a/source/blender/editors/armature/pose_utils.c b/source/blender/editors/armature/pose_utils.c
index ea038362532..57ead6a0e65 100644
--- a/source/blender/editors/armature/pose_utils.c
+++ b/source/blender/editors/armature/pose_utils.c
@@ -251,7 +251,7 @@ void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, ListBase *pfLinks,
View3D *v3d = CTX_wm_view3d(C);
bool skip = true;
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
ob->id.tag &= ~LIB_TAG_DOIT;
ob = poseAnim_object_get(ob);
@@ -299,7 +299,7 @@ void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, ListBase *pfLinks,
* - only do this if keyframes should have been added
* - do not calculate unless there are paths already to update...
*/
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
if (ob->id.tag & LIB_TAG_DOIT) {
if (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) {
// ED_pose_clear_paths(C, ob); /* XXX for now, don't need to clear. */
diff --git a/source/blender/editors/asset/ED_asset_handle.h b/source/blender/editors/asset/ED_asset_handle.h
index ff39061f231..74e32dacd4b 100644
--- a/source/blender/editors/asset/ED_asset_handle.h
+++ b/source/blender/editors/asset/ED_asset_handle.h
@@ -35,3 +35,16 @@ void ED_asset_handle_get_full_library_path(const struct bContext *C,
#ifdef __cplusplus
}
#endif
+
+#ifdef __cplusplus
+
+namespace blender::ed::asset {
+
+/** If the ID already exists in the database, return it, otherwise add it. */
+ID *get_local_id_from_asset_or_append_and_reuse(Main &bmain,
+ const AssetLibraryReference &library_ref,
+ AssetHandle asset);
+
+} // namespace blender::ed::asset
+
+#endif
diff --git a/source/blender/editors/asset/ED_asset_list.h b/source/blender/editors/asset/ED_asset_list.h
index 607d3e96ada..72f7b670efa 100644
--- a/source/blender/editors/asset/ED_asset_list.h
+++ b/source/blender/editors/asset/ED_asset_list.h
@@ -27,6 +27,7 @@ void ED_assetlist_storage_fetch(const struct AssetLibraryReference *library_refe
const struct bContext *C);
void ED_assetlist_catalog_filter_set(const struct AssetLibraryReference *,
const struct AssetCatalogFilterSettings *catalog_filter);
+bool ED_assetlist_is_loaded(const struct AssetLibraryReference *library_reference);
void ED_assetlist_clear(const struct AssetLibraryReference *library_reference, struct bContext *C);
bool ED_assetlist_storage_has_list_for_library(const AssetLibraryReference *library_reference);
diff --git a/source/blender/editors/asset/intern/asset_handle.cc b/source/blender/editors/asset/intern/asset_handle.cc
index 6ff0dfe394b..43d69a50f91 100644
--- a/source/blender/editors/asset/intern/asset_handle.cc
+++ b/source/blender/editors/asset/intern/asset_handle.cc
@@ -8,14 +8,19 @@
#include "DNA_space_types.h"
+#include "BKE_asset.h"
+#include "BKE_asset_representation.hh"
+
#include "BLO_readfile.h"
#include "ED_asset_handle.h"
#include "ED_asset_list.hh"
+#include "WM_api.h"
+
const char *ED_asset_handle_get_name(const AssetHandle *asset)
{
- return asset->file_data->name;
+ return BKE_asset_representation_name_get(asset->file_data->asset);
}
const char *ED_asset_handle_get_identifier(const AssetHandle *asset)
@@ -23,9 +28,9 @@ const char *ED_asset_handle_get_identifier(const AssetHandle *asset)
return asset->file_data->relpath;
}
-AssetMetaData *ED_asset_handle_get_metadata(const AssetHandle *asset)
+AssetMetaData *ED_asset_handle_get_metadata(const AssetHandle *asset_handle)
{
- return asset->file_data->asset_data;
+ return BKE_asset_representation_metadata_get(asset_handle->file_data->asset);
}
ID *ED_asset_handle_get_local_id(const AssetHandle *asset)
@@ -52,3 +57,31 @@ void ED_asset_handle_get_full_library_path(const bContext *C,
BLO_library_path_explode(asset_path.c_str(), r_full_lib_path, nullptr, nullptr);
}
+
+namespace blender::ed::asset {
+
+ID *get_local_id_from_asset_or_append_and_reuse(Main &bmain,
+ const AssetLibraryReference &library_ref,
+ const AssetHandle asset)
+{
+ if (ID *local_id = ED_asset_handle_get_local_id(&asset)) {
+ return local_id;
+ }
+
+ char blend_path[FILE_MAX_LIBEXTRA];
+ ED_asset_handle_get_full_library_path(nullptr, &library_ref, &asset, blend_path);
+ const char *id_name = ED_asset_handle_get_name(&asset);
+
+ return WM_file_append_datablock(&bmain,
+ nullptr,
+ nullptr,
+ nullptr,
+ blend_path,
+ ED_asset_handle_get_id_type(&asset),
+ id_name,
+ BLO_LIBLINK_APPEND_RECURSIVE |
+ BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR |
+ BLO_LIBLINK_APPEND_LOCAL_ID_REUSE);
+}
+
+} // namespace blender::ed::asset
diff --git a/source/blender/editors/asset/intern/asset_list.cc b/source/blender/editors/asset/intern/asset_list.cc
index 697ee16f6fd..fa03f943e69 100644
--- a/source/blender/editors/asset/intern/asset_list.cc
+++ b/source/blender/editors/asset/intern/asset_list.cc
@@ -408,6 +408,18 @@ void ED_assetlist_storage_fetch(const AssetLibraryReference *library_reference,
AssetListStorage::fetch_library(*library_reference, *C);
}
+bool ED_assetlist_is_loaded(const AssetLibraryReference *library_reference)
+{
+ AssetList *list = AssetListStorage::lookup_list(*library_reference);
+ if (!list) {
+ return false;
+ }
+ if (list->needsRefetch()) {
+ return false;
+ }
+ return true;
+}
+
void ED_assetlist_catalog_filter_set(const struct AssetLibraryReference *library_reference,
const struct AssetCatalogFilterSettings *settings)
{
@@ -473,7 +485,7 @@ std::string ED_assetlist_asset_filepath_get(const bContext *C,
const char *asset_relpath = asset_handle.file_data->relpath;
char path[FILE_MAX_LIBEXTRA];
- BLI_join_dirfile(path, sizeof(path), library_path, asset_relpath);
+ BLI_path_join(path, sizeof(path), library_path, asset_relpath);
return path;
}
diff --git a/source/blender/editors/asset/intern/asset_ops.cc b/source/blender/editors/asset/intern/asset_ops.cc
index 4dddf2c5d52..a0083ed676d 100644
--- a/source/blender/editors/asset/intern/asset_ops.cc
+++ b/source/blender/editors/asset/intern/asset_ops.cc
@@ -344,8 +344,8 @@ static bool asset_clear_poll(bContext *C)
return true;
}
-static char *asset_clear_get_description(struct bContext *UNUSED(C),
- struct wmOperatorType *UNUSED(op),
+static char *asset_clear_get_description(struct bContext * /*C*/,
+ struct wmOperatorType * /*op*/,
struct PointerRNA *values)
{
const bool set_fake_user = RNA_boolean_get(values, "set_fake_user");
@@ -397,7 +397,7 @@ static bool asset_library_refresh_poll(bContext *C)
return ED_assetlist_storage_has_list_for_library(library);
}
-static int asset_library_refresh_exec(bContext *C, wmOperator *UNUSED(unused))
+static int asset_library_refresh_exec(bContext *C, wmOperator * /*unused*/)
{
/* Execution mode #1: Inside the Asset Browser. */
if (ED_operator_asset_browsing_active(C)) {
@@ -789,9 +789,9 @@ static int asset_bundle_install_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static const EnumPropertyItem *rna_asset_library_reference_itemf(bContext *UNUSED(C),
- PointerRNA *UNUSED(ptr),
- PropertyRNA *UNUSED(prop),
+static const EnumPropertyItem *rna_asset_library_reference_itemf(bContext * /*C*/,
+ PointerRNA * /*ptr*/,
+ PropertyRNA * /*prop*/,
bool *r_free)
{
const EnumPropertyItem *items = ED_asset_library_reference_to_rna_enum_itemf(false);
@@ -876,7 +876,7 @@ static bool set_filepath_for_asset_lib(const Main *bmain, struct wmOperator *op)
}
char file_path[PATH_MAX];
- BLI_join_dirfile(file_path, sizeof(file_path), lib->path, blend_filename);
+ BLI_path_join(file_path, sizeof(file_path), lib->path, blend_filename);
RNA_string_set(op->ptr, "filepath", file_path);
return true;
@@ -941,9 +941,9 @@ static bool has_external_files(Main *bmain, struct ReportList *reports)
callback_info.reports,
RPT_ERROR,
"Unable to copy bundle due to %zu external dependencies; more details on the console",
- (size_t)callback_info.external_files.size());
+ size_t(callback_info.external_files.size()));
printf("Unable to copy bundle due to %zu external dependencies:\n",
- (size_t)callback_info.external_files.size());
+ size_t(callback_info.external_files.size()));
for (const std::string &path : callback_info.external_files) {
printf(" \"%s\"\n", path.c_str());
}
diff --git a/source/blender/editors/asset/intern/asset_temp_id_consumer.cc b/source/blender/editors/asset/intern/asset_temp_id_consumer.cc
index 376454d62b6..d1fd48d966c 100644
--- a/source/blender/editors/asset/intern/asset_temp_id_consumer.cc
+++ b/source/blender/editors/asset/intern/asset_temp_id_consumer.cc
@@ -72,7 +72,7 @@ AssetTempIDConsumer *ED_asset_temp_id_consumer_create(const AssetHandle *handle)
if (!handle) {
return nullptr;
}
- BLI_assert(handle->file_data->asset_data != nullptr);
+ BLI_assert(handle->file_data->asset != nullptr);
return reinterpret_cast<AssetTempIDConsumer *>(
MEM_new<AssetTemporaryIDConsumer>(__func__, *handle));
}
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 2829e8bc115..f9377503630 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -1254,7 +1254,7 @@ void ED_curve_editnurb_load(Main *bmain, Object *obedit)
}
/* We have to pass also new copied nurbs, since we want to restore original curve
- * (without edited shapekey) on obdata, but *not* on editcurve itself
+ * (without edited shape-key) on obdata, but *not* on editcurve itself
* (ED_curve_editnurb_load call does not always implies freeing
* of editcurve, e.g. when called to generate render data). */
calc_shapeKeys(obedit, &newnurb);
@@ -1298,15 +1298,15 @@ void ED_curve_editnurb_make(Object *obedit)
BLI_addtail(&editnurb->nurbs, newnu);
}
- /* animation could be added in editmode even if there was no animdata in
- * object mode hence we always need CVs index be created */
+ /* Animation could be added in edit-mode even if there was no animdata in
+ * object mode hence we always need CVs index be created. */
init_editNurb_keyIndex(editnurb, &cu->nurb);
if (actkey) {
editnurb->shapenr = obedit->shapenr;
- /* Apply shapekey to new nurbs of editnurb, not those of original curve
+ /* Apply shape-key to new nurbs of editnurb, not those of original curve
* (and *after* we generated keyIndex), else we do not have valid 'original' data
- * to properly restore curve when leaving editmode. */
+ * to properly restore curve when leaving edit-mode. */
BKE_keyblock_convert_to_curve(actkey, cu, &editnurb->nurbs);
}
}
@@ -1343,7 +1343,7 @@ static int separate_exec(bContext *C, wmOperator *op)
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &bases_len);
+ scene, view_layer, CTX_wm_view3d(C), &bases_len);
for (uint b_index = 0; b_index < bases_len; b_index++) {
Base *oldbase = bases[b_index];
Base *newbase;
@@ -1468,6 +1468,7 @@ void CURVE_OT_separate(wmOperatorType *ot)
static int curve_split_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
bool changed = false;
@@ -1475,7 +1476,7 @@ static int curve_split_exec(bContext *C, wmOperator *op)
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Curve *cu = obedit->data;
@@ -1706,6 +1707,10 @@ static void ed_surf_delete_selected(Object *obedit)
bp++;
}
if (a == 0) {
+ if (cu->actnu == BLI_findindex(editnurb, nu)) {
+ cu->actnu = CU_ACT_NONE;
+ }
+
BLI_remlink(editnurb, nu);
keyIndex_delNurb(cu->editnurb, nu);
BKE_nurb_free(nu);
@@ -2545,12 +2550,13 @@ static void adduplicateflagNurb(
static int switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Curve *cu = obedit->data;
@@ -2606,10 +2612,11 @@ void CURVE_OT_switch_direction(wmOperatorType *ot)
static int set_goal_weight_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -2672,10 +2679,11 @@ void CURVE_OT_spline_weight_set(wmOperatorType *ot)
static int set_radius_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -2783,10 +2791,11 @@ static void smooth_single_bp(BPoint *bp,
static int smooth_exec(bContext *C, wmOperator *UNUSED(op))
{
const float factor = 1.0f / 6.0f;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -3079,10 +3088,11 @@ static void curve_smooth_value(ListBase *editnurb, const int bezt_offsetof, cons
static int curve_smooth_weight_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -3122,10 +3132,11 @@ void CURVE_OT_smooth_weight(wmOperatorType *ot)
static int curve_smooth_radius_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -3165,10 +3176,11 @@ void CURVE_OT_smooth_radius(wmOperatorType *ot)
static int curve_smooth_tilt_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -3208,6 +3220,7 @@ void CURVE_OT_smooth_tilt(wmOperatorType *ot)
static int hide_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -3215,7 +3228,7 @@ static int hide_exec(bContext *C, wmOperator *op)
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Curve *cu = obedit->data;
@@ -3310,13 +3323,14 @@ void CURVE_OT_hide(wmOperatorType *ot)
static int reveal_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const bool select = RNA_boolean_get(op->ptr, "select");
bool changed_multi = false;
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
ListBase *editnurb = object_editcurve_get(obedit);
@@ -3789,12 +3803,13 @@ static int subdivide_exec(bContext *C, wmOperator *op)
const int number_cuts = RNA_int_get(op->ptr, "number_cuts");
Main *bmain = CTX_data_main(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Curve *cu = obedit->data;
@@ -3847,10 +3862,11 @@ void CURVE_OT_subdivide(wmOperatorType *ot)
static int set_spline_type_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
int ret_value = OPERATOR_CANCELLED;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@@ -3940,13 +3956,14 @@ void CURVE_OT_spline_type_set(wmOperatorType *ot)
static int set_handle_type_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
const int handle_type = RNA_enum_get(op->ptr, "type");
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Curve *cu = obedit->data;
@@ -4002,6 +4019,7 @@ void CURVE_OT_handle_type_set(wmOperatorType *ot)
static int curve_normals_make_consistent_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -4009,7 +4027,7 @@ static int curve_normals_make_consistent_exec(bContext *C, wmOperator *op)
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Curve *cu = obedit->data;
@@ -4442,6 +4460,7 @@ static int merge_nurb(View3D *v3d, Object *obedit)
static int make_segment_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -4455,7 +4474,7 @@ static int make_segment_exec(bContext *C, wmOperator *op)
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Curve *cu = obedit->data;
@@ -4779,7 +4798,7 @@ bool ED_curve_editnurb_select_pick(bContext *C,
/* Deselect everything. */
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- vc.view_layer, vc.v3d, &objects_len);
+ vc.scene, vc.view_layer, vc.v3d, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob_iter = objects[ob_index];
@@ -4945,7 +4964,8 @@ bool ED_curve_editnurb_select_pick(bContext *C,
WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, NULL);
}
- if (vc.view_layer->basact != basact) {
+ BKE_view_layer_synced_ensure(vc.scene, vc.view_layer);
+ if (BKE_view_layer_active_base_get(vc.view_layer) != basact) {
ED_object_base_activate(C, basact);
}
@@ -4979,7 +4999,7 @@ bool ed_editnurb_spin(
invert_m3_m3(persinv, persmat);
/* imat and center and size */
- copy_m3_m4(bmat, obedit->obmat);
+ copy_m3_m4(bmat, obedit->object_to_world);
invert_m3_m3(imat, bmat);
axis_angle_to_mat3(cmat, axis, M_PI_4);
@@ -5046,6 +5066,7 @@ bool ed_editnurb_spin(
static int spin_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = ED_view3d_context_rv3d(C);
@@ -5065,7 +5086,7 @@ static int spin_exec(bContext *C, wmOperator *op)
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Curve *cu = (Curve *)obedit->data;
@@ -5074,8 +5095,8 @@ static int spin_exec(bContext *C, wmOperator *op)
continue;
}
- invert_m4_m4(obedit->imat, obedit->obmat);
- mul_m4_v3(obedit->imat, cent);
+ invert_m4_m4(obedit->world_to_object, obedit->object_to_world);
+ mul_m4_v3(obedit->world_to_object, cent);
if (!ed_editnurb_spin(viewmat, v3d, obedit, axis, cent)) {
count_failed += 1;
@@ -5553,7 +5574,7 @@ static int add_vertex_exec(bContext *C, wmOperator *op)
RNA_float_get_array(op->ptr, "location", location);
- invert_m4_m4(imat, obedit->obmat);
+ invert_m4_m4(imat, obedit->object_to_world);
mul_m4_v3(imat, location);
if (ed_editcurve_addvert(cu, editnurb, v3d, location)) {
@@ -5593,10 +5614,10 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ED_curve_nurb_vert_selected_find(cu, vc.v3d, &nu, &bezt, &bp);
if (bezt) {
- mul_v3_m4v3(location, vc.obedit->obmat, bezt->vec[1]);
+ mul_v3_m4v3(location, vc.obedit->object_to_world, bezt->vec[1]);
}
else if (bp) {
- mul_v3_m4v3(location, vc.obedit->obmat, bp->vec);
+ mul_v3_m4v3(location, vc.obedit->object_to_world, bp->vec);
}
else {
copy_v3_v3(location, vc.scene->cursor.location);
@@ -5641,8 +5662,8 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* get the plane */
float plane[4];
/* only normalize to avoid precision errors */
- normalize_v3_v3(plane, vc.obedit->obmat[2]);
- plane[3] = -dot_v3v3(plane, vc.obedit->obmat[3]);
+ normalize_v3_v3(plane, vc.obedit->object_to_world[2]);
+ plane[3] = -dot_v3v3(plane, vc.obedit->object_to_world[3]);
if (fabsf(dot_v3v3(view_dir, plane)) < eps) {
/* can't project on an aligned plane. */
@@ -5704,12 +5725,13 @@ void CURVE_OT_vertex_add(wmOperatorType *ot)
static int curve_extrude_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Curve *cu = obedit->data;
@@ -5846,12 +5868,13 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op)
{
const int direction = RNA_enum_get(op->ptr, "direction");
View3D *v3d = CTX_wm_view3d(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
bool changed_multi = false;
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Curve *cu = obedit->data;
@@ -5934,6 +5957,7 @@ void CURVE_OT_cyclic_toggle(wmOperatorType *ot)
static int duplicate_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -5942,7 +5966,7 @@ static int duplicate_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Curve *cu = obedit->data;
@@ -6442,10 +6466,11 @@ static int curve_delete_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
View3D *v3d = CTX_wm_view3d(C);
eCurveElem_Types type = RNA_enum_get(op->ptr, "type");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
bool changed_multi = false;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@@ -6462,6 +6487,7 @@ static int curve_delete_exec(bContext *C, wmOperator *op)
}
else if (type == CURVE_SEGMENT) {
changed = curve_delete_segments(obedit, v3d, false);
+ cu->actnu = CU_ACT_NONE;
}
else {
BLI_assert(0);
@@ -6469,7 +6495,7 @@ static int curve_delete_exec(bContext *C, wmOperator *op)
if (changed) {
changed_multi = true;
- cu->actnu = cu->actvert = CU_ACT_NONE;
+ cu->actvert = CU_ACT_NONE;
if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
@@ -6618,12 +6644,13 @@ void ed_dissolve_bez_segment(BezTriple *bezt_prev,
static int curve_dissolve_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Curve *cu = (Curve *)obedit->data;
@@ -6712,10 +6739,11 @@ static int curve_decimate_exec(bContext *C, wmOperator *op)
float ratio = RNA_float_get(op->ptr, "ratio");
bool all_supported_multi = true;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Curve *cu = (Curve *)obedit->data;
@@ -6792,11 +6820,12 @@ void CURVE_OT_decimate(wmOperatorType *ot)
static int shade_smooth_exec(bContext *C, wmOperator *op)
{
View3D *v3d = CTX_wm_view3d(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- int clear = (STREQ(op->idname, "CURVE_OT_shade_flat"));
+ int clear = STREQ(op->idname, "CURVE_OT_shade_flat");
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
int ret_value = OPERATOR_CANCELLED;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@@ -6895,7 +6924,7 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op)
/* Inverse transform for all selected curves in this object,
* See #object_join_exec for detailed comment on why the safe version is used. */
- invert_m4_m4_safe_ortho(imat, ob_active->obmat);
+ invert_m4_m4_safe_ortho(imat, ob_active->object_to_world);
Curve *cu_active = ob_active->data;
@@ -6907,7 +6936,7 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op)
if (cu->nurb.first) {
/* watch it: switch order here really goes wrong */
- mul_m4_m4m4(cmat, imat, ob_iter->obmat);
+ mul_m4_m4m4(cmat, imat, ob_iter->object_to_world);
/* Compensate for different bevel depth. */
bool do_radius = false;
@@ -6986,12 +7015,13 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op)
static int clear_tilt_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Curve *cu = obedit->data;
diff --git a/source/blender/editors/curve/editcurve_add.c b/source/blender/editors/curve/editcurve_add.c
index a21c8fc85f8..15d6592baae 100644
--- a/source/blender/editors/curve/editcurve_add.c
+++ b/source/blender/editors/curve/editcurve_add.c
@@ -343,7 +343,7 @@ Nurb *ED_curve_add_nurbs_primitive(
bp->vec[0] += fac * grid;
fac = (float)b - 1.5f;
bp->vec[1] += fac * grid;
- if ((ELEM(a, 1, 2)) && (ELEM(b, 1, 2))) {
+ if (ELEM(a, 1, 2) && ELEM(b, 1, 2)) {
bp->vec[2] += grid;
}
mul_m4_v3(mat, bp->vec);
@@ -496,6 +496,7 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf)
struct Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
ListBase *editnurb;
Nurb *nu;
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index 7632f1b1e64..af3d439dd2e 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -148,7 +148,7 @@ static void stroke_elem_pressure_set(const struct CurveDrawData *cdd,
const float adjust = stroke_elem_radius_from_pressure(cdd, pressure) -
stroke_elem_radius_from_pressure(cdd, selem->pressure);
madd_v3_v3fl(selem->location_local, selem->normal_local, adjust);
- mul_v3_m4v3(selem->location_world, cdd->vc.obedit->obmat, selem->location_local);
+ mul_v3_m4v3(selem->location_world, cdd->vc.obedit->object_to_world, selem->location_local);
}
selem->pressure = pressure;
}
@@ -245,11 +245,11 @@ static bool stroke_elem_project_fallback(const struct CurveDrawData *cdd,
cdd->vc.v3d, cdd->vc.region, location_fallback_depth, mval_fl, r_location_world);
zero_v3(r_normal_local);
}
- mul_v3_m4v3(r_location_local, cdd->vc.obedit->imat, r_location_world);
+ mul_v3_m4v3(r_location_local, cdd->vc.obedit->world_to_object, r_location_world);
if (!is_zero_v3(r_normal_world)) {
copy_v3_v3(r_normal_local, r_normal_world);
- mul_transposed_mat3_m4_v3(cdd->vc.obedit->obmat, r_normal_local);
+ mul_transposed_mat3_m4_v3(cdd->vc.obedit->object_to_world, r_normal_local);
normalize_v3(r_normal_local);
}
else {
@@ -304,7 +304,7 @@ static void curve_draw_stroke_from_operator_elem(wmOperator *op, PointerRNA *ite
RNA_float_get_array(itemptr, "mouse", selem->mval);
RNA_float_get_array(itemptr, "location", selem->location_world);
- mul_v3_m4v3(selem->location_local, cdd->vc.obedit->imat, selem->location_world);
+ mul_v3_m4v3(selem->location_local, cdd->vc.obedit->world_to_object, selem->location_world);
selem->pressure = RNA_float_get(itemptr, "pressure");
}
@@ -367,7 +367,7 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C),
/* scale to edit-mode space */
GPU_matrix_push();
- GPU_matrix_mul(obedit->obmat);
+ GPU_matrix_mul(obedit->object_to_world);
BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter)) {
@@ -445,7 +445,7 @@ static void curve_draw_event_add(wmOperator *op, const wmEvent *event)
struct CurveDrawData *cdd = op->customdata;
Object *obedit = cdd->vc.obedit;
- invert_m4_m4(obedit->imat, obedit->obmat);
+ invert_m4_m4(obedit->world_to_object, obedit->object_to_world);
struct StrokeElem *selem = BLI_mempool_calloc(cdd->stroke_elem_pool);
@@ -758,7 +758,7 @@ static int curve_draw_exec(bContext *C, wmOperator *op)
int stroke_len = BLI_mempool_len(cdd->stroke_elem_pool);
const bool is_3d = (cu->flag & CU_3D) != 0;
- invert_m4_m4(obedit->imat, obedit->obmat);
+ invert_m4_m4(obedit->world_to_object, obedit->object_to_world);
if (BLI_mempool_len(cdd->stroke_elem_pool) == 0) {
curve_draw_stroke_from_operator(op);
@@ -1073,8 +1073,8 @@ static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (CU_IS_2D(cu)) {
/* 2D overrides other options */
- plane_co = obedit->obmat[3];
- plane_no = obedit->obmat[2];
+ plane_co = obedit->object_to_world[3];
+ plane_no = obedit->object_to_world[2];
cdd->project.use_plane = true;
}
else {
diff --git a/source/blender/editors/curve/editcurve_pen.c b/source/blender/editors/curve/editcurve_pen.c
index 27f4e4fca61..b57ce6fc7cf 100644
--- a/source/blender/editors/curve/editcurve_pen.c
+++ b/source/blender/editors/curve/editcurve_pen.c
@@ -152,8 +152,8 @@ static void update_location_for_2d_curve(const ViewContext *vc, float location[3
/* Get the plane. */
float plane[4];
/* Only normalize to avoid precision errors. */
- normalize_v3_v3(plane, vc->obedit->obmat[2]);
- plane[3] = -dot_v3v3(plane, vc->obedit->obmat[3]);
+ normalize_v3_v3(plane, vc->obedit->object_to_world[2]);
+ plane[3] = -dot_v3v3(plane, vc->obedit->object_to_world[3]);
if (fabsf(dot_v3v3(view_dir, plane)) < eps) {
/* Can't project on an aligned plane. */
@@ -173,7 +173,7 @@ static void update_location_for_2d_curve(const ViewContext *vc, float location[3
}
float imat[4][4];
- invert_m4_m4(imat, vc->obedit->obmat);
+ invert_m4_m4(imat, vc->obedit->object_to_world);
mul_m4_v3(imat, location);
if (CU_IS_2D(cu)) {
@@ -186,7 +186,7 @@ static void screenspace_to_worldspace(const ViewContext *vc,
const float depth[3],
float r_pos_3d[3])
{
- mul_v3_m4v3(r_pos_3d, vc->obedit->obmat, depth);
+ mul_v3_m4v3(r_pos_3d, vc->obedit->object_to_world, depth);
ED_view3d_win_to_3d(vc->v3d, vc->region, r_pos_3d, pos_2d, r_pos_3d);
update_location_for_2d_curve(vc, r_pos_3d);
}
@@ -1082,7 +1082,7 @@ static void extrude_points_from_selected_vertices(const ViewContext *vc,
float location[3];
if (sel_exists) {
- mul_v3_m4v3(location, vc->obedit->obmat, center);
+ mul_v3_m4v3(location, vc->obedit->object_to_world, center);
}
else {
copy_v3_v3(location, vc->scene->cursor.location);
@@ -1366,12 +1366,10 @@ static bool make_cyclic_if_endpoints(ViewContext *vc,
BPoint *sel_bp)
{
if (sel_bezt || (sel_bp && sel_nu->pntsu > 2)) {
- const bool is_bezt_endpoint = (sel_nu->type == CU_BEZIER &&
- (sel_bezt == sel_nu->bezt ||
- sel_bezt == sel_nu->bezt + sel_nu->pntsu - 1));
- const bool is_bp_endpoint = (sel_nu->type != CU_BEZIER &&
- (sel_bp == sel_nu->bp ||
- sel_bp == sel_nu->bp + sel_nu->pntsu - 1));
+ const bool is_bezt_endpoint = ((sel_nu->type == CU_BEZIER) &&
+ ELEM(sel_bezt, sel_nu->bezt, sel_nu->bezt + sel_nu->pntsu - 1));
+ const bool is_bp_endpoint = ((sel_nu->type != CU_BEZIER) &&
+ ELEM(sel_bp, sel_nu->bp, sel_nu->bp + sel_nu->pntsu - 1));
if (!(is_bezt_endpoint || is_bp_endpoint)) {
return false;
}
@@ -1388,9 +1386,8 @@ static bool make_cyclic_if_endpoints(ViewContext *vc,
if (nu == sel_nu &&
((nu->type == CU_BEZIER && bezt != sel_bezt &&
- (bezt == nu->bezt || bezt == nu->bezt + nu->pntsu - 1) && bezt_idx == 1) ||
- (nu->type != CU_BEZIER && bp != sel_bp &&
- (bp == nu->bp || bp == nu->bp + nu->pntsu - 1)))) {
+ ELEM(bezt, nu->bezt, nu->bezt + nu->pntsu - 1) && bezt_idx == 1) ||
+ (nu->type != CU_BEZIER && bp != sel_bp && ELEM(bp, nu->bp, nu->bp + nu->pntsu - 1)))) {
View3D *v3d = vc->v3d;
ListBase *nurbs = object_editcurve_get(vc->obedit);
curve_toggle_cyclic(v3d, nurbs, 0);
@@ -1532,7 +1529,7 @@ wmKeyMap *curve_pen_modal_keymap(wmKeyConfig *keyconf)
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Curve Pen Modal Map");
- /* This function is called for each spacetype, only needs to add map once */
+ /* This function is called for each space-type, only needs to add map once. */
if (keymap && keymap->modal_items) {
return NULL;
}
diff --git a/source/blender/editors/curve/editcurve_query.c b/source/blender/editors/curve/editcurve_query.c
index a08dbbe6132..56268baf1f1 100644
--- a/source/blender/editors/curve/editcurve_query.c
+++ b/source/blender/editors/curve/editcurve_query.c
@@ -118,7 +118,7 @@ bool ED_curve_pick_vert_ex(ViewContext *vc,
uint bases_len;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- vc->view_layer, vc->v3d, &bases_len);
+ vc->scene, vc->view_layer, vc->v3d, &bases_len);
for (uint base_index = 0; base_index < bases_len; base_index++) {
Base *base = bases[base_index];
data.is_changed = false;
diff --git a/source/blender/editors/curve/editcurve_select.c b/source/blender/editors/curve/editcurve_select.c
index b7e6827c6df..da742dd0c61 100644
--- a/source/blender/editors/curve/editcurve_select.c
+++ b/source/blender/editors/curve/editcurve_select.c
@@ -259,7 +259,7 @@ bool ED_curve_deselect_all_multi(struct bContext *C)
ED_view3d_viewcontext_init(C, &vc, depsgraph);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- vc.view_layer, vc.v3d, &bases_len);
+ vc.scene, vc.view_layer, vc.v3d, &bases_len);
bool changed_multi = ED_curve_deselect_all_multi_ex(bases, bases_len);
MEM_freeN(bases);
return changed_multi;
@@ -468,10 +468,11 @@ static void selectend_nurb(Object *obedit, eEndPoint_Types selfirst, bool doswap
static int de_select_first_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -501,10 +502,11 @@ void CURVE_OT_de_select_first(wmOperatorType *ot)
static int de_select_last_exec(bContext *C, wmOperator *UNUSED(op))
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -543,11 +545,12 @@ static int de_select_all_exec(bContext *C, wmOperator *op)
{
int action = RNA_enum_get(op->ptr, "action");
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@@ -616,12 +619,13 @@ void CURVE_OT_select_all(wmOperatorType *ot)
static int select_linked_exec(bContext *C, wmOperator *UNUSED(op))
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Curve *cu = obedit->data;
@@ -818,10 +822,11 @@ void CURVE_OT_select_row(wmOperatorType *ot)
static int select_next_exec(bContext *C, wmOperator *UNUSED(op))
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -859,10 +864,11 @@ void CURVE_OT_select_next(wmOperatorType *ot)
static int select_previous_exec(bContext *C, wmOperator *UNUSED(op))
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -916,7 +922,7 @@ static void curve_select_more(Object *obedit)
bp = nu->bp;
selbpoints = BLI_BITMAP_NEW(a, "selectlist");
while (a > 0) {
- if ((!BLI_BITMAP_TEST(selbpoints, a)) && (bp->hide == 0) && (bp->f1 & SELECT)) {
+ if (!BLI_BITMAP_TEST(selbpoints, a) && (bp->hide == 0) && (bp->f1 & SELECT)) {
/* upper control point */
if (a % nu->pntsu != 0) {
tempbp = bp - 1;
@@ -975,10 +981,11 @@ static void curve_select_more(Object *obedit)
static int curve_select_more_exec(bContext *C, wmOperator *UNUSED(op))
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
curve_select_more(obedit);
@@ -1193,10 +1200,11 @@ static void curve_select_less(Object *obedit)
static int curve_select_less_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
curve_select_less(obedit);
@@ -1234,10 +1242,11 @@ static int curve_select_random_exec(bContext *C, wmOperator *op)
const float randfac = RNA_float_get(op->ptr, "ratio");
const int seed = WM_operator_properties_select_random_seed_increment_get(op);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -1414,6 +1423,7 @@ static bool ed_curve_select_nth(Curve *cu, const struct CheckerIntervalParams *p
static int select_nth_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *obact = CTX_data_edit_object(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -1424,7 +1434,7 @@ static int select_nth_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Curve *cu = obedit->data;
@@ -1507,7 +1517,7 @@ static void nurb_bezt_direction_worldspace_get(Object *ob,
{
float rsmat[3][3];
BKE_nurb_bezt_calc_normal(nu, bezt, r_dir);
- copy_m3_m4(rsmat, ob->obmat);
+ copy_m3_m4(rsmat, ob->object_to_world);
mul_m3_v3(rsmat, r_dir);
normalize_v3(r_dir);
}
@@ -1516,7 +1526,7 @@ static void nurb_bpoint_direction_worldspace_get(Object *ob, Nurb *nu, BPoint *b
{
float rsmat[3][3];
BKE_nurb_bpoint_calc_normal(nu, bp, r_dir);
- copy_m3_m4(rsmat, ob->obmat);
+ copy_m3_m4(rsmat, ob->object_to_world);
mul_m3_v3(rsmat, r_dir);
normalize_v3(r_dir);
}
@@ -1704,12 +1714,13 @@ static int curve_select_similar_exec(bContext *C, wmOperator *op)
const float thresh = RNA_float_get(op->ptr, "threshold");
const int compare = RNA_enum_get(op->ptr, "compare");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
int tot_nurbs_selected_all = 0;
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -2038,7 +2049,8 @@ static int edcu_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE
BKE_curve_nurb_vert_active_set(cu, nu_dst, vert_dst_p);
- if (vc.view_layer->basact != basact) {
+ BKE_view_layer_synced_ensure(vc.scene, vc.view_layer);
+ if (BKE_view_layer_active_base_get(vc.view_layer) != basact) {
ED_object_base_activate(C, basact);
}
diff --git a/source/blender/editors/curve/editcurve_undo.c b/source/blender/editors/curve/editcurve_undo.c
index cd350e8bd3c..3f53a88ba5d 100644
--- a/source/blender/editors/curve/editcurve_undo.c
+++ b/source/blender/editors/curve/editcurve_undo.c
@@ -160,7 +160,9 @@ static void undocurve_free_data(UndoCurve *uc)
static Object *editcurve_object_from_context(bContext *C)
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
if (obedit && ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) {
Curve *cu = obedit->data;
@@ -202,9 +204,10 @@ static bool curve_undosys_step_encode(struct bContext *C, struct Main *bmain, Un
/* Important not to use the 3D view when getting objects because all objects
* outside of this list will be moved out of edit-mode when reading back undo steps. */
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
- Object **objects = ED_undo_editmode_objects_from_view_layer(view_layer, &objects_len);
+ Object **objects = ED_undo_editmode_objects_from_view_layer(scene, view_layer, &objects_len);
us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
us->elems_len = objects_len;
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index ceed12dcff1..8adc5173e22 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -26,12 +26,15 @@
#include "BKE_context.h"
#include "BKE_curve.h"
+#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_vfont.h"
+#include "BLT_translation.h"
+
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
@@ -619,18 +622,19 @@ static void txt_add_object(bContext *C,
ViewLayer *view_layer = CTX_data_view_layer(C);
Curve *cu;
Object *obedit;
- Base *base;
+ Object *object;
const struct TextLine *tmp;
int nchars = 0, nbytes = 0;
char *s;
int a;
const float rot[3] = {0.0f, 0.0f, 0.0f};
- obedit = BKE_object_add(bmain, view_layer, OB_FONT, NULL);
- base = view_layer->basact;
+ obedit = BKE_object_add(bmain, scene, view_layer, OB_FONT, NULL);
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ object = BKE_view_layer_active_object_get(view_layer);
/* seems to assume view align ? TODO: look into this, could be an operator option. */
- ED_object_base_init_transform_on_add(base->object, NULL, rot);
+ ED_object_base_init_transform_on_add(object, NULL, rot);
BKE_object_where_is_calc(depsgraph, scene, obedit);
@@ -1156,14 +1160,13 @@ static int move_cursor(bContext *C, int type, const bool select)
}
case PREV_CHAR:
- ef->pos--;
+ BLI_str_cursor_step_prev_utf32(ef->textbuf, ef->len, &ef->pos);
cursmove = FO_CURS;
break;
case NEXT_CHAR:
- ef->pos++;
+ BLI_str_cursor_step_next_utf32(ef->textbuf, ef->len, &ef->pos);
cursmove = FO_CURS;
-
break;
case PREV_LINE:
@@ -1502,10 +1505,9 @@ static int delete_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- range[0] = ef->pos - 1;
range[1] = ef->pos;
-
- ef->pos--;
+ BLI_str_cursor_step_prev_utf32(ef->textbuf, ef->len, &ef->pos);
+ range[0] = ef->pos;
break;
case DEL_NEXT_CHAR:
if (ef->pos >= ef->len) {
@@ -1513,7 +1515,8 @@ static int delete_exec(bContext *C, wmOperator *op)
}
range[0] = ef->pos;
- range[1] = ef->pos + 1;
+ range[1] = ef->pos;
+ BLI_str_cursor_step_next_utf32(ef->textbuf, ef->len, &range[1]);
break;
case DEL_NEXT_WORD: {
int pos = ef->pos;
@@ -1962,6 +1965,8 @@ static int set_case_exec(bContext *C, wmOperator *op)
void FONT_OT_case_set(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Set Case";
ot->description = "Set font case";
@@ -1975,7 +1980,8 @@ void FONT_OT_case_set(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_enum(ot->srna, "case", case_items, CASE_LOWER, "Case", "Lower or upper case");
+ prop = RNA_def_enum(ot->srna, "case", case_items, CASE_LOWER, "Case", "Lower or upper case");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_TEXT);
}
/** \} */
diff --git a/source/blender/editors/curve/editfont_undo.c b/source/blender/editors/curve/editfont_undo.c
index 06d2357dc89..17ed75b9d10 100644
--- a/source/blender/editors/curve/editfont_undo.c
+++ b/source/blender/editors/curve/editfont_undo.c
@@ -308,7 +308,9 @@ static void undofont_free_data(UndoFont *uf)
static Object *editfont_object_from_context(bContext *C)
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
if (obedit && obedit->type == OB_FONT) {
Curve *cu = obedit->data;
diff --git a/source/blender/editors/curves/intern/curves_add.cc b/source/blender/editors/curves/intern/curves_add.cc
index f234a58f439..edcd1e32cc1 100644
--- a/source/blender/editors/curves/intern/curves_add.cc
+++ b/source/blender/editors/curves/intern/curves_add.cc
@@ -125,7 +125,7 @@ bke::CurvesGeometry primitive_random_sphere(const int curves_size, const int poi
float3 co = no;
for (int key = 0; key < points_per_curve; key++) {
- float t = key / (float)(points_per_curve - 1);
+ float t = key / float(points_per_curve - 1);
curve_positions[key] = co;
curve_radii[key] = 0.02f * (1.0f - t);
diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc
index 2386fd1030d..1d2b1264477 100644
--- a/source/blender/editors/curves/intern/curves_ops.cc
+++ b/source/blender/editors/curves/intern/curves_ops.cc
@@ -232,8 +232,7 @@ static void try_convert_single_object(Object &curves_ob,
BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh); });
const Span<float3> positions_cu = curves.positions();
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&surface_me),
- BKE_mesh_runtime_looptri_len(&surface_me)};
+ const Span<MLoopTri> looptris = surface_me.looptris();
if (looptris.is_empty()) {
*r_could_not_convert_some_curves = true;
@@ -337,7 +336,7 @@ static void try_convert_single_object(Object &curves_ob,
HairKey &key = hair_keys[key_i];
copy_v3_v3(key.co, key_pos_ha);
- key.time = 100.0f * key_i / (float)(hair_keys.size() - 1);
+ key.time = 100.0f * key_i / float(hair_keys.size() - 1);
}
}
@@ -436,7 +435,7 @@ static bke::CurvesGeometry particles_to_curves(Object &object, ParticleSystem &p
bke::CurvesGeometry curves(points_num, curves_num);
curves.offsets_for_write().copy_from(curve_offsets);
- const float4x4 object_to_world_mat = object.obmat;
+ const float4x4 object_to_world_mat = object.object_to_world;
const float4x4 world_to_object_mat = object_to_world_mat.inverted();
MutableSpan<float3> positions = curves.positions_for_write();
@@ -468,9 +467,10 @@ static bke::CurvesGeometry particles_to_curves(Object &object, ParticleSystem &p
return curves;
}
-static int curves_convert_from_particle_system_exec(bContext *C, wmOperator *UNUSED(op))
+static int curves_convert_from_particle_system_exec(bContext *C, wmOperator * /*op*/)
{
Main &bmain = *CTX_data_main(C);
+ Scene &scene = *CTX_data_scene(C);
ViewLayer &view_layer = *CTX_data_view_layer(C);
Depsgraph &depsgraph = *CTX_data_depsgraph_pointer(C);
Object *ob_from_orig = ED_object_active_context(C);
@@ -495,9 +495,9 @@ static int curves_convert_from_particle_system_exec(bContext *C, wmOperator *UNU
psys_eval = psmd->psys;
}
- Object *ob_new = BKE_object_add(&bmain, &view_layer, OB_CURVES, psys_eval->name);
+ Object *ob_new = BKE_object_add(&bmain, &scene, &view_layer, OB_CURVES, psys_eval->name);
Curves *curves_id = static_cast<Curves *>(ob_new->data);
- BKE_object_apply_mat4(ob_new, ob_from_orig->obmat, true, false);
+ BKE_object_apply_mat4(ob_new, ob_from_orig->object_to_world, true, false);
bke::CurvesGeometry::wrap(curves_id->geometry) = particles_to_curves(*ob_from_eval, *psys_eval);
DEG_relations_tag_update(&bmain);
@@ -544,8 +544,7 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob,
const Mesh &surface_mesh = *static_cast<const Mesh *>(surface_ob.data);
const Span<MVert> verts = surface_mesh.verts();
const Span<MLoop> loops = surface_mesh.loops();
- const Span<MLoopTri> surface_looptris = {BKE_mesh_runtime_looptri_ensure(&surface_mesh),
- BKE_mesh_runtime_looptri_len(&surface_mesh)};
+ const Span<MLoopTri> surface_looptris = surface_mesh.looptris();
VArraySpan<float2> surface_uv_map;
if (curves_id.surface_uv_map != nullptr) {
const bke::AttributeAccessor surface_attributes = surface_mesh.attributes();
@@ -715,13 +714,13 @@ static void CURVES_OT_snap_curves_to_surface(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
static const EnumPropertyItem attach_mode_items[] = {
- {static_cast<int>(AttachMode::Nearest),
+ {int(AttachMode::Nearest),
"NEAREST",
0,
"Nearest",
"Find the closest point on the surface for the root point of every curve and move the root "
"there"},
- {static_cast<int>(AttachMode::Deform),
+ {int(AttachMode::Deform),
"DEFORM",
0,
"Deform",
@@ -733,7 +732,7 @@ static void CURVES_OT_snap_curves_to_surface(wmOperatorType *ot)
RNA_def_enum(ot->srna,
"attach_mode",
attach_mode_items,
- static_cast<int>(AttachMode::Nearest),
+ int(AttachMode::Nearest),
"Attach Mode",
"How to find the point on the surface to attach to");
}
@@ -805,7 +804,7 @@ static void CURVES_OT_set_selection_domain(wmOperatorType *ot)
namespace disable_selection {
-static int curves_disable_selection_exec(bContext *C, wmOperator *UNUSED(op))
+static int curves_disable_selection_exec(bContext *C, wmOperator * /*op*/)
{
for (Curves *curves_id : get_unique_editable_curves(*C)) {
curves_id->flag &= ~CV_SCULPT_SELECTION_ENABLED;
@@ -998,6 +997,7 @@ static int surface_set_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&curves_ob.id, ID_RECALC_TRANSFORM);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, &curves_id);
+ WM_event_add_notifier(C, NC_NODE | NA_ADDED, NULL);
/* Required for deformation. */
new_surface_ob.modifier_flag |= OB_MODIFIER_FLAG_ADD_REST_POSITION;
diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt
index 9da2c4819a3..0a8130ffb56 100644
--- a/source/blender/editors/datafiles/CMakeLists.txt
+++ b/source/blender/editors/datafiles/CMakeLists.txt
@@ -375,6 +375,8 @@ set(ICON_NAMES
small_caps
modifier
con_action
+ mod_envelope
+ mod_outline
mod_length
mod_dash
mod_lineart
diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc
index 14f2f8c6af5..73b5cab1b25 100644
--- a/source/blender/editors/geometry/geometry_attributes.cc
+++ b/source/blender/editors/geometry/geometry_attributes.cc
@@ -67,8 +67,8 @@ static bool geometry_attributes_remove_poll(bContext *C)
}
static const EnumPropertyItem *geometry_attribute_domain_itemf(bContext *C,
- PointerRNA *UNUSED(ptr),
- PropertyRNA *UNUSED(prop),
+ PointerRNA * /*ptr*/,
+ PropertyRNA * /*prop*/,
bool *r_free)
{
if (C == nullptr) {
@@ -352,7 +352,7 @@ static int geometry_attribute_convert_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static void geometry_color_attribute_add_ui(bContext *UNUSED(C), wmOperator *op)
+static void geometry_color_attribute_add_ui(bContext * /*C*/, wmOperator *op)
{
uiLayout *layout = op->layout;
uiLayoutSetPropSep(layout, true);
@@ -566,7 +566,7 @@ void GEOMETRY_OT_color_attribute_duplicate(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static void geometry_attribute_convert_ui(bContext *UNUSED(C), wmOperator *op)
+static void geometry_attribute_convert_ui(bContext * /*C*/, wmOperator *op)
{
uiLayout *layout = op->layout;
uiLayoutSetPropSep(layout, true);
@@ -585,7 +585,7 @@ static void geometry_attribute_convert_ui(bContext *UNUSED(C), wmOperator *op)
static int geometry_attribute_convert_invoke(bContext *C,
wmOperator *op,
- const wmEvent *UNUSED(event))
+ const wmEvent * /*event*/)
{
return WM_operator_props_dialog_popup(C, op, 300);
}
@@ -612,8 +612,7 @@ void GEOMETRY_OT_attribute_convert(wmOperatorType *ot)
PropertyRNA *prop;
- RNA_def_enum(
- ot->srna, "mode", mode_items, static_cast<int>(ConvertAttributeMode::Generic), "Mode", "");
+ RNA_def_enum(ot->srna, "mode", mode_items, int(ConvertAttributeMode::Generic), "Mode", "");
prop = RNA_def_enum(ot->srna,
"domain",
diff --git a/source/blender/editors/gizmo_library/gizmo_library_presets.c b/source/blender/editors/gizmo_library/gizmo_library_presets.c
index 1ac4ce0bcdf..465c72dd44f 100644
--- a/source/blender/editors/gizmo_library/gizmo_library_presets.c
+++ b/source/blender/editors/gizmo_library/gizmo_library_presets.c
@@ -114,7 +114,7 @@ void ED_gizmo_draw_preset_facemap(
}
GPU_matrix_push();
- GPU_matrix_mul(ob->obmat);
+ GPU_matrix_mul(ob->object_to_world);
ED_draw_object_facemap(depsgraph, ob, color, facemap);
GPU_matrix_pop();
diff --git a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
index 6eac235a191..dca19dcf516 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
@@ -73,7 +73,7 @@ static void button2d_geom_draw_backdrop(const wmGizmo *gz,
GPU_viewport_size_get_f(viewport);
const float max_pixel_error = 0.25f;
- int nsegments = (int)(ceilf(M_PI / acosf(1.0f - max_pixel_error / screen_scale)));
+ int nsegments = (int)ceilf(M_PI / acosf(1.0f - max_pixel_error / screen_scale));
nsegments = max_ff(nsegments, 8);
nsegments = min_ff(nsegments, 1000);
diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
index 600abaf3737..4b78b122764 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
@@ -83,8 +83,8 @@ static bool gizmo_calc_rect_view_margin(const wmGizmo *gz, const float dims[2],
return false;
}
- margin[0] = ((handle_size * scale_xy[0]));
- margin[1] = ((handle_size * scale_xy[1]));
+ margin[0] = (handle_size * scale_xy[0]);
+ margin[1] = (handle_size * scale_xy[1]);
return true;
}
diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c
index 0a5ec3330c2..8e4b4519ff8 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c
@@ -81,9 +81,9 @@ static void gizmo_calc_rect_view_margin(const wmGizmo *gz, const float dims[3],
float scale_xyz[3];
gizmo_calc_rect_view_scale(gz, dims, scale_xyz);
- margin[0] = ((handle_size * scale_xyz[0]));
- margin[1] = ((handle_size * scale_xyz[1]));
- margin[2] = ((handle_size * scale_xyz[2]));
+ margin[0] = (handle_size * scale_xyz[0]);
+ margin[1] = (handle_size * scale_xyz[1]);
+ margin[2] = (handle_size * scale_xyz[2]);
}
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c
index 9b7b157dc7e..d7ae9be6c33 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c
@@ -106,9 +106,9 @@ static void dial_geom_draw(const float color[4],
UNUSED_VARS(gz, axis_modal_mat, clip_plane);
wm_gizmo_geometryinfo_draw(&wm_gizmo_geom_data_dial, select, color);
#else
- const bool filled = ((draw_options & (select ? (ED_GIZMO_DIAL_DRAW_FLAG_FILL |
- ED_GIZMO_DIAL_DRAW_FLAG_FILL_SELECT) :
- ED_GIZMO_DIAL_DRAW_FLAG_FILL)));
+ const bool filled = (draw_options & (select ? (ED_GIZMO_DIAL_DRAW_FLAG_FILL |
+ ED_GIZMO_DIAL_DRAW_FLAG_FILL_SELECT) :
+ ED_GIZMO_DIAL_DRAW_FLAG_FILL));
GPUVertFormat *format = immVertexFormat();
/* NOTE(Metal): Prefer using 3D coordinates with 3D shader, even if rendering 2D gizmo's. */
diff --git a/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c
index af1f09d7e25..f6ae02dd010 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c
@@ -93,9 +93,9 @@ static void move_geom_draw(const wmGizmo *gz,
#else
const int draw_style = RNA_enum_get(gz->ptr, "draw_style");
const bool filled = (draw_style != ED_GIZMO_MOVE_STYLE_CROSS_2D) &&
- ((draw_options & (select ? (ED_GIZMO_MOVE_DRAW_FLAG_FILL |
- ED_GIZMO_MOVE_DRAW_FLAG_FILL_SELECT) :
- ED_GIZMO_MOVE_DRAW_FLAG_FILL)));
+ (draw_options & (select ? (ED_GIZMO_MOVE_DRAW_FLAG_FILL |
+ ED_GIZMO_MOVE_DRAW_FLAG_FILL_SELECT) :
+ ED_GIZMO_MOVE_DRAW_FLAG_FILL));
GPUVertFormat *format = immVertexFormat();
/* NOTE(Metal): Prefer using 3D coordinates with 3D shader, even if rendering 2D gizmo's. */
diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c
index 287dce1a509..2fd58a9cee0 100644
--- a/source/blender/editors/gpencil/annotate_paint.c
+++ b/source/blender/editors/gpencil/annotate_paint.c
@@ -13,9 +13,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
-#include "BLI_math.h"
-#include "BLI_math_geom.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
@@ -321,7 +318,7 @@ static void annotation_stroke_convertcoords(tGPsdata *p,
int mval_i[2];
round_v2i_v2fl(mval_i, mval);
if (annotation_project_check(p) &&
- (ED_view3d_autodist_simple(p->region, mval_i, out, 0, depth))) {
+ ED_view3d_autodist_simple(p->region, mval_i, out, 0, depth)) {
/* projecting onto 3D-Geometry
* - nothing more needs to be done here, since view_autodist_simple() has already done it
*/
@@ -1120,7 +1117,7 @@ static void annotation_stroke_eraser_dostroke(tGPsdata *p,
gpencil_point_to_xy(&p->gsc, gps, gps->points, &pc1[0], &pc1[1]);
/* Do bound-box check first. */
- if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
+ if (!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1]) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
/* only check if point is inside */
if (len_v2v2_int(mval_i, pc1) <= radius) {
/* free stroke */
@@ -1162,8 +1159,8 @@ static void annotation_stroke_eraser_dostroke(tGPsdata *p,
gpencil_point_to_xy(&p->gsc, gps, pt2, &pc2[0], &pc2[1]);
/* Check that point segment of the bound-box of the eraser stroke. */
- if (((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) ||
- ((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) {
+ if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1]) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) ||
+ (!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1]) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) {
/* Check if point segment of stroke had anything to do with
* eraser region (either within stroke painted, or on its lines)
* - this assumes that line-width is irrelevant.
@@ -2346,7 +2343,7 @@ static int annotation_draw_invoke(bContext *C, wmOperator *op, const wmEvent *ev
return OPERATOR_RUNNING_MODAL;
}
-/* gpencil modal operator stores area, which can be removed while using it (like fullscreen) */
+/* gpencil modal operator stores area, which can be removed while using it (like full-screen). */
static bool annotation_area_exists(bContext *C, ScrArea *area_test)
{
bScreen *screen = CTX_wm_screen(C);
@@ -2520,7 +2517,7 @@ static int annotation_draw_modal(bContext *C, wmOperator *op, const wmEvent *eve
* (Disabling RIGHTMOUSE case here results in bugs like T32647)
* also making sure we have a valid event value, to not exit too early
*/
- if (ELEM(event->type, LEFTMOUSE, RIGHTMOUSE) && (ELEM(event->val, KM_PRESS, KM_RELEASE))) {
+ if (ELEM(event->type, LEFTMOUSE, RIGHTMOUSE) && ELEM(event->val, KM_PRESS, KM_RELEASE)) {
/* if painting, end stroke */
if (p->status == GP_STATUS_PAINTING) {
int sketch = 0;
@@ -2698,7 +2695,7 @@ static int annotation_draw_modal(bContext *C, wmOperator *op, const wmEvent *eve
}
}
- /* gpencil modal operator stores area, which can be removed while using it (like fullscreen) */
+ /* gpencil modal operator stores area, which can be removed while using it (like full-screen). */
if (0 == annotation_area_exists(C, p->area)) {
estate = OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/gpencil/gpencil_armature.c b/source/blender/editors/gpencil/gpencil_armature.c
index d389f7eb5dd..2b7e09b7f05 100644
--- a/source/blender/editors/gpencil/gpencil_armature.c
+++ b/source/blender/editors/gpencil/gpencil_armature.c
@@ -29,6 +29,7 @@
#include "BKE_deform.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_modifier.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_object_deform.h"
#include "BKE_report.h"
@@ -328,8 +329,8 @@ static void gpencil_add_verts_to_dgroups(
copy_v3_v3(tip[j], bone->arm_tail);
}
- mul_m4_v3(ob_arm->obmat, root[j]);
- mul_m4_v3(ob_arm->obmat, tip[j]);
+ mul_m4_v3(ob_arm->object_to_world, root[j]);
+ mul_m4_v3(ob_arm->object_to_world, tip[j]);
selected[j] = 1;
@@ -363,7 +364,7 @@ static void gpencil_add_verts_to_dgroups(
/* transform stroke points to global space */
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
copy_v3_v3(verts[i], &pt->x);
- mul_m4_v3(ob->obmat, verts[i]);
+ mul_m4_v3(ob->object_to_world, verts[i]);
}
/* loop groups and assign weight */
@@ -528,6 +529,7 @@ static bool gpencil_generate_weights_poll(bContext *C)
return false;
}
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
bGPdata *gpd = (bGPdata *)ob->data;
@@ -536,7 +538,8 @@ static bool gpencil_generate_weights_poll(bContext *C)
}
/* need some armature in the view layer */
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (base->object->type == OB_ARMATURE) {
return true;
}
@@ -548,6 +551,7 @@ static bool gpencil_generate_weights_poll(bContext *C)
static int gpencil_generate_weights_exec(bContext *C, wmOperator *op)
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = CTX_data_active_object(C);
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
@@ -566,7 +570,8 @@ static int gpencil_generate_weights_exec(bContext *C, wmOperator *op)
/* get armature */
const int arm_idx = RNA_enum_get(op->ptr, "armature");
if (arm_idx > 0) {
- Base *base = BLI_findlink(&view_layer->object_bases, arm_idx - 1);
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base = BLI_findlink(BKE_view_layer_object_bases_get(view_layer), arm_idx - 1);
ob_arm = base->object;
}
else {
@@ -607,6 +612,7 @@ static const EnumPropertyItem *gpencil_armatures_enum_itemf(bContext *C,
PropertyRNA *UNUSED(prop),
bool *r_free)
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
EnumPropertyItem *item = NULL, item_tmp = {0};
int totitem = 0;
@@ -623,7 +629,8 @@ static const EnumPropertyItem *gpencil_armatures_enum_itemf(bContext *C,
RNA_enum_item_add(&item, &totitem, &item_tmp);
i++;
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *ob = base->object;
if (ob->type == OB_ARMATURE) {
item_tmp.identifier = item_tmp.name = ob->id.name + 2;
diff --git a/source/blender/editors/gpencil/gpencil_bake_animation.cc b/source/blender/editors/gpencil/gpencil_bake_animation.cc
index e480852a9bb..4ef2cf9ffd6 100644
--- a/source/blender/editors/gpencil/gpencil_bake_animation.cc
+++ b/source/blender/editors/gpencil/gpencil_bake_animation.cc
@@ -65,8 +65,8 @@ const EnumPropertyItem rna_gpencil_reproject_type_items[] = {
};
/* Check frame_end is always > start frame! */
-static void gpencil_bake_set_frame_end(struct Main *UNUSED(main),
- struct Scene *UNUSED(scene),
+static void gpencil_bake_set_frame_end(struct Main * /*main*/,
+ struct Scene * /*scene*/,
struct PointerRNA *ptr)
{
int frame_start = RNA_int_get(ptr, "frame_start");
@@ -86,7 +86,7 @@ static bool gpencil_bake_grease_pencil_animation_poll(bContext *C)
}
/* Check if grease pencil or empty for dupli groups. */
- if ((obact == nullptr) || (!ELEM(obact->type, OB_GPENCIL, OB_EMPTY))) {
+ if ((obact == nullptr) || !ELEM(obact->type, OB_GPENCIL, OB_EMPTY)) {
return false;
}
@@ -119,7 +119,7 @@ static void animdata_keyframe_list_get(ListBase *ob_list,
/* Keyframe number is x value of point. */
if ((bezt->f2 & SELECT) || (!only_selected)) {
/* Insert only one key for each keyframe number. */
- int key = (int)bezt->vec[1][0];
+ int key = int(bezt->vec[1][0]);
if (!BLI_ghash_haskey(r_keyframes, POINTER_FROM_INT(key))) {
BLI_ghash_insert(r_keyframes, POINTER_FROM_INT(key), POINTER_FROM_INT(key));
}
@@ -222,7 +222,7 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op
ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0;
ob_gpencil = ED_gpencil_add_object(C, scene->cursor.location, local_view_bits);
float invmat[4][4];
- invert_m4_m4(invmat, ob_gpencil->obmat);
+ invert_m4_m4(invmat, ob_gpencil->object_to_world);
bGPdata *gpd_dst = (bGPdata *)ob_gpencil->data;
gpd_dst->draw_mode = GP_DRAWMODE_2D;
@@ -243,7 +243,7 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op
}
/* Loop all frame range. */
- int oldframe = (int)DEG_get_ctime(depsgraph);
+ int oldframe = int(DEG_get_ctime(depsgraph));
int key = -1;
/* Get list of keyframes. */
@@ -260,7 +260,7 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op
}
/* Check if frame is in the list of frames to be exported. */
- if ((only_selected) && (!BLI_ghash_haskey(keyframe_list, POINTER_FROM_INT(i)))) {
+ if ((only_selected) && !BLI_ghash_haskey(keyframe_list, POINTER_FROM_INT(i))) {
continue;
}
@@ -298,6 +298,7 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op
BLI_addtail(&gpl_dst->frames, gpf_dst);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf_dst->strokes) {
+ gps->runtime.gps_orig = nullptr;
/* Create material of the stroke. */
Material *ma_src = BKE_object_material_get(elem->ob, gps->mat_nr + 1);
bool found = false;
@@ -320,14 +321,16 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op
/* Update point location to new object space. */
for (int j = 0; j < gps->totpoints; j++) {
bGPDspoint *pt = &gps->points[j];
- mul_m4_v3(ob_eval->obmat, &pt->x);
+ pt->runtime.idx_orig = 0;
+ pt->runtime.pt_orig = nullptr;
+ mul_m4_v3(ob_eval->object_to_world, &pt->x);
mul_m4_v3(invmat, &pt->x);
}
/* Reproject stroke. */
if (project_type != GP_REPROJECT_KEEP) {
ED_gpencil_stroke_reproject(
- depsgraph, &gsc, sctx, gpl_dst, gpf_dst, gps, project_type, false);
+ depsgraph, &gsc, sctx, gpl_dst, gpf_dst, gps, project_type, false, 0.0f);
}
else {
BKE_gpencil_stroke_geometry_update(gpd_dst, gps);
@@ -366,7 +369,7 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op
static int gpencil_bake_grease_pencil_animation_invoke(bContext *C,
wmOperator *op,
- const wmEvent *UNUSED(event))
+ const wmEvent * /*event*/)
{
PropertyRNA *prop;
Scene *scene = CTX_data_scene(C);
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index e02a82f4555..17ec33dc2bd 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -270,14 +270,13 @@ static void gpencil_timing_data_add_point(tGpTimingData *gtd,
}
else if (time < 0.0f) {
/* This is a gap, negative value! */
- gtd->times[cur_point] = -(((float)(stroke_inittime - gtd->inittime)) + time +
- gtd->offset_time);
+ gtd->times[cur_point] = -((float)(stroke_inittime - gtd->inittime) + time + gtd->offset_time);
delta_time = -gtd->times[cur_point] - gtd->times[cur_point - 1];
gtd->gap_tot_time += delta_time;
}
else {
- gtd->times[cur_point] = (((float)(stroke_inittime - gtd->inittime)) + time + gtd->offset_time);
+ gtd->times[cur_point] = ((float)(stroke_inittime - gtd->inittime) + time + gtd->offset_time);
delta_time = gtd->times[cur_point] - fabsf(gtd->times[cur_point - 1]);
}
@@ -1303,6 +1302,7 @@ static void gpencil_layer_to_curve(bContext *C,
ob = BKE_object_add_only_object(bmain, OB_CURVES_LEGACY, gpl->info);
cu = ob->data = BKE_curve_add(bmain, gpl->info, OB_CURVES_LEGACY);
BKE_collection_object_add(bmain, collection, ob);
+ BKE_view_layer_synced_ensure(scene, view_layer);
base_new = BKE_view_layer_base_find(view_layer, ob);
DEG_relations_tag_update(bmain); /* added object */
@@ -1482,7 +1482,7 @@ static bool gpencil_convert_poll(bContext *C)
*/
return ((area && area->spacetype == SPACE_VIEW3D) && (gpl = BKE_gpencil_layer_active_get(gpd)) &&
(gpf = BKE_gpencil_layer_frame_get(gpl, scene->r.cfra, GP_GETFRAME_USE_PREV)) &&
- (gpf->strokes.first) && (!GPENCIL_ANY_EDIT_MODE(gpd)));
+ (gpf->strokes.first) && !GPENCIL_ANY_EDIT_MODE(gpd));
}
static int gpencil_convert_layer_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index 340288b2d74..0417694d7bd 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -623,6 +623,7 @@ void GPENCIL_OT_layer_duplicate_object(wmOperatorType *ot)
true,
"Only Active",
"Copy only active Layer, uncheck to append all layers");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_GPENCIL);
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
@@ -2913,8 +2914,8 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
float offset_global[3];
float offset_local[3];
- sub_v3_v3v3(offset_global, ob_active->loc, ob_iter->obmat[3]);
- copy_m3_m4(bmat, ob_active->obmat);
+ sub_v3_v3v3(offset_global, ob_active->loc, ob_iter->object_to_world[3]);
+ copy_m3_m4(bmat, ob_active->object_to_world);
/* Inverse transform for all selected curves in this object,
* See #object_join_exec for detailed comment on why the safe version is used. */
@@ -3686,6 +3687,7 @@ void GPENCIL_OT_materials_copy_to_object(wmOperatorType *ot)
true,
"Only Active",
"Append only active material, uncheck to append all materials");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_GPENCIL);
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index d53c0af2c54..f9b40a4c79b 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -1618,7 +1618,7 @@ static bool gpencil_strokes_paste_poll(bContext *C)
* 2) Copy buffer must at least have something (though it may be the wrong sort...).
*/
return (ED_gpencil_data_get_active(C) != NULL) &&
- (!BLI_listbase_is_empty(&gpencil_strokes_copypastebuf));
+ !BLI_listbase_is_empty(&gpencil_strokes_copypastebuf);
}
typedef enum eGP_PasteMode {
@@ -2914,7 +2914,7 @@ static int gpencil_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
/* return data */
copy_v3_v3(&pt->x, fpt);
- gpencil_apply_parent_point(depsgraph, obact, gpl, pt);
+ gpencil_world_to_object_space_point(depsgraph, obact, gpl, pt);
changed = true;
}
@@ -3015,7 +3015,7 @@ static int gpencil_snap_to_cursor(bContext *C, wmOperator *op)
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
if (pt->flag & GP_SPOINT_SELECT) {
copy_v3_v3(&pt->x, cursor_global);
- gpencil_apply_parent_point(depsgraph, obact, gpl, pt);
+ gpencil_world_to_object_space_point(depsgraph, obact, gpl, pt);
changed = true;
}
@@ -3848,7 +3848,12 @@ static int gpencil_stroke_start_set_exec(bContext *C, wmOperator *op)
for (int i = 0; i < gps->totpoints; i++) {
pt = &gps->points[i];
if (pt->flag & GP_SPOINT_SELECT) {
- BKE_gpencil_stroke_start_set(gps, i);
+ if (i == gps->totpoints - 1) {
+ BKE_gpencil_stroke_flip(gps);
+ }
+ else {
+ BKE_gpencil_stroke_start_set(gps, i);
+ }
BKE_gpencil_stroke_geometry_update(gpd, gps);
changed = true;
break;
@@ -3905,6 +3910,7 @@ static int gpencil_strokes_reproject_exec(bContext *C, wmOperator *op)
const bool keep_original = RNA_boolean_get(op->ptr, "keep_original");
const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd);
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ const float offset = RNA_float_get(op->ptr, "offset");
/* Init snap context for geometry projection. */
SnapObjectContext *sctx = NULL;
@@ -3944,7 +3950,8 @@ static int gpencil_strokes_reproject_exec(bContext *C, wmOperator *op)
BKE_scene_graph_update_for_newframe(depsgraph);
}
- ED_gpencil_stroke_reproject(depsgraph, &gsc, sctx, gpl, gpf, gps, mode, keep_original);
+ ED_gpencil_stroke_reproject(
+ depsgraph, &gsc, sctx, gpl, gpf, gps, mode, keep_original, offset);
if (is_curve_edit && gps->editcurve != NULL) {
BKE_gpencil_stroke_editcurve_update(gpd, gpl, gps);
@@ -3984,8 +3991,29 @@ static int gpencil_strokes_reproject_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static void gpencil_strokes_reproject_ui(bContext *UNUSED(C), wmOperator *op)
+{
+ uiLayout *layout = op->layout;
+ uiLayout *row;
+
+ const eGP_ReprojectModes type = RNA_enum_get(op->ptr, "type");
+
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+ row = uiLayoutRow(layout, true);
+ uiItemR(row, op->ptr, "type", 0, NULL, ICON_NONE);
+
+ if (type == GP_REPROJECT_SURFACE) {
+ row = uiLayoutRow(layout, true);
+ uiItemR(row, op->ptr, "offset", 0, NULL, ICON_NONE);
+ }
+ row = uiLayoutRow(layout, true);
+ uiItemR(row, op->ptr, "keep_original", 0, NULL, ICON_NONE);
+}
+
void GPENCIL_OT_reproject(wmOperatorType *ot)
{
+ PropertyRNA *prop;
static const EnumPropertyItem reproject_type[] = {
{GP_REPROJECT_FRONT, "FRONT", 0, "Front", "Reproject the strokes using the X-Z plane"},
{GP_REPROJECT_SIDE, "SIDE", 0, "Side", "Reproject the strokes using the Y-Z plane"},
@@ -4023,6 +4051,7 @@ void GPENCIL_OT_reproject(wmOperatorType *ot)
ot->invoke = WM_menu_invoke;
ot->exec = gpencil_strokes_reproject_exec;
ot->poll = gpencil_strokes_edit3d_poll;
+ ot->ui = gpencil_strokes_reproject_ui;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -4031,12 +4060,15 @@ void GPENCIL_OT_reproject(wmOperatorType *ot)
ot->prop = RNA_def_enum(
ot->srna, "type", reproject_type, GP_REPROJECT_VIEW, "Projection Type", "");
- RNA_def_boolean(
+ prop = RNA_def_boolean(
ot->srna,
"keep_original",
0,
"Keep Original",
"Keep original strokes and create a copy before reprojecting instead of reproject them");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_MOVIECLIP);
+
+ RNA_def_float(ot->srna, "offset", 0.0f, 0.0f, 10.0f, "Surface Offset", "", 0.0f, 10.0f);
}
static int gpencil_recalc_geometry_exec(bContext *C, wmOperator *UNUSED(op))
@@ -4130,7 +4162,7 @@ static int gpencil_stroke_outline_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Object *cam_ob = scene->camera;
if (cam_ob != NULL) {
- invert_m4_m4(viewmat, cam_ob->obmat);
+ invert_m4_m4(viewmat, cam_ob->object_to_world);
}
break;
}
@@ -4197,7 +4229,7 @@ static int gpencil_stroke_outline_exec(bContext *C, wmOperator *op)
/* Apply layer thickness change. */
gps_duplicate->thickness += gpl->line_change;
/* Apply object scale to thickness. */
- gps_duplicate->thickness *= mat4_to_scale(ob->obmat);
+ gps_duplicate->thickness *= mat4_to_scale(ob->object_to_world);
CLAMP_MIN(gps_duplicate->thickness, 1.0f);
/* Stroke. */
@@ -4987,7 +5019,7 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- if ((mode == GP_SEPARATE_LAYER) && (BLI_listbase_is_single(&gpd_src->layers))) {
+ if ((mode == GP_SEPARATE_LAYER) && BLI_listbase_is_single(&gpd_src->layers)) {
BKE_report(op->reports, RPT_ERROR, "Cannot separate an object with one layer only");
return OPERATOR_CANCELLED;
}
@@ -5194,7 +5226,9 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
for (int slot = 1; slot <= ob_dst->totcol; slot++) {
while (slot <= ob_dst->totcol && !BKE_object_material_slot_used(ob_dst, slot)) {
ob_dst->actcol = slot;
- BKE_object_material_slot_remove(bmain, ob_dst);
+ if (!BKE_object_material_slot_remove(bmain, ob_dst)) {
+ break;
+ }
if (actcol >= slot) {
actcol--;
}
@@ -5431,10 +5465,10 @@ static bool gpencil_test_lasso(bGPDstroke *gps,
const struct GP_SelectLassoUserData *data = user_data;
bGPDspoint pt2;
int x0, y0;
- gpencil_point_to_parent_space(pt, diff_mat, &pt2);
+ gpencil_point_to_world_space(pt, diff_mat, &pt2);
gpencil_point_to_xy(gsc, gps, &pt2, &x0, &y0);
/* test if in lasso */
- return ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&data->rect, x0, y0) &&
+ return (!ELEM(V2D_IS_CLIPPED, x0, y0) && BLI_rcti_isect_pt(&data->rect, x0, y0) &&
BLI_lasso_is_point_inside(data->mcoords, data->mcoords_len, x0, y0, INT_MAX));
}
@@ -5559,7 +5593,7 @@ static int gpencil_cutter_lasso_select(bContext *C,
/* Select points */
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- if ((gpl->flag & GP_LAYER_LOCKED) || ((gpl->flag & GP_LAYER_HIDE))) {
+ if ((gpl->flag & GP_LAYER_LOCKED) || (gpl->flag & GP_LAYER_HIDE)) {
continue;
}
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 5305c764b3a..5c88e719b8c 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -67,6 +67,7 @@
#define LEAK_HORZ 0
#define LEAK_VERT 1
+#define FILL_LEAK 3.0f
#define MIN_WINDOW_SIZE 128
/* Set to 1 to debug filling internal image. By default, the value must be 0. */
@@ -78,6 +79,22 @@ enum {
GP_DRAWFILLS_ONLY3D = (1 << 1), /* only draw 3d-strokes */
};
+/* Temporary stroke data including stroke extensions. */
+typedef struct tStroke {
+ /* Referenced layer. */
+ bGPDlayer *gpl;
+ /** Referenced frame. */
+ bGPDframe *gpf;
+ /** Referenced stroke. */
+ bGPDstroke *gps;
+ /** Array of 2D points */
+ float (*points2d)[2];
+ /** Extreme Stroke A. */
+ bGPDstroke *gps_ext_a;
+ /** Extreme Stroke B. */
+ bGPDstroke *gps_ext_b;
+} tStroke;
+
/* Temporary fill operation data `op->customdata`. */
typedef struct tGPDfill {
bContext *C;
@@ -114,7 +131,7 @@ typedef struct tGPDfill {
/** For operations that require occlusion testing. */
struct ViewDepths *depths;
/** flags */
- short flag;
+ int flag;
/** avoid too fast events */
short oldkey;
/** send to back stroke */
@@ -140,12 +157,25 @@ typedef struct tGPDfill {
int fill_simplylvl;
/** boundary limits drawing mode */
int fill_draw_mode;
+ /** types of extensions **/
+ int fill_extend_mode;
/* scaling factor */
float fill_factor;
/* Frame to use. */
int active_cfra;
+ /** Center mouse position for extend length. */
+ float mouse_center[2];
+ /** Init mouse position for extend length. */
+ float mouse_init[2];
+ /** Last mouse position. */
+ float mouse_pos[2];
+ /** Use when mouse input is interpreted as spatial distance. */
+ float pixel_size;
+ /** Initial extend vector length. */
+ float initial_length;
+
/** number of elements currently in cache */
short sbuffer_used;
/** temporary points */
@@ -157,7 +187,7 @@ typedef struct tGPDfill {
Image *ima;
/** temp points data */
BLI_Stack *stack;
- /** handle for drawing strokes while operator is running 3d stuff */
+ /** handle for drawing strokes while operator is running 3d stuff. */
void *draw_handle_3d;
/* Temporary size x. */
@@ -174,11 +204,29 @@ typedef struct tGPDfill {
/** Factor of extension. */
float fill_extend_fac;
-
+ /** Size of stroke_array. */
+ int stroke_array_num;
+ /** Temp strokes array to handle strokes and stroke extensions. */
+ tStroke **stroke_array;
} tGPDfill;
bool skip_layer_check(short fill_layer_mode, int gpl_active_index, int gpl_index);
static void gpencil_draw_boundary_lines(const struct bContext *UNUSED(C), struct tGPDfill *tgpf);
+static void gpencil_fill_status_indicators(struct tGPDfill *tgpf);
+
+/* Free temp stroke array. */
+static void stroke_array_free(tGPDfill *tgpf)
+{
+ if (tgpf->stroke_array) {
+ for (int i = 0; i < tgpf->stroke_array_num; i++) {
+ tStroke *stroke = tgpf->stroke_array[i];
+ MEM_SAFE_FREE(stroke->points2d);
+ MEM_freeN(stroke);
+ }
+ MEM_SAFE_FREE(tgpf->stroke_array);
+ }
+ tgpf->stroke_array_num = 0;
+}
/* Delete any temporary stroke. */
static void gpencil_delete_temp_stroke_extension(tGPDfill *tgpf, const bool all_frames)
@@ -197,7 +245,8 @@ static void gpencil_delete_temp_stroke_extension(tGPDfill *tgpf, const bool all_
for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
/* free stroke */
- if ((gps->flag & GP_STROKE_NOFILL) && (gps->flag & GP_STROKE_TAG)) {
+ if ((gps->flag & GP_STROKE_NOFILL) &&
+ (gps->flag & GP_STROKE_TAG || gps->flag & GP_STROKE_HELP)) {
BLI_remlink(&gpf->strokes, gps);
BKE_gpencil_free_stroke(gps);
}
@@ -209,6 +258,70 @@ static void gpencil_delete_temp_stroke_extension(tGPDfill *tgpf, const bool all_
}
}
+static bool extended_bbox_overlap(
+ float min1[3], float max1[3], float min2[3], float max2[3], float extend)
+{
+ for (int axis = 0; axis < 3; axis++) {
+ float intersection_min = max_ff(min1[axis], min2[axis]) - extend;
+ float intersection_max = min_ff(max1[axis], max2[axis]) + extend;
+ if (intersection_min > intersection_max) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static void add_stroke_extension(bGPDframe *gpf, bGPDstroke *gps, float p1[3], float p2[3])
+{
+ bGPDstroke *gps_new = BKE_gpencil_stroke_new(gps->mat_nr, 2, gps->thickness);
+ gps_new->flag |= GP_STROKE_NOFILL | GP_STROKE_TAG;
+ BLI_addtail(&gpf->strokes, gps_new);
+
+ bGPDspoint *pt = &gps_new->points[0];
+ copy_v3_v3(&pt->x, p1);
+ pt->strength = 1.0f;
+ pt->pressure = 1.0f;
+
+ pt = &gps_new->points[1];
+ copy_v3_v3(&pt->x, p2);
+ pt->strength = 1.0f;
+ pt->pressure = 1.0f;
+}
+
+static void add_endpoint_radius_help(tGPDfill *tgpf,
+ bGPDframe *gpf,
+ bGPDstroke *gps,
+ const float endpoint[3],
+ const float radius,
+ const bool focused)
+{
+ float circumference = 2.0f * M_PI * radius;
+ float vertex_spacing = 0.005f;
+ int num_vertices = min_ii(max_ii((int)ceilf(circumference / vertex_spacing), 3), 40);
+
+ bGPDstroke *gps_new = BKE_gpencil_stroke_new(gps->mat_nr, num_vertices, gps->thickness);
+ gps_new->flag |= GP_STROKE_NOFILL | GP_STROKE_CYCLIC | GP_STROKE_HELP;
+ if (focused) {
+ gps_new->flag |= GP_STROKE_TAG;
+ }
+ BLI_addtail(&gpf->strokes, gps_new);
+
+ for (int i = 0; i < num_vertices; i++) {
+ float angle = ((float)i / (float)num_vertices) * 2.0f * M_PI;
+ bGPDspoint *pt = &gps_new->points[i];
+ pt->x = endpoint[0] + radius * cosf(angle);
+ pt->y = endpoint[1];
+ pt->z = endpoint[2] + radius * sinf(angle);
+ pt->strength = 1.0f;
+ pt->pressure = 1.0f;
+
+ /* Rotate to object rotation. */
+ sub_v3_v3(&pt->x, endpoint);
+ mul_mat3_m4_v3(tgpf->ob->object_to_world, &pt->x);
+ add_v3_v3(&pt->x, endpoint);
+ }
+}
+
static void extrapolate_points_by_length(bGPDspoint *a,
bGPDspoint *b,
float length,
@@ -221,8 +334,42 @@ static void extrapolate_points_by_length(bGPDspoint *a,
add_v3_v3v3(r_point, &b->x, ab);
}
-/* Loop all layers create stroke extensions. */
-static void gpencil_create_extensions(tGPDfill *tgpf)
+/* Calculate the size of the array for strokes. */
+static void gpencil_strokes_array_size(tGPDfill *tgpf)
+{
+ bGPdata *gpd = tgpf->gpd;
+ Brush *brush = tgpf->brush;
+ BrushGpencilSettings *brush_settings = brush->gpencil_settings;
+
+ bGPDlayer *gpl_active = BKE_gpencil_layer_active_get(gpd);
+ BLI_assert(gpl_active != NULL);
+
+ const int gpl_active_index = BLI_findindex(&gpd->layers, gpl_active);
+ BLI_assert(gpl_active_index >= 0);
+
+ tgpf->stroke_array_num = 0;
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ if (gpl->flag & GP_LAYER_HIDE) {
+ continue;
+ }
+
+ /* Decide if the strokes of layers are included or not depending on the layer mode. */
+ const int gpl_index = BLI_findindex(&gpd->layers, gpl);
+ bool skip = skip_layer_check(brush_settings->fill_layer_mode, gpl_active_index, gpl_index);
+ if (skip) {
+ continue;
+ }
+
+ bGPDframe *gpf = BKE_gpencil_layer_frame_get(gpl, tgpf->active_cfra, GP_GETFRAME_USE_PREV);
+ if (gpf == NULL) {
+ continue;
+ }
+ tgpf->stroke_array_num += BLI_listbase_count(&gpf->strokes);
+ }
+}
+
+/** Load all strokes to be processed by extend lines. */
+static void gpencil_load_array_strokes(tGPDfill *tgpf)
{
Object *ob = tgpf->ob;
bGPdata *gpd = tgpf->gpd;
@@ -235,6 +382,14 @@ static void gpencil_create_extensions(tGPDfill *tgpf)
const int gpl_active_index = BLI_findindex(&gpd->layers, gpl_active);
BLI_assert(gpl_active_index >= 0);
+ /* Create array of strokes. */
+ gpencil_strokes_array_size(tgpf);
+ if (tgpf->stroke_array_num == 0) {
+ return;
+ }
+
+ tgpf->stroke_array = MEM_callocN(sizeof(tStroke *) * tgpf->stroke_array_num, __func__);
+ int idx = 0;
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
if (gpl->flag & GP_LAYER_HIDE) {
continue;
@@ -252,85 +407,489 @@ static void gpencil_create_extensions(tGPDfill *tgpf)
continue;
}
+ float diff_mat[4][4];
+ BKE_gpencil_layer_transform_matrix_get(tgpf->depsgraph, tgpf->ob, gpl, diff_mat);
+
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
/* Check if stroke can be drawn. */
if ((gps->points == NULL) || (gps->totpoints < 2)) {
continue;
}
- if (gps->flag & (GP_STROKE_NOFILL | GP_STROKE_TAG)) {
- continue;
- }
/* Check if the color is visible. */
MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
if ((gp_style == NULL) || (gp_style->flag & GP_MATERIAL_HIDE)) {
continue;
}
+ /* Don't include temp strokes. */
+ if ((gps->flag & GP_STROKE_NOFILL) && (gps->flag & GP_STROKE_TAG)) {
+ continue;
+ }
+
+ tStroke *stroke = MEM_callocN(sizeof(tStroke), __func__);
+ stroke->gpl = gpl;
+ stroke->gpf = gpf;
+ stroke->gps = gps;
+
+ /* Create the extension strokes only for Lines. */
+ if (tgpf->fill_extend_mode == GP_FILL_EMODE_EXTEND) {
+ /* Convert all points to 2D to speed up collision checks and avoid convert in each
+ * iteration. */
+ stroke->points2d = (float(*)[2])MEM_mallocN(sizeof(*stroke->points2d) * gps->totpoints,
+ "GP Stroke temp 2d points");
+
+ for (int i = 0; i < gps->totpoints; i++) {
+ bGPDspoint *pt = &gps->points[i];
+ bGPDspoint pt2;
+ gpencil_point_to_world_space(pt, diff_mat, &pt2);
+ gpencil_point_to_xy_fl(
+ &tgpf->gsc, gps, &pt2, &stroke->points2d[i][0], &stroke->points2d[i][1]);
+ }
+
+ /* Extend start. */
+ bGPDspoint *pt1 = &gps->points[0];
+ stroke->gps_ext_a = BKE_gpencil_stroke_new(gps->mat_nr, 2, gps->thickness);
+ stroke->gps_ext_a->flag |= GP_STROKE_NOFILL | GP_STROKE_TAG;
+ stroke->gps_ext_a->fill_opacity_fac = FLT_MAX;
+ BLI_addtail(&gpf->strokes, stroke->gps_ext_a);
+
+ bGPDspoint *pt = &stroke->gps_ext_a->points[0];
+ copy_v3_v3(&pt->x, &pt1->x);
+ pt->strength = 1.0f;
+ pt->pressure = 1.0f;
+
+ pt = &stroke->gps_ext_a->points[1];
+ pt->strength = 1.0f;
+ pt->pressure = 1.0f;
+
+ /* Extend end. */
+ pt1 = &gps->points[gps->totpoints - 1];
+ stroke->gps_ext_b = BKE_gpencil_stroke_new(gps->mat_nr, 2, gps->thickness);
+ stroke->gps_ext_b->flag |= GP_STROKE_NOFILL | GP_STROKE_TAG;
+ stroke->gps_ext_b->fill_opacity_fac = FLT_MAX;
+ BLI_addtail(&gpf->strokes, stroke->gps_ext_b);
+
+ pt = &stroke->gps_ext_b->points[0];
+ copy_v3_v3(&pt->x, &pt1->x);
+ pt->strength = 1.0f;
+ pt->pressure = 1.0f;
+
+ pt = &stroke->gps_ext_b->points[1];
+ pt->strength = 1.0f;
+ pt->pressure = 1.0f;
+ }
+ else {
+ stroke->gps_ext_a = NULL;
+ stroke->gps_ext_b = NULL;
+ }
+
+ tgpf->stroke_array[idx] = stroke;
+
+ idx++;
+ }
+ }
+ tgpf->stroke_array_num = idx;
+}
+
+static void set_stroke_collide(bGPDstroke *gps_a, bGPDstroke *gps_b, const float connection_dist)
+{
+ gps_a->flag |= GP_STROKE_COLLIDE;
+ gps_b->flag |= GP_STROKE_COLLIDE;
+
+ /* It uses `fill_opacity_fac` to store distance because this variable is never
+ * used by this type of strokes and can be used for these
+ * temp strokes without adding new variables to the bGPStroke struct. */
+ gps_a->fill_opacity_fac = connection_dist;
+ gps_b->fill_opacity_fac = connection_dist;
+ BKE_gpencil_stroke_boundingbox_calc(gps_a);
+ BKE_gpencil_stroke_boundingbox_calc(gps_b);
+}
+
+static void gpencil_stroke_collision(
+ tGPDfill *tgpf, bGPDlayer *gpl, bGPDstroke *gps_a, float a1xy[2], float a2xy[2])
+{
+ const float connection_dist = tgpf->fill_extend_fac * 0.1f;
+ float diff_mat[4][4], inv_mat[4][4];
+
+ /* Transform matrix for original stroke.*/
+ BKE_gpencil_layer_transform_matrix_get(tgpf->depsgraph, tgpf->ob, gpl, diff_mat);
+ invert_m4_m4(inv_mat, diff_mat);
+
+ for (int idx = 0; idx < tgpf->stroke_array_num; idx++) {
+ tStroke *stroke = tgpf->stroke_array[idx];
+ bGPDstroke *gps_b = stroke->gps;
+
+ if (!extended_bbox_overlap(gps_a->boundbox_min,
+ gps_a->boundbox_max,
+ gps_b->boundbox_min,
+ gps_b->boundbox_max,
+ 1.1f)) {
+ continue;
+ }
+
+ /* Loop all segments of the stroke. */
+ for (int i = 0; i < gps_b->totpoints - 1; i++) {
+ /* Skip segments over same pixel. */
+ if (((int)a1xy[0] == (int)stroke->points2d[i + 1][0]) &&
+ ((int)a1xy[1] == (int)stroke->points2d[i + 1][1])) {
+ continue;
+ }
+
+ /* Check if extensions cross. */
+ if (isect_seg_seg_v2_simple(a1xy, a2xy, stroke->points2d[i], stroke->points2d[i + 1])) {
+ bGPDspoint *extreme_a = &gps_a->points[1];
+ float intersection2D[2];
+ isect_line_line_v2_point(
+ a1xy, a2xy, stroke->points2d[i], stroke->points2d[i + 1], intersection2D);
+
+ gpencil_point_xy_to_3d(&tgpf->gsc, tgpf->scene, intersection2D, &extreme_a->x);
+ mul_m4_v3(inv_mat, &extreme_a->x);
+ BKE_gpencil_stroke_boundingbox_calc(gps_a);
+
+ gps_a->flag |= GP_STROKE_COLLIDE;
+ gps_a->fill_opacity_fac = connection_dist;
+ return;
+ }
+ }
+ }
+}
+
+/* Cut the extended lines if collide. */
+static void gpencil_cut_extensions(tGPDfill *tgpf)
+{
+ const float connection_dist = tgpf->fill_extend_fac * 0.1f;
+ const bool use_stroke_collide = (tgpf->flag & GP_BRUSH_FILL_STROKE_COLLIDE) != 0;
+
+ bGPDlayer *gpl_prev = NULL;
+ bGPDframe *gpf_prev = NULL;
+ float diff_mat[4][4], inv_mat[4][4];
+
+ /* Allocate memory for all extend strokes. */
+ bGPDstroke **gps_array = MEM_callocN(sizeof(bGPDstroke *) * tgpf->stroke_array_num * 2,
+ __func__);
+
+ for (int idx = 0; idx < tgpf->stroke_array_num; idx++) {
+ tStroke *stroke = tgpf->stroke_array[idx];
+ bGPDframe *gpf = stroke->gpf;
+ if (stroke->gpl != gpl_prev) {
+ BKE_gpencil_layer_transform_matrix_get(tgpf->depsgraph, tgpf->ob, stroke->gpl, diff_mat);
+ invert_m4_m4(inv_mat, diff_mat);
+ gpl_prev = stroke->gpl;
+ }
+
+ if (gpf == gpf_prev) {
+ continue;
+ }
+ gpf_prev = gpf;
+
+ /* Store all frame extend strokes in an array. */
+ int tot_idx = 0;
+ for (int i = 0; i < tgpf->stroke_array_num; i++) {
+ tStroke *s = tgpf->stroke_array[i];
+ if (s->gpf != gpf) {
+ continue;
+ }
+ if ((s->gps_ext_a) && ((s->gps_ext_a->flag & GP_STROKE_COLLIDE) == 0)) {
+ gps_array[tot_idx] = s->gps_ext_a;
+ tot_idx++;
+ }
+ if ((s->gps_ext_b) && ((s->gps_ext_b->flag & GP_STROKE_COLLIDE) == 0)) {
+ gps_array[tot_idx] = s->gps_ext_b;
+ tot_idx++;
+ }
+ }
+
+ /* Compare all strokes. */
+ for (int i = 0; i < tot_idx; i++) {
+ bGPDstroke *gps_a = gps_array[i];
+
+ bGPDspoint pt2;
+ float a1xy[2], a2xy[2];
+ float b1xy[2], b2xy[2];
+
+ /* First stroke. */
+ bGPDspoint *pt = &gps_a->points[0];
+ gpencil_point_to_world_space(pt, diff_mat, &pt2);
+ gpencil_point_to_xy_fl(&tgpf->gsc, gps_a, &pt2, &a1xy[0], &a1xy[1]);
+
+ pt = &gps_a->points[1];
+ gpencil_point_to_world_space(pt, diff_mat, &pt2);
+ gpencil_point_to_xy_fl(&tgpf->gsc, gps_a, &pt2, &a2xy[0], &a2xy[1]);
+ bGPDspoint *extreme_a = &gps_a->points[1];
+
+ /* Loop all other strokes and check the intersections. */
+ for (int z = 0; z < tot_idx; z++) {
+ bGPDstroke *gps_b = gps_array[z];
+ /* Don't check stroke with itself. */
+ if (i == z) {
+ continue;
+ }
+
+ /* Don't check strokes unless the bounding boxes of the strokes
+ * are close enough together that they can plausibly be connected. */
+ if (!extended_bbox_overlap(gps_a->boundbox_min,
+ gps_a->boundbox_max,
+ gps_b->boundbox_min,
+ gps_b->boundbox_max,
+ 1.1f)) {
+ continue;
+ }
+
+ pt = &gps_b->points[0];
+ gpencil_point_to_world_space(pt, diff_mat, &pt2);
+ gpencil_point_to_xy_fl(&tgpf->gsc, gps_b, &pt2, &b1xy[0], &b1xy[1]);
+
+ pt = &gps_b->points[1];
+ gpencil_point_to_world_space(pt, diff_mat, &pt2);
+ gpencil_point_to_xy_fl(&tgpf->gsc, gps_b, &pt2, &b2xy[0], &b2xy[1]);
+ bGPDspoint *extreme_b = &gps_b->points[1];
+
+ /* Check if extreme points are near. This case is when the
+ * extended lines are co-linear or parallel and close together. */
+ const float gap_pixsize_sq = 25.0f;
+ float intersection3D[3];
+ if (len_squared_v2v2(a2xy, b2xy) <= gap_pixsize_sq) {
+ gpencil_point_xy_to_3d(&tgpf->gsc, tgpf->scene, b2xy, intersection3D);
+ mul_m4_v3(inv_mat, intersection3D);
+ copy_v3_v3(&extreme_a->x, intersection3D);
+ copy_v3_v3(&extreme_b->x, intersection3D);
+ set_stroke_collide(gps_a, gps_b, connection_dist);
+ break;
+ }
+ /* Check if extensions cross. */
+ if (isect_seg_seg_v2_simple(a1xy, a2xy, b1xy, b2xy)) {
+ float intersection2D[2];
+ isect_line_line_v2_point(a1xy, a2xy, b1xy, b2xy, intersection2D);
+
+ gpencil_point_xy_to_3d(&tgpf->gsc, tgpf->scene, intersection2D, intersection3D);
+ mul_m4_v3(inv_mat, intersection3D);
+ copy_v3_v3(&extreme_a->x, intersection3D);
+ copy_v3_v3(&extreme_b->x, intersection3D);
+ set_stroke_collide(gps_a, gps_b, connection_dist);
+ break;
+ }
+ /* Check if extension extreme is near of the origin of any other extension. */
+ if (len_squared_v2v2(a2xy, b1xy) <= gap_pixsize_sq) {
+ gpencil_point_xy_to_3d(&tgpf->gsc, tgpf->scene, b1xy, &extreme_a->x);
+ mul_m4_v3(inv_mat, &extreme_a->x);
+ set_stroke_collide(gps_a, gps_b, connection_dist);
+ break;
+ }
+ if (len_squared_v2v2(a1xy, b2xy) <= gap_pixsize_sq) {
+ gpencil_point_xy_to_3d(&tgpf->gsc, tgpf->scene, a1xy, &extreme_b->x);
+ mul_m4_v3(inv_mat, &extreme_b->x);
+ set_stroke_collide(gps_a, gps_b, connection_dist);
+ break;
+ }
+ }
- /* Extend start. */
+ /* Check if collide with normal strokes. */
+ if (use_stroke_collide && (gps_a->flag & GP_STROKE_COLLIDE) == 0) {
+ gpencil_stroke_collision(tgpf, stroke->gpl, gps_a, a1xy, a2xy);
+ }
+ }
+ }
+ MEM_SAFE_FREE(gps_array);
+}
+
+/* Loop all strokes and update stroke line extensions. */
+static void gpencil_update_extensions_line(tGPDfill *tgpf)
+{
+ float connection_dist = tgpf->fill_extend_fac * 0.1f;
+
+ for (int idx = 0; idx < tgpf->stroke_array_num; idx++) {
+ tStroke *stroke = tgpf->stroke_array[idx];
+ bGPDstroke *gps = stroke->gps;
+ bGPDstroke *gps_a = stroke->gps_ext_a;
+ bGPDstroke *gps_b = stroke->gps_ext_b;
+
+ /* Extend start. */
+ if (((gps_a->flag & GP_STROKE_COLLIDE) == 0) || (gps_a->fill_opacity_fac > connection_dist)) {
bGPDspoint *pt0 = &gps->points[1];
bGPDspoint *pt1 = &gps->points[0];
- bGPDstroke *gps_new = BKE_gpencil_stroke_new(gps->mat_nr, 2, gps->thickness);
- gps_new->flag |= GP_STROKE_NOFILL | GP_STROKE_TAG;
- BLI_addtail(&gpf->strokes, gps_new);
-
- bGPDspoint *pt = &gps_new->points[0];
- copy_v3_v3(&pt->x, &pt1->x);
- pt->strength = 1.0f;
- pt->pressure = 1.0f;
-
- pt = &gps_new->points[1];
- pt->strength = 1.0f;
- pt->pressure = 1.0f;
- extrapolate_points_by_length(pt0, pt1, tgpf->fill_extend_fac * 0.1f, &pt->x);
-
- /* Extend end. */
- pt0 = &gps->points[gps->totpoints - 2];
- pt1 = &gps->points[gps->totpoints - 1];
- gps_new = BKE_gpencil_stroke_new(gps->mat_nr, 2, gps->thickness);
- gps_new->flag |= GP_STROKE_NOFILL | GP_STROKE_TAG;
- BLI_addtail(&gpf->strokes, gps_new);
-
- pt = &gps_new->points[0];
- copy_v3_v3(&pt->x, &pt1->x);
- pt->strength = 1.0f;
- pt->pressure = 1.0f;
-
- pt = &gps_new->points[1];
- pt->strength = 1.0f;
- pt->pressure = 1.0f;
- extrapolate_points_by_length(pt0, pt1, tgpf->fill_extend_fac * 0.1f, &pt->x);
+ bGPDspoint *pt = &gps_a->points[1];
+ extrapolate_points_by_length(pt0, pt1, connection_dist, &pt->x);
+ gps_a->flag &= ~GP_STROKE_COLLIDE;
+ }
+
+ /* Extend end. */
+ if (((gps_b->flag & GP_STROKE_COLLIDE) == 0) || (gps_b->fill_opacity_fac > connection_dist)) {
+ bGPDspoint *pt0 = &gps->points[gps->totpoints - 2];
+ bGPDspoint *pt1 = &gps->points[gps->totpoints - 1];
+ bGPDspoint *pt = &gps_b->points[1];
+ extrapolate_points_by_length(pt0, pt1, connection_dist, &pt->x);
+ gps_b->flag &= ~GP_STROKE_COLLIDE;
}
}
+
+ /* Cut overlength strokes. */
+ gpencil_cut_extensions(tgpf);
+}
+
+/* Loop all strokes and create stroke radius extensions. */
+static void gpencil_create_extensions_radius(tGPDfill *tgpf)
+{
+ float connection_dist = tgpf->fill_extend_fac * 0.1f;
+ GSet *connected_endpoints = BLI_gset_ptr_new(__func__);
+
+ for (int idx = 0; idx < tgpf->stroke_array_num; idx++) {
+ tStroke *stroke = tgpf->stroke_array[idx];
+ bGPDframe *gpf = stroke->gpf;
+ bGPDstroke *gps = stroke->gps;
+
+ /* Find points of high curvature. */
+ float tan1[3];
+ float tan2[3];
+ float d1;
+ float d2;
+ float total_length = 0.f;
+ for (int i = 1; i < gps->totpoints; i++) {
+ if (i > 1) {
+ copy_v3_v3(tan1, tan2);
+ d1 = d2;
+ }
+ bGPDspoint *pt1 = &gps->points[i - 1];
+ bGPDspoint *pt2 = &gps->points[i];
+ sub_v3_v3v3(tan2, &pt2->x, &pt1->x);
+ d2 = normalize_v3(tan2);
+ total_length += d2;
+ if (i > 1) {
+ float curvature[3];
+ sub_v3_v3v3(curvature, tan2, tan1);
+ float k = normalize_v3(curvature);
+ k /= min_ff(d1, d2);
+ float radius = 1.f / k;
+ /*
+ * The smaller the radius of curvature, the sharper the corner.
+ * The thicker the line, the larger the radius of curvature it
+ * takes to be visually indistinguishable from an endpoint.
+ */
+ float min_radius = gps->thickness * 0.0001f;
+
+ if (radius < min_radius) {
+ /* Extend along direction of curvature. */
+ bGPDstroke *gps_new = BKE_gpencil_stroke_new(gps->mat_nr, 2, gps->thickness);
+ gps_new->flag |= GP_STROKE_NOFILL | GP_STROKE_TAG;
+ BLI_addtail(&gpf->strokes, gps_new);
+
+ bGPDspoint *pt = &gps_new->points[0];
+ copy_v3_v3(&pt->x, &pt1->x);
+ pt->strength = 1.0f;
+ pt->pressure = 1.0f;
+
+ pt = &gps_new->points[1];
+ pt->strength = 1.0f;
+ pt->pressure = 1.0f;
+ mul_v3_fl(curvature, -connection_dist);
+ add_v3_v3v3(&pt->x, &pt1->x, curvature);
+ }
+ }
+ }
+
+ /* Connect endpoints within a radius */
+ float *stroke1_start = &gps->points[0].x;
+ float *stroke1_end = &gps->points[gps->totpoints - 1].x;
+ /* Connect the start of the stroke to its own end if the whole stroke
+ * isn't already so short that it's within that distance
+ */
+ if (len_v3v3(stroke1_start, stroke1_end) < connection_dist && total_length > connection_dist) {
+ add_stroke_extension(gpf, gps, stroke1_start, stroke1_end);
+ BLI_gset_add(connected_endpoints, stroke1_start);
+ BLI_gset_add(connected_endpoints, stroke1_end);
+ }
+ for (bGPDstroke *gps2 = (bGPDstroke *)(((Link *)gps)->next); gps2 != NULL;
+ gps2 = (bGPDstroke *)(((Link *)gps2)->next)) {
+ /* Don't check distance to temporary extensions. */
+ if ((gps2->flag & GP_STROKE_NOFILL) && (gps2->flag & GP_STROKE_TAG)) {
+ continue;
+ }
+
+ /* Don't check endpoint distances unless the bounding boxes of the strokes
+ are close enough together that they can plausibly be connected. */
+ if (!extended_bbox_overlap(gps->boundbox_min,
+ gps->boundbox_max,
+ gps2->boundbox_min,
+ gps2->boundbox_max,
+ connection_dist)) {
+ continue;
+ }
+
+ float *stroke2_start = &gps2->points[0].x;
+ float *stroke2_end = &gps2->points[gps2->totpoints - 1].x;
+ if (len_v3v3(stroke1_start, stroke2_start) < connection_dist) {
+ add_stroke_extension(gpf, gps, stroke1_start, stroke2_start);
+ BLI_gset_add(connected_endpoints, stroke1_start);
+ BLI_gset_add(connected_endpoints, stroke2_start);
+ }
+ if (len_v3v3(stroke1_start, stroke2_end) < connection_dist) {
+ add_stroke_extension(gpf, gps, stroke1_start, stroke2_end);
+ BLI_gset_add(connected_endpoints, stroke1_start);
+ BLI_gset_add(connected_endpoints, stroke2_end);
+ }
+ if (len_v3v3(stroke1_end, stroke2_start) < connection_dist) {
+ add_stroke_extension(gpf, gps, stroke1_end, stroke2_start);
+ BLI_gset_add(connected_endpoints, stroke1_end);
+ BLI_gset_add(connected_endpoints, stroke2_start);
+ }
+ if (len_v3v3(stroke1_end, stroke2_end) < connection_dist) {
+ add_stroke_extension(gpf, gps, stroke1_end, stroke2_end);
+ BLI_gset_add(connected_endpoints, stroke1_end);
+ BLI_gset_add(connected_endpoints, stroke2_end);
+ }
+ }
+
+ bool start_connected = BLI_gset_haskey(connected_endpoints, stroke1_start);
+ bool end_connected = BLI_gset_haskey(connected_endpoints, stroke1_end);
+ add_endpoint_radius_help(tgpf, gpf, gps, stroke1_start, connection_dist, start_connected);
+ add_endpoint_radius_help(tgpf, gpf, gps, stroke1_end, connection_dist, end_connected);
+ }
+
+ BLI_gset_free(connected_endpoints, NULL);
}
static void gpencil_update_extend(tGPDfill *tgpf)
{
- gpencil_delete_temp_stroke_extension(tgpf, false);
+ if (tgpf->stroke_array == NULL) {
+ gpencil_load_array_strokes(tgpf);
+ }
- if (tgpf->fill_extend_fac > 0.0f) {
- gpencil_create_extensions(tgpf);
+ if (tgpf->fill_extend_mode == GP_FILL_EMODE_EXTEND) {
+ gpencil_update_extensions_line(tgpf);
}
+ else {
+ gpencil_delete_temp_stroke_extension(tgpf, false);
+ gpencil_create_extensions_radius(tgpf);
+ }
+ gpencil_fill_status_indicators(tgpf);
WM_event_add_notifier(tgpf->C, NC_GPENCIL | NA_EDITED, NULL);
}
static bool gpencil_stroke_is_drawable(tGPDfill *tgpf, bGPDstroke *gps)
{
+ const bool is_line_mode = (tgpf->fill_extend_mode == GP_FILL_EMODE_EXTEND);
+ const bool show_help = (tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) != 0;
+ const bool show_extend = (tgpf->flag & GP_BRUSH_FILL_SHOW_EXTENDLINES) != 0;
+ const bool use_stroke_collide = (tgpf->flag & GP_BRUSH_FILL_STROKE_COLLIDE) != 0;
+ const bool is_extend_stroke = (gps->flag & GP_STROKE_NOFILL) && (gps->flag & GP_STROKE_TAG);
+ const bool is_help_stroke = (gps->flag & GP_STROKE_NOFILL) && (gps->flag & GP_STROKE_HELP);
+ const bool stroke_collide = (gps->flag & GP_STROKE_COLLIDE) != 0;
+
+ if (is_line_mode && is_extend_stroke && tgpf->is_render && use_stroke_collide &&
+ !stroke_collide) {
+ return false;
+ }
+
if (tgpf->is_render) {
return true;
}
- const bool show_help = (tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) != 0;
- const bool show_extend = (tgpf->flag & GP_BRUSH_FILL_SHOW_EXTENDLINES) != 0;
- const bool is_extend = (gps->flag & GP_STROKE_NOFILL) && (gps->flag & GP_STROKE_TAG);
-
if ((!show_help) && (show_extend)) {
- if (!is_extend) {
+ if (!is_extend_stroke && !is_help_stroke) {
return false;
}
}
if ((show_help) && (!show_extend)) {
- if (is_extend) {
+ if (is_extend_stroke || is_help_stroke) {
return false;
}
}
@@ -357,14 +916,38 @@ static void gpencil_draw_basic_stroke(tGPDfill *tgpf,
float fpt[3];
float col[4];
const float extend_col[4] = {0.0f, 1.0f, 1.0f, 1.0f};
- const bool is_extend = (gps->flag & GP_STROKE_NOFILL) && (gps->flag & GP_STROKE_TAG);
+ const float help_col[4] = {1.0f, 0.0f, 0.5f, 1.0f};
+ const bool is_extend = (gps->flag & GP_STROKE_NOFILL) && (gps->flag & GP_STROKE_TAG) &&
+ !(gps->flag & GP_STROKE_HELP);
+ const bool is_help = gps->flag & GP_STROKE_HELP;
+ const bool is_line_mode = (tgpf->fill_extend_mode == GP_FILL_EMODE_EXTEND);
+ const bool use_stroke_collide = (tgpf->flag & GP_BRUSH_FILL_STROKE_COLLIDE) != 0;
+ const bool stroke_collide = (gps->flag & GP_STROKE_COLLIDE) != 0;
if (!gpencil_stroke_is_drawable(tgpf, gps)) {
return;
}
- if ((is_extend) && (!tgpf->is_render)) {
- copy_v4_v4(col, extend_col);
+ if (is_help && tgpf->is_render) {
+ /* Help strokes are for display only and shouldn't render. */
+ return;
+ }
+ else if (is_help) {
+ /* Color help strokes that won't affect fill or render separately from
+ * extended strokes, as they will affect them. */
+ copy_v4_v4(col, help_col);
+
+ /* If there is contact, hide the circles to avoid noise and keep the focus
+ * in the pending gaps. */
+ col[3] = (gps->flag & GP_STROKE_TAG) ? 0.0f : 0.5f;
+ }
+ else if ((is_extend) && (!tgpf->is_render)) {
+ if (stroke_collide || !use_stroke_collide || !is_line_mode) {
+ copy_v4_v4(col, extend_col);
+ }
+ else {
+ copy_v4_v4(col, help_col);
+ }
}
else {
copy_v4_v4(col, ink);
@@ -379,7 +962,7 @@ static void gpencil_draw_basic_stroke(tGPDfill *tgpf,
immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
/* draw stroke curve */
- GPU_line_width((!is_extend) ? thickness : thickness * 2.0f);
+ GPU_line_width((!is_extend && !is_help) ? thickness : thickness * 2.0f);
immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints + cyclic_add);
const bGPDspoint *pt = points;
@@ -390,7 +973,7 @@ static void gpencil_draw_basic_stroke(tGPDfill *tgpf,
CLAMP(alpha, 0.0f, 1.0f);
col[3] = alpha <= thershold ? 0.0f : 1.0f;
}
- else {
+ else if (!is_help) {
col[3] = 1.0f;
}
/* set point */
@@ -486,6 +1069,7 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
Brush *brush = tgpf->brush;
BrushGpencilSettings *brush_settings = brush->gpencil_settings;
ToolSettings *ts = tgpf->scene->toolsettings;
+ const bool extend_lines = (tgpf->fill_extend_fac > 0.0f);
tGPDdraw tgpw;
tgpw.rv3d = tgpf->rv3d;
@@ -582,12 +1166,26 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
/* Normal strokes. */
if (ELEM(tgpf->fill_draw_mode, GP_FILL_DMODE_STROKE, GP_FILL_DMODE_BOTH)) {
- if (gpencil_stroke_is_drawable(tgpf, gps) && ((gps->flag & GP_STROKE_TAG) == 0)) {
+ if (gpencil_stroke_is_drawable(tgpf, gps) && ((gps->flag & GP_STROKE_TAG) == 0) &&
+ ((gps->flag & GP_STROKE_HELP) == 0)) {
ED_gpencil_draw_fill(&tgpw);
}
+ /* In stroke mode, still must draw the extend lines. */
+ if (extend_lines && (tgpf->fill_draw_mode == GP_FILL_DMODE_STROKE)) {
+ if ((gps->flag & GP_STROKE_NOFILL) && (gps->flag & GP_STROKE_TAG)) {
+ gpencil_draw_basic_stroke(tgpf,
+ gps,
+ tgpw.diff_mat,
+ gps->flag & GP_STROKE_CYCLIC,
+ ink,
+ tgpf->flag,
+ tgpf->fill_threshold,
+ 1.0f);
+ }
+ }
}
- /* 3D Lines with basic shapes and invisible lines */
+ /* 3D Lines with basic shapes and invisible lines. */
if (ELEM(tgpf->fill_draw_mode, GP_FILL_DMODE_CONTROL, GP_FILL_DMODE_BOTH)) {
gpencil_draw_basic_stroke(tgpf,
gps,
@@ -1655,7 +2253,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
/* if parented change position relative to parent object */
for (int a = 0; a < tgpf->sbuffer_used; a++) {
pt = &gps->points[a];
- gpencil_apply_parent_point(tgpf->depsgraph, tgpf->ob, tgpf->gpl, pt);
+ gpencil_world_to_object_space_point(tgpf->depsgraph, tgpf->ob, tgpf->gpl, pt);
}
/* If camera view or view projection, reproject flat to view to avoid perspective effect. */
@@ -1675,10 +2273,22 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
/* ----------------------- */
/* Drawing */
/* Helper: Draw status message while the user is running the operator */
-static void gpencil_fill_status_indicators(bContext *C)
+static void gpencil_fill_status_indicators(tGPDfill *tgpf)
{
- const char *status_str = TIP_("Fill: ESC/RMB cancel, LMB Fill, Shift Draw on Back");
- ED_workspace_status_text(C, status_str);
+ const bool is_extend = (tgpf->fill_extend_mode == GP_FILL_EMODE_EXTEND);
+ const bool use_stroke_collide = (tgpf->flag & GP_BRUSH_FILL_STROKE_COLLIDE) != 0;
+
+ char status_str[UI_MAX_DRAW_STR];
+ BLI_snprintf(status_str,
+ sizeof(status_str),
+ TIP_("Fill: ESC/RMB cancel, LMB Fill, Shift Draw on Back, MMB Adjust Extend, S: "
+ "Switch Mode, D: "
+ "Stroke Collision | %s %s (%.3f)"),
+ (is_extend) ? TIP_("Extend") : TIP_("Radius"),
+ (is_extend && use_stroke_collide) ? TIP_("Stroke: ON") : TIP_("Stroke: OFF"),
+ tgpf->fill_extend_fac);
+
+ ED_workspace_status_text(tgpf->C, status_str);
}
/* draw boundary lines to see fill limits */
@@ -1770,6 +2380,11 @@ static tGPDfill *gpencil_session_init_fill(bContext *C, wmOperator *op)
tgpf->sbuffer = NULL;
tgpf->depth_arr = NULL;
+ /* Prepare extend handling for pen. */
+ tgpf->mouse_init[0] = -1.0f;
+ tgpf->mouse_init[1] = -1.0f;
+ tgpf->pixel_size = tgpf->rv3d ? ED_view3d_pixel_size(tgpf->rv3d, tgpf->ob->loc) : 1.0f;
+
/* save filling parameters */
Brush *brush = BKE_paint_brush(&ts->gp_paint->paint);
tgpf->brush = brush;
@@ -1777,13 +2392,17 @@ static tGPDfill *gpencil_session_init_fill(bContext *C, wmOperator *op)
tgpf->fill_threshold = brush->gpencil_settings->fill_threshold;
tgpf->fill_simplylvl = brush->gpencil_settings->fill_simplylvl;
tgpf->fill_draw_mode = brush->gpencil_settings->fill_draw_mode;
+ tgpf->fill_extend_mode = brush->gpencil_settings->fill_extend_mode;
tgpf->fill_extend_fac = brush->gpencil_settings->fill_extend_fac;
tgpf->fill_factor = max_ff(GPENCIL_MIN_FILL_FAC,
min_ff(brush->gpencil_settings->fill_factor, GPENCIL_MAX_FILL_FAC));
- tgpf->fill_leak = (int)ceil((float)brush->gpencil_settings->fill_leak * tgpf->fill_factor);
+ tgpf->fill_leak = (int)ceil(FILL_LEAK * tgpf->fill_factor);
int totcol = tgpf->ob->totcol;
+ /* Extensions array */
+ tgpf->stroke_array = NULL;
+
/* get color info */
Material *ma = BKE_gpencil_object_material_ensure_from_active_input_brush(
bmain, tgpf->ob, brush);
@@ -1832,6 +2451,9 @@ static void gpencil_fill_exit(bContext *C, wmOperator *op)
MEM_SAFE_FREE(tgpf->sbuffer);
MEM_SAFE_FREE(tgpf->depth_arr);
+ /* Clean temp strokes. */
+ stroke_array_free(tgpf);
+
/* Remove any temp stroke. */
gpencil_delete_temp_stroke_extension(tgpf, true);
@@ -1839,6 +2461,7 @@ static void gpencil_fill_exit(bContext *C, wmOperator *op)
if (tgpf->draw_handle_3d) {
ED_region_draw_cb_exit(tgpf->region->type, tgpf->draw_handle_3d);
}
+ WM_cursor_set(CTX_wm_window(C), WM_CURSOR_DEFAULT);
/* Remove depth buffer in cache. */
if (tgpf->depths) {
@@ -1859,7 +2482,8 @@ static void gpencil_fill_exit(bContext *C, wmOperator *op)
gpd2->flag |= GP_DATA_CACHE_IS_DIRTY;
}
- WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_GEOM | ND_DATA, NULL);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
}
static void gpencil_fill_cancel(bContext *C, wmOperator *op)
@@ -1928,9 +2552,8 @@ static int gpencil_fill_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
tgpf = op->customdata;
/* Enable custom drawing handlers to show help lines */
- const bool do_extend = (tgpf->fill_extend_fac > 0.0f);
- const bool help_lines = ((tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) ||
- ((tgpf->flag & GP_BRUSH_FILL_SHOW_EXTENDLINES) && (do_extend)));
+ const bool do_extend = (tgpf->flag & GP_BRUSH_FILL_SHOW_EXTENDLINES);
+ const bool help_lines = ((tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) || (do_extend));
if (help_lines) {
tgpf->draw_handle_3d = ED_region_draw_cb_activate(
@@ -1939,7 +2562,7 @@ static int gpencil_fill_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
WM_cursor_modal_set(CTX_wm_window(C), WM_CURSOR_PAINT_BRUSH);
- gpencil_fill_status_indicators(C);
+ gpencil_fill_status_indicators(tgpf);
DEG_id_tag_update(&tgpf->gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
@@ -2071,9 +2694,12 @@ static bool gpencil_find_and_mark_empty_areas(tGPDfill *tgpf)
get_pixel(ibuf, i, rgba);
if (rgba[3] == 0.0f) {
set_pixel(ibuf, i, blue_col);
+ BKE_image_release_ibuf(tgpf->ima, ibuf, NULL);
return true;
}
}
+
+ BKE_image_release_ibuf(tgpf->ima, ibuf, NULL);
return false;
}
@@ -2099,6 +2725,9 @@ static bool gpencil_do_frame_fill(tGPDfill *tgpf, const bool is_inverted)
gpencil_invert_image(tgpf);
while (gpencil_find_and_mark_empty_areas(tgpf)) {
gpencil_boundaryfill_area(tgpf);
+ if (FILL_DEBUG) {
+ break;
+ }
}
}
@@ -2179,9 +2808,10 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
const bool is_inverted = (is_brush_inv && (event->modifier & KM_CTRL) == 0) ||
(!is_brush_inv && (event->modifier & KM_CTRL) != 0);
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(tgpf->gpd);
- const bool do_extend = (tgpf->fill_extend_fac > 0.0f);
- const bool help_lines = ((tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) ||
- ((tgpf->flag & GP_BRUSH_FILL_SHOW_EXTENDLINES) && (do_extend)));
+ const bool extend_lines = (tgpf->fill_extend_fac > 0.0f);
+ const bool show_extend = ((tgpf->flag & GP_BRUSH_FILL_SHOW_EXTENDLINES) && !is_inverted);
+ const bool help_lines = (((tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) || show_extend) &&
+ !is_inverted);
int estate = OPERATOR_RUNNING_MODAL;
switch (event->type) {
@@ -2195,6 +2825,12 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
estate = OPERATOR_CANCELLED;
break;
}
+ /* if doing a extend transform with the pen, avoid false contacts of
+ * the pen with the tablet. */
+ if (tgpf->mouse_init[0] != -1.0f) {
+ break;
+ }
+ copy_v2fl_v2i(tgpf->mouse_center, event->mval);
/* first time the event is not enabled to show help lines. */
if ((tgpf->oldkey != -1) || (!help_lines)) {
@@ -2250,7 +2886,7 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
int step = ((float)i / (float)total) * 100.0f;
WM_cursor_time(win, step);
- if (do_extend) {
+ if (extend_lines) {
gpencil_update_extend(tgpf);
}
@@ -2281,7 +2917,7 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
loop_limit++;
}
- if (do_extend) {
+ if (extend_lines) {
gpencil_delete_temp_stroke_extension(tgpf, true);
}
@@ -2310,11 +2946,36 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
estate = OPERATOR_CANCELLED;
}
}
- else if (do_extend) {
+ else if (extend_lines) {
gpencil_update_extend(tgpf);
}
tgpf->oldkey = event->type;
break;
+ case EVT_SKEY:
+ if ((show_extend) && (event->val == KM_PRESS)) {
+ /* Clean temp strokes. */
+ stroke_array_free(tgpf);
+
+ /* Toggle mode. */
+ if (tgpf->fill_extend_mode == GP_FILL_EMODE_EXTEND) {
+ tgpf->fill_extend_mode = GP_FILL_EMODE_RADIUS;
+ }
+ else {
+ tgpf->fill_extend_mode = GP_FILL_EMODE_EXTEND;
+ }
+ gpencil_delete_temp_stroke_extension(tgpf, true);
+ gpencil_update_extend(tgpf);
+ }
+ break;
+ case EVT_DKEY:
+ if ((show_extend) && (event->val == KM_PRESS)) {
+ tgpf->flag ^= GP_BRUSH_FILL_STROKE_COLLIDE;
+ /* Clean temp strokes. */
+ stroke_array_free(tgpf);
+ gpencil_delete_temp_stroke_extension(tgpf, true);
+ gpencil_update_extend(tgpf);
+ }
+ break;
case EVT_PAGEUPKEY:
case WHEELUPMOUSE:
if (tgpf->oldkey == 1) {
@@ -2327,10 +2988,60 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
case WHEELDOWNMOUSE:
if (tgpf->oldkey == 1) {
tgpf->fill_extend_fac += (event->modifier & KM_SHIFT) ? 0.01f : 0.1f;
- CLAMP_MAX(tgpf->fill_extend_fac, 100.0f);
+ CLAMP_MAX(tgpf->fill_extend_fac, 10.0f);
gpencil_update_extend(tgpf);
}
break;
+ case MIDDLEMOUSE: {
+ if (event->val == KM_PRESS) {
+ /* Consider initial offset as zero position. */
+ copy_v2fl_v2i(tgpf->mouse_init, event->mval);
+ float mlen[2];
+ sub_v2_v2v2(mlen, tgpf->mouse_init, tgpf->mouse_center);
+
+ /* Offset the center a little to get enough space to reduce the extend moving the pen. */
+ const float gap = 300.0f;
+ if (len_v2(mlen) < gap) {
+ tgpf->mouse_center[0] -= gap;
+ sub_v2_v2v2(mlen, tgpf->mouse_init, tgpf->mouse_center);
+ }
+
+ WM_cursor_set(CTX_wm_window(C), WM_CURSOR_EW_ARROW);
+
+ tgpf->initial_length = len_v2(mlen);
+ }
+ if (event->val == KM_RELEASE) {
+ WM_cursor_set(CTX_wm_window(C), WM_CURSOR_DEFAULT);
+
+ tgpf->mouse_init[0] = -1.0f;
+ tgpf->mouse_init[1] = -1.0f;
+ }
+ /* Update cursor line. */
+ WM_main_add_notifier(NC_GEOM | ND_DATA, NULL);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+ break;
+ }
+ case MOUSEMOVE: {
+ if (tgpf->mouse_init[0] == -1.0f) {
+ break;
+ }
+ copy_v2fl_v2i(tgpf->mouse_pos, event->mval);
+
+ float mlen[2];
+ sub_v2_v2v2(mlen, tgpf->mouse_pos, tgpf->mouse_center);
+ float delta = (len_v2(mlen) - tgpf->initial_length) * tgpf->pixel_size * 0.5f;
+ tgpf->fill_extend_fac += delta;
+ CLAMP(tgpf->fill_extend_fac, 0.0f, 10.0f);
+
+ /* Update cursor line and extend lines. */
+ WM_main_add_notifier(NC_GEOM | ND_DATA, NULL);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+ gpencil_update_extend(tgpf);
+
+ break;
+ }
default:
break;
}
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 4d62f834d86..4847e3eabf3 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -276,35 +276,35 @@ void gpencil_point_to_xy_fl(const GP_SpaceConversion *gsc,
float *r_y);
/**
- * Convert point to parent space
+ * Convert point to world space
*
* \param pt: Original point
- * \param diff_mat: Matrix with the difference between original parent matrix
+ * \param diff_mat: Matrix with the transformation
* \param[out] r_pt: Pointer to new point after apply matrix
*/
-void gpencil_point_to_parent_space(const bGPDspoint *pt,
- const float diff_mat[4][4],
- bGPDspoint *r_pt);
+void gpencil_point_to_world_space(const bGPDspoint *pt,
+ const float diff_mat[4][4],
+ bGPDspoint *r_pt);
/**
* Change points position relative to parent object
*/
/**
* Change position relative to parent object
*/
-void gpencil_apply_parent(struct Depsgraph *depsgraph,
- struct Object *obact,
- bGPDlayer *gpl,
- bGPDstroke *gps);
+void gpencil_world_to_object_space(struct Depsgraph *depsgraph,
+ struct Object *obact,
+ bGPDlayer *gpl,
+ bGPDstroke *gps);
/**
* Change point position relative to parent object
*/
/**
* Change point position relative to parent object
*/
-void gpencil_apply_parent_point(struct Depsgraph *depsgraph,
- struct Object *obact,
- bGPDlayer *gpl,
- bGPDspoint *pt);
+void gpencil_world_to_object_space_point(struct Depsgraph *depsgraph,
+ struct Object *obact,
+ bGPDlayer *gpl,
+ bGPDspoint *pt);
/**
* generic based on gpencil_point_to_xy_fl
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index dc63acf5136..cc25ed66b3d 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -167,20 +167,20 @@ static bool gpencil_stroke_need_flip(Depsgraph *depsgraph,
/* Line from start of strokes. */
pt = &gps_from->points[0];
- gpencil_point_to_parent_space(pt, diff_mat, &pt_dummy_ps);
+ gpencil_point_to_world_space(pt, diff_mat, &pt_dummy_ps);
gpencil_point_to_xy_fl(gsc, gps_from, &pt_dummy_ps, &v_from_start[0], &v_from_start[1]);
pt = &gps_to->points[0];
- gpencil_point_to_parent_space(pt, diff_mat, &pt_dummy_ps);
+ gpencil_point_to_world_space(pt, diff_mat, &pt_dummy_ps);
gpencil_point_to_xy_fl(gsc, gps_from, &pt_dummy_ps, &v_to_start[0], &v_to_start[1]);
/* Line from end of strokes. */
pt = &gps_from->points[gps_from->totpoints - 1];
- gpencil_point_to_parent_space(pt, diff_mat, &pt_dummy_ps);
+ gpencil_point_to_world_space(pt, diff_mat, &pt_dummy_ps);
gpencil_point_to_xy_fl(gsc, gps_from, &pt_dummy_ps, &v_from_end[0], &v_from_end[1]);
pt = &gps_to->points[gps_to->totpoints - 1];
- gpencil_point_to_parent_space(pt, diff_mat, &pt_dummy_ps);
+ gpencil_point_to_world_space(pt, diff_mat, &pt_dummy_ps);
gpencil_point_to_xy_fl(gsc, gps_from, &pt_dummy_ps, &v_to_end[0], &v_to_end[1]);
const bool isect_lines = (isect_seg_seg_v2(v_from_start, v_to_start, v_from_end, v_to_end) ==
@@ -690,7 +690,7 @@ static bool gpencil_interpolate_set_init_values(bContext *C, wmOperator *op, tGP
tgpi->flag, (RNA_enum_get(op->ptr, "layers") == 1), GP_TOOLFLAG_INTERPOLATE_ALL_LAYERS);
SET_FLAG_FROM_TEST(
tgpi->flag,
- (GPENCIL_EDIT_MODE(tgpi->gpd) && (RNA_boolean_get(op->ptr, "interpolate_selected_only"))),
+ (GPENCIL_EDIT_MODE(tgpi->gpd) && RNA_boolean_get(op->ptr, "interpolate_selected_only")),
GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED);
tgpi->flipmode = RNA_enum_get(op->ptr, "flip");
diff --git a/source/blender/editors/gpencil/gpencil_mesh.cc b/source/blender/editors/gpencil/gpencil_mesh.cc
index b27e1c75746..2b01fce5bf8 100644
--- a/source/blender/editors/gpencil/gpencil_mesh.cc
+++ b/source/blender/editors/gpencil/gpencil_mesh.cc
@@ -43,8 +43,8 @@
#include "gpencil_intern.h"
/* Check frame_end is always > start frame! */
-static void gpencil_bake_set_frame_end(struct Main *UNUSED(main),
- struct Scene *UNUSED(scene),
+static void gpencil_bake_set_frame_end(struct Main * /*main*/,
+ struct Scene * /*scene*/,
struct PointerRNA *ptr)
{
int frame_start = RNA_int_get(ptr, "frame_start");
@@ -91,7 +91,7 @@ static void animdata_keyframe_list_get(ListBase *ob_list,
/* Keyframe number is x value of point. */
if ((bezt->f2 & SELECT) || (!only_selected)) {
/* Insert only one key for each keyframe number. */
- int key = (int)bezt->vec[1][0];
+ int key = int(bezt->vec[1][0]);
if (!BLI_ghash_haskey(r_keyframes, POINTER_FROM_INT(key))) {
BLI_ghash_insert(r_keyframes, POINTER_FROM_INT(key), POINTER_FROM_INT(key));
}
@@ -213,7 +213,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
bool newob = false;
if (target == GP_TARGET_OB_SELECTED) {
- ob_gpencil = BKE_view_layer_non_active_selected_object(CTX_data_view_layer(C), v3d);
+ ob_gpencil = BKE_view_layer_non_active_selected_object(scene, CTX_data_view_layer(C), v3d);
if (ob_gpencil != nullptr) {
if (ob_gpencil->type != OB_GPENCIL) {
BKE_report(op->reports, RPT_WARNING, "Target object not a grease pencil, ignoring!");
@@ -261,7 +261,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
}
/* Loop all frame range. */
- int oldframe = (int)DEG_get_ctime(depsgraph);
+ int oldframe = int(DEG_get_ctime(depsgraph));
int key = -1;
/* Get list of keyframes. */
@@ -278,7 +278,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
}
/* Check if frame is in the list of frames to be exported. */
- if ((only_selected) && (!BLI_ghash_haskey(keyframe_list, POINTER_FROM_INT(i)))) {
+ if ((only_selected) && !BLI_ghash_haskey(keyframe_list, POINTER_FROM_INT(i))) {
continue;
}
@@ -299,7 +299,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
angle,
thickness,
offset,
- ob_eval->obmat,
+ ob_eval->object_to_world,
frame_offset,
use_seams,
use_faces,
@@ -315,7 +315,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
if ((gps->flag & GP_STROKE_TAG) == 0) {
ED_gpencil_stroke_reproject(
- depsgraph, &gsc, sctx, gpl, gpf, gps, project_type, false);
+ depsgraph, &gsc, sctx, gpl, gpf, gps, project_type, false, 0.0f);
gps->flag |= GP_STROKE_TAG;
}
}
@@ -380,7 +380,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
static int gpencil_bake_mesh_animation_invoke(bContext *C,
wmOperator *op,
- const wmEvent *UNUSED(event))
+ const wmEvent * /*event*/)
{
/* Show popup dialog to allow editing. */
/* FIXME: hard-coded dimensions here are just arbitrary. */
diff --git a/source/blender/editors/gpencil/gpencil_ops_versioning.c b/source/blender/editors/gpencil/gpencil_ops_versioning.c
index 8119646137c..60b58b6f513 100644
--- a/source/blender/editors/gpencil/gpencil_ops_versioning.c
+++ b/source/blender/editors/gpencil/gpencil_ops_versioning.c
@@ -92,7 +92,7 @@ static int gpencil_convert_old_files_exec(bContext *C, wmOperator *op)
if ((!is_annotation) && (view_layer != NULL)) {
Object *ob;
ob = BKE_object_add_for_data(
- bmain, view_layer, OB_GPENCIL, "GP_Scene", &scene->gpd->id, false);
+ bmain, scene, view_layer, OB_GPENCIL, "GP_Scene", &scene->gpd->id, false);
zero_v3(ob->loc);
DEG_relations_tag_update(bmain); /* added object */
@@ -122,7 +122,7 @@ static int gpencil_convert_old_files_exec(bContext *C, wmOperator *op)
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
- if ((gps->colorname[0] != '\0') && (STREQ(gps->colorname, palcolor->info))) {
+ if ((gps->colorname[0] != '\0') && STREQ(gps->colorname, palcolor->info)) {
gps->mat_nr = ob->totcol - 1;
gps->colorname[0] = '\0';
/* weights array */
@@ -160,7 +160,7 @@ static int gpencil_convert_old_files_exec(bContext *C, wmOperator *op)
gpl->tintcolor[3] = 0.0f;
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
- if ((gps->colorname[0] != '\0') && (STREQ(gps->colorname, palcolor->info))) {
+ if ((gps->colorname[0] != '\0') && STREQ(gps->colorname, palcolor->info)) {
/* copy color settings */
copy_v4_v4(gpl->color, palcolor->color);
}
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 8e33a029229..d2ed1720bf8 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -434,8 +434,7 @@ static void gpencil_stroke_convertcoords(tGPsdata *p,
rmval[1] = mval[1] - 0.5f;
round_v2i_v2fl(mval_i, rmval);
- if (gpencil_project_check(p) &&
- (ED_view3d_autodist_simple(p->region, mval_i, out, 0, depth))) {
+ if (gpencil_project_check(p) && ED_view3d_autodist_simple(p->region, mval_i, out, 0, depth)) {
/* projecting onto 3D-Geometry
* - nothing more needs to be done here, since view_autodist_simple() has already done it
*/
@@ -937,7 +936,7 @@ static bGPDstroke *gpencil_stroke_to_outline(tGPsdata *p, bGPDstroke *gps)
/* Apply layer thickness change. */
gps_duplicate->thickness += gpl->line_change;
/* Apply object scale to thickness. */
- gps_duplicate->thickness *= mat4_to_scale(p->ob->obmat);
+ gps_duplicate->thickness *= mat4_to_scale(p->ob->object_to_world);
CLAMP_MIN(gps_duplicate->thickness, 1.0f);
/* Stroke. */
@@ -1134,11 +1133,9 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
/* reproject to plane (only in 3d space) */
gpencil_reproject_toplane(p, gps);
- pt = gps->points;
- for (int i = 0; i < gps->totpoints; i++, pt++) {
- /* if parented change position relative to parent object */
- gpencil_apply_parent_point(depsgraph, obact, gpl, pt);
- }
+
+ /* Change position relative to object. */
+ gpencil_world_to_object_space(depsgraph, obact, gpl, gps);
/* If camera view or view projection, reproject flat to view to avoid perspective effect. */
if ((!is_depth) &&
@@ -1301,8 +1298,8 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
/* reproject to plane (only in 3d space) */
gpencil_reproject_toplane(p, gps);
- /* change position relative to parent object */
- gpencil_apply_parent(depsgraph, obact, gpl, gps);
+ /* Change position relative to parent object. */
+ gpencil_world_to_object_space(depsgraph, obact, gpl, gps);
/* If camera view or view projection, reproject flat to view to avoid perspective effect. */
if ((!is_depth) && (((align_flag & GP_PROJECT_VIEWSPACE) && is_lock_axis_view) || is_camera)) {
ED_gpencil_project_stroke_to_view(p->C, p->gpl, gps);
@@ -1387,7 +1384,8 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
}
gpencil_update_cache(p->gpd);
- BKE_gpencil_tag_full_update(p->gpd, gpl, p->gpf, NULL);
+ BKE_gpencil_tag_full_update(
+ p->gpd, gpl, GPENCIL_MULTIEDIT_SESSIONS_ON(p->gpd) ? NULL : p->gpf, NULL);
}
/* --- 'Eraser' for 'Paint' Tool ------ */
@@ -1551,10 +1549,10 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
/* only process if it hasn't been masked out... */
if (!(p->flags & GP_PAINTFLAG_SELECTMASK) || (gps->points->flag & GP_SPOINT_SELECT)) {
bGPDspoint pt_temp;
- gpencil_point_to_parent_space(gps->points, p->diff_mat, &pt_temp);
+ gpencil_point_to_world_space(gps->points, p->diff_mat, &pt_temp);
gpencil_point_to_xy(&p->gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
/* Do bound-box check first. */
- if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
+ if (!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1]) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
/* only check if point is inside */
if (len_v2v2_int(mval_i, pc1) <= radius) {
/* free stroke */
@@ -1575,11 +1573,11 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
/* get points to work with */
pt1 = gps->points + i;
bGPDspoint npt;
- gpencil_point_to_parent_space(pt1, p->diff_mat, &npt);
+ gpencil_point_to_world_space(pt1, p->diff_mat, &npt);
gpencil_point_to_xy(&p->gsc, gps, &npt, &pc1[0], &pc1[1]);
/* Do bound-box check first. */
- if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
+ if (!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1]) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
/* only check if point is inside */
if (len_v2v2_int(mval_i, pc1) <= radius) {
/* free stroke */
@@ -1633,14 +1631,14 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
}
bGPDspoint npt;
- gpencil_point_to_parent_space(pt1, p->diff_mat, &npt);
+ gpencil_point_to_world_space(pt1, p->diff_mat, &npt);
gpencil_point_to_xy(&p->gsc, gps, &npt, &pc1[0], &pc1[1]);
- gpencil_point_to_parent_space(pt2, p->diff_mat, &npt);
+ gpencil_point_to_world_space(pt2, p->diff_mat, &npt);
gpencil_point_to_xy(&p->gsc, gps, &npt, &pc2[0], &pc2[1]);
if (pt0) {
- gpencil_point_to_parent_space(pt0, p->diff_mat, &npt);
+ gpencil_point_to_world_space(pt0, p->diff_mat, &npt);
gpencil_point_to_xy(&p->gsc, gps, &npt, &pc0[0], &pc0[1]);
}
else {
@@ -1649,9 +1647,9 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
}
/* Check that point segment of the bound-box of the eraser stroke. */
- if (((!ELEM(V2D_IS_CLIPPED, pc0[0], pc0[1])) && BLI_rcti_isect_pt(rect, pc0[0], pc0[1])) ||
- ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) ||
- ((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) {
+ if ((!ELEM(V2D_IS_CLIPPED, pc0[0], pc0[1]) && BLI_rcti_isect_pt(rect, pc0[0], pc0[1])) ||
+ (!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1]) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) ||
+ (!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1]) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) {
/* Check if point segment of stroke had anything to do with
* eraser region (either within stroke painted, or on its lines)
* - this assumes that line-width is irrelevant.
@@ -1743,14 +1741,14 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
/* 2) Tag any point with overly low influence for removal in the next pass */
if ((inf1 > 0.0f) &&
- (((pt1->pressure < cull_thresh) || (p->flags & GP_PAINTFLAG_HARD_ERASER) ||
- (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD)))) {
+ ((pt1->pressure < cull_thresh) || (p->flags & GP_PAINTFLAG_HARD_ERASER) ||
+ (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD))) {
pt1->flag |= GP_SPOINT_TAG;
do_cull = true;
}
if ((inf1 > 2.0f) &&
- (((pt2->pressure < cull_thresh) || (p->flags & GP_PAINTFLAG_HARD_ERASER) ||
- (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD)))) {
+ ((pt2->pressure < cull_thresh) || (p->flags & GP_PAINTFLAG_HARD_ERASER) ||
+ (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD))) {
pt2->flag |= GP_SPOINT_TAG;
do_cull = true;
}
@@ -3331,7 +3329,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
return OPERATOR_RUNNING_MODAL;
}
-/* gpencil modal operator stores area, which can be removed while using it (like fullscreen) */
+/* gpencil modal operator stores area, which can be removed while using it (like full-screen). */
static bool gpencil_area_exists(bContext *C, ScrArea *area_test)
{
bScreen *screen = CTX_wm_screen(C);
@@ -3716,7 +3714,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
* is essential for ensuring that they can quickly return to that view.
*/
}
- else if ((!ELEM(p->paintmode, GP_PAINTMODE_ERASER, GP_PAINTMODE_SET_CP))) {
+ else if (!ELEM(p->paintmode, GP_PAINTMODE_ERASER, GP_PAINTMODE_SET_CP)) {
gpencil_guide_event_handling(C, op, event, p);
estate = OPERATOR_RUNNING_MODAL;
}
@@ -3738,7 +3736,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
* (Disabling RIGHTMOUSE case here results in bugs like T32647)
* also making sure we have a valid event value, to not exit too early
*/
- if (ELEM(event->type, LEFTMOUSE, RIGHTMOUSE) && (ELEM(event->val, KM_PRESS, KM_RELEASE))) {
+ if (ELEM(event->type, LEFTMOUSE, RIGHTMOUSE) && ELEM(event->val, KM_PRESS, KM_RELEASE)) {
/* if painting, end stroke */
if (p->status == GP_STATUS_PAINTING) {
p->status = GP_STATUS_DONE;
@@ -3888,7 +3886,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
- /* gpencil modal operator stores area, which can be removed while using it (like fullscreen) */
+ /* gpencil modal operator stores area, which can be removed while using it (like full-screen). */
if (0 == gpencil_area_exists(C, p->area)) {
estate = OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index 4a4fffc9638..b693d4ae185 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -677,8 +677,8 @@ static void gpencil_primitive_circle(tGPDprimitive *tgpi, tGPspoint *points2D)
center[0] = tgpi->start[0] + ((tgpi->end[0] - tgpi->start[0]) / 2.0f);
center[1] = tgpi->start[1] + ((tgpi->end[1] - tgpi->start[1]) / 2.0f);
- radius[0] = fabsf(((tgpi->end[0] - tgpi->start[0]) / 2.0f));
- radius[1] = fabsf(((tgpi->end[1] - tgpi->start[1]) / 2.0f));
+ radius[0] = fabsf((tgpi->end[0] - tgpi->start[0]) / 2.0f);
+ radius[1] = fabsf((tgpi->end[1] - tgpi->start[1]) / 2.0f);
for (int i = tgpi->tot_stored_edges; i < totpoints; i++) {
tGPspoint *p2d = &points2D[i];
@@ -1073,7 +1073,7 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
/* if parented change position relative to parent object */
for (int i = 0; i < gps->totpoints; i++) {
bGPDspoint *pt = &gps->points[i];
- gpencil_apply_parent_point(tgpi->depsgraph, tgpi->ob, tgpi->gpl, pt);
+ gpencil_world_to_object_space_point(tgpi->depsgraph, tgpi->ob, tgpi->gpl, pt);
}
/* If camera view or view projection, reproject flat to view to avoid perspective effect. */
@@ -1515,7 +1515,7 @@ static void gpencil_primitive_edit_event_handling(
break;
}
case EVT_MKEY: {
- if ((event->val == KM_PRESS) && (tgpi->curve) && (ELEM(tgpi->orign_type, GP_STROKE_ARC))) {
+ if ((event->val == KM_PRESS) && (tgpi->curve) && ELEM(tgpi->orign_type, GP_STROKE_ARC)) {
tgpi->flip ^= 1;
gpencil_primitive_update_cps(tgpi);
gpencil_primitive_update(C, op, tgpi);
@@ -1703,7 +1703,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
}
case EVT_PADPLUSKEY:
case WHEELUPMOUSE: {
- if ((event->val != KM_RELEASE)) {
+ if (event->val != KM_RELEASE) {
tgpi->tot_edges = tgpi->tot_edges + 1;
CLAMP(tgpi->tot_edges, tgpi->type == GP_STROKE_BOX ? 1 : MIN_EDGES, MAX_EDGES);
RNA_int_set(op->ptr, "edges", tgpi->tot_edges);
@@ -1713,7 +1713,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
}
case EVT_PADMINUS:
case WHEELDOWNMOUSE: {
- if ((event->val != KM_RELEASE)) {
+ if (event->val != KM_RELEASE) {
tgpi->tot_edges = tgpi->tot_edges - 1;
CLAMP(tgpi->tot_edges, tgpi->type == GP_STROKE_BOX ? 1 : MIN_EDGES, MAX_EDGES);
RNA_int_set(op->ptr, "edges", tgpi->tot_edges);
@@ -1723,7 +1723,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
}
case EVT_FKEY: /* brush thickness/ brush strength */
{
- if ((event->val == KM_PRESS)) {
+ if (event->val == KM_PRESS) {
if (event->modifier & KM_SHIFT) {
tgpi->prev_flag = tgpi->flag;
tgpi->flag = IN_BRUSH_STRENGTH;
@@ -1808,14 +1808,14 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
}
}
else if ((event->val == KM_RELEASE) && (tgpi->flag == IN_PROGRESS) &&
- (!ELEM(tgpi->type, GP_STROKE_POLYLINE))) {
+ !ELEM(tgpi->type, GP_STROKE_POLYLINE)) {
/* set control points and enter edit mode */
tgpi->flag = IN_CURVE_EDIT;
gpencil_primitive_update_cps(tgpi);
gpencil_primitive_update(C, op, tgpi);
}
else if ((event->val == KM_RELEASE) && (tgpi->flag == IN_PROGRESS) &&
- (!ELEM(tgpi->type, GP_STROKE_CURVE, GP_STROKE_POLYLINE))) {
+ !ELEM(tgpi->type, GP_STROKE_CURVE, GP_STROKE_POLYLINE)) {
/* stop drawing primitive */
tgpi->flag = IDLE;
gpencil_primitive_interaction_end(C, op, win, tgpi);
@@ -1823,7 +1823,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
return OPERATOR_FINISHED;
}
else if ((event->val == KM_RELEASE) && (tgpi->flag == IN_PROGRESS) &&
- (ELEM(tgpi->type, GP_STROKE_POLYLINE))) {
+ ELEM(tgpi->type, GP_STROKE_POLYLINE)) {
/* set control points and enter edit mode */
tgpi->flag = IN_POLYLINE;
gpencil_primitive_update(C, op, tgpi);
@@ -1869,7 +1869,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
}
case EVT_PADPLUSKEY:
case WHEELUPMOUSE: {
- if ((event->val != KM_RELEASE)) {
+ if (event->val != KM_RELEASE) {
tgpi->tot_edges = tgpi->tot_edges + 1;
CLAMP(tgpi->tot_edges, tgpi->type == GP_STROKE_BOX ? 1 : MIN_EDGES, MAX_EDGES);
RNA_int_set(op->ptr, "edges", tgpi->tot_edges);
@@ -1881,7 +1881,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
}
case EVT_PADMINUS:
case WHEELDOWNMOUSE: {
- if ((event->val != KM_RELEASE)) {
+ if (event->val != KM_RELEASE) {
tgpi->tot_edges = tgpi->tot_edges - 1;
CLAMP(tgpi->tot_edges, tgpi->type == GP_STROKE_BOX ? 1 : MIN_EDGES, MAX_EDGES);
RNA_int_set(op->ptr, "edges", tgpi->tot_edges);
@@ -1893,7 +1893,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
}
case EVT_GKEY: /* grab mode */
{
- if ((event->val == KM_PRESS)) {
+ if (event->val == KM_PRESS) {
tgpi->flag = IN_MOVE;
WM_cursor_modal_set(win, WM_CURSOR_NSEW_SCROLL);
}
@@ -1901,7 +1901,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
}
case EVT_FKEY: /* brush thickness/ brush strength */
{
- if ((event->val == KM_PRESS)) {
+ if (event->val == KM_PRESS) {
if (event->modifier & KM_SHIFT) {
tgpi->prev_flag = tgpi->flag;
tgpi->flag = IN_BRUSH_STRENGTH;
diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
index e27cd255217..ab3edfdd4fa 100644
--- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c
+++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
@@ -68,6 +68,8 @@
#include "gpencil_intern.h"
+#define SEARCH_RADIUS_PIXEL 20
+
/* ************************************************ */
/* General Brush Editing Context */
@@ -78,6 +80,7 @@ typedef struct tGP_BrushEditData {
Main *bmain;
Scene *scene;
Object *object;
+ Object *ob_eval;
ScrArea *area;
ARegion *region;
@@ -516,7 +519,7 @@ static void gpencil_brush_grab_calc_dvec(tGP_BrushEditData *gso)
float mval_f[2];
- /* convert from 2D screenspace to 3D... */
+ /* Convert from 2D screen-space to 3D. */
mval_f[0] = (float)(gso->mval[0] - gso->mval_prev[0]);
mval_f[1] = (float)(gso->mval[1] - gso->mval_prev[1]);
@@ -544,8 +547,10 @@ static void gpencil_brush_grab_apply_cached(tGP_BrushEditData *gso,
return;
}
- float inverse_diff_mat[4][4];
- invert_m4_m4(inverse_diff_mat, diff_mat);
+ float matrix[4][4], inverse_diff_mat[4][4];
+ copy_m4_m4(matrix, diff_mat);
+ zero_axis_bias_m4(matrix);
+ invert_m4_m4(inverse_diff_mat, matrix);
/* Apply dvec to all of the stored points */
for (int i = 0; i < data->size; i++) {
@@ -669,7 +674,7 @@ static bool gpencil_brush_pinch_apply(tGP_BrushEditData *gso,
/* 1) Make this point relative to the cursor/midpoint (dvec) */
float fpt[3];
- mul_v3_m4v3(fpt, gso->object->obmat, &pt->x);
+ mul_v3_m4v3(fpt, gso->object->object_to_world, &pt->x);
sub_v3_v3v3(vec, fpt, gso->dvec);
/* 2) Shrink the distance by pulling the point towards the midpoint
@@ -689,7 +694,7 @@ static bool gpencil_brush_pinch_apply(tGP_BrushEditData *gso,
/* 3) Translate back to original space, with the shrinkage applied */
add_v3_v3v3(fpt, gso->dvec, vec);
- mul_v3_m4v3(&pt->x, gso->object->imat, fpt);
+ mul_v3_m4v3(&pt->x, gso->object->world_to_object, fpt);
/* compute lock axis */
gpencil_sculpt_compute_lock_axis(gso, pt, save_pt);
@@ -700,8 +705,8 @@ static bool gpencil_brush_pinch_apply(tGP_BrushEditData *gso,
/* ----------------------------------------------- */
/* Twist Brush - Rotate Around midpoint */
-/* Take the screenspace coordinates of the point, rotate this around the brush midpoint,
- * convert the rotated point and convert it into "data" space
+/* Take the screen-space coordinates of the point, rotate this around the brush midpoint,
+ * convert the rotated point and convert it into "data" space.
*/
static bool gpencil_brush_twist_apply(tGP_BrushEditData *gso,
@@ -741,12 +746,12 @@ static bool gpencil_brush_twist_apply(tGP_BrushEditData *gso,
/* Rotate point */
float fpt[3];
- mul_v3_m4v3(fpt, gso->object->obmat, &pt->x);
+ mul_v3_m4v3(fpt, gso->object->object_to_world, &pt->x);
sub_v3_v3v3(vec, fpt, gso->dvec); /* make relative to center
* (center is stored in dvec) */
mul_m3_v3(rmat, vec);
add_v3_v3v3(fpt, vec, gso->dvec); /* restore */
- mul_v3_m4v3(&pt->x, gso->object->imat, fpt);
+ mul_v3_m4v3(&pt->x, gso->object->world_to_object, fpt);
/* compute lock axis */
gpencil_sculpt_compute_lock_axis(gso, pt, save_pt);
@@ -807,7 +812,7 @@ static bool gpencil_brush_randomize_apply(tGP_BrushEditData *gso,
/* apply random to position */
if (gso->brush->gpencil_settings->sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_POSITION) {
/* Jitter is applied perpendicular to the mouse movement vector
- * - We compute all effects in screenspace (since it's easier)
+ * - We compute all effects in screen-space (since it's easier)
* and then project these to get the points/distances in
* view-space as needed.
*/
@@ -989,8 +994,8 @@ static void gpencil_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
float delta[3];
size_t strokes_added = 0;
- /* Compute amount to offset the points by */
- /* NOTE: This assumes that screenspace strokes are NOT used in the 3D view... */
+ /* Compute amount to offset the points by. */
+ /* NOTE: This assumes that screen-space strokes are NOT used in the 3D view. */
gpencil_brush_calc_midpoint(gso); /* this puts the cursor location into gso->dvec */
sub_v3_v3v3(delta, gso->dvec, data->buffer_midpoint);
@@ -1035,11 +1040,11 @@ static void gpencil_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
*/
for (i = 0, pt = new_stroke->points; i < new_stroke->totpoints; i++, pt++) {
/* Rotate around center new position */
- mul_mat3_m4_v3(gso->object->obmat, &pt->x); /* only rotation component */
+ mul_mat3_m4_v3(gso->object->object_to_world, &pt->x); /* only rotation component */
/* assume that the delta can just be applied, and then everything works */
add_v3_v3(&pt->x, delta);
- mul_m4_v3(gso->object->imat, &pt->x);
+ mul_m4_v3(gso->object->world_to_object, &pt->x);
}
/* Store ref for later */
@@ -1063,7 +1068,7 @@ static void gpencil_brush_clone_adjust(tGP_BrushEditData *gso)
/* For each of the stored strokes, apply the offset to each point */
/* NOTE: Again this assumes that in the 3D view,
- * we only have 3d space and not screenspace strokes... */
+ * we only have 3d space and not screen-space strokes. */
for (snum = 0; snum < data->totitems; snum++) {
bGPDstroke *gps = data->new_strokes[snum];
bGPDspoint *pt;
@@ -1169,13 +1174,18 @@ static bool gpencil_sculpt_brush_init(bContext *C, wmOperator *op)
gso->scene = scene;
gso->object = ob;
if (ob) {
- invert_m4_m4(gso->inv_mat, ob->obmat);
+ float matrix[4][4];
+ copy_m4_m4(matrix, ob->object_to_world);
+ zero_axis_bias_m4(matrix);
+ invert_m4_m4(gso->inv_mat, matrix);
gso->vrgroup = gso->gpd->vertex_group_active_index - 1;
if (!BLI_findlink(&gso->gpd->vertex_group_names, gso->vrgroup)) {
gso->vrgroup = -1;
}
/* Check if some modifier can transform the stroke. */
gso->is_transformed = BKE_gpencil_has_transform_modifiers(ob);
+
+ gso->ob_eval = (Object *)DEG_get_evaluated_id(gso->depsgraph, &ob->id);
}
else {
unit_m4(gso->inv_mat);
@@ -1191,12 +1201,19 @@ static bool gpencil_sculpt_brush_init(bContext *C, wmOperator *op)
gso->brush = brush;
BKE_curvemapping_init(gso->brush->curve);
- if (brush->gpencil_settings->sculpt_mode_flag &
- (GP_SCULPT_FLAGMODE_AUTOMASK_STROKE | GP_SCULPT_FLAGMODE_AUTOMASK_LAYER |
- GP_SCULPT_FLAGMODE_AUTOMASK_MATERIAL)) {
+ const bool is_automasking = (ts->gp_sculpt.flag &
+ (GP_SCULPT_SETT_FLAG_AUTOMASK_STROKE |
+ GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_STROKE |
+ GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_STROKE |
+ GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_ACTIVE |
+ GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_ACTIVE)) != 0;
+ if (is_automasking) {
gso->automasking_strokes = BLI_ghash_ptr_new(__func__);
}
else {
+ if (gso->automasking_strokes != NULL) {
+ BLI_ghash_free(gso->automasking_strokes, NULL, NULL);
+ }
gso->automasking_strokes = NULL;
}
/* save mask */
@@ -1287,6 +1304,10 @@ static void gpencil_sculpt_brush_exit(bContext *C, wmOperator *op)
}
default:
+ if (gso->stroke_customdata != NULL) {
+ BLI_ghash_free(gso->stroke_customdata, NULL, NULL);
+ gso->stroke_customdata = NULL;
+ }
break;
}
@@ -1462,12 +1483,12 @@ static bool gpencil_sculpt_brush_do_stroke(tGP_BrushEditData *gso,
bGPDspoint pt_temp;
pt = &gps->points[0];
if ((is_masking && (pt->flag & GP_SPOINT_SELECT) != 0) || (!is_masking)) {
- gpencil_point_to_parent_space(gps->points, diff_mat, &pt_temp);
+ gpencil_point_to_world_space(gps->points, diff_mat, &pt_temp);
gpencil_point_to_xy(gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
/* Do bound-box check first. */
- if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
+ if (!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1]) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
/* only check if point is inside */
int mval_i[2];
round_v2i_v2fl(mval_i, gso->mval);
@@ -1499,15 +1520,15 @@ static bool gpencil_sculpt_brush_do_stroke(tGP_BrushEditData *gso,
}
}
bGPDspoint npt;
- gpencil_point_to_parent_space(pt1, diff_mat, &npt);
+ gpencil_point_to_world_space(pt1, diff_mat, &npt);
gpencil_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]);
- gpencil_point_to_parent_space(pt2, diff_mat, &npt);
+ gpencil_point_to_world_space(pt2, diff_mat, &npt);
gpencil_point_to_xy(gsc, gps, &npt, &pc2[0], &pc2[1]);
/* Check that point segment of the bound-box of the selection stroke. */
- if (((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) ||
- ((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) {
+ if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1]) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) ||
+ (!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1]) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) {
/* Check if point segment of stroke had anything to do with
* brush region (either within stroke painted, or on its lines)
* - this assumes that line-width is irrelevant.
@@ -1592,13 +1613,16 @@ static bool gpencil_sculpt_brush_do_frame(bContext *C,
bGPdata *gpd = ob->data;
const char tool = gso->brush->gpencil_sculpt_tool;
GP_SpaceConversion *gsc = &gso->gsc;
+ ToolSettings *ts = gso->scene->toolsettings;
Brush *brush = gso->brush;
const int radius = (brush->flag & GP_BRUSH_USE_PRESSURE) ? gso->brush->size * gso->pressure :
gso->brush->size;
- const bool is_automasking = (brush->gpencil_settings->sculpt_mode_flag &
- (GP_SCULPT_FLAGMODE_AUTOMASK_STROKE |
- GP_SCULPT_FLAGMODE_AUTOMASK_LAYER |
- GP_SCULPT_FLAGMODE_AUTOMASK_MATERIAL)) != 0;
+ const bool is_automasking = (ts->gp_sculpt.flag &
+ (GP_SCULPT_SETT_FLAG_AUTOMASK_STROKE |
+ GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_STROKE |
+ GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_STROKE |
+ GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_ACTIVE |
+ GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_ACTIVE)) != 0;
/* Calc bound box matrix. */
float bound_mat[4][4];
BKE_gpencil_layer_transform_matrix_get(gso->depsgraph, gso->object, gpl, bound_mat);
@@ -1615,14 +1639,14 @@ static bool gpencil_sculpt_brush_do_frame(bContext *C,
{
bGPDstroke *gps_active = (gps->runtime.gps_orig) ? gps->runtime.gps_orig : gps;
- if ((is_automasking) && (!BLI_ghash_haskey(gso->automasking_strokes, gps_active))) {
+ if ((is_automasking) && !BLI_ghash_haskey(gso->automasking_strokes, gps_active)) {
continue;
}
}
/* Check if the stroke collide with brush. */
if ((gps->totpoints > 1) &&
- (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat))) {
+ !ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
continue;
}
@@ -1731,27 +1755,111 @@ static bool gpencil_sculpt_brush_do_frame(bContext *C,
return changed;
}
+/* Find the stroke nearer to the brush. */
+static void get_nearest_stroke_to_brush(tGP_BrushEditData *gso,
+ int mval_i[2],
+ bGPDlayer **r_gpl,
+ bGPDstroke **r_gps)
+{
+ const int radius = SEARCH_RADIUS_PIXEL;
+
+ Object *ob_eval = gso->ob_eval;
+ bGPdata *gpd = (bGPdata *)ob_eval->data;
+ GP_SpaceConversion *gsc = &gso->gsc;
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ float dist = FLT_MAX;
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ if (!BKE_gpencil_layer_is_editable(gpl) || (gpl->actframe == NULL)) {
+ continue;
+ }
+ /* Calculate bound box matrix. */
+ float bound_mat[4][4];
+ BKE_gpencil_layer_transform_matrix_get(gso->depsgraph, gso->object, gpl, bound_mat);
+
+ bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ bGPDstroke *gps_active = (gps->runtime.gps_orig) ? gps->runtime.gps_orig : gps;
+ if (gps->totpoints == 0) {
+ continue;
+ }
+ /* Check if the color is editable. */
+ if (ED_gpencil_stroke_material_editable(gso->object, gpl, gps) == false) {
+ continue;
+ }
+
+ /* Check if the stroke collide with brush. */
+ if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
+ continue;
+ }
+
+ bGPDspoint *pt;
+ int pc2D[2] = {0};
+ bGPDspoint npt;
+
+ for (int i = 0; i < gps->totpoints; i++) {
+ pt = gps->points + i;
+ gpencil_point_to_world_space(pt, bound_mat, &npt);
+ gpencil_point_to_xy(gsc, gps, &npt, &pc2D[0], &pc2D[1]);
+ float d = len_v2v2_int(mval_i, pc2D);
+ if (d < dist) {
+ dist = d;
+ *r_gpl = gpl;
+ *r_gps = gps_active;
+ }
+ }
+ }
+ /* If not multi-edit, exit loop. */
+ if (!is_multiedit) {
+ break;
+ }
+ }
+ }
+}
+
/* Get list of Auto-Masking strokes. */
static bool get_automasking_strokes_list(tGP_BrushEditData *gso)
{
- bGPdata *gpd = gso->gpd;
+ Object *ob_eval = gso->ob_eval;
+ bGPdata *gpd = (bGPdata *)ob_eval->data;
GP_SpaceConversion *gsc = &gso->gsc;
- Brush *brush = gso->brush;
+ ToolSettings *ts = gso->scene->toolsettings;
Object *ob = gso->object;
- Material *mat_active = BKE_gpencil_material(ob, ob->actcol);
+ const eGP_Sculpt_SettingsFlag flag = ts->gp_sculpt.flag;
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
- const bool is_masking_stroke = (brush->gpencil_settings->sculpt_mode_flag &
- GP_SCULPT_FLAGMODE_AUTOMASK_STROKE) != 0;
- const bool is_masking_layer = (brush->gpencil_settings->sculpt_mode_flag &
- GP_SCULPT_FLAGMODE_AUTOMASK_LAYER) != 0;
- const bool is_masking_material = (brush->gpencil_settings->sculpt_mode_flag &
- GP_SCULPT_FLAGMODE_AUTOMASK_MATERIAL) != 0;
+ const bool is_masking_stroke = (flag & GP_SCULPT_SETT_FLAG_AUTOMASK_STROKE) != 0;
+ const bool is_masking_layer_stroke = (flag & GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_STROKE) != 0;
+ const bool is_masking_material_stroke = (flag & GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_STROKE) !=
+ 0;
+ const bool is_masking_layer_active = (flag & GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_ACTIVE) != 0;
+ const bool is_masking_material_active = (flag & GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_ACTIVE) !=
+ 0;
int mval_i[2];
round_v2i_v2fl(mval_i, gso->mval);
/* Define a fix number of pixel as cursor radius. */
- const int radius = 10;
+ const int radius = SEARCH_RADIUS_PIXEL;
bGPDlayer *gpl_active = BKE_gpencil_layer_active_get(gpd);
+ Material *mat_active = BKE_gpencil_material(ob, ob->actcol);
+
+ /* By default use active values. */
+ bGPDlayer *gpl_active_stroke = gpl_active;
+ Material *mat_active_stroke = mat_active;
+ /* Find nearest stroke to find the layer and material. */
+ if (is_masking_layer_stroke || is_masking_material_stroke) {
+ bGPDlayer *gpl_near = NULL;
+ bGPDstroke *gps_near = NULL;
+ get_nearest_stroke_to_brush(gso, mval_i, &gpl_near, &gps_near);
+ if (gps_near != NULL) {
+ if (is_masking_layer_stroke) {
+ gpl_active_stroke = gpl_near;
+ }
+ if (is_masking_material_stroke) {
+ mat_active_stroke = BKE_object_material_get(ob, gps_near->mat_nr + 1);
+ }
+ }
+ }
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
/* Only editable and visible layers are considered. */
@@ -1765,87 +1873,113 @@ static bool get_automasking_strokes_list(tGP_BrushEditData *gso)
bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ bGPDstroke *gps_active = (gps->runtime.gps_orig) ? gps->runtime.gps_orig : gps;
+ bool pick_stroke = false;
+ bool pick_layer_stroke = false;
+ bool pick_material_stroke = false;
+ bool pick_layer_active = false;
+ bool pick_material_active = false;
+
if (gps->totpoints == 0) {
continue;
}
- /* Check if the color is editable. */
+ /* Check if the material is editable. */
if (ED_gpencil_stroke_material_editable(gso->object, gpl, gps) == false) {
continue;
}
- /* Layer Auto-Masking. */
- if ((is_masking_layer) && (gpl == gpl_active)) {
- BLI_ghash_insert(gso->automasking_strokes, gps, gps);
- continue;
+ /* Stroke Layer Auto-Masking. */
+ if (is_masking_layer_stroke && (gpl == gpl_active_stroke)) {
+ pick_layer_stroke = true;
}
- /* Material Auto-Masking. */
- if (is_masking_material) {
+ /* Active Layer Auto-Masking. */
+ if (is_masking_layer_active && (gpl == gpl_active)) {
+ pick_layer_active = true;
+ }
+ /* Stroke Material Auto-Masking. */
+ if (is_masking_material_stroke) {
Material *mat = BKE_object_material_get(ob, gps->mat_nr + 1);
- if (mat == mat_active) {
- BLI_ghash_insert(gso->automasking_strokes, gps, gps);
- continue;
+ if (mat == mat_active_stroke) {
+ pick_material_stroke = true;
}
}
-
- /* If Stroke Auto-Masking is not enabled, nothing else to do. */
- if (!is_masking_stroke) {
- continue;
+ /* Active Material Auto-Masking. */
+ if (is_masking_material_active) {
+ Material *mat = BKE_object_material_get(ob, gps->mat_nr + 1);
+ if (mat == mat_active) {
+ pick_material_active = true;
+ }
}
/* Check if the stroke collide with brush. */
- if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
- continue;
- }
-
- bGPDspoint *pt1, *pt2;
- int pc1[2] = {0};
- int pc2[2] = {0};
- bGPDspoint npt;
+ if ((is_masking_stroke) &&
+ ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
- if (gps->totpoints == 1) {
- gpencil_point_to_parent_space(gps->points, bound_mat, &npt);
- gpencil_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]);
+ bGPDspoint *pt1, *pt2;
+ int pc1[2] = {0};
+ int pc2[2] = {0};
+ bGPDspoint npt;
- /* Only check if point is inside. */
- if (len_v2v2_int(mval_i, pc1) <= radius) {
- BLI_ghash_insert(gso->automasking_strokes, gps, gps);
- }
- }
- else {
- /* Loop over the points in the stroke, checking for intersections
- * - an intersection means that we touched the stroke.
- */
- for (int i = 0; (i + 1) < gps->totpoints; i++) {
- /* Get points to work with. */
- pt1 = gps->points + i;
- pt2 = gps->points + i + 1;
-
- /* Check first point. */
- gpencil_point_to_parent_space(pt1, bound_mat, &npt);
+ if (gps->totpoints == 1) {
+ gpencil_point_to_world_space(gps->points, bound_mat, &npt);
gpencil_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]);
- if (len_v2v2_int(mval_i, pc1) <= radius) {
- BLI_ghash_insert(gso->automasking_strokes, gps, gps);
- i = gps->totpoints;
- continue;
- }
- /* Check second point. */
- gpencil_point_to_parent_space(pt2, bound_mat, &npt);
- gpencil_point_to_xy(gsc, gps, &npt, &pc2[0], &pc2[1]);
- if (len_v2v2_int(mval_i, pc2) <= radius) {
- BLI_ghash_insert(gso->automasking_strokes, gps, gps);
- i = gps->totpoints;
- continue;
+ /* Only check if point is inside. */
+ if (len_v2v2_int(mval_i, pc1) <= radius) {
+ pick_stroke = true;
}
-
- /* Check segment. */
- if (gpencil_stroke_inside_circle(gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
- BLI_ghash_insert(gso->automasking_strokes, gps, gps);
- i = gps->totpoints;
- continue;
+ }
+ else {
+ /* Loop over the points in the stroke, checking for intersections
+ * - an intersection means that we touched the stroke.
+ */
+ for (int i = 0; (i + 1) < gps->totpoints && !pick_stroke; i++) {
+ /* Get points to work with. */
+ pt1 = gps->points + i;
+ pt2 = gps->points + i + 1;
+
+ /* Check first point. */
+ gpencil_point_to_world_space(pt1, bound_mat, &npt);
+ gpencil_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]);
+ if (len_v2v2_int(mval_i, pc1) <= radius) {
+ pick_stroke = true;
+ i = gps->totpoints;
+ }
+
+ /* Check second point. */
+ gpencil_point_to_world_space(pt2, bound_mat, &npt);
+ gpencil_point_to_xy(gsc, gps, &npt, &pc2[0], &pc2[1]);
+ if (len_v2v2_int(mval_i, pc2) <= radius) {
+ pick_stroke = true;
+ i = gps->totpoints;
+ }
+
+ /* Check segment. */
+ if (!pick_stroke && gpencil_stroke_inside_circle(
+ gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
+ pick_stroke = true;
+ i = gps->totpoints;
+ }
}
}
}
+ /* if the stroke meets all the masking conditions, add to the hash table. */
+ if (is_masking_stroke && !pick_stroke) {
+ continue;
+ }
+ if (is_masking_layer_stroke && !pick_layer_stroke) {
+ continue;
+ }
+ if (is_masking_material_stroke && !pick_material_stroke) {
+ continue;
+ }
+ if (is_masking_layer_active && !pick_layer_active) {
+ continue;
+ }
+ if (is_masking_material_active && !pick_material_active) {
+ continue;
+ }
+ BLI_ghash_insert(gso->automasking_strokes, gps_active, gps_active);
}
/* If not multi-edit, exit loop. */
if (!is_multiedit) {
@@ -1865,7 +1999,7 @@ static bool gpencil_sculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *
Object *obact = gso->object;
bool changed = false;
- Object *ob_eval = (Object *)DEG_get_evaluated_id(depsgraph, &obact->id);
+ Object *ob_eval = gso->ob_eval;
bGPdata *gpd = (bGPdata *)ob_eval->data;
/* Calculate brush-specific data which applies equally to all points */
@@ -1903,7 +2037,7 @@ static bool gpencil_sculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *
/* Find visible strokes, and perform operations on those if hit */
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
/* If no active frame, don't do anything... */
- if ((!BKE_gpencil_layer_is_editable(gpl)) || (gpl->actframe == NULL)) {
+ if (!BKE_gpencil_layer_is_editable(gpl) || (gpl->actframe == NULL)) {
continue;
}
@@ -1959,6 +2093,7 @@ static void gpencil_sculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA *
{
tGP_BrushEditData *gso = op->customdata;
Brush *brush = gso->brush;
+ ToolSettings *ts = gso->scene->toolsettings;
const int radius = (brush->flag & GP_BRUSH_USE_PRESSURE) ? gso->brush->size * gso->pressure :
gso->brush->size;
float mousef[2];
@@ -2000,9 +2135,10 @@ static void gpencil_sculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA *
/* Get list of Auto-Masking strokes. */
if ((!gso->automasking_ready) &&
- (brush->gpencil_settings->sculpt_mode_flag &
- (GP_SCULPT_FLAGMODE_AUTOMASK_STROKE | GP_SCULPT_FLAGMODE_AUTOMASK_LAYER |
- GP_SCULPT_FLAGMODE_AUTOMASK_MATERIAL))) {
+ (ts->gp_sculpt.flag &
+ (GP_SCULPT_SETT_FLAG_AUTOMASK_STROKE | GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_STROKE |
+ GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_STROKE | GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_ACTIVE |
+ GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_ACTIVE))) {
gso->automasking_ready = get_automasking_strokes_list(gso);
}
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index a19265720e8..13455861924 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -94,13 +94,13 @@ static bool gpencil_select_poll(bContext *C)
ToolSettings *ts = CTX_data_tool_settings(C);
if (GPENCIL_SCULPT_MODE(gpd)) {
- if (!(GPENCIL_ANY_SCULPT_MASK(ts->gpencil_selectmode_sculpt))) {
+ if (!GPENCIL_ANY_SCULPT_MASK(ts->gpencil_selectmode_sculpt)) {
return false;
}
}
if (GPENCIL_VERTEX_MODE(gpd)) {
- if (!(GPENCIL_ANY_VERTEX_MASK(ts->gpencil_selectmode_vertex))) {
+ if (!GPENCIL_ANY_VERTEX_MASK(ts->gpencil_selectmode_vertex)) {
return false;
}
}
@@ -267,7 +267,7 @@ static int gpencil_select_all_exec(bContext *C, wmOperator *op)
/* For sculpt mode, if mask is disable, only allows deselect */
if (GPENCIL_SCULPT_MODE(gpd)) {
ToolSettings *ts = CTX_data_tool_settings(C);
- if ((!(GPENCIL_ANY_SCULPT_MASK(ts->gpencil_selectmode_sculpt))) && (action != SEL_DESELECT)) {
+ if (!GPENCIL_ANY_SCULPT_MASK(ts->gpencil_selectmode_sculpt) && (action != SEL_DESELECT)) {
return OPERATOR_CANCELLED;
}
}
@@ -529,7 +529,7 @@ static int gpencil_select_random_exec(bContext *C, wmOperator *op)
Object *ob = CTX_data_active_object(C);
ToolSettings *ts = CTX_data_tool_settings(C);
bGPdata *gpd = ED_gpencil_data_get_active(C);
- if ((gpd == NULL) || (GPENCIL_NONE_EDIT_MODE(gpd))) {
+ if ((gpd == NULL) || GPENCIL_NONE_EDIT_MODE(gpd)) {
return OPERATOR_CANCELLED;
}
@@ -576,7 +576,7 @@ static int gpencil_select_random_exec(bContext *C, wmOperator *op)
if (selectmode == GP_SELECTMODE_STROKE) {
RNG *rng = BLI_rng_new(seed_iter);
- const unsigned int j = BLI_rng_get_uint(rng) % gps->totpoints;
+ const uint j = BLI_rng_get_uint(rng) % gps->totpoints;
bool select_stroke = ((gps->totpoints * randfac) <= j) ? true : false;
select_stroke ^= select;
/* Curve function has select parameter inverted. */
@@ -647,7 +647,7 @@ static int gpencil_select_random_exec(bContext *C, wmOperator *op)
if (selectmode == GP_SELECTMODE_STROKE) {
RNG *rng = BLI_rng_new(seed_iter);
- const unsigned int j = BLI_rng_get_uint(rng) % gps->totpoints;
+ const uint j = BLI_rng_get_uint(rng) % gps->totpoints;
bool select_stroke = ((gps->totpoints * randfac) <= j) ? true : false;
select_stroke ^= select;
select_all_stroke_points(gpd, gps, select_stroke);
@@ -1497,11 +1497,11 @@ static bool gpencil_stroke_do_circle_sel(bGPdata *gpd,
pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
bGPDspoint pt_temp;
- gpencil_point_to_parent_space(pt, diff_mat, &pt_temp);
+ gpencil_point_to_world_space(pt, diff_mat, &pt_temp);
gpencil_point_to_xy(gsc, gps, &pt_temp, &x0, &y0);
/* do boundbox check first */
- if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) {
+ if (!ELEM(V2D_IS_CLIPPED, x0, y0) && BLI_rcti_isect_pt(rect, x0, y0)) {
/* only check if point is inside */
if (((x0 - mx) * (x0 - mx) + (y0 - my) * (y0 - my)) <= radius * radius) {
hit = true;
@@ -2040,7 +2040,7 @@ static bool gpencil_generic_stroke_select(bContext *C,
gpencil_point_conversion_init(C, &gsc);
/* deselect all strokes first? */
- if (SEL_OP_USE_PRE_DESELECT(sel_op) || (GPENCIL_PAINT_MODE(gpd))) {
+ if (SEL_OP_USE_PRE_DESELECT(sel_op) || GPENCIL_PAINT_MODE(gpd)) {
/* Set selection index to 0. */
gpd->select_last_index = 0;
@@ -2071,8 +2071,9 @@ static bool gpencil_generic_stroke_select(bContext *C,
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
bGPDspoint *pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
- /* convert point coords to screenspace */
- const bool is_inside = is_inside_fn(gsc.region, gpstroke_iter.diff_mat, &pt->x, user_data);
+ /* Convert point coords to screen-space. */
+ const bool is_inside = is_inside_fn(
+ gsc.region, gpstroke_iter.diff_mat, &pt_active->x, user_data);
if (strokemode == false) {
const bool is_select = (pt_active->flag & GP_SPOINT_SELECT) != 0;
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
@@ -2477,7 +2478,7 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
int xy[2];
bGPDspoint pt2;
- gpencil_point_to_parent_space(pt, gpstroke_iter.diff_mat, &pt2);
+ gpencil_point_to_world_space(pt, gpstroke_iter.diff_mat, &pt2);
gpencil_point_to_xy(&gsc, gps_active, &pt2, &xy[0], &xy[1]);
/* do boundbox check first */
@@ -2766,7 +2767,7 @@ static bool gpencil_select_vertex_color_poll(bContext *C)
bGPdata *gpd = (bGPdata *)ob->data;
if (GPENCIL_VERTEX_MODE(gpd)) {
- if (!(GPENCIL_ANY_VERTEX_MASK(ts->gpencil_selectmode_vertex))) {
+ if (!GPENCIL_ANY_VERTEX_MASK(ts->gpencil_selectmode_vertex)) {
return false;
}
diff --git a/source/blender/editors/gpencil/gpencil_trace_ops.c b/source/blender/editors/gpencil/gpencil_trace_ops.c
index f6e88e05d46..1a18e10412e 100644
--- a/source/blender/editors/gpencil/gpencil_trace_ops.c
+++ b/source/blender/editors/gpencil/gpencil_trace_ops.c
@@ -45,7 +45,7 @@
typedef struct TraceJob {
/* from wmJob */
struct Object *owner;
- short *stop, *do_update;
+ bool *stop, *do_update;
float *progress;
bContext *C;
@@ -71,6 +71,9 @@ typedef struct TraceJob {
int32_t thickness;
int32_t turnpolicy;
int32_t mode;
+ /** Frame to render to be used by python API. Not exposed in UI.
+ * This feature is only used in Studios to run custom video trace for selected frames. */
+ int32_t frame_num;
bool success;
bool was_canceled;
@@ -195,7 +198,7 @@ static void trace_initialize_job_data(TraceJob *trace_job)
}
}
-static void trace_start_job(void *customdata, short *stop, short *do_update, float *progress)
+static void trace_start_job(void *customdata, bool *stop, bool *do_update, float *progress)
{
TraceJob *trace_job = customdata;
@@ -212,7 +215,10 @@ static void trace_start_job(void *customdata, short *stop, short *do_update, flo
(trace_job->mode == GPENCIL_TRACE_MODE_SINGLE)) {
void *lock;
ImageUser *iuser = trace_job->ob_active->iuser;
- iuser->framenr = init_frame;
+
+ iuser->framenr = ((trace_job->frame_num == 0) || (trace_job->frame_num > iuser->frames)) ?
+ init_frame :
+ trace_job->frame_num;
ImBuf *ibuf = BKE_image_acquire_ibuf(trace_job->image, iuser, &lock);
if (ibuf) {
/* Create frame. */
@@ -251,7 +257,7 @@ static void trace_start_job(void *customdata, short *stop, short *do_update, flo
trace_job->success = !trace_job->was_canceled;
*do_update = true;
- *stop = 0;
+ *stop = false;
}
static void trace_end_job(void *customdata)
@@ -300,9 +306,10 @@ static int gpencil_trace_image_exec(bContext *C, wmOperator *op)
/* Create a new grease pencil object or reuse selected. */
eGP_TargetObjectMode target = RNA_enum_get(op->ptr, "target");
- job->ob_gpencil = (target == GP_TARGET_OB_SELECTED) ? BKE_view_layer_non_active_selected_object(
- CTX_data_view_layer(C), job->v3d) :
- NULL;
+ job->ob_gpencil = (target == GP_TARGET_OB_SELECTED) ?
+ BKE_view_layer_non_active_selected_object(
+ scene, CTX_data_view_layer(C), job->v3d) :
+ NULL;
if (job->ob_gpencil != NULL) {
if (job->ob_gpencil->type != OB_GPENCIL) {
@@ -324,14 +331,15 @@ static int gpencil_trace_image_exec(bContext *C, wmOperator *op)
job->thickness = RNA_int_get(op->ptr, "thickness");
job->turnpolicy = RNA_enum_get(op->ptr, "turnpolicy");
job->mode = RNA_enum_get(op->ptr, "mode");
+ job->frame_num = RNA_int_get(op->ptr, "frame_number");
trace_initialize_job_data(job);
/* Back to active base. */
ED_object_base_activate(job->C, job->base_active);
- if (job->image->source == IMA_SRC_FILE) {
- short stop = 0, do_update = true;
+ if ((job->image->source == IMA_SRC_FILE) || (job->frame_num > 0)) {
+ bool stop = false, do_update = true;
float progress;
trace_start_job(job, &stop, &do_update, &progress);
trace_end_job(job);
@@ -364,6 +372,8 @@ static int gpencil_trace_image_invoke(bContext *C, wmOperator *op, const wmEvent
void GPENCIL_OT_trace_image(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
static const EnumPropertyItem turnpolicy_type[] = {
{POTRACE_TURNPOLICY_BLACK,
"BLACK",
@@ -475,4 +485,15 @@ void GPENCIL_OT_trace_image(wmOperatorType *ot)
true,
"Start At Current Frame",
"Trace Image starting in current image frame");
+ prop = RNA_def_int(
+ ot->srna,
+ "frame_number",
+ 0,
+ 0,
+ 9999,
+ "Trace Frame",
+ "Used to trace only one frame of the image sequence, set to zero to trace all",
+ 0,
+ 9999);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/gpencil/gpencil_trace_utils.c b/source/blender/editors/gpencil/gpencil_trace_utils.c
index 735759d40ec..aa9a2a653bb 100644
--- a/source/blender/editors/gpencil/gpencil_trace_utils.c
+++ b/source/blender/editors/gpencil/gpencil_trace_utils.c
@@ -119,7 +119,7 @@ static void pixel_at_index(const ImBuf *ibuf, const int32_t idx, float r_col[4])
copy_v4_v4(r_col, frgba);
}
else {
- unsigned char *cp = (unsigned char *)(ibuf->rect + idx);
+ uchar *cp = (uchar *)(ibuf->rect + idx);
r_col[0] = (float)cp[0] / 255.0f;
r_col[1] = (float)cp[1] / 255.0f;
r_col[2] = (float)cp[2] / 255.0f;
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index e47f16ac466..7d814b43196 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -518,7 +518,7 @@ bool ED_gpencil_stroke_can_use_direct(const ScrArea *area, const bGPDstroke *gps
/* filter stroke types by flags + spacetype */
if (gps->flag & GP_STROKE_3DSPACE) {
/* 3D strokes - only in 3D view */
- return (ELEM(area->spacetype, SPACE_VIEW3D, SPACE_PROPERTIES));
+ return ELEM(area->spacetype, SPACE_VIEW3D, SPACE_PROPERTIES);
}
if (gps->flag & GP_STROKE_2DIMAGE) {
/* Special "image" strokes - only in Image Editor */
@@ -612,17 +612,17 @@ void gpencil_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
}
}
-void gpencil_point_to_parent_space(const bGPDspoint *pt,
- const float diff_mat[4][4],
- bGPDspoint *r_pt)
+void gpencil_point_to_world_space(const bGPDspoint *pt,
+ const float diff_mat[4][4],
+ bGPDspoint *r_pt)
{
- float fpt[3];
-
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
- copy_v3_v3(&r_pt->x, fpt);
+ mul_v3_m4v3(&r_pt->x, diff_mat, &pt->x);
}
-void gpencil_apply_parent(Depsgraph *depsgraph, Object *obact, bGPDlayer *gpl, bGPDstroke *gps)
+void gpencil_world_to_object_space(Depsgraph *depsgraph,
+ Object *obact,
+ bGPDlayer *gpl,
+ bGPDstroke *gps)
{
bGPDspoint *pt;
int i;
@@ -630,34 +630,31 @@ void gpencil_apply_parent(Depsgraph *depsgraph, Object *obact, bGPDlayer *gpl, b
/* undo matrix */
float diff_mat[4][4];
float inverse_diff_mat[4][4];
- float fpt[3];
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
+ zero_axis_bias_m4(diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
for (i = 0; i < gps->totpoints; i++) {
pt = &gps->points[i];
- mul_v3_m4v3(fpt, inverse_diff_mat, &pt->x);
- copy_v3_v3(&pt->x, fpt);
+ mul_m4_v3(inverse_diff_mat, &pt->x);
}
}
-void gpencil_apply_parent_point(Depsgraph *depsgraph,
- Object *obact,
- bGPDlayer *gpl,
- bGPDspoint *pt)
+void gpencil_world_to_object_space_point(Depsgraph *depsgraph,
+ Object *obact,
+ bGPDlayer *gpl,
+ bGPDspoint *pt)
{
/* undo matrix */
float diff_mat[4][4];
float inverse_diff_mat[4][4];
- float fpt[3];
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
+ zero_axis_bias_m4(diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
- mul_v3_m4v3(fpt, inverse_diff_mat, &pt->x);
-
- copy_v3_v3(&pt->x, fpt);
+ mul_m4_v3(inverse_diff_mat, &pt->x);
}
void gpencil_point_to_xy(
@@ -770,7 +767,7 @@ void gpencil_point_3d_to_xy(const GP_SpaceConversion *gsc,
float xyval[2];
/* sanity checks */
- BLI_assert((gsc->area->spacetype == SPACE_VIEW3D));
+ BLI_assert(gsc->area->spacetype == SPACE_VIEW3D);
if (flag & GP_STROKE_3DSPACE) {
if (ED_view3d_project_float_global(region, pt, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
@@ -857,7 +854,7 @@ void gpencil_stroke_convertcoords_tpoint(Scene *scene,
int mval_i[2];
round_v2i_v2fl(mval_i, point2D->m_xy);
- if ((depth != NULL) && (ED_view3d_autodist_simple(region, mval_i, r_out, 0, depth))) {
+ if ((depth != NULL) && ED_view3d_autodist_simple(region, mval_i, r_out, 0, depth)) {
/* projecting onto 3D-Geometry
* - nothing more needs to be done here, since view_autodist_simple() has already done it
*/
@@ -903,7 +900,7 @@ void ED_gpencil_drawing_reference_get(const Scene *scene,
}
else {
/* use object location */
- copy_v3_v3(r_vec, ob->obmat[3]);
+ copy_v3_v3(r_vec, ob->object_to_world[3]);
/* Apply layer offset. */
bGPdata *gpd = ob->data;
bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
@@ -935,6 +932,7 @@ void ED_gpencil_project_stroke_to_view(bContext *C, bGPDlayer *gpl, bGPDstroke *
gpencil_point_conversion_init(C, &gsc);
BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
+ zero_axis_bias_m4(diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
/* Adjust each point */
@@ -942,7 +940,7 @@ void ED_gpencil_project_stroke_to_view(bContext *C, bGPDlayer *gpl, bGPDstroke *
float xy[2];
bGPDspoint pt2;
- gpencil_point_to_parent_space(pt, diff_mat, &pt2);
+ gpencil_point_to_world_space(pt, diff_mat, &pt2);
gpencil_point_to_xy_fl(&gsc, gps, &pt2, &xy[0], &xy[1]);
/* Planar - All on same plane parallel to the viewplane */
@@ -986,7 +984,7 @@ void ED_gpencil_project_stroke_to_plane(const Scene *scene,
/* if object, apply object rotation */
if (ob && (ob->type == OB_GPENCIL)) {
float mat[4][4];
- copy_m4_m4(mat, ob->obmat);
+ copy_m4_m4(mat, ob->object_to_world);
/* move origin to cursor */
if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
@@ -1038,7 +1036,8 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
bGPDframe *gpf,
bGPDstroke *gps,
const eGP_ReprojectModes mode,
- const bool keep_original)
+ const bool keep_original,
+ const float offset)
{
ToolSettings *ts = gsc->scene->toolsettings;
ARegion *region = gsc->region;
@@ -1050,6 +1049,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
float diff_mat[4][4], inverse_diff_mat[4][4];
BKE_gpencil_layer_transform_matrix_get(depsgraph, gsc->ob, gpl, diff_mat);
+ zero_axis_bias_m4(diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
float origin[3];
@@ -1087,7 +1087,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
* artifacts in the final points. */
bGPDspoint pt2;
- gpencil_point_to_parent_space(pt, diff_mat, &pt2);
+ gpencil_point_to_world_space(pt, diff_mat, &pt2);
gpencil_point_to_xy_fl(gsc, gps_active, &pt2, &xy[0], &xy[1]);
/* Project stroke in one axis */
@@ -1121,7 +1121,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
copy_v3_v3(&pt->x, &pt2.x);
/* apply parent again */
- gpencil_apply_parent_point(depsgraph, gsc->ob, gpl, pt);
+ gpencil_world_to_object_space_point(depsgraph, gsc->ob, gpl, pt);
}
/* Project screen-space back to 3D space (from current perspective)
* so that all points have been treated the same way. */
@@ -1156,7 +1156,13 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
&depth,
&location[0],
&normal[0])) {
- copy_v3_v3(&pt->x, location);
+ /* Apply offset over surface. */
+ float normal_vector[3];
+ sub_v3_v3v3(normal_vector, ray_start, location);
+ normalize_v3(normal_vector);
+ mul_v3_fl(normal_vector, offset);
+
+ add_v3_v3v3(&pt->x, location, normal_vector);
}
else {
/* Default to planar */
@@ -1200,7 +1206,7 @@ void ED_gpencil_project_point_to_plane(const Scene *scene,
/* if object, apply object rotation */
if (ob && (ob->type == OB_GPENCIL)) {
float mat[4][4];
- copy_m4_m4(mat, ob->obmat);
+ copy_m4_m4(mat, ob->object_to_world);
if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
if (gpl != NULL) {
add_v3_v3(mat[3], gpl->location);
@@ -1227,7 +1233,7 @@ void ED_gpencil_project_point_to_plane(const Scene *scene,
/* move origin to object */
if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
- copy_v3_v3(mat[3], ob->obmat[3]);
+ copy_v3_v3(mat[3], ob->object_to_world[3]);
}
mul_mat3_m4_v3(mat, plane_normal);
@@ -1359,16 +1365,16 @@ void ED_gpencil_reset_layers_parent(Depsgraph *depsgraph, Object *obact, bGPdata
if (gpl->parent != NULL) {
/* calculate new matrix */
if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
- invert_m4_m4(cur_mat, gpl->parent->obmat);
- copy_v3_v3(gpl_loc, obact->obmat[3]);
+ invert_m4_m4(cur_mat, gpl->parent->object_to_world);
+ copy_v3_v3(gpl_loc, obact->object_to_world[3]);
}
else if (gpl->partype == PARBONE) {
bPoseChannel *pchan = BKE_pose_channel_find_name(gpl->parent->pose, gpl->parsubstr);
if (pchan) {
float tmp_mat[4][4];
- mul_m4_m4m4(tmp_mat, gpl->parent->obmat, pchan->pose_mat);
+ mul_m4_m4m4(tmp_mat, gpl->parent->object_to_world, pchan->pose_mat);
invert_m4_m4(cur_mat, tmp_mat);
- copy_v3_v3(gpl_loc, obact->obmat[3]);
+ copy_v3_v3(gpl_loc, obact->object_to_world[3]);
}
}
@@ -1656,11 +1662,11 @@ static bool gpencil_check_cursor_region(bContext *C, const int mval_i[2])
ScrArea *area = CTX_wm_area(C);
Object *ob = CTX_data_active_object(C);
- if ((ob == NULL) || (!ELEM(ob->mode,
- OB_MODE_PAINT_GPENCIL,
- OB_MODE_SCULPT_GPENCIL,
- OB_MODE_WEIGHT_GPENCIL,
- OB_MODE_VERTEX_GPENCIL))) {
+ if ((ob == NULL) || !ELEM(ob->mode,
+ OB_MODE_PAINT_GPENCIL,
+ OB_MODE_SCULPT_GPENCIL,
+ OB_MODE_WEIGHT_GPENCIL,
+ OB_MODE_VERTEX_GPENCIL)) {
return false;
}
@@ -1749,7 +1755,7 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat
const int mval_i[2] = {x, y};
/* Check if cursor is in drawing region and has valid data-block. */
- if ((!gpencil_check_cursor_region(C, mval_i)) || (gpd == NULL)) {
+ if (!gpencil_check_cursor_region(C, mval_i) || (gpd == NULL)) {
return;
}
@@ -1787,7 +1793,7 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat
* is too disruptive and the size of cursor does not change with zoom factor.
* The decision was to use a fix size, instead of brush->thickness value.
*/
- if ((gp_style) && (GPENCIL_PAINT_MODE(gpd)) &&
+ if ((gp_style) && GPENCIL_PAINT_MODE(gpd) &&
((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) &&
((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0) &&
(brush->gpencil_tool == GPAINT_TOOL_DRAW)) {
@@ -1872,7 +1878,7 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat
/* Inner Ring: Color from UI panel */
immUniformColor4f(color[0], color[1], color[2], 0.8f);
- if ((gp_style) && (GPENCIL_PAINT_MODE(gpd)) &&
+ if ((gp_style) && GPENCIL_PAINT_MODE(gpd) &&
((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) &&
((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0) &&
(brush->gpencil_tool == GPAINT_TOOL_DRAW)) {
@@ -2745,7 +2751,7 @@ void ED_gpencil_init_random_settings(Brush *brush,
const int mval[2],
GpRandomSettings *random_settings)
{
- int seed = ((uint)(ceil(PIL_check_seconds_timer())) + 1) % 128;
+ int seed = ((uint)ceil(PIL_check_seconds_timer()) + 1) % 128;
/* Use mouse position to get randomness. */
int ix = mval[0] * seed;
int iy = mval[1] * seed;
@@ -2791,7 +2797,7 @@ static void gpencil_sbuffer_vertex_color_random(
{
BrushGpencilSettings *brush_settings = brush->gpencil_settings;
if (brush_settings->flag & GP_BRUSH_GROUP_RANDOM) {
- int seed = ((uint)(ceil(PIL_check_seconds_timer())) + 1) % 128;
+ int seed = ((uint)ceil(PIL_check_seconds_timer()) + 1) % 128;
int ix = (int)(tpt->m_xy[0] * seed);
int iy = (int)(tpt->m_xy[1] * seed);
@@ -2941,7 +2947,7 @@ void ED_gpencil_projected_2d_bound_box(const GP_SpaceConversion *gsc,
for (int i = 0; i < 8; i++) {
bGPDspoint pt_dummy, pt_dummy_ps;
copy_v3_v3(&pt_dummy.x, bb.vec[i]);
- gpencil_point_to_parent_space(&pt_dummy, diff_mat, &pt_dummy_ps);
+ gpencil_point_to_world_space(&pt_dummy, diff_mat, &pt_dummy_ps);
gpencil_point_to_xy_fl(gsc, gps, &pt_dummy_ps, &bounds[i][0], &bounds[i][1]);
}
@@ -3005,7 +3011,7 @@ bool ED_gpencil_stroke_point_is_inside(const bGPDstroke *gps,
int i;
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
bGPDspoint pt2;
- gpencil_point_to_parent_space(pt, diff_mat, &pt2);
+ gpencil_point_to_world_space(pt, diff_mat, &pt2);
gpencil_point_to_xy(gsc, gps, &pt2, &mcoords[i][0], &mcoords[i][1]);
}
@@ -3014,7 +3020,7 @@ bool ED_gpencil_stroke_point_is_inside(const bGPDstroke *gps,
BLI_lasso_boundbox(&rect, mcoords, len);
/* Test if point inside stroke. */
- hit = ((!ELEM(V2D_IS_CLIPPED, mval[0], mval[1])) && BLI_rcti_isect_pt(&rect, mval[0], mval[1]) &&
+ hit = (!ELEM(V2D_IS_CLIPPED, mval[0], mval[1]) && BLI_rcti_isect_pt(&rect, mval[0], mval[1]) &&
BLI_lasso_is_point_inside(mcoords, len, mval[0], mval[1], INT_MAX));
/* Free memory. */
@@ -3031,9 +3037,9 @@ void ED_gpencil_stroke_extremes_to2d(const GP_SpaceConversion *gsc,
{
bGPDspoint pt_dummy_ps;
- gpencil_point_to_parent_space(&gps->points[0], diff_mat, &pt_dummy_ps);
+ gpencil_point_to_world_space(&gps->points[0], diff_mat, &pt_dummy_ps);
gpencil_point_to_xy_fl(gsc, gps, &pt_dummy_ps, &r_ctrl1[0], &r_ctrl1[1]);
- gpencil_point_to_parent_space(&gps->points[gps->totpoints - 1], diff_mat, &pt_dummy_ps);
+ gpencil_point_to_world_space(&gps->points[gps->totpoints - 1], diff_mat, &pt_dummy_ps);
gpencil_point_to_xy_fl(gsc, gps, &pt_dummy_ps, &r_ctrl2[0], &r_ctrl2[1]);
}
@@ -3061,11 +3067,11 @@ bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C,
float pt2d_start[2], pt2d_end[2];
bGPDspoint *pt = &gps->points[0];
- gpencil_point_to_parent_space(pt, diff_mat, &pt_parent);
+ gpencil_point_to_world_space(pt, diff_mat, &pt_parent);
gpencil_point_to_xy_fl(gsc, gps, &pt_parent, &pt2d_start[0], &pt2d_start[1]);
pt = &gps->points[gps->totpoints - 1];
- gpencil_point_to_parent_space(pt, diff_mat, &pt_parent);
+ gpencil_point_to_world_space(pt, diff_mat, &pt_parent);
gpencil_point_to_xy_fl(gsc, gps, &pt_parent, &pt2d_end[0], &pt2d_end[1]);
/* Loop all strokes of the active frame. */
@@ -3082,8 +3088,8 @@ bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C,
}
/* Check if one of the ends is inside target stroke bounding box. */
- if ((!ED_gpencil_stroke_check_collision(gsc, gps_target, pt2d_start, radius, diff_mat)) &&
- (!ED_gpencil_stroke_check_collision(gsc, gps_target, pt2d_end, radius, diff_mat))) {
+ if (!ED_gpencil_stroke_check_collision(gsc, gps_target, pt2d_start, radius, diff_mat) &&
+ !ED_gpencil_stroke_check_collision(gsc, gps_target, pt2d_end, radius, diff_mat)) {
continue;
}
/* Check the distance of the ends with the ends of target stroke to avoid middle contact.
@@ -3091,11 +3097,11 @@ bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C,
float pt2d_target_start[2], pt2d_target_end[2];
pt = &gps_target->points[0];
- gpencil_point_to_parent_space(pt, diff_mat, &pt_parent);
+ gpencil_point_to_world_space(pt, diff_mat, &pt_parent);
gpencil_point_to_xy_fl(gsc, gps, &pt_parent, &pt2d_target_start[0], &pt2d_target_start[1]);
pt = &gps_target->points[gps_target->totpoints - 1];
- gpencil_point_to_parent_space(pt, diff_mat, &pt_parent);
+ gpencil_point_to_world_space(pt, diff_mat, &pt_parent);
gpencil_point_to_xy_fl(gsc, gps, &pt_parent, &pt2d_target_end[0], &pt2d_target_end[1]);
/* If the distance to the original stroke extremes is too big, the stroke must not be joined.
@@ -3119,7 +3125,7 @@ bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C,
for (i = 0, pt = gps_target->points; i < gps_target->totpoints; i++, pt++) {
/* Convert point to 2D. */
float pt2d[2];
- gpencil_point_to_parent_space(pt, diff_mat, &pt_parent);
+ gpencil_point_to_world_space(pt, diff_mat, &pt_parent);
gpencil_point_to_xy_fl(gsc, gps, &pt_parent, &pt2d[0], &pt2d[1]);
/* Check with Start point. */
diff --git a/source/blender/editors/gpencil/gpencil_uv.c b/source/blender/editors/gpencil/gpencil_uv.c
index 51cb08cf592..0144ffa07c7 100644
--- a/source/blender/editors/gpencil/gpencil_uv.c
+++ b/source/blender/editors/gpencil/gpencil_uv.c
@@ -138,7 +138,7 @@ static bool gpencil_uv_transform_init(bContext *C, wmOperator *op)
opdata->array_loc = NULL;
opdata->array_rot = NULL;
opdata->array_scale = NULL;
- opdata->ob_scale = mat4_to_scale(opdata->ob->obmat);
+ opdata->ob_scale = mat4_to_scale(opdata->ob->object_to_world);
opdata->vinit_rotation[0] = 1.0f;
opdata->vinit_rotation[1] = 0.0f;
@@ -158,7 +158,7 @@ static bool gpencil_uv_transform_init(bContext *C, wmOperator *op)
float r_center[3];
gpencil_stroke_center(gps, r_center);
/* Add object location. */
- add_v3_v3(r_center, opdata->ob->obmat[3]);
+ add_v3_v3(r_center, opdata->ob->object_to_world[3]);
add_v3_v3(center, r_center);
i++;
}
diff --git a/source/blender/editors/gpencil/gpencil_vertex_ops.c b/source/blender/editors/gpencil/gpencil_vertex_ops.c
index 865c4e360b5..41f939813e4 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_ops.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_ops.c
@@ -131,7 +131,7 @@ static int gpencil_vertexpaint_brightness_contrast_exec(bContext *C, wmOperator
/*
* The algorithm is by Werner D. Streidt
* (http://visca.com/ffactory/archives/5-99/msg00021.html)
- * Extracted of OpenCV demhist.c
+ * Extracted of OpenCV `demhist.c`.
*/
if (contrast > 0) {
gain = 1.0f - delta * 2.0f;
diff --git a/source/blender/editors/gpencil/gpencil_vertex_paint.c b/source/blender/editors/gpencil/gpencil_vertex_paint.c
index c221d8e25e4..ca0729ecb94 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_paint.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_paint.c
@@ -846,12 +846,12 @@ static bool gpencil_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
if (gps->totpoints == 1) {
bGPDspoint pt_temp;
pt = &gps->points[0];
- gpencil_point_to_parent_space(gps->points, diff_mat, &pt_temp);
+ gpencil_point_to_world_space(gps->points, diff_mat, &pt_temp);
gpencil_point_to_xy(gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
/* Do bound-box check first. */
- if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
+ if (!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1]) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
/* only check if point is inside */
int mval_i[2];
round_v2i_v2fl(mval_i, gso->mval);
@@ -884,15 +884,15 @@ static bool gpencil_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
}
bGPDspoint npt;
- gpencil_point_to_parent_space(pt1, diff_mat, &npt);
+ gpencil_point_to_world_space(pt1, diff_mat, &npt);
gpencil_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]);
- gpencil_point_to_parent_space(pt2, diff_mat, &npt);
+ gpencil_point_to_world_space(pt2, diff_mat, &npt);
gpencil_point_to_xy(gsc, gps, &npt, &pc2[0], &pc2[1]);
/* Check that point segment of the bound-box of the selection stroke. */
- if (((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) ||
- ((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) {
+ if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1]) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) ||
+ (!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1]) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) {
/* Check if point segment of stroke had anything to do with
* brush region (either within stroke painted, or on its lines)
* - this assumes that line-width is irrelevant.
@@ -957,7 +957,7 @@ static bool gpencil_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
}
/* If nothing hit, check if the mouse is inside any filled stroke. */
- if ((!hit) && (ELEM(tool, GPAINT_TOOL_TINT, GPVERTEX_TOOL_DRAW))) {
+ if ((!hit) && ELEM(tool, GPAINT_TOOL_TINT, GPVERTEX_TOOL_DRAW)) {
MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(gso->object,
gps_active->mat_nr + 1);
if (gp_style->flag & GP_MATERIAL_FILL_SHOW) {
@@ -1113,7 +1113,7 @@ static bool gpencil_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVert
/* Find visible strokes, and perform operations on those if hit */
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
/* If locked or no active frame, don't do anything. */
- if ((!BKE_gpencil_layer_is_editable(gpl)) || (gpl->actframe == NULL)) {
+ if (!BKE_gpencil_layer_is_editable(gpl) || (gpl->actframe == NULL)) {
continue;
}
diff --git a/source/blender/editors/gpencil/gpencil_weight_paint.c b/source/blender/editors/gpencil/gpencil_weight_paint.c
index 22fbf0021fc..f73c6f8c658 100644
--- a/source/blender/editors/gpencil/gpencil_weight_paint.c
+++ b/source/blender/editors/gpencil/gpencil_weight_paint.c
@@ -235,7 +235,7 @@ static bool brush_draw_apply(tGP_BrushWeightpaintData *gso,
if (gso->vrgroup == -1) {
if (gso->object) {
Object *ob_armature = BKE_modifiers_is_deformed_by_armature(gso->object);
- if ((ob_armature != NULL)) {
+ if (ob_armature != NULL) {
Bone *actbone = ((bArmature *)ob_armature->data)->act_bone;
if (actbone != NULL) {
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_armature->pose, actbone->name);
@@ -413,12 +413,12 @@ static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
if (gps->totpoints == 1) {
bGPDspoint pt_temp;
pt = &gps->points[0];
- gpencil_point_to_parent_space(gps->points, diff_mat, &pt_temp);
+ gpencil_point_to_world_space(gps->points, diff_mat, &pt_temp);
gpencil_point_to_xy(gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
/* Do bound-box check first. */
- if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
+ if (!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1]) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
/* only check if point is inside */
int mval_i[2];
round_v2i_v2fl(mval_i, gso->mval);
@@ -440,15 +440,15 @@ static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
pt2 = gps->points + i + 1;
bGPDspoint npt;
- gpencil_point_to_parent_space(pt1, diff_mat, &npt);
+ gpencil_point_to_world_space(pt1, diff_mat, &npt);
gpencil_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]);
- gpencil_point_to_parent_space(pt2, diff_mat, &npt);
+ gpencil_point_to_world_space(pt2, diff_mat, &npt);
gpencil_point_to_xy(gsc, gps, &npt, &pc2[0], &pc2[1]);
/* Check that point segment of the bound-box of the selection stroke */
- if (((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) ||
- ((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) {
+ if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1]) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) ||
+ (!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1]) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) {
/* Check if point segment of stroke had anything to do with
* brush region (either within stroke painted, or on its lines)
* - this assumes that line-width is irrelevant.
@@ -579,7 +579,7 @@ static bool gpencil_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeig
/* Find visible strokes, and perform operations on those if hit */
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
/* If locked or no active frame, don't do anything. */
- if ((!BKE_gpencil_layer_is_editable(gpl)) || (gpl->actframe == NULL)) {
+ if (!BKE_gpencil_layer_is_editable(gpl) || (gpl->actframe == NULL)) {
continue;
}
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index ee87de5774a..8fe2d0ae60f 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -101,16 +101,16 @@ typedef struct bAnimContext {
/* Main Data container types */
typedef enum eAnimCont_Types {
ANIMCONT_NONE = 0, /* invalid or no data */
- ANIMCONT_ACTION = 1, /* action (bAction) */
- ANIMCONT_SHAPEKEY = 2, /* shapekey (Key) */
+ ANIMCONT_ACTION = 1, /* action (#bAction) */
+ ANIMCONT_SHAPEKEY = 2, /* shape-key (#Key) */
ANIMCONT_GPENCIL = 3, /* grease pencil (screen) */
- ANIMCONT_DOPESHEET = 4, /* dopesheet (bDopesheet) */
- ANIMCONT_FCURVES = 5, /* animation F-Curves (bDopesheet) */
- ANIMCONT_DRIVERS = 6, /* drivers (bDopesheet) */
- ANIMCONT_NLA = 7, /* nla (bDopesheet) */
- ANIMCONT_CHANNEL = 8, /* animation channel (bAnimListElem) */
- ANIMCONT_MASK = 9, /* mask dopesheet */
- ANIMCONT_TIMELINE = 10, /* "timeline" editor (bDopeSheet) */
+ ANIMCONT_DOPESHEET = 4, /* dope-sheet (#bDopesheet) */
+ ANIMCONT_FCURVES = 5, /* animation F-Curves (#bDopesheet) */
+ ANIMCONT_DRIVERS = 6, /* drivers (#bDopesheet) */
+ ANIMCONT_NLA = 7, /* NLA (#bDopesheet) */
+ ANIMCONT_CHANNEL = 8, /* animation channel (#bAnimListElem) */
+ ANIMCONT_MASK = 9, /* mask dope-sheet */
+ ANIMCONT_TIMELINE = 10, /* "timeline" editor (#bDopeSheet) */
} eAnimCont_Types;
/** \} */
@@ -519,6 +519,11 @@ void ANIM_animdata_update(bAnimContext *ac, ListBase *anim_data);
void ANIM_animdata_freelist(ListBase *anim_data);
+/**
+ * Check if the given animation container can contain grease pencil layer keyframes.
+ */
+bool ANIM_animdata_can_have_greasepencil(const eAnimCont_Types type);
+
/* ************************************************ */
/* ANIMATION CHANNELS LIST */
/* anim_channels_*.c */
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index d969277fef5..8e7f728a3e7 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -312,7 +312,8 @@ void ED_pose_recalculate_paths(struct bContext *C,
/**
* \return True when pick finds an element or the selection changed.
*/
-bool ED_armature_pose_select_pick_bone(struct ViewLayer *view_layer,
+bool ED_armature_pose_select_pick_bone(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct View3D *v3d,
struct Object *ob,
struct Bone *bone,
@@ -323,7 +324,8 @@ bool ED_armature_pose_select_pick_bone(struct ViewLayer *view_layer,
*
* \return True when pick finds an element or the selection changed.
*/
-bool ED_armature_pose_select_pick_with_buffer(struct ViewLayer *view_layer,
+bool ED_armature_pose_select_pick_with_buffer(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct View3D *v3d,
struct Base *base,
const struct GPUSelectResult *buffer,
@@ -338,7 +340,8 @@ bool ED_armature_pose_select_pick_with_buffer(struct ViewLayer *view_layer,
* It can't be set to the active object because we need
* to keep this set to the weight paint object.
*/
-void ED_armature_pose_select_in_wpaint_mode(struct ViewLayer *view_layer,
+void ED_armature_pose_select_in_wpaint_mode(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct Base *base_select);
bool ED_pose_deselect_all_multi_ex(struct Base **bases,
uint bases_len,
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index bf021d68cec..45e61592424 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -475,7 +475,8 @@ void ED_gpencil_stroke_reproject(struct Depsgraph *depsgraph,
struct bGPDframe *gpf,
struct bGPDstroke *gps,
eGP_ReprojectModes mode,
- bool keep_original);
+ bool keep_original,
+ const float offset);
/**
* Turn brush cursor in on/off.
diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h
index 91ae8286531..20e62ac8626 100644
--- a/source/blender/editors/include/ED_image.h
+++ b/source/blender/editors/include/ED_image.h
@@ -32,14 +32,15 @@ struct wmWindowManager;
float ED_space_image_zoom_level(const struct View2D *v2d, int grid_dimension);
void ED_space_image_grid_steps(struct SpaceImage *sima,
- float grid_steps[SI_GRID_STEPS_LEN],
+ float grid_steps_x[SI_GRID_STEPS_LEN],
+ float grid_steps_y[SI_GRID_STEPS_LEN],
int grid_dimension);
/**
* Calculate the increment snapping value for UV/image editor based on the zoom factor
* The code in here (except the offset part) is used in `grid_frag.glsl` (see `grid_res`) for
* drawing the grid overlay for the UV/Image editor.
*/
-float ED_space_image_increment_snap_value(int grid_dimesnions,
+float ED_space_image_increment_snap_value(int grid_dimensions,
const float grid_steps[SI_GRID_STEPS_LEN],
float zoom_factor);
@@ -50,6 +51,7 @@ void ED_space_image_set(struct Main *bmain,
struct SpaceImage *sima,
struct Image *ima,
bool automatic);
+void ED_space_image_sync(struct Main *bmain, Image *image, bool ignore_render_viewer);
void ED_space_image_auto_set(const struct bContext *C, struct SpaceImage *sima);
struct Mask *ED_space_image_get_mask(const struct SpaceImage *sima);
void ED_space_image_set_mask(struct bContext *C, struct SpaceImage *sima, struct Mask *mask);
diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h
index 1d63e01c84b..e5bcdcdd282 100644
--- a/source/blender/editors/include/ED_keyframes_edit.h
+++ b/source/blender/editors/include/ED_keyframes_edit.h
@@ -235,7 +235,7 @@ typedef enum eKeyPasteError {
KEYFRAME_PASTE_OK,
/* Nothing was copied */
KEYFRAME_PASTE_NOTHING_TO_PASTE,
- /* No F-curves was selected to paste into*/
+ /* No F-curves was selected to paste into. */
KEYFRAME_PASTE_NOWHERE_TO_PASTE
} eKeyPasteError;
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 26743a2bd08..52527f6c1b8 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -142,12 +142,15 @@ struct UvElementMap *BM_uv_element_map_create(struct BMesh *bm,
bool use_seams,
bool do_islands);
void BM_uv_element_map_free(struct UvElementMap *element_map);
-struct UvElement *BM_uv_element_get(const struct UvElementMap *map,
+struct UvElement *BM_uv_element_get(const struct UvElementMap *element_map,
const struct BMFace *efa,
const struct BMLoop *l);
-struct UvElement *BM_uv_element_get_head(struct UvElementMap *map, struct UvElement *child);
+struct UvElement *BM_uv_element_get_head(struct UvElementMap *element_map,
+ struct UvElement *child);
+int BM_uv_element_get_unique_index(struct UvElementMap *element_map, struct UvElement *child);
struct UvElement **BM_uv_element_map_ensure_head_table(struct UvElementMap *element_map);
+int *BM_uv_element_map_ensure_unique_index(struct UvElementMap *element_map);
/**
* Can we edit UV's for this mesh?
@@ -192,12 +195,12 @@ void EDBM_automerge_and_split(struct Object *obedit,
char hflag,
float dist);
-/* editmesh_undo.c */
+/* editmesh_undo.cc */
/** Export for ED_undo_sys. */
void ED_mesh_undosys_type(struct UndoType *ut);
-/* editmesh_select.c */
+/* editmesh_select.cc */
void EDBM_select_mirrored(struct BMEditMesh *em,
const struct Mesh *me,
diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h
index c30b8c5ec6a..24e14fdce72 100644
--- a/source/blender/editors/include/ED_node.h
+++ b/source/blender/editors/include/ED_node.h
@@ -87,17 +87,6 @@ void ED_node_tag_update_id(struct ID *id);
float ED_node_grid_size(void);
-/* node_relationships.cc */
-
-/**
- * Test == 0, clear all intersect flags.
- */
-void ED_node_link_intersect_test(struct ScrArea *area, int test);
-/**
- * Assumes link with #NODE_LINKFLAG_HILITE set.
- */
-void ED_node_link_insert(struct Main *bmain, struct ScrArea *area);
-
/* node_edit.cc */
void ED_node_set_tree_type(struct SpaceNode *snode, struct bNodeTreeType *typeinfo);
@@ -186,3 +175,20 @@ bool ED_space_node_color_sample(struct Main *bmain,
#ifdef __cplusplus
}
#endif
+
+#ifdef __cplusplus
+
+/* node_relationships.cc */
+
+namespace blender::ed::space_node {
+
+void node_insert_on_link_flags_set(SpaceNode &snode, const ARegion &region);
+/**
+ * Assumes link with #NODE_LINKFLAG_HILITE set.
+ */
+void node_insert_on_link_flags(Main &bmain, SpaceNode &snode);
+void node_insert_on_link_flags_clear(bNodeTree &node_tree);
+
+} // namespace blender::ed::space_node
+
+#endif \ No newline at end of file
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 39c7ad3556c..acb0e53aa55 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -112,6 +112,7 @@ struct XFormObjectSkipChild_Container;
struct XFormObjectSkipChild_Container *ED_object_xform_skip_child_container_create(void);
void ED_object_xform_skip_child_container_item_ensure_from_array(
struct XFormObjectSkipChild_Container *xcs,
+ const struct Scene *scene,
struct ViewLayer *view_layer,
struct Object **objects,
uint objects_len);
@@ -213,16 +214,20 @@ void ED_object_base_free_and_unlink(struct Main *bmain, struct Scene *scene, str
void ED_object_base_free_and_unlink_no_indirect_check(struct Main *bmain,
struct Scene *scene,
struct Object *ob);
-bool ED_object_base_deselect_all_ex(struct ViewLayer *view_layer,
+bool ED_object_base_deselect_all_ex(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct View3D *v3d,
int action,
bool *r_any_visible);
-bool ED_object_base_deselect_all(struct ViewLayer *view_layer, struct View3D *v3d, int action);
+bool ED_object_base_deselect_all(const struct Scene *scene,
+ struct ViewLayer *view_layer,
+ struct View3D *v3d,
+ int action);
/**
* Single object duplicate, if `dupflag == 0`, fully linked, else it uses the flags given.
* Leaves selection of base/object unaltered.
- * \note don't call this within a loop since clear_* funcs loop over the entire database.
+ * \note don't call this within a loop since clear_* functions loop over the entire database.
* \note caller must do `DAG_relations_tag_update(bmain);`
* this is not done automatic since we may duplicate many objects in a batch.
*/
@@ -539,6 +544,7 @@ bool ED_object_modifier_move_to_index(struct ReportList *reports,
bool ED_object_modifier_convert_psys_to_mesh(struct ReportList *reports,
struct Main *bmain,
struct Depsgraph *depsgraph,
+ struct Scene *scene,
struct ViewLayer *view_layer,
struct Object *ob,
struct ModifierData *md);
@@ -662,7 +668,9 @@ void ED_object_check_force_modifiers(struct Main *bmain,
* If id is not already an Object, try to find an object that uses it as data.
* Prefers active, then selected, then visible/selectable.
*/
-struct Base *ED_object_find_first_by_data_id(struct ViewLayer *view_layer, struct ID *id);
+struct Base *ED_object_find_first_by_data_id(const struct Scene *scene,
+ struct ViewLayer *view_layer,
+ struct ID *id);
/**
* Select and make the target object active in the view layer.
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index eeed1c9b286..e1fd53ccdee 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -353,8 +353,8 @@ struct ScrArea *ED_screen_state_toggle(struct bContext *C,
struct ScrArea *area,
short state);
/**
- * Wrapper to open a temporary space either as fullscreen space, or as separate window, as defined
- * by \a display_type.
+ * Wrapper to open a temporary space either as full-screen space, or as separate window,
+ * as defined by \a display_type.
*
* \param title: Title to set for the window, if a window is spawned.
* \param x, y: Position of the window, if a window is spawned.
@@ -469,6 +469,8 @@ bool ED_workspace_layout_cycle(struct WorkSpace *workspace, short direction, str
void ED_workspace_status_text(struct bContext *C, const char *str);
+void ED_workspace_do_listen(struct bContext *C, const struct wmNotifier *note);
+
/* anim */
/**
* Results in fully updated anim system.
diff --git a/source/blender/editors/include/ED_screen_types.h b/source/blender/editors/include/ED_screen_types.h
index 21bb412d072..bf64be9f7a7 100644
--- a/source/blender/editors/include/ED_screen_types.h
+++ b/source/blender/editors/include/ED_screen_types.h
@@ -112,7 +112,7 @@ enum {
*/
AZONE_REGION,
/**
- * Used when in editor fullscreen draw a corner to return to normal mode.
+ * Used when in editor full-screen draw a corner to return to normal mode.
*/
AZONE_FULLSCREEN,
/**
diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h
index 1e220d33ff4..1c1ce41ef7a 100644
--- a/source/blender/editors/include/ED_sculpt.h
+++ b/source/blender/editors/include/ED_sculpt.h
@@ -34,7 +34,10 @@ bool ED_sculpt_mask_box_select(struct bContext *C,
/* sculpt_transform.c */
void ED_sculpt_update_modal_transform(struct bContext *C, struct Object *ob);
-void ED_sculpt_init_transform(struct bContext *C, struct Object *ob, const char *undo_name);
+void ED_sculpt_init_transform(struct bContext *C,
+ struct Object *ob,
+ const int mval[2],
+ const char *undo_name);
void ED_sculpt_end_transform(struct bContext *C, struct Object *ob);
/* sculpt_undo.c */
diff --git a/source/blender/editors/include/ED_space_api.h b/source/blender/editors/include/ED_space_api.h
index c1968ab49c1..49c7d1e954a 100644
--- a/source/blender/editors/include/ED_space_api.h
+++ b/source/blender/editors/include/ED_space_api.h
@@ -51,7 +51,7 @@ void ED_spacetype_spreadsheet(void);
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Spacetype Static Data
+/** \name Space-type Static Data
* Calls for instancing and freeing space-type static data called in #WM_init_exit
* \{ */
diff --git a/source/blender/editors/include/ED_spreadsheet.h b/source/blender/editors/include/ED_spreadsheet.h
index da13e6d3636..736da367a44 100644
--- a/source/blender/editors/include/ED_spreadsheet.h
+++ b/source/blender/editors/include/ED_spreadsheet.h
@@ -7,7 +7,6 @@ struct Main;
struct Object;
struct SpaceNode;
struct SpaceSpreadsheet;
-struct SpreadsheetContext;
struct bContext;
struct bNode;
@@ -15,29 +14,8 @@ struct bNode;
extern "C" {
#endif
-struct SpreadsheetContext *ED_spreadsheet_context_new(int type);
-void ED_spreadsheet_context_free(struct SpreadsheetContext *context);
-void ED_spreadsheet_context_path_clear(struct SpaceSpreadsheet *sspreadsheet);
-bool ED_spreadsheet_context_path_update_tag(struct SpaceSpreadsheet *sspreadsheet);
-uint64_t ED_spreadsheet_context_path_hash(const struct SpaceSpreadsheet *sspreadsheet);
-
struct ID *ED_spreadsheet_get_current_id(const struct SpaceSpreadsheet *sspreadsheet);
-void ED_spreadsheet_context_path_set_geometry_node(struct SpaceSpreadsheet *sspreadsheet,
- struct SpaceNode *snode,
- struct bNode *node);
-void ED_spreadsheet_context_paths_set_geometry_node(struct Main *bmain,
- struct SpaceNode *snode,
- struct bNode *node);
-void ED_spreadsheet_context_path_set_evaluated_object(struct SpaceSpreadsheet *sspreadsheet,
- struct Object *object);
-
-void ED_spreadsheet_context_path_guess(const struct bContext *C,
- struct SpaceSpreadsheet *sspreadsheet);
-bool ED_spreadsheet_context_path_is_active(const struct bContext *C,
- struct SpaceSpreadsheet *sspreadsheet);
-bool ED_spreadsheet_context_path_exists(struct Main *bmain, struct SpaceSpreadsheet *sspreadsheet);
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index 82cc518f029..d7fb108809f 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -94,7 +94,8 @@ bool BIF_createTransformOrientation(struct bContext *C,
bool overwrite);
void BIF_selectTransformOrientation(struct bContext *C, struct TransformOrientation *target);
-void ED_getTransformOrientationMatrix(struct ViewLayer *view_layer,
+void ED_getTransformOrientationMatrix(const struct Scene *scene,
+ struct ViewLayer *view_layer,
const struct View3D *v3d,
struct Object *ob,
struct Object *obedit,
diff --git a/source/blender/editors/include/ED_undo.h b/source/blender/editors/include/ED_undo.h
index 8c5f25e6b67..39bbd8adc75 100644
--- a/source/blender/editors/include/ED_undo.h
+++ b/source/blender/editors/include/ED_undo.h
@@ -15,6 +15,7 @@ extern "C" {
struct Base;
struct CLG_LogRef;
struct Object;
+struct Scene;
struct UndoStack;
struct ViewLayer;
struct bContext;
@@ -79,9 +80,12 @@ void ED_undo_object_editmode_restore_helper(struct bContext *C,
uint object_array_len,
uint object_array_stride);
-struct Object **ED_undo_editmode_objects_from_view_layer(struct ViewLayer *view_layer,
+struct Object **ED_undo_editmode_objects_from_view_layer(const struct Scene *scene,
+ struct ViewLayer *view_layer,
uint *r_len);
-struct Base **ED_undo_editmode_bases_from_view_layer(struct ViewLayer *view_layer, uint *r_len);
+struct Base **ED_undo_editmode_bases_from_view_layer(const struct Scene *scene,
+ struct ViewLayer *view_layer,
+ uint *r_len);
/**
* Ideally we won't access the stack directly,
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index 38e542fc0ca..5fea8711a84 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -73,8 +73,8 @@ bool ED_object_get_active_image(struct Object *ob,
int mat_nr,
struct Image **r_ima,
struct ImageUser **r_iuser,
- struct bNode **r_node,
- struct bNodeTree **r_ntree);
+ const struct bNode **r_node,
+ const struct bNodeTree **r_ntree);
void ED_object_assign_active_image(struct Main *bmain,
struct Object *ob,
int mat_nr,
@@ -107,7 +107,7 @@ bool uvedit_uv_select_test(const struct Scene *scene, struct BMLoop *l, int cd_l
* Changes selection state of a single UV Face.
*/
void uvedit_face_select_set(const struct Scene *scene,
- struct BMesh *em,
+ struct BMesh *bm,
struct BMFace *efa,
bool select,
bool do_history,
@@ -118,7 +118,7 @@ void uvedit_face_select_set(const struct Scene *scene,
* Changes selection state of a single UV Edge.
*/
void uvedit_edge_select_set(const struct Scene *scene,
- struct BMesh *em,
+ struct BMesh *bm,
struct BMLoop *l,
bool select,
bool do_history,
@@ -129,7 +129,7 @@ void uvedit_edge_select_set(const struct Scene *scene,
* Changes selection state of a single UV vertex.
*/
void uvedit_uv_select_set(const struct Scene *scene,
- struct BMesh *em,
+ struct BMesh *bm,
struct BMLoop *l,
bool select,
bool do_history,
@@ -339,14 +339,22 @@ bool ED_uvedit_udim_params_from_image_space(const struct SpaceImage *sima,
bool use_active,
struct UVMapUDIM_Params *udim_params);
+typedef enum {
+ ED_UVPACK_MARGIN_SCALED = 0, /* Use scale of existing UVs to multiply margin. */
+ ED_UVPACK_MARGIN_ADD, /* Just add the margin, ignoring any UV scale. */
+ ED_UVPACK_MARGIN_FRACTION, /* Specify a precise fraction of final UV output. */
+} eUVPackIsland_MarginMethod;
+
+/** See also #UnwrapOptions. */
struct UVPackIsland_Params {
uint rotate : 1;
- /** -1 not to align to axis, otherwise 0,1 for X,Y. */
- int rotate_align_axis : 2;
uint only_selected_uvs : 1;
uint only_selected_faces : 1;
uint use_seams : 1;
uint correct_aspect : 1;
+ bool ignore_pinned; /* Ignore islands which have any pinned UVs. */
+ eUVPackIsland_MarginMethod margin_method; /* Which formula to use when scaling island margin. */
+ float margin; /* Additional space to add around each island. */
};
/**
@@ -355,9 +363,24 @@ struct UVPackIsland_Params {
bool uv_coords_isect_udim(const struct Image *image,
const int udim_grid[2],
const float coords[2]);
+
+/**
+ * Pack UV islands from multiple objects.
+ *
+ * \param scene: Scene containing the objects to be packed.
+ * \param objects: Array of Objects to pack.
+ * \param objects_len: Length of `objects` array.
+ * \param bmesh_override: BMesh array aligned with `objects`.
+ * Optional, when non-null this overrides object's BMesh.
+ * This is needed to perform UV packing on objects that aren't in edit-mode.
+ * \param udim_params: Parameters to specify UDIM target and UDIM source image.
+ * \param params: Parameters and options to pass to the packing engine.
+ *
+ */
void ED_uvedit_pack_islands_multi(const struct Scene *scene,
Object **objects,
uint objects_len,
+ struct BMesh **bmesh_override,
const struct UVMapUDIM_Params *udim_params,
const struct UVPackIsland_Params *params);
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index c72f3121217..52aa5f56fee 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -228,6 +228,7 @@ typedef enum {
/** outside range (mainly for short), (can't avoid) */
V3D_PROJ_RET_OVERFLOW = 6,
} eV3DProjStatus;
+ENUM_OPERATORS(eV3DProjStatus, V3D_PROJ_RET_OVERFLOW);
/* some clipping tests are optional */
typedef enum {
@@ -350,7 +351,7 @@ void ED_view3d_cursor_snap_draw_util(struct RegionView3D *rv3d,
const uchar color_point[4],
eSnapMode snap_elem_type);
-/* view3d_iterators.c */
+/* view3d_iterators.cc */
/* foreach iterators */
@@ -456,7 +457,9 @@ void ED_view3d_project_float_v3_m4(const struct ARegion *region,
float r_co[3],
const float mat[4][4]);
-eV3DProjStatus ED_view3d_project_base(const struct ARegion *region, struct Base *base);
+eV3DProjStatus ED_view3d_project_base(const struct ARegion *region,
+ struct Base *base,
+ float r_co[2]);
/* *** short *** */
eV3DProjStatus ED_view3d_project_short_ex(const struct ARegion *region,
@@ -1311,7 +1314,7 @@ void ED_view3d_draw_bgpic_test(const struct Scene *scene,
bool do_foreground,
bool do_camera_frame);
-/* view3d_gizmo_preselect_type.c */
+/* view3d_gizmo_preselect_type.cc */
void ED_view3d_gizmo_mesh_preselect_get_active(struct bContext *C,
struct wmGizmo *gz,
@@ -1319,7 +1322,7 @@ void ED_view3d_gizmo_mesh_preselect_get_active(struct bContext *C,
struct BMElem **r_ele);
void ED_view3d_gizmo_mesh_preselect_clear(struct wmGizmo *gz);
-/* space_view3d.c */
+/* space_view3d.cc */
void ED_view3d_buttons_region_layout_ex(const struct bContext *C,
struct ARegion *region,
diff --git a/source/blender/editors/include/ED_viewer_path.hh b/source/blender/editors/include/ED_viewer_path.hh
new file mode 100644
index 00000000000..957dfddb8af
--- /dev/null
+++ b/source/blender/editors/include/ED_viewer_path.hh
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include <optional>
+
+#include "BLI_string_ref.hh"
+#include "BLI_vector.hh"
+
+#include "BKE_viewer_path.h"
+
+struct Main;
+struct SpaceNode;
+struct bNode;
+struct bContext;
+struct Object;
+
+namespace blender::ed::viewer_path {
+
+/**
+ * Activates the given node in the context provided by the editor. This indirectly updates all
+ * non-pinned viewer paths in other editors (spreadsheet and 3d view).
+ */
+void activate_geometry_node(Main &bmain, SpaceNode &snode, bNode &node);
+
+/**
+ * Returns the object referenced by the viewer path. This only returns something if the viewer path
+ * *only* contains the object and nothing more.
+ */
+Object *parse_object_only(const ViewerPath &viewer_path);
+
+/**
+ * Represents a parsed #ViewerPath for easier consumption.
+ */
+struct ViewerPathForGeometryNodesViewer {
+ Object *object;
+ blender::StringRefNull modifier_name;
+ blender::Vector<blender::StringRefNull> group_node_names;
+ blender::StringRefNull viewer_node_name;
+};
+
+/**
+ * Parses a #ViewerPath into a #ViewerPathForGeometryNodesViewer or returns none if that does not
+ * work.
+ */
+std::optional<ViewerPathForGeometryNodesViewer> parse_geometry_nodes_viewer(
+ const ViewerPath &viewer_path);
+
+/**
+ * Finds the node referenced by the #ViewerPath within the provided editor. If no node is
+ * referenced, null is returned. When two different editors show the same node group but in a
+ * different context, it's possible that the same node is active in one editor but not the other.
+ */
+bNode *find_geometry_nodes_viewer(const ViewerPath &viewer_path, SpaceNode &snode);
+
+/**
+ * Checks if the node referenced by the viewer path and its entire context still exists. The node
+ * does not have to be visible for this to return true.
+ */
+bool exists_geometry_nodes_viewer(const ViewerPathForGeometryNodesViewer &parsed_viewer_path);
+
+/**
+ * Checks if the node referenced by the viewer and its entire context is still active, i.e. some
+ * editor is showing it.
+ */
+bool is_active_geometry_nodes_viewer(const bContext &C,
+ const ViewerPathForGeometryNodesViewer &parsed_viewer_path);
+
+} // namespace blender::ed::viewer_path
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index 09057fd846e..31c766e95f2 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -472,8 +472,8 @@ DEF_ICON_BLANK(742)
DEF_ICON_BLANK(743)
DEF_ICON_MODIFIER(CON_ACTION)
DEF_ICON_BLANK(745)
-DEF_ICON_BLANK(746)
-DEF_ICON_BLANK(747)
+DEF_ICON_MODIFIER(MOD_ENVELOPE)
+DEF_ICON_MODIFIER(MOD_OUTLINE)
DEF_ICON_MODIFIER(MOD_LENGTH)
DEF_ICON_MODIFIER(MOD_DASH)
DEF_ICON_MODIFIER(MOD_LINEART)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 27e2f89f684..415356d1d71 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -133,6 +133,8 @@ enum {
/** #uiBlock.flag (controls) */
enum {
UI_BLOCK_LOOP = 1 << 0,
+ /** Indicate that items in a popup are drawn with inverted order. Used for arrow key navigation
+ * so that it knows to invert the navigation direction to match the drawing order. */
UI_BLOCK_IS_FLIP = 1 << 1,
UI_BLOCK_NO_FLIP = 1 << 2,
UI_BLOCK_NUMSELECT = 1 << 3,
@@ -532,6 +534,7 @@ typedef struct ARegion *(*uiButSearchTooltipFn)(struct bContext *C,
const struct rcti *item_rect,
void *arg,
void *active);
+typedef void (*uiButSearchListenFn)(const struct wmRegionListenerParams *params, void *arg);
/* Must return allocated string. */
typedef char *(*uiButToolTipFunc)(struct bContext *C, void *argN, const char *tip);
@@ -783,6 +786,9 @@ void UI_block_set_search_only(uiBlock *block, bool search_only);
* Can be called with C==NULL.
*/
void UI_block_free(const struct bContext *C, uiBlock *block);
+
+void UI_block_listen(const uiBlock *block, const struct wmRegionListenerParams *listener_params);
+
/**
* Can be called with C==NULL.
*/
@@ -1392,6 +1398,7 @@ void UI_but_extra_icon_string_info_get(struct bContext *C, uiButExtraOpIcon *ext
* - AutoButR: RNA property button with type automatically defined.
*/
enum {
+ UI_ID_NOP = 0,
UI_ID_RENAME = 1 << 0,
UI_ID_BROWSE = 1 << 1,
UI_ID_ADD_NEW = 1 << 2,
@@ -1659,6 +1666,7 @@ void UI_but_func_search_set(uiBut *but,
void *active);
void UI_but_func_search_set_context_menu(uiBut *but, uiButSearchContextMenuFn context_menu_fn);
void UI_but_func_search_set_tooltip(uiBut *but, uiButSearchTooltipFn tooltip_fn);
+void UI_but_func_search_set_listen(uiBut *but, uiButSearchListenFn listen_fn);
/**
* \param search_sep_string: when not NULL, this string is used as a separator,
* showing the icon and highlighted text after the last instance of this string.
@@ -1680,6 +1688,7 @@ int UI_search_items_find_index(uiSearchItems *items, const char *name);
* Adds a hint to the button which draws right aligned, grayed out and never clipped.
*/
void UI_but_hint_drawstr_set(uiBut *but, const char *string);
+void UI_but_icon_indicator_number_set(uiBut *but, const int indicator_number);
void UI_but_node_link_set(uiBut *but, struct bNodeSocket *socket, const float draw_color[4]);
@@ -1780,7 +1789,6 @@ void UI_but_drag_attach_image(uiBut *but, struct ImBuf *imb, float scale);
void UI_but_drag_set_asset(uiBut *but,
const struct AssetHandle *asset,
const char *path,
- struct AssetMetaData *metadata,
int import_type, /* eFileAssetImportType */
int icon,
struct ImBuf *imb,
@@ -2521,6 +2529,7 @@ void uiTemplateNodeView(uiLayout *layout,
struct bNodeTree *ntree,
struct bNode *node,
struct bNodeSocket *input);
+void uiTemplateNodeAssetMenuItems(uiLayout *layout, struct bContext *C, const char *catalog_path);
void uiTemplateTextureUser(uiLayout *layout, struct bContext *C);
/**
* Button to quickly show texture in Properties Editor texture tab.
@@ -2785,7 +2794,8 @@ typedef struct uiPropertySplitWrapper {
uiPropertySplitWrapper uiItemPropertySplitWrapperCreate(uiLayout *parent_layout);
void uiItemL(uiLayout *layout, const char *name, int icon); /* label */
-void uiItemL_ex(uiLayout *layout, const char *name, int icon, bool highlight, bool redalert);
+struct uiBut *uiItemL_ex(
+ uiLayout *layout, const char *name, int icon, bool highlight, bool redalert);
/**
* Helper to add a label and creates a property split layout if needed.
*/
@@ -3192,9 +3202,6 @@ void UI_interface_tag_script_reload(void);
/* Support click-drag motion which presses the button and closes a popover (like a menu). */
#define USE_UI_POPOVER_ONCE
-void UI_block_views_listen(const uiBlock *block,
- const struct wmRegionListenerParams *listener_params);
-
bool UI_view_item_is_active(const uiViewItemHandle *item_handle);
bool UI_view_item_matches(const uiViewItemHandle *a_handle, const uiViewItemHandle *b_handle);
/**
diff --git a/source/blender/editors/include/UI_interface.hh b/source/blender/editors/include/UI_interface.hh
index 6c756984203..fc03b0218c0 100644
--- a/source/blender/editors/include/UI_interface.hh
+++ b/source/blender/editors/include/UI_interface.hh
@@ -35,6 +35,7 @@ struct ContextPathItem {
std::string name;
/* #BIFIconID */
int icon;
+ int icon_indicator_number;
};
void context_path_add_generic(Vector<ContextPathItem> &path,
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index a1a98a4b08c..9669e242dac 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -27,6 +27,12 @@ typedef struct IconFile {
int index;
} IconFile;
+typedef struct IconTextOverlay {
+ char text[5];
+} IconTextOverlay;
+
+#define UI_NO_ICON_OVERLAY_TEXT NULL
+
#define ICON_DEFAULT_HEIGHT 16
#define ICON_DEFAULT_WIDTH 16
@@ -105,7 +111,8 @@ void UI_icon_draw_ex(float x,
float alpha,
float desaturate,
const uchar mono_color[4],
- bool mono_border);
+ bool mono_border,
+ const struct IconTextOverlay *text_overlay);
void UI_icons_free(void);
void UI_icons_free_drawinfo(void *drawinfo);
@@ -124,6 +131,9 @@ int UI_icon_from_library(const struct ID *id);
int UI_icon_from_object_mode(int mode);
int UI_icon_color_from_collection(const struct Collection *collection);
+void UI_icon_text_overlay_init_from_count(struct IconTextOverlay *text_overlay,
+ const int icon_indicator_number);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h
index e508c96b4f1..f0bf04ed408 100644
--- a/source/blender/editors/include/UI_view2d.h
+++ b/source/blender/editors/include/UI_view2d.h
@@ -16,37 +16,39 @@
extern "C" {
#endif
-/* ------------------------------------------ */
-/* Settings and Defines: */
+/* -------------------------------------------------------------------- */
+/** \name General Defines
+ * \{ */
-/* ---- General Defines ---- */
-
-/* generic value to use when coordinate lies out of view when converting */
+/** Generic value to use when coordinate lies out of view when converting. */
#define V2D_IS_CLIPPED 12000
-/* Common View2D view types
- * NOTE: only define a type here if it completely sets all (+/- a few) of the relevant flags
- * and settings for a View2D region, and that set of settings is used in more
- * than one specific place
+/**
+ * Common View2D view types.
+ *
+ * \note only define a type here if it completely sets all (+/- a few) of the relevant flags and
+ * settings for a View2D region, and that set of settings is used in more than one specific place.
*/
enum eView2D_CommonViewTypes {
- /* custom view type (region has defined all necessary flags already) */
+ /** custom view type (region has defined all necessary flags already). */
V2D_COMMONVIEW_CUSTOM = -1,
- /* standard (only use this when setting up a new view, as a sensible base for most settings) */
+ /** standard (only use this when setting up a new view, as a sensible base for most settings). */
V2D_COMMONVIEW_STANDARD,
- /* listview (i.e. Outliner) */
+ /** List-view (i.e. Outliner). */
V2D_COMMONVIEW_LIST,
- /* Stack-view (this is basically a list where new items are added at the top). */
+ /** Stack-view (this is basically a list where new items are added at the top). */
V2D_COMMONVIEW_STACK,
- /* headers (this is basically the same as listview, but no y-panning) */
+ /** headers (this is basically the same as list-view, but no Y-panning). */
V2D_COMMONVIEW_HEADER,
- /* ui region containing panels */
+ /** UI region containing panels. */
V2D_COMMONVIEW_PANELS_UI,
};
-/* ---- Defines for Scroller Arguments ----- */
+/** \} */
-/* ------ Defines for Scrollers ----- */
+/* -------------------------------------------------------------------- */
+/** \name Defines for Scroll Bars
+ * \{ */
/** Scroll bar area. */
@@ -54,7 +56,7 @@ enum eView2D_CommonViewTypes {
#define V2D_SCROLL_HEIGHT ((0.45f * U.widget_unit) + (2.0f * U.pixelsize))
#define V2D_SCROLL_WIDTH ((0.45f * U.widget_unit) + (2.0f * U.pixelsize))
-/* Alpha of scrollbar when at minimum size. */
+/* Alpha of scroll-bar when at minimum size. */
#define V2D_SCROLL_MIN_ALPHA (0.4f)
/* Minimum size needs to include outline which varies with line width. */
@@ -74,25 +76,35 @@ enum eView2D_CommonViewTypes {
/** Don't allow scroll thumb to show below this size (so it's never too small to click on). */
#define V2D_SCROLL_THUMB_SIZE_MIN (30.0 * UI_DPI_FAC)
-/* ------ Define for UI_view2d_sync ----- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Define for #UI_view2d_sync
+ * \{ */
/* means copy it from another v2d */
#define V2D_LOCK_SET 0
/* means copy it to the other v2ds */
#define V2D_LOCK_COPY 1
-/* ------------------------------------------ */
-/* Macros: */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Macros
+ * \{ */
-/* test if mouse in a scrollbar (assume that scroller availability has been tested) */
+/* Test if mouse in a scroll-bar (assume that scroller availability has been tested). */
#define IN_2D_VERT_SCROLL(v2d, co) (BLI_rcti_isect_pt_v(&v2d->vert, co))
#define IN_2D_HORIZ_SCROLL(v2d, co) (BLI_rcti_isect_pt_v(&v2d->hor, co))
#define IN_2D_VERT_SCROLL_RECT(v2d, rct) (BLI_rcti_isect(&v2d->vert, rct, NULL))
#define IN_2D_HORIZ_SCROLL_RECT(v2d, rct) (BLI_rcti_isect(&v2d->hor, rct, NULL))
-/* ------------------------------------------ */
-/* Type definitions: */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Forward Declarations
+ * \{ */
struct View2D;
struct View2DScrollers;
@@ -112,8 +124,11 @@ struct wmOperatorType;
typedef struct View2DScrollers View2DScrollers;
-/* ----------------------------------------- */
-/* Prototypes: */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Prototypes
+ * \{ */
/**
* Refresh and validation (of view rects).
@@ -161,7 +176,12 @@ void UI_view2d_mask_from_win(const struct View2D *v2d, struct rcti *r_mask);
void UI_view2d_zoom_cache_reset(void);
-/* view matrix operations */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name View Matrix Operations
+ * \{ */
+
/**
* Set view matrices to use 'cur' rect as viewing frame for View2D drawing.
*/
@@ -178,7 +198,11 @@ void UI_view2d_view_orthoSpecial(struct ARegion *region, struct View2D *v2d, boo
*/
void UI_view2d_view_restore(const struct bContext *C);
-/* grid drawing */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Grid Drawing
+ * \{ */
/**
* Draw a multi-level grid in given 2d-region.
@@ -241,7 +265,11 @@ void UI_view2d_draw_scale_x__frames_or_seconds(const struct ARegion *region,
bool display_seconds,
int colorid);
-/* Scroll-bar drawing. */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Scroll-bar Drawing
+ * \{ */
/**
* Calculate relevant scroller properties.
@@ -258,7 +286,11 @@ void UI_view2d_scrollers_draw_ex(struct View2D *v2d,
bool use_full_hide);
void UI_view2d_scrollers_draw(struct View2D *v2d, const struct rcti *mask_custom);
-/* List view tools. */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name List View Tools
+ * \{ */
/**
* Get the 'cell' (row, column) that the given 2D-view coordinates
@@ -281,7 +313,11 @@ void UI_view2d_listview_view_to_cell(float columnwidth,
int *r_column,
int *r_row);
-/* Coordinate conversion. */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Coordinate Conversion
+ * \{ */
float UI_view2d_region_to_view_x(const struct View2D *v2d, float x);
float UI_view2d_region_to_view_y(const struct View2D *v2d, float y);
@@ -338,7 +374,11 @@ bool UI_view2d_view_to_region_rcti_clip(const struct View2D *v2d,
const struct rctf *rect_src,
struct rcti *rect_dst) ATTR_NONNULL();
-/* Utilities. */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Utilities
+ * \{ */
/**
* View2D data by default resides in region, so get from region stored in context.
@@ -350,8 +390,8 @@ struct View2D *UI_view2d_fromcontext(const struct bContext *C);
struct View2D *UI_view2d_fromcontext_rwin(const struct bContext *C);
/**
- * Get scrollbar sizes of the current 2D view.
- * The size will be zero if the view has its scrollbars disabled.
+ * Get scroll-bar sizes of the current 2D view.
+ * The size will be zero if the view has its scroll-bars disabled.
*
* \param mapped: whether to use view2d_scroll_mapped which changes flags
*/
@@ -432,7 +472,11 @@ void UI_view2d_text_cache_add_rectf(struct View2D *v2d,
const unsigned char col[4]);
void UI_view2d_text_cache_draw(struct ARegion *region);
-/* Operators. */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Operators
+ * \{ */
void ED_operatortypes_view2d(void);
void ED_keymap_view2d(struct wmKeyConfig *keyconf);
@@ -449,7 +493,11 @@ void UI_view2d_smooth_view(const struct bContext *C,
#define UI_MARKER_MARGIN_Y (42 * UI_DPI_FAC)
#define UI_TIME_SCRUB_MARGIN_Y (23 * UI_DPI_FAC)
-/* Gizmo Types. */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Gizmo Types
+ * \{ */
/* view2d_gizmo_navigate.c */
@@ -458,7 +506,11 @@ void UI_view2d_smooth_view(const struct bContext *C,
*/
void VIEW2D_GGT_navigate_impl(struct wmGizmoGroupType *gzgt, const char *idname);
-/* Edge pan. */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Edge Pan
+ * \{ */
/**
* Custom-data for view panning operators.
@@ -559,6 +611,8 @@ void UI_view2d_edge_pan_operator_init(struct bContext *C,
struct View2DEdgePanData *vpd,
struct wmOperator *op);
+/** \} */
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/editors/interface/eyedroppers/eyedropper_depth.c b/source/blender/editors/interface/eyedroppers/eyedropper_depth.c
index 3fb5a74944b..c6d950112b9 100644
--- a/source/blender/editors/interface/eyedroppers/eyedropper_depth.c
+++ b/source/blender/editors/interface/eyedroppers/eyedropper_depth.c
@@ -162,7 +162,7 @@ static void depthdropper_depth_sample_pt(bContext *C,
View3D *v3d = area->spacedata.first;
RegionView3D *rv3d = region->regiondata;
/* weak, we could pass in some reference point */
- const float *view_co = v3d->camera ? v3d->camera->obmat[3] : rv3d->viewinv[3];
+ const float *view_co = v3d->camera ? v3d->camera->object_to_world[3] : rv3d->viewinv[3];
const int mval[2] = {m_xy[0] - region->winrct.xmin, m_xy[1] - region->winrct.ymin};
copy_v2_v2_int(ddr->name_pos, mval);
diff --git a/source/blender/editors/interface/eyedroppers/interface_eyedropper.c b/source/blender/editors/interface/eyedroppers/interface_eyedropper.c
index c6fb8f0ab68..e49955512a1 100644
--- a/source/blender/editors/interface/eyedroppers/interface_eyedropper.c
+++ b/source/blender/editors/interface/eyedroppers/interface_eyedropper.c
@@ -41,7 +41,7 @@ wmKeyMap *eyedropper_modal_keymap(wmKeyConfig *keyconf)
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Eyedropper Modal Map");
- /* this function is called for each spacetype, only needs to add map once */
+ /* This function is called for each space-type, only needs to add map once. */
if (keymap && keymap->modal_items) {
return NULL;
}
diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc
index ca4918b2e8d..331d1581db5 100644
--- a/source/blender/editors/interface/interface.cc
+++ b/source/blender/editors/interface/interface.cc
@@ -82,9 +82,9 @@ static void ui_but_to_pixelrect(struct rcti *rect,
const struct ARegion *region,
struct uiBlock *block,
const struct uiBut *but);
-static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *but_p);
-static void ui_def_but_rna__panel_type(bContext *UNUSED(C), uiLayout *layout, void *but_p);
-static void ui_def_but_rna__menu_type(bContext *UNUSED(C), uiLayout *layout, void *but_p);
+static void ui_def_but_rna__menu(bContext * /*C*/, uiLayout *layout, void *but_p);
+static void ui_def_but_rna__panel_type(bContext * /*C*/, uiLayout *layout, void *but_p);
+static void ui_def_but_rna__menu_type(bContext * /*C*/, uiLayout *layout, void *but_p);
/* avoid unneeded calls to ui_but_value_get */
#define UI_BUT_VALUE_UNSET DBL_MAX
@@ -133,10 +133,10 @@ void ui_block_to_region_fl(const ARegion *region, uiBlock *block, float *r_x, fl
gy += block->panel->ofsy;
}
- *r_x = ((float)getsizex) * (0.5f + 0.5f * (gx * block->winmat[0][0] + gy * block->winmat[1][0] +
- block->winmat[3][0]));
- *r_y = ((float)getsizey) * (0.5f + 0.5f * (gx * block->winmat[0][1] + gy * block->winmat[1][1] +
- block->winmat[3][1]));
+ *r_x = float(getsizex) * (0.5f + 0.5f * (gx * block->winmat[0][0] + gy * block->winmat[1][0] +
+ block->winmat[3][0]));
+ *r_y = float(getsizey) * (0.5f + 0.5f * (gx * block->winmat[0][1] + gy * block->winmat[1][1] +
+ block->winmat[3][1]));
}
void ui_block_to_window_fl(const ARegion *region, uiBlock *block, float *r_x, float *r_y)
@@ -153,8 +153,8 @@ void ui_block_to_window(const ARegion *region, uiBlock *block, int *r_x, int *r_
ui_block_to_window_fl(region, block, &fx, &fy);
- *r_x = (int)lround(fx);
- *r_y = (int)lround(fy);
+ *r_x = int(lround(fx));
+ *r_y = int(lround(fy));
}
void ui_block_to_region_rctf(const ARegion *region,
@@ -195,13 +195,13 @@ void ui_window_to_block_fl(const ARegion *region, uiBlock *block, float *r_x, fl
const int sx = region->winrct.xmin;
const int sy = region->winrct.ymin;
- const float a = 0.5f * ((float)getsizex) * block->winmat[0][0];
- const float b = 0.5f * ((float)getsizex) * block->winmat[1][0];
- const float c = 0.5f * ((float)getsizex) * (1.0f + block->winmat[3][0]);
+ const float a = 0.5f * float(getsizex) * block->winmat[0][0];
+ const float b = 0.5f * float(getsizex) * block->winmat[1][0];
+ const float c = 0.5f * float(getsizex) * (1.0f + block->winmat[3][0]);
- const float d = 0.5f * ((float)getsizey) * block->winmat[0][1];
- const float e = 0.5f * ((float)getsizey) * block->winmat[1][1];
- const float f = 0.5f * ((float)getsizey) * (1.0f + block->winmat[3][1]);
+ const float d = 0.5f * float(getsizey) * block->winmat[0][1];
+ const float e = 0.5f * float(getsizey) * block->winmat[1][1];
+ const float f = 0.5f * float(getsizey) * (1.0f + block->winmat[3][1]);
const float px = *r_x - sx;
const float py = *r_y - sy;
@@ -232,8 +232,8 @@ void ui_window_to_block(const ARegion *region, uiBlock *block, int *r_x, int *r_
ui_window_to_block_fl(region, block, &fx, &fy);
- *r_x = (int)lround(fx);
- *r_y = (int)lround(fy);
+ *r_x = int(lround(fx));
+ *r_y = int(lround(fy));
}
void ui_window_to_region(const ARegion *region, int *r_x, int *r_y)
@@ -279,8 +279,8 @@ static void ui_update_flexible_spacing(const ARegion *region, uiBlock *block)
rcti rect;
ui_but_to_pixelrect(&rect, region, block, static_cast<const uiBut *>(block->buttons.last));
- const float buttons_width = (float)rect.xmax + UI_HEADER_OFFSET;
- const float region_width = (float)region->sizex * U.dpi_fac;
+ const float buttons_width = float(rect.xmax) + UI_HEADER_OFFSET;
+ const float region_width = float(region->sizex) * U.dpi_fac;
if (region_width <= buttons_width) {
return;
@@ -296,7 +296,7 @@ static void ui_update_flexible_spacing(const ARegion *region, uiBlock *block)
}
const float view_scale_x = UI_view2d_scale_get_x(&region->v2d);
- const float segment_width = region_width / (float)sepr_flex_len;
+ const float segment_width = region_width / float(sepr_flex_len);
float offset = 0, remaining_space = region_width - buttons_width;
int i = 0;
LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
@@ -502,8 +502,8 @@ static void ui_block_bounds_calc_centered(wmWindow *window, uiBlock *block)
static void ui_block_bounds_calc_centered_pie(uiBlock *block)
{
const int xy[2] = {
- (int)block->pie_data.pie_center_spawned[0],
- (int)block->pie_data.pie_center_spawned[1],
+ int(block->pie_data.pie_center_spawned[0]),
+ int(block->pie_data.pie_center_spawned[1]),
};
UI_block_translate(block, xy[0], xy[1]);
@@ -682,7 +682,7 @@ static int ui_but_calc_float_precision(uiBut *but, double value)
return 0;
}
- int prec = (int)ui_but_get_float_precision(but);
+ int prec = int(ui_but_get_float_precision(but));
/* first check for various special cases:
* * If button is radians, we want additional precision (see T39861).
@@ -1411,7 +1411,7 @@ static bool ui_but_event_property_operator_string(const bContext *C,
ui_def_but_rna__menu,
ui_def_but_rna__panel_type,
ui_def_but_rna__menu_type)) {
- prop_enum_value = (int)but->hardmin;
+ prop_enum_value = int(but->hardmin);
ptr = &but_parent->rnapoin;
prop = but_parent->rnaprop;
prop_enum_value_ok = true;
@@ -1804,7 +1804,7 @@ static void ui_but_predefined_extra_operator_icons_add(uiBut *but)
return;
}
}
- ui_but_extra_operator_icon_add_ptr(but, optype, WM_OP_INVOKE_DEFAULT, (int)icon);
+ ui_but_extra_operator_icon_add_ptr(but, optype, WM_OP_INVOKE_DEFAULT, int(icon));
}
}
@@ -1853,7 +1853,7 @@ static void ui_but_validate(const uiBut *but)
uiButNumber *number_but = (uiButNumber *)but;
if (ELEM(but->pointype, UI_BUT_POIN_CHAR, UI_BUT_POIN_SHORT, UI_BUT_POIN_INT)) {
- BLI_assert((int)number_but->step_size > 0);
+ BLI_assert(int(number_but->step_size) > 0);
}
}
}
@@ -2165,7 +2165,7 @@ int ui_but_is_pushed_ex(uiBut *but, double *value)
but->type, UI_BTYPE_TOGGLE_N, UI_BTYPE_ICON_TOGGLE_N, UI_BTYPE_CHECKBOX_N);
int lvalue;
UI_GET_BUT_VALUE_INIT(but, *value);
- lvalue = (int)*value;
+ lvalue = int(*value);
if (UI_BITBUT_TEST(lvalue, (but->bitnr))) {
is_push = state;
}
@@ -2187,7 +2187,7 @@ int ui_but_is_pushed_ex(uiBut *but, double *value)
case UI_BTYPE_ICON_TOGGLE:
case UI_BTYPE_CHECKBOX:
UI_GET_BUT_VALUE_INIT(but, *value);
- if (*value != (double)but->hardmin) {
+ if (*value != double(but->hardmin)) {
is_push = true;
}
break;
@@ -2220,12 +2220,12 @@ int ui_but_is_pushed_ex(uiBut *but, double *value)
UI_GET_BUT_VALUE_INIT(but, *value);
/* support for rna enum buts */
if (but->rnaprop && (RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG)) {
- if ((int)*value & (int)but->hardmax) {
+ if (int(*value) & int(but->hardmax)) {
is_push = true;
}
}
else {
- if (*value == (double)but->hardmax) {
+ if (*value == double(but->hardmax)) {
is_push = true;
}
}
@@ -2246,7 +2246,7 @@ int ui_but_is_pushed_ex(uiBut *but, double *value)
}
if ((but->drawflag & UI_BUT_CHECKBOX_INVERT) && (is_push != -1)) {
- is_push = !((bool)is_push);
+ is_push = !bool(is_push);
}
return is_push;
}
@@ -2315,9 +2315,9 @@ void ui_but_v3_get(uiBut *but, float vec[3])
}
else if (but->pointype == UI_BUT_POIN_CHAR) {
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;
+ 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) {
const float *fp = (float *)but->poin;
@@ -2363,9 +2363,9 @@ void ui_but_v3_set(uiBut *but, const float vec[3])
}
else if (but->pointype == UI_BUT_POIN_CHAR) {
char *cp = (char *)but->poin;
- cp[0] = (char)lround(vec[0] * 255.0f);
- cp[1] = (char)lround(vec[1] * 255.0f);
- cp[2] = (char)lround(vec[2] * 255.0f);
+ cp[0] = char(lround(vec[0] * 255.0f));
+ cp[1] = char(lround(vec[1] * 255.0f));
+ cp[2] = char(lround(vec[2] * 255.0f));
}
else if (but->pointype == UI_BUT_POIN_FLOAT) {
float *fp = (float *)but->poin;
@@ -2572,10 +2572,10 @@ void ui_but_value_set(uiBut *but, double value)
break;
case PROP_INT:
if (RNA_property_array_check(prop)) {
- RNA_property_int_set_index(&but->rnapoin, prop, but->rnaindex, (int)value);
+ RNA_property_int_set_index(&but->rnapoin, prop, but->rnaindex, int(value));
}
else {
- RNA_property_int_set(&but->rnapoin, prop, (int)value);
+ RNA_property_int_set(&but->rnapoin, prop, int(value));
}
break;
case PROP_FLOAT:
@@ -2588,7 +2588,7 @@ void ui_but_value_set(uiBut *but, double value)
break;
case PROP_ENUM:
if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
- int ivalue = (int)value;
+ int ivalue = int(value);
/* toggle for enum/flag buttons */
ivalue ^= RNA_property_enum_get(&but->rnapoin, prop);
RNA_property_enum_set(&but->rnapoin, prop, ivalue);
@@ -2621,7 +2621,7 @@ void ui_but_value_set(uiBut *but, double value)
value = round_db_to_int_clamp(value);
}
else if (but->pointype == UI_BUT_POIN_FLOAT) {
- float fval = (float)value;
+ float fval = float(value);
if (fval >= -0.00001f && fval <= 0.00001f) {
/* prevent negative zero */
fval = 0.0f;
@@ -2634,16 +2634,16 @@ void ui_but_value_set(uiBut *but, double value)
value = *but->editval = value;
}
else if (but->pointype == UI_BUT_POIN_CHAR) {
- value = *((char *)but->poin) = (char)value;
+ value = *((char *)but->poin) = char(value);
}
else if (but->pointype == UI_BUT_POIN_SHORT) {
- value = *((short *)but->poin) = (short)value;
+ value = *((short *)but->poin) = short(value);
}
else if (but->pointype == UI_BUT_POIN_INT) {
- value = *((int *)but->poin) = (int)value;
+ value = *((int *)but->poin) = int(value);
}
else if (but->pointype == UI_BUT_POIN_FLOAT) {
- value = *((float *)but->poin) = (float)value;
+ value = *((float *)but->poin) = float(value);
}
}
@@ -2721,7 +2721,7 @@ static void ui_get_but_string_unit(
/* Use precision override? */
if (float_precision == -1) {
/* Sanity checks */
- precision = (int)ui_but_get_float_precision(but);
+ precision = int(ui_but_get_float_precision(but));
if (precision > UI_PRECISION_FLOAT_MAX) {
precision = UI_PRECISION_FLOAT_MAX;
}
@@ -2763,7 +2763,7 @@ static float ui_get_but_step_unit(uiBut *but, float step_default)
BLI_assert(step > 0.0);
- step_final = (step / scale_unit) / (double)UI_PRECISION_FLOAT_SCALE;
+ step_final = (step / scale_unit) / double(UI_PRECISION_FLOAT_SCALE);
if (step == step_unit) {
/* Logic here is to scale by the original 'step_orig'
@@ -2775,7 +2775,7 @@ static float ui_get_but_step_unit(uiBut *but, float step_default)
step_final *= step_orig;
}
- return (float)step_final;
+ return float(step_final);
}
void ui_but_string_get_ex(uiBut *but,
@@ -2904,7 +2904,7 @@ void ui_but_string_get_ex(uiBut *but,
}
}
else {
- BLI_snprintf(str, maxlen, "%d", (int)value);
+ BLI_snprintf(str, maxlen, "%d", int(value));
}
}
}
@@ -3211,10 +3211,10 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
}
/* not that we use hard limits here */
- if (value < (double)but->hardmin) {
+ if (value < double(but->hardmin)) {
value = but->hardmin;
}
- if (value > (double)but->hardmax) {
+ if (value > double(but->hardmax)) {
value = but->hardmax;
}
@@ -3307,8 +3307,8 @@ void ui_but_range_set_soft(uiBut *but)
if (is_array) {
int value_range[2];
RNA_property_int_get_array_range(&but->rnapoin, but->rnaprop, value_range);
- value_min = (double)value_range[0];
- value_max = (double)value_range[1];
+ value_min = double(value_range[0]);
+ value_max = double(value_range[1]);
}
else {
value_min = value_max = ui_but_value_get(but);
@@ -3319,8 +3319,8 @@ void ui_but_range_set_soft(uiBut *but)
float fmin, fmax, fstep, fprecision;
RNA_property_float_ui_range(&but->rnapoin, but->rnaprop, &fmin, &fmax, &fstep, &fprecision);
- softmin = (fmin == -FLT_MAX) ? (float)-1e4 : fmin;
- softmax = (fmax == FLT_MAX) ? (float)1e4 : fmax;
+ softmin = (fmin == -FLT_MAX) ? float(-1e4) : fmin;
+ softmax = (fmax == FLT_MAX) ? float(1e4) : fmax;
// step = fstep; /* UNUSED */
// precision = fprecision; /* UNUSED */
@@ -3328,8 +3328,8 @@ void ui_but_range_set_soft(uiBut *but)
if (is_array && !(subtype == PROP_COLOR && but->rnaindex == 3)) {
float value_range[2];
RNA_property_float_get_array_range(&but->rnapoin, but->rnaprop, value_range);
- value_min = (double)value_range[0];
- value_max = (double)value_range[1];
+ value_min = double(value_range[0]);
+ value_max = double(value_range[1]);
}
else {
value_min = value_max = ui_but_value_get(but);
@@ -3348,8 +3348,8 @@ void ui_but_range_set_soft(uiBut *but)
softmin = soft_range_round_down(value_min, softmin);
}
- if (softmin < (double)but->hardmin) {
- softmin = (double)but->hardmin;
+ if (softmin < double(but->hardmin)) {
+ softmin = double(but->hardmin);
}
}
if (value_max - 1e-10 > softmax) {
@@ -3360,7 +3360,7 @@ void ui_but_range_set_soft(uiBut *but)
softmax = soft_range_round_up(value_max, softmax);
}
- if (softmax > (double)but->hardmax) {
+ if (softmax > double(but->hardmax)) {
softmax = but->hardmax;
}
}
@@ -3474,6 +3474,7 @@ void UI_block_free(const bContext *C, uiBlock *block)
BLI_freelistN(&block->saferct);
BLI_freelistN(&block->color_pickers.list);
+ BLI_freelistN(&block->dynamic_listeners);
ui_block_free_button_groups(block);
ui_block_free_views(block);
@@ -3481,6 +3482,20 @@ void UI_block_free(const bContext *C, uiBlock *block)
MEM_freeN(block);
}
+void UI_block_listen(const uiBlock *block, const wmRegionListenerParams *listener_params)
+{
+ /* Don't need to let invisible blocks (old blocks from previous redraw) listen. */
+ if (!block->active) {
+ return;
+ }
+
+ LISTBASE_FOREACH (uiBlockDynamicListener *, listener, &block->dynamic_listeners) {
+ listener->listener_func(listener_params);
+ }
+
+ ui_block_views_listen(block, listener_params);
+}
+
void UI_blocklist_update_window_matrix(const bContext *C, const ListBase *lb)
{
ARegion *region = CTX_wm_region(C);
@@ -3659,10 +3674,10 @@ static void ui_but_build_drawstr_float(uiBut *but, double value)
/* Change negative zero to regular zero, without altering anything else. */
value += +0.0f;
- if (value == (double)FLT_MAX) {
+ if (value == double(FLT_MAX)) {
STR_CONCAT(but->drawstr, slen, "inf");
}
- else if (value == (double)-FLT_MAX) {
+ else if (value == double(-FLT_MAX)) {
STR_CONCAT(but->drawstr, slen, "-inf");
}
else if (subtype == PROP_PERCENTAGE) {
@@ -3740,10 +3755,10 @@ static void ui_but_update_ex(uiBut *but, const bool validate)
case UI_BTYPE_NUM_SLIDER:
if (validate) {
UI_GET_BUT_VALUE_INIT(but, value);
- if (value < (double)but->hardmin) {
+ if (value < double(but->hardmin)) {
ui_but_value_set(but, but->hardmin);
}
- else if (value > (double)but->hardmax) {
+ else if (value > double(but->hardmax)) {
ui_but_value_set(but, but->hardmax);
}
@@ -3810,7 +3825,7 @@ static void ui_but_update_ex(uiBut *but, const bool validate)
ui_but_build_drawstr_float(but, value);
}
else {
- ui_but_build_drawstr_int(but, (int)value);
+ ui_but_build_drawstr_int(but, int(value));
}
break;
@@ -3843,7 +3858,7 @@ static void ui_but_update_ex(uiBut *but, const bool validate)
}
else {
UI_GET_BUT_VALUE_INIT(but, value);
- str = WM_key_event_string((short)value, false);
+ str = WM_key_event_string(short(value), false);
}
BLI_snprintf(but->drawstr, UI_MAX_DRAW_STR, "%s%s", but->str, str);
break;
@@ -4263,7 +4278,7 @@ void ui_def_but_icon_clear(uiBut *but)
but->drawflag &= ~UI_BUT_ICON_LEFT;
}
-static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *but_p)
+static void ui_def_but_rna__menu(bContext * /*C*/, uiLayout *layout, void *but_p)
{
uiBlock *block = uiLayoutGetBlock(layout);
uiPopupBlockHandle *handle = block->handle;
@@ -4573,7 +4588,7 @@ static uiBut *ui_def_but_rna(uiBlock *block,
value = RNA_property_enum_get(ptr, prop);
}
else {
- value = (int)max;
+ value = int(max);
}
const int i = RNA_enum_from_value(item, value);
@@ -5933,12 +5948,12 @@ bContextStore *UI_but_context_get(const uiBut *but)
void UI_but_unit_type_set(uiBut *but, const int unit_type)
{
- but->unit_type = (uchar)(RNA_SUBTYPE_UNIT_VALUE(unit_type));
+ but->unit_type = uchar(RNA_SUBTYPE_UNIT_VALUE(unit_type));
}
int UI_but_unit_type_get(const uiBut *but)
{
- const int ownUnit = (int)but->unit_type;
+ const int ownUnit = int(but->unit_type);
/* own unit define always takes precedence over RNA provided, allowing for overriding
* default value provided in RNA in a few special cases (i.e. Active Keyframe in Graph Edit)
@@ -6321,6 +6336,13 @@ void UI_but_func_search_set_tooltip(uiBut *but, uiButSearchTooltipFn tooltip_fn)
but_search->item_tooltip_fn = tooltip_fn;
}
+void UI_but_func_search_set_listen(uiBut *but, uiButSearchListenFn listen_fn)
+{
+ uiButSearch *but_search = (uiButSearch *)but;
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+ but_search->listen_fn = listen_fn;
+}
+
void UI_but_func_search_set_results_are_suggestions(uiBut *but, const bool value)
{
uiButSearch *but_search = (uiButSearch *)but;
@@ -6334,7 +6356,7 @@ static void operator_enum_search_update_fn(const struct bContext *C,
void *but,
const char *str,
uiSearchItems *items,
- const bool UNUSED(is_first))
+ const bool /*is_first*/)
{
wmOperatorType *ot = ((uiBut *)but)->optype;
PropertyRNA *prop = ot->prop;
@@ -6383,7 +6405,7 @@ static void operator_enum_search_update_fn(const struct bContext *C,
}
}
-static void operator_enum_search_exec_fn(struct bContext *UNUSED(C), void *but, void *arg2)
+static void operator_enum_search_exec_fn(struct bContext * /*C*/, void *but, void *arg2)
{
wmOperatorType *ot = ((uiBut *)but)->optype;
/* Will create it if needed! */
@@ -6445,6 +6467,11 @@ void UI_but_hint_drawstr_set(uiBut *but, const char *string)
ui_but_add_shortcut(but, string, false);
}
+void UI_but_icon_indicator_number_set(uiBut *but, const int indicator_number)
+{
+ UI_icon_text_overlay_init_from_count(&but->icon_overlay_text, indicator_number);
+}
+
void UI_but_node_link_set(uiBut *but, bNodeSocket *socket, const float draw_color[4])
{
but->flag |= UI_BUT_NODE_LINK;
@@ -6656,8 +6683,8 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...)
/* enum property */
ptr = &but->rnapoin;
prop = but->rnaprop;
- value = (ELEM(but->type, UI_BTYPE_ROW, UI_BTYPE_TAB)) ? (int)but->hardmax :
- (int)ui_but_value_get(but);
+ value = ELEM(but->type, UI_BTYPE_ROW, UI_BTYPE_TAB) ? int(but->hardmax) :
+ int(ui_but_value_get(but));
}
else if (but->optype) {
PointerRNA *opptr = UI_but_operator_ptr_get(but);
diff --git a/source/blender/editors/interface/interface_anim.cc b/source/blender/editors/interface/interface_anim.cc
index 4da6cefd8de..58a7ac93242 100644
--- a/source/blender/editors/interface/interface_anim.cc
+++ b/source/blender/editors/interface/interface_anim.cc
@@ -315,7 +315,7 @@ void ui_but_anim_paste_driver(bContext *C)
WM_operator_name_call(C, "ANIM_OT_paste_driver_button", WM_OP_INVOKE_DEFAULT, nullptr, nullptr);
}
-void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void *UNUSED(arg_dummy))
+void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void * /*arg_dummy*/)
{
wmWindowManager *wm = CTX_wm_manager(C);
uiButDecorator *but_decorate = static_cast<uiButDecorator *>(arg_but);
diff --git a/source/blender/editors/interface/interface_context_path.cc b/source/blender/editors/interface/interface_context_path.cc
index 3b91ca79c00..74a07d6edc8 100644
--- a/source/blender/editors/interface/interface_context_path.cc
+++ b/source/blender/editors/interface/interface_context_path.cc
@@ -17,6 +17,8 @@
#include "UI_interface.hh"
#include "UI_resources.h"
+#include "RNA_prototypes.h"
+
#include "WM_api.h"
namespace blender::ui {
@@ -41,7 +43,13 @@ void context_path_add_generic(Vector<ContextPathItem> &path,
static_cast<BIFIconID>(RNA_struct_ui_icon(rna_ptr.type)) :
icon_override;
- path.append({name, static_cast<int>(icon)});
+ if (&rna_type == &RNA_NodeTree) {
+ ID *id = (ID *)ptr;
+ path.append({name, int(icon), ID_REAL_USERS(id)});
+ }
+ else {
+ path.append({name, int(icon), 1});
+ }
}
/* -------------------------------------------------------------------- */
@@ -60,7 +68,9 @@ void template_breadcrumbs(uiLayout &layout, Span<ContextPathItem> context_path)
if (i > 0) {
uiItemL(sub_row, "", ICON_RIGHTARROW_THIN);
}
- uiItemL(sub_row, context_path[i].name.c_str(), context_path[i].icon);
+ uiBut *but = uiItemL_ex(
+ sub_row, context_path[i].name.c_str(), context_path[i].icon, false, false);
+ UI_but_icon_indicator_number_set(but, context_path[i].icon_indicator_number);
}
}
diff --git a/source/blender/editors/interface/interface_drag.cc b/source/blender/editors/interface/interface_drag.cc
index 4bf2dac4151..e959986d19e 100644
--- a/source/blender/editors/interface/interface_drag.cc
+++ b/source/blender/editors/interface/interface_drag.cc
@@ -27,15 +27,14 @@ void UI_but_drag_attach_image(uiBut *but, struct ImBuf *imb, const float scale)
}
void UI_but_drag_set_asset(uiBut *but,
- const AssetHandle *asset,
+ const AssetHandle *asset_handle,
const char *path,
- struct AssetMetaData *metadata,
int import_type,
int icon,
struct ImBuf *imb,
float scale)
{
- wmDragAsset *asset_drag = WM_drag_create_asset_data(asset, metadata, path, import_type);
+ wmDragAsset *asset_drag = WM_drag_create_asset_data(asset_handle, path, import_type);
/* FIXME: This is temporary evil solution to get scene/view-layer/etc in the copy callback of the
* #wmDropBox.
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 190830568e3..f1a324c411a 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -2307,9 +2307,6 @@ void UI_draw_box_shadow(const rctf *rect, uchar alpha)
void ui_draw_dropshadow(
const rctf *rct, float radius, float aspect, float alpha, int UNUSED(select))
{
- const float max_radius = (BLI_rctf_size_y(rct) - 10.0f) * 0.5f;
- const float rad = min_ff(radius, max_radius);
-
/* This undoes the scale of the view for higher zoom factors to clamp the shadow size. */
const float clamped_aspect = smoothminf(aspect, 1.0f, 0.5f);
@@ -2317,6 +2314,9 @@ void ui_draw_dropshadow(
const float shadow_offset = 0.5f * U.widget_unit * clamped_aspect;
const float shadow_alpha = 0.5f * alpha;
+ const float max_radius = (BLI_rctf_size_y(rct) - shadow_offset) * 0.5f;
+ const float rad = min_ff(radius, max_radius);
+
GPU_blend(GPU_BLEND_ALPHA);
uiWidgetBaseParameters widget_params = {
diff --git a/source/blender/editors/interface/interface_dropboxes.cc b/source/blender/editors/interface/interface_dropboxes.cc
index b72d8d2c238..60e1c0abfa1 100644
--- a/source/blender/editors/interface/interface_dropboxes.cc
+++ b/source/blender/editors/interface/interface_dropboxes.cc
@@ -41,10 +41,7 @@ static bool ui_view_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
return UI_view_item_can_drop(hovered_item, drag, &drag->drop_state.disabled_info);
}
-static char *ui_view_drop_tooltip(bContext *C,
- wmDrag *drag,
- const int xy[2],
- wmDropBox *UNUSED(drop))
+static char *ui_view_drop_tooltip(bContext *C, wmDrag *drag, const int xy[2], wmDropBox * /*drop*/)
{
const ARegion *region = CTX_wm_region(C);
const uiViewItemHandle *hovered_item = UI_region_views_find_item_at(region, xy);
@@ -61,12 +58,12 @@ static char *ui_view_drop_tooltip(bContext *C,
/** \name Name Drag/Drop Callbacks
* \{ */
-static bool ui_drop_name_poll(struct bContext *C, wmDrag *drag, const wmEvent *UNUSED(event))
+static bool ui_drop_name_poll(struct bContext *C, wmDrag *drag, const wmEvent * /*event*/)
{
return UI_but_active_drop_name(C) && (drag->type == WM_DRAG_ID);
}
-static void ui_drop_name_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
+static void ui_drop_name_copy(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
{
const ID *id = WM_drag_get_local_ID(drag, 0);
RNA_string_set(drop->ptr, "string", id->name + 2);
@@ -78,22 +75,22 @@ static void ui_drop_name_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop
/** \name Material Drag/Drop Callbacks
* \{ */
-static bool ui_drop_material_poll(bContext *C, wmDrag *drag, const wmEvent *UNUSED(event))
+static bool ui_drop_material_poll(bContext *C, wmDrag *drag, const wmEvent * /*event*/)
{
PointerRNA mat_slot = CTX_data_pointer_get_type(C, "material_slot", &RNA_MaterialSlot);
return WM_drag_is_ID_type(drag, ID_MA) && !RNA_pointer_is_null(&mat_slot);
}
-static void ui_drop_material_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
+static void ui_drop_material_copy(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
{
const ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, ID_MA);
- RNA_int_set(drop->ptr, "session_uuid", (int)id->session_uuid);
+ RNA_int_set(drop->ptr, "session_uuid", int(id->session_uuid));
}
static char *ui_drop_material_tooltip(bContext *C,
wmDrag *drag,
- const int UNUSED(xy[2]),
- struct wmDropBox *UNUSED(drop))
+ const int /*xy*/[2],
+ struct wmDropBox * /*drop*/)
{
PointerRNA rna_ptr = CTX_data_pointer_get_type(C, "object", &RNA_Object);
Object *ob = (Object *)rna_ptr.data;
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 6ee421fb4d2..ac16d41dabe 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -959,7 +959,7 @@ static void ui_apply_but_undo(uiBut *but)
str = "";
}
- /* delayed, after all other funcs run, popups are closed, etc */
+ /* Delayed, after all other functions run, popups are closed, etc. */
uiAfterFunc *after = ui_afterfunc_new();
BLI_strncpy(after->undostr, str, min_zz(str_len_clip + 1, sizeof(after->undostr)));
}
@@ -991,7 +991,7 @@ static void ui_apply_but_autokey(bContext *C, uiBut *but)
static void ui_apply_but_funcs_after(bContext *C)
{
- /* copy to avoid recursive calls */
+ /* Copy to avoid recursive calls. */
ListBase funcs = UIAfterFuncs;
BLI_listbase_clear(&UIAfterFuncs);
@@ -1118,9 +1118,6 @@ static void ui_apply_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data)
}
else {
value_toggle = (value == 0.0);
- if (ELEM(but->type, UI_BTYPE_TOGGLE_N, UI_BTYPE_ICON_TOGGLE_N, UI_BTYPE_CHECKBOX_N)) {
- value_toggle = !value_toggle;
- }
}
ui_but_value_set(but, (double)value_toggle);
@@ -3017,23 +3014,6 @@ static bool ui_textedit_delete_selection(uiBut *but, uiHandleButtonData *data)
return changed;
}
-static bool ui_textedit_set_cursor_pos_foreach_glyph(const char *UNUSED(str),
- const size_t str_step_ofs,
- const rcti *glyph_step_bounds,
- const int UNUSED(glyph_advance_x),
- const rcti *glyph_bounds,
- const int UNUSED(glyph_bearing[2]),
- void *user_data)
-{
- int *cursor_data = user_data;
- const int center = glyph_step_bounds->xmin + (BLI_rcti_size_x(glyph_bounds) / 2.0f);
- if (cursor_data[0] < center) {
- cursor_data[1] = str_step_ofs;
- return false;
- }
- return true;
-}
-
/**
* \param x: Screen space cursor location - #wmEvent.x
*
@@ -3064,7 +3044,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con
startx += UI_DPI_ICON_SIZE / aspect;
}
}
- startx += (UI_TEXT_MARGIN_X * U.widget_unit) / aspect;
+ startx += (UI_TEXT_MARGIN_X * U.widget_unit - U.pixelsize) / aspect;
/* mouse dragged outside the widget to the left */
if (x < startx) {
@@ -3088,23 +3068,8 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con
}
/* mouse inside the widget, mouse coords mapped in widget space */
else {
- str_last = &str[but->ofs];
- const int str_last_len = strlen(str_last);
- const int x_pos = (int)(x - startx);
- int glyph_data[2] = {
- x_pos, /* horizontal position to test. */
- -1, /* Write the character offset here. */
- };
- BLF_boundbox_foreach_glyph(fstyle.uifont_id,
- str + but->ofs,
- INT_MAX,
- ui_textedit_set_cursor_pos_foreach_glyph,
- glyph_data);
- /* If value untouched then we are to the right. */
- if (glyph_data[1] == -1) {
- glyph_data[1] = str_last_len;
- }
- but->pos = glyph_data[1] + but->ofs;
+ but->pos = but->ofs + BLF_str_offset_from_cursor_position(
+ fstyle.uifont_id, str + but->ofs, INT_MAX, (int)(x - startx));
}
ui_but_text_password_hide(password_str, but, true);
@@ -3554,7 +3519,7 @@ static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data)
static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonData *data)
{
- /* label and roundbox can overlap real buttons (backdrops...) */
+ /* Label and round-box can overlap real buttons (backdrops...). */
if (ELEM(actbut->type,
UI_BTYPE_LABEL,
UI_BTYPE_SEPR,
@@ -3586,7 +3551,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonData *data)
{
- /* label and roundbox can overlap real buttons (backdrops...) */
+ /* Label and round-box can overlap real buttons (backdrops...). */
if (ELEM(actbut->type,
UI_BTYPE_LABEL,
UI_BTYPE_SEPR,
@@ -3929,7 +3894,7 @@ static void ui_do_but_textedit(
}
if (event->type == WM_IME_COMPOSITE_EVENT && ime_data->result_len) {
if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER) &&
- strcmp(ime_data->str_result, "\xE3\x80\x82") == 0) {
+ STREQ(ime_data->str_result, "\xE3\x80\x82")) {
/* Convert Ideographic Full Stop (U+3002) to decimal point when entering numbers. */
ui_textedit_insert_ascii(but, data, '.');
}
@@ -4646,7 +4611,7 @@ static int ui_do_but_TEX(
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, EVT_PADENTER, EVT_RETKEY) &&
event->val == KM_PRESS) {
- if (ELEM(event->type, EVT_PADENTER, EVT_RETKEY) && (!UI_but_is_utf8(but))) {
+ if (ELEM(event->type, EVT_PADENTER, EVT_RETKEY) && !UI_but_is_utf8(but)) {
/* pass - allow filesel, enter to execute */
}
else if (ELEM(but->emboss, UI_EMBOSS_NONE, UI_EMBOSS_NONE_OR_STATUS) &&
@@ -5172,7 +5137,7 @@ static bool ui_numedit_but_NUM(uiButNumber *number_but,
CLAMP_MIN(non_linear_scale, 0.5f * UI_DPI_FAC);
}
- data->dragf += (((float)(mx - data->draglastx)) / deler) * non_linear_scale;
+ data->dragf += ((float)(mx - data->draglastx) / deler) * non_linear_scale;
if (but->softmin == softmin) {
CLAMP_MIN(data->dragf, 0.0f);
@@ -5797,7 +5762,7 @@ static int ui_do_but_SLI(
else
#endif
{
- f = (float)(mx - but->rect.xmin) / (BLI_rctf_size_x(&but->rect));
+ f = (float)(mx - but->rect.xmin) / BLI_rctf_size_x(&but->rect);
}
if (scale_type == PROP_SCALE_LOG) {
@@ -6004,7 +5969,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co
}
}
#ifdef USE_DRAG_TOGGLE
- if (event->type == LEFTMOUSE && event->val == KM_PRESS && (ui_but_is_drag_toggle(but))) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS && ui_but_is_drag_toggle(but)) {
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
data->dragstartx = event->xy[0];
data->dragstarty = event->xy[1];
@@ -6152,7 +6117,7 @@ static bool ui_numedit_but_UNITVEC(
* do this in "angle" space - this gives increments of same size */
for (int i = 0; i < 3; i++) {
angle = asinf(fp[i]);
- angle_snap = roundf((angle / snap_steps_angle)) * snap_steps_angle;
+ angle_snap = roundf(angle / snap_steps_angle) * snap_steps_angle;
fp[i] = sinf(angle_snap);
}
normalize_v3(fp);
@@ -7008,7 +6973,7 @@ static bool ui_numedit_but_COLORBAND(uiBut *but, uiHandleButtonData *data, int m
return changed;
}
- const float dx = ((float)(mx - data->draglastx)) / BLI_rctf_size_x(&but->rect);
+ const float dx = (float)(mx - data->draglastx) / BLI_rctf_size_x(&but->rect);
data->dragcbd->pos += dx;
CLAMP(data->dragcbd->pos, 0.0f, 1.0f);
@@ -7034,7 +6999,7 @@ static int ui_do_but_COLORBAND(
if (event->modifier & KM_CTRL) {
/* insert new key on mouse location */
- const float pos = ((float)(mx - but->rect.xmin)) / BLI_rctf_size_x(&but->rect);
+ const float pos = (float)(mx - but->rect.xmin) / BLI_rctf_size_x(&but->rect);
BKE_colorband_element_add(coba, pos);
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
@@ -9585,8 +9550,8 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *regi
else if (val == KM_PRESS) {
if ((ELEM(type, EVT_UPARROWKEY, EVT_DOWNARROWKEY, EVT_LEFTARROWKEY, EVT_RIGHTARROWKEY) &&
(event->modifier & (KM_SHIFT | KM_CTRL | KM_ALT | KM_OSKEY)) == 0) ||
- ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && (event->modifier & KM_CTRL) &&
- (event->modifier & (KM_SHIFT | KM_ALT | KM_OSKEY)) == 0))) {
+ (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && (event->modifier & KM_CTRL) &&
+ (event->modifier & (KM_SHIFT | KM_ALT | KM_OSKEY)) == 0)) {
const int value_orig = RNA_property_int_get(&listbox->rnapoin, listbox->rnaprop);
int value, min, max;
@@ -10839,7 +10804,7 @@ static int ui_handle_menu_return_submenu(bContext *C,
static bool ui_but_pie_menu_supported_apply(uiBut *but)
{
- return (!ELEM(but->type, UI_BTYPE_NUM_SLIDER, UI_BTYPE_NUM));
+ return !ELEM(but->type, UI_BTYPE_NUM_SLIDER, UI_BTYPE_NUM);
}
static int ui_but_pie_menu_apply(bContext *C,
@@ -11113,7 +11078,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle
case EVT_XKEY:
case EVT_YKEY:
case EVT_ZKEY: {
- if ((ELEM(event->val, KM_PRESS, KM_DBL_CLICK)) &&
+ if (ELEM(event->val, KM_PRESS, KM_DBL_CLICK) &&
((event->modifier & (KM_SHIFT | KM_CTRL | KM_OSKEY)) == 0)) {
LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but->menu_key == event->type) {
@@ -11380,9 +11345,9 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE
(ui_region_find_active_but(data->menu->region) == NULL) &&
/* make sure mouse isn't inside another menu (see T43247) */
(ui_screen_region_find_mouse_over(screen, event) == NULL) &&
- (ELEM(but->type, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER, UI_BTYPE_MENU)) &&
+ ELEM(but->type, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER, UI_BTYPE_MENU) &&
(but_other = ui_but_find_mouse_over(region, event)) && (but != but_other) &&
- (ELEM(but_other->type, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER, UI_BTYPE_MENU)) &&
+ ELEM(but_other->type, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER, UI_BTYPE_MENU) &&
/* Hover-opening menu's doesn't work well for buttons over one another
* along the same axis the menu is opening on (see T71719). */
(((data->menu->direction & (UI_DIR_LEFT | UI_DIR_RIGHT)) &&
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index ad2c08194aa..a5e2cd02f3b 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -415,8 +415,15 @@ static void vicon_collection_color_draw(
const float aspect = (float)ICON_DEFAULT_WIDTH / (float)w;
- UI_icon_draw_ex(
- x, y, ICON_OUTLINER_COLLECTION, aspect, 1.0f, 0.0f, collection_color->color, true);
+ UI_icon_draw_ex(x,
+ y,
+ ICON_OUTLINER_COLLECTION,
+ aspect,
+ 1.0f,
+ 0.0f,
+ collection_color->color,
+ true,
+ UI_NO_ICON_OVERLAY_TEXT);
}
# define DEF_ICON_COLLECTION_COLOR_DRAW(index, color) \
@@ -444,7 +451,8 @@ static void vicon_strip_color_draw(
const float aspect = (float)ICON_DEFAULT_WIDTH / (float)w;
- UI_icon_draw_ex(x, y, ICON_SNAP_FACE, aspect, 1.0f, 0.0f, strip_color->color, true);
+ UI_icon_draw_ex(
+ x, y, ICON_SNAP_FACE, aspect, 1.0f, 0.0f, strip_color->color, true, UI_NO_ICON_OVERLAY_TEXT);
}
# define DEF_ICON_STRIP_COLOR_DRAW(index, color) \
@@ -472,8 +480,15 @@ static void vicon_strip_color_draw_library_data_indirect(
{
const float aspect = (float)ICON_DEFAULT_WIDTH / (float)w;
- UI_icon_draw_ex(
- x, y, ICON_LIBRARY_DATA_DIRECT, aspect, ICON_INDIRECT_DATA_ALPHA * alpha, 0.0f, NULL, false);
+ UI_icon_draw_ex(x,
+ y,
+ ICON_LIBRARY_DATA_DIRECT,
+ aspect,
+ ICON_INDIRECT_DATA_ALPHA * alpha,
+ 0.0f,
+ NULL,
+ false,
+ UI_NO_ICON_OVERLAY_TEXT);
}
static void vicon_strip_color_draw_library_data_override_noneditable(
@@ -488,7 +503,8 @@ static void vicon_strip_color_draw_library_data_override_noneditable(
ICON_INDIRECT_DATA_ALPHA * alpha * 0.75f,
0.0f,
NULL,
- false);
+ false,
+ UI_NO_ICON_OVERLAY_TEXT);
}
/* Dynamically render icon instead of rendering a plain color to a texture/buffer
@@ -821,7 +837,7 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf,
blend_color_interpolate_float(dest_rgba, orig_rgba, border_rgba, 1.0 - orig_rgba[3]);
linearrgb_to_srgb_v4(dest_srgb, dest_rgba);
- const uint alpha_mask = ((uint)(dest_srgb[3] * 255)) << 24;
+ const uint alpha_mask = (uint)(dest_srgb[3] * 255) << 24;
const uint cpack = rgb_to_cpack(dest_srgb[0], dest_srgb[1], dest_srgb[2]) | alpha_mask;
result->rect[offset_write] = cpack;
}
@@ -923,7 +939,7 @@ static void init_internal_icons(void)
char iconfilestr[FILE_MAX];
if (icondir) {
- BLI_join_dirfile(iconfilestr, sizeof(iconfilestr), icondir, btheme->tui.iconfile);
+ BLI_path_join(iconfilestr, sizeof(iconfilestr), icondir, btheme->tui.iconfile);
/* if the image is missing bbuf will just be NULL */
bbuf = IMB_loadiffname(iconfilestr, IB_rect, NULL);
@@ -1047,7 +1063,7 @@ static void init_iconfile_list(struct ListBase *list)
/* check to see if the image is the right size, continue if not */
/* copying strings here should go ok, assuming that we never get back
* a complete path to file longer than 256 chars */
- BLI_join_dirfile(iconfilestr, sizeof(iconfilestr), icondir, filename);
+ BLI_path_join(iconfilestr, sizeof(iconfilestr), icondir, filename);
bbuf = IMB_loadiffname(iconfilestr, IB_rect);
if (bbuf) {
@@ -1293,8 +1309,8 @@ static void ui_id_preview_image_render_size(
const bContext *C, Scene *scene, ID *id, PreviewImage *pi, int size, const bool use_job);
static void ui_studiolight_icon_job_exec(void *customdata,
- short *UNUSED(stop),
- short *UNUSED(do_update),
+ bool *UNUSED(stop),
+ bool *UNUSED(do_update),
float *UNUSED(progress))
{
Icon **tmp = (Icon **)customdata;
@@ -1716,9 +1732,47 @@ static void icon_draw_texture(float x,
int ih,
float alpha,
const float rgb[3],
- bool with_border)
-{
- if (g_icon_draw_cache.enabled) {
+ bool with_border,
+ const IconTextOverlay *text_overlay)
+{
+ const float zoom_factor = w / UI_DPI_ICON_SIZE;
+ float text_width = 0.0f;
+
+ /* No need to show if too zoomed out, otherwise it just adds noise. */
+ const bool show_indicator = (text_overlay && text_overlay->text[0] != '\0') &&
+ (zoom_factor > 0.7f);
+
+ if (show_indicator) {
+ /* Handle the little numbers on top of the icon. */
+ uchar text_color[4];
+ UI_GetThemeColor3ubv(TH_TEXT, text_color);
+ text_color[3] = 255;
+
+ uiFontStyle fstyle_small = *UI_FSTYLE_WIDGET;
+ fstyle_small.points *= zoom_factor;
+ fstyle_small.points *= 0.8f;
+
+ rcti text_rect = {
+ .xmax = x + UI_UNIT_X * zoom_factor,
+ .xmin = x,
+ .ymax = y,
+ .ymin = y,
+ };
+
+ UI_fontstyle_draw(&fstyle_small,
+ &text_rect,
+ text_overlay->text,
+ sizeof(text_overlay->text),
+ text_color,
+ &(struct uiFontStyleDraw_Params){
+ .align = UI_STYLE_TEXT_RIGHT,
+ });
+ text_width = (float)UI_fontstyle_string_width(&fstyle_small, text_overlay->text) / UI_UNIT_X /
+ zoom_factor;
+ }
+
+ /* Draw the actual icon. */
+ if (!show_indicator && g_icon_draw_cache.enabled) {
icon_draw_texture_cached(x, y, w, h, ix, iy, iw, ih, alpha, rgb, with_border);
return;
}
@@ -1735,7 +1789,7 @@ static void icon_draw_texture(float x,
GPUTexture *texture = with_border ? icongltex.tex[1] : icongltex.tex[0];
- GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
+ GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_ICON);
GPU_shader_bind(shader);
const int img_binding = GPU_shader_get_texture_binding(shader, "image");
@@ -1752,6 +1806,7 @@ static void icon_draw_texture(float x,
GPU_shader_uniform_vector(shader, rect_tex_loc, 4, 1, (float[4]){x1, y1, x2, y2});
GPU_shader_uniform_vector(shader, rect_geom_loc, 4, 1, (float[4]){x, y, x + w, y + h});
+ GPU_shader_uniform_1f(shader, "text_width", text_width);
GPU_texture_bind_ex(texture, GPU_SAMPLER_ICON, img_binding, false);
@@ -1786,7 +1841,8 @@ static void icon_draw_size(float x,
int draw_size,
const float desaturate,
const uchar mono_rgba[4],
- const bool mono_border)
+ const bool mono_border,
+ const IconTextOverlay *text_overlay)
{
bTheme *btheme = UI_GetTheme();
const float fdraw_size = (float)draw_size;
@@ -1874,7 +1930,8 @@ static void icon_draw_size(float x,
di->data.texture.h,
alpha,
NULL,
- false);
+ false,
+ text_overlay);
}
else if (di->type == ICON_TYPE_MONO_TEXTURE) {
/* Monochrome icon that uses text or theme color. */
@@ -1908,7 +1965,8 @@ static void icon_draw_size(float x,
di->data.texture.h + 2 * border_texel,
color[3],
color,
- with_border);
+ with_border,
+ text_overlay);
}
else if (di->type == ICON_TYPE_BUFFER) {
@@ -1956,7 +2014,7 @@ static void ui_id_preview_image_render_size(
const bContext *C, Scene *scene, ID *id, PreviewImage *pi, int size, const bool use_job)
{
/* changed only ever set by dynamic icons */
- if (((pi->flag[size] & PRV_CHANGED) || !pi->rect[size])) {
+ if ((pi->flag[size] & PRV_CHANGED) || !pi->rect[size]) {
/* create the rect if necessary */
icon_set_image(C, scene, id, pi, size, use_job);
@@ -2425,17 +2483,27 @@ int UI_icon_color_from_collection(const Collection *collection)
void UI_icon_draw(float x, float y, int icon_id)
{
- UI_icon_draw_ex(x, y, icon_id, U.inv_dpi_fac, 1.0f, 0.0f, NULL, false);
+ UI_icon_draw_ex(x, y, icon_id, U.inv_dpi_fac, 1.0f, 0.0f, NULL, false, UI_NO_ICON_OVERLAY_TEXT);
}
void UI_icon_draw_alpha(float x, float y, int icon_id, float alpha)
{
- UI_icon_draw_ex(x, y, icon_id, U.inv_dpi_fac, alpha, 0.0f, NULL, false);
+ UI_icon_draw_ex(x, y, icon_id, U.inv_dpi_fac, alpha, 0.0f, NULL, false, UI_NO_ICON_OVERLAY_TEXT);
}
void UI_icon_draw_preview(float x, float y, int icon_id, float aspect, float alpha, int size)
{
- icon_draw_size(x, y, icon_id, aspect, alpha, ICON_SIZE_PREVIEW, size, false, NULL, false);
+ icon_draw_size(x,
+ y,
+ icon_id,
+ aspect,
+ alpha,
+ ICON_SIZE_PREVIEW,
+ size,
+ false,
+ NULL,
+ false,
+ UI_NO_ICON_OVERLAY_TEXT);
}
void UI_icon_draw_ex(float x,
@@ -2445,7 +2513,8 @@ void UI_icon_draw_ex(float x,
float alpha,
float desaturate,
const uchar mono_color[4],
- const bool mono_border)
+ const bool mono_border,
+ const IconTextOverlay *text_overlay)
{
const int draw_size = get_draw_size(ICON_SIZE_ICON);
icon_draw_size(x,
@@ -2457,7 +2526,19 @@ void UI_icon_draw_ex(float x,
draw_size,
desaturate,
mono_color,
- mono_border);
+ mono_border,
+ text_overlay);
+}
+
+void UI_icon_text_overlay_init_from_count(IconTextOverlay *text_overlay,
+ const int icon_indicator_number)
+{
+ /* The icon indicator is used as an aggregator, no need to show if it is 1. */
+ if (icon_indicator_number < 2) {
+ text_overlay->text[0] = '\0';
+ return;
+ }
+ BLI_str_format_integer_unit(text_overlay->text, icon_indicator_number);
}
/* ********** Alert Icons ********** */
diff --git a/source/blender/editors/interface/interface_icons_event.c b/source/blender/editors/interface/interface_icons_event.c
index e892a989191..b5cbc92741e 100644
--- a/source/blender/editors/interface/interface_icons_event.c
+++ b/source/blender/editors/interface/interface_icons_event.c
@@ -66,7 +66,7 @@ static void icon_draw_rect_input_text(
BLF_batch_draw_flush();
const int font_id = BLF_default();
BLF_color4fv(font_id, color);
- BLF_size(font_id, font_size * U.pixelsize, U.dpi);
+ BLF_size(font_id, font_size * U.dpi_fac);
float width, height;
BLF_width_and_height(font_id, str, BLF_DRAW_STR_DUMMY_MAX, &width, &height);
const float x = trunc(rect->xmin + (((rect->xmax - rect->xmin) - width) / 2.0f));
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 0c842084de6..982ac1753e1 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -23,6 +23,7 @@ struct ARegion;
struct AnimationEvalContext;
struct CurveMapping;
struct CurveProfile;
+struct IconTextOverlay;
struct ID;
struct ImBuf;
struct Main;
@@ -275,6 +276,9 @@ struct uiBut {
uiButPushedStateFunc pushed_state_func;
const void *pushed_state_arg;
+ /** Little indicator (e.g., counter) displayed on top of some icons. */
+ struct IconTextOverlay icon_overlay_text;
+
/* pointer back */
uiBlock *block;
};
@@ -307,6 +311,8 @@ typedef struct uiButSearch {
uiButSearchCreateFn popup_create_fn;
uiButSearchUpdateFn items_update_fn;
+ uiButSearchListenFn listen_fn;
+
void *item_active;
void *arg;
@@ -471,6 +477,12 @@ typedef enum uiButtonGroupFlag {
} uiButtonGroupFlag;
ENUM_OPERATORS(uiButtonGroupFlag, UI_BUTTON_GROUP_PANEL_HEADER);
+typedef struct uiBlockDynamicListener {
+ struct uiBlockDynamicListener *next, *prev;
+
+ void (*listener_func)(const struct wmRegionListenerParams *params);
+} uiBlockDynamicListener;
+
struct uiBlock {
uiBlock *next, *prev;
@@ -493,6 +505,8 @@ struct uiBlock {
* state that is persistent over redraws (e.g. collapsed tree-view items). */
ListBase views;
+ ListBase dynamic_listeners; /* #uiBlockDynamicListener */
+
char name[UI_MAX_NAME_STR];
float winmat[4][4];
@@ -1534,6 +1548,8 @@ void ui_interface_tag_script_reload_queries(void);
/* interface_view.cc */
void ui_block_free_views(struct uiBlock *block);
+void ui_block_views_listen(const uiBlock *block,
+ const struct wmRegionListenerParams *listener_params);
uiViewHandle *ui_block_view_find_matching_in_old_block(const uiBlock *new_block,
const uiViewHandle *new_view);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 2f91461c89b..ad74328e8fc 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -694,7 +694,7 @@ static void ui_item_array(uiLayout *layout,
else {
/* Even if 'expand' is false, we expand anyway. */
- /* layout for known array subtypes */
+ /* Layout for known array sub-types. */
char str[3] = {'\0'};
if (!icon_only && show_text) {
@@ -2112,11 +2112,11 @@ void uiItemFullR(uiLayout *layout,
icon = ICON_CHECKBOX_DEHLT; /* but->iconadd will set to correct icon */
}
else if (is_array) {
- icon = (RNA_property_boolean_get_index(ptr, prop, index)) ? ICON_CHECKBOX_HLT :
- ICON_CHECKBOX_DEHLT;
+ icon = RNA_property_boolean_get_index(ptr, prop, index) ? ICON_CHECKBOX_HLT :
+ ICON_CHECKBOX_DEHLT;
}
else {
- icon = (RNA_property_boolean_get(ptr, prop)) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
+ icon = RNA_property_boolean_get(ptr, prop) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
}
}
}
@@ -3235,7 +3235,7 @@ static uiBut *uiItemL_(uiLayout *layout, const char *name, int icon)
return but;
}
-void uiItemL_ex(
+uiBut *uiItemL_ex(
uiLayout *layout, const char *name, int icon, const bool highlight, const bool redalert)
{
uiBut *but = uiItemL_(layout, name, icon);
@@ -3248,6 +3248,8 @@ void uiItemL_ex(
if (redalert) {
UI_but_flag_enable(but, UI_BUT_REDALERT);
}
+
+ return but;
}
void uiItemL(uiLayout *layout, const char *name, int icon)
@@ -5812,6 +5814,14 @@ void UI_menutype_draw(bContext *C, MenuType *mt, struct uiLayout *layout)
printf("%s: opening menu \"%s\"\n", __func__, mt->idname);
}
+ if (mt->listener) {
+ /* Forward the menu type listener to the block we're drawing in. */
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiBlockDynamicListener *listener = MEM_mallocN(sizeof(*listener), "uiBlockDynamicListener");
+ listener->listener_func = mt->listener;
+ BLI_addtail(&block->dynamic_listeners, listener);
+ }
+
if (layout->context) {
CTX_store_set(C, layout->context);
}
diff --git a/source/blender/editors/interface/interface_ops.cc b/source/blender/editors/interface/interface_ops.cc
index a5b0193a86d..2d06dd2c465 100644
--- a/source/blender/editors/interface/interface_ops.cc
+++ b/source/blender/editors/interface/interface_ops.cc
@@ -270,7 +270,7 @@ static bool copy_python_command_button_poll(bContext *C)
return false;
}
-static int copy_python_command_button_exec(bContext *C, wmOperator *UNUSED(op))
+static int copy_python_command_button_exec(bContext *C, wmOperator * /*op*/)
{
uiBut *but = UI_context_active_but_get(C);
@@ -421,7 +421,7 @@ static bool assign_default_button_poll(bContext *C)
return false;
}
-static int assign_default_button_exec(bContext *C, wmOperator *UNUSED(op))
+static int assign_default_button_exec(bContext *C, wmOperator * /*op*/)
{
PointerRNA ptr;
PropertyRNA *prop;
@@ -461,7 +461,7 @@ static void UI_OT_assign_default_button(wmOperatorType *ot)
/** \name Unset Property Button Operator
* \{ */
-static int unset_property_button_exec(bContext *C, wmOperator *UNUSED(op))
+static int unset_property_button_exec(bContext *C, wmOperator * /*op*/)
{
PointerRNA ptr;
PropertyRNA *prop;
@@ -609,9 +609,7 @@ static int override_type_set_button_exec(bContext *C, wmOperator *op)
return operator_button_property_finish(C, &ptr, prop);
}
-static int override_type_set_button_invoke(bContext *C,
- wmOperator *op,
- const wmEvent *UNUSED(event))
+static int override_type_set_button_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
#if 0 /* Disabled for now */
return WM_menu_invoke_ex(C, op, WM_OP_INVOKE_DEFAULT);
@@ -806,7 +804,7 @@ static bool override_idtemplate_make_poll(bContext *C)
return override_idtemplate_poll(C, true);
}
-static int override_idtemplate_make_exec(bContext *C, wmOperator *UNUSED(op))
+static int override_idtemplate_make_exec(bContext *C, wmOperator * /*op*/)
{
ID *owner_id, *id;
PointerRNA owner_ptr;
@@ -869,7 +867,7 @@ static bool override_idtemplate_reset_poll(bContext *C)
return override_idtemplate_poll(C, false);
}
-static int override_idtemplate_reset_exec(bContext *C, wmOperator *UNUSED(op))
+static int override_idtemplate_reset_exec(bContext *C, wmOperator * /*op*/)
{
ID *owner_id, *id;
PointerRNA owner_ptr;
@@ -917,7 +915,7 @@ static bool override_idtemplate_clear_poll(bContext *C)
return override_idtemplate_poll(C, false);
}
-static int override_idtemplate_clear_exec(bContext *C, wmOperator *UNUSED(op))
+static int override_idtemplate_clear_exec(bContext *C, wmOperator * /*op*/)
{
ID *owner_id, *id;
PointerRNA owner_ptr;
@@ -939,6 +937,7 @@ static int override_idtemplate_clear_exec(bContext *C, wmOperator *UNUSED(op))
if (BKE_lib_override_library_is_hierarchy_leaf(bmain, id)) {
id_new = id->override_library->reference;
bool do_remap_active = false;
+ BKE_view_layer_synced_ensure(scene, view_layer);
if (BKE_view_layer_active_object_get(view_layer) == (Object *)id) {
BLI_assert(GS(id->name) == ID_OB);
BLI_assert(GS(id_new->name) == ID_OB);
@@ -991,7 +990,7 @@ static void UI_OT_override_idtemplate_clear(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
}
-static bool override_idtemplate_menu_poll(const bContext *C_const, MenuType *UNUSED(mt))
+static bool override_idtemplate_menu_poll(const bContext *C_const, MenuType * /*mt*/)
{
bContext *C = (bContext *)C_const;
ID *owner_id, *id;
@@ -1007,7 +1006,7 @@ static bool override_idtemplate_menu_poll(const bContext *C_const, MenuType *UNU
return true;
}
-static void override_idtemplate_menu_draw(const bContext *UNUSED(C), Menu *menu)
+static void override_idtemplate_menu_draw(const bContext * /*C*/, Menu *menu)
{
uiLayout *layout = menu->layout;
uiItemO(layout, IFACE_("Make"), ICON_NONE, "UI_OT_override_idtemplate_make");
@@ -1502,14 +1501,16 @@ static bool jump_to_target_ptr(bContext *C, PointerRNA ptr, const bool poll)
}
/* Find the containing Object. */
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Base *base = nullptr;
const short id_type = GS(ptr.owner_id->name);
if (id_type == ID_OB) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
base = BKE_view_layer_base_find(view_layer, (Object *)ptr.owner_id);
}
else if (OB_DATA_SUPPORT_ID(id_type)) {
- base = ED_object_find_first_by_data_id(view_layer, ptr.owner_id);
+ base = ED_object_find_first_by_data_id(scene, view_layer, ptr.owner_id);
}
bool ok = false;
@@ -1577,7 +1578,7 @@ static bool jump_to_target_button(bContext *C, bool poll)
int found = 0;
/* Jump to target only works with search properties currently, not search callbacks yet.
* See ui_but_add_search. */
- if (coll_search->search_prop != NULL) {
+ if (coll_search->search_prop != nullptr) {
found = RNA_property_collection_lookup_string(
&coll_search->search_ptr, coll_search->search_prop, str_ptr, &target_ptr);
}
@@ -1601,7 +1602,7 @@ bool ui_jump_to_target_button_poll(bContext *C)
return jump_to_target_button(C, true);
}
-static int jump_to_target_button_exec(bContext *C, wmOperator *UNUSED(op))
+static int jump_to_target_button_exec(bContext *C, wmOperator * /*op*/)
{
const bool success = jump_to_target_button(C, false);
@@ -1632,7 +1633,7 @@ static void UI_OT_jump_to_target_button(wmOperatorType *ot)
#ifdef WITH_PYTHON
/* ------------------------------------------------------------------------- */
-/* EditSource Utility funcs and operator,
+/* EditSource Utility functions and operator,
* NOTE: this includes utility functions and button matching checks. */
struct uiEditSourceStore {
@@ -1844,7 +1845,7 @@ static void UI_OT_editsource(wmOperatorType *ot)
* \{ */
/**
- * EditTranslation utility funcs and operator,
+ * EditTranslation utility functions and operator.
*
* \note this includes utility functions and button matching checks.
* this only works in conjunction with a Python operator!
@@ -1858,8 +1859,7 @@ static void edittranslation_find_po_file(const char *root,
/* First, full lang code. */
BLI_snprintf(tstr, sizeof(tstr), "%s.po", uilng);
- BLI_join_dirfile(path, maxlen, root, uilng);
- BLI_path_append(path, maxlen, tstr);
+ BLI_path_join(path, maxlen, root, uilng, tstr);
if (BLI_is_file(path)) {
return;
}
@@ -1884,7 +1884,7 @@ static void edittranslation_find_po_file(const char *root,
BLI_strncpy(tstr + szt, tc, sizeof(tstr) - szt);
}
- BLI_join_dirfile(path, maxlen, root, tstr);
+ BLI_path_join(path, maxlen, root, tstr);
strcat(tstr, ".po");
BLI_path_append(path, maxlen, tstr);
if (BLI_is_file(path)) {
@@ -2030,7 +2030,7 @@ static void UI_OT_edittranslation_init(wmOperatorType *ot)
/** \name Reload Translation Operator
* \{ */
-static int reloadtranslation_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
+static int reloadtranslation_exec(bContext * /*C*/, wmOperator * /*op*/)
{
BLT_lang_init();
BLF_cache_clear();
@@ -2113,7 +2113,7 @@ static void UI_OT_button_execute(wmOperatorType *ot)
/** \name Text Button Clear Operator
* \{ */
-static int button_string_clear_exec(bContext *C, wmOperator *UNUSED(op))
+static int button_string_clear_exec(bContext *C, wmOperator * /*op*/)
{
uiBut *but = UI_context_active_but_get_respect_menu(C);
@@ -2141,7 +2141,7 @@ static void UI_OT_button_string_clear(wmOperatorType *ot)
/** \name Drop Color Operator
* \{ */
-bool UI_drop_color_poll(struct bContext *C, wmDrag *drag, const wmEvent *UNUSED(event))
+bool UI_drop_color_poll(struct bContext *C, wmDrag *drag, const wmEvent * /*event*/)
{
/* should only return true for regions that include buttons, for now
* return true always */
@@ -2162,7 +2162,7 @@ bool UI_drop_color_poll(struct bContext *C, wmDrag *drag, const wmEvent *UNUSED(
return false;
}
-void UI_drop_color_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
+void UI_drop_color_copy(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
{
uiDragColorHandle *drag_info = static_cast<uiDragColorHandle *>(drag->poin);
@@ -2260,7 +2260,7 @@ static bool drop_name_poll(bContext *C)
return true;
}
-static int drop_name_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int drop_name_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
uiBut *but = UI_but_active_drop_name_button(C);
char *str = RNA_string_get_alloc(op->ptr, "string", nullptr, 0, nullptr);
@@ -2320,7 +2320,7 @@ static bool ui_list_unhide_filter_options(uiList *list)
return true;
}
-static int ui_list_start_filter_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+static int ui_list_start_filter_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
uiList *list = UI_list_find_mouse_over(region, event);
@@ -2366,7 +2366,7 @@ static bool ui_view_drop_poll(bContext *C)
return hovered_item != nullptr;
}
-static int ui_view_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+static int ui_view_drop_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *event)
{
if (event->custom != EVT_DATA_DRAGDROP) {
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
@@ -2416,7 +2416,7 @@ static bool ui_view_item_rename_poll(bContext *C)
return active_item != nullptr && UI_view_item_can_rename(active_item);
}
-static int ui_view_item_rename_exec(bContext *C, wmOperator *UNUSED(op))
+static int ui_view_item_rename_exec(bContext *C, wmOperator * /*op*/)
{
ARegion *region = CTX_wm_region(C);
uiViewItemHandle *active_item = UI_region_views_find_active_item(region);
diff --git a/source/blender/editors/interface/interface_panel.cc b/source/blender/editors/interface/interface_panel.cc
index 745a2201dc1..05b6ecf29d5 100644
--- a/source/blender/editors/interface/interface_panel.cc
+++ b/source/blender/editors/interface/interface_panel.cc
@@ -142,7 +142,7 @@ static bool panel_active_animation_changed(ListBase *lb,
}
/* Detect changes in panel expansions. */
- if ((bool)(panel->runtime_flag & PANEL_WAS_CLOSED) != UI_panel_is_closed(panel)) {
+ if (bool(panel->runtime_flag & PANEL_WAS_CLOSED) != UI_panel_is_closed(panel)) {
*r_panel_animation = panel;
return false;
}
@@ -1112,7 +1112,8 @@ static void panel_draw_aligned_widgets(const uiStyle *style,
0.7f,
0.0f,
title_color,
- false);
+ false,
+ UI_NO_ICON_OVERLAY_TEXT);
GPU_blend(GPU_BLEND_NONE);
}
@@ -1140,7 +1141,8 @@ static void panel_draw_aligned_widgets(const uiStyle *style,
1.0f,
0.0f,
title_color,
- false);
+ false,
+ UI_NO_ICON_OVERLAY_TEXT);
GPU_blend(GPU_BLEND_NONE);
}
@@ -1232,7 +1234,7 @@ void ui_draw_aligned_panel(const uiStyle *style,
rect->xmin,
rect->xmax,
rect->ymax,
- rect->ymax + (int)floor(PNL_HEADER / block->aspect + 0.001f),
+ rect->ymax + int(floor(PNL_HEADER / block->aspect + 0.001f)),
};
if (show_background) {
@@ -1343,7 +1345,7 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active)
BLF_enable(fontid, BLF_ROTATION);
BLF_rotation(fontid, M_PI_2);
ui_fontscale(&fstyle_points, aspect);
- BLF_size(fontid, fstyle_points * U.pixelsize, U.dpi);
+ BLF_size(fontid, fstyle_points * U.dpi_fac);
/* Check the region type supports categories to avoid an assert
* for showing 3D view panels in the properties space. */
@@ -1368,7 +1370,7 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active)
}
if (y_ofs > BLI_rcti_size_y(&v2d->mask)) {
- scaletabs = (float)BLI_rcti_size_y(&v2d->mask) / (float)y_ofs;
+ scaletabs = float(BLI_rcti_size_y(&v2d->mask)) / float(y_ofs);
LISTBASE_FOREACH (PanelCategoryDyn *, pc_dyn, &region->panels_category) {
rcti *rct = &pc_dyn->rect;
@@ -1705,12 +1707,12 @@ static bool uiAlignPanelStep(ARegion *region, const float factor, const bool dra
}
if (ps->new_offset_x != ps->panel->ofsx) {
- const float x = interpf((float)ps->new_offset_x, (float)ps->panel->ofsx, factor);
+ const float x = interpf(float(ps->new_offset_x), float(ps->panel->ofsx), factor);
ps->panel->ofsx = round_fl_to_int(x);
changed = true;
}
if (ps->new_offset_y != ps->panel->ofsy) {
- const float y = interpf((float)ps->new_offset_y, (float)ps->panel->ofsy, factor);
+ const float y = interpf(float(ps->new_offset_y), float(ps->panel->ofsy), factor);
ps->panel->ofsy = round_fl_to_int(y);
changed = true;
}
@@ -1804,7 +1806,7 @@ static void panels_layout_begin_clear_flags(ListBase *lb)
}
}
-void UI_panels_begin(const bContext *UNUSED(C), ARegion *region)
+void UI_panels_begin(const bContext * /*C*/, ARegion *region)
{
/* Set all panels as inactive, so that at the end we know which ones were used. Also
* clear other flags so we know later that their values were set for the current redraw. */
@@ -1875,13 +1877,13 @@ static void ui_do_drag(const bContext *C, const wmEvent *event, Panel *panel)
/* Keep the drag position in the region with a small pad to keep the panel visible. */
const int y = clamp_i(event->xy[1], region->winrct.ymin, region->winrct.ymax + DRAG_REGION_PAD);
- float dy = (float)(y - data->starty);
+ float dy = float(y - data->starty);
/* Adjust for region zoom. */
- dy *= BLI_rctf_size_y(&region->v2d.cur) / (float)BLI_rcti_size_y(&region->winrct);
+ dy *= BLI_rctf_size_y(&region->v2d.cur) / float(BLI_rcti_size_y(&region->winrct));
/* Add the movement of the view due to edge scrolling while dragging. */
- dy += ((float)region->v2d.cur.ymin - data->start_cur_ymin);
+ dy += (float(region->v2d.cur.ymin) - data->start_cur_ymin);
panel->ofsy = data->startofsy + round_fl_to_int(dy);
@@ -1902,16 +1904,16 @@ static uiPanelMouseState ui_panel_mouse_state_get(const uiBlock *block,
const int mx,
const int my)
{
- if (!IN_RANGE((float)mx, block->rect.xmin, block->rect.xmax)) {
+ if (!IN_RANGE(float(mx), block->rect.xmin, block->rect.xmax)) {
return PANEL_MOUSE_OUTSIDE;
}
- if (IN_RANGE((float)my, block->rect.ymax, block->rect.ymax + PNL_HEADER)) {
+ if (IN_RANGE(float(my), block->rect.ymax, block->rect.ymax + PNL_HEADER)) {
return PANEL_MOUSE_INSIDE_HEADER;
}
if (!UI_panel_is_closed(panel)) {
- if (IN_RANGE((float)my, block->rect.ymin, block->rect.ymax + PNL_HEADER)) {
+ if (IN_RANGE(float(my), block->rect.ymin, block->rect.ymax + PNL_HEADER)) {
return PANEL_MOUSE_INSIDE_CONTENT;
}
}
@@ -1924,7 +1926,7 @@ struct uiPanelDragCollapseHandle {
int xy_init[2];
};
-static void ui_panel_drag_collapse_handler_remove(bContext *UNUSED(C), void *userdata)
+static void ui_panel_drag_collapse_handler_remove(bContext * /*C*/, void *userdata)
{
uiPanelDragCollapseHandle *dragcol_data = static_cast<uiPanelDragCollapseHandle *>(userdata);
MEM_freeN(dragcol_data);
@@ -1937,8 +1939,8 @@ static void ui_panel_drag_collapse(const bContext *C,
ARegion *region = CTX_wm_region(C);
LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
- float xy_a_block[2] = {(float)dragcol_data->xy_init[0], (float)dragcol_data->xy_init[1]};
- float xy_b_block[2] = {(float)xy_dst[0], (float)xy_dst[1]};
+ float xy_a_block[2] = {float(dragcol_data->xy_init[0]), float(dragcol_data->xy_init[1])};
+ float xy_b_block[2] = {float(xy_dst[0]), float(xy_dst[1])};
Panel *panel = block->panel;
if (panel == nullptr || (panel->type && (panel->type->flag & PANEL_TYPE_NO_HEADER))) {
@@ -2024,7 +2026,7 @@ static void ui_panel_drag_collapse_handler_add(const bContext *C, const bool was
ui_panel_drag_collapse_handler,
ui_panel_drag_collapse_handler_remove,
dragcol_data,
- 0);
+ eWM_EventHandlerFlag(0));
}
/**
@@ -2508,8 +2510,12 @@ static void panel_handle_data_ensure(const bContext *C,
{
if (panel->activedata == nullptr) {
panel->activedata = MEM_callocN(sizeof(uiHandlePanelData), __func__);
- WM_event_add_ui_handler(
- C, &win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, panel, 0);
+ WM_event_add_ui_handler(C,
+ &win->modalhandlers,
+ ui_handler_panel,
+ ui_handler_remove_panel,
+ panel,
+ eWM_EventHandlerFlag(0));
}
uiHandlePanelData *data = static_cast<uiHandlePanelData *>(panel->activedata);
diff --git a/source/blender/editors/interface/interface_query.cc b/source/blender/editors/interface/interface_query.cc
index f084f3e06cb..7ff6acee945 100644
--- a/source/blender/editors/interface/interface_query.cc
+++ b/source/blender/editors/interface/interface_query.cc
@@ -84,7 +84,7 @@ bool ui_but_is_interactive_ex(const uiBut *but, const bool labeledit, const bool
return false;
}
if ((but->type == UI_BTYPE_TEXT) &&
- (ELEM(but->emboss, UI_EMBOSS_NONE, UI_EMBOSS_NONE_OR_STATUS)) && !labeledit) {
+ ELEM(but->emboss, UI_EMBOSS_NONE, UI_EMBOSS_NONE_OR_STATUS) && !labeledit) {
return false;
}
if ((but->type == UI_BTYPE_LISTROW) && labeledit) {
@@ -103,7 +103,7 @@ bool UI_but_is_utf8(const uiBut *but)
{
if (but->rnaprop) {
const int subtype = RNA_property_subtype(but->rnaprop);
- return !(ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME, PROP_BYTESTRING));
+ return !ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME, PROP_BYTESTRING);
}
return !(but->flag & UI_BUT_NO_UTF8);
}
@@ -182,7 +182,7 @@ void ui_but_pie_dir(RadialDirection dir, float vec[2])
BLI_assert(dir != UI_RADIAL_NONE);
- angle = DEG2RADF((float)ui_radial_dir_to_angle[dir]);
+ angle = DEG2RADF(float(ui_radial_dir_to_angle[dir]));
vec[0] = cosf(angle);
vec[1] = sinf(angle);
}
@@ -251,7 +251,7 @@ bool ui_but_contains_point_px_icon(const uiBut *but, ARegion *region, const wmEv
/* use button size itself */
}
else if (but->drawflag & UI_BUT_ICON_LEFT) {
- rect.xmax = rect.xmin + (BLI_rcti_size_y(&rect));
+ rect.xmax = rect.xmin + BLI_rcti_size_y(&rect);
}
else {
const int delta = BLI_rcti_size_x(&rect) - BLI_rcti_size_y(&rect);
@@ -424,7 +424,7 @@ uiBut *ui_list_find_from_row(const ARegion *region, const uiBut *row_but)
return ui_but_find(region, ui_but_is_listbox_with_row, row_but);
}
-static bool ui_but_is_listrow(const uiBut *but, const void *UNUSED(customdata))
+static bool ui_but_is_listrow(const uiBut *but, const void * /*customdata*/)
{
return but->type == UI_BTYPE_LISTROW;
}
@@ -456,7 +456,7 @@ uiBut *ui_list_row_find_from_index(const ARegion *region, const int index, uiBut
return ui_but_find(region, ui_but_is_listrow_at_index, &data);
}
-static bool ui_but_is_view_item_fn(const uiBut *but, const void *UNUSED(customdata))
+static bool ui_but_is_view_item_fn(const uiBut *but, const void * /*customdata*/)
{
return but->type == UI_BTYPE_VIEW_ITEM;
}
@@ -466,7 +466,7 @@ uiBut *ui_view_item_find_mouse_over(const ARegion *region, const int xy[2])
return ui_but_find_mouse_over_ex(region, xy, false, false, ui_but_is_view_item_fn, nullptr);
}
-static bool ui_but_is_active_view_item(const uiBut *but, const void *UNUSED(customdata))
+static bool ui_but_is_active_view_item(const uiBut *but, const void * /*customdata*/)
{
if (but->type != UI_BTYPE_VIEW_ITEM) {
return false;
diff --git a/source/blender/editors/interface/interface_region_color_picker.cc b/source/blender/editors/interface/interface_region_color_picker.cc
index db1e5e653de..0b2c538331a 100644
--- a/source/blender/editors/interface/interface_region_color_picker.cc
+++ b/source/blender/editors/interface/interface_region_color_picker.cc
@@ -52,10 +52,10 @@ static void ui_color_picker_rgb_round(float rgb[3])
* all color space conversions would be expensive, but for the color picker
* we can do the extra work. */
for (int i = 0; i < 3; i++) {
- if (fabsf(rgb[i]) < 1e-6f) {
+ if (fabsf(rgb[i]) < 5e-5f) {
rgb[i] = 0.0f;
}
- else if (fabsf(1.0f - rgb[i]) < 1e-6f) {
+ else if (fabsf(1.0f - rgb[i]) < 5e-5f) {
rgb[i] = 1.0f;
}
}
@@ -245,7 +245,7 @@ static void ui_update_color_picker_buts_rgb(uiBut *from_but,
}
}
-static void ui_colorpicker_rgba_update_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
+static void ui_colorpicker_rgba_update_cb(bContext * /*C*/, void *bt1, void * /*arg*/)
{
uiBut *but = (uiBut *)bt1;
uiPopupBlockHandle *popup = but->block->handle;
@@ -264,7 +264,7 @@ static void ui_colorpicker_rgba_update_cb(bContext *UNUSED(C), void *bt1, void *
}
}
-static void ui_colorpicker_hsv_update_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
+static void ui_colorpicker_hsv_update_cb(bContext * /*C*/, void *bt1, void * /*arg*/)
{
uiBut *but = (uiBut *)bt1;
uiPopupBlockHandle *popup = but->block->handle;
@@ -279,7 +279,7 @@ static void ui_colorpicker_hsv_update_cb(bContext *UNUSED(C), void *bt1, void *U
}
}
-static void ui_colorpicker_hex_rna_cb(bContext *UNUSED(C), void *bt1, void *hexcl)
+static void ui_colorpicker_hex_rna_cb(bContext * /*C*/, void *bt1, void *hexcl)
{
uiBut *but = (uiBut *)bt1;
uiPopupBlockHandle *popup = but->block->handle;
@@ -302,7 +302,7 @@ static void ui_colorpicker_hex_rna_cb(bContext *UNUSED(C), void *bt1, void *hexc
}
}
-static void ui_popup_close_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
+static void ui_popup_close_cb(bContext * /*C*/, void *bt1, void * /*arg*/)
{
uiBut *but = (uiBut *)bt1;
uiPopupBlockHandle *popup = but->block->handle;
@@ -336,7 +336,7 @@ static void ui_colorpicker_hide_reveal(uiBlock *block, ePickerType colormode)
}
}
-static void ui_colorpicker_create_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
+static void ui_colorpicker_create_mode_cb(bContext * /*C*/, void *bt1, void * /*arg*/)
{
uiBut *bt = static_cast<uiBut *>(bt1);
const short colormode = ui_but_value_get(bt);
@@ -542,7 +542,7 @@ static void ui_block_colorpicker(uiBlock *block,
UI_UNIT_Y,
&colormode,
0.0,
- (float)PICKER_TYPE_RGB,
+ float(PICKER_TYPE_RGB),
0,
0,
"");
@@ -820,7 +820,7 @@ static void ui_block_colorpicker(uiBlock *block,
ui_colorpicker_hide_reveal(block, (ePickerType)colormode);
}
-static int ui_colorpicker_small_wheel_cb(const bContext *UNUSED(C),
+static int ui_colorpicker_small_wheel_cb(const bContext * /*C*/,
uiBlock *block,
const wmEvent *event)
{
diff --git a/source/blender/editors/interface/interface_region_hud.cc b/source/blender/editors/interface/interface_region_hud.cc
index aca36686dea..9c13a776db0 100644
--- a/source/blender/editors/interface/interface_region_hud.cc
+++ b/source/blender/editors/interface/interface_region_hud.cc
@@ -87,7 +87,7 @@ static void hud_region_hide(ARegion *region)
/** \name Redo Panel
* \{ */
-static bool hud_panel_operator_redo_poll(const bContext *C, PanelType *UNUSED(pt))
+static bool hud_panel_operator_redo_poll(const bContext *C, PanelType * /*pt*/)
{
ScrArea *area = CTX_wm_area(C);
ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_HUD);
diff --git a/source/blender/editors/interface/interface_region_menu_pie.cc b/source/blender/editors/interface/interface_region_menu_pie.cc
index becdfaf4e25..f443dd43a3a 100644
--- a/source/blender/editors/interface/interface_region_menu_pie.cc
+++ b/source/blender/editors/interface/interface_region_menu_pie.cc
@@ -49,7 +49,7 @@ struct uiPieMenu {
int mx, my;
};
-static uiBlock *ui_block_func_PIE(bContext *UNUSED(C), uiPopupBlockHandle *handle, void *arg_pie)
+static uiBlock *ui_block_func_PIE(bContext * /*C*/, uiPopupBlockHandle *handle, void *arg_pie)
{
uiBlock *block;
uiPieMenu *pie = static_cast<uiPieMenu *>(arg_pie);
@@ -222,7 +222,7 @@ int UI_pie_menu_invoke(struct bContext *C, const char *idname, const wmEvent *ev
return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
}
- pie = UI_pie_menu_begin(C, IFACE_(mt->label), ICON_NONE, event);
+ pie = UI_pie_menu_begin(C, CTX_IFACE_(mt->translation_context, mt->label), ICON_NONE, event);
layout = UI_pie_menu_layout(pie);
UI_menutype_draw(C, mt, layout);
diff --git a/source/blender/editors/interface/interface_region_menu_popup.cc b/source/blender/editors/interface/interface_region_menu_popup.cc
index 0647e1a4a70..8fd6731d2ec 100644
--- a/source/blender/editors/interface/interface_region_menu_popup.cc
+++ b/source/blender/editors/interface/interface_region_menu_popup.cc
@@ -10,6 +10,7 @@
#include <cstdarg>
#include <cstdlib>
#include <cstring>
+#include <functional>
#include "MEM_guardedalloc.h"
@@ -166,31 +167,80 @@ struct uiPopupMenu {
uiBut *but;
ARegion *butregion;
+ /* Menu hash is created from this, to keep a memory of recently opened menus. */
+ const char *title;
+
int mx, my;
bool popup, slideout;
- uiMenuCreateFunc menu_func;
- void *menu_arg;
+ std::function<void(bContext *C, uiLayout *layout)> menu_func;
};
+/**
+ * \param title: Optional. If set, it will be used to store recently opened menus so they can be
+ * opened with the mouse over the last chosen entry again.
+ */
+static void ui_popup_menu_create_block(bContext *C,
+ uiPopupMenu *pup,
+ const char *title,
+ const char *block_name)
+{
+ const uiStyle *style = UI_style_get_dpi();
+
+ pup->block = UI_block_begin(C, nullptr, block_name, UI_EMBOSS_PULLDOWN);
+ if (!pup->but) {
+ pup->block->flag |= UI_BLOCK_NO_FLIP;
+ }
+ if (title && title[0]) {
+ pup->block->flag |= UI_BLOCK_POPUP_MEMORY;
+ pup->block->puphash = ui_popup_menu_hash(title);
+ }
+ pup->layout = UI_block_layout(
+ pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, UI_MENU_PADDING, style);
+
+ /* NOTE: this intentionally differs from the menu & sub-menu default because many operators
+ * use popups like this to select one of their options -
+ * where having invoke doesn't make sense.
+ * When the menu was opened from a button, use invoke still for compatibility. This used to be
+ * the default and changing now could cause issues. */
+ const wmOperatorCallContext opcontext = pup->but ? WM_OP_INVOKE_REGION_WIN :
+ WM_OP_EXEC_REGION_WIN;
+
+ uiLayoutSetOperatorContext(pup->layout, opcontext);
+
+ if (pup->but) {
+ if (pup->but->context) {
+ uiLayoutContextCopy(pup->layout, pup->but->context);
+ }
+ }
+}
+
static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, void *arg_pup)
{
- uiBlock *block;
uiPopupMenu *pup = static_cast<uiPopupMenu *>(arg_pup);
- int minwidth, width, height;
- char direction;
- bool flip;
- if (pup->menu_func) {
- pup->block->handle = handle;
- pup->menu_func(C, pup->layout, pup->menu_arg);
- pup->block->handle = nullptr;
+ int minwidth = 0;
+
+ if (!pup->layout) {
+ ui_popup_menu_create_block(C, pup, pup->title, __func__);
+
+ if (pup->menu_func) {
+ pup->block->handle = handle;
+ pup->menu_func(C, pup->layout);
+ pup->block->handle = nullptr;
+ }
+
+ if (uiLayoutGetUnitsX(pup->layout) != 0.0f) {
+ /* Use the minimum width from the layout if it's set. */
+ minwidth = uiLayoutGetUnitsX(pup->layout) * UI_UNIT_X;
+ }
+
+ pup->layout = nullptr;
}
/* Find block minimum width. */
- if (uiLayoutGetUnitsX(pup->layout) != 0.0f) {
- /* Use the minimum width from the layout if it's set. */
- minwidth = uiLayoutGetUnitsX(pup->layout) * UI_UNIT_X;
+ if (minwidth) {
+ /* Skip. */
}
else if (pup->but) {
/* Minimum width to enforce. */
@@ -207,6 +257,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
}
/* Find block direction. */
+ char direction;
if (pup->but) {
if (pup->block->direction != 0) {
/* allow overriding the direction from menu_func */
@@ -220,9 +271,9 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
direction = UI_DIR_DOWN;
}
- flip = (direction == UI_DIR_DOWN);
+ bool flip = (direction == UI_DIR_DOWN);
- block = pup->block;
+ uiBlock *block = pup->block;
/* in some cases we create the block before the region,
* so we set it delayed here if necessary */
@@ -232,49 +283,56 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
block->direction = direction;
+ int width, height;
UI_block_layout_resolve(block, &width, &height);
- UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT);
+ UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_NUMSELECT);
if (pup->popup) {
- int offset[2];
+ int offset[2] = {0, 0};
uiBut *but_activate = nullptr;
- UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_NUMSELECT);
+ UI_block_flag_enable(block, UI_BLOCK_LOOP);
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
UI_block_direction_set(block, direction);
/* offset the mouse position, possibly based on earlier selection */
- uiBut *bt;
- if ((block->flag & UI_BLOCK_POPUP_MEMORY) && (bt = ui_popup_menu_memory_get(block))) {
- /* position mouse on last clicked item, at 0.8*width of the
- * button, so it doesn't overlap the text too much, also note
- * the offset is negative because we are inverse moving the
- * block to be under the mouse */
- offset[0] = -(bt->rect.xmin + 0.8f * BLI_rctf_size_x(&bt->rect));
- offset[1] = -(bt->rect.ymin + 0.5f * UI_UNIT_Y);
-
- if (ui_but_is_editable(bt)) {
- but_activate = bt;
- }
- }
- else {
- /* position mouse at 0.8*width of the button and below the tile
- * on the first item */
- offset[0] = 0;
- LISTBASE_FOREACH (uiBut *, but_iter, &block->buttons) {
- offset[0] = min_ii(offset[0],
- -(but_iter->rect.xmin + 0.8f * BLI_rctf_size_x(&but_iter->rect)));
+ if (!handle->refresh) {
+ uiBut *bt;
+ if ((block->flag & UI_BLOCK_POPUP_MEMORY) && (bt = ui_popup_menu_memory_get(block))) {
+ /* position mouse on last clicked item, at 0.8*width of the
+ * button, so it doesn't overlap the text too much, also note
+ * the offset is negative because we are inverse moving the
+ * block to be under the mouse */
+ offset[0] = -(bt->rect.xmin + 0.8f * BLI_rctf_size_x(&bt->rect));
+ offset[1] = -(bt->rect.ymin + 0.5f * UI_UNIT_Y);
+
+ if (ui_but_is_editable(bt)) {
+ but_activate = bt;
+ }
}
+ else {
+ /* position mouse at 0.8*width of the button and below the tile
+ * on the first item */
+ offset[0] = 0;
+ LISTBASE_FOREACH (uiBut *, but_iter, &block->buttons) {
+ offset[0] = min_ii(offset[0],
+ -(but_iter->rect.xmin + 0.8f * BLI_rctf_size_x(&but_iter->rect)));
+ }
- offset[1] = 2.1 * UI_UNIT_Y;
+ offset[1] = 2.1 * UI_UNIT_Y;
- LISTBASE_FOREACH (uiBut *, but_iter, &block->buttons) {
- if (ui_but_is_editable(but_iter)) {
- but_activate = but_iter;
- break;
+ LISTBASE_FOREACH (uiBut *, but_iter, &block->buttons) {
+ if (ui_but_is_editable(but_iter)) {
+ but_activate = but_iter;
+ break;
+ }
}
}
+ copy_v2_v2_int(handle->prev_bounds_offset, offset);
+ }
+ else {
+ copy_v2_v2_int(offset, handle->prev_bounds_offset);
}
/* in rare cases this is needed since moving the popup
@@ -313,28 +371,35 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
return pup->block;
}
-uiPopupBlockHandle *ui_popup_menu_create(
- bContext *C, ARegion *butregion, uiBut *but, uiMenuCreateFunc menu_func, void *arg)
+static void ui_block_free_func_POPUP(void *arg_pup)
+{
+ uiPopupMenu *pup = static_cast<uiPopupMenu *>(arg_pup);
+ MEM_delete(pup);
+}
+
+static uiPopupBlockHandle *ui_popup_menu_create(
+ bContext *C,
+ ARegion *butregion,
+ uiBut *but,
+ const char *title,
+ std::function<void(bContext *, uiLayout *)> menu_func)
{
wmWindow *window = CTX_wm_window(C);
- const uiStyle *style = UI_style_get_dpi();
- uiPopupBlockHandle *handle;
- uiPopupMenu *pup = MEM_cnew<uiPopupMenu>(__func__);
- pup->block = UI_block_begin(C, nullptr, __func__, UI_EMBOSS_PULLDOWN);
- pup->block->flag |= UI_BLOCK_NUMSELECT; /* default menus to numselect */
- pup->layout = UI_block_layout(
- pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, UI_MENU_PADDING, style);
- pup->slideout = but ? ui_block_is_menu(but->block) : false;
- pup->but = but;
- uiLayoutSetOperatorContext(pup->layout, WM_OP_INVOKE_REGION_WIN);
+ uiPopupMenu *pup = MEM_new<uiPopupMenu>(__func__);
+ pup->title = title;
+ /* menu is created from a callback */
+ pup->menu_func = menu_func;
+ if (but) {
+ pup->slideout = ui_block_is_menu(but->block);
+ pup->but = but;
+ }
if (!but) {
/* no button to start from, means we are a popup */
pup->mx = window->eventstate->xy[0];
pup->my = window->eventstate->xy[1];
pup->popup = true;
- pup->block->flag |= UI_BLOCK_NO_FLIP;
}
/* some enums reversing is strange, currently we have no good way to
* reverse some enum's but not others, so reverse all so the first menu
@@ -348,16 +413,10 @@ uiPopupBlockHandle *ui_popup_menu_create(
pup->block->flag |= UI_BLOCK_NO_FLIP;
}
#endif
- if (but->context) {
- uiLayoutContextCopy(pup->layout, but->context);
- }
}
- /* menu is created from a callback */
- pup->menu_func = menu_func;
- pup->menu_arg = arg;
-
- handle = ui_popup_block_create(C, butregion, but, nullptr, ui_block_func_POPUP, pup, nullptr);
+ uiPopupBlockHandle *handle = ui_popup_block_create(
+ C, butregion, but, nullptr, ui_block_func_POPUP, pup, ui_block_free_func_POPUP);
if (!but) {
handle->popup = true;
@@ -366,69 +425,75 @@ uiPopupBlockHandle *ui_popup_menu_create(
WM_event_add_mousemove(window);
}
- MEM_freeN(pup);
-
return handle;
}
+uiPopupBlockHandle *ui_popup_menu_create(
+ bContext *C, ARegion *butregion, uiBut *but, uiMenuCreateFunc menu_func, void *arg)
+{
+ return ui_popup_menu_create(
+ C, butregion, but, nullptr, [menu_func, arg](bContext *C, uiLayout *layout) {
+ menu_func(C, layout, arg);
+ });
+}
+
/** \} */
/* -------------------------------------------------------------------- */
/** \name Popup Menu API with begin & end
* \{ */
+static void create_title_button(uiLayout *layout, const char *title, int icon)
+{
+ uiBlock *block = uiLayoutGetBlock(layout);
+ char titlestr[256];
+
+ if (icon) {
+ BLI_snprintf(titlestr, sizeof(titlestr), " %s", title);
+ uiDefIconTextBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ icon,
+ titlestr,
+ 0,
+ 0,
+ 200,
+ UI_UNIT_Y,
+ nullptr,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+ }
+ else {
+ uiBut *but = uiDefBut(
+ block, UI_BTYPE_LABEL, 0, title, 0, 0, 200, UI_UNIT_Y, nullptr, 0.0, 0.0, 0, 0, "");
+ but->drawflag = UI_BUT_TEXT_LEFT;
+ }
+
+ uiItemS(layout);
+}
+
+/* Used to directly create a popup menu that is not refreshed on redraw. */
uiPopupMenu *UI_popup_menu_begin_ex(bContext *C,
const char *title,
const char *block_name,
int icon)
{
- const uiStyle *style = UI_style_get_dpi();
- uiPopupMenu *pup = MEM_cnew<uiPopupMenu>(__func__);
- uiBut *but;
+ uiPopupMenu *pup = MEM_new<uiPopupMenu>(__func__);
- pup->block = UI_block_begin(C, nullptr, block_name, UI_EMBOSS_PULLDOWN);
- pup->block->flag |= UI_BLOCK_POPUP_MEMORY | UI_BLOCK_IS_FLIP;
- pup->block->puphash = ui_popup_menu_hash(title);
- pup->layout = UI_block_layout(
- pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, UI_MENU_PADDING, style);
+ pup->title = title;
- /* NOTE: this intentionally differs from the menu & sub-menu default because many operators
- * use popups like this to select one of their options -
- * where having invoke doesn't make sense */
- uiLayoutSetOperatorContext(pup->layout, WM_OP_EXEC_REGION_WIN);
+ ui_popup_menu_create_block(C, pup, title, block_name);
+ /* Further buttons will be laid out top to bottom by default. */
+ pup->block->flag |= UI_BLOCK_IS_FLIP;
/* create in advance so we can let buttons point to retval already */
pup->block->handle = MEM_cnew<uiPopupBlockHandle>(__func__);
- /* create title button */
if (title[0]) {
- char titlestr[256];
-
- if (icon) {
- BLI_snprintf(titlestr, sizeof(titlestr), " %s", title);
- uiDefIconTextBut(pup->block,
- UI_BTYPE_LABEL,
- 0,
- icon,
- titlestr,
- 0,
- 0,
- 200,
- UI_UNIT_Y,
- nullptr,
- 0.0,
- 0.0,
- 0,
- 0,
- "");
- }
- else {
- but = uiDefBut(
- pup->block, UI_BTYPE_LABEL, 0, title, 0, 0, 200, UI_UNIT_Y, nullptr, 0.0, 0.0, 0, 0, "");
- but->drawflag = UI_BUT_TEXT_LEFT;
- }
-
- uiItemS(pup->layout);
+ create_title_button(pup->layout, title, icon);
}
return pup;
@@ -448,26 +513,26 @@ void UI_popup_menu_but_set(uiPopupMenu *pup, struct ARegion *butregion, uiBut *b
void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
{
wmWindow *window = CTX_wm_window(C);
- uiPopupBlockHandle *menu;
- uiBut *but = nullptr;
- ARegion *butregion = nullptr;
pup->popup = true;
pup->mx = window->eventstate->xy[0];
pup->my = window->eventstate->xy[1];
+ uiBut *but = nullptr;
+ ARegion *butregion = nullptr;
if (pup->but) {
but = pup->but;
butregion = pup->butregion;
}
- menu = ui_popup_block_create(C, butregion, but, nullptr, ui_block_func_POPUP, pup, nullptr);
+ uiPopupBlockHandle *menu = ui_popup_block_create(
+ C, butregion, but, nullptr, ui_block_func_POPUP, pup, nullptr);
menu->popup = true;
UI_popup_handlers_add(C, &window->modalhandlers, menu, 0);
WM_event_add_mousemove(window);
- MEM_freeN(pup);
+ MEM_delete(pup);
}
bool UI_popup_menu_end_or_cancel(bContext *C, uiPopupMenu *pup)
@@ -479,7 +544,7 @@ bool UI_popup_menu_end_or_cancel(bContext *C, uiPopupMenu *pup)
UI_block_layout_resolve(pup->block, nullptr, nullptr);
MEM_freeN(pup->block->handle);
UI_block_free(C, pup->block);
- MEM_freeN(pup);
+ MEM_delete(pup);
return false;
}
@@ -543,10 +608,24 @@ void UI_popup_menu_reports(bContext *C, ReportList *reports)
}
}
+static void ui_popup_menu_create_from_menutype(bContext *C,
+ MenuType *mt,
+ const char *title,
+ const int icon)
+{
+ uiPopupBlockHandle *handle = ui_popup_menu_create(
+ C, nullptr, nullptr, title, [mt, title, icon](bContext *C, uiLayout *layout) -> void {
+ if (title && title[0]) {
+ create_title_button(layout, title, icon);
+ }
+ ui_item_menutype_func(C, layout, mt);
+ });
+
+ handle->can_refresh = true;
+}
+
int UI_popup_menu_invoke(bContext *C, const char *idname, ReportList *reports)
{
- uiPopupMenu *pup;
- uiLayout *layout;
MenuType *mt = WM_menutype_find(idname, true);
if (mt == nullptr) {
@@ -558,13 +637,21 @@ int UI_popup_menu_invoke(bContext *C, const char *idname, ReportList *reports)
/* cancel but allow event to pass through, just like operators do */
return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
}
+ /* For now always recreate menus on redraw that were invoked with this function. Maybe we want to
+ * make that optional somehow. */
+ const bool allow_refresh = true;
- pup = UI_popup_menu_begin(C, IFACE_(mt->label), ICON_NONE);
- layout = UI_popup_menu_layout(pup);
-
- UI_menutype_draw(C, mt, layout);
-
- UI_popup_menu_end(C, pup);
+ const char *title = CTX_IFACE_(mt->translation_context, mt->label);
+ if (allow_refresh) {
+ ui_popup_menu_create_from_menutype(C, mt, title, ICON_NONE);
+ }
+ else {
+ /* If no refresh is needed, create the block directly. */
+ uiPopupMenu *pup = UI_popup_menu_begin(C, title, ICON_NONE);
+ uiLayout *layout = UI_popup_menu_layout(pup);
+ UI_menutype_draw(C, mt, layout);
+ UI_popup_menu_end(C, pup);
+ }
return OPERATOR_INTERFACE;
}
@@ -579,9 +666,9 @@ void UI_popup_block_invoke_ex(
bContext *C, uiBlockCreateFunc func, void *arg, uiFreeArgFunc arg_free, bool can_refresh)
{
wmWindow *window = CTX_wm_window(C);
- uiPopupBlockHandle *handle;
- handle = ui_popup_block_create(C, nullptr, nullptr, func, nullptr, arg, arg_free);
+ uiPopupBlockHandle *handle = ui_popup_block_create(
+ C, nullptr, nullptr, func, nullptr, arg, arg_free);
handle->popup = true;
/* It can be useful to disable refresh (even though it will work)
@@ -607,9 +694,9 @@ void UI_popup_block_ex(bContext *C,
wmOperator *op)
{
wmWindow *window = CTX_wm_window(C);
- uiPopupBlockHandle *handle;
- handle = ui_popup_block_create(C, nullptr, nullptr, func, nullptr, arg, nullptr);
+ uiPopupBlockHandle *handle = ui_popup_block_create(
+ C, nullptr, nullptr, func, nullptr, arg, nullptr);
handle->popup = true;
handle->retvalue = 1;
handle->can_refresh = true;
diff --git a/source/blender/editors/interface/interface_region_popover.cc b/source/blender/editors/interface/interface_region_popover.cc
index 17c8d890755..431571c1376 100644
--- a/source/blender/editors/interface/interface_region_popover.cc
+++ b/source/blender/editors/interface/interface_region_popover.cc
@@ -146,8 +146,8 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v
ui_block_to_window_fl(handle->ctx_region, pup->but->block, &center[0], &center[1]);
/* These variables aren't used for popovers,
* we could add new variables if there is a conflict. */
- block->bounds_offset[0] = (int)center[0];
- block->bounds_offset[1] = (int)center[1];
+ block->bounds_offset[0] = int(center[0]);
+ block->bounds_offset[1] = int(center[1]);
copy_v2_v2_int(handle->prev_bounds_offset, block->bounds_offset);
}
else {
@@ -245,7 +245,7 @@ uiPopupBlockHandle *ui_popover_panel_create(
/* Scale width by changes to Text Style point size. */
const int text_points_max = MAX2(style->widget.points, style->widgetlabel.points);
pup->ui_size_x = ui_units_x * U.widget_unit *
- (text_points_max / (float)UI_DEFAULT_TEXT_POINTS);
+ (text_points_max / float(UI_DEFAULT_TEXT_POINTS));
}
pup->menu_func = menu_func;
@@ -355,7 +355,7 @@ uiPopover *UI_popover_begin(bContext *C, int ui_menu_width, bool from_active_but
return pup;
}
-static void popover_keymap_fn(wmKeyMap *UNUSED(keymap), wmKeyMapItem *UNUSED(kmi), void *user_data)
+static void popover_keymap_fn(wmKeyMap * /*keymap*/, wmKeyMapItem * /*kmi*/, void *user_data)
{
uiPopover *pup = static_cast<uiPopover *>(user_data);
pup->block->handle->menuretval = UI_RETURN_OK;
diff --git a/source/blender/editors/interface/interface_region_popup.cc b/source/blender/editors/interface/interface_region_popup.cc
index daa46b150a3..e574cb30b23 100644
--- a/source/blender/editors/interface/interface_region_popup.cc
+++ b/source/blender/editors/interface/interface_region_popup.cc
@@ -69,7 +69,6 @@ static void ui_popup_block_position(wmWindow *window,
/* Compute button position in window coordinates using the source
* button region/block, to position the popup attached to it. */
rctf butrct;
-
if (!handle->refresh) {
ui_block_to_window_rctf(butregion, but->block, &butrct, &but->rect);
@@ -165,10 +164,10 @@ static void ui_popup_block_position(wmWindow *window,
dir1 &= (UI_DIR_UP | UI_DIR_DOWN);
}
- if ((dir2 == 0) && (ELEM(dir1, UI_DIR_LEFT, UI_DIR_RIGHT))) {
+ if ((dir2 == 0) && ELEM(dir1, UI_DIR_LEFT, UI_DIR_RIGHT)) {
dir2 = UI_DIR_DOWN;
}
- if ((dir2 == 0) && (ELEM(dir1, UI_DIR_UP, UI_DIR_DOWN))) {
+ if ((dir2 == 0) && ELEM(dir1, UI_DIR_UP, UI_DIR_DOWN)) {
dir2 = UI_DIR_LEFT;
}
@@ -417,14 +416,13 @@ static void ui_popup_block_clip(wmWindow *window, uiBlock *block)
{
const float xmin_orig = block->rect.xmin;
const int margin = UI_SCREEN_MARGIN;
- int winx, winy;
if (block->flag & UI_BLOCK_NO_WIN_CLIP) {
return;
}
- winx = WM_window_pixels_x(window);
- winy = WM_window_pixels_y(window);
+ const int winx = WM_window_pixels_x(window);
+ const int winy = WM_window_pixels_y(window);
/* shift to left if outside of view */
if (block->rect.xmax > winx - margin) {
@@ -549,7 +547,6 @@ uiBlock *ui_popup_block_refresh(bContext *C,
void *arg = handle->popup_create_vars.arg;
uiBlock *block_old = static_cast<uiBlock *>(region->uiblocks.first);
- uiBlock *block;
handle->refresh = (block_old != nullptr);
@@ -561,6 +558,7 @@ uiBlock *ui_popup_block_refresh(bContext *C,
#endif
/* create ui block */
+ uiBlock *block;
if (create_func) {
block = create_func(C, region, arg);
}
@@ -618,16 +616,14 @@ uiBlock *ui_popup_block_refresh(bContext *C,
if (block->flag & UI_BLOCK_RADIAL) {
const int win_width = UI_SCREEN_MARGIN;
- int winx, winy;
-
- int x_offset = 0, y_offset = 0;
- winx = WM_window_pixels_x(window);
- winy = WM_window_pixels_y(window);
+ const int winx = WM_window_pixels_x(window);
+ const int winy = WM_window_pixels_y(window);
copy_v2_v2(block->pie_data.pie_center_init, block->pie_data.pie_center_spawned);
/* only try translation if area is large enough */
+ int x_offset = 0;
if (BLI_rctf_size_x(&block->rect) < winx - (2.0f * win_width)) {
if (block->rect.xmin < win_width) {
x_offset += win_width - block->rect.xmin;
@@ -637,6 +633,7 @@ uiBlock *ui_popup_block_refresh(bContext *C,
}
}
+ int y_offset = 0;
if (BLI_rctf_size_y(&block->rect) < winy - (2.0f * win_width)) {
if (block->rect.ymin < win_width) {
y_offset += win_width - block->rect.ymin;
@@ -756,9 +753,6 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C,
{
wmWindow *window = CTX_wm_window(C);
uiBut *activebut = UI_context_active_but_get(C);
- static ARegionType type;
- ARegion *region;
- uiBlock *block;
/* disable tooltips from buttons below */
if (activebut) {
@@ -787,9 +781,10 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C,
handle->can_refresh = false;
/* create area region */
- region = ui_region_temp_add(CTX_wm_screen(C));
+ ARegion *region = ui_region_temp_add(CTX_wm_screen(C));
handle->region = region;
+ static ARegionType type;
memset(&type, 0, sizeof(ARegionType));
type.draw = ui_block_region_draw;
type.layout = ui_block_region_refresh;
@@ -798,7 +793,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C,
UI_region_handlers_add(&region->handlers);
- block = ui_popup_block_refresh(C, handle, butregion, but);
+ uiBlock *block = ui_popup_block_refresh(C, handle, butregion, but);
handle = block->handle;
/* keep centered on window resizing */
diff --git a/source/blender/editors/interface/interface_region_search.cc b/source/blender/editors/interface/interface_region_search.cc
index 6bb47666afd..8def878c6af 100644
--- a/source/blender/editors/interface/interface_region_search.cc
+++ b/source/blender/editors/interface/interface_region_search.cc
@@ -10,6 +10,7 @@
#include <cstdarg>
#include <cstdlib>
#include <cstring>
+#include <iostream>
#include "DNA_ID.h"
#include "MEM_guardedalloc.h"
@@ -43,7 +44,7 @@
#include "interface_intern.h"
#include "interface_regions_intern.hh"
-#define MENU_BORDER (int)(0.3f * U.widget_unit)
+#define MENU_BORDER int(0.3f * U.widget_unit)
/* -------------------------------------------------------------------- */
/** \name Search Box Creation
@@ -86,6 +87,10 @@ struct uiSearchboxData {
* Used so we can show leading text to menu items less prominently (not related to 'use_sep').
*/
const char *sep_string;
+
+ /* Owned by uiButSearch */
+ void *search_arg;
+ uiButSearchListenFn search_listener;
};
#define SEARCH_ITEMS 10
@@ -302,8 +307,8 @@ bool ui_searchbox_apply(uiBut *but, ARegion *region)
static struct ARegion *wm_searchbox_tooltip_init(struct bContext *C,
struct ARegion *region,
- int *UNUSED(r_pass),
- double *UNUSED(pass_delay),
+ int * /*r_pass*/,
+ double * /*pass_delay*/,
bool *r_exit_on_event)
{
*r_exit_on_event = true;
@@ -689,6 +694,14 @@ static void ui_searchbox_region_free_fn(ARegion *region)
region->regiondata = nullptr;
}
+static void ui_searchbox_region_listen_fn(const wmRegionListenerParams *params)
+{
+ uiSearchboxData *data = static_cast<uiSearchboxData *>(params->region->regiondata);
+ if (data->search_listener) {
+ data->search_listener(params, data->search_arg);
+ }
+}
+
static ARegion *ui_searchbox_create_generic_ex(bContext *C,
ARegion *butregion,
uiButSearch *search_but,
@@ -707,11 +720,14 @@ static ARegion *ui_searchbox_create_generic_ex(bContext *C,
memset(&type, 0, sizeof(ARegionType));
type.draw = ui_searchbox_region_draw_fn;
type.free = ui_searchbox_region_free_fn;
+ type.listener = ui_searchbox_region_listen_fn;
type.regionid = RGN_TYPE_TEMPORARY;
region->type = &type;
/* Create search-box data. */
uiSearchboxData *data = MEM_cnew<uiSearchboxData>(__func__);
+ data->search_arg = search_but->arg;
+ data->search_listener = search_but->listen_fn;
/* Set font, get the bounding-box. */
data->fstyle = style->widget; /* copy struct */
@@ -887,7 +903,7 @@ static void str_tolower_titlecaps_ascii(char *str, const size_t len)
}
}
-static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARegion *region)
+static void ui_searchbox_region_draw_cb__operator(const bContext * /*C*/, ARegion *region)
{
uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata);
@@ -981,7 +997,7 @@ void ui_searchbox_free(bContext *C, ARegion *region)
ui_region_temp_remove(C, CTX_wm_screen(C), region);
}
-static void ui_searchbox_region_draw_cb__menu(const bContext *UNUSED(C), ARegion *UNUSED(region))
+static void ui_searchbox_region_draw_cb__menu(const bContext * /*C*/, ARegion * /*region*/)
{
/* Currently unused. */
}
diff --git a/source/blender/editors/interface/interface_region_tooltip.cc b/source/blender/editors/interface/interface_region_tooltip.cc
index a6e37d3f36f..2a06267d90b 100644
--- a/source/blender/editors/interface/interface_region_tooltip.cc
+++ b/source/blender/editors/interface/interface_region_tooltip.cc
@@ -56,7 +56,7 @@
#include "interface_regions_intern.hh"
#define UI_TIP_PAD_FAC 1.3f
-#define UI_TIP_PADDING (int)(UI_TIP_PAD_FAC * UI_UNIT_Y)
+#define UI_TIP_PADDING int(UI_TIP_PAD_FAC * UI_UNIT_Y)
#define UI_TIP_MAXWIDTH 600
#define UI_TIP_STR_MAX 1024
@@ -109,8 +109,7 @@ struct uiTooltipData {
#define UI_TIP_LC_MAX 6
-BLI_STATIC_ASSERT(UI_TIP_LC_MAX == static_cast<int>(uiTooltipFormat::ColorID::Alert) + 1,
- "invalid lc-max");
+BLI_STATIC_ASSERT(UI_TIP_LC_MAX == int(uiTooltipFormat::ColorID::Alert) + 1, "invalid lc-max");
BLI_STATIC_ASSERT(sizeof(uiTooltipFormat) <= sizeof(int), "oversize");
static uiTooltipField *text_field_add_only(uiTooltipData *data)
@@ -158,7 +157,7 @@ static void rgb_tint(float col[3], float h, float h_strength, float v, float v_s
hsv_to_rgb_v(col_hsv_to, col);
}
-static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *region)
+static void ui_tooltip_region_draw_cb(const bContext * /*C*/, ARegion *region)
{
const float pad_px = UI_TIP_PADDING;
uiTooltipData *data = static_cast<uiTooltipData *>(region->regiondata);
@@ -168,12 +167,12 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *region
uchar drawcol[4] = {0, 0, 0, 255}; /* to store color in while drawing (alpha is always 255) */
/* The color from the theme. */
- float *main_color = tip_colors[static_cast<int>(uiTooltipFormat::ColorID::Main)];
- float *value_color = tip_colors[static_cast<int>(uiTooltipFormat::ColorID::Value)];
- float *active_color = tip_colors[static_cast<int>(uiTooltipFormat::ColorID::Active)];
- float *normal_color = tip_colors[static_cast<int>(uiTooltipFormat::ColorID::Normal)];
- float *python_color = tip_colors[static_cast<int>(uiTooltipFormat::ColorID::Python)];
- float *alert_color = tip_colors[static_cast<int>(uiTooltipFormat::ColorID::Alert)];
+ float *main_color = tip_colors[int(uiTooltipFormat::ColorID::Main)];
+ float *value_color = tip_colors[int(uiTooltipFormat::ColorID::Value)];
+ float *active_color = tip_colors[int(uiTooltipFormat::ColorID::Active)];
+ float *normal_color = tip_colors[int(uiTooltipFormat::ColorID::Normal)];
+ float *python_color = tip_colors[int(uiTooltipFormat::ColorID::Python)];
+ float *alert_color = tip_colors[int(uiTooltipFormat::ColorID::Alert)];
float background_color[3];
@@ -224,7 +223,7 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *region
fs_params.word_wrap = true;
/* Draw header and active data (is done here to be able to change color). */
- rgb_float_to_uchar(drawcol, tip_colors[static_cast<int>(uiTooltipFormat::ColorID::Main)]);
+ rgb_float_to_uchar(drawcol, tip_colors[int(uiTooltipFormat::ColorID::Main)]);
UI_fontstyle_set(&data->fstyle);
UI_fontstyle_draw(&data->fstyle, &bbox, field->text, UI_TIP_STR_MAX, drawcol, &fs_params);
@@ -235,8 +234,7 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *region
bbox.xmin += xofs;
bbox.ymax -= yofs;
- rgb_float_to_uchar(drawcol,
- tip_colors[static_cast<int>(uiTooltipFormat::ColorID::Active)]);
+ rgb_float_to_uchar(drawcol, tip_colors[int(uiTooltipFormat::ColorID::Active)]);
UI_fontstyle_draw(
&data->fstyle, &bbox, field->text_suffix, UI_TIP_STR_MAX, drawcol, &fs_params);
@@ -254,8 +252,8 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *region
UI_fontstyle_set(&fstyle_mono);
/* XXX: needed because we don't have mono in 'U.uifonts'. */
- BLF_size(fstyle_mono.uifont_id, fstyle_mono.points * U.pixelsize, U.dpi);
- rgb_float_to_uchar(drawcol, tip_colors[static_cast<int>(field->format.color_id)]);
+ BLF_size(fstyle_mono.uifont_id, fstyle_mono.points * U.dpi_fac);
+ rgb_float_to_uchar(drawcol, tip_colors[int(field->format.color_id)]);
UI_fontstyle_draw(&fstyle_mono, &bbox, field->text, UI_TIP_STR_MAX, drawcol, &fs_params);
}
else {
@@ -265,7 +263,7 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *region
fs_params.word_wrap = true;
/* Draw remaining data. */
- rgb_float_to_uchar(drawcol, tip_colors[static_cast<int>(field->format.color_id)]);
+ rgb_float_to_uchar(drawcol, tip_colors[int(field->format.color_id)]);
UI_fontstyle_set(&data->fstyle);
UI_fontstyle_draw(&data->fstyle, &bbox, field->text, UI_TIP_STR_MAX, drawcol, &fs_params);
}
@@ -1133,7 +1131,7 @@ static ARegion *ui_tooltip_create_with_data(bContext *C,
int font_id;
if (field->format.style == uiTooltipFormat::Style::Mono) {
- BLF_size(blf_mono_font, data->fstyle.points * U.pixelsize, U.dpi);
+ BLF_size(blf_mono_font, data->fstyle.points * U.dpi_fac);
font_id = blf_mono_font;
}
else {
@@ -1398,8 +1396,7 @@ ARegion *UI_tooltip_create_from_gizmo(bContext *C, wmGizmo *gz)
{
wmWindow *win = CTX_wm_window(C);
const float aspect = 1.0f;
- float init_position[2] = {static_cast<float>(win->eventstate->xy[0]),
- static_cast<float>(win->eventstate->xy[1])};
+ float init_position[2] = {float(win->eventstate->xy[0]), float(win->eventstate->xy[1])};
uiTooltipData *data = ui_tooltip_data_from_gizmo(C, gz);
if (data == nullptr) {
diff --git a/source/blender/editors/interface/interface_regions.cc b/source/blender/editors/interface/interface_regions.cc
index 1770805cf59..63c4a6f9c42 100644
--- a/source/blender/editors/interface/interface_regions.cc
+++ b/source/blender/editors/interface/interface_regions.cc
@@ -45,6 +45,6 @@ void ui_region_temp_remove(bContext *C, bScreen *screen, ARegion *region)
}
ED_region_exit(C, region);
- BKE_area_region_free(nullptr, region); /* nullptr: no spacetype */
+ BKE_area_region_free(nullptr, region); /* nullptr: no space-type. */
BLI_freelinkN(&screen->regionbase, region);
}
diff --git a/source/blender/editors/interface/interface_style.cc b/source/blender/editors/interface/interface_style.cc
index 904765f6dc4..9493f40548d 100644
--- a/source/blender/editors/interface/interface_style.cc
+++ b/source/blender/editors/interface/interface_style.cc
@@ -319,20 +319,20 @@ const uiStyle *UI_style_get_dpi(void)
_style = *style;
- _style.paneltitle.shadx = (short)(UI_DPI_FAC * _style.paneltitle.shadx);
- _style.paneltitle.shady = (short)(UI_DPI_FAC * _style.paneltitle.shady);
- _style.grouplabel.shadx = (short)(UI_DPI_FAC * _style.grouplabel.shadx);
- _style.grouplabel.shady = (short)(UI_DPI_FAC * _style.grouplabel.shady);
- _style.widgetlabel.shadx = (short)(UI_DPI_FAC * _style.widgetlabel.shadx);
- _style.widgetlabel.shady = (short)(UI_DPI_FAC * _style.widgetlabel.shady);
-
- _style.columnspace = (short)(UI_DPI_FAC * _style.columnspace);
- _style.templatespace = (short)(UI_DPI_FAC * _style.templatespace);
- _style.boxspace = (short)(UI_DPI_FAC * _style.boxspace);
- _style.buttonspacex = (short)(UI_DPI_FAC * _style.buttonspacex);
- _style.buttonspacey = (short)(UI_DPI_FAC * _style.buttonspacey);
- _style.panelspace = (short)(UI_DPI_FAC * _style.panelspace);
- _style.panelouter = (short)(UI_DPI_FAC * _style.panelouter);
+ _style.paneltitle.shadx = short(UI_DPI_FAC * _style.paneltitle.shadx);
+ _style.paneltitle.shady = short(UI_DPI_FAC * _style.paneltitle.shady);
+ _style.grouplabel.shadx = short(UI_DPI_FAC * _style.grouplabel.shadx);
+ _style.grouplabel.shady = short(UI_DPI_FAC * _style.grouplabel.shady);
+ _style.widgetlabel.shadx = short(UI_DPI_FAC * _style.widgetlabel.shadx);
+ _style.widgetlabel.shady = short(UI_DPI_FAC * _style.widgetlabel.shady);
+
+ _style.columnspace = short(UI_DPI_FAC * _style.columnspace);
+ _style.templatespace = short(UI_DPI_FAC * _style.templatespace);
+ _style.boxspace = short(UI_DPI_FAC * _style.boxspace);
+ _style.buttonspacex = short(UI_DPI_FAC * _style.buttonspacex);
+ _style.buttonspacey = short(UI_DPI_FAC * _style.buttonspacey);
+ _style.panelspace = short(UI_DPI_FAC * _style.panelspace);
+ _style.panelouter = short(UI_DPI_FAC * _style.panelouter);
return &_style;
}
@@ -340,7 +340,7 @@ const uiStyle *UI_style_get_dpi(void)
int UI_fontstyle_string_width(const uiFontStyle *fs, const char *str)
{
UI_fontstyle_set(fs);
- return (int)BLF_width(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
+ return int(BLF_width(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX));
}
int UI_fontstyle_string_width_with_block_aspect(const uiFontStyle *fs,
@@ -359,7 +359,7 @@ int UI_fontstyle_string_width_with_block_aspect(const uiFontStyle *fs,
if (aspect != 1.0f) {
/* While in most cases rounding up isn't important, it can make a difference
* with small fonts (3px or less), zooming out in the node-editor for e.g. */
- width = (int)ceilf(width * aspect);
+ width = int(ceilf(width * aspect));
}
return width;
}
@@ -496,5 +496,5 @@ void UI_fontstyle_set(const uiFontStyle *fs)
{
uiFont *font = uifont_to_blfont(fs->uifont_id);
- BLF_size(font->blf_id, fs->points * U.pixelsize, U.dpi);
+ BLF_size(font->blf_id, fs->points * U.dpi_fac);
}
diff --git a/source/blender/editors/interface/interface_template_asset_view.cc b/source/blender/editors/interface/interface_template_asset_view.cc
index d3ed462b85d..2673c5aa168 100644
--- a/source/blender/editors/interface/interface_template_asset_view.cc
+++ b/source/blender/editors/interface/interface_template_asset_view.cc
@@ -58,7 +58,6 @@ static void asset_view_item_but_drag_set(uiBut *but,
but,
asset_handle,
BLI_strdup(blend_path),
- ED_asset_handle_get_metadata(asset_handle),
FILE_ASSET_IMPORT_APPEND,
ED_assetlist_asset_preview_icon_id_request(&list_data->asset_library_ref, asset_handle),
imbuf,
@@ -67,15 +66,15 @@ static void asset_view_item_but_drag_set(uiBut *but,
}
static void asset_view_draw_item(uiList *ui_list,
- const bContext *UNUSED(C),
+ const bContext * /*C*/,
uiLayout *layout,
- PointerRNA *UNUSED(dataptr),
+ PointerRNA * /*dataptr*/,
PointerRNA *itemptr,
- int UNUSED(icon),
- PointerRNA *UNUSED(active_dataptr),
- const char *UNUSED(active_propname),
- int UNUSED(index),
- int UNUSED(flt_flag))
+ int /*icon*/,
+ PointerRNA * /*active_dataptr*/,
+ const char * /*active_propname*/,
+ int /*index*/,
+ int /*flt_flag*/)
{
AssetViewListData *list_data = (AssetViewListData *)ui_list->dyn_data->customdata;
diff --git a/source/blender/editors/interface/interface_template_list.cc b/source/blender/editors/interface/interface_template_list.cc
index f0c91588f98..2b581f187a6 100644
--- a/source/blender/editors/interface/interface_template_list.cc
+++ b/source/blender/editors/interface/interface_template_list.cc
@@ -83,15 +83,15 @@ struct TemplateListVisualInfo {
};
static void uilist_draw_item_default(struct uiList *ui_list,
- const struct bContext *UNUSED(C),
+ const struct bContext * /*C*/,
struct uiLayout *layout,
- struct PointerRNA *UNUSED(dataptr),
+ struct PointerRNA * /*dataptr*/,
struct PointerRNA *itemptr,
int icon,
- struct PointerRNA *UNUSED(active_dataptr),
- const char *UNUSED(active_propname),
- int UNUSED(index),
- int UNUSED(flt_flag))
+ struct PointerRNA * /*active_dataptr*/,
+ const char * /*active_propname*/,
+ int /*index*/,
+ int /*flt_flag*/)
{
PropertyRNA *nameprop = RNA_struct_name_property(itemptr->type);
@@ -114,7 +114,7 @@ static void uilist_draw_item_default(struct uiList *ui_list,
}
static void uilist_draw_filter_default(struct uiList *ui_list,
- const struct bContext *UNUSED(C),
+ const struct bContext * /*C*/,
struct uiLayout *layout)
{
PointerRNA listptr;
@@ -160,7 +160,7 @@ static int cmpstringp(const void *p1, const void *p2)
}
static void uilist_filter_items_default(struct uiList *ui_list,
- const struct bContext *UNUSED(C),
+ const struct bContext * /*C*/,
struct PointerRNA *dataptr,
const char *propname)
{
@@ -519,8 +519,8 @@ static void uilist_prepare(uiList *ui_list,
int activei_row;
if (columns > 1) {
- dyn_data->height = (int)ceil((double)items->tot_items / (double)columns);
- activei_row = (int)floor((double)items->active_item_idx / (double)columns);
+ dyn_data->height = int(ceil(double(items->tot_items) / double(columns)));
+ activei_row = int(floor(double(items->active_item_idx) / double(columns)));
}
else {
dyn_data->height = items->tot_items;
@@ -561,14 +561,14 @@ static void uilist_prepare(uiList *ui_list,
items->tot_items);
}
-static void uilist_resize_update_cb(bContext *C, void *arg1, void *UNUSED(arg2))
+static void uilist_resize_update_cb(bContext *C, void *arg1, void * /*arg2*/)
{
uiList *ui_list = static_cast<uiList *>(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 = round_fl_to_int((float)(dyn_data->resize - dyn_data->resize_prev) /
- (float)UI_UNIT_Y);
+ const int diff = round_fl_to_int(float(dyn_data->resize - dyn_data->resize_prev) /
+ float(UI_UNIT_Y));
if (diff != 0) {
ui_list->list_grip += diff;
@@ -592,7 +592,7 @@ static void *uilist_item_use_dynamic_tooltip(PointerRNA *itemptr, const char *pr
return nullptr;
}
-static char *uilist_item_tooltip_func(bContext *UNUSED(C), void *argN, const char *tip)
+static char *uilist_item_tooltip_func(bContext * /*C*/, void *argN, const char *tip)
{
char *dyn_tooltip = static_cast<char *>(argN);
return BLI_sprintfN("%s - %s", tip, dyn_tooltip);
@@ -767,7 +767,7 @@ static void ui_template_list_layout_draw(const bContext *C,
uiItemL(col, "", ICON_NONE);
}
- /* add scrollbar */
+ /* Add scroll-bar. */
if (items->tot_items > visual_info.visual_items) {
uiLayoutColumn(row, false);
uiDefButI(block,
@@ -916,7 +916,7 @@ static void ui_template_list_layout_draw(const bContext *C,
uiItemL(subrow, "", ICON_NONE);
}
- /* add scrollbar */
+ /* Add scroll-bar. */
if (items->tot_items > visual_info.visual_items) {
/* col = */ uiLayoutColumn(row, false);
uiDefButI(block,
@@ -940,7 +940,7 @@ static void ui_template_list_layout_draw(const bContext *C,
box = uiLayoutListBox(layout, ui_list, &input_data->active_dataptr, input_data->activeprop);
/* For grip button. */
glob = uiLayoutColumn(box, true);
- /* For scrollbar. */
+ /* For scroll-bar. */
row = uiLayoutRow(glob, false);
const bool show_names = (flags & UI_TEMPLATE_LIST_NO_NAMES) == 0;
diff --git a/source/blender/editors/interface/interface_template_search_menu.cc b/source/blender/editors/interface/interface_template_search_menu.cc
index 5160b061ac6..574ac051322 100644
--- a/source/blender/editors/interface/interface_template_search_menu.cc
+++ b/source/blender/editors/interface/interface_template_search_menu.cc
@@ -191,7 +191,7 @@ static bool menu_items_from_ui_create_item_from_button(MenuSearch_Data *data,
if (drawstr_is_empty) {
if (prop_type == PROP_ENUM) {
- const int value_enum = (int)but->hardmax;
+ const int value_enum = int(but->hardmax);
EnumPropertyItem enum_item;
if (RNA_property_enum_item_from_value_gettexted((bContext *)but->block->evil_C,
&but->rnapoin,
@@ -227,7 +227,7 @@ static bool menu_items_from_ui_create_item_from_button(MenuSearch_Data *data,
item->rna.index = but->rnaindex;
if (prop_type == PROP_ENUM) {
- item->rna.enum_value = (int)but->hardmax;
+ item->rna.enum_value = int(but->hardmax);
}
}
}
@@ -473,8 +473,7 @@ static MenuSearch_Data *menu_items_from_ui_create(
* as the outliner only exposes functionality via the context menu. */
GHashIterator iter;
- for (WM_menutype_iter(&iter); (!BLI_ghashIterator_done(&iter));
- (BLI_ghashIterator_step(&iter))) {
+ for (WM_menutype_iter(&iter); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
MenuType *mt = (MenuType *)BLI_ghashIterator_getValue(&iter);
if (BLI_str_endswith(mt->idname, "_context_menu")) {
BLI_gset_add(menu_tagged, mt);
@@ -544,8 +543,8 @@ static MenuSearch_Data *menu_items_from_ui_create(
if (wm_contexts[space_type_ui_index].space_type_ui_index != -1) {
ScrArea *area_best = wm_contexts[space_type_ui_index].area;
- const uint value_best = (uint)area_best->winx * (uint)area_best->winy;
- const uint value_test = (uint)area->winx * (uint)area->winy;
+ const uint value_best = uint(area_best->winx) * uint(area_best->winy);
+ const uint value_test = uint(area->winx) * uint(area->winy);
if (value_best > value_test) {
continue;
}
@@ -933,7 +932,7 @@ static void menu_search_arg_free_fn(void *data_v)
MEM_freeN(data);
}
-static void menu_search_exec_fn(bContext *C, void *UNUSED(arg1), void *arg2)
+static void menu_search_exec_fn(bContext *C, void * /*arg1*/, void *arg2)
{
MenuSearch_Item *item = (MenuSearch_Item *)arg2;
if (item == nullptr) {
@@ -996,11 +995,11 @@ static void menu_search_exec_fn(bContext *C, void *UNUSED(arg1), void *arg2)
}
}
-static void menu_search_update_fn(const bContext *UNUSED(C),
+static void menu_search_update_fn(const bContext * /*C*/,
void *arg,
const char *str,
uiSearchItems *items,
- const bool UNUSED(is_first))
+ const bool /*is_first*/)
{
MenuSearch_Data *data = (MenuSearch_Data *)arg;
@@ -1079,7 +1078,7 @@ static bool ui_search_menu_create_context_menu(struct bContext *C,
static struct ARegion *ui_search_menu_create_tooltip(struct bContext *C,
struct ARegion *region,
- const rcti *UNUSED(item_rect),
+ const rcti * /*item_rect*/,
void *arg,
void *active)
{
diff --git a/source/blender/editors/interface/interface_template_search_operator.cc b/source/blender/editors/interface/interface_template_search_operator.cc
index 0d0a5f01744..58f44de5278 100644
--- a/source/blender/editors/interface/interface_template_search_operator.cc
+++ b/source/blender/editors/interface/interface_template_search_operator.cc
@@ -34,7 +34,7 @@
/** \name Operator Search Template Implementation
* \{ */
-static void operator_search_exec_fn(bContext *C, void *UNUSED(arg1), void *arg2)
+static void operator_search_exec_fn(bContext *C, void * /*arg1*/, void *arg2)
{
wmOperatorType *ot = static_cast<wmOperatorType *>(arg2);
@@ -44,10 +44,10 @@ static void operator_search_exec_fn(bContext *C, void *UNUSED(arg1), void *arg2)
}
static void operator_search_update_fn(const bContext *C,
- void *UNUSED(arg),
+ void * /*arg*/,
const char *str,
uiSearchItems *items,
- const bool UNUSED(is_first))
+ const bool /*is_first*/)
{
GHashIterator iter;
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 0b72c358dc9..b32aa82ad9e 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -910,6 +910,11 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
const char *undo_push_label = NULL;
switch (event) {
+ case UI_ID_NOP:
+ /* Don't do anything, typically set for buttons that execute an operator instead. They may
+ * still assign the callback so the button can be identified as part of an ID-template. See
+ * #UI_context_active_but_prop_get_templateID(). */
+ break;
case UI_ID_BROWSE:
case UI_ID_PIN:
RNA_warning("warning, id event %d shouldn't come here", event);
@@ -1410,7 +1415,7 @@ static void template_ID(const bContext *C,
UI_but_funcN_set(
but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_ALONE));
- if ((!BKE_id_copy_is_allowed(id)) || (idfrom && idfrom->lib) || (!editable) ||
+ if (!BKE_id_copy_is_allowed(id) || (idfrom && idfrom->lib) || (!editable) ||
/* object in editmode - don't change data */
(idfrom && GS(idfrom->name) == ID_OB && (((Object *)idfrom)->mode & OB_MODE_EDIT))) {
UI_but_flag_enable(but, UI_BUT_DISABLED);
@@ -1437,7 +1442,7 @@ static void template_ID(const bContext *C,
UI_UNIT_Y,
NULL);
}
- else if (!(ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_OB, ID_WS)) &&
+ else if (!ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_OB, ID_WS) &&
(hide_buttons == false)) {
uiDefIconButR(block,
UI_BTYPE_ICON_TOGGLE,
@@ -1543,7 +1548,8 @@ static void template_ID(const bContext *C,
UI_UNIT_Y,
NULL);
/* so we can access the template from operators, font unlinking needs this */
- UI_but_funcN_set(but, NULL, MEM_dupallocN(template_ui), NULL);
+ UI_but_funcN_set(
+ but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_NOP));
}
else {
if ((RNA_property_flag(template_ui->prop) & PROP_NEVER_UNLINK) == 0) {
@@ -3263,7 +3269,7 @@ void uiTemplatePreview(uiLayout *layout,
uiDefButS(block,
UI_BTYPE_ROW,
B_MATPRV,
- IFACE_("World"),
+ CTX_IFACE_(BLT_I18NCONTEXT_ID_WORLD, "World"),
0,
0,
UI_UNIT_X * 10,
@@ -3659,7 +3665,7 @@ static void colorband_buttons_layout(uiLayout *layout,
UI_UNIT_Y,
&coba->cur,
0.0,
- (float)(MAX2(0, coba->tot - 1)),
+ (float)MAX2(0, coba->tot - 1),
0,
0,
TIP_("Choose active color stop"));
@@ -3667,13 +3673,9 @@ static void colorband_buttons_layout(uiLayout *layout,
row = uiLayoutRow(split, false);
uiItemR(row, &ptr, "position", 0, IFACE_("Pos"), ICON_NONE);
- bt = block->buttons.last;
- UI_but_func_set(bt, colorband_update_cb, bt, coba);
row = uiLayoutRow(layout, false);
uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
- bt = block->buttons.last;
- UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
}
else {
split = uiLayoutSplit(layout, 0.5f, false);
@@ -3690,7 +3692,7 @@ static void colorband_buttons_layout(uiLayout *layout,
UI_UNIT_Y,
&coba->cur,
0.0,
- (float)(MAX2(0, coba->tot - 1)),
+ (float)MAX2(0, coba->tot - 1),
0,
0,
TIP_("Choose active color stop"));
@@ -3698,13 +3700,28 @@ static void colorband_buttons_layout(uiLayout *layout,
row = uiLayoutRow(subsplit, false);
uiItemR(row, &ptr, "position", UI_ITEM_R_SLIDER, IFACE_("Pos"), ICON_NONE);
- bt = block->buttons.last;
- UI_but_func_set(bt, colorband_update_cb, bt, coba);
row = uiLayoutRow(split, false);
uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
- bt = block->buttons.last;
- UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+ }
+
+ /* Some special (rather awkward) treatment to update UI state on certain property changes. */
+ LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) {
+ if (but->rnapoin.data != ptr.data) {
+ continue;
+ }
+ if (!but->rnaprop) {
+ continue;
+ }
+
+ const char *prop_identifier = RNA_property_identifier(but->rnaprop);
+ if (STREQ(prop_identifier, "position")) {
+ UI_but_func_set(but, colorband_update_cb, but, coba);
+ }
+
+ if (STREQ(prop_identifier, "color")) {
+ UI_but_funcN_set(but, rna_update_cb, MEM_dupallocN(cb), NULL);
+ }
}
}
}
diff --git a/source/blender/editors/interface/interface_utils.cc b/source/blender/editors/interface/interface_utils.cc
index 4b94834ce97..423eefce3f3 100644
--- a/source/blender/editors/interface/interface_utils.cc
+++ b/source/blender/editors/interface/interface_utils.cc
@@ -435,7 +435,7 @@ eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout,
/* Only buttons that can be edited as text. */
const bool use_activate_init = ((prop == prop_activate_init) &&
- (ELEM(type, PROP_STRING, PROP_INT, PROP_FLOAT)));
+ ELEM(type, PROP_STRING, PROP_INT, PROP_FLOAT));
if (use_activate_init) {
uiLayoutSetActivateInit(col, true);
@@ -495,7 +495,7 @@ static bool add_collection_search_item(CollItemSearch *cis,
cis->name,
cis->data,
cis->iconid,
- cis->has_sep_char ? (int)UI_BUT_HAS_SEP_CHAR : 0,
+ cis->has_sep_char ? int(UI_BUT_HAS_SEP_CHAR) : 0,
name_prefix_offset);
}
@@ -787,7 +787,7 @@ int UI_calc_float_precision(int prec, double value)
*/
value = fabs(value);
if ((value < pow10_neg[prec]) && (value > (1.0 / max_pow))) {
- int value_i = (int)lround(value * max_pow);
+ int value_i = int(lround(value * max_pow));
if (value_i != 0) {
const int prec_span = 3; /* show: 0.01001, 5 would allow 0.0100001 for eg. */
int test_prec;
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index ba2afce4349..0ef26de035f 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -197,16 +197,16 @@ static void color_mul_hsl_v3(uchar ch[3], float h_factor, float s_factor, float
* \{ */
/**
- * - in: roundbox codes for corner types and radius
- * - return: array of `[size][2][x, y]` points, the edges of the roundbox, + UV coords
+ * - in: `roundbox` codes for corner types and radius
+ * - return: array of `[size][2][x, y]` points, the edges of the `roundbox`, + UV coords
*
- * - draw black box with alpha 0 on exact button boundbox
- * - for every AA step:
+ * - Draw black box with alpha 0 on exact button bounding-box.
+ * - For every AA step:
* - draw the inner part for a round filled box, with color blend codes or texture coords
* - draw outline in outline color
* - draw outer part, bottom half, extruded 1 pixel to bottom, for emboss shadow
* - draw extra decorations
- * - draw background color box with alpha 1 on exact button boundbox
+ * - Draw background color box with alpha 1 on exact button bounding-box.
*/
/* fill this struct with polygon info to draw AA'ed */
@@ -693,7 +693,7 @@ static void round_box__edges(
{
float vec[WIDGET_CURVE_RESOLU][2], veci[WIDGET_CURVE_RESOLU][2];
const float minx = rect->xmin, miny = rect->ymin, maxx = rect->xmax, maxy = rect->ymax;
- const float minxi = minx + U.pixelsize; /* boundbox inner */
+ const float minxi = minx + U.pixelsize; /* Bounding-box inner. */
const float maxxi = maxx - U.pixelsize;
const float minyi = miny + U.pixelsize;
const float maxyi = maxy - U.pixelsize;
@@ -1371,7 +1371,7 @@ static void widget_draw_icon(
alpha = 0.75f;
}
}
- else if ((but->type == UI_BTYPE_LABEL)) {
+ else if (but->type == UI_BTYPE_LABEL) {
/* extra feature allows more alpha blending */
if (but->a1 == 1.0f) {
alpha *= but->a2;
@@ -1420,21 +1420,25 @@ static void widget_draw_icon(
/* to indicate draggable */
if (ui_but_drag_is_draggable(but) && (but->flag & UI_ACTIVE)) {
- UI_icon_draw_ex(xs, ys, icon, aspect, 1.25f, 0.0f, color, has_theme);
+ UI_icon_draw_ex(
+ xs, ys, icon, aspect, 1.25f, 0.0f, color, has_theme, &but->icon_overlay_text);
}
- else if ((but->flag & (UI_ACTIVE | UI_SELECT | UI_SELECT_DRAW))) {
- UI_icon_draw_ex(xs, ys, icon, aspect, alpha, 0.0f, color, has_theme);
+ else if (but->flag & (UI_ACTIVE | UI_SELECT | UI_SELECT_DRAW)) {
+ UI_icon_draw_ex(
+ xs, ys, icon, aspect, alpha, 0.0f, color, has_theme, &but->icon_overlay_text);
}
else if (!((but->icon != ICON_NONE) && UI_but_is_tool(but))) {
if (has_theme) {
alpha *= 0.8f;
}
- UI_icon_draw_ex(xs, ys, icon, aspect, alpha, 0.0f, color, has_theme);
+ UI_icon_draw_ex(
+ xs, ys, icon, aspect, alpha, 0.0f, color, has_theme, &but->icon_overlay_text);
}
else {
const bTheme *btheme = UI_GetTheme();
const float desaturate = 1.0 - btheme->tui.icon_saturation;
- UI_icon_draw_ex(xs, ys, icon, aspect, alpha, desaturate, color, has_theme);
+ UI_icon_draw_ex(
+ xs, ys, icon, aspect, alpha, desaturate, color, has_theme, &but->icon_overlay_text);
}
}
@@ -1858,33 +1862,6 @@ static void widget_draw_text_ime_underline(const uiFontStyle *fstyle,
}
#endif /* WITH_INPUT_IME */
-struct UnderlineData {
- size_t str_offset; /* The string offset of the underlined character. */
- int width_px; /* The underline width in pixels. */
- int r_offset_px[2]; /* Write the X,Y offset here. */
-};
-
-static bool widget_draw_text_underline_calc_position(const char *UNUSED(str),
- const size_t str_step_ofs,
- const rcti *glyph_step_bounds,
- const int UNUSED(glyph_advance_x),
- const rcti *glyph_bounds,
- const int UNUSED(glyph_bearing[2]),
- void *user_data)
-{
- struct UnderlineData *ul_data = user_data;
- if (ul_data->str_offset == str_step_ofs) {
- /* Full width of this glyph including both bearings. */
- const int width = glyph_bounds->xmin + BLI_rcti_size_x(glyph_bounds) + glyph_bounds->xmin;
- ul_data->r_offset_px[0] = glyph_step_bounds->xmin + ((width - ul_data->width_px) / 2);
- /* One line-width below the lower glyph bounds. */
- ul_data->r_offset_px[1] = glyph_bounds->ymin - U.pixelsize;
- /* Early exit. */
- return false;
- }
- return true;
-}
-
static void widget_draw_text(const uiFontStyle *fstyle,
const uiWidgetColors *wcol,
uiBut *but,
@@ -2150,26 +2127,18 @@ static void widget_draw_text(const uiFontStyle *fstyle,
}
if (ul_index != -1) {
- int ul_width = round_fl_to_int(BLF_width(fstyle->uifont_id, "_", 2));
-
- struct UnderlineData ul_data = {
- .str_offset = ul_index,
- .width_px = ul_width,
- };
-
- BLF_boundbox_foreach_glyph(fstyle->uifont_id,
- drawstr_ofs,
- ul_index + 1,
- widget_draw_text_underline_calc_position,
- &ul_data);
-
- const int pos_x = rect->xmin + font_xofs + ul_data.r_offset_px[0];
- const int pos_y = rect->ymin + font_yofs + ul_data.r_offset_px[1];
-
- /* Use text output because direct drawing doesn't always work. See T89246. */
- BLF_position(fstyle->uifont_id, pos_x, pos_y, 0.0f);
- BLF_color4ubv(fstyle->uifont_id, wcol->text);
- BLF_draw(fstyle->uifont_id, "_", 2);
+ rcti bounds;
+ if (BLF_str_offset_to_glyph_bounds(fstyle->uifont_id, drawstr_ofs, ul_index, &bounds) &&
+ !BLI_rcti_is_empty(&bounds)) {
+ int ul_width = round_fl_to_int(BLF_width(fstyle->uifont_id, "_", 2));
+ int pos_x = rect->xmin + font_xofs + bounds.xmin +
+ (bounds.xmax - bounds.xmin - ul_width) / 2;
+ int pos_y = rect->ymin + font_yofs + bounds.ymin - U.pixelsize;
+ /* Use text output because direct drawing doesn't always work. See T89246. */
+ BLF_position(fstyle->uifont_id, (float)pos_x, pos_y, 0.0f);
+ BLF_color4ubv(fstyle->uifont_id, wcol->text);
+ BLF_draw(fstyle->uifont_id, "_", 2);
+ }
}
}
}
@@ -5461,7 +5430,8 @@ void ui_draw_menu_item(const uiFontStyle *fstyle,
GPU_blend(GPU_BLEND_ALPHA);
/* XXX scale weak get from fstyle? */
- UI_icon_draw_ex(xs, ys, iconid, aspect, 1.0f, 0.0f, wt->wcol.text, false);
+ UI_icon_draw_ex(
+ xs, ys, iconid, aspect, 1.0f, 0.0f, wt->wcol.text, false, UI_NO_ICON_OVERLAY_TEXT);
GPU_blend(GPU_BLEND_NONE);
}
diff --git a/source/blender/editors/interface/view2d.cc b/source/blender/editors/interface/view2d.cc
index bb459f227f9..bb660d6bf7d 100644
--- a/source/blender/editors/interface/view2d.cc
+++ b/source/blender/editors/interface/view2d.cc
@@ -53,16 +53,16 @@ static void ui_view2d_curRect_validate_resize(View2D *v2d, bool resize);
BLI_INLINE int clamp_float_to_int(const float f)
{
- const float min = (float)INT_MIN;
- const float max = (float)INT_MAX;
+ const float min = float(INT_MIN);
+ const float max = float(INT_MAX);
if (UNLIKELY(f < min)) {
return min;
}
if (UNLIKELY(f > max)) {
- return (int)max;
+ return int(max);
}
- return (int)f;
+ return int(f);
}
/**
@@ -87,11 +87,11 @@ BLI_INLINE void clamp_rctf_to_rcti(rcti *dst, const rctf *src)
* \{ */
/**
- * helper to allow scrollbars to dynamically hide
- * - returns a copy of the scrollbar settings with the flags to display
- * horizontal/vertical scrollbars removed
- * - input scroll value is the v2d->scroll var
- * - hide flags are set per region at drawtime
+ * Helper to allow scroll-bars to dynamically hide:
+ * - Returns a copy of the scroll-bar settings with the flags to display
+ * horizontal/vertical scroll-bars removed.
+ * - Input scroll value is the v2d->scroll var.
+ * - Hide flags are set per region at draw-time.
*/
static int view2d_scroll_mapped(int scroll)
{
@@ -115,7 +115,7 @@ void UI_view2d_mask_from_win(const View2D *v2d, rcti *r_mask)
/**
* Called each time #View2D.cur changes, to dynamically update masks.
*
- * \param mask_scroll: Optionally clamp scrollbars by this region.
+ * \param mask_scroll: Optionally clamp scroll-bars by this region.
*/
static void view2d_masks(View2D *v2d, const rcti *mask_scroll)
{
@@ -177,7 +177,7 @@ static void view2d_masks(View2D *v2d, const rcti *mask_scroll)
/* Currently, all regions that have vertical scale handles,
* also have the scrubbing area at the top.
- * So the scrollbar has to move down a bit. */
+ * So the scroll-bar has to move down a bit. */
if (scroll & V2D_SCROLL_VERTICAL_HANDLES) {
v2d->vert.ymax -= UI_TIME_SCRUB_MARGIN_Y;
}
@@ -193,6 +193,18 @@ static void view2d_masks(View2D *v2d, const rcti *mask_scroll)
v2d->hor = *mask_scroll;
v2d->hor.ymin = v2d->hor.ymax - scroll_height;
}
+
+ /* adjust vertical scroller if there's a horizontal scroller, to leave corner free */
+ if (scroll & V2D_SCROLL_VERTICAL) {
+ if (scroll & V2D_SCROLL_BOTTOM) {
+ /* on bottom edge of region */
+ v2d->vert.ymin = v2d->hor.ymax;
+ }
+ else if (scroll & V2D_SCROLL_TOP) {
+ /* on upper edge of region */
+ v2d->vert.ymax = v2d->hor.ymin;
+ }
+ }
}
}
@@ -232,8 +244,8 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
v2d->keeptot = V2D_KEEPTOT_BOUNDS;
if (do_init) {
v2d->tot.xmin = v2d->tot.ymin = 0.0f;
- v2d->tot.xmax = (float)(winx - 1);
- v2d->tot.ymax = (float)(winy - 1);
+ v2d->tot.xmax = float(winx - 1);
+ v2d->tot.ymax = float(winy - 1);
v2d->cur = v2d->tot;
}
@@ -250,7 +262,6 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
/* tot rect has strictly regulated placement, and must only occur in +/- quadrant */
v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
v2d->keeptot = V2D_KEEPTOT_STRICT;
- v2d->keepofs = (V2D_KEEPOFS_X | V2D_KEEPOFS_Y);
tot_changed = do_init;
/* scroller settings are currently not set here... that is left for regions... */
@@ -267,7 +278,6 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
/* tot rect has strictly regulated placement, and must only occur in +/+ quadrant */
v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
v2d->keeptot = V2D_KEEPTOT_STRICT;
- v2d->keepofs = (V2D_KEEPOFS_X | V2D_KEEPOFS_Y);
tot_changed = do_init;
/* scroller settings are currently not set here... that is left for regions... */
@@ -287,8 +297,8 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
v2d->tot.ymax = winy;
v2d->cur = v2d->tot;
- v2d->min[0] = v2d->max[0] = (float)(winx - 1);
- v2d->min[1] = v2d->max[1] = (float)(winy - 1);
+ v2d->min[0] = v2d->max[0] = float(winx - 1);
+ v2d->min[1] = v2d->max[1] = float(winy - 1);
}
/* tot rect has strictly regulated placement, and must only occur in +/+ quadrant */
v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
@@ -377,9 +387,9 @@ static void ui_view2d_curRect_validate_resize(View2D *v2d, bool resize)
rctf *cur, *tot;
/* use mask as size of region that View2D resides in, as it takes into account
- * scrollbars already - keep in sync with zoomx/zoomy in view_zoomstep_apply_ex! */
- winx = (float)(BLI_rcti_size_x(&v2d->mask) + 1);
- winy = (float)(BLI_rcti_size_y(&v2d->mask) + 1);
+ * scroll-bars already - keep in sync with zoomx/zoomy in #view_zoomstep_apply_ex! */
+ winx = float(BLI_rcti_size_x(&v2d->mask) + 1);
+ winy = float(BLI_rcti_size_y(&v2d->mask) + 1);
/* get pointers to rcts for less typing */
cur = &v2d->cur;
@@ -485,7 +495,7 @@ static void ui_view2d_curRect_validate_resize(View2D *v2d, bool resize)
}
/* check if we should restore aspect ratio (if view size changed) */
- if (v2d->keepzoom & V2D_KEEPASPECT && !(v2d->keeptot == V2D_KEEPTOT_STRICT)) {
+ if (v2d->keepzoom & V2D_KEEPASPECT) {
bool do_x = false, do_y = false, do_cur;
float curRatio, winRatio;
@@ -524,17 +534,58 @@ static void ui_view2d_curRect_validate_resize(View2D *v2d, bool resize)
/* do_win = do_y; */ /* UNUSED */
if (do_cur) {
- /* portrait window: correct for x */
- width = height / winRatio;
+ if ((v2d->keeptot == V2D_KEEPTOT_STRICT) && (winx != v2d->oldwinx)) {
+ /* Special exception for Outliner (and later channel-lists):
+ * - The view may be moved left to avoid contents
+ * being pushed out of view when view shrinks.
+ * - The keeptot code will make sure cur->xmin will not be less than tot->xmin
+ * (which cannot be allowed).
+ * - width is not adjusted for changed ratios here.
+ */
+ if (winx < v2d->oldwinx) {
+ const float temp = v2d->oldwinx - winx;
+
+ cur->xmin -= temp;
+ cur->xmax -= temp;
+
+ /* width does not get modified, as keepaspect here is just set to make
+ * sure visible area adjusts to changing view shape!
+ */
+ }
+ }
+ else {
+ /* portrait window: correct for x */
+ width = height / winRatio;
+ }
}
else {
- /* landscape window: correct for y */
- height = width * winRatio;
+ if ((v2d->keeptot == V2D_KEEPTOT_STRICT) && (winy != v2d->oldwiny)) {
+ /* special exception for Outliner (and later channel-lists):
+ * - Currently, no actions need to be taken here...
+ */
+
+ if (winy < v2d->oldwiny) {
+ const float temp = v2d->oldwiny - winy;
+
+ if (v2d->align & V2D_ALIGN_NO_NEG_Y) {
+ cur->ymin -= temp;
+ cur->ymax -= temp;
+ }
+ else { /* Assume V2D_ALIGN_NO_POS_Y or combination */
+ cur->ymin += temp;
+ cur->ymax += temp;
+ }
+ }
+ }
+ else {
+ /* landscape window: correct for y */
+ height = width * winRatio;
+ }
}
/* store region size for next time */
- v2d->oldwinx = (short)winx;
- v2d->oldwiny = (short)winy;
+ v2d->oldwinx = short(winx);
+ v2d->oldwiny = short(winy);
}
/* Step 2: apply new sizes to cur rect,
@@ -865,8 +916,8 @@ void UI_view2d_curRect_reset(View2D *v2d)
float width, height;
/* assume width and height of 'cur' rect by default, should be same size as mask */
- width = (float)(BLI_rcti_size_x(&v2d->mask) + 1);
- height = (float)(BLI_rcti_size_y(&v2d->mask) + 1);
+ width = float(BLI_rcti_size_x(&v2d->mask) + 1);
+ height = float(BLI_rcti_size_y(&v2d->mask) + 1);
/* handle width - posx and negx flags are mutually exclusive, so watch out */
if ((v2d->align & V2D_ALIGN_NO_POS_X) && !(v2d->align & V2D_ALIGN_NO_NEG_X)) {
@@ -929,17 +980,17 @@ void UI_view2d_totRect_set_resize(View2D *v2d, int width, int height, bool resiz
/* handle width - posx and negx flags are mutually exclusive, so watch out */
if ((v2d->align & V2D_ALIGN_NO_POS_X) && !(v2d->align & V2D_ALIGN_NO_NEG_X)) {
/* width is in negative-x half */
- v2d->tot.xmin = (float)-width;
+ v2d->tot.xmin = float(-width);
v2d->tot.xmax = 0.0f;
}
else if ((v2d->align & V2D_ALIGN_NO_NEG_X) && !(v2d->align & V2D_ALIGN_NO_POS_X)) {
/* width is in positive-x half */
v2d->tot.xmin = 0.0f;
- v2d->tot.xmax = (float)width;
+ v2d->tot.xmax = float(width);
}
else {
/* width is centered around (x == 0) */
- const float dx = (float)width / 2.0f;
+ const float dx = float(width) / 2.0f;
v2d->tot.xmin = -dx;
v2d->tot.xmax = dx;
@@ -948,17 +999,17 @@ void UI_view2d_totRect_set_resize(View2D *v2d, int width, int height, bool resiz
/* handle height - posx and negx flags are mutually exclusive, so watch out */
if ((v2d->align & V2D_ALIGN_NO_POS_Y) && !(v2d->align & V2D_ALIGN_NO_NEG_Y)) {
/* height is in negative-y half */
- v2d->tot.ymin = (float)-height;
+ v2d->tot.ymin = float(-height);
v2d->tot.ymax = 0.0f;
}
else if ((v2d->align & V2D_ALIGN_NO_NEG_Y) && !(v2d->align & V2D_ALIGN_NO_POS_Y)) {
/* height is in positive-y half */
v2d->tot.ymin = 0.0f;
- v2d->tot.ymax = (float)height;
+ v2d->tot.ymax = float(height);
}
else {
/* height is centered around (y == 0) */
- const float dy = (float)height / 2.0f;
+ const float dy = float(height) / 2.0f;
v2d->tot.ymin = -dy;
v2d->tot.ymax = dy;
@@ -1011,17 +1062,17 @@ static void view2d_map_cur_using_mask(const View2D *v2d, rctf *r_curmasked)
const float dy = BLI_rctf_size_y(&v2d->cur) / (sizey + 1);
if (v2d->mask.xmin != 0) {
- r_curmasked->xmin -= dx * (float)v2d->mask.xmin;
+ r_curmasked->xmin -= dx * float(v2d->mask.xmin);
}
if (v2d->mask.xmax + 1 != v2d->winx) {
- r_curmasked->xmax += dx * (float)(v2d->winx - v2d->mask.xmax - 1);
+ r_curmasked->xmax += dx * float(v2d->winx - v2d->mask.xmax - 1);
}
if (v2d->mask.ymin != 0) {
- r_curmasked->ymin -= dy * (float)v2d->mask.ymin;
+ r_curmasked->ymin -= dy * float(v2d->mask.ymin);
}
if (v2d->mask.ymax + 1 != v2d->winy) {
- r_curmasked->ymax += dy * (float)(v2d->winy - v2d->mask.ymax - 1);
+ r_curmasked->ymax += dy * float(v2d->winy - v2d->mask.ymax - 1);
}
}
}
@@ -1100,7 +1151,7 @@ void UI_view2d_view_restore(const bContext *C)
const int width = BLI_rcti_size_x(&region->winrct) + 1;
const int height = BLI_rcti_size_y(&region->winrct) + 1;
- wmOrtho2(0.0f, (float)width, 0.0f, (float)height);
+ wmOrtho2(0.0f, float(width), 0.0f, float(height));
GPU_matrix_identity_set();
// ED_region_pixelspace(CTX_wm_region(C));
@@ -1126,8 +1177,8 @@ void UI_view2d_multi_grid_draw(
/* Make an estimate of at least how many vertices will be needed */
uint vertex_count = 4;
- vertex_count += 2 * ((int)((v2d->cur.xmax - v2d->cur.xmin) / lstep) + 1);
- vertex_count += 2 * ((int)((v2d->cur.ymax - v2d->cur.ymin) / lstep) + 1);
+ vertex_count += 2 * (int((v2d->cur.xmax - v2d->cur.xmin) / lstep) + 1);
+ vertex_count += 2 * (int((v2d->cur.ymax - v2d->cur.ymin) / lstep) + 1);
GPUVertFormat *format = immVertexFormat();
const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -1144,7 +1195,7 @@ void UI_view2d_multi_grid_draw(
* or high contrast grid lines. This only has an effect if colorid != TH_GRID. */
UI_GetThemeColorBlendShade3ubv(colorid, TH_GRID, 0.25f, offset, grid_line_color);
- int i = (int)(v2d->cur.xmin / lstep);
+ int i = int(v2d->cur.xmin / lstep);
if (v2d->cur.xmin > 0.0f) {
i++;
}
@@ -1161,7 +1212,7 @@ void UI_view2d_multi_grid_draw(
immVertex2f(pos, start, v2d->cur.ymax);
}
- i = (int)(v2d->cur.ymin / lstep);
+ i = int(v2d->cur.ymin / lstep);
if (v2d->cur.ymin > 0.0f) {
i++;
}
@@ -1205,10 +1256,10 @@ static void grid_axis_start_and_count(
{
*r_start = min;
if (*r_start < 0.0f) {
- *r_start += -(float)fmod(min, step);
+ *r_start += -float(fmod(min, step));
}
else {
- *r_start += step - (float)fabs(fmod(min, step));
+ *r_start += step - float(fabs(fmod(min, step)));
}
if (*r_start > max) {
@@ -1229,7 +1280,7 @@ void UI_view2d_dot_grid_draw(const View2D *v2d,
return;
}
- const float zoom_x = (float)(BLI_rcti_size_x(&v2d->mask) + 1) / BLI_rctf_size_x(&v2d->cur);
+ const float zoom_x = float(BLI_rcti_size_x(&v2d->mask) + 1) / BLI_rctf_size_x(&v2d->cur);
GPUVertFormat *format = immVertexFormat();
const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -1245,7 +1296,7 @@ void UI_view2d_dot_grid_draw(const View2D *v2d,
const int subdivision_scale = 5;
const float view_level = logf(min_step / zoom_x) / logf(subdivision_scale);
- const int largest_visible_level = (int)view_level;
+ const int largest_visible_level = int(view_level);
for (int level_offset = 0; level_offset <= grid_subdivisions; level_offset++) {
const int level = largest_visible_level - level_offset;
@@ -1326,8 +1377,8 @@ struct View2DScrollers {
/* focus bubbles */
/* focus bubbles */
/* focus bubbles */
- int vert_min, vert_max; /* vertical scrollbar */
- int hor_min, hor_max; /* horizontal scrollbar */
+ int vert_min, vert_max; /* vertical scroll-bar */
+ int hor_min, hor_max; /* horizontal scroll-bar */
/** Exact size of slider backdrop. */
rcti hor, vert;
@@ -1357,7 +1408,7 @@ void UI_view2d_scrollers_calc(View2D *v2d,
vert.ymax -= UI_HEADER_OFFSET;
/* width of sliders */
- smaller = (int)(0.1f * U.widget_unit);
+ smaller = int(0.1f * U.widget_unit);
if (scroll & V2D_SCROLL_BOTTOM) {
hor.ymin += smaller;
}
@@ -1380,7 +1431,7 @@ void UI_view2d_scrollers_calc(View2D *v2d,
r_scrollers->hor = hor;
/* scroller 'buttons':
- * - These should always remain within the visible region of the scrollbar
+ * - These should always remain within the visible region of the scroll-bar
* - They represent the region of 'tot' that is visible in 'cur'
*/
@@ -1388,7 +1439,7 @@ void UI_view2d_scrollers_calc(View2D *v2d,
if (scroll & V2D_SCROLL_HORIZONTAL) {
/* scroller 'button' extents */
totsize = BLI_rctf_size_x(&v2d->tot);
- scrollsize = (float)BLI_rcti_size_x(&hor);
+ scrollsize = float(BLI_rcti_size_x(&hor));
if (totsize == 0.0f) {
totsize = 1.0f; /* avoid divide by zero */
}
@@ -1398,7 +1449,7 @@ void UI_view2d_scrollers_calc(View2D *v2d,
r_scrollers->hor_min = hor.xmin;
}
else {
- r_scrollers->hor_min = (int)(hor.xmin + (fac1 * scrollsize));
+ r_scrollers->hor_min = int(hor.xmin + (fac1 * scrollsize));
}
fac2 = (v2d->cur.xmax - v2d->tot.xmin) / totsize;
@@ -1406,7 +1457,7 @@ void UI_view2d_scrollers_calc(View2D *v2d,
r_scrollers->hor_max = hor.xmax;
}
else {
- r_scrollers->hor_max = (int)(hor.xmin + (fac2 * scrollsize));
+ r_scrollers->hor_max = int(hor.xmin + (fac2 * scrollsize));
}
/* prevent inverted sliders */
@@ -1426,7 +1477,7 @@ void UI_view2d_scrollers_calc(View2D *v2d,
if (scroll & V2D_SCROLL_VERTICAL) {
/* scroller 'button' extents */
totsize = BLI_rctf_size_y(&v2d->tot);
- scrollsize = (float)BLI_rcti_size_y(&vert);
+ scrollsize = float(BLI_rcti_size_y(&vert));
if (totsize == 0.0f) {
totsize = 1.0f; /* avoid divide by zero */
}
@@ -1436,7 +1487,7 @@ void UI_view2d_scrollers_calc(View2D *v2d,
r_scrollers->vert_min = vert.ymin;
}
else {
- r_scrollers->vert_min = (int)(vert.ymin + (fac1 * scrollsize));
+ r_scrollers->vert_min = int(vert.ymin + (fac1 * scrollsize));
}
fac2 = (v2d->cur.ymax - v2d->tot.ymin) / totsize;
@@ -1444,7 +1495,7 @@ void UI_view2d_scrollers_calc(View2D *v2d,
r_scrollers->vert_max = vert.ymax;
}
else {
- r_scrollers->vert_max = (int)(vert.ymin + (fac2 * scrollsize));
+ r_scrollers->vert_max = int(vert.ymin + (fac2 * scrollsize));
}
/* prevent inverted sliders */
@@ -1473,14 +1524,14 @@ void UI_view2d_scrollers_draw_ex(View2D *v2d, const rcti *mask_custom, bool use_
uchar scrollers_back_color[4];
- /* Color for scrollbar backs */
+ /* Color for scroll-bar backs. */
UI_GetThemeColor4ubv(TH_BACK, scrollers_back_color);
/* make copies of rects for less typing */
vert = scrollers.vert;
hor = scrollers.hor;
- /* horizontal scrollbar */
+ /* Horizontal scroll-bar. */
if (scroll & V2D_SCROLL_HORIZONTAL) {
uiWidgetColors wcol = btheme->tui.wcol_scroll;
/* 0..255 -> min...1 */
@@ -1515,7 +1566,7 @@ void UI_view2d_scrollers_draw_ex(View2D *v2d, const rcti *mask_custom, bool use_
UI_draw_widget_scroll(&wcol, &hor, &slider, state);
}
- /* vertical scrollbar */
+ /* Vertical scroll-bar. */
if (scroll & V2D_SCROLL_VERTICAL) {
uiWidgetColors wcol = btheme->tui.wcol_scroll;
rcti slider;
@@ -1622,8 +1673,8 @@ void UI_view2d_region_to_view(
void UI_view2d_region_to_view_rctf(const 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] = {(float)BLI_rcti_size_x(&v2d->mask),
- (float)BLI_rcti_size_y(&v2d->mask)};
+ const float mask_size[2] = {float(BLI_rcti_size_x(&v2d->mask)),
+ float(BLI_rcti_size_y(&v2d->mask))};
rect_dst->xmin = (v2d->cur.xmin +
(cur_size[0] * (rect_src->xmin - v2d->mask.xmin) / mask_size[0]));
@@ -1655,8 +1706,8 @@ bool UI_view2d_view_to_region_clip(
/* check if values are within bounds */
if ((x >= 0.0f) && (x <= 1.0f) && (y >= 0.0f) && (y <= 1.0f)) {
- *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)));
+ *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;
}
@@ -1719,10 +1770,10 @@ bool UI_view2d_view_to_region_segment_clip(const View2D *v2d,
r_region_a[0] = r_region_b[0] = r_region_a[1] = r_region_b[1] = V2D_IS_CLIPPED;
if (BLI_rctf_isect_segment(&rect_unit, s_a, s_b)) {
- r_region_a[0] = (int)(v2d->mask.xmin + (s_a[0] * BLI_rcti_size_x(&v2d->mask)));
- r_region_a[1] = (int)(v2d->mask.ymin + (s_a[1] * BLI_rcti_size_y(&v2d->mask)));
- r_region_b[0] = (int)(v2d->mask.xmin + (s_b[0] * BLI_rcti_size_x(&v2d->mask)));
- r_region_b[1] = (int)(v2d->mask.ymin + (s_b[1] * BLI_rcti_size_y(&v2d->mask)));
+ r_region_a[0] = int(v2d->mask.xmin + (s_a[0] * BLI_rcti_size_x(&v2d->mask)));
+ r_region_a[1] = int(v2d->mask.ymin + (s_a[1] * BLI_rcti_size_y(&v2d->mask)));
+ r_region_b[0] = int(v2d->mask.xmin + (s_b[0] * BLI_rcti_size_x(&v2d->mask)));
+ r_region_b[1] = int(v2d->mask.ymin + (s_b[1] * BLI_rcti_size_y(&v2d->mask)));
return true;
}
@@ -1733,8 +1784,8 @@ bool UI_view2d_view_to_region_segment_clip(const View2D *v2d,
void UI_view2d_view_to_region_rcti(const 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] = {(float)BLI_rcti_size_x(&v2d->mask),
- (float)BLI_rcti_size_y(&v2d->mask)};
+ const float mask_size[2] = {float(BLI_rcti_size_x(&v2d->mask)),
+ float(BLI_rcti_size_y(&v2d->mask))};
rctf rect_tmp;
/* Step 1: express given coordinates as proportional values. */
@@ -1763,8 +1814,8 @@ void UI_view2d_view_to_region_m4(const View2D *v2d, float matrix[4][4])
bool UI_view2d_view_to_region_rcti_clip(const 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] = {(float)BLI_rcti_size_x(&v2d->mask),
- (float)BLI_rcti_size_y(&v2d->mask)};
+ const float mask_size[2] = {float(BLI_rcti_size_x(&v2d->mask)),
+ float(BLI_rcti_size_y(&v2d->mask))};
rctf rect_tmp;
BLI_assert(rect_src->xmin <= rect_src->xmax && rect_src->ymin <= rect_src->ymax);
@@ -2100,12 +2151,22 @@ void UI_view2d_text_cache_draw(ARegion *region)
col_pack_prev = v2s->col.pack;
}
- BLF_enable(font_id, BLF_CLIPPING);
- BLF_clipping(
- font_id, v2s->rect.xmin - 4, v2s->rect.ymin - 4, v2s->rect.xmax + 4, v2s->rect.ymax + 4);
- BLF_draw_default(
- v2s->rect.xmin + xofs, v2s->rect.ymin + yofs, 0.0f, v2s->str, BLF_DRAW_STR_DUMMY_MAX);
- BLF_disable(font_id, BLF_CLIPPING);
+ /* Don't use clipping if `v2s->rect` is not set. */
+ if (BLI_rcti_size_x(&v2s->rect) == 0 && BLI_rcti_size_y(&v2s->rect) == 0) {
+ BLF_draw_default(float(v2s->mval[0] + xofs),
+ float(v2s->mval[1] + yofs),
+ 0.0,
+ v2s->str,
+ BLF_DRAW_STR_DUMMY_MAX);
+ }
+ else {
+ BLF_enable(font_id, BLF_CLIPPING);
+ BLF_clipping(
+ font_id, v2s->rect.xmin - 4, v2s->rect.ymin - 4, v2s->rect.xmax + 4, v2s->rect.ymax + 4);
+ BLF_draw_default(
+ v2s->rect.xmin + xofs, v2s->rect.ymin + yofs, 0.0f, v2s->str, BLF_DRAW_STR_DUMMY_MAX);
+ BLF_disable(font_id, BLF_CLIPPING);
+ }
}
g_v2d_strings = nullptr;
diff --git a/source/blender/editors/interface/view2d_draw.cc b/source/blender/editors/interface/view2d_draw.cc
index ea4cf399a57..a8d6d6c78de 100644
--- a/source/blender/editors/interface/view2d_draw.cc
+++ b/source/blender/editors/interface/view2d_draw.cc
@@ -319,11 +319,11 @@ static void draw_horizontal_scale_indicators(const ARegion *region,
const float right_text_width = BLF_width(font_id, text, strlen(text));
const float max_text_width = max_ff(left_text_width, right_text_width);
const float max_label_count = BLI_rcti_size_x(&v2d->mask) / (max_text_width + 10.0f);
- draw_frequency = ceil((float)steps / max_label_count);
+ draw_frequency = ceil(float(steps) / max_label_count);
}
if (draw_frequency != 0) {
- const int start_index = abs((int)(start / distance)) % draw_frequency;
+ const int start_index = abs(int(start / distance)) % draw_frequency;
for (uint i = start_index; i < steps; i += draw_frequency) {
const float xpos_view = start + i * distance;
const float xpos_region = UI_view2d_view_to_region_x(v2d, xpos_view);
@@ -408,9 +408,9 @@ static void draw_vertical_scale_indicators(const ARegion *region,
}
static void view_to_string__frame_number(
- void *UNUSED(user_data), float v2d_pos, float UNUSED(v2d_step), uint max_len, char *r_str)
+ void * /*user_data*/, float v2d_pos, float /*v2d_step*/, uint max_len, char *r_str)
{
- BLI_snprintf(r_str, max_len, "%d", (int)v2d_pos);
+ BLI_snprintf(r_str, max_len, "%d", int(v2d_pos));
}
static void view_to_string__time(
@@ -424,14 +424,14 @@ static void view_to_string__time(
}
BLI_timecode_string_from_time(
- r_str, max_len, brevity_level, v2d_pos / (float)FPS, FPS, U.timecode_style);
+ r_str, max_len, brevity_level, v2d_pos / float(FPS), FPS, U.timecode_style);
}
static void view_to_string__value(
- void *UNUSED(user_data), float v2d_pos, float v2d_step, uint max_len, char *r_str)
+ void * /*user_data*/, float v2d_pos, float v2d_step, uint max_len, char *r_str)
{
if (v2d_step >= 1.0f) {
- BLI_snprintf(r_str, max_len, "%d", (int)v2d_pos);
+ BLI_snprintf(r_str, max_len, "%d", int(v2d_pos));
}
else if (v2d_step >= 0.1f) {
BLI_snprintf(r_str, max_len, "%.1f", v2d_pos);
diff --git a/source/blender/editors/interface/view2d_edge_pan.cc b/source/blender/editors/interface/view2d_edge_pan.cc
index 82959d96043..897a638dfe5 100644
--- a/source/blender/editors/interface/view2d_edge_pan.cc
+++ b/source/blender/editors/interface/view2d_edge_pan.cc
@@ -80,10 +80,10 @@ void UI_view2d_edge_pan_init(bContext *C,
vpd->enabled = false;
/* Calculate translation factor, based on size of view. */
- const float winx = (float)(BLI_rcti_size_x(&vpd->region->winrct) + 1);
- const float winy = (float)(BLI_rcti_size_y(&vpd->region->winrct) + 1);
- vpd->facx = (BLI_rctf_size_x(&vpd->v2d->cur)) / winx;
- vpd->facy = (BLI_rctf_size_y(&vpd->v2d->cur)) / winy;
+ const float winx = float(BLI_rcti_size_x(&vpd->region->winrct) + 1);
+ const float winy = float(BLI_rcti_size_y(&vpd->region->winrct) + 1);
+ vpd->facx = BLI_rctf_size_x(&vpd->v2d->cur) / winx;
+ vpd->facy = BLI_rctf_size_y(&vpd->v2d->cur) / winy;
UI_view2d_edge_pan_reset(vpd);
}
@@ -165,16 +165,16 @@ static float edge_pan_speed(View2DEdgePanData *vpd,
/* Apply a fade in to the speed based on a start time delay. */
const double start_time = x_dir ? vpd->edge_pan_start_time_x : vpd->edge_pan_start_time_y;
const float delay_factor = vpd->delay > 0.01f ?
- smootherstep(vpd->delay, (float)(current_time - start_time)) :
+ smootherstep(vpd->delay, float(current_time - start_time)) :
1.0f;
/* Zoom factor increases speed when zooming in and decreases speed when zooming out. */
- const float zoomx = (float)(BLI_rcti_size_x(&region->winrct) + 1) /
+ const float zoomx = float(BLI_rcti_size_x(&region->winrct) + 1) /
BLI_rctf_size_x(&region->v2d.cur);
const float zoom_factor = 1.0f + CLAMPIS(vpd->zoom_influence, 0.0f, 1.0f) * (zoomx - 1.0f);
return distance_factor * delay_factor * zoom_factor * vpd->max_speed * U.widget_unit *
- (float)U.dpi_fac;
+ float(U.dpi_fac);
}
static void edge_pan_apply_delta(bContext *C, View2DEdgePanData *vpd, float dx, float dy)
@@ -252,15 +252,15 @@ void UI_view2d_edge_pan_apply(bContext *C, View2DEdgePanData *vpd, const int xy[
edge_pan_manage_delay_timers(vpd, pan_dir_x, pan_dir_y, current_time);
/* Calculate the delta since the last time the operator was called. */
- const float dtime = (float)(current_time - vpd->edge_pan_last_time);
+ const float dtime = float(current_time - vpd->edge_pan_last_time);
float dx = 0.0f, dy = 0.0f;
if (pan_dir_x != 0) {
const float speed = edge_pan_speed(vpd, xy[0], true, current_time);
- dx = dtime * speed * (float)pan_dir_x;
+ dx = dtime * speed * float(pan_dir_x);
}
if (pan_dir_y != 0) {
const float speed = edge_pan_speed(vpd, xy[1], false, current_time);
- dy = dtime * speed * (float)pan_dir_y;
+ dy = dtime * speed * float(pan_dir_y);
}
vpd->edge_pan_last_time = current_time;
diff --git a/source/blender/editors/interface/view2d_gizmo_navigate.cc b/source/blender/editors/interface/view2d_gizmo_navigate.cc
index fae28833e4f..78549a33fc5 100644
--- a/source/blender/editors/interface/view2d_gizmo_navigate.cc
+++ b/source/blender/editors/interface/view2d_gizmo_navigate.cc
@@ -113,7 +113,7 @@ struct NavigateWidgetGroup {
int region_size[2];
};
-static bool WIDGETGROUP_navigate_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
+static bool WIDGETGROUP_navigate_poll(const bContext *C, wmGizmoGroupType * /*gzgt*/)
{
if ((U.uiflag & USER_SHOW_GIZMO_NAVIGATE) == 0) {
return false;
@@ -141,7 +141,7 @@ static bool WIDGETGROUP_navigate_poll(const bContext *C, wmGizmoGroupType *UNUSE
return true;
}
-static void WIDGETGROUP_navigate_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
+static void WIDGETGROUP_navigate_setup(const bContext * /*C*/, wmGizmoGroup *gzgroup)
{
NavigateWidgetGroup *navgroup = MEM_cnew<NavigateWidgetGroup>(__func__);
diff --git a/source/blender/editors/interface/view2d_ops.cc b/source/blender/editors/interface/view2d_ops.cc
index ec15c4ffc9f..30c5e79a794 100644
--- a/source/blender/editors/interface/view2d_ops.cc
+++ b/source/blender/editors/interface/view2d_ops.cc
@@ -127,10 +127,10 @@ static void view_pan_init(bContext *C, wmOperator *op)
vpd->v2d = &vpd->region->v2d;
/* calculate translation factor - based on size of view */
- const float winx = (float)(BLI_rcti_size_x(&vpd->region->winrct) + 1);
- const float winy = (float)(BLI_rcti_size_y(&vpd->region->winrct) + 1);
- vpd->facx = (BLI_rctf_size_x(&vpd->v2d->cur)) / winx;
- vpd->facy = (BLI_rctf_size_y(&vpd->v2d->cur)) / winy;
+ const float winx = float(BLI_rcti_size_x(&vpd->region->winrct) + 1);
+ const float winy = float(BLI_rcti_size_y(&vpd->region->winrct) + 1);
+ vpd->facx = BLI_rctf_size_x(&vpd->v2d->cur) / winx;
+ vpd->facy = BLI_rctf_size_y(&vpd->v2d->cur) / winy;
vpd->v2d->flag |= V2D_IS_NAVIGATING;
}
@@ -293,7 +293,7 @@ static int view_pan_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static void view_pan_cancel(bContext *UNUSED(C), wmOperator *op)
+static void view_pan_cancel(bContext * /*C*/, wmOperator *op)
{
view_pan_exit(op);
}
@@ -330,7 +330,7 @@ static void VIEW2D_OT_pan(wmOperatorType *ot)
* \{ */
/* set up modal operator and relevant settings */
-static int view_edge_pan_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int view_edge_pan_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
op->customdata = MEM_callocN(sizeof(View2DEdgePanData), "View2DEdgePanData");
View2DEdgePanData *vpd = static_cast<View2DEdgePanData *>(op->customdata);
@@ -358,7 +358,7 @@ static int view_edge_pan_modal(bContext *C, wmOperator *op, const wmEvent *event
return OPERATOR_PASS_THROUGH;
}
-static void view_edge_pan_cancel(bContext *UNUSED(C), wmOperator *op)
+static void view_edge_pan_cancel(bContext * /*C*/, wmOperator *op)
{
v2dViewPanData *vpd = static_cast<v2dViewPanData *>(op->customdata);
vpd->v2d->flag &= ~V2D_IS_NAVIGATING;
@@ -712,7 +712,7 @@ static void view_zoomstep_apply_ex(bContext *C,
if (vzd->zoom_to_mouse_pos) {
/* get zoom fac the same way as in
* ui_view2d_curRect_validate_resize - better keep in sync! */
- const float zoomx = (float)(BLI_rcti_size_x(&v2d->mask) + 1) / BLI_rctf_size_x(&v2d->cur);
+ const float zoomx = float(BLI_rcti_size_x(&v2d->mask) + 1) / BLI_rctf_size_x(&v2d->cur);
/* only move view to mouse if zoom fac is inside minzoom/maxzoom */
if (((v2d->keepzoom & V2D_LIMITZOOM) == 0) ||
@@ -747,7 +747,7 @@ static void view_zoomstep_apply_ex(bContext *C,
if (vzd->zoom_to_mouse_pos) {
/* get zoom fac the same way as in
* ui_view2d_curRect_validate_resize - better keep in sync! */
- const float zoomy = (float)(BLI_rcti_size_y(&v2d->mask) + 1) / BLI_rctf_size_y(&v2d->cur);
+ const float zoomy = float(BLI_rcti_size_y(&v2d->mask) + 1) / BLI_rctf_size_y(&v2d->cur);
/* only move view to mouse if zoom fac is inside minzoom/maxzoom */
if (((v2d->keepzoom & V2D_LIMITZOOM) == 0) ||
@@ -958,7 +958,7 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op)
* never uses the "Continuous" zoom method, and the 'timer' is not initialized. */
if ((U.viewzoom == USER_ZOOM_CONTINUE) && vzd->timer) { /* XXX store this setting as RNA prop? */
const double time = PIL_check_seconds_timer();
- const float time_step = (float)(time - vzd->timer_lastdraw);
+ const float time_step = float(time - vzd->timer_lastdraw);
dx *= time_step * 5.0f;
dy *= time_step * 5.0f;
@@ -1583,10 +1583,10 @@ void UI_view2d_smooth_view(const bContext *C,
if (changed) {
sms.orig_cur = v2d->cur;
- sms.time_allowed = (double)smooth_viewtx / 1000.0;
+ sms.time_allowed = double(smooth_viewtx) / 1000.0;
/* scale the time allowed the change in view */
- sms.time_allowed *= (double)fac;
+ sms.time_allowed *= double(fac);
/* keep track of running timer! */
if (v2d->sms == nullptr) {
@@ -1614,7 +1614,7 @@ void UI_view2d_smooth_view(const bContext *C,
}
/* only meant for timer usage */
-static int view2d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+static int view2d_smoothview_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
ARegion *region = CTX_wm_region(C);
@@ -1628,7 +1628,7 @@ static int view2d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const w
float step;
if (sms->time_allowed != 0.0) {
- step = (float)((v2d->smooth_timer->duration) / sms->time_allowed);
+ step = float((v2d->smooth_timer->duration) / sms->time_allowed);
}
else {
step = 1.0f;
@@ -1821,11 +1821,11 @@ static bool scroller_activate_poll(bContext *C)
View2D *v2d = &region->v2d;
wmEvent *event = win->eventstate;
- /* check if mouse in scrollbars, if they're enabled */
+ /* Check if mouse in scroll-bars, if they're enabled. */
return (UI_view2d_mouse_in_scrollers(region, v2d, event->xy) != 0);
}
-/* initialize customdata for scroller manipulation operator */
+/* Initialize #wmOperator.customdata for scroller manipulation operator. */
static void scroller_activate_init(bContext *C,
wmOperator *op,
const wmEvent *event,
@@ -1859,11 +1859,11 @@ static void scroller_activate_init(bContext *C,
if (in_scroller == 'h') {
/* horizontal scroller - calculate adjustment factor first */
- const float mask_size = (float)BLI_rcti_size_x(&v2d->hor);
+ const float mask_size = float(BLI_rcti_size_x(&v2d->hor));
vsm->fac = BLI_rctf_size_x(&tot_cur_union) / mask_size;
/* pixel rounding */
- vsm->fac_round = (BLI_rctf_size_x(&v2d->cur)) / (float)(BLI_rcti_size_x(&region->winrct) + 1);
+ vsm->fac_round = BLI_rctf_size_x(&v2d->cur) / float(BLI_rcti_size_x(&region->winrct) + 1);
/* get 'zone' (i.e. which part of scroller is activated) */
vsm->zone = mouse_in_scroller_handle(
@@ -1879,11 +1879,11 @@ static void scroller_activate_init(bContext *C,
}
else {
/* vertical scroller - calculate adjustment factor first */
- const float mask_size = (float)BLI_rcti_size_y(&v2d->vert);
+ const float mask_size = float(BLI_rcti_size_y(&v2d->vert));
vsm->fac = BLI_rctf_size_y(&tot_cur_union) / mask_size;
/* pixel rounding */
- vsm->fac_round = (BLI_rctf_size_y(&v2d->cur)) / (float)(BLI_rcti_size_y(&region->winrct) + 1);
+ vsm->fac_round = BLI_rctf_size_y(&v2d->cur) / float(BLI_rcti_size_y(&region->winrct) + 1);
/* get 'zone' (i.e. which part of scroller is activated) */
vsm->zone = mouse_in_scroller_handle(
@@ -2000,11 +2000,11 @@ static int scroller_activate_modal(bContext *C, wmOperator *op, const wmEvent *e
switch (vsm->scroller) {
case 'h': /* horizontal scroller - so only horizontal movement
* ('cur' moves opposite to mouse) */
- vsm->delta = (float)(event->xy[0] - vsm->lastx);
+ vsm->delta = float(event->xy[0] - vsm->lastx);
break;
case 'v': /* vertical scroller - so only vertical movement
* ('cur' moves opposite to mouse) */
- vsm->delta = (float)(event->xy[1] - vsm->lasty);
+ vsm->delta = float(event->xy[1] - vsm->lasty);
break;
}
}
@@ -2013,11 +2013,11 @@ static int scroller_activate_modal(bContext *C, wmOperator *op, const wmEvent *e
switch (vsm->scroller) {
case 'h': /* horizontal scroller - so only horizontal movement
* ('cur' moves with mouse) */
- vsm->delta = (float)(vsm->lastx - event->xy[0]);
+ vsm->delta = float(vsm->lastx - event->xy[0]);
break;
case 'v': /* vertical scroller - so only vertical movement
* ('cur' moves with to mouse) */
- vsm->delta = (float)(vsm->lasty - event->xy[1]);
+ vsm->delta = float(vsm->lasty - event->xy[1]);
break;
}
}
@@ -2065,7 +2065,7 @@ static int scroller_activate_invoke(bContext *C, wmOperator *op, const wmEvent *
ARegion *region = CTX_wm_region(C);
View2D *v2d = &region->v2d;
- /* check if mouse in scrollbars, if they're enabled */
+ /* check if mouse in scroll-bars, if they're enabled */
const char in_scroller = UI_view2d_mouse_in_scrollers(region, v2d, event->xy);
/* if in a scroller, init customdata then set modal handler which will
@@ -2080,11 +2080,11 @@ static int scroller_activate_invoke(bContext *C, wmOperator *op, const wmEvent *
switch (vsm->scroller) {
case 'h': /* horizontal scroller - so only horizontal movement
* ('cur' moves opposite to mouse) */
- vsm->delta = (float)(event->xy[0] - vsm->scrollbar_orig);
+ vsm->delta = float(event->xy[0] - vsm->scrollbar_orig);
break;
case 'v': /* vertical scroller - so only vertical movement
* ('cur' moves opposite to mouse) */
- vsm->delta = (float)(event->xy[1] - vsm->scrollbar_orig);
+ vsm->delta = float(event->xy[1] - vsm->scrollbar_orig);
break;
}
scroller_activate_apply(C, op);
@@ -2169,7 +2169,7 @@ static void VIEW2D_OT_scroller_activate(wmOperatorType *ot)
/** \name View Reset Operator
* \{ */
-static int reset_exec(bContext *C, wmOperator *UNUSED(op))
+static int reset_exec(bContext *C, wmOperator * /*op*/)
{
const uiStyle *style = UI_style_get();
ARegion *region = CTX_wm_region(C);
@@ -2177,8 +2177,8 @@ static int reset_exec(bContext *C, wmOperator *UNUSED(op))
const int snap_test = ED_region_snap_size_test(region);
/* zoom 1.0 */
- const int winx = (float)(BLI_rcti_size_x(&v2d->mask) + 1);
- const int winy = (float)(BLI_rcti_size_y(&v2d->mask) + 1);
+ const int winx = float(BLI_rcti_size_x(&v2d->mask) + 1);
+ const int winy = float(BLI_rcti_size_y(&v2d->mask) + 1);
v2d->cur.xmax = v2d->cur.xmin + winx;
v2d->cur.ymax = v2d->cur.ymin + winy;
diff --git a/source/blender/editors/interface/views/abstract_view_item.cc b/source/blender/editors/interface/views/abstract_view_item.cc
index f73183d07e9..101cb66bfa9 100644
--- a/source/blender/editors/interface/views/abstract_view_item.cc
+++ b/source/blender/editors/interface/views/abstract_view_item.cc
@@ -112,7 +112,7 @@ static AbstractViewItem *find_item_from_rename_button(const uiBut &rename_but)
return nullptr;
}
-static void rename_button_fn(bContext *UNUSED(C), void *arg, char *UNUSED(origstr))
+static void rename_button_fn(bContext * /*C*/, void *arg, char * /*origstr*/)
{
const uiBut *rename_but = static_cast<uiBut *>(arg);
AbstractViewItem *item = find_item_from_rename_button(*rename_but);
diff --git a/source/blender/editors/interface/views/grid_view.cc b/source/blender/editors/interface/views/grid_view.cc
index 52ff1460cbd..ee2fa87b1dc 100644
--- a/source/blender/editors/interface/views/grid_view.cc
+++ b/source/blender/editors/interface/views/grid_view.cc
@@ -237,7 +237,7 @@ IndexRange BuildOnlyVisibleButtonsHelper::get_visible_range() const
const float scroll_ofs_y = abs(v2d_.cur.ymax - v2d_.tot.ymax);
if (!IS_EQF(scroll_ofs_y, 0)) {
- const int scrolled_away_rows = (int)scroll_ofs_y / style_.tile_height;
+ const int scrolled_away_rows = int(scroll_ofs_y) / style_.tile_height;
first_idx_in_view = scrolled_away_rows * cols_per_row_;
}
@@ -263,7 +263,7 @@ void BuildOnlyVisibleButtonsHelper::fill_layout_before_visible(uiBlock &block) c
return;
}
- const int scrolled_away_rows = (int)scroll_ofs_y / style_.tile_height;
+ const int scrolled_away_rows = int(scroll_ofs_y) / style_.tile_height;
add_spacer_button(block, scrolled_away_rows);
}
diff --git a/source/blender/editors/interface/views/interface_view.cc b/source/blender/editors/interface/views/interface_view.cc
index c568a8cab74..71974b4d2f9 100644
--- a/source/blender/editors/interface/views/interface_view.cc
+++ b/source/blender/editors/interface/views/interface_view.cc
@@ -81,7 +81,7 @@ void ui_block_free_views(uiBlock *block)
}
}
-void UI_block_views_listen(const uiBlock *block, const wmRegionListenerParams *listener_params)
+void ui_block_views_listen(const uiBlock *block, const wmRegionListenerParams *listener_params)
{
ARegion *region = listener_params->region;
diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c
index d4855f470ff..100d56a6b0d 100644
--- a/source/blender/editors/io/io_alembic.c
+++ b/source/blender/editors/io/io_alembic.c
@@ -658,7 +658,7 @@ void WM_OT_alembic_import(wmOperatorType *ot)
ot->name = "Import Alembic";
ot->description = "Load an Alembic archive";
ot->idname = "WM_OT_alembic_import";
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_PRESET;
ot->invoke = wm_alembic_import_invoke;
ot->exec = wm_alembic_import_exec;
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index 3da7c00d5e2..7bc28a0ba89 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -219,7 +219,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
}
char buff[100];
- sprintf(buff, "Exported %d Objects", export_count);
+ BLI_snprintf(buff, sizeof(buff), "Exported %d Objects", export_count);
BKE_report(op->reports, RPT_INFO, buff);
return OPERATOR_FINISHED;
}
@@ -693,6 +693,7 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op)
int min_chain_length;
int keep_bind_info;
+ int custom_normals;
ImportSettings import_settings;
if (!RNA_struct_property_is_set_ex(op->ptr, "filepath", false)) {
@@ -702,6 +703,7 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op)
/* Options panel */
import_units = RNA_boolean_get(op->ptr, "import_units");
+ custom_normals = RNA_boolean_get(op->ptr, "custom_normals");
find_chains = RNA_boolean_get(op->ptr, "find_chains");
auto_connect = RNA_boolean_get(op->ptr, "auto_connect");
fix_orientation = RNA_boolean_get(op->ptr, "fix_orientation");
@@ -714,6 +716,7 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op)
import_settings.filepath = filename;
import_settings.import_units = import_units != 0;
+ import_settings.custom_normals = custom_normals != 0;
import_settings.auto_connect = auto_connect != 0;
import_settings.find_chains = find_chains != 0;
import_settings.fix_orientation = fix_orientation != 0;
@@ -741,6 +744,7 @@ static void uiCollada_importSettings(uiLayout *layout, PointerRNA *imfptr)
uiItemL(box, IFACE_("Import Data Options"), ICON_MESH_DATA);
uiItemR(box, imfptr, "import_units", 0, NULL, ICON_NONE);
+ uiItemR(box, imfptr, "custom_normals", 0, NULL, ICON_NONE);
box = uiLayoutBox(layout);
uiItemL(box, IFACE_("Armature Options"), ICON_ARMATURE_DATA);
@@ -766,14 +770,12 @@ void WM_OT_collada_import(wmOperatorType *ot)
ot->name = "Import COLLADA";
ot->description = "Load a Collada file";
ot->idname = "WM_OT_collada_import";
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_PRESET;
ot->invoke = WM_operator_filesel;
ot->exec = wm_collada_import_exec;
ot->poll = WM_operator_winactive;
- // ot->flag = OPTYPE_PRESET;
-
ot->ui = wm_collada_import_draw;
WM_operator_properties_filesel(ot,
@@ -792,6 +794,12 @@ void WM_OT_collada_import(wmOperatorType *ot)
"otherwise use the settings from the Imported scene");
RNA_def_boolean(ot->srna,
+ "custom_normals",
+ 1,
+ "Custom Normals",
+ "Import custom normals, if available (otherwise Blender will compute them)");
+
+ RNA_def_boolean(ot->srna,
"fix_orientation",
0,
"Fix Leaf Bones",
diff --git a/source/blender/editors/io/io_gpencil_import.c b/source/blender/editors/io/io_gpencil_import.c
index eb53f66d8b8..5325965e9a5 100644
--- a/source/blender/editors/io/io_gpencil_import.c
+++ b/source/blender/editors/io/io_gpencil_import.c
@@ -66,7 +66,7 @@ static int wm_gpencil_import_svg_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
if (!RNA_struct_property_is_set_ex(op->ptr, "filepath", false) ||
- !(RNA_struct_find_property(op->ptr, "directory"))) {
+ !RNA_struct_find_property(op->ptr, "directory")) {
BKE_report(op->reports, RPT_ERROR, "No filename given");
return OPERATOR_CANCELLED;
}
@@ -111,7 +111,7 @@ static int wm_gpencil_import_svg_exec(bContext *C, wmOperator *op)
char file_path[FILE_MAX];
RNA_PROP_BEGIN (op->ptr, itemptr, prop) {
char *filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0, NULL);
- BLI_join_dirfile(file_path, sizeof(file_path), directory, filename);
+ BLI_path_join(file_path, sizeof(file_path), directory, filename);
MEM_freeN(filename);
/* Do Import. */
diff --git a/source/blender/editors/io/io_obj.c b/source/blender/editors/io/io_obj.c
index cb8eafeb52d..27994af8fe7 100644
--- a/source/blender/editors/io/io_obj.c
+++ b/source/blender/editors/io/io_obj.c
@@ -81,7 +81,7 @@ static int wm_obj_export_exec(bContext *C, wmOperator *op)
export_params.forward_axis = RNA_enum_get(op->ptr, "forward_axis");
export_params.up_axis = RNA_enum_get(op->ptr, "up_axis");
- export_params.scaling_factor = RNA_float_get(op->ptr, "scaling_factor");
+ export_params.global_scale = RNA_float_get(op->ptr, "global_scale");
export_params.apply_modifiers = RNA_boolean_get(op->ptr, "apply_modifiers");
export_params.export_eval_mode = RNA_enum_get(op->ptr, "export_eval_mode");
@@ -122,7 +122,7 @@ static void ui_obj_export_settings(uiLayout *layout, PointerRNA *imfptr)
col = uiLayoutColumn(box, false);
sub = uiLayoutColumnWithHeading(col, false, IFACE_("Limit to"));
uiItemR(sub, imfptr, "export_selected_objects", 0, IFACE_("Selected Only"), ICON_NONE);
- uiItemR(sub, imfptr, "scaling_factor", 0, NULL, ICON_NONE);
+ uiItemR(sub, imfptr, "global_scale", 0, NULL, ICON_NONE);
row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "forward_axis", UI_ITEM_R_EXPAND, IFACE_("Forward Axis"), ICON_NONE);
@@ -301,15 +301,16 @@ void WM_OT_obj_export(struct wmOperatorType *ot)
RNA_def_property_update_runtime(prop, (void *)forward_axis_update);
prop = RNA_def_enum(ot->srna, "up_axis", io_transform_axis, IO_AXIS_Y, "Up Axis", "");
RNA_def_property_update_runtime(prop, (void *)up_axis_update);
- RNA_def_float(ot->srna,
- "scaling_factor",
- 1.0f,
- 0.001f,
- 10000.0f,
- "Scale",
- "Upscale the object by this factor",
- 0.01,
- 1000.0f);
+ RNA_def_float(
+ ot->srna,
+ "global_scale",
+ 1.0f,
+ 0.0001f,
+ 10000.0f,
+ "Scale",
+ "Value by which to enlarge or shrink the objects with respect to the world's origin",
+ 0.0001f,
+ 10000.0f);
/* File Writer options. */
RNA_def_boolean(
ot->srna, "apply_modifiers", true, "Apply Modifiers", "Apply modifiers to exported meshes");
@@ -405,6 +406,7 @@ static int wm_obj_import_exec(bContext *C, wmOperator *op)
{
struct OBJImportParams import_params;
RNA_string_get(op->ptr, "filepath", import_params.filepath);
+ import_params.global_scale = RNA_float_get(op->ptr, "global_scale");
import_params.clamp_size = RNA_float_get(op->ptr, "clamp_size");
import_params.forward_axis = RNA_enum_get(op->ptr, "forward_axis");
import_params.up_axis = RNA_enum_get(op->ptr, "up_axis");
@@ -425,8 +427,7 @@ static int wm_obj_import_exec(bContext *C, wmOperator *op)
for (int i = 0; i < files_len; i++) {
RNA_property_collection_lookup_int(op->ptr, prop, i, &fileptr);
RNA_string_get(&fileptr, "name", file_only);
- BLI_join_dirfile(
- import_params.filepath, sizeof(import_params.filepath), dir_only, file_only);
+ BLI_path_join(import_params.filepath, sizeof(import_params.filepath), dir_only, file_only);
import_params.clear_selection = (i == 0);
OBJ_import(C, &import_params);
}
@@ -459,6 +460,7 @@ static void ui_obj_import_settings(uiLayout *layout, PointerRNA *imfptr)
uiItemL(box, IFACE_("Transform"), ICON_OBJECT_DATA);
uiLayout *col = uiLayoutColumn(box, false);
uiLayout *sub = uiLayoutColumn(col, false);
+ uiItemR(sub, imfptr, "global_scale", 0, NULL, ICON_NONE);
uiItemR(sub, imfptr, "clamp_size", 0, NULL, ICON_NONE);
sub = uiLayoutColumn(col, false);
@@ -489,7 +491,7 @@ void WM_OT_obj_import(struct wmOperatorType *ot)
ot->name = "Import Wavefront OBJ";
ot->description = "Load a Wavefront OBJ scene";
ot->idname = "WM_OT_obj_import";
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_PRESET;
ot->invoke = wm_obj_import_invoke;
ot->exec = wm_obj_import_exec;
@@ -506,6 +508,16 @@ void WM_OT_obj_import(struct wmOperatorType *ot)
FILE_SORT_DEFAULT);
RNA_def_float(
ot->srna,
+ "global_scale",
+ 1.0f,
+ 0.0001f,
+ 10000.0f,
+ "Scale",
+ "Value by which to enlarge or shrink the objects with respect to the world's origin",
+ 0.0001f,
+ 10000.0f);
+ RNA_def_float(
+ ot->srna,
"clamp_size",
0.0f,
0.0f,
diff --git a/source/blender/editors/io/io_stl_ops.c b/source/blender/editors/io/io_stl_ops.c
index c98e5beaf3b..bbdb494e48a 100644
--- a/source/blender/editors/io/io_stl_ops.c
+++ b/source/blender/editors/io/io_stl_ops.c
@@ -49,7 +49,7 @@ static int wm_stl_import_execute(bContext *C, wmOperator *op)
for (int i = 0; i < files_len; i++) {
RNA_property_collection_lookup_int(op->ptr, prop, i, &fileptr);
RNA_string_get(&fileptr, "name", file_only);
- BLI_join_dirfile(params.filepath, sizeof(params.filepath), dir_only, file_only);
+ BLI_path_join(params.filepath, sizeof(params.filepath), dir_only, file_only);
STL_import(C, &params);
}
}
@@ -95,7 +95,7 @@ void WM_OT_stl_import(struct wmOperatorType *ot)
ot->exec = wm_stl_import_execute;
ot->poll = WM_operator_winactive;
ot->check = wm_stl_import_check;
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_PRESET;
WM_operator_properties_filesel(ot,
FILE_TYPE_FOLDER,
diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c
index eb80cabcd7f..c776fbf0dd7 100644
--- a/source/blender/editors/io/io_usd.c
+++ b/source/blender/editors/io/io_usd.c
@@ -500,7 +500,7 @@ void WM_OT_usd_import(struct wmOperatorType *ot)
ot->poll = WM_operator_winactive;
ot->ui = wm_usd_import_draw;
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_PRESET;
WM_operator_properties_filesel(ot,
FILE_TYPE_FOLDER | FILE_TYPE_USD,
diff --git a/source/blender/editors/lattice/editlattice_select.c b/source/blender/editors/lattice/editlattice_select.c
index 54a72c7ea5d..22a9d41fcf7 100644
--- a/source/blender/editors/lattice/editlattice_select.c
+++ b/source/blender/editors/lattice/editlattice_select.c
@@ -78,7 +78,7 @@ bool ED_lattice_deselect_all_multi(struct bContext *C)
ED_view3d_viewcontext_init(C, &vc, depsgraph);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- vc.view_layer, vc.v3d, &bases_len);
+ vc.scene, vc.view_layer, vc.v3d, &bases_len);
bool changed_multi = ED_lattice_deselect_all_multi_ex(bases, bases_len);
MEM_freeN(bases);
return changed_multi;
@@ -96,10 +96,11 @@ static int lattice_select_random_exec(bContext *C, wmOperator *op)
const float randfac = RNA_float_get(op->ptr, "ratio");
const int seed = WM_operator_properties_select_random_seed_increment_get(op);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt;
@@ -205,10 +206,11 @@ static int lattice_select_mirror_exec(bContext *C, wmOperator *op)
const int axis_flag = RNA_enum_get(op->ptr, "axis");
const bool extend = RNA_boolean_get(op->ptr, "extend");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -271,12 +273,13 @@ static bool lattice_test_bitmap_uvw(
static int lattice_select_more_less(bContext *C, const bool select)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len;
bool changed = false;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt;
@@ -396,12 +399,13 @@ bool ED_lattice_flags_set(Object *obedit, int flag)
static int lattice_select_all_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
int action = RNA_enum_get(op->ptr, "action");
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
@@ -484,13 +488,14 @@ void LATTICE_OT_select_all(wmOperatorType *ot)
static int lattice_select_ungrouped_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len;
const bool is_extend = RNA_boolean_get(op->ptr, "extend");
bool changed = false;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt;
@@ -592,7 +597,7 @@ static BPoint *findnearestLattvert(ViewContext *vc, bool select, Base **r_base)
uint bases_len;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- vc->view_layer, vc->v3d, &bases_len);
+ vc->scene, vc->view_layer, vc->v3d, &bases_len);
for (uint base_index = 0; base_index < bases_len; base_index++) {
Base *base = bases[base_index];
data.is_changed = false;
@@ -633,7 +638,7 @@ bool ED_lattice_select_pick(bContext *C, const int mval[2], const struct SelectP
/* Deselect everything. */
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- vc.view_layer, vc.v3d, &objects_len);
+ vc.scene, vc.view_layer, vc.v3d, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
if (ED_lattice_flags_set(ob, 0)) {
@@ -680,7 +685,8 @@ bool ED_lattice_select_pick(bContext *C, const int mval[2], const struct SelectP
lt->actbp = LT_ACTBP_NONE;
}
- if (vc.view_layer->basact != basact) {
+ BKE_view_layer_synced_ensure(vc.scene, vc.view_layer);
+ if (BKE_view_layer_active_base_get(vc.view_layer) != basact) {
ED_object_base_activate(C, basact);
}
diff --git a/source/blender/editors/lattice/editlattice_tools.c b/source/blender/editors/lattice/editlattice_tools.c
index bb68b244d35..cee39ff7d70 100644
--- a/source/blender/editors/lattice/editlattice_tools.c
+++ b/source/blender/editors/lattice/editlattice_tools.c
@@ -49,6 +49,7 @@ static bool make_regular_poll(bContext *C)
static int make_regular_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
const bool is_editmode = CTX_data_edit_object(C) != NULL;
@@ -56,7 +57,7 @@ static int make_regular_exec(bContext *C, wmOperator *UNUSED(op))
if (is_editmode) {
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
Lattice *lt = ob->data;
@@ -195,13 +196,14 @@ static void lattice_swap_point_pairs(
static int lattice_flip_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len;
bool changed = false;
const eLattice_FlipAxes axis = RNA_enum_get(op->ptr, "axis");
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Lattice *lt;
diff --git a/source/blender/editors/lattice/editlattice_undo.c b/source/blender/editors/lattice/editlattice_undo.c
index 64c03c217de..b77786b2421 100644
--- a/source/blender/editors/lattice/editlattice_undo.c
+++ b/source/blender/editors/lattice/editlattice_undo.c
@@ -131,7 +131,9 @@ static int validate_undoLatt(void *data, void *edata)
static Object *editlatt_object_from_context(bContext *C)
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
if (obedit && obedit->type == OB_LATTICE) {
Lattice *lt = obedit->data;
@@ -173,9 +175,10 @@ static bool lattice_undosys_step_encode(struct bContext *C, Main *bmain, UndoSte
/* Important not to use the 3D view when getting objects because all objects
* outside of this list will be moved out of edit-mode when reading back undo steps. */
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
- Object **objects = ED_undo_editmode_objects_from_view_layer(view_layer, &objects_len);
+ Object **objects = ED_undo_editmode_objects_from_view_layer(scene, view_layer, &objects_len);
us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
us->elems_len = objects_len;
diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c
index df30870007f..0ee1fc15d7f 100644
--- a/source/blender/editors/mask/mask_add.c
+++ b/source/blender/editors/mask/mask_add.c
@@ -845,7 +845,7 @@ static void define_primitive_add_properties(wmOperatorType *ot)
static int primitive_circle_add_exec(bContext *C, wmOperator *op)
{
const float points[4][2] = {{0.0f, 0.5f}, {0.5f, 1.0f}, {1.0f, 0.5f}, {0.5f, 0.0f}};
- int num_points = sizeof(points) / (sizeof(float[2]));
+ int num_points = sizeof(points) / sizeof(float[2]);
create_primitive_from_points(C, op, points, num_points, HD_AUTO);
@@ -880,7 +880,7 @@ void MASK_OT_primitive_circle_add(wmOperatorType *ot)
static int primitive_square_add_exec(bContext *C, wmOperator *op)
{
const float points[4][2] = {{0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}};
- int num_points = sizeof(points) / (sizeof(float[2]));
+ int num_points = sizeof(points) / sizeof(float[2]);
create_primitive_from_points(C, op, points, num_points, HD_VECT);
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index 3b16497f09f..4bbb656c475 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -349,9 +349,9 @@ static void draw_spline_points(const bContext *C,
static void mask_color_active_tint(uchar r_rgb[4], const uchar rgb[4], const bool is_active)
{
if (!is_active) {
- r_rgb[0] = (uchar)((((int)(rgb[0])) + 128) / 2);
- r_rgb[1] = (uchar)((((int)(rgb[1])) + 128) / 2);
- r_rgb[2] = (uchar)((((int)(rgb[2])) + 128) / 2);
+ r_rgb[0] = (uchar)(((int)rgb[0] + 128) / 2);
+ r_rgb[1] = (uchar)(((int)rgb[1] + 128) / 2);
+ r_rgb[2] = (uchar)(((int)rgb[2] + 128) / 2);
r_rgb[3] = rgb[3];
}
else {
diff --git a/source/blender/editors/mask/mask_editaction.c b/source/blender/editors/mask/mask_editaction.c
index 9819532224e..8ec6c356fd7 100644
--- a/source/blender/editors/mask/mask_editaction.c
+++ b/source/blender/editors/mask/mask_editaction.c
@@ -287,7 +287,7 @@ void ED_masklayer_frames_duplicate(MaskLayer *mask_layer)
static bool snap_mask_layer_nearest(MaskLayerShape *mask_layer_shape, Scene *UNUSED(scene))
{
if (mask_layer_shape->flag & MASK_SHAPE_SELECT) {
- mask_layer_shape->frame = (int)(floor(mask_layer_shape->frame + 0.5));
+ mask_layer_shape->frame = (int)floor(mask_layer_shape->frame + 0.5);
}
return false;
}
diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c
index 48944c081a8..77595aa0694 100644
--- a/source/blender/editors/mask/mask_shapekey.c
+++ b/source/blender/editors/mask/mask_shapekey.c
@@ -136,9 +136,9 @@ static int mask_shape_key_feather_reset_exec(bContext *C, wmOperator *UNUSED(op)
MaskLayerShape *mask_layer_shape_reset;
MaskLayerShape *mask_layer_shape;
- /* get the shapekey of the current state */
+ /* Get the shape-key of the current state. */
mask_layer_shape_reset = BKE_mask_layer_shape_alloc(mask_layer, frame);
- /* initialize from mask - as if inseting a keyframe */
+ /* Initialize from mask - as if inserting a keyframe. */
BKE_mask_layer_shape_from_mask(mask_layer, mask_layer_shape_reset);
for (mask_layer_shape = mask_layer->splines_shapes.first; mask_layer_shape;
diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt
index 218564eaf30..a43968074d6 100644
--- a/source/blender/editors/mesh/CMakeLists.txt
+++ b/source/blender/editors/mesh/CMakeLists.txt
@@ -45,10 +45,10 @@ set(SRC
editmesh_preselect_elem.c
editmesh_rip.c
editmesh_rip_edge.c
- editmesh_select.c
+ editmesh_select.cc
editmesh_select_similar.c
editmesh_tools.c
- editmesh_undo.c
+ editmesh_undo.cc
editmesh_utils.c
mesh_data.cc
mesh_mirror.c
diff --git a/source/blender/editors/mesh/editface.cc b/source/blender/editors/mesh/editface.cc
index f729db29b8c..1c6d1747516 100644
--- a/source/blender/editors/mesh/editface.cc
+++ b/source/blender/editors/mesh/editface.cc
@@ -73,14 +73,9 @@ void paintface_flush_flags(bContext *C,
Mesh *me_eval = (Mesh *)ob_eval->runtime.data_eval;
bke::MutableAttributeAccessor attributes_eval = me_eval->attributes_for_write();
bool updated = false;
- const Span<MPoly> me_polys = me->polys();
if (me_orig != nullptr && me_eval != nullptr && me_orig->totpoly == me->totpoly) {
/* Update the COW copy of the mesh. */
- MutableSpan<MPoly> orig_polys = me_orig->polys_for_write();
- for (int i = 0; i < me->totpoly; i++) {
- orig_polys[i].flag = me_polys[i].flag;
- }
if (flush_hidden) {
const VArray<bool> hide_poly_me = attributes_me.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
@@ -89,28 +84,46 @@ void paintface_flush_flags(bContext *C,
hide_poly_me.materialize(hide_poly_orig.span);
hide_poly_orig.finish();
}
+ if (flush_selection) {
+ const VArray<bool> select_poly_me = attributes_me.lookup_or_default<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE, false);
+ bke::SpanAttributeWriter<bool> select_poly_orig =
+ attributes_orig.lookup_or_add_for_write_only_span<bool>(".select_poly",
+ ATTR_DOMAIN_FACE);
+ select_poly_me.materialize(select_poly_orig.span);
+ select_poly_orig.finish();
+ }
/* Mesh polys => Final derived polys */
if ((index_array = (const int *)CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX))) {
- MutableSpan<MPoly> eval_polys = me_orig->polys_for_write();
- /* loop over final derived polys */
- for (const int i : eval_polys.index_range()) {
- if (index_array[i] != ORIGINDEX_NONE) {
- /* Copy flags onto the final derived poly from the original mesh poly */
- eval_polys[i].flag = me_polys[index_array[i]].flag;
+ if (flush_hidden) {
+ const VArray<bool> hide_poly_orig = attributes_orig.lookup_or_default<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE, false);
+ bke::SpanAttributeWriter<bool> hide_poly_eval =
+ attributes_eval.lookup_or_add_for_write_only_span<bool>(".hide_poly",
+ ATTR_DOMAIN_FACE);
+ for (const int i : IndexRange(me_eval->totpoly)) {
+ const int orig_poly_index = index_array[i];
+ if (orig_poly_index != ORIGINDEX_NONE) {
+ hide_poly_eval.span[i] = hide_poly_orig[orig_poly_index];
+ }
}
+ hide_poly_eval.finish();
}
- const VArray<bool> hide_poly_orig = attributes_orig.lookup_or_default<bool>(
- ".hide_poly", ATTR_DOMAIN_FACE, false);
- bke::SpanAttributeWriter<bool> hide_poly_eval =
- attributes_eval.lookup_or_add_for_write_only_span<bool>(".hide_poly", ATTR_DOMAIN_FACE);
- for (const int i : IndexRange(me_eval->totpoly)) {
- const int orig_poly_index = index_array[i];
- if (orig_poly_index != ORIGINDEX_NONE) {
- hide_poly_eval.span[i] = hide_poly_orig[orig_poly_index];
+ if (flush_selection) {
+ const VArray<bool> select_poly_orig = attributes_orig.lookup_or_default<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE, false);
+ bke::SpanAttributeWriter<bool> select_poly_eval =
+ attributes_eval.lookup_or_add_for_write_only_span<bool>(".select_poly",
+ ATTR_DOMAIN_FACE);
+ for (const int i : IndexRange(me_eval->totpoly)) {
+ const int orig_poly_index = index_array[i];
+ if (orig_poly_index != ORIGINDEX_NONE) {
+ select_poly_eval.span[i] = select_poly_orig[orig_poly_index];
+ }
}
+ select_poly_eval.finish();
}
- hide_poly_eval.finish();
updated = true;
}
@@ -141,25 +154,26 @@ void paintface_hide(bContext *C, Object *ob, const bool unselected)
return;
}
- MutableSpan<MPoly> polys = me->polys_for_write();
bke::MutableAttributeAccessor attributes = me->attributes_for_write();
bke::SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_span<bool>(
".hide_poly", ATTR_DOMAIN_FACE);
+ bke::SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE);
for (int i = 0; i < me->totpoly; i++) {
- MPoly *mpoly = &polys[i];
if (!hide_poly.span[i]) {
- if (((mpoly->flag & ME_FACE_SEL) == 0) == unselected) {
+ if (!select_poly.span[i] == unselected) {
hide_poly.span[i] = true;
}
}
if (hide_poly.span[i]) {
- mpoly->flag &= ~ME_FACE_SEL;
+ select_poly.span[i] = false;
}
}
hide_poly.finish();
+ select_poly.finish();
BKE_mesh_flush_hidden_from_polys(me);
@@ -174,18 +188,19 @@ void paintface_reveal(bContext *C, Object *ob, const bool select)
return;
}
- MutableSpan<MPoly> polys = me->polys_for_write();
bke::MutableAttributeAccessor attributes = me->attributes_for_write();
if (select) {
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
- for (int i = 0; i < me->totpoly; i++) {
- MPoly *mpoly = &polys[i];
+ bke::SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE);
+ for (const int i : hide_poly.index_range()) {
if (hide_poly[i]) {
- mpoly->flag |= ME_FACE_SEL;
+ select_poly.span[i] = true;
}
}
+ select_poly.finish();
}
attributes.remove(".hide_poly");
@@ -207,27 +222,29 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
BLI_bitmap *poly_tag = BLI_BITMAP_NEW(me->totpoly, __func__);
const Span<MEdge> edges = me->edges();
- MutableSpan<MPoly> polys = me->polys_for_write();
+ const Span<MPoly> polys = me->polys();
const Span<MLoop> loops = me->loops();
- bke::AttributeAccessor attributes = me->attributes();
+ bke::MutableAttributeAccessor attributes = me->attributes_for_write();
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
+ bke::SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE);
- if (index != (uint)-1) {
+ if (index != uint(-1)) {
/* only put face under cursor in array */
- const MPoly *mp = &polys[index];
- BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, &loops[mp->loopstart]);
+ const MPoly &poly = polys[index];
+ BKE_mesh_poly_edgebitmap_insert(edge_tag, &poly, &loops[poly.loopstart]);
BLI_BITMAP_ENABLE(poly_tag, index);
}
else {
/* fill array by selection */
for (int i = 0; i < me->totpoly; i++) {
- MPoly *mp = &polys[i];
if (hide_poly[i]) {
/* pass */
}
- else if (mp->flag & ME_FACE_SEL) {
- BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, &loops[mp->loopstart]);
+ else if (select_poly.span[i]) {
+ const MPoly &poly = polys[i];
+ BKE_mesh_poly_edgebitmap_insert(edge_tag, &poly, &loops[poly.loopstart]);
BLI_BITMAP_ENABLE(poly_tag, i);
}
}
@@ -238,7 +255,6 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
/* expand selection */
for (int i = 0; i < me->totpoly; i++) {
- MPoly *mp = &polys[i];
if (hide_poly[i]) {
continue;
}
@@ -246,8 +262,9 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
if (!BLI_BITMAP_TEST(poly_tag, i)) {
mark = false;
- const MLoop *ml = &loops[mp->loopstart];
- for (int b = 0; b < mp->totloop; b++, ml++) {
+ const MPoly &poly = polys[i];
+ const MLoop *ml = &loops[poly.loopstart];
+ for (int b = 0; b < poly.totloop; b++, ml++) {
if ((edges[ml->e].flag & ME_SEAM) == 0) {
if (BLI_BITMAP_TEST(edge_tag, ml->e)) {
mark = true;
@@ -258,7 +275,7 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
if (mark) {
BLI_BITMAP_ENABLE(poly_tag, i);
- BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, &loops[mp->loopstart]);
+ BKE_mesh_poly_edgebitmap_insert(edge_tag, &poly, &loops[poly.loopstart]);
do_it = true;
}
}
@@ -268,9 +285,8 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
MEM_freeN(edge_tag);
for (int i = 0; i < me->totpoly; i++) {
- MPoly *mp = &polys[index];
if (BLI_BITMAP_TEST(poly_tag, i)) {
- SET_FLAG_FROM_TEST(mp->flag, select, ME_FACE_SEL);
+ select_poly.span[i] = select;
}
}
@@ -279,7 +295,7 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
void paintface_select_linked(bContext *C, Object *ob, const int mval[2], const bool select)
{
- uint index = (uint)-1;
+ uint index = uint(-1);
Mesh *me = BKE_mesh_from_object(ob);
if (me == nullptr || me->totpoly == 0) {
@@ -305,17 +321,17 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl
return false;
}
- MutableSpan<MPoly> polys = me->polys_for_write();
- bke::AttributeAccessor attributes = me->attributes();
+ bke::MutableAttributeAccessor attributes = me->attributes_for_write();
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
+ bke::SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE);
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
for (int i = 0; i < me->totpoly; i++) {
- MPoly *mpoly = &polys[i];
- if (!hide_poly[i] && mpoly->flag & ME_FACE_SEL) {
+ if (!hide_poly[i] && select_poly.span[i]) {
action = SEL_DESELECT;
break;
}
@@ -325,29 +341,29 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl
bool changed = false;
for (int i = 0; i < me->totpoly; i++) {
- MPoly *mpoly = &polys[i];
- if (!hide_poly[i]) {
- switch (action) {
- case SEL_SELECT:
- if ((mpoly->flag & ME_FACE_SEL) == 0) {
- mpoly->flag |= ME_FACE_SEL;
- changed = true;
- }
- break;
- case SEL_DESELECT:
- if ((mpoly->flag & ME_FACE_SEL) != 0) {
- mpoly->flag &= ~ME_FACE_SEL;
- changed = true;
- }
- break;
- case SEL_INVERT:
- mpoly->flag ^= ME_FACE_SEL;
- changed = true;
- break;
- }
+ if (hide_poly[i]) {
+ continue;
+ }
+ const bool old_selection = select_poly.span[i];
+ switch (action) {
+ case SEL_SELECT:
+ select_poly.span[i] = true;
+ break;
+ case SEL_DESELECT:
+ select_poly.span[i] = false;
+ break;
+ case SEL_INVERT:
+ select_poly.span[i] = !select_poly.span[i];
+ changed = true;
+ break;
+ }
+ if (old_selection != select_poly.span[i]) {
+ changed = true;
}
}
+ select_poly.finish();
+
if (changed) {
if (flush_flags) {
paintface_flush_flags(C, ob, true, false);
@@ -367,7 +383,7 @@ bool paintface_minmax(Object *ob, float r_min[3], float r_max[3])
return ok;
}
- copy_m3_m4(bmat, ob->obmat);
+ copy_m3_m4(bmat, ob->object_to_world);
const Span<MVert> verts = me->verts();
const Span<MPoly> polys = me->polys();
@@ -375,17 +391,19 @@ bool paintface_minmax(Object *ob, float r_min[3], float r_max[3])
bke::AttributeAccessor attributes = me->attributes();
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
+ const VArray<bool> select_poly = attributes.lookup_or_default<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE, false);
for (int i = 0; i < me->totpoly; i++) {
- const MPoly *mp = &polys[i];
- if (hide_poly[i] || !(mp->flag & ME_FACE_SEL)) {
+ if (hide_poly[i] || !select_poly[i]) {
continue;
}
- const MLoop *ml = &loops[mp->loopstart];
- for (int b = 0; b < mp->totloop; b++, ml++) {
+ const MPoly &poly = polys[i];
+ const MLoop *ml = &loops[poly.loopstart];
+ for (int b = 0; b < poly.totloop; b++, ml++) {
mul_v3_m3v3(vec, bmat, verts[ml->v].co);
- add_v3_v3v3(vec, vec, ob->obmat[3]);
+ add_v3_v3v3(vec, vec, ob->object_to_world[3]);
minmax_v3v3_v3(r_min, r_max, vec);
}
@@ -401,7 +419,6 @@ bool paintface_mouse_select(bContext *C,
Object *ob)
{
using namespace blender;
- MPoly *mpoly_sel = nullptr;
uint index;
bool changed = false;
bool found = false;
@@ -409,14 +426,14 @@ bool paintface_mouse_select(bContext *C,
/* Get the face under the cursor */
Mesh *me = BKE_mesh_from_object(ob);
- MutableSpan<MPoly> polys = me->polys_for_write();
- bke::AttributeAccessor attributes = me->attributes();
+ bke::MutableAttributeAccessor attributes = me->attributes_for_write();
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
+ bke::AttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE);
if (ED_mesh_pick_face(C, ob, mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &index)) {
if (index < me->totpoly) {
- mpoly_sel = polys.data() + index;
if (!hide_poly[index]) {
found = true;
}
@@ -424,7 +441,7 @@ bool paintface_mouse_select(bContext *C,
}
if (params->sel_op == SEL_OP_SET) {
- if ((found && params->select_passthrough) && (mpoly_sel->flag & ME_FACE_SEL)) {
+ if ((found && params->select_passthrough) && select_poly.varray[index]) {
found = false;
}
else if (found || params->deselect_all) {
@@ -434,34 +451,22 @@ bool paintface_mouse_select(bContext *C,
}
if (found) {
- me->act_face = (int)index;
+ me->act_face = int(index);
switch (params->sel_op) {
- case SEL_OP_ADD: {
- mpoly_sel->flag |= ME_FACE_SEL;
+ case SEL_OP_SET:
+ case SEL_OP_ADD:
+ select_poly.varray.set(index, true);
break;
- }
- case SEL_OP_SUB: {
- mpoly_sel->flag &= ~ME_FACE_SEL;
+ case SEL_OP_SUB:
+ select_poly.varray.set(index, false);
break;
- }
- case SEL_OP_XOR: {
- if (mpoly_sel->flag & ME_FACE_SEL) {
- mpoly_sel->flag &= ~ME_FACE_SEL;
- }
- else {
- mpoly_sel->flag |= ME_FACE_SEL;
- }
- break;
- }
- case SEL_OP_SET: {
- mpoly_sel->flag |= ME_FACE_SEL;
+ case SEL_OP_XOR:
+ select_poly.varray.set(index, !select_poly.varray[index]);
break;
- }
- case SEL_OP_AND: {
+ case SEL_OP_AND:
BLI_assert_unreachable(); /* Doesn't make sense for picking. */
break;
- }
}
/* image window redraw */
@@ -476,10 +481,9 @@ bool paintface_mouse_select(bContext *C,
void paintvert_flush_flags(Object *ob)
{
using namespace blender;
+ using namespace blender;
Mesh *me = BKE_mesh_from_object(ob);
Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
- const int *index_array = nullptr;
-
if (me == nullptr) {
return;
}
@@ -492,25 +496,42 @@ void paintvert_flush_flags(Object *ob)
return;
}
- index_array = (const int *)CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
+ const bke::AttributeAccessor attributes_orig = me->attributes();
+ bke::MutableAttributeAccessor attributes_eval = me_eval->attributes_for_write();
- const Span<MVert> verts = me->verts_for_write();
- MutableSpan<MVert> verts_eval = me_eval->verts_for_write();
+ const int *orig_indices = (const int *)CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
- if (index_array) {
- int orig_index;
- for (const int i : verts_eval.index_range()) {
- orig_index = index_array[i];
- if (orig_index != ORIGINDEX_NONE) {
- verts_eval[i].flag = verts[index_array[i]].flag;
+ const VArray<bool> hide_vert_orig = attributes_orig.lookup_or_default<bool>(
+ ".hide_vert", ATTR_DOMAIN_POINT, false);
+ bke::SpanAttributeWriter<bool> hide_vert_eval =
+ attributes_eval.lookup_or_add_for_write_only_span<bool>(".hide_vert", ATTR_DOMAIN_POINT);
+ if (orig_indices) {
+ for (const int i : hide_vert_eval.span.index_range()) {
+ if (orig_indices[i] != ORIGINDEX_NONE) {
+ hide_vert_eval.span[i] = hide_vert_orig[orig_indices[i]];
}
}
}
else {
- for (const int i : verts_eval.index_range()) {
- verts_eval[i].flag = verts[i].flag;
+ hide_vert_orig.materialize(hide_vert_eval.span);
+ }
+ hide_vert_eval.finish();
+
+ const VArray<bool> select_vert_orig = attributes_orig.lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+ bke::SpanAttributeWriter<bool> select_vert_eval =
+ attributes_eval.lookup_or_add_for_write_only_span<bool>(".select_vert", ATTR_DOMAIN_POINT);
+ if (orig_indices) {
+ for (const int i : select_vert_eval.span.index_range()) {
+ if (orig_indices[i] != ORIGINDEX_NONE) {
+ select_vert_eval.span[i] = select_vert_orig[orig_indices[i]];
+ }
}
}
+ else {
+ select_vert_orig.materialize(select_vert_eval.span);
+ }
+ select_vert_eval.finish();
BKE_mesh_batch_cache_dirty_tag(me, BKE_MESH_BATCH_DIRTY_ALL);
}
@@ -529,17 +550,17 @@ bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
return false;
}
- MutableSpan<MVert> verts = me->verts_for_write();
- bke::AttributeAccessor attributes = me->attributes();
+ bke::MutableAttributeAccessor attributes = me->attributes_for_write();
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
".hide_vert", ATTR_DOMAIN_POINT, false);
+ bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT);
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
for (int i = 0; i < me->totvert; i++) {
- MVert *mvert = &verts[i];
- if (!hide_vert[i] && mvert->flag & SELECT) {
+ if (!hide_vert[i] && select_vert.span[i]) {
action = SEL_DESELECT;
break;
}
@@ -548,29 +569,28 @@ bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
bool changed = false;
for (int i = 0; i < me->totvert; i++) {
- MVert *mvert = &verts[i];
- if (!hide_vert[i]) {
- switch (action) {
- case SEL_SELECT:
- if ((mvert->flag & SELECT) == 0) {
- mvert->flag |= SELECT;
- changed = true;
- }
- break;
- case SEL_DESELECT:
- if ((mvert->flag & SELECT) != 0) {
- mvert->flag &= ~SELECT;
- changed = true;
- }
- break;
- case SEL_INVERT:
- mvert->flag ^= SELECT;
- changed = true;
- break;
- }
+ if (hide_vert[i]) {
+ continue;
+ }
+ const bool old_selection = select_vert.span[i];
+ switch (action) {
+ case SEL_SELECT:
+ select_vert.span[i] = true;
+ break;
+ case SEL_DESELECT:
+ select_vert.span[i] = false;
+ break;
+ case SEL_INVERT:
+ select_vert.span[i] = !select_vert.span[i];
+ break;
+ }
+ if (old_selection != select_vert.span[i]) {
+ changed = true;
}
}
+ select_vert.finish();
+
if (changed) {
/* handle mselect */
if (action == SEL_SELECT) {
@@ -606,22 +626,23 @@ void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags)
paintvert_deselect_all_visible(ob, SEL_DESELECT, false);
}
- MutableSpan<MVert> verts = me->verts_for_write();
- bke::AttributeAccessor attributes = me->attributes();
+ bke::MutableAttributeAccessor attributes = me->attributes_for_write();
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
".hide_vert", ATTR_DOMAIN_POINT, false);
+ bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT);
- for (int i = 0; i < me->totvert; i++) {
- MVert *mv = &verts[i];
- const MDeformVert *dv = &dverts[i];
+ for (const int i : select_vert.span.index_range()) {
if (!hide_vert[i]) {
- if (dv->dw == nullptr) {
+ if (dverts[i].dw == nullptr) {
/* if null weight then not grouped */
- mv->flag |= SELECT;
+ select_vert.span[i] = true;
}
}
}
+ select_vert.finish();
+
if (flush_flags) {
paintvert_flush_flags(ob);
}
@@ -635,24 +656,25 @@ void paintvert_hide(bContext *C, Object *ob, const bool unselected)
return;
}
- MutableSpan<MVert> verts = me->verts_for_write();
bke::MutableAttributeAccessor attributes = me->attributes_for_write();
bke::SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_span<bool>(
".hide_vert", ATTR_DOMAIN_POINT);
+ bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT);
- for (const int i : verts.index_range()) {
- MVert &vert = verts[i];
+ for (const int i : hide_vert.span.index_range()) {
if (!hide_vert.span[i]) {
- if (((vert.flag & SELECT) == 0) == unselected) {
+ if (!select_vert.span[i] == unselected) {
hide_vert.span[i] = true;
}
}
if (hide_vert.span[i]) {
- vert.flag &= ~SELECT;
+ select_vert.span[i] = false;
}
}
hide_vert.finish();
+ select_vert.finish();
BKE_mesh_flush_hidden_from_verts(me);
@@ -668,18 +690,20 @@ void paintvert_reveal(bContext *C, Object *ob, const bool select)
return;
}
- MutableSpan<MVert> verts = me->verts_for_write();
bke::MutableAttributeAccessor attributes = me->attributes_for_write();
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
".hide_vert", ATTR_DOMAIN_POINT, false);
+ bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT);
- for (const int i : verts.index_range()) {
- MVert &vert = verts[i];
+ for (const int i : select_vert.span.index_range()) {
if (hide_vert[i]) {
- SET_FLAG_FROM_TEST(vert.flag, select, SELECT);
+ select_vert.span[i] = select;
}
}
+ select_vert.finish();
+
/* Remove the hide attribute to reveal all vertices. */
attributes.remove(".hide_vert");
diff --git a/source/blender/editors/mesh/editmesh_add_gizmo.c b/source/blender/editors/mesh/editmesh_add_gizmo.c
index f5090c0143d..03c6104bb0d 100644
--- a/source/blender/editors/mesh/editmesh_add_gizmo.c
+++ b/source/blender/editors/mesh/editmesh_add_gizmo.c
@@ -316,8 +316,8 @@ static int add_primitive_cube_gizmo_exec(bContext *C, wmOperator *op)
PropertyRNA *prop_matrix = RNA_struct_find_property(op->ptr, "matrix");
if (RNA_property_is_set(op->ptr, prop_matrix)) {
RNA_property_float_get_array(op->ptr, prop_matrix, &matrix[0][0]);
- invert_m4_m4(obedit->imat, obedit->obmat);
- mul_m4_m4m4(matrix, obedit->imat, matrix);
+ invert_m4_m4(obedit->world_to_object, obedit->object_to_world);
+ mul_m4_m4m4(matrix, obedit->world_to_object, matrix);
}
else {
/* For the first update the widget may not set the matrix. */
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index e7891450bd6..92e993f74a2 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -170,7 +170,7 @@ static void edbm_bevel_update_status_text(bContext *C, wmOperator *op)
sizeof(status_text),
TIP_("%s: Confirm, "
"%s: Cancel, "
- "%s: Mode (%s), "
+ "%s: Width Type (%s), "
"%s: Width (%s), "
"%s: Segments (%d), "
"%s: Profile (%.3f), "
@@ -240,11 +240,11 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
{
uint ob_store_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, v3d, &ob_store_len);
+ scene, view_layer, v3d, &ob_store_len);
opdata->ob_store = MEM_malloc_arrayN(ob_store_len, sizeof(*opdata->ob_store), __func__);
for (uint ob_index = 0; ob_index < ob_store_len; ob_index++) {
Object *obedit = objects[ob_index];
- float scale = mat4_to_scale(obedit->obmat);
+ float scale = mat4_to_scale(obedit->object_to_world);
opdata->max_obj_scale = max_ff(opdata->max_obj_scale, scale);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
if (em->bm->totvertsel > 0) {
@@ -260,7 +260,7 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
int otype = RNA_enum_get(op->ptr, "offset_type");
opdata->value_mode = (otype == BEVEL_AMT_PERCENT) ? OFFSET_VALUE_PERCENT : OFFSET_VALUE;
opdata->segments = (float)RNA_int_get(op->ptr, "segments");
- float pixels_per_inch = U.dpi * U.pixelsize;
+ float pixels_per_inch = U.dpi;
for (int i = 0; i < NUM_VALUE_KINDS; i++) {
opdata->shift_value[i] = -1.0f;
@@ -649,7 +649,7 @@ wmKeyMap *bevel_modal_keymap(wmKeyConfig *keyconf)
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Bevel Modal Map");
- /* This function is called for each spacetype, only needs to add map once */
+ /* This function is called for each space-type, only needs to add map once. */
if (keymap && keymap->modal_items) {
return NULL;
}
@@ -751,7 +751,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
/* Update offset accordingly to new offset_type. */
- if (!has_numinput && (ELEM(opdata->value_mode, OFFSET_VALUE, OFFSET_VALUE_PERCENT))) {
+ if (!has_numinput && ELEM(opdata->value_mode, OFFSET_VALUE, OFFSET_VALUE_PERCENT)) {
edbm_bevel_mouse_set_value(op, event);
}
edbm_bevel_calc(op);
diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c
index 7b251b77750..aab33678bec 100644
--- a/source/blender/editors/mesh/editmesh_bisect.c
+++ b/source/blender/editors/mesh/editmesh_bisect.c
@@ -99,6 +99,7 @@ static void mesh_bisect_interactive_calc(bContext *C,
static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
int valid_objects = 0;
@@ -111,7 +112,7 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -284,7 +285,7 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- CTX_data_view_layer(C), CTX_wm_view3d(C), &objects_len);
+ CTX_data_scene(C), CTX_data_view_layer(C), CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -313,9 +314,9 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op)
copy_v3_v3(plane_co_local, plane_co);
copy_v3_v3(plane_no_local, plane_no);
- invert_m4_m4(imat, obedit->obmat);
+ invert_m4_m4(imat, obedit->object_to_world);
mul_m4_v3(imat, plane_co_local);
- mul_transposed_mat3_m4_v3(obedit->obmat, plane_no_local);
+ mul_transposed_mat3_m4_v3(obedit->object_to_world, plane_no_local);
BMOperator bmop;
EDBM_op_init(
diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c
index 330008d92d1..88bcefc5cc8 100644
--- a/source/blender/editors/mesh/editmesh_extrude.c
+++ b/source/blender/editors/mesh/editmesh_extrude.c
@@ -55,8 +55,8 @@ static void edbm_extrude_edge_exclude_mirror(
float mtx[4][4];
if (mmd->mirror_ob) {
float imtx[4][4];
- invert_m4_m4(imtx, mmd->mirror_ob->obmat);
- mul_m4_m4m4(mtx, imtx, obedit->obmat);
+ invert_m4_m4(imtx, mmd->mirror_ob->object_to_world);
+ mul_m4_m4m4(mtx, imtx, obedit->object_to_world);
}
BM_ITER_MESH (edge, &iter, bm, BM_EDGES_OF_MESH) {
@@ -281,10 +281,11 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
mul_v3_fl(offset, scale_offset);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
float offset_local[3], tmat[3][3];
@@ -292,7 +293,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- copy_m3_m4(tmat, obedit->obmat);
+ copy_m3_m4(tmat, obedit->object_to_world);
invert_m3(tmat);
mul_v3_m3v3(offset_local, tmat, offset);
@@ -418,10 +419,11 @@ static bool edbm_extrude_mesh(Object *obedit, BMEditMesh *em, wmOperator *op)
/* extrude without transform */
static int edbm_extrude_region_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -477,10 +479,11 @@ void MESH_OT_extrude_region(wmOperatorType *ot)
/* extrude without transform */
static int edbm_extrude_context_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -531,10 +534,11 @@ void MESH_OT_extrude_context(wmOperatorType *ot)
static int edbm_extrude_verts_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -584,10 +588,11 @@ void MESH_OT_extrude_verts_indiv(wmOperatorType *ot)
static int edbm_extrude_edges_exec(bContext *C, wmOperator *op)
{
const bool use_normal_flip = RNA_boolean_get(op->ptr, "use_normal_flip");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -637,10 +642,11 @@ void MESH_OT_extrude_edges_indiv(wmOperatorType *ot)
static int edbm_extrude_faces_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -710,7 +716,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- vc.view_layer, vc.v3d, &objects_len);
+ vc.scene, vc.view_layer, vc.v3d, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
ED_view3d_viewcontext_init_object(&vc, obedit);
@@ -730,7 +736,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
}
mul_v3_fl(local_center, 1.0f / (float)local_verts_len);
- mul_m4_v3(vc.obedit->obmat, local_center);
+ mul_m4_v3(vc.obedit->object_to_world, local_center);
mul_v3_fl(local_center, (float)local_verts_len);
add_v3_v3(center, local_center);
@@ -755,11 +761,11 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
continue;
}
- invert_m4_m4(vc.obedit->imat, vc.obedit->obmat);
+ invert_m4_m4(vc.obedit->world_to_object, vc.obedit->object_to_world);
ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
float local_center[3];
- mul_v3_m4v3(local_center, vc.obedit->imat, center);
+ mul_v3_m4v3(local_center, vc.obedit->world_to_object, center);
/* call extrude? */
if (verts_len != 0) {
@@ -785,8 +791,8 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
/* 2D rotate by 90d while adding.
* (x, y) = (y, -x)
*
- * accumulate the screenspace normal in 2D,
- * with screenspace edge length weighting the result. */
+ * Accumulate the screen-space normal in 2D,
+ * with screen-space edge length weighting the result. */
if (line_point_side_v2(co1, co2, mval_f) >= 0.0f) {
nor[0] += (co1[1] - co2[1]);
nor[1] += -(co1[0] - co2[0]);
@@ -804,11 +810,11 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
float view_vec[3], cross[3];
/* convert the 2D normal into 3D */
- mul_mat3_m4_v3(vc.rv3d->viewinv, nor); /* World-space. */
- mul_mat3_m4_v3(vc.obedit->imat, nor); /* Local-space. */
+ mul_mat3_m4_v3(vc.rv3d->viewinv, nor); /* World-space. */
+ mul_mat3_m4_v3(vc.obedit->world_to_object, nor); /* Local-space. */
/* correct the normal to be aligned on the view plane */
- mul_v3_mat3_m4v3(view_vec, vc.obedit->imat, vc.rv3d->viewinv[2]);
+ mul_v3_mat3_m4v3(view_vec, vc.obedit->world_to_object, vc.rv3d->viewinv[2]);
cross_v3_v3v3(cross, nor, view_vec);
cross_v3_v3v3(nor, view_vec, cross);
normalize_v3(nor);
@@ -817,9 +823,9 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
/* center */
copy_v3_v3(ofs, local_center);
- mul_m4_v3(vc.obedit->obmat, ofs); /* view space */
+ mul_m4_v3(vc.obedit->object_to_world, ofs); /* view space */
ED_view3d_win_to_3d_int(vc.v3d, vc.region, ofs, event->mval, ofs);
- mul_m4_v3(vc.obedit->imat, ofs); /* back in object space */
+ mul_m4_v3(vc.obedit->world_to_object, ofs); /* back in object space */
sub_v3_v3(ofs, local_center);
@@ -870,7 +876,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
copy_v3_v3(local_center, cursor);
ED_view3d_win_to_3d_int(vc.v3d, vc.region, local_center, event->mval, local_center);
- mul_m4_v3(vc.obedit->imat, local_center); /* back in object space */
+ mul_m4_v3(vc.obedit->world_to_object, local_center); /* back in object space */
EDBM_op_init(vc.em, &bmop, op, "create_vert co=%v", local_center);
BMO_op_exec(vc.em->bm, &bmop);
diff --git a/source/blender/editors/mesh/editmesh_extrude_screw.c b/source/blender/editors/mesh/editmesh_extrude_screw.c
index 5addd67ab58..9d0bcfe4e90 100644
--- a/source/blender/editors/mesh/editmesh_extrude_screw.c
+++ b/source/blender/editors/mesh/editmesh_extrude_screw.c
@@ -49,9 +49,10 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
RNA_float_get_array(op->ptr, "axis", axis);
uint objects_len = 0;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -101,11 +102,11 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
continue;
}
- copy_v3_v3(nor, obedit->obmat[2]);
+ copy_v3_v3(nor, obedit->object_to_world[2]);
/* calculate dvec */
- mul_v3_m4v3(v1_co_global, obedit->obmat, v1->co);
- mul_v3_m4v3(v2_co_global, obedit->obmat, v2->co);
+ mul_v3_m4v3(v1_co_global, obedit->object_to_world, v1->co);
+ mul_v3_m4v3(v2_co_global, obedit->object_to_world, v2->co);
sub_v3_v3v3(dvec, v1_co_global, v2_co_global);
mul_v3_fl(dvec, 1.0f / steps);
@@ -125,7 +126,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
dvec,
turns * steps,
DEG2RADF(360.0f * turns),
- obedit->obmat,
+ obedit->object_to_world,
false)) {
continue;
}
diff --git a/source/blender/editors/mesh/editmesh_extrude_spin.c b/source/blender/editors/mesh/editmesh_extrude_spin.c
index ec04ece6569..756d7f73d10 100644
--- a/source/blender/editors/mesh/editmesh_extrude_spin.c
+++ b/source/blender/editors/mesh/editmesh_extrude_spin.c
@@ -36,6 +36,7 @@
static int edbm_spin_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
float cent[3], axis[3];
const float d[3] = {0.0f, 0.0f, 0.0f};
@@ -47,7 +48,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
const bool use_normal_flip = RNA_boolean_get(op->ptr, "use_normal_flip");
const bool dupli = RNA_boolean_get(op->ptr, "dupli");
const bool use_auto_merge = (RNA_boolean_get(op->ptr, "use_auto_merge") && (dupli == false) &&
- (steps >= 3) && fabsf((fabsf(angle) - (float)(M_PI * 2))) <= 1e-6f);
+ (steps >= 3) && fabsf(fabsf(angle) - (float)(M_PI * 2)) <= 1e-6f);
if (is_zero_v3(axis)) {
BKE_report(op->reports, RPT_ERROR, "Invalid/unset axis");
@@ -56,7 +57,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -76,7 +77,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
d,
steps,
-angle,
- obedit->obmat,
+ obedit->object_to_world,
use_normal_flip,
dupli,
use_auto_merge)) {
diff --git a/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c b/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c
index 687f06c8dcf..19e23f4f212 100644
--- a/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c
+++ b/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c
@@ -362,7 +362,7 @@ static void gizmo_mesh_spin_init_refresh(const bContext *C, wmGizmoGroup *gzgrou
}
if (totsel) {
mul_v3_fl(select_center, 1.0f / totsel);
- mul_m4_v3(obedit->obmat, select_center);
+ mul_m4_v3(obedit->object_to_world, select_center);
copy_v3_v3(ggd->data.select_center, select_center);
ggd->data.use_select_center = true;
}
diff --git a/source/blender/editors/mesh/editmesh_inset.c b/source/blender/editors/mesh/editmesh_inset.c
index ae21e6143f6..fa4ae7f984c 100644
--- a/source/blender/editors/mesh/editmesh_inset.c
+++ b/source/blender/editors/mesh/editmesh_inset.c
@@ -132,11 +132,11 @@ static bool edbm_inset_init(bContext *C, wmOperator *op, const bool is_modal)
{
uint ob_store_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &ob_store_len);
+ scene, view_layer, CTX_wm_view3d(C), &ob_store_len);
opdata->ob_store = MEM_malloc_arrayN(ob_store_len, sizeof(*opdata->ob_store), __func__);
for (uint ob_index = 0; ob_index < ob_store_len; ob_index++) {
Object *obedit = objects[ob_index];
- float scale = mat4_to_scale(obedit->obmat);
+ float scale = mat4_to_scale(obedit->object_to_world);
opdata->max_obj_scale = max_ff(opdata->max_obj_scale, scale);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
if (em->bm->totvertsel > 0) {
diff --git a/source/blender/editors/mesh/editmesh_intersect.c b/source/blender/editors/mesh/editmesh_intersect.c
index 166eb40a7db..83cefd1c09d 100644
--- a/source/blender/editors/mesh/editmesh_intersect.c
+++ b/source/blender/editors/mesh/editmesh_intersect.c
@@ -180,11 +180,12 @@ static int edbm_intersect_exec(bContext *C, wmOperator *op)
default: /* ISECT_SEPARATE_NONE */
break;
}
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
uint isect_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -350,11 +351,12 @@ static int edbm_intersect_boolean_exec(bContext *C, wmOperator *op)
bool has_isect;
test_fn = use_swap ? bm_face_isect_pair_swap : bm_face_isect_pair;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
uint isect_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -815,10 +817,11 @@ static int edbm_face_split_by_edges_exec(bContext *C, wmOperator *UNUSED(op))
BLI_SMALLSTACK_DECLARE(loop_stack, BMLoop *);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 6062048e993..369162e80a3 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -100,7 +100,7 @@ typedef struct KnifeColors {
/* Knife-tool Operator. */
typedef struct KnifeVert {
Object *ob;
- uint base_index;
+ uint ob_index;
BMVert *v; /* Non-NULL if this is an original vert. */
ListBase edges;
ListBase faces;
@@ -142,7 +142,7 @@ typedef struct KnifeLineHit {
KnifeVert *v;
BMFace *f;
Object *ob;
- uint base_index;
+ uint ob_index;
} KnifeLineHit;
typedef struct KnifePosData {
@@ -156,7 +156,7 @@ typedef struct KnifePosData {
KnifeEdge *edge;
BMFace *bmface;
Object *ob; /* Object of the vert, edge or bmface. */
- uint base_index;
+ uint ob_index;
/* When true, the cursor isn't over a face. */
bool is_space;
@@ -182,7 +182,7 @@ typedef struct KnifeBVH {
BVHTree *tree; /* Knife Custom BVH Tree. */
BMLoop *(*looptris)[3]; /* Used by #knife_bvh_raycast_cb to store the intersecting looptri. */
float uv[2]; /* Used by #knife_bvh_raycast_cb to store the intersecting uv. */
- uint base_index;
+ uint ob_index;
/* Use #bm_ray_cast_cb_elem_not_in_face_check. */
bool (*filter_cb)(BMFace *f, void *userdata);
@@ -218,6 +218,7 @@ typedef struct KnifeTool_OpData {
/* Used for swapping current object when in multi-object edit mode. */
Object **objects;
uint objects_len;
+ bool objects_free;
/** Array `objects_len` length of additional per-object data. */
KnifeObjectInfo *objects_info;
@@ -495,7 +496,7 @@ static void knifetool_draw_visible_distances(const KnifeTool_OpData *kcd)
float numstr_size[2];
float posit[2];
const float bg_margin = 4.0f * U.dpi_fac;
- const float font_size = 14.0f * U.pixelsize;
+ const float font_size = 14.0f;
const int distance_precision = 4;
/* Calculate distance and convert to string. */
@@ -516,7 +517,7 @@ static void knifetool_draw_visible_distances(const KnifeTool_OpData *kcd)
}
BLF_enable(blf_mono_font, BLF_ROTATION);
- BLF_size(blf_mono_font, font_size, U.dpi);
+ BLF_size(blf_mono_font, font_size * U.dpi_fac);
BLF_rotation(blf_mono_font, 0.0f);
BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
@@ -565,7 +566,7 @@ static void knifetool_draw_angle(const KnifeTool_OpData *kcd,
const float arc_size = 64.0f * U.dpi_fac;
const float bg_margin = 4.0f * U.dpi_fac;
const float cap_size = 4.0f * U.dpi_fac;
- const float font_size = 14.0f * U.pixelsize;
+ const float font_size = 14.0f;
const int angle_precision = 3;
/* Angle arc in 3d space. */
@@ -585,9 +586,9 @@ static void knifetool_draw_angle(const KnifeTool_OpData *kcd,
float axis[3];
float arc_angle;
- const float inverse_average_scale = 1 /
- (kcd->curr.ob->obmat[0][0] + kcd->curr.ob->obmat[1][1] +
- kcd->curr.ob->obmat[2][2]);
+ const float inverse_average_scale = 1 / (kcd->curr.ob->object_to_world[0][0] +
+ kcd->curr.ob->object_to_world[1][1] +
+ kcd->curr.ob->object_to_world[2][2]);
const float px_scale =
3.0f * inverse_average_scale *
@@ -646,7 +647,7 @@ static void knifetool_draw_angle(const KnifeTool_OpData *kcd,
}
BLF_enable(blf_mono_font, BLF_ROTATION);
- BLF_size(blf_mono_font, font_size, U.dpi);
+ BLF_size(blf_mono_font, font_size * U.dpi_fac);
BLF_rotation(blf_mono_font, 0.0f);
BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
@@ -1158,11 +1159,11 @@ static void knife_update_header(bContext *C, wmOperator *op, KnifeTool_OpData *k
* \{ */
static const int *knife_bm_tri_index_get(const KnifeTool_OpData *kcd,
- int base_index,
+ int ob_index,
int tri_index,
int tri_index_buf[3])
{
- const KnifeObjectInfo *obinfo = &kcd->objects_info[base_index];
+ const KnifeObjectInfo *obinfo = &kcd->objects_info[ob_index];
if (obinfo->tri_indices) {
return obinfo->tri_indices[tri_index];
}
@@ -1173,27 +1174,27 @@ static const int *knife_bm_tri_index_get(const KnifeTool_OpData *kcd,
}
static void knife_bm_tri_cagecos_get(const KnifeTool_OpData *kcd,
- int base_index,
+ int ob_index,
int tri_index,
float cos[3][3])
{
- const KnifeObjectInfo *obinfo = &kcd->objects_info[base_index];
+ const KnifeObjectInfo *obinfo = &kcd->objects_info[ob_index];
int tri_ind_buf[3];
- const int *tri_ind = knife_bm_tri_index_get(kcd, base_index, tri_index, tri_ind_buf);
+ const int *tri_ind = knife_bm_tri_index_get(kcd, ob_index, tri_index, tri_ind_buf);
for (int i = 0; i < 3; i++) {
copy_v3_v3(cos[i], obinfo->cagecos[tri_ind[i]]);
}
}
static void knife_bm_tri_cagecos_get_worldspace(const KnifeTool_OpData *kcd,
- int base_index,
+ int ob_index,
int tri_index,
float cos[3][3])
{
- knife_bm_tri_cagecos_get(kcd, base_index, tri_index, cos);
- const Object *ob = kcd->objects[base_index];
+ knife_bm_tri_cagecos_get(kcd, ob_index, tri_index, cos);
+ const Object *ob = kcd->objects[ob_index];
for (int i = 0; i < 3; i++) {
- mul_m4_v3(ob->obmat, cos[i]);
+ mul_m4_v3(ob->object_to_world, cos[i]);
}
}
@@ -1220,7 +1221,7 @@ static void knife_bvh_init(KnifeTool_OpData *kcd)
/* Test Function. */
bool (*test_fn)(BMFace *);
- if ((kcd->only_select && kcd->cut_through)) {
+ if (kcd->only_select && kcd->cut_through) {
test_fn = knife_bm_face_is_select;
}
else {
@@ -1236,9 +1237,9 @@ static void knife_bvh_init(KnifeTool_OpData *kcd)
bool test_fn_ret = false;
/* Calculate tottri. */
- for (uint b = 0; b < kcd->objects_len; b++) {
+ for (uint ob_index = 0; ob_index < kcd->objects_len; ob_index++) {
ob_tottri = 0;
- ob = kcd->objects[b];
+ ob = kcd->objects[ob_index];
em = BKE_editmesh_from_object(ob);
for (int i = 0; i < em->tottri; i++) {
@@ -1268,8 +1269,8 @@ static void knife_bvh_init(KnifeTool_OpData *kcd)
* Don't forget to update #knife_bvh_intersect_plane!
*/
tottri = 0;
- for (uint b = 0; b < kcd->objects_len; b++) {
- ob = kcd->objects[b];
+ for (uint ob_index = 0; ob_index < kcd->objects_len; ob_index++) {
+ ob = kcd->objects[ob_index];
em = BKE_editmesh_from_object(ob);
looptris = em->looptris;
@@ -1286,7 +1287,7 @@ static void knife_bvh_init(KnifeTool_OpData *kcd)
}
float tri_cos[3][3];
- knife_bm_tri_cagecos_get_worldspace(kcd, b, i, tri_cos);
+ knife_bm_tri_cagecos_get_worldspace(kcd, ob_index, i, tri_cos);
BLI_bvhtree_insert(kcd->bvh.tree, i + tottri, &tri_cos[0][0], 3);
}
@@ -1324,10 +1325,10 @@ static void knife_bvh_raycast_cb(void *userdata,
int tottri;
tottri = 0;
- uint b = 0;
- for (; b < kcd->objects_len; b++) {
+ uint ob_index = 0;
+ for (; ob_index < kcd->objects_len; ob_index++) {
index -= tottri;
- ob = kcd->objects[b];
+ ob = kcd->objects[ob_index];
em = BKE_editmesh_from_object(ob);
tottri = em->tottri;
if (index < tottri) {
@@ -1343,7 +1344,7 @@ static void knife_bvh_raycast_cb(void *userdata,
}
float tri_cos[3][3];
- knife_bm_tri_cagecos_get_worldspace(kcd, b, index, tri_cos);
+ knife_bm_tri_cagecos_get_worldspace(kcd, ob_index, index, tri_cos);
isect = (ray->radius > 0.0f ?
isect_ray_tri_epsilon_v3(
ray->origin, ray->direction, UNPACK3(tri_cos), &dist, uv, ray->radius) :
@@ -1370,7 +1371,7 @@ static void knife_bvh_raycast_cb(void *userdata,
kcd->bvh.looptris = em->looptris;
copy_v2_v2(kcd->bvh.uv, uv);
- kcd->bvh.base_index = b;
+ kcd->bvh.ob_index = ob_index;
}
}
@@ -1382,7 +1383,7 @@ static BMFace *knife_bvh_raycast(KnifeTool_OpData *kcd,
float *r_dist,
float r_hitout[3],
float r_cagehit[3],
- uint *r_base_index)
+ uint *r_ob_index)
{
BMFace *face;
BVHTreeRayHit hit;
@@ -1399,7 +1400,7 @@ static BMFace *knife_bvh_raycast(KnifeTool_OpData *kcd,
/* Hits returned in world space. */
if (r_hitout) {
float tri_cos[3][3];
- knife_bm_tri_cagecos_get_worldspace(kcd, kcd->bvh.base_index, hit.index, tri_cos);
+ knife_bm_tri_cagecos_get_worldspace(kcd, kcd->bvh.ob_index, hit.index, tri_cos);
interp_v3_v3v3v3_uv(r_hitout, UNPACK3(tri_cos), kcd->bvh.uv);
if (r_cagehit) {
@@ -1411,8 +1412,8 @@ static BMFace *knife_bvh_raycast(KnifeTool_OpData *kcd,
*r_dist = hit.dist;
}
- if (r_base_index) {
- *r_base_index = kcd->bvh.base_index;
+ if (r_ob_index) {
+ *r_ob_index = kcd->bvh.ob_index;
}
return face;
@@ -1428,7 +1429,7 @@ static BMFace *knife_bvh_raycast_filter(KnifeTool_OpData *kcd,
float *r_dist,
float r_hitout[3],
float r_cagehit[3],
- uint *r_base_index,
+ uint *r_ob_index,
bool (*filter_cb)(BMFace *f, void *userdata),
void *filter_userdata)
{
@@ -1453,7 +1454,7 @@ static BMFace *knife_bvh_raycast_filter(KnifeTool_OpData *kcd,
/* Hits returned in world space. */
if (r_hitout) {
float tri_cos[3][3];
- knife_bm_tri_cagecos_get_worldspace(kcd, kcd->bvh.base_index, hit.index, tri_cos);
+ knife_bm_tri_cagecos_get_worldspace(kcd, kcd->bvh.ob_index, hit.index, tri_cos);
interp_v3_v3v3v3_uv(r_hitout, UNPACK3(tri_cos), kcd->bvh.uv);
if (r_cagehit) {
@@ -1465,8 +1466,8 @@ static BMFace *knife_bvh_raycast_filter(KnifeTool_OpData *kcd,
*r_dist = hit.dist;
}
- if (r_base_index) {
- *r_base_index = kcd->bvh.base_index;
+ if (r_ob_index) {
+ *r_ob_index = kcd->bvh.ob_index;
}
return face;
@@ -1726,7 +1727,7 @@ static KnifeEdge *new_knife_edge(KnifeTool_OpData *kcd)
}
/* Get a KnifeVert wrapper for an existing BMVert. */
-static KnifeVert *get_bm_knife_vert(KnifeTool_OpData *kcd, BMVert *v, Object *ob, uint base_index)
+static KnifeVert *get_bm_knife_vert(KnifeTool_OpData *kcd, BMVert *v, Object *ob, uint ob_index)
{
KnifeVert *kfv = BLI_ghash_lookup(kcd->origvertmap, v);
const float *cageco;
@@ -1736,19 +1737,19 @@ static KnifeVert *get_bm_knife_vert(KnifeTool_OpData *kcd, BMVert *v, Object *ob
BMFace *f;
if (BM_elem_index_get(v) >= 0) {
- cageco = kcd->objects_info[base_index].cagecos[BM_elem_index_get(v)];
+ cageco = kcd->objects_info[ob_index].cagecos[BM_elem_index_get(v)];
}
else {
cageco = v->co;
}
float cageco_ws[3];
- mul_v3_m4v3(cageco_ws, ob->obmat, cageco);
+ mul_v3_m4v3(cageco_ws, ob->object_to_world, cageco);
kfv = new_knife_vert(kcd, v->co, cageco_ws);
kfv->v = v;
kfv->ob = ob;
- kfv->base_index = base_index;
+ kfv->ob_index = ob_index;
BLI_ghash_insert(kcd->origvertmap, v, kfv);
BM_ITER_ELEM (f, &bmiter, v, BM_FACES_OF_VERT) {
@@ -1760,7 +1761,7 @@ static KnifeVert *get_bm_knife_vert(KnifeTool_OpData *kcd, BMVert *v, Object *ob
}
/* Get a KnifeEdge wrapper for an existing BMEdge. */
-static KnifeEdge *get_bm_knife_edge(KnifeTool_OpData *kcd, BMEdge *e, Object *ob, uint base_index)
+static KnifeEdge *get_bm_knife_edge(KnifeTool_OpData *kcd, BMEdge *e, Object *ob, uint ob_index)
{
KnifeEdge *kfe = BLI_ghash_lookup(kcd->origedgemap, e);
if (!kfe) {
@@ -1769,8 +1770,8 @@ static KnifeEdge *get_bm_knife_edge(KnifeTool_OpData *kcd, BMEdge *e, Object *ob
kfe = new_knife_edge(kcd);
kfe->e = e;
- kfe->v1 = get_bm_knife_vert(kcd, e->v1, ob, base_index);
- kfe->v2 = get_bm_knife_vert(kcd, e->v2, ob, base_index);
+ kfe->v1 = get_bm_knife_vert(kcd, e->v1, ob, ob_index);
+ kfe->v2 = get_bm_knife_vert(kcd, e->v2, ob, ob_index);
knife_add_to_vert_edges(kcd, kfe);
@@ -1784,10 +1785,7 @@ static KnifeEdge *get_bm_knife_edge(KnifeTool_OpData *kcd, BMEdge *e, Object *ob
return kfe;
}
-static ListBase *knife_get_face_kedges(KnifeTool_OpData *kcd,
- Object *ob,
- uint base_index,
- BMFace *f)
+static ListBase *knife_get_face_kedges(KnifeTool_OpData *kcd, Object *ob, uint ob_index, BMFace *f)
{
ListBase *list = BLI_ghash_lookup(kcd->kedgefacemap, f);
@@ -1798,7 +1796,7 @@ static ListBase *knife_get_face_kedges(KnifeTool_OpData *kcd,
list = knife_empty_list(kcd);
BM_ITER_ELEM (e, &bmiter, f, BM_EDGES_OF_FACE) {
- knife_append_list(kcd, list, get_bm_knife_edge(kcd, e, ob, base_index));
+ knife_append_list(kcd, list, get_bm_knife_edge(kcd, e, ob, ob_index));
}
BLI_ghash_insert(kcd->kedgefacemap, f, list);
@@ -1809,7 +1807,7 @@ static ListBase *knife_get_face_kedges(KnifeTool_OpData *kcd,
static void knife_edge_append_face(KnifeTool_OpData *kcd, KnifeEdge *kfe, BMFace *f)
{
- knife_append_list(kcd, knife_get_face_kedges(kcd, kfe->v1->ob, kfe->v1->base_index, f), kfe);
+ knife_append_list(kcd, knife_get_face_kedges(kcd, kfe->v1->ob, kfe->v1->ob_index, f), kfe);
knife_append_list(kcd, &kfe->faces, f);
}
@@ -1826,7 +1824,7 @@ static KnifeVert *knife_split_edge(KnifeTool_OpData *kcd,
newkfe->v1 = kfe->v1;
newkfe->v2 = new_knife_vert(kcd, co, cageco);
newkfe->v2->ob = kfe->v1->ob;
- newkfe->v2->base_index = kfe->v1->base_index;
+ newkfe->v2->ob_index = kfe->v1->ob_index;
newkfe->v2->is_cut = true;
if (kfe->e) {
knife_add_edge_faces_to_vert(kcd, newkfe->v2, kfe->e);
@@ -2068,7 +2066,7 @@ static bool knife_add_single_cut__is_linehit_outside_face(BMFace *f,
return true;
}
}
- else if ((lh->kfe && lh->kfe->e)) {
+ else if (lh->kfe && lh->kfe->e) {
BMLoop *l; /* side-of-edge */
if ((l = BM_face_edge_share_loop(f, lh->kfe->e)) &&
(BM_loop_point_side_of_edge_test(l, co) < 0.0f)) {
@@ -2123,7 +2121,7 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd,
BLI_assert(lh1->f);
kfe->v1 = new_knife_vert(kcd, lh1->hit, lh1->cagehit);
kfe->v1->ob = lh1->ob;
- kfe->v1->base_index = lh1->base_index;
+ kfe->v1->ob_index = lh1->ob_index;
kfe->v1->is_cut = true;
kfe->v1->is_face = true;
knife_append_list(kcd, &kfe->v1->faces, lh1->f);
@@ -2141,7 +2139,7 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd,
BLI_assert(lh2->f);
kfe->v2 = new_knife_vert(kcd, lh2->hit, lh2->cagehit);
kfe->v2->ob = lh2->ob;
- kfe->v2->base_index = lh2->base_index;
+ kfe->v2->ob_index = lh2->ob_index;
kfe->v2->is_cut = true;
kfe->v2->is_face = true;
knife_append_list(kcd, &kfe->v2->faces, lh2->f);
@@ -2567,7 +2565,7 @@ static bool knife_ray_intersect_face(KnifeTool_OpData *kcd,
const float v1[3],
const float v2[3],
Object *ob,
- uint base_index,
+ uint ob_index,
BMFace *f,
const float face_tol_sq,
float hit_co[3],
@@ -2600,7 +2598,7 @@ static bool knife_ray_intersect_face(KnifeTool_OpData *kcd,
break;
}
- knife_bm_tri_cagecos_get_worldspace(kcd, base_index, tri_i, tri_cos);
+ knife_bm_tri_cagecos_get_worldspace(kcd, ob_index, tri_i, tri_cos);
/* Using epsilon test in case ray is directly through an internal
* tessellation edge and might not hit either tessellation tri with
@@ -2617,7 +2615,7 @@ static bool knife_ray_intersect_face(KnifeTool_OpData *kcd,
}
interp_v3_v3v3v3_uv(hit_cageco, UNPACK3(tri_cos), ray_tri_uv);
/* Now check that far enough away from verts and edges. */
- list = knife_get_face_kedges(kcd, ob, base_index, f);
+ list = knife_get_face_kedges(kcd, ob, ob_index, f);
for (ref = list->first; ref; ref = ref->next) {
kfe = ref->ref;
if (kfe->is_invalid) {
@@ -2651,22 +2649,22 @@ static void calc_ortho_extent(KnifeTool_OpData *kcd)
float ws[3];
INIT_MINMAX(min, max);
- for (uint b = 0; b < kcd->objects_len; b++) {
- ob = kcd->objects[b];
+ for (uint ob_index = 0; ob_index < kcd->objects_len; ob_index++) {
+ ob = kcd->objects[ob_index];
em = BKE_editmesh_from_object(ob);
- const float(*cagecos)[3] = kcd->objects_info[b].cagecos;
+ const float(*cagecos)[3] = kcd->objects_info[ob_index].cagecos;
if (cagecos) {
for (int i = 0; i < em->bm->totvert; i++) {
copy_v3_v3(ws, cagecos[i]);
- mul_m4_v3(ob->obmat, ws);
+ mul_m4_v3(ob->object_to_world, ws);
minmax_v3v3_v3(min, max, ws);
}
}
else {
BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
copy_v3_v3(ws, v->co);
- mul_m4_v3(ob->obmat, ws);
+ mul_m4_v3(ob->object_to_world, ws);
minmax_v3v3_v3(min, max, ws);
}
}
@@ -2930,11 +2928,11 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
Object *ob;
BMEditMesh *em;
- uint b = 0;
for (i = 0, result = results; i < tot; i++, result++) {
- for (b = 0; b < kcd->objects_len; b++) {
- ob = kcd->objects[b];
+ uint ob_index = 0;
+ for (ob_index = 0; ob_index < kcd->objects_len; ob_index++) {
+ ob = kcd->objects[ob_index];
em = BKE_editmesh_from_object(ob);
if (*result >= 0 && *result < em->tottri) {
ls = (BMLoop **)em->looptris[*result];
@@ -2956,9 +2954,9 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
}
/* Don't care what the value is except that it is non-NULL, for iterator. */
BLI_smallhash_insert(&faces, (uintptr_t)f, f);
- BLI_smallhash_insert(&fobs, (uintptr_t)f, (void *)(uintptr_t)b);
+ BLI_smallhash_insert(&fobs, (uintptr_t)f, (void *)(uintptr_t)ob_index);
- list = knife_get_face_kedges(kcd, ob, b, f);
+ list = knife_get_face_kedges(kcd, ob, ob_index, f);
for (ref = list->first; ref; ref = ref->next) {
kfe = ref->ref;
if (kfe->is_invalid) {
@@ -3016,7 +3014,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
knife_project_v2(kcd, v->cageco, s);
float d = dist_squared_to_line_segment_v2(s, s1, s2);
if ((d <= vert_tol_sq) &&
- (point_is_visible(kcd, v->cageco, s, bm_elem_from_knife_vert(v, &kfe_hit)))) {
+ point_is_visible(kcd, v->cageco, s, bm_elem_from_knife_vert(v, &kfe_hit))) {
kfv_is_in_cut = true;
}
}
@@ -3033,7 +3031,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
}
hit.ob = v->ob;
- hit.base_index = v->base_index;
+ hit.ob_index = v->ob_index;
copy_v3_v3(hit.hit, v->co);
copy_v3_v3(hit.cagehit, v->cageco);
copy_v2_v2(hit.schit, s);
@@ -3109,7 +3107,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
transform_point_by_seg_v3(
hit.hit, p_cage, kfe->v1->co, kfe->v2->co, kfe->v1->cageco, kfe->v2->cageco);
hit.ob = kfe->v1->ob;
- hit.base_index = kfe->v1->base_index;
+ hit.ob_index = kfe->v1->ob_index;
copy_v3_v3(hit.cagehit, p_cage);
copy_v2_v2(hit.schit, sint);
hit.perc = lambda;
@@ -3129,16 +3127,16 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
val = BLI_smallhash_iternext(&hiter, (uintptr_t *)&f)) {
float p[3], p_cage[3];
- uint base_index = (uint)(uintptr_t)BLI_smallhash_lookup(&fobs, (uintptr_t)f);
- ob = kcd->objects[base_index];
+ uint ob_index = (uint)(uintptr_t)BLI_smallhash_lookup(&fobs, (uintptr_t)f);
+ ob = kcd->objects[ob_index];
if (use_hit_prev &&
- knife_ray_intersect_face(kcd, s1, v1, v3, ob, base_index, f, face_tol_sq, p, p_cage)) {
+ knife_ray_intersect_face(kcd, s1, v1, v3, ob, ob_index, f, face_tol_sq, p, p_cage)) {
if (point_is_visible(kcd, p_cage, s1, (BMElem *)f)) {
memset(&hit, 0, sizeof(hit));
hit.f = f;
hit.ob = ob;
- hit.base_index = base_index;
+ hit.ob_index = ob_index;
copy_v3_v3(hit.hit, p);
copy_v3_v3(hit.cagehit, p_cage);
copy_v2_v2(hit.schit, s1);
@@ -3148,12 +3146,12 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
}
if (use_hit_curr &&
- knife_ray_intersect_face(kcd, s2, v2, v4, ob, base_index, f, face_tol_sq, p, p_cage)) {
+ knife_ray_intersect_face(kcd, s2, v2, v4, ob, ob_index, f, face_tol_sq, p, p_cage)) {
if (point_is_visible(kcd, p_cage, s2, (BMElem *)f)) {
memset(&hit, 0, sizeof(hit));
hit.f = f;
hit.ob = ob;
- hit.base_index = base_index;
+ hit.ob_index = ob_index;
copy_v3_v3(hit.hit, p);
copy_v3_v3(hit.cagehit, p_cage);
copy_v2_v2(hit.schit, s2);
@@ -3205,7 +3203,7 @@ static void knife_pos_data_clear(KnifePosData *kpd)
static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd,
Object **r_ob,
- uint *r_base_index,
+ uint *r_ob_index,
bool *is_space,
float r_co[3],
float r_cageco[3])
@@ -3221,7 +3219,7 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd,
sub_v3_v3v3(ray, origin_ofs, origin);
normalize_v3_v3(ray_normal, ray);
- f = knife_bvh_raycast(kcd, origin, ray_normal, 0.0f, NULL, r_co, r_cageco, r_base_index);
+ f = knife_bvh_raycast(kcd, origin, ray_normal, 0.0f, NULL, r_co, r_cageco, r_ob_index);
if (f && kcd->only_select && BM_elem_flag_test(f, BM_ELEM_SELECT) == 0) {
f = NULL;
@@ -3232,7 +3230,7 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd,
}
if (f) {
- *r_ob = kcd->objects[*r_base_index];
+ *r_ob = kcd->objects[*r_ob_index];
}
else {
if (kcd->is_interactive) {
@@ -3267,7 +3265,7 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd,
static int knife_sample_screen_density_from_closest_face(KnifeTool_OpData *kcd,
const float radius,
Object *ob,
- uint base_index,
+ uint ob_index,
BMFace *f,
const float cageco[3])
{
@@ -3280,7 +3278,7 @@ static int knife_sample_screen_density_from_closest_face(KnifeTool_OpData *kcd,
knife_project_v2(kcd, cageco, sco);
- list = knife_get_face_kedges(kcd, ob, base_index, f);
+ list = knife_get_face_kedges(kcd, ob, ob_index, f);
for (ref = list->first; ref; ref = ref->next) {
KnifeEdge *kfe = ref->ref;
int i;
@@ -3329,7 +3327,7 @@ static float knife_snap_size(KnifeTool_OpData *kcd, float maxsize)
if (!kcd->curr.is_space) {
density = (float)knife_sample_screen_density_from_closest_face(
- kcd, maxsize * 2.0f, kcd->curr.ob, kcd->curr.base_index, kcd->curr.bmface, kcd->curr.cage);
+ kcd, maxsize * 2.0f, kcd->curr.ob, kcd->curr.ob_index, kcd->curr.bmface, kcd->curr.cage);
}
return density ? min_ff(maxsize / ((float)density * 0.5f), maxsize) : maxsize;
@@ -3388,7 +3386,7 @@ static void knife_interp_v3_v3v3(const KnifeTool_OpData *kcd,
/* p is closest point on edge to the mouse cursor. */
static KnifeEdge *knife_find_closest_edge_of_face(
- KnifeTool_OpData *kcd, Object *ob, uint base_index, BMFace *f, float p[3], float cagep[3])
+ KnifeTool_OpData *kcd, Object *ob, uint ob_index, BMFace *f, float p[3], float cagep[3])
{
float sco[2];
float maxdist;
@@ -3414,7 +3412,7 @@ static KnifeEdge *knife_find_closest_edge_of_face(
knife_project_v2(kcd, cagep, sco);
/* Look through all edges associated with this face. */
- list = knife_get_face_kedges(kcd, ob, base_index, f);
+ list = knife_get_face_kedges(kcd, ob, ob_index, f);
for (ref = list->first; ref; ref = ref->next) {
KnifeEdge *kfe = ref->ref;
float kfv1_sco[2], kfv2_sco[2], test_cagep[3];
@@ -3479,7 +3477,7 @@ static KnifeEdge *knife_find_closest_edge_of_face(
* this is important for angle snap, which uses the previous mouse position. */
edgesnap = new_knife_vert(kcd, p, cagep);
edgesnap->ob = ob;
- edgesnap->base_index = base_index;
+ edgesnap->ob_index = ob_index;
knife_project_v2(kcd, edgesnap->cageco, kcd->curr.mval);
}
@@ -3906,14 +3904,14 @@ static bool knife_snap_update_from_mval(KnifeTool_OpData *kcd, const float mval[
kcd->curr.ob = kcd->vc.obedit;
kcd->curr.bmface = knife_find_closest_face(kcd,
&kcd->curr.ob,
- &kcd->curr.base_index,
+ &kcd->curr.ob_index,
&kcd->curr.is_space,
kcd->curr.co,
kcd->curr.cage);
if (kcd->curr.bmface) {
kcd->curr.edge = knife_find_closest_edge_of_face(
- kcd, kcd->curr.ob, kcd->curr.base_index, kcd->curr.bmface, kcd->curr.co, kcd->curr.cage);
+ kcd, kcd->curr.ob, kcd->curr.ob_index, kcd->curr.bmface, kcd->curr.co, kcd->curr.cage);
}
if (kcd->curr.edge) {
@@ -4017,7 +4015,7 @@ static void knifetool_undo(KnifeTool_OpData *kcd)
static void knifetool_init_obinfo(KnifeTool_OpData *kcd,
Object *ob,
- uint base_index,
+ uint ob_index,
bool use_tri_indices)
{
@@ -4027,7 +4025,7 @@ static void knifetool_init_obinfo(KnifeTool_OpData *kcd,
BM_mesh_elem_index_ensure(em_eval->bm, BM_VERT);
- KnifeObjectInfo *obinfo = &kcd->objects_info[base_index];
+ KnifeObjectInfo *obinfo = &kcd->objects_info[ob_index];
obinfo->em = em_eval;
obinfo->cagecos = (const float(*)[3])BKE_editmesh_vert_coords_alloc(
kcd->vc.depsgraph, em_eval, scene_eval, obedit_eval, NULL);
@@ -4045,10 +4043,10 @@ static void knifetool_init_obinfo(KnifeTool_OpData *kcd,
}
}
-static void knifetool_free_obinfo(KnifeTool_OpData *kcd, uint base_index)
+static void knifetool_free_obinfo(KnifeTool_OpData *kcd, uint ob_index)
{
- MEM_SAFE_FREE(kcd->objects_info[base_index].cagecos);
- MEM_SAFE_FREE(kcd->objects_info[base_index].tri_indices);
+ MEM_SAFE_FREE(kcd->objects_info[ob_index].cagecos);
+ MEM_SAFE_FREE(kcd->objects_info[ob_index].tri_indices);
}
/** \} */
@@ -4081,6 +4079,8 @@ static void knife_init_colors(KnifeColors *colors)
/* called when modal loop selection gets set up... */
static void knifetool_init(ViewContext *vc,
KnifeTool_OpData *kcd,
+ Object **objects,
+ const int objects_len,
const bool only_select,
const bool cut_through,
const bool xray,
@@ -4101,16 +4101,24 @@ static void knifetool_init(ViewContext *vc,
kcd->scene = scene;
kcd->region = vc->region;
- kcd->objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- vc->view_layer, vc->v3d, &kcd->objects_len);
+ if (objects) {
+ kcd->objects = objects;
+ kcd->objects_len = objects_len;
+ kcd->objects_free = false;
+ }
+ else {
+ kcd->objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ vc->scene, vc->view_layer, vc->v3d, &kcd->objects_len);
+ kcd->objects_free = true;
+ }
Object *ob;
BMEditMesh *em;
kcd->objects_info = MEM_callocN(sizeof(*kcd->objects_info) * kcd->objects_len, "knife cagecos");
- for (uint b = 0; b < kcd->objects_len; b++) {
- ob = kcd->objects[b];
+ for (uint ob_index = 0; ob_index < kcd->objects_len; ob_index++) {
+ ob = kcd->objects[ob_index];
em = BKE_editmesh_from_object(ob);
- knifetool_init_obinfo(kcd, ob, b, use_tri_indices);
+ knifetool_init_obinfo(kcd, ob, ob_index, use_tri_indices);
/* Can't usefully select resulting edges in face mode. */
kcd->select_result = (em->selectmode != SCE_SELECT_FACE);
@@ -4225,7 +4233,9 @@ static void knifetool_exit_ex(KnifeTool_OpData *kcd)
}
/* Free object bases. */
- MEM_freeN(kcd->objects);
+ if (kcd->objects_free) {
+ MEM_freeN(kcd->objects);
+ }
/* Destroy kcd itself. */
MEM_freeN(kcd);
@@ -4318,9 +4328,15 @@ static void knifetool_finish_single_post(KnifeTool_OpData *UNUSED(kcd), Object *
/* Called on tool confirmation. */
static void knifetool_finish_ex(KnifeTool_OpData *kcd)
{
- for (uint b = 0; b < kcd->objects_len; b++) {
- Object *ob = kcd->objects[b];
+ /* Separate pre/post passes are needed because `em->looptris` recalculation from the 'post' pass
+ * causes causes triangle indices in #KnifeTool_OpData.bvh to get out of sync.
+ * So perform all the cuts before doing any mesh recalculation, see: T101721. */
+ for (uint ob_index = 0; ob_index < kcd->objects_len; ob_index++) {
+ Object *ob = kcd->objects[ob_index];
knifetool_finish_single_pre(kcd, ob);
+ }
+ for (uint ob_index = 0; ob_index < kcd->objects_len; ob_index++) {
+ Object *ob = kcd->objects[ob_index];
knifetool_finish_single_post(kcd, ob);
}
}
@@ -4378,7 +4394,7 @@ wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf)
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Knife Tool Modal Map");
- /* This function is called for each spacetype, only needs to add map once. */
+ /* This function is called for each space-type, only needs to add map once. */
if (keymap && keymap->modal_items) {
return NULL;
}
@@ -4789,6 +4805,8 @@ static int knifetool_invoke(bContext *C, wmOperator *op, const wmEvent *event)
knifetool_init(&vc,
kcd,
+ NULL,
+ 0,
only_select,
cut_through,
xray,
@@ -4802,8 +4820,8 @@ static int knifetool_invoke(bContext *C, wmOperator *op, const wmEvent *event)
BMEditMesh *em;
bool faces_selected = false;
- for (uint b = 0; b < kcd->objects_len; b++) {
- obedit = kcd->objects[b];
+ for (uint ob_index = 0; ob_index < kcd->objects_len; ob_index++) {
+ obedit = kcd->objects[ob_index];
em = BKE_editmesh_from_object(obedit);
if (em->bm->totfacesel != 0) {
faces_selected = true;
@@ -4893,12 +4911,13 @@ void MESH_OT_knife_tool(wmOperatorType *ot)
KNF_MEASUREMENT_NONE,
"Measurements",
"Visible distance and angle measurements");
- RNA_def_enum(ot->srna,
- "angle_snapping",
- angle_snapping_items,
- KNF_CONSTRAIN_ANGLE_MODE_NONE,
- "Angle Snapping",
- "Angle snapping mode");
+ prop = RNA_def_enum(ot->srna,
+ "angle_snapping",
+ angle_snapping_items,
+ KNF_CONSTRAIN_ANGLE_MODE_NONE,
+ "Angle Snapping",
+ "Angle snapping mode");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_MESH);
prop = RNA_def_float(ot->srna,
"angle_snapping_increment",
@@ -4941,7 +4960,12 @@ static bool edbm_mesh_knife_point_isect(LinkNode *polys, const float cent_ss[2])
return false;
}
-void EDBM_mesh_knife(ViewContext *vc, LinkNode *polys, bool use_tag, bool cut_through)
+void EDBM_mesh_knife(ViewContext *vc,
+ Object **objects,
+ const int objects_len,
+ LinkNode *polys,
+ bool use_tag,
+ bool cut_through)
{
KnifeTool_OpData *kcd;
@@ -4958,6 +4982,8 @@ void EDBM_mesh_knife(ViewContext *vc, LinkNode *polys, bool use_tag, bool cut_th
knifetool_init(vc,
kcd,
+ objects,
+ objects_len,
only_select,
cut_through,
xray,
@@ -4999,18 +5025,21 @@ void EDBM_mesh_knife(ViewContext *vc, LinkNode *polys, bool use_tag, bool cut_th
/* Finish. */
{
- Object *ob;
- BMEditMesh *em;
- for (uint b = 0; b < kcd->objects_len; b++) {
-
- ob = kcd->objects[b];
- em = BKE_editmesh_from_object(ob);
+ /* See #knifetool_finish_ex for why multiple passes are needed. */
+ for (uint ob_index = 0; ob_index < kcd->objects_len; ob_index++) {
+ Object *ob = kcd->objects[ob_index];
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
if (use_tag) {
BM_mesh_elem_hflag_enable_all(em->bm, BM_EDGE, BM_ELEM_TAG, false);
}
knifetool_finish_single_pre(kcd, ob);
+ }
+
+ for (uint ob_index = 0; ob_index < kcd->objects_len; ob_index++) {
+ Object *ob = kcd->objects[ob_index];
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
/* Tag faces inside! */
if (use_tag) {
@@ -5043,7 +5072,7 @@ void EDBM_mesh_knife(ViewContext *vc, LinkNode *polys, bool use_tag, bool cut_th
BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) {
float cent[3], cent_ss[2];
BM_face_calc_point_in_face(f, cent);
- mul_m4_v3(ob->obmat, cent);
+ mul_m4_v3(ob->object_to_world, cent);
knife_project_v2(kcd, cent, cent_ss);
if (edbm_mesh_knife_point_isect(polys, cent_ss)) {
BM_elem_flag_enable(f, BM_ELEM_TAG);
@@ -5084,7 +5113,7 @@ void EDBM_mesh_knife(ViewContext *vc, LinkNode *polys, bool use_tag, bool cut_th
if (found) {
float cent[3], cent_ss[2];
BM_face_calc_point_in_face(f, cent);
- mul_m4_v3(ob->obmat, cent);
+ mul_m4_v3(ob->object_to_world, cent);
knife_project_v2(kcd, cent, cent_ss);
if ((kcd->cut_through || point_is_visible(kcd, cent, cent_ss, (BMElem *)f)) &&
edbm_mesh_knife_point_isect(polys, cent_ss)) {
@@ -5103,9 +5132,12 @@ void EDBM_mesh_knife(ViewContext *vc, LinkNode *polys, bool use_tag, bool cut_th
#undef F_ISECT_SET_UNKNOWN
#undef F_ISECT_SET_OUTSIDE
}
+ }
+ for (uint ob_index = 0; ob_index < kcd->objects_len; ob_index++) {
/* Defer freeing data until the BVH tree is finished with, see: #point_is_visible and
* the doc-string for #knifetool_finish_single_post. */
+ Object *ob = kcd->objects[ob_index];
knifetool_finish_single_post(kcd, ob);
}
diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c
index c32b1fa99c0..6004a2943a2 100644
--- a/source/blender/editors/mesh/editmesh_knife_project.c
+++ b/source/blender/editors/mesh/editmesh_knife_project.c
@@ -132,22 +132,21 @@ static int knifeproject_exec(bContext *C, wmOperator *op)
ViewContext vc;
em_setup_viewcontext(C, &vc);
- /* TODO: Ideally meshes would occlude each other, currently they don't
- * since each knife-project runs as a separate operation. */
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- vc.view_layer, vc.v3d, &objects_len);
+ vc.scene, vc.view_layer, vc.v3d, &objects_len);
+
+ EDBM_mesh_knife(&vc, objects, objects_len, polys, true, cut_through);
+
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
ED_view3d_viewcontext_init_object(&vc, obedit);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- EDBM_mesh_knife(&vc, polys, true, cut_through);
-
/* select only tagged faces */
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
- EDBM_selectmode_disable_multi(C, SCE_SELECT_VERTEX, SCE_SELECT_EDGE);
+ 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, false, BM_ELEM_TAG);
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 5a4b12c2209..9a91d7836fe 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -88,7 +88,7 @@ typedef struct RingSelOpData {
static void ringsel_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), void *arg)
{
RingSelOpData *lcd = arg;
- EDBM_preselect_edgering_draw(lcd->presel_edgering, lcd->ob->obmat);
+ EDBM_preselect_edgering_draw(lcd->presel_edgering, lcd->ob->object_to_world);
}
static void edgering_select(RingSelOpData *lcd)
@@ -226,7 +226,7 @@ static void ringsel_finish(bContext *C, wmOperator *op)
}
else {
/* XXX Is this piece of code ever used now? Simple loop select is now
- * in editmesh_select.c (around line 1000)... */
+ * in editmesh_select.cc (around line 1000)... */
/* sets as active, useful for other tools */
if (em->selectmode & SCE_SELECT_VERTEX) {
/* low priority TODO: get vertrex close to mouse. */
@@ -376,11 +376,12 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
.e_index = (uint)RNA_int_get(op->ptr, "edge_index"),
};
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint bases_len;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(
- view_layer, CTX_wm_view3d(C), &bases_len);
+ scene, view_layer, CTX_wm_view3d(C), &bases_len);
if (is_interactive) {
for (uint base_index = 0; base_index < bases_len; base_index++) {
@@ -446,7 +447,6 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
#ifdef USE_LOOPSLIDE_HACK
/* for use in macro so we can restore, HACK */
{
- Scene *scene = CTX_data_scene(C);
ToolSettings *settings = scene->toolsettings;
const bool mesh_select_mode[3] = {
(settings->selectmode & SCE_SELECT_VERTEX) != 0,
@@ -473,7 +473,7 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
static int ringcut_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- /* When accessed as a tool, get the active edge from the preselection gizmo. */
+ /* When accessed as a tool, get the active edge from the pre-selection gizmo. */
{
ARegion *region = CTX_wm_region(C);
wmGizmoMap *gzmap = region->gizmo_map;
@@ -763,6 +763,7 @@ void MESH_OT_loopcut(wmOperatorType *ot)
/* For redo only. */
prop = RNA_def_int(ot->srna, "object_index", -1, -1, INT_MAX, "Object Index", "", 0, INT_MAX);
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_MESH);
RNA_def_property_flag(prop, PROP_HIDDEN);
prop = RNA_def_int(ot->srna, "edge_index", -1, -1, INT_MAX, "Edge Index", "", 0, INT_MAX);
RNA_def_property_flag(prop, PROP_HIDDEN);
diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c
index a4d41400bae..070f748c78e 100644
--- a/source/blender/editors/mesh/editmesh_mask_extract.c
+++ b/source/blender/editors/mesh/editmesh_mask_extract.c
@@ -88,7 +88,7 @@ static int geometry_extract_apply(bContext *C,
ED_object_sculptmode_exit(C, depsgraph);
- BKE_sculpt_mask_layers_ensure(ob, NULL);
+ BKE_sculpt_mask_layers_ensure(depsgraph, bmain, ob, NULL);
/* Ensures that deformation from sculpt mode is taken into account before duplicating the mesh to
* extract the geometry. */
@@ -209,7 +209,7 @@ static int geometry_extract_apply(bContext *C,
/* Remove the Face Sets as they need to be recreated when entering Sculpt Mode in the new object.
* TODO(pablodobarro): In the future we can try to preserve them from the original mesh. */
Mesh *new_ob_mesh = new_ob->data;
- CustomData_free_layers(&new_ob_mesh->pdata, CD_SCULPT_FACE_SETS, new_ob_mesh->totpoly);
+ CustomData_free_layer_named(&new_ob_mesh->pdata, ".sculpt_face_set", new_ob_mesh->totpoly);
/* Remove the mask from the new object so it can be sculpted directly after extracting. */
CustomData_free_layers(&new_ob_mesh->vdata, CD_PAINT_MASK, new_ob_mesh->totvert);
@@ -268,7 +268,8 @@ static void geometry_extract_tag_face_set(BMesh *bm, GeometryExtractParams *para
const int tag_face_set_id = params->active_face_set;
BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
- const int cd_face_sets_offset = CustomData_get_offset(&bm->pdata, CD_SCULPT_FACE_SETS);
+ const int cd_face_sets_offset = CustomData_get_offset_named(
+ &bm->pdata, CD_PROP_INT32, ".sculpt_face_set");
BMFace *f;
BMIter iter;
@@ -480,7 +481,7 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op)
Object *ob = CTX_data_active_object(C);
View3D *v3d = CTX_wm_view3d(C);
- BKE_sculpt_mask_layers_ensure(ob, NULL);
+ BKE_sculpt_mask_layers_ensure(NULL, NULL, ob, NULL);
Mesh *mesh = ob->data;
Mesh *new_mesh = (Mesh *)BKE_id_copy(bmain, &mesh->id);
@@ -561,7 +562,8 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op)
if (ob->mode == OB_MODE_SCULPT) {
SculptSession *ss = ob->sculpt;
- ss->face_sets = CustomData_get_layer(&((Mesh *)ob->data)->pdata, CD_SCULPT_FACE_SETS);
+ ss->face_sets = CustomData_get_layer_named(
+ &((Mesh *)ob->data)->pdata, CD_PROP_INT32, ".sculpt_face_set");
if (ss->face_sets) {
/* Assign a new Face Set ID to the new faces created by the slice operation. */
const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(ob->data);
diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c
index 1db915940a0..5db12db0e46 100644
--- a/source/blender/editors/mesh/editmesh_path.c
+++ b/source/blender/editors/mesh/editmesh_path.c
@@ -346,7 +346,9 @@ static void edgetag_ensure_cd_flag(Mesh *me, const char edge_mode)
switch (edge_mode) {
case EDGE_MODE_TAG_CREASE:
- BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_CREASE);
+ if (!CustomData_has_layer(&bm->edata, CD_CREASE)) {
+ BM_data_layer_add(bm, &bm->edata, CD_CREASE);
+ }
break;
case EDGE_MODE_TAG_BEVEL:
if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
@@ -682,7 +684,8 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE
em_setup_viewcontext(C, &vc);
copy_v2_v2_int(vc.mval, event->mval);
- Base *basact = vc.view_layer->basact;
+ BKE_view_layer_synced_ensure(vc.scene, vc.view_layer);
+ Base *basact = BKE_view_layer_active_base_get(vc.view_layer);
BMEditMesh *em = vc.em;
view3d_operator_needs_opengl(C);
@@ -690,7 +693,8 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE
{
int base_index = -1;
uint bases_len = 0;
- Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(vc.view_layer, vc.v3d, &bases_len);
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(
+ vc.scene, vc.view_layer, vc.v3d, &bases_len);
if (EDBM_unified_findnearest(&vc, bases, bases_len, &base_index, &eve, &eed, &efa)) {
basact = bases[base_index];
ED_view3d_viewcontext_init_object(&vc, basact->object);
@@ -735,7 +739,8 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE
return OPERATOR_PASS_THROUGH;
}
- if (vc.view_layer->basact != basact) {
+ BKE_view_layer_synced_ensure(vc.scene, vc.view_layer);
+ if (BKE_view_layer_active_base_get(vc.view_layer) != basact) {
ED_object_base_activate(C, basact);
}
@@ -817,7 +822,7 @@ static int edbm_shortest_path_select_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
diff --git a/source/blender/editors/mesh/editmesh_polybuild.c b/source/blender/editors/mesh/editmesh_polybuild.c
index 493e476ba4f..cfd07a6ff35 100644
--- a/source/blender/editors/mesh/editmesh_polybuild.c
+++ b/source/blender/editors/mesh/editmesh_polybuild.c
@@ -53,11 +53,14 @@ static void edbm_selectmode_ensure(Scene *scene, BMEditMesh *em, short selectmod
}
/* Could make public, for now just keep here. */
-static void edbm_flag_disable_all_multi(ViewLayer *view_layer, View3D *v3d, const char hflag)
+static void edbm_flag_disable_all_multi(const Scene *scene,
+ ViewLayer *view_layer,
+ View3D *v3d,
+ const char hflag)
{
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, v3d, &objects_len);
+ scene, view_layer, v3d, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob_iter = objects[ob_index];
BMEditMesh *em_iter = BKE_editmesh_from_object(ob_iter);
@@ -70,11 +73,11 @@ static void edbm_flag_disable_all_multi(ViewLayer *view_layer, View3D *v3d, cons
MEM_freeN(objects);
}
-/* When accessed as a tool, get the active edge from the preselection gizmo. */
+/** When accessed as a tool, get the active edge from the pre-selection gizmo. */
static bool edbm_preselect_or_active(bContext *C, const View3D *v3d, Base **r_base, BMElem **r_ele)
{
ARegion *region = CTX_wm_region(C);
- const bool show_gizmo = !((v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)));
+ const bool show_gizmo = !(v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL));
wmGizmoMap *gzmap = show_gizmo ? region->gizmo_map : NULL;
wmGizmoGroup *gzgroup = gzmap ? WM_gizmomap_group_find(gzmap, "VIEW3D_GGT_mesh_preselect_elem") :
@@ -84,8 +87,10 @@ static bool edbm_preselect_or_active(bContext *C, const View3D *v3d, Base **r_ba
ED_view3d_gizmo_mesh_preselect_get_active(C, gz, r_base, r_ele);
}
else {
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base = BKE_view_layer_active_base_get(view_layer);
Object *obedit = base->object;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
@@ -119,7 +124,7 @@ static int edbm_polybuild_transform_at_cursor_invoke(bContext *C,
BMEditMesh *em = vc.em;
BMesh *bm = em->bm;
- invert_m4_m4(vc.obedit->imat, vc.obedit->obmat);
+ invert_m4_m4(vc.obedit->world_to_object, vc.obedit->object_to_world);
ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
if (!ele_act) {
@@ -128,7 +133,7 @@ static int edbm_polybuild_transform_at_cursor_invoke(bContext *C,
edbm_selectmode_ensure(vc.scene, vc.em, SCE_SELECT_VERTEX);
- edbm_flag_disable_all_multi(vc.view_layer, vc.v3d, BM_ELEM_SELECT);
+ edbm_flag_disable_all_multi(vc.scene, vc.view_layer, vc.v3d, BM_ELEM_SELECT);
if (ele_act->head.htype == BM_VERT) {
BM_vert_select_set(bm, (BMVert *)ele_act, true);
@@ -147,7 +152,8 @@ static int edbm_polybuild_transform_at_cursor_invoke(bContext *C,
.is_destructive = true,
});
if (basact != NULL) {
- if (vc.view_layer->basact != basact) {
+ BKE_view_layer_synced_ensure(vc.scene, vc.view_layer);
+ if (BKE_view_layer_active_base_get(vc.view_layer) != basact) {
ED_object_base_activate(C, basact);
}
}
@@ -186,7 +192,7 @@ static int edbm_polybuild_delete_at_cursor_invoke(bContext *C,
BMEditMesh *em = vc.em;
BMesh *bm = em->bm;
- invert_m4_m4(vc.obedit->imat, vc.obedit->obmat);
+ invert_m4_m4(vc.obedit->world_to_object, vc.obedit->object_to_world);
ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
if (!ele_act) {
@@ -234,7 +240,8 @@ static int edbm_polybuild_delete_at_cursor_invoke(bContext *C,
.is_destructive = true,
});
if (basact != NULL) {
- if (vc.view_layer->basact != basact) {
+ BKE_view_layer_synced_ensure(vc.scene, vc.view_layer);
+ if (BKE_view_layer_active_base_get(vc.view_layer) != basact) {
ED_object_base_activate(C, basact);
}
}
@@ -279,7 +286,7 @@ static int edbm_polybuild_face_at_cursor_invoke(bContext *C, wmOperator *op, con
BMEditMesh *em = vc.em;
BMesh *bm = em->bm;
- invert_m4_m4(vc.obedit->imat, vc.obedit->obmat);
+ invert_m4_m4(vc.obedit->world_to_object, vc.obedit->object_to_world);
ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
edbm_selectmode_ensure(vc.scene, vc.em, SCE_SELECT_VERTEX);
@@ -287,12 +294,12 @@ static int edbm_polybuild_face_at_cursor_invoke(bContext *C, wmOperator *op, con
if (ele_act == NULL || ele_act->head.htype == BM_FACE) {
/* Just add vert */
copy_v3_v3(center, vc.scene->cursor.location);
- mul_v3_m4v3(center, vc.obedit->obmat, center);
+ mul_v3_m4v3(center, vc.obedit->object_to_world, center);
ED_view3d_win_to_3d_int(vc.v3d, vc.region, center, event->mval, center);
- mul_m4_v3(vc.obedit->imat, center);
+ mul_m4_v3(vc.obedit->world_to_object, center);
BMVert *v_new = BM_vert_create(bm, center, NULL, BM_CREATE_NOP);
- edbm_flag_disable_all_multi(vc.view_layer, vc.v3d, BM_ELEM_SELECT);
+ edbm_flag_disable_all_multi(vc.scene, vc.view_layer, vc.v3d, BM_ELEM_SELECT);
BM_vert_select_set(bm, v_new, true);
BM_select_history_store(bm, v_new);
changed = true;
@@ -302,14 +309,14 @@ static int edbm_polybuild_face_at_cursor_invoke(bContext *C, wmOperator *op, con
BMFace *f_reference = e_act->l ? e_act->l->f : NULL;
mid_v3_v3v3(center, e_act->v1->co, e_act->v2->co);
- mul_m4_v3(vc.obedit->obmat, center);
+ mul_m4_v3(vc.obedit->object_to_world, center);
ED_view3d_win_to_3d_int(vc.v3d, vc.region, center, event->mval, center);
- mul_m4_v3(vc.obedit->imat, center);
+ mul_m4_v3(vc.obedit->world_to_object, center);
if (f_reference->len == 3 && RNA_boolean_get(op->ptr, "create_quads")) {
const float fac = line_point_factor_v3(center, e_act->v1->co, e_act->v2->co);
BMVert *v_new = BM_edge_split(bm, e_act, e_act->v1, NULL, CLAMPIS(fac, 0.0f, 1.0f));
copy_v3_v3(v_new->co, center);
- edbm_flag_disable_all_multi(vc.view_layer, vc.v3d, BM_ELEM_SELECT);
+ edbm_flag_disable_all_multi(vc.scene, vc.view_layer, vc.v3d, BM_ELEM_SELECT);
BM_vert_select_set(bm, v_new, true);
BM_select_history_store(bm, v_new);
}
@@ -322,7 +329,7 @@ static int edbm_polybuild_face_at_cursor_invoke(bContext *C, wmOperator *op, con
SWAP(BMVert *, v_tri[0], v_tri[1]);
}
BM_face_create_verts(bm, v_tri, 3, f_reference, BM_CREATE_NOP, true);
- edbm_flag_disable_all_multi(vc.view_layer, vc.v3d, BM_ELEM_SELECT);
+ edbm_flag_disable_all_multi(vc.scene, vc.view_layer, vc.v3d, BM_ELEM_SELECT);
BM_vert_select_set(bm, v_tri[2], true);
BM_select_history_store(bm, v_tri[2]);
}
@@ -357,9 +364,9 @@ static int edbm_polybuild_face_at_cursor_invoke(bContext *C, wmOperator *op, con
BMFace *f_reference = e_pair[0]->l ? e_pair[0]->l->f : NULL;
- mul_v3_m4v3(center, vc.obedit->obmat, v_act->co);
+ mul_v3_m4v3(center, vc.obedit->object_to_world, v_act->co);
ED_view3d_win_to_3d_int(vc.v3d, vc.region, center, event->mval, center);
- mul_m4_v3(vc.obedit->imat, center);
+ mul_m4_v3(vc.obedit->world_to_object, center);
BMVert *v_quad[4];
v_quad[0] = v_act;
@@ -372,16 +379,16 @@ static int edbm_polybuild_face_at_cursor_invoke(bContext *C, wmOperator *op, con
// BMFace *f_new =
BM_face_create_verts(bm, v_quad, 4, f_reference, BM_CREATE_NOP, true);
- edbm_flag_disable_all_multi(vc.view_layer, vc.v3d, BM_ELEM_SELECT);
+ edbm_flag_disable_all_multi(vc.scene, vc.view_layer, vc.v3d, BM_ELEM_SELECT);
BM_vert_select_set(bm, v_quad[2], true);
BM_select_history_store(bm, v_quad[2]);
changed = true;
}
else {
/* Just add edge */
- mul_m4_v3(vc.obedit->obmat, center);
+ mul_m4_v3(vc.obedit->object_to_world, center);
ED_view3d_win_to_3d_int(vc.v3d, vc.region, v_act->co, event->mval, center);
- mul_m4_v3(vc.obedit->imat, center);
+ mul_m4_v3(vc.obedit->world_to_object, center);
BMVert *v_new = BM_vert_create(bm, center, NULL, BM_CREATE_NOP);
@@ -402,7 +409,8 @@ static int edbm_polybuild_face_at_cursor_invoke(bContext *C, wmOperator *op, con
});
if (basact != NULL) {
- if (vc.view_layer->basact != basact) {
+ BKE_view_layer_synced_ensure(vc.scene, vc.view_layer);
+ if (BKE_view_layer_active_base_get(vc.view_layer) != basact) {
ED_object_base_activate(C, basact);
}
}
@@ -456,7 +464,7 @@ static int edbm_polybuild_split_at_cursor_invoke(bContext *C,
BMEditMesh *em = vc.em;
BMesh *bm = em->bm;
- invert_m4_m4(vc.obedit->imat, vc.obedit->obmat);
+ invert_m4_m4(vc.obedit->world_to_object, vc.obedit->object_to_world);
ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
edbm_selectmode_ensure(vc.scene, vc.em, SCE_SELECT_VERTEX);
@@ -467,15 +475,15 @@ static int edbm_polybuild_split_at_cursor_invoke(bContext *C,
if (ele_act->head.htype == BM_EDGE) {
BMEdge *e_act = (BMEdge *)ele_act;
mid_v3_v3v3(center, e_act->v1->co, e_act->v2->co);
- mul_m4_v3(vc.obedit->obmat, center);
+ mul_m4_v3(vc.obedit->object_to_world, center);
ED_view3d_win_to_3d_int(vc.v3d, vc.region, center, event->mval, center);
- mul_m4_v3(vc.obedit->imat, center);
+ mul_m4_v3(vc.obedit->world_to_object, center);
const float fac = line_point_factor_v3(center, e_act->v1->co, e_act->v2->co);
BMVert *v_new = BM_edge_split(bm, e_act, e_act->v1, NULL, CLAMPIS(fac, 0.0f, 1.0f));
copy_v3_v3(v_new->co, center);
- edbm_flag_disable_all_multi(vc.view_layer, vc.v3d, BM_ELEM_SELECT);
+ edbm_flag_disable_all_multi(vc.scene, vc.view_layer, vc.v3d, BM_ELEM_SELECT);
BM_vert_select_set(bm, v_new, true);
BM_select_history_store(bm, v_new);
changed = true;
@@ -495,7 +503,8 @@ static int edbm_polybuild_split_at_cursor_invoke(bContext *C,
WM_event_add_mousemove(vc.win);
- if (vc.view_layer->basact != basact) {
+ BKE_view_layer_synced_ensure(vc.scene, vc.view_layer);
+ if (BKE_view_layer_active_base_get(vc.view_layer) != basact) {
ED_object_base_activate(C, basact);
}
@@ -578,7 +587,7 @@ static int edbm_polybuild_dissolve_at_cursor_invoke(bContext *C,
}
if (changed) {
- edbm_flag_disable_all_multi(vc.view_layer, vc.v3d, BM_ELEM_SELECT);
+ edbm_flag_disable_all_multi(vc.scene, vc.view_layer, vc.v3d, BM_ELEM_SELECT);
EDBM_update(vc.obedit->data,
&(const struct EDBMUpdate_Params){
@@ -587,7 +596,8 @@ static int edbm_polybuild_dissolve_at_cursor_invoke(bContext *C,
.is_destructive = true,
});
- if (vc.view_layer->basact != basact) {
+ BKE_view_layer_synced_ensure(vc.scene, vc.view_layer);
+ if (BKE_view_layer_active_base_get(vc.view_layer) != basact) {
ED_object_base_activate(C, basact);
}
diff --git a/source/blender/editors/mesh/editmesh_preselect_edgering.c b/source/blender/editors/mesh/editmesh_preselect_edgering.c
index 0773533bc5c..832390331c3 100644
--- a/source/blender/editors/mesh/editmesh_preselect_edgering.c
+++ b/source/blender/editors/mesh/editmesh_preselect_edgering.c
@@ -182,7 +182,7 @@ void EDBM_preselect_edgering_draw(struct EditMesh_PreSelEdgeRing *psel, const fl
/* Same size as an edit mode vertex */
immUniform1f("size",
2.0 * U.pixelsize *
- (max_ff(1.0f, UI_GetThemeValuef(TH_VERTEX_SIZE) * (float)M_SQRT2 / 2.0f)));
+ max_ff(1.0f, UI_GetThemeValuef(TH_VERTEX_SIZE) * (float)M_SQRT2 / 2.0f));
immBegin(GPU_PRIM_POINTS, psel->verts_len);
diff --git a/source/blender/editors/mesh/editmesh_preselect_elem.c b/source/blender/editors/mesh/editmesh_preselect_elem.c
index cf73e579700..5d8ce7cae44 100644
--- a/source/blender/editors/mesh/editmesh_preselect_elem.c
+++ b/source/blender/editors/mesh/editmesh_preselect_elem.c
@@ -243,9 +243,9 @@ static void view3d_preselect_update_preview_triangle_from_vert(struct EditMesh_P
}
if (e_pair[1] != NULL) {
- mul_v3_m4v3(center, vc->obedit->obmat, v_act->co);
+ mul_v3_m4v3(center, vc->obedit->object_to_world, v_act->co);
ED_view3d_win_to_3d_int(vc->v3d, vc->region, center, mval, center);
- mul_m4_v3(vc->obedit->imat, center);
+ mul_m4_v3(vc->obedit->world_to_object, center);
psel->preview_tris = MEM_mallocN(sizeof(*psel->preview_tris) * 2, __func__);
psel->preview_lines = MEM_mallocN(sizeof(*psel->preview_lines) * 4, __func__);
@@ -311,9 +311,9 @@ static void view3d_preselect_update_preview_triangle_from_edge(struct EditMesh_P
psel->preview_tris = MEM_mallocN(sizeof(*psel->preview_tris), __func__);
psel->preview_lines = MEM_mallocN(sizeof(*psel->preview_lines) * 3, __func__);
mid_v3_v3v3(center, eed->v1->co, eed->v2->co);
- mul_m4_v3(vc->obedit->obmat, center);
+ mul_m4_v3(vc->obedit->object_to_world, center);
ED_view3d_win_to_3d_int(vc->v3d, vc->region, center, mval, center);
- mul_m4_v3(vc->obedit->imat, center);
+ mul_m4_v3(vc->obedit->world_to_object, center);
copy_v3_v3(psel->preview_tris[0][0], eed->v1->co);
copy_v3_v3(psel->preview_tris[0][1], eed->v2->co);
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c
index 6b4edea498e..2e7fbb0200d 100644
--- a/source/blender/editors/mesh/editmesh_rip.c
+++ b/source/blender/editors/mesh/editmesh_rip.c
@@ -326,7 +326,7 @@ static BMVert *edbm_ripsel_edloop_pair_start_vert(BMEdge *e)
{
/* try step in a direction, if it fails we know do go the other way */
BMVert *v_test = e->v1;
- return (edbm_ripsel_edge_uid_step(e, &v_test)) ? e->v1 : e->v2;
+ return edbm_ripsel_edge_uid_step(e, &v_test) ? e->v1 : e->v2;
}
static void edbm_ripsel_deselect_helper(BMesh *bm,
@@ -914,7 +914,7 @@ static int edbm_rip_invoke__edge(bContext *C, const wmEvent *event, Object *obed
/* NOTE: if the case of 3 edges has one change in loop stepping,
* if this becomes more involved we may be better off splitting
* the 3 edge case into its own else-if branch */
- if ((ELEM(totedge_manifold, 4, 3)) || (all_manifold == false)) {
+ if (ELEM(totedge_manifold, 4, 3) || (all_manifold == false)) {
BMLoop *l_a = e_best->l;
BMLoop *l_b = l_a->radial_next;
@@ -987,10 +987,11 @@ static int edbm_rip_invoke__edge(bContext *C, const wmEvent *event, Object *obed
/* based on mouse cursor position, it defines how is being ripped */
static int edbm_rip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
const bool do_fill = RNA_boolean_get(op->ptr, "use_fill");
bool no_vertex_selected = true;
diff --git a/source/blender/editors/mesh/editmesh_rip_edge.c b/source/blender/editors/mesh/editmesh_rip_edge.c
index 85426acb905..dd4b247a06f 100644
--- a/source/blender/editors/mesh/editmesh_rip_edge.c
+++ b/source/blender/editors/mesh/editmesh_rip_edge.c
@@ -35,10 +35,11 @@ static int edbm_rip_edge_invoke(bContext *C, wmOperator *UNUSED(op), const wmEve
{
ARegion *region = CTX_wm_region(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.cc
index 9c8c5c45cb7..2ef2772d404 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.cc
@@ -7,23 +7,24 @@
#include "MEM_guardedalloc.h"
-#include "BLI_array.h"
#include "BLI_bitmap.h"
#include "BLI_heap.h"
#include "BLI_linklist.h"
-#include "BLI_linklist_stack.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_math_bits.h"
#include "BLI_rand.h"
#include "BLI_string.h"
#include "BLI_utildefines_stack.h"
+#include "BLI_vector.hh"
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_deform.h"
#include "BKE_editmesh.h"
+#include "BKE_editmesh_cache.h"
#include "BKE_layer.h"
+#include "BKE_mesh.h"
#include "BKE_report.h"
#include "WM_api.h"
@@ -182,11 +183,11 @@ static BMElem *edbm_select_id_bm_elem_get(Base **bases, const uint sel_id, uint
return (BMElem *)BM_vert_at_index_find_or_table(em->bm, elem_id);
default:
BLI_assert(0);
- return NULL;
+ return nullptr;
}
}
- return NULL;
+ return nullptr;
}
/** \} */
@@ -218,8 +219,8 @@ struct NearestVertUserData {
bool use_cycle;
int cycle_index_prev;
- struct NearestVertUserData_Hit hit;
- struct NearestVertUserData_Hit hit_cycle;
+ NearestVertUserData_Hit hit;
+ NearestVertUserData_Hit hit_cycle;
};
static void findnearestvert__doClosest(void *userData,
@@ -227,7 +228,7 @@ static void findnearestvert__doClosest(void *userData,
const float screen_co[2],
int index)
{
- struct NearestVertUserData *data = userData;
+ NearestVertUserData *data = static_cast<NearestVertUserData *>(userData);
float dist_test, dist_test_bias;
dist_test = dist_test_bias = len_manhattan_v2v2(data->mval_fl, screen_co);
@@ -244,7 +245,7 @@ static void findnearestvert__doClosest(void *userData,
}
if (data->use_cycle) {
- if ((data->hit_cycle.vert == NULL) && (index > data->cycle_index_prev) &&
+ if ((data->hit_cycle.vert == nullptr) && (index > data->cycle_index_prev) &&
(dist_test_bias < FIND_NEAR_CYCLE_THRESHOLD_MIN)) {
data->hit_cycle.dist_bias = dist_test_bias;
data->hit_cycle.dist = dist_test;
@@ -270,7 +271,7 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
uint index;
BMVert *eve;
- /* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
+ /* No after-queue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
{
DRW_select_buffer_context_create(bases, bases_len, SCE_SELECT_VERTEX);
@@ -281,7 +282,7 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
eve = (BMVert *)edbm_select_id_bm_elem_get(bases, index, &base_index);
}
else {
- eve = NULL;
+ eve = nullptr;
}
}
@@ -294,15 +295,15 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
return eve;
}
}
- return NULL;
+ return nullptr;
}
- struct NearestVertUserData data = {{0}};
- const struct NearestVertUserData_Hit *hit = NULL;
+ NearestVertUserData data = {{0}};
+ const NearestVertUserData_Hit *hit = nullptr;
const eV3DProjTest clip_flag = RV3D_CLIPPING_ENABLED(vc->v3d, vc->rv3d) ?
V3D_PROJ_TEST_CLIP_DEFAULT :
V3D_PROJ_TEST_CLIP_DEFAULT & ~V3D_PROJ_TEST_CLIP_BB;
- BMesh *prev_select_bm = NULL;
+ BMesh *prev_select_bm = nullptr;
static struct {
int index;
@@ -345,8 +346,8 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
}
}
- if (hit == NULL) {
- return NULL;
+ if (hit == nullptr) {
+ return nullptr;
}
prev_select.index = hit->index;
@@ -358,8 +359,9 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
BMVert *EDBM_vert_find_nearest(ViewContext *vc, float *dist_px_manhattan_p)
{
+ BKE_view_layer_synced_ensure(vc->scene, vc->view_layer);
Base *base = BKE_view_layer_base_find(vc->view_layer, vc->obact);
- return EDBM_vert_find_nearest_ex(vc, dist_px_manhattan_p, false, false, &base, 1, NULL);
+ return EDBM_vert_find_nearest_ex(vc, dist_px_manhattan_p, false, false, &base, 1, nullptr);
}
/* find the distance to the edge we already have */
@@ -373,9 +375,9 @@ static void find_nearest_edge_center__doZBuf(void *userData,
BMEdge *eed,
const float screen_co_a[2],
const float screen_co_b[2],
- int UNUSED(index))
+ int /*index*/)
{
- struct NearestEdgeUserData_ZBuf *data = userData;
+ NearestEdgeUserData_ZBuf *data = static_cast<NearestEdgeUserData_ZBuf *>(userData);
if (eed == data->edge_test) {
float dist_test;
@@ -408,15 +410,15 @@ struct NearestEdgeUserData {
bool use_cycle;
int cycle_index_prev;
- struct NearestEdgeUserData_Hit hit;
- struct NearestEdgeUserData_Hit hit_cycle;
+ NearestEdgeUserData_Hit hit;
+ NearestEdgeUserData_Hit hit_cycle;
};
/* NOTE: uses v3d, so needs active 3d window. */
static void find_nearest_edge__doClosest(
void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
{
- struct NearestEdgeUserData *data = userData;
+ NearestEdgeUserData *data = static_cast<NearestEdgeUserData *>(userData);
float dist_test, dist_test_bias;
float fac = line_point_factor_v2(data->mval_fl, screen_co_a, screen_co_b);
@@ -462,7 +464,7 @@ static void find_nearest_edge__doClosest(
}
if (data->use_cycle) {
- if ((data->hit_cycle.edge == NULL) && (index > data->cycle_index_prev) &&
+ if ((data->hit_cycle.edge == nullptr) && (index > data->cycle_index_prev) &&
(dist_test_bias < FIND_NEAR_CYCLE_THRESHOLD_MIN)) {
float screen_co_mid[2];
@@ -495,7 +497,7 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
uint index;
BMEdge *eed;
- /* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
+ /* No after-queue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
{
DRW_select_buffer_context_create(bases, bases_len, SCE_SELECT_EDGE);
@@ -506,7 +508,7 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
eed = (BMEdge *)edbm_select_id_bm_elem_get(bases, index, &base_index);
}
else {
- eed = NULL;
+ eed = nullptr;
}
}
@@ -516,7 +518,7 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
/* exception for faces (verts don't need this) */
if (r_dist_center_px_manhattan && eed) {
- struct NearestEdgeUserData_ZBuf data;
+ NearestEdgeUserData_ZBuf data;
data.mval_fl[0] = vc->mval[0];
data.mval_fl[1] = vc->mval[1];
@@ -543,14 +545,14 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
return eed;
}
}
- return NULL;
+ return nullptr;
}
- struct NearestEdgeUserData data = {{0}};
- const struct NearestEdgeUserData_Hit *hit = NULL;
+ NearestEdgeUserData data = {{nullptr}};
+ const NearestEdgeUserData_Hit *hit = nullptr;
/* interpolate along the edge before doing a clipping plane test */
const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_DEFAULT & ~V3D_PROJ_TEST_CLIP_BB;
- BMesh *prev_select_bm = NULL;
+ BMesh *prev_select_bm = nullptr;
static struct {
int index;
@@ -595,8 +597,8 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
}
}
- if (hit == NULL) {
- return NULL;
+ if (hit == nullptr) {
+ return nullptr;
}
if (r_dist_center_px_manhattan) {
@@ -612,9 +614,10 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
BMEdge *EDBM_edge_find_nearest(ViewContext *vc, float *dist_px_manhattan_p)
{
+ BKE_view_layer_synced_ensure(vc->scene, vc->view_layer);
Base *base = BKE_view_layer_base_find(vc->view_layer, vc->obact);
return EDBM_edge_find_nearest_ex(
- vc, dist_px_manhattan_p, NULL, false, false, NULL, &base, 1, NULL);
+ vc, dist_px_manhattan_p, nullptr, false, false, nullptr, &base, 1, nullptr);
}
/* find the distance to the face we already have */
@@ -627,9 +630,9 @@ struct NearestFaceUserData_ZBuf {
static void find_nearest_face_center__doZBuf(void *userData,
BMFace *efa,
const float screen_co[2],
- int UNUSED(index))
+ int /*index*/)
{
- struct NearestFaceUserData_ZBuf *data = userData;
+ NearestFaceUserData_ZBuf *data = static_cast<NearestFaceUserData_ZBuf *>(userData);
if (efa == data->face_test) {
const float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co);
@@ -653,8 +656,8 @@ struct NearestFaceUserData {
bool use_cycle;
int cycle_index_prev;
- struct NearestFaceUserData_Hit hit;
- struct NearestFaceUserData_Hit hit_cycle;
+ NearestFaceUserData_Hit hit;
+ NearestFaceUserData_Hit hit_cycle;
};
static void findnearestface__doClosest(void *userData,
@@ -662,7 +665,7 @@ static void findnearestface__doClosest(void *userData,
const float screen_co[2],
int index)
{
- struct NearestFaceUserData *data = userData;
+ NearestFaceUserData *data = static_cast<NearestFaceUserData *>(userData);
float dist_test, dist_test_bias;
dist_test = dist_test_bias = len_manhattan_v2v2(data->mval_fl, screen_co);
@@ -679,7 +682,7 @@ static void findnearestface__doClosest(void *userData,
}
if (data->use_cycle) {
- if ((data->hit_cycle.face == NULL) && (index > data->cycle_index_prev) &&
+ if ((data->hit_cycle.face == nullptr) && (index > data->cycle_index_prev) &&
(dist_test_bias < FIND_NEAR_CYCLE_THRESHOLD_MIN)) {
data->hit_cycle.dist_bias = dist_test_bias;
data->hit_cycle.dist = dist_test;
@@ -730,7 +733,7 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
efa = (BMFace *)edbm_select_id_bm_elem_get(bases, index, &base_index);
}
else {
- efa = NULL;
+ efa = nullptr;
}
}
@@ -740,7 +743,7 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
/* exception for faces (verts don't need this) */
if (r_dist_center && efa) {
- struct NearestFaceUserData_ZBuf data;
+ NearestFaceUserData_ZBuf data;
data.mval_fl[0] = vc->mval[0];
data.mval_fl[1] = vc->mval[1];
@@ -765,13 +768,13 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
return efa;
}
}
- return NULL;
+ return nullptr;
}
- struct NearestFaceUserData data = {{0}};
- const struct NearestFaceUserData_Hit *hit = NULL;
+ NearestFaceUserData data = {{0}};
+ const NearestFaceUserData_Hit *hit = nullptr;
const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_DEFAULT;
- BMesh *prev_select_bm = NULL;
+ BMesh *prev_select_bm = nullptr;
static struct {
int index;
@@ -814,8 +817,8 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
}
}
- if (hit == NULL) {
- return NULL;
+ if (hit == nullptr) {
+ return nullptr;
}
if (r_dist_center) {
@@ -831,9 +834,10 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
BMFace *EDBM_face_find_nearest(ViewContext *vc, float *dist_px_manhattan_p)
{
+ BKE_view_layer_synced_ensure(vc->scene, vc->view_layer);
Base *base = BKE_view_layer_base_find(vc->view_layer, vc->obact);
return EDBM_face_find_nearest_ex(
- vc, dist_px_manhattan_p, NULL, false, false, false, NULL, &base, 1, NULL);
+ vc, dist_px_manhattan_p, nullptr, false, false, false, nullptr, &base, 1, nullptr);
}
#undef FIND_NEAR_SELECT_BIAS
@@ -873,18 +877,18 @@ static bool unified_findnearest(ViewContext *vc,
BMFace *ele;
int base_index;
} f, f_zbuf;
- } hit = {{NULL}};
+ } hit = {{nullptr}};
- /* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */
+ /* No after-queue (yet), so we check it now, otherwise the em_xxxofs indices are bad. */
if ((dist > 0.0f) && (em->selectmode & SCE_SELECT_FACE)) {
float dist_center = 0.0f;
float *dist_center_p = (em->selectmode & (SCE_SELECT_EDGE | SCE_SELECT_VERTEX)) ?
&dist_center :
- NULL;
+ nullptr;
uint base_index = 0;
- BMFace *efa_zbuf = NULL;
+ BMFace *efa_zbuf = nullptr;
BMFace *efa_test = EDBM_face_find_nearest_ex(
vc, &dist, dist_center_p, true, true, use_cycle, &efa_zbuf, bases, bases_len, &base_index);
@@ -903,10 +907,10 @@ static bool unified_findnearest(ViewContext *vc,
if ((dist > 0.0f) && (em->selectmode & SCE_SELECT_EDGE)) {
float dist_center = 0.0f;
- float *dist_center_p = (em->selectmode & SCE_SELECT_VERTEX) ? &dist_center : NULL;
+ float *dist_center_p = (em->selectmode & SCE_SELECT_VERTEX) ? &dist_center : nullptr;
uint base_index = 0;
- BMEdge *eed_zbuf = NULL;
+ BMEdge *eed_zbuf = nullptr;
BMEdge *eed_test = EDBM_edge_find_nearest_ex(
vc, &dist, dist_center_p, true, use_cycle, &eed_zbuf, bases, bases_len, &base_index);
@@ -936,11 +940,11 @@ static bool unified_findnearest(ViewContext *vc,
/* Return only one of 3 pointers, for front-buffer redraws. */
if (hit.v.ele) {
- hit.f.ele = NULL;
- hit.e.ele = NULL;
+ hit.f.ele = nullptr;
+ hit.e.ele = nullptr;
}
else if (hit.e.ele) {
- hit.f.ele = NULL;
+ hit.f.ele = nullptr;
}
/* there may be a face under the cursor, who's center if too far away
@@ -957,7 +961,7 @@ static bool unified_findnearest(ViewContext *vc,
}
/* Only one element type will be non-null. */
- BLI_assert(((hit.v.ele != NULL) + (hit.e.ele != NULL) + (hit.f.ele != NULL)) <= 1);
+ BLI_assert(((hit.v.ele != nullptr) + (hit.e.ele != nullptr) + (hit.f.ele != nullptr)) <= 1);
if (hit.v.ele) {
*r_base_index = hit.v.base_index;
@@ -1007,35 +1011,34 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
int *r_base_index_vert,
int *r_base_index_edge,
int *r_base_index_face,
- struct BMVert **r_eve,
- struct BMEdge **r_eed,
- struct BMFace **r_efa)
+ BMVert **r_eve,
+ BMEdge **r_eed,
+ BMFace **r_efa)
{
-
- const float mval_fl[2] = {UNPACK2(vc->mval)};
+ const float mval_fl[2] = {float(vc->mval[0]), float(vc->mval[1])};
float ray_origin[3], ray_direction[3];
struct {
uint base_index;
BMElem *ele;
- } best = {0, NULL};
+ } best = {0, nullptr};
/* Currently unused, keep since we may want to pick the best. */
UNUSED_VARS(best);
struct {
uint base_index;
BMElem *ele;
- } best_vert = {0, NULL};
+ } best_vert = {0, nullptr};
struct {
uint base_index;
BMElem *ele;
- } best_edge = {0, NULL};
+ } best_edge = {0, nullptr};
struct {
uint base_index;
BMElem *ele;
- } best_face = {0, NULL};
+ } best_face = {0, nullptr};
if (ED_view3d_win_to_ray_clipped(
vc->depsgraph, vc->region, vc->v3d, mval_fl, ray_origin, ray_direction, true)) {
@@ -1044,9 +1047,9 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
float dist_sq_best_edge = FLT_MAX;
float dist_sq_best_face = FLT_MAX;
- const bool use_vert = (r_eve != NULL);
- const bool use_edge = (r_eed != NULL);
- const bool use_face = (r_efa != NULL);
+ const bool use_vert = (r_eve != nullptr);
+ const bool use_edge = (r_eed != nullptr);
+ const bool use_face = (r_efa != nullptr);
for (uint base_index = 0; base_index < bases_len; base_index++) {
Base *base_iter = bases[base_index];
@@ -1057,18 +1060,19 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
float imat3[3][3];
ED_view3d_viewcontext_init_object(vc, obedit);
- copy_m3_m4(imat3, obedit->obmat);
+ copy_m3_m4(imat3, obedit->object_to_world);
invert_m3(imat3);
- const float(*coords)[3] = NULL;
+ const float(*coords)[3] = nullptr;
{
- Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(vc->depsgraph, obedit->data);
- if (me_eval->runtime.edit_data) {
- coords = me_eval->runtime.edit_data->vertexCos;
+ Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(vc->depsgraph,
+ static_cast<ID *>(obedit->data));
+ if (me_eval->runtime->edit_data) {
+ coords = me_eval->runtime->edit_data->vertexCos;
}
}
- if (coords != NULL) {
+ if (coords != nullptr) {
BM_mesh_elem_index_ensure(bm, BM_VERT);
}
@@ -1076,12 +1080,13 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
BMEdge *e;
BMIter eiter;
BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
- if ((BM_elem_flag_test(e, BM_ELEM_HIDDEN) == false) && (BM_edge_is_boundary(e))) {
+ if ((BM_elem_flag_test(e, BM_ELEM_HIDDEN) == false) && BM_edge_is_boundary(e)) {
if (use_vert && use_boundary_vertices) {
for (uint j = 0; j < 2; j++) {
BMVert *v = *((&e->v1) + j);
float point[3];
- mul_v3_m4v3(point, obedit->obmat, coords ? coords[BM_elem_index_get(v)] : v->co);
+ mul_v3_m4v3(
+ point, obedit->object_to_world, coords ? coords[BM_elem_index_get(v)] : v->co);
const float dist_sq_test = dist_squared_to_ray_v3_normalized(
ray_origin, ray_direction, point);
if (dist_sq_test < dist_sq_best_vert) {
@@ -1110,7 +1115,7 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
else {
mid_v3_v3v3(point, e->v1->co, e->v2->co);
}
- mul_m4_v3(obedit->obmat, point);
+ mul_m4_v3(obedit->object_to_world, point);
const float dist_sq_test = dist_squared_to_ray_v3_normalized(
ray_origin, ray_direction, point);
if (dist_sq_test < dist_sq_best_edge) {
@@ -1135,7 +1140,8 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_HIDDEN) == false) {
float point[3];
- mul_v3_m4v3(point, obedit->obmat, coords ? coords[BM_elem_index_get(v)] : v->co);
+ mul_v3_m4v3(
+ point, obedit->object_to_world, coords ? coords[BM_elem_index_get(v)] : v->co);
const float dist_sq_test = dist_squared_to_ray_v3_normalized(
ray_origin, ray_direction, point);
if (dist_sq_test < dist_sq_best_vert) {
@@ -1165,7 +1171,7 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
else {
mid_v3_v3v3(point, e->v1->co, e->v2->co);
}
- mul_m4_v3(obedit->obmat, point);
+ mul_m4_v3(obedit->object_to_world, point);
const float dist_sq_test = dist_squared_to_ray_v3_normalized(
ray_origin, ray_direction, point);
if (dist_sq_test < dist_sq_best_edge) {
@@ -1194,7 +1200,7 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
else {
BM_face_calc_center_median(f, point);
}
- mul_m4_v3(obedit->obmat, point);
+ mul_m4_v3(obedit->object_to_world, point);
const float dist_sq_test = dist_squared_to_ray_v3_normalized(
ray_origin, ray_direction, point);
if (dist_sq_test < dist_sq_best_face) {
@@ -1218,13 +1224,13 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
*r_base_index_face = best_face.base_index;
if (r_eve) {
- *r_eve = NULL;
+ *r_eve = nullptr;
}
if (r_eed) {
- *r_eed = NULL;
+ *r_eed = nullptr;
}
if (r_efa) {
- *r_efa = NULL;
+ *r_efa = nullptr;
}
if (best_vert.ele) {
@@ -1237,7 +1243,7 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
*r_efa = (BMFace *)best_face.ele;
}
- return (best_vert.ele != NULL || best_edge.ele != NULL || best_face.ele != NULL);
+ return (best_vert.ele != nullptr || best_edge.ele != nullptr || best_face.ele != nullptr);
}
/** \} */
@@ -1254,7 +1260,6 @@ static int edbm_select_similar_region_exec(bContext *C, wmOperator *op)
bool changed = false;
/* group vars */
- int *groups_array;
int(*group_index)[2];
int group_tot;
int i;
@@ -1264,9 +1269,10 @@ static int edbm_select_similar_region_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totfacesel, __func__);
+ int *groups_array = static_cast<int *>(
+ MEM_mallocN(sizeof(*groups_array) * bm->totfacesel, __func__));
group_tot = BM_mesh_calc_face_groups(
- bm, groups_array, &group_index, NULL, NULL, NULL, BM_ELEM_SELECT, BM_VERT);
+ bm, groups_array, &group_index, nullptr, nullptr, nullptr, BM_ELEM_SELECT, BM_VERT);
BM_mesh_elem_table_ensure(bm, BM_FACE);
@@ -1277,7 +1283,7 @@ static int edbm_select_similar_region_exec(bContext *C, wmOperator *op)
const int fg_sta = group_index[i][0];
const int fg_len = group_index[i][1];
int j;
- BMFace **fg = MEM_mallocN(sizeof(*fg) * fg_len, __func__);
+ BMFace **fg = static_cast<BMFace **>(MEM_mallocN(sizeof(*fg) * fg_len, __func__));
for (j = 0; j < fg_len; j++) {
fg[j] = BM_face_at_index(bm, groups_array[fg_sta + j]);
@@ -1289,8 +1295,8 @@ static int edbm_select_similar_region_exec(bContext *C, wmOperator *op)
if (tot) {
LinkData *link;
- while ((link = BLI_pophead(&faces_regions))) {
- BMFace *f, **faces = link->data;
+ while ((link = static_cast<LinkData *>(BLI_pophead(&faces_regions)))) {
+ BMFace *f, **faces = static_cast<BMFace **>(link->data);
while ((f = *(faces++))) {
BM_face_select_set(bm, f, true);
}
@@ -1306,7 +1312,7 @@ static int edbm_select_similar_region_exec(bContext *C, wmOperator *op)
MEM_freeN(group_index);
if (changed) {
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
else {
@@ -1376,9 +1382,9 @@ static int edbm_select_mode_invoke(bContext *C, wmOperator *op, const wmEvent *e
return edbm_select_mode_exec(C, op);
}
-static char *edbm_select_mode_get_description(struct bContext *UNUSED(C),
- struct wmOperatorType *UNUSED(op),
- struct PointerRNA *values)
+static char *edbm_select_mode_get_description(bContext * /*C*/,
+ wmOperatorType * /*op*/,
+ PointerRNA *values)
{
const int type = RNA_enum_get(values, "type");
@@ -1404,7 +1410,7 @@ static char *edbm_select_mode_get_description(struct bContext *UNUSED(C),
}
}
- return NULL;
+ return nullptr;
}
void MESH_OT_select_mode(wmOperatorType *ot)
@@ -1412,10 +1418,10 @@ void MESH_OT_select_mode(wmOperatorType *ot)
PropertyRNA *prop;
static const EnumPropertyItem actions_items[] = {
- {0, "DISABLE", 0, "Disable", "Disable selected markers"},
- {1, "ENABLE", 0, "Enable", "Enable selected markers"},
- {2, "TOGGLE", 0, "Toggle", "Toggle disabled flag for selected markers"},
- {0, NULL, 0, NULL, NULL},
+ {0, "DISABLE", false, "Disable", "Disable selected markers"},
+ {1, "ENABLE", false, "Enable", "Enable selected markers"},
+ {2, "TOGGLE", false, "Toggle", "Toggle disabled flag for selected markers"},
+ {0, nullptr, 0, nullptr, nullptr},
};
/* identifiers */
@@ -1435,11 +1441,11 @@ void MESH_OT_select_mode(wmOperatorType *ot)
/* properties */
/* Hide all, not to show redo panel. */
prop = RNA_def_boolean(ot->srna, "use_extend", false, "Extend", "");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE));
prop = RNA_def_boolean(ot->srna, "use_expand", false, "Expand", "");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE));
ot->prop = prop = RNA_def_enum(ot->srna, "type", rna_enum_mesh_select_mode_items, 0, "Type", "");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE));
prop = RNA_def_enum(
ot->srna, "action", actions_items, 2, "Action", "Selection action to execute");
@@ -1472,7 +1478,8 @@ static void walker_select_count(BMEditMesh *em,
BMW_FLAG_TEST_HIDDEN,
BMW_NIL_LAY);
- for (ele = BMW_begin(&walker, start); ele; ele = BMW_step(&walker)) {
+ for (ele = static_cast<BMElem *>(BMW_begin(&walker, start)); ele;
+ ele = static_cast<BMElem *>(BMW_step(&walker))) {
r_count_by_select[BM_elem_flag_test(ele, BM_ELEM_SELECT) ? 1 : 0] += 1;
/* Early exit when mixed (could be optional if needed. */
@@ -1500,7 +1507,8 @@ static void walker_select(BMEditMesh *em, int walkercode, void *start, const boo
BMW_FLAG_TEST_HIDDEN,
BMW_NIL_LAY);
- for (ele = BMW_begin(&walker, start); ele; ele = BMW_step(&walker)) {
+ for (ele = static_cast<BMElem *>(BMW_begin(&walker, start)); ele;
+ ele = static_cast<BMElem *>(BMW_step(&walker))) {
if (!select) {
BM_select_history_remove(bm, ele);
}
@@ -1512,10 +1520,11 @@ static void walker_select(BMEditMesh *em, int walkercode, void *start, const boo
static int edbm_loop_multiselect_exec(bContext *C, wmOperator *op)
{
const bool is_ring = RNA_boolean_get(op->ptr, "ring");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -1525,7 +1534,6 @@ static int edbm_loop_multiselect_exec(bContext *C, wmOperator *op)
}
BMEdge *eed;
- BMEdge **edarray;
int edindex;
BMIter iter;
int totedgesel = 0;
@@ -1536,7 +1544,8 @@ static int edbm_loop_multiselect_exec(bContext *C, wmOperator *op)
}
}
- edarray = MEM_mallocN(sizeof(BMEdge *) * totedgesel, "edge array");
+ BMEdge **edarray = static_cast<BMEdge **>(
+ MEM_mallocN(sizeof(BMEdge *) * totedgesel, "edge array"));
edindex = 0;
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
@@ -1569,7 +1578,7 @@ static int edbm_loop_multiselect_exec(bContext *C, wmOperator *op)
MEM_freeN(edarray);
// if (EM_texFaceCheck())
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
MEM_freeN(objects);
@@ -1592,7 +1601,7 @@ void MESH_OT_loop_multi_select(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(ot->srna, "ring", 0, "Ring", "");
+ RNA_def_boolean(ot->srna, "ring", false, "Ring", "");
}
/** \} */
@@ -1660,10 +1669,10 @@ static void mouse_mesh_loop_edge(
static bool mouse_mesh_loop(
bContext *C, const int mval[2], bool extend, bool deselect, bool toggle, bool ring)
{
- Base *basact = NULL;
- BMVert *eve = NULL;
- BMEdge *eed = NULL;
- BMFace *efa = NULL;
+ Base *basact = nullptr;
+ BMVert *eve = nullptr;
+ BMEdge *eed = nullptr;
+ BMFace *efa = nullptr;
ViewContext vc;
BMEditMesh *em;
@@ -1673,15 +1682,16 @@ static bool mouse_mesh_loop(
float mvalf[2];
em_setup_viewcontext(C, &vc);
- mvalf[0] = (float)(vc.mval[0] = mval[0]);
- mvalf[1] = (float)(vc.mval[1] = mval[1]);
+ mvalf[0] = float(vc.mval[0] = mval[0]);
+ mvalf[1] = float(vc.mval[1] = mval[1]);
BMEditMesh *em_original = vc.em;
const short selectmode = em_original->selectmode;
em_original->selectmode = SCE_SELECT_EDGE;
uint bases_len;
- Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(vc.view_layer, vc.v3d, &bases_len);
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(
+ vc.scene, vc.view_layer, vc.v3d, &bases_len);
{
int base_index = -1;
@@ -1691,13 +1701,13 @@ static bool mouse_mesh_loop(
em = vc.em;
}
else {
- em = NULL;
+ em = nullptr;
}
}
em_original->selectmode = selectmode;
- if (em == NULL || eed == NULL) {
+ if (em == nullptr || eed == nullptr) {
MEM_freeN(bases);
return false;
}
@@ -1735,7 +1745,7 @@ static bool mouse_mesh_loop(
}
EDBM_flag_disable_all(em_iter, BM_ELEM_SELECT);
- DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(ob_iter->data), ID_RECALC_SELECT);
}
}
@@ -1789,7 +1799,7 @@ static bool mouse_mesh_loop(
BMFace *f;
BMIter iterf;
float best_dist = FLT_MAX;
- efa = NULL;
+ efa = nullptr;
/* We can't be sure this has already been set... */
ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
@@ -1820,7 +1830,7 @@ static bool mouse_mesh_loop(
MEM_freeN(bases);
- DEG_id_tag_update(vc.obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(vc.obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
return true;
@@ -1859,13 +1869,13 @@ void MESH_OT_loop_select(wmOperatorType *ot)
/* properties */
PropertyRNA *prop;
- prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "Extend the selection");
+ prop = RNA_def_boolean(ot->srna, "extend", false, "Extend Select", "Extend the selection");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Remove from the selection");
+ prop = RNA_def_boolean(ot->srna, "deselect", false, "Deselect", "Remove from the selection");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "toggle", 0, "Toggle Select", "Toggle the selection");
+ prop = RNA_def_boolean(ot->srna, "toggle", false, "Toggle Select", "Toggle the selection");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "ring", 0, "Select Ring", "Select ring");
+ prop = RNA_def_boolean(ot->srna, "ring", false, "Select Ring", "Select ring");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
@@ -1885,11 +1895,11 @@ void MESH_OT_edgering_select(wmOperatorType *ot)
/* Properties. */
PropertyRNA *prop;
- prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection");
+ prop = RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Remove from the selection");
+ prop = RNA_def_boolean(ot->srna, "deselect", false, "Deselect", "Remove from the selection");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "toggle", 0, "Toggle Select", "Toggle the selection");
+ prop = RNA_def_boolean(ot->srna, "toggle", false, "Toggle Select", "Toggle the selection");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(ot->srna, "ring", 1, "Select Ring", "Select ring");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
@@ -1903,12 +1913,13 @@ void MESH_OT_edgering_select(wmOperatorType *ot)
static int edbm_select_all_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
int action = RNA_enum_get(op->ptr, "action");
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
@@ -1937,7 +1948,7 @@ static int edbm_select_all_exec(bContext *C, wmOperator *op)
EDBM_selectmode_flush(em);
break;
}
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
@@ -1969,12 +1980,13 @@ void MESH_OT_select_all(wmOperatorType *ot)
/** \name Select Interior Faces Operator
* \{ */
-static int edbm_faces_select_interior_exec(bContext *C, wmOperator *UNUSED(op))
+static int edbm_faces_select_interior_exec(bContext *C, wmOperator * /*op*/)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -1984,7 +1996,7 @@ static int edbm_faces_select_interior_exec(bContext *C, wmOperator *UNUSED(op))
continue;
}
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
MEM_freeN(objects);
@@ -2016,14 +2028,14 @@ void MESH_OT_select_interior_faces(wmOperatorType *ot)
* Gets called via generic mouse select operator.
* \{ */
-bool EDBM_select_pick(bContext *C, const int mval[2], const struct SelectPick_Params *params)
+bool EDBM_select_pick(bContext *C, const int mval[2], const SelectPick_Params *params)
{
ViewContext vc;
int base_index_active = -1;
- BMVert *eve = NULL;
- BMEdge *eed = NULL;
- BMFace *efa = NULL;
+ BMVert *eve = nullptr;
+ BMEdge *eed = nullptr;
+ BMFace *efa = nullptr;
/* setup view context for argument to callbacks */
em_setup_viewcontext(C, &vc);
@@ -2031,7 +2043,8 @@ bool EDBM_select_pick(bContext *C, const int mval[2], const struct SelectPick_Pa
vc.mval[1] = mval[1];
uint bases_len = 0;
- Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(vc.view_layer, vc.v3d, &bases_len);
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(
+ vc.scene, vc.view_layer, vc.v3d, &bases_len);
bool changed = false;
bool found = unified_findnearest(&vc, bases, bases_len, &base_index_active, &eve, &eed, &efa);
@@ -2047,7 +2060,7 @@ bool EDBM_select_pick(bContext *C, const int mval[2], const struct SelectPick_Pa
Base *base_iter = bases[base_index];
Object *ob_iter = base_iter->object;
EDBM_flag_disable_all(BKE_editmesh_from_object(ob_iter), BM_ELEM_SELECT);
- DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(ob_iter->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data);
}
changed = true;
@@ -2191,7 +2204,7 @@ bool EDBM_select_pick(bContext *C, const int mval[2], const struct SelectPick_Pa
if (efa->mat_nr != vc.obedit->actcol - 1) {
vc.obedit->actcol = efa->mat_nr + 1;
vc.em->mat_nr = efa->mat_nr;
- WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, NULL);
+ WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, nullptr);
}
/* Change active face-map on object. */
@@ -2214,11 +2227,12 @@ bool EDBM_select_pick(bContext *C, const int mval[2], const struct SelectPick_Pa
/* Changing active object is handy since it allows us to
* switch UV layers, vgroups for eg. */
- if (vc.view_layer->basact != basact) {
+ BKE_view_layer_synced_ensure(vc.scene, vc.view_layer);
+ if (BKE_view_layer_active_base_get(vc.view_layer) != basact) {
ED_object_base_activate(C, basact);
}
- DEG_id_tag_update(vc.obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(vc.obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
changed = true;
@@ -2240,7 +2254,7 @@ static void edbm_strip_selections(BMEditMesh *em)
BMEditSelection *ese, *nextese;
if (!(em->selectmode & SCE_SELECT_VERTEX)) {
- ese = em->bm->selected.first;
+ ese = static_cast<BMEditSelection *>(em->bm->selected.first);
while (ese) {
nextese = ese->next;
if (ese->htype == BM_VERT) {
@@ -2250,7 +2264,7 @@ static void edbm_strip_selections(BMEditMesh *em)
}
}
if (!(em->selectmode & SCE_SELECT_EDGE)) {
- ese = em->bm->selected.first;
+ ese = static_cast<BMEditSelection *>(em->bm->selected.first);
while (ese) {
nextese = ese->next;
if (ese->htype == BM_EDGE) {
@@ -2260,7 +2274,7 @@ static void edbm_strip_selections(BMEditMesh *em)
}
}
if (!(em->selectmode & SCE_SELECT_FACE)) {
- ese = em->bm->selected.first;
+ ese = static_cast<BMEditSelection *>(em->bm->selected.first);
while (ese) {
nextese = ese->next;
if (ese->htype == BM_FACE) {
@@ -2441,14 +2455,14 @@ bool EDBM_selectmode_toggle_multi(bContext *C,
ViewLayer *view_layer = CTX_data_view_layer(C);
ToolSettings *ts = CTX_data_tool_settings(C);
Object *obedit = CTX_data_edit_object(C);
- BMEditMesh *em = NULL;
+ BMEditMesh *em = nullptr;
bool ret = false;
if (obedit && obedit->type == OB_MESH) {
em = BKE_editmesh_from_object(obedit);
}
- if (em == NULL) {
+ if (em == nullptr) {
return ret;
}
@@ -2488,7 +2502,7 @@ bool EDBM_selectmode_toggle_multi(bContext *C,
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob_iter = objects[ob_index];
@@ -2540,16 +2554,17 @@ bool EDBM_selectmode_toggle_multi(bContext *C,
if (ret == true) {
ts->selectmode = em->selectmode;
- em = NULL;
+ em = nullptr;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob_iter = objects[ob_index];
BMEditMesh *em_iter = BKE_editmesh_from_object(ob_iter);
em_iter->selectmode = ts->selectmode;
EDBM_selectmode_set(em_iter);
- DEG_id_tag_update(ob_iter->data, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(ob_iter->data),
+ ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data);
}
- WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, NULL);
+ WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, nullptr);
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
}
@@ -2564,11 +2579,11 @@ bool EDBM_selectmode_set_multi(bContext *C, const short selectmode)
{
Object *obedit = CTX_data_edit_object(C);
- BMEditMesh *em = NULL;
+ BMEditMesh *em = nullptr;
if (obedit && obedit->type == OB_MESH) {
em = BKE_editmesh_from_object(obedit);
}
- if (em == NULL) {
+ if (em == nullptr) {
return changed;
}
}
@@ -2584,7 +2599,7 @@ bool EDBM_selectmode_set_multi(bContext *C, const short selectmode)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob_iter = objects[ob_index];
@@ -2592,7 +2607,8 @@ bool EDBM_selectmode_set_multi(bContext *C, const short selectmode)
if (em_iter->selectmode != ts->selectmode) {
em_iter->selectmode = ts->selectmode;
EDBM_selectmode_set(em_iter);
- DEG_id_tag_update(ob_iter->data, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(ob_iter->data),
+ ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data);
changed = true;
}
@@ -2600,7 +2616,7 @@ bool EDBM_selectmode_set_multi(bContext *C, const short selectmode)
MEM_freeN(objects);
if (changed) {
- WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, NULL);
+ WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, nullptr);
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
}
return changed;
@@ -2697,7 +2713,7 @@ void EDBM_select_swap(BMEditMesh *em) /* exported for UV */
}
}
-bool EDBM_mesh_deselect_all_multi_ex(struct Base **bases, const uint bases_len)
+bool EDBM_mesh_deselect_all_multi_ex(Base **bases, const uint bases_len)
{
bool changed_multi = false;
for (uint base_index = 0; base_index < bases_len; base_index++) {
@@ -2710,27 +2726,27 @@ bool EDBM_mesh_deselect_all_multi_ex(struct Base **bases, const uint bases_len)
}
EDBM_flag_disable_all(em_iter, BM_ELEM_SELECT);
- DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(ob_iter->data), ID_RECALC_SELECT);
changed_multi = true;
}
return changed_multi;
}
-bool EDBM_mesh_deselect_all_multi(struct bContext *C)
+bool EDBM_mesh_deselect_all_multi(bContext *C)
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
ViewContext vc;
ED_view3d_viewcontext_init(C, &vc, depsgraph);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- vc.view_layer, vc.v3d, &bases_len);
+ vc.scene, vc.view_layer, vc.v3d, &bases_len);
bool changed_multi = EDBM_mesh_deselect_all_multi_ex(bases, bases_len);
MEM_freeN(bases);
return changed_multi;
}
bool EDBM_selectmode_disable_multi_ex(Scene *scene,
- struct Base **bases,
+ Base **bases,
const uint bases_len,
const short selectmode_disable,
const short selectmode_fallback)
@@ -2748,7 +2764,7 @@ bool EDBM_selectmode_disable_multi_ex(Scene *scene,
return changed_multi;
}
-bool EDBM_selectmode_disable_multi(struct bContext *C,
+bool EDBM_selectmode_disable_multi(bContext *C,
const short selectmode_disable,
const short selectmode_fallback)
{
@@ -2758,7 +2774,7 @@ bool EDBM_selectmode_disable_multi(struct bContext *C,
ED_view3d_viewcontext_init(C, &vc, depsgraph);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- vc.view_layer, NULL, &bases_len);
+ vc.scene, vc.view_layer, nullptr, &bases_len);
bool changed_multi = EDBM_selectmode_disable_multi_ex(
scene, bases, bases_len, selectmode_disable, selectmode_fallback);
MEM_freeN(bases);
@@ -2785,7 +2801,7 @@ struct BMFaceLink {
float area;
};
-static bool bm_interior_loop_filter_fn(const BMLoop *l, void *UNUSED(user_data))
+static bool bm_interior_loop_filter_fn(const BMLoop *l, void * /*user_data*/)
{
if (BM_elem_flag_test(l->e, BM_ELEM_TAG)) {
return false;
@@ -2823,7 +2839,7 @@ static float bm_interior_face_group_calc_cost(ListBase *ls, const float *edge_le
float area = 0.0f;
float cost = 0.0f;
bool found = false;
- LISTBASE_FOREACH (struct BMFaceLink *, f_link, ls) {
+ LISTBASE_FOREACH (BMFaceLink *, f_link, ls) {
BMFace *f = f_link->face;
area += f_link->area;
int i = BM_elem_index_get(f);
@@ -2872,7 +2888,8 @@ bool EDBM_select_interior_faces(BMEditMesh *em)
BMIter iter;
bool changed = false;
- float *edge_lengths = MEM_mallocN(sizeof(*edge_lengths) * bm->totedge, __func__);
+ float *edge_lengths = static_cast<float *>(
+ MEM_mallocN(sizeof(*edge_lengths) * bm->totedge, __func__));
{
bool has_nonmanifold = false;
@@ -2901,15 +2918,16 @@ bool EDBM_select_interior_faces(BMEditMesh *em)
}
/* group vars */
- int *fgroup_array;
int(*fgroup_index)[2];
int fgroup_len;
- fgroup_array = MEM_mallocN(sizeof(*fgroup_array) * bm->totface, __func__);
+ int *fgroup_array = static_cast<int *>(
+ MEM_mallocN(sizeof(*fgroup_array) * bm->totface, __func__));
fgroup_len = BM_mesh_calc_face_groups(
- bm, fgroup_array, &fgroup_index, bm_interior_loop_filter_fn, NULL, NULL, 0, BM_EDGE);
+ bm, fgroup_array, &fgroup_index, bm_interior_loop_filter_fn, nullptr, nullptr, 0, BM_EDGE);
- int *fgroup_recalc_stack = MEM_mallocN(sizeof(*fgroup_recalc_stack) * fgroup_len, __func__);
+ int *fgroup_recalc_stack = static_cast<int *>(
+ MEM_mallocN(sizeof(*fgroup_recalc_stack) * fgroup_len, __func__));
STACK_DECLARE(fgroup_recalc_stack);
STACK_INIT(fgroup_recalc_stack, fgroup_len);
@@ -2923,8 +2941,10 @@ bool EDBM_select_interior_faces(BMEditMesh *em)
}
bm->elem_index_dirty |= BM_FACE;
- ListBase *fgroup_listbase = MEM_callocN(sizeof(*fgroup_listbase) * fgroup_len, __func__);
- struct BMFaceLink *f_link_array = MEM_callocN(sizeof(*f_link_array) * bm->totface, __func__);
+ ListBase *fgroup_listbase = static_cast<ListBase *>(
+ MEM_callocN(sizeof(*fgroup_listbase) * fgroup_len, __func__));
+ BMFaceLink *f_link_array = static_cast<BMFaceLink *>(
+ MEM_callocN(sizeof(*f_link_array) * bm->totface, __func__));
for (int i = 0; i < fgroup_len; i++) {
const int fg_sta = fgroup_index[i][0];
@@ -2934,7 +2954,7 @@ bool EDBM_select_interior_faces(BMEditMesh *em)
BMFace *f = BM_face_at_index(bm, face_index);
BM_elem_index_set(f, i);
- struct BMFaceLink *f_link = &f_link_array[face_index];
+ BMFaceLink *f_link = &f_link_array[face_index];
f_link->face = f;
f_link->area = BM_face_calc_area(f);
BLI_addtail(&fgroup_listbase[i], f_link);
@@ -2945,8 +2965,10 @@ bool EDBM_select_interior_faces(BMEditMesh *em)
MEM_freeN(fgroup_index);
Heap *fgroup_heap = BLI_heap_new_ex(fgroup_len);
- HeapNode **fgroup_table = MEM_mallocN(sizeof(*fgroup_table) * fgroup_len, __func__);
- bool *fgroup_dirty = MEM_callocN(sizeof(*fgroup_dirty) * fgroup_len, __func__);
+ HeapNode **fgroup_table = static_cast<HeapNode **>(
+ MEM_mallocN(sizeof(*fgroup_table) * fgroup_len, __func__));
+ bool *fgroup_dirty = static_cast<bool *>(
+ MEM_callocN(sizeof(*fgroup_dirty) * fgroup_len, __func__));
for (int i = 0; i < fgroup_len; i++) {
const float cost = bm_interior_face_group_calc_cost(&fgroup_listbase[i], edge_lengths);
@@ -2954,7 +2976,7 @@ bool EDBM_select_interior_faces(BMEditMesh *em)
fgroup_table[i] = BLI_heap_insert(fgroup_heap, -cost, POINTER_FROM_INT(i));
}
else {
- fgroup_table[i] = NULL;
+ fgroup_table[i] = nullptr;
}
}
@@ -2984,7 +3006,7 @@ bool EDBM_select_interior_faces(BMEditMesh *em)
}
else {
BLI_heap_remove(fgroup_heap, fgroup_table[i]);
- fgroup_table[i] = NULL;
+ fgroup_table[i] = nullptr;
}
fgroup_dirty[i] = false;
}
@@ -2999,13 +3021,13 @@ bool EDBM_select_interior_faces(BMEditMesh *em)
}
const int i_min = POINTER_AS_INT(BLI_heap_pop_min(fgroup_heap));
- BLI_assert(fgroup_table[i_min] != NULL);
+ BLI_assert(fgroup_table[i_min] != nullptr);
BLI_assert(fgroup_dirty[i_min] == false);
- fgroup_table[i_min] = NULL;
+ fgroup_table[i_min] = nullptr;
changed = true;
- struct BMFaceLink *f_link;
- while ((f_link = BLI_pophead(&fgroup_listbase[i_min]))) {
+ BMFaceLink *f_link;
+ while ((f_link = static_cast<BMFaceLink *>(BLI_pophead(&fgroup_listbase[i_min])))) {
BMFace *f = f_link->face;
BM_face_select_set(bm, f, true);
BM_elem_index_set(f, -1); /* set-dirty */
@@ -3031,21 +3053,21 @@ bool EDBM_select_interior_faces(BMEditMesh *em)
/* Merge the groups. */
LISTBASE_FOREACH (LinkData *, n, &fgroup_listbase[i_b]) {
- BMFace *f_iter = n->data;
+ BMFace *f_iter = static_cast<BMFace *>(n->data);
BM_elem_index_set(f_iter, i_a);
}
BLI_movelisttolist(&fgroup_listbase[i_a], &fgroup_listbase[i_b]);
/* This may have been added to 'fgroup_recalc_stack', instead of removing it,
- * just check the heap node isn't NULL before recalculating. */
+ * just check the heap node isn't nullptr before recalculating. */
BLI_heap_remove(fgroup_heap, fgroup_table[i_b]);
- fgroup_table[i_b] = NULL;
+ fgroup_table[i_b] = nullptr;
/* Keep the dirty flag as-is for 'i_b', because it may be in the 'fgroup_recalc_stack'
* and we don't want to add it again.
- * Instead rely on the 'fgroup_table[i_b]' being NULL as a secondary check. */
+ * Instead rely on the 'fgroup_table[i_b]' being nullptr as a secondary check. */
if (fgroup_dirty[i_a] == false) {
- BLI_assert(fgroup_table[i_a] != NULL);
+ BLI_assert(fgroup_table[i_a] != nullptr);
STACK_PUSH(fgroup_recalc_stack, i_a);
fgroup_dirty[i_a] = true;
}
@@ -3058,7 +3080,7 @@ bool EDBM_select_interior_faces(BMEditMesh *em)
do {
int i_other = BM_elem_index_get(l_radial_iter->f);
if (!ELEM(i_other, -1, i_min)) {
- if ((fgroup_table[i_other] != NULL) && (fgroup_dirty[i_other] == false)) {
+ if ((fgroup_table[i_other] != nullptr) && (fgroup_dirty[i_other] == false)) {
#if !defined(USE_DELAY_FACE_GROUP_COST_CALC)
STACK_PUSH(fgroup_recalc_stack, i_other);
#endif
@@ -3073,7 +3095,7 @@ bool EDBM_select_interior_faces(BMEditMesh *em)
for (int index = 0; index < STACK_SIZE(fgroup_recalc_stack); index++) {
const int i = fgroup_recalc_stack[index];
- if (fgroup_table[i] != NULL && fgroup_dirty[i] == true) {
+ if (fgroup_table[i] != nullptr && fgroup_dirty[i] == true) {
/* First update edge tags. */
const float cost = bm_interior_face_group_calc_cost(&fgroup_listbase[i], edge_lengths);
if (cost != FLT_MAX) {
@@ -3081,7 +3103,7 @@ bool EDBM_select_interior_faces(BMEditMesh *em)
}
else {
BLI_heap_remove(fgroup_heap, fgroup_table[i]);
- fgroup_table[i] = NULL;
+ fgroup_table[i] = nullptr;
}
}
fgroup_dirty[i] = false;
@@ -3096,7 +3118,7 @@ bool EDBM_select_interior_faces(BMEditMesh *em)
MEM_freeN(fgroup_table);
MEM_freeN(fgroup_dirty);
- BLI_heap_free(fgroup_heap, NULL);
+ BLI_heap_free(fgroup_heap, nullptr);
return changed;
}
@@ -3117,9 +3139,7 @@ struct DelimitData {
int cd_loop_offset;
};
-static bool select_linked_delimit_test(BMEdge *e,
- int delimit,
- const struct DelimitData *delimit_data)
+static bool select_linked_delimit_test(BMEdge *e, int delimit, const DelimitData *delimit_data)
{
BLI_assert(delimit);
@@ -3199,7 +3219,7 @@ static void select_linked_delimit_validate(BMesh *bm, int *delimit)
static void select_linked_delimit_begin(BMesh *bm, int delimit)
{
- struct DelimitData delimit_data = {0};
+ DelimitData delimit_data = {0};
if (delimit & BMO_DELIM_UV) {
delimit_data.cd_loop_type = CD_MLOOPUV;
@@ -3209,7 +3229,7 @@ static void select_linked_delimit_begin(BMesh *bm, int delimit)
}
}
- /* grr, shouldn't need to alloc BMO flags here */
+ /* Shouldn't need to allocated BMO flags here (sigh). */
BM_mesh_elem_toolflags_ensure(bm);
{
@@ -3217,7 +3237,7 @@ static void select_linked_delimit_begin(BMesh *bm, int delimit)
BMEdge *e;
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- const bool is_walk_ok = ((select_linked_delimit_test(e, delimit, &delimit_data) == false));
+ const bool is_walk_ok = (select_linked_delimit_test(e, delimit, &delimit_data) == false);
BMO_edge_flag_set(bm, e, BMO_ELE_TAG, is_walk_ok);
}
@@ -3245,7 +3265,7 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -3430,7 +3450,7 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
select_linked_delimit_end(em);
}
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
@@ -3594,7 +3614,7 @@ static void edbm_select_linked_pick_ex(BMEditMesh *em, BMElem *ele, bool sel, in
static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewContext vc;
- Base *basact = NULL;
+ Base *basact = nullptr;
BMVert *eve;
BMEdge *eed;
BMFace *efa;
@@ -3612,7 +3632,8 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE
em_setup_viewcontext(C, &vc);
uint bases_len;
- Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(vc.view_layer, vc.v3d, &bases_len);
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(
+ vc.scene, vc.view_layer, vc.v3d, &bases_len);
{
bool has_edges = false;
@@ -3663,13 +3684,13 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE
* which might not be available on redo. */
BM_mesh_elem_index_ensure(bm, ele->head.htype);
int object_index;
- index = EDBM_elem_to_index_any_multi(vc.view_layer, em, ele, &object_index);
+ index = EDBM_elem_to_index_any_multi(vc.scene, vc.view_layer, em, ele, &object_index);
BLI_assert(object_index >= 0);
RNA_int_set(op->ptr, "object_index", object_index);
RNA_int_set(op->ptr, "index", index);
}
- DEG_id_tag_update(basact->object->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(basact->object->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, basact->object->data);
MEM_freeN(bases);
@@ -3678,18 +3699,19 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE
static int edbm_select_linked_pick_exec(bContext *C, wmOperator *op)
{
- Object *obedit = NULL;
+ Object *obedit = nullptr;
BMElem *ele;
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
/* Intentionally wrap negative values so the lookup fails. */
- const uint object_index = (uint)RNA_int_get(op->ptr, "object_index");
- const uint index = (uint)RNA_int_get(op->ptr, "index");
- ele = EDBM_elem_from_index_any_multi(view_layer, object_index, index, &obedit);
+ const uint object_index = uint(RNA_int_get(op->ptr, "object_index"));
+ const uint index = uint(RNA_int_get(op->ptr, "index"));
+ ele = EDBM_elem_from_index_any_multi(scene, view_layer, object_index, index, &obedit);
}
- if (ele == NULL) {
+ if (ele == nullptr) {
return OPERATOR_CANCELLED;
}
@@ -3704,7 +3726,7 @@ static int edbm_select_linked_pick_exec(bContext *C, wmOperator *op)
edbm_select_linked_pick_ex(em, ele, sel, delimit);
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
return OPERATOR_FINISHED;
@@ -3727,7 +3749,7 @@ void MESH_OT_select_linked_pick(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "");
+ RNA_def_boolean(ot->srna, "deselect", false, "Deselect", "");
prop = RNA_def_enum_flag(ot->srna,
"delimit",
rna_enum_mesh_delimit_mode_items,
@@ -3740,9 +3762,9 @@ void MESH_OT_select_linked_pick(wmOperatorType *ot)
/* use for redo */
prop = RNA_def_int(ot->srna, "object_index", -1, -1, INT_MAX, "", "", 0, INT_MAX);
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE));
prop = RNA_def_int(ot->srna, "index", -1, -1, INT_MAX, "", "", 0, INT_MAX);
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE));
}
/** \} */
@@ -3753,13 +3775,14 @@ void MESH_OT_select_linked_pick(wmOperatorType *ot)
static int edbm_select_face_by_sides_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
const bool extend = RNA_boolean_get(op->ptr, "extend");
const int numverts = RNA_int_get(op->ptr, "number");
const int type = RNA_enum_get(op->ptr, "type");
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -3800,7 +3823,7 @@ static int edbm_select_face_by_sides_exec(bContext *C, wmOperator *op)
EDBM_selectmode_flush(em);
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
@@ -3811,11 +3834,11 @@ static int edbm_select_face_by_sides_exec(bContext *C, wmOperator *op)
void MESH_OT_select_face_by_sides(wmOperatorType *ot)
{
static const EnumPropertyItem type_items[] = {
- {0, "LESS", 0, "Less Than", ""},
- {1, "EQUAL", 0, "Equal To", ""},
- {2, "GREATER", 0, "Greater Than", ""},
- {3, "NOTEQUAL", 0, "Not Equal To", ""},
- {0, NULL, 0, NULL, NULL},
+ {0, "LESS", false, "Less Than", ""},
+ {1, "EQUAL", false, "Equal To", ""},
+ {2, "GREATER", false, "Greater Than", ""},
+ {3, "NOTEQUAL", false, "Not Equal To", ""},
+ {0, nullptr, 0, nullptr, nullptr},
};
/* identifiers */
@@ -3844,12 +3867,13 @@ void MESH_OT_select_face_by_sides(wmOperatorType *ot)
static int edbm_select_loose_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const bool extend = RNA_boolean_get(op->ptr, "extend");
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -3899,7 +3923,7 @@ static int edbm_select_loose_exec(bContext *C, wmOperator *op)
EDBM_selectmode_flush(em);
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
@@ -3934,6 +3958,7 @@ void MESH_OT_select_loose(wmOperatorType *ot)
static int edbm_select_mirror_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const int axis_flag = RNA_enum_get(op->ptr, "axis");
const bool extend = RNA_boolean_get(op->ptr, "extend");
@@ -3944,7 +3969,7 @@ static int edbm_select_mirror_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -3958,14 +3983,19 @@ static int edbm_select_mirror_exec(bContext *C, wmOperator *op)
for (int axis = 0; axis < 3; axis++) {
if ((1 << axis) & axis_flag) {
- EDBM_select_mirrored(em, obedit->data, axis, extend, &tot_mirr_iter, &tot_fail_iter);
+ EDBM_select_mirrored(em,
+ static_cast<const Mesh *>(obedit->data),
+ axis,
+ extend,
+ &tot_mirr_iter,
+ &tot_fail_iter);
}
}
if (tot_mirr_iter) {
EDBM_selectmode_flush(em);
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
@@ -3997,7 +4027,7 @@ void MESH_OT_select_mirror(wmOperatorType *ot)
/* props */
RNA_def_enum_flag(ot->srna, "axis", rna_enum_axis_flag_xyz_items, (1 << 0), "Axis", "");
- RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the existing selection");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the existing selection");
}
/** \} */
@@ -4008,12 +4038,13 @@ void MESH_OT_select_mirror(wmOperatorType *ot)
static int edbm_select_more_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const bool use_face_step = RNA_boolean_get(op->ptr, "use_face_step");
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -4024,7 +4055,7 @@ static int edbm_select_more_exec(bContext *C, wmOperator *op)
}
EDBM_select_more(em, use_face_step);
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
@@ -4058,12 +4089,13 @@ void MESH_OT_select_more(wmOperatorType *ot)
static int edbm_select_less_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const bool use_face_step = RNA_boolean_get(op->ptr, "use_face_step");
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -4074,7 +4106,7 @@ static int edbm_select_less_exec(bContext *C, wmOperator *op)
}
EDBM_select_less(em, use_face_step);
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
@@ -4131,7 +4163,7 @@ static bool bm_edge_is_select_isolated(BMEdge *e)
* order, starting from h_act. Deselects elements if the depth when they
* are reached is not a multiple of "nth". */
static void walker_deselect_nth(BMEditMesh *em,
- const struct CheckerIntervalParams *op_params,
+ const CheckerIntervalParams *op_params,
BMHeader *h_act)
{
BMElem *ele;
@@ -4142,7 +4174,7 @@ static void walker_deselect_nth(BMEditMesh *em,
short mask_vert = 0, mask_edge = 0, mask_face = 0;
/* No active element from which to start - nothing to do */
- if (h_act == NULL) {
+ if (h_act == nullptr) {
return;
}
@@ -4171,12 +4203,12 @@ static void walker_deselect_nth(BMEditMesh *em,
break;
}
- /* grr, shouldn't need to alloc BMO flags here */
+ /* Shouldn't need to allocate BMO flags here (sigh). */
BM_mesh_elem_toolflags_ensure(bm);
/* Walker restrictions uses BMO flags, not header flags,
* so transfer BM_ELEM_SELECT from HFlags onto a BMO flag layer. */
- BMO_push(bm, NULL);
+ BMO_push(bm, nullptr);
BM_ITER_MESH (ele, &iter, bm, itertype) {
if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
BMO_elem_flag_enable(bm, (BMElemF *)ele, BMO_ELE_TAG);
@@ -4190,7 +4222,7 @@ static void walker_deselect_nth(BMEditMesh *em,
mask_vert,
mask_edge,
mask_face,
- BMW_FLAG_NOP, /* don't use BMW_FLAG_TEST_HIDDEN here since we want to desel all */
+ BMW_FLAG_NOP, /* Don't use #BMW_FLAG_TEST_HIDDEN here since we want to deselect all. */
BMW_NIL_LAY);
/* use tag to avoid touching the same verts twice */
@@ -4199,7 +4231,8 @@ static void walker_deselect_nth(BMEditMesh *em,
}
BLI_assert(walker.order == BMW_BREADTH_FIRST);
- for (ele = BMW_begin(&walker, h_act); ele != NULL; ele = BMW_step(&walker)) {
+ for (ele = static_cast<BMElem *>(BMW_begin(&walker, h_act)); ele != nullptr;
+ ele = static_cast<BMElem *>(BMW_step(&walker))) {
if (!BM_elem_flag_test(ele, BM_ELEM_TAG)) {
/* Deselect elements that aren't at "nth" depth from active */
const int depth = BMW_current_depth(&walker) - 1;
@@ -4222,9 +4255,9 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed,
BMIter iter;
BMElem *ele;
- *r_eve = NULL;
- *r_eed = NULL;
- *r_efa = NULL;
+ *r_eve = nullptr;
+ *r_eed = nullptr;
+ *r_efa = nullptr;
EDBM_selectmode_flush(em);
ele = BM_mesh_active_elem_get(em->bm);
@@ -4270,7 +4303,7 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed,
}
}
-static bool edbm_deselect_nth(BMEditMesh *em, const struct CheckerIntervalParams *op_params)
+static bool edbm_deselect_nth(BMEditMesh *em, const CheckerIntervalParams *op_params)
{
BMVert *v;
BMEdge *e;
@@ -4296,14 +4329,15 @@ static bool edbm_deselect_nth(BMEditMesh *em, const struct CheckerIntervalParams
static int edbm_select_nth_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- struct CheckerIntervalParams op_params;
+ CheckerIntervalParams op_params;
WM_operator_properties_checker_interval_from_op(op, &op_params);
bool found_active_elt = false;
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -4315,12 +4349,11 @@ static int edbm_select_nth_exec(bContext *C, wmOperator *op)
if (edbm_deselect_nth(em, &op_params) == true) {
found_active_elt = true;
- EDBM_update(obedit->data,
- &(const struct EDBMUpdate_Params){
- .calc_looptri = false,
- .calc_normals = false,
- .is_destructive = false,
- });
+ EDBMUpdate_Params params{};
+ params.calc_looptri = false;
+ params.calc_normals = false;
+ params.is_destructive = false;
+ EDBM_update(static_cast<Mesh *>(obedit->data), &params);
}
}
MEM_freeN(objects);
@@ -4374,10 +4407,11 @@ static int edbm_select_sharp_edges_exec(bContext *C, wmOperator *op)
*/
const float angle_limit_cos = cosf(RNA_float_get(op->ptr, "sharpness"));
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -4404,7 +4438,7 @@ static int edbm_select_sharp_edges_exec(bContext *C, wmOperator *op)
else {
EDBM_selectmode_flush(em);
}
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
MEM_freeN(objects);
@@ -4432,7 +4466,7 @@ void MESH_OT_edges_select_sharp(wmOperatorType *ot)
prop = RNA_def_float_rotation(ot->srna,
"sharpness",
0,
- NULL,
+ nullptr,
DEG2RADF(0.01f),
DEG2RADF(180.0f),
"Sharpness",
@@ -4450,10 +4484,11 @@ void MESH_OT_edges_select_sharp(wmOperatorType *ot)
static int edbm_select_linked_flat_faces_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
const float angle_limit_cos = cosf(RNA_float_get(op->ptr, "sharpness"));
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@@ -4465,7 +4500,7 @@ static int edbm_select_linked_flat_faces_exec(bContext *C, wmOperator *op)
continue;
}
- BLI_LINKSTACK_DECLARE(stack, BMFace *);
+ blender::Vector<BMFace *> stack;
BMIter iter, liter, liter2;
BMFace *f;
@@ -4473,8 +4508,6 @@ static int edbm_select_linked_flat_faces_exec(bContext *C, wmOperator *op)
BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
- BLI_LINKSTACK_INIT(stack);
-
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
if ((BM_elem_flag_test(f, BM_ELEM_HIDDEN) != 0) ||
(BM_elem_flag_test(f, BM_ELEM_TAG) != 0) ||
@@ -4482,7 +4515,7 @@ static int edbm_select_linked_flat_faces_exec(bContext *C, wmOperator *op)
continue;
}
- BLI_assert(BLI_LINKSTACK_SIZE(stack) == 0);
+ BLI_assert(stack.is_empty());
do {
BM_face_select_set(bm, f, true);
@@ -4501,16 +4534,14 @@ static int edbm_select_linked_flat_faces_exec(bContext *C, wmOperator *op)
angle_cos = dot_v3v3(f->no, l2->f->no);
if (angle_cos > angle_limit_cos) {
- BLI_LINKSTACK_PUSH(stack, l2->f);
+ stack.append(l2->f);
}
}
}
- } while ((f = BLI_LINKSTACK_POP(stack)));
+ } while (!stack.is_empty() && (f = stack.pop_last()));
}
- BLI_LINKSTACK_FREE(stack);
-
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
MEM_freeN(objects);
@@ -4538,7 +4569,7 @@ void MESH_OT_faces_select_linked_flat(wmOperatorType *ot)
prop = RNA_def_float_rotation(ot->srna,
"sharpness",
0,
- NULL,
+ nullptr,
DEG2RADF(0.01f),
DEG2RADF(180.0f),
"Sharpness",
@@ -4563,10 +4594,11 @@ static int edbm_select_non_manifold_exec(bContext *C, wmOperator *op)
const bool use_non_contiguous = RNA_boolean_get(op->ptr, "use_non_contiguous");
const bool use_verts = RNA_boolean_get(op->ptr, "use_verts");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -4604,7 +4636,7 @@ static int edbm_select_non_manifold_exec(bContext *C, wmOperator *op)
if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
if ((use_wire && BM_edge_is_wire(e)) || (use_boundary && BM_edge_is_boundary(e)) ||
(use_non_contiguous && (BM_edge_is_manifold(e) && !BM_edge_is_contiguous(e))) ||
- (use_multi_face && (BM_edge_face_count_is_over(e, 2)))) {
+ (use_multi_face && BM_edge_face_count_is_over(e, 2))) {
/* check we never select perfect edge (in test above) */
BLI_assert(!(BM_edge_is_manifold(e) && BM_edge_is_contiguous(e)));
@@ -4614,7 +4646,7 @@ static int edbm_select_non_manifold_exec(bContext *C, wmOperator *op)
}
}
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
EDBM_selectmode_flush(em);
@@ -4667,11 +4699,12 @@ static int edbm_select_random_exec(bContext *C, wmOperator *op)
const float randfac = RNA_float_get(op->ptr, "ratio");
const int seed = WM_operator_properties_select_random_seed_increment_get(op);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -4685,7 +4718,8 @@ static int edbm_select_random_exec(bContext *C, wmOperator *op)
if (em->selectmode & SCE_SELECT_VERTEX) {
int elem_map_len = 0;
- BMVert **elem_map = MEM_mallocN(sizeof(*elem_map) * em->bm->totvert, __func__);
+ BMVert **elem_map = static_cast<BMVert **>(
+ MEM_mallocN(sizeof(*elem_map) * em->bm->totvert, __func__));
BMVert *eve;
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
@@ -4702,7 +4736,8 @@ static int edbm_select_random_exec(bContext *C, wmOperator *op)
}
else if (em->selectmode & SCE_SELECT_EDGE) {
int elem_map_len = 0;
- BMEdge **elem_map = MEM_mallocN(sizeof(*elem_map) * em->bm->totedge, __func__);
+ BMEdge **elem_map = static_cast<BMEdge **>(
+ MEM_mallocN(sizeof(*elem_map) * em->bm->totedge, __func__));
BMEdge *eed;
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
@@ -4718,7 +4753,8 @@ static int edbm_select_random_exec(bContext *C, wmOperator *op)
}
else {
int elem_map_len = 0;
- BMFace **elem_map = MEM_mallocN(sizeof(*elem_map) * em->bm->totface, __func__);
+ BMFace **elem_map = static_cast<BMFace **>(
+ MEM_mallocN(sizeof(*elem_map) * em->bm->totface, __func__));
BMFace *efa;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
@@ -4741,7 +4777,7 @@ static int edbm_select_random_exec(bContext *C, wmOperator *op)
EDBM_deselect_flush(em);
}
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
@@ -4797,11 +4833,12 @@ static bool edbm_select_ungrouped_poll(bContext *C)
static int edbm_select_ungrouped_exec(bContext *C, wmOperator *op)
{
const bool extend = RNA_boolean_get(op->ptr, "extend");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -4827,9 +4864,9 @@ static int edbm_select_ungrouped_exec(bContext *C, wmOperator *op)
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
+ MDeformVert *dv = static_cast<MDeformVert *>(BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset));
/* no dv or dv set with no weight */
- if (ELEM(NULL, dv, dv->dw)) {
+ if (ELEM(nullptr, dv, dv->dw)) {
BM_vert_select_set(em->bm, eve, true);
changed = true;
}
@@ -4838,7 +4875,7 @@ static int edbm_select_ungrouped_exec(bContext *C, wmOperator *op)
if (changed) {
EDBM_selectmode_flush(em);
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
}
@@ -4886,7 +4923,7 @@ static int edbm_select_axis_exec(bContext *C, wmOperator *op)
const int axis = RNA_enum_get(op->ptr, "axis");
const int sign = RNA_enum_get(op->ptr, "sign");
- if (v_act == NULL) {
+ if (v_act == nullptr) {
BKE_report(
op->reports, RPT_WARNING, "This operator requires an active vertex (last selected)");
return OPERATOR_CANCELLED;
@@ -4897,7 +4934,7 @@ static int edbm_select_axis_exec(bContext *C, wmOperator *op)
float value;
float axis_mat[3][3];
- /* 3D view variables may be NULL, (no need to check in poll function). */
+ /* 3D view variables may be nullptr, (no need to check in poll function). */
ED_transform_calc_orientation_from_type_ex(scene,
view_layer,
CTX_wm_view3d(C),
@@ -4912,7 +4949,7 @@ static int edbm_select_axis_exec(bContext *C, wmOperator *op)
{
float vertex_world[3];
- mul_v3_m4v3(vertex_world, obedit->obmat, v_act->co);
+ mul_v3_m4v3(vertex_world, obedit->object_to_world, v_act->co);
value = dot_v3v3(axis_vector, vertex_world);
}
@@ -4925,7 +4962,7 @@ static int edbm_select_axis_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit_iter = objects[ob_index];
BMEditMesh *em_iter = BKE_editmesh_from_object(obedit_iter);
@@ -4942,7 +4979,7 @@ static int edbm_select_axis_exec(bContext *C, wmOperator *op)
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN | BM_ELEM_SELECT)) {
float v_iter_world[3];
- mul_v3_m4v3(v_iter_world, obedit_iter->obmat, v->co);
+ mul_v3_m4v3(v_iter_world, obedit_iter->object_to_world, v->co);
const float value_iter = dot_v3v3(axis_vector, v_iter_world);
switch (sign) {
case SELECT_AXIS_ALIGN:
@@ -4969,7 +5006,7 @@ static int edbm_select_axis_exec(bContext *C, wmOperator *op)
if (changed) {
EDBM_selectmode_flush(em_iter);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit_iter->data);
- DEG_id_tag_update(obedit_iter->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit_iter->data), ID_RECALC_SELECT);
}
}
MEM_freeN(objects);
@@ -4979,10 +5016,10 @@ static int edbm_select_axis_exec(bContext *C, wmOperator *op)
void MESH_OT_select_axis(wmOperatorType *ot)
{
static const EnumPropertyItem axis_sign_items[] = {
- {SELECT_AXIS_POS, "POS", 0, "Positive Axis", ""},
- {SELECT_AXIS_NEG, "NEG", 0, "Negative Axis", ""},
- {SELECT_AXIS_ALIGN, "ALIGN", 0, "Aligned Axis", ""},
- {0, NULL, 0, NULL, NULL},
+ {SELECT_AXIS_POS, "POS", false, "Positive Axis", ""},
+ {SELECT_AXIS_NEG, "NEG", false, "Negative Axis", ""},
+ {SELECT_AXIS_ALIGN, "ALIGN", false, "Aligned Axis", ""},
+ {0, nullptr, 0, nullptr, nullptr},
};
/* identifiers */
@@ -5021,12 +5058,13 @@ void MESH_OT_select_axis(wmOperatorType *ot)
/** \name Select Region to Loop Operator
* \{ */
-static int edbm_region_to_loop_exec(bContext *C, wmOperator *UNUSED(op))
+static int edbm_region_to_loop_exec(bContext *C, wmOperator * /*op*/)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -5105,21 +5143,18 @@ void MESH_OT_region_to_loop(wmOperatorType *ot)
static int loop_find_region(BMLoop *l, int flag, GSet *visit_face_set, BMFace ***region_out)
{
- BMFace **region = NULL;
- BMFace **stack = NULL;
- BLI_array_declare(region);
- BLI_array_declare(stack);
- BMFace *f;
+ blender::Vector<BMFace *> stack;
+ blender::Vector<BMFace *> region;
- BLI_array_append(stack, l->f);
+ stack.append(l->f);
BLI_gset_insert(visit_face_set, l->f);
- while (BLI_array_len(stack) > 0) {
+ while (!stack.is_empty()) {
BMIter liter1, liter2;
BMLoop *l1, *l2;
- f = BLI_array_pop(stack);
- BLI_array_append(region, f);
+ BMFace *f = stack.pop_last();
+ region.append(f);
BM_ITER_ELEM (l1, &liter1, f, BM_LOOPS_OF_FACE) {
if (BM_elem_flag_test(l1->e, flag)) {
@@ -5134,16 +5169,17 @@ static int loop_find_region(BMLoop *l, int flag, GSet *visit_face_set, BMFace **
}
if (BLI_gset_add(visit_face_set, l2->f)) {
- BLI_array_append(stack, l2->f);
+ stack.append(l2->f);
}
}
}
}
- BLI_array_free(stack);
-
- *region_out = region;
- return BLI_array_len(region);
+ BMFace **region_alloc = static_cast<BMFace **>(
+ MEM_malloc_arrayN(region.size(), sizeof(BMFace *), __func__));
+ memcpy(region_alloc, region.data(), region.as_span().size_in_bytes());
+ *region_out = region_alloc;
+ return region.size();
}
static int verg_radial(const void *va, const void *vb)
@@ -5174,11 +5210,11 @@ static int loop_find_regions(BMEditMesh *em, const bool selbigger)
GSet *visit_face_set;
BMIter iter;
const int edges_len = em->bm->totedgesel;
- BMEdge *e, **edges;
+ BMEdge *e;
int count = 0, i;
visit_face_set = BLI_gset_ptr_new_ex(__func__, edges_len);
- edges = MEM_mallocN(sizeof(*edges) * edges_len, __func__);
+ BMEdge **edges = static_cast<BMEdge **>(MEM_mallocN(sizeof(*edges) * edges_len, __func__));
i = 0;
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
@@ -5197,7 +5233,7 @@ static int loop_find_regions(BMEditMesh *em, const bool selbigger)
for (i = 0; i < edges_len; i++) {
BMIter liter;
BMLoop *l;
- BMFace **region = NULL, **region_out;
+ BMFace **region = nullptr, **region_out;
int c, tot = 0;
e = edges[i];
@@ -5246,7 +5282,7 @@ static int loop_find_regions(BMEditMesh *em, const bool selbigger)
}
MEM_freeN(edges);
- BLI_gset_free(visit_face_set, NULL);
+ BLI_gset_free(visit_face_set, nullptr);
return count;
}
@@ -5255,10 +5291,11 @@ static int edbm_loop_to_region_exec(bContext *C, wmOperator *op)
{
const bool select_bigger = RNA_boolean_get(op->ptr, "select_bigger");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -5288,7 +5325,7 @@ static int edbm_loop_to_region_exec(bContext *C, wmOperator *op)
EDBM_selectmode_flush(em);
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
MEM_freeN(objects);
@@ -5312,7 +5349,7 @@ void MESH_OT_loop_to_region(wmOperatorType *ot)
RNA_def_boolean(ot->srna,
"select_bigger",
- 0,
+ false,
"Select Bigger",
"Select bigger regions instead of smaller ones");
}
diff --git a/source/blender/editors/mesh/editmesh_select_similar.c b/source/blender/editors/mesh/editmesh_select_similar.c
index c71ad02537e..d9721db326a 100644
--- a/source/blender/editors/mesh/editmesh_select_similar.c
+++ b/source/blender/editors/mesh/editmesh_select_similar.c
@@ -135,9 +135,9 @@ static void face_to_plane(const Object *ob, BMFace *face, float r_plane[4])
{
float normal[3], co[3];
copy_v3_v3(normal, face->no);
- mul_transposed_mat3_m4_v3(ob->imat, normal);
+ mul_transposed_mat3_m4_v3(ob->world_to_object, normal);
normalize_v3(normal);
- mul_v3_m4v3(co, ob->obmat, BM_FACE_FIRST_LOOP(face)->v->co);
+ mul_v3_m4v3(co, ob->object_to_world, BM_FACE_FIRST_LOOP(face)->v->co);
plane_from_point_normal_v3(r_plane, co, normal);
}
@@ -147,6 +147,7 @@ static void face_to_plane(const Object *ob, BMFace *face, float r_plane[4])
*/
static int similar_face_select_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const int type = RNA_enum_get(op->ptr, "type");
@@ -157,7 +158,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
int tot_faces_selected_all = 0;
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
@@ -205,7 +206,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
BMEditMesh *em = BKE_editmesh_from_object(ob);
BMesh *bm = em->bm;
Material ***material_array = NULL;
- invert_m4_m4(ob->imat, ob->obmat);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
int custom_data_offset = 0;
if (bm->totfacesel == 0) {
@@ -213,7 +214,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
}
float ob_m3[3][3];
- copy_m3_m4(ob_m3, ob->obmat);
+ copy_m3_m4(ob_m3, ob->object_to_world);
switch (type) {
case SIMFACE_MATERIAL: {
@@ -268,7 +269,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
case SIMFACE_NORMAL: {
float normal[3];
copy_v3_v3(normal, face->no);
- mul_transposed_mat3_m4_v3(ob->imat, normal);
+ mul_transposed_mat3_m4_v3(ob->world_to_object, normal);
normalize_v3(normal);
BLI_kdtree_3d_insert(tree_3d, tree_index++, normal);
break;
@@ -334,7 +335,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
int custom_data_offset;
float ob_m3[3][3];
- copy_m3_m4(ob_m3, ob->obmat);
+ copy_m3_m4(ob_m3, ob->object_to_world);
bool has_custom_data_layer = false;
switch (type) {
@@ -413,7 +414,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
case SIMFACE_NORMAL: {
float normal[3];
copy_v3_v3(normal, face->no);
- mul_transposed_mat3_m4_v3(ob->imat, normal);
+ mul_transposed_mat3_m4_v3(ob->world_to_object, normal);
normalize_v3(normal);
/* We are treating the normals as coordinates, the "nearest" one will
@@ -558,8 +559,8 @@ static void edge_pos_direction_worldspace_get(Object *ob, BMEdge *edge, float *r
copy_v3_v3(v1, edge->v1->co);
copy_v3_v3(v2, edge->v2->co);
- mul_m4_v3(ob->obmat, v1);
- mul_m4_v3(ob->obmat, v2);
+ mul_m4_v3(ob->object_to_world, v1);
+ mul_m4_v3(ob->object_to_world, v2);
sub_v3_v3v3(r_dir, v1, v2);
normalize_v3(r_dir);
@@ -585,8 +586,8 @@ static float edge_length_squared_worldspace_get(Object *ob, BMEdge *edge)
{
float v1[3], v2[3];
- mul_v3_mat3_m4v3(v1, ob->obmat, edge->v1->co);
- mul_v3_mat3_m4v3(v2, ob->obmat, edge->v2->co);
+ mul_v3_mat3_m4v3(v1, ob->object_to_world, edge->v1->co);
+ mul_v3_mat3_m4v3(v2, ob->object_to_world, edge->v2->co);
return len_squared_v3v3(v1, v2);
}
@@ -620,6 +621,7 @@ static bool edge_data_value_set(BMEdge *edge, const int hflag, int *r_value)
*/
static int similar_edge_select_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const int type = RNA_enum_get(op->ptr, "type");
@@ -631,7 +633,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op)
int tot_edges_selected_all = 0;
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
@@ -703,7 +705,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op)
}
float ob_m3[3][3], ob_m3_inv[3][3];
- copy_m3_m4(ob_m3, ob->obmat);
+ copy_m3_m4(ob_m3, ob->object_to_world);
invert_m3_m3(ob_m3_inv, ob_m3);
BMEdge *edge; /* Mesh edge. */
@@ -810,7 +812,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op)
}
float ob_m3[3][3], ob_m3_inv[3][3];
- copy_m3_m4(ob_m3, ob->obmat);
+ copy_m3_m4(ob_m3, ob->object_to_world);
invert_m3_m3(ob_m3_inv, ob_m3);
BMEdge *edge; /* Mesh edge. */
@@ -970,6 +972,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op)
static int similar_vert_select_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
/* get the type from RNA */
@@ -981,7 +984,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
int tot_verts_selected_all = 0;
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
@@ -1025,7 +1028,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
BLI_bitmap *defbase_selected = NULL;
int defbase_len = 0;
- invert_m4_m4(ob->imat, ob->obmat);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
if (bm->totvertsel == 0) {
continue;
@@ -1064,7 +1067,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
case SIMVERT_NORMAL: {
float normal[3];
copy_v3_v3(normal, vert->no);
- mul_transposed_mat3_m4_v3(ob->imat, normal);
+ mul_transposed_mat3_m4_v3(ob->world_to_object, normal);
normalize_v3(normal);
BLI_kdtree_3d_insert(tree_3d, normal_tree_index++, normal);
@@ -1214,7 +1217,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
case SIMVERT_NORMAL: {
float normal[3];
copy_v3_v3(normal, vert->no);
- mul_transposed_mat3_m4_v3(ob->imat, normal);
+ mul_transposed_mat3_m4_v3(ob->world_to_object, normal);
normalize_v3(normal);
/* We are treating the normals as coordinates, the "nearest" one will
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 7de5ad9f151..8b29472f687 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -93,10 +93,11 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op)
const int quad_corner_type = RNA_enum_get(op->ptr, "quadcorner");
const int seed = RNA_int_get(op->ptr, "seed");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -289,11 +290,11 @@ static void mesh_operator_edgering_props_get(wmOperator *op, struct EdgeRingOpSu
static int edbm_subdivide_edge_ring_exec(bContext *C, wmOperator *op)
{
-
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
struct EdgeRingOpSubdProps op_props;
mesh_operator_edgering_props_get(op, &op_props);
@@ -358,10 +359,11 @@ void MESH_OT_subdivide_edgering(wmOperatorType *ot)
static int edbm_unsubdivide_exec(bContext *C, wmOperator *op)
{
const int iterations = RNA_int_get(op->ptr, "iterations");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -444,11 +446,12 @@ static void edbm_report_delete_info(ReportList *reports,
static int edbm_delete_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
bool changed_multi = false;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@@ -587,13 +590,14 @@ static bool bm_face_is_loose(BMFace *f)
static int edbm_delete_loose_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
int totelem_old_sel[3];
int totelem_old[3];
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
EDBM_mesh_stats_multi(objects, objects_len, totelem_old, totelem_old_sel);
@@ -695,10 +699,11 @@ void MESH_OT_delete_loose(wmOperatorType *ot)
static int edbm_collapse_edge_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -928,10 +933,11 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op)
{
/* When this is used to dissolve we could avoid this, but checking isn't too slow. */
bool changed_multi = false;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -1049,7 +1055,7 @@ static int edbm_mark_seam_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -1129,11 +1135,12 @@ static int edbm_mark_sharp_exec(bContext *C, wmOperator *op)
BMIter iter;
const bool clear = RNA_boolean_get(op->ptr, "clear");
const bool use_verts = RNA_boolean_get(op->ptr, "use_verts");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -1312,11 +1319,12 @@ static bool edbm_connect_vert_pair(BMEditMesh *em, struct Mesh *me, wmOperator *
static int edbm_vert_connect_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
uint failed_objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -1559,12 +1567,13 @@ static bool bm_vert_connect_select_history_edge_to_vert_path(BMesh *bm, ListBase
static int edbm_vert_connect_path_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
uint failed_selection_order_len = 0;
uint failed_connect_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -1655,10 +1664,11 @@ void MESH_OT_vert_connect_path(wmOperatorType *ot)
static int edbm_vert_connect_concave_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -1706,11 +1716,12 @@ void MESH_OT_vert_connect_concave(wmOperatorType *ot)
static int edbm_vert_connect_nonplaner_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const float angle_limit = RNA_float_get(op->ptr, "angle_limit");
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -1780,10 +1791,11 @@ void MESH_OT_vert_connect_nonplanar(wmOperatorType *ot)
static int edbm_face_make_planar_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
const int repeat = RNA_int_get(op->ptr, "repeat");
const float fac = RNA_float_get(op->ptr, "factor");
@@ -1947,10 +1959,11 @@ static int edbm_edge_split_exec(bContext *C, wmOperator *op)
{
const int type = RNA_enum_get(op->ptr, "type");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -2012,10 +2025,11 @@ void MESH_OT_edge_split(wmOperatorType *ot)
static int edbm_duplicate_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
bool changed = false;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@@ -2243,10 +2257,11 @@ static int edbm_flip_normals_exec(bContext *C, wmOperator *op)
{
const bool only_clnors = RNA_boolean_get(op->ptr, "only_clnors");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -2309,10 +2324,11 @@ static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op)
int tot_failed_all = 0;
bool no_selected_edges = true, invalid_selected_edges = true;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -2435,12 +2451,13 @@ void MESH_OT_edge_rotate(wmOperatorType *ot)
static int edbm_hide_exec(bContext *C, wmOperator *op)
{
const bool unselected = RNA_boolean_get(op->ptr, "unselected");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
bool changed = false;
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -2516,11 +2533,12 @@ void MESH_OT_hide(wmOperatorType *ot)
static int edbm_reveal_exec(bContext *C, wmOperator *op)
{
const bool select = RNA_boolean_get(op->ptr, "select");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -2564,12 +2582,13 @@ void MESH_OT_reveal(wmOperatorType *ot)
static int edbm_normals_make_consistent_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const bool inside = RNA_boolean_get(op->ptr, "inside");
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -2645,10 +2664,11 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op)
repeat = 1;
}
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Mesh *me = obedit->data;
@@ -2764,6 +2784,7 @@ void MESH_OT_vertices_smooth(wmOperatorType *ot)
static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
{
int tot_unselected = 0;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const float lambda_factor = RNA_float_get(op->ptr, "lambda_factor");
@@ -2780,7 +2801,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -2905,10 +2926,11 @@ static void mesh_set_smooth_faces(BMEditMesh *em, short smooth)
static int edbm_faces_shade_smooth_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -2953,10 +2975,11 @@ void MESH_OT_faces_shade_smooth(wmOperatorType *ot)
static int edbm_faces_shade_flat_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -3004,10 +3027,11 @@ static int edbm_rotate_uvs_exec(bContext *C, wmOperator *op)
/* get the direction from RNA */
const bool use_ccw = RNA_boolean_get(op->ptr, "use_ccw");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -3040,10 +3064,11 @@ static int edbm_rotate_uvs_exec(bContext *C, wmOperator *op)
static int edbm_reverse_uvs_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -3078,10 +3103,11 @@ static int edbm_rotate_colors_exec(bContext *C, wmOperator *op)
/* get the direction from RNA */
const bool use_ccw = RNA_boolean_get(op->ptr, "use_ccw");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
@@ -3131,10 +3157,11 @@ static int edbm_rotate_colors_exec(bContext *C, wmOperator *op)
static int edbm_reverse_colors_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -3329,8 +3356,8 @@ static bool merge_target(BMEditMesh *em,
if (use_cursor) {
vco = scene->cursor.location;
copy_v3_v3(co, vco);
- invert_m4_m4(ob->imat, ob->obmat);
- mul_m4_v3(ob->imat, co);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
+ mul_m4_v3(ob->world_to_object, co);
}
else {
float fac;
@@ -3376,7 +3403,7 @@ static int edbm_merge_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
const int type = RNA_enum_get(op->ptr, "type");
const bool uvs = RNA_boolean_get(op->ptr, "uvs");
@@ -3540,10 +3567,11 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op)
int count_multi = 0;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -3686,13 +3714,14 @@ static bool shape_propagate(BMEditMesh *em)
static int edbm_shape_propagate_to_all_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
int tot_shapekeys = 0;
int tot_selected_verts_objects = 0;
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Mesh *me = obedit->data;
@@ -3759,6 +3788,7 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op)
BMEditMesh *em_ref = me_ref->edit_mesh;
BMVert *eve;
BMIter iter;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
float co[3], *sco;
int totshape_ref = 0;
@@ -3787,7 +3817,7 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op)
int tot_selected_verts_objects = 0;
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Mesh *me = obedit->data;
@@ -3938,10 +3968,11 @@ static int edbm_solidify_exec(bContext *C, wmOperator *op)
{
const float thickness = RNA_float_get(op->ptr, "thickness");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -4686,7 +4717,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
uint bases_len = 0;
uint empty_selection_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &bases_len);
+ scene, view_layer, CTX_wm_view3d(C), &bases_len);
for (uint bs_index = 0; bs_index < bases_len; bs_index++) {
Base *base = bases[bs_index];
BMEditMesh *em = BKE_editmesh_from_object(base->object);
@@ -4835,10 +4866,11 @@ static int edbm_fill_exec(bContext *C, wmOperator *op)
bool has_selected_edges = false, has_faces_filled = false;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -5090,10 +5122,11 @@ static int edbm_fill_grid_exec(bContext *C, wmOperator *op)
{
const bool use_interp_simple = RNA_boolean_get(op->ptr, "use_interp_simple");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -5231,10 +5264,11 @@ static int edbm_fill_holes_exec(bContext *C, wmOperator *op)
{
const int sides = RNA_int_get(op->ptr, "sides");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -5294,10 +5328,11 @@ void MESH_OT_fill_holes(wmOperatorType *ot)
static int edbm_beautify_fill_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
const float angle_max = M_PI;
const float angle_limit = RNA_float_get(op->ptr, "angle_limit");
@@ -5392,10 +5427,11 @@ static int edbm_poke_face_exec(bContext *C, wmOperator *op)
const bool use_relative_offset = RNA_boolean_get(op->ptr, "use_relative_offset");
const int center_mode = RNA_enum_get(op->ptr, "center_mode");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -5488,11 +5524,12 @@ static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op)
{
const int quad_method = RNA_enum_get(op->ptr, "quad_method");
const int ngon_method = RNA_enum_get(op->ptr, "ngon_method");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -5582,11 +5619,12 @@ void MESH_OT_quads_convert_to_tris(wmOperatorType *ot)
static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
const bool do_seam = RNA_boolean_get(op->ptr, "seam");
const bool do_sharp = RNA_boolean_get(op->ptr, "sharp");
@@ -5743,10 +5781,11 @@ static int edbm_decimate_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -5960,10 +5999,11 @@ static int edbm_dissolve_verts_exec(bContext *C, wmOperator *op)
const bool use_face_split = RNA_boolean_get(op->ptr, "use_face_split");
const bool use_boundary_tear = RNA_boolean_get(op->ptr, "use_boundary_tear");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -6027,10 +6067,11 @@ static int edbm_dissolve_edges_exec(bContext *C, wmOperator *op)
const bool use_verts = RNA_boolean_get(op->ptr, "use_verts");
const bool use_face_split = RNA_boolean_get(op->ptr, "use_face_split");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -6092,10 +6133,11 @@ void MESH_OT_dissolve_edges(wmOperatorType *ot)
static int edbm_dissolve_faces_exec(bContext *C, wmOperator *op)
{
const bool use_verts = RNA_boolean_get(op->ptr, "use_verts");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -6208,10 +6250,11 @@ static int edbm_dissolve_limited_exec(bContext *C, wmOperator *op)
const int delimit = RNA_enum_get(op->ptr, "delimit");
char dissolve_flag;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -6329,13 +6372,14 @@ void MESH_OT_dissolve_limited(wmOperatorType *ot)
static int edbm_dissolve_degenerate_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
int totelem_old[3] = {0, 0, 0};
int totelem_new[3] = {0, 0, 0};
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -6413,11 +6457,12 @@ void MESH_OT_dissolve_degenerate(wmOperatorType *ot)
static int edbm_delete_edgeloop_exec(bContext *C, wmOperator *op)
{
const bool use_face_split = RNA_boolean_get(op->ptr, "use_face_split");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -6497,10 +6542,11 @@ void MESH_OT_delete_edgeloop(wmOperatorType *ot)
static int edbm_split_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -6638,7 +6684,7 @@ static void sort_bmelem_flag(bContext *C,
int coidx = (action == SRT_VIEW_ZAXIS) ? 2 : 0;
/* Apply the view matrix to the object matrix. */
- mul_m4_m4m4(mat, rv3d->viewmat, ob->obmat);
+ mul_m4_m4m4(mat, rv3d->viewmat, ob->object_to_world);
if (totelem[0]) {
pb = pblock[0] = MEM_callocN(sizeof(char) * totelem[0], "sort_bmelem vert pblock");
@@ -6707,7 +6753,7 @@ static void sort_bmelem_flag(bContext *C,
copy_v3_v3(cur, scene->cursor.location);
- invert_m4_m4(mat, ob->obmat);
+ invert_m4_m4(mat, ob->object_to_world);
mul_m4_v3(mat, cur);
if (totelem[0]) {
@@ -7092,7 +7138,7 @@ static int edbm_sort_elements_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
@@ -7396,11 +7442,12 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op)
const bool use_merge = RNA_boolean_get(op->ptr, "use_merge");
const float merge_factor = RNA_float_get(op->ptr, "merge_factor");
const int twist_offset = RNA_int_get(op->ptr, "twist_offset");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -7476,10 +7523,11 @@ static int edbm_wireframe_exec(bContext *C, wmOperator *op)
const float thickness = RNA_float_get(op->ptr, "thickness");
const float offset = RNA_float_get(op->ptr, "offset");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -7587,7 +7635,7 @@ static int edbm_offset_edgeloop_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &bases_len);
+ scene, view_layer, CTX_wm_view3d(C), &bases_len);
for (uint base_index = 0; base_index < bases_len; base_index++) {
Object *obedit = bases[base_index]->object;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -7676,10 +7724,11 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op)
float angle_face_threshold = RNA_float_get(op->ptr, "face_threshold");
float angle_shape_threshold = RNA_float_get(op->ptr, "shape_threshold");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -7809,10 +7858,11 @@ void MESH_OT_convex_hull(wmOperatorType *ot)
static int mesh_symmetrize_exec(bContext *C, wmOperator *op)
{
const float thresh = RNA_float_get(op->ptr, "threshold");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -7908,10 +7958,11 @@ static int mesh_symmetry_snap_exec(bContext *C, wmOperator *op)
int axis = axis_dir % 3;
bool axis_sign = axis != axis_dir;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -8074,11 +8125,12 @@ static int edbm_mark_freestyle_edge_exec(bContext *C, wmOperator *op)
BMIter iter;
FreestyleEdge *fed;
const bool clear = RNA_boolean_get(op->ptr, "clear");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -8154,11 +8206,12 @@ static int edbm_mark_freestyle_face_exec(bContext *C, wmOperator *op)
BMIter iter;
FreestyleFace *ffa;
const bool clear = RNA_boolean_get(op->ptr, "clear");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -8952,10 +9005,11 @@ static void normals_split(BMesh *bm)
static int normals_split_merge(bContext *C, const bool do_merge)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -9081,10 +9135,11 @@ static EnumPropertyItem average_method_items[] = {
static int edbm_average_normals_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
const int average_type = RNA_enum_get(op->ptr, "average_type");
const float absweight = (float)RNA_int_get(op->ptr, "weight");
const float threshold = RNA_float_get(op->ptr, "threshold");
@@ -9332,7 +9387,7 @@ static int edbm_normals_tools_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
const int mode = RNA_enum_get(op->ptr, "mode");
const bool absolute = RNA_boolean_get(op->ptr, "absolute");
float *normal_vector = scene->toolsettings->normal_vector;
@@ -9547,10 +9602,11 @@ void MESH_OT_normals_tools(struct wmOperatorType *ot)
static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -9662,10 +9718,11 @@ void MESH_OT_set_normals_from_faces(struct wmOperatorType *ot)
static int edbm_smooth_normals_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -9783,10 +9840,11 @@ void MESH_OT_smooth_normals(struct wmOperatorType *ot)
static int edbm_mod_weighted_strength_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.cc
index 7bb1dc3723f..5c837e61a79 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.cc
@@ -70,21 +70,21 @@ static CLG_LogRef LOG = {"ed.undo.mesh"};
#ifdef USE_ARRAY_STORE
/* Single linked list of layers stored per type */
-typedef struct BArrayCustomData {
- struct BArrayCustomData *next;
+struct BArrayCustomData {
+ BArrayCustomData *next;
eCustomDataType type;
int states_len; /* number of layers for each type */
BArrayState *states[0];
-} BArrayCustomData;
+};
#endif
-typedef struct UndoMesh {
+struct UndoMesh {
/**
* This undo-meshes in `um_arraystore.local_links`.
* Not to be confused with the next and previous undo steps.
*/
- struct UndoMesh *local_next, *local_prev;
+ UndoMesh *local_next, *local_prev;
Mesh me;
int selectmode;
@@ -101,7 +101,7 @@ typedef struct UndoMesh {
int shapenr;
#ifdef USE_ARRAY_STORE
- /* NULL arrays are considered empty */
+ /* Null arrays are considered empty. */
struct { /* most data is stored as 'custom' data */
BArrayCustomData *vdata, *edata, *ldata, *pdata;
BArrayState **keyblocks;
@@ -110,7 +110,7 @@ typedef struct UndoMesh {
#endif /* USE_ARRAY_STORE */
size_t undo_size;
-} UndoMesh;
+};
#ifdef USE_ARRAY_STORE
@@ -119,7 +119,7 @@ typedef struct UndoMesh {
* \{ */
static struct {
- struct BArrayStore_AtSize bs_stride;
+ BArrayStore_AtSize bs_stride;
int users;
/**
@@ -132,9 +132,9 @@ static struct {
TaskPool *task_pool;
# endif
-} um_arraystore = {{NULL}};
+} um_arraystore = {{nullptr}};
-static void um_arraystore_cd_compact(struct CustomData *cdata,
+static void um_arraystore_cd_compact(CustomData *cdata,
const size_t data_len,
bool create,
const BArrayCustomData *bcd_reference,
@@ -142,14 +142,14 @@ static void um_arraystore_cd_compact(struct CustomData *cdata,
{
if (data_len == 0) {
if (create) {
- *r_bcd_first = NULL;
+ *r_bcd_first = nullptr;
}
}
const BArrayCustomData *bcd_reference_current = bcd_reference;
- BArrayCustomData *bcd = NULL, *bcd_first = NULL, *bcd_prev = NULL;
+ BArrayCustomData *bcd = nullptr, *bcd_first = nullptr, *bcd_prev = nullptr;
for (int layer_start = 0, layer_end; layer_start < cdata->totlayer; layer_start = layer_end) {
- const eCustomDataType type = cdata->layers[layer_start].type;
+ const eCustomDataType type = eCustomDataType(cdata->layers[layer_start].type);
/* Perform a full copy on dynamic layers.
*
@@ -176,7 +176,7 @@ static void um_arraystore_cd_compact(struct CustomData *cdata,
const int stride = CustomData_sizeof(type);
BArrayStore *bs = create ? BLI_array_store_at_size_ensure(
&um_arraystore.bs_stride, stride, ARRAY_CHUNK_SIZE) :
- NULL;
+ nullptr;
const int layer_len = layer_end - layer_start;
if (create) {
@@ -184,7 +184,7 @@ static void um_arraystore_cd_compact(struct CustomData *cdata,
/* common case, the reference is aligned */
}
else {
- bcd_reference_current = NULL;
+ bcd_reference_current = nullptr;
/* Do a full lookup when unaligned. */
if (bcd_reference) {
@@ -201,8 +201,9 @@ static void um_arraystore_cd_compact(struct CustomData *cdata,
}
if (create) {
- bcd = MEM_callocN(sizeof(BArrayCustomData) + (layer_len * sizeof(BArrayState *)), __func__);
- bcd->next = NULL;
+ bcd = static_cast<BArrayCustomData *>(
+ MEM_callocN(sizeof(BArrayCustomData) + (layer_len * sizeof(BArrayState *)), __func__));
+ bcd->next = nullptr;
bcd->type = type;
bcd->states_len = layer_end - layer_start;
@@ -223,23 +224,23 @@ static void um_arraystore_cd_compact(struct CustomData *cdata,
BArrayState *state_reference = (bcd_reference_current &&
i < bcd_reference_current->states_len) ?
bcd_reference_current->states[i] :
- NULL;
+ nullptr;
/* See comment on `layer_type_is_dynamic` above. */
if (layer_type_is_dynamic) {
- state_reference = NULL;
+ state_reference = nullptr;
}
bcd->states[i] = BLI_array_store_state_add(
- bs, layer->data, (size_t)data_len * stride, state_reference);
+ bs, layer->data, size_t(data_len) * stride, state_reference);
}
else {
- bcd->states[i] = NULL;
+ bcd->states[i] = nullptr;
}
}
if (layer->data) {
MEM_freeN(layer->data);
- layer->data = NULL;
+ layer->data = nullptr;
}
}
@@ -260,7 +261,7 @@ static void um_arraystore_cd_compact(struct CustomData *cdata,
* The layers and the states are stored together so this can be kept working.
*/
static void um_arraystore_cd_expand(const BArrayCustomData *bcd,
- struct CustomData *cdata,
+ CustomData *cdata,
const size_t data_len)
{
CustomDataLayer *layer = cdata->layers;
@@ -275,7 +276,7 @@ static void um_arraystore_cd_expand(const BArrayCustomData *bcd,
UNUSED_VARS_NDEBUG(stride, data_len);
}
else {
- layer->data = NULL;
+ layer->data = nullptr;
}
layer++;
}
@@ -309,53 +310,54 @@ static void um_arraystore_compact_ex(UndoMesh *um, const UndoMesh *um_ref, bool
Mesh *me = &um->me;
um_arraystore_cd_compact(
- &me->vdata, me->totvert, create, um_ref ? um_ref->store.vdata : NULL, &um->store.vdata);
+ &me->vdata, me->totvert, create, um_ref ? um_ref->store.vdata : nullptr, &um->store.vdata);
um_arraystore_cd_compact(
- &me->edata, me->totedge, create, um_ref ? um_ref->store.edata : NULL, &um->store.edata);
+ &me->edata, me->totedge, create, um_ref ? um_ref->store.edata : nullptr, &um->store.edata);
um_arraystore_cd_compact(
- &me->ldata, me->totloop, create, um_ref ? um_ref->store.ldata : NULL, &um->store.ldata);
+ &me->ldata, me->totloop, create, um_ref ? um_ref->store.ldata : nullptr, &um->store.ldata);
um_arraystore_cd_compact(
- &me->pdata, me->totpoly, create, um_ref ? um_ref->store.pdata : NULL, &um->store.pdata);
+ &me->pdata, me->totpoly, create, um_ref ? um_ref->store.pdata : nullptr, &um->store.pdata);
if (me->key && me->key->totkey) {
const size_t stride = me->key->elemsize;
BArrayStore *bs = create ? BLI_array_store_at_size_ensure(
&um_arraystore.bs_stride, stride, ARRAY_CHUNK_SIZE) :
- NULL;
+ nullptr;
if (create) {
- um->store.keyblocks = MEM_mallocN(me->key->totkey * sizeof(*um->store.keyblocks), __func__);
+ um->store.keyblocks = static_cast<BArrayState **>(
+ MEM_mallocN(me->key->totkey * sizeof(*um->store.keyblocks), __func__));
}
- KeyBlock *keyblock = me->key->block.first;
+ KeyBlock *keyblock = static_cast<KeyBlock *>(me->key->block.first);
for (int i = 0; i < me->key->totkey; i++, keyblock = keyblock->next) {
if (create) {
BArrayState *state_reference = (um_ref && um_ref->me.key && (i < um_ref->me.key->totkey)) ?
um_ref->store.keyblocks[i] :
- NULL;
+ nullptr;
um->store.keyblocks[i] = BLI_array_store_state_add(
- bs, keyblock->data, (size_t)keyblock->totelem * stride, state_reference);
+ bs, keyblock->data, size_t(keyblock->totelem) * stride, state_reference);
}
if (keyblock->data) {
MEM_freeN(keyblock->data);
- keyblock->data = NULL;
+ keyblock->data = nullptr;
}
}
}
if (me->mselect && me->totselect) {
- BLI_assert(create == (um->store.mselect == NULL));
+ BLI_assert(create == (um->store.mselect == nullptr));
if (create) {
- BArrayState *state_reference = um_ref ? um_ref->store.mselect : NULL;
+ BArrayState *state_reference = um_ref ? um_ref->store.mselect : nullptr;
const size_t stride = sizeof(*me->mselect);
BArrayStore *bs = BLI_array_store_at_size_ensure(
&um_arraystore.bs_stride, stride, ARRAY_CHUNK_SIZE);
um->store.mselect = BLI_array_store_state_add(
- bs, me->mselect, (size_t)me->totselect * stride, state_reference);
+ bs, me->mselect, size_t(me->totselect) * stride, state_reference);
}
/* keep me->totselect for validation */
MEM_freeN(me->mselect);
- me->mselect = NULL;
+ me->mselect = nullptr;
}
if (create) {
@@ -416,11 +418,11 @@ static void um_arraystore_compact_with_info(UndoMesh *um, const UndoMesh *um_ref
struct UMArrayData {
UndoMesh *um;
- const UndoMesh *um_ref; /* can be NULL */
+ const UndoMesh *um_ref; /* can be nullptr */
};
-static void um_arraystore_compact_cb(TaskPool *__restrict UNUSED(pool), void *taskdata)
+static void um_arraystore_compact_cb(TaskPool *__restrict /*pool*/, void *taskdata)
{
- struct UMArrayData *um_data = taskdata;
+ UMArrayData *um_data = static_cast<UMArrayData *>(taskdata);
um_arraystore_compact_with_info(um_data->um, um_data->um_ref);
}
@@ -431,7 +433,7 @@ static void um_arraystore_compact_cb(TaskPool *__restrict UNUSED(pool), void *ta
*/
static void um_arraystore_expand_clear(UndoMesh *um)
{
- um_arraystore_compact_ex(um, NULL, false);
+ um_arraystore_compact_ex(um, nullptr, false);
}
static void um_arraystore_expand(UndoMesh *um)
@@ -445,7 +447,7 @@ static void um_arraystore_expand(UndoMesh *um)
if (um->store.keyblocks) {
const size_t stride = me->key->elemsize;
- KeyBlock *keyblock = me->key->block.first;
+ KeyBlock *keyblock = static_cast<KeyBlock *>(me->key->block.first);
for (int i = 0; i < me->key->totkey; i++, keyblock = keyblock->next) {
BArrayState *state = um->store.keyblocks[i];
size_t state_len;
@@ -459,7 +461,7 @@ static void um_arraystore_expand(UndoMesh *um)
const size_t stride = sizeof(*me->mselect);
BArrayState *state = um->store.mselect;
size_t state_len;
- me->mselect = BLI_array_store_state_data_get_alloc(state, &state_len);
+ me->mselect = static_cast<MSelect *>(BLI_array_store_state_data_get_alloc(state, &state_len));
BLI_assert(me->totselect == (state_len / stride));
UNUSED_VARS_NDEBUG(stride);
}
@@ -482,7 +484,7 @@ static void um_arraystore_free(UndoMesh *um)
BLI_array_store_state_remove(bs, state);
}
MEM_freeN(um->store.keyblocks);
- um->store.keyblocks = NULL;
+ um->store.keyblocks = nullptr;
}
if (um->store.mselect) {
@@ -490,7 +492,7 @@ static void um_arraystore_free(UndoMesh *um)
BArrayStore *bs = BLI_array_store_at_size_get(&um_arraystore.bs_stride, stride);
BArrayState *state = um->store.mselect;
BLI_array_store_state_remove(bs, state);
- um->store.mselect = NULL;
+ um->store.mselect = nullptr;
}
um_arraystore.users -= 1;
@@ -505,7 +507,7 @@ static void um_arraystore_free(UndoMesh *um)
# ifdef USE_ARRAY_STORE_THREAD
BLI_task_pool_free(um_arraystore.task_pool);
- um_arraystore.task_pool = NULL;
+ um_arraystore.task_pool = nullptr;
# endif
}
}
@@ -521,7 +523,7 @@ static void um_arraystore_free(UndoMesh *um)
*
* where each element in the resulting array is the most recently created
* undo-mesh for the object's mesh.
- * When no undo-mesh can be found that array index is NULL.
+ * When no undo-mesh can be found that array index is nullptr.
*
* This is used for de-duplicating memory between undo steps,
* failure to find the undo step will store a full duplicate in memory.
@@ -531,9 +533,10 @@ static UndoMesh **mesh_undostep_reference_elems_from_objects(Object **object, in
{
/* Map: `Mesh.id.session_uuid` -> `UndoMesh`. */
GHash *uuid_map = BLI_ghash_ptr_new_ex(__func__, object_len);
- UndoMesh **um_references = MEM_callocN(sizeof(UndoMesh *) * object_len, __func__);
+ UndoMesh **um_references = static_cast<UndoMesh **>(
+ MEM_callocN(sizeof(UndoMesh *) * object_len, __func__));
for (int i = 0; i < object_len; i++) {
- const Mesh *me = object[i]->data;
+ const Mesh *me = static_cast<const Mesh *>(object[i]->data);
BLI_ghash_insert(uuid_map, POINTER_FROM_INT(me->id.session_uuid), &um_references[i]);
}
int uuid_map_len = object_len;
@@ -541,20 +544,21 @@ static UndoMesh **mesh_undostep_reference_elems_from_objects(Object **object, in
/* Loop backwards over all previous mesh undo data until either:
* - All elements have been found (where `um_references` we'll have every element set).
* - There are no undo steps left to look for. */
- UndoMesh *um_iter = um_arraystore.local_links.last;
+ UndoMesh *um_iter = static_cast<UndoMesh *>(um_arraystore.local_links.last);
while (um_iter && (uuid_map_len != 0)) {
UndoMesh **um_p;
- if ((um_p = BLI_ghash_popkey(uuid_map, POINTER_FROM_INT(um_iter->me.id.session_uuid), NULL))) {
+ if ((um_p = static_cast<UndoMesh **>(BLI_ghash_popkey(
+ uuid_map, POINTER_FROM_INT(um_iter->me.id.session_uuid), nullptr)))) {
*um_p = um_iter;
uuid_map_len--;
}
um_iter = um_iter->local_prev;
}
BLI_assert(uuid_map_len == BLI_ghash_len(uuid_map));
- BLI_ghash_free(uuid_map, NULL, NULL);
+ BLI_ghash_free(uuid_map, nullptr, nullptr);
if (uuid_map_len == object_len) {
MEM_freeN(um_references);
- um_references = NULL;
+ um_references = nullptr;
}
return um_references;
}
@@ -578,12 +582,12 @@ static void *undomesh_from_editmesh(UndoMesh *um, BMEditMesh *em, Key *key, Undo
}
#endif
/* make sure shape keys work */
- if (key != NULL) {
+ if (key != nullptr) {
um->me.key = (Key *)BKE_id_copy_ex(
- NULL, &key->id, NULL, LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_NO_ANIMDATA);
+ nullptr, &key->id, nullptr, LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_NO_ANIMDATA);
}
else {
- um->me.key = NULL;
+ um->me.key = nullptr;
}
/* Uncomment for troubleshooting. */
@@ -593,17 +597,20 @@ static void *undomesh_from_editmesh(UndoMesh *um, BMEditMesh *em, Key *key, Undo
* on it. Necessary to use the attribute API. */
strcpy(um->me.id.name, "MEundomesh_from_editmesh");
- BM_mesh_bm_to_me(
- NULL,
- em->bm,
- &um->me,
- (&(struct BMeshToMeshParams){
- /* Undo code should not be manipulating 'G_MAIN->object' hooks/vertex-parent. */
- .calc_object_remap = false,
- .update_shapekey_indices = false,
- .cd_mask_extra = {.vmask = CD_MASK_SHAPE_KEYINDEX},
- .active_shapekey_to_mvert = true,
- }));
+ /* Runtime data is necessary for some asserts in other code, and the overhead of creating it for
+ * undo meshes should be low. */
+ BLI_assert(um->me.runtime == nullptr);
+ um->me.runtime = new blender::bke::MeshRuntime();
+
+ CustomData_MeshMasks cd_mask_extra{};
+ cd_mask_extra.vmask = CD_MASK_SHAPE_KEYINDEX;
+ BMeshToMeshParams params{};
+ /* Undo code should not be manipulating 'G_MAIN->object' hooks/vertex-parent. */
+ params.calc_object_remap = false;
+ params.update_shapekey_indices = false;
+ params.cd_mask_extra = cd_mask_extra;
+ params.active_shapekey_to_mvert = true;
+ BM_mesh_bm_to_me(nullptr, em->bm, &um->me, &params);
um->selectmode = em->selectmode;
um->shapenr = em->bm->shapenr;
@@ -614,15 +621,15 @@ static void *undomesh_from_editmesh(UndoMesh *um, BMEditMesh *em, Key *key, Undo
BLI_addtail(&um_arraystore.local_links, um);
# ifdef USE_ARRAY_STORE_THREAD
- if (um_arraystore.task_pool == NULL) {
- um_arraystore.task_pool = BLI_task_pool_create_background(NULL, TASK_PRIORITY_LOW);
+ if (um_arraystore.task_pool == nullptr) {
+ um_arraystore.task_pool = BLI_task_pool_create_background(nullptr, TASK_PRIORITY_LOW);
}
- struct UMArrayData *um_data = MEM_mallocN(sizeof(*um_data), __func__);
+ UMArrayData *um_data = static_cast<UMArrayData *>(MEM_mallocN(sizeof(*um_data), __func__));
um_data->um = um;
um_data->um_ref = um_ref;
- BLI_task_pool_push(um_arraystore.task_pool, um_arraystore_compact_cb, um_data, true, NULL);
+ BLI_task_pool_push(um_arraystore.task_pool, um_arraystore_compact_cb, um_data, true, nullptr);
# else
um_arraystore_compact_with_info(um, um_ref);
# endif
@@ -662,19 +669,16 @@ static void undomesh_to_editmesh(UndoMesh *um, Object *ob, BMEditMesh *em)
EDBM_mesh_free_data(em);
- bm = BM_mesh_create(&allocsize,
- &((struct BMeshCreateParams){
- .use_toolflags = true,
- }));
+ BMeshCreateParams create_params{};
+ create_params.use_toolflags = true;
+ bm = BM_mesh_create(&allocsize, &create_params);
- BM_mesh_bm_from_me(bm,
- &um->me,
- (&(struct BMeshFromMeshParams){
- /* Handled with tessellation. */
- .calc_face_normal = false,
- .calc_vert_normal = false,
- .active_shapekey = um->shapenr,
- }));
+ BMeshFromMeshParams convert_params{};
+ /* Handled with tessellation. */
+ convert_params.calc_face_normal = false;
+ convert_params.calc_vert_normal = false;
+ convert_params.active_shapekey = um->shapenr;
+ BM_mesh_bm_from_me(bm, &um->me, &convert_params);
em_tmp = BKE_editmesh_create(bm);
*em = *em_tmp;
@@ -730,15 +734,17 @@ static void undomesh_free_data(UndoMesh *um)
static Object *editmesh_object_from_context(bContext *C)
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
if (obedit && obedit->type == OB_MESH) {
- Mesh *me = obedit->data;
- if (me->edit_mesh != NULL) {
+ const Mesh *me = static_cast<Mesh *>(obedit->data);
+ if (me->edit_mesh != nullptr) {
return obedit;
}
}
- return NULL;
+ return nullptr;
}
/** \} */
@@ -749,37 +755,39 @@ static Object *editmesh_object_from_context(bContext *C)
* \note This is similar for all edit-mode types.
* \{ */
-typedef struct MeshUndoStep_Elem {
+struct MeshUndoStep_Elem {
UndoRefID_Object obedit_ref;
UndoMesh data;
-} MeshUndoStep_Elem;
+};
-typedef struct MeshUndoStep {
+struct MeshUndoStep {
UndoStep step;
MeshUndoStep_Elem *elems;
uint elems_len;
-} MeshUndoStep;
+};
static bool mesh_undosys_poll(bContext *C)
{
- return editmesh_object_from_context(C) != NULL;
+ return editmesh_object_from_context(C) != nullptr;
}
-static bool mesh_undosys_step_encode(struct bContext *C, struct Main *bmain, UndoStep *us_p)
+static bool mesh_undosys_step_encode(bContext *C, Main *bmain, UndoStep *us_p)
{
MeshUndoStep *us = (MeshUndoStep *)us_p;
/* Important not to use the 3D view when getting objects because all objects
* outside of this list will be moved out of edit-mode when reading back undo steps. */
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
ToolSettings *ts = CTX_data_tool_settings(C);
uint objects_len = 0;
- Object **objects = ED_undo_editmode_objects_from_view_layer(view_layer, &objects_len);
+ Object **objects = ED_undo_editmode_objects_from_view_layer(scene, view_layer, &objects_len);
- us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
+ us->elems = static_cast<MeshUndoStep_Elem *>(
+ MEM_callocN(sizeof(*us->elems) * objects_len, __func__));
us->elems_len = objects_len;
- UndoMesh **um_references = NULL;
+ UndoMesh **um_references = nullptr;
#ifdef USE_ARRAY_STORE
um_references = mesh_undostep_reference_elems_from_objects(objects, objects_len);
@@ -790,10 +798,10 @@ static bool mesh_undosys_step_encode(struct bContext *C, struct Main *bmain, Und
MeshUndoStep_Elem *elem = &us->elems[i];
elem->obedit_ref.ptr = ob;
- Mesh *me = elem->obedit_ref.ptr->data;
+ Mesh *me = static_cast<Mesh *>(elem->obedit_ref.ptr->data);
BMEditMesh *em = me->edit_mesh;
undomesh_from_editmesh(
- &elem->data, me->edit_mesh, me->key, um_references ? um_references[i] : NULL);
+ &elem->data, me->edit_mesh, me->key, um_references ? um_references[i] : nullptr);
em->needs_flush_to_id = 1;
us->step.data_size += elem->data.undo_size;
elem->data.uv_selectmode = ts->uv_selectmode;
@@ -805,7 +813,7 @@ static bool mesh_undosys_step_encode(struct bContext *C, struct Main *bmain, Und
}
MEM_freeN(objects);
- if (um_references != NULL) {
+ if (um_references != nullptr) {
MEM_freeN(um_references);
}
@@ -814,11 +822,8 @@ static bool mesh_undosys_step_encode(struct bContext *C, struct Main *bmain, Und
return true;
}
-static void mesh_undosys_step_decode(struct bContext *C,
- struct Main *bmain,
- UndoStep *us_p,
- const eUndoStepDir UNUSED(dir),
- bool UNUSED(is_final))
+static void mesh_undosys_step_decode(
+ bContext *C, Main *bmain, UndoStep *us_p, const eUndoStepDir /*dir*/, bool /*is_final*/)
{
MeshUndoStep *us = (MeshUndoStep *)us_p;
@@ -830,8 +835,8 @@ static void mesh_undosys_step_decode(struct bContext *C,
for (uint i = 0; i < us->elems_len; i++) {
MeshUndoStep_Elem *elem = &us->elems[i];
Object *obedit = elem->obedit_ref.ptr;
- Mesh *me = obedit->data;
- if (me->edit_mesh == NULL) {
+ Mesh *me = static_cast<Mesh *>(obedit->data);
+ if (me->edit_mesh == nullptr) {
/* Should never fail, may not crash but can give odd behavior. */
CLOG_ERROR(&LOG,
"name='%s', failed to enter edit-mode for object '%s', undo state invalid",
@@ -858,7 +863,7 @@ static void mesh_undosys_step_decode(struct bContext *C,
bmain->is_memfile_undo_flush_needed = true;
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, nullptr);
}
static void mesh_undosys_step_free(UndoStep *us_p)
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index cca2aa11ac3..bbc092d0a99 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -619,7 +619,45 @@ struct UvElement **BM_uv_element_map_ensure_head_table(struct UvElementMap *elem
return element_map->head_table;
}
-#define INVALID_ISLAND ((unsigned int)-1)
+int *BM_uv_element_map_ensure_unique_index(struct UvElementMap *element_map)
+{
+ if (!element_map->unique_index_table) {
+ element_map->unique_index_table = MEM_callocN(
+ element_map->total_uvs * sizeof(*element_map->unique_index_table), __func__);
+
+ int j = 0;
+ for (int i = 0; i < element_map->total_uvs; i++) {
+ UvElement *element = element_map->storage + i;
+ if (!element->separate) {
+ continue;
+ }
+ BLI_assert(0 <= j);
+ BLI_assert(j < element_map->total_unique_uvs);
+ while (element) {
+ element_map->unique_index_table[element - element_map->storage] = j;
+ element = element->next;
+ if (!element || element->separate) {
+ break;
+ }
+ }
+ j++;
+ }
+ BLI_assert(j == element_map->total_unique_uvs);
+ }
+
+ return element_map->unique_index_table;
+}
+
+int BM_uv_element_get_unique_index(struct UvElementMap *element_map, struct UvElement *child)
+{
+ int *unique_index = BM_uv_element_map_ensure_unique_index(element_map);
+ int index = child - element_map->storage;
+ BLI_assert(0 <= index);
+ BLI_assert(index < element_map->total_uvs);
+ return unique_index[index];
+}
+
+#define INVALID_ISLAND ((uint)-1)
static void bm_uv_assign_island(UvElementMap *element_map,
UvElement *element,
@@ -1163,6 +1201,7 @@ void BM_uv_element_map_free(UvElementMap *element_map)
MEM_SAFE_FREE(element_map->storage);
MEM_SAFE_FREE(element_map->vertex);
MEM_SAFE_FREE(element_map->head_table);
+ MEM_SAFE_FREE(element_map->unique_index_table);
MEM_SAFE_FREE(element_map->island_indices);
MEM_SAFE_FREE(element_map->island_total_uvs);
MEM_SAFE_FREE(element_map->island_total_unique_uvs);
@@ -1773,15 +1812,13 @@ BMElem *EDBM_elem_from_index_any(BMEditMesh *em, uint index)
return NULL;
}
-int EDBM_elem_to_index_any_multi(ViewLayer *view_layer,
- BMEditMesh *em,
- BMElem *ele,
- int *r_object_index)
+int EDBM_elem_to_index_any_multi(
+ const Scene *scene, ViewLayer *view_layer, BMEditMesh *em, BMElem *ele, int *r_object_index)
{
uint bases_len;
int elem_index = -1;
*r_object_index = -1;
- Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(view_layer, NULL, &bases_len);
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(scene, view_layer, NULL, &bases_len);
for (uint base_index = 0; base_index < bases_len; base_index++) {
Base *base_iter = bases[base_index];
if (BKE_editmesh_from_object(base_iter->object) == em) {
@@ -1794,13 +1831,14 @@ int EDBM_elem_to_index_any_multi(ViewLayer *view_layer,
return elem_index;
}
-BMElem *EDBM_elem_from_index_any_multi(ViewLayer *view_layer,
+BMElem *EDBM_elem_from_index_any_multi(const Scene *scene,
+ ViewLayer *view_layer,
uint object_index,
uint elem_index,
Object **r_obedit)
{
uint bases_len;
- Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(view_layer, NULL, &bases_len);
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(scene, view_layer, NULL, &bases_len);
*r_obedit = NULL;
Object *obedit = (object_index < bases_len) ? bases[object_index]->object : NULL;
MEM_freeN(bases);
@@ -1859,7 +1897,7 @@ bool BMBVH_EdgeVisible(struct BMBVHTree *tree,
ED_view3d_win_to_segment_clipped(depsgraph, region, v3d, mval_f, origin, end, false);
- invert_m4_m4(invmat, obedit->obmat);
+ invert_m4_m4(invmat, obedit->object_to_world);
mul_m4_v3(invmat, origin);
copy_v3_v3(co1, e->v1->co);
@@ -1943,7 +1981,7 @@ void EDBM_project_snap_verts(
NULL,
co_proj,
NULL)) {
- mul_v3_m4v3(eve->co, obedit->imat, co_proj);
+ mul_v3_m4v3(eve->co, obedit->world_to_object, co_proj);
}
}
}
diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc
index e362501d86c..9901f4e1836 100644
--- a/source/blender/editors/mesh/mesh_data.cc
+++ b/source/blender/editors/mesh/mesh_data.cc
@@ -161,9 +161,9 @@ static void mesh_uv_reset_array(float **fuv, const int len)
/* Make sure we ignore 2-sided faces. */
}
else if (len > 2) {
- float fac = 0.0f, dfac = 1.0f / (float)len;
+ float fac = 0.0f, dfac = 1.0f / float(len);
- dfac *= (float)M_PI * 2.0f;
+ dfac *= float(M_PI) * 2.0f;
for (int i = 0; i < len; i++) {
fuv[i][0] = 0.5f * sinf(fac) + 0.5f;
@@ -378,7 +378,7 @@ int ED_mesh_color_add(Mesh *me,
const char *name,
const bool active_set,
const bool do_init,
- ReportList *UNUSED(reports))
+ ReportList * /*reports*/)
{
/* NOTE: keep in sync with #ED_mesh_uv_add. */
@@ -464,7 +464,7 @@ static bool layers_poll(bContext *C)
int ED_mesh_sculpt_color_add(Mesh *me,
const char *name,
const bool do_init,
- ReportList *UNUSED(reports))
+ ReportList * /*reports*/)
{
/* NOTE: keep in sync with #ED_mesh_uv_add. */
@@ -566,7 +566,7 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int mesh_uv_texture_remove_exec(bContext *C, wmOperator *UNUSED(op))
+static int mesh_uv_texture_remove_exec(bContext *C, wmOperator * /*op*/)
{
Object *ob = ED_object_context(C);
Mesh *me = static_cast<Mesh *>(ob->data);
@@ -639,7 +639,7 @@ static int mesh_customdata_add_exec__internal(bContext *C, char htype, int type)
BM_data_layer_add(mesh->edit_mesh->bm, data, type);
}
else {
- CustomData_add_layer(data, type, CD_SET_DEFAULT, NULL, tot);
+ CustomData_add_layer(data, type, CD_SET_DEFAULT, nullptr, tot);
}
DEG_id_tag_update(&mesh->id, 0);
@@ -673,7 +673,7 @@ static bool mesh_customdata_mask_clear_poll(bContext *C)
}
return false;
}
-static int mesh_customdata_mask_clear_exec(bContext *C, wmOperator *UNUSED(op))
+static int mesh_customdata_mask_clear_exec(bContext *C, wmOperator * /*op*/)
{
int ret_a = mesh_customdata_clear_exec__internal(C, BM_VERT, CD_PAINT_MASK);
int ret_b = mesh_customdata_clear_exec__internal(C, BM_LOOP, CD_GRID_PAINT_MASK);
@@ -724,7 +724,7 @@ static bool mesh_customdata_skin_add_poll(bContext *C)
return (mesh_customdata_skin_state(C) == 0);
}
-static int mesh_customdata_skin_add_exec(bContext *C, wmOperator *UNUSED(op))
+static int mesh_customdata_skin_add_exec(bContext *C, wmOperator * /*op*/)
{
Object *ob = ED_object_context(C);
Mesh *me = static_cast<Mesh *>(ob->data);
@@ -757,7 +757,7 @@ static bool mesh_customdata_skin_clear_poll(bContext *C)
return (mesh_customdata_skin_state(C) == 1);
}
-static int mesh_customdata_skin_clear_exec(bContext *C, wmOperator *UNUSED(op))
+static int mesh_customdata_skin_clear_exec(bContext *C, wmOperator * /*op*/)
{
return mesh_customdata_clear_exec__internal(C, BM_VERT, CD_MVERT_SKIN);
}
@@ -778,7 +778,7 @@ void MESH_OT_customdata_skin_clear(wmOperatorType *ot)
}
/* Clear custom loop normals */
-static int mesh_customdata_custom_splitnormals_add_exec(bContext *C, wmOperator *UNUSED(op))
+static int mesh_customdata_custom_splitnormals_add_exec(bContext *C, wmOperator * /*op*/)
{
Mesh *me = ED_mesh_context(C);
@@ -787,7 +787,7 @@ static int mesh_customdata_custom_splitnormals_add_exec(bContext *C, wmOperator
if (me->edit_mesh) {
/* Tag edges as sharp according to smooth threshold if needed,
- * to preserve autosmooth shading. */
+ * to preserve auto-smooth shading. */
if (me->flag & ME_AUTOSMOOTH) {
BM_edges_sharp_from_angle_set(me->edit_mesh->bm, me->smoothresh);
}
@@ -796,7 +796,7 @@ static int mesh_customdata_custom_splitnormals_add_exec(bContext *C, wmOperator
}
else {
/* Tag edges as sharp according to smooth threshold if needed,
- * to preserve autosmooth shading. */
+ * to preserve auto-smooth shading. */
if (me->flag & ME_AUTOSMOOTH) {
const Span<MVert> verts = me->verts();
MutableSpan<MEdge> edges = me->edges_for_write();
@@ -841,7 +841,7 @@ void MESH_OT_customdata_custom_splitnormals_add(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int mesh_customdata_custom_splitnormals_clear_exec(bContext *C, wmOperator *UNUSED(op))
+static int mesh_customdata_custom_splitnormals_clear_exec(bContext *C, wmOperator * /*op*/)
{
Mesh *me = ED_mesh_context(C);
@@ -891,7 +891,7 @@ static bool mesh_customdata_bevel_weight_vertex_add_poll(bContext *C)
return mesh_customdata_bevel_weight_vertex_state(C) == 0;
}
-static int mesh_customdata_bevel_weight_vertex_add_exec(bContext *C, wmOperator *UNUSED(op))
+static int mesh_customdata_bevel_weight_vertex_add_exec(bContext *C, wmOperator * /*op*/)
{
return mesh_customdata_add_exec__internal(C, BM_VERT, CD_BWEIGHT);
}
@@ -913,7 +913,7 @@ static bool mesh_customdata_bevel_weight_vertex_clear_poll(bContext *C)
return (mesh_customdata_bevel_weight_vertex_state(C) == 1);
}
-static int mesh_customdata_bevel_weight_vertex_clear_exec(bContext *C, wmOperator *UNUSED(op))
+static int mesh_customdata_bevel_weight_vertex_clear_exec(bContext *C, wmOperator * /*op*/)
{
return mesh_customdata_clear_exec__internal(C, BM_VERT, CD_BWEIGHT);
}
@@ -951,7 +951,7 @@ static bool mesh_customdata_bevel_weight_edge_add_poll(bContext *C)
return mesh_customdata_bevel_weight_edge_state(C) == 0;
}
-static int mesh_customdata_bevel_weight_edge_add_exec(bContext *C, wmOperator *UNUSED(op))
+static int mesh_customdata_bevel_weight_edge_add_exec(bContext *C, wmOperator * /*op*/)
{
return mesh_customdata_add_exec__internal(C, BM_EDGE, CD_BWEIGHT);
}
@@ -973,7 +973,7 @@ static bool mesh_customdata_bevel_weight_edge_clear_poll(bContext *C)
return mesh_customdata_bevel_weight_edge_state(C) == 1;
}
-static int mesh_customdata_bevel_weight_edge_clear_exec(bContext *C, wmOperator *UNUSED(op))
+static int mesh_customdata_bevel_weight_edge_clear_exec(bContext *C, wmOperator * /*op*/)
{
return mesh_customdata_clear_exec__internal(C, BM_EDGE, CD_BWEIGHT);
}
@@ -990,6 +990,126 @@ void MESH_OT_customdata_bevel_weight_edge_clear(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/* Edge crease. */
+
+static int mesh_customdata_crease_edge_state(bContext *C)
+{
+ const Object *ob = ED_object_context(C);
+
+ if (ob && ob->type == OB_MESH) {
+ const Mesh *mesh = static_cast<Mesh *>(ob->data);
+ if (!ID_IS_LINKED(mesh)) {
+ const CustomData *data = GET_CD_DATA(mesh, edata);
+ return CustomData_has_layer(data, CD_CREASE);
+ }
+ }
+ return -1;
+}
+
+static bool mesh_customdata_crease_edge_add_poll(bContext *C)
+{
+ return mesh_customdata_crease_edge_state(C) == 0;
+}
+
+static int mesh_customdata_crease_edge_add_exec(bContext *C, wmOperator * /*op*/)
+{
+ return mesh_customdata_add_exec__internal(C, BM_EDGE, CD_CREASE);
+}
+
+void MESH_OT_customdata_crease_edge_add(wmOperatorType *ot)
+{
+ ot->name = "Add Edge Crease";
+ ot->idname = "MESH_OT_customdata_crease_edge_add";
+ ot->description = "Add an edge crease layer";
+
+ ot->exec = mesh_customdata_crease_edge_add_exec;
+ ot->poll = mesh_customdata_crease_edge_add_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static bool mesh_customdata_crease_edge_clear_poll(bContext *C)
+{
+ return mesh_customdata_crease_edge_state(C) == 1;
+}
+
+static int mesh_customdata_crease_edge_clear_exec(bContext *C, wmOperator * /*op*/)
+{
+ return mesh_customdata_clear_exec__internal(C, BM_EDGE, CD_CREASE);
+}
+
+void MESH_OT_customdata_crease_edge_clear(wmOperatorType *ot)
+{
+ ot->name = "Clear Edge Crease";
+ ot->idname = "MESH_OT_customdata_crease_edge_clear";
+ ot->description = "Clear the edge crease layer";
+
+ ot->exec = mesh_customdata_crease_edge_clear_exec;
+ ot->poll = mesh_customdata_crease_edge_clear_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* Vertex crease. */
+
+static int mesh_customdata_crease_vertex_state(bContext *C)
+{
+ const Object *object = ED_object_context(C);
+
+ if (object && object->type == OB_MESH) {
+ const Mesh *mesh = static_cast<Mesh *>(object->data);
+ if (!ID_IS_LINKED(mesh)) {
+ const CustomData *data = GET_CD_DATA(mesh, vdata);
+ return CustomData_has_layer(data, CD_CREASE);
+ }
+ }
+ return -1;
+}
+
+static bool mesh_customdata_crease_vertex_add_poll(bContext *C)
+{
+ return mesh_customdata_crease_vertex_state(C) == 0;
+}
+
+static int mesh_customdata_crease_vertex_add_exec(bContext *C, wmOperator * /*op*/)
+{
+ return mesh_customdata_add_exec__internal(C, BM_VERT, CD_CREASE);
+}
+
+void MESH_OT_customdata_crease_vertex_add(wmOperatorType *ot)
+{
+ ot->name = "Add Vertex Crease";
+ ot->idname = "MESH_OT_customdata_crease_vertex_add";
+ ot->description = "Add a vertex crease layer";
+
+ ot->exec = mesh_customdata_crease_vertex_add_exec;
+ ot->poll = mesh_customdata_crease_vertex_add_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static bool mesh_customdata_crease_vertex_clear_poll(bContext *C)
+{
+ return (mesh_customdata_crease_vertex_state(C) == 1);
+}
+
+static int mesh_customdata_crease_vertex_clear_exec(bContext *C, wmOperator * /*op*/)
+{
+ return mesh_customdata_clear_exec__internal(C, BM_VERT, CD_CREASE);
+}
+
+void MESH_OT_customdata_crease_vertex_clear(wmOperatorType *ot)
+{
+ ot->name = "Clear Vertex Crease";
+ ot->idname = "MESH_OT_customdata_crease_vertex_clear";
+ ot->description = "Clear the vertex crease layer";
+
+ ot->exec = mesh_customdata_crease_vertex_clear_exec;
+ ot->poll = mesh_customdata_crease_vertex_clear_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
/************************** Add Geometry Layers *************************/
void ED_mesh_update(Mesh *mesh, bContext *C, bool calc_edges, bool calc_edges_loose)
@@ -1014,6 +1134,7 @@ void ED_mesh_update(Mesh *mesh, bContext *C, bool calc_edges, bool calc_edges_lo
static void mesh_add_verts(Mesh *mesh, int len)
{
+ using namespace blender;
if (len == 0) {
return;
}
@@ -1032,17 +1153,18 @@ static void mesh_add_verts(Mesh *mesh, int len)
BKE_mesh_runtime_clear_cache(mesh);
- const int old_vertex_num = mesh->totvert;
mesh->totvert = totvert;
- MutableSpan<MVert> verts = mesh->verts_for_write();
- for (MVert &vert : verts.drop_front(old_vertex_num)) {
- vert.flag = SELECT;
- }
+ bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
+ bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT);
+ select_vert.span.take_back(len).fill(true);
+ select_vert.finish();
}
static void mesh_add_edges(Mesh *mesh, int len)
{
+ using namespace blender;
CustomData edata;
int totedge;
@@ -1065,13 +1187,18 @@ static void mesh_add_edges(Mesh *mesh, int len)
BKE_mesh_runtime_clear_cache(mesh);
- const int old_edges_num = mesh->totedge;
mesh->totedge = totedge;
MutableSpan<MEdge> edges = mesh->edges_for_write();
- for (MEdge &edge : edges.drop_front(old_edges_num)) {
- edge.flag = ME_EDGEDRAW | ME_EDGERENDER | SELECT;
+ for (MEdge &edge : edges.take_back(len)) {
+ edge.flag = ME_EDGEDRAW;
}
+
+ bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
+ bke::SpanAttributeWriter<bool> select_edge = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_edge", ATTR_DOMAIN_EDGE);
+ select_edge.span.take_back(len).fill(true);
+ select_edge.finish();
}
static void mesh_add_loops(Mesh *mesh, int len)
@@ -1103,6 +1230,7 @@ static void mesh_add_loops(Mesh *mesh, int len)
static void mesh_add_polys(Mesh *mesh, int len)
{
+ using namespace blender;
CustomData pdata;
int totpoly;
@@ -1125,13 +1253,13 @@ static void mesh_add_polys(Mesh *mesh, int len)
BKE_mesh_runtime_clear_cache(mesh);
- const int old_polys_num = mesh->totpoly;
mesh->totpoly = totpoly;
- MutableSpan<MPoly> polys = mesh->polys_for_write();
- for (MPoly &poly : polys.drop_front(old_polys_num)) {
- poly.flag = ME_FACE_SEL;
- }
+ bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
+ bke::SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE);
+ select_poly.span.take_back(len).fill(true);
+ select_poly.finish();
}
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index 14b8cf55493..0e20bb18595 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -18,6 +18,7 @@ struct BMElem;
struct BMOperator;
struct EnumPropertyItem;
struct LinkNode;
+struct Object;
struct bContext;
struct wmKeyConfig;
struct wmKeyMap;
@@ -84,11 +85,13 @@ struct BMElem *EDBM_elem_from_selectmode(struct BMEditMesh *em,
int EDBM_elem_to_index_any(struct BMEditMesh *em, struct BMElem *ele);
struct BMElem *EDBM_elem_from_index_any(struct BMEditMesh *em, uint index);
-int EDBM_elem_to_index_any_multi(struct ViewLayer *view_layer,
+int EDBM_elem_to_index_any_multi(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct BMEditMesh *em,
struct BMElem *ele,
int *r_object_index);
-struct BMElem *EDBM_elem_from_index_any_multi(struct ViewLayer *view_layer,
+struct BMElem *EDBM_elem_from_index_any_multi(const struct Scene *scene,
+ struct ViewLayer *view_layer,
uint object_index,
uint elem_index,
struct Object **r_obedit);
@@ -175,6 +178,8 @@ void MESH_OT_knife_project(struct wmOperatorType *ot);
* \param use_tag: When set, tag all faces inside the polylines.
*/
void EDBM_mesh_knife(struct ViewContext *vc,
+ struct Object **objects,
+ int objects_len,
struct LinkNode *polys,
bool use_tag,
bool cut_through);
@@ -190,7 +195,7 @@ void MESH_OT_loopcut(struct wmOperatorType *ot);
void MESH_OT_rip(struct wmOperatorType *ot);
void MESH_OT_rip_edge(struct wmOperatorType *ot);
-/* *** editmesh_select.c *** */
+/* *** editmesh_select.cc *** */
void MESH_OT_select_similar(struct wmOperatorType *ot);
void MESH_OT_select_similar_region(struct wmOperatorType *ot);
@@ -317,6 +322,10 @@ void MESH_OT_customdata_bevel_weight_vertex_add(struct wmOperatorType *ot);
void MESH_OT_customdata_bevel_weight_vertex_clear(struct wmOperatorType *ot);
void MESH_OT_customdata_bevel_weight_edge_add(struct wmOperatorType *ot);
void MESH_OT_customdata_bevel_weight_edge_clear(struct wmOperatorType *ot);
+void MESH_OT_customdata_crease_vertex_add(struct wmOperatorType *ot);
+void MESH_OT_customdata_crease_vertex_clear(struct wmOperatorType *ot);
+void MESH_OT_customdata_crease_edge_add(struct wmOperatorType *ot);
+void MESH_OT_customdata_crease_edge_clear(struct wmOperatorType *ot);
#ifdef __cplusplus
}
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 01c92a59fc9..c3c3abd46a1 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -143,6 +143,10 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_customdata_bevel_weight_vertex_clear);
WM_operatortype_append(MESH_OT_customdata_bevel_weight_edge_add);
WM_operatortype_append(MESH_OT_customdata_bevel_weight_edge_clear);
+ WM_operatortype_append(MESH_OT_customdata_crease_vertex_add);
+ WM_operatortype_append(MESH_OT_customdata_crease_vertex_clear);
+ WM_operatortype_append(MESH_OT_customdata_crease_edge_add);
+ WM_operatortype_append(MESH_OT_customdata_crease_edge_clear);
WM_operatortype_append(MESH_OT_edgering_select);
WM_operatortype_append(MESH_OT_loopcut);
diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc
index 108fa210075..147c26e521f 100644
--- a/source/blender/editors/mesh/meshtools.cc
+++ b/source/blender/editors/mesh/meshtools.cc
@@ -102,9 +102,6 @@ static void join_mesh_single(Depsgraph *depsgraph,
MPoly *mpoly = *mpoly_pp;
if (me->totvert) {
- /* merge customdata flag */
- ((Mesh *)ob_dst->data)->cd_flag |= me->cd_flag;
-
/* standard data */
CustomData_merge(&me->vdata, vdata, CD_MASK_MESH.vmask, CD_SET_DEFAULT, totvert);
CustomData_copy_data_named(&me->vdata, vdata, 0, *vertofs, me->totvert);
@@ -135,7 +132,7 @@ static void join_mesh_single(Depsgraph *depsgraph,
float cmat[4][4];
/* Watch this: switch matrix multiplication order really goes wrong. */
- mul_m4_m4m4(cmat, imat, ob_src->obmat);
+ mul_m4_m4m4(cmat, imat, ob_src->object_to_world);
/* transform vertex coordinates into new space */
for (a = 0; a < me->totvert; a++, mvert++) {
@@ -308,7 +305,8 @@ static void mesh_join_offset_face_sets_ID(const Mesh *mesh, int *face_set_offset
return;
}
- int *face_sets = (int *)CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ int *face_sets = (int *)CustomData_get_layer_named(
+ &mesh->pdata, CD_PROP_INT32, ".sculpt_face_set");
if (!face_sets) {
return;
}
@@ -317,15 +315,10 @@ static void mesh_join_offset_face_sets_ID(const Mesh *mesh, int *face_set_offset
for (int f = 0; f < mesh->totpoly; f++) {
/* As face sets encode the visibility in the integer sign, the offset needs to be added or
* subtracted depending on the initial sign of the integer to get the new ID. */
- if (abs(face_sets[f]) <= *face_set_offset) {
- if (face_sets[f] > 0) {
- face_sets[f] += *face_set_offset;
- }
- else {
- face_sets[f] -= *face_set_offset;
- }
+ if (face_sets[f] <= *face_set_offset) {
+ face_sets[f] += *face_set_offset;
}
- max_face_set = max_ii(max_face_set, abs(face_sets[f]));
+ max_face_set = max_ii(max_face_set, face_sets[f]);
}
*face_set_offset = max_face_set;
}
@@ -393,7 +386,7 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
* NOTE: This doesn't apply recursive parenting. */
if (join_parent) {
ob->parent = nullptr;
- BKE_object_apply_mat4_ex(ob, ob->obmat, ob->parent, ob->parentinv, false);
+ BKE_object_apply_mat4_ex(ob, ob->object_to_world, ob->parent, ob->parentinv, false);
}
/* that way the active object is always selected */
@@ -601,7 +594,7 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
/* Inverse transform for all selected meshes in this object,
* See #object_join_exec for detailed comment on why the safe version is used. */
- invert_m4_m4_safe_ortho(imat, ob->obmat);
+ invert_m4_m4_safe_ortho(imat, ob->object_to_world);
/* Add back active mesh first.
* This allows to keep things similar as they were, as much as possible
@@ -884,7 +877,7 @@ void ED_mesh_mirror_topo_table_begin(Object *ob, Mesh *me_eval)
ED_mesh_mirrtopo_init(em_mirror, me_mirror, &mesh_topo_store, false);
}
-void ED_mesh_mirror_topo_table_end(Object *UNUSED(ob))
+void ED_mesh_mirror_topo_table_end(Object * /*ob*/)
{
/* TODO: store this in object/object-data (keep unused argument for now). */
ED_mesh_mirrtopo_free(&mesh_topo_store);
@@ -1217,7 +1210,7 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], uint dist_px,
*r_index = DRW_select_buffer_sample_point(vc.depsgraph, vc.region, vc.v3d, mval);
}
- if ((*r_index) == 0 || (*r_index) > (uint)me->totpoly) {
+ if ((*r_index) == 0 || (*r_index) > uint(me->totpoly)) {
return false;
}
@@ -1274,7 +1267,7 @@ bool ED_mesh_pick_face_vert(
int v_idx_best = ORIGINDEX_NONE;
/* find the vert closest to 'mval' */
- const float mval_f[2] = {(float)mval[0], (float)mval[1]};
+ const float mval_f[2] = {float(mval[0]), float(mval[1])};
float len_best = FLT_MAX;
const Span<MVert> verts = me_eval->verts();
@@ -1342,7 +1335,7 @@ struct VertPickData {
static void ed_mesh_pick_vert__mapFunc(void *userData,
int index,
const float co[3],
- const float UNUSED(no[3]))
+ const float /*no*/[3])
{
VertPickData *data = static_cast<VertPickData *>(userData);
if (data->hide_vert && data->hide_vert[index]) {
@@ -1386,7 +1379,7 @@ bool ED_mesh_pick_vert(
*r_index = DRW_select_buffer_sample_point(vc.depsgraph, vc.region, vc.v3d, mval);
}
- if ((*r_index) == 0 || (*r_index) > (uint)me->totvert) {
+ if ((*r_index) == 0 || (*r_index) > uint(me->totvert)) {
return false;
}
@@ -1402,7 +1395,7 @@ bool ED_mesh_pick_vert(
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
/* find the vert closest to 'mval' */
- const float mval_f[2] = {(float)mval[0], (float)mval[1]};
+ const float mval_f[2] = {float(mval[0]), float(mval[1])};
VertPickData data = {nullptr};
diff --git a/source/blender/editors/metaball/editmball_undo.c b/source/blender/editors/metaball/editmball_undo.c
index 6b60967de48..0f9049ad70c 100644
--- a/source/blender/editors/metaball/editmball_undo.c
+++ b/source/blender/editors/metaball/editmball_undo.c
@@ -109,7 +109,9 @@ static void undomball_free_data(UndoMBall *umb)
static Object *editmball_object_from_context(bContext *C)
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
if (obedit && obedit->type == OB_MBALL) {
MetaBall *mb = obedit->data;
@@ -150,9 +152,10 @@ static bool mball_undosys_step_encode(struct bContext *C, struct Main *bmain, Un
/* Important not to use the 3D view when getting objects because all objects
* outside of this list will be moved out of edit-mode when reading back undo steps. */
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
- Object **objects = ED_undo_editmode_objects_from_view_layer(view_layer, &objects_len);
+ Object **objects = ED_undo_editmode_objects_from_view_layer(scene, view_layer, &objects_len);
us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
us->elems_len = objects_len;
diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c
index 6a5d620b546..9515306a26c 100644
--- a/source/blender/editors/metaball/mball_edit.c
+++ b/source/blender/editors/metaball/mball_edit.c
@@ -90,7 +90,7 @@ bool ED_mball_deselect_all_multi(bContext *C)
ED_view3d_viewcontext_init(C, &vc, depsgraph);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- vc.view_layer, vc.v3d, &bases_len);
+ vc.scene, vc.view_layer, vc.v3d, &bases_len);
bool changed_multi = BKE_mball_deselect_all_multi_ex(bases, bases_len);
MEM_freeN(bases);
return changed_multi;
@@ -145,10 +145,11 @@ static int mball_select_all_exec(bContext *C, wmOperator *op)
{
int action = RNA_enum_get(op->ptr, "action");
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &bases_len);
+ scene, view_layer, CTX_wm_view3d(C), &bases_len);
if (action == SEL_TOGGLE) {
action = BKE_mball_is_any_selected_multi(bases, bases_len) ? SEL_DESELECT : SEL_SELECT;
@@ -330,10 +331,11 @@ static int mball_select_similar_exec(bContext *C, wmOperator *op)
const float thresh = RNA_float_get(op->ptr, "threshold");
int tot_mball_selected_all = 0;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &bases_len);
+ scene, view_layer, CTX_wm_view3d(C), &bases_len);
tot_mball_selected_all = BKE_mball_select_count_multi(bases, bases_len);
@@ -463,10 +465,11 @@ static int select_random_metaelems_exec(bContext *C, wmOperator *op)
const float randfac = RNA_float_get(op->ptr, "ratio");
const int seed = WM_operator_properties_select_random_seed_increment_get(op);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
MetaBall *mb = (MetaBall *)obedit->data;
@@ -529,10 +532,11 @@ void MBALL_OT_select_random_metaelems(struct wmOperatorType *ot)
/* Duplicate selected MetaElements */
static int duplicate_metaelems_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
MetaBall *mb = (MetaBall *)obedit->data;
@@ -586,10 +590,11 @@ void MBALL_OT_duplicate_metaelems(wmOperatorType *ot)
static int delete_metaelems_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
MetaBall *mb = (MetaBall *)obedit->data;
@@ -790,7 +795,8 @@ static bool ed_mball_findnearest_metaelem(bContext *C,
}
uint bases_len = 0;
- Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(vc.view_layer, vc.v3d, &bases_len);
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(
+ vc.scene, vc.view_layer, vc.v3d, &bases_len);
int hit_cycle_offset = 0;
if (use_cycle) {
@@ -900,7 +906,7 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], const struct SelectPic
break;
}
}
-
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
MetaBall *mb = (MetaBall *)base->object->data;
mb->lastelem = ml;
@@ -908,7 +914,8 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], const struct SelectPic
DEG_id_tag_update(&mb->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb);
- if (view_layer->basact != base) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ if (BKE_view_layer_active_base_get(view_layer) != base) {
ED_object_base_activate(C, base);
}
diff --git a/source/blender/editors/object/object_add.cc b/source/blender/editors/object/object_add.cc
index c651affd96a..6075e4250eb 100644
--- a/source/blender/editors/object/object_add.cc
+++ b/source/blender/editors/object/object_add.cc
@@ -287,7 +287,7 @@ void ED_object_rotation_from_quat(float rot[3], const float viewquat[4], const c
}
case 'Y': {
quat_to_eul(rot, viewquat);
- rot[0] -= (float)M_PI_2;
+ rot[0] -= float(M_PI_2);
break;
}
case 'Z': {
@@ -322,7 +322,7 @@ void ED_object_base_init_transform_on_add(Object *object, const float loc[3], co
copy_v3_v3(object->rot, rot);
}
- BKE_object_to_mat4(object, object->obmat);
+ BKE_object_to_mat4(object, object->object_to_world);
}
float ED_object_new_primitive_matrix(bContext *C,
@@ -342,14 +342,14 @@ float ED_object_new_primitive_matrix(bContext *C,
invert_m3(rmat);
/* inverse transform for initial rotation and object */
- copy_m3_m4(mat, obedit->obmat);
+ copy_m3_m4(mat, obedit->object_to_world);
mul_m3_m3m3(cmat, rmat, mat);
invert_m3_m3(imat, cmat);
copy_m4_m3(r_primmat, imat);
/* center */
copy_v3_v3(r_primmat[3], loc);
- sub_v3_v3v3(r_primmat[3], r_primmat[3], obedit->obmat[3]);
+ sub_v3_v3v3(r_primmat[3], r_primmat[3], obedit->object_to_world[3]);
invert_m3_m3(imat, mat);
mul_m3_v3(imat, r_primmat[3]);
@@ -372,8 +372,8 @@ float ED_object_new_primitive_matrix(bContext *C,
/** \name Add Object Operator
* \{ */
-static void view_align_update(struct Main *UNUSED(main),
- struct Scene *UNUSED(scene),
+static void view_align_update(struct Main * /*main*/,
+ struct Scene * /*scene*/,
struct PointerRNA *ptr)
{
RNA_struct_idprops_unset(ptr, "rotation");
@@ -609,6 +609,7 @@ Object *ED_object_add_type_with_obdata(bContext *C,
ViewLayer *view_layer = CTX_data_view_layer(C);
{
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
if (obedit != nullptr) {
ED_object_editmode_exit_ex(bmain, scene, obedit, EM_FREEDATA);
@@ -619,17 +620,18 @@ Object *ED_object_add_type_with_obdata(bContext *C,
Object *ob;
if (obdata != nullptr) {
BLI_assert(type == BKE_object_obdata_to_type(obdata));
- ob = BKE_object_add_for_data(bmain, view_layer, type, name, obdata, true);
+ ob = BKE_object_add_for_data(bmain, scene, view_layer, type, name, obdata, true);
const short *materials_len_p = BKE_id_material_len_p(obdata);
if (materials_len_p && *materials_len_p > 0) {
BKE_object_materials_test(bmain, ob, static_cast<ID *>(ob->data));
}
}
else {
- ob = BKE_object_add(bmain, view_layer, type, name);
+ ob = BKE_object_add(bmain, scene, view_layer, type, name);
}
- Base *ob_base_act = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *ob_base_act = BKE_view_layer_active_base_get(view_layer);
/* While not getting a valid base is not a good thing, it can happen in convoluted corner cases,
* better not crash on it in releases. */
BLI_assert(ob_base_act != nullptr);
@@ -990,6 +992,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op)
}
bool newob = false;
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
if (obedit == nullptr || obedit->type != OB_MBALL) {
obedit = ED_object_add_type(C, OB_MBALL, nullptr, loc, rot, true, local_view_bits);
@@ -1099,6 +1102,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -1471,7 +1475,7 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static void object_add_ui(bContext *UNUSED(C), wmOperator *op)
+static void object_add_ui(bContext * /*C*/, wmOperator *op)
{
uiLayout *layout = op->layout;
@@ -2080,7 +2084,7 @@ static int object_curves_empty_hair_add_exec(bContext *C, wmOperator *op)
Object *curves_ob = ED_object_add_type(
C, OB_CURVES, nullptr, nullptr, nullptr, false, local_view_bits);
- BKE_object_apply_mat4(curves_ob, surface_ob->obmat, false, false);
+ BKE_object_apply_mat4(curves_ob, surface_ob->object_to_world, false, false);
/* Set surface object. */
Curves *curves_id = static_cast<Curves *>(curves_ob->data);
@@ -2534,6 +2538,7 @@ static void make_object_duplilist_real(bContext *C,
}
BKE_collection_object_add_from(bmain, scene, base->object, ob_dst);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base_dst = BKE_view_layer_base_find(view_layer, ob_dst);
BLI_assert(base_dst != nullptr);
@@ -2556,8 +2561,8 @@ static void make_object_duplilist_real(bContext *C,
id_us_min((ID *)ob_dst->instance_collection);
ob_dst->instance_collection = nullptr;
- copy_m4_m4(ob_dst->obmat, dob->mat);
- BKE_object_apply_mat4(ob_dst, ob_dst->obmat, false, false);
+ copy_m4_m4(ob_dst->object_to_world, dob->mat);
+ BKE_object_apply_mat4(ob_dst, ob_dst->object_to_world, false, false);
BLI_ghash_insert(dupli_gh, dob, ob_dst);
if (parent_gh) {
@@ -2831,6 +2836,7 @@ static Base *duplibase_for_convert(
DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
BKE_collection_object_add_from(bmain, scene, ob, obn);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *basen = BKE_view_layer_base_find(view_layer, obn);
ED_object_base_select(basen, BA_SELECT);
ED_object_base_select(base, BA_DESELECT);
@@ -3011,7 +3017,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0;
float loc[3], size[3], rot[3][3], eul[3];
float matrix[4][4];
- mat4_to_loc_rot_size(loc, rot, size, ob->obmat);
+ mat4_to_loc_rot_size(loc, rot, size, ob->object_to_world);
mat3_to_eul(eul, rot);
Object *ob_gpencil = ED_gpencil_add_object(C, loc, local_view_bits);
@@ -3301,7 +3307,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
baseob = BKE_mball_basis_find(scene, ob);
if (ob != baseob) {
- /* if motherball is converting it would be marked as done later */
+ /* If mother-ball is converting it would be marked as done later. */
ob->flag |= OB_DONE;
}
@@ -3443,9 +3449,13 @@ static int object_convert_exec(bContext *C, wmOperator *op)
ED_object_base_activate(C, basact);
view_layer->basact = basact;
}
- else if (view_layer->basact->object->flag & OB_DONE) {
- WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, view_layer->basact->object);
- WM_event_add_notifier(C, NC_OBJECT | ND_DATA, view_layer->basact->object);
+ else {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *object = BKE_view_layer_active_object_get(view_layer);
+ if (object->flag & OB_DONE) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, object);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DATA, object);
+ }
}
DEG_relations_tag_update(bmain);
@@ -3457,7 +3467,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static void object_convert_ui(bContext *UNUSED(C), wmOperator *op)
+static void object_convert_ui(bContext * /*C*/, wmOperator *op)
{
uiLayout *layout = op->layout;
@@ -3500,11 +3510,12 @@ void OBJECT_OT_convert(wmOperatorType *ot)
/* properties */
ot->prop = RNA_def_enum(
ot->srna, "target", convert_target_items, OB_MESH, "Target", "Type of object to convert to");
- RNA_def_boolean(ot->srna,
- "keep_original",
- false,
- "Keep Original",
- "Keep original objects instead of replacing them");
+ prop = RNA_def_boolean(ot->srna,
+ "keep_original",
+ false,
+ "Keep Original",
+ "Keep original objects instead of replacing them");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_OBJECT);
RNA_def_boolean(
ot->srna,
@@ -3545,11 +3556,62 @@ void OBJECT_OT_convert(wmOperatorType *ot)
/** \name Duplicate Object Operator
* \{ */
+static void object_add_sync_base_collection(
+ Main *bmain, Scene *scene, ViewLayer *view_layer, Base *base_src, Object *object_new)
+{
+ if ((base_src != nullptr) && (base_src->flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT)) {
+ BKE_collection_object_add_from(bmain, scene, base_src->object, object_new);
+ }
+ else {
+ LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer);
+ BKE_collection_object_add(bmain, layer_collection->collection, object_new);
+ }
+}
+
+static void object_add_sync_local_view(Base *base_src, Base *base_new)
+{
+ base_new->local_view_bits = base_src->local_view_bits;
+}
+
+static void object_add_sync_rigid_body(Main *bmain, Object *object_src, Object *object_new)
+{
+ /* 1) duplis should end up in same collection as the original
+ * 2) Rigid Body sim participants MUST always be part of a collection...
+ */
+ /* XXX: is 2) really a good measure here? */
+ if (object_src->rigidbody_object || object_src->rigidbody_constraint) {
+ LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
+ if (BKE_collection_has_object(collection, object_src)) {
+ BKE_collection_object_add(bmain, collection, object_new);
+ }
+ }
+ }
+}
+
/**
* - Assumes `id.new` is correct.
* - Leaves selection of base/object unaltered.
* - Sets #ID.newid pointers.
*/
+static void object_add_duplicate_internal(Main *bmain,
+ Object *ob,
+ const eDupli_ID_Flags dupflag,
+ const eLibIDDuplicateFlags duplicate_options,
+ Object **r_ob_new)
+{
+ if (ob->mode & OB_MODE_POSE) {
+ return;
+ }
+
+ Object *obn = static_cast<Object *>(
+ ID_NEW_SET(ob, BKE_object_duplicate(bmain, ob, dupflag, duplicate_options)));
+ if (r_ob_new) {
+ *r_ob_new = obn;
+ }
+ DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+ return;
+}
+
static Base *object_add_duplicate_internal(Main *bmain,
Scene *scene,
ViewLayer *view_layer,
@@ -3558,47 +3620,25 @@ static Base *object_add_duplicate_internal(Main *bmain,
const eLibIDDuplicateFlags duplicate_options,
Object **r_ob_new)
{
- Base *base, *basen = nullptr;
- Object *obn;
-
- if (ob->mode & OB_MODE_POSE) {
- /* nothing? */
+ Object *object_new = nullptr;
+ object_add_duplicate_internal(bmain, ob, dupflag, duplicate_options, &object_new);
+ if (r_ob_new) {
+ *r_ob_new = object_new;
+ }
+ if (object_new == nullptr) {
+ return nullptr;
}
- else {
- obn = static_cast<Object *>(
- ID_NEW_SET(ob, BKE_object_duplicate(bmain, ob, dupflag, duplicate_options)));
- if (r_ob_new) {
- *r_ob_new = obn;
- }
- DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
-
- base = BKE_view_layer_base_find(view_layer, ob);
- if ((base != nullptr) && (base->flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT)) {
- BKE_collection_object_add_from(bmain, scene, ob, obn);
- }
- else {
- LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer);
- BKE_collection_object_add(bmain, layer_collection->collection, obn);
- }
-
- basen = BKE_view_layer_base_find(view_layer, obn);
- if (base != nullptr && basen != nullptr) {
- basen->local_view_bits = base->local_view_bits;
- }
- /* 1) duplis should end up in same collection as the original
- * 2) Rigid Body sim participants MUST always be part of a collection...
- */
- /* XXX: is 2) really a good measure here? */
- if (ob->rigidbody_object || ob->rigidbody_constraint) {
- LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
- if (BKE_collection_has_object(collection, ob)) {
- BKE_collection_object_add(bmain, collection, obn);
- }
- }
- }
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base_src = BKE_view_layer_base_find(view_layer, ob);
+ object_add_sync_base_collection(bmain, scene, view_layer, base_src, object_new);
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base_new = BKE_view_layer_base_find(view_layer, object_new);
+ if (base_src && base_new) {
+ object_add_sync_local_view(base_src, base_new);
}
- return basen;
+ object_add_sync_rigid_body(bmain, ob, object_new);
+ return base_new;
}
Base *ED_object_add_duplicate(
@@ -3652,68 +3692,70 @@ static int duplicate_exec(bContext *C, wmOperator *op)
* we also want to remap pointers between those... */
BKE_main_id_newptr_and_tag_clear(bmain);
- /* Do not do collection re-syncs for each object; will do it once afterwards.
- * However this means we can't get to new duplicated Base's immediately, will
- * have to process them after the sync. */
- BKE_layer_collection_resync_forbid();
-
/* Duplicate the selected objects, remember data needed to process
- * after the sync (the base of the original object, and the copy of the
- * original object). */
- blender::Vector<std::pair<Base *, Object *>> source_bases_new_objects;
- Object *ob_new_active = nullptr;
+ * after the sync. */
+ struct DuplicateObjectLink {
+ Base *base_src = nullptr;
+ Object *object_new = nullptr;
+
+ DuplicateObjectLink(Base *base_src) : base_src(base_src)
+ {
+ }
+ };
+ blender::Vector<DuplicateObjectLink> object_base_links;
CTX_DATA_BEGIN (C, Base *, base, selected_bases) {
- Object *ob_new = nullptr;
+ object_base_links.append(DuplicateObjectLink(base));
+ }
+ CTX_DATA_END;
+
+ bool new_objects_created = false;
+ for (DuplicateObjectLink &link : object_base_links) {
object_add_duplicate_internal(bmain,
- scene,
- view_layer,
- base->object,
+ link.base_src->object,
dupflag,
LIB_ID_DUPLICATE_IS_SUBPROCESS | LIB_ID_DUPLICATE_IS_ROOT_ID,
- &ob_new);
- if (ob_new == nullptr) {
- continue;
- }
- source_bases_new_objects.append({base, ob_new});
-
- /* note that this is safe to do with this context iterator,
- * the list is made in advance */
- ED_object_base_select(base, BA_DESELECT);
-
- /* new object will become active */
- if (view_layer->basact == base) {
- ob_new_active = ob_new;
+ &link.object_new);
+ if (link.object_new) {
+ new_objects_created = true;
}
}
- CTX_DATA_END;
- BKE_layer_collection_resync_allow();
- if (source_bases_new_objects.is_empty()) {
+ if (!new_objects_created) {
return OPERATOR_CANCELLED;
}
- /* Sync the collection now, after everything is duplicated. */
- BKE_main_collection_sync(bmain);
+ /* Sync that could tag the view_layer out of sync. */
+ for (DuplicateObjectLink &link : object_base_links) {
+ /* note that this is safe to do with this context iterator,
+ * the list is made in advance */
+ ED_object_base_select(link.base_src, BA_DESELECT);
+ if (link.object_new) {
+ object_add_sync_base_collection(bmain, scene, view_layer, link.base_src, link.object_new);
+ object_add_sync_rigid_body(bmain, link.base_src->object, link.object_new);
+ }
+ }
- /* After sync we can get to the new Base data, process it here. */
- for (const auto &item : source_bases_new_objects) {
- Object *ob_new = item.second;
- Base *base_source = item.first;
- Base *base_new = BKE_view_layer_base_find(view_layer, ob_new);
- if (base_new == nullptr) {
+ /* Sync the view layer. Everything else should not tag the view_layer out of sync. */
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ const Base *active_base = BKE_view_layer_active_base_get(view_layer);
+ for (DuplicateObjectLink &link : object_base_links) {
+ if (!link.object_new) {
continue;
}
+
+ Base *base_new = BKE_view_layer_base_find(view_layer, link.object_new);
+ BLI_assert(base_new);
ED_object_base_select(base_new, BA_SELECT);
- if (ob_new == ob_new_active) {
+ if (active_base == link.base_src) {
ED_object_base_activate(C, base_new);
}
- if (base_new->object->data) {
- DEG_id_tag_update(static_cast<ID *>(base_new->object->data), 0);
+
+ if (link.object_new->data) {
+ DEG_id_tag_update(static_cast<ID *>(link.object_new->data), 0);
}
- /* #object_add_duplicate_internal will not have done this, since
- * before the collection sync it would not have found the new base yet. */
- base_new->local_view_bits = base_source->local_view_bits;
+
+ object_add_sync_local_view(link.base_src, base_new);
}
/* Note that this will also clear newid pointers and tags. */
@@ -3811,7 +3853,7 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
/* object_add_duplicate_internal() doesn't deselect other objects, unlike object_add_common() or
* BKE_view_layer_base_deselect_all(). */
- ED_object_base_deselect_all(view_layer, nullptr, SEL_DESELECT);
+ ED_object_base_deselect_all(scene, view_layer, nullptr, SEL_DESELECT);
ED_object_base_select(basen, BA_SELECT);
ED_object_base_activate(C, basen);
@@ -3829,8 +3871,8 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
PropertyRNA *prop_matrix = RNA_struct_find_property(op->ptr, "matrix");
if (RNA_property_is_set(op->ptr, prop_matrix)) {
Object *ob_add = basen->object;
- RNA_property_float_get_array(op->ptr, prop_matrix, &ob_add->obmat[0][0]);
- BKE_object_apply_mat4(ob_add, ob_add->obmat, true, true);
+ RNA_property_float_get_array(op->ptr, prop_matrix, &ob_add->object_to_world[0][0]);
+ BKE_object_apply_mat4(ob_add, ob_add->object_to_world, true, true);
DEG_id_tag_update(&ob_add->id, ID_RECALC_TRANSFORM);
}
@@ -3888,12 +3930,14 @@ void OBJECT_OT_add_named(wmOperatorType *ot)
static int object_transform_to_mouse_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = reinterpret_cast<Object *>(
WM_operator_properties_id_lookup_from_name_or_session_uuid(bmain, op->ptr, ID_OB));
if (!ob) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
ob = BKE_view_layer_active_object_get(view_layer);
}
@@ -3925,7 +3969,7 @@ static int object_transform_to_mouse_exec(bContext *C, wmOperator *op)
float mat_dst_unit[4][4];
float final_delta[4][4];
- normalize_m4_m4(mat_src_unit, ob->obmat);
+ normalize_m4_m4(mat_src_unit, ob->object_to_world);
normalize_m4_m4(mat_dst_unit, matrix);
invert_m4(mat_src_unit);
mul_m4_m4m4(final_delta, mat_dst_unit, mat_src_unit);
@@ -4080,7 +4124,7 @@ static int object_join_exec(bContext *C, wmOperator *op)
* If the zero scale is removed, the data on this axis remains un-scaled
* (something that wouldn't work for #invert_m4_m4_safe). */
float imat_test[4][4];
- if (!invert_m4_m4(imat_test, ob->obmat)) {
+ if (!invert_m4_m4(imat_test, ob->object_to_world)) {
BKE_report(op->reports,
RPT_WARNING,
"Active object final transform has one or more zero scaled axes");
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index 8d505bbca3e..91641de1605 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -191,7 +191,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op)
ok = false;
}
- if (ibuf->rect_float && !(ELEM(ibuf->channels, 0, 4))) {
+ if (ibuf->rect_float && !ELEM(ibuf->channels, 0, 4)) {
ok = false;
}
@@ -461,7 +461,7 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj)
CTX_DATA_END;
}
-static void multiresbake_startjob(void *bkv, short *stop, short *do_update, float *progress)
+static void multiresbake_startjob(void *bkv, bool *stop, bool *do_update, float *progress)
{
MultiresBakerJobData *data;
MultiresBakeJob *bkj = bkv;
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index f7b66241081..e69ccf5a50d 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -106,7 +106,7 @@ typedef struct BakeAPIRender {
/* Progress Callbacks. */
float *progress;
- short *do_update;
+ bool *do_update;
/* Operator state. */
ReportList *reports;
@@ -150,12 +150,12 @@ static int bake_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
* for exec() when there is no render job
* NOTE: this won't check for the escape key being pressed, but doing so isn't thread-safe.
*/
-static int bake_break(void *UNUSED(rjv))
+static bool bake_break(void *UNUSED(rjv))
{
if (G.is_break) {
- return 1;
+ return true;
}
- return 0;
+ return false;
}
static void bake_update_image(ScrArea *area, Image *image)
@@ -419,11 +419,13 @@ static bool is_noncolor_pass(eScenePassType pass_type)
}
/* if all is good tag image and return true */
-static bool bake_object_check(ViewLayer *view_layer,
+static bool bake_object_check(const Scene *scene,
+ ViewLayer *view_layer,
Object *ob,
const eBakeTarget target,
ReportList *reports)
{
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob);
if (base == NULL) {
@@ -465,8 +467,8 @@ static bool bake_object_check(ViewLayer *view_layer,
}
for (int i = 0; i < ob->totcol; i++) {
- bNodeTree *ntree = NULL;
- bNode *node = NULL;
+ const bNodeTree *ntree = NULL;
+ const bNode *node = NULL;
const int mat_nr = i + 1;
Image *image;
ED_object_get_active_image(ob, mat_nr, &image, NULL, &node, &ntree);
@@ -591,6 +593,7 @@ static bool bake_pass_filter_check(eScenePassType pass_type,
/* before even getting in the bake function we check for some basic errors */
static bool bake_objects_check(Main *bmain,
+ const Scene *scene,
ViewLayer *view_layer,
Object *ob,
ListBase *selected_objects,
@@ -606,7 +609,7 @@ static bool bake_objects_check(Main *bmain,
if (is_selected_to_active) {
int tot_objects = 0;
- if (!bake_object_check(view_layer, ob, target, reports)) {
+ if (!bake_object_check(scene, view_layer, ob, target, reports)) {
return false;
}
@@ -640,7 +643,7 @@ static bool bake_objects_check(Main *bmain,
}
for (link = selected_objects->first; link; link = link->next) {
- if (!bake_object_check(view_layer, link->ptr.data, target, reports)) {
+ if (!bake_object_check(scene, view_layer, link->ptr.data, target, reports)) {
return false;
}
}
@@ -890,7 +893,7 @@ static bool bake_targets_output_external(const BakeAPIRender *bkr,
else {
/* if everything else fails, use the material index */
char tmp[5];
- sprintf(tmp, "%d", i % 1000);
+ BLI_snprintf(tmp, sizeof(tmp), "%d", i % 1000);
BLI_path_suffix(name, FILE_MAX, tmp, "_");
}
}
@@ -1044,8 +1047,8 @@ static void bake_targets_populate_pixels_color_attributes(BakeTargets *targets,
const MLoopTri *lt = &looptri[i];
for (int j = 0; j < 3; j++) {
- unsigned int l = lt->tri[j];
- unsigned int v = loops[l].v;
+ uint l = lt->tri[j];
+ uint v = loops[l].v;
/* Map back to original loop if there are modifiers. */
if (vert_origindex != NULL && poly_origindex != NULL) {
@@ -1515,10 +1518,10 @@ static int bake(const BakeAPIRender *bkr,
highpoly[i].me = BKE_mesh_new_from_object(NULL, highpoly[i].ob_eval, false, false);
/* Low-poly to high-poly transformation matrix. */
- copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->obmat);
+ copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->object_to_world);
invert_m4_m4(highpoly[i].imat, highpoly[i].obmat);
- highpoly[i].is_flip_object = is_negative_m4(highpoly[i].ob->obmat);
+ highpoly[i].is_flip_object = is_negative_m4(highpoly[i].ob->object_to_world);
i++;
}
@@ -1537,18 +1540,19 @@ static int bake(const BakeAPIRender *bkr,
pixel_array_high = MEM_mallocN(sizeof(BakePixel) * targets.pixels_num,
"bake pixels high poly");
- if (!RE_bake_pixels_populate_from_objects(me_low_eval,
- pixel_array_low,
- pixel_array_high,
- highpoly,
- tot_highpoly,
- targets.pixels_num,
- ob_cage != NULL,
- bkr->cage_extrusion,
- bkr->max_ray_distance,
- ob_low_eval->obmat,
- (ob_cage ? ob_cage->obmat : ob_low_eval->obmat),
- me_cage_eval)) {
+ if (!RE_bake_pixels_populate_from_objects(
+ me_low_eval,
+ pixel_array_low,
+ pixel_array_high,
+ highpoly,
+ tot_highpoly,
+ targets.pixels_num,
+ ob_cage != NULL,
+ bkr->cage_extrusion,
+ bkr->max_ray_distance,
+ ob_low_eval->object_to_world,
+ (ob_cage ? ob_cage->object_to_world : ob_low_eval->object_to_world),
+ me_cage_eval)) {
BKE_report(reports, RPT_ERROR, "Error handling selected objects");
goto cleanup;
}
@@ -1626,7 +1630,7 @@ static int bake(const BakeAPIRender *bkr,
targets.result,
me_low_eval,
bkr->normal_swizzle,
- ob_low_eval->obmat);
+ ob_low_eval->object_to_world);
}
else {
/* From multi-resolution. */
@@ -1652,7 +1656,7 @@ static int bake(const BakeAPIRender *bkr,
targets.result,
(me_nores) ? me_nores : me_low_eval,
bkr->normal_swizzle,
- ob_low_eval->obmat);
+ ob_low_eval->object_to_world);
if (md) {
BKE_id_free(NULL, &me_nores->id);
@@ -1812,6 +1816,7 @@ static int bake_exec(bContext *C, wmOperator *op)
}
if (!bake_objects_check(bkr.main,
+ bkr.scene,
bkr.view_layer,
bkr.ob,
&bkr.selected_objects,
@@ -1849,7 +1854,7 @@ finally:
return result;
}
-static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, float *progress)
+static void bake_startjob(void *bkv, bool *UNUSED(stop), bool *do_update, float *progress)
{
BakeAPIRender *bkr = (BakeAPIRender *)bkv;
@@ -1865,6 +1870,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa
}
if (!bake_objects_check(bkr->main,
+ bkr->scene,
bkr->view_layer,
bkr->ob,
&bkr->selected_objects,
diff --git a/source/blender/editors/object/object_collection.c b/source/blender/editors/object/object_collection.c
index 426f33e53ca..53e1a75cba0 100644
--- a/source/blender/editors/object/object_collection.c
+++ b/source/blender/editors/object/object_collection.c
@@ -203,6 +203,7 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
int single_collection_index = RNA_enum_get(op->ptr, "collection");
Collection *single_collection = collection_object_active_find_index(
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 28ba2b04b6f..cbed01442ee 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -31,6 +31,7 @@
#include "BKE_constraint.h"
#include "BKE_context.h"
#include "BKE_fcurve.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_report.h"
@@ -113,7 +114,7 @@ ListBase *ED_object_constraint_list_from_constraint(Object *ob,
}
/* try object constraints first */
- if ((BLI_findindex(&ob->constraints, con) != -1)) {
+ if (BLI_findindex(&ob->constraints, con) != -1) {
return &ob->constraints;
}
@@ -125,7 +126,7 @@ ListBase *ED_object_constraint_list_from_constraint(Object *ob,
* NOTE: it's not possible to directly look up the active bone yet, so this will have to do
*/
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- if ((BLI_findindex(&pchan->constraints, con) != -1)) {
+ if (BLI_findindex(&pchan->constraints, con) != -1) {
if (r_pchan) {
*r_pchan = pchan;
@@ -181,7 +182,7 @@ static char *buildmenu_pyconstraints(Main *bmain, Text *con_text, int *pyconinde
int i;
/* add title first */
- sprintf(buf, "Scripts: %%t|[None]%%x0|");
+ BLI_snprintf(buf, sizeof(buf), "Scripts: %%t|[None]%%x0|");
BLI_dynstr_append(pupds, buf);
/* init active-index first */
@@ -200,7 +201,7 @@ static char *buildmenu_pyconstraints(Main *bmain, Text *con_text, int *pyconinde
if (BPY_is_pyconstraint(text)) {
BLI_dynstr_append(pupds, text->id.name + 2);
- sprintf(buf, "%%x%d", i);
+ BLI_snprintf(buf, sizeof(buf), "%%x%d", i);
BLI_dynstr_append(pupds, buf);
if (text->id.next) {
@@ -296,10 +297,9 @@ static void test_constraint(
if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
bKinematicConstraint *data = con->data;
- /* bad: we need a separate set of checks here as poletarget is
- * optional... otherwise poletarget must exist too or else
- * the constraint is deemed invalid
- */
+ /* Bad: we need a separate set of checks here as pole-target is optional...
+ * otherwise pole-target must exist too or else the constraint is deemed invalid. */
+
/* default IK check ... */
if (BKE_object_exists_check(bmain, data->tar) == 0) {
data->tar = NULL;
@@ -2313,26 +2313,28 @@ static bool get_new_constraint_target(
/* if still not found, add a new empty to act as a target (if allowed) */
if ((found == false) && (add)) {
Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base = BKE_view_layer_active_base_get(view_layer);
Object *obt;
/* add new target object */
- obt = BKE_object_add(bmain, view_layer, OB_EMPTY, NULL);
+ obt = BKE_object_add(bmain, scene, view_layer, OB_EMPTY, NULL);
/* transform cent to global coords for loc */
if (pchanact) {
/* Since by default, IK targets the tip of the last bone,
* use the tip of the active PoseChannel if adding a target for an IK Constraint. */
if (con_type == CONSTRAINT_TYPE_KINEMATIC) {
- mul_v3_m4v3(obt->loc, obact->obmat, pchanact->pose_tail);
+ mul_v3_m4v3(obt->loc, obact->object_to_world, pchanact->pose_tail);
}
else {
- mul_v3_m4v3(obt->loc, obact->obmat, pchanact->pose_head);
+ mul_v3_m4v3(obt->loc, obact->object_to_world, pchanact->pose_head);
}
}
else {
- copy_v3_v3(obt->loc, obact->obmat[3]);
+ copy_v3_v3(obt->loc, obact->object_to_world[3]);
}
/* restore, BKE_object_add sets active */
diff --git a/source/blender/editors/object/object_data_transform.c b/source/blender/editors/object/object_data_transform.c
index 63513eac965..cb66010c497 100644
--- a/source/blender/editors/object/object_data_transform.c
+++ b/source/blender/editors/object/object_data_transform.c
@@ -7,7 +7,7 @@
* Use to transform object origins only.
*
* This is a small API to store & apply transformations to object data,
- * where a transformation matrix can be continually applied ontop of the original values
+ * where a transformation matrix can be continually applied on top of the original values
* so we don't lose precision over time.
*/
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index cc16b58fa72..2e22e3bb00d 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -140,7 +140,9 @@ Object **ED_object_array_in_mode_or_selected(bContext *C,
uint *r_objects_len)
{
ScrArea *area = CTX_wm_area(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob_active = BKE_view_layer_active_object_get(view_layer);
ID *id_pin = NULL;
const bool use_objects_in_mode = (ob_active != NULL) &&
@@ -200,7 +202,7 @@ Object **ED_object_array_in_mode_or_selected(bContext *C,
params.filter_fn = filter_fn;
params.filter_userdata = filter_user_data;
objects = BKE_view_layer_array_from_objects_in_mode_params(
- view_layer, v3d, r_objects_len, &params);
+ scene, view_layer, v3d, r_objects_len, &params);
}
else {
objects = BKE_view_layer_array_selected_objects(
@@ -234,7 +236,8 @@ static int object_hide_view_clear_exec(bContext *C, wmOperator *op)
const bool select = RNA_boolean_get(op->ptr, "select");
bool changed = false;
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (base->flag & BASE_HIDDEN) {
base->flag &= ~BASE_HIDDEN;
changed = true;
@@ -252,7 +255,7 @@ static int object_hide_view_clear_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BKE_layer_collection_sync(scene, view_layer);
+ BKE_view_layer_need_resync_tag(view_layer);
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
WM_event_add_notifier(C, NC_SCENE | ND_OB_VISIBLE, scene);
@@ -286,7 +289,8 @@ static int object_hide_view_set_exec(bContext *C, wmOperator *op)
bool changed = false;
/* Hide selected or unselected objects. */
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (!(base->flag & BASE_ENABLED_AND_VISIBLE_IN_DEFAULT_VIEWPORT)) {
continue;
}
@@ -310,7 +314,7 @@ static int object_hide_view_set_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BKE_layer_collection_sync(scene, view_layer);
+ BKE_view_layer_need_resync_tag(view_layer);
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
WM_event_add_notifier(C, NC_SCENE | ND_OB_VISIBLE, scene);
@@ -362,10 +366,10 @@ static int object_hide_collection_exec(bContext *C, wmOperator *op)
}
if (toggle) {
lc->local_collections_bits ^= v3d->local_collections_uuid;
- BKE_layer_collection_local_sync(view_layer, v3d);
+ BKE_layer_collection_local_sync(scene, view_layer, v3d);
}
else {
- BKE_layer_collection_isolate_local(view_layer, v3d, lc, extend);
+ BKE_layer_collection_isolate_local(scene, view_layer, v3d, lc, extend);
}
}
else {
@@ -381,6 +385,7 @@ static int object_hide_collection_exec(bContext *C, wmOperator *op)
void ED_collection_hide_menu_draw(const bContext *C, uiLayout *layout)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
LayerCollection *lc_scene = view_layer->layer_collections.first;
@@ -399,7 +404,7 @@ void ED_collection_hide_menu_draw(const bContext *C, uiLayout *layout)
}
int icon = ICON_NONE;
- if (BKE_layer_collection_has_selected_objects(view_layer, lc)) {
+ if (BKE_layer_collection_has_selected_objects(scene, view_layer, lc)) {
icon = ICON_LAYER_ACTIVE;
}
else if (lc->runtime_flag & LAYER_COLLECTION_HAS_OBJECTS) {
@@ -701,6 +706,7 @@ bool ED_object_editmode_free_ex(Main *bmain, Object *obedit)
bool ED_object_editmode_exit_multi_ex(Main *bmain, Scene *scene, ViewLayer *view_layer, int flag)
{
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
if (obedit == NULL) {
return false;
@@ -708,7 +714,8 @@ bool ED_object_editmode_exit_multi_ex(Main *bmain, Scene *scene, ViewLayer *view
bool changed = false;
const short obedit_type = obedit->type;
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *ob = base->object;
if ((ob->type == obedit_type) && (ob->mode & OB_MODE_EDIT)) {
changed |= ED_object_editmode_exit_ex(bmain, scene, base->object, flag);
@@ -841,6 +848,7 @@ static int editmode_toggle_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obact = BKE_view_layer_active_object_get(view_layer);
const int mode_flag = OB_MODE_EDIT;
const bool is_mode_set = (obact->mode & mode_flag) != 0;
@@ -867,7 +875,7 @@ static int editmode_toggle_exec(bContext *C, wmOperator *op)
ED_object_editmode_exit_ex(bmain, scene, obact, EM_FREEDATA);
if ((obact->mode & mode_flag) == 0) {
- FOREACH_OBJECT_BEGIN (view_layer, ob) {
+ FOREACH_OBJECT_BEGIN (scene, view_layer, ob) {
if ((ob != obact) && (ob->type == obact->type)) {
ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA);
}
@@ -953,6 +961,7 @@ static int posemode_exec(bContext *C, wmOperator *op)
}
{
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
if (obact == obedit) {
ED_object_editmode_exit_ex(bmain, scene, obedit, EM_FREEDATA);
@@ -963,7 +972,7 @@ static int posemode_exec(bContext *C, wmOperator *op)
if (is_mode_set) {
bool ok = ED_object_posemode_exit(C, obact);
if (ok) {
- FOREACH_OBJECT_BEGIN (view_layer, ob) {
+ FOREACH_OBJECT_BEGIN (scene, view_layer, ob) {
if ((ob != obact) && (ob->type == OB_ARMATURE) && (ob->mode & mode_flag)) {
ED_object_posemode_exit_ex(bmain, ob);
}
@@ -1477,9 +1486,11 @@ static int shade_smooth_exec(bContext *C, wmOperator *op)
/* For modes that only use an active object, don't handle the whole selection. */
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obact = BKE_view_layer_active_object_get(view_layer);
- if (obact && ((obact->mode & OB_MODE_ALL_PAINT))) {
+ if (obact && (obact->mode & OB_MODE_ALL_PAINT)) {
ctx_ob_single_active.ptr.data = obact;
BLI_addtail(&ctx_objects, &ctx_ob_single_active);
}
@@ -1550,7 +1561,9 @@ static int shade_smooth_exec(bContext *C, wmOperator *op)
static bool shade_poll(bContext *C)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obact = BKE_view_layer_active_object_get(view_layer);
if (obact != NULL) {
/* Doesn't handle edit-data, sculpt dynamic-topology, or their undo systems. */
diff --git a/source/blender/editors/object/object_gpencil_modifier.c b/source/blender/editors/object/object_gpencil_modifier.c
index 42ac6d166b4..e85947534cd 100644
--- a/source/blender/editors/object/object_gpencil_modifier.c
+++ b/source/blender/editors/object/object_gpencil_modifier.c
@@ -934,6 +934,242 @@ void OBJECT_OT_gpencil_modifier_copy_to_selected(wmOperatorType *ot)
gpencil_edit_modifier_properties(ot);
}
+/************************* Time Offset Advanced Modifier *******************************/
+
+static bool time_segment_poll(bContext *C)
+{
+ return gpencil_edit_modifier_poll_generic(C, &RNA_TimeGpencilModifier, 0, false);
+}
+
+static bool time_segment_name_exists_fn(void *arg, const char *name)
+{
+ const TimeGpencilModifierData *gpmd = (const TimeGpencilModifierData *)arg;
+ for (int i = 0; i < gpmd->segments_len; i++) {
+ if (STREQ(gpmd->segments[i].name, name) && gpmd->segments[i].name != name) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static int time_segment_add_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_active_context(C);
+ TimeGpencilModifierData *gpmd = (TimeGpencilModifierData *)gpencil_edit_modifier_property_get(
+ op, ob, eGpencilModifierType_Time);
+ if (gpmd == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+ const int new_active_index = gpmd->segment_active_index + 1;
+ TimeGpencilModifierSegment *new_segments = MEM_malloc_arrayN(
+ gpmd->segments_len + 1, sizeof(TimeGpencilModifierSegment), __func__);
+
+ if (gpmd->segments_len != 0) {
+ /* Copy the segments before the new segment. */
+ memcpy(new_segments, gpmd->segments, sizeof(TimeGpencilModifierSegment) * new_active_index);
+ /* Copy the segments after the new segment. */
+ memcpy(new_segments + new_active_index + 1,
+ gpmd->segments + new_active_index,
+ sizeof(TimeGpencilModifierSegment) * (gpmd->segments_len - new_active_index));
+ }
+
+ /* Create the new segment. */
+ TimeGpencilModifierSegment *ds = &new_segments[new_active_index];
+ memcpy(
+ ds, DNA_struct_default_get(TimeGpencilModifierSegment), sizeof(TimeGpencilModifierSegment));
+ BLI_uniquename_cb(
+ time_segment_name_exists_fn, gpmd, DATA_("Segment"), '.', ds->name, sizeof(ds->name));
+ ds->gpmd = gpmd;
+
+ MEM_SAFE_FREE(gpmd->segments);
+ gpmd->segments = new_segments;
+ gpmd->segments_len++;
+ gpmd->segment_active_index++;
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int time_segment_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ if (gpencil_edit_modifier_invoke_properties(C, op, NULL, NULL)) {
+ return time_segment_add_exec(C, op);
+ }
+ return OPERATOR_CANCELLED;
+}
+
+void GPENCIL_OT_time_segment_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add Segment";
+ ot->description = "Add a segment to the time modifier";
+ ot->idname = "GPENCIL_OT_time_segment_add";
+
+ /* api callbacks */
+ ot->poll = time_segment_poll;
+ ot->invoke = time_segment_add_invoke;
+ ot->exec = time_segment_add_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ edit_modifier_properties(ot);
+}
+
+static int time_segment_remove_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_active_context(C);
+
+ TimeGpencilModifierData *gpmd = (TimeGpencilModifierData *)gpencil_edit_modifier_property_get(
+ op, ob, eGpencilModifierType_Time);
+
+ if (gpmd->segment_active_index < 0 || gpmd->segment_active_index >= gpmd->segments_len) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if (gpmd->segments_len == 1) {
+ MEM_SAFE_FREE(gpmd->segments);
+ gpmd->segment_active_index = -1;
+ }
+ else {
+ TimeGpencilModifierSegment *new_segments = MEM_malloc_arrayN(
+ gpmd->segments_len, sizeof(TimeGpencilModifierSegment), __func__);
+
+ /* Copy the segments before the deleted segment. */
+ memcpy(new_segments,
+ gpmd->segments,
+ sizeof(TimeGpencilModifierSegment) * gpmd->segment_active_index);
+
+ /* Copy the segments after the deleted segment. */
+ memcpy(new_segments + gpmd->segment_active_index,
+ gpmd->segments + gpmd->segment_active_index + 1,
+ sizeof(TimeGpencilModifierSegment) *
+ (gpmd->segments_len - gpmd->segment_active_index - 1));
+
+ MEM_freeN(gpmd->segments);
+ gpmd->segments = new_segments;
+ gpmd->segment_active_index = MAX2(gpmd->segment_active_index - 1, 0);
+ }
+
+ gpmd->segments_len--;
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int time_segment_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ if (gpencil_edit_modifier_invoke_properties(C, op, NULL, NULL)) {
+ return time_segment_remove_exec(C, op);
+ }
+ return OPERATOR_CANCELLED;
+}
+
+void GPENCIL_OT_time_segment_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Remove Time Segment";
+ ot->description = "Remove the active segment from the time modifier";
+ ot->idname = "GPENCIL_OT_time_segment_remove";
+
+ /* api callbacks */
+ ot->poll = time_segment_poll;
+ ot->invoke = time_segment_remove_invoke;
+ ot->exec = time_segment_remove_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ edit_modifier_properties(ot);
+
+ RNA_def_int(
+ ot->srna, "index", 0, 0, INT_MAX, "Index", "Index of the segment to remove", 0, INT_MAX);
+}
+
+enum {
+ GP_TIME_SEGEMENT_MOVE_UP = -1,
+ GP_TIME_SEGEMENT_MOVE_DOWN = 1,
+};
+
+static int time_segment_move_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_active_context(C);
+
+ TimeGpencilModifierData *gpmd = (TimeGpencilModifierData *)gpencil_edit_modifier_property_get(
+ op, ob, eGpencilModifierType_Time);
+
+ if (gpmd->segments_len < 2) {
+ return OPERATOR_CANCELLED;
+ }
+
+ const int direction = RNA_enum_get(op->ptr, "type");
+ if (direction == GP_TIME_SEGEMENT_MOVE_UP) {
+ if (gpmd->segment_active_index == 0) {
+ return OPERATOR_CANCELLED;
+ }
+
+ SWAP(TimeGpencilModifierSegment,
+ gpmd->segments[gpmd->segment_active_index],
+ gpmd->segments[gpmd->segment_active_index - 1]);
+
+ gpmd->segment_active_index--;
+ }
+ else if (direction == GP_TIME_SEGEMENT_MOVE_DOWN) {
+ if (gpmd->segment_active_index == gpmd->segments_len - 1) {
+ return OPERATOR_CANCELLED;
+ }
+
+ SWAP(TimeGpencilModifierSegment,
+ gpmd->segments[gpmd->segment_active_index],
+ gpmd->segments[gpmd->segment_active_index + 1]);
+
+ gpmd->segment_active_index++;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int time_segment_move_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ if (gpencil_edit_modifier_invoke_properties(C, op, NULL, NULL)) {
+ return time_segment_move_exec(C, op);
+ }
+ return OPERATOR_CANCELLED;
+}
+
+void GPENCIL_OT_time_segment_move(wmOperatorType *ot)
+{
+ static const EnumPropertyItem segment_move[] = {
+ {GP_TIME_SEGEMENT_MOVE_UP, "UP", 0, "Up", ""},
+ {GP_TIME_SEGEMENT_MOVE_DOWN, "DOWN", 0, "Down", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ /* identifiers */
+ ot->name = "Move Time Segment";
+ ot->description = "Move the active time segment up or down";
+ ot->idname = "GPENCIL_OT_time_segment_move";
+
+ /* api callbacks */
+ ot->poll = time_segment_poll;
+ ot->invoke = time_segment_move_invoke;
+ ot->exec = time_segment_move_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ edit_modifier_properties(ot);
+
+ ot->prop = RNA_def_enum(ot->srna, "type", segment_move, 0, "Type", "");
+}
+
/************************* Dash Modifier *******************************/
static bool dash_segment_poll(bContext *C)
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index b3f62f3fc0f..d52c7f0b8d4 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -484,22 +484,22 @@ static bool hook_op_edit_poll(bContext *C)
return false;
}
-static Object *add_hook_object_new(Main *bmain, ViewLayer *view_layer, View3D *v3d, Object *obedit)
+static Object *add_hook_object_new(
+ Main *bmain, Scene *scene, ViewLayer *view_layer, View3D *v3d, Object *obedit)
{
Base *basedit;
Object *ob;
-
- ob = BKE_object_add(bmain, view_layer, OB_EMPTY, NULL);
-
- basedit = BKE_view_layer_base_find(view_layer, obedit);
- BLI_assert(view_layer->basact->object == ob);
-
+ ob = BKE_object_add(bmain, scene, view_layer, OB_EMPTY, NULL);
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *basact = BKE_view_layer_active_base_get(view_layer);
+ BLI_assert(basact->object == ob);
if (v3d && v3d->localvd) {
- view_layer->basact->local_view_bits |= v3d->local_view_uuid;
+ basact->local_view_bits |= v3d->local_view_uuid;
}
/* icky, BKE_object_add sets new base as active.
* so set it back to the original edit object */
+ basedit = BKE_view_layer_base_find(view_layer, obedit);
view_layer->basact = basedit;
return ob;
@@ -532,10 +532,10 @@ static int add_hook_object(const bContext *C,
if (mode == OBJECT_ADDHOOK_NEWOB && !ob) {
- ob = add_hook_object_new(bmain, view_layer, v3d, obedit);
+ ob = add_hook_object_new(bmain, scene, view_layer, v3d, obedit);
/* transform cent to global coords for loc */
- mul_v3_m4v3(ob->loc, obedit->obmat, cent);
+ mul_v3_m4v3(ob->loc, obedit->object_to_world, cent);
}
md = obedit->modifiers.first;
@@ -556,13 +556,13 @@ static int add_hook_object(const bContext *C,
unit_m4(pose_mat);
- invert_m4_m4(obedit->imat, obedit->obmat);
+ invert_m4_m4(obedit->world_to_object, obedit->object_to_world);
if (mode == OBJECT_ADDHOOK_NEWOB) {
/* pass */
}
else {
/* may overwrite with pose-bone location, below */
- mul_v3_m4v3(cent, obedit->imat, ob->obmat[3]);
+ mul_v3_m4v3(cent, obedit->world_to_object, ob->object_to_world[3]);
}
if (mode == OBJECT_ADDHOOK_SELOB_BONE) {
@@ -576,8 +576,8 @@ static int add_hook_object(const bContext *C,
pchan_act = BKE_pose_channel_active_if_layer_visible(ob);
if (LIKELY(pchan_act)) {
invert_m4_m4(pose_mat, pchan_act->pose_mat);
- mul_v3_m4v3(cent, ob->obmat, pchan_act->pose_mat[3]);
- mul_v3_m4v3(cent, obedit->imat, cent);
+ mul_v3_m4v3(cent, ob->object_to_world, pchan_act->pose_mat[3]);
+ mul_v3_m4v3(cent, obedit->world_to_object, cent);
}
}
else {
@@ -588,16 +588,16 @@ static int add_hook_object(const bContext *C,
copy_v3_v3(hmd->cent, cent);
/* matrix calculus */
- /* vert x (obmat x hook->imat) x hook->obmat x ob->imat */
+ /* vert x (obmat x hook->world_to_object) x hook->object_to_world x ob->world_to_object */
/* (parentinv ) */
Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
BKE_object_transform_copy(object_eval, ob);
BKE_object_where_is_calc(depsgraph, scene_eval, object_eval);
- invert_m4_m4(object_eval->imat, object_eval->obmat);
+ invert_m4_m4(object_eval->world_to_object, object_eval->object_to_world);
/* apparently this call goes from right to left... */
- mul_m4_series(hmd->parentinv, pose_mat, object_eval->imat, obedit->obmat);
+ mul_m4_series(hmd->parentinv, pose_mat, object_eval->world_to_object, obedit->object_to_world);
DEG_relations_tag_update(bmain);
@@ -834,10 +834,10 @@ static int object_hook_recenter_exec(bContext *C, wmOperator *op)
}
/* recenter functionality */
- copy_m3_m4(bmat, ob->obmat);
+ copy_m3_m4(bmat, ob->object_to_world);
invert_m3_m3(imat, bmat);
- sub_v3_v3v3(hmd->cent, scene->cursor.location, ob->obmat[3]);
+ sub_v3_v3v3(hmd->cent, scene->cursor.location, ob->object_to_world[3]);
mul_m3_v3(imat, hmd->cent);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 63f010cd526..b136f311557 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -221,6 +221,10 @@ void GPENCIL_OT_segment_add(struct wmOperatorType *ot);
void GPENCIL_OT_segment_remove(struct wmOperatorType *ot);
void GPENCIL_OT_segment_move(struct wmOperatorType *ot);
+void GPENCIL_OT_time_segment_add(struct wmOperatorType *ot);
+void GPENCIL_OT_time_segment_remove(struct wmOperatorType *ot);
+void GPENCIL_OT_time_segment_move(struct wmOperatorType *ot);
+
/* object_shader_fx.c */
void OBJECT_OT_shaderfx_add(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_modes.c b/source/blender/editors/object/object_modes.c
index 27d8c326d41..6525f2d6027 100644
--- a/source/blender/editors/object/object_modes.c
+++ b/source/blender/editors/object/object_modes.c
@@ -190,7 +190,10 @@ bool ED_object_mode_compat_set(bContext *C, Object *ob, eObjectMode mode, Report
bool ED_object_mode_set_ex(bContext *C, eObjectMode mode, bool use_undo, ReportList *reports)
{
wmWindowManager *wm = CTX_wm_manager(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ob == NULL) {
return (mode == OB_MODE_OBJECT);
@@ -327,9 +330,11 @@ static void ed_object_posemode_set_for_weight_paint_ex(bContext *C,
const bool is_mode_set)
{
View3D *v3d = CTX_wm_view3d(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
if (ob_arm != NULL) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
const Base *base_arm = BKE_view_layer_base_find(view_layer, ob_arm);
if (base_arm && BASE_VISIBLE(v3d, base_arm)) {
if (is_mode_set) {
@@ -464,8 +469,9 @@ static bool object_transfer_mode_to_base(bContext *C, wmOperator *op, Base *base
if (ED_object_mode_set_ex(C, OB_MODE_OBJECT, true, op->reports)) {
Object *ob_dst_orig = DEG_get_original_object(ob_dst);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob_dst_orig);
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
BKE_view_layer_base_select_and_set_active(view_layer, base);
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc
index 2de33a3563a..67399717c72 100644
--- a/source/blender/editors/object/object_modifier.cc
+++ b/source/blender/editors/object/object_modifier.cc
@@ -21,6 +21,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_force_types.h"
+#include "DNA_pointcloud_types.h"
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
@@ -85,8 +86,6 @@
#include "ED_screen.h"
#include "ED_sculpt.h"
-#include "MOD_nodes.h"
-
#include "UI_interface.h"
#include "WM_api.h"
@@ -219,7 +218,7 @@ ModifierData *ED_object_modifier_add(
if (ob->mode & OB_MODE_SCULPT) {
/* ensure that grid paint mask layer is created */
- BKE_sculpt_mask_layers_ensure(ob, (MultiresModifierData *)new_md);
+ BKE_sculpt_mask_layers_ensure(nullptr, nullptr, ob, (MultiresModifierData *)new_md);
}
}
else if (type == eModifierType_Skin) {
@@ -522,13 +521,15 @@ void ED_object_modifier_copy_to_object(bContext *C,
DEG_relations_tag_update(bmain);
}
-bool ED_object_modifier_convert_psys_to_mesh(ReportList *UNUSED(reports),
+bool ED_object_modifier_convert_psys_to_mesh(ReportList * /*reports*/,
Main *bmain,
Depsgraph *depsgraph,
+ Scene *scene,
ViewLayer *view_layer,
Object *ob,
ModifierData *md)
{
+ using namespace blender;
int cvert = 0;
if (md->type != eModifierType_ParticleSystem) {
@@ -583,7 +584,7 @@ bool ED_object_modifier_convert_psys_to_mesh(ReportList *UNUSED(reports),
}
/* add new mesh */
- Object *obn = BKE_object_add(bmain, view_layer, OB_MESH, nullptr);
+ Object *obn = BKE_object_add(bmain, scene, view_layer, OB_MESH, nullptr);
Mesh *me = static_cast<Mesh *>(obn->data);
me->totvert = verts_num;
@@ -598,22 +599,27 @@ bool ED_object_modifier_convert_psys_to_mesh(ReportList *UNUSED(reports),
MVert *mvert = verts.data();
MEdge *medge = edges.data();
+ bke::MutableAttributeAccessor attributes = me->attributes_for_write();
+ bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT);
+
/* copy coordinates */
+ int vert_index = 0;
cache = psys_eval->pathcache;
for (int a = 0; a < part_num; a++) {
ParticleCacheKey *key = cache[a];
int kmax = key->segments;
- for (int k = 0; k <= kmax; k++, key++, cvert++, mvert++) {
- copy_v3_v3(mvert->co, key->co);
+ for (int k = 0; k <= kmax; k++, key++, cvert++, vert_index++) {
+ copy_v3_v3(mvert[vert_index].co, key->co);
if (k) {
medge->v1 = cvert - 1;
medge->v2 = cvert;
- medge->flag = ME_EDGEDRAW | ME_EDGERENDER | ME_LOOSEEDGE;
+ medge->flag = ME_EDGEDRAW | ME_LOOSEEDGE;
medge++;
}
else {
/* cheap trick to select the roots */
- mvert->flag |= SELECT;
+ select_vert.span[vert_index] = true;
}
}
}
@@ -622,21 +628,23 @@ bool ED_object_modifier_convert_psys_to_mesh(ReportList *UNUSED(reports),
for (int a = 0; a < child_num; a++) {
ParticleCacheKey *key = cache[a];
int kmax = key->segments;
- for (int k = 0; k <= kmax; k++, key++, cvert++, mvert++) {
- copy_v3_v3(mvert->co, key->co);
+ for (int k = 0; k <= kmax; k++, key++, cvert++, vert_index++) {
+ copy_v3_v3(mvert[vert_index].co, key->co);
if (k) {
medge->v1 = cvert - 1;
medge->v2 = cvert;
- medge->flag = ME_EDGEDRAW | ME_EDGERENDER | ME_LOOSEEDGE;
+ medge->flag = ME_EDGEDRAW | ME_LOOSEEDGE;
medge++;
}
else {
/* cheap trick to select the roots */
- mvert->flag |= SELECT;
+ select_vert.span[vert_index] = true;
}
}
}
+ select_vert.finish();
+
DEG_relations_tag_update(bmain);
return true;
@@ -781,7 +789,9 @@ static bool modifier_apply_obdata(
if (ELEM(mti->type, eModifierTypeType_Constructive, eModifierTypeType_Nonconstructive)) {
BKE_report(
- reports, RPT_ERROR, "Transform curve to mesh in order to apply constructive modifiers");
+ reports,
+ RPT_ERROR,
+ "Cannot apply constructive modifiers on curve. Convert curve to mesh in order to apply");
return false;
}
@@ -848,8 +858,38 @@ static bool modifier_apply_obdata(
Main *bmain = DEG_get_bmain(depsgraph);
BKE_object_material_from_eval_data(bmain, ob, &curves_eval.id);
}
+ else if (ob->type == OB_POINTCLOUD) {
+ PointCloud &points = *static_cast<PointCloud *>(ob->data);
+ if (mti->modifyGeometrySet == nullptr) {
+ BLI_assert_unreachable();
+ return false;
+ }
+
+ /* Create a temporary geometry set and component. */
+ GeometrySet geometry_set;
+ geometry_set.get_component_for_write<PointCloudComponent>().replace(
+ &points, GeometryOwnershipType::ReadOnly);
+
+ ModifierEvalContext mectx = {depsgraph, ob, (ModifierApplyFlag)0};
+ mti->modifyGeometrySet(md_eval, &mectx, &geometry_set);
+ if (!geometry_set.has_pointcloud()) {
+ BKE_report(
+ reports, RPT_ERROR, "Evaluated geometry from modifier does not contain a point cloud");
+ return false;
+ }
+ PointCloud *pointcloud_eval =
+ geometry_set.get_component_for_write<PointCloudComponent>().release();
+
+ /* Anonymous attributes shouldn't be available on the applied geometry. */
+ pointcloud_eval->attributes_for_write().remove_anonymous();
+
+ /* Copy the relevant information to the original. */
+ Main *bmain = DEG_get_bmain(depsgraph);
+ BKE_object_material_from_eval_data(bmain, ob, &pointcloud_eval->id);
+ BKE_pointcloud_nomain_to_pointcloud(pointcloud_eval, &points, true);
+ }
else {
- /* TODO: implement for point clouds and volumes. */
+ /* TODO: implement for volumes. */
BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
return false;
}
@@ -885,7 +925,7 @@ bool ED_object_modifier_apply(Main *bmain,
BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
return false;
}
- if ((ob->mode & OB_MODE_SCULPT) && (find_multires_modifier_before(scene, md)) &&
+ if ((ob->mode & OB_MODE_SCULPT) && find_multires_modifier_before(scene, md) &&
(BKE_modifier_is_same_topology(md) == false)) {
BKE_report(reports,
RPT_ERROR,
@@ -902,37 +942,62 @@ bool ED_object_modifier_apply(Main *bmain,
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
ModifierData *md_eval = (ob_eval) ? BKE_modifiers_findby_name(ob_eval, md->name) : md;
- /* Allow apply of a non-real-time modifier, by first re-enabling real-time. */
- int prev_mode = md_eval->mode;
- md_eval->mode |= eModifierMode_Realtime;
+ Depsgraph *apply_depsgraph = depsgraph;
+ Depsgraph *local_depsgraph = nullptr;
+
+ /* If the object is hidden or the modifier is not enabled for the viewport is disabled a special
+ * handling is required. This is because the viewport dependency graph optimizes out evaluation
+ * of objects which are used by hidden objects and disabled modifiers.
+ *
+ * The idea is to create a dependency graph which does not perform those optimizations. */
+ if ((ob_eval->base_flag & BASE_ENABLED_VIEWPORT) == 0 ||
+ (md_eval->mode & eModifierMode_Realtime) == 0) {
+ ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
+
+ local_depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_VIEWPORT);
+ DEG_disable_visibility_optimization(local_depsgraph);
+
+ ID *ids[] = {&ob->id};
+
+ DEG_graph_build_from_ids(local_depsgraph, ids, 1);
+ DEG_evaluate_on_refresh(local_depsgraph);
+
+ apply_depsgraph = local_depsgraph;
+
+ /* The evaluated object and modifier are now from the different dependency graph. */
+ ob_eval = DEG_get_evaluated_object(local_depsgraph, ob);
+ md_eval = BKE_modifiers_findby_name(ob_eval, md->name);
+
+ /* Force mode on the evaluated modifier, enforcing the modifier evaluation in the apply()
+ * functions. */
+ md_eval->mode |= eModifierMode_Realtime;
+ }
+ bool did_apply = false;
if (mode == MODIFIER_APPLY_SHAPE) {
- if (!modifier_apply_shape(bmain, reports, depsgraph, scene, ob, md_eval)) {
- md_eval->mode = prev_mode;
- return false;
- }
+ did_apply = modifier_apply_shape(bmain, reports, apply_depsgraph, scene, ob, md_eval);
}
else {
- if (!modifier_apply_obdata(reports, depsgraph, scene, ob, md_eval)) {
- md_eval->mode = prev_mode;
- return false;
- }
+ did_apply = modifier_apply_obdata(reports, apply_depsgraph, scene, ob, md_eval);
}
- md_eval->mode = prev_mode;
-
- if (!keep_modifier) {
- BKE_modifier_remove_from_list(ob, md);
- BKE_modifier_free(md);
+ if (did_apply) {
+ if (!keep_modifier) {
+ BKE_modifier_remove_from_list(ob, md);
+ BKE_modifier_free(md);
+ }
+ BKE_object_free_derived_caches(ob);
}
- BKE_object_free_derived_caches(ob);
+ if (local_depsgraph != nullptr) {
+ DEG_graph_free(local_depsgraph);
+ }
return true;
}
bool ED_object_modifier_copy(
- ReportList *UNUSED(reports), Main *bmain, Scene *scene, Object *ob, ModifierData *md)
+ ReportList * /*reports*/, Main *bmain, Scene *scene, Object *ob, ModifierData *md)
{
if (md->type == eModifierType_ParticleSystem) {
ModifierData *nmd = object_copy_particle_system(
@@ -977,8 +1042,8 @@ static int modifier_add_exec(bContext *C, wmOperator *op)
}
static const EnumPropertyItem *modifier_add_itemf(bContext *C,
- PointerRNA *UNUSED(ptr),
- PropertyRNA *UNUSED(prop),
+ PointerRNA * /*ptr*/,
+ PropertyRNA * /*prop*/,
bool *r_free)
{
Object *ob = ED_object_active_context(C);
@@ -1232,6 +1297,7 @@ static int modifier_remove_exec(bContext *C, wmOperator *op)
/* if cloth/softbody was removed, particle mode could be cleared */
if (mode_orig & OB_MODE_PARTICLE_EDIT) {
if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
if (ob == BKE_view_layer_active_object_get(view_layer)) {
WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, nullptr);
}
@@ -1428,7 +1494,7 @@ static bool modifier_apply_poll(bContext *C)
return false;
}
if (md != nullptr) {
- if ((ob->mode & OB_MODE_SCULPT) && (find_multires_modifier_before(scene, md)) &&
+ if ((ob->mode & OB_MODE_SCULPT) && find_multires_modifier_before(scene, md) &&
(BKE_modifier_is_same_topology(md) == false)) {
CTX_wm_operator_poll_msg_set(
C, "Constructive modifier cannot be applied to multi-res data in sculpt mode");
@@ -1554,7 +1620,7 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot)
/** \} */
/* ------------------------------------------------------------------- */
-/** \name Apply Modifier As Shapekey Operator
+/** \name Apply Modifier As Shape-Key Operator
* \{ */
static bool modifier_apply_as_shapekey_poll(bContext *C)
@@ -1578,8 +1644,8 @@ static int modifier_apply_as_shapekey_invoke(bContext *C, wmOperator *op, const
return retval;
}
-static char *modifier_apply_as_shapekey_get_description(struct bContext *UNUSED(C),
- struct wmOperatorType *UNUSED(op),
+static char *modifier_apply_as_shapekey_get_description(struct bContext * /*C*/,
+ struct wmOperatorType * /*op*/,
struct PointerRNA *values)
{
bool keep = RNA_boolean_get(values, "keep_modifier");
@@ -1621,12 +1687,13 @@ static int modifier_convert_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
if (!md || !ED_object_modifier_convert_psys_to_mesh(
- op->reports, bmain, depsgraph, view_layer, ob, md)) {
+ op->reports, bmain, depsgraph, scene, view_layer, ob, md)) {
return OPERATOR_CANCELLED;
}
@@ -1636,7 +1703,7 @@ static int modifier_convert_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int modifier_convert_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int modifier_convert_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (edit_modifier_invoke_properties(C, op)) {
return modifier_convert_exec(C, op);
@@ -1929,7 +1996,7 @@ static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
static int multires_higher_levels_delete_invoke(bContext *C,
wmOperator *op,
- const wmEvent *UNUSED(event))
+ const wmEvent * /*event*/)
{
if (edit_modifier_invoke_properties(C, op)) {
return multires_higher_levels_delete_exec(C, op);
@@ -1987,8 +2054,8 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- const eMultiresSubdivideModeType subdivide_mode = (eMultiresSubdivideModeType)(RNA_enum_get(
- op->ptr, "mode"));
+ const eMultiresSubdivideModeType subdivide_mode = (eMultiresSubdivideModeType)RNA_enum_get(
+ op->ptr, "mode");
multiresModifier_subdivide(object, mmd, subdivide_mode);
ED_object_iter_other(
@@ -1999,13 +2066,14 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op)
if (object->mode & OB_MODE_SCULPT) {
/* ensure that grid paint mask layer is created */
- BKE_sculpt_mask_layers_ensure(object, mmd);
+ BKE_sculpt_mask_layers_ensure(
+ CTX_data_ensure_evaluated_depsgraph(C), CTX_data_main(C), object, mmd);
}
return OPERATOR_FINISHED;
}
-static int multires_subdivide_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int multires_subdivide_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (edit_modifier_invoke_properties(C, op)) {
return multires_subdivide_exec(C, op);
@@ -2080,7 +2148,7 @@ static int multires_reshape_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int multires_reshape_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int multires_reshape_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (edit_modifier_invoke_properties(C, op)) {
return multires_reshape_exec(C, op);
@@ -2137,7 +2205,7 @@ static int multires_external_save_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int multires_external_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int multires_external_save_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
Object *ob = ED_object_active_context(C);
Mesh *me = static_cast<Mesh *>(ob->data);
@@ -2202,7 +2270,7 @@ void OBJECT_OT_multires_external_save(wmOperatorType *ot)
/** \name Multires Pack Operator
* \{ */
-static int multires_external_pack_exec(bContext *C, wmOperator *UNUSED(op))
+static int multires_external_pack_exec(bContext *C, wmOperator * /*op*/)
{
Object *ob = ED_object_active_context(C);
Mesh *me = static_cast<Mesh *>(ob->data);
@@ -2259,7 +2327,7 @@ static int multires_base_apply_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int multires_base_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int multires_base_apply_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (edit_modifier_invoke_properties(C, op)) {
return multires_base_apply_exec(C, op);
@@ -2311,7 +2379,7 @@ static int multires_unsubdivide_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int multires_unsubdivide_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int multires_unsubdivide_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (edit_modifier_invoke_properties(C, op)) {
return multires_unsubdivide_exec(C, op);
@@ -2365,9 +2433,7 @@ static int multires_rebuild_subdiv_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int multires_rebuild_subdiv_invoke(bContext *C,
- wmOperator *op,
- const wmEvent *UNUSED(event))
+static int multires_rebuild_subdiv_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (edit_modifier_invoke_properties(C, op)) {
return multires_rebuild_subdiv_exec(C, op);
@@ -2412,7 +2478,7 @@ static void modifier_skin_customdata_delete(Object *ob)
static bool skin_poll(bContext *C)
{
- return (edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH), false, false));
+ return edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH), false, false);
}
static bool skin_edit_poll(bContext *C)
@@ -2442,7 +2508,7 @@ static void skin_root_clear(BMVert *bm_vert, GSet *visited, const int cd_vert_sk
}
}
-static int skin_root_mark_exec(bContext *C, wmOperator *UNUSED(op))
+static int skin_root_mark_exec(bContext *C, wmOperator * /*op*/)
{
Object *ob = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(ob);
@@ -2551,7 +2617,7 @@ void OBJECT_OT_skin_loose_mark_clear(wmOperatorType *ot)
RNA_def_enum(ot->srna, "action", action_items, SKIN_LOOSE_MARK, "Action", nullptr);
}
-static int skin_radii_equalize_exec(bContext *C, wmOperator *UNUSED(op))
+static int skin_radii_equalize_exec(bContext *C, wmOperator * /*op*/)
{
Object *ob = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(ob);
@@ -2652,8 +2718,9 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain,
/* add vertex weights to original mesh */
CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, nullptr, me->totvert);
+ Scene *scene = DEG_get_input_scene(depsgraph);
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
- Object *arm_ob = BKE_object_add(bmain, view_layer, OB_ARMATURE, nullptr);
+ Object *arm_ob = BKE_object_add(bmain, scene, view_layer, OB_ARMATURE, nullptr);
BKE_object_transform_copy(arm_ob, skin_ob);
bArmature *arm = static_cast<bArmature *>(arm_ob->data);
arm->layer = 1;
@@ -2738,7 +2805,7 @@ static int skin_armature_create_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int skin_armature_create_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int skin_armature_create_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (edit_modifier_invoke_properties(C, op)) {
return skin_armature_create_exec(C, op);
@@ -2802,7 +2869,7 @@ static int correctivesmooth_bind_exec(bContext *C, wmOperator *op)
/* Signal to modifier to recalculate. */
CorrectiveSmoothModifierData *csmd_eval = (CorrectiveSmoothModifierData *)
BKE_modifier_get_evaluated(depsgraph, ob, &csmd->modifier);
- csmd_eval->bind_coords_num = (uint)-1;
+ csmd_eval->bind_coords_num = uint(-1);
/* Force modifier to run, it will call binding routine
* (this has to happen outside of depsgraph evaluation). */
@@ -2815,7 +2882,7 @@ static int correctivesmooth_bind_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int correctivesmooth_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int correctivesmooth_bind_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (edit_modifier_invoke_properties(C, op)) {
return correctivesmooth_bind_exec(C, op);
@@ -2890,7 +2957,7 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int meshdeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int meshdeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (edit_modifier_invoke_properties(C, op)) {
return meshdeform_bind_exec(C, op);
@@ -2944,7 +3011,7 @@ static int explode_refresh_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int explode_refresh_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int explode_refresh_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (edit_modifier_invoke_properties(C, op)) {
return explode_refresh_exec(C, op);
@@ -2981,7 +3048,7 @@ static bool ocean_bake_poll(bContext *C)
struct OceanBakeJob {
/* from wmJob */
struct Object *owner;
- short *stop, *do_update;
+ bool *stop, *do_update;
float *progress;
int current_frame;
struct OceanCache *och;
@@ -2996,7 +3063,7 @@ static void oceanbake_free(void *customdata)
}
/* called by oceanbake, only to check job 'stop' value */
-static int oceanbake_breakjob(void *UNUSED(customdata))
+static int oceanbake_breakjob(void * /*customdata*/)
{
// OceanBakeJob *ob = (OceanBakeJob *)customdata;
// return *(ob->stop);
@@ -3020,7 +3087,7 @@ static void oceanbake_update(void *customdata, float progress, int *cancel)
*(oj->progress) = progress;
}
-static void oceanbake_startjob(void *customdata, short *stop, short *do_update, float *progress)
+static void oceanbake_startjob(void *customdata, bool *stop, bool *do_update, float *progress)
{
OceanBakeJob *oj = static_cast<OceanBakeJob *>(customdata);
@@ -3033,7 +3100,7 @@ static void oceanbake_startjob(void *customdata, short *stop, short *do_update,
BKE_ocean_bake(oj->ocean, oj->och, oceanbake_update, (void *)oj);
*do_update = true;
- *stop = 0;
+ *stop = false;
}
static void oceanbake_endjob(void *customdata)
@@ -3145,7 +3212,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int ocean_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int ocean_bake_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (edit_modifier_invoke_properties(C, op)) {
return ocean_bake_exec(C, op);
@@ -3222,7 +3289,7 @@ static int laplaciandeform_bind_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int laplaciandeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int laplaciandeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (edit_modifier_invoke_properties(C, op)) {
return laplaciandeform_bind_exec(C, op);
@@ -3289,7 +3356,7 @@ static int surfacedeform_bind_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int surfacedeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int surfacedeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (edit_modifier_invoke_properties(C, op)) {
return surfacedeform_bind_exec(C, op);
@@ -3372,7 +3439,7 @@ void OBJECT_OT_geometry_nodes_input_attribute_toggle(wmOperatorType *ot)
/** \name Copy and Assign Geometry Node Group operator
* \{ */
-static int geometry_node_tree_copy_assign_exec(bContext *C, wmOperator *UNUSED(op))
+static int geometry_node_tree_copy_assign_exec(bContext *C, wmOperator * /*op*/)
{
Main *bmain = CTX_data_main(C);
Object *ob = ED_object_active_context(C);
@@ -3397,6 +3464,7 @@ static int geometry_node_tree_copy_assign_exec(bContext *C, wmOperator *UNUSED(o
nmd->node_group = new_tree;
id_us_min(&tree->id);
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
DEG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 24a4556b075..a73cc98c78e 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -151,6 +151,10 @@ void ED_operatortypes_object(void)
WM_operatortype_append(GPENCIL_OT_segment_remove);
WM_operatortype_append(GPENCIL_OT_segment_move);
+ WM_operatortype_append(GPENCIL_OT_time_segment_add);
+ WM_operatortype_append(GPENCIL_OT_time_segment_remove);
+ WM_operatortype_append(GPENCIL_OT_time_segment_move);
+
/* grease pencil line art */
WM_operatortypes_lineart();
diff --git a/source/blender/editors/object/object_random.c b/source/blender/editors/object/object_random.c
index 7d670d3f452..3117cbb0166 100644
--- a/source/blender/editors/object/object_random.c
+++ b/source/blender/editors/object/object_random.c
@@ -9,6 +9,7 @@
#include "DNA_layer_types.h"
#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
#include "BLI_math.h"
#include "BLI_rand.h"
@@ -77,6 +78,7 @@ static bool object_rand_transverts(TransVertStore *tvs,
static int object_rand_verts_exec(bContext *C, wmOperator *op)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob_active = CTX_data_edit_object(C);
const int ob_mode = ob_active->mode;
@@ -89,7 +91,7 @@ static int object_rand_verts_exec(bContext *C, wmOperator *op)
bool changed_multi = false;
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len, ob_mode);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len, ob_mode);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob_iter = objects[ob_index];
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 40dbd6b7bd8..10068def991 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -262,8 +262,8 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
}
else {
Object workob;
-
- ob->parent = view_layer->basact->object;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ ob->parent = BKE_view_layer_active_object_get(view_layer);
if (par3 != INDEX_UNSET) {
ob->partype = PARVERT3;
ob->par1 = par1;
@@ -272,7 +272,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
/* inverse parent matrix */
BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
- invert_m4_m4(ob->parentinv, workob.obmat);
+ invert_m4_m4(ob->parentinv, workob.object_to_world);
}
else {
ob->partype = PARVERT1;
@@ -280,7 +280,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
/* inverse parent matrix */
BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
- invert_m4_m4(ob->parentinv, workob.obmat);
+ invert_m4_m4(ob->parentinv, workob.object_to_world);
}
}
}
@@ -401,7 +401,7 @@ void ED_object_parent_clear(Object *ob, const 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->object_to_world, true, false);
break;
}
case CLEAR_PARENT_INVERSE: {
@@ -570,7 +570,9 @@ bool ED_object_parent_set(ReportList *reports,
pchan = BKE_pose_channel_active_if_layer_visible(par);
pchan_eval = BKE_pose_channel_active_if_layer_visible(parent_eval);
- if (pchan == NULL) {
+ if (pchan == NULL || pchan_eval == NULL) {
+ /* If pchan_eval is NULL, pchan should also be NULL. */
+ BLI_assert_msg(pchan == NULL, "Missing evaluated bone data");
BKE_report(reports, RPT_ERROR, "No active bone");
return false;
}
@@ -582,7 +584,7 @@ bool ED_object_parent_set(ReportList *reports,
if (keep_transform) {
/* Was removed because of bug T23577,
* but this can be handy in some cases too T32616, so make optional. */
- BKE_object_apply_mat4(ob, ob->obmat, false, false);
+ BKE_object_apply_mat4(ob, ob->object_to_world, false, false);
}
/* Set the parent (except for follow-path constraint option). */
@@ -704,7 +706,7 @@ bool ED_object_parent_set(ReportList *reports,
BKE_constraint_target_matrix_get(
depsgraph, scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra);
- sub_v3_v3v3(vec, ob->obmat[3], cmat[3]);
+ sub_v3_v3v3(vec, ob->object_to_world[3], cmat[3]);
copy_v3_v3(ob->loc, vec);
}
@@ -727,7 +729,7 @@ bool ED_object_parent_set(ReportList *reports,
ob->partype = PAROBJECT;
BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
- invert_m4_m4(ob->parentinv, workob.obmat);
+ invert_m4_m4(ob->parentinv, workob.object_to_world);
}
else if (is_armature_parent && (ob->type == OB_GPENCIL) && (par->type == OB_ARMATURE)) {
if (partype == PAR_ARMATURE) {
@@ -745,7 +747,7 @@ bool ED_object_parent_set(ReportList *reports,
ob->partype = PAROBJECT;
BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
- invert_m4_m4(ob->parentinv, workob.obmat);
+ invert_m4_m4(ob->parentinv, workob.object_to_world);
}
else if ((ob->type == OB_GPENCIL) && (par->type == OB_LATTICE)) {
/* Add Lattice modifier */
@@ -756,12 +758,12 @@ bool ED_object_parent_set(ReportList *reports,
ob->partype = PAROBJECT;
BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
- invert_m4_m4(ob->parentinv, workob.obmat);
+ invert_m4_m4(ob->parentinv, workob.object_to_world);
}
else {
/* calculate inverse parent matrix */
BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
- invert_m4_m4(ob->parentinv, workob.obmat);
+ invert_m4_m4(ob->parentinv, workob.object_to_world);
}
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
@@ -770,7 +772,7 @@ bool ED_object_parent_set(ReportList *reports,
static void parent_set_vert_find(KDTree_3d *tree, Object *child, int vert_par[3], bool is_tri)
{
- const float *co_find = child->obmat[3];
+ const float *co_find = child->object_to_world[3];
if (is_tri) {
KDTreeNearest_3d nearest[3];
int tot;
@@ -1184,7 +1186,7 @@ static int object_track_clear_exec(bContext *C, wmOperator *op)
}
if (type == CLEAR_TRACK_KEEP_TRANSFORM) {
- BKE_object_apply_mat4(ob, ob->obmat, true, true);
+ BKE_object_apply_mat4(ob, ob->object_to_world, true, true);
}
}
CTX_DATA_END;
@@ -2073,6 +2075,7 @@ static void tag_localizable_objects(bContext *C, const int mode)
* otherwise they're lost on reload, see T40595.
*/
static bool make_local_all__instance_indirect_unused(Main *bmain,
+ const Scene *scene,
ViewLayer *view_layer,
Collection *collection)
{
@@ -2086,6 +2089,7 @@ static bool make_local_all__instance_indirect_unused(Main *bmain,
id_us_plus(&ob->id);
BKE_collection_object_add(bmain, collection, ob);
+ BKE_view_layer_synced_ensure(scene, view_layer);
base = BKE_view_layer_base_find(view_layer, ob);
ED_object_base_select(base, BA_SELECT);
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
@@ -2153,15 +2157,16 @@ static int make_local_exec(bContext *C, wmOperator *op)
/* NOTE: we (ab)use LIB_TAG_PRE_EXISTING to cherry pick which ID to make local... */
if (mode == MAKE_LOCAL_ALL) {
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Collection *collection = CTX_data_collection(C);
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
/* De-select so the user can differentiate newly instanced from existing objects. */
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
- if (make_local_all__instance_indirect_unused(bmain, view_layer, collection)) {
+ if (make_local_all__instance_indirect_unused(bmain, scene, view_layer, collection)) {
BKE_report(op->reports,
RPT_INFO,
"Orphan library objects added to the current scene to avoid loss");
@@ -2211,7 +2216,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
}
- BKE_library_make_local(bmain, NULL, NULL, true, false); /* NULL is all libs */
+ BKE_library_make_local(bmain, NULL, NULL, true, false); /* NULL is all libraries. */
WM_event_add_notifier(C, NC_WINDOW, NULL);
return OPERATOR_FINISHED;
@@ -2313,26 +2318,39 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
id_root = &collection->id;
user_overrides_from_selected_objects = true;
}
- /* Else, poll func ensures us that ID_IS_LINKED(obact) is true. */
+ /* Else, poll func ensures us that ID_IS_LINKED(obact) is true, or that it is already an existing
+ * liboverride. */
else {
+ BLI_assert(ID_IS_LINKED(obact) || ID_IS_OVERRIDE_LIBRARY_REAL(obact));
id_root = &obact->id;
user_overrides_from_selected_objects = true;
}
- const bool do_fully_editable = !user_overrides_from_selected_objects;
-
- GSet *user_overrides_objects_uids = do_fully_editable ? NULL :
- BLI_gset_new(BLI_ghashutil_inthash_p,
- BLI_ghashutil_intcmp,
- __func__);
-
/* Make already existing selected liboverrides editable. */
+ bool is_active_override = false;
FOREACH_SELECTED_OBJECT_BEGIN (view_layer, CTX_wm_view3d(C), ob_iter) {
if (ID_IS_OVERRIDE_LIBRARY_REAL(ob_iter) && !ID_IS_LINKED(ob_iter)) {
ob_iter->id.override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED;
+ is_active_override = is_active_override || (&ob_iter->id == id_root);
+ DEG_id_tag_update(&ob_iter->id, ID_RECALC_COPY_ON_WRITE);
}
}
FOREACH_SELECTED_OBJECT_END;
+ /* If the active object is a liboverride, there is no point going further, since in the weird
+ * case where some other selected objects would be linked ones, there is no way to properly
+ * create overrides for them currently.
+ *
+ * Could be added later if really needed, but would rather avoid that extra complexity here. */
+ if (is_active_override) {
+ return OPERATOR_FINISHED;
+ }
+
+ const bool do_fully_editable = !user_overrides_from_selected_objects;
+
+ GSet *user_overrides_objects_uids = do_fully_editable ? NULL :
+ BLI_gset_new(BLI_ghashutil_inthash_p,
+ BLI_ghashutil_intcmp,
+ __func__);
if (do_fully_editable) {
/* Pass. */
@@ -2622,6 +2640,7 @@ static int clear_override_library_exec(bContext *C, wmOperator *UNUSED(op))
Object *ob_iter = todo_object_iter->link;
if (BKE_lib_override_library_is_hierarchy_leaf(bmain, &ob_iter->id)) {
bool do_remap_active = false;
+ BKE_view_layer_synced_ensure(scene, view_layer);
if (BKE_view_layer_active_object_get(view_layer) == ob_iter) {
do_remap_active = true;
}
@@ -2692,7 +2711,7 @@ static int make_single_user_exec(bContext *C, wmOperator *op)
if (RNA_boolean_get(op->ptr, "object")) {
if (flag == SELECT) {
- BKE_view_layer_selected_objects_tag(view_layer, OB_DONE);
+ BKE_view_layer_selected_objects_tag(scene, view_layer, OB_DONE);
single_object_users(bmain, scene, v3d, OB_DONE, copy_collections);
}
else {
diff --git a/source/blender/editors/object/object_remesh.cc b/source/blender/editors/object/object_remesh.cc
index aa8dc4debd9..b9acf5ae27b 100644
--- a/source/blender/editors/object/object_remesh.cc
+++ b/source/blender/editors/object/object_remesh.cc
@@ -186,7 +186,6 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op)
}
if (ob->mode == OB_MODE_SCULPT) {
- BKE_sculpt_ensure_orig_mesh_data(ob);
ED_sculpt_undo_geometry_end(ob);
}
@@ -247,7 +246,7 @@ static void voxel_size_parallel_lines_draw(uint pos3d,
const float spacing)
{
const float total_len = len_v3v3(initial_co, end_co);
- const int tot_lines = (int)(total_len / spacing);
+ const int tot_lines = int(total_len / spacing);
const int tot_lines_half = (tot_lines / 2) + 1;
float spacing_dir[3], lines_start[3];
float line_dir[3];
@@ -262,7 +261,7 @@ static void voxel_size_parallel_lines_draw(uint pos3d,
mid_v3_v3v3(lines_start, initial_co, end_co);
- immBegin(GPU_PRIM_LINES, (uint)tot_lines_half * 2);
+ immBegin(GPU_PRIM_LINES, uint(tot_lines_half) * 2);
for (int i = 0; i < tot_lines_half; i++) {
float line_start[3];
float line_end[3];
@@ -275,7 +274,7 @@ static void voxel_size_parallel_lines_draw(uint pos3d,
mul_v3_fl(spacing_dir, -1.0f);
- immBegin(GPU_PRIM_LINES, (uint)(tot_lines_half - 1) * 2);
+ immBegin(GPU_PRIM_LINES, uint(tot_lines_half - 1) * 2);
for (int i = 1; i < tot_lines_half; i++) {
float line_start[3];
float line_end[3];
@@ -287,7 +286,7 @@ static void voxel_size_parallel_lines_draw(uint pos3d,
immEnd();
}
-static void voxel_size_edit_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
+static void voxel_size_edit_draw(const bContext *C, ARegion * /*region*/, void *arg)
{
VoxelSizeEditCustomData *cd = static_cast<VoxelSizeEditCustomData *>(arg);
@@ -297,7 +296,7 @@ static void voxel_size_edit_draw(const bContext *C, ARegion *UNUSED(ar), void *a
uint pos3d = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
GPU_matrix_push();
- GPU_matrix_mul(cd->active_object->obmat);
+ GPU_matrix_mul(cd->active_object->object_to_world);
/* Draw Rect */
immUniformColor4f(0.9f, 0.9f, 0.9f, 0.8f);
@@ -321,7 +320,7 @@ static void voxel_size_edit_draw(const bContext *C, ARegion *UNUSED(ar), void *a
GPU_line_width(1.0f);
const float total_len = len_v3v3(cd->preview_plane[0], cd->preview_plane[1]);
- const int tot_lines = (int)(total_len / cd->voxel_size);
+ const int tot_lines = int(total_len / cd->voxel_size);
/* Smooth-step to reduce the alpha of the grid as the line number increases. */
const float a = VOXEL_SIZE_EDIT_MAX_GRIDS_LINES * 0.1f;
@@ -347,7 +346,7 @@ static void voxel_size_edit_draw(const bContext *C, ARegion *UNUSED(ar), void *a
UnitSettings *unit = &scene->unit;
BKE_unit_value_as_string(str,
VOXEL_SIZE_EDIT_MAX_STR_LEN,
- (double)(cd->voxel_size * unit->scale_length),
+ double(cd->voxel_size * unit->scale_length),
-3,
B_UNIT_LENGTH,
unit,
@@ -358,7 +357,7 @@ static void voxel_size_edit_draw(const bContext *C, ARegion *UNUSED(ar), void *a
GPU_matrix_push();
GPU_matrix_mul(cd->text_mat);
- BLF_size(fontid, 10.0f * fstyle_points, U.dpi);
+ BLF_size(fontid, 10.0f * fstyle_points * U.dpi_fac);
BLF_color3f(fontid, 1.0f, 1.0f, 1.0f);
BLF_width_and_height(fontid, str, strdrawlen, &strwidth, &strheight);
BLF_position(fontid, -0.5f * strwidth, -0.5f * strheight, 0.0f);
@@ -495,10 +494,10 @@ static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *ev
float view_normal[3] = {0.0f, 0.0f, 1.0f};
/* Calculate the view normal. */
- invert_m4_m4(active_object->imat, active_object->obmat);
+ invert_m4_m4(active_object->world_to_object, active_object->object_to_world);
copy_m3_m4(mat, rv3d->viewinv);
mul_m3_v3(mat, view_normal);
- copy_m3_m4(mat, active_object->imat);
+ copy_m3_m4(mat, active_object->world_to_object);
mul_m3_v3(mat, view_normal);
normalize_v3(view_normal);
@@ -536,7 +535,7 @@ static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *ev
/* Project the selected face in the previous step of the Bounding Box. */
for (int i = 0; i < 4; i++) {
float preview_plane_world_space[3];
- mul_v3_m4v3(preview_plane_world_space, active_object->obmat, cd->preview_plane[i]);
+ mul_v3_m4v3(preview_plane_world_space, active_object->object_to_world, cd->preview_plane[i]);
ED_view3d_project_v2(region, preview_plane_world_space, preview_plane_proj[i]);
}
@@ -583,7 +582,7 @@ static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *ev
/* Invert object scale. */
float scale[3];
- mat4_to_size(scale, active_object->obmat);
+ mat4_to_size(scale, active_object->object_to_world);
invert_v3(scale);
size_to_mat4(scale_mat, scale);
@@ -594,7 +593,7 @@ static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *ev
/* Scale the text to constant viewport size. */
float text_pos_word_space[3];
- mul_v3_m4v3(text_pos_word_space, active_object->obmat, text_pos);
+ mul_v3_m4v3(text_pos_word_space, active_object->object_to_world, text_pos);
const float pixelsize = ED_view3d_pixel_size(rv3d, text_pos_word_space);
scale_m4_fl(scale_mat, pixelsize * 0.5f);
mul_m4_m4_post(cd->text_mat, scale_mat);
@@ -655,7 +654,7 @@ enum eSymmetryAxes {
struct QuadriFlowJob {
/* from wmJob */
struct Object *owner;
- short *stop, *do_update;
+ bool *stop, *do_update;
float *progress;
const struct wmOperator *op;
@@ -837,7 +836,7 @@ static Mesh *remesh_symmetry_mirror(Object *ob, Mesh *mesh, eSymmetryAxes symmet
return mesh_mirror;
}
-static void quadriflow_start_job(void *customdata, short *stop, short *do_update, float *progress)
+static void quadriflow_start_job(void *customdata, bool *stop, bool *do_update, float *progress)
{
QuadriFlowJob *qj = static_cast<QuadriFlowJob *>(customdata);
@@ -885,7 +884,7 @@ static void quadriflow_start_job(void *customdata, short *stop, short *do_update
if (new_mesh == nullptr) {
*do_update = true;
- *stop = 0;
+ *stop = false;
if (qj->success == 1) {
/* This is not a user cancellation event. */
qj->success = 0;
@@ -912,14 +911,13 @@ static void quadriflow_start_job(void *customdata, short *stop, short *do_update
}
if (ob->mode == OB_MODE_SCULPT) {
- BKE_sculpt_ensure_orig_mesh_data(ob);
ED_sculpt_undo_geometry_end(ob);
}
BKE_mesh_batch_cache_dirty_tag(static_cast<Mesh *>(ob->data), BKE_MESH_BATCH_DIRTY_ALL);
*do_update = true;
- *stop = 0;
+ *stop = false;
}
static void quadriflow_end_job(void *customdata)
@@ -994,7 +992,7 @@ static int quadriflow_remesh_exec(bContext *C, wmOperator *op)
if (op->flag == 0) {
/* This is called directly from the exec operator, this operation is now blocking */
job->is_nonblocking_job = false;
- short stop = 0, do_update = true;
+ bool stop = false, do_update = true;
float progress;
quadriflow_start_job(job, &stop, &do_update, &progress);
quadriflow_end_job(job);
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index 2ce00490273..ee0a07bd7be 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -117,29 +117,28 @@ void ED_object_base_activate(bContext *C, Base *base)
void ED_object_base_activate_with_mode_exit_if_needed(bContext *C, Base *base)
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
/* Currently we only need to be concerned with edit-mode. */
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
if (obedit) {
Object *ob = base->object;
if (((ob->mode & OB_MODE_EDIT) == 0) || (obedit->type != ob->type)) {
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
ED_object_editmode_exit_multi_ex(bmain, scene, view_layer, EM_FREEDATA);
}
}
ED_object_base_activate(C, base);
}
-bool ED_object_base_deselect_all_ex(ViewLayer *view_layer,
- View3D *v3d,
- int action,
- bool *r_any_visible)
+bool ED_object_base_deselect_all_ex(
+ const Scene *scene, ViewLayer *view_layer, View3D *v3d, int action, bool *r_any_visible)
{
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
- FOREACH_VISIBLE_BASE_BEGIN (view_layer, v3d, base) {
+ FOREACH_VISIBLE_BASE_BEGIN (scene, view_layer, v3d, base) {
if (v3d && ((v3d->object_type_exclude_select & (1 << base->object->type)) != 0)) {
continue;
}
@@ -153,7 +152,7 @@ bool ED_object_base_deselect_all_ex(ViewLayer *view_layer,
bool any_visible = false;
bool changed = false;
- FOREACH_VISIBLE_BASE_BEGIN (view_layer, v3d, base) {
+ FOREACH_VISIBLE_BASE_BEGIN (scene, view_layer, v3d, base) {
if (v3d && ((v3d->object_type_exclude_select & (1 << base->object->type)) != 0)) {
continue;
}
@@ -190,9 +189,12 @@ bool ED_object_base_deselect_all_ex(ViewLayer *view_layer,
return changed;
}
-bool ED_object_base_deselect_all(ViewLayer *view_layer, View3D *v3d, int action)
+bool ED_object_base_deselect_all(const Scene *scene,
+ ViewLayer *view_layer,
+ View3D *v3d,
+ int action)
{
- return ED_object_base_deselect_all_ex(view_layer, v3d, action, NULL);
+ return ED_object_base_deselect_all_ex(scene, view_layer, v3d, action, NULL);
}
/** \} */
@@ -212,12 +214,13 @@ static int get_base_select_priority(Base *base)
return 1;
}
-Base *ED_object_find_first_by_data_id(ViewLayer *view_layer, ID *id)
+Base *ED_object_find_first_by_data_id(const Scene *scene, ViewLayer *view_layer, ID *id)
{
BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
/* Try active object. */
- Base *basact = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *basact = BKE_view_layer_active_base_get(view_layer);
if (basact && basact->object && basact->object->data == id) {
return basact;
@@ -227,7 +230,7 @@ Base *ED_object_find_first_by_data_id(ViewLayer *view_layer, ID *id)
Base *base_best = NULL;
int priority_best = 0;
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (base->object && base->object->data == id) {
if (base->flag & BASE_SELECTED) {
return base;
@@ -247,8 +250,10 @@ Base *ED_object_find_first_by_data_id(ViewLayer *view_layer, ID *id)
bool ED_object_jump_to_object(bContext *C, Object *ob, const bool UNUSED(reveal_hidden))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob);
if (base == NULL) {
@@ -257,10 +262,10 @@ bool ED_object_jump_to_object(bContext *C, Object *ob, const bool UNUSED(reveal_
/* TODO: use 'reveal_hidden', as is done with bones. */
- if (view_layer->basact != base || !(base->flag & BASE_SELECTED)) {
+ if (BKE_view_layer_active_base_get(view_layer) != base || !(base->flag & BASE_SELECTED)) {
/* Select if not selected. */
if (!(base->flag & BASE_SELECTED)) {
- ED_object_base_deselect_all(view_layer, v3d, SEL_DESELECT);
+ ED_object_base_deselect_all(scene, view_layer, v3d, SEL_DESELECT);
if (BASE_VISIBLE(v3d, base)) {
ED_object_base_select(base, BA_SELECT);
@@ -382,6 +387,7 @@ static bool objects_selectable_poll(bContext *C)
static int object_select_by_type_exec(bContext *C, wmOperator *op)
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
short obtype, extend;
@@ -390,7 +396,7 @@ static int object_select_by_type_exec(bContext *C, wmOperator *op)
extend = RNA_boolean_get(op->ptr, "extend");
if (extend == 0) {
- ED_object_base_deselect_all(view_layer, v3d, SEL_DESELECT);
+ ED_object_base_deselect_all(scene, view_layer, v3d, SEL_DESELECT);
}
CTX_DATA_BEGIN (C, Base *, base, visible_bases) {
@@ -400,7 +406,6 @@ static int object_select_by_type_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- Scene *scene = CTX_data_scene(C);
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
@@ -623,9 +628,10 @@ static int object_select_linked_exec(bContext *C, wmOperator *op)
extend = RNA_boolean_get(op->ptr, "extend");
if (extend == 0) {
- ED_object_base_deselect_all(view_layer, v3d, SEL_DESELECT);
+ ED_object_base_deselect_all(scene, view_layer, v3d, SEL_DESELECT);
}
+ BKE_view_layer_synced_ensure(scene, view_layer);
ob = BKE_view_layer_active_object_get(view_layer);
if (ob == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active object");
@@ -780,6 +786,7 @@ static bool select_grouped_children(bContext *C, Object *ob, const bool recursiv
/* Makes parent active and de-selected BKE_view_layer_active_object_get. */
static bool select_grouped_parent(bContext *C)
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
Base *baspar, *basact = CTX_data_active_base(C);
@@ -790,6 +797,7 @@ static bool select_grouped_parent(bContext *C)
return 0;
}
+ BKE_view_layer_synced_ensure(scene, view_layer);
baspar = BKE_view_layer_base_find(view_layer, basact->object->parent);
/* can be NULL if parent in other scene */
@@ -858,6 +866,7 @@ static bool select_grouped_collection(bContext *C, Object *ob)
static bool select_grouped_object_hooks(bContext *C, Object *ob)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -870,8 +879,9 @@ static bool select_grouped_object_hooks(bContext *C, Object *ob)
if (md->type == eModifierType_Hook) {
hmd = (HookModifierData *)md;
if (hmd->object) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
base = BKE_view_layer_base_find(view_layer, hmd->object);
- if (base && ((base->flag & BASE_SELECTED) == 0) && (BASE_SELECTABLE(v3d, base))) {
+ if (base && ((base->flag & BASE_SELECTED) == 0) && BASE_SELECTABLE(v3d, base)) {
ED_object_base_select(base, BA_SELECT);
changed = true;
}
@@ -948,7 +958,7 @@ static bool select_grouped_color(bContext *C, Object *ob)
CTX_DATA_BEGIN (C, Base *, base, selectable_bases) {
if (((base->flag & BASE_SELECTED) == 0) &&
- (compare_v3v3(base->object->color, ob->color, 0.005f))) {
+ compare_v3v3(base->object->color, ob->color, 0.005f)) {
ED_object_base_select(base, BA_SELECT);
changed = true;
}
@@ -1020,9 +1030,10 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op)
extend = RNA_boolean_get(op->ptr, "extend");
if (extend == 0) {
- changed = ED_object_base_deselect_all(view_layer, v3d, SEL_DESELECT);
+ changed = ED_object_base_deselect_all(scene, view_layer, v3d, SEL_DESELECT);
}
+ BKE_view_layer_synced_ensure(scene, view_layer);
ob = BKE_view_layer_active_object_get(view_layer);
if (ob == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active object");
@@ -1113,15 +1124,15 @@ void OBJECT_OT_select_grouped(wmOperatorType *ot)
static int object_select_all_exec(bContext *C, wmOperator *op)
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
int action = RNA_enum_get(op->ptr, "action");
bool any_visible = false;
- bool changed = ED_object_base_deselect_all_ex(view_layer, v3d, action, &any_visible);
+ bool changed = ED_object_base_deselect_all_ex(scene, view_layer, v3d, action, &any_visible);
if (changed) {
- Scene *scene = CTX_data_scene(C);
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
@@ -1240,6 +1251,7 @@ static int object_select_mirror_exec(bContext *C, wmOperator *op)
if (!STREQ(name_flip, primbase->object->id.name + 2)) {
Object *ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, name_flip);
if (ob) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *secbase = BKE_view_layer_base_find(view_layer, ob);
if (secbase) {
@@ -1291,9 +1303,11 @@ void OBJECT_OT_select_mirror(wmOperatorType *ot)
static bool object_select_more_less(bContext *C, const bool select)
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *ob = base->object;
ob->flag &= ~OB_DONE;
ob->id.tag &= ~LIB_TAG_DOIT;
diff --git a/source/blender/editors/object/object_transform.cc b/source/blender/editors/object/object_transform.cc
index e4f96d95173..7d0b62db827 100644
--- a/source/blender/editors/object/object_transform.cc
+++ b/source/blender/editors/object/object_transform.cc
@@ -7,6 +7,7 @@
#include <cstdlib>
#include <cstring>
+#include <limits>
#include <numeric>
#include "DNA_anim_types.h"
@@ -321,7 +322,7 @@ static int object_clear_transform_generic_exec(bContext *C,
BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
xcs = ED_object_xform_skip_child_container_create();
ED_object_xform_skip_child_container_item_ensure_from_array(
- xcs, view_layer, objects.data(), objects.size());
+ xcs, scene, view_layer, objects.data(), objects.size());
}
if (use_transform_data_origin) {
BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
@@ -469,7 +470,7 @@ void OBJECT_OT_scale_clear(wmOperatorType *ot)
/** \name Clear Origin Operator
* \{ */
-static int object_origin_clear_exec(bContext *C, wmOperator *UNUSED(op))
+static int object_origin_clear_exec(bContext *C, wmOperator * /*op*/)
{
float *v1, *v3;
float mat[3][3];
@@ -527,9 +528,9 @@ static void ignore_parent_tx(Main *bmain, Depsgraph *depsgraph, Scene *scene, Ob
LISTBASE_FOREACH (Object *, ob_child, &bmain->objects) {
if (ob_child->parent == ob) {
Object *ob_child_eval = DEG_get_evaluated_object(depsgraph, ob_child);
- BKE_object_apply_mat4(ob_child_eval, ob_child_eval->obmat, true, false);
+ BKE_object_apply_mat4(ob_child_eval, ob_child_eval->object_to_world, true, false);
BKE_object_workob_calc_parent(depsgraph, scene, ob_child_eval, &workob);
- invert_m4_m4(ob_child->parentinv, workob.obmat);
+ invert_m4_m4(ob_child->parentinv, workob.object_to_world);
/* Copy result of BKE_object_apply_mat4(). */
BKE_object_transform_copy(ob_child, ob_child_eval);
/* Make sure evaluated object is in a consistent state with the original one.
@@ -660,11 +661,11 @@ static int apply_objects_internal(bContext *C,
if (do_multi_user) {
obact = CTX_data_active_object(C);
- invert_m4_m4(obact_invmat, obact->obmat);
+ invert_m4_m4(obact_invmat, obact->object_to_world);
Object workob;
BKE_object_workob_calc_parent(depsgraph, scene, obact, &workob);
- copy_m4_m4(obact_parent, workob.obmat);
+ copy_m4_m4(obact_parent, workob.object_to_world);
copy_m4_m4(obact_parentinv, obact->parentinv);
if (apply_objects_internal_need_single_user(C)) {
@@ -989,7 +990,7 @@ static int apply_objects_internal(bContext *C,
float _obmat[4][4], _iobmat[4][4];
float _mat[4][4];
- copy_m4_m4(_obmat, ob->obmat);
+ copy_m4_m4(_obmat, ob->object_to_world);
invert_m4_m4(_iobmat, _obmat);
copy_m4_m4(_mat, _obmat);
@@ -1066,7 +1067,7 @@ static int apply_objects_internal(bContext *C,
return OPERATOR_FINISHED;
}
-static int visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op))
+static int visual_transform_apply_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
@@ -1075,7 +1076,7 @@ static int visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op))
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
BKE_object_where_is_calc(depsgraph, scene, ob_eval);
- BKE_object_apply_mat4(ob_eval, ob_eval->obmat, true, true);
+ BKE_object_apply_mat4(ob_eval, ob_eval->object_to_world, true, true);
BKE_object_transform_copy(ob, ob_eval);
/* update for any children that may get moved */
@@ -1123,7 +1124,7 @@ static int object_transform_apply_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int object_transform_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int object_transform_apply_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
Object *ob = ED_object_active_context(C);
@@ -1181,7 +1182,7 @@ void OBJECT_OT_transform_apply(wmOperatorType *ot)
/** \name Apply Parent Inverse Operator
* \{ */
-static int object_parent_inverse_apply_exec(bContext *C, wmOperator *UNUSED(op))
+static int object_parent_inverse_apply_exec(bContext *C, wmOperator * /*op*/)
{
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
if (ob->parent == nullptr) {
@@ -1274,8 +1275,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
if (centermode == ORIGIN_TO_CURSOR) {
copy_v3_v3(cent, cursor);
- invert_m4_m4(obedit->imat, obedit->obmat);
- mul_m4_v3(obedit->imat, cent);
+ invert_m4_m4(obedit->world_to_object, obedit->object_to_world);
+ mul_m4_v3(obedit->world_to_object, cent);
}
else {
if (around == V3D_AROUND_CENTER_BOUNDS) {
@@ -1288,7 +1289,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
}
else { /* #V3D_AROUND_CENTER_MEDIAN. */
if (em->bm->totvert) {
- const float total_div = 1.0f / (float)em->bm->totvert;
+ const float total_div = 1.0f / float(em->bm->totvert);
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
madd_v3_v3fl(cent, eve->co, total_div);
}
@@ -1342,8 +1343,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
if (centermode == ORIGIN_TO_CURSOR) {
copy_v3_v3(cent, cursor);
- invert_m4_m4(ob->imat, ob->obmat);
- mul_m4_v3(ob->imat, cent);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
+ mul_m4_v3(ob->world_to_object, cent);
}
if (ob->data == nullptr) {
@@ -1363,8 +1364,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
INIT_MINMAX(min, max);
BKE_object_minmax_dupli(depsgraph, scene, ob, min, max, true);
mid_v3_v3v3(cent, min, max);
- invert_m4_m4(ob->imat, ob->obmat);
- mul_m4_v3(ob->imat, cent);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
+ mul_m4_v3(ob->world_to_object, cent);
}
add_v3_v3(ob->instance_collection->instance_offset, cent);
@@ -1554,7 +1555,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
if (centermode == ORIGIN_TO_GEOMETRY) {
zero_v3(gpcenter);
BKE_gpencil_centroid_3d(gpd, gpcenter);
- add_v3_v3(gpcenter, ob->obmat[3]);
+ add_v3_v3(gpcenter, ob->object_to_world[3]);
}
if (centermode == ORIGIN_TO_CURSOR) {
copy_v3_v3(gpcenter, cursor);
@@ -1566,8 +1567,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
float offset_local[3];
int i;
- sub_v3_v3v3(offset_global, gpcenter, ob->obmat[3]);
- copy_m3_m4(bmat, obact->obmat);
+ sub_v3_v3v3(offset_global, gpcenter, ob->object_to_world[3]);
+ copy_m3_m4(bmat, obact->object_to_world);
invert_m3_m3(imat, bmat);
mul_m3_v3(imat, offset_global);
mul_v3_m3v3(offset_local, imat, offset_global);
@@ -1643,8 +1644,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
/* done */
}
else if (around == V3D_AROUND_CENTER_BOUNDS) {
- float3 min;
- float3 max;
+ float3 min(std::numeric_limits<float>::max());
+ float3 max(-std::numeric_limits<float>::max());
if (curves.bounds_min_max(min, max)) {
cent = math::midpoint(min, max);
}
@@ -1699,7 +1700,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
ob_other->flag |= OB_DONE;
DEG_id_tag_update(&ob_other->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
- mul_v3_mat3_m4v3(centn, ob_other->obmat, cent); /* omit translation part */
+ mul_v3_mat3_m4v3(centn, ob_other->object_to_world, cent); /* omit translation part */
add_v3_v3(ob_other->loc, centn);
Object *ob_other_eval = DEG_get_evaluated_object(depsgraph, ob_other);
@@ -1866,16 +1867,16 @@ struct XFormAxisData {
static void object_transform_axis_target_calc_depth_init(XFormAxisData *xfd, const int mval[2])
{
float view_co_a[3], view_co_b[3];
- const float2 mval_fl = {static_cast<float>(mval[0]), static_cast<float>(mval[1])};
+ const float2 mval_fl = {float(mval[0]), float(mval[1])};
ED_view3d_win_to_ray(xfd->vc.region, mval_fl, view_co_a, view_co_b);
add_v3_v3(view_co_b, view_co_a);
float center[3] = {0.0f};
int center_tot = 0;
for (XFormAxisItem &item : xfd->object_data) {
const Object *ob = item.ob;
- const float *ob_co_a = ob->obmat[3];
+ const float *ob_co_a = ob->object_to_world[3];
float ob_co_b[3];
- add_v3_v3v3(ob_co_b, ob->obmat[3], ob->obmat[2]);
+ add_v3_v3v3(ob_co_b, ob->object_to_world[3], ob->object_to_world[2]);
float view_isect[3], ob_isect[3];
if (isect_line_line_v3(view_co_a, view_co_b, ob_co_a, ob_co_b, view_isect, ob_isect)) {
add_v3_v3(center, view_isect);
@@ -1946,7 +1947,7 @@ static void object_apply_location(Object *ob, const float loc[3])
/* quick but weak */
Object ob_prev = blender::dna::shallow_copy(*ob);
float mat[4][4];
- copy_m4_m4(mat, ob->obmat);
+ copy_m4_m4(mat, ob->object_to_world);
copy_v3_v3(mat[3], loc);
BKE_object_apply_mat4(ob, mat, true, true);
copy_v3_v3(mat[3], ob->loc);
@@ -1961,7 +1962,7 @@ static bool object_orient_to_location(Object *ob,
const bool z_flip)
{
float delta[3];
- sub_v3_v3v3(delta, ob->obmat[3], location);
+ sub_v3_v3v3(delta, ob->object_to_world[3], location);
if (normalize_v3(delta) != 0.0f) {
if (z_flip) {
negate_v3(delta);
@@ -2079,7 +2080,7 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const
if (event->type == MOUSEMOVE || is_translate_init) {
const ViewDepths *depths = xfd->depths;
- if (depths && ((uint)event->mval[0] < depths->w) && ((uint)event->mval[1] < depths->h)) {
+ if (depths && (uint(event->mval[0]) < depths->w) && (uint(event->mval[1]) < depths->h)) {
float depth_fl = 1.0f;
ED_view3d_depth_read_cached(depths, event->mval, 0, &depth_fl);
float location_world[3];
@@ -2101,7 +2102,7 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const
}
#endif
- double depth = (double)depth_fl;
+ double depth = double(depth_fl);
if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
xfd->prev.depth = depth_fl;
xfd->prev.is_depth_valid = true;
@@ -2139,7 +2140,7 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const
float xform_rot_offset_inv_first[3][3];
for (const int i : xfd->object_data.index_range()) {
XFormAxisItem &item = xfd->object_data[i];
- copy_m3_m4(item.xform_rot_offset, item.ob->obmat);
+ copy_m3_m4(item.xform_rot_offset, item.ob->object_to_world);
normalize_m3(item.xform_rot_offset);
if (i == 0) {
@@ -2158,8 +2159,8 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const
XFormAxisItem &item = xfd->object_data[i];
if (is_translate_init) {
float ob_axis[3];
- item.xform_dist = len_v3v3(item.ob->obmat[3], location_world);
- normalize_v3_v3(ob_axis, item.ob->obmat[2]);
+ item.xform_dist = len_v3v3(item.ob->object_to_world[3], location_world);
+ normalize_v3_v3(ob_axis, item.ob->object_to_world[2]);
/* Scale to avoid adding distance when moving between surfaces. */
if (normal_found) {
float scale = fabsf(dot_v3v3(ob_axis, normal));
@@ -2173,7 +2174,7 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const
copy_v3_v3(target_normal, normal);
}
else {
- normalize_v3_v3(target_normal, item.ob->obmat[2]);
+ normalize_v3_v3(target_normal, item.ob->object_to_world[2]);
}
#ifdef USE_RELATIVE_ROTATION
@@ -2190,7 +2191,7 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const
madd_v3_v3fl(loc, target_normal, item.xform_dist);
object_apply_location(item.ob, loc);
/* so orient behaves as expected */
- copy_v3_v3(item.ob->obmat[3], loc);
+ copy_v3_v3(item.ob->object_to_world[3], loc);
}
object_orient_to_location(
diff --git a/source/blender/editors/object/object_utils.c b/source/blender/editors/object/object_utils.c
index cb9c8a92abe..1387282357f 100644
--- a/source/blender/editors/object/object_utils.c
+++ b/source/blender/editors/object/object_utils.c
@@ -22,6 +22,7 @@
#include "BKE_armature.h"
#include "BKE_editmesh.h"
#include "BKE_lattice.h"
+#include "BKE_layer.h"
#include "BKE_object.h"
#include "BKE_scene.h"
@@ -113,20 +114,20 @@ bool ED_object_calc_active_center(Object *ob, const bool select_only, float r_ce
{
if (ob->mode & OB_MODE_EDIT) {
if (ED_object_calc_active_center_for_editmode(ob, select_only, r_center)) {
- mul_m4_v3(ob->obmat, r_center);
+ mul_m4_v3(ob->object_to_world, r_center);
return true;
}
return false;
}
if (ob->mode & OB_MODE_POSE) {
if (ED_object_calc_active_center_for_posemode(ob, select_only, r_center)) {
- mul_m4_v3(ob->obmat, r_center);
+ mul_m4_v3(ob->object_to_world, r_center);
return true;
}
return false;
}
if (!select_only || (ob->base_flag & BASE_SELECTED)) {
- copy_v3_v3(r_center, ob->obmat[3]);
+ copy_v3_v3(r_center, ob->object_to_world[3]);
return true;
}
return false;
@@ -169,6 +170,7 @@ struct XFormObjectSkipChild_Container *ED_object_xform_skip_child_container_crea
void ED_object_xform_skip_child_container_item_ensure_from_array(
struct XFormObjectSkipChild_Container *xcs,
+ const Scene *scene,
ViewLayer *view_layer,
Object **objects,
uint objects_len)
@@ -178,8 +180,9 @@ void ED_object_xform_skip_child_container_item_ensure_from_array(
Object *ob = objects[ob_index];
BLI_gset_add(objects_in_transdata, ob);
}
-
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ ListBase *object_bases = BKE_view_layer_object_bases_get(view_layer);
+ LISTBASE_FOREACH (Base *, base, object_bases) {
Object *ob = base->object;
if (ob->parent != NULL) {
if (!BLI_gset_haskey(objects_in_transdata, ob)) {
@@ -209,7 +212,7 @@ void ED_object_xform_skip_child_container_item_ensure_from_array(
}
}
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, object_bases) {
Object *ob = base->object;
if (BLI_gset_haskey(objects_in_transdata, ob)) {
@@ -242,11 +245,11 @@ void ED_object_xform_skip_child_container_item_ensure(struct XFormObjectSkipChil
if (!BLI_ghash_ensure_p(xcs->obchild_in_obmode_map, ob, &xf_p)) {
struct XFormObjectSkipChild *xf = MEM_mallocN(sizeof(*xf), __func__);
copy_m4_m4(xf->parentinv_orig, ob->parentinv);
- copy_m4_m4(xf->obmat_orig, ob->obmat);
- copy_m4_m4(xf->parent_obmat_orig, ob->parent->obmat);
- invert_m4_m4(xf->parent_obmat_inv_orig, ob->parent->obmat);
+ copy_m4_m4(xf->obmat_orig, ob->object_to_world);
+ copy_m4_m4(xf->parent_obmat_orig, ob->parent->object_to_world);
+ invert_m4_m4(xf->parent_obmat_inv_orig, ob->parent->object_to_world);
if (ob_parent_recurse) {
- copy_m4_m4(xf->parent_recurse_obmat_orig, ob_parent_recurse->obmat);
+ copy_m4_m4(xf->parent_recurse_obmat_orig, ob_parent_recurse->object_to_world);
}
xf->mode = mode;
xf->ob_parent_recurse = ob_parent_recurse;
@@ -271,14 +274,14 @@ void ED_object_xform_skip_child_container_update_all(struct XFormObjectSkipChild
if (xf->mode == XFORM_OB_SKIP_CHILD_PARENT_IS_XFORM) {
/* Parent is transformed, this isn't so compensate. */
Object *ob_parent_eval = DEG_get_evaluated_object(depsgraph, ob->parent);
- mul_m4_m4m4(dmat, xf->parent_obmat_inv_orig, ob_parent_eval->obmat);
+ mul_m4_m4m4(dmat, xf->parent_obmat_inv_orig, ob_parent_eval->object_to_world);
invert_m4(dmat);
}
else if (xf->mode == XFORM_OB_SKIP_CHILD_PARENT_IS_XFORM_INDIRECT) {
/* Calculate parent matrix (from the root transform). */
Object *ob_parent_recurse_eval = DEG_get_evaluated_object(depsgraph, xf->ob_parent_recurse);
float parent_recurse_obmat_inv[4][4];
- invert_m4_m4(parent_recurse_obmat_inv, ob_parent_recurse_eval->obmat);
+ invert_m4_m4(parent_recurse_obmat_inv, ob_parent_recurse_eval->object_to_world);
mul_m4_m4m4(dmat, xf->parent_recurse_obmat_orig, parent_recurse_obmat_inv);
invert_m4(dmat);
float parent_obmat_calc[4][4];
@@ -293,7 +296,7 @@ void ED_object_xform_skip_child_container_update_all(struct XFormObjectSkipChild
/* Transform this - without transform data. */
Object *ob_parent_recurse_eval = DEG_get_evaluated_object(depsgraph, xf->ob_parent_recurse);
float parent_recurse_obmat_inv[4][4];
- invert_m4_m4(parent_recurse_obmat_inv, ob_parent_recurse_eval->obmat);
+ invert_m4_m4(parent_recurse_obmat_inv, ob_parent_recurse_eval->object_to_world);
mul_m4_m4m4(dmat, xf->parent_recurse_obmat_orig, parent_recurse_obmat_inv);
invert_m4(dmat);
float obmat_calc[4][4];
@@ -347,7 +350,7 @@ void ED_object_data_xform_container_item_ensure(struct XFormObjectData_Container
void **xf_p;
if (!BLI_ghash_ensure_p(xds->obdata_in_obmode_map, ob->data, &xf_p)) {
struct XFormObjectData_Extra *xf = MEM_mallocN(sizeof(*xf), __func__);
- copy_m4_m4(xf->obmat_orig, ob->obmat);
+ copy_m4_m4(xf->obmat_orig, ob->object_to_world);
xf->ob = ob;
/* Result may be NULL, that's OK. */
xf->xod = ED_object_data_xform_create(ob->data);
@@ -375,7 +378,7 @@ void ED_object_data_xform_container_update_all(struct XFormObjectData_Container
Object *ob_eval = DEG_get_evaluated_object(depsgraph, xf->ob);
float imat[4][4], dmat[4][4];
invert_m4_m4(imat, xf->obmat_orig);
- mul_m4_m4m4(dmat, imat, ob_eval->obmat);
+ mul_m4_m4m4(dmat, imat, ob_eval->object_to_world);
invert_m4(dmat);
ED_object_data_xform_by_mat4(xf->xod, dmat);
diff --git a/source/blender/editors/object/object_vgroup.cc b/source/blender/editors/object/object_vgroup.cc
index 1d1263494c7..d3bdf8ca4d3 100644
--- a/source/blender/editors/object/object_vgroup.cc
+++ b/source/blender/editors/object/object_vgroup.cc
@@ -31,6 +31,7 @@
#include "BLI_utildefines_stack.h"
#include "BLI_vector.hh"
+#include "BKE_attribute.hh"
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_deform.h"
@@ -154,6 +155,7 @@ bool ED_vgroup_parray_alloc(ID *id,
int *dvert_tot,
const bool use_vert_sel)
{
+ using namespace blender;
*dvert_tot = 0;
*dvert_arr = nullptr;
@@ -200,7 +202,6 @@ bool ED_vgroup_parray_alloc(ID *id,
return true;
}
if (!me->deform_verts().is_empty()) {
- const Span<MVert> verts = me->verts();
MutableSpan<MDeformVert> dverts = me->deform_verts_for_write();
*dvert_tot = me->totvert;
@@ -208,8 +209,12 @@ bool ED_vgroup_parray_alloc(ID *id,
MEM_mallocN(sizeof(void *) * me->totvert, __func__));
if (use_vert_sel) {
+ const bke::AttributeAccessor attributes = me->attributes();
+ const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+
for (int i = 0; i < me->totvert; i++) {
- (*dvert_arr)[i] = (verts[i].flag & SELECT) ? &dverts[i] : nullptr;
+ (*dvert_arr)[i] = select_vert[i] ? &dverts[i] : nullptr;
}
}
else {
@@ -636,6 +641,7 @@ static bool vgroup_normalize_active_vertex(Object *ob, eVGroupSelect subset_type
static void vgroup_copy_active_to_sel(Object *ob, eVGroupSelect subset_type)
{
+ using namespace blender;
Mesh *me = static_cast<Mesh *>(ob->data);
BMEditMesh *em = me->edit_mesh;
MDeformVert *dvert_act;
@@ -663,14 +669,17 @@ static void vgroup_copy_active_to_sel(Object *ob, eVGroupSelect subset_type)
}
}
else {
- const Span<MVert> verts = me->verts();
+ const bke::AttributeAccessor attributes = me->attributes();
+ const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+
int v_act;
dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
if (dvert_act) {
MutableSpan<MDeformVert> dverts = me->deform_verts_for_write();
for (i = 0; i < me->totvert; i++) {
- if ((verts[i].flag & SELECT) && &dverts[i] != dvert_act) {
+ if (select_vert[i] && &dverts[i] != dvert_act) {
BKE_defvert_copy_subset(&dverts[i], dvert_act, vgroup_validmap, vgroup_tot);
if (me->symmetry & ME_SYMMETRY_X) {
ED_mesh_defvert_mirror_update_ob(ob, -1, i);
@@ -706,7 +715,7 @@ static const EnumPropertyItem WT_vertex_group_select_item[] = {
};
const EnumPropertyItem *ED_object_vgroup_selection_itemf_helper(const bContext *C,
- PointerRNA *UNUSED(ptr),
+ PointerRNA * /*ptr*/,
PropertyRNA *prop,
bool *r_free,
const uint selection_mask)
@@ -1011,6 +1020,7 @@ void ED_vgroup_select_by_name(Object *ob, const char *name)
/* only in editmode */
static void vgroup_select_verts(Object *ob, int select)
{
+ using namespace blender;
const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
const ListBase *defbase = BKE_object_defgroup_list(ob);
@@ -1051,26 +1061,21 @@ static void vgroup_select_verts(Object *ob, int select)
else {
const Span<MDeformVert> dverts = me->deform_verts();
if (!dverts.is_empty()) {
- const bool *hide_vert = (const bool *)CustomData_get_layer_named(
- &me->vdata, CD_PROP_BOOL, ".hide_vert");
- MVert *mv;
- int i;
-
- mv = me->verts_for_write().data();
-
- for (i = 0; i < me->totvert; i++, mv++) {
- if (!(hide_vert != nullptr && hide_vert[i])) {
+ bke::MutableAttributeAccessor attributes = me->attributes_for_write();
+ const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
+ ".hide_vert", ATTR_DOMAIN_POINT, false);
+ bke::SpanAttributeWriter<bool> select_vert =
+ attributes.lookup_or_add_for_write_only_span<bool>(".select_vert", ATTR_DOMAIN_POINT);
+
+ for (const int i : select_vert.span.index_range()) {
+ if (!hide_vert[i]) {
if (BKE_defvert_find_index(&dverts[i], def_nr)) {
- if (select) {
- mv->flag |= SELECT;
- }
- else {
- mv->flag &= ~SELECT;
- }
+ select_vert.span[i] = select;
}
}
}
+ select_vert.finish();
paintvert_flush_flags(ob);
}
}
@@ -1335,7 +1340,7 @@ static void getVerticalAndHorizontalChange(const float norm[3],
* `coord` is a point on the plane.
*/
static void moveCloserToDistanceFromPlane(Depsgraph *depsgraph,
- Scene *UNUSED(scene),
+ Scene * /*scene*/,
Object *ob,
Mesh *me,
int index,
@@ -1517,8 +1522,9 @@ static void moveCloserToDistanceFromPlane(Depsgraph *depsgraph,
/* this is used to try to smooth a surface by only adjusting the nonzero weights of a vertex
* but it could be used to raise or lower an existing 'bump.' */
static void vgroup_fix(
- const bContext *C, Scene *UNUSED(scene), Object *ob, float distToBe, float strength, float cp)
+ const bContext *C, Scene * /*scene*/, Object *ob, float distToBe, float strength, float cp)
{
+ using namespace blender;
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
@@ -1529,8 +1535,11 @@ static void vgroup_fix(
if (!(me->editflag & ME_EDIT_PAINT_VERT_SEL)) {
return;
}
+ const bke::AttributeAccessor attributes = me->attributes();
+ const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
for (i = 0; i < me->totvert && mvert; i++, mvert++) {
- if (mvert->flag & SELECT) {
+ if (select_vert[i]) {
blender::Vector<int> verts = getSurroundingVerts(me, i);
const int count = verts.size();
if (!verts.is_empty()) {
@@ -1571,7 +1580,7 @@ static void vgroup_fix(
static void vgroup_levels_subset(Object *ob,
const bool *vgroup_validmap,
const int vgroup_tot,
- const int UNUSED(subset_count),
+ const int /*subset_count*/,
const float offset,
const float gain)
{
@@ -1832,7 +1841,7 @@ static void vgroup_lock_all(Object *ob, int action, int mask)
static void vgroup_invert_subset(Object *ob,
const bool *vgroup_validmap,
const int vgroup_tot,
- const int UNUSED(subset_count),
+ const int /*subset_count*/,
const bool auto_assign,
const bool auto_remove)
{
@@ -1893,6 +1902,7 @@ static void vgroup_smooth_subset(Object *ob,
const int repeat,
const float fac_expand)
{
+ using namespace blender;
const float ifac = 1.0f - fac;
MDeformVert **dvert_array = nullptr;
int dvert_tot = 0;
@@ -1955,7 +1965,7 @@ static void vgroup_smooth_subset(Object *ob,
nullptr;
#define IS_ME_VERT_READ(v) (use_hide ? !(hide_vert && hide_vert[v]) : true)
-#define IS_ME_VERT_WRITE(v) (use_select ? (((v)->flag & SELECT) != 0) : true)
+#define IS_ME_VERT_WRITE(v) (use_select ? select_vert[v] : true)
/* initialize used verts */
if (bm) {
@@ -1975,11 +1985,13 @@ static void vgroup_smooth_subset(Object *ob,
}
}
else {
- const Span<MVert> verts = me->verts();
+ const bke::AttributeAccessor attributes = me->attributes();
+ const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+
const blender::Span<MEdge> edges = me->edges();
for (int i = 0; i < dvert_tot; i++) {
- const MVert *v = &verts[i];
- if (IS_ME_VERT_WRITE(v)) {
+ if (IS_ME_VERT_WRITE(i)) {
for (int j = 0; j < emap[i].count; j++) {
const MEdge *e = &edges[emap[i].indices[j]];
const int i_other = (e->v1 == i) ? e->v2 : e->v1;
@@ -2049,11 +2061,15 @@ static void vgroup_smooth_subset(Object *ob,
}
}
else {
+ const bke::AttributeAccessor attributes = me->attributes();
+ const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+
int j;
const blender::Span<MEdge> edges = me->edges();
/* checked already */
- BLI_assert(IS_ME_VERT_WRITE(&me->verts()[i]));
+ BLI_assert(IS_ME_VERT_WRITE(i));
for (j = 0; j < emap[i].count; j++) {
const MEdge *e = &edges[emap[i].indices[j]];
@@ -2215,7 +2231,7 @@ static int vgroup_limit_total_subset(Object *ob,
static void vgroup_clean_subset(Object *ob,
const bool *vgroup_validmap,
const int vgroup_tot,
- const int UNUSED(subset_count),
+ const int /*subset_count*/,
const float epsilon,
const bool keep_single)
{
@@ -2246,7 +2262,7 @@ static void vgroup_clean_subset(Object *ob,
static void vgroup_quantize_subset(Object *ob,
const bool *vgroup_validmap,
const int vgroup_tot,
- const int UNUSED(subset_count),
+ const int /*subset_count*/,
const int steps)
{
MDeformVert **dvert_array = nullptr;
@@ -2360,25 +2376,10 @@ void ED_vgroup_mirror(Object *ob,
int *r_totmirr,
int *r_totfail)
{
+ using namespace blender;
/* TODO: vgroup locking.
* TODO: face masking. */
-#define VGROUP_MIRR_OP \
- dvert_mirror_op(dvert, \
- dvert_mirr, \
- sel, \
- sel_mirr, \
- flip_map, \
- flip_map_len, \
- mirror_weights, \
- flip_vgroups, \
- all_vgroups, \
- def_nr)
-
- BMVert *eve, *eve_mirr;
- MDeformVert *dvert_mirr;
- char sel, sel_mirr;
- int *flip_map = nullptr, flip_map_len;
const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
int totmirr = 0, totfail = 0;
@@ -2391,6 +2392,8 @@ void ED_vgroup_mirror(Object *ob,
return;
}
+ int *flip_map = nullptr;
+ int flip_map_len;
if (flip_vgroups) {
flip_map = all_vgroups ? BKE_object_defgroup_flip_map(ob, false, &flip_map_len) :
BKE_object_defgroup_flip_map_single(ob, false, def_nr, &flip_map_len);
@@ -2425,21 +2428,27 @@ void ED_vgroup_mirror(Object *ob,
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
/* Go through the list of edit-vertices and assign them. */
+ BMVert *eve, *eve_mirr;
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (!BM_elem_flag_test(eve, BM_ELEM_TAG)) {
if ((eve_mirr = EDBM_verts_mirror_get(em, eve))) {
if (eve_mirr != eve) {
if (!BM_elem_flag_test(eve_mirr, BM_ELEM_TAG)) {
- sel = BM_elem_flag_test(eve, BM_ELEM_SELECT);
- sel_mirr = BM_elem_flag_test(eve_mirr, BM_ELEM_SELECT);
+ const bool sel = BM_elem_flag_test(eve, BM_ELEM_SELECT);
+ const bool sel_mirr = BM_elem_flag_test(eve_mirr, BM_ELEM_SELECT);
if ((sel || sel_mirr) && (eve != eve_mirr)) {
- MDeformVert *dvert = static_cast<MDeformVert *>(
- BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset));
- dvert_mirr = static_cast<MDeformVert *>(
- BM_ELEM_CD_GET_VOID_P(eve_mirr, cd_dvert_offset));
-
- VGROUP_MIRR_OP;
+ dvert_mirror_op(
+ static_cast<MDeformVert *>(BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset)),
+ static_cast<MDeformVert *>(BM_ELEM_CD_GET_VOID_P(eve_mirr, cd_dvert_offset)),
+ sel,
+ sel_mirr,
+ flip_map,
+ flip_map_len,
+ mirror_weights,
+ flip_vgroups,
+ all_vgroups,
+ def_nr);
totmirr++;
}
@@ -2458,39 +2467,38 @@ void ED_vgroup_mirror(Object *ob,
}
else {
/* object mode / weight paint */
- const MVert *mv, *mv_mirr;
- int vidx, vidx_mirr;
const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
if (me->deform_verts().is_empty()) {
goto cleanup;
}
- if (!use_vert_sel) {
- sel = sel_mirr = true;
- }
-
BLI_bitmap *vert_tag = BLI_BITMAP_NEW(me->totvert, __func__);
- const MVert *verts = me->verts().data();
MutableSpan<MDeformVert> dverts = me->deform_verts_for_write();
+ const bke::AttributeAccessor attributes = me->attributes();
+ const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
- for (vidx = 0, mv = verts; vidx < me->totvert; vidx++, mv++) {
+ for (int vidx = 0; vidx < me->totvert; vidx++) {
if (!BLI_BITMAP_TEST(vert_tag, vidx)) {
+ int vidx_mirr;
if ((vidx_mirr = mesh_get_x_mirror_vert(ob, nullptr, vidx, use_topology)) != -1) {
if (vidx != vidx_mirr) {
- mv_mirr = &verts[vidx_mirr];
if (!BLI_BITMAP_TEST(vert_tag, vidx_mirr)) {
-
- if (use_vert_sel) {
- sel = mv->flag & SELECT;
- sel_mirr = mv_mirr->flag & SELECT;
- }
+ const bool sel = use_vert_sel ? select_vert[vidx] : true;
+ const bool sel_mirr = use_vert_sel ? select_vert[vidx_mirr] : true;
if (sel || sel_mirr) {
- MDeformVert *dvert = &dverts[vidx];
- dvert_mirr = &dvert[vidx_mirr];
-
- VGROUP_MIRR_OP;
+ dvert_mirror_op(&dverts[vidx],
+ &dverts[vidx_mirr],
+ sel,
+ sel_mirr,
+ flip_map,
+ flip_map_len,
+ mirror_weights,
+ flip_vgroups,
+ all_vgroups,
+ def_nr);
totmirr++;
}
@@ -2510,9 +2518,6 @@ void ED_vgroup_mirror(Object *ob,
}
else if (ob->type == OB_LATTICE) {
Lattice *lt = vgroup_edit_lattice(ob);
- int i1, i2;
- int u, v, w;
- int pntsu_half;
/* half but found up odd value */
if (lt->pntsu == 1 || lt->dvert == nullptr) {
@@ -2522,29 +2527,33 @@ void ED_vgroup_mirror(Object *ob,
/* unlike editmesh we know that by only looping over the first half of
* the 'u' indices it will cover all points except the middle which is
* ok in this case */
- pntsu_half = lt->pntsu / 2;
+ int pntsu_half = lt->pntsu / 2;
- for (w = 0; w < lt->pntsw; w++) {
- for (v = 0; v < lt->pntsv; v++) {
- for (u = 0; u < pntsu_half; u++) {
+ for (int w = 0; w < lt->pntsw; w++) {
+ for (int v = 0; v < lt->pntsv; v++) {
+ for (int u = 0; u < pntsu_half; u++) {
int u_inv = (lt->pntsu - 1) - u;
if (u != u_inv) {
- BPoint *bp, *bp_mirr;
-
- i1 = BKE_lattice_index_from_uvw(lt, u, v, w);
- i2 = BKE_lattice_index_from_uvw(lt, u_inv, v, w);
+ const int i1 = BKE_lattice_index_from_uvw(lt, u, v, w);
+ const int i2 = BKE_lattice_index_from_uvw(lt, u_inv, v, w);
- bp = &lt->def[i1];
- bp_mirr = &lt->def[i2];
+ const BPoint *bp = &lt->def[i1];
+ const BPoint *bp_mirr = &lt->def[i2];
- sel = bp->f1 & SELECT;
- sel_mirr = bp_mirr->f1 & SELECT;
+ const bool sel = bp->f1 & SELECT;
+ const bool sel_mirr = bp_mirr->f1 & SELECT;
if (sel || sel_mirr) {
- MDeformVert *dvert = &lt->dvert[i1];
- dvert_mirr = &lt->dvert[i2];
-
- VGROUP_MIRR_OP;
+ dvert_mirror_op(&lt->dvert[i1],
+ &lt->dvert[i2],
+ sel,
+ sel_mirr,
+ flip_map,
+ flip_map_len,
+ mirror_weights,
+ flip_vgroups,
+ all_vgroups,
+ def_nr);
totmirr++;
}
}
@@ -2587,6 +2596,7 @@ static void vgroup_delete_active(Object *ob)
/* only in editmode */
static void vgroup_assign_verts(Object *ob, const float weight)
{
+ using namespace blender;
const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
const ListBase *defbase = BKE_object_defgroup_list(ob);
@@ -2625,15 +2635,16 @@ static void vgroup_assign_verts(Object *ob, const float weight)
}
}
else {
- const Span<MVert> verts = me->verts();
+ const bke::AttributeAccessor attributes = me->attributes();
+ const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+
MutableSpan<MDeformVert> dverts = me->deform_verts_for_write();
- MDeformVert *dv = dverts.data();
- for (int i = 0; i < me->totvert; i++, dv++) {
- const MVert *mv = &verts[i];
- if (mv->flag & SELECT) {
+ for (int i = 0; i < me->totvert; i++) {
+ if (select_vert[i]) {
MDeformWeight *dw;
- dw = BKE_defvert_ensure_index(dv, def_nr);
+ dw = BKE_defvert_ensure_index(&dverts[i], def_nr);
if (dw) {
dw->weight = weight;
}
@@ -2774,7 +2785,7 @@ static bool vertex_group_vert_poll_ex(bContext *C,
return false;
}
- if (ob_type_flag && (((1 << ob->type) & ob_type_flag)) == 0) {
+ if (ob_type_flag && ((1 << ob->type) & ob_type_flag) == 0) {
return false;
}
@@ -2835,8 +2846,9 @@ static bool vertex_group_vert_select_unlocked_poll(bContext *C)
if (def_nr != 0) {
const ListBase *defbase = BKE_object_defgroup_list(ob);
const bDeformGroup *dg = static_cast<const bDeformGroup *>(BLI_findlink(defbase, def_nr - 1));
- if (dg) {
- return !(dg->flag & DG_LOCK_WEIGHT);
+ if (dg && (dg->flag & DG_LOCK_WEIGHT)) {
+ CTX_wm_operator_poll_msg_set(C, "The active vertex group is locked");
+ return false;
}
}
return true;
@@ -2864,7 +2876,7 @@ static bool vertex_group_vert_select_mesh_poll(bContext *C)
/** \name Vertex Group Add Operator
* \{ */
-static int vertex_group_add_exec(bContext *C, wmOperator *UNUSED(op))
+static int vertex_group_add_exec(bContext *C, wmOperator * /*op*/)
{
Object *ob = ED_object_context(C);
@@ -2951,7 +2963,7 @@ void OBJECT_OT_vertex_group_remove(wmOperatorType *ot)
/** \name Vertex Group Assign Operator
* \{ */
-static int vertex_group_assign_exec(bContext *C, wmOperator *UNUSED(op))
+static int vertex_group_assign_exec(bContext *C, wmOperator * /*op*/)
{
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = ED_object_context(C);
@@ -3082,7 +3094,7 @@ void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot)
/** \name Vertex Group Select Operator
* \{ */
-static int vertex_group_select_exec(bContext *C, wmOperator *UNUSED(op))
+static int vertex_group_select_exec(bContext *C, wmOperator * /*op*/)
{
Object *ob = ED_object_context(C);
@@ -3118,7 +3130,7 @@ void OBJECT_OT_vertex_group_select(wmOperatorType *ot)
/** \name Vertex Group Deselect Operator
* \{ */
-static int vertex_group_deselect_exec(bContext *C, wmOperator *UNUSED(op))
+static int vertex_group_deselect_exec(bContext *C, wmOperator * /*op*/)
{
Object *ob = ED_object_context(C);
@@ -3150,7 +3162,7 @@ void OBJECT_OT_vertex_group_deselect(wmOperatorType *ot)
/** \name Vertex Group Copy Operator
* \{ */
-static int vertex_group_copy_exec(bContext *C, wmOperator *UNUSED(op))
+static int vertex_group_copy_exec(bContext *C, wmOperator * /*op*/)
{
Object *ob = ED_object_context(C);
@@ -3235,7 +3247,7 @@ void OBJECT_OT_vertex_group_levels(wmOperatorType *ot)
/** \name Vertex Group Normalize Operator
* \{ */
-static int vertex_group_normalize_exec(bContext *C, wmOperator *UNUSED(op))
+static int vertex_group_normalize_exec(bContext *C, wmOperator * /*op*/)
{
Object *ob = ED_object_context(C);
bool changed;
@@ -3428,8 +3440,8 @@ static int vertex_group_lock_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static char *vertex_group_lock_description(bContext *UNUSED(C),
- wmOperatorType *UNUSED(op),
+static char *vertex_group_lock_description(bContext * /*C*/,
+ wmOperatorType * /*op*/,
PointerRNA *params)
{
int action = RNA_enum_get(params, "action");
@@ -3952,8 +3964,8 @@ static int set_active_group_exec(bContext *C, wmOperator *op)
}
static const EnumPropertyItem *vgroup_itemf(bContext *C,
- PointerRNA *UNUSED(ptr),
- PropertyRNA *UNUSED(prop),
+ PointerRNA * /*ptr*/,
+ PropertyRNA * /*prop*/,
bool *r_free)
{
if (C == nullptr) {
@@ -4314,6 +4326,7 @@ void OBJECT_OT_vertex_group_move(wmOperatorType *ot)
static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr)
{
+ using namespace blender;
MDeformVert *dvert_act;
Mesh *me = static_cast<Mesh *>(ob->data);
@@ -4348,7 +4361,6 @@ static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr)
}
}
else {
- MDeformVert *dv;
int v_act;
dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
@@ -4356,14 +4368,14 @@ static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr)
return;
}
- const Span<MVert> verts = me->verts();
MutableSpan<MDeformVert> dverts = me->deform_verts_for_write();
+ const bke::AttributeAccessor attributes = me->attributes();
+ const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
- dv = dverts.data();
- for (i = 0; i < me->totvert; i++, dv++) {
- if ((verts[i].flag & SELECT) && (dv != dvert_act)) {
-
- BKE_defvert_copy_index(dv, def_nr, dvert_act, def_nr);
+ for (i = 0; i < me->totvert; i++) {
+ if (select_vert[i] && (&dverts[i] != dvert_act)) {
+ BKE_defvert_copy_index(&dverts[i], def_nr, dvert_act, def_nr);
if (me->symmetry & ME_SYMMETRY_X) {
ED_mesh_defvert_mirror_update_ob(ob, -1, i);
@@ -4543,7 +4555,7 @@ void OBJECT_OT_vertex_weight_set_active(wmOperatorType *ot)
/** \name Vertex Group Normalize Active Vertex Operator
* \{ */
-static int vertex_weight_normalize_active_vertex_exec(bContext *C, wmOperator *UNUSED(op))
+static int vertex_weight_normalize_active_vertex_exec(bContext *C, wmOperator * /*op*/)
{
Object *ob = ED_object_context(C);
ToolSettings *ts = CTX_data_tool_settings(C);
@@ -4582,7 +4594,7 @@ void OBJECT_OT_vertex_weight_normalize_active_vertex(wmOperatorType *ot)
/** \name Vertex Group Copy Weights from Active Operator
* \{ */
-static int vertex_weight_copy_exec(bContext *C, wmOperator *UNUSED(op))
+static int vertex_weight_copy_exec(bContext *C, wmOperator * /*op*/)
{
Object *ob = ED_object_context(C);
ToolSettings *ts = CTX_data_tool_settings(C);
diff --git a/source/blender/editors/object/object_warp.c b/source/blender/editors/object/object_warp.c
index a1d53cadd06..d1e6e7000d9 100644
--- a/source/blender/editors/object/object_warp.c
+++ b/source/blender/editors/object/object_warp.c
@@ -38,7 +38,7 @@ static void object_warp_calc_view_matrix(float r_mat_view[4][4],
mul_m4_m4m4(viewmat_roll, mat_offset, viewmat);
/* apply the view and the object matrix */
- mul_m4_m4m4(r_mat_view, viewmat_roll, obedit->obmat);
+ mul_m4_m4m4(r_mat_view, viewmat_roll, obedit->object_to_world);
/* get the view-space cursor */
mul_v3_m4v3(r_center_view, viewmat_roll, center);
diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c
index 1ce90849a88..1a3f0f0f2ac 100644
--- a/source/blender/editors/physics/dynamicpaint_ops.c
+++ b/source/blender/editors/physics/dynamicpaint_ops.c
@@ -285,7 +285,7 @@ void DPAINT_OT_output_toggle(wmOperatorType *ot)
typedef struct DynamicPaintBakeJob {
/* from wmJob */
void *owner;
- short *stop, *do_update;
+ bool *stop, *do_update;
float *progress;
struct Main *bmain;
@@ -405,7 +405,7 @@ static void dynamicPaint_bakeImageSequence(DynamicPaintBakeJob *job)
/* primary output layer */
if (surface->flags & MOD_DPAINT_OUT1) {
/* set filepath */
- BLI_join_dirfile(
+ BLI_path_join(
filepath, sizeof(filepath), surface->image_output_path, surface->output_name);
BLI_path_frame(filepath, frame, 4);
@@ -415,7 +415,7 @@ static void dynamicPaint_bakeImageSequence(DynamicPaintBakeJob *job)
/* secondary output */
if (surface->flags & MOD_DPAINT_OUT2 && surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
/* set filepath */
- BLI_join_dirfile(
+ BLI_path_join(
filepath, sizeof(filepath), surface->image_output_path, surface->output_name2);
BLI_path_frame(filepath, frame, 4);
@@ -429,7 +429,7 @@ static void dynamicPaint_bakeImageSequence(DynamicPaintBakeJob *job)
ED_update_for_newframe(job->bmain, job->depsgraph);
}
-static void dpaint_bake_startjob(void *customdata, short *stop, short *do_update, float *progress)
+static void dpaint_bake_startjob(void *customdata, bool *stop, bool *do_update, float *progress)
{
DynamicPaintBakeJob *job = customdata;
@@ -450,7 +450,7 @@ static void dpaint_bake_startjob(void *customdata, short *stop, short *do_update
dynamicPaint_bakeImageSequence(job);
*do_update = true;
- *stop = 0;
+ *stop = false;
}
/*
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 30dab322fbc..22295c260e2 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -169,6 +169,7 @@ void PE_free_ptcache_edit(PTCacheEdit *edit)
int PE_minmax(
Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, float min[3], float max[3])
{
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
PTCacheEdit *edit = PE_get_current(depsgraph, scene, ob);
ParticleSystem *psys;
@@ -3117,9 +3118,8 @@ static void subdivide_particle(PEData *data, int pa_index)
pa->flag |= PARS_REKEY;
- nkey = new_keys = MEM_callocN((pa->totkey + totnewkey) * (sizeof(HairKey)),
- "Hair subdivide keys");
- nekey = new_ekeys = MEM_callocN((pa->totkey + totnewkey) * (sizeof(PTCacheEditKey)),
+ nkey = new_keys = MEM_callocN((pa->totkey + totnewkey) * sizeof(HairKey), "Hair subdivide keys");
+ nekey = new_ekeys = MEM_callocN((pa->totkey + totnewkey) * sizeof(PTCacheEditKey),
"Hair subdivide edit keys");
key = pa->hair;
@@ -3533,7 +3533,7 @@ static void PE_mirror_x(Depsgraph *depsgraph, Scene *scene, Object *ob, int tagg
}
const bool use_dm_final_indices = (psys->part->use_modifier_stack &&
- !psmd_eval->mesh_final->runtime.deformed_only);
+ !BKE_mesh_is_deformed_only(psmd_eval->mesh_final));
/* NOTE: this is not nice to use tessfaces but hard to avoid since pa->num uses tessfaces */
BKE_mesh_tessface_ensure(me);
@@ -3920,8 +3920,8 @@ static void brush_puff(PEData *data, int point_index, float mouse_distance)
mul_m4_v3(mat, co);
/* Use `kco` as the object space version of world-space `co`,
- * `ob->imat` is set before calling. */
- mul_v3_m4v3(kco, data->ob->imat, co);
+ * `ob->world_to_object` is set before calling. */
+ mul_v3_m4v3(kco, data->ob->world_to_object, co);
point_index = BLI_kdtree_3d_find_nearest(edit->emitter_field, kco, NULL);
if (point_index == -1) {
@@ -3930,7 +3930,7 @@ static void brush_puff(PEData *data, int point_index, float mouse_distance)
copy_v3_v3(co_root, co);
copy_v3_v3(no_root, &edit->emitter_cosnos[point_index * 6 + 3]);
- mul_mat3_m4_v3(data->ob->obmat, no_root); /* normal into global-space */
+ mul_mat3_m4_v3(data->ob->object_to_world, no_root); /* normal into global-space */
normalize_v3(no_root);
if (puff_volume) {
@@ -3987,7 +3987,7 @@ static void brush_puff(PEData *data, int point_index, float mouse_distance)
/* Translate (not rotate) the rest of the hair if its not selected. */
{
/* NOLINTNEXTLINE: readability-redundant-preprocessor */
-# if 0 /* kindof works but looks worse than what's below */
+# if 0 /* Kind of works but looks worse than what's below. */
/* Move the unselected point on a vector based on the
* hair direction and the offset */
@@ -4010,14 +4010,14 @@ static void brush_puff(PEData *data, int point_index, float mouse_distance)
mul_m4_v3(mat, oco);
/* Use `kco` as the object space version of world-space `co`,
- * `ob->imat` is set before calling. */
- mul_v3_m4v3(kco, data->ob->imat, oco);
+ * `ob->world_to_object` is set before calling. */
+ mul_v3_m4v3(kco, data->ob->world_to_object, oco);
point_index = BLI_kdtree_3d_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 world-space. */
- mul_mat3_m4_v3(imat, onor); /* World-space into particle-space. */
+ mul_mat3_m4_v3(data->ob->object_to_world, onor); /* Normal into world-space. */
+ mul_mat3_m4_v3(imat, onor); /* World-space into particle-space. */
normalize_v3(onor);
}
else {
@@ -4353,7 +4353,7 @@ static void brush_add_count_iter(void *__restrict iter_data_v,
0,
0,
0)) {
- if (psys->part->use_modifier_stack && !psmd_eval->mesh_final->runtime.deformed_only) {
+ if (psys->part->use_modifier_stack && !BKE_mesh_is_deformed_only(psmd_eval->mesh_final)) {
add_pars[iter].num = add_pars[iter].num_dmcache;
add_pars[iter].num_dmcache = DMCACHE_ISCHILD;
}
@@ -4412,7 +4412,7 @@ static int brush_add(const bContext *C, PEData *data, short number)
short size = pset->brush[PE_BRUSH_ADD].size;
RNG *rng;
- invert_m4_m4(imat, ob->obmat);
+ invert_m4_m4(imat, ob->object_to_world);
if (psys->flag & PSYS_GLOBAL_HAIR) {
return 0;
@@ -4430,7 +4430,7 @@ static int brush_add(const bContext *C, PEData *data, short number)
timestep = psys_get_timestep(&sim);
- if (psys->part->use_modifier_stack || psmd_eval->mesh_final->runtime.deformed_only) {
+ if (psys->part->use_modifier_stack || BKE_mesh_is_deformed_only(psmd_eval->mesh_final)) {
mesh = psmd_eval->mesh_final;
}
else {
@@ -4797,7 +4797,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
data.combfac = 1.0f - data.combfac;
}
- invert_m4_m4(ob->imat, ob->obmat);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
ED_view3d_win_to_delta(region, xy_delta, bedit->zfac, vec);
data.dvec = vec;
@@ -4865,7 +4865,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
}
data.invert = (brush->invert ^ flip);
- invert_m4_m4(ob->imat, ob->obmat);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
foreach_mouse_hit_point(&data, brush_puff, selected);
}
@@ -4895,7 +4895,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
data.smoothfac = brush->strength;
- invert_m4_m4(ob->imat, ob->obmat);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
foreach_mouse_hit_key(&data, brush_smooth_get, selected);
@@ -5112,7 +5112,7 @@ static bool shape_cut_test_point(PEData *data, ParticleEditSettings *pset, Parti
userdata.num_hits = 0;
float co_shape[3];
- mul_v3_m4v3(co_shape, pset->shape_object->imat, key->co);
+ mul_v3_m4v3(co_shape, pset->shape_object->world_to_object, key->co);
BLI_bvhtree_ray_cast_all(
shape_bvh->tree, co_shape, dir, 0.0f, BVH_RAYCAST_DIST_MAX, point_inside_bvh_cb, &userdata);
@@ -5153,8 +5153,8 @@ static void shape_cut(PEData *data, int pa_index)
float dir_shape[3];
float len_shape;
- mul_v3_m4v3(co_curr_shape, pset->shape_object->imat, key->co);
- mul_v3_m4v3(co_next_shape, pset->shape_object->imat, (key + 1)->co);
+ mul_v3_m4v3(co_curr_shape, pset->shape_object->world_to_object, key->co);
+ mul_v3_m4v3(co_next_shape, pset->shape_object->world_to_object, (key + 1)->co);
sub_v3_v3v3(dir_shape, co_next_shape, co_curr_shape);
len_shape = normalize_v3(dir_shape);
diff --git a/source/blender/editors/physics/particle_edit_undo.c b/source/blender/editors/physics/particle_edit_undo.c
index d1a2bb31454..bc9a90b5b3f 100644
--- a/source/blender/editors/physics/particle_edit_undo.c
+++ b/source/blender/editors/physics/particle_edit_undo.c
@@ -212,6 +212,7 @@ static bool particle_undosys_poll(struct bContext *C)
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
PTCacheEdit *edit = PE_get_current(depsgraph, scene, ob);
@@ -226,6 +227,7 @@ static bool particle_undosys_step_encode(struct bContext *C,
ParticleUndoStep *us = (ParticleUndoStep *)us_p;
ViewLayer *view_layer = CTX_data_view_layer(C);
us->scene_ref.ptr = CTX_data_scene(C);
+ BKE_view_layer_synced_ensure(us->scene_ref.ptr, view_layer);
us->object_ref.ptr = BKE_view_layer_active_object_get(view_layer);
PTCacheEdit *edit = PE_get_current(depsgraph, us->scene_ref.ptr, us->object_ref.ptr);
undoptcache_from_editcache(&us->data, edit);
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index f13b7519cd7..852156f9403 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -23,6 +23,7 @@
#include "BKE_bvhutils.h"
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
@@ -118,7 +119,8 @@ static int particle_system_remove_exec(bContext *C, wmOperator *UNUSED(op))
*/
if (mode_orig & OB_MODE_PARTICLE_EDIT) {
if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0) {
- if (view_layer->basact && view_layer->basact->object == ob) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ if (BKE_view_layer_active_object_get(view_layer) == ob) {
WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
}
}
@@ -724,13 +726,13 @@ static bool remap_hair_emitter(Depsgraph *depsgraph,
edit_point = target_edit ? target_edit->points : NULL;
- invert_m4_m4(from_ob_imat, ob->obmat);
- invert_m4_m4(to_ob_imat, target_ob->obmat);
+ invert_m4_m4(from_ob_imat, ob->object_to_world);
+ invert_m4_m4(to_ob_imat, target_ob->object_to_world);
invert_m4_m4(from_imat, from_mat);
invert_m4_m4(to_imat, to_mat);
const bool use_dm_final_indices = (target_psys->part->use_modifier_stack &&
- !target_psmd->mesh_final->runtime.deformed_only);
+ !BKE_mesh_is_deformed_only(target_psmd->mesh_final));
if (use_dm_final_indices || !target_psmd->mesh_original) {
mesh = target_psmd->mesh_final;
@@ -841,7 +843,7 @@ static bool remap_hair_emitter(Depsgraph *depsgraph,
float offset[3];
if (to_global) {
- copy_m4_m4(imat, target_ob->obmat);
+ copy_m4_m4(imat, target_ob->object_to_world);
}
else {
/* NOTE: using target_dm here, which is in target_ob object space and has full modifiers.
@@ -921,8 +923,8 @@ static bool connect_hair(Depsgraph *depsgraph, Scene *scene, Object *ob, Particl
ob,
psys,
psys->edit,
- ob->obmat,
- ob->obmat,
+ ob->object_to_world,
+ ob->object_to_world,
psys->flag & PSYS_GLOBAL_HAIR,
false);
if (ok) {
@@ -1172,8 +1174,8 @@ static bool copy_particle_systems_to_object(const bContext *C,
to_mat = I;
break;
case PAR_COPY_SPACE_WORLD:
- from_mat = ob_from->obmat;
- to_mat = ob_to->obmat;
+ from_mat = ob_from->object_to_world;
+ to_mat = ob_to->object_to_world;
break;
default:
/* should not happen */
@@ -1202,9 +1204,7 @@ static bool copy_particle_systems_to_object(const bContext *C,
#undef PSYS_FROM_FIRST
#undef PSYS_FROM_NEXT
- if (duplicate_settings) {
- DEG_relations_tag_update(bmain);
- }
+ DEG_relations_tag_update(bmain);
DEG_id_tag_update(&ob_to->id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, ob_to);
return true;
@@ -1267,8 +1267,7 @@ static int copy_particle_systems_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
if (changed_tot > 0) {
- Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
- DEG_graph_tag_relations_update(depsgraph);
+ DEG_relations_tag_update(CTX_data_main(C));
}
if ((changed_tot == 0 && fail == 0) || fail) {
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index 1d3cf7c36af..d5e55c99444 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -61,7 +61,7 @@
typedef struct FluidJob {
/* from wmJob */
void *owner;
- short *stop, *do_update;
+ bool *stop, *do_update;
float *progress;
const char *type;
const char *name;
@@ -81,51 +81,51 @@ typedef struct FluidJob {
static inline bool fluid_is_bake_all(FluidJob *job)
{
- return (STREQ(job->type, FLUID_JOB_BAKE_ALL));
+ return STREQ(job->type, FLUID_JOB_BAKE_ALL);
}
static inline bool fluid_is_bake_data(FluidJob *job)
{
- return (STREQ(job->type, FLUID_JOB_BAKE_DATA));
+ return STREQ(job->type, FLUID_JOB_BAKE_DATA);
}
static inline bool fluid_is_bake_noise(FluidJob *job)
{
- return (STREQ(job->type, FLUID_JOB_BAKE_NOISE));
+ return STREQ(job->type, FLUID_JOB_BAKE_NOISE);
}
static inline bool fluid_is_bake_mesh(FluidJob *job)
{
- return (STREQ(job->type, FLUID_JOB_BAKE_MESH));
+ return STREQ(job->type, FLUID_JOB_BAKE_MESH);
}
static inline bool fluid_is_bake_particle(FluidJob *job)
{
- return (STREQ(job->type, FLUID_JOB_BAKE_PARTICLES));
+ return STREQ(job->type, FLUID_JOB_BAKE_PARTICLES);
}
static inline bool fluid_is_bake_guiding(FluidJob *job)
{
- return (STREQ(job->type, FLUID_JOB_BAKE_GUIDES));
+ return STREQ(job->type, FLUID_JOB_BAKE_GUIDES);
}
static inline bool fluid_is_free_all(FluidJob *job)
{
- return (STREQ(job->type, FLUID_JOB_FREE_ALL));
+ return STREQ(job->type, FLUID_JOB_FREE_ALL);
}
static inline bool fluid_is_free_data(FluidJob *job)
{
- return (STREQ(job->type, FLUID_JOB_FREE_DATA));
+ return STREQ(job->type, FLUID_JOB_FREE_DATA);
}
static inline bool fluid_is_free_noise(FluidJob *job)
{
- return (STREQ(job->type, FLUID_JOB_FREE_NOISE));
+ return STREQ(job->type, FLUID_JOB_FREE_NOISE);
}
static inline bool fluid_is_free_mesh(FluidJob *job)
{
- return (STREQ(job->type, FLUID_JOB_FREE_MESH));
+ return STREQ(job->type, FLUID_JOB_FREE_MESH);
}
static inline bool fluid_is_free_particles(FluidJob *job)
{
- return (STREQ(job->type, FLUID_JOB_FREE_PARTICLES));
+ return STREQ(job->type, FLUID_JOB_FREE_PARTICLES);
}
static inline bool fluid_is_free_guiding(FluidJob *job)
{
- return (STREQ(job->type, FLUID_JOB_FREE_GUIDES));
+ return STREQ(job->type, FLUID_JOB_FREE_GUIDES);
}
static bool fluid_initjob(
@@ -349,7 +349,7 @@ static void fluid_bake_endjob(void *customdata)
}
}
-static void fluid_bake_startjob(void *customdata, short *stop, short *do_update, float *progress)
+static void fluid_bake_startjob(void *customdata, bool *stop, bool *do_update, float *progress)
{
FluidJob *job = customdata;
FluidDomainSettings *fds = job->fmd->domain;
@@ -368,7 +368,7 @@ static void fluid_bake_startjob(void *customdata, short *stop, short *do_update,
BKE_spacedata_draw_locks(true);
if (fluid_is_bake_noise(job) || fluid_is_bake_all(job)) {
- BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE, NULL);
+ BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE);
BLI_path_abs(temp_dir, relbase);
BLI_dir_create_recursive(temp_dir); /* Create 'noise' subdir if it does not exist already */
fds->cache_flag &= ~(FLUID_DOMAIN_BAKED_NOISE | FLUID_DOMAIN_OUTDATED_NOISE);
@@ -376,7 +376,7 @@ static void fluid_bake_startjob(void *customdata, short *stop, short *do_update,
job->pause_frame = &fds->cache_frame_pause_noise;
}
if (fluid_is_bake_mesh(job) || fluid_is_bake_all(job)) {
- BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_MESH, NULL);
+ BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_MESH);
BLI_path_abs(temp_dir, relbase);
BLI_dir_create_recursive(temp_dir); /* Create 'mesh' subdir if it does not exist already */
fds->cache_flag &= ~(FLUID_DOMAIN_BAKED_MESH | FLUID_DOMAIN_OUTDATED_MESH);
@@ -384,8 +384,7 @@ static void fluid_bake_startjob(void *customdata, short *stop, short *do_update,
job->pause_frame = &fds->cache_frame_pause_mesh;
}
if (fluid_is_bake_particle(job) || fluid_is_bake_all(job)) {
- BLI_path_join(
- temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_PARTICLES, NULL);
+ BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_PARTICLES);
BLI_path_abs(temp_dir, relbase);
/* Create 'particles' subdir if it does not exist already */
@@ -396,7 +395,7 @@ static void fluid_bake_startjob(void *customdata, short *stop, short *do_update,
job->pause_frame = &fds->cache_frame_pause_particles;
}
if (fluid_is_bake_guiding(job) || fluid_is_bake_all(job)) {
- BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_GUIDE, NULL);
+ BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_GUIDE);
BLI_path_abs(temp_dir, relbase);
BLI_dir_create_recursive(temp_dir); /* Create 'guiding' subdir if it does not exist already */
fds->cache_flag &= ~(FLUID_DOMAIN_BAKED_GUIDE | FLUID_DOMAIN_OUTDATED_GUIDE);
@@ -404,11 +403,11 @@ static void fluid_bake_startjob(void *customdata, short *stop, short *do_update,
job->pause_frame = &fds->cache_frame_pause_guide;
}
if (fluid_is_bake_data(job) || fluid_is_bake_all(job)) {
- BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_CONFIG, NULL);
+ BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_CONFIG);
BLI_path_abs(temp_dir, relbase);
BLI_dir_create_recursive(temp_dir); /* Create 'config' subdir if it does not exist already */
- BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_DATA, NULL);
+ BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_DATA);
BLI_path_abs(temp_dir, relbase);
BLI_dir_create_recursive(temp_dir); /* Create 'data' subdir if it does not exist already */
fds->cache_flag &= ~(FLUID_DOMAIN_BAKED_DATA | FLUID_DOMAIN_OUTDATED_DATA);
@@ -416,8 +415,7 @@ static void fluid_bake_startjob(void *customdata, short *stop, short *do_update,
job->pause_frame = &fds->cache_frame_pause_data;
if (fds->flags & FLUID_DOMAIN_EXPORT_MANTA_SCRIPT) {
- BLI_path_join(
- temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, NULL);
+ BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT);
BLI_path_abs(temp_dir, relbase);
BLI_dir_create_recursive(temp_dir); /* Create 'script' subdir if it does not exist already */
}
@@ -430,7 +428,7 @@ static void fluid_bake_startjob(void *customdata, short *stop, short *do_update,
*do_update = true;
}
if (stop) {
- *stop = 0;
+ *stop = false;
}
}
@@ -463,7 +461,7 @@ static void fluid_free_endjob(void *customdata)
}
}
-static void fluid_free_startjob(void *customdata, short *stop, short *do_update, float *progress)
+static void fluid_free_startjob(void *customdata, bool *stop, bool *do_update, float *progress)
{
FluidJob *job = customdata;
FluidDomainSettings *fds = job->fmd->domain;
@@ -506,7 +504,7 @@ static void fluid_free_startjob(void *customdata, short *stop, short *do_update,
#endif
*do_update = true;
- *stop = 0;
+ *stop = false;
/* Update scene so that viewport shows freed up scene */
ED_update_for_newframe(job->bmain, job->depsgraph);
diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c
index 97cd0d1d149..9fac93187ee 100644
--- a/source/blender/editors/physics/physics_pointcache.c
+++ b/source/blender/editors/physics/physics_pointcache.c
@@ -86,7 +86,7 @@ static bool ptcache_add_remove_poll(bContext *C)
typedef struct PointCacheJob {
wmWindowManager *wm;
void *owner;
- short *stop, *do_update;
+ bool *stop, *do_update;
float *progress;
PTCacheBaker *baker;
@@ -126,7 +126,7 @@ static void ptcache_job_update(void *customdata, float progress, int *cancel)
*(job->progress) = progress;
}
-static void ptcache_job_startjob(void *customdata, short *stop, short *do_update, float *progress)
+static void ptcache_job_startjob(void *customdata, bool *stop, bool *do_update, float *progress)
{
PointCacheJob *job = customdata;
@@ -144,7 +144,7 @@ static void ptcache_job_startjob(void *customdata, short *stop, short *do_update
BKE_ptcache_bake(job->baker);
*do_update = true;
- *stop = 0;
+ *stop = false;
}
static void ptcache_job_endjob(void *customdata)
diff --git a/source/blender/editors/physics/rigidbody_constraint.c b/source/blender/editors/physics/rigidbody_constraint.c
index 3cd2a7dbd29..10d97b02066 100644
--- a/source/blender/editors/physics/rigidbody_constraint.c
+++ b/source/blender/editors/physics/rigidbody_constraint.c
@@ -123,6 +123,7 @@ static int rigidbody_con_add_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
int type = RNA_enum_get(op->ptr, "type");
bool changed;
@@ -175,6 +176,7 @@ static int rigidbody_con_remove_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
/* apply to active object */
diff --git a/source/blender/editors/render/render_internal.cc b/source/blender/editors/render/render_internal.cc
index 7583d329de1..5abf5867f92 100644
--- a/source/blender/editors/render/render_internal.cc
+++ b/source/blender/editors/render/render_internal.cc
@@ -32,6 +32,7 @@
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_image_format.h"
+#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_node.h"
@@ -68,7 +69,7 @@
#include "render_intern.hh"
/* Render Callbacks */
-static int render_break(void *rjv);
+static bool render_break(void *rjv);
struct RenderJob {
Main *main;
@@ -86,8 +87,8 @@ struct RenderJob {
Image *image;
ImageUser iuser;
bool image_outdated;
- short *stop;
- short *do_update;
+ bool *stop;
+ bool *do_update;
float *progress;
ReportList *reports;
int orig_layer;
@@ -404,56 +405,57 @@ static void make_renderinfo_string(const RenderStats *rs,
/* local view */
if (rs->localview) {
- spos += sprintf(spos, "%s | ", TIP_("3D Local View"));
+ spos += BLI_sprintf(spos, "%s | ", TIP_("3D Local View"));
}
else if (v3d_override) {
- spos += sprintf(spos, "%s | ", TIP_("3D View"));
+ spos += BLI_sprintf(spos, "%s | ", TIP_("3D View"));
}
/* frame number */
- spos += sprintf(spos, TIP_("Frame:%d "), (scene->r.cfra));
+ spos += BLI_sprintf(spos, TIP_("Frame:%d "), (scene->r.cfra));
/* previous and elapsed time */
BLI_timecode_string_from_time_simple(info_time_str, sizeof(info_time_str), rs->lastframetime);
if (rs->infostr && rs->infostr[0]) {
if (rs->lastframetime != 0.0) {
- spos += sprintf(spos, TIP_("| Last:%s "), info_time_str);
+ spos += BLI_sprintf(spos, TIP_("| Last:%s "), info_time_str);
}
else {
- spos += sprintf(spos, "| ");
+ spos += BLI_sprintf(spos, "| ");
}
BLI_timecode_string_from_time_simple(
info_time_str, sizeof(info_time_str), PIL_check_seconds_timer() - rs->starttime);
}
else {
- spos += sprintf(spos, "| ");
+ spos += BLI_sprintf(spos, "| ");
}
- spos += sprintf(spos, TIP_("Time:%s "), info_time_str);
+ spos += BLI_sprintf(spos, TIP_("Time:%s "), info_time_str);
/* statistics */
if (rs->statstr) {
if (rs->statstr[0]) {
- spos += sprintf(spos, "| %s ", rs->statstr);
+ spos += BLI_sprintf(spos, "| %s ", rs->statstr);
}
}
else {
if (rs->mem_peak == 0.0f) {
- spos += sprintf(spos, TIP_("| Mem:%.2fM (Peak %.2fM) "), megs_used_memory, megs_peak_memory);
+ spos += BLI_sprintf(
+ spos, TIP_("| Mem:%.2fM (Peak %.2fM) "), megs_used_memory, megs_peak_memory);
}
else {
- spos += sprintf(spos, TIP_("| Mem:%.2fM, Peak: %.2fM "), rs->mem_used, rs->mem_peak);
+ spos += BLI_sprintf(spos, TIP_("| Mem:%.2fM, Peak: %.2fM "), rs->mem_used, rs->mem_peak);
}
}
/* extra info */
if (rs->infostr && rs->infostr[0]) {
- spos += sprintf(spos, "| %s ", rs->infostr);
+ spos += BLI_sprintf(spos, "| %s ", rs->infostr);
}
else if (error && error[0]) {
- spos += sprintf(spos, "| %s ", error);
+ spos += BLI_sprintf(spos, "| %s ", error);
}
/* very weak... but 512 characters is quite safe */
@@ -636,7 +638,7 @@ static void current_scene_update(void *rjv, Scene *scene)
rj->iuser.scene = scene;
}
-static void render_startjob(void *rjv, short *stop, short *do_update, float *progress)
+static void render_startjob(void *rjv, bool *stop, bool *do_update, float *progress)
{
RenderJob *rj = static_cast<RenderJob *>(rjv);
@@ -790,29 +792,29 @@ static void render_endjob(void *rjv)
}
/* called by render, check job 'stop' value or the global */
-static int render_breakjob(void *rjv)
+static bool render_breakjob(void *rjv)
{
RenderJob *rj = static_cast<RenderJob *>(rjv);
if (G.is_break) {
- return 1;
+ return true;
}
if (rj->stop && *(rj->stop)) {
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/**
* For exec() when there is no render job
* NOTE: this won't check for the escape key being pressed, but doing so isn't thread-safe.
*/
-static int render_break(void *UNUSED(rjv))
+static bool render_break(void * /*rjv*/)
{
if (G.is_break) {
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/* runs in thread, no cursor setting here works. careful with notifiers too (malloc conflicts) */
@@ -885,9 +887,10 @@ static void clean_viewport_memory(Main *bmain, Scene *scene)
wm = static_cast<wmWindowManager *>(wm->id.next)) {
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ BKE_view_layer_synced_ensure(scene, view_layer);
- for (base = static_cast<Base *>(view_layer->object_bases.first); base; base = base->next) {
- clean_viewport_memory_base(base);
+ LISTBASE_FOREACH (Base *, b, BKE_view_layer_object_bases_get(view_layer)) {
+ clean_viewport_memory_base(b);
}
}
}
diff --git a/source/blender/editors/render/render_opengl.cc b/source/blender/editors/render/render_opengl.cc
index e91bffce2c2..d5e3d1171cd 100644
--- a/source/blender/editors/render/render_opengl.cc
+++ b/source/blender/editors/render/render_opengl.cc
@@ -1310,8 +1310,8 @@ static int screen_opengl_render_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static char *screen_opengl_render_description(struct bContext *UNUSED(C),
- struct wmOperatorType *UNUSED(ot),
+static char *screen_opengl_render_description(struct bContext * /*C*/,
+ struct wmOperatorType * /*ot*/,
struct PointerRNA *ptr)
{
if (!RNA_boolean_get(ptr, "animation")) {
diff --git a/source/blender/editors/render/render_preview.cc b/source/blender/editors/render/render_preview.cc
index aa05b2ff198..09394ea33be 100644
--- a/source/blender/editors/render/render_preview.cc
+++ b/source/blender/editors/render/render_preview.cc
@@ -104,7 +104,7 @@ static void icon_copy_rect(ImBuf *ibuf, uint w, uint h, uint *rect);
struct ShaderPreview {
/* from wmJob */
void *owner;
- short *stop, *do_update;
+ bool *stop, *do_update;
Scene *scene;
ID *id, *id_copy;
@@ -307,7 +307,8 @@ static void switch_preview_floor_visibility(Main *pr_main,
const ePreviewRenderMethod pr_method)
{
/* Hide floor for icon renders. */
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (STREQ(base->object->id.name + 2, "Floor")) {
base->object->visibility_flag &= ~OB_HIDE_RENDER;
if (pr_method == PR_ICON_RENDER) {
@@ -533,8 +534,8 @@ static Scene *preview_prepare_scene(
else {
sce->display.render_aa = SCE_DISPLAY_AA_OFF;
}
-
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(sce, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (base->object->id.name[2] == 'p') {
/* copy over object color, in case material uses it */
copy_v4_v4(base->object->color, sp->color);
@@ -586,7 +587,8 @@ static Scene *preview_prepare_scene(
sce->world->horb = 0.0f;
}
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(sce, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (base->object->id.name[2] == 'p') {
if (base->object->type == OB_LAMP) {
base->object->data = la;
@@ -628,10 +630,10 @@ static bool ed_preview_draw_rect(ScrArea *area, int split, int first, rcti *rect
bool ok = false;
if (!split || first) {
- sprintf(name, "Preview %p", (void *)area);
+ BLI_snprintf(name, sizeof(name), "Preview %p", (void *)area);
}
else {
- sprintf(name, "SecondPreview %p", (void *)area);
+ BLI_snprintf(name, sizeof(name), "SecondPreview %p", (void *)area);
}
if (split) {
@@ -775,14 +777,15 @@ static bool object_preview_is_type_supported(const Object *ob)
}
static Object *object_preview_camera_create(Main *preview_main,
+ Scene *scene,
ViewLayer *view_layer,
Object *preview_object)
{
- Object *camera = BKE_object_add(preview_main, view_layer, OB_CAMERA, "Preview Camera");
+ Object *camera = BKE_object_add(preview_main, scene, view_layer, OB_CAMERA, "Preview Camera");
float rotmat[3][3];
float dummyscale[3];
- mat4_to_loc_rot_size(camera->loc, rotmat, dummyscale, preview_object->obmat);
+ mat4_to_loc_rot_size(camera->loc, rotmat, dummyscale, preview_object->object_to_world);
/* Camera is Y up, so needs additional rotations to obliquely face the front. */
float drotmat[3][3];
@@ -817,13 +820,14 @@ static Scene *object_preview_scene_create(const struct ObjectPreviewData *previe
BKE_collection_object_add(preview_data->pr_main, scene->master_collection, preview_data->object);
Object *camera_object = object_preview_camera_create(
- preview_data->pr_main, view_layer, preview_data->object);
+ preview_data->pr_main, scene, view_layer, preview_data->object);
scene->camera = camera_object;
scene->r.xsch = preview_data->sizex;
scene->r.ysch = preview_data->sizey;
scene->r.size = 100;
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *preview_base = BKE_view_layer_base_find(view_layer, preview_data->object);
/* For 'view selected' below. */
preview_base->flag |= BASE_SELECTED;
@@ -1035,7 +1039,7 @@ static void action_preview_render(IconPreview *preview, IconPreviewSize *preview
* \{ */
/* inside thread, called by renderer, sets job update value */
-static void shader_preview_update(void *spv, RenderResult *UNUSED(rr), struct rcti *UNUSED(rect))
+static void shader_preview_update(void *spv, RenderResult * /*rr*/, struct rcti * /*rect*/)
{
ShaderPreview *sp = static_cast<ShaderPreview *>(spv);
@@ -1043,14 +1047,14 @@ static void shader_preview_update(void *spv, RenderResult *UNUSED(rr), struct rc
}
/* called by renderer, checks job value */
-static int shader_preview_break(void *spv)
+static bool shader_preview_break(void *spv)
{
ShaderPreview *sp = static_cast<ShaderPreview *>(spv);
return *(sp->stop);
}
-static void shader_preview_updatejob(void *UNUSED(spv))
+static void shader_preview_updatejob(void * /*spv*/)
{
}
@@ -1084,10 +1088,10 @@ static void shader_preview_texture(ShaderPreview *sp, Tex *tex, Scene *sce, Rend
for (int y = 0; y < height; y++) {
/* Tex coords between -1.0f and 1.0f. */
- tex_coord[1] = ((float)y / (float)height) * 2.0f - 1.0f;
+ tex_coord[1] = (float(y) / float(height)) * 2.0f - 1.0f;
for (int x = 0; x < width; x++) {
- tex_coord[0] = ((float)x / (float)height) * 2.0f - 1.0f;
+ tex_coord[0] = (float(x) / float(height)) * 2.0f - 1.0f;
/* Evaluate texture at tex_coord. */
TexResult texres = {0};
@@ -1148,10 +1152,10 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
}
if (!split || first) {
- sprintf(name, "Preview %p", sp->owner);
+ BLI_snprintf(name, sizeof(name), "Preview %p", sp->owner);
}
else {
- sprintf(name, "SecondPreview %p", sp->owner);
+ BLI_snprintf(name, sizeof(name), "SecondPreview %p", sp->owner);
}
re = RE_GetRender(name);
@@ -1182,7 +1186,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
/* lens adjust */
oldlens = ((Camera *)sce->camera->data)->lens;
if (sizex > sp->sizey) {
- ((Camera *)sce->camera->data)->lens *= (float)sp->sizey / (float)sizex;
+ ((Camera *)sce->camera->data)->lens *= float(sp->sizey) / float(sizex);
}
/* entire cycle for render engine */
@@ -1219,7 +1223,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
}
/* runs inside thread for material and icons */
-static void shader_preview_startjob(void *customdata, short *stop, short *do_update)
+static void shader_preview_startjob(void *customdata, bool *stop, bool *do_update)
{
ShaderPreview *sp = static_cast<ShaderPreview *>(customdata);
@@ -1321,7 +1325,7 @@ static ImBuf *icon_preview_imbuf_from_brush(Brush *brush)
const char *brushicons_dir = BKE_appdir_folder_id(BLENDER_DATAFILES, "brushicons");
/* Expected to be found, but don't crash if it's not. */
if (brushicons_dir) {
- BLI_join_dirfile(filepath, sizeof(filepath), brushicons_dir, brush->icon_filepath);
+ BLI_path_join(filepath, sizeof(filepath), brushicons_dir, brush->icon_filepath);
/* Use default color spaces. */
brush->icon_imbuf = IMB_loadiffname(filepath, flags, nullptr);
@@ -1360,17 +1364,17 @@ static void icon_copy_rect(ImBuf *ibuf, uint w, uint h, uint *rect)
}
if (ima->x > ima->y) {
- scaledx = (float)w;
- scaledy = ((float)ima->y / (float)ima->x) * (float)w;
+ scaledx = float(w);
+ scaledy = (float(ima->y) / float(ima->x)) * float(w);
}
else {
- scaledx = ((float)ima->x / (float)ima->y) * (float)h;
- scaledy = (float)h;
+ scaledx = (float(ima->x) / float(ima->y)) * float(h);
+ scaledy = float(h);
}
/* Scaling down must never assign zero width/height, see: T89868. */
- ex = MAX2(1, (short)scaledx);
- ey = MAX2(1, (short)scaledy);
+ ex = MAX2(1, short(scaledx));
+ ey = MAX2(1, short(scaledy));
dx = (w - ex) / 2;
dy = (h - ey) / 2;
@@ -1404,7 +1408,7 @@ static void set_alpha(char *cp, int sizex, int sizey, char alpha)
}
}
-static void icon_preview_startjob(void *customdata, short *stop, short *do_update)
+static void icon_preview_startjob(void *customdata, bool *stop, bool *do_update)
{
ShaderPreview *sp = static_cast<ShaderPreview *>(customdata);
@@ -1484,9 +1488,9 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat
* does not run two of them at the same time. */
static void common_preview_startjob(void *customdata,
- short *stop,
- short *do_update,
- float *UNUSED(progress))
+ bool *stop,
+ bool *do_update,
+ float * /*progress*/)
{
ShaderPreview *sp = static_cast<ShaderPreview *>(customdata);
@@ -1505,8 +1509,8 @@ static void common_preview_startjob(void *customdata,
static void other_id_types_preview_render(IconPreview *ip,
IconPreviewSize *cur_size,
const ePreviewRenderMethod pr_method,
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress)
{
ShaderPreview *sp = MEM_cnew<ShaderPreview>("Icon ShaderPreview");
@@ -1566,8 +1570,8 @@ static int icon_previewimg_size_index_get(const IconPreviewSize *icon_size,
}
static void icon_preview_startjob_all_sizes(void *customdata,
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress)
{
IconPreview *ip = (IconPreview *)customdata;
@@ -1731,7 +1735,7 @@ class PreviewLoadJob {
void push_load_request(PreviewImage *preview, eIconSizes icon_size);
private:
- static void run_fn(void *customdata, short *stop, short *do_update, float *progress);
+ static void run_fn(void *customdata, bool *stop, bool *do_update, float *progress);
static void update_fn(void *customdata);
static void end_fn(void *customdata);
static void free_fn(void *customdata);
@@ -1751,7 +1755,8 @@ PreviewLoadJob::~PreviewLoadJob()
PreviewLoadJob &PreviewLoadJob::ensure_job(wmWindowManager *wm, wmWindow *win)
{
- wmJob *wm_job = WM_jobs_get(wm, win, nullptr, "Load Previews", 0, WM_JOB_TYPE_LOAD_PREVIEW);
+ wmJob *wm_job = WM_jobs_get(
+ wm, win, nullptr, "Load Previews", eWM_JobFlag(0), WM_JOB_TYPE_LOAD_PREVIEW);
if (!WM_jobs_is_running(wm_job)) {
PreviewLoadJob *job_data = MEM_new<PreviewLoadJob>("PreviewLoadJobData");
@@ -1772,7 +1777,7 @@ void PreviewLoadJob::load_jobless(PreviewImage *preview, const eIconSizes icon_s
job_data.push_load_request(preview, icon_size);
- short stop = 0, do_update = 0;
+ bool stop = false, do_update = false;
float progress = 0;
run_fn(&job_data, &stop, &do_update, &progress);
update_fn(&job_data);
@@ -1794,10 +1799,7 @@ void PreviewLoadJob::push_load_request(PreviewImage *preview, const eIconSizes i
BLI_thread_queue_push(todo_queue_, &requested_previews_.back());
}
-void PreviewLoadJob::run_fn(void *customdata,
- short *stop,
- short *do_update,
- float *UNUSED(progress))
+void PreviewLoadJob::run_fn(void *customdata, bool *stop, bool *do_update, float * /*progress*/)
{
PreviewLoadJob *job_data = static_cast<PreviewLoadJob *>(customdata);
@@ -1935,7 +1937,7 @@ void ED_preview_icon_render(
}
IconPreview ip = {nullptr};
- short stop = false, update = false;
+ bool stop = false, update = false;
float progress = 0.0f;
ED_preview_ensure_dbase();
@@ -2105,7 +2107,7 @@ void ED_preview_shader_job(const bContext *C,
WM_jobs_start(CTX_wm_manager(C), wm_job);
}
-void ED_preview_kill_jobs(wmWindowManager *wm, Main *UNUSED(bmain))
+void ED_preview_kill_jobs(wmWindowManager *wm, Main * /*bmain*/)
{
if (wm) {
/* This is called to stop all preview jobs before scene data changes, to
diff --git a/source/blender/editors/render/render_shading.cc b/source/blender/editors/render/render_shading.cc
index f784346ec8f..e5c2b9702e5 100644
--- a/source/blender/editors/render/render_shading.cc
+++ b/source/blender/editors/render/render_shading.cc
@@ -163,7 +163,7 @@ static bool object_materials_supported_poll(bContext *C)
/** \name Material Slot Add Operator
* \{ */
-static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op))
+static int material_slot_add_exec(bContext *C, wmOperator * /*op*/)
{
Main *bmain = CTX_data_main(C);
Object *ob = ED_object_context(C);
@@ -259,7 +259,7 @@ void OBJECT_OT_material_slot_remove(wmOperatorType *ot)
/** \name Material Slot Assign Operator
* \{ */
-static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
+static int material_slot_assign_exec(bContext *C, wmOperator * /*op*/)
{
View3D *v3d = CTX_wm_view3d(C);
bool changed_multi = false;
@@ -475,7 +475,7 @@ static int material_slot_de_select(bContext *C, bool select)
return (changed_multi) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
-static int material_slot_select_exec(bContext *C, wmOperator *UNUSED(op))
+static int material_slot_select_exec(bContext *C, wmOperator * /*op*/)
{
return material_slot_de_select(C, true);
}
@@ -494,7 +494,7 @@ void OBJECT_OT_material_slot_select(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
-static int material_slot_deselect_exec(bContext *C, wmOperator *UNUSED(op))
+static int material_slot_deselect_exec(bContext *C, wmOperator * /*op*/)
{
return material_slot_de_select(C, false);
}
@@ -519,7 +519,7 @@ void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
/** \name Material Slot Copy Operator
* \{ */
-static int material_slot_copy_exec(bContext *C, wmOperator *UNUSED(op))
+static int material_slot_copy_exec(bContext *C, wmOperator * /*op*/)
{
Main *bmain = CTX_data_main(C);
Object *ob = ED_object_context(C);
@@ -534,7 +534,7 @@ static int material_slot_copy_exec(bContext *C, wmOperator *UNUSED(op))
Material ***matar_object = &ob->mat;
Material **matar = static_cast<Material **>(
- MEM_callocN(sizeof(*matar) * (size_t)ob->totcol, __func__));
+ MEM_callocN(sizeof(*matar) * size_t(ob->totcol), __func__));
for (int i = ob->totcol; i--;) {
matar[i] = ob->matbits[i] ? (*matar_object)[i] : (*matar_obdata)[i];
}
@@ -736,7 +736,7 @@ void OBJECT_OT_material_slot_remove_unused(wmOperatorType *ot)
/** \name New Material Operator
* \{ */
-static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
+static int new_material_exec(bContext *C, wmOperator * /*op*/)
{
Material *ma = static_cast<Material *>(
CTX_data_pointer_get_type(C, "material", &RNA_Material).data);
@@ -812,7 +812,7 @@ void MATERIAL_OT_new(wmOperatorType *ot)
/** \name New Texture Operator
* \{ */
-static int new_texture_exec(bContext *C, wmOperator *UNUSED(op))
+static int new_texture_exec(bContext *C, wmOperator * /*op*/)
{
Tex *tex = static_cast<Tex *>(CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data);
Main *bmain = CTX_data_main(C);
@@ -865,7 +865,7 @@ void TEXTURE_OT_new(wmOperatorType *ot)
/** \name new world operator
* \{ */
-static int new_world_exec(bContext *C, wmOperator *UNUSED(op))
+static int new_world_exec(bContext *C, wmOperator * /*op*/)
{
World *wo = static_cast<World *>(CTX_data_pointer_get_type(C, "world", &RNA_World).data);
Main *bmain = CTX_data_main(C);
@@ -879,7 +879,7 @@ static int new_world_exec(bContext *C, wmOperator *UNUSED(op))
wo = new_wo;
}
else {
- wo = BKE_world_add(bmain, DATA_("World"));
+ wo = BKE_world_add(bmain, CTX_DATA_(BLT_I18NCONTEXT_ID_WORLD, "World"));
ED_node_shader_default(C, &wo->id);
wo->use_nodes = true;
}
@@ -982,7 +982,7 @@ static bool view_layer_remove_poll(bContext *C)
return (scene->view_layers.first != scene->view_layers.last);
}
-static int view_layer_remove_exec(bContext *C, wmOperator *UNUSED(op))
+static int view_layer_remove_exec(bContext *C, wmOperator * /*op*/)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -1018,7 +1018,7 @@ void SCENE_OT_view_layer_remove(wmOperatorType *ot)
/** \name View Layer Add AOV Operator
* \{ */
-static int view_layer_add_aov_exec(bContext *C, wmOperator *UNUSED(op))
+static int view_layer_add_aov_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1066,7 +1066,7 @@ void SCENE_OT_view_layer_add_aov(wmOperatorType *ot)
/** \name View Layer Remove AOV Operator
* \{ */
-static int view_layer_remove_aov_exec(bContext *C, wmOperator *UNUSED(op))
+static int view_layer_remove_aov_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1131,7 +1131,7 @@ static int view_layer_add_lightgroup_exec(bContext *C, wmOperator *op)
/* Ensure that there are no dots in the name. */
BLI_str_replace_char(name, '.', '_');
LISTBASE_FOREACH (ViewLayerLightgroup *, lightgroup, &view_layer->lightgroups) {
- if (strcmp(lightgroup->name, name) == 0) {
+ if (STREQ(lightgroup->name, name)) {
return OPERATOR_CANCELLED;
}
}
@@ -1178,7 +1178,7 @@ void SCENE_OT_view_layer_add_lightgroup(wmOperatorType *ot)
/** \name View Layer Remove Lightgroup Operator
* \{ */
-static int view_layer_remove_lightgroup_exec(bContext *C, wmOperator *UNUSED(op))
+static int view_layer_remove_lightgroup_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1238,7 +1238,7 @@ static GSet *get_used_lightgroups(Scene *scene)
return used_lightgroups;
}
-static int view_layer_add_used_lightgroups_exec(bContext *C, wmOperator *UNUSED(op))
+static int view_layer_add_used_lightgroups_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1284,7 +1284,7 @@ void SCENE_OT_view_layer_add_used_lightgroups(wmOperatorType *ot)
/** \name View Layer Remove Unused Lightgroups Operator
* \{ */
-static int view_layer_remove_unused_lightgroups_exec(bContext *C, wmOperator *UNUSED(op))
+static int view_layer_remove_unused_lightgroups_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1398,7 +1398,7 @@ static int light_cache_bake_exec(bContext *C, wmOperator *op)
light_cache_bake_tag_cache(scene, op);
- short stop = 0, do_update;
+ bool stop = false, do_update;
float progress; /* Not actually used. */
EEVEE_lightbake_job(rj, &stop, &do_update, &progress);
EEVEE_lightbake_job_data_free(rj);
@@ -1411,7 +1411,7 @@ static int light_cache_bake_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int light_cache_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int light_cache_bake_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
@@ -1505,7 +1505,7 @@ static bool light_cache_free_poll(bContext *C)
return scene->eevee.light_cache_data;
}
-static int light_cache_free_exec(bContext *C, wmOperator *UNUSED(op))
+static int light_cache_free_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
@@ -1555,7 +1555,7 @@ static bool render_view_remove_poll(bContext *C)
return scene->r.actview > 1;
}
-static int render_view_add_exec(bContext *C, wmOperator *UNUSED(op))
+static int render_view_add_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
@@ -1587,7 +1587,7 @@ void SCENE_OT_render_view_add(wmOperatorType *ot)
/** \name Render View Add Operator
* \{ */
-static int render_view_remove_exec(bContext *C, wmOperator *UNUSED(op))
+static int render_view_remove_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
SceneRenderView *rv = static_cast<SceneRenderView *>(
@@ -1651,7 +1651,7 @@ static bool freestyle_active_module_poll(bContext *C)
return module != nullptr;
}
-static int freestyle_module_add_exec(bContext *C, wmOperator *UNUSED(op))
+static int freestyle_module_add_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1683,7 +1683,7 @@ void SCENE_OT_freestyle_module_add(wmOperatorType *ot)
/** \name Free Style Module Remove Operator
* \{ */
-static int freestyle_module_remove_exec(bContext *C, wmOperator *UNUSED(op))
+static int freestyle_module_remove_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1770,7 +1770,7 @@ void SCENE_OT_freestyle_module_move(wmOperatorType *ot)
/** \name Free Style Line Set Add Operator
* \{ */
-static int freestyle_lineset_add_exec(bContext *C, wmOperator *UNUSED(op))
+static int freestyle_lineset_add_exec(bContext *C, wmOperator * /*op*/)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -1815,7 +1815,7 @@ static bool freestyle_active_lineset_poll(bContext *C)
return BKE_freestyle_lineset_get_active(&view_layer->freestyle_config) != nullptr;
}
-static int freestyle_lineset_copy_exec(bContext *C, wmOperator *UNUSED(op))
+static int freestyle_lineset_copy_exec(bContext *C, wmOperator * /*op*/)
{
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1845,7 +1845,7 @@ void SCENE_OT_freestyle_lineset_copy(wmOperatorType *ot)
/** \name Free Style Line Set Paste Operator
* \{ */
-static int freestyle_lineset_paste_exec(bContext *C, wmOperator *UNUSED(op))
+static int freestyle_lineset_paste_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1879,7 +1879,7 @@ void SCENE_OT_freestyle_lineset_paste(wmOperatorType *ot)
/** \name Free Style Line Set Remove Operator
* \{ */
-static int freestyle_lineset_remove_exec(bContext *C, wmOperator *UNUSED(op))
+static int freestyle_lineset_remove_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -2517,7 +2517,7 @@ void TEXTURE_OT_slot_move(wmOperatorType *ot)
* \{ */
/* material copy/paste */
-static int copy_material_exec(bContext *C, wmOperator *UNUSED(op))
+static int copy_material_exec(bContext *C, wmOperator * /*op*/)
{
Material *ma = static_cast<Material *>(
CTX_data_pointer_get_type(C, "material", &RNA_Material).data);
@@ -2552,7 +2552,7 @@ void MATERIAL_OT_copy(wmOperatorType *ot)
/** \name Material Paste Operator
* \{ */
-static int paste_material_exec(bContext *C, wmOperator *UNUSED(op))
+static int paste_material_exec(bContext *C, wmOperator * /*op*/)
{
Material *ma = static_cast<Material *>(
CTX_data_pointer_get_type(C, "material", &RNA_Material).data);
@@ -2661,7 +2661,7 @@ static void paste_mtex_copybuf(ID *id)
/** \name Texture Slot Copy Operator
* \{ */
-static int copy_mtex_exec(bContext *C, wmOperator *UNUSED(op))
+static int copy_mtex_exec(bContext *C, wmOperator * /*op*/)
{
ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).owner_id;
@@ -2705,7 +2705,7 @@ void TEXTURE_OT_slot_copy(wmOperatorType *ot)
/** \name Texture Slot Paste Operator
* \{ */
-static int paste_mtex_exec(bContext *C, wmOperator *UNUSED(op))
+static int paste_mtex_exec(bContext *C, wmOperator * /*op*/)
{
ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).owner_id;
diff --git a/source/blender/editors/render/render_update.cc b/source/blender/editors/render/render_update.cc
index 7cefcf9815e..8aadb9edf6a 100644
--- a/source/blender/editors/render/render_update.cc
+++ b/source/blender/editors/render/render_update.cc
@@ -226,13 +226,13 @@ void ED_render_view_layer_changed(Main *bmain, bScreen *screen)
* we can get rid of the manual dependency checks.
* \{ */
-static void material_changed(Main *UNUSED(bmain), Material *ma)
+static void material_changed(Main * /*bmain*/, Material *ma)
{
/* icons */
BKE_icon_changed(BKE_icon_id_ensure(&ma->id));
}
-static void lamp_changed(Main *UNUSED(bmain), Light *la)
+static void lamp_changed(Main * /*bmain*/, Light *la)
{
/* icons */
BKE_icon_changed(BKE_icon_id_ensure(&la->id));
@@ -265,7 +265,7 @@ static void texture_changed(Main *bmain, Tex *tex)
}
}
-static void world_changed(Main *UNUSED(bmain), World *wo)
+static void world_changed(Main * /*bmain*/, World *wo)
{
/* icons */
BKE_icon_changed(BKE_icon_id_ensure(&wo->id));
diff --git a/source/blender/editors/render/render_view.cc b/source/blender/editors/render/render_view.cc
index 9a16c910205..f0427bf8683 100644
--- a/source/blender/editors/render/render_view.cc
+++ b/source/blender/editors/render/render_view.cc
@@ -74,7 +74,7 @@ static ScrArea *find_area_showing_r_result(bContext *C, Scene *scene, wmWindow *
ScrArea *area = nullptr;
SpaceImage *sima;
- /* find an imagewindow showing render result */
+ /* find an image-window showing render result */
for (*win = static_cast<wmWindow *>(wm->windows.first); *win; *win = (*win)->next) {
if (WM_window_get_active_scene(*win) == scene) {
const bScreen *screen = WM_window_get_active_screen(*win);
@@ -102,7 +102,7 @@ static ScrArea *find_area_image_empty(bContext *C)
ScrArea *area;
SpaceImage *sima;
- /* find an imagewindow showing render result */
+ /* find an image-window showing render result */
for (area = static_cast<ScrArea *>(screen->areabase.first); area; area = area->next) {
if (area->spacetype == SPACE_IMAGE) {
sima = static_cast<SpaceImage *>(area->spacedata.first);
@@ -256,7 +256,7 @@ ScrArea *render_view_open(bContext *C, int mx, int my, ReportList *reports)
/*************************** cancel render viewer **********************/
-static int render_view_cancel_exec(bContext *C, wmOperator *UNUSED(op))
+static int render_view_cancel_exec(bContext *C, wmOperator * /*op*/)
{
wmWindow *win = CTX_wm_window(C);
ScrArea *area = CTX_wm_area(C);
diff --git a/source/blender/editors/scene/scene_edit.c b/source/blender/editors/scene/scene_edit.c
index 07a93d3907a..01877deb716 100644
--- a/source/blender/editors/scene/scene_edit.c
+++ b/source/blender/editors/scene/scene_edit.c
@@ -286,6 +286,7 @@ static void SCENE_OT_new(wmOperatorType *ot)
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", scene_new_items, SCE_COPY_NEW, "Type", "");
+ RNA_def_property_translation_context(ot->prop, BLT_I18NCONTEXT_ID_SCENE);
}
/** \} */
@@ -333,7 +334,7 @@ static const EnumPropertyItem *scene_new_sequencer_enum_itemf(bContext *C,
else {
Scene *scene = CTX_data_scene(C);
Sequence *seq = SEQ_select_active_get(scene);
- if ((seq && (seq->type == SEQ_TYPE_SCENE) && (seq->scene != NULL))) {
+ if (seq && (seq->type == SEQ_TYPE_SCENE) && (seq->scene != NULL)) {
has_scene_or_no_context = true;
}
}
diff --git a/source/blender/editors/screen/CMakeLists.txt b/source/blender/editors/screen/CMakeLists.txt
index 119758f3335..bde73402277 100644
--- a/source/blender/editors/screen/CMakeLists.txt
+++ b/source/blender/editors/screen/CMakeLists.txt
@@ -34,6 +34,7 @@ set(SRC
screendump.c
workspace_edit.c
workspace_layout_edit.c
+ workspace_listen.cc
screen_intern.h
)
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 4e99e384f9f..a62e027ba03 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -147,7 +147,7 @@ void ED_region_do_listen(wmRegionListenerParams *params)
}
LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
- UI_block_views_listen(block, params);
+ UI_block_listen(block, params);
}
LISTBASE_FOREACH (uiList *, list, &region->ui_lists) {
@@ -175,7 +175,7 @@ void ED_area_do_refresh(bContext *C, ScrArea *area)
}
/**
- * \brief Corner widget use for quitting fullscreen.
+ * \brief Corner widget use for quitting full-screen.
*/
static void area_draw_azone_fullscreen(
short UNUSED(x1), short UNUSED(y1), short x2, short y2, float alpha)
@@ -187,7 +187,8 @@ static void area_draw_azone_fullscreen(
min_ff(alpha, 0.75f),
0.0f,
NULL,
- false);
+ false,
+ UI_NO_ICON_OVERLAY_TEXT);
}
/**
@@ -845,7 +846,7 @@ void ED_workspace_status_text(bContext *C, const char *str)
static void area_azone_init(wmWindow *win, const bScreen *screen, ScrArea *area)
{
- /* reinitialize entirely, regions and fullscreen add azones too */
+ /* reinitialize entirely, regions and full-screen add azones too */
BLI_freelistN(&area->actionzones);
if (screen->state != SCREENNORMAL) {
@@ -1902,6 +1903,7 @@ void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area)
{
WorkSpace *workspace = WM_window_get_active_workspace(win);
const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
if (ED_area_is_global(area) && (area->global->flag & GLOBAL_AREA_IS_HIDDEN)) {
@@ -1966,7 +1968,7 @@ void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area)
/* Avoid re-initializing tools while resizing the window. */
if ((G.moving & G_TRANSFORM_WM) == 0) {
if ((1 << area->spacetype) & WM_TOOLSYSTEM_SPACE_MASK) {
- WM_toolsystem_refresh_screen_area(workspace, view_layer, area);
+ WM_toolsystem_refresh_screen_area(workspace, scene, view_layer, area);
area->flag |= AREA_FLAG_ACTIVE_TOOL_UPDATE;
}
else {
@@ -2577,8 +2579,8 @@ void ED_area_prevspace(bContext *C, ScrArea *area)
/* no change */
return;
}
- /* If this is a stacked fullscreen, changing to previous area exits it (meaning we're still in a
- * fullscreen, but not in a stacked one). */
+ /* If this is a stacked full-screen, changing to previous area exits it (meaning we're still in a
+ * full-screen, but not in a stacked one). */
area->flag &= ~AREA_FLAG_STACKED_FULLSCREEN;
ED_area_tag_redraw(area);
@@ -3793,7 +3795,7 @@ void ED_region_cache_draw_curfra_label(const int framenr, const float x, const f
float font_dims[2] = {0.0f, 0.0f};
/* frame number */
- BLF_size(fontid, 11.0f * U.pixelsize, U.dpi);
+ BLF_size(fontid, 11.0f * U.dpi_fac);
BLI_snprintf(numstr, sizeof(numstr), "%d", framenr);
BLF_width_and_height(fontid, numstr, sizeof(numstr), &font_dims[0], &font_dims[1]);
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index 7bdae1464c0..ffd76e70eb8 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -129,9 +129,11 @@ static eContextResult screen_ctx_visible_objects(const bContext *C, bContextData
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C); /* This may be NULL in a lot of cases. */
+ Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ BKE_view_layer_synced_ensure(scene, view_layer);
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (BASE_VISIBLE(v3d, base)) {
CTX_data_id_list_add(result, &base->object->id);
}
@@ -143,9 +145,11 @@ static eContextResult screen_ctx_selectable_objects(const bContext *C, bContextD
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C); /* This may be NULL in a lot of cases. */
+ Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ BKE_view_layer_synced_ensure(scene, view_layer);
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (BASE_SELECTABLE(v3d, base)) {
CTX_data_id_list_add(result, &base->object->id);
}
@@ -157,9 +161,11 @@ static eContextResult screen_ctx_selected_objects(const bContext *C, bContextDat
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C); /* This may be NULL in a lot of cases. */
+ Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ BKE_view_layer_synced_ensure(scene, view_layer);
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (BASE_SELECTED(v3d, base)) {
CTX_data_id_list_add(result, &base->object->id);
}
@@ -172,9 +178,11 @@ static eContextResult screen_ctx_selected_editable_objects(const bContext *C,
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C); /* This may be NULL in a lot of cases. */
+ Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ BKE_view_layer_synced_ensure(scene, view_layer);
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (BASE_SELECTED_EDITABLE(v3d, base)) {
CTX_data_id_list_add(result, &base->object->id);
}
@@ -186,10 +194,12 @@ static eContextResult screen_ctx_editable_objects(const bContext *C, bContextDat
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C); /* This may be NULL in a lot of cases. */
+ Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ BKE_view_layer_synced_ensure(scene, view_layer);
/* Visible + Editable, but not necessarily selected */
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (BASE_EDITABLE(v3d, base)) {
CTX_data_id_list_add(result, &base->object->id);
}
@@ -201,11 +211,13 @@ static eContextResult screen_ctx_objects_in_mode(const bContext *C, bContextData
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C); /* This may be NULL in a lot of cases. */
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
if (obact && (obact->mode != OB_MODE_OBJECT)) {
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, obact->type, obact->mode, ob_iter) {
CTX_data_id_list_add(result, &ob_iter->id);
}
FOREACH_OBJECT_IN_MODE_END;
@@ -218,15 +230,17 @@ static eContextResult screen_ctx_objects_in_mode_unique_data(const bContext *C,
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C); /* This may be NULL in a lot of cases. */
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
if (obact && (obact->mode != OB_MODE_OBJECT)) {
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, obact->type, obact->mode, ob_iter) {
ob_iter->id.tag |= LIB_TAG_DOIT;
}
FOREACH_OBJECT_IN_MODE_END;
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, obact->type, obact->mode, ob_iter) {
if (ob_iter->id.tag & LIB_TAG_DOIT) {
ob_iter->id.tag &= ~LIB_TAG_DOIT;
CTX_data_id_list_add(result, &ob_iter->id);
@@ -242,7 +256,9 @@ static eContextResult screen_ctx_visible_or_editable_bones_(const bContext *C,
const bool editable_bones)
{
wmWindow *win = CTX_wm_window(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
@@ -251,7 +267,7 @@ static eContextResult screen_ctx_visible_or_editable_bones_(const bContext *C,
if (arm && arm->edbo) {
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint i = 0; i < objects_len; i++) {
Object *ob = objects[i];
arm = ob->data;
@@ -313,7 +329,9 @@ static eContextResult screen_ctx_selected_bones_(const bContext *C,
const bool selected_editable_bones)
{
wmWindow *win = CTX_wm_window(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
EditBone *flipbone = NULL;
@@ -321,7 +339,7 @@ static eContextResult screen_ctx_selected_bones_(const bContext *C,
if (arm && arm->edbo) {
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint i = 0; i < objects_len; i++) {
Object *ob = objects[i];
arm = ob->data;
@@ -383,8 +401,10 @@ static eContextResult screen_ctx_visible_pose_bones(const bContext *C, bContextD
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C); /* This may be NULL in a lot of cases. */
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
Object *obpose = BKE_object_pose_armature_get(obact);
if (obpose && obpose->pose && obpose->data) {
if (obpose != obact) {
@@ -394,7 +414,7 @@ static eContextResult screen_ctx_visible_pose_bones(const bContext *C, bContextD
FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
}
else if (obact->mode & OB_MODE_POSE) {
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) {
FOREACH_PCHAN_VISIBLE_IN_OBJECT_BEGIN (ob_iter, pchan) {
CTX_data_list_add(result, &ob_iter->id, &RNA_PoseBone, pchan);
}
@@ -411,8 +431,9 @@ static eContextResult screen_ctx_selected_pose_bones(const bContext *C, bContext
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C); /* This may be NULL in a lot of cases. */
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
Object *obpose = BKE_object_pose_armature_get(obact);
if (obpose && obpose->pose && obpose->data) {
if (obpose != obact) {
@@ -422,7 +443,7 @@ static eContextResult screen_ctx_selected_pose_bones(const bContext *C, bContext
FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
}
else if (obact->mode & OB_MODE_POSE) {
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) {
FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan) {
CTX_data_list_add(result, &ob_iter->id, &RNA_PoseBone, pchan);
}
@@ -439,8 +460,10 @@ static eContextResult screen_ctx_selected_pose_bones_from_active_object(const bC
bContextDataResult *result)
{
wmWindow *win = CTX_wm_window(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
Object *obpose = BKE_object_pose_armature_get(obact);
if (obpose && obpose->pose && obpose->data) {
if (obpose != obact) {
@@ -463,8 +486,10 @@ static eContextResult screen_ctx_selected_pose_bones_from_active_object(const bC
static eContextResult screen_ctx_active_bone(const bContext *C, bContextDataResult *result)
{
wmWindow *win = CTX_wm_window(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
if (obact && obact->type == OB_ARMATURE) {
bArmature *arm = obact->data;
if (arm->edbo) {
@@ -485,8 +510,10 @@ static eContextResult screen_ctx_active_bone(const bContext *C, bContextDataResu
static eContextResult screen_ctx_active_pose_bone(const bContext *C, bContextDataResult *result)
{
wmWindow *win = CTX_wm_window(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
Object *obpose = BKE_object_pose_armature_get(obact);
bPoseChannel *pchan = BKE_pose_channel_active_if_layer_visible(obpose);
@@ -499,8 +526,10 @@ static eContextResult screen_ctx_active_pose_bone(const bContext *C, bContextDat
static eContextResult screen_ctx_active_object(const bContext *C, bContextDataResult *result)
{
wmWindow *win = CTX_wm_window(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
if (obact) {
CTX_data_id_pointer_set(result, &obact->id);
@@ -511,8 +540,10 @@ static eContextResult screen_ctx_active_object(const bContext *C, bContextDataRe
static eContextResult screen_ctx_object(const bContext *C, bContextDataResult *result)
{
wmWindow *win = CTX_wm_window(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
if (obact) {
CTX_data_id_pointer_set(result, &obact->id);
@@ -523,7 +554,9 @@ static eContextResult screen_ctx_object(const bContext *C, bContextDataResult *r
static eContextResult screen_ctx_edit_object(const bContext *C, bContextDataResult *result)
{
wmWindow *win = CTX_wm_window(C);
+ Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
/* convenience for now, 1 object per scene in editmode */
if (obedit) {
@@ -535,8 +568,10 @@ static eContextResult screen_ctx_edit_object(const bContext *C, bContextDataResu
static eContextResult screen_ctx_sculpt_object(const bContext *C, bContextDataResult *result)
{
wmWindow *win = CTX_wm_window(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
if (obact && (obact->mode & OB_MODE_SCULPT)) {
CTX_data_id_pointer_set(result, &obact->id);
@@ -547,8 +582,10 @@ static eContextResult screen_ctx_sculpt_object(const bContext *C, bContextDataRe
static eContextResult screen_ctx_vertex_paint_object(const bContext *C, bContextDataResult *result)
{
wmWindow *win = CTX_wm_window(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
if (obact && (obact->mode & OB_MODE_VERTEX_PAINT)) {
CTX_data_id_pointer_set(result, &obact->id);
}
@@ -558,8 +595,10 @@ static eContextResult screen_ctx_vertex_paint_object(const bContext *C, bContext
static eContextResult screen_ctx_weight_paint_object(const bContext *C, bContextDataResult *result)
{
wmWindow *win = CTX_wm_window(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
if (obact && (obact->mode & OB_MODE_ALL_WEIGHT_PAINT)) {
CTX_data_id_pointer_set(result, &obact->id);
}
@@ -569,8 +608,10 @@ static eContextResult screen_ctx_weight_paint_object(const bContext *C, bContext
static eContextResult screen_ctx_image_paint_object(const bContext *C, bContextDataResult *result)
{
wmWindow *win = CTX_wm_window(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
if (obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) {
CTX_data_id_pointer_set(result, &obact->id);
}
@@ -581,8 +622,10 @@ static eContextResult screen_ctx_particle_edit_object(const bContext *C,
bContextDataResult *result)
{
wmWindow *win = CTX_wm_window(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT)) {
CTX_data_id_pointer_set(result, &obact->id);
}
@@ -592,8 +635,10 @@ static eContextResult screen_ctx_particle_edit_object(const bContext *C,
static eContextResult screen_ctx_pose_object(const bContext *C, bContextDataResult *result)
{
wmWindow *win = CTX_wm_window(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
Object *obpose = BKE_object_pose_armature_get(obact);
if (obpose) {
CTX_data_id_pointer_set(result, &obpose->id);
@@ -736,8 +781,10 @@ static eContextResult screen_ctx_gpencil_data(const bContext *C, bContextDataRes
{
wmWindow *win = CTX_wm_window(C);
ScrArea *area = CTX_wm_area(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
/* FIXME: for some reason, CTX_data_active_object(C) returns NULL when called from these
* situations (as outlined above - see Campbell's #ifdefs).
* That causes the get_active function to fail when called from context.
@@ -755,8 +802,10 @@ static eContextResult screen_ctx_gpencil_data_owner(const bContext *C, bContextD
{
wmWindow *win = CTX_wm_window(C);
ScrArea *area = CTX_wm_area(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
/* Pointer to which data/datablock owns the reference to the Grease Pencil data being used
* (as gpencil_data). */
@@ -806,8 +855,10 @@ static eContextResult screen_ctx_active_gpencil_layer(const bContext *C,
{
wmWindow *win = CTX_wm_window(C);
ScrArea *area = CTX_wm_area(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact);
if (gpd) {
@@ -844,8 +895,10 @@ static eContextResult screen_ctx_active_gpencil_frame(const bContext *C,
{
wmWindow *win = CTX_wm_window(C);
ScrArea *area = CTX_wm_area(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact);
if (gpd) {
@@ -863,8 +916,10 @@ static eContextResult screen_ctx_visible_gpencil_layers(const bContext *C,
{
wmWindow *win = CTX_wm_window(C);
ScrArea *area = CTX_wm_area(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact);
if (gpd) {
@@ -883,8 +938,10 @@ static eContextResult screen_ctx_editable_gpencil_layers(const bContext *C,
{
wmWindow *win = CTX_wm_window(C);
ScrArea *area = CTX_wm_area(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact);
if (gpd) {
@@ -903,8 +960,10 @@ static eContextResult screen_ctx_editable_gpencil_strokes(const bContext *C,
{
wmWindow *win = CTX_wm_window(C);
ScrArea *area = CTX_wm_area(C);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *obact = BKE_view_layer_active_object_get(view_layer);
bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact);
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 67871d08089..f06e2bd4f3c 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -1163,8 +1163,9 @@ static void screen_set_3dview_camera(Scene *scene,
/* fix any cameras that are used in the 3d view but not in the scene */
BKE_screen_view3d_sync(v3d, scene);
+ BKE_view_layer_synced_ensure(scene, view_layer);
if (!v3d->camera || !BKE_view_layer_base_find(view_layer, v3d->camera)) {
- v3d->camera = BKE_view_layer_camera_find(view_layer);
+ v3d->camera = BKE_view_layer_camera_find(scene, view_layer);
// XXX if (screen == curscreen) handle_view3d_lock();
if (!v3d->camera) {
ListBase *regionbase;
@@ -1274,7 +1275,7 @@ void ED_screen_full_prevspace(bContext *C, ScrArea *area)
BLI_assert(area->full);
if (area->flag & AREA_FLAG_STACKED_FULLSCREEN) {
- /* stacked fullscreen -> only go back to previous area and don't toggle out of fullscreen */
+ /* Stacked full-screen -> only go back to previous area and don't toggle out of full-screen. */
ED_area_prevspace(C, area);
}
else {
@@ -1305,8 +1306,8 @@ void ED_screen_full_restore(bContext *C, ScrArea *area)
bScreen *screen = CTX_wm_screen(C);
short state = (screen ? screen->state : SCREENMAXIMIZED);
- /* if fullscreen area has a temporary space (such as a file browser or fullscreen render
- * overlaid on top of an existing setup) then return to the previous space */
+ /* If full-screen area has a temporary space (such as a file browser or full-screen render
+ * overlaid on top of an existing setup) then return to the previous space. */
if (sl->next) {
if (sl->link_flag & SPACE_FLAG_TYPE_TEMPORARY) {
@@ -1640,7 +1641,7 @@ void ED_screen_animation_timer(bContext *C, int redraws, int sync, int enable)
spacetype = area->spacetype;
}
- sad->from_anim_edit = (ELEM(spacetype, SPACE_GRAPH, SPACE_ACTION, SPACE_NLA));
+ sad->from_anim_edit = ELEM(spacetype, SPACE_GRAPH, SPACE_ACTION, SPACE_NLA);
screen->animtimer->customdata = sad;
}
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h
index 4c2d94e2018..feda68a51a7 100644
--- a/source/blender/editors/screen/screen_intern.h
+++ b/source/blender/editors/screen/screen_intern.h
@@ -53,7 +53,7 @@ typedef enum eScreenAxis {
/* area.c */
/**
- * we swap spaces for fullscreen to keep all allocated data area vertices were set
+ * We swap spaces for full-screen to keep all allocated data area vertices were set.
*/
void ED_area_data_copy(ScrArea *area_dst, ScrArea *area_src, bool do_free);
void ED_area_data_swap(ScrArea *area_dst, ScrArea *area_src);
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 5331747beae..6a910170e44 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -241,7 +241,7 @@ bool ED_operator_animview_active(bContext *C)
{
if (ED_operator_areaactive(C)) {
SpaceLink *sl = (SpaceLink *)CTX_wm_space_data(C);
- if (sl && (ELEM(sl->spacetype, SPACE_SEQ, SPACE_ACTION, SPACE_NLA, SPACE_GRAPH))) {
+ if (sl && ELEM(sl->spacetype, SPACE_SEQ, SPACE_ACTION, SPACE_NLA, SPACE_GRAPH)) {
return true;
}
}
@@ -834,8 +834,7 @@ static AZone *area_actionzone_refresh_xy(ScrArea *area, const int xy[2], const b
az->alpha = 1.0f;
}
else if (mouse_sq < fadeout_sq) {
- az->alpha = 1.0f -
- ((float)(mouse_sq - fadein_sq)) / ((float)(fadeout_sq - fadein_sq));
+ az->alpha = 1.0f - (float)(mouse_sq - fadein_sq) / (float)(fadeout_sq - fadein_sq);
}
else {
az->alpha = 0.0f;
@@ -859,7 +858,7 @@ static AZone *area_actionzone_refresh_xy(ScrArea *area, const int xy[2], const b
/* Check if we even have scroll bars. */
if (((az->direction == AZ_SCROLL_HOR) && !(scroll_flag & V2D_SCROLL_HORIZONTAL)) ||
((az->direction == AZ_SCROLL_VERT) && !(scroll_flag & V2D_SCROLL_VERTICAL))) {
- /* no scrollbars, do nothing. */
+ /* No scroll-bars, do nothing. */
}
else if (test_only) {
if (isect_value != 0) {
@@ -1584,28 +1583,28 @@ static void area_move_set_limits(wmWindow *win,
/* logic here is only tested for lower edge :) */
/* left edge */
- if ((area->v1->editflag && area->v2->editflag)) {
+ if (area->v1->editflag && area->v2->editflag) {
*smaller = area->v4->vec.x - size_max;
*bigger = area->v4->vec.x - size_min;
*use_bigger_smaller_snap = true;
return;
}
/* top edge */
- if ((area->v2->editflag && area->v3->editflag)) {
+ if (area->v2->editflag && area->v3->editflag) {
*smaller = area->v1->vec.y + size_min;
*bigger = area->v1->vec.y + size_max;
*use_bigger_smaller_snap = true;
return;
}
/* right edge */
- if ((area->v3->editflag && area->v4->editflag)) {
+ if (area->v3->editflag && area->v4->editflag) {
*smaller = area->v1->vec.x + size_min;
*bigger = area->v1->vec.x + size_max;
*use_bigger_smaller_snap = true;
return;
}
/* lower edge */
- if ((area->v4->editflag && area->v1->editflag)) {
+ if (area->v4->editflag && area->v1->editflag) {
*smaller = area->v2->vec.y - size_max;
*bigger = area->v2->vec.y - size_min;
*use_bigger_smaller_snap = true;
@@ -2277,8 +2276,8 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
/* The factor will be close to 1.0f when near the top-left and the bottom-right corners. */
- const float factor_v = ((float)(event->xy[1] - sad->sa1->v1->vec.y)) / (float)sad->sa1->winy;
- const float factor_h = ((float)(event->xy[0] - sad->sa1->v1->vec.x)) / (float)sad->sa1->winx;
+ const float factor_v = (float)(event->xy[1] - sad->sa1->v1->vec.y) / (float)sad->sa1->winy;
+ const float factor_h = (float)(event->xy[0] - sad->sa1->v1->vec.x) / (float)sad->sa1->winx;
const bool is_left = factor_v < 0.5f;
const bool is_bottom = factor_h < 0.5f;
const bool is_right = !is_left;
@@ -2316,11 +2315,11 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
dir_axis = RNA_property_enum_get(op->ptr, prop_dir);
if (dir_axis == SCREEN_AXIS_H) {
RNA_property_float_set(
- op->ptr, prop_factor, ((float)(event->xy[0] - area->v1->vec.x)) / (float)area->winx);
+ op->ptr, prop_factor, (float)(event->xy[0] - area->v1->vec.x) / (float)area->winx);
}
else {
RNA_property_float_set(
- op->ptr, prop_factor, ((float)(event->xy[1] - area->v1->vec.y)) / (float)area->winy);
+ op->ptr, prop_factor, (float)(event->xy[1] - area->v1->vec.y) / (float)area->winy);
}
if (!area_split_init(C, op)) {
@@ -3267,7 +3266,7 @@ static int screen_maximize_area_exec(bContext *C, wmOperator *op)
BLI_assert(!screen->temp);
- /* search current screen for 'fullscreen' areas */
+ /* search current screen for 'full-screen' areas */
/* prevents restoring info header, when mouse is over it */
LISTBASE_FOREACH (ScrArea *, area_iter, &screen->areabase) {
if (area_iter->full) {
@@ -4503,7 +4502,7 @@ static void screen_animation_region_tag_redraw(
{
/* Do follow time here if editor type supports it */
if ((redraws & TIME_FOLLOW) &&
- (screen_animation_region_supports_time_follow(area->spacetype, region->regiontype))) {
+ screen_animation_region_supports_time_follow(area->spacetype, region->regiontype)) {
float w = BLI_rctf_size_x(&region->v2d.cur);
if (scene->r.cfra < region->v2d.cur.xmin) {
region->v2d.cur.xmax = scene->r.cfra;
@@ -4842,11 +4841,11 @@ int ED_screen_animation_play(bContext *C, int sync, int mode)
static int screen_animation_play_exec(bContext *C, wmOperator *op)
{
- int mode = (RNA_boolean_get(op->ptr, "reverse")) ? -1 : 1;
+ int mode = RNA_boolean_get(op->ptr, "reverse") ? -1 : 1;
int sync = -1;
if (RNA_struct_property_is_set(op->ptr, "sync")) {
- sync = (RNA_boolean_get(op->ptr, "sync"));
+ sync = RNA_boolean_get(op->ptr, "sync");
}
return ED_screen_animation_play(C, sync, mode);
@@ -5742,7 +5741,7 @@ static void keymap_modal_set(wmKeyConfig *keyconf)
static bool blend_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH) {
- if (ELEM(drag->icon, ICON_FILE_BLEND, ICON_BLENDER)) {
+ if (ELEM(drag->icon, ICON_FILE_BLEND, ICON_FILE_BACKUP, ICON_BLENDER)) {
return true;
}
}
diff --git a/source/blender/editors/screen/screen_user_menu.c b/source/blender/editors/screen/screen_user_menu.c
index 01c208bf48d..a7ef40361ea 100644
--- a/source/blender/editors/screen/screen_user_menu.c
+++ b/source/blender/editors/screen/screen_user_menu.c
@@ -103,7 +103,7 @@ bUserMenuItem_Op *ED_screen_user_menu_item_find_operator(ListBase *lb,
if (umi->type == USER_MENU_TYPE_OPERATOR) {
bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
if (STREQ(ot->idname, umi_op->op_idname) && (opcontext == umi_op->opcontext) &&
- (IDP_EqualsProperties(prop, umi_op->prop))) {
+ IDP_EqualsProperties(prop, umi_op->prop)) {
return umi_op;
}
}
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index 38a9d8ba7ab..569d6c2793c 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -124,7 +124,8 @@ static int screenshot_exec(bContext *C, wmOperator *op)
scd->dumprect = ibuf->rect;
}
- if (scd->im_format.planes == R_IMF_PLANES_BW) {
+ if ((scd->im_format.planes == R_IMF_PLANES_BW) &&
+ (scd->im_format.imtype != R_IMF_IMTYPE_MULTILAYER)) {
/* bw screenshot? - users will notice if it fails! */
IMB_color_to_bw(ibuf);
}
@@ -195,7 +196,7 @@ static bool screenshot_draw_check_prop(PointerRNA *UNUSED(ptr),
{
const char *prop_id = RNA_property_identifier(prop);
- return !(STREQ(prop_id, "filepath"));
+ return !STREQ(prop_id, "filepath");
}
static void screenshot_draw(bContext *UNUSED(C), wmOperator *op)
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index 9a6bdc98d76..8cf11583b3a 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -405,7 +405,7 @@ static WorkspaceConfigFileData *workspace_config_file_read(const char *app_templ
char startup_file_path[FILE_MAX] = {0};
if (cfgdir) {
- BLI_join_dirfile(startup_file_path, sizeof(startup_file_path), cfgdir, BLENDER_STARTUP_FILE);
+ BLI_path_join(startup_file_path, sizeof(startup_file_path), cfgdir, BLENDER_STARTUP_FILE);
}
bool has_path = BLI_exists(startup_file_path);
@@ -425,8 +425,7 @@ static WorkspaceConfigFileData *workspace_system_file_read(const char *app_templ
}
char startup_file_path[FILE_MAX];
- BLI_join_dirfile(
- startup_file_path, sizeof(startup_file_path), template_dir, BLENDER_STARTUP_FILE);
+ BLI_path_join(startup_file_path, sizeof(startup_file_path), template_dir, BLENDER_STARTUP_FILE);
bool has_path = BLI_exists(startup_file_path);
return (has_path) ? BKE_blendfile_workspace_config_read(startup_file_path, NULL, 0, NULL) : NULL;
diff --git a/source/blender/editors/screen/workspace_listen.cc b/source/blender/editors/screen/workspace_listen.cc
new file mode 100644
index 00000000000..84326007d66
--- /dev/null
+++ b/source/blender/editors/screen/workspace_listen.cc
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BKE_context.h"
+
+#include "ED_screen.h"
+#include "ED_viewer_path.hh"
+
+#include "WM_api.h"
+
+/**
+ * Checks if the viewer path stored in the workspace is still active and resets it if not.
+ * The viewer path stored in the workspace is the ground truth for other editors, so it should be
+ * updated before other editors look at it.
+ */
+static void validate_viewer_paths(bContext &C, WorkSpace &workspace)
+{
+ if (BLI_listbase_is_empty(&workspace.viewer_path.path)) {
+ return;
+ }
+
+ const std::optional<blender::ed::viewer_path::ViewerPathForGeometryNodesViewer> parsed_path =
+ blender::ed::viewer_path::parse_geometry_nodes_viewer(workspace.viewer_path);
+ if (parsed_path.has_value() &&
+ blender::ed::viewer_path::is_active_geometry_nodes_viewer(C, *parsed_path)) {
+ /* The current viewer path is still valid and active. */
+ return;
+ }
+ /* Reset inactive viewer path. */
+ BKE_viewer_path_clear(&workspace.viewer_path);
+ WM_event_add_notifier(&C, NC_VIEWER_PATH, nullptr);
+}
+
+void ED_workspace_do_listen(bContext *C, const wmNotifier * /*note*/)
+{
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ validate_viewer_paths(*C, *workspace);
+}
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index f4d3002219d..2709ac3fd91 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -68,7 +68,7 @@ set(SRC
sculpt_detail.c
sculpt_dyntopo.c
sculpt_expand.c
- sculpt_face_set.c
+ sculpt_face_set.cc
sculpt_filter_color.c
sculpt_filter_mask.c
sculpt_filter_mesh.c
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc
index b5d739ae08e..0d2c2d3f0c9 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc
@@ -144,8 +144,7 @@ struct AddOperationExecutor {
}
surface_verts_eval_ = surface_eval_->verts();
surface_loops_eval_ = surface_eval_->loops();
- surface_looptris_eval_ = {BKE_mesh_runtime_looptri_ensure(surface_eval_),
- BKE_mesh_runtime_looptri_len(surface_eval_)};
+ surface_looptris_eval_ = surface_eval_->looptris();
BKE_bvhtree_from_mesh_get(&surface_bvh_eval_, surface_eval_, BVHTREE_FROM_LOOPTRI, 2);
BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh_eval_); });
@@ -206,8 +205,7 @@ struct AddOperationExecutor {
return;
}
- const Span<MLoopTri> surface_looptris_orig = {BKE_mesh_runtime_looptri_ensure(&surface_orig),
- BKE_mesh_runtime_looptri_len(&surface_orig)};
+ const Span<MLoopTri> surface_looptris_orig = surface_orig.looptris();
/* Find normals. */
if (!CustomData_has_layer(&surface_orig.ldata, CD_NORMAL)) {
@@ -420,7 +418,7 @@ struct AddOperationExecutor {
*surface_bvh_eval_.tree,
brush_pos_su,
brush_radius_su,
- [&](const int index, const float3 &UNUSED(co), const float UNUSED(dist_sq)) {
+ [&](const int index, const float3 & /*co*/, const float /*dist_sq*/) {
const MLoopTri &looptri = surface_looptris_eval_[index];
const float3 v0_su = surface_verts_eval_[surface_loops_eval_[looptri.tri[0]].v].co;
const float3 v1_su = surface_verts_eval_[surface_loops_eval_[looptri.tri[1]].v].co;
@@ -438,7 +436,7 @@ struct AddOperationExecutor {
*surface_bvh_eval_.tree,
brush_pos_su,
brush_radius_su,
- [&](const int index, const float3 &UNUSED(co), const float UNUSED(dist_sq)) {
+ [&](const int index, const float3 & /*co*/, const float /*dist_sq*/) {
selected_looptri_indices.append(index);
});
}
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc b/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc
index 95261f29914..8172eb8a5d7 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc
@@ -8,7 +8,6 @@
#include "BKE_bvhutils.h"
#include "BKE_context.h"
#include "BKE_curves.hh"
-#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_report.h"
@@ -16,10 +15,6 @@
#include "UI_interface.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-
-#include "BLI_enumerable_thread_specific.hh"
#include "BLI_length_parameterize.hh"
#include "BLI_task.hh"
@@ -59,7 +54,7 @@ static std::optional<float3> find_curves_brush_position(const CurvesGeometry &cu
const Span<float3> positions)
{
/* This value might have to be adjusted based on user feedback. */
- const float brush_inner_radius_re = std::min<float>(brush_radius_re, (float)UI_UNIT_X / 3.0f);
+ const float brush_inner_radius_re = std::min<float>(brush_radius_re, float(UI_UNIT_X) / 3.0f);
const float brush_inner_radius_sq_re = pow2f(brush_inner_radius_re);
float4x4 projection;
@@ -190,7 +185,7 @@ std::optional<CurvesBrush3D> sample_curves_3d_brush(const Depsgraph &depsgraph,
/* Shorten ray when the surface object is hit. */
if (surface_object_eval != nullptr) {
- const float4x4 surface_to_world_mat = surface_object->obmat;
+ const float4x4 surface_to_world_mat = surface_object->object_to_world;
const float4x4 world_to_surface_mat = surface_to_world_mat.inverted();
Mesh *surface_eval = BKE_object_get_evaluated_mesh(surface_object_eval);
@@ -223,7 +218,7 @@ std::optional<CurvesBrush3D> sample_curves_3d_brush(const Depsgraph &depsgraph,
}
}
- const float4x4 curves_to_world_mat = curves_object.obmat;
+ const float4x4 curves_to_world_mat = curves_object.object_to_world;
const float4x4 world_to_curves_mat = curves_to_world_mat.inverted();
const float3 center_ray_start_cu = world_to_curves_mat * center_ray_start_wo;
@@ -352,33 +347,37 @@ float transform_brush_radius(const float4x4 &transform,
return math::distance(new_position, new_offset_position);
}
-void move_last_point_and_resample(MutableSpan<float3> positions, const float3 &new_last_position)
+void move_last_point_and_resample(MoveAndResampleBuffers &buffer,
+ MutableSpan<float3> positions,
+ const float3 &new_last_position)
{
/* Find the accumulated length of each point in the original curve,
* treating it as a poly curve for performance reasons and simplicity. */
- Array<float> orig_lengths(length_parameterize::segments_num(positions.size(), false));
- length_parameterize::accumulate_lengths<float3>(positions, false, orig_lengths);
- const float orig_total_length = orig_lengths.last();
+ buffer.orig_lengths.reinitialize(length_parameterize::segments_num(positions.size(), false));
+ length_parameterize::accumulate_lengths<float3>(positions, false, buffer.orig_lengths);
+ const float orig_total_length = buffer.orig_lengths.last();
/* Find the factor by which the new curve is shorter or longer than the original. */
const float new_last_segment_length = math::distance(positions.last(1), new_last_position);
- const float new_total_length = orig_lengths.last(1) + new_last_segment_length;
+ const float new_total_length = buffer.orig_lengths.last(1) + new_last_segment_length;
const float length_factor = safe_divide(new_total_length, orig_total_length);
/* Calculate the lengths to sample the original curve with by scaling the original lengths. */
- Array<float> new_lengths(positions.size() - 1);
- new_lengths.first() = 0.0f;
- for (const int i : new_lengths.index_range().drop_front(1)) {
- new_lengths[i] = orig_lengths[i - 1] * length_factor;
+ buffer.new_lengths.reinitialize(positions.size() - 1);
+ buffer.new_lengths.first() = 0.0f;
+ for (const int i : buffer.new_lengths.index_range().drop_front(1)) {
+ buffer.new_lengths[i] = buffer.orig_lengths[i - 1] * length_factor;
}
- Array<int> indices(positions.size() - 1);
- Array<float> factors(positions.size() - 1);
- length_parameterize::sample_at_lengths(orig_lengths, new_lengths, indices, factors);
+ buffer.sample_indices.reinitialize(positions.size() - 1);
+ buffer.sample_factors.reinitialize(positions.size() - 1);
+ length_parameterize::sample_at_lengths(
+ buffer.orig_lengths, buffer.new_lengths, buffer.sample_indices, buffer.sample_factors);
- Array<float3> new_positions(positions.size() - 1);
- length_parameterize::interpolate<float3>(positions, indices, factors, new_positions);
- positions.drop_back(1).copy_from(new_positions);
+ buffer.new_positions.reinitialize(positions.size() - 1);
+ length_parameterize::interpolate<float3>(
+ positions, buffer.sample_indices, buffer.sample_factors, buffer.new_positions);
+ positions.drop_back(1).copy_from(buffer.new_positions);
positions.last() = new_last_position;
}
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_density.cc b/source/blender/editors/sculpt_paint/curves_sculpt_density.cc
index a37eb4bb560..78e2d55e6b9 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_density.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_density.cc
@@ -132,8 +132,7 @@ struct DensityAddOperationExecutor {
BKE_bvhtree_from_mesh_get(&surface_bvh_eval_, surface_eval_, BVHTREE_FROM_LOOPTRI, 2);
BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh_eval_); });
- surface_looptris_eval_ = {BKE_mesh_runtime_looptri_ensure(surface_eval_),
- BKE_mesh_runtime_looptri_len(surface_eval_)};
+ surface_looptris_eval_ = surface_eval_->looptris();
/* Find UV map. */
VArraySpan<float2> surface_uv_map;
if (curves_id_orig_->surface_uv_map != nullptr) {
@@ -235,7 +234,7 @@ struct DensityAddOperationExecutor {
new_roots_kdtree,
root_pos_cu,
brush_settings_->minimum_distance,
- [&](const int other_new_i, const float *UNUSED(co), float UNUSED(dist_sq)) {
+ [&](const int other_new_i, const float * /*co*/, float /*dist_sq*/) {
if (other_new_i == -1) {
new_curve_skipped[new_i] = true;
return false;
@@ -265,8 +264,7 @@ struct DensityAddOperationExecutor {
reinterpret_cast<const float3 *>(CustomData_get_layer(&surface_orig_->ldata, CD_NORMAL)),
surface_orig_->totloop};
- const Span<MLoopTri> surface_looptris_orig = {BKE_mesh_runtime_looptri_ensure(surface_orig_),
- BKE_mesh_runtime_looptri_len(surface_orig_)};
+ const Span<MLoopTri> surface_looptris_orig = surface_orig_->looptris();
const geometry::ReverseUVSampler reverse_uv_sampler{surface_uv_map, surface_looptris_orig};
geometry::AddCurvesOnMeshInputs add_inputs;
@@ -417,7 +415,7 @@ struct DensityAddOperationExecutor {
*surface_bvh_eval_.tree,
brush_pos_su,
brush_radius_su,
- [&](const int index, const float3 &UNUSED(co), const float UNUSED(dist_sq)) {
+ [&](const int index, const float3 & /*co*/, const float /*dist_sq*/) {
selected_looptri_indices.append(index);
});
@@ -644,7 +642,7 @@ struct DensitySubtractOperationExecutor {
* strength. */
Array<bool> allow_remove_curve(curves_->curves_num(), false);
threading::parallel_for(curves_->curves_range(), 512, [&](const IndexRange range) {
- RandomNumberGenerator rng((int)(PIL_check_seconds_timer() * 1000000.0));
+ RandomNumberGenerator rng(int(PIL_check_seconds_timer() * 1000000.0));
for (const int curve_i : range) {
if (curves_to_delete[curve_i]) {
@@ -689,7 +687,7 @@ struct DensitySubtractOperationExecutor {
root_points_kdtree_,
orig_pos_cu,
minimum_distance_,
- [&](const int other_curve_i, const float *UNUSED(co), float UNUSED(dist_sq)) {
+ [&](const int other_curve_i, const float * /*co*/, float /*dist_sq*/) {
if (other_curve_i == curve_i) {
return true;
}
@@ -733,7 +731,7 @@ struct DensitySubtractOperationExecutor {
* strength. */
Array<bool> allow_remove_curve(curves_->curves_num(), false);
threading::parallel_for(curves_->curves_range(), 512, [&](const IndexRange range) {
- RandomNumberGenerator rng((int)(PIL_check_seconds_timer() * 1000000.0));
+ RandomNumberGenerator rng(int(PIL_check_seconds_timer() * 1000000.0));
for (const int curve_i : range) {
if (curves_to_delete[curve_i]) {
@@ -774,7 +772,7 @@ struct DensitySubtractOperationExecutor {
root_points_kdtree_,
pos_cu,
minimum_distance_,
- [&](const int other_curve_i, const float *UNUSED(co), float UNUSED(dist_sq)) {
+ [&](const int other_curve_i, const float * /*co*/, float /*dist_sq*/) {
if (other_curve_i == curve_i) {
return true;
}
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc
index 0ca22004540..2624d70ccf7 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc
@@ -7,8 +7,6 @@
#include "BLI_length_parameterize.hh"
#include "BLI_vector.hh"
-#include "PIL_time.h"
-
#include "DEG_depsgraph.h"
#include "BKE_attribute_math.hh"
@@ -141,11 +139,11 @@ class ExtrapolateCurvesEffect : public CurvesEffect {
{
MutableSpan<float3> positions_cu = curves.positions_for_write();
threading::parallel_for(curve_indices.index_range(), 256, [&](const IndexRange range) {
+ MoveAndResampleBuffers resample_buffer;
for (const int influence_i : range) {
const int curve_i = curve_indices[influence_i];
const float move_distance_cu = move_distances_cu[influence_i];
const IndexRange points = curves.points_for_curve(curve_i);
-
if (points.size() <= 1) {
continue;
}
@@ -157,7 +155,7 @@ class ExtrapolateCurvesEffect : public CurvesEffect {
const float3 direction = math::normalize(old_last_pos_cu - direction_reference_point);
const float3 new_last_pos_cu = old_last_pos_cu + direction * move_distance_cu;
- move_last_point_and_resample(positions_cu.slice(points), new_last_pos_cu);
+ move_last_point_and_resample(resample_buffer, positions_cu.slice(points), new_last_pos_cu);
}
});
}
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh
index 5c8c0cedc6f..61e2559f303 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh
@@ -102,7 +102,23 @@ VArray<float> get_curves_selection(const Curves &curves_id);
*/
VArray<float> get_point_selection(const Curves &curves_id);
-void move_last_point_and_resample(MutableSpan<float3> positions, const float3 &new_last_position);
+/** See #move_last_point_and_resample. */
+struct MoveAndResampleBuffers {
+ Array<float> orig_lengths;
+ Array<float> new_lengths;
+
+ Array<int> sample_indices;
+ Array<float> sample_factors;
+
+ Array<float3> new_positions;
+};
+
+/**
+ * \param buffer: Reused memory to avoid reallocations when the function is called many times.
+ */
+void move_last_point_and_resample(MoveAndResampleBuffers &buffer,
+ MutableSpan<float3> positions,
+ const float3 &new_last_position);
class CurvesSculptCommonContext {
public:
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc
index 6e1ac24e21b..df7dd871a94 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc
@@ -153,7 +153,7 @@ struct SculptCurvesBrushStrokeData {
static bool stroke_get_location(bContext *C,
float out[3],
const float mouse[2],
- bool UNUSED(force_original))
+ bool /*force_original*/)
{
out[0] = mouse[0];
out[1] = mouse[1];
@@ -170,7 +170,7 @@ static bool stroke_test_start(bContext *C, struct wmOperator *op, const float mo
static void stroke_update_step(bContext *C,
wmOperator *op,
- PaintStroke *UNUSED(stroke),
+ PaintStroke * /*stroke*/,
PointerRNA *stroke_element)
{
SculptCurvesBrushStrokeData *op_data = static_cast<SculptCurvesBrushStrokeData *>(
@@ -220,8 +220,10 @@ static int sculpt_curves_stroke_invoke(bContext *C, wmOperator *op, const wmEven
int return_value = op->type->modal(C, op, event);
if (return_value == OPERATOR_FINISHED) {
- paint_stroke_free(C, op, op_data->stroke);
- MEM_delete(op_data);
+ if (op->customdata != nullptr) {
+ paint_stroke_free(C, op, op_data->stroke);
+ MEM_delete(op_data);
+ }
return OPERATOR_FINISHED;
}
@@ -236,16 +238,19 @@ static int sculpt_curves_stroke_modal(bContext *C, wmOperator *op, const wmEvent
int return_value = paint_stroke_modal(C, op, event, &op_data->stroke);
if (ELEM(return_value, OPERATOR_FINISHED, OPERATOR_CANCELLED)) {
MEM_delete(op_data);
+ op->customdata = nullptr;
}
return return_value;
}
static void sculpt_curves_stroke_cancel(bContext *C, wmOperator *op)
{
- SculptCurvesBrushStrokeData *op_data = static_cast<SculptCurvesBrushStrokeData *>(
- op->customdata);
- paint_stroke_cancel(C, op, op_data->stroke);
- MEM_delete(op_data);
+ if (op->customdata != nullptr) {
+ SculptCurvesBrushStrokeData *op_data = static_cast<SculptCurvesBrushStrokeData *>(
+ op->customdata);
+ paint_stroke_cancel(C, op, op_data->stroke);
+ MEM_delete(op_data);
+ }
}
static void SCULPT_CURVES_OT_brush_stroke(struct wmOperatorType *ot)
@@ -344,7 +349,7 @@ static int select_random_exec(bContext *C, wmOperator *op)
VectorSet<Curves *> unique_curves = curves::get_unique_editable_curves(*C);
const int seed = RNA_int_get(op->ptr, "seed");
- RandomNumberGenerator rng{static_cast<uint32_t>(seed)};
+ RandomNumberGenerator rng{uint32_t(seed)};
const bool partial = RNA_boolean_get(op->ptr, "partial");
const bool constant_per_curve = RNA_boolean_get(op->ptr, "constant_per_curve");
@@ -448,7 +453,7 @@ static int select_random_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static void select_random_ui(bContext *UNUSED(C), wmOperator *op)
+static void select_random_ui(bContext * /*C*/, wmOperator *op)
{
uiLayout *layout = op->layout;
@@ -786,7 +791,7 @@ static void select_grow_invoke_per_curve(Curves &curves_id,
});
});
- float4x4 curves_to_world_mat = curves_ob.obmat;
+ float4x4 curves_to_world_mat = curves_ob.object_to_world;
float4x4 world_to_curves_mat = curves_to_world_mat.inverted();
float4x4 projection;
@@ -914,7 +919,7 @@ static void SCULPT_CURVES_OT_select_grow(wmOperatorType *ot)
"Distance",
"By how much to grow the selection",
-10.0f,
- 10.f);
+ 10.0f);
RNA_def_property_subtype(prop, PROP_DISTANCE);
}
@@ -1003,7 +1008,7 @@ static int calculate_points_per_side(bContext *C, MinDistanceEditData &op_data)
return std::min(300, needed_points);
}
-static void min_distance_edit_draw(bContext *C, int UNUSED(x), int UNUSED(y), void *customdata)
+static void min_distance_edit_draw(bContext *C, int /*x*/, int /*y*/, void *customdata)
{
Scene *scene = CTX_data_scene(C);
MinDistanceEditData &op_data = *static_cast<MinDistanceEditData *>(customdata);
@@ -1093,7 +1098,7 @@ static void min_distance_edit_draw(bContext *C, int UNUSED(x), int UNUSED(y), vo
GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
/* Draw the brush circle. */
- GPU_matrix_translate_2f((float)op_data.initial_mouse.x, (float)op_data.initial_mouse.y);
+ GPU_matrix_translate_2f(float(op_data.initial_mouse.x), float(op_data.initial_mouse.y));
GPUVertFormat *format = immVertexFormat();
uint pos2d = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc
index ec69aae372c..b4e949106e7 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc
@@ -121,8 +121,7 @@ struct PuffOperationExecutor {
surface_verts_ = surface_->verts();
surface_loops_ = surface_->loops();
- surface_looptris_ = {BKE_mesh_runtime_looptri_ensure(surface_),
- BKE_mesh_runtime_looptri_len(surface_)};
+ surface_looptris_ = surface_->looptris();
BKE_bvhtree_from_mesh_get(&surface_bvh_, surface_, BVHTREE_FROM_LOOPTRI, 2);
BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh_); });
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc
index 1108f5c72a9..ae89bc1c58b 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc
@@ -8,8 +8,6 @@
#include "BLI_float4x4.hh"
#include "BLI_vector.hh"
-#include "PIL_time.h"
-
#include "DEG_depsgraph.h"
#include "BKE_attribute_math.hh"
@@ -17,17 +15,13 @@
#include "BKE_bvhutils.h"
#include "BKE_context.h"
#include "BKE_curves.hh"
-#include "BKE_geometry_set.hh"
#include "BKE_mesh.h"
-#include "BKE_mesh_runtime.h"
#include "BKE_mesh_sample.hh"
-#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_report.h"
#include "DNA_brush_enums.h"
-#include "DNA_brush_types.h"
#include "DNA_curves_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -37,8 +31,6 @@
#include "ED_screen.h"
#include "ED_view3d.h"
-#include "UI_interface.h"
-
#include "WM_api.h"
#include "DEG_depsgraph_query.h"
@@ -178,8 +170,7 @@ struct SlideOperationExecutor {
report_empty_original_surface(stroke_extension.reports);
return;
}
- surface_looptris_orig_ = {BKE_mesh_runtime_looptri_ensure(surface_orig_),
- BKE_mesh_runtime_looptri_len(surface_orig_)};
+ surface_looptris_orig_ = surface_orig_->looptris();
surface_uv_map_orig_ = surface_orig_->attributes().lookup<float2>(uv_map_name,
ATTR_DOMAIN_CORNER);
if (surface_uv_map_orig_.is_empty()) {
@@ -205,8 +196,7 @@ struct SlideOperationExecutor {
report_empty_evaluated_surface(stroke_extension.reports);
return;
}
- surface_looptris_eval_ = {BKE_mesh_runtime_looptri_ensure(surface_eval_),
- BKE_mesh_runtime_looptri_len(surface_eval_)};
+ surface_looptris_eval_ = surface_eval_->looptris();
surface_verts_eval_ = surface_eval_->verts();
surface_loops_eval_ = surface_eval_->loops();
surface_uv_map_eval_ = surface_eval_->attributes().lookup<float2>(uv_map_name,
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc
index 54b81fa221d..67757ce5f4a 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc
@@ -188,6 +188,7 @@ struct SnakeHookOperatorExecutor {
const float brush_radius_sq_re = pow2f(brush_radius_re);
threading::parallel_for(curves_->curves_range(), 256, [&](const IndexRange curves_range) {
+ MoveAndResampleBuffers resample_buffer;
for (const int curve_i : curves_range) {
const IndexRange points = curves_->points_for_curve(curve_i);
const int last_point_i = points.last();
@@ -221,8 +222,8 @@ struct SnakeHookOperatorExecutor {
const float3 translation_orig = deformation.translation_from_deformed_to_original(
last_point_i, translation_eval);
- move_last_point_and_resample(positions_cu.slice(points),
- positions_cu[last_point_i] + translation_orig);
+ const float3 last_point_cu = positions_cu[last_point_i] + translation_orig;
+ move_last_point_and_resample(resample_buffer, positions_cu.slice(points), last_point_cu);
}
});
}
@@ -268,6 +269,7 @@ struct SnakeHookOperatorExecutor {
const float brush_radius_sq_cu = pow2f(brush_radius_cu);
threading::parallel_for(curves_->curves_range(), 256, [&](const IndexRange curves_range) {
+ MoveAndResampleBuffers resample_buffer;
for (const int curve_i : curves_range) {
const IndexRange points = curves_->points_for_curve(curve_i);
const int last_point_i = points.last();
@@ -289,8 +291,8 @@ struct SnakeHookOperatorExecutor {
const float3 translation_orig = deformation.translation_from_deformed_to_original(
last_point_i, translation_eval);
- move_last_point_and_resample(positions_cu.slice(points),
- positions_cu[last_point_i] + translation_orig);
+ const float3 last_point_cu = positions_cu[last_point_i] + translation_orig;
+ move_last_point_and_resample(resample_buffer, positions_cu.slice(points), last_point_cu);
}
});
}
diff --git a/source/blender/editors/sculpt_paint/paint_canvas.cc b/source/blender/editors/sculpt_paint/paint_canvas.cc
index 9262cbebcac..22e1ecbedd7 100644
--- a/source/blender/editors/sculpt_paint/paint_canvas.cc
+++ b/source/blender/editors/sculpt_paint/paint_canvas.cc
@@ -1,4 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
#include "BLI_compiler_compat.h"
#include "DNA_material_types.h"
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 164e13ac3c9..b6e83187c86 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -27,7 +27,6 @@
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_image.h"
-#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_paint.h"
@@ -563,31 +562,36 @@ static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups,
if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
GPU_matrix_push();
+ float center[2] = {
+ ups->draw_anchored ? ups->anchored_initial_mouse[0] : x,
+ ups->draw_anchored ? ups->anchored_initial_mouse[1] : y,
+ };
+
/* Brush rotation. */
- GPU_matrix_translate_2f(x, y);
+ GPU_matrix_translate_2fv(center);
GPU_matrix_rotate_2d(-RAD2DEGF(primary ? ups->brush_rotation : ups->brush_rotation_sec));
- GPU_matrix_translate_2f(-x, -y);
+ GPU_matrix_translate_2f(-center[0], -center[1]);
/* Scale based on tablet pressure. */
if (primary && ups->stroke_active && BKE_brush_use_size_pressure(brush)) {
const float scale = ups->size_pressure_value;
- GPU_matrix_translate_2f(x, y);
+ GPU_matrix_translate_2fv(center);
GPU_matrix_scale_2f(scale, scale);
- GPU_matrix_translate_2f(-x, -y);
+ GPU_matrix_translate_2f(-center[0], -center[1]);
}
if (ups->draw_anchored) {
- quad.xmin = ups->anchored_initial_mouse[0] - ups->anchored_size;
- quad.ymin = ups->anchored_initial_mouse[1] - ups->anchored_size;
- quad.xmax = ups->anchored_initial_mouse[0] + ups->anchored_size;
- quad.ymax = ups->anchored_initial_mouse[1] + ups->anchored_size;
+ quad.xmin = center[0] - ups->anchored_size;
+ quad.ymin = center[1] - ups->anchored_size;
+ quad.xmax = center[0] + ups->anchored_size;
+ quad.ymax = center[1] + ups->anchored_size;
}
else {
const int radius = BKE_brush_size_get(vc->scene, brush) * zoom;
- quad.xmin = x - radius;
- quad.ymin = y - radius;
- quad.xmax = x + radius;
- quad.ymax = y + radius;
+ quad.xmin = center[0] - radius;
+ quad.ymin = center[1] - radius;
+ quad.xmax = center[0] + radius;
+ quad.ymax = center[1] + radius;
}
}
else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
@@ -1072,7 +1076,7 @@ static void cursor_draw_tiling_preview(const uint gpuattr,
for (int dim = 0; dim < 3; dim++) {
location[dim] = cur[dim] * step[dim] + orgLoc[dim];
}
- cursor_draw_point_screen_space(gpuattr, region, location, ob->obmat, 3);
+ cursor_draw_point_screen_space(gpuattr, region, location, ob->object_to_world, 3);
}
}
}
@@ -1089,11 +1093,11 @@ static void cursor_draw_point_with_symmetry(const uint gpuattr,
float location[3], symm_rot_mat[4][4];
for (int i = 0; i <= symm; i++) {
- if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (!ELEM(i, 3, 5))))) {
+ if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || !ELEM(i, 3, 5)))) {
/* Axis Symmetry. */
flip_v3_v3(location, true_location, (char)i);
- cursor_draw_point_screen_space(gpuattr, region, location, ob->obmat, 3);
+ cursor_draw_point_screen_space(gpuattr, region, location, ob->object_to_world, 3);
/* Tiling. */
cursor_draw_tiling_preview(gpuattr, region, location, sd, ob, radius);
@@ -1108,7 +1112,7 @@ static void cursor_draw_point_with_symmetry(const uint gpuattr,
mul_m4_v3(symm_rot_mat, location);
cursor_draw_tiling_preview(gpuattr, region, location, sd, ob, radius);
- cursor_draw_point_screen_space(gpuattr, region, location, ob->obmat, 3);
+ cursor_draw_point_screen_space(gpuattr, region, location, ob->object_to_world, 3);
}
}
}
@@ -1335,7 +1339,7 @@ static void paint_cursor_update_pixel_radius(PaintCursorContext *pcontext)
}
copy_v3_v3(pcontext->scene_space_location, pcontext->location);
- mul_m4_v3(pcontext->vc.obact->obmat, pcontext->scene_space_location);
+ mul_m4_v3(pcontext->vc.obact->object_to_world, pcontext->scene_space_location);
}
else {
Sculpt *sd = CTX_data_tool_settings(pcontext->C)->sculpt;
@@ -1465,7 +1469,7 @@ static void paint_cursor_drawing_setup_cursor_space(PaintCursorContext *pcontext
float cursor_trans[4][4], cursor_rot[4][4];
const float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
float quat[4];
- copy_m4_m4(cursor_trans, pcontext->vc.obact->obmat);
+ copy_m4_m4(cursor_trans, pcontext->vc.obact->object_to_world);
translate_m4(cursor_trans, pcontext->location[0], pcontext->location[1], pcontext->location[2]);
rotation_between_vecs_to_quat(quat, z_axis, pcontext->normal);
quat_to_mat4(cursor_rot, quat);
@@ -1509,7 +1513,7 @@ static void paint_cursor_pose_brush_origins_draw(PaintCursorContext *pcontext)
cursor_draw_point_screen_space(pcontext->pos,
pcontext->region,
ss->pose_ik_chain_preview->segments[i].initial_orig,
- pcontext->vc.obact->obmat,
+ pcontext->vc.obact->object_to_world,
3);
}
}
@@ -1527,7 +1531,7 @@ static void paint_cursor_preview_boundary_data_pivot_draw(PaintCursorContext *pc
pcontext->pos,
pcontext->region,
SCULPT_vertex_co_get(pcontext->ss, pcontext->ss->boundary_preview->pivot_vertex),
- pcontext->vc.obact->obmat,
+ pcontext->vc.obact->object_to_world,
3);
}
@@ -1635,7 +1639,7 @@ static void paint_cursor_draw_3d_view_brush_cursor_inactive(PaintCursorContext *
pcontext->pos,
pcontext->region,
SCULPT_vertex_co_get(pcontext->ss, pcontext->ss->expand_cache->initial_active_vertex),
- pcontext->vc.obact->obmat,
+ pcontext->vc.obact->object_to_world,
2);
}
@@ -1657,7 +1661,7 @@ static void paint_cursor_draw_3d_view_brush_cursor_inactive(PaintCursorContext *
NULL);
GPU_matrix_push();
- GPU_matrix_mul(pcontext->vc.obact->obmat);
+ GPU_matrix_mul(pcontext->vc.obact->object_to_world);
/* Drawing Cursor overlays in 3D object space. */
if (is_brush_tool && brush->sculpt_tool == SCULPT_TOOL_GRAB &&
@@ -1748,7 +1752,7 @@ static void paint_cursor_cursor_draw_3d_view_brush_cursor_active(PaintCursorCont
NULL,
NULL);
GPU_matrix_push();
- GPU_matrix_mul(pcontext->vc.obact->obmat);
+ GPU_matrix_mul(pcontext->vc.obact->object_to_world);
/* Draw the special active cursors different tools may have. */
diff --git a/source/blender/editors/sculpt_paint/paint_curve.c b/source/blender/editors/sculpt_paint/paint_curve.c
index 22d6626ab16..26f76d46f85 100644
--- a/source/blender/editors/sculpt_paint/paint_curve.c
+++ b/source/blender/editors/sculpt_paint/paint_curve.c
@@ -44,7 +44,7 @@ bool paint_curve_poll(bContext *C)
RegionView3D *rv3d = CTX_wm_region_view3d(C);
SpaceImage *sima;
- if (rv3d && !(ob && ((ob->mode & OB_MODE_ALL_PAINT) != 0))) {
+ if (rv3d && !(ob && ((ob->mode & (OB_MODE_ALL_PAINT | OB_MODE_SCULPT_CURVES)) != 0))) {
return false;
}
@@ -676,6 +676,9 @@ static int paintcurve_draw_exec(bContext *C, wmOperator *UNUSED(op))
case PAINT_MODE_SCULPT:
name = "SCULPT_OT_brush_stroke";
break;
+ case PAINT_MODE_SCULPT_CURVES:
+ name = "SCULPT_CURVES_OT_brush_stroke";
+ break;
default:
return OPERATOR_PASS_THROUGH;
}
diff --git a/source/blender/editors/sculpt_paint/paint_curve_undo.c b/source/blender/editors/sculpt_paint/paint_curve_undo.c
index 2678ec6e115..a5daa13b762 100644
--- a/source/blender/editors/sculpt_paint/paint_curve_undo.c
+++ b/source/blender/editors/sculpt_paint/paint_curve_undo.c
@@ -9,9 +9,6 @@
#include "MEM_guardedalloc.h"
#include "DNA_brush_types.h"
-#include "DNA_space_types.h"
-
-#include "BLI_array_utils.h"
#include "BKE_context.h"
#include "BKE_paint.h"
@@ -24,6 +21,10 @@
#include "paint_intern.h"
+#ifndef NDEBUG
+# include "BLI_array_utils.h" /* #BLI_array_is_zeroed */
+#endif
+
/* -------------------------------------------------------------------- */
/** \name Undo Conversion
* \{ */
diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c
index c1289364fb2..9e435ee0748 100644
--- a/source/blender/editors/sculpt_paint/paint_hide.c
+++ b/source/blender/editors/sculpt_paint/paint_hide.c
@@ -383,10 +383,9 @@ static int hide_show_exec(bContext *C, wmOperator *op)
* sculpt but it looks wrong when entering editmode otherwise). */
if (pbvh_type == PBVH_FACES) {
BKE_mesh_flush_hidden_from_verts(me);
+ BKE_pbvh_update_hide_attributes_from_mesh(pbvh);
}
- SCULPT_visibility_sync_all_vertex_to_face_sets(ob->sculpt);
-
DEG_id_tag_update(&ob->id, ID_RECALC_SHADING);
ED_region_tag_redraw(region);
diff --git a/source/blender/editors/sculpt_paint/paint_image.cc b/source/blender/editors/sculpt_paint/paint_image.cc
index c852fd25bc4..f334b2eb8f8 100644
--- a/source/blender/editors/sculpt_paint/paint_image.cc
+++ b/source/blender/editors/sculpt_paint/paint_image.cc
@@ -13,7 +13,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -35,9 +34,7 @@
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
-#include "BKE_node.h"
#include "BKE_paint.h"
-#include "BKE_undo_system.h"
#include "NOD_texture.h"
@@ -50,7 +47,6 @@
#include "ED_object.h"
#include "ED_paint.h"
#include "ED_screen.h"
-#include "ED_view3d.h"
#include "WM_api.h"
#include "WM_message.h"
@@ -60,9 +56,6 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "GPU_immediate.h"
-#include "GPU_state.h"
-
#include "IMB_colormanagement.h"
#include "paint_intern.h"
@@ -328,7 +321,7 @@ bool paint_use_opacity_masking(Brush *brush)
{
return ((brush->flag & BRUSH_AIRBRUSH) || (brush->flag & BRUSH_DRAG_DOT) ||
(brush->flag & BRUSH_ANCHORED) ||
- (ELEM(brush->imagepaint_tool, PAINT_TOOL_SMEAR, PAINT_TOOL_SOFTEN)) ||
+ ELEM(brush->imagepaint_tool, PAINT_TOOL_SMEAR, PAINT_TOOL_SOFTEN) ||
(brush->imagepaint_tool == PAINT_TOOL_FILL) ||
(brush->flag & BRUSH_USE_GRADIENT) ||
(brush->mtex.tex && !ELEM(brush->mtex.brush_map_mode,
@@ -546,7 +539,7 @@ static int grab_clone_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static void grab_clone_cancel(bContext *UNUSED(C), wmOperator *op)
+static void grab_clone_cancel(bContext * /*C*/, wmOperator *op)
{
GrabClone *cmv = static_cast<GrabClone *>(op->customdata);
MEM_delete(cmv);
@@ -787,20 +780,7 @@ void ED_object_texture_paint_mode_enter_ex(Main *bmain, Scene *scene, Object *ob
}
if (ima) {
- wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
- LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
- const bScreen *screen = WM_window_get_active_screen(win);
- LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
- SpaceLink *sl = static_cast<SpaceLink *>(area->spacedata.first);
- if (sl->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = (SpaceImage *)sl;
-
- if (!sima->pin) {
- ED_space_image_set(bmain, sima, ima, true);
- }
- }
- }
- }
+ ED_space_image_sync(bmain, ima, false);
}
ob->mode |= OB_MODE_TEXTURE_PAINT;
@@ -911,7 +891,7 @@ void PAINT_OT_texture_paint_toggle(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int brush_colors_flip_exec(bContext *C, wmOperator *UNUSED(op))
+static int brush_colors_flip_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
@@ -980,7 +960,7 @@ void ED_imapaint_bucket_fill(struct bContext *C,
ED_image_undo_push_begin(op->type->name, PAINT_MODE_TEXTURE_2D);
- const float mouse_init[2] = {static_cast<float>(mouse[0]), static_cast<float>(mouse[1])};
+ const float mouse_init[2] = {float(mouse[0]), float(mouse[1])};
paint_2d_bucket_fill(C, color, nullptr, mouse_init, nullptr, nullptr);
ED_image_undo_push_end();
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index 5df65e596b9..b7ce4b2973c 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -150,7 +150,7 @@ static void brush_painter_2d_require_imbuf(
{
BrushPainterCache *cache = &tile->cache;
- if ((cache->use_float != use_float)) {
+ if (cache->use_float != use_float) {
if (cache->ibuf) {
IMB_freeImBuf(cache->ibuf);
}
@@ -402,7 +402,8 @@ static ImBuf *brush_painter_imbuf_new(
if (is_texbrush) {
brush_imbuf_tex_co(&tex_mapping, x, y, texco);
- BKE_brush_sample_tex_3d(scene, brush, texco, rgba, thread, pool);
+ const MTex *mtex = &brush->mtex;
+ BKE_brush_sample_tex_3d(scene, brush, mtex, texco, rgba, thread, pool);
/* TODO(sergey): Support texture paint color space. */
if (!use_float) {
IMB_colormanagement_scene_linear_to_display_v3(rgba, display);
@@ -446,6 +447,7 @@ static void brush_painter_imbuf_update(BrushPainter *painter,
{
Scene *scene = painter->scene;
Brush *brush = painter->brush;
+ const MTex *mtex = &brush->mtex;
BrushPainterCache *cache = &tile->cache;
const char *display_device = scene->display_settings.display_device;
@@ -485,7 +487,7 @@ static void brush_painter_imbuf_update(BrushPainter *painter,
if (!use_texture_old) {
if (is_texbrush) {
brush_imbuf_tex_co(&tex_mapping, x, y, texco);
- BKE_brush_sample_tex_3d(scene, brush, texco, rgba, thread, pool);
+ BKE_brush_sample_tex_3d(scene, brush, mtex, texco, rgba, thread, pool);
/* TODO(sergey): Support texture paint color space. */
if (!use_float) {
IMB_colormanagement_scene_linear_to_display_v3(rgba, display);
@@ -1178,8 +1180,8 @@ static ImBuf *paint_2d_lift_clone(ImBuf *ibuf, ImBuf *ibufb, const int *pos)
static void paint_2d_convert_brushco(ImBuf *ibufb, const float pos[2], int ipos[2])
{
- ipos[0] = (int)floorf((pos[0] - ibufb->x / 2));
- ipos[1] = (int)floorf((pos[1] - ibufb->y / 2));
+ ipos[0] = (int)floorf(pos[0] - ibufb->x / 2);
+ ipos[1] = (int)floorf(pos[1] - ibufb->y / 2);
}
static void paint_2d_do_making_brush(ImagePaintState *s,
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d_curve_mask.cc b/source/blender/editors/sculpt_paint/paint_image_2d_curve_mask.cc
index f5657b004e2..6c7029cccd1 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d_curve_mask.cc
+++ b/source/blender/editors/sculpt_paint/paint_image_2d_curve_mask.cc
@@ -52,29 +52,29 @@ static void update_curve_mask(CurveMaskCache *curve_mask_cache,
const float cursor_position[2])
{
BLI_assert(curve_mask_cache->curve_mask != nullptr);
- int offset = (int)floorf(diameter / 2.0f);
+ int offset = int(floorf(diameter / 2.0f));
int clamped_radius = max_ff(radius, 1.0);
- unsigned short *m = curve_mask_cache->curve_mask;
+ ushort *m = curve_mask_cache->curve_mask;
const int aa_samples = aa_samples_per_texel_axis(brush, radius);
- const float aa_offset = 1.0f / (2.0f * (float)aa_samples);
- const float aa_step = 1.0f / (float)aa_samples;
+ const float aa_offset = 1.0f / (2.0f * float(aa_samples));
+ const float aa_step = 1.0f / float(aa_samples);
float bpos[2];
bpos[0] = cursor_position[0] - floorf(cursor_position[0]) + offset;
bpos[1] = cursor_position[1] - floorf(cursor_position[1]) + offset;
- float weight_factor = 65535.0f / (float)(aa_samples * aa_samples);
+ float weight_factor = 65535.0f / float(aa_samples * aa_samples);
for (int y = 0; y < diameter; y++) {
for (int x = 0; x < diameter; x++, m++) {
float pixel_xy[2];
- pixel_xy[0] = static_cast<float>(x) + aa_offset;
+ pixel_xy[0] = float(x) + aa_offset;
float total_weight = 0;
for (int i = 0; i < aa_samples; i++) {
- pixel_xy[1] = static_cast<float>(y) + aa_offset;
+ pixel_xy[1] = float(y) + aa_offset;
for (int j = 0; j < aa_samples; j++) {
const float len = len_v2v2(pixel_xy, bpos);
const int sample_index = min_ii((len / clamped_radius) * CurveSamplesBaseLen,
@@ -87,7 +87,7 @@ static void update_curve_mask(CurveMaskCache *curve_mask_cache,
}
pixel_xy[0] += aa_step;
}
- *m = (unsigned short)(total_weight * weight_factor);
+ *m = ushort(total_weight * weight_factor);
}
}
}
@@ -140,8 +140,7 @@ static void curve_mask_free(CurveMaskCache *curve_mask_cache)
static void curve_mask_allocate(CurveMaskCache *curve_mask_cache, const int diameter)
{
const size_t curve_mask_size = diameter_to_curve_mask_size(diameter);
- curve_mask_cache->curve_mask = static_cast<unsigned short *>(
- MEM_mallocN(curve_mask_size, __func__));
+ curve_mask_cache->curve_mask = static_cast<ushort *>(MEM_mallocN(curve_mask_size, __func__));
curve_mask_cache->curve_mask_size = curve_mask_size;
}
diff --git a/source/blender/editors/sculpt_paint/paint_image_ops_paint.cc b/source/blender/editors/sculpt_paint/paint_image_ops_paint.cc
index 928f3e9a496..d5c5aa5cebd 100644
--- a/source/blender/editors/sculpt_paint/paint_image_ops_paint.cc
+++ b/source/blender/editors/sculpt_paint/paint_image_ops_paint.cc
@@ -17,8 +17,6 @@
#include "BKE_paint.h"
#include "BKE_undo_system.h"
-#include "DEG_depsgraph.h"
-
#include "ED_paint.h"
#include "ED_view3d.h"
@@ -28,11 +26,8 @@
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
-#include "RNA_define.h"
#include "WM_api.h"
-#include "WM_message.h"
-#include "WM_toolsystem.h"
#include "WM_types.h"
#include "ED_image.h"
@@ -79,16 +74,13 @@ class AbstractPaintMode {
class ImagePaintMode : public AbstractPaintMode {
public:
- void *paint_new_stroke(bContext *C,
- wmOperator *op,
- Object *UNUSED(ob),
- const float UNUSED(mouse[2]),
- int mode) override
+ void *paint_new_stroke(
+ bContext *C, wmOperator *op, Object * /*ob*/, const float /*mouse*/[2], int mode) override
{
return paint_2d_new_stroke(C, op, mode);
}
- void paint_stroke(bContext *UNUSED(C),
+ void paint_stroke(bContext * /*C*/,
void *stroke_handle,
float prev_mouse[2],
float mouse[2],
@@ -111,9 +103,9 @@ class ImagePaintMode : public AbstractPaintMode {
}
void paint_gradient_fill(const bContext *C,
- const Scene *UNUSED(scene),
+ const Scene * /*scene*/,
Brush *brush,
- struct PaintStroke *UNUSED(stroke),
+ struct PaintStroke * /*stroke*/,
void *stroke_handle,
float mouse_start[2],
float mouse_end[2]) override
@@ -143,7 +135,7 @@ class ImagePaintMode : public AbstractPaintMode {
class ProjectionPaintMode : public AbstractPaintMode {
public:
void *paint_new_stroke(
- bContext *C, wmOperator *UNUSED(op), Object *ob, const float mouse[2], int mode) override
+ bContext *C, wmOperator * /*op*/, Object *ob, const float mouse[2], int mode) override
{
return paint_proj_new_stroke(C, ob, mouse, mode);
}
@@ -240,7 +232,7 @@ struct PaintOperation {
}
};
-static void gradient_draw_line(bContext *UNUSED(C), int x, int y, void *customdata)
+static void gradient_draw_line(bContext * /*C*/, int x, int y, void *customdata)
{
PaintOperation *pop = (PaintOperation *)customdata;
@@ -294,6 +286,7 @@ static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const flo
copy_v2_v2(pop->startmouse, mouse);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
/* initialize from context */
@@ -329,7 +322,7 @@ static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const flo
}
static void paint_stroke_update_step(bContext *C,
- wmOperator *UNUSED(op),
+ wmOperator * /*op*/,
struct PaintStroke *stroke,
PointerRNA *itemptr)
{
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 1ca5df47e17..c85044bf915 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -74,6 +74,7 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
+#include "ED_image.h"
#include "ED_node.h"
#include "ED_object.h"
#include "ED_paint.h"
@@ -415,6 +416,7 @@ typedef struct ProjPaintState {
const float (*vert_normals)[3];
const MEdge *medge_eval;
const MPoly *mpoly_eval;
+ const bool *select_poly_eval;
const int *material_indices;
const MLoop *mloop_eval;
const MLoopTri *mlooptri_eval;
@@ -591,8 +593,8 @@ static int project_bucket_offset(const ProjPaintState *ps, const float projCoSS[
*
* Second multiplication does similar but for vertical offset
*/
- return ((int)(((projCoSS[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x)) +
- (((int)(((projCoSS[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y)) *
+ return (int)(((projCoSS[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) +
+ ((int)(((projCoSS[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) *
ps->buckets_x);
}
@@ -1233,12 +1235,12 @@ static VertSeam *find_adjacent_seam(const ProjPaintState *ps,
LISTBASE_CIRCULAR_BACKWARD_END(VertSeam *, vert_seams, adjacent, seam);
}
else {
- LISTBASE_CIRCULAR_FORWARD_BEGIN (vert_seams, adjacent, seam) {
+ LISTBASE_CIRCULAR_FORWARD_BEGIN (VertSeam *, vert_seams, adjacent, seam) {
if ((adjacent->normal_cw != seam->normal_cw) && cmp_uv(adjacent->uv, seam->uv)) {
break;
}
}
- LISTBASE_CIRCULAR_FORWARD_END(vert_seams, adjacent, seam);
+ LISTBASE_CIRCULAR_FORWARD_END(VertSeam *, vert_seams, adjacent, seam);
}
BLI_assert(adjacent);
@@ -1523,7 +1525,7 @@ static void project_face_seams_init(const ProjPaintState *ps,
static void screen_px_from_ortho(const float uv[2],
const float v1co[3],
const float v2co[3],
- const float v3co[3], /* Screenspace coords */
+ const float v3co[3], /* Screen-space coords */
const float uv1co[2],
const float uv2co[2],
const float uv3co[2],
@@ -1941,8 +1943,8 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps,
}
/* which bounding box cell are we in?, needed for undo */
- projPixel->bb_cell_index = ((int)(((float)x_px / (float)ibuf->x) * PROJ_BOUNDBOX_DIV)) +
- ((int)(((float)y_px / (float)ibuf->y) * PROJ_BOUNDBOX_DIV)) *
+ projPixel->bb_cell_index = (int)(((float)x_px / (float)ibuf->x) * PROJ_BOUNDBOX_DIV) +
+ (int)(((float)y_px / (float)ibuf->y) * PROJ_BOUNDBOX_DIV) *
PROJ_BOUNDBOX_DIV;
/* done with view3d_project_float inline */
@@ -2411,7 +2413,7 @@ static bool IsectPT2Df_limit(
const float pt[2], const float v1[2], const float v2[2], const float v3[2], const float limit)
{
return ((area_tri_v2(pt, v1, v2) + area_tri_v2(pt, v2, v3) + area_tri_v2(pt, v3, v1)) /
- (area_tri_v2(v1, v2, v3))) < limit;
+ area_tri_v2(v1, v2, v3)) < limit;
}
/**
@@ -3683,7 +3685,7 @@ static void proj_paint_state_viewport_init(ProjPaintState *ps, const char symmet
ps->viewDir[1] = 0.0f;
ps->viewDir[2] = 1.0f;
- copy_m4_m4(ps->obmat, ps->ob->obmat);
+ copy_m4_m4(ps->obmat, ps->ob->object_to_world);
if (symmetry_flag) {
int i;
@@ -3741,7 +3743,7 @@ static void proj_paint_state_viewport_init(ProjPaintState *ps, const char symmet
CameraParams params;
/* viewmat & viewinv */
- copy_m4_m4(viewinv, cam_ob_eval->obmat);
+ copy_m4_m4(viewinv, cam_ob_eval->object_to_world);
normalize_m4(viewinv);
invert_m4_m4(viewmat, viewinv);
@@ -4062,6 +4064,8 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p
}
ps->mloop_eval = BKE_mesh_loops(ps->me_eval);
ps->mpoly_eval = BKE_mesh_polys(ps->me_eval);
+ ps->select_poly_eval = (const bool *)CustomData_get_layer_named(
+ &ps->me_eval->pdata, CD_PROP_BOOL, ".select_poly");
ps->material_indices = (const int *)CustomData_get_layer_named(
&ps->me_eval->pdata, CD_PROP_INT32, "material_index");
@@ -4071,7 +4075,7 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p
ps->totloop_eval = ps->me_eval->totloop;
ps->mlooptri_eval = BKE_mesh_runtime_looptri_ensure(ps->me_eval);
- ps->totlooptri_eval = ps->me_eval->runtime.looptris.len;
+ ps->totlooptri_eval = BKE_mesh_runtime_looptri_len(ps->me_eval);
ps->poly_to_loop_uv = MEM_mallocN(ps->totpoly_eval * sizeof(MLoopUV *), "proj_paint_mtfaces");
@@ -4145,7 +4149,7 @@ static bool project_paint_clone_face_skip(ProjPaintState *ps,
}
typedef struct {
- const MPoly *mpoly_orig;
+ const bool *select_poly_orig;
const int *index_mp_to_orig;
} ProjPaintFaceLookup;
@@ -4154,8 +4158,10 @@ static void proj_paint_face_lookup_init(const ProjPaintState *ps, ProjPaintFaceL
{
memset(face_lookup, 0, sizeof(*face_lookup));
if (ps->do_face_sel) {
+ Mesh *orig_mesh = (Mesh *)ps->ob->data;
face_lookup->index_mp_to_orig = CustomData_get_layer(&ps->me_eval->pdata, CD_ORIGINDEX);
- face_lookup->mpoly_orig = BKE_mesh_polys((Mesh *)ps->ob->data);
+ face_lookup->select_poly_orig = CustomData_get_layer_named(
+ &orig_mesh->pdata, CD_PROP_BOOL, ".select_poly");
}
}
@@ -4166,17 +4172,12 @@ static bool project_paint_check_face_sel(const ProjPaintState *ps,
{
if (ps->do_face_sel) {
int orig_index;
- const MPoly *mp;
if ((face_lookup->index_mp_to_orig != NULL) &&
- (((orig_index = (face_lookup->index_mp_to_orig[lt->poly]))) != ORIGINDEX_NONE)) {
- mp = &face_lookup->mpoly_orig[orig_index];
+ ((orig_index = (face_lookup->index_mp_to_orig[lt->poly])) != ORIGINDEX_NONE)) {
+ return face_lookup->select_poly_orig && face_lookup->select_poly_orig[orig_index];
}
- else {
- mp = &ps->mpoly_eval[lt->poly];
- }
-
- return ((mp->flag & ME_FACE_SEL) != 0);
+ return ps->select_poly_eval && ps->select_poly_eval[lt->poly];
}
return true;
}
@@ -4462,7 +4463,7 @@ static void project_paint_begin(const bContext *C,
if (ps->source == PROJ_SRC_VIEW) {
/* faster clipping lookups */
- ED_view3d_clipping_local(ps->rv3d, ps->ob->obmat);
+ ED_view3d_clipping_local(ps->rv3d, ps->ob->object_to_world);
}
ps->do_face_sel = ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) != 0);
@@ -5370,7 +5371,7 @@ static void do_projectpaint_thread(TaskPool *__restrict UNUSED(pool), void *ph_v
/* Color texture (alpha used as mask). */
if (ps->is_texbrush) {
- MTex *mtex = &brush->mtex;
+ const MTex *mtex = BKE_brush_color_texture_get(brush, OB_MODE_TEXTURE_PAINT);
float samplecos[3];
float texrgba[4];
@@ -5386,7 +5387,8 @@ static void do_projectpaint_thread(TaskPool *__restrict UNUSED(pool), void *ph_v
/* NOTE: for clone and smear,
* we only use the alpha, could be a special function */
- BKE_brush_sample_tex_3d(ps->scene, brush, samplecos, texrgba, thread_index, pool);
+ BKE_brush_sample_tex_3d(
+ ps->scene, brush, mtex, samplecos, texrgba, thread_index, pool);
copy_v3_v3(texrgb, texrgba);
custom_mask *= texrgba[3];
@@ -6042,6 +6044,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
int orig_brush_size;
IDProperty *idgroup;
IDProperty *view_data = NULL;
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
bool uvs, mat, tex;
@@ -6249,8 +6252,8 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
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 */
+ /* NOTE(@sergey): Mostly happens when OpenGL off-screen buffer was failed to create, */
+ /* but could be other reasons. Should be handled in the future. */
BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer: %s", err_out);
return OPERATOR_CANCELLED;
}
@@ -6702,6 +6705,7 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op)
BKE_texpaint_slot_refresh_cache(scene, ma, ob);
BKE_image_signal(bmain, ima, NULL, IMA_SIGNAL_USER_NEW_IMAGE);
WM_event_add_notifier(C, NC_IMAGE | NA_ADDED, ima);
+ ED_space_image_sync(bmain, ima, false);
}
if (layer) {
BKE_texpaint_slot_refresh_cache(scene, ma, ob);
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index 99c25953d50..c6fe7ed3072 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -100,6 +100,8 @@ struct ViewContext *paint_stroke_view_context(struct PaintStroke *stroke);
void *paint_stroke_mode_data(struct PaintStroke *stroke);
float paint_stroke_distance_get(struct PaintStroke *stroke);
void paint_stroke_set_mode_data(struct PaintStroke *stroke, void *mode_data);
+bool paint_stroke_started(struct PaintStroke *stroke);
+
bool PAINT_brush_tool_poll(struct bContext *C);
/**
* Delete overlay cursor textures to preserve memory and invalidate all overlay flags.
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index 437ff7506ba..ce7db91571c 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -31,6 +31,7 @@
#include "BKE_multires.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
+#include "BKE_scene.h"
#include "BKE_subsurf.h"
#include "DEG_depsgraph.h"
@@ -41,12 +42,10 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "ED_screen.h"
#include "ED_sculpt.h"
#include "ED_view3d.h"
#include "bmesh.h"
-#include "bmesh_tools.h"
#include "tools/bmesh_boolean.h"
#include "paint_intern.h"
@@ -148,7 +147,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
value = RNA_float_get(op->ptr, "value");
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
- BKE_sculpt_mask_layers_ensure(ob, mmd);
+ BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd);
BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true, false);
pbvh = ob->sculpt->pbvh;
@@ -349,7 +348,7 @@ static void sculpt_gesture_context_init_common(bContext *C,
copy_m3_m4(mat, sgcontext->vc.rv3d->viewinv);
mul_m3_v3(mat, view_dir);
normalize_v3_v3(sgcontext->world_space_view_normal, view_dir);
- copy_m3_m4(mat, ob->imat);
+ copy_m3_m4(mat, ob->world_to_object);
mul_m3_v3(mat, view_dir);
normalize_v3_v3(sgcontext->true_view_normal, view_dir);
@@ -461,12 +460,12 @@ static void sculpt_gesture_line_plane_from_tri(float *r_plane,
{
float normal[3];
normal_tri_v3(normal, p1, p2, p3);
- mul_v3_mat3_m4v3(normal, sgcontext->vc.obact->imat, normal);
+ mul_v3_mat3_m4v3(normal, sgcontext->vc.obact->world_to_object, normal);
if (flip) {
mul_v3_fl(normal, -1.0f);
}
float plane_point_object_space[3];
- mul_v3_m4v3(plane_point_object_space, sgcontext->vc.obact->imat, p1);
+ mul_v3_m4v3(plane_point_object_space, sgcontext->vc.obact->world_to_object, p1);
plane_from_point_normal_v3(r_plane, plane_point_object_space, normal);
}
@@ -863,7 +862,9 @@ static void sculpt_gesture_mask_end(bContext *C, SculptGestureContext *sgcontext
BKE_pbvh_update_vertex_data(sgcontext->ss->pbvh, PBVH_UpdateMask);
}
-static void sculpt_gesture_init_mask_properties(SculptGestureContext *sgcontext, wmOperator *op)
+static void sculpt_gesture_init_mask_properties(bContext *C,
+ SculptGestureContext *sgcontext,
+ wmOperator *op)
{
sgcontext->operation = MEM_callocN(sizeof(SculptGestureMaskOperation), "Mask Operation");
@@ -871,7 +872,8 @@ static void sculpt_gesture_init_mask_properties(SculptGestureContext *sgcontext,
Object *object = sgcontext->vc.obact;
MultiresModifierData *mmd = BKE_sculpt_multires_active(sgcontext->vc.scene, object);
- BKE_sculpt_mask_layers_ensure(sgcontext->vc.obact, mmd);
+ BKE_sculpt_mask_layers_ensure(
+ CTX_data_depsgraph_pointer(C), CTX_data_main(C), sgcontext->vc.obact, mmd);
mask_operation->op.sculpt_gesture_begin = sculpt_gesture_mask_begin;
mask_operation->op.sculpt_gesture_apply_for_symmetry_pass =
@@ -1007,11 +1009,12 @@ static void sculpt_gesture_trim_shape_origin_normal_get(SculptGestureContext *sg
copy_v3_v3(r_normal, sgcontext->world_space_view_normal);
break;
case SCULPT_GESTURE_TRIM_ORIENTATION_SURFACE:
- mul_v3_m4v3(r_origin, sgcontext->vc.obact->obmat, sgcontext->ss->gesture_initial_location);
+ mul_v3_m4v3(
+ r_origin, sgcontext->vc.obact->object_to_world, sgcontext->ss->gesture_initial_location);
/* Transforming the normal does not take non uniform scaling into account. Sculpt mode is not
* expected to work on object with non uniform scaling. */
copy_v3_v3(r_normal, sgcontext->ss->gesture_initial_normal);
- mul_mat3_m4_v3(sgcontext->vc.obact->obmat, r_normal);
+ mul_mat3_m4_v3(sgcontext->vc.obact->object_to_world, r_normal);
break;
}
}
@@ -1042,7 +1045,7 @@ static void sculpt_gesture_trim_calculate_depth(SculptGestureContext *sgcontext)
* mesh, coordinates are first calculated in world space, then converted to object space to
* store them. */
float world_space_vco[3];
- mul_v3_m4v3(world_space_vco, vc->obact->obmat, vco);
+ mul_v3_m4v3(world_space_vco, vc->obact->object_to_world, vco);
const float dist = dist_signed_to_plane_v3(world_space_vco, shape_plane);
trim_operation->depth_front = min_ff(dist, trim_operation->depth_front);
trim_operation->depth_back = max_ff(dist, trim_operation->depth_back);
@@ -1050,8 +1053,9 @@ static void sculpt_gesture_trim_calculate_depth(SculptGestureContext *sgcontext)
if (trim_operation->use_cursor_depth) {
float world_space_gesture_initial_location[3];
- mul_v3_m4v3(
- world_space_gesture_initial_location, vc->obact->obmat, ss->gesture_initial_location);
+ mul_v3_m4v3(world_space_gesture_initial_location,
+ vc->obact->object_to_world,
+ ss->gesture_initial_location);
float mid_point_depth;
if (trim_operation->orientation == SCULPT_GESTURE_TRIM_ORIENTATION_VIEW) {
@@ -1130,7 +1134,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex
sculpt_gesture_trim_shape_origin_normal_get(sgcontext, shape_origin, shape_normal);
plane_from_point_normal_v3(shape_plane, shape_origin, shape_normal);
- const float(*ob_imat)[4] = vc->obact->imat;
+ const float(*ob_imat)[4] = vc->obact->world_to_object;
/* Write vertices coordinates for the front face. */
MVert *verts = BKE_mesh_verts_for_write(trim_operation->mesh);
@@ -1354,7 +1358,9 @@ static void sculpt_gesture_trim_end(bContext *UNUSED(C), SculptGestureContext *s
{
Object *object = sgcontext->vc.obact;
SculptSession *ss = object->sculpt;
- ss->face_sets = CustomData_get_layer(&((Mesh *)object->data)->pdata, CD_SCULPT_FACE_SETS);
+
+ ss->face_sets = CustomData_get_layer_named(
+ &((Mesh *)object->data)->pdata, CD_PROP_INT32, ".sculpt_face_set");
if (ss->face_sets) {
/* Assign a new Face Set ID to the new faces created by the trim operation. */
const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(object->data);
@@ -1514,7 +1520,7 @@ static int paint_mask_gesture_box_exec(bContext *C, wmOperator *op)
if (!sgcontext) {
return OPERATOR_CANCELLED;
}
- sculpt_gesture_init_mask_properties(sgcontext, op);
+ sculpt_gesture_init_mask_properties(C, sgcontext, op);
sculpt_gesture_apply(C, sgcontext, op);
sculpt_gesture_context_free(sgcontext);
return OPERATOR_FINISHED;
@@ -1526,7 +1532,7 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
if (!sgcontext) {
return OPERATOR_CANCELLED;
}
- sculpt_gesture_init_mask_properties(sgcontext, op);
+ sculpt_gesture_init_mask_properties(C, sgcontext, op);
sculpt_gesture_apply(C, sgcontext, op);
sculpt_gesture_context_free(sgcontext);
return OPERATOR_FINISHED;
@@ -1538,7 +1544,7 @@ static int paint_mask_gesture_line_exec(bContext *C, wmOperator *op)
if (!sgcontext) {
return OPERATOR_CANCELLED;
}
- sculpt_gesture_init_mask_properties(sgcontext, op);
+ sculpt_gesture_init_mask_properties(C, sgcontext, op);
sculpt_gesture_apply(C, sgcontext, op);
sculpt_gesture_context_free(sgcontext);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 60f4a9d59a5..f1f864fdf82 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -249,7 +249,7 @@ static bool paint_stroke_use_scene_spacing(Brush *brush, ePaintMode mode)
static bool paint_tool_raycast_original(Brush *brush, ePaintMode UNUSED(mode))
{
- return brush->flag & BRUSH_ANCHORED;
+ return brush->flag & (BRUSH_ANCHORED | BRUSH_DRAG_DOT);
}
static bool paint_tool_require_inbetween_mouse_events(Brush *brush, ePaintMode mode)
@@ -564,7 +564,7 @@ static void paint_brush_stroke_add_step(
if (SCULPT_stroke_get_location(
C, world_space_position, stroke->last_mouse_position, stroke->original)) {
copy_v3_v3(stroke->last_world_space_position, world_space_position);
- mul_m4_v3(stroke->vc.obact->obmat, stroke->last_world_space_position);
+ mul_m4_v3(stroke->vc.obact->object_to_world, stroke->last_world_space_position);
}
else {
add_v3_v3(stroke->last_world_space_position, stroke->last_scene_spacing_delta);
@@ -681,8 +681,9 @@ static float paint_space_stroke_spacing(bContext *C,
if (paint_stroke_use_scene_spacing(brush, mode)) {
if (!BKE_brush_use_locked_size(scene, brush)) {
float last_object_space_position[3];
- mul_v3_m4v3(
- last_object_space_position, stroke->vc.obact->imat, stroke->last_world_space_position);
+ mul_v3_m4v3(last_object_space_position,
+ stroke->vc.obact->world_to_object,
+ stroke->last_world_space_position);
size_clamp = paint_calc_object_space_radius(&stroke->vc, last_object_space_position, size);
}
else {
@@ -825,7 +826,7 @@ static int paint_space_stroke(bContext *C,
if (use_scene_spacing) {
float world_space_position[3];
bool hit = SCULPT_stroke_get_location(C, world_space_position, final_mouse, stroke->original);
- mul_m4_v3(stroke->vc.obact->obmat, world_space_position);
+ mul_m4_v3(stroke->vc.obact->object_to_world, world_space_position);
if (hit && stroke->stroke_over_mesh) {
sub_v3_v3v3(d_world_space_position, world_space_position, stroke->last_world_space_position);
length = len_v3(d_world_space_position);
@@ -1140,7 +1141,7 @@ struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf)
struct wmKeyMap *keymap = WM_modalkeymap_find(keyconf, name);
- /* this function is called for each spacetype, only needs to add map once */
+ /* This function is called for each space-type, only needs to add map once. */
if (!keymap) {
keymap = WM_modalkeymap_ensure(keyconf, name, modal_items);
}
@@ -1216,8 +1217,8 @@ static void paint_line_strokes_spacing(bContext *C,
C, world_space_position_old, old_pos, stroke->original);
bool hit_new = SCULPT_stroke_get_location(
C, world_space_position_new, new_pos, stroke->original);
- mul_m4_v3(stroke->vc.obact->obmat, world_space_position_old);
- mul_m4_v3(stroke->vc.obact->obmat, world_space_position_new);
+ mul_m4_v3(stroke->vc.obact->object_to_world, world_space_position_old);
+ mul_m4_v3(stroke->vc.obact->object_to_world, world_space_position_new);
if (hit_old && hit_new && stroke->stroke_over_mesh) {
sub_v3_v3v3(d_world_space_position, world_space_position_new, world_space_position_old);
length = len_v3(d_world_space_position);
@@ -1360,7 +1361,7 @@ static bool paint_stroke_curve_end(bContext *C, wmOperator *op, PaintStroke *str
if (paint_stroke_use_scene_spacing(br, BKE_paintmode_get_active_from_context(C))) {
stroke->stroke_over_mesh = SCULPT_stroke_get_location(
C, stroke->last_world_space_position, data + 2 * j, stroke->original);
- mul_m4_v3(stroke->vc.obact->obmat, stroke->last_world_space_position);
+ mul_m4_v3(stroke->vc.obact->object_to_world, stroke->last_world_space_position);
}
stroke->stroke_started = stroke->test_start(C, op, stroke->last_mouse_position);
@@ -1492,7 +1493,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintS
if (paint_stroke_use_scene_spacing(br, mode)) {
stroke->stroke_over_mesh = SCULPT_stroke_get_location(
C, stroke->last_world_space_position, sample_average.mouse, stroke->original);
- mul_m4_v3(stroke->vc.obact->obmat, stroke->last_world_space_position);
+ mul_m4_v3(stroke->vc.obact->object_to_world, stroke->last_world_space_position);
}
stroke->stroke_started = stroke->test_start(C, op, sample_average.mouse);
BLI_assert((stroke->stroke_started & ~1) == 0); /* 0/1 */
@@ -1674,6 +1675,11 @@ void paint_stroke_set_mode_data(PaintStroke *stroke, void *mode_data)
stroke->mode_data = mode_data;
}
+bool paint_stroke_started(PaintStroke *stroke)
+{
+ return stroke->stroke_started;
+}
+
bool PAINT_brush_tool_poll(bContext *C)
{
Paint *p = BKE_paint_get_active_from_context(C);
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index 1cedcde7035..f87ca073c82 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -135,12 +135,12 @@ float paint_calc_object_space_radius(ViewContext *vc, const float center[3], flo
float delta[3], scale, loc[3];
const float xy_delta[2] = {pixel_radius, 0.0f};
- mul_v3_m4v3(loc, ob->obmat, center);
+ mul_v3_m4v3(loc, ob->object_to_world, center);
const float zfac = ED_view3d_calc_zfac(vc->rv3d, loc);
ED_view3d_win_to_delta(vc->region, xy_delta, zfac, delta);
- scale = fabsf(mat4_to_scale(ob->obmat));
+ scale = fabsf(mat4_to_scale(ob->object_to_world));
scale = (scale == 0.0f) ? 1.0f : scale;
return len_v3(delta) / scale;
@@ -286,7 +286,7 @@ static void imapaint_pick_uv(
const ePaintCanvasSource mode = scene->toolsettings->imapaint.mode;
const MLoopTri *lt = BKE_mesh_runtime_looptri_ensure(me_eval);
- const int tottri = me_eval->runtime.looptris.len;
+ const int tottri = BKE_mesh_runtime_looptri_len(me_eval);
const MVert *mvert = BKE_mesh_verts(me_eval);
const MLoop *mloop = BKE_mesh_loops(me_eval);
@@ -297,7 +297,7 @@ static void imapaint_pick_uv(
GPU_matrix_model_view_get(matrix);
GPU_matrix_projection_get(proj);
view[0] = view[1] = 0;
- mul_m4_m4m4(matrix, matrix, ob_eval->obmat);
+ mul_m4_m4m4(matrix, matrix, ob_eval->object_to_world);
mul_m4_m4m4(matrix, proj, matrix);
minabsw = 1e10;
@@ -404,6 +404,7 @@ void paint_sample_color(
if (v3d && texpaint_proj) {
/* first try getting a color directly from the mesh faces if possible */
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.cc b/source/blender/editors/sculpt_paint/paint_vertex.cc
index c38a79cb6bb..8e790ac435e 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.cc
+++ b/source/blender/editors/sculpt_paint/paint_vertex.cc
@@ -29,25 +29,21 @@
#include "DNA_scene_types.h"
#include "RNA_access.h"
-#include "RNA_prototypes.h"
#include "BKE_attribute.h"
+#include "BKE_attribute.hh"
#include "BKE_brush.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_deform.h"
#include "BKE_editmesh.h"
-#include "BKE_layer.h"
#include "BKE_lib_id.h"
-#include "BKE_main.h"
#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"
-#include "BKE_subsurf.h"
#include "DEG_depsgraph.h"
@@ -56,7 +52,6 @@
#include "WM_toolsystem.h"
#include "WM_types.h"
-#include "ED_armature.h"
#include "ED_image.h"
#include "ED_mesh.h"
#include "ED_object.h"
@@ -170,8 +165,8 @@ static void view_angle_limits_init(NormalAnglePrecalc *a, float angle, bool do_m
a->angle_inner = a->angle = angle;
}
- a->angle_inner *= (float)(M_PI_2 / 90);
- a->angle *= (float)(M_PI_2 / 90);
+ a->angle_inner *= float(M_PI_2 / 90);
+ a->angle *= float(M_PI_2 / 90);
a->angle_range = a->angle - a->angle_inner;
if (a->angle_range <= 0.0f) {
@@ -397,7 +392,7 @@ static float wpaint_blend(const VPaint *wp,
float weight,
const float alpha,
float paintval,
- const float UNUSED(brush_alpha_value),
+ const float /*brush_alpha_value*/,
const bool do_flip)
{
const Brush *brush = wp->paint.brush;
@@ -438,9 +433,10 @@ static void paint_and_tex_color_alpha_intern(VPaint *vp,
float r_rgba[4])
{
const Brush *brush = BKE_paint_brush(&vp->paint);
- BLI_assert(brush->mtex.tex != nullptr);
- if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) {
- BKE_brush_sample_tex_3d(vc->scene, brush, co, r_rgba, 0, nullptr);
+ const MTex *mtex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT);
+ BLI_assert(mtex->tex != nullptr);
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
+ BKE_brush_sample_tex_3d(vc->scene, brush, mtex, co, r_rgba, 0, nullptr);
}
else {
float co_ss[2]; /* screenspace */
@@ -450,7 +446,7 @@ static void paint_and_tex_color_alpha_intern(VPaint *vp,
co_ss,
(eV3DProjTest)(V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR)) == V3D_PROJ_RET_OK) {
const float co_ss_3d[3] = {co_ss[0], co_ss[1], 0.0f}; /* we need a 3rd empty value */
- BKE_brush_sample_tex_3d(vc->scene, brush, co_ss_3d, r_rgba, 0, nullptr);
+ BKE_brush_sample_tex_3d(vc->scene, brush, mtex, co_ss_3d, r_rgba, 0, nullptr);
}
else {
zero_v4(r_rgba);
@@ -893,7 +889,7 @@ static void do_weight_paint_vertex_single(
else {
/* dv and dv_mirr are the same */
int totweight_prev = dv_mirr->totweight;
- int dw_offset = (int)(dw - dv_mirr->dw);
+ int dw_offset = int(dw - dv_mirr->dw);
dw_mirr = BKE_defvert_ensure_index(dv_mirr, vgroup_mirr);
/* if we added another, get our old one back */
@@ -1651,10 +1647,10 @@ static void vwpaint_update_cache_invariants(
/* cache projection matrix */
ED_view3d_ob_project_mat_get(cache->vc->rv3d, ob, cache->projection_mat);
- invert_m4_m4(ob->imat, ob->obmat);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
copy_m3_m4(mat, cache->vc->rv3d->viewinv);
mul_m3_v3(mat, view_dir);
- copy_m3_m4(mat, ob->imat);
+ copy_m3_m4(mat, ob->world_to_object);
mul_m3_v3(mat, view_dir);
normalize_v3_v3(cache->true_view_normal, view_dir);
@@ -1901,7 +1897,7 @@ static float wpaint_get_active_weight(const MDeformVert *dv, const WeightPaintIn
static void do_wpaint_precompute_weight_cb_ex(void *__restrict userdata,
const int n,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
SculptThreadedTaskData *data = (SculptThreadedTaskData *)userdata;
const MDeformVert *dv = &data->wpi->dvert[n];
@@ -1933,7 +1929,7 @@ static void precompute_weight_values(
static void do_wpaint_brush_blur_task_cb_ex(void *__restrict userdata,
const int n,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
SculptThreadedTaskData *data = (SculptThreadedTaskData *)userdata;
SculptSession *ss = data->ob->sculpt;
@@ -1958,6 +1954,10 @@ static void do_wpaint_brush_blur_task_cb_ex(void *__restrict userdata,
const float *sculpt_normal_frontface = SCULPT_brush_frontface_normal_from_falloff_shape(
ss, data->brush->falloff_shape);
+ const blender::bke::AttributeAccessor attributes = data->me->attributes();
+ const blender::VArray<bool> select_vert = attributes.lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+
/* For each vertex */
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
@@ -1967,9 +1967,8 @@ static void do_wpaint_brush_blur_task_cb_ex(void *__restrict userdata,
* Otherwise, take the current vert. */
const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f;
- const char v_flag = ss->mvert[v_index].flag;
/* If the vertex is selected */
- if (!(use_face_sel || use_vert_sel) || v_flag & SELECT) {
+ if (!(use_face_sel || use_vert_sel) || select_vert[v_index]) {
/* Get the average poly weight */
int total_hit_loops = 0;
float weight_final = 0.0f;
@@ -2023,7 +2022,7 @@ static void do_wpaint_brush_blur_task_cb_ex(void *__restrict userdata,
static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata,
const int n,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
SculptThreadedTaskData *data = (SculptThreadedTaskData *)userdata;
SculptSession *ss = data->ob->sculpt;
@@ -2045,6 +2044,10 @@ static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata,
sub_v3_v3v3(brush_dir, cache->location, cache->last_location);
project_plane_v3_v3v3(brush_dir, brush_dir, cache->view_normal);
+ const blender::bke::AttributeAccessor attributes = data->me->attributes();
+ const blender::VArray<bool> select_vert = attributes.lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+
if (cache->is_last_valid && (normalize_v3(brush_dir) != 0.0f)) {
SculptBrushTest test;
@@ -2065,7 +2068,7 @@ static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata,
const MVert *mv_curr = &ss->mvert[v_index];
/* If the vertex is selected */
- if (!(use_face_sel || use_vert_sel) || mv_curr->flag & SELECT) {
+ if (!(use_face_sel || use_vert_sel) || select_vert[v_index]) {
float brush_strength = cache->bstrength;
const float angle_cos = (use_normal && vd.no) ?
dot_v3v3(sculpt_normal_frontface, vd.no) :
@@ -2120,7 +2123,7 @@ static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata,
}
do_weight_paint_vertex(
- data->vp, data->ob, data->wpi, v_index, final_alpha, (float)weight_final);
+ data->vp, data->ob, data->wpi, v_index, final_alpha, float(weight_final));
}
}
}
@@ -2132,7 +2135,7 @@ static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata,
static void do_wpaint_brush_draw_task_cb_ex(void *__restrict userdata,
const int n,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
SculptThreadedTaskData *data = (SculptThreadedTaskData *)userdata;
SculptSession *ss = data->ob->sculpt;
@@ -2158,6 +2161,10 @@ static void do_wpaint_brush_draw_task_cb_ex(void *__restrict userdata,
const float *sculpt_normal_frontface = SCULPT_brush_frontface_normal_from_falloff_shape(
ss, data->brush->falloff_shape);
+ const blender::bke::AttributeAccessor attributes = data->me->attributes();
+ const blender::VArray<bool> select_vert = attributes.lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+
/* For each vertex */
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
@@ -2169,9 +2176,8 @@ static void do_wpaint_brush_draw_task_cb_ex(void *__restrict userdata,
const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f;
- const char v_flag = ss->mvert[v_index].flag;
/* If the vertex is selected */
- if (!(use_face_sel || use_vert_sel) || v_flag & SELECT) {
+ if (!(use_face_sel || use_vert_sel) || select_vert[v_index]) {
float brush_strength = cache->bstrength;
const float angle_cos = (use_normal && vd.no) ? dot_v3v3(sculpt_normal_frontface, vd.no) :
1.0f;
@@ -2201,8 +2207,9 @@ static void do_wpaint_brush_draw_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_end;
}
-static void do_wpaint_brush_calc_average_weight_cb_ex(
- void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
+static void do_wpaint_brush_calc_average_weight_cb_ex(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict /*tls*/)
{
SculptThreadedTaskData *data = (SculptThreadedTaskData *)userdata;
SculptSession *ss = data->ob->sculpt;
@@ -2224,6 +2231,10 @@ static void do_wpaint_brush_calc_average_weight_cb_ex(
const float *sculpt_normal_frontface = SCULPT_brush_frontface_normal_from_falloff_shape(
ss, data->brush->falloff_shape);
+ const blender::bke::AttributeAccessor attributes = data->me->attributes();
+ const blender::VArray<bool> select_vert = attributes.lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+
/* For each vertex */
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
@@ -2234,10 +2245,9 @@ static void do_wpaint_brush_calc_average_weight_cb_ex(
if (angle_cos > 0.0 &&
BKE_brush_curve_strength(data->brush, sqrtf(test.dist), cache->radius) > 0.0) {
const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
- const char v_flag = ss->mvert[v_index].flag;
/* If the vertex is selected. */
- if (!(use_face_sel || use_vert_sel) || v_flag & SELECT) {
+ if (!(use_face_sel || use_vert_sel) || select_vert[v_index]) {
const MDeformVert *dv = &data->wpi->dvert[v_index];
accum->len += 1;
accum->value += wpaint_get_active_weight(dv, data->wpi);
@@ -2249,7 +2259,7 @@ static void do_wpaint_brush_calc_average_weight_cb_ex(
}
static void calculate_average_weight(SculptThreadedTaskData *data,
- PBVHNode **UNUSED(nodes),
+ PBVHNode ** /*nodes*/,
int totnode)
{
WPaintAverageAccum *accum = (WPaintAverageAccum *)MEM_mallocN(sizeof(*accum) * totnode,
@@ -2268,7 +2278,7 @@ static void calculate_average_weight(SculptThreadedTaskData *data,
}
if (accum_len != 0) {
accum_weight /= accum_len;
- data->strength = (float)accum_weight;
+ data->strength = float(accum_weight);
}
MEM_SAFE_FREE(data->custom_data); /* 'accum' */
@@ -2445,7 +2455,7 @@ static void wpaint_do_symmetrical_brush_actions(
/* symm is a bit combination of XYZ - 1 is mirror
* X; 2 is Y; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */
for (i = 1; i <= symm; i++) {
- if ((symm & i && (symm != 5 || i != 3) && (symm != 6 || (!ELEM(i, 3, 5))))) {
+ if (symm & i && (symm != 5 || i != 3) && (symm != 6 || !ELEM(i, 3, 5))) {
cache->mirror_symmetry_pass = i;
cache->radial_symmetry_pass = 0;
SCULPT_cache_calc_brushdata_symm(cache, i, 0, 0);
@@ -2469,7 +2479,7 @@ static void wpaint_do_symmetrical_brush_actions(
}
static void wpaint_stroke_update_step(bContext *C,
- wmOperator *UNUSED(op),
+ wmOperator * /*op*/,
PaintStroke *stroke,
PointerRNA *itemptr)
{
@@ -2508,7 +2518,7 @@ static void wpaint_stroke_update_step(bContext *C,
ED_view3d_init_mats_rv3d(ob, vc->rv3d);
/* load projection matrix */
- mul_m4_m4m4(mat, vc->rv3d->persmat, ob->obmat);
+ mul_m4_m4m4(mat, vc->rv3d->persmat, ob->object_to_world);
Mesh *mesh = static_cast<Mesh *>(ob->data);
@@ -2546,7 +2556,7 @@ static void wpaint_stroke_update_step(bContext *C,
/* Calculate pivot for rotation around selection if needed.
* also needed for "Frame Selected" on last stroke. */
float loc_world[3];
- mul_v3_m4v3(loc_world, ob->obmat, ss->cache->true_location);
+ mul_v3_m4v3(loc_world, ob->object_to_world, ss->cache->true_location);
paint_last_stroke_update(scene, loc_world);
BKE_mesh_batch_cache_dirty_tag(mesh, BKE_MESH_BATCH_DIRTY_ALL);
@@ -2938,7 +2948,7 @@ static bool vpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
template<class Color = ColorPaint4b, typename Traits = ByteTraits>
static void do_vpaint_brush_blur_loops(bContext *C,
- Sculpt *UNUSED(sd),
+ Sculpt * /*sd*/,
VPaint *vp,
VPaintData<Color, Traits, ATTR_DOMAIN_CORNER> *vpd,
Object *ob,
@@ -2956,6 +2966,11 @@ static void do_vpaint_brush_blur_loops(bContext *C,
Color *previous_color = static_cast<Color *>(ss->cache->prev_colors_vpaint);
+ const blender::VArray<bool> select_vert = me->attributes().lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+ const blender::VArray<bool> select_poly = me->attributes().lookup_or_default<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE, false);
+
blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) {
for (int n : range) {
const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh);
@@ -2987,10 +3002,9 @@ static void do_vpaint_brush_blur_loops(bContext *C,
const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v :
vd.vert_indices[vd.i];
const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f;
- const MVert *mv = &ss->mvert[v_index];
/* If the vertex is selected for painting. */
- if (!use_vert_sel || mv->flag & SELECT) {
+ if (!use_vert_sel || select_vert[v_index]) {
float brush_strength = cache->bstrength;
const float angle_cos = (use_normal && vd.no) ?
dot_v3v3(sculpt_normal_frontface, vd.no) :
@@ -3011,7 +3025,7 @@ static void do_vpaint_brush_blur_loops(bContext *C,
for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) {
int p_index = gmap->vert_to_poly[v_index].indices[j];
const MPoly *mp = &ss->mpoly[p_index];
- if (!use_face_sel || mp->flag & ME_FACE_SEL) {
+ if (!use_face_sel || select_poly[p_index]) {
total_hit_loops += mp->totloop;
for (int k = 0; k < mp->totloop; k++) {
const uint l_index = mp->loopstart + k;
@@ -3045,8 +3059,7 @@ static void do_vpaint_brush_blur_loops(bContext *C,
const int p_index = gmap->vert_to_poly[v_index].indices[j];
const int l_index = gmap->vert_to_loop[v_index].indices[j];
BLI_assert(ss->mloop[l_index].v == v_index);
- const MPoly *mp = &ss->mpoly[p_index];
- if (!use_face_sel || mp->flag & ME_FACE_SEL) {
+ if (!use_face_sel || select_poly[p_index]) {
Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */
if (previous_color != nullptr) {
@@ -3080,7 +3093,7 @@ static void do_vpaint_brush_blur_loops(bContext *C,
template<class Color = ColorPaint4b, typename Traits = ByteTraits>
static void do_vpaint_brush_blur_verts(bContext *C,
- Sculpt *UNUSED(sd),
+ Sculpt * /*sd*/,
VPaint *vp,
VPaintData<Color, Traits, ATTR_DOMAIN_POINT> *vpd,
Object *ob,
@@ -3098,6 +3111,11 @@ static void do_vpaint_brush_blur_verts(bContext *C,
Color *previous_color = static_cast<Color *>(ss->cache->prev_colors_vpaint);
+ const blender::VArray<bool> select_vert = me->attributes().lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+ const blender::VArray<bool> select_poly = me->attributes().lookup_or_default<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE, false);
+
blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) {
for (int n : range) {
const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh);
@@ -3129,10 +3147,9 @@ static void do_vpaint_brush_blur_verts(bContext *C,
const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v :
vd.vert_indices[vd.i];
const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f;
- const MVert *mv = &ss->mvert[v_index];
/* If the vertex is selected for painting. */
- if (!use_vert_sel || mv->flag & SELECT) {
+ if (!use_vert_sel || select_vert[v_index]) {
float brush_strength = cache->bstrength;
const float angle_cos = (use_normal && vd.no) ?
dot_v3v3(sculpt_normal_frontface, vd.no) :
@@ -3153,7 +3170,7 @@ static void do_vpaint_brush_blur_verts(bContext *C,
for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) {
int p_index = gmap->vert_to_poly[v_index].indices[j];
const MPoly *mp = &ss->mpoly[p_index];
- if (!use_face_sel || mp->flag & ME_FACE_SEL) {
+ if (!use_face_sel || select_poly[p_index]) {
total_hit_loops += mp->totloop;
for (int k = 0; k < mp->totloop; k++) {
const uint l_index = mp->loopstart + k;
@@ -3190,8 +3207,7 @@ static void do_vpaint_brush_blur_verts(bContext *C,
BLI_assert(ss->mloop[gmap->vert_to_loop[v_index].indices[j]].v == v_index);
- const MPoly *mp = &ss->mpoly[p_index];
- if (!use_face_sel || mp->flag & ME_FACE_SEL) {
+ if (!use_face_sel || select_poly[p_index]) {
Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */
if (previous_color != nullptr) {
@@ -3225,7 +3241,7 @@ static void do_vpaint_brush_blur_verts(bContext *C,
template<typename Color = ColorPaint4b, typename Traits, eAttrDomain domain>
static void do_vpaint_brush_smear(bContext *C,
- Sculpt *UNUSED(sd),
+ Sculpt * /*sd*/,
VPaint *vp,
VPaintData<Color, Traits, domain> *vpd,
Object *ob,
@@ -3247,6 +3263,11 @@ static void do_vpaint_brush_smear(bContext *C,
Color *color_prev_smear = static_cast<Color *>(vpd->smear.color_prev);
Color *color_prev = reinterpret_cast<Color *>(ss->cache->prev_colors_vpaint);
+ const blender::VArray<bool> select_vert = me->attributes().lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+ const blender::VArray<bool> select_poly = me->attributes().lookup_or_default<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE, false);
+
blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) {
for (int n : range) {
float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
@@ -3283,7 +3304,7 @@ static void do_vpaint_brush_smear(bContext *C,
const MVert *mv_curr = &ss->mvert[v_index];
/* if the vertex is selected for painting. */
- if (!use_vert_sel || mv_curr->flag & SELECT) {
+ if (!use_vert_sel || select_vert[v_index]) {
/* Calc the dot prod. between ray norm on surf and current vert
* (ie splash prevention factor), and only paint front facing verts. */
float brush_strength = cache->bstrength;
@@ -3312,7 +3333,7 @@ static void do_vpaint_brush_smear(bContext *C,
BLI_assert(ss->mloop[l_index].v == v_index);
UNUSED_VARS_NDEBUG(l_index);
const MPoly *mp = &ss->mpoly[p_index];
- if (!use_face_sel || mp->flag & ME_FACE_SEL) {
+ if (!use_face_sel || select_poly[p_index]) {
const MLoop *ml_other = &ss->mloop[mp->loopstart];
for (int k = 0; k < mp->totloop; k++, ml_other++) {
const uint v_other_index = ml_other->v;
@@ -3366,8 +3387,7 @@ static void do_vpaint_brush_smear(bContext *C,
BLI_assert(ss->mloop[l_index].v == v_index);
}
- const MPoly *mp = &ss->mpoly[p_index];
- if (!use_face_sel || mp->flag & ME_FACE_SEL) {
+ if (!use_face_sel || select_poly[p_index]) {
/* Get the previous element color */
Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */
@@ -3413,6 +3433,9 @@ static void calculate_average_color(VPaintData<Color, Traits, domain> *vpd,
{
using Blend = typename Traits::BlendType;
+ const blender::VArray<bool> select_vert = me->attributes().lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+
VPaintAverageAccum<Blend> *accum = (VPaintAverageAccum<Blend> *)MEM_mallocN(
sizeof(*accum) * totnode, __func__);
blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) {
@@ -3443,8 +3466,7 @@ static void calculate_average_color(VPaintData<Color, Traits, domain> *vpd,
vd.vert_indices[vd.i];
if (BKE_brush_curve_strength(brush, 0.0, cache->radius) > 0.0) {
/* If the vertex is selected for painting. */
- const MVert *mv = &ss->mvert[v_index];
- if (!use_vert_sel || mv->flag & SELECT) {
+ if (!use_vert_sel || select_vert[v_index]) {
accum2->len += gmap->vert_to_loop[v_index].count;
/* if a vertex is within the brush region, then add its color to the blend. */
for (int j = 0; j < gmap->vert_to_loop[v_index].count; j++) {
@@ -3512,7 +3534,7 @@ static float paint_and_tex_color_alpha(VPaint *vp,
template<typename Color, typename Traits, eAttrDomain domain>
static void vpaint_do_draw(bContext *C,
- Sculpt *UNUSED(sd),
+ Sculpt * /*sd*/,
VPaint *vp,
VPaintData<Color, Traits, domain> *vpd,
Object *ob,
@@ -3529,6 +3551,11 @@ static void vpaint_do_draw(bContext *C,
Color *previous_color = static_cast<Color *>(ss->cache->prev_colors_vpaint);
+ const blender::VArray<bool> select_vert = me->attributes().lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+ const blender::VArray<bool> select_poly = me->attributes().lookup_or_default<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE, false);
+
blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) {
for (int n : range) {
const bool has_grids = (pbvh_type == PBVH_GRIDS);
@@ -3562,10 +3589,9 @@ static void vpaint_do_draw(bContext *C,
const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v :
vd.vert_indices[vd.i];
const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f;
- const MVert *mv = &ss->mvert[v_index];
/* If the vertex is selected for painting. */
- if (!use_vert_sel || mv->flag & SELECT) {
+ if (!use_vert_sel || select_vert[v_index]) {
/* Calc the dot prod. between ray norm on surf and current vert
* (ie splash prevention factor), and only paint front facing verts. */
float brush_strength = cache->bstrength;
@@ -3617,8 +3643,7 @@ static void vpaint_do_draw(bContext *C,
const int p_index = gmap->vert_to_poly[v_index].indices[j];
const int l_index = gmap->vert_to_loop[v_index].indices[j];
BLI_assert(ss->mloop[l_index].v == v_index);
- const MPoly *mp = &ss->mpoly[p_index];
- if (!use_face_sel || mp->flag & ME_FACE_SEL) {
+ if (!use_face_sel || select_poly[p_index]) {
Color color_orig = Color(0, 0, 0, 0); /* unused when array is nullptr */
if (previous_color != nullptr) {
@@ -3778,7 +3803,7 @@ static void vpaint_do_symmetrical_brush_actions(
/* symm is a bit combination of XYZ - 1 is mirror
* X; 2 is Y; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */
for (i = 1; i <= symm; i++) {
- if (symm & i && (symm != 5 || i != 3) && (symm != 6 || (!ELEM(i, 3, 5)))) {
+ if (symm & i && (symm != 5 || i != 3) && (symm != 6 || !ELEM(i, 3, 5))) {
cache->mirror_symmetry_pass = i;
cache->radial_symmetry_pass = 0;
SCULPT_cache_calc_brushdata_symm(cache, i, 0, 0);
@@ -3822,7 +3847,7 @@ static void vpaint_stroke_update_step_intern(bContext *C, PaintStroke *stroke, P
ED_view3d_init_mats_rv3d(ob, vc->rv3d);
/* load projection matrix */
- mul_m4_m4m4(mat, vc->rv3d->persmat, ob->obmat);
+ mul_m4_m4m4(mat, vc->rv3d->persmat, ob->object_to_world);
swap_m4m4(vc->rv3d->persmat, mat);
@@ -3845,7 +3870,7 @@ static void vpaint_stroke_update_step_intern(bContext *C, PaintStroke *stroke, P
/* Calculate pivot for rotation around selection if needed.
* also needed for "Frame Selected" on last stroke. */
float loc_world[3];
- mul_v3_m4v3(loc_world, ob->obmat, ss->cache->true_location);
+ mul_v3_m4v3(loc_world, ob->object_to_world, ss->cache->true_location);
paint_last_stroke_update(scene, loc_world);
ED_region_tag_redraw(vc->region);
@@ -3854,7 +3879,7 @@ static void vpaint_stroke_update_step_intern(bContext *C, PaintStroke *stroke, P
}
static void vpaint_stroke_update_step(bContext *C,
- wmOperator *UNUSED(op),
+ wmOperator * /*op*/,
PaintStroke *stroke,
PointerRNA *itemptr)
{
@@ -3883,7 +3908,7 @@ static void vpaint_stroke_update_step(bContext *C,
}
template<typename Color, typename Traits, eAttrDomain domain>
-static void vpaint_free_vpaintdata(Object *UNUSED(ob), void *_vpd)
+static void vpaint_free_vpaintdata(Object * /*ob*/, void *_vpd)
{
VPaintData<Color, Traits, domain> *vpd = static_cast<VPaintData<Color, Traits, domain> *>(_vpd);
@@ -4045,6 +4070,11 @@ static bool vertex_color_set(Object *ob, ColorPaint4f paintcol_in, CustomDataLay
return false;
}
+ const blender::VArray<bool> select_vert = me->attributes().lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
+ const blender::VArray<bool> select_poly = me->attributes().lookup_or_default<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE, false);
+
Color paintcol = fromFloat<Color>(paintcol_in);
const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
@@ -4073,7 +4103,7 @@ static bool vertex_color_set(Object *ob, ColorPaint4f paintcol_in, CustomDataLay
BMLoop *l = f->l_first;
do {
- if (!(use_vert_sel && !(BM_elem_flag_test(l->v, BM_ELEM_SELECT)))) {
+ if (!(use_vert_sel && !BM_elem_flag_test(l->v, BM_ELEM_SELECT))) {
if constexpr (domain == ATTR_DOMAIN_CORNER) {
color = static_cast<Color *>(BM_ELEM_CD_GET_VOID_P(l, cd_offset));
}
@@ -4088,21 +4118,20 @@ static bool vertex_color_set(Object *ob, ColorPaint4f paintcol_in, CustomDataLay
}
else {
Color *color_layer = static_cast<Color *>(layer->data);
- const Span<MVert> verts = me->verts();
const Span<MPoly> polys = me->polys();
const Span<MLoop> loops = me->loops();
for (const int i : polys.index_range()) {
- const MPoly &poly = polys[i];
- if (use_face_sel && !(poly.flag & ME_FACE_SEL)) {
+ if (use_face_sel && !select_poly[i]) {
continue;
}
+ const MPoly &poly = polys[i];
int j = 0;
do {
uint vidx = loops[poly.loopstart + j].v;
- if (!(use_vert_sel && !(verts[vidx].flag & SELECT))) {
+ if (!(use_vert_sel && !(select_vert[vidx]))) {
if constexpr (domain == ATTR_DOMAIN_CORNER) {
color_layer[poly.loopstart + j] = paintcol;
}
@@ -4177,7 +4206,7 @@ extern "C" bool BKE_object_attributes_active_color_fill(Object *ob,
return paint_object_attributes_active_color_fill_ex(ob, ColorPaint4f(fill_color), only_selected);
}
-static int vertex_color_set_exec(bContext *C, wmOperator *UNUSED(op))
+static int vertex_color_set_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
Object *obact = CTX_data_active_object(C);
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc
index 10ad4c2192f..09374422888 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc
+++ b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc
@@ -49,7 +49,7 @@ static bool vertex_weight_paint_mode_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
Mesh *me = BKE_mesh_from_object(ob);
- return (ob && (ELEM(ob->mode, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT))) &&
+ return (ob && ELEM(ob->mode, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT)) &&
(me && me->totpoly && !me->deform_verts().is_empty());
}
@@ -73,8 +73,7 @@ static bool vertex_paint_from_weight(Object *ob)
using namespace blender;
Mesh *me;
- if (((me = BKE_mesh_from_object(ob)) == nullptr ||
- (ED_mesh_color_ensure(me, nullptr)) == false)) {
+ if ((me = BKE_mesh_from_object(ob)) == nullptr || ED_mesh_color_ensure(me, nullptr) == false) {
return false;
}
@@ -121,7 +120,7 @@ static bool vertex_paint_from_weight(Object *ob)
return true;
}
-static int vertex_paint_from_weight_exec(bContext *C, wmOperator *UNUSED(op))
+static int vertex_paint_from_weight_exec(bContext *C, wmOperator * /*op*/)
{
Object *obact = CTX_data_active_object(C);
if (vertex_paint_from_weight(obact)) {
@@ -159,29 +158,19 @@ static IndexMask get_selected_indices(const Mesh &mesh,
Vector<int64_t> &indices)
{
using namespace blender;
- const Span<MVert> verts = mesh.verts();
- const Span<MPoly> polys = mesh.polys();
-
- bke::AttributeAccessor attributes = mesh.attributes();
+ const bke::AttributeAccessor attributes = mesh.attributes();
if (mesh.editflag & ME_EDIT_PAINT_FACE_SEL) {
- const VArray<bool> selection = attributes.adapt_domain(
- VArray<bool>::ForFunc(polys.size(),
- [&](const int i) { return polys[i].flag & ME_FACE_SEL; }),
- ATTR_DOMAIN_FACE,
- domain);
-
+ const VArray<bool> selection = attributes.lookup_or_default<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE, false);
return index_mask_ops::find_indices_from_virtual_array(
- IndexMask(attributes.domain_size(domain)), selection, 4096, indices);
+ selection.index_range(), selection, 4096, indices);
}
if (mesh.editflag & ME_EDIT_PAINT_VERT_SEL) {
- const VArray<bool> selection = attributes.adapt_domain(
- VArray<bool>::ForFunc(verts.size(), [&](const int i) { return verts[i].flag & SELECT; }),
- ATTR_DOMAIN_POINT,
- domain);
-
+ const VArray<bool> selection = attributes.lookup_or_default<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT, false);
return index_mask_ops::find_indices_from_virtual_array(
- IndexMask(attributes.domain_size(domain)), selection, 4096, indices);
+ selection.index_range(), selection, 4096, indices);
}
return IndexMask(attributes.domain_size(domain));
}
@@ -228,7 +217,7 @@ static bool vertex_color_smooth(Object *ob)
return true;
}
-static int vertex_color_smooth_exec(bContext *C, wmOperator *UNUSED(op))
+static int vertex_color_smooth_exec(bContext *C, wmOperator * /*op*/)
{
Object *obact = CTX_data_active_object(C);
if (vertex_color_smooth(obact)) {
@@ -320,7 +309,7 @@ static int vertex_color_brightness_contrast_exec(bContext *C, wmOperator *op)
/*
* The algorithm is by Werner D. Streidt
* (http://visca.com/ffactory/archives/5-99/msg00021.html)
- * Extracted of OpenCV demhist.c
+ * Extracted of OpenCV `demhist.c`.
*/
if (contrast > 0) {
gain = 1.0f - delta * 2.0f;
@@ -430,7 +419,7 @@ void PAINT_OT_vertex_color_hsv(wmOperatorType *ot)
RNA_def_float(ot->srna, "v", 1.0f, 0.0f, 2.0f, "Value", "", 0.0f, 2.0f);
}
-static int vertex_color_invert_exec(bContext *C, wmOperator *UNUSED(op))
+static int vertex_color_invert_exec(bContext *C, wmOperator * /*op*/)
{
Object *obact = CTX_data_active_object(C);
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_proj.c b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
index b4e2d4901c9..bac3e7a9e52 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
@@ -10,7 +10,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_listbase.h"
#include "BLI_math.h"
#include "DNA_mesh_types.h"
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
index 0a0d7cff214..fca25ee2e4b 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
@@ -7,7 +7,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_bitmap.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "DNA_brush_types.h"
@@ -445,7 +444,6 @@ static bool weight_paint_set(Object *ob, float paintweight)
/* mutually exclusive, could be made into a */
const short paint_selmode = ME_EDIT_PAINT_SEL_MODE(me);
- const MVert *verts = BKE_mesh_verts(me);
const MPoly *polys = BKE_mesh_polys(me);
const MLoop *loops = BKE_mesh_loops(me);
MDeformVert *dvert = BKE_mesh_deform_verts_for_write(me);
@@ -464,10 +462,15 @@ static bool weight_paint_set(Object *ob, float paintweight)
struct WPaintPrev wpp;
wpaint_prev_create(&wpp, dvert, me->totvert);
+ const bool *select_vert = (const bool *)CustomData_get_layer_named(
+ &me->vdata, CD_PROP_BOOL, ".select_vert");
+ const bool *select_poly = (const bool *)CustomData_get_layer_named(
+ &me->pdata, CD_PROP_BOOL, ".select_poly");
+
for (index = 0, mp = polys; index < me->totpoly; index++, mp++) {
uint fidx = mp->totloop - 1;
- if ((paint_selmode == SCE_SELECT_FACE) && !(mp->flag & ME_FACE_SEL)) {
+ if ((paint_selmode == SCE_SELECT_FACE) && !(select_poly && select_poly[index])) {
continue;
}
@@ -475,7 +478,7 @@ static bool weight_paint_set(Object *ob, float paintweight)
uint vidx = loops[mp->loopstart + fidx].v;
if (!dvert[vidx].flag) {
- if ((paint_selmode == SCE_SELECT_VERTEX) && !(verts[vidx].flag & SELECT)) {
+ if ((paint_selmode == SCE_SELECT_VERTEX) && !(select_vert && select_vert[vidx])) {
continue;
}
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c
index ac16631f115..9ab36fe1402 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c
@@ -203,7 +203,7 @@ BLI_INLINE float wval_screen(float weight, float paintval, float fac)
return weight;
}
mfac = 1.0f - fac;
- temp = max_ff(1.0f - (((1.0f - weight) * (1.0f - paintval))), 0);
+ temp = max_ff(1.0f - ((1.0f - weight) * (1.0f - paintval)), 0);
return mfac * weight + temp * fac;
}
BLI_INLINE float wval_hardlight(float weight, float paintval, float fac)
@@ -258,7 +258,7 @@ BLI_INLINE float wval_exclusion(float weight, float paintval, float fac)
return weight;
}
mfac = 1.0f - fac;
- temp = 0.5f - ((2.0f * (weight - 0.5f) * (paintval - 0.5f)));
+ temp = 0.5f - (2.0f * (weight - 0.5f) * (paintval - 0.5f));
return temp * fac + weight * mfac;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 65e69bd8761..3477285814e 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -12,17 +12,10 @@
#include "BLI_dial_2d.h"
#include "BLI_ghash.h"
#include "BLI_gsqueue.h"
-#include "BLI_hash.h"
#include "BLI_math.h"
-#include "BLI_math_color.h"
-#include "BLI_math_color_blend.h"
#include "BLI_task.h"
#include "BLI_utildefines.h"
-#include "BLT_translation.h"
-
-#include "PIL_time.h"
-
#include "DNA_brush_types.h"
#include "DNA_customdata_types.h"
#include "DNA_mesh_types.h"
@@ -37,24 +30,18 @@
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_image.h"
-#include "BKE_kelvinlet.h"
#include "BKE_key.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
-#include "BKE_mesh_mirror.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
-#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_paint.h"
-#include "BKE_particle.h"
#include "BKE_pbvh.h"
-#include "BKE_pointcache.h"
#include "BKE_report.h"
#include "BKE_scene.h"
-#include "BKE_screen.h"
#include "BKE_subdiv_ccg.h"
#include "BKE_subsurf.h"
@@ -62,29 +49,21 @@
#include "DEG_depsgraph.h"
-#include "IMB_colormanagement.h"
-
#include "WM_api.h"
-#include "WM_message.h"
-#include "WM_toolsystem.h"
#include "WM_types.h"
-#include "ED_object.h"
#include "ED_paint.h"
#include "ED_screen.h"
#include "ED_sculpt.h"
#include "ED_view3d.h"
+
#include "paint_intern.h"
#include "sculpt_intern.h"
#include "RNA_access.h"
#include "RNA_define.h"
-#include "UI_interface.h"
-#include "UI_resources.h"
-
#include "bmesh.h"
-#include "bmesh_tools.h"
#include <math.h>
#include <stdlib.h>
@@ -194,9 +173,10 @@ void SCULPT_vertex_normal_get(SculptSession *ss, PBVHVertRef vertex, float no[3]
const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, PBVHVertRef vertex)
{
- if (ss->persistent_base) {
- return ss->persistent_base[BKE_pbvh_vertex_to_index(ss->pbvh, vertex)].co;
+ if (ss->attrs.persistent_co) {
+ return (const float *)SCULPT_vertex_attr_get(vertex, ss->attrs.persistent_co);
}
+
return SCULPT_vertex_co_get(ss, vertex);
}
@@ -240,8 +220,8 @@ void SCULPT_vertex_limit_surface_get(SculptSession *ss, PBVHVertRef vertex, floa
void SCULPT_vertex_persistent_normal_get(SculptSession *ss, PBVHVertRef vertex, float no[3])
{
- if (ss->persistent_base) {
- copy_v3_v3(no, ss->persistent_base[vertex.i].no);
+ if (ss->attrs.persistent_no) {
+ copy_v3_v3(no, (float *)SCULPT_vertex_attr_get(vertex, ss->attrs.persistent_no));
return;
}
SCULPT_vertex_normal_get(ss, vertex, no);
@@ -249,15 +229,16 @@ void SCULPT_vertex_persistent_normal_get(SculptSession *ss, PBVHVertRef vertex,
float SCULPT_vertex_mask_get(SculptSession *ss, PBVHVertRef vertex)
{
- BMVert *v;
- float *mask;
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES:
return ss->vmask ? ss->vmask[vertex.i] : 0.0f;
- case PBVH_BMESH:
+ case PBVH_BMESH: {
+ BMVert *v;
+ int cd_mask = CustomData_get_offset(&ss->bm->vdata, CD_PAINT_MASK);
+
v = (BMVert *)vertex.i;
- mask = BM_ELEM_CD_GET_VOID_P(v, CustomData_get_offset(&ss->bm->vdata, CD_PAINT_MASK));
- return mask ? *mask : 0.0f;
+ return cd_mask != -1 ? BM_ELEM_CD_GET_FLOAT(v, cd_mask) : 0.0f;
+ }
case PBVH_GRIDS: {
const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
const int grid_index = vertex.i / key->grid_area;
@@ -390,19 +371,15 @@ bool SCULPT_vertex_visible_get(SculptSession *ss, PBVHVertRef vertex)
void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visible)
{
BLI_assert(ss->face_sets != NULL);
+ BLI_assert(ss->hide_poly != NULL);
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES:
case PBVH_GRIDS:
for (int i = 0; i < ss->totfaces; i++) {
- if (abs(ss->face_sets[i]) != face_set) {
+ if (ss->face_sets[i] != face_set) {
continue;
}
- if (visible) {
- ss->face_sets[i] = abs(ss->face_sets[i]);
- }
- else {
- ss->face_sets[i] = -abs(ss->face_sets[i]);
- }
+ ss->hide_poly[i] = !visible;
}
break;
case PBVH_BMESH:
@@ -410,62 +387,59 @@ void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visibl
}
}
-void SCULPT_face_sets_visibility_invert(SculptSession *ss)
+void SCULPT_face_visibility_all_invert(SculptSession *ss)
{
BLI_assert(ss->face_sets != NULL);
+ BLI_assert(ss->hide_poly != NULL);
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES:
case PBVH_GRIDS:
for (int i = 0; i < ss->totfaces; i++) {
- ss->face_sets[i] *= -1;
+ ss->hide_poly[i] = !ss->hide_poly[i];
}
break;
- case PBVH_BMESH:
+ case PBVH_BMESH: {
+ BMIter iter;
+ BMFace *f;
+
+ BM_ITER_MESH (f, &iter, ss->bm, BM_FACES_OF_MESH) {
+ BM_elem_flag_toggle(f, BM_ELEM_HIDDEN);
+ }
break;
+ }
}
}
-void SCULPT_face_sets_visibility_all_set(SculptSession *ss, bool visible)
+void SCULPT_face_visibility_all_set(SculptSession *ss, bool visible)
{
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES:
case PBVH_GRIDS:
- if (!ss->face_sets) {
- return;
- }
- for (int i = 0; i < ss->totfaces; i++) {
-
- /* This can run on geometry without a face set assigned, so its ID sign can't be changed to
- * modify the visibility. Force that geometry to the ID 1 to enable changing the visibility
- * here. */
- if (ss->face_sets[i] == SCULPT_FACE_SET_NONE) {
- ss->face_sets[i] = 1;
- }
+ BLI_assert(ss->hide_poly != NULL);
+ memset(ss->hide_poly, !visible, sizeof(bool) * ss->totfaces);
+ break;
+ case PBVH_BMESH: {
+ BMIter iter;
+ BMFace *f;
- if (visible) {
- ss->face_sets[i] = abs(ss->face_sets[i]);
- }
- else {
- ss->face_sets[i] = -abs(ss->face_sets[i]);
- }
+ BM_ITER_MESH (f, &iter, ss->bm, BM_FACES_OF_MESH) {
+ BM_elem_flag_set(f, BM_ELEM_HIDDEN, !visible);
}
break;
- case PBVH_BMESH:
- break;
+ }
}
}
-bool SCULPT_vertex_any_face_set_visible_get(SculptSession *ss, PBVHVertRef vertex)
+bool SCULPT_vertex_any_face_visible_get(SculptSession *ss, PBVHVertRef vertex)
{
- const bool *hide_poly = BKE_pbvh_get_poly_hide(ss->pbvh);
- if (!hide_poly) {
- return true;
- }
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES: {
- MeshElemMap *vert_map = &ss->pmap[vertex.i];
+ if (!ss->hide_poly) {
+ return true;
+ }
+ const MeshElemMap *vert_map = &ss->pmap[vertex.i];
for (int j = 0; j < ss->pmap[vertex.i].count; j++) {
- if (!hide_poly[vert_map->indices[j]]) {
+ if (!ss->hide_poly[vert_map->indices[j]]) {
return true;
}
}
@@ -479,29 +453,53 @@ bool SCULPT_vertex_any_face_set_visible_get(SculptSession *ss, PBVHVertRef verte
return true;
}
-bool SCULPT_vertex_all_face_sets_visible_get(const SculptSession *ss, PBVHVertRef vertex)
+bool SCULPT_vertex_all_faces_visible_get(const SculptSession *ss, PBVHVertRef vertex)
{
- const bool *hide_poly = BKE_pbvh_get_poly_hide(ss->pbvh);
- if (!hide_poly) {
- return true;
- }
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES: {
- MeshElemMap *vert_map = &ss->pmap[vertex.i];
- for (int j = 0; j < ss->pmap[vertex.i].count; j++) {
- if (hide_poly[vert_map->indices[j]]) {
+ if (!ss->hide_poly) {
+ return true;
+ }
+ const MeshElemMap *vert_map = &ss->pmap[vertex.i];
+ for (int j = 0; j < vert_map->count; j++) {
+ if (ss->hide_poly[vert_map->indices[j]]) {
return false;
}
}
return true;
}
- case PBVH_BMESH:
+ case PBVH_BMESH: {
+ BMVert *v = (BMVert *)vertex.i;
+ BMEdge *e = v->e;
+
+ if (!e) {
+ return true;
+ }
+
+ do {
+ BMLoop *l = e->l;
+
+ if (!l) {
+ continue;
+ }
+
+ do {
+ if (BM_elem_flag_test(l->f, BM_ELEM_HIDDEN)) {
+ return false;
+ }
+ } while ((l = l->radial_next) != e->l);
+ } while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
+
return true;
+ }
case PBVH_GRIDS: {
+ if (!ss->hide_poly) {
+ return true;
+ }
const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
const int grid_index = vertex.i / key->grid_area;
const int face_index = BKE_subdiv_ccg_grid_to_face_index(ss->subdiv_ccg, grid_index);
- return !hide_poly[face_index];
+ return !ss->hide_poly[face_index];
}
}
return true;
@@ -512,13 +510,17 @@ void SCULPT_vertex_face_set_set(SculptSession *ss, PBVHVertRef vertex, int face_
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES: {
BLI_assert(ss->face_sets != NULL);
- MeshElemMap *vert_map = &ss->pmap[vertex.i];
- for (int j = 0; j < ss->pmap[vertex.i].count; j++) {
- if (ss->face_sets[vert_map->indices[j]] > 0) {
- ss->face_sets[vert_map->indices[j]] = abs(face_set);
+ const MeshElemMap *vert_map = &ss->pmap[vertex.i];
+ for (int j = 0; j < vert_map->count; j++) {
+ const int poly_index = vert_map->indices[j];
+ if (ss->hide_poly && ss->hide_poly[poly_index]) {
+ /* Skip hidden faces connected to the vertex. */
+ continue;
}
+ ss->face_sets[poly_index] = face_set;
}
- } break;
+ break;
+ }
case PBVH_BMESH:
break;
case PBVH_GRIDS: {
@@ -526,11 +528,13 @@ void SCULPT_vertex_face_set_set(SculptSession *ss, PBVHVertRef vertex, int face_
const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
const int grid_index = vertex.i / key->grid_area;
const int face_index = BKE_subdiv_ccg_grid_to_face_index(ss->subdiv_ccg, grid_index);
- if (ss->face_sets[face_index] > 0) {
- ss->face_sets[face_index] = abs(face_set);
+ if (ss->hide_poly && ss->hide_poly[face_index]) {
+ /* Skip the vertex if it's in a hidden face. */
+ return;
}
-
- } break;
+ ss->face_sets[face_index] = face_set;
+ break;
+ }
}
}
@@ -541,9 +545,9 @@ int SCULPT_vertex_face_set_get(SculptSession *ss, PBVHVertRef vertex)
if (!ss->face_sets) {
return SCULPT_FACE_SET_NONE;
}
- MeshElemMap *vert_map = &ss->pmap[vertex.i];
+ const MeshElemMap *vert_map = &ss->pmap[vertex.i];
int face_set = 0;
- for (int i = 0; i < ss->pmap[vertex.i].count; i++) {
+ for (int i = 0; i < vert_map->count; i++) {
if (ss->face_sets[vert_map->indices[i]] > face_set) {
face_set = abs(ss->face_sets[vert_map->indices[i]]);
}
@@ -572,8 +576,8 @@ bool SCULPT_vertex_has_face_set(SculptSession *ss, PBVHVertRef vertex, int face_
if (!ss->face_sets) {
return face_set == SCULPT_FACE_SET_NONE;
}
- MeshElemMap *vert_map = &ss->pmap[vertex.i];
- for (int i = 0; i < ss->pmap[vertex.i].count; i++) {
+ const MeshElemMap *vert_map = &ss->pmap[vertex.i];
+ for (int i = 0; i < vert_map->count; i++) {
if (ss->face_sets[vert_map->indices[i]] == face_set) {
return true;
}
@@ -595,61 +599,51 @@ bool SCULPT_vertex_has_face_set(SculptSession *ss, PBVHVertRef vertex, int face_
return true;
}
-void SCULPT_visibility_sync_all_face_sets_to_verts(Object *ob)
+void SCULPT_visibility_sync_all_from_faces(Object *ob)
{
SculptSession *ss = ob->sculpt;
Mesh *mesh = BKE_object_get_original_mesh(ob);
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES: {
- BKE_sculpt_sync_face_sets_visibility_to_base_mesh(mesh);
+ /* We may have adjusted the ".hide_poly" attribute, now make the hide status attributes for
+ * vertices and edges consistent. */
+ BKE_mesh_flush_hidden_from_polys(mesh);
+ BKE_pbvh_update_hide_attributes_from_mesh(ss->pbvh);
break;
}
case PBVH_GRIDS: {
- BKE_sculpt_sync_face_sets_visibility_to_base_mesh(mesh);
- BKE_sculpt_sync_face_sets_visibility_to_grids(mesh, ss->subdiv_ccg);
- break;
- }
- case PBVH_BMESH:
+ /* In addition to making the hide status of the base mesh consistent, we also have to
+ * propagate the status to the Multires grids. */
+ BKE_mesh_flush_hidden_from_polys(mesh);
+ BKE_sculpt_sync_face_visibility_to_grids(mesh, ss->subdiv_ccg);
break;
- }
-}
-
-static void UNUSED_FUNCTION(sculpt_visibility_sync_vertex_to_face_sets)(SculptSession *ss,
- PBVHVertRef vertex)
-{
- MeshElemMap *vert_map = &ss->pmap[vertex.i];
- const bool visible = SCULPT_vertex_visible_get(ss, vertex);
- for (int i = 0; i < ss->pmap[vertex.i].count; i++) {
- if (visible) {
- ss->face_sets[vert_map->indices[i]] = abs(ss->face_sets[vert_map->indices[i]]);
- }
- else {
- ss->face_sets[vert_map->indices[i]] = -abs(ss->face_sets[vert_map->indices[i]]);
}
- }
-}
+ case PBVH_BMESH: {
+ BMIter iter;
+ BMFace *f;
+
+ /* Hide all verts and edges attached to faces.*/
+ BM_ITER_MESH (f, &iter, ss->bm, BM_FACES_OF_MESH) {
+ BMLoop *l = f->l_first;
+ do {
+ BM_elem_flag_enable(l->v, BM_ELEM_HIDDEN);
+ BM_elem_flag_enable(l->e, BM_ELEM_HIDDEN);
+ } while ((l = l->next) != f->l_first);
+ }
-void SCULPT_visibility_sync_all_vertex_to_face_sets(SculptSession *ss)
-{
- if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
- if (ss->face_sets == NULL) {
- return;
- }
- for (int i = 0; i < ss->totfaces; i++) {
- const MPoly *poly = &ss->mpoly[i];
- bool poly_visible = true;
- for (int l = 0; l < poly->totloop; l++) {
- const MLoop *loop = &ss->mloop[poly->loopstart + l];
- if (!SCULPT_vertex_visible_get(ss, BKE_pbvh_make_vref(loop->v))) {
- poly_visible = false;
+ /* Unhide verts and edges attached to visible faces. */
+ BM_ITER_MESH (f, &iter, ss->bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ continue;
}
+
+ BMLoop *l = f->l_first;
+ do {
+ BM_elem_flag_disable(l->v, BM_ELEM_HIDDEN);
+ BM_elem_flag_disable(l->e, BM_ELEM_HIDDEN);
+ } while ((l = l->next) != f->l_first);
}
- if (poly_visible) {
- ss->face_sets[i] = abs(ss->face_sets[i]);
- }
- else {
- ss->face_sets[i] = -abs(ss->face_sets[i]);
- }
+ break;
}
}
}
@@ -659,14 +653,14 @@ static bool sculpt_check_unique_face_set_in_base_mesh(SculptSession *ss, int ind
if (!ss->face_sets) {
return true;
}
- MeshElemMap *vert_map = &ss->pmap[index];
+ const MeshElemMap *vert_map = &ss->pmap[index];
int face_set = -1;
- for (int i = 0; i < ss->pmap[index].count; i++) {
+ for (int i = 0; i < vert_map->count; i++) {
if (face_set == -1) {
- face_set = abs(ss->face_sets[vert_map->indices[i]]);
+ face_set = ss->face_sets[vert_map->indices[i]];
}
else {
- if (abs(ss->face_sets[vert_map->indices[i]]) != face_set) {
+ if (ss->face_sets[vert_map->indices[i]] != face_set) {
return false;
}
}
@@ -680,9 +674,9 @@ static bool sculpt_check_unique_face_set_in_base_mesh(SculptSession *ss, int ind
*/
static bool sculpt_check_unique_face_set_for_edge_in_base_mesh(SculptSession *ss, int v1, int v2)
{
- MeshElemMap *vert_map = &ss->pmap[v1];
+ const MeshElemMap *vert_map = &ss->pmap[v1];
int p1 = -1, p2 = -1;
- for (int i = 0; i < ss->pmap[v1].count; i++) {
+ for (int i = 0; i < vert_map->count; i++) {
const MPoly *p = &ss->mpoly[vert_map->indices[i]];
for (int l = 0; l < p->totloop; l++) {
const MLoop *loop = &ss->mloop[p->loopstart + l];
@@ -750,8 +744,8 @@ int SCULPT_face_set_next_available_get(SculptSession *ss)
}
int next_face_set = 0;
for (int i = 0; i < ss->totfaces; i++) {
- if (abs(ss->face_sets[i]) > next_face_set) {
- next_face_set = abs(ss->face_sets[i]);
+ if (ss->face_sets[i] > next_face_set) {
+ next_face_set = ss->face_sets[i];
}
}
next_face_set++;
@@ -831,21 +825,20 @@ static void sculpt_vertex_neighbors_get_faces(SculptSession *ss,
PBVHVertRef vertex,
SculptVertexNeighborIter *iter)
{
- MeshElemMap *vert_map = &ss->pmap[vertex.i];
+ const MeshElemMap *vert_map = &ss->pmap[vertex.i];
iter->size = 0;
iter->num_duplicates = 0;
iter->capacity = SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY;
iter->neighbors = iter->neighbors_fixed;
iter->neighbor_indices = iter->neighbor_indices_fixed;
- const bool *hide_poly = BKE_pbvh_get_vert_hide(ss->pbvh);
- for (int i = 0; i < ss->pmap[vertex.i].count; i++) {
- if (hide_poly && hide_poly[vert_map->indices[i]]) {
+ for (int i = 0; i < vert_map->count; i++) {
+ if (ss->hide_poly && ss->hide_poly[vert_map->indices[i]]) {
/* Skip connectivity from hidden faces. */
continue;
}
const MPoly *p = &ss->mpoly[vert_map->indices[i]];
- uint f_adj_v[2];
+ int f_adj_v[2];
if (poly_get_adj_loops_from_vert(p, ss->mloop, vertex.i, f_adj_v) != -1) {
for (int j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) {
if (f_adj_v[j] != vertex.i) {
@@ -939,7 +932,7 @@ bool SCULPT_vertex_is_boundary(const SculptSession *ss, const PBVHVertRef vertex
{
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES: {
- if (!SCULPT_vertex_all_face_sets_visible_get(ss, vertex)) {
+ if (!SCULPT_vertex_all_faces_visible_get(ss, vertex)) {
return true;
}
return sculpt_check_boundary_vertex_in_base_mesh(ss, vertex.i);
@@ -1097,7 +1090,7 @@ PBVHVertRef SCULPT_nearest_vertex_get(
bool SCULPT_is_symmetry_iteration_valid(char i, char symm)
{
- return i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (!ELEM(i, 3, 5))));
+ return i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || !ELEM(i, 3, 5)));
}
bool SCULPT_is_vertex_inside_brush_radius_symm(const float vertex[3],
@@ -1128,8 +1121,8 @@ void SCULPT_tag_update_overlays(bContext *C)
DEG_id_tag_update(&ob->id, ID_RECALC_SHADING);
- View3D *v3d = CTX_wm_view3d(C);
- if (!BKE_sculptsession_use_pbvh_draw(ob, v3d)) {
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ if (!BKE_sculptsession_use_pbvh_draw(ob, rv3d)) {
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
}
}
@@ -1315,11 +1308,11 @@ static bool sculpt_brush_use_topology_rake(const SculptSession *ss, const Brush
/**
* Test whether the #StrokeCache.sculpt_normal needs update in #do_brush_action
*/
-static int sculpt_brush_needs_normal(const SculptSession *ss, const Brush *brush)
+static int sculpt_brush_needs_normal(const SculptSession *ss, Sculpt *sd, const Brush *brush)
{
return ((SCULPT_TOOL_HAS_NORMAL_WEIGHT(brush->sculpt_tool) &&
(ss->cache->normal_weight > 0.0f)) ||
-
+ SCULPT_automasking_needs_normal(ss, sd, brush) ||
ELEM(brush->sculpt_tool,
SCULPT_TOOL_BLOB,
SCULPT_TOOL_CREASE,
@@ -1989,7 +1982,7 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
int(*orco_tris)[3];
int orco_tris_num;
- BKE_pbvh_node_get_bm_orco_data(data->nodes[n], &orco_tris, &orco_tris_num, &orco_coords);
+ BKE_pbvh_node_get_bm_orco_data(data->nodes[n], &orco_tris, &orco_tris_num, &orco_coords, NULL);
for (int i = 0; i < orco_tris_num; i++) {
const float *co_tri[3] = {
@@ -2460,11 +2453,12 @@ float SCULPT_brush_strength_factor(SculptSession *ss,
const float fno[3],
float mask,
const PBVHVertRef vertex,
- int thread_id)
+ const int thread_id,
+ AutomaskingNodeData *automask_data)
{
StrokeCache *cache = ss->cache;
const Scene *scene = cache->vc->scene;
- const MTex *mtex = &br->mtex;
+ const MTex *mtex = BKE_brush_mask_texture_get(br, OB_MODE_SCULPT);
float avg = 1.0f;
float rgba[4];
float point[3];
@@ -2476,7 +2470,7 @@ float SCULPT_brush_strength_factor(SculptSession *ss,
}
else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
/* Get strength by feeding the vertex location directly into a texture. */
- avg = BKE_brush_sample_tex_3d(scene, br, point, rgba, 0, ss->tex_pool);
+ avg = BKE_brush_sample_tex_3d(scene, br, mtex, point, rgba, 0, ss->tex_pool);
}
else {
float symm_point[3], point_2d[2];
@@ -2505,19 +2499,19 @@ float SCULPT_brush_strength_factor(SculptSession *ss,
x = symm_point[0];
y = symm_point[1];
- x *= br->mtex.size[0];
- y *= br->mtex.size[1];
+ x *= mtex->size[0];
+ y *= mtex->size[1];
- x += br->mtex.ofs[0];
- y += br->mtex.ofs[1];
+ x += mtex->ofs[0];
+ y += mtex->ofs[1];
- avg = paint_get_tex_pixel(&br->mtex, x, y, ss->tex_pool, thread_id);
+ avg = paint_get_tex_pixel(mtex, x, y, ss->tex_pool, thread_id);
avg += br->texture_sample_bias;
}
else {
const float point_3d[3] = {point_2d[0], point_2d[1], 0.0f};
- avg = BKE_brush_sample_tex_3d(scene, br, point_3d, rgba, 0, ss->tex_pool);
+ avg = BKE_brush_sample_tex_3d(scene, br, mtex, point_3d, rgba, 0, ss->tex_pool);
}
}
@@ -2544,7 +2538,7 @@ float SCULPT_brush_strength_factor(SculptSession *ss,
avg *= 1.0f - mask;
/* Auto-masking. */
- avg *= SCULPT_automasking_factor_get(cache->automasking, ss, vertex);
+ avg *= SCULPT_automasking_factor_get(cache->automasking, ss, vertex, automask_data);
return avg;
}
@@ -2779,14 +2773,14 @@ static void calc_local_y(ViewContext *vc, const float center[3], float y[3])
float loc[3];
const float xy_delta[2] = {0.0f, 1.0f};
- mul_v3_m4v3(loc, ob->imat, center);
+ mul_v3_m4v3(loc, ob->world_to_object, center);
const float zfac = ED_view3d_calc_zfac(vc->rv3d, loc);
ED_view3d_win_to_delta(vc->region, xy_delta, zfac, y);
normalize_v3(y);
add_v3_v3(y, ob->loc);
- mul_m4_v3(ob->imat, y);
+ mul_m4_v3(ob->world_to_object, y);
}
static void calc_brush_local_mat(const Brush *brush, Object *ob, float local_mat[4][4])
@@ -2798,8 +2792,8 @@ static void calc_brush_local_mat(const Brush *brush, Object *ob, float local_mat
float angle, v[3];
float up[3];
- /* Ensure `ob->imat` is up to date. */
- invert_m4_m4(ob->imat, ob->obmat);
+ /* Ensure `ob->world_to_object` is up to date. */
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
/* Initialize last column of matrix. */
mat[0][3] = 0.0f;
@@ -2839,13 +2833,13 @@ void SCULPT_tilt_apply_to_normal(float r_normal[3], StrokeCache *cache, const fl
return;
}
const float rot_max = M_PI_2 * tilt_strength * SCULPT_TILT_SENSITIVITY;
- mul_v3_mat3_m4v3(r_normal, cache->vc->obact->obmat, r_normal);
+ mul_v3_mat3_m4v3(r_normal, cache->vc->obact->object_to_world, r_normal);
float normal_tilt_y[3];
rotate_v3_v3v3fl(normal_tilt_y, r_normal, cache->vc->rv3d->viewinv[0], cache->y_tilt * rot_max);
float normal_tilt_xy[3];
rotate_v3_v3v3fl(
normal_tilt_xy, normal_tilt_y, cache->vc->rv3d->viewinv[1], cache->x_tilt * rot_max);
- mul_v3_mat3_m4v3(r_normal, cache->vc->obact->imat, normal_tilt_xy);
+ mul_v3_mat3_m4v3(r_normal, cache->vc->obact->world_to_object, normal_tilt_xy);
normalize_v3(r_normal);
}
@@ -3031,7 +3025,7 @@ void SCULPT_calc_brush_plane(
}
/* For area normal. */
- if ((!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) &&
+ if (!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache) &&
(brush->flag & BRUSH_ORIGINAL_NORMAL)) {
copy_v3_v3(r_area_no, ss->cache->sculpt_normal);
}
@@ -3040,7 +3034,7 @@ void SCULPT_calc_brush_plane(
}
/* For flatten center. */
- if ((!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) &&
+ if (!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache) &&
(brush->flag & BRUSH_ORIGINAL_PLANE)) {
copy_v3_v3(r_area_co, ss->cache->last_center);
}
@@ -3075,7 +3069,7 @@ void SCULPT_calc_brush_plane(
int SCULPT_plane_trim(const StrokeCache *cache, const Brush *brush, const float val[3])
{
return (!(brush->flag & BRUSH_PLANE_TRIM) ||
- ((dot_v3v3(val, val) <= cache->radius_squared * cache->plane_trim_squared)));
+ (dot_v3v3(val, val) <= cache->radius_squared * cache->plane_trim_squared));
}
int SCULPT_plane_point_side(const float co[3], const float plane[4])
@@ -3134,7 +3128,8 @@ static void do_gravity_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ NULL);
mul_v3_v3fl(proxy[vd.i], offset, fade);
@@ -3271,7 +3266,7 @@ static void sculpt_topology_update(Sculpt *sd,
if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
BKE_pbvh_node_mark_topology_update(nodes[n]);
- BKE_pbvh_bmesh_node_save_orig(ss->bm, nodes[n]);
+ BKE_pbvh_bmesh_node_save_orig(ss->bm, ss->bm_log, nodes[n], false);
}
}
@@ -3289,7 +3284,7 @@ static void sculpt_topology_update(Sculpt *sd,
/* Update average stroke position. */
copy_v3_v3(location, ss->cache->true_location);
- mul_m4_v3(ob->obmat, location);
+ mul_m4_v3(ob->object_to_world, location);
}
static void do_brush_action_task_cb(void *__restrict userdata,
@@ -3348,15 +3343,6 @@ static void do_brush_action(Sculpt *sd,
BKE_pbvh_ensure_node_loops(ss->pbvh);
}
- if (SCULPT_tool_is_mask(brush->sculpt_tool)) {
- MultiresModifierData *mmd = BKE_sculpt_multires_active(ss->scene, ob);
- BKE_sculpt_mask_layers_ensure(ob, mmd);
- }
- if (SCULPT_tool_is_face_sets(brush->sculpt_tool)) {
- Mesh *mesh = BKE_object_get_original_mesh(ob);
- ss->face_sets = BKE_sculpt_face_sets_ensure(mesh);
- }
-
/* Build a list of all nodes that are potentially within the brush's area of influence */
if (SCULPT_tool_needs_all_pbvh_nodes(brush)) {
@@ -3420,6 +3406,8 @@ static void do_brush_action(Sculpt *sd,
/* Initialize auto-masking cache. */
if (SCULPT_is_automasking_enabled(sd, ss, brush)) {
ss->cache->automasking = SCULPT_automasking_cache_init(sd, brush, ob);
+ ss->last_automasking_settings_hash = SCULPT_automasking_settings_hash(
+ ob, ss->cache->automasking);
}
/* Initialize surface smooth cache. */
if ((brush->sculpt_tool == SCULPT_TOOL_SMOOTH) &&
@@ -3450,7 +3438,7 @@ static void do_brush_action(Sculpt *sd,
BLI_task_parallel_range(0, totnode, &task_data, do_brush_action_task_cb, &settings);
}
- if (sculpt_brush_needs_normal(ss, brush)) {
+ if (sculpt_brush_needs_normal(ss, sd, brush)) {
update_sculpt_normal(sd, ob, nodes, totnode);
}
@@ -3602,6 +3590,12 @@ static void do_brush_action(Sculpt *sd,
SCULPT_bmesh_topology_rake(sd, ob, nodes, totnode, brush->topology_rake_factor);
}
+ if (!SCULPT_tool_can_reuse_automask(brush->sculpt_tool) ||
+ (ss->cache->supports_gravity && sd->gravity_factor > 0.0f)) {
+ /* Clear cavity mask cache. */
+ ss->last_automasking_settings_hash = 0;
+ }
+
/* The cloth brush adds the gravity as a regular force and it is processed in the solver. */
if (ss->cache->supports_gravity && !ELEM(brush->sculpt_tool,
SCULPT_TOOL_CLOTH,
@@ -3621,7 +3615,7 @@ static void do_brush_action(Sculpt *sd,
/* Update average stroke position. */
copy_v3_v3(location, ss->cache->true_location);
- mul_m4_v3(ob->obmat, location);
+ mul_m4_v3(ob->object_to_world, location);
add_v3_v3(ups->average_stroke_accum, location);
ups->average_stroke_counter++;
@@ -4207,8 +4201,8 @@ static void sculpt_init_mirror_clipping(Object *ob, SculptSession *ss)
/* Store matrix for mirror object clipping. */
if (mmd->mirror_ob) {
float imtx_mirror_ob[4][4];
- invert_m4_m4(imtx_mirror_ob, mmd->mirror_ob->obmat);
- mul_m4_m4m4(ss->cache->clip_mirror_mtx, imtx_mirror_ob, ob->obmat);
+ invert_m4_m4(imtx_mirror_ob, mmd->mirror_ob->object_to_world);
+ mul_m4_m4m4(ss->cache->clip_mirror_mtx, imtx_mirror_ob, ob->object_to_world);
}
}
}
@@ -4279,7 +4273,8 @@ static void sculpt_update_cache_invariants(
bContext *C, Sculpt *sd, SculptSession *ss, wmOperator *op, const float mval[2])
{
StrokeCache *cache = MEM_callocN(sizeof(StrokeCache), "stroke cache");
- UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
+ ToolSettings *tool_settings = CTX_data_tool_settings(C);
+ UnifiedPaintSettings *ups = &tool_settings->unified_paint_settings;
Brush *brush = BKE_paint_brush(&sd->paint);
ViewContext *vc = paint_stroke_view_context(op->customdata);
Object *ob = CTX_data_active_object(C);
@@ -4359,10 +4354,10 @@ static void sculpt_update_cache_invariants(
/* Cache projection matrix. */
ED_view3d_ob_project_mat_get(cache->vc->rv3d, ob, cache->projection_mat);
- invert_m4_m4(ob->imat, ob->obmat);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
copy_m3_m4(mat, cache->vc->rv3d->viewinv);
mul_m3_v3(mat, viewDir);
- copy_m3_m4(mat, ob->imat);
+ copy_m3_m4(mat, ob->world_to_object);
mul_m3_v3(mat, viewDir);
normalize_v3_v3(cache->true_view_normal, viewDir);
@@ -4378,7 +4373,7 @@ static void sculpt_update_cache_invariants(
if (sd->gravity_object) {
Object *gravity_object = sd->gravity_object;
- copy_v3_v3(cache->true_gravity_direction, gravity_object->obmat[2]);
+ copy_v3_v3(cache->true_gravity_direction, gravity_object->object_to_world[2]);
}
else {
cache->true_gravity_direction[0] = cache->true_gravity_direction[1] = 0.0f;
@@ -4395,6 +4390,10 @@ static void sculpt_update_cache_invariants(
cache->original = true;
}
+ if (SCULPT_automasking_needs_original(sd, brush)) {
+ cache->original = true;
+ }
+
/* Draw sharp does not need the original coordinates to produce the accumulate effect, so it
* should work the opposite way. */
if (brush->sculpt_tool == SCULPT_TOOL_DRAW_SHARP) {
@@ -4410,6 +4409,13 @@ static void sculpt_update_cache_invariants(
}
}
+ /* Original coordinates require the sculpt undo system, which isn't used
+ * for image brushes. It's also not necessary, just disable it. */
+ if (brush && brush->sculpt_tool == SCULPT_TOOL_PAINT &&
+ SCULPT_use_image_paint_brush(&tool_settings->paint_mode, ob)) {
+ cache->original = false;
+ }
+
cache->first_time = true;
#define PIXEL_INPUT_THRESHHOLD 5
@@ -4521,27 +4527,27 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
}
/* Compute 3d coordinate at same z from original location + mval. */
- mul_v3_m4v3(loc, ob->obmat, cache->orig_grab_location);
+ mul_v3_m4v3(loc, ob->object_to_world, cache->orig_grab_location);
ED_view3d_win_to_3d(cache->vc->v3d, cache->vc->region, loc, mval, grab_location);
/* Compute delta to move verts by. */
if (!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
if (sculpt_needs_delta_from_anchored_origin(brush)) {
sub_v3_v3v3(delta, grab_location, cache->old_grab_location);
- invert_m4_m4(imat, ob->obmat);
+ invert_m4_m4(imat, ob->object_to_world);
mul_mat3_m4_v3(imat, delta);
add_v3_v3(cache->grab_delta, delta);
}
else if (sculpt_needs_delta_for_tip_orientation(brush)) {
if (brush->flag & BRUSH_ANCHORED) {
float orig[3];
- mul_v3_m4v3(orig, ob->obmat, cache->orig_grab_location);
+ mul_v3_m4v3(orig, ob->object_to_world, cache->orig_grab_location);
sub_v3_v3v3(cache->grab_delta, grab_location, orig);
}
else {
sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location);
}
- invert_m4_m4(imat, ob->obmat);
+ invert_m4_m4(imat, ob->object_to_world);
mul_mat3_m4_v3(imat, cache->grab_delta);
}
else {
@@ -4586,7 +4592,7 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
/* Handle 'rake' */
cache->is_rake_rotation_valid = false;
- invert_m4_m4(imat, ob->obmat);
+ invert_m4_m4(imat, ob->object_to_world);
mul_mat3_m4_v3(imat, grab_location);
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
@@ -4807,12 +4813,12 @@ static bool sculpt_needs_connectivity_info(const Sculpt *sd,
void SCULPT_stroke_modifiers_check(const bContext *C, Object *ob, const Brush *brush)
{
SculptSession *ss = ob->sculpt;
- View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
bool need_pmap = sculpt_needs_connectivity_info(sd, brush, ss, 0);
if (ss->shapekey_active || ss->deform_modifiers_active ||
- (!BKE_sculptsession_use_pbvh_draw(ob, v3d) && need_pmap)) {
+ (!BKE_sculptsession_use_pbvh_draw(ob, rv3d) && need_pmap)) {
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
BKE_sculpt_update_object_for_edit(
depsgraph, ob, need_pmap, false, SCULPT_tool_is_paint(brush->sculpt_tool));
@@ -4907,7 +4913,7 @@ float SCULPT_raycast_init(ViewContext *vc,
ED_view3d_win_to_segment_clipped(
vc->depsgraph, vc->region, vc->v3d, mval, ray_start, ray_end, true);
- invert_m4_m4(obimat, ob->obmat);
+ invert_m4_m4(obimat, ob->object_to_world);
mul_m4_v3(obimat, ray_start);
mul_m4_v3(obimat, ray_end);
@@ -5015,10 +5021,10 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
float radius;
/* Update cursor data in SculptSession. */
- invert_m4_m4(ob->imat, ob->obmat);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
copy_m3_m4(mat, vc.rv3d->viewinv);
mul_m3_v3(mat, viewDir);
- copy_m3_m4(mat, ob->imat);
+ copy_m3_m4(mat, ob->world_to_object);
mul_m3_v3(mat, viewDir);
normalize_v3_v3(ss->cursor_view_normal, viewDir);
copy_v3_v3(ss->cursor_normal, srd.face_normal);
@@ -5207,7 +5213,7 @@ static void sculpt_restore_mesh(Sculpt *sd, Object *ob)
/* Restore the mesh before continuing with anchored stroke. */
if ((brush->flag & BRUSH_ANCHORED) ||
- ((ELEM(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_ELASTIC_DEFORM)) &&
+ (ELEM(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_ELASTIC_DEFORM) &&
BKE_brush_use_size_pressure(brush)) ||
(brush->flag & BRUSH_DRAG_DOT)) {
@@ -5243,7 +5249,6 @@ void SCULPT_flush_update_step(bContext *C, SculptUpdateType update_flags)
SculptSession *ss = ob->sculpt;
ARegion *region = CTX_wm_region(C);
MultiresModifierData *mmd = ss->multires.modifier;
- View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
if (rv3d) {
@@ -5268,7 +5273,7 @@ void SCULPT_flush_update_step(bContext *C, SculptUpdateType update_flags)
/* Only current viewport matters, slower update for all viewports will
* be done in sculpt_flush_update_done. */
- if (!BKE_sculptsession_use_pbvh_draw(ob, v3d)) {
+ if (!BKE_sculptsession_use_pbvh_draw(ob, rv3d)) {
/* Slow update with full dependency graph update and all that comes with it.
* Needed when there are modifiers or full shading in the 3D viewport. */
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
@@ -5310,16 +5315,15 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up
/* After we are done drawing the stroke, check if we need to do a more
* expensive depsgraph tag to update geometry. */
wmWindowManager *wm = CTX_wm_manager(C);
- View3D *current_v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ RegionView3D *current_rv3d = CTX_wm_region_view3d(C);
SculptSession *ss = ob->sculpt;
Mesh *mesh = ob->data;
/* Always needed for linked duplicates. */
bool need_tag = (ID_REAL_USERS(&mesh->id) > 1);
- if (rv3d) {
- rv3d->rflag &= ~RV3D_PAINTING;
+ if (current_rv3d) {
+ current_rv3d->rflag &= ~RV3D_PAINTING;
}
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
@@ -5329,16 +5333,17 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up
if (sl->spacetype != SPACE_VIEW3D) {
continue;
}
- View3D *v3d = (View3D *)sl;
- if (v3d != current_v3d) {
- need_tag |= !BKE_sculptsession_use_pbvh_draw(ob, v3d);
- }
/* Tag all 3D viewports for redraw now that we are done. Others
* viewports did not get a full redraw, and anti-aliasing for the
* current viewport was deactivated. */
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->regiontype == RGN_TYPE_WINDOW) {
+ RegionView3D *rv3d = region->regiondata;
+ if (rv3d != current_rv3d) {
+ need_tag |= !BKE_sculptsession_use_pbvh_draw(ob, rv3d);
+ }
+
ED_region_tag_redraw(region);
}
}
@@ -5370,15 +5375,19 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up
BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateColor);
}
- if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
- BKE_pbvh_bmesh_after_stroke(ss->pbvh);
- }
+ BKE_sculpt_attributes_destroy_temporary_stroke(ob);
- /* Optimization: if there is locked key and active modifiers present in */
- /* the stack, keyblock is updating at each step. otherwise we could update */
- /* keyblock only when stroke is finished. */
- if (ss->shapekey_active && !ss->deform_modifiers_active) {
- sculpt_update_keyblock(ob);
+ if (update_flags & SCULPT_UPDATE_COORDS) {
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
+ BKE_pbvh_bmesh_after_stroke(ss->pbvh);
+ }
+
+ /* Optimization: if there is locked key and active modifiers present in */
+ /* the stack, keyblock is updating at each step. otherwise we could update */
+ /* keyblock only when stroke is finished. */
+ if (ss->shapekey_active && !ss->deform_modifiers_active) {
+ sculpt_update_keyblock(ob);
+ }
}
if (need_tag) {
@@ -5394,6 +5403,38 @@ static bool over_mesh(bContext *C, struct wmOperator *UNUSED(op), const float mv
return SCULPT_stroke_get_location(C, co_dummy, mval, false);
}
+static void sculpt_stroke_undo_begin(const bContext *C, wmOperator *op)
+{
+ Object *ob = CTX_data_active_object(C);
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ Brush *brush = BKE_paint_brush(&sd->paint);
+ ToolSettings *tool_settings = CTX_data_tool_settings(C);
+
+ /* Setup the correct undo system. Image painting and sculpting are mutual exclusive.
+ * Color attributes are part of the sculpting undo system. */
+ if (brush && brush->sculpt_tool == SCULPT_TOOL_PAINT &&
+ SCULPT_use_image_paint_brush(&tool_settings->paint_mode, ob)) {
+ ED_image_undo_push_begin(op->type->name, PAINT_MODE_SCULPT);
+ }
+ else {
+ SCULPT_undo_push_begin_ex(ob, sculpt_tool_name(sd));
+ }
+}
+
+static void sculpt_stroke_undo_end(const bContext *C, Brush *brush)
+{
+ Object *ob = CTX_data_active_object(C);
+ ToolSettings *tool_settings = CTX_data_tool_settings(C);
+
+ if (brush && brush->sculpt_tool == SCULPT_TOOL_PAINT &&
+ SCULPT_use_image_paint_brush(&tool_settings->paint_mode, ob)) {
+ ED_image_undo_push_end();
+ }
+ else {
+ SCULPT_undo_push_end(ob);
+ }
+}
+
bool SCULPT_handles_colors_report(SculptSession *ss, ReportList *reports)
{
switch (BKE_pbvh_type(ss->pbvh)) {
@@ -5442,15 +5483,10 @@ static bool sculpt_stroke_test_start(bContext *C, struct wmOperator *op, const f
SculptCursorGeometryInfo sgi;
SCULPT_cursor_geometry_info_update(C, &sgi, mval, false);
- /* Setup the correct undo system. Image painting and sculpting are mutual exclusive.
- * Color attributes are part of the sculpting undo system. */
- if (brush && brush->sculpt_tool == SCULPT_TOOL_PAINT &&
- SCULPT_use_image_paint_brush(&tool_settings->paint_mode, ob)) {
- ED_image_undo_push_begin(op->type->name, PAINT_MODE_SCULPT);
- }
- else {
- SCULPT_undo_push_begin_ex(ob, sculpt_tool_name(sd));
- }
+ sculpt_stroke_undo_begin(C, op);
+
+ SCULPT_stroke_id_next(ob);
+ ss->cache->stroke_id = ss->stroke_id;
return true;
}
@@ -5476,7 +5512,8 @@ static void sculpt_stroke_update_step(bContext *C,
sculpt_restore_mesh(sd, ob);
if (sd->flags & (SCULPT_DYNTOPO_DETAIL_CONSTANT | SCULPT_DYNTOPO_DETAIL_MANUAL)) {
- float object_space_constant_detail = 1.0f / (sd->constant_detail * mat4_to_scale(ob->obmat));
+ float object_space_constant_detail = 1.0f / (sd->constant_detail *
+ mat4_to_scale(ob->object_to_world));
BKE_pbvh_bmesh_detail_size_set(ss->pbvh, object_space_constant_detail);
}
else if (sd->flags & SCULPT_DYNTOPO_DETAIL_BRUSH) {
@@ -5579,13 +5616,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
SCULPT_cache_free(ss->cache);
ss->cache = NULL;
- if (brush && brush->sculpt_tool == SCULPT_TOOL_PAINT &&
- SCULPT_use_image_paint_brush(&tool_settings->paint_mode, ob)) {
- ED_image_undo_push_end();
- }
- else {
- SCULPT_undo_push_end(ob);
- }
+ sculpt_stroke_undo_end(C, brush);
if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
@@ -5594,6 +5625,10 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
if (SCULPT_use_image_paint_brush(&tool_settings->paint_mode, ob)) {
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_IMAGE);
}
+ else {
+ BKE_sculpt_attributes_destroy_temporary_stroke(ob);
+ SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COLOR);
+ }
}
else {
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
@@ -5627,11 +5662,20 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
+ SculptSession *ss = ob->sculpt;
if (SCULPT_tool_is_paint(brush->sculpt_tool) &&
!SCULPT_handles_colors_report(ob->sculpt, op->reports)) {
return OPERATOR_CANCELLED;
}
+ if (SCULPT_tool_is_mask(brush->sculpt_tool)) {
+ MultiresModifierData *mmd = BKE_sculpt_multires_active(ss->scene, ob);
+ BKE_sculpt_mask_layers_ensure(CTX_data_depsgraph_pointer(C), CTX_data_main(C), ob, mmd);
+ }
+ if (SCULPT_tool_is_face_sets(brush->sculpt_tool)) {
+ Mesh *mesh = BKE_object_get_original_mesh(ob);
+ ss->face_sets = BKE_sculpt_face_sets_ensure(mesh);
+ }
stroke = paint_stroke_new(C,
op,
@@ -5652,9 +5696,10 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent
return OPERATOR_PASS_THROUGH;
}
- if ((retval = op->type->modal(C, op, event)) == OPERATOR_FINISHED) {
+ retval = op->type->modal(C, op, event);
+ if (ELEM(retval, OPERATOR_FINISHED, OPERATOR_CANCELLED)) {
paint_stroke_free(C, op, op->customdata);
- return OPERATOR_FINISHED;
+ return retval;
}
/* Add modal handler. */
WM_event_add_modal_handler(C, op);
@@ -5709,7 +5754,29 @@ static void sculpt_brush_stroke_cancel(bContext *C, wmOperator *op)
static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- return paint_stroke_modal(C, op, event, (struct PaintStroke **)&op->customdata);
+ bool started = op->customdata && paint_stroke_started((struct PaintStroke *)op->customdata);
+
+ int retval = paint_stroke_modal(C, op, event, (struct PaintStroke **)&op->customdata);
+
+ if (!started && ELEM(retval, OPERATOR_FINISHED, OPERATOR_CANCELLED)) {
+ /* Did the stroke never start? If so push a blank sculpt undo
+ * step to prevent a global undo step (which is triggered by the
+ * #OPTYPE_UNDO flag in #SCULPT_OT_brush_stroke).
+ *
+ * Having blank global undo steps interleaved with sculpt steps
+ * corrupts the DynTopo undo stack.
+ * See T101430.
+ *
+ * NOTE: simply returning #OPERATOR_CANCELLED was not
+ * sufficient to prevent this. */
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ Brush *brush = BKE_paint_brush(&sd->paint);
+
+ sculpt_stroke_undo_begin(C, op);
+ sculpt_stroke_undo_end(C, brush);
+ }
+
+ return retval;
}
static void sculpt_redo_empty_ui(bContext *UNUSED(C), wmOperator *UNUSED(op))
@@ -6041,4 +6108,91 @@ void SCULPT_fake_neighbors_free(Object *ob)
sculpt_pose_fake_neighbors_free(ss);
}
+void SCULPT_automasking_node_begin(Object *ob,
+ const SculptSession *UNUSED(ss),
+ AutomaskingCache *automasking,
+ AutomaskingNodeData *automask_data,
+ PBVHNode *node)
+{
+ if (!automasking) {
+ memset(automask_data, 0, sizeof(*automask_data));
+ return;
+ }
+
+ automask_data->node = node;
+ automask_data->have_orig_data = automasking->settings.flags &
+ (BRUSH_AUTOMASKING_BRUSH_NORMAL | BRUSH_AUTOMASKING_VIEW_NORMAL);
+
+ if (automask_data->have_orig_data) {
+ SCULPT_orig_vert_data_init(&automask_data->orig_data, ob, node, SCULPT_UNDO_COORDS);
+ }
+ else {
+ memset(&automask_data->orig_data, 0, sizeof(automask_data->orig_data));
+ }
+}
+
+void SCULPT_automasking_node_update(SculptSession *UNUSED(ss),
+ AutomaskingNodeData *automask_data,
+ PBVHVertexIter *vd)
+{
+ if (automask_data->have_orig_data) {
+ SCULPT_orig_vert_data_update(&automask_data->orig_data, vd);
+ }
+}
+
+bool SCULPT_vertex_is_occluded(SculptSession *ss, PBVHVertRef vertex, bool original)
+{
+ float ray_start[3], ray_end[3], ray_normal[3], face_normal[3];
+ float co[3];
+
+ copy_v3_v3(co, SCULPT_vertex_co_get(ss, vertex));
+ float mouse[2];
+
+ ED_view3d_project_float_v2_m4(ss->cache->vc->region, co, mouse, ss->cache->projection_mat);
+
+ int depth = SCULPT_raycast_init(ss->cache->vc, mouse, ray_end, ray_start, ray_normal, original);
+
+ negate_v3(ray_normal);
+
+ copy_v3_v3(ray_start, SCULPT_vertex_co_get(ss, vertex));
+ madd_v3_v3fl(ray_start, ray_normal, 0.002);
+
+ SculptRaycastData srd = {0};
+ srd.original = original;
+ srd.ss = ss;
+ srd.hit = false;
+ srd.ray_start = ray_start;
+ srd.ray_normal = ray_normal;
+ srd.depth = depth;
+ srd.face_normal = face_normal;
+
+ isect_ray_tri_watertight_v3_precalc(&srd.isect_precalc, ray_normal);
+ BKE_pbvh_raycast(ss->pbvh, sculpt_raycast_cb, &srd, ray_start, ray_normal, srd.original);
+
+ return srd.hit;
+}
+
+void SCULPT_stroke_id_next(Object *ob)
+{
+ /* Manually wrap in int32 space to avoid tripping up undefined behavior
+ * sanitizers.
+ */
+ ob->sculpt->stroke_id = (uchar)(((int)ob->sculpt->stroke_id + 1) & 255);
+}
+
+void SCULPT_stroke_id_ensure(Object *ob)
+{
+ SculptSession *ss = ob->sculpt;
+
+ if (!ss->attrs.automasking_stroke_id) {
+ SculptAttributeParams params = {0};
+ ss->attrs.automasking_stroke_id = BKE_sculpt_attribute_ensure(
+ ob,
+ ATTR_DOMAIN_POINT,
+ CD_PROP_INT8,
+ SCULPT_ATTRIBUTE_NAME(automasking_stroke_id),
+ &params);
+ }
+}
+
/** \} */
diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.cc b/source/blender/editors/sculpt_paint/sculpt_automasking.cc
index a9fe8cc4b2f..505440c9272 100644
--- a/source/blender/editors/sculpt_paint/sculpt_automasking.cc
+++ b/source/blender/editors/sculpt_paint/sculpt_automasking.cc
@@ -7,17 +7,22 @@
#include "MEM_guardedalloc.h"
+#include "BLI_array.hh"
#include "BLI_blenlib.h"
#include "BLI_hash.h"
#include "BLI_index_range.hh"
#include "BLI_math.h"
+#include "BLI_math_vec_types.hh"
+#include "BLI_set.hh"
#include "BLI_task.h"
+#include "BLI_vector.hh"
#include "DNA_brush_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_brush.h"
+#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
@@ -47,7 +52,10 @@
#include <cmath>
#include <cstdlib>
+using blender::float3;
using blender::IndexRange;
+using blender::Set;
+using blender::Vector;
AutomaskingCache *SCULPT_automasking_active_cache_get(SculptSession *ss)
{
@@ -64,10 +72,13 @@ bool SCULPT_is_automasking_mode_enabled(const Sculpt *sd,
const Brush *br,
const eAutomasking_flag mode)
{
+ int automasking = sd->automasking_flags;
+
if (br) {
- return br->automasking_flags & mode || sd->automasking_flags & mode;
+ automasking |= br->automasking_flags;
}
- return sd->automasking_flags & mode;
+
+ return (eAutomasking_flag)automasking & mode;
}
bool SCULPT_is_automasking_enabled(const Sculpt *sd, const SculptSession *ss, const Brush *br)
@@ -87,17 +98,85 @@ bool SCULPT_is_automasking_enabled(const Sculpt *sd, const SculptSession *ss, co
if (SCULPT_is_automasking_mode_enabled(sd, br, BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS)) {
return true;
}
+ if (SCULPT_is_automasking_mode_enabled(sd, br, BRUSH_AUTOMASKING_BRUSH_NORMAL)) {
+ return true;
+ }
+ if (SCULPT_is_automasking_mode_enabled(sd, br, BRUSH_AUTOMASKING_VIEW_NORMAL)) {
+ return true;
+ }
+ if (SCULPT_is_automasking_mode_enabled(sd, br, BRUSH_AUTOMASKING_CAVITY_ALL)) {
+ return true;
+ }
+
return false;
}
static int sculpt_automasking_mode_effective_bits(const Sculpt *sculpt, const Brush *brush)
{
if (brush) {
- return sculpt->automasking_flags | brush->automasking_flags;
+ int flags = sculpt->automasking_flags | brush->automasking_flags;
+
+ /* Check if we are using brush cavity settings. */
+ if (brush->automasking_flags & BRUSH_AUTOMASKING_CAVITY_ALL) {
+ flags &= ~(BRUSH_AUTOMASKING_CAVITY_ALL | BRUSH_AUTOMASKING_CAVITY_USE_CURVE |
+ BRUSH_AUTOMASKING_CAVITY_NORMAL);
+ flags |= brush->automasking_flags;
+ }
+ else if (sculpt->automasking_flags & BRUSH_AUTOMASKING_CAVITY_ALL) {
+ flags &= ~(BRUSH_AUTOMASKING_CAVITY_ALL | BRUSH_AUTOMASKING_CAVITY_USE_CURVE |
+ BRUSH_AUTOMASKING_CAVITY_NORMAL);
+ flags |= sculpt->automasking_flags;
+ }
+
+ return flags;
}
return sculpt->automasking_flags;
}
+bool SCULPT_automasking_needs_normal(const SculptSession * /*ss*/,
+ const Sculpt *sculpt,
+ const Brush *brush)
+{
+ int flags = sculpt_automasking_mode_effective_bits(sculpt, brush);
+
+ return flags & (BRUSH_AUTOMASKING_BRUSH_NORMAL | BRUSH_AUTOMASKING_VIEW_NORMAL);
+}
+
+static float sculpt_automasking_normal_calc(SculptSession *ss,
+ PBVHVertRef vertex,
+ float3 &normal,
+ float limit_lower,
+ float limit_upper,
+ AutomaskingNodeData *automask_data)
+{
+ float3 normal_v;
+
+ if (automask_data->have_orig_data) {
+ normal_v = automask_data->orig_data.no;
+ }
+ else {
+ SCULPT_vertex_normal_get(ss, vertex, normal_v);
+ }
+
+ float angle = saacos(dot_v3v3(normal, normal_v));
+
+ /* note that limit is pre-divided by M_PI */
+
+ if (angle > limit_lower && angle < limit_upper) {
+ float t = 1.0f - (angle - limit_lower) / (limit_upper - limit_lower);
+
+ /* smoothstep */
+ t = t * t * (3.0 - 2.0 * t);
+
+ return t;
+ }
+ if (angle > limit_upper) {
+ return 0.0f;
+ }
+
+ return 1.0f;
+}
+
static bool SCULPT_automasking_needs_factors_cache(const Sculpt *sd, const Brush *brush)
{
@@ -105,30 +184,352 @@ static bool SCULPT_automasking_needs_factors_cache(const Sculpt *sd, const Brush
if (automasking_flags & BRUSH_AUTOMASKING_TOPOLOGY) {
return true;
}
- if (automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_EDGES) {
- return brush && brush->automasking_boundary_edges_propagation_steps != 1;
- }
- if (automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS) {
+
+ if (automasking_flags &
+ (BRUSH_AUTOMASKING_BOUNDARY_EDGES | BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS |
+ BRUSH_AUTOMASKING_BRUSH_NORMAL | BRUSH_AUTOMASKING_VIEW_NORMAL)) {
return brush && brush->automasking_boundary_edges_propagation_steps != 1;
}
return false;
}
+static float automasking_brush_normal_factor(AutomaskingCache *automasking,
+ SculptSession *ss,
+ PBVHVertRef vertex,
+ AutomaskingNodeData *automask_data)
+{
+ float falloff = automasking->settings.start_normal_falloff * M_PI;
+ float3 initial_normal;
+
+ if (ss->cache) {
+ initial_normal = ss->cache->initial_normal;
+ }
+ else {
+ initial_normal = ss->filter_cache->initial_normal;
+ }
+
+ return sculpt_automasking_normal_calc(ss,
+ vertex,
+ initial_normal,
+ automasking->settings.start_normal_limit - falloff * 0.5f,
+ automasking->settings.start_normal_limit + falloff * 0.5f,
+ automask_data);
+}
+
+static float automasking_view_normal_factor(AutomaskingCache *automasking,
+ SculptSession *ss,
+ PBVHVertRef vertex,
+ AutomaskingNodeData *automask_data)
+{
+ float falloff = automasking->settings.view_normal_falloff * M_PI;
+
+ float3 view_normal;
+
+ if (ss->cache) {
+ view_normal = ss->cache->view_normal;
+ }
+ else {
+ view_normal = ss->filter_cache->view_normal;
+ }
+
+ return sculpt_automasking_normal_calc(ss,
+ vertex,
+ view_normal,
+ automasking->settings.view_normal_limit,
+ automasking->settings.view_normal_limit + falloff,
+ automask_data);
+}
+
+static float automasking_view_occlusion_factor(AutomaskingCache *automasking,
+ SculptSession *ss,
+ PBVHVertRef vertex,
+ uchar stroke_id,
+ AutomaskingNodeData * /*automask_data*/)
+{
+ char f = *(char *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_occlusion);
+
+ if (stroke_id != automasking->current_stroke_id) {
+ f = *(char *)SCULPT_vertex_attr_get(
+ vertex,
+ ss->attrs.automasking_occlusion) = SCULPT_vertex_is_occluded(ss, vertex, true) ? 2 : 1;
+ }
+
+ return f == 2;
+}
+
+/* Updates vertex stroke id. */
+static float automasking_factor_end(SculptSession *ss,
+ AutomaskingCache *automasking,
+ PBVHVertRef vertex,
+ float value)
+{
+ if (ss->attrs.automasking_stroke_id) {
+ *(uchar *)SCULPT_vertex_attr_get(
+ vertex, ss->attrs.automasking_stroke_id) = automasking->current_stroke_id;
+ }
+
+ return value;
+}
+
+static float sculpt_cavity_calc_factor(AutomaskingCache *automasking, float factor)
+{
+ float sign = signf(factor);
+
+ factor = fabsf(factor) * automasking->settings.cavity_factor * 50.0f;
+
+ factor = factor * sign * 0.5f + 0.5f;
+ CLAMP(factor, 0.0f, 1.0f);
+
+ return (automasking->settings.flags & BRUSH_AUTOMASKING_CAVITY_INVERTED) ? 1.0f - factor :
+ factor;
+}
+
+struct CavityBlurVert {
+ PBVHVertRef vertex;
+ float dist;
+ int depth;
+
+ CavityBlurVert(PBVHVertRef vertex_, float dist_, int depth_)
+ : vertex(vertex_), dist(dist_), depth(depth_)
+ {
+ }
+
+ CavityBlurVert() = default;
+};
+
+static void sculpt_calc_blurred_cavity(SculptSession *ss,
+ AutomaskingCache *automasking,
+ int steps,
+ PBVHVertRef vertex)
+{
+ float3 sno1(0.0f);
+ float3 sno2(0.0f);
+ float3 sco1(0.0f);
+ float3 sco2(0.0f);
+ float len1_sum = 0.0f;
+ int sco1_len = 0, sco2_len = 0;
+
+ /* Steps starts at 1, but API and user interface
+ * are zero-based.
+ */
+ steps++;
+
+ Vector<CavityBlurVert, 64> queue;
+ Set<int64_t, 64> visit;
+
+ int start = 0, end = 0;
+
+ queue.resize(64);
+
+ CavityBlurVert initial(vertex, 0.0f, 0);
+
+ visit.add_new(vertex.i);
+ queue[0] = initial;
+ end = 1;
+
+ const float *co1 = SCULPT_vertex_co_get(ss, vertex);
+
+ while (start != end) {
+ CavityBlurVert &blurvert = queue[start];
+ PBVHVertRef v = blurvert.vertex;
+ start = (start + 1) % queue.size();
+
+ float3 no;
+
+ const float *co = SCULPT_vertex_co_get(ss, v);
+ SCULPT_vertex_normal_get(ss, v, no);
+
+ float centdist = len_v3v3(co, co1);
+
+ sco1 += co;
+ sno1 += no;
+ len1_sum += centdist;
+ sco1_len++;
+
+ if (blurvert.depth < steps) {
+ sco2 += co;
+ sno2 += no;
+ sco2_len++;
+ }
+
+ if (blurvert.depth >= steps) {
+ continue;
+ }
+
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, v, ni) {
+ PBVHVertRef v2 = ni.vertex;
+
+ if (visit.contains(v2.i)) {
+ continue;
+ }
+
+ float dist = len_v3v3(SCULPT_vertex_co_get(ss, v2), SCULPT_vertex_co_get(ss, v));
+
+ visit.add_new(v2.i);
+ CavityBlurVert blurvert2(v2, dist, blurvert.depth + 1);
+
+ int nextend = (end + 1) % queue.size();
+
+ if (nextend == start) {
+ int oldsize = queue.size();
+
+ queue.resize(queue.size() << 1);
+
+ if (end < start) {
+ int n = oldsize - start;
+
+ for (int i = 0; i < n; i++) {
+ queue[queue.size() - n + i] = queue[i + start];
+ }
+
+ start = queue.size() - n;
+ }
+ }
+
+ queue[end] = blurvert2;
+ end = (end + 1) % queue.size();
+ }
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+ }
+
+ BLI_assert(sco1_len != sco2_len);
+
+ if (!sco1_len) {
+ sco1 = SCULPT_vertex_co_get(ss, vertex);
+ }
+ else {
+ sco1 /= float(sco1_len);
+ len1_sum /= sco1_len;
+ }
+
+ if (!sco2_len) {
+ sco2 = SCULPT_vertex_co_get(ss, vertex);
+ }
+ else {
+ sco2 /= float(sco2_len);
+ }
+
+ normalize_v3(sno1);
+ if (dot_v3v3(sno1, sno1) == 0.0f) {
+ SCULPT_vertex_normal_get(ss, vertex, sno1);
+ }
+
+ normalize_v3(sno2);
+ if (dot_v3v3(sno2, sno2) == 0.0f) {
+ SCULPT_vertex_normal_get(ss, vertex, sno2);
+ }
+
+ float3 vec = sco1 - sco2;
+ float factor_sum = dot_v3v3(vec, sno2) / len1_sum;
+
+ factor_sum = sculpt_cavity_calc_factor(automasking, factor_sum);
+
+ *(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_cavity) = factor_sum;
+}
+
+int SCULPT_automasking_settings_hash(Object *ob, AutomaskingCache *automasking)
+{
+ SculptSession *ss = ob->sculpt;
+
+ int hash;
+ int totvert = SCULPT_vertex_count_get(ss);
+
+ hash = BLI_hash_int(automasking->settings.flags);
+ hash = BLI_hash_int_2d(hash, totvert);
+
+ if (automasking->settings.flags & BRUSH_AUTOMASKING_CAVITY_ALL) {
+ hash = BLI_hash_int_2d(hash, automasking->settings.cavity_blur_steps);
+ hash = BLI_hash_int_2d(hash, *reinterpret_cast<uint *>(&automasking->settings.cavity_factor));
+
+ if (automasking->settings.cavity_curve) {
+ CurveMap *cm = automasking->settings.cavity_curve->cm;
+
+ for (int i = 0; i < cm->totpoint; i++) {
+ hash = BLI_hash_int_2d(hash, *reinterpret_cast<uint *>(&cm->curve[i].x));
+ hash = BLI_hash_int_2d(hash, *reinterpret_cast<uint *>(&cm->curve[i].y));
+ hash = BLI_hash_int_2d(hash, uint(cm->curve[i].flag));
+ hash = BLI_hash_int_2d(hash, uint(cm->curve[i].shorty));
+ }
+ }
+ }
+
+ if (automasking->settings.flags & BRUSH_AUTOMASKING_FACE_SETS) {
+ hash = BLI_hash_int_2d(hash, automasking->settings.initial_face_set);
+ }
+
+ if (automasking->settings.flags & BRUSH_AUTOMASKING_VIEW_NORMAL) {
+ hash = BLI_hash_int_2d(hash,
+ *reinterpret_cast<uint *>(&automasking->settings.view_normal_falloff));
+ hash = BLI_hash_int_2d(hash,
+ *reinterpret_cast<uint *>(&automasking->settings.view_normal_limit));
+ }
+
+ if (automasking->settings.flags & BRUSH_AUTOMASKING_BRUSH_NORMAL) {
+ hash = BLI_hash_int_2d(hash,
+ *reinterpret_cast<uint *>(&automasking->settings.start_normal_falloff));
+ hash = BLI_hash_int_2d(hash,
+ *reinterpret_cast<uint *>(&automasking->settings.start_normal_limit));
+ }
+
+ return hash;
+}
+
+static float sculpt_automasking_cavity_factor(AutomaskingCache *automasking,
+ SculptSession *ss,
+ PBVHVertRef vertex)
+{
+ uchar stroke_id = *(uchar *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_stroke_id);
+
+ if (stroke_id != automasking->current_stroke_id) {
+ sculpt_calc_blurred_cavity(ss, automasking, automasking->settings.cavity_blur_steps, vertex);
+ }
+
+ float factor = *(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_cavity);
+ bool inverted = automasking->settings.flags & BRUSH_AUTOMASKING_CAVITY_INVERTED;
+
+ if ((automasking->settings.flags & BRUSH_AUTOMASKING_CAVITY_ALL) &&
+ (automasking->settings.flags & BRUSH_AUTOMASKING_CAVITY_USE_CURVE)) {
+ factor = inverted ? 1.0f - factor : factor;
+ factor = BKE_curvemapping_evaluateF(automasking->settings.cavity_curve, 0, factor);
+ factor = inverted ? 1.0f - factor : factor;
+ }
+
+ return factor;
+}
+
float SCULPT_automasking_factor_get(AutomaskingCache *automasking,
SculptSession *ss,
- PBVHVertRef vert)
+ PBVHVertRef vert,
+ AutomaskingNodeData *automask_data)
{
- if (!automasking) {
+ if (!automasking || vert.i == PBVH_REF_NONE) {
return 1.0f;
}
- int index = BKE_pbvh_vertex_to_index(ss->pbvh, vert);
-
/* If the cache is initialized with valid info, use the cache. This is used when the
* automasking information can't be computed in real time per vertex and needs to be
* initialized for the whole mesh when the stroke starts. */
- if (automasking->factor) {
- return automasking->factor[index];
+ if (ss->attrs.automasking_factor) {
+ float factor = *(float *)SCULPT_vertex_attr_get(vert, ss->attrs.automasking_factor);
+
+ if (automasking->settings.flags & BRUSH_AUTOMASKING_CAVITY_ALL) {
+ factor *= sculpt_automasking_cavity_factor(automasking, ss, vert);
+ }
+
+ return factor;
+ }
+
+ uchar stroke_id = ss->attrs.automasking_stroke_id ?
+ *(uchar *)SCULPT_vertex_attr_get(vert, ss->attrs.automasking_stroke_id) :
+ -1;
+
+ bool do_occlusion = (automasking->settings.flags &
+ (BRUSH_AUTOMASKING_VIEW_OCCLUSION | BRUSH_AUTOMASKING_VIEW_NORMAL)) ==
+ (BRUSH_AUTOMASKING_VIEW_OCCLUSION | BRUSH_AUTOMASKING_VIEW_NORMAL);
+ if (do_occlusion &&
+ automasking_view_occlusion_factor(automasking, ss, vert, stroke_id, automask_data)) {
+ return automasking_factor_end(ss, automasking, vert, 0.0f);
}
if (automasking->settings.flags & BRUSH_AUTOMASKING_FACE_SETS) {
@@ -149,7 +550,23 @@ float SCULPT_automasking_factor_get(AutomaskingCache *automasking,
}
}
- return 1.0f;
+ float mask = 1.0f;
+
+ if ((ss->cache || ss->filter_cache) &&
+ (automasking->settings.flags & BRUSH_AUTOMASKING_BRUSH_NORMAL)) {
+ mask *= automasking_brush_normal_factor(automasking, ss, vert, automask_data);
+ }
+
+ if ((ss->cache || ss->filter_cache) &&
+ (automasking->settings.flags & BRUSH_AUTOMASKING_VIEW_NORMAL)) {
+ mask *= automasking_view_normal_factor(automasking, ss, vert, automask_data);
+ }
+
+ if (automasking->settings.flags & BRUSH_AUTOMASKING_CAVITY_ALL) {
+ mask *= sculpt_automasking_cavity_factor(automasking, ss, vert);
+ }
+
+ return automasking_factor_end(ss, automasking, vert, mask);
}
void SCULPT_automasking_cache_free(AutomaskingCache *automasking)
@@ -158,7 +575,6 @@ void SCULPT_automasking_cache_free(AutomaskingCache *automasking)
return;
}
- MEM_SAFE_FREE(automasking->factor);
MEM_SAFE_FREE(automasking);
}
@@ -176,43 +592,39 @@ static bool sculpt_automasking_is_constrained_by_radius(Brush *br)
}
struct AutomaskFloodFillData {
- float *automask_factor;
float radius;
bool use_radius;
float location[3];
char symm;
};
-static bool automask_floodfill_cb(SculptSession *ss,
- PBVHVertRef from_v,
- PBVHVertRef to_v,
- bool UNUSED(is_duplicate),
- void *userdata)
+static bool automask_floodfill_cb(
+ SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool /*is_duplicate*/, void *userdata)
{
AutomaskFloodFillData *data = (AutomaskFloodFillData *)userdata;
- int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v);
- int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
- data->automask_factor[to_v_i] = 1.0f;
- data->automask_factor[from_v_i] = 1.0f;
+ *(float *)SCULPT_vertex_attr_get(to_v, ss->attrs.automasking_factor) = 1.0f;
+ *(float *)SCULPT_vertex_attr_get(from_v, ss->attrs.automasking_factor) = 1.0f;
return (!data->use_radius ||
SCULPT_is_vertex_inside_brush_radius_symm(
SCULPT_vertex_co_get(ss, to_v), data->location, data->radius, data->symm));
}
-static float *SCULPT_topology_automasking_init(Sculpt *sd, Object *ob, float *automask_factor)
+static void SCULPT_topology_automasking_init(Sculpt *sd, Object *ob)
{
SculptSession *ss = ob->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && !ss->pmap) {
- BLI_assert_msg(0, "Topology masking: pmap missing");
- return nullptr;
+ BLI_assert_unreachable();
+ return;
}
const int totvert = SCULPT_vertex_count_get(ss);
for (int i : IndexRange(totvert)) {
- automask_factor[i] = 0.0f;
+ PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
+
+ (*(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_factor)) = 0.0f;
}
/* Flood fill automask to connected vertices. Limited to vertices inside
@@ -222,9 +634,8 @@ static float *SCULPT_topology_automasking_init(Sculpt *sd, Object *ob, float *au
const float radius = ss->cache ? ss->cache->radius : FLT_MAX;
SCULPT_floodfill_add_active(sd, ob, ss, &flood, radius);
- AutomaskFloodFillData fdata = {nullptr};
+ AutomaskFloodFillData fdata = {0};
- fdata.automask_factor = automask_factor;
fdata.radius = radius;
fdata.use_radius = ss->cache && sculpt_automasking_is_constrained_by_radius(brush);
fdata.symm = SCULPT_mesh_symmetry_xyz_get(ob);
@@ -232,22 +643,20 @@ static float *SCULPT_topology_automasking_init(Sculpt *sd, Object *ob, float *au
copy_v3_v3(fdata.location, SCULPT_active_vertex_co_get(ss));
SCULPT_floodfill_execute(ss, &flood, automask_floodfill_cb, &fdata);
SCULPT_floodfill_free(&flood);
-
- return automask_factor;
}
-static float *sculpt_face_sets_automasking_init(Sculpt *sd, Object *ob, float *automask_factor)
+static void sculpt_face_sets_automasking_init(Sculpt *sd, Object *ob)
{
SculptSession *ss = ob->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
if (!SCULPT_is_automasking_enabled(sd, ss, brush)) {
- return nullptr;
+ return;
}
if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && !ss->pmap) {
BLI_assert_msg(0, "Face Sets automasking: pmap missing");
- return nullptr;
+ return;
}
int tot_vert = SCULPT_vertex_count_get(ss);
@@ -256,25 +665,22 @@ static float *sculpt_face_sets_automasking_init(Sculpt *sd, Object *ob, float *a
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
if (!SCULPT_vertex_has_face_set(ss, vertex, active_face_set)) {
- automask_factor[i] *= 0.0f;
+ *(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_factor) = 0.0f;
}
}
-
- return automask_factor;
}
#define EDGE_DISTANCE_INF -1
-float *SCULPT_boundary_automasking_init(Object *ob,
- eBoundaryAutomaskMode mode,
- int propagation_steps,
- float *automask_factor)
+static void SCULPT_boundary_automasking_init(Object *ob,
+ eBoundaryAutomaskMode mode,
+ int propagation_steps)
{
SculptSession *ss = ob->sculpt;
if (!ss->pmap) {
BLI_assert_msg(0, "Boundary Edges masking: pmap missing");
- return nullptr;
+ return;
}
const int totvert = SCULPT_vertex_count_get(ss);
@@ -316,16 +722,19 @@ float *SCULPT_boundary_automasking_init(Object *ob,
}
for (int i : IndexRange(totvert)) {
+ PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
+
if (edge_distance[i] == EDGE_DISTANCE_INF) {
continue;
}
- const float p = 1.0f - ((float)edge_distance[i] / (float)propagation_steps);
+ const float p = 1.0f - (float(edge_distance[i]) / float(propagation_steps));
const float edge_boundary_automask = pow2f(p);
- automask_factor[i] *= (1.0f - edge_boundary_automask);
+
+ *(float *)SCULPT_vertex_attr_get(
+ vertex, ss->attrs.automasking_factor) *= (1.0f - edge_boundary_automask);
}
MEM_SAFE_FREE(edge_distance);
- return automask_factor;
}
static void SCULPT_automasking_cache_settings_update(AutomaskingCache *automasking,
@@ -335,6 +744,66 @@ static void SCULPT_automasking_cache_settings_update(AutomaskingCache *automaski
{
automasking->settings.flags = sculpt_automasking_mode_effective_bits(sd, brush);
automasking->settings.initial_face_set = SCULPT_active_face_set_get(ss);
+
+ automasking->settings.view_normal_limit = sd->automasking_view_normal_limit;
+ automasking->settings.view_normal_falloff = sd->automasking_view_normal_falloff;
+ automasking->settings.start_normal_limit = sd->automasking_start_normal_limit;
+ automasking->settings.start_normal_falloff = sd->automasking_start_normal_falloff;
+
+ if (brush && (brush->automasking_flags & BRUSH_AUTOMASKING_CAVITY_ALL)) {
+ automasking->settings.cavity_curve = brush->automasking_cavity_curve;
+ automasking->settings.cavity_factor = brush->automasking_cavity_factor;
+ automasking->settings.cavity_blur_steps = brush->automasking_cavity_blur_steps;
+ }
+ else {
+ automasking->settings.cavity_curve = sd->automasking_cavity_curve;
+ automasking->settings.cavity_factor = sd->automasking_cavity_factor;
+ automasking->settings.cavity_blur_steps = sd->automasking_cavity_blur_steps;
+ }
+}
+
+static void sculpt_normal_occlusion_automasking_fill(AutomaskingCache *automasking,
+ Object *ob,
+ eAutomasking_flag mode)
+{
+ SculptSession *ss = ob->sculpt;
+ const int totvert = SCULPT_vertex_count_get(ss);
+
+ /* No need to build original data since this is only called at the beginning of strokes.*/
+ AutomaskingNodeData nodedata;
+ nodedata.have_orig_data = false;
+
+ for (int i = 0; i < totvert; i++) {
+ PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
+
+ float f = *(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_factor);
+
+ if (int(mode) & BRUSH_AUTOMASKING_BRUSH_NORMAL) {
+ f *= automasking_brush_normal_factor(automasking, ss, vertex, &nodedata);
+ }
+ if (int(mode) & BRUSH_AUTOMASKING_VIEW_NORMAL) {
+ if (int(mode) & BRUSH_AUTOMASKING_VIEW_OCCLUSION) {
+ f *= automasking_view_occlusion_factor(automasking, ss, vertex, -1, &nodedata);
+ }
+
+ f *= automasking_view_normal_factor(automasking, ss, vertex, &nodedata);
+ }
+
+ if (ss->attrs.automasking_stroke_id) {
+ *(uchar *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_stroke_id) = ss->stroke_id;
+ }
+
+ *(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_factor) = f;
+ }
+}
+
+bool SCULPT_tool_can_reuse_automask(int sculpt_tool)
+{
+ return ELEM(sculpt_tool,
+ SCULPT_TOOL_PAINT,
+ SCULPT_TOOL_SMEAR,
+ SCULPT_TOOL_MASK,
+ SCULPT_TOOL_DRAW_FACE_SETS);
}
AutomaskingCache *SCULPT_automasking_cache_init(Sculpt *sd, Brush *brush, Object *ob)
@@ -351,38 +820,134 @@ AutomaskingCache *SCULPT_automasking_cache_init(Sculpt *sd, Brush *brush, Object
SCULPT_automasking_cache_settings_update(automasking, ss, sd, brush);
SCULPT_boundary_info_ensure(ob);
+ automasking->current_stroke_id = ss->stroke_id;
+
+ bool use_stroke_id = false;
+ int mode = sculpt_automasking_mode_effective_bits(sd, brush);
+
+ if ((mode & BRUSH_AUTOMASKING_VIEW_OCCLUSION) && (mode & BRUSH_AUTOMASKING_VIEW_NORMAL)) {
+ use_stroke_id = true;
+
+ if (!ss->attrs.automasking_occlusion) {
+ SculptAttributeParams params = {0};
+ ss->attrs.automasking_occlusion = BKE_sculpt_attribute_ensure(
+ ob,
+ ATTR_DOMAIN_POINT,
+ CD_PROP_INT8,
+ SCULPT_ATTRIBUTE_NAME(automasking_occlusion),
+ &params);
+ }
+ }
+
+ if (mode & BRUSH_AUTOMASKING_CAVITY_ALL) {
+ use_stroke_id = true;
+
+ if (SCULPT_is_automasking_mode_enabled(sd, brush, BRUSH_AUTOMASKING_CAVITY_USE_CURVE)) {
+ BKE_curvemapping_init(brush->automasking_cavity_curve);
+ BKE_curvemapping_init(sd->automasking_cavity_curve);
+ }
+
+ if (!ss->attrs.automasking_cavity) {
+ SculptAttributeParams params = {0};
+ ss->attrs.automasking_cavity = BKE_sculpt_attribute_ensure(
+ ob,
+ ATTR_DOMAIN_POINT,
+ CD_PROP_FLOAT,
+ SCULPT_ATTRIBUTE_NAME(automasking_cavity),
+ &params);
+ }
+ }
+
+ if (use_stroke_id) {
+ SCULPT_stroke_id_ensure(ob);
+
+ bool have_occlusion = (mode & BRUSH_AUTOMASKING_VIEW_OCCLUSION) &&
+ (mode & BRUSH_AUTOMASKING_VIEW_NORMAL);
+
+ if (brush && SCULPT_tool_can_reuse_automask(brush->sculpt_tool) && !have_occlusion) {
+ int hash = SCULPT_automasking_settings_hash(ob, automasking);
+
+ if (hash == ss->last_automasking_settings_hash) {
+ automasking->current_stroke_id = ss->last_automask_stroke_id;
+ automasking->can_reuse_mask = true;
+ }
+ }
+
+ if (!automasking->can_reuse_mask) {
+ ss->last_automask_stroke_id = ss->stroke_id;
+ }
+ }
+
if (!SCULPT_automasking_needs_factors_cache(sd, brush)) {
return automasking;
}
- automasking->factor = (float *)MEM_malloc_arrayN(totvert, sizeof(float), "automask_factor");
+ SculptAttributeParams params = {0};
+ params.stroke_only = true;
+
+ ss->attrs.automasking_factor = BKE_sculpt_attribute_ensure(
+ ob, ATTR_DOMAIN_POINT, CD_PROP_FLOAT, SCULPT_ATTRIBUTE_NAME(automasking_factor), &params);
+
+ float initial_value;
+
+ /* Topology, boundary and boundary face sets build up the mask
+ * from zero which other modes can subtract from. If none of them are
+ * enabled initialize to 1.
+ */
+ if (!(mode & (BRUSH_AUTOMASKING_BOUNDARY_EDGES | BRUSH_AUTOMASKING_TOPOLOGY |
+ BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS))) {
+ initial_value = 1.0f;
+ }
+ else {
+ initial_value = 0.0f;
+ }
+
for (int i : IndexRange(totvert)) {
- automasking->factor[i] = 1.0f;
+ PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
+
+ (*(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_factor)) = initial_value;
}
const int boundary_propagation_steps = brush ?
brush->automasking_boundary_edges_propagation_steps :
1;
+ /* Additive modes. */
if (SCULPT_is_automasking_mode_enabled(sd, brush, BRUSH_AUTOMASKING_TOPOLOGY)) {
SCULPT_vertex_random_access_ensure(ss);
- SCULPT_topology_automasking_init(sd, ob, automasking->factor);
+ SCULPT_topology_automasking_init(sd, ob);
}
if (SCULPT_is_automasking_mode_enabled(sd, brush, BRUSH_AUTOMASKING_FACE_SETS)) {
SCULPT_vertex_random_access_ensure(ss);
- sculpt_face_sets_automasking_init(sd, ob, automasking->factor);
+ sculpt_face_sets_automasking_init(sd, ob);
}
if (SCULPT_is_automasking_mode_enabled(sd, brush, BRUSH_AUTOMASKING_BOUNDARY_EDGES)) {
SCULPT_vertex_random_access_ensure(ss);
- SCULPT_boundary_automasking_init(
- ob, AUTOMASK_INIT_BOUNDARY_EDGES, boundary_propagation_steps, automasking->factor);
+ SCULPT_boundary_automasking_init(ob, AUTOMASK_INIT_BOUNDARY_EDGES, boundary_propagation_steps);
}
if (SCULPT_is_automasking_mode_enabled(sd, brush, BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS)) {
SCULPT_vertex_random_access_ensure(ss);
SCULPT_boundary_automasking_init(
- ob, AUTOMASK_INIT_BOUNDARY_FACE_SETS, boundary_propagation_steps, automasking->factor);
+ ob, AUTOMASK_INIT_BOUNDARY_FACE_SETS, boundary_propagation_steps);
+ }
+
+ /* Subtractive modes. */
+ int normal_bits = sculpt_automasking_mode_effective_bits(sd, brush) &
+ (BRUSH_AUTOMASKING_BRUSH_NORMAL | BRUSH_AUTOMASKING_VIEW_NORMAL |
+ BRUSH_AUTOMASKING_VIEW_OCCLUSION);
+
+ if (normal_bits) {
+ sculpt_normal_occlusion_automasking_fill(automasking, ob, (eAutomasking_flag)normal_bits);
}
return automasking;
}
+
+bool SCULPT_automasking_needs_original(const Sculpt *sd, const Brush *brush)
+{
+
+ return sculpt_automasking_mode_effective_bits(sd, brush) &
+ (BRUSH_AUTOMASKING_CAVITY_ALL | BRUSH_AUTOMASKING_BRUSH_NORMAL |
+ BRUSH_AUTOMASKING_VIEW_NORMAL);
+}
diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c
index 005892b88a0..355f260ae11 100644
--- a/source/blender/editors/sculpt_paint/sculpt_boundary.c
+++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c
@@ -7,13 +7,11 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_edgehash.h"
#include "BLI_math.h"
#include "BLI_task.h"
#include "DNA_brush_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -21,20 +19,13 @@
#include "BKE_ccg.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_mesh.h"
-#include "BKE_multires.h"
-#include "BKE_node.h"
-#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
-#include "BKE_scene.h"
#include "paint_intern.h"
#include "sculpt_intern.h"
#include "GPU_immediate.h"
-#include "GPU_immediate_util.h"
-#include "GPU_matrix.h"
#include "GPU_state.h"
#include "bmesh.h"
@@ -681,12 +672,16 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
angle_factor = floorf(angle_factor * 10) / 10.0f;
}
const float angle = angle_factor * M_PI;
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (boundary->edit_info[vd.index].propagation_steps_num == -1) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
@@ -694,7 +689,8 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
}
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex);
+ const float automask = SCULPT_automasking_factor_get(
+ ss->cache->automasking, ss, vd.vertex, &automask_data);
float t_orig_co[3];
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
sub_v3_v3v3(t_orig_co, orig_data.co, boundary->bend.pivot_positions[vd.index]);
@@ -729,12 +725,16 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, boundary);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (boundary->edit_info[vd.index].propagation_steps_num == -1) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
@@ -742,7 +742,8 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
}
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex);
+ const float automask = SCULPT_automasking_factor_get(
+ ss->cache->automasking, ss, vd.vertex, &automask_data);
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
madd_v3_v3v3fl(target_co,
orig_data.co,
@@ -773,6 +774,9 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
PBVHVertexIter vd;
SculptOrigVertData orig_data;
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, boundary);
@@ -781,6 +785,7 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
@@ -788,7 +793,8 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
}
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex);
+ const float automask = SCULPT_automasking_factor_get(
+ ss->cache->automasking, ss, vd.vertex, &automask_data);
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
madd_v3_v3v3fl(target_co,
orig_data.co,
@@ -819,12 +825,16 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
PBVHVertexIter vd;
SculptOrigVertData orig_data;
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (boundary->edit_info[vd.index].propagation_steps_num == -1) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
@@ -832,7 +842,8 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
}
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex);
+ const float automask = SCULPT_automasking_factor_get(
+ ss->cache->automasking, ss, vd.vertex, &automask_data);
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
madd_v3_v3v3fl(target_co,
orig_data.co,
@@ -862,6 +873,9 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
PBVHVertexIter vd;
SculptOrigVertData orig_data;
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
const float disp = strength * sculpt_boundary_displacement_from_grab_delta_get(ss, boundary);
float angle_factor = disp / ss->cache->radius;
@@ -876,6 +890,7 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
@@ -883,7 +898,8 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
}
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex);
+ const float automask = SCULPT_automasking_factor_get(
+ ss->cache->automasking, ss, vd.vertex, &automask_data);
float t_orig_co[3];
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
sub_v3_v3v3(t_orig_co, orig_data.co, boundary->twist.pivot_position);
diff --git a/source/blender/editors/sculpt_paint/sculpt_brush_types.c b/source/blender/editors/sculpt_paint/sculpt_brush_types.c
index 245cbe0f54e..666fa884e03 100644
--- a/source/blender/editors/sculpt_paint/sculpt_brush_types.c
+++ b/source/blender/editors/sculpt_paint/sculpt_brush_types.c
@@ -8,26 +8,15 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
-#include "BLI_dial_2d.h"
#include "BLI_ghash.h"
#include "BLI_gsqueue.h"
-#include "BLI_hash.h"
#include "BLI_math.h"
-#include "BLI_math_color.h"
-#include "BLI_math_color_blend.h"
#include "BLI_task.h"
#include "BLI_utildefines.h"
-#include "BLT_translation.h"
-
-#include "PIL_time.h"
-
#include "DNA_brush_types.h"
#include "DNA_customdata_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -35,53 +24,16 @@
#include "BKE_ccg.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_image.h"
#include "BKE_kelvinlet.h"
-#include "BKE_key.h"
-#include "BKE_lib_id.h"
-#include "BKE_main.h"
-#include "BKE_mesh.h"
-#include "BKE_mesh_mapping.h"
-#include "BKE_mesh_mirror.h"
-#include "BKE_modifier.h"
-#include "BKE_multires.h"
-#include "BKE_node.h"
-#include "BKE_object.h"
#include "BKE_paint.h"
-#include "BKE_particle.h"
#include "BKE_pbvh.h"
-#include "BKE_pointcache.h"
-#include "BKE_report.h"
-#include "BKE_scene.h"
-#include "BKE_screen.h"
-#include "BKE_subdiv_ccg.h"
-#include "BKE_subsurf.h"
-
-#include "DEG_depsgraph.h"
-
-#include "IMB_colormanagement.h"
-
-#include "WM_api.h"
-#include "WM_message.h"
-#include "WM_toolsystem.h"
-#include "WM_types.h"
-#include "ED_object.h"
-#include "ED_screen.h"
-#include "ED_sculpt.h"
#include "ED_view3d.h"
#include "paint_intern.h"
#include "sculpt_intern.h"
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
#include "bmesh.h"
-#include "bmesh_tools.h"
#include <math.h>
#include <stdlib.h>
@@ -179,7 +131,7 @@ static void calc_sculpt_plane(
}
/* For area normal. */
- if ((!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) &&
+ if (!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache) &&
(brush->flag & BRUSH_ORIGINAL_NORMAL)) {
copy_v3_v3(r_area_no, ss->cache->sculpt_normal);
}
@@ -188,7 +140,7 @@ static void calc_sculpt_plane(
}
/* For flatten center. */
- if ((!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) &&
+ if (!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache) &&
(brush->flag & BRUSH_ORIGINAL_PLANE)) {
copy_v3_v3(r_area_co, ss->cache->last_center);
}
@@ -302,10 +254,17 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
+
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
/* Offset vertex. */
const float fade = SCULPT_brush_strength_factor(ss,
brush,
@@ -315,7 +274,8 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
mul_v3_v3fl(proxy[vd.i], offset, fade);
@@ -387,6 +347,10 @@ static void do_fill_brush_task_cb_ex(void *__restrict userdata,
plane_from_point_normal_v3(test.plane_tool, area_co, area_no);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
@@ -405,6 +369,8 @@ static void do_fill_brush_task_cb_ex(void *__restrict userdata,
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -413,7 +379,8 @@ static void do_fill_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
mul_v3_v3fl(proxy[vd.i], val, fade);
@@ -485,6 +452,10 @@ static void do_scrape_brush_task_cb_ex(void *__restrict userdata,
const int thread_id = BLI_task_parallel_thread_id(tls);
plane_from_point_normal_v3(test.plane_tool, area_co, area_no);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
@@ -503,6 +474,8 @@ static void do_scrape_brush_task_cb_ex(void *__restrict userdata,
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -511,7 +484,8 @@ static void do_scrape_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
mul_v3_v3fl(proxy[vd.i], val, fade);
@@ -601,6 +575,10 @@ static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata,
/* Tilted plane (front part of the brush). */
plane_from_point_normal_v3(plane_tilt, area_co, normal_tilt);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
@@ -621,6 +599,8 @@ static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata,
interp_v3_v3v3(intr, intr, intr_tilt, tilt_mix);
sub_v3_v3v3(val, intr_tilt, vd.co);
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -629,7 +609,8 @@ static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
mul_v3_v3fl(proxy[vd.i], val, fade);
@@ -764,6 +745,10 @@ static void do_flatten_brush_task_cb_ex(void *__restrict userdata,
plane_from_point_normal_v3(test.plane_tool, area_co, area_no);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
@@ -776,6 +761,8 @@ static void do_flatten_brush_task_cb_ex(void *__restrict userdata,
sub_v3_v3v3(val, intr, vd.co);
if (SCULPT_plane_trim(ss->cache, brush, val)) {
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -784,7 +771,8 @@ static void do_flatten_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
mul_v3_v3fl(proxy[vd.i], val, fade);
@@ -922,6 +910,10 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata,
plane_from_point_normal_v3(test.plane_tool, area_co, area_no);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
@@ -933,6 +925,8 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata,
sub_v3_v3v3(val, intr, vd.co);
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -941,7 +935,8 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
mul_v3_v3fl(proxy[vd.i], val, fade);
@@ -1041,6 +1036,10 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata,
plane_from_point_normal_v3(test.plane_tool, area_co, area_no_sp);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!SCULPT_brush_test_cube(&test, vd.co, mat, brush->tip_roundness)) {
continue;
@@ -1058,6 +1057,9 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata,
if (!SCULPT_plane_trim(ss->cache, brush, val)) {
continue;
}
+
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
/* The normal from the vertices is ignored, it causes glitch with planes, see: T44390. */
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
@@ -1067,7 +1069,8 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
mul_v3_v3fl(proxy[vd.i], val, fade);
@@ -1202,6 +1205,10 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
KelvinletParams params;
BKE_kelvinlet_init_params(&params, ss->cache->radius, bstrength, 1.0f, 0.4f);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!do_elastic && !sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
@@ -1212,6 +1219,8 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
fade = 1.0f;
}
else {
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -1220,7 +1229,8 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
}
mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
@@ -1267,7 +1277,9 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
if (vd.mask) {
mul_v3_fl(disp, 1.0f - *vd.mask);
}
- mul_v3_fl(disp, SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex));
+ mul_v3_fl(
+ disp,
+ SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex, &automask_data));
copy_v3_v3(proxy[vd.i], disp);
}
@@ -1339,12 +1351,18 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
orig_data.co,
@@ -1353,7 +1371,8 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata,
NULL,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
mul_v3_v3fl(proxy[vd.i], cono, fade);
@@ -1412,12 +1431,19 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
continue;
}
+
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
float vec[3], rot[3][3];
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
@@ -1427,7 +1453,8 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata,
NULL,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
sub_v3_v3v3(vec, orig_data.co, ss->cache->location);
axis_angle_normalized_to_mat3(rot, ss->cache->sculpt_normal_symm, angle * fade);
@@ -1472,7 +1499,8 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
Sculpt *sd = data->sd;
const Brush *brush = data->brush;
- const bool use_persistent_base = ss->persistent_base && brush->flag & BRUSH_PERSISTENT;
+ const bool use_persistent_base = !ss->bm && ss->attrs.persistent_co &&
+ brush->flag & BRUSH_PERSISTENT;
PBVHVertexIter vd;
SculptOrigVertData orig_data;
@@ -1484,12 +1512,18 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -1498,12 +1532,13 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
const int vi = vd.index;
float *disp_factor;
if (use_persistent_base) {
- disp_factor = &ss->persistent_base[vi].disp;
+ disp_factor = (float *)SCULPT_vertex_attr_get(vd.vertex, ss->attrs.persistent_disp);
}
else {
disp_factor = &ss->cache->layer_displacement_factor[vi];
@@ -1599,10 +1634,16 @@ static void do_inflate_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -1611,7 +1652,8 @@ static void do_inflate_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
float val[3];
if (vd.fno) {
@@ -1667,10 +1709,16 @@ static void do_nudge_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -1679,7 +1727,8 @@ static void do_nudge_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
mul_v3_v3fl(proxy[vd.i], cono, fade);
@@ -1745,11 +1794,17 @@ static void do_crease_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
/* Offset vertex. */
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -1758,7 +1813,8 @@ static void do_crease_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
float val1[3];
float val2[3];
@@ -1862,10 +1918,16 @@ static void do_pinch_brush_task_cb_ex(void *__restrict userdata,
copy_v3_v3(x_object_space, stroke_xz[0]);
copy_v3_v3(z_object_space, stroke_xz[1]);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -1874,7 +1936,8 @@ static void do_pinch_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
float disp_center[3];
float x_disp[3];
float z_disp[3];
@@ -1976,12 +2039,18 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata,
const bool grab_silhouette = brush->flag2 & BRUSH_GRAB_SILHOUETTE;
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
orig_data.co,
@@ -1990,7 +2059,8 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata,
NULL,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
if (grab_silhouette) {
float silhouette_test_dir[3];
@@ -2054,6 +2124,9 @@ static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata,
const float bstrength = ss->cache->bstrength;
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
@@ -2079,6 +2152,8 @@ static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
float final_disp[3];
switch (brush->elastic_deform_type) {
case BRUSH_ELASTIC_DEFORM_GRAB:
@@ -2109,7 +2184,9 @@ static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata,
mul_v3_fl(final_disp, 1.0f - *vd.mask);
}
- mul_v3_fl(final_disp, SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex));
+ mul_v3_fl(
+ final_disp,
+ SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex, &automask_data));
copy_v3_v3(proxy[vd.i], final_disp);
@@ -2173,12 +2250,18 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
continue;
}
/* Offset vertex. */
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = SCULPT_brush_strength_factor(ss,
brush,
orig_data.co,
@@ -2187,7 +2270,8 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata,
NULL,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
mul_v3_v3fl(proxy[vd.i], offset, fade);
@@ -2257,11 +2341,17 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = SCULPT_brush_strength_factor(ss,
brush,
orig_data.co,
@@ -2270,7 +2360,8 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata,
NULL,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
float current_disp[3];
float current_disp_norm[3];
float final_disp[3] = {0.0f, 0.0f, 0.0f};
@@ -2414,11 +2505,17 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = SCULPT_brush_strength_factor(ss,
brush,
orig_data.co,
@@ -2427,7 +2524,8 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata,
NULL,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
SCULPT_relax_vertex(ss, &vd, fade * bstrength, false, vd.co);
if (vd.mvert) {
@@ -2490,11 +2588,17 @@ static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -2503,7 +2607,8 @@ static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
float limit_co[3];
float disp[3];
@@ -2556,11 +2661,17 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -2569,7 +2680,8 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
float current_disp[3];
float current_disp_norm[3];
@@ -2717,16 +2829,29 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
- const float fade =
- bstrength *
- SCULPT_brush_strength_factor(
- ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, *vd.mask, vd.vertex, thread_id) *
- ss->cache->pressure;
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
+ const float fade = bstrength *
+ SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ *vd.mask,
+ vd.vertex,
+ thread_id,
+ &automask_data) *
+ ss->cache->pressure;
float avg[3], val[3];
@@ -2796,13 +2921,26 @@ static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
- const float fade = SCULPT_brush_strength_factor(
- ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, 0.0f, vd.vertex, thread_id);
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ 0.0f,
+ vd.vertex,
+ thread_id,
+ &automask_data);
if (bstrength > 0.0f) {
(*vd.mask) += fade * bstrength * (1.0f - *vd.mask);
diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c
index 691dfa21851..cf7e1d027f7 100644
--- a/source/blender/editors/sculpt_paint/sculpt_cloth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c
@@ -7,22 +7,15 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
-#include "BLI_dial_2d.h"
#include "BLI_edgehash.h"
#include "BLI_gsqueue.h"
-#include "BLI_hash.h"
#include "BLI_math.h"
#include "BLI_task.h"
#include "BLI_utildefines.h"
-#include "BLT_translation.h"
-
#include "DNA_brush_types.h"
#include "DNA_customdata_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -32,41 +25,16 @@
#include "BKE_collision.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_image.h"
-#include "BKE_kelvinlet.h"
-#include "BKE_key.h"
-#include "BKE_lib_id.h"
-#include "BKE_main.h"
-#include "BKE_mesh.h"
-#include "BKE_mesh_mapping.h"
-#include "BKE_mesh_mirror.h"
#include "BKE_modifier.h"
-#include "BKE_multires.h"
-#include "BKE_node.h"
-#include "BKE_object.h"
#include "BKE_paint.h"
-#include "BKE_particle.h"
#include "BKE_pbvh.h"
-#include "BKE_pointcache.h"
-#include "BKE_report.h"
-#include "BKE_scene.h"
-#include "BKE_screen.h"
-#include "BKE_subdiv_ccg.h"
-#include "BKE_subsurf.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
#include "WM_api.h"
-#include "WM_message.h"
-#include "WM_toolsystem.h"
#include "WM_types.h"
-#include "ED_object.h"
-#include "ED_screen.h"
-#include "ED_sculpt.h"
-#include "ED_view3d.h"
-#include "paint_intern.h"
#include "sculpt_intern.h"
#include "RNA_access.h"
@@ -78,10 +46,8 @@
#include "GPU_state.h"
#include "UI_interface.h"
-#include "UI_resources.h"
#include "bmesh.h"
-#include "bmesh_tools.h"
#include <math.h>
#include <stdlib.h>
@@ -504,7 +470,13 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
madd_v3_v3fl(gravity, ss->cache->gravity_direction, -data->sd->gravity_factor);
}
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, SCULPT_automasking_active_cache_get(ss), &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
float force[3];
float sim_location[3];
cloth_brush_simulation_location_get(ss, brush, sim_location);
@@ -544,7 +516,8 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
float brush_disp[3];
@@ -617,10 +590,11 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
static ListBase *cloth_brush_collider_cache_create(Object *object, Depsgraph *depsgraph)
{
ListBase *cache = NULL;
- DEG_OBJECT_ITER_BEGIN (depsgraph,
- ob,
- DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE |
- DEG_ITER_OBJECT_FLAG_DUPLI) {
+ DEGObjectIterSettings deg_iter_settings = {0};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
if (STREQ(object->id.name, ob->id.name)) {
continue;
}
@@ -693,15 +667,15 @@ static void cloth_brush_solve_collision(Object *object,
BVHTreeRayHit hit;
float obmat_inv[4][4];
- invert_m4_m4(obmat_inv, object->obmat);
+ invert_m4_m4(obmat_inv, object->object_to_world);
for (collider_cache = cloth_sim->collider_list->first; collider_cache;
collider_cache = collider_cache->next) {
float ray_start[3], ray_normal[3];
float pos_world_space[3], prev_pos_world_space[3];
- mul_v3_m4v3(pos_world_space, object->obmat, cloth_sim->pos[i]);
- mul_v3_m4v3(prev_pos_world_space, object->obmat, cloth_sim->last_iteration_pos[i]);
+ mul_v3_m4v3(pos_world_space, object->object_to_world, cloth_sim->pos[i]);
+ mul_v3_m4v3(prev_pos_world_space, object->object_to_world, cloth_sim->last_iteration_pos[i]);
sub_v3_v3v3(ray_normal, pos_world_space, prev_pos_world_space);
copy_v3_v3(ray_start, prev_pos_world_space);
hit.index = -1;
@@ -764,8 +738,13 @@ static void do_cloth_brush_solve_simulation_task_cb_ex(
}
AutomaskingCache *automasking = SCULPT_automasking_active_cache_get(ss);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, SCULPT_automasking_active_cache_get(ss), &automask_data, data->nodes[n]);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
float sim_location[3];
cloth_brush_simulation_location_get(ss, brush, sim_location);
const float sim_factor =
@@ -787,7 +766,7 @@ static void do_cloth_brush_solve_simulation_task_cb_ex(
mul_v3_fl(pos_diff, (1.0f - cloth_sim->damping) * sim_factor);
const float mask_v = (1.0f - (vd.mask ? *vd.mask : 0.0f)) *
- SCULPT_automasking_factor_get(automasking, ss, vd.vertex);
+ SCULPT_automasking_factor_get(automasking, ss, vd.vertex, &automask_data);
madd_v3_v3fl(cloth_sim->pos[i], pos_diff, mask_v);
madd_v3_v3fl(cloth_sim->pos[i], cloth_sim->acceleration[i], mask_v);
@@ -820,6 +799,9 @@ static void cloth_brush_satisfy_constraints(SculptSession *ss,
{
AutomaskingCache *automasking = SCULPT_automasking_active_cache_get(ss);
+ AutomaskingNodeData automask_data = {0};
+
+ automask_data.have_orig_data = true;
for (int constraint_it = 0; constraint_it < CLOTH_SIMULATION_ITERATIONS; constraint_it++) {
for (int i = 0; i < cloth_sim->tot_length_constraints; i++) {
@@ -858,10 +840,17 @@ static void cloth_brush_satisfy_constraints(SculptSession *ss,
PBVHVertRef vertex1 = BKE_pbvh_index_to_vertex(ss->pbvh, v1);
PBVHVertRef vertex2 = BKE_pbvh_index_to_vertex(ss->pbvh, v2);
+ automask_data.orig_data.co = cloth_sim->init_pos[v1];
+ automask_data.orig_data.no = cloth_sim->init_no[v1];
const float mask_v1 = (1.0f - SCULPT_vertex_mask_get(ss, vertex1)) *
- SCULPT_automasking_factor_get(automasking, ss, vertex1);
+ SCULPT_automasking_factor_get(
+ automasking, ss, vertex1, &automask_data);
+
+ automask_data.orig_data.co = cloth_sim->init_pos[v2];
+ automask_data.orig_data.no = cloth_sim->init_no[v2];
const float mask_v2 = (1.0f - SCULPT_vertex_mask_get(ss, vertex2)) *
- SCULPT_automasking_factor_get(automasking, ss, vertex2);
+ SCULPT_automasking_factor_get(
+ automasking, ss, vertex2, &automask_data);
float sim_location[3];
cloth_brush_simulation_location_get(ss, brush, sim_location);
@@ -1064,6 +1053,7 @@ SculptClothSimulation *SCULPT_cloth_brush_simulation_create(Object *ob,
cloth_sim->last_iteration_pos = MEM_calloc_arrayN(
totverts, sizeof(float[3]), "cloth sim last iteration pos");
cloth_sim->init_pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim init pos");
+ cloth_sim->init_no = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim init normals");
cloth_sim->length_constraint_tweak = MEM_calloc_arrayN(
totverts, sizeof(float), "cloth sim length tweak");
@@ -1139,6 +1129,7 @@ void SCULPT_cloth_brush_simulation_init(SculptSession *ss, SculptClothSimulation
copy_v3_v3(cloth_sim->last_iteration_pos[i], SCULPT_vertex_co_get(ss, vertex));
copy_v3_v3(cloth_sim->init_pos[i], SCULPT_vertex_co_get(ss, vertex));
+ SCULPT_vertex_normal_get(ss, vertex, cloth_sim->init_no[i]);
copy_v3_v3(cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, vertex));
if (has_deformation_pos) {
copy_v3_v3(cloth_sim->deformation_pos[i], SCULPT_vertex_co_get(ss, vertex));
@@ -1252,6 +1243,7 @@ void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim)
MEM_SAFE_FREE(cloth_sim->deformation_pos);
MEM_SAFE_FREE(cloth_sim->softbody_pos);
MEM_SAFE_FREE(cloth_sim->init_pos);
+ MEM_SAFE_FREE(cloth_sim->init_no);
MEM_SAFE_FREE(cloth_sim->deformation_strength);
MEM_SAFE_FREE(cloth_sim->node_state);
BLI_ghash_free(cloth_sim->node_state_index, NULL, NULL);
@@ -1427,17 +1419,23 @@ static void cloth_filter_apply_forces_task_cb(void *__restrict userdata,
float sculpt_gravity[3] = {0.0f};
if (sd->gravity_object) {
- copy_v3_v3(sculpt_gravity, sd->gravity_object->obmat[2]);
+ copy_v3_v3(sculpt_gravity, sd->gravity_object->object_to_world[2]);
}
else {
sculpt_gravity[2] = -1.0f;
}
mul_v3_fl(sculpt_gravity, sd->gravity_factor * data->filter_strength);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, SCULPT_automasking_active_cache_get(ss), &automask_data, node);
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
float fade = vd.mask ? *vd.mask : 0.0f;
- fade *= SCULPT_automasking_factor_get(ss->filter_cache->automasking, ss, vd.vertex);
+ fade *= SCULPT_automasking_factor_get(
+ ss->filter_cache->automasking, ss, vd.vertex, &automask_data);
fade = 1.0f - fade;
float force[3] = {0.0f, 0.0f, 0.0f};
float disp[3], temp[3], transform[3][3];
@@ -1579,8 +1577,11 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent
/* Needs mask data to be available as it is used when solving the constraints. */
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
+ SCULPT_stroke_id_next(ob);
+
SCULPT_undo_push_begin(ob, op);
- SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS);
+ SCULPT_filter_cache_init(
+ C, ob, sd, SCULPT_UNDO_COORDS, event->mval, RNA_float_get(op->ptr, "area_normal_radius"));
ss->filter_cache->automasking = SCULPT_automasking_cache_init(sd, NULL, ob);
@@ -1643,14 +1644,14 @@ void SCULPT_OT_cloth_filter(struct wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* RNA. */
+ SCULPT_mesh_filter_properties(ot);
+
RNA_def_enum(ot->srna,
"type",
prop_cloth_filter_type,
CLOTH_FILTER_GRAVITY,
"Filter Type",
"Operation that is going to be applied to the mesh");
- RNA_def_float(
- ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter strength", -10.0f, 10.0f);
RNA_def_enum_flag(ot->srna,
"force_axis",
prop_cloth_filter_force_axis_items,
diff --git a/source/blender/editors/sculpt_paint/sculpt_detail.c b/source/blender/editors/sculpt_paint/sculpt_detail.c
index 8f87cd1b6ed..0e46fd50f3b 100644
--- a/source/blender/editors/sculpt_paint/sculpt_detail.c
+++ b/source/blender/editors/sculpt_paint/sculpt_detail.c
@@ -30,7 +30,6 @@
#include "WM_types.h"
#include "ED_screen.h"
-#include "ED_sculpt.h"
#include "ED_space_api.h"
#include "ED_view3d.h"
#include "sculpt_intern.h"
@@ -103,7 +102,8 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *op)
size = max_fff(dim[0], dim[1], dim[2]);
/* Update topology size. */
- float object_space_constant_detail = 1.0f / (sd->constant_detail * mat4_to_scale(ob->obmat));
+ float object_space_constant_detail = 1.0f /
+ (sd->constant_detail * mat4_to_scale(ob->object_to_world));
BKE_pbvh_bmesh_detail_size_set(ss->pbvh, object_space_constant_detail);
SCULPT_undo_push_begin(ob, op);
@@ -224,7 +224,7 @@ static void sample_detail_dyntopo(bContext *C, ViewContext *vc, const int mval[2
if (srd.hit && srd.edge_length > 0.0f) {
/* Convert edge length to world space detail resolution. */
- sd->constant_detail = 1 / (srd.edge_length * mat4_to_scale(ob->obmat));
+ sd->constant_detail = 1 / (srd.edge_length * mat4_to_scale(ob->object_to_world));
}
}
@@ -474,8 +474,8 @@ static void dyntopo_detail_size_parallel_lines_draw(uint pos3d,
bool flip,
const float angle)
{
- float object_space_constant_detail = 1.0f /
- (cd->detail_size * mat4_to_scale(cd->active_object->obmat));
+ float object_space_constant_detail = 1.0f / (cd->detail_size *
+ mat4_to_scale(cd->active_object->object_to_world));
/* The constant detail represents the maximum edge length allowed before subdividing it. If the
* triangle grid preview is created with this value it will represent an ideal mesh density where
@@ -593,7 +593,8 @@ static void dyntopo_detail_size_sample_from_surface(Object *ob,
if (num_neighbors > 0) {
const float avg_edge_len = len_accum / num_neighbors;
/* Use 0.7 as the average of min and max dyntopo edge length. */
- const float detail_size = 0.7f / (avg_edge_len * mat4_to_scale(cd->active_object->obmat));
+ const float detail_size = 0.7f /
+ (avg_edge_len * mat4_to_scale(cd->active_object->object_to_world));
cd->detail_size = clamp_f(detail_size, 1.0f, 500.0f);
}
}
@@ -717,7 +718,7 @@ static int dyntopo_detail_size_edit_invoke(bContext *C, wmOperator *op, const wm
float cursor_trans[4][4], cursor_rot[4][4];
const float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
float quat[4];
- copy_m4_m4(cursor_trans, active_object->obmat);
+ copy_m4_m4(cursor_trans, active_object->object_to_world);
translate_m4(
cursor_trans, ss->cursor_location[0], ss->cursor_location[1], ss->cursor_location[2]);
diff --git a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
index 46674c5d239..388f4111555 100644
--- a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
@@ -7,9 +7,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
-#include "BLI_hash.h"
-#include "BLI_math.h"
#include "BLI_task.h"
#include "BLT_translation.h"
@@ -18,12 +15,10 @@
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
-#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
-#include "BKE_mesh_mapping.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_paint.h"
@@ -31,26 +26,15 @@
#include "BKE_pbvh.h"
#include "BKE_pointcache.h"
#include "BKE_scene.h"
-#include "BKE_screen.h"
#include "DEG_depsgraph.h"
#include "WM_api.h"
-#include "WM_message.h"
-#include "WM_toolsystem.h"
#include "WM_types.h"
-#include "ED_object.h"
-#include "ED_screen.h"
-#include "ED_sculpt.h"
#include "ED_undo.h"
-#include "ED_view3d.h"
-#include "paint_intern.h"
#include "sculpt_intern.h"
-#include "RNA_access.h"
-#include "RNA_define.h"
-
#include "UI_interface.h"
#include "UI_resources.h"
@@ -88,45 +72,6 @@ void SCULPT_pbvh_clear(Object *ob)
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
}
-void SCULPT_dyntopo_node_layers_add(SculptSession *ss)
-{
- int cd_node_layer_index;
-
- char node_vertex_id[] = "_dyntopo_vnode_id";
- char node_face_id[] = "_dyntopo_fnode_id";
-
- cd_node_layer_index = CustomData_get_named_layer_index(
- &ss->bm->vdata, CD_PROP_INT32, node_vertex_id);
-
- if (cd_node_layer_index == -1) {
- BM_data_layer_add_named(ss->bm, &ss->bm->vdata, CD_PROP_INT32, node_vertex_id);
- cd_node_layer_index = CustomData_get_named_layer_index(
- &ss->bm->vdata, CD_PROP_INT32, node_vertex_id);
- }
-
- ss->cd_vert_node_offset = CustomData_get_n_offset(
- &ss->bm->vdata,
- CD_PROP_INT32,
- cd_node_layer_index - CustomData_get_layer_index(&ss->bm->vdata, CD_PROP_INT32));
-
- 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_INT32, node_face_id);
- if (cd_node_layer_index == -1) {
- BM_data_layer_add_named(ss->bm, &ss->bm->pdata, CD_PROP_INT32, node_face_id);
- cd_node_layer_index = CustomData_get_named_layer_index(
- &ss->bm->pdata, CD_PROP_INT32, node_face_id);
- }
-
- ss->cd_face_node_offset = CustomData_get_n_offset(
- &ss->bm->pdata,
- CD_PROP_INT32,
- cd_node_layer_index - CustomData_get_layer_index(&ss->bm->pdata, CD_PROP_INT32));
-
- ss->bm->pdata.layers[cd_node_layer_index].flag |= CD_FLAG_TEMPORARY;
-}
-
void SCULPT_dynamic_topology_enable_ex(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob)
{
SculptSession *ss = ob->sculpt;
@@ -156,8 +101,9 @@ void SCULPT_dynamic_topology_enable_ex(Main *bmain, Depsgraph *depsgraph, Scene
.active_shapekey = 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. */
if (me->totpoly != ss->bm->totface) {
BM_mesh_normals_update(ss->bm);
@@ -185,6 +131,14 @@ static void SCULPT_dynamic_topology_disable_ex(
SculptSession *ss = ob->sculpt;
Mesh *me = ob->data;
+ if (ss->attrs.dyntopo_node_id_vertex) {
+ BKE_sculpt_attribute_destroy(ob, ss->attrs.dyntopo_node_id_vertex);
+ }
+
+ if (ss->attrs.dyntopo_node_id_face) {
+ BKE_sculpt_attribute_destroy(ob, ss->attrs.dyntopo_node_id_face);
+ }
+
SCULPT_pbvh_clear(ob);
if (unode) {
@@ -215,7 +169,7 @@ static void SCULPT_dynamic_topology_disable_ex(
BKE_sculptsession_bm_to_me(ob, true);
/* Reset Face Sets as they are no longer valid. */
- CustomData_free_layers(&me->pdata, CD_SCULPT_FACE_SETS, me->totpoly);
+ CustomData_free_layer_named(&me->pdata, ".sculpt_face_set", me->totpoly);
me->face_sets_color_default = 1;
/* Sync the visibility to vertices manually as the pmap is still not initialized. */
diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c
index 414a855ab2f..3133bb2007e 100644
--- a/source/blender/editors/sculpt_paint/sculpt_expand.c
+++ b/source/blender/editors/sculpt_paint/sculpt_expand.c
@@ -7,13 +7,10 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_linklist_stack.h"
#include "BLI_math.h"
#include "BLI_task.h"
-#include "BLT_translation.h"
-
#include "DNA_brush_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -27,9 +24,6 @@
#include "BKE_image.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
-#include "BKE_multires.h"
-#include "BKE_node.h"
-#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
#include "BKE_report.h"
@@ -39,17 +33,13 @@
#include "DEG_depsgraph.h"
#include "WM_api.h"
-#include "WM_message.h"
-#include "WM_toolsystem.h"
#include "WM_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
-#include "ED_object.h"
#include "ED_screen.h"
#include "ED_sculpt.h"
-#include "ED_view3d.h"
#include "paint_intern.h"
#include "sculpt_intern.h"
@@ -177,15 +167,16 @@ static float sculpt_expand_falloff_value_vertex_get(SculptSession *ss,
if (expand_cache->texture_distortion_strength == 0.0f) {
return expand_cache->vert_falloff[v_i];
}
-
- if (!expand_cache->brush->mtex.tex) {
+ const Brush *brush = expand_cache->brush;
+ const MTex *mtex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT);
+ if (!mtex->tex) {
return expand_cache->vert_falloff[v_i];
}
float rgba[4];
const float *vertex_co = SCULPT_vertex_co_get(ss, v);
const float avg = BKE_brush_sample_tex_3d(
- expand_cache->scene, expand_cache->brush, vertex_co, rgba, 0, ss->tex_pool);
+ expand_cache->scene, brush, mtex, vertex_co, rgba, 0, ss->tex_pool);
const float distortion = (avg - 0.5f) * expand_cache->texture_distortion_strength *
expand_cache->max_vert_falloff;
@@ -617,7 +608,7 @@ static float *sculpt_expand_boundary_topology_falloff_create(Object *ob, const P
for (int i = 0; i < boundary->verts_num; i++) {
BLI_gsqueue_push(queue, &boundary->verts[i]);
- BLI_BITMAP_ENABLE(visited_verts, boundary->verts_i[i]);
+ BLI_BITMAP_ENABLE(visited_verts, BKE_pbvh_vertex_to_index(ss->pbvh, boundary->verts[i]));
}
SCULPT_boundary_data_free(boundary);
}
@@ -2102,6 +2093,8 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even
SculptSession *ss = ob->sculpt;
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ SCULPT_stroke_id_next(ob);
+
/* Create and configure the Expand Cache. */
ss->expand_cache = MEM_callocN(sizeof(ExpandCache), "expand cache");
sculpt_expand_cache_initial_config_set(C, op, ss->expand_cache);
@@ -2116,6 +2109,11 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even
depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
}
+ if (ss->expand_cache->target == SCULPT_EXPAND_TARGET_MASK) {
+ MultiresModifierData *mmd = BKE_sculpt_multires_active(ss->scene, ob);
+ BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd);
+ }
+
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, needs_colors);
/* Do nothing when the mesh has 0 vertices. */
@@ -2130,11 +2128,6 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even
ss->face_sets = BKE_sculpt_face_sets_ensure(mesh);
}
- if (ss->expand_cache->target == SCULPT_EXPAND_TARGET_MASK) {
- MultiresModifierData *mmd = BKE_sculpt_multires_active(ss->scene, ob);
- BKE_sculpt_mask_layers_ensure(ob, mmd);
- }
-
/* Face Set operations are not supported in dyntopo. */
if (ss->expand_cache->target == SCULPT_EXPAND_TARGET_FACE_SETS &&
BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
@@ -2244,7 +2237,7 @@ void sculpt_expand_modal_keymap(wmKeyConfig *keyconf)
static const char *name = "Sculpt Expand Modal";
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, name);
- /* This function is called for each spacetype, only needs to add map once. */
+ /* This function is called for each space-type, only needs to add map once. */
if (keymap && keymap->modal_items) {
return;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.cc
index 8aa645c6af5..40835172be9 100644
--- a/source/blender/editors/sculpt_paint/sculpt_face_set.c
+++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc
@@ -5,12 +5,20 @@
* \ingroup edsculpt
*/
+#include <cmath>
+#include <cstdlib>
+#include <queue>
+
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
+#include "BLI_bit_vector.hh"
+#include "BLI_function_ref.hh"
#include "BLI_hash.h"
#include "BLI_math.h"
+#include "BLI_math_vector.hh"
+#include "BLI_span.hh"
#include "BLI_task.h"
+#include "BLI_task.hh"
#include "DNA_brush_types.h"
#include "DNA_customdata_types.h"
@@ -19,7 +27,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "BKE_brush.h"
+#include "BKE_attribute.hh"
#include "BKE_ccg.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
@@ -27,25 +35,17 @@
#include "BKE_mesh.h"
#include "BKE_mesh_fair.h"
#include "BKE_mesh_mapping.h"
-#include "BKE_multires.h"
-#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
-#include "BKE_scene.h"
#include "DEG_depsgraph.h"
#include "WM_api.h"
-#include "WM_message.h"
-#include "WM_toolsystem.h"
#include "WM_types.h"
-#include "ED_object.h"
-#include "ED_screen.h"
#include "ED_sculpt.h"
-#include "ED_view3d.h"
-#include "paint_intern.h"
+
#include "sculpt_intern.h"
#include "RNA_access.h"
@@ -53,21 +53,19 @@
#include "bmesh.h"
-#include <math.h>
-#include <stdlib.h>
-
/* Utils. */
int ED_sculpt_face_sets_find_next_available_id(struct Mesh *mesh)
{
- const int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ const int *face_sets = static_cast<const int *>(
+ CustomData_get_layer_named(&mesh->pdata, CD_PROP_INT32, ".sculpt_face_set"));
if (!face_sets) {
return SCULPT_FACE_SET_NONE;
}
int next_face_set_id = 0;
for (int i = 0; i < mesh->totpoly; i++) {
- next_face_set_id = max_ii(next_face_set_id, abs(face_sets[i]));
+ next_face_set_id = max_ii(next_face_set_id, face_sets[i]);
}
next_face_set_id++;
@@ -76,7 +74,8 @@ int ED_sculpt_face_sets_find_next_available_id(struct Mesh *mesh)
void ED_sculpt_face_sets_initialize_none_to_id(struct Mesh *mesh, const int new_id)
{
- int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ int *face_sets = static_cast<int *>(
+ CustomData_get_layer_named(&mesh->pdata, CD_PROP_INT32, ".sculpt_face_set"));
if (!face_sets) {
return;
}
@@ -109,7 +108,7 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict tls)
{
- SculptThreadedTaskData *data = userdata;
+ SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
SculptSession *ss = data->ob->sculpt;
const Brush *brush = data->brush;
const float bstrength = ss->cache->bstrength;
@@ -122,8 +121,13 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata,
const int thread_id = BLI_task_parallel_thread_id(tls);
MVert *mvert = SCULPT_mesh_deformed_mverts_get(ss);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
MeshElemMap *vert_map = &ss->pmap[vd.index];
for (int j = 0; j < ss->pmap[vd.index].count; j++) {
@@ -135,6 +139,10 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata,
if (!sculpt_brush_test_sq_fn(&test, poly_center)) {
continue;
}
+ const bool face_hidden = ss->hide_poly && ss->hide_poly[vert_map->indices[j]];
+ if (face_hidden) {
+ continue;
+ }
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -143,10 +151,11 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
- if (fade > 0.05f && ss->face_sets[vert_map->indices[j]] > 0) {
- ss->face_sets[vert_map->indices[j]] = abs(ss->cache->paint_face_set);
+ if (fade > 0.05f) {
+ ss->face_sets[vert_map->indices[j]] = ss->cache->paint_face_set;
}
}
}
@@ -162,7 +171,8 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
if (fade > 0.05f) {
SCULPT_vertex_face_set_set(ss, vd.vertex, ss->cache->paint_face_set);
@@ -176,7 +186,7 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict tls)
{
- SculptThreadedTaskData *data = userdata;
+ SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
SculptSession *ss = data->ob->sculpt;
const Brush *brush = data->brush;
float bstrength = ss->cache->bstrength;
@@ -189,13 +199,18 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata,
const bool relax_face_sets = !(ss->cache->iteration_count % 3 == 0);
/* This operations needs a strength tweak as the relax deformation is too weak by default. */
- if (relax_face_sets) {
- bstrength *= 2.0f;
+ if (relax_face_sets && data->iteration < 2) {
+ bstrength *= 1.5f;
}
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
@@ -211,7 +226,8 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
SCULPT_relax_vertex(ss, &vd, fade * bstrength, relax_face_sets, vd.co);
if (vd.mvert) {
@@ -226,21 +242,27 @@ void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
SculptSession *ss = ob->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
+ if (ss->pbvh) {
+ Mesh *mesh = BKE_mesh_from_object(ob);
+ BKE_pbvh_face_sets_color_set(
+ ss->pbvh, mesh->face_sets_color_seed, mesh->face_sets_color_default);
+ }
+
BKE_curvemapping_init(brush->curve);
/* Threaded loop over nodes. */
- SculptThreadedTaskData data = {
- .sd = sd,
- .ob = ob,
- .brush = brush,
- .nodes = nodes,
- };
+ SculptThreadedTaskData data{};
+ data.sd = sd;
+ data.ob = ob;
+ data.brush = brush;
+ data.nodes = nodes;
TaskParallelSettings settings;
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
if (ss->cache->alt_smooth) {
SCULPT_boundary_info_ensure(ob);
for (int i = 0; i < 4; i++) {
+ data.iteration = i;
BLI_task_parallel_range(0, totnode, &data, do_relax_face_sets_brush_task_cb_ex, &settings);
}
}
@@ -251,12 +273,12 @@ void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
/* Face Sets Operators */
-typedef enum eSculptFaceGroupsCreateModes {
+enum eSculptFaceGroupsCreateModes {
SCULPT_FACE_SET_MASKED = 0,
SCULPT_FACE_SET_VISIBLE = 1,
SCULPT_FACE_SET_ALL = 2,
SCULPT_FACE_SET_SELECTION = 3,
-} eSculptFaceGroupsCreateModes;
+};
static EnumPropertyItem prop_sculpt_face_set_create_types[] = {
{
@@ -287,11 +309,12 @@ static EnumPropertyItem prop_sculpt_face_set_create_types[] = {
"Face Set from Edit Mode Selection",
"Create an Face Set corresponding to the Edit Mode face selection",
},
- {0, NULL, 0, NULL, NULL},
+ {0, nullptr, 0, nullptr, nullptr},
};
static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
{
+ using namespace blender;
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
@@ -303,7 +326,7 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- Mesh *mesh = ob->data;
+ Mesh *mesh = static_cast<Mesh *>(ob->data);
ss->face_sets = BKE_sculpt_face_sets_ensure(mesh);
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, mode == SCULPT_FACE_SET_MASKED, false);
@@ -314,7 +337,7 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
PBVH *pbvh = ob->sculpt->pbvh;
PBVHNode **nodes;
int totnode;
- BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
+ BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
if (!nodes) {
return OPERATOR_CANCELLED;
@@ -375,28 +398,16 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
}
if (mode == SCULPT_FACE_SET_SELECTION) {
- BMesh *bm;
- const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh);
- bm = BM_mesh_create(&allocsize,
- &((struct BMeshCreateParams){
- .use_toolflags = true,
- }));
-
- BM_mesh_bm_from_me(bm,
- mesh,
- (&(struct BMeshFromMeshParams){
- .calc_face_normal = true,
- .calc_vert_normal = true,
- }));
-
- BMIter iter;
- BMFace *f;
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
- ss->face_sets[BM_elem_index_get(f)] = next_face_set;
+ const bke::AttributeAccessor attributes = mesh->attributes();
+ const VArraySpan<bool> select_poly = attributes.lookup_or_default<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE, false);
+ threading::parallel_for(IndexRange(mesh->totvert), 4096, [&](const IndexRange range) {
+ for (const int i : range) {
+ if (select_poly[i]) {
+ ss->face_sets[i] = next_face_set;
+ }
}
- }
- BM_mesh_free(bm);
+ });
}
for (int i = 0; i < totnode; i++) {
@@ -429,7 +440,7 @@ void SCULPT_OT_face_sets_create(wmOperatorType *ot)
ot->srna, "mode", prop_sculpt_face_set_create_types, SCULPT_FACE_SET_MASKED, "Mode", "");
}
-typedef enum eSculptFaceSetsInitMode {
+enum eSculptFaceSetsInitMode {
SCULPT_FACE_SETS_FROM_LOOSE_PARTS = 0,
SCULPT_FACE_SETS_FROM_MATERIALS = 1,
SCULPT_FACE_SETS_FROM_NORMALS = 2,
@@ -439,7 +450,7 @@ typedef enum eSculptFaceSetsInitMode {
SCULPT_FACE_SETS_FROM_BEVEL_WEIGHT = 6,
SCULPT_FACE_SETS_FROM_FACE_MAPS = 7,
SCULPT_FACE_SETS_FROM_FACE_SET_BOUNDARIES = 8,
-} eSculptFaceSetsInitMode;
+};
static EnumPropertyItem prop_sculpt_face_sets_init_types[] = {
{
@@ -506,203 +517,120 @@ static EnumPropertyItem prop_sculpt_face_sets_init_types[] = {
"Create a Face Set per isolated Face Set",
},
- {0, NULL, 0, NULL, NULL},
+ {0, nullptr, 0, nullptr, nullptr},
};
-typedef bool (*face_sets_flood_fill_test)(
- BMesh *bm, BMFace *from_f, BMEdge *from_e, BMFace *to_f, const float threshold);
-
-static bool sculpt_face_sets_init_loose_parts_test(BMesh *UNUSED(bm),
- BMFace *UNUSED(from_f),
- BMEdge *UNUSED(from_e),
- BMFace *UNUSED(to_f),
- const float UNUSED(threshold))
-{
- return true;
-}
-
-static bool sculpt_face_sets_init_normals_test(
- BMesh *UNUSED(bm), BMFace *from_f, BMEdge *UNUSED(from_e), BMFace *to_f, const float threshold)
-{
- return fabsf(dot_v3v3(from_f->no, to_f->no)) > threshold;
-}
-
-static bool sculpt_face_sets_init_uv_seams_test(BMesh *UNUSED(bm),
- BMFace *UNUSED(from_f),
- BMEdge *from_e,
- BMFace *UNUSED(to_f),
- const float UNUSED(threshold))
-{
- return !BM_elem_flag_test(from_e, BM_ELEM_SEAM);
-}
-
-static bool sculpt_face_sets_init_crease_test(
- BMesh *bm, BMFace *UNUSED(from_f), BMEdge *from_e, BMFace *UNUSED(to_f), const float threshold)
-{
- return BM_elem_float_data_get(&bm->edata, from_e, CD_CREASE) < threshold;
-}
-
-static bool sculpt_face_sets_init_bevel_weight_test(
- BMesh *bm, BMFace *UNUSED(from_f), BMEdge *from_e, BMFace *UNUSED(to_f), const float threshold)
-{
- return BM_elem_float_data_get(&bm->edata, from_e, CD_BWEIGHT) < threshold;
-}
-
-static bool sculpt_face_sets_init_sharp_edges_test(BMesh *UNUSED(bm),
- BMFace *UNUSED(from_f),
- BMEdge *from_e,
- BMFace *UNUSED(to_f),
- const float UNUSED(threshold))
-{
- return BM_elem_flag_test(from_e, BM_ELEM_SMOOTH);
-}
+using FaceSetsFloodFillFn = blender::FunctionRef<bool(int from_face, int edge, int to_face)>;
-static bool sculpt_face_sets_init_face_set_boundary_test(
- BMesh *bm, BMFace *from_f, BMEdge *UNUSED(from_e), BMFace *to_f, const float UNUSED(threshold))
-{
- const int cd_face_sets_offset = CustomData_get_offset(&bm->pdata, CD_SCULPT_FACE_SETS);
- return BM_ELEM_CD_GET_INT(from_f, cd_face_sets_offset) ==
- BM_ELEM_CD_GET_INT(to_f, cd_face_sets_offset);
-}
-
-static void sculpt_face_sets_init_flood_fill(Object *ob,
- face_sets_flood_fill_test test,
- const float threshold)
+static void sculpt_face_sets_init_flood_fill(Object *ob, const FaceSetsFloodFillFn &test_fn)
{
+ using namespace blender;
SculptSession *ss = ob->sculpt;
- Mesh *mesh = ob->data;
- BMesh *bm;
- const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh);
- bm = BM_mesh_create(&allocsize,
- &((struct BMeshCreateParams){
- .use_toolflags = true,
- }));
+ Mesh *mesh = static_cast<Mesh *>(ob->data);
- BM_mesh_bm_from_me(bm,
- mesh,
- (&(struct BMeshFromMeshParams){
- .calc_face_normal = true,
- .calc_vert_normal = true,
- }));
-
- BLI_bitmap *visited_faces = BLI_BITMAP_NEW(mesh->totpoly, "visited faces");
- const int totfaces = mesh->totpoly;
+ BitVector<> visited_faces(mesh->totpoly, false);
int *face_sets = ss->face_sets;
- BM_mesh_elem_table_init(bm, BM_FACE);
- BM_mesh_elem_table_ensure(bm, BM_FACE);
+ const Span<MEdge> edges = mesh->edges();
+ const Span<MPoly> polys = mesh->polys();
+ const Span<MLoop> loops = mesh->loops();
+
+ if (!ss->epmap) {
+ BKE_mesh_edge_poly_map_create(&ss->epmap,
+ &ss->epmap_mem,
+ edges.data(),
+ edges.size(),
+ polys.data(),
+ polys.size(),
+ loops.data(),
+ loops.size());
+ }
int next_face_set = 1;
- for (int i = 0; i < totfaces; i++) {
- if (BLI_BITMAP_TEST(visited_faces, i)) {
+ for (const int i : polys.index_range()) {
+ if (visited_faces[i]) {
continue;
}
- GSQueue *queue;
- queue = BLI_gsqueue_new(sizeof(int));
+ std::queue<int> queue;
face_sets[i] = next_face_set;
- BLI_BITMAP_ENABLE(visited_faces, i);
- BLI_gsqueue_push(queue, &i);
-
- while (!BLI_gsqueue_is_empty(queue)) {
- int from_f;
- BLI_gsqueue_pop(queue, &from_f);
-
- BMFace *f, *f_neighbor;
- BMEdge *ed;
- BMIter iter_a, iter_b;
-
- f = BM_face_at_index(bm, from_f);
-
- BM_ITER_ELEM (ed, &iter_a, f, BM_EDGES_OF_FACE) {
- BM_ITER_ELEM (f_neighbor, &iter_b, ed, BM_FACES_OF_EDGE) {
- if (f_neighbor == f) {
+ visited_faces[i].set(true);
+ queue.push(i);
+
+ while (!queue.empty()) {
+ const int poly_i = queue.front();
+ const MPoly &poly = polys[poly_i];
+ queue.pop();
+
+ for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
+ const int edge_i = loop.e;
+ const Span<int> neighbor_polys(ss->epmap[edge_i].indices, ss->epmap[edge_i].count);
+ for (const int neighbor_i : neighbor_polys) {
+ if (neighbor_i == poly_i) {
continue;
}
- int neighbor_face_index = BM_elem_index_get(f_neighbor);
- if (BLI_BITMAP_TEST(visited_faces, neighbor_face_index)) {
+ if (visited_faces[neighbor_i]) {
continue;
}
- if (!test(bm, f, ed, f_neighbor, threshold)) {
+ if (!test_fn(poly_i, edge_i, neighbor_i)) {
continue;
}
- face_sets[neighbor_face_index] = next_face_set;
- BLI_BITMAP_ENABLE(visited_faces, neighbor_face_index);
- BLI_gsqueue_push(queue, &neighbor_face_index);
+ face_sets[neighbor_i] = next_face_set;
+ visited_faces[neighbor_i].set(true);
+ queue.push(neighbor_i);
}
}
}
next_face_set += 1;
-
- BLI_gsqueue_free(queue);
}
-
- MEM_SAFE_FREE(visited_faces);
-
- BM_mesh_free(bm);
}
static void sculpt_face_sets_init_loop(Object *ob, const int mode)
{
- Mesh *mesh = ob->data;
+ using namespace blender;
+ Mesh *mesh = static_cast<Mesh *>(ob->data);
SculptSession *ss = ob->sculpt;
- BMesh *bm;
- const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh);
- bm = BM_mesh_create(&allocsize,
- &((struct BMeshCreateParams){
- .use_toolflags = true,
- }));
-
- BM_mesh_bm_from_me(bm,
- mesh,
- (&(struct BMeshFromMeshParams){
- .calc_face_normal = true,
- .calc_vert_normal = true,
- }));
- BMIter iter;
- BMFace *f;
-
- const int cd_fmaps_offset = CustomData_get_offset(&bm->pdata, CD_FACEMAP);
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- if (mode == SCULPT_FACE_SETS_FROM_MATERIALS) {
- ss->face_sets[BM_elem_index_get(f)] = (int)(f->mat_nr + 1);
+ if (mode == SCULPT_FACE_SETS_FROM_MATERIALS) {
+ const bke::AttributeAccessor attributes = mesh->attributes();
+ const VArraySpan<int> material_indices = attributes.lookup_or_default<int>(
+ "material_index", ATTR_DOMAIN_FACE, 0);
+ for (const int i : IndexRange(mesh->totpoly)) {
+ ss->face_sets[i] = material_indices[i] + 1;
}
- else if (mode == SCULPT_FACE_SETS_FROM_FACE_MAPS) {
- if (cd_fmaps_offset != -1) {
- ss->face_sets[BM_elem_index_get(f)] = BM_ELEM_CD_GET_INT(f, cd_fmaps_offset) + 2;
- }
- else {
- ss->face_sets[BM_elem_index_get(f)] = 1;
- }
+ }
+ else if (mode == SCULPT_FACE_SETS_FROM_FACE_MAPS) {
+ const int *face_maps = static_cast<int *>(CustomData_get_layer(&mesh->pdata, CD_FACEMAP));
+ for (const int i : IndexRange(mesh->totpoly)) {
+ ss->face_sets[i] = face_maps ? face_maps[i] : 1;
}
}
- BM_mesh_free(bm);
}
static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
{
+ using namespace blender;
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
const int mode = RNA_enum_get(op->ptr, "mode");
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
+
/* Dyntopo not supported. */
if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
return OPERATOR_CANCELLED;
}
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
-
PBVH *pbvh = ob->sculpt->pbvh;
PBVHNode **nodes;
int totnode;
- BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
+ BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
if (!nodes) {
return OPERATOR_CANCELLED;
@@ -713,44 +641,85 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
const float threshold = RNA_float_get(op->ptr, "threshold");
- Mesh *mesh = ob->data;
+ Mesh *mesh = static_cast<Mesh *>(ob->data);
ss->face_sets = BKE_sculpt_face_sets_ensure(mesh);
+ const bke::AttributeAccessor attributes = mesh->attributes();
switch (mode) {
- case SCULPT_FACE_SETS_FROM_LOOSE_PARTS:
- sculpt_face_sets_init_flood_fill(ob, sculpt_face_sets_init_loose_parts_test, threshold);
+ case SCULPT_FACE_SETS_FROM_LOOSE_PARTS: {
+ const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE, false);
+ sculpt_face_sets_init_flood_fill(
+ ob, [&](const int from_face, const int /*edge*/, const int to_face) {
+ return hide_poly[from_face] == hide_poly[to_face];
+ });
break;
- case SCULPT_FACE_SETS_FROM_MATERIALS:
+ }
+ case SCULPT_FACE_SETS_FROM_MATERIALS: {
sculpt_face_sets_init_loop(ob, SCULPT_FACE_SETS_FROM_MATERIALS);
break;
- case SCULPT_FACE_SETS_FROM_NORMALS:
- sculpt_face_sets_init_flood_fill(ob, sculpt_face_sets_init_normals_test, threshold);
+ }
+ case SCULPT_FACE_SETS_FROM_NORMALS: {
+ const Span<float3> poly_normals(
+ reinterpret_cast<const float3 *>(BKE_mesh_poly_normals_ensure(mesh)), mesh->totpoly);
+ sculpt_face_sets_init_flood_fill(
+ ob, [&](const int from_face, const int /*edge*/, const int to_face) -> bool {
+ return std::abs(math::dot(poly_normals[from_face], poly_normals[to_face])) > threshold;
+ });
break;
- case SCULPT_FACE_SETS_FROM_UV_SEAMS:
- sculpt_face_sets_init_flood_fill(ob, sculpt_face_sets_init_uv_seams_test, threshold);
+ }
+ case SCULPT_FACE_SETS_FROM_UV_SEAMS: {
+ const Span<MEdge> edges = mesh->edges();
+ sculpt_face_sets_init_flood_fill(
+ ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool {
+ return (edges[edge].flag & ME_SEAM) == 0;
+ });
break;
- case SCULPT_FACE_SETS_FROM_CREASES:
- sculpt_face_sets_init_flood_fill(ob, sculpt_face_sets_init_crease_test, threshold);
+ }
+ case SCULPT_FACE_SETS_FROM_CREASES: {
+ const float *creases = static_cast<const float *>(
+ CustomData_get_layer(&mesh->edata, CD_CREASE));
+ sculpt_face_sets_init_flood_fill(
+ ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool {
+ return creases[edge] < threshold;
+ });
break;
- case SCULPT_FACE_SETS_FROM_SHARP_EDGES:
- sculpt_face_sets_init_flood_fill(ob, sculpt_face_sets_init_sharp_edges_test, threshold);
+ }
+ case SCULPT_FACE_SETS_FROM_SHARP_EDGES: {
+ const Span<MEdge> edges = mesh->edges();
+ sculpt_face_sets_init_flood_fill(
+ ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool {
+ return (edges[edge].flag & ME_SHARP) == 0;
+ });
break;
- case SCULPT_FACE_SETS_FROM_BEVEL_WEIGHT:
- sculpt_face_sets_init_flood_fill(ob, sculpt_face_sets_init_bevel_weight_test, threshold);
+ }
+ case SCULPT_FACE_SETS_FROM_BEVEL_WEIGHT: {
+ const float *bevel_weights = static_cast<const float *>(
+ CustomData_get_layer(&mesh->edata, CD_BWEIGHT));
+ sculpt_face_sets_init_flood_fill(
+ ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool {
+ return bevel_weights ? bevel_weights[edge] / 255.0f < threshold : true;
+ });
break;
- case SCULPT_FACE_SETS_FROM_FACE_SET_BOUNDARIES:
+ }
+ case SCULPT_FACE_SETS_FROM_FACE_SET_BOUNDARIES: {
+ Array<int> face_sets_copy(Span<int>(ss->face_sets, mesh->totpoly));
sculpt_face_sets_init_flood_fill(
- ob, sculpt_face_sets_init_face_set_boundary_test, threshold);
+ ob, [&](const int from_face, const int /*edge*/, const int to_face) -> bool {
+ return face_sets_copy[from_face] == face_sets_copy[to_face];
+ });
break;
- case SCULPT_FACE_SETS_FROM_FACE_MAPS:
+ }
+ case SCULPT_FACE_SETS_FROM_FACE_MAPS: {
sculpt_face_sets_init_loop(ob, SCULPT_FACE_SETS_FROM_FACE_MAPS);
break;
+ }
}
SCULPT_undo_push_end(ob);
/* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */
- SCULPT_visibility_sync_all_face_sets_to_verts(ob);
+ SCULPT_visibility_sync_all_from_faces(ob);
for (int i = 0; i < totnode; i++) {
BKE_pbvh_node_mark_update_visibility(nodes[i]);
@@ -761,7 +730,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
MEM_SAFE_FREE(nodes);
if (BKE_pbvh_type(pbvh) == PBVH_FACES) {
- BKE_mesh_flush_hidden_from_verts(ob->data);
+ BKE_mesh_flush_hidden_from_verts(mesh);
}
SCULPT_tag_update_overlays(C);
@@ -796,13 +765,12 @@ void SCULPT_OT_face_sets_init(wmOperatorType *ot)
1.0f);
}
-typedef enum eSculptFaceGroupVisibilityModes {
+enum eSculptFaceGroupVisibilityModes {
SCULPT_FACE_SET_VISIBILITY_TOGGLE = 0,
SCULPT_FACE_SET_VISIBILITY_SHOW_ACTIVE = 1,
SCULPT_FACE_SET_VISIBILITY_HIDE_ACTIVE = 2,
SCULPT_FACE_SET_VISIBILITY_INVERT = 3,
- SCULPT_FACE_SET_VISIBILITY_SHOW_ALL = 4,
-} eSculptFaceGroupVisibilityModes;
+};
static EnumPropertyItem prop_sculpt_face_sets_change_visibility_types[] = {
{
@@ -833,14 +801,7 @@ static EnumPropertyItem prop_sculpt_face_sets_change_visibility_types[] = {
"Invert Face Set Visibility",
"Invert Face Set Visibility",
},
- {
- SCULPT_FACE_SET_VISIBILITY_SHOW_ALL,
- "SHOW_ALL",
- 0,
- "Show All Face Sets",
- "Show All Face Sets",
- },
- {0, NULL, 0, NULL, NULL},
+ {0, nullptr, 0, nullptr, nullptr},
};
static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op)
@@ -849,102 +810,123 @@ static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op)
SculptSession *ss = ob->sculpt;
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
- /* Dyntopo not supported. */
- if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
- return OPERATOR_CANCELLED;
- }
+ Mesh *mesh = BKE_object_get_original_mesh(ob);
- if (!pbvh_has_face_sets(ss->pbvh)) {
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
+
+ /* Not supported for dyntopo. */
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
return OPERATOR_CANCELLED;
}
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
-
- const int tot_vert = SCULPT_vertex_count_get(ss);
const int mode = RNA_enum_get(op->ptr, "mode");
- const int active_face_set = SCULPT_active_face_set_get(ss);
-
- SCULPT_undo_push_begin(ob, op);
+ const int tot_vert = SCULPT_vertex_count_get(ss);
PBVH *pbvh = ob->sculpt->pbvh;
PBVHNode **nodes;
int totnode;
- BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
+ BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
if (totnode == 0) {
MEM_SAFE_FREE(nodes);
return OPERATOR_CANCELLED;
}
- SCULPT_undo_push_node(ob, nodes[0], SCULPT_UNDO_FACE_SETS);
-
- if (mode == SCULPT_FACE_SET_VISIBILITY_TOGGLE) {
- bool hidden_vertex = false;
+ const int active_face_set = SCULPT_active_face_set_get(ss);
- /* This can fail with regular meshes with non-manifold geometry as the visibility state can't
- * be synced from face sets to non-manifold vertices. */
- if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
- for (int i = 0; i < tot_vert; i++) {
- PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
+ SCULPT_undo_push_begin(ob, op);
+ for (int i = 0; i < totnode; i++) {
+ SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_HIDDEN);
+ }
- if (!SCULPT_vertex_visible_get(ss, vertex)) {
- hidden_vertex = true;
- break;
+ switch (mode) {
+ case SCULPT_FACE_SET_VISIBILITY_TOGGLE: {
+ bool hidden_vertex = false;
+
+ /* This can fail with regular meshes with non-manifold geometry as the visibility state can't
+ * be synced from face sets to non-manifold vertices. */
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
+ for (int i = 0; i < tot_vert; i++) {
+ PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
+
+ if (!SCULPT_vertex_visible_get(ss, vertex)) {
+ hidden_vertex = true;
+ break;
+ }
}
}
- }
- for (int i = 0; i < ss->totfaces; i++) {
- if (ss->face_sets[i] <= 0) {
- hidden_vertex = true;
- break;
+ if (ss->hide_poly) {
+ for (int i = 0; i < ss->totfaces; i++) {
+ if (ss->hide_poly[i]) {
+ hidden_vertex = true;
+ break;
+ }
+ }
}
- }
- if (hidden_vertex) {
- SCULPT_face_sets_visibility_all_set(ss, true);
- }
- else {
- SCULPT_face_sets_visibility_all_set(ss, false);
- SCULPT_face_set_visibility_set(ss, active_face_set, true);
- }
- }
+ ss->hide_poly = BKE_sculpt_hide_poly_ensure(mesh);
- if (mode == SCULPT_FACE_SET_VISIBILITY_SHOW_ALL) {
- SCULPT_face_sets_visibility_all_set(ss, true);
- }
+ if (hidden_vertex) {
+ SCULPT_face_visibility_all_set(ss, true);
+ }
+ else {
+ if (ss->face_sets) {
+ SCULPT_face_visibility_all_set(ss, false);
+ SCULPT_face_set_visibility_set(ss, active_face_set, true);
+ }
+ else {
+ SCULPT_face_visibility_all_set(ss, true);
+ }
+ }
+ break;
+ }
+ case SCULPT_FACE_SET_VISIBILITY_SHOW_ACTIVE:
+ ss->hide_poly = BKE_sculpt_hide_poly_ensure(mesh);
- if (mode == SCULPT_FACE_SET_VISIBILITY_SHOW_ACTIVE) {
- SCULPT_face_sets_visibility_all_set(ss, false);
- SCULPT_face_set_visibility_set(ss, active_face_set, true);
- }
+ if (ss->face_sets) {
+ SCULPT_face_visibility_all_set(ss, false);
+ SCULPT_face_set_visibility_set(ss, active_face_set, true);
+ }
+ else {
+ SCULPT_face_set_visibility_set(ss, active_face_set, true);
+ }
+ break;
+ case SCULPT_FACE_SET_VISIBILITY_HIDE_ACTIVE:
+ ss->hide_poly = BKE_sculpt_hide_poly_ensure(mesh);
- if (mode == SCULPT_FACE_SET_VISIBILITY_HIDE_ACTIVE) {
- SCULPT_face_set_visibility_set(ss, active_face_set, false);
- }
+ if (ss->face_sets) {
+ SCULPT_face_set_visibility_set(ss, active_face_set, false);
+ }
+ else {
+ SCULPT_face_visibility_all_set(ss, false);
+ }
- if (mode == SCULPT_FACE_SET_VISIBILITY_INVERT) {
- SCULPT_face_sets_visibility_invert(ss);
+ break;
+ case SCULPT_FACE_SET_VISIBILITY_INVERT:
+ ss->hide_poly = BKE_sculpt_hide_poly_ensure(mesh);
+ SCULPT_face_visibility_all_invert(ss);
+ break;
}
/* For modes that use the cursor active vertex, update the rotation origin for viewport
- * navigation. */
+ * navigation.
+ */
if (ELEM(mode, SCULPT_FACE_SET_VISIBILITY_TOGGLE, SCULPT_FACE_SET_VISIBILITY_SHOW_ACTIVE)) {
UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
float location[3];
copy_v3_v3(location, SCULPT_active_vertex_co_get(ss));
- mul_m4_v3(ob->obmat, location);
+ mul_m4_v3(ob->object_to_world, location);
copy_v3_v3(ups->average_stroke_accum, location);
ups->average_stroke_counter = 1;
ups->last_stroke_valid = true;
}
/* Sync face sets visibility and vertex visibility. */
- SCULPT_visibility_sync_all_face_sets_to_verts(ob);
+ SCULPT_visibility_sync_all_from_faces(ob);
SCULPT_undo_push_end(ob);
-
for (int i = 0; i < totnode; i++) {
BKE_pbvh_node_mark_update_visibility(nodes[i]);
}
@@ -968,7 +950,7 @@ static int sculpt_face_sets_change_visibility_invoke(bContext *C,
/* Update the active vertex and Face Set using the cursor position to avoid relying on the paint
* cursor updates. */
SculptCursorGeometryInfo sgi;
- const float mval_fl[2] = {UNPACK2(event->mval)};
+ const float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])};
SCULPT_vertex_random_access_ensure(ss);
SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
@@ -997,7 +979,7 @@ void SCULPT_OT_face_sets_change_visibility(wmOperatorType *ot)
"");
}
-static int sculpt_face_sets_randomize_colors_exec(bContext *C, wmOperator *UNUSED(op))
+static int sculpt_face_sets_randomize_colors_exec(bContext *C, wmOperator * /*op*/)
{
Object *ob = CTX_data_active_object(C);
@@ -1008,14 +990,14 @@ static int sculpt_face_sets_randomize_colors_exec(bContext *C, wmOperator *UNUSE
return OPERATOR_CANCELLED;
}
- if (!pbvh_has_face_sets(ss->pbvh)) {
+ if (!ss->face_sets) {
return OPERATOR_CANCELLED;
}
PBVH *pbvh = ob->sculpt->pbvh;
PBVHNode **nodes;
int totnode;
- Mesh *mesh = ob->data;
+ Mesh *mesh = static_cast<Mesh *>(ob->data);
mesh->face_sets_color_seed += 1;
if (ss->face_sets) {
@@ -1026,7 +1008,7 @@ static int sculpt_face_sets_randomize_colors_exec(bContext *C, wmOperator *UNUSE
}
BKE_pbvh_face_sets_color_set(pbvh, mesh->face_sets_color_seed, mesh->face_sets_color_default);
- BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
+ BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
for (int i = 0; i < totnode; i++) {
BKE_pbvh_node_mark_redraw(nodes[i]);
}
@@ -1052,13 +1034,13 @@ void SCULPT_OT_face_sets_randomize_colors(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-typedef enum eSculptFaceSetEditMode {
+enum eSculptFaceSetEditMode {
SCULPT_FACE_SET_EDIT_GROW = 0,
SCULPT_FACE_SET_EDIT_SHRINK = 1,
SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY = 2,
SCULPT_FACE_SET_EDIT_FAIR_POSITIONS = 3,
SCULPT_FACE_SET_EDIT_FAIR_TANGENCY = 4,
-} eSculptFaceSetEditMode;
+};
static EnumPropertyItem prop_sculpt_face_sets_edit_types[] = {
{
@@ -1098,7 +1080,7 @@ static EnumPropertyItem prop_sculpt_face_sets_edit_types[] = {
"Creates a smooth as possible geometry patch from the Face Set minimizing changes in "
"vertex tangents",
},
- {0, NULL, 0, NULL, NULL},
+ {0, nullptr, 0, nullptr, nullptr},
};
static void sculpt_face_set_grow(Object *ob,
@@ -1164,22 +1146,25 @@ static void sculpt_face_set_shrink(Object *ob,
}
}
-static bool check_single_face_set(SculptSession *ss, int *face_sets, const bool check_visible_only)
+static bool check_single_face_set(SculptSession *ss,
+ const int *face_sets,
+ const bool check_visible_only)
{
- if (face_sets == NULL) {
+ if (face_sets == nullptr) {
return true;
}
int first_face_set = SCULPT_FACE_SET_NONE;
if (check_visible_only) {
for (int f = 0; f < ss->totfaces; f++) {
- if (face_sets[f] > 0) {
- first_face_set = face_sets[f];
- break;
+ if (ss->hide_poly && ss->hide_poly[f]) {
+ continue;
}
+ first_face_set = face_sets[f];
+ break;
}
}
else {
- first_face_set = abs(face_sets[0]);
+ first_face_set = face_sets[0];
}
if (first_face_set == SCULPT_FACE_SET_NONE) {
@@ -1187,8 +1172,10 @@ static bool check_single_face_set(SculptSession *ss, int *face_sets, const bool
}
for (int f = 0; f < ss->totfaces; f++) {
- const int face_set_id = check_visible_only ? face_sets[f] : abs(face_sets[f]);
- if (face_set_id != first_face_set) {
+ if (check_visible_only && ss->hide_poly && ss->hide_poly[f]) {
+ continue;
+ }
+ if (face_sets[f] != first_face_set) {
return false;
}
}
@@ -1201,19 +1188,16 @@ static void sculpt_face_set_delete_geometry(Object *ob,
const bool modify_hidden)
{
- Mesh *mesh = ob->data;
+ Mesh *mesh = static_cast<Mesh *>(ob->data);
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh);
- BMesh *bm = BM_mesh_create(&allocsize,
- &((struct BMeshCreateParams){
- .use_toolflags = true,
- }));
-
- BM_mesh_bm_from_me(bm,
- mesh,
- (&(struct BMeshFromMeshParams){
- .calc_face_normal = true,
- .calc_vert_normal = true,
- }));
+ BMeshCreateParams create_params{};
+ create_params.use_toolflags = true;
+ BMesh *bm = BM_mesh_create(&allocsize, &create_params);
+
+ BMeshFromMeshParams convert_params{};
+ convert_params.calc_vert_normal = true;
+ convert_params.calc_face_normal = true;
+ BM_mesh_bm_from_me(bm, mesh, &convert_params);
BM_mesh_elem_table_init(bm, BM_FACE);
BM_mesh_elem_table_ensure(bm, BM_FACE);
@@ -1222,32 +1206,31 @@ static void sculpt_face_set_delete_geometry(Object *ob,
BMFace *f;
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
const int face_index = BM_elem_index_get(f);
- const int face_set_id = modify_hidden ? abs(ss->face_sets[face_index]) :
- ss->face_sets[face_index];
- BM_elem_flag_set(f, BM_ELEM_TAG, face_set_id == active_face_set_id);
+ if (!modify_hidden && ss->hide_poly && ss->hide_poly[face_index]) {
+ continue;
+ }
+ BM_elem_flag_set(f, BM_ELEM_TAG, ss->face_sets[face_index] == active_face_set_id);
}
BM_mesh_delete_hflag_context(bm, BM_ELEM_TAG, DEL_FACES);
BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
- BM_mesh_bm_to_me(NULL,
- bm,
- ob->data,
- (&(struct BMeshToMeshParams){
- .calc_object_remap = false,
- }));
+ BMeshToMeshParams bmesh_to_mesh_params{};
+ bmesh_to_mesh_params.calc_object_remap = false;
+ BM_mesh_bm_to_me(nullptr, bm, mesh, &bmesh_to_mesh_params);
BM_mesh_free(bm);
}
static void sculpt_face_set_edit_fair_face_set(Object *ob,
const int active_face_set_id,
- const int fair_order)
+ const eMeshFairingDepth fair_order)
{
SculptSession *ss = ob->sculpt;
const int totvert = SCULPT_vertex_count_get(ss);
- Mesh *mesh = ob->data;
- bool *fair_verts = MEM_malloc_arrayN(totvert, sizeof(bool), "fair vertices");
+ Mesh *mesh = static_cast<Mesh *>(ob->data);
+ bool *fair_verts = static_cast<bool *>(
+ MEM_malloc_arrayN(totvert, sizeof(bool), "fair vertices"));
SCULPT_boundary_info_ensure(ob);
@@ -1273,13 +1256,13 @@ static void sculpt_face_set_apply_edit(Object *ob,
switch (mode) {
case SCULPT_FACE_SET_EDIT_GROW: {
- int *prev_face_sets = MEM_dupallocN(ss->face_sets);
+ int *prev_face_sets = static_cast<int *>(MEM_dupallocN(ss->face_sets));
sculpt_face_set_grow(ob, ss, prev_face_sets, active_face_set_id, modify_hidden);
MEM_SAFE_FREE(prev_face_sets);
break;
}
case SCULPT_FACE_SET_EDIT_SHRINK: {
- int *prev_face_sets = MEM_dupallocN(ss->face_sets);
+ int *prev_face_sets = static_cast<int *>(MEM_dupallocN(ss->face_sets));
sculpt_face_set_shrink(ob, ss, prev_face_sets, active_face_set_id, modify_hidden);
MEM_SAFE_FREE(prev_face_sets);
break;
@@ -1339,21 +1322,23 @@ static void sculpt_face_set_edit_modify_geometry(bContext *C,
const bool modify_hidden,
wmOperator *op)
{
+ Mesh *mesh = static_cast<Mesh *>(ob->data);
ED_sculpt_undo_geometry_begin(ob, op);
sculpt_face_set_apply_edit(ob, abs(active_face_set), mode, modify_hidden);
ED_sculpt_undo_geometry_end(ob);
- BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
+ BKE_mesh_batch_cache_dirty_tag(mesh, BKE_MESH_BATCH_DIRTY_ALL);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, mesh);
}
static void face_set_edit_do_post_visibility_updates(Object *ob, PBVHNode **nodes, int totnode)
{
SculptSession *ss = ob->sculpt;
PBVH *pbvh = ss->pbvh;
+ Mesh *mesh = static_cast<Mesh *>(ob->data);
/* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */
- SCULPT_visibility_sync_all_face_sets_to_verts(ob);
+ SCULPT_visibility_sync_all_from_faces(ob);
for (int i = 0; i < totnode; i++) {
BKE_pbvh_node_mark_update_visibility(nodes[i]);
@@ -1362,7 +1347,7 @@ static void face_set_edit_do_post_visibility_updates(Object *ob, PBVHNode **node
BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility);
if (BKE_pbvh_type(pbvh) == PBVH_FACES) {
- BKE_mesh_flush_hidden_from_verts(ob->data);
+ BKE_mesh_flush_hidden_from_verts(mesh);
}
}
@@ -1375,7 +1360,7 @@ static void sculpt_face_set_edit_modify_face_sets(Object *ob,
PBVH *pbvh = ob->sculpt->pbvh;
PBVHNode **nodes;
int totnode;
- BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
+ BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
if (!nodes) {
return;
@@ -1399,7 +1384,7 @@ static void sculpt_face_set_edit_modify_coordinates(bContext *C,
PBVH *pbvh = ss->pbvh;
PBVHNode **nodes;
int totnode;
- BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
+ BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
SCULPT_undo_push_begin(ob, op);
for (int i = 0; i < totnode; i++) {
BKE_pbvh_node_mark_update(nodes[i]);
@@ -1422,19 +1407,21 @@ static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEven
SculptSession *ss = ob->sculpt;
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- const int mode = RNA_enum_get(op->ptr, "mode");
+ const eSculptFaceSetEditMode mode = static_cast<eSculptFaceSetEditMode>(
+ RNA_enum_get(op->ptr, "mode"));
const bool modify_hidden = RNA_boolean_get(op->ptr, "modify_hidden");
if (!sculpt_face_set_edit_is_operation_valid(ss, mode, modify_hidden)) {
return OPERATOR_CANCELLED;
}
+ ss->face_sets = BKE_sculpt_face_sets_ensure(BKE_mesh_from_object(ob));
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
/* Update the current active Face Set and Vertex as the operator can be used directly from the
* tool without brush cursor. */
SculptCursorGeometryInfo sgi;
- const float mval_fl[2] = {UNPACK2(event->mval)};
+ const float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])};
if (!SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false)) {
/* The cursor is not over the mesh. Cancel to avoid editing the last updated Face Set ID. */
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
index 161fc563950..89cb67a875f 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
@@ -7,47 +7,29 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
-#include "BLI_hash.h"
#include "BLI_math.h"
#include "BLI_math_color_blend.h"
#include "BLI_task.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "BKE_brush.h"
-#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_mesh.h"
-#include "BKE_mesh_mapping.h"
-#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
-#include "BKE_report.h"
-#include "BKE_scene.h"
#include "IMB_colormanagement.h"
#include "DEG_depsgraph.h"
#include "WM_api.h"
-#include "WM_message.h"
-#include "WM_toolsystem.h"
#include "WM_types.h"
-#include "ED_object.h"
#include "ED_paint.h"
-#include "ED_screen.h"
-#include "ED_sculpt.h"
-#include "paint_intern.h"
#include "sculpt_intern.h"
#include "RNA_access.h"
#include "RNA_define.h"
-#include "UI_interface.h"
-
#include "bmesh.h"
#include <math.h>
@@ -95,16 +77,23 @@ static void color_filter_task_cb(void *__restrict userdata,
SculptOrigVertData orig_data;
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COLOR);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->filter_cache->automasking, &automask_data, data->nodes[n]);
+
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
float orig_color[3], final_color[4], hsv_color[3];
int hue;
float brightness, contrast, gain, delta, offset;
float fade = vd.mask ? *vd.mask : 0.0f;
fade = 1.0f - fade;
fade *= data->filter_strength;
- fade *= SCULPT_automasking_factor_get(ss->filter_cache->automasking, ss, vd.vertex);
+ fade *= SCULPT_automasking_factor_get(
+ ss->filter_cache->automasking, ss, vd.vertex, &automask_data);
if (fade == 0.0f) {
continue;
}
@@ -334,6 +323,9 @@ static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent
const bool use_automasking = SCULPT_is_automasking_enabled(sd, ss, NULL);
if (use_automasking) {
+ /* Increment stroke id for automasking system. */
+ SCULPT_stroke_id_next(ob);
+
/* Update the active face set manually as the paint cursor is not enabled when using the Mesh
* Filter Tool. */
float mval_fl[2] = {UNPACK2(event->mval)};
@@ -358,7 +350,8 @@ static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent
return OPERATOR_CANCELLED;
}
- SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COLOR);
+ SCULPT_filter_cache_init(
+ C, ob, sd, SCULPT_UNDO_COLOR, event->mval, RNA_float_get(op->ptr, "area_normal_radius"));
FilterCache *filter_cache = ss->filter_cache;
filter_cache->active_face_set = SCULPT_FACE_SET_NONE;
filter_cache->automasking = SCULPT_automasking_cache_init(sd, NULL, ob);
@@ -383,9 +376,9 @@ void SCULPT_OT_color_filter(struct wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* rna */
+ SCULPT_mesh_filter_properties(ot);
+
RNA_def_enum(ot->srna, "type", prop_color_filter_types, COLOR_FILTER_HUE, "Filter Type", "");
- RNA_def_float(
- ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter strength", -10.0f, 10.0f);
PropertyRNA *prop = RNA_def_float_color(
ot->srna, "fill_color", 3, NULL, 0.0f, FLT_MAX, "Fill Color", "", 0.0f, 1.0f);
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c b/source/blender/editors/sculpt_paint/sculpt_filter_mask.c
index bb27e4f1e9e..8e199a72858 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_mask.c
@@ -7,20 +7,13 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
-#include "BLI_hash.h"
#include "BLI_math.h"
#include "BLI_task.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
-#include "BKE_brush.h"
#include "BKE_context.h"
-#include "BKE_mesh.h"
-#include "BKE_mesh_mapping.h"
-#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
#include "BKE_scene.h"
@@ -28,21 +21,13 @@
#include "DEG_depsgraph.h"
#include "WM_api.h"
-#include "WM_message.h"
-#include "WM_toolsystem.h"
#include "WM_types.h"
-#include "ED_object.h"
-#include "ED_screen.h"
-#include "ED_sculpt.h"
-#include "paint_intern.h"
#include "sculpt_intern.h"
#include "RNA_access.h"
#include "RNA_define.h"
-#include "UI_interface.h"
-
#include "bmesh.h"
#include <math.h>
@@ -182,7 +167,7 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
int filter_type = RNA_enum_get(op->ptr, "filter_type");
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
- BKE_sculpt_mask_layers_ensure(ob, mmd);
+ BKE_sculpt_mask_layers_ensure(CTX_data_depsgraph_pointer(C), CTX_data_main(C), ob, mmd);
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
@@ -303,173 +288,3 @@ void SCULPT_OT_mask_filter(struct wmOperatorType *ot)
"Auto Iteration Count",
"Use a automatic number of iterations based on the number of vertices of the sculpt");
}
-
-static float neighbor_dirty_mask(SculptSession *ss, PBVHVertexIter *vd)
-{
- int total = 0;
- float avg[3];
- zero_v3(avg);
-
- SculptVertexNeighborIter ni;
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd->vertex, ni) {
- float normalized[3];
- sub_v3_v3v3(normalized, SCULPT_vertex_co_get(ss, ni.vertex), vd->co);
- normalize_v3(normalized);
- add_v3_v3(avg, normalized);
- total++;
- }
- SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
-
- if (total > 0) {
- mul_v3_fl(avg, 1.0f / total);
- float dot = dot_v3v3(avg, vd->no ? vd->no : vd->fno);
- float angle = max_ff(saacosf(dot), 0.0f);
- return angle;
- }
- return 0.0f;
-}
-
-typedef struct DirtyMaskRangeData {
- float min, max;
-} DirtyMaskRangeData;
-
-static void dirty_mask_compute_range_task_cb(void *__restrict userdata,
- const int i,
- const TaskParallelTLS *__restrict tls)
-{
- SculptThreadedTaskData *data = userdata;
- SculptSession *ss = data->ob->sculpt;
- PBVHNode *node = data->nodes[i];
- DirtyMaskRangeData *range = tls->userdata_chunk;
- PBVHVertexIter vd;
-
- BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
- float dirty_mask = neighbor_dirty_mask(ss, &vd);
- range->min = min_ff(dirty_mask, range->min);
- range->max = max_ff(dirty_mask, range->max);
- }
- BKE_pbvh_vertex_iter_end;
-}
-
-static void dirty_mask_compute_range_reduce(const void *__restrict UNUSED(userdata),
- void *__restrict chunk_join,
- void *__restrict chunk)
-{
- DirtyMaskRangeData *join = chunk_join;
- DirtyMaskRangeData *range = chunk;
- join->min = min_ff(range->min, join->min);
- join->max = max_ff(range->max, join->max);
-}
-
-static void dirty_mask_apply_task_cb(void *__restrict userdata,
- const int i,
- const TaskParallelTLS *__restrict UNUSED(tls))
-{
- SculptThreadedTaskData *data = userdata;
- SculptSession *ss = data->ob->sculpt;
- PBVHNode *node = data->nodes[i];
- PBVHVertexIter vd;
-
- const bool dirty_only = data->dirty_mask_dirty_only;
- const float min = data->dirty_mask_min;
- const float max = data->dirty_mask_max;
-
- float range = max - min;
- if (range < 0.0001f) {
- range = 0.0f;
- }
- else {
- range = 1.0f / range;
- }
-
- BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
- float dirty_mask = neighbor_dirty_mask(ss, &vd);
- float mask = *vd.mask + (1.0f - ((dirty_mask - min) * range));
- if (dirty_only) {
- mask = fminf(mask, 0.5f) * 2.0f;
- }
- *vd.mask = CLAMPIS(mask, 0.0f, 1.0f);
- }
- BKE_pbvh_vertex_iter_end;
- BKE_pbvh_node_mark_update_mask(node);
-}
-
-static int sculpt_dirty_mask_exec(bContext *C, wmOperator *op)
-{
- ARegion *region = CTX_wm_region(C);
- Object *ob = CTX_data_active_object(C);
- SculptSession *ss = ob->sculpt;
- Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
- PBVH *pbvh = ob->sculpt->pbvh;
- PBVHNode **nodes;
- Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
- int totnode;
-
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
-
- SCULPT_vertex_random_access_ensure(ss);
-
- if (!ob->sculpt->pmap) {
- return OPERATOR_CANCELLED;
- }
-
- BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
- SCULPT_undo_push_begin(ob, op);
-
- for (int i = 0; i < totnode; i++) {
- SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK);
- }
-
- SculptThreadedTaskData data = {
- .sd = sd,
- .ob = ob,
- .nodes = nodes,
- .dirty_mask_dirty_only = RNA_boolean_get(op->ptr, "dirty_only"),
- };
- DirtyMaskRangeData range = {
- .min = FLT_MAX,
- .max = -FLT_MAX,
- };
-
- TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, true, totnode);
-
- settings.func_reduce = dirty_mask_compute_range_reduce;
- settings.userdata_chunk = &range;
- settings.userdata_chunk_size = sizeof(DirtyMaskRangeData);
-
- BLI_task_parallel_range(0, totnode, &data, dirty_mask_compute_range_task_cb, &settings);
- data.dirty_mask_min = range.min;
- data.dirty_mask_max = range.max;
- BLI_task_parallel_range(0, totnode, &data, dirty_mask_apply_task_cb, &settings);
-
- MEM_SAFE_FREE(nodes);
-
- BKE_pbvh_update_vertex_data(pbvh, PBVH_UpdateMask);
-
- SCULPT_undo_push_end(ob);
-
- ED_region_tag_redraw(region);
-
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
-
- return OPERATOR_FINISHED;
-}
-
-void SCULPT_OT_dirty_mask(struct wmOperatorType *ot)
-{
- /* Identifiers. */
- ot->name = "Dirty Mask";
- ot->idname = "SCULPT_OT_dirty_mask";
- ot->description = "Generates a mask based on the geometry cavity and pointiness";
-
- /* API callbacks. */
- ot->exec = sculpt_dirty_mask_exec;
- ot->poll = SCULPT_mode_poll;
-
- ot->flag = OPTYPE_REGISTER;
-
- /* RNA. */
- RNA_def_boolean(
- ot->srna, "dirty_only", false, "Dirty Only", "Don't calculate cleans for convex areas");
-}
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
index e576cfda3af..c158cf33f6d 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
@@ -7,34 +7,24 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_hash.h"
#include "BLI_math.h"
#include "BLI_task.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_brush.h"
#include "BKE_context.h"
-#include "BKE_mesh.h"
-#include "BKE_mesh_mapping.h"
-#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
-#include "BKE_scene.h"
#include "DEG_depsgraph.h"
#include "WM_api.h"
-#include "WM_message.h"
-#include "WM_toolsystem.h"
#include "WM_types.h"
-#include "ED_object.h"
-#include "ED_screen.h"
-#include "ED_sculpt.h"
#include "ED_view3d.h"
+
#include "paint_intern.h"
#include "sculpt_intern.h"
@@ -101,7 +91,12 @@ static void filter_cache_init_task_cb(void *__restrict userdata,
SCULPT_undo_push_node(data->ob, node, data->filter_undo_type);
}
-void SCULPT_filter_cache_init(bContext *C, Object *ob, Sculpt *sd, const int undo_type)
+void SCULPT_filter_cache_init(bContext *C,
+ Object *ob,
+ Sculpt *sd,
+ const int undo_type,
+ const int mval[2],
+ float area_normal_radius)
{
SculptSession *ss = ob->sculpt;
PBVH *pbvh = ob->sculpt->pbvh;
@@ -151,14 +146,87 @@ void SCULPT_filter_cache_init(bContext *C, Object *ob, Sculpt *sd, const int und
0, ss->filter_cache->totnode, &data, filter_cache_init_task_cb, &settings);
/* Setup orientation matrices. */
- copy_m4_m4(ss->filter_cache->obmat, ob->obmat);
- invert_m4_m4(ss->filter_cache->obmat_inv, ob->obmat);
+ copy_m4_m4(ss->filter_cache->obmat, ob->object_to_world);
+ invert_m4_m4(ss->filter_cache->obmat_inv, ob->object_to_world);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
ViewContext vc;
ED_view3d_viewcontext_init(C, &vc, depsgraph);
copy_m4_m4(ss->filter_cache->viewmat, vc.rv3d->viewmat);
copy_m4_m4(ss->filter_cache->viewmat_inv, vc.rv3d->viewinv);
+
+ Scene *scene = CTX_data_scene(C);
+ UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
+
+ float co[3];
+ float mval_fl[2] = {(float)mval[0], (float)mval[1]};
+
+ if (SCULPT_stroke_get_location(C, co, mval_fl, false)) {
+ PBVHNode **nodes;
+ int totnode;
+
+ /* Get radius from brush. */
+ Brush *brush = BKE_paint_brush(&sd->paint);
+ float radius;
+
+ if (brush) {
+ if (BKE_brush_use_locked_size(scene, brush)) {
+ radius = paint_calc_object_space_radius(
+ &vc, co, (float)BKE_brush_size_get(scene, brush) * area_normal_radius);
+ }
+ else {
+ radius = BKE_brush_unprojected_radius_get(scene, brush) * area_normal_radius;
+ }
+ }
+ else {
+ radius = paint_calc_object_space_radius(&vc, co, (float)ups->size * area_normal_radius);
+ }
+
+ SculptSearchSphereData search_data2 = {
+ .original = true,
+ .center = co,
+ .radius_squared = radius * radius,
+ .ignore_fully_ineffective = true,
+ };
+
+ BKE_pbvh_search_gather(pbvh, SCULPT_search_sphere_cb, &search_data2, &nodes, &totnode);
+
+ if (SCULPT_pbvh_calc_area_normal(
+ brush, ob, nodes, totnode, true, ss->filter_cache->initial_normal)) {
+ copy_v3_v3(ss->last_normal, ss->filter_cache->initial_normal);
+ }
+ else {
+ copy_v3_v3(ss->filter_cache->initial_normal, ss->last_normal);
+ }
+
+ MEM_SAFE_FREE(nodes);
+
+ /* Update last stroke location */
+
+ mul_m4_v3(ob->object_to_world, co);
+
+ add_v3_v3(ups->average_stroke_accum, co);
+ ups->average_stroke_counter++;
+ ups->last_stroke_valid = true;
+ }
+ else {
+ /* Use last normal. */
+ copy_v3_v3(ss->filter_cache->initial_normal, ss->last_normal);
+ }
+
+ /* Update view normal */
+ float projection_mat[4][4];
+ float mat[3][3];
+ float viewDir[3] = {0.0f, 0.0f, 1.0f};
+
+ ED_view3d_ob_project_mat_get(vc.rv3d, ob, projection_mat);
+
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
+ copy_m3_m4(mat, vc.rv3d->viewinv);
+ mul_m3_v3(mat, viewDir);
+ copy_m3_m4(mat, ob->world_to_object);
+ mul_m3_v3(mat, viewDir);
+ normalize_v3_v3(ss->filter_cache->view_normal, viewDir);
}
void SCULPT_filter_cache_free(SculptSession *ss)
@@ -288,15 +356,20 @@ static void mesh_filter_task_cb(void *__restrict userdata,
/* This produces better results as the relax operation is no completely focused on the
* boundaries. */
const bool relax_face_sets = !(ss->filter_cache->iteration_count % 3 == 0);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(data->ob, ss, ss->filter_cache->automasking, &automask_data, node);
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
float orig_co[3], val[3], avg[3], disp[3], disp2[3], transform[3][3], final_pos[3];
float fade = vd.mask ? *vd.mask : 0.0f;
fade = 1.0f - fade;
fade *= data->filter_strength;
- fade *= SCULPT_automasking_factor_get(ss->filter_cache->automasking, ss, vd.vertex);
+ fade *= SCULPT_automasking_factor_get(
+ ss->filter_cache->automasking, ss, vd.vertex, &automask_data);
if (fade == 0.0f && filter_type != MESH_FILTER_SURFACE_SMOOTH) {
/* Surface Smooth can't skip the loop for this vertex as it needs to calculate its
@@ -580,11 +653,18 @@ static void mesh_filter_surface_smooth_displace_task_cb(
PBVHNode *node = data->nodes[i];
PBVHVertexIter vd;
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->filter_cache->automasking, &automask_data, data->nodes[i]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
float fade = vd.mask ? *vd.mask : 0.0f;
fade = 1.0f - fade;
fade *= data->filter_strength;
- fade *= SCULPT_automasking_factor_get(ss->filter_cache->automasking, ss, vd.vertex);
+ fade *= SCULPT_automasking_factor_get(
+ ss->filter_cache->automasking, ss, vd.vertex, &automask_data);
if (fade == 0.0f) {
continue;
}
@@ -681,6 +761,9 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
}
if (use_automasking) {
+ /* Increment stroke id for automasking system. */
+ SCULPT_stroke_id_next(ob);
+
/* Update the active face set manually as the paint cursor is not enabled when using the Mesh
* Filter Tool. */
float mval_fl[2] = {UNPACK2(event->mval)};
@@ -696,7 +779,8 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
SCULPT_undo_push_begin(ob, op);
- SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS);
+ SCULPT_filter_cache_init(
+ C, ob, sd, SCULPT_UNDO_COORDS, event->mval, RNA_float_get(op->ptr, "area_normal_radius"));
FilterCache *filter_cache = ss->filter_cache;
filter_cache->active_face_set = SCULPT_FACE_SET_NONE;
@@ -743,6 +827,22 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
return OPERATOR_RUNNING_MODAL;
}
+void SCULPT_mesh_filter_properties(struct wmOperatorType *ot)
+{
+ RNA_def_float(
+ ot->srna,
+ "area_normal_radius",
+ 0.25,
+ 0.001,
+ 5.0,
+ "Normal Radius",
+ "Radius used for calculating area normal on initial click,\nin percentage of brush radius",
+ 0.01,
+ 1.0);
+ RNA_def_float(
+ ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter strength", -10.0f, 10.0f);
+}
+
void SCULPT_OT_mesh_filter(struct wmOperatorType *ot)
{
/* Identifiers. */
@@ -758,14 +858,14 @@ void SCULPT_OT_mesh_filter(struct wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* RNA. */
+ SCULPT_mesh_filter_properties(ot);
+
RNA_def_enum(ot->srna,
"type",
prop_mesh_filter_types,
MESH_FILTER_INFLATE,
"Filter Type",
"Operation that is going to be applied to the mesh");
- RNA_def_float(
- ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter strength", -10.0f, 10.0f);
RNA_def_enum_flag(ot->srna,
"deform_axis",
prop_mesh_filter_deform_axis_items,
diff --git a/source/blender/editors/sculpt_paint/sculpt_geodesic.c b/source/blender/editors/sculpt_paint/sculpt_geodesic.c
index c0856ab21d2..5d74853be8c 100644
--- a/source/blender/editors/sculpt_paint/sculpt_geodesic.c
+++ b/source/blender/editors/sculpt_paint/sculpt_geodesic.c
@@ -7,52 +7,26 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_linklist_stack.h"
#include "BLI_math.h"
#include "BLI_task.h"
-#include "BLT_translation.h"
-
#include "DNA_brush_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "BKE_brush.h"
#include "BKE_ccg.h"
-#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_image.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
-#include "BKE_multires.h"
-#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
-#include "BKE_scene.h"
-#include "BKE_subdiv_ccg.h"
-
-#include "DEG_depsgraph.h"
-
-#include "WM_api.h"
-#include "WM_toolsystem.h"
-#include "WM_types.h"
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "ED_object.h"
-#include "ED_screen.h"
-#include "ED_sculpt.h"
-#include "ED_view3d.h"
#include "paint_intern.h"
#include "sculpt_intern.h"
-#include "IMB_colormanagement.h"
-#include "IMB_imbuf.h"
-
#include "bmesh.h"
#include <math.h>
@@ -170,8 +144,6 @@ static float *SCULPT_geodesic_mesh_create(Object *ob,
}
}
- const bool *hide_poly = BKE_pbvh_get_poly_hide(ss->pbvh);
-
/* Add edges adjacent to an initial vertex to the queue. */
for (int i = 0; i < totedge; i++) {
const int v1 = edges[i].v1;
@@ -201,7 +173,7 @@ static float *SCULPT_geodesic_mesh_create(Object *ob,
if (ss->epmap[e].count != 0) {
for (int poly_map_index = 0; poly_map_index < ss->epmap[e].count; poly_map_index++) {
const int poly = ss->epmap[e].indices[poly_map_index];
- if (hide_poly && hide_poly[poly]) {
+ if (ss->hide_poly && ss->hide_poly[poly]) {
continue;
}
const MPoly *mpoly = &polys[poly];
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 7a72e5cc84b..bf47b64d176 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -27,6 +27,7 @@ extern "C" {
#endif
struct AutomaskingCache;
+struct AutomaskingNodeData;
struct Image;
struct ImageUser;
struct KeyBlock;
@@ -34,6 +35,9 @@ struct Object;
struct SculptUndoNode;
struct bContext;
struct PaintModeSettings;
+struct wmKeyConfig;
+struct wmOperator;
+struct wmOperatorType;
/* Updates */
@@ -311,10 +315,6 @@ typedef struct SculptThreadedTaskData {
float *cloth_sim_initial_location;
float cloth_sim_radius;
- float dirty_mask_min;
- float dirty_mask_max;
- bool dirty_mask_dirty_only;
-
/* Mask By Color Tool */
float mask_by_color_threshold;
@@ -332,7 +332,7 @@ typedef struct SculptThreadedTaskData {
int mask_init_seed;
ThreadMutex mutex;
-
+ int iteration;
} SculptThreadedTaskData;
/*************** Brush testing declarations ****************/
@@ -398,13 +398,20 @@ typedef struct AutomaskingSettings {
/* Flags from eAutomasking_flag. */
int flags;
int initial_face_set;
+
+ float cavity_factor;
+ int cavity_blur_steps;
+ struct CurveMapping *cavity_curve;
+
+ float start_normal_limit, start_normal_falloff;
+ float view_normal_limit, view_normal_falloff;
} AutomaskingSettings;
typedef struct AutomaskingCache {
AutomaskingSettings settings;
- /* Precomputed auto-mask factor indexed by vertex, owned by the auto-masking system and
- * initialized in #SCULPT_automasking_cache_init when needed. */
- float *factor;
+
+ bool can_reuse_mask;
+ uchar current_stroke_id;
} AutomaskingCache;
typedef struct FilterCache {
@@ -464,6 +471,8 @@ typedef struct FilterCache {
/* Auto-masking. */
AutomaskingCache *automasking;
+ float initial_normal[3];
+ float view_normal[3];
/* Pre-smoothed colors used by sharpening. Colors are HSL. */
float (*pre_smoothed_color)[4];
@@ -636,6 +645,7 @@ typedef struct StrokeCache {
rcti previous_r; /* previous redraw rectangle */
rcti current_r; /* current redraw rectangle */
+ int stroke_id;
} StrokeCache;
/* -------------------------------------------------------------------- */
@@ -913,6 +923,8 @@ float SCULPT_vertex_mask_get(struct SculptSession *ss, PBVHVertRef vertex);
void SCULPT_vertex_color_get(const SculptSession *ss, PBVHVertRef vertex, float r_color[4]);
void SCULPT_vertex_color_set(SculptSession *ss, PBVHVertRef vertex, const float color[4]);
+bool SCULPT_vertex_is_occluded(SculptSession *ss, PBVHVertRef vertex, bool original);
+
/** Returns true if a color attribute exists in the current sculpt session. */
bool SCULPT_has_colors(const SculptSession *ss);
@@ -1004,9 +1016,13 @@ void SCULPT_connected_components_ensure(Object *ob);
void SCULPT_vertex_visible_set(SculptSession *ss, PBVHVertRef vertex, bool visible);
bool SCULPT_vertex_visible_get(SculptSession *ss, PBVHVertRef vertex);
+bool SCULPT_vertex_all_faces_visible_get(const SculptSession *ss, PBVHVertRef vertex);
+bool SCULPT_vertex_any_face_visible_get(SculptSession *ss, PBVHVertRef vertex);
+
+void SCULPT_face_visibility_all_invert(SculptSession *ss);
+void SCULPT_face_visibility_all_set(SculptSession *ss, bool visible);
-void SCULPT_visibility_sync_all_face_sets_to_verts(struct Object *ob);
-void SCULPT_visibility_sync_all_vertex_to_face_sets(struct SculptSession *ss);
+void SCULPT_visibility_sync_all_from_faces(struct Object *ob);
/** \} */
@@ -1024,11 +1040,6 @@ bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, PBVHVertRef vertex);
int SCULPT_face_set_next_available_get(SculptSession *ss);
void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visible);
-bool SCULPT_vertex_all_face_sets_visible_get(const SculptSession *ss, PBVHVertRef vertex);
-bool SCULPT_vertex_any_face_set_visible_get(SculptSession *ss, PBVHVertRef vertex);
-
-void SCULPT_face_sets_visibility_invert(SculptSession *ss);
-void SCULPT_face_sets_visibility_all_set(SculptSession *ss, bool visible);
/** \} */
@@ -1195,7 +1206,8 @@ float SCULPT_brush_strength_factor(struct SculptSession *ss,
const float fno[3],
float mask,
const PBVHVertRef vertex,
- int thread_id);
+ int thread_id,
+ struct AutomaskingNodeData *automask_data);
/**
* Tilts a normal by the x and y tilt values using the view axis.
@@ -1274,7 +1286,6 @@ void sculpt_dynamic_topology_disable_with_undo(struct Main *bmain,
bool SCULPT_stroke_is_dynamic_topology(const SculptSession *ss, const Brush *brush);
void SCULPT_dynamic_topology_triangulate(struct BMesh *bm);
-void SCULPT_dyntopo_node_layers_add(struct SculptSession *ss);
enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob);
@@ -1284,9 +1295,30 @@ enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob);
/** \name Auto-masking.
* \{ */
+typedef struct AutomaskingNodeData {
+ PBVHNode *node;
+ SculptOrigVertData orig_data;
+ bool have_orig_data;
+} AutomaskingNodeData;
+
+/** Call before PBVH vertex iteration.
+ * \param automask_data: pointer to an uninitialized AutomaskingNodeData struct.
+ */
+void SCULPT_automasking_node_begin(struct Object *ob,
+ const SculptSession *ss,
+ struct AutomaskingCache *automasking,
+ AutomaskingNodeData *automask_data,
+ PBVHNode *node);
+
+/* Call before SCULPT_automasking_factor_get and SCULPT_brush_strength_factor. */
+void SCULPT_automasking_node_update(SculptSession *ss,
+ AutomaskingNodeData *automask_data,
+ PBVHVertexIter *vd);
+
float SCULPT_automasking_factor_get(struct AutomaskingCache *automasking,
SculptSession *ss,
- PBVHVertRef vertex);
+ PBVHVertRef vertex,
+ AutomaskingNodeData *automask_data);
/* Returns the automasking cache depending on the active tool. Used for code that can run both for
* brushes and filter. */
@@ -1302,6 +1334,12 @@ float *SCULPT_boundary_automasking_init(Object *ob,
eBoundaryAutomaskMode mode,
int propagation_steps,
float *automask_factor);
+bool SCULPT_automasking_needs_normal(const SculptSession *ss,
+ const Sculpt *sculpt,
+ const Brush *brush);
+bool SCULPT_automasking_needs_original(const struct Sculpt *sd, const struct Brush *brush);
+int SCULPT_automasking_settings_hash(Object *ob, AutomaskingCache *automasking);
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -1315,7 +1353,7 @@ float *SCULPT_boundary_automasking_init(Object *ob,
* fallback to euclidean distances to one of the initial vertices in the set.
*/
float *SCULPT_geodesic_distances_create(struct Object *ob,
- struct GSet *initial_vertices,
+ struct GSet *initial_verts,
float limit_radius);
float *SCULPT_geodesic_from_vertex_and_symm(struct Sculpt *sd,
struct Object *ob,
@@ -1328,8 +1366,14 @@ float *SCULPT_geodesic_from_vertex(Object *ob, PBVHVertRef vertex, float limit_r
/** \name Filter API
* \{ */
-void SCULPT_filter_cache_init(struct bContext *C, Object *ob, Sculpt *sd, int undo_type);
+void SCULPT_filter_cache_init(struct bContext *C,
+ Object *ob,
+ Sculpt *sd,
+ int undo_type,
+ const int mval[2],
+ float area_normal_radius);
void SCULPT_filter_cache_free(SculptSession *ss);
+void SCULPT_mesh_filter_properties(struct wmOperatorType *ot);
void SCULPT_mask_filter_smooth_apply(
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, int smooth_iterations);
@@ -1592,7 +1636,6 @@ void SCULPT_OT_color_filter(struct wmOperatorType *ot);
/* Mask filter and Dirty Mask. */
void SCULPT_OT_mask_filter(struct wmOperatorType *ot);
-void SCULPT_OT_dirty_mask(struct wmOperatorType *ot);
/* Mask and Face Sets Expand. */
@@ -1847,6 +1890,15 @@ BLI_INLINE bool SCULPT_tool_is_face_sets(int tool)
return ELEM(tool, SCULPT_TOOL_DRAW_FACE_SETS);
}
+void SCULPT_stroke_id_ensure(struct Object *ob);
+void SCULPT_stroke_id_next(struct Object *ob);
+bool SCULPT_tool_can_reuse_automask(int sculpt_tool);
+
#ifdef __cplusplus
}
#endif
+
+/* Make SCULPT_ alias to a few blenkernel sculpt methods. */
+
+#define SCULPT_vertex_attr_get BKE_sculpt_vertex_attr_get
+#define SCULPT_face_attr_get BKE_sculpt_face_attr_get
diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c
index ec246cd3788..1b8cc5347ac 100644
--- a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c
+++ b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c
@@ -7,44 +7,30 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_task.h"
#include "BLT_translation.h"
#include "DNA_brush_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
-#include "BKE_brush.h"
#include "BKE_ccg.h"
-#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_mesh.h"
-#include "BKE_multires.h"
-#include "BKE_node.h"
-#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
-#include "BKE_scene.h"
#include "DEG_depsgraph.h"
#include "WM_api.h"
-#include "WM_message.h"
-#include "WM_toolsystem.h"
#include "WM_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
-#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_sculpt.h"
-#include "ED_view3d.h"
-#include "paint_intern.h"
#include "sculpt_intern.h"
#include "bmesh.h"
@@ -346,6 +332,11 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent
SculptCursorGeometryInfo sgi;
const float mval_fl[2] = {UNPACK2(event->mval)};
+ MultiresModifierData *mmd = BKE_sculpt_multires_active(CTX_data_scene(C), ob);
+ BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd);
+
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
+
SCULPT_vertex_random_access_ensure(ss);
op->customdata = MEM_mallocN(sizeof(float[2]), "initial mouse position");
@@ -353,8 +344,6 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent
SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
-
int vertex_count = SCULPT_vertex_count_get(ss);
ss->filter_cache = MEM_callocN(sizeof(FilterCache), "filter cache");
diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_init.c b/source/blender/editors/sculpt_paint/sculpt_mask_init.c
index b9b889ab2ce..99a7bb8a926 100644
--- a/source/blender/editors/sculpt_paint/sculpt_mask_init.c
+++ b/source/blender/editors/sculpt_paint/sculpt_mask_init.c
@@ -7,27 +7,20 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_hash.h"
#include "BLI_math.h"
#include "BLI_task.h"
-#include "BLT_translation.h"
-
#include "PIL_time.h"
#include "DNA_brush_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
-#include "BKE_brush.h"
#include "BKE_ccg.h"
#include "BKE_context.h"
-#include "BKE_mesh.h"
#include "BKE_multires.h"
-#include "BKE_node.h"
-#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
@@ -39,8 +32,6 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "ED_sculpt.h"
-#include "paint_intern.h"
#include "sculpt_intern.h"
#include "bmesh.h"
@@ -120,6 +111,9 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op)
const int mode = RNA_enum_get(op->ptr, "mode");
+ MultiresModifierData *mmd = BKE_sculpt_multires_active(CTX_data_scene(C), ob);
+ BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd);
+
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
PBVH *pbvh = ob->sculpt->pbvh;
diff --git a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
index 1e8731e54c0..fd8f5b8945c 100644
--- a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
+++ b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
@@ -5,36 +5,22 @@
* \ingroup edsculpt
*/
-#include "MEM_guardedalloc.h"
-
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_task.h"
#include "DNA_brush_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "BKE_brush.h"
#include "BKE_ccg.h"
-#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_mesh.h"
-#include "BKE_multires.h"
-#include "BKE_node.h"
-#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
-#include "BKE_scene.h"
-#include "paint_intern.h"
#include "sculpt_intern.h"
#include "GPU_immediate.h"
-#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
-#include "GPU_state.h"
#include "bmesh.h"
@@ -69,6 +55,10 @@ static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata,
test_radius *= brush->normal_radius_factor;
test.radius_squared = test_radius * test_radius;
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
@@ -78,6 +68,9 @@ static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata,
float normal[3];
copy_v3_v3(normal, vd.no ? vd.no : vd.fno);
mul_v3_m4v3(local_co, mat, vd.co);
+
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
/* Use the brush falloff to weight the sampled normals. */
const float fade = SCULPT_brush_strength_factor(ss,
brush,
@@ -87,7 +80,8 @@ static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
/* Sample the normal and area of the +X and -X axis individually. */
if (local_co[0] > 0.0f) {
@@ -144,6 +138,10 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
@@ -184,6 +182,9 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata,
if (!SCULPT_plane_trim(ss->cache, brush, val)) {
continue;
}
+
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
/* Deform the local space along the Y axis to avoid artifacts on curved strokes. */
/* This produces a not round brush tip. */
local_co[1] *= 2.0f;
@@ -195,7 +196,8 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
mul_v3_v3fl(proxy[vd.i], val, fade);
diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.c b/source/blender/editors/sculpt_paint/sculpt_ops.c
index 055e02a5703..8affb0e9d53 100644
--- a/source/blender/editors/sculpt_paint/sculpt_ops.c
+++ b/source/blender/editors/sculpt_paint/sculpt_ops.c
@@ -8,33 +8,20 @@
#include "MEM_guardedalloc.h"
-#include "BLI_array.h"
-#include "BLI_blenlib.h"
-#include "BLI_dial_2d.h"
#include "BLI_ghash.h"
#include "BLI_gsqueue.h"
-#include "BLI_hash.h"
-#include "BLI_link_utils.h"
-#include "BLI_linklist.h"
-#include "BLI_linklist_stack.h"
-#include "BLI_listbase.h"
#include "BLI_math.h"
-#include "BLI_math_color_blend.h"
-#include "BLI_memarena.h"
-#include "BLI_rand.h"
#include "BLI_task.h"
#include "BLI_utildefines.h"
-#include "atomic_ops.h"
#include "BLT_translation.h"
-#include "PIL_time.h"
-
#include "DNA_brush_types.h"
#include "DNA_customdata_types.h"
#include "DNA_listBase.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -42,44 +29,23 @@
#include "BKE_attribute.h"
#include "BKE_brush.h"
#include "BKE_ccg.h"
-#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_image.h"
-#include "BKE_kelvinlet.h"
-#include "BKE_key.h"
#include "BKE_layer.h"
-#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
-#include "BKE_mesh_fair.h"
-#include "BKE_mesh_mapping.h"
#include "BKE_mesh_mirror.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
-#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_paint.h"
-#include "BKE_particle.h"
#include "BKE_pbvh.h"
-#include "BKE_pointcache.h"
#include "BKE_report.h"
#include "BKE_scene.h"
-#include "BKE_screen.h"
-#include "BKE_subdiv_ccg.h"
-#include "BKE_subsurf.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
#include "IMB_colormanagement.h"
-#include "GPU_batch.h"
-#include "GPU_batch_presets.h"
-#include "GPU_immediate.h"
-#include "GPU_immediate_util.h"
-#include "GPU_matrix.h"
-#include "GPU_state.h"
-
#include "WM_api.h"
#include "WM_message.h"
#include "WM_toolsystem.h"
@@ -89,9 +55,6 @@
#include "ED_object.h"
#include "ED_screen.h"
#include "ED_sculpt.h"
-#include "ED_space_api.h"
-#include "ED_transform_snap_object_context.h"
-#include "ED_view3d.h"
#include "paint_intern.h"
#include "sculpt_intern.h"
@@ -103,7 +66,6 @@
#include "UI_resources.h"
#include "bmesh.h"
-#include "bmesh_tools.h"
#include <math.h>
#include <stdlib.h>
@@ -117,24 +79,33 @@ static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op))
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
- if (!ss) {
+ /* Do not allow in DynTopo just yet. */
+ if (!ss || (ss && ss->bm)) {
return OPERATOR_FINISHED;
}
SCULPT_vertex_random_access_ensure(ss);
BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
- MEM_SAFE_FREE(ss->persistent_base);
+ SculptAttributeParams params = {0};
+ params.permanent = true;
+
+ ss->attrs.persistent_co = BKE_sculpt_attribute_ensure(
+ ob, ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, SCULPT_ATTRIBUTE_NAME(persistent_co), &params);
+ ss->attrs.persistent_no = BKE_sculpt_attribute_ensure(
+ ob, ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, SCULPT_ATTRIBUTE_NAME(persistent_no), &params);
+ ss->attrs.persistent_disp = BKE_sculpt_attribute_ensure(
+ ob, ATTR_DOMAIN_POINT, CD_PROP_FLOAT, SCULPT_ATTRIBUTE_NAME(persistent_disp), &params);
const int totvert = SCULPT_vertex_count_get(ss);
- ss->persistent_base = MEM_mallocN(sizeof(SculptPersistentBase) * totvert,
- "layer persistent base");
for (int i = 0; i < totvert; i++) {
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
- copy_v3_v3(ss->persistent_base[i].co, SCULPT_vertex_co_get(ss, vertex));
- SCULPT_vertex_normal_get(ss, vertex, ss->persistent_base[i].no);
- ss->persistent_base[i].disp = 0.0f;
+ copy_v3_v3((float *)SCULPT_vertex_attr_get(vertex, ss->attrs.persistent_co),
+ SCULPT_vertex_co_get(ss, vertex));
+ SCULPT_vertex_normal_get(
+ ss, vertex, (float *)SCULPT_vertex_attr_get(vertex, ss->attrs.persistent_no));
+ (*(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.persistent_disp)) = 0.0f;
}
return OPERATOR_FINISHED;
@@ -300,7 +271,11 @@ static void sculpt_init_session(Main *bmain, Depsgraph *depsgraph, Scene *scene,
ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
ob->sculpt->mode_type = OB_MODE_SCULPT;
- BKE_sculpt_ensure_orig_mesh_data(ob);
+ /* Trigger evaluation of modifier stack to ensure
+ * multires modifier sets .runtime.ccg in
+ * the evaluated mesh.
+ */
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
@@ -348,7 +323,7 @@ void ED_object_sculptmode_enter_ex(Main *bmain,
BKE_report(
reports, RPT_WARNING, "Object has non-uniform scale, sculpting may be unpredictable");
}
- else if (is_negative_m4(ob->obmat)) {
+ else if (is_negative_m4(ob->object_to_world)) {
BKE_report(reports, RPT_WARNING, "Object has negative scale, sculpting may be unpredictable");
}
@@ -421,6 +396,7 @@ void ED_object_sculptmode_enter(struct bContext *C, Depsgraph *depsgraph, Report
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, false, reports);
}
@@ -473,6 +449,7 @@ void ED_object_sculptmode_exit(bContext *C, Depsgraph *depsgraph)
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
ED_object_sculptmode_exit_ex(bmain, depsgraph, scene, ob);
}
@@ -485,6 +462,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = scene->toolsettings;
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
const int mode_flag = OB_MODE_SCULPT;
const bool is_mode_set = (ob->mode & mode_flag) != 0;
@@ -986,6 +964,368 @@ static void SCULPT_OT_mask_by_color(wmOperatorType *ot)
1.0f);
}
+typedef enum {
+ AUTOMASK_BAKE_MIX,
+ AUTOMASK_BAKE_MULTIPLY,
+ AUTOMASK_BAKE_DIVIDE,
+ AUTOMASK_BAKE_ADD,
+ AUTOMASK_BAKE_SUBTRACT,
+} CavityBakeMixMode;
+
+typedef struct AutomaskBakeTaskData {
+ SculptSession *ss;
+ AutomaskingCache *automasking;
+ PBVHNode **nodes;
+ CavityBakeMixMode mode;
+ float factor;
+ Object *ob;
+} AutomaskBakeTaskData;
+
+static void sculpt_bake_cavity_exec_task_cb(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ AutomaskBakeTaskData *tdata = userdata;
+ SculptSession *ss = tdata->ss;
+ PBVHNode *node = tdata->nodes[n];
+ PBVHVertexIter vd;
+ const CavityBakeMixMode mode = tdata->mode;
+ const float factor = tdata->factor;
+
+ SCULPT_undo_push_node(tdata->ob, node, SCULPT_UNDO_MASK);
+
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(tdata->ob, ss, tdata->automasking, &automask_data, node);
+
+ BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
+ float automask = SCULPT_automasking_factor_get(
+ tdata->automasking, ss, vd.vertex, &automask_data);
+ float mask;
+
+ switch (mode) {
+ case AUTOMASK_BAKE_MIX:
+ mask = automask;
+ break;
+ case AUTOMASK_BAKE_MULTIPLY:
+ mask = *vd.mask * automask;
+ break;
+ break;
+ case AUTOMASK_BAKE_DIVIDE:
+ mask = automask > 0.00001f ? *vd.mask / automask : 0.0f;
+ break;
+ break;
+ case AUTOMASK_BAKE_ADD:
+ mask = *vd.mask + automask;
+ break;
+ case AUTOMASK_BAKE_SUBTRACT:
+ mask = *vd.mask - automask;
+ break;
+ }
+
+ mask = *vd.mask + (mask - *vd.mask) * factor;
+ CLAMP(mask, 0.0f, 1.0f);
+
+ *vd.mask = mask;
+ }
+ BKE_pbvh_vertex_iter_end;
+
+ BKE_pbvh_node_mark_update_mask(node);
+}
+
+static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op)
+{
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ Brush *brush = BKE_paint_brush(&sd->paint);
+
+ MultiresModifierData *mmd = BKE_sculpt_multires_active(CTX_data_scene(C), ob);
+ BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd);
+
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
+ SCULPT_vertex_random_access_ensure(ss);
+
+ SCULPT_undo_push_begin(ob, op);
+
+ CavityBakeMixMode mode = RNA_enum_get(op->ptr, "mix_mode");
+ float factor = RNA_float_get(op->ptr, "mix_factor");
+
+ PBVHNode **nodes;
+ int totnode;
+
+ BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+
+ AutomaskBakeTaskData tdata;
+
+ /* Set up automasking settings.
+ */
+ Sculpt sd2 = *sd;
+
+ /* Override cavity mask settings if use_automask_settings is false. */
+ if (!RNA_boolean_get(op->ptr, "use_automask_settings")) {
+ if (RNA_boolean_get(op->ptr, "invert")) {
+ sd2.automasking_flags = BRUSH_AUTOMASKING_CAVITY_INVERTED;
+ }
+ else {
+ sd2.automasking_flags = BRUSH_AUTOMASKING_CAVITY_NORMAL;
+ }
+
+ if (RNA_boolean_get(op->ptr, "use_curve")) {
+ sd2.automasking_flags |= BRUSH_AUTOMASKING_CAVITY_USE_CURVE;
+ }
+
+ sd2.automasking_cavity_blur_steps = RNA_int_get(op->ptr, "blur_steps");
+ sd2.automasking_cavity_factor = RNA_float_get(op->ptr, "factor");
+
+ sd2.automasking_cavity_curve = sd->automasking_cavity_curve_op;
+ }
+ else {
+ sd2.automasking_flags &= BRUSH_AUTOMASKING_CAVITY_ALL | BRUSH_AUTOMASKING_CAVITY_USE_CURVE;
+
+ /* Ensure cavity mask is actually enabled. */
+ if (!(sd2.automasking_flags & BRUSH_AUTOMASKING_CAVITY_ALL)) {
+ sd2.automasking_flags |= BRUSH_AUTOMASKING_CAVITY_NORMAL;
+ }
+ }
+
+ /* Create copy of brush with cleared automasking settings. */
+ Brush brush2 = *brush;
+ brush2.automasking_flags = 0;
+ brush2.automasking_boundary_edges_propagation_steps = 1;
+ brush2.automasking_cavity_curve = sd2.automasking_cavity_curve;
+
+ SCULPT_stroke_id_next(ob);
+
+ tdata.ob = ob;
+ tdata.mode = mode;
+ tdata.factor = factor;
+ tdata.ss = ss;
+ tdata.nodes = nodes;
+ tdata.automasking = SCULPT_automasking_cache_init(&sd2, &brush2, ob);
+
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+ BLI_task_parallel_range(0, totnode, &tdata, sculpt_bake_cavity_exec_task_cb, &settings);
+
+ MEM_SAFE_FREE(nodes);
+ SCULPT_automasking_cache_free(tdata.automasking);
+
+ BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateMask);
+ SCULPT_undo_push_end(ob);
+
+ SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
+ SCULPT_tag_update_overlays(C);
+
+ return OPERATOR_FINISHED;
+}
+
+static void cavity_bake_ui(bContext *C, wmOperator *op)
+{
+ uiLayout *layout = op->layout;
+ Scene *scene = CTX_data_scene(C);
+ Sculpt *sd = scene->toolsettings ? scene->toolsettings->sculpt : NULL;
+
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+ bool use_curve = false;
+
+ if (!sd || !RNA_boolean_get(op->ptr, "use_automask_settings")) {
+ uiItemR(layout, op->ptr, "mix_mode", 0, NULL, ICON_NONE);
+ uiItemR(layout, op->ptr, "mix_factor", 0, NULL, ICON_NONE);
+ uiItemR(layout, op->ptr, "use_automask_settings", 0, NULL, ICON_NONE);
+ uiItemR(layout, op->ptr, "factor", 0, NULL, ICON_NONE);
+ uiItemR(layout, op->ptr, "blur_steps", 0, NULL, ICON_NONE);
+ uiItemR(layout, op->ptr, "invert", 0, NULL, ICON_NONE);
+ uiItemR(layout, op->ptr, "use_curve", 0, NULL, ICON_NONE);
+
+ use_curve = RNA_boolean_get(op->ptr, "use_curve");
+ }
+ else {
+ PointerRNA sculpt_ptr;
+
+ RNA_pointer_create(&scene->id, &RNA_Sculpt, sd, &sculpt_ptr);
+ uiItemR(layout, op->ptr, "mix_mode", 0, NULL, ICON_NONE);
+ uiItemR(layout, op->ptr, "mix_factor", 0, NULL, ICON_NONE);
+ uiItemR(layout, op->ptr, "use_automask_settings", 0, NULL, ICON_NONE);
+
+ use_curve = false;
+ }
+
+ if (use_curve) {
+ PointerRNA sculpt_ptr;
+
+ const char *curve_prop;
+
+ if (RNA_boolean_get(op->ptr, "use_automask_settings")) {
+ curve_prop = "automasking_cavity_curve";
+ }
+ else {
+ curve_prop = "automasking_cavity_curve_op";
+ }
+
+ if (scene->toolsettings && scene->toolsettings->sculpt) {
+ RNA_pointer_create(&scene->id, &RNA_Sculpt, scene->toolsettings->sculpt, &sculpt_ptr);
+ uiTemplateCurveMapping(layout, &sculpt_ptr, curve_prop, 'v', false, false, false, false);
+ }
+ }
+}
+
+static void SCULPT_OT_mask_from_cavity(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Mask From Cavity";
+ ot->idname = "SCULPT_OT_mask_from_cavity";
+ ot->description = "Creates a mask based on the curvature of the surface";
+ ot->ui = cavity_bake_ui;
+
+ static EnumPropertyItem mix_modes[] = {
+ {AUTOMASK_BAKE_MIX, "MIX", ICON_NONE, "Mix", ""},
+ {AUTOMASK_BAKE_MULTIPLY, "MULTIPLY", ICON_NONE, "Multiply", ""},
+ {AUTOMASK_BAKE_DIVIDE, "DIVIDE", ICON_NONE, "Divide", ""},
+ {AUTOMASK_BAKE_ADD, "ADD", ICON_NONE, "Add", ""},
+ {AUTOMASK_BAKE_SUBTRACT, "SUBTRACT", ICON_NONE, "Subtract", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ /* api callbacks */
+ ot->exec = sculpt_bake_cavity_exec;
+ ot->poll = SCULPT_mode_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_enum(ot->srna, "mix_mode", mix_modes, AUTOMASK_BAKE_MIX, "Mode", "Mix mode");
+ RNA_def_float(ot->srna, "mix_factor", 1.0f, 0.0f, 5.0f, "Mix Factor", "", 0.0f, 1.0f);
+
+ RNA_def_boolean(ot->srna,
+ "use_automask_settings",
+ false,
+ "Use Automask Settings",
+ "Use default settings from Options panel in sculpt mode");
+
+ RNA_def_float(ot->srna,
+ "factor",
+ 0.5f,
+ 0.0f,
+ 5.0f,
+ "Cavity Factor",
+ "The contrast of the cavity mask",
+ 0.0f,
+ 1.0f);
+ RNA_def_int(ot->srna,
+ "blur_steps",
+ 2,
+ 0,
+ 25,
+ "Cavity Blur",
+ "The number of times the cavity mask is blurred",
+ 0,
+ 25);
+ RNA_def_boolean(ot->srna, "use_curve", false, "Use Curve", "");
+
+ RNA_def_boolean(ot->srna, "invert", false, "Cavity (Inverted)", "");
+}
+
+static int sculpt_reveal_all_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+
+ Mesh *mesh = BKE_object_get_original_mesh(ob);
+
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
+
+ if (!ss->pbvh) {
+ return OPERATOR_CANCELLED;
+ }
+
+ PBVHNode **nodes;
+ int totnode;
+ bool with_bmesh = BKE_pbvh_type(ss->pbvh) == PBVH_BMESH;
+
+ BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+
+ if (!totnode) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Propagate face hide state to verts for undo. */
+ SCULPT_visibility_sync_all_from_faces(ob);
+
+ SCULPT_undo_push_begin(ob, op);
+
+ for (int i = 0; i < totnode; i++) {
+ BKE_pbvh_node_mark_update_visibility(nodes[i]);
+
+ if (!with_bmesh) {
+ SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_HIDDEN);
+ }
+ }
+
+ if (!with_bmesh) {
+ /* As an optimization, free the hide attribute when making all geometry visible. This allows
+ * reduced memory usage without manually clearing it later, and allows sculpt operations to
+ * avoid checking element's hide status. */
+ CustomData_free_layer_named(&mesh->pdata, ".hide_poly", mesh->totpoly);
+ ss->hide_poly = NULL;
+ }
+ else {
+ SCULPT_undo_push_node(ob, nodes[0], SCULPT_UNDO_HIDDEN);
+
+ BMIter iter;
+ BMFace *f;
+ BMVert *v;
+ const int cd_mask = CustomData_get_offset(&ss->bm->vdata, CD_PAINT_MASK);
+
+ BM_ITER_MESH (v, &iter, ss->bm, BM_VERTS_OF_MESH) {
+ BM_log_vert_before_modified(ss->bm_log, v, cd_mask);
+ }
+ BM_ITER_MESH (f, &iter, ss->bm, BM_FACES_OF_MESH) {
+ BM_log_face_modified(ss->bm_log, f);
+ }
+
+ SCULPT_face_visibility_all_set(ss, true);
+ }
+
+ SCULPT_visibility_sync_all_from_faces(ob);
+
+ /* NOTE: #SCULPT_visibility_sync_all_from_faces may have deleted
+ * `pbvh->hide_vert` if hide_poly did not exist, which is why
+ * we call #BKE_pbvh_update_hide_attributes_from_mesh here instead of
+ * after #CustomData_free_layer_named above. */
+ if (!with_bmesh) {
+ BKE_pbvh_update_hide_attributes_from_mesh(ss->pbvh);
+ }
+
+ BKE_pbvh_update_visibility(ss->pbvh);
+
+ SCULPT_undo_push_end(ob);
+ MEM_SAFE_FREE(nodes);
+
+ SCULPT_tag_update_overlays(C);
+ DEG_id_tag_update(&ob->id, ID_RECALC_SHADING);
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return OPERATOR_FINISHED;
+}
+
+static void SCULPT_OT_reveal_all(wmOperatorType *ot)
+{
+ /* Identifiers. */
+ ot->name = "Reveal All";
+ ot->idname = "SCULPT_OT_reveal_all";
+ ot->description = "Unhide all geometry";
+
+ /* Api callbacks. */
+ ot->exec = sculpt_reveal_all_exec;
+ ot->poll = SCULPT_mode_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
void ED_operatortypes_sculpt(void)
{
WM_operatortype_append(SCULPT_OT_brush_stroke);
@@ -999,7 +1339,6 @@ void ED_operatortypes_sculpt(void)
WM_operatortype_append(SCULPT_OT_set_detail_size);
WM_operatortype_append(SCULPT_OT_mesh_filter);
WM_operatortype_append(SCULPT_OT_mask_filter);
- WM_operatortype_append(SCULPT_OT_dirty_mask);
WM_operatortype_append(SCULPT_OT_mask_expand);
WM_operatortype_append(SCULPT_OT_set_pivot_position);
WM_operatortype_append(SCULPT_OT_face_sets_create);
@@ -1021,4 +1360,6 @@ void ED_operatortypes_sculpt(void)
WM_operatortype_append(SCULPT_OT_mask_init);
WM_operatortype_append(SCULPT_OT_expand);
+ WM_operatortype_append(SCULPT_OT_mask_from_cavity);
+ WM_operatortype_append(SCULPT_OT_reveal_all);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
index c494c71f1eb..ee716d1107a 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
@@ -7,46 +7,24 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_hash.h"
#include "BLI_math.h"
#include "BLI_math_color_blend.h"
#include "BLI_task.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_brush.h"
#include "BKE_colorband.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_mesh.h"
-#include "BKE_mesh_mapping.h"
-#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
-#include "BKE_scene.h"
-
-#include "DEG_depsgraph.h"
#include "IMB_colormanagement.h"
-#include "WM_api.h"
-#include "WM_message.h"
-#include "WM_toolsystem.h"
-#include "WM_types.h"
-
-#include "ED_object.h"
-#include "ED_screen.h"
-#include "ED_sculpt.h"
-#include "paint_intern.h"
#include "sculpt_intern.h"
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "UI_interface.h"
-
#include "IMB_imbuf.h"
#include "bmesh.h"
@@ -70,10 +48,17 @@ static void do_color_smooth_task_cb_exec(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
+
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -82,7 +67,8 @@ static void do_color_smooth_task_cb_exec(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
float smooth_color[4];
SCULPT_neighbor_color_average(ss, smooth_color, vd.vertex);
@@ -125,6 +111,10 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
IMB_colormanagement_srgb_to_scene_linear_v3(brush_color, brush_color);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
if (brush->flag & BRUSH_USE_GRADIENT) {
switch (brush->gradient_stroke_mode) {
case BRUSH_GRADIENT_PRESSURE:
@@ -161,6 +151,8 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -169,7 +161,8 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
/* Density. */
float noise = 1.0f;
@@ -195,8 +188,11 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
paint_color, paint_color, wet_mix_color, ss->cache->paint_brush.wet_mix);
blend_color_mix_float(color_buffer->color[vd.i], color_buffer->color[vd.i], paint_color);
- /* Final mix over the original color using brush alpha. */
- mul_v4_v4fl(buffer_color, color_buffer->color[vd.i], brush->alpha);
+ /* Final mix over the original color using brush alpha. We apply auto-making again
+ * at this point to avoid washing out non-binary masking modes like cavity masking. */
+ float automasking = SCULPT_automasking_factor_get(
+ ss->cache->automasking, ss, vd.vertex, &automask_data);
+ mul_v4_v4fl(buffer_color, color_buffer->color[vd.i], brush->alpha * automasking);
float col[4];
SCULPT_vertex_color_get(ss, vd.vertex, col);
@@ -402,10 +398,17 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata,
sub_v3_v3v3(brush_delta, ss->cache->location, ss->cache->last_location);
}
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
+
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -414,7 +417,8 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
float current_disp[3];
float current_disp_norm[3];
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
index 8a3a3fe7adc..d3b3100458d 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
@@ -2,13 +2,9 @@
* Copyright 2022 Blender Foundation. All rights reserved. */
#include "DNA_image_types.h"
-#include "DNA_material_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "ED_paint.h"
-#include "ED_uvedit.h"
#include "BLI_math.h"
#include "BLI_math_color_blend.h"
@@ -19,14 +15,11 @@
#include "BKE_brush.h"
#include "BKE_image_wrappers.hh"
-#include "BKE_material.h"
#include "BKE_pbvh.h"
#include "BKE_pbvh_pixels.hh"
#include "bmesh.h"
-#include "NOD_shader.h"
-
#include "sculpt_intern.h"
namespace blender::ed::sculpt_paint::paint::image {
@@ -153,7 +146,10 @@ template<typename ImageBuffer> class PaintingKernel {
init_brush_test();
}
- bool paint(const Triangles &triangles, const PackedPixelRow &pixel_row, ImBuf *image_buffer)
+ bool paint(const Triangles &triangles,
+ const PackedPixelRow &pixel_row,
+ ImBuf *image_buffer,
+ AutomaskingNodeData *automask_data)
{
image_accessor.set_image_position(image_buffer, pixel_row.start_image_coordinate);
const TrianglePaintInput triangle = triangles.get_paint_input(pixel_row.triangle_index);
@@ -171,6 +167,7 @@ template<typename ImageBuffer> class PaintingKernel {
const float3 normal(0.0f, 0.0f, 0.0f);
const float3 face_normal(0.0f, 0.0f, 0.0f);
const float mask = 0.0f;
+
const float falloff_strength = SCULPT_brush_strength_factor(
ss,
brush,
@@ -180,7 +177,8 @@ template<typename ImageBuffer> class PaintingKernel {
face_normal,
mask,
BKE_pbvh_make_vref(PBVH_REF_NONE),
- thread_id);
+ thread_id,
+ automask_data);
float4 paint_color = brush_color * falloff_strength * brush_strength;
float4 buffer_color;
blend_color_mix_float(buffer_color, color, paint_color);
@@ -321,6 +319,9 @@ static void do_paint_pixels(void *__restrict userdata,
PaintingKernel<ImageBufferFloat4> kernel_float4(ss, brush, thread_id, mvert);
PaintingKernel<ImageBufferByte4> kernel_byte4(ss, brush, thread_id, mvert);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
ImageUser image_user = *data->image_data.image_user;
bool pixels_updated = false;
for (UDIMTilePixels &tile_data : node_data.tiles) {
@@ -347,10 +348,12 @@ static void do_paint_pixels(void *__restrict userdata,
}
bool pixels_painted = false;
if (image_buffer->rect_float != nullptr) {
- pixels_painted = kernel_float4.paint(node_data.triangles, pixel_row, image_buffer);
+ pixels_painted = kernel_float4.paint(
+ node_data.triangles, pixel_row, image_buffer, &automask_data);
}
else {
- pixels_painted = kernel_byte4.paint(node_data.triangles, pixel_row, image_buffer);
+ pixels_painted = kernel_byte4.paint(
+ node_data.triangles, pixel_row, image_buffer, &automask_data);
}
if (pixels_painted) {
@@ -421,7 +424,7 @@ static void push_undo(const NodeData &node_data,
static void do_push_undo_tile(void *__restrict userdata,
const int n,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
TexturePaintingUserData *data = static_cast<TexturePaintingUserData *>(userdata);
PBVHNode *node = data->nodes[n];
@@ -450,7 +453,7 @@ static void do_push_undo_tile(void *__restrict userdata,
static void do_mark_dirty_regions(void *__restrict userdata,
const int n,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
TexturePaintingUserData *data = static_cast<TexturePaintingUserData *>(userdata);
PBVHNode *node = data->nodes[n];
diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c
index d1418c8dc35..5f671c1f0e1 100644
--- a/source/blender/editors/sculpt_paint/sculpt_pose.c
+++ b/source/blender/editors/sculpt_paint/sculpt_pose.c
@@ -7,12 +7,10 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_task.h"
#include "DNA_brush_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -20,13 +18,8 @@
#include "BKE_ccg.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_mesh.h"
-#include "BKE_multires.h"
-#include "BKE_node.h"
-#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
-#include "BKE_scene.h"
#include "paint_intern.h"
#include "sculpt_intern.h"
@@ -157,9 +150,13 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata,
SculptOrigVertData orig_data;
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
float total_disp[3];
zero_v3(total_disp);
@@ -182,7 +179,8 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata,
/* Apply the vertex mask to the displacement. */
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex);
+ const float automask = SCULPT_automasking_factor_get(
+ ss->cache->automasking, ss, vd.vertex, &automask_data);
mul_v3_fl(disp, mask * automask);
/* Accumulate the displacement. */
diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c
index 2ef3c28ba0c..09b1c69da45 100644
--- a/source/blender/editors/sculpt_paint/sculpt_smooth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c
@@ -7,40 +7,18 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
-#include "BLI_hash.h"
#include "BLI_math.h"
#include "BLI_task.h"
#include "DNA_brush_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "BKE_brush.h"
#include "BKE_context.h"
-#include "BKE_mesh.h"
-#include "BKE_mesh_mapping.h"
-#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
-#include "BKE_scene.h"
-#include "DEG_depsgraph.h"
-
-#include "WM_api.h"
-#include "WM_message.h"
-#include "WM_toolsystem.h"
-#include "WM_types.h"
-
-#include "ED_object.h"
-#include "ED_screen.h"
-#include "ED_sculpt.h"
-#include "paint_intern.h"
#include "sculpt_intern.h"
-#include "RNA_access.h"
-#include "RNA_define.h"
-
#include "bmesh.h"
#include <math.h>
@@ -217,11 +195,17 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -230,7 +214,8 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
float disp[3];
madd_v3_v3v3fl(disp, vd.co, ss->cache->detail_directions[vd.index], fade);
@@ -300,11 +285,17 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
+
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = bstrength * SCULPT_brush_strength_factor(
ss,
brush,
@@ -314,7 +305,8 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata,
vd.fno,
smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f),
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
if (smooth_mask) {
float val = SCULPT_neighbor_mask_average(ss, vd.vertex) - *vd.mask;
val *= fade * bstrength;
@@ -470,12 +462,18 @@ static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex(
const int thread_id = BLI_task_parallel_thread_id(tls);
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
+
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -484,7 +482,8 @@ static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex(
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
float disp[3];
SCULPT_surface_smooth_laplacian_step(
@@ -512,11 +511,17 @@ static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex(
SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
}
+
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
+
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -525,7 +530,8 @@ static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex(
vd.fno,
vd.mask ? *vd.mask : 0.0f,
vd.vertex,
- thread_id);
+ thread_id,
+ &automask_data);
SCULPT_surface_smooth_displace_step(
ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.vertex, beta, fade);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.c b/source/blender/editors/sculpt_paint/sculpt_transform.c
index dfaa0bd4daa..0463e8adbaf 100644
--- a/source/blender/editors/sculpt_paint/sculpt_transform.c
+++ b/source/blender/editors/sculpt_paint/sculpt_transform.c
@@ -7,31 +7,22 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_task.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_kelvinlet.h"
-#include "BKE_mesh.h"
-#include "BKE_mesh_mapping.h"
-#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
-#include "BKE_scene.h"
#include "DEG_depsgraph.h"
#include "WM_api.h"
-#include "WM_message.h"
-#include "WM_toolsystem.h"
#include "WM_types.h"
-#include "ED_object.h"
#include "ED_screen.h"
#include "ED_sculpt.h"
#include "ED_view3d.h"
@@ -46,7 +37,10 @@
#include <math.h>
#include <stdlib.h>
-void ED_sculpt_init_transform(struct bContext *C, Object *ob, const char *undo_name)
+void ED_sculpt_init_transform(struct bContext *C,
+ Object *ob,
+ const int mval[2],
+ const char *undo_name)
{
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
SculptSession *ss = ob->sculpt;
@@ -66,7 +60,8 @@ void ED_sculpt_init_transform(struct bContext *C, Object *ob, const char *undo_n
ss->pivot_rot[3] = 1.0f;
SCULPT_vertex_random_access_ensure(ss);
- SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS);
+
+ SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS, mval, 5.0);
if (sd->transform_mode == SCULPT_TRANSFORM_MODE_RADIUS_ELASTIC) {
ss->filter_cache->transform_displacement_mode = SCULPT_TRANSFORM_DISPLACEMENT_INCREMENTAL;
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index af94cad88f3..eb92c865f18 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -56,7 +56,6 @@
#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
-#include "BKE_mesh_mapping.h"
#include "BKE_mesh_runtime.h"
#include "BKE_multires.h"
#include "BKE_object.h"
@@ -82,6 +81,9 @@
#include "bmesh.h"
#include "sculpt_intern.h"
+/* Uncomment to print the undo stack in the console on push/undo/redo. */
+//#define SCULPT_UNDO_DEBUG
+
/* Implementation of undo system for objects in sculpt mode.
*
* Each undo step in sculpt mode consists of list of nodes, each node contains:
@@ -148,11 +150,130 @@ typedef struct SculptUndoStep {
SculptAttrRef active_color_end;
bContext *C;
+
+#ifdef SCULPT_UNDO_DEBUG
+ int id;
+#endif
} SculptUndoStep;
static UndoSculpt *sculpt_undo_get_nodes(void);
static bool sculpt_attribute_ref_equals(SculptAttrRef *a, SculptAttrRef *b);
static void sculpt_save_active_attribute(Object *ob, SculptAttrRef *attr);
+static UndoSculpt *sculpt_undosys_step_get_nodes(UndoStep *us_p);
+
+#ifdef SCULPT_UNDO_DEBUG
+# ifdef _
+# undef _
+# endif
+# define _(type) \
+ case type: \
+ return #type;
+static char *undo_type_to_str(int type)
+{
+ switch (type) {
+ _(SCULPT_UNDO_DYNTOPO_BEGIN)
+ _(SCULPT_UNDO_DYNTOPO_END)
+ _(SCULPT_UNDO_COORDS)
+ _(SCULPT_UNDO_GEOMETRY)
+ _(SCULPT_UNDO_DYNTOPO_SYMMETRIZE)
+ _(SCULPT_UNDO_FACE_SETS)
+ _(SCULPT_UNDO_HIDDEN)
+ _(SCULPT_UNDO_MASK)
+ _(SCULPT_UNDO_COLOR)
+ default:
+ return "unknown node type";
+ }
+}
+# undef _
+
+static int nodeidgen = 1;
+
+static void print_sculpt_node(Object *ob, SculptUndoNode *node)
+{
+ printf(" %s:%s {applied=%d}\n", undo_type_to_str(node->type), node->idname, node->applied);
+
+ if (node->bm_entry) {
+ BM_log_print_entry(ob->sculpt ? ob->sculpt->bm : NULL, node->bm_entry);
+ }
+}
+
+static void print_sculpt_undo_step(Object *ob, UndoStep *us, UndoStep *active, int i)
+{
+ SculptUndoNode *node;
+
+ if (us->type != BKE_UNDOSYS_TYPE_SCULPT) {
+ printf("%d %s (non-sculpt): '%s', type:%s, use_memfile_step:%s\n",
+ i,
+ us == active ? "->" : " ",
+ us->name,
+ us->type->name,
+ us->use_memfile_step ? "true" : "false");
+ return;
+ }
+
+ int id = -1;
+
+ SculptUndoStep *su = (SculptUndoStep *)us;
+ if (!su->id) {
+ su->id = nodeidgen++;
+ }
+
+ id = su->id;
+
+ printf("id=%d %s %d %s (use_memfile_step=%s)\n",
+ id,
+ us == active ? "->" : " ",
+ i,
+ us->name,
+ us->use_memfile_step ? "true" : "false");
+
+ if (us->type == BKE_UNDOSYS_TYPE_SCULPT) {
+ UndoSculpt *usculpt = sculpt_undosys_step_get_nodes(us);
+
+ for (node = usculpt->nodes.first; node; node = node->next) {
+ print_sculpt_node(ob, node);
+ }
+ }
+}
+void sculpt_undo_print_nodes(Object *ob, void *active)
+{
+
+ printf("=================== Sculpt undo steps ==============\n");
+
+ UndoStack *ustack = ED_undo_stack_get();
+ UndoStep *us = ustack->steps.first;
+ if (active == NULL) {
+ active = ustack->step_active;
+ }
+
+ if (!us) {
+ return;
+ }
+
+ printf("\n");
+ if (ustack->step_init) {
+ printf("===Undo initialization stepB===\n");
+ print_sculpt_undo_step(ob, ustack->step_init, active, -1);
+ printf("===============\n");
+ }
+
+ int i = 0, act_i = -1;
+ for (; us; us = us->next, i++) {
+ if (active == us) {
+ act_i = i;
+ }
+
+ print_sculpt_undo_step(ob, us, active, i);
+ }
+
+ if (ustack->step_active) {
+ printf("\n\n==Active step:==\n");
+ print_sculpt_undo_step(ob, ustack->step_active, active, act_i);
+ }
+}
+#else
+# define sculpt_undo_print_nodes(ob, active) while (0)
+#endif
static void update_cb(PBVHNode *node, void *rebuild)
{
@@ -253,7 +374,9 @@ static bool sculpt_undo_restore_deformed(
static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, SculptUndoNode *unode)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
SculptSession *ss = ob->sculpt;
SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
@@ -365,7 +488,9 @@ static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, Sculpt
static bool sculpt_undo_restore_hidden(bContext *C, SculptUndoNode *unode, bool *modified_vertices)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
SculptSession *ss = ob->sculpt;
SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
@@ -395,7 +520,9 @@ static bool sculpt_undo_restore_hidden(bContext *C, SculptUndoNode *unode, bool
static bool sculpt_undo_restore_color(bContext *C, SculptUndoNode *unode, bool *modified_vertices)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
SculptSession *ss = ob->sculpt;
@@ -427,7 +554,9 @@ static bool sculpt_undo_restore_color(bContext *C, SculptUndoNode *unode, bool *
static bool sculpt_undo_restore_mask(bContext *C, SculptUndoNode *unode, bool *modified_vertices)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
SculptSession *ss = ob->sculpt;
SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
@@ -473,11 +602,18 @@ static bool sculpt_undo_restore_mask(bContext *C, SculptUndoNode *unode, bool *m
static bool sculpt_undo_restore_face_sets(bContext *C, SculptUndoNode *unode)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
Mesh *me = BKE_object_get_original_mesh(ob);
- int *face_sets = CustomData_add_layer(
- &me->pdata, CD_SCULPT_FACE_SETS, CD_CONSTRUCT, NULL, me->totpoly);
+
+ int *face_sets = CustomData_get_layer_named(&me->pdata, CD_PROP_INT32, ".sculpt_face_set");
+ if (!face_sets) {
+ face_sets = CustomData_add_layer_named(
+ &me->pdata, CD_PROP_INT32, CD_CONSTRUCT, NULL, me->totpoly, ".sculpt_face_set");
+ }
+
for (int i = 0; i < me->totpoly; i++) {
SWAP(int, face_sets[i], unode->face_sets[i]);
}
@@ -537,7 +673,7 @@ static void sculpt_undo_bmesh_enable(Object *ob, SculptUndoNode *unode)
.use_toolflags = false,
}));
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. */
@@ -721,7 +857,8 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
SculptSession *ss = ob->sculpt;
SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
@@ -729,8 +866,13 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
bool update = false, rebuild = false, update_mask = false, update_visibility = false;
bool need_mask = false;
bool need_refine_subdiv = false;
+ bool clear_automask_cache = false;
for (unode = lb->first; unode; unode = unode->next) {
+ if (!ELEM(unode->type, SCULPT_UNDO_COLOR, SCULPT_UNDO_MASK)) {
+ clear_automask_cache = true;
+ }
+
/* Restore pivot. */
copy_v3_v3(ss->pivot_pos, unode->pivot_pos);
copy_v3_v3(ss->pivot_rot, unode->pivot_rot);
@@ -744,6 +886,10 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
}
}
+ if (clear_automask_cache) {
+ ss->last_automasking_settings_hash = 0;
+ }
+
DEG_id_tag_update(&ob->id, ID_RECALC_SHADING);
if (lb->first) {
@@ -756,7 +902,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, need_mask, false);
- SCULPT_visibility_sync_all_face_sets_to_verts(ob);
+ SCULPT_visibility_sync_all_from_faces(ob);
BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility);
@@ -765,7 +911,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
}
DEG_id_tag_update(&ob->id, ID_RECALC_SHADING);
- if (!BKE_sculptsession_use_pbvh_draw(ob, v3d)) {
+ if (!BKE_sculptsession_use_pbvh_draw(ob, rv3d)) {
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
}
@@ -912,7 +1058,6 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
}
if (update_visibility) {
- SCULPT_visibility_sync_all_vertex_to_face_sets(ss);
BKE_pbvh_update_visibility(ss->pbvh);
}
@@ -925,7 +1070,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
}
}
- tag_update |= ID_REAL_USERS(ob->data) > 1 || !BKE_sculptsession_use_pbvh_draw(ob, v3d) ||
+ tag_update |= ID_REAL_USERS(ob->data) > 1 || !BKE_sculptsession_use_pbvh_draw(ob, rv3d) ||
ss->shapekey_active || ss->deform_modifiers_active;
if (tag_update) {
@@ -1354,7 +1499,7 @@ static SculptUndoNode *sculpt_undo_face_sets_push(Object *ob, SculptUndoType typ
unode->face_sets = MEM_callocN(me->totpoly * sizeof(int), "sculpt face sets");
- const int *face_sets = CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS);
+ const int *face_sets = CustomData_get_layer_named(&me->pdata, CD_PROP_INT32, ".sculpt_face_set");
if (face_sets) {
for (int i = 0; i < me->totpoly; i++) {
unode->face_sets[i] = face_sets[i];
@@ -1645,6 +1790,7 @@ void SCULPT_undo_push_end_ex(struct Object *ob, const bool use_nested_undo)
ustack, BKE_UNDOSYS_TYPE_SCULPT);
sculpt_save_active_attribute(ob, &us->active_color_end);
+ sculpt_undo_print_nodes(ob, NULL);
}
/* -------------------------------------------------------------------- */
@@ -1744,6 +1890,8 @@ static void sculpt_undosys_step_decode_undo_impl(struct bContext *C,
sculpt_undo_restore_list(C, depsgraph, &us->data.nodes);
us->step.is_applied = false;
+
+ sculpt_undo_print_nodes(CTX_data_active_object(C), NULL);
}
static void sculpt_undosys_step_decode_redo_impl(struct bContext *C,
@@ -1754,6 +1902,8 @@ static void sculpt_undosys_step_decode_redo_impl(struct bContext *C,
sculpt_undo_restore_list(C, depsgraph, &us->data.nodes);
us->step.is_applied = true;
+
+ sculpt_undo_print_nodes(CTX_data_active_object(C), NULL);
}
static void sculpt_undosys_step_decode_undo(struct bContext *C,
@@ -1823,6 +1973,7 @@ static void sculpt_undosys_step_decode(
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ob && (ob->type == OB_MESH)) {
if (ob->mode & (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT)) {
diff --git a/source/blender/editors/space_action/CMakeLists.txt b/source/blender/editors/space_action/CMakeLists.txt
index b9e27c4de49..3ec814ada48 100644
--- a/source/blender/editors/space_action/CMakeLists.txt
+++ b/source/blender/editors/space_action/CMakeLists.txt
@@ -4,6 +4,7 @@ set(INC
../include
../../blenkernel
../../blenlib
+ ../../blenloader
../../blentranslation
../../depsgraph
../../gpu
@@ -11,6 +12,9 @@ set(INC
../../makesrna
../../windowmanager
../../../../intern/guardedalloc
+
+ # dna_type_offsets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
# RNA_prototypes.h
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
@@ -35,5 +39,5 @@ set(LIB
blender_add_lib(bf_editor_space_action "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
-# RNA_prototypes.h
+# RNA_prototypes.h dna_type_offsets.h
add_dependencies(bf_editor_space_action bf_rna)
diff --git a/source/blender/editors/space_action/action_data.c b/source/blender/editors/space_action/action_data.c
index 8f97a58451e..79047b171ef 100644
--- a/source/blender/editors/space_action/action_data.c
+++ b/source/blender/editors/space_action/action_data.c
@@ -169,7 +169,7 @@ static bool action_new_poll(bContext *C)
SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
Object *ob = CTX_data_active_object(C);
- /* For now, actions are only for the active object, and on object and shapekey levels... */
+ /* For now, actions are only for the active object, and on object and shape-key levels... */
if (saction->mode == SACTCONT_ACTION) {
/* XXX: This assumes that actions are assigned to the active object in this mode */
if (ob) {
@@ -460,7 +460,8 @@ static bool action_stash_create_poll(bContext *C)
Scene *scene = CTX_data_scene(C);
if (!(scene->flag & SCE_NLA_EDIT_ON)) {
- /* For now, actions are only for the active object, and on object and shapekey levels... */
+ /* For now, actions are only for the active object, and on object and shape-key levels...
+ */
return ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY);
}
}
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index eb56c6c4b54..343975919e2 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -104,7 +104,7 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region)
UI_block_draw(C, block);
}
- /* free tempolary channels */
+ /* Free temporary channels. */
ANIM_animdata_freelist(&anim_data);
}
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index 6d880f338f6..0803c5dc575 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -1326,7 +1326,7 @@ static int actkeys_expo_exec(bContext *C, wmOperator *op)
void ACTION_OT_extrapolation_type(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Set Keyframe Extrapolation";
+ ot->name = "Set F-Curve Extrapolation";
ot->idname = "ACTION_OT_extrapolation_type";
ot->description = "Set extrapolation mode for selected F-Curves";
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index ed9d86e1a4e..a425026a1ef 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -322,7 +322,7 @@ static int actkeys_deselectall_exec(bContext *C, wmOperator *op)
/* set notifier that keyframe selection have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- if (ac.datatype == ANIMCONT_GPENCIL) {
+ if (ANIM_animdata_can_have_greasepencil(ac.datatype)) {
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
}
return OPERATOR_FINISHED;
@@ -449,7 +449,7 @@ static void box_select_action(bAnimContext *ac, const rcti rect, short mode, sho
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* Get beztriple editing/validation funcs. */
+ /* Get beztriple editing/validation functions. */
sel_data.select_cb = ANIM_editkeyframes_select(selectmode);
if (ELEM(mode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS)) {
@@ -563,7 +563,7 @@ static int actkeys_box_select_exec(bContext *C, wmOperator *op)
/* set notifier that keyframe selection have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- if (ac.datatype == ANIMCONT_GPENCIL) {
+ if (ANIM_animdata_can_have_greasepencil(ac.datatype)) {
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
}
return OPERATOR_FINISHED;
@@ -585,7 +585,7 @@ void ACTION_OT_select_box(wmOperatorType *ot)
ot->poll = ED_operator_action_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_UNDO;
/* rna */
ot->prop = RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", "");
@@ -693,7 +693,7 @@ static void region_select_action_keys(
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* Get beztriple editing/validation funcs. */
+ /* Get beztriple editing/validation functions. */
sel_data.select_cb = ANIM_editkeyframes_select(selectmode);
sel_data.ok_cb = ANIM_editkeyframes_ok(mode);
@@ -800,7 +800,7 @@ static int actkeys_lassoselect_exec(bContext *C, wmOperator *op)
/* send notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- if (ac.datatype == ANIMCONT_GPENCIL) {
+ if (ANIM_animdata_can_have_greasepencil(ac.datatype)) {
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
}
return OPERATOR_FINISHED;
@@ -868,7 +868,7 @@ static int action_circle_select_exec(bContext *C, wmOperator *op)
/* send notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- if (ac.datatype == ANIMCONT_GPENCIL) {
+ if (ANIM_animdata_can_have_greasepencil(ac.datatype)) {
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
}
return OPERATOR_FINISHED;
@@ -936,7 +936,7 @@ static void markers_selectkeys_between(bAnimContext *ac)
min -= 0.5f;
max += 0.5f;
- /* get editing funcs + data */
+ /* Get editing functions + data. */
ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
select_cb = ANIM_editkeyframes_select(SELECT_ADD);
@@ -1107,7 +1107,7 @@ static int actkeys_columnselect_exec(bContext *C, wmOperator *op)
/* set notifier that keyframe selection have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- if (ac.datatype == ANIMCONT_GPENCIL) {
+ if (ANIM_animdata_can_have_greasepencil(ac.datatype)) {
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
}
return OPERATOR_FINISHED;
@@ -1129,6 +1129,7 @@ void ACTION_OT_select_column(wmOperatorType *ot)
/* props */
ot->prop = RNA_def_enum(ot->srna, "mode", prop_column_select_types, 0, "Mode", "");
+ RNA_def_property_flag(ot->prop, PROP_HIDDEN);
}
/* ******************** Select Linked Operator *********************** */
@@ -1169,7 +1170,7 @@ static int actkeys_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
/* set notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- if (ac.datatype == ANIMCONT_GPENCIL) {
+ if (ANIM_animdata_can_have_greasepencil(ac.datatype)) {
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
}
return OPERATOR_FINISHED;
@@ -1255,7 +1256,7 @@ static int actkeys_select_more_exec(bContext *C, wmOperator *UNUSED(op))
/* set notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- if (ac.datatype == ANIMCONT_GPENCIL) {
+ if (ANIM_animdata_can_have_greasepencil(ac.datatype)) {
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
}
return OPERATOR_FINISHED;
@@ -1292,7 +1293,7 @@ static int actkeys_select_less_exec(bContext *C, wmOperator *UNUSED(op))
/* set notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- if (ac.datatype == ANIMCONT_GPENCIL) {
+ if (ANIM_animdata_can_have_greasepencil(ac.datatype)) {
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
}
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 98782ca15a8..2f22121f7de 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -42,6 +42,8 @@
#include "ED_space_api.h"
#include "ED_time_scrub_ui.h"
+#include "BLO_read_write.h"
+
#include "action_intern.h" /* own include */
/* ******************** default callbacks for action space ***************** */
@@ -834,6 +836,30 @@ static void action_space_subtype_item_extend(bContext *UNUSED(C),
RNA_enum_items_add(item, totitem, rna_enum_space_action_mode_items);
}
+static void action_blend_read_data(BlendDataReader *UNUSED(reader), SpaceLink *sl)
+{
+ SpaceAction *saction = (SpaceAction *)sl;
+ memset(&saction->runtime, 0x0, sizeof(saction->runtime));
+}
+
+static void action_blend_read_lib(BlendLibReader *reader, ID *parent_id, SpaceLink *sl)
+{
+ SpaceAction *saction = (SpaceAction *)sl;
+ bDopeSheet *ads = &saction->ads;
+
+ if (ads) {
+ BLO_read_id_address(reader, parent_id->lib, &ads->source);
+ BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp);
+ }
+
+ BLO_read_id_address(reader, parent_id->lib, &saction->action);
+}
+
+static void action_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ BLO_write_struct(writer, SpaceAction, sl);
+}
+
void ED_spacetype_action(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype action");
@@ -854,6 +880,9 @@ void ED_spacetype_action(void)
st->space_subtype_item_extend = action_space_subtype_item_extend;
st->space_subtype_get = action_space_subtype_get;
st->space_subtype_set = action_space_subtype_set;
+ st->blend_read_data = action_blend_read_data;
+ st->blend_read_lib = action_blend_read_lib;
+ st->blend_write = action_blend_write;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype action region");
@@ -905,5 +934,8 @@ void ED_spacetype_action(void)
action_buttons_register(art);
+ art = ED_area_type_hud(st->spaceid);
+ BLI_addhead(&st->regiontypes, art);
+
BKE_spacetype_register(st);
}
diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt
index d0ad510f5cf..53a00b6d70b 100644
--- a/source/blender/editors/space_buttons/CMakeLists.txt
+++ b/source/blender/editors/space_buttons/CMakeLists.txt
@@ -4,6 +4,7 @@ set(INC
../include
../../blenkernel
../../blenlib
+ ../../blenloader
../../blentranslation
../../gpu
../../makesdna
@@ -11,6 +12,9 @@ set(INC
../../windowmanager
../../../../intern/guardedalloc
../../bmesh
+
+ # dna_type_offsets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
# RNA_prototypes.h
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
@@ -39,5 +43,5 @@ endif()
blender_add_lib(bf_editor_space_buttons "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
-# RNA_prototypes.h
+# RNA_prototypes.h dna_type_offsets.h
add_dependencies(bf_editor_space_buttons bf_rna)
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 5f535cbccd1..c5f457b3fd8 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -155,7 +155,8 @@ static bool buttons_context_path_collection(const bContext *C,
/* if we have a view layer, use the view layer's active collection */
if (buttons_context_path_view_layer(path, window)) {
ViewLayer *view_layer = path->ptr[path->len - 1].data;
- Collection *c = view_layer->active_collection->collection;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Collection *c = BKE_view_layer_active_collection_get(view_layer)->collection;
/* Do not show collection tab for master collection. */
if (c == scene->master_collection) {
@@ -209,7 +210,7 @@ static bool buttons_context_path_object(ButsContextPath *path)
}
ViewLayer *view_layer = ptr->data;
- Object *ob = (view_layer->basact) ? view_layer->basact->object : NULL;
+ Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ob) {
RNA_id_pointer_create(&ob->id, &path->ptr[path->len]);
@@ -227,53 +228,53 @@ static bool buttons_context_path_data(ButsContextPath *path, int type)
PointerRNA *ptr = &path->ptr[path->len - 1];
/* if we already have a data, we're done */
- if (RNA_struct_is_a(ptr->type, &RNA_Mesh) && (ELEM(type, -1, OB_MESH))) {
+ if (RNA_struct_is_a(ptr->type, &RNA_Mesh) && ELEM(type, -1, OB_MESH)) {
return true;
}
if (RNA_struct_is_a(ptr->type, &RNA_Curve) &&
(type == -1 || ELEM(type, OB_CURVES_LEGACY, OB_SURF, OB_FONT))) {
return true;
}
- if (RNA_struct_is_a(ptr->type, &RNA_Armature) && (ELEM(type, -1, OB_ARMATURE))) {
+ if (RNA_struct_is_a(ptr->type, &RNA_Armature) && ELEM(type, -1, OB_ARMATURE)) {
return true;
}
- if (RNA_struct_is_a(ptr->type, &RNA_MetaBall) && (ELEM(type, -1, OB_MBALL))) {
+ if (RNA_struct_is_a(ptr->type, &RNA_MetaBall) && ELEM(type, -1, OB_MBALL)) {
return true;
}
- if (RNA_struct_is_a(ptr->type, &RNA_Lattice) && (ELEM(type, -1, OB_LATTICE))) {
+ if (RNA_struct_is_a(ptr->type, &RNA_Lattice) && ELEM(type, -1, OB_LATTICE)) {
return true;
}
- if (RNA_struct_is_a(ptr->type, &RNA_Camera) && (ELEM(type, -1, OB_CAMERA))) {
+ if (RNA_struct_is_a(ptr->type, &RNA_Camera) && ELEM(type, -1, OB_CAMERA)) {
return true;
}
- if (RNA_struct_is_a(ptr->type, &RNA_Light) && (ELEM(type, -1, OB_LAMP))) {
+ if (RNA_struct_is_a(ptr->type, &RNA_Light) && ELEM(type, -1, OB_LAMP)) {
return true;
}
- if (RNA_struct_is_a(ptr->type, &RNA_Speaker) && (ELEM(type, -1, OB_SPEAKER))) {
+ if (RNA_struct_is_a(ptr->type, &RNA_Speaker) && ELEM(type, -1, OB_SPEAKER)) {
return true;
}
- if (RNA_struct_is_a(ptr->type, &RNA_LightProbe) && (ELEM(type, -1, OB_LIGHTPROBE))) {
+ if (RNA_struct_is_a(ptr->type, &RNA_LightProbe) && ELEM(type, -1, OB_LIGHTPROBE)) {
return true;
}
- if (RNA_struct_is_a(ptr->type, &RNA_GreasePencil) && (ELEM(type, -1, OB_GPENCIL))) {
+ if (RNA_struct_is_a(ptr->type, &RNA_GreasePencil) && ELEM(type, -1, OB_GPENCIL)) {
return true;
}
- if (RNA_struct_is_a(ptr->type, &RNA_Curves) && (ELEM(type, -1, OB_CURVES))) {
+ if (RNA_struct_is_a(ptr->type, &RNA_Curves) && ELEM(type, -1, OB_CURVES)) {
return true;
}
#ifdef WITH_POINT_CLOUD
- if (RNA_struct_is_a(ptr->type, &RNA_PointCloud) && (ELEM(type, -1, OB_POINTCLOUD))) {
+ if (RNA_struct_is_a(ptr->type, &RNA_PointCloud) && ELEM(type, -1, OB_POINTCLOUD)) {
return true;
}
#endif
- if (RNA_struct_is_a(ptr->type, &RNA_Volume) && (ELEM(type, -1, OB_VOLUME))) {
+ if (RNA_struct_is_a(ptr->type, &RNA_Volume) && ELEM(type, -1, OB_VOLUME)) {
return true;
}
/* try to get an object in the path, no pinning supported here */
if (buttons_context_path_object(path)) {
Object *ob = path->ptr[path->len - 1].data;
- if (ob && (ELEM(type, -1, ob->type))) {
+ if (ob && ELEM(type, -1, ob->type)) {
RNA_id_pointer_create(ob->data, &path->ptr[path->len]);
path->len++;
@@ -642,7 +643,9 @@ static bool buttons_context_path(
static bool buttons_shading_context(const bContext *C, int mainb)
{
wmWindow *window = CTX_wm_window(C);
+ const Scene *scene = WM_window_get_active_scene(window);
ViewLayer *view_layer = WM_window_get_active_view_layer(window);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ELEM(mainb, BCONTEXT_MATERIAL, BCONTEXT_WORLD, BCONTEXT_TEXTURE)) {
@@ -658,7 +661,9 @@ static bool buttons_shading_context(const bContext *C, int mainb)
static int buttons_shading_new_context(const bContext *C, int flag)
{
wmWindow *window = CTX_wm_window(C);
+ const Scene *scene = WM_window_get_active_scene(window);
ViewLayer *view_layer = WM_window_get_active_view_layer(window);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (flag & (1 << BCONTEXT_MATERIAL)) {
@@ -1183,22 +1188,22 @@ static void buttons_panel_context_draw(const bContext *C, Panel *panel)
PointerRNA *ptr = &path->ptr[i];
/* Skip scene and view layer to save space. */
- if ((!ELEM(sbuts->mainb,
- BCONTEXT_RENDER,
- BCONTEXT_OUTPUT,
- BCONTEXT_SCENE,
- BCONTEXT_VIEW_LAYER,
- BCONTEXT_WORLD) &&
- ptr->type == &RNA_Scene)) {
+ if (!ELEM(sbuts->mainb,
+ BCONTEXT_RENDER,
+ BCONTEXT_OUTPUT,
+ BCONTEXT_SCENE,
+ BCONTEXT_VIEW_LAYER,
+ BCONTEXT_WORLD) &&
+ ptr->type == &RNA_Scene) {
continue;
}
- if ((!ELEM(sbuts->mainb,
- BCONTEXT_RENDER,
- BCONTEXT_OUTPUT,
- BCONTEXT_SCENE,
- BCONTEXT_VIEW_LAYER,
- BCONTEXT_WORLD) &&
- ptr->type == &RNA_ViewLayer)) {
+ if (!ELEM(sbuts->mainb,
+ BCONTEXT_RENDER,
+ BCONTEXT_OUTPUT,
+ BCONTEXT_SCENE,
+ BCONTEXT_VIEW_LAYER,
+ BCONTEXT_WORLD) &&
+ ptr->type == &RNA_ViewLayer) {
continue;
}
diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h
index 520d3a7c38d..1430cd4a8e8 100644
--- a/source/blender/editors/space_buttons/buttons_intern.h
+++ b/source/blender/editors/space_buttons/buttons_intern.h
@@ -26,7 +26,7 @@ struct SpaceProperties_Runtime {
/** For filtering properties displayed in the space. */
char search_string[UI_MAX_NAME_STR];
/**
- * Bitfield (in the same order as the tabs) for whether each tab has properties
+ * Bit-field (in the same order as the tabs) for whether each tab has properties
* that match the search filter. Only valid when #search_string is set.
*/
BLI_bitmap *tab_search_results;
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index 10fb008049d..9c8d46a41f9 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -41,7 +41,7 @@
/* -------------------------------------------------------------------- */
/** \name Start / Clear Search Filter Operators
*
- * \note Almost a duplicate of the file browser operator #FILE_OT_start_filter.
+ * \note Almost a duplicate of the file browser operator #FILE_OT_start_filter.
* \{ */
static int buttons_start_filter_exec(bContext *C, wmOperator *UNUSED(op))
@@ -205,7 +205,7 @@ static int file_browse_exec(bContext *C, wmOperator *op)
if (BLI_is_dir(path)) {
/* Do this first so '//' isn't converted to '//\' on windows. */
- BLI_path_slash_ensure(path);
+ BLI_path_slash_ensure(path, sizeof(path));
if (is_relative) {
BLI_path_rel(path, BKE_main_blendfile_path(bmain));
str_len = strlen(path);
@@ -337,6 +337,12 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
RNA_string_set(op->ptr, path_prop, str);
MEM_freeN(str);
+ PropertyRNA *prop_check_existing = RNA_struct_find_property(op->ptr, "check_existing");
+ if (!RNA_property_is_set(op->ptr, prop_check_existing)) {
+ const bool is_output_path = (RNA_property_flag(prop) & PROP_PATH_OUTPUT) != 0;
+ RNA_property_boolean_set(op->ptr, prop_check_existing, is_output_path);
+ }
+
WM_event_add_fileselect(C, op);
return OPERATOR_RUNNING_MODAL;
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 46692d29094..8b04398c559 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -179,7 +179,7 @@ static void buttons_texture_modifier_geonodes_users_add(Object *ob,
prop = RNA_struct_find_property(&ptr, "default_value");
PointerRNA texptr = RNA_property_pointer_get(&ptr, prop);
- Tex *tex = (RNA_struct_is_a(texptr.type, &RNA_Texture)) ? (Tex *)texptr.data : NULL;
+ Tex *tex = RNA_struct_is_a(texptr.type, &RNA_Texture) ? (Tex *)texptr.data : NULL;
if (tex != NULL) {
buttons_texture_user_socket_property_add(users,
&ob->id,
@@ -281,6 +281,7 @@ static void buttons_texture_users_from_context(ListBase *users,
brush = BKE_paint_brush(BKE_paint_get_active_from_context(C));
linestyle = BKE_linestyle_active_from_view_layer(view_layer);
+ BKE_view_layer_synced_ensure(scene, view_layer);
ob = BKE_view_layer_active_object_get(view_layer);
}
@@ -413,7 +414,7 @@ void buttons_texture_context_compute(const bContext *C, SpaceProperties *sbuts)
/* Get texture datablock pointer if it's a property. */
texptr = RNA_property_pointer_get(&ct->user->ptr, ct->user->prop);
- tex = (RNA_struct_is_a(texptr.type, &RNA_Texture)) ? texptr.data : NULL;
+ tex = RNA_struct_is_a(texptr.type, &RNA_Texture) ? texptr.data : NULL;
ct->texture = tex;
}
@@ -448,7 +449,7 @@ static void template_texture_select(bContext *C, void *user_p, void *UNUSED(arg)
}
if (user->ptr.data) {
texptr = RNA_property_pointer_get(&user->ptr, user->prop);
- tex = (RNA_struct_is_a(texptr.type, &RNA_Texture)) ? texptr.data : NULL;
+ tex = RNA_struct_is_a(texptr.type, &RNA_Texture) ? texptr.data : NULL;
ct->texture = tex;
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 74b7fa3719a..5a333869dea 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -37,6 +37,8 @@
#include "UI_interface.h"
#include "UI_resources.h"
+#include "BLO_read_write.h"
+
#include "buttons_intern.h" /* own include */
/* -------------------------------------------------------------------- */
@@ -603,7 +605,7 @@ static void buttons_navigation_bar_region_draw(const bContext *C, ARegion *regio
}
ED_region_panels_layout(C, region);
- /* ED_region_panels_layout adds vertical scrollbars, we don't want them. */
+ /* #ED_region_panels_layout adds vertical scroll-bars, we don't want them. */
region->v2d.scroll &= ~V2D_SCROLL_VERTICAL;
ED_region_panels_draw(C, region);
}
@@ -905,6 +907,31 @@ static void buttons_id_remap(ScrArea *UNUSED(area),
}
}
+static void buttons_blend_read_data(BlendDataReader *UNUSED(reader), SpaceLink *sl)
+{
+ SpaceProperties *sbuts = (SpaceProperties *)sl;
+
+ sbuts->path = NULL;
+ sbuts->texuser = NULL;
+ sbuts->mainbo = sbuts->mainb;
+ sbuts->mainbuser = sbuts->mainb;
+ sbuts->runtime = NULL;
+}
+
+static void buttons_blend_read_lib(BlendLibReader *reader, ID *parent_id, SpaceLink *sl)
+{
+ SpaceProperties *sbuts = (SpaceProperties *)sl;
+ BLO_read_id_address(reader, parent_id->lib, &sbuts->pinid);
+ if (sbuts->pinid == NULL) {
+ sbuts->flag &= ~SB_PIN_CONTEXT;
+ }
+}
+
+static void buttons_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ BLO_write_struct(writer, SpaceProperties, sl);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -928,6 +955,9 @@ void ED_spacetype_buttons(void)
st->listener = buttons_area_listener;
st->context = buttons_context;
st->id_remap = buttons_id_remap;
+ st->blend_read_data = buttons_blend_read_data;
+ st->blend_read_lib = buttons_blend_read_lib;
+ st->blend_write = buttons_blend_write;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype buttons region");
diff --git a/source/blender/editors/space_clip/CMakeLists.txt b/source/blender/editors/space_clip/CMakeLists.txt
index 8cb5299df6d..011072270db 100644
--- a/source/blender/editors/space_clip/CMakeLists.txt
+++ b/source/blender/editors/space_clip/CMakeLists.txt
@@ -6,6 +6,7 @@ set(INC
../../blenfont
../../blenkernel
../../blenlib
+ ../../blenloader
../../blentranslation
../../depsgraph
../../gpu
diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c
index 72df2b74b11..3a4a2faa5f7 100644
--- a/source/blender/editors/space_clip/clip_buttons.c
+++ b/source/blender/editors/space_clip/clip_buttons.c
@@ -57,7 +57,7 @@ static void metadata_panel_context_draw(const bContext *C, Panel *panel)
SpaceClip *space_clip = CTX_wm_space_clip(C);
/* NOTE: This might not be exactly the same image buffer as shown in the
* clip editor itself, since that might be coming from proxy, or being
- * postprocessed (stabilized or undistored).
+ * postprocessed (stabilized or undistorted).
* Ideally we need to query metadata from an original image or movie without
* reading actual pixels to speed up the process. */
ImBuf *ibuf = ED_space_clip_get_buffer(space_clip);
diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c
index 8f876f6a8a3..b7ca6334e35 100644
--- a/source/blender/editors/space_clip/clip_dopesheet_draw.c
+++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c
@@ -343,7 +343,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *region)
/* second pass: text */
y = (float)CHANNEL_FIRST;
- BLF_size(fontid, 11.0f * U.pixelsize, U.dpi);
+ BLF_size(fontid, 11.0f * U.dpi_fac);
for (channel = dopesheet->channels.first; channel; channel = channel->next) {
float yminc = (float)(y - CHANNEL_HEIGHT_HALF);
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index b9bd97260ef..ea286fd2c2d 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -1034,7 +1034,7 @@ static void draw_marker_texts(SpaceClip *sc,
return;
}
- BLF_size(fontid, 11.0f * U.pixelsize, U.dpi);
+ BLF_size(fontid, 11.0f * U.dpi_fac);
fontsize = BLF_height_max(fontid);
if (marker->flag & MARKER_DISABLED) {
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index 9a690f36aab..10a037a1c3c 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -676,8 +676,8 @@ typedef struct PrefetchQueue {
SpinLock spin;
- short *stop;
- short *do_update;
+ bool *stop;
+ bool *do_update;
float *progress;
} PrefetchQueue;
@@ -819,7 +819,7 @@ static uchar *prefetch_thread_next_frame(PrefetchQueue *queue,
(queue->initial_frame - queue->current_frame);
}
- *queue->do_update = 1;
+ *queue->do_update = true;
*queue->progress = (float)frames_processed / (queue->end_frame - queue->start_frame);
}
}
@@ -868,7 +868,7 @@ static void prefetch_task_func(TaskPool *__restrict pool, void *task_data)
if (!result) {
/* no more space in the cache, stop reading frames */
- *queue->stop = 1;
+ *queue->stop = true;
break;
}
}
@@ -880,8 +880,8 @@ static void start_prefetch_threads(MovieClip *clip,
int end_frame,
short render_size,
short render_flag,
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress)
{
int tot_thread = BLI_task_scheduler_num_threads();
@@ -918,7 +918,7 @@ static bool prefetch_movie_frame(MovieClip *clip,
int frame,
short render_size,
short render_flag,
- short *stop)
+ bool *stop)
{
MovieClipUser user = *DNA_struct_default_get(MovieClipUser);
@@ -940,14 +940,14 @@ static bool prefetch_movie_frame(MovieClip *clip,
if (!result) {
/* no more space in the cache, we could stop prefetching here */
- *stop = 1;
+ *stop = true;
}
IMB_freeImBuf(ibuf);
}
else {
/* error reading frame, fair enough stop attempting further reading */
- *stop = 1;
+ *stop = true;
}
}
@@ -961,8 +961,8 @@ static void do_prefetch_movie(MovieClip *clip,
int end_frame,
short render_size,
short render_flag,
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress)
{
int frame;
@@ -976,7 +976,7 @@ static void do_prefetch_movie(MovieClip *clip,
frames_processed++;
- *do_update = 1;
+ *do_update = true;
*progress = (float)frames_processed / (end_frame - start_frame);
}
@@ -988,12 +988,12 @@ static void do_prefetch_movie(MovieClip *clip,
frames_processed++;
- *do_update = 1;
+ *do_update = true;
*progress = (float)frames_processed / (end_frame - start_frame);
}
}
-static void prefetch_startjob(void *pjv, short *stop, short *do_update, float *progress)
+static void prefetch_startjob(void *pjv, bool *stop, bool *do_update, float *progress)
{
PrefetchJob *pj = pjv;
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index f276c2acd1a..2c0668625a0 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -201,7 +201,7 @@ static int open_exec(bContext *C, wmOperator *op)
RNA_property_collection_lookup_int(op->ptr, prop, 0, &fileptr);
RNA_string_get(&fileptr, "name", file_only);
- BLI_join_dirfile(str, sizeof(str), dir_only, file_only);
+ BLI_path_join(str, sizeof(str), dir_only, file_only);
}
else {
BKE_report(op->reports, RPT_ERROR, "No files selected to be opened");
@@ -1219,8 +1219,8 @@ static void do_movie_proxy(void *pjv,
int UNUSED(build_count),
int *build_undistort_sizes,
int build_undistort_count,
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress)
{
ProxyJob *pj = pjv;
@@ -1285,8 +1285,8 @@ typedef struct ProxyQueue {
int efra;
SpinLock spin;
- const short *stop;
- short *do_update;
+ const bool *stop;
+ bool *do_update;
float *progress;
} ProxyQueue;
@@ -1343,7 +1343,7 @@ static uchar *proxy_thread_next_frame(ProxyQueue *queue,
queue->cfra++;
close(file);
- *queue->do_update = 1;
+ *queue->do_update = true;
*queue->progress = (float)(queue->cfra - queue->sfra) / (queue->efra - queue->sfra);
}
BLI_spin_unlock(&queue->spin);
@@ -1392,8 +1392,8 @@ static void do_sequence_proxy(void *pjv,
int build_undistort_count,
/* Cannot be const, because it is assigned to a non-const variable.
* NOLINTNEXTLINE: readability-non-const-parameter. */
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress)
{
ProxyJob *pj = pjv;
@@ -1452,7 +1452,7 @@ static void do_sequence_proxy(void *pjv,
MEM_freeN(handles);
}
-static void proxy_startjob(void *pjv, short *stop, short *do_update, float *progress)
+static void proxy_startjob(void *pjv, bool *stop, bool *do_update, float *progress)
{
ProxyJob *pj = pjv;
MovieClip *clip = pj->clip;
@@ -1611,7 +1611,9 @@ void CLIP_OT_mode_set(wmOperatorType *ot)
ot->poll = ED_space_clip_poll;
/* properties */
- RNA_def_enum(ot->srna, "mode", rna_enum_clip_editor_mode_items, SC_MODE_TRACKING, "Mode", "");
+ ot->prop = RNA_def_enum(
+ ot->srna, "mode", rna_enum_clip_editor_mode_items, SC_MODE_TRACKING, "Mode", "");
+ RNA_def_property_translation_context(ot->prop, BLT_I18NCONTEXT_ID_MOVIECLIP);
}
/** \} */
@@ -1639,14 +1641,14 @@ static int clip_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), const wmEv
float pan_vec[3];
const wmNDOFMotionData *ndof = event->customdata;
- const float speed = NDOF_PIXELS_PER_SECOND;
+ const float pan_speed = NDOF_PIXELS_PER_SECOND;
WM_event_ndof_pan_get(ndof, pan_vec, true);
- mul_v2_fl(pan_vec, (speed * ndof->dt) / sc->zoom);
- pan_vec[2] *= -ndof->dt;
+ mul_v3_fl(pan_vec, ndof->dt);
+ mul_v2_fl(pan_vec, pan_speed / sc->zoom);
- sclip_zoom_set_factor(C, 1.0f + pan_vec[2], NULL, false);
+ sclip_zoom_set_factor(C, max_ff(0.0f, 1.0f - pan_vec[2]), NULL, false);
sc->xof += pan_vec[0];
sc->yof += pan_vec[1];
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index ab952470757..3631a1740f7 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -49,6 +49,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "BLO_read_write.h"
+
#include "RNA_access.h"
#include "clip_intern.h" /* own include */
@@ -1245,6 +1247,27 @@ static void clip_id_remap(ScrArea *UNUSED(area),
BKE_id_remapper_apply(mappings, (ID **)&sclip->mask_info.mask, ID_REMAP_APPLY_ENSURE_REAL);
}
+static void clip_blend_read_data(BlendDataReader *UNUSED(reader), SpaceLink *sl)
+{
+ SpaceClip *sclip = (SpaceClip *)sl;
+
+ sclip->scopes.track_search = NULL;
+ sclip->scopes.track_preview = NULL;
+ sclip->scopes.ok = 0;
+}
+
+static void clip_blend_read_lib(BlendLibReader *reader, ID *parent_id, SpaceLink *sl)
+{
+ SpaceClip *sclip = (SpaceClip *)sl;
+ BLO_read_id_address(reader, parent_id->lib, &sclip->clip);
+ BLO_read_id_address(reader, parent_id->lib, &sclip->mask_info.mask);
+}
+
+static void clip_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ BLO_write_struct(writer, SpaceClip, sl);
+}
+
void ED_spacetype_clip(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype clip");
@@ -1265,6 +1288,9 @@ void ED_spacetype_clip(void)
st->dropboxes = clip_dropboxes;
st->refresh = clip_refresh;
st->id_remap = clip_id_remap;
+ st->blend_read_data = clip_blend_read_data;
+ st->blend_read_lib = clip_blend_read_lib;
+ st->blend_write = clip_blend_write;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype clip region");
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index cba4157d044..49725a26562 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -1535,6 +1535,7 @@ void CLIP_OT_average_tracks(wmOperatorType *ot)
PropertyRNA *prop;
prop = RNA_def_boolean(ot->srna, "keep_original", 1, "Keep Original", "Keep original tracks");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_MOVIECLIP);
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
@@ -1846,7 +1847,7 @@ static int clean_tracks_exec(bContext *C, wmOperator *op)
if ((track->flag & TRACK_HIDDEN) == 0 && (track->flag & TRACK_LOCKED) == 0) {
bool ok;
- ok = (is_track_clean(track, frames, action == TRACKING_CLEAN_DELETE_SEGMENT)) &&
+ ok = is_track_clean(track, frames, action == TRACKING_CLEAN_DELETE_SEGMENT) &&
((error == 0.0f) || (track->flag & TRACK_HAS_BUNDLE) == 0 || (track->error < error));
if (!ok) {
diff --git a/source/blender/editors/space_clip/tracking_ops_orient.c b/source/blender/editors/space_clip/tracking_ops_orient.c
index 315c17a6d74..c6d4a6ad104 100644
--- a/source/blender/editors/space_clip/tracking_ops_orient.c
+++ b/source/blender/editors/space_clip/tracking_ops_orient.c
@@ -72,6 +72,7 @@ static Object *get_orientation_object(bContext *C)
object = get_camera_with_movieclip(scene, clip);
}
else {
+ BKE_view_layer_synced_ensure(scene, view_layer);
object = BKE_view_layer_active_object_get(view_layer);
}
@@ -86,6 +87,7 @@ static bool set_orientation_poll(bContext *C)
{
SpaceClip *sc = CTX_wm_space_clip(C);
if (sc != NULL) {
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
if (clip != NULL) {
@@ -94,6 +96,7 @@ static bool set_orientation_poll(bContext *C)
if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
return true;
}
+ BKE_view_layer_synced_ensure(scene, view_layer);
return BKE_view_layer_active_object_get(view_layer) != NULL;
}
}
diff --git a/source/blender/editors/space_clip/tracking_ops_solve.c b/source/blender/editors/space_clip/tracking_ops_solve.c
index bfa45053e96..ddfcaa282e3 100644
--- a/source/blender/editors/space_clip/tracking_ops_solve.c
+++ b/source/blender/editors/space_clip/tracking_ops_solve.c
@@ -87,7 +87,7 @@ static void solve_camera_updatejob(void *scv)
BLI_strncpy(tracking->stats->message, scj->stats_message, sizeof(tracking->stats->message));
}
-static void solve_camera_startjob(void *scv, short *stop, short *do_update, float *progress)
+static void solve_camera_startjob(void *scv, bool *stop, bool *do_update, float *progress)
{
SolveCameraJob *scj = (SolveCameraJob *)scv;
BKE_tracking_reconstruction_solve(
diff --git a/source/blender/editors/space_clip/tracking_ops_track.c b/source/blender/editors/space_clip/tracking_ops_track.c
index f6fd2980c19..2753af609e7 100644
--- a/source/blender/editors/space_clip/tracking_ops_track.c
+++ b/source/blender/editors/space_clip/tracking_ops_track.c
@@ -204,8 +204,8 @@ static void track_markers_startjob(
void *tmv,
/* Cannot be const, this function implements wm_jobs_start_callback.
* NOLINTNEXTLINE: readability-non-const-parameter. */
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress)
{
TrackMarkersJob *tmj = (TrackMarkersJob *)tmv;
@@ -353,7 +353,7 @@ static int track_markers(bContext *C, wmOperator *op, bool use_job)
return OPERATOR_RUNNING_MODAL;
}
- short stop = 0, do_update = 0;
+ bool stop = false, do_update = false;
float progress = 0.0f;
track_markers_startjob(tmj, &stop, &do_update, &progress);
track_markers_endjob(tmj);
diff --git a/source/blender/editors/space_console/CMakeLists.txt b/source/blender/editors/space_console/CMakeLists.txt
index 345ab8b0970..51523bcb383 100644
--- a/source/blender/editors/space_console/CMakeLists.txt
+++ b/source/blender/editors/space_console/CMakeLists.txt
@@ -5,11 +5,15 @@ set(INC
../../blenfont
../../blenkernel
../../blenlib
+ ../../blenloader
../../gpu
../../makesdna
../../makesrna
../../windowmanager
../../../../intern/guardedalloc
+
+ # dna_type_offsets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
)
set(SRC
@@ -31,3 +35,6 @@ endif()
blender_add_lib(bf_editor_space_console "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
+
+# dna_type_offsets.h
+add_dependencies(bf_editor_space_console bf_dna)
diff --git a/source/blender/editors/space_console/console_intern.h b/source/blender/editors/space_console/console_intern.h
index deaaff05a33..8e2ebc9b8e9 100644
--- a/source/blender/editors/space_console/console_intern.h
+++ b/source/blender/editors/space_console/console_intern.h
@@ -15,7 +15,7 @@ struct wmOperatorType;
/* console_draw.c */
void console_textview_main(struct SpaceConsole *sc, const struct ARegion *region);
-/* needed to calculate the scrollbar */
+/* Needed to calculate the scroll-bar. */
int console_textview_height(struct SpaceConsole *sc, const struct ARegion *region);
int console_char_pick(struct SpaceConsole *sc, const struct ARegion *region, const int mval[2]);
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index ef22b1b9f0b..11234d446da 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -280,7 +280,7 @@ static bool console_line_column_from_index(
return false;
}
-/* static funcs for text editing */
+/* Static functions for text editing. */
/* similar to the text editor, with some not used. keep compatible */
static const EnumPropertyItem console_move_type_items[] = {
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index 8af0c1fc6ab..0abb108d5e8 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -28,6 +28,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "BLO_read_write.h"
+
#include "console_intern.h" /* own include */
/* ******************** default callbacks for console space ***************** */
@@ -121,13 +123,14 @@ static void console_main_region_init(wmWindowManager *wm, ARegion *region)
region->v2d.cur.ymax = prev_y_min + cur_y_range;
}
- keymap = WM_keymap_ensure(wm->defaultconf, "View2D Buttons List", 0, 0);
- WM_event_add_keymap_handler(&region->handlers, keymap);
-
/* own keymap */
keymap = WM_keymap_ensure(wm->defaultconf, "Console", SPACE_CONSOLE, 0);
WM_event_add_keymap_handler_v2d_mask(&region->handlers, keymap);
+ /* Include after "Console" so cursor motion keys such as "Home" isn't overridden. */
+ keymap = WM_keymap_ensure(wm->defaultconf, "View2D Buttons List", 0, 0);
+ WM_event_add_keymap_handler(&region->handlers, keymap);
+
/* add drop boxes */
lb = WM_dropboxmap_find("Console", SPACE_CONSOLE, RGN_TYPE_WINDOW);
@@ -283,6 +286,41 @@ static void console_main_region_listener(const wmRegionListenerParams *params)
}
}
+static void console_blend_read_data(BlendDataReader *reader, SpaceLink *sl)
+{
+ SpaceConsole *sconsole = (SpaceConsole *)sl;
+
+ BLO_read_list(reader, &sconsole->scrollback);
+ BLO_read_list(reader, &sconsole->history);
+
+ /* Comma expressions, (e.g. expr1, expr2, expr3) evaluate each expression,
+ * from left to right. the right-most expression sets the result of the comma
+ * expression as a whole. */
+ LISTBASE_FOREACH_MUTABLE (ConsoleLine *, cl, &sconsole->history) {
+ BLO_read_data_address(reader, &cl->line);
+ if (cl->line) {
+ /* The allocated length is not written, so reset here. */
+ cl->len_alloc = cl->len + 1;
+ }
+ else {
+ BLI_remlink(&sconsole->history, cl);
+ MEM_freeN(cl);
+ }
+ }
+}
+
+static void console_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ SpaceConsole *con = (SpaceConsole *)sl;
+
+ LISTBASE_FOREACH (ConsoleLine *, cl, &con->history) {
+ /* 'len_alloc' is invalid on write, set from 'len' on read */
+ BLO_write_struct(writer, ConsoleLine, cl);
+ BLO_write_raw(writer, (size_t)cl->len + 1, cl->line);
+ }
+ BLO_write_struct(writer, SpaceConsole, sl);
+}
+
void ED_spacetype_console(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype console");
@@ -298,6 +336,8 @@ void ED_spacetype_console(void)
st->operatortypes = console_operatortypes;
st->keymap = console_keymap;
st->dropboxes = console_dropboxes;
+ st->blend_read_data = console_blend_read_data;
+ st->blend_write = console_blend_write;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype console region");
diff --git a/source/blender/editors/space_file/CMakeLists.txt b/source/blender/editors/space_file/CMakeLists.txt
index 792b9120e7b..76564f38da8 100644
--- a/source/blender/editors/space_file/CMakeLists.txt
+++ b/source/blender/editors/space_file/CMakeLists.txt
@@ -16,6 +16,9 @@ set(INC
../../windowmanager
../../../../intern/atomic
../../../../intern/guardedalloc
+
+ # dna_type_offsets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
# RNA_prototypes.h
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
@@ -27,8 +30,9 @@ set(SRC
file_ops.c
file_panels.c
file_utils.c
- filelist.c
+ filelist.cc
filesel.c
+ folder_history.cc
fsmenu.c
space_file.c
@@ -42,6 +46,10 @@ set(LIB
bf_blenkernel
)
+if(WIN32)
+ add_definitions(-DNOMINMAX)
+endif()
+
if(WITH_HEADLESS)
add_definitions(-DWITH_HEADLESS)
else()
@@ -88,5 +96,5 @@ endif()
blender_add_lib(bf_editor_space_file "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
-# RNA_prototypes.h
+# RNA_prototypes.h dna_type_offsets.h
add_dependencies(bf_editor_space_file bf_rna)
diff --git a/source/blender/editors/space_file/asset_catalog_tree_view.cc b/source/blender/editors/space_file/asset_catalog_tree_view.cc
index 79e32287d26..bd714d024fb 100644
--- a/source/blender/editors/space_file/asset_catalog_tree_view.cc
+++ b/source/blender/editors/space_file/asset_catalog_tree_view.cc
@@ -598,7 +598,7 @@ std::string AssetCatalogTreeViewAllItem::DropController::drop_tooltip(const wmDr
TIP_("to the top level of the tree");
}
-bool AssetCatalogTreeViewAllItem::DropController::on_drop(struct bContext *UNUSED(C),
+bool AssetCatalogTreeViewAllItem::DropController::on_drop(struct bContext * /*C*/,
const wmDrag &drag)
{
BLI_assert(drag.type == WM_DRAG_ASSET_CATALOG);
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 93eb5938301..ed0132c6990 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -171,7 +171,6 @@ static void file_draw_icon(const SpaceFile *sfile,
UI_but_drag_set_asset(but,
&(AssetHandle){.file_data = file},
BLI_strdup(blend_path),
- file->asset_data,
asset_params->import_type,
icon,
preview_image,
@@ -410,8 +409,15 @@ static void file_draw_preview(const SpaceFile *sfile,
}
icon_x = xco + (ex / 2.0f) - (icon_size / 2.0f);
icon_y = yco + (ey / 2.0f) - (icon_size * ((file->typeflag & FILE_TYPE_DIR) ? 0.78f : 0.75f));
- UI_icon_draw_ex(
- icon_x, icon_y, icon, icon_aspect / U.dpi_fac, icon_opacity, 0.0f, icon_color, false);
+ UI_icon_draw_ex(icon_x,
+ icon_y,
+ icon,
+ icon_aspect / U.dpi_fac,
+ icon_opacity,
+ 0.0f,
+ icon_color,
+ false,
+ UI_NO_ICON_OVERLAY_TEXT);
}
if (is_link || is_offline) {
@@ -424,8 +430,24 @@ static void file_draw_preview(const SpaceFile *sfile,
/* At very bottom-left if preview style. */
const uchar dark[4] = {0, 0, 0, 255};
const uchar light[4] = {255, 255, 255, 255};
- UI_icon_draw_ex(icon_x + 1, icon_y - 1, arrow, 1.0f / U.dpi_fac, 0.2f, 0.0f, dark, false);
- UI_icon_draw_ex(icon_x, icon_y, arrow, 1.0f / U.dpi_fac, 0.6f, 0.0f, light, false);
+ UI_icon_draw_ex(icon_x + 1,
+ icon_y - 1,
+ arrow,
+ 1.0f / U.dpi_fac,
+ 0.2f,
+ 0.0f,
+ dark,
+ false,
+ UI_NO_ICON_OVERLAY_TEXT);
+ UI_icon_draw_ex(icon_x,
+ icon_y,
+ arrow,
+ 1.0f / U.dpi_fac,
+ 0.6f,
+ 0.0f,
+ light,
+ false,
+ UI_NO_ICON_OVERLAY_TEXT);
}
else {
/* Link to folder or non-previewed file. */
@@ -433,8 +455,15 @@ static void file_draw_preview(const SpaceFile *sfile,
UI_GetThemeColor4ubv(TH_BACK, icon_color);
icon_x = xco + ((file->typeflag & FILE_TYPE_DIR) ? 0.14f : 0.23f) * scaledx;
icon_y = yco + ((file->typeflag & FILE_TYPE_DIR) ? 0.24f : 0.14f) * scaledy;
- UI_icon_draw_ex(
- icon_x, icon_y, arrow, icon_aspect / U.dpi_fac * 1.8, 0.3f, 0.0f, icon_color, false);
+ UI_icon_draw_ex(icon_x,
+ icon_y,
+ arrow,
+ icon_aspect / U.dpi_fac * 1.8,
+ 0.3f,
+ 0.0f,
+ icon_color,
+ false,
+ UI_NO_ICON_OVERLAY_TEXT);
}
}
else if (icon && !is_icon && !(file->typeflag & FILE_TYPE_FTFONT)) {
@@ -444,8 +473,17 @@ static void file_draw_preview(const SpaceFile *sfile,
const uchar light[4] = {255, 255, 255, 255};
icon_x = xco + (2.0f * UI_DPI_FAC);
icon_y = yco + (2.0f * UI_DPI_FAC);
- UI_icon_draw_ex(icon_x + 1, icon_y - 1, icon, 1.0f / U.dpi_fac, 0.2f, 0.0f, dark, false);
- UI_icon_draw_ex(icon_x, icon_y, icon, 1.0f / U.dpi_fac, 0.6f, 0.0f, light, false);
+ UI_icon_draw_ex(icon_x + 1,
+ icon_y - 1,
+ icon,
+ 1.0f / U.dpi_fac,
+ 0.2f,
+ 0.0f,
+ dark,
+ false,
+ UI_NO_ICON_OVERLAY_TEXT);
+ UI_icon_draw_ex(
+ icon_x, icon_y, icon, 1.0f / U.dpi_fac, 0.6f, 0.0f, light, false, UI_NO_ICON_OVERLAY_TEXT);
}
const bool is_current_main_data = filelist_file_get_id(file) != NULL;
@@ -456,7 +494,15 @@ static void file_draw_preview(const SpaceFile *sfile,
const uchar light[4] = {255, 255, 255, 255};
icon_x = xco + ex - UI_UNIT_X;
icon_y = yco + ey - UI_UNIT_Y;
- UI_icon_draw_ex(icon_x, icon_y, ICON_CURRENT_FILE, 1.0f / U.dpi_fac, 0.6f, 0.0f, light, false);
+ UI_icon_draw_ex(icon_x,
+ icon_y,
+ ICON_CURRENT_FILE,
+ 1.0f / U.dpi_fac,
+ 0.6f,
+ 0.0f,
+ light,
+ false,
+ UI_NO_ICON_OVERLAY_TEXT);
}
/* Contrasting outline around some preview types. */
@@ -518,7 +564,6 @@ static void file_draw_preview(const SpaceFile *sfile,
UI_but_drag_set_asset(but,
&(AssetHandle){.file_data = file},
BLI_strdup(blend_path),
- file->asset_data,
asset_params->import_type,
icon,
imb,
@@ -544,10 +589,10 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
ARegion *region = CTX_wm_region(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- BLI_join_dirfile(orgname, sizeof(orgname), params->dir, oldname);
+ BLI_path_join(orgname, sizeof(orgname), params->dir, oldname);
BLI_strncpy(filename, params->renamefile, sizeof(filename));
BLI_filename_make_safe(filename);
- BLI_join_dirfile(newname, sizeof(newname), params->dir, filename);
+ BLI_path_join(newname, sizeof(newname), params->dir, filename);
if (!STREQ(orgname, newname)) {
if (!BLI_exists(newname)) {
@@ -952,7 +997,7 @@ void file_draw_list(const bContext *C, ARegion *region)
file = filelist_file(files, i);
file_selflag = filelist_entry_select_get(sfile->files, file, CHECK_ALL);
- BLI_join_dirfile(path, sizeof(path), root, file->relpath);
+ BLI_path_join(path, sizeof(path), root, file->relpath);
if (!(file_selflag & FILE_SEL_EDITING)) {
if ((params->highlight_file == i) || (file_selflag & FILE_SEL_HIGHLIGHTED) ||
@@ -971,7 +1016,7 @@ void file_draw_list(const bContext *C, ARegion *region)
UI_draw_roundbox_corner_set(UI_CNR_NONE);
/* don't drag parent or refresh items */
- do_drag = !(FILENAME_IS_CURRPAR(file->relpath));
+ do_drag = !FILENAME_IS_CURRPAR(file->relpath);
const bool is_hidden = (file->attributes & FILE_ATTR_HIDDEN);
const bool is_link = (file->attributes & FILE_ATTR_ANY_LINK);
diff --git a/source/blender/editors/space_file/file_indexer.cc b/source/blender/editors/space_file/file_indexer.cc
index 7c2ec1a30fd..8520ac34122 100644
--- a/source/blender/editors/space_file/file_indexer.cc
+++ b/source/blender/editors/space_file/file_indexer.cc
@@ -17,17 +17,17 @@
namespace blender::ed::file::indexer {
-static eFileIndexerResult read_index(const char *UNUSED(file_name),
- FileIndexerEntries *UNUSED(entries),
- int *UNUSED(r_read_entries_len),
- void *UNUSED(user_data))
+static eFileIndexerResult read_index(const char * /*file_name*/,
+ FileIndexerEntries * /*entries*/,
+ int * /*r_read_entries_len*/,
+ void * /*user_data*/)
{
return FILE_INDEXER_NEEDS_UPDATE;
}
-static void update_index(const char *UNUSED(file_name),
- FileIndexerEntries *UNUSED(entries),
- void *UNUSED(user_data))
+static void update_index(const char * /*file_name*/,
+ FileIndexerEntries * /*entries*/,
+ void * /*user_data*/)
{
}
@@ -67,8 +67,9 @@ void ED_file_indexer_entries_extend_from_datablock_infos(
}
}
-static void ED_file_indexer_entry_free(void *indexer_entry)
+static void ED_file_indexer_entry_free(void *indexer_entry_ptr)
{
+ FileIndexerEntry *indexer_entry = static_cast<FileIndexerEntry *>(indexer_entry_ptr);
MEM_freeN(indexer_entry);
}
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index ce0a2e8fc04..6e14aed6ede 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -95,11 +95,15 @@ int file_highlight_set(struct SpaceFile *sfile, struct ARegion *region, int mx,
* Use to set the file selector path from some arbitrary source.
*/
void file_sfile_filepath_set(struct SpaceFile *sfile, const char *filepath);
-void file_sfile_to_operator_ex(struct Main *bmain,
+void file_sfile_to_operator_ex(struct bContext *C,
+ struct Main *bmain,
struct wmOperator *op,
struct SpaceFile *sfile,
char *filepath);
-void file_sfile_to_operator(struct Main *bmain, struct wmOperator *op, struct SpaceFile *sfile);
+void file_sfile_to_operator(struct bContext *C,
+ struct Main *bmain,
+ struct wmOperator *op,
+ struct SpaceFile *sfile);
void file_operator_to_sfile(struct Main *bmain, struct SpaceFile *sfile, struct wmOperator *op);
@@ -113,7 +117,7 @@ void fileselect_refresh_params(struct SpaceFile *sfile);
/**
* Sets #FileSelectParams.file (name of selected file)
*/
-void fileselect_file_set(SpaceFile *sfile, int index);
+void fileselect_file_set(struct bContext *C, SpaceFile *sfile, int index);
bool file_attribute_column_type_enabled(const FileSelectParams *params,
FileAttributeColumnType column);
/**
@@ -181,6 +185,19 @@ void file_on_reload_callback_register(struct SpaceFile *sfile,
onReloadFn callback,
onReloadFnData custom_data);
+/* folder_history.cc */
+
+/* not listbase itself */
+void folderlist_free(struct ListBase *folderlist);
+void folderlist_popdir(struct ListBase *folderlist, char *dir);
+void folderlist_pushdir(struct ListBase *folderlist, const char *dir);
+const char *folderlist_peeklastdir(struct ListBase *folderlist);
+bool folderlist_clear_next(struct SpaceFile *sfile);
+
+void folder_history_list_ensure_for_active_browse_mode(struct SpaceFile *sfile);
+void folder_history_list_free(struct SpaceFile *sfile);
+struct ListBase folder_history_list_duplicate(struct ListBase *listbase);
+
/* file_panels.c */
void file_tool_props_region_panels_register(struct ARegionType *art);
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 721c58fc34e..6d7365fa136 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -112,10 +112,10 @@ static void clamp_to_filelist(int numfiles, FileSelection *sel)
}
/* clamp */
- if ((sel->first >= numfiles)) {
+ if (sel->first >= numfiles) {
sel->first = numfiles - 1;
}
- if ((sel->last >= numfiles)) {
+ if (sel->last >= numfiles) {
sel->last = numfiles - 1;
}
}
@@ -197,13 +197,12 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen)
}
else if (file->redirection_path) {
BLI_strncpy(params->dir, file->redirection_path, sizeof(params->dir));
- BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir);
- BLI_path_slash_ensure(params->dir);
+ BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir, sizeof(params->dir));
+ BLI_path_slash_ensure(params->dir, sizeof(params->dir));
}
else {
- BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir);
- strcat(params->dir, file->relpath);
- BLI_path_slash_ensure(params->dir);
+ BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir, sizeof(params->dir));
+ BLI_path_append_dir(params->dir, sizeof(params->dir), file->relpath);
}
ED_file_change_dir(C);
@@ -213,7 +212,7 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen)
else {
retval = FILE_SELECT_FILE;
}
- fileselect_file_set(sfile, selected_idx);
+ fileselect_file_set(C, sfile, selected_idx);
}
return retval;
}
@@ -386,7 +385,7 @@ static bool fsmenu_write_file_and_refresh_or_report_error(struct FSMenu *fsmenu,
}
char filepath[FILE_MAX];
- BLI_join_dirfile(filepath, sizeof(filepath), cfgdir, BLENDER_BOOKMARK_FILE);
+ BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_BOOKMARK_FILE);
if (UNLIKELY(!fsmenu_write_file(fsmenu, filepath))) {
BKE_reportf(reports, RPT_ERROR, "Unable to open or write bookmark file \"%s\"", filepath);
return false;
@@ -484,7 +483,7 @@ static int file_box_select_modal(bContext *C, wmOperator *op, const wmEvent *eve
else {
params->highlight_file = -1;
params->sel_first = params->sel_last = -1;
- fileselect_file_set(sfile, params->active_file);
+ fileselect_file_set(C, sfile, params->active_file);
file_select_deselect_all(sfile, FILE_SEL_HIGHLIGHTED);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
}
@@ -702,7 +701,8 @@ void FILE_OT_select(wmOperatorType *ot)
/**
* \returns true if selection has changed
*/
-static bool file_walk_select_selection_set(wmWindow *win,
+static bool file_walk_select_selection_set(struct bContext *C,
+ wmWindow *win,
ARegion *region,
SpaceFile *sfile,
const int direction,
@@ -808,7 +808,7 @@ static bool file_walk_select_selection_set(wmWindow *win,
}
BLI_assert(IN_RANGE(active, -1, numfiles));
- fileselect_file_set(sfile, params->active_file);
+ fileselect_file_set(C, sfile, params->active_file);
/* ensure newly selected file is inside viewbounds */
file_ensure_inside_viewbounds(region, sfile, params->active_file);
@@ -889,7 +889,8 @@ static bool file_walk_select_do(bContext *C,
}
}
- return file_walk_select_selection_set(win,
+ return file_walk_select_selection_set(C,
+ win,
region,
sfile,
direction,
@@ -1093,7 +1094,7 @@ static int bookmark_select_exec(bContext *C, wmOperator *op)
RNA_property_string_get(op->ptr, prop, entry);
BLI_strncpy(params->dir, entry, sizeof(params->dir));
- BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir);
+ BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir, sizeof(params->dir));
ED_file_change_dir(C);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
@@ -1308,6 +1309,18 @@ static int bookmark_move_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static bool file_bookmark_move_poll(bContext *C)
+{
+ SpaceFile *sfile = CTX_wm_space_file(C);
+
+ /* Bookmarks are for file browsing only (not asset browsing). */
+ if (!ED_operator_file_browsing_active(C)) {
+ return false;
+ }
+
+ return sfile->bookmarknr != -1;
+}
+
void FILE_OT_bookmark_move(wmOperatorType *ot)
{
static const EnumPropertyItem slot_move[] = {
@@ -1324,8 +1337,7 @@ void FILE_OT_bookmark_move(wmOperatorType *ot)
/* api callbacks */
ot->exec = bookmark_move_exec;
- /* Bookmarks are for file browsing only (not asset browsing). */
- ot->poll = ED_operator_file_browsing_active;
+ ot->poll = file_bookmark_move_poll;
/* flags */
ot->flag = OPTYPE_REGISTER; /* No undo! */
@@ -1555,13 +1567,20 @@ void FILE_OT_cancel(struct wmOperatorType *ot)
/** \name Operator Utilities
* \{ */
-void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, char *filepath)
+void file_sfile_to_operator_ex(
+ bContext *C, Main *bmain, wmOperator *op, SpaceFile *sfile, char *filepath)
{
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
PropertyRNA *prop;
/* XXX, not real length */
- BLI_join_dirfile(filepath, FILE_MAX, params->dir, params->file);
+ if (params->file[0]) {
+ BLI_path_join(filepath, FILE_MAX, params->dir, params->file);
+ }
+ else {
+ BLI_strncpy(filepath, params->dir, FILE_MAX);
+ BLI_path_slash_ensure(filepath, FILE_MAX);
+ }
if ((prop = RNA_struct_find_property(op->ptr, "relative_path"))) {
if (RNA_property_boolean_get(op->ptr, prop)) {
@@ -1569,14 +1588,27 @@ void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, ch
}
}
+ char value[FILE_MAX];
if ((prop = RNA_struct_find_property(op->ptr, "filename"))) {
+ RNA_property_string_get(op->ptr, prop, value);
RNA_property_string_set(op->ptr, prop, params->file);
+ if (RNA_property_update_check(prop) && !STREQ(params->file, value)) {
+ RNA_property_update(C, op->ptr, prop);
+ }
}
if ((prop = RNA_struct_find_property(op->ptr, "directory"))) {
+ RNA_property_string_get(op->ptr, prop, value);
RNA_property_string_set(op->ptr, prop, params->dir);
+ if (RNA_property_update_check(prop) && !STREQ(params->dir, value)) {
+ RNA_property_update(C, op->ptr, prop);
+ }
}
if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) {
+ RNA_property_string_get(op->ptr, prop, value);
RNA_property_string_set(op->ptr, prop, filepath);
+ if (RNA_property_update_check(prop) && !STREQ(filepath, value)) {
+ RNA_property_update(C, op->ptr, prop);
+ }
}
/* some ops have multiple files to select */
@@ -1630,11 +1662,11 @@ void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, ch
}
}
}
-void file_sfile_to_operator(Main *bmain, wmOperator *op, SpaceFile *sfile)
+void file_sfile_to_operator(bContext *C, Main *bmain, wmOperator *op, SpaceFile *sfile)
{
char filepath_dummy[FILE_MAX];
- file_sfile_to_operator_ex(bmain, op, sfile, filepath_dummy);
+ file_sfile_to_operator_ex(C, bmain, op, sfile, filepath_dummy);
}
void file_operator_to_sfile(Main *bmain, SpaceFile *sfile, wmOperator *op)
@@ -1695,7 +1727,7 @@ void file_draw_check_ex(bContext *C, ScrArea *area)
if (op) { /* fail on reload */
if (op->type->check) {
Main *bmain = CTX_data_main(C);
- file_sfile_to_operator(bmain, op, sfile);
+ file_sfile_to_operator(C, bmain, op, sfile);
/* redraw */
if (op->type->check(C, op)) {
@@ -1725,7 +1757,7 @@ bool file_draw_check_exists(SpaceFile *sfile)
const FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (params && (params->flag & FILE_CHECK_EXISTING)) {
char filepath[FILE_MAX];
- BLI_join_dirfile(filepath, sizeof(filepath), params->dir, params->file);
+ BLI_path_join(filepath, sizeof(filepath), params->dir, params->file);
if (BLI_is_file(filepath)) {
return true;
}
@@ -1775,8 +1807,7 @@ static bool file_execute(bContext *C, SpaceFile *sfile)
}
else {
BLI_path_normalize(BKE_main_blendfile_path(bmain), params->dir);
- BLI_path_append(params->dir, sizeof(params->dir) - 1, file->relpath);
- BLI_path_slash_ensure(params->dir);
+ BLI_path_append_dir(params->dir, sizeof(params->dir), file->relpath);
}
ED_file_change_dir(C);
}
@@ -1789,7 +1820,7 @@ static bool file_execute(bContext *C, SpaceFile *sfile)
sfile->op = NULL;
- file_sfile_to_operator_ex(bmain, op, sfile, filepath);
+ file_sfile_to_operator_ex(C, bmain, op, sfile, filepath);
if (BLI_exists(params->dir)) {
fsmenu_insert_entry(fsmenu,
@@ -1939,7 +1970,7 @@ static int file_parent_exec(bContext *C, wmOperator *UNUSED(unused))
if (params) {
if (BLI_path_parent_dir(params->dir)) {
- BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir);
+ BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir, sizeof(params->dir));
ED_file_change_dir(C);
if (params->recursion_level > 1) {
/* Disable 'dirtree' recursion when going up in tree. */
@@ -2254,7 +2285,7 @@ static int filepath_drop_exec(bContext *C, wmOperator *op)
file_sfile_filepath_set(sfile, filepath);
if (sfile->op) {
- file_sfile_to_operator(bmain, sfile->op, sfile);
+ file_sfile_to_operator(C, bmain, sfile->op, sfile);
file_draw_check(C);
}
@@ -2295,13 +2326,13 @@ static bool new_folder_path(const char *parent, char folder[FILE_MAX], char name
int len = 0;
BLI_strncpy(name, "New Folder", FILE_MAXFILE);
- BLI_join_dirfile(folder, FILE_MAX, parent, name);
+ BLI_path_join(folder, FILE_MAX, parent, name);
/* check whether folder with the name already exists, in this case
* add number to the name. Check length of generated name to avoid
* crazy case of huge number of folders each named 'New Folder (x)' */
while (BLI_exists(folder) && (len < FILE_MAXFILE)) {
len = BLI_snprintf(name, FILE_MAXFILE, "New Folder(%d)", i);
- BLI_join_dirfile(folder, FILE_MAX, parent, name);
+ BLI_path_join(folder, FILE_MAX, parent, name);
i++;
}
@@ -2441,8 +2472,7 @@ static void file_expand_directory(bContext *C)
else if (params->dir[0] == '~') {
char tmpstr[sizeof(params->dir) - 1];
BLI_strncpy(tmpstr, params->dir + 1, sizeof(tmpstr));
- BLI_path_join(
- params->dir, sizeof(params->dir), BKE_appdir_folder_default_or_root(), tmpstr, NULL);
+ BLI_path_join(params->dir, sizeof(params->dir), BKE_appdir_folder_default_or_root(), tmpstr);
}
else if (params->dir[0] == '\0')
@@ -2523,7 +2553,7 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN
}
}
- BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir);
+ BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir, sizeof(params->dir));
if (filelist_is_dir(sfile->files, params->dir)) {
if (!STREQ(params->dir, old_dir)) { /* Avoids flickering when nothing's changed. */
@@ -2606,11 +2636,11 @@ void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg
}
if (matches == 1) {
- BLI_join_dirfile(filepath, sizeof(params->dir), params->dir, params->file);
+ BLI_path_join(filepath, sizeof(params->dir), params->dir, params->file);
/* if directory, open it and empty filename field */
if (filelist_is_dir(sfile->files, filepath)) {
- BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), filepath);
+ BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), filepath, sizeof(filepath));
BLI_strncpy(params->dir, filepath, sizeof(params->dir));
params->file[0] = '\0';
ED_file_change_dir(C);
@@ -2834,7 +2864,7 @@ static bool file_delete_single(const FileSelectParams *params,
const char **r_error_message)
{
char str[FILE_MAX];
- BLI_join_dirfile(str, sizeof(str), params->dir, file->relpath);
+ BLI_path_join(str, sizeof(str), params->dir, file->relpath);
if (BLI_delete_soft(str, r_error_message) != 0 || BLI_exists(str)) {
return false;
}
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.cc
index 1859e7ccdfc..6638a875871 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.cc
@@ -7,11 +7,11 @@
/* global includes */
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cmath>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
#include <sys/stat.h>
-#include <time.h>
#ifndef WIN32
# include <unistd.h>
@@ -31,6 +31,7 @@
#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_stack.h"
+#include "BLI_string_utils.h"
#include "BLI_task.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
@@ -42,6 +43,8 @@
#include "BKE_asset.h"
#include "BKE_asset_library.h"
+#include "BKE_asset_library.hh"
+#include "BKE_asset_representation.hh"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_icons.h"
@@ -78,185 +81,18 @@
#include "file_intern.h"
#include "filelist.h"
-#define FILEDIR_NBR_ENTRIES_UNSET -1
-
-/* ----------------- FOLDERLIST (previous/next) -------------- */
-
-typedef struct FolderList {
- struct FolderList *next, *prev;
- char *foldername;
-} FolderList;
-
-void folderlist_popdir(struct ListBase *folderlist, char *dir)
-{
- const char *prev_dir;
- struct FolderList *folder;
- folder = folderlist->last;
-
- if (folder) {
- /* remove the current directory */
- MEM_freeN(folder->foldername);
- BLI_freelinkN(folderlist, folder);
-
- folder = folderlist->last;
- if (folder) {
- prev_dir = folder->foldername;
- BLI_strncpy(dir, prev_dir, FILE_MAXDIR);
- }
- }
- /* delete the folder next or use setdir directly before PREVIOUS OP */
-}
-
-void folderlist_pushdir(ListBase *folderlist, const char *dir)
-{
- if (!dir[0]) {
- return;
- }
-
- struct FolderList *folder, *previous_folder;
- previous_folder = folderlist->last;
-
- /* check if already exists */
- if (previous_folder && previous_folder->foldername) {
- if (BLI_path_cmp(previous_folder->foldername, dir) == 0) {
- return;
- }
- }
-
- /* create next folder element */
- folder = MEM_mallocN(sizeof(*folder), __func__);
- folder->foldername = BLI_strdup(dir);
-
- /* add it to the end of the list */
- BLI_addtail(folderlist, folder);
-}
-
-const char *folderlist_peeklastdir(ListBase *folderlist)
-{
- struct FolderList *folder;
-
- if (!folderlist->last) {
- return NULL;
- }
-
- folder = folderlist->last;
- return folder->foldername;
-}
-
-int folderlist_clear_next(struct SpaceFile *sfile)
-{
- const FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- struct FolderList *folder;
-
- /* if there is no folder_next there is nothing we can clear */
- if (BLI_listbase_is_empty(sfile->folders_next)) {
- return 0;
- }
-
- /* if previous_folder, next_folder or refresh_folder operators are executed
- * it doesn't clear folder_next */
- folder = sfile->folders_prev->last;
- if ((!folder) || (BLI_path_cmp(folder->foldername, params->dir) == 0)) {
- return 0;
- }
-
- /* eventually clear flist->folders_next */
- return 1;
-}
-
-void folderlist_free(ListBase *folderlist)
-{
- if (folderlist) {
- FolderList *folder;
- for (folder = folderlist->first; folder; folder = folder->next) {
- MEM_freeN(folder->foldername);
- }
- BLI_freelistN(folderlist);
- }
-}
-
-static ListBase folderlist_duplicate(ListBase *folderlist)
-{
- ListBase folderlistn = {NULL};
-
- BLI_duplicatelist(&folderlistn, folderlist);
-
- for (FolderList *folder = folderlistn.first; folder; folder = folder->next) {
- folder->foldername = MEM_dupallocN(folder->foldername);
- }
- return folderlistn;
-}
-
-/* ----------------- Folder-History (wraps/owns file list above) -------------- */
-
-static FileFolderHistory *folder_history_find(const SpaceFile *sfile, eFileBrowse_Mode browse_mode)
-{
- LISTBASE_FOREACH (FileFolderHistory *, history, &sfile->folder_histories) {
- if (history->browse_mode == browse_mode) {
- return history;
- }
- }
-
- return NULL;
-}
-
-void folder_history_list_ensure_for_active_browse_mode(SpaceFile *sfile)
-{
- FileFolderHistory *history = folder_history_find(sfile, sfile->browse_mode);
-
- if (!history) {
- history = MEM_callocN(sizeof(*history), __func__);
- history->browse_mode = sfile->browse_mode;
- BLI_addtail(&sfile->folder_histories, history);
- }
-
- sfile->folders_next = &history->folders_next;
- sfile->folders_prev = &history->folders_prev;
-}
-
-static void folder_history_entry_free(SpaceFile *sfile, FileFolderHistory *history)
-{
- if (sfile->folders_prev == &history->folders_prev) {
- sfile->folders_prev = NULL;
- }
- if (sfile->folders_next == &history->folders_next) {
- sfile->folders_next = NULL;
- }
- folderlist_free(&history->folders_prev);
- folderlist_free(&history->folders_next);
- BLI_freelinkN(&sfile->folder_histories, history);
-}
-
-void folder_history_list_free(SpaceFile *sfile)
-{
- LISTBASE_FOREACH_MUTABLE (FileFolderHistory *, history, &sfile->folder_histories) {
- folder_history_entry_free(sfile, history);
- }
-}
-
-ListBase folder_history_list_duplicate(ListBase *listbase)
-{
- ListBase histories = {NULL};
-
- LISTBASE_FOREACH (FileFolderHistory *, history, listbase) {
- FileFolderHistory *history_new = MEM_dupallocN(history);
- history_new->folders_prev = folderlist_duplicate(&history->folders_prev);
- history_new->folders_next = folderlist_duplicate(&history->folders_next);
- BLI_addtail(&histories, history_new);
- }
+using namespace blender;
- return histories;
-}
+#define FILEDIR_NBR_ENTRIES_UNSET -1
/* ------------------FILELIST------------------------ */
-typedef struct FileListInternEntry {
- struct FileListInternEntry *next, *prev;
+struct FileListInternEntry {
+ FileListInternEntry *next, *prev;
FileUID uid;
- /** eFileSel_File_Types */
- int typeflag;
+ eFileSel_File_Types typeflag;
/** ID type, in case typeflag has FILE_TYPE_BLENDERLIB set. */
int blentype;
@@ -264,7 +100,7 @@ typedef struct FileListInternEntry {
/** Optional argument for shortcuts, aliases etc. */
char *redirection_path;
/** not strictly needed, but used during sorting, avoids to have to recompute it there... */
- char *name;
+ const char *name;
bool free_name;
/**
@@ -281,25 +117,27 @@ typedef struct FileListInternEntry {
PreviewImage *preview_image;
} local_data;
- /** When the file represents an asset read from another file, it is stored here.
- * Owning pointer. */
- AssetMetaData *imported_asset_data;
+ /* References an asset in the asset library storage. */
+ bke::AssetRepresentation *asset; /* Non-owning. */
+
+ /* See #FILE_ENTRY_BLENDERLIB_NO_PREVIEW. */
+ bool blenderlib_has_no_preview;
/** Defined in BLI_fileops.h */
eFileAttributes attributes;
BLI_stat_t st;
-} FileListInternEntry;
+};
-typedef struct FileListIntern {
+struct FileListIntern {
/** FileListInternEntry items. */
ListBase entries;
FileListInternEntry **filtered;
FileUID curr_uid; /* Used to generate UID during internal listing. */
-} FileListIntern;
+};
#define FILELIST_ENTRYCACHESIZE_DEFAULT 1024 /* Keep it a power of two! */
-typedef struct FileListEntryCache {
+struct FileListEntryCache {
size_t size; /* The size of the cache... */
int flags;
@@ -328,7 +166,7 @@ typedef struct FileListEntryCache {
* previews either in `previews_pool` or `previews_done`. #filelist_cache_previews_update() makes
* previews in `preview_done` ready for display, so the counter is decremented there. */
int previews_todo_count;
-} FileListEntryCache;
+};
/** #FileListCache.flags */
enum {
@@ -336,21 +174,21 @@ enum {
FLC_PREVIEWS_ACTIVE = 1 << 1,
};
-typedef struct FileListEntryPreview {
+struct FileListEntryPreview {
char filepath[FILE_MAX];
uint flags;
int index;
int attributes; /* from FileDirEntry. */
int icon_id;
-} FileListEntryPreview;
+};
/* Dummy wrapper around FileListEntryPreview to ensure we do not access freed memory when freeing
* tasks' data (see T74609). */
-typedef struct FileListEntryPreviewTaskData {
+struct FileListEntryPreviewTaskData {
FileListEntryPreview *preview;
-} FileListEntryPreviewTaskData;
+};
-typedef struct FileListFilter {
+struct FileListFilter {
uint64_t filter;
uint64_t filter_id;
char filter_glob[FILE_MAXFILE];
@@ -358,7 +196,7 @@ typedef struct FileListFilter {
short flags;
AssetViewCatalogFilterSettingsHandle *asset_catalog_filter;
-} FileListFilter;
+};
/** #FileListFilter.flags */
enum {
@@ -370,13 +208,13 @@ enum {
};
struct FileListReadJob;
-typedef struct FileList {
+struct FileList {
FileDirEntryArr filelist;
eFileSelectType type;
/* The library this list was created for. Stored here so we know when to re-read. */
AssetLibraryReference *asset_library_ref;
- struct AssetLibrary *asset_library; /* Non-owning pointer. */
+ bke::AssetLibrary *asset_library; /* Non-owning. */
short flags;
@@ -387,24 +225,24 @@ typedef struct FileList {
/**
* File indexer to use. Attribute is always set.
*/
- const struct FileIndexerType *indexer;
+ const FileIndexerType *indexer;
- struct FileListIntern filelist_intern;
+ FileListIntern filelist_intern;
- struct FileListEntryCache filelist_cache;
+ FileListEntryCache filelist_cache;
/* We need to keep those info outside of actual filelist items,
* because those are no more persistent
* (only generated on demand, and freed as soon as possible).
* Persistent part (mere list of paths + stat info)
- * is kept as small as possible, and filebrowser-agnostic.
+ * is kept as small as possible, and file-browser agnostic.
*/
GHash *selection_state;
short max_recursion;
short recursion_level;
- struct BlendHandle *libfiledata;
+ BlendHandle *libfiledata;
/* Set given path as root directory,
* if last bool is true may change given string in place to a valid value.
@@ -412,7 +250,7 @@ typedef struct FileList {
bool (*check_dir_fn)(struct FileList *, char *, const bool);
/* Fill filelist (to be called by read job). */
- void (*read_job_fn)(struct FileListReadJob *, short *, short *, float *);
+ void (*read_job_fn)(struct FileListReadJob *, bool *, bool *, float *);
/* Filter an entry of current filelist. */
bool (*filter_fn)(struct FileListInternEntry *, const char *, FileListFilter *);
@@ -420,7 +258,7 @@ typedef struct FileList {
void (*prepare_filter_fn)(const struct FileList *, FileListFilter *);
short tags; /* FileListTags */
-} FileList;
+};
/** #FileList.flags */
enum {
@@ -460,25 +298,25 @@ enum {
static ImBuf *gSpecialFileImages[SPECIAL_IMG_MAX];
-static void filelist_readjob_main(struct FileListReadJob *job_params,
- short *stop,
- short *do_update,
+static void filelist_readjob_main(FileListReadJob *job_params,
+ bool *stop,
+ bool *do_update,
float *progress);
-static void filelist_readjob_lib(struct FileListReadJob *job_params,
- short *stop,
- short *do_update,
+static void filelist_readjob_lib(FileListReadJob *job_params,
+ bool *stop,
+ bool *do_update,
float *progress);
-static void filelist_readjob_dir(struct FileListReadJob *job_params,
- short *stop,
- short *do_update,
+static void filelist_readjob_dir(FileListReadJob *job_params,
+ bool *stop,
+ bool *do_update,
float *progress);
-static void filelist_readjob_asset_library(struct FileListReadJob *job_params,
- short *stop,
- short *do_update,
+static void filelist_readjob_asset_library(FileListReadJob *job_params,
+ bool *stop,
+ bool *do_update,
float *progress);
-static void filelist_readjob_main_assets(struct FileListReadJob *job_params,
- short *stop,
- short *do_update,
+static void filelist_readjob_main_assets(FileListReadJob *job_params,
+ bool *stop,
+ bool *do_update,
float *progress);
/* helper, could probably go in BKE actually? */
@@ -494,7 +332,7 @@ struct FileSortData {
bool inverted;
};
-static int compare_apply_inverted(int val, const struct FileSortData *sort_data)
+static int compare_apply_inverted(int val, const FileSortData *sort_data)
{
return sort_data->inverted ? -val : val;
}
@@ -558,7 +396,7 @@ static int compare_direntry_generic(const FileListInternEntry *entry1,
if (entry1->typeflag & FILE_TYPE_DIR) {
if (entry2->typeflag & FILE_TYPE_DIR) {
/* If both entries are tagged as dirs, we make a 'sub filter' that shows first the real dirs,
- * then libs (.blend files), then categories in libs. */
+ * then libraries (.blend files), then categories in libraries. */
if (entry1->typeflag & FILE_TYPE_BLENDERLIB) {
if (!(entry2->typeflag & FILE_TYPE_BLENDERLIB)) {
return 1;
@@ -603,9 +441,9 @@ static int compare_direntry_generic(const FileListInternEntry *entry1,
static int compare_name(void *user_data, const void *a1, const void *a2)
{
- const FileListInternEntry *entry1 = a1;
- const FileListInternEntry *entry2 = a2;
- const struct FileSortData *sort_data = user_data;
+ const FileListInternEntry *entry1 = static_cast<const FileListInternEntry *>(a1);
+ const FileListInternEntry *entry2 = static_cast<const FileListInternEntry *>(a2);
+ const FileSortData *sort_data = static_cast<const FileSortData *>(user_data);
int ret;
if ((ret = compare_direntry_generic(entry1, entry2))) {
@@ -617,9 +455,9 @@ static int compare_name(void *user_data, const void *a1, const void *a2)
static int compare_date(void *user_data, const void *a1, const void *a2)
{
- const FileListInternEntry *entry1 = a1;
- const FileListInternEntry *entry2 = a2;
- const struct FileSortData *sort_data = user_data;
+ const FileListInternEntry *entry1 = static_cast<const FileListInternEntry *>(a1);
+ const FileListInternEntry *entry2 = static_cast<const FileListInternEntry *>(a2);
+ const FileSortData *sort_data = static_cast<const FileSortData *>(user_data);
int64_t time1, time2;
int ret;
@@ -627,8 +465,8 @@ static int compare_date(void *user_data, const void *a1, const void *a2)
return ret;
}
- time1 = (int64_t)entry1->st.st_mtime;
- time2 = (int64_t)entry2->st.st_mtime;
+ time1 = int64_t(entry1->st.st_mtime);
+ time2 = int64_t(entry2->st.st_mtime);
if (time1 < time2) {
return compare_apply_inverted(1, sort_data);
}
@@ -641,9 +479,9 @@ static int compare_date(void *user_data, const void *a1, const void *a2)
static int compare_size(void *user_data, const void *a1, const void *a2)
{
- const FileListInternEntry *entry1 = a1;
- const FileListInternEntry *entry2 = a2;
- const struct FileSortData *sort_data = user_data;
+ const FileListInternEntry *entry1 = static_cast<const FileListInternEntry *>(a1);
+ const FileListInternEntry *entry2 = static_cast<const FileListInternEntry *>(a2);
+ const FileSortData *sort_data = static_cast<const FileSortData *>(user_data);
uint64_t size1, size2;
int ret;
@@ -665,9 +503,9 @@ static int compare_size(void *user_data, const void *a1, const void *a2)
static int compare_extension(void *user_data, const void *a1, const void *a2)
{
- const FileListInternEntry *entry1 = a1;
- const FileListInternEntry *entry2 = a2;
- const struct FileSortData *sort_data = user_data;
+ const FileListInternEntry *entry1 = static_cast<const FileListInternEntry *>(a1);
+ const FileListInternEntry *entry2 = static_cast<const FileListInternEntry *>(a2);
+ const FileSortData *sort_data = static_cast<const FileSortData *>(user_data);
int ret;
if ((ret = compare_direntry_generic(entry1, entry2))) {
@@ -721,7 +559,7 @@ static int compare_extension(void *user_data, const void *a1, const void *a2)
void filelist_sort(struct FileList *filelist)
{
if (filelist->flags & FL_NEED_SORTING) {
- void *sort_cb = NULL;
+ int (*sort_cb)(void *, const void *, const void *) = nullptr;
switch (filelist->sort) {
case FILE_SORT_ALPHA:
@@ -741,10 +579,10 @@ void filelist_sort(struct FileList *filelist)
BLI_assert(0);
break;
}
- BLI_listbase_sort_r(
- &filelist->filelist_intern.entries,
- sort_cb,
- &(struct FileSortData){.inverted = (filelist->flags & FL_SORT_INVERT) != 0});
+
+ FileSortData sort_data{};
+ sort_data.inverted = (filelist->flags & FL_SORT_INVERT) != 0;
+ BLI_listbase_sort_r(&filelist->filelist_intern.entries, sort_cb, &sort_data);
filelist_tag_needs_filtering(filelist);
filelist->flags &= ~FL_NEED_SORTING;
@@ -903,7 +741,7 @@ static bool is_filtered_file_type(const FileListInternEntry *file, const FileLis
/** \return true when the file should be in the result set, false if it should be filtered out. */
static bool is_filtered_file(FileListInternEntry *file,
- const char *UNUSED(root),
+ const char * /*root*/,
FileListFilter *filter)
{
return is_filtered_file_type(file, filter) &&
@@ -942,8 +780,10 @@ static bool is_filtered_id_file_type(const FileListInternEntry *file,
*/
static AssetMetaData *filelist_file_internal_get_asset_data(const FileListInternEntry *file)
{
- const ID *local_id = file->local_data.id;
- return local_id ? local_id->asset_data : file->imported_asset_data;
+ if (!file->asset) {
+ return nullptr;
+ }
+ return &file->asset->get_metadata();
}
static void prepare_filter_asset_library(const FileList *filelist, FileListFilter *filter)
@@ -956,8 +796,8 @@ static void prepare_filter_asset_library(const FileList *filelist, FileListFilte
"prepare_filter_asset_library() should only be called when the file browser is "
"in asset browser mode");
- asset_view_ensure_updated_catalog_filter_data(filter->asset_catalog_filter,
- filelist->asset_library);
+ asset_view_ensure_updated_catalog_filter_data(
+ filter->asset_catalog_filter, reinterpret_cast<::AssetLibrary *>(filelist->asset_library));
}
/**
@@ -975,7 +815,7 @@ static void prepare_filter_asset_library(const FileList *filelist, FileListFilte
static bool asset_tag_matches_filter(const char *filter_search, const AssetMetaData *asset_data)
{
LISTBASE_FOREACH (const AssetTag *, asset_tag, &asset_data->tags) {
- if (BLI_strcasestr(asset_tag->name, filter_search) != NULL) {
+ if (BLI_strcasestr(asset_tag->name, filter_search) != nullptr) {
return true;
}
}
@@ -1003,7 +843,7 @@ static bool is_filtered_asset(FileListInternEntry *file, FileListFilter *filter)
/* When doing a name comparison, get rid of the leading/trailing asterisks. */
filter_search[string_length - 1] = '\0';
- if (BLI_strcasestr(file->name, filter_search + 1) != NULL) {
+ if (BLI_strcasestr(file->name, filter_search + 1) != nullptr) {
return true;
}
return asset_tag_matches_filter(filter_search + 1, asset_data);
@@ -1015,7 +855,7 @@ static bool is_filtered_lib_type(FileListInternEntry *file,
{
char path[FILE_MAX_LIBEXTRA], dir[FILE_MAX_LIBEXTRA], *group, *name;
- BLI_join_dirfile(path, sizeof(path), root, file->relpath);
+ BLI_path_join(path, sizeof(path), root, file->relpath);
if (BLO_library_path_explode(path, dir, &group, &name)) {
return is_filtered_id_file_type(file, group, name, filter);
@@ -1029,14 +869,14 @@ static bool is_filtered_lib(FileListInternEntry *file, const char *root, FileLis
}
static bool is_filtered_main(FileListInternEntry *file,
- const char *UNUSED(dir),
+ const char * /*dir*/,
FileListFilter *filter)
{
return !is_filtered_hidden(file->relpath, filter, file);
}
static bool is_filtered_main_assets(FileListInternEntry *file,
- const char *UNUSED(dir),
+ const char * /*dir*/,
FileListFilter *filter)
{
/* "Filtered" means *not* being filtered out... So return true if the file should be visible. */
@@ -1064,7 +904,7 @@ void filelist_filter(FileList *filelist)
{
int num_filtered = 0;
const int num_files = filelist->filelist.entries_num;
- FileListInternEntry **filtered_tmp, *file;
+ FileListInternEntry **filtered_tmp;
if (ELEM(filelist->filelist.entries_num, FILEDIR_NBR_ENTRIES_UNSET, 0)) {
return;
@@ -1080,7 +920,7 @@ void filelist_filter(FileList *filelist)
/* Never show lib ID 'categories' directories when we are in 'flat' mode, unless
* root path is a blend file. */
char dir[FILE_MAX_LIBEXTRA];
- if (!filelist_islibrary(filelist, dir, NULL)) {
+ if (!filelist_islibrary(filelist, dir, nullptr)) {
filelist->filter_data.flags |= FLF_HIDE_LIB_DIR;
}
}
@@ -1089,10 +929,11 @@ void filelist_filter(FileList *filelist)
filelist->prepare_filter_fn(filelist, &filelist->filter_data);
}
- filtered_tmp = MEM_mallocN(sizeof(*filtered_tmp) * (size_t)num_files, __func__);
+ filtered_tmp = static_cast<FileListInternEntry **>(
+ MEM_mallocN(sizeof(*filtered_tmp) * size_t(num_files), __func__));
/* Filter remap & count how many files are left after filter in a single loop. */
- for (file = filelist->filelist_intern.entries.first; file; file = file->next) {
+ LISTBASE_FOREACH (FileListInternEntry *, file, &filelist->filelist_intern.entries) {
if (filelist->filter_fn(file, filelist->filelist.root, &filelist->filter_data)) {
filtered_tmp[num_filtered++] = file;
}
@@ -1101,11 +942,11 @@ void filelist_filter(FileList *filelist)
if (filelist->filelist_intern.filtered) {
MEM_freeN(filelist->filelist_intern.filtered);
}
- filelist->filelist_intern.filtered = MEM_mallocN(
- sizeof(*filelist->filelist_intern.filtered) * (size_t)num_filtered, __func__);
+ filelist->filelist_intern.filtered = static_cast<FileListInternEntry **>(
+ MEM_mallocN(sizeof(*filelist->filelist_intern.filtered) * size_t(num_filtered), __func__));
memcpy(filelist->filelist_intern.filtered,
filtered_tmp,
- sizeof(*filelist->filelist_intern.filtered) * (size_t)num_filtered);
+ sizeof(*filelist->filelist_intern.filtered) * size_t(num_filtered));
filelist->filelist.entries_filtered_num = num_filtered;
// printf("Filetered: %d over %d entries\n", num_filtered, filelist->filelist.entries_num);
@@ -1157,7 +998,7 @@ void filelist_setfilter_options(FileList *filelist,
filelist->filter_data.filter_glob, filter_glob, sizeof(filelist->filter_data.filter_glob));
update = true;
}
- if ((BLI_strcmp_ignore_pad(filelist->filter_data.filter_search, filter_search, '*') != 0)) {
+ if (BLI_strcmp_ignore_pad(filelist->filter_data.filter_search, filter_search, '*') != 0) {
BLI_strncpy_ensure_pad(filelist->filter_data.filter_search,
filter_search,
'*',
@@ -1181,7 +1022,7 @@ void filelist_setindexer(FileList *filelist, const FileIndexerType *indexer)
void filelist_set_asset_catalog_filter_options(FileList *filelist,
AssetCatalogFilterMode catalog_visibility,
- const bUUID *catalog_id)
+ const ::bUUID *catalog_id)
{
if (!filelist->filter_data.asset_catalog_filter) {
/* There's no filter data yet. */
@@ -1210,7 +1051,7 @@ static bool filelist_compare_asset_libraries(const AssetLibraryReference *librar
/* Don't only check the index, also check that it's valid. */
bUserAssetLibrary *library_ptr_a = BKE_preferences_asset_library_find_from_index(
&U, library_a->custom_library_index);
- return (library_ptr_a != NULL) &&
+ return (library_ptr_a != nullptr) &&
(library_a->custom_library_index == library_b->custom_library_index);
}
@@ -1229,8 +1070,7 @@ void filelist_setlibrary(FileList *filelist, const AssetLibraryReference *asset_
}
if (!filelist->asset_library_ref) {
- filelist->asset_library_ref = MEM_mallocN(sizeof(*filelist->asset_library_ref),
- "filelist asset library");
+ filelist->asset_library_ref = MEM_new<AssetLibraryReference>("filelist asset library");
*filelist->asset_library_ref = *asset_library_ref;
filelist->flags |= FL_FORCE_RESET;
@@ -1252,10 +1092,13 @@ void filelist_init_icons(void)
BLI_assert(G.background == false);
#ifdef WITH_HEADLESS
- bbuf = NULL;
+ bbuf = nullptr;
#else
- bbuf = IMB_ibImageFromMemory(
- (const uchar *)datatoc_prvicons_png, datatoc_prvicons_png_size, IB_rect, NULL, "<splash>");
+ bbuf = IMB_ibImageFromMemory((const uchar *)datatoc_prvicons_png,
+ datatoc_prvicons_png_size,
+ IB_rect,
+ nullptr,
+ "<splash>");
#endif
if (bbuf) {
for (y = 0; y < SPECIAL_IMG_ROWS; y++) {
@@ -1283,7 +1126,7 @@ void filelist_free_icons(void)
for (int i = 0; i < SPECIAL_IMG_MAX; i++) {
IMB_freeImBuf(gSpecialFileImages[i]);
- gSpecialFileImages[i] = NULL;
+ gSpecialFileImages[i] = nullptr;
}
}
@@ -1298,17 +1141,17 @@ ImBuf *filelist_getimage(struct FileList *filelist, const int index)
{
FileDirEntry *file = filelist_geticon_get_file(filelist, index);
- return file->preview_icon_id ? BKE_icon_imbuf_get_buffer(file->preview_icon_id) : NULL;
+ return file->preview_icon_id ? BKE_icon_imbuf_get_buffer(file->preview_icon_id) : nullptr;
}
ImBuf *filelist_file_getimage(const FileDirEntry *file)
{
- return file->preview_icon_id ? BKE_icon_imbuf_get_buffer(file->preview_icon_id) : NULL;
+ return file->preview_icon_id ? BKE_icon_imbuf_get_buffer(file->preview_icon_id) : nullptr;
}
ImBuf *filelist_geticon_image_ex(const FileDirEntry *file)
{
- ImBuf *ibuf = NULL;
+ ImBuf *ibuf = nullptr;
if (file->typeflag & FILE_TYPE_DIR) {
if (FILENAME_IS_PARENT(file->relpath)) {
@@ -1336,7 +1179,7 @@ static int filelist_geticon_ex(const FileDirEntry *file,
const bool is_main,
const bool ignore_libdir)
{
- const eFileSel_File_Types typeflag = file->typeflag;
+ const eFileSel_File_Types typeflag = (eFileSel_File_Types)file->typeflag;
if ((typeflag & FILE_TYPE_DIR) &&
!(ignore_libdir && (typeflag & (FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER)))) {
@@ -1371,8 +1214,8 @@ static int filelist_geticon_ex(const FileDirEntry *file,
target = file->redirection_path;
}
else if (root) {
- BLI_join_dirfile(fullpath, sizeof(fullpath), root, file->relpath);
- BLI_path_slash_ensure(fullpath);
+ BLI_path_join(fullpath, sizeof(fullpath), root, file->relpath);
+ BLI_path_slash_ensure(fullpath, sizeof(fullpath));
}
for (; tfsm; tfsm = tfsm->next) {
if (STREQ(tfsm->path, target)) {
@@ -1457,12 +1300,12 @@ int filelist_geticon(struct FileList *filelist, const int index, const bool is_m
int ED_file_icon(const FileDirEntry *file)
{
return file->preview_icon_id ? file->preview_icon_id :
- filelist_geticon_ex(file, NULL, false, false);
+ filelist_geticon_ex(file, nullptr, false, false);
}
static bool filelist_intern_entry_is_main_file(const FileListInternEntry *intern_entry)
{
- return intern_entry->local_data.id != NULL;
+ return intern_entry->local_data.id != nullptr;
}
/* ********** Main ********** */
@@ -1478,7 +1321,7 @@ static void parent_dir_until_exists_or_default_root(char *dir)
}
}
-static bool filelist_checkdir_dir(struct FileList *UNUSED(filelist),
+static bool filelist_checkdir_dir(struct FileList * /*filelist*/,
char *r_dir,
const bool do_change)
{
@@ -1489,7 +1332,7 @@ static bool filelist_checkdir_dir(struct FileList *UNUSED(filelist),
return BLI_is_dir(r_dir);
}
-static bool filelist_checkdir_lib(struct FileList *UNUSED(filelist),
+static bool filelist_checkdir_lib(struct FileList * /*filelist*/,
char *r_dir,
const bool do_change)
{
@@ -1497,7 +1340,7 @@ static bool filelist_checkdir_lib(struct FileList *UNUSED(filelist),
char *name;
const bool is_valid = (BLI_is_dir(r_dir) ||
- (BLO_library_path_explode(r_dir, tdir, NULL, &name) &&
+ (BLO_library_path_explode(r_dir, tdir, nullptr, &name) &&
BLI_is_file(tdir) && !name));
if (do_change && !is_valid) {
@@ -1514,9 +1357,9 @@ static bool filelist_checkdir_main(struct FileList *filelist, char *r_dir, const
return filelist_checkdir_lib(filelist, r_dir, do_change);
}
-static bool filelist_checkdir_main_assets(struct FileList *UNUSED(filelist),
- char *UNUSED(r_dir),
- const bool UNUSED(do_change))
+static bool filelist_checkdir_main_assets(struct FileList * /*filelist*/,
+ char * /*r_dir*/,
+ const bool /*do_change*/)
{
/* Main is always valid. */
return true;
@@ -1525,7 +1368,7 @@ static bool filelist_checkdir_main_assets(struct FileList *UNUSED(filelist),
static void filelist_entry_clear(FileDirEntry *entry)
{
if (entry->name && ((entry->flags & FILE_ENTRY_NAME_FREE) != 0)) {
- MEM_freeN(entry->name);
+ MEM_freeN((char *)entry->name);
}
if (entry->relpath) {
MEM_freeN(entry->relpath);
@@ -1562,8 +1405,13 @@ static void filelist_direntryarr_free(FileDirEntryArr *array)
array->entries_filtered_num = FILEDIR_NBR_ENTRIES_UNSET;
}
-static void filelist_intern_entry_free(FileListInternEntry *entry)
+static void filelist_intern_entry_free(FileList *filelist, FileListInternEntry *entry)
{
+ if (entry->asset) {
+ BLI_assert(filelist->asset_library);
+ filelist->asset_library->remove_asset(*entry->asset);
+ }
+
if (entry->relpath) {
MEM_freeN(entry->relpath);
}
@@ -1571,22 +1419,16 @@ static void filelist_intern_entry_free(FileListInternEntry *entry)
MEM_freeN(entry->redirection_path);
}
if (entry->name && entry->free_name) {
- MEM_freeN(entry->name);
- }
- /* If we own the asset-data (it was generated from external file data), free it. */
- if (entry->imported_asset_data) {
- BKE_asset_metadata_free(&entry->imported_asset_data);
+ MEM_freeN((char *)entry->name);
}
MEM_freeN(entry);
}
-static void filelist_intern_free(FileListIntern *filelist_intern)
+static void filelist_intern_free(FileList *filelist)
{
- FileListInternEntry *entry, *entry_next;
-
- for (entry = filelist_intern->entries.first; entry; entry = entry_next) {
- entry_next = entry->next;
- filelist_intern_entry_free(entry);
+ FileListIntern *filelist_intern = &filelist->filelist_intern;
+ LISTBASE_FOREACH_MUTABLE (FileListInternEntry *, entry, &filelist_intern->entries) {
+ filelist_intern_entry_free(filelist, entry);
}
BLI_listbase_clear(&filelist_intern->entries);
@@ -1596,8 +1438,9 @@ static void filelist_intern_free(FileListIntern *filelist_intern)
/**
* \return the number of main files removed.
*/
-static int filelist_intern_free_main_files(FileListIntern *filelist_intern)
+static int filelist_intern_free_main_files(FileList *filelist)
{
+ FileListIntern *filelist_intern = &filelist->filelist_intern;
int removed_counter = 0;
LISTBASE_FOREACH_MUTABLE (FileListInternEntry *, entry, &filelist_intern->entries) {
if (!filelist_intern_entry_is_main_file(entry)) {
@@ -1605,7 +1448,7 @@ static int filelist_intern_free_main_files(FileListIntern *filelist_intern)
}
BLI_remlink(&filelist_intern->entries, entry);
- filelist_intern_entry_free(entry);
+ filelist_intern_entry_free(filelist, entry);
removed_counter++;
}
@@ -1613,7 +1456,7 @@ static int filelist_intern_free_main_files(FileListIntern *filelist_intern)
return removed_counter;
}
-int /* ThumbSource */ filelist_preview_source_get(int /* eFileSel_File_Types */ file_type)
+int filelist_preview_source_get(int /* eFileSel_File_Types */ file_type)
{
if (file_type & FILE_TYPE_IMAGE) {
return THB_SOURCE_IMAGE;
@@ -1635,11 +1478,12 @@ int /* ThumbSource */ filelist_preview_source_get(int /* eFileSel_File_Types */
static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdata)
{
- FileListEntryCache *cache = BLI_task_pool_user_data(pool);
- FileListEntryPreviewTaskData *preview_taskdata = taskdata;
+ FileListEntryCache *cache = static_cast<FileListEntryCache *>(BLI_task_pool_user_data(pool));
+ FileListEntryPreviewTaskData *preview_taskdata = static_cast<FileListEntryPreviewTaskData *>(
+ taskdata);
FileListEntryPreview *preview = preview_taskdata->preview;
- ThumbSource source = filelist_preview_source_get(preview->flags);
+ ThumbSource source = static_cast<ThumbSource>(filelist_preview_source_get(preview->flags));
// printf("%s: Start (%d)...\n", __func__, threadid);
@@ -1657,16 +1501,17 @@ static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdat
}
/* Move ownership to the done queue. */
- preview_taskdata->preview = NULL;
+ preview_taskdata->preview = nullptr;
BLI_thread_queue_push(cache->previews_done, preview);
// printf("%s: End (%d)...\n", __func__, threadid);
}
-static void filelist_cache_preview_freef(TaskPool *__restrict UNUSED(pool), void *taskdata)
+static void filelist_cache_preview_freef(TaskPool *__restrict /*pool*/, void *taskdata)
{
- FileListEntryPreviewTaskData *preview_taskdata = taskdata;
+ FileListEntryPreviewTaskData *preview_taskdata = static_cast<FileListEntryPreviewTaskData *>(
+ taskdata);
/* In case the preview wasn't moved to the "done" queue yet. */
if (preview_taskdata->preview) {
@@ -1693,7 +1538,8 @@ static void filelist_cache_previews_clear(FileListEntryCache *cache)
BLI_task_pool_cancel(cache->previews_pool);
FileListEntryPreview *preview;
- while ((preview = BLI_thread_queue_pop_timeout(cache->previews_done, 0))) {
+ while ((preview = static_cast<FileListEntryPreview *>(
+ BLI_thread_queue_pop_timeout(cache->previews_done, 0)))) {
// printf("%s: DONE %d - %s - %p\n", __func__, preview->index, preview->path,
// preview->img);
if (preview->icon_id) {
@@ -1714,8 +1560,8 @@ static void filelist_cache_previews_free(FileListEntryCache *cache)
BLI_thread_queue_free(cache->previews_done);
BLI_task_pool_free(cache->previews_pool);
- cache->previews_pool = NULL;
- cache->previews_done = NULL;
+ cache->previews_pool = nullptr;
+ cache->previews_done = nullptr;
cache->previews_todo_count = 0;
IMB_thumb_locks_release();
@@ -1743,6 +1589,14 @@ static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry
return;
}
+ /* If we know this is an external ID without a preview, skip loading the preview. Can save quite
+ * some time in heavy files, because otherwise for each missing preview and for each preview
+ * reload, we'd reopen the .blend to look for the preview. */
+ if ((entry->typeflag & FILE_TYPE_BLENDERLIB) &&
+ (entry->flags & FILE_ENTRY_BLENDERLIB_NO_PREVIEW)) {
+ return;
+ }
+
FileListInternEntry *intern_entry = filelist->filelist_intern.filtered[index];
PreviewImage *preview_in_memory = intern_entry->local_data.preview_image;
if (preview_in_memory && !BKE_previewimg_is_finished(preview_in_memory, ICON_SIZE_PREVIEW)) {
@@ -1753,7 +1607,7 @@ static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry
filelist_cache_preview_ensure_running(cache);
entry->flags |= FILE_ENTRY_PREVIEW_LOADING;
- FileListEntryPreview *preview = MEM_mallocN(sizeof(*preview), __func__);
+ FileListEntryPreview *preview = MEM_new<FileListEntryPreview>(__func__);
preview->index = index;
preview->flags = entry->typeflag;
preview->attributes = entry->attributes;
@@ -1774,13 +1628,13 @@ static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry
BLI_strncpy(preview->filepath, entry->redirection_path, FILE_MAXDIR);
}
else {
- BLI_join_dirfile(
+ BLI_path_join(
preview->filepath, sizeof(preview->filepath), filelist->filelist.root, entry->relpath);
}
// printf("%s: %d - %s\n", __func__, preview->index, preview->filepath);
- FileListEntryPreviewTaskData *preview_taskdata = MEM_mallocN(sizeof(*preview_taskdata),
- __func__);
+ FileListEntryPreviewTaskData *preview_taskdata = MEM_new<FileListEntryPreviewTaskData>(
+ __func__);
preview_taskdata->preview = preview;
BLI_task_pool_push(cache->previews_pool,
filelist_cache_preview_runf,
@@ -1797,11 +1651,12 @@ static void filelist_cache_init(FileListEntryCache *cache, size_t cache_size)
cache->block_cursor = cache->block_start_index = cache->block_center_index =
cache->block_end_index = 0;
- cache->block_entries = MEM_mallocN(sizeof(*cache->block_entries) * cache_size, __func__);
+ cache->block_entries = static_cast<FileDirEntry **>(
+ MEM_mallocN(sizeof(*cache->block_entries) * cache_size, __func__));
cache->misc_entries = BLI_ghash_ptr_new_ex(__func__, cache_size);
- cache->misc_entries_indices = MEM_mallocN(sizeof(*cache->misc_entries_indices) * cache_size,
- __func__);
+ cache->misc_entries_indices = static_cast<int *>(
+ MEM_mallocN(sizeof(*cache->misc_entries_indices) * cache_size, __func__));
copy_vn_i(cache->misc_entries_indices, cache_size, -1);
cache->misc_cursor = 0;
@@ -1812,15 +1667,10 @@ static void filelist_cache_init(FileListEntryCache *cache, size_t cache_size)
cache->flags = FLC_IS_INIT;
cache->previews_todo_count = 0;
-
- /* We cannot translate from non-main thread, so init translated strings once from here. */
- IMB_thumb_ensure_translations();
}
static void filelist_cache_free(FileListEntryCache *cache)
{
- FileDirEntry *entry, *entry_next;
-
if (!(cache->flags & FLC_IS_INIT)) {
return;
}
@@ -1829,13 +1679,12 @@ static void filelist_cache_free(FileListEntryCache *cache)
MEM_freeN(cache->block_entries);
- BLI_ghash_free(cache->misc_entries, NULL, NULL);
+ BLI_ghash_free(cache->misc_entries, nullptr, nullptr);
MEM_freeN(cache->misc_entries_indices);
- BLI_ghash_free(cache->uids, NULL, NULL);
+ BLI_ghash_free(cache->uids, nullptr, nullptr);
- for (entry = cache->cached_entries.first; entry; entry = entry_next) {
- entry_next = entry->next;
+ LISTBASE_FOREACH_MUTABLE (FileDirEntry *, entry, &cache->cached_entries) {
filelist_entry_free(entry);
}
BLI_listbase_clear(&cache->cached_entries);
@@ -1843,8 +1692,6 @@ static void filelist_cache_free(FileListEntryCache *cache)
static void filelist_cache_clear(FileListEntryCache *cache, size_t new_size)
{
- FileDirEntry *entry, *entry_next;
-
if (!(cache->flags & FLC_IS_INIT)) {
return;
}
@@ -1854,23 +1701,22 @@ static void filelist_cache_clear(FileListEntryCache *cache, size_t new_size)
cache->block_cursor = cache->block_start_index = cache->block_center_index =
cache->block_end_index = 0;
if (new_size != cache->size) {
- cache->block_entries = MEM_reallocN(cache->block_entries,
- sizeof(*cache->block_entries) * new_size);
+ cache->block_entries = static_cast<FileDirEntry **>(
+ MEM_reallocN(cache->block_entries, sizeof(*cache->block_entries) * new_size));
}
- BLI_ghash_clear_ex(cache->misc_entries, NULL, NULL, new_size);
+ BLI_ghash_clear_ex(cache->misc_entries, nullptr, nullptr, new_size);
if (new_size != cache->size) {
- cache->misc_entries_indices = MEM_reallocN(cache->misc_entries_indices,
- sizeof(*cache->misc_entries_indices) * new_size);
+ cache->misc_entries_indices = static_cast<int *>(MEM_reallocN(
+ cache->misc_entries_indices, sizeof(*cache->misc_entries_indices) * new_size));
}
copy_vn_i(cache->misc_entries_indices, new_size, -1);
- BLI_ghash_clear_ex(cache->uids, NULL, NULL, new_size * 2);
+ BLI_ghash_clear_ex(cache->uids, nullptr, nullptr, new_size * 2);
cache->size = new_size;
- for (entry = cache->cached_entries.first; entry; entry = entry_next) {
- entry_next = entry->next;
+ LISTBASE_FOREACH_MUTABLE (FileDirEntry *, entry, &cache->cached_entries) {
filelist_entry_free(entry);
}
BLI_listbase_clear(&cache->cached_entries);
@@ -1878,7 +1724,7 @@ static void filelist_cache_clear(FileListEntryCache *cache, size_t new_size)
FileList *filelist_new(short type)
{
- FileList *p = MEM_callocN(sizeof(*p), __func__);
+ FileList *p = MEM_cnew<FileList>(__func__);
filelist_cache_init(&p->filelist_cache, FILELIST_ENTRYCACHESIZE_DEFAULT);
@@ -1895,20 +1741,20 @@ void filelist_settype(FileList *filelist, short type)
return;
}
- filelist->type = type;
+ filelist->type = (eFileSelectType)type;
filelist->tags = 0;
filelist->indexer = &file_indexer_noop;
switch (filelist->type) {
case FILE_MAIN:
filelist->check_dir_fn = filelist_checkdir_main;
filelist->read_job_fn = filelist_readjob_main;
- filelist->prepare_filter_fn = NULL;
+ filelist->prepare_filter_fn = nullptr;
filelist->filter_fn = is_filtered_main;
break;
case FILE_LOADLIB:
filelist->check_dir_fn = filelist_checkdir_lib;
filelist->read_job_fn = filelist_readjob_lib;
- filelist->prepare_filter_fn = NULL;
+ filelist->prepare_filter_fn = nullptr;
filelist->filter_fn = is_filtered_lib;
break;
case FILE_ASSET_LIBRARY:
@@ -1928,7 +1774,7 @@ void filelist_settype(FileList *filelist, short type)
default:
filelist->check_dir_fn = filelist_checkdir_dir;
filelist->read_job_fn = filelist_readjob_dir;
- filelist->prepare_filter_fn = NULL;
+ filelist->prepare_filter_fn = nullptr;
filelist->filter_fn = is_filtered_file;
break;
}
@@ -1939,7 +1785,7 @@ void filelist_settype(FileList *filelist, short type)
static void filelist_clear_asset_library(FileList *filelist)
{
/* The AssetLibraryService owns the AssetLibrary pointer, so no need for us to free it. */
- filelist->asset_library = NULL;
+ filelist->asset_library = nullptr;
asset_view_delete_catalog_filter_settings(&filelist->filter_data.asset_catalog_filter);
}
@@ -1958,12 +1804,12 @@ void filelist_clear_ex(struct FileList *filelist,
filelist_cache_clear(&filelist->filelist_cache, filelist->filelist_cache.size);
}
- filelist_intern_free(&filelist->filelist_intern);
+ filelist_intern_free(filelist);
filelist_direntryarr_free(&filelist->filelist);
if (do_selection && filelist->selection_state) {
- BLI_ghash_clear(filelist->selection_state, NULL, NULL);
+ BLI_ghash_clear(filelist->selection_state, nullptr, nullptr);
}
if (do_asset_library) {
@@ -1986,14 +1832,14 @@ static void filelist_clear_main_files(FileList *filelist,
filelist_cache_clear(&filelist->filelist_cache, filelist->filelist_cache.size);
}
- const int removed_files = filelist_intern_free_main_files(&filelist->filelist_intern);
+ const int removed_files = filelist_intern_free_main_files(filelist);
filelist->filelist.entries_num -= removed_files;
filelist->filelist.entries_filtered_num = FILEDIR_NBR_ENTRIES_UNSET;
BLI_assert(filelist->filelist.entries_num > FILEDIR_NBR_ENTRIES_UNSET);
if (do_selection && filelist->selection_state) {
- BLI_ghash_clear(filelist->selection_state, NULL, NULL);
+ BLI_ghash_clear(filelist->selection_state, nullptr, nullptr);
}
if (do_asset_library) {
@@ -2032,8 +1878,8 @@ void filelist_free(struct FileList *filelist)
filelist_cache_free(&filelist->filelist_cache);
if (filelist->selection_state) {
- BLI_ghash_free(filelist->selection_state, NULL, NULL);
- filelist->selection_state = NULL;
+ BLI_ghash_free(filelist->selection_state, nullptr, nullptr);
+ filelist->selection_state = nullptr;
}
MEM_SAFE_FREE(filelist->asset_library_ref);
@@ -2045,7 +1891,7 @@ void filelist_free(struct FileList *filelist)
AssetLibrary *filelist_asset_library(FileList *filelist)
{
- return filelist->asset_library;
+ return reinterpret_cast<::AssetLibrary *>(filelist->asset_library);
}
void filelist_freelib(struct FileList *filelist)
@@ -2053,7 +1899,7 @@ void filelist_freelib(struct FileList *filelist)
if (filelist->libfiledata) {
BLO_blendhandle_close(filelist->libfiledata);
}
- filelist->libfiledata = NULL;
+ filelist->libfiledata = nullptr;
}
BlendHandle *filelist_lib(struct FileList *filelist)
@@ -2061,16 +1907,20 @@ BlendHandle *filelist_lib(struct FileList *filelist)
return filelist->libfiledata;
}
-static char *fileentry_uiname(const char *root,
- const char *relpath,
- const eFileSel_File_Types typeflag,
- char *buff)
+static const char *fileentry_uiname(const char *root, FileListInternEntry *entry, char *buff)
{
- char *name = NULL;
+ if (entry->asset) {
+ const StringRefNull asset_name = entry->asset->get_name();
+ return BLI_strdupn(asset_name.c_str(), asset_name.size());
+ }
+
+ const char *relpath = entry->relpath;
+ const eFileSel_File_Types typeflag = entry->typeflag;
+ char *name = nullptr;
if (typeflag & FILE_TYPE_FTFONT && !(typeflag & FILE_TYPE_BLENDERLIB)) {
char abspath[FILE_MAX_LIBEXTRA];
- BLI_join_dirfile(abspath, sizeof(abspath), root, relpath);
+ BLI_path_join(abspath, sizeof(abspath), root, relpath);
name = BLF_display_name_from_file(abspath);
if (name) {
/* Allocated string, so no need to #BLI_strdup. */
@@ -2082,7 +1932,7 @@ static char *fileentry_uiname(const char *root,
char abspath[FILE_MAX_LIBEXTRA];
char *group;
- BLI_join_dirfile(abspath, sizeof(abspath), root, relpath);
+ BLI_path_join(abspath, sizeof(abspath), root, relpath);
BLO_library_path_explode(abspath, buff, &group, &name);
if (!name) {
name = group;
@@ -2114,10 +1964,10 @@ bool filelist_is_dir(struct FileList *filelist, const char *path)
void filelist_setdir(struct FileList *filelist, char *r_dir)
{
- const bool allow_invalid = filelist->asset_library_ref != NULL;
+ const bool allow_invalid = filelist->asset_library_ref != nullptr;
BLI_assert(strlen(r_dir) < FILE_MAX_LIBEXTRA);
- BLI_path_normalize_dir(BKE_main_blendfile_path_from_global(), r_dir);
+ BLI_path_normalize_dir(BKE_main_blendfile_path_from_global(), r_dir, FILE_MAX_LIBEXTRA);
const bool is_valid_path = filelist->check_dir_fn(filelist, r_dir, !allow_invalid);
BLI_assert(is_valid_path || allow_invalid);
UNUSED_VARS_NDEBUG(is_valid_path);
@@ -2185,10 +2035,10 @@ static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int in
FileListEntryCache *cache = &filelist->filelist_cache;
FileDirEntry *ret;
- ret = MEM_callocN(sizeof(*ret), __func__);
+ ret = MEM_cnew<FileDirEntry>(__func__);
- ret->size = (uint64_t)entry->st.st_size;
- ret->time = (int64_t)entry->st.st_mtime;
+ ret->size = uint64_t(entry->st.st_size);
+ ret->time = int64_t(entry->st.st_mtime);
ret->relpath = BLI_strdup(entry->relpath);
if (entry->free_name) {
@@ -2206,10 +2056,7 @@ static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int in
ret->redirection_path = BLI_strdup(entry->redirection_path);
}
ret->id = entry->local_data.id;
- ret->asset_data = entry->imported_asset_data ? entry->imported_asset_data : NULL;
- if (ret->id && (ret->asset_data == NULL)) {
- ret->asset_data = ret->id->asset_data;
- }
+ ret->asset = reinterpret_cast<::AssetRepresentation *>(entry->asset);
/* For some file types the preview is already available. */
if (entry->local_data.preview_image &&
BKE_previewimg_is_finished(entry->local_data.preview_image, ICON_SIZE_PREVIEW)) {
@@ -2218,6 +2065,9 @@ static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int in
ret->preview_icon_id = BKE_icon_imbuf_create(ibuf);
}
}
+ if (entry->blenderlib_has_no_preview) {
+ ret->flags |= FILE_ENTRY_BLENDERLIB_NO_PREVIEW;
+ }
BLI_addtail(&cache->cached_entries, ret);
return ret;
}
@@ -2230,7 +2080,7 @@ static void filelist_file_release_entry(FileList *filelist, FileDirEntry *entry)
FileDirEntry *filelist_file_ex(struct FileList *filelist, const int index, const bool use_request)
{
- FileDirEntry *ret = NULL, *old;
+ FileDirEntry *ret = nullptr, *old;
FileListEntryCache *cache = &filelist->filelist_cache;
const size_t cache_size = cache->size;
int old_index;
@@ -2244,12 +2094,13 @@ FileDirEntry *filelist_file_ex(struct FileList *filelist, const int index, const
return cache->block_entries[idx];
}
- if ((ret = BLI_ghash_lookup(cache->misc_entries, POINTER_FROM_INT(index)))) {
+ if ((ret = static_cast<FileDirEntry *>(
+ BLI_ghash_lookup(cache->misc_entries, POINTER_FROM_INT(index))))) {
return ret;
}
if (!use_request) {
- return NULL;
+ return nullptr;
}
// printf("requesting file %d (not yet cached)\n", index);
@@ -2257,8 +2108,9 @@ FileDirEntry *filelist_file_ex(struct FileList *filelist, const int index, const
/* Else, we have to add new entry to 'misc' cache - and possibly make room for it first! */
ret = filelist_file_create_entry(filelist, index);
old_index = cache->misc_entries_indices[cache->misc_cursor];
- if ((old = BLI_ghash_popkey(cache->misc_entries, POINTER_FROM_INT(old_index), NULL))) {
- BLI_ghash_remove(cache->uids, POINTER_FROM_UINT(old->uid), NULL, NULL);
+ if ((old = static_cast<FileDirEntry *>(
+ BLI_ghash_popkey(cache->misc_entries, POINTER_FROM_INT(old_index), nullptr)))) {
+ BLI_ghash_remove(cache->uids, POINTER_FROM_UINT(old->uid), nullptr, nullptr);
filelist_file_release_entry(filelist, old);
}
BLI_ghash_insert(cache->misc_entries, POINTER_FROM_INT(index), ret);
@@ -2375,7 +2227,8 @@ static bool filelist_file_cache_block_create(FileList *filelist,
FileDirEntry *entry;
/* That entry might have already been requested and stored in misc cache... */
- if ((entry = BLI_ghash_popkey(cache->misc_entries, POINTER_FROM_INT(idx), NULL)) == NULL) {
+ if ((entry = static_cast<FileDirEntry *>(BLI_ghash_popkey(
+ cache->misc_entries, POINTER_FROM_INT(idx), nullptr))) == nullptr) {
entry = filelist_file_create_entry(filelist, idx);
BLI_ghash_insert(cache->uids, POINTER_FROM_UINT(entry->uid), entry);
}
@@ -2403,10 +2256,10 @@ static void filelist_file_cache_block_release(struct FileList *filelist,
__func__,
cursor /*, cache->block_entries[cursor], cache->block_entries[cursor]->relpath*/);
#endif
- BLI_ghash_remove(cache->uids, POINTER_FROM_UINT(entry->uid), NULL, NULL);
+ BLI_ghash_remove(cache->uids, POINTER_FROM_UINT(entry->uid), nullptr, nullptr);
filelist_file_release_entry(filelist, entry);
#ifndef NDEBUG
- cache->block_entries[cursor] = NULL;
+ cache->block_entries[cursor] = nullptr;
#endif
}
}
@@ -2612,7 +2465,7 @@ bool filelist_file_cache_block(struct FileList *filelist, const int index)
do {
int offs_idx = index + offs;
if (start_index <= offs_idx && offs_idx < end_index) {
- int offs_block_idx = (block_index + offs) % (int)cache_size;
+ int offs_block_idx = (block_index + offs) % int(cache_size);
filelist_cache_previews_push(filelist, cache->block_entries[offs_block_idx], offs_idx);
}
} while ((offs = -offs) < 0); /* Switch between negative and positive offset. */
@@ -2637,7 +2490,7 @@ void filelist_cache_previews_set(FileList *filelist, const bool use_previews)
if (use_previews && (filelist->flags & FL_IS_READY)) {
cache->flags |= FLC_PREVIEWS_ACTIVE;
- BLI_assert((cache->previews_pool == NULL) && (cache->previews_done == NULL) &&
+ BLI_assert((cache->previews_pool == nullptr) && (cache->previews_done == nullptr) &&
(cache->previews_todo_count == 0));
// printf("%s: Init Previews...\n", __func__);
@@ -2664,7 +2517,8 @@ bool filelist_cache_previews_update(FileList *filelist)
// printf("%s: Update Previews...\n", __func__);
while (!BLI_thread_queue_is_empty(cache->previews_done)) {
- FileListEntryPreview *preview = BLI_thread_queue_pop(cache->previews_done);
+ FileListEntryPreview *preview = static_cast<FileListEntryPreview *>(
+ BLI_thread_queue_pop(cache->previews_done));
FileDirEntry *entry;
/* Paranoid (should never happen currently
@@ -2712,7 +2566,7 @@ bool filelist_cache_previews_running(FileList *filelist)
{
FileListEntryCache *cache = &filelist->filelist_cache;
- return (cache->previews_pool != NULL);
+ return (cache->previews_pool != nullptr);
}
bool filelist_cache_previews_done(FileList *filelist)
@@ -2723,7 +2577,7 @@ bool filelist_cache_previews_done(FileList *filelist)
return false;
}
- return (cache->previews_pool == NULL) || (cache->previews_done == NULL) ||
+ return (cache->previews_pool == nullptr) || (cache->previews_done == nullptr) ||
(cache->previews_todo_count == 0);
}
@@ -2732,7 +2586,7 @@ static bool file_is_blend_backup(const char *str)
{
const size_t a = strlen(str);
size_t b = 7;
- bool retval = 0;
+ bool retval = false;
if (a == 0 || b >= a) {
/* pass */
@@ -2748,7 +2602,7 @@ static bool file_is_blend_backup(const char *str)
loc = BLI_strcasestr(str + a - b, ".blend");
if (loc) {
- retval = 1;
+ retval = true;
}
}
@@ -2769,7 +2623,7 @@ int ED_path_extension_type(const char *path)
".app",
/* Safari in-progress/paused download */
".download",
- NULL)) {
+ nullptr)) {
return FILE_TYPE_BUNDLE;
}
#endif
@@ -2786,11 +2640,11 @@ int ED_path_extension_type(const char *path)
".mcr",
".inc",
".fountain",
- NULL)) {
+ nullptr)) {
return FILE_TYPE_TEXT;
}
if (BLI_path_extension_check_n(
- path, ".ttf", ".ttc", ".pfb", ".otf", ".otc", ".woff", ".woff2", NULL)) {
+ path, ".ttf", ".ttc", ".pfb", ".otf", ".otc", ".woff", ".woff2", nullptr)) {
return FILE_TYPE_FTFONT;
}
if (BLI_path_extension_check(path, ".btx")) {
@@ -2802,7 +2656,7 @@ int ED_path_extension_type(const char *path)
if (BLI_path_extension_check(path, ".abc")) {
return FILE_TYPE_ALEMBIC;
}
- if (BLI_path_extension_check_n(path, ".usd", ".usda", ".usdc", NULL)) {
+ if (BLI_path_extension_check_n(path, ".usd", ".usda", ".usdc", nullptr)) {
return FILE_TYPE_USD;
}
if (BLI_path_extension_check(path, ".vdb")) {
@@ -2812,7 +2666,7 @@ int ED_path_extension_type(const char *path)
return FILE_TYPE_ARCHIVE;
}
if (BLI_path_extension_check_n(
- path, ".obj", ".mtl", ".3ds", ".fbx", ".glb", ".gltf", ".svg", ".stl", NULL)) {
+ path, ".obj", ".mtl", ".3ds", ".fbx", ".glb", ".gltf", ".svg", ".stl", nullptr)) {
return FILE_TYPE_OBJECT_IO;
}
if (BLI_path_extension_check_array(path, imb_ext_image)) {
@@ -2881,7 +2735,7 @@ uint filelist_entry_select_set(const FileList *filelist,
uint flag,
FileCheckType check)
{
- /* Default NULL pointer if not found is fine here! */
+ /* Default nullptr pointer if not found is fine here! */
void **es_p = BLI_ghash_lookup_p(filelist->selection_state, POINTER_FROM_UINT(entry->uid));
uint entry_flag = es_p ? POINTER_AS_UINT(*es_p) : 0;
const uint org_entry_flag = entry_flag;
@@ -2889,7 +2743,7 @@ uint filelist_entry_select_set(const FileList *filelist,
BLI_assert(entry);
BLI_assert(ELEM(check, CHECK_DIRS, CHECK_FILES, CHECK_ALL));
- if (((check == CHECK_ALL)) || ((check == CHECK_DIRS) && (entry->typeflag & FILE_TYPE_DIR)) ||
+ if ((check == CHECK_ALL) || ((check == CHECK_DIRS) && (entry->typeflag & FILE_TYPE_DIR)) ||
((check == CHECK_FILES) && !(entry->typeflag & FILE_TYPE_DIR))) {
switch (select) {
case FILE_SEL_REMOVE:
@@ -2910,7 +2764,8 @@ uint filelist_entry_select_set(const FileList *filelist,
*es_p = POINTER_FROM_UINT(entry_flag);
}
else {
- BLI_ghash_remove(filelist->selection_state, POINTER_FROM_UINT(entry->uid), NULL, NULL);
+ BLI_ghash_remove(
+ filelist->selection_state, POINTER_FROM_UINT(entry->uid), nullptr, nullptr);
}
}
else if (entry_flag) {
@@ -2950,9 +2805,9 @@ uint filelist_entry_select_get(FileList *filelist, FileDirEntry *entry, FileChec
BLI_assert(entry);
BLI_assert(ELEM(check, CHECK_DIRS, CHECK_FILES, CHECK_ALL));
- if (((check == CHECK_ALL)) || ((check == CHECK_DIRS) && (entry->typeflag & FILE_TYPE_DIR)) ||
+ if ((check == CHECK_ALL) || ((check == CHECK_DIRS) && (entry->typeflag & FILE_TYPE_DIR)) ||
((check == CHECK_FILES) && !(entry->typeflag & FILE_TYPE_DIR))) {
- /* Default NULL pointer if not found is fine here! */
+ /* Default nullptr pointer if not found is fine here! */
return POINTER_AS_UINT(
BLI_ghash_lookup(filelist->selection_state, POINTER_FROM_UINT(entry->uid)));
}
@@ -2976,7 +2831,7 @@ bool filelist_entry_is_selected(FileList *filelist, const int index)
BLI_assert(index >= 0 && index < filelist->filelist.entries_filtered_num);
FileListInternEntry *intern_entry = filelist->filelist_intern.filtered[index];
- /* BLI_ghash_lookup returns NULL if not found, which gets mapped to 0, which gets mapped to
+ /* BLI_ghash_lookup returns nullptr if not found, which gets mapped to 0, which gets mapped to
* "not selected". */
const uint selection_state = POINTER_AS_UINT(
BLI_ghash_lookup(filelist->selection_state, POINTER_FROM_UINT(intern_entry->uid)));
@@ -2996,7 +2851,7 @@ void filelist_entry_parent_select_set(FileList *filelist,
bool filelist_islibrary(struct FileList *filelist, char *dir, char **r_group)
{
- return BLO_library_path_explode(filelist->filelist.root, dir, r_group, NULL);
+ return BLO_library_path_explode(filelist->filelist.root, dir, r_group, nullptr);
}
static int groupname_to_code(const char *group)
@@ -3027,10 +2882,10 @@ static uint64_t groupname_to_filter_id(const char *group)
* i.e. have to be careful about sharing stuff between background working thread.
* and main one (used by UI among other things).
*/
-typedef struct TodoDir {
+struct TodoDir {
int level;
char *dir;
-} TodoDir;
+};
static int filelist_readjob_list_dir(const char *root,
ListBase *entries,
@@ -3054,11 +2909,11 @@ static int filelist_readjob_list_dir(const char *root,
continue;
}
- entry = MEM_callocN(sizeof(*entry), __func__);
- entry->relpath = MEM_dupallocN(files[i].relname);
+ entry = MEM_cnew<FileListInternEntry>(__func__);
+ entry->relpath = static_cast<char *>(MEM_dupallocN(files[i].relname));
entry->st = files[i].s;
- BLI_join_dirfile(full_path, FILE_MAX, root, entry->relpath);
+ BLI_path_join(full_path, FILE_MAX, root, entry->relpath);
char *target = full_path;
/* Set initial file type and attributes. */
@@ -3073,14 +2928,14 @@ static int filelist_readjob_list_dir(const char *root,
/* Is this a file that points to another file? */
if (entry->attributes & FILE_ATTR_ALIAS) {
- entry->redirection_path = MEM_callocN(FILE_MAXDIR, __func__);
+ entry->redirection_path = MEM_cnew_array<char>(FILE_MAXDIR, __func__);
if (BLI_file_alias_target(full_path, entry->redirection_path)) {
if (BLI_is_dir(entry->redirection_path)) {
entry->typeflag = FILE_TYPE_DIR;
- BLI_path_slash_ensure(entry->redirection_path);
+ BLI_path_slash_ensure(entry->redirection_path, FILE_MAXDIR);
}
else {
- entry->typeflag = ED_path_extension_type(entry->redirection_path);
+ entry->typeflag = (eFileSel_File_Types)ED_path_extension_type(entry->redirection_path);
}
target = entry->redirection_path;
#ifdef WIN32
@@ -3090,14 +2945,14 @@ static int filelist_readjob_list_dir(const char *root,
}
else {
MEM_freeN(entry->redirection_path);
- entry->redirection_path = NULL;
+ entry->redirection_path = nullptr;
entry->attributes |= FILE_ATTR_HIDDEN;
}
}
if (!(entry->typeflag & FILE_TYPE_DIR)) {
if (do_lib && BLO_has_bfile_extension(target)) {
- /* If we are considering .blend files as libs, promote them to directory status. */
+ /* If we are considering .blend files as libraries, promote them to directory status. */
entry->typeflag = FILE_TYPE_BLENDER;
/* prevent current file being used as acceptable dir */
if (BLI_path_cmp(main_name, target) != 0) {
@@ -3105,7 +2960,7 @@ static int filelist_readjob_list_dir(const char *root,
}
}
else {
- entry->typeflag = ED_path_extension_type(target);
+ entry->typeflag = (eFileSel_File_Types)ED_path_extension_type(target);
if (filter_glob[0] && BLI_path_extension_check_glob(target, filter_glob)) {
entry->typeflag |= FILE_TYPE_OPERATOR;
}
@@ -3127,7 +2982,9 @@ static int filelist_readjob_list_dir(const char *root,
return entries_num;
}
-typedef enum ListLibOptions {
+enum ListLibOptions {
+ LIST_LIB_OPTION_NONE = 0,
+
/* Will read both the groups + actual ids from the library. Reduces the amount of times that
* a library needs to be opened. */
LIST_LIB_RECURSIVE = (1 << 0),
@@ -3137,25 +2994,31 @@ typedef enum ListLibOptions {
/* Add given root as result. */
LIST_LIB_ADD_PARENT = (1 << 2),
-} ListLibOptions;
+};
+ENUM_OPERATORS(ListLibOptions, LIST_LIB_ADD_PARENT);
static FileListInternEntry *filelist_readjob_list_lib_group_create(const int idcode,
const char *group_name)
{
- FileListInternEntry *entry = MEM_callocN(sizeof(*entry), __func__);
+ FileListInternEntry *entry = MEM_cnew<FileListInternEntry>(__func__);
entry->relpath = BLI_strdup(group_name);
entry->typeflag |= FILE_TYPE_BLENDERLIB | FILE_TYPE_DIR;
entry->blentype = idcode;
return entry;
}
-static void filelist_readjob_list_lib_add_datablock(ListBase *entries,
- const BLODataBlockInfo *datablock_info,
+/**
+ * \warning: This "steals" the asset metadata from \a datablock_info. Not great design but fixing
+ * this requires redesigning things on the caller side for proper ownership management.
+ */
+static void filelist_readjob_list_lib_add_datablock(FileList *filelist,
+ ListBase *entries,
+ BLODataBlockInfo *datablock_info,
const bool prefix_relpath_with_group_name,
const int idcode,
const char *group_name)
{
- FileListInternEntry *entry = MEM_callocN(sizeof(*entry), __func__);
+ FileListInternEntry *entry = MEM_cnew<FileListInternEntry>(__func__);
if (prefix_relpath_with_group_name) {
entry->relpath = BLI_sprintfN("%s/%s", group_name, datablock_info->name);
}
@@ -3163,37 +3026,52 @@ static void filelist_readjob_list_lib_add_datablock(ListBase *entries,
entry->relpath = BLI_strdup(datablock_info->name);
}
entry->typeflag |= FILE_TYPE_BLENDERLIB;
- if (datablock_info && datablock_info->asset_data) {
- entry->typeflag |= FILE_TYPE_ASSET;
- /* Moves ownership! */
- entry->imported_asset_data = datablock_info->asset_data;
+ if (datablock_info) {
+ entry->blenderlib_has_no_preview = datablock_info->no_preview_found;
+
+ if (datablock_info->asset_data) {
+ entry->typeflag |= FILE_TYPE_ASSET;
+
+ if (filelist->asset_library) {
+ /** XXX Moving out the asset metadata like this isn't great. */
+ std::unique_ptr metadata = BKE_asset_metadata_move_to_unique_ptr(
+ datablock_info->asset_data);
+ BKE_asset_metadata_free(&datablock_info->asset_data);
+
+ entry->asset = &filelist->asset_library->add_external_asset(datablock_info->name,
+ std::move(metadata));
+ }
+ }
}
entry->blentype = idcode;
BLI_addtail(entries, entry);
}
-static void filelist_readjob_list_lib_add_datablocks(ListBase *entries,
+static void filelist_readjob_list_lib_add_datablocks(FileList *filelist,
+ ListBase *entries,
LinkNode *datablock_infos,
const bool prefix_relpath_with_group_name,
const int idcode,
const char *group_name)
{
for (LinkNode *ln = datablock_infos; ln; ln = ln->next) {
- struct BLODataBlockInfo *datablock_info = ln->link;
+ struct BLODataBlockInfo *datablock_info = static_cast<BLODataBlockInfo *>(ln->link);
filelist_readjob_list_lib_add_datablock(
- entries, datablock_info, prefix_relpath_with_group_name, idcode, group_name);
+ filelist, entries, datablock_info, prefix_relpath_with_group_name, idcode, group_name);
}
}
static void filelist_readjob_list_lib_add_from_indexer_entries(
+ FileList *filelist,
ListBase *entries,
const FileIndexerEntries *indexer_entries,
const bool prefix_relpath_with_group_name)
{
for (const LinkNode *ln = indexer_entries->entries; ln; ln = ln->next) {
- const FileIndexerEntry *indexer_entry = (const FileIndexerEntry *)ln->link;
+ FileIndexerEntry *indexer_entry = static_cast<FileIndexerEntry *>(ln->link);
const char *group_name = BKE_idtype_idcode_to_name(indexer_entry->idcode);
- filelist_readjob_list_lib_add_datablock(entries,
+ filelist_readjob_list_lib_add_datablock(filelist,
+ entries,
&indexer_entry->datablock_info,
prefix_relpath_with_group_name,
indexer_entry->idcode,
@@ -3203,7 +3081,7 @@ static void filelist_readjob_list_lib_add_from_indexer_entries(
static FileListInternEntry *filelist_readjob_list_lib_navigate_to_parent_entry_create(void)
{
- FileListInternEntry *entry = MEM_callocN(sizeof(*entry), __func__);
+ FileListInternEntry *entry = MEM_cnew<FileListInternEntry>(__func__);
entry->relpath = BLI_strdup(FILENAME_PARENT);
entry->typeflag |= (FILE_TYPE_BLENDERLIB | FILE_TYPE_DIR);
return entry;
@@ -3221,7 +3099,8 @@ typedef struct FileIndexer {
void *user_data;
} FileIndexer;
-static int filelist_readjob_list_lib_populate_from_index(ListBase *entries,
+static int filelist_readjob_list_lib_populate_from_index(FileList *filelist,
+ ListBase *entries,
const ListLibOptions options,
const int read_from_index,
const FileIndexerEntries *indexer_entries)
@@ -3233,11 +3112,12 @@ static int filelist_readjob_list_lib_populate_from_index(ListBase *entries,
navigate_to_parent_len = 1;
}
- filelist_readjob_list_lib_add_from_indexer_entries(entries, indexer_entries, true);
+ filelist_readjob_list_lib_add_from_indexer_entries(filelist, entries, indexer_entries, true);
return read_from_index + navigate_to_parent_len;
}
-static int filelist_readjob_list_lib(const char *root,
+static int filelist_readjob_list_lib(FileList *filelist,
+ const char *root,
ListBase *entries,
const ListLibOptions options,
FileIndexer *indexer_runtime)
@@ -3246,19 +3126,19 @@ static int filelist_readjob_list_lib(const char *root,
char dir[FILE_MAX_LIBEXTRA], *group;
- struct BlendHandle *libfiledata = NULL;
+ struct BlendHandle *libfiledata = nullptr;
/* Check if the given root is actually a library. All folders are passed to
* `filelist_readjob_list_lib` and based on the number of found entries `filelist_readjob_do`
* will do a dir listing only when this function does not return any entries. */
/* TODO(jbakker): We should consider introducing its own function to detect if it is a lib and
* call it directly from `filelist_readjob_do` to increase readability. */
- const bool is_lib = BLO_library_path_explode(root, dir, &group, NULL);
+ const bool is_lib = BLO_library_path_explode(root, dir, &group, nullptr);
if (!is_lib) {
return 0;
}
- const bool group_came_from_path = group != NULL;
+ const bool group_came_from_path = group != nullptr;
/* Try read from indexer_runtime. */
/* Indexing returns all entries in a blend file. We should ignore the index when listing a group
@@ -3269,23 +3149,23 @@ static int filelist_readjob_list_lib(const char *root,
* Adding support for partial reading/updating indexes would increase the complexity.
*/
const bool use_indexer = !group_came_from_path;
- FileIndexerEntries indexer_entries = {NULL};
+ FileIndexerEntries indexer_entries = {nullptr};
if (use_indexer) {
int read_from_index = 0;
eFileIndexerResult indexer_result = indexer_runtime->callbacks->read_index(
dir, &indexer_entries, &read_from_index, indexer_runtime->user_data);
if (indexer_result == FILE_INDEXER_ENTRIES_LOADED) {
int entries_read = filelist_readjob_list_lib_populate_from_index(
- entries, options, read_from_index, &indexer_entries);
+ filelist, entries, options, read_from_index, &indexer_entries);
ED_file_indexer_entries_clear(&indexer_entries);
return entries_read;
}
}
/* Open the library file. */
- BlendFileReadReport bf_reports = {.reports = NULL};
+ BlendFileReadReport bf_reports{};
libfiledata = BLO_blendhandle_from_file(dir, &bf_reports);
- if (libfiledata == NULL) {
+ if (libfiledata == nullptr) {
return 0;
}
@@ -3306,7 +3186,8 @@ static int filelist_readjob_list_lib(const char *root,
const int idcode = groupname_to_code(group);
LinkNode *datablock_infos = BLO_blendhandle_get_datablock_info(
libfiledata, idcode, options & LIST_LIB_ASSETS_ONLY, &datablock_len);
- filelist_readjob_list_lib_add_datablocks(entries, datablock_infos, false, idcode, group);
+ filelist_readjob_list_lib_add_datablocks(
+ filelist, entries, datablock_infos, false, idcode, group);
BLI_linklist_freeN(datablock_infos);
}
else {
@@ -3314,7 +3195,7 @@ static int filelist_readjob_list_lib(const char *root,
group_len = BLI_linklist_count(groups);
for (LinkNode *ln = groups; ln; ln = ln->next) {
- const char *group_name = ln->link;
+ const char *group_name = static_cast<char *>(ln->link);
const int idcode = groupname_to_code(group_name);
FileListInternEntry *group_entry = filelist_readjob_list_lib_group_create(idcode,
group_name);
@@ -3325,7 +3206,7 @@ static int filelist_readjob_list_lib(const char *root,
LinkNode *group_datablock_infos = BLO_blendhandle_get_datablock_info(
libfiledata, idcode, options & LIST_LIB_ASSETS_ONLY, &group_datablock_len);
filelist_readjob_list_lib_add_datablocks(
- entries, group_datablock_infos, true, idcode, group_name);
+ filelist, entries, group_datablock_infos, true, idcode, group_name);
if (use_indexer) {
ED_file_indexer_entries_extend_from_datablock_infos(
&indexer_entries, group_datablock_infos, idcode);
@@ -3358,13 +3239,13 @@ static int filelist_readjob_list_lib(const char *root,
static void filelist_readjob_main_recursive(Main *bmain, FileList *filelist)
{
ID *id;
- FileDirEntry *files, *firstlib = NULL;
+ FileDirEntry *files, *firstlib = nullptr;
ListBase *lb;
int a, fake, idcode, ok, totlib, totbl;
// filelist->type = FILE_MAIN; /* XXX TODO: add modes to file-browser */
- BLI_assert(filelist->filelist.entries == NULL);
+ BLI_assert(filelist->filelist.entries == nullptr);
if (filelist->filelist.root[0] == '/') {
filelist->filelist.root[0] = '\0';
@@ -3425,7 +3306,7 @@ static void filelist_readjob_main_recursive(Main *bmain, FileList *filelist)
idcode = groupname_to_code(filelist->filelist.root);
lb = which_libbase(bmain, idcode);
- if (lb == NULL) {
+ if (lb == nullptr) {
return;
}
@@ -3524,11 +3405,11 @@ static void filelist_readjob_main_recursive(Main *bmain, FileList *filelist)
}
#endif
-typedef struct FileListReadJob {
+struct FileListReadJob {
ThreadMutex lock;
char main_name[FILE_MAX];
Main *current_main;
- struct FileList *filelist;
+ FileList *filelist;
/** Set to request a partial read that only adds files representing #Main data (IDs). Used when
* #Main may have received changes of interest (e.g. asset removed or renamed). */
bool only_main_data;
@@ -3542,14 +3423,14 @@ typedef struct FileListReadJob {
* and moved to #filelist once all categories are loaded.
*
* NOTE: #tmp_filelist is freed in #filelist_readjob_free, so any copied pointers need to be
- * set to NULL to avoid double-freeing them. */
- struct FileList *tmp_filelist;
-} FileListReadJob;
+ * set to nullptr to avoid double-freeing them. */
+ FileList *tmp_filelist;
+};
static void filelist_readjob_append_entries(FileListReadJob *job_params,
ListBase *from_entries,
int from_entries_num,
- short *do_update)
+ bool *do_update)
{
BLI_assert(BLI_listbase_count(from_entries) == from_entries_num);
if (from_entries_num <= 0) {
@@ -3604,12 +3485,12 @@ static bool filelist_readjob_should_recurse_into_entry(const int max_recursion,
static void filelist_readjob_recursive_dir_add_items(const bool do_lib,
FileListReadJob *job_params,
- const short *stop,
- short *do_update,
+ const bool *stop,
+ bool *do_update,
float *progress)
{
FileList *filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */
- ListBase entries = {0};
+ ListBase entries = {nullptr};
BLI_Stack *todo_dirs;
TodoDir *td_dir;
char dir[FILE_MAX_LIBEXTRA];
@@ -3619,23 +3500,23 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib,
int dirs_done_count = 0, dirs_todo_count = 1;
todo_dirs = BLI_stack_new(sizeof(*td_dir), __func__);
- td_dir = BLI_stack_push_r(todo_dirs);
+ td_dir = static_cast<TodoDir *>(BLI_stack_push_r(todo_dirs));
td_dir->level = 1;
BLI_strncpy(dir, filelist->filelist.root, sizeof(dir));
BLI_strncpy(filter_glob, filelist->filter_data.filter_glob, sizeof(filter_glob));
- BLI_path_normalize_dir(job_params->main_name, dir);
+ BLI_path_normalize_dir(job_params->main_name, dir, sizeof(dir));
td_dir->dir = BLI_strdup(dir);
/* Init the file indexer. */
- FileIndexer indexer_runtime = {.callbacks = filelist->indexer};
+ FileIndexer indexer_runtime{};
+ indexer_runtime.callbacks = filelist->indexer;
if (indexer_runtime.callbacks->init_user_data) {
indexer_runtime.user_data = indexer_runtime.callbacks->init_user_data(dir, sizeof(dir));
}
while (!BLI_stack_is_empty(todo_dirs) && !(*stop)) {
- FileListInternEntry *entry;
int entries_num = 0;
char *subdir;
@@ -3643,7 +3524,7 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib,
int recursion_level;
bool skip_currpar;
- td_dir = BLI_stack_peek(todo_dirs);
+ td_dir = static_cast<TodoDir *>(BLI_stack_peek(todo_dirs));
subdir = td_dir->dir;
recursion_level = td_dir->level;
skip_currpar = (recursion_level > 1);
@@ -3656,12 +3537,12 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib,
* Note that in the end, this means we 'cache' valid relative subdir once here,
* this is actually better. */
BLI_strncpy(rel_subdir, subdir, sizeof(rel_subdir));
- BLI_path_normalize_dir(root, rel_subdir);
+ BLI_path_normalize_dir(root, rel_subdir, sizeof(rel_subdir));
BLI_path_rel(rel_subdir, root);
bool is_lib = false;
if (do_lib) {
- ListLibOptions list_lib_options = 0;
+ ListLibOptions list_lib_options = LIST_LIB_OPTION_NONE;
if (!skip_currpar) {
list_lib_options |= LIST_LIB_ADD_PARENT;
}
@@ -3677,7 +3558,7 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib,
list_lib_options |= LIST_LIB_ASSETS_ONLY;
}
entries_num = filelist_readjob_list_lib(
- subdir, &entries, list_lib_options, &indexer_runtime);
+ filelist, subdir, &entries, list_lib_options, &indexer_runtime);
if (entries_num > 0) {
is_lib = true;
}
@@ -3688,24 +3569,26 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib,
subdir, &entries, filter_glob, do_lib, job_params->main_name, skip_currpar);
}
- for (entry = entries.first; entry; entry = entry->next) {
+ LISTBASE_FOREACH (FileListInternEntry *, entry, &entries) {
entry->uid = filelist_uid_generate(filelist);
- /* When loading entries recursive, the rel_path should be relative from the root dir.
- * we combine the relative path to the subdir with the relative path of the entry. */
- BLI_join_dirfile(dir, sizeof(dir), rel_subdir, entry->relpath);
+ /* When loading entries recursive, the `rel_path` should be relative from the root dir.
+ * we combine the relative path to the `subdir` with the relative path of the entry.
+ * Using #BLI_path_join works but isn't needed as `rel_subdir` has a trailing slash. */
+ BLI_string_join(dir, sizeof(dir), rel_subdir, entry->relpath);
MEM_freeN(entry->relpath);
entry->relpath = BLI_strdup(dir + 2); /* + 2 to remove '//'
* added by BLI_path_rel to rel_subdir. */
- entry->name = fileentry_uiname(root, entry->relpath, entry->typeflag, dir);
+ entry->name = fileentry_uiname(root, entry, dir);
entry->free_name = true;
if (filelist_readjob_should_recurse_into_entry(
max_recursion, is_lib, recursion_level, entry)) {
- /* We have a directory we want to list, add it to todo list! */
- BLI_join_dirfile(dir, sizeof(dir), root, entry->relpath);
- BLI_path_normalize_dir(job_params->main_name, dir);
- td_dir = BLI_stack_push_r(todo_dirs);
+ /* We have a directory we want to list, add it to todo list!
+ * Using #BLI_path_join works but isn't needed as `root` has a trailing slash. */
+ BLI_string_join(dir, sizeof(dir), root, entry->relpath);
+ BLI_path_normalize_dir(job_params->main_name, dir, sizeof(dir));
+ td_dir = static_cast<TodoDir *>(BLI_stack_push_r(todo_dirs));
td_dir->level = recursion_level + 1;
td_dir->dir = BLI_strdup(dir);
dirs_todo_count++;
@@ -3715,7 +3598,7 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib,
filelist_readjob_append_entries(job_params, &entries, entries_num, do_update);
dirs_done_count++;
- *progress = (float)dirs_done_count / (float)dirs_todo_count;
+ *progress = float(dirs_done_count) / float(dirs_todo_count);
MEM_freeN(subdir);
}
@@ -3725,13 +3608,13 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib,
}
if (indexer_runtime.callbacks->free_user_data && indexer_runtime.user_data) {
indexer_runtime.callbacks->free_user_data(indexer_runtime.user_data);
- indexer_runtime.user_data = NULL;
+ indexer_runtime.user_data = nullptr;
}
/* If we were interrupted by stop, stack may not be empty and we need to free
* pending dir paths. */
while (!BLI_stack_is_empty(todo_dirs)) {
- td_dir = BLI_stack_peek(todo_dirs);
+ td_dir = static_cast<TodoDir *>(BLI_stack_peek(todo_dirs));
MEM_freeN(td_dir->dir);
BLI_stack_discard(todo_dirs);
}
@@ -3740,13 +3623,13 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib,
static void filelist_readjob_do(const bool do_lib,
FileListReadJob *job_params,
- const short *stop,
- short *do_update,
+ const bool *stop,
+ bool *do_update,
float *progress)
{
FileList *filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */
- // BLI_assert(filelist->filtered == NULL);
+ // BLI_assert(filelist->filtered == nullptr);
BLI_assert(BLI_listbase_is_empty(&filelist->filelist.entries) &&
(filelist->filelist.entries_num == FILEDIR_NBR_ENTRIES_UNSET));
@@ -3757,65 +3640,49 @@ static void filelist_readjob_do(const bool do_lib,
}
static void filelist_readjob_dir(FileListReadJob *job_params,
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress)
{
filelist_readjob_do(false, job_params, stop, do_update, progress);
}
static void filelist_readjob_lib(FileListReadJob *job_params,
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress)
{
filelist_readjob_do(true, job_params, stop, do_update, progress);
}
-static void filelist_asset_library_path(const FileListReadJob *job_params,
- char r_library_root_path[FILE_MAX])
-{
- if (job_params->filelist->type == FILE_MAIN_ASSET) {
- /* For the "Current File" library (#FILE_MAIN_ASSET) we get the asset library root path based
- * on main. */
- BKE_asset_library_find_suitable_root_path_from_main(job_params->current_main,
- r_library_root_path);
- }
- else {
- BLI_strncpy(r_library_root_path, job_params->tmp_filelist->filelist.root, FILE_MAX);
- }
-}
-
/**
* Load asset library data, which currently means loading the asset catalogs for the library.
*/
-static void filelist_readjob_load_asset_library_data(FileListReadJob *job_params, short *do_update)
+static void filelist_readjob_load_asset_library_data(FileListReadJob *job_params, bool *do_update)
{
FileList *tmp_filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */
*do_update = false;
- if (job_params->filelist->asset_library_ref == NULL) {
+ if (job_params->filelist->asset_library_ref == nullptr) {
return;
}
- if (tmp_filelist->asset_library != NULL) {
+ if (tmp_filelist->asset_library != nullptr) {
/* Asset library already loaded. */
return;
}
- char library_root_path[FILE_MAX];
- filelist_asset_library_path(job_params, library_root_path);
-
/* Load asset catalogs, into the temp filelist for thread-safety.
* #filelist_readjob_endjob() will move it into the real filelist. */
- tmp_filelist->asset_library = BKE_asset_library_load(library_root_path);
+ tmp_filelist->asset_library = BKE_asset_library_load(job_params->current_main,
+ *job_params->filelist->asset_library_ref);
*do_update = true;
}
static void filelist_readjob_main_assets_add_items(FileListReadJob *job_params,
- short *UNUSED(stop),
- short *do_update,
- float *UNUSED(progress))
+ bool * /*stop*/,
+ bool *do_update,
+ float * /*progress*/)
{
FileList *filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */
@@ -3835,7 +3702,7 @@ static void filelist_readjob_main_assets_add_items(FileListReadJob *job_params,
const char *id_code_name = BKE_idtype_idcode_to_name(GS(id_iter->name));
- entry = MEM_callocN(sizeof(*entry), __func__);
+ entry = MEM_cnew<FileListInternEntry>(__func__);
entry->relpath = BLI_strdup(id_code_name);
entry->name = id_iter->name + 2;
entry->free_name = false;
@@ -3845,6 +3712,9 @@ static void filelist_readjob_main_assets_add_items(FileListReadJob *job_params,
entry->local_data.preview_image = BKE_asset_metadata_preview_get_from_id(id_iter->asset_data,
id_iter);
entry->local_data.id = id_iter;
+ if (filelist->asset_library) {
+ entry->asset = &filelist->asset_library->add_local_id_asset(*id_iter);
+ }
entries_num++;
BLI_addtail(&tmp_entries, entry);
}
@@ -3875,8 +3745,8 @@ static bool filelist_contains_main(const FileList *filelist, const Main *bmain)
}
static void filelist_readjob_asset_library(FileListReadJob *job_params,
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress)
{
FileList *filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */
@@ -3899,8 +3769,8 @@ static void filelist_readjob_asset_library(FileListReadJob *job_params,
}
static void filelist_readjob_main(FileListReadJob *job_params,
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress)
{
/* TODO! */
@@ -3908,8 +3778,8 @@ static void filelist_readjob_main(FileListReadJob *job_params,
}
static void filelist_readjob_main_assets(FileListReadJob *job_params,
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress)
{
FileList *filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */
@@ -3937,23 +3807,23 @@ static bool filelist_readjob_is_partial_read(const FileListReadJob *read_job)
* some current entries are kept and we just call the readjob to update the main files (see
* #FileListReadJob.only_main_data).
*/
-static void filelist_readjob_startjob(void *flrjv, short *stop, short *do_update, float *progress)
+static void filelist_readjob_startjob(void *flrjv, bool *stop, bool *do_update, float *progress)
{
- FileListReadJob *flrj = flrjv;
+ FileListReadJob *flrj = static_cast<FileListReadJob *>(flrjv);
// printf("START filelist reading (%d files, main thread: %d)\n",
// flrj->filelist->filelist.entries_num, BLI_thread_is_main());
BLI_mutex_lock(&flrj->lock);
- BLI_assert((flrj->tmp_filelist == NULL) && flrj->filelist);
+ BLI_assert((flrj->tmp_filelist == nullptr) && flrj->filelist);
- flrj->tmp_filelist = MEM_dupallocN(flrj->filelist);
+ flrj->tmp_filelist = static_cast<FileList *>(MEM_dupallocN(flrj->filelist));
BLI_listbase_clear(&flrj->tmp_filelist->filelist.entries);
flrj->tmp_filelist->filelist.entries_num = FILEDIR_NBR_ENTRIES_UNSET;
- flrj->tmp_filelist->filelist_intern.filtered = NULL;
+ flrj->tmp_filelist->filelist_intern.filtered = nullptr;
BLI_listbase_clear(&flrj->tmp_filelist->filelist_intern.entries);
if (filelist_readjob_is_partial_read(flrj)) {
/* Don't unset the current UID on partial read, would give duplicates otherwise. */
@@ -3962,11 +3832,11 @@ static void filelist_readjob_startjob(void *flrjv, short *stop, short *do_update
filelist_uid_unset(&flrj->tmp_filelist->filelist_intern.curr_uid);
}
- flrj->tmp_filelist->libfiledata = NULL;
+ flrj->tmp_filelist->libfiledata = nullptr;
memset(&flrj->tmp_filelist->filelist_cache, 0, sizeof(flrj->tmp_filelist->filelist_cache));
- flrj->tmp_filelist->selection_state = NULL;
- flrj->tmp_filelist->asset_library_ref = NULL;
- flrj->tmp_filelist->filter_data.asset_catalog_filter = NULL;
+ flrj->tmp_filelist->selection_state = nullptr;
+ flrj->tmp_filelist->asset_library_ref = nullptr;
+ flrj->tmp_filelist->filter_data.asset_catalog_filter = nullptr;
BLI_mutex_unlock(&flrj->lock);
@@ -3980,9 +3850,9 @@ static void filelist_readjob_startjob(void *flrjv, short *stop, short *do_update
*/
static void filelist_readjob_update(void *flrjv)
{
- FileListReadJob *flrj = flrjv;
+ FileListReadJob *flrj = static_cast<FileListReadJob *>(flrjv);
FileListIntern *fl_intern = &flrj->filelist->filelist_intern;
- ListBase new_entries = {NULL};
+ ListBase new_entries = {nullptr};
int entries_num, new_entries_num = 0;
BLI_movelisttolist(&new_entries, &fl_intern->entries);
@@ -4023,7 +3893,7 @@ static void filelist_readjob_update(void *flrjv)
static void filelist_readjob_endjob(void *flrjv)
{
- FileListReadJob *flrj = flrjv;
+ FileListReadJob *flrj = static_cast<FileListReadJob *>(flrjv);
/* In case there would be some dangling update... */
filelist_readjob_update(flrjv);
@@ -4034,7 +3904,7 @@ static void filelist_readjob_endjob(void *flrjv)
static void filelist_readjob_free(void *flrjv)
{
- FileListReadJob *flrj = flrjv;
+ FileListReadJob *flrj = static_cast<FileListReadJob *>(flrjv);
// printf("END filelist reading (%d files)\n", flrj->filelist->filelist.entries_num);
@@ -4064,7 +3934,7 @@ void filelist_readjob_start(FileList *filelist, const int space_notifier, const
}
/* prepare job data */
- flrj = MEM_callocN(sizeof(*flrj), __func__);
+ flrj = MEM_cnew<FileListReadJob>(__func__);
flrj->filelist = filelist;
flrj->current_main = bmain;
BLI_strncpy(flrj->main_name, BKE_main_blendfile_path(bmain), sizeof(flrj->main_name));
@@ -4085,8 +3955,8 @@ void filelist_readjob_start(FileList *filelist, const int space_notifier, const
const bool no_threads = (filelist->tags & FILELIST_TAGS_NO_THREADS) || flrj->only_main_data;
if (no_threads) {
- short dummy_stop = false;
- short dummy_do_update = false;
+ bool dummy_stop = false;
+ bool dummy_do_update = false;
float dummy_progress = 0.0f;
/* Single threaded execution. Just directly call the callbacks. */
@@ -4094,7 +3964,7 @@ void filelist_readjob_start(FileList *filelist, const int space_notifier, const
filelist_readjob_endjob(flrj);
filelist_readjob_free(flrj);
- WM_event_add_notifier(C, space_notifier | NA_JOB_FINISHED, NULL);
+ WM_event_add_notifier(C, space_notifier | NA_JOB_FINISHED, nullptr);
return;
}
@@ -4107,8 +3977,11 @@ void filelist_readjob_start(FileList *filelist, const int space_notifier, const
WM_JOB_TYPE_FILESEL_READDIR);
WM_jobs_customdata_set(wm_job, flrj, filelist_readjob_free);
WM_jobs_timer(wm_job, 0.01, space_notifier, space_notifier | NA_JOB_FINISHED);
- WM_jobs_callbacks(
- wm_job, filelist_readjob_startjob, NULL, filelist_readjob_update, filelist_readjob_endjob);
+ WM_jobs_callbacks(wm_job,
+ filelist_readjob_startjob,
+ nullptr,
+ filelist_readjob_update,
+ filelist_readjob_endjob);
/* start the job */
WM_jobs_start(CTX_wm_manager(C), wm_job);
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index d8297226a8d..419528f0fb8 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -35,17 +35,6 @@ typedef enum FileCheckType {
CHECK_ALL = 3,
} FileCheckType;
-/* not listbase itself */
-void folderlist_free(struct ListBase *folderlist);
-void folderlist_popdir(struct ListBase *folderlist, char *dir);
-void folderlist_pushdir(struct ListBase *folderlist, const char *dir);
-const char *folderlist_peeklastdir(struct ListBase *folderlist);
-int folderlist_clear_next(struct SpaceFile *sfile);
-
-void folder_history_list_ensure_for_active_browse_mode(struct SpaceFile *sfile);
-void folder_history_list_free(struct SpaceFile *sfile);
-struct ListBase folder_history_list_duplicate(struct ListBase *listbase);
-
void filelist_setsorting(struct FileList *filelist, short sort, bool invert_sort);
void filelist_sort(struct FileList *filelist);
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 3409ffd4fff..fa7976cde23 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -197,7 +197,7 @@ static FileSelectParams *fileselect_ensure_updated_file_params(SpaceFile *sfile)
}
if (params->dir[0]) {
- BLI_path_normalize_dir(blendfile_path, params->dir);
+ BLI_path_normalize_dir(blendfile_path, params->dir, sizeof(params->dir));
BLI_path_abs(params->dir, blendfile_path);
}
@@ -665,12 +665,17 @@ void ED_fileselect_params_to_userdef(SpaceFile *sfile,
}
}
-void fileselect_file_set(SpaceFile *sfile, const int index)
+void fileselect_file_set(struct bContext *C, SpaceFile *sfile, const int index)
{
const struct FileDirEntry *file = filelist_file(sfile->files, index);
if (file && file->relpath && file->relpath[0] && !(file->typeflag & FILE_TYPE_DIR)) {
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
BLI_strncpy(params->file, file->relpath, FILE_MAXFILE);
+ if (sfile->op) {
+ /* Update the filepath properties of the operator. */
+ Main *bmain = CTX_data_main(C);
+ file_sfile_to_operator(C, bmain, sfile->op, sfile);
+ }
}
}
@@ -690,14 +695,14 @@ int ED_fileselect_layout_numfiles(FileLayout *layout, ARegion *region)
*/
if (layout->flag & FILE_LAYOUT_HOR) {
const int x_item = layout->tile_w + (2 * layout->tile_border_x);
- const int x_view = (int)(BLI_rctf_size_x(&region->v2d.cur));
+ const int x_view = (int)BLI_rctf_size_x(&region->v2d.cur);
const int x_over = x_item - (x_view % x_item);
numfiles = (int)((float)(x_view + x_over) / (float)(x_item));
return numfiles * layout->rows;
}
const int y_item = layout->tile_h + (2 * layout->tile_border_y);
- const int y_view = (int)(BLI_rctf_size_y(&region->v2d.cur)) - layout->offset_top;
+ const int y_view = (int)BLI_rctf_size_y(&region->v2d.cur) - layout->offset_top;
const int y_over = y_item - (y_view % y_item);
numfiles = (int)((float)(y_view + y_over) / (float)(y_item));
return numfiles * layout->flow_columns;
@@ -1041,7 +1046,7 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *region)
layout->attribute_column_header_h = 0;
layout->offset_top = layout->attribute_column_header_h;
layout->height = (int)(BLI_rctf_size_y(&v2d->cur) - 2 * layout->tile_border_y);
- /* Padding by full scrollbar H is too much, can overlap tile border Y. */
+ /* Padding by full scroll-bar H is too much, can overlap tile border Y. */
layout->rows = (layout->height - V2D_SCROLL_HEIGHT + layout->tile_border_y) /
(layout->tile_h + 2 * layout->tile_border_y);
layout->tile_w = VERTLIST_MAJORCOLUMN_WIDTH;
@@ -1169,7 +1174,7 @@ int autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v))
char path[FILE_MAX];
BLI_stat_t status;
- BLI_join_dirfile(path, sizeof(path), dirname, de->d_name);
+ BLI_path_join(path, sizeof(path), dirname, de->d_name);
if (BLI_stat(path, &status) == 0) {
if (S_ISDIR(status.st_mode)) { /* is subdir */
@@ -1182,7 +1187,7 @@ int autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v))
match = UI_autocomplete_end(autocpl, str);
if (match == AUTOCOMPLETE_FULL_MATCH) {
- BLI_path_slash_ensure(str);
+ BLI_path_slash_ensure(str, FILE_MAX);
}
}
}
diff --git a/source/blender/editors/space_file/folder_history.cc b/source/blender/editors/space_file/folder_history.cc
new file mode 100644
index 00000000000..8f44c0aa08a
--- /dev/null
+++ b/source/blender/editors/space_file/folder_history.cc
@@ -0,0 +1,199 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2007 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup spfile
+ *
+ * Storage for a list of folders for history backward and forward navigation.
+ */
+
+#include <cstring>
+
+#include "BLI_listbase.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+
+#include "BKE_context.h"
+
+#include "DNA_space_types.h"
+
+#include "ED_fileselect.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "file_intern.h"
+
+/* -------------------------------------------------------------------- */
+/** \name FOLDERLIST (previous/next)
+ * \{ */
+
+struct FolderList {
+ FolderList *next, *prev;
+ char *foldername;
+};
+
+void folderlist_popdir(struct ListBase *folderlist, char *dir)
+{
+ const char *prev_dir;
+ FolderList *folder;
+ folder = static_cast<FolderList *>(folderlist->last);
+
+ if (folder) {
+ /* remove the current directory */
+ MEM_freeN(folder->foldername);
+ BLI_freelinkN(folderlist, folder);
+
+ folder = static_cast<FolderList *>(folderlist->last);
+ if (folder) {
+ prev_dir = folder->foldername;
+ BLI_strncpy(dir, prev_dir, FILE_MAXDIR);
+ }
+ }
+ /* Delete the folder next or use set-directory directly before PREVIOUS OP. */
+}
+
+void folderlist_pushdir(ListBase *folderlist, const char *dir)
+{
+ if (!dir[0]) {
+ return;
+ }
+
+ FolderList *folder, *previous_folder;
+ previous_folder = static_cast<FolderList *>(folderlist->last);
+
+ /* check if already exists */
+ if (previous_folder && previous_folder->foldername) {
+ if (BLI_path_cmp(previous_folder->foldername, dir) == 0) {
+ return;
+ }
+ }
+
+ /* create next folder element */
+ folder = MEM_new<FolderList>(__func__);
+ folder->foldername = BLI_strdup(dir);
+
+ /* add it to the end of the list */
+ BLI_addtail(folderlist, folder);
+}
+
+const char *folderlist_peeklastdir(ListBase *folderlist)
+{
+ FolderList *folder;
+
+ if (!folderlist->last) {
+ return nullptr;
+ }
+
+ folder = static_cast<FolderList *>(folderlist->last);
+ return folder->foldername;
+}
+
+bool folderlist_clear_next(struct SpaceFile *sfile)
+{
+ const FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+ FolderList *folder;
+
+ /* if there is no folder_next there is nothing we can clear */
+ if (BLI_listbase_is_empty(sfile->folders_next)) {
+ return false;
+ }
+
+ /* if previous_folder, next_folder or refresh_folder operators are executed
+ * it doesn't clear folder_next */
+ folder = static_cast<FolderList *>(sfile->folders_prev->last);
+ if ((!folder) || (BLI_path_cmp(folder->foldername, params->dir) == 0)) {
+ return false;
+ }
+
+ /* eventually clear flist->folders_next */
+ return true;
+}
+
+void folderlist_free(ListBase *folderlist)
+{
+ if (folderlist) {
+ LISTBASE_FOREACH (FolderList *, folder, folderlist) {
+ MEM_freeN(folder->foldername);
+ }
+ BLI_freelistN(folderlist);
+ }
+}
+
+static ListBase folderlist_duplicate(ListBase *folderlist)
+{
+ ListBase folderlistn = {nullptr};
+
+ BLI_duplicatelist(&folderlistn, folderlist);
+
+ LISTBASE_FOREACH (FolderList *, folder, &folderlistn) {
+ folder->foldername = (char *)MEM_dupallocN(folder->foldername);
+ }
+ return folderlistn;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Folder-History (wraps/owns file list above)
+ * \{ */
+
+static FileFolderHistory *folder_history_find(const SpaceFile *sfile, eFileBrowse_Mode browse_mode)
+{
+ LISTBASE_FOREACH (FileFolderHistory *, history, &sfile->folder_histories) {
+ if (history->browse_mode == browse_mode) {
+ return history;
+ }
+ }
+
+ return nullptr;
+}
+
+void folder_history_list_ensure_for_active_browse_mode(SpaceFile *sfile)
+{
+ FileFolderHistory *history = folder_history_find(sfile, (eFileBrowse_Mode)sfile->browse_mode);
+
+ if (!history) {
+ history = MEM_cnew<FileFolderHistory>(__func__);
+ history->browse_mode = sfile->browse_mode;
+ BLI_addtail(&sfile->folder_histories, history);
+ }
+
+ sfile->folders_next = &history->folders_next;
+ sfile->folders_prev = &history->folders_prev;
+}
+
+static void folder_history_entry_free(SpaceFile *sfile, FileFolderHistory *history)
+{
+ if (sfile->folders_prev == &history->folders_prev) {
+ sfile->folders_prev = nullptr;
+ }
+ if (sfile->folders_next == &history->folders_next) {
+ sfile->folders_next = nullptr;
+ }
+ folderlist_free(&history->folders_prev);
+ folderlist_free(&history->folders_next);
+ BLI_freelinkN(&sfile->folder_histories, history);
+}
+
+void folder_history_list_free(SpaceFile *sfile)
+{
+ LISTBASE_FOREACH_MUTABLE (FileFolderHistory *, history, &sfile->folder_histories) {
+ folder_history_entry_free(sfile, history);
+ }
+}
+
+ListBase folder_history_list_duplicate(ListBase *listbase)
+{
+ ListBase histories = {nullptr};
+
+ LISTBASE_FOREACH (FileFolderHistory *, history, listbase) {
+ FileFolderHistory *history_new = static_cast<FileFolderHistory *>(MEM_dupallocN(history));
+ history_new->folders_prev = folderlist_duplicate(&history->folders_prev);
+ history_new->folders_next = folderlist_duplicate(&history->folders_next);
+ BLI_addtail(&histories, history_new);
+ }
+
+ return histories;
+}
+
+/** \} */
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index 35ce7ef364c..959f8b01ec8 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -113,10 +113,10 @@ static GHash *fsmenu_xdg_user_dirs_parse(const char *home)
char filepath[FILE_MAX];
const char *xdg_config_home = getenv("XDG_CONFIG_HOME");
if (xdg_config_home != NULL) {
- BLI_path_join(filepath, sizeof(filepath), xdg_config_home, "user-dirs.dirs", NULL);
+ BLI_path_join(filepath, sizeof(filepath), xdg_config_home, "user-dirs.dirs");
}
else {
- BLI_path_join(filepath, sizeof(filepath), home, ".config", "user-dirs.dirs", NULL);
+ BLI_path_join(filepath, sizeof(filepath), home, ".config", "user-dirs.dirs");
}
fp = BLI_fopen(filepath, "r");
if (!fp) {
@@ -147,7 +147,7 @@ static GHash *fsmenu_xdg_user_dirs_parse(const char *home)
* Based on the 'user-dirs.dirs' man page,
* there is no need to resolve arbitrary environment variables. */
if (STRPREFIX(l_value, "$HOME" SEP_STR)) {
- BLI_path_join(l_value_expanded, sizeof(l_value_expanded), home, l_value + 6, NULL);
+ BLI_path_join(l_value_expanded, sizeof(l_value_expanded), home, l_value + 6);
l_value_final = l_value_expanded;
}
@@ -186,7 +186,7 @@ static void fsmenu_xdg_insert_entry(GHash *xdg_map,
char xdg_path_buf[FILE_MAXDIR];
const char *xdg_path = xdg_map ? BLI_ghash_lookup(xdg_map, key) : NULL;
if (xdg_path == NULL) {
- BLI_path_join(xdg_path_buf, sizeof(xdg_path_buf), home, default_path, NULL);
+ BLI_path_join(xdg_path_buf, sizeof(xdg_path_buf), home, default_path);
xdg_path = xdg_path_buf;
}
fsmenu_insert_entry(
@@ -254,10 +254,10 @@ void ED_fsmenu_entry_set_path(struct FSMenuEntry *fsentry, const char *path)
fsentry->path = (path && path[0]) ? BLI_strdup(path) : NULL;
- BLI_join_dirfile(tmp_name,
- sizeof(tmp_name),
- BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL),
- BLENDER_BOOKMARK_FILE);
+ BLI_path_join(tmp_name,
+ sizeof(tmp_name),
+ BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL),
+ BLENDER_BOOKMARK_FILE);
fsmenu_write_file(ED_fsmenu_get(), tmp_name);
}
}
@@ -318,10 +318,10 @@ void ED_fsmenu_entry_set_name(struct FSMenuEntry *fsentry, const char *name)
BLI_strncpy(fsentry->name, name, sizeof(fsentry->name));
}
- BLI_join_dirfile(tmp_name,
- sizeof(tmp_name),
- BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL),
- BLENDER_BOOKMARK_FILE);
+ BLI_path_join(tmp_name,
+ sizeof(tmp_name),
+ BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL),
+ BLENDER_BOOKMARK_FILE);
fsmenu_write_file(ED_fsmenu_get(), tmp_name);
}
}
@@ -983,7 +983,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
if (xdg_runtime_dir != NULL) {
struct direntry *dirs;
char name[FILE_MAX];
- BLI_join_dirfile(name, sizeof(name), xdg_runtime_dir, "gvfs/");
+ BLI_path_join(name, sizeof(name), xdg_runtime_dir, "gvfs/");
const uint dirs_num = BLI_filelist_dir_contents(name, &dirs);
for (uint i = 0; i < dirs_num; i++) {
if (dirs[i].type & S_IFDIR) {
@@ -1147,8 +1147,8 @@ static void fsmenu_bookmark_validate_job_startjob(
void *fsmenuv,
/* Cannot be const, this function implements wm_jobs_start_callback.
* NOLINTNEXTLINE: readability-non-const-parameter. */
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *UNUSED(progress))
{
FSMenu *fsmenu = fsmenuv;
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index bba0c27bb4d..95b87f06d96 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -41,6 +41,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "BLO_read_write.h"
+
#include "GPU_framebuffer.h"
#include "file_indexer.h"
#include "file_intern.h" /* own include */
@@ -948,7 +950,7 @@ static int /*eContextResult*/ file_context(const bContext *C,
for (int file_index = 0; file_index < num_files_filtered; file_index++) {
if (filelist_entry_is_selected(sfile->files, file_index)) {
FileDirEntry *entry = filelist_file(sfile->files, file_index);
- if (entry->asset_data) {
+ if (entry->asset) {
CTX_data_list_add(result, &screen->id, &RNA_FileSelectEntry, entry);
}
}
@@ -986,6 +988,52 @@ static void file_id_remap(ScrArea *area, SpaceLink *sl, const struct IDRemapper
file_reset_filelist_showing_main_data(area, sfile);
}
+static void file_blend_read_data(BlendDataReader *reader, SpaceLink *sl)
+{
+ SpaceFile *sfile = (SpaceFile *)sl;
+
+ /* this sort of info is probably irrelevant for reloading...
+ * plus, it isn't saved to files yet!
+ */
+ sfile->folders_prev = sfile->folders_next = NULL;
+ BLI_listbase_clear(&sfile->folder_histories);
+ sfile->files = NULL;
+ sfile->layout = NULL;
+ sfile->op = NULL;
+ sfile->previews_timer = NULL;
+ sfile->tags = 0;
+ sfile->runtime = NULL;
+ BLO_read_data_address(reader, &sfile->params);
+ BLO_read_data_address(reader, &sfile->asset_params);
+ if (sfile->params) {
+ sfile->params->rename_id = NULL;
+ }
+ if (sfile->asset_params) {
+ sfile->asset_params->base_params.rename_id = NULL;
+ }
+}
+
+static void file_blend_read_lib(BlendLibReader *UNUSED(reader),
+ ID *UNUSED(parent_id),
+ SpaceLink *sl)
+{
+ SpaceFile *sfile = (SpaceFile *)sl;
+ sfile->tags |= FILE_TAG_REBUILD_MAIN_FILES;
+}
+
+static void file_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ SpaceFile *sfile = (SpaceFile *)sl;
+
+ BLO_write_struct(writer, SpaceFile, sl);
+ if (sfile->params) {
+ BLO_write_struct(writer, FileSelectParams, sfile->params);
+ }
+ if (sfile->asset_params) {
+ BLO_write_struct(writer, FileAssetSelectParams, sfile->asset_params);
+ }
+}
+
void ED_spacetype_file(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype file");
@@ -1009,6 +1057,9 @@ void ED_spacetype_file(void)
st->space_subtype_set = file_space_subtype_set;
st->context = file_context;
st->id_remap = file_id_remap;
+ st->blend_read_data = file_blend_read_data;
+ st->blend_read_lib = file_blend_read_lib;
+ st->blend_write = file_blend_write;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype file region");
@@ -1106,7 +1157,7 @@ void ED_file_read_bookmarks(void)
if (cfgdir) {
char name[FILE_MAX];
- BLI_join_dirfile(name, sizeof(name), cfgdir, BLENDER_BOOKMARK_FILE);
+ BLI_path_join(name, sizeof(name), cfgdir, BLENDER_BOOKMARK_FILE);
fsmenu_read_bookmarks(ED_fsmenu_get(), name);
}
}
diff --git a/source/blender/editors/space_graph/CMakeLists.txt b/source/blender/editors/space_graph/CMakeLists.txt
index 39878debc39..f67434b0f6d 100644
--- a/source/blender/editors/space_graph/CMakeLists.txt
+++ b/source/blender/editors/space_graph/CMakeLists.txt
@@ -4,6 +4,7 @@ set(INC
../include
../../blenkernel
../../blenlib
+ ../../blenloader
../../blentranslation
../../depsgraph
../../gpu
@@ -11,6 +12,9 @@ set(INC
../../makesrna
../../windowmanager
../../../../intern/guardedalloc
+
+ # dna_type_offsets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
# RNA_prototypes.h
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
@@ -50,5 +54,5 @@ endif()
blender_add_lib(bf_editor_space_graph "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
-# RNA_prototypes.h
+# RNA_prototypes.h dna_type_offsets.h
add_dependencies(bf_editor_space_graph bf_rna)
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index 2d3b43ec728..8ada6d31a2d 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -641,7 +641,7 @@ static void do_graph_region_driver_buttons(bContext *C, void *id_v, int event)
ID *id = id_v;
AnimData *adt = BKE_animdata_from_id(id);
- /* rebuild depsgraph for the new deps, and ensure COW copies get flushed. */
+ /* Rebuild depsgraph for the new dependencies, and ensure COW copies get flushed. */
DEG_relations_tag_update(bmain);
DEG_id_tag_update_ex(bmain, id, ID_RECALC_COPY_ON_WRITE);
if (adt != NULL) {
@@ -905,6 +905,45 @@ static void graph_panel_driverVar__transChan(uiLayout *layout, ID *id, DriverVar
/* ----------------------------------------------------------------- */
/* property driven by the driver - duplicates Active FCurve, but useful for clarity */
+
+static void graph_draw_driven_property_enabled_btn(uiLayout *layout,
+ ID *id,
+ FCurve *fcu,
+ const char *label)
+{
+ PointerRNA fcurve_ptr;
+ RNA_pointer_create(id, &RNA_FCurve, fcu, &fcurve_ptr);
+
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiDefButR(block,
+ UI_BTYPE_CHECKBOX_N,
+ 0,
+ label,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &fcurve_ptr,
+ "mute",
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Let the driver determine this property's value"));
+}
+
+static void graph_panel_drivers_header(const bContext *C, Panel *panel)
+{
+ bAnimListElem *ale;
+ FCurve *fcu;
+ if (!graph_panel_context(C, &ale, &fcu)) {
+ return;
+ }
+
+ graph_draw_driven_property_enabled_btn(panel->layout, ale->id, fcu, IFACE_("Driver"));
+}
+
static void graph_draw_driven_property_panel(uiLayout *layout, ID *id, FCurve *fcu)
{
PointerRNA fcu_ptr;
@@ -1315,7 +1354,7 @@ static void graph_panel_drivers_popover(const bContext *C, Panel *panel)
uiItemS(layout);
/* Drivers Settings */
- uiItemL(layout, IFACE_("Driver Settings:"), ICON_NONE);
+ graph_draw_driven_property_enabled_btn(panel->layout, id, fcu, IFACE_("Driver:"));
graph_draw_driver_settings_panel(panel->layout, id, fcu, true);
}
}
@@ -1432,6 +1471,7 @@ void graph_buttons_register(ARegionType *art)
strcpy(pt->category, "Drivers");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = graph_panel_drivers;
+ pt->draw_header = graph_panel_drivers_header;
pt->poll = graph_panel_drivers_poll;
BLI_addtail(&art->paneltypes, pt);
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index 41a8368152d..f8a0dff3a41 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -1446,7 +1446,7 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region)
GPU_blend(GPU_BLEND_NONE);
}
- /* free tempolary channels */
+ /* Free temporary channels. */
ANIM_animdata_freelist(&anim_data);
}
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 64a3c603e73..cb01b0d9dc8 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -1448,7 +1448,7 @@ static int graphkeys_expo_exec(bContext *C, wmOperator *op)
void GRAPH_OT_extrapolation_type(wmOperatorType *ot)
{
/* Identifiers */
- ot->name = "Set Keyframe Extrapolation";
+ ot->name = "Set F-Curve Extrapolation";
ot->idname = "GRAPH_OT_extrapolation_type";
ot->description = "Set extrapolation mode for selected F-Curves";
@@ -1771,7 +1771,7 @@ static ListBase /*tEulerFilter*/ euler_filter_group_channels(
* so if the paths or the ID's don't match up, then a curve needs to be added
* to a new group.
*/
- if ((euf) && (euf->id == ale->id) && (STREQ(euf->rna_path, fcu->rna_path))) {
+ if ((euf) && (euf->id == ale->id) && STREQ(euf->rna_path, fcu->rna_path)) {
/* This should be fine to add to the existing group then. */
euf->fcurves[fcu->array_index] = fcu;
continue;
@@ -2333,6 +2333,48 @@ static int graphkeys_snap_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static bool graph_has_selected_control_points(struct bContext *C)
+{
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+
+ /* Get editor data. */
+ if (ANIM_animdata_get_context(C, &ac) == 0) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Filter data. */
+ const int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY |
+ ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* Check if any of the visible and editable f-curves have at least one selected control point. */
+ bool has_selected_control_points = false;
+ LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
+ const FCurve *fcu = ale->key_data;
+ if (BKE_fcurve_has_selected_control_points(fcu)) {
+ has_selected_control_points = true;
+ break;
+ }
+ }
+
+ ANIM_animdata_freelist(&anim_data);
+
+ return has_selected_control_points;
+}
+
+static int graphkeys_selected_control_points_invoke(struct bContext *C,
+ struct wmOperator *op,
+ const struct wmEvent *event)
+{
+ if (!graph_has_selected_control_points(C)) {
+ BKE_report(op->reports, RPT_ERROR, "No control points are selected");
+ return OPERATOR_CANCELLED;
+ }
+
+ return WM_menu_invoke(C, op, event);
+}
+
void GRAPH_OT_snap(wmOperatorType *ot)
{
/* Identifiers */
@@ -2341,7 +2383,7 @@ void GRAPH_OT_snap(wmOperatorType *ot)
ot->description = "Snap selected keyframes to the chosen times/values";
/* API callbacks */
- ot->invoke = WM_menu_invoke;
+ ot->invoke = graphkeys_selected_control_points_invoke;
ot->exec = graphkeys_snap_exec;
ot->poll = graphop_editable_keyframes_poll;
@@ -2418,7 +2460,7 @@ void GRAPH_OT_equalize_handles(wmOperatorType *ot)
"Ensure selected keyframes' handles have equal length, optionally making them horizontal. "
"Automatic, Automatic Clamped, or Vector handle types will be converted to Aligned";
/* API callbacks */
- ot->invoke = WM_menu_invoke;
+ ot->invoke = graphkeys_selected_control_points_invoke;
ot->exec = graphkeys_equalize_handles_exec;
ot->poll = graphop_editable_keyframes_poll;
@@ -3020,7 +3062,7 @@ static int graph_driver_vars_paste_exec(bContext *C, wmOperator *op)
/* Successful or not? */
if (ok) {
- /* Rebuild depsgraph, now that there are extra deps here. */
+ /* Rebuild depsgraph, now that there are extra dependencies here. */
DEG_relations_tag_update(CTX_data_main(C));
/* Set notifier that keyframes have changed. */
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 0ce3e1a797a..3265dcbf0d1 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -585,7 +585,7 @@ static bool box_select_graphkeys(bAnimContext *ac,
initialize_box_select_key_editing_data(
sipo, incl_handles, mode, ac, data, &scaled_rectf, &ked, &mapping_flag);
- /* Get beztriple editing/validation funcs. */
+ /* Get beztriple editing/validation functions. */
const KeyframeEditFunc select_cb = ANIM_editkeyframes_select(selectmode);
const KeyframeEditFunc ok_cb = ANIM_editkeyframes_ok(mode);
@@ -893,7 +893,7 @@ void GRAPH_OT_select_box(wmOperatorType *ot)
ot->poll = graphop_visible_keyframes_poll;
/* Flags. */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_UNDO;
/* Properties. */
ot->prop = RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", "");
@@ -1061,6 +1061,12 @@ static int graph_circle_select_exec(bContext *C, wmOperator *op)
/* Apply box_select action. */
const bool any_key_selection_changed = box_select_graphkeys(
&ac, &rect_fl, BEZT_OK_REGION_CIRCLE, selectmode, incl_handles, &data);
+ if (any_key_selection_changed) {
+ /* If any key was selected at any time during this process, the entire-curve selection should
+ * be disabled. Otherwise, sliding over any keyless part of the curve will immediately cause
+ * the entire curve to be selected. */
+ RNA_boolean_set(op->ptr, "use_curve_selection", false);
+ }
const bool use_curve_selection = RNA_boolean_get(op->ptr, "use_curve_selection");
if (use_curve_selection && !any_key_selection_changed) {
box_select_graphcurves(&ac, &rect_fl, BEZT_OK_REGION_CIRCLE, selectmode, incl_handles, &data);
@@ -1145,7 +1151,7 @@ static void markers_selectkeys_between(bAnimContext *ac)
min -= 0.5f;
max += 0.5f;
- /* get editing funcs + data */
+ /* Get editing functions + data. */
ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
select_cb = ANIM_editkeyframes_select(SELECT_ADD);
@@ -1295,6 +1301,7 @@ void GRAPH_OT_select_column(wmOperatorType *ot)
/* props */
ot->prop = RNA_def_enum(ot->srna, "mode", prop_column_select_types, 0, "Mode", "");
+ RNA_def_property_flag(ot->prop, PROP_HIDDEN);
}
/** \} */
diff --git a/source/blender/editors/space_graph/graph_slider_ops.c b/source/blender/editors/space_graph/graph_slider_ops.c
index f3d92911155..62aecf930d3 100644
--- a/source/blender/editors/space_graph/graph_slider_ops.c
+++ b/source/blender/editors/space_graph/graph_slider_ops.c
@@ -458,16 +458,13 @@ static bool decimate_poll_property(const bContext *UNUSED(C),
const PropertyRNA *prop)
{
const char *prop_id = RNA_property_identifier(prop);
+ const int mode = RNA_enum_get(op->ptr, "mode");
- if (STRPREFIX(prop_id, "remove")) {
- int mode = RNA_enum_get(op->ptr, "mode");
-
- if (STREQ(prop_id, "factor") && mode != DECIM_RATIO) {
- return false;
- }
- if (STREQ(prop_id, "remove_error_margin") && mode != DECIM_ERROR) {
- return false;
- }
+ if (STREQ(prop_id, "factor") && mode != DECIM_RATIO) {
+ return false;
+ }
+ if (STREQ(prop_id, "remove_error_margin") && mode != DECIM_ERROR) {
+ return false;
}
return true;
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 1434f204ee5..1dc02fee59d 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -45,6 +45,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "BLO_read_write.h"
+
#include "graph_intern.h" /* own include */
/* ******************** default callbacks for ipo space ***************** */
@@ -221,7 +223,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *region)
v2d->tot.xmax += 10.0f;
}
- if (((sipo->flag & SIPO_NODRAWCURSOR) == 0)) {
+ if ((sipo->flag & SIPO_NODRAWCURSOR) == 0) {
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
@@ -804,6 +806,42 @@ static void graph_space_subtype_item_extend(bContext *UNUSED(C),
RNA_enum_items_add(item, totitem, rna_enum_space_graph_mode_items);
}
+static void graph_blend_read_data(BlendDataReader *reader, SpaceLink *sl)
+{
+ SpaceGraph *sipo = (SpaceGraph *)sl;
+
+ BLO_read_data_address(reader, &sipo->ads);
+ memset(&sipo->runtime, 0x0, sizeof(sipo->runtime));
+}
+
+static void graph_blend_read_lib(BlendLibReader *reader, ID *parent_id, SpaceLink *sl)
+{
+ SpaceGraph *sipo = (SpaceGraph *)sl;
+ bDopeSheet *ads = sipo->ads;
+
+ if (ads) {
+ BLO_read_id_address(reader, parent_id->lib, &ads->source);
+ BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp);
+ }
+}
+
+static void graph_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ SpaceGraph *sipo = (SpaceGraph *)sl;
+ ListBase tmpGhosts = sipo->runtime.ghost_curves;
+
+ /* temporarily disable ghost curves when saving */
+ BLI_listbase_clear(&sipo->runtime.ghost_curves);
+
+ BLO_write_struct(writer, SpaceGraph, sl);
+ if (sipo->ads) {
+ BLO_write_struct(writer, bDopeSheet, sipo->ads);
+ }
+
+ /* Re-enable ghost curves. */
+ sipo->runtime.ghost_curves = tmpGhosts;
+}
+
void ED_spacetype_ipo(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype ipo");
@@ -824,6 +862,9 @@ void ED_spacetype_ipo(void)
st->space_subtype_item_extend = graph_space_subtype_item_extend;
st->space_subtype_get = graph_space_subtype_get;
st->space_subtype_set = graph_space_subtype_set;
+ st->blend_read_data = graph_blend_read_data;
+ st->blend_read_lib = graph_blend_read_lib;
+ st->blend_write = graph_blend_write;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
diff --git a/source/blender/editors/space_image/CMakeLists.txt b/source/blender/editors/space_image/CMakeLists.txt
index 4284d0f76af..f0915243bbc 100644
--- a/source/blender/editors/space_image/CMakeLists.txt
+++ b/source/blender/editors/space_image/CMakeLists.txt
@@ -5,6 +5,7 @@ set(INC
../../blenfont
../../blenkernel
../../blenlib
+ ../../blenloader
../../blentranslation
../../bmesh
../../depsgraph
@@ -17,6 +18,9 @@ set(INC
../../windowmanager
../../../../intern/clog
../../../../intern/guardedalloc
+
+ # dna_type_offsets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
# RNA_prototypes.h
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
@@ -65,5 +69,5 @@ endif()
blender_add_lib(bf_editor_space_image "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
-# RNA_prototypes.h
+# RNA_prototypes.h dna_type_offsets.h
add_dependencies(bf_editor_space_image bf_rna)
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index bc367a99d6b..c8efee504b4 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -654,7 +654,7 @@ static void uiblock_layer_pass_buttons(uiLayout *layout,
/* view */
if (BLI_listbase_count_at_most(&rr->views, 2) > 1 &&
- ((!show_stereo) || (!RE_RenderResult_is_stereo(rr)))) {
+ ((!show_stereo) || !RE_RenderResult_is_stereo(rr))) {
rview = BLI_findlink(&rr->views, iuser->view);
display_name = rview ? rview->name : "";
@@ -974,8 +974,16 @@ void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, bool color_ma
uiLayoutSetPropDecorate(col, false);
uiItemR(col, imfptr, "file_format", 0, NULL, ICON_NONE);
- uiItemR(
- uiLayoutRow(col, true), imfptr, "color_mode", UI_ITEM_R_EXPAND, IFACE_("Color"), ICON_NONE);
+
+ /* Multi-layer always saves raw unmodified channels. */
+ if (imf->imtype != R_IMF_IMTYPE_MULTILAYER) {
+ uiItemR(uiLayoutRow(col, true),
+ imfptr,
+ "color_mode",
+ UI_ITEM_R_EXPAND,
+ IFACE_("Color"),
+ ICON_NONE);
+ }
/* only display depth setting if multiple depths can be used */
if (ELEM(depth_ok,
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index b55bac0bc2f..85b1e2b6707 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -168,7 +168,7 @@ void ED_image_draw_info(Scene *scene,
GPU_blend(GPU_BLEND_NONE);
- BLF_size(blf_mono_font, 11.0f * U.pixelsize, U.dpi);
+ BLF_size(blf_mono_font, 11.0f * U.dpi_fac);
BLF_color3ub(blf_mono_font, 255, 255, 255);
SNPRINTF(str, "X:%-4d Y:%-4d |", x, y);
@@ -572,47 +572,60 @@ void draw_image_cache(const bContext *C, ARegion *region)
float ED_space_image_zoom_level(const View2D *v2d, const int grid_dimension)
{
/* UV-space length per pixel */
- float xzoom = (v2d->cur.xmax - v2d->cur.xmin) / ((float)(v2d->mask.xmax - v2d->mask.xmin));
- float yzoom = (v2d->cur.ymax - v2d->cur.ymin) / ((float)(v2d->mask.ymax - v2d->mask.ymin));
+ float xzoom = (v2d->cur.xmax - v2d->cur.xmin) / (float)(v2d->mask.xmax - v2d->mask.xmin);
+ float yzoom = (v2d->cur.ymax - v2d->cur.ymin) / (float)(v2d->mask.ymax - v2d->mask.ymin);
/* Zoom_factor for UV/Image editor is calculated based on:
* - Default grid size on startup, which is 256x256 pixels
* - How blend factor for grid lines is set up in the fragment shader `grid_frag.glsl`. */
float zoom_factor;
zoom_factor = (xzoom + yzoom) / 2.0f; /* Average for accuracy. */
- zoom_factor *= 256.0f / (powf(grid_dimension, 2));
+ zoom_factor *= 256.0f / powf(grid_dimension, 2);
return zoom_factor;
}
void ED_space_image_grid_steps(SpaceImage *sima,
- float grid_steps[SI_GRID_STEPS_LEN],
+ float grid_steps_x[SI_GRID_STEPS_LEN],
+ float grid_steps_y[SI_GRID_STEPS_LEN],
const int grid_dimension)
{
- if (sima->flag & SI_CUSTOM_GRID) {
- for (int step = 0; step < SI_GRID_STEPS_LEN; step++) {
- grid_steps[step] = powf(1, step) * (1.0f / ((float)sima->custom_grid_subdiv));
- }
- }
- else {
- for (int step = 0; step < SI_GRID_STEPS_LEN; step++) {
- grid_steps[step] = powf(grid_dimension, step) *
- (1.0f / (powf(grid_dimension, SI_GRID_STEPS_LEN)));
+ const eSpaceImage_GridShapeSource grid_shape_source = sima->grid_shape_source;
+ for (int step = 0; step < SI_GRID_STEPS_LEN; step++) {
+ switch (grid_shape_source) {
+ case SI_GRID_SHAPE_DYNAMIC:
+ grid_steps_x[step] = powf(grid_dimension, step - SI_GRID_STEPS_LEN);
+ grid_steps_y[step] = powf(grid_dimension, step - SI_GRID_STEPS_LEN);
+ break;
+ case SI_GRID_SHAPE_FIXED:
+ grid_steps_x[step] = 1.0f / sima->custom_grid_subdiv[0];
+ grid_steps_y[step] = 1.0f / sima->custom_grid_subdiv[1];
+ break;
+ case SI_GRID_SHAPE_PIXEL: {
+ int pixel_width = IMG_SIZE_FALLBACK;
+ int pixel_height = IMG_SIZE_FALLBACK;
+ ED_space_image_get_size(sima, &pixel_width, &pixel_height);
+ BLI_assert(pixel_width > 0 && pixel_height > 0);
+ grid_steps_x[step] = 1.0f / pixel_width;
+ grid_steps_y[step] = 1.0f / pixel_height;
+ } break;
+ default:
+ BLI_assert_unreachable();
}
}
}
-float ED_space_image_increment_snap_value(const int grid_dimesnions,
+float ED_space_image_increment_snap_value(const int grid_dimensions,
const float grid_steps[SI_GRID_STEPS_LEN],
const float zoom_factor)
{
/* Small offset on each grid_steps[] so that snapping value doesn't change until grid lines are
* significantly visible.
- * `Offset = 3/4 * (grid_steps[i] - (grid_steps[i] / grid_dimesnsions))`
+ * `Offset = 3/4 * (grid_steps[i] - (grid_steps[i] / grid_dimensions))`
*
* Refer `grid_frag.glsl` to find out when grid lines actually start appearing */
for (int step = 0; step < SI_GRID_STEPS_LEN; step++) {
- float offset = (3.0f / 4.0f) * (grid_steps[step] - (grid_steps[step] / grid_dimesnions));
+ float offset = (3.0f / 4.0f) * (grid_steps[step] - (grid_steps[step] / grid_dimensions));
if ((grid_steps[step] - offset) > zoom_factor) {
return grid_steps[step];
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index d17602ecd05..68b1a9e4466 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -67,6 +67,30 @@ void ED_space_image_set(Main *bmain, SpaceImage *sima, Image *ima, bool automati
WM_main_add_notifier(NC_SPACE | ND_SPACE_IMAGE, NULL);
}
+void ED_space_image_sync(struct Main *bmain, struct Image *image, bool ignore_render_viewer)
+{
+ wmWindowManager *wm = (wmWindowManager *)bmain->wm.first;
+ LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
+ const bScreen *screen = WM_window_get_active_screen(win);
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ if (sl->spacetype != SPACE_IMAGE) {
+ continue;
+ }
+ SpaceImage *sima = (SpaceImage *)sl;
+ if (sima->pin) {
+ continue;
+ }
+ if (ignore_render_viewer && sima->image &&
+ ELEM(sima->image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)) {
+ continue;
+ }
+ ED_space_image_set(bmain, sima, image, true);
+ }
+ }
+ }
+}
+
void ED_space_image_auto_set(const bContext *C, SpaceImage *sima)
{
if (sima->mode != SI_MODE_UV || sima->pin) {
@@ -383,7 +407,7 @@ bool ED_image_slot_cycle(struct Image *image, int direction)
image->render_slot = ((cur == 1) ? 0 : 1);
}
- if ((cur != image->render_slot)) {
+ if (cur != image->render_slot) {
BKE_image_partial_update_mark_full_update(image);
}
return (cur != image->render_slot);
@@ -408,7 +432,7 @@ void ED_space_image_scopes_update(const struct bContext *C,
/* We also don't update scopes of render result during render. */
if (G.is_rendering) {
const Image *image = sima->image;
- if (image != NULL && (ELEM(image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE))) {
+ if (image != NULL && ELEM(image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)) {
return;
}
}
@@ -471,7 +495,9 @@ bool ED_space_image_maskedit_poll(bContext *C)
SpaceImage *sima = CTX_wm_space_image(C);
if (sima) {
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
return ED_space_image_check_show_maskedit(sima, obedit);
}
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 78aaf957a87..3503c4c8168 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -762,14 +762,14 @@ static int image_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), const wmE
float pan_vec[3];
const wmNDOFMotionData *ndof = event->customdata;
- const float speed = NDOF_PIXELS_PER_SECOND;
+ const float pan_speed = NDOF_PIXELS_PER_SECOND;
WM_event_ndof_pan_get(ndof, pan_vec, true);
- mul_v2_fl(pan_vec, (speed * ndof->dt) / sima->zoom);
- pan_vec[2] *= -ndof->dt;
+ mul_v3_fl(pan_vec, ndof->dt);
+ mul_v2_fl(pan_vec, pan_speed / sima->zoom);
- sima_zoom_set_factor(sima, region, 1.0f + pan_vec[2], NULL, false);
+ sima_zoom_set_factor(sima, region, max_ff(0.0f, 1.0f - pan_vec[2]), NULL, false);
sima->xof += pan_vec[0];
sima->yof += pan_vec[1];
@@ -941,7 +941,7 @@ static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
if (ED_space_image_show_uvedit(sima, obedit)) {
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
bool success = ED_uvedit_minmax_multi(scene, objects, objects_len, min, max);
MEM_freeN(objects);
if (!success) {
@@ -1485,7 +1485,7 @@ static bool image_open_draw_check_prop(PointerRNA *UNUSED(ptr),
{
const char *prop_id = RNA_property_identifier(prop);
- return !(STR_ELEM(prop_id, "filepath", "directory", "filename"));
+ return !STR_ELEM(prop_id, "filepath", "directory", "filename");
}
static void image_open_draw(bContext *UNUSED(C), wmOperator *op)
@@ -1871,8 +1871,7 @@ static ImageSaveData *image_save_as_init(bContext *C, wmOperator *op)
}
/* Enable save_copy by default for render results. */
- if (ELEM(image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE) &&
- !RNA_struct_property_is_set(op->ptr, "copy")) {
+ if (image->source == IMA_SRC_VIEWER && !RNA_struct_property_is_set(op->ptr, "copy")) {
RNA_boolean_set(op->ptr, "copy", true);
}
@@ -1964,16 +1963,16 @@ static void image_save_as_cancel(bContext *UNUSED(C), wmOperator *op)
image_save_as_free(op);
}
-static bool image_save_as_draw_check_prop(PointerRNA *ptr,
- PropertyRNA *prop,
- void *UNUSED(user_data))
+static bool image_save_as_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *user_data)
{
+ ImageSaveData *isd = user_data;
const char *prop_id = RNA_property_identifier(prop);
return !(STREQ(prop_id, "filepath") || STREQ(prop_id, "directory") ||
STREQ(prop_id, "filename") ||
/* when saving a copy, relative path has no effect */
- (STREQ(prop_id, "relative_path") && RNA_boolean_get(ptr, "copy")));
+ (STREQ(prop_id, "relative_path") && RNA_boolean_get(ptr, "copy")) ||
+ (STREQ(prop_id, "save_as_render") && isd->image->source == IMA_SRC_VIEWER));
}
static void image_save_as_draw(bContext *UNUSED(C), wmOperator *op)
@@ -1987,13 +1986,13 @@ static void image_save_as_draw(bContext *UNUSED(C), wmOperator *op)
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
- /* main draw call */
+ /* Operator settings. */
uiDefAutoButsRNA(
- layout, op->ptr, image_save_as_draw_check_prop, NULL, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
+ layout, op->ptr, image_save_as_draw_check_prop, isd, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
uiItemS(layout);
- /* image template */
+ /* Image format settings. */
RNA_pointer_create(NULL, &RNA_ImageFormatSettings, &isd->opts.im_format, &imf_ptr);
uiTemplateImageSettings(layout, &imf_ptr, save_as_render);
@@ -2004,7 +2003,7 @@ static void image_save_as_draw(bContext *UNUSED(C), wmOperator *op)
uiItemR(col, &linear_settings_ptr, "name", 0, IFACE_("Color Space"), ICON_NONE);
}
- /* multiview template */
+ /* Multiview settings. */
if (is_multiview) {
uiTemplateImageFormatViews(layout, &imf_ptr, op->ptr);
}
@@ -2049,11 +2048,14 @@ void IMAGE_OT_save_as(wmOperatorType *ot)
/* properties */
PropertyRNA *prop;
- prop = RNA_def_boolean(ot->srna,
- "save_as_render",
- 0,
- "Save As Render",
- "Apply render part of display transform when saving byte image");
+ prop = RNA_def_boolean(
+ ot->srna,
+ "save_as_render",
+ 0,
+ "Save As Render",
+ "Save image with render color management.\n"
+ "For display image formats like PNG, apply view and display transform.\n"
+ "For intermediate image formats like OpenEXR, use the default render output color space");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(ot->srna,
"copy",
diff --git a/source/blender/editors/space_image/image_sequence.c b/source/blender/editors/space_image/image_sequence.c
index fbeef47e278..d2725652979 100644
--- a/source/blender/editors/space_image/image_sequence.c
+++ b/source/blender/editors/space_image/image_sequence.c
@@ -58,18 +58,18 @@ static void image_sequence_get_frame_ranges(wmOperator *op, ListBase *ranges)
frame->framenr = BLI_path_sequence_decode(filename, head, tail, &digits);
/* still in the same sequence */
- if (do_frame_range && (range != NULL) && (STREQLEN(base_head, head, FILE_MAX)) &&
- (STREQLEN(base_tail, tail, FILE_MAX))) {
+ if (do_frame_range && (range != NULL) && STREQLEN(base_head, head, FILE_MAX) &&
+ STREQLEN(base_tail, tail, FILE_MAX)) {
/* Set filepath to first frame in the range. */
if (frame->framenr < range_first_frame) {
- BLI_join_dirfile(range->filepath, sizeof(range->filepath), dir, filename);
+ BLI_path_join(range->filepath, sizeof(range->filepath), dir, filename);
range_first_frame = frame->framenr;
}
}
else {
/* start a new frame range */
range = MEM_callocN(sizeof(*range), __func__);
- BLI_join_dirfile(range->filepath, sizeof(range->filepath), dir, filename);
+ BLI_path_join(range->filepath, sizeof(range->filepath), dir, filename);
BLI_addtail(ranges, range);
BLI_strncpy(base_head, head, sizeof(base_head));
diff --git a/source/blender/editors/space_image/image_undo.cc b/source/blender/editors/space_image/image_undo.cc
index 8f144264824..1589195d2af 100644
--- a/source/blender/editors/space_image/image_undo.cc
+++ b/source/blender/editors/space_image/image_undo.cc
@@ -637,7 +637,7 @@ static void uhandle_free_list(ListBase *undo_handles)
/** #UndoImageHandle utilities */
static UndoImageBuf *uhandle_lookup_ubuf(UndoImageHandle *uh,
- const Image *UNUSED(image),
+ const Image * /*image*/,
const char *ibuf_name)
{
LISTBASE_FOREACH (UndoImageBuf *, ubuf, &uh->buffers) {
@@ -775,7 +775,7 @@ static bool image_undosys_poll(bContext *C)
return false;
}
-static void image_undosys_step_encode_init(struct bContext *UNUSED(C), UndoStep *us_p)
+static void image_undosys_step_encode_init(struct bContext * /*C*/, UndoStep *us_p)
{
ImageUndoStep *us = reinterpret_cast<ImageUndoStep *>(us_p);
/* dummy, memory is cleared anyway. */
@@ -784,9 +784,7 @@ static void image_undosys_step_encode_init(struct bContext *UNUSED(C), UndoStep
us->paint_tile_map = MEM_new<PaintTileMap>(__func__);
}
-static bool image_undosys_step_encode(struct bContext *C,
- struct Main *UNUSED(bmain),
- UndoStep *us_p)
+static bool image_undosys_step_encode(struct bContext *C, struct Main * /*bmain*/, UndoStep *us_p)
{
/* Encoding is done along the way by adding tiles
* to the current 'ImageUndoStep' added by encode_init.
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 08b7897ec5a..53e1bc0a1e5 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -5,6 +5,7 @@
* \ingroup spimage
*/
+#include "DNA_defaults.h"
#include "DNA_gpencil_types.h"
#include "DNA_image_types.h"
#include "DNA_mask_types.h"
@@ -50,6 +51,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "BLO_read_write.h"
+
#include "DRW_engine.h"
#include "image_intern.h"
@@ -112,7 +115,10 @@ static SpaceLink *image_create(const ScrArea *UNUSED(area), const Scene *UNUSED(
simage->tile_grid_shape[0] = 1;
simage->tile_grid_shape[1] = 1;
- simage->custom_grid_subdiv = 10;
+ simage->custom_grid_subdiv[0] = 10;
+ simage->custom_grid_subdiv[1] = 10;
+
+ simage->mask_info = *DNA_struct_default_get(MaskSpaceInfo);
/* header */
region = MEM_callocN(sizeof(ARegion), "header for image");
@@ -351,7 +357,9 @@ static void image_listener(const wmSpaceTypeListenerParams *params)
}
break;
case NC_MASK: {
+ Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
if (ED_space_image_check_show_maskedit(sima, obedit)) {
switch (wmn->data) {
@@ -393,7 +401,9 @@ static void image_listener(const wmSpaceTypeListenerParams *params)
switch (wmn->data) {
case ND_TRANSFORM:
case ND_MODIFIER: {
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ob && (ob == wmn->reference) && (ob->mode & OB_MODE_EDIT)) {
if (sima->lock && (sima->flag & SI_DRAWSHADOW)) {
@@ -1021,6 +1031,46 @@ static void image_space_subtype_item_extend(bContext *UNUSED(C),
RNA_enum_items_add(item, totitem, rna_enum_space_image_mode_items);
}
+static void image_blend_read_data(BlendDataReader *UNUSED(reader), SpaceLink *sl)
+{
+ SpaceImage *sima = (SpaceImage *)sl;
+
+ sima->iuser.scene = NULL;
+ sima->scopes.waveform_1 = NULL;
+ sima->scopes.waveform_2 = NULL;
+ sima->scopes.waveform_3 = NULL;
+ sima->scopes.vecscope = NULL;
+ sima->scopes.ok = 0;
+
+ /* WARNING: gpencil data is no longer stored directly in sima after 2.5
+ * so sacrifice a few old files for now to avoid crashes with new files!
+ * committed: r28002 */
+#if 0
+ sima->gpd = newdataadr(fd, sima->gpd);
+ if (sima->gpd) {
+ BKE_gpencil_blend_read_data(fd, sima->gpd);
+ }
+#endif
+}
+
+static void image_blend_read_lib(BlendLibReader *reader, ID *parent_id, SpaceLink *sl)
+{
+ SpaceImage *sima = (SpaceImage *)sl;
+
+ BLO_read_id_address(reader, parent_id->lib, &sima->image);
+ BLO_read_id_address(reader, parent_id->lib, &sima->mask_info.mask);
+
+ /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
+ * so fingers crossed this works fine!
+ */
+ BLO_read_id_address(reader, parent_id->lib, &sima->gpd);
+}
+
+static void image_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ BLO_write_struct(writer, SpaceImage, sl);
+}
+
/**************************** spacetype *****************************/
void ED_spacetype_image(void)
@@ -1046,6 +1096,9 @@ void ED_spacetype_image(void)
st->space_subtype_item_extend = image_space_subtype_item_extend;
st->space_subtype_get = image_space_subtype_get;
st->space_subtype_set = image_space_subtype_set;
+ st->blend_read_data = image_blend_read_data;
+ st->blend_read_lib = image_blend_read_lib;
+ st->blend_write = image_blend_write;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype image region");
diff --git a/source/blender/editors/space_info/CMakeLists.txt b/source/blender/editors/space_info/CMakeLists.txt
index 4e9df2b93b0..03314158813 100644
--- a/source/blender/editors/space_info/CMakeLists.txt
+++ b/source/blender/editors/space_info/CMakeLists.txt
@@ -15,6 +15,9 @@ set(INC
../../makesrna
../../windowmanager
../../../../intern/guardedalloc
+
+ # dna_type_offsets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
# RNA_prototypes.h
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
@@ -37,5 +40,5 @@ set(LIB
blender_add_lib(bf_editor_space_info "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
-# RNA_prototypes.h
+# RNA_prototypes.h dna_type_offsets.h
add_dependencies(bf_editor_space_info bf_rna)
diff --git a/source/blender/editors/space_info/info_stats.cc b/source/blender/editors/space_info/info_stats.cc
index 0169acc36b7..e8b005b2b67 100644
--- a/source/blender/editors/space_info/info_stats.cc
+++ b/source/blender/editors/space_info/info_stats.cc
@@ -40,6 +40,7 @@
#include "BKE_key.h"
#include "BKE_layer.h"
#include "BKE_main.h"
+#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
@@ -94,8 +95,8 @@ static bool stats_mesheval(const Mesh *me_eval, bool is_selected, SceneStats *st
int totvert, totedge, totface, totloop;
- const SubdivCCG *subdiv_ccg = me_eval->runtime.subdiv_ccg;
- const SubsurfRuntimeData *subsurf_runtime_data = me_eval->runtime.subsurf_runtime_data;
+ const SubdivCCG *subdiv_ccg = me_eval->runtime->subdiv_ccg;
+ const SubsurfRuntimeData *subsurf_runtime_data = me_eval->runtime->subsurf_runtime_data;
if (subdiv_ccg != nullptr) {
BKE_subdiv_ccg_topology_counters(subdiv_ccg, &totvert, &totedge, &totface, &totloop);
@@ -353,10 +354,12 @@ static void stats_object_sculpt(const Object *ob, SceneStats *stats)
/* Statistics displayed in info header. Called regularly on scene changes. */
static void stats_update(Depsgraph *depsgraph,
+ const Scene *scene,
ViewLayer *view_layer,
View3D *v3d_local,
SceneStats *stats)
{
+ BKE_view_layer_synced_ensure(scene, view_layer);
const Object *ob = BKE_view_layer_active_object_get(view_layer);
const Object *obedit = BKE_view_layer_edit_object_get(view_layer);
@@ -364,7 +367,7 @@ static void stats_update(Depsgraph *depsgraph,
if (obedit) {
/* Edit Mode. */
- FOREACH_OBJECT_BEGIN (view_layer, ob_iter) {
+ FOREACH_OBJECT_BEGIN (scene, view_layer, ob_iter) {
if (ob_iter->base_flag & BASE_ENABLED_AND_VISIBLE_IN_DEFAULT_VIEWPORT) {
if (ob_iter->mode & OB_MODE_EDIT) {
stats_object_edit(ob_iter, stats);
@@ -373,7 +376,7 @@ static void stats_update(Depsgraph *depsgraph,
else {
/* Skip hidden objects in local view that are not in edit-mode,
* an exception for edit-mode, in most other modes these would be considered hidden. */
- if ((v3d_local && !BKE_object_is_visible_in_viewport(v3d_local, ob_iter))) {
+ if (v3d_local && !BKE_object_is_visible_in_viewport(v3d_local, ob_iter)) {
continue;
}
}
@@ -384,7 +387,7 @@ static void stats_update(Depsgraph *depsgraph,
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
/* Pose Mode. */
- FOREACH_OBJECT_BEGIN (view_layer, ob_iter) {
+ FOREACH_OBJECT_BEGIN (scene, view_layer, ob_iter) {
if (ob_iter->base_flag & BASE_ENABLED_AND_VISIBLE_IN_DEFAULT_VIEWPORT) {
if (ob_iter->mode & OB_MODE_POSE) {
stats_object_pose(ob_iter, stats);
@@ -392,7 +395,7 @@ static void stats_update(Depsgraph *depsgraph,
}
else {
/* See comment for edit-mode. */
- if ((v3d_local && !BKE_object_is_visible_in_viewport(v3d_local, ob_iter))) {
+ if (v3d_local && !BKE_object_is_visible_in_viewport(v3d_local, ob_iter)) {
continue;
}
}
@@ -408,10 +411,13 @@ static void stats_update(Depsgraph *depsgraph,
else {
/* Objects. */
GSet *objects_gset = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob_iter) {
+ DEGObjectIterSettings deg_iter_settings{};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob_iter) {
stats_object(ob_iter, v3d_local, stats, objects_gset);
}
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
+ DEG_OBJECT_ITER_END;
BLI_gset_free(objects_gset, nullptr);
}
}
@@ -450,7 +456,7 @@ static bool format_stats(
}
Depsgraph *depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, view_layer);
*stats_p = (SceneStats *)MEM_mallocN(sizeof(SceneStats), __func__);
- stats_update(depsgraph, view_layer, v3d_local, *stats_p);
+ stats_update(depsgraph, scene, view_layer, v3d_local, *stats_p);
}
SceneStats *stats = *stats_p;
@@ -489,13 +495,18 @@ static bool format_stats(
return true;
}
-static void get_stats_string(
- char *info, int len, size_t *ofs, ViewLayer *view_layer, SceneStatsFmt *stats_fmt)
+static void get_stats_string(char *info,
+ int len,
+ size_t *ofs,
+ const Scene *scene,
+ ViewLayer *view_layer,
+ SceneStatsFmt *stats_fmt)
{
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
Object *obedit = OBEDIT_FROM_OBACT(ob);
eObjectMode object_mode = ob ? (eObjectMode)ob->mode : OB_MODE_OBJECT;
- LayerCollection *layer_collection = view_layer->active_collection;
+ LayerCollection *layer_collection = BKE_view_layer_active_collection_get(view_layer);
if (object_mode == OB_MODE_OBJECT) {
*ofs += BLI_snprintf_rlen(info + *ofs,
@@ -599,7 +610,7 @@ static const char *info_statusbar_string(Main *bmain,
if (statusbar_flag & STATUSBAR_SHOW_STATS) {
SceneStatsFmt stats_fmt;
if (format_stats(bmain, scene, view_layer, nullptr, &stats_fmt)) {
- get_stats_string(info + ofs, len, &ofs, view_layer, &stats_fmt);
+ get_stats_string(info + ofs, len, &ofs, scene, view_layer, &stats_fmt);
}
}
@@ -614,7 +625,7 @@ static const char *info_statusbar_string(Main *bmain,
}
/* GPU VRAM status. */
- if ((statusbar_flag & STATUSBAR_SHOW_VRAM) && (GPU_mem_stats_supported())) {
+ if ((statusbar_flag & STATUSBAR_SHOW_VRAM) && GPU_mem_stats_supported()) {
int gpu_free_mem_kb, gpu_tot_mem_kb;
GPU_mem_stats_get(&gpu_tot_mem_kb, &gpu_free_mem_kb);
float gpu_total_gb = gpu_tot_mem_kb / 1048576.0f;
@@ -684,6 +695,7 @@ void ED_info_draw_stats(
return;
}
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
Object *obedit = OBEDIT_FROM_OBACT(ob);
eObjectMode object_mode = ob ? (eObjectMode)ob->mode : OB_MODE_OBJECT;
diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c
index 63c8d74c684..11294ed6ecc 100644
--- a/source/blender/editors/space_info/space_info.c
+++ b/source/blender/editors/space_info/space_info.c
@@ -28,6 +28,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "BLO_read_write.h"
+
#include "info_intern.h" /* own include */
/* ******************** default callbacks for info space ***************** */
@@ -248,6 +250,11 @@ static void info_header_region_message_subscribe(const wmRegionMessageSubscribeP
WM_msg_subscribe_rna_anon_prop(mbus, ViewLayer, name, &msg_sub_value_region_tag_redraw);
}
+static void info_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ BLO_write_struct(writer, SpaceInfo, sl);
+}
+
void ED_spacetype_info(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype info");
@@ -262,6 +269,7 @@ void ED_spacetype_info(void)
st->duplicate = info_duplicate;
st->operatortypes = info_operatortypes;
st->keymap = info_keymap;
+ st->blend_write = info_blend_write;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype info region");
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index 9aa2b84169e..12ee6f45991 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -25,7 +25,7 @@
static void textview_font_begin(const int font_id, const int lheight)
{
/* Font size in relation to line height. */
- BLF_size(font_id, 0.8f * lheight, 72);
+ BLF_size(font_id, 0.8f * lheight);
}
typedef struct TextViewDrawState {
@@ -235,7 +235,8 @@ static bool textview_draw_string(TextViewDrawState *tds,
1.0f,
0.0f,
icon_fg,
- false);
+ false,
+ UI_NO_ICON_OVERLAY_TEXT);
GPU_blend(GPU_BLEND_NONE);
}
diff --git a/source/blender/editors/space_nla/CMakeLists.txt b/source/blender/editors/space_nla/CMakeLists.txt
index e6995085dbe..5df0ebb3b28 100644
--- a/source/blender/editors/space_nla/CMakeLists.txt
+++ b/source/blender/editors/space_nla/CMakeLists.txt
@@ -4,6 +4,7 @@ set(INC
../include
../../blenkernel
../../blenlib
+ ../../blenloader
../../blentranslation
../../depsgraph
../../gpu
@@ -11,6 +12,9 @@ set(INC
../../makesrna
../../windowmanager
../../../../intern/guardedalloc
+
+ # dna_type_offsets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
# RNA_prototypes.h
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
@@ -36,5 +40,5 @@ set(LIB
blender_add_lib(bf_editor_space_nla "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
-# RNA_prototypes.h
+# RNA_prototypes.h dna_type_offsets.h
add_dependencies(bf_editor_space_nla bf_rna)
diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c
index 72b2eb20f8f..4aff3766b12 100644
--- a/source/blender/editors/space_nla/nla_buttons.c
+++ b/source/blender/editors/space_nla/nla_buttons.c
@@ -107,7 +107,6 @@ bool nla_panel_context(const bContext *C,
found = 1;
break;
}
- case ANIMTYPE_NLAACTION:
case ANIMTYPE_SCENE: /* Top-Level Widgets doubling up as datablocks */
case ANIMTYPE_OBJECT:
case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
@@ -158,6 +157,11 @@ bool nla_panel_context(const bContext *C,
}
break;
}
+ /* Don't set a pointer for NLA Actions.
+ * This will break the dependency graph for the context menu.
+ */
+ case ANIMTYPE_NLAACTION:
+ break;
}
if (found > 0) {
@@ -214,7 +218,8 @@ static bool nla_animdata_panel_poll(const bContext *C, PanelType *UNUSED(pt))
{
PointerRNA ptr;
PointerRNA strip_ptr;
- return (nla_panel_context(C, &ptr, NULL, &strip_ptr) && (ptr.data != NULL) && (ptr.owner_id != strip_ptr.owner_id));
+ return (nla_panel_context(C, &ptr, NULL, &strip_ptr) && (ptr.data != NULL) &&
+ (ptr.owner_id != strip_ptr.owner_id));
}
static bool nla_strip_panel_poll(const bContext *C, PanelType *UNUSED(pt))
@@ -277,7 +282,7 @@ static void nla_panel_animdata(const bContext *C, Panel *panel)
return;
}
- if(adt_ptr.owner_id == strip_ptr.owner_id){
+ if (adt_ptr.owner_id == strip_ptr.owner_id) {
return;
}
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index a0c6a29c422..3c0238806bf 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -20,6 +20,7 @@
#include "BKE_anim_data.h"
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_layer.h"
#include "BKE_nla.h"
#include "BKE_report.h"
#include "BKE_scene.h"
@@ -129,7 +130,8 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, int channel_index,
else {
/* deselect all */
/* TODO: should this deselect all other types of channels too? */
- LISTBASE_FOREACH (Base *, b, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(ac->scene, view_layer);
+ LISTBASE_FOREACH (Base *, b, BKE_view_layer_object_bases_get(view_layer)) {
ED_object_base_select(b, BA_DESELECT);
if (b->object->adt) {
b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE);
@@ -478,7 +480,7 @@ void NLA_OT_action_pushdown(wmOperatorType *ot)
"Index of NLA action channel to perform pushdown operation on",
0,
INT_MAX);
- RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
+ RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE | PROP_HIDDEN);
}
/* ******************** Action Unlink ******************************** */
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index e614055441d..45bbe50eedd 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -22,6 +22,7 @@
#include "BLI_range.h"
#include "BLI_utildefines.h"
+#include "BKE_action.h"
#include "BKE_context.h"
#include "BKE_fcurve.h"
#include "BKE_nla.h"
@@ -856,8 +857,9 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *region)
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- /* just draw a semi-shaded rect spanning the width of the viewable area if there's data,
- * and a second darker rect within which we draw keyframe indicator dots if there's data
+ /* just draw a semi-shaded rect spanning the width of the viewable area, based on if
+ * there's data and the action's extrapolation mode. Draw a second darker rect within
+ * which we draw keyframe indicator dots if there's data.
*/
GPU_blend(GPU_BLEND_ALPHA);
@@ -869,8 +871,26 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *region)
/* draw slightly shifted up for greater separation from standard channels,
* but also slightly shorter for some more contrast when viewing the strips
*/
- immRectf(
- pos, v2d->cur.xmin, ymin + NLACHANNEL_SKIP, v2d->cur.xmax, ymax - NLACHANNEL_SKIP);
+ switch (adt->act_extendmode) {
+ case NLASTRIP_EXTEND_HOLD: {
+ immRectf(pos,
+ v2d->cur.xmin,
+ ymin + NLACHANNEL_SKIP,
+ v2d->cur.xmax,
+ ymax - NLACHANNEL_SKIP);
+ break;
+ }
+ case NLASTRIP_EXTEND_HOLD_FORWARD: {
+ float r_start;
+ float r_end;
+ BKE_action_get_frame_range(ale->data, &r_start, &r_end);
+
+ immRectf(pos, r_end, ymin + NLACHANNEL_SKIP, v2d->cur.xmax, ymax - NLACHANNEL_SKIP);
+ break;
+ }
+ case NLASTRIP_EXTEND_NOTHING:
+ break;
+ }
immUnbindProgram();
@@ -885,7 +905,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *region)
}
}
- /* free tempolary channels */
+ /* Free temporary channels. */
ANIM_animdata_freelist(&anim_data);
}
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index bcdbbb00d1c..8a3c6745259 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -610,7 +610,7 @@ void NLA_OT_view_frame(wmOperatorType *ot)
static int nlaedit_get_editable_tracks(bAnimContext *ac, ListBase *anim_data)
{
const int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ACTIVE | ANIMFILTER_FOREDIT |
- ANIMFILTER_FCURVESONLY);
+ ANIMFILTER_FCURVESONLY);
return ANIM_animdata_filter(ac, anim_data, filter, ac->data, ac->datatype);
}
@@ -2641,6 +2641,8 @@ static int nla_fmodifier_add_exec(bContext *C, wmOperator *op)
void NLA_OT_fmodifier_add(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Add F-Modifier";
ot->idname = "NLA_OT_fmodifier_add";
@@ -2659,11 +2661,12 @@ void NLA_OT_fmodifier_add(wmOperatorType *ot)
RNA_def_property_translation_context(ot->prop, BLT_I18NCONTEXT_ID_ACTION);
RNA_def_enum_funcs(ot->prop, nla_fmodifier_itemf);
- RNA_def_boolean(ot->srna,
- "only_active",
- true,
- "Only Active",
- "Only add a F-Modifier of the specified type to the active strip");
+ prop = RNA_def_boolean(ot->srna,
+ "only_active",
+ true,
+ "Only Active",
+ "Only add a F-Modifier of the specified type to the active strip");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ACTION);
}
/** \} */
@@ -2832,8 +2835,10 @@ void NLA_OT_fmodifier_paste(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(
+ ot->prop = RNA_def_boolean(
ot->srna, "only_active", true, "Only Active", "Only paste F-Modifiers on active strip");
+ RNA_def_property_translation_context(ot->prop, BLT_I18NCONTEXT_ID_ACTION);
+
RNA_def_boolean(
ot->srna,
"replace",
diff --git a/source/blender/editors/space_nla/nla_select.c b/source/blender/editors/space_nla/nla_select.c
index a816f8fa4f6..ce93e36474f 100644
--- a/source/blender/editors/space_nla/nla_select.c
+++ b/source/blender/editors/space_nla/nla_select.c
@@ -401,7 +401,7 @@ void NLA_OT_select_box(wmOperatorType *ot)
ot->poll = nlaop_poll_tweakmode_off;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_UNDO;
/* properties */
RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", "");
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index c71e63e9dcd..12f8915764b 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -36,6 +36,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "BLO_read_write.h"
+
#include "nla_intern.h" /* own include */
/* ******************** default callbacks for nla space ***************** */
@@ -562,6 +564,33 @@ static void nla_id_remap(ScrArea *UNUSED(area),
BKE_id_remapper_apply(mappings, (ID **)&snla->ads->source, ID_REMAP_APPLY_DEFAULT);
}
+static void nla_blend_read_data(BlendDataReader *reader, SpaceLink *sl)
+{
+ SpaceNla *snla = (SpaceNla *)sl;
+ BLO_read_data_address(reader, &snla->ads);
+}
+
+static void nla_blend_read_lib(BlendLibReader *reader, ID *parent_id, SpaceLink *sl)
+{
+ SpaceNla *snla = (SpaceNla *)sl;
+ bDopeSheet *ads = snla->ads;
+
+ if (ads) {
+ BLO_read_id_address(reader, parent_id->lib, &ads->source);
+ BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp);
+ }
+}
+
+static void nla_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ SpaceNla *snla = (SpaceNla *)sl;
+
+ BLO_write_struct(writer, SpaceNla, snla);
+ if (snla->ads) {
+ BLO_write_struct(writer, bDopeSheet, snla->ads);
+ }
+}
+
void ED_spacetype_nla(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype nla");
@@ -578,6 +607,9 @@ void ED_spacetype_nla(void)
st->listener = nla_listener;
st->keymap = nla_keymap;
st->id_remap = nla_id_remap;
+ st->blend_read_data = nla_blend_read_data;
+ st->blend_read_lib = nla_blend_read_lib;
+ st->blend_write = nla_blend_write;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype nla region");
@@ -628,5 +660,8 @@ void ED_spacetype_nla(void)
nla_buttons_register(art);
+ art = ED_area_type_hud(st->spaceid);
+ BLI_addhead(&st->regiontypes, art);
+
BKE_spacetype_register(st);
}
diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt
index 8a1d47eaa8d..ff9e5352d0a 100644
--- a/source/blender/editors/space_node/CMakeLists.txt
+++ b/source/blender/editors/space_node/CMakeLists.txt
@@ -5,6 +5,7 @@ set(INC
../../blenfont
../../blenkernel
../../blenlib
+ ../../blenloader
../../blentranslation
../../compositor
../../depsgraph
@@ -18,12 +19,17 @@ set(INC
../../render
../../windowmanager
../../../../intern/guardedalloc
+
+ # dna_type_offsets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
# RNA_prototypes.h
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
set(SRC
+ add_node_search.cc
+ add_menu_assets.cc
drawnode.cc
link_drag_search.cc
node_add.cc
@@ -79,5 +85,5 @@ endif()
blender_add_lib(bf_editor_space_node "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
-# RNA_prototypes.h
+# RNA_prototypes.h dna_type_offsets.h
add_dependencies(bf_editor_space_node bf_rna)
diff --git a/source/blender/editors/space_node/add_menu_assets.cc b/source/blender/editors/space_node/add_menu_assets.cc
new file mode 100644
index 00000000000..4bb98124a3f
--- /dev/null
+++ b/source/blender/editors/space_node/add_menu_assets.cc
@@ -0,0 +1,316 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BLI_multi_value_map.hh"
+
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_asset.h"
+#include "BKE_asset_catalog.hh"
+#include "BKE_asset_library.hh"
+#include "BKE_idprop.h"
+#include "BKE_screen.h"
+
+#include "BLT_translation.h"
+
+#include "RNA_access.h"
+#include "RNA_prototypes.h"
+
+#include "ED_asset.h"
+#include "ED_screen.h"
+
+#include "node_intern.hh"
+
+namespace blender::ed::space_node {
+
+static bool node_add_menu_poll(const bContext *C, MenuType * /*mt*/)
+{
+ return CTX_wm_space_node(C);
+}
+
+static void node_add_menu_assets_listen_fn(const wmRegionListenerParams *params)
+{
+ const wmNotifier *wmn = params->notifier;
+ ARegion *region = params->region;
+
+ switch (wmn->category) {
+ case NC_ASSET:
+ if (wmn->data == ND_ASSET_LIST_READING) {
+ ED_region_tag_refresh_ui(region);
+ }
+ break;
+ }
+}
+
+struct LibraryAsset {
+ AssetLibraryReference library_ref;
+ AssetHandle handle;
+};
+
+struct LibraryCatalog {
+ bke::AssetLibrary *library;
+ const bke::AssetCatalog *catalog;
+};
+
+struct AssetItemTree {
+ bke::AssetCatalogTree catalogs;
+ MultiValueMap<bke::AssetCatalogPath, LibraryAsset> assets_per_path;
+ Map<const bke::AssetCatalogTreeItem *, bke::AssetCatalogPath> full_catalog_per_tree_item;
+};
+
+static bool all_loading_finished()
+{
+ for (const AssetLibraryReference &library : bke::all_valid_asset_library_refs()) {
+ if (!ED_assetlist_is_loaded(&library)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static AssetItemTree build_catalog_tree(const bContext &C, const bNodeTree *node_tree)
+{
+ if (!node_tree) {
+ return {};
+ }
+ const Main &bmain = *CTX_data_main(&C);
+ const Vector<AssetLibraryReference> all_libraries = bke::all_valid_asset_library_refs();
+
+ /* Merge catalogs from all libraries to deduplicate menu items. Also store the catalog and
+ * library for each asset ID in order to use them later when retrieving assets and removing
+ * empty catalogs. */
+ Map<bke::CatalogID, LibraryCatalog> id_to_catalog_map;
+ bke::AssetCatalogTree catalogs_from_all_libraries;
+ for (const AssetLibraryReference &library_ref : all_libraries) {
+ if (bke::AssetLibrary *library = BKE_asset_library_load(&bmain, library_ref)) {
+ if (bke::AssetCatalogTree *tree = library->catalog_service->get_catalog_tree()) {
+ tree->foreach_item([&](bke::AssetCatalogTreeItem &item) {
+ const bke::CatalogID &id = item.get_catalog_id();
+ bke::AssetCatalog *catalog = library->catalog_service->find_catalog(id);
+ catalogs_from_all_libraries.insert_item(*catalog);
+ id_to_catalog_map.add(item.get_catalog_id(), LibraryCatalog{library, catalog});
+ });
+ }
+ }
+ }
+
+ /* Find all the matching node group assets for every catalog path. */
+ MultiValueMap<bke::AssetCatalogPath, LibraryAsset> assets_per_path;
+ for (const AssetLibraryReference &library_ref : all_libraries) {
+ AssetFilterSettings type_filter{};
+ type_filter.id_types = FILTER_ID_NT;
+
+ ED_assetlist_storage_fetch(&library_ref, &C);
+ ED_assetlist_iterate(library_ref, [&](AssetHandle asset) {
+ if (!ED_asset_filter_matches_asset(&type_filter, &asset)) {
+ return true;
+ }
+ const AssetMetaData &meta_data = *ED_asset_handle_get_metadata(&asset);
+ const IDProperty *tree_type = BKE_asset_metadata_idprop_find(&meta_data, "type");
+ if (tree_type == nullptr || IDP_Int(tree_type) != node_tree->type) {
+ return true;
+ }
+ if (BLI_uuid_is_nil(meta_data.catalog_id)) {
+ return true;
+ }
+ const LibraryCatalog *library_catalog = id_to_catalog_map.lookup_ptr(meta_data.catalog_id);
+ if (library_catalog == nullptr) {
+ return true;
+ }
+ assets_per_path.add(library_catalog->catalog->path, LibraryAsset{library_ref, asset});
+ return true;
+ });
+ }
+
+ /* Build the final tree without any of the catalogs that don't have proper node group assets. */
+ bke::AssetCatalogTree catalogs_with_node_assets;
+ catalogs_from_all_libraries.foreach_item([&](bke::AssetCatalogTreeItem &item) {
+ if (!assets_per_path.lookup(item.catalog_path()).is_empty()) {
+ const bke::CatalogID &id = item.get_catalog_id();
+ const LibraryCatalog &library_catalog = id_to_catalog_map.lookup(id);
+ bke::AssetCatalog *catalog = library_catalog.library->catalog_service->find_catalog(id);
+ catalogs_with_node_assets.insert_item(*catalog);
+ }
+ });
+
+ /* Build another map storing full asset paths for each tree item, in order to have stable
+ * pointers to asset catalog paths to use for context pointers. This is necessary because
+ * #bke::AssetCatalogTreeItem doesn't store its full path directly. */
+ Map<const bke::AssetCatalogTreeItem *, bke::AssetCatalogPath> full_catalog_per_tree_item;
+ catalogs_with_node_assets.foreach_item([&](bke::AssetCatalogTreeItem &item) {
+ full_catalog_per_tree_item.add_new(&item, item.catalog_path());
+ });
+
+ return {std::move(catalogs_with_node_assets),
+ std::move(assets_per_path),
+ std::move(full_catalog_per_tree_item)};
+}
+
+static void node_add_catalog_assets_draw(const bContext *C, Menu *menu)
+{
+ bScreen &screen = *CTX_wm_screen(C);
+ const SpaceNode &snode = *CTX_wm_space_node(C);
+ if (!snode.runtime->assets_for_menu) {
+ BLI_assert_unreachable();
+ return;
+ }
+ AssetItemTree &tree = *snode.runtime->assets_for_menu;
+ const bNodeTree *edit_tree = snode.edittree;
+ if (!edit_tree) {
+ return;
+ }
+
+ const PointerRNA menu_path_ptr = CTX_data_pointer_get(C, "asset_catalog_path");
+ if (RNA_pointer_is_null(&menu_path_ptr)) {
+ return;
+ }
+ const bke::AssetCatalogPath &menu_path = *static_cast<const bke::AssetCatalogPath *>(
+ menu_path_ptr.data);
+
+ const Span<LibraryAsset> asset_items = tree.assets_per_path.lookup(menu_path);
+ bke::AssetCatalogTreeItem *catalog_item = tree.catalogs.find_item(menu_path);
+ BLI_assert(catalog_item != nullptr);
+
+ if (asset_items.is_empty() && !catalog_item->has_children()) {
+ return;
+ }
+
+ uiLayout *layout = menu->layout;
+ uiItemS(layout);
+
+ for (const LibraryAsset &item : asset_items) {
+ uiLayout *col = uiLayoutColumn(layout, false);
+ PointerRNA file{
+ &screen.id, &RNA_FileSelectEntry, const_cast<FileDirEntry *>(item.handle.file_data)};
+ uiLayoutSetContextPointer(col, "active_file", &file);
+
+ PointerRNA library_ptr{&screen.id,
+ &RNA_AssetLibraryReference,
+ const_cast<AssetLibraryReference *>(&item.library_ref)};
+ uiLayoutSetContextPointer(col, "asset_library_ref", &library_ptr);
+
+ uiItemO(col, ED_asset_handle_get_name(&item.handle), ICON_NONE, "NODE_OT_add_group_asset");
+ }
+
+ catalog_item->foreach_child([&](bke::AssetCatalogTreeItem &child_item) {
+ const bke::AssetCatalogPath &path = tree.full_catalog_per_tree_item.lookup(&child_item);
+ PointerRNA path_ptr{
+ &screen.id, &RNA_AssetCatalogPath, const_cast<bke::AssetCatalogPath *>(&path)};
+ uiLayout *col = uiLayoutColumn(layout, false);
+ uiLayoutSetContextPointer(col, "asset_catalog_path", &path_ptr);
+ uiItemM(col, "NODE_MT_node_add_catalog_assets", path.name().c_str(), ICON_NONE);
+ });
+}
+
+static void add_root_catalogs_draw(const bContext *C, Menu *menu)
+{
+ bScreen &screen = *CTX_wm_screen(C);
+ SpaceNode &snode = *CTX_wm_space_node(C);
+ const bNodeTree *edit_tree = snode.edittree;
+ uiLayout *layout = menu->layout;
+
+ snode.runtime->assets_for_menu = std::make_shared<AssetItemTree>(
+ build_catalog_tree(*C, edit_tree));
+
+ const bool loading_finished = all_loading_finished();
+
+ AssetItemTree &tree = *snode.runtime->assets_for_menu;
+ if (tree.catalogs.is_empty() && loading_finished) {
+ return;
+ }
+
+ uiItemS(layout);
+
+ if (!loading_finished) {
+ uiItemL(layout, IFACE_("Loading Asset Libraries"), ICON_INFO);
+ }
+
+ /* Avoid adding a separate root catalog when the assets have already been added to one of the
+ * builtin menus.
+ * TODO: The need to define the builtin menu labels here is completely non-ideal. We don't have
+ * any UI introspection that can do this though. This can be solved in the near future by
+ * removing the need to define the add menu completely, instead using a per-node-type path which
+ * can be merged with catalog tree.
+ */
+ static Set<std::string> all_builtin_menus = []() {
+ Set<std::string> menus;
+ menus.add_new("Attribute");
+ menus.add_new("Color");
+ menus.add_new("Curve");
+ menus.add_new("Curve Primitives");
+ menus.add_new("Curve Topology");
+ menus.add_new("Geometry");
+ menus.add_new("Input");
+ menus.add_new("Instances");
+ menus.add_new("Material");
+ menus.add_new("Mesh");
+ menus.add_new("Mesh Primitives");
+ menus.add_new("Mesh Topology");
+ menus.add_new("Output");
+ menus.add_new("Point");
+ menus.add_new("Text");
+ menus.add_new("Texture");
+ menus.add_new("Utilities");
+ menus.add_new("UV");
+ menus.add_new("Vector");
+ menus.add_new("Volume");
+ menus.add_new("Group");
+ menus.add_new("Layout");
+ return menus;
+ }();
+
+ tree.catalogs.foreach_root_item([&](bke::AssetCatalogTreeItem &item) {
+ if (all_builtin_menus.contains(item.get_name())) {
+ return;
+ }
+ const bke::AssetCatalogPath &path = tree.full_catalog_per_tree_item.lookup(&item);
+ PointerRNA path_ptr{
+ &screen.id, &RNA_AssetCatalogPath, const_cast<bke::AssetCatalogPath *>(&path)};
+ uiLayout *col = uiLayoutColumn(layout, false);
+ uiLayoutSetContextPointer(col, "asset_catalog_path", &path_ptr);
+ uiItemM(col, "NODE_MT_node_add_catalog_assets", path.name().c_str(), ICON_NONE);
+ });
+}
+
+MenuType add_catalog_assets_menu_type()
+{
+ MenuType type{};
+ BLI_strncpy(type.idname, "NODE_MT_node_add_catalog_assets", sizeof(type.idname));
+ type.poll = node_add_menu_poll;
+ type.draw = node_add_catalog_assets_draw;
+ type.listener = node_add_menu_assets_listen_fn;
+ return type;
+}
+
+MenuType add_root_catalogs_menu_type()
+{
+ MenuType type{};
+ BLI_strncpy(type.idname, "NODE_MT_node_add_root_catalogs", sizeof(type.idname));
+ type.poll = node_add_menu_poll;
+ type.draw = add_root_catalogs_draw;
+ type.listener = node_add_menu_assets_listen_fn;
+ return type;
+}
+
+} // namespace blender::ed::space_node
+
+/* Note: This is only necessary because Python can't set an asset catalog path context item. */
+void uiTemplateNodeAssetMenuItems(uiLayout *layout, bContext *C, const char *catalog_path)
+{
+ using namespace blender;
+ using namespace blender::ed::space_node;
+ bScreen &screen = *CTX_wm_screen(C);
+ SpaceNode &snode = *CTX_wm_space_node(C);
+ AssetItemTree &tree = *snode.runtime->assets_for_menu;
+ const bke::AssetCatalogTreeItem *item = tree.catalogs.find_root_item(catalog_path);
+ if (!item) {
+ return;
+ }
+ const bke::AssetCatalogPath &path = tree.full_catalog_per_tree_item.lookup(item);
+ PointerRNA path_ptr{
+ &screen.id, &RNA_AssetCatalogPath, const_cast<bke::AssetCatalogPath *>(&path)};
+ uiItemS(layout);
+ uiLayout *col = uiLayoutColumn(layout, false);
+ uiLayoutSetContextPointer(col, "asset_catalog_path", &path_ptr);
+ uiItemMContents(col, "NODE_MT_node_add_catalog_assets");
+}
diff --git a/source/blender/editors/space_node/add_node_search.cc b/source/blender/editors/space_node/add_node_search.cc
new file mode 100644
index 00000000000..23ec2f2f66e
--- /dev/null
+++ b/source/blender/editors/space_node/add_node_search.cc
@@ -0,0 +1,358 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <optional>
+
+#include "BLI_listbase.h"
+#include "BLI_string_search.h"
+
+#include "DNA_space_types.h"
+
+#include "BKE_asset.h"
+#include "BKE_asset_catalog.hh"
+#include "BKE_asset_library.hh"
+#include "BKE_context.h"
+#include "BKE_idprop.h"
+#include "BKE_lib_id.h"
+#include "BKE_main.h"
+#include "BKE_node_tree_update.h"
+#include "BKE_screen.h"
+
+#include "DEG_depsgraph_build.h"
+
+#include "BLT_translation.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+
+#include "ED_asset.h"
+#include "ED_node.h"
+
+#include "node_intern.hh"
+
+struct bContext;
+
+namespace blender::ed::space_node {
+
+struct AddNodeItem {
+ std::string ui_name;
+ std::string identifier;
+ std::string description;
+ std::optional<AssetHandle> asset;
+ std::function<void(const bContext &, bNodeTree &, bNode &)> after_add_fn;
+ int weight = 0;
+};
+
+struct AddNodeSearchStorage {
+ float2 cursor;
+ bool use_transform;
+ Vector<AddNodeItem> search_add_items;
+ char search[256];
+ bool update_items_tag = true;
+};
+
+static void add_node_search_listen_fn(const wmRegionListenerParams *params, void *arg)
+{
+ AddNodeSearchStorage &storage = *static_cast<AddNodeSearchStorage *>(arg);
+ const wmNotifier *wmn = params->notifier;
+
+ switch (wmn->category) {
+ case NC_ASSET:
+ if (wmn->data == ND_ASSET_LIST_READING) {
+ storage.update_items_tag = true;
+ }
+ break;
+ }
+}
+
+static void search_items_for_asset_metadata(const bNodeTree &node_tree,
+ const AssetLibraryReference &library_ref,
+ const AssetHandle asset,
+ Vector<AddNodeItem> &search_items)
+{
+ const AssetMetaData &asset_data = *ED_asset_handle_get_metadata(&asset);
+ const IDProperty *tree_type = BKE_asset_metadata_idprop_find(&asset_data, "type");
+ if (tree_type == nullptr || IDP_Int(tree_type) != node_tree.type) {
+ return;
+ }
+
+ AddNodeItem item{};
+ item.ui_name = ED_asset_handle_get_name(&asset);
+ item.identifier = node_tree.typeinfo->group_idname;
+ item.description = asset_data.description == nullptr ? "" : asset_data.description;
+ item.asset = asset;
+ item.after_add_fn = [asset, library_ref](const bContext &C, bNodeTree &node_tree, bNode &node) {
+ Main &bmain = *CTX_data_main(&C);
+ node.flag &= ~NODE_OPTIONS;
+ node.id = asset::get_local_id_from_asset_or_append_and_reuse(bmain, library_ref, asset);
+ id_us_plus(node.id);
+ BKE_ntree_update_tag_node_property(&node_tree, &node);
+ DEG_relations_tag_update(&bmain);
+ };
+
+ search_items.append(std::move(item));
+}
+
+static void gather_search_items_for_asset_library(const bContext &C,
+ const bNodeTree &node_tree,
+ const AssetLibraryReference &library_ref,
+ Set<std::string> &r_added_assets,
+ Vector<AddNodeItem> &search_items)
+{
+ AssetFilterSettings filter_settings{};
+ filter_settings.id_types = FILTER_ID_NT;
+
+ ED_assetlist_storage_fetch(&library_ref, &C);
+ ED_assetlist_iterate(library_ref, [&](AssetHandle asset) {
+ if (!ED_asset_filter_matches_asset(&filter_settings, &asset)) {
+ return true;
+ }
+ if (!r_added_assets.add(ED_asset_handle_get_name(&asset))) {
+ /* If an asset with the same name has already been added, skip this. */
+ return true;
+ }
+ search_items_for_asset_metadata(node_tree, library_ref, asset, search_items);
+ return true;
+ });
+}
+
+static void gather_search_items_for_all_assets(const bContext &C,
+ const bNodeTree &node_tree,
+ Set<std::string> &r_added_assets,
+ Vector<AddNodeItem> &search_items)
+{
+ int i;
+ LISTBASE_FOREACH_INDEX (const bUserAssetLibrary *, asset_library, &U.asset_libraries, i) {
+ AssetLibraryReference library_ref{};
+ library_ref.custom_library_index = i;
+ library_ref.type = ASSET_LIBRARY_CUSTOM;
+ /* Skip local assets to avoid duplicates when the asset is part of the local file library. */
+ gather_search_items_for_asset_library(C, node_tree, library_ref, r_added_assets, search_items);
+ }
+
+ AssetLibraryReference library_ref{};
+ library_ref.custom_library_index = -1;
+ library_ref.type = ASSET_LIBRARY_LOCAL;
+ gather_search_items_for_asset_library(C, node_tree, library_ref, r_added_assets, search_items);
+}
+
+static void gather_search_items_for_node_groups(const bContext &C,
+ const bNodeTree &node_tree,
+ const Set<std::string> &local_assets,
+ Vector<AddNodeItem> &search_items)
+{
+ const StringRef group_node_id = node_tree.typeinfo->group_idname;
+
+ Main &bmain = *CTX_data_main(&C);
+ LISTBASE_FOREACH (bNodeTree *, node_group, &bmain.nodetrees) {
+ if (node_group->typeinfo->group_idname != group_node_id) {
+ continue;
+ }
+ if (local_assets.contains(node_group->id.name)) {
+ continue;
+ }
+ if (!nodeGroupPoll(&node_tree, node_group, nullptr)) {
+ continue;
+ }
+ AddNodeItem item{};
+ item.ui_name = node_group->id.name + 2;
+ item.identifier = node_tree.typeinfo->group_idname;
+ item.after_add_fn = [node_group](const bContext &C, bNodeTree &node_tree, bNode &node) {
+ Main &bmain = *CTX_data_main(&C);
+ node.id = &node_group->id;
+ id_us_plus(node.id);
+ BKE_ntree_update_tag_node_property(&node_tree, &node);
+ DEG_relations_tag_update(&bmain);
+ };
+ search_items.append(std::move(item));
+ }
+}
+
+static void gather_add_node_operations(const bContext &C,
+ bNodeTree &node_tree,
+ Vector<AddNodeItem> &r_search_items)
+{
+ NODE_TYPES_BEGIN (node_type) {
+ const char *disabled_hint;
+ if (!(node_type->poll && node_type->poll(node_type, &node_tree, &disabled_hint))) {
+ continue;
+ }
+ if ((StringRefNull(node_tree.typeinfo->group_idname) == node_type->idname)) {
+ /* Skip the empty group type. */
+ continue;
+ }
+ if (StringRefNull(node_type->ui_name).endswith("(Legacy)")) {
+ continue;
+ }
+
+ AddNodeItem item{};
+ item.ui_name = IFACE_(node_type->ui_name);
+ item.identifier = node_type->idname;
+ item.description = TIP_(node_type->ui_description);
+ r_search_items.append(std::move(item));
+ }
+ NODE_TYPES_END;
+
+ /* Use a set to avoid adding items for node groups that are also assets. Using data-block
+ * names is a crutch, since different assets may have the same name. However, an alternative
+ * using #ED_asset_handle_get_local_id didn't work in this case. */
+ Set<std::string> added_assets;
+ gather_search_items_for_all_assets(C, node_tree, added_assets, r_search_items);
+ gather_search_items_for_node_groups(C, node_tree, added_assets, r_search_items);
+}
+
+static void add_node_search_update_fn(
+ const bContext *C, void *arg, const char *str, uiSearchItems *items, const bool is_first)
+{
+ AddNodeSearchStorage &storage = *static_cast<AddNodeSearchStorage *>(arg);
+ if (storage.update_items_tag) {
+ bNodeTree *node_tree = CTX_wm_space_node(C)->edittree;
+ storage.search_add_items.clear();
+ gather_add_node_operations(*C, *node_tree, storage.search_add_items);
+ storage.update_items_tag = false;
+ }
+
+ StringSearch *search = BLI_string_search_new();
+
+ for (AddNodeItem &item : storage.search_add_items) {
+ BLI_string_search_add(search, item.ui_name.c_str(), &item, item.weight);
+ }
+
+ /* Don't filter when the menu is first opened, but still run the search
+ * so the items are in the same order they will appear in while searching. */
+ const char *string = is_first ? "" : str;
+ AddNodeItem **filtered_items;
+ const int filtered_amount = BLI_string_search_query(search, string, (void ***)&filtered_items);
+
+ for (const int i : IndexRange(filtered_amount)) {
+ AddNodeItem &item = *filtered_items[i];
+ if (!UI_search_item_add(items, item.ui_name.c_str(), &item, ICON_NONE, 0, 0)) {
+ break;
+ }
+ }
+
+ MEM_freeN(filtered_items);
+ BLI_string_search_free(search);
+}
+
+static void add_node_search_exec_fn(bContext *C, void *arg1, void *arg2)
+{
+ Main &bmain = *CTX_data_main(C);
+ SpaceNode &snode = *CTX_wm_space_node(C);
+ bNodeTree &node_tree = *snode.edittree;
+ AddNodeSearchStorage &storage = *static_cast<AddNodeSearchStorage *>(arg1);
+ AddNodeItem *item = static_cast<AddNodeItem *>(arg2);
+ if (item == nullptr) {
+ return;
+ }
+
+ node_deselect_all(snode);
+ bNode *new_node = nodeAddNode(C, &node_tree, item->identifier.c_str());
+ BLI_assert(new_node != nullptr);
+
+ if (item->after_add_fn) {
+ item->after_add_fn(*C, node_tree, *new_node);
+ }
+
+ new_node->locx = storage.cursor.x / UI_DPI_FAC;
+ new_node->locy = storage.cursor.y / UI_DPI_FAC + 20 * UI_DPI_FAC;
+
+ nodeSetSelected(new_node, true);
+ nodeSetActive(&node_tree, new_node);
+
+ /* Ideally it would be possible to tag the node tree in some way so it updates only after the
+ * translate operation is finished, but normally moving nodes around doesn't cause updates. */
+ ED_node_tree_propagate_change(C, &bmain, &node_tree);
+
+ if (storage.use_transform) {
+ wmOperatorType *ot = WM_operatortype_find("NODE_OT_translate_attach_remove_on_cancel", true);
+ BLI_assert(ot);
+ PointerRNA ptr;
+ WM_operator_properties_create_ptr(&ptr, ot);
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, nullptr);
+ WM_operator_properties_free(&ptr);
+ }
+}
+
+static ARegion *add_node_search_tooltip_fn(
+ bContext *C, ARegion *region, const rcti *item_rect, void * /*arg*/, void *active)
+{
+ const AddNodeItem *item = static_cast<const AddNodeItem *>(active);
+
+ uiSearchItemTooltipData tooltip_data{};
+
+ BLI_strncpy(tooltip_data.description,
+ item->asset ? item->description.c_str() : TIP_(item->description.c_str()),
+ sizeof(tooltip_data.description));
+
+ return UI_tooltip_create_from_search_item_generic(C, region, item_rect, &tooltip_data);
+}
+
+static void add_node_search_free_fn(void *arg)
+{
+ AddNodeSearchStorage *storage = static_cast<AddNodeSearchStorage *>(arg);
+ delete storage;
+}
+
+static uiBlock *create_search_popup_block(bContext *C, ARegion *region, void *arg_op)
+{
+ AddNodeSearchStorage &storage = *(AddNodeSearchStorage *)arg_op;
+
+ uiBlock *block = UI_block_begin(C, region, "_popup", UI_EMBOSS);
+ UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
+ UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
+
+ uiBut *but = uiDefSearchBut(block,
+ storage.search,
+ 0,
+ ICON_VIEWZOOM,
+ sizeof(storage.search),
+ 10,
+ 10,
+ UI_searchbox_size_x(),
+ UI_UNIT_Y,
+ 0,
+ 0,
+ "");
+ UI_but_func_search_set_sep_string(but, UI_MENU_ARROW_SEP);
+ UI_but_func_search_set(but,
+ nullptr,
+ add_node_search_update_fn,
+ &storage,
+ false,
+ add_node_search_free_fn,
+ add_node_search_exec_fn,
+ nullptr);
+ UI_but_flag_enable(but, UI_BUT_ACTIVATE_ON_INIT);
+ UI_but_func_search_set_tooltip(but, add_node_search_tooltip_fn);
+ UI_but_func_search_set_listen(but, add_node_search_listen_fn);
+
+ /* Fake button to hold space for the search items. */
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ "",
+ 10,
+ 10 - UI_searchbox_size_y(),
+ UI_searchbox_size_x(),
+ UI_searchbox_size_y(),
+ nullptr,
+ 0,
+ 0,
+ 0,
+ 0,
+ nullptr);
+
+ const int offset[2] = {0, -UI_UNIT_Y};
+ UI_block_bounds_set_popup(block, 0.3f * U.widget_unit, offset);
+ return block;
+}
+
+void invoke_add_node_search_menu(bContext &C, const float2 &cursor, const bool use_transform)
+{
+ AddNodeSearchStorage *storage = new AddNodeSearchStorage{cursor, use_transform};
+ /* Use the "_ex" variant with `can_refresh` false to avoid a double free when closing Blender. */
+ UI_popup_block_invoke_ex(&C, create_search_popup_block, storage, nullptr, false);
+}
+
+} // namespace blender::ed::space_node
diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc
index fbbdd40e92e..c66b8ad4ff0 100644
--- a/source/blender/editors/space_node/drawnode.cc
+++ b/source/blender/editors/space_node/drawnode.cc
@@ -73,10 +73,10 @@ namespace blender::ed::space_node {
/* ****************** SOCKET BUTTON DRAW FUNCTIONS ***************** */
-static void node_socket_button_label(bContext *UNUSED(C),
+static void node_socket_button_label(bContext * /*C*/,
uiLayout *layout,
- PointerRNA *UNUSED(ptr),
- PointerRNA *UNUSED(node_ptr),
+ PointerRNA * /*ptr*/,
+ PointerRNA * /*node_ptr*/,
const char *text)
{
uiItemL(layout, text, 0);
@@ -84,7 +84,7 @@ static void node_socket_button_label(bContext *UNUSED(C),
/* ****************** BUTTON CALLBACKS FOR ALL TREES ***************** */
-static void node_buts_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_buts_value(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
/* first output stores value */
@@ -95,7 +95,7 @@ static void node_buts_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *p
uiItemR(layout, &sockptr, "default_value", DEFAULT_FLAGS, "", ICON_NONE);
}
-static void node_buts_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_buts_rgb(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
/* first output stores value */
@@ -109,7 +109,7 @@ static void node_buts_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr
uiItemR(col, &sockptr, "default_value", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
}
-static void node_buts_mix_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_buts_mix_rgb(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
@@ -123,7 +123,7 @@ static void node_buts_mix_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA
uiItemR(col, ptr, "use_clamp", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
-static void node_buts_time(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_buts_time(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiTemplateCurveMapping(layout, ptr, "curve", 's', false, false, false, false);
@@ -132,17 +132,17 @@ static void node_buts_time(uiLayout *layout, bContext *UNUSED(C), PointerRNA *pt
uiItemR(col, ptr, "frame_end", DEFAULT_FLAGS, IFACE_("End"), ICON_NONE);
}
-static void node_buts_colorramp(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_buts_colorramp(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiTemplateColorRamp(layout, ptr, "color_ramp", false);
}
-static void node_buts_curvevec(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_buts_curvevec(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiTemplateCurveMapping(layout, ptr, "mapping", 'v', false, false, false, false);
}
-static void node_buts_curvefloat(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_buts_curvefloat(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiTemplateCurveMapping(layout, ptr, "mapping", 0, false, false, false, false);
}
@@ -164,7 +164,7 @@ void ED_node_sample_set(const float col[4])
namespace blender::ed::space_node {
-static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_buts_curvecol(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
CurveMapping *cumap = (CurveMapping *)node->storage;
@@ -183,7 +183,7 @@ static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA
layout, ptr, "mapping", 'c', false, false, false, (ntree->type == NTREE_COMPOSIT));
}
-static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_buts_normal(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
/* first output stores normal */
@@ -194,7 +194,7 @@ static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA *
uiItemR(layout, &sockptr, "default_value", DEFAULT_FLAGS, "", ICON_NONE);
}
-static void node_buts_texture(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_buts_texture(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
@@ -209,13 +209,13 @@ static void node_buts_texture(uiLayout *layout, bContext *UNUSED(C), PointerRNA
}
}
-static void node_buts_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_buts_math(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE);
uiItemR(layout, ptr, "use_clamp", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
-static void node_buts_combsep_color(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_buts_combsep_color(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", DEFAULT_FLAGS, "", ICON_NONE);
}
@@ -283,7 +283,7 @@ static void node_draw_buttons_group(uiLayout *layout, bContext *C, PointerRNA *p
layout, C, ptr, "node_tree", nullptr, nullptr, nullptr, UI_TEMPLATE_ID_FILTER_ALL, nullptr);
}
-static void node_buts_frame_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_buts_frame_ex(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "label_size", DEFAULT_FLAGS, IFACE_("Label Size"), ICON_NONE);
uiItemR(layout, ptr, "shrink", DEFAULT_FLAGS, IFACE_("Shrink"), ICON_NONE);
@@ -441,17 +441,17 @@ static void node_shader_buts_tex_environment_ex(uiLayout *layout, bContext *C, P
uiItemR(layout, ptr, "projection", DEFAULT_FLAGS, IFACE_("Projection"), ICON_NONE);
}
-static void node_shader_buts_displacement(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_displacement(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "space", DEFAULT_FLAGS, "", 0);
}
-static void node_shader_buts_glossy(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_glossy(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "distribution", DEFAULT_FLAGS, "", ICON_NONE);
}
-static void node_buts_output_shader(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_buts_output_shader(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "target", DEFAULT_FLAGS, "", ICON_NONE);
}
@@ -519,7 +519,7 @@ static void node_shader_set_butfunc(bNodeType *ntype)
/* ****************** BUTTON CALLBACKS FOR COMPOSITE NODES ***************** */
static void node_buts_image_views(uiLayout *layout,
- bContext *UNUSED(C),
+ bContext * /*C*/,
PointerRNA *ptr,
PointerRNA *imaptr)
{
@@ -579,7 +579,7 @@ static void node_composit_buts_image_ex(uiLayout *layout, bContext *C, PointerRN
uiTemplateImage(layout, C, ptr, "image", &iuserptr, false, true);
}
-static void node_composit_buts_huecorrect(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_huecorrect(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
CurveMapping *cumap = (CurveMapping *)node->storage;
@@ -595,14 +595,12 @@ static void node_composit_buts_huecorrect(uiLayout *layout, bContext *UNUSED(C),
uiTemplateCurveMapping(layout, ptr, "mapping", 'h', false, false, false, false);
}
-static void node_composit_buts_ycc(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_ycc(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", DEFAULT_FLAGS, "", ICON_NONE);
}
-static void node_composit_buts_combsep_color(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_composit_buts_combsep_color(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)node->storage;
@@ -733,7 +731,7 @@ static void node_composit_backdrop_ellipsemask(
}
static void node_composit_buts_cryptomatte_legacy(uiLayout *layout,
- bContext *UNUSED(C),
+ bContext * /*C*/,
PointerRNA *ptr)
{
uiLayout *col = uiLayoutColumn(layout, true);
@@ -748,8 +746,8 @@ static void node_composit_buts_cryptomatte_legacy(uiLayout *layout,
}
static void node_composit_buts_cryptomatte_legacy_ex(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *UNUSED(ptr))
+ bContext * /*C*/,
+ PointerRNA * /*ptr*/)
{
uiItemO(layout, IFACE_("Add Crypto Layer"), ICON_ADD, "NODE_OT_cryptomatte_layer_add");
uiItemO(layout, IFACE_("Remove Crypto Layer"), ICON_REMOVE, "NODE_OT_cryptomatte_layer_remove");
@@ -874,7 +872,7 @@ static void node_composit_set_butfunc(bNodeType *ntype)
/* ****************** BUTTON CALLBACKS FOR TEXTURE NODES ***************** */
-static void node_texture_buts_bricks(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_texture_buts_bricks(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
@@ -887,7 +885,7 @@ static void node_texture_buts_bricks(uiLayout *layout, bContext *UNUSED(C), Poin
uiItemR(col, ptr, "squash_frequency", DEFAULT_FLAGS, IFACE_("Frequency"), ICON_NONE);
}
-static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_texture_buts_proc(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
PointerRNA tex_ptr;
bNode *node = (bNode *)ptr->data;
@@ -938,7 +936,7 @@ static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), Pointe
uiItemR(
row, &tex_ptr, "noise_basis_2", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
row = uiLayoutRow(col, false);
- uiLayoutSetActive(row, !(ELEM(tex->stype, TEX_BAND, TEX_RING)));
+ uiLayoutSetActive(row, !ELEM(tex->stype, TEX_BAND, TEX_RING));
uiItemR(row, &tex_ptr, "noise_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
break;
@@ -998,12 +996,12 @@ static void node_texture_buts_image_ex(uiLayout *layout, bContext *C, PointerRNA
uiTemplateImage(layout, C, ptr, "image", &iuserptr, false, false);
}
-static void node_texture_buts_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_texture_buts_output(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "filepath", DEFAULT_FLAGS, "", ICON_NONE);
}
-static void node_texture_buts_combsep_color(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_texture_buts_combsep_color(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", DEFAULT_FLAGS, "", ICON_NONE);
}
@@ -1068,7 +1066,7 @@ static void node_texture_set_butfunc(bNodeType *ntype)
* Only called on node initialization, once.
* \{ */
-static void node_property_update_default(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
+static void node_property_update_default(Main *bmain, Scene * /*scene*/, PointerRNA *ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
bNode *node = (bNode *)ptr->data;
@@ -1102,18 +1100,18 @@ static void node_template_properties_update(bNodeType *ntype)
}
}
-static void node_socket_undefined_draw(bContext *UNUSED(C),
+static void node_socket_undefined_draw(bContext * /*C*/,
uiLayout *layout,
- PointerRNA *UNUSED(ptr),
- PointerRNA *UNUSED(node_ptr),
- const char *UNUSED(text))
+ PointerRNA * /*ptr*/,
+ PointerRNA * /*node_ptr*/,
+ const char * /*text*/)
{
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),
+static void node_socket_undefined_draw_color(bContext * /*C*/,
+ PointerRNA * /*ptr*/,
+ PointerRNA * /*node_ptr*/,
float *r_color)
{
r_color[0] = 1.0f;
@@ -1122,15 +1120,15 @@ static void node_socket_undefined_draw_color(bContext *UNUSED(C),
r_color[3] = 1.0f;
}
-static void node_socket_undefined_interface_draw(bContext *UNUSED(C),
+static void node_socket_undefined_interface_draw(bContext * /*C*/,
uiLayout *layout,
- PointerRNA *UNUSED(ptr))
+ PointerRNA * /*ptr*/)
{
uiItemL(layout, IFACE_("Undefined Socket Type"), ICON_ERROR);
}
-static void node_socket_undefined_interface_draw_color(bContext *UNUSED(C),
- PointerRNA *UNUSED(ptr),
+static void node_socket_undefined_interface_draw_color(bContext * /*C*/,
+ PointerRNA * /*ptr*/,
float *r_color)
{
r_color[0] = 1.0f;
@@ -1173,7 +1171,7 @@ void ED_node_init_butfuncs()
NODE_TYPES_END;
}
-void ED_init_custom_node_type(bNodeType *UNUSED(ntype))
+void ED_init_custom_node_type(bNodeType * /*ntype*/)
{
}
@@ -1205,18 +1203,16 @@ static const float std_node_socket_colors[][4] = {
};
/* common color callbacks for standard types */
-static void std_node_socket_draw_color(bContext *UNUSED(C),
+static void std_node_socket_draw_color(bContext * /*C*/,
PointerRNA *ptr,
- PointerRNA *UNUSED(node_ptr),
+ PointerRNA * /*node_ptr*/,
float *r_color)
{
bNodeSocket *sock = (bNodeSocket *)ptr->data;
int type = sock->typeinfo->type;
copy_v4_v4(r_color, std_node_socket_colors[type]);
}
-static void std_node_socket_interface_draw_color(bContext *UNUSED(C),
- PointerRNA *ptr,
- float *r_color)
+static void std_node_socket_interface_draw_color(bContext * /*C*/, PointerRNA *ptr, float *r_color)
{
bNodeSocket *sock = (bNodeSocket *)ptr->data;
int type = sock->typeinfo->type;
@@ -1425,7 +1421,7 @@ static void std_node_socket_draw(
}
}
-static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout, PointerRNA *ptr)
+static void std_node_socket_interface_draw(bContext * /*C*/, uiLayout *layout, PointerRNA *ptr)
{
bNodeSocket *sock = (bNodeSocket *)ptr->data;
int type = sock->typeinfo->type;
@@ -1469,9 +1465,9 @@ static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout
uiItemR(layout, ptr, "hide_value", DEFAULT_FLAGS, nullptr, 0);
}
-static void node_socket_virtual_draw_color(bContext *UNUSED(C),
- PointerRNA *UNUSED(ptr),
- PointerRNA *UNUSED(node_ptr),
+static void node_socket_virtual_draw_color(bContext * /*C*/,
+ PointerRNA * /*ptr*/,
+ PointerRNA * /*node_ptr*/,
float *r_color)
{
copy_v4_v4(r_color, virtual_node_socket_color);
@@ -1585,10 +1581,12 @@ void draw_nodespace_back_pix(const bContext &C,
GPU_matrix_pop();
}
-static float2 socket_link_connection_location(const bNodeSocket &socket, const bNodeLink &link)
+static float2 socket_link_connection_location(const bNode &node,
+ const bNodeSocket &socket,
+ const bNodeLink &link)
{
const float2 socket_location(socket.locx, socket.locy);
- if (socket.flag & SOCK_MULTI_INPUT && socket.in_out == SOCK_IN) {
+ if (socket.is_multi_input() && socket.is_input() && !(node.flag & NODE_HIDDEN)) {
return node_link_calculate_multi_input_position(
socket_location, link.multi_input_socket_index, socket.total_inputs);
}
@@ -1604,12 +1602,19 @@ static void calculate_inner_link_bezier_points(std::array<float2, 4> &points)
points[2] = math::interpolate(points[0], points[3], 2.0f / 3.0f);
}
else {
- const float dist = curving * 0.1f * math::distance(points[0].x, points[3].x);
+ const float dist_x = math::distance(points[0].x, points[3].x);
+ const float dist_y = math::distance(points[0].y, points[3].y);
- points[1].x = points[0].x + dist;
+ /* Reduce the handle offset when the link endpoints are close to horizontal. */
+ const float slope = safe_divide(dist_y, dist_x);
+ const float clamp_factor = math::min(1.0f, slope * (4.5f - 0.25f * float(curving)));
+
+ const float handle_offset = curving * 0.1f * dist_x * clamp_factor;
+
+ points[1].x = points[0].x + handle_offset;
points[1].y = points[0].y;
- points[2].x = points[3].x - dist;
+ points[2].x = points[3].x - handle_offset;
points[2].y = points[3].y;
}
}
@@ -1617,8 +1622,8 @@ static void calculate_inner_link_bezier_points(std::array<float2, 4> &points)
static std::array<float2, 4> node_link_bezier_points(const bNodeLink &link)
{
std::array<float2, 4> points;
- points[0] = socket_link_connection_location(*link.fromsock, link);
- points[3] = socket_link_connection_location(*link.tosock, link);
+ points[0] = socket_link_connection_location(*link.fromnode, *link.fromsock, link);
+ points[3] = socket_link_connection_location(*link.tonode, *link.tosock, link);
calculate_inner_link_bezier_points(points);
return points;
}
@@ -1757,7 +1762,7 @@ static void nodelink_batch_init()
/* curve strip */
for (int i = 0; i < LINK_RESOL; i++) {
- uv[0] = 255 * (i / (float)(LINK_RESOL - 1));
+ uv[0] = 255 * (i / float(LINK_RESOL - 1));
uv[1] = 0;
set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
uv[1] = 255;
@@ -1901,7 +1906,7 @@ static void nodelink_batch_draw(const SpaceNode &snode)
GPU_blend(GPU_BLEND_NONE);
}
-void nodelink_batch_start(SpaceNode &UNUSED(snode))
+void nodelink_batch_start(SpaceNode & /*snode*/)
{
g_batch_link.enabled = true;
}
@@ -1976,7 +1981,7 @@ static void node_draw_link_end_marker(const float2 center,
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(&rect, true, radius, color);
- /* Roundbox disables alpha. Reenable it for node links that are drawn after this one. */
+ /* Round-box disables alpha. Re-enable it for node links that are drawn after this one. */
GPU_blend(GPU_BLEND_ALPHA);
}
@@ -2209,8 +2214,11 @@ static std::array<float2, 4> node_link_bezier_points_dragged(const SpaceNode &sn
{
const float2 cursor = snode.runtime->cursor * UI_DPI_FAC;
std::array<float2, 4> points;
- points[0] = link.fromsock ? socket_link_connection_location(*link.fromsock, link) : cursor;
- points[3] = link.tosock ? socket_link_connection_location(*link.tosock, link) : cursor;
+ points[0] = link.fromsock ?
+ socket_link_connection_location(*link.fromnode, *link.fromsock, link) :
+ cursor;
+ points[3] = link.tosock ? socket_link_connection_location(*link.tonode, *link.tosock, link) :
+ cursor;
calculate_inner_link_bezier_points(points);
return points;
}
diff --git a/source/blender/editors/space_node/link_drag_search.cc b/source/blender/editors/space_node/link_drag_search.cc
index f1387da97b5..b2dfbd47aeb 100644
--- a/source/blender/editors/space_node/link_drag_search.cc
+++ b/source/blender/editors/space_node/link_drag_search.cc
@@ -5,7 +5,12 @@
#include "DNA_space_types.h"
+#include "BKE_asset.h"
#include "BKE_context.h"
+#include "BKE_idprop.h"
+#include "BKE_lib_id.h"
+#include "BKE_node_tree_update.h"
+#include "BKE_screen.h"
#include "NOD_socket_search_link.hh"
@@ -15,6 +20,9 @@
#include "WM_api.h"
+#include "DEG_depsgraph_build.h"
+
+#include "ED_asset.h"
#include "ED_node.h"
#include "node_intern.hh"
@@ -29,6 +37,7 @@ struct LinkDragSearchStorage {
float2 cursor;
Vector<SocketLinkOperation> search_link_ops;
char search[256];
+ bool update_items_tag = true;
eNodeSocketInOut in_out() const
{
@@ -36,6 +45,20 @@ struct LinkDragSearchStorage {
}
};
+static void link_drag_search_listen_fn(const wmRegionListenerParams *params, void *arg)
+{
+ LinkDragSearchStorage &storage = *static_cast<LinkDragSearchStorage *>(arg);
+ const wmNotifier *wmn = params->notifier;
+
+ switch (wmn->category) {
+ case NC_ASSET:
+ if (wmn->data == ND_ASSET_LIST_READING) {
+ storage.update_items_tag = true;
+ }
+ break;
+ }
+}
+
static void add_reroute_node_fn(nodes::LinkSearchOpParams &params)
{
bNode &reroute = params.add_node("NodeReroute");
@@ -112,11 +135,136 @@ static void add_existing_group_input_fn(nodes::LinkSearchOpParams &params,
}
/**
+ * \note This could use #search_link_ops_for_socket_templates, but we have to store the inputs and
+ * outputs as IDProperties for assets because of asset indexing, so that's all we have without
+ * loading the file.
+ */
+static void search_link_ops_for_asset_metadata(const bNodeTree &node_tree,
+ const bNodeSocket &socket,
+ const AssetLibraryReference &library_ref,
+ const AssetHandle asset,
+ Vector<SocketLinkOperation> &search_link_ops)
+{
+ const AssetMetaData &asset_data = *ED_asset_handle_get_metadata(&asset);
+ const IDProperty *tree_type = BKE_asset_metadata_idprop_find(&asset_data, "type");
+ if (tree_type == nullptr || IDP_Int(tree_type) != node_tree.type) {
+ return;
+ }
+
+ const bNodeTreeType &node_tree_type = *node_tree.typeinfo;
+ const eNodeSocketInOut in_out = socket.in_out == SOCK_OUT ? SOCK_IN : SOCK_OUT;
+
+ const IDProperty *sockets = BKE_asset_metadata_idprop_find(
+ &asset_data, in_out == SOCK_IN ? "inputs" : "outputs");
+
+ int weight = -1;
+ Set<StringRef> socket_names;
+ LISTBASE_FOREACH (IDProperty *, socket_property, &sockets->data.group) {
+ if (socket_property->type != IDP_STRING) {
+ continue;
+ }
+ const char *socket_idname = IDP_String(socket_property);
+ const bNodeSocketType *socket_type = nodeSocketTypeFind(socket_idname);
+ if (socket_type == nullptr) {
+ continue;
+ }
+ eNodeSocketDatatype from = (eNodeSocketDatatype)socket.type;
+ eNodeSocketDatatype to = (eNodeSocketDatatype)socket_type->type;
+ if (socket.in_out == SOCK_OUT) {
+ std::swap(from, to);
+ }
+ if (node_tree_type.validate_link && !node_tree_type.validate_link(from, to)) {
+ continue;
+ }
+ if (!socket_names.add(socket_property->name)) {
+ /* See comment in #search_link_ops_for_declarations. */
+ continue;
+ }
+
+ const StringRef asset_name = ED_asset_handle_get_name(&asset);
+ const StringRef socket_name = socket_property->name;
+
+ search_link_ops.append(
+ {asset_name + " " + UI_MENU_ARROW_SEP + socket_name,
+ [library_ref, asset, socket_property, in_out](nodes::LinkSearchOpParams &params) {
+ Main &bmain = *CTX_data_main(&params.C);
+
+ bNode &node = params.add_node(params.node_tree.typeinfo->group_idname);
+ node.flag &= ~NODE_OPTIONS;
+
+ node.id = asset::get_local_id_from_asset_or_append_and_reuse(bmain, library_ref, asset);
+ id_us_plus(node.id);
+ BKE_ntree_update_tag_node_property(&params.node_tree, &node);
+ DEG_relations_tag_update(&bmain);
+
+ /* Create the inputs and outputs on the new node. */
+ node.typeinfo->group_update_func(&params.node_tree, &node);
+
+ bNodeSocket *new_node_socket = bke::node_find_enabled_socket(
+ node, in_out, socket_property->name);
+ if (new_node_socket != nullptr) {
+ /* Rely on the way #nodeAddLink switches in/out if necessary. */
+ nodeAddLink(&params.node_tree, &params.node, &params.socket, &node, new_node_socket);
+ }
+ },
+ weight});
+
+ weight--;
+ }
+}
+
+static void gather_search_link_ops_for_asset_library(const bContext &C,
+ const bNodeTree &node_tree,
+ const bNodeSocket &socket,
+ const AssetLibraryReference &library_ref,
+ const bool skip_local,
+ Vector<SocketLinkOperation> &search_link_ops)
+{
+ AssetFilterSettings filter_settings{};
+ filter_settings.id_types = FILTER_ID_NT;
+
+ ED_assetlist_storage_fetch(&library_ref, &C);
+ ED_assetlist_iterate(library_ref, [&](AssetHandle asset) {
+ if (!ED_asset_filter_matches_asset(&filter_settings, &asset)) {
+ return true;
+ }
+ if (skip_local && ED_asset_handle_get_local_id(&asset) != nullptr) {
+ return true;
+ }
+ search_link_ops_for_asset_metadata(node_tree, socket, library_ref, asset, search_link_ops);
+ return true;
+ });
+}
+
+static void gather_search_link_ops_for_all_assets(const bContext &C,
+ const bNodeTree &node_tree,
+ const bNodeSocket &socket,
+ Vector<SocketLinkOperation> &search_link_ops)
+{
+ int i;
+ LISTBASE_FOREACH_INDEX (const bUserAssetLibrary *, asset_library, &U.asset_libraries, i) {
+ AssetLibraryReference library_ref{};
+ library_ref.custom_library_index = i;
+ library_ref.type = ASSET_LIBRARY_CUSTOM;
+ /* Skip local assets to avoid duplicates when the asset is part of the local file library. */
+ gather_search_link_ops_for_asset_library(
+ C, node_tree, socket, library_ref, true, search_link_ops);
+ }
+
+ AssetLibraryReference library_ref{};
+ library_ref.custom_library_index = -1;
+ library_ref.type = ASSET_LIBRARY_LOCAL;
+ gather_search_link_ops_for_asset_library(
+ C, node_tree, socket, library_ref, false, search_link_ops);
+}
+
+/**
* Call the callback to gather compatible socket connections for all node types, and the operations
* that will actually make the connections. Also add some custom operations like connecting a group
* output node.
*/
-static void gather_socket_link_operations(bNodeTree &node_tree,
+static void gather_socket_link_operations(const bContext &C,
+ bNodeTree &node_tree,
const bNodeSocket &socket,
Vector<SocketLinkOperation> &search_link_ops)
{
@@ -125,7 +273,9 @@ static void gather_socket_link_operations(bNodeTree &node_tree,
if (!(node_type->poll && node_type->poll(node_type, &node_tree, &disabled_hint))) {
continue;
}
-
+ if (StringRefNull(node_type->ui_name).endswith("(Legacy)")) {
+ continue;
+ }
if (node_type->gather_link_search_ops) {
nodes::GatherLinkSearchOpParams params{*node_type, node_tree, socket, search_link_ops};
node_type->gather_link_search_ops(params);
@@ -156,15 +306,20 @@ static void gather_socket_link_operations(bNodeTree &node_tree,
weight--;
}
}
+
+ gather_search_link_ops_for_all_assets(C, node_tree, socket, search_link_ops);
}
-static void link_drag_search_update_fn(const bContext *UNUSED(C),
- void *arg,
- const char *str,
- uiSearchItems *items,
- const bool is_first)
+static void link_drag_search_update_fn(
+ const bContext *C, void *arg, const char *str, uiSearchItems *items, const bool is_first)
{
LinkDragSearchStorage &storage = *static_cast<LinkDragSearchStorage *>(arg);
+ if (storage.update_items_tag) {
+ bNodeTree *node_tree = CTX_wm_space_node(C)->edittree;
+ storage.search_link_ops.clear();
+ gather_socket_link_operations(*C, *node_tree, storage.from_socket, storage.search_link_ops);
+ storage.update_items_tag = false;
+ }
StringSearch *search = BLI_string_search_new();
@@ -214,7 +369,7 @@ static void link_drag_search_exec_fn(bContext *C, void *arg1, void *arg2)
bNode *new_node = new_nodes.first();
new_node->locx = storage.cursor.x / UI_DPI_FAC;
- new_node->locy = storage.cursor.y / UI_DPI_FAC + 20 * UI_DPI_FAC;
+ new_node->locy = storage.cursor.y / UI_DPI_FAC + 20;
if (storage.in_out() == SOCK_IN) {
new_node->locx -= new_node->width;
}
@@ -245,9 +400,6 @@ static uiBlock *create_search_popup_block(bContext *C, ARegion *region, void *ar
{
LinkDragSearchStorage &storage = *(LinkDragSearchStorage *)arg_op;
- bNodeTree &node_tree = *CTX_wm_space_node(C)->edittree;
- gather_socket_link_operations(node_tree, storage.from_socket, storage.search_link_ops);
-
uiBlock *block = UI_block_begin(C, region, "_popup", UI_EMBOSS);
UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
@@ -265,6 +417,7 @@ static uiBlock *create_search_popup_block(bContext *C, ARegion *region, void *ar
0,
"");
UI_but_func_search_set_sep_string(but, UI_MENU_ARROW_SEP);
+ UI_but_func_search_set_listen(but, link_drag_search_listen_fn);
UI_but_func_search_set(but,
nullptr,
link_drag_search_update_fn,
diff --git a/source/blender/editors/space_node/node_add.cc b/source/blender/editors/space_node/node_add.cc
index 9949037479e..41f70a6d8cf 100644
--- a/source/blender/editors/space_node/node_add.cc
+++ b/source/blender/editors/space_node/node_add.cc
@@ -30,6 +30,7 @@
#include "DEG_depsgraph_build.h"
+#include "ED_asset.h"
#include "ED_node.h" /* own include */
#include "ED_render.h"
#include "ED_screen.h"
@@ -194,15 +195,16 @@ static int add_reroute_exec(bContext *C, wmOperator *op)
}
/* Place the new reroute at the average location of all connected cuts. */
- const float2 loc = std::accumulate(cuts.values().begin(), cuts.values().end(), float2(0)) /
- cuts.size() / UI_DPI_FAC;
- reroute->locx = loc.x;
- reroute->locy = loc.y;
+ const float2 insert_point = std::accumulate(
+ cuts.values().begin(), cuts.values().end(), float2(0)) /
+ cuts.size();
+ reroute->locx = insert_point.x / UI_DPI_FAC;
+ reroute->locy = insert_point.y / UI_DPI_FAC;
/* Attach the reroute node to frame nodes behind it. */
for (const int i : frame_nodes.index_range()) {
bNode *frame_node = frame_nodes.last(i);
- if (BLI_rctf_isect_pt_v(&frame_node->totr, loc)) {
+ if (BLI_rctf_isect_pt_v(&frame_node->totr, insert_point)) {
nodeAttachNode(reroute, frame_node);
break;
}
@@ -243,38 +245,36 @@ void NODE_OT_add_reroute(wmOperatorType *ot)
/** \name Add Node Group Operator
* \{ */
-static bNodeTree *node_add_group_get_and_poll_group_node_tree(Main *bmain,
- wmOperator *op,
- bNodeTree *ntree)
+static bool node_group_add_poll(const bNodeTree &node_tree,
+ const bNodeTree &node_group,
+ ReportList &reports)
{
- bNodeTree *node_group = reinterpret_cast<bNodeTree *>(
- WM_operator_properties_id_lookup_from_name_or_session_uuid(bmain, op->ptr, ID_NT));
- if (!node_group) {
- return nullptr;
+ if (node_group.type != node_tree.type) {
+ return false;
}
const char *disabled_hint = nullptr;
- if ((node_group->type != ntree->type) || !nodeGroupPoll(ntree, node_group, &disabled_hint)) {
+ if (!nodeGroupPoll(&node_tree, &node_group, &disabled_hint)) {
if (disabled_hint) {
- BKE_reportf(op->reports,
+ BKE_reportf(&reports,
RPT_ERROR,
"Can not add node group '%s' to '%s':\n %s",
- node_group->id.name + 2,
- ntree->id.name + 2,
+ node_group.id.name + 2,
+ node_tree.id.name + 2,
disabled_hint);
}
else {
- BKE_reportf(op->reports,
+ BKE_reportf(&reports,
RPT_ERROR,
"Can not add node group '%s' to '%s'",
- node_group->id.name + 2,
- ntree->id.name + 2);
+ node_group.id.name + 2,
+ node_tree.id.name + 2);
}
- return nullptr;
+ return false;
}
- return node_group;
+ return true;
}
static int node_add_group_exec(bContext *C, wmOperator *op)
@@ -283,10 +283,14 @@ static int node_add_group_exec(bContext *C, wmOperator *op)
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *ntree = snode->edittree;
- bNodeTree *node_group = node_add_group_get_and_poll_group_node_tree(bmain, op, ntree);
+ bNodeTree *node_group = reinterpret_cast<bNodeTree *>(
+ WM_operator_properties_id_lookup_from_name_or_session_uuid(bmain, op->ptr, ID_NT));
if (!node_group) {
return OPERATOR_CANCELLED;
}
+ if (!node_group_add_poll(*ntree, *node_group, *op->reports)) {
+ return OPERATOR_CANCELLED;
+ }
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
@@ -319,9 +323,8 @@ static bool node_add_group_poll(bContext *C)
}
const SpaceNode *snode = CTX_wm_space_node(C);
if (snode->edittree->type == NTREE_CUSTOM) {
- CTX_wm_operator_poll_msg_set(C,
- "This node editor displays a custom (Python defined) node tree. "
- "Dropping node groups isn't supported for this");
+ CTX_wm_operator_poll_msg_set(
+ C, "Adding node groups isn't supported for custom (Python defined) node trees");
return false;
}
return true;
@@ -366,6 +369,105 @@ void NODE_OT_add_group(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Add Node Group Asset Operator
+ * \{ */
+
+static bool add_node_group_asset(const bContext &C,
+ const AssetLibraryReference &library_ref,
+ const AssetHandle asset,
+ ReportList &reports)
+{
+ Main &bmain = *CTX_data_main(&C);
+ SpaceNode &snode = *CTX_wm_space_node(&C);
+ bNodeTree &edit_tree = *snode.edittree;
+
+ bNodeTree *node_group = reinterpret_cast<bNodeTree *>(
+ asset::get_local_id_from_asset_or_append_and_reuse(bmain, library_ref, asset));
+ if (!node_group) {
+ return false;
+ }
+ if (!node_group_add_poll(edit_tree, *node_group, reports)) {
+ /* Remove the node group if it was newly appended but can't be added to the tree. */
+ id_us_plus(&node_group->id);
+ BKE_id_free_us(&bmain, node_group);
+ return false;
+ }
+
+ ED_preview_kill_jobs(CTX_wm_manager(&C), CTX_data_main(&C));
+
+ bNode *group_node = add_node(
+ C, ntreeTypeFind(node_group->idname)->group_idname, snode.runtime->cursor);
+ if (!group_node) {
+ BKE_report(&reports, RPT_WARNING, "Could not add node group");
+ return false;
+ }
+ /* By default, don't show the data-block selector since it's not usually necessary for assets. */
+ group_node->flag &= ~NODE_OPTIONS;
+
+ group_node->id = &node_group->id;
+ id_us_plus(group_node->id);
+ BKE_ntree_update_tag_node_property(&edit_tree, group_node);
+
+ nodeSetActive(&edit_tree, group_node);
+ ED_node_tree_propagate_change(&C, &bmain, nullptr);
+ DEG_relations_tag_update(&bmain);
+
+ return true;
+}
+
+static int node_add_group_asset_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ ARegion &region = *CTX_wm_region(C);
+ SpaceNode &snode = *CTX_wm_space_node(C);
+
+ const AssetLibraryReference *library_ref = CTX_wm_asset_library_ref(C);
+ if (!library_ref) {
+ return OPERATOR_CANCELLED;
+ }
+ bool is_valid;
+ const AssetHandle handle = CTX_wm_asset_handle(C, &is_valid);
+ if (!is_valid) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Convert mouse coordinates to v2d space. */
+ UI_view2d_region_to_view(&region.v2d,
+ event->mval[0],
+ event->mval[1],
+ &snode.runtime->cursor[0],
+ &snode.runtime->cursor[1]);
+
+ snode.runtime->cursor /= UI_DPI_FAC;
+
+ if (!add_node_group_asset(*C, *library_ref, handle, *op->reports)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ wmOperatorType *ot = WM_operatortype_find("NODE_OT_translate_attach_remove_on_cancel", true);
+ BLI_assert(ot);
+ PointerRNA ptr;
+ WM_operator_properties_create_ptr(&ptr, ot);
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, nullptr);
+ WM_operator_properties_free(&ptr);
+
+ return OPERATOR_FINISHED;
+}
+
+void NODE_OT_add_group_asset(wmOperatorType *ot)
+{
+ ot->name = "Add Node Group Asset";
+ ot->description = "Add a node group asset to the active node tree";
+ ot->idname = "NODE_OT_add_group_asset";
+
+ ot->invoke = node_add_group_asset_invoke;
+ ot->poll = node_add_group_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Add Node Object Operator
* \{ */
@@ -392,7 +494,7 @@ static int node_add_object_exec(bContext *C, wmOperator *op)
bNodeSocket *sock = nodeFindSocket(object_node, SOCK_IN, "Object");
if (!sock) {
- BKE_report(op->reports, RPT_WARNING, "Could not find node object socket");
+ BLI_assert_unreachable();
return OPERATOR_CANCELLED;
}
@@ -777,12 +879,14 @@ static int new_node_tree_exec(bContext *C, wmOperator *op)
ED_node_tree_update(C);
}
+ WM_event_add_notifier(C, NC_NODE | NA_ADDED, nullptr);
+
return OPERATOR_FINISHED;
}
-static const EnumPropertyItem *new_node_tree_type_itemf(bContext *UNUSED(C),
- PointerRNA *UNUSED(ptr),
- PropertyRNA *UNUSED(prop),
+static const EnumPropertyItem *new_node_tree_type_itemf(bContext * /*C*/,
+ PointerRNA * /*ptr*/,
+ PropertyRNA * /*prop*/,
bool *r_free)
{
return rna_node_tree_type_itemf(nullptr, nullptr, r_free);
@@ -810,4 +914,37 @@ void NODE_OT_new_node_tree(wmOperatorType *ot)
/** \} */
+/* -------------------------------------------------------------------- */
+/** \name Add Node Search
+ * \{ */
+
+static int node_add_search_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ const ARegion &region = *CTX_wm_region(C);
+
+ float2 cursor;
+ UI_view2d_region_to_view(&region.v2d, event->mval[0], event->mval[1], &cursor.x, &cursor.y);
+
+ invoke_add_node_search_menu(*C, cursor, RNA_boolean_get(op->ptr, "use_transform"));
+
+ return OPERATOR_FINISHED;
+}
+
+void NODE_OT_add_search(wmOperatorType *ot)
+{
+ ot->name = "Search and Add Node";
+ ot->idname = "NODE_OT_add_search";
+ ot->description = "Search for nodes and add one to the active tree";
+
+ ot->invoke = node_add_search_invoke;
+ ot->poll = ED_operator_node_editable;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_boolean(
+ ot->srna, "use_transform", true, "Use Transform", "Start moving the node after adding it");
+}
+
+/** \} */
+
} // namespace blender::ed::space_node
diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc
index 3a8e5d0aed6..5ae6573df7c 100644
--- a/source/blender/editors/space_node/node_draw.cc
+++ b/source/blender/editors/space_node/node_draw.cc
@@ -60,6 +60,7 @@
#include "ED_node.h"
#include "ED_screen.h"
#include "ED_space_api.h"
+#include "ED_viewer_path.hh"
#include "UI_interface.hh"
#include "UI_resources.h"
@@ -95,6 +96,14 @@ extern void ui_draw_dropshadow(
*/
struct TreeDrawContext {
/**
+ * Whether a viewer node is active in geometry nodes can not be determined by a flag on the node
+ * alone. That's because if the node group with the viewer is used multiple times, it's only
+ * active in one of these cases.
+ * The active node is cached here to avoid doing the more expensive check for every viewer node
+ * in the tree.
+ */
+ const bNode *active_geometry_nodes_viewer = nullptr;
+ /**
* Geometry nodes logs various data during execution. The logged data that corresponds to the
* currently drawn node tree can be retrieved from the log below.
*/
@@ -432,7 +441,7 @@ static void node_update_basis(const bContext &C,
float aspect = 1.0f;
if (node.preview_xsize && node.preview_ysize) {
- aspect = (float)node.preview_ysize / (float)node.preview_xsize;
+ aspect = float(node.preview_ysize) / float(node.preview_xsize);
}
dy -= NODE_DYS / 2;
@@ -597,7 +606,7 @@ static void node_update_hidden(bNode &node, uiBlock &block)
float hiddenrad = HIDDEN_RAD;
float tot = MAX2(totin, totout);
if (tot > 4) {
- hiddenrad += 5.0f * (float)(tot - 4);
+ hiddenrad += 5.0f * float(tot - 4);
}
node.totr.xmin = loc.x;
@@ -606,7 +615,7 @@ static void node_update_hidden(bNode &node, uiBlock &block)
node.totr.ymin = node.totr.ymax - 2 * hiddenrad;
/* Output sockets. */
- float rad = (float)M_PI / (1.0f + (float)totout);
+ float rad = float(M_PI) / (1.0f + float(totout));
float drad = rad;
LISTBASE_FOREACH (bNodeSocket *, socket, &node.outputs) {
@@ -619,7 +628,7 @@ static void node_update_hidden(bNode &node, uiBlock &block)
}
/* Input sockets. */
- rad = drad = -(float)M_PI / (1.0f + (float)totin);
+ rad = drad = -float(M_PI) / (1.0f + float(totin));
LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) {
if (!nodeSocketIsHidden(socket)) {
@@ -639,15 +648,19 @@ static void node_update_hidden(bNode &node, uiBlock &block)
node.totr.ymax);
}
-static int node_get_colorid(const bNode &node)
+static int node_get_colorid(TreeDrawContext &tree_draw_ctx, const bNode &node)
{
const int nclass = (node.typeinfo->ui_class == nullptr) ? node.typeinfo->nclass :
node.typeinfo->ui_class(&node);
switch (nclass) {
case NODE_CLASS_INPUT:
return TH_NODE_INPUT;
- case NODE_CLASS_OUTPUT:
+ case NODE_CLASS_OUTPUT: {
+ if (node.type == GEO_NODE_VIEWER) {
+ return &node == tree_draw_ctx.active_geometry_nodes_viewer ? TH_NODE_OUTPUT : TH_NODE;
+ }
return (node.flag & NODE_DO_OUTPUT) ? TH_NODE_OUTPUT : TH_NODE;
+ }
case NODE_CLASS_CONVERTER:
return TH_NODE_CONVERTER;
case NODE_CLASS_OP_COLOR:
@@ -1066,7 +1079,7 @@ static bool node_socket_has_tooltip(const bNodeTree &ntree, const bNodeSocket &s
static char *node_socket_get_tooltip(const bContext *C,
const bNodeTree *ntree,
- const bNode *UNUSED(node),
+ const bNode * /*node*/,
const bNodeSocket *socket)
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -1108,7 +1121,7 @@ static char *node_socket_get_tooltip(const bContext *C,
return BLI_strdup(output.str().c_str());
}
-static void node_socket_add_tooltip_in_node_editor(TreeDrawContext *UNUSED(tree_draw_ctx),
+static void node_socket_add_tooltip_in_node_editor(TreeDrawContext * /*tree_draw_ctx*/,
const bNodeTree *ntree,
const bNode *node,
const bNodeSocket *sock,
@@ -1125,7 +1138,7 @@ static void node_socket_add_tooltip_in_node_editor(TreeDrawContext *UNUSED(tree_
uiLayoutSetTooltipFunc(
layout,
- [](bContext *C, void *argN, const char *UNUSED(tip)) {
+ [](bContext *C, void *argN, const char * /*tip*/) {
SocketTooltipData *data = static_cast<SocketTooltipData *>(argN);
return node_socket_get_tooltip(C, data->ntree, data->node, data->socket);
},
@@ -1204,7 +1217,7 @@ static void node_socket_draw_nested(const bContext &C,
UI_but_func_tooltip_set(
but,
- [](bContext *C, void *argN, const char *UNUSED(tip)) {
+ [](bContext *C, void *argN, const char * /*tip*/) {
SocketTooltipData *data = (SocketTooltipData *)argN;
return node_socket_get_tooltip(C, data->ntree, data->node, data->socket);
},
@@ -1293,20 +1306,20 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
{
float xrect = BLI_rctf_size_x(prv);
float yrect = BLI_rctf_size_y(prv);
- float xscale = xrect / ((float)preview->xsize);
- float yscale = yrect / ((float)preview->ysize);
+ float xscale = xrect / float(preview->xsize);
+ float yscale = yrect / float(preview->ysize);
float scale;
/* Uniform scale and offset. */
rctf draw_rect = *prv;
if (xscale < yscale) {
- float offset = 0.5f * (yrect - ((float)preview->ysize) * xscale);
+ float offset = 0.5f * (yrect - float(preview->ysize) * xscale);
draw_rect.ymin += offset;
draw_rect.ymax -= offset;
scale = xscale;
}
else {
- float offset = 0.5f * (xrect - ((float)preview->xsize) * yscale);
+ float offset = 0.5f * (xrect - float(preview->xsize) * yscale);
draw_rect.xmin += offset;
draw_rect.xmax -= offset;
scale = yscale;
@@ -1613,7 +1626,7 @@ struct NodeErrorsTooltipData {
Span<geo_log::NodeWarning> warnings;
};
-static char *node_errors_tooltip_fn(bContext *UNUSED(C), void *argN, const char *UNUSED(tip))
+static char *node_errors_tooltip_fn(bContext * /*C*/, void *argN, const char * /*tip*/)
{
NodeErrorsTooltipData &data = *(NodeErrorsTooltipData *)argN;
@@ -1770,10 +1783,10 @@ struct NodeExtraInfoRow {
};
struct NamedAttributeTooltipArg {
- Map<std::string, geo_log::NamedAttributeUsage> usage_by_attribute;
+ Map<StringRefNull, geo_log::NamedAttributeUsage> usage_by_attribute;
};
-static char *named_attribute_tooltip(bContext *UNUSED(C), void *argN, const char *UNUSED(tip))
+static char *named_attribute_tooltip(bContext * /*C*/, void *argN, const char * /*tip*/)
{
NamedAttributeTooltipArg &arg = *static_cast<NamedAttributeTooltipArg *>(argN);
@@ -1824,7 +1837,7 @@ static char *named_attribute_tooltip(bContext *UNUSED(C), void *argN, const char
}
static NodeExtraInfoRow row_from_used_named_attribute(
- const Map<std::string, geo_log::NamedAttributeUsage> &usage_by_attribute_name)
+ const Map<StringRefNull, geo_log::NamedAttributeUsage> &usage_by_attribute_name)
{
const int attributes_num = usage_by_attribute_name.size();
@@ -1930,8 +1943,8 @@ static void node_draw_extra_info_row(const bNode &node,
UI_BTYPE_BUT,
0,
extra_info_row.icon,
- (int)but_icon_left,
- (int)(rect.ymin + row * (20.0f * U.dpi_fac)),
+ int(but_icon_left),
+ int(rect.ymin + row * (20.0f * U.dpi_fac)),
but_icon_width,
UI_UNIT_Y,
nullptr,
@@ -1956,10 +1969,10 @@ static void node_draw_extra_info_row(const bNode &node,
UI_BTYPE_LABEL,
0,
extra_info_row.text.c_str(),
- (int)but_text_left,
- (int)(rect.ymin + row * (20.0f * U.dpi_fac)),
- (short)but_text_width,
- (short)NODE_DY,
+ int(but_text_left),
+ int(rect.ymin + row * (20.0f * U.dpi_fac)),
+ short(but_text_width),
+ short(NODE_DY),
nullptr,
0,
0,
@@ -2055,7 +2068,7 @@ static void node_draw_basis(const bContext &C,
const rctf &rct = node.totr;
float color[4];
- int color_id = node_get_colorid(node);
+ int color_id = node_get_colorid(tree_draw_ctx, node);
GPU_line_width(1.0f);
@@ -2132,6 +2145,9 @@ static void node_draw_basis(const bContext &C,
0,
"");
UI_but_func_set(but, node_toggle_button_cb, &node, (void *)"NODE_OT_group_edit");
+ if (node.id) {
+ UI_but_icon_indicator_number_set(but, ID_REAL_USERS(node.id));
+ }
UI_block_emboss_set(&block, UI_EMBOSS);
}
if (node.type == NODE_CUSTOM && node.typeinfo->ui_icon != ICON_NONE) {
@@ -2153,6 +2169,29 @@ static void node_draw_basis(const bContext &C,
"");
UI_block_emboss_set(&block, UI_EMBOSS);
}
+ if (node.type == GEO_NODE_VIEWER) {
+ const bool is_active = &node == tree_draw_ctx.active_geometry_nodes_viewer;
+ iconofs -= iconbutw;
+ UI_block_emboss_set(&block, UI_EMBOSS_NONE);
+ uiBut *but = uiDefIconBut(&block,
+ UI_BTYPE_BUT,
+ 0,
+ is_active ? ICON_HIDE_OFF : ICON_HIDE_ON,
+ iconofs,
+ rct.ymax - NODE_DY,
+ iconbutw,
+ UI_UNIT_Y,
+ nullptr,
+ 0,
+ 0,
+ 0,
+ 0,
+ "");
+ /* Selection implicitly activates the node. */
+ const char *operator_idname = is_active ? "NODE_OT_deactivate_viewer" : "NODE_OT_select";
+ UI_but_func_set(but, node_toggle_button_cb, &node, (void *)operator_idname);
+ UI_block_emboss_set(&block, UI_EMBOSS);
+ }
node_add_error_message_button(tree_draw_ctx, node, block, rct, iconofs);
@@ -2195,10 +2234,10 @@ static void node_draw_basis(const bContext &C,
UI_BTYPE_LABEL,
0,
showname,
- (int)(rct.xmin + NODE_MARGIN_X + 0.4f),
- (int)(rct.ymax - NODE_DY),
- (short)(iconofs - rct.xmin - (18.0f * U.dpi_fac)),
- (short)NODE_DY,
+ int(rct.xmin + NODE_MARGIN_X + 0.4f),
+ int(rct.ymax - NODE_DY),
+ short(iconofs - rct.xmin - (18.0f * U.dpi_fac)),
+ short(NODE_DY),
nullptr,
0,
0,
@@ -2341,7 +2380,7 @@ static void node_draw_hidden(const bContext &C,
float scale;
UI_view2d_scale_get(&v2d, &scale, nullptr);
- const int color_id = node_get_colorid(node);
+ const int color_id = node_get_colorid(tree_draw_ctx, node);
node_draw_extra_info_panel(tree_draw_ctx, snode, node, block);
@@ -2425,8 +2464,8 @@ static void node_draw_hidden(const bContext &C,
showname,
round_fl_to_int(rct.xmin + NODE_MARGIN_X),
round_fl_to_int(centy - NODE_DY * 0.5f),
- (short)(BLI_rctf_size_x(&rct) - ((18.0f + 12.0f) * U.dpi_fac)),
- (short)NODE_DY,
+ short(BLI_rctf_size_x(&rct) - ((18.0f + 12.0f) * U.dpi_fac)),
+ short(NODE_DY),
nullptr,
0,
0,
@@ -2698,7 +2737,8 @@ static void node_update_nodetree(const bContext &C,
}
}
-static void frame_node_draw_label(const bNodeTree &ntree,
+static void frame_node_draw_label(TreeDrawContext &tree_draw_ctx,
+ const bNodeTree &ntree,
const bNode &node,
const SpaceNode &snode)
{
@@ -2714,15 +2754,15 @@ static void frame_node_draw_label(const bNodeTree &ntree,
BLF_enable(fontid, BLF_ASPECT);
BLF_aspect(fontid, aspect, aspect, 1.0f);
/* clamp otherwise it can suck up a LOT of memory */
- BLF_size(fontid, MIN2(24.0f, font_size) * U.pixelsize, U.dpi);
+ BLF_size(fontid, MIN2(24.0f, font_size) * U.dpi_fac);
/* title color */
- int color_id = node_get_colorid(node);
+ int color_id = node_get_colorid(tree_draw_ctx, node);
uchar color[3];
UI_GetThemeColorBlendShade3ubv(TH_TEXT, color_id, 0.4f, 10, color);
BLF_color3ubv(fontid, color);
- const float margin = (float)(NODE_DY / 4);
+ const float margin = float(NODE_DY / 4);
const float width = BLF_width(fontid, label, sizeof(label));
const float ascender = BLF_ascender(fontid);
const int label_height = ((margin / aspect) + (ascender * aspect));
@@ -2831,7 +2871,7 @@ static void frame_node_draw(const bContext &C,
}
/* label and text */
- frame_node_draw_label(ntree, node, snode);
+ frame_node_draw_label(tree_draw_ctx, ntree, node, snode);
node_draw_extra_info_panel(tree_draw_ctx, snode, node, block);
@@ -2866,7 +2906,7 @@ static void reroute_node_draw(
x,
y,
width,
- (short)NODE_DY,
+ short(NODE_DY),
nullptr,
0,
0,
@@ -2974,7 +3014,7 @@ static void node_draw_nodetree(const bContext &C,
}
}
-/* Draw the breadcrumb on the bottom of the editor. */
+/* Draw the breadcrumb on the top of the editor. */
static void draw_tree_path(const bContext &C, ARegion &region)
{
using namespace blender;
@@ -3013,7 +3053,7 @@ static void snode_setup_v2d(SpaceNode &snode, ARegion &region, const float2 &cen
UI_view2d_view_ortho(&v2d);
/* Aspect + font, set each time. */
- snode.runtime->aspect = BLI_rctf_size_x(&v2d.cur) / (float)region.winx;
+ snode.runtime->aspect = BLI_rctf_size_x(&v2d.cur) / float(region.winx);
// XXX snode->curfont = uiSetCurFont_ext(snode->aspect);
}
@@ -3036,6 +3076,9 @@ static void draw_nodetree(const bContext &C,
tree_draw_ctx.geo_tree_log->ensure_node_warnings();
tree_draw_ctx.geo_tree_log->ensure_node_run_time();
}
+ WorkSpace *workspace = CTX_wm_workspace(&C);
+ tree_draw_ctx.active_geometry_nodes_viewer = viewer_path::find_geometry_nodes_viewer(
+ workspace->viewer_path, *snode);
}
node_update_nodetree(C, tree_draw_ctx, ntree, nodes, blocks);
diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc
index f07a1205c6b..7982b47f363 100644
--- a/source/blender/editors/space_node/node_edit.cc
+++ b/source/blender/editors/space_node/node_edit.cc
@@ -43,7 +43,7 @@
#include "ED_render.h"
#include "ED_screen.h"
#include "ED_select_utils.h"
-#include "ED_spreadsheet.h"
+#include "ED_viewer_path.hh"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -89,8 +89,8 @@ struct CompoJob {
Depsgraph *compositor_depsgraph;
bNodeTree *localtree;
/* Jon system integration. */
- const short *stop;
- short *do_update;
+ const bool *stop;
+ bool *do_update;
float *progress;
};
@@ -166,7 +166,7 @@ static int compo_get_recalc_flags(const bContext *C)
}
/* called by compo, only to check job 'stop' value */
-static int compo_breakjob(void *cjv)
+static bool compo_breakjob(void *cjv)
{
CompoJob *cj = (CompoJob *)cjv;
@@ -179,7 +179,7 @@ static int compo_breakjob(void *cjv)
}
/* called by compo, wmJob sends notifier */
-static void compo_statsdrawjob(void *cjv, const char *UNUSED(str))
+static void compo_statsdrawjob(void *cjv, const char * /*str*/)
{
CompoJob *cj = (CompoJob *)cjv;
@@ -234,7 +234,7 @@ static void compo_initjob(void *cjv)
}
/* called before redraw notifiers, it moves finished previews over */
-static void compo_updatejob(void *UNUSED(cjv))
+static void compo_updatejob(void * /*cjv*/)
{
WM_main_add_notifier(NC_SCENE | ND_COMPO_RESULT, nullptr);
}
@@ -250,8 +250,8 @@ static void compo_progressjob(void *cjv, float progress)
static void compo_startjob(void *cjv,
/* Cannot be const, this function implements wm_jobs_start_callback.
* NOLINTNEXTLINE: readability-non-const-parameter. */
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress)
{
CompoJob *cj = (CompoJob *)cjv;
@@ -443,11 +443,11 @@ void ED_node_tree_propagate_change(const bContext *C, Main *bmain, bNodeTree *ro
}
NodeTreeUpdateExtraParams params = {nullptr};
- params.tree_changed_fn = [](ID *id, bNodeTree *ntree, void *UNUSED(user_data)) {
+ params.tree_changed_fn = [](ID *id, bNodeTree *ntree, void * /*user_data*/) {
blender::ed::space_node::send_notifiers_after_tree_change(id, ntree);
DEG_id_tag_update(&ntree->id, ID_RECALC_COPY_ON_WRITE);
};
- params.tree_output_changed_fn = [](ID *UNUSED(id), bNodeTree *ntree, void *UNUSED(user_data)) {
+ params.tree_output_changed_fn = [](ID * /*id*/, bNodeTree *ntree, void * /*user_data*/) {
DEG_id_tag_update(&ntree->id, ID_RECALC_NTREE_OUTPUT);
};
@@ -502,6 +502,7 @@ void ED_node_shader_default(const bContext *C, ID *id)
}
ma->nodetree = ntreeCopyTree(bmain, ma_default->nodetree);
+ ma->nodetree->owner_id = &ma->id;
BKE_ntree_update_main_tree(bmain, ma->nodetree, nullptr);
}
else if (ELEM(GS(id->name), ID_WO, ID_LA)) {
@@ -713,10 +714,12 @@ void ED_node_set_active(
/* Sync to active texpaint slot, otherwise we can end up painting on a different slot
* than we are looking at. */
if (ma->texpaintslot) {
- Image *image = (Image *)node->id;
- for (int i = 0; i < ma->tot_slots; i++) {
- if (ma->texpaintslot[i].ima == image) {
- ma->paint_active_slot = i;
+ if (node->id != nullptr && GS(node->id->name) == ID_IM) {
+ Image *image = (Image *)node->id;
+ for (int i = 0; i < ma->tot_slots; i++) {
+ if (ma->texpaintslot[i].ima == image) {
+ ma->paint_active_slot = i;
+ }
}
}
}
@@ -732,25 +735,9 @@ void ED_node_set_active(
/* Sync to Image Editor under the following conditions:
* - current image is not pinned
* - current image is not a Render Result or ViewerNode (want to keep looking at these) */
- Image *image = (Image *)node->id;
- wmWindowManager *wm = (wmWindowManager *)bmain->wm.first;
- LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
- const bScreen *screen = WM_window_get_active_screen(win);
- LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
- LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
- if (sl->spacetype != SPACE_IMAGE) {
- continue;
- }
- SpaceImage *sima = (SpaceImage *)sl;
- if (sima->pin) {
- continue;
- }
- if (sima->image && ELEM(sima->image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)) {
- continue;
- }
- ED_space_image_set(bmain, sima, image, true);
- }
- }
+ if (node->id != nullptr && GS(node->id->name) == ID_IM) {
+ Image *image = (Image *)node->id;
+ ED_space_image_sync(bmain, image, true);
}
if (r_active_texture_changed) {
@@ -816,14 +803,14 @@ void ED_node_set_active(
}
}
node->flag |= NODE_DO_OUTPUT;
- ED_spreadsheet_context_paths_set_geometry_node(bmain, snode, node);
}
+ blender::ed::viewer_path::activate_geometry_node(*bmain, *snode, *node);
}
}
}
}
-void ED_node_post_apply_transform(bContext *UNUSED(C), bNodeTree *UNUSED(ntree))
+void ED_node_post_apply_transform(bContext * /*C*/, bNodeTree * /*ntree*/)
{
/* XXX This does not work due to layout functions relying on node->block,
* which only exists during actual drawing. Can we rely on valid totr rects?
@@ -1356,12 +1343,15 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *ntree = snode->edittree;
const bool keep_inputs = RNA_boolean_get(op->ptr, "keep_inputs");
+ bool linked = RNA_boolean_get(op->ptr, "linked") || ((U.dupflag & USER_DUP_NTREE) == 0);
+ const bool dupli_node_tree = !linked;
bool changed = false;
ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
Map<const bNode *, bNode *> node_map;
Map<const bNodeSocket *, bNodeSocket *> socket_map;
+ Map<const ID *, ID *> duplicated_node_groups;
bNode *lastnode = (bNode *)ntree->nodes.last;
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
@@ -1369,6 +1359,18 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
bNode *new_node = bke::node_copy_with_mapping(
ntree, *node, LIB_ID_COPY_DEFAULT, true, socket_map);
node_map.add_new(node, new_node);
+
+ if (node->id && dupli_node_tree) {
+ ID *new_group = duplicated_node_groups.lookup_or_add_cb(node->id, [&]() {
+ ID *new_group = BKE_id_copy(bmain, node->id);
+ /* Remove user added by copying. */
+ id_us_min(new_group);
+ return new_group;
+ });
+ id_us_plus(new_group);
+ id_us_min(new_node->id);
+ new_node->id = new_group;
+ }
changed = true;
}
@@ -1457,6 +1459,8 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
void NODE_OT_duplicate(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Duplicate Nodes";
ot->description = "Duplicate selected nodes";
@@ -1471,12 +1475,19 @@ void NODE_OT_duplicate(wmOperatorType *ot)
RNA_def_boolean(
ot->srna, "keep_inputs", false, "Keep Inputs", "Keep the input links to duplicated nodes");
+
+ prop = RNA_def_boolean(ot->srna,
+ "linked",
+ true,
+ "Linked",
+ "Duplicate node but not node trees, linking to the original data");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* XXX: some code needing updating to operators. */
/* goes over all scenes, reads render layers */
-static int node_read_viewlayers_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_read_viewlayers_exec(bContext *C, wmOperator * /*op*/)
{
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
@@ -1524,7 +1535,7 @@ void NODE_OT_read_viewlayers(wmOperatorType *ot)
ot->flag = 0;
}
-int node_render_changed_exec(bContext *C, wmOperator *UNUSED(op))
+int node_render_changed_exec(bContext *C, wmOperator * /*op*/)
{
Scene *sce = CTX_data_scene(C);
@@ -1631,7 +1642,7 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag)
}
}
-static int node_hide_toggle_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_hide_toggle_exec(bContext *C, wmOperator * /*op*/)
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -1662,7 +1673,7 @@ void NODE_OT_hide_toggle(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int node_preview_toggle_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_preview_toggle_exec(bContext *C, wmOperator * /*op*/)
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -1695,7 +1706,47 @@ void NODE_OT_preview_toggle(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int node_options_toggle_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_deactivate_viewer_exec(bContext *C, wmOperator * /*op*/)
+{
+ SpaceNode &snode = *CTX_wm_space_node(C);
+ WorkSpace &workspace = *CTX_wm_workspace(C);
+
+ bNode *active_viewer = viewer_path::find_geometry_nodes_viewer(workspace.viewer_path, snode);
+
+ LISTBASE_FOREACH (bNode *, node, &snode.edittree->nodes) {
+ if (node->type != GEO_NODE_VIEWER) {
+ continue;
+ }
+ if (!(node->flag & SELECT)) {
+ continue;
+ }
+ if (node == active_viewer) {
+ node->flag &= ~NODE_DO_OUTPUT;
+ BKE_ntree_update_tag_node_property(snode.edittree, node);
+ }
+ }
+
+ ED_node_tree_propagate_change(C, CTX_data_main(C), snode.edittree);
+
+ return OPERATOR_FINISHED;
+}
+
+void NODE_OT_deactivate_viewer(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Deactivate Viewer Node";
+ ot->description = "Deactivate selected viewer node in geometry nodes";
+ ot->idname = __func__;
+
+ /* callbacks */
+ ot->exec = node_deactivate_viewer_exec;
+ ot->poll = ED_operator_node_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int node_options_toggle_exec(bContext *C, wmOperator * /*op*/)
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -1726,7 +1777,7 @@ void NODE_OT_options_toggle(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_socket_toggle_exec(bContext *C, wmOperator * /*op*/)
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -1782,7 +1833,7 @@ void NODE_OT_hide_socket_toggle(wmOperatorType *ot)
/** \name Node Mute Operator
* \{ */
-static int node_mute_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_mute_exec(bContext *C, wmOperator * /*op*/)
{
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
@@ -1822,7 +1873,7 @@ void NODE_OT_mute_toggle(wmOperatorType *ot)
/** \name Node Delete Operator
* \{ */
-static int node_delete_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_delete_exec(bContext *C, wmOperator * /*op*/)
{
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
@@ -1872,7 +1923,7 @@ static bool node_switch_view_poll(bContext *C)
return false;
}
-static int node_switch_view_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_switch_view_exec(bContext *C, wmOperator * /*op*/)
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -1909,7 +1960,7 @@ void NODE_OT_switch_view_update(wmOperatorType *ot)
/** \name Node Delete with Reconnect Operator
* \{ */
-static int node_delete_reconnect_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_delete_reconnect_exec(bContext *C, wmOperator * /*op*/)
{
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
@@ -2003,7 +2054,7 @@ void NODE_OT_output_file_add_socket(wmOperatorType *ot)
/** \name Node Multi File Output Remove Socket Operator
* \{ */
-static int node_output_file_remove_active_socket_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_output_file_remove_active_socket_exec(bContext *C, wmOperator * /*op*/)
{
SpaceNode *snode = CTX_wm_space_node(C);
PointerRNA ptr = CTX_data_pointer_get(C, "node");
@@ -2129,7 +2180,7 @@ void NODE_OT_output_file_move_active_socket(wmOperatorType *ot)
/** \name Node Copy Node Color Operator
* \{ */
-static int node_copy_color_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_copy_color_exec(bContext *C, wmOperator * /*op*/)
{
SpaceNode &snode = *CTX_wm_space_node(C);
bNodeTree &ntree = *snode.edittree;
@@ -2177,7 +2228,7 @@ void NODE_OT_node_copy_color(wmOperatorType *ot)
/** \name Node Copy to Clipboard Operator
* \{ */
-static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_clipboard_copy_exec(bContext *C, wmOperator * /*op*/)
{
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *ntree = snode->edittree;
@@ -2230,6 +2281,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op))
newlink->tosock = socket_map.lookup(link->tosock);
newlink->fromnode = node_map.lookup(link->fromnode);
newlink->fromsock = socket_map.lookup(link->fromsock);
+ newlink->multi_input_socket_index = link->multi_input_socket_index;
BKE_node_clipboard_add_link(newlink);
}
@@ -2351,11 +2403,19 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
}
LISTBASE_FOREACH (bNodeLink *, link, clipboard_links_lb) {
- nodeAddLink(ntree,
- node_map.lookup(link->fromnode),
- socket_map.lookup(link->fromsock),
- node_map.lookup(link->tonode),
- socket_map.lookup(link->tosock));
+ bNodeLink *new_link = nodeAddLink(ntree,
+ node_map.lookup(link->fromnode),
+ socket_map.lookup(link->fromsock),
+ node_map.lookup(link->tonode),
+ socket_map.lookup(link->tosock));
+ new_link->multi_input_socket_index = link->multi_input_socket_index;
+ }
+
+ ntree->ensure_topology_cache();
+
+ for (bNode *new_node : node_map.values()) {
+ /* Update multi input socket indices in case all connected nodes weren't copied. */
+ update_multi_input_indices_for_removed_links(*new_node);
}
Main *bmain = CTX_data_main(C);
@@ -2532,7 +2592,7 @@ static int ntree_socket_change_type_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- /* Don't handle subtypes for now. */
+ /* Don't handle sub-types for now. */
nodeModifySocketType(ntree, nullptr, iosock, socket_type->idname);
/* Need the extra update here because the loop above does not check for valid links in the node
@@ -2570,8 +2630,8 @@ static bool socket_change_poll_type(void *userdata, bNodeSocketType *socket_type
}
static const EnumPropertyItem *socket_change_type_itemf(bContext *C,
- PointerRNA *UNUSED(ptr),
- PropertyRNA *UNUSED(prop),
+ PointerRNA * /*ptr*/,
+ PropertyRNA * /*prop*/,
bool *r_free)
{
if (!C) {
@@ -2854,8 +2914,8 @@ static void viewer_border_corner_to_backdrop(SpaceNode *snode,
float bufx = backdrop_width * snode->zoom;
float bufy = backdrop_height * snode->zoom;
- *fx = (bufx > 0.0f ? ((float)x - 0.5f * region->winx - snode->xof) / bufx + 0.5f : 0.0f);
- *fy = (bufy > 0.0f ? ((float)y - 0.5f * region->winy - snode->yof) / bufy + 0.5f : 0.0f);
+ *fx = (bufx > 0.0f ? (float(x) - 0.5f * region->winx - snode->xof) / bufx + 0.5f : 0.0f);
+ *fy = (bufy > 0.0f ? (float(y) - 0.5f * region->winy - snode->yof) / bufy + 0.5f : 0.0f);
}
static int viewer_border_exec(bContext *C, wmOperator *op)
@@ -2935,7 +2995,7 @@ void NODE_OT_viewer_border(wmOperatorType *ot)
WM_operator_properties_gesture_box(ot);
}
-static int clear_viewer_border_exec(bContext *C, wmOperator *UNUSED(op))
+static int clear_viewer_border_exec(bContext *C, wmOperator * /*op*/)
{
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *btree = snode->nodetree;
@@ -2968,7 +3028,7 @@ void NODE_OT_clear_viewer_border(wmOperatorType *ot)
/** \name Cryptomatte Add Socket
* \{ */
-static int node_cryptomatte_add_socket_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_cryptomatte_add_socket_exec(bContext *C, wmOperator * /*op*/)
{
SpaceNode *snode = CTX_wm_space_node(C);
PointerRNA ptr = CTX_data_pointer_get(C, "node");
@@ -3016,7 +3076,7 @@ void NODE_OT_cryptomatte_layer_add(wmOperatorType *ot)
/** \name Cryptomatte Remove Socket
* \{ */
-static int node_cryptomatte_remove_socket_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_cryptomatte_remove_socket_exec(bContext *C, wmOperator * /*op*/)
{
SpaceNode *snode = CTX_wm_space_node(C);
PointerRNA ptr = CTX_data_pointer_get(C, "node");
diff --git a/source/blender/editors/space_node/node_geometry_attribute_search.cc b/source/blender/editors/space_node/node_geometry_attribute_search.cc
index 809c4b2fe59..a1a8fd0dfdc 100644
--- a/source/blender/editors/space_node/node_geometry_attribute_search.cc
+++ b/source/blender/editors/space_node/node_geometry_attribute_search.cc
@@ -213,7 +213,7 @@ static void attribute_search_exec_fn(bContext *C, void *data_v, void *item_v)
ED_undo_push(C, "Assign Attribute Name");
}
-void node_geometry_add_attribute_search_button(const bContext &UNUSED(C),
+void node_geometry_add_attribute_search_button(const bContext & /*C*/,
const bNode &node,
PointerRNA &socket_ptr,
uiLayout &layout)
diff --git a/source/blender/editors/space_node/node_gizmo.cc b/source/blender/editors/space_node/node_gizmo.cc
index f9126556b71..7a77d523f43 100644
--- a/source/blender/editors/space_node/node_gizmo.cc
+++ b/source/blender/editors/space_node/node_gizmo.cc
@@ -65,7 +65,7 @@ static void node_gizmo_calc_matrix_space_with_image_dims(const SpaceNode *snode,
/** \name Backdrop Gizmo
* \{ */
-static void gizmo_node_backdrop_prop_matrix_get(const wmGizmo *UNUSED(gz),
+static void gizmo_node_backdrop_prop_matrix_get(const wmGizmo * /*gz*/,
wmGizmoProperty *gz_prop,
void *value_p)
{
@@ -78,7 +78,7 @@ static void gizmo_node_backdrop_prop_matrix_get(const wmGizmo *UNUSED(gz),
matrix[3][1] = snode->yof;
}
-static void gizmo_node_backdrop_prop_matrix_set(const wmGizmo *UNUSED(gz),
+static void gizmo_node_backdrop_prop_matrix_set(const wmGizmo * /*gz*/,
wmGizmoProperty *gz_prop,
const void *value_p)
{
@@ -90,7 +90,7 @@ static void gizmo_node_backdrop_prop_matrix_set(const wmGizmo *UNUSED(gz),
snode->yof = matrix[3][1];
}
-static bool WIDGETGROUP_node_transform_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
+static bool WIDGETGROUP_node_transform_poll(const bContext *C, wmGizmoGroupType * /*gzgt*/)
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -109,7 +109,7 @@ static bool WIDGETGROUP_node_transform_poll(const bContext *C, wmGizmoGroupType
return false;
}
-static void WIDGETGROUP_node_transform_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
+static void WIDGETGROUP_node_transform_setup(const bContext * /*C*/, wmGizmoGroup *gzgroup)
{
wmGizmoWrapper *wwrapper = (wmGizmoWrapper *)MEM_mallocN(sizeof(wmGizmoWrapper), __func__);
@@ -252,7 +252,7 @@ static void gizmo_node_crop_prop_matrix_get(const wmGizmo *gz,
const float *dims = crop_group->state.dims;
const bNode *node = (const bNode *)gz_prop->custom_func.user_data;
const NodeTwoXYs *nxy = (const NodeTwoXYs *)node->storage;
- bool is_relative = (bool)node->custom2;
+ bool is_relative = bool(node->custom2);
rctf rct;
two_xy_to_rect(nxy, &rct, dims, is_relative);
matrix[0][0] = fabsf(BLI_rctf_size_x(&rct));
@@ -271,7 +271,7 @@ static void gizmo_node_crop_prop_matrix_set(const wmGizmo *gz,
const float *dims = crop_group->state.dims;
bNode *node = (bNode *)gz_prop->custom_func.user_data;
NodeTwoXYs *nxy = (NodeTwoXYs *)node->storage;
- bool is_relative = (bool)node->custom2;
+ bool is_relative = bool(node->custom2);
rctf rct;
two_xy_to_rect(nxy, &rct, dims, is_relative);
const bool nx = rct.xmin > rct.xmax;
@@ -294,7 +294,7 @@ static void gizmo_node_crop_prop_matrix_set(const wmGizmo *gz,
gizmo_node_crop_update(crop_group);
}
-static bool WIDGETGROUP_node_crop_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
+static bool WIDGETGROUP_node_crop_poll(const bContext *C, wmGizmoGroupType * /*gzgt*/)
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -316,7 +316,7 @@ static bool WIDGETGROUP_node_crop_poll(const bContext *C, wmGizmoGroupType *UNUS
return false;
}
-static void WIDGETGROUP_node_crop_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
+static void WIDGETGROUP_node_crop_setup(const bContext * /*C*/, wmGizmoGroup *gzgroup)
{
NodeCropWidgetGroup *crop_group = MEM_new<NodeCropWidgetGroup>(__func__);
crop_group->border = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, nullptr);
@@ -406,7 +406,7 @@ struct NodeSunBeamsWidgetGroup {
} state;
};
-static bool WIDGETGROUP_node_sbeam_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
+static bool WIDGETGROUP_node_sbeam_poll(const bContext *C, wmGizmoGroupType * /*gzgt*/)
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -425,7 +425,7 @@ static bool WIDGETGROUP_node_sbeam_poll(const bContext *C, wmGizmoGroupType *UNU
return false;
}
-static void WIDGETGROUP_node_sbeam_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
+static void WIDGETGROUP_node_sbeam_setup(const bContext * /*C*/, wmGizmoGroup *gzgroup)
{
NodeSunBeamsWidgetGroup *sbeam_group = (NodeSunBeamsWidgetGroup *)MEM_mallocN(
sizeof(NodeSunBeamsWidgetGroup), __func__);
@@ -511,7 +511,7 @@ struct NodeCornerPinWidgetGroup {
} state;
};
-static bool WIDGETGROUP_node_corner_pin_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
+static bool WIDGETGROUP_node_corner_pin_poll(const bContext *C, wmGizmoGroupType * /*gzgt*/)
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -530,7 +530,7 @@ static bool WIDGETGROUP_node_corner_pin_poll(const bContext *C, wmGizmoGroupType
return false;
}
-static void WIDGETGROUP_node_corner_pin_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
+static void WIDGETGROUP_node_corner_pin_setup(const bContext * /*C*/, wmGizmoGroup *gzgroup)
{
NodeCornerPinWidgetGroup *cpin_group = (NodeCornerPinWidgetGroup *)MEM_mallocN(
sizeof(NodeCornerPinWidgetGroup), __func__);
diff --git a/source/blender/editors/space_node/node_group.cc b/source/blender/editors/space_node/node_group.cc
index 21def1bd9d7..329f78860a4 100644
--- a/source/blender/editors/space_node/node_group.cc
+++ b/source/blender/editors/space_node/node_group.cc
@@ -14,6 +14,7 @@
#include "BLI_linklist.h"
#include "BLI_listbase.h"
+#include "BLI_map.hh"
#include "BLI_math_vec_types.hh"
#include "BLI_string.h"
#include "BLI_vector.hh"
@@ -603,9 +604,7 @@ static int node_group_separate_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int node_group_separate_invoke(bContext *C,
- wmOperator *UNUSED(op),
- const wmEvent *UNUSED(event))
+static int node_group_separate_invoke(bContext *C, wmOperator * /*op*/, const wmEvent * /*event*/)
{
uiPopupMenu *pup = UI_popup_menu_begin(
C, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Separate"), ICON_NONE);
@@ -737,6 +736,74 @@ static int node_get_selected_minmax(
return totselect;
}
+/**
+ * Redirect a link that are connecting a non-selected node to selected one.
+ * Create new socket or reuse an existing one that was connected from the same input.
+ * The output sockets of group nodes usually have consciously given names so they have
+ * precedence over socket names the link points to.
+ *
+ * \param ntree: The node tree that the node group is being created from.
+ * \param ngroup: The node tree of the new node group.
+ * \param gnode: The new group node in the original tree.
+ * \param input_node: The input node of the new node group.
+ * \param link: The incoming link that needs to be altered.
+ * \param reusable_sockets: Map for input socket interface lookup.
+ */
+static void node_group_make_redirect_incoming_link(
+ bNodeTree &ntree,
+ bNodeTree *ngroup,
+ bNode *gnode,
+ bNode *input_node,
+ bNodeLink *link,
+ Map<bNodeSocket *, bNodeSocket *> &reusable_sockets)
+{
+ bNodeSocket *input_socket = reusable_sockets.lookup_default(link->fromsock, nullptr);
+ if (input_socket) {
+ /* The incoming link is from a socket that has already been linked to
+ * a socket interface of the input node.
+ * Change the source of the link to the previously created socket interface.
+ * Move the link into the node tree of the new group. */
+ link->fromnode = input_node;
+ link->fromsock = input_socket;
+ BLI_remlink(&ntree.links, link);
+ BLI_addtail(&ngroup->links, link);
+ }
+ else {
+ bNode *node_for_typeinfo = nullptr;
+ bNodeSocket *socket_for_typeinfo = nullptr;
+ /* Find a socket where typeinfo and name may come from. */
+ node_socket_skip_reroutes(
+ &ntree.links, link->tonode, link->tosock, &node_for_typeinfo, &socket_for_typeinfo);
+ bNodeSocket *socket_for_naming = socket_for_typeinfo;
+
+ /* Use the name of group node output sockets. */
+ if (ELEM(link->fromnode->type, NODE_GROUP_INPUT, NODE_GROUP, NODE_CUSTOM_GROUP)) {
+ socket_for_naming = link->fromsock;
+ }
+
+ bNodeSocket *iosock = ntreeAddSocketInterfaceFromSocketWithName(ngroup,
+ node_for_typeinfo,
+ socket_for_typeinfo,
+ socket_for_naming->idname,
+ socket_for_naming->name);
+
+ /* Update the group node and interface sockets so the new interface socket can be linked. */
+ node_group_update(&ntree, gnode);
+ node_group_input_update(ngroup, input_node);
+
+ /* Create new internal link. */
+ bNodeSocket *input_sock = node_group_input_find_socket(input_node, iosock->identifier);
+ nodeAddLink(ngroup, input_node, input_sock, link->tonode, link->tosock);
+
+ /* Redirect external link. */
+ link->tonode = gnode;
+ link->tosock = node_group_find_input_socket(gnode, iosock->identifier);
+
+ /* Remember which interface socket the link has been redirected to. */
+ reusable_sockets.add_new(link->fromsock, input_sock);
+ }
+}
+
static void node_group_make_insert_selected(const bContext &C, bNodeTree &ntree, bNode *gnode)
{
Main *bmain = CTX_data_main(&C);
@@ -836,6 +903,10 @@ static void node_group_make_insert_selected(const bContext &C, bNodeTree &ntree,
output_node->locy = -offsety;
/* relink external sockets */
+
+ /* A map from link sources to input sockets already connected. */
+ Map<bNodeSocket *, bNodeSocket *> reusable_sockets;
+
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree.links) {
const bool fromselect = node_group_make_use_node(*link->fromnode, gnode);
const bool toselect = node_group_make_use_node(*link->tonode, gnode);
@@ -853,24 +924,8 @@ static void node_group_make_insert_selected(const bContext &C, bNodeTree &ntree,
continue;
}
- bNodeSocket *link_sock;
- bNode *link_node;
- node_socket_skip_reroutes(&ntree.links, link->tonode, link->tosock, &link_node, &link_sock);
- bNodeSocket *iosock = ntreeAddSocketInterfaceFromSocket(ngroup, link_node, link_sock);
-
- /* update the group node and interface node sockets,
- * so the new interface socket can be linked.
- */
- node_group_update(&ntree, gnode);
- node_group_input_update(ngroup, input_node);
-
- /* create new internal link */
- bNodeSocket *input_sock = node_group_input_find_socket(input_node, iosock->identifier);
- nodeAddLink(ngroup, input_node, input_sock, link->tonode, link->tosock);
-
- /* redirect external link */
- link->tonode = gnode;
- link->tosock = node_group_find_input_socket(gnode, iosock->identifier);
+ node_group_make_redirect_incoming_link(
+ ntree, ngroup, gnode, input_node, link, reusable_sockets);
}
else if (fromselect && !toselect) {
/* Remove hidden links to not create unconnected sockets in the interface. */
@@ -1047,6 +1102,8 @@ static int node_group_make_exec(bContext *C, wmOperator *op)
ED_node_tree_propagate_change(C, bmain, nullptr);
+ WM_event_add_notifier(C, NC_NODE | NA_ADDED, nullptr);
+
/* We broke relations in node tree, need to rebuild them in the graphs. */
DEG_relations_tag_update(bmain);
diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh
index 456cbf5064d..88be9a52c61 100644
--- a/source/blender/editors/space_node/node_intern.hh
+++ b/source/blender/editors/space_node/node_intern.hh
@@ -38,6 +38,8 @@ extern const char *node_context_dir[];
namespace blender::ed::space_node {
+struct AssetItemTree;
+
/** Temporary data used in node link drag modal operator. */
struct bNodeLinkDrag {
/** Links dragged by the operator. */
@@ -96,6 +98,15 @@ struct SpaceNode_Runtime {
/* XXX hack for translate_attach op-macros to pass data from transform op to insert_offset op */
/** Temporary data for node insert offset (in UI called Auto-offset). */
struct NodeInsertOfsData *iofsd;
+
+ /**
+ * Temporary data for node add menu in order to provide longer-term storage for context pointers.
+ * Recreated every time the root menu is opened. In the future this will be replaced with an "all
+ * libraries" cache in the asset system itself.
+ *
+ * Stored with a shared pointer so that it can be forward declared.
+ */
+ std::shared_ptr<AssetItemTree> assets_for_menu;
};
enum NodeResizeDirection {
@@ -251,7 +262,9 @@ bNode *add_node(const bContext &C, StringRef idname, const float2 &location);
bNode *add_static_node(const bContext &C, int type, const float2 &location);
void NODE_OT_add_reroute(wmOperatorType *ot);
+void NODE_OT_add_search(wmOperatorType *ot);
void NODE_OT_add_group(wmOperatorType *ot);
+void NODE_OT_add_group_asset(wmOperatorType *ot);
void NODE_OT_add_object(wmOperatorType *ot);
void NODE_OT_add_collection(wmOperatorType *ot);
void NODE_OT_add_file(wmOperatorType *ot);
@@ -269,6 +282,8 @@ void NODE_OT_group_edit(wmOperatorType *ot);
/* node_relationships.cc */
+void update_multi_input_indices_for_removed_links(bNode &node);
+
void NODE_OT_link(wmOperatorType *ot);
void NODE_OT_link_make(wmOperatorType *ot);
void NODE_OT_links_cut(wmOperatorType *ot);
@@ -321,6 +336,7 @@ void NODE_OT_hide_socket_toggle(wmOperatorType *ot);
void NODE_OT_preview_toggle(wmOperatorType *ot);
void NODE_OT_options_toggle(wmOperatorType *ot);
void NODE_OT_node_copy_color(wmOperatorType *ot);
+void NODE_OT_deactivate_viewer(wmOperatorType *ot);
void NODE_OT_read_viewlayers(wmOperatorType *ot);
void NODE_OT_render_changed(wmOperatorType *ot);
@@ -375,4 +391,13 @@ void invoke_node_link_drag_add_menu(bContext &C,
bNodeSocket &socket,
const float2 &cursor);
+/* add_node_search.cc */
+
+void invoke_add_node_search_menu(bContext &C, const float2 &cursor, bool use_transform);
+
+/* add_menu_assets.cc */
+
+MenuType add_catalog_assets_menu_type();
+MenuType add_root_catalogs_menu_type();
+
} // namespace blender::ed::space_node
diff --git a/source/blender/editors/space_node/node_ops.cc b/source/blender/editors/space_node/node_ops.cc
index a208370a6f9..104d1acf3b4 100644
--- a/source/blender/editors/space_node/node_ops.cc
+++ b/source/blender/editors/space_node/node_ops.cc
@@ -44,6 +44,7 @@ void node_operatortypes()
WM_operatortype_append(NODE_OT_options_toggle);
WM_operatortype_append(NODE_OT_hide_socket_toggle);
WM_operatortype_append(NODE_OT_node_copy_color);
+ WM_operatortype_append(NODE_OT_deactivate_viewer);
WM_operatortype_append(NODE_OT_duplicate);
WM_operatortype_append(NODE_OT_delete);
@@ -75,7 +76,9 @@ void node_operatortypes()
WM_operatortype_append(NODE_OT_backimage_fit);
WM_operatortype_append(NODE_OT_backimage_sample);
+ WM_operatortype_append(NODE_OT_add_search);
WM_operatortype_append(NODE_OT_add_group);
+ WM_operatortype_append(NODE_OT_add_group_asset);
WM_operatortype_append(NODE_OT_add_object);
WM_operatortype_append(NODE_OT_add_collection);
WM_operatortype_append(NODE_OT_add_file);
@@ -134,6 +137,7 @@ void ED_operatormacros_node()
mot = WM_operatortype_macro_define(ot, "NODE_OT_select");
RNA_boolean_set(mot->ptr, "extend", false);
RNA_boolean_set(mot->ptr, "socket_select", true);
+ RNA_boolean_set(mot->ptr, "clear_viewer", true);
WM_operatortype_macro_define(ot, "NODE_OT_link_viewer");
ot = WM_operatortype_append_macro("NODE_OT_translate_attach",
@@ -171,7 +175,17 @@ void ED_operatormacros_node()
"Duplicate",
"Duplicate selected nodes and move them",
OPTYPE_UNDO | OPTYPE_REGISTER);
- WM_operatortype_macro_define(ot, "NODE_OT_duplicate");
+ mot = WM_operatortype_macro_define(ot, "NODE_OT_duplicate");
+ RNA_boolean_set(mot->ptr, "linked", false);
+ WM_operatortype_macro_define(ot, "NODE_OT_translate_attach");
+
+ ot = WM_operatortype_append_macro(
+ "NODE_OT_duplicate_move_linked",
+ "Duplicate Linked",
+ "Duplicate selected nodes, but not their node trees, and move them",
+ OPTYPE_UNDO | OPTYPE_REGISTER);
+ mot = WM_operatortype_macro_define(ot, "NODE_OT_duplicate");
+ RNA_boolean_set(mot->ptr, "linked", true);
WM_operatortype_macro_define(ot, "NODE_OT_translate_attach");
/* modified operator call for duplicating with input links */
diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc
index 929fb64bd70..8eeba8727dc 100644
--- a/source/blender/editors/space_node/node_relationships.cc
+++ b/source/blender/editors/space_node/node_relationships.cc
@@ -27,8 +27,8 @@
#include "ED_render.h"
#include "ED_screen.h"
#include "ED_space_api.h"
-#include "ED_spreadsheet.h"
#include "ED_util.h"
+#include "ED_viewer_path.hh"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -64,6 +64,10 @@ struct NodeInsertOfsData {
float offset_x; /* offset to apply to node chain */
};
+namespace blender::ed::space_node {
+
+bNodeSocket *get_main_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_out);
+
static void clear_picking_highlight(ListBase *links)
{
LISTBASE_FOREACH (bNodeLink *, link, links) {
@@ -71,10 +75,6 @@ static void clear_picking_highlight(ListBase *links)
}
}
-namespace blender::ed::space_node {
-
-void update_multi_input_indices_for_removed_links(bNode &node);
-
/* -------------------------------------------------------------------- */
/** \name Add Node
* \{ */
@@ -170,7 +170,7 @@ static void pick_input_link_by_link_intersect(const bContext &C,
}
}
-static bool socket_is_available(bNodeTree *UNUSED(ntree), bNodeSocket *sock, const bool allow_used)
+static bool socket_is_available(bNodeTree * /*ntree*/, bNodeSocket *sock, const bool allow_used)
{
if (nodeSocketIsHidden(sock)) {
return false;
@@ -495,17 +495,6 @@ static bool is_viewer_node(const bNode &node)
return ELEM(node.type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER);
}
-static Vector<const bNode *> find_viewer_nodes(const bNodeTree &tree)
-{
- Vector<const bNode *> viewer_nodes;
- for (const bNode *node : tree.all_nodes()) {
- if (is_viewer_node(*node)) {
- viewer_nodes.append(node);
- }
- }
- return viewer_nodes;
-}
-
static bool is_viewer_socket_in_viewer(const bNodeSocket &socket)
{
const bNode &node = socket.owner_node();
@@ -516,18 +505,10 @@ static bool is_viewer_socket_in_viewer(const bNodeSocket &socket)
return socket.index() == 0;
}
-static bool is_linked_to_viewer(const bNodeSocket &socket, const bNode &viewer_node)
+static bool is_viewer_socket(const bNodeSocket &socket)
{
- for (const bNodeSocket *target_socket : socket.directly_linked_sockets()) {
- if (&target_socket->owner_node() != &viewer_node) {
- continue;
- }
- if (!target_socket->is_available()) {
- continue;
- }
- if (is_viewer_socket_in_viewer(*target_socket)) {
- return true;
- }
+ if (is_viewer_node(socket.owner_node())) {
+ return is_viewer_socket_in_viewer(socket);
}
return false;
}
@@ -549,137 +530,165 @@ static void remove_links_to_unavailable_viewer_sockets(bNodeTree &btree, bNode &
}
}
-static const bNode *get_existing_viewer(const bNodeTree &tree)
+static bNodeSocket *determine_socket_to_view(bNode &node_to_view)
{
- Vector<const bNode *> viewer_nodes = find_viewer_nodes(tree);
-
- /* Check if there is already an active viewer node that should be used. */
- for (const bNode *viewer_node : viewer_nodes) {
- if (viewer_node->flag & NODE_DO_OUTPUT) {
- return viewer_node;
+ int last_linked_socket_index = -1;
+ for (bNodeSocket *socket : node_to_view.output_sockets()) {
+ if (!socket_can_be_viewed(*socket)) {
+ continue;
}
- }
-
- /* If no active but non-active viewers exist, make one active. */
- if (!viewer_nodes.is_empty()) {
- const_cast<bNode *>(viewer_nodes[0])->flag |= NODE_DO_OUTPUT;
- return viewer_nodes[0];
- }
- return nullptr;
-}
-
-static const bNodeSocket *find_output_socket_to_be_viewed(const bNode *active_viewer_node,
- const bNode &node_to_view)
-{
- /* Check if any of the output sockets is selected, which is the case when the user just clicked
- * on the socket. */
- for (const bNodeSocket *output_socket : node_to_view.output_sockets()) {
- if (output_socket->flag & SELECT) {
- return output_socket;
+ for (bNodeLink *link : socket->directly_linked_links()) {
+ bNodeSocket &target_socket = *link->tosock;
+ bNode &target_node = *link->tonode;
+ if (is_viewer_socket(target_socket)) {
+ if (link->is_muted() || !(target_node.flag & NODE_DO_OUTPUT)) {
+ /* This socket is linked to a deactivated viewer, the viewer should be activated. */
+ return socket;
+ }
+ last_linked_socket_index = socket->index();
+ }
}
}
- const bNodeSocket *last_socket_linked_to_viewer = nullptr;
- if (active_viewer_node != nullptr) {
- for (const bNodeSocket *output_socket : node_to_view.output_sockets()) {
- if (!socket_can_be_viewed(*output_socket)) {
- continue;
- }
- if (is_linked_to_viewer(*output_socket, *active_viewer_node)) {
- last_socket_linked_to_viewer = output_socket;
+ if (last_linked_socket_index == -1) {
+ /* Return the first socket that can be viewed. */
+ for (bNodeSocket *socket : node_to_view.output_sockets()) {
+ if (socket_can_be_viewed(*socket)) {
+ return socket;
}
}
+ return nullptr;
}
- if (last_socket_linked_to_viewer == nullptr) {
- /* If no output is connected to a viewer, use the first output that can be viewed. */
- for (const bNodeSocket *output_socket : node_to_view.output_sockets()) {
- if (socket_can_be_viewed(*output_socket)) {
- return output_socket;
- }
+
+ /* Pick the next socket to be linked to the viewer. */
+ const int tot_outputs = node_to_view.output_sockets().size();
+ for (const int offset : IndexRange(1, tot_outputs)) {
+ const int index = (last_linked_socket_index + offset) % tot_outputs;
+ bNodeSocket &output_socket = node_to_view.output_socket(index);
+ if (!socket_can_be_viewed(output_socket)) {
+ continue;
}
- }
- else {
- /* Pick the next socket to be linked to the viewer. */
- const int tot_outputs = node_to_view.output_sockets().size();
- for (const int offset : IndexRange(1, tot_outputs - 1)) {
- const int index = (last_socket_linked_to_viewer->index() + offset) % tot_outputs;
- const bNodeSocket &output_socket = node_to_view.output_socket(index);
- if (!socket_can_be_viewed(output_socket)) {
+ bool is_currently_viewed = false;
+ for (const bNodeLink *link : output_socket.directly_linked_links()) {
+ bNodeSocket &target_socket = *link->tosock;
+ bNode &target_node = *link->tonode;
+ if (!is_viewer_socket(target_socket)) {
continue;
}
- if (is_linked_to_viewer(output_socket, *active_viewer_node)) {
+ if (link->is_muted()) {
continue;
}
- return &output_socket;
+ if (!(target_node.flag & NODE_DO_OUTPUT)) {
+ continue;
+ }
+ is_currently_viewed = true;
+ break;
+ }
+ if (is_currently_viewed) {
+ continue;
}
+ return &output_socket;
}
return nullptr;
}
-static int link_socket_to_viewer(const bContext &C,
- bNode *viewer_bnode,
- bNode &bnode_to_view,
- bNodeSocket &bsocket_to_view)
+static void finalize_viewer_link(const bContext &C,
+ SpaceNode &snode,
+ bNode &viewer_node,
+ bNodeLink &viewer_link)
{
- SpaceNode &snode = *CTX_wm_space_node(&C);
- bNodeTree &btree = *snode.edittree;
+ Main *bmain = CTX_data_main(&C);
+ remove_links_to_unavailable_viewer_sockets(*snode.edittree, viewer_node);
+ viewer_link.flag &= ~NODE_LINK_MUTED;
+ viewer_node.flag &= ~NODE_MUTED;
+ viewer_node.flag |= NODE_DO_OUTPUT;
+ if (snode.edittree->type == NTREE_GEOMETRY) {
+ viewer_path::activate_geometry_node(*bmain, snode, viewer_node);
+ }
+ ED_node_tree_propagate_change(&C, bmain, snode.edittree);
+}
+
+static int view_socket(const bContext &C,
+ SpaceNode &snode,
+ bNodeTree &btree,
+ bNode &bnode_to_view,
+ bNodeSocket &bsocket_to_view)
+{
+ bNode *viewer_node = nullptr;
+ /* Try to find a viewer that is already active. */
+ LISTBASE_FOREACH (bNode *, node, &btree.nodes) {
+ if (is_viewer_node(*node)) {
+ if (node->flag & NODE_DO_OUTPUT) {
+ viewer_node = node;
+ break;
+ }
+ }
+ }
+
+ /* Try to reactivate existing viewer connection. */
+ for (bNodeLink *link : bsocket_to_view.directly_linked_links()) {
+ bNodeSocket &target_socket = *link->tosock;
+ bNode &target_node = *link->tonode;
+ if (is_viewer_socket(target_socket) && ELEM(viewer_node, nullptr, &target_node)) {
+ finalize_viewer_link(C, snode, target_node, *link);
+ return OPERATOR_FINISHED;
+ }
+ }
- if (viewer_bnode == nullptr) {
- /* Create a new viewer node if none exists. */
+ if (viewer_node == nullptr) {
+ LISTBASE_FOREACH (bNode *, node, &btree.nodes) {
+ if (is_viewer_node(*node)) {
+ viewer_node = node;
+ break;
+ }
+ }
+ }
+ if (viewer_node == nullptr) {
const int viewer_type = get_default_viewer_type(&C);
const float2 location{bsocket_to_view.locx / UI_DPI_FAC + 100,
bsocket_to_view.locy / UI_DPI_FAC};
- viewer_bnode = add_static_node(C, viewer_type, location);
- if (viewer_bnode == nullptr) {
- return OPERATOR_CANCELLED;
- }
+ viewer_node = add_static_node(C, viewer_type, location);
}
- bNodeSocket *viewer_bsocket = node_link_viewer_get_socket(btree, *viewer_bnode, bsocket_to_view);
+ bNodeSocket *viewer_bsocket = node_link_viewer_get_socket(btree, *viewer_node, bsocket_to_view);
if (viewer_bsocket == nullptr) {
return OPERATOR_CANCELLED;
}
-
- bNodeLink *link_to_change = nullptr;
- LISTBASE_FOREACH (bNodeLink *, link, &btree.links) {
+ bNodeLink *viewer_link = nullptr;
+ LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &btree.links) {
if (link->tosock == viewer_bsocket) {
- link_to_change = link;
+ viewer_link = link;
break;
}
}
-
- if (link_to_change == nullptr) {
- nodeAddLink(&btree, &bnode_to_view, &bsocket_to_view, viewer_bnode, viewer_bsocket);
+ if (viewer_link == nullptr) {
+ viewer_link = nodeAddLink(
+ &btree, &bnode_to_view, &bsocket_to_view, viewer_node, viewer_bsocket);
}
else {
- link_to_change->fromnode = &bnode_to_view;
- link_to_change->fromsock = &bsocket_to_view;
+ viewer_link->fromnode = &bnode_to_view;
+ viewer_link->fromsock = &bsocket_to_view;
BKE_ntree_update_tag_link_changed(&btree);
}
-
- remove_links_to_unavailable_viewer_sockets(btree, *viewer_bnode);
-
- if (btree.type == NTREE_GEOMETRY) {
- ED_spreadsheet_context_paths_set_geometry_node(CTX_data_main(&C), &snode, viewer_bnode);
- }
-
- ED_node_tree_propagate_change(&C, CTX_data_main(&C), &btree);
- return OPERATOR_FINISHED;
+ finalize_viewer_link(C, snode, *viewer_node, *viewer_link);
+ return OPERATOR_CANCELLED;
}
-static int node_link_viewer(const bContext &C, bNode &bnode_to_view)
+static int node_link_viewer(const bContext &C, bNode &bnode_to_view, bNodeSocket *bsocket_to_view)
{
SpaceNode &snode = *CTX_wm_space_node(&C);
bNodeTree *btree = snode.edittree;
btree->ensure_topology_cache();
- bNode *active_viewer_bnode = const_cast<bNode *>(get_existing_viewer(*btree));
- bNodeSocket *bsocket_to_view = const_cast<bNodeSocket *>(
- find_output_socket_to_be_viewed(active_viewer_bnode, bnode_to_view));
if (bsocket_to_view == nullptr) {
- return OPERATOR_FINISHED;
+ bsocket_to_view = determine_socket_to_view(bnode_to_view);
+ }
+
+ if (bsocket_to_view == nullptr) {
+ return OPERATOR_CANCELLED;
}
- return link_socket_to_viewer(C, active_viewer_bnode, bnode_to_view, *bsocket_to_view);
+
+ return view_socket(C, snode, *btree, bnode_to_view, *bsocket_to_view);
}
/** \} */
@@ -690,7 +699,7 @@ static int node_link_viewer(const bContext &C, bNode &bnode_to_view)
/** \name Link to Viewer Node Operator
* \{ */
-static int node_active_link_viewer_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_active_link_viewer_exec(bContext *C, wmOperator * /*op*/)
{
SpaceNode &snode = *CTX_wm_space_node(C);
bNode *node = nodeGetActive(snode.edittree);
@@ -701,7 +710,15 @@ static int node_active_link_viewer_exec(bContext *C, wmOperator *UNUSED(op))
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
- if (viewer_linking::node_link_viewer(*C, *node) == OPERATOR_CANCELLED) {
+ bNodeSocket *socket_to_view = nullptr;
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
+ if (socket->flag & SELECT) {
+ socket_to_view = socket;
+ break;
+ }
+ }
+
+ if (viewer_linking::node_link_viewer(*C, *node, socket_to_view) == OPERATOR_CANCELLED) {
return OPERATOR_CANCELLED;
}
@@ -788,7 +805,7 @@ static bool should_create_drag_link_search_menu(const bNodeTree &node_tree,
return true;
}
-static void draw_draglink_tooltip(const bContext *UNUSED(C), ARegion *UNUSED(region), void *arg)
+static void draw_draglink_tooltip(const bContext * /*C*/, ARegion * /*region*/, void *arg)
{
bNodeLinkDrag *nldrag = static_cast<bNodeLinkDrag *>(arg);
@@ -798,7 +815,8 @@ static void draw_draglink_tooltip(const bContext *UNUSED(C), ARegion *UNUSED(reg
nldrag->cursor[0];
const float y = nldrag->cursor[1] - 2.0f * UI_DPI_FAC;
- UI_icon_draw_ex(x, y, ICON_ADD, U.inv_dpi_fac, 1.0f, 0.0f, text_col, false);
+ UI_icon_draw_ex(
+ x, y, ICON_ADD, U.inv_dpi_fac, 1.0f, 0.0f, text_col, false, UI_NO_ICON_OVERLAY_TEXT);
}
static void draw_draglink_tooltip_activate(const ARegion &region, bNodeLinkDrag &nldrag)
@@ -817,7 +835,7 @@ static void draw_draglink_tooltip_deactivate(const ARegion &region, bNodeLinkDra
}
}
-static void node_link_update_header(bContext *C, bNodeLinkDrag *UNUSED(nldrag))
+static void node_link_update_header(bContext *C, bNodeLinkDrag * /*nldrag*/)
{
char header[UI_MAX_DRAW_STR];
@@ -915,7 +933,7 @@ static void node_link_exit(bContext &C, wmOperator &op, const bool apply_links)
ED_node_tree_propagate_change(&C, bmain, &ntree);
- /* Ensure draglink tooltip is disabled. */
+ /* Ensure drag-link tool-tip is disabled. */
draw_draglink_tooltip_deactivate(*CTX_wm_region(&C), *nldrag);
ED_workspace_status_text(&C, nullptr);
@@ -1532,7 +1550,7 @@ void NODE_OT_links_mute(wmOperatorType *ot)
/** \name Detach Links Operator
* \{ */
-static int detach_links_exec(bContext *C, wmOperator *UNUSED(op))
+static int detach_links_exec(bContext *C, wmOperator * /*op*/)
{
SpaceNode &snode = *CTX_wm_space_node(C);
bNodeTree &ntree = *snode.edittree;
@@ -1569,7 +1587,7 @@ void NODE_OT_links_detach(wmOperatorType *ot)
/** \name Set Parent Operator
* \{ */
-static int node_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_parent_set_exec(bContext *C, wmOperator * /*op*/)
{
SpaceNode &snode = *CTX_wm_space_node(C);
bNodeTree &ntree = *snode.edittree;
@@ -1651,7 +1669,7 @@ static void node_join_attach_recursive(bNode *node,
}
}
-static int node_join_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_join_exec(bContext *C, wmOperator * /*op*/)
{
Main &bmain = *CTX_data_main(C);
SpaceNode &snode = *CTX_wm_space_node(C);
@@ -1660,6 +1678,7 @@ static int node_join_exec(bContext *C, wmOperator *UNUSED(op))
const Set<bNode *> selected_nodes = get_selected_nodes(ntree);
bNode *frame_node = nodeAddStaticNode(C, &ntree, NODE_FRAME);
+ nodeSetActive(&ntree, frame_node);
/* reset tags */
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
@@ -1721,7 +1740,7 @@ static bNode *node_find_frame_to_attach(ARegion &region,
return nullptr;
}
-static int node_attach_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+static int node_attach_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *event)
{
ARegion &region = *CTX_wm_region(C);
SpaceNode &snode = *CTX_wm_space_node(C);
@@ -1733,29 +1752,31 @@ static int node_attach_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent
}
LISTBASE_FOREACH_BACKWARD (bNode *, node, &ntree.nodes) {
- if (node->flag & NODE_SELECT) {
- if (node->parent == nullptr) {
- /* disallow moving a parent into its child */
- if (nodeAttachNodeCheck(frame, node) == false) {
- /* attach all unparented nodes */
- nodeAttachNode(node, frame);
- }
+ if (!(node->flag & NODE_SELECT)) {
+ continue;
+ }
+
+ if (node->parent == nullptr) {
+ /* disallow moving a parent into its child */
+ if (nodeAttachNodeCheck(frame, node) == false) {
+ /* attach all unparented nodes */
+ nodeAttachNode(node, frame);
}
- else {
- /* attach nodes which share parent with the frame */
- bNode *parent;
- for (parent = frame->parent; parent; parent = parent->parent) {
- if (parent == node->parent) {
- break;
- }
+ }
+ else {
+ /* attach nodes which share parent with the frame */
+ bNode *parent;
+ for (parent = frame->parent; parent; parent = parent->parent) {
+ if (parent == node->parent) {
+ break;
}
+ }
- if (parent) {
- /* disallow moving a parent into its child */
- if (nodeAttachNodeCheck(frame, node) == false) {
- nodeDetachNode(node);
- nodeAttachNode(node, frame);
- }
+ if (parent) {
+ /* disallow moving a parent into its child */
+ if (nodeAttachNodeCheck(frame, node) == false) {
+ nodeDetachNode(node);
+ nodeAttachNode(node, frame);
}
}
}
@@ -1819,7 +1840,7 @@ static void node_detach_recursive(bNode *node)
}
/* detach the root nodes in the current selection */
-static int node_detach_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_detach_exec(bContext *C, wmOperator * /*op*/)
{
SpaceNode &snode = *CTX_wm_space_node(C);
bNodeTree &ntree = *snode.edittree;
@@ -1864,100 +1885,55 @@ void NODE_OT_detach(wmOperatorType *ot)
/** \name Automatic Node Insert on Dragging
* \{ */
-/* prevent duplicate testing code below */
-static bool ed_node_link_conditions(ScrArea *area,
- bool test,
- SpaceNode **r_snode,
- bNode **r_select)
+static bNode *get_selected_node_for_insertion(bNodeTree &node_tree)
{
- SpaceNode *snode = area ? (SpaceNode *)area->spacedata.first : nullptr;
-
- *r_snode = snode;
- *r_select = nullptr;
-
- /* no unlucky accidents */
- if (area == nullptr || area->spacetype != SPACE_NODE) {
- return false;
- }
-
- if (!test) {
- /* no need to look for a node */
- return true;
- }
-
- bNode *node;
- bNode *select = nullptr;
- for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) {
+ bNode *selected_node = nullptr;
+ int selected_node_count = 0;
+ for (bNode *node : node_tree.all_nodes()) {
if (node->flag & SELECT) {
- if (select) {
- break;
- }
- select = node;
+ selected_node = node;
+ selected_node_count++;
+ }
+ if (selected_node_count > 1) {
+ return nullptr;
}
}
- /* only one selected */
- if (node || select == nullptr) {
- return false;
+ if (!selected_node) {
+ return nullptr;
}
-
- /* correct node */
- if (BLI_listbase_is_empty(&select->inputs) || BLI_listbase_is_empty(&select->outputs)) {
- return false;
+ if (selected_node->input_sockets().is_empty() || selected_node->output_sockets().is_empty()) {
+ return nullptr;
}
-
- ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
-
- /* test node for links */
- LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
- if (node_link_is_hidden_or_dimmed(region->v2d, *link)) {
- continue;
- }
-
- if (link->tonode == select || link->fromnode == select) {
- return false;
- }
+ if (std::any_of(selected_node->input_sockets().begin(),
+ selected_node->input_sockets().end(),
+ [&](const bNodeSocket *socket) { return socket->is_directly_linked(); })) {
+ return nullptr;
}
-
- *r_select = select;
- return true;
+ if (std::any_of(selected_node->output_sockets().begin(),
+ selected_node->output_sockets().end(),
+ [&](const bNodeSocket *socket) { return socket->is_directly_linked(); })) {
+ return nullptr;
+ };
+ return selected_node;
}
-/** \} */
-
-} // namespace blender::ed::space_node
-
-/* -------------------------------------------------------------------- */
-/** \name Node Line Intersection Test
- * \{ */
-
-void ED_node_link_intersect_test(ScrArea *area, int test)
+void node_insert_on_link_flags_set(SpaceNode &snode, const ARegion &region)
{
- using namespace blender;
- using namespace blender::ed::space_node;
-
- bNode *select;
- SpaceNode *snode;
- if (!ed_node_link_conditions(area, test, &snode, &select)) {
- return;
- }
+ bNodeTree &node_tree = *snode.edittree;
+ node_tree.ensure_topology_cache();
- /* clear flags */
- LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
- link->flag &= ~NODE_LINKFLAG_HILITE;
- }
+ node_insert_on_link_flags_clear(node_tree);
- if (test == 0) {
+ bNode *node_to_insert = get_selected_node_for_insertion(node_tree);
+ if (!node_to_insert) {
return;
}
- ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
-
/* find link to select/highlight */
bNodeLink *selink = nullptr;
float dist_best = FLT_MAX;
- LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
-
- if (node_link_is_hidden_or_dimmed(region->v2d, *link)) {
+ LISTBASE_FOREACH (bNodeLink *, link, &node_tree.links) {
+ if (node_link_is_hidden_or_dimmed(region.v2d, *link)) {
continue;
}
@@ -1969,10 +1945,10 @@ void ED_node_link_intersect_test(ScrArea *area, int test)
* upper left node edge of a intersected line segment */
for (int i = 0; i < NODE_LINK_RESOL; i++) {
/* Check if the node rectangle intersects the line from this point to next one. */
- if (BLI_rctf_isect_segment(&select->totr, coords[i], coords[i + 1])) {
+ if (BLI_rctf_isect_segment(&node_to_insert->totr, coords[i], coords[i + 1])) {
/* store the shortest distance to the upper left edge
* of all intersections found so far */
- const float node_xy[] = {select->totr.xmin, select->totr.ymax};
+ const float node_xy[] = {node_to_insert->totr.xmin, node_to_insert->totr.ymax};
/* to be precise coords should be clipped by select->totr,
* but not done since there's no real noticeable difference */
@@ -1992,9 +1968,89 @@ void ED_node_link_intersect_test(ScrArea *area, int test)
}
}
-/** \} */
+void node_insert_on_link_flags_clear(bNodeTree &node_tree)
+{
+ LISTBASE_FOREACH (bNodeLink *, link, &node_tree.links) {
+ link->flag &= ~NODE_LINKFLAG_HILITE;
+ }
+}
-namespace blender::ed::space_node {
+void node_insert_on_link_flags(Main &bmain, SpaceNode &snode)
+{
+ bNodeTree &node_tree = *snode.edittree;
+ node_tree.ensure_topology_cache();
+ bNode *node_to_insert = get_selected_node_for_insertion(node_tree);
+ if (!node_to_insert) {
+ return;
+ }
+
+ /* Find link to insert on. */
+ bNodeTree &ntree = *snode.edittree;
+ bNodeLink *old_link = nullptr;
+ LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
+ if (link->flag & NODE_LINKFLAG_HILITE) {
+ old_link = link;
+ break;
+ }
+ }
+ if (old_link == nullptr) {
+ return;
+ }
+
+ old_link->flag &= ~NODE_LINKFLAG_HILITE;
+
+ bNodeSocket *best_input = get_main_socket(ntree, *node_to_insert, SOCK_IN);
+ bNodeSocket *best_output = get_main_socket(ntree, *node_to_insert, SOCK_OUT);
+
+ if (node_to_insert->type != NODE_REROUTE) {
+ /* Ignore main sockets when the types don't match. */
+ if (best_input != nullptr && ntree.typeinfo->validate_link != nullptr &&
+ !ntree.typeinfo->validate_link(static_cast<eNodeSocketDatatype>(old_link->fromsock->type),
+ static_cast<eNodeSocketDatatype>(best_input->type))) {
+ best_input = nullptr;
+ }
+ if (best_output != nullptr && ntree.typeinfo->validate_link != nullptr &&
+ !ntree.typeinfo->validate_link(static_cast<eNodeSocketDatatype>(best_output->type),
+ static_cast<eNodeSocketDatatype>(old_link->tosock->type))) {
+ best_output = nullptr;
+ }
+ }
+
+ bNode *from_node = old_link->fromnode;
+ bNodeSocket *from_socket = old_link->fromsock;
+ bNode *to_node = old_link->tonode;
+
+ if (best_output != nullptr) {
+ /* Relink the "start" of the existing link to the newly inserted node. */
+ old_link->fromnode = node_to_insert;
+ old_link->fromsock = best_output;
+ BKE_ntree_update_tag_link_changed(&ntree);
+ }
+ else {
+ nodeRemLink(&ntree, old_link);
+ }
+
+ if (best_input != nullptr) {
+ /* Add a new link that connects the node on the left to the newly inserted node. */
+ nodeAddLink(&ntree, from_node, from_socket, node_to_insert, best_input);
+ }
+
+ /* Set up insert offset data, it needs stuff from here. */
+ if ((snode.flag & SNODE_SKIP_INSOFFSET) == 0) {
+ BLI_assert(snode.runtime->iofsd == nullptr);
+ NodeInsertOfsData *iofsd = MEM_cnew<NodeInsertOfsData>(__func__);
+
+ iofsd->insert = node_to_insert;
+ iofsd->prev = from_node;
+ iofsd->next = to_node;
+
+ snode.runtime->iofsd = iofsd;
+ }
+
+ ED_node_tree_propagate_change(nullptr, &bmain, &ntree);
+}
+
+/** \} */
/* -------------------------------------------------------------------- */
/** \name Node Insert Offset Operator
@@ -2031,7 +2087,7 @@ static int get_main_socket_priority(const bNodeSocket *socket)
}
/** Get the "main" socket based on the node declaration or an heuristic. */
-static bNodeSocket *get_main_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_out)
+bNodeSocket *get_main_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_out)
{
ListBase *sockets = (in_out == SOCK_IN) ? &node.inputs : &node.outputs;
@@ -2087,7 +2143,7 @@ static bNodeSocket *get_main_socket(bNodeTree &ntree, bNode &node, eNodeSocketIn
return nullptr;
}
-static bool node_parents_offset_flag_enable_cb(bNode *parent, void *UNUSED(userdata))
+static bool node_parents_offset_flag_enable_cb(bNode *parent, void * /*userdata*/)
{
/* NODE_TEST is used to flag nodes that shouldn't be offset (again) */
parent->flag |= NODE_TEST;
@@ -2312,10 +2368,10 @@ static void node_link_insert_offset_ntree(NodeInsertOfsData *iofsd,
/**
* Modal handler for insert offset animation
*/
-static int node_insert_offset_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+static int node_insert_offset_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
- NodeInsertOfsData *iofsd = snode->runtime->iofsd;
+ NodeInsertOfsData *iofsd = static_cast<NodeInsertOfsData *>(op->customdata);
bool redraw = false;
if (!snode || event->type != TIMER || iofsd == nullptr ||
@@ -2323,7 +2379,7 @@ static int node_insert_offset_modal(bContext *C, wmOperator *UNUSED(op), const w
return OPERATOR_PASS_THROUGH;
}
- const float duration = (float)iofsd->anim_timer->duration;
+ const float duration = float(iofsd->anim_timer->duration);
/* handle animation - do this before possibly aborting due to duration, since
* main thread might be so busy that node hasn't reached final position yet */
@@ -2355,7 +2411,6 @@ static int node_insert_offset_modal(bContext *C, wmOperator *UNUSED(op), const w
node->anim_init_locx = node->anim_ofsx = 0.0f;
}
- snode->runtime->iofsd = nullptr;
MEM_freeN(iofsd);
return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
@@ -2370,6 +2425,8 @@ static int node_insert_offset_invoke(bContext *C, wmOperator *op, const wmEvent
{
const SpaceNode *snode = CTX_wm_space_node(C);
NodeInsertOfsData *iofsd = snode->runtime->iofsd;
+ snode->runtime->iofsd = nullptr;
+ op->customdata = iofsd;
if (!iofsd || !iofsd->insert) {
return OPERATOR_CANCELLED;
@@ -2408,84 +2465,3 @@ void NODE_OT_insert_offset(wmOperatorType *ot)
/** \} */
} // namespace blender::ed::space_node
-
-/* -------------------------------------------------------------------- */
-/** \name Note Link Insert
- * \{ */
-
-void ED_node_link_insert(Main *bmain, ScrArea *area)
-{
- using namespace blender::ed::space_node;
-
- bNode *node_to_insert;
- SpaceNode *snode;
- if (!ed_node_link_conditions(area, true, &snode, &node_to_insert)) {
- return;
- }
-
- /* Find link to insert on. */
- bNodeTree &ntree = *snode->edittree;
- bNodeLink *old_link = nullptr;
- LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
- if (link->flag & NODE_LINKFLAG_HILITE) {
- old_link = link;
- break;
- }
- }
- if (old_link == nullptr) {
- return;
- }
-
- old_link->flag &= ~NODE_LINKFLAG_HILITE;
-
- bNodeSocket *best_input = get_main_socket(ntree, *node_to_insert, SOCK_IN);
- bNodeSocket *best_output = get_main_socket(ntree, *node_to_insert, SOCK_OUT);
-
- if (node_to_insert->type != NODE_REROUTE) {
- /* Ignore main sockets when the types don't match. */
- if (best_input != nullptr && ntree.typeinfo->validate_link != nullptr &&
- !ntree.typeinfo->validate_link(static_cast<eNodeSocketDatatype>(old_link->fromsock->type),
- static_cast<eNodeSocketDatatype>(best_input->type))) {
- best_input = nullptr;
- }
- if (best_output != nullptr && ntree.typeinfo->validate_link != nullptr &&
- !ntree.typeinfo->validate_link(static_cast<eNodeSocketDatatype>(best_output->type),
- static_cast<eNodeSocketDatatype>(old_link->tosock->type))) {
- best_output = nullptr;
- }
- }
-
- bNode *from_node = old_link->fromnode;
- bNodeSocket *from_socket = old_link->fromsock;
- bNode *to_node = old_link->tonode;
-
- if (best_output != nullptr) {
- /* Relink the "start" of the existing link to the newly inserted node. */
- old_link->fromnode = node_to_insert;
- old_link->fromsock = best_output;
- BKE_ntree_update_tag_link_changed(&ntree);
- }
- else {
- nodeRemLink(&ntree, old_link);
- }
-
- if (best_input != nullptr) {
- /* Add a new link that connects the node on the left to the newly inserted node. */
- nodeAddLink(&ntree, from_node, from_socket, node_to_insert, best_input);
- }
-
- /* Set up insert offset data, it needs stuff from here. */
- if ((snode->flag & SNODE_SKIP_INSOFFSET) == 0) {
- NodeInsertOfsData *iofsd = MEM_cnew<NodeInsertOfsData>(__func__);
-
- iofsd->insert = node_to_insert;
- iofsd->prev = from_node;
- iofsd->next = to_node;
-
- snode->runtime->iofsd = iofsd;
- }
-
- ED_node_tree_propagate_change(nullptr, bmain, snode->edittree);
-}
-
-/** \} */
diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc
index d93b205b1b7..7c39169415b 100644
--- a/source/blender/editors/space_node/node_select.cc
+++ b/source/blender/editors/space_node/node_select.cc
@@ -23,13 +23,14 @@
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_node_runtime.hh"
+#include "BKE_node_tree_update.h"
#include "BKE_workspace.h"
#include "ED_node.h" /* own include */
#include "ED_screen.h"
#include "ED_select_utils.h"
-#include "ED_spreadsheet.h"
#include "ED_view3d.h"
+#include "ED_viewer_path.hh"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -644,6 +645,15 @@ static bool node_mouse_select(bContext *C,
}
}
+ if (RNA_boolean_get(op->ptr, "clear_viewer")) {
+ if (node == nullptr) {
+ /* Disable existing active viewer. */
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ BKE_viewer_path_clear(&workspace->viewer_path);
+ WM_event_add_notifier(C, NC_VIEWER_PATH, nullptr);
+ }
+ }
+
if (!(changed || found)) {
return false;
}
@@ -655,7 +665,7 @@ static bool node_mouse_select(bContext *C,
ED_node_set_active(&bmain, &snode, snode.edittree, node, &active_texture_changed);
}
else if (node != nullptr && node->type == GEO_NODE_VIEWER) {
- ED_spreadsheet_context_paths_set_geometry_node(&bmain, &snode, node);
+ viewer_path::activate_geometry_node(bmain, snode, *node);
}
ED_node_set_active_viewer_key(&snode);
node_sort(*snode.edittree);
@@ -731,6 +741,12 @@ void NODE_OT_select(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_HIDDEN);
RNA_def_boolean(ot->srna, "socket_select", false, "Socket Select", "");
+
+ RNA_def_boolean(ot->srna,
+ "clear_viewer",
+ false,
+ "Clear Viewer",
+ "Deactivate geometry nodes viewer when clicking in empty space");
}
/** \} */
@@ -843,8 +859,7 @@ static int node_circleselect_exec(bContext *C, wmOperator *op)
int x, y, radius;
float2 offset;
- float zoom = (float)(BLI_rcti_size_x(&region->winrct)) /
- (float)(BLI_rctf_size_x(&region->v2d.cur));
+ float zoom = float(BLI_rcti_size_x(&region->winrct)) / float(BLI_rctf_size_x(&region->v2d.cur));
const eSelectOp sel_op = ED_select_op_modal(
(eSelectOp)RNA_enum_get(op->ptr, "mode"),
@@ -867,7 +882,7 @@ static int node_circleselect_exec(bContext *C, wmOperator *op)
/* Frame nodes are selectable by their borders (including their whole rect - as for other
* nodes - would prevent selection of _only_ other nodes inside that frame. */
rctf frame_inside = node_frame_rect_inside(*node);
- const float radius_adjusted = (float)radius / zoom;
+ const float radius_adjusted = float(radius) / zoom;
BLI_rctf_pad(&frame_inside, -2.0f * radius_adjusted, -2.0f * radius_adjusted);
if (BLI_rctf_isect_circle(&node->totr, offset, radius_adjusted) &&
!BLI_rctf_isect_circle(&frame_inside, offset, radius_adjusted)) {
@@ -1119,7 +1134,7 @@ void NODE_OT_select_all(wmOperatorType *ot)
/** \name Select Linked To Operator
* \{ */
-static int node_select_linked_to_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_select_linked_to_exec(bContext *C, wmOperator * /*op*/)
{
SpaceNode &snode = *CTX_wm_space_node(C);
bNodeTree &node_tree = *snode.edittree;
@@ -1169,7 +1184,7 @@ void NODE_OT_select_linked_to(wmOperatorType *ot)
/** \name Select Linked From Operator
* \{ */
-static int node_select_linked_from_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_select_linked_from_exec(bContext *C, wmOperator * /*op*/)
{
SpaceNode &snode = *CTX_wm_space_node(C);
bNodeTree &node_tree = *snode.edittree;
@@ -1337,10 +1352,10 @@ static void node_find_create_label(const bNode *node, char *str, int maxlen)
/* Generic search invoke. */
static void node_find_update_fn(const bContext *C,
- void *UNUSED(arg),
+ void * /*arg*/,
const char *str,
uiSearchItems *items,
- const bool UNUSED(is_first))
+ const bool /*is_first*/)
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -1368,7 +1383,7 @@ static void node_find_update_fn(const bContext *C,
BLI_string_search_free(search);
}
-static void node_find_exec_fn(bContext *C, void *UNUSED(arg1), void *arg2)
+static void node_find_exec_fn(bContext *C, void * /*arg1*/, void *arg2)
{
SpaceNode *snode = CTX_wm_space_node(C);
bNode *active = (bNode *)arg2;
@@ -1435,7 +1450,7 @@ static uiBlock *node_find_menu(bContext *C, ARegion *region, void *arg_op)
return block;
}
-static int node_find_node_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int node_find_node_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
UI_popup_block_invoke(C, node_find_menu, op, nullptr);
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/space_node/node_templates.cc b/source/blender/editors/space_node/node_templates.cc
index 5fc194e02a4..1b7eadd336a 100644
--- a/source/blender/editors/space_node/node_templates.cc
+++ b/source/blender/editors/space_node/node_templates.cc
@@ -494,7 +494,7 @@ static int ui_node_item_name_compare(const void *a, const void *b)
return BLI_strcasecmp_natural(type_a->ui_name, type_b->ui_name);
}
-static bool ui_node_item_special_poll(const bNodeTree *UNUSED(ntree), const bNodeType *ntype)
+static bool ui_node_item_special_poll(const bNodeTree * /*ntree*/, const bNodeType *ntype)
{
if (STREQ(ntype->idname, "ShaderNodeUVAlongStroke")) {
/* TODO(sergey): Currently we don't have Freestyle nodes edited from
diff --git a/source/blender/editors/space_node/node_view.cc b/source/blender/editors/space_node/node_view.cc
index 00756083580..f9b019e12ea 100644
--- a/source/blender/editors/space_node/node_view.cc
+++ b/source/blender/editors/space_node/node_view.cc
@@ -240,7 +240,7 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *
NodeViewMove *nvm;
Image *ima;
ImBuf *ibuf;
- const float pad = 32.0f; /* better be bigger than scrollbars */
+ const float pad = 32.0f; /* Better be bigger than scroll-bars. */
void *lock;
@@ -273,7 +273,7 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *
return OPERATOR_RUNNING_MODAL;
}
-static void snode_bg_viewmove_cancel(bContext *UNUSED(C), wmOperator *op)
+static void snode_bg_viewmove_cancel(bContext * /*C*/, wmOperator *op)
{
MEM_freeN(op->customdata);
op->customdata = nullptr;
@@ -341,7 +341,7 @@ void NODE_OT_backimage_zoom(wmOperatorType *ot)
/** \name Background Image Fit
* \{ */
-static int backimage_fit_exec(bContext *C, wmOperator *UNUSED(op))
+static int backimage_fit_exec(bContext *C, wmOperator * /*op*/)
{
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
@@ -464,9 +464,9 @@ bool ED_space_node_get_position(
/* map the mouse coords to the backdrop image space */
float bufx = ibuf->x * snode->zoom;
float bufy = ibuf->y * snode->zoom;
- fpos[0] = (bufx > 0.0f ? ((float)mval[0] - 0.5f * region->winx - snode->xof) / bufx + 0.5f :
+ fpos[0] = (bufx > 0.0f ? (float(mval[0]) - 0.5f * region->winx - snode->xof) / bufx + 0.5f :
0.0f);
- fpos[1] = (bufy > 0.0f ? ((float)mval[1] - 0.5f * region->winy - snode->yof) / bufy + 0.5f :
+ fpos[1] = (bufy > 0.0f ? (float(mval[1]) - 0.5f * region->winy - snode->yof) / bufy + 0.5f :
0.0f);
BKE_image_release_ibuf(ima, ibuf, lock);
@@ -498,13 +498,13 @@ bool ED_space_node_color_sample(
/* map the mouse coords to the backdrop image space */
bufx = ibuf->x * snode->zoom;
bufy = ibuf->y * snode->zoom;
- fx = (bufx > 0.0f ? ((float)mval[0] - 0.5f * region->winx - snode->xof) / bufx + 0.5f : 0.0f);
- fy = (bufy > 0.0f ? ((float)mval[1] - 0.5f * region->winy - snode->yof) / bufy + 0.5f : 0.0f);
+ fx = (bufx > 0.0f ? (float(mval[0]) - 0.5f * region->winx - snode->xof) / bufx + 0.5f : 0.0f);
+ fy = (bufy > 0.0f ? (float(mval[1]) - 0.5f * region->winy - snode->yof) / bufy + 0.5f : 0.0f);
if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) {
const float *fp;
uchar *cp;
- int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y);
+ int x = int(fx * ibuf->x), y = int(fy * ibuf->y);
CLAMP(x, 0, ibuf->x - 1);
CLAMP(y, 0, ibuf->y - 1);
@@ -555,15 +555,15 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
/* map the mouse coords to the backdrop image space */
bufx = ibuf->x * snode->zoom;
bufy = ibuf->y * snode->zoom;
- fx = (bufx > 0.0f ? ((float)event->mval[0] - 0.5f * region->winx - snode->xof) / bufx + 0.5f :
+ fx = (bufx > 0.0f ? (float(event->mval[0]) - 0.5f * region->winx - snode->xof) / bufx + 0.5f :
0.0f);
- fy = (bufy > 0.0f ? ((float)event->mval[1] - 0.5f * region->winy - snode->yof) / bufy + 0.5f :
+ fy = (bufy > 0.0f ? (float(event->mval[1]) - 0.5f * region->winy - snode->yof) / bufy + 0.5f :
0.0f);
if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) {
const float *fp;
uchar *cp;
- int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y);
+ int x = int(fx * ibuf->x), y = int(fy * ibuf->y);
CLAMP(x, 0, ibuf->x - 1);
CLAMP(y, 0, ibuf->y - 1);
@@ -584,10 +584,10 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
info->col[2] = cp[2];
info->col[3] = cp[3];
- info->colf[0] = (float)cp[0] / 255.0f;
- info->colf[1] = (float)cp[1] / 255.0f;
- info->colf[2] = (float)cp[2] / 255.0f;
- info->colf[3] = (float)cp[3] / 255.0f;
+ info->colf[0] = float(cp[0]) / 255.0f;
+ info->colf[1] = float(cp[1]) / 255.0f;
+ info->colf[2] = float(cp[2]) / 255.0f;
+ info->colf[3] = float(cp[3]) / 255.0f;
copy_v4_v4(info->linearcol, info->colf);
IMB_colormanagement_colorspace_to_scene_linear_v4(
diff --git a/source/blender/editors/space_node/space_node.cc b/source/blender/editors/space_node/space_node.cc
index fae3eb1a143..c993fa57d76 100644
--- a/source/blender/editors/space_node/space_node.cc
+++ b/source/blender/editors/space_node/space_node.cc
@@ -5,6 +5,7 @@
* \ingroup spnode
*/
+#include "DNA_ID.h"
#include "DNA_gpencil_types.h"
#include "DNA_light_types.h"
#include "DNA_material_types.h"
@@ -14,6 +15,7 @@
#include "MEM_guardedalloc.h"
#include "BKE_context.h"
+#include "BKE_gpencil.h"
#include "BKE_lib_id.h"
#include "BKE_lib_remap.h"
#include "BKE_node.h"
@@ -27,6 +29,10 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "DEG_depsgraph.h"
+
+#include "BLO_read_write.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -178,7 +184,7 @@ void ED_node_tree_path_get(SpaceNode *snode, char *value)
value += strlen(path->display_name);
}
else {
- sprintf(value, "/%s", path->display_name);
+ BLI_sprintf(value, "/%s", path->display_name);
value += strlen(path->display_name) + 1;
}
}
@@ -188,6 +194,13 @@ void ED_node_set_active_viewer_key(SpaceNode *snode)
{
bNodeTreePath *path = (bNodeTreePath *)snode->treepath.last;
if (snode->nodetree && path) {
+ /* A change in active viewer may result in the change of the output node used by the
+ * compositor, so we need to get notified about such changes. */
+ if (snode->nodetree->active_viewer_key.value != path->parent_key.value) {
+ DEG_id_tag_update(&snode->nodetree->id, ID_RECALC_NTREE_OUTPUT);
+ WM_main_add_notifier(NC_NODE, nullptr);
+ }
+
snode->nodetree->active_viewer_key = path->parent_key;
}
}
@@ -216,7 +229,7 @@ float2 space_node_group_offset(const SpaceNode &snode)
/* ******************** default callbacks for node space ***************** */
-static SpaceLink *node_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *node_create(const ScrArea * /*area*/, const Scene * /*scene*/)
{
SpaceNode *snode = MEM_cnew<SpaceNode>("initnode");
snode->spacetype = SPACE_NODE;
@@ -297,12 +310,12 @@ static void node_free(SpaceLink *sl)
if (snode->runtime) {
snode->runtime->linkdrag.reset();
- MEM_freeN(snode->runtime);
+ MEM_delete(snode->runtime);
}
}
/* spacetype; init callback */
-static void node_init(wmWindowManager *UNUSED(wm), ScrArea *area)
+static void node_init(wmWindowManager * /*wm*/, ScrArea *area)
{
SpaceNode *snode = (SpaceNode *)area->spacedata.first;
@@ -637,57 +650,55 @@ static void node_main_region_draw(const bContext *C, ARegion *region)
/* ************* dropboxes ************* */
-static bool node_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static bool node_group_drop_poll(bContext * /*C*/, wmDrag *drag, const wmEvent * /*event*/)
{
return WM_drag_is_ID_type(drag, ID_NT);
}
-static bool node_object_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static bool node_object_drop_poll(bContext * /*C*/, wmDrag *drag, const wmEvent * /*event*/)
{
return WM_drag_is_ID_type(drag, ID_OB);
}
-static bool node_collection_drop_poll(bContext *UNUSED(C),
- wmDrag *drag,
- const wmEvent *UNUSED(event))
+static bool node_collection_drop_poll(bContext * /*C*/, wmDrag *drag, const wmEvent * /*event*/)
{
return WM_drag_is_ID_type(drag, ID_GR);
}
-static bool node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static bool node_ima_drop_poll(bContext * /*C*/, wmDrag *drag, const wmEvent * /*event*/)
{
if (drag->type == WM_DRAG_PATH) {
/* rule might not work? */
- return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE));
+ return ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE);
}
return WM_drag_is_ID_type(drag, ID_IM);
}
-static bool node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static bool node_mask_drop_poll(bContext * /*C*/, wmDrag *drag, const wmEvent * /*event*/)
{
return WM_drag_is_ID_type(drag, ID_MSK);
}
-static void node_group_drop_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
+static void node_group_drop_copy(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0);
- RNA_int_set(drop->ptr, "session_uuid", (int)id->session_uuid);
+ RNA_int_set(drop->ptr, "session_uuid", int(id->session_uuid));
}
-static void node_id_drop_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
+static void node_id_drop_copy(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0);
- RNA_int_set(drop->ptr, "session_uuid", (int)id->session_uuid);
+ RNA_int_set(drop->ptr, "session_uuid", int(id->session_uuid));
}
-static void node_id_path_drop_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
+static void node_id_path_drop_copy(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0);
if (id) {
- RNA_int_set(drop->ptr, "session_uuid", (int)id->session_uuid);
+ RNA_int_set(drop->ptr, "session_uuid", int(id->session_uuid));
RNA_struct_property_unset(drop->ptr, "filepath");
}
else if (drag->path[0]) {
@@ -736,7 +747,7 @@ static void node_dropboxes()
/* ************* end drop *********** */
/* add handlers, stuff you only do once or on area/region changes */
-static void node_header_region_init(wmWindowManager *UNUSED(wm), ARegion *region)
+static void node_header_region_init(wmWindowManager * /*wm*/, ARegion *region)
{
ED_region_header_init(region);
}
@@ -820,6 +831,9 @@ static void node_region_listener(const wmRegionListenerParams *params)
ED_region_tag_redraw(region);
}
break;
+ case NC_VIEWER_PATH:
+ ED_region_tag_redraw(region);
+ break;
}
}
@@ -973,7 +987,7 @@ static void node_id_remap_cb(ID *old_id, ID *new_id, void *user_data)
}
}
-static void node_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, const IDRemapper *mappings)
+static void node_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemapper *mappings)
{
/* Although we should be able to perform all the mappings in a single go this lead to issues when
* running the python test cases. Somehow the nodetree/edittree weren't updated to the new
@@ -1011,6 +1025,81 @@ static void node_space_subtype_item_extend(bContext *C, EnumPropertyItem **item,
}
}
+static void node_blend_read_data(BlendDataReader *reader, SpaceLink *sl)
+{
+ SpaceNode *snode = (SpaceNode *)sl;
+
+ if (snode->gpd) {
+ BLO_read_data_address(reader, &snode->gpd);
+ BKE_gpencil_blend_read_data(reader, snode->gpd);
+ }
+
+ BLO_read_list(reader, &snode->treepath);
+ snode->edittree = nullptr;
+ snode->runtime = nullptr;
+}
+
+static void node_blend_read_lib(BlendLibReader *reader, ID *parent_id, SpaceLink *sl)
+{
+ SpaceNode *snode = (SpaceNode *)sl;
+
+ /* node tree can be stored locally in id too, link this first */
+ BLO_read_id_address(reader, parent_id->lib, &snode->id);
+ BLO_read_id_address(reader, parent_id->lib, &snode->from);
+
+ bNodeTree *ntree = snode->id ? ntreeFromID(snode->id) : nullptr;
+ if (ntree) {
+ snode->nodetree = ntree;
+ }
+ else {
+ BLO_read_id_address(reader, parent_id->lib, &snode->nodetree);
+ }
+
+ bNodeTreePath *path;
+ for (path = static_cast<bNodeTreePath *>(snode->treepath.first); path; path = path->next) {
+ if (path == snode->treepath.first) {
+ /* first nodetree in path is same as snode->nodetree */
+ path->nodetree = snode->nodetree;
+ }
+ else {
+ BLO_read_id_address(reader, parent_id->lib, &path->nodetree);
+ }
+
+ if (!path->nodetree) {
+ break;
+ }
+ }
+
+ /* remaining path entries are invalid, remove */
+ bNodeTreePath *path_next;
+ for (; path; path = path_next) {
+ path_next = path->next;
+
+ BLI_remlink(&snode->treepath, path);
+ MEM_freeN(path);
+ }
+
+ /* edittree is just the last in the path,
+ * set this directly since the path may have been shortened above */
+ if (snode->treepath.last) {
+ path = static_cast<bNodeTreePath *>(snode->treepath.last);
+ snode->edittree = path->nodetree;
+ }
+ else {
+ snode->edittree = nullptr;
+ }
+}
+
+static void node_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ SpaceNode *snode = (SpaceNode *)sl;
+ BLO_write_struct(writer, SpaceNode, snode);
+
+ LISTBASE_FOREACH (bNodeTreePath *, path, &snode->treepath) {
+ BLO_write_struct(writer, bNodeTreePath, path);
+ }
+}
+
} // namespace blender::ed::space_node
void ED_spacetype_node()
@@ -1038,6 +1127,9 @@ void ED_spacetype_node()
st->space_subtype_item_extend = node_space_subtype_item_extend;
st->space_subtype_get = node_space_subtype_get;
st->space_subtype_set = node_space_subtype_set;
+ st->blend_read_data = node_blend_read_data;
+ st->blend_read_lib = node_blend_read_lib;
+ st->blend_write = node_blend_write;
/* regions: main window */
art = MEM_cnew<ARegionType>("spacetype node region");
@@ -1088,5 +1180,8 @@ void ED_spacetype_node()
art->draw = node_toolbar_region_draw;
BLI_addhead(&st->regiontypes, art);
+ WM_menutype_add(MEM_new<MenuType>(__func__, add_catalog_assets_menu_type()));
+ WM_menutype_add(MEM_new<MenuType>(__func__, add_root_catalogs_menu_type()));
+
BKE_spacetype_register(st);
}
diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt
index d29028dad63..d1998f15757 100644
--- a/source/blender/editors/space_outliner/CMakeLists.txt
+++ b/source/blender/editors/space_outliner/CMakeLists.txt
@@ -4,6 +4,7 @@ set(INC
../include
../../blenkernel
../../blenlib
+ ../../blenloader
../../blentranslation
../../depsgraph
../../gpu
@@ -14,6 +15,9 @@ set(INC
../../windowmanager
../../../../intern/clog
../../../../intern/guardedalloc
+
+ # dna_type_offsets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
# RNA_prototypes.h
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
@@ -90,5 +94,5 @@ set(LIB
blender_add_lib(bf_editor_space_outliner "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
-# RNA_prototypes.h
+# RNA_prototypes.h dna_type_offsets.h
add_dependencies(bf_editor_space_outliner bf_rna)
diff --git a/source/blender/editors/space_outliner/outliner_collections.cc b/source/blender/editors/space_outliner/outliner_collections.cc
index 6b1ca5a53f8..f76727bff7c 100644
--- a/source/blender/editors/space_outliner/outliner_collections.cc
+++ b/source/blender/editors/space_outliner/outliner_collections.cc
@@ -411,7 +411,8 @@ static int collection_hierarchy_delete_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
struct wmMsgBus *mbus = CTX_wm_message_bus(C);
- const Base *basact_prev = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ const Base *basact_prev = BKE_view_layer_active_base_get(view_layer);
outliner_collection_delete(C, bmain, scene, op->reports, true);
@@ -420,7 +421,8 @@ static int collection_hierarchy_delete_exec(bContext *C, wmOperator *op)
WM_main_add_notifier(NC_SCENE | ND_LAYER, nullptr);
- if (basact_prev != view_layer->basact) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ if (basact_prev != BKE_view_layer_active_base_get(view_layer)) {
WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, LayerObjects, active);
}
@@ -491,6 +493,7 @@ static LayerCollection *outliner_active_layer_collection(bContext *C)
static int collection_objects_select_exec(bContext *C, wmOperator *op)
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
LayerCollection *layer_collection = outliner_active_layer_collection(C);
bool deselect = STREQ(op->idname, "OUTLINER_OT_collection_objects_deselect");
@@ -499,9 +502,8 @@ static int collection_objects_select_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BKE_layer_collection_objects_select(view_layer, layer_collection, deselect);
+ BKE_layer_collection_objects_select(scene, view_layer, layer_collection, deselect);
- Scene *scene = CTX_data_scene(C);
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene);
ED_outliner_select_sync_from_object_tag(C);
@@ -753,7 +755,7 @@ void OUTLINER_OT_collection_link(wmOperatorType *ot)
/** \name Instance Collection
* \{ */
-static int collection_instance_exec(bContext *C, wmOperator *UNUSED(op))
+static int collection_instance_exec(bContext *C, wmOperator * /*op*/)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -960,7 +962,7 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op)
BLI_gset_free(data.collections_to_edit, nullptr);
- BKE_layer_collection_sync(scene, view_layer);
+ BKE_view_layer_need_resync_tag(view_layer);
DEG_relations_tag_update(bmain);
WM_main_add_notifier(NC_SCENE | ND_LAYER, nullptr);
@@ -1109,7 +1111,7 @@ static int collection_isolate_exec(bContext *C, wmOperator *op)
}
BLI_gset_free(data.collections_to_edit, nullptr);
- BKE_layer_collection_sync(scene, view_layer);
+ BKE_view_layer_need_resync_tag(view_layer);
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, nullptr);
@@ -1189,11 +1191,11 @@ static int collection_visibility_exec(bContext *C, wmOperator *op)
GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
LayerCollection *layer_collection = static_cast<LayerCollection *>(
BLI_gsetIterator_getKey(&collections_to_edit_iter));
- BKE_layer_collection_set_visible(view_layer, layer_collection, show, is_inside);
+ BKE_layer_collection_set_visible(scene, view_layer, layer_collection, show, is_inside);
}
BLI_gset_free(data.collections_to_edit, nullptr);
- BKE_layer_collection_sync(scene, view_layer);
+ BKE_view_layer_need_resync_tag(view_layer);
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, nullptr);
@@ -1383,7 +1385,7 @@ static int collection_flag_exec(bContext *C, wmOperator *op)
BLI_gset_free(data.collections_to_edit, nullptr);
}
- BKE_layer_collection_sync(scene, view_layer);
+ BKE_view_layer_need_resync_tag(view_layer);
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
if (!is_render) {
@@ -1492,6 +1494,7 @@ static TreeTraversalAction outliner_hide_collect_data_to_edit(TreeElement *te, v
}
else if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) {
Object *ob = (Object *)tselem->id;
+ BKE_view_layer_synced_ensure(data->scene, data->view_layer);
Base *base = BKE_view_layer_base_find(data->view_layer, ob);
BLI_gset_add(data->bases_to_edit, base);
}
@@ -1499,7 +1502,7 @@ static TreeTraversalAction outliner_hide_collect_data_to_edit(TreeElement *te, v
return TRAVERSE_CONTINUE;
}
-static int outliner_hide_exec(bContext *C, wmOperator *UNUSED(op))
+static int outliner_hide_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1522,7 +1525,7 @@ static int outliner_hide_exec(bContext *C, wmOperator *UNUSED(op))
GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
LayerCollection *layer_collection = static_cast<LayerCollection *>(
BLI_gsetIterator_getKey(&collections_to_edit_iter));
- BKE_layer_collection_set_visible(view_layer, layer_collection, false, false);
+ BKE_layer_collection_set_visible(scene, view_layer, layer_collection, false, false);
}
BLI_gset_free(data.collections_to_edit, nullptr);
@@ -1533,7 +1536,7 @@ static int outliner_hide_exec(bContext *C, wmOperator *UNUSED(op))
}
BLI_gset_free(data.bases_to_edit, nullptr);
- BKE_layer_collection_sync(scene, view_layer);
+ BKE_view_layer_need_resync_tag(view_layer);
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, nullptr);
@@ -1555,7 +1558,7 @@ void OUTLINER_OT_hide(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int outliner_unhide_all_exec(bContext *C, wmOperator *UNUSED(op))
+static int outliner_unhide_all_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1567,11 +1570,12 @@ static int outliner_unhide_all_exec(bContext *C, wmOperator *UNUSED(op))
}
/* Unhide all objects. */
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
base->flag &= ~BASE_HIDDEN;
}
- BKE_layer_collection_sync(scene, view_layer);
+ BKE_view_layer_need_resync_tag(view_layer);
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, nullptr);
diff --git a/source/blender/editors/space_outliner/outliner_context.cc b/source/blender/editors/space_outliner/outliner_context.cc
index 001bda57fa2..87eb2d3e73f 100644
--- a/source/blender/editors/space_outliner/outliner_context.cc
+++ b/source/blender/editors/space_outliner/outliner_context.cc
@@ -21,7 +21,7 @@ static void outliner_context_selected_ids_recursive(const SpaceOutliner &space_o
{
tree_iterator::all(space_outliner, [&](const TreeElement *te) {
const TreeStoreElem *tse = TREESTORE(te);
- if ((tse->flag & TSE_SELECTED) && (ELEM(tse->type, TSE_SOME_ID, TSE_LAYER_COLLECTION))) {
+ if ((tse->flag & TSE_SELECTED) && ELEM(tse->type, TSE_SOME_ID, TSE_LAYER_COLLECTION)) {
CTX_data_id_list_add(result, tse->id);
}
});
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.cc b/source/blender/editors/space_outliner/outliner_dragdrop.cc
index 4a0e00b8bf1..3b07c6da5fa 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.cc
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.cc
@@ -293,6 +293,7 @@ static bool parent_drop_allowed(TreeElement *te, Object *potential_child)
* active scene and parenting them is allowed (sergey) */
if (scene) {
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
if (BKE_view_layer_base_find(view_layer, potential_child)) {
return true;
}
@@ -499,7 +500,7 @@ static bool parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *event)
}
}
-static int parent_clear_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+static int parent_clear_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *event)
{
Main *bmain = CTX_data_main(C);
@@ -554,7 +555,7 @@ static bool scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
return (ob && (outliner_ID_drop_find(C, event, ID_SCE) != nullptr));
}
-static int scene_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+static int scene_drop_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *event)
{
Main *bmain = CTX_data_main(C);
Scene *scene = (Scene *)outliner_ID_drop_find(C, event, ID_SCE);
@@ -580,6 +581,7 @@ static int scene_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent
BKE_collection_object_add(bmain, collection, ob);
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob);
if (base) {
ED_object_base_select(base, BA_SELECT);
@@ -623,7 +625,7 @@ static bool material_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
return (ma && (outliner_ID_drop_find(C, event, ID_OB) != nullptr));
}
-static int material_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+static int material_drop_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *event)
{
Main *bmain = CTX_data_main(C);
Object *ob = (Object *)outliner_ID_drop_find(C, event, ID_OB);
@@ -884,10 +886,10 @@ static bool datastack_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
return true;
}
-static char *datastack_drop_tooltip(bContext *UNUSED(C),
+static char *datastack_drop_tooltip(bContext * /*C*/,
wmDrag *drag,
- const int UNUSED(xy[2]),
- struct wmDropBox *UNUSED(drop))
+ const int /*xy*/[2],
+ struct wmDropBox * /*drop*/)
{
StackDropData *drop_data = static_cast<StackDropData *>(drag->poin);
switch (drop_data->drop_action) {
@@ -1222,7 +1224,7 @@ static bool collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event
static char *collection_drop_tooltip(bContext *C,
wmDrag *drag,
const int xy[2],
- wmDropBox *UNUSED(drop))
+ wmDropBox * /*drop*/)
{
wmWindow *win = CTX_wm_window(C);
const wmEvent *event = win ? win->eventstate : nullptr;
@@ -1288,7 +1290,7 @@ static char *collection_drop_tooltip(bContext *C,
return nullptr;
}
-static int collection_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+static int collection_drop_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *event)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -1402,9 +1404,7 @@ static TreeElement *outliner_item_drag_element_find(SpaceOutliner *space_outline
return outliner_find_item_at_y(space_outliner, &space_outliner->tree, my);
}
-static int outliner_item_drag_drop_invoke(bContext *C,
- wmOperator *UNUSED(op),
- const wmEvent *event)
+static int outliner_item_drag_drop_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
@@ -1571,7 +1571,7 @@ void OUTLINER_OT_item_drag_drop(wmOperatorType *ot)
/** \name Drop Boxes
* \{ */
-void outliner_dropboxes(void)
+void outliner_dropboxes()
{
ListBase *lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW);
diff --git a/source/blender/editors/space_outliner/outliner_draw.cc b/source/blender/editors/space_outliner/outliner_draw.cc
index 4259d3572be..699dd6d4844 100644
--- a/source/blender/editors/space_outliner/outliner_draw.cc
+++ b/source/blender/editors/space_outliner/outliner_draw.cc
@@ -166,12 +166,12 @@ static void restrictbutton_recursive_bone(Bone *bone_parent, int flag, bool set_
}
}
-static void restrictbutton_r_lay_fn(bContext *C, void *poin, void *UNUSED(poin2))
+static void restrictbutton_r_lay_fn(bContext *C, void *poin, void * /*poin2*/)
{
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, poin);
}
-static void restrictbutton_bone_visibility_fn(bContext *C, void *poin, void *UNUSED(poin2))
+static void restrictbutton_bone_visibility_fn(bContext *C, void *poin, void * /*poin2*/)
{
Bone *bone = (Bone *)poin;
@@ -180,7 +180,7 @@ static void restrictbutton_bone_visibility_fn(bContext *C, void *poin, void *UNU
}
}
-static void restrictbutton_bone_select_fn(bContext *C, void *UNUSED(poin), void *poin2)
+static void restrictbutton_bone_select_fn(bContext *C, void * /*poin*/, void *poin2)
{
Bone *bone = (Bone *)poin2;
if (bone->flag & BONE_UNSELECTABLE) {
@@ -226,7 +226,7 @@ static void restrictbutton_ebone_visibility_fn(bContext *C, void *poin, void *po
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, nullptr);
}
-static void restrictbutton_gp_layer_flag_fn(bContext *C, void *poin, void *UNUSED(poin2))
+static void restrictbutton_gp_layer_flag_fn(bContext *C, void *poin, void * /*poin2*/)
{
ID *id = (ID *)poin;
@@ -234,7 +234,7 @@ static void restrictbutton_gp_layer_flag_fn(bContext *C, void *poin, void *UNUSE
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, nullptr);
}
-static void restrictbutton_id_user_toggle(bContext *UNUSED(C), void *poin, void *UNUSED(poin2))
+static void restrictbutton_id_user_toggle(bContext * /*C*/, void *poin, void * /*poin2*/)
{
ID *id = (ID *)poin;
@@ -284,6 +284,7 @@ static void outliner_object_set_flag_recursive_fn(bContext *C,
DEG_id_tag_update(&ob_iter->id, ID_RECALC_COPY_ON_WRITE);
}
else {
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base_iter = BKE_view_layer_base_find(view_layer, ob_iter);
/* Child can be in a collection excluded from view-layer. */
if (base_iter == nullptr) {
@@ -301,7 +302,7 @@ static void outliner_object_set_flag_recursive_fn(bContext *C,
DEG_relations_tag_update(bmain);
}
else {
- BKE_layer_collection_sync(scene, view_layer);
+ BKE_view_layer_need_resync_tag(view_layer);
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
}
}
@@ -348,6 +349,7 @@ static void outliner_base_or_object_pointer_create(
RNA_id_pointer_create(&ob->id, ptr);
}
else {
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob);
RNA_pointer_create(&scene->id, &RNA_ObjectBase, base, ptr);
}
@@ -1121,7 +1123,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
VIEW_LAYER_RENDER,
0,
ICON_RESTRICT_RENDER_OFF,
- (int)(region->v2d.cur.xmax - restrict_offsets.render),
+ int(region->v2d.cur.xmax - restrict_offsets.render),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1146,6 +1148,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
RNA_id_pointer_create(&ob->id, &ptr);
if (space_outliner->show_restrict_flags & SO_RESTRICT_HIDE) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = (te->directdata) ? (Base *)te->directdata :
BKE_view_layer_base_find(view_layer, ob);
if (base) {
@@ -1155,7 +1158,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(region->v2d.cur.xmax - restrict_offsets.hide),
+ int(region->v2d.cur.xmax - restrict_offsets.hide),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1182,7 +1185,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(region->v2d.cur.xmax - restrict_offsets.select),
+ int(region->v2d.cur.xmax - restrict_offsets.select),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1207,7 +1210,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(region->v2d.cur.xmax - restrict_offsets.viewport),
+ int(region->v2d.cur.xmax - restrict_offsets.viewport),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1232,7 +1235,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(region->v2d.cur.xmax - restrict_offsets.render),
+ int(region->v2d.cur.xmax - restrict_offsets.render),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1263,7 +1266,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(region->v2d.cur.xmax - restrict_offsets.hide),
+ int(region->v2d.cur.xmax - restrict_offsets.hide),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1292,7 +1295,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(region->v2d.cur.xmax - restrict_offsets.viewport),
+ int(region->v2d.cur.xmax - restrict_offsets.viewport),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1315,7 +1318,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(region->v2d.cur.xmax - restrict_offsets.render),
+ int(region->v2d.cur.xmax - restrict_offsets.render),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1347,7 +1350,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(region->v2d.cur.xmax - restrict_offsets.viewport),
+ int(region->v2d.cur.xmax - restrict_offsets.viewport),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1371,7 +1374,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
BONE_UNSELECTABLE,
0,
ICON_RESTRICT_SELECT_OFF,
- (int)(region->v2d.cur.xmax - restrict_offsets.select),
+ int(region->v2d.cur.xmax - restrict_offsets.select),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1397,7 +1400,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
BONE_HIDDEN_A,
0,
ICON_RESTRICT_VIEW_OFF,
- (int)(region->v2d.cur.xmax - restrict_offsets.viewport),
+ int(region->v2d.cur.xmax - restrict_offsets.viewport),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1419,7 +1422,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
BONE_UNSELECTABLE,
0,
ICON_RESTRICT_SELECT_OFF,
- (int)(region->v2d.cur.xmax - restrict_offsets.select),
+ int(region->v2d.cur.xmax - restrict_offsets.select),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1445,7 +1448,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
GP_LAYER_HIDE,
0,
ICON_HIDE_OFF,
- (int)(region->v2d.cur.xmax - restrict_offsets.hide),
+ int(region->v2d.cur.xmax - restrict_offsets.hide),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1466,7 +1469,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
GP_LAYER_LOCKED,
0,
ICON_UNLOCKED,
- (int)(region->v2d.cur.xmax - restrict_offsets.select),
+ int(region->v2d.cur.xmax - restrict_offsets.select),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1498,7 +1501,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(region->v2d.cur.xmax) - restrict_offsets.enable,
+ int(region->v2d.cur.xmax) - restrict_offsets.enable,
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1518,7 +1521,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(region->v2d.cur.xmax - restrict_offsets.hide),
+ int(region->v2d.cur.xmax - restrict_offsets.hide),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1547,7 +1550,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(region->v2d.cur.xmax - restrict_offsets.holdout),
+ int(region->v2d.cur.xmax - restrict_offsets.holdout),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1577,7 +1580,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(region->v2d.cur.xmax - restrict_offsets.indirect_only),
+ int(region->v2d.cur.xmax - restrict_offsets.indirect_only),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1609,7 +1612,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(region->v2d.cur.xmax - restrict_offsets.viewport),
+ int(region->v2d.cur.xmax - restrict_offsets.viewport),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1646,7 +1649,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(region->v2d.cur.xmax - restrict_offsets.render),
+ int(region->v2d.cur.xmax - restrict_offsets.render),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1681,7 +1684,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(region->v2d.cur.xmax - restrict_offsets.select),
+ int(region->v2d.cur.xmax - restrict_offsets.select),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1756,7 +1759,7 @@ static void outliner_draw_userbuts(uiBlock *block,
UI_BTYPE_BUT,
1,
buf,
- (int)(region->v2d.cur.xmax - OL_TOG_USER_BUTS_USERS),
+ int(region->v2d.cur.xmax - OL_TOG_USER_BUTS_USERS),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1779,7 +1782,7 @@ static void outliner_draw_userbuts(uiBlock *block,
LIB_FAKEUSER,
1,
ICON_FAKE_USER_OFF,
- (int)(region->v2d.cur.xmax - OL_TOG_USER_BUTS_STATUS),
+ int(region->v2d.cur.xmax - OL_TOG_USER_BUTS_STATUS),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -2090,7 +2093,7 @@ static void outliner_buttons(const bContext *C,
UI_UNIT_Y - 1,
(void *)te->name,
1.0,
- (float)len,
+ float(len),
0,
0,
"");
@@ -2105,7 +2108,7 @@ static void outliner_buttons(const bContext *C,
}
}
-static void outliner_mode_toggle_fn(bContext *C, void *tselem_poin, void *UNUSED(arg2))
+static void outliner_mode_toggle_fn(bContext *C, void *tselem_poin, void * /*arg2*/)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
TreeStoreElem *tselem = (TreeStoreElem *)tselem_poin;
@@ -2364,7 +2367,7 @@ static BIFIconID tree_element_get_icon_from_id(const ID *id)
/* TODO(sergey): Casting to short here just to handle ID_NLA which is
* NOT inside of IDType enum.
*/
- switch ((short)GS(id->name)) {
+ switch (short(GS(id->name))) {
case ID_SCE:
return ICON_SCENE_DATA;
case ID_ME:
@@ -2874,7 +2877,8 @@ static bool tselem_draw_icon(uiBlock *block,
TreeStoreElem *tselem,
TreeElement *te,
float alpha,
- const bool is_clickable)
+ const bool is_clickable,
+ const int num_elements)
{
TreeElementIcon data = tree_element_get_icon(tselem, te);
if (data.icon == 0) {
@@ -2882,6 +2886,8 @@ static bool tselem_draw_icon(uiBlock *block,
}
const bool is_collection = outliner_is_collection_tree_element(te);
+ IconTextOverlay text_overlay;
+ UI_icon_text_overlay_init_from_count(&text_overlay, num_elements);
/* Collection colors and icons covered by restrict buttons. */
if (!is_clickable || x >= xmax || is_collection) {
@@ -2901,7 +2907,8 @@ static bool tselem_draw_icon(uiBlock *block,
alpha,
0.0f,
btheme->collection_color[collection->color_tag].color,
- true);
+ true,
+ &text_overlay);
return true;
}
}
@@ -2912,10 +2919,10 @@ static bool tselem_draw_icon(uiBlock *block,
/* Restrict column clip. it has been coded by simply overdrawing, doesn't work for buttons. */
uchar color[4];
if (UI_icon_get_theme_color(data.icon, color)) {
- UI_icon_draw_ex(x, y, data.icon, U.inv_dpi_fac, alpha, 0.0f, color, true);
+ UI_icon_draw_ex(x, y, data.icon, U.inv_dpi_fac, alpha, 0.0f, color, true, &text_overlay);
}
else {
- UI_icon_draw_ex(x, y, data.icon, U.inv_dpi_fac, alpha, 0.0f, nullptr, false);
+ UI_icon_draw_ex(x, y, data.icon, U.inv_dpi_fac, alpha, 0.0f, nullptr, false, &text_overlay);
}
}
else {
@@ -2938,53 +2945,6 @@ static bool tselem_draw_icon(uiBlock *block,
return true;
}
-/**
- * For icon-only children of a collapsed tree,
- * Draw small number over the icon to show how many items of this type are displayed.
- */
-static void outliner_draw_iconrow_number(const uiFontStyle *fstyle,
- int offsx,
- int ys,
- const int num_elements)
-{
- const float color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
- float ufac = 0.25f * UI_UNIT_X;
- float offset_x = (float)offsx + UI_UNIT_X * 0.35f;
- rctf rect{};
- BLI_rctf_init(&rect,
- offset_x + ufac,
- offset_x + UI_UNIT_X - ufac,
- (float)ys - UI_UNIT_Y * 0.2f + ufac,
- (float)ys - UI_UNIT_Y * 0.2f + UI_UNIT_Y - ufac);
-
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(&rect, true, (float)UI_UNIT_Y / 2.0f - ufac, color);
-
- /* Now the numbers. */
- uchar text_col[4];
-
- UI_GetThemeColor3ubv(TH_TEXT_HI, text_col);
- text_col[3] = 255;
-
- uiFontStyle fstyle_small = *fstyle;
- fstyle_small.points *= 0.8f;
-
- /* We treat +99 as 4 digits to make sure the (eyeballed) alignment looks nice. */
- int num_digits = 4;
- char number_text[4] = "+99";
- if (num_elements < 100) {
- BLI_snprintf(number_text, sizeof(number_text), "%d", num_elements);
- num_digits = num_elements < 10 ? 1 : 2;
- }
- UI_fontstyle_draw_simple(&fstyle_small,
- (offset_x + ufac + UI_UNIT_X * (2 - num_digits) * 0.12f),
- (float)ys - UI_UNIT_Y * 0.095f + ufac,
- number_text,
- text_col);
- UI_fontstyle_set(fstyle);
- GPU_blend(GPU_BLEND_ALPHA); /* Roundbox and text drawing disables. */
-}
-
static void outliner_icon_background_colors(float icon_color[4], float icon_border[4])
{
float text[4];
@@ -3012,12 +2972,11 @@ static void outliner_draw_active_indicator(const float minx,
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_aa(&rect, true, radius, icon_color);
UI_draw_roundbox_aa(&rect, false, radius, icon_border);
- GPU_blend(GPU_BLEND_ALPHA); /* Roundbox disables. */
+ GPU_blend(GPU_BLEND_ALPHA); /* Round-box disables. */
}
static void outliner_draw_iconrow_doit(uiBlock *block,
TreeElement *te,
- const uiFontStyle *fstyle,
int xmax,
int *offsx,
int ys,
@@ -3035,10 +2994,10 @@ static void outliner_draw_iconrow_doit(uiBlock *block,
icon_border[3] = 0.3f;
}
- outliner_draw_active_indicator((float)*offsx,
- (float)ys,
- (float)*offsx + UI_UNIT_X,
- (float)ys + UI_UNIT_Y,
+ outliner_draw_active_indicator(float(*offsx),
+ float(ys),
+ float(*offsx) + UI_UNIT_X,
+ float(ys) + UI_UNIT_Y,
icon_color,
icon_border);
}
@@ -3046,13 +3005,13 @@ static void outliner_draw_iconrow_doit(uiBlock *block,
if (tselem->flag & TSE_HIGHLIGHTED_ICON) {
alpha_fac += 0.5;
}
- tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, alpha_fac, false);
+ tselem_draw_icon(
+ block, xmax, float(*offsx), float(ys), tselem, te, alpha_fac, false, num_elements);
te->xs = *offsx;
te->ys = ys;
- te->xend = (short)*offsx + UI_UNIT_X;
+ te->xend = short(*offsx) + UI_UNIT_X;
if (num_elements > 1) {
- outliner_draw_iconrow_number(fstyle, *offsx, ys, num_elements);
te->flag |= TE_ICONROW_MERGED;
}
else {
@@ -3095,6 +3054,7 @@ static void outliner_draw_iconrow(bContext *C,
int *offsx,
int ys,
float alpha_fac,
+ bool in_bone_hierarchy,
MergedIconRow *merged)
{
eOLDrawState active = OL_DRAWSEL_NONE;
@@ -3104,8 +3064,12 @@ static void outliner_draw_iconrow(bContext *C,
te->flag &= ~(TE_ICONROW | TE_ICONROW_MERGED);
/* object hierarchy always, further constrained on level */
+ /* Bones are also hierarchies and get a merged count, but we only start recursing into them if
+ * an they are at the root level of a collapsed subtree (e.g. not "hidden" in a collapsed
+ * collection). */
+ const bool is_bone = ELEM(tselem->type, TSE_BONE, TSE_EBONE, TSE_POSE_CHANNEL);
if ((level < 1) || ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) ||
- ELEM(tselem->type, TSE_BONE, TSE_EBONE, TSE_POSE_CHANNEL)) {
+ (in_bone_hierarchy && is_bone)) {
/* active blocks get white circle */
if (tselem->type == TSE_SOME_ID) {
if (te->idcode == ID_OB) {
@@ -3136,7 +3100,7 @@ static void outliner_draw_iconrow(bContext *C,
TSE_POSE_CHANNEL,
TSE_POSEGRP,
TSE_DEFGROUP)) {
- outliner_draw_iconrow_doit(block, te, fstyle, xmax, offsx, ys, alpha_fac, active, 1);
+ outliner_draw_iconrow_doit(block, te, xmax, offsx, ys, alpha_fac, active, 1);
}
else {
const int index = tree_element_id_type_to_index(te);
@@ -3148,8 +3112,13 @@ static void outliner_draw_iconrow(bContext *C,
}
}
- /* this tree element always has same amount of branches, so don't draw */
- if (tselem->type != TSE_R_LAYER) {
+ /* TSE_R_LAYER tree element always has same amount of branches, so don't draw. */
+ /* Also only recurse into bone hierarchies if a direct child of the collapsed element to merge
+ * into. */
+ const bool is_root_level_bone = is_bone && (level == 0);
+ in_bone_hierarchy |= is_root_level_bone;
+ if (!ELEM(tselem->type, TSE_R_LAYER, TSE_BONE, TSE_EBONE, TSE_POSE_CHANNEL) ||
+ in_bone_hierarchy) {
outliner_draw_iconrow(C,
block,
fstyle,
@@ -3161,6 +3130,7 @@ static void outliner_draw_iconrow(bContext *C,
offsx,
ys,
alpha_fac,
+ in_bone_hierarchy,
merged);
}
}
@@ -3178,7 +3148,6 @@ static void outliner_draw_iconrow(bContext *C,
if (merged->num_elements[index] != 0) {
outliner_draw_iconrow_doit(block,
merged->tree_element[index],
- fstyle,
xmax,
offsx,
ys,
@@ -3213,6 +3182,7 @@ static bool element_should_draw_faded(const TreeViewContext *tvc,
case ID_OB: {
const Object *ob = (const Object *)tselem->id;
/* Lookup in view layer is logically const as it only checks a cache. */
+ BKE_view_layer_synced_ensure(tvc->scene, tvc->view_layer);
const Base *base = (te->directdata) ? (const Base *)te->directdata :
BKE_view_layer_base_find(
(ViewLayer *)tvc->view_layer, (Object *)ob);
@@ -3281,6 +3251,7 @@ static void outliner_draw_tree_element(bContext *C,
if (tselem->type == TSE_SOME_ID) {
if (te->idcode == ID_OB) {
Object *ob = (Object *)tselem->id;
+ BKE_view_layer_synced_ensure(tvc->scene, tvc->view_layer);
Base *base = (te->directdata) ? (Base *)te->directdata :
BKE_view_layer_base_find(tvc->view_layer, ob);
const bool is_selected = (base != nullptr) && ((base->flag & BASE_SELECTED) != 0);
@@ -3322,10 +3293,10 @@ static void outliner_draw_tree_element(bContext *C,
/* Active circle. */
if (active != OL_DRAWSEL_NONE) {
- outliner_draw_active_indicator((float)startx + offsx + UI_UNIT_X,
- (float)*starty,
- (float)startx + offsx + 2.0f * UI_UNIT_X,
- (float)*starty + UI_UNIT_Y,
+ outliner_draw_active_indicator(float(startx) + offsx + UI_UNIT_X,
+ float(*starty),
+ float(startx) + offsx + 2.0f * UI_UNIT_X,
+ float(*starty) + UI_UNIT_Y,
icon_bgcolor,
icon_border);
@@ -3342,14 +3313,14 @@ static void outliner_draw_tree_element(bContext *C,
/* Icons a bit higher. */
if (TSELEM_OPEN(tselem, space_outliner)) {
- UI_icon_draw_alpha((float)icon_x + 2 * ufac,
- (float)*starty + 1 * ufac,
+ UI_icon_draw_alpha(float(icon_x) + 2 * ufac,
+ float(*starty) + 1 * ufac,
ICON_DISCLOSURE_TRI_DOWN,
alpha_fac);
}
else {
- UI_icon_draw_alpha((float)icon_x + 2 * ufac,
- (float)*starty + 1 * ufac,
+ UI_icon_draw_alpha(float(icon_x) + 2 * ufac,
+ float(*starty) + 1 * ufac,
ICON_DISCLOSURE_TRI_RIGHT,
alpha_fac);
}
@@ -3357,15 +3328,16 @@ static void outliner_draw_tree_element(bContext *C,
offsx += UI_UNIT_X;
/* Data-type icon. */
- if (!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, TSE_ID_BASE)) &&
+ if (!ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, TSE_ID_BASE) &&
tselem_draw_icon(block,
xmax,
- (float)startx + offsx,
- (float)*starty,
+ float(startx) + offsx,
+ float(*starty),
tselem,
te,
(tselem->flag & TSE_HIGHLIGHTED_ICON) ? alpha_fac + 0.5f : alpha_fac,
- true)) {
+ true,
+ 1)) {
offsx += UI_UNIT_X + 4 * ufac;
}
else {
@@ -3378,7 +3350,7 @@ static void outliner_draw_tree_element(bContext *C,
const BIFIconID lib_icon = (BIFIconID)UI_icon_from_library(tselem->id);
if (lib_icon != ICON_NONE) {
UI_icon_draw_alpha(
- (float)startx + offsx + 2 * ufac, (float)*starty + 2 * ufac, lib_icon, alpha_fac);
+ float(startx) + offsx + 2 * ufac, float(*starty) + 2 * ufac, lib_icon, alpha_fac);
offsx += UI_UNIT_X + 4 * ufac;
}
}
@@ -3394,7 +3366,7 @@ static void outliner_draw_tree_element(bContext *C,
UI_fontstyle_draw_simple(fstyle, startx + offsx, *starty + 5 * ufac, te->name, text_color);
}
- offsx += (int)(UI_UNIT_X + UI_fontstyle_string_width(fstyle, te->name));
+ offsx += int(UI_UNIT_X + UI_fontstyle_string_width(fstyle, te->name));
/* Closed item, we draw the icons, not when it's a scene, or master-server list though. */
if (!TSELEM_OPEN(tselem, space_outliner)) {
@@ -3420,6 +3392,7 @@ static void outliner_draw_tree_element(bContext *C,
&tempx,
*starty,
alpha_fac,
+ false,
&merged);
GPU_blend(GPU_BLEND_NONE);
@@ -3585,7 +3558,7 @@ static void outliner_draw_struct_marks(ARegion *region,
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immThemeColorShadeAlpha(TH_BACK, -15, -200);
- immRecti(pos, 0, *starty + 1, (int)region->v2d.cur.xmax, *starty + UI_UNIT_Y - 1);
+ immRecti(pos, 0, *starty + 1, int(region->v2d.cur.xmax), *starty + UI_UNIT_Y - 1);
immUnbindProgram();
}
}
@@ -3600,8 +3573,8 @@ static void outliner_draw_struct_marks(ARegion *region,
immThemeColorShadeAlpha(TH_BACK, -15, -200);
immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, 0, (float)*starty + UI_UNIT_Y);
- immVertex2f(pos, region->v2d.cur.xmax, (float)*starty + UI_UNIT_Y);
+ immVertex2f(pos, 0, float(*starty) + UI_UNIT_Y);
+ immVertex2f(pos, region->v2d.cur.xmax, float(*starty) + UI_UNIT_Y);
immEnd();
immUnbindProgram();
@@ -3631,16 +3604,16 @@ static void outliner_draw_highlights(uint pos,
/* Selection status. */
if ((tselem->flag & TSE_ACTIVE) && (tselem->flag & TSE_SELECTED)) {
immUniformColor4fv(col_active);
- immRecti(pos, 0, start_y, (int)region->v2d.cur.xmax, start_y + UI_UNIT_Y);
+ immRecti(pos, 0, start_y, int(region->v2d.cur.xmax), start_y + UI_UNIT_Y);
}
else if (tselem->flag & TSE_SELECTED) {
immUniformColor4fv(col_selection);
- immRecti(pos, 0, start_y, (int)region->v2d.cur.xmax, start_y + UI_UNIT_Y);
+ immRecti(pos, 0, start_y, int(region->v2d.cur.xmax), start_y + UI_UNIT_Y);
}
/* Highlights. */
if (tselem->flag & (TSE_DRAG_ANY | TSE_HIGHLIGHTED | TSE_SEARCHMATCH)) {
- const int end_x = (int)region->v2d.cur.xmax;
+ const int end_x = int(region->v2d.cur.xmax);
if (tselem->flag & TSE_DRAG_ANY) {
/* Drag and drop highlight. */
@@ -3744,19 +3717,19 @@ static void outliner_draw_tree(bContext *C,
if (space_outliner->outlinevis == SO_DATA_API) {
/* struct marks */
- starty = (int)region->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
+ starty = int(region->v2d.tot.ymax) - UI_UNIT_Y - OL_Y_OFFSET;
outliner_draw_struct_marks(region, space_outliner, &space_outliner->tree, &starty);
}
/* Draw highlights before hierarchy. */
- starty = (int)region->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
+ starty = int(region->v2d.tot.ymax) - UI_UNIT_Y - OL_Y_OFFSET;
startx = 0;
outliner_draw_highlights(region, space_outliner, startx, &starty);
/* Set scissor so tree elements or lines can't overlap restriction icons. */
int scissor[4] = {0};
if (right_column_width > 0.0f) {
- int mask_x = BLI_rcti_size_x(&region->v2d.mask) - (int)right_column_width + 1;
+ int mask_x = BLI_rcti_size_x(&region->v2d.mask) - int(right_column_width) + 1;
CLAMP_MIN(mask_x, 0);
GPU_scissor_get(scissor);
@@ -3764,12 +3737,12 @@ static void outliner_draw_tree(bContext *C,
}
/* Draw hierarchy lines for collections and object children. */
- starty = (int)region->v2d.tot.ymax - OL_Y_OFFSET;
+ starty = int(region->v2d.tot.ymax) - OL_Y_OFFSET;
startx = columns_offset + UI_UNIT_X / 2 - (U.pixelsize + 1) / 2;
outliner_draw_hierarchy_lines(space_outliner, &space_outliner->tree, startx, &starty);
/* Items themselves. */
- starty = (int)region->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
+ starty = int(region->v2d.tot.ymax) - UI_UNIT_Y - OL_Y_OFFSET;
startx = columns_offset;
LISTBASE_FOREACH (TreeElement *, te, &space_outliner->tree) {
outliner_draw_tree_element(C,
@@ -3796,7 +3769,7 @@ static void outliner_back(ARegion *region)
{
int ystart;
- ystart = (int)region->v2d.tot.ymax;
+ ystart = int(region->v2d.tot.ymax);
ystart = UI_UNIT_Y * (ystart / (UI_UNIT_Y)) - OL_Y_OFFSET;
GPUVertFormat *format = immVertexFormat();
@@ -3810,7 +3783,7 @@ static void outliner_back(ARegion *region)
const float x1 = 0.0f, x2 = region->v2d.cur.xmax;
float y1 = ystart, y2;
- int tot = (int)floor(ystart - region->v2d.cur.ymin + 2 * UI_UNIT_Y) / (2 * UI_UNIT_Y);
+ int tot = int(floor(ystart - region->v2d.cur.ymin + 2 * UI_UNIT_Y)) / (2 * UI_UNIT_Y);
if (tot > 0) {
immBegin(GPU_PRIM_TRIS, 6 * tot);
@@ -3854,7 +3827,7 @@ static void outliner_update_viewable_area(ARegion *region,
int sizex = outliner_width(space_outliner, tree_width, right_column_width);
int sizey = tree_height;
- /* Extend size to allow for horizontal scrollbar and extra offset. */
+ /* Extend size to allow for horizontal scroll-bar and extra offset. */
sizey += V2D_SCROLL_HEIGHT + OL_Y_OFFSET;
UI_view2d_totRect_set(&region->v2d, sizex, sizey);
diff --git a/source/blender/editors/space_outliner/outliner_edit.cc b/source/blender/editors/space_outliner/outliner_edit.cc
index 8618c2999c2..9a6a25fdbae 100644
--- a/source/blender/editors/space_outliner/outliner_edit.cc
+++ b/source/blender/editors/space_outliner/outliner_edit.cc
@@ -77,7 +77,7 @@ static void outliner_show_active(SpaceOutliner *space_outliner,
/** \name Highlight on Cursor Motion Operator
* \{ */
-static int outliner_highlight_update(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+static int outliner_highlight_update(bContext *C, wmOperator * /*op*/, const wmEvent *event)
{
/* stop highlighting if out of area */
if (!ED_screen_area_active(C)) {
@@ -239,7 +239,7 @@ static int outliner_item_openclose_invoke(bContext *C, wmOperator *op, const wmE
TreeStoreElem *tselem = TREESTORE(te);
const bool open = (tselem->flag & TSE_CLOSED) ||
- (toggle_all && (outliner_flag_is_any_test(&te->subtree, TSE_CLOSED, 1)));
+ (toggle_all && outliner_flag_is_any_test(&te->subtree, TSE_CLOSED, 1));
outliner_item_openclose(te, open, toggle_all);
outliner_tag_redraw_avoid_rebuild_on_open_change(space_outliner, region);
@@ -358,11 +358,11 @@ static void do_item_rename(ARegion *region,
void item_rename_fn(bContext *C,
ReportList *reports,
- Scene *UNUSED(scene),
+ Scene * /*scene*/,
TreeElement *te,
- TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem * /*tsep*/,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
ARegion *region = CTX_wm_region(C);
do_item_rename(region, te, tselem, reports);
@@ -501,11 +501,11 @@ static void id_delete_tag(bContext *C, ReportList *reports, TreeElement *te, Tre
void id_delete_tag_fn(bContext *C,
ReportList *reports,
- Scene *UNUSED(scene),
+ Scene * /*scene*/,
TreeElement *te,
- TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem * /*tsep*/,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
id_delete_tag(C, reports, te, tselem);
}
@@ -596,7 +596,7 @@ static int outliner_id_remap_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
- const short id_type = (short)RNA_enum_get(op->ptr, "id_type");
+ const short id_type = short(RNA_enum_get(op->ptr, "id_type"));
ID *old_id = static_cast<ID *>(
BLI_findlink(which_libbase(CTX_data_main(C), id_type), RNA_enum_get(op->ptr, "old_id")));
ID *new_id = static_cast<ID *>(
@@ -681,7 +681,7 @@ static int outliner_id_remap_invoke(bContext *C, wmOperator *op, const wmEvent *
static const EnumPropertyItem *outliner_id_itemf(bContext *C,
PointerRNA *ptr,
- PropertyRNA *UNUSED(prop),
+ PropertyRNA * /*prop*/,
bool *r_free)
{
if (C == nullptr) {
@@ -692,7 +692,7 @@ static const EnumPropertyItem *outliner_id_itemf(bContext *C,
int totitem = 0;
int i = 0;
- short id_type = (short)RNA_enum_get(ptr, "id_type");
+ short id_type = short(RNA_enum_get(ptr, "id_type"));
ID *id = static_cast<ID *>(which_libbase(CTX_data_main(C), id_type)->first);
for (; id; id = static_cast<ID *>(id->next)) {
@@ -744,12 +744,12 @@ void OUTLINER_OT_id_remap(wmOperatorType *ot)
}
void id_remap_fn(bContext *C,
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep),
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
+ TreeElement * /*te*/,
+ TreeStoreElem * /*tsep*/,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
wmOperatorType *ot = WM_operatortype_find("OUTLINER_OT_id_remap", false);
PointerRNA op_props;
@@ -809,7 +809,7 @@ static int outliner_id_copy_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BLI_join_dirfile(str, sizeof(str), BKE_tempdir_base(), "copybuffer.blend");
+ BLI_path_join(str, sizeof(str), BKE_tempdir_base(), "copybuffer.blend");
BKE_copybuffer_copy_end(bmain, str, op->reports);
BKE_reportf(op->reports, RPT_INFO, "Copied %d selected data-block(s)", num_ids);
@@ -843,7 +843,7 @@ static int outliner_id_paste_exec(bContext *C, wmOperator *op)
char str[FILE_MAX];
const short flag = FILE_AUTOSELECT | FILE_ACTIVE_COLLECTION;
- BLI_join_dirfile(str, sizeof(str), BKE_tempdir_base(), "copybuffer.blend");
+ BLI_path_join(str, sizeof(str), BKE_tempdir_base(), "copybuffer.blend");
const int num_pasted = BKE_copybuffer_paste(C, str, flag, op->reports, 0);
if (num_pasted == 0) {
@@ -985,12 +985,12 @@ void OUTLINER_OT_lib_relocate(wmOperatorType *ot)
}
void lib_relocate_fn(bContext *C,
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
TreeElement *te,
- TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem * /*tsep*/,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
/* XXX: This does not work with several items
* (it is only called once in the end, due to the 'deferred'
@@ -1042,12 +1042,12 @@ void OUTLINER_OT_lib_reload(wmOperatorType *ot)
}
void lib_reload_fn(bContext *C,
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
TreeElement *te,
- TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem * /*tsep*/,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
wmOperatorType *ot = WM_operatortype_find("WM_OT_lib_reload", false);
@@ -1139,7 +1139,7 @@ bool outliner_flag_flip(const ListBase &lb, const short flag)
/** \name Toggle Expanded (Outliner) Operator
* \{ */
-static int outliner_toggle_expanded_exec(bContext *C, wmOperator *UNUSED(op))
+static int outliner_toggle_expanded_exec(bContext *C, wmOperator * /*op*/)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
ARegion *region = CTX_wm_region(C);
@@ -1233,12 +1233,12 @@ void OUTLINER_OT_select_all(wmOperatorType *ot)
void outliner_set_coordinates(const ARegion *region, const SpaceOutliner *space_outliner)
{
- int starty = (int)(region->v2d.tot.ymax) - UI_UNIT_Y;
+ int starty = int(region->v2d.tot.ymax) - UI_UNIT_Y;
tree_iterator::all_open(*space_outliner, [&](TreeElement *te) {
/* store coord and continue, we need coordinates for elements outside view too */
te->xs = 0;
- te->ys = (float)starty;
+ te->ys = float(starty);
starty -= UI_UNIT_Y;
});
}
@@ -1262,10 +1262,12 @@ static int outliner_open_back(TreeElement *te)
/* Return element representing the active base or bone in the outliner, or NULL if none exists */
static TreeElement *outliner_show_active_get_element(bContext *C,
SpaceOutliner *space_outliner,
+ const Scene *scene,
ViewLayer *view_layer)
{
TreeElement *te;
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obact = BKE_view_layer_active_object_get(view_layer);
if (!obact) {
@@ -1314,14 +1316,16 @@ static void outliner_show_active(SpaceOutliner *space_outliner,
}
}
-static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op))
+static int outliner_show_active_exec(bContext *C, wmOperator * /*op*/)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
ARegion *region = CTX_wm_region(C);
View2D *v2d = &region->v2d;
- TreeElement *active_element = outliner_show_active_get_element(C, space_outliner, view_layer);
+ TreeElement *active_element = outliner_show_active_get_element(
+ C, space_outliner, scene, view_layer);
if (active_element) {
ID *id = TREESTORE(active_element)->id;
@@ -1541,7 +1545,7 @@ static void tree_element_show_hierarchy(Scene *scene, SpaceOutliner *space_outli
}
/* show entire object level hierarchy */
-static int outliner_show_hierarchy_exec(bContext *C, wmOperator *UNUSED(op))
+static int outliner_show_hierarchy_exec(bContext *C, wmOperator * /*op*/)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
ARegion *region = CTX_wm_region(C);
@@ -1598,7 +1602,7 @@ static void tree_element_to_path(TreeElement *te,
char **path,
int *array_index,
short *flag,
- short *UNUSED(groupmode))
+ short * /*groupmode*/)
{
ListBase hierarchy = {nullptr, nullptr};
char *newpath = nullptr;
@@ -2053,7 +2057,7 @@ void OUTLINER_OT_keyingset_add_selected(wmOperatorType *ot)
/** \name Keying-Set Remove Operator
* \{ */
-static int outliner_keyingset_removeitems_exec(bContext *C, wmOperator *UNUSED(op))
+static int outliner_keyingset_removeitems_exec(bContext *C, wmOperator * /*op*/)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
Scene *scene = CTX_data_scene(C);
@@ -2104,7 +2108,7 @@ static bool ed_operator_outliner_id_orphans_active(bContext *C)
return true;
}
-static int outliner_orphans_purge_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int outliner_orphans_purge_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
Main *bmain = CTX_data_main(C);
int num_tagged[INDEX_ID_MAX] = {0};
diff --git a/source/blender/editors/space_outliner/outliner_select.cc b/source/blender/editors/space_outliner/outliner_select.cc
index 071b244bd3d..20319a8befe 100644
--- a/source/blender/editors/space_outliner/outliner_select.cc
+++ b/source/blender/editors/space_outliner/outliner_select.cc
@@ -164,9 +164,10 @@ static void do_outliner_item_mode_toggle_generic(bContext *C, TreeViewContext *t
ED_undo_group_begin(C);
if (ED_object_mode_set(C, OB_MODE_OBJECT)) {
+ BKE_view_layer_synced_ensure(tvc->scene, tvc->view_layer);
Base *base_active = BKE_view_layer_base_find(tvc->view_layer, tvc->obact);
if (base_active != base) {
- BKE_view_layer_base_deselect_all(tvc->view_layer);
+ BKE_view_layer_base_deselect_all(tvc->scene, tvc->view_layer);
BKE_view_layer_base_select_and_set_active(tvc->view_layer, base);
DEG_id_tag_update(&tvc->scene->id, ID_RECALC_SELECT);
ED_undo_push(C, "Change Active");
@@ -188,6 +189,7 @@ void outliner_item_mode_toggle(bContext *C,
if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) {
Object *ob = (Object *)tselem->id;
+ BKE_view_layer_synced_ensure(tvc->scene, tvc->view_layer);
Base *base = BKE_view_layer_base_find(tvc->view_layer, ob);
/* Hidden objects can be removed from the mode. */
@@ -234,14 +236,16 @@ static void tree_element_viewlayer_activate(bContext *C, TreeElement *te)
/**
* Select object tree
*/
-static void do_outliner_object_select_recursive(ViewLayer *view_layer,
+static void do_outliner_object_select_recursive(const Scene *scene,
+ ViewLayer *view_layer,
Object *ob_parent,
bool select)
{
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *ob = base->object;
- if ((((base->flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT) != 0) &&
- BKE_object_is_child_recursive(ob_parent, ob))) {
+ if (((base->flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT) != 0) &&
+ BKE_object_is_child_recursive(ob_parent, ob)) {
ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
}
}
@@ -300,6 +304,7 @@ static void tree_element_object_activate(bContext *C,
ob = (Object *)parent_tselem->id;
/* Don't return when activating children of the previous active object. */
+ BKE_view_layer_synced_ensure(scene, view_layer);
if (ob == BKE_view_layer_active_object_get(view_layer) && set == OL_SETSEL_NONE) {
return;
}
@@ -316,6 +321,7 @@ static void tree_element_object_activate(bContext *C,
}
/* find associated base in current scene */
+ BKE_view_layer_synced_ensure(sce, view_layer);
base = BKE_view_layer_base_find(view_layer, ob);
if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
@@ -361,7 +367,7 @@ static void tree_element_object_activate(bContext *C,
if ((scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) ?
(ob->mode == OB_MODE_OBJECT) :
true) {
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
}
ED_object_base_select(base, BA_SELECT);
if (parent_tselem) {
@@ -371,7 +377,8 @@ static void tree_element_object_activate(bContext *C,
if (recursive) {
/* Recursive select/deselect for Object hierarchies */
- do_outliner_object_select_recursive(view_layer, ob, (base->flag & BASE_SELECTED) != 0);
+ do_outliner_object_select_recursive(
+ scene, view_layer, ob, (base->flag & BASE_SELECTED) != 0);
}
if (set != OL_SETSEL_NONE) {
@@ -382,11 +389,15 @@ static void tree_element_object_activate(bContext *C,
}
}
-static void tree_element_material_activate(bContext *C, ViewLayer *view_layer, TreeElement *te)
+static void tree_element_material_activate(bContext *C,
+ const Scene *scene,
+ ViewLayer *view_layer,
+ TreeElement *te)
{
/* we search for the object parent */
Object *ob = (Object *)outliner_search_back(te, ID_OB);
/* Note : ob->matbits can be nullptr when a local object points to a library mesh. */
+ BKE_view_layer_synced_ensure(scene, view_layer);
if (ob == nullptr || ob != BKE_view_layer_active_object_get(view_layer) ||
ob->matbits == nullptr) {
return; /* just paranoia */
@@ -479,6 +490,7 @@ static void tree_element_posegroup_activate(bContext *C, TreeElement *te, TreeSt
}
static void tree_element_posechannel_activate(bContext *C,
+ const Scene *scene,
ViewLayer *view_layer,
TreeElement *te,
TreeStoreElem *tselem,
@@ -493,7 +505,8 @@ static void tree_element_posechannel_activate(bContext *C,
if (set != OL_SETSEL_EXTEND) {
/* Single select forces all other bones to get unselected. */
uint objects_len = 0;
- Object **objects = BKE_object_pose_array_get_unique(view_layer, nullptr, &objects_len);
+ Object **objects = BKE_object_pose_array_get_unique(
+ scene, view_layer, nullptr, &objects_len);
for (uint object_index = 0; object_index < objects_len; object_index++) {
Object *ob_iter = BKE_object_pose_armature_get(objects[object_index]);
@@ -534,6 +547,7 @@ static void tree_element_posechannel_activate(bContext *C,
}
static void tree_element_bone_activate(bContext *C,
+ const Scene *scene,
ViewLayer *view_layer,
TreeElement *te,
TreeStoreElem *tselem,
@@ -544,6 +558,7 @@ static void tree_element_bone_activate(bContext *C,
Bone *bone = static_cast<Bone *>(te->directdata);
if (!(bone->flag & BONE_HIDDEN_P)) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ob) {
if (set != OL_SETSEL_EXTEND) {
@@ -583,6 +598,7 @@ static void tree_element_active_ebone__sel(bContext *C, bArmature *arm, EditBone
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, CTX_data_edit_object(C));
}
static void tree_element_ebone_activate(bContext *C,
+ const Scene *scene,
ViewLayer *view_layer,
TreeElement *te,
TreeStoreElem *tselem,
@@ -601,7 +617,7 @@ static void tree_element_ebone_activate(bContext *C,
ob_params.no_dup_data = true;
Base **bases = BKE_view_layer_array_from_bases_in_mode_params(
- view_layer, nullptr, &bases_len, &ob_params);
+ scene, view_layer, nullptr, &bases_len, &ob_params);
ED_armature_edit_deselect_all_multi_ex(bases, bases_len);
MEM_freeN(bases);
@@ -648,6 +664,7 @@ static void tree_element_psys_activate(bContext *C, TreeStoreElem *tselem)
}
static void tree_element_constraint_activate(bContext *C,
+ const Scene *scene,
ViewLayer *view_layer,
TreeElement *te,
TreeStoreElem *tselem,
@@ -660,7 +677,7 @@ static void tree_element_constraint_activate(bContext *C,
while (te) {
tselem = TREESTORE(te);
if (tselem->type == TSE_POSE_CHANNEL) {
- tree_element_posechannel_activate(C, view_layer, te, tselem, set, false);
+ tree_element_posechannel_activate(C, scene, view_layer, te, tselem, set, false);
return;
}
te = te->parent;
@@ -696,7 +713,7 @@ static void tree_element_sequence_activate(bContext *C,
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
}
-static void tree_element_sequence_dup_activate(Scene *scene, TreeElement *UNUSED(te))
+static void tree_element_sequence_dup_activate(Scene *scene, TreeElement * /*te*/)
{
Editing *ed = SEQ_editing_get(scene);
@@ -765,7 +782,7 @@ void tree_element_activate(bContext *C,
}
break;
case ID_MA:
- tree_element_material_activate(C, tvc->view_layer, te);
+ tree_element_material_activate(C, tvc->scene, tvc->view_layer, te);
break;
case ID_WO:
tree_element_world_activate(C, tvc->scene, te);
@@ -792,10 +809,10 @@ void tree_element_type_active_set(bContext *C,
tree_element_defgroup_activate(C, te, tselem);
break;
case TSE_BONE:
- tree_element_bone_activate(C, tvc->view_layer, te, tselem, set, recursive);
+ tree_element_bone_activate(C, tvc->scene, tvc->view_layer, te, tselem, set, recursive);
break;
case TSE_EBONE:
- tree_element_ebone_activate(C, tvc->view_layer, te, tselem, set, recursive);
+ tree_element_ebone_activate(C, tvc->scene, tvc->view_layer, te, tselem, set, recursive);
break;
case TSE_MODIFIER:
tree_element_modifier_activate(C, te, tselem, set);
@@ -809,11 +826,12 @@ void tree_element_type_active_set(bContext *C,
case TSE_POSE_BASE:
return;
case TSE_POSE_CHANNEL:
- tree_element_posechannel_activate(C, tvc->view_layer, te, tselem, set, recursive);
+ tree_element_posechannel_activate(
+ C, tvc->scene, tvc->view_layer, te, tselem, set, recursive);
break;
case TSE_CONSTRAINT_BASE:
case TSE_CONSTRAINT:
- tree_element_constraint_activate(C, tvc->view_layer, te, tselem, set);
+ tree_element_constraint_activate(C, tvc->scene, tvc->view_layer, te, tselem, set);
break;
case TSE_R_LAYER:
tree_element_viewlayer_activate(C, te);
@@ -839,11 +857,13 @@ void tree_element_type_active_set(bContext *C,
}
}
-static eOLDrawState tree_element_defgroup_state_get(const ViewLayer *view_layer,
+static eOLDrawState tree_element_defgroup_state_get(const Scene *scene,
+ ViewLayer *view_layer,
const TreeElement *te,
const TreeStoreElem *tselem)
{
const Object *ob = (const Object *)tselem->id;
+ BKE_view_layer_synced_ensure(scene, view_layer);
if (ob == BKE_view_layer_active_object_get(view_layer)) {
if (BKE_object_defgroup_active_index_get(ob) == te->index + 1) {
return OL_DRAWSEL_NORMAL;
@@ -852,12 +872,14 @@ static eOLDrawState tree_element_defgroup_state_get(const ViewLayer *view_layer,
return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_bone_state_get(const ViewLayer *view_layer,
+static eOLDrawState tree_element_bone_state_get(const Scene *scene,
+ ViewLayer *view_layer,
const TreeElement *te,
const TreeStoreElem *tselem)
{
const bArmature *arm = (const bArmature *)tselem->id;
const Bone *bone = static_cast<Bone *>(te->directdata);
+ BKE_view_layer_synced_ensure(scene, view_layer);
const Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ob && ob->data == arm) {
if (bone->flag & BONE_SELECTED) {
@@ -891,11 +913,13 @@ static eOLDrawState tree_element_object_state_get(const TreeViewContext *tvc,
return (tselem->id == (const ID *)tvc->obact) ? OL_DRAWSEL_NORMAL : OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_pose_state_get(const ViewLayer *view_layer,
+static eOLDrawState tree_element_pose_state_get(const Scene *scene,
+ const ViewLayer *view_layer,
const TreeStoreElem *tselem)
{
const Object *ob = (const Object *)tselem->id;
/* This will just lookup in a cache, it will not change the arguments. */
+ BKE_view_layer_synced_ensure(scene, (ViewLayer *)view_layer);
const Base *base = BKE_view_layer_base_find((ViewLayer *)view_layer, (Object *)ob);
if (base == nullptr) {
/* Armature not instantiated in current scene (e.g. inside an appended group). */
@@ -937,12 +961,14 @@ static eOLDrawState tree_element_viewlayer_state_get(const bContext *C, const Tr
return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_posegroup_state_get(const ViewLayer *view_layer,
+static eOLDrawState tree_element_posegroup_state_get(const Scene *scene,
+ ViewLayer *view_layer,
const TreeElement *te,
const TreeStoreElem *tselem)
{
const Object *ob = (const Object *)tselem->id;
+ BKE_view_layer_synced_ensure(scene, view_layer);
if (ob == BKE_view_layer_active_object_get(view_layer) && ob->pose) {
if (ob->pose->active_group == te->index + 1) {
return OL_DRAWSEL_NORMAL;
@@ -1003,12 +1029,14 @@ static eOLDrawState tree_element_layer_collection_state_get(const bContext *C,
return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_material_get(const ViewLayer *view_layer,
+static eOLDrawState tree_element_active_material_get(const Scene *scene,
+ ViewLayer *view_layer,
const TreeElement *te)
{
/* we search for the object parent */
const Object *ob = (const Object *)outliner_search_back((TreeElement *)te, ID_OB);
/* Note : ob->matbits can be nullptr when a local object points to a library mesh. */
+ BKE_view_layer_synced_ensure(scene, view_layer);
if (ob == nullptr || ob != BKE_view_layer_active_object_get(view_layer) ||
ob->matbits == nullptr) {
return OL_DRAWSEL_NONE; /* just paranoia */
@@ -1079,7 +1107,7 @@ eOLDrawState tree_element_active_state_get(const TreeViewContext *tvc,
return OL_DRAWSEL_NONE;
break;
case ID_MA:
- return tree_element_active_material_get(tvc->view_layer, te);
+ return tree_element_active_material_get(tvc->scene, tvc->view_layer, te);
case ID_WO:
return tree_element_active_world_get(tvc->scene, te);
case ID_CA:
@@ -1095,9 +1123,9 @@ eOLDrawState tree_element_type_active_state_get(const bContext *C,
{
switch (tselem->type) {
case TSE_DEFGROUP:
- return tree_element_defgroup_state_get(tvc->view_layer, te, tselem);
+ return tree_element_defgroup_state_get(tvc->scene, tvc->view_layer, te, tselem);
case TSE_BONE:
- return tree_element_bone_state_get(tvc->view_layer, te, tselem);
+ return tree_element_bone_state_get(tvc->scene, tvc->view_layer, te, tselem);
case TSE_EBONE:
return tree_element_ebone_state_get(te);
case TSE_MODIFIER:
@@ -1107,7 +1135,7 @@ eOLDrawState tree_element_type_active_state_get(const bContext *C,
case TSE_LINKED_PSYS:
return OL_DRAWSEL_NONE;
case TSE_POSE_BASE:
- return tree_element_pose_state_get(tvc->view_layer, tselem);
+ return tree_element_pose_state_get(tvc->scene, tvc->view_layer, tselem);
case TSE_POSE_CHANNEL:
return tree_element_posechannel_state_get(tvc->ob_pose, te, tselem);
case TSE_CONSTRAINT_BASE:
@@ -1116,7 +1144,7 @@ eOLDrawState tree_element_type_active_state_get(const bContext *C,
case TSE_R_LAYER:
return tree_element_viewlayer_state_get(C, te);
case TSE_POSEGRP:
- return tree_element_posegroup_state_get(tvc->view_layer, te, tselem);
+ return tree_element_posegroup_state_get(tvc->scene, tvc->view_layer, te, tselem);
case TSE_SEQUENCE:
return tree_element_sequence_state_get(tvc->scene, te);
case TSE_SEQUENCE_DUP:
@@ -1397,6 +1425,7 @@ static void do_outliner_item_activate_tree_element(bContext *C,
}
else if ((te->idcode == ID_GR) && (space_outliner->outlinevis != SO_VIEW_LAYER)) {
Collection *gr = (Collection *)tselem->id;
+ BKE_view_layer_synced_ensure(tvc->scene, tvc->view_layer);
if (extend) {
eObjectSelect_Mode sel = BA_SELECT;
@@ -1418,7 +1447,7 @@ static void do_outliner_item_activate_tree_element(bContext *C,
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
else {
- BKE_view_layer_base_deselect_all(tvc->view_layer);
+ BKE_view_layer_base_deselect_all(tvc->scene, tvc->view_layer);
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (gr, object) {
Base *base = BKE_view_layer_base_find(tvc->view_layer, object);
@@ -1570,7 +1599,9 @@ static bool outliner_is_co_within_active_mode_column(bContext *C,
SpaceOutliner *space_outliner,
const float view_mval[2])
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obact = BKE_view_layer_active_object_get(view_layer);
return outliner_is_co_within_mode_column(space_outliner, view_mval) && obact &&
@@ -1986,7 +2017,7 @@ static void outliner_walk_scroll(SpaceOutliner *space_outliner, ARegion *region,
}
}
-static int outliner_walk_select_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int outliner_walk_select_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
ARegion *region = CTX_wm_region(C);
diff --git a/source/blender/editors/space_outliner/outliner_sync.cc b/source/blender/editors/space_outliner/outliner_sync.cc
index 8f1c15873b4..995c83b589d 100644
--- a/source/blender/editors/space_outliner/outliner_sync.cc
+++ b/source/blender/editors/space_outliner/outliner_sync.cc
@@ -225,7 +225,8 @@ static void outliner_select_sync_to_object(ViewLayer *view_layer,
}
}
-static void outliner_select_sync_to_edit_bone(ViewLayer *view_layer,
+static void outliner_select_sync_to_edit_bone(const Scene *scene,
+ ViewLayer *view_layer,
TreeElement *te,
TreeStoreElem *tselem,
GSet *selected_ebones)
@@ -250,6 +251,7 @@ static void outliner_select_sync_to_edit_bone(ViewLayer *view_layer,
/* Tag if selection changed */
if (bone_flag != ebone->flag) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
DEG_id_tag_update(&arm->id, ID_RECALC_SELECT);
WM_main_add_notifier(NC_OBJECT | ND_BONE_SELECT, obedit);
@@ -318,7 +320,8 @@ static void outliner_sync_selection_from_outliner(Scene *scene,
}
else if (tselem->type == TSE_EBONE) {
if (sync_types->edit_bone) {
- outliner_select_sync_to_edit_bone(view_layer, te, tselem, selected_items->edit_bones);
+ outliner_select_sync_to_edit_bone(
+ scene, view_layer, te, tselem, selected_items->edit_bones);
}
}
else if (tselem->type == TSE_POSE_CHANNEL) {
@@ -388,12 +391,14 @@ void ED_outliner_select_sync_from_outliner(bContext *C, SpaceOutliner *space_out
namespace blender::ed::outliner {
-static void outliner_select_sync_from_object(ViewLayer *view_layer,
+static void outliner_select_sync_from_object(const Scene *scene,
+ ViewLayer *view_layer,
Object *obact,
TreeElement *te,
TreeStoreElem *tselem)
{
Object *ob = (Object *)tselem->id;
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = (te->directdata) ? (Base *)te->directdata :
BKE_view_layer_base_find(view_layer, ob);
const bool is_selected = (base != nullptr) && ((base->flag & BASE_SELECTED) != 0);
@@ -487,7 +492,8 @@ struct SyncSelectActiveData {
};
/** Sync select and active flags from active view layer, bones, and sequences to the outliner. */
-static void outliner_sync_selection_to_outliner(ViewLayer *view_layer,
+static void outliner_sync_selection_to_outliner(const Scene *scene,
+ ViewLayer *view_layer,
SpaceOutliner *space_outliner,
ListBase *tree,
SyncSelectActiveData *active_data,
@@ -498,7 +504,7 @@ static void outliner_sync_selection_to_outliner(ViewLayer *view_layer,
if ((tselem->type == TSE_SOME_ID) && te->idcode == ID_OB) {
if (sync_types->object) {
- outliner_select_sync_from_object(view_layer, active_data->object, te, tselem);
+ outliner_select_sync_from_object(scene, view_layer, active_data->object, te, tselem);
}
}
else if (tselem->type == TSE_EBONE) {
@@ -522,7 +528,7 @@ static void outliner_sync_selection_to_outliner(ViewLayer *view_layer,
/* Sync subtree elements */
outliner_sync_selection_to_outliner(
- view_layer, space_outliner, &te->subtree, active_data, sync_types);
+ scene, view_layer, space_outliner, &te->subtree, active_data, sync_types);
}
}
@@ -531,6 +537,7 @@ static void get_sync_select_active_data(const bContext *C, SyncSelectActiveData
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
active_data->object = BKE_view_layer_active_object_get(view_layer);
active_data->edit_bone = CTX_data_active_bone(C);
active_data->pose_channel = CTX_data_active_pose_bone(C);
@@ -545,6 +552,7 @@ void outliner_sync_selection(const bContext *C, SpaceOutliner *space_outliner)
C, space_outliner, &sync_types);
if (sync_required) {
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
/* Store active object, bones, and sequence */
@@ -552,7 +560,7 @@ void outliner_sync_selection(const bContext *C, SpaceOutliner *space_outliner)
get_sync_select_active_data(C, &active_data);
outliner_sync_selection_to_outliner(
- view_layer, space_outliner, &space_outliner->tree, &active_data, &sync_types);
+ scene, view_layer, space_outliner, &space_outliner->tree, &active_data, &sync_types);
/* Keep any un-synced data in the dirty flag. */
if (sync_types.object) {
diff --git a/source/blender/editors/space_outliner/outliner_tools.cc b/source/blender/editors/space_outliner/outliner_tools.cc
index bab5b945d43..81e36fa6764 100644
--- a/source/blender/editors/space_outliner/outliner_tools.cc
+++ b/source/blender/editors/space_outliner/outliner_tools.cc
@@ -118,7 +118,7 @@ static void get_element_operation_type(
*datalevel = tselem->type;
}
else {
- const int idcode = (int)GS(tselem->id->name);
+ const int idcode = int(GS(tselem->id->name));
bool is_standard_id = false;
switch ((ID_Type)idcode) {
case ID_SCE:
@@ -215,25 +215,25 @@ static bool outliner_operation_tree_element_poll(bContext *C)
}
static void unlink_action_fn(bContext *C,
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
+ TreeElement * /*te*/,
TreeStoreElem *tsep,
- TreeStoreElem *UNUSED(tselem),
- void *UNUSED(user_data))
+ TreeStoreElem * /*tselem*/,
+ void * /*user_data*/)
{
/* just set action to nullptr */
BKE_animdata_set_action(CTX_wm_reports(C), tsep->id, nullptr);
DEG_id_tag_update(tsep->id, ID_RECALC_ANIMATION);
}
-static void unlink_material_fn(bContext *UNUSED(C),
+static void unlink_material_fn(bContext * /*C*/,
ReportList *reports,
- Scene *UNUSED(scene),
+ Scene * /*scene*/,
TreeElement *te,
TreeStoreElem *tsep,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
const bool te_is_material = TSE_IS_REAL_ID(tselem) && (GS(tselem->id->name) == ID_MA);
@@ -315,13 +315,13 @@ static void unlink_material_fn(bContext *UNUSED(C),
}
}
-static void unlink_texture_fn(bContext *UNUSED(C),
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
+static void unlink_texture_fn(bContext * /*C*/,
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
TreeElement *te,
TreeStoreElem *tsep,
- TreeStoreElem *UNUSED(tselem),
- void *UNUSED(user_data))
+ TreeStoreElem * /*tselem*/,
+ void * /*user_data*/)
{
MTex **mtex = nullptr;
int a;
@@ -345,12 +345,12 @@ static void unlink_texture_fn(bContext *UNUSED(C),
}
static void unlink_collection_fn(bContext *C,
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
+ TreeElement * /*te*/,
TreeStoreElem *tsep,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
Main *bmain = CTX_data_main(C);
Collection *collection = (Collection *)tselem->id;
@@ -381,12 +381,12 @@ static void unlink_collection_fn(bContext *C,
}
static void unlink_object_fn(bContext *C,
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
+ ReportList *reports,
+ Scene * /*scene*/,
TreeElement *te,
TreeStoreElem *tsep,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
if (tsep && tsep->id) {
Main *bmain = CTX_data_main(C);
@@ -396,12 +396,28 @@ static void unlink_object_fn(bContext *C,
/* Parented objects need to find which collection to unlink from. */
TreeElement *te_parent = te->parent;
while (tsep && GS(tsep->id->name) == ID_OB) {
+ if (ID_IS_LINKED(tsep->id)) {
+ BKE_reportf(reports,
+ RPT_WARNING,
+ "Cannot unlink object '%s' parented to another linked object '%s'",
+ ob->id.name + 2,
+ tsep->id->name + 2);
+ return;
+ }
te_parent = te_parent->parent;
tsep = te_parent ? TREESTORE(te_parent) : nullptr;
}
}
if (tsep && tsep->id) {
+ if (ID_IS_LINKED(tsep->id) || ID_IS_OVERRIDE_LIBRARY(tsep->id)) {
+ BKE_reportf(reports,
+ RPT_WARNING,
+ "Cannot unlink object '%s' from linked collection or scene '%s'",
+ ob->id.name + 2,
+ tsep->id->name + 2);
+ return;
+ }
if (GS(tsep->id->name) == ID_GR) {
Collection *parent = (Collection *)tsep->id;
BKE_collection_object_remove(bmain, parent, ob, true);
@@ -419,13 +435,13 @@ static void unlink_object_fn(bContext *C,
}
}
-static void unlink_world_fn(bContext *UNUSED(C),
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
+static void unlink_world_fn(bContext * /*C*/,
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
+ TreeElement * /*te*/,
TreeStoreElem *tsep,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
Scene *parscene = (Scene *)tsep->id;
World *wo = (World *)tselem->id;
@@ -584,7 +600,7 @@ static bool outliner_do_scene_operation(
static bool scene_fn(bContext *C,
eOutliner_PropSceneOps event,
- TreeElement *UNUSED(te),
+ TreeElement * /*te*/,
TreeStoreElem *tselem)
{
Scene *scene = (Scene *)tselem->id;
@@ -684,11 +700,11 @@ static void merged_element_search_fn_recursive(
}
/* Get a list of elements that match the search string */
-static void merged_element_search_update_fn(const bContext *UNUSED(C),
+static void merged_element_search_update_fn(const bContext * /*C*/,
void *data,
const char *str,
uiSearchItems *items,
- const bool UNUSED(is_first))
+ const bool /*is_first*/)
{
MergedSearchData *search_data = (MergedSearchData *)data;
TreeElement *parent = search_data->parent_element;
@@ -700,7 +716,7 @@ static void merged_element_search_update_fn(const bContext *UNUSED(C),
}
/* Activate an element from the merged element search menu */
-static void merged_element_search_exec_fn(struct bContext *C, void *UNUSED(arg1), void *element)
+static void merged_element_search_exec_fn(struct bContext *C, void * /*arg1*/, void *element)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
TreeElement *te = (TreeElement *)element;
@@ -775,15 +791,17 @@ void merged_element_search_menu_invoke(bContext *C,
}
static void object_select_fn(bContext *C,
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep),
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
+ TreeElement * /*te*/,
+ TreeStoreElem * /*tsep*/,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = (Object *)tselem->id;
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob);
if (base) {
@@ -798,12 +816,12 @@ static void object_select_fn(bContext *C,
* \{ */
static void object_select_hierarchy_fn(bContext *C,
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
TreeElement *te,
- TreeStoreElem *UNUSED(tsep),
- TreeStoreElem *UNUSED(tselem),
- void *UNUSED(user_data))
+ TreeStoreElem * /*tsep*/,
+ TreeStoreElem * /*tselem*/,
+ void * /*user_data*/)
{
/* Don't extend because this toggles, which is nice for Ctrl-Click but not for a menu item.
* it's especially confusing when multiple items are selected since some toggle on/off. */
@@ -813,15 +831,17 @@ static void object_select_hierarchy_fn(bContext *C,
}
static void object_deselect_fn(bContext *C,
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep),
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
+ TreeElement * /*te*/,
+ TreeStoreElem * /*tsep*/,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = (Object *)tselem->id;
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob);
if (base) {
@@ -858,12 +878,12 @@ static void outliner_object_delete_fn(bContext *C, ReportList *reports, Scene *s
}
static void id_local_fn(bContext *C,
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep),
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
+ TreeElement * /*te*/,
+ TreeStoreElem * /*tsep*/,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
if (ID_IS_LINKED(tselem->id) && (tselem->id->tag & LIB_TAG_EXTERN)) {
Main *bmain = CTX_data_main(C);
@@ -956,7 +976,7 @@ struct OutlinerLibOverrideData {
* hierarchy. */
static void id_override_library_create_hierarchy_pre_process_fn(bContext *C,
ReportList *reports,
- Scene *UNUSED(scene),
+ Scene * /*scene*/,
TreeElement *te,
TreeStoreElem *tsep,
TreeStoreElem *tselem,
@@ -1209,7 +1229,7 @@ static void id_override_library_create_hierarchy(
/* Remove the instance empty from this scene, the items now have an overridden collection
* instead. */
if (success && data_idroot.is_override_instancing_object) {
- BLI_assert(GS(data_idroot.id_instance_hint) == ID_OB);
+ BLI_assert(GS(data_idroot.id_instance_hint->name) == ID_OB);
ED_object_base_free_and_unlink(
&bmain, scene, reinterpret_cast<Object *>(data_idroot.id_instance_hint));
}
@@ -1263,10 +1283,10 @@ static void id_override_library_create_hierarchy_process(bContext *C,
}
static void id_override_library_reset_fn(bContext *C,
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep),
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
+ TreeElement * /*te*/,
+ TreeStoreElem * /*tsep*/,
TreeStoreElem *tselem,
void *user_data)
{
@@ -1293,10 +1313,10 @@ static void id_override_library_reset_fn(bContext *C,
static void id_override_library_clear_single_fn(bContext *C,
ReportList *reports,
Scene *scene,
- TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep),
+ TreeElement * /*te*/,
+ TreeStoreElem * /*tsep*/,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
BLI_assert(TSE_IS_REAL_ID(tselem));
Main *bmain = CTX_data_main(C);
@@ -1317,6 +1337,7 @@ static void id_override_library_clear_single_fn(bContext *C,
* override. */
if (BKE_lib_override_library_is_hierarchy_leaf(bmain, id)) {
bool do_remap_active = false;
+ BKE_view_layer_synced_ensure(CTX_data_scene(C), view_layer);
if (BKE_view_layer_active_object_get(view_layer) == reinterpret_cast<Object *>(id)) {
BLI_assert(GS(id->name) == ID_OB);
do_remap_active = true;
@@ -1339,11 +1360,11 @@ static void id_override_library_clear_single_fn(bContext *C,
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE);
}
-static void id_override_library_resync_fn(bContext *UNUSED(C),
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep),
+static void id_override_library_resync_fn(bContext * /*C*/,
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
+ TreeElement * /*te*/,
+ TreeStoreElem * /*tsep*/,
TreeStoreElem *tselem,
void *user_data)
{
@@ -1388,11 +1409,11 @@ static void id_override_library_resync_hierarchy_process(bContext *C,
WM_event_add_notifier(C, NC_WINDOW, nullptr);
}
-static void id_override_library_delete_hierarchy_fn(bContext *UNUSED(C),
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep),
+static void id_override_library_delete_hierarchy_fn(bContext * /*C*/,
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
+ TreeElement * /*te*/,
+ TreeStoreElem * /*tsep*/,
TreeStoreElem *tselem,
void *user_data)
{
@@ -1415,7 +1436,7 @@ static void id_override_library_delete_hierarchy_fn(bContext *UNUSED(C),
/* Clear (delete) a hierarchy of library overrides. */
static void id_override_library_delete_hierarchy_process(bContext *C,
- ReportList *UNUSED(reports),
+ ReportList * /*reports*/,
OutlinerLibOverrideData &data)
{
Main *bmain = CTX_data_main(C);
@@ -1425,26 +1446,26 @@ static void id_override_library_delete_hierarchy_process(bContext *C,
}
}
-static void id_fake_user_set_fn(bContext *UNUSED(C),
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep),
+static void id_fake_user_set_fn(bContext * /*C*/,
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
+ TreeElement * /*te*/,
+ TreeStoreElem * /*tsep*/,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
ID *id = tselem->id;
id_fake_user_set(id);
}
-static void id_fake_user_clear_fn(bContext *UNUSED(C),
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep),
+static void id_fake_user_clear_fn(bContext * /*C*/,
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
+ TreeElement * /*te*/,
+ TreeStoreElem * /*tsep*/,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
ID *id = tselem->id;
@@ -1452,12 +1473,12 @@ static void id_fake_user_clear_fn(bContext *UNUSED(C),
}
static void id_select_linked_fn(bContext *C,
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep),
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
+ TreeElement * /*te*/,
+ TreeStoreElem * /*tsep*/,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
ID *id = tselem->id;
@@ -1465,12 +1486,12 @@ static void id_select_linked_fn(bContext *C,
}
static void singleuser_action_fn(bContext *C,
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
TreeElement *te,
TreeStoreElem *tsep,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
/* This callback runs for all selected elements, some of which may not be actions which results
* in a crash. */
@@ -1493,12 +1514,12 @@ static void singleuser_action_fn(bContext *C,
}
static void singleuser_world_fn(bContext *C,
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
+ ReportList * /*reports*/,
+ Scene * /*scene*/,
+ TreeElement * /*te*/,
TreeStoreElem *tsep,
TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ void * /*user_data*/)
{
ID *id = tselem->id;
@@ -1574,29 +1595,29 @@ void outliner_do_object_operation(bContext *C,
/** \name Internal Tagging Utilities
* \{ */
-static void clear_animdata_fn(int UNUSED(event),
- TreeElement *UNUSED(te),
+static void clear_animdata_fn(int /*event*/,
+ TreeElement * /*te*/,
TreeStoreElem *tselem,
- void *UNUSED(arg))
+ void * /*arg*/)
{
BKE_animdata_free(tselem->id, true);
DEG_id_tag_update(tselem->id, ID_RECALC_ANIMATION);
}
-static void unlinkact_animdata_fn(int UNUSED(event),
- TreeElement *UNUSED(te),
+static void unlinkact_animdata_fn(int /*event*/,
+ TreeElement * /*te*/,
TreeStoreElem *tselem,
- void *UNUSED(arg))
+ void * /*arg*/)
{
/* just set action to nullptr */
BKE_animdata_set_action(nullptr, tselem->id, nullptr);
DEG_id_tag_update(tselem->id, ID_RECALC_ANIMATION);
}
-static void cleardrivers_animdata_fn(int UNUSED(event),
- TreeElement *UNUSED(te),
+static void cleardrivers_animdata_fn(int /*event*/,
+ TreeElement * /*te*/,
TreeStoreElem *tselem,
- void *UNUSED(arg))
+ void * /*arg*/)
{
IdAdtTemplate *iat = (IdAdtTemplate *)tselem->id;
@@ -1605,10 +1626,10 @@ static void cleardrivers_animdata_fn(int UNUSED(event),
DEG_id_tag_update(tselem->id, ID_RECALC_ANIMATION);
}
-static void refreshdrivers_animdata_fn(int UNUSED(event),
- TreeElement *UNUSED(te),
+static void refreshdrivers_animdata_fn(int /*event*/,
+ TreeElement * /*te*/,
TreeStoreElem *tselem,
- void *UNUSED(arg))
+ void * /*arg*/)
{
IdAdtTemplate *iat = (IdAdtTemplate *)tselem->id;
@@ -1794,7 +1815,7 @@ static int outliner_liboverride_operation_exec(bContext *C, wmOperator *op)
space_outliner,
id_override_library_delete_hierarchy_fn,
OUTLINER_LIB_SELECTIONSET_SELECTED,
- nullptr);
+ &override_data);
id_override_library_delete_hierarchy_process(C, op->reports, override_data);
@@ -1890,7 +1911,7 @@ enum eOutliner_PropModifierOps {
OL_MODIFIER_OP_DELETE,
};
-static void pchan_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
+static void pchan_fn(int event, TreeElement *te, TreeStoreElem * /*tselem*/, void * /*arg*/)
{
bPoseChannel *pchan = (bPoseChannel *)te->directdata;
@@ -1909,7 +1930,7 @@ static void pchan_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem),
}
}
-static void bone_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
+static void bone_fn(int event, TreeElement *te, TreeStoreElem * /*tselem*/, void * /*arg*/)
{
Bone *bone = (Bone *)te->directdata;
@@ -1928,7 +1949,7 @@ static void bone_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), v
}
}
-static void ebone_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
+static void ebone_fn(int event, TreeElement *te, TreeStoreElem * /*tselem*/, void * /*arg*/)
{
EditBone *ebone = (EditBone *)te->directdata;
@@ -1947,7 +1968,7 @@ static void ebone_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem),
}
}
-static void sequence_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *scene_ptr)
+static void sequence_fn(int event, TreeElement *te, TreeStoreElem * /*tselem*/, void *scene_ptr)
{
TreeElementSequence *te_seq = tree_element_cast<TreeElementSequence>(te);
Sequence *seq = &te_seq->getSequence();
@@ -1977,8 +1998,8 @@ static void sequence_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem
static void gpencil_layer_fn(int event,
TreeElement *te,
- TreeStoreElem *UNUSED(tselem),
- void *UNUSED(arg))
+ TreeStoreElem * /*tselem*/,
+ void * /*arg*/)
{
bGPDlayer *gpl = (bGPDlayer *)te->directdata;
@@ -1998,7 +2019,7 @@ static void gpencil_layer_fn(int event,
static void data_select_linked_fn(int event,
TreeElement *te,
- TreeStoreElem *UNUSED(tselem),
+ TreeStoreElem * /*tselem*/,
void *C_v)
{
const TreeElementRNAStruct *te_rna_struct = tree_element_cast<TreeElementRNAStruct>(te);
@@ -2017,7 +2038,7 @@ static void data_select_linked_fn(int event,
}
}
-static void constraint_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *C_v)
+static void constraint_fn(int event, TreeElement *te, TreeStoreElem * /*tselem*/, void *C_v)
{
bContext *C = static_cast<bContext *>(C_v);
Main *bmain = CTX_data_main(C);
@@ -2057,7 +2078,7 @@ static void constraint_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tsel
}
}
-static void modifier_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *Carg)
+static void modifier_fn(int event, TreeElement *te, TreeStoreElem * /*tselem*/, void *Carg)
{
bContext *C = (bContext *)Carg;
Main *bmain = CTX_data_main(C);
@@ -2108,9 +2129,10 @@ static Base *outliner_batch_delete_hierarchy(
if (!base) {
return nullptr;
}
-
+ BKE_view_layer_synced_ensure(scene, view_layer);
object = base->object;
- for (child_base = static_cast<Base *>(view_layer->object_bases.first); child_base;
+ for (child_base = static_cast<Base *>(BKE_view_layer_object_bases_get(view_layer)->first);
+ child_base;
child_base = base_next) {
base_next = child_base->next;
for (parent = child_base->object->parent; parent && (parent != object);
@@ -2160,6 +2182,7 @@ static void object_batch_delete_hierarchy_fn(bContext *C,
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *obedit = CTX_data_edit_object(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob);
if (base) {
@@ -2348,7 +2371,7 @@ static TreeTraversalAction outliner_collect_objects_to_delete(TreeElement *te, v
/* Do not allow to delete children objects of an override collection. */
TreeElement *te_parent = te->parent;
- if (outliner_is_collection_tree_element(te_parent)) {
+ if (te_parent != nullptr && outliner_is_collection_tree_element(te_parent)) {
TreeStoreElem *tselem_parent = TREESTORE(te_parent);
ID *id_parent = tselem_parent->id;
BLI_assert(GS(id_parent->name) == ID_GR);
@@ -2384,7 +2407,8 @@ static int outliner_delete_exec(bContext *C, wmOperator *op)
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
struct wmMsgBus *mbus = CTX_wm_message_bus(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- const Base *basact_prev = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ const Base *basact_prev = BKE_view_layer_active_base_get(view_layer);
const bool delete_hierarchy = RNA_boolean_get(op->ptr, "hierarchy");
@@ -2428,7 +2452,8 @@ static int outliner_delete_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
DEG_relations_tag_update(bmain);
- if (basact_prev != view_layer->basact) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ if (basact_prev != BKE_view_layer_active_base_get(view_layer)) {
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, LayerObjects, active);
}
@@ -2514,8 +2539,8 @@ static const EnumPropertyItem prop_id_op_types[] = {
};
static bool outliner_id_operation_item_poll(bContext *C,
- PointerRNA *UNUSED(ptr),
- PropertyRNA *UNUSED(prop),
+ PointerRNA * /*ptr*/,
+ PropertyRNA * /*prop*/,
const int enum_value)
{
if (!outliner_operation_tree_element_poll(C)) {
@@ -2882,7 +2907,7 @@ static void outliner_do_id_set_operation(
});
}
-static void actionset_id_fn(TreeElement *UNUSED(te),
+static void actionset_id_fn(TreeElement * /*te*/,
TreeStoreElem *tselem,
TreeStoreElem *tsep,
ID *actId)
@@ -3265,9 +3290,9 @@ static int outliner_data_operation_exec(bContext *C, wmOperator *op)
/* Dynamically populate an enum of Keying Sets */
static const EnumPropertyItem *outliner_data_op_sets_enum_item_fn(bContext *C,
- PointerRNA *UNUSED(ptr),
- PropertyRNA *UNUSED(prop),
- bool *UNUSED(r_free))
+ PointerRNA * /*ptr*/,
+ PropertyRNA * /*prop*/,
+ bool * /*r_free*/)
{
/* Check for invalid states. */
if (C == nullptr) {
@@ -3424,7 +3449,7 @@ static int do_outliner_operation_event(bContext *C,
return OPERATOR_CANCELLED;
}
-static int outliner_operation(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+static int outliner_operation(bContext *C, wmOperator * /*op*/, const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
diff --git a/source/blender/editors/space_outliner/outliner_tree.cc b/source/blender/editors/space_outliner/outliner_tree.cc
index a8f469c135a..235dc3afa5f 100644
--- a/source/blender/editors/space_outliner/outliner_tree.cc
+++ b/source/blender/editors/space_outliner/outliner_tree.cc
@@ -1395,7 +1395,8 @@ static int outliner_exclude_filter_get(const SpaceOutliner *space_outliner)
return exclude_filter;
}
-static bool outliner_element_visible_get(ViewLayer *view_layer,
+static bool outliner_element_visible_get(const Scene *scene,
+ ViewLayer *view_layer,
TreeElement *te,
const int exclude_filter)
{
@@ -1450,6 +1451,7 @@ static bool outliner_element_visible_get(ViewLayer *view_layer,
if (exclude_filter & SO_FILTER_OB_STATE) {
if (base == nullptr) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
base = BKE_view_layer_base_find(view_layer, ob);
if (base == nullptr) {
@@ -1475,7 +1477,8 @@ static bool outliner_element_visible_get(ViewLayer *view_layer,
}
else {
BLI_assert(exclude_filter & SO_FILTER_OB_STATE_ACTIVE);
- if (base != view_layer->basact) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ if (base != BKE_view_layer_active_base_get(view_layer)) {
is_visible = false;
}
}
@@ -1557,6 +1560,7 @@ static TreeElement *outliner_extract_children_from_subtree(TreeElement *element,
}
static int outliner_filter_subtree(SpaceOutliner *space_outliner,
+ const Scene *scene,
ViewLayer *view_layer,
ListBase *lb,
const char *search_string,
@@ -1567,18 +1571,18 @@ static int outliner_filter_subtree(SpaceOutliner *space_outliner,
for (te = static_cast<TreeElement *>(lb->first); te; te = te_next) {
te_next = te->next;
- if ((outliner_element_visible_get(view_layer, te, exclude_filter) == false)) {
+ if (outliner_element_visible_get(scene, view_layer, te, exclude_filter) == false) {
/* Don't free the tree, but extract the children from the parent and add to this tree. */
/* This also needs filtering the subtree prior (see T69246). */
outliner_filter_subtree(
- space_outliner, view_layer, &te->subtree, search_string, exclude_filter);
+ space_outliner, scene, view_layer, &te->subtree, search_string, exclude_filter);
te_next = outliner_extract_children_from_subtree(te, lb);
continue;
}
if ((exclude_filter & SO_FILTER_SEARCH) == 0) {
/* Filter subtree too. */
outliner_filter_subtree(
- space_outliner, view_layer, &te->subtree, search_string, exclude_filter);
+ space_outliner, scene, view_layer, &te->subtree, search_string, exclude_filter);
continue;
}
@@ -1594,9 +1598,10 @@ static int outliner_filter_subtree(SpaceOutliner *space_outliner,
/* flag as not a found item */
tselem->flag &= ~TSE_SEARCHMATCH;
- if ((!TSELEM_OPEN(tselem, space_outliner)) ||
+ if (!TSELEM_OPEN(tselem, space_outliner) ||
outliner_filter_subtree(
- space_outliner, view_layer, &te->subtree, search_string, exclude_filter) == 0) {
+ space_outliner, scene, view_layer, &te->subtree, search_string, exclude_filter) ==
+ 0) {
outliner_free_tree_element(te, lb);
}
}
@@ -1608,7 +1613,7 @@ static int outliner_filter_subtree(SpaceOutliner *space_outliner,
/* filter subtree too */
outliner_filter_subtree(
- space_outliner, view_layer, &te->subtree, search_string, exclude_filter);
+ space_outliner, scene, view_layer, &te->subtree, search_string, exclude_filter);
}
}
@@ -1616,7 +1621,9 @@ static int outliner_filter_subtree(SpaceOutliner *space_outliner,
return (BLI_listbase_is_empty(lb) == false);
}
-static void outliner_filter_tree(SpaceOutliner *space_outliner, ViewLayer *view_layer)
+static void outliner_filter_tree(SpaceOutliner *space_outliner,
+ const Scene *scene,
+ ViewLayer *view_layer)
{
char search_buff[sizeof(((struct SpaceOutliner *)nullptr)->search_string) + 2];
char *search_string;
@@ -1637,7 +1644,7 @@ static void outliner_filter_tree(SpaceOutliner *space_outliner, ViewLayer *view_
}
outliner_filter_subtree(
- space_outliner, view_layer, &space_outliner->tree, search_string, exclude_filter);
+ space_outliner, scene, view_layer, &space_outliner->tree, search_string, exclude_filter);
}
static void outliner_clear_newid_from_main(Main *bmain)
@@ -1714,7 +1721,7 @@ void outliner_build_tree(Main *mainvar,
outliner_collections_children_sort(&space_outliner->tree);
}
- outliner_filter_tree(space_outliner, view_layer);
+ outliner_filter_tree(space_outliner, scene, view_layer);
outliner_restore_scrolling_position(space_outliner, region, &focus);
/* `ID.newid` pointer is abused when building tree, DO NOT call #BKE_main_id_newptr_and_tag_clear
diff --git a/source/blender/editors/space_outliner/outliner_utils.cc b/source/blender/editors/space_outliner/outliner_utils.cc
index ff5292e2883..2deedccc29e 100644
--- a/source/blender/editors/space_outliner/outliner_utils.cc
+++ b/source/blender/editors/space_outliner/outliner_utils.cc
@@ -45,6 +45,7 @@ void outliner_viewcontext_init(const bContext *C, TreeViewContext *tvc)
tvc->view_layer = CTX_data_view_layer(C);
/* Objects. */
+ BKE_view_layer_synced_ensure(tvc->scene, tvc->view_layer);
tvc->obact = BKE_view_layer_active_object_get(tvc->view_layer);
if (tvc->obact != nullptr) {
tvc->ob_edit = OBEDIT_FROM_OBACT(tvc->obact);
@@ -452,6 +453,7 @@ using namespace blender::ed::outliner;
Base *ED_outliner_give_base_under_cursor(bContext *C, const int mval[2])
{
ARegion *region = CTX_wm_region(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
TreeElement *te;
@@ -465,6 +467,7 @@ Base *ED_outliner_give_base_under_cursor(bContext *C, const int mval[2])
TreeStoreElem *tselem = TREESTORE(te);
if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) {
Object *ob = (Object *)tselem->id;
+ BKE_view_layer_synced_ensure(scene, view_layer);
base = (te->directdata) ? (Base *)te->directdata : BKE_view_layer_base_find(view_layer, ob);
}
}
diff --git a/source/blender/editors/space_outliner/space_outliner.cc b/source/blender/editors/space_outliner/space_outliner.cc
index 365bcae3f5d..af2da7fa872 100644
--- a/source/blender/editors/space_outliner/space_outliner.cc
+++ b/source/blender/editors/space_outliner/space_outliner.cc
@@ -5,6 +5,9 @@
* \ingroup spoutliner
*/
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include <cstdio>
#include <cstring>
@@ -34,6 +37,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "BLO_read_write.h"
+
#include "outliner_intern.hh"
#include "tree/tree_display.hh"
@@ -87,7 +92,7 @@ static void outliner_main_region_draw(const bContext *C, ARegion *region)
UI_view2d_scrollers_draw(v2d, nullptr);
}
-static void outliner_main_region_free(ARegion *UNUSED(region))
+static void outliner_main_region_free(ARegion * /*region*/)
{
}
@@ -251,6 +256,12 @@ static void outliner_main_region_listener(const wmRegionListenerParams *params)
ED_region_tag_redraw(region);
}
break;
+ case NC_NODE:
+ if (ELEM(wmn->action, NA_ADDED, NA_REMOVED) &&
+ ELEM(space_outliner->outlinevis, SO_LIBRARIES, SO_DATA_API)) {
+ ED_region_tag_redraw(region);
+ }
+ break;
}
}
@@ -274,7 +285,7 @@ static void outliner_main_region_message_subscribe(const wmRegionMessageSubscrib
/* ************************ header outliner area region *********************** */
/* add handlers, stuff you only do once or on area/region changes */
-static void outliner_header_region_init(wmWindowManager *UNUSED(wm), ARegion *region)
+static void outliner_header_region_init(wmWindowManager * /*wm*/, ARegion *region)
{
ED_region_header_init(region);
}
@@ -284,7 +295,7 @@ static void outliner_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void outliner_header_region_free(ARegion *UNUSED(region))
+static void outliner_header_region_free(ARegion * /*region*/)
{
}
@@ -310,7 +321,7 @@ static void outliner_header_region_listener(const wmRegionListenerParams *params
/* ******************** default callbacks for outliner space ***************** */
-static SpaceLink *outliner_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *outliner_create(const ScrArea * /*area*/, const Scene * /*scene*/)
{
ARegion *region;
SpaceOutliner *space_outliner;
@@ -354,7 +365,7 @@ static void outliner_free(SpaceLink *sl)
}
/* spacetype; init callback */
-static void outliner_init(wmWindowManager *UNUSED(wm), ScrArea *area)
+static void outliner_init(wmWindowManager * /*wm*/, ScrArea *area)
{
SpaceOutliner *space_outliner = static_cast<SpaceOutliner *>(area->spacedata.first);
@@ -435,6 +446,115 @@ static void outliner_deactivate(struct ScrArea *area)
ED_region_tag_redraw_no_rebuild(BKE_area_find_region_type(area, RGN_TYPE_WINDOW));
}
+static void outliner_blend_read_data(BlendDataReader *reader, SpaceLink *sl)
+{
+ SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
+
+ /* use #BLO_read_get_new_data_address_no_us and do not free old memory avoiding double
+ * frees and use of freed memory. this could happen because of a
+ * bug fixed in revision 58959 where the treestore memory address
+ * was not unique */
+ TreeStore *ts = static_cast<TreeStore *>(
+ BLO_read_get_new_data_address_no_us(reader, space_outliner->treestore));
+ space_outliner->treestore = nullptr;
+ if (ts) {
+ TreeStoreElem *elems = static_cast<TreeStoreElem *>(
+ BLO_read_get_new_data_address_no_us(reader, ts->data));
+
+ space_outliner->treestore = BLI_mempool_create(
+ sizeof(TreeStoreElem), ts->usedelem, 512, BLI_MEMPOOL_ALLOW_ITER);
+ if (ts->usedelem && elems) {
+ for (int i = 0; i < ts->usedelem; i++) {
+ TreeStoreElem *new_elem = static_cast<TreeStoreElem *>(
+ BLI_mempool_alloc(space_outliner->treestore));
+ *new_elem = elems[i];
+ }
+ }
+ /* we only saved what was used */
+ space_outliner->storeflag |= SO_TREESTORE_CLEANUP; /* at first draw */
+ }
+ space_outliner->tree.first = space_outliner->tree.last = nullptr;
+ space_outliner->runtime = nullptr;
+}
+
+static void outliner_blend_read_lib(BlendLibReader *reader, ID * /*parent_id*/, SpaceLink *sl)
+{
+ SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
+
+ if (space_outliner->treestore) {
+ TreeStoreElem *tselem;
+ BLI_mempool_iter iter;
+
+ BLI_mempool_iternew(space_outliner->treestore, &iter);
+ while ((tselem = static_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) {
+ BLO_read_id_address(reader, nullptr, &tselem->id);
+ }
+ /* rebuild hash table, because it depends on ids too */
+ space_outliner->storeflag |= SO_TREESTORE_REBUILD;
+ }
+}
+
+static void write_space_outliner(BlendWriter *writer, const SpaceOutliner *space_outliner)
+{
+ BLI_mempool *ts = space_outliner->treestore;
+
+ if (ts) {
+ const int elems = BLI_mempool_len(ts);
+ /* linearize mempool to array */
+ TreeStoreElem *data = elems ? static_cast<TreeStoreElem *>(
+ BLI_mempool_as_arrayN(ts, "TreeStoreElem")) :
+ nullptr;
+
+ if (data) {
+ BLO_write_struct(writer, SpaceOutliner, space_outliner);
+
+ /* To store #TreeStore (instead of the mempool), two unique memory addresses are needed,
+ * which can be used to identify the data on read:
+ * 1) One for the #TreeStore data itself.
+ * 2) One for the array of #TreeStoreElem's inside #TreeStore (#TreeStore.data).
+ *
+ * For 1) we just use the mempool's address (#SpaceOutliner::treestore).
+ * For 2) we don't have such a direct choice. We can't just use the array's address from
+ * above, since that may not be unique over all Outliners. So instead use an address relative
+ * to 1).
+ */
+ /* TODO the mempool could be moved to #SpaceOutliner_Runtime so that #SpaceOutliner could
+ * hold the #TreeStore directly. */
+
+ /* Address relative to the tree-store, as noted above. */
+ void *data_addr = (void *)POINTER_OFFSET(ts, sizeof(void *));
+ /* There should be plenty of memory addresses within the mempool data that we can point into,
+ * just double-check we don't potentially end up with a memory address that another DNA
+ * struct might use. Assumes BLI_mempool uses the guarded allocator. */
+ BLI_assert(MEM_allocN_len(ts) >= sizeof(void *) * 2);
+
+ TreeStore ts_flat = {0};
+ ts_flat.usedelem = elems;
+ ts_flat.totelem = elems;
+ ts_flat.data = static_cast<TreeStoreElem *>(data_addr);
+
+ BLO_write_struct_at_address(writer, TreeStore, ts, &ts_flat);
+ BLO_write_struct_array_at_address(writer, TreeStoreElem, elems, data_addr, data);
+
+ MEM_freeN(data);
+ }
+ else {
+ SpaceOutliner space_outliner_flat = *space_outliner;
+ space_outliner_flat.treestore = nullptr;
+ BLO_write_struct_at_address(writer, SpaceOutliner, space_outliner, &space_outliner_flat);
+ }
+ }
+ else {
+ BLO_write_struct(writer, SpaceOutliner, space_outliner);
+ }
+}
+
+static void outliner_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
+ write_space_outliner(writer, space_outliner);
+}
+
} // namespace blender::ed::outliner
void ED_spacetype_outliner(void)
@@ -457,6 +577,9 @@ void ED_spacetype_outliner(void)
st->id_remap = outliner_id_remap;
st->deactivate = outliner_deactivate;
st->context = outliner_context;
+ st->blend_read_data = outliner_blend_read_data;
+ st->blend_read_lib = outliner_blend_read_lib;
+ st->blend_write = outliner_blend_write;
/* regions: main window */
art = MEM_cnew<ARegionType>("spacetype outliner region");
diff --git a/source/blender/editors/space_outliner/tree/tree_display.hh b/source/blender/editors/space_outliner/tree/tree_display.hh
index 295eeb59eaa..13b46651562 100644
--- a/source/blender/editors/space_outliner/tree/tree_display.hh
+++ b/source/blender/editors/space_outliner/tree/tree_display.hh
@@ -105,6 +105,7 @@ class AbstractTreeDisplay {
* \brief Tree-Display for the View Layer display mode.
*/
class TreeDisplayViewLayer final : public AbstractTreeDisplay {
+ Scene *scene_ = nullptr;
ViewLayer *view_layer_ = nullptr;
bool show_objects_ = true;
diff --git a/source/blender/editors/space_outliner/tree/tree_display_override_library_hierarchies.cc b/source/blender/editors/space_outliner/tree/tree_display_override_library_hierarchies.cc
index fa4479d0d9d..2150d2b211a 100644
--- a/source/blender/editors/space_outliner/tree/tree_display_override_library_hierarchies.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display_override_library_hierarchies.cc
@@ -324,7 +324,7 @@ static bool id_is_in_override_hierarchy(const Main &bmain,
if (ID_IS_OVERRIDE_LIBRARY_VIRTUAL(&id)) {
/* In many cases, `relationship_parent_id` is the owner, but not always (e.g. there can be
- * drivers directly between an object and a shapekey). */
+ * drivers directly between an object and a shape-key). */
BKE_lib_override_library_get(const_cast<Main *>(&bmain),
const_cast<ID *>(&id),
const_cast<ID *>(&relationship_parent_id),
diff --git a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc
index c8869d90eca..66c1fa34914 100644
--- a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc
@@ -64,6 +64,7 @@ ListBase TreeDisplayViewLayer::buildTree(const TreeSourceData &source_data)
{
ListBase tree = {nullptr};
Scene *scene = source_data.scene;
+ scene_ = scene;
show_objects_ = !(space_outliner_.filter & SO_FILTER_NO_OBJECT);
for (auto *view_layer : ListBaseWrapper<ViewLayer>(scene->view_layers)) {
@@ -96,7 +97,8 @@ void TreeDisplayViewLayer::add_view_layer(Scene &scene, ListBase &tree, TreeElem
if (space_outliner_.filter & SO_FILTER_NO_COLLECTION) {
/* Show objects in the view layer. */
- for (Base *base : List<Base>(view_layer_->object_bases)) {
+ BKE_view_layer_synced_ensure(&scene, view_layer_);
+ for (Base *base : List<Base>(*BKE_view_layer_object_bases_get(view_layer_))) {
TreeElement *te_object = outliner_add_element(
&space_outliner_, &tree, base->object, parent, TSE_SOME_ID, 0);
te_object->directdata = base;
@@ -166,6 +168,7 @@ void TreeDisplayViewLayer::add_layer_collection_objects(ListBase &tree,
LayerCollection &lc,
TreeElement &ten)
{
+ BKE_view_layer_synced_ensure(scene_, view_layer_);
for (CollectionObject *cob : List<CollectionObject>(lc.collection->gobject)) {
Base *base = BKE_view_layer_base_find(view_layer_, cob->ob);
TreeElement *te_object = outliner_add_element(
diff --git a/source/blender/editors/space_outliner/tree/tree_element_rna.cc b/source/blender/editors/space_outliner/tree/tree_element_rna.cc
index 9e1f22b49d6..275b4391d24 100644
--- a/source/blender/editors/space_outliner/tree/tree_element_rna.cc
+++ b/source/blender/editors/space_outliner/tree/tree_element_rna.cc
@@ -52,7 +52,7 @@ bool TreeElementRNACommon::isRNAValid() const
return rna_ptr_.data != nullptr;
}
-bool TreeElementRNACommon::expandPoll(const SpaceOutliner &UNUSED(space_outliner)) const
+bool TreeElementRNACommon::expandPoll(const SpaceOutliner & /*space_outliner*/) const
{
return isRNAValid();
}
@@ -232,12 +232,13 @@ TreeElementRNAArrayElement::TreeElementRNAArrayElement(TreeElement &legacy_te,
char c = RNA_property_array_item_char(TreeElementRNAArrayElement::getPropertyRNA(), index);
- legacy_te_.name = static_cast<char *>(MEM_callocN(sizeof(char[20]), "OutlinerRNAArrayName"));
+ const size_t name_size = sizeof(char[20]);
+ legacy_te_.name = static_cast<char *>(MEM_callocN(name_size, "OutlinerRNAArrayName"));
if (c) {
- sprintf((char *)legacy_te_.name, " %c", c);
+ BLI_snprintf((char *)legacy_te_.name, name_size, " %c", c);
}
else {
- sprintf((char *)legacy_te_.name, " %d", index + 1);
+ BLI_snprintf((char *)legacy_te_.name, name_size, " %d", index + 1);
}
legacy_te_.flag |= TE_FREE_NAME;
}
diff --git a/source/blender/editors/space_script/CMakeLists.txt b/source/blender/editors/space_script/CMakeLists.txt
index f7fc4e38c17..8902703b6ea 100644
--- a/source/blender/editors/space_script/CMakeLists.txt
+++ b/source/blender/editors/space_script/CMakeLists.txt
@@ -4,11 +4,15 @@ set(INC
../include
../../blenkernel
../../blenlib
+ ../../blenloader
../../gpu
../../makesdna
../../makesrna
../../windowmanager
../../../../intern/guardedalloc
+
+ # dna_type_offsets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
)
@@ -32,3 +36,6 @@ endif()
blender_add_lib(bf_editor_space_script "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
+
+# dna_type_offsets.h
+add_dependencies(bf_editor_space_script bf_dna)
diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c
index c35b1e00184..4495501efe9 100644
--- a/source/blender/editors/space_script/space_script.c
+++ b/source/blender/editors/space_script/space_script.c
@@ -24,6 +24,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "BLO_read_write.h"
+
#ifdef WITH_PYTHON
#endif
@@ -146,6 +148,25 @@ static void script_main_region_listener(const wmRegionListenerParams *UNUSED(par
#endif
}
+static void script_blend_read_lib(BlendLibReader *reader, ID *parent_id, SpaceLink *sl)
+{
+ SpaceScript *scpt = (SpaceScript *)sl;
+ /*scpt->script = NULL; - 2.45 set to null, better re-run the script */
+ if (scpt->script) {
+ BLO_read_id_address(reader, parent_id->lib, &scpt->script);
+ if (scpt->script) {
+ SCRIPT_SET_NULL(scpt->script);
+ }
+ }
+}
+
+static void script_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ SpaceScript *scr = (SpaceScript *)sl;
+ scr->but_refs = NULL;
+ BLO_write_struct(writer, SpaceScript, sl);
+}
+
void ED_spacetype_script(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype script");
@@ -160,6 +181,8 @@ void ED_spacetype_script(void)
st->duplicate = script_duplicate;
st->operatortypes = script_operatortypes;
st->keymap = script_keymap;
+ st->blend_read_lib = script_blend_read_lib;
+ st->blend_write = script_blend_write;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype script region");
diff --git a/source/blender/editors/space_sequencer/CMakeLists.txt b/source/blender/editors/space_sequencer/CMakeLists.txt
index deaec0136c4..5466beca255 100644
--- a/source/blender/editors/space_sequencer/CMakeLists.txt
+++ b/source/blender/editors/space_sequencer/CMakeLists.txt
@@ -5,6 +5,7 @@ set(INC
../../blenfont
../../blenkernel
../../blenlib
+ ../../blenloader
../../blentranslation
../../depsgraph
../../draw
@@ -16,6 +17,9 @@ set(INC
../../windowmanager
../../../../intern/atomic
../../../../intern/guardedalloc
+
+ # dna_type_offsets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
# RNA_prototypes.h
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
@@ -62,5 +66,5 @@ endif()
blender_add_lib(bf_editor_space_sequencer "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
-# RNA_prototypes.h
+# RNA_prototypes.h dna_type_offsets.h
add_dependencies(bf_editor_space_sequencer bf_rna)
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index dd6d58ee5a2..b17d0bfac4e 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -201,7 +201,7 @@ static int sequencer_generic_invoke_xy_guess_channel(bContext *C, int type)
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
const int strip_end = SEQ_time_right_handle_frame_get(scene, seq);
- if ((ELEM(type, -1, seq->type)) && (strip_end < timeline_frame) &&
+ if (ELEM(type, -1, seq->type) && (strip_end < timeline_frame) &&
(timeline_frame - strip_end < proximity)) {
tgt = seq;
proximity = timeline_frame - strip_end;
@@ -274,7 +274,7 @@ static void load_data_init_from_operator(SeqLoadData *load_data, bContext *C, wm
RNA_PROP_BEGIN (op->ptr, itemptr, prop) {
char *filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0, NULL);
BLI_strncpy(load_data->name, filename, sizeof(load_data->name));
- BLI_join_dirfile(load_data->path, sizeof(load_data->path), directory, filename);
+ BLI_path_join(load_data->path, sizeof(load_data->path), directory, filename);
MEM_freeN(filename);
break;
}
@@ -399,7 +399,7 @@ static bool seq_effect_add_properties_poll(const bContext *UNUSED(C),
return false;
}
}
- if ((type != SEQ_TYPE_COLOR) && (STREQ(prop_id, "color"))) {
+ if ((type != SEQ_TYPE_COLOR) && STREQ(prop_id, "color")) {
return false;
}
@@ -564,7 +564,7 @@ static const EnumPropertyItem *strip_new_sequencer_enum_itemf(bContext *C,
else {
Scene *scene = CTX_data_scene(C);
Sequence *seq = SEQ_select_active_get(scene);
- if ((seq && (seq->type == SEQ_TYPE_SCENE) && (seq->scene != NULL))) {
+ if (seq && (seq->type == SEQ_TYPE_SCENE) && (seq->scene != NULL)) {
has_scene_or_no_context = true;
}
}
@@ -747,7 +747,7 @@ static bool sequencer_add_draw_check_fn(PointerRNA *UNUSED(ptr),
{
const char *prop_id = RNA_property_identifier(prop);
- return !(STR_ELEM(prop_id, "filepath", "directory", "filename"));
+ return !STR_ELEM(prop_id, "filepath", "directory", "filename");
}
/* Strips are added in context of timeline which has different preview size than actual preview. We
@@ -834,7 +834,7 @@ static void sequencer_add_movie_multiple_strips(bContext *C,
char file_only[FILE_MAX];
RNA_string_get(op->ptr, "directory", dir_only);
RNA_string_get(&itemptr, "name", file_only);
- BLI_join_dirfile(load_data->path, sizeof(load_data->path), dir_only, file_only);
+ BLI_path_join(load_data->path, sizeof(load_data->path), dir_only, file_only);
BLI_strncpy(load_data->name, file_only, sizeof(load_data->name));
Sequence *seq_movie = NULL;
Sequence *seq_sound = NULL;
@@ -1082,7 +1082,7 @@ static void sequencer_add_sound_multiple_strips(bContext *C,
char file_only[FILE_MAX];
RNA_string_get(op->ptr, "directory", dir_only);
RNA_string_get(&itemptr, "name", file_only);
- BLI_join_dirfile(load_data->path, sizeof(load_data->path), dir_only, file_only);
+ BLI_path_join(load_data->path, sizeof(load_data->path), dir_only, file_only);
BLI_strncpy(load_data->name, file_only, sizeof(load_data->name));
Sequence *seq = SEQ_add_sound_strip(bmain, scene, ed->seqbasep, load_data);
if (seq == NULL) {
diff --git a/source/blender/editors/space_sequencer/sequencer_channels_draw.c b/source/blender/editors/space_sequencer/sequencer_channels_draw.c
index 81fc87598f8..901417c152f 100644
--- a/source/blender/editors/space_sequencer/sequencer_channels_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_channels_draw.c
@@ -78,7 +78,7 @@ static float icon_width_get(const SeqChannelDrawContext *context)
static float widget_y_offset(const SeqChannelDrawContext *context)
{
- return (((context->channel_height / context->scale) - icon_width_get(context))) / 2;
+ return ((context->channel_height / context->scale) - icon_width_get(context)) / 2;
}
static float channel_index_y_min(const SeqChannelDrawContext *context, const int index)
@@ -357,6 +357,10 @@ void draw_channels(const bContext *C, ARegion *region)
SeqChannelDrawContext context;
channel_draw_context_init(C, region, &context);
+ if (round_fl_to_int(context.channel_height) == 0) {
+ return;
+ }
+
UI_view2d_view_ortho(context.v2d);
draw_channel_headers(&context);
diff --git a/source/blender/editors/space_sequencer/sequencer_drag_drop.c b/source/blender/editors/space_sequencer/sequencer_drag_drop.c
index c892e7d7e55..d43ce26d2a1 100644
--- a/source/blender/editors/space_sequencer/sequencer_drag_drop.c
+++ b/source/blender/editors/space_sequencer/sequencer_drag_drop.c
@@ -505,8 +505,8 @@ typedef struct DropJobData {
} DropJobData;
static void prefetch_data_fn(void *custom_data,
- short *UNUSED(stop),
- short *UNUSED(do_update),
+ bool *UNUSED(stop),
+ bool *UNUSED(do_update),
float *UNUSED(progress))
{
DropJobData *job_data = (DropJobData *)custom_data;
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 71804d29e6b..3a2c62326de 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -804,7 +804,7 @@ static void draw_seq_text_get_source(Sequence *seq, char *r_source, size_t sourc
switch (seq->type) {
case SEQ_TYPE_IMAGE:
case SEQ_TYPE_MOVIE: {
- BLI_join_dirfile(r_source, source_len, seq->strip->dir, seq->strip->stripdata->name);
+ BLI_path_join(r_source, source_len, seq->strip->dir, seq->strip->stripdata->name);
break;
}
case SEQ_TYPE_SOUND_RAM: {
@@ -890,8 +890,7 @@ static size_t draw_seq_text_get_overlay_string(const Scene *scene,
BLI_assert(i <= ARRAY_SIZE(text_array));
- return BLI_string_join_array(r_overlay_string, overlay_string_len, text_array, i) -
- r_overlay_string;
+ return BLI_string_join_array(r_overlay_string, overlay_string_len, text_array, i);
}
/* Draw info text on a sequence strip. */
@@ -963,8 +962,7 @@ static void draw_sequence_extensions_overlay(
UI_GetColorPtrShade3ubv(col, blend_col, 10);
const float strip_content_start = SEQ_time_start_frame_get(seq);
- const float strip_content_end = SEQ_time_start_frame_get(seq) +
- SEQ_time_strip_length_get(scene, seq);
+ const float strip_content_end = SEQ_time_content_end_frame_get(scene, seq);
float right_handle_frame = SEQ_time_right_handle_frame_get(scene, seq);
float left_handle_frame = SEQ_time_left_handle_frame_get(scene, seq);
@@ -1095,8 +1093,7 @@ static void draw_seq_background(Scene *scene,
}
if (SEQ_time_has_right_still_frames(scene, seq)) {
float right_handle_frame = SEQ_time_right_handle_frame_get(scene, seq);
- const float content_end = SEQ_time_start_frame_get(seq) +
- SEQ_time_strip_length_get(scene, seq);
+ const float content_end = SEQ_time_content_end_frame_get(scene, seq);
immRectf(pos, content_end, y1, right_handle_frame, y2);
}
}
@@ -1198,7 +1195,7 @@ static void fcurve_batch_add_verts(GPUVertBuf *vbo,
float y_height,
int timeline_frame,
float curve_val,
- unsigned int *vert_count)
+ uint *vert_count)
{
float vert_pos[2][2];
@@ -1317,9 +1314,8 @@ static void draw_seq_strip(const bContext *C,
x1 = SEQ_time_has_left_still_frames(scene, seq) ? SEQ_time_start_frame_get(seq) :
SEQ_time_left_handle_frame_get(scene, seq);
y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
- x2 = SEQ_time_has_right_still_frames(scene, seq) ?
- SEQ_time_start_frame_get(seq) + SEQ_time_strip_length_get(scene, seq) :
- SEQ_time_right_handle_frame_get(scene, seq);
+ x2 = SEQ_time_has_right_still_frames(scene, seq) ? SEQ_time_content_end_frame_get(scene, seq) :
+ SEQ_time_right_handle_frame_get(scene, seq);
y2 = seq->machine + SEQ_STRIP_OFSTOP;
/* Limit body to strip bounds. Meta strip can end up with content outside of strip range. */
@@ -1374,7 +1370,7 @@ static void draw_seq_strip(const bContext *C,
if ((sseq->flag & SEQ_SHOW_OVERLAY) &&
(sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_THUMBNAILS) &&
- (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE))) {
+ ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE)) {
draw_seq_strip_thumbnail(
v2d, C, scene, seq, y1, y_threshold ? text_margin_y : y2, pixelx, pixely);
}
@@ -2290,8 +2286,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region)
continue;
}
if (max_ii(SEQ_time_right_handle_frame_get(scene, seq),
- SEQ_time_start_frame_get(seq) + SEQ_time_strip_length_get(scene, seq)) <
- v2d->cur.xmin) {
+ SEQ_time_content_end_frame_get(scene, seq)) < v2d->cur.xmin) {
continue;
}
if (seq->machine + 1.0f < v2d->cur.ymin) {
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 415bb5898a9..a9e31de2096 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -120,7 +120,7 @@ bool ED_space_sequencer_maskedit_poll(bContext *C)
bool ED_space_sequencer_check_show_imbuf(SpaceSeq *sseq)
{
return (sseq->mainb == SEQ_DRAW_IMG_IMBUF) &&
- (ELEM(sseq->view, SEQ_VIEW_PREVIEW, SEQ_VIEW_SEQUENCE_PREVIEW));
+ ELEM(sseq->view, SEQ_VIEW_PREVIEW, SEQ_VIEW_SEQUENCE_PREVIEW);
}
bool ED_space_sequencer_check_show_strip(SpaceSeq *sseq)
@@ -194,7 +194,7 @@ bool sequencer_strip_has_path_poll(bContext *C)
Editing *ed;
Sequence *seq;
return (((ed = SEQ_editing_get(CTX_data_scene(C))) != NULL) && ((seq = ed->act_seq) != NULL) &&
- (SEQ_HAS_PATH(seq)));
+ SEQ_HAS_PATH(seq));
}
bool sequencer_view_has_preview_poll(bContext *C)
@@ -371,7 +371,6 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
else { /* SEQ_RIGHTSEL */
SEQ_time_right_handle_frame_set(scene, seq, snap_frame);
}
- SEQ_transform_fix_single_image_seq_offsets(scene, seq);
}
}
}
@@ -2939,7 +2938,7 @@ static int sequencer_change_path_invoke(bContext *C, wmOperator *op, const wmEve
Sequence *seq = SEQ_select_active_get(scene);
char filepath[FILE_MAX];
- BLI_join_dirfile(filepath, sizeof(filepath), seq->strip->dir, seq->strip->stripdata->name);
+ BLI_path_join(filepath, sizeof(filepath), seq->strip->dir, seq->strip->stripdata->name);
RNA_string_set(op->ptr, "directory", seq->strip->dir);
RNA_string_set(op->ptr, "filepath", filepath);
diff --git a/source/blender/editors/space_sequencer/sequencer_preview.c b/source/blender/editors/space_sequencer/sequencer_preview.c
index 2820edc95aa..2410055d76d 100644
--- a/source/blender/editors/space_sequencer/sequencer_preview.c
+++ b/source/blender/editors/space_sequencer/sequencer_preview.c
@@ -51,7 +51,7 @@ static void free_preview_job(void *data)
}
/* Only this runs inside thread. */
-static void preview_startjob(void *data, short *stop, short *do_update, float *progress)
+static void preview_startjob(void *data, bool *stop, bool *do_update, float *progress)
{
PreviewJob *pj = data;
PreviewJobAudio *previewjb;
diff --git a/source/blender/editors/space_sequencer/sequencer_proxy.c b/source/blender/editors/space_sequencer/sequencer_proxy.c
index c851d3a29d4..30817771015 100644
--- a/source/blender/editors/space_sequencer/sequencer_proxy.c
+++ b/source/blender/editors/space_sequencer/sequencer_proxy.c
@@ -118,7 +118,7 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
if (seq->flag & SELECT) {
ListBase queue = {NULL, NULL};
LinkData *link;
- short stop = 0, do_update;
+ bool stop = false, do_update;
float progress;
SEQ_proxy_rebuild_context(bmain, depsgraph, scene, seq, file_list, &queue, false);
@@ -126,7 +126,7 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
for (link = queue.first; link; link = link->next) {
struct SeqIndexBuildContext *context = link->data;
SEQ_proxy_rebuild(context, &stop, &do_update, &progress);
- SEQ_proxy_rebuild_finish(context, 0);
+ SEQ_proxy_rebuild_finish(context, false);
}
SEQ_relations_free_imbuf(scene, &ed->seqbase, false);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_scopes.c b/source/blender/editors/space_sequencer/sequencer_scopes.c
index af0aa093e40..a1dd9ce2ac2 100644
--- a/source/blender/editors/space_sequencer/sequencer_scopes.c
+++ b/source/blender/editors/space_sequencer/sequencer_scopes.c
@@ -615,7 +615,7 @@ static void vectorscope_put_cross(uchar r, uchar g, uchar b, char *tgt, int w, i
rgb[2] = (float)b / 255.0f;
rgb_to_yuv_normalized(rgb, yuv);
- p = tgt + 4 * (w * (int)((yuv[2] * (h - 3) + 1)) + (int)((yuv[1] * (w - 3) + 1)));
+ p = tgt + 4 * (w * (int)(yuv[2] * (h - 3) + 1) + (int)(yuv[1] * (w - 3) + 1));
if (r == 0 && g == 0 && b == 0) {
r = 255;
@@ -667,7 +667,7 @@ static ImBuf *make_vectorscope_view_from_ibuf_byte(ImBuf *ibuf)
rgb[2] = (float)src1[2] / 255.0f;
rgb_to_yuv_normalized(rgb, yuv);
- p = tgt + 4 * (w * (int)((yuv[2] * (h - 3) + 1)) + (int)((yuv[1] * (w - 3) + 1)));
+ p = tgt + 4 * (w * (int)(yuv[2] * (h - 3) + 1) + (int)(yuv[1] * (w - 3) + 1));
scope_put_pixel(wtable, (uchar *)p);
}
}
@@ -713,7 +713,7 @@ static ImBuf *make_vectorscope_view_from_ibuf_float(ImBuf *ibuf)
rgb_to_yuv_normalized(rgb, yuv);
- p = tgt + 4 * (w * (int)((yuv[2] * (h - 3) + 1)) + (int)((yuv[1] * (w - 3) + 1)));
+ p = tgt + 4 * (w * (int)(yuv[2] * (h - 3) + 1) + (int)(yuv[1] * (w - 3) + 1));
scope_put_pixel(wtable, (uchar *)p);
}
}
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index 4aaa3aeb2ff..7f7e9878dd6 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -117,13 +117,13 @@ static void select_active_side(
if (channel == seq->machine) {
switch (sel_side) {
case SEQ_SIDE_LEFT:
- if (frame > (SEQ_time_left_handle_frame_get(scene, seq))) {
+ if (frame > SEQ_time_left_handle_frame_get(scene, seq)) {
seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL);
seq->flag |= SELECT;
}
break;
case SEQ_SIDE_RIGHT:
- if (frame < (SEQ_time_left_handle_frame_get(scene, seq))) {
+ if (frame < SEQ_time_left_handle_frame_get(scene, seq)) {
seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL);
seq->flag |= SELECT;
}
@@ -154,13 +154,13 @@ static void select_active_side_range(const Scene *scene,
}
switch (sel_side) {
case SEQ_SIDE_LEFT:
- if (frame > (SEQ_time_left_handle_frame_get(scene, seq))) {
+ if (frame > SEQ_time_left_handle_frame_get(scene, seq)) {
seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL);
seq->flag |= SELECT;
}
break;
case SEQ_SIDE_RIGHT:
- if (frame < (SEQ_time_left_handle_frame_get(scene, seq))) {
+ if (frame < SEQ_time_left_handle_frame_get(scene, seq)) {
seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL);
seq->flag |= SELECT;
}
@@ -276,13 +276,13 @@ Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int se
switch (lr) {
case SEQ_SIDE_LEFT:
if (SEQ_time_left_handle_frame_get(scene, test) ==
- (SEQ_time_right_handle_frame_get(scene, seq))) {
+ SEQ_time_right_handle_frame_get(scene, seq)) {
return seq;
}
break;
case SEQ_SIDE_RIGHT:
if (SEQ_time_right_handle_frame_get(scene, test) ==
- (SEQ_time_left_handle_frame_get(scene, seq))) {
+ SEQ_time_left_handle_frame_get(scene, seq)) {
return seq;
}
break;
@@ -973,7 +973,7 @@ static int sequencer_select_exec(bContext *C, wmOperator *op)
bool changed = false;
/* Deselect everything */
- if (deselect_all || (seq && ((extend == false && deselect == false && toggle == false)))) {
+ if (deselect_all || (seq && (extend == false && deselect == false && toggle == false))) {
ED_sequencer_deselect_all(scene);
changed = true;
}
@@ -1815,7 +1815,7 @@ static const EnumPropertyItem sequencer_prop_select_grouped_types[] = {
#define SEQ_USE_DATA(_seq) \
(ELEM(_seq->type, SEQ_TYPE_SCENE, SEQ_TYPE_MOVIECLIP, SEQ_TYPE_MASK) || SEQ_HAS_PATH(_seq))
-#define SEQ_CHANNEL_CHECK(_seq, _chan) (ELEM((_chan), 0, (_seq)->machine))
+#define SEQ_CHANNEL_CHECK(_seq, _chan) ELEM((_chan), 0, (_seq)->machine)
static bool select_grouped_type(SeqCollection *strips,
ListBase *UNUSED(seqbase),
diff --git a/source/blender/editors/space_sequencer/sequencer_thumbnails.c b/source/blender/editors/space_sequencer/sequencer_thumbnails.c
index a11b5663620..d1606b14152 100644
--- a/source/blender/editors/space_sequencer/sequencer_thumbnails.c
+++ b/source/blender/editors/space_sequencer/sequencer_thumbnails.c
@@ -74,11 +74,12 @@ static bool check_seq_need_thumbnails(const Scene *scene, Sequence *seq, rctf *v
if (!ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE)) {
return false;
}
- if (min_ii(SEQ_time_left_handle_frame_get(scene, seq), seq->start) > view_area->xmax) {
+ if (min_ii(SEQ_time_left_handle_frame_get(scene, seq), SEQ_time_start_frame_get(seq)) >
+ view_area->xmax) {
return false;
}
- if (max_ii(SEQ_time_right_handle_frame_get(scene, seq), seq->start + seq->len) <
- view_area->xmin) {
+ if (max_ii(SEQ_time_right_handle_frame_get(scene, seq),
+ SEQ_time_content_end_frame_get(scene, seq)) < view_area->xmin) {
return false;
}
if (seq->machine + 1.0f < view_area->ymin) {
@@ -131,8 +132,8 @@ static void seq_get_thumb_image_dimensions(Sequence *seq,
}
static void thumbnail_start_job(void *data,
- short *stop,
- short *UNUSED(do_update),
+ bool *stop,
+ bool *UNUSED(do_update),
float *UNUSED(progress))
{
ThumbnailDrawJob *tj = data;
@@ -374,7 +375,7 @@ static int sequencer_thumbnail_closest_guaranteed_frame_get(struct Scene *scene,
/* Set of "guaranteed" thumbnails. */
const int frame_index = timeline_frame - SEQ_time_left_handle_frame_get(scene, seq);
const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(scene, seq);
- const int relative_base_frame = round_fl_to_int((frame_index / (float)frame_step)) * frame_step;
+ const int relative_base_frame = round_fl_to_int(frame_index / (float)frame_step) * frame_step;
const int nearest_guaranted_absolute_frame = relative_base_frame +
SEQ_time_left_handle_frame_get(scene, seq);
return nearest_guaranted_absolute_frame;
@@ -536,7 +537,7 @@ void draw_seq_strip_thumbnail(View2D *v2d,
if (seq->flag & SEQ_OVERLAP) {
GPU_blend(GPU_BLEND_ALPHA);
if (ibuf->rect) {
- unsigned char *buf = (unsigned char *)ibuf->rect;
+ uchar *buf = (uchar *)ibuf->rect;
for (int pixel = ibuf->x * ibuf->y; pixel--; buf += 4) {
buf[3] = OVERLAP_ALPHA;
}
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index 538cfad14f5..1d20926d16c 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -44,6 +44,8 @@
#include "UI_interface.h"
#include "UI_view2d.h"
+#include "BLO_read_write.h"
+
#include "IMB_imbuf.h"
/* Only for cursor drawing. */
@@ -127,7 +129,6 @@ static SpaceLink *sequencer_create(const ScrArea *UNUSED(area), const Scene *sce
region->regiontype = RGN_TYPE_TOOLS;
region->alignment = RGN_ALIGN_LEFT;
region->flag = RGN_FLAG_HIDDEN;
- region->v2d.flag |= V2D_VIEWSYNC_AREA_VERTICAL;
/* Channels. */
region = MEM_callocN(sizeof(ARegion), "channels for sequencer");
@@ -135,6 +136,7 @@ static SpaceLink *sequencer_create(const ScrArea *UNUSED(area), const Scene *sce
BLI_addtail(&sseq->regionbase, region);
region->regiontype = RGN_TYPE_CHANNELS;
region->alignment = RGN_ALIGN_LEFT;
+ region->v2d.flag |= V2D_VIEWSYNC_AREA_VERTICAL;
/* Preview region. */
/* NOTE: if you change values here, also change them in sequencer_init_preview_region. */
@@ -229,7 +231,7 @@ static void sequencer_free(SpaceLink *sl)
}
}
-/* Spacetype init callback. */
+/* Space-type init callback. */
static void sequencer_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(area))
{
}
@@ -991,6 +993,47 @@ static void sequencer_channel_region_draw(const bContext *C, ARegion *region)
draw_channels(C, region);
}
+static void sequencer_blend_read_data(BlendDataReader *UNUSED(reader), SpaceLink *sl)
+{
+ SpaceSeq *sseq = (SpaceSeq *)sl;
+
+ /* grease pencil data is not a direct data and can't be linked from direct_link*
+ * functions, it should be linked from lib_link* functions instead
+ *
+ * otherwise it'll lead to lost grease data on open because it'll likely be
+ * read from file after all other users of grease pencil and newdataadr would
+ * simple return NULL here (sergey)
+ */
+#if 0
+ if (sseq->gpd) {
+ sseq->gpd = newdataadr(fd, sseq->gpd);
+ BKE_gpencil_blend_read_data(fd, sseq->gpd);
+ }
+#endif
+ sseq->scopes.reference_ibuf = NULL;
+ sseq->scopes.zebra_ibuf = NULL;
+ sseq->scopes.waveform_ibuf = NULL;
+ sseq->scopes.sep_waveform_ibuf = NULL;
+ sseq->scopes.vector_ibuf = NULL;
+ sseq->scopes.histogram_ibuf = NULL;
+ memset(&sseq->runtime, 0x0, sizeof(sseq->runtime));
+}
+
+static void sequencer_blend_read_lib(BlendLibReader *reader, ID *parent_id, SpaceLink *sl)
+{
+ SpaceSeq *sseq = (SpaceSeq *)sl;
+
+ /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
+ * so fingers crossed this works fine!
+ */
+ BLO_read_id_address(reader, parent_id->lib, &sseq->gpd);
+}
+
+static void sequencer_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ BLO_write_struct(writer, SpaceSeq, sl);
+}
+
void ED_spacetype_sequencer(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype sequencer");
@@ -1011,6 +1054,9 @@ void ED_spacetype_sequencer(void)
st->refresh = sequencer_refresh;
st->listener = sequencer_listener;
st->id_remap = sequencer_id_remap;
+ st->blend_read_data = sequencer_blend_read_data;
+ st->blend_read_lib = sequencer_blend_read_lib;
+ st->blend_write = sequencer_blend_write;
/* Create regions: */
/* Main window. */
diff --git a/source/blender/editors/space_spreadsheet/CMakeLists.txt b/source/blender/editors/space_spreadsheet/CMakeLists.txt
index 173d976c124..08032ddbaeb 100644
--- a/source/blender/editors/space_spreadsheet/CMakeLists.txt
+++ b/source/blender/editors/space_spreadsheet/CMakeLists.txt
@@ -5,6 +5,7 @@ set(INC
../../blenfont
../../blenkernel
../../blenlib
+ ../../blenloader
../../blentranslation
../../bmesh
../../depsgraph
@@ -15,6 +16,9 @@ set(INC
../../nodes
../../windowmanager
../../../../intern/guardedalloc
+
+ # dna_type_offsets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
# RNA_prototypes.h
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
@@ -23,7 +27,6 @@ set(SRC
space_spreadsheet.cc
spreadsheet_cache.cc
spreadsheet_column.cc
- spreadsheet_context.cc
spreadsheet_data_source.cc
spreadsheet_data_source_geometry.cc
spreadsheet_dataset_draw.cc
@@ -37,7 +40,6 @@ set(SRC
spreadsheet_cache.hh
spreadsheet_column.hh
spreadsheet_column_values.hh
- spreadsheet_context.hh
spreadsheet_data_source.hh
spreadsheet_data_source_geometry.hh
spreadsheet_dataset_draw.hh
@@ -63,5 +65,5 @@ endif()
blender_add_lib(bf_editor_space_spreadsheet "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
-# RNA_prototypes.h
+# RNA_prototypes.h dna_type_offsets.h
add_dependencies(bf_editor_space_spreadsheet bf_rna)
diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
index 435436611c5..c546a371ef0 100644
--- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
+++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
@@ -10,6 +10,7 @@
#include "ED_screen.h"
#include "ED_space_api.h"
#include "ED_spreadsheet.h"
+#include "ED_viewer_path.hh"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -21,6 +22,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "BLO_read_write.h"
+
#include "DEG_depsgraph_query.h"
#include "RNA_access.h"
@@ -32,7 +35,6 @@
#include "BLF_api.h"
-#include "spreadsheet_context.hh"
#include "spreadsheet_data_source_geometry.hh"
#include "spreadsheet_dataset_draw.hh"
#include "spreadsheet_intern.hh"
@@ -43,7 +45,7 @@
using namespace blender;
using namespace blender::ed::spreadsheet;
-static SpaceLink *spreadsheet_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *spreadsheet_create(const ScrArea * /*area*/, const Scene * /*scene*/)
{
SpaceSpreadsheet *spreadsheet_space = MEM_cnew<SpaceSpreadsheet>("spreadsheet space");
spreadsheet_space->spacetype = SPACE_SPREADSHEET;
@@ -105,12 +107,10 @@ static void spreadsheet_free(SpaceLink *sl)
LISTBASE_FOREACH_MUTABLE (SpreadsheetColumn *, column, &sspreadsheet->columns) {
spreadsheet_column_free(column);
}
- LISTBASE_FOREACH_MUTABLE (SpreadsheetContext *, context, &sspreadsheet->context_path) {
- spreadsheet_context_free(context);
- }
+ BKE_viewer_path_clear(&sspreadsheet->viewer_path);
}
-static void spreadsheet_init(wmWindowManager *UNUSED(wm), ScrArea *area)
+static void spreadsheet_init(wmWindowManager * /*wm*/, ScrArea *area)
{
SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)area->spacedata.first;
if (sspreadsheet->runtime == nullptr) {
@@ -141,11 +141,7 @@ static SpaceLink *spreadsheet_duplicate(SpaceLink *sl)
BLI_addtail(&sspreadsheet_new->columns, new_column);
}
- BLI_listbase_clear(&sspreadsheet_new->context_path);
- LISTBASE_FOREACH_MUTABLE (SpreadsheetContext *, src_context, &sspreadsheet_old->context_path) {
- SpreadsheetContext *new_context = spreadsheet_context_copy(src_context);
- BLI_addtail(&sspreadsheet_new->context_path, new_context);
- }
+ BKE_viewer_path_copy(&sspreadsheet_new->viewer_path, &sspreadsheet_old->viewer_path);
return (SpaceLink *)sspreadsheet_new;
}
@@ -156,24 +152,10 @@ static void spreadsheet_keymap(wmKeyConfig *keyconf)
WM_keymap_ensure(keyconf, "Spreadsheet Generic", SPACE_SPREADSHEET, 0);
}
-static void spreadsheet_id_remap(ScrArea *UNUSED(area),
- SpaceLink *slink,
- const IDRemapper *mappings)
+static void spreadsheet_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemapper *mappings)
{
SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)slink;
- LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) {
- if (context->type != SPREADSHEET_CONTEXT_OBJECT) {
- continue;
- }
- SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context;
-
- if (object_context->object != nullptr && GS(object_context->object->id.name) != ID_OB) {
- object_context->object = nullptr;
- continue;
- }
-
- BKE_id_remapper_apply(mappings, ((ID **)&object_context->object), ID_REMAP_APPLY_DEFAULT);
- }
+ BKE_viewer_path_id_remap(&sspreadsheet->viewer_path, mappings);
}
static void spreadsheet_main_region_init(wmWindowManager *wm, ARegion *region)
@@ -199,54 +181,101 @@ static void spreadsheet_main_region_init(wmWindowManager *wm, ARegion *region)
ID *ED_spreadsheet_get_current_id(const struct SpaceSpreadsheet *sspreadsheet)
{
- if (BLI_listbase_is_empty(&sspreadsheet->context_path)) {
+ if (BLI_listbase_is_empty(&sspreadsheet->viewer_path.path)) {
return nullptr;
}
- SpreadsheetContext *root_context = (SpreadsheetContext *)sspreadsheet->context_path.first;
- if (root_context->type != SPREADSHEET_CONTEXT_OBJECT) {
+ ViewerPathElem *root_context = static_cast<ViewerPathElem *>(
+ sspreadsheet->viewer_path.path.first);
+ if (root_context->type != VIEWER_PATH_ELEM_TYPE_ID) {
return nullptr;
}
- SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)root_context;
- return (ID *)object_context->object;
+ IDViewerPathElem *id_elem = reinterpret_cast<IDViewerPathElem *>(root_context);
+ return id_elem->id;
}
-/* Check if the pinned context still exists. If it doesn't try to find a new context. */
-static void update_pinned_context_path_if_outdated(const bContext *C)
+static void view_active_object(const bContext *C, SpaceSpreadsheet *sspreadsheet)
{
- SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
- Main *bmain = CTX_data_main(C);
- if (!ED_spreadsheet_context_path_exists(bmain, sspreadsheet)) {
- ED_spreadsheet_context_path_guess(C, sspreadsheet);
- if (ED_spreadsheet_context_path_update_tag(sspreadsheet)) {
- ED_area_tag_redraw(CTX_wm_area(C));
- }
- }
-
- if (BLI_listbase_is_empty(&sspreadsheet->context_path)) {
- /* Don't pin empty context_path, that could be annoying. */
- sspreadsheet->flag &= ~SPREADSHEET_FLAG_PINNED;
+ BKE_viewer_path_clear(&sspreadsheet->viewer_path);
+ Object *ob = CTX_data_active_object(C);
+ if (ob == nullptr) {
+ return;
}
+ IDViewerPathElem *id_elem = BKE_viewer_path_elem_new_id();
+ id_elem->id = &ob->id;
+ BLI_addtail(&sspreadsheet->viewer_path.path, id_elem);
+ ED_area_tag_redraw(CTX_wm_area(C));
}
-static void update_context_path_from_context(const bContext *C)
+static void spreadsheet_update_context(const bContext *C)
{
+ using blender::ed::viewer_path::ViewerPathForGeometryNodesViewer;
+
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
- if (!ED_spreadsheet_context_path_is_active(C, sspreadsheet)) {
- ED_spreadsheet_context_path_guess(C, sspreadsheet);
- if (ED_spreadsheet_context_path_update_tag(sspreadsheet)) {
- ED_area_tag_redraw(CTX_wm_area(C));
+ Object *active_object = CTX_data_active_object(C);
+ Object *context_object = blender::ed::viewer_path::parse_object_only(sspreadsheet->viewer_path);
+ switch (eSpaceSpreadsheet_ObjectEvalState(sspreadsheet->object_eval_state)) {
+ case SPREADSHEET_OBJECT_EVAL_STATE_ORIGINAL:
+ case SPREADSHEET_OBJECT_EVAL_STATE_EVALUATED: {
+ if (sspreadsheet->flag & SPREADSHEET_FLAG_PINNED) {
+ if (context_object == nullptr) {
+ /* Object is not available anymore, so clear the pinning. */
+ sspreadsheet->flag &= ~SPREADSHEET_FLAG_PINNED;
+ }
+ else {
+ /* The object is still pinned, do nothing. */
+ break;
+ }
+ }
+ else {
+ if (active_object != context_object) {
+ /* The active object has changed, so view the new active object. */
+ view_active_object(C, sspreadsheet);
+ }
+ else {
+ /* Nothing changed. */
+ break;
+ }
+ }
+ break;
}
- }
-}
+ case SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE: {
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ if (sspreadsheet->flag & SPREADSHEET_FLAG_PINNED) {
+ const std::optional<ViewerPathForGeometryNodesViewer> parsed_path =
+ blender::ed::viewer_path::parse_geometry_nodes_viewer(sspreadsheet->viewer_path);
+ if (parsed_path.has_value()) {
+ if (blender::ed::viewer_path::exists_geometry_nodes_viewer(*parsed_path)) {
+ /* The pinned path is still valid, do nothing. */
+ break;
+ }
+ /* The pinned path does not exist anymore, clear pinning. */
+ sspreadsheet->flag &= ~SPREADSHEET_FLAG_PINNED;
+ }
+ else {
+ /* Unknown pinned path, clear pinning. */
+ sspreadsheet->flag &= ~SPREADSHEET_FLAG_PINNED;
+ }
+ }
+ /* Now try to update the viewer path from the workspace. */
+ const std::optional<ViewerPathForGeometryNodesViewer> workspace_parsed_path =
+ blender::ed::viewer_path::parse_geometry_nodes_viewer(workspace->viewer_path);
+ if (workspace_parsed_path.has_value()) {
+ if (BKE_viewer_path_equal(&sspreadsheet->viewer_path, &workspace->viewer_path)) {
+ /* Nothing changed. */
+ break;
+ }
+ /* Update the viewer path from the workspace. */
+ BKE_viewer_path_clear(&sspreadsheet->viewer_path);
+ BKE_viewer_path_copy(&sspreadsheet->viewer_path, &workspace->viewer_path);
+ }
+ else {
+ /* No active viewer node, change back to showing evaluated active object. */
+ sspreadsheet->object_eval_state = SPREADSHEET_OBJECT_EVAL_STATE_EVALUATED;
+ view_active_object(C, sspreadsheet);
+ }
-void spreadsheet_update_context_path(const bContext *C)
-{
- SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
- if (sspreadsheet->flag & SPREADSHEET_FLAG_PINNED) {
- update_pinned_context_path_if_outdated(C);
- }
- else {
- update_context_path_from_context(C);
+ break;
+ }
}
}
@@ -327,7 +356,7 @@ static float get_column_width(const ColumnValues &values)
{
float data_width = get_default_column_width(values);
const int fontid = UI_style_get()->widget.uifont_id;
- BLF_size(fontid, UI_DEFAULT_TEXT_POINTS, U.dpi);
+ BLF_size(fontid, UI_DEFAULT_TEXT_POINTS * U.dpi_fac);
const StringRefNull name = values.name();
const float name_width = BLF_width(fontid, name.data(), name.size());
return std::max<float>(name_width / UI_UNIT_X + 1.0f, data_width);
@@ -341,7 +370,7 @@ static float get_column_width_in_pixels(const ColumnValues &values)
static int get_index_column_width(const int tot_rows)
{
const int fontid = UI_style_get()->widget.uifont_id;
- BLF_size(fontid, UI_style_get_dpi()->widget.points * U.pixelsize, U.dpi);
+ BLF_size(fontid, UI_style_get_dpi()->widget.points * U.dpi_fac);
return std::to_string(std::max(0, tot_rows - 1)).size() * BLF_width(fontid, "0", 1) +
UI_UNIT_X * 0.75;
}
@@ -388,7 +417,7 @@ static void spreadsheet_main_region_draw(const bContext *C, ARegion *region)
{
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
sspreadsheet->runtime->cache.set_all_unused();
- spreadsheet_update_context_path(C);
+ spreadsheet_update_context(C);
std::unique_ptr<DataSource> data_source = get_data_source(C);
if (!data_source) {
@@ -437,6 +466,7 @@ static void spreadsheet_main_region_listener(const wmRegionListenerParams *param
{
ARegion *region = params->region;
const wmNotifier *wmn = params->notifier;
+ SpaceSpreadsheet *sspreadsheet = static_cast<SpaceSpreadsheet *>(params->area->spacedata.first);
switch (wmn->category) {
case NC_SCENE: {
@@ -465,21 +495,27 @@ static void spreadsheet_main_region_listener(const wmRegionListenerParams *param
ED_region_tag_redraw(region);
break;
}
+ case NC_VIEWER_PATH: {
+ if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) {
+ ED_region_tag_redraw(region);
+ }
+ break;
+ }
}
}
-static void spreadsheet_header_region_init(wmWindowManager *UNUSED(wm), ARegion *region)
+static void spreadsheet_header_region_init(wmWindowManager * /*wm*/, ARegion *region)
{
ED_region_header_init(region);
}
static void spreadsheet_header_region_draw(const bContext *C, ARegion *region)
{
- spreadsheet_update_context_path(C);
+ spreadsheet_update_context(C);
ED_region_header(C, region);
}
-static void spreadsheet_header_region_free(ARegion *UNUSED(region))
+static void spreadsheet_header_region_free(ARegion * /*region*/)
{
}
@@ -487,6 +523,7 @@ static void spreadsheet_header_region_listener(const wmRegionListenerParams *par
{
ARegion *region = params->region;
const wmNotifier *wmn = params->notifier;
+ SpaceSpreadsheet *sspreadsheet = static_cast<SpaceSpreadsheet *>(params->area->spacedata.first);
switch (wmn->category) {
case NC_SCENE: {
@@ -513,10 +550,16 @@ static void spreadsheet_header_region_listener(const wmRegionListenerParams *par
ED_region_tag_redraw(region);
break;
}
+ case NC_VIEWER_PATH: {
+ if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) {
+ ED_region_tag_redraw(region);
+ }
+ break;
+ }
}
}
-static void spreadsheet_footer_region_init(wmWindowManager *UNUSED(wm), ARegion *region)
+static void spreadsheet_footer_region_init(wmWindowManager * /*wm*/, ARegion *region)
{
ED_region_header_init(region);
}
@@ -559,11 +602,11 @@ static void spreadsheet_footer_region_draw(const bContext *C, ARegion *region)
UI_block_draw(C, block);
}
-static void spreadsheet_footer_region_free(ARegion *UNUSED(region))
+static void spreadsheet_footer_region_free(ARegion * /*region*/)
{
}
-static void spreadsheet_footer_region_listener(const wmRegionListenerParams *UNUSED(params))
+static void spreadsheet_footer_region_listener(const wmRegionListenerParams * /*params*/)
{
}
@@ -591,7 +634,7 @@ static void spreadsheet_dataset_region_listener(const wmRegionListenerParams *pa
static void spreadsheet_dataset_region_draw(const bContext *C, ARegion *region)
{
- spreadsheet_update_context_path(C);
+ spreadsheet_update_context(C);
ED_region_panels(C, region);
}
@@ -605,14 +648,65 @@ static void spreadsheet_sidebar_init(wmWindowManager *wm, ARegion *region)
WM_event_add_keymap_handler(&region->handlers, keymap);
}
-static void spreadsheet_right_region_free(ARegion *UNUSED(region))
+static void spreadsheet_right_region_free(ARegion * /*region*/)
{
}
-static void spreadsheet_right_region_listener(const wmRegionListenerParams *UNUSED(params))
+static void spreadsheet_right_region_listener(const wmRegionListenerParams * /*params*/)
{
}
+static void spreadsheet_blend_read_data(BlendDataReader *reader, SpaceLink *sl)
+{
+ SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
+
+ sspreadsheet->runtime = nullptr;
+ BLO_read_list(reader, &sspreadsheet->row_filters);
+ LISTBASE_FOREACH (SpreadsheetRowFilter *, row_filter, &sspreadsheet->row_filters) {
+ BLO_read_data_address(reader, &row_filter->value_string);
+ }
+ BLO_read_list(reader, &sspreadsheet->columns);
+ LISTBASE_FOREACH (SpreadsheetColumn *, column, &sspreadsheet->columns) {
+ BLO_read_data_address(reader, &column->id);
+ BLO_read_data_address(reader, &column->id->name);
+ /* While the display name is technically runtime data, it is loaded here, otherwise the row
+ * filters might not now their type if their region draws before the main region.
+ * This would ideally be cleared here. */
+ BLO_read_data_address(reader, &column->display_name);
+ }
+
+ BKE_viewer_path_blend_read_data(reader, &sspreadsheet->viewer_path);
+}
+
+static void spreadsheet_blend_read_lib(BlendLibReader *reader, ID *parent_id, SpaceLink *sl)
+{
+ SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
+ BKE_viewer_path_blend_read_lib(reader, parent_id->lib, &sspreadsheet->viewer_path);
+}
+
+static void spreadsheet_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ BLO_write_struct(writer, SpaceSpreadsheet, sl);
+ SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
+
+ LISTBASE_FOREACH (SpreadsheetRowFilter *, row_filter, &sspreadsheet->row_filters) {
+ BLO_write_struct(writer, SpreadsheetRowFilter, row_filter);
+ BLO_write_string(writer, row_filter->value_string);
+ }
+
+ LISTBASE_FOREACH (SpreadsheetColumn *, column, &sspreadsheet->columns) {
+ BLO_write_struct(writer, SpreadsheetColumn, column);
+ BLO_write_struct(writer, SpreadsheetColumnID, column->id);
+ BLO_write_string(writer, column->id->name);
+ /* While the display name is technically runtime data, we write it here, otherwise the row
+ * filters might not now their type if their region draws before the main region.
+ * This would ideally be cleared here. */
+ BLO_write_string(writer, column->display_name);
+ }
+
+ BKE_viewer_path_blend_write(writer, &sspreadsheet->viewer_path);
+}
+
void ED_spacetype_spreadsheet()
{
SpaceType *st = MEM_cnew<SpaceType>("spacetype spreadsheet");
@@ -628,6 +722,9 @@ void ED_spacetype_spreadsheet()
st->operatortypes = spreadsheet_operatortypes;
st->keymap = spreadsheet_keymap;
st->id_remap = spreadsheet_id_remap;
+ st->blend_read_data = spreadsheet_blend_read_data;
+ st->blend_read_lib = spreadsheet_blend_read_lib;
+ st->blend_write = spreadsheet_blend_write;
/* regions: main window */
art = MEM_cnew<ARegionType>("spacetype spreadsheet region");
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_cache.cc b/source/blender/editors/space_spreadsheet/spreadsheet_cache.cc
index 931a00ab583..752a7451964 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_cache.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_cache.cc
@@ -45,12 +45,11 @@ void SpreadsheetCache::set_all_unused()
void SpreadsheetCache::remove_all_unused()
{
/* First remove the keys from the map and free the values. */
- for (auto it = cache_map_.keys().begin(); it != cache_map_.keys().end(); ++it) {
- const Key &key = *it;
- if (!key.is_used) {
- cache_map_.remove(it);
- }
- }
+ cache_map_.remove_if([&](auto item) {
+ const Key &key = item.key;
+ return !key.is_used;
+ });
+
/* Then free the keys. */
for (int i = 0; i < keys_.size();) {
if (keys_[i]->is_used) {
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_column.cc b/source/blender/editors/space_spreadsheet/spreadsheet_column.cc
index 46e98acb8e8..af41225f42a 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_column.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_column.cc
@@ -12,6 +12,7 @@
#include "BLI_string_ref.hh"
#include "BKE_geometry_set.hh"
+#include "BKE_instances.hh"
#include "spreadsheet_column.hh"
#include "spreadsheet_column_values.hh"
@@ -44,7 +45,7 @@ eSpreadsheetColumnValueType cpp_type_to_column_type(const CPPType &type)
if (type.is<std::string>()) {
return SPREADSHEET_VALUE_TYPE_STRING;
}
- if (type.is<InstanceReference>()) {
+ if (type.is<bke::InstanceReference>()) {
return SPREADSHEET_VALUE_TYPE_INSTANCES;
}
if (type.is<ColorGeometry4b>()) {
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_context.cc b/source/blender/editors/space_spreadsheet/spreadsheet_context.cc
deleted file mode 100644
index ec9fa72edb1..00000000000
--- a/source/blender/editors/space_spreadsheet/spreadsheet_context.cc
+++ /dev/null
@@ -1,591 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_hash.h"
-#include "BLI_hash.hh"
-#include "BLI_hash_mm2a.h"
-#include "BLI_listbase.h"
-#include "BLI_string.h"
-#include "BLI_utildefines.h"
-#include "BLI_vector.hh"
-
-#include "ED_screen.h"
-#include "ED_spreadsheet.h"
-
-#include "DEG_depsgraph.h"
-
-#include "BKE_context.h"
-#include "BKE_main.h"
-#include "BKE_modifier.h"
-#include "BKE_node.h"
-#include "BKE_object.h"
-#include "BKE_workspace.h"
-
-#include "DNA_modifier_types.h"
-#include "DNA_windowmanager_types.h"
-
-#include "spreadsheet_context.hh"
-
-using blender::IndexRange;
-using blender::Span;
-using blender::StringRef;
-using blender::Vector;
-
-namespace blender::ed::spreadsheet {
-
-static SpreadsheetContextObject *spreadsheet_context_object_new()
-{
- SpreadsheetContextObject *context = MEM_cnew<SpreadsheetContextObject>(__func__);
- context->base.type = SPREADSHEET_CONTEXT_OBJECT;
- return context;
-}
-
-static SpreadsheetContextObject *spreadsheet_context_object_copy(
- const SpreadsheetContextObject *src_context)
-{
- SpreadsheetContextObject *new_context = spreadsheet_context_object_new();
- new_context->object = src_context->object;
- return new_context;
-}
-
-static void spreadsheet_context_object_hash(const SpreadsheetContextObject *context,
- BLI_HashMurmur2A *mm2)
-{
- BLI_hash_mm2a_add(mm2, (const uchar *)&context->object, sizeof(Object *));
-}
-
-static void spreadsheet_context_object_free(SpreadsheetContextObject *context)
-{
- MEM_freeN(context);
-}
-
-static SpreadsheetContextModifier *spreadsheet_context_modifier_new()
-{
- SpreadsheetContextModifier *context = MEM_cnew<SpreadsheetContextModifier>(__func__);
- context->base.type = SPREADSHEET_CONTEXT_MODIFIER;
- return context;
-}
-
-static SpreadsheetContextModifier *spreadsheet_context_modifier_copy(
- const SpreadsheetContextModifier *src_context)
-{
- SpreadsheetContextModifier *new_context = spreadsheet_context_modifier_new();
- if (src_context->modifier_name) {
- new_context->modifier_name = BLI_strdup(src_context->modifier_name);
- }
- return new_context;
-}
-
-static void spreadsheet_context_modifier_hash(const SpreadsheetContextModifier *context,
- BLI_HashMurmur2A *mm2)
-{
- if (context->modifier_name) {
- BLI_hash_mm2a_add(mm2, (const uchar *)context->modifier_name, strlen(context->modifier_name));
- }
-}
-
-static void spreadsheet_context_modifier_free(SpreadsheetContextModifier *context)
-{
- if (context->modifier_name) {
- MEM_freeN(context->modifier_name);
- }
- MEM_freeN(context);
-}
-
-static SpreadsheetContextNode *spreadsheet_context_node_new()
-{
- SpreadsheetContextNode *context = MEM_cnew<SpreadsheetContextNode>(__func__);
- context->base.type = SPREADSHEET_CONTEXT_NODE;
- return context;
-}
-
-static SpreadsheetContextNode *spreadsheet_context_node_copy(
- const SpreadsheetContextNode *src_context)
-{
- SpreadsheetContextNode *new_context = spreadsheet_context_node_new();
- if (src_context->node_name) {
- new_context->node_name = BLI_strdup(src_context->node_name);
- }
- return new_context;
-}
-
-static void spreadsheet_context_node_hash(const SpreadsheetContextNode *context,
- BLI_HashMurmur2A *mm2)
-{
- if (context->node_name) {
- BLI_hash_mm2a_add(mm2, (const uchar *)context->node_name, strlen(context->node_name));
- }
-}
-
-static void spreadsheet_context_node_free(SpreadsheetContextNode *context)
-{
- if (context->node_name) {
- MEM_freeN(context->node_name);
- }
- MEM_freeN(context);
-}
-
-SpreadsheetContext *spreadsheet_context_new(eSpaceSpreadsheet_ContextType type)
-{
- switch (type) {
- case SPREADSHEET_CONTEXT_OBJECT: {
- return (SpreadsheetContext *)spreadsheet_context_object_new();
- }
- case SPREADSHEET_CONTEXT_MODIFIER: {
- return (SpreadsheetContext *)spreadsheet_context_modifier_new();
- }
- case SPREADSHEET_CONTEXT_NODE: {
- return (SpreadsheetContext *)spreadsheet_context_node_new();
- }
- }
- BLI_assert_unreachable();
- return nullptr;
-}
-
-SpreadsheetContext *spreadsheet_context_copy(const SpreadsheetContext *old_context)
-{
- switch (old_context->type) {
- case SPREADSHEET_CONTEXT_OBJECT: {
- return (SpreadsheetContext *)spreadsheet_context_object_copy(
- (const SpreadsheetContextObject *)old_context);
- }
- case SPREADSHEET_CONTEXT_MODIFIER: {
- return (SpreadsheetContext *)spreadsheet_context_modifier_copy(
- (const SpreadsheetContextModifier *)old_context);
- }
- case SPREADSHEET_CONTEXT_NODE: {
- return (SpreadsheetContext *)spreadsheet_context_node_copy(
- (const SpreadsheetContextNode *)old_context);
- }
- }
- BLI_assert_unreachable();
- return nullptr;
-}
-
-static void spreadsheet_context_hash(const SpreadsheetContext *context, BLI_HashMurmur2A *mm2)
-{
- BLI_hash_mm2a_add_int(mm2, context->type);
- switch (context->type) {
- case SPREADSHEET_CONTEXT_OBJECT: {
- spreadsheet_context_object_hash((const SpreadsheetContextObject *)context, mm2);
- break;
- }
- case SPREADSHEET_CONTEXT_MODIFIER: {
- spreadsheet_context_modifier_hash((const SpreadsheetContextModifier *)context, mm2);
- break;
- }
- case SPREADSHEET_CONTEXT_NODE: {
- spreadsheet_context_node_hash((const SpreadsheetContextNode *)context, mm2);
- break;
- }
- }
-}
-
-void spreadsheet_context_free(SpreadsheetContext *context)
-{
- switch (context->type) {
- case SPREADSHEET_CONTEXT_OBJECT: {
- return spreadsheet_context_object_free((SpreadsheetContextObject *)context);
- }
- case SPREADSHEET_CONTEXT_MODIFIER: {
- return spreadsheet_context_modifier_free((SpreadsheetContextModifier *)context);
- }
- case SPREADSHEET_CONTEXT_NODE: {
- return spreadsheet_context_node_free((SpreadsheetContextNode *)context);
- }
- }
- BLI_assert_unreachable();
-}
-
-/**
- * Tag any data relevant to the spreadsheet's context for recalculation in order to collect
- * information to display in the editor, which may be cached during evaluation.
- * \return True when any data has been tagged for update.
- */
-static bool spreadsheet_context_update_tag(SpaceSpreadsheet *sspreadsheet)
-{
- using namespace blender;
- Vector<const SpreadsheetContext *> context_path = sspreadsheet->context_path;
- if (context_path.is_empty()) {
- return false;
- }
- if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) {
- return false;
- }
- SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context_path[0];
- Object *object = object_context->object;
- if (object == nullptr) {
- return false;
- }
- if (context_path.size() == 1) {
- /* No need to reevaluate, when the final or original object is viewed. */
- return false;
- }
-
- DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY);
- return true;
-}
-
-} // namespace blender::ed::spreadsheet
-
-SpreadsheetContext *ED_spreadsheet_context_new(int type)
-{
- return blender::ed::spreadsheet::spreadsheet_context_new((eSpaceSpreadsheet_ContextType)type);
-}
-
-void ED_spreadsheet_context_free(struct SpreadsheetContext *context)
-{
- blender::ed::spreadsheet::spreadsheet_context_free(context);
-}
-
-void ED_spreadsheet_context_path_clear(struct SpaceSpreadsheet *sspreadsheet)
-{
- LISTBASE_FOREACH_MUTABLE (SpreadsheetContext *, context, &sspreadsheet->context_path) {
- ED_spreadsheet_context_free(context);
- }
- BLI_listbase_clear(&sspreadsheet->context_path);
-}
-
-bool ED_spreadsheet_context_path_update_tag(SpaceSpreadsheet *sspreadsheet)
-{
- return blender::ed::spreadsheet::spreadsheet_context_update_tag(sspreadsheet);
-}
-
-uint64_t ED_spreadsheet_context_path_hash(const SpaceSpreadsheet *sspreadsheet)
-{
- BLI_HashMurmur2A mm2;
- BLI_hash_mm2a_init(&mm2, 1234);
- LISTBASE_FOREACH (const SpreadsheetContext *, context, &sspreadsheet->context_path) {
- blender::ed::spreadsheet::spreadsheet_context_hash(context, &mm2);
- }
- return BLI_hash_mm2a_end(&mm2);
-}
-
-void ED_spreadsheet_context_path_set_geometry_node(struct SpaceSpreadsheet *sspreadsheet,
- struct SpaceNode *snode,
- struct bNode *node)
-{
- using namespace blender::ed::spreadsheet;
-
- Object *object = (Object *)snode->id;
- /* Try to find the modifier the node tree belongs to. */
- ModifierData *modifier = BKE_object_active_modifier(object);
- if (modifier && modifier->type != eModifierType_Nodes) {
- modifier = nullptr;
- LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
- if (md->type == eModifierType_Nodes) {
- NodesModifierData *nmd = (NodesModifierData *)md;
- if (nmd->node_group == snode->nodetree) {
- modifier = md;
- break;
- }
- }
- }
- }
- if (modifier == nullptr) {
- return;
- }
-
- ED_spreadsheet_context_path_clear(sspreadsheet);
-
- {
- SpreadsheetContextObject *context = spreadsheet_context_object_new();
- context->object = object;
- BLI_addtail(&sspreadsheet->context_path, context);
- }
- {
- SpreadsheetContextModifier *context = spreadsheet_context_modifier_new();
- context->modifier_name = BLI_strdup(modifier->name);
- BLI_addtail(&sspreadsheet->context_path, context);
- }
- {
- int i;
- LISTBASE_FOREACH_INDEX (bNodeTreePath *, path, &snode->treepath, i) {
- if (i == 0) {
- continue;
- }
- SpreadsheetContextNode *context = spreadsheet_context_node_new();
- context->node_name = BLI_strdup(path->node_name);
- BLI_addtail(&sspreadsheet->context_path, context);
- }
- }
- {
- SpreadsheetContextNode *context = spreadsheet_context_node_new();
- context->node_name = BLI_strdup(node->name);
- BLI_addtail(&sspreadsheet->context_path, context);
- }
-
- sspreadsheet->object_eval_state = SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE;
-}
-
-void ED_spreadsheet_context_paths_set_geometry_node(Main *bmain, SpaceNode *snode, bNode *node)
-{
- wmWindowManager *wm = (wmWindowManager *)bmain->wm.first;
- if (wm == nullptr) {
- return;
- }
- LISTBASE_FOREACH (wmWindow *, window, &wm->windows) {
- bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook);
- LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
- SpaceLink *sl = (SpaceLink *)area->spacedata.first;
- if (sl->spacetype == SPACE_SPREADSHEET) {
- SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
- if ((sspreadsheet->flag & SPREADSHEET_FLAG_PINNED) == 0) {
- const uint64_t context_hash_before = ED_spreadsheet_context_path_hash(sspreadsheet);
- ED_spreadsheet_context_path_set_geometry_node(sspreadsheet, snode, node);
- const uint64_t context_hash_after = ED_spreadsheet_context_path_hash(sspreadsheet);
- if (context_hash_before != context_hash_after) {
- ED_spreadsheet_context_path_update_tag(sspreadsheet);
- }
- ED_area_tag_redraw(area);
- }
- }
- }
- }
-}
-
-void ED_spreadsheet_context_path_set_evaluated_object(SpaceSpreadsheet *sspreadsheet,
- Object *object)
-{
- using namespace blender::ed::spreadsheet;
- ED_spreadsheet_context_path_clear(sspreadsheet);
-
- SpreadsheetContextObject *context = spreadsheet_context_object_new();
- context->object = object;
- BLI_addtail(&sspreadsheet->context_path, context);
-}
-
-static bScreen *find_screen_to_search_for_context(wmWindow *window,
- SpaceSpreadsheet *current_space)
-{
- bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook);
- if (ELEM(screen->state, SCREENMAXIMIZED, SCREENFULL)) {
- /* If the spreadsheet is maximized, try to find the context in the unmaximized screen. */
- ScrArea *main_area = (ScrArea *)screen->areabase.first;
- SpaceLink *sl = (SpaceLink *)main_area->spacedata.first;
- if (sl == (SpaceLink *)current_space) {
- return main_area->full;
- }
- }
- return screen;
-}
-
-void ED_spreadsheet_context_path_guess(const bContext *C, SpaceSpreadsheet *sspreadsheet)
-{
- ED_spreadsheet_context_path_clear(sspreadsheet);
-
- Main *bmain = CTX_data_main(C);
- wmWindowManager *wm = (wmWindowManager *)bmain->wm.first;
- if (wm == nullptr) {
- return;
- }
-
- if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) {
- LISTBASE_FOREACH (wmWindow *, window, &wm->windows) {
- bScreen *screen = find_screen_to_search_for_context(window, sspreadsheet);
- LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
- SpaceLink *sl = (SpaceLink *)area->spacedata.first;
- if (sl == nullptr) {
- continue;
- }
- if (sl->spacetype == SPACE_NODE) {
- SpaceNode *snode = (SpaceNode *)sl;
- if (snode->edittree != nullptr) {
- if (snode->edittree->type == NTREE_GEOMETRY) {
- LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
- if (node->type == GEO_NODE_VIEWER) {
- if (node->flag & NODE_DO_OUTPUT) {
- ED_spreadsheet_context_path_set_geometry_node(sspreadsheet, snode, node);
- return;
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
- Object *active_object = CTX_data_active_object(C);
- if (active_object != nullptr) {
- ED_spreadsheet_context_path_set_evaluated_object(sspreadsheet, active_object);
- return;
- }
-}
-
-bool ED_spreadsheet_context_path_is_active(const bContext *C, SpaceSpreadsheet *sspreadsheet)
-{
- Main *bmain = CTX_data_main(C);
- wmWindowManager *wm = (wmWindowManager *)bmain->wm.first;
- if (wm == nullptr) {
- return false;
- }
- Vector<SpreadsheetContext *> context_path = sspreadsheet->context_path;
- if (context_path.is_empty()) {
- return false;
- }
- if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) {
- return false;
- }
- Object *object = ((SpreadsheetContextObject *)context_path[0])->object;
- if (object == nullptr) {
- return false;
- }
- if (context_path.size() == 1) {
- if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) {
- return false;
- }
- Object *active_object = CTX_data_active_object(C);
- return object == active_object;
- }
- if (sspreadsheet->object_eval_state != SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) {
- return false;
- }
- if (context_path[1]->type != SPREADSHEET_CONTEXT_MODIFIER) {
- return false;
- }
- const char *modifier_name = ((SpreadsheetContextModifier *)context_path[1])->modifier_name;
- const ModifierData *modifier = BKE_modifiers_findby_name(object, modifier_name);
- if (modifier == nullptr) {
- return false;
- }
- const bool modifier_is_active = modifier->flag & eModifierFlag_Active;
- if (modifier->type != eModifierType_Nodes) {
- return false;
- }
- bNodeTree *root_node_tree = ((NodesModifierData *)modifier)->node_group;
- if (root_node_tree == nullptr) {
- return false;
- }
- const Span<SpreadsheetContext *> node_context_path = context_path.as_span().drop_front(2);
- if (node_context_path.is_empty()) {
- return false;
- }
-
- LISTBASE_FOREACH (wmWindow *, window, &wm->windows) {
- bScreen *screen = find_screen_to_search_for_context(window, sspreadsheet);
- LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
- SpaceLink *sl = (SpaceLink *)area->spacedata.first;
- if (sl == nullptr) {
- continue;
- }
- if (sl->spacetype != SPACE_NODE) {
- continue;
- }
- SpaceNode *snode = (SpaceNode *)sl;
- if (snode->nodetree != root_node_tree) {
- continue;
- }
- if (!modifier_is_active) {
- if (!(snode->flag & SNODE_PIN)) {
- /* Node tree has to be pinned when the modifier is not active. */
- continue;
- }
- }
- if (snode->id != &object->id) {
- continue;
- }
- Vector<bNodeTreePath *> tree_path = snode->treepath;
- if (node_context_path.size() != tree_path.size()) {
- continue;
- }
- int valid_count = 0;
- for (const int i : IndexRange(tree_path.size() - 1)) {
- if (node_context_path[i]->type != SPREADSHEET_CONTEXT_NODE) {
- break;
- }
- SpreadsheetContextNode *node_context = (SpreadsheetContextNode *)node_context_path[i];
- if (!STREQ(node_context->node_name, tree_path[i + 1]->node_name)) {
- break;
- }
- valid_count++;
- }
- if (valid_count != tree_path.size() - 1) {
- continue;
- }
- SpreadsheetContext *last_context = node_context_path.last();
- if (last_context->type != SPREADSHEET_CONTEXT_NODE) {
- return false;
- }
- const char *node_name = ((SpreadsheetContextNode *)last_context)->node_name;
- bNode *node = nodeFindNodebyName(snode->edittree, node_name);
- if (node == nullptr) {
- return false;
- }
- if (node->type != GEO_NODE_VIEWER) {
- return false;
- }
- if (!(node->flag & NODE_DO_OUTPUT)) {
- return false;
- }
- return true;
- }
- }
- return false;
-}
-
-bool ED_spreadsheet_context_path_exists(Main *UNUSED(bmain), SpaceSpreadsheet *sspreadsheet)
-{
- Vector<SpreadsheetContext *> context_path = sspreadsheet->context_path;
- if (context_path.is_empty()) {
- return false;
- }
- if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) {
- return false;
- }
- Object *object = ((SpreadsheetContextObject *)context_path[0])->object;
- if (object == nullptr) {
- return false;
- }
- if (context_path.size() == 1) {
- return true;
- }
- if (context_path[1]->type != SPREADSHEET_CONTEXT_MODIFIER) {
- return false;
- }
- const char *modifier_name = ((SpreadsheetContextModifier *)context_path[1])->modifier_name;
- const ModifierData *modifier = BKE_modifiers_findby_name(object, modifier_name);
- if (modifier == nullptr) {
- return false;
- }
- if (modifier->type != eModifierType_Nodes) {
- return false;
- }
- bNodeTree *root_node_tree = ((NodesModifierData *)modifier)->node_group;
- if (root_node_tree == nullptr) {
- return false;
- }
- const Span<SpreadsheetContext *> node_context_path = context_path.as_span().drop_front(2);
- if (node_context_path.is_empty()) {
- return false;
- }
- bNodeTree *node_tree = root_node_tree;
- for (const int i : node_context_path.index_range()) {
- if (node_context_path[i]->type != SPREADSHEET_CONTEXT_NODE) {
- return false;
- }
- const char *node_name = ((SpreadsheetContextNode *)node_context_path[i])->node_name;
- bNode *node = nodeFindNodebyName(node_tree, node_name);
- if (node == nullptr) {
- return false;
- }
- if (node->type == GEO_NODE_VIEWER) {
- if (i == node_context_path.index_range().last()) {
- return true;
- }
- return false;
- }
- if (node->id != nullptr) {
- if (GS(node->id->name) != ID_NT) {
- return false;
- }
- node_tree = (bNodeTree *)node->id;
- }
- else {
- return false;
- }
- }
- return false;
-}
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_context.hh b/source/blender/editors/space_spreadsheet/spreadsheet_context.hh
deleted file mode 100644
index 758ae392894..00000000000
--- a/source/blender/editors/space_spreadsheet/spreadsheet_context.hh
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#pragma once
-
-#include "DNA_space_types.h"
-
-namespace blender::ed::spreadsheet {
-
-SpreadsheetContext *spreadsheet_context_new(eSpaceSpreadsheet_ContextType type);
-SpreadsheetContext *spreadsheet_context_copy(const SpreadsheetContext *old_context);
-void spreadsheet_context_free(SpreadsheetContext *context);
-
-} // namespace blender::ed::spreadsheet
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
index 4703eacdcb9..59a8daf4f4a 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
@@ -10,6 +10,7 @@
#include "BKE_editmesh.h"
#include "BKE_geometry_fields.hh"
#include "BKE_global.h"
+#include "BKE_instances.hh"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh_wrapper.h"
@@ -98,7 +99,8 @@ void GeometryDataSource::foreach_default_column_ids(
}
SpreadsheetColumnID column_id;
column_id.name = (char *)attribute_id.name().data();
- fn(column_id, false);
+ const bool is_front = attribute_id.name() == ".viewer";
+ fn(column_id, is_front);
return true;
});
@@ -142,29 +144,31 @@ std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
}
if (component_->type() == GEO_COMPONENT_TYPE_INSTANCES) {
- const InstancesComponent &instances = static_cast<const InstancesComponent &>(*component_);
- if (STREQ(column_id.name, "Name")) {
- Span<int> reference_handles = instances.instance_reference_handles();
- Span<InstanceReference> references = instances.references();
- return std::make_unique<ColumnValues>(
- column_id.name,
- VArray<InstanceReference>::ForFunc(domain_num,
- [reference_handles, references](int64_t index) {
- return references[reference_handles[index]];
- }));
- }
- Span<float4x4> transforms = instances.instance_transforms();
- if (STREQ(column_id.name, "Rotation")) {
- return std::make_unique<ColumnValues>(
- column_id.name, VArray<float3>::ForFunc(domain_num, [transforms](int64_t index) {
- return transforms[index].to_euler();
- }));
- }
- if (STREQ(column_id.name, "Scale")) {
- return std::make_unique<ColumnValues>(
- column_id.name, VArray<float3>::ForFunc(domain_num, [transforms](int64_t index) {
- return transforms[index].scale();
- }));
+ if (const bke::Instances *instances =
+ static_cast<const InstancesComponent &>(*component_).get_for_read()) {
+ if (STREQ(column_id.name, "Name")) {
+ Span<int> reference_handles = instances->reference_handles();
+ Span<bke::InstanceReference> references = instances->references();
+ return std::make_unique<ColumnValues>(
+ column_id.name,
+ VArray<bke::InstanceReference>::ForFunc(
+ domain_num, [reference_handles, references](int64_t index) {
+ return references[reference_handles[index]];
+ }));
+ }
+ Span<float4x4> transforms = instances->transforms();
+ if (STREQ(column_id.name, "Rotation")) {
+ return std::make_unique<ColumnValues>(
+ column_id.name, VArray<float3>::ForFunc(domain_num, [transforms](int64_t index) {
+ return transforms[index].to_euler();
+ }));
+ }
+ if (STREQ(column_id.name, "Scale")) {
+ return std::make_unique<ColumnValues>(
+ column_id.name, VArray<float3>::ForFunc(domain_num, [transforms](int64_t index) {
+ return transforms[index].scale();
+ }));
+ }
}
}
else if (G.debug_value == 4001 && component_->type() == GEO_COMPONENT_TYPE_MESH) {
@@ -228,7 +232,12 @@ std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
return {};
}
- return std::make_unique<ColumnValues>(column_id.name, std::move(varray));
+ StringRefNull column_display_name = column_id.name;
+ if (column_display_name == ".viewer") {
+ column_display_name = "Viewer";
+ }
+
+ return std::make_unique<ColumnValues>(column_display_name, std::move(varray));
}
int GeometryDataSource::tot_rows() const
@@ -271,6 +280,9 @@ IndexMask GeometryDataSource::apply_selection_filter(Vector<int64_t> &indices) c
{
std::lock_guard lock{mutex_};
const IndexMask full_range(this->tot_rows());
+ if (full_range.is_empty()) {
+ return full_range;
+ }
switch (component_->type()) {
case GEO_COMPONENT_TYPE_MESH: {
@@ -460,7 +472,7 @@ GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspread
mesh_component.replace(mesh, GeometryOwnershipType::ReadOnly);
}
else {
- if (BLI_listbase_count(&sspreadsheet->context_path) == 1) {
+ if (BLI_listbase_count(&sspreadsheet->viewer_path.path) == 1) {
/* Use final evaluated object. */
if (object_eval->runtime.geometry_set_eval != nullptr) {
geometry_set = *object_eval->runtime.geometry_set_eval;
@@ -468,8 +480,8 @@ GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspread
}
else {
if (const ViewerNodeLog *viewer_log =
- nodes::geo_eval_log::GeoModifierLog::find_viewer_node_log_for_spreadsheet(
- *sspreadsheet)) {
+ nodes::geo_eval_log::GeoModifierLog::find_viewer_node_log_for_path(
+ sspreadsheet->viewer_path)) {
geometry_set = viewer_log->geometry;
}
}
@@ -478,88 +490,6 @@ GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspread
return geometry_set;
}
-static void find_fields_to_evaluate(const SpaceSpreadsheet *sspreadsheet,
- Map<std::string, GField> &r_fields)
-{
- if (sspreadsheet->object_eval_state != SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) {
- return;
- }
- if (BLI_listbase_count(&sspreadsheet->context_path) <= 1) {
- /* No viewer is currently referenced by the context path. */
- return;
- }
- if (const ViewerNodeLog *viewer_log =
- nodes::geo_eval_log::GeoModifierLog::find_viewer_node_log_for_spreadsheet(
- *sspreadsheet)) {
- if (viewer_log->field) {
- r_fields.add("Viewer", viewer_log->field);
- }
- }
-}
-
-class GeometryComponentCacheKey : public SpreadsheetCache::Key {
- public:
- /* Use the pointer to the geometry component as a key to detect when the geometry changed. */
- const GeometryComponent *component;
-
- GeometryComponentCacheKey(const GeometryComponent &component) : component(&component)
- {
- }
-
- uint64_t hash() const override
- {
- return get_default_hash(this->component);
- }
-
- bool is_equal_to(const Key &other) const override
- {
- if (const GeometryComponentCacheKey *other_geo =
- dynamic_cast<const GeometryComponentCacheKey *>(&other)) {
- return this->component == other_geo->component;
- }
- return false;
- }
-};
-
-class GeometryComponentCacheValue : public SpreadsheetCache::Value {
- public:
- /* Stores the result of fields evaluated on a geometry component. Without this, fields would have
- * to be reevaluated on every redraw. */
- Map<std::pair<eAttrDomain, GField>, GArray<>> arrays;
-};
-
-static void add_fields_as_extra_columns(SpaceSpreadsheet *sspreadsheet,
- const GeometryComponent &component,
- ExtraColumns &r_extra_columns)
-{
- Map<std::string, GField> fields_to_show;
- find_fields_to_evaluate(sspreadsheet, fields_to_show);
-
- GeometryComponentCacheValue &cache =
- sspreadsheet->runtime->cache.lookup_or_add<GeometryComponentCacheValue>(
- std::make_unique<GeometryComponentCacheKey>(component));
-
- const eAttrDomain domain = (eAttrDomain)sspreadsheet->attribute_domain;
- const int domain_num = component.attribute_domain_size(domain);
- for (const auto item : fields_to_show.items()) {
- const StringRef name = item.key;
- const GField &field = item.value;
-
- /* Use the cached evaluated array if it exists, otherwise evaluate the field now. */
- GArray<> &evaluated_array = cache.arrays.lookup_or_add_cb({domain, field}, [&]() {
- GArray<> evaluated_array(field.cpp_type(), domain_num);
-
- bke::GeometryFieldContext field_context{component, domain};
- fn::FieldEvaluator field_evaluator{field_context, domain_num};
- field_evaluator.add_with_destination(field, evaluated_array);
- field_evaluator.evaluate();
- return evaluated_array;
- });
-
- r_extra_columns.add(name, evaluated_array.as_span());
- }
-}
-
std::unique_ptr<DataSource> data_source_from_geometry(const bContext *C, Object *object_eval)
{
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
@@ -571,15 +501,11 @@ std::unique_ptr<DataSource> data_source_from_geometry(const bContext *C, Object
return {};
}
- const GeometryComponent &component = *geometry_set.get_component_for_read(component_type);
- ExtraColumns extra_columns;
- add_fields_as_extra_columns(sspreadsheet, component, extra_columns);
-
if (component_type == GEO_COMPONENT_TYPE_VOLUME) {
return std::make_unique<VolumeDataSource>(std::move(geometry_set));
}
return std::make_unique<GeometryDataSource>(
- object_eval, std::move(geometry_set), component_type, domain, std::move(extra_columns));
+ object_eval, std::move(geometry_set), component_type, domain);
}
} // namespace blender::ed::spreadsheet
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh
index 71bc4768949..478b3372427 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh
@@ -54,7 +54,7 @@ class GeometryDataSource : public DataSource {
GeometrySet geometry_set,
const GeometryComponentType component_type,
const eAttrDomain domain,
- ExtraColumns extra_columns)
+ ExtraColumns extra_columns = {})
: object_eval_(object_eval),
geometry_set_(std::move(geometry_set)),
component_(geometry_set_.get_component_for_read(component_type)),
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_draw.cc b/source/blender/editors/space_spreadsheet/spreadsheet_draw.cc
index e1f13f05715..e50e655853f 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_draw.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_draw.cc
@@ -26,23 +26,23 @@ SpreadsheetDrawer::SpreadsheetDrawer()
SpreadsheetDrawer::~SpreadsheetDrawer() = default;
-void SpreadsheetDrawer::draw_top_row_cell(int UNUSED(column_index),
- const CellDrawParams &UNUSED(params)) const
+void SpreadsheetDrawer::draw_top_row_cell(int /*column_index*/,
+ const CellDrawParams & /*params*/) const
{
}
-void SpreadsheetDrawer::draw_left_column_cell(int UNUSED(row_index),
- const CellDrawParams &UNUSED(params)) const
+void SpreadsheetDrawer::draw_left_column_cell(int /*row_index*/,
+ const CellDrawParams & /*params*/) const
{
}
-void SpreadsheetDrawer::draw_content_cell(int UNUSED(row_index),
- int UNUSED(column_index),
- const CellDrawParams &UNUSED(params)) const
+void SpreadsheetDrawer::draw_content_cell(int /*row_index*/,
+ int /*column_index*/,
+ const CellDrawParams & /*params*/) const
{
}
-int SpreadsheetDrawer::column_width(int UNUSED(column_index)) const
+int SpreadsheetDrawer::column_width(int /*column_index*/) const
{
return 5 * UI_UNIT_X;
}
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc
index 3fe4c7c8ee0..06eb338bd00 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc
@@ -6,6 +6,7 @@
#include "BLI_math_vec_types.hh"
#include "BKE_geometry_set.hh"
+#include "BKE_instances.hh"
#include "spreadsheet_column_values.hh"
#include "spreadsheet_layout.hh"
@@ -197,10 +198,10 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer {
const ColorGeometry4b value = data.get<ColorGeometry4b>(real_index);
this->draw_byte_color(params, value);
}
- else if (data.type().is<InstanceReference>()) {
- const InstanceReference value = data.get<InstanceReference>(real_index);
+ else if (data.type().is<bke::InstanceReference>()) {
+ const bke::InstanceReference value = data.get<bke::InstanceReference>(real_index);
switch (value.type()) {
- case InstanceReference::Type::Object: {
+ case bke::InstanceReference::Type::Object: {
const Object &object = value.object();
uiDefIconTextBut(params.block,
UI_BTYPE_LABEL,
@@ -219,7 +220,7 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer {
nullptr);
break;
}
- case InstanceReference::Type::Collection: {
+ case bke::InstanceReference::Type::Collection: {
Collection &collection = value.collection();
uiDefIconTextBut(params.block,
UI_BTYPE_LABEL,
@@ -238,7 +239,7 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer {
nullptr);
break;
}
- case InstanceReference::Type::GeometrySet: {
+ case bke::InstanceReference::Type::GeometrySet: {
uiDefIconTextBut(params.block,
UI_BTYPE_LABEL,
0,
@@ -256,7 +257,7 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer {
nullptr);
break;
}
- case InstanceReference::Type::None: {
+ case bke::InstanceReference::Type::None: {
break;
}
}
@@ -283,7 +284,7 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer {
void draw_float_vector(const CellDrawParams &params, const Span<float> values) const
{
BLI_assert(!values.is_empty());
- const float segment_width = (float)params.width / values.size();
+ const float segment_width = float(params.width) / values.size();
for (const int i : values.index_range()) {
std::stringstream ss;
const float value = values[i];
@@ -314,7 +315,7 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer {
{
const ColorGeometry4f float_color = color.decode();
Span<float> values(&float_color.r, 4);
- const float segment_width = (float)params.width / values.size();
+ const float segment_width = float(params.width) / values.size();
for (const int i : values.index_range()) {
std::stringstream ss;
const float value = values[i];
@@ -342,7 +343,7 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer {
/* Tooltip showing raw byte values. Encode values in pointer to avoid memory allocation. */
UI_but_func_tooltip_set(
but,
- [](bContext * /*C*/, void *argN, const char *UNUSED(tip)) {
+ [](bContext * /*C*/, void *argN, const char * /*tip*/) {
const uint32_t uint_color = POINTER_AS_UINT(argN);
ColorGeometry4b color = *(ColorGeometry4b *)&uint_color;
return BLI_sprintfN(TIP_("Byte Color (sRGB encoded):\n%3d %3d %3d %3d"),
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc b/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc
index 166c5de9fc3..baa58a7d824 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc
@@ -22,7 +22,7 @@
using namespace blender::ed::spreadsheet;
-static int row_filter_add_exec(bContext *C, wmOperator *UNUSED(op))
+static int row_filter_add_exec(bContext *C, wmOperator * /*op*/)
{
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
@@ -78,9 +78,7 @@ static void SPREADSHEET_OT_remove_row_filter_rule(wmOperatorType *ot)
RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, INT_MAX);
}
-static int select_component_domain_invoke(bContext *C,
- wmOperator *op,
- const wmEvent *UNUSED(event))
+static int select_component_domain_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
GeometryComponentType component_type = static_cast<GeometryComponentType>(
RNA_int_get(op->ptr, "component_type"));
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc
index 03cf0116dce..3586389b00b 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc
@@ -14,6 +14,8 @@
#include "RNA_access.h"
+#include "BKE_instances.hh"
+
#include "spreadsheet_data_source_geometry.hh"
#include "spreadsheet_intern.hh"
#include "spreadsheet_layout.hh"
@@ -242,14 +244,14 @@ static void apply_row_filter(const SpreadsheetRowFilter &row_filter,
switch (row_filter.operation) {
case SPREADSHEET_ROW_FILTER_EQUAL: {
const float4 value_floats = {
- (float)value.r, (float)value.g, (float)value.b, (float)value.a};
+ float(value.r), float(value.g), float(value.b), float(value.a)};
const float threshold_sq = pow2f(row_filter.threshold);
apply_filter_operation(
column_data.typed<ColorGeometry4b>(),
[&](const ColorGeometry4b cell_bytes) {
const ColorGeometry4f cell = cell_bytes.decode();
const float4 cell_floats = {
- (float)cell.r, (float)cell.g, (float)cell.b, (float)cell.a};
+ float(cell.r), float(cell.g), float(cell.b), float(cell.a)};
return len_squared_v4v4(value_floats, cell_floats) <= threshold_sq;
},
prev_mask,
@@ -280,22 +282,22 @@ static void apply_row_filter(const SpreadsheetRowFilter &row_filter,
}
}
}
- else if (column_data.type().is<InstanceReference>()) {
+ else if (column_data.type().is<bke::InstanceReference>()) {
const StringRef value = row_filter.value_string;
apply_filter_operation(
- column_data.typed<InstanceReference>(),
- [&](const InstanceReference cell) {
+ column_data.typed<bke::InstanceReference>(),
+ [&](const bke::InstanceReference cell) {
switch (cell.type()) {
- case InstanceReference::Type::Object: {
+ case bke::InstanceReference::Type::Object: {
return value == (reinterpret_cast<ID &>(cell.object()).name + 2);
}
- case InstanceReference::Type::Collection: {
+ case bke::InstanceReference::Type::Collection: {
return value == (reinterpret_cast<ID &>(cell.collection()).name + 2);
}
- case InstanceReference::Type::GeometrySet: {
+ case bke::InstanceReference::Type::GeometrySet: {
return false;
}
- case InstanceReference::Type::None: {
+ case bke::InstanceReference::Type::None: {
return false;
}
}
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc
index 548e6cf29e4..fa22da4f26a 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc
@@ -30,7 +30,7 @@
using namespace blender;
using namespace blender::ed::spreadsheet;
-static void filter_panel_id_fn(void *UNUSED(row_filter_v), char *r_name)
+static void filter_panel_id_fn(void * /*row_filter_v*/, char *r_name)
{
/* All row filters use the same panel ID. */
BLI_snprintf(r_name, BKE_ST_MAXNAME, "SPREADSHEET_PT_filter");
@@ -304,15 +304,15 @@ static void filter_reorder(bContext *C, Panel *panel, int new_index)
BLI_listbase_link_move(row_filters, filter, new_index - current_index);
}
-static short get_filter_expand_flag(const bContext *UNUSED(C), Panel *panel)
+static short get_filter_expand_flag(const bContext * /*C*/, Panel *panel)
{
PointerRNA *filter_ptr = UI_panel_custom_data_get(panel);
SpreadsheetRowFilter *filter = (SpreadsheetRowFilter *)filter_ptr->data;
- return (short)filter->flag & SPREADSHEET_ROW_FILTER_UI_EXPAND;
+ return short(filter->flag) & SPREADSHEET_ROW_FILTER_UI_EXPAND;
}
-static void set_filter_expand_flag(const bContext *UNUSED(C), Panel *panel, short expand_flag)
+static void set_filter_expand_flag(const bContext * /*C*/, Panel *panel, short expand_flag)
{
PointerRNA *filter_ptr = UI_panel_custom_data_get(panel);
SpreadsheetRowFilter *filter = (SpreadsheetRowFilter *)filter_ptr->data;
diff --git a/source/blender/editors/space_statusbar/CMakeLists.txt b/source/blender/editors/space_statusbar/CMakeLists.txt
index cf0ccd4e552..f73e03815a3 100644
--- a/source/blender/editors/space_statusbar/CMakeLists.txt
+++ b/source/blender/editors/space_statusbar/CMakeLists.txt
@@ -11,6 +11,9 @@ set(INC
../../makesrna
../../windowmanager
../../../../intern/guardedalloc
+
+ # dna_type_offsets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
# RNA_prototypes.h
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
@@ -28,5 +31,5 @@ set(LIB
blender_add_lib(bf_editor_space_statusbar "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
-# RNA_prototypes.h
+# RNA_prototypes.h dna_type_offsets.h
add_dependencies(bf_editor_space_statusbar bf_rna)
diff --git a/source/blender/editors/space_statusbar/space_statusbar.c b/source/blender/editors/space_statusbar/space_statusbar.c
index e99e8f21364..e82eeeed93a 100644
--- a/source/blender/editors/space_statusbar/space_statusbar.c
+++ b/source/blender/editors/space_statusbar/space_statusbar.c
@@ -21,6 +21,8 @@
#include "UI_interface.h"
+#include "BLO_read_write.h"
+
#include "WM_api.h"
#include "WM_message.h"
#include "WM_types.h"
@@ -130,6 +132,11 @@ static void statusbar_header_region_message_subscribe(const wmRegionMessageSubsc
WM_msg_subscribe_rna_anon_prop(mbus, ViewLayer, name, &msg_sub_value_region_tag_redraw);
}
+static void statusbar_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ BLO_write_struct(writer, SpaceStatusBar, sl);
+}
+
void ED_spacetype_statusbar(void)
{
SpaceType *st = MEM_callocN(sizeof(*st), "spacetype statusbar");
@@ -144,6 +151,7 @@ void ED_spacetype_statusbar(void)
st->duplicate = statusbar_duplicate;
st->operatortypes = statusbar_operatortypes;
st->keymap = statusbar_keymap;
+ st->blend_write = statusbar_blend_write;
/* regions: header window */
art = MEM_callocN(sizeof(*art), "spacetype statusbar header region");
diff --git a/source/blender/editors/space_text/CMakeLists.txt b/source/blender/editors/space_text/CMakeLists.txt
index 38787a84fce..dfd6111e067 100644
--- a/source/blender/editors/space_text/CMakeLists.txt
+++ b/source/blender/editors/space_text/CMakeLists.txt
@@ -5,12 +5,16 @@ set(INC
../../blenfont
../../blenkernel
../../blenlib
+ ../../blenloader
../../blentranslation
../../gpu
../../makesdna
../../makesrna
../../windowmanager
../../../../intern/guardedalloc
+
+ # dna_type_offsets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
)
@@ -47,3 +51,6 @@ endif()
blender_add_lib(bf_editor_space_text "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
+
+# dna_type_offsets.h
+add_dependencies(bf_editor_space_text bf_dna)
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index be9bbdf109e..5b9b3651459 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -29,6 +29,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "BLO_read_write.h"
+
#include "RNA_access.h"
#include "RNA_path.h"
@@ -395,6 +397,23 @@ static void text_id_remap(ScrArea *UNUSED(area),
BKE_id_remapper_apply(mappings, (ID **)&stext->text, ID_REMAP_APPLY_ENSURE_REAL);
}
+static void text_blend_read_data(BlendDataReader *UNUSED(reader), SpaceLink *sl)
+{
+ SpaceText *st = (SpaceText *)sl;
+ memset(&st->runtime, 0x0, sizeof(st->runtime));
+}
+
+static void text_blend_read_lib(BlendLibReader *reader, ID *parent_id, SpaceLink *sl)
+{
+ SpaceText *st = (SpaceText *)sl;
+ BLO_read_id_address(reader, parent_id->lib, &st->text);
+}
+
+static void text_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ BLO_write_struct(writer, SpaceText, sl);
+}
+
/********************* registration ********************/
void ED_spacetype_text(void)
@@ -415,6 +434,9 @@ void ED_spacetype_text(void)
st->context = text_context;
st->dropboxes = text_dropboxes;
st->id_remap = text_id_remap;
+ st->blend_read_data = text_blend_read_data;
+ st->blend_read_lib = text_blend_read_lib;
+ st->blend_write = text_blend_write;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype text region");
diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c
index 461606f63aa..db4fc7da9dc 100644
--- a/source/blender/editors/space_text/text_autocomplete.c
+++ b/source/blender/editors/space_text/text_autocomplete.c
@@ -162,13 +162,13 @@ static GHash *text_autocomplete_build(Text *text)
/* seek identifier beginning */
i_pos = i_start;
while ((i_start < linep->len) &&
- (!text_check_identifier_nodigit_unicode(
- BLI_str_utf8_as_unicode_step(linep->line, linep->len, &i_pos)))) {
+ !text_check_identifier_nodigit_unicode(
+ BLI_str_utf8_as_unicode_step(linep->line, linep->len, &i_pos))) {
i_start = i_pos;
}
i_pos = i_end = i_start;
- while ((i_end < linep->len) && (text_check_identifier_unicode(BLI_str_utf8_as_unicode_step(
- linep->line, linep->len, &i_pos)))) {
+ while ((i_end < linep->len) && text_check_identifier_unicode(BLI_str_utf8_as_unicode_step(
+ linep->line, linep->len, &i_pos))) {
i_end = i_pos;
}
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 46c459dd0bc..3cff9a25bba 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -57,7 +57,7 @@ static void text_draw_context_init(const SpaceText *st, TextDrawContext *tdc)
static void text_font_begin(const TextDrawContext *tdc)
{
- BLF_size(tdc->font_id, (float)tdc->lheight_px, 72);
+ BLF_size(tdc->font_id, (float)tdc->lheight_px);
}
static void text_font_end(const TextDrawContext *UNUSED(tdc))
@@ -925,12 +925,12 @@ static void calc_text_rcts(SpaceText *st, ARegion *region, rcti *scroll, rcti *b
hlstart = (lhlstart * pix_available) / ltexth;
hlend = (lhlend * pix_available) / ltexth;
- /* The scrollbar is non-linear sized. */
+ /* The scroll-bar is non-linear sized. */
if (pix_bardiff > 0) {
/* the start of the highlight is in the current viewport */
if (st->runtime.viewlines && lhlstart >= st->top &&
lhlstart <= st->top + st->runtime.viewlines) {
- /* Speed the progression of the start of the highlight through the scrollbar. */
+ /* Speed the progression of the start of the highlight through the scroll-bar. */
hlstart = (((pix_available - pix_bardiff) * lhlstart) / ltexth) +
(pix_bardiff * (lhlstart - st->top) / st->runtime.viewlines);
}
@@ -951,7 +951,7 @@ static void calc_text_rcts(SpaceText *st, ARegion *region, rcti *scroll, rcti *b
/* the end of the highlight is in the current viewport */
if (st->runtime.viewlines && lhlend >= st->top &&
lhlend <= st->top + st->runtime.viewlines) {
- /* Speed the progression of the end of the highlight through the scrollbar. */
+ /* Speed the progression of the end of the highlight through the scroll-bar. */
hlend = (((pix_available - pix_bardiff) * lhlend) / ltexth) +
(pix_bardiff * (lhlend - st->top) / st->runtime.viewlines);
}
@@ -994,7 +994,7 @@ static void draw_textscroll(const SpaceText *st, rcti *scroll, rcti *back)
float col[4];
float rad;
- /* background so highlights don't go behind the scrollbar */
+ /* Background so highlights don't go behind the scroll-bar. */
uint pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
diff --git a/source/blender/editors/space_text/text_format_py.c b/source/blender/editors/space_text/text_format_py.c
index 28f536ffa98..6aff8c7b966 100644
--- a/source/blender/editors/space_text/text_format_py.c
+++ b/source/blender/editors/space_text/text_format_py.c
@@ -226,7 +226,7 @@ static uint txtfmt_py_numeral_string_count_hexadecimal(const char *string)
/* Zeros. */
static bool txtfmt_py_numeral_char_is_zero(const char c)
{
- return (ELEM(c, '0', '_'));
+ return ELEM(c, '0', '_');
}
static uint txtfmt_py_numeral_string_count_zeros(const char *string)
{
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index f0196bf8e00..0ddd06ead62 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -3487,10 +3487,10 @@ static int text_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* NOTE: the "text" property is always set from key-map,
* so we can't use #RNA_struct_property_is_set, check the length instead. */
if (!RNA_string_length(op->ptr, "text")) {
- /* if alt/ctrl/super are pressed pass through except for utf8 character event
+ /* If Alt/Control/Super are pressed pass through except for utf8 character event
* (when input method are used for utf8 inputs, the user may assign key event
- * including alt/ctrl/super like ctrl+m to commit utf8 string. in such case,
- * the modifiers in the utf8 character event make no sense.) */
+ * including Alt/Control/Super like Control-M to commit utf8 string.
+ * In such case, the modifiers in the utf8 character event make no sense). */
if ((event->modifier & (KM_CTRL | KM_OSKEY)) && !event->utf8_buf[0]) {
return OPERATOR_PASS_THROUGH;
}
diff --git a/source/blender/editors/space_topbar/CMakeLists.txt b/source/blender/editors/space_topbar/CMakeLists.txt
index f529c855e6d..a0854bd688c 100644
--- a/source/blender/editors/space_topbar/CMakeLists.txt
+++ b/source/blender/editors/space_topbar/CMakeLists.txt
@@ -11,6 +11,9 @@ set(INC
../../makesrna
../../windowmanager
../../../../intern/guardedalloc
+
+ # dna_type_offsets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
# RNA_prototypes.h
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
@@ -27,5 +30,5 @@ set(LIB
blender_add_lib(bf_editor_space_topbar "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
-# RNA_prototypes.h
+# RNA_prototypes.h dna_type_offsets.h
add_dependencies(bf_editor_space_topbar bf_rna)
diff --git a/source/blender/editors/space_topbar/space_topbar.c b/source/blender/editors/space_topbar/space_topbar.c
index e4826ed5964..aa5689bd047 100644
--- a/source/blender/editors/space_topbar/space_topbar.c
+++ b/source/blender/editors/space_topbar/space_topbar.c
@@ -28,6 +28,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "BLO_read_write.h"
+
#include "RNA_access.h"
#include "WM_api.h"
@@ -282,6 +284,11 @@ static void undo_history_menu_register(void)
WM_menutype_add(mt);
}
+static void topbar_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ BLO_write_struct(writer, SpaceTopBar, sl);
+}
+
void ED_spacetype_topbar(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype topbar");
@@ -296,6 +303,7 @@ void ED_spacetype_topbar(void)
st->duplicate = topbar_duplicate;
st->operatortypes = topbar_operatortypes;
st->keymap = topbar_keymap;
+ st->blend_write = topbar_blend_write;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype topbar main region");
diff --git a/source/blender/editors/space_userpref/CMakeLists.txt b/source/blender/editors/space_userpref/CMakeLists.txt
index 37408dd85af..e75d5b28ffd 100644
--- a/source/blender/editors/space_userpref/CMakeLists.txt
+++ b/source/blender/editors/space_userpref/CMakeLists.txt
@@ -4,10 +4,14 @@ set(INC
../include
../../blenkernel
../../blenlib
+ ../../blenloader
../../makesdna
../../makesrna
../../windowmanager
../../../../intern/guardedalloc
+
+ # dna_type_offsets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
)
set(INC_SYS
@@ -25,3 +29,6 @@ set(LIB
)
blender_add_lib(bf_editor_space_userpref "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
+
+# dna_type_offsets.h
+add_dependencies(bf_editor_space_userpref bf_dna)
diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c
index 06a4c1d8702..1516435c6fc 100644
--- a/source/blender/editors/space_userpref/space_userpref.c
+++ b/source/blender/editors/space_userpref/space_userpref.c
@@ -27,6 +27,8 @@
#include "UI_interface.h"
+#include "BLO_read_write.h"
+
/* ******************** default callbacks for userpref space ***************** */
static SpaceLink *userpref_create(const ScrArea *area, const Scene *UNUSED(scene))
@@ -183,6 +185,11 @@ static void userpref_execute_region_listener(const wmRegionListenerParams *UNUSE
{
}
+static void userpref_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ BLO_write_struct(writer, SpaceUserPref, sl);
+}
+
void ED_spacetype_userpref(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype userpref");
@@ -197,6 +204,7 @@ void ED_spacetype_userpref(void)
st->duplicate = userpref_duplicate;
st->operatortypes = userpref_operatortypes;
st->keymap = userpref_keymap;
+ st->blend_write = userpref_blend_write;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype userpref region");
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt
index 100266f4433..579e27b9259 100644
--- a/source/blender/editors/space_view3d/CMakeLists.txt
+++ b/source/blender/editors/space_view3d/CMakeLists.txt
@@ -5,6 +5,7 @@ set(INC
../../blenfont
../../blenkernel
../../blenlib
+ ../../blenloader
../../blentranslation
../../bmesh
../../depsgraph
@@ -27,11 +28,11 @@ set(INC
set(SRC
drawobject.c
- space_view3d.c
+ space_view3d.cc
view3d_buttons.c
view3d_camera_control.c
view3d_cursor_snap.c
- view3d_draw.c
+ view3d_draw.cc
view3d_edit.c
view3d_gizmo_armature.c
view3d_gizmo_camera.c
@@ -41,11 +42,11 @@ set(SRC
view3d_gizmo_navigate.c
view3d_gizmo_navigate_type.c
view3d_gizmo_preselect.c
- view3d_gizmo_preselect_type.c
+ view3d_gizmo_preselect_type.cc
view3d_gizmo_ruler.c
view3d_gizmo_tool_generic.c
view3d_header.c
- view3d_iterators.c
+ view3d_iterators.cc
view3d_navigate.c
view3d_navigate_dolly.c
view3d_navigate_fly.c
@@ -75,7 +76,7 @@ set(LIB
)
if(WITH_PYTHON)
- blender_include_dirs(../../python)
+ list(APPEND INC ../../python)
add_definitions(-DWITH_PYTHON)
endif()
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 36ced74a8b7..6370d56ae8c 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -17,6 +17,7 @@
#include "BKE_editmesh.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_object.h"
#include "DEG_depsgraph.h"
@@ -94,8 +95,8 @@ void ED_draw_object_facemap(Depsgraph *depsgraph,
const MPoly *mp;
int i;
- if (me->runtime.looptris.array) {
- const MLoopTri *mlt = me->runtime.looptris.array;
+ if (BKE_mesh_runtime_looptri_ensure(me)) {
+ const MLoopTri *mlt = BKE_mesh_runtime_looptri_ensure(me);
for (mp = polys, i = 0; i < mpoly_len; i++, mp++) {
if (facemap_data[i] == facemap) {
for (int j = 2; j < mp->totloop; j++) {
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.cc
index 860bb604270..05fb0c6a720 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.cc
@@ -5,8 +5,11 @@
* \ingroup spview3d
*/
-#include <stdio.h>
-#include <string.h>
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
+#include <cstdio>
+#include <cstring>
#include "DNA_collection_types.h"
#include "DNA_defaults.h"
@@ -29,6 +32,7 @@
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_global.h"
+#include "BKE_gpencil.h"
#include "BKE_icons.h"
#include "BKE_idprop.h"
#include "BKE_lattice.h"
@@ -40,6 +44,7 @@
#include "BKE_object.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
+#include "BKE_viewer_path.h"
#include "BKE_workspace.h"
#include "ED_object.h"
@@ -49,6 +54,7 @@
#include "ED_space_api.h"
#include "ED_transform.h"
#include "ED_undo.h"
+#include "ED_viewer_path.hh"
#include "GPU_matrix.h"
@@ -67,6 +73,8 @@
#include "UI_interface.h"
#include "UI_resources.h"
+#include "BLO_read_write.h"
+
#ifdef WITH_PYTHON
# include "BPY_extern.h"
#endif
@@ -83,12 +91,12 @@ RegionView3D *ED_view3d_context_rv3d(bContext *C)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
- if (rv3d == NULL) {
+ if (rv3d == nullptr) {
ScrArea *area = CTX_wm_area(C);
if (area && area->spacetype == SPACE_VIEW3D) {
ARegion *region = BKE_area_find_region_active_win(area);
if (region) {
- rv3d = region->regiondata;
+ rv3d = static_cast<RegionView3D *>(region->regiondata);
}
}
}
@@ -99,8 +107,8 @@ bool ED_view3d_context_user_region(bContext *C, View3D **r_v3d, ARegion **r_regi
{
ScrArea *area = CTX_wm_area(C);
- *r_v3d = NULL;
- *r_region = NULL;
+ *r_v3d = nullptr;
+ *r_region = nullptr;
if (area && area->spacetype == SPACE_VIEW3D) {
ARegion *region = CTX_wm_region(C);
@@ -108,7 +116,8 @@ bool ED_view3d_context_user_region(bContext *C, View3D **r_v3d, ARegion **r_regi
if (region) {
RegionView3D *rv3d;
- if ((region->regiontype == RGN_TYPE_WINDOW) && (rv3d = region->regiondata) &&
+ if ((region->regiontype == RGN_TYPE_WINDOW) &&
+ (rv3d = static_cast<RegionView3D *>(region->regiondata)) &&
(rv3d->viewlock & RV3D_LOCK_ROTATION) == 0) {
*r_v3d = v3d;
*r_region = region;
@@ -127,9 +136,9 @@ bool ED_view3d_context_user_region(bContext *C, View3D **r_v3d, ARegion **r_regi
bool ED_view3d_area_user_region(const ScrArea *area, const View3D *v3d, ARegion **r_region)
{
- RegionView3D *rv3d = NULL;
- ARegion *region_unlock_user = NULL;
- ARegion *region_unlock = NULL;
+ RegionView3D *rv3d = nullptr;
+ ARegion *region_unlock_user = nullptr;
+ ARegion *region_unlock = nullptr;
const ListBase *region_list = (v3d == area->spacedata.first) ? &area->regionbase :
&v3d->regionbase;
@@ -138,7 +147,7 @@ bool ED_view3d_area_user_region(const ScrArea *area, const View3D *v3d, ARegion
LISTBASE_FOREACH (ARegion *, region, region_list) {
/* find the first unlocked rv3d */
if (region->regiondata && region->regiontype == RGN_TYPE_WINDOW) {
- rv3d = region->regiondata;
+ rv3d = static_cast<RegionView3D *>(region->regiondata);
if ((rv3d->viewlock & RV3D_LOCK_ROTATION) == 0) {
region_unlock = region;
if (ELEM(rv3d->persp, RV3D_PERSP, RV3D_CAMOB)) {
@@ -166,21 +175,21 @@ bool ED_view3d_area_user_region(const ScrArea *area, const View3D *v3d, ARegion
void ED_view3d_init_mats_rv3d(const struct Object *ob, struct RegionView3D *rv3d)
{
/* local viewmat and persmat, to calculate projections */
- mul_m4_m4m4(rv3d->viewmatob, rv3d->viewmat, ob->obmat);
- mul_m4_m4m4(rv3d->persmatob, rv3d->persmat, ob->obmat);
+ mul_m4_m4m4(rv3d->viewmatob, rv3d->viewmat, ob->object_to_world);
+ mul_m4_m4m4(rv3d->persmatob, rv3d->persmat, ob->object_to_world);
/* initializes object space clipping, speeds up clip tests */
- ED_view3d_clipping_local(rv3d, ob->obmat);
+ ED_view3d_clipping_local(rv3d, ob->object_to_world);
}
void ED_view3d_init_mats_rv3d_gl(const struct Object *ob, struct RegionView3D *rv3d)
{
ED_view3d_init_mats_rv3d(ob, rv3d);
- /* we have to multiply instead of loading viewmatob to make
- * it work with duplis using displists, otherwise it will
- * override the dupli-matrix */
- GPU_matrix_mul(ob->obmat);
+ /* We have to multiply instead of loading `viewmatob` to make
+ * it work with duplis using display-lists, otherwise it will
+ * override the dupli-matrix. */
+ GPU_matrix_mul(ob->object_to_world);
}
#ifdef DEBUG
@@ -199,7 +208,7 @@ void ED_view3d_check_mats_rv3d(struct RegionView3D *rv3d)
void ED_view3d_stop_render_preview(wmWindowManager *wm, ARegion *region)
{
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
if (rv3d->render_engine) {
#ifdef WITH_PYTHON
@@ -213,7 +222,7 @@ void ED_view3d_stop_render_preview(wmWindowManager *wm, ARegion *region)
#endif
RE_engine_free(rv3d->render_engine);
- rv3d->render_engine = NULL;
+ rv3d->render_engine = nullptr;
}
/* A bit overkill but this make sure the viewport is reset completely. (fclem) */
@@ -222,12 +231,12 @@ void ED_view3d_stop_render_preview(wmWindowManager *wm, ARegion *region)
void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *area)
{
- wmWindowManager *wm = bmain->wm.first;
+ wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
if (v3d->shading.type != OB_RENDER) {
ARegion *region;
- for (region = area->regionbase.first; region; region = region->next) {
+ for (region = static_cast<ARegion *>(area->regionbase.first); region; region = region->next) {
if ((region->regiontype == RGN_TYPE_WINDOW) && region->regiondata) {
ED_view3d_stop_render_preview(wm, region);
}
@@ -237,7 +246,7 @@ void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *area)
/* ******************** default callbacks for view3d space ***************** */
-static SpaceLink *view3d_create(const ScrArea *UNUSED(area), const Scene *scene)
+static SpaceLink *view3d_create(const ScrArea * /*area*/, const Scene *scene)
{
ARegion *region;
View3D *v3d;
@@ -250,14 +259,14 @@ static SpaceLink *view3d_create(const ScrArea *UNUSED(area), const Scene *scene)
}
/* header */
- region = MEM_callocN(sizeof(ARegion), "header for view3d");
+ region = MEM_cnew<ARegion>("header for view3d");
BLI_addtail(&v3d->regionbase, region);
region->regiontype = RGN_TYPE_HEADER;
region->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
/* tool header */
- region = MEM_callocN(sizeof(ARegion), "tool header for view3d");
+ region = MEM_cnew<ARegion>("tool header for view3d");
BLI_addtail(&v3d->regionbase, region);
region->regiontype = RGN_TYPE_TOOL_HEADER;
@@ -265,7 +274,7 @@ static SpaceLink *view3d_create(const ScrArea *UNUSED(area), const Scene *scene)
region->flag = RGN_FLAG_HIDDEN | RGN_FLAG_HIDDEN_BY_USER;
/* tool shelf */
- region = MEM_callocN(sizeof(ARegion), "toolshelf for view3d");
+ region = MEM_cnew<ARegion>("toolshelf for view3d");
BLI_addtail(&v3d->regionbase, region);
region->regiontype = RGN_TYPE_TOOLS;
@@ -273,7 +282,7 @@ static SpaceLink *view3d_create(const ScrArea *UNUSED(area), const Scene *scene)
region->flag = RGN_FLAG_HIDDEN;
/* buttons/list view */
- region = MEM_callocN(sizeof(ARegion), "buttons for view3d");
+ region = MEM_cnew<ARegion>("buttons for view3d");
BLI_addtail(&v3d->regionbase, region);
region->regiontype = RGN_TYPE_UI;
@@ -281,13 +290,13 @@ static SpaceLink *view3d_create(const ScrArea *UNUSED(area), const Scene *scene)
region->flag = RGN_FLAG_HIDDEN;
/* main region */
- region = MEM_callocN(sizeof(ARegion), "main region for view3d");
+ region = MEM_cnew<ARegion>("main region for view3d");
BLI_addtail(&v3d->regionbase, region);
region->regiontype = RGN_TYPE_WINDOW;
- region->regiondata = MEM_callocN(sizeof(RegionView3D), "region view3d");
- rv3d = region->regiondata;
+ region->regiondata = MEM_cnew<RegionView3D>("region view3d");
+ rv3d = static_cast<RegionView3D *>(region->regiondata);
rv3d->viewquat[0] = 1.0f;
rv3d->persp = RV3D_PERSP;
rv3d->view = RV3D_VIEW_USER;
@@ -313,33 +322,35 @@ static void view3d_free(SpaceLink *sl)
if (vd->shading.prop) {
IDP_FreeProperty(vd->shading.prop);
- vd->shading.prop = NULL;
+ vd->shading.prop = nullptr;
}
+
+ BKE_viewer_path_clear(&vd->viewer_path);
}
/* spacetype; init callback */
-static void view3d_init(wmWindowManager *UNUSED(wm), ScrArea *UNUSED(area))
+static void view3d_init(wmWindowManager * /*wm*/, ScrArea * /*area*/)
{
}
-static void view3d_exit(wmWindowManager *UNUSED(wm), ScrArea *area)
+static void view3d_exit(wmWindowManager * /*wm*/, ScrArea *area)
{
BLI_assert(area->spacetype == SPACE_VIEW3D);
- View3D *v3d = area->spacedata.first;
+ View3D *v3d = static_cast<View3D *>(area->spacedata.first);
MEM_SAFE_FREE(v3d->runtime.local_stats);
}
static SpaceLink *view3d_duplicate(SpaceLink *sl)
{
View3D *v3do = (View3D *)sl;
- View3D *v3dn = MEM_dupallocN(sl);
+ View3D *v3dn = static_cast<View3D *>(MEM_dupallocN(sl));
memset(&v3dn->runtime, 0x0, sizeof(v3dn->runtime));
/* clear or remove stuff from old */
if (v3dn->localvd) {
- v3dn->localvd = NULL;
+ v3dn->localvd = nullptr;
}
v3dn->local_collections_uuid = 0;
@@ -353,6 +364,8 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
v3dn->shading.prop = IDP_CopyProperty(v3do->shading.prop);
}
+ BKE_viewer_path_copy(&v3dn->viewer_path, &v3do->viewer_path);
+
/* copy or clear inside new stuff */
return (SpaceLink *)v3dn;
@@ -459,10 +472,10 @@ static ID_Type view3d_drop_id_in_main_region_poll_get_id_type(bContext *C,
const ScrArea *area = CTX_wm_area(C);
if (ED_region_overlap_isect_any_xy(area, event->xy)) {
- return 0;
+ return ID_Type(0);
}
if (!view3d_drop_in_main_region_poll(C, event)) {
- return 0;
+ return ID_Type(0);
}
ID *local_id = WM_drag_get_local_ID(drag, 0);
@@ -472,10 +485,10 @@ static ID_Type view3d_drop_id_in_main_region_poll_get_id_type(bContext *C,
wmDragAsset *asset_drag = WM_drag_get_asset_data(drag, 0);
if (asset_drag) {
- return asset_drag->id_type;
+ return ID_Type(asset_drag->id_type);
}
- return 0;
+ return ID_Type(0);
}
static bool view3d_drop_id_in_main_region_poll(bContext *C,
@@ -492,7 +505,7 @@ static bool view3d_drop_id_in_main_region_poll(bContext *C,
static void view3d_ob_drop_draw_activate(struct wmDropBox *drop, wmDrag *drag)
{
- V3DSnapCursorState *state = drop->draw_data;
+ V3DSnapCursorState *state = static_cast<V3DSnapCursorState *>(drop->draw_data);
if (state) {
return;
}
@@ -503,7 +516,8 @@ static void view3d_ob_drop_draw_activate(struct wmDropBox *drop, wmDrag *drag)
return;
}
- state = drop->draw_data = ED_view3d_cursor_snap_active();
+ state = static_cast<V3DSnapCursorState *>(ED_view3d_cursor_snap_active());
+ drop->draw_data = state;
state->draw_plane = true;
float dimensions[3] = {0.0f};
@@ -515,7 +529,7 @@ static void view3d_ob_drop_draw_activate(struct wmDropBox *drop, wmDrag *drag)
struct AssetMetaData *meta_data = WM_drag_get_asset_meta_data(drag, ID_OB);
IDProperty *dimensions_prop = BKE_asset_metadata_idprop_find(meta_data, "dimensions");
if (dimensions_prop) {
- copy_v3_v3(dimensions, IDP_Array(dimensions_prop));
+ copy_v3_v3(dimensions, static_cast<float *>(IDP_Array(dimensions_prop)));
}
}
@@ -526,12 +540,12 @@ static void view3d_ob_drop_draw_activate(struct wmDropBox *drop, wmDrag *drag)
}
}
-static void view3d_ob_drop_draw_deactivate(struct wmDropBox *drop, wmDrag *UNUSED(drag))
+static void view3d_ob_drop_draw_deactivate(struct wmDropBox *drop, wmDrag * /*drag*/)
{
- V3DSnapCursorState *state = drop->draw_data;
+ V3DSnapCursorState *state = static_cast<V3DSnapCursorState *>(drop->draw_data);
if (state) {
ED_view3d_cursor_snap_deactive(state);
- drop->draw_data = NULL;
+ drop->draw_data = nullptr;
}
}
@@ -590,7 +604,7 @@ static bool view3d_mat_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event
static char *view3d_mat_drop_tooltip(bContext *C,
wmDrag *drag,
const int xy[2],
- wmDropBox *UNUSED(drop))
+ wmDropBox * /*drop*/)
{
const char *name = WM_drag_get_item_name(drag);
ARegion *region = CTX_wm_region(C);
@@ -615,10 +629,10 @@ static bool view3d_object_data_drop_poll(bContext *C, wmDrag *drag, const wmEven
return false;
}
-static char *view3d_object_data_drop_tooltip(bContext *UNUSED(C),
- wmDrag *UNUSED(drag),
- const int UNUSED(xy[2]),
- wmDropBox *UNUSED(drop))
+static char *view3d_object_data_drop_tooltip(bContext * /*C*/,
+ wmDrag * /*drag*/,
+ const int /*xy*/[2],
+ wmDropBox * /*drop*/)
{
return BLI_strdup(TIP_("Create object instance from object-data"));
}
@@ -630,7 +644,7 @@ static bool view3d_ima_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event
}
if (drag->type == WM_DRAG_PATH) {
/* rule might not work? */
- return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE));
+ return ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE);
}
return WM_drag_is_ID_type(drag, ID_IM);
@@ -639,7 +653,7 @@ static bool view3d_ima_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event
static bool view3d_ima_bg_is_camera_view(bContext *C)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
- if ((rv3d && (rv3d->persp == RV3D_CAMOB))) {
+ if (rv3d && (rv3d->persp == RV3D_CAMOB)) {
View3D *v3d = CTX_wm_view3d(C);
if (v3d && v3d->camera && v3d->camera->type == OB_CAMERA) {
return true;
@@ -669,7 +683,7 @@ static bool view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent
Object *ob = ED_view3d_give_object_under_cursor(C, event->mval);
- if (ob == NULL) {
+ if (ob == nullptr) {
return true;
}
@@ -680,9 +694,7 @@ static bool view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent
return false;
}
-static bool view3d_volume_drop_poll(bContext *UNUSED(C),
- wmDrag *drag,
- const wmEvent *UNUSED(event))
+static bool view3d_volume_drop_poll(bContext * /*C*/, wmDrag *drag, const wmEvent * /*event*/)
{
return (drag->type == WM_DRAG_PATH) && (drag->icon == ICON_FILE_VOLUME);
}
@@ -698,7 +710,7 @@ static void view3d_ob_drop_matrix_from_snap(V3DSnapCursorState *snap_state,
copy_v3_v3(obmat_final[3], snap_data->loc);
float scale[3];
- mat4_to_size(scale, ob->obmat);
+ mat4_to_size(scale, ob->object_to_world);
rescale_m4(obmat_final, scale);
const BoundBox *bb = BKE_object_boundbox_get(ob);
@@ -711,7 +723,7 @@ static void view3d_ob_drop_matrix_from_snap(V3DSnapCursorState *snap_state,
}
}
-static void view3d_ob_drop_copy_local_id(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
+static void view3d_ob_drop_copy_local_id(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_get_local_ID(drag, ID_OB);
@@ -729,7 +741,7 @@ static void view3d_ob_drop_copy_local_id(bContext *UNUSED(C), wmDrag *drag, wmDr
/* Mostly the same logic as #view3d_collection_drop_copy_external_asset(), just different enough to
* make sharing code a bit difficult. */
-static void view3d_ob_drop_copy_external_asset(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
+static void view3d_ob_drop_copy_external_asset(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
{
/* NOTE(@campbellbarton): Selection is handled here, de-selecting objects before append,
* using auto-select to ensure the new objects are selected.
@@ -742,7 +754,7 @@ static void view3d_ob_drop_copy_external_asset(bContext *UNUSED(C), wmDrag *drag
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
ID *id = WM_drag_asset_id_import(asset_drag, FILE_AUTOSELECT);
@@ -752,15 +764,16 @@ static void view3d_ob_drop_copy_external_asset(bContext *UNUSED(C), wmDrag *drag
RNA_int_set(drop->ptr, "session_uuid", id->session_uuid);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, (Object *)id);
- if (base != NULL) {
+ if (base != nullptr) {
BKE_view_layer_base_select_and_set_active(view_layer, base);
WM_main_add_notifier(NC_SCENE | ND_OB_ACTIVE, scene);
}
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
ED_outliner_select_sync_from_object_tag(C);
- V3DSnapCursorState *snap_state = drop->draw_data;
+ V3DSnapCursorState *snap_state = static_cast<V3DSnapCursorState *>(drop->draw_data);
if (snap_state) {
float obmat_final[4][4];
@@ -770,17 +783,15 @@ static void view3d_ob_drop_copy_external_asset(bContext *UNUSED(C), wmDrag *drag
}
}
-static void view3d_collection_drop_copy_local_id(bContext *UNUSED(C),
- wmDrag *drag,
- wmDropBox *drop)
+static void view3d_collection_drop_copy_local_id(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_get_local_ID(drag, ID_GR);
- RNA_int_set(drop->ptr, "session_uuid", (int)id->session_uuid);
+ RNA_int_set(drop->ptr, "session_uuid", int(id->session_uuid));
}
/* Mostly the same logic as #view3d_ob_drop_copy_external_asset(), just different enough to make
* sharing code a bit difficult. */
-static void view3d_collection_drop_copy_external_asset(bContext *UNUSED(C),
+static void view3d_collection_drop_copy_external_asset(bContext * /*C*/,
wmDrag *drag,
wmDropBox *drop)
{
@@ -791,7 +802,7 @@ static void view3d_collection_drop_copy_external_asset(bContext *UNUSED(C),
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
ID *id = WM_drag_asset_id_import(asset_drag, FILE_AUTOSELECT);
Collection *collection = (Collection *)id;
@@ -800,11 +811,12 @@ static void view3d_collection_drop_copy_external_asset(bContext *UNUSED(C),
DEG_relations_tag_update(CTX_data_main(C));
WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
- RNA_int_set(drop->ptr, "session_uuid", (int)id->session_uuid);
+ RNA_int_set(drop->ptr, "session_uuid", int(id->session_uuid));
/* Make an object active, just use the first one in the collection. */
- CollectionObject *cobject = collection->gobject.first;
- Base *base = cobject ? BKE_view_layer_base_find(view_layer, cobject->ob) : NULL;
+ CollectionObject *cobject = static_cast<CollectionObject *>(collection->gobject.first);
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base = cobject ? BKE_view_layer_base_find(view_layer, cobject->ob) : nullptr;
if (base) {
BLI_assert((base->flag & BASE_SELECTABLE) && (base->flag & BASE_ENABLED_VIEWPORT));
BKE_view_layer_base_select_and_set_active(view_layer, base);
@@ -818,14 +830,14 @@ static void view3d_collection_drop_copy_external_asset(bContext *UNUSED(C),
ED_undo_push(C, "Collection_Drop");
}
-static void view3d_id_drop_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
+static void view3d_id_drop_copy(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0);
WM_operator_properties_id_lookup_set_from_id(drop->ptr, id);
}
-static void view3d_id_drop_copy_with_type(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
+static void view3d_id_drop_copy_with_type(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0);
@@ -833,7 +845,7 @@ static void view3d_id_drop_copy_with_type(bContext *UNUSED(C), wmDrag *drag, wmD
WM_operator_properties_id_lookup_set_from_id(drop->ptr, id);
}
-static void view3d_id_path_drop_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
+static void view3d_id_path_drop_copy(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0);
@@ -863,13 +875,13 @@ static void view3d_lightcache_update(bContext *C)
RNA_int_set(&op_ptr, "delay", 200);
RNA_enum_set_identifier(C, &op_ptr, "subset", "DIRTY");
- WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &op_ptr, NULL);
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &op_ptr, nullptr);
WM_operator_properties_free(&op_ptr);
}
/* region dropbox definition */
-static void view3d_dropboxes(void)
+static void view3d_dropboxes()
{
ListBase *lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
@@ -879,7 +891,7 @@ static void view3d_dropboxes(void)
view3d_ob_drop_poll_local_id,
view3d_ob_drop_copy_local_id,
WM_drag_free_imported_drag_ID,
- NULL);
+ nullptr);
drop->draw_droptip = WM_drag_draw_item_name_fn;
drop->draw_activate = view3d_ob_drop_draw_activate;
@@ -890,7 +902,7 @@ static void view3d_dropboxes(void)
view3d_ob_drop_poll_external_asset,
view3d_ob_drop_copy_external_asset,
WM_drag_free_imported_drag_ID,
- NULL);
+ nullptr);
drop->draw_droptip = WM_drag_draw_item_name_fn;
drop->draw_activate = view3d_ob_drop_draw_activate;
@@ -901,13 +913,13 @@ static void view3d_dropboxes(void)
view3d_collection_drop_poll_external_asset,
view3d_collection_drop_copy_external_asset,
WM_drag_free_imported_drag_ID,
- NULL);
+ nullptr);
WM_dropbox_add(lb,
"OBJECT_OT_collection_instance_add",
view3d_collection_drop_poll_local_id,
view3d_collection_drop_copy_local_id,
WM_drag_free_imported_drag_ID,
- NULL);
+ nullptr);
WM_dropbox_add(lb,
"OBJECT_OT_drop_named_material",
@@ -920,19 +932,19 @@ static void view3d_dropboxes(void)
view3d_ima_bg_drop_poll,
view3d_id_path_drop_copy,
WM_drag_free_imported_drag_ID,
- NULL);
+ nullptr);
WM_dropbox_add(lb,
"OBJECT_OT_drop_named_image",
view3d_ima_empty_drop_poll,
view3d_id_path_drop_copy,
WM_drag_free_imported_drag_ID,
- NULL);
+ nullptr);
WM_dropbox_add(lb,
"OBJECT_OT_volume_import",
view3d_volume_drop_poll,
view3d_id_path_drop_copy,
WM_drag_free_imported_drag_ID,
- NULL);
+ nullptr);
WM_dropbox_add(lb,
"OBJECT_OT_data_instance_add",
view3d_object_data_drop_poll,
@@ -944,13 +956,13 @@ static void view3d_dropboxes(void)
view3d_world_drop_poll,
view3d_id_drop_copy,
WM_drag_free_imported_drag_ID,
- NULL);
+ nullptr);
}
-static void view3d_widgets(void)
+static void view3d_widgets()
{
- wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure(
- &(const struct wmGizmoMapType_Params){SPACE_VIEW3D, RGN_TYPE_WINDOW});
+ wmGizmoMapType_Params params{SPACE_VIEW3D, RGN_TYPE_WINDOW};
+ wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure(&params);
WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_xform_gizmo_context);
WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_light_spot);
@@ -986,7 +998,7 @@ static void view3d_widgets(void)
/* type callback, not region itself */
static void view3d_main_region_free(ARegion *region)
{
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
if (rv3d) {
if (rv3d->localvd) {
@@ -1005,7 +1017,7 @@ static void view3d_main_region_free(ARegion *region)
}
MEM_freeN(rv3d);
- region->regiondata = NULL;
+ region->regiondata = nullptr;
}
}
@@ -1013,23 +1025,24 @@ static void view3d_main_region_free(ARegion *region)
static void *view3d_main_region_duplicate(void *poin)
{
if (poin) {
- RegionView3D *rv3d = poin, *new;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(poin);
+ RegionView3D *new_rv3d;
- new = MEM_dupallocN(rv3d);
+ new_rv3d = static_cast<RegionView3D *>(MEM_dupallocN(rv3d));
if (rv3d->localvd) {
- new->localvd = MEM_dupallocN(rv3d->localvd);
+ new_rv3d->localvd = static_cast<RegionView3D *>(MEM_dupallocN(rv3d->localvd));
}
if (rv3d->clipbb) {
- new->clipbb = MEM_dupallocN(rv3d->clipbb);
+ new_rv3d->clipbb = static_cast<BoundBox *>(MEM_dupallocN(rv3d->clipbb));
}
- new->render_engine = NULL;
- new->sms = NULL;
- new->smooth_timer = NULL;
+ new_rv3d->render_engine = nullptr;
+ new_rv3d->sms = nullptr;
+ new_rv3d->smooth_timer = nullptr;
- return new;
+ return new_rv3d;
}
- return NULL;
+ return nullptr;
}
static void view3d_main_region_listener(const wmRegionListenerParams *params)
@@ -1039,8 +1052,8 @@ static void view3d_main_region_listener(const wmRegionListenerParams *params)
ARegion *region = params->region;
const wmNotifier *wmn = params->notifier;
const Scene *scene = params->scene;
- View3D *v3d = area->spacedata.first;
- RegionView3D *rv3d = region->regiondata;
+ View3D *v3d = static_cast<View3D *>(area->spacedata.first);
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
wmGizmoMap *gzmap = region->gizmo_map;
/* context changes */
@@ -1085,7 +1098,7 @@ static void view3d_main_region_listener(const wmRegionListenerParams *params)
break;
case ND_LAYER:
if (wmn->reference) {
- BKE_screen_view3d_sync(v3d, wmn->reference);
+ BKE_screen_view3d_sync(v3d, static_cast<Scene *>(wmn->reference));
}
ED_region_tag_redraw(region);
WM_gizmomap_tag_refresh(gzmap);
@@ -1262,7 +1275,8 @@ static void view3d_main_region_listener(const wmRegionListenerParams *params)
}
else if (wmn->subtype == NS_VIEW3D_SHADING) {
#ifdef WITH_XR_OPENXR
- ED_view3d_xr_shading_update(G_MAIN->wm.first, v3d, scene);
+ ED_view3d_xr_shading_update(
+ static_cast<wmWindowManager *>(G_MAIN->wm.first), v3d, scene);
#endif
ViewLayer *view_layer = WM_window_get_active_view_layer(window);
@@ -1307,11 +1321,21 @@ static void view3d_main_region_listener(const wmRegionListenerParams *params)
/* In case the region displays workspace settings. */
ED_region_tag_redraw(region);
break;
+ case NC_VIEWER_PATH: {
+ if (v3d->flag2 & V3D_SHOW_VIEWER) {
+ ViewLayer *view_layer = WM_window_get_active_view_layer(window);
+ if (Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer)) {
+ ED_render_view3d_update(depsgraph, window, area, true);
+ }
+ ED_region_tag_redraw(region);
+ }
+ break;
+ }
}
}
static void view3d_do_msg_notify_workbench_view_update(struct bContext *C,
- struct wmMsgSubscribeKey *UNUSED(msg_key),
+ struct wmMsgSubscribeKey * /*msg_key*/,
struct wmMsgSubscribeValue *msg_val)
{
Scene *scene = CTX_data_scene(C);
@@ -1319,7 +1343,7 @@ static void view3d_do_msg_notify_workbench_view_update(struct bContext *C,
View3D *v3d = (View3D *)area->spacedata.first;
if (v3d->shading.type == OB_SOLID) {
RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
- DRWUpdateContext drw_context = {NULL};
+ DRWUpdateContext drw_context = {nullptr};
drw_context.bmain = CTX_data_main(C);
drw_context.depsgraph = CTX_data_depsgraph_pointer(C);
drw_context.scene = scene;
@@ -1343,7 +1367,7 @@ static void view3d_main_region_message_subscribe(const wmRegionMessageSubscribeP
* accepting some redundant redraws.
*
* For other space types we might try avoid this, keep the 3D view as an exceptional case! */
- wmMsgParams_RNA msg_key_params = {{0}};
+ wmMsgParams_RNA msg_key_params{};
/* Only subscribe to types. */
StructRNA *type_array[] = {
@@ -1366,17 +1390,15 @@ static void view3d_main_region_message_subscribe(const wmRegionMessageSubscribeP
&RNA_World,
};
- wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
- .owner = region,
- .user_data = region,
- .notify = ED_region_do_msg_notify_tag_redraw,
- };
+ wmMsgSubscribeValue msg_sub_value_region_tag_redraw{};
+ msg_sub_value_region_tag_redraw.owner = region;
+ msg_sub_value_region_tag_redraw.user_data = region;
+ msg_sub_value_region_tag_redraw.notify = ED_region_do_msg_notify_tag_redraw;
- wmMsgSubscribeValue msg_sub_value_workbench_view_update = {
- .owner = region,
- .user_data = area,
- .notify = view3d_do_msg_notify_workbench_view_update,
- };
+ wmMsgSubscribeValue msg_sub_value_workbench_view_update{};
+ msg_sub_value_workbench_view_update.owner = region;
+ msg_sub_value_workbench_view_update.user_data = area;
+ msg_sub_value_workbench_view_update.notify = view3d_do_msg_notify_workbench_view_update;
for (int i = 0; i < ARRAY_SIZE(type_array); i++) {
msg_key_params.ptr.type = type_array[i];
@@ -1384,7 +1406,7 @@ static void view3d_main_region_message_subscribe(const wmRegionMessageSubscribeP
}
/* Subscribe to a handful of other properties. */
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, engine, &msg_sub_value_region_tag_redraw);
WM_msg_subscribe_rna_anon_prop(
@@ -1404,9 +1426,11 @@ static void view3d_main_region_message_subscribe(const wmRegionMessageSubscribeP
WM_msg_subscribe_rna_anon_type(mbus, SceneDisplay, &msg_sub_value_region_tag_redraw);
WM_msg_subscribe_rna_anon_type(mbus, ObjectDisplay, &msg_sub_value_region_tag_redraw);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obact = BKE_view_layer_active_object_get(view_layer);
- if (obact != NULL) {
+ if (obact != nullptr) {
switch (obact->mode) {
case OB_MODE_PARTICLE_EDIT:
WM_msg_subscribe_rna_anon_type(mbus, ParticleEdit, &msg_sub_value_region_tag_redraw);
@@ -1422,11 +1446,10 @@ static void view3d_main_region_message_subscribe(const wmRegionMessageSubscribeP
}
{
- wmMsgSubscribeValue msg_sub_value_region_tag_refresh = {
- .owner = region,
- .user_data = area,
- .notify = WM_toolsystem_do_msg_notify_tag_refresh,
- };
+ wmMsgSubscribeValue msg_sub_value_region_tag_refresh{};
+ msg_sub_value_region_tag_refresh.owner = region;
+ msg_sub_value_region_tag_refresh.user_data = area;
+ msg_sub_value_region_tag_refresh.notify = WM_toolsystem_do_msg_notify_tag_refresh;
WM_msg_subscribe_rna_anon_prop(mbus, Object, mode, &msg_sub_value_region_tag_refresh);
WM_msg_subscribe_rna_anon_prop(mbus, LayerObjects, active, &msg_sub_value_region_tag_refresh);
}
@@ -1439,7 +1462,9 @@ static void view3d_main_region_cursor(wmWindow *win, ScrArea *area, ARegion *reg
return;
}
+ Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
if (obedit) {
WM_cursor_set(win, WM_CURSOR_EDIT);
@@ -1504,7 +1529,7 @@ static void view3d_header_region_listener(const wmRegionListenerParams *params)
break;
}
- /* From topbar, which ones are needed? split per header? */
+ /* From top-bar, which ones are needed? split per header? */
/* Disable for now, re-enable if needed, or remove - campbell. */
#if 0
/* context changes */
@@ -1538,18 +1563,17 @@ static void view3d_header_region_message_subscribe(const wmRegionMessageSubscrib
struct wmMsgBus *mbus = params->message_bus;
ARegion *region = params->region;
- wmMsgParams_RNA msg_key_params = {{0}};
+ wmMsgParams_RNA msg_key_params{};
/* Only subscribe to types. */
StructRNA *type_array[] = {
&RNA_View3DShading,
};
- wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
- .owner = region,
- .user_data = region,
- .notify = ED_region_do_msg_notify_tag_redraw,
- };
+ wmMsgSubscribeValue msg_sub_value_region_tag_redraw{};
+ msg_sub_value_region_tag_redraw.owner = region;
+ msg_sub_value_region_tag_redraw.user_data = region;
+ msg_sub_value_region_tag_redraw.notify = ED_region_do_msg_notify_tag_redraw;
for (int i = 0; i < ARRAY_SIZE(type_array); i++) {
msg_key_params.ptr.type = type_array[i];
@@ -1574,7 +1598,7 @@ void ED_view3d_buttons_region_layout_ex(const bContext *C,
{
const enum eContextObjectMode mode = CTX_data_mode_enum(C);
- const char *contexts_base[4] = {NULL};
+ const char *contexts_base[4] = {nullptr};
contexts_base[0] = CTX_data_mode_string(C);
const char **contexts = &contexts_base[1];
@@ -1667,7 +1691,7 @@ void ED_view3d_buttons_region_layout_ex(const bContext *C,
ListBase *paneltypes = &region->type->paneltypes;
/* Allow drawing 3D view toolbar from non 3D view space type. */
- if (category_override != NULL) {
+ if (category_override != nullptr) {
SpaceType *st = BKE_spacetype_from_id(SPACE_VIEW3D);
ARegionType *art = BKE_regiontype_from_id(st, RGN_TYPE_UI);
paneltypes = &art->paneltypes;
@@ -1678,7 +1702,7 @@ void ED_view3d_buttons_region_layout_ex(const bContext *C,
static void view3d_buttons_region_layout(const bContext *C, ARegion *region)
{
- ED_view3d_buttons_region_layout_ex(C, region, NULL);
+ ED_view3d_buttons_region_layout_ex(C, region, nullptr);
}
static void view3d_buttons_region_listener(const wmRegionListenerParams *params)
@@ -1800,7 +1824,8 @@ static void view3d_tools_region_init(wmWindowManager *wm, ARegion *region)
static void view3d_tools_region_draw(const bContext *C, ARegion *region)
{
- ED_region_panels_ex(C, region, (const char *[]){CTX_data_mode_string(C), NULL});
+ const char *contexts[] = {CTX_data_mode_string(C), nullptr};
+ ED_region_panels_ex(C, region, contexts);
}
/* area (not region) level listener */
@@ -1808,7 +1833,7 @@ static void space_view3d_listener(const wmSpaceTypeListenerParams *params)
{
ScrArea *area = params->area;
const wmNotifier *wmn = params->notifier;
- View3D *v3d = area->spacedata.first;
+ View3D *v3d = static_cast<View3D *>(area->spacedata.first);
/* context changes */
switch (wmn->category) {
@@ -1862,7 +1887,7 @@ static void space_view3d_refresh(const bContext *C, ScrArea *area)
const char *view3d_context_dir[] = {
"active_object",
"selected_ids",
- NULL,
+ nullptr,
};
static int view3d_context(const bContext *C, const char *member, bContextDataResult *result)
@@ -1876,7 +1901,7 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
}
if (CTX_data_equals(member, "active_object")) {
/* In most cases the active object is the `view_layer->basact->object`.
- * For the 3D view however it can be NULL when hidden.
+ * For the 3D view however it can be nullptr when hidden.
*
* This is ignored in the case the object is in any mode (besides object-mode),
* since the object's mode impacts the current tool, cursor, gizmos etc.
@@ -1888,11 +1913,14 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
* without showing the object.
*
* See T85532 for alternatives that were considered. */
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- if (view_layer->basact) {
- Object *ob = view_layer->basact->object;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base = BKE_view_layer_active_base_get(view_layer);
+ if (base) {
+ Object *ob = base->object;
/* if hidden but in edit mode, we still display, can happen with animation */
- if ((view_layer->basact->flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT) != 0 ||
+ if ((base->flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT) != 0 ||
(ob->mode != OB_MODE_OBJECT)) {
CTX_data_id_pointer_set(result, &ob->id);
}
@@ -1919,7 +1947,7 @@ static void view3d_id_remap_v3d_ob_centers(View3D *v3d, const struct IDRemapper
{
if (BKE_id_remapper_apply(mappings, (ID **)&v3d->ob_center, ID_REMAP_APPLY_DEFAULT) ==
ID_REMAP_RESULT_SOURCE_UNASSIGNED) {
- /* Otherwise, bonename may remain valid...
+ /* Otherwise, bone-name may remain valid...
* We could be smart and check this, too? */
v3d->ob_center_bone[0] = '\0';
}
@@ -1937,10 +1965,10 @@ static void view3d_id_remap_v3d(ScrArea *area,
/* 3D view might be inactive, in that case needs to use slink->regionbase */
ListBase *regionbase = (slink == area->spacedata.first) ? &area->regionbase :
&slink->regionbase;
- for (region = regionbase->first; region; region = region->next) {
+ for (region = static_cast<ARegion *>(regionbase->first); region; region = region->next) {
if (region->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = is_local ? ((RegionView3D *)region->regiondata)->localvd :
- region->regiondata;
+ static_cast<RegionView3D *>(region->regiondata);
if (rv3d && (rv3d->persp == RV3D_CAMOB)) {
rv3d->persp = RV3D_PERSP;
}
@@ -1960,15 +1988,69 @@ static void view3d_id_remap(ScrArea *area, SpaceLink *slink, const struct IDRema
View3D *view3d = (View3D *)slink;
view3d_id_remap_v3d(area, slink, view3d, mappings, false);
view3d_id_remap_v3d_ob_centers(view3d, mappings);
- if (view3d->localvd != NULL) {
+ if (view3d->localvd != nullptr) {
/* Object centers in local-view aren't used, see: T52663 */
view3d_id_remap_v3d(area, slink, view3d->localvd, mappings, true);
}
+ BKE_viewer_path_id_remap(&view3d->viewer_path, mappings);
+}
+
+static void view3d_blend_read_data(BlendDataReader *reader, SpaceLink *sl)
+{
+ View3D *v3d = (View3D *)sl;
+
+ memset(&v3d->runtime, 0x0, sizeof(v3d->runtime));
+
+ if (v3d->gpd) {
+ BLO_read_data_address(reader, &v3d->gpd);
+ BKE_gpencil_blend_read_data(reader, v3d->gpd);
+ }
+ BLO_read_data_address(reader, &v3d->localvd);
+
+ /* render can be quite heavy, set to solid on load */
+ if (v3d->shading.type == OB_RENDER) {
+ v3d->shading.type = OB_SOLID;
+ }
+ v3d->shading.prev_type = OB_SOLID;
+
+ BKE_screen_view3d_shading_blend_read_data(reader, &v3d->shading);
+
+ BKE_screen_view3d_do_versions_250(v3d, &sl->regionbase);
+
+ BKE_viewer_path_blend_read_data(reader, &v3d->viewer_path);
+}
+
+static void view3d_blend_read_lib(BlendLibReader *reader, ID *parent_id, SpaceLink *sl)
+{
+ View3D *v3d = (View3D *)sl;
+
+ BLO_read_id_address(reader, parent_id->lib, &v3d->camera);
+ BLO_read_id_address(reader, parent_id->lib, &v3d->ob_center);
+
+ if (v3d->localvd) {
+ BLO_read_id_address(reader, parent_id->lib, &v3d->localvd->camera);
+ }
+
+ BKE_viewer_path_blend_read_lib(reader, parent_id->lib, &v3d->viewer_path);
+}
+
+static void view3d_blend_write(BlendWriter *writer, SpaceLink *sl)
+{
+ View3D *v3d = (View3D *)sl;
+ BLO_write_struct(writer, View3D, v3d);
+
+ if (v3d->localvd) {
+ BLO_write_struct(writer, View3D, v3d->localvd);
+ }
+
+ BKE_screen_view3d_shading_blend_write(writer, &v3d->shading);
+
+ BKE_viewer_path_blend_write(writer, &v3d->viewer_path);
}
-void ED_spacetype_view3d(void)
+void ED_spacetype_view3d()
{
- SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype view3d");
+ SpaceType *st = MEM_cnew<SpaceType>("spacetype view3d");
ARegionType *art;
st->spaceid = SPACE_VIEW3D;
@@ -1987,9 +2069,12 @@ void ED_spacetype_view3d(void)
st->gizmos = view3d_widgets;
st->context = view3d_context;
st->id_remap = view3d_id_remap;
+ st->blend_read_data = view3d_blend_read_data;
+ st->blend_read_lib = view3d_blend_read_lib;
+ st->blend_write = view3d_blend_write;
/* regions: main window */
- art = MEM_callocN(sizeof(ARegionType), "spacetype view3d main region");
+ art = MEM_cnew<ARegionType>("spacetype view3d main region");
art->regionid = RGN_TYPE_WINDOW;
art->keymapflag = ED_KEYMAP_GIZMO | ED_KEYMAP_TOOL | ED_KEYMAP_GPENCIL;
art->draw = view3d_main_region_draw;
@@ -2004,7 +2089,7 @@ void ED_spacetype_view3d(void)
BLI_addhead(&st->regiontypes, art);
/* regions: listview/buttons */
- art = MEM_callocN(sizeof(ARegionType), "spacetype view3d buttons region");
+ art = MEM_cnew<ARegionType>("spacetype view3d buttons region");
art->regionid = RGN_TYPE_UI;
art->prefsizex = UI_SIDEBAR_PANEL_WIDTH;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
@@ -2018,7 +2103,7 @@ void ED_spacetype_view3d(void)
view3d_buttons_register(art);
/* regions: tool(bar) */
- art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tools region");
+ art = MEM_cnew<ARegionType>("spacetype view3d tools region");
art->regionid = RGN_TYPE_TOOLS;
art->prefsizex = 58; /* XXX */
art->prefsizey = 50; /* XXX */
@@ -2031,7 +2116,7 @@ void ED_spacetype_view3d(void)
BLI_addhead(&st->regiontypes, art);
/* regions: tool header */
- art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tool header region");
+ art = MEM_cnew<ARegionType>("spacetype view3d tool header region");
art->regionid = RGN_TYPE_TOOL_HEADER;
art->prefsizey = HEADERY;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
@@ -2042,7 +2127,7 @@ void ED_spacetype_view3d(void)
BLI_addhead(&st->regiontypes, art);
/* regions: header */
- art = MEM_callocN(sizeof(ARegionType), "spacetype view3d header region");
+ art = MEM_cnew<ARegionType>("spacetype view3d header region");
art->regionid = RGN_TYPE_HEADER;
art->prefsizey = HEADERY;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
@@ -2057,7 +2142,7 @@ void ED_spacetype_view3d(void)
BLI_addhead(&st->regiontypes, art);
/* regions: xr */
- art = MEM_callocN(sizeof(ARegionType), "spacetype view3d xr region");
+ art = MEM_cnew<ARegionType>("spacetype view3d xr region");
art->regionid = RGN_TYPE_XR;
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index fe7e3a797c9..f71ce54729c 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -474,7 +474,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
/* Location, X/Y/Z */
mul_v3_fl(median_basis.generic.location, 1.0f / (float)tot);
if (v3d->flag & V3D_GLOBAL_STATS) {
- mul_m4_v3(ob->obmat, median_basis.generic.location);
+ mul_m4_v3(ob->object_to_world, median_basis.generic.location);
}
if (has_meshdata) {
@@ -954,9 +954,9 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
memcpy(&ve_median_basis, &tfp->ve_median, sizeof(tfp->ve_median));
if (v3d->flag & V3D_GLOBAL_STATS) {
- invert_m4_m4(ob->imat, ob->obmat);
- mul_m4_v3(ob->imat, median_basis.generic.location);
- mul_m4_v3(ob->imat, ve_median_basis.generic.location);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
+ mul_m4_v3(ob->world_to_object, median_basis.generic.location);
+ mul_m4_v3(ob->world_to_object, ve_median_basis.generic.location);
}
sub_vn_vnvn((float *)&median_basis,
(float *)&ve_median_basis,
@@ -1005,7 +1005,9 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
if (median->v_crease) {
- BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_VERT_CREASE);
+ if (!CustomData_has_layer(&bm->vdata, CD_CREASE)) {
+ BM_data_layer_add(bm, &bm->vdata, CD_CREASE);
+ }
cd_vert_crease_offset = CustomData_get_offset(&bm->vdata, CD_CREASE);
BLI_assert(cd_vert_crease_offset != -1);
@@ -1073,7 +1075,9 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
if (median->e_crease) {
- BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_CREASE);
+ if (!CustomData_has_layer(&bm->edata, CD_CREASE)) {
+ BM_data_layer_add(bm, &bm->edata, CD_CREASE);
+ }
cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
BLI_assert(cd_edge_crease_offset != -1);
@@ -1211,7 +1215,7 @@ static void v3d_object_dimension_buts(bContext *C, uiLayout *layout, View3D *v3d
BKE_object_dimensions_get(ob, tfp->ob_dims);
copy_v3_v3(tfp->ob_dims_orig, tfp->ob_dims);
copy_v3_v3(tfp->ob_scale_orig, ob->scale);
- copy_m4_m4(tfp->ob_obmat_orig, ob->obmat);
+ copy_m4_m4(tfp->ob_obmat_orig, ob->object_to_world);
uiDefBut(block,
UI_BTYPE_LABEL,
@@ -1278,8 +1282,10 @@ static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event)
return;
}
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = view_layer->basact->object;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *ob = BKE_view_layer_active_object_get(view_layer);
ED_vgroup_vert_active_mirror(ob, event - B_VGRP_PNL_EDIT_SINGLE);
DEG_id_tag_update(ob->data, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
@@ -1287,7 +1293,9 @@ static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event)
static bool view3d_panel_vgroup_poll(const bContext *C, PanelType *UNUSED(pt))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ob && (BKE_object_is_in_editmode_vgroup(ob) || BKE_object_is_in_wpaint_select_vert(ob))) {
MDeformVert *dvert_act = ED_mesh_active_dvert_get_only(ob);
@@ -1304,7 +1312,8 @@ static void view3d_panel_vgroup(const bContext *C, Panel *panel)
uiBlock *block = uiLayoutAbsoluteBlock(panel->layout);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = view_layer->basact->object;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *ob = BKE_view_layer_active_object_get(view_layer);
MDeformVert *dv;
@@ -1686,8 +1695,10 @@ static void v3d_editmetaball_buts(uiLayout *layout, Object *ob)
static void do_view3d_region_buttons(bContext *C, void *UNUSED(index), int event)
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
switch (event) {
@@ -1715,15 +1726,19 @@ static void do_view3d_region_buttons(bContext *C, void *UNUSED(index), int event
static bool view3d_panel_transform_poll(const bContext *C, PanelType *UNUSED(pt))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- return (view_layer->basact != NULL);
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ return (BKE_view_layer_active_base_get(view_layer) != NULL);
}
static void view3d_panel_transform(const bContext *C, Panel *panel)
{
uiBlock *block;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = view_layer->basact->object;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *ob = BKE_view_layer_active_object_get(view_layer);
Object *obedit = OBEDIT_FROM_OBACT(ob);
uiLayout *col;
@@ -1806,7 +1821,7 @@ static int view3d_object_mode_menu(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "No active object found");
return OPERATOR_CANCELLED;
}
- if (((ob->mode & OB_MODE_EDIT) == 0) && (ELEM(ob->type, OB_ARMATURE))) {
+ if (((ob->mode & OB_MODE_EDIT) == 0) && ELEM(ob->type, OB_ARMATURE)) {
ED_object_mode_set(C, (ob->mode == OB_MODE_OBJECT) ? OB_MODE_POSE : OB_MODE_OBJECT);
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c
index b5962647278..299c8638b02 100644
--- a/source/blender/editors/space_view3d/view3d_camera_control.c
+++ b/source/blender/editors/space_view3d/view3d_camera_control.c
@@ -142,7 +142,7 @@ struct View3DCameraControl *ED_view3d_cameracontrol_acquire(Depsgraph *depsgraph
vctrl->obtfm = BKE_object_tfm_backup(ob_back);
BKE_object_where_is_calc(depsgraph, scene, v3d->camera);
- negate_v3_v3(rv3d->ofs, v3d->camera->obmat[3]);
+ negate_v3_v3(rv3d->ofs, v3d->camera->object_to_world[3]);
rv3d->dist = 0.0;
}
@@ -251,7 +251,7 @@ void ED_view3d_cameracontrol_update(View3DCameraControl *vctrl,
invert_m4_m4(prev_view_imat, vctrl->view_mat_prev);
mul_m4_m4m4(diff_mat, view_mat, prev_view_imat);
- mul_m4_m4m4(parent_mat, diff_mat, vctrl->root_parent->obmat);
+ mul_m4_m4m4(parent_mat, diff_mat, vctrl->root_parent->object_to_world);
if (object_apply_mat4_with_protect(vctrl->root_parent, parent_mat, false, rv3d, view_mat)) {
/* Calculate again since the view locking changes the matrix. */
diff --git a/source/blender/editors/space_view3d/view3d_cursor_snap.c b/source/blender/editors/space_view3d/view3d_cursor_snap.c
index 195806fbecc..72e1f6f46c7 100644
--- a/source/blender/editors/space_view3d/view3d_cursor_snap.c
+++ b/source/blender/editors/space_view3d/view3d_cursor_snap.c
@@ -692,6 +692,7 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
}
else {
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(CTX_data_scene(C), view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
const int orient_index = BKE_scene_orientation_get_index(scene, SCE_ORIENT_DEFAULT);
const int pivot_point = scene->toolsettings->transform_pivot_point;
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.cc
index efc8b4a8502..5d4ed032bb4 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.cc
@@ -5,11 +5,12 @@
* \ingroup spview3d
*/
-#include <math.h>
+#include <cmath>
#include "BLI_jitter_2d.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
+#include "BLI_math_vector.hh"
#include "BLI_rect.h"
#include "BLI_string.h"
#include "BLI_string_utils.h"
@@ -54,6 +55,7 @@
#include "ED_screen_types.h"
#include "ED_transform.h"
#include "ED_view3d_offscreen.h"
+#include "ED_viewer_path.hh"
#include "DEG_depsgraph_query.h"
@@ -84,6 +86,8 @@
#include "view3d_intern.h" /* own include */
+using blender::float4;
+
#define M_GOLDEN_RATIO_CONJUGATE 0.618033988749895f
#define VIEW3D_OVERLAY_LINEHEIGHT (0.9f * U.widget_unit)
@@ -101,7 +105,7 @@ void ED_view3d_update_viewmat(Depsgraph *depsgraph,
const rcti *rect,
bool offscreen)
{
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
/* setup window matrices */
if (winmat) {
@@ -118,11 +122,11 @@ void ED_view3d_update_viewmat(Depsgraph *depsgraph,
else {
float rect_scale[2];
if (rect) {
- rect_scale[0] = (float)BLI_rcti_size_x(rect) / (float)region->winx;
- rect_scale[1] = (float)BLI_rcti_size_y(rect) / (float)region->winy;
+ rect_scale[0] = float(BLI_rcti_size_x(rect)) / float(region->winx);
+ rect_scale[1] = float(BLI_rcti_size_y(rect)) / float(region->winy);
}
/* NOTE: calls BKE_object_where_is_calc for camera... */
- view3d_viewmatrix_set(depsgraph, scene, v3d, rv3d, rect ? rect_scale : NULL);
+ view3d_viewmatrix_set(depsgraph, scene, v3d, rv3d, rect ? rect_scale : nullptr);
}
/* update utility matrices */
mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
@@ -135,11 +139,11 @@ void ED_view3d_update_viewmat(Depsgraph *depsgraph,
if (!offscreen && rv3d->persp == RV3D_CAMOB && v3d->camera) {
rctf cameraborder;
ED_view3d_calc_camera_border(scene, depsgraph, region, v3d, rv3d, &cameraborder, false);
- rv3d->viewcamtexcofac[0] = (float)region->winx / BLI_rctf_size_x(&cameraborder);
- rv3d->viewcamtexcofac[1] = (float)region->winy / BLI_rctf_size_y(&cameraborder);
+ rv3d->viewcamtexcofac[0] = float(region->winx) / BLI_rctf_size_x(&cameraborder);
+ rv3d->viewcamtexcofac[1] = float(region->winy) / BLI_rctf_size_y(&cameraborder);
- rv3d->viewcamtexcofac[2] = -rv3d->viewcamtexcofac[0] * cameraborder.xmin / (float)region->winx;
- rv3d->viewcamtexcofac[3] = -rv3d->viewcamtexcofac[1] * cameraborder.ymin / (float)region->winy;
+ rv3d->viewcamtexcofac[2] = -rv3d->viewcamtexcofac[0] * cameraborder.xmin / float(region->winx);
+ rv3d->viewcamtexcofac[3] = -rv3d->viewcamtexcofac[1] * cameraborder.ymin / float(region->winy);
}
else {
rv3d->viewcamtexcofac[0] = rv3d->viewcamtexcofac[1] = 1.0f;
@@ -164,10 +168,10 @@ void ED_view3d_update_viewmat(Depsgraph *depsgraph,
len_px = 2.0f / sqrtf(min_ff(len_squared_v3(v1), len_squared_v3(v2)));
if (rect) {
- len_sc = (float)max_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect));
+ len_sc = float(max_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)));
}
else {
- len_sc = (float)MAX2(region->winx, region->winy);
+ len_sc = float(MAX2(region->winx, region->winy));
}
rv3d->pixsize = len_px / len_sc;
@@ -182,7 +186,7 @@ static void view3d_main_region_setup_view(Depsgraph *depsgraph,
const float winmat[4][4],
const rcti *rect)
{
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
ED_view3d_update_viewmat(depsgraph, scene, v3d, region, viewmat, winmat, rect, false);
@@ -198,8 +202,8 @@ static void view3d_main_region_setup_offscreen(Depsgraph *depsgraph,
const float viewmat[4][4],
const float winmat[4][4])
{
- RegionView3D *rv3d = region->regiondata;
- ED_view3d_update_viewmat(depsgraph, scene, v3d, region, viewmat, winmat, NULL, true);
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
+ ED_view3d_update_viewmat(depsgraph, scene, v3d, region, viewmat, winmat, nullptr, true);
/* set for opengl */
GPU_matrix_projection_set(rv3d->winmat);
@@ -215,7 +219,7 @@ static bool view3d_stereo3d_active(wmWindow *win,
return false;
}
- if ((v3d->camera == NULL) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB) {
+ if ((v3d->camera == nullptr) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB) {
return false;
}
@@ -224,8 +228,8 @@ static bool view3d_stereo3d_active(wmWindow *win,
return false;
break;
case STEREO_3D_ID:
- /* win will be NULL when calling this from the selection or draw loop. */
- if ((win == NULL) || (WM_stereo3d_enabled(win, true) == false)) {
+ /* win will be nullptr when calling this from the selection or draw loop. */
+ if ((win == nullptr) || (WM_stereo3d_enabled(win, true) == false)) {
return false;
}
if (((scene->r.views_format & SCE_VIEWS_FORMAT_MULTIVIEW) != 0) &&
@@ -280,7 +284,7 @@ static void view3d_stereo3d_setup(
data_eval->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
- view3d_main_region_setup_view(depsgraph, scene, v3d, region, viewmat, NULL, rect);
+ view3d_main_region_setup_view(depsgraph, scene, v3d, region, viewmat, nullptr, rect);
data_eval->shiftx = shiftx;
BLI_thread_unlock(LOCK_VIEW3D);
@@ -294,7 +298,7 @@ static void view3d_stereo3d_setup(
v3d->camera = camera;
BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
- view3d_main_region_setup_view(depsgraph, scene, v3d, region, viewmat, NULL, rect);
+ view3d_main_region_setup_view(depsgraph, scene, v3d, region, viewmat, nullptr, rect);
v3d->camera = view_ob;
BLI_thread_unlock(LOCK_VIEW3D);
@@ -309,7 +313,7 @@ static void view3d_xr_mirror_setup(const wmWindowManager *wm,
ARegion *region,
const rcti *rect)
{
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
float viewmat[4][4];
const float lens_old = v3d->lens;
@@ -318,7 +322,7 @@ static void view3d_xr_mirror_setup(const wmWindowManager *wm,
copy_m4_m4(viewmat, rv3d->viewmat);
v3d->lens = lens_old;
}
- view3d_main_region_setup_view(depsgraph, scene, v3d, region, viewmat, NULL, rect);
+ view3d_main_region_setup_view(depsgraph, scene, v3d, region, viewmat, nullptr, rect);
/* Set draw flags. */
SET_FLAG_FROM_TEST(v3d->flag2,
@@ -346,7 +350,7 @@ void ED_view3d_draw_setup_view(const wmWindowManager *wm,
const float winmat[4][4],
const rcti *rect)
{
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
#ifdef WITH_XR_OPENXR
/* Setup the view matrix. */
@@ -531,14 +535,14 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region,
float x1i, x2i, y1i, y2i;
rctf viewborder;
- Camera *ca = NULL;
- RegionView3D *rv3d = region->regiondata;
+ Camera *ca = nullptr;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
- if (v3d->camera == NULL) {
+ if (v3d->camera == nullptr) {
return;
}
if (v3d->camera->type == OB_CAMERA) {
- ca = v3d->camera->data;
+ ca = static_cast<Camera *>(v3d->camera->data);
}
ED_view3d_calc_camera_border(scene, depsgraph, region, v3d, rv3d, &viewborder, false);
@@ -557,10 +561,10 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region,
* obscures the 3D camera border */
/* NOTE: with VIEW3D_CAMERA_BORDER_HACK defined this error isn't noticeable
* but keep it here in case we need to remove the workaround */
- x1i = (int)(x1 - 1.0001f);
- y1i = (int)(y1 - 1.0001f);
- x2i = (int)(x2 + (1.0f - 0.0001f));
- y2i = (int)(y2 + (1.0f - 0.0001f));
+ x1i = int(x1 - 1.0001f);
+ y1i = int(y1 - 1.0001f);
+ x2i = int(x2 + (1.0f - 0.0001f));
+ y2i = int(y2 + (1.0f - 0.0001f));
uint shdr_pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -711,24 +715,23 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region,
}
if (ca->flag & CAM_SHOW_SAFE_MARGINS) {
- UI_draw_safe_areas(shdr_pos,
- &(const rctf){
- .xmin = x1,
- .xmax = x2,
- .ymin = y1,
- .ymax = y2,
- },
- scene->safe_areas.title,
- scene->safe_areas.action);
+ rctf margins_rect{};
+ margins_rect.xmin = x1;
+ margins_rect.xmax = x2;
+ margins_rect.ymin = y1;
+ margins_rect.ymax = y2;
+
+ UI_draw_safe_areas(
+ shdr_pos, &margins_rect, scene->safe_areas.title, scene->safe_areas.action);
if (ca->flag & CAM_SHOW_SAFE_CENTER) {
+ rctf center_rect{};
+ center_rect.xmin = x1;
+ center_rect.xmax = x2;
+ center_rect.ymin = y1;
+ center_rect.ymax = y2;
UI_draw_safe_areas(shdr_pos,
- &(const rctf){
- .xmin = x1,
- .xmax = x2,
- .ymin = y1,
- .ymax = y2,
- },
+ &center_rect,
scene->safe_areas.title_center,
scene->safe_areas.action_center);
}
@@ -840,7 +843,7 @@ float ED_scene_grid_scale(const Scene *scene, const char **r_grid_unit)
if (r_grid_unit) {
*r_grid_unit = BKE_unit_display_name_get(usys, i);
}
- return (float)BKE_unit_scalar_get(usys, i) / scene->unit.scale_length;
+ return float(BKE_unit_scalar_get(usys, i)) / scene->unit.scale_length;
}
}
@@ -874,7 +877,7 @@ void ED_view3d_grid_steps(const Scene *scene,
int i;
for (i = 0; i < len; i++) {
- r_grid_steps[i] = (float)BKE_unit_scalar_get(usys, len - 1 - i) * grid_scale;
+ r_grid_steps[i] = float(BKE_unit_scalar_get(usys, len - 1 - i)) * grid_scale;
}
for (; i < STEPS_LEN; i++) {
/* Fill last slots */
@@ -904,7 +907,7 @@ float ED_view3d_grid_view_scale(Scene *scene,
const char **r_grid_unit)
{
float grid_scale;
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
if (!rv3d->is_persp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
/* Decrease the distance between grid snap points depending on zoom. */
float dist = 12.0f / (region->sizex * rv3d->winmat[0][0]);
@@ -1002,7 +1005,7 @@ static void draw_view_axis(RegionView3D *rv3d, const rcti *rect)
for (int axis_i = 0; axis_i < 3; axis_i++) {
int i = axis_order[axis_i];
- const char axis_text[2] = {'x' + i, '\0'};
+ const char axis_text[2] = {char('x' + i), '\0'};
BLF_color4ubv(BLF_default(), axis_col[i]);
BLF_draw_default(axis_pos[i][0] + 2, axis_pos[i][1] + 2, 0.0f, axis_text, 1);
}
@@ -1060,7 +1063,7 @@ static void draw_rotation_guide(const RegionView3D *rv3d)
# define ROT_AXIS_DETAIL 13
const float s = 0.05f * scale;
- const float step = 2.0f * (float)(M_PI / ROT_AXIS_DETAIL);
+ const float step = 2.0f * float(M_PI / ROT_AXIS_DETAIL);
float q[4]; /* rotate ring so it's perpendicular to axis */
const int upright = fabsf(rv3d->rot_axis[2]) >= 0.95f;
@@ -1121,7 +1124,7 @@ static void view3d_draw_border(const bContext *C, ARegion *region)
{
Scene *scene = CTX_data_scene(C);
Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C);
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
View3D *v3d = CTX_wm_view3d(C);
if (rv3d->persp == RV3D_CAMOB) {
@@ -1141,7 +1144,7 @@ static void view3d_draw_border(const bContext *C, ARegion *region)
/**
* Draw Info
*/
-static void view3d_draw_grease_pencil(const bContext *UNUSED(C))
+static void view3d_draw_grease_pencil(const bContext * /*C*/)
{
/* TODO: viewport. */
}
@@ -1151,7 +1154,7 @@ static void view3d_draw_grease_pencil(const bContext *UNUSED(C))
*/
static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
{
- const char *name = NULL;
+ const char *name = nullptr;
switch (rv3d->view) {
case RV3D_VIEW_FRONT:
@@ -1207,7 +1210,7 @@ static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
if (rv3d->persp == RV3D_CAMOB) {
if ((v3d->camera) && (v3d->camera->type == OB_CAMERA)) {
Camera *cam;
- cam = v3d->camera->data;
+ cam = static_cast<Camera *>(v3d->camera->data);
if (cam->type == CAM_PERSP) {
name = IFACE_("Camera Perspective");
}
@@ -1234,9 +1237,9 @@ static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
static void draw_viewport_name(ARegion *region, View3D *v3d, int xoffset, int *yoffset)
{
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
const char *name = view3d_get_name(v3d, rv3d);
- const char *name_array[3] = {name, NULL, NULL};
+ const char *name_array[3] = {name, nullptr, nullptr};
int name_array_len = 1;
const int font_id = BLF_default();
@@ -1245,7 +1248,7 @@ static void draw_viewport_name(ARegion *region, View3D *v3d, int xoffset, int *y
char tmpstr[96 + 6];
BLF_enable(font_id, BLF_SHADOW);
- BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f});
+ BLF_shadow(font_id, 5, float4{0.0f, 0.0f, 0.0f, 1.0f});
BLF_shadow_offset(font_id, 1, -1);
if (RV3D_VIEW_IS_AXIS(rv3d->view) && (rv3d->view_axis_roll != RV3D_VIEW_AXIS_ROLL_0)) {
@@ -1292,7 +1295,7 @@ static void draw_viewport_name(ARegion *region, View3D *v3d, int xoffset, int *y
* frame-number, collection, object name, bone name (if available), marker name (if available).
*/
static void draw_selected_name(
- Scene *scene, ViewLayer *view_layer, Object *ob, int xoffset, int *yoffset)
+ const View3D *v3d, Scene *scene, ViewLayer *view_layer, Object *ob, int xoffset, int *yoffset)
{
const int cfra = scene->r.cfra;
const char *msg_pin = " (Pinned)";
@@ -1303,14 +1306,15 @@ static void draw_selected_name(
char info[300];
char *s = info;
- s += sprintf(s, "(%d)", cfra);
+ s += BLI_sprintf(s, "(%d)", cfra);
- if ((ob == NULL) || (ob->mode == OB_MODE_OBJECT)) {
- LayerCollection *layer_collection = view_layer->active_collection;
- s += sprintf(s,
- " %s%s",
- BKE_collection_ui_name_get(layer_collection->collection),
- (ob == NULL) ? "" : " |");
+ if ((ob == nullptr) || (ob->mode == OB_MODE_OBJECT)) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LayerCollection *layer_collection = BKE_view_layer_active_collection_get(view_layer);
+ s += BLI_sprintf(s,
+ " %s%s",
+ BKE_collection_ui_name_get(layer_collection->collection),
+ (ob == nullptr) ? "" : " |");
}
/* Info can contain:
@@ -1332,7 +1336,7 @@ static void draw_selected_name(
/* name(s) to display depends on type of object */
if (ob->type == OB_ARMATURE) {
- bArmature *arm = ob->data;
+ bArmature *arm = static_cast<bArmature *>(ob->data);
/* show name of active bone too (if possible) */
if (arm->edbo) {
@@ -1352,12 +1356,12 @@ static void draw_selected_name(
}
}
else if (ELEM(ob->type, OB_MESH, OB_LATTICE, OB_CURVES_LEGACY)) {
- /* try to display active bone and active shapekey too (if they exist) */
+ /* Try to display active bone and active shape-key too (if they exist). */
if (ob->type == OB_MESH && ob->mode & OB_MODE_WEIGHT_PAINT) {
Object *armobj = BKE_object_pose_armature_get(ob);
if (armobj && armobj->mode & OB_MODE_POSE) {
- bArmature *arm = armobj->data;
+ bArmature *arm = static_cast<bArmature *>(armobj->data);
if (arm->act_bone) {
if (arm->act_bone->layer & arm->layer) {
s += BLI_strcpy_rlen(s, msg_sep);
@@ -1369,7 +1373,7 @@ static void draw_selected_name(
Key *key = BKE_key_from_object(ob);
if (key) {
- KeyBlock *kb = BLI_findlink(&key->block, ob->shapenr - 1);
+ KeyBlock *kb = static_cast<KeyBlock *>(BLI_findlink(&key->block, ob->shapenr - 1));
if (kb) {
s += BLI_strcpy_rlen(s, msg_sep);
s += BLI_strcpy_rlen(s, kb->name);
@@ -1382,7 +1386,7 @@ static void draw_selected_name(
/* color depends on whether there is a keyframe */
if (id_frame_has_keyframe(
- (ID *)ob, /* BKE_scene_ctime_get(scene) */ (float)cfra, ANIMFILTER_KEYS_LOCAL)) {
+ (ID *)ob, /* BKE_scene_ctime_get(scene) */ float(cfra), ANIMFILTER_KEYS_LOCAL)) {
UI_FontThemeColor(font_id, TH_TIME_KEYFRAME);
}
else if (ED_gpencil_has_keyframe_v3d(scene, ob, cfra)) {
@@ -1394,7 +1398,7 @@ static void draw_selected_name(
}
else {
/* no object */
- if (ED_gpencil_has_keyframe_v3d(scene, NULL, cfra)) {
+ if (ED_gpencil_has_keyframe_v3d(scene, nullptr, cfra)) {
UI_FontThemeColor(font_id, TH_TIME_GP_KEYFRAME);
}
else {
@@ -1403,11 +1407,17 @@ static void draw_selected_name(
}
if (markern) {
- s += sprintf(s, " <%s>", markern);
+ s += BLI_sprintf(s, " <%s>", markern);
+ }
+
+ if (v3d->flag2 & V3D_SHOW_VIEWER) {
+ if (!BLI_listbase_is_empty(&v3d->viewer_path.path)) {
+ s += BLI_sprintf(s, "%s", IFACE_(" (Viewer)"));
+ }
}
BLF_enable(font_id, BLF_SHADOW);
- BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f});
+ BLF_shadow(font_id, 5, float4{0.0f, 0.0f, 0.0f, 1.0f});
BLF_shadow_offset(font_id, 1, -1);
*yoffset -= VIEW3D_OVERLAY_LINEHEIGHT;
@@ -1419,9 +1429,9 @@ static void draw_selected_name(
static void draw_grid_unit_name(
Scene *scene, ARegion *region, View3D *v3d, int xoffset, int *yoffset)
{
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
if (!rv3d->is_persp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
- const char *grid_unit = NULL;
+ const char *grid_unit = nullptr;
int font_id = BLF_default();
ED_view3d_grid_view_scale(scene, v3d, region, &grid_unit);
@@ -1434,7 +1444,7 @@ static void draw_grid_unit_name(
*yoffset -= VIEW3D_OVERLAY_LINEHEIGHT;
BLF_enable(font_id, BLF_SHADOW);
- BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f});
+ BLF_shadow(font_id, 5, float4{0.0f, 0.0f, 0.0f, 1.0f});
BLF_shadow_offset(font_id, 1, -1);
BLF_draw_default(xoffset, *yoffset, 0.0f, numstr[0] ? numstr : grid_unit, sizeof(numstr));
BLF_disable(font_id, BLF_SHADOW);
@@ -1444,7 +1454,7 @@ static void draw_grid_unit_name(
void view3d_draw_region_info(const bContext *C, ARegion *region)
{
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
wmWindowManager *wm = CTX_wm_manager(C);
@@ -1497,8 +1507,9 @@ void view3d_draw_region_info(const bContext *C, ARegion *region)
}
if (U.uiflag & USER_DRAWVIEWINFO) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
- draw_selected_name(scene, view_layer, ob, xoffset, &yoffset);
+ draw_selected_name(v3d, scene, view_layer, ob, xoffset, &yoffset);
}
if (v3d->gridflag & (V3D_SHOW_FLOOR | V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z)) {
@@ -1510,7 +1521,7 @@ void view3d_draw_region_info(const bContext *C, ARegion *region)
}
if ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 && (v3d->overlay.flag & V3D_OVERLAY_STATS)) {
- View3D *v3d_local = v3d->localvd ? v3d : NULL;
+ View3D *v3d_local = v3d->localvd ? v3d : nullptr;
ED_info_draw_stats(
bmain, scene, view_layer, v3d_local, xoffset, &yoffset, VIEW3D_OVERLAY_LINEHEIGHT);
}
@@ -1532,9 +1543,9 @@ static void view3d_draw_view(const bContext *C, ARegion *region)
CTX_data_scene(C),
region,
CTX_wm_view3d(C),
- NULL,
- NULL,
- NULL);
+ nullptr,
+ nullptr,
+ nullptr);
/* Only 100% compliant on new spec goes below */
DRW_draw_view(C);
@@ -1554,11 +1565,23 @@ RenderEngineType *ED_view3d_engine_type(const Scene *scene, int drawtype)
return type;
}
+static void view3d_update_viewer_path(const bContext *C)
+{
+ View3D *v3d = CTX_wm_view3d(C);
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ /* Always use viewer path from workspace, pinning is not supported currently. */
+ if (!BKE_viewer_path_equal(&v3d->viewer_path, &workspace->viewer_path)) {
+ BKE_viewer_path_clear(&v3d->viewer_path);
+ BKE_viewer_path_copy(&v3d->viewer_path, &workspace->viewer_path);
+ }
+}
+
void view3d_main_region_draw(const bContext *C, ARegion *region)
{
Main *bmain = CTX_data_main(C);
View3D *v3d = CTX_wm_view3d(C);
+ view3d_update_viewer_path(C);
view3d_draw_view(C, region);
DRW_cache_free_old_subdiv();
@@ -1620,7 +1643,7 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph,
GPUOffScreen *ofs,
GPUViewport *viewport)
{
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
RenderEngineType *engine_type = ED_view3d_engine_type(scene, drawtype);
/* Store `orig` variables. */
@@ -1640,15 +1663,12 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph,
* Without this the #wmPaintCursor can't use the pixel size & view matrices for drawing.
*/
struct RV3DMatrixStore *rv3d_mats;
- } orig = {
- .v3d_shading_type = v3d->shading.type,
-
- .region_winx = region->winx,
- .region_winy = region->winy,
- .region_winrct = region->winrct,
-
- .rv3d_mats = ED_view3d_mats_rv3d_backup(region->regiondata),
- };
+ } orig{};
+ orig.v3d_shading_type = eDrawType(v3d->shading.type);
+ orig.region_winx = region->winx;
+ orig.region_winy = region->winy;
+ orig.region_winrct = region->winrct;
+ orig.rv3d_mats = ED_view3d_mats_rv3d_backup(static_cast<RegionView3D *>(region->regiondata));
UI_Theme_Store(&orig.theme_state);
UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
@@ -1679,7 +1699,7 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph,
GPU_matrix_push();
GPU_matrix_identity_set();
- if ((viewname != NULL && viewname[0] != '\0') && (viewmat == NULL) &&
+ if ((viewname != nullptr && viewname[0] != '\0') && (viewmat == nullptr) &&
rv3d->persp == RV3D_CAMOB && v3d->camera) {
view3d_stereo3d_setup_offscreen(depsgraph, scene, v3d, region, winmat, viewname);
}
@@ -1708,7 +1728,7 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph,
/* Optionally do _not_ restore rv3d matrices (e.g. they are used/stored in the ImBuff for
* reprojection, see texture_paint_image_from_view_exec(). */
if (restore_rv3d_mats) {
- ED_view3d_mats_rv3d_restore(region->regiondata, orig.rv3d_mats);
+ ED_view3d_mats_rv3d_restore(static_cast<RegionView3D *>(region->regiondata), orig.rv3d_mats);
}
MEM_freeN(orig.rv3d_mats);
@@ -1740,8 +1760,8 @@ void ED_view3d_draw_offscreen_simple(Depsgraph *depsgraph,
GPUOffScreen *ofs,
GPUViewport *viewport)
{
- View3D v3d = {NULL};
- ARegion ar = {NULL};
+ View3D v3d = {nullptr};
+ ARegion ar = {nullptr};
RegionView3D rv3d = {{{0}}};
v3d.regionbase.first = v3d.regionbase.last = &ar;
@@ -1749,7 +1769,7 @@ void ED_view3d_draw_offscreen_simple(Depsgraph *depsgraph,
ar.regiontype = RGN_TYPE_WINDOW;
View3DShading *source_shading_settings = &scene->display.shading;
- if (draw_flags & V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS && shading_override != NULL) {
+ if (draw_flags & V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS && shading_override != nullptr) {
source_shading_settings = shading_override;
}
memcpy(&v3d.shading, source_shading_settings, sizeof(View3DShading));
@@ -1842,7 +1862,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
GPUOffScreen *ofs,
char err_out[256])
{
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
const bool draw_sky = (alpha_mode == R_ADDSKY);
/* view state */
@@ -1851,7 +1871,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
if (ofs && ((GPU_offscreen_width(ofs) != sizex) || (GPU_offscreen_height(ofs) != sizey))) {
/* sizes differ, can't reuse */
- ofs = NULL;
+ ofs = nullptr;
}
GPUFrameBuffer *old_fb = GPU_framebuffer_active_get();
@@ -1860,15 +1880,15 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
GPU_framebuffer_restore();
}
- const bool own_ofs = (ofs == NULL);
+ const bool own_ofs = (ofs == nullptr);
DRW_opengl_context_enable();
if (own_ofs) {
/* bind */
ofs = GPU_offscreen_create(sizex, sizey, true, GPU_RGBA8, err_out);
- if (ofs == NULL) {
+ if (ofs == nullptr) {
DRW_opengl_context_disable();
- return NULL;
+ return nullptr;
}
}
@@ -1900,7 +1920,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
float clip_start, clipend;
is_ortho = ED_view3d_viewplane_get(
- depsgraph, v3d, rv3d, sizex, sizey, &viewplane, &clip_start, &clipend, NULL);
+ depsgraph, v3d, rv3d, sizex, sizey, &viewplane, &clip_start, &clipend, nullptr);
if (is_ortho) {
orthographic_m4(winmat,
viewplane.xmin,
@@ -1931,7 +1951,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
* When using workbench the color differences haven't been reported as a bug. But users also use
* the viewport rendering to render Eevee scenes. In the later situation the saved colors are
* totally wrong. */
- const bool do_color_management = (ibuf->rect_float == NULL);
+ const bool do_color_management = (ibuf->rect_float == nullptr);
ED_view3d_draw_offscreen(depsgraph,
scene,
drawtype,
@@ -1939,7 +1959,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
region,
sizex,
sizey,
- NULL,
+ nullptr,
winmat,
true,
draw_sky,
@@ -1947,7 +1967,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
do_color_management,
restore_rv3d_mats,
ofs,
- NULL);
+ nullptr);
if (ibuf->rect_float) {
GPU_offscreen_read_pixels(ofs, GPU_DATA_FLOAT, ibuf->rect_float);
@@ -1990,8 +2010,8 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Depsgraph *depsgraph,
GPUOffScreen *ofs,
char err_out[256])
{
- View3D v3d = {NULL};
- ARegion region = {NULL};
+ View3D v3d = {nullptr};
+ ARegion region = {nullptr};
RegionView3D rv3d = {{{0}}};
/* connect data */
@@ -2001,7 +2021,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Depsgraph *depsgraph,
v3d.camera = camera;
View3DShading *source_shading_settings = &scene->display.shading;
- if (draw_flags & V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS && shading_override != NULL) {
+ if (draw_flags & V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS && shading_override != nullptr) {
source_shading_settings = shading_override;
}
memcpy(&v3d.shading, source_shading_settings, sizeof(View3DShading));
@@ -2046,7 +2066,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Depsgraph *depsgraph,
rv3d.persp = RV3D_CAMOB;
- copy_m4_m4(rv3d.viewinv, v3d.camera->obmat);
+ copy_m4_m4(rv3d.viewinv, v3d.camera->object_to_world);
normalize_m4(rv3d.viewinv);
invert_m4_m4(rv3d.viewmat, rv3d.viewinv);
@@ -2072,7 +2092,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Depsgraph *depsgraph,
return ED_view3d_draw_offscreen_imbuf(depsgraph,
scene,
- v3d.shading.type,
+ eDrawType(v3d.shading.type),
&v3d,
&region,
width,
@@ -2121,6 +2141,7 @@ bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const
* \note Only use in object mode.
*/
static void validate_object_select_id(struct Depsgraph *depsgraph,
+ const Scene *scene,
ViewLayer *view_layer,
ARegion *region,
View3D *v3d,
@@ -2153,6 +2174,7 @@ static void validate_object_select_id(struct Depsgraph *depsgraph,
}
if (obact_eval && ((obact_eval->base_flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT) != 0)) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, obact);
DRW_select_buffer_context_create(&base, 1, -1);
}
@@ -2166,7 +2188,7 @@ static void view3d_opengl_read_Z_pixels(GPUViewport *viewport, rcti *rect, void
{
GPUTexture *depth_tx = GPU_viewport_depth_texture(viewport);
- GPUFrameBuffer *depth_read_fb = NULL;
+ GPUFrameBuffer *depth_read_fb = nullptr;
GPU_framebuffer_ensure_config(&depth_read_fb,
{
GPU_ATTACHMENT_TEXTURE(depth_tx),
@@ -2188,12 +2210,13 @@ static void view3d_opengl_read_Z_pixels(GPUViewport *viewport, rcti *rect, void
void ED_view3d_select_id_validate(ViewContext *vc)
{
- validate_object_select_id(vc->depsgraph, vc->view_layer, vc->region, vc->v3d, vc->obact);
+ validate_object_select_id(
+ vc->depsgraph, vc->scene, vc->view_layer, vc->region, vc->v3d, vc->obact);
}
int ED_view3d_backbuf_sample_size_clamp(ARegion *region, const float dist)
{
- return (int)min_ff(ceilf(dist), (float)max_ii(region->winx, region->winx));
+ return int(min_ff(ceilf(dist), float(max_ii(region->winx, region->winx))));
}
/** \} */
@@ -2205,12 +2228,11 @@ int ED_view3d_backbuf_sample_size_clamp(ARegion *region, const float dist)
void view3d_depths_rect_create(ARegion *region, rcti *rect, ViewDepths *r_d)
{
/* clamp rect by region */
- rcti r = {
- .xmin = 0,
- .xmax = region->winx - 1,
- .ymin = 0,
- .ymax = region->winy - 1,
- };
+ rcti r{};
+ r.xmin = 0;
+ r.xmax = region->winx - 1;
+ r.ymin = 0;
+ r.ymax = region->winy - 1;
/* Constrain rect to depth bounds */
BLI_rcti_isect(&r, rect, rect);
@@ -2223,7 +2245,7 @@ void view3d_depths_rect_create(ARegion *region, rcti *rect, ViewDepths *r_d)
int h = BLI_rcti_size_y(rect);
if (w <= 0 || h <= 0) {
- r_d->depths = NULL;
+ r_d->depths = nullptr;
return;
}
@@ -2232,7 +2254,7 @@ void view3d_depths_rect_create(ARegion *region, rcti *rect, ViewDepths *r_d)
r_d->w = w;
r_d->h = h;
- r_d->depths = MEM_mallocN(sizeof(float) * w * h, "View depths Subset");
+ r_d->depths = static_cast<float *>(MEM_mallocN(sizeof(float) * w * h, "View depths Subset"));
{
GPUViewport *viewport = WM_draw_region_get_viewport(region);
@@ -2243,22 +2265,23 @@ void view3d_depths_rect_create(ARegion *region, rcti *rect, ViewDepths *r_d)
}
}
-/* NOTE: with nouveau drivers the glReadPixels() is very slow. T24339. */
+/* NOTE: with NOUVEAU drivers the #glReadPixels() is very slow. T24339. */
static ViewDepths *view3d_depths_create(ARegion *region)
{
- ViewDepths *d = MEM_callocN(sizeof(ViewDepths), "ViewDepths");
+ ViewDepths *d = MEM_cnew<ViewDepths>("ViewDepths");
{
GPUViewport *viewport = WM_draw_region_get_viewport(region);
GPUTexture *depth_tx = GPU_viewport_depth_texture(viewport);
- uint32_t *int_depths = GPU_texture_read(depth_tx, GPU_DATA_UINT_24_8, 0);
+ uint32_t *int_depths = static_cast<uint32_t *>(
+ GPU_texture_read(depth_tx, GPU_DATA_UINT_24_8, 0));
d->w = GPU_texture_width(depth_tx);
d->h = GPU_texture_height(depth_tx);
d->depths = (float *)int_depths;
/* Convert in-place. */
int pixel_count = d->w * d->h;
for (int i = 0; i < pixel_count; i++) {
- d->depths[i] = (int_depths[i] >> 8u) / (float)0xFFFFFF;
+ d->depths[i] = (int_depths[i] >> 8u) / float(0xFFFFFF);
}
/* Assumed to be this as they are never changed. */
d->depth_range[0] = 0.0;
@@ -2270,13 +2293,13 @@ static ViewDepths *view3d_depths_create(ARegion *region)
float view3d_depth_near(ViewDepths *d)
{
/* Convert to float for comparisons. */
- const float near = (float)d->depth_range[0];
- const float far_real = (float)d->depth_range[1];
+ const float near = float(d->depth_range[0]);
+ const float far_real = float(d->depth_range[1]);
float far = far_real;
const float *depths = d->depths;
float depth = FLT_MAX;
- int i = (int)d->w * (int)d->h; /* Cast to avoid short overflow. */
+ int i = int(d->w) * int(d->h); /* Cast to avoid short overflow. */
/* Far is both the starting 'far' value
* and the closest value found. */
@@ -2299,13 +2322,13 @@ void ED_view3d_depth_override(Depsgraph *depsgraph,
{
if (v3d->runtime.flag & V3D_RUNTIME_DEPTHBUF_OVERRIDDEN) {
/* Force redraw if `r_depths` is required. */
- if (!r_depths || *r_depths != NULL) {
+ if (!r_depths || *r_depths != nullptr) {
return;
}
}
struct bThemeState theme_state;
Scene *scene = DEG_get_evaluated_scene(depsgraph);
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
short flag = v3d->flag;
/* temp set drawtype to solid */
@@ -2316,8 +2339,15 @@ void ED_view3d_depth_override(Depsgraph *depsgraph,
UI_Theme_Store(&theme_state);
UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
- ED_view3d_draw_setup_view(
- G_MAIN->wm.first, NULL, depsgraph, scene, region, v3d, NULL, NULL, NULL);
+ ED_view3d_draw_setup_view(static_cast<wmWindowManager *>(G_MAIN->wm.first),
+ nullptr,
+ depsgraph,
+ scene,
+ region,
+ v3d,
+ nullptr,
+ nullptr,
+ nullptr);
/* get surface depth without bias */
rv3d->rflag |= RV3D_ZOFFSET_DISABLED;
@@ -2329,13 +2359,14 @@ void ED_view3d_depth_override(Depsgraph *depsgraph,
GPUViewport *viewport = WM_draw_region_get_viewport(region);
/* When Blender is starting, a click event can trigger a depth test while the viewport is not
* yet available. */
- if (viewport != NULL) {
+ if (viewport != nullptr) {
switch (mode) {
case V3D_DEPTH_NO_GPENCIL:
- DRW_draw_depth_loop(depsgraph, region, v3d, viewport);
+ DRW_draw_depth_loop(
+ depsgraph, region, v3d, viewport, false, true, (v3d->flag2 & V3D_HIDE_OVERLAYS) == 0);
break;
case V3D_DEPTH_GPENCIL_ONLY:
- DRW_draw_depth_loop_gpencil(depsgraph, region, v3d, viewport);
+ DRW_draw_depth_loop(depsgraph, region, v3d, viewport, true, false, false);
break;
case V3D_DEPTH_OBJECT_ONLY:
DRW_draw_depth_object(
@@ -2376,7 +2407,7 @@ void ED_view3d_depths_free(ViewDepths *depths)
* \{ */
void ED_view3d_datamask(const bContext *C,
- const Scene *UNUSED(scene),
+ const Scene * /*scene*/,
const View3D *v3d,
CustomData_MeshMasks *r_cddata_masks)
{
@@ -2398,9 +2429,8 @@ void ED_view3d_datamask(const bContext *C,
(v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT)) {
r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
}
- if ((CTX_data_mode_enum(C) == CTX_MODE_SCULPT)) {
+ if (CTX_data_mode_enum(C) == CTX_MODE_SCULPT) {
r_cddata_masks->vmask |= CD_MASK_PAINT_MASK;
- r_cddata_masks->pmask |= CD_MASK_SCULPT_FACE_SETS;
}
}
@@ -2414,7 +2444,7 @@ void ED_view3d_screen_datamask(const bContext *C,
/* Check if we need tfaces & mcols due to view mode. */
LISTBASE_FOREACH (const ScrArea *, area, &screen->areabase) {
if (area->spacetype == SPACE_VIEW3D) {
- ED_view3d_datamask(C, scene, area->spacedata.first, r_cddata_masks);
+ ED_view3d_datamask(C, scene, static_cast<View3D *>(area->spacedata.first), r_cddata_masks);
}
}
}
@@ -2444,7 +2474,8 @@ struct RV3DMatrixStore {
struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d)
{
- struct RV3DMatrixStore *rv3dmat = MEM_mallocN(sizeof(*rv3dmat), __func__);
+ struct RV3DMatrixStore *rv3dmat = static_cast<RV3DMatrixStore *>(
+ MEM_mallocN(sizeof(*rv3dmat), __func__));
copy_m4_m4(rv3dmat->winmat, rv3d->winmat);
copy_m4_m4(rv3dmat->viewmat, rv3d->viewmat);
copy_m4_m4(rv3dmat->persmat, rv3d->persmat);
@@ -2475,7 +2506,7 @@ void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixSto
void ED_scene_draw_fps(const Scene *scene, int xoffset, int *yoffset)
{
- ScreenFrameRateInfo *fpsi = scene->fps_info;
+ ScreenFrameRateInfo *fpsi = static_cast<ScreenFrameRateInfo *>(scene->fps_info);
char printable[16];
if (!fpsi || !fpsi->lredrawtime || !fpsi->redrawtime) {
@@ -2485,8 +2516,8 @@ void ED_scene_draw_fps(const Scene *scene, int xoffset, int *yoffset)
printable[0] = '\0';
/* Doing an average for a more robust calculation. */
- fpsi->redrawtimes_fps[fpsi->redrawtime_index] = (float)(1.0 /
- (fpsi->lredrawtime - fpsi->redrawtime));
+ fpsi->redrawtimes_fps[fpsi->redrawtime_index] = float(1.0 /
+ (fpsi->lredrawtime - fpsi->redrawtime));
float fps = 0.0f;
int tot = 0;
@@ -2504,17 +2535,17 @@ void ED_scene_draw_fps(const Scene *scene, int xoffset, int *yoffset)
const int font_id = BLF_default();
/* Is this more than half a frame behind? */
- if (fps + 0.5f < (float)(FPS)) {
+ if (fps + 0.5f < float(FPS)) {
UI_FontThemeColor(font_id, TH_REDALERT);
BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %.2f"), fps);
}
else {
UI_FontThemeColor(font_id, TH_TEXT_HI);
- BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %i"), (int)(fps + 0.5f));
+ BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %i"), int(fps + 0.5f));
}
BLF_enable(font_id, BLF_SHADOW);
- BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f});
+ BLF_shadow(font_id, 5, float4{0.0f, 0.0f, 0.0f, 1.0f});
BLF_shadow_offset(font_id, 1, -1);
*yoffset -= VIEW3D_OVERLAY_LINEHEIGHT;
@@ -2539,7 +2570,7 @@ static bool view3d_main_region_do_render_draw(const Scene *scene)
bool ED_view3d_calc_render_border(
const Scene *scene, Depsgraph *depsgraph, View3D *v3d, ARegion *region, rcti *rect)
{
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
bool use_border;
/* Test if there is a 3d view rendering. */
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 6001f701c00..23e06c895fc 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -300,7 +300,7 @@ static int render_border_exec(bContext *C, wmOperator *op)
}
/* drawing a border outside the camera view switches off border rendering */
- if ((border.xmin == border.xmax || border.ymin == border.ymax)) {
+ if (border.xmin == border.xmax || border.ymin == border.ymax) {
if (rv3d->persp == RV3D_CAMOB) {
scene->r.mode &= ~R_BORDER;
}
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_armature.c b/source/blender/editors/space_view3d/view3d_gizmo_armature.c
index 89b46069df1..8a4301d1314 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_armature.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_armature.c
@@ -113,8 +113,10 @@ static bool WIDGETGROUP_armature_spline_poll(const bContext *C, wmGizmoGroupType
return false;
}
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base = BKE_view_layer_active_base_get(view_layer);
if (base && BASE_SELECTABLE(v3d, base)) {
Object *ob = BKE_object_pose_armature_get(base->object);
if (ob) {
@@ -132,7 +134,9 @@ static bool WIDGETGROUP_armature_spline_poll(const bContext *C, wmGizmoGroupType
static void WIDGETGROUP_armature_spline_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_object_pose_armature_get(BKE_view_layer_active_object_get(view_layer));
bPoseChannel *pchan = BKE_pose_channel_active_if_layer_visible(ob);
@@ -165,7 +169,9 @@ static void WIDGETGROUP_armature_spline_setup(const bContext *C, wmGizmoGroup *g
static void WIDGETGROUP_armature_spline_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_object_pose_armature_get(BKE_view_layer_active_object_get(view_layer));
if (!gzgroup->customdata) {
@@ -182,7 +188,7 @@ static void WIDGETGROUP_armature_spline_refresh(const bContext *C, wmGizmoGroup
bspline_group->handles[i].index = i;
float mat[4][4];
- mul_m4_m4m4(mat, ob->obmat, (i == 0) ? pchan->disp_mat : pchan->disp_tail_mat);
+ mul_m4_m4m4(mat, ob->object_to_world, (i == 0) ? pchan->disp_mat : pchan->disp_tail_mat);
copy_m4_m4(gz->matrix_space, mat);
/* need to set property here for undo. TODO: would prefer to do this in _init. */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_camera.c b/source/blender/editors/space_view3d/view3d_gizmo_camera.c
index d4720d01d70..56a1f6212a0 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_camera.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_camera.c
@@ -55,8 +55,10 @@ static bool WIDGETGROUP_camera_poll(const bContext *C, wmGizmoGroupType *UNUSED(
return false;
}
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base = BKE_view_layer_active_base_get(view_layer);
if (base && BASE_SELECTABLE(v3d, base)) {
Object *ob = base->object;
if (ob->type == OB_CAMERA) {
@@ -72,7 +74,9 @@ static bool WIDGETGROUP_camera_poll(const bContext *C, wmGizmoGroupType *UNUSED(
static void WIDGETGROUP_camera_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
float dir[3];
@@ -81,7 +85,7 @@ static void WIDGETGROUP_camera_setup(const bContext *C, wmGizmoGroup *gzgroup)
struct CameraWidgetGroup *cagzgroup = MEM_callocN(sizeof(struct CameraWidgetGroup), __func__);
gzgroup->customdata = cagzgroup;
- negate_v3_v3(dir, ob->obmat[2]);
+ negate_v3_v3(dir, ob->object_to_world[2]);
/* dof distance */
{
@@ -124,7 +128,9 @@ static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *gzgroup)
struct CameraWidgetGroup *cagzgroup = gzgroup->customdata;
View3D *v3d = CTX_wm_view3d(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
Camera *ca = ob->data;
PointerRNA camera_ptr;
@@ -132,11 +138,11 @@ static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *gzgroup)
RNA_pointer_create(&ca->id, &RNA_Camera, ca, &camera_ptr);
- negate_v3_v3(dir, ob->obmat[2]);
+ negate_v3_v3(dir, ob->object_to_world[2]);
if ((ca->flag & CAM_SHOWLIMITS) && (v3d->gizmo_show_camera & V3D_GIZMO_SHOW_CAMERA_DOF_DIST)) {
- WM_gizmo_set_matrix_location(cagzgroup->dop_dist, ob->obmat[3]);
- WM_gizmo_set_matrix_rotation_from_yz_axis(cagzgroup->dop_dist, ob->obmat[1], dir);
+ WM_gizmo_set_matrix_location(cagzgroup->dop_dist, ob->object_to_world[3]);
+ WM_gizmo_set_matrix_rotation_from_yz_axis(cagzgroup->dop_dist, ob->object_to_world[1], dir);
WM_gizmo_set_scale(cagzgroup->dop_dist, ca->drawsize);
WM_gizmo_set_flag(cagzgroup->dop_dist, WM_GIZMO_HIDDEN, false);
@@ -151,7 +157,6 @@ static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *gzgroup)
}
/* TODO: make focal length/ortho ob_scale_inv widget optional. */
- const Scene *scene = CTX_data_scene(C);
const float aspx = (float)scene->r.xsch * scene->r.xasp;
const float aspy = (float)scene->r.ysch * scene->r.yasp;
const bool is_ortho = (ca->type == CAM_ORTHO);
@@ -178,17 +183,17 @@ static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *gzgroup)
aspect[1] = (sensor_fit == CAMERA_SENSOR_FIT_HOR) ? aspy / aspx : 1.0f;
unit_m4(widget->matrix_basis);
- WM_gizmo_set_matrix_location(widget, ob->obmat[3]);
- WM_gizmo_set_matrix_rotation_from_yz_axis(widget, ob->obmat[1], dir);
+ WM_gizmo_set_matrix_location(widget, ob->object_to_world[3]);
+ WM_gizmo_set_matrix_rotation_from_yz_axis(widget, ob->object_to_world[1], dir);
if (is_ortho) {
scale_matrix = ca->ortho_scale * 0.5f;
}
else {
const float ob_scale_inv[3] = {
- 1.0f / len_v3(ob->obmat[0]),
- 1.0f / len_v3(ob->obmat[1]),
- 1.0f / len_v3(ob->obmat[2]),
+ 1.0f / len_v3(ob->object_to_world[0]),
+ 1.0f / len_v3(ob->object_to_world[1]),
+ 1.0f / len_v3(ob->object_to_world[2]),
};
const float ob_scale_uniform_inv = (ob_scale_inv[0] + ob_scale_inv[1] + ob_scale_inv[2]) /
3.0f;
@@ -241,7 +246,9 @@ static void WIDGETGROUP_camera_message_subscribe(const bContext *C,
struct wmMsgBus *mbus)
{
ARegion *region = CTX_wm_region(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
Camera *ca = ob->data;
@@ -370,6 +377,7 @@ static bool WIDGETGROUP_camera_view_poll(const bContext *C, wmGizmoGroupType *UN
* We could change the rules for when to show. */
{
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
if (scene->camera != BKE_view_layer_active_object_get(view_layer)) {
return false;
}
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_empty.c b/source/blender/editors/space_view3d/view3d_gizmo_empty.c
index a7febe11672..03fc7328e39 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_empty.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_empty.c
@@ -99,8 +99,10 @@ static bool WIDGETGROUP_empty_image_poll(const bContext *C, wmGizmoGroupType *UN
return false;
}
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base = BKE_view_layer_active_base_get(view_layer);
if (base && BASE_SELECTABLE(v3d, base)) {
Object *ob = base->object;
if (ob->type == OB_EMPTY) {
@@ -132,10 +134,12 @@ static void WIDGETGROUP_empty_image_refresh(const bContext *C, wmGizmoGroup *gzg
{
struct EmptyImageWidgetGroup *igzgroup = gzgroup->customdata;
wmGizmo *gz = igzgroup->gizmo;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
- copy_m4_m4(gz->matrix_basis, ob->obmat);
+ copy_m4_m4(gz->matrix_basis, ob->object_to_world);
RNA_enum_set(gz->ptr,
"transform",
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c b/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c
index f2f9e9092fa..d194e2a6279 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c
@@ -42,8 +42,10 @@ static bool WIDGETGROUP_forcefield_poll(const bContext *C, wmGizmoGroupType *UNU
return false;
}
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base = BKE_view_layer_active_base_get(view_layer);
if (base && BASE_SELECTABLE(v3d, base)) {
Object *ob = base->object;
if (ob->pd && ob->pd->forcefield) {
@@ -73,7 +75,9 @@ static void WIDGETGROUP_forcefield_refresh(const bContext *C, wmGizmoGroup *gzgr
{
wmGizmoWrapper *wwrapper = gzgroup->customdata;
wmGizmo *gz = wwrapper->gizmo;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
PartDeflect *pd = ob->pd;
@@ -83,8 +87,8 @@ static void WIDGETGROUP_forcefield_refresh(const bContext *C, wmGizmoGroup *gzgr
PointerRNA field_ptr;
RNA_pointer_create(&ob->id, &RNA_FieldSettings, pd, &field_ptr);
- WM_gizmo_set_matrix_location(gz, ob->obmat[3]);
- WM_gizmo_set_matrix_rotation_from_z_axis(gz, ob->obmat[2]);
+ WM_gizmo_set_matrix_location(gz, ob->object_to_world[3]);
+ WM_gizmo_set_matrix_rotation_from_z_axis(gz, ob->object_to_world[2]);
WM_gizmo_set_matrix_offset_location(gz, ofs);
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
WM_gizmo_target_property_def_rna(gz, "offset", &field_ptr, "strength", -1);
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_light.c b/source/blender/editors/space_view3d/view3d_gizmo_light.c
index d0f58f43c2b..0b115bc0604 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_light.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_light.c
@@ -45,8 +45,10 @@ static bool WIDGETGROUP_light_spot_poll(const bContext *C, wmGizmoGroupType *UNU
return false;
}
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base = BKE_view_layer_active_base_get(view_layer);
if (base && BASE_SELECTABLE(v3d, base)) {
Object *ob = base->object;
if (ob->type == OB_LAMP) {
@@ -76,15 +78,17 @@ static void WIDGETGROUP_light_spot_refresh(const bContext *C, wmGizmoGroup *gzgr
{
wmGizmoWrapper *wwrapper = gzgroup->customdata;
wmGizmo *gz = wwrapper->gizmo;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
Light *la = ob->data;
float dir[3];
- negate_v3_v3(dir, ob->obmat[2]);
+ negate_v3_v3(dir, ob->object_to_world[2]);
WM_gizmo_set_matrix_rotation_from_z_axis(gz, dir);
- WM_gizmo_set_matrix_location(gz, ob->obmat[3]);
+ WM_gizmo_set_matrix_location(gz, ob->object_to_world[3]);
/* need to set property here for undo. TODO: would prefer to do this in _init. */
PointerRNA lamp_ptr;
@@ -156,8 +160,10 @@ static bool WIDGETGROUP_light_area_poll(const bContext *C, wmGizmoGroupType *UNU
return false;
}
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base = BKE_view_layer_active_base_get(view_layer);
if (base && BASE_SELECTABLE(v3d, base)) {
Object *ob = base->object;
if (ob->type == OB_LAMP) {
@@ -186,12 +192,14 @@ static void WIDGETGROUP_light_area_setup(const bContext *UNUSED(C), wmGizmoGroup
static void WIDGETGROUP_light_area_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
wmGizmoWrapper *wwrapper = gzgroup->customdata;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
Light *la = ob->data;
wmGizmo *gz = wwrapper->gizmo;
- copy_m4_m4(gz->matrix_basis, ob->obmat);
+ copy_m4_m4(gz->matrix_basis, ob->object_to_world);
int flag = ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE;
if (ELEM(la->area_shape, LA_AREA_SQUARE, LA_AREA_DISK)) {
@@ -239,13 +247,15 @@ static bool WIDGETGROUP_light_target_poll(const bContext *C, wmGizmoGroupType *U
return false;
}
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base = BKE_view_layer_active_base_get(view_layer);
if (base && BASE_SELECTABLE(v3d, base)) {
Object *ob = base->object;
if (ob->type == OB_LAMP) {
Light *la = ob->data;
- return (ELEM(la->type, LA_SUN, LA_SPOT, LA_AREA));
+ return ELEM(la->type, LA_SUN, LA_SPOT, LA_AREA);
}
#if 0
else if (ob->type == OB_CAMERA) {
@@ -280,11 +290,13 @@ static void WIDGETGROUP_light_target_setup(const bContext *UNUSED(C), wmGizmoGro
static void WIDGETGROUP_light_target_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
wmGizmoWrapper *wwrapper = gzgroup->customdata;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
wmGizmo *gz = wwrapper->gizmo;
- normalize_m4_m4(gz->matrix_basis, ob->obmat);
+ normalize_m4_m4(gz->matrix_basis, ob->object_to_world);
unit_m4(gz->matrix_offset);
if (ob->type == OB_LAMP) {
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
index 41af24977db..22ab6636c47 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
@@ -267,7 +267,7 @@ static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *g
icon_offset_from_axis = icon_offset * 2.1f;
break;
case USER_MINI_AXIS_TYPE_MINIMAL:
- icon_offset_from_axis = (UI_UNIT_X * 2.5) + ((U.rvisize * U.pixelsize * 2.0f));
+ icon_offset_from_axis = (UI_UNIT_X * 2.5) + (U.rvisize * U.pixelsize * 2.0f);
break;
case USER_MINI_AXIS_TYPE_NONE:
icon_offset_from_axis = icon_offset_mini * 0.75f;
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c
index 73ac3f3a1d8..70afb0eaff1 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c
@@ -118,7 +118,7 @@ static void gizmo_axis_draw(const bContext *C, wmGizmo *gz)
font.id = BLF_default();
BLF_disable(font.id, BLF_ROTATION | BLF_SHADOW | BLF_MATRIX | BLF_ASPECT | BLF_WORD_WRAP);
BLF_enable(font.id, BLF_BOLD);
- BLF_size(font.id, AXIS_TEXT_SIZE, 72);
+ BLF_size(font.id, AXIS_TEXT_SIZE);
BLF_position(font.id, 0, 0, 0);
/* Calculate the inverse of the (matrix_final * matrix_offset).
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.cc
index a0c010a6813..86aecfb6c34 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.cc
@@ -3,7 +3,7 @@
/** \file
* \ingroup wm
*
- * \name Preselection Gizmo
+ * \name Pre-selection Gizmo
*
* Use for tools to hover over data before activation.
*
@@ -19,8 +19,10 @@
#include "BKE_context.h"
#include "BKE_editmesh.h"
+#include "BKE_editmesh_cache.h"
#include "BKE_global.h"
#include "BKE_layer.h"
+#include "BKE_mesh.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
@@ -75,7 +77,7 @@ static bool gizmo_preselect_poll_for_draw(const bContext *C, wmGizmo *gz)
/** \name Mesh Element (Vert/Edge/Face) Pre-Select Gizmo API
* \{ */
-typedef struct MeshElemGizmo3D {
+struct MeshElemGizmo3D {
wmGizmo gizmo;
Base **bases;
uint bases_len;
@@ -83,8 +85,8 @@ typedef struct MeshElemGizmo3D {
int vert_index;
int edge_index;
int face_index;
- struct EditMesh_PreSelElem *psel;
-} MeshElemGizmo3D;
+ EditMesh_PreSelElem *psel;
+};
static void gizmo_preselect_elem_draw(const bContext *C, wmGizmo *gz)
{
@@ -95,7 +97,7 @@ static void gizmo_preselect_elem_draw(const bContext *C, wmGizmo *gz)
MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
if (gz_ele->base_index != -1) {
Object *ob = gz_ele->bases[gz_ele->base_index]->object;
- EDBM_preselect_elem_draw(gz_ele->psel, ob->obmat);
+ EDBM_preselect_elem_draw(gz_ele->psel, ob->object_to_world);
}
}
@@ -115,22 +117,24 @@ static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int
EDBM_preselect_action_set(gz_ele->psel, PRESELECT_ACTION_DELETE);
}
- struct {
+ struct Best {
Object *ob;
BMElem *ele;
float dist;
int base_index;
- } best = {
- .dist = ED_view3d_select_dist_px(),
- };
+ } best{};
+ best.dist = ED_view3d_select_dist_px();
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
- if (((gz_ele->bases)) == NULL || (gz_ele->bases[0] != view_layer->basact)) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ if ((gz_ele->bases) == nullptr ||
+ (gz_ele->bases[0] != BKE_view_layer_active_base_get(view_layer))) {
MEM_SAFE_FREE(gz_ele->bases);
gz_ele->bases = BKE_view_layer_array_from_bases_in_edit_mode(
- view_layer, v3d, &gz_ele->bases_len);
+ scene, view_layer, v3d, &gz_ele->bases_len);
}
}
@@ -180,8 +184,8 @@ static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int
if (eve_test) {
BMVert *vert = (BMVert *)eve_test;
float vert_p_co[2], vert_co[3];
- const float mval_f[2] = {UNPACK2(vc.mval)};
- mul_v3_m4v3(vert_co, gz_ele->bases[base_index_vert]->object->obmat, vert->co);
+ const float mval_f[2] = {float(vc.mval[0]), float(vc.mval[1])};
+ mul_v3_m4v3(vert_co, gz_ele->bases[base_index_vert]->object->object_to_world, vert->co);
ED_view3d_project_v2(vc.region, vert_co, vert_p_co);
float len = len_v2v2(vert_p_co, mval_f);
if (len < 35) {
@@ -203,7 +207,7 @@ static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int
}
}
- BMesh *bm = NULL;
+ BMesh *bm = nullptr;
gz_ele->base_index = -1;
gz_ele->vert_index = -1;
@@ -227,13 +231,13 @@ static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int
}
if (best.ele) {
- const float(*coords)[3] = NULL;
+ const float(*coords)[3] = nullptr;
{
Object *ob = gz_ele->bases[gz_ele->base_index]->object;
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, ob->data);
- if (me_eval->runtime.edit_data) {
- coords = me_eval->runtime.edit_data->vertexCos;
+ Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, static_cast<ID *>(ob->data));
+ if (me_eval->runtime->edit_data) {
+ coords = me_eval->runtime->edit_data->vertexCos;
}
}
EDBM_preselect_elem_update_from_single(gz_ele->psel, bm, best.ele, coords);
@@ -261,7 +265,7 @@ static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int
static void gizmo_preselect_elem_setup(wmGizmo *gz)
{
MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
- if (gz_ele->psel == NULL) {
+ if (gz_ele->psel == nullptr) {
gz_ele->psel = EDBM_preselect_elem_create();
}
gz_ele->base_index = -1;
@@ -271,13 +275,13 @@ static void gizmo_preselect_elem_free(wmGizmo *gz)
{
MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
EDBM_preselect_elem_destroy(gz_ele->psel);
- gz_ele->psel = NULL;
+ gz_ele->psel = nullptr;
MEM_SAFE_FREE(gz_ele->bases);
}
-static int gizmo_preselect_elem_invoke(bContext *UNUSED(C),
- wmGizmo *UNUSED(gz),
- const wmEvent *UNUSED(event))
+static int gizmo_preselect_elem_invoke(bContext * /*C*/,
+ wmGizmo * /*gz*/,
+ const wmEvent * /*event*/)
{
return OPERATOR_PASS_THROUGH;
}
@@ -308,14 +312,14 @@ static void GIZMO_GT_mesh_preselect_elem_3d(wmGizmoType *gzt)
/** \name Mesh Edge-Ring Pre-Select Gizmo API
* \{ */
-typedef struct MeshEdgeRingGizmo3D {
+struct MeshEdgeRingGizmo3D {
wmGizmo gizmo;
Base **bases;
uint bases_len;
int base_index;
int edge_index;
- struct EditMesh_PreSelEdgeRing *psel;
-} MeshEdgeRingGizmo3D;
+ EditMesh_PreSelEdgeRing *psel;
+};
static void gizmo_preselect_edgering_draw(const bContext *C, wmGizmo *gz)
{
@@ -326,37 +330,38 @@ static void gizmo_preselect_edgering_draw(const bContext *C, wmGizmo *gz)
MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
if (gz_ring->base_index != -1) {
Object *ob = gz_ring->bases[gz_ring->base_index]->object;
- EDBM_preselect_edgering_draw(gz_ring->psel, ob->obmat);
+ EDBM_preselect_edgering_draw(gz_ring->psel, ob->object_to_world);
}
}
static int gizmo_preselect_edgering_test_select(bContext *C, wmGizmo *gz, const int mval[2])
{
MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
- struct {
+ struct Best {
Object *ob;
BMEdge *eed;
float dist;
int base_index;
- } best = {
- .dist = ED_view3d_select_dist_px(),
- };
+ } best{};
+ best.dist = ED_view3d_select_dist_px();
- struct {
+ struct Prev {
int base_index;
int edge_index;
- } prev = {
- .base_index = gz_ring->base_index,
- .edge_index = gz_ring->edge_index,
- };
+ } prev{};
+ prev.base_index = gz_ring->base_index;
+ prev.edge_index = gz_ring->edge_index;
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
- if (((gz_ring->bases)) == NULL || (gz_ring->bases[0] != view_layer->basact)) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ if ((gz_ring->bases) == nullptr ||
+ (gz_ring->bases[0] != BKE_view_layer_active_base_get(view_layer))) {
MEM_SAFE_FREE(gz_ring->bases);
gz_ring->bases = BKE_view_layer_array_from_bases_in_edit_mode(
- view_layer, v3d, &gz_ring->bases_len);
+ scene, view_layer, v3d, &gz_ring->bases_len);
}
}
@@ -365,8 +370,15 @@ static int gizmo_preselect_edgering_test_select(bContext *C, wmGizmo *gz, const
copy_v2_v2_int(vc.mval, mval);
uint base_index;
- BMEdge *eed_test = EDBM_edge_find_nearest_ex(
- &vc, &best.dist, NULL, false, false, NULL, gz_ring->bases, gz_ring->bases_len, &base_index);
+ BMEdge *eed_test = EDBM_edge_find_nearest_ex(&vc,
+ &best.dist,
+ nullptr,
+ false,
+ false,
+ nullptr,
+ gz_ring->bases,
+ gz_ring->bases_len,
+ &base_index);
if (eed_test) {
best.ob = gz_ring->bases[base_index]->object;
@@ -374,7 +386,7 @@ static int gizmo_preselect_edgering_test_select(bContext *C, wmGizmo *gz, const
best.base_index = base_index;
}
- BMesh *bm = NULL;
+ BMesh *bm = nullptr;
if (best.eed) {
gz_ring->base_index = best.base_index;
bm = BKE_editmesh_from_object(gz_ring->bases[gz_ring->base_index]->object)->bm;
@@ -399,7 +411,7 @@ static int gizmo_preselect_edgering_test_select(bContext *C, wmGizmo *gz, const
* the mesh hasn't been edited since last update. */
bool is_alloc = false;
const float(*coords)[3] = BKE_editmesh_vert_coords_when_deformed(
- vc.depsgraph, em_eval, scene_eval, ob_eval, NULL, &is_alloc);
+ vc.depsgraph, em_eval, scene_eval, ob_eval, nullptr, &is_alloc);
EDBM_preselect_edgering_update_from_edge(gz_ring->psel, bm, best.eed, 1, coords);
if (is_alloc) {
MEM_freeN((void *)coords);
@@ -423,7 +435,7 @@ static int gizmo_preselect_edgering_test_select(bContext *C, wmGizmo *gz, const
static void gizmo_preselect_edgering_setup(wmGizmo *gz)
{
MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
- if (gz_ring->psel == NULL) {
+ if (gz_ring->psel == nullptr) {
gz_ring->psel = EDBM_preselect_edgering_create();
}
gz_ring->base_index = -1;
@@ -433,13 +445,13 @@ static void gizmo_preselect_edgering_free(wmGizmo *gz)
{
MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
EDBM_preselect_edgering_destroy(gz_ring->psel);
- gz_ring->psel = NULL;
+ gz_ring->psel = nullptr;
MEM_SAFE_FREE(gz_ring->bases);
}
-static int gizmo_preselect_edgering_invoke(bContext *UNUSED(C),
- wmGizmo *UNUSED(gz),
- const wmEvent *UNUSED(event))
+static int gizmo_preselect_edgering_invoke(bContext * /*C*/,
+ wmGizmo * /*gz*/,
+ const wmEvent * /*event*/)
{
return OPERATOR_PASS_THROUGH;
}
@@ -488,17 +500,18 @@ void ED_view3d_gizmo_mesh_preselect_get_active(bContext *C,
Base **r_base,
BMElem **r_ele)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const int object_index = RNA_int_get(gz->ptr, "object_index");
/* weak, allocate an array just to access the index. */
- Base *base = NULL;
- Object *obedit = NULL;
+ Base *base = nullptr;
+ Object *obedit = nullptr;
{
uint bases_len;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(
- view_layer, CTX_wm_view3d(C), &bases_len);
+ scene, view_layer, CTX_wm_view3d(C), &bases_len);
if (object_index < bases_len) {
base = bases[object_index];
obedit = base->object;
@@ -507,7 +520,7 @@ void ED_view3d_gizmo_mesh_preselect_get_active(bContext *C,
}
*r_base = base;
- *r_ele = NULL;
+ *r_ele = nullptr;
if (obedit) {
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -555,7 +568,7 @@ void ED_view3d_gizmo_mesh_preselect_clear(wmGizmo *gz)
const char *prop_ids[] = {"object_index", "vert_index", "edge_index", "face_index"};
for (int i = 0; i < ARRAY_SIZE(prop_ids); i++) {
PropertyRNA *prop = RNA_struct_find_property(gz->ptr, prop_ids[i]);
- if (prop == NULL) {
+ if (prop == nullptr) {
continue;
}
RNA_property_int_set(gz->ptr, prop, -1);
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
index 41a0e137b03..8be170a3481 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
@@ -421,6 +421,7 @@ static bool view3d_ruler_item_mousemove(const bContext *C,
Scene *scene = DEG_get_input_scene(depsgraph);
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
RegionView3D *rv3d = ruler_info->region->regiondata;
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
Object *obedit = OBEDIT_FROM_OBACT(ob);
@@ -646,7 +647,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
GPU_line_width(1.0f);
BLF_enable(blf_mono_font, BLF_ROTATION);
- BLF_size(blf_mono_font, 14.0f * U.pixelsize, U.dpi);
+ BLF_size(blf_mono_font, 14.0f * U.dpi_fac);
BLF_rotation(blf_mono_font, 0.0f);
UI_GetThemeColor3ubv(TH_TEXT, color_text);
@@ -1039,7 +1040,7 @@ static int gizmo_ruler_modal(bContext *C,
const bool do_snap = !(tweak_flag & WM_GIZMO_TWEAK_SNAP);
#endif
const bool do_thickness = tweak_flag & WM_GIZMO_TWEAK_PRECISE;
- if ((ruler_info->drag_state_prev.do_thickness != do_thickness)) {
+ if (ruler_info->drag_state_prev.do_thickness != do_thickness) {
do_cursor_update = true;
}
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index 90d108c23cc..45f7a3a8fe9 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -125,7 +125,9 @@ void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
static void uiTemplatePaintModeSelection(uiLayout *layout, struct bContext *C)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
/* Gizmos aren't used in paint modes */
@@ -147,7 +149,9 @@ static void uiTemplatePaintModeSelection(uiLayout *layout, struct bContext *C)
void uiTemplateHeader3D_mode(uiLayout *layout, struct bContext *C)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
Object *obedit = CTX_data_edit_object(C);
bGPdata *gpd = CTX_data_gpencil_data(C);
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 4c9e2595023..08d42471998 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -206,7 +206,7 @@ void VIEW3D_OT_snap_cursor_to_active(struct wmOperatorType *ot);
void VIEW3D_OT_interactive_add(struct wmOperatorType *ot);
-/* space_view3d.c */
+/* space_view3d.cc */
extern const char *view3d_context_dir[]; /* doc access */
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.cc
index 60141fd00cd..aaa817ec00c 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.cc
@@ -57,9 +57,9 @@ static int content_planes_from_clip_flag(const ARegion *region,
{
BLI_assert(clip_flag & V3D_PROJ_TEST_CLIP_CONTENT);
- float *clip_xmin = NULL, *clip_xmax = NULL;
- float *clip_ymin = NULL, *clip_ymax = NULL;
- float *clip_zmin = NULL, *clip_zmax = NULL;
+ float *clip_xmin = nullptr, *clip_xmax = nullptr;
+ float *clip_ymin = nullptr, *clip_ymax = nullptr;
+ float *clip_zmin = nullptr, *clip_zmax = nullptr;
int planes_len = 0;
@@ -84,7 +84,7 @@ static int content_planes_from_clip_flag(const ARegion *region,
BLI_assert(planes_len <= 6);
if (planes_len != 0) {
- RegionView3D *rv3d = region->regiondata;
+ RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
float projmat[4][4];
ED_view3d_ob_project_mat_get(rv3d, ob, projmat);
planes_from_projmat(projmat, clip_xmin, clip_xmax, clip_ymin, clip_ymax, clip_zmin, clip_zmax);
@@ -202,24 +202,24 @@ static bool view3d_project_segment_to_screen_with_clip_tag(const ARegion *region
/** \name Private User Data Structures
* \{ */
-typedef struct foreachScreenObjectVert_userData {
+struct foreachScreenObjectVert_userData {
void (*func)(void *userData, MVert *mv, const float screen_co[2], int index);
void *userData;
ViewContext vc;
MVert *verts;
const bool *hide_vert;
eV3DProjTest clip_flag;
-} foreachScreenObjectVert_userData;
+};
-typedef struct foreachScreenVert_userData {
+struct foreachScreenVert_userData {
void (*func)(void *userData, BMVert *eve, const float screen_co[2], int index);
void *userData;
ViewContext vc;
eV3DProjTest clip_flag;
-} foreachScreenVert_userData;
+};
/* user data structures for derived mesh callbacks */
-typedef struct foreachScreenEdge_userData {
+struct foreachScreenEdge_userData {
void (*func)(void *userData,
BMEdge *eed,
const float screen_co_a[2],
@@ -237,17 +237,17 @@ typedef struct foreachScreenEdge_userData {
*/
float content_planes[6][4];
int content_planes_len;
-} foreachScreenEdge_userData;
+};
-typedef struct foreachScreenFace_userData {
+struct foreachScreenFace_userData {
void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index);
void *userData;
ViewContext vc;
eV3DProjTest clip_flag;
-} foreachScreenFace_userData;
+};
/**
- * \note foreach funcs should be called while drawing or directly after
+ * \note foreach functions should be called while drawing or directly after
* if not, #ED_view3d_init_mats_rv3d() can be used for selection tools
* but would not give correct results with dupli's for eg. which don't
* use the object matrix in the usual way.
@@ -262,9 +262,10 @@ typedef struct foreachScreenFace_userData {
static void meshobject_foreachScreenVert__mapFunc(void *userData,
int index,
const float co[3],
- const float UNUSED(no[3]))
+ const float /*no*/[3])
{
- foreachScreenObjectVert_userData *data = userData;
+ foreachScreenObjectVert_userData *data = static_cast<foreachScreenObjectVert_userData *>(
+ userData);
if (data->hide_vert && data->hide_vert[index]) {
return;
}
@@ -306,7 +307,7 @@ void meshobject_foreachScreenVert(
&me->vdata, CD_PROP_BOOL, ".hide_vert");
if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
- ED_view3d_clipping_local(vc->rv3d, vc->obact->obmat);
+ ED_view3d_clipping_local(vc->rv3d, vc->obact->object_to_world);
}
BKE_mesh_foreach_mapped_vert(me, meshobject_foreachScreenVert__mapFunc, &data, MESH_FOREACH_NOP);
@@ -315,9 +316,9 @@ void meshobject_foreachScreenVert(
static void mesh_foreachScreenVert__mapFunc(void *userData,
int index,
const float co[3],
- const float UNUSED(no[3]))
+ const float /*no*/[3])
{
- foreachScreenVert_userData *data = userData;
+ foreachScreenVert_userData *data = static_cast<foreachScreenVert_userData *>(userData);
BMVert *eve = BM_vert_at_index(data->vc.em->bm, index);
if (UNLIKELY(BM_elem_flag_test(eve, BM_ELEM_HIDDEN))) {
return;
@@ -352,7 +353,8 @@ void mesh_foreachScreenVert(
data.clip_flag = clip_flag;
if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
- ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
+ ED_view3d_clipping_local(vc->rv3d,
+ vc->obedit->object_to_world); /* for local clipping lookups */
}
BM_mesh_elem_table_ensure(vc->em->bm, BM_VERT);
@@ -370,7 +372,7 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData,
const float v_a[3],
const float v_b[3])
{
- foreachScreenEdge_userData *data = userData;
+ foreachScreenEdge_userData *data = static_cast<foreachScreenEdge_userData *>(userData);
BMEdge *eed = BM_edge_at_index(data->vc.em->bm, index);
if (UNLIKELY(BM_elem_flag_test(eed, BM_ELEM_HIDDEN))) {
return;
@@ -421,7 +423,8 @@ void mesh_foreachScreenEdge(ViewContext *vc,
data.clip_flag = clip_flag;
if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
- ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
+ ED_view3d_clipping_local(vc->rv3d,
+ vc->obedit->object_to_world); /* for local clipping lookups */
}
if (clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) {
@@ -451,7 +454,7 @@ static void mesh_foreachScreenEdge_clip_bb_segment__mapFunc(void *userData,
const float v_a[3],
const float v_b[3])
{
- foreachScreenEdge_userData *data = userData;
+ foreachScreenEdge_userData *data = static_cast<foreachScreenEdge_userData *>(userData);
BMEdge *eed = BM_edge_at_index(data->vc.em->bm, index);
if (UNLIKELY(BM_elem_flag_test(eed, BM_ELEM_HIDDEN))) {
return;
@@ -518,8 +521,9 @@ void mesh_foreachScreenEdge_clip_bb_segment(ViewContext *vc,
BM_mesh_elem_table_ensure(vc->em->bm, BM_EDGE);
- if ((clip_flag & V3D_PROJ_TEST_CLIP_BB) && (vc->rv3d->clipbb != NULL)) {
- ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups. */
+ if ((clip_flag & V3D_PROJ_TEST_CLIP_BB) && (vc->rv3d->clipbb != nullptr)) {
+ ED_view3d_clipping_local(vc->rv3d,
+ vc->obedit->object_to_world); /* for local clipping lookups. */
BKE_mesh_foreach_mapped_edge(
me, vc->em->bm->totedge, mesh_foreachScreenEdge_clip_bb_segment__mapFunc, &data);
}
@@ -537,9 +541,9 @@ void mesh_foreachScreenEdge_clip_bb_segment(ViewContext *vc,
static void mesh_foreachScreenFace__mapFunc(void *userData,
int index,
const float cent[3],
- const float UNUSED(no[3]))
+ const float /*no*/[3])
{
- foreachScreenFace_userData *data = userData;
+ foreachScreenFace_userData *data = static_cast<foreachScreenFace_userData *>(userData);
BMFace *efa = BM_face_at_index(data->vc.em->bm, index);
if (UNLIKELY(BM_elem_flag_test(efa, BM_ELEM_HIDDEN))) {
return;
@@ -575,7 +579,7 @@ void mesh_foreachScreenFace(
BM_mesh_elem_table_ensure(vc->em->bm, BM_FACE);
- if (me->runtime.subsurf_face_dot_tags != NULL) {
+ if (me->runtime->subsurf_face_dot_tags != nullptr) {
BKE_mesh_foreach_mapped_subdiv_face_center(
me, mesh_foreachScreenFace__mapFunc, &data, MESH_FOREACH_NOP);
}
@@ -602,8 +606,7 @@ void nurbs_foreachScreenVert(ViewContext *vc,
void *userData,
const eV3DProjTest clip_flag)
{
- Curve *cu = vc->obedit->data;
- Nurb *nu;
+ Curve *cu = static_cast<Curve *>(vc->obedit->data);
int i;
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
/* If no point in the triple is selected, the handles are invisible. */
@@ -612,10 +615,11 @@ void nurbs_foreachScreenVert(ViewContext *vc,
ED_view3d_check_mats_rv3d(vc->rv3d);
if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
- ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
+ ED_view3d_clipping_local(vc->rv3d,
+ vc->obedit->object_to_world); /* for local clipping lookups */
}
- for (nu = nurbs->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, nurbs) {
if (nu->type == CU_BEZIER) {
for (i = 0; i < nu->pntsu; i++) {
BezTriple *bezt = &nu->bezt[i];
@@ -626,35 +630,39 @@ void nurbs_foreachScreenVert(ViewContext *vc,
float screen_co[2];
if (!handles_visible) {
- if (ED_view3d_project_float_object(vc->region,
- bezt->vec[1],
- screen_co,
- V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) ==
+ if (ED_view3d_project_float_object(
+ vc->region,
+ bezt->vec[1],
+ screen_co,
+ eV3DProjTest(V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN)) ==
V3D_PROJ_RET_OK) {
- func(userData, nu, NULL, bezt, 1, false, screen_co);
+ func(userData, nu, nullptr, bezt, 1, false, screen_co);
}
}
else {
- if (ED_view3d_project_float_object(vc->region,
- bezt->vec[0],
- screen_co,
- V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) ==
+ if (ED_view3d_project_float_object(
+ vc->region,
+ bezt->vec[0],
+ screen_co,
+ eV3DProjTest(V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN)) ==
V3D_PROJ_RET_OK) {
- func(userData, nu, NULL, bezt, 0, true, screen_co);
+ func(userData, nu, nullptr, bezt, 0, true, screen_co);
}
- if (ED_view3d_project_float_object(vc->region,
- bezt->vec[1],
- screen_co,
- V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) ==
+ if (ED_view3d_project_float_object(
+ vc->region,
+ bezt->vec[1],
+ screen_co,
+ eV3DProjTest(V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN)) ==
V3D_PROJ_RET_OK) {
- func(userData, nu, NULL, bezt, 1, true, screen_co);
+ func(userData, nu, nullptr, bezt, 1, true, screen_co);
}
- if (ED_view3d_project_float_object(vc->region,
- bezt->vec[2],
- screen_co,
- V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) ==
+ if (ED_view3d_project_float_object(
+ vc->region,
+ bezt->vec[2],
+ screen_co,
+ eV3DProjTest(V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN)) ==
V3D_PROJ_RET_OK) {
- func(userData, nu, NULL, bezt, 2, true, screen_co);
+ func(userData, nu, nullptr, bezt, 2, true, screen_co);
}
}
}
@@ -667,9 +675,11 @@ void nurbs_foreachScreenVert(ViewContext *vc,
if (bp->hide == 0) {
float screen_co[2];
if (ED_view3d_project_float_object(
- vc->region, bp->vec, screen_co, V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) ==
- V3D_PROJ_RET_OK) {
- func(userData, nu, bp, NULL, -1, false, screen_co);
+ vc->region,
+ bp->vec,
+ screen_co,
+ eV3DProjTest(V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN)) == V3D_PROJ_RET_OK) {
+ func(userData, nu, bp, nullptr, -1, false, screen_co);
}
}
}
@@ -683,19 +693,18 @@ void nurbs_foreachScreenVert(ViewContext *vc,
/** \name Edit-Meta: For Each Screen Meta-Element
* \{ */
-void mball_foreachScreenElem(struct ViewContext *vc,
+void mball_foreachScreenElem(ViewContext *vc,
void (*func)(void *userData,
- struct MetaElem *ml,
+ MetaElem *ml,
const float screen_co_b[2]),
void *userData,
const eV3DProjTest clip_flag)
{
MetaBall *mb = (MetaBall *)vc->obedit->data;
- MetaElem *ml;
ED_view3d_check_mats_rv3d(vc->rv3d);
- for (ml = mb->editelems->first; ml; ml = ml->next) {
+ LISTBASE_FOREACH (MetaElem *, ml, mb->editelems) {
float screen_co[2];
if (ED_view3d_project_float_object(vc->region, &ml->x, screen_co, clip_flag) ==
V3D_PROJ_RET_OK) {
@@ -716,18 +725,18 @@ void lattice_foreachScreenVert(ViewContext *vc,
const eV3DProjTest clip_flag)
{
Object *obedit = vc->obedit;
- Lattice *lt = obedit->data;
+ Lattice *lt = static_cast<Lattice *>(obedit->data);
BPoint *bp = lt->editlatt->latt->def;
DispList *dl = obedit->runtime.curve_cache ?
BKE_displist_find(&obedit->runtime.curve_cache->disp, DL_VERTS) :
- NULL;
- const float *co = dl ? dl->verts : NULL;
+ nullptr;
+ const float *co = dl ? dl->verts : nullptr;
int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
ED_view3d_check_mats_rv3d(vc->rv3d);
if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
- ED_view3d_clipping_local(vc->rv3d, obedit->obmat); /* for local clipping lookups */
+ ED_view3d_clipping_local(vc->rv3d, obedit->object_to_world); /* for local clipping lookups */
}
for (i = 0; i < N; i++, bp++, co += 3) {
@@ -747,16 +756,15 @@ void lattice_foreachScreenVert(ViewContext *vc,
/** \name Edit-Armature: For Each Screen Bone
* \{ */
-void armature_foreachScreenBone(struct ViewContext *vc,
+void armature_foreachScreenBone(ViewContext *vc,
void (*func)(void *userData,
- struct EditBone *ebone,
+ EditBone *ebone,
const float screen_co_a[2],
const float screen_co_b[2]),
void *userData,
const eV3DProjTest clip_flag)
{
- bArmature *arm = vc->obedit->data;
- EditBone *ebone;
+ bArmature *arm = static_cast<bArmature *>(vc->obedit->data);
ED_view3d_check_mats_rv3d(vc->rv3d);
@@ -776,7 +784,7 @@ void armature_foreachScreenBone(struct ViewContext *vc,
content_planes_len = 0;
}
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ LISTBASE_FOREACH (EditBone *, ebone, arm->edbo) {
if (!EBONE_VISIBLE(arm, ebone)) {
continue;
}
@@ -814,9 +822,9 @@ void armature_foreachScreenBone(struct ViewContext *vc,
/** \name Pose: For Each Screen Bone
* \{ */
-void pose_foreachScreenBone(struct ViewContext *vc,
+void pose_foreachScreenBone(ViewContext *vc,
void (*func)(void *userData,
- struct bPoseChannel *pchan,
+ bPoseChannel *pchan,
const float screen_co_a[2],
const float screen_co_b[2]),
void *userData,
@@ -825,9 +833,8 @@ void pose_foreachScreenBone(struct ViewContext *vc,
/* Almost _exact_ copy of #armature_foreachScreenBone */
const Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact);
- const bArmature *arm_eval = ob_eval->data;
+ const bArmature *arm_eval = static_cast<const bArmature *>(ob_eval->data);
bPose *pose = vc->obact->pose;
- bPoseChannel *pchan;
ED_view3d_check_mats_rv3d(vc->rv3d);
@@ -847,7 +854,7 @@ void pose_foreachScreenBone(struct ViewContext *vc,
content_planes_len = 0;
}
- for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
if (!PBONE_VISIBLE(arm_eval, pchan->bone)) {
continue;
}
diff --git a/source/blender/editors/space_view3d/view3d_navigate.c b/source/blender/editors/space_view3d/view3d_navigate.c
index 684b3539943..7d2beecd9a3 100644
--- a/source/blender/editors/space_view3d/view3d_navigate.c
+++ b/source/blender/editors/space_view3d/view3d_navigate.c
@@ -164,8 +164,10 @@ bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Scene *scene = CTX_data_scene(C);
+ Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
View3D *v3d = CTX_wm_view3d(C);
+ BKE_view_layer_synced_ensure(scene_eval, view_layer_eval);
Object *ob_act_eval = BKE_view_layer_active_object_get(view_layer_eval);
Object *ob_act = DEG_get_original_object(ob_act_eval);
@@ -183,7 +185,7 @@ bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
copy_v3_v3(lastofs, stroke);
}
else {
- copy_v3_v3(lastofs, ob_act_eval->obmat[3]);
+ copy_v3_v3(lastofs, ob_act_eval->object_to_world[3]);
}
is_set = true;
}
@@ -197,7 +199,7 @@ bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
}
mul_v2_fl(lastofs, 1.0f / 4.0f);
- mul_m4_v3(ob_act_eval->obmat, lastofs);
+ mul_m4_v3(ob_act_eval->object_to_world, lastofs);
is_set = true;
}
@@ -207,7 +209,7 @@ bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
float select_center[3];
zero_v3(select_center);
- LISTBASE_FOREACH (Base *, base_eval, &view_layer_eval->object_bases) {
+ LISTBASE_FOREACH (Base *, base_eval, BKE_view_layer_object_bases_get(view_layer_eval)) {
if (BASE_SELECTED(v3d, base_eval)) {
/* use the boundbox if we can */
Object *ob_eval = base_eval->object;
@@ -217,11 +219,11 @@ bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
BKE_boundbox_calc_center_aabb(ob_eval->runtime.bb, cent);
- mul_m4_v3(ob_eval->obmat, cent);
+ mul_m4_v3(ob_eval->object_to_world, cent);
add_v3_v3(select_center, cent);
}
else {
- add_v3_v3(select_center, ob_eval->obmat[3]);
+ add_v3_v3(select_center, ob_eval->object_to_world[3]);
}
tot++;
}
@@ -624,7 +626,7 @@ static void view3d_object_calc_minmax(Depsgraph *depsgraph,
if (BKE_object_minmax_dupli(depsgraph, scene, ob_eval, min, max, false) == 0) {
/* Use if duplis aren't found. */
if (only_center) {
- minmax_v3v3_v3(min, max, ob_eval->obmat[3]);
+ minmax_v3v3_v3(min, max, ob_eval->object_to_world[3]);
}
else {
BKE_object_minmax(ob_eval, min, max, false);
@@ -751,8 +753,9 @@ static int view3d_all_exec(bContext *C, wmOperator *op)
RegionView3D *rv3d = CTX_wm_region_view3d(C);
Scene *scene = CTX_data_scene(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
- Base *base_eval;
+
const bool use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions");
const bool skip_camera = (ED_view3d_camera_lock_check(v3d, region->regiondata) ||
/* any one of the regions may be locked */
@@ -777,7 +780,8 @@ static int view3d_all_exec(bContext *C, wmOperator *op)
INIT_MINMAX(min, max);
}
- for (base_eval = view_layer_eval->object_bases.first; base_eval; base_eval = base_eval->next) {
+ BKE_view_layer_synced_ensure(scene_eval, view_layer_eval);
+ LISTBASE_FOREACH (Base *, base_eval, BKE_view_layer_object_bases_get(view_layer_eval)) {
if (BASE_VISIBLE(v3d, base_eval)) {
bool only_center = false;
Object *ob = DEG_get_original_object(base_eval->object);
@@ -861,7 +865,9 @@ static int viewselected_exec(bContext *C, wmOperator *op)
RegionView3D *rv3d = CTX_wm_region_view3d(C);
Scene *scene = CTX_data_scene(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ const Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
+ BKE_view_layer_synced_ensure(scene_eval, view_layer_eval);
Object *ob_eval = BKE_view_layer_active_object_get(view_layer_eval);
Object *obedit = CTX_data_edit_object(C);
const bGPdata *gpd_eval = ob_eval && (ob_eval->type == OB_GPENCIL) ? ob_eval->data : NULL;
@@ -886,7 +892,8 @@ static int viewselected_exec(bContext *C, wmOperator *op)
/* this is weak code this way, we should make a generic
* active/selection callback interface once... */
Base *base_eval;
- for (base_eval = view_layer_eval->object_bases.first; base_eval; base_eval = base_eval->next) {
+ for (base_eval = BKE_view_layer_object_bases_get(view_layer_eval)->first; base_eval;
+ base_eval = base_eval->next) {
if (BASE_SELECTED_EDITABLE(v3d, base_eval)) {
if (base_eval->object->type == OB_ARMATURE) {
if (base_eval->object->mode & OB_MODE_POSE) {
@@ -909,15 +916,15 @@ static int viewselected_exec(bContext *C, wmOperator *op)
if (gps->editcurve != NULL) {
for (int i = 0; i < gps->editcurve->tot_curve_points; i++) {
BezTriple *bezt = &gps->editcurve->curve_points[i].bezt;
- if ((bezt->f1 & SELECT)) {
+ if (bezt->f1 & SELECT) {
minmax_v3v3_v3(min, max, bezt->vec[0]);
ok = true;
}
- if ((bezt->f2 & SELECT)) {
+ if (bezt->f2 & SELECT) {
minmax_v3v3_v3(min, max, bezt->vec[1]);
ok = true;
}
- if ((bezt->f3 & SELECT)) {
+ if (bezt->f3 & SELECT) {
minmax_v3v3_v3(min, max, bezt->vec[2]);
ok = true;
}
@@ -927,8 +934,8 @@ static int viewselected_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
if ((ob_eval) && (ok)) {
- mul_m4_v3(ob_eval->obmat, min);
- mul_m4_v3(ob_eval->obmat, max);
+ mul_m4_v3(ob_eval->object_to_world, min);
+ mul_m4_v3(ob_eval->object_to_world, max);
}
}
else if (is_face_map) {
@@ -936,14 +943,15 @@ static int viewselected_exec(bContext *C, wmOperator *op)
}
else if (obedit) {
/* only selected */
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer_eval, v3d, obedit->type, obedit->mode, ob_eval_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (
+ scene_eval, view_layer_eval, v3d, obedit->type, obedit->mode, ob_eval_iter) {
ok |= ED_view3d_minmax_verts(ob_eval_iter, min, max);
}
FOREACH_OBJECT_IN_MODE_END;
}
else if (ob_eval && (ob_eval->mode & OB_MODE_POSE)) {
FOREACH_OBJECT_IN_MODE_BEGIN (
- view_layer_eval, v3d, ob_eval->type, ob_eval->mode, ob_eval_iter) {
+ scene_eval, view_layer_eval, v3d, ob_eval->type, ob_eval->mode, ob_eval_iter) {
ok |= BKE_pose_minmax(ob_eval_iter, min, max, true, true);
}
FOREACH_OBJECT_IN_MODE_END;
@@ -962,7 +970,7 @@ static int viewselected_exec(bContext *C, wmOperator *op)
ok_dist = 0; /* don't zoom */
}
else {
- LISTBASE_FOREACH (Base *, base_eval, &view_layer_eval->object_bases) {
+ LISTBASE_FOREACH (Base *, base_eval, BKE_view_layer_object_bases_get(view_layer_eval)) {
if (BASE_SELECTED(v3d, base_eval)) {
bool only_center = false;
Object *ob = DEG_get_original_object(base_eval->object);
@@ -1167,10 +1175,12 @@ static int view_axis_exec(bContext *C, wmOperator *op)
Object *obact = CTX_data_active_object(C);
if (obact != NULL) {
float twmat[3][3];
+ const Scene *scene = CTX_data_scene(C);
struct ViewLayer *view_layer = CTX_data_view_layer(C);
Object *obedit = CTX_data_edit_object(C);
/* same as transform gizmo when normal is set */
- ED_getTransformOrientationMatrix(view_layer, v3d, obact, obedit, V3D_AROUND_ACTIVE, twmat);
+ ED_getTransformOrientationMatrix(
+ scene, view_layer, v3d, obact, obedit, V3D_AROUND_ACTIVE, twmat);
align_quat = align_quat_buf;
mat3_to_quat(align_quat, twmat);
invert_qt_normalized(align_quat);
@@ -1304,6 +1314,7 @@ static int view_camera_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
if (rv3d->persp != RV3D_CAMOB) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (!rv3d->smooth_timer) {
@@ -1331,7 +1342,7 @@ static int view_camera_exec(bContext *C, wmOperator *op)
}
if (v3d->camera == NULL) {
- v3d->camera = BKE_view_layer_camera_find(view_layer);
+ v3d->camera = BKE_view_layer_camera_find(scene, view_layer);
}
/* couldn't find any useful camera, bail out */
diff --git a/source/blender/editors/space_view3d/view3d_navigate.h b/source/blender/editors/space_view3d/view3d_navigate.h
index 925acd90573..792357ae134 100644
--- a/source/blender/editors/space_view3d/view3d_navigate.h
+++ b/source/blender/editors/space_view3d/view3d_navigate.h
@@ -7,6 +7,10 @@
#pragma once
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
* Size of the sphere being dragged for trackball rotation within the view bounds.
* also affects speed (smaller is faster).
@@ -298,3 +302,7 @@ void VIEW3D_OT_zoom(struct wmOperatorType *ot);
/* view3d_navigate_zoom_border.c */
void VIEW3D_OT_zoom_border(struct wmOperatorType *ot);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/editors/space_view3d/view3d_navigate_dolly.c b/source/blender/editors/space_view3d/view3d_navigate_dolly.c
index 376e8ba190b..df0f4e6e94b 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_dolly.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_dolly.c
@@ -41,7 +41,7 @@ void viewdolly_modal_keymap(wmKeyConfig *keyconf)
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "View3D Dolly Modal");
- /* this function is called for each spacetype, only needs to add map once */
+ /* This function is called for each space-type, only needs to add map once. */
if (keymap && keymap->modal_items) {
return;
}
diff --git a/source/blender/editors/space_view3d/view3d_navigate_fly.c b/source/blender/editors/space_view3d/view3d_navigate_fly.c
index b607abe8226..3e83f8085c7 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_fly.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_fly.c
@@ -122,7 +122,7 @@ void fly_modal_keymap(wmKeyConfig *keyconf)
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "View3D Fly Modal");
- /* this function is called for each spacetype, only needs to add map once */
+ /* This function is called for each space-type, only needs to add map once. */
if (keymap && keymap->modal_items) {
return;
}
diff --git a/source/blender/editors/space_view3d/view3d_navigate_move.c b/source/blender/editors/space_view3d/view3d_navigate_move.c
index e236b702fb8..9de0a2ae4c2 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_move.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_move.c
@@ -35,7 +35,7 @@ void viewmove_modal_keymap(wmKeyConfig *keyconf)
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "View3D Move Modal");
- /* this function is called for each spacetype, only needs to add map once */
+ /* This function is called for each space-type, only needs to add map once. */
if (keymap && keymap->modal_items) {
return;
}
diff --git a/source/blender/editors/space_view3d/view3d_navigate_ndof.c b/source/blender/editors/space_view3d/view3d_navigate_ndof.c
index 88abf602c26..9fb33013c4e 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_ndof.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_ndof.c
@@ -32,7 +32,7 @@ static bool ndof_has_translate(const wmNDOFMotionData *ndof,
const View3D *v3d,
const RegionView3D *rv3d)
{
- return !is_zero_v3(ndof->tvec) && (!ED_view3d_offset_lock_check(v3d, rv3d));
+ return !is_zero_v3(ndof->tvec) && !ED_view3d_offset_lock_check(v3d, rv3d);
}
static bool ndof_has_rotate(const wmNDOFMotionData *ndof, const RegionView3D *rv3d)
@@ -363,19 +363,25 @@ static int view3d_ndof_cameraview_pan_zoom(bContext *C, const wmEvent *event)
ED_view3d_smooth_view_force_finish(C, v3d, region);
- if ((v3d->camera && (rv3d->persp == RV3D_CAMOB) && (v3d->flag2 & V3D_LOCK_CAMERA) == 0)) {
+ if (v3d->camera && (rv3d->persp == RV3D_CAMOB) && (v3d->flag2 & V3D_LOCK_CAMERA) == 0) {
/* pass */
}
else {
return OPERATOR_PASS_THROUGH;
}
+ const float pan_speed = NDOF_PIXELS_PER_SECOND;
const bool has_translate = !is_zero_v2(ndof->tvec);
const bool has_zoom = ndof->tvec[2] != 0.0f;
float pan_vec[3];
WM_event_ndof_pan_get(ndof, pan_vec, true);
+ mul_v3_fl(pan_vec, ndof->dt);
+ /* NOTE: unlike image and clip views, the 2D pan doesn't have to be scaled by the zoom level.
+ * #ED_view3d_camera_view_pan already takes the zoom level into account. */
+ mul_v2_fl(pan_vec, pan_speed);
+
/* NOTE(@campbellbarton): In principle rotating could pass through to regular
* non-camera NDOF behavior (exiting the camera-view and rotating).
* Disabled this block since in practice it's difficult to control NDOF devices
@@ -390,16 +396,14 @@ static int view3d_ndof_cameraview_pan_zoom(bContext *C, const wmEvent *event)
bool changed = false;
if (has_translate) {
- const float speed = ndof->dt * NDOF_PIXELS_PER_SECOND;
- float event_ofs[2] = {pan_vec[0] * speed, pan_vec[1] * speed};
- if (ED_view3d_camera_view_pan(region, event_ofs)) {
+ /* Use the X & Y of `pan_vec`. */
+ if (ED_view3d_camera_view_pan(region, pan_vec)) {
changed = true;
}
}
if (has_zoom) {
- const float scale = 1.0f + (ndof->dt * pan_vec[2]);
- if (ED_view3d_camera_view_zoom_scale(rv3d, scale)) {
+ if (ED_view3d_camera_view_zoom_scale(rv3d, max_ff(0.0f, 1.0f - pan_vec[2]))) {
changed = true;
}
}
diff --git a/source/blender/editors/space_view3d/view3d_navigate_rotate.c b/source/blender/editors/space_view3d/view3d_navigate_rotate.c
index 20385e15c48..10adf238001 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_rotate.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_rotate.c
@@ -37,7 +37,7 @@ void viewrotate_modal_keymap(wmKeyConfig *keyconf)
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "View3D Rotate Modal");
- /* this function is called for each spacetype, only needs to add map once */
+ /* This function is called for each space-type, only needs to add map once. */
if (keymap && keymap->modal_items) {
return;
}
diff --git a/source/blender/editors/space_view3d/view3d_navigate_smoothview.c b/source/blender/editors/space_view3d/view3d_navigate_smoothview.c
index 6b150d1e771..a5eee436fdb 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_smoothview.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_smoothview.c
@@ -259,7 +259,7 @@ void ED_view3d_smooth_view_ex(
Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, sview->camera);
if (sview->ofs != NULL) {
sms.dst.dist = ED_view3d_offset_distance(
- ob_camera_eval->obmat, sview->ofs, VIEW3D_DIST_FALLBACK);
+ ob_camera_eval->object_to_world, sview->ofs, VIEW3D_DIST_FALLBACK);
}
ED_view3d_from_object(ob_camera_eval, sms.dst.ofs, sms.dst.quat, &sms.dst.dist, &sms.dst.lens);
sms.to_camera = true; /* restore view3d values in end */
@@ -282,7 +282,8 @@ void ED_view3d_smooth_view_ex(
if (sview->camera_old) {
Object *ob_camera_old_eval = DEG_get_evaluated_object(depsgraph, sview->camera_old);
if (sview->ofs != NULL) {
- sms.src.dist = ED_view3d_offset_distance(ob_camera_old_eval->obmat, sview->ofs, 0.0f);
+ sms.src.dist = ED_view3d_offset_distance(
+ ob_camera_old_eval->object_to_world, sview->ofs, 0.0f);
}
ED_view3d_from_object(
ob_camera_old_eval, sms.src.ofs, sms.src.quat, &sms.src.dist, &sms.src.lens);
diff --git a/source/blender/editors/space_view3d/view3d_navigate_walk.c b/source/blender/editors/space_view3d/view3d_navigate_walk.c
index 7e537d0c141..fcb4f549353 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_walk.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_walk.c
@@ -170,7 +170,7 @@ void walk_modal_keymap(wmKeyConfig *keyconf)
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "View3D Walk Modal");
- /* this function is called for each spacetype, only needs to add map once */
+ /* This function is called for each space-type, only needs to add map once. */
if (keymap && keymap->modal_items) {
return;
}
@@ -849,11 +849,15 @@ static void walkEvent(WalkInfo *walk, const wmEvent *event)
if (ret) {
WalkTeleport *teleport = &walk->teleport;
+
+ /* Store the current navigation mode if we are not already teleporting. */
+ if (teleport->state == WALK_TELEPORT_STATE_OFF) {
+ teleport->navigation_mode = walk->navigation_mode;
+ }
teleport->state = WALK_TELEPORT_STATE_ON;
teleport->initial_time = PIL_check_seconds_timer();
teleport->duration = U.walk_navigation.teleport_time;
- teleport->navigation_mode = walk->navigation_mode;
walk_navigation_mode_set(walk, WALK_MODE_FREE);
copy_v3_v3(teleport->origin, walk->rv3d->viewinv[3]);
@@ -864,9 +868,7 @@ static void walkEvent(WalkInfo *walk, const wmEvent *event)
sub_v3_v3v3(teleport->direction, loc, teleport->origin);
}
- else {
- walk->teleport.state = WALK_TELEPORT_STATE_OFF;
- }
+
break;
}
@@ -1229,11 +1231,11 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
/* keep moving if we were moving */
copy_v2_v2(dvec, walk->teleport.direction);
- z_cur = walk->rv3d->viewinv[3][2];
- z_new = walk->teleport.origin[2] - getFreeFallDistance(walk->gravity, t) * walk->grid;
+ z_cur = walk->rv3d->viewinv[3][2] / walk->grid;
+ z_new = (walk->teleport.origin[2] / walk->grid) - getFreeFallDistance(walk->gravity, t);
/* jump */
- z_new += t * walk->speed_jump * walk->grid;
+ z_new += t * walk->speed_jump;
/* duration is the jump duration */
if (t > walk->teleport.duration) {
diff --git a/source/blender/editors/space_view3d/view3d_navigate_zoom.c b/source/blender/editors/space_view3d/view3d_navigate_zoom.c
index 9230aa09b1a..40df2b1a9c9 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_zoom.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_zoom.c
@@ -41,7 +41,7 @@ void viewzoom_modal_keymap(wmKeyConfig *keyconf)
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "View3D Zoom Modal");
- /* this function is called for each spacetype, only needs to add map once */
+ /* This function is called for each space-type, only needs to add map once. */
if (keymap && keymap->modal_items) {
return;
}
diff --git a/source/blender/editors/space_view3d/view3d_navigate_zoom_border.c b/source/blender/editors/space_view3d/view3d_navigate_zoom_border.c
index 7cafc3dfd42..fe83bbb7c59 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_zoom_border.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_zoom_border.c
@@ -96,8 +96,8 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
/* convert border to 3d coordinates */
- if ((!ED_view3d_unproject_v3(region, cent[0], cent[1], depth_close, p)) ||
- (!ED_view3d_unproject_v3(region, rect.xmin, rect.ymin, depth_close, p_corner))) {
+ if (!ED_view3d_unproject_v3(region, cent[0], cent[1], depth_close, p) ||
+ !ED_view3d_unproject_v3(region, rect.xmin, rect.ymin, depth_close, p_corner)) {
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index 6fbd553e17b..ad12aef6d67 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -59,7 +59,7 @@ static int view3d_copybuffer_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- BLI_join_dirfile(str, sizeof(str), BKE_tempdir_base(), "copybuffer.blend");
+ BLI_path_join(str, sizeof(str), BKE_tempdir_base(), "copybuffer.blend");
BKE_copybuffer_copy_end(bmain, str, op->reports);
BKE_reportf(op->reports, RPT_INFO, "Copied %d selected object(s)", num_copied);
@@ -91,7 +91,7 @@ static int view3d_pastebuffer_exec(bContext *C, wmOperator *op)
flag |= FILE_ACTIVE_COLLECTION;
}
- BLI_join_dirfile(str, sizeof(str), BKE_tempdir_base(), "copybuffer.blend");
+ BLI_path_join(str, sizeof(str), BKE_tempdir_base(), "copybuffer.blend");
const int num_pasted = BKE_copybuffer_paste(C, str, flag, op->reports, FILTER_ID_OB);
if (num_pasted == 0) {
diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c
index d3b82476d09..7588ad8d2c1 100644
--- a/source/blender/editors/space_view3d/view3d_placement.c
+++ b/source/blender/editors/space_view3d/view3d_placement.c
@@ -585,13 +585,13 @@ static void draw_primitive_view_impl(const struct bContext *C,
}
else if (ipd->primitive_type == PLACE_PRIMITIVE_TYPE_CYLINDER) {
draw_circle_in_quad(UNPACK4(bounds.vec), 32, color);
- draw_circle_in_quad(UNPACK4((&bounds.vec[4])), 32, color);
+ draw_circle_in_quad(UNPACK4(&bounds.vec[4]), 32, color);
}
else if (ipd->primitive_type == PLACE_PRIMITIVE_TYPE_CONE) {
draw_circle_in_quad(UNPACK4(bounds.vec), 32, color);
float center[3];
- mid_v3_v3v3v3v3(center, UNPACK4((&bounds.vec[4])));
+ mid_v3_v3v3v3v3(center, UNPACK4(&bounds.vec[4]));
float coords_a[4][3];
float coords_b[4][3];
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index 1230515a180..2718f14c855 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -75,14 +75,18 @@ void ED_view3d_project_float_v3_m4(const ARegion *region,
/* Clipping Projection Functions
* ***************************** */
-eV3DProjStatus ED_view3d_project_base(const struct ARegion *region, struct Base *base)
+eV3DProjStatus ED_view3d_project_base(const struct ARegion *region,
+ struct Base *base,
+ float r_co[2])
{
- eV3DProjStatus ret = ED_view3d_project_short_global(
- region, base->object->obmat[3], &base->sx, V3D_PROJ_TEST_CLIP_DEFAULT);
+ eV3DProjStatus ret = ED_view3d_project_float_global(
+ region, base->object->object_to_world[3], r_co, V3D_PROJ_TEST_CLIP_DEFAULT);
+ /* Prevent uninitialized values when projection fails,
+ * although the callers should check the return value. */
if (ret != V3D_PROJ_RET_OK) {
- base->sx = IS_CLIPPED;
- base->sy = 0;
+ r_co[0] = -1.0;
+ r_co[1] = -1.0;
}
return ret;
@@ -532,12 +536,27 @@ bool ED_view3d_win_to_3d_on_plane(const ARegion *region,
const bool do_clip,
float r_out[3])
{
+ const RegionView3D *rv3d = region->regiondata;
+ const bool ray_co_is_centered = rv3d->is_persp == false && rv3d->persp != RV3D_CAMOB;
+ const bool do_clip_ray_plane = do_clip && !ray_co_is_centered;
float ray_co[3], ray_no[3];
ED_view3d_win_to_origin(region, mval, ray_co);
ED_view3d_win_to_vector(region, mval, ray_no);
float lambda;
- if (isect_ray_plane_v3(ray_co, ray_no, plane, &lambda, do_clip)) {
+ if (isect_ray_plane_v3(ray_co, ray_no, plane, &lambda, do_clip_ray_plane)) {
madd_v3_v3v3fl(r_out, ray_co, ray_no, lambda);
+
+ /* Handle clipping with an orthographic view differently,
+ * check if the resulting point is behind the view instead of clipping the ray. */
+ if (do_clip && (do_clip_ray_plane == false)) {
+ /* The offset is unit length where over 1.0 is beyond the views clip-plane (near and far)
+ * as non-camera orthographic views only use far distance in both directions.
+ * Multiply `r_out` by `persmat` (with translation), and get it's Z value. */
+ const float z_offset = fabsf(dot_m4_v3_row_z(rv3d->persmat, r_out) + rv3d->persmat[3][2]);
+ if (z_offset > 1.0f) {
+ return false;
+ }
+ }
return true;
}
return false;
@@ -668,7 +687,7 @@ void ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, const Object *ob, fl
{
float vmat[4][4];
- mul_m4_m4m4(vmat, rv3d->viewmat, ob->obmat);
+ mul_m4_m4m4(vmat, rv3d->viewmat, ob->object_to_world);
mul_m4_m4m4(r_pmat, rv3d->winmat, vmat);
}
diff --git a/source/blender/editors/space_view3d/view3d_select.cc b/source/blender/editors/space_view3d/view3d_select.cc
index ad816f420fe..48a3cb386fd 100644
--- a/source/blender/editors/space_view3d/view3d_select.cc
+++ b/source/blender/editors/space_view3d/view3d_select.cc
@@ -28,6 +28,7 @@
#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
+#include "BLI_math_bits.h"
#include "BLI_rect.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -45,6 +46,7 @@
#include "BKE_action.h"
#include "BKE_armature.h"
+#include "BKE_attribute.hh"
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_editmesh.h"
@@ -140,10 +142,11 @@ void ED_view3d_viewcontext_init_object(ViewContext *vc, Object *obact)
/** \name Internal Object Utilities
* \{ */
-static bool object_deselect_all_visible(ViewLayer *view_layer, View3D *v3d)
+static bool object_deselect_all_visible(const Scene *scene, ViewLayer *view_layer, View3D *v3d)
{
bool changed = false;
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (base->flag & BASE_SELECTED) {
if (BASE_SELECTABLE(v3d, base)) {
ED_object_base_select(base, BA_DESELECT);
@@ -155,10 +158,11 @@ static bool object_deselect_all_visible(ViewLayer *view_layer, View3D *v3d)
}
/* deselect all except b */
-static bool object_deselect_all_except(ViewLayer *view_layer, Base *b)
+static bool object_deselect_all_except(const Scene *scene, ViewLayer *view_layer, Base *b)
{
bool changed = false;
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (base->flag & BASE_SELECTED) {
if (b != base) {
ED_object_base_select(base, BA_DESELECT);
@@ -191,7 +195,7 @@ static void editselect_buf_cache_init(ViewContext *vc, short select_mode)
if (vc->obedit) {
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(
- vc->view_layer, vc->v3d, &bases_len);
+ vc->scene, vc->view_layer, vc->v3d, &bases_len);
DRW_select_buffer_context_create(bases, bases_len, select_mode);
MEM_freeN(bases);
@@ -199,6 +203,7 @@ static void editselect_buf_cache_init(ViewContext *vc, short select_mode)
else {
/* Use for paint modes, currently only a single object at a time. */
if (vc->obact) {
+ BKE_view_layer_synced_ensure(vc->scene, vc->view_layer);
Base *base = BKE_view_layer_base_find(vc->view_layer, vc->obact);
DRW_select_buffer_context_create(&base, 1, select_mode);
}
@@ -334,28 +339,29 @@ static bool edbm_backbuf_check_and_select_verts_obmode(Mesh *me,
EditSelectBuf_Cache *esel,
const eSelectOp sel_op)
{
- MVert *verts = BKE_mesh_verts_for_write(me);
- MVert *mv = verts;
+ using namespace blender;
bool changed = false;
const BLI_bitmap *select_bitmap = esel->select_bitmap;
- if (mv) {
- const bool *hide_vert = (const bool *)CustomData_get_layer_named(
- &me->vdata, CD_PROP_BOOL, ".hide_vert");
+ bke::MutableAttributeAccessor attributes = me->attributes_for_write();
+ bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT);
+ const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
+ ".hide_vert", ATTR_DOMAIN_POINT, false);
- for (int index = 0; index < me->totvert; index++, mv++) {
- if (!(hide_vert && hide_vert[index])) {
- const bool is_select = mv->flag & SELECT;
- const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
- const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(mv->flag, sel_op_result, SELECT);
- changed = true;
- }
+ for (int index = 0; index < me->totvert; index++) {
+ if (!hide_vert[index]) {
+ const bool is_select = select_vert.span[index];
+ const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
+ const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ select_vert.span[index] = sel_op_result == 1;
+ changed = true;
}
}
}
+ select_vert.finish();
return changed;
}
@@ -364,27 +370,29 @@ static bool edbm_backbuf_check_and_select_faces_obmode(Mesh *me,
EditSelectBuf_Cache *esel,
const eSelectOp sel_op)
{
- MPoly *polys = BKE_mesh_polys_for_write(me);
+ using namespace blender;
bool changed = false;
const BLI_bitmap *select_bitmap = esel->select_bitmap;
- if (polys) {
- const bool *hide_poly = (const bool *)CustomData_get_layer_named(
- &me->vdata, CD_PROP_BOOL, ".hide_poly");
+ bke::MutableAttributeAccessor attributes = me->attributes_for_write();
+ bke::SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_poly", ATTR_DOMAIN_FACE);
+ const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE, false);
- for (int index = 0; index < me->totpoly; index++) {
- if (!(hide_poly && hide_poly[index])) {
- const bool is_select = polys[index].flag & ME_FACE_SEL;
- const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
- const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(polys[index].flag, sel_op_result, ME_FACE_SEL);
- changed = true;
- }
+ for (int index = 0; index < me->totpoly; index++) {
+ if (!hide_poly[index]) {
+ const bool is_select = select_poly.span[index];
+ const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
+ const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ select_poly.span[index] = sel_op_result == 1;
+ changed = true;
}
}
}
+ select_poly.finish();
return changed;
}
@@ -559,19 +567,24 @@ static bool do_lasso_select_objects(ViewContext *vc,
const eSelectOp sel_op)
{
View3D *v3d = vc->v3d;
- Base *base;
bool changed = false;
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- changed |= object_deselect_all_visible(vc->view_layer, vc->v3d);
+ changed |= object_deselect_all_visible(vc->scene, vc->view_layer, vc->v3d);
}
-
- for (base = static_cast<Base *>(vc->view_layer->object_bases.first); base; base = base->next) {
+ BKE_view_layer_synced_ensure(vc->scene, vc->view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(vc->view_layer)) {
if (BASE_SELECTABLE(v3d, base)) { /* Use this to avoid unnecessary lasso look-ups. */
+ float region_co[2];
const bool is_select = base->flag & BASE_SELECTED;
- const bool is_inside = ((ED_view3d_project_base(vc->region, base) == V3D_PROJ_RET_OK) &&
- BLI_lasso_is_point_inside(
- mcoords, mcoords_len, base->sx, base->sy, IS_CLIPPED));
+ const bool is_inside = (ED_view3d_project_base(vc->region, base, region_co) ==
+ V3D_PROJ_RET_OK) &&
+ BLI_lasso_is_point_inside(mcoords,
+ mcoords_len,
+ int(region_co[0]),
+ int(region_co[1]),
+ /* Dummy value. */
+ INT_MAX);
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
if (sel_op_result != -1) {
ED_object_base_select(base, sel_op_result ? BA_SELECT : BA_DESELECT);
@@ -594,7 +607,8 @@ static blender::Vector<Base *> do_pose_tag_select_op_prepare(ViewContext *vc)
{
blender::Vector<Base *> bases;
- FOREACH_BASE_IN_MODE_BEGIN (vc->view_layer, vc->v3d, OB_ARMATURE, OB_MODE_POSE, base_iter) {
+ FOREACH_BASE_IN_MODE_BEGIN (
+ vc->scene, vc->view_layer, vc->v3d, OB_ARMATURE, OB_MODE_POSE, base_iter) {
Object *ob_iter = base_iter->object;
bArmature *arm = static_cast<bArmature *>(ob_iter->data);
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob_iter->pose->chanbase) {
@@ -688,7 +702,7 @@ static bool do_lasso_select_pose(ViewContext *vc,
static void do_lasso_select_mesh__doSelectVert(void *userData,
BMVert *eve,
const float screen_co[2],
- int UNUSED(index))
+ int /*index*/)
{
LassoSelectUserData *data = static_cast<LassoSelectUserData *>(userData);
const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
@@ -767,7 +781,7 @@ static void do_lasso_select_mesh__doSelectEdge_pass1(void *user_data,
static void do_lasso_select_mesh__doSelectFace(void *userData,
BMFace *efa,
const float screen_co[2],
- int UNUSED(index))
+ int /*index*/)
{
LassoSelectUserData *data = static_cast<LassoSelectUserData *>(userData);
const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
@@ -875,7 +889,7 @@ static bool do_lasso_select_mesh(ViewContext *vc,
}
static void do_lasso_select_curve__doSelect(void *userData,
- Nurb *UNUSED(nu),
+ Nurb * /*nu*/,
BPoint *bp,
BezTriple *bezt,
int beztindex,
@@ -1151,20 +1165,27 @@ static bool do_lasso_select_meta(ViewContext *vc,
return data.is_changed;
}
+struct LassoSelectUserData_ForMeshVert {
+ LassoSelectUserData lasso_data;
+ blender::MutableSpan<bool> select_vert;
+};
static void do_lasso_select_meshobject__doSelectVert(void *userData,
- MVert *mv,
+ MVert * /*mv*/,
const float screen_co[2],
- int UNUSED(index))
+ int index)
{
- LassoSelectUserData *data = static_cast<LassoSelectUserData *>(userData);
- const bool is_select = mv->flag & SELECT;
+ using namespace blender;
+ LassoSelectUserData_ForMeshVert *mesh_data = static_cast<LassoSelectUserData_ForMeshVert *>(
+ userData);
+ LassoSelectUserData *data = &mesh_data->lasso_data;
+ const bool is_select = mesh_data->select_vert[index];
const bool is_inside =
(BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
BLI_lasso_is_point_inside(
data->mcoords, data->mcoords_len, screen_co[0], screen_co[1], IS_CLIPPED));
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(mv->flag, sel_op_result, SELECT);
+ mesh_data->select_vert[index] = sel_op_result == 1;
data->is_changed = true;
}
}
@@ -1174,6 +1195,7 @@ static bool do_lasso_select_paintvert(ViewContext *vc,
const int mcoords_len,
const eSelectOp sel_op)
{
+ using namespace blender;
const bool use_zbuf = !XRAY_ENABLED(vc->v3d);
Object *ob = vc->obact;
Mesh *me = static_cast<Mesh *>(ob->data);
@@ -1207,16 +1229,22 @@ static bool do_lasso_select_paintvert(ViewContext *vc,
}
}
else {
- LassoSelectUserData data;
+ bke::MutableAttributeAccessor attributes = me->attributes_for_write();
+ bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT);
+
+ LassoSelectUserData_ForMeshVert data;
+ data.select_vert = select_vert.span;
- view3d_userdata_lassoselect_init(&data, vc, &rect, mcoords, mcoords_len, sel_op);
+ view3d_userdata_lassoselect_init(&data.lasso_data, vc, &rect, mcoords, mcoords_len, sel_op);
ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d);
meshobject_foreachScreenVert(
vc, do_lasso_select_meshobject__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- changed |= data.is_changed;
+ changed |= data.lasso_data.is_changed;
+ select_vert.finish();
}
if (changed) {
@@ -1309,7 +1337,8 @@ static bool view3d_lasso_select(bContext *C,
}
}
else { /* Edit Mode */
- FOREACH_OBJECT_IN_MODE_BEGIN (vc->view_layer, vc->v3d, ob->type, ob->mode, ob_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (
+ vc->scene, vc->view_layer, vc->v3d, ob->type, ob->mode, ob_iter) {
ED_view3d_viewcontext_init_object(vc, ob_iter);
bool changed = false;
@@ -1420,8 +1449,8 @@ static SelMenuItemF object_mouse_select_menu_data[SEL_MENU_SIZE];
/* special (crappy) operator only for menu select */
static const EnumPropertyItem *object_select_menu_enum_itemf(bContext *C,
- PointerRNA *UNUSED(ptr),
- PropertyRNA *UNUSED(prop),
+ PointerRNA * /*ptr*/,
+ PropertyRNA * /*prop*/,
bool *r_free)
{
EnumPropertyItem *item = nullptr, item_tmp = {0};
@@ -1457,8 +1486,10 @@ static int object_select_menu_exec(bContext *C, wmOperator *op)
const char *name = object_mouse_select_menu_data[name_index].idname;
View3D *v3d = CTX_wm_view3d(C);
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- const Base *oldbasact = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ const Base *oldbasact = BKE_view_layer_active_base_get(view_layer);
Base *basact = nullptr;
CTX_DATA_BEGIN (C, Base *, base, selectable_bases) {
@@ -1498,12 +1529,12 @@ static int object_select_menu_exec(bContext *C, wmOperator *op)
}
}
else {
- object_deselect_all_except(view_layer, basact);
+ object_deselect_all_except(scene, view_layer, basact);
ED_object_base_select(basact, BA_SELECT);
changed = true;
}
- if ((oldbasact != basact)) {
+ if (oldbasact != basact) {
ED_object_base_activate(C, basact);
}
@@ -1564,13 +1595,24 @@ static bool object_mouse_select_menu(bContext *C,
const SelectPick_Params *params,
Base **r_basact)
{
+
+ const float mval_fl[2] = {float(mval[0]), float(mval[1])};
+ /* Distance from object center to use for selection. */
+ const float dist_threshold_sq = square_f(15 * U.pixelsize);
int base_count = 0;
- bool ok;
- LinkNodePair linklist = {nullptr, nullptr};
+
+ struct BaseRefWithDepth {
+ struct BaseRefWithDepth *next, *prev;
+ Base *base;
+ /** The scale isn't defined, simply use for sorting. */
+ uint depth_id;
+ };
+ ListBase base_ref_list = {nullptr, nullptr}; /* List of #BaseRefWithDepth. */
/* handle base->object->select_id */
CTX_DATA_BEGIN (C, Base *, base, selectable_bases) {
- ok = false;
+ bool ok = false;
+ uint depth_id;
/* two selection methods, the CTRL select uses max dist of 15 */
if (buffer) {
@@ -1578,27 +1620,29 @@ static bool object_mouse_select_menu(bContext *C,
/* index was converted */
if (base->object->runtime.select_id == (buffer[a].id & ~0xFFFF0000)) {
ok = true;
+ depth_id = buffer[a].depth;
break;
}
}
}
else {
- const int dist = 15 * U.pixelsize;
- if (ED_view3d_project_base(vc->region, base) == V3D_PROJ_RET_OK) {
- const int delta_px[2] = {base->sx - mval[0], base->sy - mval[1]};
- if (len_manhattan_v2_int(delta_px) < dist) {
+ float region_co[2];
+ if (ED_view3d_project_base(vc->region, base, region_co) == V3D_PROJ_RET_OK) {
+ const float dist_test_sq = len_squared_v2v2(mval_fl, region_co);
+ if (dist_test_sq < dist_threshold_sq) {
ok = true;
+ /* Match GPU depth logic, as the float is always positive, it can be sorted as an int. */
+ depth_id = float_as_uint(dist_test_sq);
}
}
}
if (ok) {
base_count++;
- BLI_linklist_append(&linklist, base);
-
- if (base_count == SEL_MENU_SIZE) {
- break;
- }
+ BaseRefWithDepth *base_ref = MEM_new<BaseRefWithDepth>(__func__);
+ base_ref->base = base;
+ base_ref->depth_id = depth_id;
+ BLI_addtail(&base_ref_list, (void *)base_ref);
}
}
CTX_DATA_END;
@@ -1609,20 +1653,30 @@ static bool object_mouse_select_menu(bContext *C,
return false;
}
if (base_count == 1) {
- Base *base = (Base *)linklist.list->link;
- BLI_linklist_free(linklist.list, nullptr);
+ Base *base = ((BaseRefWithDepth *)base_ref_list.first)->base;
+ BLI_freelistN(&base_ref_list);
*r_basact = base;
return false;
}
+ /* Sort by depth or distance to cursor. */
+ BLI_listbase_sort(&base_ref_list, [](const void *a, const void *b) {
+ return int(static_cast<const BaseRefWithDepth *>(a)->depth_id >
+ static_cast<const BaseRefWithDepth *>(b)->depth_id);
+ });
+
+ while (base_count > SEL_MENU_SIZE) {
+ BLI_freelinkN(&base_ref_list, base_ref_list.last);
+ base_count -= 1;
+ }
+
/* UI, full in static array values that we later use in an enum function */
- LinkNode *node;
- int i;
memset(object_mouse_select_menu_data, 0, sizeof(object_mouse_select_menu_data));
- for (node = linklist.list, i = 0; node; node = node->next, i++) {
- Base *base = static_cast<Base *>(node->link);
+ int i;
+ LISTBASE_FOREACH_INDEX (BaseRefWithDepth *, base_ref, &base_ref_list, i) {
+ Base *base = base_ref->base;
Object *ob = base->object;
const char *name = ob->id.name + 2;
@@ -1640,7 +1694,7 @@ static bool object_mouse_select_menu(bContext *C,
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, nullptr);
WM_operator_properties_free(&ptr);
- BLI_linklist_free(linklist.list, nullptr);
+ BLI_freelistN(&base_ref_list);
return true;
}
@@ -1652,8 +1706,10 @@ static int bone_select_menu_exec(bContext *C, wmOperator *op)
params.sel_op = ED_select_op_from_operator(op->ptr);
View3D *v3d = CTX_wm_view3d(C);
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- const Base *oldbasact = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ const Base *oldbasact = BKE_view_layer_active_base_get(view_layer);
Base *basact = object_mouse_select_menu_data[name_index].base_ptr;
@@ -1669,7 +1725,8 @@ static int bone_select_menu_exec(bContext *C, wmOperator *op)
}
else {
bPoseChannel *pchan = (bPoseChannel *)object_mouse_select_menu_data[name_index].item_ptr;
- ED_armature_pose_select_pick_bone(view_layer, v3d, basact->object, pchan->bone, &params);
+ ED_armature_pose_select_pick_bone(
+ scene, view_layer, v3d, basact->object, pchan->bone, &params);
}
/* Weak but ensures we activate the menu again before using the enum. */
@@ -1693,7 +1750,7 @@ static int bone_select_menu_exec(bContext *C, wmOperator *op)
* Selection causes this to be considered the 'active' pose in weight-paint mode.
* Eventually this limitation may be removed.
* For now, de-select all other pose objects deforming this mesh. */
- ED_armature_pose_select_in_wpaint_mode(view_layer, basact);
+ ED_armature_pose_select_in_wpaint_mode(scene, view_layer, basact);
}
else {
if (oldbasact != basact) {
@@ -1703,7 +1760,6 @@ static int bone_select_menu_exec(bContext *C, wmOperator *op)
}
/* Undo? */
- Scene *scene = CTX_data_scene(C);
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
@@ -1755,8 +1811,20 @@ static bool bone_mouse_select_menu(bContext *C,
BLI_assert(buffer);
int bone_count = 0;
- LinkNodePair base_list = {nullptr, nullptr};
- LinkNodePair bone_list = {nullptr, nullptr};
+
+ struct BoneRefWithDepth {
+ struct BoneRefWithDepth *next, *prev;
+ Base *base;
+ union {
+ EditBone *ebone;
+ bPoseChannel *pchan;
+ void *bone_ptr;
+ };
+ /** The scale isn't defined, simply use for sorting. */
+ uint depth_id;
+ };
+ ListBase bone_ref_list = {nullptr, nullptr};
+
GSet *added_bones = BLI_gset_ptr_new("Bone mouse select menu");
/* Select logic taken from ed_armature_pick_bone_from_selectbuffer_impl in armature_select.c */
@@ -1788,18 +1856,16 @@ static bool bone_mouse_select_menu(bContext *C,
/* Determine what the current bone is */
if (is_editmode) {
- EditBone *ebone;
const uint hit_bone = (hitresult & ~BONESEL_ANY) >> 16;
bArmature *arm = static_cast<bArmature *>(bone_base->object->data);
- ebone = static_cast<EditBone *>(BLI_findlink(arm->edbo, hit_bone));
+ EditBone *ebone = static_cast<EditBone *>(BLI_findlink(arm->edbo, hit_bone));
if (ebone && !(ebone->flag & BONE_UNSELECTABLE)) {
bone_ptr = ebone;
}
}
else {
- bPoseChannel *pchan;
const uint hit_bone = (hitresult & ~BONESEL_ANY) >> 16;
- pchan = static_cast<bPoseChannel *>(
+ bPoseChannel *pchan = static_cast<bPoseChannel *>(
BLI_findlink(&bone_base->object->pose->chanbase, hit_bone));
if (pchan && !(pchan->bone->flag & BONE_UNSELECTABLE)) {
bone_ptr = pchan;
@@ -1815,13 +1881,13 @@ static bool bone_mouse_select_menu(bContext *C,
if (!is_duplicate_bone) {
bone_count++;
- BLI_linklist_append(&base_list, bone_base);
- BLI_linklist_append(&bone_list, bone_ptr);
- BLI_gset_insert(added_bones, bone_ptr);
+ BoneRefWithDepth *bone_ref = MEM_new<BoneRefWithDepth>(__func__);
+ bone_ref->base = bone_base;
+ bone_ref->bone_ptr = bone_ptr;
+ bone_ref->depth_id = buffer[a].depth;
+ BLI_addtail(&bone_ref_list, (void *)bone_ref);
- if (bone_count == SEL_MENU_SIZE) {
- break;
- }
+ BLI_gset_insert(added_bones, bone_ptr);
}
}
@@ -1831,31 +1897,38 @@ static bool bone_mouse_select_menu(bContext *C,
return false;
}
if (bone_count == 1) {
- BLI_linklist_free(base_list.list, nullptr);
- BLI_linklist_free(bone_list.list, nullptr);
+ BLI_freelistN(&bone_ref_list);
return false;
}
- /* UI, full in static array values that we later use in an enum function */
- LinkNode *bone_node, *base_node;
- int i;
+ /* Sort by depth or distance to cursor. */
+ BLI_listbase_sort(&bone_ref_list, [](const void *a, const void *b) {
+ return int(static_cast<const BoneRefWithDepth *>(a)->depth_id >
+ static_cast<const BoneRefWithDepth *>(b)->depth_id);
+ });
+
+ while (bone_count > SEL_MENU_SIZE) {
+ BLI_freelinkN(&bone_ref_list, bone_ref_list.last);
+ bone_count -= 1;
+ }
+ /* UI, full in static array values that we later use in an enum function */
memset(object_mouse_select_menu_data, 0, sizeof(object_mouse_select_menu_data));
- for (base_node = base_list.list, bone_node = bone_list.list, i = 0; bone_node;
- base_node = base_node->next, bone_node = bone_node->next, i++) {
+ int i;
+ LISTBASE_FOREACH_INDEX (BoneRefWithDepth *, bone_ref, &bone_ref_list, i) {
char *name;
- object_mouse_select_menu_data[i].base_ptr = static_cast<Base *>(base_node->link);
+ object_mouse_select_menu_data[i].base_ptr = bone_ref->base;
if (is_editmode) {
- EditBone *ebone = static_cast<EditBone *>(bone_node->link);
- object_mouse_select_menu_data[i].item_ptr = ebone;
+ EditBone *ebone = bone_ref->ebone;
+ object_mouse_select_menu_data[i].item_ptr = static_cast<void *>(ebone);
name = ebone->name;
}
else {
- bPoseChannel *pchan = static_cast<bPoseChannel *>(bone_node->link);
- object_mouse_select_menu_data[i].item_ptr = pchan;
+ bPoseChannel *pchan = bone_ref->pchan;
+ object_mouse_select_menu_data[i].item_ptr = static_cast<void *>(pchan);
name = pchan->name;
}
@@ -1873,8 +1946,7 @@ static bool bone_mouse_select_menu(bContext *C,
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, nullptr);
WM_operator_properties_free(&ptr);
- BLI_linklist_free(base_list.list, nullptr);
- BLI_linklist_free(bone_list.list, nullptr);
+ BLI_freelistN(&bone_ref_list);
return true;
}
@@ -1889,7 +1961,7 @@ static bool selectbuffer_has_bones(const GPUSelectResult *buffer, const uint hit
}
/* utility function for mixed_bones_object_selectbuffer */
-static int selectbuffer_ret_hits_15(GPUSelectResult *UNUSED(buffer), const int hits15)
+static int selectbuffer_ret_hits_15(GPUSelectResult * /*buffer*/, const int hits15)
{
return hits15;
}
@@ -2098,6 +2170,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc,
bool do_bones_get_priotity,
int *r_select_id_subelem)
{
+ Scene *scene = vc->scene;
ViewLayer *view_layer = vc->view_layer;
View3D *v3d = vc->v3d;
int a;
@@ -2161,8 +2234,10 @@ static Base *mouse_select_eval_buffer(ViewContext *vc,
/* It's possible there are no hits (all objects contained bones). */
if (hits > 0) {
/* Only exclude active object when it is selected. */
- if (view_layer->basact && (view_layer->basact->flag & BASE_SELECTED)) {
- const int select_id_active = view_layer->basact->object->runtime.select_id;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base = BKE_view_layer_active_base_get(view_layer);
+ if (base && (base->flag & BASE_SELECTED)) {
+ const int select_id_active = base->object->runtime.select_id;
for (int i_next = 0, i_prev = hits - 1; i_next < hits; i_prev = i_next++) {
if ((select_id_active == (buffer[i_prev].id & 0xFFFF)) &&
(select_id_active != (buffer[i_next].id & 0xFFFF))) {
@@ -2189,7 +2264,8 @@ static Base *mouse_select_eval_buffer(ViewContext *vc,
Base *basact = nullptr;
if (found) {
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (has_bones ? BASE_VISIBLE(v3d, base) : BASE_SELECTABLE(v3d, base)) {
if (base->object->runtime.select_id == select_id) {
basact = base;
@@ -2209,12 +2285,14 @@ static Base *mouse_select_eval_buffer(ViewContext *vc,
static Base *mouse_select_object_center(ViewContext *vc, Base *startbase, const int mval[2])
{
ARegion *region = vc->region;
+ Scene *scene = vc->scene;
ViewLayer *view_layer = vc->view_layer;
View3D *v3d = vc->v3d;
- Base *oldbasact = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *oldbasact = BKE_view_layer_active_base_get(view_layer);
- const float mval_fl[2] = {(float)mval[0], (float)mval[1]};
+ const float mval_fl[2] = {float(mval[0]), float(mval[1])};
float dist = ED_view3d_select_dist_px() * 1.3333f;
Base *basact = nullptr;
@@ -2225,7 +2303,7 @@ static Base *mouse_select_object_center(ViewContext *vc, Base *startbase, const
if (BASE_SELECTABLE(v3d, base)) {
float screen_co[2];
if (ED_view3d_project_float_global(
- region, base->object->obmat[3], screen_co, V3D_PROJ_TEST_CLIP_DEFAULT) ==
+ region, base->object->object_to_world[3], screen_co, V3D_PROJ_TEST_CLIP_DEFAULT) ==
V3D_PROJ_RET_OK) {
float dist_test = len_manhattan_v2v2(mval_fl, screen_co);
if (base == oldbasact) {
@@ -2240,7 +2318,7 @@ static Base *mouse_select_object_center(ViewContext *vc, Base *startbase, const
base = base->next;
if (base == nullptr) {
- base = static_cast<Base *>(view_layer->object_bases.first);
+ base = static_cast<Base *>(BKE_view_layer_object_bases_get(view_layer)->first);
}
if (base == startbase) {
break;
@@ -2526,17 +2604,24 @@ static bool ed_object_select_pick(bContext *C,
/* No menu, continue with selection. */
ViewLayer *view_layer = vc.view_layer;
+ BKE_view_layer_synced_ensure(scene, view_layer);
/* Don't set when the context has no active object (hidden), see: T60807. */
- const Base *oldbasact = vc.obact ? view_layer->basact : nullptr;
+ const Base *oldbasact = vc.obact ? BKE_view_layer_active_base_get(view_layer) : nullptr;
/* Always start list from `basact` when cycling the selection. */
Base *startbase = (oldbasact && oldbasact->next) ?
oldbasact->next :
- static_cast<Base *>(view_layer->object_bases.first);
+ static_cast<Base *>(BKE_view_layer_object_bases_get(view_layer)->first);
/* The next object's base to make active. */
Base *basact = nullptr;
const eObjectMode object_mode = oldbasact ? static_cast<eObjectMode>(oldbasact->object->mode) :
OB_MODE_OBJECT;
+ /* For the most part this is equivalent to `(object_mode & OB_MODE_POSE) != 0`
+ * however this logic should also run with weight-paint + pose selection.
+ * Without this, selection in weight-paint mode can de-select armatures which isn't useful,
+ * see: T101686. */
+ const bool has_pose_old = (oldbasact &&
+ BKE_object_pose_armature_get_with_wpaint_check(oldbasact->object));
/* When enabled, don't attempt any further selection. */
bool handled = false;
@@ -2575,7 +2660,7 @@ static bool ed_object_select_pick(bContext *C,
*
* This way prioritizing based on pose-mode has a bias to stay in pose-mode
* without having to enforce this through locking the object mode. */
- bool do_bones_get_priotity = (object_mode & OB_MODE_POSE) != 0;
+ bool do_bones_get_priotity = has_pose_old;
basact = (gpu->hits > 0) ? mouse_select_eval_buffer(&vc,
gpu->buffer,
@@ -2587,10 +2672,14 @@ static bool ed_object_select_pick(bContext *C,
nullptr;
}
+ /* See comment for `has_pose_old`, the same rationale applies here. */
+ const bool has_pose_new = (basact &&
+ BKE_object_pose_armature_get_with_wpaint_check(basact->object));
+
/* Select pose-bones or camera-tracks. */
if (((gpu->hits > 0) && gpu->has_bones) ||
/* Special case, even when there are no hits, pose logic may de-select all bones. */
- ((gpu->hits == 0) && (object_mode & OB_MODE_POSE))) {
+ ((gpu->hits == 0) && has_pose_old)) {
if (basact && (gpu->has_bones && (basact->object->type == OB_CAMERA))) {
MovieClip *clip = BKE_object_movieclip_get(scene, basact->object, false);
@@ -2611,7 +2700,8 @@ static bool ed_object_select_pick(bContext *C,
}
}
}
- else if (ED_armature_pose_select_pick_with_buffer(view_layer,
+ else if (ED_armature_pose_select_pick_with_buffer(scene,
+ view_layer,
v3d,
basact ? basact : (Base *)oldbasact,
gpu->buffer,
@@ -2624,7 +2714,10 @@ static bool ed_object_select_pick(bContext *C,
/* When there is no `baseact` this will have operated on `oldbasact`,
* allowing #SelectPick_Params.deselect_all work in pose-mode.
* In this case no object operations are needed. */
- if (basact != nullptr) {
+ if (basact == nullptr) {
+ handled = true;
+ }
+ else {
/* By convention the armature-object is selected when in pose-mode.
* While leaving it unselected will work, leaving pose-mode would leave the object
* active + unselected which isn't ideal when performing other actions on the object. */
@@ -2642,11 +2735,11 @@ static bool ed_object_select_pick(bContext *C,
* Selection causes this to be considered the 'active' pose in weight-paint mode.
* Eventually this limitation may be removed.
* For now, de-select all other pose objects deforming this mesh. */
- ED_armature_pose_select_in_wpaint_mode(view_layer, basact);
+ ED_armature_pose_select_in_wpaint_mode(scene, view_layer, basact);
handled = true;
}
- else if ((object_mode & OB_MODE_POSE) && (basact->object->mode & OB_MODE_POSE)) {
+ else if (has_pose_old && has_pose_new) {
/* Within pose-mode, keep the current selection when switching pose bones,
* this is noticeable when in pose mode with multiple objects at once.
* Where selecting the bone of a different object would de-select this one.
@@ -2701,7 +2794,7 @@ static bool ed_object_select_pick(bContext *C,
/* Ensure code above doesn't change the active base. This code is already fairly involved,
* it's best if changing the active object is localized to a single place. */
- BLI_assert(oldbasact == (vc.obact ? view_layer->basact : nullptr));
+ BLI_assert(oldbasact == (vc.obact ? BKE_view_layer_active_base_get(view_layer) : nullptr));
bool found = (basact != nullptr);
if ((handled == false) && (vc.obedit == nullptr)) {
@@ -2713,7 +2806,7 @@ static bool ed_object_select_pick(bContext *C,
else if (found || params->deselect_all) {
/* Deselect everything. */
/* `basact` may be nullptr. */
- if (object_deselect_all_except(view_layer, basact)) {
+ if (object_deselect_all_except(scene, view_layer, basact)) {
changed_object = true;
}
}
@@ -2725,7 +2818,7 @@ static bool ed_object_select_pick(bContext *C,
if (vc.obedit) {
/* Only do the select (use for setting vertex parents & hooks).
* In edit-mode do not activate. */
- object_deselect_all_except(view_layer, basact);
+ object_deselect_all_except(scene, view_layer, basact);
ED_object_base_select(basact, BA_SELECT);
changed_object = true;
@@ -2756,7 +2849,7 @@ static bool ed_object_select_pick(bContext *C,
break;
}
case SEL_OP_SET: {
- object_deselect_all_except(view_layer, basact);
+ object_deselect_all_except(scene, view_layer, basact);
ED_object_base_select(basact, BA_SELECT);
break;
}
@@ -2809,20 +2902,22 @@ static bool ed_wpaint_vertex_select_pick(bContext *C,
const SelectPick_Params *params,
Object *obact)
{
+ using namespace blender;
View3D *v3d = CTX_wm_view3d(C);
const bool use_zbuf = !XRAY_ENABLED(v3d);
Mesh *me = static_cast<Mesh *>(obact->data); /* already checked for nullptr */
uint index = 0;
- MVert *verts = BKE_mesh_verts_for_write(me);
-
- MVert *mv;
bool changed = false;
bool found = ED_mesh_pick_vert(C, obact, mval, ED_MESH_PICK_DEFAULT_VERT_DIST, use_zbuf, &index);
+ bke::MutableAttributeAccessor attributes = me->attributes_for_write();
+ bke::AttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT);
+
if (params->sel_op == SEL_OP_SET) {
- if ((found && params->select_passthrough) && (verts[index].flag & SELECT)) {
+ if ((found && params->select_passthrough) && select_vert.varray[index]) {
found = false;
}
else if (found || params->deselect_all) {
@@ -2832,23 +2927,22 @@ static bool ed_wpaint_vertex_select_pick(bContext *C,
}
if (found) {
- mv = &verts[index];
switch (params->sel_op) {
case SEL_OP_ADD: {
- mv->flag |= SELECT;
+ select_vert.varray.set(index, true);
break;
}
case SEL_OP_SUB: {
- mv->flag &= ~SELECT;
+ select_vert.varray.set(index, false);
break;
}
case SEL_OP_XOR: {
- mv->flag ^= SELECT;
+ select_vert.varray.set(index, !select_vert.varray[index]);
break;
}
case SEL_OP_SET: {
paintvert_deselect_all_visible(obact, SEL_DESELECT, false);
- mv->flag |= SELECT;
+ select_vert.varray.set(index, true);
break;
}
case SEL_OP_AND: {
@@ -2858,17 +2952,22 @@ static bool ed_wpaint_vertex_select_pick(bContext *C,
}
/* update mselect */
- if (mv->flag & SELECT) {
+ if (select_vert.varray[index]) {
BKE_mesh_mselect_active_set(me, index, ME_VSEL);
}
else {
BKE_mesh_mselect_validate(me);
}
+ select_vert.finish();
+
paintvert_flush_flags(obact);
changed = true;
}
+ else {
+ select_vert.finish();
+ }
if (changed) {
paintvert_tag_select_update(C, obact);
@@ -3101,17 +3200,23 @@ bool edge_inside_circle(const float cent[2],
return (dist_squared_to_line_segment_v2(cent, screen_co_a, screen_co_b) < radius_squared);
}
+struct BoxSelectUserData_ForMeshVert {
+ BoxSelectUserData box_data;
+ blender::MutableSpan<bool> select_vert;
+};
static void do_paintvert_box_select__doSelectVert(void *userData,
- MVert *mv,
+ MVert * /*mv*/,
const float screen_co[2],
- int UNUSED(index))
+ int index)
{
- BoxSelectUserData *data = static_cast<BoxSelectUserData *>(userData);
- const bool is_select = mv->flag & SELECT;
+ BoxSelectUserData_ForMeshVert *mesh_data = static_cast<BoxSelectUserData_ForMeshVert *>(
+ userData);
+ BoxSelectUserData *data = &mesh_data->box_data;
+ const bool is_select = mesh_data->select_vert[index];
const bool is_inside = BLI_rctf_isect_pt_v(data->rect_fl, screen_co);
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(mv->flag, sel_op_result, SELECT);
+ mesh_data->select_vert[index] = sel_op_result == 1;
data->is_changed = true;
}
}
@@ -3120,6 +3225,7 @@ static bool do_paintvert_box_select(ViewContext *vc,
const rcti *rect,
const eSelectOp sel_op)
{
+ using namespace blender;
const bool use_zbuf = !XRAY_ENABLED(vc->v3d);
Mesh *me = static_cast<Mesh *>(vc->obact->data);
@@ -3148,15 +3254,21 @@ static bool do_paintvert_box_select(ViewContext *vc,
}
}
else {
- BoxSelectUserData data;
+ bke::MutableAttributeAccessor attributes = me->attributes_for_write();
+ bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT);
- view3d_userdata_boxselect_init(&data, vc, rect, sel_op);
+ BoxSelectUserData_ForMeshVert data;
+ data.select_vert = select_vert.span;
+
+ view3d_userdata_boxselect_init(&data.box_data, vc, rect, sel_op);
ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d);
meshobject_foreachScreenVert(
vc, do_paintvert_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- changed |= data.is_changed;
+ changed |= data.box_data.is_changed;
+ select_vert.finish();
}
if (changed) {
@@ -3210,7 +3322,7 @@ static bool do_paintface_box_select(ViewContext *vc,
}
static void do_nurbs_box_select__doSelect(void *userData,
- Nurb *UNUSED(nu),
+ Nurb * /*nu*/,
BPoint *bp,
BezTriple *bezt,
int beztindex,
@@ -3310,7 +3422,7 @@ static bool do_lattice_box_select(ViewContext *vc, rcti *rect, const eSelectOp s
static void do_mesh_box_select__doSelectVert(void *userData,
BMVert *eve,
const float screen_co[2],
- int UNUSED(index))
+ int /*index*/)
{
BoxSelectUserData *data = static_cast<BoxSelectUserData *>(userData);
const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
@@ -3377,7 +3489,7 @@ static void do_mesh_box_select__doSelectEdge_pass1(
static void do_mesh_box_select__doSelectFace(void *userData,
BMFace *efa,
const float screen_co[2],
- int UNUSED(index))
+ int /*index*/)
{
BoxSelectUserData *data = static_cast<BoxSelectUserData *>(userData);
const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
@@ -3558,7 +3670,7 @@ static bool do_armature_box_select(ViewContext *vc, const rcti *rect, const eSel
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- vc->view_layer, vc->v3d, &bases_len);
+ vc->scene, vc->view_layer, vc->v3d, &bases_len);
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
changed |= ED_armature_edit_deselect_all_visible_multi_ex(bases, bases_len);
@@ -3637,8 +3749,8 @@ static bool do_object_box_select(bContext *C, ViewContext *vc, rcti *rect, const
vc->obact);
const int hits = view3d_opengl_select(
vc, buffer, (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL, select_filter);
-
- LISTBASE_FOREACH (Base *, base, &vc->view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(vc->scene, vc->view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(vc->view_layer)) {
base->object->id.tag &= ~LIB_TAG_DOIT;
}
@@ -3646,14 +3758,15 @@ static bool do_object_box_select(bContext *C, ViewContext *vc, rcti *rect, const
bool changed = false;
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- changed |= object_deselect_all_visible(vc->view_layer, vc->v3d);
+ changed |= object_deselect_all_visible(vc->scene, vc->view_layer, vc->v3d);
}
+ ListBase *object_bases = BKE_view_layer_object_bases_get(vc->view_layer);
if ((hits == -1) && !SEL_OP_USE_OUTSIDE(sel_op)) {
goto finally;
}
- LISTBASE_FOREACH (Base *, base, &vc->view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, object_bases) {
if (BASE_SELECTABLE(v3d, base)) {
if ((base->object->runtime.select_id & 0x0000FFFF) != 0) {
bases.append(base);
@@ -3674,8 +3787,7 @@ static bool do_object_box_select(bContext *C, ViewContext *vc, rcti *rect, const
}
}
- for (Base *base = static_cast<Base *>(vc->view_layer->object_bases.first); base && hits;
- base = base->next) {
+ for (Base *base = static_cast<Base *>(object_bases->first); base && hits; base = base->next) {
if (BASE_SELECTABLE(v3d, base)) {
const bool is_select = base->flag & BASE_SELECTED;
const bool is_inside = base->object->id.tag & LIB_TAG_DOIT;
@@ -3796,7 +3908,7 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op)
if (vc.obedit) {
FOREACH_OBJECT_IN_MODE_BEGIN (
- vc.view_layer, vc.v3d, vc.obedit->type, vc.obedit->mode, ob_iter) {
+ vc.scene, vc.view_layer, vc.v3d, vc.obedit->type, vc.obedit->mode, ob_iter) {
ED_view3d_viewcontext_init_object(&vc, ob_iter);
bool changed = false;
@@ -3945,7 +4057,7 @@ static void view3d_userdata_circleselect_init(CircleSelectUserData *r_data,
static void mesh_circle_doSelectVert(void *userData,
BMVert *eve,
const float screen_co[2],
- int UNUSED(index))
+ int /*index*/)
{
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);
@@ -3958,7 +4070,7 @@ static void mesh_circle_doSelectEdge(void *userData,
BMEdge *eed,
const float screen_co_a[2],
const float screen_co_b[2],
- int UNUSED(index))
+ int /*index*/)
{
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);
@@ -3970,7 +4082,7 @@ static void mesh_circle_doSelectEdge(void *userData,
static void mesh_circle_doSelectFace(void *userData,
BMFace *efa,
const float screen_co[2],
- int UNUSED(index))
+ int /*index*/)
{
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);
@@ -4018,7 +4130,7 @@ static bool mesh_circle_select(ViewContext *vc,
if (use_zbuf) {
if (esel->select_bitmap == nullptr) {
esel->select_bitmap = DRW_select_buffer_bitmap_from_circle(
- vc->depsgraph, vc->region, vc->v3d, mval, (int)(rad + 1.0f), nullptr);
+ vc->depsgraph, vc->region, vc->v3d, mval, int(rad + 1.0f), nullptr);
}
}
@@ -4094,7 +4206,7 @@ static bool paint_facesel_circle_select(ViewContext *vc,
{
EditSelectBuf_Cache *esel = static_cast<EditSelectBuf_Cache *>(wm_userdata->data);
esel->select_bitmap = DRW_select_buffer_bitmap_from_circle(
- vc->depsgraph, vc->region, vc->v3d, mval, (int)(rad + 1.0f), nullptr);
+ vc->depsgraph, vc->region, vc->v3d, mval, int(rad + 1.0f), nullptr);
if (esel->select_bitmap != nullptr) {
changed |= edbm_backbuf_check_and_select_faces_obmode(me, esel, sel_op);
MEM_freeN(esel->select_bitmap);
@@ -4108,15 +4220,21 @@ static bool paint_facesel_circle_select(ViewContext *vc,
return changed;
}
+struct CircleSelectUserData_ForMeshVert {
+ CircleSelectUserData circle_data;
+ blender::MutableSpan<bool> select_vert;
+};
static void paint_vertsel_circle_select_doSelectVert(void *userData,
- MVert *mv,
+ MVert * /*mv*/,
const float screen_co[2],
- int UNUSED(index))
+ int index)
{
- CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);
+ CircleSelectUserData_ForMeshVert *mesh_data = static_cast<CircleSelectUserData_ForMeshVert *>(
+ userData);
+ CircleSelectUserData *data = &mesh_data->circle_data;
if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
- SET_FLAG_FROM_TEST(mv->flag, data->select, SELECT);
+ mesh_data->select_vert[index] = data->select;
data->is_changed = true;
}
}
@@ -4126,6 +4244,7 @@ static bool paint_vertsel_circle_select(ViewContext *vc,
const int mval[2],
float rad)
{
+ using namespace blender;
BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
const bool use_zbuf = !XRAY_ENABLED(vc->v3d);
Object *ob = vc->obact;
@@ -4149,7 +4268,7 @@ static bool paint_vertsel_circle_select(ViewContext *vc,
if (use_zbuf) {
EditSelectBuf_Cache *esel = static_cast<EditSelectBuf_Cache *>(wm_userdata->data);
esel->select_bitmap = DRW_select_buffer_bitmap_from_circle(
- vc->depsgraph, vc->region, vc->v3d, mval, (int)(rad + 1.0f), nullptr);
+ vc->depsgraph, vc->region, vc->v3d, mval, int(rad + 1.0f), nullptr);
if (esel->select_bitmap != nullptr) {
changed |= edbm_backbuf_check_and_select_verts_obmode(me, esel, sel_op);
MEM_freeN(esel->select_bitmap);
@@ -4157,14 +4276,20 @@ static bool paint_vertsel_circle_select(ViewContext *vc,
}
}
else {
- CircleSelectUserData data;
+ bke::MutableAttributeAccessor attributes = me->attributes_for_write();
+ bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
+ ".select_vert", ATTR_DOMAIN_POINT);
+
+ CircleSelectUserData_ForMeshVert data;
+ data.select_vert = select_vert.span;
ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */
- view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
+ view3d_userdata_circleselect_init(&data.circle_data, vc, select, mval, rad);
meshobject_foreachScreenVert(
vc, paint_vertsel_circle_select_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- changed |= data.is_changed;
+ changed |= data.circle_data.is_changed;
+ select_vert.finish();
}
if (changed) {
@@ -4178,11 +4303,11 @@ static bool paint_vertsel_circle_select(ViewContext *vc,
}
static void nurbscurve_circle_doSelect(void *userData,
- Nurb *UNUSED(nu),
+ Nurb * /*nu*/,
BPoint *bp,
BezTriple *bezt,
int beztindex,
- bool UNUSED(handles_visible),
+ bool /*handles_visible*/,
const float screen_co[2])
{
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);
@@ -4301,7 +4426,7 @@ static void do_circle_select_pose__doSelectBone(void *userData,
bool is_point_done = false;
int points_proj_tot = 0;
- /* project head location to screenspace */
+ /* Project head location to screen-space. */
if (screen_co_a[0] != IS_CLIPPED) {
points_proj_tot++;
if (pchan_circle_doSelectJoint(data, pchan, screen_co_a)) {
@@ -4309,7 +4434,7 @@ static void do_circle_select_pose__doSelectBone(void *userData,
}
}
- /* project tail location to screenspace */
+ /* Project tail location to screen-space. */
if (screen_co_b[0] != IS_CLIPPED) {
points_proj_tot++;
if (pchan_circle_doSelectJoint(data, pchan, screen_co_b)) {
@@ -4415,7 +4540,7 @@ static void do_circle_select_armature__doSelectBone(void *userData,
bool is_edge_done = false;
int points_proj_tot = 0;
- /* project head location to screenspace */
+ /* Project head location to screen-space. */
if (screen_co_a[0] != IS_CLIPPED) {
points_proj_tot++;
if (armature_circle_doSelectJoint(data, ebone, screen_co_a, true)) {
@@ -4423,7 +4548,7 @@ static void do_circle_select_armature__doSelectBone(void *userData,
}
}
- /* project tail location to screenspace */
+ /* Project tail location to screen-space. */
if (screen_co_b[0] != IS_CLIPPED) {
points_proj_tot++;
if (armature_circle_doSelectJoint(data, ebone, screen_co_b, false)) {
@@ -4599,25 +4724,27 @@ static bool object_circle_select(ViewContext *vc,
float rad)
{
BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
+ Scene *scene = vc->scene;
ViewLayer *view_layer = vc->view_layer;
View3D *v3d = vc->v3d;
const float radius_squared = rad * rad;
- const float mval_fl[2] = {static_cast<float>(mval[0]), static_cast<float>(mval[1])};
+ const float mval_fl[2] = {float(mval[0]), float(mval[1])};
bool changed = false;
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- changed |= object_deselect_all_visible(vc->view_layer, vc->v3d);
+ changed |= object_deselect_all_visible(vc->scene, vc->view_layer, vc->v3d);
}
const bool select = (sel_op != SEL_OP_SUB);
const int select_flag = select ? BASE_SELECTED : 0;
-
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (BASE_SELECTABLE(v3d, base) && ((base->flag & BASE_SELECTED) != select_flag)) {
float screen_co[2];
- if (ED_view3d_project_float_global(
- vc->region, base->object->obmat[3], screen_co, V3D_PROJ_TEST_CLIP_DEFAULT) ==
- V3D_PROJ_RET_OK) {
+ if (ED_view3d_project_float_global(vc->region,
+ base->object->object_to_world[3],
+ screen_co,
+ V3D_PROJ_TEST_CLIP_DEFAULT) == V3D_PROJ_RET_OK) {
if (len_squared_v2v2(mval_fl, screen_co) <= radius_squared) {
ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
changed = true;
@@ -4642,7 +4769,7 @@ static void view3d_circle_select_recalc(void *user_data)
switch (vc.obedit->type) {
case OB_MESH: {
FOREACH_OBJECT_IN_MODE_BEGIN (
- vc.view_layer, vc.v3d, vc.obact->type, vc.obact->mode, ob_iter) {
+ vc.scene, vc.view_layer, vc.v3d, vc.obact->type, vc.obact->mode, ob_iter) {
ED_view3d_viewcontext_init_object(&vc, ob_iter);
BM_mesh_select_mode_flush_ex(
vc.em->bm, vc.em->selectmode, BM_SELECT_LEN_FLUSH_RECALC_ALL);
@@ -4698,23 +4825,24 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
BKE_object_update_select_id(CTX_data_main(C));
}
- FOREACH_OBJECT_IN_MODE_BEGIN (vc.view_layer, vc.v3d, obact->type, obact->mode, ob_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (
+ vc.scene, vc.view_layer, vc.v3d, obact->type, obact->mode, ob_iter) {
ED_view3d_viewcontext_init_object(&vc, ob_iter);
obact = vc.obact;
obedit = vc.obedit;
if (obedit) {
- obedit_circle_select(C, &vc, wm_userdata, sel_op, mval, (float)radius);
+ obedit_circle_select(C, &vc, wm_userdata, sel_op, mval, float(radius));
}
else if (BKE_paint_select_face_test(obact)) {
- paint_facesel_circle_select(&vc, wm_userdata, sel_op, mval, (float)radius);
+ paint_facesel_circle_select(&vc, wm_userdata, sel_op, mval, float(radius));
}
else if (BKE_paint_select_vert_test(obact)) {
- paint_vertsel_circle_select(&vc, wm_userdata, sel_op, mval, (float)radius);
+ paint_vertsel_circle_select(&vc, wm_userdata, sel_op, mval, float(radius));
}
else if (obact->mode & OB_MODE_POSE) {
- pose_circle_select(&vc, sel_op, mval, (float)radius);
+ pose_circle_select(&vc, sel_op, mval, float(radius));
ED_outliner_select_sync_from_pose_bone_tag(C);
}
else {
@@ -4724,7 +4852,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
FOREACH_OBJECT_IN_MODE_END;
}
else if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT)) {
- if (PE_circle_select(C, wm_userdata, sel_op, mval, (float)radius)) {
+ if (PE_circle_select(C, wm_userdata, sel_op, mval, float(radius))) {
return OPERATOR_FINISHED;
}
return OPERATOR_CANCELLED;
@@ -4733,7 +4861,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
else {
- if (object_circle_select(&vc, sel_op, mval, (float)radius)) {
+ if (object_circle_select(&vc, sel_op, mval, float(radius))) {
DEG_id_tag_update(&vc.scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc.scene);
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 2f51b2dce3b..8c6f4387851 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -69,7 +69,7 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -86,18 +86,18 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
}
if (tvs.transverts_tot != 0) {
- copy_m3_m4(bmat, obedit->obmat);
+ copy_m3_m4(bmat, obedit->object_to_world);
invert_m3_m3(imat, bmat);
tv = tvs.transverts;
for (a = 0; a < tvs.transverts_tot; a++, tv++) {
copy_v3_v3(vec, tv->loc);
mul_m3_v3(bmat, vec);
- add_v3_v3(vec, obedit->obmat[3]);
+ add_v3_v3(vec, obedit->object_to_world[3]);
vec[0] = gridf * floorf(0.5f + vec[0] / gridf);
vec[1] = gridf * floorf(0.5f + vec[1] / gridf);
vec[2] = gridf * floorf(0.5f + vec[2] / gridf);
- sub_v3_v3(vec, obedit->obmat[3]);
+ sub_v3_v3(vec, obedit->object_to_world[3]);
mul_m3_v3(imat, vec);
copy_v3_v3(tv->loc, vec);
@@ -111,14 +111,14 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
else if (OBPOSE_FROM_OBACT(obact)) {
struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
uint objects_len = 0;
- Object **objects_eval = BKE_object_pose_array_get(view_layer_eval, v3d, &objects_len);
+ Object **objects_eval = BKE_object_pose_array_get(scene, view_layer_eval, v3d, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob_eval = objects_eval[ob_index];
Object *ob = DEG_get_original_object(ob_eval);
bPoseChannel *pchan_eval;
bArmature *arm_eval = ob_eval->data;
- invert_m4_m4(ob_eval->imat, ob_eval->obmat);
+ invert_m4_m4(ob_eval->world_to_object, ob_eval->object_to_world);
for (pchan_eval = ob_eval->pose->chanbase.first; pchan_eval; pchan_eval = pchan_eval->next) {
if (pchan_eval->bone->flag & BONE_SELECTED) {
@@ -129,12 +129,12 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
/* get nearest grid point to snap to */
copy_v3_v3(nLoc, pchan_eval->pose_mat[3]);
/* We must operate in world space! */
- mul_m4_v3(ob_eval->obmat, nLoc);
+ mul_m4_v3(ob_eval->object_to_world, nLoc);
vec[0] = gridf * floorf(0.5f + nLoc[0] / gridf);
vec[1] = gridf * floorf(0.5f + nLoc[1] / gridf);
vec[2] = gridf * floorf(0.5f + nLoc[2] / gridf);
/* Back in object space... */
- mul_m4_v3(ob_eval->imat, vec);
+ mul_m4_v3(ob_eval->world_to_object, vec);
/* Get location of grid point in pose space. */
BKE_armature_loc_pose_to_bone(pchan_eval, vec, vec);
@@ -203,7 +203,7 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
xcs = ED_object_xform_skip_child_container_create();
ED_object_xform_skip_child_container_item_ensure_from_array(
- xcs, view_layer, objects, objects_eval_len);
+ xcs, scene, view_layer, objects, objects_eval_len);
MEM_freeN(objects);
}
if (use_transform_data_origin) {
@@ -214,9 +214,12 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
for (int ob_index = 0; ob_index < objects_eval_len; ob_index++) {
Object *ob_eval = objects_eval[ob_index];
Object *ob = DEG_get_original_object(ob_eval);
- vec[0] = -ob_eval->obmat[3][0] + gridf * floorf(0.5f + ob_eval->obmat[3][0] / gridf);
- vec[1] = -ob_eval->obmat[3][1] + gridf * floorf(0.5f + ob_eval->obmat[3][1] / gridf);
- vec[2] = -ob_eval->obmat[3][2] + gridf * floorf(0.5f + ob_eval->obmat[3][2] / gridf);
+ vec[0] = -ob_eval->object_to_world[3][0] +
+ gridf * floorf(0.5f + ob_eval->object_to_world[3][0] / gridf);
+ vec[1] = -ob_eval->object_to_world[3][1] +
+ gridf * floorf(0.5f + ob_eval->object_to_world[3][1] / gridf);
+ vec[2] = -ob_eval->object_to_world[3][2] +
+ gridf * floorf(0.5f + ob_eval->object_to_world[3][2] / gridf);
if (ob->parent) {
float originmat[3][3];
@@ -326,7 +329,7 @@ static bool snap_selected_to_location(bContext *C,
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, v3d, &objects_len);
+ scene, view_layer, v3d, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
obedit = objects[ob_index];
@@ -343,11 +346,11 @@ static bool snap_selected_to_location(bContext *C,
}
if (tvs.transverts_tot != 0) {
- copy_m3_m4(bmat, obedit->obmat);
+ copy_m3_m4(bmat, obedit->object_to_world);
invert_m3_m3(imat, bmat);
/* get the cursor in object space */
- sub_v3_v3v3(snap_target_local, snap_target_global, obedit->obmat[3]);
+ sub_v3_v3v3(snap_target_local, snap_target_global, obedit->object_to_world[3]);
mul_m3_v3(imat, snap_target_local);
if (use_offset) {
@@ -376,7 +379,7 @@ static bool snap_selected_to_location(bContext *C,
struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
- Object **objects = BKE_object_pose_array_get(view_layer, v3d, &objects_len);
+ Object **objects = BKE_object_pose_array_get(scene, view_layer, v3d, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
@@ -384,11 +387,11 @@ static bool snap_selected_to_location(bContext *C,
bArmature *arm = ob->data;
float snap_target_local[3];
- invert_m4_m4(ob->imat, ob->obmat);
- mul_v3_m4v3(snap_target_local, ob->imat, snap_target_global);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
+ mul_v3_m4v3(snap_target_local, ob->world_to_object, snap_target_global);
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- if ((pchan->bone->flag & BONE_SELECTED) && (PBONE_VISIBLE(arm, pchan->bone)) &&
+ if ((pchan->bone->flag & BONE_SELECTED) && PBONE_VISIBLE(arm, pchan->bone) &&
/* if the bone has a parent and is connected to the parent,
* don't do anything - will break chain unless we do auto-ik.
*/
@@ -409,10 +412,10 @@ static bool snap_selected_to_location(bContext *C,
float cursor_pose[3];
if (use_offset) {
- mul_v3_m4v3(cursor_pose, ob->obmat, pchan->pose_mat[3]);
+ mul_v3_m4v3(cursor_pose, ob->object_to_world, pchan->pose_mat[3]);
add_v3_v3(cursor_pose, offset_global);
- mul_m4_v3(ob->imat, cursor_pose);
+ mul_m4_v3(ob->world_to_object, cursor_pose);
BKE_armature_loc_pose_to_bone(pchan, cursor_pose, cursor_pose);
}
else {
@@ -487,7 +490,7 @@ static bool snap_selected_to_location(bContext *C,
BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
xcs = ED_object_xform_skip_child_container_create();
ED_object_xform_skip_child_container_item_ensure_from_array(
- xcs, view_layer, objects, objects_len);
+ xcs, scene, view_layer, objects, objects_len);
}
if (use_transform_data_origin) {
BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
@@ -510,13 +513,13 @@ static bool snap_selected_to_location(bContext *C,
float cursor_parent[3]; /* parent-relative */
if (use_offset) {
- add_v3_v3v3(cursor_parent, ob->obmat[3], offset_global);
+ add_v3_v3v3(cursor_parent, ob->object_to_world[3], offset_global);
}
else {
copy_v3_v3(cursor_parent, snap_target_global);
}
- sub_v3_v3(cursor_parent, ob->obmat[3]);
+ sub_v3_v3(cursor_parent, ob->object_to_world[3]);
if (ob->parent) {
float originmat[3][3], parentmat[4][4];
@@ -730,7 +733,7 @@ static void bundle_midpoint(Scene *scene, Object *ob, float r_vec[3])
tracking = &clip->tracking;
- copy_m4_m4(cammat, ob->obmat);
+ copy_m4_m4(cammat, ob->object_to_world);
BKE_tracking_get_camera_object_matrix(ob, mat);
@@ -789,7 +792,7 @@ static bool snap_curs_to_sel_ex(bContext *C, const int pivot_point, float r_curs
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
obedit = objects[ob_index];
@@ -809,13 +812,13 @@ static bool snap_curs_to_sel_ex(bContext *C, const int pivot_point, float r_curs
count += tvs.transverts_tot;
if (tvs.transverts_tot != 0) {
Object *obedit_eval = DEG_get_evaluated_object(depsgraph, obedit);
- copy_m3_m4(bmat, obedit_eval->obmat);
+ copy_m3_m4(bmat, obedit_eval->object_to_world);
tv = tvs.transverts;
for (int i = 0; i < tvs.transverts_tot; i++, tv++) {
copy_v3_v3(vec, tv->loc);
mul_m3_v3(bmat, vec);
- add_v3_v3(vec, obedit_eval->obmat[3]);
+ add_v3_v3(vec, obedit_eval->object_to_world[3]);
add_v3_v3(centroid, vec);
minmax_v3v3_v3(min, max, vec);
}
@@ -835,7 +838,7 @@ static bool snap_curs_to_sel_ex(bContext *C, const int pivot_point, float r_curs
if (arm->layer & pchan->bone->layer) {
if (pchan->bone->flag & BONE_SELECTED) {
copy_v3_v3(vec, pchan->pose_head);
- mul_m4_v3(obact_eval->obmat, vec);
+ mul_m4_v3(obact_eval->object_to_world, vec);
add_v3_v3(centroid, vec);
minmax_v3v3_v3(min, max, vec);
count++;
@@ -845,7 +848,7 @@ static bool snap_curs_to_sel_ex(bContext *C, const int pivot_point, float r_curs
}
else {
FOREACH_SELECTED_OBJECT_BEGIN (view_layer_eval, v3d, ob_eval) {
- copy_v3_v3(vec, ob_eval->obmat[3]);
+ copy_v3_v3(vec, ob_eval->object_to_world[3]);
/* special case for camera -- snap to bundles */
if (ob_eval->type == OB_CAMERA) {
@@ -1008,7 +1011,7 @@ bool ED_view3d_minmax_verts(Object *obedit, float r_min[3], float r_max[3])
float ob_min[3], ob_max[3];
bool changed;
- changed = BKE_mball_minmax_ex(obedit->data, ob_min, ob_max, obedit->obmat, SELECT);
+ changed = BKE_mball_minmax_ex(obedit->data, ob_min, ob_max, obedit->object_to_world, SELECT);
if (changed) {
minmax_v3v3_v3(r_min, r_max, ob_min);
minmax_v3v3_v3(r_min, r_max, ob_max);
@@ -1024,13 +1027,13 @@ bool ED_view3d_minmax_verts(Object *obedit, float r_min[3], float r_max[3])
return false;
}
- copy_m3_m4(bmat, obedit->obmat);
+ copy_m3_m4(bmat, obedit->object_to_world);
tv = tvs.transverts;
for (int a = 0; a < tvs.transverts_tot; a++, tv++) {
copy_v3_v3(vec, (tv->flag & TX_VERT_USE_MAPLOC) ? tv->maploc : tv->loc);
mul_m3_v3(bmat, vec);
- add_v3_v3(vec, obedit->obmat[3]);
+ add_v3_v3(vec, obedit->object_to_world[3]);
add_v3_v3(centroid, vec);
minmax_v3v3_v3(r_min, r_max, vec);
}
diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c
index cb716391fb2..fc26e6b4a06 100644
--- a/source/blender/editors/space_view3d/view3d_utils.c
+++ b/source/blender/editors/space_view3d/view3d_utils.c
@@ -271,8 +271,8 @@ void ED_view3d_clipping_calc(
/* four clipping planes and bounding volume */
/* first do the bounding volume */
for (int val = 0; val < 4; val++) {
- float xs = (ELEM(val, 0, 3)) ? rect->xmin : rect->xmax;
- float ys = (ELEM(val, 0, 1)) ? rect->ymin : rect->ymax;
+ float xs = ELEM(val, 0, 3) ? rect->xmin : rect->xmax;
+ float ys = ELEM(val, 0, 1) ? rect->ymin : rect->ymax;
ED_view3d_unproject_v3(region, xs, ys, 0.0, bb->vec[val]);
ED_view3d_unproject_v3(region, xs, ys, 1.0, bb->vec[4 + val]);
@@ -281,7 +281,7 @@ void ED_view3d_clipping_calc(
/* optionally transform to object space */
if (ob) {
float imat[4][4];
- invert_m4_m4(imat, ob->obmat);
+ invert_m4_m4(imat, ob->object_to_world);
for (int val = 0; val < 8; val++) {
mul_m4_v3(imat, bb->vec[val]);
@@ -291,7 +291,7 @@ void ED_view3d_clipping_calc(
/* verify if we have negative scale. doing the transform before cross
* product flips the sign of the vector compared to doing cross product
* before transform then, so we correct for that. */
- int flip_sign = (ob) ? is_negative_m4(ob->obmat) : false;
+ int flip_sign = (ob) ? is_negative_m4(ob->object_to_world) : false;
ED_view3d_clipping_calc_from_boundbox(planes, bb, flip_sign);
}
@@ -466,7 +466,8 @@ void ED_view3d_persp_switch_from_camera(const Depsgraph *depsgraph,
if (v3d->camera) {
Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
- rv3d->dist = ED_view3d_offset_distance(ob_camera_eval->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
+ rv3d->dist = ED_view3d_offset_distance(
+ ob_camera_eval->object_to_world, rv3d->ofs, VIEW3D_DIST_FALLBACK);
ED_view3d_from_object(ob_camera_eval, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
}
@@ -544,7 +545,7 @@ bool ED_view3d_camera_view_pan(ARegion *region, const float event_ofs[2])
bool ED_view3d_camera_lock_check(const View3D *v3d, const RegionView3D *rv3d)
{
- return ((v3d->camera) && (!ID_IS_LINKED(v3d->camera)) && (v3d->flag2 & V3D_LOCK_CAMERA) &&
+ return ((v3d->camera) && !ID_IS_LINKED(v3d->camera) && (v3d->flag2 & V3D_LOCK_CAMERA) &&
(rv3d->persp == RV3D_CAMOB));
}
@@ -558,7 +559,7 @@ void ED_view3d_camera_lock_init_ex(const Depsgraph *depsgraph,
if (calc_dist) {
/* using a fallback dist is OK here since ED_view3d_from_object() compensates for it */
rv3d->dist = ED_view3d_offset_distance(
- ob_camera_eval->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
+ ob_camera_eval->object_to_world, rv3d->ofs, VIEW3D_DIST_FALLBACK);
}
ED_view3d_from_object(ob_camera_eval, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
}
@@ -592,12 +593,12 @@ bool ED_view3d_camera_lock_sync(const Depsgraph *depsgraph, View3D *v3d, RegionV
ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
- normalize_m4_m4(tmat, ob_camera_eval->obmat);
+ normalize_m4_m4(tmat, ob_camera_eval->object_to_world);
invert_m4_m4(imat, tmat);
mul_m4_m4m4(diff_mat, view_mat, imat);
- mul_m4_m4m4(parent_mat, diff_mat, root_parent_eval->obmat);
+ mul_m4_m4m4(parent_mat, diff_mat, root_parent_eval->object_to_world);
BKE_object_tfm_protected_backup(root_parent, &obtfm);
BKE_object_apply_mat4(root_parent, parent_mat, true, false);
@@ -1508,7 +1509,7 @@ void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], c
void ED_view3d_from_object(const Object *ob, float ofs[3], float quat[4], float *dist, float *lens)
{
- ED_view3d_from_m4(ob->obmat, ofs, quat, dist);
+ ED_view3d_from_m4(ob->object_to_world, ofs, quat, dist);
if (lens) {
CameraParams params;
@@ -1555,7 +1556,7 @@ static bool view3d_camera_to_view_selected_impl(struct Main *bmain,
is_ortho_camera = true;
}
- copy_m4_m4(obmat_new, camera_ob_eval->obmat);
+ copy_m4_m4(obmat_new, camera_ob_eval->object_to_world);
copy_v3_v3(obmat_new[3], co);
/* only touch location */
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 124527822a5..c630a1a5653 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -365,7 +365,7 @@ static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob)
rv3d->view = RV3D_VIEW_USER; /* don't show the grid */
- normalize_m4_m4(bmat, ob->obmat);
+ normalize_m4_m4(bmat, ob->object_to_world);
invert_m4_m4(rv3d->viewmat, bmat);
/* view quat calculation, needed for add object */
@@ -404,12 +404,12 @@ void view3d_viewmatrix_set(Depsgraph *depsgraph,
Object *ob_eval = DEG_get_evaluated_object(depsgraph, v3d->ob_center);
float vec[3];
- copy_v3_v3(vec, ob_eval->obmat[3]);
+ copy_v3_v3(vec, ob_eval->object_to_world[3]);
if (ob_eval->type == OB_ARMATURE && v3d->ob_center_bone[0]) {
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_eval->pose, v3d->ob_center_bone);
if (pchan) {
copy_v3_v3(vec, pchan->pose_mat[3]);
- mul_m4_v3(ob_eval->obmat, vec);
+ mul_m4_v3(ob_eval->object_to_world, vec);
}
}
translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]);
@@ -553,6 +553,7 @@ int view3d_opengl_select_ex(ViewContext *vc,
ARegion *region = vc->region;
rcti rect;
int hits = 0;
+ BKE_view_layer_synced_ensure(scene, vc->view_layer);
const bool use_obedit_skip = (BKE_view_layer_edit_object_get(vc->view_layer) != NULL) &&
(vc->obedit == NULL);
const bool is_pick_select = (U.gpu_flag & USER_GPU_FLAG_NO_DEPT_PICK) == 0;
@@ -824,6 +825,7 @@ static bool view3d_localview_init(const Depsgraph *depsgraph,
wmWindowManager *wm,
wmWindow *win,
Main *bmain,
+ const Scene *scene,
ViewLayer *view_layer,
ScrArea *area,
const bool frame_selected,
@@ -851,12 +853,14 @@ static bool view3d_localview_init(const Depsgraph *depsgraph,
ok = false;
}
else {
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
if (obedit) {
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
base->local_view_bits &= ~local_view_bit;
}
- FOREACH_BASE_IN_EDIT_MODE_BEGIN (view_layer, v3d, base_iter) {
+ FOREACH_BASE_IN_EDIT_MODE_BEGIN (scene, view_layer, v3d, base_iter) {
BKE_object_minmax(base_iter->object, min, max, false);
base_iter->local_view_bits |= local_view_bit;
ok = true;
@@ -864,7 +868,8 @@ static bool view3d_localview_init(const Depsgraph *depsgraph,
FOREACH_BASE_IN_EDIT_MODE_END;
}
else {
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (BASE_SELECTED(v3d, base)) {
BKE_object_minmax(base->object, min, max, false);
base->local_view_bits |= local_view_bit;
@@ -955,6 +960,7 @@ static bool view3d_localview_init(const Depsgraph *depsgraph,
static void view3d_localview_exit(const Depsgraph *depsgraph,
wmWindowManager *wm,
wmWindow *win,
+ const Scene *scene,
ViewLayer *view_layer,
ScrArea *area,
const bool frame_selected,
@@ -965,8 +971,8 @@ static void view3d_localview_exit(const Depsgraph *depsgraph,
if (v3d->localvd == NULL) {
return;
}
-
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (base->local_view_bits & v3d->local_view_uuid) {
base->local_view_bits &= ~v3d->local_view_uuid;
}
@@ -1039,12 +1045,21 @@ static int localview_exec(bContext *C, wmOperator *op)
bool changed;
if (v3d->localvd) {
- view3d_localview_exit(depsgraph, wm, win, view_layer, area, frame_selected, smooth_viewtx);
+ view3d_localview_exit(
+ depsgraph, wm, win, scene, view_layer, area, frame_selected, smooth_viewtx);
changed = true;
}
else {
- changed = view3d_localview_init(
- depsgraph, wm, win, bmain, view_layer, area, frame_selected, smooth_viewtx, op->reports);
+ changed = view3d_localview_init(depsgraph,
+ wm,
+ win,
+ bmain,
+ scene,
+ view_layer,
+ area,
+ frame_selected,
+ smooth_viewtx,
+ op->reports);
}
if (changed) {
@@ -1092,8 +1107,8 @@ static int localview_remove_from_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
bool changed = false;
-
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (BASE_SELECTED(v3d, base)) {
base->local_view_bits &= ~v3d->local_view_uuid;
ED_object_base_select(base, BA_DESELECT);
@@ -1265,7 +1280,7 @@ void ED_view3d_local_collections_reset(struct bContext *C, const bool reset_all)
else if (reset_all && (do_reset || (local_view_bit != ~(0)))) {
view3d_local_collections_reset(bmain, ~(0));
View3D v3d = {.local_collections_uuid = ~(0)};
- BKE_layer_collection_local_sync(CTX_data_view_layer(C), &v3d);
+ BKE_layer_collection_local_sync(CTX_data_scene(C), CTX_data_view_layer(C), &v3d);
DEG_id_tag_update(&CTX_data_scene(C)->id, ID_RECALC_BASE_FLAGS);
}
}
diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt
index ec6f62e0f5b..3787a59c83c 100644
--- a/source/blender/editors/transform/CMakeLists.txt
+++ b/source/blender/editors/transform/CMakeLists.txt
@@ -40,7 +40,7 @@ set(SRC
transform_convert_mesh_uv.c
transform_convert_mesh_vert_cdata.c
transform_convert_nla.c
- transform_convert_node.c
+ transform_convert_node.cc
transform_convert_object.c
transform_convert_object_texspace.c
transform_convert_paintcurve.c
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 49258d63611..ad6ab625438 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -60,14 +60,12 @@
* and being able to set it to zero is handy. */
/* #define USE_NUM_NO_ZERO */
-static void initSnapSpatial(TransInfo *t, float r_snap[2]);
-
bool transdata_check_local_islands(TransInfo *t, short around)
{
if (t->options & (CTX_CURSOR | CTX_TEXTURE_SPACE)) {
return false;
}
- return ((around == V3D_AROUND_LOCAL_ORIGINS) && (ELEM(t->obedit_type, OB_MESH, OB_GPENCIL)));
+ return ((around == V3D_AROUND_LOCAL_ORIGINS) && ELEM(t->obedit_type, OB_MESH, OB_GPENCIL));
}
/* ************************** SPACE DEPENDENT CODE **************************** */
@@ -485,6 +483,7 @@ static void viewRedrawForce(const bContext *C, TransInfo *t)
/* XXX how to deal with lock? */
SpaceImage *sima = (SpaceImage *)t->area->spacedata.first;
if (sima->lock) {
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
WM_event_add_notifier(
C, NC_GEOM | ND_DATA, BKE_view_layer_edit_object_get(t->view_layer)->data);
}
@@ -1478,6 +1477,7 @@ static void drawTransformPixel(const struct bContext *C, ARegion *region, void *
if (region == t->region) {
Scene *scene = t->scene;
ViewLayer *view_layer = t->view_layer;
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
/* draw auto-key-framing hint in the corner
@@ -1516,28 +1516,29 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
}
}
- bool use_prop_edit = false;
- int prop_edit_flag = 0;
- if (t->flag & T_PROP_EDIT_ALL) {
- if (t->flag & T_PROP_EDIT) {
- use_prop_edit = true;
- }
- if (t->flag & T_PROP_CONNECTED) {
- prop_edit_flag |= PROP_EDIT_CONNECTED;
- }
- if (t->flag & T_PROP_PROJECTED) {
- prop_edit_flag |= PROP_EDIT_PROJECTED;
+ /* Save proportional edit settings.
+ * Skip saving proportional edit if it was not actually used. */
+ if (!(t->options & CTX_NO_PET)) {
+ bool use_prop_edit = false;
+ int prop_edit_flag = 0;
+ if (t->flag & T_PROP_EDIT_ALL) {
+ if (t->flag & T_PROP_EDIT) {
+ use_prop_edit = true;
+ }
+ if (t->flag & T_PROP_CONNECTED) {
+ prop_edit_flag |= PROP_EDIT_CONNECTED;
+ }
+ if (t->flag & T_PROP_PROJECTED) {
+ prop_edit_flag |= PROP_EDIT_PROJECTED;
+ }
}
- }
-
- /* If modal, save settings back in scene if not set as operator argument */
- if ((t->flag & T_MODAL) || (op->flag & OP_IS_REPEAT)) {
- /* save settings if not set in operator */
- /* skip saving proportional edit if it was not actually used */
- if (!(t->options & CTX_NO_PET)) {
+ /* If modal, save settings back in scene if not set as operator argument */
+ if ((t->flag & T_MODAL) || (op->flag & OP_IS_REPEAT)) {
+ /* save settings if not set in operator */
if ((prop = RNA_struct_find_property(op->ptr, "use_proportional_edit")) &&
!RNA_property_is_set(op->ptr, prop)) {
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
const Object *obact = BKE_view_layer_active_object_get(t->view_layer);
if (t->spacetype == SPACE_GRAPH) {
@@ -1573,54 +1574,73 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
ts->prop_mode = t->prop_mode;
}
}
+
+ if ((prop = RNA_struct_find_property(op->ptr, "use_proportional_edit"))) {
+ RNA_property_boolean_set(op->ptr, prop, use_prop_edit);
+ RNA_boolean_set(op->ptr, "use_proportional_connected", prop_edit_flag & PROP_EDIT_CONNECTED);
+ RNA_boolean_set(op->ptr, "use_proportional_projected", prop_edit_flag & PROP_EDIT_PROJECTED);
+ RNA_enum_set(op->ptr, "proportional_edit_falloff", t->prop_mode);
+ RNA_float_set(op->ptr, "proportional_size", t->prop_size);
+ }
}
- if (t->flag & T_MODAL) {
- /* do we check for parameter? */
- if (transformModeUseSnap(t)) {
- if (!(t->modifiers & MOD_SNAP) != !(t->tsnap.flag & SCE_SNAP)) {
- /* Type is #eSnapFlag, but type must match various snap attributes in #ToolSettings. */
- short *snap_flag_ptr;
+ /* Save snapping settings. */
+ if ((prop = RNA_struct_find_property(op->ptr, "snap"))) {
+ RNA_property_boolean_set(op->ptr, prop, (t->modifiers & MOD_SNAP) != 0);
- wmMsgParams_RNA msg_key_params = {{0}};
- RNA_pointer_create(&t->scene->id, &RNA_ToolSettings, ts, &msg_key_params.ptr);
+ if ((prop = RNA_struct_find_property(op->ptr, "snap_elements"))) {
+ RNA_property_enum_set(op->ptr, prop, t->tsnap.mode);
+ RNA_boolean_set(op->ptr, "use_snap_project", t->tsnap.project);
+ RNA_enum_set(op->ptr, "snap_target", t->tsnap.source_select);
- if (t->spacetype == SPACE_NODE) {
- snap_flag_ptr = &ts->snap_flag_node;
- msg_key_params.prop = &rna_ToolSettings_use_snap_node;
- }
- else if (t->spacetype == SPACE_IMAGE) {
- snap_flag_ptr = &ts->snap_uv_flag;
- msg_key_params.prop = &rna_ToolSettings_use_snap_uv;
- }
- else if (t->spacetype == SPACE_SEQ) {
- snap_flag_ptr = &ts->snap_flag_seq;
- msg_key_params.prop = &rna_ToolSettings_use_snap_sequencer;
- }
- else {
- snap_flag_ptr = &ts->snap_flag;
- msg_key_params.prop = &rna_ToolSettings_use_snap;
- }
+ eSnapTargetSelect target = t->tsnap.target_select;
+ RNA_boolean_set(op->ptr, "use_snap_self", (target & SCE_SNAP_TARGET_NOT_ACTIVE) == 0);
+ RNA_boolean_set(op->ptr, "use_snap_edit", (target & SCE_SNAP_TARGET_NOT_EDITED) == 0);
+ RNA_boolean_set(op->ptr, "use_snap_nonedit", (target & SCE_SNAP_TARGET_NOT_NONEDITED) == 0);
+ RNA_boolean_set(
+ op->ptr, "use_snap_selectable", (target & SCE_SNAP_TARGET_ONLY_SELECTABLE) != 0);
+ }
- if (t->modifiers & MOD_SNAP) {
- *snap_flag_ptr |= SCE_SNAP;
- }
- else {
- *snap_flag_ptr &= ~SCE_SNAP;
+ /* Update `ToolSettings` for properties that change during modal. */
+ if (t->flag & T_MODAL) {
+ /* Do we check for parameter? */
+ if (transformModeUseSnap(t)) {
+ if (!(t->modifiers & MOD_SNAP) != !(t->tsnap.flag & SCE_SNAP)) {
+ /* Type is #eSnapFlag, but type must match various snap attributes in #ToolSettings. */
+ short *snap_flag_ptr;
+
+ wmMsgParams_RNA msg_key_params = {{0}};
+ RNA_pointer_create(&t->scene->id, &RNA_ToolSettings, ts, &msg_key_params.ptr);
+
+ if (t->spacetype == SPACE_NODE) {
+ snap_flag_ptr = &ts->snap_flag_node;
+ msg_key_params.prop = &rna_ToolSettings_use_snap_node;
+ }
+ else if (t->spacetype == SPACE_IMAGE) {
+ snap_flag_ptr = &ts->snap_uv_flag;
+ msg_key_params.prop = &rna_ToolSettings_use_snap_uv;
+ }
+ else if (t->spacetype == SPACE_SEQ) {
+ snap_flag_ptr = &ts->snap_flag_seq;
+ msg_key_params.prop = &rna_ToolSettings_use_snap_sequencer;
+ }
+ else {
+ snap_flag_ptr = &ts->snap_flag;
+ msg_key_params.prop = &rna_ToolSettings_use_snap;
+ }
+
+ if (t->modifiers & MOD_SNAP) {
+ *snap_flag_ptr |= SCE_SNAP;
+ }
+ else {
+ *snap_flag_ptr &= ~SCE_SNAP;
+ }
+ WM_msg_publish_rna_params(t->mbus, &msg_key_params);
}
- WM_msg_publish_rna_params(t->mbus, &msg_key_params);
}
}
}
- if ((prop = RNA_struct_find_property(op->ptr, "use_proportional_edit"))) {
- RNA_property_boolean_set(op->ptr, prop, use_prop_edit);
- RNA_boolean_set(op->ptr, "use_proportional_connected", prop_edit_flag & PROP_EDIT_CONNECTED);
- RNA_boolean_set(op->ptr, "use_proportional_projected", prop_edit_flag & PROP_EDIT_PROJECTED);
- RNA_enum_set(op->ptr, "proportional_edit_falloff", t->prop_mode);
- RNA_float_set(op->ptr, "proportional_size", t->prop_size);
- }
-
if ((prop = RNA_struct_find_property(op->ptr, "mirror"))) {
RNA_property_boolean_set(op->ptr, prop, (t->flag & T_NO_MIRROR) == 0);
}
@@ -1655,8 +1675,8 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
orient_type_set = orient_type_curr;
}
- if (((prop = RNA_struct_find_property(op->ptr, "orient_matrix_type")) &&
- !RNA_property_is_set(op->ptr, prop))) {
+ if ((prop = RNA_struct_find_property(op->ptr, "orient_matrix_type")) &&
+ !RNA_property_is_set(op->ptr, prop)) {
/* Set the first time to register on redo. */
RNA_property_enum_set(op->ptr, prop, orient_type_set);
RNA_float_set_array(op->ptr, "orient_matrix", &t->spacemtx[0][0]);
@@ -1701,13 +1721,18 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
}
}
-static void initSnapSpatial(TransInfo *t, float r_snap[2])
+static void initSnapSpatial(TransInfo *t, float r_snap[3], float *r_snap_precision)
{
+ /* Default values. */
+ r_snap[0] = r_snap[1] = 1.0f;
+ r_snap[2] = 0.0f;
+ *r_snap_precision = 0.1f;
+
if (t->spacetype == SPACE_VIEW3D) {
if (t->region->regiondata) {
View3D *v3d = t->area->spacedata.first;
- r_snap[0] = ED_view3d_grid_view_scale(t->scene, v3d, t->region, NULL) * 1.0f;
- r_snap[1] = r_snap[0] * 0.1f;
+ r_snap[0] = r_snap[1] = r_snap[2] = ED_view3d_grid_view_scale(
+ t->scene, v3d, t->region, NULL);
}
}
else if (t->spacetype == SPACE_IMAGE) {
@@ -1715,27 +1740,22 @@ static void initSnapSpatial(TransInfo *t, float r_snap[2])
View2D *v2d = &t->region->v2d;
int grid_size = SI_GRID_STEPS_LEN;
float zoom_factor = ED_space_image_zoom_level(v2d, grid_size);
- float grid_steps[SI_GRID_STEPS_LEN];
+ float grid_steps_x[SI_GRID_STEPS_LEN];
+ float grid_steps_y[SI_GRID_STEPS_LEN];
- ED_space_image_grid_steps(sima, grid_steps, grid_size);
+ ED_space_image_grid_steps(sima, grid_steps_x, grid_steps_y, grid_size);
/* Snapping value based on what type of grid is used (adaptive-subdividing or custom-grid). */
- r_snap[0] = ED_space_image_increment_snap_value(grid_size, grid_steps, zoom_factor);
- r_snap[1] = r_snap[0] / 2.0f;
+ r_snap[0] = ED_space_image_increment_snap_value(grid_size, grid_steps_x, zoom_factor);
+ r_snap[1] = ED_space_image_increment_snap_value(grid_size, grid_steps_y, zoom_factor);
+ *r_snap_precision = 0.5f;
}
else if (t->spacetype == SPACE_CLIP) {
- r_snap[0] = 0.125f;
- r_snap[1] = 0.0625f;
+ r_snap[0] = r_snap[1] = 0.125f;
+ *r_snap_precision = 0.5f;
}
else if (t->spacetype == SPACE_NODE) {
r_snap[0] = r_snap[1] = ED_node_grid_size();
}
- else if (t->spacetype == SPACE_GRAPH) {
- r_snap[0] = 1.0;
- r_snap[1] = 0.1f;
- }
- else {
- r_snap[0] = r_snap[1] = 1.0f;
- }
}
bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event, int mode)
@@ -1875,7 +1895,7 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
initSnapping(t, op); /* Initialize snapping data AFTER mode flags */
- initSnapSpatial(t, t->snap_spatial);
+ initSnapSpatial(t, t->snap_spatial, &t->snap_spatial_precision);
/* EVIL! posemode code can switch translation to rotate when 1 bone is selected.
* will be removed (ton) */
@@ -2047,7 +2067,7 @@ bool checkUseAxisMatrix(TransInfo *t)
/* currently only checks for editmode */
if (t->flag & T_EDIT) {
if ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
- (ELEM(t->obedit_type, OB_MESH, OB_CURVES_LEGACY, OB_MBALL, OB_ARMATURE))) {
+ ELEM(t->obedit_type, OB_MESH, OB_CURVES_LEGACY, OB_MBALL, OB_ARMATURE)) {
/* not all editmode supports axis-matrix */
return true;
}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 09fc07f57f4..1e260ecd292 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -19,6 +19,10 @@
#include "transform_data.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* use node center for transform instead of upper-left corner.
* disabled since it makes absolute snapping not work so nicely
*/
@@ -141,6 +145,7 @@ typedef enum {
/** No cursor wrapping on region bounds */
T_NO_CURSOR_WRAP = 1 << 23,
} eTFlag;
+ENUM_OPERATORS(eTFlag, T_NO_CURSOR_WRAP);
#define T_ALL_RESTRICTIONS (T_NO_CONSTRAINT | T_NULL_ONE)
#define T_PROP_EDIT_ALL (T_PROP_EDIT | T_PROP_CONNECTED | T_PROP_PROJECTED)
@@ -464,7 +469,8 @@ typedef struct TransDataContainer {
/**
* Store matrix, this avoids having to have duplicate check all over
- * Typically: 'obedit->obmat' or 'poseobj->obmat', but may be used elsewhere too.
+ * Typically: 'obedit->object_to_world' or 'poseobj->object_to_world', but may be used elsewhere
+ * too.
*/
bool use_local_mat;
@@ -550,7 +556,12 @@ typedef struct TransInfo {
/** Snapping Gears. */
float snap[2];
/** Spatial snapping gears(even when rotating, scaling... etc). */
- float snap_spatial[2];
+ float snap_spatial[3];
+ /**
+ * Precision factor that is multiplied to snap_spatial when precision
+ * modifier is enabled for snap to grid or incremental snap.
+ */
+ float snap_spatial_precision;
/** Mouse side of the current frame, 'L', 'R' or 'B' */
char frame_side;
@@ -864,3 +875,7 @@ bool checkUseAxisMatrix(TransInfo *t);
th++, i++)
/** \} */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 2e12611a7c9..7abf0e5c00c 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -337,25 +337,20 @@ static bool isPlaneProjectionViewAligned(const TransInfo *t, const float plane[4
return fabsf(factor) < eps;
}
-static void planeProjection(const TransInfo *t, const float in[3], float out[3])
+static void planeProjection(const TransInfo *t,
+ const float plane[4],
+ const float in[3],
+ float out[3])
{
- float vec[3], factor, norm[3];
- add_v3_v3v3(vec, in, t->center_global);
- view_vector_calc(t, vec, norm);
+ float pos[3], view_vec[3], factor;
- sub_v3_v3v3(vec, out, in);
+ add_v3_v3v3(pos, in, t->center_global);
+ view_vector_calc(t, pos, view_vec);
- factor = dot_v3v3(vec, norm);
- if (factor == 0.0f) {
- return; /* prevent divide by zero */
+ if (isect_ray_plane_v3(pos, view_vec, plane, &factor, false)) {
+ madd_v3_v3v3fl(out, in, view_vec, factor);
}
- factor = dot_v3v3(vec, vec) / factor;
-
- copy_v3_v3(vec, norm);
- mul_v3_fl(vec, factor);
-
- add_v3_v3v3(out, in, vec);
}
static short transform_orientation_or_default(const TransInfo *t)
@@ -397,7 +392,6 @@ static void applyAxisConstraintVec(const TransInfo *t,
copy_v3_v3(out, in);
if (!td && t->con.mode & CON_APPLY) {
bool is_snap_to_point = false, is_snap_to_edge = false, is_snap_to_face = false;
- mul_m3_v3(t->con.pmtx, out);
if (activeSnap(t)) {
if (validSnap(t)) {
@@ -410,8 +404,13 @@ static void applyAxisConstraintVec(const TransInfo *t,
}
}
- /* With snap points, a projection is alright, no adjustments needed. */
- if (!is_snap_to_point || is_snap_to_edge || is_snap_to_face) {
+ /* Fallback for when axes are aligned. */
+ mul_m3_v3(t->con.pmtx, out);
+
+ if (is_snap_to_point) {
+ /* Pass. With snap points, a projection is alright, no adjustments needed. */
+ }
+ else {
const int dims = getConstraintSpaceDimension(t);
if (dims == 2) {
if (!is_zero_v3(out)) {
@@ -425,11 +424,9 @@ static void applyAxisConstraintVec(const TransInfo *t,
/* Disabled, as it has not proven to be really useful. (See T82386). */
// constraint_snap_plane_to_face(t, plane, out);
}
- else {
+ else if (!isPlaneProjectionViewAligned(t, plane)) {
/* View alignment correction. */
- if (!isPlaneProjectionViewAligned(t, plane)) {
- planeProjection(t, in, out);
- }
+ planeProjection(t, plane, in, out);
}
}
}
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c
index 63dcf6c0989..a5b2442f11c 100644
--- a/source/blender/editors/transform/transform_convert.c
+++ b/source/blender/editors/transform/transform_convert.c
@@ -945,7 +945,11 @@ static void init_TransDataContainers(TransInfo *t,
/* Pose transform operates on `ob->pose` so don't skip duplicate object-data. */
params.no_dup_data = (object_mode & OB_MODE_POSE) == 0;
objects = BKE_view_layer_array_from_objects_in_mode_params(
- t->view_layer, (t->spacetype == SPACE_VIEW3D) ? t->view : NULL, &objects_len, &params);
+ t->scene,
+ t->view_layer,
+ (t->spacetype == SPACE_VIEW3D) ? t->view : NULL,
+ &objects_len,
+ &params);
free_objects = true;
}
@@ -977,7 +981,7 @@ static void init_TransDataContainers(TransInfo *t,
if (tc->use_local_mat) {
BLI_assert((t->flag & T_2D_EDIT) == 0);
- copy_m4_m4(tc->mat, objects[i]->obmat);
+ copy_m4_m4(tc->mat, objects[i]->object_to_world);
copy_m3_m4(tc->mat3, tc->mat);
/* for non-invertible scale matrices, invert_m4_m4_fallback()
* can still provide a valid pivot */
@@ -997,6 +1001,7 @@ static void init_TransDataContainers(TransInfo *t,
static TransConvertTypeInfo *convert_type_get(const TransInfo *t, Object **r_obj_armature)
{
ViewLayer *view_layer = t->view_layer;
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
/* if tests must match recalcData for correct updates */
@@ -1110,11 +1115,11 @@ static TransConvertTypeInfo *convert_type_get(const TransInfo *t, Object **r_obj
}
return NULL;
}
- if ((ob) && (ELEM(ob->mode,
- OB_MODE_PAINT_GPENCIL,
- OB_MODE_SCULPT_GPENCIL,
- OB_MODE_WEIGHT_GPENCIL,
- OB_MODE_VERTEX_GPENCIL))) {
+ if (ob && ELEM(ob->mode,
+ OB_MODE_PAINT_GPENCIL,
+ OB_MODE_SCULPT_GPENCIL,
+ OB_MODE_WEIGHT_GPENCIL,
+ OB_MODE_VERTEX_GPENCIL)) {
/* In grease pencil all transformations must be canceled if not Object or Edit. */
return NULL;
}
@@ -1140,8 +1145,8 @@ void createTransData(bContext *C, TransInfo *t)
init_TransDataContainers(t, ob_armature, &ob_armature, 1);
}
else {
- ViewLayer *view_layer = t->view_layer;
- Object *ob = BKE_view_layer_active_object_get(view_layer);
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
+ Object *ob = BKE_view_layer_active_object_get(t->view_layer);
init_TransDataContainers(t, ob, NULL, 0);
}
@@ -1230,8 +1235,8 @@ void transform_convert_clip_mirror_modifier_apply(TransDataContainer *tc)
if (mmd->mirror_ob) {
float obinv[4][4];
- invert_m4_m4(obinv, mmd->mirror_ob->obmat);
- mul_m4_m4m4(mtx, obinv, ob->obmat);
+ invert_m4_m4(obinv, mmd->mirror_ob->object_to_world);
+ mul_m4_m4m4(mtx, obinv, ob->object_to_world);
invert_m4_m4(imtx, mtx);
}
diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h
index f32bff6dcff..4798d666d70 100644
--- a/source/blender/editors/transform/transform_convert.h
+++ b/source/blender/editors/transform/transform_convert.h
@@ -10,6 +10,10 @@
#include "RE_engine.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct BMEditMesh;
struct BMesh;
struct BezTriple;
@@ -222,8 +226,6 @@ void transform_convert_mesh_crazyspace_transdata_set(const float mtx[3][3],
struct TransData *r_td);
void transform_convert_mesh_crazyspace_free(struct TransMeshDataCrazySpace *r_crazyspace_data);
-void special_aftertrans_update__mesh(bContext *C, TransInfo *t);
-
/* transform_convert_mesh_edge.c */
extern TransConvertTypeInfo TransConvertType_MeshEdge;
@@ -244,7 +246,7 @@ extern TransConvertTypeInfo TransConvertType_MeshVertCData;
extern TransConvertTypeInfo TransConvertType_NLA;
-/* transform_convert_node.c */
+/* transform_convert_node.cc */
extern TransConvertTypeInfo TransConvertType_Node;
@@ -279,3 +281,7 @@ extern TransConvertTypeInfo TransConvertType_SequencerImage;
/* transform_convert_tracking.c */
extern TransConvertTypeInfo TransConvertType_Tracking;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/editors/transform/transform_convert_action.c b/source/blender/editors/transform/transform_convert_action.c
index 83e47d9acc0..8c6f2baf84a 100644
--- a/source/blender/editors/transform/transform_convert_action.c
+++ b/source/blender/editors/transform/transform_convert_action.c
@@ -576,6 +576,8 @@ static void recalcData_actedit(TransInfo *t)
bAnimListElem *ale;
int filter;
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
+
/* initialize relevant anim-context 'context' data from TransInfo data */
/* NOTE: sync this with the code in ANIM_animdata_get_context() */
ac.bmain = CTX_data_main(t->context);
diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c
index d83cca15219..2e37f6b7c34 100644
--- a/source/blender/editors/transform/transform_convert_armature.c
+++ b/source/blender/editors/transform/transform_convert_armature.c
@@ -306,8 +306,9 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan)
* just make things obey standard rotation locks too */
if (data->rootbone == 0) {
for (bPoseChannel *pchan_iter = pchan; pchan_iter; pchan_iter = pchan_iter->parent) {
- /* here, we set ik-settings for bone from pchan->protectflag */
- /* XXX: careful with quats/axis-angle rotations where we're locking 4d components. */
+ /* Here, we set IK-settings for bone from `pchan->protectflag`. */
+ /* XXX: careful with quaternion/axis-angle rotations
+ * where we're locking 4d components. */
if (pchan_iter->protectflag & OB_LOCK_ROTX) {
pchan_iter->ikflag |= BONE_IK_NO_XDOF_TEMP;
}
@@ -592,7 +593,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
td->ext->rotOrder = pchan->rotmode;
/* proper way to get parent transform + own transform + constraints transform */
- copy_m3_m4(omat, ob->obmat);
+ copy_m3_m4(omat, ob->object_to_world);
/* New code, using "generic" BKE_bone_parent_transform_calc_from_pchan(). */
{
@@ -954,7 +955,7 @@ static void createTransArmatureVerts(bContext *UNUSED(C), TransInfo *t)
bool mirror = ((arm->flag & ARM_MIRROR_EDIT) != 0);
BoneInitData *bid = tc->custom.type.data;
- copy_m3_m4(mtx, tc->obedit->obmat);
+ copy_m3_m4(mtx, tc->obedit->object_to_world);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransEditBone");
@@ -1506,7 +1507,7 @@ static void bone_children_clear_transflag(int mode, short around, ListBase *lb)
if ((bone->flag & BONE_HINGE) && (bone->flag & BONE_CONNECTED)) {
bone->flag |= BONE_HINGE_CHILD_TRANSFORM;
}
- else if ((bone->flag & BONE_TRANSFORM) && (ELEM(mode, TFM_ROTATION, TFM_TRACKBALL)) &&
+ else if ((bone->flag & BONE_TRANSFORM) && ELEM(mode, TFM_ROTATION, TFM_TRACKBALL) &&
(around == V3D_AROUND_LOCAL_ORIGINS)) {
bone->flag |= BONE_TRANSFORM_CHILD;
}
diff --git a/source/blender/editors/transform/transform_convert_curve.c b/source/blender/editors/transform/transform_convert_curve.c
index 404b1293208..13ba28ec3d0 100644
--- a/source/blender/editors/transform/transform_convert_curve.c
+++ b/source/blender/editors/transform/transform_convert_curve.c
@@ -174,7 +174,7 @@ static void createTransCurveVerts(bContext *UNUSED(C), TransInfo *t)
transform_mode_use_local_origins(t));
float mtx[3][3], smtx[3][3];
- copy_m3_m4(mtx, tc->obedit->obmat);
+ copy_m3_m4(mtx, tc->obedit->object_to_world);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
TransData *td = tc->data;
diff --git a/source/blender/editors/transform/transform_convert_gpencil.c b/source/blender/editors/transform/transform_convert_gpencil.c
index 5056b30f77f..8c23f3c2b96 100644
--- a/source/blender/editors/transform/transform_convert_gpencil.c
+++ b/source/blender/editors/transform/transform_convert_gpencil.c
@@ -682,6 +682,7 @@ static void createTransGPencil(bContext *C, TransInfo *t)
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
const Scene *scene = CTX_data_scene(C);
ToolSettings *ts = scene->toolsettings;
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
Object *obact = BKE_view_layer_active_object_get(t->view_layer);
bGPdata *gpd = obact->data;
BLI_assert(gpd != NULL);
@@ -749,7 +750,7 @@ static void recalcData_gpencil_strokes(TransInfo *t)
for (int i = 0; i < tc->data_len; i++, td++) {
bGPDstroke *gps = td->extra;
- if ((gps != NULL) && (!BLI_ghash_haskey(strokes, gps))) {
+ if ((gps != NULL) && !BLI_ghash_haskey(strokes, gps)) {
BLI_ghash_insert(strokes, gps, gps);
if (is_curve_edit && gps->editcurve != NULL) {
BKE_gpencil_editcurve_recalculate_handles(gps);
diff --git a/source/blender/editors/transform/transform_convert_graph.c b/source/blender/editors/transform/transform_convert_graph.c
index fad192d54db..27e6c8a25e1 100644
--- a/source/blender/editors/transform/transform_convert_graph.c
+++ b/source/blender/editors/transform/transform_convert_graph.c
@@ -639,7 +639,7 @@ static bool fcu_test_selected(FCurve *fcu)
return 0;
}
-/* this function is called on recalcData to apply the transforms applied
+/* This function is called on recalcData to apply the transforms applied
* to the transdata on to the actual keyframe data
*/
static void flushTransGraphData(TransInfo *t)
@@ -908,6 +908,8 @@ static void recalcData_graphedit(TransInfo *t)
bAnimListElem *ale;
int dosort = 0;
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
+
/* initialize relevant anim-context 'context' data from TransInfo data */
/* NOTE: sync this with the code in ANIM_animdata_get_context() */
ac.bmain = CTX_data_main(t->context);
diff --git a/source/blender/editors/transform/transform_convert_lattice.c b/source/blender/editors/transform/transform_convert_lattice.c
index b77538dc249..e9b3401974b 100644
--- a/source/blender/editors/transform/transform_convert_lattice.c
+++ b/source/blender/editors/transform/transform_convert_lattice.c
@@ -66,7 +66,7 @@ static void createTransLatticeVerts(bContext *UNUSED(C), TransInfo *t)
}
tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Lattice EditMode)");
- copy_m3_m4(mtx, tc->obedit->obmat);
+ copy_m3_m4(mtx, tc->obedit->object_to_world);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
td = tc->data;
diff --git a/source/blender/editors/transform/transform_convert_mball.c b/source/blender/editors/transform/transform_convert_mball.c
index 7ae93524d0b..c90052e9e8c 100644
--- a/source/blender/editors/transform/transform_convert_mball.c
+++ b/source/blender/editors/transform/transform_convert_mball.c
@@ -61,7 +61,7 @@ static void createTransMBallVerts(bContext *UNUSED(C), TransInfo *t)
tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension),
"MetaElement_TransExtension");
- copy_m3_m4(mtx, tc->obedit->obmat);
+ copy_m3_m4(mtx, tc->obedit->object_to_world);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
for (ml = mb->editelems->first; ml; ml = ml->next) {
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index f67a44703e5..3192b1b6786 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -1423,8 +1423,7 @@ static void VertsToTransData(TransInfo *t,
copy_v3_v3(td->iloc, td->loc);
if ((t->mode == TFM_SHRINKFATTEN) && (em->selectmode & SCE_SELECT_FACE) &&
- BM_elem_flag_test(eve, BM_ELEM_SELECT) &&
- (BM_vert_calc_normal_ex(eve, BM_ELEM_SELECT, _no))) {
+ BM_elem_flag_test(eve, BM_ELEM_SELECT) && BM_vert_calc_normal_ex(eve, BM_ELEM_SELECT, _no)) {
no = _no;
}
else {
@@ -1528,7 +1527,7 @@ static void createTransEditVerts(bContext *UNUSED(C), TransInfo *t)
em, calc_single_islands, calc_island_center, calc_island_axismtx, &island_data);
}
- copy_m3_m4(mtx, tc->obedit->obmat);
+ copy_m3_m4(mtx, tc->obedit->object_to_world);
/* we use a pseudo-inverse so that when one of the axes is scaled to 0,
* matrix inversion still works and we can still moving along the other */
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
@@ -2069,7 +2068,7 @@ static void recalcData_mesh(TransInfo *t)
/** \name Special After Transform Mesh
* \{ */
-void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t)
+static void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t)
{
const bool is_canceling = (t->state == TRANS_CANCEL);
const bool use_automerge = !is_canceling && (t->flag & (T_AUTOMERGE | T_AUTOSPLIT)) != 0;
diff --git a/source/blender/editors/transform/transform_convert_mesh_edge.c b/source/blender/editors/transform/transform_convert_mesh_edge.c
index b1627e62f8c..fd62b199345 100644
--- a/source/blender/editors/transform/transform_convert_mesh_edge.c
+++ b/source/blender/editors/transform/transform_convert_mesh_edge.c
@@ -62,7 +62,7 @@ static void createTransEdge(bContext *UNUSED(C), TransInfo *t)
td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransCrease");
- copy_m3_m4(mtx, tc->obedit->obmat);
+ copy_m3_m4(mtx, tc->obedit->object_to_world);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
/* create data we need */
@@ -74,7 +74,9 @@ static void createTransEdge(bContext *UNUSED(C), TransInfo *t)
}
else { /* if (t->mode == TFM_EDGE_CREASE) { */
BLI_assert(t->mode == TFM_EDGE_CREASE);
- BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_CREASE);
+ if (!CustomData_has_layer(&em->bm->edata, CD_CREASE)) {
+ BM_data_layer_add(em->bm, &em->bm->edata, CD_CREASE);
+ }
cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE);
}
@@ -123,5 +125,5 @@ TransConvertTypeInfo TransConvertType_MeshEdge = {
/* flags */ T_EDIT,
/* createTransData */ createTransEdge,
/* recalcData */ recalcData_mesh_edge,
- /* special_aftertrans_update */ special_aftertrans_update__mesh,
+ /* special_aftertrans_update */ NULL,
};
diff --git a/source/blender/editors/transform/transform_convert_mesh_skin.c b/source/blender/editors/transform/transform_convert_mesh_skin.c
index 376e559181e..cb6108a4c45 100644
--- a/source/blender/editors/transform/transform_convert_mesh_skin.c
+++ b/source/blender/editors/transform/transform_convert_mesh_skin.c
@@ -130,7 +130,7 @@ static void createTransMeshSkin(bContext *UNUSED(C), TransInfo *t)
em, calc_single_islands, calc_island_center, calc_island_axismtx, &island_data);
}
- copy_m3_m4(mtx, tc->obedit->obmat);
+ copy_m3_m4(mtx, tc->obedit->object_to_world);
/* we use a pseudo-inverse so that when one of the axes is scaled to 0,
* matrix inversion still works and we can still moving along the other */
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
diff --git a/source/blender/editors/transform/transform_convert_mesh_uv.c b/source/blender/editors/transform/transform_convert_mesh_uv.c
index 27f12137e3a..4f15fc240d3 100644
--- a/source/blender/editors/transform/transform_convert_mesh_uv.c
+++ b/source/blender/editors/transform/transform_convert_mesh_uv.c
@@ -74,8 +74,12 @@ static void UVsToTransData(const float aspect[2],
/**
* \param dists: Store the closest connected distance to selected vertices.
*/
-static void uv_set_connectivity_distance(BMesh *bm, float *dists, const float aspect[2])
+static void uv_set_connectivity_distance(const ToolSettings *ts,
+ BMesh *bm,
+ float *dists,
+ const float aspect[2])
{
+#define TMP_LOOP_SELECT_TAG BM_ELEM_TAG_ALT
/* Mostly copied from #transform_convert_mesh_connectivity_distance. */
BLI_LINKSTACK_DECLARE(queue, BMLoop *);
@@ -101,15 +105,15 @@ static void uv_set_connectivity_distance(BMesh *bm, float *dists, const float as
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
float dist;
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
-
- bool uv_vert_sel = luv->flag & MLOOPUV_VERTSEL;
+ bool uv_vert_sel = uvedit_uv_select_test_ex(ts, l, cd_loop_uv_offset);
if (uv_vert_sel) {
BLI_LINKSTACK_PUSH(queue, l);
+ BM_elem_flag_enable(l, TMP_LOOP_SELECT_TAG);
dist = 0.0f;
}
else {
+ BM_elem_flag_disable(l, TMP_LOOP_SELECT_TAG);
dist = FLT_MAX;
}
@@ -164,7 +168,7 @@ static void uv_set_connectivity_distance(BMesh *bm, float *dists, const float as
bool other_vert_sel, connected_vert_sel;
- other_vert_sel = luv_other->flag & MLOOPUV_VERTSEL;
+ other_vert_sel = BM_elem_flag_test_bool(l_other, TMP_LOOP_SELECT_TAG);
BM_ITER_ELEM (l_connected, &l_connected_iter, l_other->v, BM_LOOPS_OF_VERT) {
if (l_connected == l_other) {
@@ -176,7 +180,7 @@ static void uv_set_connectivity_distance(BMesh *bm, float *dists, const float as
}
MLoopUV *luv_connected = BM_ELEM_CD_GET_VOID_P(l_connected, cd_loop_uv_offset);
- connected_vert_sel = luv_connected->flag & MLOOPUV_VERTSEL;
+ connected_vert_sel = BM_elem_flag_test_bool(l_connected, TMP_LOOP_SELECT_TAG);
/* Check if this loop is connected in UV space.
* If the uv loops share the same selection state (if not, they are not connected as
@@ -232,6 +236,7 @@ static void uv_set_connectivity_distance(BMesh *bm, float *dists, const float as
BLI_LINKSTACK_FREE(queue_next);
MEM_freeN(dists_prev);
+#undef TMP_LOOP_SELECT_TAG
}
static void createTransUVs(bContext *C, TransInfo *t)
@@ -337,7 +342,7 @@ static void createTransUVs(bContext *C, TransInfo *t)
if (is_prop_connected) {
prop_dists = MEM_callocN(em->bm->totloop * sizeof(float), "TransObPropDists(UV Editing)");
- uv_set_connectivity_distance(em->bm, prop_dists, t->aspect);
+ uv_set_connectivity_distance(t->settings, em->bm, prop_dists, t->aspect);
}
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -399,8 +404,8 @@ static void createTransUVs(bContext *C, TransInfo *t)
static void flushTransUVs(TransInfo *t)
{
SpaceImage *sima = t->area->spacedata.first;
- const bool use_pixel_snap = ((sima->pixel_snap_mode != SI_PIXEL_SNAP_DISABLED) &&
- (t->state != TRANS_CANCEL));
+ const bool use_pixel_round = ((sima->pixel_round_mode != SI_PIXEL_ROUND_DISABLED) &&
+ (t->state != TRANS_CANCEL));
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData2D *td;
@@ -410,7 +415,7 @@ static void flushTransUVs(TransInfo *t)
aspect_inv[0] = 1.0f / t->aspect[0];
aspect_inv[1] = 1.0f / t->aspect[1];
- if (use_pixel_snap) {
+ if (use_pixel_round) {
int size_i[2];
ED_space_image_get_size(sima, &size_i[0], &size_i[1]);
size[0] = size_i[0];
@@ -422,16 +427,16 @@ static void flushTransUVs(TransInfo *t)
td->loc2d[0] = td->loc[0] * aspect_inv[0];
td->loc2d[1] = td->loc[1] * aspect_inv[1];
- if (use_pixel_snap) {
+ if (use_pixel_round) {
td->loc2d[0] *= size[0];
td->loc2d[1] *= size[1];
- switch (sima->pixel_snap_mode) {
- case SI_PIXEL_SNAP_CENTER:
+ switch (sima->pixel_round_mode) {
+ case SI_PIXEL_ROUND_CENTER:
td->loc2d[0] = roundf(td->loc2d[0] - 0.5f) + 0.5f;
td->loc2d[1] = roundf(td->loc2d[1] - 0.5f) + 0.5f;
break;
- case SI_PIXEL_SNAP_CORNER:
+ case SI_PIXEL_ROUND_CORNER:
td->loc2d[0] = roundf(td->loc2d[0]);
td->loc2d[1] = roundf(td->loc2d[1]);
break;
diff --git a/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c b/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c
index 39705f87a0d..d253261f458 100644
--- a/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c
+++ b/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c
@@ -90,7 +90,9 @@ static void createTransMeshVertCData(bContext *UNUSED(C), TransInfo *t)
cd_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
}
else {
- BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_VERT_CREASE);
+ if (!CustomData_has_layer(&bm->vdata, CD_CREASE)) {
+ BM_data_layer_add(bm, &bm->vdata, CD_CREASE);
+ }
cd_offset = CustomData_get_offset(&bm->vdata, CD_CREASE);
}
@@ -129,7 +131,7 @@ static void createTransMeshVertCData(bContext *UNUSED(C), TransInfo *t)
em, calc_single_islands, calc_island_center, calc_island_axismtx, &island_data);
}
- copy_m3_m4(mtx, tc->obedit->obmat);
+ copy_m3_m4(mtx, tc->obedit->object_to_world);
/* we use a pseudo-inverse so that when one of the axes is scaled to 0,
* matrix inversion still works and we can still moving along the other */
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
diff --git a/source/blender/editors/transform/transform_convert_nla.c b/source/blender/editors/transform/transform_convert_nla.c
index cfa933d1600..830094ebe83 100644
--- a/source/blender/editors/transform/transform_convert_nla.c
+++ b/source/blender/editors/transform/transform_convert_nla.c
@@ -56,6 +56,29 @@ typedef struct TransDataNla {
} TransDataNla;
/* -------------------------------------------------------------------- */
+/** \name Transform application to NLA strips
+ * \{ */
+
+/**
+ * \brief Applies a translation to the given #NlaStrip.
+ * \param strip_rna_ptr: The RNA pointer of the NLA strip to modify.
+ * \param transdata: The transformation info structure.
+ */
+static void applyTransformNLA_translation(PointerRNA *strip_rna_ptr, const TransDataNla *transdata)
+{
+ /* NOTE: we write these twice to avoid truncation errors which can arise when
+ * moving the strips a large distance using numeric input T33852.
+ */
+ RNA_float_set(strip_rna_ptr, "frame_start", transdata->h1[0]);
+ RNA_float_set(strip_rna_ptr, "frame_end", transdata->h2[0]);
+
+ RNA_float_set(strip_rna_ptr, "frame_start", transdata->h1[0]);
+ RNA_float_set(strip_rna_ptr, "frame_end", transdata->h2[0]);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name NLA Transform Creation
* \{ */
@@ -329,15 +352,8 @@ static void recalcData_nla(TransInfo *t)
*
* this is done as a iterative procedure (done 5 times max for now)
*/
- NlaStrip *prev = strip->prev;
- while (prev != NULL && (prev->type & NLASTRIP_TYPE_TRANSITION)) {
- prev = prev->prev;
- }
-
- NlaStrip *next = strip->next;
- while (next != NULL && (next->type & NLASTRIP_TYPE_TRANSITION)) {
- next = next->next;
- }
+ NlaStrip *prev = BKE_nlastrip_prev_in_track(strip, true);
+ NlaStrip *next = BKE_nlastrip_next_in_track(strip, true);
for (short iter = 0; iter < 5; iter++) {
const bool pExceeded = (prev != NULL) && (tdn->h1[0] < prev->end);
@@ -380,17 +396,10 @@ static void recalcData_nla(TransInfo *t)
/* Use RNA to write the values to ensure that constraints on these are obeyed
* (e.g. for transition strips, the values are taken from the neighbors)
- *
- * NOTE: we write these twice to avoid truncation errors which can arise when
- * moving the strips a large distance using numeric input T33852.
*/
RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
- RNA_float_set(&strip_ptr, "frame_start", tdn->h1[0]);
- RNA_float_set(&strip_ptr, "frame_end", tdn->h2[0]);
-
- RNA_float_set(&strip_ptr, "frame_start", tdn->h1[0]);
- RNA_float_set(&strip_ptr, "frame_end", tdn->h2[0]);
+ applyTransformNLA_translation(&strip_ptr, tdn);
/* flush transforms to child strips (since this should be a meta) */
BKE_nlameta_flush_transforms(strip);
diff --git a/source/blender/editors/transform/transform_convert_node.c b/source/blender/editors/transform/transform_convert_node.cc
index ed19789fdd8..6ab0e1fe701 100644
--- a/source/blender/editors/transform/transform_convert_node.c
+++ b/source/blender/editors/transform/transform_convert_node.cc
@@ -96,13 +96,13 @@ static bool is_node_parent_select(bNode *node)
return false;
}
-static void createTransNodeData(bContext *UNUSED(C), TransInfo *t)
+static void createTransNodeData(bContext * /*C*/, TransInfo *t)
{
const float dpi_fac = UI_DPI_FAC;
- SpaceNode *snode = t->area->spacedata.first;
+ SpaceNode *snode = static_cast<SpaceNode *>(t->area->spacedata.first);
/* Custom data to enable edge panning during the node transform */
- struct TransCustomDataNode *customdata = MEM_callocN(sizeof(*customdata), __func__);
+ TransCustomDataNode *customdata = MEM_cnew<TransCustomDataNode>(__func__);
UI_view2d_edge_pan_init(t->context,
&customdata->edgepan_data,
NODE_EDGE_PAN_INSIDE_PAD,
@@ -125,7 +125,7 @@ static void createTransNodeData(bContext *UNUSED(C), TransInfo *t)
}
/* Nodes don't support PET and probably never will. */
- t->flag &= ~T_PROP_EDIT_ALL;
+ t->flag = t->flag & ~T_PROP_EDIT_ALL;
/* set transform flags on nodes */
LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
@@ -142,9 +142,8 @@ static void createTransNodeData(bContext *UNUSED(C), TransInfo *t)
return;
}
- TransData *td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransNode TransData");
- TransData2D *td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D),
- "TransNode TransData2D");
+ TransData *td = tc->data = MEM_cnew_array<TransData>(tc->data_len, __func__);
+ TransData2D *td2d = tc->data_2d = MEM_cnew_array<TransData2D>(tc->data_len, __func__);
LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
if (node->flag & NODE_TRANSFORM) {
@@ -156,14 +155,59 @@ static void createTransNodeData(bContext *UNUSED(C), TransInfo *t)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Node Transform Creation
+/** \name Flush Transform Nodes
* \{ */
+static void node_snap_grid_apply(TransInfo *t)
+{
+ int i;
+
+ if (!(activeSnap(t) && (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) {
+ return;
+ }
+
+ float grid_size[2];
+ copy_v2_v2(grid_size, t->snap_spatial);
+ if (t->modifiers & MOD_PRECISION) {
+ mul_v2_fl(grid_size, t->snap_spatial_precision);
+ }
+
+ /* Early exit on unusable grid size. */
+ if (is_zero_v2(grid_size)) {
+ return;
+ }
+
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ TransData *td;
+
+ for (i = 0, td = tc->data; i < tc->data_len; i++, td++) {
+ float iloc[2], loc[2], tvec[2];
+ if (td->flag & TD_SKIP) {
+ continue;
+ }
+
+ if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f)) {
+ continue;
+ }
+
+ copy_v2_v2(iloc, td->loc);
+
+ loc[0] = roundf(iloc[0] / grid_size[0]) * grid_size[0];
+ loc[1] = roundf(iloc[1] / grid_size[1]) * grid_size[1];
+
+ sub_v2_v2v2(tvec, loc, iloc);
+ add_v2_v2(td->loc, tvec);
+ }
+ }
+}
+
static void flushTransNodes(TransInfo *t)
{
+ using namespace blender::ed;
const float dpi_fac = UI_DPI_FAC;
+ SpaceNode *snode = static_cast<SpaceNode *>(t->area->spacedata.first);
- struct TransCustomDataNode *customdata = (struct TransCustomDataNode *)t->custom.type.data;
+ TransCustomDataNode *customdata = (TransCustomDataNode *)t->custom.type.data;
if (t->options & CTX_VIEW2D_EDGE_PAN) {
if (t->state == TRANS_CANCEL) {
@@ -190,13 +234,13 @@ static void flushTransNodes(TransInfo *t)
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- applyGridAbsolute(t);
+ node_snap_grid_apply(t);
/* flush to 2d vector from internally used 3d vector */
for (int i = 0; i < tc->data_len; i++) {
TransData *td = &tc->data[i];
TransData2D *td2d = &tc->data_2d[i];
- bNode *node = td->extra;
+ bNode *node = static_cast<bNode *>(td->extra);
float loc[2];
add_v2_v2v2(loc, td2d->loc, offset);
@@ -221,7 +265,7 @@ static void flushTransNodes(TransInfo *t)
/* handle intersection with noodles */
if (tc->data_len == 1) {
- ED_node_link_intersect_test(t->area, 1);
+ space_node::node_insert_on_link_flags_set(*snode, *t->region);
}
}
}
@@ -234,13 +278,15 @@ static void flushTransNodes(TransInfo *t)
static void special_aftertrans_update__node(bContext *C, TransInfo *t)
{
- struct Main *bmain = CTX_data_main(C);
+ using namespace blender::ed;
+ Main *bmain = CTX_data_main(C);
+ SpaceNode *snode = (SpaceNode *)t->area->spacedata.first;
+ bNodeTree *ntree = snode->edittree;
+
const bool canceled = (t->state == TRANS_CANCEL);
- SpaceNode *snode = (SpaceNode *)t->area->spacedata.first;
if (canceled && t->remove_on_cancel) {
/* remove selected nodes on cancel */
- bNodeTree *ntree = snode->edittree;
if (ntree) {
LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) {
if (node->flag & NODE_SELECT) {
@@ -253,11 +299,10 @@ static void special_aftertrans_update__node(bContext *C, TransInfo *t)
if (!canceled) {
ED_node_post_apply_transform(C, snode->edittree);
- ED_node_link_insert(bmain, t->area);
+ space_node::node_insert_on_link_flags(*bmain, *snode);
}
- /* clear link line */
- ED_node_link_intersect_test(t->area, 0);
+ space_node::node_insert_on_link_flags_clear(*ntree);
}
/** \} */
diff --git a/source/blender/editors/transform/transform_convert_object.c b/source/blender/editors/transform/transform_convert_object.c
index 15ba307ab30..55f7cd9b23d 100644
--- a/source/blender/editors/transform/transform_convert_object.c
+++ b/source/blender/editors/transform/transform_convert_object.c
@@ -158,14 +158,14 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
copy_qt_qt(td->ext->oquat, ob->quat);
}
/* update object's loc/rot to get current rigid body transform */
- mat4_to_loc_rot_size(ob->loc, rot, scale, ob->obmat);
+ mat4_to_loc_rot_size(ob->loc, rot, scale, ob->object_to_world);
sub_v3_v3(ob->loc, ob->dloc);
BKE_object_mat3_to_rot(ob, rot, false); /* drot is already corrected here */
}
}
/* axismtx has the real orientation */
- transform_orientations_create_from_axis(td->axismtx, UNPACK3(ob->obmat));
+ transform_orientations_create_from_axis(td->axismtx, UNPACK3(ob->object_to_world));
if (t->orient_type_mask & (1 << V3D_ORIENT_GIMBAL)) {
if (!gimbal_axis_object(ob, td->ext->axismtx_gimbal)) {
copy_m3_m3(td->ext->axismtx_gimbal, td->axismtx);
@@ -192,7 +192,7 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
* More proper solution would be to make a shallow copy of the object and
* evaluate that, and access matrix of that evaluated copy of the object.
* Might be more tricky than it sounds, if some logic later on accesses the
- * object matrix via td->ob->obmat. */
+ * object matrix via td->ob->object_to_world. */
Object *object_eval = DEG_get_evaluated_object(t->depsgraph, ob);
if (skip_invert == false && constinv == false) {
object_eval->transflag |= OB_NO_CONSTRAINTS; /* BKE_object_where_is_calc checks this */
@@ -208,7 +208,7 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
}
/* Copy newly evaluated fields to the original object, similar to how
* active dependency graph will do it. */
- copy_m4_m4(ob->obmat, object_eval->obmat);
+ copy_m4_m4(ob->object_to_world, object_eval->object_to_world);
/* Only copy negative scale flag, this is the only flag which is modified by
* the BKE_object_where_is_calc(). The rest of the flags we need to keep,
* otherwise we might lose dupli flags (see T61787). */
@@ -258,9 +258,9 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
copy_v3_v3(td->ext->isize, ob->scale);
copy_v3_v3(td->ext->dscale, ob->dscale);
- copy_v3_v3(td->center, ob->obmat[3]);
+ copy_v3_v3(td->center, ob->object_to_world[3]);
- copy_m4_m4(td->ext->obmat, ob->obmat);
+ copy_m4_m4(td->ext->obmat, ob->object_to_world);
/* is there a need to set the global<->data space conversion matrices? */
if (ob->parent || constinv) {
@@ -271,7 +271,7 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
* done, as it doesn't work well.
*/
BKE_object_to_mat3(ob, obmtx);
- copy_m3_m4(totmat, ob->obmat);
+ copy_m3_m4(totmat, ob->object_to_world);
/* If the object scale is zero on any axis, this might result in a zero matrix.
* In this case, the transformation would not do anything, see: T50103. */
@@ -291,9 +291,10 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
}
}
-static void trans_object_base_deps_flag_prepare(ViewLayer *view_layer)
+static void trans_object_base_deps_flag_prepare(const Scene *scene, ViewLayer *view_layer)
{
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
base->object->id.tag &= ~LIB_TAG_DOIT;
}
}
@@ -323,11 +324,14 @@ static void flush_trans_object_base_deps_flag(Depsgraph *depsgraph, Object *obje
NULL);
}
-static void trans_object_base_deps_flag_finish(const TransInfo *t, ViewLayer *view_layer)
+static void trans_object_base_deps_flag_finish(const TransInfo *t,
+ const Scene *scene,
+ ViewLayer *view_layer)
{
if ((t->options & CTX_OBMODE_XFORM_OBDATA) == 0) {
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (base->object->id.tag & LIB_TAG_DOIT) {
base->flag_legacy |= BA_SNAP_FIX_DEPS_FIASCO;
}
@@ -352,13 +356,14 @@ static void set_trans_object_base_flags(TransInfo *t)
return;
}
/* Makes sure base flags and object flags are identical. */
- BKE_scene_base_flag_to_objects(t->view_layer);
+ BKE_scene_base_flag_to_objects(t->scene, t->view_layer);
/* Make sure depsgraph is here. */
DEG_graph_relations_update(depsgraph);
/* Clear all flags we need. It will be used to detect dependencies. */
- trans_object_base_deps_flag_prepare(view_layer);
+ trans_object_base_deps_flag_prepare(scene, view_layer);
/* Traverse all bases and set all possible flags. */
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
base->flag_legacy &= ~(BA_WAS_SEL | BA_TRANSFORM_LOCKED_IN_PLACE);
if (BASE_SELECTED_EDITABLE(v3d, base)) {
Object *ob = base->object;
@@ -378,7 +383,7 @@ static void set_trans_object_base_flags(TransInfo *t)
if (parsel != NULL) {
/* Rotation around local centers are allowed to propagate. */
if ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
- (ELEM(t->mode, TFM_ROTATION, TFM_TRACKBALL))) {
+ ELEM(t->mode, TFM_ROTATION, TFM_TRACKBALL)) {
base->flag_legacy |= BA_TRANSFORM_CHILD;
}
else {
@@ -392,7 +397,7 @@ static void set_trans_object_base_flags(TransInfo *t)
/* Store temporary bits in base indicating that base is being modified
* (directly or indirectly) by transforming objects.
*/
- trans_object_base_deps_flag_finish(t, view_layer);
+ trans_object_base_deps_flag_finish(t, scene, view_layer);
}
static bool mark_children(Object *ob)
@@ -420,11 +425,11 @@ static int count_proportional_objects(TransInfo *t)
Scene *scene = t->scene;
Depsgraph *depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, view_layer);
/* Clear all flags we need. It will be used to detect dependencies. */
- trans_object_base_deps_flag_prepare(view_layer);
+ trans_object_base_deps_flag_prepare(scene, view_layer);
/* Rotations around local centers are allowed to propagate, so we take all objects. */
- if (!((t->around == V3D_AROUND_LOCAL_ORIGINS) && (ELEM(t->mode, TFM_ROTATION, TFM_TRACKBALL)))) {
+ if (!((t->around == V3D_AROUND_LOCAL_ORIGINS) && ELEM(t->mode, TFM_ROTATION, TFM_TRACKBALL))) {
/* Mark all parents. */
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (BASE_SELECTED_EDITABLE(v3d, base) && BASE_SELECTABLE(v3d, base)) {
Object *parent = base->object->parent;
/* flag all parents */
@@ -435,7 +440,7 @@ static int count_proportional_objects(TransInfo *t)
}
}
/* Mark all children. */
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
/* all base not already selected or marked that is editable */
if ((base->object->flag & (BA_TRANSFORM_CHILD | BA_TRANSFORM_PARENT)) == 0 &&
(base->flag & BASE_SELECTED) == 0 &&
@@ -445,7 +450,7 @@ static int count_proportional_objects(TransInfo *t)
}
}
/* Flush changed flags to all dependencies. */
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *ob = base->object;
/* If base is not selected, not a parent of selection or not a child of
* selection and it is editable and selectable.
@@ -460,16 +465,17 @@ static int count_proportional_objects(TransInfo *t)
/* Store temporary bits in base indicating that base is being modified
* (directly or indirectly) by transforming objects.
*/
- trans_object_base_deps_flag_finish(t, view_layer);
+ trans_object_base_deps_flag_finish(t, scene, view_layer);
return total;
}
static void clear_trans_object_base_flags(TransInfo *t)
{
+ Scene *scene = t->scene;
ViewLayer *view_layer = t->view_layer;
- Base *base;
- for (base = view_layer->object_bases.first; base; base = base->next) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (base->flag_legacy & BA_WAS_SEL) {
ED_object_base_select(base, BA_SELECT);
}
@@ -559,11 +565,12 @@ static void createTransObject(bContext *C, TransInfo *t)
CTX_DATA_END;
if (is_prop_edit) {
+ Scene *scene = t->scene;
ViewLayer *view_layer = t->view_layer;
View3D *v3d = t->view;
- Base *base;
- for (base = view_layer->object_bases.first; base; base = base->next) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *ob = base->object;
/* if base is not selected, not a parent of selection
@@ -592,10 +599,12 @@ static void createTransObject(bContext *C, TransInfo *t)
}
}
+ Scene *scene = t->scene;
ViewLayer *view_layer = t->view_layer;
View3D *v3d = t->view;
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *ob = base->object;
/* if base is not selected, not a parent of selection
@@ -640,14 +649,16 @@ static void createTransObject(bContext *C, TransInfo *t)
}
}
+ Scene *scene = t->scene;
ViewLayer *view_layer = t->view_layer;
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *ob = base->object;
if (ob->parent != NULL) {
if (ob->parent && !BLI_gset_haskey(objects_in_transdata, ob->parent) &&
!BLI_gset_haskey(objects_in_transdata, ob)) {
- if (((base->flag_legacy & BA_WAS_SEL) && (base->flag & BASE_SELECTED) == 0)) {
+ if ((base->flag_legacy & BA_WAS_SEL) && (base->flag & BASE_SELECTED) == 0) {
Base *base_parent = BKE_view_layer_base_find(view_layer, ob->parent);
if (base_parent && !BASE_XFORM_INDIRECT(base_parent)) {
Object *ob_parent_recurse = ob->parent;
@@ -672,7 +683,7 @@ static void createTransObject(bContext *C, TransInfo *t)
}
}
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *ob = base->object;
if (BASE_XFORM_INDIRECT(base) || BLI_gset_haskey(objects_in_transdata, ob)) {
@@ -782,6 +793,7 @@ static void autokeyframe_object(
}
else if (ELEM(tmode, TFM_ROTATION, TFM_TRACKBALL)) {
if (scene->toolsettings->transform_pivot_point == V3D_AROUND_ACTIVE) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
if (ob != BKE_view_layer_active_object_get(view_layer)) {
do_loc = true;
}
@@ -796,6 +808,7 @@ static void autokeyframe_object(
}
else if (tmode == TFM_RESIZE) {
if (scene->toolsettings->transform_pivot_point == V3D_AROUND_ACTIVE) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
if (ob != BKE_view_layer_active_object_get(view_layer)) {
do_loc = true;
}
diff --git a/source/blender/editors/transform/transform_convert_object_texspace.c b/source/blender/editors/transform/transform_convert_object_texspace.c
index 4dc4218c433..b4c1c134d49 100644
--- a/source/blender/editors/transform/transform_convert_object_texspace.c
+++ b/source/blender/editors/transform/transform_convert_object_texspace.c
@@ -38,6 +38,7 @@ static void createTransTexspace(bContext *UNUSED(C), TransInfo *t)
ID *id;
char *texflag;
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
ob = BKE_view_layer_active_object_get(view_layer);
if (ob == NULL) { /* Shouldn't logically happen, but still. */
@@ -66,8 +67,8 @@ static void createTransTexspace(bContext *UNUSED(C), TransInfo *t)
td->flag = TD_SELECTED;
td->ob = ob;
- copy_m3_m4(td->mtx, ob->obmat);
- copy_m3_m4(td->axismtx, ob->obmat);
+ copy_m3_m4(td->mtx, ob->object_to_world);
+ copy_m3_m4(td->axismtx, ob->object_to_world);
normalize_m3(td->axismtx);
pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
diff --git a/source/blender/editors/transform/transform_convert_particle.c b/source/blender/editors/transform/transform_convert_particle.c
index 354402a305f..e6ff730d4d1 100644
--- a/source/blender/editors/transform/transform_convert_particle.c
+++ b/source/blender/editors/transform/transform_convert_particle.c
@@ -35,6 +35,7 @@ static void createTransParticleVerts(bContext *UNUSED(C), TransInfo *t)
TransData *td = NULL;
TransDataExtension *tx;
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
Object *ob = BKE_view_layer_active_object_get(t->view_layer);
ParticleEditSettings *pset = PE_settings(t->scene);
PTCacheEdit *edit = PE_get_current(t->depsgraph, t->scene, ob);
@@ -94,7 +95,7 @@ static void createTransParticleVerts(bContext *UNUSED(C), TransInfo *t)
unit_m4(mat);
- invert_m4_m4(ob->imat, ob->obmat);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) {
TransData *head, *tail;
@@ -184,6 +185,7 @@ static void flushTransParticles(TransInfo *t)
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
Scene *scene = t->scene;
ViewLayer *view_layer = t->view_layer;
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
PTCacheEdit *edit = PE_get_current(t->depsgraph, scene, ob);
ParticleSystem *psys = edit->psys;
@@ -224,7 +226,7 @@ static void flushTransParticles(TransInfo *t)
}
}
- PE_update_object(t->depsgraph, scene, BKE_view_layer_active_object_get(view_layer), 1);
+ PE_update_object(t->depsgraph, scene, ob, 1);
BKE_particle_batch_cache_dirty_tag(psys, BKE_PARTICLE_BATCH_DIRTY_ALL);
DEG_id_tag_update(&ob->id, ID_RECALC_PSYS_REDO);
}
diff --git a/source/blender/editors/transform/transform_convert_sculpt.c b/source/blender/editors/transform/transform_convert_sculpt.c
index 86dc9f42b6b..cdbf497c584 100644
--- a/source/blender/editors/transform/transform_convert_sculpt.c
+++ b/source/blender/editors/transform/transform_convert_sculpt.c
@@ -34,6 +34,7 @@ static void createTransSculpt(bContext *C, TransInfo *t)
return;
}
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
Object *ob = BKE_view_layer_active_object_get(t->view_layer);
SculptSession *ss = ob->sculpt;
@@ -48,7 +49,7 @@ static void createTransSculpt(bContext *C, TransInfo *t)
td->flag = TD_SELECTED;
copy_v3_v3(td->center, ss->pivot_pos);
- mul_m4_v3(ob->obmat, td->center);
+ mul_m4_v3(ob->object_to_world, td->center);
td->ob = ob;
td->loc = ss->pivot_pos;
@@ -59,16 +60,16 @@ static void createTransSculpt(bContext *C, TransInfo *t)
}
float obmat_inv[3][3];
- copy_m3_m4(obmat_inv, ob->obmat);
+ copy_m3_m4(obmat_inv, ob->object_to_world);
invert_m3(obmat_inv);
td->ext->rot = NULL;
td->ext->rotAxis = NULL;
td->ext->rotAngle = NULL;
td->ext->quat = ss->pivot_rot;
- copy_m4_m4(td->ext->obmat, ob->obmat);
+ copy_m4_m4(td->ext->obmat, ob->object_to_world);
copy_m3_m3(td->ext->l_smtx, obmat_inv);
- copy_m3_m4(td->ext->r_mtx, ob->obmat);
+ copy_m3_m4(td->ext->r_mtx, ob->object_to_world);
copy_m3_m3(td->ext->r_smtx, obmat_inv);
copy_qt_qt(td->ext->iquat, ss->pivot_rot);
@@ -82,11 +83,11 @@ static void createTransSculpt(bContext *C, TransInfo *t)
copy_v3_v3(td->ext->isize, ss->init_pivot_scale);
copy_m3_m3(td->smtx, obmat_inv);
- copy_m3_m4(td->mtx, ob->obmat);
- copy_m3_m4(td->axismtx, ob->obmat);
+ copy_m3_m4(td->mtx, ob->object_to_world);
+ copy_m3_m4(td->axismtx, ob->object_to_world);
BLI_assert(!(t->options & CTX_PAINT_CURVE));
- ED_sculpt_init_transform(C, ob, t->undo_name);
+ ED_sculpt_init_transform(C, ob, t->mval, t->undo_name);
}
/** \} */
@@ -97,6 +98,7 @@ static void createTransSculpt(bContext *C, TransInfo *t)
static void recalcData_sculpt(TransInfo *t)
{
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
Object *ob = BKE_view_layer_active_object_get(t->view_layer);
ED_sculpt_update_modal_transform(t->context, ob);
}
@@ -109,6 +111,7 @@ static void special_aftertrans_update__sculpt(bContext *C, TransInfo *t)
return;
}
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
Object *ob = BKE_view_layer_active_object_get(t->view_layer);
BLI_assert(!(t->options & CTX_PAINT_CURVE));
ED_sculpt_end_transform(C, ob);
diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c
index ddc99caeef5..80c74b81cfa 100644
--- a/source/blender/editors/transform/transform_convert_sequencer.c
+++ b/source/blender/editors/transform/transform_convert_sequencer.c
@@ -94,7 +94,7 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_count, int *r_flag)
int left = SEQ_time_left_handle_frame_get(scene, seq);
int right = SEQ_time_right_handle_frame_get(scene, seq);
- if (((seq->flag & SELECT) == 0 || SEQ_transform_is_locked(channels, seq))) {
+ if ((seq->flag & SELECT) == 0 || SEQ_transform_is_locked(channels, seq)) {
*r_count = 0;
*r_flag = 0;
}
@@ -615,7 +615,6 @@ static void flushTransSeq(TransInfo *t)
case SEQ_LEFTSEL: { /* No vertical transform. */
int old_startdisp = SEQ_time_left_handle_frame_get(scene, seq);
SEQ_time_left_handle_frame_set(t->scene, seq, new_frame);
- SEQ_transform_fix_single_image_seq_offsets(t->scene, seq);
if (abs(SEQ_time_left_handle_frame_get(scene, seq) - old_startdisp) > abs(max_offset)) {
max_offset = SEQ_time_left_handle_frame_get(scene, seq) - old_startdisp;
@@ -625,7 +624,6 @@ static void flushTransSeq(TransInfo *t)
case SEQ_RIGHTSEL: { /* No vertical transform. */
int old_enddisp = SEQ_time_right_handle_frame_get(scene, seq);
SEQ_time_right_handle_frame_set(t->scene, seq, new_frame);
- SEQ_transform_fix_single_image_seq_offsets(t->scene, seq);
if (abs(SEQ_time_right_handle_frame_get(scene, seq) - old_enddisp) > abs(max_offset)) {
max_offset = SEQ_time_right_handle_frame_get(scene, seq) - old_enddisp;
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 9ba5c9ebfe8..e1f93bf881b 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -176,6 +176,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
{
Scene *sce = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(sce, view_layer);
Object *obact = BKE_view_layer_active_object_get(view_layer);
const eObjectMode object_mode = obact ? obact->mode : OB_MODE_OBJECT;
ToolSettings *ts = CTX_data_tool_settings(C);
@@ -316,7 +317,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
}
/* initialize UV transform from */
- if (op && ((prop = RNA_struct_find_property(op->ptr, "correct_uv")))) {
+ if (op && (prop = RNA_struct_find_property(op->ptr, "correct_uv"))) {
if (RNA_property_is_set(op->ptr, prop)) {
if (RNA_property_boolean_get(op->ptr, prop)) {
t->settings->uvcalc_flag |= UVCALC_TRANSFORM_CORRECT_SLIDE;
@@ -333,6 +334,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
}
else if (t->spacetype == SPACE_IMAGE) {
SpaceImage *sima = area->spacedata.first;
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
if (ED_space_image_show_uvedit(sima, BKE_view_layer_active_object_get(t->view_layer))) {
/* UV transform */
}
@@ -1061,15 +1063,15 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3])
}
if (tc->obedit) {
if (ED_object_calc_active_center_for_editmode(tc->obedit, select_only, r_center)) {
- mul_m4_v3(tc->obedit->obmat, r_center);
+ mul_m4_v3(tc->obedit->object_to_world, r_center);
return true;
}
}
else if (t->options & CTX_POSE_BONE) {
- ViewLayer *view_layer = t->view_layer;
- Object *ob = BKE_view_layer_active_object_get(view_layer);
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
+ Object *ob = BKE_view_layer_active_object_get(t->view_layer);
if (ED_object_calc_active_center_for_posemode(ob, select_only, r_center)) {
- mul_m4_v3(ob->obmat, r_center);
+ mul_m4_v3(ob->object_to_world, r_center);
return true;
}
}
@@ -1083,11 +1085,10 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3])
}
else {
/* object mode */
- ViewLayer *view_layer = t->view_layer;
- Object *ob = BKE_view_layer_active_object_get(view_layer);
- Base *base = view_layer->basact;
- if (ob && ((!select_only) || ((base->flag & BASE_SELECTED) != 0))) {
- copy_v3_v3(r_center, ob->obmat[3]);
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
+ Base *base = BKE_view_layer_active_base_get(t->view_layer);
+ if (base && ((!select_only) || ((base->flag & BASE_SELECTED) != 0))) {
+ copy_v3_v3(r_center, base->object->object_to_world[3]);
return true;
}
}
@@ -1464,6 +1465,7 @@ Object *transform_object_deform_pose_armature_get(const TransInfo *t, Object *ob
* Lines below just check is also visible. */
Object *ob_armature = BKE_modifiers_is_deformed_by_armature(ob);
if (ob_armature && ob_armature->mode & OB_MODE_POSE) {
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
Base *base_arm = BKE_view_layer_base_find(t->view_layer, ob_armature);
if (base_arm) {
View3D *v3d = t->view;
diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c
index 426b338f8a7..a6eb25975e9 100644
--- a/source/blender/editors/transform/transform_gizmo_2d.c
+++ b/source/blender/editors/transform/transform_gizmo_2d.c
@@ -236,7 +236,7 @@ static bool gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, NULL, &objects_len);
+ scene, view_layer, NULL, &objects_len);
if (ED_uvedit_minmax_multi(scene, objects, objects_len, r_min, r_max)) {
has_select = true;
}
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index 7b6c0e1654d..71a449ad10c 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -553,7 +553,7 @@ static void axis_angle_to_gimbal_axis(float gmat[3][3], const float axis[3], con
static bool test_rotmode_euler(short rotmode)
{
- return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1;
+ return ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT) ? 0 : 1;
}
bool gimbal_axis_pose(Object *ob, const bPoseChannel *pchan, float gmat[3][3])
@@ -581,12 +581,12 @@ bool gimbal_axis_pose(Object *ob, const bPoseChannel *pchan, float gmat[3][3])
mul_m3_m3m3(mat, parent_mat, tmat);
/* needed if object transformation isn't identity */
- copy_m3_m4(obmat, ob->obmat);
+ copy_m3_m4(obmat, ob->object_to_world);
mul_m3_m3m3(gmat, obmat, mat);
}
else {
/* needed if object transformation isn't identity */
- copy_m3_m4(obmat, ob->obmat);
+ copy_m3_m4(obmat, ob->object_to_world);
mul_m3_m3m3(gmat, obmat, tmat);
}
@@ -608,7 +608,7 @@ bool gimbal_axis_object(Object *ob, float gmat[3][3])
if (ob->parent) {
float parent_mat[3][3];
- copy_m3_m4(parent_mat, ob->parent->obmat);
+ copy_m3_m4(parent_mat, ob->parent->object_to_world);
normalize_m3(parent_mat);
mul_m3_m3m3(gmat, parent_mat, gmat);
}
@@ -639,6 +639,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
(params->orientation_index - 1) :
BKE_scene_orientation_get_index(scene, SCE_ORIENT_DEFAULT);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
Object *obedit = OBEDIT_FROM_OBACT(ob);
if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) {
@@ -674,14 +675,14 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
copy_m3_m4(tbounds->axis, rv3d->twmat);
if (params->use_local_axis && (ob && ob->mode & (OB_MODE_EDIT | OB_MODE_POSE))) {
float diff_mat[3][3];
- copy_m3_m4(diff_mat, ob->obmat);
+ copy_m3_m4(diff_mat, ob->object_to_world);
normalize_m3(diff_mat);
invert_m3(diff_mat);
mul_m3_m3m3(tbounds->axis, tbounds->axis, diff_mat);
normalize_m3(tbounds->axis);
tbounds->use_matrix_space = true;
- copy_m4_m4(tbounds->matrix_space, ob->obmat);
+ copy_m4_m4(tbounds->matrix_space, ob->object_to_world);
}
if (is_gp_edit) {
@@ -750,10 +751,10 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
#define FOREACH_EDIT_OBJECT_BEGIN(ob_iter, use_mat_local) \
{ \
- invert_m4_m4(obedit->imat, obedit->obmat); \
+ invert_m4_m4(obedit->world_to_object, obedit->object_to_world); \
uint objects_len = 0; \
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode( \
- view_layer, CTX_wm_view3d(C), &objects_len); \
+ scene, view_layer, CTX_wm_view3d(C), &objects_len); \
for (uint ob_index = 0; ob_index < objects_len; ob_index++) { \
Object *ob_iter = objects[ob_index]; \
const bool use_mat_local = (ob_iter != obedit);
@@ -779,7 +780,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
float mat_local[4][4];
if (use_mat_local) {
- mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
+ mul_m4_m4m4(mat_local, obedit->world_to_object, ob_iter->object_to_world);
}
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
@@ -799,7 +800,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
float mat_local[4][4];
if (use_mat_local) {
- mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
+ mul_m4_m4m4(mat_local, obedit->world_to_object, ob_iter->object_to_world);
}
LISTBASE_FOREACH (EditBone *, ebo, arm->edbo) {
if (EBONE_VISIBLE(arm, ebo)) {
@@ -832,7 +833,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
float mat_local[4][4];
if (use_mat_local) {
- mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
+ mul_m4_m4m4(mat_local, obedit->world_to_object, ob_iter->object_to_world);
}
nu = nurbs->first;
@@ -892,7 +893,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
float mat_local[4][4];
if (use_mat_local) {
- mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
+ mul_m4_m4m4(mat_local, obedit->world_to_object, ob_iter->object_to_world);
}
LISTBASE_FOREACH (MetaElem *, ml, mb->editelems) {
@@ -912,7 +913,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
float mat_local[4][4];
if (use_mat_local) {
- mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat);
+ mul_m4_m4m4(mat_local, obedit->world_to_object, ob_iter->object_to_world);
}
while (a--) {
@@ -932,16 +933,16 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
/* selection center */
if (totsel) {
mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */
- mul_m4_v3(obedit->obmat, tbounds->center);
- mul_m4_v3(obedit->obmat, tbounds->min);
- mul_m4_v3(obedit->obmat, tbounds->max);
+ mul_m4_v3(obedit->object_to_world, tbounds->center);
+ mul_m4_v3(obedit->object_to_world, tbounds->min);
+ mul_m4_v3(obedit->object_to_world, tbounds->max);
}
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
- invert_m4_m4(ob->imat, ob->obmat);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
uint objects_len = 0;
- Object **objects = BKE_object_pose_array_get(view_layer, v3d, &objects_len);
+ Object **objects = BKE_object_pose_array_get(scene, view_layer, v3d, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob_iter = objects[ob_index];
@@ -953,7 +954,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
float mat_local[4][4];
if (use_mat_local) {
- mul_m4_m4m4(mat_local, ob->imat, ob_iter->obmat);
+ mul_m4_m4m4(mat_local, ob->world_to_object, ob_iter->object_to_world);
}
/* Use channels to get stats. */
@@ -970,18 +971,18 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
if (totsel) {
mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */
- mul_m4_v3(ob->obmat, tbounds->center);
- mul_m4_v3(ob->obmat, tbounds->min);
- mul_m4_v3(ob->obmat, tbounds->max);
+ mul_m4_v3(ob->object_to_world, tbounds->center);
+ mul_m4_v3(ob->object_to_world, tbounds->min);
+ mul_m4_v3(ob->object_to_world, tbounds->max);
}
}
else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) {
if (ob->mode & OB_MODE_SCULPT) {
totsel = 1;
- calc_tw_center_with_matrix(tbounds, ob->sculpt->pivot_pos, false, ob->obmat);
- mul_m4_v3(ob->obmat, tbounds->center);
- mul_m4_v3(ob->obmat, tbounds->min);
- mul_m4_v3(ob->obmat, tbounds->max);
+ calc_tw_center_with_matrix(tbounds, ob->sculpt->pivot_pos, false, ob->object_to_world);
+ mul_m4_v3(ob->object_to_world, tbounds->center);
+ mul_m4_v3(ob->object_to_world, tbounds->min);
+ mul_m4_v3(ob->object_to_world, tbounds->max);
}
}
else if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) {
@@ -1014,13 +1015,14 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
else {
/* we need the one selected object, if its not active */
- base = view_layer->basact;
- ob = BKE_view_layer_active_object_get(view_layer);
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ base = BKE_view_layer_active_base_get(view_layer);
+ ob = base ? base->object : NULL;
if (base && ((base->flag & BASE_SELECTED) == 0)) {
ob = NULL;
}
- for (base = view_layer->object_bases.first; base; base = base->next) {
+ for (base = BKE_view_layer_object_bases_get(view_layer)->first; base; base = base->next) {
if (!BASE_SELECTED_EDITABLE(v3d, base)) {
continue;
}
@@ -1035,12 +1037,12 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
}
if (params->use_only_center || (bb == NULL)) {
- calc_tw_center(tbounds, base->object->obmat[3]);
+ calc_tw_center(tbounds, base->object->object_to_world[3]);
}
else {
for (uint j = 0; j < 8; j++) {
float co[3];
- mul_v3_m4v3(co, base->object->obmat, bb->vec[j]);
+ mul_v3_m4v3(co, base->object->object_to_world, bb->vec[j]);
calc_tw_center(tbounds, co);
}
}
@@ -1098,13 +1100,15 @@ static void gizmo_prepare_mat(const bContext *C,
mid_v3_v3v3(rv3d->twmat[3], tbounds->min, tbounds->max);
if (scene->toolsettings->transform_pivot_point == V3D_AROUND_ACTIVE) {
- bGPdata *gpd = CTX_data_gpencil_data(C);
- if (gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) {
- /* pass */
- }
- else {
- Object *ob = BKE_view_layer_active_object_get(view_layer);
- if (ob != NULL) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *ob = BKE_view_layer_active_object_get(view_layer);
+ if (ob != NULL) {
+ /* Grease Pencil uses object origin. */
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ if (gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) {
+ ED_object_calc_active_center(ob, false, rv3d->twmat[3]);
+ }
+ else {
if ((ob->mode & OB_MODE_ALL_SCULPT) && ob->sculpt) {
SculptSession *ss = ob->sculpt;
copy_v3_v3(rv3d->twmat[3], ss->pivot_pos);
diff --git a/source/blender/editors/transform/transform_gizmo_extrude_3d.c b/source/blender/editors/transform/transform_gizmo_extrude_3d.c
index a3b5fd2c575..0271f8e1988 100644
--- a/source/blender/editors/transform/transform_gizmo_extrude_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_extrude_3d.c
@@ -101,7 +101,7 @@ static void gizmo_mesh_extrude_orientation_matrix_set_for_adjust(struct GizmoExt
for (int j = 0; j < 3; j++) {
copy_v3_v3(ggd->adjust[0]->matrix_basis[j], mat[j]);
}
- /* nop when (i == 2). */
+ /* NOP when (i == 2). */
swap_v3_v3(ggd->adjust[0]->matrix_basis[ggd->adjust_axis], ggd->adjust[0]->matrix_basis[2]);
}
diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c
index 10ea022757d..aeceedf0690 100644
--- a/source/blender/editors/transform/transform_mode.c
+++ b/source/blender/editors/transform/transform_mode.c
@@ -57,7 +57,7 @@ bool transdata_check_local_center(const TransInfo *t, short around)
return ((around == V3D_AROUND_LOCAL_ORIGINS) &&
((t->options & (CTX_OBJECT | CTX_POSE_BONE)) ||
/* implicit: (t->flag & T_EDIT) */
- (ELEM(t->obedit_type, OB_MESH, OB_CURVES_LEGACY, OB_MBALL, OB_ARMATURE, OB_GPENCIL)) ||
+ ELEM(t->obedit_type, OB_MESH, OB_CURVES_LEGACY, OB_MBALL, OB_ARMATURE, OB_GPENCIL) ||
(t->spacetype == SPACE_GRAPH) ||
(t->options & (CTX_MOVIECLIP | CTX_MASK | CTX_PAINT_CURVE | CTX_SEQUENCER_IMAGE))));
}
@@ -1041,7 +1041,7 @@ void ElementResize(const TransInfo *t,
if (t->options & CTX_POSE_BONE) {
/* Without this, the resulting location of scaled bones aren't correct,
* especially noticeable scaling root or disconnected bones around the cursor, see T92515. */
- mul_mat3_m4_v3(tc->poseobj->obmat, vec);
+ mul_mat3_m4_v3(tc->poseobj->object_to_world, vec);
}
mul_m3_v3(td->smtx, vec);
}
diff --git a/source/blender/editors/transform/transform_mode_curveshrinkfatten.c b/source/blender/editors/transform/transform_mode_curveshrinkfatten.c
index f7f9e14b8ac..0b87b45679a 100644
--- a/source/blender/editors/transform/transform_mode_curveshrinkfatten.c
+++ b/source/blender/editors/transform/transform_mode_curveshrinkfatten.c
@@ -8,6 +8,7 @@
#include <stdlib.h>
#include "BLI_math.h"
+#include "BLI_math_bits.h"
#include "BLI_string.h"
#include "BKE_context.h"
@@ -62,7 +63,14 @@ static void applyCurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
}
if (td->val) {
- *td->val = td->ival * ratio;
+ if (td->ival == 0.0f && ratio > 1.0f) {
+ /* Allow Shrink/Fatten for zero radius. */
+ *td->val = (ratio - 1.0f) * uint_as_float(POINTER_AS_UINT(t->custom.mode.data));
+ }
+ else {
+ *td->val = td->ival * ratio;
+ }
+
/* apply PET */
*td->val = interpf(*td->val, td->ival, td->factor);
CLAMP_MIN(*td->val, 0.0f);
@@ -92,6 +100,18 @@ void initCurveShrinkFatten(TransInfo *t)
t->num.unit_type[0] = B_UNIT_NONE;
t->flag |= T_NO_CONSTRAINT;
+
+ float scale_factor = 0.0f;
+ if (((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW) &&
+ (t->data_len_all == 1)) ||
+ (t->data_len_all == 3 && TRANS_DATA_CONTAINER_FIRST_OK(t)->data[0].val == NULL)) {
+ /* For cases where only one point on the curve is being transformed and the radius of that
+ * point is zero, use the factor to multiply the offset of the ratio and allow scaling.
+ * Note that for bezier curves, 3 TransData equals 1 point in most cases. */
+ RegionView3D *rv3d = t->region->regiondata;
+ scale_factor = rv3d->pixsize * t->mouse.factor * t->zfac;
+ }
+ t->custom.mode.data = POINTER_FROM_UINT(float_as_uint(scale_factor));
}
/** \} */
diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c
index 85285e38bdd..5cdb4d3bf61 100644
--- a/source/blender/editors/transform/transform_mode_edge_slide.c
+++ b/source/blender/editors/transform/transform_mode_edge_slide.c
@@ -360,7 +360,7 @@ static void edge_slide_data_init_mval(MouseInput *mi, EdgeSlideData *sld, float
}
/**
- * Calculate screenspace `mval_start` / `mval_end`, optionally slide direction.
+ * Calculate screen-space `mval_start` / `mval_end`, optionally slide direction.
*/
static void calcEdgeSlide_mval_range(TransInfo *t,
TransDataContainer *tc,
@@ -954,7 +954,7 @@ static EdgeSlideData *createEdgeSlideVerts_single_side(TransInfo *t, TransDataCo
BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
sv_table[i] = -1;
- if ((v->e != NULL) && (BM_elem_flag_test(v, BM_ELEM_SELECT))) {
+ if ((v->e != NULL) && BM_elem_flag_test(v, BM_ELEM_SELECT)) {
if (BM_elem_flag_test(v->e, BM_ELEM_SELECT) == 0) {
TransDataEdgeSlideVert *sv;
sv = &sv_array[j];
@@ -1149,7 +1149,7 @@ void drawEdgeSlide(TransInfo *t)
GPU_blend(GPU_BLEND_ALPHA);
GPU_matrix_push();
- GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat);
+ GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->object_to_world);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
diff --git a/source/blender/editors/transform/transform_mode_rotate.c b/source/blender/editors/transform/transform_mode_rotate.c
index f3186b21cb9..110000def35 100644
--- a/source/blender/editors/transform/transform_mode_rotate.c
+++ b/source/blender/editors/transform/transform_mode_rotate.c
@@ -334,7 +334,7 @@ static bool clip_uv_transform_rotate(const TransInfo *t, float *vec, float *vec_
for (int i = 0; i < max_i; i++) {
/* Binary search. */
const float angle_mid = (angle_inside_bounds + angle) / 2.0f;
- if (angle_mid == angle_inside_bounds || angle_mid == angle) {
+ if (ELEM(angle_mid, angle_inside_bounds, angle)) {
break; /* float precision reached. */
}
if (uv_rotation_in_clip_bounds_test(t, angle_mid)) {
diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c
index 8f6ec7bd98f..59d34c3918b 100644
--- a/source/blender/editors/transform/transform_mode_translate.c
+++ b/source/blender/editors/transform/transform_mode_translate.c
@@ -170,7 +170,7 @@ static void transdata_elem_translate_fn(void *__restrict iter_data_v,
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Transform (Translation)
+/** \name Transform (Translation) Header
* \{ */
static void translate_dist_to_str(char *r_str,
@@ -341,6 +341,96 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Transform (Translation) Snapping
+ * \{ */
+
+static void translate_snap_target_grid_ensure(TransInfo *t)
+{
+ /* Only need to calculate once. */
+ if ((t->tsnap.status & TARGET_GRID_INIT) == 0) {
+ if (t->data_type == &TransConvertType_Cursor3D) {
+ /* Use a fallback when transforming the cursor.
+ * In this case the center is _not_ derived from the cursor which is being transformed. */
+ copy_v3_v3(t->tsnap.snapTargetGrid, TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->data->iloc);
+ }
+ else if (t->around == V3D_AROUND_CURSOR) {
+ /* Use a fallback for cursor selection,
+ * this isn't useful as a global center for absolute grid snapping
+ * since its not based on the position of the selection. */
+ tranform_snap_target_median_calc(t, t->tsnap.snapTargetGrid);
+ }
+ else {
+ copy_v3_v3(t->tsnap.snapTargetGrid, t->center_global);
+ }
+ t->tsnap.status |= TARGET_GRID_INIT;
+ }
+}
+
+static void translate_snap_grid_apply(TransInfo *t,
+ const int max_index,
+ const float grid_dist[3],
+ const float loc[3],
+ float r_out[3])
+{
+ BLI_assert(max_index <= 2);
+ translate_snap_target_grid_ensure(t);
+ const float *center_global = t->tsnap.snapTargetGrid;
+ const float *asp = t->aspect;
+
+ float in[3];
+ if (t->con.mode & CON_APPLY) {
+ BLI_assert(t->tsnap.snapElem == SCE_SNAP_MODE_NONE);
+ t->con.applyVec(t, NULL, NULL, loc, in);
+ }
+ else {
+ copy_v3_v3(in, loc);
+ }
+
+ for (int i = 0; i <= max_index; i++) {
+ const float iter_fac = grid_dist[i] * asp[i];
+ r_out[i] = iter_fac * roundf((in[i] + center_global[i]) / iter_fac) - center_global[i];
+ }
+}
+
+static bool translate_snap_grid(TransInfo *t, float *val)
+{
+ if (!activeSnap(t)) {
+ return false;
+ }
+
+ if (!(t->tsnap.mode & SCE_SNAP_MODE_GRID) || validSnap(t)) {
+ /* Don't do grid snapping if there is a valid snap point. */
+ return false;
+ }
+
+ /* Don't do grid snapping if not in 3D viewport or UV editor */
+ if (!ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE)) {
+ return false;
+ }
+
+ if (t->mode != TFM_TRANSLATION) {
+ return false;
+ }
+
+ float grid_dist[3];
+ copy_v3_v3(grid_dist, t->snap_spatial);
+ if (t->modifiers & MOD_PRECISION) {
+ mul_v3_fl(grid_dist, t->snap_spatial_precision);
+ }
+
+ /* Early bailing out if no need to snap */
+ if (is_zero_v3(grid_dist)) {
+ return false;
+ }
+
+ translate_snap_grid_apply(t, t->idx_max, grid_dist, val, val);
+ t->tsnap.snapElem = SCE_SNAP_MODE_GRID;
+ return true;
+}
+
static void ApplySnapTranslation(TransInfo *t, float vec[3])
{
float point[3];
@@ -372,6 +462,12 @@ static void ApplySnapTranslation(TransInfo *t, float vec[3])
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Transform (Translation)
+ * \{ */
+
static void applyTranslationValue(TransInfo *t, const float vec[3])
{
struct TranslateCustomData *custom_data = t->custom.mode.data;
@@ -514,7 +610,7 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2]))
t->tsnap.snapElem = SCE_SNAP_MODE_NONE;
applySnappingAsGroup(t, global_dir);
- transform_snap_grid(t, global_dir);
+ translate_snap_grid(t, global_dir);
if (t->con.mode & CON_APPLY) {
float in[3];
@@ -590,7 +686,8 @@ void initTranslation(TransInfo *t)
t->num.flag = 0;
t->num.idx_max = t->idx_max;
- copy_v2_v2(t->snap, t->snap_spatial);
+ t->snap[0] = t->snap_spatial[0];
+ t->snap[1] = t->snap_spatial[0] * t->snap_spatial_precision;
copy_v3_fl(t->num.val_inc, t->snap[0]);
t->num.unit_sys = t->scene->unit.system;
diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c
index d7c4d862b23..a54888fe515 100644
--- a/source/blender/editors/transform/transform_mode_vert_slide.c
+++ b/source/blender/editors/transform/transform_mode_vert_slide.c
@@ -167,7 +167,7 @@ static void calcVertSlideMouseActiveEdges(struct TransInfo *t, const int mval[2]
float dir_dot;
sub_v3_v3v3(tdir, sv->co_orig_3d, sv->co_link_orig_3d[j]);
- mul_mat3_m4_v3(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat, tdir);
+ mul_mat3_m4_v3(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->object_to_world, tdir);
project_plane_v3_v3v3(tdir, tdir, t->viewinv[2]);
normalize_v3(tdir);
@@ -382,7 +382,7 @@ void drawVertSlide(TransInfo *t)
GPU_blend(GPU_BLEND_ALPHA);
GPU_matrix_push();
- GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat);
+ GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->object_to_world);
GPU_line_width(line_size);
@@ -437,15 +437,16 @@ void drawVertSlide(TransInfo *t)
xy_delta[0] = t->mval[0] - t->mouse.imval[0];
xy_delta[1] = t->mval[1] - t->mouse.imval[1];
- mul_v3_m4v3(
- co_orig_3d, TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat, curr_sv->co_orig_3d);
+ mul_v3_m4v3(co_orig_3d,
+ TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->object_to_world,
+ curr_sv->co_orig_3d);
zfac = ED_view3d_calc_zfac(t->region->regiondata, co_orig_3d);
ED_view3d_win_to_delta(t->region, xy_delta, zfac, co_dest_3d);
- invert_m4_m4(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->imat,
- TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat);
- mul_mat3_m4_v3(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->imat, co_dest_3d);
+ invert_m4_m4(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->world_to_object,
+ TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->object_to_world);
+ mul_mat3_m4_v3(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->world_to_object, co_dest_3d);
add_v3_v3(co_dest_3d, curr_sv->co_orig_3d);
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 99919c0ed78..82791b2a9f5 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -523,9 +523,7 @@ static int transform_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static bool transform_poll_property(const bContext *UNUSED(C),
- wmOperator *op,
- const PropertyRNA *prop)
+static bool transform_poll_property(const bContext *C, wmOperator *op, const PropertyRNA *prop)
{
const char *prop_id = RNA_property_identifier(prop);
@@ -559,21 +557,28 @@ static bool transform_poll_property(const bContext *UNUSED(C),
}
/* Proportional Editing. */
- {
+ if (STRPREFIX(prop_id, "proportional") || STRPREFIX(prop_id, "use_proportional")) {
+ ScrArea *area = CTX_wm_area(C);
+ if (area->spacetype == SPACE_NLA) {
+ /* Hide properties that are not supported in some spaces. */
+ return false;
+ }
+
PropertyRNA *prop_pet = RNA_struct_find_property(op->ptr, "use_proportional_edit");
- if (prop_pet && (prop_pet != prop) && (RNA_property_boolean_get(op->ptr, prop_pet) == false)) {
- if (STRPREFIX(prop_id, "proportional") || STRPREFIX(prop_id, "use_proportional")) {
- return false;
- }
+ if ((prop_pet != prop) && (RNA_property_boolean_get(op->ptr, prop_pet) == false)) {
+ /* If "use_proportional_edit" is false, hide:
+ * - "proportional_edit_falloff",
+ * - "proportional_size",
+ * - "use_proportional_connected",
+ * - "use_proportional_projected". */
+ return false;
}
}
/* Snapping. */
{
- PropertyRNA *prop_snap = RNA_struct_find_property(op->ptr, "snap");
- if (prop_snap && (prop_snap != prop) &&
- (RNA_property_boolean_get(op->ptr, prop_snap) == false)) {
- if (STRPREFIX(prop_id, "snap") || STRPREFIX(prop_id, "use_snap")) {
+ if (STREQ(prop_id, "use_snap_project")) {
+ if (RNA_boolean_get(op->ptr, "snap") == false) {
return false;
}
}
@@ -626,7 +631,7 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
if (flags & P_MIRROR) {
prop = RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
- if (flags & P_MIRROR_DUMMY) {
+ if ((flags & P_MIRROR_DUMMY) == P_MIRROR_DUMMY) {
/* only used so macros can disable this option */
RNA_def_property_flag(prop, PROP_HIDDEN);
}
@@ -660,17 +665,17 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
prop = RNA_def_boolean(ot->srna, "snap", false, "Use Snapping Options", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
- prop = RNA_def_enum(ot->srna,
- "snap_elements",
- rna_enum_snap_element_items,
- SCE_SNAP_MODE_INCREMENT,
- "Snap to Elements",
- "");
- RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ if ((flags & P_GEO_SNAP) == P_GEO_SNAP) {
+ prop = RNA_def_enum(ot->srna,
+ "snap_elements",
+ rna_enum_snap_element_items,
+ SCE_SNAP_MODE_INCREMENT,
+ "Snap to Elements",
+ "");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_ENUM_FLAG);
- RNA_def_boolean(ot->srna, "use_snap_project", false, "Project Individual Elements", "");
+ RNA_def_boolean(ot->srna, "use_snap_project", false, "Project Individual Elements", "");
- if (flags & P_GEO_SNAP) {
/* TODO(@gfxcoder): Rename `snap_target` to `snap_source` to avoid previous ambiguity of
* "target" (now, "source" is geometry to be moved and "target" is geometry to which moved
* geometry is snapped). Use "Source snap point" and "Point on source that will snap to
@@ -686,22 +691,14 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
prop = RNA_def_boolean(ot->srna, "use_snap_nonedit", true, "Target: Include Non-Edited", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
prop = RNA_def_boolean(
- ot->srna, "use_snap_selectable_only", false, "Target: Exclude Non-Selectable", "");
- RNA_def_property_flag(prop, PROP_HIDDEN);
-
- /* Face Nearest options */
- prop = RNA_def_boolean(
- ot->srna, "use_snap_to_same_target", false, "Snap to Same Target", "");
- RNA_def_property_flag(prop, PROP_HIDDEN);
- prop = RNA_def_int(
- ot->srna, "snap_face_nearest_steps", 1, 1, 32767, "Face Nearest Steps", "", 1, 32767);
+ ot->srna, "use_snap_selectable", false, "Target: Exclude Non-Selectable", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
prop = RNA_def_float_vector(
ot->srna, "snap_point", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX);
RNA_def_property_flag(prop, PROP_HIDDEN);
- if (flags & P_ALIGN_SNAP) {
+ if ((flags & P_ALIGN_SNAP) == P_ALIGN_SNAP) {
prop = RNA_def_boolean(ot->srna, "snap_align", false, "Align with Point Normal", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
prop = RNA_def_float_vector(
@@ -709,11 +706,6 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
RNA_def_property_flag(prop, PROP_HIDDEN);
}
}
- else {
- prop = RNA_def_boolean(
- ot->srna, "use_snap_selectable_only", false, "Target: Exclude Non-Selectable", "");
- RNA_def_property_flag(prop, PROP_HIDDEN);
- }
}
if (flags & P_GPENCIL_EDIT) {
@@ -1165,7 +1157,7 @@ static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot)
"When Even mode is active, flips between the two adjacent edge loops");
RNA_def_boolean(ot->srna, "use_clamp", true, "Clamp", "Clamp within the edge extents");
- Transform_Properties(ot, P_MIRROR | P_SNAP | P_CORRECT_UV);
+ Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV);
}
static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot)
@@ -1200,7 +1192,7 @@ static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot)
"When Even mode is active, flips between the two adjacent edge loops");
RNA_def_boolean(ot->srna, "use_clamp", true, "Clamp", "Clamp within the edge extents");
- Transform_Properties(ot, P_MIRROR | P_SNAP | P_CORRECT_UV);
+ Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV);
}
static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot)
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 53f496a5d3c..66fee01f864 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -126,7 +126,7 @@ static TransformOrientation *createObjectSpace(bContext *C,
ob = base->object;
- copy_m3_m4(mat, ob->obmat);
+ copy_m3_m4(mat, ob->object_to_world);
normalize_m3(mat);
/* use object name if no name is given */
@@ -476,6 +476,7 @@ void ED_transform_calc_orientation_from_type(const bContext *C, float r_mat[3][3
Object *obedit = CTX_data_edit_object(C);
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = region->regiondata;
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
const short orient_index = BKE_scene_orientation_get_index(scene, SCE_ORIENT_DEFAULT);
const int pivot_point = scene->toolsettings->transform_pivot_point;
@@ -515,7 +516,7 @@ short ED_transform_calc_orientation_from_type_ex(const Scene *scene,
}
case V3D_ORIENT_NORMAL: {
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
- ED_getTransformOrientationMatrix(view_layer, v3d, ob, obedit, pivot_point, r_mat);
+ ED_getTransformOrientationMatrix(scene, view_layer, v3d, ob, obedit, pivot_point, r_mat);
break;
}
/* No break we define 'normal' as 'local' in Object mode. */
@@ -528,10 +529,10 @@ short ED_transform_calc_orientation_from_type_ex(const Scene *scene,
* use the active pones axis for display T33575, this works as expected on a single
* bone and users who select many bones will understand what's going on and what local
* means when they start transforming. */
- ED_getTransformOrientationMatrix(view_layer, v3d, ob, obedit, pivot_point, r_mat);
+ ED_getTransformOrientationMatrix(scene, view_layer, v3d, ob, obedit, pivot_point, r_mat);
}
else {
- transform_orientations_create_from_axis(r_mat, UNPACK3(ob->obmat));
+ transform_orientations_create_from_axis(r_mat, UNPACK3(ob->object_to_world));
}
break;
}
@@ -744,7 +745,8 @@ static uint bm_mesh_faces_select_get_n(BMesh *bm, BMVert **elems, const uint n)
}
#endif
-int getTransformOrientation_ex(ViewLayer *view_layer,
+int getTransformOrientation_ex(const Scene *scene,
+ ViewLayer *view_layer,
const View3D *v3d,
struct Object *ob,
struct Object *obedit,
@@ -762,7 +764,7 @@ int getTransformOrientation_ex(ViewLayer *view_layer,
float imat[3][3], mat[3][3];
/* we need the transpose of the inverse for a normal... */
- copy_m3_m4(imat, ob->obmat);
+ copy_m3_m4(imat, ob->object_to_world);
invert_m3_m3(mat, imat);
transpose_m3(mat);
@@ -1190,8 +1192,8 @@ int getTransformOrientation_ex(ViewLayer *view_layer,
if (result == ORIENTATION_EDGE) {
float tvec[3];
- mul_mat3_m4_v3(ob->obmat, normal);
- mul_mat3_m4_v3(ob->obmat, plane);
+ mul_mat3_m4_v3(ob->object_to_world, normal);
+ mul_mat3_m4_v3(ob->object_to_world, plane);
/* align normal to edge direction (so normal is perpendicular to the plane).
* 'ORIENTATION_EDGE' will do the other way around.
@@ -1233,7 +1235,7 @@ int getTransformOrientation_ex(ViewLayer *view_layer,
/* use for both active & all */
if (ok) {
/* we need the transpose of the inverse for a normal... */
- copy_m3_m4(imat, ob->obmat);
+ copy_m3_m4(imat, ob->object_to_world);
invert_m3_m3(mat, imat);
transpose_m3(mat);
@@ -1252,6 +1254,7 @@ int getTransformOrientation_ex(ViewLayer *view_layer,
ok = true;
}
else {
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob);
if (UNLIKELY(base == NULL)) {
/* This is very unlikely, if it happens allow the value to be set since the caller
@@ -1264,8 +1267,8 @@ int getTransformOrientation_ex(ViewLayer *view_layer,
}
if (ok) {
- copy_v3_v3(normal, ob->obmat[2]);
- copy_v3_v3(plane, ob->obmat[1]);
+ copy_v3_v3(normal, ob->object_to_world[2]);
+ copy_v3_v3(plane, ob->object_to_world[1]);
}
}
result = ORIENTATION_NORMAL;
@@ -1282,13 +1285,15 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3])
/* dummy value, not V3D_AROUND_ACTIVE and not V3D_AROUND_LOCAL_ORIGINS */
short around = V3D_AROUND_CENTER_BOUNDS;
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
- return getTransformOrientation_ex(view_layer, v3d, obact, obedit, normal, plane, around);
+ return getTransformOrientation_ex(scene, view_layer, v3d, obact, obedit, normal, plane, around);
}
-void ED_getTransformOrientationMatrix(ViewLayer *view_layer,
+void ED_getTransformOrientationMatrix(const Scene *scene,
+ ViewLayer *view_layer,
const View3D *v3d,
Object *ob,
Object *obedit,
@@ -1300,7 +1305,7 @@ void ED_getTransformOrientationMatrix(ViewLayer *view_layer,
int type;
- type = getTransformOrientation_ex(view_layer, v3d, ob, obedit, normal, plane, around);
+ type = getTransformOrientation_ex(scene, view_layer, v3d, ob, obedit, normal, plane, around);
/* Fallback, when the plane can't be calculated. */
if (ORIENTATION_USE_PLANE(type) && is_zero_v3(plane)) {
diff --git a/source/blender/editors/transform/transform_orientations.h b/source/blender/editors/transform/transform_orientations.h
index 3ac235517a7..32093e830b0 100644
--- a/source/blender/editors/transform/transform_orientations.h
+++ b/source/blender/editors/transform/transform_orientations.h
@@ -55,7 +55,8 @@ enum {
};
#define ORIENTATION_USE_PLANE(ty) ELEM(ty, ORIENTATION_NORMAL, ORIENTATION_EDGE, ORIENTATION_FACE)
-int getTransformOrientation_ex(ViewLayer *view_layer,
+int getTransformOrientation_ex(const Scene *scene,
+ ViewLayer *view_layer,
const View3D *v3d,
struct Object *ob,
struct Object *obedit,
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 02355fd4642..11cb57dc911 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -125,15 +125,11 @@ bool activeSnap(const TransInfo *t)
bool activeSnap_SnappingIndividual(const TransInfo *t)
{
- if (activeSnap(t) && t->tsnap.mode & SCE_SNAP_MODE_FACE_NEAREST) {
- return true;
- }
-
- if (!t->tsnap.project) {
+ if (!activeSnap(t) || (t->flag & T_NO_PROJECT)) {
return false;
}
- if (!activeSnap(t) || (t->flag & T_NO_PROJECT)) {
+ if (!(t->tsnap.project || (t->tsnap.mode & SCE_SNAP_MODE_FACE_NEAREST))) {
return false;
}
@@ -376,7 +372,7 @@ static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td
}
else if (t->options & CTX_OBJECT) {
BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob);
- copy_v3_v3(iloc, td->ob->obmat[3]);
+ copy_v3_v3(iloc, td->ob->object_to_world[3]);
}
if (ED_view3d_project_float_global(t->region, iloc, mval_fl, V3D_PROJ_TEST_NOP) !=
@@ -448,7 +444,7 @@ static void applyFaceNearest(TransInfo *t, TransDataContainer *tc, TransData *td
}
else if (t->options & CTX_OBJECT) {
BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob);
- copy_v3_v3(init_loc, td->ob->obmat[3]);
+ copy_v3_v3(init_loc, td->ob->object_to_world[3]);
}
eSnapMode hit = ED_transform_snap_object_project_view3d(
@@ -515,56 +511,6 @@ void applySnappingIndividual(TransInfo *t)
}
}
-void applyGridAbsolute(TransInfo *t)
-{
- int i;
-
- if (!(activeSnap(t) && (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) {
- return;
- }
-
- float grid_size = (t->modifiers & MOD_PRECISION) ? t->snap_spatial[1] : t->snap_spatial[0];
-
- /* early exit on unusable grid size */
- if (grid_size == 0.0f) {
- return;
- }
-
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td;
-
- for (i = 0, td = tc->data; i < tc->data_len; i++, td++) {
- float iloc[3], loc[3], tvec[3];
- if (td->flag & TD_SKIP) {
- continue;
- }
-
- if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f)) {
- continue;
- }
-
- copy_v3_v3(iloc, td->loc);
- if (tc->use_local_mat) {
- mul_m4_v3(tc->mat, iloc);
- }
- else if (t->options & CTX_OBJECT) {
- BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob);
- copy_v3_v3(iloc, td->ob->obmat[3]);
- }
-
- mul_v3_v3fl(loc, iloc, 1.0f / grid_size);
- loc[0] = roundf(loc[0]);
- loc[1] = roundf(loc[1]);
- loc[2] = roundf(loc[2]);
- mul_v3_fl(loc, grid_size);
-
- sub_v3_v3v3(tvec, loc, iloc);
- mul_m3_v3(td->smtx, tvec);
- add_v3_v3(td->loc, tvec);
- }
- }
-}
-
void applySnappingAsGroup(TransInfo *t, float *vec)
{
if (!activeSnap_SnappingAsGroup(t)) {
@@ -722,15 +668,13 @@ static eSnapMode snap_mode_from_spacetype(TransInfo *t)
static eSnapTargetSelect snap_target_select_from_spacetype(TransInfo *t)
{
- ViewLayer *view_layer = t->view_layer;
- Base *base_act = view_layer->basact;
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
+ Base *base_act = BKE_view_layer_active_base_get(t->view_layer);
eSnapTargetSelect ret = SCE_SNAP_TARGET_ALL;
- bool use_snap_active = (t->tsnap.target_select & SCE_SNAP_TARGET_NOT_ACTIVE) == 0;
- bool use_snap_edit = (t->tsnap.target_select & SCE_SNAP_TARGET_NOT_EDITED) == 0;
- bool use_snap_nonedit = (t->tsnap.target_select & SCE_SNAP_TARGET_NOT_NONEDITED) == 0;
- bool use_snap_selectable_only = (t->tsnap.target_select & SCE_SNAP_TARGET_ONLY_SELECTABLE) != 0;
+ /* `t->tsnap.target_select` not initialized yet. */
+ BLI_assert(t->tsnap.target_select == SCE_SNAP_TARGET_ALL);
if (ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE) && !(t->options & CTX_CAMERA)) {
if (base_act && (base_act->object->mode & OB_MODE_PARTICLE_EDIT)) {
@@ -738,10 +682,6 @@ static eSnapTargetSelect snap_target_select_from_spacetype(TransInfo *t)
return ret;
}
- if (use_snap_selectable_only) {
- ret |= SCE_SNAP_TARGET_ONLY_SELECTABLE;
- }
-
if (t->options & (CTX_GPENCIL_STROKES | CTX_CURSOR | CTX_OBMODE_XFORM_OBDATA)) {
/* In "Edit Strokes" mode,
* snap tool can perform snap to selected or active objects (see T49632)
@@ -760,15 +700,6 @@ static eSnapTargetSelect snap_target_select_from_spacetype(TransInfo *t)
/* Exclude editmesh when using proportional edit */
ret |= SCE_SNAP_TARGET_NOT_EDITED;
}
- if (!use_snap_active) {
- ret |= SCE_SNAP_TARGET_NOT_ACTIVE;
- }
- if (!use_snap_edit) {
- ret |= SCE_SNAP_TARGET_NOT_EDITED;
- }
- if (!use_snap_nonedit) {
- ret |= SCE_SNAP_TARGET_NOT_NONEDITED;
- }
}
else if (ELEM(obedit_type, OB_ARMATURE, OB_CURVES_LEGACY, OB_SURF, OB_LATTICE, OB_MBALL)) {
/* Temporary limited to edit mode armature, curves, surfaces, lattices, and metaballs. */
@@ -813,7 +744,7 @@ static void initSnappingMode(TransInfo *t)
(bool (*)(BMVert *, void *))BM_elem_cb_check_hflag_disabled,
bm_edge_is_snap_target,
bm_face_is_snap_target,
- POINTER_FROM_UINT((BM_ELEM_SELECT | BM_ELEM_HIDDEN)));
+ POINTER_FROM_UINT(BM_ELEM_SELECT | BM_ELEM_HIDDEN));
}
else {
/* Ignore hidden geometry in the general case. */
@@ -960,7 +891,8 @@ static void setSnappingCallback(TransInfo *t)
}
else if (t->spacetype == SPACE_IMAGE) {
SpaceImage *sima = t->area->spacedata.first;
- Object *obact = t->view_layer->basact ? t->view_layer->basact->object : NULL;
+ BKE_view_layer_synced_ensure(t->scene, t->view_layer);
+ Object *obact = BKE_view_layer_active_object_get(t->view_layer);
const bool is_uv_editor = sima->mode == SI_MODE_UV;
const bool has_edit_object = obact && BKE_object_is_in_editmode(obact);
@@ -1145,7 +1077,7 @@ static void snap_calc_uv_fn(TransInfo *t, float *UNUSED(vec))
if (t->tsnap.mode & SCE_SNAP_MODE_VERTEX) {
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- t->view_layer, NULL, &objects_len);
+ t->scene, t->view_layer, NULL, &objects_len);
float dist_sq = square_f((float)SNAP_MIN_DISTANCE);
if (ED_uvedit_nearest_uv_multi(&t->region->v2d,
@@ -1205,7 +1137,7 @@ static void snap_calc_sequencer_fn(TransInfo *t, float *UNUSED(vec))
/** \name Target
* \{ */
-static void snap_target_median_impl(TransInfo *t, float r_median[3])
+void tranform_snap_target_median_calc(const TransInfo *t, float r_median[3])
{
int i_accum = 0;
@@ -1241,28 +1173,6 @@ static void snap_target_median_impl(TransInfo *t, float r_median[3])
// TargetSnapOffset(t, NULL);
}
-static void snap_target_grid_ensure(TransInfo *t)
-{
- /* Only need to calculate once. */
- if ((t->tsnap.status & TARGET_GRID_INIT) == 0) {
- if (t->data_type == &TransConvertType_Cursor3D) {
- /* Use a fallback when transforming the cursor.
- * In this case the center is _not_ derived from the cursor which is being transformed. */
- copy_v3_v3(t->tsnap.snapTargetGrid, TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->data->iloc);
- }
- else if (t->around == V3D_AROUND_CURSOR) {
- /* Use a fallback for cursor selection,
- * this isn't useful as a global center for absolute grid snapping
- * since its not based on the position of the selection. */
- snap_target_median_impl(t, t->tsnap.snapTargetGrid);
- }
- else {
- copy_v3_v3(t->tsnap.snapTargetGrid, t->center_global);
- }
- t->tsnap.status |= TARGET_GRID_INIT;
- }
-}
-
static void TargetSnapOffset(TransInfo *t, TransData *td)
{
if (t->spacetype == SPACE_NODE && td != NULL) {
@@ -1334,7 +1244,7 @@ static void TargetSnapMedian(TransInfo *t)
{
/* Only need to calculate once. */
if ((t->tsnap.status & TARGET_INIT) == 0) {
- snap_target_median_impl(t, t->tsnap.snapTarget);
+ tranform_snap_target_median_calc(t, t->tsnap.snapTarget);
t->tsnap.status |= TARGET_INIT;
}
}
@@ -1672,61 +1582,6 @@ bool snapNodesTransform(
/** \name snap Grid
* \{ */
-static void snap_grid_apply(
- TransInfo *t, const int max_index, const float grid_dist, const float loc[3], float r_out[3])
-{
- BLI_assert(max_index <= 2);
- snap_target_grid_ensure(t);
- const float *center_global = t->tsnap.snapTargetGrid;
- const float *asp = t->aspect;
-
- float in[3];
- if (t->con.mode & CON_APPLY) {
- BLI_assert(t->tsnap.snapElem == SCE_SNAP_MODE_NONE);
- t->con.applyVec(t, NULL, NULL, loc, in);
- }
- else {
- copy_v3_v3(in, loc);
- }
-
- for (int i = 0; i <= max_index; i++) {
- const float iter_fac = grid_dist * asp[i];
- r_out[i] = iter_fac * roundf((in[i] + center_global[i]) / iter_fac) - center_global[i];
- }
-}
-
-bool transform_snap_grid(TransInfo *t, float *val)
-{
- if (!activeSnap(t)) {
- return false;
- }
-
- if ((!(t->tsnap.mode & SCE_SNAP_MODE_GRID)) || validSnap(t)) {
- /* Don't do grid snapping if there is a valid snap point. */
- return false;
- }
-
- /* Don't do grid snapping if not in 3D viewport or UV editor */
- if (!ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE)) {
- return false;
- }
-
- if (t->mode != TFM_TRANSLATION) {
- return false;
- }
-
- float grid_dist = (t->modifiers & MOD_PRECISION) ? t->snap[1] : t->snap[0];
-
- /* Early bailing out if no need to snap */
- if (grid_dist == 0.0f) {
- return false;
- }
-
- snap_grid_apply(t, t->idx_max, grid_dist, val, val);
- t->tsnap.snapElem = SCE_SNAP_MODE_GRID;
- return true;
-}
-
static void snap_increment_apply_ex(const TransInfo *UNUSED(t),
const int max_index,
const float increment_val,
diff --git a/source/blender/editors/transform/transform_snap.h b/source/blender/editors/transform/transform_snap.h
index 3672e76c778..16d9062e978 100644
--- a/source/blender/editors/transform/transform_snap.h
+++ b/source/blender/editors/transform/transform_snap.h
@@ -11,6 +11,10 @@
/* For enum. */
#include "DNA_space_types.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
bool peelObjectsTransform(struct TransInfo *t,
const float mval[2],
bool use_peel_object,
@@ -34,10 +38,10 @@ bool snapNodesTransform(struct TransInfo *t,
bool transformModeUseSnap(const TransInfo *t);
+void tranform_snap_target_median_calc(const TransInfo *t, float r_median[3]);
bool transform_snap_increment_ex(const TransInfo *t, bool use_local_space, float *r_val);
bool transform_snap_increment(const TransInfo *t, float *val);
float transform_snap_increment_get(const TransInfo *t);
-bool transform_snap_grid(TransInfo *t, float *val);
bool activeSnap(const TransInfo *t);
bool activeSnap_SnappingIndividual(const TransInfo *t);
@@ -48,7 +52,6 @@ bool validSnap(const TransInfo *t);
void initSnapping(struct TransInfo *t, struct wmOperator *op);
void freeSnapping(struct TransInfo *t);
void applySnappingIndividual(TransInfo *t);
-void applyGridAbsolute(TransInfo *t);
void applySnappingAsGroup(TransInfo *t, float *vec);
void resetSnapping(TransInfo *t);
eRedrawFlag handleSnapping(TransInfo *t, const struct wmEvent *event);
@@ -92,3 +95,7 @@ void transform_snap_anim_flush_data(TransInfo *t,
TransData *td,
eAnimEdit_AutoSnap autosnap,
float *r_val_final);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/editors/transform/transform_snap_animation.c b/source/blender/editors/transform/transform_snap_animation.c
index e4273affdb6..fbb7c812525 100644
--- a/source/blender/editors/transform/transform_snap_animation.c
+++ b/source/blender/editors/transform/transform_snap_animation.c
@@ -115,7 +115,7 @@ void transform_snap_anim_flush_data(TransInfo *t,
float val = td->loc[0];
float ival = td->iloc[0];
- AnimData *adt = (!ELEM(t->spacetype, SPACE_NLA, SPACE_SEQ)) ? td->extra : NULL;
+ AnimData *adt = !ELEM(t->spacetype, SPACE_NLA, SPACE_SEQ) ? td->extra : NULL;
/* Convert frame to nla-action time (if needed) */
if (adt) {
diff --git a/source/blender/editors/transform/transform_snap_object.cc b/source/blender/editors/transform/transform_snap_object.cc
index c72511d213d..87c467d44d8 100644
--- a/source/blender/editors/transform/transform_snap_object.cc
+++ b/source/blender/editors/transform/transform_snap_object.cc
@@ -35,6 +35,7 @@
#include "BKE_layer.h"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
+#include "BKE_mesh_wrapper.h"
#include "BKE_object.h"
#include "BKE_tracking.h"
@@ -61,41 +62,6 @@ enum eViewProj {
VIEW_PROJ_PERSP = -1,
};
-/* SnapObjectContext.cache.mesh_map */
-struct SnapData_Mesh {
- /* Loose edges, loose verts. */
- BVHTree *bvhtree[2];
- bool cached[2];
-
- /* Looptris. */
- BVHTreeFromMesh treedata_mesh;
-
- const MPoly *poly;
- bool has_looptris;
- bool has_loose_edge;
- bool has_loose_vert;
-
- void clear()
- {
- for (int i = 0; i < ARRAY_SIZE(this->bvhtree); i++) {
- if (!this->cached[i]) {
- BLI_bvhtree_free(this->bvhtree[i]);
- }
- this->bvhtree[i] = nullptr;
- }
- free_bvhtree_from_mesh(&this->treedata_mesh);
- }
-
- ~SnapData_Mesh()
- {
- this->clear();
- }
-
-#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("SnapData_Mesh")
-#endif
-};
-
/* SnapObjectContext.cache.editmesh_map */
struct SnapData_EditMesh {
/* Verts, Edges. */
@@ -105,7 +71,7 @@ struct SnapData_EditMesh {
/* Looptris. */
BVHTreeFromEditMesh treedata_editmesh;
- struct Mesh_Runtime *mesh_runtime;
+ blender::bke::MeshRuntime *mesh_runtime;
float min[3], max[3];
void clear()
@@ -134,7 +100,6 @@ struct SnapObjectContext {
int flag;
- Map<const Object *, std::unique_ptr<SnapData_Mesh>> mesh_caches;
Map<const BMEditMesh *, std::unique_ptr<SnapData_EditMesh>> editmesh_caches;
/* Filter data, returns true to check this value */
@@ -161,6 +126,28 @@ struct SnapObjectContext {
eSnapMode snap_to_flag;
bool has_occlusion_plane; /* Ignore plane of occlusion in curves. */
} runtime;
+
+ /* Output. */
+ struct {
+ /* Location of snapped point on target surface. */
+ float loc[3];
+ /* Normal of snapped point on target surface. */
+ float no[3];
+ /* Index of snapped element on target object (-1 when no valid index is found). */
+ int index;
+ /* Matrix of target object (may not be #Object.object_to_world with dupli-instances). */
+ float obmat[4][4];
+ /* List of #SnapObjectHitDepth (caller must free). */
+ ListBase *hit_list;
+ /* Snapped object. */
+ Object *ob;
+ /* Snapped data. */
+ ID *data;
+
+ float dist_sq;
+
+ bool is_edit;
+ } ret;
};
/** \} */
@@ -176,37 +163,48 @@ struct SnapObjectContext {
* - In rare cases there is no evaluated mesh available and a null result doesn't imply an
* edit-mesh, so callers need to account for a null edit-mesh too, see: T96536.
*/
-static const Mesh *mesh_for_snap(Object *ob_eval, eSnapEditType edit_mode_type, bool *r_use_hide)
+static ID *data_for_snap(Object *ob_eval, eSnapEditType edit_mode_type, bool *r_use_hide)
{
- const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
bool use_hide = false;
- if (BKE_object_is_in_editmode(ob_eval)) {
- if (edit_mode_type == SNAP_GEOM_EDIT) {
- return nullptr;
- }
- const Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob_eval);
- const Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob_eval);
+ switch (ob_eval->type) {
+ case OB_MESH: {
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
+ if (BKE_object_is_in_editmode(ob_eval)) {
+ if (edit_mode_type == SNAP_GEOM_EDIT) {
+ return nullptr;
+ }
+
+ Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob_eval);
+ Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob_eval);
- if ((edit_mode_type == SNAP_GEOM_FINAL) && editmesh_eval_final) {
- if (editmesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
- return nullptr;
+ if ((edit_mode_type == SNAP_GEOM_FINAL) && editmesh_eval_final) {
+ if (editmesh_eval_final->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
+ return nullptr;
+ }
+ me_eval = editmesh_eval_final;
+ use_hide = true;
+ }
+ else if ((edit_mode_type == SNAP_GEOM_CAGE) && editmesh_eval_cage) {
+ if (editmesh_eval_cage->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
+ return nullptr;
+ }
+ me_eval = editmesh_eval_cage;
+ use_hide = true;
+ }
}
- me_eval = editmesh_eval_final;
- use_hide = true;
- }
- else if ((edit_mode_type == SNAP_GEOM_CAGE) && editmesh_eval_cage) {
- if (editmesh_eval_cage->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
- return nullptr;
+ if (r_use_hide) {
+ *r_use_hide = use_hide;
}
- me_eval = editmesh_eval_cage;
- use_hide = true;
+ return (ID *)me_eval;
}
+ default:
+ break;
}
if (r_use_hide) {
*r_use_hide = use_hide;
}
- return me_eval;
+ return (ID *)ob_eval->data;
}
/** \} */
@@ -236,113 +234,49 @@ static void snap_editmesh_minmax(SnapObjectContext *sctx,
}
}
-static SnapData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx,
- Object *ob_eval,
- const Mesh *me_eval,
- bool use_hide)
+static void snap_object_data_mesh_get(SnapObjectContext *sctx,
+ Object *ob_eval,
+ const Mesh *me_eval,
+ bool use_hide,
+ BVHTreeFromMesh *r_treedata)
{
- SnapData_Mesh *sod;
- bool init = false;
-
const Span<MVert> verts = me_eval->verts();
- const Span<MEdge> edges = me_eval->edges();
const Span<MPoly> polys = me_eval->polys();
const Span<MLoop> loops = me_eval->loops();
- if (std::unique_ptr<SnapData_Mesh> *sod_p = sctx->mesh_caches.lookup_ptr(ob_eval)) {
- sod = sod_p->get();
- bool is_dirty = false;
- if (sod->treedata_mesh.tree && sod->treedata_mesh.cached &&
- !bvhcache_has_tree(me_eval->runtime.bvh_cache, sod->treedata_mesh.tree)) {
- /* The tree is owned by the Mesh and may have been freed since we last used. */
- is_dirty = true;
- }
- else if (sod->bvhtree[0] && sod->cached[0] &&
- !bvhcache_has_tree(me_eval->runtime.bvh_cache, sod->bvhtree[0])) {
- /* The tree is owned by the Mesh and may have been freed since we last used. */
- is_dirty = true;
- }
- else if (sod->bvhtree[1] && sod->cached[1] &&
- !bvhcache_has_tree(me_eval->runtime.bvh_cache, sod->bvhtree[1])) {
- /* The tree is owned by the Mesh and may have been freed since we last used. */
- is_dirty = true;
- }
- else if (sod->treedata_mesh.looptri != me_eval->runtime.looptris.array) {
- is_dirty = true;
- }
- else if (sod->treedata_mesh.vert != verts.data()) {
- is_dirty = true;
- }
- else if (sod->treedata_mesh.loop != loops.data()) {
- is_dirty = true;
- }
- else if (sod->treedata_mesh.edge != edges.data()) {
- is_dirty = true;
- }
- else if (sod->poly != polys.data()) {
- is_dirty = true;
- }
-
- if (is_dirty) {
- sod->clear();
- init = true;
- }
- }
- else {
- if (ob_eval->type == OB_MESH) {
- /* Any existing #SnapData_EditMesh is now invalid. */
- sctx->editmesh_caches.remove(BKE_editmesh_from_object(ob_eval));
- }
-
- std::unique_ptr<SnapData_Mesh> sod_ptr = std::make_unique<SnapData_Mesh>();
- sod = sod_ptr.get();
- sctx->mesh_caches.add_new(ob_eval, std::move(sod_ptr));
-
- init = true;
+ if (ob_eval->type == OB_MESH) {
+ /* Any existing #SnapData_EditMesh is now invalid. */
+ sctx->editmesh_caches.remove(BKE_editmesh_from_object(ob_eval));
}
- if (init) {
- /* The BVHTree from looptris is always required. */
- BLI_assert(sod->treedata_mesh.tree == nullptr);
- BKE_bvhtree_from_mesh_get(&sod->treedata_mesh,
- me_eval,
- use_hide ? BVHTREE_FROM_LOOPTRI_NO_HIDDEN : BVHTREE_FROM_LOOPTRI,
- 4);
-
- BLI_assert(sod->treedata_mesh.vert == verts.data());
- BLI_assert(!verts.data() || sod->treedata_mesh.vert_normals);
- BLI_assert(sod->treedata_mesh.loop == loops.data());
- BLI_assert(!polys.data() || sod->treedata_mesh.looptri);
+ /* The BVHTree from looptris is always required. */
+ BKE_bvhtree_from_mesh_get(
+ r_treedata, me_eval, use_hide ? BVHTREE_FROM_LOOPTRI_NO_HIDDEN : BVHTREE_FROM_LOOPTRI, 4);
- sod->has_looptris = sod->treedata_mesh.tree != nullptr;
+ BLI_assert(r_treedata->vert == verts.data());
+ BLI_assert(!verts.data() || r_treedata->vert_normals);
+ BLI_assert(r_treedata->loop == loops.data());
+ BLI_assert(!polys.data() || r_treedata->looptri);
+ BLI_assert(!r_treedata->tree || r_treedata->looptri);
- /* Required for snapping with occlusion. */
- sod->treedata_mesh.edge = edges.data();
- sod->poly = polys.data();
-
- /* Start assuming that it has each of these element types. */
- sod->has_loose_edge = true;
- sod->has_loose_vert = true;
- }
-
- return sod;
+ UNUSED_VARS_NDEBUG(verts, polys, loops);
}
/* Searches for the #Mesh_Runtime associated with the object that is most likely to be updated due
* to changes in the `edit_mesh`. */
-static Mesh_Runtime *snap_object_data_editmesh_runtime_get(Object *ob_eval)
+static blender::bke::MeshRuntime *snap_object_data_editmesh_runtime_get(Object *ob_eval)
{
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob_eval);
if (editmesh_eval_final) {
- return &editmesh_eval_final->runtime;
+ return editmesh_eval_final->runtime;
}
Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob_eval);
if (editmesh_eval_cage) {
- return &editmesh_eval_cage->runtime;
+ return editmesh_eval_cage->runtime;
}
- return &((Mesh *)ob_eval->data)->runtime;
+ return ((Mesh *)ob_eval->data)->runtime;
}
static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
@@ -352,9 +286,6 @@ static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
SnapData_EditMesh *sod;
bool init = false;
- /* Any existing #SnapData_Mesh is now invalid. */
- sctx->mesh_caches.remove(ob_eval);
-
if (std::unique_ptr<SnapData_EditMesh> *sod_p = sctx->editmesh_caches.lookup_ptr(em)) {
sod = sod_p->get();
bool is_dirty = false;
@@ -411,15 +342,6 @@ static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
return sod;
}
-static BVHTreeFromMesh *snap_object_data_mesh_treedata_get(SnapObjectContext *sctx,
- Object *ob_eval,
- const Mesh *me_eval,
- bool use_hide)
-{
- SnapData_Mesh *sod = snap_object_data_mesh_get(sctx, ob_eval, me_eval, use_hide);
- return &sod->treedata_mesh;
-}
-
static BVHTreeFromEditMesh *snap_object_data_editmesh_treedata_get(SnapObjectContext *sctx,
Object *ob_eval,
BMEditMesh *em)
@@ -457,7 +379,7 @@ static BVHTreeFromEditMesh *snap_object_data_editmesh_treedata_get(SnapObjectCon
4,
BVHTREE_FROM_EM_LOOPTRI,
&sod->mesh_runtime->bvh_cache,
- static_cast<ThreadMutex *>(sod->mesh_runtime->eval_mutex));
+ &sod->mesh_runtime->eval_mutex);
}
}
if (treedata == nullptr || treedata->tree == nullptr) {
@@ -473,12 +395,14 @@ static BVHTreeFromEditMesh *snap_object_data_editmesh_treedata_get(SnapObjectCon
/** \name Iterator
* \{ */
-using IterSnapObjsCallback = void (*)(SnapObjectContext *sctx,
- const SnapObjectParams *params,
- Object *ob_eval,
- const float obmat[4][4],
- bool is_object_active,
- void *data);
+using IterSnapObjsCallback = eSnapMode (*)(SnapObjectContext *sctx,
+ const SnapObjectParams *params,
+ Object *ob_eval,
+ ID *ob_data,
+ const float obmat[4][4],
+ bool is_object_active,
+ bool use_hide,
+ void *data);
static bool snap_object_is_snappable(const SnapObjectContext *sctx,
const eSnapTargetSelect snap_target_select,
@@ -538,16 +462,21 @@ static bool snap_object_is_snappable(const SnapObjectContext *sctx,
/**
* Walks through all objects in the scene to create the list of objects to snap.
*/
-static void iter_snap_objects(SnapObjectContext *sctx,
- const SnapObjectParams *params,
- IterSnapObjsCallback sob_callback,
- void *data)
+static eSnapMode iter_snap_objects(SnapObjectContext *sctx,
+ const SnapObjectParams *params,
+ IterSnapObjsCallback sob_callback,
+ void *data)
{
+ eSnapMode ret = SCE_SNAP_MODE_NONE;
+ eSnapMode tmp;
+
+ Scene *scene = DEG_get_input_scene(sctx->runtime.depsgraph);
ViewLayer *view_layer = DEG_get_input_view_layer(sctx->runtime.depsgraph);
const eSnapTargetSelect snap_target_select = params->snap_target_select;
- Base *base_act = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *base_act = BKE_view_layer_active_base_get(view_layer);
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (!snap_object_is_snappable(sctx, snap_target_select, base_act, base)) {
continue;
}
@@ -558,19 +487,40 @@ static void iter_snap_objects(SnapObjectContext *sctx,
ListBase *lb = object_duplilist(sctx->runtime.depsgraph, sctx->scene, obj_eval);
LISTBASE_FOREACH (DupliObject *, dupli_ob, lb) {
BLI_assert(DEG_is_evaluated_object(dupli_ob->ob));
- sob_callback(sctx, params, dupli_ob->ob, dupli_ob->mat, is_object_active, data);
+ if ((tmp = sob_callback(sctx,
+ params,
+ dupli_ob->ob,
+ dupli_ob->ob_data,
+ dupli_ob->mat,
+ is_object_active,
+ false,
+ data)) != SCE_SNAP_MODE_NONE) {
+ ret = tmp;
+ }
}
free_object_duplilist(lb);
}
- sob_callback(sctx, params, obj_eval, obj_eval->obmat, is_object_active, data);
+ bool use_hide = false;
+ ID *ob_data = data_for_snap(obj_eval, params->edit_mode_type, &use_hide);
+ if ((tmp = sob_callback(sctx,
+ params,
+ obj_eval,
+ ob_data,
+ obj_eval->object_to_world,
+ is_object_active,
+ use_hide,
+ data)) != SCE_SNAP_MODE_NONE) {
+ ret = tmp;
+ }
}
+ return ret;
}
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Ray Cast Funcs
+/** \name Ray Cast Functions
* \{ */
/* Store all ray-hits
@@ -765,14 +715,17 @@ static bool raycastMesh(SnapObjectContext *sctx,
}
/* Test BoundBox */
- const BoundBox *bb = BKE_object_boundbox_get(ob_eval);
- if (bb) {
- /* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
- if (!isect_ray_aabb_v3_simple(
- ray_start_local, ray_normal_local, bb->vec[0], bb->vec[6], &len_diff, nullptr)) {
- return retval;
+ if (ob_eval->data == me_eval) {
+ const BoundBox *bb = BKE_object_boundbox_get(ob_eval);
+ if (bb) {
+ /* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
+ if (!isect_ray_aabb_v3_simple(
+ ray_start_local, ray_normal_local, bb->vec[0], bb->vec[6], &len_diff, nullptr)) {
+ return retval;
+ }
}
}
+
/* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with
* very far away ray_start values (as returned in case of ortho view3d), see T50486, T38358.
*/
@@ -785,23 +738,22 @@ static bool raycastMesh(SnapObjectContext *sctx,
len_diff = 0.0f;
}
- SnapData_Mesh *sod = snap_object_data_mesh_get(sctx, ob_eval, me_eval, use_hide);
+ BVHTreeFromMesh treedata;
+ snap_object_data_mesh_get(sctx, ob_eval, me_eval, use_hide, &treedata);
- BVHTreeFromMesh *treedata = &sod->treedata_mesh;
-
- if (treedata->tree == nullptr) {
+ if (treedata.tree == nullptr) {
return retval;
}
float timat[3][3]; /* transpose inverse matrix for normals */
transpose_m3_m4(timat, imat);
- BLI_assert(treedata->raycast_callback != nullptr);
+ BLI_assert(treedata.raycast_callback != nullptr);
if (r_hit_list) {
RayCastAll_Data data;
- data.bvhdata = treedata;
- data.raycast_callback = treedata->raycast_callback;
+ data.bvhdata = &treedata;
+ data.raycast_callback = treedata.raycast_callback;
data.obmat = obmat;
data.timat = timat;
data.len_diff = len_diff;
@@ -811,13 +763,8 @@ static bool raycastMesh(SnapObjectContext *sctx,
data.hit_list = r_hit_list;
data.retval = retval;
- BLI_bvhtree_ray_cast_all(treedata->tree,
- ray_start_local,
- ray_normal_local,
- 0.0f,
- *ray_depth,
- raycast_all_cb,
- &data);
+ BLI_bvhtree_ray_cast_all(
+ treedata.tree, ray_start_local, ray_normal_local, 0.0f, *ray_depth, raycast_all_cb, &data);
retval = data.retval;
}
@@ -826,15 +773,15 @@ static bool raycastMesh(SnapObjectContext *sctx,
hit.index = -1;
hit.dist = local_depth;
- if (BLI_bvhtree_ray_cast(treedata->tree,
+ if (BLI_bvhtree_ray_cast(treedata.tree,
ray_start_local,
ray_normal_local,
0.0f,
&hit,
params->use_backface_culling ?
mesh_looptri_raycast_backface_culling_cb :
- treedata->raycast_callback,
- treedata) != -1) {
+ treedata.raycast_callback,
+ &treedata) != -1) {
hit.dist += len_diff;
hit.dist /= local_scale;
if (hit.dist <= *ray_depth) {
@@ -853,7 +800,7 @@ static bool raycastMesh(SnapObjectContext *sctx,
retval = true;
if (r_index) {
- *r_index = treedata->looptri[hit.index].poly;
+ *r_index = treedata.looptri[hit.index].poly;
}
}
}
@@ -1005,26 +952,21 @@ struct RaycastObjUserData {
uint ob_index;
/* read/write args */
float *ray_depth;
- /* return args */
- float *r_loc;
- float *r_no;
- int *r_index;
- Object **r_ob;
- float (*r_obmat)[4];
- ListBase *r_hit_list;
+
bool use_occlusion_test;
- bool ret;
};
/**
* \note Duplicate args here are documented at #snapObjectsRay
*/
-static void raycast_obj_fn(SnapObjectContext *sctx,
- const SnapObjectParams *params,
- Object *ob_eval,
- const float obmat[4][4],
- bool is_object_active,
- void *data)
+static eSnapMode raycast_obj_fn(SnapObjectContext *sctx,
+ const SnapObjectParams *params,
+ Object *ob_eval,
+ ID *ob_data,
+ const float obmat[4][4],
+ bool is_object_active,
+ bool use_hide,
+ void *data)
{
RaycastObjUserData *dt = static_cast<RaycastObjUserData *>(data);
const uint ob_index = dt->ob_index++;
@@ -1033,92 +975,74 @@ static void raycast_obj_fn(SnapObjectContext *sctx,
float *ray_depth = dt->ray_depth;
bool retval = false;
+ bool is_edit = false;
if (use_occlusion_test) {
if (ELEM(ob_eval->dt, OB_BOUNDBOX, OB_WIRE)) {
/* Do not hit objects that are in wire or bounding box
* display mode. */
- return;
+ return SCE_SNAP_MODE_NONE;
}
}
- switch (ob_eval->type) {
- case OB_MESH: {
- const eSnapEditType edit_mode_type = params->edit_mode_type;
- bool use_hide = false;
- const Mesh *me_eval = mesh_for_snap(ob_eval, edit_mode_type, &use_hide);
- if (me_eval == nullptr) {
- BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
- if (UNLIKELY(!em)) { /* See #mesh_for_snap doc-string. */
- return;
- }
- BLI_assert_msg(em == BKE_editmesh_from_object(DEG_get_original_object(ob_eval)),
- "Make sure there is only one pointer for looptris");
- retval = raycastEditMesh(sctx,
- params,
- dt->ray_start,
- dt->ray_dir,
- ob_eval,
- em,
- obmat,
- ob_index,
- ray_depth,
- dt->r_loc,
- dt->r_no,
- dt->r_index,
- dt->r_hit_list);
- break;
+ if (ob_data == nullptr) {
+ if (ob_eval->type == OB_MESH) {
+ BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
+ if (UNLIKELY(!em)) { /* See #mesh_for_snap doc-string. */
+ return SCE_SNAP_MODE_NONE;
}
- retval = raycastMesh(sctx,
- params,
- dt->ray_start,
- dt->ray_dir,
- ob_eval,
- me_eval,
- obmat,
- ob_index,
- use_hide,
- ray_depth,
- dt->r_loc,
- dt->r_no,
- dt->r_index,
- dt->r_hit_list);
- break;
- }
- case OB_CURVES_LEGACY:
- case OB_SURF:
- case OB_FONT: {
- if (!is_object_active) {
- const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
- if (mesh_eval) {
- retval = raycastMesh(sctx,
- params,
- dt->ray_start,
- dt->ray_dir,
- ob_eval,
- mesh_eval,
- obmat,
- ob_index,
- false,
- ray_depth,
- dt->r_loc,
- dt->r_no,
- dt->r_index,
- dt->r_hit_list);
- }
+ if (raycastEditMesh(sctx,
+ params,
+ dt->ray_start,
+ dt->ray_dir,
+ ob_eval,
+ em,
+ obmat,
+ ob_index,
+ ray_depth,
+ sctx->ret.loc,
+ sctx->ret.no,
+ &sctx->ret.index,
+ sctx->ret.hit_list)) {
+ retval = true;
+ is_edit = true;
}
- break;
}
+ else {
+ return SCE_SNAP_MODE_NONE;
+ }
+ }
+ else if (GS(ob_data->name) != ID_ME) {
+ return SCE_SNAP_MODE_NONE;
+ }
+ else if (is_object_active && ELEM(ob_eval->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) {
+ return SCE_SNAP_MODE_NONE;
+ }
+ else {
+ const Mesh *me_eval = (const Mesh *)ob_data;
+ retval = raycastMesh(sctx,
+ params,
+ dt->ray_start,
+ dt->ray_dir,
+ ob_eval,
+ me_eval,
+ obmat,
+ ob_index,
+ use_hide,
+ ray_depth,
+ sctx->ret.loc,
+ sctx->ret.no,
+ &sctx->ret.index,
+ sctx->ret.hit_list);
}
if (retval) {
- if (dt->r_ob) {
- *dt->r_ob = ob_eval;
- }
- if (dt->r_obmat) {
- copy_m4_m4(dt->r_obmat, obmat);
- }
- dt->ret = true;
+ copy_m4_m4(sctx->ret.obmat, obmat);
+ sctx->ret.ob = ob_eval;
+ sctx->ret.data = ob_data;
+ sctx->ret.is_edit = is_edit;
+ return SCE_SNAP_MODE_FACE_RAYCAST;
}
+ return SCE_SNAP_MODE_NONE;
}
/**
@@ -1134,17 +1058,6 @@ static void raycast_obj_fn(SnapObjectContext *sctx,
*
* \param ray_depth: maximum depth allowed for r_co,
* elements deeper than this value will be ignored.
- *
- * Output Args
- * -----------
- *
- * \param r_loc: Hit location.
- * \param r_no: Hit normal (optional).
- * \param r_index: Hit index or -1 when no valid index is found.
- * (currently only set to the polygon index when using `snap_to == SCE_SNAP_MODE_FACE_RAYCAST`).
- * \param r_ob: Hit object.
- * \param r_obmat: Object matrix (may not be #Object.obmat with dupli-instances).
- * \param r_hit_list: List of #SnapObjectHitDepth (caller must free).
*/
static bool raycastObjects(SnapObjectContext *sctx,
const SnapObjectParams *params,
@@ -1153,14 +1066,7 @@ static bool raycastObjects(SnapObjectContext *sctx,
/* read/write args */
/* Parameters below cannot be const, because they are assigned to a
* non-const variable (readability-non-const-parameter). */
- float *ray_depth /* NOLINT */,
- /* return args */
- float r_loc[3] /* NOLINT */,
- float r_no[3] /* NOLINT */,
- int *r_index /* NOLINT */,
- Object **r_ob,
- float r_obmat[4][4],
- ListBase *r_hit_list)
+ float *ray_depth /* NOLINT */)
{
const View3D *v3d = sctx->runtime.v3d;
if (params->use_occlusion_test && v3d && XRAY_FLAG_ENABLED(v3d)) {
@@ -1176,38 +1082,20 @@ static bool raycastObjects(SnapObjectContext *sctx,
data.ray_dir = ray_dir;
data.ob_index = 0;
data.ray_depth = ray_depth;
- data.r_loc = r_loc;
- data.r_no = r_no;
- data.r_index = r_index;
- data.r_ob = r_ob;
- data.r_obmat = r_obmat;
- data.r_hit_list = r_hit_list;
data.use_occlusion_test = params->use_occlusion_test;
- data.ret = false;
- iter_snap_objects(sctx, params, raycast_obj_fn, &data);
-
- return data.ret;
+ return iter_snap_objects(sctx, params, raycast_obj_fn, &data) != SCE_SNAP_MODE_NONE;
}
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Surface Snap Funcs
+/** \name Surface Snap Functions
* \{ */
struct NearestWorldObjUserData {
const float *init_co;
const float *curr_co;
- /* return args */
- float *r_loc;
- float *r_no;
- int *r_index;
- float r_dist_sq;
- Object **r_ob;
- float (*r_obmat)[4];
- ListBase *r_hit_list;
- bool ret;
};
static void nearest_world_tree_co(BVHTree *tree,
@@ -1242,7 +1130,7 @@ static void nearest_world_tree_co(BVHTree *tree,
}
}
-static bool nearest_world_tree(SnapObjectContext *UNUSED(sctx),
+static bool nearest_world_tree(SnapObjectContext * /*sctx*/,
const struct SnapObjectParams *params,
BVHTree *tree,
BVHTree_NearestPointCallback nearest_cb,
@@ -1291,19 +1179,18 @@ static bool nearest_world_tree(SnapObjectContext *UNUSED(sctx),
*r_dist_sq = dist_sq;
/* scale to make `snap_face_nearest_steps` steps */
- float step_scale_factor = 1.0f / max_ff(1.0f, (float)params->face_nearest_steps);
+ float step_scale_factor = 1.0f / max_ff(1.0f, float(params->face_nearest_steps));
mul_v3_fl(delta_local, step_scale_factor);
float co_local[3];
float no_local[3];
- int index;
copy_v3_v3(co_local, init_co_local);
for (int i = 0; i < params->face_nearest_steps; i++) {
add_v3_v3(co_local, delta_local);
nearest_world_tree_co(
- tree, nearest_cb, treedata, co_local, co_local, no_local, &index, nullptr);
+ tree, nearest_cb, treedata, co_local, co_local, no_local, r_index, nullptr);
}
mul_v3_m4v3(r_loc, obmat, co_local);
@@ -1313,10 +1200,6 @@ static bool nearest_world_tree(SnapObjectContext *UNUSED(sctx),
normalize_v3(r_no);
}
- if (r_index) {
- *r_index = index;
- }
-
return true;
}
@@ -1333,16 +1216,17 @@ static bool nearest_world_mesh(SnapObjectContext *sctx,
float *r_no,
int *r_index)
{
- BVHTreeFromMesh *treedata = snap_object_data_mesh_treedata_get(sctx, ob_eval, me_eval, use_hide);
- if (treedata == nullptr || treedata->tree == nullptr) {
+ BVHTreeFromMesh treedata;
+ snap_object_data_mesh_get(sctx, ob_eval, me_eval, use_hide, &treedata);
+ if (treedata.tree == nullptr) {
return false;
}
return nearest_world_tree(sctx,
params,
- treedata->tree,
- treedata->nearest_callback,
- treedata,
+ treedata.tree,
+ treedata.nearest_callback,
+ &treedata,
obmat,
init_co,
curr_co,
@@ -1382,85 +1266,75 @@ static bool nearest_world_editmesh(SnapObjectContext *sctx,
r_no,
r_index);
}
-static void nearest_world_object_fn(SnapObjectContext *sctx,
- const struct SnapObjectParams *params,
- Object *ob_eval,
- const float obmat[4][4],
- bool is_object_active,
- void *data)
+static eSnapMode nearest_world_object_fn(SnapObjectContext *sctx,
+ const SnapObjectParams *params,
+ Object *ob_eval,
+ ID *ob_data,
+ const float obmat[4][4],
+ bool is_object_active,
+ bool use_hide,
+ void *data)
{
struct NearestWorldObjUserData *dt = static_cast<NearestWorldObjUserData *>(data);
bool retval = false;
- switch (ob_eval->type) {
- case OB_MESH: {
- const eSnapEditType edit_mode_type = params->edit_mode_type;
- bool use_hide = false;
- const Mesh *me_eval = mesh_for_snap(ob_eval, edit_mode_type, &use_hide);
- if (me_eval) {
- retval = nearest_world_mesh(sctx,
- params,
- ob_eval,
- me_eval,
- obmat,
- use_hide,
- dt->init_co,
- dt->curr_co,
- &dt->r_dist_sq,
- dt->r_loc,
- dt->r_no,
- dt->r_index);
+ bool is_edit = false;
+
+ if (ob_data == nullptr) {
+ if (ob_eval->type == OB_MESH) {
+ BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
+ if (UNLIKELY(!em)) { /* See #data_for_snap doc-string. */
+ return SCE_SNAP_MODE_NONE;
}
- else {
- BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
- BLI_assert_msg(em == BKE_editmesh_from_object(DEG_get_original_object(ob_eval)),
- "Make sure there is only one pointer for looptris");
- retval = nearest_world_editmesh(sctx,
- params,
- ob_eval,
- em,
- obmat,
- dt->init_co,
- dt->curr_co,
- &dt->r_dist_sq,
- dt->r_loc,
- dt->r_no,
- dt->r_index);
+ if (nearest_world_editmesh(sctx,
+ params,
+ ob_eval,
+ em,
+ obmat,
+ dt->init_co,
+ dt->curr_co,
+ &sctx->ret.dist_sq,
+ sctx->ret.loc,
+ sctx->ret.no,
+ &sctx->ret.index)) {
+ retval = true;
+ is_edit = true;
}
- break;
}
- case OB_CURVES_LEGACY:
- case OB_SURF:
- case OB_FONT:
- if (!is_object_active) {
- const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
- if (me_eval) {
- retval = nearest_world_mesh(sctx,
- params,
- ob_eval,
- me_eval,
- obmat,
- false,
- dt->init_co,
- dt->curr_co,
- &dt->r_dist_sq,
- dt->r_loc,
- dt->r_no,
- dt->r_index);
- }
- }
- break;
+ else {
+ return SCE_SNAP_MODE_NONE;
+ }
+ }
+ else if (GS(ob_data) != ID_ME) {
+ return SCE_SNAP_MODE_NONE;
+ }
+ else if (is_object_active && ELEM(ob_eval->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) {
+ return SCE_SNAP_MODE_NONE;
+ }
+ else {
+ const Mesh *me_eval = (const Mesh *)ob_data;
+ retval = nearest_world_mesh(sctx,
+ params,
+ ob_eval,
+ me_eval,
+ obmat,
+ use_hide,
+ dt->init_co,
+ dt->curr_co,
+ &sctx->ret.dist_sq,
+ sctx->ret.loc,
+ sctx->ret.no,
+ &sctx->ret.index);
}
if (retval) {
- if (dt->r_ob) {
- *dt->r_ob = ob_eval;
- }
- if (dt->r_obmat) {
- copy_m4_m4(dt->r_obmat, obmat);
- }
- dt->ret = true;
+ copy_m4_m4(sctx->ret.obmat, obmat);
+ sctx->ret.ob = ob_eval;
+ sctx->ret.data = ob_data;
+ sctx->ret.is_edit = is_edit;
+ return SCE_SNAP_MODE_FACE_NEAREST;
}
+ return SCE_SNAP_MODE_NONE;
}
/**
@@ -1473,39 +1347,17 @@ static void nearest_world_object_fn(SnapObjectContext *sctx,
* \param params: Settings for snapping.
* \param init_co: Initial location of source point.
* \param prev_co: Current location of source point after transformation but before snapping.
- *
- * Output Args
- * -----------
- *
- * \param r_loc: Location of nearest point on target surface.
- * \param r_no: Normal of nearest point on target surface.
- * \param r_index: Index of nearest polygon on target surface.
- * \param r_ob: Nearest target object.
- * \param r_obmat: Nearest target matrix (may not be #Object.obmat with dupli-instances).
*/
static bool nearestWorldObjects(SnapObjectContext *sctx,
const struct SnapObjectParams *params,
const float init_co[3],
- const float curr_co[3],
- float *r_loc /* NOLINT */,
- float *r_no /* NOLINT */,
- int *r_index /* NOLINT */,
- Object **r_ob,
- float r_obmat[4][4])
+ const float curr_co[3])
{
NearestWorldObjUserData data = {};
data.init_co = init_co;
data.curr_co = curr_co;
- data.r_loc = r_loc;
- data.r_no = r_no;
- data.r_index = r_index;
- data.r_dist_sq = FLT_MAX;
- data.r_ob = r_ob;
- data.r_obmat = r_obmat;
- data.ret = false;
-
- iter_snap_objects(sctx, params, nearest_world_object_fn, &data);
- return data.ret;
+
+ return iter_snap_objects(sctx, params, nearest_world_object_fn, &data) != SCE_SNAP_MODE_NONE;
}
/** \} */
@@ -1852,7 +1704,7 @@ static void cb_snap_tri_verts(void *userdata,
}
}
-static void nearest2d_data_init_mesh(SnapData_Mesh *sod,
+static void nearest2d_data_init_mesh(const Mesh *mesh,
bool is_persp,
bool use_backface_culling,
Nearest2dUserData *r_nearest2d)
@@ -1863,11 +1715,11 @@ static void nearest2d_data_init_mesh(SnapData_Mesh *sod,
r_nearest2d->get_tri_verts_index = cb_mlooptri_verts_get;
r_nearest2d->get_tri_edges_index = cb_mlooptri_edges_get;
- r_nearest2d->vert = sod->treedata_mesh.vert;
- r_nearest2d->vert_normals = sod->treedata_mesh.vert_normals;
- r_nearest2d->edge = sod->treedata_mesh.edge;
- r_nearest2d->loop = sod->treedata_mesh.loop;
- r_nearest2d->looptri = sod->treedata_mesh.looptri;
+ r_nearest2d->vert = mesh->verts().data();
+ r_nearest2d->vert_normals = BKE_mesh_vertex_normals_ensure(mesh);
+ r_nearest2d->edge = mesh->edges().data();
+ r_nearest2d->loop = mesh->loops().data();
+ r_nearest2d->looptri = BKE_mesh_runtime_looptri_ensure(mesh);
r_nearest2d->is_persp = is_persp;
r_nearest2d->use_backface_culling = use_backface_culling;
@@ -1898,26 +1750,20 @@ static void nearest2d_data_init_editmesh(SnapData_EditMesh *sod,
static eSnapMode snap_mesh_polygon(SnapObjectContext *sctx,
const SnapObjectParams *params,
- Object *ob_eval,
- const float obmat[4][4],
/* read/write args */
- float *dist_px,
- /* return args */
- float r_loc[3],
- float r_no[3],
- int *r_index)
+ float *dist_px)
{
eSnapMode elem = SCE_SNAP_MODE_NONE;
float lpmat[4][4];
- mul_m4_m4m4(lpmat, sctx->runtime.pmat, obmat);
+ mul_m4_m4m4(lpmat, sctx->runtime.pmat, sctx->ret.obmat);
DistProjectedAABBPrecalc neasrest_precalc;
dist_squared_to_projected_aabb_precalc(
&neasrest_precalc, lpmat, sctx->runtime.win_size, sctx->runtime.mval);
float tobmat[4][4], clip_planes_local[MAX_CLIPPLANE_LEN][4];
- transpose_m4_m4(tobmat, obmat);
+ transpose_m4_m4(tobmat, sctx->ret.obmat);
for (int i = sctx->runtime.clip_plane_len; i--;) {
mul_v4_m4v4(clip_planes_local[i], tobmat, sctx->runtime.clip_plane[i]);
}
@@ -1927,23 +1773,23 @@ static eSnapMode snap_mesh_polygon(SnapObjectContext *sctx,
nearest.dist_sq = square_f(*dist_px);
Nearest2dUserData nearest2d;
- std::unique_ptr<SnapData_Mesh> *sod_mesh = sctx->mesh_caches.lookup_ptr(ob_eval);
- if (sod_mesh) {
- nearest2d_data_init_mesh(sod_mesh->get(),
+ const Mesh *mesh = sctx->ret.data && GS(sctx->ret.data->name) == ID_ME ?
+ (const Mesh *)sctx->ret.data :
+ nullptr;
+ if (mesh) {
+ nearest2d_data_init_mesh(mesh,
sctx->runtime.view_proj == VIEW_PROJ_PERSP,
params->use_backface_culling,
&nearest2d);
- BVHTreeFromMesh *treedata = &sod_mesh->get()->treedata_mesh;
-
- const MPoly *mp = &sod_mesh->get()->poly[*r_index];
- const MLoop *ml = &treedata->loop[mp->loopstart];
+ const MPoly *mp = &mesh->polys()[sctx->ret.index];
+ const MLoop *ml = &nearest2d.loop[mp->loopstart];
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) {
elem = SCE_SNAP_MODE_EDGE;
- BLI_assert(treedata->edge != nullptr);
+ BLI_assert(nearest2d.edge != nullptr);
for (int i = mp->totloop; i--; ml++) {
cb_snap_edge(&nearest2d,
- ml->e,
+ (int)ml->e,
&neasrest_precalc,
clip_planes_local,
sctx->runtime.clip_plane_len,
@@ -1954,7 +1800,7 @@ static eSnapMode snap_mesh_polygon(SnapObjectContext *sctx,
elem = SCE_SNAP_MODE_VERTEX;
for (int i = mp->totloop; i--; ml++) {
cb_snap_vert(&nearest2d,
- ml->v,
+ (int)ml->v,
&neasrest_precalc,
clip_planes_local,
sctx->runtime.clip_plane_len,
@@ -1962,10 +1808,10 @@ static eSnapMode snap_mesh_polygon(SnapObjectContext *sctx,
}
}
}
- else {
+ else if (sctx->ret.is_edit) {
/* The object's #BMEditMesh was used to snap instead. */
std::unique_ptr<SnapData_EditMesh> &sod_editmesh = sctx->editmesh_caches.lookup(
- BKE_editmesh_from_object(ob_eval));
+ BKE_editmesh_from_object(sctx->ret.ob));
BLI_assert(sod_editmesh.get() != nullptr);
nearest2d_data_init_editmesh(sod_editmesh.get(),
@@ -1976,7 +1822,7 @@ static eSnapMode snap_mesh_polygon(SnapObjectContext *sctx,
BMEditMesh *em = sod_editmesh->treedata_editmesh.em;
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
- BMFace *f = BM_face_at_index(em->bm, *r_index);
+ BMFace *f = BM_face_at_index(em->bm, sctx->ret.index);
BMLoop *l_iter, *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) {
@@ -2010,19 +1856,19 @@ static eSnapMode snap_mesh_polygon(SnapObjectContext *sctx,
if (nearest.index != -1) {
*dist_px = sqrtf(nearest.dist_sq);
- copy_v3_v3(r_loc, nearest.co);
- mul_m4_v3(obmat, r_loc);
+ copy_v3_v3(sctx->ret.loc, nearest.co);
+ mul_m4_v3(sctx->ret.obmat, sctx->ret.loc);
- if (r_no) {
+ {
float imat[4][4];
- invert_m4_m4(imat, obmat);
+ invert_m4_m4(imat, sctx->ret.obmat);
- copy_v3_v3(r_no, nearest.no);
- mul_transposed_mat3_m4_v3(imat, r_no);
- normalize_v3(r_no);
+ copy_v3_v3(sctx->ret.no, nearest.no);
+ mul_transposed_mat3_m4_v3(imat, sctx->ret.no);
+ normalize_v3(sctx->ret.no);
}
- *r_index = nearest.index;
+ sctx->ret.index = nearest.index;
return elem;
}
@@ -2031,45 +1877,44 @@ static eSnapMode snap_mesh_polygon(SnapObjectContext *sctx,
static eSnapMode snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
const SnapObjectParams *params,
- Object *ob_eval,
- const float obmat[4][4],
float original_dist_px,
const float prev_co[3],
/* read/write args */
- float *dist_px,
- /* return args */
- float r_loc[3],
- float r_no[3],
- int *r_index)
+ float *dist_px)
{
eSnapMode elem = SCE_SNAP_MODE_EDGE;
- if (ob_eval->type != OB_MESH) {
+ if (sctx->ret.ob->type != OB_MESH) {
return elem;
}
Nearest2dUserData nearest2d;
{
- std::unique_ptr<SnapData_Mesh> *sod_mesh = sctx->mesh_caches.lookup_ptr(ob_eval);
- if (sod_mesh) {
- nearest2d_data_init_mesh(sod_mesh->get(),
+ const Mesh *mesh = sctx->ret.data && GS(sctx->ret.data->name) == ID_ME ?
+ (const Mesh *)sctx->ret.data :
+ nullptr;
+ if (mesh) {
+ nearest2d_data_init_mesh(mesh,
sctx->runtime.view_proj == VIEW_PROJ_PERSP,
params->use_backface_culling,
&nearest2d);
}
- else {
+ else if (sctx->ret.is_edit) {
/* The object's #BMEditMesh was used to snap instead. */
std::unique_ptr<SnapData_EditMesh> &sod_editmesh = sctx->editmesh_caches.lookup(
- BKE_editmesh_from_object(ob_eval));
+ BKE_editmesh_from_object(sctx->ret.ob));
nearest2d_data_init_editmesh(sod_editmesh.get(),
sctx->runtime.view_proj == VIEW_PROJ_PERSP,
params->use_backface_culling,
&nearest2d);
}
+ else {
+ return elem;
+ }
}
int vindex[2];
- nearest2d.get_edge_verts_index(*r_index, &nearest2d, vindex);
+ nearest2d.get_edge_verts_index(sctx->ret.index, &nearest2d, vindex);
const float *v_pair[2];
nearest2d.get_vert_co(vindex[0], &nearest2d, &v_pair[0]);
@@ -2078,7 +1923,7 @@ static eSnapMode snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
DistProjectedAABBPrecalc neasrest_precalc;
{
float lpmat[4][4];
- mul_m4_m4m4(lpmat, sctx->runtime.pmat, obmat);
+ mul_m4_m4m4(lpmat, sctx->runtime.pmat, sctx->ret.obmat);
dist_squared_to_projected_aabb_precalc(
&neasrest_precalc, lpmat, sctx->runtime.win_size, sctx->runtime.mval);
@@ -2116,12 +1961,12 @@ static eSnapMode snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
nearest.co)) {
nearest.index = vindex[v_id];
elem = SCE_SNAP_MODE_VERTEX;
- if (r_no) {
+ {
float imat[4][4];
- invert_m4_m4(imat, obmat);
- nearest2d.copy_vert_no(vindex[v_id], &nearest2d, r_no);
- mul_transposed_mat3_m4_v3(imat, r_no);
- normalize_v3(r_no);
+ invert_m4_m4(imat, sctx->ret.obmat);
+ nearest2d.copy_vert_no(vindex[v_id], &nearest2d, sctx->ret.no);
+ mul_transposed_mat3_m4_v3(imat, sctx->ret.no);
+ normalize_v3(sctx->ret.no);
}
}
}
@@ -2140,7 +1985,7 @@ static eSnapMode snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
vmid,
&nearest.dist_sq,
nearest.co)) {
- nearest.index = *r_index;
+ nearest.index = sctx->ret.index;
elem = SCE_SNAP_MODE_EDGE_MIDPOINT;
}
}
@@ -2149,8 +1994,8 @@ static eSnapMode snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
if (prev_co && (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
float v_near[3], va_g[3], vb_g[3];
- mul_v3_m4v3(va_g, obmat, v_pair[0]);
- mul_v3_m4v3(vb_g, obmat, v_pair[1]);
+ mul_v3_m4v3(va_g, sctx->ret.obmat, v_pair[0]);
+ mul_v3_m4v3(vb_g, sctx->ret.obmat, v_pair[1]);
lambda = line_point_factor_v3(prev_co, va_g, vb_g);
if (IN_RANGE(lambda, 0.0f, 1.0f)) {
@@ -2167,7 +2012,7 @@ static eSnapMode snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
v_near,
&nearest.dist_sq,
nearest.co)) {
- nearest.index = *r_index;
+ nearest.index = sctx->ret.index;
elem = SCE_SNAP_MODE_EDGE_PERPENDICULAR;
}
}
@@ -2178,12 +2023,12 @@ static eSnapMode snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
if (nearest.index != -1) {
*dist_px = sqrtf(nearest.dist_sq);
- copy_v3_v3(r_loc, nearest.co);
+ copy_v3_v3(sctx->ret.loc, nearest.co);
if (elem != SCE_SNAP_MODE_EDGE_PERPENDICULAR) {
- mul_m4_v3(obmat, r_loc);
+ mul_m4_v3(sctx->ret.obmat, sctx->ret.loc);
}
- *r_index = nearest.index;
+ sctx->ret.index = nearest.index;
}
return elem;
@@ -2198,7 +2043,7 @@ static eSnapMode snapArmature(SnapObjectContext *sctx,
float *dist_px,
/* return args */
float r_loc[3],
- float *UNUSED(r_no),
+ float * /*r_no*/,
int *r_index)
{
eSnapMode retval = SCE_SNAP_MODE_NONE;
@@ -2365,7 +2210,7 @@ static eSnapMode snapCurve(SnapObjectContext *sctx,
float *dist_px,
/* return args */
float r_loc[3],
- float *UNUSED(r_no),
+ float * /*r_no*/,
int *r_index)
{
bool has_snap = false;
@@ -2535,7 +2380,7 @@ static eSnapMode snap_object_center(const SnapObjectContext *sctx,
float *dist_px,
/* return args */
float r_loc[3],
- float *UNUSED(r_no),
+ float * /*r_no*/,
int *r_index)
{
eSnapMode retval = SCE_SNAP_MODE_NONE;
@@ -2704,45 +2549,34 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
float dist_px_sq = square_f(*dist_px);
/* Test BoundBox */
- const BoundBox *bb = BKE_object_boundbox_get(ob_eval);
- if (bb &&
- !snap_bound_box_check_dist(
- bb->vec[0], bb->vec[6], lpmat, sctx->runtime.win_size, sctx->runtime.mval, dist_px_sq)) {
- return SCE_SNAP_MODE_NONE;
- }
-
- SnapData_Mesh *sod = snap_object_data_mesh_get(sctx, ob_eval, me_eval, use_hide);
-
- BVHTreeFromMesh *treedata, treedata_tmp;
- treedata = &sod->treedata_mesh;
-
- if (sod->has_loose_edge && sod->bvhtree[0] == nullptr) {
- sod->bvhtree[0] = BKE_bvhtree_from_mesh_get(
- &treedata_tmp, me_eval, BVHTREE_FROM_LOOSEEDGES, 2);
- if (sod->bvhtree[0] == nullptr) {
- sod->has_loose_edge = false;
+ if (ob_eval->data == me_eval) {
+ const BoundBox *bb = BKE_object_boundbox_get(ob_eval);
+ if (!snap_bound_box_check_dist(bb->vec[0],
+ bb->vec[6],
+ lpmat,
+ sctx->runtime.win_size,
+ sctx->runtime.mval,
+ dist_px_sq)) {
+ return SCE_SNAP_MODE_NONE;
}
- sod->cached[0] = treedata_tmp.cached;
}
+ BVHTreeFromMesh treedata, treedata_dummy;
+ snap_object_data_mesh_get(sctx, ob_eval, me_eval, use_hide, &treedata);
+
+ BVHTree *bvhtree[2] = {nullptr};
+ bvhtree[0] = BKE_bvhtree_from_mesh_get(&treedata_dummy, me_eval, BVHTREE_FROM_LOOSEEDGES, 2);
+ BLI_assert(treedata_dummy.cached);
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) {
- if (sod->has_loose_vert && sod->bvhtree[1] == nullptr) {
- sod->bvhtree[1] = BKE_bvhtree_from_mesh_get(
- &treedata_tmp, me_eval, BVHTREE_FROM_LOOSEVERTS, 2);
- if (sod->bvhtree[1] == nullptr) {
- sod->has_loose_vert = false;
- }
- sod->cached[1] = treedata_tmp.cached;
- }
- }
- else {
- /* Not necessary, just to keep the data more consistent. */
- sod->has_loose_vert = false;
+ bvhtree[1] = BKE_bvhtree_from_mesh_get(&treedata_dummy, me_eval, BVHTREE_FROM_LOOSEVERTS, 2);
+ BLI_assert(treedata_dummy.cached);
}
Nearest2dUserData nearest2d;
- nearest2d_data_init_mesh(
- sod, sctx->runtime.view_proj == VIEW_PROJ_PERSP, params->use_backface_culling, &nearest2d);
+ nearest2d_data_init_mesh(me_eval,
+ sctx->runtime.view_proj == VIEW_PROJ_PERSP,
+ params->use_backface_culling,
+ &nearest2d);
BVHTreeNearest nearest{};
nearest.index = -1;
@@ -2757,9 +2591,10 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
mul_v4_m4v4(clip_planes_local[i], tobmat, sctx->runtime.clip_plane[i]);
}
- if (sod->bvhtree[1] && (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX)) {
+ if (bvhtree[1]) {
+ BLI_assert(sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX);
/* snap to loose verts */
- BLI_bvhtree_find_nearest_projected(sod->bvhtree[1],
+ BLI_bvhtree_find_nearest_projected(bvhtree[1],
lpmat,
sctx->runtime.win_size,
sctx->runtime.mval,
@@ -2773,9 +2608,9 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
}
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) {
- if (sod->bvhtree[0]) {
+ if (bvhtree[0]) {
/* snap to loose edges */
- BLI_bvhtree_find_nearest_projected(sod->bvhtree[0],
+ BLI_bvhtree_find_nearest_projected(bvhtree[0],
lpmat,
sctx->runtime.win_size,
sctx->runtime.mval,
@@ -2786,9 +2621,9 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
&nearest2d);
}
- if (treedata->tree) {
+ if (treedata.tree) {
/* snap to looptris */
- BLI_bvhtree_find_nearest_projected(treedata->tree,
+ BLI_bvhtree_find_nearest_projected(treedata.tree,
lpmat,
sctx->runtime.win_size,
sctx->runtime.mval,
@@ -2805,9 +2640,9 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
}
else {
BLI_assert(sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX);
- if (sod->bvhtree[0]) {
+ if (bvhtree[0]) {
/* snap to loose edge verts */
- BLI_bvhtree_find_nearest_projected(sod->bvhtree[0],
+ BLI_bvhtree_find_nearest_projected(bvhtree[0],
lpmat,
sctx->runtime.win_size,
sctx->runtime.mval,
@@ -2818,9 +2653,9 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
&nearest2d);
}
- if (treedata->tree) {
+ if (treedata.tree) {
/* snap to looptri verts */
- BLI_bvhtree_find_nearest_projected(treedata->tree,
+ BLI_bvhtree_find_nearest_projected(treedata.tree,
lpmat,
sctx->runtime.win_size,
sctx->runtime.mval,
@@ -2921,7 +2756,7 @@ static eSnapMode snapEditMesh(SnapObjectContext *sctx,
2,
BVHTREE_FROM_EM_VERTS,
&sod->mesh_runtime->bvh_cache,
- (ThreadMutex *)sod->mesh_runtime->eval_mutex);
+ &sod->mesh_runtime->eval_mutex);
}
sod->bvhtree[0] = treedata.tree;
sod->cached[0] = treedata.cached;
@@ -2953,7 +2788,7 @@ static eSnapMode snapEditMesh(SnapObjectContext *sctx,
2,
BVHTREE_FROM_EM_EDGES,
&sod->mesh_runtime->bvh_cache,
- static_cast<ThreadMutex *>(sod->mesh_runtime->eval_mutex));
+ &sod->mesh_runtime->eval_mutex);
}
sod->bvhtree[1] = treedata.tree;
sod->cached[1] = treedata.cached;
@@ -3040,118 +2875,130 @@ static eSnapMode snapEditMesh(SnapObjectContext *sctx,
struct SnapObjUserData {
/* read/write args */
float *dist_px;
- /* return args */
- float *r_loc;
- float *r_no;
- int *r_index;
- Object **r_ob;
- float (*r_obmat)[4];
- eSnapMode ret;
};
/**
* \note Duplicate args here are documented at #snapObjectsRay
*/
-static void snap_obj_fn(SnapObjectContext *sctx,
- const SnapObjectParams *params,
- Object *ob_eval,
- const float obmat[4][4],
- bool is_object_active,
- void *data)
+static eSnapMode snap_obj_fn(SnapObjectContext *sctx,
+ const SnapObjectParams *params,
+ Object *ob_eval,
+ ID *ob_data,
+ const float obmat[4][4],
+ bool is_object_active,
+ bool use_hide,
+ void *data)
{
SnapObjUserData *dt = static_cast<SnapObjUserData *>(data);
eSnapMode retval = SCE_SNAP_MODE_NONE;
+ bool is_edit = false;
- switch (ob_eval->type) {
- case OB_MESH: {
- const eSnapEditType edit_mode_type = params->edit_mode_type;
- bool use_hide;
- const Mesh *me_eval = mesh_for_snap(ob_eval, edit_mode_type, &use_hide);
- if (me_eval == nullptr) {
- BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
- if (UNLIKELY(!em)) { /* See #mesh_for_snap doc-string. */
- return;
- }
- BLI_assert_msg(em == BKE_editmesh_from_object(DEG_get_original_object(ob_eval)),
- "Make sure there is only one pointer for looptris");
- retval = snapEditMesh(
- sctx, params, ob_eval, em, obmat, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index);
- break;
- }
- if (ob_eval->dt == OB_BOUNDBOX) {
- /* Do not snap to objects that are in bounding box display mode */
- return;
- }
-
- retval = snapMesh(sctx,
- params,
- ob_eval,
- me_eval,
- obmat,
- use_hide,
- dt->dist_px,
- dt->r_loc,
- dt->r_no,
- dt->r_index);
- break;
+ if (ob_data == nullptr && (ob_eval->type == OB_MESH)) {
+ BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
+ if (UNLIKELY(!em)) { /* See #data_for_snap doc-string. */
+ return SCE_SNAP_MODE_NONE;
}
- case OB_ARMATURE:
- retval = snapArmature(sctx,
+ retval = snapEditMesh(sctx,
+ params,
+ ob_eval,
+ em,
+ obmat,
+ dt->dist_px,
+ sctx->ret.loc,
+ sctx->ret.no,
+ &sctx->ret.index);
+ if (retval) {
+ is_edit = true;
+ }
+ }
+ else if (ob_data == nullptr) {
+ retval = snap_object_center(
+ sctx, ob_eval, obmat, dt->dist_px, sctx->ret.loc, sctx->ret.no, &sctx->ret.index);
+ }
+ else {
+ switch (ob_eval->type) {
+ case OB_MESH: {
+ if (ob_eval->dt == OB_BOUNDBOX) {
+ /* Do not snap to objects that are in bounding box display mode */
+ return SCE_SNAP_MODE_NONE;
+ }
+ if (GS(ob_data->name) == ID_ME) {
+ retval = snapMesh(sctx,
params,
ob_eval,
+ (const Mesh *)ob_data,
obmat,
- is_object_active,
+ use_hide,
dt->dist_px,
- dt->r_loc,
- dt->r_no,
- dt->r_index);
- break;
- case OB_CURVES_LEGACY:
- case OB_SURF:
- if (ob_eval->type == OB_CURVES_LEGACY || BKE_object_is_in_editmode(ob_eval)) {
- retval = snapCurve(
- sctx, params, ob_eval, obmat, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index);
- if (params->edit_mode_type != SNAP_GEOM_FINAL) {
- break;
+ sctx->ret.loc,
+ sctx->ret.no,
+ &sctx->ret.index);
}
+ break;
}
- ATTR_FALLTHROUGH;
- case OB_FONT: {
- const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
- if (mesh_eval) {
- retval |= snapMesh(sctx,
- params,
- ob_eval,
- mesh_eval,
- obmat,
- false,
- dt->dist_px,
- dt->r_loc,
- dt->r_no,
- dt->r_index);
+ case OB_ARMATURE:
+ retval = snapArmature(sctx,
+ params,
+ ob_eval,
+ obmat,
+ is_object_active,
+ dt->dist_px,
+ sctx->ret.loc,
+ sctx->ret.no,
+ &sctx->ret.index);
+ break;
+ case OB_CURVES_LEGACY:
+ case OB_SURF:
+ if (ob_eval->type == OB_CURVES_LEGACY || BKE_object_is_in_editmode(ob_eval)) {
+ retval = snapCurve(sctx,
+ params,
+ ob_eval,
+ obmat,
+ dt->dist_px,
+ sctx->ret.loc,
+ sctx->ret.no,
+ &sctx->ret.index);
+ if (params->edit_mode_type != SNAP_GEOM_FINAL) {
+ break;
+ }
+ }
+ ATTR_FALLTHROUGH;
+ case OB_FONT: {
+ const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
+ if (mesh_eval) {
+ retval |= snapMesh(sctx,
+ params,
+ ob_eval,
+ mesh_eval,
+ obmat,
+ false,
+ dt->dist_px,
+ sctx->ret.loc,
+ sctx->ret.no,
+ &sctx->ret.index);
+ }
+ break;
}
- break;
+ case OB_EMPTY:
+ case OB_GPENCIL:
+ case OB_LAMP:
+ retval = snap_object_center(
+ sctx, ob_eval, obmat, dt->dist_px, sctx->ret.loc, sctx->ret.no, &sctx->ret.index);
+ break;
+ case OB_CAMERA:
+ retval = snapCamera(
+ sctx, ob_eval, obmat, dt->dist_px, sctx->ret.loc, sctx->ret.no, &sctx->ret.index);
+ break;
}
- case OB_EMPTY:
- case OB_GPENCIL:
- case OB_LAMP:
- retval = snap_object_center(
- sctx, ob_eval, obmat, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index);
- break;
- case OB_CAMERA:
- retval = snapCamera(sctx, ob_eval, obmat, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index);
- break;
}
if (retval) {
- if (dt->r_ob) {
- *dt->r_ob = ob_eval;
- }
- if (dt->r_obmat) {
- copy_m4_m4(dt->r_obmat, obmat);
- }
- dt->ret = retval;
+ copy_m4_m4(sctx->ret.obmat, obmat);
+ sctx->ret.ob = ob_eval;
+ sctx->ret.data = ob_data;
+ sctx->ret.is_edit = is_edit;
}
+ return retval;
}
/**
@@ -3166,42 +3013,18 @@ static void snap_obj_fn(SnapObjectContext *sctx,
* ---------------
*
* \param dist_px: Maximum threshold distance (in pixels).
- *
- * Output Args
- * -----------
- *
- * \param r_loc: Hit location.
- * \param r_no: Hit normal (optional).
- * \param r_index: Hit index or -1 when no valid index is found.
- * (currently only set to the polygon index when using `snap_to == SCE_SNAP_MODE_FACE_RAYCAST`).
- * \param r_ob: Hit object.
- * \param r_obmat: Object matrix (may not be #Object.obmat with dupli-instances).
*/
static eSnapMode snapObjectsRay(SnapObjectContext *sctx,
const SnapObjectParams *params,
/* read/write args */
/* Parameters below cannot be const, because they are assigned to a
* non-const variable (readability-non-const-parameter). */
- float *dist_px /* NOLINT */,
- /* return args */
- float r_loc[3] /* NOLINT */,
- float r_no[3] /* NOLINT */,
- int *r_index /* NOLINT */,
- Object **r_ob,
- float r_obmat[4][4])
+ float *dist_px /* NOLINT */)
{
SnapObjUserData data = {};
data.dist_px = dist_px;
- data.r_loc = r_loc;
- data.r_no = r_no;
- data.r_ob = r_ob;
- data.r_index = r_index;
- data.r_obmat = r_obmat;
- data.ret = SCE_SNAP_MODE_NONE;
-
- iter_snap_objects(sctx, params, snap_obj_fn, &data);
- return data.ret;
+ return iter_snap_objects(sctx, params, snap_obj_fn, &data);
}
/** \} */
@@ -3256,17 +3079,33 @@ bool ED_transform_snap_object_project_ray_ex(SnapObjectContext *sctx,
sctx->runtime.depsgraph = depsgraph;
sctx->runtime.v3d = v3d;
- return raycastObjects(sctx,
- params,
- ray_start,
- ray_normal,
- ray_depth,
- r_loc,
- r_no,
- r_index,
- r_ob,
- r_obmat,
- nullptr);
+ zero_v3(sctx->ret.loc);
+ zero_v3(sctx->ret.no);
+ sctx->ret.index = -1;
+ zero_m4(sctx->ret.obmat);
+ sctx->ret.hit_list = nullptr;
+ sctx->ret.ob = nullptr;
+ sctx->ret.data = nullptr;
+ sctx->ret.dist_sq = FLT_MAX;
+ sctx->ret.is_edit = false;
+
+ if (raycastObjects(sctx, params, ray_start, ray_normal, ray_depth)) {
+ copy_v3_v3(r_loc, sctx->ret.loc);
+ if (r_no) {
+ copy_v3_v3(r_no, sctx->ret.no);
+ }
+ if (r_index) {
+ *r_index = sctx->ret.index;
+ }
+ if (r_ob) {
+ *r_ob = sctx->ret.ob;
+ }
+ if (r_obmat) {
+ copy_m4_m4(r_obmat, sctx->ret.obmat);
+ }
+ return true;
+ }
+ return false;
}
bool ED_transform_snap_object_project_ray_all(SnapObjectContext *sctx,
@@ -3282,6 +3121,16 @@ bool ED_transform_snap_object_project_ray_all(SnapObjectContext *sctx,
sctx->runtime.depsgraph = depsgraph;
sctx->runtime.v3d = v3d;
+ zero_v3(sctx->ret.loc);
+ zero_v3(sctx->ret.no);
+ sctx->ret.index = -1;
+ zero_m4(sctx->ret.obmat);
+ sctx->ret.hit_list = r_hit_list;
+ sctx->ret.ob = nullptr;
+ sctx->ret.data = nullptr;
+ sctx->ret.dist_sq = FLT_MAX;
+ sctx->ret.is_edit = false;
+
if (ray_depth == -1.0f) {
ray_depth = BVH_RAYCAST_DIST_MAX;
}
@@ -3290,28 +3139,17 @@ bool ED_transform_snap_object_project_ray_all(SnapObjectContext *sctx,
float ray_depth_prev = ray_depth;
#endif
- bool retval = raycastObjects(sctx,
- params,
- ray_start,
- ray_normal,
- &ray_depth,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- r_hit_list);
-
- /* meant to be readonly for 'all' hits, ensure it is */
+ if (raycastObjects(sctx, params, ray_start, ray_normal, &ray_depth)) {
+ if (sort) {
+ BLI_listbase_sort(r_hit_list, hit_depth_cmp);
+ }
+ /* meant to be readonly for 'all' hits, ensure it is */
#ifdef DEBUG
- BLI_assert(ray_depth_prev == ray_depth);
+ BLI_assert(ray_depth_prev == ray_depth);
#endif
-
- if (sort) {
- BLI_listbase_sort(r_hit_list, hit_depth_cmp);
+ return true;
}
-
- return retval;
+ return false;
}
/**
@@ -3391,18 +3229,21 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont
sctx->runtime.region = region;
sctx->runtime.v3d = v3d;
+ zero_v3(sctx->ret.loc);
+ zero_v3(sctx->ret.no);
+ sctx->ret.index = -1;
+ zero_m4(sctx->ret.obmat);
+ sctx->ret.hit_list = nullptr;
+ sctx->ret.ob = nullptr;
+ sctx->ret.data = nullptr;
+ sctx->ret.dist_sq = FLT_MAX;
+ sctx->ret.is_edit = false;
+
BLI_assert((snap_to_flag & SCE_SNAP_MODE_GEOM) != 0);
eSnapMode retval = SCE_SNAP_MODE_NONE;
bool has_hit = false;
- Object *ob_eval = nullptr;
- float loc[3];
- /* Not all snapping callbacks set the normal,
- * initialize this since any hit copies both the `loc` and `no`. */
- float no[3] = {0.0f, 0.0f, 0.0f};
- float obmat[4][4];
- int index = -1;
const RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
@@ -3411,24 +3252,23 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont
/* NOTE: if both face ray-cast and face nearest are enabled, first find result of nearest, then
* override with ray-cast. */
if ((snap_to_flag & SCE_SNAP_MODE_FACE_NEAREST) && !has_hit) {
- has_hit = nearestWorldObjects(
- sctx, params, init_co, prev_co, loc, no, &index, &ob_eval, obmat);
+ has_hit = nearestWorldObjects(sctx, params, init_co, prev_co);
if (has_hit) {
retval = SCE_SNAP_MODE_FACE_NEAREST;
- copy_v3_v3(r_loc, loc);
+ copy_v3_v3(r_loc, sctx->ret.loc);
if (r_no) {
- copy_v3_v3(r_no, no);
+ copy_v3_v3(r_no, sctx->ret.no);
}
if (r_ob) {
- *r_ob = ob_eval;
+ *r_ob = sctx->ret.ob;
}
if (r_obmat) {
- copy_m4_m4(r_obmat, obmat);
+ copy_m4_m4(r_obmat, sctx->ret.obmat);
}
if (r_index) {
- *r_index = index;
+ *r_index = sctx->ret.index;
}
}
}
@@ -3442,38 +3282,28 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont
float dummy_ray_depth = BVH_RAYCAST_DIST_MAX;
- has_hit = raycastObjects(sctx,
- params,
- ray_start,
- ray_normal,
- &dummy_ray_depth,
- loc,
- no,
- &index,
- &ob_eval,
- obmat,
- nullptr);
+ has_hit = raycastObjects(sctx, params, ray_start, ray_normal, &dummy_ray_depth);
if (has_hit) {
if (r_face_nor) {
- copy_v3_v3(r_face_nor, no);
+ copy_v3_v3(r_face_nor, sctx->ret.no);
}
- if ((snap_to_flag & SCE_SNAP_MODE_FACE_RAYCAST)) {
+ if (snap_to_flag & SCE_SNAP_MODE_FACE_RAYCAST) {
retval = SCE_SNAP_MODE_FACE_RAYCAST;
- copy_v3_v3(r_loc, loc);
+ copy_v3_v3(r_loc, sctx->ret.loc);
if (r_no) {
- copy_v3_v3(r_no, no);
+ copy_v3_v3(r_no, sctx->ret.no);
}
if (r_ob) {
- *r_ob = ob_eval;
+ *r_ob = sctx->ret.ob;
}
if (r_obmat) {
- copy_m4_m4(r_obmat, obmat);
+ copy_m4_m4(r_obmat, sctx->ret.obmat);
}
if (r_index) {
- *r_index = index;
+ *r_index = sctx->ret.index;
}
}
}
@@ -3510,11 +3340,11 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont
sctx->runtime.has_occlusion_plane = false;
/* By convention we only snap to the original elements of a curve. */
- if (has_hit && ob_eval->type != OB_CURVES_LEGACY) {
+ if (has_hit && sctx->ret.ob->type != OB_CURVES_LEGACY) {
/* Compute the new clip_pane but do not add it yet. */
float new_clipplane[4];
- BLI_ASSERT_UNIT_V3(no);
- plane_from_point_normal_v3(new_clipplane, loc, no);
+ BLI_ASSERT_UNIT_V3(sctx->ret.no);
+ plane_from_point_normal_v3(new_clipplane, sctx->ret.loc, sctx->ret.no);
if (dot_v3v3(sctx->runtime.clip_plane[0], new_clipplane) > 0.0f) {
/* The plane is facing the wrong direction. */
negate_v4(new_clipplane);
@@ -3524,7 +3354,7 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont
new_clipplane[3] += 0.01f;
/* Try to snap only to the polygon. */
- elem_test = snap_mesh_polygon(sctx, params, ob_eval, obmat, &dist_px_tmp, loc, no, &index);
+ elem_test = snap_mesh_polygon(sctx, params, &dist_px_tmp);
if (elem_test) {
elem = elem_test;
}
@@ -3538,7 +3368,7 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont
sctx->runtime.has_occlusion_plane = true;
}
- elem_test = snapObjectsRay(sctx, params, &dist_px_tmp, loc, no, &index, &ob_eval, obmat);
+ elem_test = snapObjectsRay(sctx, params, &dist_px_tmp);
if (elem_test) {
elem = elem_test;
}
@@ -3547,25 +3377,24 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont
(snap_to_flag & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE_MIDPOINT |
SCE_SNAP_MODE_EDGE_PERPENDICULAR))) {
sctx->runtime.snap_to_flag = snap_to_flag;
- elem = snap_mesh_edge_verts_mixed(
- sctx, params, ob_eval, obmat, *dist_px, prev_co, &dist_px_tmp, loc, no, &index);
+ elem = snap_mesh_edge_verts_mixed(sctx, params, *dist_px, prev_co, &dist_px_tmp);
}
if (elem & snap_to_flag) {
retval = elem;
- copy_v3_v3(r_loc, loc);
+ copy_v3_v3(r_loc, sctx->ret.loc);
if (r_no) {
- copy_v3_v3(r_no, no);
+ copy_v3_v3(r_no, sctx->ret.no);
}
if (r_ob) {
- *r_ob = ob_eval;
+ *r_ob = sctx->ret.ob;
}
if (r_obmat) {
- copy_m4_m4(r_obmat, obmat);
+ copy_m4_m4(r_obmat, sctx->ret.obmat);
}
if (r_index) {
- *r_index = index;
+ *r_index = sctx->ret.index;
}
*dist_px = dist_px_tmp;
diff --git a/source/blender/editors/transform/transform_snap_sequencer.c b/source/blender/editors/transform/transform_snap_sequencer.c
index 06d9bb05206..10a51750ed3 100644
--- a/source/blender/editors/transform/transform_snap_sequencer.c
+++ b/source/blender/editors/transform/transform_snap_sequencer.c
@@ -203,8 +203,10 @@ static void seq_snap_target_points_build(Scene *scene,
i += 2;
if (snap_mode & SEQ_SNAP_TO_STRIP_HOLD) {
- int content_start = min_ii(SEQ_time_right_handle_frame_get(scene, seq), seq->start);
- int content_end = max_ii(SEQ_time_left_handle_frame_get(scene, seq), seq->start + seq->len);
+ int content_start = min_ii(SEQ_time_left_handle_frame_get(scene, seq),
+ SEQ_time_start_frame_get(seq));
+ int content_end = max_ii(SEQ_time_right_handle_frame_get(scene, seq),
+ SEQ_time_content_end_frame_get(scene, seq));
/* Effects and single image strips produce incorrect content length. Skip these strips. */
if ((seq->type & SEQ_TYPE_EFFECT) != 0 || seq->len == 1) {
content_start = SEQ_time_left_handle_frame_get(scene, seq);
diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c
index 40dcb646367..42563cb8f83 100644
--- a/source/blender/editors/undo/ed_undo.c
+++ b/source/blender/editors/undo/ed_undo.c
@@ -433,8 +433,10 @@ bool ED_undo_is_memfile_compatible(const bContext *C)
{
/* Some modes don't co-exist with memfile undo, disable their use: T60593
* (this matches 2.7x behavior). */
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
if (view_layer != NULL) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obact = BKE_view_layer_active_object_get(view_layer);
if (obact != NULL) {
if (obact->mode & OB_MODE_EDIT) {
@@ -447,8 +449,10 @@ bool ED_undo_is_memfile_compatible(const bContext *C)
bool ED_undo_is_legacy_compatible_for_property(struct bContext *C, ID *id)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
if (view_layer != NULL) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obact = BKE_view_layer_active_object_get(view_layer);
if (obact != NULL) {
if (obact->mode & OB_MODE_ALL_PAINT) {
@@ -800,6 +804,7 @@ void ED_OT_undo_history(wmOperatorType *ot)
void ED_undo_object_set_active_or_warn(
Scene *scene, ViewLayer *view_layer, Object *ob, const char *info, CLG_LogRef *log)
{
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob_prev = BKE_view_layer_active_object_get(view_layer);
if (ob_prev != ob) {
Base *base = BKE_view_layer_base_find(view_layer, ob);
@@ -820,15 +825,15 @@ void ED_undo_object_editmode_restore_helper(struct bContext *C,
uint object_array_stride)
{
Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint bases_len = 0;
/* Don't request unique data because we want to de-select objects when exiting edit-mode
* for that to be done on all objects we can't skip ones that share data. */
- Base **bases = ED_undo_editmode_bases_from_view_layer(view_layer, &bases_len);
+ Base **bases = ED_undo_editmode_bases_from_view_layer(scene, view_layer, &bases_len);
for (uint i = 0; i < bases_len; i++) {
((ID *)bases[i]->object->data)->tag |= LIB_TAG_DOIT;
}
- Scene *scene = CTX_data_scene(C);
Object **ob_p = object_array;
for (uint i = 0; i < object_array_len; i++, ob_p = POINTER_OFFSET(ob_p, object_array_stride)) {
Object *obedit = *ob_p;
@@ -859,11 +864,14 @@ void ED_undo_object_editmode_restore_helper(struct bContext *C,
* and local collections may be used.
* \{ */
-static int undo_editmode_objects_from_view_layer_prepare(ViewLayer *view_layer, Object *obact)
+static int undo_editmode_objects_from_view_layer_prepare(const Scene *scene,
+ ViewLayer *view_layer,
+ Object *obact)
{
const short object_type = obact->type;
-
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ ListBase *object_bases = BKE_view_layer_object_bases_get(view_layer);
+ LISTBASE_FOREACH (Base *, base, object_bases) {
Object *ob = base->object;
if ((ob->type == object_type) && (ob->mode & OB_MODE_EDIT)) {
ID *id = ob->data;
@@ -872,7 +880,7 @@ static int undo_editmode_objects_from_view_layer_prepare(ViewLayer *view_layer,
}
int len = 0;
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, object_bases) {
Object *ob = base->object;
if ((ob->type == object_type) && (ob->mode & OB_MODE_EDIT)) {
ID *id = ob->data;
@@ -885,19 +893,23 @@ static int undo_editmode_objects_from_view_layer_prepare(ViewLayer *view_layer,
return len;
}
-Object **ED_undo_editmode_objects_from_view_layer(ViewLayer *view_layer, uint *r_len)
+Object **ED_undo_editmode_objects_from_view_layer(const Scene *scene,
+ ViewLayer *view_layer,
+ uint *r_len)
{
- Base *baseact = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *baseact = BKE_view_layer_active_base_get(view_layer);
if ((baseact == NULL) || (baseact->object->mode & OB_MODE_EDIT) == 0) {
return MEM_mallocN(0, __func__);
}
- const int len = undo_editmode_objects_from_view_layer_prepare(view_layer, baseact->object);
+ const int len = undo_editmode_objects_from_view_layer_prepare(
+ scene, view_layer, baseact->object);
const short object_type = baseact->object->type;
int i = 0;
Object **objects = MEM_malloc_arrayN(len, sizeof(*objects), __func__);
/* Base iteration, starting with the active-base to ensure it's the first item in the array.
* Looping over the active-base twice is OK as the tag check prevents it being handled twice. */
- for (Base *base = baseact, *base_next = view_layer->object_bases.first; base;
+ for (Base *base = baseact, *base_next = BKE_view_layer_object_bases_get(view_layer)->first; base;
base = base_next, base_next = base_next ? base_next->next : NULL) {
Object *ob = base->object;
if ((ob->type == object_type) && (ob->mode & OB_MODE_EDIT)) {
@@ -914,19 +926,25 @@ Object **ED_undo_editmode_objects_from_view_layer(ViewLayer *view_layer, uint *r
return objects;
}
-Base **ED_undo_editmode_bases_from_view_layer(ViewLayer *view_layer, uint *r_len)
+Base **ED_undo_editmode_bases_from_view_layer(const Scene *scene,
+ ViewLayer *view_layer,
+ uint *r_len)
{
- Base *baseact = view_layer->basact;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Base *baseact = BKE_view_layer_active_base_get(view_layer);
if ((baseact == NULL) || (baseact->object->mode & OB_MODE_EDIT) == 0) {
return MEM_mallocN(0, __func__);
}
- const int len = undo_editmode_objects_from_view_layer_prepare(view_layer, baseact->object);
+ const int len = undo_editmode_objects_from_view_layer_prepare(
+ scene, view_layer, baseact->object);
const short object_type = baseact->object->type;
int i = 0;
Base **base_array = MEM_malloc_arrayN(len, sizeof(*base_array), __func__);
/* Base iteration, starting with the active-base to ensure it's the first item in the array.
* Looping over the active-base twice is OK as the tag check prevents it being handled twice. */
- for (Base *base = view_layer->basact, *base_next = view_layer->object_bases.first; base;
+ for (Base *base = BKE_view_layer_active_base_get(view_layer),
+ *base_next = BKE_view_layer_object_bases_get(view_layer)->first;
+ base;
base = base_next, base_next = base_next ? base_next->next : NULL) {
Object *ob = base->object;
if ((ob->type == object_type) && (ob->mode & OB_MODE_EDIT)) {
diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt
index a9e6adc6e60..128cb897ac4 100644
--- a/source/blender/editors/util/CMakeLists.txt
+++ b/source/blender/editors/util/CMakeLists.txt
@@ -28,6 +28,7 @@ set(SRC
ed_util.c
ed_util_imbuf.c
ed_util_ops.cc
+ ed_viewer_path.cc
gizmo_utils.c
numinput.c
select_utils.c
@@ -89,6 +90,7 @@ set(SRC
../include/ED_uvedit.h
../include/ED_view3d.h
../include/ED_view3d_offscreen.h
+ ../include/ED_viewer_path.hh
../include/UI_abstract_view.hh
../include/UI_grid_view.hh
../include/UI_icons.h
diff --git a/source/blender/editors/util/ed_draw.c b/source/blender/editors/util/ed_draw.c
index 7ec3d3c1ef4..80bf732e173 100644
--- a/source/blender/editors/util/ed_draw.c
+++ b/source/blender/editors/util/ed_draw.c
@@ -484,6 +484,7 @@ float ED_slider_factor_get(struct tSlider *slider)
void ED_slider_factor_set(struct tSlider *slider, const float factor)
{
+ slider->raw_factor = factor;
slider->factor = factor;
if (!slider->overshoot) {
slider->factor = clamp_f(slider->factor, 0, 1);
@@ -768,7 +769,7 @@ void ED_region_image_metadata_draw(
GPU_matrix_translate_2f(x, y);
GPU_matrix_scale_2f(zoomx, zoomy);
- BLF_size(blf_mono_font, style->widgetlabel.points * 1.5f * U.pixelsize, U.dpi);
+ BLF_size(blf_mono_font, style->widgetlabel.points * U.dpi_fac);
/* *** upper box*** */
diff --git a/source/blender/editors/util/ed_transverts.c b/source/blender/editors/util/ed_transverts.c
index ef57f9e9b33..334516bfd6c 100644
--- a/source/blender/editors/util/ed_transverts.c
+++ b/source/blender/editors/util/ed_transverts.c
@@ -318,8 +318,8 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, const Object *obedit,
if (ebo->layer & arm->layer) {
const bool tipsel = (ebo->flag & BONE_TIPSEL) != 0;
const bool rootsel = (ebo->flag & BONE_ROOTSEL) != 0;
- const bool rootok = (!(ebo->parent && (ebo->flag & BONE_CONNECTED) &&
- (ebo->parent->flag & BONE_TIPSEL)));
+ const bool rootok = !(ebo->parent && (ebo->flag & BONE_CONNECTED) &&
+ (ebo->parent->flag & BONE_TIPSEL));
if ((tipsel && rootsel) || (rootsel)) {
/* Don't add the tip (unless mode & TM_ALL_JOINTS, for getting all joints),
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index e70851aedd6..92d65688bf1 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -54,22 +54,19 @@
#include "WM_api.h"
#include "WM_types.h"
-/* ********* general editor util funcs, not BKE stuff please! ********* */
+/* ********* general editor util functions, not BKE stuff please! ********* */
void ED_editors_init_for_undo(Main *bmain)
{
wmWindowManager *wm = bmain->wm.first;
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
+ Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Base *base = view_layer->basact;
- if (base != NULL) {
- Object *ob = base->object;
- if (ob->mode & OB_MODE_TEXTURE_PAINT) {
- Scene *scene = WM_window_get_active_scene(win);
-
- BKE_texpaint_slots_refresh_object(scene, ob);
- ED_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
- }
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *ob = BKE_view_layer_active_object_get(view_layer);
+ if (ob && (ob->mode & OB_MODE_TEXTURE_PAINT)) {
+ BKE_texpaint_slots_refresh_object(scene, ob);
+ ED_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
}
}
}
@@ -377,7 +374,7 @@ void unpack_menu(bContext *C,
char local_name[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
BLI_split_file_part(abs_name, fi, sizeof(fi));
- BLI_path_join(local_name, sizeof(local_name), "//", folder, fi, NULL);
+ BLI_path_join(local_name, sizeof(local_name), "//", folder, fi);
if (!STREQ(abs_name, local_name)) {
switch (BKE_packedfile_compare_to_file(blendfile_path, local_name, pf)) {
case PF_CMP_NOFILE:
diff --git a/source/blender/editors/util/ed_util_imbuf.c b/source/blender/editors/util/ed_util_imbuf.c
index f222f93d2b6..b1c8fc42d08 100644
--- a/source/blender/editors/util/ed_util_imbuf.c
+++ b/source/blender/editors/util/ed_util_imbuf.c
@@ -52,13 +52,13 @@ typedef struct ImageSampleInfo {
int width, height;
int sample_size;
- unsigned char col[4];
+ uchar col[4];
float colf[4];
float linearcol[4];
int z;
float zf;
- unsigned char *colp;
+ uchar *colp;
const float *colfp;
int *zp;
float *zfp;
@@ -79,7 +79,7 @@ static void image_sample_pixel_color_ubyte(const ImBuf *ibuf,
uchar r_col[4],
float r_col_linear[4])
{
- const uchar *cp = (unsigned char *)(ibuf->rect + coord[1] * ibuf->x + coord[0]);
+ const uchar *cp = (uchar *)(ibuf->rect + coord[1] * ibuf->x + coord[0]);
copy_v4_v4_uchar(r_col, cp);
rgba_uchar_to_float(r_col_linear, r_col);
IMB_colormanagement_colorspace_to_scene_linear_v4(r_col_linear, false, ibuf->rect_colorspace);
@@ -311,7 +311,7 @@ static void sequencer_sample_apply(bContext *C, wmOperator *op, const wmEvent *e
if (fx >= 0.0f && fy >= 0.0f && fx < ibuf->x && fy < ibuf->y) {
const float *fp;
- unsigned char *cp;
+ uchar *cp;
int x = (int)fx, y = (int)fy;
info->x = x;
@@ -323,7 +323,7 @@ static void sequencer_sample_apply(bContext *C, wmOperator *op, const wmEvent *e
info->colfp = NULL;
if (ibuf->rect) {
- cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x);
+ cp = (uchar *)(ibuf->rect + y * ibuf->x + x);
info->col[0] = cp[0];
info->col[1] = cp[1];
diff --git a/source/blender/editors/util/ed_util_ops.cc b/source/blender/editors/util/ed_util_ops.cc
index af3589e50f0..18d47af7854 100644
--- a/source/blender/editors/util/ed_util_ops.cc
+++ b/source/blender/editors/util/ed_util_ops.cc
@@ -125,7 +125,7 @@ static bool lib_id_generate_preview_poll(bContext *C)
return true;
}
-static int lib_id_generate_preview_exec(bContext *C, wmOperator *UNUSED(op))
+static int lib_id_generate_preview_exec(bContext *C, wmOperator * /*op*/)
{
PointerRNA idptr = CTX_data_pointer_get(C, "id");
ID *id = (ID *)idptr.data;
@@ -170,7 +170,7 @@ static bool lib_id_generate_preview_from_object_poll(bContext *C)
return true;
}
-static int lib_id_generate_preview_from_object_exec(bContext *C, wmOperator *UNUSED(op))
+static int lib_id_generate_preview_from_object_exec(bContext *C, wmOperator * /*op*/)
{
PointerRNA idptr = CTX_data_pointer_get(C, "id");
ID *id = (ID *)idptr.data;
@@ -229,7 +229,7 @@ static int lib_id_fake_user_toggle_exec(bContext *C, wmOperator *op)
ID *id = (ID *)idptr.data;
if (!BKE_id_is_editable(CTX_data_main(C), id) ||
- (ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB, ID_WS))) {
+ ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB, ID_WS)) {
BKE_report(op->reports, RPT_ERROR, "Data-block type does not support fake user");
return OPERATOR_CANCELLED;
}
@@ -304,7 +304,7 @@ static bool lib_id_override_editable_toggle_poll(bContext *C)
return id && ID_IS_OVERRIDE_LIBRARY_REAL(id) && !ID_IS_LINKED(id);
}
-static int lib_id_override_editable_toggle_exec(bContext *C, wmOperator *UNUSED(op))
+static int lib_id_override_editable_toggle_exec(bContext *C, wmOperator * /*op*/)
{
Main *bmain = CTX_data_main(C);
const PointerRNA id_ptr = CTX_data_pointer_get_type(C, "id", &RNA_ID);
@@ -346,7 +346,7 @@ static void ED_OT_lib_id_override_editable_toggle(wmOperatorType *ot)
/** \name General editor utils.
* \{ */
-static int ed_flush_edits_exec(bContext *C, wmOperator *UNUSED(op))
+static int ed_flush_edits_exec(bContext *C, wmOperator * /*op*/)
{
Main *bmain = CTX_data_main(C);
ED_editors_flush_edits(bmain);
diff --git a/source/blender/editors/util/ed_viewer_path.cc b/source/blender/editors/util/ed_viewer_path.cc
new file mode 100644
index 00000000000..4da1559b726
--- /dev/null
+++ b/source/blender/editors/util/ed_viewer_path.cc
@@ -0,0 +1,365 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "ED_viewer_path.hh"
+#include "ED_screen.h"
+
+#include "BKE_context.h"
+#include "BKE_main.h"
+#include "BKE_node_runtime.hh"
+#include "BKE_workspace.h"
+
+#include "BLI_listbase.h"
+#include "BLI_vector.hh"
+
+#include "DNA_modifier_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "DEG_depsgraph.h"
+
+#include "WM_api.h"
+
+namespace blender::ed::viewer_path {
+
+static void viewer_path_for_geometry_node(const SpaceNode &snode,
+ const bNode &node,
+ ViewerPath &r_dst)
+{
+ BKE_viewer_path_init(&r_dst);
+
+ Object *ob = reinterpret_cast<Object *>(snode.id);
+ IDViewerPathElem *id_elem = BKE_viewer_path_elem_new_id();
+ id_elem->id = &ob->id;
+ BLI_addtail(&r_dst.path, id_elem);
+
+ NodesModifierData *modifier = nullptr;
+ LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
+ if (md->type != eModifierType_Nodes) {
+ continue;
+ }
+ NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md);
+ if (nmd->node_group != snode.nodetree) {
+ continue;
+ }
+ if (snode.flag & SNODE_PIN) {
+ /* If the node group is pinned, use the first matching modifier. This can be improved by
+ * storing the modifier name in the node editor when the context is pinned. */
+ modifier = nmd;
+ break;
+ }
+ if (md->flag & eModifierFlag_Active) {
+ modifier = nmd;
+ }
+ }
+
+ ModifierViewerPathElem *modifier_elem = BKE_viewer_path_elem_new_modifier();
+ modifier_elem->modifier_name = BLI_strdup(modifier->modifier.name);
+ BLI_addtail(&r_dst.path, modifier_elem);
+
+ Vector<const bNodeTreePath *, 16> tree_path = snode.treepath;
+ for (const bNodeTreePath *tree_path_elem : tree_path.as_span().drop_front(1)) {
+ NodeViewerPathElem *node_elem = BKE_viewer_path_elem_new_node();
+ node_elem->node_name = BLI_strdup(tree_path_elem->node_name);
+ BLI_addtail(&r_dst.path, node_elem);
+ }
+
+ NodeViewerPathElem *viewer_node_elem = BKE_viewer_path_elem_new_node();
+ viewer_node_elem->node_name = BLI_strdup(node.name);
+ BLI_addtail(&r_dst.path, viewer_node_elem);
+}
+
+void activate_geometry_node(Main &bmain, SpaceNode &snode, bNode &node)
+{
+ wmWindowManager *wm = (wmWindowManager *)bmain.wm.first;
+ if (wm == nullptr) {
+ return;
+ }
+ LISTBASE_FOREACH (bNode *, iter_node, &snode.edittree->nodes) {
+ if (iter_node->type == GEO_NODE_VIEWER) {
+ SET_FLAG_FROM_TEST(iter_node->flag, iter_node == &node, NODE_DO_OUTPUT);
+ }
+ }
+ ViewerPath new_viewer_path{};
+ BLI_SCOPED_DEFER([&]() { BKE_viewer_path_clear(&new_viewer_path); });
+ viewer_path_for_geometry_node(snode, node, new_viewer_path);
+
+ bool found_view3d_with_enabled_viewer = false;
+ View3D *any_view3d_without_viewer = nullptr;
+ LISTBASE_FOREACH (wmWindow *, window, &wm->windows) {
+ WorkSpace *workspace = BKE_workspace_active_get(window->workspace_hook);
+ bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook);
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ SpaceLink *sl = static_cast<SpaceLink *>(area->spacedata.first);
+ if (sl->spacetype == SPACE_SPREADSHEET) {
+ SpaceSpreadsheet &sspreadsheet = *reinterpret_cast<SpaceSpreadsheet *>(sl);
+ if (!(sspreadsheet.flag & SPREADSHEET_FLAG_PINNED)) {
+ sspreadsheet.object_eval_state = SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE;
+ }
+ }
+ else if (sl->spacetype == SPACE_VIEW3D) {
+ View3D &v3d = *reinterpret_cast<View3D *>(sl);
+ if (v3d.flag2 & V3D_SHOW_VIEWER) {
+ found_view3d_with_enabled_viewer = true;
+ }
+ else {
+ any_view3d_without_viewer = &v3d;
+ }
+ }
+ }
+
+ /* Enable viewer in one viewport if it is disable in all of them. */
+ if (!found_view3d_with_enabled_viewer && any_view3d_without_viewer != nullptr) {
+ any_view3d_without_viewer->flag2 |= V3D_SHOW_VIEWER;
+ }
+
+ BKE_viewer_path_clear(&workspace->viewer_path);
+ BKE_viewer_path_copy(&workspace->viewer_path, &new_viewer_path);
+
+ /* Make sure the viewed data becomes available. */
+ DEG_id_tag_update(snode.id, ID_RECALC_GEOMETRY);
+ WM_main_add_notifier(NC_VIEWER_PATH, nullptr);
+ }
+}
+
+Object *parse_object_only(const ViewerPath &viewer_path)
+{
+ if (BLI_listbase_count(&viewer_path.path) != 1) {
+ return nullptr;
+ }
+ const ViewerPathElem *elem = static_cast<ViewerPathElem *>(viewer_path.path.first);
+ if (elem->type != VIEWER_PATH_ELEM_TYPE_ID) {
+ return nullptr;
+ }
+ ID *id = reinterpret_cast<const IDViewerPathElem *>(elem)->id;
+ if (id == nullptr) {
+ return nullptr;
+ }
+ if (GS(id->name) != ID_OB) {
+ return nullptr;
+ }
+ return reinterpret_cast<Object *>(id);
+}
+
+std::optional<ViewerPathForGeometryNodesViewer> parse_geometry_nodes_viewer(
+ const ViewerPath &viewer_path)
+{
+ const Vector<const ViewerPathElem *, 16> elems_vec = viewer_path.path;
+ if (elems_vec.size() < 3) {
+ /* Need at least the object, modifier and viewer node name. */
+ return std::nullopt;
+ }
+ Span<const ViewerPathElem *> remaining_elems = elems_vec;
+ const ViewerPathElem &id_elem = *remaining_elems[0];
+ if (id_elem.type != VIEWER_PATH_ELEM_TYPE_ID) {
+ return std::nullopt;
+ }
+ ID *root_id = reinterpret_cast<const IDViewerPathElem &>(id_elem).id;
+ if (root_id == nullptr) {
+ return std::nullopt;
+ }
+ if (GS(root_id->name) != ID_OB) {
+ return std::nullopt;
+ }
+ Object *root_ob = reinterpret_cast<Object *>(root_id);
+ remaining_elems = remaining_elems.drop_front(1);
+ const ViewerPathElem &modifier_elem = *remaining_elems[0];
+ if (modifier_elem.type != VIEWER_PATH_ELEM_TYPE_MODIFIER) {
+ return std::nullopt;
+ }
+ const char *modifier_name =
+ reinterpret_cast<const ModifierViewerPathElem &>(modifier_elem).modifier_name;
+ if (modifier_name == nullptr) {
+ return std::nullopt;
+ }
+ remaining_elems = remaining_elems.drop_front(1);
+ Vector<StringRefNull> node_names;
+ for (const ViewerPathElem *elem : remaining_elems) {
+ if (elem->type != VIEWER_PATH_ELEM_TYPE_NODE) {
+ return std::nullopt;
+ }
+ const char *node_name = reinterpret_cast<const NodeViewerPathElem *>(elem)->node_name;
+ if (node_name == nullptr) {
+ return std::nullopt;
+ }
+ node_names.append(node_name);
+ }
+ const StringRefNull viewer_node_name = node_names.pop_last();
+ return ViewerPathForGeometryNodesViewer{root_ob, modifier_name, node_names, viewer_node_name};
+}
+
+bool exists_geometry_nodes_viewer(const ViewerPathForGeometryNodesViewer &parsed_viewer_path)
+{
+ const NodesModifierData *modifier = nullptr;
+ LISTBASE_FOREACH (const ModifierData *, md, &parsed_viewer_path.object->modifiers) {
+ if (md->type != eModifierType_Nodes) {
+ continue;
+ }
+ if (md->name != parsed_viewer_path.modifier_name) {
+ continue;
+ }
+ modifier = reinterpret_cast<const NodesModifierData *>(md);
+ break;
+ }
+ if (modifier == nullptr) {
+ return false;
+ }
+ if (modifier->node_group == nullptr) {
+ return false;
+ }
+ const bNodeTree *ngroup = modifier->node_group;
+ ngroup->ensure_topology_cache();
+ for (const StringRefNull group_node_name : parsed_viewer_path.group_node_names) {
+ const bNode *group_node = nullptr;
+ for (const bNode *node : ngroup->group_nodes()) {
+ if (node->name != group_node_name) {
+ continue;
+ }
+ group_node = node;
+ break;
+ }
+ if (group_node == nullptr) {
+ return false;
+ }
+ if (group_node->id == nullptr) {
+ return false;
+ }
+ ngroup = reinterpret_cast<const bNodeTree *>(group_node->id);
+ }
+ const bNode *viewer_node = nullptr;
+ for (const bNode *node : ngroup->nodes_by_type("GeometryNodeViewer")) {
+ if (node->name != parsed_viewer_path.viewer_node_name) {
+ continue;
+ }
+ viewer_node = node;
+ break;
+ }
+ if (viewer_node == nullptr) {
+ return false;
+ }
+ return true;
+}
+
+bool is_active_geometry_nodes_viewer(const bContext &C,
+ const ViewerPathForGeometryNodesViewer &parsed_viewer_path)
+{
+ const NodesModifierData *modifier = nullptr;
+ LISTBASE_FOREACH (const ModifierData *, md, &parsed_viewer_path.object->modifiers) {
+ if (md->name != parsed_viewer_path.modifier_name) {
+ continue;
+ }
+ if (md->type != eModifierType_Nodes) {
+ return false;
+ }
+ if ((md->mode & eModifierMode_Realtime) == 0) {
+ return false;
+ }
+ modifier = reinterpret_cast<const NodesModifierData *>(md);
+ break;
+ }
+ if (modifier == nullptr) {
+ return false;
+ }
+ if (modifier->node_group == nullptr) {
+ return false;
+ }
+ const bool modifier_is_active = modifier->modifier.flag & eModifierFlag_Active;
+
+ const Main *bmain = CTX_data_main(&C);
+ const wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
+ if (wm == nullptr) {
+ return false;
+ }
+ LISTBASE_FOREACH (const wmWindow *, window, &wm->windows) {
+ const bScreen *active_screen = BKE_workspace_active_screen_get(window->workspace_hook);
+ Vector<const bScreen *> screens = {active_screen};
+ if (ELEM(active_screen->state, SCREENMAXIMIZED, SCREENFULL)) {
+ const ScrArea *area = static_cast<ScrArea *>(active_screen->areabase.first);
+ screens.append(area->full);
+ }
+ for (const bScreen *screen : screens) {
+ LISTBASE_FOREACH (const ScrArea *, area, &screen->areabase) {
+ const SpaceLink *sl = static_cast<SpaceLink *>(area->spacedata.first);
+ if (sl == nullptr) {
+ continue;
+ }
+ if (sl->spacetype != SPACE_NODE) {
+ continue;
+ }
+ const SpaceNode &snode = *reinterpret_cast<const SpaceNode *>(sl);
+ if (!modifier_is_active) {
+ if (!(snode.flag & SNODE_PIN)) {
+ /* Node tree has to be pinned when the modifier is not active. */
+ continue;
+ }
+ }
+ if (snode.id != &parsed_viewer_path.object->id) {
+ continue;
+ }
+ if (snode.nodetree != modifier->node_group) {
+ continue;
+ }
+ Vector<const bNodeTreePath *, 16> tree_path = snode.treepath;
+ if (tree_path.size() != parsed_viewer_path.group_node_names.size() + 1) {
+ continue;
+ }
+ bool valid_path = true;
+ for (const int i : parsed_viewer_path.group_node_names.index_range()) {
+ if (parsed_viewer_path.group_node_names[i] != tree_path[i + 1]->node_name) {
+ valid_path = false;
+ break;
+ }
+ }
+ if (!valid_path) {
+ continue;
+ }
+ const bNodeTree *ngroup = snode.edittree;
+ ngroup->ensure_topology_cache();
+ const bNode *viewer_node = nullptr;
+ for (const bNode *node : ngroup->nodes_by_type("GeometryNodeViewer")) {
+ if (node->name != parsed_viewer_path.viewer_node_name) {
+ continue;
+ }
+ viewer_node = node;
+ }
+ if (viewer_node == nullptr) {
+ continue;
+ }
+ if (!(viewer_node->flag & NODE_DO_OUTPUT)) {
+ continue;
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bNode *find_geometry_nodes_viewer(const ViewerPath &viewer_path, SpaceNode &snode)
+{
+ const std::optional<ViewerPathForGeometryNodesViewer> parsed_viewer_path =
+ parse_geometry_nodes_viewer(viewer_path);
+ if (!parsed_viewer_path.has_value()) {
+ return nullptr;
+ }
+
+ snode.edittree->ensure_topology_cache();
+ bNode *possible_viewer = nullptr;
+ for (bNode *node : snode.edittree->nodes_by_type("GeometryNodeViewer")) {
+ if (node->name == parsed_viewer_path->viewer_node_name) {
+ possible_viewer = node;
+ break;
+ }
+ }
+ if (possible_viewer == nullptr) {
+ return nullptr;
+ }
+ ViewerPath tmp_viewer_path;
+ BLI_SCOPED_DEFER([&]() { BKE_viewer_path_clear(&tmp_viewer_path); });
+ viewer_path_for_geometry_node(snode, *possible_viewer, tmp_viewer_path);
+
+ if (BKE_viewer_path_equal(&viewer_path, &tmp_viewer_path)) {
+ return possible_viewer;
+ }
+ return nullptr;
+}
+
+} // namespace blender::ed::viewer_path
diff --git a/source/blender/editors/uvedit/uvedit_buttons.c b/source/blender/editors/uvedit/uvedit_buttons.c
index 6192ae56d65..10368f7d43f 100644
--- a/source/blender/editors/uvedit/uvedit_buttons.c
+++ b/source/blender/editors/uvedit/uvedit_buttons.c
@@ -123,7 +123,7 @@ static void uvedit_vertex_buttons(const bContext *C, uiBlock *block)
int imx, imy, step, digits;
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- CTX_data_view_layer(C), CTX_wm_view3d(C), &objects_len);
+ scene, CTX_data_view_layer(C), CTX_wm_view3d(C), &objects_len);
ED_space_image_get_size(sima, &imx, &imy);
@@ -211,7 +211,7 @@ static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- CTX_data_view_layer(C), CTX_wm_view3d(C), &objects_len);
+ scene, CTX_data_view_layer(C), CTX_wm_view3d(C), &objects_len);
ED_space_image_get_size(sima, &imx, &imy);
uvedit_center(scene, objects, objects_len, center);
diff --git a/source/blender/editors/uvedit/uvedit_islands.cc b/source/blender/editors/uvedit/uvedit_islands.cc
index 42415be656a..d8e10435146 100644
--- a/source/blender/editors/uvedit/uvedit_islands.cc
+++ b/source/blender/editors/uvedit/uvedit_islands.cc
@@ -36,46 +36,54 @@
#include "bmesh.h"
-/* -------------------------------------------------------------------- */
-/** \name UV Face Utilities
- * \{ */
-
-static void bm_face_uv_scale_y(BMFace *f, const float scale_y, const int cd_loop_uv_offset)
+static void mul_v2_m2_add_v2v2(float r[2],
+ const float mat[2][2],
+ const float a[2],
+ const float b[2])
{
- BMLoop *l_iter;
- BMLoop *l_first;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- MLoopUV *luv = static_cast<MLoopUV *>(BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset));
- luv->uv[1] *= scale_y;
- } while ((l_iter = l_iter->next) != l_first);
+ /* Compute `r = mat * (a + b)` with high precision. */
+ const double x = static_cast<double>(a[0]) + static_cast<double>(b[0]);
+ const double y = static_cast<double>(a[1]) + static_cast<double>(b[1]);
+
+ r[0] = static_cast<float>(mat[0][0] * x + mat[1][0] * y);
+ r[1] = static_cast<float>(mat[0][1] * x + mat[1][1] * y);
}
-static void bm_face_uv_translate_and_scale_around_pivot(BMFace *f,
- const float offset[2],
- const float scale[2],
- const float pivot[2],
- const int cd_loop_uv_offset)
+static void island_uv_transform(FaceIsland *island,
+ const float matrix[2][2], /* Scale and rotation. */
+ const float pre_translate[2] /* (pre) Translation. */
+)
{
- BMLoop *l_iter;
- BMLoop *l_first;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- MLoopUV *luv = static_cast<MLoopUV *>(BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset));
- for (int i = 0; i < 2; i++) {
- luv->uv[i] = offset[i] + (((luv->uv[i] - pivot[i]) * scale[i]) + pivot[i]);
+ /* Use a pre-transform to compute `A * (x+b)`
+ *
+ * \note Ordinarily, we'd use a post_transform like `A * x + b`
+ * In general, post-transforms are easier to work with when using homogenous co-ordinates.
+ *
+ * When UV mapping into the unit square, post-transforms can lose precision on small islands.
+ * Instead we're using a pre-transform to maintain precision.
+ *
+ * To convert post-transform to pre-transform, use `A * x + b == A * (x + c), c = A^-1 * b`
+ */
+
+ const int cd_loop_uv_offset = island->cd_loop_uv_offset;
+ const int faces_len = island->faces_len;
+ for (int i = 0; i < faces_len; i++) {
+ BMFace *f = island->faces[i];
+ BMLoop *l;
+ BMIter iter;
+ BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) {
+ MLoopUV *luv = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ mul_v2_m2_add_v2v2(luv->uv, matrix, luv->uv, pre_translate);
}
- } while ((l_iter = l_iter->next) != l_first);
+ }
}
-/** \} */
-
/* -------------------------------------------------------------------- */
/** \name UV Face Array Utilities
* \{ */
static void bm_face_array_calc_bounds(BMFace **faces,
- int faces_len,
+ const int faces_len,
const int cd_loop_uv_offset,
rctf *r_bounds_rect)
{
@@ -137,7 +145,7 @@ static float (*bm_face_array_calc_unique_uv_coords(
BMEdge *e_first = v_pivot->e;
const BMEdge *e = e_first;
do {
- if (e->l != NULL) {
+ if (e->l != nullptr) {
const BMLoop *l_radial = e->l;
do {
if (l_radial->v == l_iter->v) {
@@ -159,65 +167,62 @@ static float (*bm_face_array_calc_unique_uv_coords(
return coords;
}
-/**
- * \param align_to_axis:
- * - -1: don't align to an axis.
- * - 0: align horizontally.
- * - 1: align vertically.
- */
-static void bm_face_array_uv_rotate_fit_aabb(BMFace **faces,
- int faces_len,
- int align_to_axis,
- const int cd_loop_uv_offset)
+static void face_island_uv_rotate_fit_aabb(FaceIsland *island)
{
+ BMFace **faces = island->faces;
+ const int faces_len = island->faces_len;
+ const float aspect_y = island->aspect_y;
+ const int cd_loop_uv_offset = island->cd_loop_uv_offset;
+
/* Calculate unique coordinates since calculating a convex hull can be an expensive operation. */
int coords_len;
float(*coords)[2] = bm_face_array_calc_unique_uv_coords(
faces, faces_len, cd_loop_uv_offset, &coords_len);
- float angle = BLI_convexhull_aabb_fit_points_2d(coords, coords_len);
-
- if (align_to_axis != -1) {
- if (angle != 0.0f) {
- float matrix[2][2];
- angle_to_mat2(matrix, angle);
- for (int i = 0; i < coords_len; i++) {
- mul_m2_v2(matrix, coords[i]);
- }
+ /* Correct aspect ratio. */
+ if (aspect_y != 1.0f) {
+ for (int i = 0; i < coords_len; i++) {
+ coords[i][1] /= aspect_y;
}
+ }
- float bounds_min[2], bounds_max[2];
- INIT_MINMAX2(bounds_min, bounds_max);
+ float angle = BLI_convexhull_aabb_fit_points_2d(coords, coords_len);
+
+ /* Rotate coords by `angle` before computing bounding box. */
+ if (angle != 0.0f) {
+ float matrix[2][2];
+ angle_to_mat2(matrix, angle);
+ matrix[0][1] *= aspect_y;
+ matrix[1][1] *= aspect_y;
for (int i = 0; i < coords_len; i++) {
- minmax_v2v2_v2(bounds_min, bounds_max, coords[i]);
+ mul_m2_v2(matrix, coords[i]);
}
+ }
- float size[2];
- sub_v2_v2v2(size, bounds_max, bounds_min);
- if (align_to_axis ? (size[1] < size[0]) : (size[0] < size[1])) {
- angle += DEG2RAD(90.0);
- }
+ /* Compute new AABB. */
+ float bounds_min[2], bounds_max[2];
+ INIT_MINMAX2(bounds_min, bounds_max);
+ for (int i = 0; i < coords_len; i++) {
+ minmax_v2v2_v2(bounds_min, bounds_max, coords[i]);
+ }
+
+ float size[2];
+ sub_v2_v2v2(size, bounds_max, bounds_min);
+ if (size[1] < size[0]) {
+ angle += DEG2RADF(90.0f);
}
MEM_freeN(coords);
+ /* Apply rotation back to BMesh. */
if (angle != 0.0f) {
float matrix[2][2];
+ float pre_translate[2] = {0, 0};
angle_to_mat2(matrix, angle);
- for (int i = 0; i < faces_len; i++) {
- BM_face_uv_transform(faces[i], matrix, cd_loop_uv_offset);
- }
- }
-}
-
-static void bm_face_array_uv_scale_y(BMFace **faces,
- int faces_len,
- const float scale_y,
- const int cd_loop_uv_offset)
-{
- for (int i = 0; i < faces_len; i++) {
- BMFace *f = faces[i];
- bm_face_uv_scale_y(f, scale_y, cd_loop_uv_offset);
+ matrix[1][0] *= 1.0f / aspect_y;
+ /* matrix[1][1] *= aspect_y / aspect_y; */
+ matrix[0][1] *= aspect_y;
+ island_uv_transform(island, matrix, pre_translate);
}
}
@@ -276,7 +281,7 @@ static float uv_nearest_image_tile_distance(const Image *image,
* Calculates distance to nearest UDIM grid tile in UV space and its UDIM tile number.
*/
static float uv_nearest_grid_tile_distance(const int udim_grid[2],
- float coords[2],
+ const float coords[2],
float nearest_tile_co[2])
{
const float coords_floor[2] = {floorf(coords[0]), floorf(coords[1])};
@@ -349,7 +354,7 @@ int bm_mesh_calc_uv_islands(const Scene *scene,
BM_mesh_elem_table_ensure(bm, BM_FACE);
int *groups_array = static_cast<int *>(
- MEM_mallocN(sizeof(*groups_array) * (size_t)bm->totface, __func__));
+ MEM_mallocN(sizeof(*groups_array) * size_t(bm->totface), __func__));
int(*group_index)[2];
@@ -381,7 +386,7 @@ int bm_mesh_calc_uv_islands(const Scene *scene,
const int group_len = BM_mesh_calc_face_groups(bm,
groups_array,
&group_index,
- NULL,
+ nullptr,
bm_loop_uv_shared_edge_check,
&user_data,
hflag_face_test,
@@ -416,28 +421,246 @@ int bm_mesh_calc_uv_islands(const Scene *scene,
/** \} */
+static float pack_islands_scale_margin(const blender::Vector<FaceIsland *> &island_vector,
+ BoxPack *box_array,
+ const float scale,
+ const float margin)
+{
+ for (const int index : island_vector.index_range()) {
+ FaceIsland *island = island_vector[index];
+ BoxPack *box = &box_array[index];
+ box->index = index;
+ box->w = BLI_rctf_size_x(&island->bounds_rect) * scale + 2 * margin;
+ box->h = BLI_rctf_size_y(&island->bounds_rect) * scale + 2 * margin;
+ }
+ float max_u, max_v;
+ BLI_box_pack_2d(box_array, island_vector.size(), &max_u, &max_v);
+ return max_ff(max_u, max_v);
+}
+
+static float pack_islands_margin_fraction(const blender::Vector<FaceIsland *> &island_vector,
+ BoxPack *box_array,
+ const float margin_fraction)
+{
+ /*
+ * Root finding using a combined search / modified-secant method.
+ * First, use a robust search procedure to bracket the root within a factor of 10.
+ * Then, use a modified-secant method to converge.
+ *
+ * This is a specialized solver using domain knowledge to accelerate convergence.
+ */
+
+ float scale_low = 0.0f;
+ float value_low = 0.0f;
+ float scale_high = 0.0f;
+ float value_high = 0.0f;
+ float scale_last = 0.0f;
+
+ /* Scaling smaller than `min_scale_roundoff` is unlikely to fit and
+ * will destroy information in existing UVs. */
+ float min_scale_roundoff = 1e-5f;
+
+ /* Certain inputs might have poor convergence properties.
+ * Use `max_iteration` to prevent an infinite loop. */
+ int max_iteration = 25;
+ for (int iteration = 0; iteration < max_iteration; iteration++) {
+ float scale = 1.0f;
+
+ if (iteration == 0) {
+ BLI_assert(iteration == 0);
+ BLI_assert(scale == 1.0f);
+ BLI_assert(scale_low == 0.0f);
+ BLI_assert(scale_high == 0.0f);
+ }
+ else if (scale_low == 0.0f) {
+ BLI_assert(scale_high > 0.0f);
+ /* Search mode, shrink layout until we can find a scale that fits. */
+ scale = scale_high * 0.1f;
+ }
+ else if (scale_high == 0.0f) {
+ BLI_assert(scale_low > 0.0f);
+ /* Search mode, grow layout until we can find a scale that doesn't fit. */
+ scale = scale_low * 10.0f;
+ }
+ else {
+ /* Bracket mode, use modified secant method to find root. */
+ BLI_assert(scale_low > 0.0f);
+ BLI_assert(scale_high > 0.0f);
+ BLI_assert(value_low <= 0.0f);
+ BLI_assert(value_high >= 0.0f);
+ if (scale_high < scale_low * 1.0001f) {
+ /* Convergence. */
+ break;
+ }
+
+ /* Secant method for area. */
+ scale = (sqrtf(scale_low) * value_high - sqrtf(scale_high) * value_low) /
+ (value_high - value_low);
+ scale = scale * scale;
+
+ if (iteration & 1) {
+ /* Modified binary-search to improve robustness. */
+ scale = sqrtf(scale * sqrtf(scale_low * scale_high));
+ }
+ }
+
+ scale = max_ff(scale, min_scale_roundoff);
+
+ /* Evaluate our `f`. */
+ scale_last = scale;
+ float max_uv = pack_islands_scale_margin(
+ island_vector, box_array, scale_last, margin_fraction);
+ float value = sqrtf(max_uv) - 1.0f;
+
+ if (value <= 0.0f) {
+ scale_low = scale;
+ value_low = value;
+ }
+ else {
+ scale_high = scale;
+ value_high = value;
+ if (scale == min_scale_roundoff) {
+ /* Unable to pack without damaging UVs. */
+ scale_low = scale;
+ break;
+ }
+ }
+ }
+
+ const bool flush = true;
+ if (flush) {
+ /* Write back best pack as a side-effect. First get best pack. */
+ if (scale_last != scale_low) {
+ scale_last = scale_low;
+ float max_uv = pack_islands_scale_margin(
+ island_vector, box_array, scale_last, margin_fraction);
+ UNUSED_VARS(max_uv);
+ /* TODO (?): `if (max_uv < 1.0f) { scale_last /= max_uv; }` */
+ }
+
+ /* Then expand FaceIslands by the correct amount. */
+ for (const int index : island_vector.index_range()) {
+ BoxPack *box = &box_array[index];
+ box->x /= scale_last;
+ box->y /= scale_last;
+ FaceIsland *island = island_vector[index];
+ BLI_rctf_pad(
+ &island->bounds_rect, margin_fraction / scale_last, margin_fraction / scale_last);
+ }
+ }
+ return scale_last;
+}
+
+static float calc_margin_from_aabb_length_sum(const blender::Vector<FaceIsland *> &island_vector,
+ const struct UVPackIsland_Params &params)
+{
+ /* Logic matches behavior from #GEO_uv_parametrizer_pack.
+ * Attempt to give predictable results
+ * not dependent on current UV scale by using
+ * `aabb_length_sum` (was "`area`") to multiply
+ * the margin by the length (was "area").
+ */
+ double aabb_length_sum = 0.0f;
+ for (FaceIsland *island : island_vector) {
+ float w = BLI_rctf_size_x(&island->bounds_rect);
+ float h = BLI_rctf_size_y(&island->bounds_rect);
+ aabb_length_sum += sqrtf(w * h);
+ }
+ return params.margin * aabb_length_sum * 0.1f;
+}
+
+static BoxPack *pack_islands_params(const blender::Vector<FaceIsland *> &island_vector,
+ const struct UVPackIsland_Params &params,
+ float r_scale[2])
+{
+ BoxPack *box_array = static_cast<BoxPack *>(
+ MEM_mallocN(sizeof(*box_array) * island_vector.size(), __func__));
+
+ if (params.margin == 0.0f) {
+ /* Special case for zero margin. Margin_method is ignored as all formulas give same result. */
+ const float max_uv = pack_islands_scale_margin(island_vector, box_array, 1.0f, 0.0f);
+ r_scale[0] = 1.0f / max_uv;
+ r_scale[1] = r_scale[0];
+ return box_array;
+ }
+
+ if (params.margin_method == ED_UVPACK_MARGIN_FRACTION) {
+ /* Uses a line search on scale. ~10x slower than other method. */
+ const float scale = pack_islands_margin_fraction(island_vector, box_array, params.margin);
+ r_scale[0] = scale;
+ r_scale[1] = scale;
+ /* pack_islands_margin_fraction will pad FaceIslands, return early. */
+ return box_array;
+ }
+
+ float margin = params.margin;
+ switch (params.margin_method) {
+ case ED_UVPACK_MARGIN_ADD: /* Default for Blender 2.8 and earlier. */
+ break; /* Nothing to do. */
+ case ED_UVPACK_MARGIN_SCALED: /* Default for Blender 3.3 and later. */
+ margin = calc_margin_from_aabb_length_sum(island_vector, params);
+ break;
+ case ED_UVPACK_MARGIN_FRACTION: /* Added as an option in Blender 3.4. */
+ BLI_assert_unreachable(); /* Handled above. */
+ break;
+ default:
+ BLI_assert_unreachable();
+ }
+
+ const float max_uv = pack_islands_scale_margin(island_vector, box_array, 1.0f, margin);
+ r_scale[0] = 1.0f / max_uv;
+ r_scale[1] = r_scale[0];
+
+ for (int index = 0; index < island_vector.size(); index++) {
+ FaceIsland *island = island_vector[index];
+ BLI_rctf_pad(&island->bounds_rect, margin, margin);
+ }
+ return box_array;
+}
+
+static bool island_has_pins(FaceIsland *island)
+{
+ BMLoop *l;
+ BMIter iter;
+ const int cd_loop_uv_offset = island->cd_loop_uv_offset;
+ for (int i = 0; i < island->faces_len; i++) {
+ BM_ITER_ELEM (l, &iter, island->faces[i], BM_LOOPS_OF_FACE) {
+ MLoopUV *luv = static_cast<MLoopUV *>(BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset));
+ if (luv->flag & MLOOPUV_PINNED) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
/* -------------------------------------------------------------------- */
/** \name Public UV Island Packing
*
- * \note This behavior follows #param_pack.
+ * \note This behavior loosely follows #GEO_uv_parametrizer_pack.
* \{ */
void ED_uvedit_pack_islands_multi(const Scene *scene,
Object **objects,
const uint objects_len,
+ BMesh **bmesh_override,
const struct UVMapUDIM_Params *udim_params,
const struct UVPackIsland_Params *params)
{
- /* Align to the Y axis, could make this configurable. */
- const int rotate_align_axis = 1;
- ListBase island_list = {NULL};
- int island_list_len = 0;
+ blender::Vector<FaceIsland *> island_vector;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- BMesh *bm = em->bm;
-
+ BMesh *bm = nullptr;
+ if (bmesh_override) {
+ /* Note: obedit is still required for aspect ratio and ID_RECALC_GEOMETRY. */
+ bm = bmesh_override[ob_index];
+ }
+ else {
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ bm = em->bm;
+ }
+ BLI_assert(bm);
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
if (cd_loop_uv_offset == -1) {
continue;
@@ -452,35 +675,38 @@ void ED_uvedit_pack_islands_multi(const Scene *scene,
}
}
- island_list_len += bm_mesh_calc_uv_islands(scene,
- bm,
- &island_list,
- params->only_selected_faces,
- params->only_selected_uvs,
- params->use_seams,
- aspect_y,
- cd_loop_uv_offset);
+ ListBase island_list = {nullptr};
+ bm_mesh_calc_uv_islands(scene,
+ bm,
+ &island_list,
+ params->only_selected_faces,
+ params->only_selected_uvs,
+ params->use_seams,
+ aspect_y,
+ cd_loop_uv_offset);
+
+ /* Remove from linked list and append to blender::Vector. */
+ LISTBASE_FOREACH_MUTABLE (struct FaceIsland *, island, &island_list) {
+ BLI_remlink(&island_list, island);
+ if (params->ignore_pinned && island_has_pins(island)) {
+ MEM_freeN(island->faces);
+ MEM_freeN(island);
+ continue;
+ }
+ island_vector.append(island);
+ }
}
- if (island_list_len == 0) {
+ if (island_vector.size() == 0) {
return;
}
- float margin = scene->toolsettings->uvcalc_margin;
- double area = 0.0f;
-
- struct FaceIsland **island_array = static_cast<struct FaceIsland **>(
- MEM_mallocN(sizeof(*island_array) * island_list_len, __func__));
- BoxPack *boxarray = static_cast<BoxPack *>(
- MEM_mallocN(sizeof(*boxarray) * island_list_len, __func__));
-
- int index;
/* Coordinates of bounding box containing all selected UVs. */
float selection_min_co[2], selection_max_co[2];
INIT_MINMAX2(selection_min_co, selection_max_co);
- LISTBASE_FOREACH_INDEX (struct FaceIsland *, island, &island_list, index) {
-
+ for (int index = 0; index < island_vector.size(); index++) {
+ FaceIsland *island = island_vector[index];
/* Skip calculation if using specified UDIM option. */
if (udim_params && (udim_params->use_target_udim == false)) {
float bounds_min[2], bounds_max[2];
@@ -497,35 +723,11 @@ void ED_uvedit_pack_islands_multi(const Scene *scene,
}
if (params->rotate) {
- if (island->aspect_y != 1.0f) {
- bm_face_array_uv_scale_y(
- island->faces, island->faces_len, 1.0f / island->aspect_y, island->cd_loop_uv_offset);
- }
-
- bm_face_array_uv_rotate_fit_aabb(
- island->faces, island->faces_len, rotate_align_axis, island->cd_loop_uv_offset);
-
- if (island->aspect_y != 1.0f) {
- bm_face_array_uv_scale_y(
- island->faces, island->faces_len, island->aspect_y, island->cd_loop_uv_offset);
- }
+ face_island_uv_rotate_fit_aabb(island);
}
bm_face_array_calc_bounds(
island->faces, island->faces_len, island->cd_loop_uv_offset, &island->bounds_rect);
-
- BoxPack *box = &boxarray[index];
- box->index = index;
- box->x = 0.0f;
- box->y = 0.0f;
- box->w = BLI_rctf_size_x(&island->bounds_rect);
- box->h = BLI_rctf_size_y(&island->bounds_rect);
-
- island_array[index] = island;
-
- if (margin > 0.0f) {
- area += (double)sqrtf(box->w * box->h);
- }
}
/* Center of bounding box containing all selected UVs. */
@@ -535,34 +737,14 @@ void ED_uvedit_pack_islands_multi(const Scene *scene,
selection_center[1] = (selection_min_co[1] + selection_max_co[1]) / 2.0f;
}
- if (margin > 0.0f) {
- /* Logic matches behavior from #param_pack,
- * use area so multiply the margin by the area to give
- * predictable results not dependent on UV scale. */
- margin = (margin * (float)area) * 0.1f;
- for (int i = 0; i < island_list_len; i++) {
- struct FaceIsland *island = island_array[i];
- BoxPack *box = &boxarray[i];
-
- BLI_rctf_pad(&island->bounds_rect, margin, margin);
- box->w = BLI_rctf_size_x(&island->bounds_rect);
- box->h = BLI_rctf_size_y(&island->bounds_rect);
- }
- }
-
- float boxarray_size[2];
- BLI_box_pack_2d(boxarray, island_list_len, &boxarray_size[0], &boxarray_size[1]);
-
- /* Don't change the aspect when scaling. */
- boxarray_size[0] = boxarray_size[1] = max_ff(boxarray_size[0], boxarray_size[1]);
-
- const float scale[2] = {1.0f / boxarray_size[0], 1.0f / boxarray_size[1]};
+ float scale[2] = {1.0f, 1.0f};
+ BoxPack *box_array = pack_islands_params(island_vector, *params, scale);
/* Tile offset. */
float base_offset[2] = {0.0f, 0.0f};
/* CASE: ignore UDIM. */
- if (udim_params == NULL) {
+ if (udim_params == nullptr) {
/* pass */
}
/* CASE: Active/specified(smart uv project) UDIM. */
@@ -605,21 +787,24 @@ void ED_uvedit_pack_islands_multi(const Scene *scene,
}
}
- for (int i = 0; i < island_list_len; i++) {
- struct FaceIsland *island = island_array[boxarray[i].index];
- const float pivot[2] = {
- island->bounds_rect.xmin,
- island->bounds_rect.ymin,
- };
- const float offset[2] = {
- ((boxarray[i].x * scale[0]) - island->bounds_rect.xmin) + base_offset[0],
- ((boxarray[i].y * scale[1]) - island->bounds_rect.ymin) + base_offset[1],
- };
- for (int j = 0; j < island->faces_len; j++) {
- BMFace *efa = island->faces[j];
- bm_face_uv_translate_and_scale_around_pivot(
- efa, offset, scale, pivot, island->cd_loop_uv_offset);
- }
+ float matrix[2][2];
+ float matrix_inverse[2][2];
+ float pre_translate[2];
+ for (int i = 0; i < island_vector.size(); i++) {
+ FaceIsland *island = island_vector[box_array[i].index];
+ matrix[0][0] = scale[0];
+ matrix[0][1] = 0.0f;
+ matrix[1][0] = 0.0f;
+ matrix[1][1] = scale[1];
+ invert_m2_m2(matrix_inverse, matrix);
+
+ /* Add base_offset, post transform. */
+ mul_v2_m2v2(pre_translate, matrix_inverse, base_offset);
+
+ /* Translate to box_array from bounds_rect. */
+ pre_translate[0] += box_array[i].x - island->bounds_rect.xmin;
+ pre_translate[1] += box_array[i].y - island->bounds_rect.ymin;
+ island_uv_transform(island, matrix, pre_translate);
}
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@@ -628,13 +813,12 @@ void ED_uvedit_pack_islands_multi(const Scene *scene,
WM_main_add_notifier(NC_GEOM | ND_DATA, obedit->data);
}
- for (int i = 0; i < island_list_len; i++) {
- MEM_freeN(island_array[i]->faces);
- MEM_freeN(island_array[i]);
+ for (FaceIsland *island : island_vector) {
+ MEM_freeN(island->faces);
+ MEM_freeN(island);
}
- MEM_freeN(island_array);
- MEM_freeN(boxarray);
+ MEM_freeN(box_array);
}
/** \} */
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 4cc2c6450df..0e77a8ba4ad 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -37,6 +37,7 @@
#include "BKE_node.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "ED_image.h"
#include "ED_mesh.h"
@@ -110,10 +111,11 @@ bool ED_object_get_active_image(Object *ob,
int mat_nr,
Image **r_ima,
ImageUser **r_iuser,
- bNode **r_node,
- bNodeTree **r_ntree)
+ const bNode **r_node,
+ const bNodeTree **r_ntree)
{
- Material *ma = BKE_object_material_get(ob, mat_nr);
+ Material *ma = DEG_is_evaluated_object(ob) ? BKE_object_material_get_eval(ob, mat_nr) :
+ BKE_object_material_get(ob, mat_nr);
bNodeTree *ntree = (ma && ma->use_nodes) ? ma->nodetree : NULL;
bNode *node = (ntree) ? nodeGetActiveTexture(ntree) : NULL;
@@ -320,7 +322,7 @@ bool ED_uvedit_center_from_pivot_ex(SpaceImage *sima,
if (r_has_select != NULL) {
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
*r_has_select = uvedit_select_is_any_selected_multi(scene, objects, objects_len);
MEM_freeN(objects);
}
@@ -329,7 +331,7 @@ bool ED_uvedit_center_from_pivot_ex(SpaceImage *sima,
default: {
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
changed = ED_uvedit_center_multi(scene, objects, objects_len, r_center, mode);
MEM_freeN(objects);
if (r_has_select != NULL) {
@@ -565,7 +567,7 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
if (tool == UV_ALIGN_AUTO) {
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@@ -695,7 +697,7 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
bool *changed = MEM_callocN(sizeof(bool) * objects_len, "uv_remove_doubles_selected.changed");
@@ -839,7 +841,7 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
/* Calculate max possible number of kdtree nodes. */
int uv_maxlen = 0;
@@ -1047,7 +1049,7 @@ static int uv_snap_cursor_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
changed = uv_snap_cursor_to_selection(scene, objects, objects_len, sima);
MEM_freeN(objects);
break;
@@ -1255,7 +1257,7 @@ static int uv_snap_selection_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
if (target == 2) {
float center[2];
@@ -1348,7 +1350,7 @@ static int uv_pin_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -1450,7 +1452,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
@@ -1622,7 +1624,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
@@ -1838,7 +1840,7 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
@@ -1943,7 +1945,7 @@ static int uv_mark_seam_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
bool changed = false;
diff --git a/source/blender/editors/uvedit/uvedit_path.c b/source/blender/editors/uvedit/uvedit_path.c
index 19218259b95..78436d17203 100644
--- a/source/blender/editors/uvedit/uvedit_path.c
+++ b/source/blender/editors/uvedit/uvedit_path.c
@@ -628,8 +628,8 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
else {
l_src = ED_uvedit_active_edge_loop_get(bm);
if (l_src != NULL) {
- if ((!uvedit_uv_select_test(scene, l_src, cd_loop_uv_offset)) &&
- (!uvedit_uv_select_test(scene, l_src->next, cd_loop_uv_offset))) {
+ if (!uvedit_uv_select_test(scene, l_src, cd_loop_uv_offset) &&
+ !uvedit_uv_select_test(scene, l_src->next, cd_loop_uv_offset)) {
l_src = NULL;
}
ele_src = (BMElem *)l_src;
@@ -799,7 +799,7 @@ static int uv_shortest_path_select_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
diff --git a/source/blender/editors/uvedit/uvedit_rip.c b/source/blender/editors/uvedit/uvedit_rip.c
index 52e92b2e3c5..5497b9cd1e5 100644
--- a/source/blender/editors/uvedit/uvedit_rip.c
+++ b/source/blender/editors/uvedit/uvedit_rip.c
@@ -910,7 +910,7 @@ static int uv_rip_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c
index 43c8620df1d..777cc1d97e4 100644
--- a/source/blender/editors/uvedit/uvedit_select.c
+++ b/source/blender/editors/uvedit/uvedit_select.c
@@ -228,7 +228,7 @@ bool uvedit_face_visible_test(const Scene *scene, BMFace *efa)
bool uvedit_face_select_test_ex(const ToolSettings *ts, BMFace *efa, const int cd_loop_uv_offset)
{
if (ts->uv_flag & UV_SYNC_SELECTION) {
- return (BM_elem_flag_test(efa, BM_ELEM_SELECT));
+ return BM_elem_flag_test(efa, BM_ELEM_SELECT);
}
BMLoop *l;
@@ -1549,7 +1549,7 @@ static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, c
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
if (extend) {
- select = !(uvedit_edge_select_test(scene, hit->l, cd_loop_uv_offset));
+ select = !uvedit_edge_select_test(scene, hit->l, cd_loop_uv_offset);
}
else {
select = true;
@@ -1618,7 +1618,7 @@ static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, c
}
}
- return (select) ? 1 : -1;
+ return select ? 1 : -1;
}
/** \} */
@@ -1641,7 +1641,7 @@ static int uv_select_faceloop(Scene *scene, Object *obedit, UvNearestHit *hit, c
BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, false);
if (extend) {
- select = !(uvedit_face_select_test(scene, hit->l->f, cd_loop_uv_offset));
+ select = !uvedit_face_select_test(scene, hit->l->f, cd_loop_uv_offset);
}
else {
select = true;
@@ -1710,7 +1710,7 @@ static int uv_select_edgering(Scene *scene, Object *obedit, UvNearestHit *hit, c
BM_mesh_elem_hflag_disable_all(em->bm, BM_EDGE, BM_ELEM_TAG, false);
if (extend) {
- select = !(uvedit_edge_select_test(scene, hit->l, cd_loop_uv_offset));
+ select = !uvedit_edge_select_test(scene, hit->l, cd_loop_uv_offset);
}
else {
select = true;
@@ -2048,7 +2048,7 @@ static int uv_select_more_less(bContext *C, const bool select)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
const bool is_uv_face_selectmode = (ts->uv_selectmode == UV_SELECT_FACE);
@@ -2403,7 +2403,7 @@ static int uv_select_all_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
uv_select_all_perform_multi(scene, objects, objects_len, action);
@@ -2665,10 +2665,11 @@ static bool uv_mouse_select_multi(bContext *C,
}
static bool uv_mouse_select(bContext *C, const float co[2], const struct SelectPick_Params *params)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
bool changed = uv_mouse_select_multi(C, objects, objects_len, co, params);
MEM_freeN(objects);
return changed;
@@ -2817,10 +2818,11 @@ static int uv_mouse_select_loop_generic(bContext *C,
const bool extend,
enum eUVLoopGenericType loop_type)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
int ret = uv_mouse_select_loop_generic_multi(C, objects, objects_len, co, extend, loop_type);
MEM_freeN(objects);
return ret;
@@ -2977,7 +2979,7 @@ static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
if (pick) {
float co[2];
@@ -3135,7 +3137,7 @@ static int uv_select_split_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -3538,7 +3540,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
if (use_pre_deselect) {
uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
@@ -3634,7 +3636,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
bool has_selected = false;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if ((select) != (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))) {
+ if (select != uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
if (!pinned || (ts->uv_flag & UV_SYNC_SELECTION)) {
/* UV_SYNC_SELECTION - can't do pinned selection */
if (BLI_rctf_isect_pt_v(&rectf, luv->uv)) {
@@ -3785,7 +3787,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
const eSelectOp sel_op = ED_select_op_modal(RNA_enum_get(op->ptr, "mode"),
WM_gesture_is_modal_first(op->customdata));
@@ -3854,7 +3856,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
}
bool has_selected = false;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if ((select) != (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))) {
+ if (select != uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (uv_circle_select_is_point_inside(luv->uv, offset, ellipse)) {
changed = true;
@@ -3991,7 +3993,7 @@ static bool do_lasso_select_mesh_uv(bContext *C,
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
if (use_pre_deselect) {
uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
@@ -4084,7 +4086,7 @@ static bool do_lasso_select_mesh_uv(bContext *C,
}
bool has_selected = false;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if ((select) != (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))) {
+ 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);
if (do_lasso_select_mesh_uv_is_point_inside(
region, &rect, mcoords, mcoords_len, luv->uv)) {
@@ -4190,7 +4192,7 @@ static int uv_select_pinned_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -4325,7 +4327,7 @@ static int uv_select_overlap(bContext *C, const bool extend)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
/* Calculate maximum number of tree nodes and prepare initial selection. */
uint uv_tri_len = 0;
@@ -4673,7 +4675,7 @@ static int uv_select_similar_vert_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
int max_verts_selected_all = 0;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@@ -4703,7 +4705,7 @@ static int uv_select_similar_vert_exec(bContext *C, wmOperator *op)
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
float ob_m3[3][3];
- copy_m3_m4(ob_m3, ob->obmat);
+ copy_m3_m4(ob_m3, ob->object_to_world);
BMFace *face;
BMIter iter;
@@ -4740,7 +4742,7 @@ static int uv_select_similar_vert_exec(bContext *C, wmOperator *op)
bool changed = false;
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
float ob_m3[3][3];
- copy_m3_m4(ob_m3, ob->obmat);
+ copy_m3_m4(ob_m3, ob->object_to_world);
BMFace *face;
BMIter iter;
@@ -4786,7 +4788,7 @@ static int uv_select_similar_edge_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
int max_edges_selected_all = 0;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@@ -4816,7 +4818,7 @@ static int uv_select_similar_edge_exec(bContext *C, wmOperator *op)
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
float ob_m3[3][3];
- copy_m3_m4(ob_m3, ob->obmat);
+ copy_m3_m4(ob_m3, ob->object_to_world);
BMFace *face;
BMIter iter;
@@ -4857,7 +4859,7 @@ static int uv_select_similar_edge_exec(bContext *C, wmOperator *op)
bool changed = false;
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
float ob_m3[3][3];
- copy_m3_m4(ob_m3, ob->obmat);
+ copy_m3_m4(ob_m3, ob->object_to_world);
BMFace *face;
BMIter iter;
@@ -4905,7 +4907,7 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
int max_faces_selected_all = 0;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@@ -4925,7 +4927,7 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op)
BMesh *bm = em->bm;
float ob_m3[3][3];
- copy_m3_m4(ob_m3, ob->obmat);
+ copy_m3_m4(ob_m3, ob->object_to_world);
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
@@ -4961,7 +4963,7 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op)
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
float ob_m3[3][3];
- copy_m3_m4(ob_m3, ob->obmat);
+ copy_m3_m4(ob_m3, ob->object_to_world);
BMFace *face;
BMIter iter;
@@ -5010,7 +5012,7 @@ static int uv_select_similar_island_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
ListBase *island_list_ptr = MEM_callocN(sizeof(*island_list_ptr) * objects_len, __func__);
int island_list_len = 0;
@@ -5051,7 +5053,7 @@ static int uv_select_similar_island_exec(bContext *C, wmOperator *op)
}
float ob_m3[3][3];
- copy_m3_m4(ob_m3, obedit->obmat);
+ copy_m3_m4(ob_m3, obedit->object_to_world);
int index;
LISTBASE_FOREACH_INDEX (struct FaceIsland *, island, &island_list_ptr[ob_index], index) {
@@ -5080,7 +5082,7 @@ static int uv_select_similar_island_exec(bContext *C, wmOperator *op)
continue;
}
float ob_m3[3][3];
- copy_m3_m4(ob_m3, obedit->obmat);
+ copy_m3_m4(ob_m3, obedit->object_to_world);
bool changed = false;
int index;
@@ -5503,7 +5505,7 @@ void ED_uvedit_selectmode_clean_multi(bContext *C)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, ((View3D *)NULL), &objects_len);
+ scene, view_layer, ((View3D *)NULL), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index e19cc67bd16..865262e6947 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -14,6 +14,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_windowmanager_types.h"
#include "BLI_ghash.h"
#include "BLI_math.h"
@@ -28,6 +29,7 @@
#include "BKE_editmesh.h"
#include "BKE_layer.h"
#include "BKE_mesh_mapping.h"
+#include "BKE_report.h"
#include "DEG_depsgraph.h"
@@ -2174,6 +2176,28 @@ static int stitch_init_all(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = scene->toolsettings;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
+ scene, view_layer, v3d, &objects_len);
+
+ if (objects_len == 0) {
+ MEM_freeN(objects);
+ BKE_report(op->reports, RPT_ERROR, "No objects selected");
+ return 0;
+ }
+
+ if (objects_len > RNA_MAX_ARRAY_LENGTH) {
+ MEM_freeN(objects);
+ BKE_reportf(op->reports,
+ RPT_ERROR,
+ "Stitching only works with less than %i objects selected (%u selected)",
+ RNA_MAX_ARRAY_LENGTH,
+ objects_len);
+ return 0;
+ }
+
StitchStateContainer *ssc = MEM_callocN(sizeof(StitchStateContainer), "stitch collection");
op->customdata = ssc;
@@ -2208,21 +2232,6 @@ static int stitch_init_all(bContext *C, wmOperator *op)
}
}
- ssc->objects_len = 0;
- ssc->states = NULL;
-
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, v3d, &objects_len);
-
- if (objects_len == 0) {
- MEM_freeN(objects);
- state_delete_all(ssc);
- return 0;
- }
-
ssc->objects = MEM_callocN(sizeof(Object *) * objects_len, "Object *ssc->objects");
ssc->states = MEM_callocN(sizeof(StitchState *) * objects_len, "StitchState");
ssc->objects_len = 0;
@@ -2288,6 +2297,7 @@ static int stitch_init_all(bContext *C, wmOperator *op)
if (ssc->objects_len == 0) {
state_delete_all(ssc);
+ BKE_report(op->reports, RPT_ERROR, "Could not initialize stitching on any selected object");
return 0;
}
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index b01a24af68f..071f1c44c6b 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -798,7 +798,7 @@ static bool minimize_stretch_init(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
if (!uvedit_have_selection_multi(scene, objects, objects_len, &options)) {
MEM_freeN(objects);
@@ -1050,50 +1050,6 @@ void UV_OT_minimize_stretch(wmOperatorType *ot)
/** \name Pack UV Islands Operator
* \{ */
-static void uvedit_pack_islands(const Scene *scene, Object *ob, BMesh *bm)
-{
- const UnwrapOptions options = {
- .topology_from_uvs = true,
- .only_selected_faces = false,
- .only_selected_uvs = true,
- .fill_holes = false,
- .correct_aspect = false,
- };
-
- bool rotate = true;
- bool ignore_pinned = false;
-
- ParamHandle *handle = construct_param_handle(scene, ob, bm, &options, NULL);
- GEO_uv_parametrizer_pack(handle, scene->toolsettings->uvcalc_margin, rotate, ignore_pinned);
- GEO_uv_parametrizer_flush(handle);
- GEO_uv_parametrizer_delete(handle);
-}
-
-/**
- * \warning Since this uses #ParamHandle it doesn't work with non-manifold meshes (see T82637).
- * Use #ED_uvedit_pack_islands_multi for a more general solution.
- *
- * TODO: remove this function, in favor of #ED_uvedit_pack_islands_multi.
- */
-static void uvedit_pack_islands_multi(const Scene *scene,
- Object **objects,
- const uint objects_len,
- const UnwrapOptions *options,
- bool rotate,
- bool ignore_pinned)
-{
- ParamHandle *handle = construct_param_handle_multi(scene, objects, objects_len, options);
- GEO_uv_parametrizer_pack(handle, scene->toolsettings->uvcalc_margin, rotate, ignore_pinned);
- GEO_uv_parametrizer_flush(handle);
- GEO_uv_parametrizer_delete(handle);
-
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- DEG_id_tag_update(obedit->data, ID_RECALC_GEOMETRY);
- WM_main_add_notifier(NC_GEOM | ND_DATA, obedit->data);
- }
-}
-
/* Packing targets. */
enum {
PACK_UDIM_SRC_CLOSEST = 0,
@@ -1116,7 +1072,7 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
/* Early exit in case no UVs are selected. */
if (!uvedit_have_selection_multi(scene, objects, objects_len, &options)) {
@@ -1125,7 +1081,6 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
}
/* RNA props */
- const bool rotate = RNA_boolean_get(op->ptr, "rotate");
const int udim_source = RNA_enum_get(op->ptr, "udim_source");
if (RNA_struct_property_is_set(op->ptr, "margin")) {
scene->toolsettings->uvcalc_margin = RNA_float_get(op->ptr, "margin");
@@ -1139,22 +1094,42 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
const bool use_udim_params = ED_uvedit_udim_params_from_image_space(
sima, use_active, &udim_params);
+ const struct UVPackIsland_Params pack_island_params = {
+ .rotate = RNA_boolean_get(op->ptr, "rotate"),
+ .only_selected_uvs = options.only_selected_uvs,
+ .only_selected_faces = options.only_selected_faces,
+ .use_seams = !options.topology_from_uvs || options.topology_from_uvs_use_seams,
+ .correct_aspect = options.correct_aspect,
+ .ignore_pinned = false,
+ .margin_method = RNA_enum_get(op->ptr, "margin_method"),
+ .margin = RNA_float_get(op->ptr, "margin"),
+ };
ED_uvedit_pack_islands_multi(scene,
objects,
objects_len,
+ NULL,
use_udim_params ? &udim_params : NULL,
- &(struct UVPackIsland_Params){
- .rotate = rotate,
- .rotate_align_axis = -1,
- .only_selected_uvs = true,
- .only_selected_faces = true,
- .correct_aspect = true,
- });
+ &pack_island_params);
MEM_freeN(objects);
return OPERATOR_FINISHED;
}
+const EnumPropertyItem pack_margin_method[] = {
+ {ED_UVPACK_MARGIN_SCALED,
+ "SCALED",
+ 0,
+ "Scaled",
+ "Use scale of existing UVs to multiply margin"},
+ {ED_UVPACK_MARGIN_ADD, "ADD", 0, "Add", "Just add the margin, ignoring any UV scale"},
+ {ED_UVPACK_MARGIN_FRACTION,
+ "FRACTION",
+ 0,
+ "Fraction",
+ "Specify a precise fraction of final UV output"},
+ {0, NULL, 0, NULL, NULL},
+};
+
void UV_OT_pack_islands(wmOperatorType *ot)
{
static const EnumPropertyItem pack_target[] = {
@@ -1181,6 +1156,8 @@ void UV_OT_pack_islands(wmOperatorType *ot)
/* properties */
RNA_def_enum(ot->srna, "udim_source", pack_target, PACK_UDIM_SRC_CLOSEST, "Pack to", "");
RNA_def_boolean(ot->srna, "rotate", true, "Rotate", "Rotate islands for best fit");
+ RNA_def_enum(
+ ot->srna, "margin_method", pack_margin_method, ED_UVPACK_MARGIN_SCALED, "Margin Method", "");
RNA_def_float_factor(
ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f);
}
@@ -1208,7 +1185,7 @@ static int average_islands_scale_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
if (!uvedit_have_selection_multi(scene, objects, objects_len, &options)) {
MEM_freeN(objects);
@@ -1411,8 +1388,8 @@ static void uv_map_transform_center(const Scene *scene,
}
case V3D_AROUND_CURSOR: /* cursor center */
{
- invert_m4_m4(ob->imat, ob->obmat);
- mul_v3_m4v3(r_center, ob->imat, scene->cursor.location);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
+ mul_v3_m4v3(r_center, ob->world_to_object, scene->cursor.location);
break;
}
case V3D_AROUND_ACTIVE: {
@@ -1462,7 +1439,7 @@ static void uv_map_rotation_matrix_ex(float result[4][4],
zero_v3(viewmatrix[3]);
/* get rotation of the current object matrix */
- copy_m4_m4(rotobj, ob->obmat);
+ copy_m4_m4(rotobj, ob->object_to_world);
zero_v3(rotobj[3]);
/* but shifting */
@@ -1797,8 +1774,8 @@ static void uv_map_clip_correct(const Scene *scene,
dy = 1.0f / dy;
}
- if (dx == 1.0f && dy == 1.0f) {
- /* Scaling by 1.0 has no effect. */
+ if (dx == 1.0f && dy == 1.0f && min[0] == 0.0f && min[1] == 0.0f) {
+ /* Scaling by 1.0, without translating, has no effect. */
return;
}
@@ -1834,7 +1811,7 @@ static void uv_map_clip_correct(const Scene *scene,
/** \name UV Unwrap Operator
* \{ */
-/* Assumes UV Map exists, doesn't run update funcs. */
+/* Assumes UV Map exists, doesn't run update functions. */
static void uvedit_unwrap(const Scene *scene,
Object *obedit,
const UnwrapOptions *options,
@@ -1893,12 +1870,19 @@ void ED_uvedit_live_unwrap(const Scene *scene, Object **objects, int objects_len
.fill_holes = (scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES) != 0,
.correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) == 0,
};
-
- bool rotate = true;
- bool ignore_pinned = true;
-
uvedit_unwrap_multi(scene, objects, objects_len, &options, NULL);
- uvedit_pack_islands_multi(scene, objects, objects_len, &options, rotate, ignore_pinned);
+
+ const struct UVPackIsland_Params pack_island_params = {
+ .rotate = true,
+ .only_selected_uvs = options.only_selected_uvs,
+ .only_selected_faces = options.only_selected_faces,
+ .use_seams = !options.topology_from_uvs || options.topology_from_uvs_use_seams,
+ .correct_aspect = options.correct_aspect,
+ .ignore_pinned = true,
+ .margin_method = ED_UVPACK_MARGIN_SCALED,
+ .margin = scene->toolsettings->uvcalc_margin,
+ };
+ ED_uvedit_pack_islands_multi(scene, objects, objects_len, NULL, NULL, &pack_island_params);
}
}
@@ -1920,7 +1904,7 @@ static int unwrap_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
UnwrapOptions options = {
.topology_from_uvs = false,
@@ -1930,8 +1914,6 @@ static int unwrap_exec(bContext *C, wmOperator *op)
.correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"),
};
- bool rotate = true;
- bool ignore_pinned = true;
if (CTX_wm_space_image(C)) {
/* Inside the UV Editor, only unwrap selected UVs. */
options.only_selected_uvs = true;
@@ -1966,7 +1948,7 @@ static int unwrap_exec(bContext *C, wmOperator *op)
continue;
}
- mat4_to_size(obsize, obedit->obmat);
+ mat4_to_size(obsize, obedit->object_to_world);
if (!(fabsf(obsize[0] - obsize[1]) < 1e-4f && fabsf(obsize[1] - obsize[2]) < 1e-4f)) {
if ((reported_errors & UNWRAP_ERROR_NONUNIFORM) == 0) {
BKE_report(op->reports,
@@ -1976,7 +1958,7 @@ static int unwrap_exec(bContext *C, wmOperator *op)
reported_errors |= UNWRAP_ERROR_NONUNIFORM;
}
}
- else if (is_negative_m4(obedit->obmat)) {
+ else if (is_negative_m4(obedit->object_to_world)) {
if ((reported_errors & UNWRAP_ERROR_NEGATIVE) == 0) {
BKE_report(
op->reports,
@@ -2036,7 +2018,18 @@ static int unwrap_exec(bContext *C, wmOperator *op)
.count_failed = 0,
};
uvedit_unwrap_multi(scene, objects, objects_len, &options, &result_info);
- uvedit_pack_islands_multi(scene, objects, objects_len, &options, rotate, ignore_pinned);
+
+ const struct UVPackIsland_Params pack_island_params = {
+ .rotate = true,
+ .only_selected_uvs = options.only_selected_uvs,
+ .only_selected_faces = options.only_selected_faces,
+ .use_seams = !options.topology_from_uvs || options.topology_from_uvs_use_seams,
+ .correct_aspect = options.correct_aspect,
+ .ignore_pinned = true,
+ .margin_method = RNA_enum_get(op->ptr, "margin_method"),
+ .margin = RNA_float_get(op->ptr, "margin"),
+ };
+ ED_uvedit_pack_islands_multi(scene, objects, objects_len, NULL, NULL, &pack_island_params);
MEM_freeN(objects);
@@ -2099,6 +2092,8 @@ void UV_OT_unwrap(wmOperatorType *ot)
0,
"Use Subdivision Surface",
"Map UVs taking vertex position after Subdivision Surface modifier has been applied");
+ RNA_def_enum(
+ ot->srna, "margin_method", pack_margin_method, ED_UVPACK_MARGIN_SCALED, "Margin Method", "");
RNA_def_float_factor(
ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f);
}
@@ -2119,7 +2114,6 @@ typedef struct ThickFace {
static int smart_uv_project_thickface_area_cmp_fn(const void *tf_a_p, const void *tf_b_p)
{
-
const ThickFace *tf_a = (ThickFace *)tf_a_p;
const ThickFace *tf_b = (ThickFace *)tf_b_p;
@@ -2272,7 +2266,7 @@ static int smart_project_exec(bContext *C, wmOperator *op)
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, v3d, &objects_len);
+ scene, view_layer, v3d, &objects_len);
Object **objects_changed = MEM_mallocN(sizeof(*objects_changed) * objects_len, __func__);
uint object_changed_len = 0;
@@ -2413,19 +2407,17 @@ static int smart_project_exec(bContext *C, wmOperator *op)
/* Depsgraph refresh functions are called here. */
const bool correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect");
- ED_uvedit_pack_islands_multi(scene,
- objects_changed,
- object_changed_len,
- NULL,
- &(struct UVPackIsland_Params){
- .rotate = true,
- /* We could make this optional. */
- .rotate_align_axis = 1,
- .only_selected_uvs = true,
- .only_selected_faces = true,
- .correct_aspect = correct_aspect,
- .use_seams = true,
- });
+
+ const struct UVPackIsland_Params params = {
+ .rotate = true,
+ .only_selected_uvs = only_selected_uvs,
+ .only_selected_faces = true,
+ .correct_aspect = correct_aspect,
+ .use_seams = true,
+ .margin_method = RNA_enum_get(op->ptr, "margin_method"),
+ .margin = RNA_float_get(op->ptr, "island_margin"),
+ };
+ ED_uvedit_pack_islands_multi(scene, objects_changed, object_changed_len, NULL, NULL, &params);
/* #ED_uvedit_pack_islands_multi only supports `per_face_aspect = false`. */
const bool per_face_aspect = false;
@@ -2467,6 +2459,8 @@ void UV_OT_smart_project(wmOperatorType *ot)
DEG2RADF(89.0f));
RNA_def_property_float_default(prop, DEG2RADF(66.0f));
+ RNA_def_enum(
+ ot->srna, "margin_method", pack_margin_method, ED_UVPACK_MARGIN_SCALED, "Margin Method", "");
RNA_def_float(ot->srna,
"island_margin",
0.0f,
@@ -2537,14 +2531,14 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
/* NOTE: objects that aren't touched are set to NULL (to skip clipping). */
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, v3d, &objects_len);
+ scene, view_layer, v3d, &objects_len);
if (use_orthographic) {
/* Calculate average object position. */
float objects_pos_avg[4] = {0};
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- add_v4_v4(objects_pos_avg, objects[ob_index]->obmat[3]);
+ add_v4_v4(objects_pos_avg, objects[ob_index]->object_to_world[3]);
}
mul_v4_fl(objects_pos_avg, 1.0f / objects_len);
@@ -2582,7 +2576,7 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
const bool camera_bounds = RNA_boolean_get(op->ptr, "camera_bounds");
struct ProjCameraInfo *uci = BLI_uvproject_camera_info(
v3d->camera,
- obedit->obmat,
+ obedit->object_to_world,
camera_bounds ? (scene->r.xsch * scene->r.xasp) : 1.0f,
camera_bounds ? (scene->r.ysch * scene->r.yasp) : 1.0f);
@@ -2603,7 +2597,7 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
}
}
else {
- copy_m4_m4(rotmat, obedit->obmat);
+ copy_m4_m4(rotmat, obedit->object_to_world);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
@@ -2688,12 +2682,13 @@ void UV_OT_project_from_view(wmOperatorType *ot)
static int reset_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, v3d, &objects_len);
+ scene, view_layer, v3d, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Mesh *me = (Mesh *)obedit->data;
@@ -2803,7 +2798,7 @@ static int sphere_project_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, v3d, &objects_len);
+ scene, view_layer, v3d, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -2915,7 +2910,7 @@ static int cylinder_project_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, v3d, &objects_len);
+ scene, view_layer, v3d, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -3060,7 +3055,7 @@ static int cube_project_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, v3d, &objects_len);
+ scene, view_layer, v3d, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -3163,13 +3158,24 @@ void ED_uvedit_add_simple_uvs(Main *bmain, const Scene *scene, Object *ob)
.calc_face_normal = true,
.calc_vert_normal = true,
}));
- /* select all uv loops first - pack parameters needs this to make sure charts are registered */
+ /* Select all UVs for cube_project. */
ED_uvedit_select_all(bm);
/* A cube size of 2.0 maps [-1..1] vertex coords to [0.0..1.0] in UV coords. */
uvedit_unwrap_cube_project(scene, bm, 2.0, false, false, NULL);
- /* Set the margin really quickly before the packing operation. */
- scene->toolsettings->uvcalc_margin = 0.001f;
- uvedit_pack_islands(scene, ob, bm);
+
+ /* Pack UVs. */
+ const struct UVPackIsland_Params params = {
+ .rotate = true,
+ .only_selected_uvs = false,
+ .only_selected_faces = false,
+ .correct_aspect = false,
+ .use_seams = true,
+ .margin_method = ED_UVPACK_MARGIN_SCALED,
+ .margin = 0.001f,
+ };
+ ED_uvedit_pack_islands_multi(scene, &ob, 1, &bm, NULL, &params);
+
+ /* Write back from BMesh to Mesh. */
BM_mesh_bm_to_me(bmain, bm, me, (&(struct BMeshToMeshParams){0}));
BM_mesh_free(bm);
diff --git a/source/blender/freestyle/CMakeLists.txt b/source/blender/freestyle/CMakeLists.txt
index 40db98ebd74..8f9e493023c 100644
--- a/source/blender/freestyle/CMakeLists.txt
+++ b/source/blender/freestyle/CMakeLists.txt
@@ -561,6 +561,10 @@ set(INC_SYS
add_definitions(-DWITH_FREESTYLE)
+if(WITH_PYTHON_MODULE)
+ add_definitions(-DPy_ENABLE_SHARED)
+endif()
+
if(WITH_PYTHON_SAFETY)
# For bpy_rna.h access.
add_definitions(-DWITH_PYTHON_SAFETY)
diff --git a/source/blender/freestyle/intern/application/AppCanvas.cpp b/source/blender/freestyle/intern/application/AppCanvas.cpp
index ee316bbf220..109afd48b1b 100644
--- a/source/blender/freestyle/intern/application/AppCanvas.cpp
+++ b/source/blender/freestyle/intern/application/AppCanvas.cpp
@@ -89,7 +89,7 @@ void AppCanvas::init()
void AppCanvas::postDraw()
{
- for (unsigned int i = 0; i < _StyleModules.size(); i++) {
+ for (uint i = 0; i < _StyleModules.size(); i++) {
if (!_StyleModules[i]->getDisplayed() || !_Layers[i]) {
continue;
}
@@ -118,8 +118,8 @@ void AppCanvas::readColorPixels(int x, int y, int w, int h, RGBImage &oImage) co
int ymax = border().getMax().y();
int rectx = _pass_diffuse.width;
int recty = _pass_diffuse.height;
- float xfac = ((float)rectx) / ((float)(xmax - xmin));
- float yfac = ((float)recty) / ((float)(ymax - ymin));
+ float xfac = float(rectx) / float(xmax - xmin);
+ float yfac = float(recty) / float(ymax - ymin);
#if 0
if (G.debug & G_DEBUG_FREESTYLE) {
printf("readColorPixels %d x %d @ (%d, %d) in %d x %d [%d x %d] -- %d x %d @ %d%%\n",
@@ -138,12 +138,12 @@ void AppCanvas::readColorPixels(int x, int y, int w, int h, RGBImage &oImage) co
#endif
int ii, jj;
for (int j = 0; j < h; j++) {
- jj = (int)((y - ymin + j) * yfac);
+ jj = int((y - ymin + j) * yfac);
if (jj < 0 || jj >= recty) {
continue;
}
for (int i = 0; i < w; i++) {
- ii = (int)((x - xmin + i) * xfac);
+ ii = int((x - xmin + i) * xfac);
if (ii < 0 || ii >= rectx) {
continue;
}
@@ -167,8 +167,8 @@ void AppCanvas::readDepthPixels(int x, int y, int w, int h, GrayImage &oImage) c
int ymax = border().getMax().y();
int rectx = _pass_z.width;
int recty = _pass_z.height;
- float xfac = ((float)rectx) / ((float)(xmax - xmin));
- float yfac = ((float)recty) / ((float)(ymax - ymin));
+ float xfac = float(rectx) / float(xmax - xmin);
+ float yfac = float(recty) / float(ymax - ymin);
#if 0
if (G.debug & G_DEBUG_FREESTYLE) {
printf("readDepthPixels %d x %d @ (%d, %d) in %d x %d [%d x %d] -- %d x %d @ %d%%\n",
@@ -187,12 +187,12 @@ void AppCanvas::readDepthPixels(int x, int y, int w, int h, GrayImage &oImage) c
#endif
int ii, jj;
for (int j = 0; j < h; j++) {
- jj = (int)((y - ymin + j) * yfac);
+ jj = int((y - ymin + j) * yfac);
if (jj < 0 || jj >= recty) {
continue;
}
for (int i = 0; i < w; i++) {
- ii = (int)((x - xmin + i) * xfac);
+ ii = int((x - xmin + i) * xfac);
if (ii < 0 || ii >= rectx) {
continue;
}
diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp
index cc815b5317f..670482a23a6 100644
--- a/source/blender/freestyle/intern/application/Controller.cpp
+++ b/source/blender/freestyle/intern/application/Controller.cpp
@@ -919,7 +919,7 @@ Render *Controller::RenderStrokes(Render *re, bool render)
return freestyle_render;
}
-void Controller::InsertStyleModule(unsigned index, const char *iFileName)
+void Controller::InsertStyleModule(uint index, const char *iFileName)
{
if (!BLI_path_extension_check(iFileName, ".py")) {
cerr << "Error: Cannot load \"" << string(iFileName) << "\", unknown extension" << endl;
@@ -930,13 +930,13 @@ void Controller::InsertStyleModule(unsigned index, const char *iFileName)
_Canvas->InsertStyleModule(index, sm);
}
-void Controller::InsertStyleModule(unsigned index, const char *iName, const char *iBuffer)
+void Controller::InsertStyleModule(uint index, const char *iName, const char *iBuffer)
{
StyleModule *sm = new BufferedStyleModule(iBuffer, iName, _inter);
_Canvas->InsertStyleModule(index, sm);
}
-void Controller::InsertStyleModule(unsigned index, const char *iName, struct Text *iText)
+void Controller::InsertStyleModule(uint index, const char *iName, struct Text *iText)
{
StyleModule *sm = new BlenderStyleModule(iText, iName, _inter);
_Canvas->InsertStyleModule(index, sm);
@@ -947,7 +947,7 @@ void Controller::AddStyleModule(const char * /*iFileName*/)
//_pStyleWindow->Add(iFileName);
}
-void Controller::RemoveStyleModule(unsigned index)
+void Controller::RemoveStyleModule(uint index)
{
_Canvas->RemoveStyleModule(index);
}
@@ -957,34 +957,34 @@ void Controller::Clear()
_Canvas->Clear();
}
-void Controller::ReloadStyleModule(unsigned index, const char *iFileName)
+void Controller::ReloadStyleModule(uint index, const char *iFileName)
{
StyleModule *sm = new StyleModule(iFileName, _inter);
_Canvas->ReplaceStyleModule(index, sm);
}
-void Controller::SwapStyleModules(unsigned i1, unsigned i2)
+void Controller::SwapStyleModules(uint i1, uint i2)
{
_Canvas->SwapStyleModules(i1, i2);
}
-void Controller::toggleLayer(unsigned index, bool iDisplay)
+void Controller::toggleLayer(uint index, bool iDisplay)
{
_Canvas->setVisible(index, iDisplay);
}
-void Controller::setModified(unsigned index, bool iMod)
+void Controller::setModified(uint index, bool iMod)
{
//_pStyleWindow->setModified(index, iMod);
_Canvas->setModified(index, iMod);
updateCausalStyleModules(index + 1);
}
-void Controller::updateCausalStyleModules(unsigned index)
+void Controller::updateCausalStyleModules(uint index)
{
- vector<unsigned> vec;
+ vector<uint> vec;
_Canvas->causalStyleModules(vec, index);
- for (vector<unsigned>::const_iterator it = vec.begin(); it != vec.end(); it++) {
+ for (vector<uint>::const_iterator it = vec.begin(); it != vec.end(); it++) {
//_pStyleWindow->setModified(*it, true);
_Canvas->setModified(*it, true);
}
@@ -1004,7 +1004,7 @@ NodeGroup *Controller::BuildRep(vector<ViewEdge *>::iterator vedges_begin,
mat.setDiffuse(1, 1, 0.3, 1);
tesselator2D.setFrsMaterial(mat);
- return (tesselator2D.Tesselate(vedges_begin, vedges_end));
+ return tesselator2D.Tesselate(vedges_begin, vedges_end);
}
void Controller::toggleEdgeTesselationNature(Nature::EdgeNature iNature)
@@ -1051,14 +1051,14 @@ void Controller::displayDensityCurves(int x, int y)
return;
}
- unsigned int i, j;
+ uint i, j;
using densityCurve = vector<Vec3r>;
vector<densityCurve> curves(svm->getNumberOfOrientations() + 1);
vector<densityCurve> curvesDirection(svm->getNumberOfPyramidLevels());
// collect the curves values
- unsigned nbCurves = svm->getNumberOfOrientations() + 1;
- unsigned nbPoints = svm->getNumberOfPyramidLevels();
+ uint nbCurves = svm->getNumberOfOrientations() + 1;
+ uint nbPoints = svm->getNumberOfPyramidLevels();
if (!nbPoints) {
return;
}
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
index c4a633e920e..53c2b1d235b 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
@@ -63,16 +63,18 @@ NodeGroup *BlenderFileLoader::Load()
int id = 0;
const eEvaluationMode eval_mode = DEG_get_mode(_depsgraph);
- DEG_OBJECT_ITER_BEGIN (_depsgraph,
- ob,
- DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
- DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE |
- DEG_ITER_OBJECT_FLAG_DUPLI) {
+ DEGObjectIterSettings deg_iter_settings{};
+ deg_iter_settings.depsgraph = _depsgraph;
+ deg_iter_settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
if (_pRenderMonitor && _pRenderMonitor->testBreak()) {
break;
}
- if (ob->base_flag & (BASE_HOLDOUT | BASE_INDIRECT_ONLY)) {
+ if ((ob->base_flag & (BASE_HOLDOUT | BASE_INDIRECT_ONLY)) ||
+ (ob->visibility_flag & OB_HOLDOUT)) {
continue;
}
@@ -272,7 +274,7 @@ void BlenderFileLoader::addTriangle(struct LoaderState *ls,
#if 0
float len;
#endif
- unsigned int i, j;
+ uint i, j;
IndexedFaceSet::FaceEdgeMark marks = 0;
// initialize the bounding box by the first vertex
@@ -429,13 +431,13 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id)
// Compute matrix including camera transform
float obmat[4][4], nmat[4][4];
- mul_m4_m4m4(obmat, viewmat, ob->obmat);
+ mul_m4_m4m4(obmat, viewmat, ob->object_to_world);
invert_m4_m4(nmat, obmat);
transpose_m4(nmat);
// We count the number of triangles after the clipping by the near and far view
// planes is applied (NOTE: mesh vertices are in the camera coordinate system).
- unsigned numFaces = 0;
+ uint numFaces = 0;
float v1[3], v2[3], v3[3];
float n1[3], n2[3], n3[3], facenormal[3];
int clip[3];
@@ -470,16 +472,16 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id)
NodeGroup *currentMesh = new NodeGroup;
NodeShape *shape = new NodeShape;
- unsigned vSize = 3 * 3 * numFaces;
+ uint vSize = 3 * 3 * numFaces;
float *vertices = new float[vSize];
- unsigned nSize = vSize;
+ uint nSize = vSize;
float *normals = new float[nSize];
- unsigned *numVertexPerFaces = new unsigned[numFaces];
+ uint *numVertexPerFaces = new uint[numFaces];
vector<Material *> meshMaterials;
vector<FrsMaterial> meshFrsMaterials;
IndexedFaceSet::TRIANGLES_STYLE *faceStyle = new IndexedFaceSet::TRIANGLES_STYLE[numFaces];
- unsigned i;
+ uint i;
for (i = 0; i < numFaces; i++) {
faceStyle[i] = IndexedFaceSet::TRIANGLES;
numVertexPerFaces[i] = 3;
@@ -487,11 +489,11 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id)
IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = new IndexedFaceSet::FaceEdgeMark[numFaces];
- unsigned viSize = 3 * numFaces;
- unsigned *VIndices = new unsigned[viSize];
- unsigned niSize = viSize;
- unsigned *NIndices = new unsigned[niSize];
- unsigned *MIndices = new unsigned[viSize]; // Material Indices
+ uint viSize = 3 * numFaces;
+ uint *VIndices = new uint[viSize];
+ uint niSize = viSize;
+ uint *NIndices = new uint[niSize];
+ uint *MIndices = new uint[viSize]; // Material Indices
struct LoaderState ls;
ls.pv = vertices;
@@ -548,7 +550,7 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id)
copy_v3_v3(n3, facenormal);
}
- unsigned int numTris = countClippedFaces(v1, v2, v3, clip);
+ uint numTris = countClippedFaces(v1, v2, v3, clip);
if (numTris == 0) {
continue;
}
@@ -577,7 +579,7 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id)
}
else {
// find if the Blender material is already in the list
- unsigned int i = 0;
+ uint i = 0;
bool found = false;
for (vector<Material *>::iterator it = meshMaterials.begin(), itend = meshMaterials.end();
@@ -623,22 +625,22 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id)
// We might have several times the same vertex. We want a clean
// shape with no real-vertex. Here, we are making a cleaning pass.
float *cleanVertices = nullptr;
- unsigned int cvSize;
- unsigned int *cleanVIndices = nullptr;
+ uint cvSize;
+ uint *cleanVIndices = nullptr;
GeomCleaner::CleanIndexedVertexArray(
vertices, vSize, VIndices, viSize, &cleanVertices, &cvSize, &cleanVIndices);
float *cleanNormals = nullptr;
- unsigned int cnSize;
- unsigned int *cleanNIndices = nullptr;
+ uint cnSize;
+ uint *cleanNIndices = nullptr;
GeomCleaner::CleanIndexedVertexArray(
normals, nSize, NIndices, niSize, &cleanNormals, &cnSize, &cleanNIndices);
// format materials array
FrsMaterial **marray = new FrsMaterial *[meshFrsMaterials.size()];
- unsigned int mindex = 0;
+ uint mindex = 0;
for (vector<FrsMaterial>::iterator m = meshFrsMaterials.begin(), mend = meshFrsMaterials.end();
m != mend;
++m) {
@@ -661,7 +663,7 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id)
// addressed later in WShape::MakeFace().
vector<detri_t> detriList;
Vec3r zero(0.0, 0.0, 0.0);
- unsigned vi0, vi1, vi2;
+ uint vi0, vi1, vi2;
for (i = 0; i < viSize; i += 3) {
detri_t detri;
vi0 = cleanVIndices[i];
@@ -694,7 +696,7 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id)
detri.v = zero;
detri.n = 0;
- for (unsigned int j = 0; j < viSize; j += 3) {
+ for (uint j = 0; j < viSize; j += 3) {
if (i == j) {
continue;
}
@@ -753,7 +755,7 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id)
if (G.debug & G_DEBUG_FREESTYLE) {
printf("Warning: Object %s contains %lu degenerated triangle%s (strokes may be incorrect)\n",
name,
- (long unsigned int)detriList.size(),
+ ulong(detriList.size()),
(detriList.size() > 1) ? "s" : "");
}
}
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index d2fc5a698bc..64e7be5169c 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -128,7 +128,8 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count)
view_layer->layflag = SCE_LAY_SOLID;
// Camera
- Object *object_camera = BKE_object_add(freestyle_bmain, view_layer, OB_CAMERA, nullptr);
+ Object *object_camera = BKE_object_add(
+ freestyle_bmain, freestyle_scene, view_layer, OB_CAMERA, nullptr);
Camera *camera = (Camera *)object_camera->data;
camera->type = CAM_ORTHO;
@@ -186,9 +187,9 @@ float BlenderStrokeRenderer::get_stroke_vertex_z() const
return -z;
}
-unsigned int BlenderStrokeRenderer::get_stroke_mesh_id() const
+uint BlenderStrokeRenderer::get_stroke_mesh_id() const
{
- unsigned mesh_id = _mesh_id;
+ uint mesh_id = _mesh_id;
BlenderStrokeRenderer *self = const_cast<BlenderStrokeRenderer *>(this);
self->_mesh_id--;
return mesh_id;
@@ -811,7 +812,7 @@ Object *BlenderStrokeRenderer::NewMesh() const
{
Object *ob;
char name[MAX_ID_NAME];
- unsigned int mesh_id = get_stroke_mesh_id();
+ uint mesh_id = get_stroke_mesh_id();
BLI_snprintf(name, MAX_ID_NAME, "0%08xOB", mesh_id);
ob = BKE_object_add_only_object(freestyle_bmain, OB_MESH, name);
diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
index b7aae20a5ea..af9ef7f352e 100644
--- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
+++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
@@ -131,9 +131,9 @@ static void init_view(Render *re)
int ymax = re->disprect.ymax;
float thickness = 1.0f;
- switch (re->r.line_thickness_mode) {
+ switch (re->scene->r.line_thickness_mode) {
case R_LINE_THICKNESS_ABSOLUTE:
- thickness = re->r.unit_line_thickness * (re->r.size / 100.0f);
+ thickness = re->scene->r.unit_line_thickness * (re->r.size / 100.0f);
break;
case R_LINE_THICKNESS_RELATIVE:
thickness = height / 480.0f;
@@ -485,7 +485,7 @@ void FRS_composite_result(Render *re, ViewLayer *view_layer, Render *freestyle_r
return;
}
- rl = render_get_active_layer(freestyle_render, freestyle_render->result);
+ rl = render_get_single_layer(freestyle_render, freestyle_render->result);
if (!rl) {
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "No source render layer to composite" << endl;
@@ -596,7 +596,7 @@ void FRS_init_stroke_renderer(Render *re)
controller->ResetRenderCount();
}
-void FRS_begin_stroke_rendering(Render *UNUSED(re))
+void FRS_begin_stroke_rendering(Render * /*re*/)
{
}
diff --git a/source/blender/freestyle/intern/geometry/Bezier.cpp b/source/blender/freestyle/intern/geometry/Bezier.cpp
index b12b189853c..30eece55d5f 100644
--- a/source/blender/freestyle/intern/geometry/Bezier.cpp
+++ b/source/blender/freestyle/intern/geometry/Bezier.cpp
@@ -50,7 +50,7 @@ void BezierCurveSegment::Build()
y[3] = p0->y();
int nvertices = 12;
- float increment = 1.0 / (float)nvertices;
+ float increment = 1.0 / float(nvertices);
float t = 0.0f;
for (int i = 0; i <= nvertices; ++i) {
_Vertices.emplace_back((x[3] + t * (x[2] + t * (x[1] + t * x[0]))),
diff --git a/source/blender/freestyle/intern/geometry/FastGrid.cpp b/source/blender/freestyle/intern/geometry/FastGrid.cpp
index 442087040bc..24ecacbad2a 100644
--- a/source/blender/freestyle/intern/geometry/FastGrid.cpp
+++ b/source/blender/freestyle/intern/geometry/FastGrid.cpp
@@ -20,7 +20,7 @@ void FastGrid::clear()
return;
}
- for (unsigned int i = 0; i < _cells_size; i++) {
+ for (uint i = 0; i < _cells_size; i++) {
if (_cells[i]) {
delete _cells[i];
}
@@ -32,7 +32,7 @@ void FastGrid::clear()
Grid::clear();
}
-void FastGrid::configure(const Vec3r &orig, const Vec3r &size, unsigned nb)
+void FastGrid::configure(const Vec3r &orig, const Vec3r &size, uint nb)
{
Grid::configure(orig, size, nb);
_cells_size = _cells_nb[0] * _cells_nb[1] * _cells_nb[2];
diff --git a/source/blender/freestyle/intern/geometry/FitCurve.cpp b/source/blender/freestyle/intern/geometry/FitCurve.cpp
index eb53fd1257c..0d47665c6d3 100644
--- a/source/blender/freestyle/intern/geometry/FitCurve.cpp
+++ b/source/blender/freestyle/intern/geometry/FitCurve.cpp
@@ -12,6 +12,8 @@
#include "FitCurve.h"
+#include "BLI_sys_types.h"
+
using namespace std;
namespace Freestyle {
@@ -45,7 +47,7 @@ static double V2SquaredLength(Vector2 *a)
/* returns length of input vector */
static double V2Length(Vector2 *a)
{
- return (sqrt(V2SquaredLength(a)));
+ return sqrt(V2SquaredLength(a));
}
static Vector2 *V2Scale(Vector2 *v, double newlen)
@@ -69,7 +71,7 @@ static double V2DistanceBetween2Points(Vector2 *a, Vector2 *b)
{
double dx = (*a)[0] - (*b)[0];
double dy = (*a)[1] - (*b)[1];
- return (sqrt((dx * dx) + (dy * dy)));
+ return sqrt((dx * dx) + (dy * dy));
}
/* return vector sum c = a+b */
@@ -273,7 +275,7 @@ static Vector2 BezierII(int degree, Vector2 *V, double t)
Vector2 *Vtemp; /* Local copy of control points */
/* Copy array */
- Vtemp = (Vector2 *)malloc((unsigned)((degree + 1) * sizeof(Vector2)));
+ Vtemp = (Vector2 *)malloc(uint((degree + 1) * sizeof(Vector2)));
for (i = 0; i <= degree; i++) {
Vtemp[i] = V[i];
}
@@ -376,7 +378,7 @@ static double *ChordLengthParameterize(Vector2 *d, int first, int last)
int i;
double *u; /* Parameterization */
- u = (double *)malloc((unsigned)(last - first + 1) * sizeof(double));
+ u = (double *)malloc(uint(last - first + 1) * sizeof(double));
u[0] = 0.0;
for (i = first + 1; i <= last; i++) {
diff --git a/source/blender/freestyle/intern/geometry/GeomCleaner.cpp b/source/blender/freestyle/intern/geometry/GeomCleaner.cpp
index 116154650f3..db6816bf045 100644
--- a/source/blender/freestyle/intern/geometry/GeomCleaner.cpp
+++ b/source/blender/freestyle/intern/geometry/GeomCleaner.cpp
@@ -25,20 +25,22 @@
#include "BKE_global.h"
+#include "BLI_sys_types.h"
+
using namespace std;
namespace Freestyle {
void GeomCleaner::SortIndexedVertexArray(const float *iVertices,
- unsigned iVSize,
- const unsigned *iIndices,
- unsigned iISize,
+ uint iVSize,
+ const uint *iIndices,
+ uint iISize,
float **oVertices,
- unsigned **oIndices)
+ uint **oIndices)
{
// First, we build a list of IndexVertex:
list<IndexedVertex> indexedVertices;
- unsigned i;
+ uint i;
for (i = 0; i < iVSize; i += 3) {
indexedVertices.emplace_back(Vec3f(iVertices[i], iVertices[i + 1], iVertices[i + 2]), i / 3);
}
@@ -47,11 +49,11 @@ void GeomCleaner::SortIndexedVertexArray(const float *iVertices,
indexedVertices.sort();
// build the indices mapping array:
- unsigned *mapIndices = new unsigned[iVSize / 3];
+ uint *mapIndices = new uint[iVSize / 3];
*oVertices = new float[iVSize];
list<IndexedVertex>::iterator iv;
- unsigned newIndex = 0;
- unsigned vIndex = 0;
+ uint newIndex = 0;
+ uint vIndex = 0;
for (iv = indexedVertices.begin(); iv != indexedVertices.end(); iv++) {
// Build the final results:
(*oVertices)[vIndex] = iv->x();
@@ -64,7 +66,7 @@ void GeomCleaner::SortIndexedVertexArray(const float *iVertices,
}
// Build the final index array:
- *oIndices = new unsigned[iISize];
+ *oIndices = new uint[iISize];
for (i = 0; i < iISize; i++) {
(*oIndices)[i] = 3 * mapIndices[iIndices[i] / 3];
}
@@ -73,21 +75,21 @@ void GeomCleaner::SortIndexedVertexArray(const float *iVertices,
}
void GeomCleaner::CompressIndexedVertexArray(const float *iVertices,
- unsigned iVSize,
- const unsigned *iIndices,
- unsigned iISize,
+ uint iVSize,
+ const uint *iIndices,
+ uint iISize,
float **oVertices,
- unsigned *oVSize,
- unsigned **oIndices)
+ uint *oVSize,
+ uint **oIndices)
{
// First, we build a list of IndexVertex:
vector<Vec3f> vertices;
- unsigned i;
+ uint i;
for (i = 0; i < iVSize; i += 3) {
vertices.emplace_back(iVertices[i], iVertices[i + 1], iVertices[i + 2]);
}
- unsigned *mapVertex = new unsigned[iVSize];
+ uint *mapVertex = new uint[iVSize];
vector<Vec3f>::iterator v = vertices.begin();
vector<Vec3f> compressedVertices;
@@ -123,7 +125,7 @@ void GeomCleaner::CompressIndexedVertexArray(const float *iVertices,
}
// Map the index array:
- *oIndices = new unsigned[iISize];
+ *oIndices = new uint[iISize];
for (i = 0; i < iISize; i++) {
(*oIndices)[i] = 3 * mapVertex[iIndices[i] / 3];
}
@@ -132,16 +134,16 @@ void GeomCleaner::CompressIndexedVertexArray(const float *iVertices,
}
void GeomCleaner::SortAndCompressIndexedVertexArray(const float *iVertices,
- unsigned iVSize,
- const unsigned *iIndices,
- unsigned iISize,
+ uint iVSize,
+ const uint *iIndices,
+ uint iISize,
float **oVertices,
- unsigned *oVSize,
- unsigned **oIndices)
+ uint *oVSize,
+ uint **oIndices)
{
// tmp arrays used to store the sorted data:
float *tmpVertices;
- unsigned *tmpIndices;
+ uint *tmpIndices;
Chronometer chrono;
// Sort data
@@ -172,35 +174,35 @@ struct GeomCleanerHasher {
#define _MOD 2147483647UL
inline size_t operator()(const Vec3r &p) const
{
- size_t res = ((unsigned long)(p[0] * _MUL)) % _MOD;
- res = ((res + (unsigned long)(p[1]) * _MUL)) % _MOD;
- return ((res + (unsigned long)(p[2]) * _MUL)) % _MOD;
+ size_t res = ulong(p[0] * _MUL) % _MOD;
+ res = (res + ulong(p[1]) * _MUL) % _MOD;
+ return (res + ulong(p[2]) * _MUL) % _MOD;
}
#undef _MUL
#undef _MOD
};
void GeomCleaner::CleanIndexedVertexArray(const float *iVertices,
- unsigned iVSize,
- const unsigned *iIndices,
- unsigned iISize,
+ uint iVSize,
+ const uint *iIndices,
+ uint iISize,
float **oVertices,
- unsigned *oVSize,
- unsigned **oIndices)
+ uint *oVSize,
+ uint **oIndices)
{
- using cleanHashTable = map<Vec3f, unsigned>;
+ using cleanHashTable = map<Vec3f, uint>;
vector<Vec3f> vertices;
- unsigned i;
+ uint i;
for (i = 0; i < iVSize; i += 3) {
vertices.emplace_back(iVertices[i], iVertices[i + 1], iVertices[i + 2]);
}
cleanHashTable ht;
- vector<unsigned> newIndices;
+ vector<uint> newIndices;
vector<Vec3f> newVertices;
// elimination of needless points
- unsigned currentIndex = 0;
+ uint currentIndex = 0;
vector<Vec3f>::const_iterator v = vertices.begin();
vector<Vec3f>::const_iterator end = vertices.end();
cleanHashTable::const_iterator found;
@@ -230,7 +232,7 @@ void GeomCleaner::CleanIndexedVertexArray(const float *iVertices,
}
// map new indices:
- *oIndices = new unsigned[iISize];
+ *oIndices = new uint[iISize];
for (i = 0; i < iISize; i++) {
(*oIndices)[i] = 3 * newIndices[iIndices[i] / 3];
}
diff --git a/source/blender/freestyle/intern/geometry/GeomUtils.cpp b/source/blender/freestyle/intern/geometry/GeomUtils.cpp
index ca1fb63ec64..b8beeed5880 100644
--- a/source/blender/freestyle/intern/geometry/GeomUtils.cpp
+++ b/source/blender/freestyle/intern/geometry/GeomUtils.cpp
@@ -7,10 +7,12 @@
#include "GeomUtils.h"
+#include "BLI_sys_types.h"
+
namespace Freestyle::GeomUtils {
// This internal procedure is defined below.
-bool intersect2dSegPoly(Vec2r *seg, Vec2r *poly, unsigned n);
+bool intersect2dSegPoly(Vec2r *seg, Vec2r *poly, uint n);
bool intersect2dSeg2dArea(const Vec2r &min, const Vec2r &max, const Vec2r &A, const Vec2r &B)
{
@@ -607,9 +609,9 @@ void transformVertex(const Vec3r &vert, const Matrix44r &matrix, Vec3r &res)
{
HVec3r hvert(vert), res_tmp;
real scale;
- for (unsigned int j = 0; j < 4; j++) {
+ for (uint j = 0; j < 4; j++) {
scale = hvert[j];
- for (unsigned int i = 0; i < 4; i++) {
+ for (uint i = 0; i < 4; i++) {
res_tmp[i] += matrix(i, j) * scale;
}
}
@@ -631,9 +633,9 @@ void transformVertices(const vector<Vec3r> &vertices, const Matrix44r &trans, ve
Vec3r rotateVector(const Matrix44r &mat, const Vec3r &v)
{
Vec3r res;
- for (unsigned int i = 0; i < 3; i++) {
+ for (uint i = 0; i < 3; i++) {
res[i] = 0;
- for (unsigned int j = 0; j < 3; j++) {
+ for (uint j = 0; j < 3; j++) {
res[i] += mat(i, j) * v[j];
}
}
@@ -718,9 +720,9 @@ void fromCameraToWorld(const Vec3r &p, Vec3r &q, const real model_view_matrix[4]
model_view_matrix[1][3],
model_view_matrix[2][3],
};
- for (unsigned short i = 0; i < 3; i++) {
+ for (ushort i = 0; i < 3; i++) {
q[i] = 0.0;
- for (unsigned short j = 0; j < 3; j++) {
+ for (ushort j = 0; j < 3; j++) {
q[i] += model_view_matrix[j][i] * (p[j] - translation[j]);
}
}
@@ -739,7 +741,7 @@ void fromCameraToWorld(const Vec3r &p, Vec3r &q, const real model_view_matrix[4]
#define PERP(u, v) ((u)[0] * (v)[1] - (u)[1] * (v)[0]) // 2D perp product
-inline bool intersect2dSegPoly(Vec2r *seg, Vec2r *poly, unsigned n)
+inline bool intersect2dSegPoly(Vec2r *seg, Vec2r *poly, uint n)
{
if (seg[0] == seg[1]) {
return false;
@@ -751,7 +753,7 @@ inline bool intersect2dSegPoly(Vec2r *seg, Vec2r *poly, unsigned n)
Vec2r dseg = seg[1] - seg[0]; // the segment direction vector
Vec2r e; // edge vector
- for (unsigned int i = 0; i < n; i++) { // process polygon edge poly[i]poly[i+1]
+ for (uint i = 0; i < n; i++) { // process polygon edge poly[i]poly[i+1]
e = poly[i + 1] - poly[i];
N = PERP(e, seg[0] - poly[i]);
D = -PERP(e, dseg);
@@ -790,7 +792,7 @@ inline bool overlapPlaneBox(Vec3r &normal, real d, Vec3r &maxbox)
{
Vec3r vmin, vmax;
- for (unsigned int q = X; q <= Z; q++) {
+ for (uint q = X; q <= Z; q++) {
if (normal[q] > 0.0f) {
vmin[q] = -maxbox[q];
vmax[q] = maxbox[q];
@@ -814,8 +816,8 @@ inline void fromCoordAToCoordB(const Vec3r &p, Vec3r &q, const real transform[4]
HVec3r hp(p);
HVec3r hq(0, 0, 0, 0);
- for (unsigned int i = 0; i < 4; i++) {
- for (unsigned int j = 0; j < 4; j++) {
+ for (uint i = 0; i < 4; i++) {
+ for (uint j = 0; j < 4; j++) {
hq[i] += transform[i][j] * hp[j];
}
}
@@ -825,7 +827,7 @@ inline void fromCoordAToCoordB(const Vec3r &p, Vec3r &q, const real transform[4]
return;
}
- for (unsigned int k = 0; k < 3; k++) {
+ for (uint k = 0; k < 3; k++) {
q[k] = hq[k] / hq[3];
}
}
diff --git a/source/blender/freestyle/intern/geometry/Grid.cpp b/source/blender/freestyle/intern/geometry/Grid.cpp
index 2b2272959e4..a2620aa25d7 100644
--- a/source/blender/freestyle/intern/geometry/Grid.cpp
+++ b/source/blender/freestyle/intern/geometry/Grid.cpp
@@ -36,7 +36,7 @@ void firstIntersectionGridVisitor::examineOccluder(Polygon3r *occ)
// check whether the edge and the polygon plane are coincident:
//-------------------------------------------------------------
// first let us compute the plane equation.
- Vec3r v1(((occ)->getVertices())[0]);
+ Vec3r v1((occ)->getVertices()[0]);
Vec3d normal((occ)->getNormal());
// soc unused - double d = -(v1 * normal);
@@ -93,7 +93,7 @@ void Grid::clear()
//_ray_occluders.clear();
}
-void Grid::configure(const Vec3r &orig, const Vec3r &size, unsigned nb)
+void Grid::configure(const Vec3r &orig, const Vec3r &size, uint nb)
{
_orig = orig;
Vec3r tmpSize = size;
@@ -125,9 +125,9 @@ void Grid::configure(const Vec3r &orig, const Vec3r &size, unsigned nb)
real edge = pow(cell_vol, 1.0 / 3.0);
// We compute the number of cells par edge such as we cover at least the whole box.
- unsigned i;
+ uint i;
for (i = 0; i < 3; i++) {
- _cells_nb[i] = (unsigned)floor(tmpSize[i] / edge) + 1;
+ _cells_nb[i] = uint(floor(tmpSize[i] / edge)) + 1;
}
_size = tmpSize;
@@ -161,7 +161,7 @@ void Grid::insertOccluder(Polygon3r *occluder)
// overlapping with the triangle in order to only fill in the ones really overlapping the
// triangle.
- unsigned i, x, y, z;
+ uint i, x, y, z;
vector<Vec3r>::const_iterator it;
Vec3u coord;
@@ -225,10 +225,10 @@ bool Grid::nextRayCell(Vec3u &current_cell, Vec3u &next_cell)
{
next_cell = current_cell;
real t_min, t;
- unsigned i;
+ uint i;
- t_min = FLT_MAX; // init tmin with handle of the case where one or 2 _u[i] = 0.
- unsigned coord = 0; // predominant coord(0=x, 1=y, 2=z)
+ t_min = FLT_MAX; // init tmin with handle of the case where one or 2 _u[i] = 0.
+ uint coord = 0; // predominant coord(0=x, 1=y, 2=z)
// using a parametric equation of a line : B = A + t u, we find the tx, ty and tz respectively
// corresponding to the intersections with the plans:
@@ -280,10 +280,7 @@ bool Grid::nextRayCell(Vec3u &current_cell, Vec3u &next_cell)
return true;
}
-void Grid::castRay(const Vec3r &orig,
- const Vec3r &end,
- OccludersSet &occluders,
- unsigned timestamp)
+void Grid::castRay(const Vec3r &orig, const Vec3r &end, OccludersSet &occluders, uint timestamp)
{
initRay(orig, end, timestamp);
allOccludersGridVisitor visitor(occluders);
@@ -293,7 +290,7 @@ void Grid::castRay(const Vec3r &orig,
void Grid::castInfiniteRay(const Vec3r &orig,
const Vec3r &dir,
OccludersSet &occluders,
- unsigned timestamp)
+ uint timestamp)
{
Vec3r end = Vec3r(orig + FLT_MAX * dir / dir.norm());
bool inter = initInfiniteRay(orig, dir, timestamp);
@@ -305,7 +302,7 @@ void Grid::castInfiniteRay(const Vec3r &orig,
}
Polygon3r *Grid::castRayToFindFirstIntersection(
- const Vec3r &orig, const Vec3r &dir, double &t, double &u, double &v, unsigned timestamp)
+ const Vec3r &orig, const Vec3r &dir, double &t, double &u, double &v, uint timestamp)
{
Polygon3r *occluder = nullptr;
Vec3r end = Vec3r(orig + FLT_MAX * dir / dir.norm());
@@ -325,7 +322,7 @@ Polygon3r *Grid::castRayToFindFirstIntersection(
return occluder;
}
-void Grid::initRay(const Vec3r &orig, const Vec3r &end, unsigned timestamp)
+void Grid::initRay(const Vec3r &orig, const Vec3r &end, uint timestamp)
{
_ray_dir = end - orig;
_t_end = _ray_dir.norm();
@@ -333,15 +330,15 @@ void Grid::initRay(const Vec3r &orig, const Vec3r &end, unsigned timestamp)
_ray_dir.normalize();
_timestamp = timestamp;
- for (unsigned i = 0; i < 3; i++) {
- _current_cell[i] = (unsigned)floor((orig[i] - _orig[i]) / _cell_size[i]);
+ for (uint i = 0; i < 3; i++) {
+ _current_cell[i] = uint(floor((orig[i] - _orig[i]) / _cell_size[i]));
// soc unused - unsigned u = _current_cell[i];
_pt[i] = orig[i] - _orig[i] - _current_cell[i] * _cell_size[i];
}
//_ray_occluders.clear();
}
-bool Grid::initInfiniteRay(const Vec3r &orig, const Vec3r &dir, unsigned timestamp)
+bool Grid::initInfiniteRay(const Vec3r &orig, const Vec3r &dir, uint timestamp)
{
_ray_dir = dir;
_t_end = FLT_MAX;
@@ -354,8 +351,8 @@ bool Grid::initInfiniteRay(const Vec3r &orig, const Vec3r &dir, unsigned timesta
Vec3r boxMax(_orig + _size);
BBox<Vec3r> box(boxMin, boxMax);
if (box.inside(orig)) {
- for (unsigned int i = 0; i < 3; i++) {
- _current_cell[i] = (unsigned int)floor((orig[i] - _orig[i]) / _cell_size[i]);
+ for (uint i = 0; i < 3; i++) {
+ _current_cell[i] = uint(floor((orig[i] - _orig[i]) / _cell_size[i]));
// soc unused - unsigned u = _current_cell[i];
_pt[i] = orig[i] - _orig[i] - _current_cell[i] * _cell_size[i];
}
@@ -366,8 +363,8 @@ bool Grid::initInfiniteRay(const Vec3r &orig, const Vec3r &dir, unsigned timesta
if (GeomUtils::intersectRayBBox(orig, _ray_dir, boxMin, boxMax, 0, _t_end, tmin, tmax)) {
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]);
+ for (uint i = 0; i < 3; i++) {
+ _current_cell[i] = uint(floor((newOrig[i] - _orig[i]) / _cell_size[i]));
if (_current_cell[i] == _cells_nb[i]) {
_current_cell[i] = _cells_nb[i] - 1;
}
diff --git a/source/blender/freestyle/intern/geometry/HashGrid.cpp b/source/blender/freestyle/intern/geometry/HashGrid.cpp
index c86aa4fd22c..46ce9184951 100644
--- a/source/blender/freestyle/intern/geometry/HashGrid.cpp
+++ b/source/blender/freestyle/intern/geometry/HashGrid.cpp
@@ -7,6 +7,8 @@
#include "HashGrid.h"
+#include "BLI_sys_types.h"
+
namespace Freestyle {
void HashGrid::clear()
@@ -22,7 +24,7 @@ void HashGrid::clear()
Grid::clear();
}
-void HashGrid::configure(const Vec3r &orig, const Vec3r &size, unsigned nb)
+void HashGrid::configure(const Vec3r &orig, const Vec3r &size, uint nb)
{
Grid::configure(orig, size, nb);
}
diff --git a/source/blender/freestyle/intern/geometry/Noise.cpp b/source/blender/freestyle/intern/geometry/Noise.cpp
index d8a09bd8ab7..04e271f7a5b 100644
--- a/source/blender/freestyle/intern/geometry/Noise.cpp
+++ b/source/blender/freestyle/intern/geometry/Noise.cpp
@@ -12,6 +12,7 @@
#include "BLI_compiler_attrs.h"
#include "BLI_rand.h"
+#include "BLI_sys_types.h"
#include "Noise.h"
@@ -45,7 +46,7 @@ namespace Freestyle {
(t) = (i) + (N); \
(r0) = modff((t), &(u)); \
(r1) = (r0)-1.0; \
- (b0) = ((int)(u)) & BM; \
+ (b0) = int(u) & BM; \
(b1) = ((b0) + 1) & BM; \
} \
(void)0
@@ -69,7 +70,7 @@ static void normalize3(float v[3])
v[2] = v[2] / s;
}
-float Noise::turbulence1(float arg, float freq, float amp, unsigned oct)
+float Noise::turbulence1(float arg, float freq, float amp, uint oct)
{
float t;
float vec;
@@ -81,7 +82,7 @@ float Noise::turbulence1(float arg, float freq, float amp, unsigned oct)
return t;
}
-float Noise::turbulence2(Vec2f &v, float freq, float amp, unsigned oct)
+float Noise::turbulence2(Vec2f &v, float freq, float amp, uint oct)
{
float t;
Vec2f vec;
@@ -94,7 +95,7 @@ float Noise::turbulence2(Vec2f &v, float freq, float amp, unsigned oct)
return t;
}
-float Noise::turbulence3(Vec3f &v, float freq, float amp, unsigned oct)
+float Noise::turbulence3(Vec3f &v, float freq, float amp, uint oct)
{
float t;
Vec3f vec;
@@ -229,15 +230,15 @@ Noise::Noise(long seed)
for (i = 0; i < _NOISE_B; i++) {
p[i] = i;
- g1[i] = (float)((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
+ g1[i] = float((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
for (j = 0; j < 2; j++) {
- g2[i][j] = (float)((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
+ g2[i][j] = float((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
}
normalize2(g2[i]);
for (j = 0; j < 3; j++) {
- g3[i][j] = (float)((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
+ g3[i][j] = float((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
}
normalize3(g3[i]);
}
diff --git a/source/blender/freestyle/intern/image/GaussianFilter.cpp b/source/blender/freestyle/intern/image/GaussianFilter.cpp
index 7e523311d4c..421b739197b 100644
--- a/source/blender/freestyle/intern/image/GaussianFilter.cpp
+++ b/source/blender/freestyle/intern/image/GaussianFilter.cpp
@@ -46,7 +46,7 @@ GaussianFilter::~GaussianFilter()
int GaussianFilter::computeMaskSize(float sigma)
{
- int maskSize = (int)floor(4 * sigma) + 1;
+ int maskSize = int(floor(4 * sigma)) + 1;
if (0 == (maskSize % 2)) {
++maskSize;
}
diff --git a/source/blender/freestyle/intern/image/ImagePyramid.cpp b/source/blender/freestyle/intern/image/ImagePyramid.cpp
index 2a555a22915..bc68d17a1f9 100644
--- a/source/blender/freestyle/intern/image/ImagePyramid.cpp
+++ b/source/blender/freestyle/intern/image/ImagePyramid.cpp
@@ -11,6 +11,8 @@
#include "Image.h"
#include "ImagePyramid.h"
+#include "BLI_sys_types.h"
+
using namespace std;
namespace Freestyle {
@@ -54,9 +56,9 @@ float ImagePyramid::pixel(int x, int y, int level)
if (0 == level) {
return img->pixel(x, y);
}
- unsigned int i = 1 << level;
- unsigned int sx = x >> level;
- unsigned int sy = y >> level;
+ uint i = 1 << level;
+ uint sx = x >> level;
+ uint sy = y >> level;
if (sx >= img->width()) {
sx = img->width() - 1;
}
@@ -96,7 +98,7 @@ float ImagePyramid::pixel(int x, int y, int level)
else {
P2 = P1;
}
- return (1.0f / (float)(1 << (2 * level))) * (C * P1 + D * P2);
+ return (1.0f / float(1 << (2 * level))) * (C * P1 + D * P2);
}
int ImagePyramid::width(int level)
@@ -109,13 +111,13 @@ int ImagePyramid::height(int level)
return _levels[level]->height();
}
-GaussianPyramid::GaussianPyramid(const GrayImage &level0, unsigned nbLevels, float iSigma)
+GaussianPyramid::GaussianPyramid(const GrayImage &level0, uint nbLevels, float iSigma)
{
_sigma = iSigma;
BuildPyramid(level0, nbLevels);
}
-GaussianPyramid::GaussianPyramid(GrayImage *level0, unsigned nbLevels, float iSigma)
+GaussianPyramid::GaussianPyramid(GrayImage *level0, uint nbLevels, float iSigma)
{
_sigma = iSigma;
BuildPyramid(level0, nbLevels);
@@ -126,27 +128,27 @@ GaussianPyramid::GaussianPyramid(const GaussianPyramid &iBrother) : ImagePyramid
_sigma = iBrother._sigma;
}
-void GaussianPyramid::BuildPyramid(const GrayImage &level0, unsigned nbLevels)
+void GaussianPyramid::BuildPyramid(const GrayImage &level0, uint nbLevels)
{
GrayImage *pLevel = new GrayImage(level0);
BuildPyramid(pLevel, nbLevels);
}
-void GaussianPyramid::BuildPyramid(GrayImage *level0, unsigned nbLevels)
+void GaussianPyramid::BuildPyramid(GrayImage *level0, uint nbLevels)
{
GrayImage *pLevel = level0;
_levels.push_back(pLevel);
GaussianFilter gf(_sigma);
// build the nbLevels:
- unsigned w = pLevel->width();
- unsigned h = pLevel->height();
+ uint w = pLevel->width();
+ uint h = pLevel->height();
if (nbLevels != 0) {
- for (unsigned int i = 0; i < nbLevels; ++i) { // soc
+ for (uint i = 0; i < nbLevels; ++i) { // soc
w = pLevel->width() >> 1;
h = pLevel->height() >> 1;
GrayImage *img = new GrayImage(w, h);
- for (unsigned int y = 0; y < h; ++y) {
- for (unsigned int x = 0; x < w; ++x) {
+ for (uint y = 0; y < h; ++y) {
+ for (uint x = 0; x < w; ++x) {
float v = gf.getSmoothedPixel<GrayImage>(pLevel, 2 * x, 2 * y);
img->setPixel(x, y, v);
}
@@ -160,8 +162,8 @@ void GaussianPyramid::BuildPyramid(GrayImage *level0, unsigned nbLevels)
w = pLevel->width() >> 1;
h = pLevel->height() >> 1;
GrayImage *img = new GrayImage(w, h);
- for (unsigned int y = 0; y < h; ++y) {
- for (unsigned int x = 0; x < w; ++x) {
+ for (uint y = 0; y < h; ++y) {
+ for (uint x = 0; x < w; ++x) {
float v = gf.getSmoothedPixel<GrayImage>(pLevel, 2 * x, 2 * y);
img->setPixel(x, y, v);
}
diff --git a/source/blender/freestyle/intern/python/BPy_BBox.cpp b/source/blender/freestyle/intern/python/BPy_BBox.cpp
index 8fb5f60eff7..30ff0af7c1e 100644
--- a/source/blender/freestyle/intern/python/BPy_BBox.cpp
+++ b/source/blender/freestyle/intern/python/BPy_BBox.cpp
@@ -65,43 +65,44 @@ static PyObject *BBox_repr(BPy_BBox *self)
/*-----------------------BPy_BBox type definition ------------------------------*/
PyTypeObject BBox_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "BBox", /* tp_name */
- sizeof(BPy_BBox), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)BBox_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)BBox_repr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- BBox_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)BBox_init, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "BBox",
+ /*tp_basicsize*/ sizeof(BPy_BBox),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)BBox_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)BBox_repr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ BBox_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)BBox_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp b/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp
index 6669c021f27..3f9e96ffa73 100644
--- a/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp
@@ -120,7 +120,7 @@ PyDoc_STRVAR(BinaryPredicate0D_name_doc,
"\n"
":type: str");
-static PyObject *BinaryPredicate0D_name_get(BPy_BinaryPredicate0D *self, void *UNUSED(closure))
+static PyObject *BinaryPredicate0D_name_get(BPy_BinaryPredicate0D *self, void * /*closure*/)
{
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
}
@@ -137,43 +137,44 @@ static PyGetSetDef BPy_BinaryPredicate0D_getseters[] = {
/*-----------------------BPy_BinaryPredicate0D type definition ------------------------------*/
PyTypeObject BinaryPredicate0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "BinaryPredicate0D", /* tp_name */
- sizeof(BPy_BinaryPredicate0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)BinaryPredicate0D___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)BinaryPredicate0D___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)BinaryPredicate0D___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- BinaryPredicate0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_BinaryPredicate0D_getseters, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)BinaryPredicate0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "BinaryPredicate0D",
+ /*tp_basicsize*/ sizeof(BPy_BinaryPredicate0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)BinaryPredicate0D___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)BinaryPredicate0D___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)BinaryPredicate0D___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ BinaryPredicate0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_BinaryPredicate0D_getseters,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)BinaryPredicate0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp b/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp
index 496900a712b..bf4bf2d099a 100644
--- a/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp
@@ -155,7 +155,7 @@ PyDoc_STRVAR(BinaryPredicate1D_name_doc,
"\n"
":type: str");
-static PyObject *BinaryPredicate1D_name_get(BPy_BinaryPredicate1D *self, void *UNUSED(closure))
+static PyObject *BinaryPredicate1D_name_get(BPy_BinaryPredicate1D *self, void * /*closure*/)
{
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
}
@@ -170,44 +170,45 @@ static PyGetSetDef BPy_BinaryPredicate1D_getseters[] = {
};
/*-----------------------BPy_BinaryPredicate1D type definition ------------------------------*/
+
PyTypeObject BinaryPredicate1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "BinaryPredicate1D", /* tp_name */
- sizeof(BPy_BinaryPredicate1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)BinaryPredicate1D___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)BinaryPredicate1D___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)BinaryPredicate1D___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- BinaryPredicate1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_BinaryPredicate1D_getseters, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)BinaryPredicate1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ /*tp_name*/ PyVarObject_HEAD_INIT(nullptr, 0) "BinaryPredicate1D",
+ /*tp_basicsize*/ sizeof(BPy_BinaryPredicate1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)BinaryPredicate1D___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)BinaryPredicate1D___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)BinaryPredicate1D___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ BinaryPredicate1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_BinaryPredicate1D_getseters,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)BinaryPredicate1D___init__,
+ /*tp_alloc*/ nullptr,
+ PyType_GenericNew, /*tp_new*/
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_ContextFunctions.cpp b/source/blender/freestyle/intern/python/BPy_ContextFunctions.cpp
index 16b08722fb2..a4b83b840f3 100644
--- a/source/blender/freestyle/intern/python/BPy_ContextFunctions.cpp
+++ b/source/blender/freestyle/intern/python/BPy_ContextFunctions.cpp
@@ -9,6 +9,8 @@
#include "../stroke/ContextFunctions.h"
+#include "BLI_sys_types.h"
+
using namespace Freestyle;
#ifdef __cplusplus
@@ -98,7 +100,7 @@ static PyObject *ContextFunctions_load_map(PyObject * /*self*/, PyObject *args,
{
static const char *kwlist[] = {"file_name", "map_name", "num_levels", "sigma", nullptr};
char *fileName, *mapName;
- unsigned nbLevels = 4;
+ uint nbLevels = 4;
float sigma = 1.0;
if (!PyArg_ParseTupleAndKeywords(
@@ -135,7 +137,7 @@ static PyObject *ContextFunctions_read_map_pixel(PyObject * /*self*/,
static const char *kwlist[] = {"map_name", "level", "x", "y", nullptr};
char *mapName;
int level;
- unsigned x, y;
+ uint x, y;
if (!PyArg_ParseTupleAndKeywords(
args, kwds, "siII", (char **)kwlist, &mapName, &level, &x, &y)) {
@@ -167,7 +169,7 @@ static PyObject *ContextFunctions_read_complete_view_map_pixel(PyObject * /*self
{
static const char *kwlist[] = {"level", "x", "y", nullptr};
int level;
- unsigned x, y;
+ uint x, y;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "iII", (char **)kwlist, &level, &x, &y)) {
return nullptr;
@@ -201,7 +203,7 @@ static PyObject *ContextFunctions_read_directional_view_map_pixel(PyObject * /*s
{
static const char *kwlist[] = {"orientation", "level", "x", "y", nullptr};
int orientation, level;
- unsigned x, y;
+ uint x, y;
if (!PyArg_ParseTupleAndKeywords(
args, kwds, "iiII", (char **)kwlist, &orientation, &level, &x, &y)) {
@@ -278,10 +280,14 @@ static PyMethodDef module_functions[] = {
static PyModuleDef module_definition = {
PyModuleDef_HEAD_INIT,
- "Freestyle.ContextFunctions",
- module_docstring,
- -1,
- module_functions,
+ /*m_name*/ "Freestyle.ContextFunctions",
+ /*m_doc*/ module_docstring,
+ /*m_size*/ -1,
+ /*m_methods*/ module_functions,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
//------------------- MODULE INITIALIZATION --------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_Convert.cpp b/source/blender/freestyle/intern/python/BPy_Convert.cpp
index 02ed3f463c7..0701b1c4ef3 100644
--- a/source/blender/freestyle/intern/python/BPy_Convert.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Convert.cpp
@@ -236,7 +236,7 @@ PyObject *BPy_FEdge_from_FEdge(FEdge &fe)
return py_fe;
}
-PyObject *BPy_Nature_from_Nature(unsigned short n)
+PyObject *BPy_Nature_from_Nature(ushort n)
{
PyObject *args = PyTuple_New(1);
PyTuple_SET_ITEM(args, 0, PyLong_FromLong(n));
diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
index 96bab8c2028..f99e66c822d 100644
--- a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
@@ -200,7 +200,7 @@ static PyObject *Freestyle_evaluateColorRamp(PyObject * /*self*/, PyObject *args
ColorBand *coba;
float in, out[4];
- if (!(PyArg_ParseTuple(args, "O!f", &pyrna_struct_Type, &py_srna, &in))) {
+ if (!PyArg_ParseTuple(args, "O!f", &pyrna_struct_Type, &py_srna, &in)) {
return nullptr;
}
if (!RNA_struct_is_a(py_srna->ptr.type, &RNA_ColorRamp)) {
@@ -239,7 +239,7 @@ static PyObject *Freestyle_evaluateCurveMappingF(PyObject * /*self*/, PyObject *
int cur;
float value;
- if (!(PyArg_ParseTuple(args, "O!if", &pyrna_struct_Type, &py_srna, &cur, &value))) {
+ if (!PyArg_ParseTuple(args, "O!if", &pyrna_struct_Type, &py_srna, &cur, &value)) {
return nullptr;
}
if (!RNA_struct_is_a(py_srna->ptr.type, &RNA_CurveMapping)) {
@@ -509,10 +509,14 @@ static PyMethodDef module_functions[] = {
static PyModuleDef module_definition = {
PyModuleDef_HEAD_INIT,
- "_freestyle",
- module_docstring,
- -1,
- module_functions,
+ /*m_name*/ "_freestyle",
+ /*m_doc*/ module_docstring,
+ /*m_size*/ -1,
+ /*m_methods*/ module_functions,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
//-------------------MODULE INITIALIZATION--------------------------------
@@ -531,7 +535,7 @@ PyObject *Freestyle_Init(void)
const char *const path = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, "freestyle");
if (path) {
char modpath[FILE_MAX];
- BLI_join_dirfile(modpath, sizeof(modpath), path, "modules");
+ BLI_path_join(modpath, sizeof(modpath), path, "modules");
PyObject *sys_path = PySys_GetObject("path"); /* borrow */
PyObject *py_modpath = PyUnicode_FromString(modpath);
PyList_Append(sys_path, py_modpath);
diff --git a/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp b/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp
index bd37e84761e..7bc3f2ea05a 100644
--- a/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp
+++ b/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp
@@ -282,7 +282,7 @@ static Mathutils_Callback FrsMaterial_mathutils_cb = {
FrsMaterial_mathutils_set_index,
};
-static unsigned char FrsMaterial_mathutils_cb_index = -1;
+static uchar FrsMaterial_mathutils_cb_index = -1;
void FrsMaterial_mathutils_register_callback()
{
@@ -296,13 +296,13 @@ PyDoc_STRVAR(FrsMaterial_line_doc,
"\n"
":type: :class:`mathutils.Vector`");
-static PyObject *FrsMaterial_line_get(BPy_FrsMaterial *self, void *UNUSED(closure))
+static PyObject *FrsMaterial_line_get(BPy_FrsMaterial *self, void * /*closure*/)
{
return Vector_CreatePyObject_cb(
(PyObject *)self, 4, FrsMaterial_mathutils_cb_index, MATHUTILS_SUBTYPE_LINE);
}
-static int FrsMaterial_line_set(BPy_FrsMaterial *self, PyObject *value, void *UNUSED(closure))
+static int FrsMaterial_line_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
{
float color[4];
if (mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") == -1) {
@@ -317,13 +317,13 @@ PyDoc_STRVAR(FrsMaterial_diffuse_doc,
"\n"
":type: :class:`mathutils.Vector`");
-static PyObject *FrsMaterial_diffuse_get(BPy_FrsMaterial *self, void *UNUSED(closure))
+static PyObject *FrsMaterial_diffuse_get(BPy_FrsMaterial *self, void * /*closure*/)
{
return Vector_CreatePyObject_cb(
(PyObject *)self, 4, FrsMaterial_mathutils_cb_index, MATHUTILS_SUBTYPE_DIFFUSE);
}
-static int FrsMaterial_diffuse_set(BPy_FrsMaterial *self, PyObject *value, void *UNUSED(closure))
+static int FrsMaterial_diffuse_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
{
float color[4];
if (mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") == -1) {
@@ -338,13 +338,13 @@ PyDoc_STRVAR(FrsMaterial_specular_doc,
"\n"
":type: :class:`mathutils.Vector`");
-static PyObject *FrsMaterial_specular_get(BPy_FrsMaterial *self, void *UNUSED(closure))
+static PyObject *FrsMaterial_specular_get(BPy_FrsMaterial *self, void * /*closure*/)
{
return Vector_CreatePyObject_cb(
(PyObject *)self, 4, FrsMaterial_mathutils_cb_index, MATHUTILS_SUBTYPE_SPECULAR);
}
-static int FrsMaterial_specular_set(BPy_FrsMaterial *self, PyObject *value, void *UNUSED(closure))
+static int FrsMaterial_specular_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
{
float color[4];
if (mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") == -1) {
@@ -359,13 +359,13 @@ PyDoc_STRVAR(FrsMaterial_ambient_doc,
"\n"
":type: :class:`mathutils.Color`");
-static PyObject *FrsMaterial_ambient_get(BPy_FrsMaterial *self, void *UNUSED(closure))
+static PyObject *FrsMaterial_ambient_get(BPy_FrsMaterial *self, void * /*closure*/)
{
return Vector_CreatePyObject_cb(
(PyObject *)self, 4, FrsMaterial_mathutils_cb_index, MATHUTILS_SUBTYPE_AMBIENT);
}
-static int FrsMaterial_ambient_set(BPy_FrsMaterial *self, PyObject *value, void *UNUSED(closure))
+static int FrsMaterial_ambient_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
{
float color[4];
if (mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") == -1) {
@@ -380,13 +380,13 @@ PyDoc_STRVAR(FrsMaterial_emission_doc,
"\n"
":type: :class:`mathutils.Color`");
-static PyObject *FrsMaterial_emission_get(BPy_FrsMaterial *self, void *UNUSED(closure))
+static PyObject *FrsMaterial_emission_get(BPy_FrsMaterial *self, void * /*closure*/)
{
return Vector_CreatePyObject_cb(
(PyObject *)self, 4, FrsMaterial_mathutils_cb_index, MATHUTILS_SUBTYPE_EMISSION);
}
-static int FrsMaterial_emission_set(BPy_FrsMaterial *self, PyObject *value, void *UNUSED(closure))
+static int FrsMaterial_emission_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
{
float color[4];
if (mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") == -1) {
@@ -401,12 +401,12 @@ PyDoc_STRVAR(FrsMaterial_shininess_doc,
"\n"
":type: float");
-static PyObject *FrsMaterial_shininess_get(BPy_FrsMaterial *self, void *UNUSED(closure))
+static PyObject *FrsMaterial_shininess_get(BPy_FrsMaterial *self, void * /*closure*/)
{
return PyFloat_FromDouble(self->m->shininess());
}
-static int FrsMaterial_shininess_set(BPy_FrsMaterial *self, PyObject *value, void *UNUSED(closure))
+static int FrsMaterial_shininess_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
{
float scalar;
if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
@@ -423,12 +423,12 @@ PyDoc_STRVAR(FrsMaterial_priority_doc,
"\n"
":type: int");
-static PyObject *FrsMaterial_priority_get(BPy_FrsMaterial *self, void *UNUSED(closure))
+static PyObject *FrsMaterial_priority_get(BPy_FrsMaterial *self, void * /*closure*/)
{
return PyLong_FromLong(self->m->priority());
}
-static int FrsMaterial_priority_set(BPy_FrsMaterial *self, PyObject *value, void *UNUSED(closure))
+static int FrsMaterial_priority_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
{
int scalar;
if ((scalar = PyLong_AsLong(value)) == -1 && PyErr_Occurred()) {
@@ -517,48 +517,49 @@ static PyObject *BPy_FrsMaterial_richcmpr(PyObject *objectA,
static Py_hash_t FrsMaterial_hash(PyObject *self)
{
- return (Py_uhash_t)BLI_hash_mm2((const unsigned char *)self, sizeof(*self), 0);
+ return (Py_uhash_t)BLI_hash_mm2((const uchar *)self, sizeof(*self), 0);
}
/*-----------------------BPy_FrsMaterial type definition ------------------------------*/
PyTypeObject FrsMaterial_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Material", /* tp_name */
- sizeof(BPy_FrsMaterial), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)FrsMaterial_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)FrsMaterial_repr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- (hashfunc)FrsMaterial_hash, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- FrsMaterial_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- (richcmpfunc)BPy_FrsMaterial_richcmpr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_FrsMaterial_getseters, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)FrsMaterial_init, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Material",
+ /*tp_basicsize*/ sizeof(BPy_FrsMaterial),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)FrsMaterial_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)FrsMaterial_repr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ (hashfunc)FrsMaterial_hash,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ FrsMaterial_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ (richcmpfunc)BPy_FrsMaterial_richcmpr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_FrsMaterial_getseters,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)FrsMaterial_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_FrsNoise.cpp b/source/blender/freestyle/intern/python/BPy_FrsNoise.cpp
index 5bdc8ce16e8..3a07fdb3d88 100644
--- a/source/blender/freestyle/intern/python/BPy_FrsNoise.cpp
+++ b/source/blender/freestyle/intern/python/BPy_FrsNoise.cpp
@@ -9,6 +9,8 @@
#include "../system/RandGen.h"
+#include "BLI_sys_types.h"
+
#include <sstream>
#ifdef __cplusplus
@@ -109,7 +111,7 @@ static PyObject *FrsNoise_turbulence_smooth(BPy_FrsNoise *self, PyObject *args,
static const char *kwlist[] = {"v", "oct", nullptr};
double x; // NOTE: this has to be a double (not float)
- unsigned nbOctaves = 8;
+ uint nbOctaves = 8;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "d|I", (char **)kwlist, &x, &nbOctaves)) {
return nullptr;
@@ -121,7 +123,7 @@ static PyObject *FrsNoise_turbulence1(BPy_FrsNoise *self, PyObject *args, PyObje
{
static const char *kwlist[] = {"v", "freq", "amp", "oct", nullptr};
float f1, f2, f3;
- unsigned int i = 4;
+ uint i = 4;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "fff|I", (char **)kwlist, &f1, &f2, &f3, &i)) {
return nullptr;
@@ -150,7 +152,7 @@ static PyObject *FrsNoise_turbulence2(BPy_FrsNoise *self, PyObject *args, PyObje
static const char *kwlist[] = {"v", "freq", "amp", "oct", nullptr};
PyObject *obj1;
float f2, f3;
- unsigned int i = 4;
+ uint i = 4;
Vec2f vec;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "Off|I", (char **)kwlist, &obj1, &f2, &f3, &i)) {
@@ -186,7 +188,7 @@ static PyObject *FrsNoise_turbulence3(BPy_FrsNoise *self, PyObject *args, PyObje
static const char *kwlist[] = {"v", "freq", "amp", "oct", nullptr};
PyObject *obj1;
float f2, f3;
- unsigned int i = 4;
+ uint i = 4;
Vec3f vec;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "Off|I", (char **)kwlist, &obj1, &f2, &f3, &i)) {
@@ -314,43 +316,44 @@ static PyMethodDef BPy_FrsNoise_methods[] = {
/*-----------------------BPy_FrsNoise type definition ------------------------------*/
PyTypeObject FrsNoise_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Noise", /* tp_name */
- sizeof(BPy_FrsNoise), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)FrsNoise_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)FrsNoise_repr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- FrsNoise_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_FrsNoise_methods, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)FrsNoise_init, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Noise",
+ /*tp_basicsize*/ sizeof(BPy_FrsNoise),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)FrsNoise_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)FrsNoise_repr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ FrsNoise_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_FrsNoise_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)FrsNoise_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_Id.cpp b/source/blender/freestyle/intern/python/BPy_Id.cpp
index fd665f56189..7745bc11512 100644
--- a/source/blender/freestyle/intern/python/BPy_Id.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Id.cpp
@@ -97,7 +97,7 @@ static PyObject *Id_RichCompare(BPy_Id *o1, BPy_Id *o2, int opid)
case Py_GT:
return PyBool_from_bool(!(o1->id->operator<(*(o2->id)) || o1->id->operator==(*(o2->id))));
case Py_GE:
- return PyBool_from_bool(!(o1->id->operator<(*(o2->id))));
+ return PyBool_from_bool(!o1->id->operator<(*(o2->id)));
}
Py_RETURN_NONE;
}
@@ -109,12 +109,12 @@ PyDoc_STRVAR(Id_first_doc,
"\n"
":type: int");
-static PyObject *Id_first_get(BPy_Id *self, void *UNUSED(closure))
+static PyObject *Id_first_get(BPy_Id *self, void * /*closure*/)
{
return PyLong_FromLong(self->id->getFirst());
}
-static int Id_first_set(BPy_Id *self, PyObject *value, void *UNUSED(closure))
+static int Id_first_set(BPy_Id *self, PyObject *value, void * /*closure*/)
{
int scalar;
if ((scalar = PyLong_AsLong(value)) == -1 && PyErr_Occurred()) {
@@ -130,12 +130,12 @@ PyDoc_STRVAR(Id_second_doc,
"\n"
":type: int");
-static PyObject *Id_second_get(BPy_Id *self, void *UNUSED(closure))
+static PyObject *Id_second_get(BPy_Id *self, void * /*closure*/)
{
return PyLong_FromLong(self->id->getSecond());
}
-static int Id_second_set(BPy_Id *self, PyObject *value, void *UNUSED(closure))
+static int Id_second_set(BPy_Id *self, PyObject *value, void * /*closure*/)
{
int scalar;
if ((scalar = PyLong_AsLong(value)) == -1 && PyErr_Occurred()) {
@@ -155,43 +155,44 @@ static PyGetSetDef BPy_Id_getseters[] = {
/*-----------------------BPy_Id type definition ------------------------------*/
PyTypeObject Id_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Id", /* tp_name */
- sizeof(BPy_Id), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)Id_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)Id_repr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- Id_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- (richcmpfunc)Id_RichCompare, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_Id_getseters, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Id_init, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Id",
+ /*tp_basicsize*/ sizeof(BPy_Id),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)Id_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)Id_repr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ Id_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ (richcmpfunc)Id_RichCompare,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_Id_getseters,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)Id_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp b/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp
index fc7581a93c0..c862b226271 100644
--- a/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp
+++ b/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp
@@ -12,6 +12,8 @@
#include "UnaryFunction0D/BPy_UnaryFunction0DFloat.h"
#include "UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h"
+#include "BLI_sys_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -82,8 +84,8 @@ static PyObject *Integrator_integrate(PyObject * /*self*/, PyObject *args, PyObj
return PyFloat_FromDouble(res);
}
if (BPy_UnaryFunction0DUnsigned_Check(obj1)) {
- UnaryFunction0D<unsigned int> *fun = ((BPy_UnaryFunction0DUnsigned *)obj1)->uf0D_unsigned;
- unsigned int res = integrate(*fun, it, it_end, t);
+ UnaryFunction0D<uint> *fun = ((BPy_UnaryFunction0DUnsigned *)obj1)->uf0D_unsigned;
+ uint res = integrate(*fun, it, it_end, t);
return PyLong_FromLong(res);
}
@@ -110,10 +112,14 @@ static PyMethodDef module_functions[] = {
static PyModuleDef module_definition = {
PyModuleDef_HEAD_INIT,
- "Freestyle.Integrator",
- module_docstring,
- -1,
- module_functions,
+ /*m_name*/ "Freestyle.Integrator",
+ /*m_doc*/ module_docstring,
+ /*m_size*/ -1,
+ /*m_methods*/ module_functions,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
/*-----------------------BPy_IntegrationType type definition ------------------------------*/
@@ -137,43 +143,44 @@ PyDoc_STRVAR(IntegrationType_doc,
" last of the values obtained for the 0D elements.");
PyTypeObject IntegrationType_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "IntegrationType", /* tp_name */
- sizeof(PyLongObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- IntegrationType_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &PyLong_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- nullptr, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "IntegrationType",
+ /*tp_basicsize*/ sizeof(PyLongObject),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT,
+ /*tp_doc*/ IntegrationType_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &PyLong_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ nullptr,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
/*-----------------------BPy_IntegrationType instance definitions -------------------------*/
diff --git a/source/blender/freestyle/intern/python/BPy_Interface0D.cpp b/source/blender/freestyle/intern/python/BPy_Interface0D.cpp
index c87e58e954b..11ac078124a 100644
--- a/source/blender/freestyle/intern/python/BPy_Interface0D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Interface0D.cpp
@@ -159,7 +159,7 @@ PyDoc_STRVAR(Interface0D_name_doc,
"\n"
":type: str");
-static PyObject *Interface0D_name_get(BPy_Interface0D *self, void *UNUSED(closure))
+static PyObject *Interface0D_name_get(BPy_Interface0D *self, void * /*closure*/)
{
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
}
@@ -169,7 +169,7 @@ PyDoc_STRVAR(Interface0D_point_3d_doc,
"\n"
":type: :class:`mathutils.Vector`");
-static PyObject *Interface0D_point_3d_get(BPy_Interface0D *self, void *UNUSED(closure))
+static PyObject *Interface0D_point_3d_get(BPy_Interface0D *self, void * /*closure*/)
{
Vec3f p(self->if0D->getPoint3D());
if (PyErr_Occurred()) {
@@ -183,7 +183,7 @@ PyDoc_STRVAR(Interface0D_projected_x_doc,
"\n"
":type: float");
-static PyObject *Interface0D_projected_x_get(BPy_Interface0D *self, void *UNUSED(closure))
+static PyObject *Interface0D_projected_x_get(BPy_Interface0D *self, void * /*closure*/)
{
real x = self->if0D->getProjectedX();
if (PyErr_Occurred()) {
@@ -197,7 +197,7 @@ PyDoc_STRVAR(Interface0D_projected_y_doc,
"\n"
":type: float");
-static PyObject *Interface0D_projected_y_get(BPy_Interface0D *self, void *UNUSED(closure))
+static PyObject *Interface0D_projected_y_get(BPy_Interface0D *self, void * /*closure*/)
{
real y = self->if0D->getProjectedY();
if (PyErr_Occurred()) {
@@ -211,7 +211,7 @@ PyDoc_STRVAR(Interface0D_projected_z_doc,
"\n"
":type: float");
-static PyObject *Interface0D_projected_z_get(BPy_Interface0D *self, void *UNUSED(closure))
+static PyObject *Interface0D_projected_z_get(BPy_Interface0D *self, void * /*closure*/)
{
real z = self->if0D->getProjectedZ();
if (PyErr_Occurred()) {
@@ -225,7 +225,7 @@ PyDoc_STRVAR(Interface0D_point_2d_doc,
"\n"
":type: :class:`mathutils.Vector`");
-static PyObject *Interface0D_point_2d_get(BPy_Interface0D *self, void *UNUSED(closure))
+static PyObject *Interface0D_point_2d_get(BPy_Interface0D *self, void * /*closure*/)
{
Vec2f p(self->if0D->getPoint2D());
if (PyErr_Occurred()) {
@@ -239,7 +239,7 @@ PyDoc_STRVAR(Interface0D_id_doc,
"\n"
":type: :class:`Id`");
-static PyObject *Interface0D_id_get(BPy_Interface0D *self, void *UNUSED(closure))
+static PyObject *Interface0D_id_get(BPy_Interface0D *self, void * /*closure*/)
{
Id id(self->if0D->getId());
if (PyErr_Occurred()) {
@@ -253,7 +253,7 @@ PyDoc_STRVAR(Interface0D_nature_doc,
"\n"
":type: :class:`Nature`");
-static PyObject *Interface0D_nature_get(BPy_Interface0D *self, void *UNUSED(closure))
+static PyObject *Interface0D_nature_get(BPy_Interface0D *self, void * /*closure*/)
{
Nature::VertexNature nature = self->if0D->getNature();
if (PyErr_Occurred()) {
@@ -297,43 +297,44 @@ static PyGetSetDef BPy_Interface0D_getseters[] = {
/*-----------------------BPy_Interface0D type definition ------------------------------*/
PyTypeObject Interface0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Interface0D", /* tp_name */
- sizeof(BPy_Interface0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)Interface0D_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)Interface0D_repr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- Interface0D_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_Interface0D_methods, /* tp_methods */
- nullptr, /* tp_members */
- BPy_Interface0D_getseters, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Interface0D_init, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Interface0D",
+ /*tp_basicsize*/ sizeof(BPy_Interface0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)Interface0D_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)Interface0D_repr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ Interface0D_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_Interface0D_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_Interface0D_getseters,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)Interface0D_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_Interface1D.cpp b/source/blender/freestyle/intern/python/BPy_Interface1D.cpp
index fbe81d26e79..992d69ad594 100644
--- a/source/blender/freestyle/intern/python/BPy_Interface1D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Interface1D.cpp
@@ -234,7 +234,7 @@ PyDoc_STRVAR(Interface1D_name_doc,
"\n"
":type: str");
-static PyObject *Interface1D_name_get(BPy_Interface1D *self, void *UNUSED(closure))
+static PyObject *Interface1D_name_get(BPy_Interface1D *self, void * /*closure*/)
{
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
}
@@ -244,7 +244,7 @@ PyDoc_STRVAR(Interface1D_id_doc,
"\n"
":type: :class:`Id`");
-static PyObject *Interface1D_id_get(BPy_Interface1D *self, void *UNUSED(closure))
+static PyObject *Interface1D_id_get(BPy_Interface1D *self, void * /*closure*/)
{
Id id(self->if1D->getId());
if (PyErr_Occurred()) {
@@ -258,7 +258,7 @@ PyDoc_STRVAR(Interface1D_nature_doc,
"\n"
":type: :class:`Nature`");
-static PyObject *Interface1D_nature_get(BPy_Interface1D *self, void *UNUSED(closure))
+static PyObject *Interface1D_nature_get(BPy_Interface1D *self, void * /*closure*/)
{
Nature::VertexNature nature = self->if1D->getNature();
if (PyErr_Occurred()) {
@@ -272,13 +272,13 @@ PyDoc_STRVAR(Interface1D_length_2d_doc,
"\n"
":type: float");
-static PyObject *Interface1D_length_2d_get(BPy_Interface1D *self, void *UNUSED(closure))
+static PyObject *Interface1D_length_2d_get(BPy_Interface1D *self, void * /*closure*/)
{
real length = self->if1D->getLength2D();
if (PyErr_Occurred()) {
return nullptr;
}
- return PyFloat_FromDouble((double)length);
+ return PyFloat_FromDouble(double(length));
}
PyDoc_STRVAR(Interface1D_time_stamp_doc,
@@ -286,14 +286,12 @@ PyDoc_STRVAR(Interface1D_time_stamp_doc,
"\n"
":type: int");
-static PyObject *Interface1D_time_stamp_get(BPy_Interface1D *self, void *UNUSED(closure))
+static PyObject *Interface1D_time_stamp_get(BPy_Interface1D *self, void * /*closure*/)
{
return PyLong_FromLong(self->if1D->getTimeStamp());
}
-static int Interface1D_time_stamp_set(BPy_Interface1D *self,
- PyObject *value,
- void *UNUSED(closure))
+static int Interface1D_time_stamp_set(BPy_Interface1D *self, PyObject *value, void * /*closure*/)
{
int timestamp;
@@ -325,43 +323,44 @@ static PyGetSetDef BPy_Interface1D_getseters[] = {
/*-----------------------BPy_Interface1D type definition ------------------------------*/
PyTypeObject Interface1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Interface1D", /* tp_name */
- sizeof(BPy_Interface1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)Interface1D_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)Interface1D_repr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- Interface1D_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_Interface1D_methods, /* tp_methods */
- nullptr, /* tp_members */
- BPy_Interface1D_getseters, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Interface1D_init, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Interface1D",
+ /*tp_basicsize*/ sizeof(BPy_Interface1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)Interface1D_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)Interface1D_repr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ Interface1D_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_Interface1D_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_Interface1D_getseters,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)Interface1D_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_Iterator.cpp b/source/blender/freestyle/intern/python/BPy_Iterator.cpp
index 35e6dd5536e..f35c201d3eb 100644
--- a/source/blender/freestyle/intern/python/BPy_Iterator.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Iterator.cpp
@@ -177,7 +177,7 @@ PyDoc_STRVAR(Iterator_name_doc,
"\n"
":type: str");
-static PyObject *Iterator_name_get(BPy_Iterator *self, void *UNUSED(closure))
+static PyObject *Iterator_name_get(BPy_Iterator *self, void * /*closure*/)
{
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
}
@@ -187,7 +187,7 @@ PyDoc_STRVAR(Iterator_is_begin_doc,
"\n"
":type: bool");
-static PyObject *Iterator_is_begin_get(BPy_Iterator *self, void *UNUSED(closure))
+static PyObject *Iterator_is_begin_get(BPy_Iterator *self, void * /*closure*/)
{
return PyBool_from_bool(self->it->isBegin());
}
@@ -197,7 +197,7 @@ PyDoc_STRVAR(Iterator_is_end_doc,
"\n"
":type: bool");
-static PyObject *Iterator_is_end_get(BPy_Iterator *self, void *UNUSED(closure))
+static PyObject *Iterator_is_end_get(BPy_Iterator *self, void * /*closure*/)
{
return PyBool_from_bool(self->it->isEnd());
}
@@ -212,43 +212,44 @@ static PyGetSetDef BPy_Iterator_getseters[] = {
/*-----------------------BPy_Iterator type definition ------------------------------*/
PyTypeObject Iterator_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Iterator", /* tp_name */
- sizeof(BPy_Iterator), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)Iterator_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)Iterator_repr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- Iterator_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_Iterator_methods, /* tp_methods */
- nullptr, /* tp_members */
- BPy_Iterator_getseters, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Iterator_init, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Iterator",
+ /*tp_basicsize*/ sizeof(BPy_Iterator),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)Iterator_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)Iterator_repr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ Iterator_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_Iterator_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_Iterator_getseters,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)Iterator_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_MediumType.cpp b/source/blender/freestyle/intern/python/BPy_MediumType.cpp
index cf8e900e003..72bb8203077 100644
--- a/source/blender/freestyle/intern/python/BPy_MediumType.cpp
+++ b/source/blender/freestyle/intern/python/BPy_MediumType.cpp
@@ -29,43 +29,44 @@ PyDoc_STRVAR(MediumType_doc,
"* Stroke.OPAQUE_MEDIUM: To simulate an opaque medium (oil, spray...).");
PyTypeObject MediumType_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "MediumType", /* tp_name */
- sizeof(PyLongObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- MediumType_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &PyLong_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- nullptr, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "MediumType",
+ /*tp_basicsize*/ sizeof(PyLongObject),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT,
+ /*tp_doc*/ MediumType_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &PyLong_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ nullptr,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
/*-----------------------BPy_IntegrationType instance definitions -------------------------*/
diff --git a/source/blender/freestyle/intern/python/BPy_Nature.cpp b/source/blender/freestyle/intern/python/BPy_Nature.cpp
index 33c4ce17820..c06e6859514 100644
--- a/source/blender/freestyle/intern/python/BPy_Nature.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Nature.cpp
@@ -23,40 +23,42 @@ static PyObject *BPy_Nature_or(PyObject *a, PyObject *b);
/*-----------------------BPy_Nature number method definitions --------------------*/
static PyNumberMethods nature_as_number = {
- nullptr, /* binaryfunc nb_add */
- nullptr, /* binaryfunc nb_subtract */
- nullptr, /* binaryfunc nb_multiply */
- nullptr, /* binaryfunc nb_remainder */
- nullptr, /* binaryfunc nb_divmod */
- nullptr, /* ternaryfunc nb_power */
- nullptr, /* unaryfunc nb_negative */
- nullptr, /* unaryfunc nb_positive */
- nullptr, /* unaryfunc nb_absolute */
- nullptr, /* inquiry nb_bool */
- nullptr, /* unaryfunc nb_invert */
- nullptr, /* binaryfunc nb_lshift */
- nullptr, /* binaryfunc nb_rshift */
- (binaryfunc)BPy_Nature_and, /* binaryfunc nb_and */
- (binaryfunc)BPy_Nature_xor, /* binaryfunc nb_xor */
- (binaryfunc)BPy_Nature_or, /* binaryfunc nb_or */
- nullptr, /* unaryfunc nb_int */
- nullptr, /* void *nb_reserved */
- nullptr, /* unaryfunc nb_float */
- nullptr, /* binaryfunc nb_inplace_add */
- nullptr, /* binaryfunc nb_inplace_subtract */
- nullptr, /* binaryfunc nb_inplace_multiply */
- nullptr, /* binaryfunc nb_inplace_remainder */
- nullptr, /* ternaryfunc nb_inplace_power */
- nullptr, /* binaryfunc nb_inplace_lshift */
- nullptr, /* binaryfunc nb_inplace_rshift */
- nullptr, /* binaryfunc nb_inplace_and */
- nullptr, /* binaryfunc nb_inplace_xor */
- nullptr, /* binaryfunc nb_inplace_or */
- nullptr, /* binaryfunc nb_floor_divide */
- nullptr, /* binaryfunc nb_true_divide */
- nullptr, /* binaryfunc nb_inplace_floor_divide */
- nullptr, /* binaryfunc nb_inplace_true_divide */
- nullptr, /* unaryfunc nb_index */
+ /*nb_add*/ nullptr,
+ /*nb_subtract*/ nullptr,
+ /*nb_multiply*/ nullptr,
+ /*nb_remainder*/ nullptr,
+ /*nb_divmod*/ nullptr,
+ /*nb_power*/ nullptr,
+ /*nb_negative*/ nullptr,
+ /*nb_positive*/ nullptr,
+ /*nb_absolute*/ nullptr,
+ /*nb_bool*/ nullptr,
+ /*nb_invert*/ nullptr,
+ /*nb_lshift*/ nullptr,
+ /*nb_rshift*/ nullptr,
+ /*nb_and*/ (binaryfunc)BPy_Nature_and,
+ /*nb_xor*/ (binaryfunc)BPy_Nature_xor,
+ /*nb_or*/ (binaryfunc)BPy_Nature_or,
+ /*nb_int*/ nullptr,
+ /*nb_reserved*/ nullptr,
+ /*nb_float*/ nullptr,
+ /*nb_inplace_add*/ nullptr,
+ /*nb_inplace_subtract*/ nullptr,
+ /*nb_inplace_multiply*/ nullptr,
+ /*nb_inplace_remainder*/ nullptr,
+ /*nb_inplace_power*/ nullptr,
+ /*nb_inplace_lshift*/ nullptr,
+ /*nb_inplace_rshift*/ nullptr,
+ /*nb_inplace_and*/ nullptr,
+ /*nb_inplace_xor*/ nullptr,
+ /*nb_inplace_or*/ nullptr,
+ /*nb_floor_divide*/ nullptr,
+ /*nb_true_divide*/ nullptr,
+ /*nb_inplace_floor_divide*/ nullptr,
+ /*nb_inplace_true_divide*/ nullptr,
+ /*nb_index*/ nullptr,
+ /*nb_matrix_multiply*/ NULL,
+ /*nb_inplace_matrix_multiply*/ NULL,
};
/*-----------------------BPy_Nature docstring ------------------------------------*/
@@ -91,43 +93,44 @@ PyDoc_STRVAR(Nature_doc,
/*-----------------------BPy_Nature type definition ------------------------------*/
PyTypeObject Nature_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Nature", /* tp_name */
- sizeof(PyLongObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- &nature_as_number, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- Nature_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &PyLong_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- nullptr, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Nature",
+ /*tp_basicsize*/ sizeof(PyLongObject),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ &nature_as_number,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT,
+ /*tp_doc*/ Nature_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &PyLong_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ nullptr,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
/*-----------------------BPy_Nature instance definitions ----------------------------------*/
diff --git a/source/blender/freestyle/intern/python/BPy_Operators.cpp b/source/blender/freestyle/intern/python/BPy_Operators.cpp
index 20fd091c249..df2312c8680 100644
--- a/source/blender/freestyle/intern/python/BPy_Operators.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Operators.cpp
@@ -16,6 +16,8 @@
#include "UnaryFunction0D/BPy_UnaryFunction0DDouble.h"
#include "UnaryFunction1D/BPy_UnaryFunction1DVoid.h"
+#include "BLI_sys_types.h"
+
#include <sstream>
#ifdef __cplusplus
@@ -585,7 +587,7 @@ static PyObject *Operators_get_viewedge_from_index(BPy_Operators * /*self*/,
PyObject *kwds)
{
static const char *kwlist[] = {"i", nullptr};
- unsigned int i;
+ uint i;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "I", (char **)kwlist, &i)) {
return nullptr;
@@ -612,7 +614,7 @@ static PyObject *Operators_get_chain_from_index(BPy_Operators * /*self*/,
PyObject *kwds)
{
static const char *kwlist[] = {"i", nullptr};
- unsigned int i;
+ uint i;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "I", (char **)kwlist, &i)) {
return nullptr;
@@ -639,7 +641,7 @@ static PyObject *Operators_get_stroke_from_index(BPy_Operators * /*self*/,
PyObject *kwds)
{
static const char *kwlist[] = {"i", nullptr};
- unsigned int i;
+ uint i;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "I", (char **)kwlist, &i)) {
return nullptr;
@@ -754,43 +756,44 @@ static PyMethodDef BPy_Operators_methods[] = {
/*-----------------------BPy_Operators type definition ------------------------------*/
PyTypeObject Operators_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Operators", /* tp_name */
- sizeof(BPy_Operators), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)Operators_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- Operators_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_Operators_methods, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- nullptr, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Operators",
+ /*tp_basicsize*/ sizeof(BPy_Operators),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)Operators_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT,
+ /*tp_doc*/ Operators_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_Operators_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ nullptr,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_SShape.cpp b/source/blender/freestyle/intern/python/BPy_SShape.cpp
index fb72ed0ca62..c3f4daf5d21 100644
--- a/source/blender/freestyle/intern/python/BPy_SShape.cpp
+++ b/source/blender/freestyle/intern/python/BPy_SShape.cpp
@@ -12,6 +12,8 @@
#include "Interface0D/BPy_SVertex.h"
#include "Interface1D/BPy_FEdge.h"
+#include "BLI_sys_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -155,13 +157,13 @@ PyDoc_STRVAR(SShape_id_doc,
"\n"
":type: :class:`Id`");
-static PyObject *SShape_id_get(BPy_SShape *self, void *UNUSED(closure))
+static PyObject *SShape_id_get(BPy_SShape *self, void * /*closure*/)
{
Id id(self->ss->getId());
return BPy_Id_from_Id(id); // return a copy
}
-static int SShape_id_set(BPy_SShape *self, PyObject *value, void *UNUSED(closure))
+static int SShape_id_set(BPy_SShape *self, PyObject *value, void * /*closure*/)
{
if (!BPy_Id_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an Id");
@@ -176,12 +178,12 @@ PyDoc_STRVAR(SShape_name_doc,
"\n"
":type: str");
-static PyObject *SShape_name_get(BPy_SShape *self, void *UNUSED(closure))
+static PyObject *SShape_name_get(BPy_SShape *self, void * /*closure*/)
{
return PyUnicode_FromString(self->ss->getName().c_str());
}
-static int SShape_name_set(BPy_SShape *self, PyObject *value, void *UNUSED(closure))
+static int SShape_name_set(BPy_SShape *self, PyObject *value, void * /*closure*/)
{
if (!PyUnicode_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be a string");
@@ -197,13 +199,13 @@ PyDoc_STRVAR(SShape_bbox_doc,
"\n"
":type: :class:`BBox`");
-static PyObject *SShape_bbox_get(BPy_SShape *self, void *UNUSED(closure))
+static PyObject *SShape_bbox_get(BPy_SShape *self, void * /*closure*/)
{
BBox<Vec3r> bb(self->ss->bbox());
return BPy_BBox_from_BBox(bb); // return a copy
}
-static int SShape_bbox_set(BPy_SShape *self, PyObject *value, void *UNUSED(closure))
+static int SShape_bbox_set(BPy_SShape *self, PyObject *value, void * /*closure*/)
{
if (!BPy_BBox_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be a BBox");
@@ -218,13 +220,13 @@ PyDoc_STRVAR(SShape_vertices_doc,
"\n"
":type: List of :class:`SVertex` objects");
-static PyObject *SShape_vertices_get(BPy_SShape *self, void *UNUSED(closure))
+static PyObject *SShape_vertices_get(BPy_SShape *self, void * /*closure*/)
{
vector<SVertex *> vertices = self->ss->getVertexList();
vector<SVertex *>::iterator it;
PyObject *py_vertices = PyList_New(vertices.size());
- unsigned int i = 0;
+ uint i = 0;
for (it = vertices.begin(); it != vertices.end(); it++) {
PyList_SET_ITEM(py_vertices, i++, BPy_SVertex_from_SVertex(*(*it)));
@@ -238,13 +240,13 @@ PyDoc_STRVAR(SShape_edges_doc,
"\n"
":type: List of :class:`FEdge` objects");
-static PyObject *SShape_edges_get(BPy_SShape *self, void *UNUSED(closure))
+static PyObject *SShape_edges_get(BPy_SShape *self, void * /*closure*/)
{
vector<FEdge *> edges = self->ss->getEdgeList();
vector<FEdge *>::iterator it;
PyObject *py_edges = PyList_New(edges.size());
- unsigned int i = 0;
+ uint i = 0;
for (it = edges.begin(); it != edges.end(); it++) {
PyList_SET_ITEM(py_edges, i++, Any_BPy_FEdge_from_FEdge(*(*it)));
@@ -265,43 +267,44 @@ static PyGetSetDef BPy_SShape_getseters[] = {
/*-----------------------BPy_SShape type definition ------------------------------*/
PyTypeObject SShape_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "SShape", /* tp_name */
- sizeof(BPy_SShape), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)SShape_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)SShape_repr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- SShape_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_SShape_methods, /* tp_methods */
- nullptr, /* tp_members */
- BPy_SShape_getseters, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)SShape_init, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "SShape",
+ /*tp_basicsize*/ sizeof(BPy_SShape),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)SShape_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)SShape_repr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ SShape_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_SShape_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_SShape_getseters,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)SShape_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp
index 7dddf90f2b3..ed2af40545a 100644
--- a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp
+++ b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp
@@ -531,7 +531,7 @@ static Mathutils_Callback StrokeAttribute_mathutils_cb = {
StrokeAttribute_mathutils_set_index,
};
-static unsigned char StrokeAttribute_mathutils_cb_index = -1;
+static uchar StrokeAttribute_mathutils_cb_index = -1;
void StrokeAttribute_mathutils_register_callback()
{
@@ -545,14 +545,14 @@ PyDoc_STRVAR(StrokeAttribute_alpha_doc,
"\n"
":type: float");
-static PyObject *StrokeAttribute_alpha_get(BPy_StrokeAttribute *self, void *UNUSED(closure))
+static PyObject *StrokeAttribute_alpha_get(BPy_StrokeAttribute *self, void * /*closure*/)
{
return PyFloat_FromDouble(self->sa->getAlpha());
}
static int StrokeAttribute_alpha_set(BPy_StrokeAttribute *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
float scalar;
if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
@@ -569,7 +569,7 @@ PyDoc_STRVAR(StrokeAttribute_color_doc,
"\n"
":type: :class:`mathutils.Color`");
-static PyObject *StrokeAttribute_color_get(BPy_StrokeAttribute *self, void *UNUSED(closure))
+static PyObject *StrokeAttribute_color_get(BPy_StrokeAttribute *self, void * /*closure*/)
{
return Color_CreatePyObject_cb(
(PyObject *)self, StrokeAttribute_mathutils_cb_index, MATHUTILS_SUBTYPE_COLOR);
@@ -577,7 +577,7 @@ static PyObject *StrokeAttribute_color_get(BPy_StrokeAttribute *self, void *UNUS
static int StrokeAttribute_color_set(BPy_StrokeAttribute *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
float v[3];
if (mathutils_array_parse(v, 3, 3, value, "value must be a 3-dimensional vector") == -1) {
@@ -594,7 +594,7 @@ PyDoc_STRVAR(StrokeAttribute_thickness_doc,
"\n"
":type: :class:`mathutils.Vector`");
-static PyObject *StrokeAttribute_thickness_get(BPy_StrokeAttribute *self, void *UNUSED(closure))
+static PyObject *StrokeAttribute_thickness_get(BPy_StrokeAttribute *self, void * /*closure*/)
{
return Vector_CreatePyObject_cb(
(PyObject *)self, 2, StrokeAttribute_mathutils_cb_index, MATHUTILS_SUBTYPE_THICKNESS);
@@ -602,7 +602,7 @@ static PyObject *StrokeAttribute_thickness_get(BPy_StrokeAttribute *self, void *
static int StrokeAttribute_thickness_set(BPy_StrokeAttribute *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
float v[2];
if (mathutils_array_parse(v, 2, 2, value, "value must be a 2-dimensional vector") == -1) {
@@ -617,14 +617,14 @@ PyDoc_STRVAR(StrokeAttribute_visible_doc,
"\n"
":type: bool");
-static PyObject *StrokeAttribute_visible_get(BPy_StrokeAttribute *self, void *UNUSED(closure))
+static PyObject *StrokeAttribute_visible_get(BPy_StrokeAttribute *self, void * /*closure*/)
{
return PyBool_from_bool(self->sa->isVisible());
}
static int StrokeAttribute_visible_set(BPy_StrokeAttribute *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
if (!PyBool_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be boolean");
@@ -661,43 +661,44 @@ static PyGetSetDef BPy_StrokeAttribute_getseters[] = {
/*-----------------------BPy_StrokeAttribute type definition ------------------------------*/
PyTypeObject StrokeAttribute_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "StrokeAttribute", /* tp_name */
- sizeof(BPy_StrokeAttribute), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)StrokeAttribute_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)StrokeAttribute_repr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- StrokeAttribute_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_StrokeAttribute_methods, /* tp_methods */
- nullptr, /* tp_members */
- BPy_StrokeAttribute_getseters, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)StrokeAttribute_init, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "StrokeAttribute",
+ /*tp_basicsize*/ sizeof(BPy_StrokeAttribute),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)StrokeAttribute_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)StrokeAttribute_repr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ StrokeAttribute_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_StrokeAttribute_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_StrokeAttribute_getseters,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)StrokeAttribute_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp b/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp
index 2e1e7157b83..42e8452a4b5 100644
--- a/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp
+++ b/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp
@@ -253,7 +253,7 @@ PyDoc_STRVAR(StrokeShader_name_doc,
"\n"
":type: str");
-static PyObject *StrokeShader_name_get(BPy_StrokeShader *self, void *UNUSED(closure))
+static PyObject *StrokeShader_name_get(BPy_StrokeShader *self, void * /*closure*/)
{
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
}
@@ -266,43 +266,44 @@ static PyGetSetDef BPy_StrokeShader_getseters[] = {
/*-----------------------BPy_StrokeShader type definition ------------------------------*/
PyTypeObject StrokeShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "StrokeShader", /* tp_name */
- sizeof(BPy_StrokeShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)StrokeShader___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)StrokeShader___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- StrokeShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_StrokeShader_methods, /* tp_methods */
- nullptr, /* tp_members */
- BPy_StrokeShader_getseters, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)StrokeShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "StrokeShader",
+ /*tp_basicsize*/ sizeof(BPy_StrokeShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)StrokeShader___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)StrokeShader___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ StrokeShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_StrokeShader_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_StrokeShader_getseters,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)StrokeShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.cpp b/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.cpp
index 20941df20be..a8f4c5e4f3a 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.cpp
@@ -91,7 +91,7 @@ PyDoc_STRVAR(UnaryFunction0D_name_doc,
"\n"
":type: str");
-static PyObject *UnaryFunction0D_name_get(BPy_UnaryFunction0D *self, void *UNUSED(closure))
+static PyObject *UnaryFunction0D_name_get(BPy_UnaryFunction0D *self, void * /*closure*/)
{
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
}
@@ -108,43 +108,44 @@ static PyGetSetDef BPy_UnaryFunction0D_getseters[] = {
/*-----------------------BPy_UnaryFunction0D type definition ------------------------------*/
PyTypeObject UnaryFunction0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction0D", /* tp_name */
- sizeof(BPy_UnaryFunction0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction0D___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction0D___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_UnaryFunction0D_getseters, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- nullptr, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction0D",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction0D___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction0D___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_UnaryFunction0D_getseters,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ nullptr,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.cpp b/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.cpp
index 6c2877428a7..a78c6a056e6 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.cpp
@@ -85,7 +85,7 @@ PyDoc_STRVAR(UnaryFunction1D_name_doc,
"\n"
":type: str");
-static PyObject *UnaryFunction1D_name_get(BPy_UnaryFunction1D *self, void *UNUSED(closure))
+static PyObject *UnaryFunction1D_name_get(BPy_UnaryFunction1D *self, void * /*closure*/)
{
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
}
@@ -102,43 +102,44 @@ static PyGetSetDef BPy_UnaryFunction1D_getseters[] = {
/*-----------------------BPy_UnaryFunction1D type definition ------------------------------*/
PyTypeObject UnaryFunction1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction1D", /* tp_name */
- sizeof(BPy_UnaryFunction1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction1D___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction1D___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_UnaryFunction1D_getseters, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- nullptr, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction1D",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction1D___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction1D___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_UnaryFunction1D_getseters,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ nullptr,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp b/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp
index fe70658fd17..388f5d52ff0 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp
@@ -134,7 +134,7 @@ PyDoc_STRVAR(UnaryPredicate0D_name_doc,
"\n"
":type: str");
-static PyObject *UnaryPredicate0D_name_get(BPy_UnaryPredicate0D *self, void *UNUSED(closure))
+static PyObject *UnaryPredicate0D_name_get(BPy_UnaryPredicate0D *self, void * /*closure*/)
{
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
}
@@ -151,43 +151,44 @@ static PyGetSetDef BPy_UnaryPredicate0D_getseters[] = {
/*-----------------------BPy_UnaryPredicate0D type definition ------------------------------*/
PyTypeObject UnaryPredicate0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryPredicate0D", /* tp_name */
- sizeof(BPy_UnaryPredicate0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryPredicate0D___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryPredicate0D___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryPredicate0D___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryPredicate0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_UnaryPredicate0D_getseters, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryPredicate0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryPredicate0D",
+ /*tp_basicsize*/ sizeof(BPy_UnaryPredicate0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryPredicate0D___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryPredicate0D___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryPredicate0D___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryPredicate0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_UnaryPredicate0D_getseters,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryPredicate0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp
index a42f8bc6963..9240b4ed3ea 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp
@@ -192,7 +192,7 @@ PyDoc_STRVAR(UnaryPredicate1D_name_doc,
"\n"
":type: str");
-static PyObject *UnaryPredicate1D_name_get(BPy_UnaryPredicate1D *self, void *UNUSED(closure))
+static PyObject *UnaryPredicate1D_name_get(BPy_UnaryPredicate1D *self, void * /*closure*/)
{
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
}
@@ -209,43 +209,44 @@ static PyGetSetDef BPy_UnaryPredicate1D_getseters[] = {
/*-----------------------BPy_UnaryPredicate1D type definition ------------------------------*/
PyTypeObject UnaryPredicate1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryPredicate1D", /* tp_name */
- sizeof(BPy_UnaryPredicate1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryPredicate1D___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryPredicate1D___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryPredicate1D___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryPredicate1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_UnaryPredicate1D_getseters, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryPredicate1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryPredicate1D",
+ /*tp_basicsize*/ sizeof(BPy_UnaryPredicate1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryPredicate1D___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryPredicate1D___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryPredicate1D___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryPredicate1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_UnaryPredicate1D_getseters,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryPredicate1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_ViewMap.cpp b/source/blender/freestyle/intern/python/BPy_ViewMap.cpp
index 075e5220e43..31d6b89828e 100644
--- a/source/blender/freestyle/intern/python/BPy_ViewMap.cpp
+++ b/source/blender/freestyle/intern/python/BPy_ViewMap.cpp
@@ -141,12 +141,12 @@ PyDoc_STRVAR(ViewMap_scene_bbox_doc,
"\n"
":type: :class:`BBox`");
-static PyObject *ViewMap_scene_bbox_get(BPy_ViewMap *self, void *UNUSED(closure))
+static PyObject *ViewMap_scene_bbox_get(BPy_ViewMap *self, void * /*closure*/)
{
return BPy_BBox_from_BBox(self->vm->getScene3dBBox());
}
-static int ViewMap_scene_bbox_set(BPy_ViewMap *self, PyObject *value, void *UNUSED(closure))
+static int ViewMap_scene_bbox_set(BPy_ViewMap *self, PyObject *value, void * /*closure*/)
{
if (!BPy_BBox_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be a BBox");
@@ -168,43 +168,44 @@ static PyGetSetDef BPy_ViewMap_getseters[] = {
/*-----------------------BPy_ViewMap type definition ------------------------------*/
PyTypeObject ViewMap_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ViewMap", /* tp_name */
- sizeof(BPy_ViewMap), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)ViewMap_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)ViewMap_repr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ViewMap_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_ViewMap_methods, /* tp_methods */
- nullptr, /* tp_members */
- BPy_ViewMap_getseters, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ViewMap_init, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ViewMap",
+ /*tp_basicsize*/ sizeof(BPy_ViewMap),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)ViewMap_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)ViewMap_repr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ViewMap_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_ViewMap_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_ViewMap_getseters,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ViewMap_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BPy_ViewShape.cpp b/source/blender/freestyle/intern/python/BPy_ViewShape.cpp
index 806739239de..58c60e9b9fd 100644
--- a/source/blender/freestyle/intern/python/BPy_ViewShape.cpp
+++ b/source/blender/freestyle/intern/python/BPy_ViewShape.cpp
@@ -11,6 +11,8 @@
#include "Interface0D/BPy_ViewVertex.h"
#include "Interface1D/BPy_ViewEdge.h"
+#include "BLI_sys_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -163,7 +165,7 @@ PyDoc_STRVAR(ViewShape_sshape_doc,
"\n"
":type: :class:`SShape`");
-static PyObject *ViewShape_sshape_get(BPy_ViewShape *self, void *UNUSED(closure))
+static PyObject *ViewShape_sshape_get(BPy_ViewShape *self, void * /*closure*/)
{
SShape *ss = self->vs->sshape();
if (!ss) {
@@ -172,7 +174,7 @@ static PyObject *ViewShape_sshape_get(BPy_ViewShape *self, void *UNUSED(closure)
return BPy_SShape_from_SShape(*ss);
}
-static int ViewShape_sshape_set(BPy_ViewShape *self, PyObject *value, void *UNUSED(closure))
+static int ViewShape_sshape_set(BPy_ViewShape *self, PyObject *value, void * /*closure*/)
{
if (!BPy_SShape_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an SShape");
@@ -195,12 +197,12 @@ PyDoc_STRVAR(ViewShape_vertices_doc,
"\n"
":type: List of :class:`ViewVertex` objects");
-static PyObject *ViewShape_vertices_get(BPy_ViewShape *self, void *UNUSED(closure))
+static PyObject *ViewShape_vertices_get(BPy_ViewShape *self, void * /*closure*/)
{
vector<ViewVertex *> vertices = self->vs->vertices();
vector<ViewVertex *>::iterator it;
PyObject *py_vertices = PyList_New(vertices.size());
- unsigned int i = 0;
+ uint i = 0;
for (it = vertices.begin(); it != vertices.end(); it++) {
PyList_SET_ITEM(py_vertices, i++, Any_BPy_ViewVertex_from_ViewVertex(*(*it)));
@@ -208,7 +210,7 @@ static PyObject *ViewShape_vertices_get(BPy_ViewShape *self, void *UNUSED(closur
return py_vertices;
}
-static int ViewShape_vertices_set(BPy_ViewShape *self, PyObject *value, void *UNUSED(closure))
+static int ViewShape_vertices_set(BPy_ViewShape *self, PyObject *value, void * /*closure*/)
{
PyObject *item;
vector<ViewVertex *> v;
@@ -219,7 +221,7 @@ static int ViewShape_vertices_set(BPy_ViewShape *self, PyObject *value, void *UN
}
v.reserve(PyList_GET_SIZE(value));
- for (unsigned int i = 0; i < PyList_GET_SIZE(value); i++) {
+ for (uint i = 0; i < PyList_GET_SIZE(value); i++) {
item = PyList_GET_ITEM(value, i);
if (BPy_ViewVertex_Check(item)) {
v.push_back(((BPy_ViewVertex *)item)->vv);
@@ -238,12 +240,12 @@ PyDoc_STRVAR(ViewShape_edges_doc,
"\n"
":type: List of :class:`ViewEdge` objects");
-static PyObject *ViewShape_edges_get(BPy_ViewShape *self, void *UNUSED(closure))
+static PyObject *ViewShape_edges_get(BPy_ViewShape *self, void * /*closure*/)
{
vector<ViewEdge *> edges = self->vs->edges();
vector<ViewEdge *>::iterator it;
PyObject *py_edges = PyList_New(edges.size());
- unsigned int i = 0;
+ uint i = 0;
for (it = edges.begin(); it != edges.end(); it++) {
PyList_SET_ITEM(py_edges, i++, BPy_ViewEdge_from_ViewEdge(*(*it)));
@@ -251,7 +253,7 @@ static PyObject *ViewShape_edges_get(BPy_ViewShape *self, void *UNUSED(closure))
return py_edges;
}
-static int ViewShape_edges_set(BPy_ViewShape *self, PyObject *value, void *UNUSED(closure))
+static int ViewShape_edges_set(BPy_ViewShape *self, PyObject *value, void * /*closure*/)
{
PyObject *item;
vector<ViewEdge *> v;
@@ -281,7 +283,7 @@ PyDoc_STRVAR(ViewShape_name_doc,
"\n"
":type: str");
-static PyObject *ViewShape_name_get(BPy_ViewShape *self, void *UNUSED(closure))
+static PyObject *ViewShape_name_get(BPy_ViewShape *self, void * /*closure*/)
{
return PyUnicode_FromString(self->vs->getName().c_str());
}
@@ -291,7 +293,7 @@ PyDoc_STRVAR(ViewShape_library_path_doc,
"\n"
":type: str, or None if the ViewShape is not part of a library");
-static PyObject *ViewShape_library_path_get(BPy_ViewShape *self, void *UNUSED(closure))
+static PyObject *ViewShape_library_path_get(BPy_ViewShape *self, void * /*closure*/)
{
return PyUnicode_FromString(self->vs->getLibraryPath().c_str());
}
@@ -301,7 +303,7 @@ PyDoc_STRVAR(ViewShape_id_doc,
"\n"
":type: :class:`Id`");
-static PyObject *ViewShape_id_get(BPy_ViewShape *self, void *UNUSED(closure))
+static PyObject *ViewShape_id_get(BPy_ViewShape *self, void * /*closure*/)
{
Id id(self->vs->getId());
return BPy_Id_from_Id(id); // return a copy
@@ -336,43 +338,44 @@ static PyGetSetDef BPy_ViewShape_getseters[] = {
/*-----------------------BPy_ViewShape type definition ------------------------------*/
PyTypeObject ViewShape_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ViewShape", /* tp_name */
- sizeof(BPy_ViewShape), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)ViewShape_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)ViewShape_repr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ViewShape_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_ViewShape_methods, /* tp_methods */
- nullptr, /* tp_members */
- BPy_ViewShape_getseters, /* tp_getset */
- nullptr, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ViewShape_init, /* tp_init */
- nullptr, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ViewShape",
+ /*tp_basicsize*/ sizeof(BPy_ViewShape),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)ViewShape_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)ViewShape_repr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ViewShape_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_ViewShape_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_ViewShape_getseters,
+ /*tp_base*/ nullptr,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ViewShape_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ PyType_GenericNew,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp
index a76b40fd847..58ff6eeafa4 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp
@@ -42,44 +42,45 @@ static int FalseBP1D___init__(BPy_FalseBP1D *self, PyObject *args, PyObject *kwd
}
/*-----------------------BPy_FalseBP1D type definition ------------------------------*/
+
PyTypeObject FalseBP1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "FalseBP1D", /* tp_name */
- sizeof(BPy_FalseBP1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- FalseBP1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &BinaryPredicate1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)FalseBP1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ /*tp_name*/ PyVarObject_HEAD_INIT(nullptr, 0) "FalseBP1D",
+ /*tp_basicsize*/ sizeof(BPy_FalseBP1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ FalseBP1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &BinaryPredicate1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)FalseBP1D___init__,
+ /*tp_alloc*/ nullptr,
+ nullptr, /*tp_new*/
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp
index fe68e4ed3b8..55025c43c17 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp
@@ -45,43 +45,44 @@ static int Length2DBP1D___init__(BPy_Length2DBP1D *self, PyObject *args, PyObjec
/*-----------------------BPy_Length2DBP1D type definition ------------------------------*/
PyTypeObject Length2DBP1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Length2DBP1D", /* tp_name */
- sizeof(BPy_Length2DBP1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- Length2DBP1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &BinaryPredicate1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Length2DBP1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Length2DBP1D",
+ /*tp_basicsize*/ sizeof(BPy_Length2DBP1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ Length2DBP1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &BinaryPredicate1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)Length2DBP1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp
index 48b112aca6a..e202b661171 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp
@@ -44,43 +44,44 @@ static int SameShapeIdBP1D___init__(BPy_SameShapeIdBP1D *self, PyObject *args, P
/*-----------------------BPy_SameShapeIdBP1D type definition ------------------------------*/
PyTypeObject SameShapeIdBP1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "SameShapeIdBP1D", /* tp_name */
- sizeof(BPy_SameShapeIdBP1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- SameShapeIdBP1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &BinaryPredicate1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)SameShapeIdBP1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "SameShapeIdBP1D",
+ /*tp_basicsize*/ sizeof(BPy_SameShapeIdBP1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ SameShapeIdBP1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &BinaryPredicate1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)SameShapeIdBP1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp
index 5bf588d30d6..7dfcd10b468 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp
@@ -44,43 +44,44 @@ static int TrueBP1D___init__(BPy_TrueBP1D *self, PyObject *args, PyObject *kwds)
/*-----------------------BPy_TrueBP1D type definition ------------------------------*/
PyTypeObject TrueBP1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "TrueBP1D", /* tp_name */
- sizeof(BPy_TrueBP1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- TrueBP1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &BinaryPredicate1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)TrueBP1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "TrueBP1D",
+ /*tp_basicsize*/ sizeof(BPy_TrueBP1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ TrueBP1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &BinaryPredicate1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)TrueBP1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp
index 2a88efdb3ba..fd0d2dcfebd 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp
@@ -74,43 +74,44 @@ static int ViewMapGradientNormBP1D___init__(BPy_ViewMapGradientNormBP1D *self,
/*-----------------------BPy_ViewMapGradientNormBP1D type definition ----------------------------*/
PyTypeObject ViewMapGradientNormBP1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ViewMapGradientNormBP1D", /* tp_name */
- sizeof(BPy_ViewMapGradientNormBP1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ViewMapGradientNormBP1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &BinaryPredicate1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ViewMapGradientNormBP1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ViewMapGradientNormBP1D",
+ /*tp_basicsize*/ sizeof(BPy_ViewMapGradientNormBP1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ViewMapGradientNormBP1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &BinaryPredicate1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ViewMapGradientNormBP1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Director.cpp b/source/blender/freestyle/intern/python/Director.cpp
index 752b498a302..40df2033221 100644
--- a/source/blender/freestyle/intern/python/Director.cpp
+++ b/source/blender/freestyle/intern/python/Director.cpp
@@ -42,6 +42,8 @@
#include "UnaryFunction1D/BPy_UnaryFunction1DVec3f.h"
#include "UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h"
+#include "BLI_sys_types.h"
+
using namespace Freestyle;
// BinaryPredicate0D: __call__
@@ -254,7 +256,7 @@ int Director_BPy_UnaryFunction0D___call__(void *uf0D, void *py_uf0D, Interface0D
((UnaryFunction0D<FrsMaterial> *)uf0D)->result = *(((BPy_FrsMaterial *)result)->m);
}
else if (BPy_UnaryFunction0DUnsigned_Check(obj)) {
- ((UnaryFunction0D<unsigned> *)uf0D)->result = PyLong_AsLong(result);
+ ((UnaryFunction0D<uint> *)uf0D)->result = PyLong_AsLong(result);
}
else if (BPy_UnaryFunction0DVec2f_Check(obj)) {
Vec2f vec;
@@ -312,7 +314,7 @@ int Director_BPy_UnaryFunction1D___call__(void *uf1D, void *py_uf1D, Interface1D
((UnaryFunction1D<float> *)uf1D)->result = PyFloat_AsDouble(result);
}
else if (BPy_UnaryFunction1DUnsigned_Check(obj)) {
- ((UnaryFunction1D<unsigned> *)uf1D)->result = PyLong_AsLong(result);
+ ((UnaryFunction1D<uint> *)uf1D)->result = PyLong_AsLong(result);
}
else if (BPy_UnaryFunction1DVec2f_Check(obj)) {
Vec2f vec;
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
index 2b6d40e1710..655f9cdce1e 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
@@ -123,7 +123,7 @@ PyDoc_STRVAR(CurvePoint_first_svertex_doc,
"\n"
":type: :class:`SVertex`");
-static PyObject *CurvePoint_first_svertex_get(BPy_CurvePoint *self, void *UNUSED(closure))
+static PyObject *CurvePoint_first_svertex_get(BPy_CurvePoint *self, void * /*closure*/)
{
SVertex *A = self->cp->A();
if (A) {
@@ -132,9 +132,7 @@ static PyObject *CurvePoint_first_svertex_get(BPy_CurvePoint *self, void *UNUSED
Py_RETURN_NONE;
}
-static int CurvePoint_first_svertex_set(BPy_CurvePoint *self,
- PyObject *value,
- void *UNUSED(closure))
+static int CurvePoint_first_svertex_set(BPy_CurvePoint *self, PyObject *value, void * /*closure*/)
{
if (!BPy_SVertex_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
@@ -149,7 +147,7 @@ PyDoc_STRVAR(CurvePoint_second_svertex_doc,
"\n"
":type: :class:`SVertex`");
-static PyObject *CurvePoint_second_svertex_get(BPy_CurvePoint *self, void *UNUSED(closure))
+static PyObject *CurvePoint_second_svertex_get(BPy_CurvePoint *self, void * /*closure*/)
{
SVertex *B = self->cp->B();
if (B) {
@@ -158,9 +156,7 @@ static PyObject *CurvePoint_second_svertex_get(BPy_CurvePoint *self, void *UNUSE
Py_RETURN_NONE;
}
-static int CurvePoint_second_svertex_set(BPy_CurvePoint *self,
- PyObject *value,
- void *UNUSED(closure))
+static int CurvePoint_second_svertex_set(BPy_CurvePoint *self, PyObject *value, void * /*closure*/)
{
if (!BPy_SVertex_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
@@ -176,7 +172,7 @@ PyDoc_STRVAR(CurvePoint_fedge_doc,
"\n"
":type: :class:`FEdge`");
-static PyObject *CurvePoint_fedge_get(BPy_CurvePoint *self, void *UNUSED(closure))
+static PyObject *CurvePoint_fedge_get(BPy_CurvePoint *self, void * /*closure*/)
{
SVertex *A = self->cp->A();
Interface0D *B = (Interface0D *)self->cp->B();
@@ -192,12 +188,12 @@ PyDoc_STRVAR(CurvePoint_t2d_doc,
"\n"
":type: float");
-static PyObject *CurvePoint_t2d_get(BPy_CurvePoint *self, void *UNUSED(closure))
+static PyObject *CurvePoint_t2d_get(BPy_CurvePoint *self, void * /*closure*/)
{
return PyFloat_FromDouble(self->cp->t2d());
}
-static int CurvePoint_t2d_set(BPy_CurvePoint *self, PyObject *value, void *UNUSED(closure))
+static int CurvePoint_t2d_set(BPy_CurvePoint *self, PyObject *value, void * /*closure*/)
{
float scalar;
if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
@@ -225,44 +221,45 @@ static PyGetSetDef BPy_CurvePoint_getseters[] = {
};
/*-----------------------BPy_CurvePoint type definition ------------------------------*/
+
PyTypeObject CurvePoint_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "CurvePoint", /* tp_name */
- sizeof(BPy_CurvePoint), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- CurvePoint_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_CurvePoint_getseters, /* tp_getset */
- &Interface0D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)CurvePoint_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ /*tp_name*/ PyVarObject_HEAD_INIT(nullptr, 0) "CurvePoint",
+ /*tp_basicsize*/ sizeof(BPy_CurvePoint),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ CurvePoint_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_CurvePoint_getseters,
+ /*tp_base*/ &Interface0D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)CurvePoint_init,
+ /*tp_alloc*/ nullptr,
+ nullptr, /*tp_new*/
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
index ff59e5b1a10..9d3089e2bc2 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
@@ -10,6 +10,8 @@
#include "../BPy_Id.h"
#include "../Interface1D/BPy_FEdge.h"
+#include "BLI_sys_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -251,7 +253,7 @@ static Mathutils_Callback SVertex_mathutils_cb = {
SVertex_mathutils_set_index,
};
-static unsigned char SVertex_mathutils_cb_index = -1;
+static uchar SVertex_mathutils_cb_index = -1;
void SVertex_mathutils_register_callback()
{
@@ -265,13 +267,13 @@ PyDoc_STRVAR(SVertex_point_3d_doc,
"\n"
":type: :class:`mathutils.Vector`");
-static PyObject *SVertex_point_3d_get(BPy_SVertex *self, void *UNUSED(closure))
+static PyObject *SVertex_point_3d_get(BPy_SVertex *self, void * /*closure*/)
{
return Vector_CreatePyObject_cb(
(PyObject *)self, 3, SVertex_mathutils_cb_index, MATHUTILS_SUBTYPE_POINT3D);
}
-static int SVertex_point_3d_set(BPy_SVertex *self, PyObject *value, void *UNUSED(closure))
+static int SVertex_point_3d_set(BPy_SVertex *self, PyObject *value, void * /*closure*/)
{
float v[3];
if (mathutils_array_parse(v, 3, 3, value, "value must be a 3-dimensional vector") == -1) {
@@ -287,13 +289,13 @@ PyDoc_STRVAR(SVertex_point_2d_doc,
"\n"
":type: :class:`mathutils.Vector`");
-static PyObject *SVertex_point_2d_get(BPy_SVertex *self, void *UNUSED(closure))
+static PyObject *SVertex_point_2d_get(BPy_SVertex *self, void * /*closure*/)
{
return Vector_CreatePyObject_cb(
(PyObject *)self, 3, SVertex_mathutils_cb_index, MATHUTILS_SUBTYPE_POINT2D);
}
-static int SVertex_point_2d_set(BPy_SVertex *self, PyObject *value, void *UNUSED(closure))
+static int SVertex_point_2d_set(BPy_SVertex *self, PyObject *value, void * /*closure*/)
{
float v[3];
if (mathutils_array_parse(v, 3, 3, value, "value must be a 3-dimensional vector") == -1) {
@@ -309,13 +311,13 @@ PyDoc_STRVAR(SVertex_id_doc,
"\n"
":type: :class:`Id`");
-static PyObject *SVertex_id_get(BPy_SVertex *self, void *UNUSED(closure))
+static PyObject *SVertex_id_get(BPy_SVertex *self, void * /*closure*/)
{
Id id(self->sv->getId());
return BPy_Id_from_Id(id); // return a copy
}
-static int SVertex_id_set(BPy_SVertex *self, PyObject *value, void *UNUSED(closure))
+static int SVertex_id_set(BPy_SVertex *self, PyObject *value, void * /*closure*/)
{
if (!BPy_Id_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an Id");
@@ -332,13 +334,13 @@ PyDoc_STRVAR(SVertex_normals_doc,
"\n"
":type: list of :class:`mathutils.Vector` objects");
-static PyObject *SVertex_normals_get(BPy_SVertex *self, void *UNUSED(closure))
+static PyObject *SVertex_normals_get(BPy_SVertex *self, void * /*closure*/)
{
PyObject *py_normals;
set<Vec3r> normals = self->sv->normals();
set<Vec3r>::iterator it;
py_normals = PyList_New(normals.size());
- unsigned int i = 0;
+ uint i = 0;
for (it = normals.begin(); it != normals.end(); it++) {
Vec3r v(*it);
@@ -352,7 +354,7 @@ PyDoc_STRVAR(SVertex_normals_size_doc,
"\n"
":type: int");
-static PyObject *SVertex_normals_size_get(BPy_SVertex *self, void *UNUSED(closure))
+static PyObject *SVertex_normals_size_get(BPy_SVertex *self, void * /*closure*/)
{
return PyLong_FromLong(self->sv->normalsSize());
}
@@ -363,7 +365,7 @@ PyDoc_STRVAR(SVertex_viewvertex_doc,
"\n"
":type: :class:`ViewVertex`");
-static PyObject *SVertex_viewvertex_get(BPy_SVertex *self, void *UNUSED(closure))
+static PyObject *SVertex_viewvertex_get(BPy_SVertex *self, void * /*closure*/)
{
ViewVertex *vv = self->sv->viewvertex();
if (vv) {
@@ -385,7 +387,7 @@ PyDoc_STRVAR(SVertex_curvatures_doc,
"\n"
":type: tuple");
-static PyObject *SVertex_curvatures_get(BPy_SVertex *self, void *UNUSED(closure))
+static PyObject *SVertex_curvatures_get(BPy_SVertex *self, void * /*closure*/)
{
const CurvatureInfo *info = self->sv->getCurvatureInfo();
if (!info) {
@@ -438,44 +440,45 @@ static PyGetSetDef BPy_SVertex_getseters[] = {
};
/*-----------------------BPy_SVertex type definition ------------------------------*/
+
PyTypeObject SVertex_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "SVertex", /* tp_name */
- sizeof(BPy_SVertex), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- SVertex_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_SVertex_methods, /* tp_methods */
- nullptr, /* tp_members */
- BPy_SVertex_getseters, /* tp_getset */
- &Interface0D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)SVertex_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ /*tp_name*/ PyVarObject_HEAD_INIT(nullptr, 0) "SVertex",
+ /*tp_basicsize*/ sizeof(BPy_SVertex),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ SVertex_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_SVertex_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_SVertex_getseters,
+ /*tp_base*/ &Interface0D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)SVertex_init,
+ /*tp_alloc*/ nullptr,
+ nullptr, /*tp_new*/
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.cpp
index 4695d61af9c..07b399de1dc 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.cpp
@@ -118,7 +118,7 @@ PyDoc_STRVAR(ViewVertex_nature_doc,
"\n"
":type: :class:`Nature`");
-static PyObject *ViewVertex_nature_get(BPy_ViewVertex *self, void *UNUSED(closure))
+static PyObject *ViewVertex_nature_get(BPy_ViewVertex *self, void * /*closure*/)
{
Nature::VertexNature nature = self->vv->getNature();
if (PyErr_Occurred()) {
@@ -127,7 +127,7 @@ static PyObject *ViewVertex_nature_get(BPy_ViewVertex *self, void *UNUSED(closur
return BPy_Nature_from_Nature(nature); // return a copy
}
-static int ViewVertex_nature_set(BPy_ViewVertex *self, PyObject *value, void *UNUSED(closure))
+static int ViewVertex_nature_set(BPy_ViewVertex *self, PyObject *value, void * /*closure*/)
{
if (!BPy_Nature_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be a Nature");
@@ -147,44 +147,45 @@ static PyGetSetDef BPy_ViewVertex_getseters[] = {
};
/*-----------------------BPy_ViewVertex type definition ------------------------------*/
+
PyTypeObject ViewVertex_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ViewVertex", /* tp_name */
- sizeof(BPy_ViewVertex), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ViewVertex_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_ViewVertex_methods, /* tp_methods */
- nullptr, /* tp_members */
- BPy_ViewVertex_getseters, /* tp_getset */
- &Interface0D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ViewVertex_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ /*tp_name*/ PyVarObject_HEAD_INIT(nullptr, 0) "ViewVertex",
+ /*tp_basicsize*/ sizeof(BPy_ViewVertex),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ViewVertex_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_ViewVertex_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_ViewVertex_getseters,
+ /*tp_base*/ &Interface0D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ViewVertex_init,
+ /*tp_alloc*/ nullptr,
+ nullptr, /*tp_new*/
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp
index 1c1d8bf032a..f6edde778d4 100644
--- a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp
@@ -153,8 +153,8 @@ static int StrokeVertex_mathutils_check(BaseMathObject *bmo)
static int StrokeVertex_mathutils_get(BaseMathObject *bmo, int /*subtype*/)
{
BPy_StrokeVertex *self = (BPy_StrokeVertex *)bmo->cb_user;
- bmo->data[0] = (float)self->sv->x();
- bmo->data[1] = (float)self->sv->y();
+ bmo->data[0] = float(self->sv->x());
+ bmo->data[1] = float(self->sv->y());
return 0;
}
@@ -171,10 +171,10 @@ static int StrokeVertex_mathutils_get_index(BaseMathObject *bmo, int /*subtype*/
BPy_StrokeVertex *self = (BPy_StrokeVertex *)bmo->cb_user;
switch (index) {
case 0:
- bmo->data[0] = (float)self->sv->x();
+ bmo->data[0] = float(self->sv->x());
break;
case 1:
- bmo->data[1] = (float)self->sv->y();
+ bmo->data[1] = float(self->sv->y());
break;
default:
return -1;
@@ -206,7 +206,7 @@ static Mathutils_Callback StrokeVertex_mathutils_cb = {
StrokeVertex_mathutils_set_index,
};
-static unsigned char StrokeVertex_mathutils_cb_index = -1;
+static uchar StrokeVertex_mathutils_cb_index = -1;
void StrokeVertex_mathutils_register_callback()
{
@@ -220,14 +220,12 @@ PyDoc_STRVAR(StrokeVertex_attribute_doc,
"\n"
":type: :class:`StrokeAttribute`");
-static PyObject *StrokeVertex_attribute_get(BPy_StrokeVertex *self, void *UNUSED(closure))
+static PyObject *StrokeVertex_attribute_get(BPy_StrokeVertex *self, void * /*closure*/)
{
return BPy_StrokeAttribute_from_StrokeAttribute(self->sv->attribute());
}
-static int StrokeVertex_attribute_set(BPy_StrokeVertex *self,
- PyObject *value,
- void *UNUSED(closure))
+static int StrokeVertex_attribute_set(BPy_StrokeVertex *self, PyObject *value, void * /*closure*/)
{
if (!BPy_StrokeAttribute_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be a StrokeAttribute object");
@@ -242,15 +240,14 @@ PyDoc_STRVAR(StrokeVertex_curvilinear_abscissa_doc,
"\n"
":type: float");
-static PyObject *StrokeVertex_curvilinear_abscissa_get(BPy_StrokeVertex *self,
- void *UNUSED(closure))
+static PyObject *StrokeVertex_curvilinear_abscissa_get(BPy_StrokeVertex *self, void * /*closure*/)
{
return PyFloat_FromDouble(self->sv->curvilinearAbscissa());
}
static int StrokeVertex_curvilinear_abscissa_set(BPy_StrokeVertex *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
float scalar;
if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
@@ -267,12 +264,12 @@ PyDoc_STRVAR(StrokeVertex_point_doc,
"\n"
":type: :class:`mathutils.Vector`");
-static PyObject *StrokeVertex_point_get(BPy_StrokeVertex *self, void *UNUSED(closure))
+static PyObject *StrokeVertex_point_get(BPy_StrokeVertex *self, void * /*closure*/)
{
return Vector_CreatePyObject_cb((PyObject *)self, 2, StrokeVertex_mathutils_cb_index, 0);
}
-static int StrokeVertex_point_set(BPy_StrokeVertex *self, PyObject *value, void *UNUSED(closure))
+static int StrokeVertex_point_set(BPy_StrokeVertex *self, PyObject *value, void * /*closure*/)
{
float v[2];
if (mathutils_array_parse(v, 2, 2, value, "value must be a 2-dimensional vector") == -1) {
@@ -289,14 +286,14 @@ PyDoc_STRVAR(StrokeVertex_stroke_length_doc,
"\n"
":type: float");
-static PyObject *StrokeVertex_stroke_length_get(BPy_StrokeVertex *self, void *UNUSED(closure))
+static PyObject *StrokeVertex_stroke_length_get(BPy_StrokeVertex *self, void * /*closure*/)
{
return PyFloat_FromDouble(self->sv->strokeLength());
}
static int StrokeVertex_stroke_length_set(BPy_StrokeVertex *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
float scalar;
if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
@@ -313,7 +310,7 @@ PyDoc_STRVAR(StrokeVertex_u_doc,
"\n"
":type: float");
-static PyObject *StrokeVertex_u_get(BPy_StrokeVertex *self, void *UNUSED(closure))
+static PyObject *StrokeVertex_u_get(BPy_StrokeVertex *self, void * /*closure*/)
{
return PyFloat_FromDouble(self->sv->u());
}
@@ -344,44 +341,45 @@ static PyGetSetDef BPy_StrokeVertex_getseters[] = {
};
/*-----------------------BPy_StrokeVertex type definition ------------------------------*/
+
PyTypeObject StrokeVertex_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "StrokeVertex", /* tp_name */
- sizeof(BPy_StrokeVertex), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- StrokeVertex_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_StrokeVertex_getseters, /* tp_getset */
- &CurvePoint_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)StrokeVertex_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ /*tp_name*/ PyVarObject_HEAD_INIT(nullptr, 0) "StrokeVertex",
+ /*tp_basicsize*/ sizeof(BPy_StrokeVertex),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ StrokeVertex_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_StrokeVertex_getseters,
+ /*tp_base*/ &CurvePoint_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)StrokeVertex_init,
+ /*tp_alloc*/ nullptr,
+ nullptr, /*tp_new*/
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.cpp
index de9748d41c1..5e597f5294b 100644
--- a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.cpp
@@ -63,7 +63,7 @@ PyDoc_STRVAR(NonTVertex_svertex_doc,
"\n"
":type: :class:`SVertex`");
-static PyObject *NonTVertex_svertex_get(BPy_NonTVertex *self, void *UNUSED(closure))
+static PyObject *NonTVertex_svertex_get(BPy_NonTVertex *self, void * /*closure*/)
{
SVertex *v = self->ntv->svertex();
if (v) {
@@ -72,7 +72,7 @@ static PyObject *NonTVertex_svertex_get(BPy_NonTVertex *self, void *UNUSED(closu
Py_RETURN_NONE;
}
-static int NonTVertex_svertex_set(BPy_NonTVertex *self, PyObject *value, void *UNUSED(closure))
+static int NonTVertex_svertex_set(BPy_NonTVertex *self, PyObject *value, void * /*closure*/)
{
if (!BPy_SVertex_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
@@ -92,44 +92,45 @@ static PyGetSetDef BPy_NonTVertex_getseters[] = {
};
/*-----------------------BPy_NonTVertex type definition ------------------------------*/
+
PyTypeObject NonTVertex_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "NonTVertex", /* tp_name */
- sizeof(BPy_NonTVertex), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- NonTVertex_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_NonTVertex_getseters, /* tp_getset */
- &ViewVertex_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)NonTVertex_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ /*tp_name*/ PyVarObject_HEAD_INIT(nullptr, 0) "NonTVertex",
+ /*tp_basicsize*/ sizeof(BPy_NonTVertex),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ NonTVertex_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_NonTVertex_getseters,
+ /*tp_base*/ &ViewVertex_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)NonTVertex_init,
+ /*tp_alloc*/ nullptr,
+ nullptr, /*tp_new*/
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.cpp
index 8dc76c1c448..737f1548826 100644
--- a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.cpp
@@ -122,7 +122,7 @@ PyDoc_STRVAR(TVertex_front_svertex_doc,
"\n"
":type: :class:`SVertex`");
-static PyObject *TVertex_front_svertex_get(BPy_TVertex *self, void *UNUSED(closure))
+static PyObject *TVertex_front_svertex_get(BPy_TVertex *self, void * /*closure*/)
{
SVertex *v = self->tv->frontSVertex();
if (v) {
@@ -131,7 +131,7 @@ static PyObject *TVertex_front_svertex_get(BPy_TVertex *self, void *UNUSED(closu
Py_RETURN_NONE;
}
-static int TVertex_front_svertex_set(BPy_TVertex *self, PyObject *value, void *UNUSED(closure))
+static int TVertex_front_svertex_set(BPy_TVertex *self, PyObject *value, void * /*closure*/)
{
if (!BPy_SVertex_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
@@ -146,7 +146,7 @@ PyDoc_STRVAR(TVertex_back_svertex_doc,
"\n"
":type: :class:`SVertex`");
-static PyObject *TVertex_back_svertex_get(BPy_TVertex *self, void *UNUSED(closure))
+static PyObject *TVertex_back_svertex_get(BPy_TVertex *self, void * /*closure*/)
{
SVertex *v = self->tv->backSVertex();
if (v) {
@@ -155,7 +155,7 @@ static PyObject *TVertex_back_svertex_get(BPy_TVertex *self, void *UNUSED(closur
Py_RETURN_NONE;
}
-static int TVertex_back_svertex_set(BPy_TVertex *self, PyObject *value, void *UNUSED(closure))
+static int TVertex_back_svertex_set(BPy_TVertex *self, PyObject *value, void * /*closure*/)
{
if (!BPy_SVertex_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
@@ -170,13 +170,13 @@ PyDoc_STRVAR(TVertex_id_doc,
"\n"
":type: :class:`Id`");
-static PyObject *TVertex_id_get(BPy_TVertex *self, void *UNUSED(closure))
+static PyObject *TVertex_id_get(BPy_TVertex *self, void * /*closure*/)
{
Id id(self->tv->getId());
return BPy_Id_from_Id(id); // return a copy
}
-static int TVertex_id_set(BPy_TVertex *self, PyObject *value, void *UNUSED(closure))
+static int TVertex_id_set(BPy_TVertex *self, PyObject *value, void * /*closure*/)
{
if (!BPy_Id_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an Id");
@@ -202,44 +202,45 @@ static PyGetSetDef BPy_TVertex_getseters[] = {
};
/*-----------------------BPy_TVertex type definition ------------------------------*/
+
PyTypeObject TVertex_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "TVertex", /* tp_name */
- sizeof(BPy_TVertex), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- TVertex_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_TVertex_methods, /* tp_methods */
- nullptr, /* tp_members */
- BPy_TVertex_getseters, /* tp_getset */
- &ViewVertex_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)TVertex_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ /*tp_name*/ PyVarObject_HEAD_INIT(nullptr, 0) "TVertex",
+ /*tp_basicsize*/ sizeof(BPy_TVertex),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ TVertex_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_TVertex_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_TVertex_getseters,
+ /*tp_base*/ &ViewVertex_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)TVertex_init,
+ /*tp_alloc*/ nullptr,
+ nullptr, /*tp_new*/
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp
index db4ce6a8162..9684f96d586 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp
@@ -89,7 +89,7 @@ static Py_ssize_t FEdge_sq_length(BPy_FEdge * /*self*/)
return 2;
}
-static PyObject *FEdge_sq_item(BPy_FEdge *self, int keynum)
+static PyObject *FEdge_sq_item(BPy_FEdge *self, Py_ssize_t keynum)
{
if (keynum < 0) {
keynum += FEdge_sq_length(self);
@@ -106,16 +106,16 @@ static PyObject *FEdge_sq_item(BPy_FEdge *self, int keynum)
}
static PySequenceMethods BPy_FEdge_as_sequence = {
- (lenfunc)FEdge_sq_length, /* sq_length */
- nullptr, /* sq_concat */
- nullptr, /* sq_repeat */
- (ssizeargfunc)FEdge_sq_item, /* sq_item */
- nullptr, /* sq_slice */
- nullptr, /* sq_ass_item */
- nullptr, /* *was* sq_ass_slice */
- nullptr, /* sq_contains */
- nullptr, /* sq_inplace_concat */
- nullptr, /* sq_inplace_repeat */
+ /*sq_length*/ (lenfunc)FEdge_sq_length,
+ /*sq_concat*/ nullptr,
+ /*sq_repeat*/ nullptr,
+ /*sq_item*/ (ssizeargfunc)FEdge_sq_item,
+ /*was_sq_slice*/ nullptr, /* DEPRECATED. */
+ /*sq_ass_item*/ nullptr,
+ /*was_sq_ass_slice*/ nullptr, /* DEPRECATED. */
+ /*sq_contains*/ nullptr,
+ /*sq_inplace_concat*/ nullptr,
+ /*sq_inplace_repeat*/ nullptr,
};
/*----------------------FEdge get/setters ----------------------------*/
@@ -125,7 +125,7 @@ PyDoc_STRVAR(FEdge_first_svertex_doc,
"\n"
":type: :class:`SVertex`");
-static PyObject *FEdge_first_svertex_get(BPy_FEdge *self, void *UNUSED(closure))
+static PyObject *FEdge_first_svertex_get(BPy_FEdge *self, void * /*closure*/)
{
SVertex *A = self->fe->vertexA();
if (A) {
@@ -134,7 +134,7 @@ static PyObject *FEdge_first_svertex_get(BPy_FEdge *self, void *UNUSED(closure))
Py_RETURN_NONE;
}
-static int FEdge_first_svertex_set(BPy_FEdge *self, PyObject *value, void *UNUSED(closure))
+static int FEdge_first_svertex_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
{
if (!BPy_SVertex_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
@@ -149,7 +149,7 @@ PyDoc_STRVAR(FEdge_second_svertex_doc,
"\n"
":type: :class:`SVertex`");
-static PyObject *FEdge_second_svertex_get(BPy_FEdge *self, void *UNUSED(closure))
+static PyObject *FEdge_second_svertex_get(BPy_FEdge *self, void * /*closure*/)
{
SVertex *B = self->fe->vertexB();
if (B) {
@@ -158,7 +158,7 @@ static PyObject *FEdge_second_svertex_get(BPy_FEdge *self, void *UNUSED(closure)
Py_RETURN_NONE;
}
-static int FEdge_second_svertex_set(BPy_FEdge *self, PyObject *value, void *UNUSED(closure))
+static int FEdge_second_svertex_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
{
if (!BPy_SVertex_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
@@ -174,7 +174,7 @@ PyDoc_STRVAR(FEdge_next_fedge_doc,
"\n"
":type: :class:`FEdge`");
-static PyObject *FEdge_next_fedge_get(BPy_FEdge *self, void *UNUSED(closure))
+static PyObject *FEdge_next_fedge_get(BPy_FEdge *self, void * /*closure*/)
{
FEdge *fe = self->fe->nextEdge();
if (fe) {
@@ -183,7 +183,7 @@ static PyObject *FEdge_next_fedge_get(BPy_FEdge *self, void *UNUSED(closure))
Py_RETURN_NONE;
}
-static int FEdge_next_fedge_set(BPy_FEdge *self, PyObject *value, void *UNUSED(closure))
+static int FEdge_next_fedge_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
{
if (!BPy_FEdge_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an FEdge");
@@ -199,7 +199,7 @@ PyDoc_STRVAR(FEdge_previous_fedge_doc,
"\n"
":type: :class:`FEdge`");
-static PyObject *FEdge_previous_fedge_get(BPy_FEdge *self, void *UNUSED(closure))
+static PyObject *FEdge_previous_fedge_get(BPy_FEdge *self, void * /*closure*/)
{
FEdge *fe = self->fe->previousEdge();
if (fe) {
@@ -208,7 +208,7 @@ static PyObject *FEdge_previous_fedge_get(BPy_FEdge *self, void *UNUSED(closure)
Py_RETURN_NONE;
}
-static int FEdge_previous_fedge_set(BPy_FEdge *self, PyObject *value, void *UNUSED(closure))
+static int FEdge_previous_fedge_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
{
if (!BPy_FEdge_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an FEdge");
@@ -223,7 +223,7 @@ PyDoc_STRVAR(FEdge_viewedge_doc,
"\n"
":type: :class:`ViewEdge`");
-static PyObject *FEdge_viewedge_get(BPy_FEdge *self, void *UNUSED(closure))
+static PyObject *FEdge_viewedge_get(BPy_FEdge *self, void * /*closure*/)
{
ViewEdge *ve = self->fe->viewedge();
if (ve) {
@@ -232,7 +232,7 @@ static PyObject *FEdge_viewedge_get(BPy_FEdge *self, void *UNUSED(closure))
Py_RETURN_NONE;
}
-static int FEdge_viewedge_set(BPy_FEdge *self, PyObject *value, void *UNUSED(closure))
+static int FEdge_viewedge_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
{
if (!BPy_ViewEdge_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an ViewEdge");
@@ -247,12 +247,12 @@ PyDoc_STRVAR(FEdge_is_smooth_doc,
"\n"
":type: bool");
-static PyObject *FEdge_is_smooth_get(BPy_FEdge *self, void *UNUSED(closure))
+static PyObject *FEdge_is_smooth_get(BPy_FEdge *self, void * /*closure*/)
{
return PyBool_from_bool(self->fe->isSmooth());
}
-static int FEdge_is_smooth_set(BPy_FEdge *self, PyObject *value, void *UNUSED(closure))
+static int FEdge_is_smooth_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
{
if (!PyBool_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be boolean");
@@ -267,13 +267,13 @@ PyDoc_STRVAR(FEdge_id_doc,
"\n"
":type: :class:`Id`");
-static PyObject *FEdge_id_get(BPy_FEdge *self, void *UNUSED(closure))
+static PyObject *FEdge_id_get(BPy_FEdge *self, void * /*closure*/)
{
Id id(self->fe->getId());
return BPy_Id_from_Id(id); // return a copy
}
-static int FEdge_id_set(BPy_FEdge *self, PyObject *value, void *UNUSED(closure))
+static int FEdge_id_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
{
if (!BPy_Id_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an Id");
@@ -288,12 +288,12 @@ PyDoc_STRVAR(FEdge_nature_doc,
"\n"
":type: :class:`Nature`");
-static PyObject *FEdge_nature_get(BPy_FEdge *self, void *UNUSED(closure))
+static PyObject *FEdge_nature_get(BPy_FEdge *self, void * /*closure*/)
{
return BPy_Nature_from_Nature(self->fe->getNature());
}
-static int FEdge_nature_set(BPy_FEdge *self, PyObject *value, void *UNUSED(closure))
+static int FEdge_nature_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
{
if (!BPy_Nature_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be a Nature");
@@ -342,43 +342,44 @@ static PyGetSetDef BPy_FEdge_getseters[] = {
/*-----------------------BPy_FEdge type definition ------------------------------*/
PyTypeObject FEdge_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "FEdge", /* tp_name */
- sizeof(BPy_FEdge), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- &BPy_FEdge_as_sequence, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- FEdge_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_FEdge_getseters, /* tp_getset */
- &Interface1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)FEdge_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "FEdge",
+ /*tp_basicsize*/ sizeof(BPy_FEdge),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ &BPy_FEdge_as_sequence,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ FEdge_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_FEdge_getseters,
+ /*tp_base*/ &Interface1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)FEdge_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp
index 726e9f44956..cc6e6cb7d53 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp
@@ -146,7 +146,7 @@ PyDoc_STRVAR(FrsCurve_is_empty_doc,
"\n"
":type: bool");
-static PyObject *FrsCurve_is_empty_get(BPy_FrsCurve *self, void *UNUSED(closure))
+static PyObject *FrsCurve_is_empty_get(BPy_FrsCurve *self, void * /*closure*/)
{
return PyBool_from_bool(self->c->empty());
}
@@ -156,7 +156,7 @@ PyDoc_STRVAR(FrsCurve_segments_size_doc,
"\n"
":type: int");
-static PyObject *FrsCurve_segments_size_get(BPy_FrsCurve *self, void *UNUSED(closure))
+static PyObject *FrsCurve_segments_size_get(BPy_FrsCurve *self, void * /*closure*/)
{
return PyLong_FromLong(self->c->nSegments());
}
@@ -174,43 +174,44 @@ static PyGetSetDef BPy_FrsCurve_getseters[] = {
/*-----------------------BPy_FrsCurve type definition ------------------------------*/
PyTypeObject FrsCurve_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Curve", /* tp_name */
- sizeof(BPy_FrsCurve), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- FrsCurve_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_FrsCurve_methods, /* tp_methods */
- nullptr, /* tp_members */
- BPy_FrsCurve_getseters, /* tp_getset */
- &Interface1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)FrsCurve_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Curve",
+ /*tp_basicsize*/ sizeof(BPy_FrsCurve),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ FrsCurve_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_FrsCurve_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_FrsCurve_getseters,
+ /*tp_base*/ &Interface1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)FrsCurve_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp
index 57c00ab1b99..8acbfefa995 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp
@@ -13,6 +13,8 @@
#include "../Interface0D/CurvePoint/BPy_StrokeVertex.h"
#include "../Iterator/BPy_StrokeVertexIterator.h"
+#include "BLI_sys_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -72,7 +74,7 @@ static Py_ssize_t Stroke_sq_length(BPy_Stroke *self)
return self->s->strokeVerticesSize();
}
-static PyObject *Stroke_sq_item(BPy_Stroke *self, int keynum)
+static PyObject *Stroke_sq_item(BPy_Stroke *self, Py_ssize_t keynum)
{
if (keynum < 0) {
keynum += Stroke_sq_length(self);
@@ -351,12 +353,12 @@ PyDoc_STRVAR(Stroke_medium_type_doc,
"\n"
":type: :class:`MediumType`");
-static PyObject *Stroke_medium_type_get(BPy_Stroke *self, void *UNUSED(closure))
+static PyObject *Stroke_medium_type_get(BPy_Stroke *self, void * /*closure*/)
{
return BPy_MediumType_from_MediumType(self->s->getMediumType());
}
-static int Stroke_medium_type_set(BPy_Stroke *self, PyObject *value, void *UNUSED(closure))
+static int Stroke_medium_type_set(BPy_Stroke *self, PyObject *value, void * /*closure*/)
{
if (!BPy_MediumType_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be a MediumType");
@@ -371,14 +373,14 @@ PyDoc_STRVAR(Stroke_texture_id_doc,
"\n"
":type: int");
-static PyObject *Stroke_texture_id_get(BPy_Stroke *self, void *UNUSED(closure))
+static PyObject *Stroke_texture_id_get(BPy_Stroke *self, void * /*closure*/)
{
return PyLong_FromLong(self->s->getTextureId());
}
-static int Stroke_texture_id_set(BPy_Stroke *self, PyObject *value, void *UNUSED(closure))
+static int Stroke_texture_id_set(BPy_Stroke *self, PyObject *value, void * /*closure*/)
{
- unsigned int i = PyLong_AsUnsignedLong(value);
+ uint i = PyLong_AsUnsignedLong(value);
if (PyErr_Occurred()) {
return -1;
}
@@ -391,12 +393,12 @@ PyDoc_STRVAR(Stroke_tips_doc,
"\n"
":type: bool");
-static PyObject *Stroke_tips_get(BPy_Stroke *self, void *UNUSED(closure))
+static PyObject *Stroke_tips_get(BPy_Stroke *self, void * /*closure*/)
{
return PyBool_from_bool(self->s->hasTips());
}
-static int Stroke_tips_set(BPy_Stroke *self, PyObject *value, void *UNUSED(closure))
+static int Stroke_tips_set(BPy_Stroke *self, PyObject *value, void * /*closure*/)
{
if (!PyBool_Check(value)) {
return -1;
@@ -410,12 +412,12 @@ PyDoc_STRVAR(Stroke_length_2d_doc,
"\n"
":type: float");
-static PyObject *Stroke_length_2d_get(BPy_Stroke *self, void *UNUSED(closure))
+static PyObject *Stroke_length_2d_get(BPy_Stroke *self, void * /*closure*/)
{
return PyFloat_FromDouble(self->s->getLength2D());
}
-static int Stroke_length_2d_set(BPy_Stroke *self, PyObject *value, void *UNUSED(closure))
+static int Stroke_length_2d_set(BPy_Stroke *self, PyObject *value, void * /*closure*/)
{
float scalar;
if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
@@ -432,13 +434,13 @@ PyDoc_STRVAR(Stroke_id_doc,
"\n"
":type: :class:`Id`");
-static PyObject *Stroke_id_get(BPy_Stroke *self, void *UNUSED(closure))
+static PyObject *Stroke_id_get(BPy_Stroke *self, void * /*closure*/)
{
Id id(self->s->getId());
return BPy_Id_from_Id(id); // return a copy
}
-static int Stroke_id_set(BPy_Stroke *self, PyObject *value, void *UNUSED(closure))
+static int Stroke_id_set(BPy_Stroke *self, PyObject *value, void * /*closure*/)
{
if (!BPy_Id_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an Id");
@@ -472,56 +474,57 @@ static PyGetSetDef BPy_Stroke_getseters[] = {
/*-----------------------BPy_Stroke type definition ------------------------------*/
static PySequenceMethods BPy_Stroke_as_sequence = {
- (lenfunc)Stroke_sq_length, /* sq_length */
- nullptr, /* sq_concat */
- nullptr, /* sq_repeat */
- (ssizeargfunc)Stroke_sq_item, /* sq_item */
- nullptr, /* sq_slice */
- nullptr, /* sq_ass_item */
- nullptr, /* *was* sq_ass_slice */
- nullptr, /* sq_contains */
- nullptr, /* sq_inplace_concat */
- nullptr, /* sq_inplace_repeat */
+ /*sq_length*/ (lenfunc)Stroke_sq_length,
+ /*sq_concat*/ nullptr,
+ /*sq_repeat*/ nullptr,
+ /*sq_item*/ (ssizeargfunc)Stroke_sq_item,
+ /*was_sq_slice*/ nullptr, /* DEPRECATED. */
+ /*sq_ass_item*/ nullptr,
+ /*was_sq_ass_slice*/ nullptr, /* DEPRECATED. */
+ /*sq_contains*/ nullptr,
+ /*sq_inplace_concat*/ nullptr,
+ /*sq_inplace_repeat*/ nullptr,
};
PyTypeObject Stroke_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Stroke", /* tp_name */
- sizeof(BPy_Stroke), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- &BPy_Stroke_as_sequence, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- Stroke_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- (getiterfunc)Stroke_iter, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_Stroke_methods, /* tp_methods */
- nullptr, /* tp_members */
- BPy_Stroke_getseters, /* tp_getset */
- &Interface1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Stroke_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Stroke",
+ /*tp_basicsize*/ sizeof(BPy_Stroke),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ &BPy_Stroke_as_sequence,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ Stroke_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ (getiterfunc)Stroke_iter,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_Stroke_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_Stroke_getseters,
+ /*tp_base*/ &Interface1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)Stroke_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.cpp
index 5a58a09d346..f15b3c3050a 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.cpp
@@ -85,7 +85,7 @@ PyDoc_STRVAR(ViewEdge_first_viewvertex_doc,
"\n"
":type: :class:`ViewVertex`");
-static PyObject *ViewEdge_first_viewvertex_get(BPy_ViewEdge *self, void *UNUSED(closure))
+static PyObject *ViewEdge_first_viewvertex_get(BPy_ViewEdge *self, void * /*closure*/)
{
ViewVertex *v = self->ve->A();
if (v) {
@@ -94,9 +94,7 @@ static PyObject *ViewEdge_first_viewvertex_get(BPy_ViewEdge *self, void *UNUSED(
Py_RETURN_NONE;
}
-static int ViewEdge_first_viewvertex_set(BPy_ViewEdge *self,
- PyObject *value,
- void *UNUSED(closure))
+static int ViewEdge_first_viewvertex_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
{
if (!BPy_ViewVertex_Check(value)) {
return -1;
@@ -110,7 +108,7 @@ PyDoc_STRVAR(ViewEdge_last_viewvertex_doc,
"\n"
":type: :class:`ViewVertex`");
-static PyObject *ViewEdge_last_viewvertex_get(BPy_ViewEdge *self, void *UNUSED(closure))
+static PyObject *ViewEdge_last_viewvertex_get(BPy_ViewEdge *self, void * /*closure*/)
{
ViewVertex *v = self->ve->B();
if (v) {
@@ -119,7 +117,7 @@ static PyObject *ViewEdge_last_viewvertex_get(BPy_ViewEdge *self, void *UNUSED(c
Py_RETURN_NONE;
}
-static int ViewEdge_last_viewvertex_set(BPy_ViewEdge *self, PyObject *value, void *UNUSED(closure))
+static int ViewEdge_last_viewvertex_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
{
if (!BPy_ViewVertex_Check(value)) {
return -1;
@@ -133,7 +131,7 @@ PyDoc_STRVAR(ViewEdge_first_fedge_doc,
"\n"
":type: :class:`FEdge`");
-static PyObject *ViewEdge_first_fedge_get(BPy_ViewEdge *self, void *UNUSED(closure))
+static PyObject *ViewEdge_first_fedge_get(BPy_ViewEdge *self, void * /*closure*/)
{
FEdge *fe = self->ve->fedgeA();
if (fe) {
@@ -142,7 +140,7 @@ static PyObject *ViewEdge_first_fedge_get(BPy_ViewEdge *self, void *UNUSED(closu
Py_RETURN_NONE;
}
-static int ViewEdge_first_fedge_set(BPy_ViewEdge *self, PyObject *value, void *UNUSED(closure))
+static int ViewEdge_first_fedge_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
{
if (!BPy_FEdge_Check(value)) {
return -1;
@@ -156,7 +154,7 @@ PyDoc_STRVAR(ViewEdge_last_fedge_doc,
"\n"
":type: :class:`FEdge`");
-static PyObject *ViewEdge_last_fedge_get(BPy_ViewEdge *self, void *UNUSED(closure))
+static PyObject *ViewEdge_last_fedge_get(BPy_ViewEdge *self, void * /*closure*/)
{
FEdge *fe = self->ve->fedgeB();
if (fe) {
@@ -165,7 +163,7 @@ static PyObject *ViewEdge_last_fedge_get(BPy_ViewEdge *self, void *UNUSED(closur
Py_RETURN_NONE;
}
-static int ViewEdge_last_fedge_set(BPy_ViewEdge *self, PyObject *value, void *UNUSED(closure))
+static int ViewEdge_last_fedge_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
{
if (!BPy_FEdge_Check(value)) {
return -1;
@@ -179,7 +177,7 @@ PyDoc_STRVAR(ViewEdge_viewshape_doc,
"\n"
":type: :class:`ViewShape`");
-static PyObject *ViewEdge_viewshape_get(BPy_ViewEdge *self, void *UNUSED(closure))
+static PyObject *ViewEdge_viewshape_get(BPy_ViewEdge *self, void * /*closure*/)
{
ViewShape *vs = self->ve->viewShape();
if (vs) {
@@ -188,7 +186,7 @@ static PyObject *ViewEdge_viewshape_get(BPy_ViewEdge *self, void *UNUSED(closure
Py_RETURN_NONE;
}
-static int ViewEdge_viewshape_set(BPy_ViewEdge *self, PyObject *value, void *UNUSED(closure))
+static int ViewEdge_viewshape_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
{
if (!BPy_ViewShape_Check(value)) {
return -1;
@@ -203,7 +201,7 @@ PyDoc_STRVAR(ViewEdge_occludee_doc,
"\n"
":type: :class:`ViewShape`");
-static PyObject *ViewEdge_occludee_get(BPy_ViewEdge *self, void *UNUSED(closure))
+static PyObject *ViewEdge_occludee_get(BPy_ViewEdge *self, void * /*closure*/)
{
ViewShape *vs = self->ve->aShape();
if (vs) {
@@ -212,7 +210,7 @@ static PyObject *ViewEdge_occludee_get(BPy_ViewEdge *self, void *UNUSED(closure)
Py_RETURN_NONE;
}
-static int ViewEdge_occludee_set(BPy_ViewEdge *self, PyObject *value, void *UNUSED(closure))
+static int ViewEdge_occludee_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
{
if (!BPy_ViewShape_Check(value)) {
return -1;
@@ -226,7 +224,7 @@ PyDoc_STRVAR(ViewEdge_is_closed_doc,
"\n"
":type: bool");
-static PyObject *ViewEdge_is_closed_get(BPy_ViewEdge *self, void *UNUSED(closure))
+static PyObject *ViewEdge_is_closed_get(BPy_ViewEdge *self, void * /*closure*/)
{
return PyBool_from_bool(self->ve->isClosed());
}
@@ -236,13 +234,13 @@ PyDoc_STRVAR(ViewEdge_id_doc,
"\n"
":type: :class:`Id`");
-static PyObject *ViewEdge_id_get(BPy_ViewEdge *self, void *UNUSED(closure))
+static PyObject *ViewEdge_id_get(BPy_ViewEdge *self, void * /*closure*/)
{
Id id(self->ve->getId());
return BPy_Id_from_Id(id); // return a copy
}
-static int ViewEdge_id_set(BPy_ViewEdge *self, PyObject *value, void *UNUSED(closure))
+static int ViewEdge_id_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
{
if (!BPy_Id_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an Id");
@@ -257,12 +255,12 @@ PyDoc_STRVAR(ViewEdge_nature_doc,
"\n"
":type: :class:`Nature`");
-static PyObject *ViewEdge_nature_get(BPy_ViewEdge *self, void *UNUSED(closure))
+static PyObject *ViewEdge_nature_get(BPy_ViewEdge *self, void * /*closure*/)
{
return BPy_Nature_from_Nature(self->ve->getNature());
}
-static int ViewEdge_nature_set(BPy_ViewEdge *self, PyObject *value, void *UNUSED(closure))
+static int ViewEdge_nature_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
{
if (!BPy_Nature_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be a Nature");
@@ -277,12 +275,12 @@ PyDoc_STRVAR(ViewEdge_qi_doc,
"\n"
":type: int");
-static PyObject *ViewEdge_qi_get(BPy_ViewEdge *self, void *UNUSED(closure))
+static PyObject *ViewEdge_qi_get(BPy_ViewEdge *self, void * /*closure*/)
{
return PyLong_FromLong(self->ve->qi());
}
-static int ViewEdge_qi_set(BPy_ViewEdge *self, PyObject *value, void *UNUSED(closure))
+static int ViewEdge_qi_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
{
int qi;
@@ -298,14 +296,14 @@ PyDoc_STRVAR(ViewEdge_chaining_time_stamp_doc,
"\n"
":type: int");
-static PyObject *ViewEdge_chaining_time_stamp_get(BPy_ViewEdge *self, void *UNUSED(closure))
+static PyObject *ViewEdge_chaining_time_stamp_get(BPy_ViewEdge *self, void * /*closure*/)
{
return PyLong_FromLong(self->ve->getChainingTimeStamp());
}
static int ViewEdge_chaining_time_stamp_set(BPy_ViewEdge *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
int timestamp;
@@ -370,43 +368,44 @@ static PyGetSetDef BPy_ViewEdge_getseters[] = {
/*-----------------------BPy_ViewEdge type definition ------------------------------*/
PyTypeObject ViewEdge_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ViewEdge", /* tp_name */
- sizeof(BPy_ViewEdge), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ViewEdge_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_ViewEdge_methods, /* tp_methods */
- nullptr, /* tp_members */
- BPy_ViewEdge_getseters, /* tp_getset */
- &Interface1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ViewEdge_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ViewEdge",
+ /*tp_basicsize*/ sizeof(BPy_ViewEdge),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ViewEdge_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_ViewEdge_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_ViewEdge_getseters,
+ /*tp_base*/ &Interface1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ViewEdge_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp
index 5f98252844f..e69572687ca 100644
--- a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp
@@ -134,43 +134,44 @@ static PyMethodDef BPy_Chain_methods[] = {
/*-----------------------BPy_Chain type definition ------------------------------*/
PyTypeObject Chain_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Chain", /* tp_name */
- sizeof(BPy_Chain), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- Chain_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_Chain_methods, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &FrsCurve_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Chain_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Chain",
+ /*tp_basicsize*/ sizeof(BPy_Chain),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ Chain_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_Chain_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &FrsCurve_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)Chain_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp
index 840f49ff345..bb8c8f42042 100644
--- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp
@@ -9,6 +9,8 @@
#include "../../BPy_Convert.h"
#include "../../Interface0D/BPy_SVertex.h"
+#include "BLI_sys_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -178,7 +180,7 @@ static Mathutils_Callback FEdgeSharp_mathutils_cb = {
FEdgeSharp_mathutils_set_index,
};
-static unsigned char FEdgeSharp_mathutils_cb_index = -1;
+static uchar FEdgeSharp_mathutils_cb_index = -1;
void FEdgeSharp_mathutils_register_callback()
{
@@ -193,15 +195,13 @@ PyDoc_STRVAR(FEdgeSharp_normal_right_doc,
"\n"
":type: :class:`mathutils.Vector`");
-static PyObject *FEdgeSharp_normal_right_get(BPy_FEdgeSharp *self, void *UNUSED(closure))
+static PyObject *FEdgeSharp_normal_right_get(BPy_FEdgeSharp *self, void * /*closure*/)
{
return Vector_CreatePyObject_cb(
(PyObject *)self, 3, FEdgeSharp_mathutils_cb_index, MATHUTILS_SUBTYPE_NORMAL_A);
}
-static int FEdgeSharp_normal_right_set(BPy_FEdgeSharp *self,
- PyObject *value,
- void *UNUSED(closure))
+static int FEdgeSharp_normal_right_set(BPy_FEdgeSharp *self, PyObject *value, void * /*closure*/)
{
float v[3];
if (mathutils_array_parse(v, 3, 3, value, "value must be a 3-dimensional vector") == -1) {
@@ -217,13 +217,13 @@ PyDoc_STRVAR(FEdgeSharp_normal_left_doc,
"\n"
":type: :class:`mathutils.Vector`");
-static PyObject *FEdgeSharp_normal_left_get(BPy_FEdgeSharp *self, void *UNUSED(closure))
+static PyObject *FEdgeSharp_normal_left_get(BPy_FEdgeSharp *self, void * /*closure*/)
{
return Vector_CreatePyObject_cb(
(PyObject *)self, 3, FEdgeSharp_mathutils_cb_index, MATHUTILS_SUBTYPE_NORMAL_B);
}
-static int FEdgeSharp_normal_left_set(BPy_FEdgeSharp *self, PyObject *value, void *UNUSED(closure))
+static int FEdgeSharp_normal_left_set(BPy_FEdgeSharp *self, PyObject *value, void * /*closure*/)
{
float v[3];
if (mathutils_array_parse(v, 3, 3, value, "value must be a 3-dimensional vector") == -1) {
@@ -241,16 +241,16 @@ PyDoc_STRVAR(FEdgeSharp_material_index_right_doc,
"\n"
":type: int");
-static PyObject *FEdgeSharp_material_index_right_get(BPy_FEdgeSharp *self, void *UNUSED(closure))
+static PyObject *FEdgeSharp_material_index_right_get(BPy_FEdgeSharp *self, void * /*closure*/)
{
return PyLong_FromLong(self->fes->aFrsMaterialIndex());
}
static int FEdgeSharp_material_index_right_set(BPy_FEdgeSharp *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
- unsigned int i = PyLong_AsUnsignedLong(value);
+ uint i = PyLong_AsUnsignedLong(value);
if (PyErr_Occurred()) {
return -1;
}
@@ -263,16 +263,16 @@ PyDoc_STRVAR(FEdgeSharp_material_index_left_doc,
"\n"
":type: int");
-static PyObject *FEdgeSharp_material_index_left_get(BPy_FEdgeSharp *self, void *UNUSED(closure))
+static PyObject *FEdgeSharp_material_index_left_get(BPy_FEdgeSharp *self, void * /*closure*/)
{
return PyLong_FromLong(self->fes->bFrsMaterialIndex());
}
static int FEdgeSharp_material_index_left_set(BPy_FEdgeSharp *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
- unsigned int i = PyLong_AsUnsignedLong(value);
+ uint i = PyLong_AsUnsignedLong(value);
if (PyErr_Occurred()) {
return -1;
}
@@ -286,7 +286,7 @@ PyDoc_STRVAR(FEdgeSharp_material_right_doc,
"\n"
":type: :class:`Material`");
-static PyObject *FEdgeSharp_material_right_get(BPy_FEdgeSharp *self, void *UNUSED(closure))
+static PyObject *FEdgeSharp_material_right_get(BPy_FEdgeSharp *self, void * /*closure*/)
{
return BPy_FrsMaterial_from_FrsMaterial(self->fes->aFrsMaterial());
}
@@ -296,7 +296,7 @@ PyDoc_STRVAR(FEdgeSharp_material_left_doc,
"\n"
":type: :class:`Material`");
-static PyObject *FEdgeSharp_material_left_get(BPy_FEdgeSharp *self, void *UNUSED(closure))
+static PyObject *FEdgeSharp_material_left_get(BPy_FEdgeSharp *self, void * /*closure*/)
{
return BPy_FrsMaterial_from_FrsMaterial(self->fes->bFrsMaterial());
}
@@ -308,14 +308,14 @@ PyDoc_STRVAR(FEdgeSharp_face_mark_right_doc,
"\n"
":type: bool");
-static PyObject *FEdgeSharp_face_mark_right_get(BPy_FEdgeSharp *self, void *UNUSED(closure))
+static PyObject *FEdgeSharp_face_mark_right_get(BPy_FEdgeSharp *self, void * /*closure*/)
{
return PyBool_from_bool(self->fes->aFaceMark());
}
static int FEdgeSharp_face_mark_right_set(BPy_FEdgeSharp *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
if (!PyBool_Check(value)) {
return -1;
@@ -329,14 +329,12 @@ PyDoc_STRVAR(FEdgeSharp_face_mark_left_doc,
"\n"
":type: bool");
-static PyObject *FEdgeSharp_face_mark_left_get(BPy_FEdgeSharp *self, void *UNUSED(closure))
+static PyObject *FEdgeSharp_face_mark_left_get(BPy_FEdgeSharp *self, void * /*closure*/)
{
return PyBool_from_bool(self->fes->bFaceMark());
}
-static int FEdgeSharp_face_mark_left_set(BPy_FEdgeSharp *self,
- PyObject *value,
- void *UNUSED(closure))
+static int FEdgeSharp_face_mark_left_set(BPy_FEdgeSharp *self, PyObject *value, void * /*closure*/)
{
if (!PyBool_Check(value)) {
return -1;
@@ -392,43 +390,44 @@ static PyGetSetDef BPy_FEdgeSharp_getseters[] = {
/*-----------------------BPy_FEdgeSharp type definition ------------------------------*/
PyTypeObject FEdgeSharp_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "FEdgeSharp", /* tp_name */
- sizeof(BPy_FEdgeSharp), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- FEdgeSharp_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_FEdgeSharp_getseters, /* tp_getset */
- &FEdge_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)FEdgeSharp_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "FEdgeSharp",
+ /*tp_basicsize*/ sizeof(BPy_FEdgeSharp),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ FEdgeSharp_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_FEdgeSharp_getseters,
+ /*tp_base*/ &FEdge_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)FEdgeSharp_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp
index bf62d5bd31d..47f0aff8374 100644
--- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp
@@ -9,6 +9,8 @@
#include "../../BPy_Convert.h"
#include "../../Interface0D/BPy_SVertex.h"
+#include "BLI_sys_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -129,7 +131,7 @@ static Mathutils_Callback FEdgeSmooth_mathutils_cb = {
FEdgeSmooth_mathutils_set_index,
};
-static unsigned char FEdgeSmooth_mathutils_cb_index = -1;
+static uchar FEdgeSmooth_mathutils_cb_index = -1;
void FEdgeSmooth_mathutils_register_callback()
{
@@ -143,12 +145,12 @@ PyDoc_STRVAR(FEdgeSmooth_normal_doc,
"\n"
":type: :class:`mathutils.Vector`");
-static PyObject *FEdgeSmooth_normal_get(BPy_FEdgeSmooth *self, void *UNUSED(closure))
+static PyObject *FEdgeSmooth_normal_get(BPy_FEdgeSmooth *self, void * /*closure*/)
{
return Vector_CreatePyObject_cb((PyObject *)self, 3, FEdgeSmooth_mathutils_cb_index, 0);
}
-static int FEdgeSmooth_normal_set(BPy_FEdgeSmooth *self, PyObject *value, void *UNUSED(closure))
+static int FEdgeSmooth_normal_set(BPy_FEdgeSmooth *self, PyObject *value, void * /*closure*/)
{
float v[3];
if (mathutils_array_parse(v, 3, 3, value, "value must be a 3-dimensional vector") == -1) {
@@ -164,16 +166,16 @@ PyDoc_STRVAR(FEdgeSmooth_material_index_doc,
"\n"
":type: int");
-static PyObject *FEdgeSmooth_material_index_get(BPy_FEdgeSmooth *self, void *UNUSED(closure))
+static PyObject *FEdgeSmooth_material_index_get(BPy_FEdgeSmooth *self, void * /*closure*/)
{
return PyLong_FromLong(self->fes->frs_materialIndex());
}
static int FEdgeSmooth_material_index_set(BPy_FEdgeSmooth *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
- unsigned int i = PyLong_AsUnsignedLong(value);
+ uint i = PyLong_AsUnsignedLong(value);
if (PyErr_Occurred()) {
return -1;
}
@@ -186,7 +188,7 @@ PyDoc_STRVAR(FEdgeSmooth_material_doc,
"\n"
":type: :class:`Material`");
-static PyObject *FEdgeSmooth_material_get(BPy_FEdgeSmooth *self, void *UNUSED(closure))
+static PyObject *FEdgeSmooth_material_get(BPy_FEdgeSmooth *self, void * /*closure*/)
{
return BPy_FrsMaterial_from_FrsMaterial(self->fes->frs_material());
}
@@ -196,12 +198,12 @@ PyDoc_STRVAR(FEdgeSmooth_face_mark_doc,
"\n"
":type: bool");
-static PyObject *FEdgeSmooth_face_mark_get(BPy_FEdgeSmooth *self, void *UNUSED(closure))
+static PyObject *FEdgeSmooth_face_mark_get(BPy_FEdgeSmooth *self, void * /*closure*/)
{
return PyBool_from_bool(self->fes->faceMark());
}
-static int FEdgeSmooth_face_mark_set(BPy_FEdgeSmooth *self, PyObject *value, void *UNUSED(closure))
+static int FEdgeSmooth_face_mark_set(BPy_FEdgeSmooth *self, PyObject *value, void * /*closure*/)
{
if (!PyBool_Check(value)) {
return -1;
@@ -237,43 +239,44 @@ static PyGetSetDef BPy_FEdgeSmooth_getseters[] = {
/*-----------------------BPy_FEdgeSmooth type definition ------------------------------*/
PyTypeObject FEdgeSmooth_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "FEdgeSmooth", /* tp_name */
- sizeof(BPy_FEdgeSmooth), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- FEdgeSmooth_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_FEdgeSmooth_getseters, /* tp_getset */
- &FEdge_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)FEdgeSmooth_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "FEdgeSmooth",
+ /*tp_basicsize*/ sizeof(BPy_FEdgeSmooth),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ FEdgeSmooth_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_FEdgeSmooth_getseters,
+ /*tp_base*/ &FEdge_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)FEdgeSmooth_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp
index 80b5cd4ba3b..ba17a92ca0d 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp
@@ -124,7 +124,7 @@ PyDoc_STRVAR(AdjacencyIterator_object_doc,
"\n"
":type: :class:`ViewEdge`");
-static PyObject *AdjacencyIterator_object_get(BPy_AdjacencyIterator *self, void *UNUSED(closure))
+static PyObject *AdjacencyIterator_object_get(BPy_AdjacencyIterator *self, void * /*closure*/)
{
if (self->a_it->isEnd()) {
PyErr_SetString(PyExc_RuntimeError, "iteration has stopped");
@@ -143,8 +143,7 @@ PyDoc_STRVAR(AdjacencyIterator_is_incoming_doc,
"\n"
":type: bool");
-static PyObject *AdjacencyIterator_is_incoming_get(BPy_AdjacencyIterator *self,
- void *UNUSED(closure))
+static PyObject *AdjacencyIterator_is_incoming_get(BPy_AdjacencyIterator *self, void * /*closure*/)
{
if (self->a_it->isEnd()) {
PyErr_SetString(PyExc_RuntimeError, "iteration has stopped");
@@ -170,43 +169,44 @@ static PyGetSetDef BPy_AdjacencyIterator_getseters[] = {
/*-----------------------BPy_AdjacencyIterator type definition ------------------------------*/
PyTypeObject AdjacencyIterator_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "AdjacencyIterator", /* tp_name */
- sizeof(BPy_AdjacencyIterator), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- AdjacencyIterator_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- (getiterfunc)AdjacencyIterator_iter, /* tp_iter */
- (iternextfunc)AdjacencyIterator_iternext, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_AdjacencyIterator_getseters, /* tp_getset */
- &Iterator_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)AdjacencyIterator_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "AdjacencyIterator",
+ /*tp_basicsize*/ sizeof(BPy_AdjacencyIterator),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ AdjacencyIterator_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ (getiterfunc)AdjacencyIterator_iter,
+ /*tp_iternext*/ (iternextfunc)AdjacencyIterator_iternext,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_AdjacencyIterator_getseters,
+ /*tp_base*/ &Iterator_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)AdjacencyIterator_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
index 1960d33ea88..4d35cdabee9 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
@@ -151,43 +151,44 @@ static void ChainPredicateIterator_dealloc(BPy_ChainPredicateIterator *self)
/*-----------------------BPy_ChainPredicateIterator type definition ----------------------------*/
PyTypeObject ChainPredicateIterator_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ChainPredicateIterator", /* tp_name */
- sizeof(BPy_ChainPredicateIterator), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)ChainPredicateIterator_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ChainPredicateIterator_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &ChainingIterator_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ChainPredicateIterator_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ChainPredicateIterator",
+ /*tp_basicsize*/ sizeof(BPy_ChainPredicateIterator),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)ChainPredicateIterator_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ChainPredicateIterator_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &ChainingIterator_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ChainPredicateIterator_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp
index 784ee87cc06..ea4ab4b5a7b 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp
@@ -105,43 +105,44 @@ static int ChainSilhouetteIterator_init(BPy_ChainSilhouetteIterator *self,
/*-----------------------BPy_ChainSilhouetteIterator type definition ----------------------------*/
PyTypeObject ChainSilhouetteIterator_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ChainSilhouetteIterator", /* tp_name */
- sizeof(BPy_ChainSilhouetteIterator), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ChainSilhouetteIterator_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &ChainingIterator_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ChainSilhouetteIterator_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ChainSilhouetteIterator",
+ /*tp_basicsize*/ sizeof(BPy_ChainSilhouetteIterator),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ChainSilhouetteIterator_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &ChainingIterator_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ChainSilhouetteIterator_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp
index b4b3fd2bf1f..3fde8abe1f9 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp
@@ -176,7 +176,7 @@ PyDoc_STRVAR(ChainingIterator_object_doc,
"\n"
":type: :class:`ViewEdge`");
-static PyObject *ChainingIterator_object_get(BPy_ChainingIterator *self, void *UNUSED(closure))
+static PyObject *ChainingIterator_object_get(BPy_ChainingIterator *self, void * /*closure*/)
{
if (self->c_it->isEnd()) {
PyErr_SetString(PyExc_RuntimeError, "iteration has stopped");
@@ -195,8 +195,7 @@ PyDoc_STRVAR(ChainingIterator_next_vertex_doc,
"\n"
":type: :class:`ViewVertex`");
-static PyObject *ChainingIterator_next_vertex_get(BPy_ChainingIterator *self,
- void *UNUSED(closure))
+static PyObject *ChainingIterator_next_vertex_get(BPy_ChainingIterator *self, void * /*closure*/)
{
ViewVertex *v = self->c_it->getVertex();
if (v) {
@@ -212,7 +211,7 @@ PyDoc_STRVAR(ChainingIterator_is_incrementing_doc,
":type: bool");
static PyObject *ChainingIterator_is_incrementing_get(BPy_ChainingIterator *self,
- void *UNUSED(closure))
+ void * /*closure*/)
{
return PyBool_from_bool(self->c_it->isIncrementing());
}
@@ -239,43 +238,44 @@ static PyGetSetDef BPy_ChainingIterator_getseters[] = {
/*-----------------------BPy_ChainingIterator type definition ------------------------------*/
PyTypeObject ChainingIterator_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ChainingIterator", /* tp_name */
- sizeof(BPy_ChainingIterator), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ChainingIterator_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_ChainingIterator_methods, /* tp_methods */
- nullptr, /* tp_members */
- BPy_ChainingIterator_getseters, /* tp_getset */
- &ViewEdgeIterator_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ChainingIterator___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ChainingIterator",
+ /*tp_basicsize*/ sizeof(BPy_ChainingIterator),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ChainingIterator_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_ChainingIterator_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_ChainingIterator_getseters,
+ /*tp_base*/ &ViewEdgeIterator_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ChainingIterator___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp
index e39439dc0b1..180a3e00a9b 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp
@@ -76,7 +76,7 @@ PyDoc_STRVAR(CurvePointIterator_object_doc,
"\n"
":type: :class:`CurvePoint`");
-static PyObject *CurvePointIterator_object_get(BPy_CurvePointIterator *self, void *UNUSED(closure))
+static PyObject *CurvePointIterator_object_get(BPy_CurvePointIterator *self, void * /*closure*/)
{
if (self->cp_it->isEnd()) {
PyErr_SetString(PyExc_RuntimeError, "iteration has stopped");
@@ -90,7 +90,7 @@ PyDoc_STRVAR(CurvePointIterator_t_doc,
"\n"
":type: float");
-static PyObject *CurvePointIterator_t_get(BPy_CurvePointIterator *self, void *UNUSED(closure))
+static PyObject *CurvePointIterator_t_get(BPy_CurvePointIterator *self, void * /*closure*/)
{
return PyFloat_FromDouble(self->cp_it->t());
}
@@ -100,7 +100,7 @@ PyDoc_STRVAR(CurvePointIterator_u_doc,
"\n"
":type: float");
-static PyObject *CurvePointIterator_u_get(BPy_CurvePointIterator *self, void *UNUSED(closure))
+static PyObject *CurvePointIterator_u_get(BPy_CurvePointIterator *self, void * /*closure*/)
{
return PyFloat_FromDouble(self->cp_it->u());
}
@@ -119,43 +119,44 @@ static PyGetSetDef BPy_CurvePointIterator_getseters[] = {
/*-----------------------BPy_CurvePointIterator type definition ------------------------------*/
PyTypeObject CurvePointIterator_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "CurvePointIterator", /* tp_name */
- sizeof(BPy_CurvePointIterator), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- CurvePointIterator_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_CurvePointIterator_getseters, /* tp_getset */
- &Iterator_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)CurvePointIterator_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "CurvePointIterator",
+ /*tp_basicsize*/ sizeof(BPy_CurvePointIterator),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ CurvePointIterator_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_CurvePointIterator_getseters,
+ /*tp_base*/ &Iterator_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)CurvePointIterator_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp
index def217bb278..9d12de9efb7 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp
@@ -133,8 +133,7 @@ PyDoc_STRVAR(Interface0DIterator_object_doc,
"\n"
":type: :class:`Interface0D` or one of its subclasses.");
-static PyObject *Interface0DIterator_object_get(BPy_Interface0DIterator *self,
- void *UNUSED(closure))
+static PyObject *Interface0DIterator_object_get(BPy_Interface0DIterator *self, void * /*closure*/)
{
if (self->if0D_it->isEnd()) {
PyErr_SetString(PyExc_RuntimeError, "iteration has stopped");
@@ -148,7 +147,7 @@ PyDoc_STRVAR(Interface0DIterator_t_doc,
"\n"
":type: float");
-static PyObject *Interface0DIterator_t_get(BPy_Interface0DIterator *self, void *UNUSED(closure))
+static PyObject *Interface0DIterator_t_get(BPy_Interface0DIterator *self, void * /*closure*/)
{
return PyFloat_FromDouble(self->if0D_it->t());
}
@@ -158,7 +157,7 @@ PyDoc_STRVAR(Interface0DIterator_u_doc,
"\n"
":type: float");
-static PyObject *Interface0DIterator_u_get(BPy_Interface0DIterator *self, void *UNUSED(closure))
+static PyObject *Interface0DIterator_u_get(BPy_Interface0DIterator *self, void * /*closure*/)
{
return PyFloat_FromDouble(self->if0D_it->u());
}
@@ -169,8 +168,7 @@ PyDoc_STRVAR(Interface0DIterator_at_last_doc,
"\n"
":type: bool");
-static PyObject *Interface0DIterator_at_last_get(BPy_Interface0DIterator *self,
- void *UNUSED(closure))
+static PyObject *Interface0DIterator_at_last_get(BPy_Interface0DIterator *self, void * /*closure*/)
{
return PyBool_from_bool(self->if0D_it->atLast());
}
@@ -194,43 +192,44 @@ static PyGetSetDef BPy_Interface0DIterator_getseters[] = {
/*-----------------------BPy_Interface0DIterator type definition ------------------------------*/
PyTypeObject Interface0DIterator_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Interface0DIterator", /* tp_name */
- sizeof(BPy_Interface0DIterator), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- Interface0DIterator_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- (getiterfunc)Interface0DIterator_iter, /* tp_iter */
- (iternextfunc)Interface0DIterator_iternext, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_Interface0DIterator_getseters, /* tp_getset */
- &Iterator_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Interface0DIterator_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Interface0DIterator",
+ /*tp_basicsize*/ sizeof(BPy_Interface0DIterator),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ Interface0DIterator_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ (getiterfunc)Interface0DIterator_iter,
+ /*tp_iternext*/ (iternextfunc)Interface0DIterator_iternext,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_Interface0DIterator_getseters,
+ /*tp_base*/ &Iterator_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)Interface0DIterator_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp
index 922f979b4cb..78b8cd07fb4 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp
@@ -99,7 +99,7 @@ PyDoc_STRVAR(SVertexIterator_object_doc,
"\n"
":type: :class:`SVertex`");
-static PyObject *SVertexIterator_object_get(BPy_SVertexIterator *self, void *UNUSED(closure))
+static PyObject *SVertexIterator_object_get(BPy_SVertexIterator *self, void * /*closure*/)
{
if (self->sv_it->isEnd()) {
PyErr_SetString(PyExc_RuntimeError, "iteration has stopped");
@@ -117,7 +117,7 @@ PyDoc_STRVAR(SVertexIterator_t_doc,
"\n"
":type: float");
-static PyObject *SVertexIterator_t_get(BPy_SVertexIterator *self, void *UNUSED(closure))
+static PyObject *SVertexIterator_t_get(BPy_SVertexIterator *self, void * /*closure*/)
{
return PyFloat_FromDouble(self->sv_it->t());
}
@@ -127,7 +127,7 @@ PyDoc_STRVAR(SVertexIterator_u_doc,
"\n"
":type: float");
-static PyObject *SVertexIterator_u_get(BPy_SVertexIterator *self, void *UNUSED(closure))
+static PyObject *SVertexIterator_u_get(BPy_SVertexIterator *self, void * /*closure*/)
{
return PyFloat_FromDouble(self->sv_it->u());
}
@@ -146,43 +146,44 @@ static PyGetSetDef BPy_SVertexIterator_getseters[] = {
/*-----------------------BPy_SVertexIterator type definition ------------------------------*/
PyTypeObject SVertexIterator_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "SVertexIterator", /* tp_name */
- sizeof(BPy_SVertexIterator), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- SVertexIterator_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_SVertexIterator_getseters, /* tp_getset */
- &Iterator_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)SVertexIterator_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "SVertexIterator",
+ /*tp_basicsize*/ sizeof(BPy_SVertexIterator),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ SVertexIterator_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_SVertexIterator_getseters,
+ /*tp_base*/ &Iterator_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)SVertexIterator_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp
index 2a9efcdded4..abbaae19b9e 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp
@@ -206,7 +206,7 @@ PyDoc_STRVAR(StrokeVertexIterator_object_doc,
":type: :class:`StrokeVertex`");
static PyObject *StrokeVertexIterator_object_get(BPy_StrokeVertexIterator *self,
- void *UNUSED(closure))
+ void * /*closure*/)
{
if (self->sv_it->isEnd()) {
PyErr_SetString(PyExc_RuntimeError, "iteration has stopped");
@@ -224,7 +224,7 @@ PyDoc_STRVAR(StrokeVertexIterator_t_doc,
"\n"
":type: float");
-static PyObject *StrokeVertexIterator_t_get(BPy_StrokeVertexIterator *self, void *UNUSED(closure))
+static PyObject *StrokeVertexIterator_t_get(BPy_StrokeVertexIterator *self, void * /*closure*/)
{
return PyFloat_FromDouble(self->sv_it->t());
}
@@ -234,7 +234,7 @@ PyDoc_STRVAR(StrokeVertexIterator_u_doc,
"\n"
":type: float");
-static PyObject *StrokeVertexIterator_u_get(BPy_StrokeVertexIterator *self, void *UNUSED(closure))
+static PyObject *StrokeVertexIterator_u_get(BPy_StrokeVertexIterator *self, void * /*closure*/)
{
return PyFloat_FromDouble(self->sv_it->u());
}
@@ -277,43 +277,44 @@ static PyGetSetDef BPy_StrokeVertexIterator_getseters[] = {
/*-----------------------BPy_StrokeVertexIterator type definition ------------------------------*/
PyTypeObject StrokeVertexIterator_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "StrokeVertexIterator", /* tp_name */
- sizeof(BPy_StrokeVertexIterator), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- StrokeVertexIterator_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- (getiterfunc)StrokeVertexIterator_iter, /* tp_iter */
- (iternextfunc)StrokeVertexIterator_iternext, /* tp_iternext */
- BPy_StrokeVertexIterator_methods, /* tp_methods */
- nullptr, /* tp_members */
- BPy_StrokeVertexIterator_getseters, /* tp_getset */
- &Iterator_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)StrokeVertexIterator_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "StrokeVertexIterator",
+ /*tp_basicsize*/ sizeof(BPy_StrokeVertexIterator),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ StrokeVertexIterator_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ (getiterfunc)StrokeVertexIterator_iter,
+ /*tp_iternext*/ (iternextfunc)StrokeVertexIterator_iternext,
+ /*tp_methods*/ BPy_StrokeVertexIterator_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_StrokeVertexIterator_getseters,
+ /*tp_base*/ &Iterator_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)StrokeVertexIterator_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp
index 634d4d6434b..7d1691d577f 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp
@@ -104,7 +104,7 @@ PyDoc_STRVAR(ViewEdgeIterator_object_doc,
"\n"
":type: :class:`ViewEdge`");
-static PyObject *ViewEdgeIterator_object_get(BPy_ViewEdgeIterator *self, void *UNUSED(closure))
+static PyObject *ViewEdgeIterator_object_get(BPy_ViewEdgeIterator *self, void * /*closure*/)
{
if (!self->ve_it->isEnd()) {
PyErr_SetString(PyExc_RuntimeError, "iteration has stopped");
@@ -122,8 +122,7 @@ PyDoc_STRVAR(ViewEdgeIterator_current_edge_doc,
"\n"
":type: :class:`ViewEdge`");
-static PyObject *ViewEdgeIterator_current_edge_get(BPy_ViewEdgeIterator *self,
- void *UNUSED(closure))
+static PyObject *ViewEdgeIterator_current_edge_get(BPy_ViewEdgeIterator *self, void * /*closure*/)
{
ViewEdge *ve = self->ve_it->getCurrentEdge();
if (ve) {
@@ -134,7 +133,7 @@ static PyObject *ViewEdgeIterator_current_edge_get(BPy_ViewEdgeIterator *self,
static int ViewEdgeIterator_current_edge_set(BPy_ViewEdgeIterator *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
if (!BPy_ViewEdge_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be a ViewEdge");
@@ -153,15 +152,14 @@ PyDoc_STRVAR(ViewEdgeIterator_orientation_doc,
"\n"
":type: bool");
-static PyObject *ViewEdgeIterator_orientation_get(BPy_ViewEdgeIterator *self,
- void *UNUSED(closure))
+static PyObject *ViewEdgeIterator_orientation_get(BPy_ViewEdgeIterator *self, void * /*closure*/)
{
return PyBool_from_bool(self->ve_it->getOrientation());
}
static int ViewEdgeIterator_orientation_set(BPy_ViewEdgeIterator *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
if (!PyBool_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be a boolean");
@@ -176,7 +174,7 @@ PyDoc_STRVAR(ViewEdgeIterator_begin_doc,
"\n"
":type: :class:`ViewEdge`");
-static PyObject *ViewEdgeIterator_begin_get(BPy_ViewEdgeIterator *self, void *UNUSED(closure))
+static PyObject *ViewEdgeIterator_begin_get(BPy_ViewEdgeIterator *self, void * /*closure*/)
{
ViewEdge *ve = self->ve_it->getBegin();
if (ve) {
@@ -187,7 +185,7 @@ static PyObject *ViewEdgeIterator_begin_get(BPy_ViewEdgeIterator *self, void *UN
static int ViewEdgeIterator_begin_set(BPy_ViewEdgeIterator *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
if (!BPy_ViewEdge_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be a ViewEdge");
@@ -224,43 +222,44 @@ static PyGetSetDef BPy_ViewEdgeIterator_getseters[] = {
/*-----------------------BPy_ViewEdgeIterator type definition ------------------------------*/
PyTypeObject ViewEdgeIterator_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ViewEdgeIterator", /* tp_name */
- sizeof(BPy_ViewEdgeIterator), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ViewEdgeIterator_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- BPy_ViewEdgeIterator_methods, /* tp_methods */
- nullptr, /* tp_members */
- BPy_ViewEdgeIterator_getseters, /* tp_getset */
- &Iterator_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ViewEdgeIterator_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ViewEdgeIterator",
+ /*tp_basicsize*/ sizeof(BPy_ViewEdgeIterator),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ViewEdgeIterator_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ BPy_ViewEdgeIterator_methods,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_ViewEdgeIterator_getseters,
+ /*tp_base*/ &Iterator_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ViewEdgeIterator_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp
index 504c43a8542..7dad62818f4 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp
@@ -107,7 +107,7 @@ PyDoc_STRVAR(orientedViewEdgeIterator_object_doc,
":type: (:class:`ViewEdge`, bool)");
static PyObject *orientedViewEdgeIterator_object_get(BPy_orientedViewEdgeIterator *self,
- void *UNUSED(closure))
+ void * /*closure*/)
{
if (self->ove_it->isEnd()) {
PyErr_SetString(PyExc_RuntimeError, "iteration has stopped");
@@ -128,43 +128,44 @@ static PyGetSetDef BPy_orientedViewEdgeIterator_getseters[] = {
/*-----------------------BPy_orientedViewEdgeIterator type definition ---------------------------*/
PyTypeObject orientedViewEdgeIterator_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "orientedViewEdgeIterator", /* tp_name */
- sizeof(BPy_orientedViewEdgeIterator), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- orientedViewEdgeIterator_doc, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- (getiterfunc)orientedViewEdgeIterator_iter, /* tp_iter */
- (iternextfunc)orientedViewEdgeIterator_iternext, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_orientedViewEdgeIterator_getseters, /* tp_getset */
- &Iterator_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)orientedViewEdgeIterator_init, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "orientedViewEdgeIterator",
+ /*tp_basicsize*/ sizeof(BPy_orientedViewEdgeIterator),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ orientedViewEdgeIterator_doc,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ (getiterfunc)orientedViewEdgeIterator_iter,
+ /*tp_iternext*/ (iternextfunc)orientedViewEdgeIterator_iternext,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_orientedViewEdgeIterator_getseters,
+ /*tp_base*/ &Iterator_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)orientedViewEdgeIterator_init,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp
index ce8c62374a6..d54e305c963 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp
@@ -55,43 +55,44 @@ static int BackboneStretcherShader___init__(BPy_BackboneStretcherShader *self,
/*-----------------------BPy_BackboneStretcherShader type definition ----------------------------*/
PyTypeObject BackboneStretcherShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "BackboneStretcherShader", /* tp_name */
- sizeof(BPy_BackboneStretcherShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- BackboneStretcherShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)BackboneStretcherShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "BackboneStretcherShader",
+ /*tp_basicsize*/ sizeof(BPy_BackboneStretcherShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ BackboneStretcherShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)BackboneStretcherShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp
index 3970fdbe511..23de68b3cf4 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp
@@ -55,43 +55,44 @@ static int BezierCurveShader___init__(BPy_BezierCurveShader *self, PyObject *arg
/*-----------------------BPy_BezierCurveShader type definition ------------------------------*/
PyTypeObject BezierCurveShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "BezierCurveShader", /* tp_name */
- sizeof(BPy_BezierCurveShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- BezierCurveShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)BezierCurveShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "BezierCurveShader",
+ /*tp_basicsize*/ sizeof(BPy_BezierCurveShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ BezierCurveShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)BezierCurveShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp
index b1d413bb426..c0dfebfaf37 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp
@@ -75,43 +75,44 @@ static int BlenderTextureShader___init__(BPy_BlenderTextureShader *self,
/*-----------------------BPy_BlenderTextureShader type definition ------------------------------*/
PyTypeObject BlenderTextureShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "BlenderTextureShader", /* tp_name */
- sizeof(BPy_BlenderTextureShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- BlenderTextureShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)BlenderTextureShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "BlenderTextureShader",
+ /*tp_basicsize*/ sizeof(BPy_BlenderTextureShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ BlenderTextureShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)BlenderTextureShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp
index b357baa394c..99e344ee24b 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp
@@ -73,43 +73,44 @@ static int CalligraphicShader___init__(BPy_CalligraphicShader *self,
/*-----------------------BPy_CalligraphicShader type definition ------------------------------*/
PyTypeObject CalligraphicShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "CalligraphicShader", /* tp_name */
- sizeof(BPy_CalligraphicShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- CalligraphicShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)CalligraphicShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "CalligraphicShader",
+ /*tp_basicsize*/ sizeof(BPy_CalligraphicShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ CalligraphicShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)CalligraphicShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp
index 01ed7bc5cf8..c6e0da91d22 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp
@@ -54,43 +54,44 @@ static int ColorNoiseShader___init__(BPy_ColorNoiseShader *self, PyObject *args,
/*-----------------------BPy_ColorNoiseShader type definition ------------------------------*/
PyTypeObject ColorNoiseShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ColorNoiseShader", /* tp_name */
- sizeof(BPy_ColorNoiseShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ColorNoiseShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ColorNoiseShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ColorNoiseShader",
+ /*tp_basicsize*/ sizeof(BPy_ColorNoiseShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ColorNoiseShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ColorNoiseShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp
index e7eff87fb2b..d8cdadfd539 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp
@@ -60,43 +60,44 @@ static int ConstantColorShader___init__(BPy_ConstantColorShader *self,
/*-----------------------BPy_ConstantColorShader type definition ------------------------------*/
PyTypeObject ConstantColorShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ConstantColorShader", /* tp_name */
- sizeof(BPy_ConstantColorShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ConstantColorShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ConstantColorShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ConstantColorShader",
+ /*tp_basicsize*/ sizeof(BPy_ConstantColorShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ConstantColorShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ConstantColorShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp
index e05658e500f..c03a8fe11fe 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp
@@ -54,43 +54,44 @@ static int ConstantThicknessShader___init__(BPy_ConstantThicknessShader *self,
/*-----------------------BPy_ConstantThicknessShader type definition ----------------------------*/
PyTypeObject ConstantThicknessShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ConstantThicknessShader", /* tp_name */
- sizeof(BPy_ConstantThicknessShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ConstantThicknessShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ConstantThicknessShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ConstantThicknessShader",
+ /*tp_basicsize*/ sizeof(BPy_ConstantThicknessShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ConstantThicknessShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ConstantThicknessShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp
index 88ce8099669..bf86e283161 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp
@@ -60,43 +60,44 @@ static int ConstrainedIncreasingThicknessShader___init__(
/*-----------------------BPy_ConstrainedIncreasingThicknessShader type definition ---------------*/
PyTypeObject ConstrainedIncreasingThicknessShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ConstrainedIncreasingThicknessShader", /* tp_name */
- sizeof(BPy_ConstrainedIncreasingThicknessShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ConstrainedIncreasingThicknessShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ConstrainedIncreasingThicknessShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ConstrainedIncreasingThicknessShader",
+ /*tp_basicsize*/ sizeof(BPy_ConstrainedIncreasingThicknessShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ConstrainedIncreasingThicknessShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ConstrainedIncreasingThicknessShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp
index 08c5e70d11a..25bfa182043 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp
@@ -62,43 +62,44 @@ static int GuidingLinesShader___init__(BPy_GuidingLinesShader *self,
/*-----------------------BPy_GuidingLinesShader type definition ------------------------------*/
PyTypeObject GuidingLinesShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GuidingLinesShader", /* tp_name */
- sizeof(BPy_GuidingLinesShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GuidingLinesShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GuidingLinesShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GuidingLinesShader",
+ /*tp_basicsize*/ sizeof(BPy_GuidingLinesShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GuidingLinesShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GuidingLinesShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp
index 33f2eb41548..d8f8ae84543 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp
@@ -82,43 +82,44 @@ static int IncreasingColorShader___init__(BPy_IncreasingColorShader *self,
/*-----------------------BPy_IncreasingColorShader type definition ------------------------------*/
PyTypeObject IncreasingColorShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "IncreasingColorShader", /* tp_name */
- sizeof(BPy_IncreasingColorShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- IncreasingColorShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)IncreasingColorShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "IncreasingColorShader",
+ /*tp_basicsize*/ sizeof(BPy_IncreasingColorShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ IncreasingColorShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)IncreasingColorShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp
index 9e489f24c88..7bc1f73d9e8 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp
@@ -60,43 +60,44 @@ static int IncreasingThicknessShader___init__(BPy_IncreasingThicknessShader *sel
/*-----------------------BPy_IncreasingThicknessShader type definition --------------------------*/
PyTypeObject IncreasingThicknessShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "IncreasingThicknessShader", /* tp_name */
- sizeof(BPy_IncreasingThicknessShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- IncreasingThicknessShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)IncreasingThicknessShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "IncreasingThicknessShader",
+ /*tp_basicsize*/ sizeof(BPy_IncreasingThicknessShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ IncreasingThicknessShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)IncreasingThicknessShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp
index 25021696694..9afdf786e5c 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp
@@ -61,43 +61,44 @@ static int PolygonalizationShader___init__(BPy_PolygonalizationShader *self,
/*-----------------------BPy_PolygonalizationShader type definition -----------------------------*/
PyTypeObject PolygonalizationShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "PolygonalizationShader", /* tp_name */
- sizeof(BPy_PolygonalizationShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- PolygonalizationShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)PolygonalizationShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "PolygonalizationShader",
+ /*tp_basicsize*/ sizeof(BPy_PolygonalizationShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ PolygonalizationShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)PolygonalizationShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp
index 9bf322cd1f8..6ee3f0130b8 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp
@@ -52,43 +52,44 @@ static int SamplingShader___init__(BPy_SamplingShader *self, PyObject *args, PyO
/*-----------------------BPy_SamplingShader type definition ------------------------------*/
PyTypeObject SamplingShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "SamplingShader", /* tp_name */
- sizeof(BPy_SamplingShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- SamplingShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)SamplingShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "SamplingShader",
+ /*tp_basicsize*/ sizeof(BPy_SamplingShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ SamplingShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)SamplingShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp
index 1a3cba74f18..b07a1f26a3e 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp
@@ -84,43 +84,44 @@ static int SmoothingShader___init__(BPy_SmoothingShader *self, PyObject *args, P
/*-----------------------BPy_SmoothingShader type definition ------------------------------*/
PyTypeObject SmoothingShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "SmoothingShader", /* tp_name */
- sizeof(BPy_SmoothingShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- SmoothingShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)SmoothingShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "SmoothingShader",
+ /*tp_basicsize*/ sizeof(BPy_SmoothingShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ SmoothingShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)SmoothingShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp
index 26f0dcadf86..04ea15d7b47 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp
@@ -78,43 +78,44 @@ static int SpatialNoiseShader___init__(BPy_SpatialNoiseShader *self,
/*-----------------------BPy_SpatialNoiseShader type definition ------------------------------*/
PyTypeObject SpatialNoiseShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "SpatialNoiseShader", /* tp_name */
- sizeof(BPy_SpatialNoiseShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- SpatialNoiseShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)SpatialNoiseShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "SpatialNoiseShader",
+ /*tp_basicsize*/ sizeof(BPy_SpatialNoiseShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ SpatialNoiseShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)SpatialNoiseShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp
index a79bee0b120..ec6e7e69b49 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp
@@ -54,43 +54,44 @@ static int StrokeTextureStepShader___init__(BPy_StrokeTextureStepShader *self,
/*-----------------------BPy_StrokeTextureStepShader type definition ----------------------------*/
PyTypeObject StrokeTextureStepShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "StrokeTextureStepShader", /* tp_name */
- sizeof(BPy_StrokeTextureStepShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- StrokeTextureStepShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)StrokeTextureStepShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "StrokeTextureStepShader",
+ /*tp_basicsize*/ sizeof(BPy_StrokeTextureStepShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ StrokeTextureStepShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)StrokeTextureStepShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp
index 24bcbff1990..08731659cc4 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp
@@ -56,43 +56,44 @@ static int ThicknessNoiseShader___init__(BPy_ThicknessNoiseShader *self,
/*-----------------------BPy_ThicknessNoiseShader type definition ------------------------------*/
PyTypeObject ThicknessNoiseShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ThicknessNoiseShader", /* tp_name */
- sizeof(BPy_ThicknessNoiseShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ThicknessNoiseShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ThicknessNoiseShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ThicknessNoiseShader",
+ /*tp_basicsize*/ sizeof(BPy_ThicknessNoiseShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ThicknessNoiseShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ThicknessNoiseShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp
index e36c99713e8..81f1aca792d 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp
@@ -53,43 +53,44 @@ static int TipRemoverShader___init__(BPy_TipRemoverShader *self, PyObject *args,
/*-----------------------BPy_TipRemoverShader type definition ------------------------------*/
PyTypeObject TipRemoverShader_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "TipRemoverShader", /* tp_name */
- sizeof(BPy_TipRemoverShader), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- TipRemoverShader___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &StrokeShader_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)TipRemoverShader___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "TipRemoverShader",
+ /*tp_basicsize*/ sizeof(BPy_TipRemoverShader),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ TipRemoverShader___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &StrokeShader_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)TipRemoverShader___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp
index da4fdfe5095..a8be9722cff 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp
@@ -171,43 +171,44 @@ static PyObject *UnaryFunction0DDouble___call__(BPy_UnaryFunction0DDouble *self,
/*-----------------------BPy_UnaryFunction0DDouble type definition ------------------------------*/
PyTypeObject UnaryFunction0DDouble_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction0DDouble", /* tp_name */
- sizeof(BPy_UnaryFunction0DDouble), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction0DDouble___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction0DDouble___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction0DDouble___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction0DDouble___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction0DDouble___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction0DDouble",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction0DDouble),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction0DDouble___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction0DDouble___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction0DDouble___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction0DDouble___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction0DDouble___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp
index d6c095c9f0a..b1a1cf816d4 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp
@@ -110,43 +110,44 @@ static PyObject *UnaryFunction0DEdgeNature___call__(BPy_UnaryFunction0DEdgeNatur
/*-----------------------BPy_UnaryFunction0DEdgeNature type definition --------------------------*/
PyTypeObject UnaryFunction0DEdgeNature_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction0DEdgeNature", /* tp_name */
- sizeof(BPy_UnaryFunction0DEdgeNature), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction0DEdgeNature___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction0DEdgeNature___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction0DEdgeNature___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction0DEdgeNature___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction0DEdgeNature___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction0DEdgeNature",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction0DEdgeNature),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction0DEdgeNature___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction0DEdgeNature___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction0DEdgeNature___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction0DEdgeNature___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction0DEdgeNature___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp
index 20511cb0d4b..588959667c5 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp
@@ -147,43 +147,44 @@ static PyObject *UnaryFunction0DFloat___call__(BPy_UnaryFunction0DFloat *self,
/*-----------------------BPy_UnaryFunction0DFloat type definition ------------------------------*/
PyTypeObject UnaryFunction0DFloat_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction0DFloat", /* tp_name */
- sizeof(BPy_UnaryFunction0DFloat), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction0DFloat___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction0DFloat___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction0DFloat___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction0DFloat___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction0DFloat___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction0DFloat",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction0DFloat),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction0DFloat___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction0DFloat___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction0DFloat___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction0DFloat___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction0DFloat___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp
index 61a7693d605..f0a62995c6d 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp
@@ -106,43 +106,44 @@ static PyObject *UnaryFunction0DId___call__(BPy_UnaryFunction0DId *self,
/*-----------------------BPy_UnaryFunction0DId type definition ------------------------------*/
PyTypeObject UnaryFunction0DId_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction0DId", /* tp_name */
- sizeof(BPy_UnaryFunction0DId), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction0DId___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction0DId___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction0DId___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction0DId___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction0DId___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction0DId",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction0DId),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction0DId___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction0DId___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction0DId___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction0DId___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction0DId___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp
index 224f1ad7229..0c8294ff8dc 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp
@@ -109,43 +109,44 @@ static PyObject *UnaryFunction0DMaterial___call__(BPy_UnaryFunction0DMaterial *s
/*-----------------------BPy_UnaryFunction0DMaterial type definition ----------------------------*/
PyTypeObject UnaryFunction0DMaterial_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction0DMaterial", /* tp_name */
- sizeof(BPy_UnaryFunction0DMaterial), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction0DMaterial___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction0DMaterial___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction0DMaterial___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction0DMaterial___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction0DMaterial___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction0DMaterial",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction0DMaterial),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction0DMaterial___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction0DMaterial___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction0DMaterial___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction0DMaterial___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction0DMaterial___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp
index be1b9f42ce4..c6e7fed4424 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp
@@ -11,6 +11,8 @@
#include "UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.h"
+#include "BLI_sys_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -64,7 +66,7 @@ static int UnaryFunction0DUnsigned___init__(BPy_UnaryFunction0DUnsigned *self,
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", (char **)kwlist)) {
return -1;
}
- self->uf0D_unsigned = new UnaryFunction0D<unsigned int>();
+ self->uf0D_unsigned = new UnaryFunction0D<uint>();
self->uf0D_unsigned->py_uf0D = (PyObject *)self;
return 0;
}
@@ -93,7 +95,7 @@ static PyObject *UnaryFunction0DUnsigned___call__(BPy_UnaryFunction0DUnsigned *s
return nullptr;
}
- if (typeid(*(self->uf0D_unsigned)) == typeid(UnaryFunction0D<unsigned int>)) {
+ if (typeid(*(self->uf0D_unsigned)) == typeid(UnaryFunction0D<uint>)) {
PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden");
return nullptr;
}
@@ -110,43 +112,44 @@ static PyObject *UnaryFunction0DUnsigned___call__(BPy_UnaryFunction0DUnsigned *s
/*-----------------------BPy_UnaryFunction0DUnsigned type definition ----------------------------*/
PyTypeObject UnaryFunction0DUnsigned_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction0DUnsigned", /* tp_name */
- sizeof(BPy_UnaryFunction0DUnsigned), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction0DUnsigned___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction0DUnsigned___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction0DUnsigned___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction0DUnsigned___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction0DUnsigned___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction0DUnsigned",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction0DUnsigned),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction0DUnsigned___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction0DUnsigned___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction0DUnsigned___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction0DUnsigned___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction0DUnsigned___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp
index c13dbc85eee..fda4536b252 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp
@@ -115,43 +115,44 @@ static PyObject *UnaryFunction0DVec2f___call__(BPy_UnaryFunction0DVec2f *self,
/*-----------------------BPy_UnaryFunction0DVec2f type definition ------------------------------*/
PyTypeObject UnaryFunction0DVec2f_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction0DVec2f", /* tp_name */
- sizeof(BPy_UnaryFunction0DVec2f), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction0DVec2f___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction0DVec2f___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction0DVec2f___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction0DVec2f___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction0DVec2f___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction0DVec2f",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction0DVec2f),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction0DVec2f___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction0DVec2f___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction0DVec2f___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction0DVec2f___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction0DVec2f___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp
index d373ae7fe03..5409bd94789 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp
@@ -108,43 +108,44 @@ static PyObject *UnaryFunction0DVec3f___call__(BPy_UnaryFunction0DVec3f *self,
/*-----------------------BPy_UnaryFunction0DVec3f type definition ------------------------------*/
PyTypeObject UnaryFunction0DVec3f_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction0DVec3f", /* tp_name */
- sizeof(BPy_UnaryFunction0DVec3f), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction0DVec3f___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction0DVec3f___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction0DVec3f___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction0DVec3f___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction0DVec3f___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction0DVec3f",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction0DVec3f),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction0DVec3f___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction0DVec3f___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction0DVec3f___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction0DVec3f___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction0DVec3f___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp
index 6d17f6debdf..73049f8e0c2 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp
@@ -11,6 +11,8 @@
#include "UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.h"
+#include "BLI_sys_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -106,9 +108,9 @@ static PyObject *UnaryFunction0DVectorViewShape___call__(BPy_UnaryFunction0DVect
return nullptr;
}
- const unsigned int list_len = self->uf0D_vectorviewshape->result.size();
+ const uint list_len = self->uf0D_vectorviewshape->result.size();
PyObject *list = PyList_New(list_len);
- for (unsigned int i = 0; i < list_len; i++) {
+ for (uint i = 0; i < list_len; i++) {
ViewShape *v = self->uf0D_vectorviewshape->result[i];
PyList_SET_ITEM(list, i, v ? BPy_ViewShape_from_ViewShape(*v) : (Py_INCREF(Py_None), Py_None));
}
@@ -119,43 +121,44 @@ static PyObject *UnaryFunction0DVectorViewShape___call__(BPy_UnaryFunction0DVect
/*-----------------------BPy_UnaryFunction0DVectorViewShape type definition ---------------------*/
PyTypeObject UnaryFunction0DVectorViewShape_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction0DVectorViewShape", /* tp_name */
- sizeof(BPy_UnaryFunction0DVectorViewShape), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction0DVectorViewShape___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction0DVectorViewShape___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction0DVectorViewShape___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction0DVectorViewShape___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction0DVectorViewShape___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction0DVectorViewShape",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction0DVectorViewShape),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction0DVectorViewShape___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction0DVectorViewShape___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction0DVectorViewShape___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction0DVectorViewShape___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction0DVectorViewShape___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp
index 06a08cc02f5..319087b5092 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp
@@ -117,43 +117,44 @@ static PyObject *UnaryFunction0DViewShape___call__(BPy_UnaryFunction0DViewShape
/*-----------------------BPy_UnaryFunction0DViewShape type definition ---------------------------*/
PyTypeObject UnaryFunction0DViewShape_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction0DViewShape", /* tp_name */
- sizeof(BPy_UnaryFunction0DViewShape), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction0DViewShape___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction0DViewShape___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction0DViewShape___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction0DViewShape___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction0DViewShape___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction0DViewShape",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction0DViewShape),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction0DViewShape___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction0DViewShape___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction0DViewShape___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction0DViewShape___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction0DViewShape___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.cpp
index deea7008002..55a02890066 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.cpp
@@ -58,43 +58,44 @@ static int ShapeIdF0D___init__(BPy_ShapeIdF0D *self, PyObject *args, PyObject *k
/*-----------------------BPy_ShapeIdF0D type definition ------------------------------*/
PyTypeObject ShapeIdF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ShapeIdF0D", /* tp_name */
- sizeof(BPy_ShapeIdF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ShapeIdF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DId_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ShapeIdF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ShapeIdF0D",
+ /*tp_basicsize*/ sizeof(BPy_ShapeIdF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ShapeIdF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DId_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ShapeIdF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.cpp
index 49273ddf132..5abd54a48ad 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.cpp
@@ -61,43 +61,44 @@ static int MaterialF0D___init__(BPy_MaterialF0D *self, PyObject *args, PyObject
/*-----------------------BPy_MaterialF0D type definition ------------------------------*/
PyTypeObject MaterialF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "MaterialF0D", /* tp_name */
- sizeof(BPy_MaterialF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- MaterialF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DMaterial_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)MaterialF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "MaterialF0D",
+ /*tp_basicsize*/ sizeof(BPy_MaterialF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ MaterialF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DMaterial_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)MaterialF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.cpp
index 66a93f961e7..750e5253793 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.cpp
@@ -52,43 +52,44 @@ static int CurveNatureF0D___init__(BPy_CurveNatureF0D *self, PyObject *args, PyO
/*-----------------------BPy_CurveNatureF0D type definition ------------------------------*/
PyTypeObject CurveNatureF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "CurveNatureF0D", /* tp_name */
- sizeof(BPy_CurveNatureF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- CurveNatureF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DEdgeNature_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)CurveNatureF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "CurveNatureF0D",
+ /*tp_basicsize*/ sizeof(BPy_CurveNatureF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ CurveNatureF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DEdgeNature_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)CurveNatureF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.cpp
index 0b5c818de9d..ba4f1e9bc37 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.cpp
@@ -54,43 +54,44 @@ static int Normal2DF0D___init__(BPy_Normal2DF0D *self, PyObject *args, PyObject
/*-----------------------BPy_Normal2DF0D type definition ------------------------------*/
PyTypeObject Normal2DF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Normal2DF0D", /* tp_name */
- sizeof(BPy_Normal2DF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- Normal2DF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DVec2f_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Normal2DF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Normal2DF0D",
+ /*tp_basicsize*/ sizeof(BPy_Normal2DF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ Normal2DF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DVec2f_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)Normal2DF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.cpp
index 7792cbb2495..9d6d1e31da3 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.cpp
@@ -56,43 +56,44 @@ static int VertexOrientation2DF0D___init__(BPy_VertexOrientation2DF0D *self,
/*-----------------------BPy_VertexOrientation2DF0D type definition -----------------------------*/
PyTypeObject VertexOrientation2DF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "VertexOrientation2DF0D", /* tp_name */
- sizeof(BPy_VertexOrientation2DF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- VertexOrientation2DF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DVec2f_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)VertexOrientation2DF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "VertexOrientation2DF0D",
+ /*tp_basicsize*/ sizeof(BPy_VertexOrientation2DF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ VertexOrientation2DF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DVec2f_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)VertexOrientation2DF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.cpp
index 9a0aa3ae4a8..95cf14eafdf 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.cpp
@@ -56,43 +56,44 @@ static int VertexOrientation3DF0D___init__(BPy_VertexOrientation3DF0D *self,
/*-----------------------BPy_VertexOrientation3DF0D type definition -----------------------------*/
PyTypeObject VertexOrientation3DF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "VertexOrientation3DF0D", /* tp_name */
- sizeof(BPy_VertexOrientation3DF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- VertexOrientation3DF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DVec3f_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)VertexOrientation3DF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "VertexOrientation3DF0D",
+ /*tp_basicsize*/ sizeof(BPy_VertexOrientation3DF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ VertexOrientation3DF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DVec3f_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)VertexOrientation3DF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.cpp
index 7a7e13dbb90..92644c21bde 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.cpp
@@ -51,43 +51,44 @@ static int GetOccludeeF0D___init__(BPy_GetOccludeeF0D *self, PyObject *args, PyO
/*-----------------------BPy_GetOccludeeF0D type definition ------------------------------*/
PyTypeObject GetOccludeeF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetOccludeeF0D", /* tp_name */
- sizeof(BPy_GetOccludeeF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetOccludeeF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DViewShape_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetOccludeeF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetOccludeeF0D",
+ /*tp_basicsize*/ sizeof(BPy_GetOccludeeF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetOccludeeF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DViewShape_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetOccludeeF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.cpp
index 6b9c2355c6c..38cc90f366a 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.cpp
@@ -51,43 +51,44 @@ static int GetShapeF0D___init__(BPy_GetShapeF0D *self, PyObject *args, PyObject
/*-----------------------BPy_GetShapeF0D type definition ------------------------------*/
PyTypeObject GetShapeF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetShapeF0D", /* tp_name */
- sizeof(BPy_GetShapeF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetShapeF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DViewShape_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetShapeF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetShapeF0D",
+ /*tp_basicsize*/ sizeof(BPy_GetShapeF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetShapeF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DViewShape_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetShapeF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.cpp
index a596e13c465..884d7da3f77 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.cpp
@@ -56,43 +56,44 @@ static int Curvature2DAngleF0D___init__(BPy_Curvature2DAngleF0D *self,
/*-----------------------BPy_Curvature2DAngleF0D type definition ------------------------------*/
PyTypeObject Curvature2DAngleF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Curvature2DAngleF0D", /* tp_name */
- sizeof(BPy_Curvature2DAngleF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- Curvature2DAngleF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Curvature2DAngleF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Curvature2DAngleF0D",
+ /*tp_basicsize*/ sizeof(BPy_Curvature2DAngleF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ Curvature2DAngleF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)Curvature2DAngleF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.cpp
index 25385d05b7b..3668c81c454 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.cpp
@@ -61,43 +61,44 @@ static int DensityF0D___init__(BPy_DensityF0D *self, PyObject *args, PyObject *k
/*-----------------------BPy_DensityF0D type definition ------------------------------*/
PyTypeObject DensityF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "DensityF0D", /* tp_name */
- sizeof(BPy_DensityF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- DensityF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)DensityF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "DensityF0D",
+ /*tp_basicsize*/ sizeof(BPy_DensityF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ DensityF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)DensityF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.cpp
index c3be379e32d..2c3b78ffbc9 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.cpp
@@ -51,43 +51,44 @@ static int GetProjectedXF0D___init__(BPy_GetProjectedXF0D *self, PyObject *args,
/*-----------------------BPy_GetProjectedXF0D type definition ------------------------------*/
PyTypeObject GetProjectedXF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetProjectedXF0D", /* tp_name */
- sizeof(BPy_GetProjectedXF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetProjectedXF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetProjectedXF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetProjectedXF0D",
+ /*tp_basicsize*/ sizeof(BPy_GetProjectedXF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetProjectedXF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetProjectedXF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.cpp
index b6ce4bc9bcd..47d3ee34fb0 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.cpp
@@ -51,43 +51,44 @@ static int GetProjectedYF0D___init__(BPy_GetProjectedYF0D *self, PyObject *args,
/*-----------------------BPy_GetProjectedYF0D type definition ------------------------------*/
PyTypeObject GetProjectedYF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetProjectedYF0D", /* tp_name */
- sizeof(BPy_GetProjectedYF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetProjectedYF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetProjectedYF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetProjectedYF0D",
+ /*tp_basicsize*/ sizeof(BPy_GetProjectedYF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetProjectedYF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetProjectedYF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.cpp
index 4bba4e23665..8978624eea0 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.cpp
@@ -51,43 +51,44 @@ static int GetProjectedZF0D___init__(BPy_GetProjectedZF0D *self, PyObject *args,
/*-----------------------BPy_GetProjectedZF0D type definition ------------------------------*/
PyTypeObject GetProjectedZF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetProjectedZF0D", /* tp_name */
- sizeof(BPy_GetProjectedZF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetProjectedZF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetProjectedZF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetProjectedZF0D",
+ /*tp_basicsize*/ sizeof(BPy_GetProjectedZF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetProjectedZF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetProjectedZF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.cpp
index 3ed3cf7f7f3..39bc12a1b2a 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.cpp
@@ -51,43 +51,44 @@ static int GetXF0D___init__(BPy_GetXF0D *self, PyObject *args, PyObject *kwds)
/*-----------------------BPy_GetXF0D type definition ------------------------------*/
PyTypeObject GetXF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetXF0D", /* tp_name */
- sizeof(BPy_GetXF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetXF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetXF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetXF0D",
+ /*tp_basicsize*/ sizeof(BPy_GetXF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetXF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetXF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.cpp
index fd8238e4726..5c0435cc3a4 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.cpp
@@ -51,43 +51,44 @@ static int GetYF0D___init__(BPy_GetYF0D *self, PyObject *args, PyObject *kwds)
/*-----------------------BPy_GetYF0D type definition ------------------------------*/
PyTypeObject GetYF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetYF0D", /* tp_name */
- sizeof(BPy_GetYF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetYF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetYF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetYF0D",
+ /*tp_basicsize*/ sizeof(BPy_GetYF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetYF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetYF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.cpp
index 8c44c9bf7dc..fc569cac044 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.cpp
@@ -51,43 +51,44 @@ static int GetZF0D___init__(BPy_GetZF0D *self, PyObject *args, PyObject *kwds)
/*-----------------------BPy_GetZF0D type definition ------------------------------*/
PyTypeObject GetZF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetZF0D", /* tp_name */
- sizeof(BPy_GetZF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetZF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetZF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetZF0D",
+ /*tp_basicsize*/ sizeof(BPy_GetZF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetZF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetZF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.cpp
index 0dc9f9b4b21..93f1ee6cd13 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.cpp
@@ -59,43 +59,44 @@ static int LocalAverageDepthF0D___init__(BPy_LocalAverageDepthF0D *self,
/*-----------------------BPy_LocalAverageDepthF0D type definition ------------------------------*/
PyTypeObject LocalAverageDepthF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "LocalAverageDepthF0D", /* tp_name */
- sizeof(BPy_LocalAverageDepthF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- LocalAverageDepthF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)LocalAverageDepthF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "LocalAverageDepthF0D",
+ /*tp_basicsize*/ sizeof(BPy_LocalAverageDepthF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ LocalAverageDepthF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)LocalAverageDepthF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.cpp
index 395da54356d..019340204a5 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.cpp
@@ -56,43 +56,44 @@ static int ZDiscontinuityF0D___init__(BPy_ZDiscontinuityF0D *self, PyObject *arg
/*-----------------------BPy_ZDiscontinuityF0D type definition ------------------------------*/
PyTypeObject ZDiscontinuityF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ZDiscontinuityF0D", /* tp_name */
- sizeof(BPy_ZDiscontinuityF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ZDiscontinuityF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ZDiscontinuityF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ZDiscontinuityF0D",
+ /*tp_basicsize*/ sizeof(BPy_ZDiscontinuityF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ZDiscontinuityF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ZDiscontinuityF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.cpp
index fffea12e0da..c9ad1b20b47 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.cpp
@@ -54,43 +54,44 @@ static int GetCurvilinearAbscissaF0D___init__(BPy_GetCurvilinearAbscissaF0D *sel
/*-----------------------BPy_GetCurvilinearAbscissaF0D type definition --------------------------*/
PyTypeObject GetCurvilinearAbscissaF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetCurvilinearAbscissaF0D", /* tp_name */
- sizeof(BPy_GetCurvilinearAbscissaF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetCurvilinearAbscissaF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DFloat_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetCurvilinearAbscissaF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetCurvilinearAbscissaF0D",
+ /*tp_basicsize*/ sizeof(BPy_GetCurvilinearAbscissaF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetCurvilinearAbscissaF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DFloat_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetCurvilinearAbscissaF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.cpp
index 4354d651f27..1420e41d90a 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.cpp
@@ -49,44 +49,45 @@ static int GetParameterF0D___init__(BPy_GetParameterF0D *self, PyObject *args, P
}
/*-----------------------BPy_GetParameterF0D type definition ------------------------------*/
+
PyTypeObject GetParameterF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetParameterF0D", /* tp_name */
- sizeof(BPy_GetParameterF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetParameterF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DFloat_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetParameterF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ /*tp_name*/ PyVarObject_HEAD_INIT(nullptr, 0) "GetParameterF0D",
+ /*tp_basicsize*/ sizeof(BPy_GetParameterF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetParameterF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DFloat_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetParameterF0D___init__,
+ /*tp_alloc*/ nullptr,
+ nullptr, /*tp_new*/
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.cpp
index 671844fb6b3..1fce16fc53a 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.cpp
@@ -59,43 +59,44 @@ static int GetViewMapGradientNormF0D___init__(BPy_GetViewMapGradientNormF0D *sel
/*-----------------------BPy_GetViewMapGradientNormF0D type definition --------------------------*/
PyTypeObject GetViewMapGradientNormF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetViewMapGradientNormF0D", /* tp_name */
- sizeof(BPy_GetViewMapGradientNormF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetViewMapGradientNormF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DFloat_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetViewMapGradientNormF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetViewMapGradientNormF0D",
+ /*tp_basicsize*/ sizeof(BPy_GetViewMapGradientNormF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetViewMapGradientNormF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DFloat_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetViewMapGradientNormF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.cpp
index ed1902cbd8b..b65032d650f 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.cpp
@@ -57,43 +57,44 @@ static int ReadCompleteViewMapPixelF0D___init__(BPy_ReadCompleteViewMapPixelF0D
/*-----------------------BPy_ReadCompleteViewMapPixelF0D type definition ------------------------*/
PyTypeObject ReadCompleteViewMapPixelF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ReadCompleteViewMapPixelF0D", /* tp_name */
- sizeof(BPy_ReadCompleteViewMapPixelF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ReadCompleteViewMapPixelF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DFloat_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ReadCompleteViewMapPixelF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ReadCompleteViewMapPixelF0D",
+ /*tp_basicsize*/ sizeof(BPy_ReadCompleteViewMapPixelF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ReadCompleteViewMapPixelF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DFloat_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ReadCompleteViewMapPixelF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.cpp
index cd60d99593a..ff934bc4a50 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.cpp
@@ -58,43 +58,44 @@ static int ReadMapPixelF0D___init__(BPy_ReadMapPixelF0D *self, PyObject *args, P
/*-----------------------BPy_ReadMapPixelF0D type definition ------------------------------*/
PyTypeObject ReadMapPixelF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ReadMapPixelF0D", /* tp_name */
- sizeof(BPy_ReadMapPixelF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ReadMapPixelF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DFloat_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ReadMapPixelF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ReadMapPixelF0D",
+ /*tp_basicsize*/ sizeof(BPy_ReadMapPixelF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ReadMapPixelF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DFloat_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ReadMapPixelF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.cpp
index f0435ea1294..262dc90a2d7 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.cpp
@@ -8,6 +8,8 @@
#include "../../../stroke/AdvancedFunctions0D.h"
+#include "BLI_sys_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -47,7 +49,7 @@ static int ReadSteerableViewMapPixelF0D___init__(BPy_ReadSteerableViewMapPixelF0
PyObject *kwds)
{
static const char *kwlist[] = {"orientation", "level", nullptr};
- unsigned int u;
+ uint u;
int i;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "Ii", (char **)kwlist, &u, &i)) {
@@ -61,43 +63,44 @@ static int ReadSteerableViewMapPixelF0D___init__(BPy_ReadSteerableViewMapPixelF0
/*-----------------------BPy_ReadSteerableViewMapPixelF0D type definition -----------------------*/
PyTypeObject ReadSteerableViewMapPixelF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ReadSteerableViewMapPixelF0D", /* tp_name */
- sizeof(BPy_ReadSteerableViewMapPixelF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ReadSteerableViewMapPixelF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DFloat_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ReadSteerableViewMapPixelF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ReadSteerableViewMapPixelF0D",
+ /*tp_basicsize*/ sizeof(BPy_ReadSteerableViewMapPixelF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ReadSteerableViewMapPixelF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DFloat_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ReadSteerableViewMapPixelF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.cpp
index 2c4300a8059..658345bed1b 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.cpp
@@ -59,43 +59,44 @@ static int QuantitativeInvisibilityF0D___init__(BPy_QuantitativeInvisibilityF0D
/*-----------------------BPy_QuantitativeInvisibilityF0D type definition ------------------------*/
PyTypeObject QuantitativeInvisibilityF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "QuantitativeInvisibilityF0D", /* tp_name */
- sizeof(BPy_QuantitativeInvisibilityF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- QuantitativeInvisibilityF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DUnsigned_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)QuantitativeInvisibilityF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "QuantitativeInvisibilityF0D",
+ /*tp_basicsize*/ sizeof(BPy_QuantitativeInvisibilityF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ QuantitativeInvisibilityF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DUnsigned_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)QuantitativeInvisibilityF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.cpp
index 797708daa9b..e91528a42a2 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.cpp
@@ -52,43 +52,44 @@ static int GetOccludersF0D___init__(BPy_GetOccludersF0D *self, PyObject *args, P
/*-----------------------BPy_GetOccludersF0D type definition ------------------------------*/
PyTypeObject GetOccludersF0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetOccludersF0D", /* tp_name */
- sizeof(BPy_GetOccludersF0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetOccludersF0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction0DVectorViewShape_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetOccludersF0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetOccludersF0D",
+ /*tp_basicsize*/ sizeof(BPy_GetOccludersF0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetOccludersF0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction0DVectorViewShape_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetOccludersF0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp
index 4e4e4d31385..2adaeee6e9f 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp
@@ -223,14 +223,14 @@ PyDoc_STRVAR(integration_type_doc,
"\n"
":type: :class:`IntegrationType`");
-static PyObject *integration_type_get(BPy_UnaryFunction1DDouble *self, void *UNUSED(closure))
+static PyObject *integration_type_get(BPy_UnaryFunction1DDouble *self, void * /*closure*/)
{
return BPy_IntegrationType_from_IntegrationType(self->uf1D_double->getIntegrationType());
}
static int integration_type_set(BPy_UnaryFunction1DDouble *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
if (!BPy_IntegrationType_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an IntegrationType");
@@ -252,43 +252,44 @@ static PyGetSetDef BPy_UnaryFunction1DDouble_getseters[] = {
/*-----------------------BPy_UnaryFunction1DDouble type definition ------------------------------*/
PyTypeObject UnaryFunction1DDouble_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction1DDouble", /* tp_name */
- sizeof(BPy_UnaryFunction1DDouble), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction1DDouble___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction1DDouble___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction1DDouble___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction1DDouble___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_UnaryFunction1DDouble_getseters, /* tp_getset */
- &UnaryFunction1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction1DDouble___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction1DDouble",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction1DDouble),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction1DDouble___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction1DDouble___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction1DDouble___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction1DDouble___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_UnaryFunction1DDouble_getseters,
+ /*tp_base*/ &UnaryFunction1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction1DDouble___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp
index ce654de8bc0..03e6417a316 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp
@@ -130,14 +130,14 @@ PyDoc_STRVAR(integration_type_doc,
"\n"
":type: :class:`IntegrationType`");
-static PyObject *integration_type_get(BPy_UnaryFunction1DEdgeNature *self, void *UNUSED(closure))
+static PyObject *integration_type_get(BPy_UnaryFunction1DEdgeNature *self, void * /*closure*/)
{
return BPy_IntegrationType_from_IntegrationType(self->uf1D_edgenature->getIntegrationType());
}
static int integration_type_set(BPy_UnaryFunction1DEdgeNature *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
if (!BPy_IntegrationType_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an IntegrationType");
@@ -159,43 +159,44 @@ static PyGetSetDef BPy_UnaryFunction1DEdgeNature_getseters[] = {
/*-----------------------BPy_UnaryFunction1DEdgeNature type definition --------------------------*/
PyTypeObject UnaryFunction1DEdgeNature_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction1DEdgeNature", /* tp_name */
- sizeof(BPy_UnaryFunction1DEdgeNature), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction1DEdgeNature___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction1DEdgeNature___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction1DEdgeNature___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction1DEdgeNature___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_UnaryFunction1DEdgeNature_getseters, /* tp_getset */
- &UnaryFunction1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction1DEdgeNature___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction1DEdgeNature",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction1DEdgeNature),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction1DEdgeNature___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction1DEdgeNature___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction1DEdgeNature___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction1DEdgeNature___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_UnaryFunction1DEdgeNature_getseters,
+ /*tp_base*/ &UnaryFunction1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction1DEdgeNature___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp
index 83958dbb3d7..e843313e63f 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp
@@ -119,14 +119,14 @@ PyDoc_STRVAR(integration_type_doc,
"\n"
":type: :class:`IntegrationType`");
-static PyObject *integration_type_get(BPy_UnaryFunction1DFloat *self, void *UNUSED(closure))
+static PyObject *integration_type_get(BPy_UnaryFunction1DFloat *self, void * /*closure*/)
{
return BPy_IntegrationType_from_IntegrationType(self->uf1D_float->getIntegrationType());
}
static int integration_type_set(BPy_UnaryFunction1DFloat *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
if (!BPy_IntegrationType_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an IntegrationType");
@@ -148,43 +148,44 @@ static PyGetSetDef BPy_UnaryFunction1DFloat_getseters[] = {
/*-----------------------BPy_UnaryFunction1DFloat type definition ------------------------------*/
PyTypeObject UnaryFunction1DFloat_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction1DFloat", /* tp_name */
- sizeof(BPy_UnaryFunction1DFloat), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction1DFloat___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction1DFloat___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction1DFloat___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction1DFloat___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_UnaryFunction1DFloat_getseters, /* tp_getset */
- &UnaryFunction1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction1DFloat___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction1DFloat",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction1DFloat),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction1DFloat___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction1DFloat___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction1DFloat___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction1DFloat___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_UnaryFunction1DFloat_getseters,
+ /*tp_base*/ &UnaryFunction1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction1DFloat___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp
index e9023d90b42..a029dec4e29 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp
@@ -12,6 +12,8 @@
#include "UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.h"
+#include "BLI_sys_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -74,11 +76,10 @@ static int UnaryFunction1DUnsigned___init__(BPy_UnaryFunction1DUnsigned *self,
}
if (!obj) {
- self->uf1D_unsigned = new UnaryFunction1D<unsigned int>();
+ self->uf1D_unsigned = new UnaryFunction1D<uint>();
}
else {
- self->uf1D_unsigned = new UnaryFunction1D<unsigned int>(
- IntegrationType_from_BPy_IntegrationType(obj));
+ self->uf1D_unsigned = new UnaryFunction1D<uint>(IntegrationType_from_BPy_IntegrationType(obj));
}
self->uf1D_unsigned->py_uf1D = (PyObject *)self;
@@ -109,7 +110,7 @@ static PyObject *UnaryFunction1DUnsigned___call__(BPy_UnaryFunction1DUnsigned *s
return nullptr;
}
- if (typeid(*(self->uf1D_unsigned)) == typeid(UnaryFunction1D<unsigned int>)) {
+ if (typeid(*(self->uf1D_unsigned)) == typeid(UnaryFunction1D<uint>)) {
PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden");
return nullptr;
}
@@ -130,14 +131,14 @@ PyDoc_STRVAR(integration_type_doc,
"\n"
":type: :class:`IntegrationType`");
-static PyObject *integration_type_get(BPy_UnaryFunction1DUnsigned *self, void *UNUSED(closure))
+static PyObject *integration_type_get(BPy_UnaryFunction1DUnsigned *self, void * /*closure*/)
{
return BPy_IntegrationType_from_IntegrationType(self->uf1D_unsigned->getIntegrationType());
}
static int integration_type_set(BPy_UnaryFunction1DUnsigned *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
if (!BPy_IntegrationType_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an IntegrationType");
@@ -159,43 +160,44 @@ static PyGetSetDef BPy_UnaryFunction1DUnsigned_getseters[] = {
/*-----------------------BPy_UnaryFunction1DUnsigned type definition ----------------------------*/
PyTypeObject UnaryFunction1DUnsigned_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction1DUnsigned", /* tp_name */
- sizeof(BPy_UnaryFunction1DUnsigned), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction1DUnsigned___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction1DUnsigned___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction1DUnsigned___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction1DUnsigned___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_UnaryFunction1DUnsigned_getseters, /* tp_getset */
- &UnaryFunction1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction1DUnsigned___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction1DUnsigned",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction1DUnsigned),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction1DUnsigned___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction1DUnsigned___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction1DUnsigned___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction1DUnsigned___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_UnaryFunction1DUnsigned_getseters,
+ /*tp_base*/ &UnaryFunction1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction1DUnsigned___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp
index c7bd84b0d18..b2272d0ecbc 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp
@@ -134,14 +134,14 @@ PyDoc_STRVAR(integration_type_doc,
"\n"
":type: :class:`IntegrationType`");
-static PyObject *integration_type_get(BPy_UnaryFunction1DVec2f *self, void *UNUSED(closure))
+static PyObject *integration_type_get(BPy_UnaryFunction1DVec2f *self, void * /*closure*/)
{
return BPy_IntegrationType_from_IntegrationType(self->uf1D_vec2f->getIntegrationType());
}
static int integration_type_set(BPy_UnaryFunction1DVec2f *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
if (!BPy_IntegrationType_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an IntegrationType");
@@ -163,43 +163,44 @@ static PyGetSetDef BPy_UnaryFunction1DVec2f_getseters[] = {
/*-----------------------BPy_UnaryFunction1DVec2f type definition ------------------------------*/
PyTypeObject UnaryFunction1DVec2f_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction1DVec2f", /* tp_name */
- sizeof(BPy_UnaryFunction1DVec2f), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction1DVec2f___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction1DVec2f___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction1DVec2f___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction1DVec2f___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_UnaryFunction1DVec2f_getseters, /* tp_getset */
- &UnaryFunction1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction1DVec2f___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction1DVec2f",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction1DVec2f),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction1DVec2f___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction1DVec2f___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction1DVec2f___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction1DVec2f___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_UnaryFunction1DVec2f_getseters,
+ /*tp_base*/ &UnaryFunction1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction1DVec2f___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp
index 1eced4cd9f1..59745628a52 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp
@@ -127,14 +127,14 @@ PyDoc_STRVAR(integration_type_doc,
"\n"
":type: :class:`IntegrationType`");
-static PyObject *integration_type_get(BPy_UnaryFunction1DVec3f *self, void *UNUSED(closure))
+static PyObject *integration_type_get(BPy_UnaryFunction1DVec3f *self, void * /*closure*/)
{
return BPy_IntegrationType_from_IntegrationType(self->uf1D_vec3f->getIntegrationType());
}
static int integration_type_set(BPy_UnaryFunction1DVec3f *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
if (!BPy_IntegrationType_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an IntegrationType");
@@ -156,43 +156,44 @@ static PyGetSetDef BPy_UnaryFunction1DVec3f_getseters[] = {
/*-----------------------BPy_UnaryFunction1DVec3f type definition ------------------------------*/
PyTypeObject UnaryFunction1DVec3f_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction1DVec3f", /* tp_name */
- sizeof(BPy_UnaryFunction1DVec3f), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction1DVec3f___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction1DVec3f___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction1DVec3f___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction1DVec3f___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_UnaryFunction1DVec3f_getseters, /* tp_getset */
- &UnaryFunction1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction1DVec3f___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction1DVec3f",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction1DVec3f),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction1DVec3f___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction1DVec3f___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction1DVec3f___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction1DVec3f___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_UnaryFunction1DVec3f_getseters,
+ /*tp_base*/ &UnaryFunction1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction1DVec3f___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp
index df504b1cdaa..4579fe7682d 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp
@@ -14,6 +14,8 @@
#include "UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.h"
#include "UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.h"
+#include "BLI_sys_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -136,9 +138,9 @@ static PyObject *UnaryFunction1DVectorViewShape___call__(BPy_UnaryFunction1DVect
return nullptr;
}
- const unsigned int list_len = self->uf1D_vectorviewshape->result.size();
+ const uint list_len = self->uf1D_vectorviewshape->result.size();
PyObject *list = PyList_New(list_len);
- for (unsigned int i = 0; i < list_len; i++) {
+ for (uint i = 0; i < list_len; i++) {
ViewShape *v = self->uf1D_vectorviewshape->result[i];
PyList_SET_ITEM(list, i, v ? BPy_ViewShape_from_ViewShape(*v) : (Py_INCREF(Py_None), Py_None));
}
@@ -153,8 +155,7 @@ PyDoc_STRVAR(integration_type_doc,
"\n"
":type: :class:`IntegrationType`");
-static PyObject *integration_type_get(BPy_UnaryFunction1DVectorViewShape *self,
- void *UNUSED(closure))
+static PyObject *integration_type_get(BPy_UnaryFunction1DVectorViewShape *self, void * /*closure*/)
{
return BPy_IntegrationType_from_IntegrationType(
self->uf1D_vectorviewshape->getIntegrationType());
@@ -162,7 +163,7 @@ static PyObject *integration_type_get(BPy_UnaryFunction1DVectorViewShape *self,
static int integration_type_set(BPy_UnaryFunction1DVectorViewShape *self,
PyObject *value,
- void *UNUSED(closure))
+ void * /*closure*/)
{
if (!BPy_IntegrationType_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an IntegrationType");
@@ -184,43 +185,44 @@ static PyGetSetDef BPy_UnaryFunction1DVectorViewShape_getseters[] = {
/*-----------------------BPy_UnaryFunction1DVectorViewShape type definition ---------------------*/
PyTypeObject UnaryFunction1DVectorViewShape_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction1DVectorViewShape", /* tp_name */
- sizeof(BPy_UnaryFunction1DVectorViewShape), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction1DVectorViewShape___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction1DVectorViewShape___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction1DVectorViewShape___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction1DVectorViewShape___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_UnaryFunction1DVectorViewShape_getseters, /* tp_getset */
- &UnaryFunction1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction1DVectorViewShape___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction1DVectorViewShape",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction1DVectorViewShape),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction1DVectorViewShape___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction1DVectorViewShape___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction1DVectorViewShape___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction1DVectorViewShape___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_UnaryFunction1DVectorViewShape_getseters,
+ /*tp_base*/ &UnaryFunction1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction1DVectorViewShape___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp
index 84152b8141f..2b4f1c148fc 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp
@@ -142,14 +142,12 @@ PyDoc_STRVAR(integration_type_doc,
"\n"
":type: :class:`IntegrationType`");
-static PyObject *integration_type_get(BPy_UnaryFunction1DVoid *self, void *UNUSED(closure))
+static PyObject *integration_type_get(BPy_UnaryFunction1DVoid *self, void * /*closure*/)
{
return BPy_IntegrationType_from_IntegrationType(self->uf1D_void->getIntegrationType());
}
-static int integration_type_set(BPy_UnaryFunction1DVoid *self,
- PyObject *value,
- void *UNUSED(closure))
+static int integration_type_set(BPy_UnaryFunction1DVoid *self, PyObject *value, void * /*closure*/)
{
if (!BPy_IntegrationType_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an IntegrationType");
@@ -171,43 +169,44 @@ static PyGetSetDef BPy_UnaryFunction1DVoid_getseters[] = {
/*-----------------------BPy_UnaryFunction1DVoid type definition ------------------------------*/
PyTypeObject UnaryFunction1DVoid_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "UnaryFunction1DVoid", /* tp_name */
- sizeof(BPy_UnaryFunction1DVoid), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)UnaryFunction1DVoid___dealloc__, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- (reprfunc)UnaryFunction1DVoid___repr__, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- (ternaryfunc)UnaryFunction1DVoid___call__, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- UnaryFunction1DVoid___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- BPy_UnaryFunction1DVoid_getseters, /* tp_getset */
- &UnaryFunction1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)UnaryFunction1DVoid___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "UnaryFunction1DVoid",
+ /*tp_basicsize*/ sizeof(BPy_UnaryFunction1DVoid),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)UnaryFunction1DVoid___dealloc__,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ (reprfunc)UnaryFunction1DVoid___repr__,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ (ternaryfunc)UnaryFunction1DVoid___call__,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ UnaryFunction1DVoid___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ BPy_UnaryFunction1DVoid_getseters,
+ /*tp_base*/ &UnaryFunction1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)UnaryFunction1DVoid___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.cpp
index ca51824acf0..901a309f9be 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.cpp
@@ -64,43 +64,44 @@ static int CurveNatureF1D___init__(BPy_CurveNatureF1D *self, PyObject *args, PyO
/*-----------------------BPy_CurveNatureF1D type definition ------------------------------*/
PyTypeObject CurveNatureF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "CurveNatureF1D", /* tp_name */
- sizeof(BPy_CurveNatureF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- CurveNatureF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DEdgeNature_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)CurveNatureF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "CurveNatureF1D",
+ /*tp_basicsize*/ sizeof(BPy_CurveNatureF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ CurveNatureF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DEdgeNature_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)CurveNatureF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.cpp
index 3da7d8fa0a2..aa0e6be7b27 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.cpp
@@ -58,43 +58,44 @@ static int Normal2DF1D___init__(BPy_Normal2DF1D *self, PyObject *args, PyObject
/*-----------------------BPy_Normal2DF1D type definition ------------------------------*/
PyTypeObject Normal2DF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Normal2DF1D", /* tp_name */
- sizeof(BPy_Normal2DF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- Normal2DF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DVec2f_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Normal2DF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Normal2DF1D",
+ /*tp_basicsize*/ sizeof(BPy_Normal2DF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ Normal2DF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DVec2f_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)Normal2DF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.cpp
index 64613c1aa09..0a9b7aa506b 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.cpp
@@ -58,43 +58,44 @@ static int Orientation2DF1D___init__(BPy_Orientation2DF1D *self, PyObject *args,
/*-----------------------BPy_Orientation2DF1D type definition ------------------------------*/
PyTypeObject Orientation2DF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Orientation2DF1D", /* tp_name */
- sizeof(BPy_Orientation2DF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- Orientation2DF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DVec2f_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Orientation2DF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Orientation2DF1D",
+ /*tp_basicsize*/ sizeof(BPy_Orientation2DF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ Orientation2DF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DVec2f_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)Orientation2DF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.cpp
index f840bf928bf..09b421768a7 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.cpp
@@ -58,43 +58,44 @@ static int Orientation3DF1D___init__(BPy_Orientation3DF1D *self, PyObject *args,
/*-----------------------BPy_Orientation3DF1D type definition ------------------------------*/
PyTypeObject Orientation3DF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Orientation3DF1D", /* tp_name */
- sizeof(BPy_Orientation3DF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- Orientation3DF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DVec3f_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Orientation3DF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Orientation3DF1D",
+ /*tp_basicsize*/ sizeof(BPy_Orientation3DF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ Orientation3DF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DVec3f_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)Orientation3DF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.cpp
index 704fdc14d5b..0e1817b7aaa 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.cpp
@@ -59,43 +59,44 @@ static int Curvature2DAngleF1D___init__(BPy_Curvature2DAngleF1D *self,
/*-----------------------BPy_Curvature2DAngleF1D type definition ------------------------------*/
PyTypeObject Curvature2DAngleF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "Curvature2DAngleF1D", /* tp_name */
- sizeof(BPy_Curvature2DAngleF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- Curvature2DAngleF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Curvature2DAngleF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "Curvature2DAngleF1D",
+ /*tp_basicsize*/ sizeof(BPy_Curvature2DAngleF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ Curvature2DAngleF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)Curvature2DAngleF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.cpp
index cfc75a6a60c..34c222cae28 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.cpp
@@ -72,43 +72,44 @@ static int DensityF1D___init__(BPy_DensityF1D *self, PyObject *args, PyObject *k
/*-----------------------BPy_DensityF1D type definition ------------------------------*/
PyTypeObject DensityF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "DensityF1D", /* tp_name */
- sizeof(BPy_DensityF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- DensityF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)DensityF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "DensityF1D",
+ /*tp_basicsize*/ sizeof(BPy_DensityF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ DensityF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)DensityF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.cpp
index d5e6e51fb7f..42ab6926557 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.cpp
@@ -76,43 +76,44 @@ static int GetCompleteViewMapDensityF1D___init__(BPy_GetCompleteViewMapDensityF1
/*-----------------------BPy_GetCompleteViewMapDensityF1D type definition -----------------------*/
PyTypeObject GetCompleteViewMapDensityF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetCompleteViewMapDensityF1D", /* tp_name */
- sizeof(BPy_GetCompleteViewMapDensityF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetCompleteViewMapDensityF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetCompleteViewMapDensityF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetCompleteViewMapDensityF1D",
+ /*tp_basicsize*/ sizeof(BPy_GetCompleteViewMapDensityF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetCompleteViewMapDensityF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetCompleteViewMapDensityF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.cpp
index c4d4aedc954..dcd5d2189bf 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.cpp
@@ -10,6 +10,8 @@
#include "../../BPy_Convert.h"
#include "../../BPy_IntegrationType.h"
+#include "BLI_sys_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -67,7 +69,7 @@ static int GetDirectionalViewMapDensityF1D___init__(BPy_GetDirectionalViewMapDen
{
static const char *kwlist[] = {"orientation", "level", "integration_type", "sampling", nullptr};
PyObject *obj = nullptr;
- unsigned int u1, u2;
+ uint u1, u2;
float f = 2.0;
if (!PyArg_ParseTupleAndKeywords(
@@ -83,43 +85,44 @@ static int GetDirectionalViewMapDensityF1D___init__(BPy_GetDirectionalViewMapDen
/*-----------------------BPy_GetDirectionalViewMapDensityF1D type definition --------------------*/
PyTypeObject GetDirectionalViewMapDensityF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetDirectionalViewMapDensityF1D", /* tp_name */
- sizeof(BPy_GetDirectionalViewMapDensityF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetDirectionalViewMapDensityF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetDirectionalViewMapDensityF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetDirectionalViewMapDensityF1D",
+ /*tp_basicsize*/ sizeof(BPy_GetDirectionalViewMapDensityF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetDirectionalViewMapDensityF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetDirectionalViewMapDensityF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.cpp
index 2a1749f69dc..4c3a95098af 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.cpp
@@ -58,43 +58,44 @@ static int GetProjectedXF1D___init__(BPy_GetProjectedXF1D *self, PyObject *args,
/*-----------------------BPy_GetProjectedXF1D type definition ------------------------------*/
PyTypeObject GetProjectedXF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetProjectedXF1D", /* tp_name */
- sizeof(BPy_GetProjectedXF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetProjectedXF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetProjectedXF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetProjectedXF1D",
+ /*tp_basicsize*/ sizeof(BPy_GetProjectedXF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetProjectedXF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetProjectedXF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.cpp
index 9960702ccdb..840d7c12920 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.cpp
@@ -58,43 +58,44 @@ static int GetProjectedYF1D___init__(BPy_GetProjectedYF1D *self, PyObject *args,
/*-----------------------BPy_GetProjectedYF1D type definition ------------------------------*/
PyTypeObject GetProjectedYF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetProjectedYF1D", /* tp_name */
- sizeof(BPy_GetProjectedYF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetProjectedYF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetProjectedYF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetProjectedYF1D",
+ /*tp_basicsize*/ sizeof(BPy_GetProjectedYF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetProjectedYF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetProjectedYF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.cpp
index d5b02bb7666..dd2d8577d37 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.cpp
@@ -58,43 +58,44 @@ static int GetProjectedZF1D___init__(BPy_GetProjectedZF1D *self, PyObject *args,
/*-----------------------BPy_GetProjectedZF1D type definition ------------------------------*/
PyTypeObject GetProjectedZF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetProjectedZF1D", /* tp_name */
- sizeof(BPy_GetProjectedZF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetProjectedZF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetProjectedZF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetProjectedZF1D",
+ /*tp_basicsize*/ sizeof(BPy_GetProjectedZF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetProjectedZF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetProjectedZF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.cpp
index 6a133751d8a..ad1a65f9f81 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.cpp
@@ -73,43 +73,44 @@ static int GetSteerableViewMapDensityF1D___init__(BPy_GetSteerableViewMapDensity
/*-----------------------BPy_GetSteerableViewMapDensityF1D type definition ----------------------*/
PyTypeObject GetSteerableViewMapDensityF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetSteerableViewMapDensityF1D", /* tp_name */
- sizeof(BPy_GetSteerableViewMapDensityF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetSteerableViewMapDensityF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetSteerableViewMapDensityF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetSteerableViewMapDensityF1D",
+ /*tp_basicsize*/ sizeof(BPy_GetSteerableViewMapDensityF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetSteerableViewMapDensityF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetSteerableViewMapDensityF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.cpp
index 0ce50a9d29c..90912e32747 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.cpp
@@ -73,43 +73,44 @@ static int GetViewMapGradientNormF1D___init__(BPy_GetViewMapGradientNormF1D *sel
/*-----------------------BPy_GetViewMapGradientNormF1D type definition --------------------------*/
PyTypeObject GetViewMapGradientNormF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetViewMapGradientNormF1D", /* tp_name */
- sizeof(BPy_GetViewMapGradientNormF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetViewMapGradientNormF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetViewMapGradientNormF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetViewMapGradientNormF1D",
+ /*tp_basicsize*/ sizeof(BPy_GetViewMapGradientNormF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetViewMapGradientNormF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetViewMapGradientNormF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.cpp
index b9213b7af82..d56d297e9dc 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.cpp
@@ -58,43 +58,44 @@ static int GetXF1D___init__(BPy_GetXF1D *self, PyObject *args, PyObject *kwds)
/*-----------------------BPy_GetXF1D type definition ------------------------------*/
PyTypeObject GetXF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetXF1D", /* tp_name */
- sizeof(BPy_GetXF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetXF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetXF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetXF1D",
+ /*tp_basicsize*/ sizeof(BPy_GetXF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetXF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetXF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.cpp
index 2e1a7139796..eeff432e50e 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.cpp
@@ -57,43 +57,44 @@ static int GetYF1D___init__(BPy_GetYF1D *self, PyObject *args, PyObject *kwds)
/*-----------------------BPy_GetYF1D type definition ------------------------------*/
PyTypeObject GetYF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetYF1D", /* tp_name */
- sizeof(BPy_GetYF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetYF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetYF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetYF1D",
+ /*tp_basicsize*/ sizeof(BPy_GetYF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetYF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetYF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.cpp
index a7d468f4afd..1a1e72e03ec 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.cpp
@@ -58,43 +58,44 @@ static int GetZF1D___init__(BPy_GetZF1D *self, PyObject *args, PyObject *kwds)
/*-----------------------BPy_GetZF1D type definition ------------------------------*/
PyTypeObject GetZF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetZF1D", /* tp_name */
- sizeof(BPy_GetZF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetZF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetZF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetZF1D",
+ /*tp_basicsize*/ sizeof(BPy_GetZF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetZF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetZF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.cpp
index 6ae5500b15f..df77dd26b38 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.cpp
@@ -68,43 +68,44 @@ static int LocalAverageDepthF1D___init__(BPy_LocalAverageDepthF1D *self,
/*-----------------------BPy_LocalAverageDepthF1D type definition ------------------------------*/
PyTypeObject LocalAverageDepthF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "LocalAverageDepthF1D", /* tp_name */
- sizeof(BPy_LocalAverageDepthF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- LocalAverageDepthF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)LocalAverageDepthF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "LocalAverageDepthF1D",
+ /*tp_basicsize*/ sizeof(BPy_LocalAverageDepthF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ LocalAverageDepthF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)LocalAverageDepthF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.cpp
index ed510c25aba..4da68e657b5 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.cpp
@@ -62,43 +62,44 @@ static int ZDiscontinuityF1D___init__(BPy_ZDiscontinuityF1D *self, PyObject *arg
/*-----------------------BPy_ZDiscontinuityF1D type definition ------------------------------*/
PyTypeObject ZDiscontinuityF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ZDiscontinuityF1D", /* tp_name */
- sizeof(BPy_ZDiscontinuityF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ZDiscontinuityF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DDouble_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ZDiscontinuityF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ZDiscontinuityF1D",
+ /*tp_basicsize*/ sizeof(BPy_ZDiscontinuityF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ZDiscontinuityF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DDouble_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ZDiscontinuityF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.cpp
index 7dc3daa2911..3318482b20d 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.cpp
@@ -64,43 +64,44 @@ static int QuantitativeInvisibilityF1D___init__(BPy_QuantitativeInvisibilityF1D
/*-----------------------BPy_QuantitativeInvisibilityF1D type definition ------------------------*/
PyTypeObject QuantitativeInvisibilityF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "QuantitativeInvisibilityF1D", /* tp_name */
- sizeof(BPy_QuantitativeInvisibilityF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- QuantitativeInvisibilityF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DUnsigned_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)QuantitativeInvisibilityF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "QuantitativeInvisibilityF1D",
+ /*tp_basicsize*/ sizeof(BPy_QuantitativeInvisibilityF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ QuantitativeInvisibilityF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DUnsigned_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)QuantitativeInvisibilityF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.cpp
index c765e521eb5..014a8decea1 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.cpp
@@ -51,43 +51,44 @@ static int GetOccludeeF1D___init__(BPy_GetOccludeeF1D *self, PyObject *args, PyO
/*-----------------------BPy_GetOccludeeF1D type definition ------------------------------*/
PyTypeObject GetOccludeeF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetOccludeeF1D", /* tp_name */
- sizeof(BPy_GetOccludeeF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetOccludeeF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DVectorViewShape_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetOccludeeF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetOccludeeF1D",
+ /*tp_basicsize*/ sizeof(BPy_GetOccludeeF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetOccludeeF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DVectorViewShape_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetOccludeeF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.cpp
index 02284d145f0..4423fd788fa 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.cpp
@@ -51,43 +51,44 @@ static int GetOccludersF1D___init__(BPy_GetOccludersF1D *self, PyObject *args, P
/*-----------------------BPy_GetOccludersF1D type definition ------------------------------*/
PyTypeObject GetOccludersF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetOccludersF1D", /* tp_name */
- sizeof(BPy_GetOccludersF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetOccludersF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DVectorViewShape_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetOccludersF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetOccludersF1D",
+ /*tp_basicsize*/ sizeof(BPy_GetOccludersF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetOccludersF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DVectorViewShape_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetOccludersF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.cpp
index 039b7631711..34dad93df0c 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.cpp
@@ -51,43 +51,44 @@ static int GetShapeF1D___init__(BPy_GetShapeF1D *self, PyObject *args, PyObject
/*-----------------------BPy_GetShapeF1D type definition ------------------------------*/
PyTypeObject GetShapeF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "GetShapeF1D", /* tp_name */
- sizeof(BPy_GetShapeF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- GetShapeF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DVectorViewShape_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)GetShapeF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "GetShapeF1D",
+ /*tp_basicsize*/ sizeof(BPy_GetShapeF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ GetShapeF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DVectorViewShape_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)GetShapeF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.cpp
index 0f752a56b43..529f604f989 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.cpp
@@ -51,43 +51,44 @@ static int ChainingTimeStampF1D___init__(BPy_ChainingTimeStampF1D *self,
/*-----------------------BPy_ChainingTimeStampF1D type definition ------------------------------*/
PyTypeObject ChainingTimeStampF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ChainingTimeStampF1D", /* tp_name */
- sizeof(BPy_ChainingTimeStampF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ChainingTimeStampF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DVoid_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ChainingTimeStampF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ChainingTimeStampF1D",
+ /*tp_basicsize*/ sizeof(BPy_ChainingTimeStampF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ChainingTimeStampF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DVoid_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ChainingTimeStampF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.cpp
index 5477e3e246b..99549b2c754 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.cpp
@@ -51,43 +51,44 @@ static int IncrementChainingTimeStampF1D___init__(BPy_IncrementChainingTimeStamp
/*-----------------------BPy_IncrementChainingTimeStampF1D type definition ----------------------*/
PyTypeObject IncrementChainingTimeStampF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "IncrementChainingTimeStampF1D", /* tp_name */
- sizeof(BPy_IncrementChainingTimeStampF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- IncrementChainingTimeStampF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DVoid_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)IncrementChainingTimeStampF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "IncrementChainingTimeStampF1D",
+ /*tp_basicsize*/ sizeof(BPy_IncrementChainingTimeStampF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ IncrementChainingTimeStampF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DVoid_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)IncrementChainingTimeStampF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.cpp
index 6f5253c4e83..d812d274bfe 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.cpp
@@ -49,43 +49,44 @@ static int TimeStampF1D___init__(BPy_TimeStampF1D *self, PyObject *args, PyObjec
/*-----------------------BPy_TimeStampF1D type definition ------------------------------*/
PyTypeObject TimeStampF1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "TimeStampF1D", /* tp_name */
- sizeof(BPy_TimeStampF1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- TimeStampF1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryFunction1DVoid_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)TimeStampF1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "TimeStampF1D",
+ /*tp_basicsize*/ sizeof(BPy_TimeStampF1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ TimeStampF1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryFunction1DVoid_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)TimeStampF1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp
index d86c7216d03..c55f570743b 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp
@@ -42,43 +42,44 @@ static int FalseUP0D___init__(BPy_FalseUP0D *self, PyObject *args, PyObject *kwd
/*-----------------------BPy_FalseUP0D type definition ------------------------------*/
PyTypeObject FalseUP0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "FalseUP0D", /* tp_name */
- sizeof(BPy_FalseUP0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- FalseUP0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryPredicate0D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)FalseUP0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "FalseUP0D",
+ /*tp_basicsize*/ sizeof(BPy_FalseUP0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ FalseUP0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryPredicate0D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)FalseUP0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp
index 76f8ae01769..0af4d7f35eb 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp
@@ -42,43 +42,43 @@ static int TrueUP0D___init__(BPy_TrueUP0D *self, PyObject *args, PyObject *kwds)
/*-----------------------BPy_TrueUP0D type definition ------------------------------*/
PyTypeObject TrueUP0D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "TrueUP0D", /* tp_name */
- sizeof(BPy_TrueUP0D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- TrueUP0D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryPredicate0D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)TrueUP0D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ /*tp_name*/ PyVarObject_HEAD_INIT(nullptr, 0) "TrueUP0D",
+ /*tp_basicsize*/ sizeof(BPy_TrueUP0D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ TrueUP0D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryPredicate0D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)TrueUP0D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp
index 81b7f3990b1..ffea29804e7 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp
@@ -43,43 +43,44 @@ static int ContourUP1D___init__(BPy_ContourUP1D *self, PyObject *args, PyObject
/*-----------------------BPy_ContourUP1D type definition ------------------------------*/
PyTypeObject ContourUP1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ContourUP1D", /* tp_name */
- sizeof(BPy_ContourUP1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ContourUP1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryPredicate1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ContourUP1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ContourUP1D",
+ /*tp_basicsize*/ sizeof(BPy_ContourUP1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ContourUP1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryPredicate1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ContourUP1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp
index e376acd2d84..c133c742c0c 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp
@@ -59,43 +59,44 @@ static int DensityLowerThanUP1D___init__(BPy_DensityLowerThanUP1D *self,
/*-----------------------BPy_DensityLowerThanUP1D type definition ------------------------------*/
PyTypeObject DensityLowerThanUP1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "DensityLowerThanUP1D", /* tp_name */
- sizeof(BPy_DensityLowerThanUP1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- DensityLowerThanUP1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryPredicate1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)DensityLowerThanUP1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "DensityLowerThanUP1D",
+ /*tp_basicsize*/ sizeof(BPy_DensityLowerThanUP1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ DensityLowerThanUP1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryPredicate1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)DensityLowerThanUP1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp
index 2f22e435017..13a74bd2f41 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp
@@ -6,6 +6,8 @@
#include "BPy_EqualToChainingTimeStampUP1D.h"
+#include "BLI_sys_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -42,7 +44,7 @@ static int EqualToChainingTimeStampUP1D___init__(BPy_EqualToChainingTimeStampUP1
PyObject *kwds)
{
static const char *kwlist[] = {"ts", nullptr};
- unsigned u;
+ uint u;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "I", (char **)kwlist, &u)) {
return -1;
@@ -54,43 +56,44 @@ static int EqualToChainingTimeStampUP1D___init__(BPy_EqualToChainingTimeStampUP1
/*-----------------------BPy_EqualToChainingTimeStampUP1D type definition -----------------------*/
PyTypeObject EqualToChainingTimeStampUP1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "EqualToChainingTimeStampUP1D", /* tp_name */
- sizeof(BPy_EqualToChainingTimeStampUP1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- EqualToChainingTimeStampUP1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryPredicate1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)EqualToChainingTimeStampUP1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "EqualToChainingTimeStampUP1D",
+ /*tp_basicsize*/ sizeof(BPy_EqualToChainingTimeStampUP1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ EqualToChainingTimeStampUP1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryPredicate1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)EqualToChainingTimeStampUP1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp
index dd7a3f3baa3..ac4cd389fd4 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp
@@ -6,6 +6,8 @@
#include "BPy_EqualToTimeStampUP1D.h"
+#include "BLI_sys_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -41,7 +43,7 @@ static int EqualToTimeStampUP1D___init__(BPy_EqualToTimeStampUP1D *self,
PyObject *kwds)
{
static const char *kwlist[] = {"ts", nullptr};
- unsigned u;
+ uint u;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "I", (char **)kwlist, &u)) {
return -1;
@@ -53,43 +55,44 @@ static int EqualToTimeStampUP1D___init__(BPy_EqualToTimeStampUP1D *self,
/*-----------------------BPy_EqualToTimeStampUP1D type definition ------------------------------*/
PyTypeObject EqualToTimeStampUP1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "EqualToTimeStampUP1D", /* tp_name */
- sizeof(BPy_EqualToTimeStampUP1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- EqualToTimeStampUP1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryPredicate1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)EqualToTimeStampUP1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "EqualToTimeStampUP1D",
+ /*tp_basicsize*/ sizeof(BPy_EqualToTimeStampUP1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ EqualToTimeStampUP1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryPredicate1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)EqualToTimeStampUP1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp
index ab8153e6fea..7c1b8685771 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp
@@ -47,43 +47,44 @@ static int ExternalContourUP1D___init__(BPy_ExternalContourUP1D *self,
/*-----------------------BPy_ExternalContourUP1D type definition ------------------------------*/
PyTypeObject ExternalContourUP1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ExternalContourUP1D", /* tp_name */
- sizeof(BPy_ExternalContourUP1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ExternalContourUP1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryPredicate1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ExternalContourUP1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ExternalContourUP1D",
+ /*tp_basicsize*/ sizeof(BPy_ExternalContourUP1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ExternalContourUP1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryPredicate1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ExternalContourUP1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp
index 4d1730040d7..506c724023c 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp
@@ -42,43 +42,44 @@ static int FalseUP1D___init__(BPy_FalseUP1D *self, PyObject *args, PyObject *kwd
/*-----------------------BPy_FalseUP1D type definition ------------------------------*/
PyTypeObject FalseUP1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "FalseUP1D", /* tp_name */
- sizeof(BPy_FalseUP1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- FalseUP1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryPredicate1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)FalseUP1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "FalseUP1D",
+ /*tp_basicsize*/ sizeof(BPy_FalseUP1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ FalseUP1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryPredicate1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)FalseUP1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp
index e17c7705420..c834aa81445 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp
@@ -58,43 +58,44 @@ static int QuantitativeInvisibilityUP1D___init__(BPy_QuantitativeInvisibilityUP1
/*-----------------------BPy_QuantitativeInvisibilityUP1D type definition -----------------------*/
PyTypeObject QuantitativeInvisibilityUP1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "QuantitativeInvisibilityUP1D", /* tp_name */
- sizeof(BPy_QuantitativeInvisibilityUP1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- QuantitativeInvisibilityUP1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryPredicate1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)QuantitativeInvisibilityUP1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "QuantitativeInvisibilityUP1D",
+ /*tp_basicsize*/ sizeof(BPy_QuantitativeInvisibilityUP1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ QuantitativeInvisibilityUP1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryPredicate1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)QuantitativeInvisibilityUP1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp
index 773e6c8dfb2..f7307a81540 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp
@@ -6,6 +6,8 @@
#include "BPy_ShapeUP1D.h"
+#include "BLI_sys_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -42,7 +44,7 @@ static char ShapeUP1D___doc__[] =
static int ShapeUP1D___init__(BPy_ShapeUP1D *self, PyObject *args, PyObject *kwds)
{
static const char *kwlist[] = {"first", "second", nullptr};
- unsigned u1, u2 = 0;
+ uint u1, u2 = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "I|I", (char **)kwlist, &u1, &u2)) {
return -1;
@@ -54,43 +56,44 @@ static int ShapeUP1D___init__(BPy_ShapeUP1D *self, PyObject *args, PyObject *kwd
/*-----------------------BPy_ShapeUP1D type definition ------------------------------*/
PyTypeObject ShapeUP1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "ShapeUP1D", /* tp_name */
- sizeof(BPy_ShapeUP1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- ShapeUP1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryPredicate1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)ShapeUP1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "ShapeUP1D",
+ /*tp_basicsize*/ sizeof(BPy_ShapeUP1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ ShapeUP1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryPredicate1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)ShapeUP1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp
index 03c7f364b55..704bb5e9608 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp
@@ -42,43 +42,44 @@ static int TrueUP1D___init__(BPy_TrueUP1D *self, PyObject *args, PyObject *kwds)
/*-----------------------BPy_TrueUP1D type definition ------------------------------*/
PyTypeObject TrueUP1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "TrueUP1D", /* tp_name */
- sizeof(BPy_TrueUP1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- TrueUP1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryPredicate1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)TrueUP1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "TrueUP1D",
+ /*tp_basicsize*/ sizeof(BPy_TrueUP1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ TrueUP1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryPredicate1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)TrueUP1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp
index eea3a1cacc4..da1e07162d1 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp
@@ -55,43 +55,44 @@ static int WithinImageBoundaryUP1D___init__(BPy_WithinImageBoundaryUP1D *self,
/*-----------------------BPy_TrueUP1D type definition ------------------------------*/
PyTypeObject WithinImageBoundaryUP1D_Type = {
- PyVarObject_HEAD_INIT(nullptr, 0) "WithinImageBoundaryUP1D", /* tp_name */
- sizeof(BPy_WithinImageBoundaryUP1D), /* tp_basicsize */
- 0, /* tp_itemsize */
- nullptr, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- nullptr, /* tp_getattr */
- nullptr, /* tp_setattr */
- nullptr, /* tp_reserved */
- nullptr, /* tp_repr */
- nullptr, /* tp_as_number */
- nullptr, /* tp_as_sequence */
- nullptr, /* tp_as_mapping */
- nullptr, /* tp_hash */
- nullptr, /* tp_call */
- nullptr, /* tp_str */
- nullptr, /* tp_getattro */
- nullptr, /* tp_setattro */
- nullptr, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- WithinImageBoundaryUP1D___doc__, /* tp_doc */
- nullptr, /* tp_traverse */
- nullptr, /* tp_clear */
- nullptr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- nullptr, /* tp_iter */
- nullptr, /* tp_iternext */
- nullptr, /* tp_methods */
- nullptr, /* tp_members */
- nullptr, /* tp_getset */
- &UnaryPredicate1D_Type, /* tp_base */
- nullptr, /* tp_dict */
- nullptr, /* tp_descr_get */
- nullptr, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)WithinImageBoundaryUP1D___init__, /* tp_init */
- nullptr, /* tp_alloc */
- nullptr, /* tp_new */
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ /*tp_name*/ "WithinImageBoundaryUP1D",
+ /*tp_basicsize*/ sizeof(BPy_WithinImageBoundaryUP1D),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ nullptr,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ nullptr,
+ /*tp_setattr*/ nullptr,
+ /*tp_as_async*/ nullptr,
+ /*tp_repr*/ nullptr,
+ /*tp_as_number*/ nullptr,
+ /*tp_as_sequence*/ nullptr,
+ /*tp_as_mapping*/ nullptr,
+ /*tp_hash*/ nullptr,
+ /*tp_call*/ nullptr,
+ /*tp_str*/ nullptr,
+ /*tp_getattro*/ nullptr,
+ /*tp_setattro*/ nullptr,
+ /*tp_as_buffer*/ nullptr,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ WithinImageBoundaryUP1D___doc__,
+ /*tp_traverse*/ nullptr,
+ /*tp_clear*/ nullptr,
+ /*tp_richcompare*/ nullptr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ nullptr,
+ /*tp_iternext*/ nullptr,
+ /*tp_methods*/ nullptr,
+ /*tp_members*/ nullptr,
+ /*tp_getset*/ nullptr,
+ /*tp_base*/ &UnaryPredicate1D_Type,
+ /*tp_dict*/ nullptr,
+ /*tp_descr_get*/ nullptr,
+ /*tp_descr_set*/ nullptr,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)WithinImageBoundaryUP1D___init__,
+ /*tp_alloc*/ nullptr,
+ /*tp_new*/ nullptr,
};
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp
index d02ff6990a5..39dbf4b87a9 100644
--- a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp
+++ b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp
@@ -7,6 +7,8 @@
#include "IndexedFaceSet.h"
+#include "BLI_sys_types.h"
+
namespace Freestyle {
IndexedFaceSet::IndexedFaceSet()
@@ -34,26 +36,26 @@ IndexedFaceSet::IndexedFaceSet()
}
IndexedFaceSet::IndexedFaceSet(float *iVertices,
- unsigned iVSize,
+ uint iVSize,
float *iNormals,
- unsigned iNSize,
+ uint iNSize,
FrsMaterial **iMaterials,
- unsigned iMSize,
+ uint iMSize,
float *iTexCoords,
- unsigned iTSize,
- unsigned iNumFaces,
- unsigned *iNumVertexPerFace,
+ uint iTSize,
+ uint iNumFaces,
+ uint *iNumVertexPerFace,
TRIANGLES_STYLE *iFaceStyle,
FaceEdgeMark *iFaceEdgeMarks,
- unsigned *iVIndices,
- unsigned iVISize,
- unsigned *iNIndices,
- unsigned iNISize,
- unsigned *iMIndices,
- unsigned iMISize,
- unsigned *iTIndices,
- unsigned iTISize,
- unsigned iCopy)
+ uint *iVIndices,
+ uint iVISize,
+ uint *iNIndices,
+ uint iNISize,
+ uint *iMIndices,
+ uint iMISize,
+ uint *iTIndices,
+ uint iTISize,
+ uint iCopy)
{
if (1 == iCopy) {
_VSize = iVSize;
@@ -68,7 +70,7 @@ IndexedFaceSet::IndexedFaceSet(float *iVertices,
_FrsMaterials = nullptr;
if (iMaterials) {
_FrsMaterials = new FrsMaterial *[_MSize];
- for (unsigned int i = 0; i < _MSize; ++i) {
+ for (uint i = 0; i < _MSize; ++i) {
_FrsMaterials[i] = new FrsMaterial(*(iMaterials[i]));
}
}
@@ -80,8 +82,8 @@ IndexedFaceSet::IndexedFaceSet(float *iVertices,
}
_NumFaces = iNumFaces;
- _NumVertexPerFace = new unsigned[_NumFaces];
- memcpy(_NumVertexPerFace, iNumVertexPerFace, _NumFaces * sizeof(unsigned));
+ _NumVertexPerFace = new uint[_NumFaces];
+ memcpy(_NumVertexPerFace, iNumVertexPerFace, _NumFaces * sizeof(uint));
_FaceStyle = new TRIANGLES_STYLE[_NumFaces];
memcpy(_FaceStyle, iFaceStyle, _NumFaces * sizeof(TRIANGLES_STYLE));
@@ -90,24 +92,24 @@ IndexedFaceSet::IndexedFaceSet(float *iVertices,
memcpy(_FaceEdgeMarks, iFaceEdgeMarks, _NumFaces * sizeof(FaceEdgeMark));
_VISize = iVISize;
- _VIndices = new unsigned[_VISize];
- memcpy(_VIndices, iVIndices, _VISize * sizeof(unsigned));
+ _VIndices = new uint[_VISize];
+ memcpy(_VIndices, iVIndices, _VISize * sizeof(uint));
_NISize = iNISize;
- _NIndices = new unsigned[_NISize];
- memcpy(_NIndices, iNIndices, _NISize * sizeof(unsigned));
+ _NIndices = new uint[_NISize];
+ memcpy(_NIndices, iNIndices, _NISize * sizeof(uint));
_MISize = iMISize;
_MIndices = nullptr;
if (iMIndices) {
- _MIndices = new unsigned[_MISize];
- memcpy(_MIndices, iMIndices, _MISize * sizeof(unsigned));
+ _MIndices = new uint[_MISize];
+ memcpy(_MIndices, iMIndices, _MISize * sizeof(uint));
}
_TISize = iTISize;
_TIndices = nullptr;
if (_TISize) {
- _TIndices = new unsigned[_TISize];
- memcpy(_TIndices, iTIndices, _TISize * sizeof(unsigned));
+ _TIndices = new uint[_TISize];
+ memcpy(_TIndices, iTIndices, _TISize * sizeof(uint));
}
}
else {
@@ -161,7 +163,7 @@ IndexedFaceSet::IndexedFaceSet(const IndexedFaceSet &iBrother) : Rep(iBrother)
_MSize = iBrother.msize();
if (_MSize) {
_FrsMaterials = new FrsMaterial *[_MSize];
- for (unsigned int i = 0; i < _MSize; ++i) {
+ for (uint i = 0; i < _MSize; ++i) {
_FrsMaterials[i] = new FrsMaterial(*(iBrother._FrsMaterials[i]));
}
}
@@ -177,8 +179,8 @@ IndexedFaceSet::IndexedFaceSet(const IndexedFaceSet &iBrother) : Rep(iBrother)
}
_NumFaces = iBrother.numFaces();
- _NumVertexPerFace = new unsigned[_NumFaces];
- memcpy(_NumVertexPerFace, iBrother.numVertexPerFaces(), _NumFaces * sizeof(unsigned));
+ _NumVertexPerFace = new uint[_NumFaces];
+ memcpy(_NumVertexPerFace, iBrother.numVertexPerFaces(), _NumFaces * sizeof(uint));
_FaceStyle = new TRIANGLES_STYLE[_NumFaces];
memcpy(_FaceStyle, iBrother.trianglesStyle(), _NumFaces * sizeof(TRIANGLES_STYLE));
@@ -187,17 +189,17 @@ IndexedFaceSet::IndexedFaceSet(const IndexedFaceSet &iBrother) : Rep(iBrother)
memcpy(_FaceEdgeMarks, iBrother.faceEdgeMarks(), _NumFaces * sizeof(FaceEdgeMark));
_VISize = iBrother.visize();
- _VIndices = new unsigned[_VISize];
- memcpy(_VIndices, iBrother.vindices(), _VISize * sizeof(unsigned));
+ _VIndices = new uint[_VISize];
+ memcpy(_VIndices, iBrother.vindices(), _VISize * sizeof(uint));
_NISize = iBrother.nisize();
- _NIndices = new unsigned[_NISize];
- memcpy(_NIndices, iBrother.nindices(), _NISize * sizeof(unsigned));
+ _NIndices = new uint[_NISize];
+ memcpy(_NIndices, iBrother.nindices(), _NISize * sizeof(uint));
_MISize = iBrother.misize();
if (_MISize) {
- _MIndices = new unsigned[_MISize];
- memcpy(_MIndices, iBrother.mindices(), _MISize * sizeof(unsigned));
+ _MIndices = new uint[_MISize];
+ memcpy(_MIndices, iBrother.mindices(), _MISize * sizeof(uint));
}
else {
_MIndices = nullptr;
@@ -206,8 +208,8 @@ IndexedFaceSet::IndexedFaceSet(const IndexedFaceSet &iBrother) : Rep(iBrother)
_TISize = iBrother.tisize();
_TIndices = nullptr;
if (_TISize) {
- _TIndices = new unsigned[_TISize];
- memcpy(_TIndices, iBrother.tindices(), _TISize * sizeof(unsigned));
+ _TIndices = new uint[_TISize];
+ memcpy(_TIndices, iBrother.tindices(), _TISize * sizeof(uint));
}
}
@@ -224,7 +226,7 @@ IndexedFaceSet::~IndexedFaceSet()
}
if (nullptr != _FrsMaterials) {
- for (unsigned int i = 0; i < _MSize; ++i) {
+ for (uint i = 0; i < _MSize; ++i) {
delete _FrsMaterials[i];
}
delete[] _FrsMaterials;
@@ -290,7 +292,7 @@ void IndexedFaceSet::ComputeBBox()
// parse all the coordinates to find the Xmax, YMax, ZMax
float *v = _Vertices;
- for (unsigned int i = 0; i < (_VSize / 3); ++i) {
+ for (uint i = 0; i < (_VSize / 3); ++i) {
if (*v > XMax) {
XMax = *v;
}
diff --git a/source/blender/freestyle/intern/scene_graph/NodeTransform.cpp b/source/blender/freestyle/intern/scene_graph/NodeTransform.cpp
index 31101e988e5..0089f68ce2d 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeTransform.cpp
+++ b/source/blender/freestyle/intern/scene_graph/NodeTransform.cpp
@@ -9,6 +9,7 @@
#include "NodeTransform.h"
#include "BLI_math.h"
+#include "BLI_sys_types.h"
namespace Freestyle {
@@ -122,7 +123,7 @@ void NodeTransform::AddBBox(const BBox<Vec3r> &iBBox)
// Computes the transform iBBox
HVec3r tbox[8];
- unsigned int i;
+ uint i;
for (i = 0; i < 8; i++) {
tbox[i] = _Matrix * box[i];
}
@@ -130,7 +131,7 @@ void NodeTransform::AddBBox(const BBox<Vec3r> &iBBox)
Vec3r newMin(tbox[0]);
Vec3r newMax(tbox[0]);
for (i = 0; i < 8; i++) {
- for (unsigned int j = 0; j < 3; j++) {
+ for (uint j = 0; j < 3; j++) {
if (newMin[j] > tbox[i][j]) {
newMin[j] = tbox[i][j];
}
@@ -147,9 +148,9 @@ void NodeTransform::AddBBox(const BBox<Vec3r> &iBBox)
bool NodeTransform::isScaled(const Matrix44r &M)
{
- for (unsigned int j = 0; j < 3; j++) {
+ for (uint j = 0; j < 3; j++) {
real norm = 0;
- for (unsigned int i = 0; i < 3; i++) {
+ for (uint i = 0; i < 3; i++) {
norm += M(i, j) * M(i, j);
}
if ((norm > 1.01) || (norm < 0.99)) {
diff --git a/source/blender/freestyle/intern/scene_graph/SceneHash.cpp b/source/blender/freestyle/intern/scene_graph/SceneHash.cpp
index af41421fa72..0ab83003514 100644
--- a/source/blender/freestyle/intern/scene_graph/SceneHash.cpp
+++ b/source/blender/freestyle/intern/scene_graph/SceneHash.cpp
@@ -6,6 +6,8 @@
#include "SceneHash.h"
+#include "BLI_sys_types.h"
+
#include <sstream>
namespace Freestyle {
@@ -20,38 +22,38 @@ string SceneHash::toString()
void SceneHash::visitNodeViewLayer(NodeViewLayer &node)
{
struct RenderData *r = &node.scene().r;
- adler32((unsigned char *)&r->xsch, sizeof(r->xsch)); // resolution_x
- adler32((unsigned char *)&r->ysch, sizeof(r->ysch)); // resolution_y
- adler32((unsigned char *)&r->size, sizeof(r->size)); // resolution_percentage
+ adler32((uchar *)&r->xsch, sizeof(r->xsch)); // resolution_x
+ adler32((uchar *)&r->ysch, sizeof(r->ysch)); // resolution_y
+ adler32((uchar *)&r->size, sizeof(r->size)); // resolution_percentage
struct FreestyleConfig *config = &node.sceneLayer().freestyle_config;
- adler32((unsigned char *)&config->flags, sizeof(config->flags));
- adler32((unsigned char *)&config->crease_angle, sizeof(config->crease_angle));
- adler32((unsigned char *)&config->sphere_radius, sizeof(config->sphere_radius));
- adler32((unsigned char *)&config->dkr_epsilon, sizeof(config->dkr_epsilon));
+ adler32((uchar *)&config->flags, sizeof(config->flags));
+ adler32((uchar *)&config->crease_angle, sizeof(config->crease_angle));
+ adler32((uchar *)&config->sphere_radius, sizeof(config->sphere_radius));
+ adler32((uchar *)&config->dkr_epsilon, sizeof(config->dkr_epsilon));
}
void SceneHash::visitNodeCamera(NodeCamera &cam)
{
double *proj = cam.projectionMatrix();
for (int i = 0; i < 16; i++) {
- adler32((unsigned char *)&proj[i], sizeof(double));
+ adler32((uchar *)&proj[i], sizeof(double));
}
}
void SceneHash::visitIndexedFaceSet(IndexedFaceSet &ifs)
{
const float *v = ifs.vertices();
- const unsigned n = ifs.vsize();
+ const uint n = ifs.vsize();
- for (unsigned i = 0; i < n; i++) {
- adler32((unsigned char *)&v[i], sizeof(v[i]));
+ for (uint i = 0; i < n; i++) {
+ adler32((uchar *)&v[i], sizeof(v[i]));
}
}
static const int MOD_ADLER = 65521;
-void SceneHash::adler32(const unsigned char *data, int size)
+void SceneHash::adler32(const uchar *data, int size)
{
uint32_t sum1 = _sum & 0xffff;
uint32_t sum2 = (_sum >> 16) & 0xffff;
diff --git a/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp b/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp
index 623b6b0e2bf..4a2b6979985 100644
--- a/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp
+++ b/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp
@@ -10,6 +10,8 @@
#include "IndexedFaceSet.h"
#include "ScenePrettyPrinter.h"
+#include "BLI_sys_types.h"
+
namespace Freestyle {
#define VISIT(CLASS) \
@@ -25,42 +27,42 @@ VISIT(NodeLight)
VISIT(NodeDrawingStyle)
VISIT(NodeTransform)
-void ScenePrettyPrinter::visitNodeShapeBefore(NodeShape &UNUSED(shape))
+void ScenePrettyPrinter::visitNodeShapeBefore(NodeShape & /*shape*/)
{
increaseSpace();
}
-void ScenePrettyPrinter::visitNodeShapeAfter(NodeShape &UNUSED(shape))
+void ScenePrettyPrinter::visitNodeShapeAfter(NodeShape & /*shape*/)
{
decreaseSpace();
}
-void ScenePrettyPrinter::visitNodeGroupBefore(NodeGroup &UNUSED(group))
+void ScenePrettyPrinter::visitNodeGroupBefore(NodeGroup & /*group*/)
{
increaseSpace();
}
-void ScenePrettyPrinter::visitNodeGroupAfter(NodeGroup &UNUSED(group))
+void ScenePrettyPrinter::visitNodeGroupAfter(NodeGroup & /*group*/)
{
decreaseSpace();
}
-void ScenePrettyPrinter::visitNodeDrawingStyleBefore(NodeDrawingStyle &UNUSED(style))
+void ScenePrettyPrinter::visitNodeDrawingStyleBefore(NodeDrawingStyle & /*style*/)
{
increaseSpace();
}
-void ScenePrettyPrinter::visitNodeDrawingStyleAfter(NodeDrawingStyle &UNUSED(style))
+void ScenePrettyPrinter::visitNodeDrawingStyleAfter(NodeDrawingStyle & /*style*/)
{
decreaseSpace();
}
-void ScenePrettyPrinter::visitNodeTransformBefore(NodeTransform &UNUSED(transform))
+void ScenePrettyPrinter::visitNodeTransformBefore(NodeTransform & /*transform*/)
{
increaseSpace();
}
-void ScenePrettyPrinter::visitNodeTransformAfter(NodeTransform &UNUSED(transform))
+void ScenePrettyPrinter::visitNodeTransformAfter(NodeTransform & /*transform*/)
{
decreaseSpace();
}
@@ -73,11 +75,11 @@ VISIT(VertexRep)
void ScenePrettyPrinter::visitIndexedFaceSet(IndexedFaceSet &ifs)
{
const float *vertices = ifs.vertices();
- unsigned vsize = ifs.vsize();
+ uint vsize = ifs.vsize();
_ofs << _space << "IndexedFaceSet" << endl;
const float *p = vertices;
- for (unsigned int i = 0; i < vsize / 3; i++) {
+ for (uint i = 0; i < vsize / 3; i++) {
_ofs << _space << " " << setw(3) << setfill('0') << i << ": " << p[0] << ", " << p[1] << ", "
<< p[2] << endl;
p += 3;
diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.cpp b/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.cpp
index 0bd2b960de3..37f5fb5cfbb 100644
--- a/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.cpp
+++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.cpp
@@ -25,13 +25,13 @@ int DensityF0D::operator()(Interface0DIterator &iter)
}
RGBImage image;
- canvas->readColorPixels((int)iter->getProjectedX() - bound,
- (int)iter->getProjectedY() - bound,
+ canvas->readColorPixels(int(iter->getProjectedX()) - bound,
+ int(iter->getProjectedY()) - bound,
_filter.maskSize(),
_filter.maskSize(),
image);
result = _filter.getSmoothedPixel<RGBImage>(
- &image, (int)iter->getProjectedX(), (int)iter->getProjectedY());
+ &image, int(iter->getProjectedX()), int(iter->getProjectedY()));
return 0;
}
@@ -48,13 +48,13 @@ int LocalAverageDepthF0D::operator()(Interface0DIterator &iter)
}
GrayImage image;
- iViewer->readDepthPixels((int)iter->getProjectedX() - bound,
- (int)iter->getProjectedY() - bound,
+ iViewer->readDepthPixels(int(iter->getProjectedX()) - bound,
+ int(iter->getProjectedY()) - bound,
_filter.maskSize(),
_filter.maskSize(),
image);
result = _filter.getSmoothedPixel(
- &image, (int)iter->getProjectedX(), (int)iter->getProjectedY());
+ &image, int(iter->getProjectedX()), int(iter->getProjectedY()));
return 0;
}
@@ -63,7 +63,7 @@ int ReadMapPixelF0D::operator()(Interface0DIterator &iter)
{
Canvas *canvas = Canvas::getInstance();
result = canvas->readMapPixel(
- _mapName, _level, (int)iter->getProjectedX(), (int)iter->getProjectedY());
+ _mapName, _level, int(iter->getProjectedX()), int(iter->getProjectedY()));
return 0;
}
@@ -71,7 +71,7 @@ int ReadSteerableViewMapPixelF0D::operator()(Interface0DIterator &iter)
{
SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap();
result = svm->readSteerableViewMapPixel(
- _orientation, _level, (int)iter->getProjectedX(), (int)iter->getProjectedY());
+ _orientation, _level, int(iter->getProjectedX()), int(iter->getProjectedY()));
return 0;
}
@@ -79,7 +79,7 @@ int ReadCompleteViewMapPixelF0D::operator()(Interface0DIterator &iter)
{
SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap();
result = svm->readCompleteViewMapPixel(
- _level, (int)iter->getProjectedX(), (int)iter->getProjectedY());
+ _level, int(iter->getProjectedX()), int(iter->getProjectedY()));
return 0;
}
@@ -87,12 +87,12 @@ int GetViewMapGradientNormF0D::operator()(Interface0DIterator &iter)
{
SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap();
float pxy = svm->readCompleteViewMapPixel(
- _level, (int)iter->getProjectedX(), (int)iter->getProjectedY());
+ _level, int(iter->getProjectedX()), int(iter->getProjectedY()));
float gx = svm->readCompleteViewMapPixel(
- _level, (int)iter->getProjectedX() + _step, (int)iter->getProjectedY()) -
+ _level, int(iter->getProjectedX()) + _step, int(iter->getProjectedY())) -
pxy;
float gy = svm->readCompleteViewMapPixel(
- _level, (int)iter->getProjectedX(), (int)iter->getProjectedY() + _step) -
+ _level, int(iter->getProjectedX()), int(iter->getProjectedY()) + _step) -
pxy;
result = Vec2f(gx, gy).norm();
return 0;
diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.cpp b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.cpp
index a759cc333f1..a221e0e8bbd 100644
--- a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.cpp
+++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.cpp
@@ -10,6 +10,8 @@
#include "../view_map/SteerableViewMap.h"
+#include "BLI_sys_types.h"
+
namespace Freestyle::Functions1D {
int GetSteerableViewMapDensityF1D::operator()(Interface1D &inter)
@@ -19,7 +21,7 @@ int GetSteerableViewMapDensityF1D::operator()(Interface1D &inter)
Interface0DIterator itnext = it;
++itnext;
FEdge *fe;
- unsigned nSVM;
+ uint nSVM;
vector<float> values;
while (!itnext.isEnd()) {
@@ -38,14 +40,14 @@ int GetSteerableViewMapDensityF1D::operator()(Interface1D &inter)
}
Vec2r m((i0D.getProjectedX() + i0Dnext.getProjectedX()) / 2.0,
(i0D.getProjectedY() + i0Dnext.getProjectedY()) / 2.0);
- values.push_back(svm->readSteerableViewMapPixel(nSVM, _level, (int)m[0], (int)m[1]));
+ values.push_back(svm->readSteerableViewMapPixel(nSVM, _level, int(m[0]), int(m[1])));
++it;
++itnext;
}
float res, res_tmp;
vector<float>::iterator v = values.begin(), vend = values.end();
- unsigned size = 1;
+ uint size = 1;
switch (_integration) {
case MIN:
res = *v;
diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h
index c19ac31ae4a..e5009f2b4f8 100644
--- a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h
+++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h
@@ -33,7 +33,7 @@ class DensityF1D : public UnaryFunction1D<double> {
public:
/** Builds the functor.
* \param sigma:
- * Thesigma used in DensityF0D and determining the window size used in each density query.
+ * The sigma used in DensityF0D and determining the window size used in each density query.
* \param iType:
* The integration method used to compute a single value from a set of values.
* \param sampling:
diff --git a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp
index 5530026b7ec..6508c95f2b4 100644
--- a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp
+++ b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp
@@ -11,6 +11,8 @@
#include "../system/PseudoNoise.h"
#include "../system/RandGen.h"
+#include "BLI_sys_types.h"
+
namespace Freestyle {
/////////////////////////////////////////
@@ -71,7 +73,7 @@ int CalligraphicShader::shade(Stroke &ioStroke) const
//
/////////////////////////////////////////
-static const unsigned NB_VALUE_NOISE = 512;
+static const uint NB_VALUE_NOISE = 512;
SpatialNoiseShader::SpatialNoiseShader(
float iAmount, float ixScale, int nbOctave, bool smooth, bool pureRandom)
diff --git a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp
index c801dc70114..e77ba63f3d6 100644
--- a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp
+++ b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp
@@ -23,6 +23,8 @@
#include "BKE_global.h"
+#include "BLI_sys_types.h"
+
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -80,11 +82,11 @@ int IncreasingThicknessShader::shade(Stroke &stroke) const
for (i = 0, v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); v != vend;
++v, ++i) {
float t;
- if (i < (float)n / 2.0f) {
- t = (1.0 - (float)i / (float)n) * _ThicknessMin + (float)i / (float)n * _ThicknessMax;
+ if (i < float(n) / 2.0f) {
+ t = (1.0 - float(i) / float(n)) * _ThicknessMin + float(i) / float(n) * _ThicknessMax;
}
else {
- t = (1.0 - (float)i / (float)n) * _ThicknessMax + (float)i / (float)n * _ThicknessMin;
+ t = (1.0 - float(i) / float(n)) * _ThicknessMax + float(i) / float(n) * _ThicknessMin;
}
v->attribute().setThickness(t / 2.0, t / 2.0);
}
@@ -102,11 +104,11 @@ int ConstrainedIncreasingThicknessShader::shade(Stroke &stroke) const
// XXX Why not using an if/else here? Else, if last condition is true, everything else is
// computed for nothing!
float t;
- if (i < (float)n / 2.0f) {
- t = (1.0 - (float)i / (float)n) * _ThicknessMin + (float)i / (float)n * maxT;
+ if (i < float(n) / 2.0f) {
+ t = (1.0 - float(i) / float(n)) * _ThicknessMin + float(i) / float(n) * maxT;
}
else {
- t = (1.0 - (float)i / (float)n) * maxT + (float)i / (float)n * _ThicknessMin;
+ t = (1.0 - float(i) / float(n)) * maxT + float(i) / float(n) * _ThicknessMin;
}
v->attribute().setThickness(t / 2.0, t / 2.0);
if (i == n - 1) {
@@ -152,18 +154,18 @@ int LengthDependingThicknessShader::shade(Stroke &stroke) const
return 0;
}
-static const unsigned NB_VALUE_NOISE = 512;
+static const uint NB_VALUE_NOISE = 512;
ThicknessNoiseShader::ThicknessNoiseShader()
{
_amplitude = 1.0f;
- _scale = 1.0f / 2.0f / (float)NB_VALUE_NOISE;
+ _scale = 1.0f / 2.0f / float(NB_VALUE_NOISE);
}
ThicknessNoiseShader::ThicknessNoiseShader(float iAmplitude, float iPeriod)
{
_amplitude = iAmplitude;
- _scale = 1.0f / iPeriod / (float)NB_VALUE_NOISE;
+ _scale = 1.0f / iPeriod / float(NB_VALUE_NOISE);
}
int ThicknessNoiseShader::shade(Stroke &stroke) const
@@ -213,8 +215,8 @@ int IncreasingColorShader::shade(Stroke &stroke) const
for (yo = 0, v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); v != vend;
++v, ++yo) {
for (int i = 0; i < 4; ++i) {
- newcolor[i] = (1.0 - (float)yo / (float)n) * _colorMin[i] +
- (float)yo / (float)n * _colorMax[i];
+ newcolor[i] = (1.0 - float(yo) / float(n)) * _colorMin[i] +
+ float(yo) / float(n) * _colorMax[i];
}
v->attribute().setColor(newcolor[0], newcolor[1], newcolor[2]);
v->attribute().setAlpha(newcolor[3]);
@@ -243,13 +245,13 @@ int MaterialColorShader::shade(Stroke &stroke) const
ColorNoiseShader::ColorNoiseShader()
{
_amplitude = 1.0f;
- _scale = 1.0f / 2.0f / (float)NB_VALUE_NOISE;
+ _scale = 1.0f / 2.0f / float(NB_VALUE_NOISE);
}
ColorNoiseShader::ColorNoiseShader(float iAmplitude, float iPeriod)
{
_amplitude = iAmplitude;
- _scale = 1.0f / iPeriod / (float)NB_VALUE_NOISE;
+ _scale = 1.0f / iPeriod / float(NB_VALUE_NOISE);
}
int ColorNoiseShader::shade(Stroke &stroke) const
@@ -373,7 +375,7 @@ int BezierCurveShader::shade(Stroke &stroke) const
++v;
for (vend = stroke.strokeVerticesEnd(); v != vend; ++v) {
if (!((fabs(v->x() - (previous)->x()) < M_EPSILON) &&
- ((fabs(v->y() - (previous)->y()) < M_EPSILON)))) {
+ (fabs(v->y() - (previous)->y()) < M_EPSILON))) {
data.emplace_back(v->x(), v->y());
}
previous = v;
@@ -395,7 +397,7 @@ int BezierCurveShader::shade(Stroke &stroke) const
p = segmentsVertices.begin();
++p;
for (pend = segmentsVertices.end(); p != pend; ++p) {
- CurveVertices.push_back((*p));
+ CurveVertices.push_back(*p);
}
}
@@ -467,7 +469,7 @@ int BezierCurveShader::shade(Stroke &stroke) const
vector<StrokeAttribute>::iterator a = attributes.begin(), aend = attributes.end();
int index = 0;
- int index1 = (int)floor((float)originalSize / 2.0);
+ int index1 = int(floor(float(originalSize) / 2.0));
int index2 = index1 + nExtraVertex;
for (it = stroke.strokeVerticesBegin(), itend = stroke.strokeVerticesEnd();
(it != itend) && (a != aend);
@@ -614,7 +616,7 @@ int GuidingLinesShader::shade(Stroke &stroke) const
n[0] = -n[0];
n[1] = -n[1];
}
- float offset = (piece.error()) / 2.0f * _offset;
+ float offset = piece.error() / 2.0f * _offset;
StrokeInternal::StrokeVertexIterator v, vend;
for (v = a, vend = stroke.strokeVerticesEnd(); v != vend; ++v) {
v->setPoint(piece.A.x() + v->u() * u.x() + n.x() * offset,
@@ -660,13 +662,13 @@ int TipRemoverShader::shade(Stroke &stroke) const
vector<StrokeVertex *>::iterator sv, svend;
for (sv = verticesToRemove.begin(), svend = verticesToRemove.end(); sv != svend; ++sv) {
- stroke.RemoveVertex((*sv));
+ stroke.RemoveVertex(*sv);
}
// Resample so that our new stroke have the same number of vertices than before
stroke.Resample(originalSize);
- if ((int)stroke.strokeVerticesSize() != originalSize) { // soc
+ if (int(stroke.strokeVerticesSize()) != originalSize) { // soc
cerr << "Warning: resampling problem" << endl;
}
diff --git a/source/blender/freestyle/intern/stroke/Canvas.cpp b/source/blender/freestyle/intern/stroke/Canvas.cpp
index 68a18323621..741fad592cf 100644
--- a/source/blender/freestyle/intern/stroke/Canvas.cpp
+++ b/source/blender/freestyle/intern/stroke/Canvas.cpp
@@ -22,6 +22,8 @@
#include "../view_map/SteerableViewMap.h"
+#include "BLI_sys_types.h"
+
#include "BKE_global.h"
// soc #include <qimage.h>
@@ -91,7 +93,7 @@ void Canvas::Draw()
preDraw();
TimeStamp *timestamp = TimeStamp::instance();
- for (unsigned int i = 0; i < _StyleModules.size(); ++i) {
+ for (uint i = 0; i < _StyleModules.size(); ++i) {
_current_sm = _StyleModules[i];
if (i < _Layers.size() && _Layers[i]) {
@@ -169,11 +171,11 @@ void Canvas::PushBackStyleModule(StyleModule *iStyleModule)
_Layers.push_back(layer);
}
-void Canvas::InsertStyleModule(unsigned index, StyleModule *iStyleModule)
+void Canvas::InsertStyleModule(uint index, StyleModule *iStyleModule)
{
- unsigned size = _StyleModules.size();
+ uint size = _StyleModules.size();
StrokeLayer *layer = new StrokeLayer();
- if ((_StyleModules.empty()) || (index == size)) {
+ if (_StyleModules.empty() || (index == size)) {
_StyleModules.push_back(iStyleModule);
_Layers.push_back(layer);
return;
@@ -182,9 +184,9 @@ void Canvas::InsertStyleModule(unsigned index, StyleModule *iStyleModule)
_Layers.insert(_Layers.begin() + index, layer);
}
-void Canvas::RemoveStyleModule(unsigned index)
+void Canvas::RemoveStyleModule(uint index)
{
- unsigned int i = 0;
+ uint i = 0;
if (!_StyleModules.empty()) {
for (deque<StyleModule *>::iterator s = _StyleModules.begin(), send = _StyleModules.end();
s != send;
@@ -216,7 +218,7 @@ void Canvas::RemoveStyleModule(unsigned index)
}
}
-void Canvas::SwapStyleModules(unsigned i1, unsigned i2)
+void Canvas::SwapStyleModules(uint i1, uint i2)
{
StyleModule *tmp;
tmp = _StyleModules[i1];
@@ -229,9 +231,9 @@ void Canvas::SwapStyleModules(unsigned i1, unsigned i2)
_Layers[i2] = tmp2;
}
-void Canvas::ReplaceStyleModule(unsigned index, StyleModule *iStyleModule)
+void Canvas::ReplaceStyleModule(uint index, StyleModule *iStyleModule)
{
- unsigned i = 0;
+ uint i = 0;
for (deque<StyleModule *>::iterator s = _StyleModules.begin(), send = _StyleModules.end();
s != send;
++s, ++i) {
@@ -245,29 +247,29 @@ void Canvas::ReplaceStyleModule(unsigned index, StyleModule *iStyleModule)
}
}
-void Canvas::setVisible(unsigned index, bool iVisible)
+void Canvas::setVisible(uint index, bool iVisible)
{
_StyleModules[index]->setDisplayed(iVisible);
}
-void Canvas::setModified(unsigned index, bool iMod)
+void Canvas::setModified(uint index, bool iMod)
{
_StyleModules[index]->setModified(iMod);
}
void Canvas::resetModified(bool iMod /* = false */)
{
- unsigned int size = _StyleModules.size();
- for (unsigned int i = 0; i < size; ++i) {
+ uint size = _StyleModules.size();
+ for (uint i = 0; i < size; ++i) {
setModified(i, iMod);
}
}
-void Canvas::causalStyleModules(vector<unsigned> &vec, unsigned index)
+void Canvas::causalStyleModules(vector<uint> &vec, uint index)
{
- unsigned int size = _StyleModules.size();
+ uint size = _StyleModules.size();
- for (unsigned int i = index; i < size; ++i) {
+ for (uint i = index; i < size; ++i) {
if (_StyleModules[i]->getCausal()) {
vec.push_back(i);
}
@@ -276,7 +278,7 @@ void Canvas::causalStyleModules(vector<unsigned> &vec, unsigned index)
void Canvas::Render(const StrokeRenderer *iRenderer)
{
- for (unsigned int i = 0; i < _StyleModules.size(); ++i) {
+ for (uint i = 0; i < _StyleModules.size(); ++i) {
if (!_StyleModules[i]->getDisplayed() || !_Layers[i]) {
continue;
}
@@ -286,7 +288,7 @@ void Canvas::Render(const StrokeRenderer *iRenderer)
void Canvas::RenderBasic(const StrokeRenderer *iRenderer)
{
- for (unsigned int i = 0; i < _StyleModules.size(); ++i) {
+ for (uint i = 0; i < _StyleModules.size(); ++i) {
if (!_StyleModules[i]->getDisplayed() || !_Layers[i]) {
continue;
}
@@ -294,10 +296,7 @@ void Canvas::RenderBasic(const StrokeRenderer *iRenderer)
}
}
-void Canvas::loadMap(const char *iFileName,
- const char *iMapName,
- unsigned int iNbLevels,
- float iSigma)
+void Canvas::loadMap(const char *iFileName, const char *iMapName, uint iNbLevels, float iSigma)
{
// check whether this map was already loaded:
if (!_maps.empty()) {
diff --git a/source/blender/freestyle/intern/stroke/Chain.cpp b/source/blender/freestyle/intern/stroke/Chain.cpp
index 3778727da37..b3f4d4547e9 100644
--- a/source/blender/freestyle/intern/stroke/Chain.cpp
+++ b/source/blender/freestyle/intern/stroke/Chain.cpp
@@ -120,7 +120,7 @@ void Chain::push_viewedge_front(ViewEdge *iViewEdge, bool orientation)
}
do {
current = (*v)->point2d();
- Curve::push_vertex_front((*v));
+ Curve::push_vertex_front(*v);
//_Length += (current - previous).norm();
previous = current;
if (orientation) {
diff --git a/source/blender/freestyle/intern/stroke/ChainingIterators.cpp b/source/blender/freestyle/intern/stroke/ChainingIterators.cpp
index 453eea58c93..87aabf71636 100644
--- a/source/blender/freestyle/intern/stroke/ChainingIterators.cpp
+++ b/source/blender/freestyle/intern/stroke/ChainingIterators.cpp
@@ -26,7 +26,7 @@ bool AdjacencyIterator::isIncoming() const
int AdjacencyIterator::increment()
{
++_internalIterator;
- while ((!_internalIterator.isEnd()) && (!isValid((*_internalIterator).first))) {
+ while (!_internalIterator.isEnd() && !isValid((*_internalIterator).first)) {
++_internalIterator;
}
return 0;
diff --git a/source/blender/freestyle/intern/stroke/ContextFunctions.cpp b/source/blender/freestyle/intern/stroke/ContextFunctions.cpp
index e50b5f0b242..cd37a5f893d 100644
--- a/source/blender/freestyle/intern/stroke/ContextFunctions.cpp
+++ b/source/blender/freestyle/intern/stroke/ContextFunctions.cpp
@@ -12,19 +12,21 @@
#include "../system/TimeStamp.h"
+#include "BLI_sys_types.h"
+
namespace Freestyle::ContextFunctions {
-unsigned GetTimeStampCF()
+uint GetTimeStampCF()
{
return TimeStamp::instance()->getTimeStamp();
}
-unsigned GetCanvasWidthCF()
+uint GetCanvasWidthCF()
{
return Canvas::getInstance()->width();
}
-unsigned GetCanvasHeightCF()
+uint GetCanvasHeightCF()
{
return Canvas::getInstance()->height();
}
@@ -34,24 +36,24 @@ BBox<Vec2i> GetBorderCF()
return Canvas::getInstance()->border();
}
-void LoadMapCF(const char *iFileName, const char *iMapName, unsigned iNbLevels, float iSigma)
+void LoadMapCF(const char *iFileName, const char *iMapName, uint iNbLevels, float iSigma)
{
return Canvas::getInstance()->loadMap(iFileName, iMapName, iNbLevels, iSigma);
}
-float ReadMapPixelCF(const char *iMapName, int level, unsigned x, unsigned y)
+float ReadMapPixelCF(const char *iMapName, int level, uint x, uint y)
{
Canvas *canvas = Canvas::getInstance();
return canvas->readMapPixel(iMapName, level, x, y);
}
-float ReadCompleteViewMapPixelCF(int level, unsigned x, unsigned y)
+float ReadCompleteViewMapPixelCF(int level, uint x, uint y)
{
SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap();
return svm->readCompleteViewMapPixel(level, x, y);
}
-float ReadDirectionalViewMapPixelCF(int iOrientation, int level, unsigned x, unsigned y)
+float ReadDirectionalViewMapPixelCF(int iOrientation, int level, uint x, uint y)
{
SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap();
return svm->readSteerableViewMapPixel(iOrientation, level, x, y);
diff --git a/source/blender/freestyle/intern/stroke/Operators.cpp b/source/blender/freestyle/intern/stroke/Operators.cpp
index ee9fa33285f..93524e6ebe5 100644
--- a/source/blender/freestyle/intern/stroke/Operators.cpp
+++ b/source/blender/freestyle/intern/stroke/Operators.cpp
@@ -14,6 +14,8 @@
#include "Stroke.h"
#include "StrokeIterators.h"
+#include "BLI_sys_types.h"
+
#include "BKE_global.h"
namespace Freestyle {
@@ -73,7 +75,7 @@ int Operators::chain(ViewEdgeInternal::ViewEdgeIterator &it,
return 0;
}
- unsigned id = 0;
+ uint id = 0;
ViewEdge *edge;
I1DContainer new_chains_set;
@@ -137,7 +139,7 @@ int Operators::chain(ViewEdgeInternal::ViewEdgeIterator &it, UnaryPredicate1D &p
return 0;
}
- unsigned id = 0;
+ uint id = 0;
Functions1D::IncrementChainingTimeStampF1D ts;
Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp() + 1);
ViewEdge *edge;
@@ -318,7 +320,7 @@ int Operators::bidirectionalChain(ChainingIterator &it, UnaryPredicate1D &pred)
return 0;
}
- unsigned id = 0;
+ uint id = 0;
Functions1D::IncrementChainingTimeStampF1D ts;
Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp() + 1);
ViewEdge *edge;
@@ -421,7 +423,7 @@ int Operators::bidirectionalChain(ChainingIterator &it)
return 0;
}
- unsigned id = 0;
+ uint id = 0;
Functions1D::IncrementChainingTimeStampF1D ts;
Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp() + 1);
ViewEdge *edge;
@@ -873,7 +875,7 @@ static int __recursiveSplit(Chain *_curve,
++it;
// real mean = 0.0f;
// soc unused - real variance = 0.0f;
- unsigned count = 0;
+ uint count = 0;
CurveInternal::CurvePointIterator next = it;
++next;
diff --git a/source/blender/freestyle/intern/stroke/Stroke.cpp b/source/blender/freestyle/intern/stroke/Stroke.cpp
index 101b89d720a..66a31d02a9b 100644
--- a/source/blender/freestyle/intern/stroke/Stroke.cpp
+++ b/source/blender/freestyle/intern/stroke/Stroke.cpp
@@ -486,11 +486,11 @@ void Stroke::setLength(float iLength)
float Stroke::ComputeSampling(int iNVertices)
{
- if (iNVertices <= (int)_Vertices.size()) { // soc
+ if (iNVertices <= int(_Vertices.size())) { // soc
return _sampling;
}
- float sampling = _Length / (float)(iNVertices - _Vertices.size() + 1);
+ float sampling = _Length / float(iNVertices - _Vertices.size() + 1);
return sampling;
}
@@ -542,8 +542,8 @@ int Stroke::Resample(int iNPoints)
Vec2r b((next)->getPoint());
Vec2r vec_tmp(b - a);
real norm_var = vec_tmp.norm();
- int numberOfPointsToAdd = (int)floor(NPointsToAdd * norm_var / _Length);
- float csampling = norm_var / (float)(numberOfPointsToAdd + 1);
+ int numberOfPointsToAdd = int(floor(NPointsToAdd * norm_var / _Length));
+ float csampling = norm_var / float(numberOfPointsToAdd + 1);
strokeSegments.emplace_back(it, next, norm_var, numberOfPointsToAdd, csampling);
N += numberOfPointsToAdd;
meanlength += norm_var;
@@ -551,7 +551,7 @@ int Stroke::Resample(int iNPoints)
++it;
++next;
}
- meanlength /= (float)nsegments;
+ meanlength /= float(nsegments);
// if we don't have enough points let's resample finer some segments
bool checkEveryone = false;
@@ -571,7 +571,7 @@ int Stroke::Resample(int iNPoints)
}
// resample
s->_n = s->_n + 1;
- s->_sampling = s->_length / (float)(s->_n + 1);
+ s->_sampling = s->_length / float(s->_n + 1);
s->_resampled = resampled = true;
N++;
if (N == NPointsToAdd) {
@@ -593,14 +593,14 @@ int Stroke::Resample(int iNPoints)
for (vector<StrokeSegment>::iterator s = strokeSegments.begin(), send = strokeSegments.end();
s != send;
++s) {
- newVertices.push_back(&(*(s->_begin)));
+ newVertices.push_back(&*(s->_begin));
if (s->_sampling < _sampling) {
_sampling = s->_sampling;
}
t = s->_sampling / s->_length;
for (int i = 0; i < s->_n; ++i) {
- newVertex = new StrokeVertex(&(*(s->_begin)), &(*(s->_end)), t);
+ newVertex = new StrokeVertex(&*(s->_begin), &*(s->_end), t);
newVertices.push_back(newVertex);
t += s->_sampling / s->_length;
}
diff --git a/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp b/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp
index 35ee41adbaf..095cb74d607 100644
--- a/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp
@@ -9,6 +9,8 @@
#include "../geometry/GeomUtils.h"
+#include "BLI_sys_types.h"
+
using namespace std;
namespace Freestyle {
@@ -69,12 +71,12 @@ void TextureManager::load()
_hasLoadedTextures = true;
}
-unsigned TextureManager::getBrushTextureIndex(string name, Stroke::MediumType iType)
+uint TextureManager::getBrushTextureIndex(string name, Stroke::MediumType iType)
{
BrushTexture bt(name, iType);
brushesMap::iterator b = _brushesMap.find(bt);
if (b == _brushesMap.end()) {
- unsigned texId = loadBrush(name, iType);
+ uint texId = loadBrush(name, iType);
_brushesMap[bt] = texId;
return texId;
// XXX!
diff --git a/source/blender/freestyle/intern/stroke/StrokeRep.cpp b/source/blender/freestyle/intern/stroke/StrokeRep.cpp
index e8ff46df731..89567d7e780 100644
--- a/source/blender/freestyle/intern/stroke/StrokeRep.cpp
+++ b/source/blender/freestyle/intern/stroke/StrokeRep.cpp
@@ -360,7 +360,7 @@ void Strip::createStrip(const vector<StrokeVertex *> &iStrokeVertices)
}
}
- if (i != 2 * (int)iStrokeVertices.size()) {
+ if (i != 2 * int(iStrokeVertices.size())) {
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "Warning: problem with stripe size\n";
}
@@ -837,11 +837,11 @@ void StrokeRep::create()
bool first = true;
bool end = false;
while (v != vend) {
- while ((v != vend) && (!(*v).attribute().isVisible())) {
+ while ((v != vend) && !(*v).attribute().isVisible()) {
++v;
first = false;
}
- while ((v != vend) && ((*v).attribute().isVisible())) {
+ while ((v != vend) && (*v).attribute().isVisible()) {
strip.push_back(&(*v));
++v;
}
@@ -852,7 +852,7 @@ void StrokeRep::create()
else {
end = true;
}
- if ((!strip.empty()) && (strip.size() > 1)) {
+ if (!strip.empty() && (strip.size() > 1)) {
_strips.push_back(new Strip(strip, _hasTex, first, end, _textureStep));
strip.clear();
}
diff --git a/source/blender/freestyle/intern/stroke/StrokeTesselator.cpp b/source/blender/freestyle/intern/stroke/StrokeTesselator.cpp
index 2dce6140c3f..07ba45b81ab 100644
--- a/source/blender/freestyle/intern/stroke/StrokeTesselator.cpp
+++ b/source/blender/freestyle/intern/stroke/StrokeTesselator.cpp
@@ -64,7 +64,7 @@ NodeGroup *StrokeTesselator::Tesselate(StrokeVertexIterator begin, StrokeVertexI
tshape->setFrsMaterial(_FrsMaterial);
for (StrokeVertexIterator c = begin, cend = end; c != cend; c++) {
- tshape->AddRep(Tesselate((*c)));
+ tshape->AddRep(Tesselate(*c));
}
return group;
diff --git a/source/blender/freestyle/intern/system/PseudoNoise.cpp b/source/blender/freestyle/intern/system/PseudoNoise.cpp
index ad2950c73a9..98115691f52 100644
--- a/source/blender/freestyle/intern/system/PseudoNoise.cpp
+++ b/source/blender/freestyle/intern/system/PseudoNoise.cpp
@@ -11,11 +11,11 @@
#include "PseudoNoise.h"
#include "RandGen.h"
-static int modf_to_index(Freestyle::real x, unsigned int range)
+static int modf_to_index(Freestyle::real x, uint range)
{
if (isfinite(x)) {
Freestyle::real tmp;
- int i = abs((int)(modf(x, &tmp) * range));
+ int i = abs(int(modf(x, &tmp) * range));
BLI_assert(i >= 0 && i < range);
return i;
}
@@ -30,7 +30,7 @@ real PseudoNoise::_values[];
void PseudoNoise::init(long seed)
{
RandGen::srand48(seed);
- for (unsigned int i = 0; i < NB_VALUE_NOISE; i++) {
+ for (uint i = 0; i < NB_VALUE_NOISE; i++) {
_values[i] = -1.0 + 2.0 * RandGen::drand48();
}
}
@@ -79,22 +79,22 @@ real PseudoNoise::smoothNoise(real x)
return (x0 * y0 + x1 * y1 + x2 * y2 + x3 * y3) / (y0 + y1 + y2 + y3);
}
-real PseudoNoise::turbulenceSmooth(real x, unsigned nbOctave)
+real PseudoNoise::turbulenceSmooth(real x, uint nbOctave)
{
real y = 0;
real k = 1.0;
- for (unsigned int i = 0; i < nbOctave; i++) {
+ for (uint i = 0; i < nbOctave; i++) {
y = y + k * smoothNoise(x * k);
k = k / 2.0;
}
return y;
}
-real PseudoNoise::turbulenceLinear(real x, unsigned nbOctave)
+real PseudoNoise::turbulenceLinear(real x, uint nbOctave)
{
real y = 0;
real k = 1.0;
- for (unsigned int i = 0; i < nbOctave; i++) {
+ for (uint i = 0; i < nbOctave; i++) {
y = y + k * linearNoise(x * k);
k = k / 2.0;
}
diff --git a/source/blender/freestyle/intern/system/RandGen.cpp b/source/blender/freestyle/intern/system/RandGen.cpp
index d18d53c767f..b2161480c74 100644
--- a/source/blender/freestyle/intern/system/RandGen.cpp
+++ b/source/blender/freestyle/intern/system/RandGen.cpp
@@ -7,6 +7,8 @@
#include "RandGen.h"
+#include "BLI_sys_types.h"
+
namespace Freestyle {
//
@@ -15,7 +17,7 @@ namespace Freestyle {
///////////////////////////////////////////////////////////////////////////////
#define N 16
-#define MASK ((unsigned)(1 << (N - 1)) + (1 << (N - 1)) - 1)
+#define MASK (uint(1 << (N - 1)) + (1 << (N - 1)) - 1)
#define X0 0x330E
#define X1 0xABCD
#define X2 0x1234
@@ -27,18 +29,18 @@ namespace Freestyle {
# define HI_BIT (1L << (2 * N - 1))
#endif
-#define LOW(x) ((unsigned)(x)&MASK)
+#define LOW(x) (uint(x) & MASK)
#define HIGH(x) LOW((x) >> N)
#define MUL(x, y, z) \
{ \
- long l = (long)(x) * (long)(y); \
+ long l = long(x) * long(y); \
(z)[0] = LOW(l); \
(z)[1] = HIGH(l); \
} \
((void)0)
-#define CARRY(x, y) ((unsigned long)((long)(x) + (long)(y)) > MASK)
+#define CARRY(x, y) (ulong(long(x) + long(y)) > MASK)
#define ADDEQU(x, y, z) (z = CARRY(x, (y)), x = LOW(x + (y)))
#define SET3(x, x0, x1, x2) ((x)[0] = (x0), (x)[1] = (x1), (x)[2] = (x2))
#if 0 // XXX, unused
@@ -70,17 +72,17 @@ namespace Freestyle {
}
#endif
-static unsigned x[3] = {
+static uint x[3] = {
X0,
X1,
X2,
};
-static unsigned a[3] = {
+static uint a[3] = {
A0,
A1,
A2,
};
-static unsigned c = C;
+static uint c = C;
//
// Methods implementation
@@ -101,7 +103,7 @@ void RandGen::srand48(long seedval)
void RandGen::next()
{
- unsigned p[2], q[2], r[2], carry0, carry1;
+ uint p[2], q[2], r[2], carry0, carry1;
MUL(a[0], x[0], p);
ADDEQU(p[0], c, carry0);
diff --git a/source/blender/freestyle/intern/system/StringUtils.cpp b/source/blender/freestyle/intern/system/StringUtils.cpp
index 1ecd5a2126d..fbd85815da1 100644
--- a/source/blender/freestyle/intern/system/StringUtils.cpp
+++ b/source/blender/freestyle/intern/system/StringUtils.cpp
@@ -10,6 +10,8 @@
#include "StringUtils.h"
#include "FreestyleConfig.h"
+#include "BLI_sys_types.h"
+
namespace Freestyle::StringUtils {
void getPathName(const string &path, const string &base, vector<string> &pathnames)
@@ -17,13 +19,13 @@ void getPathName(const string &path, const string &base, vector<string> &pathnam
string dir;
string res;
char cleaned[FILE_MAX];
- unsigned size = path.size();
+ uint size = path.size();
pathnames.push_back(base);
- for (unsigned int pos = 0, sep = path.find(Config::PATH_SEP, pos); pos < size;
+ for (uint pos = 0, sep = path.find(Config::PATH_SEP, pos); pos < size;
pos = sep + 1, sep = path.find(Config::PATH_SEP, pos)) {
- if (sep == (unsigned)string::npos) {
+ if (sep == uint(string::npos)) {
sep = size;
}
diff --git a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp
index ad2ebb737a5..f4619e6e85f 100644
--- a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp
+++ b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp
@@ -7,13 +7,15 @@
#include "ArbitraryGridDensityProvider.h"
+#include "BLI_sys_types.h"
+
#include "BKE_global.h"
namespace Freestyle {
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource &source,
const real proscenium[4],
- unsigned numCells)
+ uint numCells)
: GridDensityProvider(source), numCells(numCells)
{
initialize(proscenium);
@@ -22,7 +24,7 @@ ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource &sourc
ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource &source,
const BBox<Vec3r> &bbox,
const GridHelpers::Transform &transform,
- unsigned numCells)
+ uint numCells)
: GridDensityProvider(source), numCells(numCells)
{
real proscenium[4];
@@ -31,8 +33,7 @@ ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource &sourc
initialize(proscenium);
}
-ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource &source,
- unsigned numCells)
+ArbitraryGridDensityProvider::ArbitraryGridDensityProvider(OccluderSource &source, uint numCells)
: GridDensityProvider(source), numCells(numCells)
{
real proscenium[4];
@@ -76,7 +77,7 @@ void ArbitraryGridDensityProvider::initialize(const real proscenium[4])
_cellOrigin[1] = ((proscenium[2] + proscenium[3]) / 2.0) - (_cellsY / 2.0) * _cellSize;
}
-ArbitraryGridDensityProviderFactory::ArbitraryGridDensityProviderFactory(unsigned numCells)
+ArbitraryGridDensityProviderFactory::ArbitraryGridDensityProviderFactory(uint numCells)
: numCells(numCells)
{
}
diff --git a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp
index 6b66ce17373..b984d5dba29 100644
--- a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp
+++ b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp
@@ -7,6 +7,8 @@
#include "AverageAreaGridDensityProvider.h"
+#include "BLI_sys_types.h"
+
#include "BKE_global.h"
namespace Freestyle {
@@ -48,7 +50,7 @@ void AverageAreaGridDensityProvider::initialize(const real proscenium[4], real s
float prosceniumHeight = (proscenium[3] - proscenium[2]);
real cellArea = 0.0;
- unsigned numFaces = 0;
+ uint numFaces = 0;
for (source.begin(); source.isValid(); source.next()) {
Polygon3r &poly(source.getGridSpacePolygon());
Vec3r min, max;
@@ -66,7 +68,7 @@ void AverageAreaGridDensityProvider::initialize(const real proscenium[4], real s
}
_cellSize = sqrt(cellArea);
- unsigned maxCells = 931; // * 1.1 = 1024
+ uint maxCells = 931; // * 1.1 = 1024
if (std::max(prosceniumWidth, prosceniumHeight) / _cellSize > maxCells) {
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "Scene-dependent cell size (" << _cellSize << " square) is too small." << endl;
diff --git a/source/blender/freestyle/intern/view_map/BoxGrid.cpp b/source/blender/freestyle/intern/view_map/BoxGrid.cpp
index c8a6f0a0a3e..4464aab6419 100644
--- a/source/blender/freestyle/intern/view_map/BoxGrid.cpp
+++ b/source/blender/freestyle/intern/view_map/BoxGrid.cpp
@@ -10,6 +10,8 @@
#include "BoxGrid.h"
+#include "BLI_sys_types.h"
+
#include "BKE_global.h"
using namespace std;
@@ -127,7 +129,7 @@ void BoxGrid::assignCells(OccluderSource & /*source*/,
++f) {
if ((*f)->isInImage()) {
Vec3r point = transform((*f)->center3d());
- unsigned int i, j;
+ uint i, j;
getCellCoordinates(point, i, j);
if (_cells[i * _cellsY + j] == nullptr) {
// This is an uninitialized cell
@@ -149,8 +151,8 @@ void BoxGrid::assignCells(OccluderSource & /*source*/,
void BoxGrid::distributePolygons(OccluderSource &source)
{
- unsigned long nFaces = 0;
- unsigned long nKeptFaces = 0;
+ ulong nFaces = 0;
+ ulong nKeptFaces = 0;
for (source.begin(); source.isValid(); source.next()) {
OccluderData *occluder = nullptr;
@@ -186,15 +188,15 @@ void BoxGrid::reorganizeCells()
}
}
-void BoxGrid::getCellCoordinates(const Vec3r &point, unsigned &x, unsigned &y)
+void BoxGrid::getCellCoordinates(const Vec3r &point, uint &x, uint &y)
{
- x = min(_cellsX - 1, (unsigned)floor(max((double)0.0f, point[0] - _cellOrigin[0]) / _cellSize));
- y = min(_cellsY - 1, (unsigned)floor(max((double)0.0f, point[1] - _cellOrigin[1]) / _cellSize));
+ x = min(_cellsX - 1, uint(floor(max(double(0.0f), point[0] - _cellOrigin[0]) / _cellSize)));
+ y = min(_cellsY - 1, uint(floor(max(double(0.0f), point[1] - _cellOrigin[1]) / _cellSize)));
}
BoxGrid::Cell *BoxGrid::findCell(const Vec3r &point)
{
- unsigned int x, y;
+ uint x, y;
getCellCoordinates(point, x, y);
return _cells[x * _cellsY + y];
}
diff --git a/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp b/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp
index 8ae6bec2fb2..c1afb6de881 100644
--- a/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp
+++ b/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp
@@ -9,6 +9,8 @@
#include "../geometry/GridHelpers.h"
+#include "BLI_sys_types.h"
+
#include "BKE_global.h"
namespace Freestyle {
@@ -56,7 +58,7 @@ bool CulledOccluderSource::next()
void CulledOccluderSource::getOccluderProscenium(real proscenium[4])
{
- for (unsigned int i = 0; i < 4; ++i) {
+ for (uint i = 0; i < 4; ++i) {
proscenium[i] = gridSpaceOccluderProscenium[i];
}
}
diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
index cd36e4b0fe9..b7e805f8767 100644
--- a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
+++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
@@ -12,6 +12,8 @@
#include "../geometry/GeomUtils.h"
#include "../geometry/normal_cycle.h"
+#include "BLI_sys_types.h"
+
#include "BKE_global.h"
namespace Freestyle {
@@ -318,8 +320,8 @@ void FEdgeXDetector::ProcessSilhouetteEdge(WXEdge *iEdge)
WXFace *fA = (WXFace *)iEdge->GetaOEdge()->GetaFace();
WXFace *fB = (WXFace *)iEdge->GetaOEdge()->GetbFace();
- if ((fA->front()) ^
- (fB->front())) { // fA->visible XOR fB->visible (true if one is 0 and the other is 1)
+ if (fA->front() ^
+ fB->front()) { // fA->visible XOR fB->visible (true if one is 0 and the other is 1)
// The only edges we want to set as silhouette edges in this way are the ones with 2 different
// normals for 1 vertex for these two faces
//--------------------
@@ -420,8 +422,8 @@ void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace)
WXFaceLayer *flayer = new WXFaceLayer(iFace, Nature::RIDGE | Nature::VALLEY, false);
iFace->AddSmoothLayer(flayer);
- unsigned int numVertices = iFace->numberOfVertices();
- for (unsigned int i = 0; i < numVertices; ++i) {
+ uint numVertices = iFace->numberOfVertices();
+ for (uint i = 0; i < numVertices; ++i) {
WVertex *wv = iFace->GetVertex(i);
WXVertex *wxv = dynamic_cast<WXVertex *>(wv);
flayer->PushDotP(wxv->curvatures()->K1);
@@ -570,8 +572,8 @@ void FEdgeXDetector::ProcessSuggestiveContourFace(WXFace *iFace)
WXFaceLayer *faceLayer = new WXFaceLayer(iFace, Nature::SUGGESTIVE_CONTOUR, true);
iFace->AddSmoothLayer(faceLayer);
- unsigned int numVertices = iFace->numberOfVertices();
- for (unsigned int i = 0; i < numVertices; ++i) {
+ uint numVertices = iFace->numberOfVertices();
+ for (uint i = 0; i < numVertices; ++i) {
WVertex *wv = iFace->GetVertex(i);
WXVertex *wxv = dynamic_cast<WXVertex *>(wv);
faceLayer->PushDotP(wxv->curvatures()->Kr);
@@ -618,7 +620,7 @@ void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace)
// Compute the derivative value at each vertex of the face, and add it in a vector.
vector<real> kr_derivatives;
- unsigned vertices_nb = iFace->numberOfVertices();
+ uint vertices_nb = iFace->numberOfVertices();
WXVertex *v, *opposite_vertex_a, *opposite_vertex_b;
WXFace *wxf;
WOEdge *opposite_edge;
@@ -626,8 +628,8 @@ void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace)
GeomUtils::intersection_test res;
real kr(0), kr1(0), kr2(0), t;
- for (unsigned int i = 0; i < vertices_nb; ++i) {
- v = (WXVertex *)(iFace->GetVertex(i));
+ for (uint i = 0; i < vertices_nb; ++i) {
+ v = (WXVertex *)iFace->GetVertex(i);
// v is a singular vertex, skip it.
if (v->isBoundary()) {
diff --git a/source/blender/freestyle/intern/view_map/Functions0D.cpp b/source/blender/freestyle/intern/view_map/Functions0D.cpp
index a461f368859..aaafc5c884a 100644
--- a/source/blender/freestyle/intern/view_map/Functions0D.cpp
+++ b/source/blender/freestyle/intern/view_map/Functions0D.cpp
@@ -8,6 +8,8 @@
#include "Functions0D.h"
#include "ViewMap.h"
+#include "BLI_sys_types.h"
+
#include "BKE_global.h"
using namespace std;
@@ -105,14 +107,14 @@ void getOccludersF0D(Interface0DIterator &it, set<ViewShape *> &oOccluders)
occluder_container::const_iterator oitend = ve1->occluders_end();
for (; oit != oitend; ++oit) {
- oOccluders.insert((*oit));
+ oOccluders.insert(*oit);
}
if (ve2 != nullptr) {
oit = ve2->occluders_begin();
oitend = ve2->occluders_end();
for (; oit != oitend; ++oit) {
- oOccluders.insert((*oit));
+ oOccluders.insert(*oit);
}
}
}
@@ -202,12 +204,12 @@ int Curvature2DAngleF0D::operator()(Interface0DIterator &iter)
{
Interface0DIterator tmp1 = iter, tmp2 = iter;
++tmp2;
- unsigned count = 1;
- while ((!tmp1.isBegin()) && (count < 3)) {
+ uint count = 1;
+ while (!tmp1.isBegin() && (count < 3)) {
--tmp1;
++count;
}
- while ((!tmp2.isEnd()) && (count < 3)) {
+ while (!tmp2.isEnd() && (count < 3)) {
++tmp2;
++count;
}
@@ -319,7 +321,7 @@ int QuantitativeInvisibilityF0D::operator()(Interface0DIterator &iter)
{
ViewEdge *ve1, *ve2;
getViewEdges(iter, ve1, ve2);
- unsigned int qi1, qi2;
+ uint qi1, qi2;
qi1 = ve1->qi();
if (ve2 != nullptr) {
qi2 = ve2->qi();
@@ -355,7 +357,7 @@ int GetOccludersF0D::operator()(Interface0DIterator &iter)
// vsOccluders.insert(vsOccluders.begin(), occluders.begin(), occluders.end());
for (set<ViewShape *>::iterator it = occluders.begin(), itend = occluders.end(); it != itend;
++it) {
- result.push_back((*it));
+ result.push_back(*it);
}
return 0;
}
diff --git a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
index f5a6a5ed5a9..40fa8387637 100644
--- a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
+++ b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
@@ -7,10 +7,12 @@
#include "HeuristicGridDensityProviderFactory.h"
+#include "BLI_sys_types.h"
+
namespace Freestyle {
HeuristicGridDensityProviderFactory::HeuristicGridDensityProviderFactory(real sizeFactor,
- unsigned numFaces)
+ uint numFaces)
: sizeFactor(sizeFactor), numFaces(numFaces)
{
}
diff --git a/source/blender/freestyle/intern/view_map/Interface0D.cpp b/source/blender/freestyle/intern/view_map/Interface0D.cpp
index 8c5e762d147..a7e767cc551 100644
--- a/source/blender/freestyle/intern/view_map/Interface0D.cpp
+++ b/source/blender/freestyle/intern/view_map/Interface0D.cpp
@@ -62,7 +62,7 @@ Geometry::Vec2r Interface0D::getPoint2D() const
return 0;
}
-FEdge *Interface0D::getFEdge(Interface0D &UNUSED(element))
+FEdge *Interface0D::getFEdge(Interface0D & /*element*/)
{
PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden");
return nullptr;
diff --git a/source/blender/freestyle/intern/view_map/OccluderSource.cpp b/source/blender/freestyle/intern/view_map/OccluderSource.cpp
index 378b017b504..7ac5de9abbc 100644
--- a/source/blender/freestyle/intern/view_map/OccluderSource.cpp
+++ b/source/blender/freestyle/intern/view_map/OccluderSource.cpp
@@ -9,6 +9,8 @@
#include "OccluderSource.h"
+#include "BLI_sys_types.h"
+
#include "BKE_global.h"
namespace Freestyle {
@@ -114,7 +116,7 @@ void OccluderSource::getOccluderProscenium(real proscenium[4])
real OccluderSource::averageOccluderArea()
{
real area = 0.0;
- unsigned numFaces = 0;
+ uint numFaces = 0;
for (begin(); isValid(); next()) {
Vec3r min, max;
cachedPolygon.getBBox(min, max);
diff --git a/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp b/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp
index 0fde521d315..af6924eea6e 100644
--- a/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp
+++ b/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp
@@ -7,13 +7,15 @@
#include "Pow23GridDensityProvider.h"
+#include "BLI_sys_types.h"
+
#include "BKE_global.h"
namespace Freestyle {
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource &source,
const real proscenium[4],
- unsigned numFaces)
+ uint numFaces)
: GridDensityProvider(source), numFaces(numFaces)
{
initialize(proscenium);
@@ -22,7 +24,7 @@ Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource &source,
Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource &source,
const BBox<Vec3r> &bbox,
const GridHelpers::Transform &transform,
- unsigned numFaces)
+ uint numFaces)
: GridDensityProvider(source), numFaces(numFaces)
{
real proscenium[4];
@@ -31,7 +33,7 @@ Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource &source,
initialize(proscenium);
}
-Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource &source, unsigned numFaces)
+Pow23GridDensityProvider::Pow23GridDensityProvider(OccluderSource &source, uint numFaces)
: GridDensityProvider(source), numFaces(numFaces)
{
real proscenium[4];
@@ -75,7 +77,7 @@ void Pow23GridDensityProvider::initialize(const real proscenium[4])
_cellOrigin[1] = ((proscenium[2] + proscenium[3]) / 2.0) - (_cellsY / 2.0) * _cellSize;
}
-Pow23GridDensityProviderFactory::Pow23GridDensityProviderFactory(unsigned numFaces)
+Pow23GridDensityProviderFactory::Pow23GridDensityProviderFactory(uint numFaces)
: numFaces(numFaces)
{
}
diff --git a/source/blender/freestyle/intern/view_map/Silhouette.cpp b/source/blender/freestyle/intern/view_map/Silhouette.cpp
index 54e0626a7af..2398e82aca7 100644
--- a/source/blender/freestyle/intern/view_map/Silhouette.cpp
+++ b/source/blender/freestyle/intern/view_map/Silhouette.cpp
@@ -297,7 +297,7 @@ real FEdge::z_discontinuity() const
z_discontinuity_functor<SVertex> _functor;
Evaluate<SVertex, z_discontinuity_functor<SVertex>>(&_functor, iCombination, result);
#endif
- Vec3r middle((_VertexB->point3d() - _VertexA->point3d()));
+ Vec3r middle(_VertexB->point3d() - _VertexA->point3d());
middle /= 2;
Vec3r disc_vec(middle - _occludeeIntersection);
real res = disc_vec.norm() / bboxsize;
diff --git a/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp
index dfe6bfdd0cf..ce4c8fcd453 100644
--- a/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp
+++ b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp
@@ -14,6 +14,8 @@
#include "../geometry/GeomUtils.h"
+#include "BLI_sys_types.h"
+
#include "BKE_global.h"
using namespace std;
@@ -66,7 +68,7 @@ void SilhouetteGeomEngine::setTransform(const real iModelViewMatrix[4][4],
const int iViewport[4],
real iFocal)
{
- unsigned int i, j;
+ uint i, j;
_translation[0] = iModelViewMatrix[3][0];
_translation[1] = iModelViewMatrix[3][1];
_translation[2] = iModelViewMatrix[3][2];
@@ -88,7 +90,7 @@ void SilhouetteGeomEngine::setTransform(const real iModelViewMatrix[4][4],
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
_transform[i][j] = 0;
- for (unsigned int k = 0; k < 4; k++) {
+ for (uint k = 0; k < 4; k++) {
_transform[i][j] += _projectionMatrix[i][k] * _modelViewMatrix[k][j];
}
}
diff --git a/source/blender/freestyle/intern/view_map/SphericalGrid.cpp b/source/blender/freestyle/intern/view_map/SphericalGrid.cpp
index 2a7637eb350..bb4dbd17f70 100644
--- a/source/blender/freestyle/intern/view_map/SphericalGrid.cpp
+++ b/source/blender/freestyle/intern/view_map/SphericalGrid.cpp
@@ -10,6 +10,8 @@
#include "SphericalGrid.h"
+#include "BLI_sys_types.h"
+
#include "BKE_global.h"
using namespace std;
@@ -124,7 +126,7 @@ void SphericalGrid::assignCells(OccluderSource & /*source*/,
++f) {
if ((*f)->isInImage()) {
Vec3r point = SphericalGrid::Transform::sphericalProjection((*f)->center3d());
- unsigned i, j;
+ uint i, j;
getCellCoordinates(point, i, j);
if (_cells[i * _cellsY + j] == nullptr) {
// This is an uninitialized cell
@@ -146,8 +148,8 @@ void SphericalGrid::assignCells(OccluderSource & /*source*/,
void SphericalGrid::distributePolygons(OccluderSource &source)
{
- unsigned long nFaces = 0;
- unsigned long nKeptFaces = 0;
+ ulong nFaces = 0;
+ ulong nKeptFaces = 0;
for (source.begin(); source.isValid(); source.next()) {
OccluderData *occluder = nullptr;
@@ -182,15 +184,15 @@ void SphericalGrid::reorganizeCells()
}
}
-void SphericalGrid::getCellCoordinates(const Vec3r &point, unsigned &x, unsigned &y)
+void SphericalGrid::getCellCoordinates(const Vec3r &point, uint &x, uint &y)
{
- x = min(_cellsX - 1, (unsigned)floor(max((double)0.0f, point[0] - _cellOrigin[0]) / _cellSize));
- y = min(_cellsY - 1, (unsigned)floor(max((double)0.0f, point[1] - _cellOrigin[1]) / _cellSize));
+ x = min(_cellsX - 1, uint(floor(max(double(0.0f), point[0] - _cellOrigin[0]) / _cellSize)));
+ y = min(_cellsY - 1, uint(floor(max(double(0.0f), point[1] - _cellOrigin[1]) / _cellSize)));
}
SphericalGrid::Cell *SphericalGrid::findCell(const Vec3r &point)
{
- unsigned x, y;
+ uint x, y;
getCellCoordinates(point, x, y);
return _cells[x * _cellsY + y];
}
diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
index 1211b55e8e1..20472599835 100644
--- a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
+++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
@@ -16,8 +16,10 @@
#include "../image/Image.h"
#include "../image/ImagePyramid.h"
-#include "BKE_global.h"
#include "BLI_math.h"
+#include "BLI_sys_types.h"
+
+#include "BKE_global.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -26,13 +28,13 @@ namespace Freestyle {
using namespace Geometry;
-SteerableViewMap::SteerableViewMap(unsigned int nbOrientations)
+SteerableViewMap::SteerableViewMap(uint nbOrientations)
{
_nbOrientations = nbOrientations;
- _bound = cos(M_PI / (float)_nbOrientations);
- for (unsigned int i = 0; i < _nbOrientations; ++i) {
- _directions.emplace_back(cos((float)i * M_PI / (float)_nbOrientations),
- sin((float)i * M_PI / (float)_nbOrientations));
+ _bound = cos(M_PI / float(_nbOrientations));
+ for (uint i = 0; i < _nbOrientations; ++i) {
+ _directions.emplace_back(cos(float(i) * M_PI / float(_nbOrientations)),
+ sin(float(i) * M_PI / float(_nbOrientations)));
}
Build();
}
@@ -47,7 +49,7 @@ void SteerableViewMap::Build()
SteerableViewMap::SteerableViewMap(const SteerableViewMap &iBrother)
{
_nbOrientations = iBrother._nbOrientations;
- unsigned int i;
+ uint i;
_bound = iBrother._bound;
_directions = iBrother._directions;
_mapping = iBrother._mapping;
@@ -66,7 +68,7 @@ SteerableViewMap::~SteerableViewMap()
void SteerableViewMap::Clear()
{
- unsigned int i;
+ uint i;
if (_imagesPyramids) {
for (i = 0; i <= _nbOrientations; ++i) {
if (_imagesPyramids[i]) {
@@ -77,8 +79,7 @@ void SteerableViewMap::Clear()
_imagesPyramids = nullptr;
}
if (!_mapping.empty()) {
- for (map<unsigned int, double *>::iterator m = _mapping.begin(), mend = _mapping.end();
- m != mend;
+ for (map<uint, double *>::iterator m = _mapping.begin(), mend = _mapping.end(); m != mend;
++m) {
delete[](*m).second;
}
@@ -92,7 +93,7 @@ void SteerableViewMap::Reset()
Build();
}
-double SteerableViewMap::ComputeWeight(const Vec2d &dir, unsigned i)
+double SteerableViewMap::ComputeWeight(const Vec2d &dir, uint i)
{
double dotp = fabs(dir * _directions[i]);
if (dotp < _bound) {
@@ -102,14 +103,14 @@ double SteerableViewMap::ComputeWeight(const Vec2d &dir, unsigned i)
dotp = 1.0;
}
- return cos((float)_nbOrientations / 2.0 * acos(dotp));
+ return cos(float(_nbOrientations) / 2.0 * acos(dotp));
}
double *SteerableViewMap::AddFEdge(FEdge *iFEdge)
{
- unsigned i;
- unsigned id = iFEdge->getId().getFirst();
- map<unsigned int, double *>::iterator o = _mapping.find(id);
+ uint i;
+ uint id = iFEdge->getId().getFirst();
+ map<uint, double *>::iterator o = _mapping.find(id);
if (o != _mapping.end()) {
return (*o).second;
}
@@ -132,7 +133,7 @@ double *SteerableViewMap::AddFEdge(FEdge *iFEdge)
return res;
}
-unsigned SteerableViewMap::getSVMNumber(Vec2f dir)
+uint SteerableViewMap::getSVMNumber(Vec2f dir)
{
// soc unsigned res = 0;
real norm = dir.norm();
@@ -141,8 +142,8 @@ unsigned SteerableViewMap::getSVMNumber(Vec2f dir)
}
dir /= norm;
double maxw = 0.0f;
- unsigned winner = _nbOrientations + 1;
- for (unsigned int i = 0; i < _nbOrientations; ++i) {
+ uint winner = _nbOrientations + 1;
+ for (uint i = 0; i < _nbOrientations; ++i) {
double w = ComputeWeight(dir, i);
if (w > maxw) {
maxw = w;
@@ -152,14 +153,14 @@ unsigned SteerableViewMap::getSVMNumber(Vec2f dir)
return winner;
}
-unsigned SteerableViewMap::getSVMNumber(unsigned id)
+uint SteerableViewMap::getSVMNumber(uint id)
{
- map<unsigned int, double *>::iterator o = _mapping.find(id);
+ map<uint, double *>::iterator o = _mapping.find(id);
if (o != _mapping.end()) {
double *wvalues = (*o).second;
double maxw = 0.0;
- unsigned winner = _nbOrientations + 1;
- for (unsigned i = 0; i < _nbOrientations; ++i) {
+ uint winner = _nbOrientations + 1;
+ for (uint i = 0; i < _nbOrientations; ++i) {
double w = wvalues[i];
if (w > maxw) {
maxw = w;
@@ -173,10 +174,10 @@ unsigned SteerableViewMap::getSVMNumber(unsigned id)
void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases,
bool copy,
- unsigned iNbLevels,
+ uint iNbLevels,
float iSigma)
{
- for (unsigned int i = 0; i <= _nbOrientations; ++i) {
+ for (uint i = 0; i <= _nbOrientations; ++i) {
ImagePyramid *svm = (_imagesPyramids)[i];
delete svm;
if (copy) {
@@ -189,7 +190,7 @@ void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases,
}
}
-float SteerableViewMap::readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y)
+float SteerableViewMap::readSteerableViewMapPixel(uint iOrientation, int iLevel, int x, int y)
{
ImagePyramid *pyramid = _imagesPyramids[iOrientation];
if (!pyramid) {
@@ -215,7 +216,7 @@ float SteerableViewMap::readCompleteViewMapPixel(int iLevel, int x, int y)
return readSteerableViewMapPixel(_nbOrientations, iLevel, x, y);
}
-unsigned int SteerableViewMap::getNumberOfPyramidLevels() const
+uint SteerableViewMap::getNumberOfPyramidLevels() const
{
if (_imagesPyramids[0]) {
return _imagesPyramids[0]->getNumberOfLevels();
@@ -225,7 +226,7 @@ unsigned int SteerableViewMap::getNumberOfPyramidLevels() const
void SteerableViewMap::saveSteerableViewMap() const
{
- for (unsigned int i = 0; i <= _nbOrientations; ++i) {
+ for (uint i = 0; i <= _nbOrientations; ++i) {
if (_imagesPyramids[i] == nullptr) {
cerr << "SteerableViewMap warning: orientation " << i
<< " of steerable View Map whas not been computed yet" << endl;
@@ -247,7 +248,7 @@ void SteerableViewMap::saveSteerableViewMap() const
for (int y = 0; y < oh; ++y) { // soc
for (int x = 0; x < ow; ++x) { // soc
- int c = (int)(coeff * _imagesPyramids[i]->pixel(x, y, j));
+ int c = int(coeff * _imagesPyramids[i]->pixel(x, y, j));
if (c > 255) {
c = 255;
}
diff --git a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp
index 81e7abf6d5c..fcb157a4e60 100644
--- a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp
@@ -13,6 +13,8 @@
#include "../winged_edge/WXEdge.h"
+#include "BLI_sys_types.h"
+
using namespace std;
namespace Freestyle {
@@ -57,7 +59,7 @@ void ViewEdgeXBuilder::BuildViewEdges(WXShape *iWShape,
WXFace *wxf;
for (wf = wfaces.begin(), wfend = wfaces.end(); wf != wfend; wf++) {
wxf = dynamic_cast<WXFace *>(*wf);
- if (false == ((wxf))->hasSmoothEdges()) { // does it contain at least one smooth edge ?
+ if (false == (wxf)->hasSmoothEdges()) { // does it contain at least one smooth edge ?
continue;
}
// parse all smooth layers:
@@ -68,7 +70,7 @@ void ViewEdgeXBuilder::BuildViewEdges(WXShape *iWShape,
if (!(*sl)->hasSmoothEdge()) {
continue;
}
- if (stopSmoothViewEdge((*sl))) { // has it been parsed already ?
+ if (stopSmoothViewEdge(*sl)) { // has it been parsed already ?
continue;
}
// here we know that we're dealing with a face layer that has not been processed yet and that
@@ -128,7 +130,7 @@ ViewEdge *ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer &iFaceLayer)
// bidirectional chaining.
// first direction
list<OWXFaceLayer> facesChain;
- unsigned size = 0;
+ uint size = 0;
while (!stopSmoothViewEdge(currentFace.fl)) {
facesChain.push_back(currentFace);
++size;
@@ -210,7 +212,7 @@ ViewEdge *ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge &iWEdge)
ViewEdge *newVEdge = new ViewEdge;
newVEdge->setId(_currentViewId);
++_currentViewId;
- unsigned size = 0;
+ uint size = 0;
_pCurrentVShape->AddEdge(newVEdge);
@@ -350,7 +352,7 @@ OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer &iFaceLayer)
vector<WXFaceLayer *> sameNatureLayers;
nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
// don't know how to deal with several edges of same nature on a single face
- if ((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) {
+ if (sameNatureLayers.empty() || (sameNatureLayers.size() != 1)) {
return OWXFaceLayer(nullptr, true);
}
@@ -431,7 +433,7 @@ OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer &iFaceLa
vector<WXFaceLayer *> sameNatureLayers;
previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
// don't know how to deal with several edges of same nature on a single face
- if ((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) {
+ if (sameNatureLayers.empty() || (sameNatureLayers.size() != 1)) {
return OWXFaceLayer(nullptr, true);
}
@@ -685,26 +687,26 @@ FEdge *ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge &iwe)
// get the faces normals and the material indices
Vec3r normalA, normalB;
- unsigned matA(0), matB(0);
+ uint matA(0), matB(0);
bool faceMarkA = false, faceMarkB = false;
if (iwe.order) {
- normalB = (iwe.e->GetbFace()->GetNormal());
- matB = (iwe.e->GetbFace()->frs_materialIndex());
- faceMarkB = (iwe.e->GetbFace()->GetMark());
+ normalB = iwe.e->GetbFace()->GetNormal();
+ matB = iwe.e->GetbFace()->frs_materialIndex();
+ faceMarkB = iwe.e->GetbFace()->GetMark();
if (!(iwe.e->nature() & Nature::BORDER)) {
- normalA = (iwe.e->GetaFace()->GetNormal());
- matA = (iwe.e->GetaFace()->frs_materialIndex());
- faceMarkA = (iwe.e->GetaFace()->GetMark());
+ normalA = iwe.e->GetaFace()->GetNormal();
+ matA = iwe.e->GetaFace()->frs_materialIndex();
+ faceMarkA = iwe.e->GetaFace()->GetMark();
}
}
else {
- normalA = (iwe.e->GetbFace()->GetNormal());
- matA = (iwe.e->GetbFace()->frs_materialIndex());
- faceMarkA = (iwe.e->GetbFace()->GetMark());
+ normalA = iwe.e->GetbFace()->GetNormal();
+ matA = iwe.e->GetbFace()->frs_materialIndex();
+ faceMarkA = iwe.e->GetbFace()->GetMark();
if (!(iwe.e->nature() & Nature::BORDER)) {
- normalB = (iwe.e->GetaFace()->GetNormal());
- matB = (iwe.e->GetaFace()->frs_materialIndex());
- faceMarkB = (iwe.e->GetaFace()->GetMark());
+ normalB = iwe.e->GetaFace()->GetNormal();
+ matB = iwe.e->GetaFace()->frs_materialIndex();
+ faceMarkB = iwe.e->GetaFace()->GetMark();
}
}
// Creates the corresponding feature edge
diff --git a/source/blender/freestyle/intern/view_map/ViewMap.cpp b/source/blender/freestyle/intern/view_map/ViewMap.cpp
index d918cfec2ae..09432aa4ac7 100644
--- a/source/blender/freestyle/intern/view_map/ViewMap.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMap.cpp
@@ -13,6 +13,8 @@
#include "../geometry/GeomUtils.h"
+#include "BLI_sys_types.h"
+
namespace Freestyle {
/**********************************/
@@ -73,7 +75,7 @@ void ViewMap::Clean()
}
}
-ViewShape *ViewMap::viewShape(unsigned id)
+ViewShape *ViewMap::viewShape(uint id)
{
int index = _shapeIdToIndex[id];
return _VShapes[index];
@@ -770,7 +772,7 @@ ViewShape::~ViewShape()
{
_Vertices.clear();
- if (!(_Edges.empty())) {
+ if (!_Edges.empty()) {
for (vector<ViewEdge *>::iterator e = _Edges.begin(), eend = _Edges.end(); e != eend; e++) {
delete (*e);
}
diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
index 5642a80e77f..9c2919b0ca8 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
@@ -24,6 +24,8 @@
#include "../winged_edge/WFillGrid.h"
+#include "BLI_sys_types.h"
+
#include "BKE_global.h"
namespace Freestyle {
@@ -73,7 +75,7 @@ static void findOccludee(FEdge *fe,
#endif
oface = occluders.getWFace();
Polygon3r *p = occluders.getCameraSpacePolygon();
- real d = -((p->getVertices())[0] * p->getNormal());
+ real d = -(p->getVertices()[0] * p->getNormal());
real t, t_u, t_v;
if (nullptr != face) {
@@ -286,7 +288,7 @@ static int computeVisibility(ViewMap *viewMap,
<< ", norm: " << p1.getNormal() << endl;
}
#else
- real d = -((p->getVertices())[0] * p->getNormal());
+ real d = -(p->getVertices()[0] * p->getNormal());
#endif
if (face) {
@@ -430,12 +432,12 @@ static void computeCumulativeVisibility(ViewMap *ioViewMap,
int nSamples = 0;
vector<WFace *> wFaces;
WFace *wFace = nullptr;
- unsigned count = 0;
- unsigned count_step = (unsigned)ceil(0.01f * vedges.size());
- unsigned tmpQI = 0;
- unsigned qiClasses[256];
- unsigned maxIndex, maxCard;
- unsigned qiMajority;
+ uint count = 0;
+ uint count_step = uint(ceil(0.01f * vedges.size()));
+ uint tmpQI = 0;
+ uint qiClasses[256];
+ uint maxIndex, maxCard;
+ uint qiMajority;
for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
if (iRenderMonitor) {
if (iRenderMonitor->testBreak()) {
@@ -445,7 +447,7 @@ static void computeCumulativeVisibility(ViewMap *ioViewMap,
stringstream ss;
ss << "Freestyle: Visibility computations " << (100 * count / vedges.size()) << "%";
iRenderMonitor->setInfo(ss.str());
- iRenderMonitor->progress((float)count / vedges.size());
+ iRenderMonitor->progress(float(count) / vedges.size());
}
count++;
}
@@ -582,7 +584,7 @@ static void computeCumulativeVisibility(ViewMap *ioViewMap,
// ViewEdge
// qi --
// Find the minimum value that is >= the majority of the QI
- for (unsigned count = 0, i = 0; i < 256; ++i) {
+ for (uint count = 0, i = 0; i < 256; ++i) {
count += qiClasses[i];
if (count >= qiMajority) {
(*ve)->setQI(i);
@@ -595,7 +597,7 @@ static void computeCumulativeVisibility(ViewMap *ioViewMap,
for (set<ViewShape *>::iterator o = foundOccluders.begin(), oend = foundOccluders.end();
o != oend;
++o) {
- (*ve)->AddOccluder((*o));
+ (*ve)->AddOccluder(*o);
}
#if LOGGING
if (_global.debug & G_DEBUG_FREESTYLE) {
@@ -607,7 +609,7 @@ static void computeCumulativeVisibility(ViewMap *ioViewMap,
#endif
// occludee --
if (!wFaces.empty()) {
- if (wFaces.size() <= (float)nSamples / 2.0f) {
+ if (wFaces.size() <= float(nSamples) / 2.0f) {
(*ve)->setaShape(nullptr);
}
else {
@@ -623,7 +625,7 @@ static void computeCumulativeVisibility(ViewMap *ioViewMap,
stringstream ss;
ss << "Freestyle: Visibility computations " << (100 * count / vedges.size()) << "%";
iRenderMonitor->setInfo(ss.str());
- iRenderMonitor->progress((float)count / vedges.size());
+ iRenderMonitor->progress(float(count) / vedges.size());
}
}
@@ -639,10 +641,10 @@ static void computeDetailedVisibility(ViewMap *ioViewMap,
int nSamples = 0;
vector<WFace *> wFaces;
WFace *wFace = nullptr;
- unsigned tmpQI = 0;
- unsigned qiClasses[256];
- unsigned maxIndex, maxCard;
- unsigned qiMajority;
+ uint tmpQI = 0;
+ uint qiClasses[256];
+ uint maxIndex, maxCard;
+ uint qiMajority;
for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
if (iRenderMonitor && iRenderMonitor->testBreak()) {
break;
@@ -786,7 +788,7 @@ static void computeDetailedVisibility(ViewMap *ioViewMap,
for (set<ViewShape *>::iterator o = foundOccluders.begin(), oend = foundOccluders.end();
o != oend;
++o) {
- (*ve)->AddOccluder((*o));
+ (*ve)->AddOccluder(*o);
}
#if LOGGING
if (_global.debug & G_DEBUG_FREESTYLE) {
@@ -796,7 +798,7 @@ static void computeDetailedVisibility(ViewMap *ioViewMap,
#endif
// occludee --
if (!wFaces.empty()) {
- if (wFaces.size() <= (float)nSamples / 2.0f) {
+ if (wFaces.size() <= float(nSamples) / 2.0f) {
(*ve)->setaShape(nullptr);
}
else {
@@ -816,13 +818,13 @@ static void computeFastVisibility(ViewMap *ioViewMap, G &grid, real epsilon)
vector<ViewEdge *> &vedges = ioViewMap->ViewEdges();
FEdge *fe, *festart;
- unsigned nSamples = 0;
+ uint nSamples = 0;
vector<WFace *> wFaces;
WFace *wFace = nullptr;
- unsigned tmpQI = 0;
- unsigned qiClasses[256];
- unsigned maxIndex, maxCard;
- unsigned qiMajority;
+ uint tmpQI = 0;
+ uint qiClasses[256];
+ uint maxIndex, maxCard;
+ uint qiMajority;
bool even_test;
for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
// Find an edge to test
@@ -925,7 +927,7 @@ static void computeFastVisibility(ViewMap *ioViewMap, G &grid, real epsilon)
for (set<ViewShape *>::iterator o = foundOccluders.begin(), oend = foundOccluders.end();
o != oend;
++o) {
- (*ve)->AddOccluder((*o));
+ (*ve)->AddOccluder(*o);
}
// occludee --
@@ -950,7 +952,7 @@ static void computeVeryFastVisibility(ViewMap *ioViewMap, G &grid, real epsilon)
vector<ViewEdge *> &vedges = ioViewMap->ViewEdges();
FEdge *fe;
- unsigned qi = 0;
+ uint qi = 0;
WFace *wFace = nullptr;
for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
@@ -1003,11 +1005,11 @@ static void computeVeryFastVisibility(ViewMap *ioViewMap, G &grid, real epsilon)
}
}
-void ViewMapBuilder::BuildGrid(WingedEdge &we, const BBox<Vec3r> &bbox, unsigned int sceneNumFaces)
+void ViewMapBuilder::BuildGrid(WingedEdge &we, const BBox<Vec3r> &bbox, uint sceneNumFaces)
{
_Grid->clear();
Vec3r size;
- for (unsigned int i = 0; i < 3; i++) {
+ for (uint i = 0; i < 3; i++) {
size[i] = fabs(bbox.getMax()[i] - bbox.getMin()[i]);
// let make the grid 1/10 bigger to avoid numerical errors while computing triangles/cells
// intersections.
@@ -1032,7 +1034,7 @@ ViewMap *ViewMapBuilder::BuildViewMap(WingedEdge &we,
visibility_algo iAlgo,
real epsilon,
const BBox<Vec3r> &bbox,
- unsigned int sceneNumFaces)
+ uint sceneNumFaces)
{
_ViewMap = new ViewMap;
_currentId = 1;
@@ -1289,7 +1291,7 @@ void ViewMapBuilder::computeCusps(ViewMap *ioViewMap)
if (_pRenderMonitor && _pRenderMonitor->testBreak()) {
break;
}
- if ((!((*ve)->getNature() & Nature::SILHOUETTE)) || (!((*ve)->fedgeA()->isSmooth()))) {
+ if (!((*ve)->getNature() & Nature::SILHOUETTE) || !(*ve)->fedgeA()->isSmooth()) {
continue;
}
FEdge *fe = (*ve)->fedgeA();
@@ -1435,7 +1437,7 @@ void ViewMapBuilder::ComputeDetailedVisibility(ViewMap *ioViewMap,
void ViewMapBuilder::ComputeEdgesVisibility(ViewMap *ioViewMap,
WingedEdge &we,
const BBox<Vec3r> &bbox,
- unsigned int sceneNumFaces,
+ uint sceneNumFaces,
visibility_algo iAlgo,
real epsilon)
{
@@ -1531,19 +1533,19 @@ void ViewMapBuilder::ComputeEdgesVisibility(ViewMap *ioViewMap,
}
}
-static const unsigned gProgressBarMaxSteps = 10;
-static const unsigned gProgressBarMinSize = 2000;
+static const uint gProgressBarMaxSteps = 10;
+static const uint gProgressBarMinSize = 2000;
void ViewMapBuilder::ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilon)
{
vector<ViewEdge *> &vedges = ioViewMap->ViewEdges();
bool progressBarDisplay = false;
- unsigned progressBarStep = 0;
- unsigned vEdgesSize = vedges.size();
- unsigned fEdgesSize = ioViewMap->FEdges().size();
+ uint progressBarStep = 0;
+ uint vEdgesSize = vedges.size();
+ uint fEdgesSize = ioViewMap->FEdges().size();
if (_pProgressBar != nullptr && fEdgesSize > gProgressBarMinSize) {
- unsigned progressBarSteps = min(gProgressBarMaxSteps, vEdgesSize);
+ uint progressBarSteps = min(gProgressBarMaxSteps, vEdgesSize);
progressBarStep = vEdgesSize / progressBarSteps;
_pProgressBar->reset();
_pProgressBar->setLabelText("Computing Ray casting Visibility");
@@ -1552,16 +1554,16 @@ void ViewMapBuilder::ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilo
progressBarDisplay = true;
}
- unsigned counter = progressBarStep;
+ uint counter = progressBarStep;
FEdge *fe, *festart;
int nSamples = 0;
vector<Polygon3r *> aFaces;
Polygon3r *aFace = nullptr;
- unsigned tmpQI = 0;
- unsigned qiClasses[256];
- unsigned maxIndex, maxCard;
- unsigned qiMajority;
- static unsigned timestamp = 1;
+ uint tmpQI = 0;
+ uint qiClasses[256];
+ uint maxIndex, maxCard;
+ uint qiMajority;
+ static uint timestamp = 1;
for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
if (_pRenderMonitor && _pRenderMonitor->testBreak()) {
break;
@@ -1658,7 +1660,7 @@ void ViewMapBuilder::ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilo
// occluders --
for (set<ViewShape *>::iterator o = occluders.begin(), oend = occluders.end(); o != oend;
++o) {
- (*ve)->AddOccluder((*o));
+ (*ve)->AddOccluder(*o);
}
#if LOGGING
if (_global.debug & G_DEBUG_FREESTYLE) {
@@ -1668,7 +1670,7 @@ void ViewMapBuilder::ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilo
#endif
// occludee --
if (!aFaces.empty()) {
- if (aFaces.size() <= (float)nSamples / 2.0f) {
+ if (aFaces.size() <= float(nSamples) / 2.0f) {
(*ve)->setaShape(nullptr);
}
else {
@@ -1695,12 +1697,12 @@ void ViewMapBuilder::ComputeFastRayCastingVisibility(ViewMap *ioViewMap, real ep
{
vector<ViewEdge *> &vedges = ioViewMap->ViewEdges();
bool progressBarDisplay = false;
- unsigned progressBarStep = 0;
- unsigned vEdgesSize = vedges.size();
- unsigned fEdgesSize = ioViewMap->FEdges().size();
+ uint progressBarStep = 0;
+ uint vEdgesSize = vedges.size();
+ uint fEdgesSize = ioViewMap->FEdges().size();
if (_pProgressBar != nullptr && fEdgesSize > gProgressBarMinSize) {
- unsigned progressBarSteps = min(gProgressBarMaxSteps, vEdgesSize);
+ uint progressBarSteps = min(gProgressBarMaxSteps, vEdgesSize);
progressBarStep = vEdgesSize / progressBarSteps;
_pProgressBar->reset();
_pProgressBar->setLabelText("Computing Ray casting Visibility");
@@ -1709,16 +1711,16 @@ void ViewMapBuilder::ComputeFastRayCastingVisibility(ViewMap *ioViewMap, real ep
progressBarDisplay = true;
}
- unsigned counter = progressBarStep;
+ uint counter = progressBarStep;
FEdge *fe, *festart;
- unsigned nSamples = 0;
+ uint nSamples = 0;
vector<Polygon3r *> aFaces;
Polygon3r *aFace = nullptr;
- unsigned tmpQI = 0;
- unsigned qiClasses[256];
- unsigned maxIndex, maxCard;
- unsigned qiMajority;
- static unsigned timestamp = 1;
+ uint tmpQI = 0;
+ uint qiClasses[256];
+ uint maxIndex, maxCard;
+ uint qiMajority;
+ static uint timestamp = 1;
bool even_test;
for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
if (_pRenderMonitor && _pRenderMonitor->testBreak()) {
@@ -1828,12 +1830,12 @@ void ViewMapBuilder::ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, rea
{
vector<ViewEdge *> &vedges = ioViewMap->ViewEdges();
bool progressBarDisplay = false;
- unsigned progressBarStep = 0;
- unsigned vEdgesSize = vedges.size();
- unsigned fEdgesSize = ioViewMap->FEdges().size();
+ uint progressBarStep = 0;
+ uint vEdgesSize = vedges.size();
+ uint fEdgesSize = ioViewMap->FEdges().size();
if (_pProgressBar != nullptr && fEdgesSize > gProgressBarMinSize) {
- unsigned progressBarSteps = min(gProgressBarMaxSteps, vEdgesSize);
+ uint progressBarSteps = min(gProgressBarMaxSteps, vEdgesSize);
progressBarStep = vEdgesSize / progressBarSteps;
_pProgressBar->reset();
_pProgressBar->setLabelText("Computing Ray casting Visibility");
@@ -1842,11 +1844,11 @@ void ViewMapBuilder::ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, rea
progressBarDisplay = true;
}
- unsigned counter = progressBarStep;
+ uint counter = progressBarStep;
FEdge *fe;
- unsigned qi = 0;
+ uint qi = 0;
Polygon3r *aFace = nullptr;
- static unsigned timestamp = 1;
+ static uint timestamp = 1;
for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
if (_pRenderMonitor && _pRenderMonitor->testBreak()) {
break;
@@ -1882,7 +1884,7 @@ void ViewMapBuilder::FindOccludee(FEdge *fe,
Grid *iGrid,
real epsilon,
Polygon3r **oaPolygon,
- unsigned timestamp,
+ uint timestamp,
Vec3r &u,
Vec3r &A,
Vec3r &origin,
@@ -1916,7 +1918,7 @@ void ViewMapBuilder::FindOccludee(FEdge *fe,
//-------------------------------------------------------------
// first let us compute the plane equation.
oface = (WFace *)(*p)->userdata;
- Vec3r v1(((*p)->getVertices())[0]);
+ Vec3r v1((*p)->getVertices()[0]);
Vec3r normal((*p)->getNormal());
real d = -(v1 * normal);
real t, t_u, t_v;
@@ -1986,7 +1988,7 @@ void ViewMapBuilder::FindOccludee(FEdge *fe,
}
void ViewMapBuilder::FindOccludee(
- FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp)
+ FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, uint timestamp)
{
OccludersSet occluders;
@@ -2030,7 +2032,7 @@ int ViewMapBuilder::ComputeRayCastingVisibility(FEdge *fe,
real epsilon,
set<ViewShape *> &oOccluders,
Polygon3r **oaPolygon,
- unsigned timestamp)
+ uint timestamp)
{
OccludersSet occluders;
int qi = 0;
@@ -2115,7 +2117,7 @@ int ViewMapBuilder::ComputeRayCastingVisibility(FEdge *fe,
<< "\t\t\tand ray " << vp << " * " << u << " (center " << center << ")" << endl;
}
#endif
- Vec3r v1(((*p)->getVertices())[0]);
+ Vec3r v1((*p)->getVertices()[0]);
Vec3r normal((*p)->getNormal());
real d = -(v1 * normal);
real t, t_u, t_v;
@@ -2270,7 +2272,7 @@ struct less_SVertex2D {
{
Vec3r A = x->point2D();
Vec3r B = y->point2D();
- for (unsigned int i = 0; i < 3; i++) {
+ for (uint i = 0; i < 3; i++) {
if (fabs(A[i] - B[i]) < epsilon) {
continue;
}
@@ -2313,8 +2315,8 @@ struct silhouette_binary_rule : public binary_rule<segment, segment> {
FEdge *f1 = s1.edge();
FEdge *f2 = s2.edge();
- if ((!(((f1)->getNature() & Nature::SILHOUETTE) || ((f1)->getNature() & Nature::BORDER))) &&
- (!(((f2)->getNature() & Nature::SILHOUETTE) || ((f2)->getNature() & Nature::BORDER)))) {
+ if (!(((f1)->getNature() & Nature::SILHOUETTE) || ((f1)->getNature() & Nature::BORDER)) &&
+ !(((f2)->getNature() & Nature::SILHOUETTE) || ((f2)->getNature() & Nature::BORDER))) {
return false;
}
@@ -2326,8 +2328,8 @@ void ViewMapBuilder::ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsi
{
vector<SVertex *> &svertices = ioViewMap->SVertices();
bool progressBarDisplay = false;
- unsigned sVerticesSize = svertices.size();
- unsigned fEdgesSize = ioViewMap->FEdges().size();
+ uint sVerticesSize = svertices.size();
+ uint fEdgesSize = ioViewMap->FEdges().size();
#if 0
if (_global.debug & G_DEBUG_FREESTYLE) {
ViewMap::fedges_container &fedges = ioViewMap->FEdges();
@@ -2338,10 +2340,10 @@ void ViewMapBuilder::ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsi
}
}
#endif
- unsigned progressBarStep = 0;
+ uint progressBarStep = 0;
if (_pProgressBar != nullptr && fEdgesSize > gProgressBarMinSize) {
- unsigned progressBarSteps = min(gProgressBarMaxSteps, sVerticesSize);
+ uint progressBarSteps = min(gProgressBarMaxSteps, sVerticesSize);
progressBarStep = sVerticesSize / progressBarSteps;
_pProgressBar->reset();
_pProgressBar->setLabelText("Computing Sweep Line Intersections");
@@ -2350,7 +2352,7 @@ void ViewMapBuilder::ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsi
progressBarDisplay = true;
}
- unsigned counter = progressBarStep;
+ uint counter = progressBarStep;
sort(svertices.begin(), svertices.end(), less_SVertex2D(epsilon));
@@ -2500,8 +2502,8 @@ void ViewMapBuilder::ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsi
progressBarStep = 0;
if (progressBarDisplay) {
- unsigned iEdgesSize = iedges.size();
- unsigned progressBarSteps = min(gProgressBarMaxSteps, iEdgesSize);
+ uint iEdgesSize = iedges.size();
+ uint progressBarSteps = min(gProgressBarMaxSteps, iEdgesSize);
progressBarStep = iEdgesSize / progressBarSteps;
_pProgressBar->reset();
_pProgressBar->setLabelText("Splitting intersected edges");
diff --git a/source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp b/source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp
index 75b716ee9da..86c264892e0 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp
@@ -19,7 +19,7 @@ NodeGroup *ViewMapTesselator::Tesselate(ViewMap *iViewMap)
return Tesselate(viewedges.begin(), viewedges.end());
}
-NodeGroup *ViewMapTesselator::Tesselate(WShape *UNUSED(iWShape))
+NodeGroup *ViewMapTesselator::Tesselate(WShape * /*iWShape*/)
{
return nullptr;
}
diff --git a/source/blender/freestyle/intern/view_map/ViewMapTesselator.h b/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
index 2da95d47912..c666e548884 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
@@ -89,7 +89,7 @@ class ViewMapTesselator {
#endif
};
-/** Class to tesselate the 2D projected silhouette */
+/** Class to tessellate the 2D projected silhouette */
class ViewMapTesselator2D : public ViewMapTesselator {
public:
inline ViewMapTesselator2D() : ViewMapTesselator()
@@ -110,7 +110,7 @@ class ViewMapTesselator2D : public ViewMapTesselator {
#endif
};
-/** Class to tesselate the 3D silhouette */
+/** Class to tessellate the 3D silhouette */
class ViewMapTesselator3D : public ViewMapTesselator {
public:
inline ViewMapTesselator3D() : ViewMapTesselator()
diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.cpp b/source/blender/freestyle/intern/winged_edge/Curvature.cpp
index 9086593a945..36c06fde78e 100644
--- a/source/blender/freestyle/intern/winged_edge/Curvature.cpp
+++ b/source/blender/freestyle/intern/winged_edge/Curvature.cpp
@@ -38,7 +38,7 @@ static bool angle_obtuse(WVertex *v, WFace *f)
// FIXME
// WVvertex is useless but kept for history reasons
-static bool triangle_obtuse(WVertex *UNUSED(v), WFace *f)
+static bool triangle_obtuse(WVertex * /*v*/, WFace *f)
{
bool b = false;
for (int i = 0; i < 3; i++) {
@@ -80,7 +80,7 @@ static real angle_from_cotan(WVertex *vo, WVertex *v1, WVertex *v2)
/* NOTE(Ray Jones): I assume this is what they mean by using #atan2. */
/* tan = denom/udotv = y/x (see man page for atan2) */
- return (fabs(atan2(denom, udotv)));
+ return fabs(atan2(denom, udotv));
}
bool gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &Kh)
diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.cpp b/source/blender/freestyle/intern/winged_edge/WEdge.cpp
index 8b9388caa86..3082988bd36 100644
--- a/source/blender/freestyle/intern/winged_edge/WEdge.cpp
+++ b/source/blender/freestyle/intern/winged_edge/WEdge.cpp
@@ -9,6 +9,8 @@
#include "WEdge.h"
+#include "BLI_sys_types.h"
+
namespace Freestyle {
/** Temporary structures */
@@ -451,7 +453,7 @@ WShape *WFace::getShape()
* *
**********************************/
-unsigned WShape::_SceneCurrentId = 0;
+uint WShape::_SceneCurrentId = 0;
WShape *WShape::duplicate()
{
@@ -500,7 +502,7 @@ WShape::WShape(WShape &iBrother)
for (v = _VertexList.begin(); v != vend; ++v) {
const vector<WEdge *> &vedgeList = (*v)->GetEdges();
vector<WEdge *> newvedgelist;
- unsigned int i;
+ uint i;
for (i = 0; i < vedgeList.size(); i++) {
WEdge *current = vedgeList[i];
edgedata *currentvedata = (edgedata *)current->userdata;
@@ -536,11 +538,11 @@ WShape::WShape(WShape &iBrother)
fend = _FaceList.end();
for (f = _FaceList.begin(); f != fend; ++f) {
- unsigned int i;
+ uint i;
const vector<WOEdge *> &oedgeList = (*f)->getEdgeList();
vector<WOEdge *> newoedgelist;
- unsigned int n = oedgeList.size();
+ uint n = oedgeList.size();
for (i = 0; i < n; i++) {
WOEdge *current = oedgeList[i];
oedgedata *currentoedata = (oedgedata *)current->userdata;
@@ -585,7 +587,7 @@ WShape::WShape(WShape &iBrother)
WFace *WShape::MakeFace(vector<WVertex *> &iVertexList,
vector<bool> &iFaceEdgeMarksList,
- unsigned iMaterial)
+ uint iMaterial)
{
// allocate the new face
WFace *face = instanciateFace();
@@ -601,7 +603,7 @@ WFace *WShape::MakeFace(vector<WVertex *> &iVertexList,
vector<Vec3f> &iNormalsList,
vector<Vec2f> &iTexCoordsList,
vector<bool> &iFaceEdgeMarksList,
- unsigned iMaterial)
+ uint iMaterial)
{
// allocate the new face
WFace *face = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial);
@@ -620,7 +622,7 @@ WFace *WShape::MakeFace(vector<WVertex *> &iVertexList,
WFace *WShape::MakeFace(vector<WVertex *> &iVertexList,
vector<bool> &iFaceEdgeMarksList,
- unsigned iMaterial,
+ uint iMaterial,
WFace *face)
{
int id = _FaceList.size();
diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.cpp b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp
index b18d232dbbe..6838060b44e 100644
--- a/source/blender/freestyle/intern/winged_edge/WXEdge.cpp
+++ b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp
@@ -6,6 +6,9 @@
*/
#include "WXEdge.h"
+
+#include "BLI_sys_types.h"
+
#include "BKE_global.h"
namespace Freestyle {
@@ -18,7 +21,7 @@ namespace Freestyle {
* *
**********************************/
-unsigned int WXFaceLayer::Get0VertexIndex() const
+uint WXFaceLayer::Get0VertexIndex() const
{
int i = 0;
int nEdges = _pWXFace->numberOfEdges();
@@ -29,7 +32,7 @@ unsigned int WXFaceLayer::Get0VertexIndex() const
}
return -1;
}
-unsigned int WXFaceLayer::GetSmoothEdgeIndex() const
+uint WXFaceLayer::GetSmoothEdgeIndex() const
{
int i = 0;
int nEdges = _pWXFace->numberOfEdges();
@@ -64,7 +67,7 @@ WXSmoothEdge *WXFaceLayer::BuildSmoothEdge()
bool ok = false;
vector<int> cuspEdgesIndices;
int indexStart, indexEnd;
- unsigned nedges = _pWXFace->numberOfEdges();
+ uint nedges = _pWXFace->numberOfEdges();
if (_nNullDotP == nedges) {
_pSmoothEdge = nullptr;
return _pSmoothEdge;
@@ -118,8 +121,8 @@ WXSmoothEdge *WXFaceLayer::BuildSmoothEdge()
_pSmoothEdge = nullptr;
return nullptr;
}
- unsigned index0 = Get0VertexIndex(); // retrieve the 0 vertex index
- unsigned nedges = _pWXFace->numberOfEdges();
+ uint index0 = Get0VertexIndex(); // retrieve the 0 vertex index
+ uint nedges = _pWXFace->numberOfEdges();
if (_DotP[cuspEdgesIndices[0]] > 0.0f) {
woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
woeb = _pWXFace->GetOEdge(index0);
@@ -243,7 +246,7 @@ void WXFace::ComputeCenter()
++wv) {
center += (*wv)->GetVertex();
}
- center /= (float)iVertexList.size();
+ center /= float(iVertexList.size());
setCenter(center);
}
@@ -257,7 +260,7 @@ void WXFace::ComputeCenter()
WFace *WXShape::MakeFace(vector<WVertex *> &iVertexList,
vector<bool> &iFaceEdgeMarksList,
- unsigned iMaterialIndex)
+ uint iMaterialIndex)
{
WFace *face = WShape::MakeFace(iVertexList, iFaceEdgeMarksList, iMaterialIndex);
if (!face) {
@@ -270,7 +273,7 @@ WFace *WXShape::MakeFace(vector<WVertex *> &iVertexList,
++wv) {
center += (*wv)->GetVertex();
}
- center /= (float)iVertexList.size();
+ center /= float(iVertexList.size());
((WXFace *)face)->setCenter(center);
return face;
@@ -280,7 +283,7 @@ WFace *WXShape::MakeFace(vector<WVertex *> &iVertexList,
vector<Vec3f> &iNormalsList,
vector<Vec2f> &iTexCoordsList,
vector<bool> &iFaceEdgeMarksList,
- unsigned iMaterialIndex)
+ uint iMaterialIndex)
{
WFace *face = WShape::MakeFace(
iVertexList, iNormalsList, iTexCoordsList, iFaceEdgeMarksList, iMaterialIndex);
diff --git a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp
index 3a5cdbc663c..e22de505472 100644
--- a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp
+++ b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp
@@ -9,6 +9,8 @@
#include "WXEdgeBuilder.h"
#include "WXEdge.h"
+#include "BLI_sys_types.h"
+
namespace Freestyle {
void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet &ifs)
@@ -27,10 +29,10 @@ void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet &ifs)
// ifs.setId(shape->GetId());
}
-void WXEdgeBuilder::buildWVertices(WShape &shape, const float *vertices, unsigned vsize)
+void WXEdgeBuilder::buildWVertices(WShape &shape, const float *vertices, uint vsize)
{
WXVertex *vertex;
- for (unsigned int i = 0; i < vsize; i += 3) {
+ for (uint i = 0; i < vsize; i += 3) {
vertex = new WXVertex(Vec3f(vertices[i], vertices[i + 1], vertices[i + 2]));
vertex->setId(i / 3);
shape.AddVertex(vertex);
diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp
index 0a3ab97717b..ce6054830f3 100644
--- a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp
+++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp
@@ -14,6 +14,8 @@
#include "../scene_graph/NodeShape.h"
+#include "BLI_sys_types.h"
+
using namespace std;
namespace Freestyle {
@@ -35,7 +37,7 @@ void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet &ifs)
void WingedEdgeBuilder::visitNodeShape(NodeShape &ns)
{
// Sets the current material to iShapeode->material:
- _current_frs_material = &(ns.frs_material());
+ _current_frs_material = &ns.frs_material();
}
void WingedEdgeBuilder::visitNodeTransform(NodeTransform &tn)
@@ -50,7 +52,7 @@ void WingedEdgeBuilder::visitNodeTransform(NodeTransform &tn)
_current_matrix = new_matrix;
}
-void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform &UNUSED(transform))
+void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform & /*transform*/)
{
delete _current_matrix;
@@ -65,8 +67,8 @@ void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform &UNUSED(transform)
bool WingedEdgeBuilder::buildWShape(WShape &shape, IndexedFaceSet &ifs)
{
- unsigned int vsize = ifs.vsize();
- unsigned int nsize = ifs.nsize();
+ uint vsize = ifs.vsize();
+ uint nsize = ifs.nsize();
// soc unused - unsigned tsize = ifs.tsize();
const float *vertices = ifs.vertices();
@@ -94,7 +96,7 @@ bool WingedEdgeBuilder::buildWShape(WShape &shape, IndexedFaceSet &ifs)
vector<FrsMaterial> frs_materials;
if (ifs.msize()) {
const FrsMaterial *const *mats = ifs.frs_materials();
- for (unsigned i = 0; i < ifs.msize(); ++i) {
+ for (uint i = 0; i < ifs.msize(); ++i) {
frs_materials.push_back(*(mats[i]));
}
shape.setFrsMaterials(frs_materials);
@@ -117,21 +119,21 @@ bool WingedEdgeBuilder::buildWShape(WShape &shape, IndexedFaceSet &ifs)
// create a WVertex for each vertex
buildWVertices(shape, new_vertices, vsize);
- const unsigned int *vindices = ifs.vindices();
- const unsigned int *nindices = ifs.nindices();
- const unsigned int *tindices = nullptr;
+ const uint *vindices = ifs.vindices();
+ const uint *nindices = ifs.nindices();
+ const uint *tindices = nullptr;
if (ifs.tsize()) {
tindices = ifs.tindices();
}
- const unsigned int *mindices = nullptr;
+ const uint *mindices = nullptr;
if (ifs.msize()) {
mindices = ifs.mindices();
}
- const unsigned int *numVertexPerFace = ifs.numVertexPerFaces();
- const unsigned int numfaces = ifs.numFaces();
+ const uint *numVertexPerFace = ifs.numVertexPerFaces();
+ const uint numfaces = ifs.numFaces();
- for (unsigned int index = 0; index < numfaces; index++) {
+ for (uint index = 0; index < numfaces; index++) {
switch (faceStyle[index]) {
case IndexedFaceSet::TRIANGLE_STRIP:
buildTriangleStrip(new_vertices,
@@ -228,10 +230,10 @@ bool WingedEdgeBuilder::buildWShape(WShape &shape, IndexedFaceSet &ifs)
return true;
}
-void WingedEdgeBuilder::buildWVertices(WShape &shape, const float *vertices, unsigned vsize)
+void WingedEdgeBuilder::buildWVertices(WShape &shape, const float *vertices, uint vsize)
{
WVertex *vertex;
- for (unsigned int i = 0; i < vsize; i += 3) {
+ for (uint i = 0; i < vsize; i += 3) {
vertex = new WVertex(Vec3f(vertices[i], vertices[i + 1], vertices[i + 2]));
vertex->setId(i / 3);
shape.AddVertex(vertex);
@@ -243,15 +245,15 @@ void WingedEdgeBuilder::buildTriangleStrip(const float * /*vertices*/,
vector<FrsMaterial> & /*iMaterials*/,
const float *texCoords,
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
- const unsigned *vindices,
- const unsigned *nindices,
- const unsigned *mindices,
- const unsigned *tindices,
- const unsigned nvertices)
+ const uint *vindices,
+ const uint *nindices,
+ const uint *mindices,
+ const uint *tindices,
+ const uint nvertices)
{
- unsigned nDoneVertices = 2; // number of vertices already treated
- unsigned nTriangle = 0; // number of the triangle currently being treated
- // int nVertex = 0; // vertex number
+ uint nDoneVertices = 2; /* Number of vertices already treated. */
+ uint nTriangle = 0; /* Number of the triangle currently being treated. */
+ // int nVertex = 0; /* Vertex number. */
WShape *currentShape = _current_wshape; // the current shape being built
vector<WVertex *> triangleVertices;
@@ -340,11 +342,11 @@ void WingedEdgeBuilder::buildTriangleFan(const float * /*vertices*/,
vector<FrsMaterial> & /*iMaterials*/,
const float * /*texCoords*/,
const IndexedFaceSet::FaceEdgeMark * /*iFaceEdgeMarks*/,
- const unsigned * /*vindices*/,
- const unsigned * /*nindices*/,
- const unsigned * /*mindices*/,
- const unsigned * /*tindices*/,
- const unsigned /*nvertices*/)
+ const uint * /*vindices*/,
+ const uint * /*nindices*/,
+ const uint * /*mindices*/,
+ const uint * /*tindices*/,
+ const uint /*nvertices*/)
{
// Nothing to be done
}
@@ -354,11 +356,11 @@ void WingedEdgeBuilder::buildTriangles(const float * /*vertices*/,
vector<FrsMaterial> & /*iMaterials*/,
const float *texCoords,
const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
- const unsigned *vindices,
- const unsigned *nindices,
- const unsigned *mindices,
- const unsigned *tindices,
- const unsigned nvertices)
+ const uint *vindices,
+ const uint *nindices,
+ const uint *mindices,
+ const uint *tindices,
+ const uint nvertices)
{
WShape *currentShape = _current_wshape; // the current shape begin built
vector<WVertex *> triangleVertices;
@@ -367,7 +369,7 @@ void WingedEdgeBuilder::buildTriangles(const float * /*vertices*/,
vector<bool> triangleFaceEdgeMarks;
// Each triplet of vertices is considered as an independent triangle
- for (unsigned int i = 0; i < nvertices / 3; i++) {
+ for (uint i = 0; i < nvertices / 3; i++) {
triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 1] / 3]);
triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 2] / 3]);
@@ -405,17 +407,17 @@ void WingedEdgeBuilder::buildTriangles(const float * /*vertices*/,
}
void WingedEdgeBuilder::transformVertices(const float *vertices,
- unsigned vsize,
+ uint vsize,
const Matrix44r &transform,
float *res)
{
const float *v = vertices;
float *pv = res;
- for (unsigned int i = 0; i < vsize / 3; i++) {
+ for (uint i = 0; i < vsize / 3; i++) {
HVec3r hv_tmp(v[0], v[1], v[2]);
HVec3r hv(transform * hv_tmp);
- for (unsigned int j = 0; j < 3; j++) {
+ for (uint j = 0; j < 3; j++) {
pv[j] = hv[j] / hv[3];
}
v += 3;
@@ -424,17 +426,17 @@ void WingedEdgeBuilder::transformVertices(const float *vertices,
}
void WingedEdgeBuilder::transformNormals(const float *normals,
- unsigned nsize,
+ uint nsize,
const Matrix44r &transform,
float *res)
{
const float *n = normals;
float *pn = res;
- for (unsigned int i = 0; i < nsize / 3; i++) {
+ for (uint i = 0; i < nsize / 3; i++) {
Vec3r hn(n[0], n[1], n[2]);
hn = GeomUtils::rotateVector(transform, hn);
- for (unsigned int j = 0; j < 3; j++) {
+ for (uint j = 0; j < 3; j++) {
pn[j] = hn[j];
}
n += 3;
diff --git a/source/blender/functions/FN_field.hh b/source/blender/functions/FN_field.hh
index ca12f407e49..bff9c77ef7d 100644
--- a/source/blender/functions/FN_field.hh
+++ b/source/blender/functions/FN_field.hh
@@ -412,7 +412,7 @@ class FieldEvaluator : NonMovable, NonCopyable {
const int field_index = fields_to_evaluate_.append_and_get_index(std::move(field));
dst_varrays_.append({});
output_pointer_infos_.append(OutputPointerInfo{
- varray_ptr, [](void *dst, const GVArray &varray, ResourceScope &UNUSED(scope)) {
+ varray_ptr, [](void *dst, const GVArray &varray, ResourceScope & /*scope*/) {
*(VArray<T> *)dst = varray.typed<T>();
}});
return field_index;
@@ -546,7 +546,7 @@ template<typename T> struct ValueOrField {
bool is_field() const
{
- return (bool)this->field;
+ return bool(this->field);
}
Field<T> as_field() const
diff --git a/source/blender/functions/FN_lazy_function.hh b/source/blender/functions/FN_lazy_function.hh
index 59a3a90b0b0..4a539e7cbd1 100644
--- a/source/blender/functions/FN_lazy_function.hh
+++ b/source/blender/functions/FN_lazy_function.hh
@@ -43,6 +43,13 @@
#include "BLI_linear_allocator.hh"
#include "BLI_vector.hh"
+#include <atomic>
+#include <thread>
+
+#ifdef DEBUG
+# define FN_LAZY_FUNCTION_DEBUG_THREADS
+#endif
+
namespace blender::fn::lazy_function {
enum class ValueUsage {
@@ -102,9 +109,13 @@ class Params {
* The lazy-function this #Params has been prepared for.
*/
const LazyFunction &fn_;
+#ifdef FN_LAZY_FUNCTION_DEBUG_THREADS
+ std::thread::id main_thread_id_;
+ std::atomic<bool> allow_multi_threading_;
+#endif
public:
- Params(const LazyFunction &fn);
+ Params(const LazyFunction &fn, bool allow_multi_threading_initially);
/**
* Get a pointer to an input value if the value is available already. Otherwise null is returned.
@@ -154,7 +165,7 @@ class Params {
* Typed utility methods that wrap the methods above.
*/
template<typename T> T extract_input(int index);
- template<typename T> const T &get_input(int index);
+ template<typename T> const T &get_input(int index) const;
template<typename T> T *try_get_input_data_ptr_or_request(int index);
template<typename T> void set_output(int index, T &&value);
@@ -163,7 +174,15 @@ class Params {
*/
void set_default_remaining_outputs();
+ /**
+ * Returns true when the lazy-function is now allowed to use multi-threading when interacting
+ * with this #Params. That means, it is allowed to call non-const methods from different threads.
+ */
+ bool try_enable_multi_threading();
+
private:
+ void assert_valid_thread() const;
+
/**
* Methods that need to be implemented by subclasses. Those are separate from the non-virtual
* methods above to make it easy to insert additional debugging logic on top of the
@@ -176,6 +195,7 @@ class Params {
virtual bool output_was_set_impl(int index) const = 0;
virtual ValueUsage get_output_usage_impl(int index) const = 0;
virtual void set_input_unused_impl(int index) = 0;
+ virtual bool try_enable_multi_threading_impl();
};
/**
@@ -312,7 +332,14 @@ inline void LazyFunction::execute(Params &params, const Context &context) const
/** \name #Params Inline Methods
* \{ */
-inline Params::Params(const LazyFunction &fn) : fn_(fn)
+inline Params::Params(const LazyFunction &fn,
+ [[maybe_unused]] bool allow_multi_threading_initially)
+ : fn_(fn)
+#ifdef FN_LAZY_FUNCTION_DEBUG_THREADS
+ ,
+ main_thread_id_(std::this_thread::get_id()),
+ allow_multi_threading_(allow_multi_threading_initially)
+#endif
{
}
@@ -323,16 +350,19 @@ inline void *Params::try_get_input_data_ptr(const int index) const
inline void *Params::try_get_input_data_ptr_or_request(const int index)
{
+ this->assert_valid_thread();
return this->try_get_input_data_ptr_or_request_impl(index);
}
inline void *Params::get_output_data_ptr(const int index)
{
+ this->assert_valid_thread();
return this->get_output_data_ptr_impl(index);
}
inline void Params::output_set(const int index)
{
+ this->assert_valid_thread();
this->output_set_impl(index);
}
@@ -348,18 +378,20 @@ inline ValueUsage Params::get_output_usage(const int index) const
inline void Params::set_input_unused(const int index)
{
+ this->assert_valid_thread();
this->set_input_unused_impl(index);
}
template<typename T> inline T Params::extract_input(const int index)
{
+ this->assert_valid_thread();
void *data = this->try_get_input_data_ptr(index);
BLI_assert(data != nullptr);
T return_value = std::move(*static_cast<T *>(data));
return return_value;
}
-template<typename T> inline const T &Params::get_input(const int index)
+template<typename T> inline const T &Params::get_input(const int index) const
{
const void *data = this->try_get_input_data_ptr(index);
BLI_assert(data != nullptr);
@@ -368,17 +400,43 @@ template<typename T> inline const T &Params::get_input(const int index)
template<typename T> inline T *Params::try_get_input_data_ptr_or_request(const int index)
{
+ this->assert_valid_thread();
return static_cast<T *>(this->try_get_input_data_ptr_or_request(index));
}
template<typename T> inline void Params::set_output(const int index, T &&value)
{
using DecayT = std::decay_t<T>;
+ this->assert_valid_thread();
void *data = this->get_output_data_ptr(index);
new (data) DecayT(std::forward<T>(value));
this->output_set(index);
}
+inline bool Params::try_enable_multi_threading()
+{
+ this->assert_valid_thread();
+ const bool success = this->try_enable_multi_threading_impl();
+#ifdef FN_LAZY_FUNCTION_DEBUG_THREADS
+ if (success) {
+ allow_multi_threading_ = true;
+ }
+#endif
+ return success;
+}
+
+inline void Params::assert_valid_thread() const
+{
+#ifdef FN_LAZY_FUNCTION_DEBUG_THREADS
+ if (allow_multi_threading_) {
+ return;
+ }
+ if (main_thread_id_ != std::this_thread::get_id()) {
+ BLI_assert_unreachable();
+ }
+#endif
+}
+
/** \} */
} // namespace blender::fn::lazy_function
diff --git a/source/blender/functions/FN_lazy_function_execute.hh b/source/blender/functions/FN_lazy_function_execute.hh
index a59d363a9d5..31bbddf5baf 100644
--- a/source/blender/functions/FN_lazy_function_execute.hh
+++ b/source/blender/functions/FN_lazy_function_execute.hh
@@ -41,6 +41,7 @@ class BasicParams : public Params {
bool output_was_set_impl(const int index) const override;
ValueUsage get_output_usage_impl(const int index) const override;
void set_input_unused_impl(const int index) override;
+ bool try_enable_multi_threading_impl() override;
};
namespace detail {
@@ -67,7 +68,8 @@ inline void execute_lazy_function_eagerly_impl(
(
[&]() {
constexpr size_t I = InIndices;
- using T = Inputs;
+ /* Use `typedef` instead of `using` to work around a compiler bug. */
+ typedef Inputs T;
const CPPType &type = CPPType::get<T>();
input_pointers[I] = {type, &std::get<I>(inputs)};
}(),
@@ -75,7 +77,8 @@ inline void execute_lazy_function_eagerly_impl(
(
[&]() {
constexpr size_t I = OutIndices;
- using T = Outputs;
+ /* Use `typedef` instead of `using` to work around a compiler bug. */
+ typedef Outputs T;
const CPPType &type = CPPType::get<T>();
output_pointers[I] = {type, std::get<I>(outputs)};
}(),
diff --git a/source/blender/functions/FN_multi_function.hh b/source/blender/functions/FN_multi_function.hh
index accbaf899be..7089f6895a7 100644
--- a/source/blender/functions/FN_multi_function.hh
+++ b/source/blender/functions/FN_multi_function.hh
@@ -60,7 +60,7 @@ class MultiFunction {
return get_default_hash(this);
}
- virtual bool equals(const MultiFunction &UNUSED(other)) const
+ virtual bool equals(const MultiFunction & /*other*/) const
{
return false;
}
diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh
index e6dc01eb539..eeadb1938bb 100644
--- a/source/blender/functions/FN_multi_function_builder.hh
+++ b/source/blender/functions/FN_multi_function_builder.hh
@@ -207,6 +207,7 @@ void execute_materialized(TypeSequence<ParamTags...> /* param_tags */,
(
/* Setup information for all parameters. */
[&] {
+ /* Use `typedef` instead of `using` to work around a compiler bug. */
typedef ParamTags ParamTag;
typedef typename ParamTag::base_type T;
[[maybe_unused]] ArgInfo<ParamTags> &arg_info = std::get<I>(args_info);
@@ -282,6 +283,7 @@ void execute_materialized(TypeSequence<ParamTags...> /* param_tags */,
(
/* Destruct values that have been materialized before. */
[&] {
+ /* Use `typedef` instead of `using` to work around a compiler bug. */
typedef ParamTags ParamTag;
typedef typename ParamTag::base_type T;
[[maybe_unused]] ArgInfo<ParamTags> &arg_info = std::get<I>(args_info);
@@ -298,6 +300,7 @@ void execute_materialized(TypeSequence<ParamTags...> /* param_tags */,
(
/* Destruct buffers for single value inputs. */
[&] {
+ /* Use `typedef` instead of `using` to work around a compiler bug. */
typedef ParamTags ParamTag;
typedef typename ParamTag::base_type T;
[[maybe_unused]] ArgInfo<ParamTags> &arg_info = std::get<I>(args_info);
@@ -347,6 +350,7 @@ template<typename... ParamTags> class CustomMF : public MultiFunction {
(
/* Get all parameters from #params and store them in #retrieved_params. */
[&]() {
+ /* Use `typedef` instead of `using` to work around a compiler bug. */
typedef typename TagsSequence::template at_index<I> ParamTag;
typedef typename ParamTag::base_type T;
@@ -402,13 +406,14 @@ template<typename... ParamTags> class CustomMF : public MultiFunction {
(
/* Loop over all parameter types and add an entry for each in the signature. */
[&] {
+ /* Use `typedef` instead of `using` to work around a compiler bug. */
typedef typename TagsSequence::template at_index<I> ParamTag;
signature.add(ParamTag(), "");
}(),
...);
}
- void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
{
fn_(mask, params);
}
@@ -566,7 +571,7 @@ template<typename Mut1> class CustomMF_SM : public MultiFunction {
};
}
- void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
{
MutableSpan<Mut1> mut1 = params.single_mutable<Mut1>(0);
function_(mask, mut1);
@@ -626,7 +631,7 @@ template<typename T> class CustomMF_Constant : public MultiFunction {
this->set_signature(&signature_);
}
- void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
{
MutableSpan<T> output = params.uninitialized_single_output<T>(0);
mask.to_best_mask_type([&](const auto &mask) {
diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc
index fd5eab57d33..d2205864945 100644
--- a/source/blender/functions/intern/field.cc
+++ b/source/blender/functions/intern/field.cc
@@ -16,9 +16,9 @@
namespace blender::fn {
-/* --------------------------------------------------------------------
- * Field Evaluation.
- */
+/* -------------------------------------------------------------------- */
+/** \name Field Evaluation
+ * \{ */
struct FieldTreeInfo {
/**
@@ -552,9 +552,9 @@ GVArray IndexFieldInput::get_index_varray(IndexMask mask)
return VArray<int>::ForFunc(mask.min_array_size(), index_func);
}
-GVArray IndexFieldInput::get_varray_for_context(const fn::FieldContext &UNUSED(context),
+GVArray IndexFieldInput::get_varray_for_context(const fn::FieldContext & /*context*/,
IndexMask mask,
- ResourceScope &UNUSED(scope)) const
+ ResourceScope & /*scope*/) const
{
/* TODO: Investigate a similar method to IndexRange::as_span() */
return get_index_varray(mask);
@@ -571,16 +571,20 @@ bool IndexFieldInput::is_equal_to(const fn::FieldNode &other) const
return dynamic_cast<const IndexFieldInput *>(&other) != nullptr;
}
-/* --------------------------------------------------------------------
- * FieldNode.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name #FieldNode
+ * \{ */
/* Avoid generating the destructor in every translation unit. */
FieldNode::~FieldNode() = default;
-/* --------------------------------------------------------------------
- * FieldOperation.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name #FieldOperation
+ * \{ */
FieldOperation::FieldOperation(std::shared_ptr<const MultiFunction> function,
Vector<GField> inputs)
@@ -653,9 +657,11 @@ FieldOperation::FieldOperation(const MultiFunction &function, Vector<GField> inp
field_inputs_ = combine_field_inputs(inputs_);
}
-/* --------------------------------------------------------------------
- * FieldInput.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name #FieldInput
+ * \{ */
FieldInput::FieldInput(const CPPType &type, std::string debug_name)
: FieldNode(FieldNodeType::Input), type_(&type), debug_name_(std::move(debug_name))
@@ -669,9 +675,11 @@ FieldInput::FieldInput(const CPPType &type, std::string debug_name)
/* Avoid generating the destructor in every translation unit. */
FieldInput::~FieldInput() = default;
-/* --------------------------------------------------------------------
- * FieldConstant.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name #FieldConstant
+ * \{ */
FieldConstant::FieldConstant(const CPPType &type, const void *value)
: FieldNode(FieldNodeType::Constant), type_(type)
@@ -703,9 +711,11 @@ GPointer FieldConstant::value() const
return {type_, value_};
}
-/* --------------------------------------------------------------------
- * FieldEvaluator.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name #FieldEvaluator
+ * \{ */
static IndexMask index_mask_from_selection(const IndexMask full_mask,
const VArray<bool> &selection,
@@ -733,8 +743,8 @@ int FieldEvaluator::add(GField field, GVArray *varray_ptr)
const int field_index = fields_to_evaluate_.append_and_get_index(std::move(field));
dst_varrays_.append(nullptr);
output_pointer_infos_.append(OutputPointerInfo{
- varray_ptr, [](void *dst, const GVArray &varray, ResourceScope &UNUSED(scope)) {
- *(GVArray *)dst = varray;
+ varray_ptr, [](void *dst, const GVArray &varray, ResourceScope & /*scope*/) {
+ *static_cast<GVArray *>(dst) = varray;
}});
return field_index;
}
@@ -800,4 +810,6 @@ IndexMask FieldEvaluator::get_evaluated_selection_as_mask()
return selection_mask_;
}
+/** \} */
+
} // namespace blender::fn
diff --git a/source/blender/functions/intern/lazy_function.cc b/source/blender/functions/intern/lazy_function.cc
index 46572283e9b..f1c53a04b3f 100644
--- a/source/blender/functions/intern/lazy_function.cc
+++ b/source/blender/functions/intern/lazy_function.cc
@@ -25,7 +25,7 @@ std::string LazyFunction::output_name(int index) const
return outputs_[index].debug_name;
}
-void *LazyFunction::init_storage(LinearAllocator<> &UNUSED(allocator)) const
+void *LazyFunction::init_storage(LinearAllocator<> & /*allocator*/) const
{
return nullptr;
}
@@ -63,4 +63,9 @@ void Params::set_default_remaining_outputs()
}
}
+bool Params::try_enable_multi_threading_impl()
+{
+ return false;
+}
+
} // namespace blender::fn::lazy_function
diff --git a/source/blender/functions/intern/lazy_function_execute.cc b/source/blender/functions/intern/lazy_function_execute.cc
index 279056afa99..cea9b48d5bc 100644
--- a/source/blender/functions/intern/lazy_function_execute.cc
+++ b/source/blender/functions/intern/lazy_function_execute.cc
@@ -14,7 +14,7 @@ BasicParams::BasicParams(const LazyFunction &fn,
MutableSpan<std::optional<ValueUsage>> input_usages,
Span<ValueUsage> output_usages,
MutableSpan<bool> set_outputs)
- : Params(fn),
+ : Params(fn, true),
inputs_(inputs),
outputs_(outputs),
input_usages_(input_usages),
@@ -62,4 +62,9 @@ void BasicParams::set_input_unused_impl(const int index)
input_usages_[index] = ValueUsage::Unused;
}
+bool BasicParams::try_enable_multi_threading_impl()
+{
+ return true;
+}
+
} // namespace blender::fn::lazy_function
diff --git a/source/blender/functions/intern/lazy_function_graph_executor.cc b/source/blender/functions/intern/lazy_function_graph_executor.cc
index 176509bd687..4c5c3fa47a2 100644
--- a/source/blender/functions/intern/lazy_function_graph_executor.cc
+++ b/source/blender/functions/intern/lazy_function_graph_executor.cc
@@ -3,18 +3,20 @@
/**
* This file implements the evaluation of a lazy-function graph. It's main objectives are:
* - Only compute values that are actually used.
- * - Allow spreading the work over an arbitrary number of CPU cores.
+ * - Stay single threaded when nodes are executed quickly.
+ * - Allow spreading the work over an arbitrary number of threads efficiently.
*
- * Other (simpler) executors with different main objectives could be implemented in the future. For
- * some scenarios those could be simpler when many nodes do very little work or most nodes have to
- * be processed sequentially. Those assumptions make the first and second objective less important
- * respectively.
+ * This executor makes use of `FN_lazy_threading.hh` to enable multi-threading only when it seems
+ * beneficial. It operates in two modes: single- and multi-threaded. The use of a task pool and
+ * locks is avoided in single-threaded mode. Once multi-threading is enabled the executor starts
+ * using both. It is not possible to switch back from multi-threaded to single-threaded mode.
*
- * The design implemented in this executor requires *no* main thread that coordinates everything.
- * Instead, one thread will trigger some initial work and then many threads coordinate themselves
- * in a distributed fashion. In an ideal situation, every thread ends up processing a separate part
- * of the graph which results in less communication overhead. The way TBB schedules tasks helps
- * with that: a thread will next process the task that it added to a task pool just before.
+ * The multi-threading design implemented in this executor requires *no* main thread that
+ * coordinates everything. Instead, one thread will trigger some initial work and then many threads
+ * coordinate themselves in a distributed fashion. In an ideal situation, every thread ends up
+ * processing a separate part of the graph which results in less communication overhead. The way
+ * TBB schedules tasks helps with that: a thread will next process the task that it added to a task
+ * pool just before.
*
* Communication between threads is synchronized by using a mutex in every node. When a thread
* wants to access the state of a node, its mutex has to be locked first (with some documented
@@ -26,15 +28,14 @@
* state of its inputs and outputs. Every time a node is executed, it has to advance its state in
* some way (e.g. it requests a new input or computes a new output).
*
- * At the core of the executor is a task pool. Every task in that pool represents a node execution.
- * When a node is executed it may send notifications to other nodes which may in turn add those
- * nodes to the task pool. For example, the current node has computed one of its outputs, then the
+ * When a node is executed it may send notifications to other nodes which may in turn schedule
+ * those nodes. For example, when the current node has computed one of its outputs, then the
* computed value is forwarded to all linked inputs, changing their node states in the process. If
- * this input was the last missing required input, the node will be added to the task pool so that
- * it is executed next.
+ * this input was the last missing required input, the node will be scheduled that it is executed
+ * next.
*
- * When the task pool is empty, the executor gives back control to the caller which may later
- * provide new inputs to the graph which in turn adds new nodes to the task pool and the process
+ * When all tasks are completed, the executor gives back control to the caller which may later
+ * provide new inputs to the graph which in turn leads to new nodes being scheduled and the process
* starts again.
*/
@@ -190,27 +191,31 @@ struct LockedNode {
*/
Vector<const OutputSocket *> delayed_required_outputs;
Vector<const OutputSocket *> delayed_unused_outputs;
- Vector<const FunctionNode *> delayed_scheduled_nodes;
LockedNode(const Node &node, NodeState &node_state) : node(node), node_state(node_state)
{
}
};
+class Executor;
+class GraphExecutorLFParams;
+
struct CurrentTask {
/**
- * The node that should be run on the same thread after the current node is done. This avoids
- * some overhead by skipping a round trip through the task pool.
+ * Mutex used to protect #scheduled_nodes when the executor uses multi-threading.
*/
- std::atomic<const FunctionNode *> next_node = nullptr;
+ std::mutex mutex;
/**
- * Indicates that some node has been added to the task pool.
+ * Nodes that have been scheduled to execute next.
*/
- std::atomic<bool> added_node_to_pool = false;
+ Vector<const FunctionNode *> scheduled_nodes;
+ /**
+ * Makes it cheaper to check if there are any scheduled nodes because it avoids locking the
+ * mutex.
+ */
+ std::atomic<bool> has_scheduled_nodes = false;
};
-class GraphExecutorLFParams;
-
class Executor {
private:
const GraphExecutor &self_;
@@ -230,13 +235,18 @@ class Executor {
const Context *context_ = nullptr;
/**
* Used to distribute work on separate nodes to separate threads.
+ * If this is empty, the executor is in single threaded mode.
*/
- TaskPool *task_pool_ = nullptr;
+ std::atomic<TaskPool *> task_pool_ = nullptr;
+#ifdef FN_LAZY_FUNCTION_DEBUG_THREADS
+ std::thread::id current_main_thread_;
+#endif
/**
* A separate linear allocator for every thread. We could potentially reuse some memory, but that
* doesn't seem worth it yet.
*/
threading::EnumerableThreadSpecific<LinearAllocator<>> local_allocators_;
+ LinearAllocator<> *main_local_allocator_ = nullptr;
/**
* Set to false when the first execution ends.
*/
@@ -249,11 +259,14 @@ class Executor {
{
/* The indices are necessary, because they are used as keys in #node_states_. */
BLI_assert(self_.graph_.node_indices_are_valid());
+ main_local_allocator_ = &local_allocators_.local();
}
~Executor()
{
- BLI_task_pool_free(task_pool_);
+ if (TaskPool *task_pool = task_pool_.load()) {
+ BLI_task_pool_free(task_pool);
+ }
threading::parallel_for(node_states_.index_range(), 1024, [&](const IndexRange range) {
for (const int node_index : range) {
const Node &node = *self_.graph_.nodes()[node_index];
@@ -270,18 +283,23 @@ class Executor {
{
params_ = &params;
context_ = &context;
- BLI_SCOPED_DEFER([&]() {
- /* Make sure the #params_ pointer is not dangling, even when it shouldn't be accessed by
- * anyone. */
+#ifdef FN_LAZY_FUNCTION_DEBUG_THREADS
+ current_main_thread_ = std::this_thread::get_id();
+#endif
+ const auto deferred_func = [&]() {
+ /* Make sure the pointers are not dangling, even when it shouldn't be accessed by anyone. */
params_ = nullptr;
context_ = nullptr;
is_first_execution_ = false;
- });
+#ifdef FN_LAZY_FUNCTION_DEBUG_THREADS
+ current_main_thread_ = {};
+#endif
+ };
+ BLI_SCOPED_DEFER(deferred_func);
CurrentTask current_task;
if (is_first_execution_) {
this->initialize_node_states();
- task_pool_ = BLI_task_pool_create(this, TASK_PRIORITY_HIGH);
/* Initialize atomics to zero. */
memset(static_cast<void *>(loaded_inputs_.data()), 0, loaded_inputs_.size() * sizeof(bool));
@@ -294,21 +312,11 @@ class Executor {
this->schedule_newly_requested_outputs(current_task);
this->forward_newly_provided_inputs(current_task);
- /* Avoid using task pool when there is no parallel work to do. */
- while (!current_task.added_node_to_pool) {
- if (current_task.next_node == nullptr) {
- /* Nothing to do. */
- return;
- }
- const FunctionNode &node = *current_task.next_node;
- current_task.next_node = nullptr;
- this->run_node_task(node, current_task);
- }
- if (current_task.next_node != nullptr) {
- this->add_node_to_task_pool(*current_task.next_node);
- }
+ this->run_task(current_task);
- BLI_task_pool_work_and_wait(task_pool_);
+ if (TaskPool *task_pool = task_pool_.load()) {
+ BLI_task_pool_work_and_wait(task_pool);
+ }
}
private:
@@ -426,7 +434,7 @@ class Executor {
NodeState &node_state = *node_states_[node->index_in_graph()];
node_state.has_side_effects = true;
this->with_locked_node(*node, node_state, current_task, [&](LockedNode &locked_node) {
- this->schedule_node(locked_node);
+ this->schedule_node(locked_node, current_task);
});
}
}
@@ -434,7 +442,7 @@ class Executor {
void forward_newly_provided_inputs(CurrentTask &current_task)
{
- LinearAllocator<> &allocator = local_allocators_.local();
+ LinearAllocator<> &allocator = this->get_main_or_local_allocator();
for (const int graph_input_index : self_.graph_inputs_.index_range()) {
std::atomic<uint8_t> &was_loaded = loaded_inputs_[graph_input_index];
if (was_loaded.load()) {
@@ -488,7 +496,7 @@ class Executor {
return;
}
this->forward_newly_provided_input(
- current_task, local_allocators_.local(), graph_input_index, input_data);
+ current_task, this->get_main_or_local_allocator(), graph_input_index, input_data);
return;
}
@@ -498,7 +506,7 @@ class Executor {
return;
}
output_state.usage = ValueUsage::Used;
- this->schedule_node(locked_node);
+ this->schedule_node(locked_node, current_task);
});
}
@@ -520,25 +528,28 @@ class Executor {
params_->set_input_unused(graph_input_index);
}
else {
- this->schedule_node(locked_node);
+ this->schedule_node(locked_node, current_task);
}
}
}
});
}
- void schedule_node(LockedNode &locked_node)
+ void schedule_node(LockedNode &locked_node, CurrentTask &current_task)
{
BLI_assert(locked_node.node.is_function());
switch (locked_node.node_state.schedule_state) {
case NodeScheduleState::NotScheduled: {
- /* Don't add the node to the task pool immediately, because the task pool might start
- * executing it immediately (when Blender is started with a single thread).
- * That would often result in a deadlock, because we are still holding the mutex of the
- * current node. Also see comments in #LockedNode. */
locked_node.node_state.schedule_state = NodeScheduleState::Scheduled;
- locked_node.delayed_scheduled_nodes.append(
- &static_cast<const FunctionNode &>(locked_node.node));
+ const FunctionNode &node = static_cast<const FunctionNode &>(locked_node.node);
+ if (this->use_multi_threading()) {
+ std::lock_guard lock{current_task.mutex};
+ current_task.scheduled_nodes.append(&node);
+ }
+ else {
+ current_task.scheduled_nodes.append(&node);
+ }
+ current_task.has_scheduled_nodes.store(true, std::memory_order_relaxed);
break;
}
case NodeScheduleState::Scheduled: {
@@ -562,14 +573,16 @@ class Executor {
BLI_assert(&node_state == node_states_[node.index_in_graph()]);
LockedNode locked_node{node, node_state};
- {
+ if (this->use_multi_threading()) {
std::lock_guard lock{node_state.mutex};
threading::isolate_task([&]() { f(locked_node); });
}
+ else {
+ f(locked_node);
+ }
this->send_output_required_notifications(locked_node.delayed_required_outputs, current_task);
this->send_output_unused_notifications(locked_node.delayed_unused_outputs, current_task);
- this->schedule_new_nodes(locked_node.delayed_scheduled_nodes, current_task);
}
void send_output_required_notifications(const Span<const OutputSocket *> sockets,
@@ -588,49 +601,21 @@ class Executor {
}
}
- void schedule_new_nodes(const Span<const FunctionNode *> nodes, CurrentTask &current_task)
+ void run_task(CurrentTask &current_task)
{
- for (const FunctionNode *node_to_schedule : nodes) {
- /* Avoid a round trip through the task pool for the first node that is scheduled by the
- * current node execution. Other nodes are added to the pool so that other threads can pick
- * them up. */
- const FunctionNode *expected = nullptr;
- if (current_task.next_node.compare_exchange_strong(
- expected, node_to_schedule, std::memory_order_relaxed)) {
- continue;
+ while (!current_task.scheduled_nodes.is_empty()) {
+ const FunctionNode &node = *current_task.scheduled_nodes.pop_last();
+ if (current_task.scheduled_nodes.is_empty()) {
+ current_task.has_scheduled_nodes.store(false, std::memory_order_relaxed);
}
- this->add_node_to_task_pool(*node_to_schedule);
- current_task.added_node_to_pool.store(true, std::memory_order_relaxed);
- }
- }
-
- void add_node_to_task_pool(const Node &node)
- {
- BLI_task_pool_push(
- task_pool_, Executor::run_node_from_task_pool, (void *)&node, false, nullptr);
- }
-
- static void run_node_from_task_pool(TaskPool *task_pool, void *task_data)
- {
- void *user_data = BLI_task_pool_user_data(task_pool);
- Executor &executor = *static_cast<Executor *>(user_data);
- const FunctionNode &node = *static_cast<const FunctionNode *>(task_data);
-
- /* This loop reduces the number of round trips through the task pool as long as the current
- * node is scheduling more nodes. */
- CurrentTask current_task;
- current_task.next_node = &node;
- while (current_task.next_node != nullptr) {
- const FunctionNode &node_to_run = *current_task.next_node;
- current_task.next_node = nullptr;
- executor.run_node_task(node_to_run, current_task);
+ this->run_node_task(node, current_task);
}
}
void run_node_task(const FunctionNode &node, CurrentTask &current_task)
{
NodeState &node_state = *node_states_[node.index_in_graph()];
- LinearAllocator<> &allocator = local_allocators_.local();
+ LinearAllocator<> &allocator = this->get_main_or_local_allocator();
const LazyFunction &fn = node.function();
bool node_needs_execution = false;
@@ -672,7 +657,7 @@ class Executor {
}
void *buffer = allocator.allocate(type.size(), type.alignment());
type.copy_construct(default_value, buffer);
- this->forward_value_to_input(locked_node, input_state, {type, buffer});
+ this->forward_value_to_input(locked_node, input_state, {type, buffer}, current_task);
}
/* Request linked inputs that are always needed. */
@@ -723,7 +708,7 @@ class Executor {
NodeScheduleState::RunningAndRescheduled;
node_state.schedule_state = NodeScheduleState::NotScheduled;
if (reschedule_requested && !node_state.node_has_finished) {
- this->schedule_node(locked_node);
+ this->schedule_node(locked_node, current_task);
}
});
}
@@ -887,7 +872,7 @@ class Executor {
CurrentTask &current_task)
{
BLI_assert(value_to_forward.get() != nullptr);
- LinearAllocator<> &allocator = local_allocators_.local();
+ LinearAllocator<> &allocator = this->get_main_or_local_allocator();
const CPPType &type = *value_to_forward.type();
if (self_.logger_ != nullptr) {
@@ -938,13 +923,13 @@ class Executor {
}
if (is_last_target) {
/* No need to make a copy if this is the last target. */
- this->forward_value_to_input(locked_node, input_state, value_to_forward);
+ this->forward_value_to_input(locked_node, input_state, value_to_forward, current_task);
value_to_forward = {};
}
else {
void *buffer = allocator.allocate(type.size(), type.alignment());
type.copy_construct(value_to_forward.get(), buffer);
- this->forward_value_to_input(locked_node, input_state, {type, buffer});
+ this->forward_value_to_input(locked_node, input_state, {type, buffer}, current_task);
}
});
}
@@ -955,7 +940,8 @@ class Executor {
void forward_value_to_input(LockedNode &locked_node,
InputState &input_state,
- GMutablePointer value)
+ GMutablePointer value,
+ CurrentTask &current_task)
{
NodeState &node_state = locked_node.node_state;
@@ -966,10 +952,82 @@ class Executor {
if (input_state.usage == ValueUsage::Used) {
node_state.missing_required_inputs -= 1;
if (node_state.missing_required_inputs == 0) {
- this->schedule_node(locked_node);
+ this->schedule_node(locked_node, current_task);
}
}
}
+
+ bool use_multi_threading() const
+ {
+ return task_pool_.load() != nullptr;
+ }
+
+ bool try_enable_multi_threading()
+ {
+ if (this->use_multi_threading()) {
+ return true;
+ }
+#ifdef FN_LAZY_FUNCTION_DEBUG_THREADS
+ /* Only the current main thread is allowed to enabled multi-threading, because the executor is
+ * still in single-threaded mode. */
+ if (current_main_thread_ != std::this_thread::get_id()) {
+ BLI_assert_unreachable();
+ }
+#endif
+ /* Check of the caller supports multi-threading. */
+ if (!params_->try_enable_multi_threading()) {
+ return false;
+ }
+ /* Avoid using multiple threads when only one thread can be used anyway. */
+ if (BLI_system_thread_count() <= 1) {
+ return false;
+ }
+ task_pool_.store(BLI_task_pool_create(this, TASK_PRIORITY_HIGH));
+ return true;
+ }
+
+ /**
+ * Allow other threads to steal all the nodes that are currently scheduled on this thread.
+ */
+ void move_scheduled_nodes_to_task_pool(CurrentTask &current_task)
+ {
+ BLI_assert(this->use_multi_threading());
+ using FunctionNodeVector = Vector<const FunctionNode *>;
+ FunctionNodeVector *nodes = MEM_new<FunctionNodeVector>(__func__);
+ {
+ std::lock_guard lock{current_task.mutex};
+ if (current_task.scheduled_nodes.is_empty()) {
+ return;
+ }
+ *nodes = std::move(current_task.scheduled_nodes);
+ current_task.has_scheduled_nodes.store(false, std::memory_order_relaxed);
+ }
+ /* All nodes are pushed as a single task in the pool. This avoids unnecessary threading
+ * overhead when the nodes are fast to compute. */
+ BLI_task_pool_push(
+ task_pool_.load(),
+ [](TaskPool *pool, void *data) {
+ Executor &executor = *static_cast<Executor *>(BLI_task_pool_user_data(pool));
+ FunctionNodeVector &nodes = *static_cast<FunctionNodeVector *>(data);
+ CurrentTask new_current_task;
+ new_current_task.scheduled_nodes = std::move(nodes);
+ new_current_task.has_scheduled_nodes.store(true, std::memory_order_relaxed);
+ executor.run_task(new_current_task);
+ },
+ nodes,
+ true,
+ [](TaskPool * /*pool*/, void *data) {
+ MEM_delete(static_cast<FunctionNodeVector *>(data));
+ });
+ }
+
+ LinearAllocator<> &get_main_or_local_allocator()
+ {
+ if (this->use_multi_threading()) {
+ return local_allocators_.local();
+ }
+ return *main_local_allocator_;
+ }
};
class GraphExecutorLFParams final : public Params {
@@ -985,7 +1043,7 @@ class GraphExecutorLFParams final : public Params {
const Node &node,
NodeState &node_state,
CurrentTask &current_task)
- : Params(fn),
+ : Params(fn, executor.use_multi_threading()),
executor_(executor),
node_(node),
node_state_(node_state),
@@ -1017,7 +1075,7 @@ class GraphExecutorLFParams final : public Params {
OutputState &output_state = node_state_.outputs[index];
BLI_assert(!output_state.has_been_computed);
if (output_state.value == nullptr) {
- LinearAllocator<> &allocator = executor_.local_allocators_.local();
+ LinearAllocator<> &allocator = executor_.get_main_or_local_allocator();
const CPPType &type = node_.output(index).type();
output_state.value = allocator.allocate(type.size(), type.alignment());
}
@@ -1052,6 +1110,11 @@ class GraphExecutorLFParams final : public Params {
{
executor_.set_input_unused_during_execution(node_, node_state_, index, current_task_);
}
+
+ bool try_enable_multi_threading_impl() override
+ {
+ return executor_.try_enable_multi_threading();
+ }
};
/**
@@ -1073,6 +1136,20 @@ inline void Executor::execute_node(const FunctionNode &node,
self_.logger_->log_before_node_execute(node, node_params, fn_context);
}
+ /* This is run when the execution of the node calls `lazy_threading::send_hint` to indicate that
+ * the execution will take a while. In this case, other tasks waiting on this thread should be
+ * allowed to be picked up by another thread. */
+ auto blocking_hint_fn = [&]() {
+ if (!current_task.has_scheduled_nodes.load()) {
+ return;
+ }
+ if (!this->try_enable_multi_threading()) {
+ return;
+ }
+ this->move_scheduled_nodes_to_task_pool(current_task);
+ };
+
+ lazy_threading::HintReceiver blocking_hint_receiver{blocking_hint_fn};
fn.execute(node_params, fn_context);
if (self_.logger_ != nullptr) {
diff --git a/source/blender/functions/intern/multi_function_builder.cc b/source/blender/functions/intern/multi_function_builder.cc
index 020d6ba0139..32a41f99c48 100644
--- a/source/blender/functions/intern/multi_function_builder.cc
+++ b/source/blender/functions/intern/multi_function_builder.cc
@@ -27,14 +27,12 @@ CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type,
CustomMF_GenericConstant::~CustomMF_GenericConstant()
{
if (owns_value_) {
- signature_.param_types[0].data_type().single_type().destruct((void *)value_);
- MEM_freeN((void *)value_);
+ signature_.param_types[0].data_type().single_type().destruct(const_cast<void *>(value_));
+ MEM_freeN(const_cast<void *>(value_));
}
}
-void CustomMF_GenericConstant::call(IndexMask mask,
- MFParams params,
- MFContext UNUSED(context)) const
+void CustomMF_GenericConstant::call(IndexMask mask, MFParams params, MFContext /*context*/) const
{
GMutableSpan output = params.uninitialized_single_output(0);
type_.fill_construct_indices(value_, output.data(), mask);
@@ -42,7 +40,7 @@ void CustomMF_GenericConstant::call(IndexMask mask,
uint64_t CustomMF_GenericConstant::hash() const
{
- return type_.hash_or_fallback(value_, (uintptr_t)this);
+ return type_.hash_or_fallback(value_, uintptr_t(this));
}
bool CustomMF_GenericConstant::equals(const MultiFunction &other) const
@@ -68,7 +66,7 @@ CustomMF_GenericConstantArray::CustomMF_GenericConstantArray(GSpan array) : arra
void CustomMF_GenericConstantArray::call(IndexMask mask,
MFParams params,
- MFContext UNUSED(context)) const
+ MFContext /*context*/) const
{
GVectorArray &vectors = params.vector_output(0);
for (int64_t i : mask) {
@@ -90,7 +88,7 @@ CustomMF_DefaultOutput::CustomMF_DefaultOutput(Span<MFDataType> input_types,
signature_ = signature.build();
this->set_signature(&signature_);
}
-void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const
+void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext /*context*/) const
{
for (int param_index : this->param_indices()) {
MFParamType param_type = this->param_type(param_index);
@@ -115,7 +113,7 @@ CustomMF_GenericCopy::CustomMF_GenericCopy(MFDataType data_type)
this->set_signature(&signature_);
}
-void CustomMF_GenericCopy::call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const
+void CustomMF_GenericCopy::call(IndexMask mask, MFParams params, MFContext /*context*/) const
{
const MFDataType data_type = this->param_type(0).data_type();
switch (data_type.category()) {
diff --git a/source/blender/functions/intern/multi_function_procedure.cc b/source/blender/functions/intern/multi_function_procedure.cc
index 7ad324a9574..b78787de57c 100644
--- a/source/blender/functions/intern/multi_function_procedure.cc
+++ b/source/blender/functions/intern/multi_function_procedure.cc
@@ -801,12 +801,12 @@ class MFProcedureDotExport {
variable_to_string(instruction.variable(), ss);
}
- void instruction_to_string(const MFDummyInstruction &UNUSED(instruction), std::stringstream &ss)
+ void instruction_to_string(const MFDummyInstruction & /*instruction*/, std::stringstream &ss)
{
instruction_name_format("Dummy ", ss);
}
- void instruction_to_string(const MFReturnInstruction &UNUSED(instruction), std::stringstream &ss)
+ void instruction_to_string(const MFReturnInstruction & /*instruction*/, std::stringstream &ss)
{
instruction_name_format("Return ", ss);
diff --git a/source/blender/functions/intern/multi_function_procedure_executor.cc b/source/blender/functions/intern/multi_function_procedure_executor.cc
index 7d9b2fcd1f0..4fe3c27ea27 100644
--- a/source/blender/functions/intern/multi_function_procedure_executor.cc
+++ b/source/blender/functions/intern/multi_function_procedure_executor.cc
@@ -289,7 +289,7 @@ class ValueAllocator : NonCopyable, NonMovable {
}
}
- Stack<VariableValue *> &stack = variable_value_free_lists_[(int)value->type];
+ Stack<VariableValue *> &stack = variable_value_free_lists_[int(value->type)];
stack.push(value);
}
@@ -297,7 +297,7 @@ class ValueAllocator : NonCopyable, NonMovable {
template<typename T, typename... Args> T *obtain(Args &&...args)
{
static_assert(std::is_base_of_v<VariableValue, T>);
- Stack<VariableValue *> &stack = variable_value_free_lists_[(int)T::static_type];
+ Stack<VariableValue *> &stack = variable_value_free_lists_[int(T::static_type)];
if (stack.is_empty()) {
void *buffer = linear_allocator_.allocate(sizeof(T), alignof(T));
return new (buffer) T(std::forward<Args>(args)...);
@@ -449,7 +449,7 @@ class VariableState : NonCopyable, NonMovable {
}
else {
new_value = value_allocator.obtain_GVectorArray_not_owned(
- *(GVectorArray *)caller_provided_storage_);
+ *static_cast<GVectorArray *>(caller_provided_storage_));
}
if (value_ != nullptr) {
if (value_->type == ValueType::GVVectorArray) {
@@ -780,8 +780,9 @@ class VariableState : NonCopyable, NonMovable {
break;
}
case ValueType::Span: {
- const Span<bool> span((bool *)this->value_as<VariableValue_Span>()->data,
- mask.min_array_size());
+ const Span<bool> span(
+ static_cast<const bool *>(this->value_as<VariableValue_Span>()->data),
+ mask.min_array_size());
for (const int i : mask) {
r_indices[span[i]].append(i);
}
@@ -790,7 +791,7 @@ class VariableState : NonCopyable, NonMovable {
case ValueType::OneSingle: {
auto *value_typed = this->value_as<VariableValue_OneSingle>();
BLI_assert(value_typed->is_initialized);
- const bool condition = *(bool *)value_typed->data;
+ const bool condition = *static_cast<const bool *>(value_typed->data);
r_indices[condition].extend(mask);
break;
}
diff --git a/source/blender/functions/tests/FN_field_test.cc b/source/blender/functions/tests/FN_field_test.cc
index ea3c0471411..8c5cc817174 100644
--- a/source/blender/functions/tests/FN_field_test.cc
+++ b/source/blender/functions/tests/FN_field_test.cc
@@ -34,9 +34,9 @@ class IndexFieldInput final : public FieldInput {
{
}
- GVArray get_varray_for_context(const FieldContext &UNUSED(context),
+ GVArray get_varray_for_context(const FieldContext & /*context*/,
IndexMask mask,
- ResourceScope &UNUSED(scope)) const final
+ ResourceScope & /*scope*/) const final
{
auto index_func = [](int i) { return i; };
return VArray<int>::ForFunc(mask.min_array_size(), index_func);
@@ -171,7 +171,7 @@ class TwoOutputFunction : public MultiFunction {
this->set_signature(&signature_);
}
- void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
{
const VArray<int> &in1 = params.readonly_single_input<int>(0, "In1");
const VArray<int> &in2 = params.readonly_single_input<int>(1, "In2");
diff --git a/source/blender/functions/tests/FN_lazy_function_test.cc b/source/blender/functions/tests/FN_lazy_function_test.cc
index 8df064cd8a6..dc1c698598d 100644
--- a/source/blender/functions/tests/FN_lazy_function_test.cc
+++ b/source/blender/functions/tests/FN_lazy_function_test.cc
@@ -21,7 +21,7 @@ class AddLazyFunction : public LazyFunction {
outputs_.append({"Result", CPPType::get<int>()});
}
- void execute_impl(Params &params, const Context &UNUSED(context)) const override
+ void execute_impl(Params &params, const Context & /*context*/) const override
{
const int a = params.get_input<int>(0);
const int b = params.get_input<int>(1);
@@ -42,7 +42,7 @@ class StoreValueFunction : public LazyFunction {
inputs_.append({"B", CPPType::get<int>(), ValueUsage::Maybe});
}
- void execute_impl(Params &params, const Context &UNUSED(context)) const override
+ void execute_impl(Params &params, const Context & /*context*/) const override
{
*dst1_ = params.get_input<int>(0);
if (int *value = params.try_get_input_data_ptr_or_request<int>(1)) {
@@ -62,7 +62,7 @@ class SimpleSideEffectProvider : public GraphExecutor::SideEffectProvider {
}
Vector<const FunctionNode *> get_nodes_with_side_effects(
- const Context &UNUSED(context)) const override
+ const Context & /*context*/) const override
{
return side_effect_nodes_;
}
diff --git a/source/blender/functions/tests/FN_multi_function_test.cc b/source/blender/functions/tests/FN_multi_function_test.cc
index 577b09cb014..ca788b0a6ee 100644
--- a/source/blender/functions/tests/FN_multi_function_test.cc
+++ b/source/blender/functions/tests/FN_multi_function_test.cc
@@ -26,7 +26,7 @@ class AddFunction : public MultiFunction {
return signature.build();
}
- void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
{
const VArray<int> &a = params.readonly_single_input<int>(0, "A");
const VArray<int> &b = params.readonly_single_input<int>(1, "B");
@@ -198,7 +198,7 @@ TEST(multi_function, CustomMF_SI_SI_SI_SO)
{
CustomMF_SI_SI_SI_SO<int, std::string, bool, uint> fn{
"custom",
- [](int a, const std::string &b, bool c) { return (uint)((uint)a + b.size() + (uint)c); }};
+ [](int a, const std::string &b, bool c) { return uint(uint(a) + b.size() + uint(c)); }};
Array<int> values_a = {5, 7, 3, 8};
Array<std::string> values_b = {"hello", "world", "another", "test"};
diff --git a/source/blender/functions/tests/FN_multi_function_test_common.hh b/source/blender/functions/tests/FN_multi_function_test_common.hh
index a01a3fa27c6..15e8baf2001 100644
--- a/source/blender/functions/tests/FN_multi_function_test_common.hh
+++ b/source/blender/functions/tests/FN_multi_function_test_common.hh
@@ -20,7 +20,7 @@ class AddPrefixFunction : public MultiFunction {
return signature.build();
}
- void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
{
const VArray<std::string> &prefixes = params.readonly_single_input<std::string>(0, "Prefix");
MutableSpan<std::string> strings = params.single_mutable<std::string>(1, "Strings");
@@ -47,7 +47,7 @@ class CreateRangeFunction : public MultiFunction {
return signature.build();
}
- void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
{
const VArray<int> &sizes = params.readonly_single_input<int>(0, "Size");
GVectorArray &ranges = params.vector_output(1, "Range");
@@ -75,7 +75,7 @@ class GenericAppendFunction : public MultiFunction {
this->set_signature(&signature_);
}
- void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
{
GVectorArray &vectors = params.vector_mutable(0, "Vector");
const GVArray &values = params.readonly_single_input(1, "Value");
@@ -105,7 +105,7 @@ class ConcatVectorsFunction : public MultiFunction {
return signature.build();
}
- void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
{
GVectorArray &a = params.vector_mutable(0);
const GVVectorArray &b = params.readonly_vector_input(1);
@@ -129,7 +129,7 @@ class AppendFunction : public MultiFunction {
return signature.build();
}
- void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
{
GVectorArray_TypedMutableRef<int> vectors = params.vector_mutable<int>(0);
const VArray<int> &values = params.readonly_single_input<int>(1);
@@ -156,7 +156,7 @@ class SumVectorFunction : public MultiFunction {
return signature.build();
}
- void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
{
const VVectorArray<int> &vectors = params.readonly_vector_input<int>(0);
MutableSpan<int> sums = params.uninitialized_single_output<int>(1);
@@ -187,7 +187,7 @@ class OptionalOutputsFunction : public MultiFunction {
return signature.build();
}
- void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
{
if (params.single_output_is_required(0, "Out 1")) {
MutableSpan<int> values = params.uninitialized_single_output<int>(0, "Out 1");
diff --git a/source/blender/geometry/CMakeLists.txt b/source/blender/geometry/CMakeLists.txt
index 0f06890cbfa..9e1929b60a8 100644
--- a/source/blender/geometry/CMakeLists.txt
+++ b/source/blender/geometry/CMakeLists.txt
@@ -27,6 +27,7 @@ set(SRC
intern/reverse_uv_sampler.cc
intern/set_curve_type.cc
intern/subdivide_curves.cc
+ intern/trim_curves.cc
intern/uv_parametrizer.cc
GEO_add_curves_on_mesh.hh
@@ -41,6 +42,7 @@ set(SRC
GEO_reverse_uv_sampler.hh
GEO_set_curve_type.hh
GEO_subdivide_curves.hh
+ GEO_trim_curves.hh
GEO_uv_parametrizer.h
)
diff --git a/source/blender/geometry/GEO_resample_curves.hh b/source/blender/geometry/GEO_resample_curves.hh
index 7ecfb5c26ec..35365167eba 100644
--- a/source/blender/geometry/GEO_resample_curves.hh
+++ b/source/blender/geometry/GEO_resample_curves.hh
@@ -4,12 +4,18 @@
#include "FN_field.hh"
+#include "BKE_anonymous_attribute.hh"
#include "BKE_curves.hh"
namespace blender::geometry {
using bke::CurvesGeometry;
+struct ResampleCurvesOutputAttributeIDs {
+ bke::AttributeIDRef tangent_id;
+ bke::AttributeIDRef normal_id;
+};
+
/**
* Create new curves where the selected curves have been resampled with a number of uniform-length
* samples defined by the count field. Interpolate attributes to the result, with an accuracy that
@@ -19,7 +25,8 @@ using bke::CurvesGeometry;
*/
CurvesGeometry resample_to_count(const CurvesGeometry &src_curves,
const fn::Field<bool> &selection_field,
- const fn::Field<int> &count_field);
+ const fn::Field<int> &count_field,
+ const ResampleCurvesOutputAttributeIDs &output_ids = {});
/**
* Create new curves resampled to make each segment have the length specified by the
@@ -28,12 +35,14 @@ CurvesGeometry resample_to_count(const CurvesGeometry &src_curves,
*/
CurvesGeometry resample_to_length(const CurvesGeometry &src_curves,
const fn::Field<bool> &selection_field,
- const fn::Field<float> &segment_length_field);
+ const fn::Field<float> &segment_length_field,
+ const ResampleCurvesOutputAttributeIDs &output_ids = {});
/**
* Evaluate each selected curve to its implicit evaluated points.
*/
CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves,
- const fn::Field<bool> &selection_field);
+ const fn::Field<bool> &selection_field,
+ const ResampleCurvesOutputAttributeIDs &output_ids = {});
} // namespace blender::geometry
diff --git a/source/blender/geometry/GEO_trim_curves.hh b/source/blender/geometry/GEO_trim_curves.hh
new file mode 100644
index 00000000000..197ef79c25b
--- /dev/null
+++ b/source/blender/geometry/GEO_trim_curves.hh
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include "BLI_span.hh"
+#include "DNA_node_types.h"
+
+#include "BKE_curves.hh"
+#include "BKE_curves_utils.hh"
+#include "BKE_geometry_set.hh"
+
+namespace blender::geometry {
+
+/*
+ * Create a new Curves instance by trimming the input curves. Copying the selected splines
+ * between the start and end points.
+ */
+bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves,
+ IndexMask selection,
+ const VArray<float> &starts,
+ const VArray<float> &ends,
+ GeometryNodeCurveSampleMode mode);
+
+} // namespace blender::geometry
diff --git a/source/blender/geometry/intern/add_curves_on_mesh.cc b/source/blender/geometry/intern/add_curves_on_mesh.cc
index bb5e2a0a28a..a03c9b994a9 100644
--- a/source/blender/geometry/intern/add_curves_on_mesh.cc
+++ b/source/blender/geometry/intern/add_curves_on_mesh.cc
@@ -51,7 +51,7 @@ static void initialize_straight_curve_positions(const float3 &p1,
const float3 &p2,
MutableSpan<float3> r_positions)
{
- const float step = 1.0f / (float)(r_positions.size() - 1);
+ const float step = 1.0f / float(r_positions.size() - 1);
for (const int i : r_positions.index_range()) {
r_positions[i] = math::interpolate(p1, p2, i * step);
}
@@ -385,10 +385,11 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves,
return true;
}
bke::GSpanAttributeWriter attribute = attributes.lookup_for_write_span(id);
- const int new_elements_num = attribute.domain == ATTR_DOMAIN_POINT ? new_points_num :
- new_curves_num;
+ /* The new elements are added at the end of the array. */
+ const int old_elements_num = attribute.domain == ATTR_DOMAIN_POINT ? old_points_num :
+ old_curves_num;
const CPPType &type = attribute.span.type();
- GMutableSpan new_data = attribute.span.take_back(new_elements_num);
+ GMutableSpan new_data = attribute.span.drop_front(old_elements_num);
type.fill_assign_n(type.default_value(), new_data.data(), new_data.size());
attribute.finish();
return true;
diff --git a/source/blender/geometry/intern/fillet_curves.cc b/source/blender/geometry/intern/fillet_curves.cc
index 1bbbee6edef..2479458f88d 100644
--- a/source/blender/geometry/intern/fillet_curves.cc
+++ b/source/blender/geometry/intern/fillet_curves.cc
@@ -148,12 +148,14 @@ static float limit_radius(const float3 &position_prev,
const float displacement_prev = radius_prev * std::tan(angle_prev / 2.0f);
const float segment_length_prev = math::distance(position, position_prev);
const float total_displacement_prev = displacement_prev + displacement;
- const float factor_prev = std::clamp(segment_length_prev / total_displacement_prev, 0.0f, 1.0f);
+ const float factor_prev = std::clamp(
+ safe_divide(segment_length_prev, total_displacement_prev), 0.0f, 1.0f);
const float displacement_next = radius_next * std::tan(angle_next / 2.0f);
const float segment_length_next = math::distance(position, position_next);
const float total_displacement_next = displacement_next + displacement;
- const float factor_next = std::clamp(segment_length_next / total_displacement_next, 0.0f, 1.0f);
+ const float factor_next = std::clamp(
+ safe_divide(segment_length_next, total_displacement_next), 0.0f, 1.0f);
return radius * std::min(factor_prev, factor_next);
}
diff --git a/source/blender/geometry/intern/mesh_merge_by_distance.cc b/source/blender/geometry/intern/mesh_merge_by_distance.cc
index 17318c277aa..288fd407641 100644
--- a/source/blender/geometry/intern/mesh_merge_by_distance.cc
+++ b/source/blender/geometry/intern/mesh_merge_by_distance.cc
@@ -21,11 +21,11 @@
namespace blender::geometry {
/* Indicates when the element was not computed. */
-#define OUT_OF_CONTEXT (int)(-1)
+#define OUT_OF_CONTEXT int(-1)
/* Indicates if the edge or face will be collapsed. */
-#define ELEM_COLLAPSED (int)(-2)
+#define ELEM_COLLAPSED int(-2)
/* indicates whether an edge or vertex in groups_map will be merged. */
-#define ELEM_MERGED (int)(-2)
+#define ELEM_MERGED int(-2)
/* Used to indicate a range in an array specifying a group. */
struct WeldGroup {
@@ -702,7 +702,7 @@ static bool weld_iter_loop_of_poly_next(WeldLoopOfPolyIter &iter)
else {
const MLoop &ml = iter.mloop[l];
#ifdef USE_WELD_DEBUG
- BLI_assert((uint)iter.v != ml.v);
+ BLI_assert(uint(iter.v) != ml.v);
#endif
iter.v = ml.v;
iter.e = ml.e;
@@ -1232,7 +1232,6 @@ static void customdata_weld(
#ifdef USE_WELD_NORMALS
float no[3] = {0.0f, 0.0f, 0.0f};
#endif
- int crease = 0;
short flag = 0;
/* interpolates a layer at a time */
@@ -1266,13 +1265,11 @@ static void customdata_weld(
no[1] += mv_src_no[1];
no[2] += mv_src_no[2];
#endif
- flag |= mv_src->flag;
}
}
else if (type == CD_MEDGE) {
for (j = 0; j < count; j++) {
MEdge *me_src = &((MEdge *)src_data)[src_indices[j]];
- crease += me_src->crease;
flag |= me_src->flag;
}
}
@@ -1283,10 +1280,10 @@ static void customdata_weld(
else if (CustomData_layer_has_math(dest, dest_i)) {
const int size = CustomData_sizeof(type);
void *dst_data = dest->layers[dest_i].data;
- void *v_dst = POINTER_OFFSET(dst_data, (size_t)dest_index * size);
+ void *v_dst = POINTER_OFFSET(dst_data, size_t(dest_index) * size);
for (j = 0; j < count; j++) {
CustomData_data_add(
- type, v_dst, POINTER_OFFSET(src_data, (size_t)src_indices[j] * size));
+ type, v_dst, POINTER_OFFSET(src_data, size_t(src_indices[j]) * size));
}
}
else {
@@ -1314,19 +1311,13 @@ static void customdata_weld(
#ifdef USE_WELD_NORMALS
mul_v3_fl(no, fac);
short *mv_no = mv->no;
- mv_no[0] = (short)no[0];
- mv_no[1] = (short)no[1];
- mv_no[2] = (short)no[2];
+ mv_no[0] = short(no[0]);
+ mv_no[1] = short(no[1]);
+ mv_no[2] = short(no[2]);
#endif
-
- mv->flag = (char)flag;
}
else if (type == CD_MEDGE) {
MEdge *me = &((MEdge *)layer_dst->data)[dest_index];
- crease *= fac;
- CLAMP_MAX(crease, 255);
-
- me->crease = (char)crease;
me->flag = flag;
}
else if (CustomData_layer_has_interp(dest, dest_i)) {
@@ -1335,7 +1326,7 @@ static void customdata_weld(
else if (CustomData_layer_has_math(dest, dest_i)) {
const int size = CustomData_sizeof(type);
void *dst_data = layer_dst->data;
- void *v_dst = POINTER_OFFSET(dst_data, (size_t)dest_index * size);
+ void *v_dst = POINTER_OFFSET(dst_data, size_t(dest_index) * size);
CustomData_data_multiply(type, v_dst, fac);
}
}
@@ -1541,7 +1532,7 @@ static Mesh *create_merged_mesh(const Mesh &mesh,
r_i++;
}
- BLI_assert((int)r_i == result_npolys);
+ BLI_assert(int(r_i) == result_npolys);
BLI_assert(loop_cur == result_nloops);
return result;
@@ -1639,7 +1630,7 @@ std::optional<Mesh *> mesh_merge_by_distance_connected(const Mesh &mesh,
const float dist_sq = len_squared_v3(edgedir);
if (dist_sq <= merge_dist_sq) {
float influence = (v2_cluster->merged_verts + 1) /
- (float)(v1_cluster->merged_verts + v2_cluster->merged_verts + 2);
+ float(v1_cluster->merged_verts + v2_cluster->merged_verts + 2);
madd_v3_v3fl(v1_cluster->co, edgedir, influence);
v1_cluster->merged_verts += v2_cluster->merged_verts + 1;
diff --git a/source/blender/geometry/intern/mesh_primitive_cuboid.cc b/source/blender/geometry/intern/mesh_primitive_cuboid.cc
index 39571f2931e..a014c488a3b 100644
--- a/source/blender/geometry/intern/mesh_primitive_cuboid.cc
+++ b/source/blender/geometry/intern/mesh_primitive_cuboid.cc
@@ -328,9 +328,9 @@ static void calculate_uvs(const CuboidConfig &config, Mesh *mesh, const bke::Att
int loop_index = 0;
- const float x_delta = 0.25f / static_cast<float>(config.edges_x);
- const float y_delta = 0.25f / static_cast<float>(config.edges_y);
- const float z_delta = 0.25f / static_cast<float>(config.edges_z);
+ const float x_delta = 0.25f / float(config.edges_x);
+ const float y_delta = 0.25f / float(config.edges_y);
+ const float z_delta = 0.25f / float(config.edges_z);
/* Calculate bottom face UVs. */
for (const int y : IndexRange(config.edges_y)) {
diff --git a/source/blender/geometry/intern/mesh_to_curve_convert.cc b/source/blender/geometry/intern/mesh_to_curve_convert.cc
index 22961504015..c2a9b16c8b6 100644
--- a/source/blender/geometry/intern/mesh_to_curve_convert.cc
+++ b/source/blender/geometry/intern/mesh_to_curve_convert.cc
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_array.hh"
+#include "BLI_array_utils.hh"
#include "BLI_devirtualize_parameters.hh"
#include "BLI_set.hh"
#include "BLI_task.hh"
@@ -18,19 +19,6 @@
namespace blender::geometry {
-template<typename T>
-static void copy_with_map(const VArray<T> &src, Span<int> map, MutableSpan<T> dst)
-{
- devirtualize_varray(src, [&](const auto &src) {
- threading::parallel_for(map.index_range(), 1024, [&](const IndexRange range) {
- for (const int i : range) {
- const int vert_index = map[i];
- dst[i] = src[vert_index];
- }
- });
- });
-}
-
bke::CurvesGeometry create_curve_from_vert_indices(const Mesh &mesh,
const Span<int> vert_indices,
const Span<int> curve_offsets,
@@ -71,7 +59,7 @@ bke::CurvesGeometry create_curve_from_vert_indices(const Mesh &mesh,
using T = decltype(dummy);
bke::SpanAttributeWriter<T> attribute =
curves_attributes.lookup_or_add_for_write_only_span<T>(attribute_id, ATTR_DOMAIN_POINT);
- copy_with_map<T>(mesh_attribute.typed<T>(), vert_indices, attribute.span);
+ array_utils::gather<T>(mesh_attribute.typed<T>(), vert_indices, attribute.span);
attribute.finish();
});
}
diff --git a/source/blender/geometry/intern/mesh_to_volume.cc b/source/blender/geometry/intern/mesh_to_volume.cc
index b1c7be38609..b6025f8f1a9 100644
--- a/source/blender/geometry/intern/mesh_to_volume.cc
+++ b/source/blender/geometry/intern/mesh_to_volume.cc
@@ -25,30 +25,26 @@ class OpenVDBMeshAdapter {
OpenVDBMeshAdapter(const Mesh &mesh, float4x4 transform);
size_t polygonCount() const;
size_t pointCount() const;
- size_t vertexCount(size_t UNUSED(polygon_index)) const;
+ size_t vertexCount(size_t /*polygon_index*/) const;
void getIndexSpacePoint(size_t polygon_index, size_t vertex_index, openvdb::Vec3d &pos) const;
};
OpenVDBMeshAdapter::OpenVDBMeshAdapter(const Mesh &mesh, float4x4 transform)
- : verts_(mesh.verts()), loops_(mesh.loops()), transform_(transform)
+ : verts_(mesh.verts()), loops_(mesh.loops()), looptris_(mesh.looptris()), transform_(transform)
{
- /* This only updates a cache and can be considered to be logically const. */
- const MLoopTri *looptris = BKE_mesh_runtime_looptri_ensure(&mesh);
- const int looptris_len = BKE_mesh_runtime_looptri_len(&mesh);
- looptris_ = Span(looptris, looptris_len);
}
size_t OpenVDBMeshAdapter::polygonCount() const
{
- return static_cast<size_t>(looptris_.size());
+ return size_t(looptris_.size());
}
size_t OpenVDBMeshAdapter::pointCount() const
{
- return static_cast<size_t>(verts_.size());
+ return size_t(verts_.size());
}
-size_t OpenVDBMeshAdapter::vertexCount(size_t UNUSED(polygon_index)) const
+size_t OpenVDBMeshAdapter::vertexCount(size_t /*polygon_index*/) const
{
/* All polygons are triangles. */
return 3;
diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc
index 29a9f51c0a7..2d9c23df348 100644
--- a/source/blender/geometry/intern/realize_instances.cc
+++ b/source/blender/geometry/intern/realize_instances.cc
@@ -17,6 +17,7 @@
#include "BKE_curves.hh"
#include "BKE_deform.h"
#include "BKE_geometry_set_instances.hh"
+#include "BKE_instances.hh"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_pointcloud.h"
@@ -30,6 +31,8 @@ using blender::bke::AttributeMetaData;
using blender::bke::custom_data_type_to_cpp_type;
using blender::bke::CustomDataAttributes;
using blender::bke::GSpanAttributeWriter;
+using blender::bke::InstanceReference;
+using blender::bke::Instances;
using blender::bke::object_get_evaluated_geometry_set;
using blender::bke::SpanAttributeWriter;
@@ -370,11 +373,11 @@ static void gather_realize_tasks_recursive(GatherTasksInfo &gather_info,
*/
static Vector<std::pair<int, GSpan>> prepare_attribute_fallbacks(
GatherTasksInfo &gather_info,
- const InstancesComponent &instances_component,
+ const Instances &instances,
const OrderedAttributes &ordered_attributes)
{
Vector<std::pair<int, GSpan>> attributes_to_override;
- const CustomDataAttributes &attributes = instances_component.instance_attributes();
+ const CustomDataAttributes &attributes = instances.custom_data_attributes();
attributes.foreach_attribute(
[&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
const int attribute_index = ordered_attributes.ids.index_of_try(attribute_id);
@@ -394,7 +397,7 @@ static Vector<std::pair<int, GSpan>> prepare_attribute_fallbacks(
}
/* Convert the attribute on the instances component to the expected attribute type. */
std::unique_ptr<GArray<>> temporary_array = std::make_unique<GArray<>>(
- to_type, instances_component.instances_num());
+ to_type, instances.instances_num());
conversions.convert_to_initialized_n(span, temporary_array->as_mutable_span());
span = temporary_array->as_span();
gather_info.r_temporary_arrays.append(std::move(temporary_array));
@@ -430,7 +433,7 @@ static void foreach_geometry_in_reference(
int index = 0;
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (&collection, object) {
const GeometrySet object_geometry_set = object_get_evaluated_geometry_set(*object);
- const float4x4 matrix = base_transform * offset_matrix * object->obmat;
+ const float4x4 matrix = base_transform * offset_matrix * object->object_to_world;
const int sub_id = noise::hash(id, index);
fn(object_geometry_set, matrix, sub_id);
index++;
@@ -450,17 +453,17 @@ static void foreach_geometry_in_reference(
}
static void gather_realize_tasks_for_instances(GatherTasksInfo &gather_info,
- const InstancesComponent &instances_component,
+ const Instances &instances,
const float4x4 &base_transform,
const InstanceContext &base_instance_context)
{
- const Span<InstanceReference> references = instances_component.references();
- const Span<int> handles = instances_component.instance_reference_handles();
- const Span<float4x4> transforms = instances_component.instance_transforms();
+ const Span<InstanceReference> references = instances.references();
+ const Span<int> handles = instances.reference_handles();
+ const Span<float4x4> transforms = instances.transforms();
Span<int> stored_instance_ids;
if (gather_info.create_id_attribute_on_any_component) {
- std::optional<GSpan> ids = instances_component.instance_attributes().get_for_read("id");
+ std::optional<GSpan> ids = instances.custom_data_attributes().get_for_read("id");
if (ids.has_value()) {
stored_instance_ids = ids->typed<int>();
}
@@ -469,11 +472,11 @@ static void gather_realize_tasks_for_instances(GatherTasksInfo &gather_info,
/* Prepare attribute fallbacks. */
InstanceContext instance_context = base_instance_context;
Vector<std::pair<int, GSpan>> pointcloud_attributes_to_override = prepare_attribute_fallbacks(
- gather_info, instances_component, gather_info.pointclouds.attributes);
+ gather_info, instances, gather_info.pointclouds.attributes);
Vector<std::pair<int, GSpan>> mesh_attributes_to_override = prepare_attribute_fallbacks(
- gather_info, instances_component, gather_info.meshes.attributes);
+ gather_info, instances, gather_info.meshes.attributes);
Vector<std::pair<int, GSpan>> curve_attributes_to_override = prepare_attribute_fallbacks(
- gather_info, instances_component, gather_info.curves.attributes);
+ gather_info, instances, gather_info.curves.attributes);
for (const int i : transforms.index_range()) {
const int handle = handles[i];
@@ -495,10 +498,10 @@ static void gather_realize_tasks_for_instances(GatherTasksInfo &gather_info,
uint32_t local_instance_id = 0;
if (gather_info.create_id_attribute_on_any_component) {
if (stored_instance_ids.is_empty()) {
- local_instance_id = (uint32_t)i;
+ local_instance_id = uint32_t(i);
}
else {
- local_instance_id = (uint32_t)stored_instance_ids[i];
+ local_instance_id = uint32_t(stored_instance_ids[i]);
}
}
const uint32_t instance_id = noise::hash(base_instance_context.id, local_instance_id);
@@ -584,8 +587,11 @@ static void gather_realize_tasks_recursive(GatherTasksInfo &gather_info,
case GEO_COMPONENT_TYPE_INSTANCES: {
const InstancesComponent &instances_component = *static_cast<const InstancesComponent *>(
component);
- gather_realize_tasks_for_instances(
- gather_info, instances_component, base_transform, base_instance_context);
+ const Instances *instances = instances_component.get_for_read();
+ if (instances != nullptr && instances->instances_num() > 0) {
+ gather_realize_tasks_for_instances(
+ gather_info, *instances, base_transform, base_instance_context);
+ }
break;
}
case GEO_COMPONENT_TYPE_VOLUME: {
@@ -645,8 +651,7 @@ static void gather_pointclouds_to_realize(const GeometrySet &geometry_set,
r_pointclouds.add(pointcloud);
}
}
- if (const InstancesComponent *instances =
- geometry_set.get_component_for_read<InstancesComponent>()) {
+ if (const Instances *instances = geometry_set.get_instances_for_read()) {
instances->foreach_referenced_geometry([&](const GeometrySet &instance_geometry_set) {
gather_pointclouds_to_realize(instance_geometry_set, r_pointclouds);
});
@@ -782,9 +787,7 @@ static void execute_realize_pointcloud_tasks(const RealizeInstancesOptions &opti
dst_attribute.finish();
}
positions.finish();
- if (point_ids) {
- point_ids.finish();
- }
+ point_ids.finish();
}
/** \} */
@@ -811,7 +814,6 @@ static OrderedAttributes gather_generic_mesh_attributes_to_propagate(
attributes_to_propagate.remove("position");
attributes_to_propagate.remove("normal");
attributes_to_propagate.remove("shade_smooth");
- attributes_to_propagate.remove("crease");
r_create_id = attributes_to_propagate.pop_try("id").has_value();
r_create_material_index = attributes_to_propagate.pop_try("material_index").has_value();
OrderedAttributes ordered_attributes;
@@ -830,8 +832,7 @@ static void gather_meshes_to_realize(const GeometrySet &geometry_set,
r_meshes.add(mesh);
}
}
- if (const InstancesComponent *instances =
- geometry_set.get_component_for_read<InstancesComponent>()) {
+ if (const Instances *instances = geometry_set.get_instances_for_read()) {
instances->foreach_referenced_geometry([&](const GeometrySet &instance_geometry_set) {
gather_meshes_to_realize(instance_geometry_set, r_meshes);
});
@@ -858,6 +859,7 @@ static AllMeshesInfo preprocess_meshes(const GeometrySet &geometry_set,
}
}
}
+ info.create_material_index_attribute |= info.materials.size() > 1;
info.realize_info.reinitialize(info.order.size());
for (const int mesh_index : info.realize_info.index_range()) {
MeshRealizeInfo &mesh_info = info.realize_info[mesh_index];
@@ -1107,12 +1109,8 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options,
for (GSpanAttributeWriter &dst_attribute : dst_attribute_writers) {
dst_attribute.finish();
}
- if (vertex_ids) {
- vertex_ids.finish();
- }
- if (material_indices) {
- material_indices.finish();
- }
+ vertex_ids.finish();
+ material_indices.finish();
}
/** \} */
@@ -1155,8 +1153,7 @@ static void gather_curves_to_realize(const GeometrySet &geometry_set,
r_curves.add(curves);
}
}
- if (const InstancesComponent *instances =
- geometry_set.get_component_for_read<InstancesComponent>()) {
+ if (const Instances *instances = geometry_set.get_instances_for_read()) {
instances->foreach_referenced_geometry([&](const GeometrySet &instance_geometry_set) {
gather_curves_to_realize(instance_geometry_set, r_curves);
});
@@ -1406,19 +1403,11 @@ static void execute_realize_curve_tasks(const RealizeInstancesOptions &options,
for (GSpanAttributeWriter &dst_attribute : dst_attribute_writers) {
dst_attribute.finish();
}
- if (point_ids) {
- point_ids.finish();
- }
- if (radius) {
- radius.finish();
- }
- if (resolution) {
- resolution.finish();
- }
- if (all_curves_info.create_handle_postion_attributes) {
- handle_left.finish();
- handle_right.finish();
- }
+ point_ids.finish();
+ radius.finish();
+ resolution.finish();
+ handle_left.finish();
+ handle_right.finish();
}
/** \} */
@@ -1430,9 +1419,8 @@ static void execute_realize_curve_tasks(const RealizeInstancesOptions &options,
static void remove_id_attribute_from_instances(GeometrySet &geometry_set)
{
geometry_set.modify_geometry_sets([&](GeometrySet &sub_geometry) {
- if (sub_geometry.has<InstancesComponent>()) {
- InstancesComponent &component = sub_geometry.get_component_for_write<InstancesComponent>();
- component.instance_attributes().remove("id");
+ if (Instances *instances = sub_geometry.get_instances_for_write()) {
+ instances->custom_data_attributes().remove("id");
}
});
}
diff --git a/source/blender/geometry/intern/resample_curves.cc b/source/blender/geometry/intern/resample_curves.cc
index d5560a95a18..3be850ec097 100644
--- a/source/blender/geometry/intern/resample_curves.cc
+++ b/source/blender/geometry/intern/resample_curves.cc
@@ -116,14 +116,21 @@ struct AttributesForInterpolation : NonCopyable, NonMovable {
Vector<GSpan> src_no_interpolation;
Vector<GMutableSpan> dst_no_interpolation;
+
+ Span<float3> src_evaluated_tangents;
+ Span<float3> src_evaluated_normals;
+ MutableSpan<float3> dst_tangents;
+ MutableSpan<float3> dst_normals;
};
/**
* Gather a set of all generic attribute IDs to copy to the result curves.
*/
-static void gather_point_attributes_to_interpolate(const CurvesGeometry &src_curves,
- CurvesGeometry &dst_curves,
- AttributesForInterpolation &result)
+static void gather_point_attributes_to_interpolate(
+ const CurvesGeometry &src_curves,
+ CurvesGeometry &dst_curves,
+ AttributesForInterpolation &result,
+ const ResampleCurvesOutputAttributeIDs &output_ids)
{
VectorSet<bke::AttributeIDRef> ids;
VectorSet<bke::AttributeIDRef> ids_no_interpolation;
@@ -132,6 +139,9 @@ static void gather_point_attributes_to_interpolate(const CurvesGeometry &src_cur
if (meta_data.domain != ATTR_DOMAIN_POINT) {
return true;
}
+ if (meta_data.data_type == CD_PROP_STRING) {
+ return true;
+ }
if (!interpolate_attribute_to_curves(id, dst_curves.curve_type_counts())) {
return true;
}
@@ -159,11 +169,75 @@ static void gather_point_attributes_to_interpolate(const CurvesGeometry &src_cur
result.src_no_interpolation,
result.dst_no_interpolation,
result.dst_attributes);
+
+ bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write();
+ if (output_ids.tangent_id) {
+ result.src_evaluated_tangents = src_curves.evaluated_tangents();
+ bke::GSpanAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write_only_span(
+ output_ids.tangent_id, ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
+ result.dst_tangents = dst_attribute.span.typed<float3>();
+ result.dst_attributes.append(std::move(dst_attribute));
+ }
+ if (output_ids.normal_id) {
+ result.src_evaluated_normals = src_curves.evaluated_normals();
+ bke::GSpanAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write_only_span(
+ output_ids.normal_id, ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
+ result.dst_normals = dst_attribute.span.typed<float3>();
+ result.dst_attributes.append(std::move(dst_attribute));
+ }
+}
+
+static void copy_or_defaults_for_unselected_curves(const CurvesGeometry &src_curves,
+ const Span<IndexRange> unselected_ranges,
+ const AttributesForInterpolation &attributes,
+ CurvesGeometry &dst_curves)
+{
+ bke::curves::copy_point_data(src_curves,
+ dst_curves,
+ unselected_ranges,
+ src_curves.positions(),
+ dst_curves.positions_for_write());
+
+ for (const int i : attributes.src.index_range()) {
+ bke::curves::copy_point_data(
+ src_curves, dst_curves, unselected_ranges, attributes.src[i], attributes.dst[i]);
+ }
+ for (const int i : attributes.src_no_interpolation.index_range()) {
+ bke::curves::copy_point_data(src_curves,
+ dst_curves,
+ unselected_ranges,
+ attributes.src_no_interpolation[i],
+ attributes.dst_no_interpolation[i]);
+ }
+
+ if (!attributes.dst_tangents.is_empty()) {
+ bke::curves::fill_points(dst_curves, unselected_ranges, float3(0), attributes.dst_tangents);
+ }
+ if (!attributes.dst_normals.is_empty()) {
+ bke::curves::fill_points(dst_curves, unselected_ranges, float3(0), attributes.dst_normals);
+ }
+}
+
+static void normalize_span(MutableSpan<float3> data)
+{
+ for (const int i : data.index_range()) {
+ data[i] = math::normalize(data[i]);
+ }
+}
+
+static void normalize_curve_point_data(const CurvesGeometry &curves,
+ const IndexMask curve_selection,
+ MutableSpan<float3> data)
+{
+ for (const int i_curve : curve_selection) {
+ normalize_span(data.slice(curves.points_for_curve(i_curve)));
+ }
}
static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves,
const fn::Field<bool> &selection_field,
- const fn::Field<int> &count_field)
+ const fn::Field<int> &count_field,
+ const ResampleCurvesOutputAttributeIDs &output_ids)
{
/* Create the new curves without any points and evaluate the final count directly
* into the offsets array, in order to be accumulated into offsets later. */
@@ -200,7 +274,7 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves,
MutableSpan<float3> dst_positions = dst_curves.positions_for_write();
AttributesForInterpolation attributes;
- gather_point_attributes_to_interpolate(src_curves, dst_curves, attributes);
+ gather_point_attributes_to_interpolate(src_curves, dst_curves, attributes, output_ids);
src_curves.ensure_evaluated_lengths();
@@ -272,14 +346,27 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves,
});
}
+ auto interpolate_evaluated_data = [&](const Span<float3> src, MutableSpan<float3> dst) {
+ for (const int i_curve : sliced_selection) {
+ const IndexRange src_points = src_curves.evaluated_points_for_curve(i_curve);
+ const IndexRange dst_points = dst_curves.points_for_curve(i_curve);
+ length_parameterize::interpolate(src.slice(src_points),
+ sample_indices.as_span().slice(dst_points),
+ sample_factors.as_span().slice(dst_points),
+ dst.slice(dst_points));
+ }
+ };
+
/* Interpolate the evaluated positions to the resampled curves. */
- for (const int i_curve : sliced_selection) {
- const IndexRange src_points = src_curves.evaluated_points_for_curve(i_curve);
- const IndexRange dst_points = dst_curves.points_for_curve(i_curve);
- length_parameterize::interpolate(evaluated_positions.slice(src_points),
- sample_indices.as_span().slice(dst_points),
- sample_factors.as_span().slice(dst_points),
- dst_positions.slice(dst_points));
+ interpolate_evaluated_data(evaluated_positions, dst_positions);
+
+ if (!attributes.dst_tangents.is_empty()) {
+ interpolate_evaluated_data(attributes.src_evaluated_tangents, attributes.dst_tangents);
+ normalize_curve_point_data(dst_curves, sliced_selection, attributes.dst_tangents);
+ }
+ if (!attributes.dst_normals.is_empty()) {
+ interpolate_evaluated_data(attributes.src_evaluated_normals, attributes.dst_normals);
+ normalize_curve_point_data(dst_curves, sliced_selection, attributes.dst_normals);
}
/* Fill the default value for non-interpolating attributes that still must be copied. */
@@ -291,23 +378,7 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves,
}
});
- /* Any attribute data from unselected curve points can be directly copied. */
- for (const int i : attributes.src.index_range()) {
- bke::curves::copy_point_data(
- src_curves, dst_curves, unselected_ranges, attributes.src[i], attributes.dst[i]);
- }
- for (const int i : attributes.src_no_interpolation.index_range()) {
- bke::curves::copy_point_data(src_curves,
- dst_curves,
- unselected_ranges,
- attributes.src_no_interpolation[i],
- attributes.dst_no_interpolation[i]);
- }
-
- /* Copy positions for unselected curves. */
- Span<float3> src_positions = src_curves.positions();
- bke::curves::copy_point_data(
- src_curves, dst_curves, unselected_ranges, src_positions, dst_positions);
+ copy_or_defaults_for_unselected_curves(src_curves, unselected_ranges, attributes, dst_curves);
for (bke::GSpanAttributeWriter &attribute : attributes.dst_attributes) {
attribute.finish();
@@ -318,21 +389,25 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves,
CurvesGeometry resample_to_count(const CurvesGeometry &src_curves,
const fn::Field<bool> &selection_field,
- const fn::Field<int> &count_field)
+ const fn::Field<int> &count_field,
+ const ResampleCurvesOutputAttributeIDs &output_ids)
{
- return resample_to_uniform(src_curves, selection_field, get_count_input_max_one(count_field));
+ return resample_to_uniform(
+ src_curves, selection_field, get_count_input_max_one(count_field), output_ids);
}
CurvesGeometry resample_to_length(const CurvesGeometry &src_curves,
const fn::Field<bool> &selection_field,
- const fn::Field<float> &segment_length_field)
+ const fn::Field<float> &segment_length_field,
+ const ResampleCurvesOutputAttributeIDs &output_ids)
{
return resample_to_uniform(
- src_curves, selection_field, get_count_input_from_length(segment_length_field));
+ src_curves, selection_field, get_count_input_from_length(segment_length_field), output_ids);
}
CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves,
- const fn::Field<bool> &selection_field)
+ const fn::Field<bool> &selection_field,
+ const ResampleCurvesOutputAttributeIDs &output_ids)
{
src_curves.ensure_evaluated_offsets();
@@ -368,11 +443,11 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves,
dst_curves.resize(dst_offsets.last(), dst_curves.curves_num());
/* Create the correct number of uniform-length samples for every selected curve. */
- Span<float3> evaluated_positions = src_curves.evaluated_positions();
+ const Span<float3> evaluated_positions = src_curves.evaluated_positions();
MutableSpan<float3> dst_positions = dst_curves.positions_for_write();
AttributesForInterpolation attributes;
- gather_point_attributes_to_interpolate(src_curves, dst_curves, attributes);
+ gather_point_attributes_to_interpolate(src_curves, dst_curves, attributes, output_ids);
threading::parallel_for(selection.index_range(), 512, [&](IndexRange selection_range) {
const IndexMask sliced_selection = selection.slice(selection_range);
@@ -393,11 +468,24 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves,
});
}
+ auto copy_evaluated_data = [&](const Span<float3> src, MutableSpan<float3> dst) {
+ for (const int i_curve : sliced_selection) {
+ const IndexRange src_points = src_curves.evaluated_points_for_curve(i_curve);
+ const IndexRange dst_points = dst_curves.points_for_curve(i_curve);
+ dst.slice(dst_points).copy_from(src.slice(src_points));
+ }
+ };
+
/* Copy the evaluated positions to the selected curves. */
- for (const int i_curve : sliced_selection) {
- const IndexRange src_points = src_curves.evaluated_points_for_curve(i_curve);
- const IndexRange dst_points = dst_curves.points_for_curve(i_curve);
- dst_positions.slice(dst_points).copy_from(evaluated_positions.slice(src_points));
+ copy_evaluated_data(evaluated_positions, dst_positions);
+
+ if (!attributes.dst_tangents.is_empty()) {
+ copy_evaluated_data(attributes.src_evaluated_tangents, attributes.dst_tangents);
+ normalize_curve_point_data(dst_curves, sliced_selection, attributes.dst_tangents);
+ }
+ if (!attributes.dst_normals.is_empty()) {
+ copy_evaluated_data(attributes.src_evaluated_normals, attributes.dst_normals);
+ normalize_curve_point_data(dst_curves, sliced_selection, attributes.dst_normals);
}
/* Fill the default value for non-interpolating attributes that still must be copied. */
@@ -409,23 +497,7 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves,
}
});
- /* Any attribute data from unselected curve points can be directly copied. */
- for (const int i : attributes.src.index_range()) {
- bke::curves::copy_point_data(
- src_curves, dst_curves, unselected_ranges, attributes.src[i], attributes.dst[i]);
- }
- for (const int i : attributes.src_no_interpolation.index_range()) {
- bke::curves::copy_point_data(src_curves,
- dst_curves,
- unselected_ranges,
- attributes.src_no_interpolation[i],
- attributes.dst_no_interpolation[i]);
- }
-
- /* Copy positions for unselected curves. */
- Span<float3> src_positions = src_curves.positions();
- bke::curves::copy_point_data(
- src_curves, dst_curves, unselected_ranges, src_positions, dst_positions);
+ copy_or_defaults_for_unselected_curves(src_curves, unselected_ranges, attributes, dst_curves);
for (bke::GSpanAttributeWriter &attribute : attributes.dst_attributes) {
attribute.finish();
diff --git a/source/blender/geometry/intern/set_curve_type.cc b/source/blender/geometry/intern/set_curve_type.cc
index 92609a45bdc..e069732ca9b 100644
--- a/source/blender/geometry/intern/set_curve_type.cc
+++ b/source/blender/geometry/intern/set_curve_type.cc
@@ -186,12 +186,12 @@ static Vector<float3> create_nurbs_to_bezier_handles(const Span<float3> nurbs_po
const int segments_num = nurbs_positions_num - 1;
const bool ignore_interior_segment = segments_num == 3 && is_periodic == false;
if (ignore_interior_segment == false) {
- const float mid_offset = (float)(segments_num - 1) / 2.0f;
+ const float mid_offset = float(segments_num - 1) / 2.0f;
for (const int i : IndexRange(1, segments_num - 2)) {
/* Divisor can have values: 1, 2 or 3. */
const int divisor = is_periodic ?
3 :
- std::min(3, (int)(-std::abs(i - mid_offset) + mid_offset + 1.0f));
+ std::min(3, int(-std::abs(i - mid_offset) + mid_offset + 1.0f));
const float3 &p1 = nurbs_positions[i];
const float3 &p2 = nurbs_positions[i + 1];
const float3 displacement = (p2 - p1) / divisor;
@@ -257,7 +257,7 @@ static int to_bezier_size(const CurveType src_type,
switch (src_type) {
case CURVE_TYPE_NURBS: {
if (is_nurbs_to_bezier_one_to_one(knots_mode)) {
- return cyclic ? src_size : src_size - 2;
+ return cyclic ? src_size : std::max(1, src_size - 2);
}
return (src_size + 1) / 3;
}
@@ -392,6 +392,13 @@ static bke::CurvesGeometry convert_curves_to_bezier(const bke::CurvesGeometry &s
const IndexRange src_points = src_curves.points_for_curve(i);
const IndexRange dst_points = dst_curves.points_for_curve(i);
const Span<float3> src_curve_positions = src_positions.slice(src_points);
+ if (dst_points.size() == 1) {
+ const float3 &position = src_positions[src_points.first()];
+ dst_positions[dst_points.first()] = position;
+ dst_handles_l[dst_points.first()] = position;
+ dst_handles_r[dst_points.first()] = position;
+ continue;
+ }
KnotsMode knots_mode = KnotsMode(src_knot_modes[i]);
Span<float3> nurbs_positions = src_curve_positions;
diff --git a/source/blender/geometry/intern/trim_curves.cc b/source/blender/geometry/intern/trim_curves.cc
new file mode 100644
index 00000000000..82e9ee78592
--- /dev/null
+++ b/source/blender/geometry/intern/trim_curves.cc
@@ -0,0 +1,1031 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "BLI_array_utils.hh"
+#include "BLI_length_parameterize.hh"
+
+#include "BKE_attribute.hh"
+#include "BKE_attribute_math.hh"
+#include "BKE_curves.hh"
+#include "BKE_curves_utils.hh"
+#include "BKE_geometry_set.hh"
+
+#include "GEO_trim_curves.hh"
+
+namespace blender::geometry {
+
+/* -------------------------------------------------------------------- */
+/** \name Lookup Curve Points
+ * \{ */
+
+/**
+ * Find the point on the curve defined by the distance along the curve. Assumes curve resolution is
+ * constant for all curve segments and evaluated curve points are uniformly spaced between the
+ * segment endpoints in relation to the curve parameter.
+ *
+ * \param lengths: Accumulated length for the evaluated curve.
+ * \param sample_length: Distance along the curve to determine the #CurvePoint for.
+ * \param cyclic: If curve is cyclic.
+ * \param resolution: Curve resolution (number of evaluated points per segment).
+ * \param num_curve_points: Total number of control points in the curve.
+ * \return: Point on the piecewise segment matching the given distance.
+ */
+static bke::curves::CurvePoint lookup_point_uniform_spacing(const Span<float> lengths,
+ const float sample_length,
+ const bool cyclic,
+ const int resolution,
+ const int num_curve_points)
+{
+ BLI_assert(!cyclic || lengths.size() / resolution >= 2);
+ const int last_index = num_curve_points - 1;
+ if (sample_length <= 0.0f) {
+ return {{0, 1}, 0.0f};
+ }
+ if (sample_length >= lengths.last()) {
+ return cyclic ? bke::curves::CurvePoint{{last_index, 0}, 1.0} :
+ bke::curves::CurvePoint{{last_index - 1, last_index}, 1.0};
+ }
+ int eval_index;
+ float eval_factor;
+ length_parameterize::sample_at_length(lengths, sample_length, eval_index, eval_factor);
+
+ const int index = eval_index / resolution;
+ const int next_index = (index == last_index) ? 0 : index + 1;
+ const float parameter = (eval_factor + eval_index) / resolution - index;
+
+ return bke::curves::CurvePoint{{index, next_index}, parameter};
+}
+
+/**
+ * Find the point on the 'evaluated' polygonal curve.
+ */
+static bke::curves::CurvePoint lookup_point_polygonal(const Span<float> lengths,
+ const float sample_length,
+ const bool cyclic,
+ const int evaluated_size)
+{
+ const int last_index = evaluated_size - 1;
+ if (sample_length <= 0.0f) {
+ return {{0, 1}, 0.0f};
+ }
+ if (sample_length >= lengths.last()) {
+ return cyclic ? bke::curves::CurvePoint{{last_index, 0}, 1.0} :
+ bke::curves::CurvePoint{{last_index - 1, last_index}, 1.0};
+ }
+
+ int eval_index;
+ float eval_factor;
+ length_parameterize::sample_at_length(lengths, sample_length, eval_index, eval_factor);
+
+ const int next_eval_index = (eval_index == last_index) ? 0 : eval_index + 1;
+ return bke::curves::CurvePoint{{eval_index, next_eval_index}, eval_factor};
+}
+
+/**
+ * Find the point on a Bezier curve using the 'bezier_offsets' cache.
+ */
+static bke::curves::CurvePoint lookup_point_bezier(const Span<int> bezier_offsets,
+ const Span<float> lengths,
+ const float sample_length,
+ const bool cyclic,
+ const int num_curve_points)
+{
+ const int last_index = num_curve_points - 1;
+ if (sample_length <= 0.0f) {
+ return {{0, 1}, 0.0f};
+ }
+ if (sample_length >= lengths.last()) {
+ return cyclic ? bke::curves::CurvePoint{{last_index, 0}, 1.0} :
+ bke::curves::CurvePoint{{last_index - 1, last_index}, 1.0};
+ }
+ int eval_index;
+ float eval_factor;
+ length_parameterize::sample_at_length(lengths, sample_length, eval_index, eval_factor);
+
+ /* Find the segment index from the offset mapping. */
+ const int *offset = std::upper_bound(bezier_offsets.begin(), bezier_offsets.end(), eval_index);
+ const int left = offset - bezier_offsets.begin();
+ const int right = left == last_index ? 0 : left + 1;
+
+ const int prev_offset = left == 0 ? 0 : bezier_offsets[int64_t(left) - 1];
+ const float offset_in_segment = eval_factor + (eval_index - prev_offset);
+ const int segment_resolution = bezier_offsets[left] - prev_offset;
+ const float parameter = std::clamp(offset_in_segment / segment_resolution, 0.0f, 1.0f);
+
+ return {{left, right}, parameter};
+}
+
+static bke::curves::CurvePoint lookup_point_bezier(const bke::CurvesGeometry &src_curves,
+ const int64_t curve_index,
+ const Span<float> accumulated_lengths,
+ const float sample_length,
+ const bool cyclic,
+ const int resolution,
+ const int num_curve_points)
+{
+ if (bke::curves::bezier::has_vector_handles(
+ num_curve_points,
+ src_curves.evaluated_points_for_curve(curve_index).size(),
+ cyclic,
+ resolution)) {
+ const Span<int> bezier_offsets = src_curves.bezier_evaluated_offsets_for_curve(curve_index);
+ return lookup_point_bezier(
+ bezier_offsets, accumulated_lengths, sample_length, cyclic, num_curve_points);
+ }
+ else {
+ return lookup_point_uniform_spacing(
+ accumulated_lengths, sample_length, cyclic, resolution, num_curve_points);
+ }
+}
+
+static bke::curves::CurvePoint lookup_curve_point(const bke::CurvesGeometry &src_curves,
+ const CurveType curve_type,
+ const int64_t curve_index,
+ const Span<float> accumulated_lengths,
+ const float sample_length,
+ const bool cyclic,
+ const int resolution,
+ const int num_curve_points)
+{
+ if (num_curve_points == 1) {
+ return {{0, 0}, 0.0f};
+ }
+
+ if (curve_type == CURVE_TYPE_CATMULL_ROM) {
+ return lookup_point_uniform_spacing(
+ accumulated_lengths, sample_length, cyclic, resolution, num_curve_points);
+ }
+ else if (curve_type == CURVE_TYPE_BEZIER) {
+ return lookup_point_bezier(src_curves,
+ curve_index,
+ accumulated_lengths,
+ sample_length,
+ cyclic,
+ resolution,
+ num_curve_points);
+ }
+ else if (curve_type == CURVE_TYPE_POLY) {
+ return lookup_point_polygonal(accumulated_lengths, sample_length, cyclic, num_curve_points);
+ }
+ else {
+ /* Handle evaluated curve. */
+ BLI_assert(resolution > 0);
+ return lookup_point_polygonal(accumulated_lengths,
+ sample_length,
+ cyclic,
+ src_curves.evaluated_points_for_curve(curve_index).size());
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Utility Functions
+ * \{ */
+
+static void fill_bezier_data(bke::CurvesGeometry &dst_curves, const IndexMask selection)
+{
+ if (!dst_curves.has_curve_with_type(CURVE_TYPE_BEZIER)) {
+ return;
+ }
+ MutableSpan<float3> handle_positions_left = dst_curves.handle_positions_left_for_write();
+ MutableSpan<float3> handle_positions_right = dst_curves.handle_positions_right_for_write();
+ MutableSpan<int8_t> handle_types_left = dst_curves.handle_types_left_for_write();
+ MutableSpan<int8_t> handle_types_right = dst_curves.handle_types_right_for_write();
+
+ threading::parallel_for(selection.index_range(), 4096, [&](const IndexRange range) {
+ for (const int64_t curve_i : selection.slice(range)) {
+ const IndexRange points = dst_curves.points_for_curve(curve_i);
+ handle_types_right.slice(points).fill(int8_t(BEZIER_HANDLE_FREE));
+ handle_types_left.slice(points).fill(int8_t(BEZIER_HANDLE_FREE));
+ handle_positions_left.slice(points).fill({0.0f, 0.0f, 0.0f});
+ handle_positions_right.slice(points).fill({0.0f, 0.0f, 0.0f});
+ }
+ });
+}
+static void fill_nurbs_data(bke::CurvesGeometry &dst_curves, const IndexMask selection)
+{
+ if (!dst_curves.has_curve_with_type(CURVE_TYPE_NURBS)) {
+ return;
+ }
+ bke::curves::fill_points(dst_curves, selection, 0.0f, dst_curves.nurbs_weights_for_write());
+}
+
+template<typename T>
+static int64_t copy_point_data_between_endpoints(const Span<T> src_data,
+ MutableSpan<T> dst_data,
+ const bke::curves::IndexRangeCyclic src_range,
+ int64_t dst_index)
+{
+ int64_t increment;
+ if (src_range.cycles()) {
+ increment = src_range.size_before_loop();
+ dst_data.slice(dst_index, increment).copy_from(src_data.slice(src_range.first(), increment));
+ dst_index += increment;
+
+ increment = src_range.size_after_loop();
+ dst_data.slice(dst_index, increment)
+ .copy_from(src_data.slice(src_range.curve_range().first(), increment));
+ dst_index += increment;
+ }
+ else {
+ increment = src_range.one_after_last() - src_range.first();
+ dst_data.slice(dst_index, increment).copy_from(src_data.slice(src_range.first(), increment));
+ dst_index += increment;
+ }
+ return dst_index;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Sampling Utilities
+ * \{ */
+
+template<typename T>
+static T interpolate_catmull_rom(const Span<T> src_data,
+ const bke::curves::CurvePoint insertion_point,
+ const bool src_cyclic)
+{
+ BLI_assert(insertion_point.index >= 0 && insertion_point.next_index < src_data.size());
+ int i0;
+ if (insertion_point.index == 0) {
+ i0 = src_cyclic ? src_data.size() - 1 : insertion_point.index;
+ }
+ else {
+ i0 = insertion_point.index - 1;
+ }
+ int i3 = insertion_point.next_index + 1;
+ if (i3 == src_data.size()) {
+ i3 = src_cyclic ? 0 : insertion_point.next_index;
+ }
+ return bke::curves::catmull_rom::interpolate<T>(src_data[i0],
+ src_data[insertion_point.index],
+ src_data[insertion_point.next_index],
+ src_data[i3],
+ insertion_point.parameter);
+}
+
+static bke::curves::bezier::Insertion knot_insert_bezier(
+ const Span<float3> positions,
+ const Span<float3> handles_left,
+ const Span<float3> handles_right,
+ const bke::curves::CurvePoint insertion_point)
+{
+ BLI_assert(
+ insertion_point.index + 1 == insertion_point.next_index ||
+ (insertion_point.next_index >= 0 && insertion_point.next_index < insertion_point.index));
+ return bke::curves::bezier::insert(positions[insertion_point.index],
+ handles_right[insertion_point.index],
+ handles_left[insertion_point.next_index],
+ positions[insertion_point.next_index],
+ insertion_point.parameter);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Sample Curve Interval (Trim)
+ * \{ */
+
+/**
+ * Sample source curve data in the interval defined by the points [start_point, end_point].
+ * Uses linear interpolation to compute the endpoints.
+ *
+ * \tparam include_start_point If False, the 'start_point' point sample will not be copied
+ * and not accounted for in the destination range.
+ * \param src_data: Source to sample from.
+ * \param dst_data: Destination to write samples to.
+ * \param src_range: Interval within [start_point, end_point] to copy from the source point domain.
+ * \param dst_range: Interval to copy point data to in the destination buffer.
+ * \param start_point: Point on the source curve to start sampling from.
+ * \param end_point: Last point to sample in the source curve.
+ */
+template<typename T, bool include_start_point = true>
+static void sample_interval_linear(const Span<T> src_data,
+ MutableSpan<T> dst_data,
+ bke::curves::IndexRangeCyclic src_range,
+ const IndexRange dst_range,
+ const bke::curves::CurvePoint start_point,
+ const bke::curves::CurvePoint end_point)
+{
+ int64_t dst_index = dst_range.first();
+
+ if (start_point.is_controlpoint()) {
+ /* 'start_point' is included in the copy iteration. */
+ if constexpr (!include_start_point) {
+ /* Skip first. */
+ src_range = src_range.drop_front();
+ }
+ }
+ else if constexpr (!include_start_point) {
+ /* Do nothing (excluded). */
+ }
+ else {
+ /* General case, sample 'start_point' */
+ dst_data[dst_index] = attribute_math::mix2(
+ start_point.parameter, src_data[start_point.index], src_data[start_point.next_index]);
+ ++dst_index;
+ }
+
+ dst_index = copy_point_data_between_endpoints(src_data, dst_data, src_range, dst_index);
+ if (dst_range.size() == 1) {
+ BLI_assert(dst_index == dst_range.one_after_last());
+ return;
+ }
+
+ /* Handle last case */
+ if (end_point.is_controlpoint()) {
+ /* 'end_point' is included in the copy iteration. */
+ }
+ else {
+ dst_data[dst_index] = attribute_math::mix2(
+ end_point.parameter, src_data[end_point.index], src_data[end_point.next_index]);
+#ifdef DEBUG
+ ++dst_index;
+#endif
+ }
+ BLI_assert(dst_index == dst_range.one_after_last());
+}
+
+template<typename T>
+static void sample_interval_catmull_rom(const Span<T> src_data,
+ MutableSpan<T> dst_data,
+ bke::curves::IndexRangeCyclic src_range,
+ const IndexRange dst_range,
+ const bke::curves::CurvePoint start_point,
+ const bke::curves::CurvePoint end_point,
+ const bool src_cyclic)
+{
+ int64_t dst_index = dst_range.first();
+
+ if (start_point.is_controlpoint()) {
+ }
+ else {
+ /* General case, sample 'start_point' */
+ dst_data[dst_index] = interpolate_catmull_rom(src_data, start_point, src_cyclic);
+ ++dst_index;
+ }
+
+ dst_index = copy_point_data_between_endpoints(src_data, dst_data, src_range, dst_index);
+ if (dst_range.size() == 1) {
+ BLI_assert(dst_index == dst_range.one_after_last());
+ return;
+ }
+
+ /* Handle last case */
+ if (end_point.is_controlpoint()) {
+ /* 'end_point' is included in the copy iteration. */
+ }
+ else {
+ dst_data[dst_index] = interpolate_catmull_rom(src_data, end_point, src_cyclic);
+#ifdef DEBUG
+ ++dst_index;
+#endif
+ }
+ BLI_assert(dst_index == dst_range.one_after_last());
+}
+
+template<bool include_start_point = true>
+static void sample_interval_bezier(const Span<float3> src_positions,
+ const Span<float3> src_handles_l,
+ const Span<float3> src_handles_r,
+ const Span<int8_t> src_types_l,
+ const Span<int8_t> src_types_r,
+ MutableSpan<float3> dst_positions,
+ MutableSpan<float3> dst_handles_l,
+ MutableSpan<float3> dst_handles_r,
+ MutableSpan<int8_t> dst_types_l,
+ MutableSpan<int8_t> dst_types_r,
+ bke::curves::IndexRangeCyclic src_range,
+ const IndexRange dst_range,
+ const bke::curves::CurvePoint start_point,
+ const bke::curves::CurvePoint end_point)
+{
+ bke::curves::bezier::Insertion start_point_insert;
+ int64_t dst_index = dst_range.first();
+
+ bool start_point_trimmed = false;
+ if (start_point.is_controlpoint()) {
+ /* The 'start_point' control point is included in the copy iteration. */
+ if constexpr (!include_start_point) {
+ src_range = src_range.drop_front();
+ }
+ }
+ else if constexpr (!include_start_point) {
+ /* Do nothing, 'start_point' is excluded. */
+ }
+ else {
+ /* General case, sample 'start_point'. */
+ start_point_insert = knot_insert_bezier(
+ src_positions, src_handles_l, src_handles_r, start_point);
+ dst_positions[dst_range.first()] = start_point_insert.position;
+ dst_handles_l[dst_range.first()] = start_point_insert.left_handle;
+ dst_handles_r[dst_range.first()] = start_point_insert.right_handle;
+ dst_types_l[dst_range.first()] = src_types_l[start_point.index];
+ dst_types_r[dst_range.first()] = src_types_r[start_point.index];
+
+ start_point_trimmed = true;
+ ++dst_index;
+ }
+
+ /* Copy point data between the 'start_point' and 'end_point'. */
+ int64_t increment = src_range.cycles() ? src_range.size_before_loop() :
+ src_range.one_after_last() - src_range.first();
+
+ const IndexRange dst_range_to_end(dst_index, increment);
+ const IndexRange src_range_to_end(src_range.first(), increment);
+ dst_positions.slice(dst_range_to_end).copy_from(src_positions.slice(src_range_to_end));
+ dst_handles_l.slice(dst_range_to_end).copy_from(src_handles_l.slice(src_range_to_end));
+ dst_handles_r.slice(dst_range_to_end).copy_from(src_handles_r.slice(src_range_to_end));
+ dst_types_l.slice(dst_range_to_end).copy_from(src_types_l.slice(src_range_to_end));
+ dst_types_r.slice(dst_range_to_end).copy_from(src_types_r.slice(src_range_to_end));
+ dst_index += increment;
+
+ if (dst_range.size() == 1) {
+ BLI_assert(dst_index == dst_range.one_after_last());
+ return;
+ }
+
+ increment = src_range.size_after_loop();
+ if (src_range.cycles() && increment > 0) {
+ const IndexRange dst_range_looped(dst_index, increment);
+ const IndexRange src_range_looped(src_range.curve_range().first(), increment);
+ dst_positions.slice(dst_range_looped).copy_from(src_positions.slice(src_range_looped));
+ dst_handles_l.slice(dst_range_looped).copy_from(src_handles_l.slice(src_range_looped));
+ dst_handles_r.slice(dst_range_looped).copy_from(src_handles_r.slice(src_range_looped));
+ dst_types_l.slice(dst_range_looped).copy_from(src_types_l.slice(src_range_looped));
+ dst_types_r.slice(dst_range_looped).copy_from(src_types_r.slice(src_range_looped));
+ dst_index += increment;
+ }
+
+ if (start_point_trimmed) {
+ dst_handles_l[dst_range.first() + 1] = start_point_insert.handle_next;
+ /* No need to set handle type (remains the same)! */
+ }
+
+ /* Handle 'end_point' */
+ bke::curves::bezier::Insertion end_point_insert;
+ if (end_point.is_controlpoint()) {
+ /* Do nothing, the 'end_point' control point is included in the copy iteration. */
+ }
+ else {
+ /* Trimmed in both ends within the same (and only) segment! Ensure both end points is not a
+ * loop. */
+ if (start_point_trimmed && start_point.index == end_point.index &&
+ start_point.parameter <= end_point.parameter) {
+
+ /* Copy following segment control point. */
+ dst_positions[dst_index] = src_positions[end_point.next_index];
+ dst_handles_r[dst_index] = src_handles_r[end_point.next_index];
+
+ /* Compute interpolation in the result curve. */
+ const float parameter = (end_point.parameter - start_point.parameter) /
+ (1.0f - start_point.parameter);
+ end_point_insert = knot_insert_bezier(
+ dst_positions,
+ dst_handles_l,
+ dst_handles_r,
+ {{int(dst_range.first()), int(dst_range.first() + 1)}, parameter});
+ }
+ else {
+ /* General case, compute the insertion point. */
+ end_point_insert = knot_insert_bezier(
+ src_positions, src_handles_l, src_handles_r, end_point);
+ }
+
+ dst_handles_r[dst_index - 1] = end_point_insert.handle_prev;
+ dst_types_r[dst_index - 1] = src_types_l[end_point.index];
+
+ dst_handles_l[dst_index] = end_point_insert.left_handle;
+ dst_handles_r[dst_index] = end_point_insert.right_handle;
+ dst_positions[dst_index] = end_point_insert.position;
+ dst_types_l[dst_index] = src_types_l[end_point.next_index];
+ dst_types_r[dst_index] = src_types_r[end_point.next_index];
+#ifdef DEBUG
+ ++dst_index;
+#endif // DEBUG
+ }
+ BLI_assert(dst_index == dst_range.one_after_last());
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Trim Curves
+ * \{ */
+
+static void trim_attribute_linear(const bke::CurvesGeometry &src_curves,
+ bke::CurvesGeometry &dst_curves,
+ const IndexMask selection,
+ const Span<bke::curves::CurvePoint> start_points,
+ const Span<bke::curves::CurvePoint> end_points,
+ const Span<bke::curves::IndexRangeCyclic> src_ranges,
+ MutableSpan<bke::AttributeTransferData> transfer_attributes)
+{
+ for (bke::AttributeTransferData &attribute : transfer_attributes) {
+ attribute_math::convert_to_static_type(attribute.meta_data.data_type, [&](auto dummy) {
+ using T = decltype(dummy);
+
+ threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) {
+ for (const int64_t curve_i : selection.slice(range)) {
+ const IndexRange src_points = src_curves.points_for_curve(curve_i);
+
+ sample_interval_linear<T>(attribute.src.template typed<T>().slice(src_points),
+ attribute.dst.span.typed<T>(),
+ src_ranges[curve_i],
+ dst_curves.points_for_curve(curve_i),
+ start_points[curve_i],
+ end_points[curve_i]);
+ }
+ });
+ });
+ }
+}
+
+static void trim_polygonal_curves(const bke::CurvesGeometry &src_curves,
+ bke::CurvesGeometry &dst_curves,
+ const IndexMask selection,
+ const Span<bke::curves::CurvePoint> start_points,
+ const Span<bke::curves::CurvePoint> end_points,
+ const Span<bke::curves::IndexRangeCyclic> src_ranges,
+ MutableSpan<bke::AttributeTransferData> transfer_attributes)
+{
+ const Span<float3> src_positions = src_curves.positions();
+ MutableSpan<float3> dst_positions = dst_curves.positions_for_write();
+
+ threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) {
+ for (const int64_t curve_i : selection.slice(range)) {
+ const IndexRange src_points = src_curves.points_for_curve(curve_i);
+ const IndexRange dst_points = dst_curves.points_for_curve(curve_i);
+
+ sample_interval_linear<float3>(src_positions.slice(src_points),
+ dst_positions,
+ src_ranges[curve_i],
+ dst_points,
+ start_points[curve_i],
+ end_points[curve_i]);
+ }
+ });
+ fill_bezier_data(dst_curves, selection);
+ fill_nurbs_data(dst_curves, selection);
+ trim_attribute_linear(src_curves,
+ dst_curves,
+ selection,
+ start_points,
+ end_points,
+ src_ranges,
+ transfer_attributes);
+}
+
+static void trim_catmull_rom_curves(const bke::CurvesGeometry &src_curves,
+ bke::CurvesGeometry &dst_curves,
+ const IndexMask selection,
+ const Span<bke::curves::CurvePoint> start_points,
+ const Span<bke::curves::CurvePoint> end_points,
+ const Span<bke::curves::IndexRangeCyclic> src_ranges,
+ MutableSpan<bke::AttributeTransferData> transfer_attributes)
+{
+ const Span<float3> src_positions = src_curves.positions();
+ const VArray<bool> src_cyclic = src_curves.cyclic();
+ MutableSpan<float3> dst_positions = dst_curves.positions_for_write();
+
+ threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) {
+ for (const int64_t curve_i : selection.slice(range)) {
+ const IndexRange src_points = src_curves.points_for_curve(curve_i);
+ const IndexRange dst_points = dst_curves.points_for_curve(curve_i);
+
+ sample_interval_catmull_rom<float3>(src_positions.slice(src_points),
+ dst_positions,
+ src_ranges[curve_i],
+ dst_points,
+ start_points[curve_i],
+ end_points[curve_i],
+ src_cyclic[curve_i]);
+ }
+ });
+ fill_bezier_data(dst_curves, selection);
+ fill_nurbs_data(dst_curves, selection);
+
+ for (bke::AttributeTransferData &attribute : transfer_attributes) {
+ attribute_math::convert_to_static_type(attribute.meta_data.data_type, [&](auto dummy) {
+ using T = decltype(dummy);
+
+ threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) {
+ for (const int64_t curve_i : selection.slice(range)) {
+ const IndexRange src_points = src_curves.points_for_curve(curve_i);
+ const IndexRange dst_points = dst_curves.points_for_curve(curve_i);
+
+ sample_interval_catmull_rom<T>(attribute.src.template typed<T>().slice(src_points),
+ attribute.dst.span.typed<T>(),
+ src_ranges[curve_i],
+ dst_points,
+ start_points[curve_i],
+ end_points[curve_i],
+ src_cyclic[curve_i]);
+ }
+ });
+ });
+ }
+}
+
+static void trim_bezier_curves(const bke::CurvesGeometry &src_curves,
+ bke::CurvesGeometry &dst_curves,
+ const IndexMask selection,
+ const Span<bke::curves::CurvePoint> start_points,
+ const Span<bke::curves::CurvePoint> end_points,
+ const Span<bke::curves::IndexRangeCyclic> src_ranges,
+ MutableSpan<bke::AttributeTransferData> transfer_attributes)
+{
+ const Span<float3> src_positions = src_curves.positions();
+ const VArraySpan<int8_t> src_types_l{src_curves.handle_types_left()};
+ const VArraySpan<int8_t> src_types_r{src_curves.handle_types_right()};
+ const Span<float3> src_handles_l = src_curves.handle_positions_left();
+ const Span<float3> src_handles_r = src_curves.handle_positions_right();
+
+ MutableSpan<float3> dst_positions = dst_curves.positions_for_write();
+ MutableSpan<int8_t> dst_types_l = dst_curves.handle_types_left_for_write();
+ MutableSpan<int8_t> dst_types_r = dst_curves.handle_types_right_for_write();
+ MutableSpan<float3> dst_handles_l = dst_curves.handle_positions_left_for_write();
+ MutableSpan<float3> dst_handles_r = dst_curves.handle_positions_right_for_write();
+
+ threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) {
+ for (const int64_t curve_i : selection.slice(range)) {
+ const IndexRange src_points = src_curves.points_for_curve(curve_i);
+ const IndexRange dst_points = dst_curves.points_for_curve(curve_i);
+
+ sample_interval_bezier(src_positions.slice(src_points),
+ src_handles_l.slice(src_points),
+ src_handles_r.slice(src_points),
+ src_types_l.slice(src_points),
+ src_types_r.slice(src_points),
+ dst_positions,
+ dst_handles_l,
+ dst_handles_r,
+ dst_types_l,
+ dst_types_r,
+ src_ranges[curve_i],
+ dst_points,
+ start_points[curve_i],
+ end_points[curve_i]);
+ }
+ });
+ fill_nurbs_data(dst_curves, selection);
+ trim_attribute_linear(src_curves,
+ dst_curves,
+ selection,
+ start_points,
+ end_points,
+ src_ranges,
+ transfer_attributes);
+}
+
+static void trim_evaluated_curves(const bke::CurvesGeometry &src_curves,
+ bke::CurvesGeometry &dst_curves,
+ const IndexMask selection,
+ const Span<bke::curves::CurvePoint> start_points,
+ const Span<bke::curves::CurvePoint> end_points,
+ const Span<bke::curves::IndexRangeCyclic> src_ranges,
+ MutableSpan<bke::AttributeTransferData> transfer_attributes)
+{
+ const Span<float3> src_eval_positions = src_curves.evaluated_positions();
+ MutableSpan<float3> dst_positions = dst_curves.positions_for_write();
+
+ threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) {
+ for (const int64_t curve_i : selection.slice(range)) {
+ const IndexRange dst_points = dst_curves.points_for_curve(curve_i);
+ const IndexRange src_evaluated_points = src_curves.evaluated_points_for_curve(curve_i);
+
+ sample_interval_linear<float3>(src_eval_positions.slice(src_evaluated_points),
+ dst_positions,
+ src_ranges[curve_i],
+ dst_points,
+ start_points[curve_i],
+ end_points[curve_i]);
+ }
+ });
+ fill_bezier_data(dst_curves, selection);
+ fill_nurbs_data(dst_curves, selection);
+
+ for (bke::AttributeTransferData &attribute : transfer_attributes) {
+ attribute_math::convert_to_static_type(attribute.meta_data.data_type, [&](auto dummy) {
+ using T = decltype(dummy);
+
+ threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) {
+ for (const int64_t curve_i : selection.slice(range)) {
+ /* Interpolate onto the evaluated point domain and sample the evaluated domain. */
+ const IndexRange src_evaluated_points = src_curves.evaluated_points_for_curve(curve_i);
+ GArray evaluated_data(CPPType::get<T>(), src_evaluated_points.size());
+ GMutableSpan evaluated_span = evaluated_data.as_mutable_span();
+ src_curves.interpolate_to_evaluated(
+ curve_i, attribute.src.slice(src_curves.points_for_curve(curve_i)), evaluated_span);
+ sample_interval_linear<T>(evaluated_span.typed<T>(),
+ attribute.dst.span.typed<T>(),
+ src_ranges[curve_i],
+ dst_curves.points_for_curve(curve_i),
+ start_points[curve_i],
+ end_points[curve_i]);
+ }
+ });
+ });
+ }
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Compute trim parameters
+ * \{ */
+
+static float trim_sample_length(const Span<float> accumulated_lengths,
+ const float sample_length,
+ const GeometryNodeCurveSampleMode mode)
+{
+ float length = mode == GEO_NODE_CURVE_SAMPLE_FACTOR ?
+ sample_length * accumulated_lengths.last() :
+ sample_length;
+ return std::clamp(length, 0.0f, accumulated_lengths.last());
+}
+
+/**
+ * Compute the selection for the given curve type. Tracks indices for splitting the selection if
+ * there are curves reduced to a single point.
+ */
+static void compute_curve_trim_parameters(const bke::CurvesGeometry &curves,
+ const IndexMask selection,
+ const VArray<float> &starts,
+ const VArray<float> &ends,
+ const GeometryNodeCurveSampleMode mode,
+ MutableSpan<int> dst_curve_size,
+ MutableSpan<int8_t> dst_curve_types,
+ MutableSpan<bke::curves::CurvePoint> start_points,
+ MutableSpan<bke::curves::CurvePoint> end_points,
+ MutableSpan<bke::curves::IndexRangeCyclic> src_ranges)
+{
+ const VArray<bool> src_cyclic = curves.cyclic();
+ const VArray<int> resolution = curves.resolution();
+ const VArray<int8_t> curve_types = curves.curve_types();
+
+ /* Compute. */
+ threading::parallel_for(selection.index_range(), 128, [&](const IndexRange selection_range) {
+ for (const int64_t curve_i : selection.slice(selection_range)) {
+ CurveType curve_type = CurveType(curve_types[curve_i]);
+
+ int point_count;
+ if (curve_type == CURVE_TYPE_NURBS) {
+ dst_curve_types[curve_i] = CURVE_TYPE_POLY;
+ point_count = curves.evaluated_points_for_curve(curve_i).size();
+ }
+ else {
+ dst_curve_types[curve_i] = curve_type;
+ point_count = curves.points_num_for_curve(curve_i);
+ }
+ if (point_count == 1) {
+ /* Single point. */
+ dst_curve_size[curve_i] = 1;
+ src_ranges[curve_i] = bke::curves::IndexRangeCyclic(0, 0, 1, 1);
+ start_points[curve_i] = {0, 0, 0.0f};
+ end_points[curve_i] = {0, 0, 0.0f};
+ continue;
+ }
+
+ const bool cyclic = src_cyclic[curve_i];
+ const Span<float> lengths = curves.evaluated_lengths_for_curve(curve_i, cyclic);
+ BLI_assert(lengths.size() > 0);
+
+ const float start_length = trim_sample_length(lengths, starts[curve_i], mode);
+ float end_length;
+
+ bool equal_sample_point;
+ if (cyclic) {
+ end_length = trim_sample_length(lengths, ends[curve_i], mode);
+ const float cyclic_start = start_length == lengths.last() ? 0.0f : start_length;
+ const float cyclic_end = end_length == lengths.last() ? 0.0f : end_length;
+ equal_sample_point = cyclic_start == cyclic_end;
+ }
+ else {
+ end_length = ends[curve_i] <= starts[curve_i] ?
+ start_length :
+ trim_sample_length(lengths, ends[curve_i], mode);
+ equal_sample_point = start_length == end_length;
+ }
+
+ start_points[curve_i] = lookup_curve_point(curves,
+ curve_type,
+ curve_i,
+ lengths,
+ start_length,
+ cyclic,
+ resolution[curve_i],
+ point_count);
+ if (equal_sample_point) {
+ end_points[curve_i] = start_points[curve_i];
+ if (end_length <= start_length) {
+ /* Single point. */
+ dst_curve_size[curve_i] = 1;
+ src_ranges[curve_i] = bke::curves::IndexRangeCyclic::get_range_from_size(
+ start_points[curve_i].index,
+ start_points[curve_i].is_controlpoint(), /* Only iterate if control point. */
+ point_count);
+ }
+ else {
+ /* Split. */
+ src_ranges[curve_i] = bke::curves::IndexRangeCyclic::get_range_between_endpoints(
+ start_points[curve_i], end_points[curve_i], point_count)
+ .push_loop();
+ const int count = 1 + !start_points[curve_i].is_controlpoint() + point_count;
+ BLI_assert(count > 1);
+ dst_curve_size[curve_i] = count;
+ }
+ }
+ else {
+ /* General case. */
+ end_points[curve_i] = lookup_curve_point(curves,
+ curve_type,
+ curve_i,
+ lengths,
+ end_length,
+ cyclic,
+ resolution[curve_i],
+ point_count);
+
+ src_ranges[curve_i] = bke::curves::IndexRangeCyclic::get_range_between_endpoints(
+ start_points[curve_i], end_points[curve_i], point_count);
+ const int count = src_ranges[curve_i].size() + !start_points[curve_i].is_controlpoint() +
+ !end_points[curve_i].is_controlpoint();
+ BLI_assert(count > 1);
+ dst_curve_size[curve_i] = count;
+ }
+ BLI_assert(dst_curve_size[curve_i] > 0);
+ }
+ });
+}
+
+/** \} */
+
+bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves,
+ const IndexMask selection,
+ const VArray<float> &starts,
+ const VArray<float> &ends,
+ const GeometryNodeCurveSampleMode mode)
+{
+ BLI_assert(selection.size() > 0);
+ BLI_assert(selection.last() <= src_curves.curves_num());
+ BLI_assert(starts.size() == src_curves.curves_num());
+ BLI_assert(starts.size() == ends.size());
+ src_curves.ensure_evaluated_lengths();
+
+ Vector<int64_t> inverse_selection_indices;
+ const IndexMask inverse_selection = selection.invert(src_curves.curves_range(),
+ inverse_selection_indices);
+
+ /* Create destination curves. */
+ bke::CurvesGeometry dst_curves(0, src_curves.curves_num());
+ MutableSpan<int> dst_curve_offsets = dst_curves.offsets_for_write();
+ MutableSpan<int8_t> dst_curve_types = dst_curves.curve_types_for_write();
+ Array<bke::curves::CurvePoint, 12> start_points(src_curves.curves_num());
+ Array<bke::curves::CurvePoint, 12> end_points(src_curves.curves_num());
+ Array<bke::curves::IndexRangeCyclic, 12> src_ranges(src_curves.curves_num());
+
+ if (src_curves.has_curve_with_type({CURVE_TYPE_BEZIER, CURVE_TYPE_NURBS})) {
+ src_curves.ensure_evaluated_offsets();
+ if (src_curves.has_curve_with_type(CURVE_TYPE_NURBS)) {
+ src_curves.evaluated_positions();
+ }
+ }
+
+ /* Compute destination curves. */
+ compute_curve_trim_parameters(src_curves,
+ selection,
+ starts,
+ ends,
+ mode,
+ dst_curve_offsets,
+ dst_curve_types,
+ start_points,
+ end_points,
+ src_ranges);
+
+ /* Transfer copied curves parameters. */
+ const VArray<int8_t> src_curve_types = src_curves.curve_types();
+ threading::parallel_for(
+ inverse_selection.index_range(), 4096, [&](const IndexRange selection_range) {
+ for (const int64_t curve_i : inverse_selection.slice(selection_range)) {
+ dst_curve_offsets[curve_i] = src_curves.points_num_for_curve(curve_i);
+ dst_curve_types[curve_i] = src_curve_types[curve_i];
+ }
+ });
+ /* Finalize and update the geometry container. */
+ bke::curves::accumulate_counts_to_offsets(dst_curve_offsets);
+ dst_curves.resize(dst_curves.offsets().last(), dst_curves.curves_num());
+ dst_curves.update_curve_types();
+
+ /* Populate curve domain. */
+ const bke::AttributeAccessor src_attributes = src_curves.attributes();
+ bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write();
+ Set<std::string> transfer_curve_skip = {"cyclic", "curve_type", "nurbs_order", "knots_mode"};
+ if (dst_curves.has_curve_with_type(CURVE_TYPE_NURBS)) {
+ /* If a NURBS curve is copied keep */
+ transfer_curve_skip.remove("nurbs_order");
+ transfer_curve_skip.remove("knots_mode");
+ }
+ bke::copy_attribute_domain(
+ src_attributes, dst_attributes, selection, ATTR_DOMAIN_CURVE, transfer_curve_skip);
+
+ /* Fetch custom point domain attributes for transfer (copy). */
+ Vector<bke::AttributeTransferData> transfer_attributes = bke::retrieve_attributes_for_transfer(
+ src_attributes,
+ dst_attributes,
+ ATTR_DOMAIN_MASK_POINT,
+ {"position",
+ "handle_left",
+ "handle_right",
+ "handle_type_left",
+ "handle_type_right",
+ "nurbs_weight"});
+
+ auto trim_catmull = [&](const IndexMask selection) {
+ trim_catmull_rom_curves(src_curves,
+ dst_curves,
+ selection,
+ start_points,
+ end_points,
+ src_ranges,
+ transfer_attributes);
+ };
+ auto trim_poly = [&](const IndexMask selection) {
+ trim_polygonal_curves(src_curves,
+ dst_curves,
+ selection,
+ start_points,
+ end_points,
+ src_ranges,
+ transfer_attributes);
+ };
+ auto trim_bezier = [&](const IndexMask selection) {
+ trim_bezier_curves(src_curves,
+ dst_curves,
+ selection,
+ start_points,
+ end_points,
+ src_ranges,
+ transfer_attributes);
+ };
+ auto trim_evaluated = [&](const IndexMask selection) {
+ /* Ensure evaluated positions are available. */
+ src_curves.ensure_evaluated_offsets();
+ src_curves.evaluated_positions();
+ trim_evaluated_curves(src_curves,
+ dst_curves,
+ selection,
+ start_points,
+ end_points,
+ src_ranges,
+ transfer_attributes);
+ };
+
+ /* Populate point domain. */
+ bke::curves::foreach_curve_by_type(src_curves.curve_types(),
+ src_curves.curve_type_counts(),
+ selection,
+ trim_catmull,
+ trim_poly,
+ trim_bezier,
+ trim_evaluated);
+
+ /* Cleanup/close context */
+ for (bke::AttributeTransferData &attribute : transfer_attributes) {
+ attribute.dst.finish();
+ }
+
+ /* Copy unselected */
+ if (!inverse_selection.is_empty()) {
+ transfer_curve_skip.remove("cyclic");
+ bke::copy_attribute_domain(
+ src_attributes, dst_attributes, inverse_selection, ATTR_DOMAIN_CURVE, transfer_curve_skip);
+ /* Trim curves are no longer cyclic. If all curves are trimmed, this will be set implicitly. */
+ dst_curves.cyclic_for_write().fill_indices(selection, false);
+
+ Set<std::string> copy_point_skip;
+ if (!dst_curves.has_curve_with_type(CURVE_TYPE_NURBS) &&
+ src_curves.has_curve_with_type(CURVE_TYPE_NURBS)) {
+ copy_point_skip.add("nurbs_weight");
+ }
+
+ /* Copy point domain. */
+ for (auto &attribute : bke::retrieve_attributes_for_transfer(
+ src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, copy_point_skip)) {
+ bke::curves::copy_point_data(
+ src_curves, dst_curves, inverse_selection, attribute.src, attribute.dst.span);
+ attribute.dst.finish();
+ }
+ }
+
+ dst_curves.tag_topology_changed();
+ return dst_curves;
+}
+
+/** \} */
+
+} // namespace blender::geometry
diff --git a/source/blender/geometry/intern/uv_parametrizer.cc b/source/blender/geometry/intern/uv_parametrizer.cc
index f074febe23a..070703f5228 100644
--- a/source/blender/geometry/intern/uv_parametrizer.cc
+++ b/source/blender/geometry/intern/uv_parametrizer.cc
@@ -22,11 +22,11 @@
/* Utils */
#define param_assert(condition) \
- if (!(condition)) { /*printf("Assertion %s:%d\n", __FILE__, __LINE__); abort();*/ \
+ if (!(condition)) { /* `printf("Assertion %s:%d\n", __FILE__, __LINE__); abort();` */ \
} \
(void)0
#define param_warning(message) \
- {/*printf("Warning %s:%d: %s\n", __FILE__, __LINE__, message);*/}(void)0
+ {/* `printf("Warning %s:%d: %s\n", __FILE__, __LINE__, message);` */}(void)0
/* Special Purpose Hash */
@@ -195,7 +195,7 @@ static int PHashSizes[] = {
1048583, 2097169, 4194319, 8388617, 16777259, 33554467, 67108879, 134217757, 268435459,
};
-#define PHASH_hash(ph, item) (((uintptr_t)(item)) % ((uint)(ph)->cursize))
+#define PHASH_hash(ph, item) (uintptr_t(item) % uint((ph)->cursize))
#define PHASH_edge(v1, v2) (((v1) < (v2)) ? ((v1)*39) ^ ((v2)*31) : ((v1)*31) ^ ((v2)*39))
static PHash *phash_new(PHashLink **list, int sizehint)
@@ -319,7 +319,7 @@ static void fix_large_angle(const float v_fix[3],
float *r_a1,
float *r_a2)
{
- const float max_angle = (float)M_PI * (179.0f / 180.0f);
+ const float max_angle = float(M_PI) * (179.0f / 180.0f);
const float fix_amount = *r_fix - max_angle;
if (fix_amount < 0.0f) {
return; /* angle is reasonable, i.e. less than 179 degrees. */
@@ -1903,7 +1903,7 @@ static bool p_collapse_allowed_geometric(PEdge *edge, PEdge *pair)
if (p_vert_interior(oldv)) {
/* HLSCM criterion: angular defect smaller than threshold. */
- if (fabsf(angulardefect) > (float)(M_PI * 30.0 / 180.0)) {
+ if (fabsf(angulardefect) > float(M_PI * 30.0 / 180.0)) {
return false;
}
}
@@ -2465,7 +2465,7 @@ static float p_abf_compute_gradient(PAbfSystem *sys, PChart *chart)
norm += galpha1 * galpha1 + galpha2 * galpha2 + galpha3 * galpha3;
- gtriangle = sys->alpha[e1->u.id] + sys->alpha[e2->u.id] + sys->alpha[e3->u.id] - (float)M_PI;
+ gtriangle = sys->alpha[e1->u.id] + sys->alpha[e2->u.id] + sys->alpha[e3->u.id] - float(M_PI);
sys->bTriangle[f->u.id] = -gtriangle;
norm += gtriangle * gtriangle;
}
@@ -2696,8 +2696,8 @@ static bool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart)
/* clamp */
PEdge *e = f->edge;
do {
- if (sys->alpha[e->u.id] > (float)M_PI) {
- sys->alpha[e->u.id] = (float)M_PI;
+ if (sys->alpha[e->u.id] > float(M_PI)) {
+ sys->alpha[e->u.id] = float(M_PI);
}
else if (sys->alpha[e->u.id] < 0.0f) {
sys->alpha[e->u.id] = 0.0f;
@@ -2706,8 +2706,8 @@ static bool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart)
}
for (int i = 0; i < ninterior; i++) {
- sys->lambdaPlanar[i] += (float)EIG_linear_solver_variable_get(context, 0, i);
- sys->lambdaLength[i] += (float)EIG_linear_solver_variable_get(context, 0, ninterior + i);
+ sys->lambdaPlanar[i] += float(EIG_linear_solver_variable_get(context, 0, i));
+ sys->lambdaLength[i] += float(EIG_linear_solver_variable_get(context, 0, ninterior + i));
}
}
@@ -2780,7 +2780,7 @@ static bool p_chart_abf_solve(PChart *chart)
e = e->next->next->pair;
} while (e && (e != v->edge));
- scale = (anglesum == 0.0f) ? 0.0f : 2.0f * (float)M_PI / anglesum;
+ scale = (anglesum == 0.0f) ? 0.0f : 2.0f * float(M_PI) / anglesum;
e = v->edge;
do {
@@ -3061,7 +3061,7 @@ static void p_chart_lscm_begin(PChart *chart, bool live, bool abf)
}
}
- if ((live && (!select || !deselect))) {
+ if (live && (!select || !deselect)) {
chart->u.lscm.context = nullptr;
}
else {
@@ -3409,7 +3409,7 @@ static void p_chart_stretch_minimize(PChart *chart, RNG *rng)
trusted_radius /= 2 * nedges;
- random_angle = BLI_rng_get_float(rng) * 2.0f * (float)M_PI;
+ random_angle = BLI_rng_get_float(rng) * 2.0f * float(M_PI);
dir[0] = trusted_radius * cosf(random_angle);
dir[1] = trusted_radius * sinf(random_angle);
@@ -3588,7 +3588,7 @@ static float p_chart_minimum_area_angle(PChart *chart)
p2 = points[i];
p3 = (i == npoints - 1) ? points[0] : points[i + 1];
- angles[i] = (float)M_PI - p_vec2_angle(p1->uv, p2->uv, p3->uv);
+ angles[i] = float(M_PI) - p_vec2_angle(p1->uv, p2->uv, p3->uv);
if (points[i]->uv[1] < miny) {
miny = points[i]->uv[1];
@@ -3628,7 +3628,7 @@ static float p_chart_minimum_area_angle(PChart *chart)
minarea = 1e10;
minangle = 0.0;
- while (rotated <= (float)M_PI_2) { /* INVESTIGATE: how far to rotate? */
+ while (rotated <= float(M_PI_2)) { /* INVESTIGATE: how far to rotate? */
/* rotate with the smallest angle */
i_min = 0;
mina = 1e10;
@@ -3675,8 +3675,8 @@ static float p_chart_minimum_area_angle(PChart *chart)
}
/* try keeping rotation as small as possible */
- if (minangle > (float)M_PI_4) {
- minangle -= (float)M_PI_2;
+ if (minangle > float(M_PI_4)) {
+ minangle -= float(M_PI_2);
}
MEM_freeN(angles);
@@ -3869,9 +3869,9 @@ static void p_add_ngon(ParamHandle *handle,
Heap *heap = handle->polyfill_heap;
uint nfilltri = nverts - 2;
uint(*tris)[3] = static_cast<uint(*)[3]>(
- BLI_memarena_alloc(arena, sizeof(*tris) * (size_t)nfilltri));
+ BLI_memarena_alloc(arena, sizeof(*tris) * size_t(nfilltri)));
float(*projverts)[2] = static_cast<float(*)[2]>(
- BLI_memarena_alloc(arena, sizeof(*projverts) * (size_t)nverts));
+ BLI_memarena_alloc(arena, sizeof(*projverts) * size_t(nverts)));
/* Calc normal, flipped: to get a positive 2d cross product. */
float normal[3];
@@ -4209,7 +4209,7 @@ void GEO_uv_parametrizer_pack(ParamHandle *handle,
box->index = i; /* Warning this index skips chart->has_pins boxes. */
if (margin > 0.0f) {
- area += (double)sqrtf(box->w * box->h);
+ area += double(sqrtf(box->w * box->h));
}
}
@@ -4218,7 +4218,7 @@ void GEO_uv_parametrizer_pack(ParamHandle *handle,
* ...Without using the area running pack multiple times also gives a bad feedback loop.
* multiply by 0.1 so the margin value from the UI can be from
* 0.0 to 1.0 but not give a massive margin */
- margin = (margin * (float)area) * 0.1f;
+ margin = (margin * float(area)) * 0.1f;
unpacked = 0;
for (i = 0; i < handle->ncharts; i++) {
chart = handle->charts[i];
@@ -4342,7 +4342,7 @@ void GEO_uv_parametrizer_average(ParamHandle *phandle,
/* Compute correction transform. */
float t[2][2];
t[0][0] = scale_factor_u;
- t[1][0] = clamp_f((float)(scale_cross / weight_sum), -0.5f, 0.5f);
+ t[1][0] = clamp_f(float(scale_cross / weight_sum), -0.5f, 0.5f);
t[0][1] = 0;
t[1][1] = 1.0f / scale_factor_u;
diff --git a/source/blender/gpencil_modifiers/CMakeLists.txt b/source/blender/gpencil_modifiers/CMakeLists.txt
index 5ef9ae1bbc6..8dbac602c06 100644
--- a/source/blender/gpencil_modifiers/CMakeLists.txt
+++ b/source/blender/gpencil_modifiers/CMakeLists.txt
@@ -47,6 +47,7 @@ set(SRC
intern/MOD_gpencilnoise.c
intern/MOD_gpenciloffset.c
intern/MOD_gpencilopacity.c
+ intern/MOD_gpenciloutline.c
intern/MOD_gpencilshrinkwrap.c
intern/MOD_gpencilsimplify.c
intern/MOD_gpencilsmooth.c
diff --git a/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h
index 9025fecacd8..2f3cf4d2312 100644
--- a/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h
+++ b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h
@@ -20,6 +20,7 @@ extern GpencilModifierTypeInfo modifierType_Gpencil_Color;
extern GpencilModifierTypeInfo modifierType_Gpencil_Array;
extern GpencilModifierTypeInfo modifierType_Gpencil_Build;
extern GpencilModifierTypeInfo modifierType_Gpencil_Opacity;
+extern GpencilModifierTypeInfo modifierType_Gpencil_Outline;
extern GpencilModifierTypeInfo modifierType_Gpencil_Lattice;
extern GpencilModifierTypeInfo modifierType_Gpencil_Length;
extern GpencilModifierTypeInfo modifierType_Gpencil_Mirror;
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c
index bd8fd9f72ad..d4ada842d0b 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c
@@ -41,6 +41,7 @@ void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[])
INIT_GP_TYPE(Array);
INIT_GP_TYPE(Build);
INIT_GP_TYPE(Opacity);
+ INIT_GP_TYPE(Outline);
INIT_GP_TYPE(Lattice);
INIT_GP_TYPE(Length);
INIT_GP_TYPE(Mirror);
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c
index 8bb61136cc2..e51fe8832f0 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c
@@ -104,9 +104,9 @@ static void BKE_gpencil_instance_modifier_instance_tfm(Object *ob,
if (mmd->flag & GP_ARRAY_USE_OFFSET) {
add_v3_v3(mat_offset[3], mmd->offset);
}
- invert_m4_m4(obinv, ob->obmat);
+ invert_m4_m4(obinv, ob->object_to_world);
- mul_m4_series(r_offset, mat_offset, obinv, mmd->object->obmat);
+ mul_m4_series(r_offset, mat_offset, obinv, mmd->object->object_to_world);
copy_m4_m4(mat_offset, r_offset);
/* clear r_mat locations to avoid double transform */
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c
index 3c971ec6af0..49ac3275c82 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c
@@ -303,8 +303,8 @@ static void build_sequential(Object *ob,
/* Compute distance to control object if set, and build according to that order. */
if (mmd->object) {
float sv1[3], sv2[3];
- mul_v3_m4v3(sv1, ob->obmat, &gps->points[0].x);
- mul_v3_m4v3(sv2, ob->obmat, &gps->points[gps->totpoints - 1].x);
+ mul_v3_m4v3(sv1, ob->object_to_world, &gps->points[0].x);
+ mul_v3_m4v3(sv2, ob->object_to_world, &gps->points[gps->totpoints - 1].x);
float dist_l = len_v3v3(sv1, mmd->object->loc);
float dist_r = len_v3v3(sv2, mmd->object->loc);
if (dist_r < dist_l) {
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c
index 1a2bfebdc55..e3b4e1c5e02 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c
@@ -234,14 +234,14 @@ static void deformStroke(GpencilModifierData *md,
/* get world-space matrix of target, corrected for the space the verts are in */
if (mmd->subtarget[0] && pchan) {
/* bone target if there's a matching pose-channel */
- mul_m4_m4m4(dmat, mmd->object->obmat, pchan->pose_mat);
+ mul_m4_m4m4(dmat, mmd->object->object_to_world, pchan->pose_mat);
}
else {
/* just object target */
- copy_m4_m4(dmat, mmd->object->obmat);
+ copy_m4_m4(dmat, mmd->object->object_to_world);
}
- invert_m4_m4(ob->imat, ob->obmat);
- mul_m4_series(tData.mat, ob->imat, dmat, mmd->parentinv);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
+ mul_m4_series(tData.mat, ob->world_to_object, dmat, mmd->parentinv);
/* loop points and apply deform */
for (int i = 0; i < gps->totpoints; i++) {
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillength.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillength.c
index c1a978162b8..b4dac1557f0 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencillength.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillength.c
@@ -138,7 +138,7 @@ static void applyLength(GpencilModifierData *md,
seed += BLI_hash_string(md->name);
if (lmd->flag & GP_LENGTH_USE_RANDOM) {
- seed += ((int)DEG_get_ctime(depsgraph)) / lmd->step;
+ seed += (int)DEG_get_ctime(depsgraph) / lmd->step;
}
float rand_offset = BLI_hash_int_01(seed);
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
index 6bb59f29b98..ec4cf71e00c 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
@@ -145,13 +145,12 @@ static void generateStrokes(GpencilModifierData *md, Depsgraph *depsgraph, Objec
LineartCache *local_lc = gpd->runtime.lineart_cache;
if (!gpd->runtime.lineart_cache) {
MOD_lineart_compute_feature_lines(
- depsgraph, lmd, &gpd->runtime.lineart_cache, (!(ob->dtx & OB_DRAW_IN_FRONT)));
+ depsgraph, lmd, &gpd->runtime.lineart_cache, !(ob->dtx & OB_DRAW_IN_FRONT));
MOD_lineart_destroy_render_data(lmd);
}
else {
if (!(lmd->flags & LRT_GPENCIL_USE_CACHE)) {
- MOD_lineart_compute_feature_lines(
- depsgraph, lmd, &local_lc, (!(ob->dtx & OB_DRAW_IN_FRONT)));
+ MOD_lineart_compute_feature_lines(depsgraph, lmd, &local_lc, !(ob->dtx & OB_DRAW_IN_FRONT));
MOD_lineart_destroy_render_data(lmd);
}
MOD_lineart_chain_clear_picked_flag(local_lc);
@@ -198,7 +197,7 @@ static void bakeModifier(Main *UNUSED(bmain),
lmd->shadow_selection_override = lmd->shadow_selection;
MOD_lineart_compute_feature_lines(
- depsgraph, lmd, &gpd->runtime.lineart_cache, (!(ob->dtx & OB_DRAW_IN_FRONT)));
+ depsgraph, lmd, &gpd->runtime.lineart_cache, !(ob->dtx & OB_DRAW_IN_FRONT));
MOD_lineart_destroy_render_data(lmd);
}
@@ -397,7 +396,12 @@ static void edge_types_panel_draw(const bContext *UNUSED(C), Panel *panel)
sub = uiLayoutRow(entry, false);
uiItemR(sub, ptr, "use_light_contour", 0, IFACE_("Light Contour"), ICON_NONE);
- uiItemR(entry, ptr, "use_shadow", 0, IFACE_("Cast Shadow"), ICON_NONE);
+ uiItemR(entry,
+ ptr,
+ "use_shadow",
+ 0,
+ CTX_IFACE_(BLT_I18NCONTEXT_ID_GPENCIL, "Cast Shadow"),
+ ICON_NONE);
uiItemL(layout, IFACE_("Options"), ICON_NONE);
@@ -442,8 +446,8 @@ static void options_light_reference_draw(const bContext *UNUSED(C), Panel *panel
uiItemR(remaining, ptr, "shadow_camera_size", 0, NULL, ICON_NONE);
uiLayout *col = uiLayoutColumn(remaining, true);
- uiItemR(col, ptr, "shadow_camera_near", 0, "Near", ICON_NONE);
- uiItemR(col, ptr, "shadow_camera_far", 0, "Far", ICON_NONE);
+ uiItemR(col, ptr, "shadow_camera_near", 0, IFACE_("Near"), ICON_NONE);
+ uiItemR(col, ptr, "shadow_camera_far", 0, IFACE_("Far"), ICON_NONE);
}
static void options_panel_draw(const bContext *UNUSED(C), Panel *panel)
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c
index 326e86091c5..bc91094e80e 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c
@@ -81,8 +81,8 @@ static void update_mirror_object(Object *ob,
float tmp[4][4];
float itmp[4][4];
- invert_m4_m4(tmp, mmd->object->obmat);
- mul_m4_m4m4(tmp, tmp, ob->obmat);
+ invert_m4_m4(tmp, mmd->object->object_to_world);
+ mul_m4_m4m4(tmp, tmp, ob->object_to_world);
invert_m4_m4(itmp, tmp);
mul_m4_series(mtx, itmp, mtx, tmp);
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilmultiply.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilmultiply.c
index 1cf11a694ac..cb4a7893080 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilmultiply.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilmultiply.c
@@ -109,7 +109,7 @@ static void duplicateStroke(Object *ob,
float opacity_factor;
/* Apply object scale to offset distance. */
- offset *= mat4_to_scale(ob->obmat);
+ offset *= mat4_to_scale(ob->object_to_world);
BKE_gpencil_stroke_normal(gps, stroke_normal);
if (len_v3(stroke_normal) < FLT_EPSILON) {
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciloutline.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciloutline.c
new file mode 100644
index 00000000000..455d8b0b528
--- /dev/null
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciloutline.c
@@ -0,0 +1,343 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. */
+
+/** \file
+ * \ingroup modifiers
+ */
+
+#include <stdio.h>
+
+#include "BLI_utildefines.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math_vector.h"
+
+#include "BLT_translation.h"
+
+#include "DNA_defaults.h"
+#include "DNA_gpencil_modifier_types.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_material_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+
+#include "BKE_context.h"
+#include "BKE_gpencil.h"
+#include "BKE_gpencil_geom.h"
+#include "BKE_gpencil_modifier.h"
+#include "BKE_lib_query.h"
+#include "BKE_main.h"
+#include "BKE_material.h"
+#include "BKE_scene.h"
+#include "BKE_screen.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "BKE_modifier.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#include "MOD_gpencil_modifiertypes.h"
+#include "MOD_gpencil_ui_common.h"
+#include "MOD_gpencil_util.h"
+
+static void initData(GpencilModifierData *md)
+{
+ OutlineGpencilModifierData *gpmd = (OutlineGpencilModifierData *)md;
+
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(gpmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(gpmd, DNA_struct_default_get(OutlineGpencilModifierData), modifier);
+}
+
+static void copyData(const GpencilModifierData *md, GpencilModifierData *target)
+{
+ BKE_gpencil_modifier_copydata_generic(md, target);
+}
+
+static void free_old_strokes(Depsgraph *depsgraph, Object *ob, bGPdata *gpd)
+{
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ /* Free old strokes. */
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ bGPDframe *gpf = BKE_gpencil_frame_retime_get(depsgraph, scene, ob, gpl);
+ if (gpf == NULL) {
+ continue;
+ }
+ LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
+ if (gps->flag & GP_STROKE_TAG) {
+ BLI_remlink(&gpf->strokes, gps);
+ BKE_gpencil_free_stroke(gps);
+ }
+ }
+ }
+}
+
+static void convert_stroke(GpencilModifierData *md,
+ Object *ob,
+ bGPDlayer *gpl,
+ bGPDframe *gpf,
+ bGPDstroke *gps,
+ float viewmat[4][4],
+ float diff_mat[4][4])
+{
+ OutlineGpencilModifierData *mmd = (OutlineGpencilModifierData *)md;
+ bGPdata *gpd = (bGPdata *)ob->data;
+ const bool keep = (mmd->flag & GP_OUTLINE_KEEP_SHAPE) != 0;
+
+ if (!is_stroke_affected_by_modifier(ob,
+ mmd->layername,
+ mmd->material,
+ mmd->pass_index,
+ mmd->layer_pass,
+ 1,
+ gpl,
+ gps,
+ mmd->flag & GP_OUTLINE_INVERT_LAYER,
+ mmd->flag & GP_OUTLINE_INVERT_PASS,
+ mmd->flag & GP_OUTLINE_INVERT_LAYERPASS,
+ mmd->flag & GP_OUTLINE_INVERT_MATERIAL)) {
+ return;
+ }
+
+ MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
+ const bool is_stroke = (gp_style->flag & GP_MATERIAL_STROKE_SHOW) != 0;
+ /* Only strokes type, no fill strokes. */
+ if (!is_stroke) {
+ return;
+ }
+
+ /* Duplicate the stroke to apply any layer thickness change. */
+ bGPDstroke *gps_duplicate = BKE_gpencil_stroke_duplicate(gps, true, false);
+
+ /* Apply layer thickness change. */
+ gps_duplicate->thickness += gpl->line_change;
+ /* Apply object scale to thickness. */
+ gps_duplicate->thickness *= mat4_to_scale(ob->object_to_world);
+ CLAMP_MIN(gps_duplicate->thickness, 1.0f);
+
+ /* Stroke. */
+ const float ovr_thickness = keep ? mmd->thickness : 0.0f;
+ bGPDstroke *gps_perimeter = BKE_gpencil_stroke_perimeter_from_view(
+ viewmat, gpd, gpl, gps_duplicate, mmd->subdiv, diff_mat, ovr_thickness);
+ gps_perimeter->flag &= ~GP_STROKE_SELECT;
+ gps_perimeter->runtime.gps_orig = gps->runtime.gps_orig;
+
+ /* Assign material. */
+ if (mmd->outline_material) {
+ Material *ma = mmd->outline_material;
+ int mat_idx = BKE_gpencil_material_find_index_by_name_prefix(ob, ma->id.name + 2);
+ if (mat_idx > -1) {
+ gps_perimeter->mat_nr = mat_idx;
+ }
+ else {
+ gps_perimeter->mat_nr = gps->mat_nr;
+ }
+ }
+ else {
+ gps_perimeter->mat_nr = gps->mat_nr;
+ }
+
+ /* Sample stroke. */
+ if (mmd->sample_length > 0.0f) {
+ BKE_gpencil_stroke_sample(gpd, gps_perimeter, mmd->sample_length, false, 0);
+ }
+ /* Set stroke thickness. */
+ gps_perimeter->thickness = mmd->thickness;
+
+ /* Set pressure constant. */
+ int orig_idx = -1;
+ float min_distance = FLT_MAX;
+ bGPDspoint *pt;
+ for (int i = 0; i < gps_perimeter->totpoints; i++) {
+ pt = &gps_perimeter->points[i];
+ pt->pressure = 1.0f;
+ pt->runtime.pt_orig = NULL;
+ /* If any target object is defined, find the nearest point. */
+ if (mmd->object) {
+ float wpt[3];
+ mul_v3_m4v3(wpt, diff_mat, &pt->x);
+ float dist = len_squared_v3v3(wpt, mmd->object->loc);
+ if (dist < min_distance) {
+ min_distance = dist;
+ orig_idx = i;
+ }
+ }
+ }
+
+ if (orig_idx > 0) {
+ BKE_gpencil_stroke_start_set(gps_perimeter, orig_idx);
+ BKE_gpencil_stroke_geometry_update(gpd, gps_perimeter);
+ }
+
+ /* Add perimeter stroke to frame. */
+ BLI_insertlinkafter(&gpf->strokes, gps, gps_perimeter);
+
+ /* Free Temp stroke. */
+ BKE_gpencil_free_stroke(gps_duplicate);
+
+ /* Tag original stroke to be removed. */
+ gps->flag |= GP_STROKE_TAG;
+}
+
+static void generateStrokes(GpencilModifierData *md, Depsgraph *depsgraph, Object *ob)
+{
+ bGPdata *gpd = (bGPdata *)ob->data;
+
+ /* Calc camera view matrix. */
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ /* Ensure the camera is the right one. */
+ BKE_scene_camera_switch_update(scene);
+
+ if (!scene->camera) {
+ return;
+ }
+ Object *cam_ob = scene->camera;
+ float viewmat[4][4];
+ invert_m4_m4(viewmat, cam_ob->object_to_world);
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ bGPDframe *gpf = BKE_gpencil_frame_retime_get(depsgraph, scene, ob, gpl);
+ if (gpf == NULL) {
+ continue;
+ }
+ /* Prepare transform matrix. */
+ float diff_mat[4][4];
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
+
+ LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
+ gps->flag &= ~GP_STROKE_TAG;
+ convert_stroke(md, ob, gpl, gpf, gps, viewmat, diff_mat);
+ }
+ }
+
+ /* Delete original strokes. */
+ free_old_strokes(depsgraph, ob, gpd);
+}
+
+static void bakeModifier(Main *UNUSED(bmain),
+ Depsgraph *depsgraph,
+ GpencilModifierData *md,
+ Object *ob)
+{
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ bGPdata *gpd = ob->data;
+ int oldframe = (int)DEG_get_ctime(depsgraph);
+
+ /* Calc camera view matrix. */
+ if (!scene->camera) {
+ return;
+ }
+ Object *cam_ob = scene->camera;
+ float viewmat[4][4];
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ scene->r.cfra = gpf->framenum;
+ BKE_scene_graph_update_for_newframe(depsgraph);
+ /* Ensure the camera is the right one. */
+ BKE_scene_camera_switch_update(scene);
+ invert_m4_m4(viewmat, cam_ob->object_to_world);
+
+ /* Prepare transform matrix. */
+ float diff_mat[4][4];
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
+
+ /* Compute all strokes of this frame. */
+ LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
+ convert_stroke(md, ob, gpl, gpf, gps, viewmat, diff_mat);
+ }
+ }
+ }
+
+ /* Delete original strokes. */
+ free_old_strokes(depsgraph, ob, gpd);
+
+ /* Return frame state and DB to original state. */
+ scene->r.cfra = oldframe;
+ BKE_scene_graph_update_for_newframe(depsgraph);
+}
+
+static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
+{
+ OutlineGpencilModifierData *mmd = (OutlineGpencilModifierData *)md;
+
+ walk(userData, ob, (ID **)&mmd->material, IDWALK_CB_USER);
+ walk(userData, ob, (ID **)&mmd->outline_material, IDWALK_CB_USER);
+ walk(userData, ob, (ID **)&mmd->object, IDWALK_CB_NOP);
+}
+
+static void updateDepsgraph(GpencilModifierData *md,
+ const ModifierUpdateDepsgraphContext *ctx,
+ const int UNUSED(mode))
+{
+ OutlineGpencilModifierData *lmd = (OutlineGpencilModifierData *)md;
+ if (ctx->scene->camera) {
+ DEG_add_object_relation(
+ ctx->node, ctx->scene->camera, DEG_OB_COMP_TRANSFORM, "Outline Modifier");
+ DEG_add_object_relation(
+ ctx->node, ctx->scene->camera, DEG_OB_COMP_PARAMETERS, "Outline Modifier");
+ }
+ if (lmd->object != NULL) {
+ DEG_add_object_relation(ctx->node, lmd->object, DEG_OB_COMP_TRANSFORM, "Outline Modifier");
+ }
+ DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Outline Modifier");
+}
+
+static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+{
+ uiLayout *layout = panel->layout;
+
+ PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL);
+
+ uiLayoutSetPropSep(layout, true);
+
+ uiItemR(layout, ptr, "thickness", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_keep_shape", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "subdivision", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "sample_length", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "outline_material", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
+
+ gpencil_modifier_panel_end(layout, ptr);
+}
+
+static void mask_panel_draw(const bContext *UNUSED(C), Panel *panel)
+{
+ gpencil_modifier_masking_panel_draw(panel, true, false);
+}
+
+static void panelRegister(ARegionType *region_type)
+{
+ PanelType *panel_type = gpencil_modifier_panel_register(
+ region_type, eGpencilModifierType_Outline, panel_draw);
+ gpencil_modifier_subpanel_register(
+ region_type, "mask", "Influence", NULL, mask_panel_draw, panel_type);
+}
+
+GpencilModifierTypeInfo modifierType_Gpencil_Outline = {
+ /* name */ N_("Outline"),
+ /* structName */ "OutlineGpencilModifierData",
+ /* structSize */ sizeof(OutlineGpencilModifierData),
+ /* type */ eGpencilModifierTypeType_Gpencil,
+ /* flags */ eGpencilModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ copyData,
+
+ /* deformStroke */ NULL,
+ /* generateStrokes */ generateStrokes,
+ /* bakeModifier */ bakeModifier,
+ /* remapTime */ NULL,
+
+ /* initData */ initData,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ NULL,
+ /* panelRegister */ panelRegister,
+};
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c
index 1d45030b68b..b04fdeb0a83 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c
@@ -9,6 +9,11 @@
#include <stdlib.h>
#include <string.h>
+#include "MEM_guardedalloc.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
@@ -16,20 +21,33 @@
#include "DNA_defaults.h"
#include "DNA_gpencil_modifier_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "BKE_context.h"
+#include "BKE_gpencil.h"
+#include "BKE_gpencil_geom.h"
#include "BKE_gpencil_modifier.h"
+#include "BKE_lib_query.h"
+#include "BKE_main.h"
+#include "BKE_modifier.h"
#include "BKE_screen.h"
-#include "UI_interface.h"
-#include "UI_resources.h"
-
#include "RNA_access.h"
+#include "RNA_prototypes.h"
#include "MOD_gpencil_modifiertypes.h"
#include "MOD_gpencil_ui_common.h"
+#include "MOD_gpencil_util.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "WM_api.h"
+
+#include "DEG_depsgraph.h"
static void initData(GpencilModifierData *md)
{
@@ -38,11 +56,26 @@ static void initData(GpencilModifierData *md)
BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(gpmd, modifier));
MEMCPY_STRUCT_AFTER(gpmd, DNA_struct_default_get(TimeGpencilModifierData), modifier);
+ TimeGpencilModifierSegment *ds = DNA_struct_default_alloc(TimeGpencilModifierSegment);
+ ds->gpmd = gpmd;
+ BLI_strncpy(ds->name, DATA_("Segment"), sizeof(ds->name));
+
+ gpmd->segments = ds;
}
static void copyData(const GpencilModifierData *md, GpencilModifierData *target)
{
+ TimeGpencilModifierData *gpmd = (TimeGpencilModifierData *)target;
+ const TimeGpencilModifierData *gpmd_src = (const TimeGpencilModifierData *)md;
BKE_gpencil_modifier_copydata_generic(md, target);
+ gpmd->segments = MEM_dupallocN(gpmd_src->segments);
+}
+
+static void freeData(GpencilModifierData *md)
+{
+ TimeGpencilModifierData *gpmd = (TimeGpencilModifierData *)md;
+
+ MEM_SAFE_FREE(gpmd->segments);
}
static int remapTime(struct GpencilModifierData *md,
@@ -60,6 +93,7 @@ static int remapTime(struct GpencilModifierData *md,
int efra = custom ? mmd->efra : scene->r.efra;
int offset = mmd->offset;
int nfra = 0;
+
CLAMP_MIN(sfra, 0);
CLAMP_MIN(efra, 0);
@@ -100,6 +134,7 @@ static int remapTime(struct GpencilModifierData *md,
/* apply frame scale */
cfra *= mmd->frame_scale;
+ CLAMP_MIN(cfra, 1);
/* if fix mode, return predefined frame number */
if (mmd->mode == GP_TIME_MODE_FIX) {
@@ -146,10 +181,111 @@ static int remapTime(struct GpencilModifierData *md,
}
}
+ if (mmd->mode == GP_TIME_MODE_CHAIN) {
+ int sequence_length = 0;
+ int frame_key = 0;
+ int *segment_arr;
+ int start, end;
+ if (mmd->segments_len > 0) {
+ for (int i = 0; i < mmd->segments_len; i++) {
+ start = mmd->segments[i].seg_start;
+ end = mmd->segments[i].seg_end;
+ if (mmd->segments[i].seg_end < mmd->segments[i].seg_start) {
+ start = mmd->segments[i].seg_end;
+ end = mmd->segments[i].seg_start;
+ }
+
+ if (ELEM(mmd->segments[i].seg_mode, GP_TIME_SEG_MODE_PINGPONG)) {
+ sequence_length += ((end - start) * mmd->segments[i].seg_repeat) * 2 + 1;
+ }
+ else {
+ sequence_length += ((end - start + 1) * mmd->segments[i].seg_repeat);
+ }
+ }
+ segment_arr = MEM_malloc_arrayN(sequence_length, sizeof(int *), __func__);
+
+ for (int i = 0; i < mmd->segments_len; i++) {
+
+ if (mmd->segments[i].seg_end < mmd->segments[i].seg_start) {
+ start = mmd->segments[i].seg_end;
+ end = mmd->segments[i].seg_start;
+ }
+ else {
+ start = mmd->segments[i].seg_start;
+ end = mmd->segments[i].seg_end;
+ }
+ for (int a = 0; a < mmd->segments[i].seg_repeat; a++) {
+ switch (mmd->segments[i].seg_mode) {
+ case GP_TIME_SEG_MODE_NORMAL:
+ for (int b = 0; b < end - start + 1; b++) {
+ segment_arr[frame_key] = start + b;
+ frame_key++;
+ }
+ break;
+ case GP_TIME_SEG_MODE_REVERSE:
+ for (int b = 0; b < end - start + 1; b++) {
+ segment_arr[frame_key] = end - b;
+ frame_key++;
+ }
+ break;
+ case GP_TIME_SEG_MODE_PINGPONG:
+ for (int b = 0; b < end - start; b++) {
+ segment_arr[frame_key] = start + b;
+ frame_key++;
+ }
+ for (int b = 0; b < end - start; b++) {
+ segment_arr[frame_key] = end - b;
+ frame_key++;
+ if (a == mmd->segments[i].seg_repeat - 1 && b == end - start - 1) {
+ segment_arr[frame_key] = start;
+ frame_key++;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ if ((mmd->flag & GP_TIME_KEEP_LOOP) == 0) {
+ if ((cfra + offset - 1) < sequence_length) {
+ nfra = segment_arr[(cfra - 1 + offset)];
+ }
+ else {
+ nfra = segment_arr[frame_key - 1];
+ }
+ }
+ else {
+ nfra = segment_arr[(cfra - 1 + offset) % sequence_length];
+ }
+
+ MEM_freeN(segment_arr);
+ }
+ }
+
return nfra;
}
-static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void segment_list_item(struct uiList *UNUSED(ui_list),
+ const struct bContext *UNUSED(C),
+ struct uiLayout *layout,
+ struct PointerRNA *UNUSED(idataptr),
+ struct PointerRNA *itemptr,
+ int UNUSED(icon),
+ struct PointerRNA *UNUSED(active_dataptr),
+ const char *UNUSED(active_propname),
+ int UNUSED(index),
+ int UNUSED(flt_flag))
+{
+ uiLayout *row = uiLayoutRow(layout, true);
+ uiItemR(row, itemptr, "name", UI_ITEM_R_NO_BG, "", ICON_NONE);
+}
+static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
+{
+ TimeGpencilModifierData *mmd = (TimeGpencilModifierData *)md;
+
+ walk(userData, ob, (ID **)&mmd->material, IDWALK_CB_USER);
+}
+static void panel_draw(const bContext *C, Panel *panel)
{
uiLayout *row, *col;
uiLayout *layout = panel->layout;
@@ -175,6 +311,56 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetActive(row, mode != GP_TIME_MODE_FIX);
uiItemR(row, ptr, "use_keep_loop", 0, NULL, ICON_NONE);
+ if (mode == GP_TIME_MODE_CHAIN) {
+
+ row = uiLayoutRow(layout, false);
+ uiLayoutSetPropSep(row, false);
+
+ uiTemplateList(row,
+ (bContext *)C,
+ "MOD_UL_time_segment",
+ "",
+ ptr,
+ "segments",
+ ptr,
+ "segment_active_index",
+ NULL,
+ 3,
+ 10,
+ 0,
+ 1,
+ UI_TEMPLATE_LIST_FLAG_NONE);
+
+ col = uiLayoutColumn(row, false);
+ uiLayoutSetContextPointer(col, "modifier", ptr);
+
+ uiLayout *sub = uiLayoutColumn(col, true);
+ uiItemO(sub, "", ICON_ADD, "GPENCIL_OT_time_segment_add");
+ uiItemO(sub, "", ICON_REMOVE, "GPENCIL_OT_time_segment_remove");
+ uiItemS(col);
+ sub = uiLayoutColumn(col, true);
+ uiItemEnumO_string(sub, "", ICON_TRIA_UP, "GPENCIL_OT_time_segment_move", "type", "UP");
+ uiItemEnumO_string(sub, "", ICON_TRIA_DOWN, "GPENCIL_OT_time_segment_move", "type", "DOWN");
+
+ TimeGpencilModifierData *gpmd = ptr->data;
+ if (gpmd->segment_active_index >= 0 && gpmd->segment_active_index < gpmd->segments_len) {
+ PointerRNA ds_ptr;
+ RNA_pointer_create(ptr->owner_id,
+ &RNA_TimeGpencilModifierSegment,
+ &gpmd->segments[gpmd->segment_active_index],
+ &ds_ptr);
+
+ sub = uiLayoutColumn(layout, true);
+ uiItemR(sub, &ds_ptr, "seg_mode", 0, NULL, ICON_NONE);
+ sub = uiLayoutColumn(layout, true);
+ uiItemR(sub, &ds_ptr, "seg_start", 0, NULL, ICON_NONE);
+ uiItemR(sub, &ds_ptr, "seg_end", 0, NULL, ICON_NONE);
+ uiItemR(sub, &ds_ptr, "seg_repeat", 0, NULL, ICON_NONE);
+ }
+
+ gpencil_modifier_panel_end(layout, ptr);
+ }
+
gpencil_modifier_panel_end(layout, ptr);
}
@@ -186,7 +372,7 @@ static void custom_range_header_draw(const bContext *UNUSED(C), Panel *panel)
int mode = RNA_enum_get(ptr, "mode");
- uiLayoutSetActive(layout, mode != GP_TIME_MODE_FIX);
+ uiLayoutSetActive(layout, (mode != GP_TIME_MODE_FIX && mode != GP_TIME_MODE_CHAIN));
uiItemR(layout, ptr, "use_custom_frame_range", 0, NULL, ICON_NONE);
}
@@ -201,9 +387,9 @@ static void custom_range_panel_draw(const bContext *UNUSED(C), Panel *panel)
int mode = RNA_enum_get(ptr, "mode");
uiLayoutSetPropSep(layout, true);
-
- uiLayoutSetActive(
- layout, (mode != GP_TIME_MODE_FIX) && (RNA_boolean_get(ptr, "use_custom_frame_range")));
+ uiLayoutSetActive(layout,
+ (mode != GP_TIME_MODE_FIX && mode != GP_TIME_MODE_CHAIN) &&
+ RNA_boolean_get(ptr, "use_custom_frame_range"));
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "frame_start", 0, IFACE_("Frame Start"), ICON_NONE);
@@ -227,6 +413,11 @@ static void panelRegister(ARegionType *region_type)
panel_type);
gpencil_modifier_subpanel_register(
region_type, "mask", "Influence", NULL, mask_panel_draw, panel_type);
+
+ uiListType *list_type = MEM_callocN(sizeof(uiListType), "time modifier segment uilist");
+ strcpy(list_type->idname, "MOD_UL_time_segment");
+ list_type->draw_item = segment_list_item;
+ WM_uilisttype_add(list_type);
}
GpencilModifierTypeInfo modifierType_Gpencil_Time = {
@@ -244,11 +435,11 @@ GpencilModifierTypeInfo modifierType_Gpencil_Time = {
/* remapTime */ remapTime,
/* initData */ initData,
- /* freeData */ NULL,
+ /* freeData */ freeData,
/* isDisabled */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* panelRegister */ panelRegister,
};
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c
index 94d8cb98290..8331188fbd8 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c
@@ -144,7 +144,7 @@ static void deformStroke(GpencilModifierData *md,
float coba_res[4];
float matrix[4][4];
if (is_gradient) {
- mul_m4_m4m4(matrix, mmd->object->imat, ob->obmat);
+ mul_m4_m4m4(matrix, mmd->object->world_to_object, ob->object_to_world);
}
/* loop points and apply color. */
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilweight_angle.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilweight_angle.c
index 3ecff4bf447..e9761732614 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilweight_angle.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilweight_angle.c
@@ -97,7 +97,7 @@ static void deformStroke(GpencilModifierData *md,
/* Apply the rotation of the object. */
if (mmd->space == GP_SPACE_LOCAL) {
- mul_mat3_m4_v3(ob->obmat, vec_ref);
+ mul_mat3_m4_v3(ob->object_to_world, vec_ref);
}
/* Ensure there is a vertex group. */
@@ -122,8 +122,8 @@ static void deformStroke(GpencilModifierData *md,
bGPDspoint *pt1 = (i > 0) ? &gps->points[i] : &gps->points[i + 1];
bGPDspoint *pt2 = (i > 0) ? &gps->points[i - 1] : &gps->points[i];
float fpt1[3], fpt2[3];
- mul_v3_m4v3(fpt1, ob->obmat, &pt1->x);
- mul_v3_m4v3(fpt2, ob->obmat, &pt2->x);
+ mul_v3_m4v3(fpt1, ob->object_to_world, &pt1->x);
+ mul_v3_m4v3(fpt2, ob->object_to_world, &pt2->x);
float vec[3];
sub_v3_v3v3(vec, fpt1, fpt2);
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilweight_proximity.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilweight_proximity.c
index f64c83443d8..ddf852bcd11 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilweight_proximity.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilweight_proximity.c
@@ -64,8 +64,8 @@ static float calc_point_weight_by_distance(Object *ob,
{
float weight;
float gvert[3];
- mul_v3_m4v3(gvert, ob->obmat, &pt->x);
- float dist = len_v3v3(mmd->object->obmat[3], gvert);
+ mul_v3_m4v3(gvert, ob->object_to_world, &pt->x);
+ float dist = len_v3v3(mmd->object->object_to_world[3], gvert);
if (dist > dist_max) {
weight = 1.0f;
diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index ae013a7dd02..22037d10a71 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -442,6 +442,7 @@ typedef enum eLineartTriangleFlags {
LRT_TRIANGLE_INTERSECTION_ONLY = (1 << 3),
LRT_TRIANGLE_NO_INTERSECTION = (1 << 4),
LRT_TRIANGLE_MAT_BACK_FACE_CULLING = (1 << 5),
+ LRT_TRIANGLE_FORCE_INTERSECTION = (1 << 6),
} eLineartTriangleFlags;
#define LRT_SHADOW_MASK_UNDEFINED 0
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
index f32141a31eb..c46b83ea052 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
@@ -31,7 +31,7 @@ static LineartEdge *lineart_line_get_connected(LineartBoundingArea *ba,
for (int i = 0; i < ba->line_count; i++) {
LineartEdge *n_e = ba->linked_lines[i];
- if ((!(n_e->flags & LRT_EDGE_FLAG_ALL_TYPE)) || (n_e->flags & LRT_EDGE_FLAG_CHAIN_PICKED)) {
+ if (!(n_e->flags & LRT_EDGE_FLAG_ALL_TYPE) || (n_e->flags & LRT_EDGE_FLAG_CHAIN_PICKED)) {
continue;
}
@@ -186,7 +186,7 @@ void MOD_lineart_chain_feature_lines(LineartData *ld)
LRT_ITER_ALL_LINES_BEGIN
{
- if ((!(e->flags & LRT_EDGE_FLAG_ALL_TYPE)) || (e->flags & LRT_EDGE_FLAG_CHAIN_PICKED)) {
+ if (!(e->flags & LRT_EDGE_FLAG_ALL_TYPE) || (e->flags & LRT_EDGE_FLAG_CHAIN_PICKED)) {
LRT_ITER_ALL_LINES_NEXT
continue;
}
@@ -809,8 +809,8 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartData *ld,
if (!ld->conf.fuzzy_everything) {
if (ld->conf.fuzzy_intersections) {
/* If none of those are intersection lines... */
- if ((!(cre->ec->type & LRT_EDGE_FLAG_INTERSECTION)) &&
- (!(ec->type & LRT_EDGE_FLAG_INTERSECTION))) {
+ if (!(cre->ec->type & LRT_EDGE_FLAG_INTERSECTION) &&
+ !(ec->type & LRT_EDGE_FLAG_INTERSECTION)) {
continue; /* We don't want to chain along different objects at the moment. */
}
}
@@ -1092,7 +1092,7 @@ void MOD_lineart_smooth_chains(LineartData *ld, float tolerance)
eci = next_eci) {
LineartEdgeChainItem *eci2, *eci3, *eci4;
- if ((!(eci2 = eci->next)) || (!(eci3 = eci2->next))) {
+ if (!(eci2 = eci->next) || !(eci3 = eci2->next)) {
/* Not enough points to simplify. */
next_eci = eci->next;
continue;
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpp_bridge.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpp_bridge.cc
index 5e741ccbd55..85f158d42e6 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpp_bridge.cc
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpp_bridge.cc
@@ -9,17 +9,15 @@
#include "MOD_lineart.h"
#include "lineart_intern.h"
-static bool cmp_adjacent_items(const LineartAdjacentEdge &p1, const LineartAdjacentEdge &p2)
-{
- int a = p1.v1 - p2.v1;
- int b = p1.v2 - p2.v2;
- /* parallel_sort() requires cmp() to return true when the first element needs to appear before
- * the second element in the sorted array, false otherwise (strict weak ordering), see
- * https://en.cppreference.com/w/cpp/named_req/Compare. */
- return a < 0 ? true : (a == 0 ? b < 0 : false);
-}
-
void lineart_sort_adjacent_items(LineartAdjacentEdge *ai, int length)
{
- blender::parallel_sort(ai, ai + length, cmp_adjacent_items);
+ blender::parallel_sort(
+ ai, ai + length, [](const LineartAdjacentEdge &p1, const LineartAdjacentEdge &p2) {
+ int a = p1.v1 - p2.v1;
+ int b = p1.v2 - p2.v2;
+ /* parallel_sort() requires cmp() to return true when the first element needs to appear
+ * before the second element in the sorted array, false otherwise (strict weak ordering),
+ * see https://en.cppreference.com/w/cpp/named_req/Compare. */
+ return a < 0 ? true : (a == 0 ? b < 0 : false);
+ });
}
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index c4a235d06bc..4b5c40c0e38 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -1397,7 +1397,7 @@ void lineart_main_discard_out_of_frame_edges(LineartData *ld)
LISTBASE_FOREACH (LineartElementLinkNode *, eln, &ld->geom.line_buffer_pointers) {
e = (LineartEdge *)eln->pointer;
for (i = 0; i < eln->element_count; i++) {
- if ((LRT_VERT_OUT_OF_BOUND(e[i].v1) && LRT_VERT_OUT_OF_BOUND(e[i].v2))) {
+ if (LRT_VERT_OUT_OF_BOUND(e[i].v1) && LRT_VERT_OUT_OF_BOUND(e[i].v2)) {
e[i].flags = LRT_EDGE_FLAG_CHAIN_PICKED;
}
}
@@ -1905,8 +1905,10 @@ static void lineart_load_tri_task(void *__restrict userdata,
if (ob_info->usage == OBJECT_LRT_INTERSECTION_ONLY) {
tri->flags |= LRT_TRIANGLE_INTERSECTION_ONLY;
}
- else if (ob_info->usage == OBJECT_LRT_NO_INTERSECTION ||
- ob_info->usage == OBJECT_LRT_OCCLUSION_ONLY) {
+ else if (ob_info->usage == OBJECT_LRT_FORCE_INTERSECTION) {
+ tri->flags |= LRT_TRIANGLE_FORCE_INTERSECTION;
+ }
+ else if (ELEM(ob_info->usage, OBJECT_LRT_NO_INTERSECTION, OBJECT_LRT_OCCLUSION_ONLY)) {
tri->flags |= LRT_TRIANGLE_NO_INTERSECTION;
}
@@ -1951,8 +1953,6 @@ static LineartEdgeNeighbor *lineart_build_edge_neighbor(Mesh *me, int total_edge
LineartEdgeNeighbor *edge_nabr = MEM_mallocN(sizeof(LineartEdgeNeighbor) * total_edges,
"LineartEdgeNeighbor arr");
- MLoopTri *mlooptri = me->runtime.looptris.array;
-
TaskParallelSettings en_settings;
BLI_parallel_range_settings_defaults(&en_settings);
/* Set the minimum amount of edges a thread has to process. */
@@ -1961,7 +1961,7 @@ static LineartEdgeNeighbor *lineart_build_edge_neighbor(Mesh *me, int total_edge
EdgeNeighborData en_data;
en_data.adj_e = adj_e;
en_data.edge_nabr = edge_nabr;
- en_data.mlooptri = mlooptri;
+ en_data.mlooptri = BKE_mesh_runtime_looptri_ensure(me);
en_data.mloop = BKE_mesh_loops(me);
BLI_task_parallel_range(0, total_edges, &en_data, lineart_edge_neighbor_init_task, &en_settings);
@@ -2251,8 +2251,11 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info,
}
}
- if (usage == OBJECT_LRT_INHERIT || usage == OBJECT_LRT_INCLUDE ||
- usage == OBJECT_LRT_NO_INTERSECTION) {
+ if (ELEM(usage,
+ OBJECT_LRT_INHERIT,
+ OBJECT_LRT_INCLUDE,
+ OBJECT_LRT_NO_INTERSECTION,
+ OBJECT_LRT_FORCE_INTERSECTION)) {
lineart_add_edge_to_array_thread(ob_info, la_edge);
}
@@ -2280,8 +2283,11 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info,
la_edge->object_ref = orig_ob;
la_edge->edge_identifier = LRT_EDGE_IDENTIFIER(ob_info, la_edge);
BLI_addtail(&la_edge->segments, la_seg);
- if (usage == OBJECT_LRT_INHERIT || usage == OBJECT_LRT_INCLUDE ||
- usage == OBJECT_LRT_NO_INTERSECTION) {
+ if (ELEM(usage,
+ OBJECT_LRT_INHERIT,
+ OBJECT_LRT_INCLUDE,
+ OBJECT_LRT_NO_INTERSECTION,
+ OBJECT_LRT_FORCE_INTERSECTION)) {
lineart_add_edge_to_array_thread(ob_info, la_edge);
if (shadow_eln) {
LineartEdge *shadow_e = lineart_find_matching_edge(shadow_eln, la_edge->edge_identifier);
@@ -2382,6 +2388,8 @@ static int lineart_usage_check(Collection *c, Object *ob, bool is_render)
return OBJECT_LRT_INTERSECTION_ONLY;
case COLLECTION_LRT_NO_INTERSECTION:
return OBJECT_LRT_NO_INTERSECTION;
+ case COLLECTION_LRT_FORCE_INTERSECTION:
+ return OBJECT_LRT_FORCE_INTERSECTION;
}
return OBJECT_LRT_INHERIT;
}
@@ -2597,9 +2605,13 @@ void lineart_main_load_geometries(Depsgraph *depsgraph,
flags |= DEG_ITER_OBJECT_FLAG_DUPLI;
}
+ DEGObjectIterSettings deg_iter_settings = {0};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = flags;
+
/* XXX(@Yiming): Temporary solution, this iterator is technically unsafe to use *during*
* depsgraph evaluation, see D14997 for detailed explanations. */
- DEG_OBJECT_ITER_BEGIN (depsgraph, ob, flags) {
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
obindex++;
@@ -2621,7 +2633,7 @@ void lineart_main_load_geometries(Depsgraph *depsgraph,
scene,
eval_ob,
eval_ob,
- eval_ob->obmat,
+ eval_ob->object_to_world,
is_render,
olti,
thread_count,
@@ -2877,7 +2889,7 @@ static bool lineart_triangle_edge_image_space_occlusion(const LineartTriangle *t
if ((e->flags & LRT_EDGE_FLAG_PROJECTED_SHADOW) &&
(e->target_reference == tri->target_reference)) {
if (((dot_f > 0) && (e->flags & LRT_EDGE_FLAG_SHADOW_FACING_LIGHT)) ||
- ((dot_f < 0) && (!(e->flags & LRT_EDGE_FLAG_SHADOW_FACING_LIGHT)))) {
+ ((dot_f < 0) && !(e->flags & LRT_EDGE_FLAG_SHADOW_FACING_LIGHT))) {
*from = 0.0f;
*to = 1.0f;
return true;
@@ -3203,8 +3215,7 @@ static bool lineart_triangle_2v_intersection_math(
return false;
}
- if (!(lineart_point_inside_triangle3d(
- gloc, tri->v[0]->gloc, tri->v[1]->gloc, tri->v[2]->gloc))) {
+ if (!lineart_point_inside_triangle3d(gloc, tri->v[0]->gloc, tri->v[1]->gloc, tri->v[2]->gloc)) {
return false;
}
@@ -3410,10 +3421,11 @@ static void lineart_triangle_intersect_in_bounding_area(LineartTriangle *tri,
}
tt->testing_e[th->thread_id] = (LineartEdge *)tri;
- if ((testing_triangle->flags & LRT_TRIANGLE_NO_INTERSECTION) ||
- ((testing_triangle->flags & LRT_TRIANGLE_INTERSECTION_ONLY) &&
- (tri->flags & LRT_TRIANGLE_INTERSECTION_ONLY))) {
- continue;
+ if (!((testing_triangle->flags | tri->flags) & LRT_TRIANGLE_FORCE_INTERSECTION)) {
+ if (((testing_triangle->flags | tri->flags) & LRT_TRIANGLE_NO_INTERSECTION) ||
+ (testing_triangle->flags & tri->flags & LRT_TRIANGLE_INTERSECTION_ONLY)) {
+ continue;
+ }
}
double *RG0 = testing_triangle->v[0]->gloc, *RG1 = testing_triangle->v[1]->gloc,
@@ -3577,11 +3589,11 @@ static LineartData *lineart_create_render_buffer(Scene *scene,
clipping_offset = 0.0001;
}
- copy_v3db_v3fl(ld->conf.camera_pos, camera->obmat[3]);
+ copy_v3db_v3fl(ld->conf.camera_pos, camera->object_to_world[3]);
if (active_camera) {
- copy_v3db_v3fl(ld->conf.active_camera_pos, active_camera->obmat[3]);
+ copy_v3db_v3fl(ld->conf.active_camera_pos, active_camera->object_to_world[3]);
}
- copy_m4_m4(ld->conf.cam_obmat, camera->obmat);
+ copy_m4_m4(ld->conf.cam_obmat, camera->object_to_world);
ld->conf.cam_is_persp = (c->type == CAM_PERSP);
ld->conf.near_clip = c->clip_start + clipping_offset;
@@ -3608,8 +3620,8 @@ static LineartData *lineart_create_render_buffer(Scene *scene,
if (lmd->light_contour_object) {
Object *light_obj = lmd->light_contour_object;
- copy_v3db_v3fl(ld->conf.camera_pos_secondary, light_obj->obmat[3]);
- copy_m4_m4(ld->conf.cam_obmat_secondary, light_obj->obmat);
+ copy_v3db_v3fl(ld->conf.camera_pos_secondary, light_obj->object_to_world[3]);
+ copy_m4_m4(ld->conf.cam_obmat_secondary, light_obj->object_to_world);
ld->conf.light_reference_available = true;
if (light_obj->type == OB_LAMP) {
ld->conf.cam_is_persp_secondary = ((Light *)light_obj->data)->type != LA_SUN;
@@ -4535,14 +4547,8 @@ static void lineart_add_triangles_worker(TaskPool *__restrict UNUSED(pool), Line
_dir_control++;
for (co = x1; co <= x2; co++) {
for (r = y1; r <= y2; r++) {
- lineart_bounding_area_link_triangle(ld,
- &ld->qtree.initials[r * ld->qtree.count_x + co],
- tri,
- 0,
- 1,
- 0,
- (!(tri->flags & LRT_TRIANGLE_NO_INTERSECTION)),
- th);
+ lineart_bounding_area_link_triangle(
+ ld, &ld->qtree.initials[r * ld->qtree.count_x + co], tri, 0, 1, 0, 1, th);
}
}
} /* Else throw away. */
@@ -5246,12 +5252,12 @@ static void lineart_gpencil_generate(LineartCache *cache,
if (shaodow_selection) {
if (ec->shadow_mask_bits != LRT_SHADOW_MASK_UNDEFINED) {
/* TODO(@Yiming): Give a behavior option for how to display undefined shadow info. */
- if ((shaodow_selection == LRT_SHADOW_FILTER_ILLUMINATED &&
- (!(ec->shadow_mask_bits & LRT_SHADOW_MASK_ILLUMINATED)))) {
+ if (shaodow_selection == LRT_SHADOW_FILTER_ILLUMINATED &&
+ !(ec->shadow_mask_bits & LRT_SHADOW_MASK_ILLUMINATED)) {
continue;
}
- if ((shaodow_selection == LRT_SHADOW_FILTER_SHADED &&
- (!(ec->shadow_mask_bits & LRT_SHADOW_MASK_SHADED)))) {
+ if (shaodow_selection == LRT_SHADOW_FILTER_SHADED &&
+ !(ec->shadow_mask_bits & LRT_SHADOW_MASK_SHADED)) {
continue;
}
if (shaodow_selection == LRT_SHADOW_FILTER_ILLUMINATED_ENCLOSED_SHAPES) {
@@ -5317,7 +5323,7 @@ static void lineart_gpencil_generate(LineartCache *cache,
if (source_vgname && vgname) {
Object *eval_ob = DEG_get_evaluated_object(depsgraph, ec->object_ref);
int gpdg = -1;
- if ((match_output || (gpdg = BKE_object_defgroup_name_index(gpencil_object, vgname)) >= 0)) {
+ if (match_output || (gpdg = BKE_object_defgroup_name_index(gpencil_object, vgname)) >= 0) {
if (eval_ob && eval_ob->type == OB_MESH) {
int dindex = 0;
Mesh *me = BKE_object_get_evaluated_mesh(eval_ob);
@@ -5412,7 +5418,7 @@ void MOD_lineart_gpencil_generate(LineartCache *cache,
}
float gp_obmat_inverse[4][4];
- invert_m4_m4(gp_obmat_inverse, ob->obmat);
+ invert_m4_m4(gp_obmat_inverse, ob->object_to_world);
lineart_gpencil_generate(cache,
depsgraph,
ob,
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c
index 138c016e2e2..6f44cc68a19 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c
@@ -102,12 +102,12 @@ static bool bake_strokes(Object *ob,
}
LineartCache *local_lc = *lc;
if (!(*lc)) {
- MOD_lineart_compute_feature_lines(dg, lmd, lc, (!(ob->dtx & OB_DRAW_IN_FRONT)));
+ MOD_lineart_compute_feature_lines(dg, lmd, lc, !(ob->dtx & OB_DRAW_IN_FRONT));
MOD_lineart_destroy_render_data(lmd);
}
else {
- if (is_first || (!(lmd->flags & LRT_GPENCIL_USE_CACHE))) {
- MOD_lineart_compute_feature_lines(dg, lmd, &local_lc, (!(ob->dtx & OB_DRAW_IN_FRONT)));
+ if (is_first || !(lmd->flags & LRT_GPENCIL_USE_CACHE)) {
+ MOD_lineart_compute_feature_lines(dg, lmd, &local_lc, !(ob->dtx & OB_DRAW_IN_FRONT));
MOD_lineart_destroy_render_data(lmd);
}
MOD_lineart_chain_clear_picked_flag(local_lc);
@@ -154,7 +154,7 @@ static bool bake_strokes(Object *ob,
typedef struct LineartBakeJob {
wmWindowManager *wm;
void *owner;
- short *stop, *do_update;
+ bool *stop, *do_update;
float *progress;
/* C or ob must have one != NULL. */
@@ -218,8 +218,8 @@ static void lineart_gpencil_guard_modifiers(LineartBakeJob *bj)
}
static void lineart_gpencil_bake_startjob(void *customdata,
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress)
{
LineartBakeJob *bj = (LineartBakeJob *)customdata;
@@ -337,7 +337,7 @@ static int lineart_gpencil_bake_common(bContext *C,
}
float pseduo_progress;
- short pseduo_do_update;
+ bool pseduo_do_update;
lineart_gpencil_bake_startjob(bj, NULL, &pseduo_do_update, &pseduo_progress);
BLI_linklist_free(bj->objects, NULL);
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c
index 257184bae1e..edea052e728 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c
@@ -108,8 +108,8 @@ void lineart_register_shadow_cuts(LineartData *ld, LineartEdge *e, LineartEdge *
(e->v1->fbcoord[3] - la1 * (e->v1->fbcoord[3] - e->v2->fbcoord[3]));
la2 = la2 * e->v2->fbcoord[3] /
(e->v1->fbcoord[3] - la2 * (e->v1->fbcoord[3] - e->v2->fbcoord[3]));
- unsigned char shadow_bits = (es->occlusion != 0) ? LRT_SHADOW_MASK_SHADED :
- LRT_SHADOW_MASK_ILLUMINATED;
+ uchar shadow_bits = (es->occlusion != 0) ? LRT_SHADOW_MASK_SHADED :
+ LRT_SHADOW_MASK_ILLUMINATED;
if (lineart_contour_viewed_from_dark_side(ld, e) &&
shadow_bits == LRT_SHADOW_MASK_ILLUMINATED) {
@@ -1167,7 +1167,7 @@ bool lineart_main_try_generate_shadow(Depsgraph *depsgraph,
copy_v3_v3_db(ld->conf.camera_pos_secondary, ld->conf.camera_pos);
copy_m4_m4(ld->conf.cam_obmat_secondary, ld->conf.cam_obmat);
- copy_m4_m4(ld->conf.cam_obmat, lmd->light_contour_object->obmat);
+ copy_m4_m4(ld->conf.cam_obmat, lmd->light_contour_object->object_to_world);
copy_v3db_v3fl(ld->conf.camera_pos, ld->conf.cam_obmat[3]);
ld->conf.cam_is_persp_secondary = ld->conf.cam_is_persp;
ld->conf.cam_is_persp = is_persp;
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_util.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_util.c
index 95647f2dd75..a2e724d9ebe 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_util.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_util.c
@@ -110,7 +110,7 @@ void *lineart_mem_acquire(LineartStaticMemPool *smp, size_t size)
smpn = lineart_mem_new_static_pool(smp, size);
}
- ret = ((unsigned char *)smpn) + smpn->used_byte;
+ ret = ((uchar *)smpn) + smpn->used_byte;
smpn->used_byte += size;
@@ -128,7 +128,7 @@ void *lineart_mem_acquire_thread(LineartStaticMemPool *smp, size_t size)
smpn = lineart_mem_new_static_pool(smp, size);
}
- ret = ((unsigned char *)smpn) + smpn->used_byte;
+ ret = ((uchar *)smpn) + smpn->used_byte;
smpn->used_byte += size;
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 8b38c22ae28..8da17720339 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -12,6 +12,7 @@ endif()
set(INC
.
intern
+ vulkan
metal
opengl
../blenkernel
@@ -26,6 +27,7 @@ set(INC
../editors/include
# For *_info.hh includes.
+ ../compositor/realtime_compositor
../draw/engines/eevee_next
../draw/intern
@@ -47,7 +49,6 @@ set(SRC
intern/gpu_batch.cc
intern/gpu_batch_presets.c
intern/gpu_batch_utils.c
- intern/gpu_buffers.c
intern/gpu_capabilities.cc
intern/gpu_codegen.cc
intern/gpu_compute.cc
@@ -84,7 +85,6 @@ set(SRC
GPU_batch.h
GPU_batch_presets.h
GPU_batch_utils.h
- GPU_buffers.h
GPU_capabilities.h
GPU_common.h
GPU_common_types.h
@@ -186,12 +186,43 @@ set(OPENGL_SRC
opengl/gl_vertex_buffer.hh
)
+set(VULKAN_SRC
+ vulkan/vk_backend.cc
+ vulkan/vk_batch.cc
+ vulkan/vk_context.cc
+ vulkan/vk_drawlist.cc
+ vulkan/vk_framebuffer.cc
+ vulkan/vk_index_buffer.cc
+ vulkan/vk_query.cc
+ vulkan/vk_shader.cc
+ vulkan/vk_storage_buffer.cc
+ vulkan/vk_texture.cc
+ vulkan/vk_uniform_buffer.cc
+ vulkan/vk_vertex_buffer.cc
+
+ vulkan/vk_backend.hh
+ vulkan/vk_batch.hh
+ vulkan/vk_context.hh
+ vulkan/vk_drawlist.hh
+ vulkan/vk_framebuffer.hh
+ vulkan/vk_index_buffer.hh
+ vulkan/vk_query.hh
+ vulkan/vk_shader.hh
+ vulkan/vk_storage_buffer.hh
+ vulkan/vk_texture.hh
+ vulkan/vk_uniform_buffer.hh
+ vulkan/vk_vertex_buffer.hh
+)
+
set(METAL_SRC
metal/mtl_backend.mm
+ metal/mtl_batch.mm
metal/mtl_command_buffer.mm
metal/mtl_context.mm
metal/mtl_debug.mm
+ metal/mtl_drawlist.mm
metal/mtl_framebuffer.mm
+ metal/mtl_immediate.mm
metal/mtl_index_buffer.mm
metal/mtl_memory.mm
metal/mtl_query.mm
@@ -202,13 +233,17 @@ set(METAL_SRC
metal/mtl_texture.mm
metal/mtl_texture_util.mm
metal/mtl_uniform_buffer.mm
+ metal/mtl_vertex_buffer.mm
metal/mtl_backend.hh
+ metal/mtl_batch.hh
metal/mtl_capabilities.hh
metal/mtl_common.hh
metal/mtl_context.hh
metal/mtl_debug.hh
+ metal/mtl_drawlist.hh
metal/mtl_framebuffer.hh
+ metal/mtl_immediate.hh
metal/mtl_index_buffer.hh
metal/mtl_memory.hh
metal/mtl_primitive.hh
@@ -222,6 +257,7 @@ set(METAL_SRC
metal/mtl_state.hh
metal/mtl_texture.hh
metal/mtl_uniform_buffer.hh
+ metal/mtl_vertex_buffer.hh
)
# Select Backend source based on availability
@@ -229,6 +265,10 @@ if(WITH_OPENGL)
list(APPEND SRC ${OPENGL_SRC})
endif()
+if(WITH_VULKAN_BACKEND)
+ list(APPEND SRC ${VULKAN_SRC})
+endif()
+
if(WITH_METAL_BACKEND)
list(APPEND SRC ${METAL_SRC})
endif()
@@ -276,6 +316,8 @@ set(GLSL_SRC
shaders/gpu_shader_2D_image_vert.glsl
shaders/gpu_shader_2D_image_rect_vert.glsl
shaders/gpu_shader_2D_image_multi_rect_vert.glsl
+ shaders/gpu_shader_icon_frag.glsl
+ shaders/gpu_shader_icon_vert.glsl
shaders/gpu_shader_image_frag.glsl
shaders/gpu_shader_image_desaturate_frag.glsl
shaders/gpu_shader_image_overlays_merge_frag.glsl
@@ -291,6 +333,7 @@ set(GLSL_SRC
shaders/gpu_shader_3D_polyline_frag.glsl
shaders/gpu_shader_3D_polyline_geom.glsl
shaders/gpu_shader_3D_polyline_vert.glsl
+ shaders/gpu_shader_3D_polyline_vert_no_geom.glsl
shaders/gpu_shader_3D_smooth_color_vert.glsl
shaders/gpu_shader_3D_smooth_color_frag.glsl
shaders/gpu_shader_3D_passthrough_vert.glsl
@@ -324,59 +367,6 @@ set(GLSL_SRC
shaders/common/gpu_shader_common_math_utils.glsl
shaders/common/gpu_shader_common_mix_rgb.glsl
- shaders/compositor/compositor_alpha_crop.glsl
- shaders/compositor/compositor_bilateral_blur.glsl
- shaders/compositor/compositor_blur.glsl
- shaders/compositor/compositor_bokeh_image.glsl
- shaders/compositor/compositor_box_mask.glsl
- shaders/compositor/compositor_convert.glsl
- shaders/compositor/compositor_despeckle.glsl
- shaders/compositor/compositor_directional_blur.glsl
- shaders/compositor/compositor_edge_filter.glsl
- shaders/compositor/compositor_ellipse_mask.glsl
- shaders/compositor/compositor_filter.glsl
- shaders/compositor/compositor_flip.glsl
- shaders/compositor/compositor_image_crop.glsl
- shaders/compositor/compositor_morphological_distance.glsl
- shaders/compositor/compositor_morphological_distance_feather.glsl
- shaders/compositor/compositor_morphological_distance_threshold.glsl
- shaders/compositor/compositor_morphological_step.glsl
- shaders/compositor/compositor_projector_lens_distortion.glsl
- shaders/compositor/compositor_realize_on_domain.glsl
- shaders/compositor/compositor_screen_lens_distortion.glsl
- shaders/compositor/compositor_set_alpha.glsl
- shaders/compositor/compositor_split_viewer.glsl
- shaders/compositor/compositor_symmetric_blur.glsl
- shaders/compositor/compositor_symmetric_separable_blur.glsl
-
- shaders/compositor/library/gpu_shader_compositor_alpha_over.glsl
- shaders/compositor/library/gpu_shader_compositor_blur_common.glsl
- shaders/compositor/library/gpu_shader_compositor_bright_contrast.glsl
- shaders/compositor/library/gpu_shader_compositor_channel_matte.glsl
- shaders/compositor/library/gpu_shader_compositor_chroma_matte.glsl
- shaders/compositor/library/gpu_shader_compositor_color_balance.glsl
- shaders/compositor/library/gpu_shader_compositor_color_correction.glsl
- shaders/compositor/library/gpu_shader_compositor_color_matte.glsl
- shaders/compositor/library/gpu_shader_compositor_color_spill.glsl
- shaders/compositor/library/gpu_shader_compositor_color_to_luminance.glsl
- shaders/compositor/library/gpu_shader_compositor_difference_matte.glsl
- shaders/compositor/library/gpu_shader_compositor_distance_matte.glsl
- shaders/compositor/library/gpu_shader_compositor_exposure.glsl
- shaders/compositor/library/gpu_shader_compositor_gamma.glsl
- shaders/compositor/library/gpu_shader_compositor_hue_correct.glsl
- shaders/compositor/library/gpu_shader_compositor_hue_saturation_value.glsl
- shaders/compositor/library/gpu_shader_compositor_invert.glsl
- shaders/compositor/library/gpu_shader_compositor_luminance_matte.glsl
- shaders/compositor/library/gpu_shader_compositor_main.glsl
- shaders/compositor/library/gpu_shader_compositor_map_value.glsl
- shaders/compositor/library/gpu_shader_compositor_normal.glsl
- shaders/compositor/library/gpu_shader_compositor_posterize.glsl
- shaders/compositor/library/gpu_shader_compositor_separate_combine.glsl
- shaders/compositor/library/gpu_shader_compositor_set_alpha.glsl
- shaders/compositor/library/gpu_shader_compositor_store_output.glsl
- shaders/compositor/library/gpu_shader_compositor_texture_utilities.glsl
- shaders/compositor/library/gpu_shader_compositor_type_conversion.glsl
-
shaders/material/gpu_shader_material_add_shader.glsl
shaders/material/gpu_shader_material_ambient_occlusion.glsl
shaders/material/gpu_shader_material_anisotropic.glsl
@@ -552,6 +542,7 @@ set(SRC_SHADER_CREATE_INFOS
../draw/engines/overlay/shaders/infos/overlay_paint_info.hh
../draw/engines/overlay/shaders/infos/overlay_sculpt_curves_info.hh
../draw/engines/overlay/shaders/infos/overlay_sculpt_info.hh
+ ../draw/engines/overlay/shaders/infos/overlay_viewer_attribute_info.hh
../draw/engines/overlay/shaders/infos/overlay_volume_info.hh
../draw/engines/overlay/shaders/infos/overlay_wireframe_info.hh
../draw/engines/select/shaders/infos/select_id_info.hh
@@ -596,37 +587,13 @@ set(SRC_SHADER_CREATE_INFOS
shaders/infos/gpu_shader_3D_smooth_color_info.hh
shaders/infos/gpu_shader_3D_uniform_color_info.hh
shaders/infos/gpu_shader_gpencil_stroke_info.hh
+ shaders/infos/gpu_shader_icon_info.hh
shaders/infos/gpu_shader_instance_varying_color_varying_size_info.hh
shaders/infos/gpu_shader_keyframe_shape_info.hh
shaders/infos/gpu_shader_line_dashed_uniform_color_info.hh
shaders/infos/gpu_shader_simple_lighting_info.hh
shaders/infos/gpu_shader_text_info.hh
shaders/infos/gpu_srgb_to_framebuffer_space_info.hh
-
- shaders/compositor/infos/compositor_alpha_crop_info.hh
- shaders/compositor/infos/compositor_bilateral_blur_info.hh
- shaders/compositor/infos/compositor_blur_info.hh
- shaders/compositor/infos/compositor_bokeh_image_info.hh
- shaders/compositor/infos/compositor_box_mask_info.hh
- shaders/compositor/infos/compositor_convert_info.hh
- shaders/compositor/infos/compositor_despeckle_info.hh
- shaders/compositor/infos/compositor_directional_blur_info.hh
- shaders/compositor/infos/compositor_edge_filter_info.hh
- shaders/compositor/infos/compositor_ellipse_mask_info.hh
- shaders/compositor/infos/compositor_filter_info.hh
- shaders/compositor/infos/compositor_flip_info.hh
- shaders/compositor/infos/compositor_image_crop_info.hh
- shaders/compositor/infos/compositor_morphological_distance_feather_info.hh
- shaders/compositor/infos/compositor_morphological_distance_info.hh
- shaders/compositor/infos/compositor_morphological_distance_threshold_info.hh
- shaders/compositor/infos/compositor_morphological_step_info.hh
- shaders/compositor/infos/compositor_projector_lens_distortion_info.hh
- shaders/compositor/infos/compositor_realize_on_domain_info.hh
- shaders/compositor/infos/compositor_screen_lens_distortion_info.hh
- shaders/compositor/infos/compositor_set_alpha_info.hh
- shaders/compositor/infos/compositor_split_viewer_info.hh
- shaders/compositor/infos/compositor_symmetric_blur_info.hh
- shaders/compositor/infos/compositor_symmetric_separable_blur_info.hh
)
set(SRC_SHADER_CREATE_INFOS_MTL
@@ -661,6 +628,7 @@ endif()
blender_add_lib(bf_gpu "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
target_link_libraries(bf_gpu PUBLIC
+ bf_compositor_shaders
bf_draw_shaders
bf_gpu_shaders
)
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
deleted file mode 100644
index 5cdc5f19540..00000000000
--- a/source/blender/gpu/GPU_buffers.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later
- * Copyright 2005 Blender Foundation. All rights reserved. */
-
-/** \file
- * \ingroup gpu
- */
-
-#pragma once
-
-#include <stddef.h>
-
-#include "BKE_attribute.h"
-#include "BKE_pbvh.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct BMesh;
-struct CCGElem;
-struct CCGKey;
-struct DMFlagMat;
-struct GSet;
-struct TableGSet;
-struct Mesh;
-struct MLoop;
-struct MLoopCol;
-struct MLoopTri;
-struct MPoly;
-struct MPropCol;
-struct MVert;
-struct Mesh;
-struct PBVH;
-struct SubdivCCG;
-struct CustomData;
-
-typedef struct PBVHGPUFormat PBVHGPUFormat;
-
-/**
- * Buffers for drawing from PBVH grids.
- */
-typedef struct GPU_PBVH_Buffers GPU_PBVH_Buffers;
-
-/**
- * Build must be called once before using the other functions,
- * used every time mesh topology changes.
- *
- * Threaded: do not call any functions that use OpenGL calls!
- */
-GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const struct Mesh *mesh,
- const struct MLoopTri *looptri,
- const int *face_indices,
- int face_indices_len);
-
-/**
- * Threaded: do not call any functions that use OpenGL calls!
- */
-GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(int totgrid,
- unsigned int **grid_hidden,
- bool smooth);
-
-/**
- * Threaded: do not call any functions that use OpenGL calls!
- */
-GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading);
-
-/**
- * Free part of data for update. Not thread safe, must run in OpenGL main thread.
- */
-void GPU_pbvh_bmesh_buffers_update_free(GPU_PBVH_Buffers *buffers);
-void GPU_pbvh_grid_buffers_update_free(GPU_PBVH_Buffers *buffers,
- const struct DMFlagMat *grid_flag_mats,
- const int *grid_indices);
-
-/**
- * Update mesh buffers without topology changes. Threaded.
- */
-enum {
- GPU_PBVH_BUFFERS_SHOW_MASK = (1 << 1),
- GPU_PBVH_BUFFERS_SHOW_VCOL = (1 << 2),
- GPU_PBVH_BUFFERS_SHOW_SCULPT_FACE_SETS = (1 << 3),
-};
-
-/**
- * Creates a vertex buffer (coordinate, normal, color) and,
- * if smooth shading, an element index buffer.
- * Threaded: do not call any functions that use OpenGL calls!
- */
-void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
- GPU_PBVH_Buffers *buffers,
- const struct Mesh *mesh,
- const struct MVert *mvert,
- const float *vmask,
- const int *sculpt_face_sets,
- const int face_sets_color_seed,
- const int face_sets_color_default,
- const int update_flags,
- const float (*vert_normals)[3]);
-
-bool GPU_pbvh_attribute_names_update(PBVHType pbvh_type,
- PBVHGPUFormat *vbo_id,
- const struct CustomData *vdata,
- const struct CustomData *ldata,
- bool active_attrs_only);
-
-/**
- * Creates a vertex buffer (coordinate, normal, color) and,
- * if smooth shading, an element index buffer.
- * Threaded: do not call any functions that use OpenGL calls!
- */
-void GPU_pbvh_bmesh_buffers_update(PBVHGPUFormat *vbo_id,
- struct GPU_PBVH_Buffers *buffers,
- struct BMesh *bm,
- struct GSet *bm_faces,
- struct GSet *bm_unique_verts,
- struct GSet *bm_other_verts,
- const int update_flags);
-
-/**
- * Threaded: do not call any functions that use OpenGL calls!
- */
-void GPU_pbvh_grid_buffers_update(PBVHGPUFormat *vbo_id,
- GPU_PBVH_Buffers *buffers,
- struct SubdivCCG *subdiv_ccg,
- struct CCGElem **grids,
- const struct DMFlagMat *grid_flag_mats,
- int *grid_indices,
- int totgrid,
- const int *sculpt_face_sets,
- int face_sets_color_seed,
- int face_sets_color_default,
- const struct CCGKey *key,
- int update_flags);
-
-/**
- * Finish update. Not thread safe, must run in OpenGL main
- * thread.
- */
-void GPU_pbvh_buffers_update_flush(GPU_PBVH_Buffers *buffers);
-
-/**
- * Free buffers. Not thread safe, must run in OpenGL main thread.
- */
-void GPU_pbvh_buffers_free(GPU_PBVH_Buffers *buffers);
-
-/** Draw. */
-struct GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast, bool wires);
-
-short GPU_pbvh_buffers_material_index_get(GPU_PBVH_Buffers *buffers);
-bool GPU_pbvh_buffers_has_overlays(GPU_PBVH_Buffers *buffers);
-
-PBVHGPUFormat *GPU_pbvh_make_format(void);
-void GPU_pbvh_free_format(PBVHGPUFormat *vbo_id);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/source/blender/gpu/GPU_context.h b/source/blender/gpu/GPU_context.h
index a242bb7cc94..ac82774039a 100644
--- a/source/blender/gpu/GPU_context.h
+++ b/source/blender/gpu/GPU_context.h
@@ -21,12 +21,14 @@ extern "C" {
* automatically initializes the back-end, and #GPU_context_discard frees it when there
* are no more contexts. */
bool GPU_backend_supported(void);
+void GPU_backend_type_selection_set(const eGPUBackendType backend);
+eGPUBackendType GPU_backend_type_selection_get(void);
eGPUBackendType GPU_backend_get_type(void);
/** Opaque type hiding blender::gpu::Context. */
typedef struct GPUContext GPUContext;
-GPUContext *GPU_context_create(void *ghost_window);
+GPUContext *GPU_context_create(void *ghost_window, void *ghost_context);
/**
* To be called after #GPU_context_active_set(ctx_to_destroy).
*/
diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h
index 70ec7c19e7c..917407eece3 100644
--- a/source/blender/gpu/GPU_framebuffer.h
+++ b/source/blender/gpu/GPU_framebuffer.h
@@ -47,6 +47,9 @@ typedef struct GPUOffScreen GPUOffScreen;
GPUFrameBuffer *GPU_framebuffer_create(const char *name);
void GPU_framebuffer_free(GPUFrameBuffer *fb);
void GPU_framebuffer_bind(GPUFrameBuffer *fb);
+
+const char *GPU_framebuffer_get_name(GPUFrameBuffer *fb);
+
/**
* Workaround for binding a SRGB frame-buffer without doing the SRGB transform.
*/
@@ -189,6 +192,12 @@ void GPU_framebuffer_texture_layer_attach(
void GPU_framebuffer_texture_cubeface_attach(
GPUFrameBuffer *fb, GPUTexture *tex, int slot, int face, int mip);
+/**
+ * Default size is used if the framebuffer contains no attachments.
+ * It needs to be re-specified each time an attachment is added.
+ */
+void GPU_framebuffer_default_size(GPUFrameBuffer *gpu_fb, int width, int height);
+
/* Frame-buffer operations. */
/**
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 023221543ec..3dad2a1a19a 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -117,6 +117,15 @@ typedef enum eGPUMaterialStatus {
GPU_MAT_SUCCESS,
} eGPUMaterialStatus;
+/* GPU_MAT_OPTIMIZATION_SKIP for cases where we do not
+ * plan to perform optimization on a given material. */
+typedef enum eGPUMaterialOptimizationStatus {
+ GPU_MAT_OPTIMIZATION_SKIP = 0,
+ GPU_MAT_OPTIMIZATION_READY,
+ GPU_MAT_OPTIMIZATION_QUEUED,
+ GPU_MAT_OPTIMIZATION_SUCCESS,
+} eGPUMaterialOptimizationStatus;
+
typedef enum eGPUDefaultValue {
GPU_DEFAULT_0 = 0,
GPU_DEFAULT_1,
@@ -153,6 +162,7 @@ GPUNodeLink *GPU_uniform_attribute(GPUMaterial *mat,
const char *name,
bool use_dupli,
uint32_t *r_hash);
+GPUNodeLink *GPU_layer_attribute(GPUMaterial *mat, const char *name);
GPUNodeLink *GPU_image(GPUMaterial *mat,
struct Image *ima,
struct ImageUser *iuser,
@@ -162,6 +172,12 @@ GPUNodeLink *GPU_image_tiled(GPUMaterial *mat,
struct ImageUser *iuser,
eGPUSamplerState sampler_state);
GPUNodeLink *GPU_image_tiled_mapping(GPUMaterial *mat, struct Image *ima, struct ImageUser *iuser);
+GPUNodeLink *GPU_image_sky(GPUMaterial *mat,
+ int width,
+ int height,
+ const float *pixels,
+ float *layer,
+ eGPUSamplerState sampler_state);
GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *row);
/**
@@ -240,6 +256,7 @@ struct Scene *GPU_material_scene(GPUMaterial *material);
struct GPUPass *GPU_material_get_pass(GPUMaterial *material);
struct GPUShader *GPU_material_get_shader(GPUMaterial *material);
const char *GPU_material_get_name(GPUMaterial *material);
+
/**
* Return can be NULL if it's a world material.
*/
@@ -250,6 +267,13 @@ struct Material *GPU_material_get_material(GPUMaterial *material);
eGPUMaterialStatus GPU_material_status(GPUMaterial *mat);
void GPU_material_status_set(GPUMaterial *mat, eGPUMaterialStatus status);
+/**
+ * Return status for async optimization jobs.
+ */
+eGPUMaterialOptimizationStatus GPU_material_optimization_status(GPUMaterial *mat);
+void GPU_material_optimization_status_set(GPUMaterial *mat, eGPUMaterialOptimizationStatus status);
+bool GPU_material_optimization_ready(GPUMaterial *mat);
+
struct GPUUniformBuf *GPU_material_uniform_buffer_get(GPUMaterial *material);
/**
* Create dynamic UBO from parameters
@@ -297,6 +321,7 @@ typedef struct GPUMaterialTexture {
struct ImageUser iuser;
bool iuser_available;
struct GPUTexture **colorband;
+ struct GPUTexture **sky;
char sampler_name[32]; /* Name of sampler in GLSL. */
char tiled_mapping_name[32]; /* Name of tile mapping sampler in GLSL. */
int users;
@@ -311,8 +336,6 @@ typedef struct GPUUniformAttr {
/* Meaningful part of the attribute set key. */
char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */
- /** Escaped name with [""]. */
- char name_id_prop[64 * 2 + 4];
/** Hash of name[64] + use_dupli. */
uint32_t hash_code;
bool use_dupli;
@@ -335,6 +358,20 @@ struct GHash *GPU_uniform_attr_list_hash_new(const char *info);
void GPU_uniform_attr_list_copy(GPUUniformAttrList *dest, const GPUUniformAttrList *src);
void GPU_uniform_attr_list_free(GPUUniformAttrList *set);
+typedef struct GPULayerAttr {
+ struct GPULayerAttr *next, *prev;
+
+ /* Meaningful part of the attribute set key. */
+ char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */
+ /** Hash of name[64]. */
+ uint32_t hash_code;
+
+ /* Helper fields used by code generation. */
+ int users;
+} GPULayerAttr;
+
+const ListBase *GPU_material_layer_attributes(const GPUMaterial *material);
+
/* A callback passed to GPU_material_from_callbacks to construct the material graph by adding and
* linking the necessary GPU material nodes. */
typedef void (*ConstructGPUMaterialFn)(void *thunk, GPUMaterial *material);
diff --git a/source/blender/gpu/GPU_platform.h b/source/blender/gpu/GPU_platform.h
index b63fe4c0580..657b45df1a5 100644
--- a/source/blender/gpu/GPU_platform.h
+++ b/source/blender/gpu/GPU_platform.h
@@ -16,6 +16,7 @@ typedef enum eGPUBackendType {
GPU_BACKEND_NONE = 0,
GPU_BACKEND_OPENGL = 1 << 0,
GPU_BACKEND_METAL = 1 << 1,
+ GPU_BACKEND_VULKAN = 1 << 3,
GPU_BACKEND_ANY = 0xFFFFFFFFu
} eGPUBackendType;
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index c1b3b879c34..1148207fc57 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -64,7 +64,8 @@ struct GPU_ShaderCreateFromArray_Params {
/**
* Use via #GPU_shader_create_from_arrays macro (avoids passing in param).
*
- * Similar to #DRW_shader_create_with_lib with the ability to include libs for each type of shader.
+ * Similar to #DRW_shader_create_with_lib with the ability to include libraries for each type of
+ * shader.
*
* It has the advantage that each item can be conditionally included
* without having to build the string inline, then free it.
@@ -144,6 +145,7 @@ typedef enum {
GPU_UNIFORM_BLOCK_DRW_VIEW,
GPU_UNIFORM_BLOCK_DRW_MODEL,
GPU_UNIFORM_BLOCK_DRW_INFOS,
+ GPU_UNIFORM_BLOCK_DRW_CLIPPING,
GPU_NUM_UNIFORM_BLOCKS, /* Special value, denotes number of builtin uniforms block. */
} GPUUniformBlockBuiltin;
@@ -207,6 +209,10 @@ typedef enum eGPUBuiltinShader {
GPU_SHADER_KEYFRAME_SHAPE,
GPU_SHADER_SIMPLE_LIGHTING,
/**
+ * Draw an icon, leaving a semi-transparent rectangle on top of the icon.
+ */
+ GPU_SHADER_ICON,
+ /**
* Take a 2D position and color for each vertex with linear interpolation in window space.
*
* \param color: in vec4
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 8b54f4c9822..e91d4703014 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -257,6 +257,15 @@ GPUTexture *GPU_texture_create_view(const char *name,
int layer_len,
bool cube_as_array);
+GPUTexture *GPU_texture_create_single_layer_view(const char *name, const GPUTexture *src);
+
+/**
+ * Create an alias of the source texture as a texture array with only one layer.
+ * Works for 1D, 2D and cube-map source texture.
+ * If \a src is freed, the texture view will continue to be valid.
+ */
+GPUTexture *GPU_texture_create_single_layer_array_view(const char *name, const GPUTexture *src);
+
void GPU_texture_update_mipmap(GPUTexture *tex,
int miplvl,
eGPUDataFormat gpu_data_format,
diff --git a/source/blender/gpu/GPU_uniform_buffer.h b/source/blender/gpu/GPU_uniform_buffer.h
index f78719d1963..28f06d6071d 100644
--- a/source/blender/gpu/GPU_uniform_buffer.h
+++ b/source/blender/gpu/GPU_uniform_buffer.h
@@ -44,6 +44,7 @@ void GPU_uniformbuf_unbind_all(void);
#define GPU_UBO_BLOCK_NAME "node_tree"
#define GPU_ATTRIBUTE_UBO_BLOCK_NAME "unf_attrs"
+#define GPU_LAYER_ATTRIBUTE_UBO_BLOCK_NAME "drw_layer_attrs"
#ifdef __cplusplus
}
diff --git a/source/blender/gpu/intern/gpu_backend.hh b/source/blender/gpu/intern/gpu_backend.hh
index d2890efee72..2a545c8114e 100644
--- a/source/blender/gpu/intern/gpu_backend.hh
+++ b/source/blender/gpu/intern/gpu_backend.hh
@@ -38,7 +38,7 @@ class GPUBackend {
virtual void compute_dispatch(int groups_x_len, int groups_y_len, int groups_z_len) = 0;
virtual void compute_dispatch_indirect(StorageBuf *indirect_buf) = 0;
- virtual Context *context_alloc(void *ghost_window) = 0;
+ virtual Context *context_alloc(void *ghost_window, void *ghost_context) = 0;
virtual Batch *batch_alloc() = 0;
virtual DrawList *drawlist_alloc(int list_length) = 0;
diff --git a/source/blender/gpu/intern/gpu_batch.cc b/source/blender/gpu/intern/gpu_batch.cc
index c871004deac..e1876f6d8ac 100644
--- a/source/blender/gpu/intern/gpu_batch.cc
+++ b/source/blender/gpu/intern/gpu_batch.cc
@@ -56,7 +56,6 @@ void GPU_batch_init_ex(GPUBatch *batch,
GPUIndexBuf *elem,
eGPUBatchFlag owns_flag)
{
- BLI_assert(verts != nullptr);
/* Do not pass any other flag */
BLI_assert((owns_flag & ~(GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX)) == 0);
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
deleted file mode 100644
index 78f595cbff2..00000000000
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ /dev/null
@@ -1,1475 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later
- * Copyright 2005 Blender Foundation. All rights reserved. */
-
-/** \file
- * \ingroup gpu
- *
- * Mesh drawing using OpenGL VBO (Vertex Buffer Objects)
- */
-
-#include <limits.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_bitmap.h"
-#include "BLI_ghash.h"
-#include "BLI_math_color.h"
-#include "BLI_utildefines.h"
-
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-
-#include "BKE_DerivedMesh.h"
-#include "BKE_attribute.h"
-#include "BKE_ccg.h"
-#include "BKE_customdata.h"
-#include "BKE_mesh.h"
-#include "BKE_paint.h"
-#include "BKE_pbvh.h"
-#include "BKE_subdiv_ccg.h"
-
-#include "GPU_batch.h"
-#include "GPU_buffers.h"
-
-#include "DRW_engine.h"
-
-#include "gpu_private.h"
-
-#include "bmesh.h"
-
-struct GPU_PBVH_Buffers {
- GPUIndexBuf *index_buf, *index_buf_fast;
- GPUIndexBuf *index_lines_buf, *index_lines_buf_fast;
- GPUVertBuf *vert_buf;
-
- GPUBatch *lines;
- GPUBatch *lines_fast;
- GPUBatch *triangles;
- GPUBatch *triangles_fast;
-
- /* mesh pointers in case buffer allocation fails */
- const MPoly *mpoly;
- const MLoop *mloop;
- const MLoopTri *looptri;
- const MVert *mvert;
-
- const int *face_indices;
- int face_indices_len;
-
- /* grid pointers */
- CCGKey gridkey;
- CCGElem **grids;
- const DMFlagMat *grid_flag_mats;
- BLI_bitmap *const *grid_hidden;
- const int *grid_indices;
- int totgrid;
-
- bool use_bmesh;
- bool clear_bmesh_on_flush;
-
- uint tot_tri, tot_quad;
-
- short material_index;
-
- /* The PBVH ensures that either all faces in the node are
- * smooth-shaded or all faces are flat-shaded */
- bool smooth;
-
- bool show_overlay;
-};
-
-typedef struct GPUAttrRef {
- uchar domain, type;
- ushort cd_offset;
- int layer_idx;
-} GPUAttrRef;
-
-#define MAX_GPU_ATTR 256
-
-typedef struct PBVHGPUFormat {
- GPUVertFormat format;
- uint pos, nor, msk, fset;
- uint col[MAX_GPU_ATTR];
- uint uv[MAX_GPU_ATTR];
- int totcol, totuv;
-
- /* Upload only the active color and UV attributes,
- * used for workbench mode. */
- bool active_attrs_only;
-} PBVHGPUFormat;
-
-PBVHGPUFormat *GPU_pbvh_make_format(void)
-{
- PBVHGPUFormat *vbo_id = MEM_callocN(sizeof(PBVHGPUFormat), "PBVHGPUFormat");
-
- GPU_pbvh_attribute_names_update(PBVH_FACES, vbo_id, NULL, NULL, false);
-
- return vbo_id;
-}
-
-void GPU_pbvh_free_format(PBVHGPUFormat *vbo_id)
-{
- MEM_SAFE_FREE(vbo_id);
-}
-
-static int gpu_pbvh_make_attr_offs(eAttrDomainMask domain_mask,
- eCustomDataMask type_mask,
- const CustomData *vdata,
- const CustomData *edata,
- const CustomData *ldata,
- const CustomData *pdata,
- GPUAttrRef r_cd_attrs[MAX_GPU_ATTR],
- bool active_only,
- int active_type,
- int active_domain,
- const CustomDataLayer *active_layer,
- const CustomDataLayer *render_layer);
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name PBVH Utils
- * \{ */
-
-void gpu_pbvh_init()
-{
-}
-
-void gpu_pbvh_exit()
-{
- /* Nothing to do. */
-}
-
-static CustomDataLayer *get_active_layer(const CustomData *cdata, int type)
-{
- int idx = CustomData_get_active_layer_index(cdata, type);
- return idx != -1 ? cdata->layers + idx : NULL;
-}
-
-static CustomDataLayer *get_render_layer(const CustomData *cdata, int type)
-{
- int idx = CustomData_get_render_layer_index(cdata, type);
- return idx != -1 ? cdata->layers + idx : NULL;
-}
-
-/* Allocates a non-initialized buffer to be sent to GPU.
- * Return is false it indicates that the memory map failed. */
-static bool gpu_pbvh_vert_buf_data_set(PBVHGPUFormat *vbo_id,
- GPU_PBVH_Buffers *buffers,
- uint vert_len)
-{
- /* Keep so we can test #GPU_USAGE_DYNAMIC buffer use.
- * Not that format initialization match in both blocks.
- * Do this to keep braces balanced - otherwise indentation breaks. */
-
- if (buffers->vert_buf == NULL) {
- /* Initialize vertex buffer (match 'VertexBufferFormat'). */
- buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&vbo_id->format, GPU_USAGE_STATIC);
- }
- if (GPU_vertbuf_get_data(buffers->vert_buf) == NULL ||
- GPU_vertbuf_get_vertex_len(buffers->vert_buf) != vert_len) {
- /* Allocate buffer if not allocated yet or size changed. */
- GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len);
- }
-
- return GPU_vertbuf_get_data(buffers->vert_buf) != NULL;
-}
-
-static void gpu_pbvh_batch_init(GPU_PBVH_Buffers *buffers, GPUPrimType prim)
-{
- if (buffers->triangles == NULL) {
- buffers->triangles = GPU_batch_create(prim,
- buffers->vert_buf,
- /* can be NULL if buffer is empty */
- buffers->index_buf);
- }
-
- if ((buffers->triangles_fast == NULL) && buffers->index_buf_fast) {
- buffers->triangles_fast = GPU_batch_create(prim, buffers->vert_buf, buffers->index_buf_fast);
- }
-
- if (buffers->lines == NULL) {
- buffers->lines = GPU_batch_create(GPU_PRIM_LINES,
- buffers->vert_buf,
- /* can be NULL if buffer is empty */
- buffers->index_lines_buf);
- }
-
- if ((buffers->lines_fast == NULL) && buffers->index_lines_buf_fast) {
- buffers->lines_fast = GPU_batch_create(
- GPU_PRIM_LINES, buffers->vert_buf, buffers->index_lines_buf_fast);
- }
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Mesh PBVH
- * \{ */
-
-static bool gpu_pbvh_is_looptri_visible(const MLoopTri *lt, const bool *hide_poly)
-{
- return !paint_is_face_hidden(lt, hide_poly);
-}
-
-void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
- GPU_PBVH_Buffers *buffers,
- const Mesh *mesh,
- const MVert *mvert,
- const float *vmask,
- const int *sculpt_face_sets,
- int face_sets_color_seed,
- int face_sets_color_default,
- int update_flags,
- const float (*vert_normals)[3])
-{
- GPUAttrRef vcol_refs[MAX_GPU_ATTR];
- GPUAttrRef cd_uvs[MAX_GPU_ATTR];
-
- const bool *hide_poly = (const bool *)CustomData_get_layer_named(
- &mesh->pdata, CD_PROP_BOOL, ".hide_poly");
- const int *material_indices = (const int *)CustomData_get_layer_named(
- &mesh->pdata, CD_PROP_INT32, "material_index");
-
- const CustomDataLayer *actcol = BKE_id_attributes_active_color_get(&mesh->id);
- eAttrDomain actcol_domain = actcol ? BKE_id_attribute_domain(&mesh->id, actcol) :
- ATTR_DOMAIN_AUTO;
-
- const CustomDataLayer *rendercol = BKE_id_attributes_render_color_get(&mesh->id);
-
- int totcol;
-
- if (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) {
- totcol = gpu_pbvh_make_attr_offs(ATTR_DOMAIN_MASK_COLOR,
- CD_MASK_COLOR_ALL,
- &mesh->vdata,
- NULL,
- &mesh->ldata,
- NULL,
- vcol_refs,
- vbo_id->active_attrs_only,
- actcol ? actcol->type : 0,
- actcol_domain,
- actcol,
- rendercol);
- }
- else {
- totcol = 0;
- }
-
- int totuv = gpu_pbvh_make_attr_offs(ATTR_DOMAIN_MASK_CORNER,
- CD_MASK_MLOOPUV,
- NULL,
- NULL,
- &mesh->ldata,
- NULL,
- cd_uvs,
- vbo_id->active_attrs_only,
- CD_MLOOPUV,
- ATTR_DOMAIN_CORNER,
- get_active_layer(&mesh->ldata, CD_MLOOPUV),
- get_render_layer(&mesh->ldata, CD_MLOOPUV));
-
- const bool show_mask = vmask && (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
- const bool show_face_sets = sculpt_face_sets &&
- (update_flags & GPU_PBVH_BUFFERS_SHOW_SCULPT_FACE_SETS) != 0;
- bool empty_mask = true;
- bool default_face_set = true;
-
- {
- const int totelem = buffers->tot_tri * 3;
-
- /* Build VBO */
- if (gpu_pbvh_vert_buf_data_set(vbo_id, buffers, totelem)) {
- GPUVertBufRaw pos_step = {0};
- GPUVertBufRaw nor_step = {0};
- GPUVertBufRaw msk_step = {0};
- GPUVertBufRaw fset_step = {0};
- GPUVertBufRaw col_step = {0};
- GPUVertBufRaw uv_step = {0};
-
- GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, vbo_id->pos, &pos_step);
- GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, vbo_id->nor, &nor_step);
- GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, vbo_id->msk, &msk_step);
- GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, vbo_id->fset, &fset_step);
-
- /* calculate normal for each polygon only once */
- uint mpoly_prev = UINT_MAX;
- short no[3] = {0, 0, 0};
-
- if (totuv > 0) {
- for (int uv_i = 0; uv_i < totuv; uv_i++) {
- GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, vbo_id->uv[uv_i], &uv_step);
-
- GPUAttrRef *ref = cd_uvs + uv_i;
- CustomDataLayer *layer = mesh->ldata.layers + ref->layer_idx;
- MLoopUV *muv = layer->data;
-
- for (uint i = 0; i < buffers->face_indices_len; i++) {
- const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
-
- if (!gpu_pbvh_is_looptri_visible(lt, hide_poly)) {
- continue;
- }
-
- for (uint j = 0; j < 3; j++) {
- MLoopUV *muv2 = muv + lt->tri[j];
-
- memcpy(GPU_vertbuf_raw_step(&uv_step), muv2->uv, sizeof(muv2->uv));
- }
- }
- }
- }
-
- for (int col_i = 0; col_i < totcol; col_i++) {
- GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, vbo_id->col[col_i], &col_step);
-
- const MPropCol *pcol = NULL;
- const MLoopCol *mcol = NULL;
-
- GPUAttrRef *ref = vcol_refs + col_i;
- const CustomData *cdata = ref->domain == ATTR_DOMAIN_POINT ? &mesh->vdata : &mesh->ldata;
- const CustomDataLayer *layer = cdata->layers + ref->layer_idx;
-
- bool color_loops = ref->domain == ATTR_DOMAIN_CORNER;
-
- if (layer->type == CD_PROP_COLOR) {
- pcol = (const MPropCol *)layer->data;
- }
- else {
- mcol = (const MLoopCol *)layer->data;
- }
-
- for (uint i = 0; i < buffers->face_indices_len; i++) {
- const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
- const uint vtri[3] = {
- buffers->mloop[lt->tri[0]].v,
- buffers->mloop[lt->tri[1]].v,
- buffers->mloop[lt->tri[2]].v,
- };
-
- if (!gpu_pbvh_is_looptri_visible(lt, hide_poly)) {
- continue;
- }
-
- for (uint j = 0; j < 3; j++) {
- /* Vertex Colors. */
- const uint loop_index = lt->tri[j];
-
- ushort scol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
-
- if (pcol) {
- const MPropCol *pcol2 = pcol + (color_loops ? loop_index : vtri[j]);
-
- scol[0] = unit_float_to_ushort_clamp(pcol2->color[0]);
- scol[1] = unit_float_to_ushort_clamp(pcol2->color[1]);
- scol[2] = unit_float_to_ushort_clamp(pcol2->color[2]);
- scol[3] = unit_float_to_ushort_clamp(pcol2->color[3]);
- }
- else {
- const MLoopCol *mcol2 = mcol + (color_loops ? loop_index : vtri[j]);
-
- scol[0] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol2->r]);
- scol[1] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol2->g]);
- scol[2] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol2->b]);
- scol[3] = unit_float_to_ushort_clamp(mcol2->a * (1.0f / 255.0f));
- }
-
- memcpy(GPU_vertbuf_raw_step(&col_step), scol, sizeof(scol));
- }
- }
- }
-
- for (uint i = 0; i < buffers->face_indices_len; i++) {
- const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
- const uint vtri[3] = {
- buffers->mloop[lt->tri[0]].v,
- buffers->mloop[lt->tri[1]].v,
- buffers->mloop[lt->tri[2]].v,
- };
-
- if (!gpu_pbvh_is_looptri_visible(lt, hide_poly)) {
- continue;
- }
-
- /* Face normal and mask */
- if (lt->poly != mpoly_prev && !buffers->smooth) {
- const MPoly *mp = &buffers->mpoly[lt->poly];
- float fno[3];
- BKE_mesh_calc_poly_normal(mp, &buffers->mloop[mp->loopstart], mvert, fno);
- normal_float_to_short_v3(no, fno);
- mpoly_prev = lt->poly;
- }
-
- uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
- if (show_face_sets) {
- const int fset = abs(sculpt_face_sets[lt->poly]);
- /* Skip for the default color Face Set to render it white. */
- if (fset != face_sets_color_default) {
- BKE_paint_face_set_overlay_color_get(fset, face_sets_color_seed, face_set_color);
- default_face_set = false;
- }
- }
-
- float fmask = 0.0f;
- uchar cmask = 0;
- if (show_mask && !buffers->smooth) {
- fmask = (vmask[vtri[0]] + vmask[vtri[1]] + vmask[vtri[2]]) / 3.0f;
- cmask = (uchar)(fmask * 255);
- }
-
- for (uint j = 0; j < 3; j++) {
- const MVert *v = &mvert[vtri[j]];
- copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), v->co);
-
- if (buffers->smooth) {
- normal_float_to_short_v3(no, vert_normals[vtri[j]]);
- }
- copy_v3_v3_short(GPU_vertbuf_raw_step(&nor_step), no);
-
- if (show_mask && buffers->smooth) {
- cmask = (uchar)(vmask[vtri[j]] * 255);
- }
-
- *(uchar *)GPU_vertbuf_raw_step(&msk_step) = cmask;
- empty_mask = empty_mask && (cmask == 0);
- /* Face Sets. */
- memcpy(GPU_vertbuf_raw_step(&fset_step), face_set_color, sizeof(uchar[3]));
- }
- }
- }
-
- gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS);
- }
-
- /* Get material index from the first face of this buffer. */
- const MLoopTri *lt = &buffers->looptri[buffers->face_indices[0]];
- buffers->material_index = material_indices ? material_indices[lt->poly] : 0;
-
- buffers->show_overlay = !empty_mask || !default_face_set;
- buffers->mvert = mvert;
-}
-
-GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const Mesh *mesh,
- const MLoopTri *looptri,
- const int *face_indices,
- const int face_indices_len)
-{
- GPU_PBVH_Buffers *buffers;
- int i, tottri;
- int tot_real_edges = 0;
-
- const MPoly *polys = BKE_mesh_polys(mesh);
- const MLoop *loops = BKE_mesh_loops(mesh);
-
- buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
-
- const bool *hide_poly = (bool *)CustomData_get_layer_named(
- &mesh->pdata, CD_PROP_BOOL, ".hide_poly");
-
- /* smooth or flat for all */
- buffers->smooth = polys[looptri[face_indices[0]].poly].flag & ME_SMOOTH;
-
- buffers->show_overlay = false;
-
- /* Count the number of visible triangles */
- for (i = 0, tottri = 0; i < face_indices_len; i++) {
- const MLoopTri *lt = &looptri[face_indices[i]];
- if (gpu_pbvh_is_looptri_visible(lt, hide_poly)) {
- int r_edges[3];
- BKE_mesh_looptri_get_real_edges(mesh, lt, r_edges);
- for (int j = 0; j < 3; j++) {
- if (r_edges[j] != -1) {
- tot_real_edges++;
- }
- }
- tottri++;
- }
- }
-
- if (tottri == 0) {
- buffers->tot_tri = 0;
-
- buffers->mpoly = polys;
- buffers->mloop = loops;
- buffers->looptri = looptri;
- buffers->face_indices = face_indices;
- buffers->face_indices_len = 0;
-
- return buffers;
- }
-
- /* Fill the only the line buffer. */
- GPUIndexBufBuilder elb_lines;
- GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tot_real_edges, INT_MAX);
- int vert_idx = 0;
-
- for (i = 0; i < face_indices_len; i++) {
- const MLoopTri *lt = &looptri[face_indices[i]];
-
- /* Skip hidden faces */
- if (!gpu_pbvh_is_looptri_visible(lt, hide_poly)) {
- continue;
- }
-
- int r_edges[3];
- BKE_mesh_looptri_get_real_edges(mesh, lt, r_edges);
- if (r_edges[0] != -1) {
- GPU_indexbuf_add_line_verts(&elb_lines, vert_idx * 3 + 0, vert_idx * 3 + 1);
- }
- if (r_edges[1] != -1) {
- GPU_indexbuf_add_line_verts(&elb_lines, vert_idx * 3 + 1, vert_idx * 3 + 2);
- }
- if (r_edges[2] != -1) {
- GPU_indexbuf_add_line_verts(&elb_lines, vert_idx * 3 + 2, vert_idx * 3 + 0);
- }
-
- vert_idx++;
- }
- buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
-
- buffers->tot_tri = tottri;
-
- buffers->mpoly = polys;
- buffers->mloop = loops;
- buffers->looptri = looptri;
-
- buffers->face_indices = face_indices;
- buffers->face_indices_len = face_indices_len;
-
- return buffers;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Grid PBVH
- * \{ */
-
-static void gpu_pbvh_grid_fill_index_buffers(GPU_PBVH_Buffers *buffers,
- SubdivCCG *UNUSED(subdiv_ccg),
- const int *UNUSED(face_sets),
- const int *grid_indices,
- uint visible_quad_len,
- int totgrid,
- int gridsize)
-{
- GPUIndexBufBuilder elb, elb_lines;
- GPUIndexBufBuilder elb_fast, elb_lines_fast;
-
- GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, 2 * visible_quad_len, INT_MAX);
- GPU_indexbuf_init(&elb_fast, GPU_PRIM_TRIS, 2 * totgrid, INT_MAX);
- GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, 2 * totgrid * gridsize * (gridsize - 1), INT_MAX);
- GPU_indexbuf_init(&elb_lines_fast, GPU_PRIM_LINES, 4 * totgrid, INT_MAX);
-
- if (buffers->smooth) {
- uint offset = 0;
- const uint grid_vert_len = gridsize * gridsize;
- for (int i = 0; i < totgrid; i++, offset += grid_vert_len) {
- uint v0, v1, v2, v3;
- bool grid_visible = false;
-
- BLI_bitmap *gh = buffers->grid_hidden[grid_indices[i]];
-
- for (int j = 0; j < gridsize - 1; j++) {
- for (int k = 0; k < gridsize - 1; k++) {
- /* Skip hidden grid face */
- if (gh && paint_is_grid_face_hidden(gh, gridsize, k, j)) {
- continue;
- }
- /* Indices in a Clockwise QUAD disposition. */
- v0 = offset + j * gridsize + k;
- v1 = v0 + 1;
- v2 = v1 + gridsize;
- v3 = v2 - 1;
-
- GPU_indexbuf_add_tri_verts(&elb, v0, v2, v1);
- GPU_indexbuf_add_tri_verts(&elb, v0, v3, v2);
-
- GPU_indexbuf_add_line_verts(&elb_lines, v0, v1);
- GPU_indexbuf_add_line_verts(&elb_lines, v0, v3);
-
- if (j + 2 == gridsize) {
- GPU_indexbuf_add_line_verts(&elb_lines, v2, v3);
- }
- grid_visible = true;
- }
-
- if (grid_visible) {
- GPU_indexbuf_add_line_verts(&elb_lines, v1, v2);
- }
- }
-
- if (grid_visible) {
- /* Grid corners */
- v0 = offset;
- v1 = offset + gridsize - 1;
- v2 = offset + grid_vert_len - 1;
- v3 = offset + grid_vert_len - gridsize;
-
- GPU_indexbuf_add_tri_verts(&elb_fast, v0, v2, v1);
- GPU_indexbuf_add_tri_verts(&elb_fast, v0, v3, v2);
-
- GPU_indexbuf_add_line_verts(&elb_lines_fast, v0, v1);
- GPU_indexbuf_add_line_verts(&elb_lines_fast, v1, v2);
- GPU_indexbuf_add_line_verts(&elb_lines_fast, v2, v3);
- GPU_indexbuf_add_line_verts(&elb_lines_fast, v3, v0);
- }
- }
- }
- else {
- uint offset = 0;
- const uint grid_vert_len = square_uint(gridsize - 1) * 4;
- for (int i = 0; i < totgrid; i++, offset += grid_vert_len) {
- bool grid_visible = false;
- BLI_bitmap *gh = buffers->grid_hidden[grid_indices[i]];
-
- uint v0, v1, v2, v3;
- for (int j = 0; j < gridsize - 1; j++) {
- for (int k = 0; k < gridsize - 1; k++) {
- /* Skip hidden grid face */
- if (gh && paint_is_grid_face_hidden(gh, gridsize, k, j)) {
- continue;
- }
- /* VBO data are in a Clockwise QUAD disposition. */
- v0 = offset + (j * (gridsize - 1) + k) * 4;
- v1 = v0 + 1;
- v2 = v0 + 2;
- v3 = v0 + 3;
-
- GPU_indexbuf_add_tri_verts(&elb, v0, v2, v1);
- GPU_indexbuf_add_tri_verts(&elb, v0, v3, v2);
-
- GPU_indexbuf_add_line_verts(&elb_lines, v0, v1);
- GPU_indexbuf_add_line_verts(&elb_lines, v0, v3);
-
- if (j + 2 == gridsize) {
- GPU_indexbuf_add_line_verts(&elb_lines, v2, v3);
- }
- grid_visible = true;
- }
-
- if (grid_visible) {
- GPU_indexbuf_add_line_verts(&elb_lines, v1, v2);
- }
- }
-
- if (grid_visible) {
- /* Grid corners */
- v0 = offset;
- v1 = offset + (gridsize - 1) * 4 - 3;
- v2 = offset + grid_vert_len - 2;
- v3 = offset + grid_vert_len - (gridsize - 1) * 4 + 3;
-
- GPU_indexbuf_add_tri_verts(&elb_fast, v0, v2, v1);
- GPU_indexbuf_add_tri_verts(&elb_fast, v0, v3, v2);
-
- GPU_indexbuf_add_line_verts(&elb_lines_fast, v0, v1);
- GPU_indexbuf_add_line_verts(&elb_lines_fast, v1, v2);
- GPU_indexbuf_add_line_verts(&elb_lines_fast, v2, v3);
- GPU_indexbuf_add_line_verts(&elb_lines_fast, v3, v0);
- }
- }
- }
-
- buffers->index_buf = GPU_indexbuf_build(&elb);
- buffers->index_buf_fast = GPU_indexbuf_build(&elb_fast);
- buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
- buffers->index_lines_buf_fast = GPU_indexbuf_build(&elb_lines_fast);
-}
-
-void GPU_pbvh_grid_buffers_update_free(GPU_PBVH_Buffers *buffers,
- const struct DMFlagMat *grid_flag_mats,
- const int *grid_indices)
-{
- const bool smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
-
- if (buffers->smooth != smooth) {
- buffers->smooth = smooth;
- GPU_BATCH_DISCARD_SAFE(buffers->triangles);
- GPU_BATCH_DISCARD_SAFE(buffers->triangles_fast);
- GPU_BATCH_DISCARD_SAFE(buffers->lines);
- GPU_BATCH_DISCARD_SAFE(buffers->lines_fast);
-
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf_fast);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf_fast);
- }
-}
-
-void GPU_pbvh_grid_buffers_update(PBVHGPUFormat *vbo_id,
- GPU_PBVH_Buffers *buffers,
- SubdivCCG *subdiv_ccg,
- CCGElem **grids,
- const struct DMFlagMat *grid_flag_mats,
- int *grid_indices,
- int totgrid,
- const int *sculpt_face_sets,
- const int face_sets_color_seed,
- const int face_sets_color_default,
- const struct CCGKey *key,
- const int update_flags)
-{
- const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
- const bool show_vcol = (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0;
- const bool show_face_sets = sculpt_face_sets &&
- (update_flags & GPU_PBVH_BUFFERS_SHOW_SCULPT_FACE_SETS) != 0;
- bool empty_mask = true;
- bool default_face_set = true;
-
- int i, j, k, x, y;
-
- /* Build VBO */
- const int has_mask = key->has_mask;
-
- uint vert_per_grid = (buffers->smooth) ? key->grid_area : (square_i(key->grid_size - 1) * 4);
- uint vert_count = totgrid * vert_per_grid;
-
- if (buffers->index_buf == NULL) {
- uint visible_quad_len = BKE_pbvh_count_grid_quads(
- (BLI_bitmap **)buffers->grid_hidden, grid_indices, totgrid, key->grid_size);
-
- /* totally hidden node, return here to avoid BufferData with zero below. */
- if (visible_quad_len == 0) {
- return;
- }
-
- gpu_pbvh_grid_fill_index_buffers(buffers,
- subdiv_ccg,
- sculpt_face_sets,
- grid_indices,
- visible_quad_len,
- totgrid,
- key->grid_size);
- }
-
- uint vbo_index_offset = 0;
- /* Build VBO */
- if (gpu_pbvh_vert_buf_data_set(vbo_id, buffers, vert_count)) {
- GPUIndexBufBuilder elb_lines;
-
- if (buffers->index_lines_buf == NULL) {
- GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, totgrid * key->grid_area * 2, vert_count);
- }
-
- for (i = 0; i < totgrid; i++) {
- const int grid_index = grid_indices[i];
- CCGElem *grid = grids[grid_index];
- int vbo_index = vbo_index_offset;
-
- uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
-
- if (show_face_sets && subdiv_ccg && sculpt_face_sets) {
- const int face_index = BKE_subdiv_ccg_grid_to_face_index(subdiv_ccg, grid_index);
-
- const int fset = abs(sculpt_face_sets[face_index]);
- /* Skip for the default color Face Set to render it white. */
- if (fset != face_sets_color_default) {
- BKE_paint_face_set_overlay_color_get(fset, face_sets_color_seed, face_set_color);
- default_face_set = false;
- }
- }
-
- if (buffers->smooth) {
- for (y = 0; y < key->grid_size; y++) {
- for (x = 0; x < key->grid_size; x++) {
- CCGElem *elem = CCG_grid_elem(key, grid, x, y);
- GPU_vertbuf_attr_set(
- buffers->vert_buf, vbo_id->pos, vbo_index, CCG_elem_co(key, elem));
-
- short no_short[3];
- normal_float_to_short_v3(no_short, CCG_elem_no(key, elem));
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->nor, vbo_index, no_short);
-
- if (has_mask && show_mask) {
- float fmask = *CCG_elem_mask(key, elem);
- uchar cmask = (uchar)(fmask * 255);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->msk, vbo_index, &cmask);
- empty_mask = empty_mask && (cmask == 0);
- }
-
- if (show_vcol) {
- const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->col[0], vbo_index, &vcol);
- }
-
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->fset, vbo_index, &face_set_color);
-
- vbo_index += 1;
- }
- }
- vbo_index_offset += key->grid_area;
- }
- else {
- for (j = 0; j < key->grid_size - 1; j++) {
- for (k = 0; k < key->grid_size - 1; k++) {
- CCGElem *elems[4] = {
- CCG_grid_elem(key, grid, k, j),
- CCG_grid_elem(key, grid, k + 1, j),
- CCG_grid_elem(key, grid, k + 1, j + 1),
- CCG_grid_elem(key, grid, k, j + 1),
- };
- float *co[4] = {
- CCG_elem_co(key, elems[0]),
- CCG_elem_co(key, elems[1]),
- CCG_elem_co(key, elems[2]),
- CCG_elem_co(key, elems[3]),
- };
-
- float fno[3];
- short no_short[3];
- /* NOTE: Clockwise indices ordering, that's why we invert order here. */
- normal_quad_v3(fno, co[3], co[2], co[1], co[0]);
- normal_float_to_short_v3(no_short, fno);
-
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->pos, vbo_index + 0, co[0]);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->nor, vbo_index + 0, no_short);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->pos, vbo_index + 1, co[1]);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->nor, vbo_index + 1, no_short);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->pos, vbo_index + 2, co[2]);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->nor, vbo_index + 2, no_short);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->pos, vbo_index + 3, co[3]);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->nor, vbo_index + 3, no_short);
-
- if (has_mask && show_mask) {
- float fmask = (*CCG_elem_mask(key, elems[0]) + *CCG_elem_mask(key, elems[1]) +
- *CCG_elem_mask(key, elems[2]) + *CCG_elem_mask(key, elems[3])) *
- 0.25f;
- uchar cmask = (uchar)(fmask * 255);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->msk, vbo_index + 0, &cmask);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->msk, vbo_index + 1, &cmask);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->msk, vbo_index + 2, &cmask);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->msk, vbo_index + 3, &cmask);
- empty_mask = empty_mask && (cmask == 0);
- }
-
- const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->col[0], vbo_index + 0, &vcol);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->col[0], vbo_index + 1, &vcol);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->col[0], vbo_index + 2, &vcol);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->col[0], vbo_index + 3, &vcol);
-
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->fset, vbo_index + 0, &face_set_color);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->fset, vbo_index + 1, &face_set_color);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->fset, vbo_index + 2, &face_set_color);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->fset, vbo_index + 3, &face_set_color);
-
- vbo_index += 4;
- }
- }
- vbo_index_offset += square_i(key->grid_size - 1) * 4;
- }
- }
-
- gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS);
- }
-
- /* Get material index from the first face of this buffer. */
- buffers->material_index = grid_flag_mats[grid_indices[0]].mat_nr;
-
- buffers->grids = grids;
- buffers->grid_indices = grid_indices;
- buffers->totgrid = totgrid;
- buffers->grid_flag_mats = grid_flag_mats;
- buffers->gridkey = *key;
- buffers->show_overlay = !empty_mask || !default_face_set;
-}
-
-GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(int totgrid, BLI_bitmap **grid_hidden, bool smooth)
-{
- GPU_PBVH_Buffers *buffers;
-
- buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
- buffers->grid_hidden = grid_hidden;
- buffers->totgrid = totgrid;
- buffers->smooth = smooth;
-
- buffers->show_overlay = false;
-
- return buffers;
-}
-
-#undef FILL_QUAD_BUFFER
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name BMesh PBVH
- * \{ */
-
-/* Output a BMVert into a VertexBufferFormat array at v_index. */
-static void gpu_bmesh_vert_to_buffer_copy(PBVHGPUFormat *vbo_id,
- BMVert *v,
- GPUVertBuf *vert_buf,
- int v_index,
- const float fno[3],
- const float *fmask,
- const int cd_vert_mask_offset,
- const bool show_mask,
- const bool show_vcol,
- bool *empty_mask)
-{
- /* Vertex should always be visible if it's used by a visible face. */
- BLI_assert(!BM_elem_flag_test(v, BM_ELEM_HIDDEN));
-
- /* Set coord, normal, and mask */
- GPU_vertbuf_attr_set(vert_buf, vbo_id->pos, v_index, v->co);
-
- short no_short[3];
- normal_float_to_short_v3(no_short, fno ? fno : v->no);
- GPU_vertbuf_attr_set(vert_buf, vbo_id->nor, v_index, no_short);
-
- if (show_mask) {
- float effective_mask = fmask ? *fmask : BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset);
- uchar cmask = (uchar)(effective_mask * 255);
- GPU_vertbuf_attr_set(vert_buf, vbo_id->msk, v_index, &cmask);
- *empty_mask = *empty_mask && (cmask == 0);
- }
-
- if (show_vcol) {
- const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
- GPU_vertbuf_attr_set(vert_buf, vbo_id->col[0], v_index, &vcol);
- }
-
- /* Add default face sets color to avoid artifacts. */
- const uchar face_set[3] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
- GPU_vertbuf_attr_set(vert_buf, vbo_id->fset, v_index, &face_set);
-}
-
-/* Return the total number of vertices that don't have BM_ELEM_HIDDEN set */
-static int gpu_bmesh_vert_visible_count(GSet *bm_unique_verts, GSet *bm_other_verts)
-{
- GSetIterator gs_iter;
- int totvert = 0;
-
- GSET_ITER (gs_iter, bm_unique_verts) {
- BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
- if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
- totvert++;
- }
- }
- GSET_ITER (gs_iter, bm_other_verts) {
- BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
- if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
- totvert++;
- }
- }
-
- return totvert;
-}
-
-/* Return the total number of visible faces */
-static int gpu_bmesh_face_visible_count(GSet *bm_faces)
-{
- GSetIterator gh_iter;
- int totface = 0;
-
- GSET_ITER (gh_iter, bm_faces) {
- BMFace *f = BLI_gsetIterator_getKey(&gh_iter);
-
- if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- totface++;
- }
- }
-
- return totface;
-}
-
-void GPU_pbvh_bmesh_buffers_update_free(GPU_PBVH_Buffers *buffers)
-{
- if (buffers->smooth) {
- /* Smooth needs to recreate index buffer, so we have to invalidate the batch. */
- GPU_BATCH_DISCARD_SAFE(buffers->triangles);
- GPU_BATCH_DISCARD_SAFE(buffers->lines);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
- }
- else {
- GPU_BATCH_DISCARD_SAFE(buffers->lines);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
- }
-}
-
-void GPU_pbvh_bmesh_buffers_update(PBVHGPUFormat *vbo_id,
- GPU_PBVH_Buffers *buffers,
- BMesh *bm,
- GSet *bm_faces,
- GSet *bm_unique_verts,
- GSet *bm_other_verts,
- const int update_flags)
-{
- const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
- const bool show_vcol = (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0;
- int tottri, totvert;
- bool empty_mask = true;
- BMFace *f = NULL;
-
- /* Count visible triangles */
- tottri = gpu_bmesh_face_visible_count(bm_faces);
-
- if (buffers->smooth) {
- /* Count visible vertices */
- totvert = gpu_bmesh_vert_visible_count(bm_unique_verts, bm_other_verts);
- }
- else {
- totvert = tottri * 3;
- }
-
- if (!tottri) {
- if (BLI_gset_len(bm_faces) != 0) {
- /* Node is just hidden. */
- }
- else {
- buffers->clear_bmesh_on_flush = true;
- }
- buffers->tot_tri = 0;
- return;
- }
-
- /* TODO: make mask layer optional for bmesh buffer. */
- const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
-
- /* Fill vertex buffer */
- if (!gpu_pbvh_vert_buf_data_set(vbo_id, buffers, totvert)) {
- /* Memory map failed */
- return;
- }
-
- int v_index = 0;
-
- if (buffers->smooth) {
- /* Fill the vertex and triangle buffer in one pass over faces. */
- GPUIndexBufBuilder elb, elb_lines;
- GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tottri, totvert);
- GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tottri * 3, totvert);
-
- GHash *bm_vert_to_index = BLI_ghash_int_new_ex("bm_vert_to_index", totvert);
-
- GSetIterator gs_iter;
- GSET_ITER (gs_iter, bm_faces) {
- f = BLI_gsetIterator_getKey(&gs_iter);
-
- if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- BMVert *v[3];
- BM_face_as_array_vert_tri(f, v);
-
- uint idx[3];
- for (int i = 0; i < 3; i++) {
- void **idx_p;
- if (!BLI_ghash_ensure_p(bm_vert_to_index, v[i], &idx_p)) {
- /* Add vertex to the vertex buffer each time a new one is encountered */
- *idx_p = POINTER_FROM_UINT(v_index);
-
- gpu_bmesh_vert_to_buffer_copy(vbo_id,
- v[i],
- buffers->vert_buf,
- v_index,
- NULL,
- NULL,
- cd_vert_mask_offset,
- show_mask,
- show_vcol,
- &empty_mask);
-
- idx[i] = v_index;
- v_index++;
- }
- else {
- /* Vertex already in the vertex buffer, just get the index. */
- idx[i] = POINTER_AS_UINT(*idx_p);
- }
- }
-
- GPU_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]);
-
- GPU_indexbuf_add_line_verts(&elb_lines, idx[0], idx[1]);
- GPU_indexbuf_add_line_verts(&elb_lines, idx[1], idx[2]);
- GPU_indexbuf_add_line_verts(&elb_lines, idx[2], idx[0]);
- }
- }
-
- BLI_ghash_free(bm_vert_to_index, NULL, NULL);
-
- buffers->tot_tri = tottri;
- if (buffers->index_buf == NULL) {
- buffers->index_buf = GPU_indexbuf_build(&elb);
- }
- else {
- GPU_indexbuf_build_in_place(&elb, buffers->index_buf);
- }
- buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
- }
- else {
- GSetIterator gs_iter;
-
- GPUIndexBufBuilder elb_lines;
- GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tottri * 3, tottri * 3);
-
- GSET_ITER (gs_iter, bm_faces) {
- f = BLI_gsetIterator_getKey(&gs_iter);
-
- BLI_assert(f->len == 3);
-
- if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- BMVert *v[3];
- float fmask = 0.0f;
- int i;
-
- BM_face_as_array_vert_tri(f, v);
-
- /* Average mask value */
- for (i = 0; i < 3; i++) {
- fmask += BM_ELEM_CD_GET_FLOAT(v[i], cd_vert_mask_offset);
- }
- fmask /= 3.0f;
-
- GPU_indexbuf_add_line_verts(&elb_lines, v_index + 0, v_index + 1);
- GPU_indexbuf_add_line_verts(&elb_lines, v_index + 1, v_index + 2);
- GPU_indexbuf_add_line_verts(&elb_lines, v_index + 2, v_index + 0);
-
- for (i = 0; i < 3; i++) {
- gpu_bmesh_vert_to_buffer_copy(vbo_id,
- v[i],
- buffers->vert_buf,
- v_index++,
- f->no,
- &fmask,
- cd_vert_mask_offset,
- show_mask,
- show_vcol,
- &empty_mask);
- }
- }
- }
-
- buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
- buffers->tot_tri = tottri;
- }
-
- /* Get material index from the last face we iterated on. */
- buffers->material_index = (f) ? f->mat_nr : 0;
-
- buffers->show_overlay = !empty_mask;
-
- gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Generic
- * \{ */
-
-GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading)
-{
- GPU_PBVH_Buffers *buffers;
-
- buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
- buffers->use_bmesh = true;
- buffers->smooth = smooth_shading;
- buffers->show_overlay = true;
-
- return buffers;
-}
-
-/**
- * Builds a list of attributes from a set of domains and a set of
- * customdata types.
- *
- * \param active_only: Returns only one item, a #GPUAttrRef to active_layer.
- * \param active_layer: #CustomDataLayer to use for the active layer.
- * \param active_layer: #CustomDataLayer to use for the render layer.
- */
-static int gpu_pbvh_make_attr_offs(eAttrDomainMask domain_mask,
- eCustomDataMask type_mask,
- const CustomData *vdata,
- const CustomData *edata,
- const CustomData *ldata,
- const CustomData *pdata,
- GPUAttrRef r_cd_attrs[MAX_GPU_ATTR],
- bool active_only,
- int active_type,
- int active_domain,
- const CustomDataLayer *active_layer,
- const CustomDataLayer *render_layer)
-{
- const CustomData *cdata_active = active_domain == ATTR_DOMAIN_POINT ? vdata : ldata;
-
- if (!cdata_active) {
- return 0;
- }
-
- if (active_only) {
- int idx = active_layer ? active_layer - cdata_active->layers : -1;
-
- if (idx >= 0 && idx < cdata_active->totlayer) {
- r_cd_attrs[0].cd_offset = cdata_active->layers[idx].offset;
- r_cd_attrs[0].domain = active_domain;
- r_cd_attrs[0].type = active_type;
- r_cd_attrs[0].layer_idx = idx;
-
- return 1;
- }
-
- return 0;
- }
-
- const CustomData *datas[4] = {vdata, edata, pdata, ldata};
-
- int count = 0;
- for (eAttrDomain domain = 0; domain < 4; domain++) {
- const CustomData *cdata = datas[domain];
-
- if (!cdata || !((1 << domain) & domain_mask)) {
- continue;
- }
-
- const CustomDataLayer *cl = cdata->layers;
-
- for (int i = 0; count < MAX_GPU_ATTR && i < cdata->totlayer; i++, cl++) {
- if ((CD_TYPE_AS_MASK(cl->type) & type_mask) && !(cl->flag & CD_FLAG_TEMPORARY)) {
- GPUAttrRef *ref = r_cd_attrs + count;
-
- ref->cd_offset = cl->offset;
- ref->type = cl->type;
- ref->layer_idx = i;
- ref->domain = domain;
-
- count++;
- }
- }
- }
-
- /* Ensure render layer is last, draw cache code seems to need this. */
-
- for (int i = 0; i < count; i++) {
- GPUAttrRef *ref = r_cd_attrs + i;
- const CustomData *cdata = datas[ref->domain];
-
- if (cdata->layers + ref->layer_idx == render_layer) {
- SWAP(GPUAttrRef, r_cd_attrs[i], r_cd_attrs[count - 1]);
- break;
- }
- }
-
- return count;
-}
-
-static bool gpu_pbvh_format_equals(PBVHGPUFormat *a, PBVHGPUFormat *b)
-{
- bool bad = false;
-
- bad |= a->active_attrs_only != b->active_attrs_only;
-
- bad |= a->pos != b->pos;
- bad |= a->fset != b->fset;
- bad |= a->msk != b->msk;
- bad |= a->nor != b->nor;
-
- for (int i = 0; i < MIN2(a->totuv, b->totuv); i++) {
- bad |= a->uv[i] != b->uv[i];
- }
-
- for (int i = 0; i < MIN2(a->totcol, b->totcol); i++) {
- bad |= a->col[i] != b->col[i];
- }
-
- bad |= a->totuv != b->totuv;
- bad |= a->totcol != b->totcol;
-
- return !bad;
-}
-
-bool GPU_pbvh_attribute_names_update(PBVHType pbvh_type,
- PBVHGPUFormat *vbo_id,
- const CustomData *vdata,
- const CustomData *ldata,
- bool active_attrs_only)
-{
- const bool active_only = active_attrs_only;
- PBVHGPUFormat old_format = *vbo_id;
-
- GPU_vertformat_clear(&vbo_id->format);
-
- vbo_id->active_attrs_only = active_attrs_only;
-
- if (vbo_id->format.attr_len == 0) {
- vbo_id->pos = GPU_vertformat_attr_add(
- &vbo_id->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- vbo_id->nor = GPU_vertformat_attr_add(
- &vbo_id->format, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
-
- /* TODO: Do not allocate these `.msk` and `.col` when they are not used. */
- vbo_id->msk = GPU_vertformat_attr_add(
- &vbo_id->format, "msk", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
-
- vbo_id->totcol = 0;
- if (pbvh_type == PBVH_FACES) {
- int ci = 0;
-
- Mesh me_query;
-
- BKE_id_attribute_copy_domains_temp(ID_ME, vdata, NULL, ldata, NULL, NULL, &me_query.id);
-
- const CustomDataLayer *active_color_layer = BKE_id_attributes_active_color_get(&me_query.id);
- const CustomDataLayer *render_color_layer = BKE_id_attributes_render_color_get(&me_query.id);
- eAttrDomain active_color_domain = active_color_layer ?
- BKE_id_attribute_domain(&me_query.id,
- active_color_layer) :
- ATTR_DOMAIN_POINT;
-
- GPUAttrRef vcol_layers[MAX_GPU_ATTR];
- int totlayer = gpu_pbvh_make_attr_offs(ATTR_DOMAIN_MASK_COLOR,
- CD_MASK_COLOR_ALL,
- vdata,
- NULL,
- ldata,
- NULL,
- vcol_layers,
- active_only,
- active_color_layer ? active_color_layer->type : -1,
- active_color_domain,
- active_color_layer,
- render_color_layer);
-
- for (int i = 0; i < totlayer; i++) {
- GPUAttrRef *ref = vcol_layers + i;
- const CustomData *cdata = ref->domain == ATTR_DOMAIN_POINT ? vdata : ldata;
-
- const CustomDataLayer *layer = cdata->layers + ref->layer_idx;
-
- if (vbo_id->totcol < MAX_GPU_ATTR) {
- vbo_id->col[ci++] = GPU_vertformat_attr_add(
- &vbo_id->format, "c", GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
- vbo_id->totcol++;
-
- bool is_render = render_color_layer == layer;
- bool is_active = active_color_layer == layer;
-
- DRW_cdlayer_attr_aliases_add(&vbo_id->format, "c", cdata, layer, is_render, is_active);
- }
- }
- }
-
- /* ensure at least one vertex color layer */
- if (vbo_id->totcol == 0) {
- vbo_id->col[0] = GPU_vertformat_attr_add(
- &vbo_id->format, "c", GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
- vbo_id->totcol = 1;
-
- GPU_vertformat_alias_add(&vbo_id->format, "ac");
- }
-
- vbo_id->fset = GPU_vertformat_attr_add(
- &vbo_id->format, "fset", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
-
- vbo_id->totuv = 0;
- if (pbvh_type == PBVH_FACES && ldata && CustomData_has_layer(ldata, CD_MLOOPUV)) {
- GPUAttrRef uv_layers[MAX_GPU_ATTR];
- const CustomDataLayer *active = NULL, *render = NULL;
-
- active = get_active_layer(ldata, CD_MLOOPUV);
- render = get_render_layer(ldata, CD_MLOOPUV);
-
- int totlayer = gpu_pbvh_make_attr_offs(ATTR_DOMAIN_MASK_CORNER,
- CD_MASK_MLOOPUV,
- NULL,
- NULL,
- ldata,
- NULL,
- uv_layers,
- active_only,
- CD_MLOOPUV,
- ATTR_DOMAIN_CORNER,
- active,
- render);
-
- vbo_id->totuv = totlayer;
-
- for (int i = 0; i < totlayer; i++) {
- GPUAttrRef *ref = uv_layers + i;
-
- vbo_id->uv[i] = GPU_vertformat_attr_add(
- &vbo_id->format, "uvs", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- const CustomDataLayer *cl = ldata->layers + ref->layer_idx;
- bool is_active = ref->layer_idx == CustomData_get_active_layer_index(ldata, CD_MLOOPUV);
-
- DRW_cdlayer_attr_aliases_add(&vbo_id->format, "u", ldata, cl, cl == render, is_active);
-
- /* Apparently the render attribute is 'a' while active is 'au',
- * at least going by the draw cache extractor code.
- */
- if (cl == render) {
- GPU_vertformat_alias_add(&vbo_id->format, "a");
- }
- }
- }
- }
-
- if (!gpu_pbvh_format_equals(&old_format, vbo_id)) {
- return true;
- }
-
- return false;
-}
-
-GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast, bool wires)
-{
- if (wires) {
- return (fast && buffers->lines_fast) ? buffers->lines_fast : buffers->lines;
- }
-
- return (fast && buffers->triangles_fast) ? buffers->triangles_fast : buffers->triangles;
-}
-
-bool GPU_pbvh_buffers_has_overlays(GPU_PBVH_Buffers *buffers)
-{
- return buffers->show_overlay;
-}
-
-short GPU_pbvh_buffers_material_index_get(GPU_PBVH_Buffers *buffers)
-{
- return buffers->material_index;
-}
-
-static void gpu_pbvh_buffers_clear(GPU_PBVH_Buffers *buffers)
-{
- GPU_BATCH_DISCARD_SAFE(buffers->lines);
- GPU_BATCH_DISCARD_SAFE(buffers->lines_fast);
- GPU_BATCH_DISCARD_SAFE(buffers->triangles);
- GPU_BATCH_DISCARD_SAFE(buffers->triangles_fast);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf_fast);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf_fast);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
- GPU_VERTBUF_DISCARD_SAFE(buffers->vert_buf);
-}
-
-void GPU_pbvh_buffers_update_flush(GPU_PBVH_Buffers *buffers)
-{
- /* Free empty bmesh node buffers. */
- if (buffers->clear_bmesh_on_flush) {
- gpu_pbvh_buffers_clear(buffers);
- buffers->clear_bmesh_on_flush = false;
- }
-
- /* Force flushing to the GPU. */
- if (buffers->vert_buf && GPU_vertbuf_get_data(buffers->vert_buf)) {
- GPU_vertbuf_use(buffers->vert_buf);
- }
-}
-
-void GPU_pbvh_buffers_free(GPU_PBVH_Buffers *buffers)
-{
- if (buffers) {
- gpu_pbvh_buffers_clear(buffers);
- MEM_freeN(buffers);
- }
-}
-
-/** \} */
diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc
index 75e148e0a8f..4adeac1b49a 100644
--- a/source/blender/gpu/intern/gpu_codegen.cc
+++ b/source/blender/gpu/intern/gpu_codegen.cc
@@ -183,6 +183,8 @@ static std::ostream &operator<<(std::ostream &stream, const GPUInput *input)
return stream << "var_attrs.v" << input->attr->id;
case GPU_SOURCE_UNIFORM_ATTR:
return stream << "unf_attrs[resource_id].attr" << input->uniform_attr->id;
+ case GPU_SOURCE_LAYER_ATTR:
+ return stream << "attr_load_layer(" << input->layer_attr->hash_code << ")";
case GPU_SOURCE_STRUCT:
return stream << "strct" << input->id;
case GPU_SOURCE_TEX:
@@ -386,6 +388,10 @@ void GPUCodegen::generate_resources()
const char *name = info.name_buffer.append_sampler_name(tex->sampler_name);
info.sampler(slot++, ImageType::FLOAT_1D_ARRAY, name, Frequency::BATCH);
}
+ else if (tex->sky) {
+ const char *name = info.name_buffer.append_sampler_name(tex->sampler_name);
+ info.sampler(0, ImageType::FLOAT_2D_ARRAY, name, Frequency::BATCH);
+ }
else if (tex->tiled_mapping_name[0] != '\0') {
const char *name = info.name_buffer.append_sampler_name(tex->sampler_name);
info.sampler(slot++, ImageType::FLOAT_2D_ARRAY, name, Frequency::BATCH);
@@ -428,6 +434,10 @@ void GPUCodegen::generate_resources()
info.uniform_buf(2, "UniformAttrs", GPU_ATTRIBUTE_UBO_BLOCK_NAME "[512]", Frequency::BATCH);
}
+ if (!BLI_listbase_is_empty(&graph.layer_attrs)) {
+ info.additional_info("draw_layer_attributes");
+ }
+
info.typedef_source_generated = ss.str();
}
@@ -807,7 +817,7 @@ void GPU_pass_cache_garbage_collect(void)
{
static int lasttime = 0;
const int shadercollectrate = 60; /* hardcoded for now. */
- int ctime = (int)PIL_check_seconds_timer();
+ int ctime = int(PIL_check_seconds_timer());
if (ctime < shadercollectrate + lasttime) {
return;
diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc
index bcc418169b7..7e94538892a 100644
--- a/source/blender/gpu/intern/gpu_context.cc
+++ b/source/blender/gpu/intern/gpu_context.cc
@@ -33,6 +33,9 @@
# include "gl_backend.hh"
# include "gl_context.hh"
#endif
+#ifdef WITH_VULKAN_BACKEND
+# include "vk_backend.hh"
+#endif
#ifdef WITH_METAL_BACKEND
# include "mtl_backend.hh"
#endif
@@ -94,7 +97,7 @@ Context *Context::get()
/* -------------------------------------------------------------------- */
-GPUContext *GPU_context_create(void *ghost_window)
+GPUContext *GPU_context_create(void *ghost_window, void *ghost_context)
{
{
std::scoped_lock lock(backend_users_mutex);
@@ -105,7 +108,7 @@ GPUContext *GPU_context_create(void *ghost_window)
num_backend_users++;
}
- Context *ctx = GPUBackend::get()->context_alloc(ghost_window);
+ Context *ctx = GPUBackend::get()->context_alloc(ghost_window, ghost_context);
GPU_context_active_set(wrap(ctx));
return wrap(ctx);
@@ -195,7 +198,11 @@ void GPU_render_begin()
{
GPUBackend *backend = GPUBackend::get();
BLI_assert(backend);
- backend->render_begin();
+ /* WORKAROUND: Currently a band-aid for the heist production. Has no side effect for GL backend
+ * but should be fixed for Metal. */
+ if (backend) {
+ backend->render_begin();
+ }
}
void GPU_render_end()
{
@@ -216,9 +223,22 @@ void GPU_render_step()
/** \name Backend selection
* \{ */
-static const eGPUBackendType g_backend_type = GPU_BACKEND_OPENGL;
+/* NOTE: To enable Metal API, we need to temporarily change this to `GPU_BACKEND_METAL`.
+ * Until a global switch is added, Metal also needs to be enabled in GHOST_ContextCGL:
+ * `m_useMetalForRendering = true`. */
+static eGPUBackendType g_backend_type = GPU_BACKEND_OPENGL;
static GPUBackend *g_backend = nullptr;
+void GPU_backend_type_selection_set(const eGPUBackendType backend)
+{
+ g_backend_type = backend;
+}
+
+eGPUBackendType GPU_backend_type_selection_get()
+{
+ return g_backend_type;
+}
+
bool GPU_backend_supported(void)
{
switch (g_backend_type) {
@@ -228,6 +248,12 @@ bool GPU_backend_supported(void)
#else
return false;
#endif
+ case GPU_BACKEND_VULKAN:
+#ifdef WITH_VULKAN_BACKEND
+ return true;
+#else
+ return false;
+#endif
case GPU_BACKEND_METAL:
#ifdef WITH_METAL_BACKEND
return MTLBackend::metal_is_supported();
@@ -251,6 +277,11 @@ static void gpu_backend_create()
g_backend = new GLBackend;
break;
#endif
+#ifdef WITH_VULKAN_BACKEND
+ case GPU_BACKEND_VULKAN:
+ g_backend = new VKBackend;
+ break;
+#endif
#ifdef WITH_METAL_BACKEND
case GPU_BACKEND_METAL:
g_backend = new MTLBackend;
diff --git a/source/blender/gpu/intern/gpu_framebuffer.cc b/source/blender/gpu/intern/gpu_framebuffer.cc
index 8d93e49d588..5b50fd66196 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.cc
+++ b/source/blender/gpu/intern/gpu_framebuffer.cc
@@ -148,9 +148,9 @@ void FrameBuffer::load_store_config_array(const GPULoadStore *load_store_actions
}
}
-unsigned int FrameBuffer::get_bits_per_pixel()
+uint FrameBuffer::get_bits_per_pixel()
{
- unsigned int total_bits = 0;
+ uint total_bits = 0;
for (GPUAttachment &attachment : attachments_) {
Texture *tex = reinterpret_cast<Texture *>(attachment.tex);
if (tex != nullptr) {
@@ -179,7 +179,7 @@ void FrameBuffer::recursive_downsample(int max_lvl,
/* Some Intel HDXXX have issue with rendering to a mipmap that is below
* the texture GL_TEXTURE_MAX_LEVEL. So even if it not correct, in this case
* we allow GL_TEXTURE_MAX_LEVEL to be one level lower. In practice it does work! */
- int mip_max = (GPU_mip_render_workaround()) ? mip_lvl : (mip_lvl - 1);
+ int mip_max = GPU_mip_render_workaround() ? mip_lvl : (mip_lvl - 1);
/* Restrict fetches only to previous level. */
tex->mip_range_set(mip_lvl - 1, mip_max);
/* Bind next level. */
@@ -238,6 +238,11 @@ void GPU_framebuffer_free(GPUFrameBuffer *gpu_fb)
delete unwrap(gpu_fb);
}
+const char *GPU_framebuffer_get_name(GPUFrameBuffer *gpu_fb)
+{
+ return unwrap(gpu_fb)->name_get();
+}
+
/* ---------- Binding ----------- */
void GPU_framebuffer_bind(GPUFrameBuffer *gpu_fb)
@@ -368,6 +373,11 @@ void GPU_framebuffer_config_array(GPUFrameBuffer *gpu_fb,
}
}
+void GPU_framebuffer_default_size(GPUFrameBuffer *gpu_fb, int width, int height)
+{
+ unwrap(gpu_fb)->size_set(width, height);
+}
+
/* ---------- Viewport & Scissor Region ----------- */
void GPU_framebuffer_viewport_set(GPUFrameBuffer *gpu_fb, int x, int y, int width, int height)
@@ -668,7 +678,7 @@ void GPU_offscreen_bind(GPUOffScreen *ofs, bool save)
unwrap(gpu_offscreen_fb_get(ofs))->bind(false);
}
-void GPU_offscreen_unbind(GPUOffScreen *UNUSED(ofs), bool restore)
+void GPU_offscreen_unbind(GPUOffScreen * /*ofs*/, bool restore)
{
GPUFrameBuffer *fb = nullptr;
if (restore) {
diff --git a/source/blender/gpu/intern/gpu_framebuffer_private.hh b/source/blender/gpu/intern/gpu_framebuffer_private.hh
index 8cecc6b8b15..cb7fd62445c 100644
--- a/source/blender/gpu/intern/gpu_framebuffer_private.hh
+++ b/source/blender/gpu/intern/gpu_framebuffer_private.hh
@@ -40,12 +40,12 @@ typedef enum GPUAttachmentType : int {
inline constexpr GPUAttachmentType operator-(GPUAttachmentType a, int b)
{
- return static_cast<GPUAttachmentType>(static_cast<int>(a) - b);
+ return static_cast<GPUAttachmentType>(int(a) - b);
}
inline constexpr GPUAttachmentType operator+(GPUAttachmentType a, int b)
{
- return static_cast<GPUAttachmentType>(static_cast<int>(a) + b);
+ return static_cast<GPUAttachmentType>(int(a) + b);
}
inline GPUAttachmentType &operator++(GPUAttachmentType &a)
@@ -74,9 +74,9 @@ class FrameBuffer {
/** Set of texture attachments to render to. DEPTH and DEPTH_STENCIL are mutually exclusive. */
GPUAttachment attachments_[GPU_FB_MAX_ATTACHMENT];
/** Is true if internal representation need to be updated. */
- bool dirty_attachments_;
+ bool dirty_attachments_ = true;
/** Size of attachment textures. */
- int width_, height_;
+ int width_ = 0, height_ = 0;
/** Debug name. */
char name_[DEBUG_NAME_LEN];
/** Frame-buffer state. */
@@ -95,11 +95,6 @@ class FrameBuffer {
#endif
public:
- /* Reference of a pointer that needs to be cleaned when deallocating the frame-buffer.
- * Points to #BPyGPUFrameBuffer::fb */
- void **ref = nullptr;
-
- public:
FrameBuffer(const char *name);
virtual ~FrameBuffer();
@@ -209,6 +204,11 @@ class FrameBuffer {
{
return attachments_[GPU_FB_COLOR_ATTACHMENT0 + slot].tex;
};
+
+ inline const char *const name_get() const
+ {
+ return name_;
+ };
};
/* Syntactic sugar. */
diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc
index 3b4accf9cc5..81c0a65bb7c 100644
--- a/source/blender/gpu/intern/gpu_immediate.cc
+++ b/source/blender/gpu/intern/gpu_immediate.cc
@@ -45,7 +45,7 @@ void immBindShader(GPUShader *shader)
BLI_assert(imm->shader == nullptr);
imm->shader = shader;
- imm->builtin_shader_bound = GPU_SHADER_TEXT; /* Default value. */
+ imm->builtin_shader_bound = std::nullopt;
if (!imm->vertex_format.packed) {
VertexFormat_pack(&imm->vertex_format);
@@ -125,9 +125,12 @@ static void wide_line_workaround_start(GPUPrimType prim_type)
/* No need to change the shader. */
return;
}
+ if (!imm->builtin_shader_bound) {
+ return;
+ }
eGPUBuiltinShader polyline_sh;
- switch (imm->builtin_shader_bound) {
+ switch (*imm->builtin_shader_bound) {
case GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR:
polyline_sh = GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR;
break;
@@ -180,8 +183,8 @@ static void wide_line_workaround_end()
}
immUnbindProgram();
- immBindBuiltinProgram(imm->prev_builtin_shader);
- imm->prev_builtin_shader = GPU_SHADER_TEXT;
+ immBindBuiltinProgram(*imm->prev_builtin_shader);
+ imm->prev_builtin_shader = std::nullopt;
}
}
diff --git a/source/blender/gpu/intern/gpu_immediate_private.hh b/source/blender/gpu/intern/gpu_immediate_private.hh
index 74ebbdc7ae3..c4e11e7082b 100644
--- a/source/blender/gpu/intern/gpu_immediate_private.hh
+++ b/source/blender/gpu/intern/gpu_immediate_private.hh
@@ -9,6 +9,8 @@
#pragma once
+#include <optional>
+
#include "GPU_batch.h"
#include "GPU_primitive.h"
#include "GPU_shader.h"
@@ -42,9 +44,9 @@ class Immediate {
/** Wide Line workaround. */
/** Previously bound shader to restore after drawing. */
- eGPUBuiltinShader prev_builtin_shader = GPU_SHADER_TEXT;
- /** Builtin shader index. Used to test if the workaround can be done. */
- eGPUBuiltinShader builtin_shader_bound = GPU_SHADER_TEXT;
+ std::optional<eGPUBuiltinShader> prev_builtin_shader;
+ /** Builtin shader index. Used to test if the line width workaround can be done. */
+ std::optional<eGPUBuiltinShader> builtin_shader_bound;
/** Uniform color: Kept here to update the wide-line shader just before #immBegin. */
float uniform_color[4];
diff --git a/source/blender/gpu/intern/gpu_immediate_util.c b/source/blender/gpu/intern/gpu_immediate_util.c
index 743bc058b45..39b5a6a93c0 100644
--- a/source/blender/gpu/intern/gpu_immediate_util.c
+++ b/source/blender/gpu/intern/gpu_immediate_util.c
@@ -195,7 +195,7 @@ static void imm_draw_circle_partial(GPUPrimType prim_type,
float sweep)
{
/* shift & reverse angle, increase 'nsegments' to match gluPartialDisk */
- const float angle_start = -(DEG2RADF(start)) + (float)M_PI_2;
+ const float angle_start = -DEG2RADF(start) + (float)M_PI_2;
const float angle_end = -(DEG2RADF(sweep) - angle_start);
nsegments += 1;
immBegin(prim_type, nsegments);
@@ -219,7 +219,7 @@ static void imm_draw_circle_partial_3d(GPUPrimType prim_type,
float sweep)
{
/* shift & reverse angle, increase 'nsegments' to match gluPartialDisk */
- const float angle_start = -(DEG2RADF(start)) + (float)(M_PI / 2);
+ const float angle_start = -DEG2RADF(start) + (float)(M_PI / 2);
const float angle_end = -(DEG2RADF(sweep) - angle_start);
nsegments += 1;
immBegin(prim_type, nsegments);
@@ -259,7 +259,7 @@ static void imm_draw_disk_partial(GPUPrimType prim_type,
CLAMP(sweep, -max_angle, max_angle);
/* shift & reverse angle, increase 'nsegments' to match gluPartialDisk */
- const float angle_start = -(DEG2RADF(start)) + (float)M_PI_2;
+ const float angle_start = -DEG2RADF(start) + (float)M_PI_2;
const float angle_end = -(DEG2RADF(sweep) - angle_start);
nsegments += 1;
immBegin(prim_type, nsegments * 2);
@@ -289,7 +289,7 @@ static void imm_draw_disk_partial_3d(GPUPrimType prim_type,
CLAMP(sweep, -max_angle, max_angle);
/* shift & reverse angle, increase 'nsegments' to match gluPartialDisk */
- const float angle_start = -(DEG2RADF(start)) + (float)M_PI_2;
+ const float angle_start = -DEG2RADF(start) + (float)M_PI_2;
const float angle_end = -(DEG2RADF(sweep) - angle_start);
nsegments += 1;
immBegin(prim_type, nsegments * 2);
diff --git a/source/blender/gpu/intern/gpu_index_buffer.cc b/source/blender/gpu/intern/gpu_index_buffer.cc
index 3a66f547403..99e47f5452a 100644
--- a/source/blender/gpu/intern/gpu_index_buffer.cc
+++ b/source/blender/gpu/intern/gpu_index_buffer.cc
@@ -76,7 +76,7 @@ void GPU_indexbuf_init(GPUIndexBufBuilder *builder,
#if TRUST_NO_ONE
assert(verts_per_prim != -1);
#endif
- GPU_indexbuf_init_ex(builder, prim_type, prim_len * (uint)verts_per_prim, vertex_len);
+ GPU_indexbuf_init_ex(builder, prim_type, prim_len * uint(verts_per_prim), vertex_len);
}
GPUIndexBuf *GPU_indexbuf_build_on_device(uint index_len)
@@ -388,13 +388,13 @@ void IndexBuf::squeeze_indices_short(uint min_idx,
0xFFFFu :
(max_idx - min_idx);
for (uint i = 0; i < index_len_; i++) {
- ushort_idx[i] = (uint16_t)MIN2(clamp_max_idx, uint_idx[i] - min_idx);
+ ushort_idx[i] = uint16_t(MIN2(clamp_max_idx, uint_idx[i] - min_idx));
}
}
else {
index_base_ = 0;
for (uint i = 0; i < index_len_; i++) {
- ushort_idx[i] = (uint16_t)(uint_idx[i]);
+ ushort_idx[i] = uint16_t(uint_idx[i]);
}
}
}
diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c
index 34b355eefaf..2dbb4b215bb 100644
--- a/source/blender/gpu/intern/gpu_init_exit.c
+++ b/source/blender/gpu/intern/gpu_init_exit.c
@@ -36,18 +36,10 @@ void GPU_init(void)
gpu_codegen_init();
gpu_batch_init();
-
-#ifndef GPU_STANDALONE
- gpu_pbvh_init();
-#endif
}
void GPU_exit(void)
{
-#ifndef GPU_STANDALONE
- gpu_pbvh_exit();
-#endif
-
gpu_batch_exit();
gpu_codegen_exit();
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 75066b21e7b..ca2a9f5cf28 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -41,15 +41,21 @@
/* Structs */
#define MAX_COLOR_BAND 128
+#define MAX_GPU_SKIES 8
typedef struct GPUColorBandBuilder {
float pixels[MAX_COLOR_BAND][CM_TABLE + 1][4];
int current_layer;
} GPUColorBandBuilder;
+typedef struct GPUSkyBuilder {
+ float pixels[MAX_GPU_SKIES][GPU_SKY_WIDTH * GPU_SKY_HEIGHT][4];
+ int current_layer;
+} GPUSkyBuilder;
+
struct GPUMaterial {
- /* Contains GPUShader and source code for deferred compilation.
- * Can be shared between similar material (i.e: sharing same nodetree topology). */
+ /* Contains #GPUShader and source code for deferred compilation.
+ * Can be shared between similar material (i.e: sharing same node-tree topology). */
GPUPass *pass;
/** UBOs for this material parameters. */
GPUUniformBuf *ubo;
@@ -73,6 +79,10 @@ struct GPUMaterial {
GPUTexture *coba_tex;
/** Builder for coba_tex. */
GPUColorBandBuilder *coba_builder;
+ /** 2D Texture array containing all sky textures. */
+ GPUTexture *sky_tex;
+ /** Builder for sky_tex. */
+ GPUSkyBuilder *sky_builder;
/* Low level node graph(s). Also contains resources needed by the material. */
GPUNodeGraph graph;
@@ -98,6 +108,35 @@ struct GPUMaterial {
/* Functions */
+GPUTexture **gpu_material_sky_texture_layer_set(
+ GPUMaterial *mat, int width, int height, const float *pixels, float *row)
+{
+ /* In order to put all sky textures into one 2D array texture,
+ * we need them to be the same size. */
+ BLI_assert(width == GPU_SKY_WIDTH);
+ BLI_assert(height == GPU_SKY_HEIGHT);
+ UNUSED_VARS_NDEBUG(width, height);
+
+ if (mat->sky_builder == NULL) {
+ mat->sky_builder = MEM_mallocN(sizeof(GPUSkyBuilder), "GPUSkyBuilder");
+ mat->sky_builder->current_layer = 0;
+ }
+
+ int layer = mat->sky_builder->current_layer;
+ *row = (float)layer;
+
+ if (*row == MAX_GPU_SKIES) {
+ printf("Too many sky textures in shader!\n");
+ }
+ else {
+ float *dst = (float *)mat->sky_builder->pixels[layer];
+ memcpy(dst, pixels, sizeof(float) * GPU_SKY_WIDTH * GPU_SKY_HEIGHT * 4);
+ mat->sky_builder->current_layer += 1;
+ }
+
+ return &mat->sky_tex;
+}
+
GPUTexture **gpu_material_ramp_texture_row_set(GPUMaterial *mat,
int size,
float *pixels,
@@ -143,6 +182,24 @@ static void gpu_material_ramp_texture_build(GPUMaterial *mat)
mat->coba_builder = NULL;
}
+static void gpu_material_sky_texture_build(GPUMaterial *mat)
+{
+ if (mat->sky_builder == NULL) {
+ return;
+ }
+
+ mat->sky_tex = GPU_texture_create_2d_array("mat_sky",
+ GPU_SKY_WIDTH,
+ GPU_SKY_HEIGHT,
+ mat->sky_builder->current_layer,
+ 1,
+ GPU_RGBA32F,
+ (float *)mat->sky_builder->pixels);
+
+ MEM_freeN(mat->sky_builder);
+ mat->sky_builder = NULL;
+}
+
void GPU_material_free_single(GPUMaterial *material)
{
bool do_free = atomic_sub_and_fetch_uint32(&material->refcount, 1) == 0;
@@ -161,6 +218,9 @@ void GPU_material_free_single(GPUMaterial *material)
if (material->coba_tex != NULL) {
GPU_texture_free(material->coba_tex);
}
+ if (material->sky_tex != NULL) {
+ GPU_texture_free(material->sky_tex);
+ }
if (material->sss_profile != NULL) {
GPU_uniformbuf_free(material->sss_profile);
}
@@ -231,6 +291,12 @@ const GPUUniformAttrList *GPU_material_uniform_attributes(const GPUMaterial *mat
return attrs->count > 0 ? attrs : NULL;
}
+const ListBase *GPU_material_layer_attributes(const GPUMaterial *material)
+{
+ const ListBase *attrs = &material->graph.layer_attrs;
+ return !BLI_listbase_is_empty(attrs) ? attrs : NULL;
+}
+
#if 1 /* End of life code. */
/* Eevee Subsurface scattering. */
/* Based on Separable SSS. by Jorge Jimenez and Diego Gutierrez */
@@ -684,6 +750,7 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene,
ntreeGPUMaterialNodes(localtree, mat);
gpu_material_ramp_texture_build(mat);
+ gpu_material_sky_texture_build(mat);
{
/* Create source code and search pass cache for an already compiled version. */
diff --git a/source/blender/gpu/intern/gpu_matrix.cc b/source/blender/gpu/intern/gpu_matrix.cc
index 94fd44f832b..b46860cf0f4 100644
--- a/source/blender/gpu/intern/gpu_matrix.cc
+++ b/source/blender/gpu/intern/gpu_matrix.cc
@@ -429,7 +429,7 @@ void GPU_matrix_frustum_set(
void GPU_matrix_perspective_set(float fovy, float aspect, float near, float far)
{
- float half_height = tanf(fovy * (float)(M_PI / 360.0)) * near;
+ float half_height = tanf(fovy * float(M_PI / 360.0)) * near;
float half_width = half_height * aspect;
GPU_matrix_frustum_set(-half_width, +half_width, -half_height, +half_height, near, far);
}
@@ -669,13 +669,13 @@ BLI_STATIC_ASSERT(GPU_PY_MATRIX_STACK_LEN + 1 == MATRIX_STACK_DEPTH, "define mis
int GPU_matrix_stack_level_get_model_view()
{
GPUMatrixState *state = Context::get()->matrix_state;
- return (int)state->model_view_stack.top;
+ return int(state->model_view_stack.top);
}
int GPU_matrix_stack_level_get_projection()
{
GPUMatrixState *state = Context::get()->matrix_state;
- return (int)state->projection_stack.top;
+ return int(state->projection_stack.top);
}
/** \} */
@@ -700,7 +700,7 @@ float GPU_polygon_offset_calc(const float (*winmat)[4], float viewdist, float di
if (depth_fac == 0.0f) {
/* Hard-code for 24 bit precision. */
int depthbits = 24;
- depth_fac = 1.0f / (float)((1 << depthbits) - 1);
+ depth_fac = 1.0f / float((1 << depthbits) - 1);
}
ofs = (-1.0 / winmat[2][2]) * dist * depth_fac;
diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c
index f82af7538b5..c72e7097b33 100644
--- a/source/blender/gpu/intern/gpu_node_graph.c
+++ b/source/blender/gpu/intern/gpu_node_graph.c
@@ -83,6 +83,9 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType
case GPU_SOURCE_UNIFORM_ATTR:
input->uniform_attr->users++;
break;
+ case GPU_SOURCE_LAYER_ATTR:
+ input->layer_attr->users++;
+ break;
case GPU_SOURCE_TEX:
case GPU_SOURCE_TEX_TILED_MAPPING:
input->texture->users++;
@@ -112,6 +115,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType
break;
case GPU_NODE_LINK_IMAGE:
case GPU_NODE_LINK_IMAGE_TILED:
+ case GPU_NODE_LINK_IMAGE_SKY:
case GPU_NODE_LINK_COLORBAND:
input->source = GPU_SOURCE_TEX;
input->texture = link->texture;
@@ -132,6 +136,10 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType
input->source = GPU_SOURCE_UNIFORM_ATTR;
input->uniform_attr = link->uniform_attr;
break;
+ case GPU_NODE_LINK_LAYER_ATTR:
+ input->source = GPU_SOURCE_LAYER_ATTR;
+ input->layer_attr = link->layer_attr;
+ break;
case GPU_NODE_LINK_CONSTANT:
input->source = (type == GPU_CLOSURE) ? GPU_SOURCE_STRUCT : GPU_SOURCE_CONSTANT;
break;
@@ -262,7 +270,7 @@ static int uniform_attr_sort_cmp(const void *a, const void *b)
return (attr_a->use_dupli && !attr_b->use_dupli);
}
-static unsigned int uniform_attr_list_hash(const void *key)
+static uint uniform_attr_list_hash(const void *key)
{
const GPUUniformAttrList *attrs = key;
return attrs->hash_code;
@@ -415,11 +423,6 @@ static GPUUniformAttr *gpu_node_graph_add_uniform_attribute(GPUNodeGraph *graph,
if (attr == NULL && attrs->count < GPU_MAX_UNIFORM_ATTR) {
attr = MEM_callocN(sizeof(*attr), __func__);
STRNCPY(attr->name, name);
- {
- char attr_name_esc[sizeof(attr->name) * 2];
- BLI_str_escape(attr_name_esc, attr->name, sizeof(attr_name_esc));
- SNPRINTF(attr->name_id_prop, "[\"%s\"]", attr_name_esc);
- }
attr->use_dupli = use_dupli;
attr->hash_code = BLI_ghashutil_strhash_p(attr->name) << 1 | (attr->use_dupli ? 0 : 1);
attr->id = -1;
@@ -434,10 +437,39 @@ static GPUUniformAttr *gpu_node_graph_add_uniform_attribute(GPUNodeGraph *graph,
return attr;
}
+/** Add a new uniform attribute of given type and name. Returns NULL if out of slots. */
+static GPULayerAttr *gpu_node_graph_add_layer_attribute(GPUNodeGraph *graph, const char *name)
+{
+ /* Find existing attribute. */
+ ListBase *attrs = &graph->layer_attrs;
+ GPULayerAttr *attr = attrs->first;
+
+ for (; attr; attr = attr->next) {
+ if (STREQ(attr->name, name)) {
+ break;
+ }
+ }
+
+ /* Add new requested attribute to the list. */
+ if (attr == NULL) {
+ attr = MEM_callocN(sizeof(*attr), __func__);
+ STRNCPY(attr->name, name);
+ attr->hash_code = BLI_ghashutil_strhash_p(attr->name);
+ BLI_addtail(attrs, attr);
+ }
+
+ if (attr != NULL) {
+ attr->users++;
+ }
+
+ return attr;
+}
+
static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph,
Image *ima,
ImageUser *iuser,
struct GPUTexture **colorband,
+ struct GPUTexture **sky,
GPUNodeLinkType link_type,
eGPUSamplerState sampler_state)
{
@@ -445,7 +477,8 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph,
int num_textures = 0;
GPUMaterialTexture *tex = graph->textures.first;
for (; tex; tex = tex->next) {
- if (tex->ima == ima && tex->colorband == colorband && tex->sampler_state == sampler_state) {
+ if (tex->ima == ima && tex->colorband == colorband && tex->sky == sky &&
+ tex->sampler_state == sampler_state) {
break;
}
num_textures++;
@@ -460,6 +493,7 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph,
tex->iuser_available = true;
}
tex->colorband = colorband;
+ tex->sky = sky;
tex->sampler_state = sampler_state;
BLI_snprintf(tex->sampler_name, sizeof(tex->sampler_name), "samp%d", num_textures);
if (ELEM(link_type, GPU_NODE_LINK_IMAGE_TILED, GPU_NODE_LINK_IMAGE_TILED_MAPPING)) {
@@ -547,6 +581,17 @@ GPUNodeLink *GPU_uniform_attribute(GPUMaterial *mat,
return link;
}
+GPUNodeLink *GPU_layer_attribute(GPUMaterial *mat, const char *name)
+{
+ GPUNodeGraph *graph = gpu_material_node_graph(mat);
+ GPULayerAttr *attr = gpu_node_graph_add_layer_attribute(graph, name);
+
+ GPUNodeLink *link = gpu_node_link_create();
+ link->link_type = GPU_NODE_LINK_LAYER_ATTR;
+ link->layer_attr = attr;
+ return link;
+}
+
GPUNodeLink *GPU_constant(const float *num)
{
GPUNodeLink *link = gpu_node_link_create();
@@ -580,7 +625,24 @@ GPUNodeLink *GPU_image(GPUMaterial *mat,
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_IMAGE;
link->texture = gpu_node_graph_add_texture(
- graph, ima, iuser, NULL, link->link_type, sampler_state);
+ graph, ima, iuser, NULL, NULL, link->link_type, sampler_state);
+ return link;
+}
+
+GPUNodeLink *GPU_image_sky(GPUMaterial *mat,
+ int width,
+ int height,
+ const float *pixels,
+ float *layer,
+ eGPUSamplerState sampler_state)
+{
+ struct GPUTexture **sky = gpu_material_sky_texture_layer_set(mat, width, height, pixels, layer);
+
+ GPUNodeGraph *graph = gpu_material_node_graph(mat);
+ GPUNodeLink *link = gpu_node_link_create();
+ link->link_type = GPU_NODE_LINK_IMAGE_SKY;
+ link->texture = gpu_node_graph_add_texture(
+ graph, NULL, NULL, NULL, sky, link->link_type, sampler_state);
return link;
}
@@ -593,7 +655,7 @@ GPUNodeLink *GPU_image_tiled(GPUMaterial *mat,
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_IMAGE_TILED;
link->texture = gpu_node_graph_add_texture(
- graph, ima, iuser, NULL, link->link_type, sampler_state);
+ graph, ima, iuser, NULL, NULL, link->link_type, sampler_state);
return link;
}
@@ -603,7 +665,7 @@ GPUNodeLink *GPU_image_tiled_mapping(GPUMaterial *mat, Image *ima, ImageUser *iu
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_IMAGE_TILED_MAPPING;
link->texture = gpu_node_graph_add_texture(
- graph, ima, iuser, NULL, link->link_type, GPU_SAMPLER_MAX);
+ graph, ima, iuser, NULL, NULL, link->link_type, GPU_SAMPLER_MAX);
return link;
}
@@ -616,7 +678,7 @@ GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *ro
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_COLORBAND;
link->texture = gpu_node_graph_add_texture(
- graph, NULL, NULL, colorband, link->link_type, GPU_SAMPLER_MAX);
+ graph, NULL, NULL, colorband, NULL, link->link_type, GPU_SAMPLER_MAX);
return link;
}
@@ -751,14 +813,22 @@ static void gpu_inputs_free(ListBase *inputs)
GPUInput *input;
for (input = inputs->first; input; input = input->next) {
- if (input->source == GPU_SOURCE_ATTR) {
- input->attr->users--;
- }
- else if (input->source == GPU_SOURCE_UNIFORM_ATTR) {
- input->uniform_attr->users--;
- }
- else if (ELEM(input->source, GPU_SOURCE_TEX, GPU_SOURCE_TEX_TILED_MAPPING)) {
- input->texture->users--;
+ switch (input->source) {
+ case GPU_SOURCE_ATTR:
+ input->attr->users--;
+ break;
+ case GPU_SOURCE_UNIFORM_ATTR:
+ input->uniform_attr->users--;
+ break;
+ case GPU_SOURCE_LAYER_ATTR:
+ input->layer_attr->users--;
+ break;
+ case GPU_SOURCE_TEX:
+ case GPU_SOURCE_TEX_TILED_MAPPING:
+ input->texture->users--;
+ break;
+ default:
+ break;
}
if (input->link) {
@@ -810,6 +880,7 @@ void gpu_node_graph_free(GPUNodeGraph *graph)
BLI_freelistN(&graph->textures);
BLI_freelistN(&graph->attributes);
GPU_uniform_attr_list_free(&graph->uniform_attrs);
+ BLI_freelistN(&graph->layer_attrs);
if (graph->used_libraries) {
BLI_gset_free(graph->used_libraries, NULL);
@@ -892,4 +963,10 @@ void gpu_node_graph_prune_unused(GPUNodeGraph *graph)
uattrs->count--;
}
}
+
+ LISTBASE_FOREACH_MUTABLE (GPULayerAttr *, attr, &graph->layer_attrs) {
+ if (attr->users == 0) {
+ BLI_freelinkN(&graph->layer_attrs, attr);
+ }
+ }
}
diff --git a/source/blender/gpu/intern/gpu_node_graph.h b/source/blender/gpu/intern/gpu_node_graph.h
index 74afb721a1c..de0a0687b13 100644
--- a/source/blender/gpu/intern/gpu_node_graph.h
+++ b/source/blender/gpu/intern/gpu_node_graph.h
@@ -31,6 +31,7 @@ typedef enum eGPUDataSource {
GPU_SOURCE_UNIFORM,
GPU_SOURCE_ATTR,
GPU_SOURCE_UNIFORM_ATTR,
+ GPU_SOURCE_LAYER_ATTR,
GPU_SOURCE_STRUCT,
GPU_SOURCE_TEX,
GPU_SOURCE_TEX_TILED_MAPPING,
@@ -42,11 +43,13 @@ typedef enum {
GPU_NODE_LINK_NONE = 0,
GPU_NODE_LINK_ATTR,
GPU_NODE_LINK_UNIFORM_ATTR,
+ GPU_NODE_LINK_LAYER_ATTR,
GPU_NODE_LINK_COLORBAND,
GPU_NODE_LINK_CONSTANT,
GPU_NODE_LINK_IMAGE,
GPU_NODE_LINK_IMAGE_TILED,
GPU_NODE_LINK_IMAGE_TILED_MAPPING,
+ GPU_NODE_LINK_IMAGE_SKY,
GPU_NODE_LINK_OUTPUT,
GPU_NODE_LINK_UNIFORM,
GPU_NODE_LINK_DIFFERENTIATE_FLOAT_FN,
@@ -94,6 +97,8 @@ struct GPUNodeLink {
struct GPUMaterialAttribute *attr;
/* GPU_NODE_LINK_UNIFORM_ATTR */
struct GPUUniformAttr *uniform_attr;
+ /* GPU_NODE_LINK_LAYER_ATTR */
+ struct GPULayerAttr *layer_attr;
/* GPU_NODE_LINK_IMAGE_BLENDER */
struct GPUMaterialTexture *texture;
/* GPU_NODE_LINK_DIFFERENTIATE_FLOAT_FN */
@@ -130,6 +135,8 @@ typedef struct GPUInput {
struct GPUMaterialAttribute *attr;
/* GPU_SOURCE_UNIFORM_ATTR */
struct GPUUniformAttr *uniform_attr;
+ /* GPU_SOURCE_LAYER_ATTR */
+ struct GPULayerAttr *layer_attr;
/* GPU_SOURCE_FUNCTION_CALL */
char function_call[64];
};
@@ -170,6 +177,9 @@ typedef struct GPUNodeGraph {
/* The list of uniform attributes. */
GPUUniformAttrList uniform_attrs;
+ /* The list of layer attributes. */
+ ListBase layer_attrs;
+
/** Set of all the GLSL lib code blocks . */
GSet *used_libraries;
} GPUNodeGraph;
@@ -178,6 +188,7 @@ typedef struct GPUNodeGraph {
void gpu_node_graph_prune_unused(GPUNodeGraph *graph);
void gpu_node_graph_finalize_uniform_attrs(GPUNodeGraph *graph);
+
/**
* Free intermediate node graph.
*/
@@ -197,6 +208,11 @@ struct GPUTexture **gpu_material_ramp_texture_row_set(struct GPUMaterial *mat,
int size,
float *pixels,
float *row);
+/**
+ * Returns the address of the future pointer to sky_tex
+ */
+struct GPUTexture **gpu_material_sky_texture_layer_set(
+ struct GPUMaterial *mat, int width, int height, const float *pixels, float *layer);
#ifdef __cplusplus
}
diff --git a/source/blender/gpu/intern/gpu_shader_builder.cc b/source/blender/gpu/intern/gpu_shader_builder.cc
index 9b699c60126..96e3eacd6f5 100644
--- a/source/blender/gpu/intern/gpu_shader_builder.cc
+++ b/source/blender/gpu/intern/gpu_shader_builder.cc
@@ -15,6 +15,8 @@
#include "GPU_init_exit.h"
#include "gpu_shader_create_info_private.hh"
+#include "BLI_vector.hh"
+
#include "CLG_log.h"
namespace blender::gpu::shader_builder {
@@ -41,11 +43,27 @@ void ShaderBuilder::init()
CLG_init();
GHOST_GLSettings glSettings = {0};
- ghost_system_ = GHOST_CreateSystem();
+ switch (GPU_backend_type_selection_get()) {
+ case GPU_BACKEND_OPENGL:
+ glSettings.context_type = GHOST_kDrawingContextTypeOpenGL;
+ break;
+
+#ifdef WITH_METAL_BACKEND
+ case GPU_BACKEND_METAL:
+ glSettings.context_type = GHOST_kDrawingContextTypeMetal;
+ break;
+#endif
+
+ default:
+ BLI_assert_unreachable();
+ break;
+ }
+
+ ghost_system_ = GHOST_CreateSystemBackground();
ghost_context_ = GHOST_CreateOpenGLContext(ghost_system_, glSettings);
GHOST_ActivateOpenGLContext(ghost_context_);
- gpu_context_ = GPU_context_create(nullptr);
+ gpu_context_ = GPU_context_create(nullptr, ghost_context_);
GPU_init();
}
@@ -73,13 +91,32 @@ int main(int argc, const char *argv[])
int exit_code = 0;
- blender::gpu::shader_builder::ShaderBuilder builder;
- builder.init();
- if (!builder.bake_create_infos()) {
- exit_code = 1;
+ struct NamedBackend {
+ std::string name;
+ eGPUBackendType backend;
+ };
+
+ blender::Vector<NamedBackend> backends_to_validate;
+ backends_to_validate.append({"OpenGL", GPU_BACKEND_OPENGL});
+#ifdef WITH_METAL_BACKEND
+ backends_to_validate.append({"Metal", GPU_BACKEND_METAL});
+#endif
+ for (NamedBackend &backend : backends_to_validate) {
+ GPU_backend_type_selection_set(backend.backend);
+ if (!GPU_backend_supported()) {
+ printf("%s isn't supported on this platform. Shader compilation is skipped\n",
+ backend.name.c_str());
+ continue;
+ }
+ blender::gpu::shader_builder::ShaderBuilder builder;
+ builder.init();
+ if (!builder.bake_create_infos()) {
+ printf("Shader compilation failed for %s backend\n", backend.name.c_str());
+ exit_code = 1;
+ }
+ builder.exit();
}
- builder.exit();
- exit(exit_code);
+ exit(exit_code);
return exit_code;
}
diff --git a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc
index db14d7fbeb9..65bda7ba858 100644
--- a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc
+++ b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc
@@ -41,60 +41,66 @@ UserDef U;
/** \name Stubs of BLI_imbuf_types.h
* \{ */
-void IMB_freeImBuf(ImBuf *UNUSED(ibuf))
+void IMB_freeImBuf(ImBuf * /*ibuf*/)
{
BLI_assert_unreachable();
}
+struct ImBuf *IMB_allocImBuf(unsigned int /*x*/,
+ unsigned int /*y*/,
+ unsigned char /*planes*/,
+ unsigned int /*flags*/)
+{
+ BLI_assert_unreachable();
+ return nullptr;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
/** \name Stubs of UI_resources.h
* \{ */
-void UI_GetThemeColor4fv(int UNUSED(colorid), float UNUSED(col[4]))
+void UI_GetThemeColor4fv(int /*colorid*/, float UNUSED(col[4]))
{
BLI_assert_unreachable();
}
-void UI_GetThemeColor3fv(int UNUSED(colorid), float UNUSED(col[3]))
+void UI_GetThemeColor3fv(int /*colorid*/, float UNUSED(col[3]))
{
BLI_assert_unreachable();
}
-void UI_GetThemeColorShade4fv(int UNUSED(colorid), int UNUSED(offset), float UNUSED(col[4]))
+void UI_GetThemeColorShade4fv(int /*colorid*/, int /*offset*/, float UNUSED(col[4]))
{
BLI_assert_unreachable();
}
-void UI_GetThemeColorShadeAlpha4fv(int UNUSED(colorid),
- int UNUSED(coloffset),
- int UNUSED(alphaoffset),
+void UI_GetThemeColorShadeAlpha4fv(int /*colorid*/,
+ int /*coloffset*/,
+ int /*alphaoffset*/,
float UNUSED(col[4]))
{
BLI_assert_unreachable();
}
-void UI_GetThemeColorBlendShade4fv(int UNUSED(colorid1),
- int UNUSED(colorid2),
- float UNUSED(fac),
- int UNUSED(offset),
- float UNUSED(col[4]))
+void UI_GetThemeColorBlendShade4fv(
+ int /*colorid1*/, int /*colorid2*/, float /*fac*/, int /*offset*/, float UNUSED(col[4]))
{
BLI_assert_unreachable();
}
-void UI_GetThemeColorBlend3ubv(int UNUSED(colorid1),
- int UNUSED(colorid2),
- float UNUSED(fac),
- unsigned char UNUSED(col[3]))
+void UI_GetThemeColorBlend3ubv(int /*colorid1*/,
+ int /*colorid2*/,
+ float /*fac*/,
+ uchar UNUSED(col[3]))
{
BLI_assert_unreachable();
}
-void UI_GetThemeColorShadeAlpha4ubv(int UNUSED(colorid),
- int UNUSED(coloffset),
- int UNUSED(alphaoffset),
- unsigned char UNUSED(col[4]))
+void UI_GetThemeColorShadeAlpha4ubv(int /*colorid*/,
+ int /*coloffset*/,
+ int /*alphaoffset*/,
+ uchar UNUSED(col[4]))
{
BLI_assert_unreachable();
}
@@ -105,28 +111,28 @@ void UI_GetThemeColorShadeAlpha4ubv(int UNUSED(colorid),
/** \name Stubs of BKE_attribute.h
* \{ */
-void BKE_id_attribute_copy_domains_temp(short UNUSED(id_type),
- const struct CustomData *UNUSED(vdata),
- const struct CustomData *UNUSED(edata),
- const struct CustomData *UNUSED(ldata),
- const struct CustomData *UNUSED(pdata),
- const struct CustomData *UNUSED(cdata),
- struct ID *UNUSED(r_id))
+void BKE_id_attribute_copy_domains_temp(short /*id_type*/,
+ const struct CustomData * /*vdata*/,
+ const struct CustomData * /*edata*/,
+ const struct CustomData * /*ldata*/,
+ const struct CustomData * /*pdata*/,
+ const struct CustomData * /*cdata*/,
+ struct ID * /*r_id*/)
{
}
-struct CustomDataLayer *BKE_id_attributes_active_color_get(const struct ID *UNUSED(id))
+struct CustomDataLayer *BKE_id_attributes_active_color_get(const struct ID * /*id*/)
{
return nullptr;
}
-struct CustomDataLayer *BKE_id_attributes_render_color_get(const struct ID *UNUSED(id))
+struct CustomDataLayer *BKE_id_attributes_render_color_get(const struct ID * /*id*/)
{
return nullptr;
}
-eAttrDomain BKE_id_attribute_domain(const struct ID *UNUSED(id),
- const struct CustomDataLayer *UNUSED(layer))
+eAttrDomain BKE_id_attribute_domain(const struct ID * /*id*/,
+ const struct CustomDataLayer * /*layer*/)
{
return ATTR_DOMAIN_AUTO;
}
@@ -136,23 +142,23 @@ eAttrDomain BKE_id_attribute_domain(const struct ID *UNUSED(id),
/* -------------------------------------------------------------------- */
/** \name Stubs of BKE_paint.h
* \{ */
-bool paint_is_face_hidden(const struct MLoopTri *UNUSED(lt), const bool *UNUSED(hide_poly))
+bool paint_is_face_hidden(const struct MLoopTri * /*lt*/, const bool * /*hide_poly*/)
{
BLI_assert_unreachable();
return false;
}
-void BKE_paint_face_set_overlay_color_get(const int UNUSED(face_set),
- const int UNUSED(seed),
+void BKE_paint_face_set_overlay_color_get(const int /*face_set*/,
+ const int /*seed*/,
uchar UNUSED(r_color[4]))
{
BLI_assert_unreachable();
}
-bool paint_is_grid_face_hidden(const unsigned int *UNUSED(grid_hidden),
- int UNUSED(gridsize),
- int UNUSED(x),
- int UNUSED(y))
+bool paint_is_grid_face_hidden(const uint * /*grid_hidden*/,
+ int /*gridsize*/,
+ int /*x*/,
+ int /*y*/)
{
BLI_assert_unreachable();
return false;
@@ -163,16 +169,16 @@ bool paint_is_grid_face_hidden(const unsigned int *UNUSED(grid_hidden),
/* -------------------------------------------------------------------- */
/** \name Stubs of BKE_mesh.h
* \{ */
-void BKE_mesh_calc_poly_normal(const struct MPoly *UNUSED(mpoly),
- const struct MLoop *UNUSED(loopstart),
- const struct MVert *UNUSED(mvarray),
+void BKE_mesh_calc_poly_normal(const struct MPoly * /*mpoly*/,
+ const struct MLoop * /*loopstart*/,
+ const struct MVert * /*mvarray*/,
float UNUSED(r_no[3]))
{
BLI_assert_unreachable();
}
-void BKE_mesh_looptri_get_real_edges(const struct Mesh *UNUSED(mesh),
- const struct MLoopTri *UNUSED(looptri),
+void BKE_mesh_looptri_get_real_edges(const struct Mesh * /*mesh*/,
+ const struct MLoopTri * /*looptri*/,
int UNUSED(r_edges[3]))
{
BLI_assert_unreachable();
@@ -195,42 +201,42 @@ void BKE_material_defaults_free_gpu()
/** \name Stubs of BKE_customdata.h
* \{ */
-int CustomData_get_offset(const struct CustomData *UNUSED(data), int UNUSED(type))
+int CustomData_get_offset(const struct CustomData * /*data*/, int /*type*/)
{
BLI_assert_unreachable();
return 0;
}
-int CustomData_get_named_layer_index(const struct CustomData *UNUSED(data),
- int UNUSED(type),
- const char *UNUSED(name))
+int CustomData_get_named_layer_index(const struct CustomData * /*data*/,
+ int /*type*/,
+ const char * /*name*/)
{
return -1;
}
-int CustomData_get_active_layer_index(const struct CustomData *UNUSED(data), int UNUSED(type))
+int CustomData_get_active_layer_index(const struct CustomData * /*data*/, int /*type*/)
{
return -1;
}
-int CustomData_get_render_layer_index(const struct CustomData *UNUSED(data), int UNUSED(type))
+int CustomData_get_render_layer_index(const struct CustomData * /*data*/, int /*type*/)
{
return -1;
}
-bool CustomData_has_layer(const struct CustomData *UNUSED(data), int UNUSED(type))
+bool CustomData_has_layer(const struct CustomData * /*data*/, int /*type*/)
{
return false;
}
-void *CustomData_get_layer_named(const struct CustomData *UNUSED(data),
- int UNUSED(type),
- const char *UNUSED(name))
+void *CustomData_get_layer_named(const struct CustomData * /*data*/,
+ int /*type*/,
+ const char * /*name*/)
{
return nullptr;
}
-void *CustomData_get_layer(const struct CustomData *UNUSED(data), int UNUSED(type))
+void *CustomData_get_layer(const struct CustomData * /*data*/, int /*type*/)
{
return nullptr;
}
@@ -241,10 +247,10 @@ void *CustomData_get_layer(const struct CustomData *UNUSED(data), int UNUSED(typ
/** \name Stubs of BKE_pbvh.h
* \{ */
-int BKE_pbvh_count_grid_quads(BLI_bitmap **UNUSED(grid_hidden),
- const int *UNUSED(grid_indices),
- int UNUSED(totgrid),
- int UNUSED(gridsize))
+int BKE_pbvh_count_grid_quads(BLI_bitmap ** /*grid_hidden*/,
+ const int * /*grid_indices*/,
+ int /*totgrid*/,
+ int /*gridsize*/)
{
BLI_assert_unreachable();
return 0;
@@ -255,8 +261,7 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **UNUSED(grid_hidden),
/* -------------------------------------------------------------------- */
/** \name Stubs of BKE_subdiv_ccg.h
* \{ */
-int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG *UNUSED(subdiv_ccg),
- const int UNUSED(grid_index))
+int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG * /*subdiv_ccg*/, const int /*grid_index*/)
{
BLI_assert_unreachable();
return 0;
@@ -267,18 +272,18 @@ int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG *UNUSED(subdiv_ccg),
/* -------------------------------------------------------------------- */
/** \name Stubs of BKE_node.h
* \{ */
-void ntreeGPUMaterialNodes(struct bNodeTree *UNUSED(localtree), struct GPUMaterial *UNUSED(mat))
+void ntreeGPUMaterialNodes(struct bNodeTree * /*localtree*/, struct GPUMaterial * /*mat*/)
{
BLI_assert_unreachable();
}
-struct bNodeTree *ntreeLocalize(struct bNodeTree *UNUSED(ntree))
+struct bNodeTree *ntreeLocalize(struct bNodeTree * /*ntree*/)
{
BLI_assert_unreachable();
return nullptr;
}
-void ntreeFreeLocalTree(struct bNodeTree *UNUSED(ntree))
+void ntreeFreeLocalTree(struct bNodeTree * /*ntree*/)
{
BLI_assert_unreachable();
}
@@ -288,7 +293,7 @@ void ntreeFreeLocalTree(struct bNodeTree *UNUSED(ntree))
/* -------------------------------------------------------------------- */
/** \name Stubs of bmesh.h
* \{ */
-void BM_face_as_array_vert_tri(BMFace *UNUSED(f), BMVert *UNUSED(r_verts[3]))
+void BM_face_as_array_vert_tri(BMFace * /*f*/, BMVert *UNUSED(r_verts[3]))
{
BLI_assert_unreachable();
}
@@ -297,17 +302,17 @@ void BM_face_as_array_vert_tri(BMFace *UNUSED(f), BMVert *UNUSED(r_verts[3]))
/* -------------------------------------------------------------------- */
/** \name Stubs of DRW_engine.h
* \{ */
-void DRW_deferred_shader_remove(struct GPUMaterial *UNUSED(mat))
+void DRW_deferred_shader_remove(struct GPUMaterial * /*mat*/)
{
BLI_assert_unreachable();
}
-void DRW_cdlayer_attr_aliases_add(struct GPUVertFormat *UNUSED(format),
- const char *UNUSED(base_name),
- const struct CustomData *UNUSED(data),
- const struct CustomDataLayer *UNUSED(cl),
- bool UNUSED(is_active_render),
- bool UNUSED(is_active_layer))
+void DRW_cdlayer_attr_aliases_add(struct GPUVertFormat * /*format*/,
+ const char * /*base_name*/,
+ const struct CustomData * /*data*/,
+ const struct CustomDataLayer * /*cl*/,
+ bool /*is_active_render*/,
+ bool /*is_active_layer*/)
{
}
diff --git a/source/blender/gpu/intern/gpu_shader_builtin.c b/source/blender/gpu/intern/gpu_shader_builtin.c
index 8a6586e06f6..470643ba863 100644
--- a/source/blender/gpu/intern/gpu_shader_builtin.c
+++ b/source/blender/gpu/intern/gpu_shader_builtin.c
@@ -153,6 +153,11 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
.create_info = "gpu_shader_2D_diag_stripes",
},
+ [GPU_SHADER_ICON] =
+ {
+ .name = "GPU_SHADER_ICON",
+ .create_info = "gpu_shader_icon",
+ },
[GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE] =
{
.name = "GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE",
diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc
index a18fdcd32df..ebbddccbe47 100644
--- a/source/blender/gpu/intern/gpu_shader_create_info.cc
+++ b/source/blender/gpu/intern/gpu_shader_create_info.cc
@@ -284,6 +284,7 @@ void gpu_shader_create_info_init()
_info
/* Declare, register and construct the infos. */
+#include "compositor_shader_create_info_list.hh"
#include "gpu_shader_create_info_list.hh"
/* Baked shader data appended to create infos. */
@@ -305,6 +306,31 @@ void gpu_shader_create_info_init()
draw_resource_id_new = draw_resource_id_fallback;
}
+ /* Metal-specific alternatives for Geometry shaders. */
+ if (GPU_type_matches_ex(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY, GPU_BACKEND_METAL)) {
+
+ /* 3D polyline. */
+ gpu_shader_3D_polyline_uniform_color = gpu_shader_3D_polyline_uniform_color_no_geom;
+ gpu_shader_3D_polyline_flat_color = gpu_shader_3D_polyline_flat_color_no_geom;
+ gpu_shader_3D_polyline_smooth_color = gpu_shader_3D_polyline_smooth_color_no_geom;
+ gpu_shader_3D_polyline_uniform_color_clipped =
+ gpu_shader_3D_polyline_uniform_color_clipped_no_geom;
+
+ /* Overlay Edit Mesh. */
+ overlay_edit_mesh_edge = overlay_edit_mesh_edge_no_geom;
+ overlay_edit_mesh_edge_flat = overlay_edit_mesh_edge_flat_no_geom;
+ overlay_edit_mesh_edge_clipped = overlay_edit_mesh_edge_clipped_no_geom;
+ overlay_edit_mesh_edge_flat_clipped = overlay_edit_mesh_edge_flat_clipped_no_geom;
+
+ /* Overlay Armature Shape outline. */
+ overlay_armature_shape_outline = overlay_armature_shape_outline_no_geom;
+ overlay_armature_shape_outline_clipped = overlay_armature_shape_outline_clipped_no_geom;
+
+ /* Overlay Motion Path Line. */
+ overlay_motion_path_line = overlay_motion_path_line_no_geom;
+ overlay_motion_path_line_clipped = overlay_motion_path_line_clipped_no_geom;
+ }
+
for (ShaderCreateInfo *info : g_create_infos->values()) {
if (info->do_static_compilation_) {
info->builtins_ |= gpu_shader_dependency_get_builtins(info->vertex_source_);
diff --git a/source/blender/gpu/intern/gpu_shader_dependency.cc b/source/blender/gpu/intern/gpu_shader_dependency.cc
index 2c59cb6e501..7d5b8c891b9 100644
--- a/source/blender/gpu/intern/gpu_shader_dependency.cc
+++ b/source/blender/gpu/intern/gpu_shader_dependency.cc
@@ -24,6 +24,7 @@
extern "C" {
#define SHADER_SOURCE(datatoc, filename, filepath) extern char datatoc[];
+#include "glsl_compositor_source_list.h"
#include "glsl_draw_source_list.h"
#include "glsl_gpu_source_list.h"
#ifdef WITH_OCIO
@@ -109,8 +110,7 @@ struct GPUSource {
}
if ((source.find("drw_debug_") != StringRef::not_found) &&
/* Avoid these two files where it makes no sense to add the dependency. */
- (filename != "common_debug_draw_lib.glsl" &&
- filename != "draw_debug_draw_display_vert.glsl")) {
+ !ELEM(filename, "common_debug_draw_lib.glsl", "draw_debug_draw_display_vert.glsl")) {
builtins |= shader::BuiltinBits::USE_DEBUG_DRAW;
}
check_no_quotes();
@@ -141,7 +141,7 @@ struct GPUSource {
if constexpr (check_whole_word) {
/* Fix false positive if something has "enum" as suffix. */
char previous_char = input[offset - 1];
- if (!(ELEM(previous_char, '\n', '\t', ' ', ':', '(', ','))) {
+ if (!ELEM(previous_char, '\n', '\t', ' ', ':', '(', ',')) {
offset += (reversed) ? -1 : 1;
continue;
}
@@ -846,6 +846,7 @@ void gpu_shader_dependency_init()
#define SHADER_SOURCE(datatoc, filename, filepath) \
g_sources->add_new(filename, new GPUSource(filepath, filename, datatoc, g_functions));
+#include "glsl_compositor_source_list.h"
#include "glsl_draw_source_list.h"
#include "glsl_gpu_source_list.h"
#ifdef WITH_OCIO
diff --git a/source/blender/gpu/intern/gpu_shader_interface.cc b/source/blender/gpu/intern/gpu_shader_interface.cc
index 6f43b379d31..d9e5e066fea 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.cc
+++ b/source/blender/gpu/intern/gpu_shader_interface.cc
@@ -22,8 +22,8 @@ ShaderInterface::ShaderInterface() = default;
ShaderInterface::~ShaderInterface()
{
/* Free memory used by name_buffer. */
- MEM_freeN(name_buffer_);
- MEM_freeN(inputs_);
+ MEM_SAFE_FREE(name_buffer_);
+ MEM_SAFE_FREE(inputs_);
}
static void sort_input_list(MutableSpan<ShaderInput> dst)
diff --git a/source/blender/gpu/intern/gpu_shader_interface.hh b/source/blender/gpu/intern/gpu_shader_interface.hh
index 41e06569bdc..d223daa4a61 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.hh
+++ b/source/blender/gpu/intern/gpu_shader_interface.hh
@@ -228,6 +228,8 @@ inline const char *ShaderInterface::builtin_uniform_block_name(GPUUniformBlockBu
return "drw_matrices";
case GPU_UNIFORM_BLOCK_DRW_INFOS:
return "drw_infos";
+ case GPU_UNIFORM_BLOCK_DRW_CLIPPING:
+ return "drw_clipping";
default:
return nullptr;
}
diff --git a/source/blender/gpu/intern/gpu_shader_log.cc b/source/blender/gpu/intern/gpu_shader_log.cc
index dbc36c5afd0..e593c4fa508 100644
--- a/source/blender/gpu/intern/gpu_shader_log.cc
+++ b/source/blender/gpu/intern/gpu_shader_log.cc
@@ -93,10 +93,10 @@ void Shader::print_log(Span<const char *> sources,
}
/* Silence not useful lines. */
- StringRef logref = StringRefNull(log_line).substr(0, (size_t)line_end - (size_t)log_line);
+ StringRef logref = StringRefNull(log_line).substr(0, size_t(line_end) - size_t(log_line));
if (logref.endswith(" shader failed to compile with the following errors:") ||
logref.endswith(" No code generated")) {
- log_line += (size_t)line_end - (size_t)log_line;
+ log_line += size_t(line_end) - size_t(log_line);
continue;
}
@@ -291,7 +291,7 @@ bool GPULogParser::at_any(const char *log_line, const StringRef chars) const
int GPULogParser::parse_number(const char *log_line, char **r_new_position) const
{
- return (int)strtol(log_line, r_new_position, 10);
+ return int(strtol(log_line, r_new_position, 10));
}
/** \} */
diff --git a/source/blender/gpu/intern/gpu_state.cc b/source/blender/gpu/intern/gpu_state.cc
index a1e0b8867a0..8e9d5cb3184 100644
--- a/source/blender/gpu/intern/gpu_state.cc
+++ b/source/blender/gpu/intern/gpu_state.cc
@@ -97,10 +97,10 @@ void GPU_color_mask(bool r, bool g, bool b, bool a)
StateManager *stack = Context::get()->state_manager;
auto &state = stack->state;
uint32_t write_mask = state.write_mask;
- SET_FLAG_FROM_TEST(write_mask, r, (uint32_t)GPU_WRITE_RED);
- SET_FLAG_FROM_TEST(write_mask, g, (uint32_t)GPU_WRITE_GREEN);
- SET_FLAG_FROM_TEST(write_mask, b, (uint32_t)GPU_WRITE_BLUE);
- SET_FLAG_FROM_TEST(write_mask, a, (uint32_t)GPU_WRITE_ALPHA);
+ SET_FLAG_FROM_TEST(write_mask, r, uint32_t(GPU_WRITE_RED));
+ SET_FLAG_FROM_TEST(write_mask, g, uint32_t(GPU_WRITE_GREEN));
+ SET_FLAG_FROM_TEST(write_mask, b, uint32_t(GPU_WRITE_BLUE));
+ SET_FLAG_FROM_TEST(write_mask, a, uint32_t(GPU_WRITE_ALPHA));
state.write_mask = write_mask;
}
@@ -109,7 +109,7 @@ void GPU_depth_mask(bool depth)
StateManager *stack = Context::get()->state_manager;
auto &state = stack->state;
uint32_t write_mask = state.write_mask;
- SET_FLAG_FROM_TEST(write_mask, depth, (uint32_t)GPU_WRITE_DEPTH);
+ SET_FLAG_FROM_TEST(write_mask, depth, uint32_t(GPU_WRITE_DEPTH));
state.write_mask = write_mask;
}
@@ -133,13 +133,13 @@ void GPU_state_set(eGPUWriteMask write_mask,
{
StateManager *stack = Context::get()->state_manager;
auto &state = stack->state;
- state.write_mask = (uint32_t)write_mask;
- state.blend = (uint32_t)blend;
- state.culling_test = (uint32_t)culling_test;
- state.depth_test = (uint32_t)depth_test;
- state.stencil_test = (uint32_t)stencil_test;
- state.stencil_op = (uint32_t)stencil_op;
- state.provoking_vert = (uint32_t)provoking_vert;
+ state.write_mask = uint32_t(write_mask);
+ state.blend = uint32_t(blend);
+ state.culling_test = uint32_t(culling_test);
+ state.depth_test = uint32_t(depth_test);
+ state.stencil_test = uint32_t(stencil_test);
+ state.stencil_op = uint32_t(stencil_op);
+ state.provoking_vert = uint32_t(provoking_vert);
}
/** \} */
@@ -196,17 +196,17 @@ void GPU_viewport(int x, int y, int width, int height)
void GPU_stencil_reference_set(uint reference)
{
- SET_MUTABLE_STATE(stencil_reference, (uint8_t)reference);
+ SET_MUTABLE_STATE(stencil_reference, uint8_t(reference));
}
void GPU_stencil_write_mask_set(uint write_mask)
{
- SET_MUTABLE_STATE(stencil_write_mask, (uint8_t)write_mask);
+ SET_MUTABLE_STATE(stencil_write_mask, uint8_t(write_mask));
}
void GPU_stencil_compare_mask_set(uint compare_mask)
{
- SET_MUTABLE_STATE(stencil_compare_mask, (uint8_t)compare_mask);
+ SET_MUTABLE_STATE(stencil_compare_mask, uint8_t(compare_mask));
}
/** \} */
diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc
index bec8b8a0df3..cd1f8bf582c 100644
--- a/source/blender/gpu/intern/gpu_texture.cc
+++ b/source/blender/gpu/intern/gpu_texture.cc
@@ -132,6 +132,7 @@ bool Texture::init_buffer(GPUVertBuf *vbo, eGPUTextureFormat format)
bool Texture::init_view(const GPUTexture *src_,
eGPUTextureFormat format,
+ eGPUTextureType type,
int mip_start,
int mip_len,
int layer_start,
@@ -144,7 +145,7 @@ bool Texture::init_view(const GPUTexture *src_,
d_ = src->d_;
layer_start = min_ii(layer_start, src->layer_count() - 1);
layer_len = min_ii(layer_len, (src->layer_count() - layer_start));
- switch (src->type_) {
+ switch (type) {
case GPU_TEXTURE_1D_ARRAY:
h_ = layer_len;
break;
@@ -163,8 +164,7 @@ bool Texture::init_view(const GPUTexture *src_,
mipmaps_ = mip_len;
format_ = format;
format_flag_ = to_format_flag(format);
- /* For now always copy the target. Target aliasing could be exposed later. */
- type_ = src->type_;
+ type_ = type;
if (cube_as_array) {
BLI_assert(type_ & GPU_TEXTURE_CUBE);
type_ = (type_ & ~GPU_TEXTURE_CUBE) | GPU_TEXTURE_2D_ARRAY;
@@ -404,7 +404,26 @@ GPUTexture *GPU_texture_create_view(const char *name,
BLI_assert(mip_len > 0);
BLI_assert(layer_len > 0);
Texture *view = GPUBackend::get()->texture_alloc(name);
- view->init_view(src, format, mip_start, mip_len, layer_start, layer_len, cube_as_array);
+ view->init_view(src,
+ format,
+ unwrap(src)->type_get(),
+ mip_start,
+ mip_len,
+ layer_start,
+ layer_len,
+ cube_as_array);
+ return wrap(view);
+}
+
+GPUTexture *GPU_texture_create_single_layer_view(const char *name, const GPUTexture *src)
+{
+ eGPUTextureFormat format = unwrap(src)->format_get();
+ eGPUTextureType type = unwrap(src)->type_get();
+ BLI_assert(ELEM(type, GPU_TEXTURE_1D, GPU_TEXTURE_2D, GPU_TEXTURE_CUBE));
+ type |= GPU_TEXTURE_ARRAY;
+
+ Texture *view = GPUBackend::get()->texture_alloc(name);
+ view->init_view(src, format, type, 0, 9999, 0, 1, false);
return wrap(view);
}
@@ -463,7 +482,7 @@ void GPU_unpack_row_length_set(uint len)
void GPU_texture_bind_ex(GPUTexture *tex_,
eGPUSamplerState state,
int unit,
- const bool UNUSED(set_number))
+ const bool /*set_number*/)
{
Texture *tex = reinterpret_cast<Texture *>(tex_);
state = (state >= GPU_SAMPLER_MAX) ? tex->sampler_state : state;
diff --git a/source/blender/gpu/intern/gpu_texture_private.hh b/source/blender/gpu/intern/gpu_texture_private.hh
index 8521b0fd77f..124b1751b96 100644
--- a/source/blender/gpu/intern/gpu_texture_private.hh
+++ b/source/blender/gpu/intern/gpu_texture_private.hh
@@ -108,6 +108,7 @@ class Texture {
bool init_buffer(GPUVertBuf *vbo, eGPUTextureFormat format);
bool init_view(const GPUTexture *src,
eGPUTextureFormat format,
+ eGPUTextureType type,
int mip_start,
int mip_len,
int layer_start,
@@ -430,15 +431,16 @@ inline bool validate_data_format(eGPUTextureFormat tex_format, eGPUDataFormat da
case GPU_DEPTH_COMPONENT24:
case GPU_DEPTH_COMPONENT16:
case GPU_DEPTH_COMPONENT32F:
- return data_format == GPU_DATA_FLOAT;
+ return ELEM(data_format, GPU_DATA_FLOAT, GPU_DATA_UINT);
case GPU_DEPTH24_STENCIL8:
case GPU_DEPTH32F_STENCIL8:
- return data_format == GPU_DATA_UINT_24_8;
+ return ELEM(data_format, GPU_DATA_UINT_24_8, GPU_DATA_UINT);
case GPU_R8UI:
case GPU_R16UI:
case GPU_RG16UI:
case GPU_R32UI:
return data_format == GPU_DATA_UINT;
+ case GPU_R32I:
case GPU_RG16I:
case GPU_R16I:
return data_format == GPU_DATA_INT;
@@ -452,6 +454,8 @@ inline bool validate_data_format(eGPUTextureFormat tex_format, eGPUDataFormat da
return ELEM(data_format, GPU_DATA_2_10_10_10_REV, GPU_DATA_FLOAT);
case GPU_R11F_G11F_B10F:
return ELEM(data_format, GPU_DATA_10_11_11_REV, GPU_DATA_FLOAT);
+ case GPU_RGBA16F:
+ return ELEM(data_format, GPU_DATA_HALF_FLOAT, GPU_DATA_FLOAT);
default:
return data_format == GPU_DATA_FLOAT;
}
@@ -584,7 +588,7 @@ inline eGPUFrameBufferBits to_framebuffer_bits(eGPUTextureFormat tex_format)
static inline eGPUTextureFormat to_texture_format(const GPUVertFormat *format)
{
- if (format->attr_len > 1 || format->attr_len == 0) {
+ if (format->attr_len == 0) {
BLI_assert_msg(0, "Incorrect vertex format for buffer texture");
return GPU_DEPTH_COMPONENT24;
}
diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.cc b/source/blender/gpu/intern/gpu_vertex_buffer.cc
index a441cfe2fb8..abf5d2dc4c0 100644
--- a/source/blender/gpu/intern/gpu_vertex_buffer.cc
+++ b/source/blender/gpu/intern/gpu_vertex_buffer.cc
@@ -278,7 +278,7 @@ void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *verts_, uint a_idx, GPUVertBufRaw
access->data = (uchar *)verts->data + a->offset;
access->data_init = access->data;
#ifdef DEBUG
- access->_data_end = access->data_init + (size_t)(verts->vertex_alloc * format->stride);
+ access->_data_end = access->data_init + size_t(verts->vertex_alloc * format->stride);
#endif
}
diff --git a/source/blender/gpu/intern/gpu_vertex_format.cc b/source/blender/gpu/intern/gpu_vertex_format.cc
index 897e80293bf..76d95ac1b55 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.cc
+++ b/source/blender/gpu/intern/gpu_vertex_format.cc
@@ -251,7 +251,7 @@ static void safe_bytes(char out[11], const char data[8])
}
}
-void GPU_vertformat_safe_attr_name(const char *attr_name, char *r_safe_name, uint UNUSED(max_len))
+void GPU_vertformat_safe_attr_name(const char *attr_name, char *r_safe_name, uint /*max_len*/)
{
char data[8] = {0};
uint len = strlen(attr_name);
@@ -361,8 +361,12 @@ void VertexFormat_texture_buffer_pack(GPUVertFormat *format)
* minimum per-vertex stride, which mandates 4-byte alignment in Metal.
* This additional alignment padding caused smaller data types, e.g. U16,
* to mis-align. */
- BLI_assert_msg(format->attr_len == 1,
- "Texture buffer mode should only use a single vertex attribute.");
+ for (int i = 0; i < format->attr_len; i++) {
+ /* The buffer texture setup uses the first attribute for type and size.
+ * Make sure all attributes use the same size. */
+ BLI_assert_msg(format->attrs[i].size == format->attrs[0].size,
+ "Texture buffer mode should only use a attributes with the same size.");
+ }
/* Pack vertex format without minimum stride, as this is not required by texture buffers. */
VertexFormat_pack_impl(format, 1);
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index 71bdf9e336b..e267d5a2f12 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -147,6 +147,10 @@ static void gpu_viewport_textures_create(GPUViewport *viewport)
if (viewport->depth_tx == NULL) {
viewport->depth_tx = GPU_texture_create_2d(
"dtxl_depth", UNPACK2(size), 1, GPU_DEPTH24_STENCIL8, NULL);
+ if (GPU_clear_viewport_workaround()) {
+ static int depth_clear = 0;
+ GPU_texture_clear(viewport->depth_tx, GPU_DATA_UINT_24_8, &depth_clear);
+ }
}
if (!viewport->depth_tx || !viewport->color_render_tx[0] || !viewport->color_overlay_tx[0]) {
diff --git a/source/blender/gpu/metal/mtl_backend.hh b/source/blender/gpu/metal/mtl_backend.hh
index 214a5d738a9..082fab24ba4 100644
--- a/source/blender/gpu/metal/mtl_backend.hh
+++ b/source/blender/gpu/metal/mtl_backend.hh
@@ -63,7 +63,7 @@ class MTLBackend : public GPUBackend {
/* MTL Allocators need to be implemented in separate .mm files, due to allocation of Objective-C
* objects. */
- Context *context_alloc(void *ghost_window) override;
+ Context *context_alloc(void *ghost_window, void *ghost_context) override;
Batch *batch_alloc() override;
DrawList *drawlist_alloc(int list_length) override;
FrameBuffer *framebuffer_alloc(const char *name) override;
diff --git a/source/blender/gpu/metal/mtl_backend.mm b/source/blender/gpu/metal/mtl_backend.mm
index 3cd7794f6c9..240951c1ebd 100644
--- a/source/blender/gpu/metal/mtl_backend.mm
+++ b/source/blender/gpu/metal/mtl_backend.mm
@@ -8,12 +8,16 @@
#include "gpu_backend.hh"
#include "mtl_backend.hh"
+#include "mtl_batch.hh"
#include "mtl_context.hh"
+#include "mtl_drawlist.hh"
#include "mtl_framebuffer.hh"
+#include "mtl_immediate.hh"
#include "mtl_index_buffer.hh"
#include "mtl_query.hh"
#include "mtl_shader.hh"
#include "mtl_uniform_buffer.hh"
+#include "mtl_vertex_buffer.hh"
#include "gpu_capabilities_private.hh"
#include "gpu_platform_private.hh"
@@ -36,21 +40,19 @@ void MTLBackend::samplers_update(){
/* Placeholder -- Handled in MTLContext. */
};
-Context *MTLBackend::context_alloc(void *ghost_window)
+Context *MTLBackend::context_alloc(void *ghost_window, void *ghost_context)
{
- return new MTLContext(ghost_window);
+ return new MTLContext(ghost_window, ghost_context);
};
Batch *MTLBackend::batch_alloc()
{
- /* TODO(Metal): Implement MTLBatch. */
- return nullptr;
+ return new MTLBatch();
};
DrawList *MTLBackend::drawlist_alloc(int list_length)
{
- /* TODO(Metal): Implement MTLDrawList. */
- return nullptr;
+ return new MTLDrawList(list_length);
};
FrameBuffer *MTLBackend::framebuffer_alloc(const char *name)
@@ -94,8 +96,7 @@ StorageBuf *MTLBackend::storagebuf_alloc(int size, GPUUsageType usage, const cha
VertBuf *MTLBackend::vertbuf_alloc()
{
- /* TODO(Metal): Implement MTLVertBuf. */
- return nullptr;
+ return new MTLVertBuf();
}
void MTLBackend::render_begin()
@@ -417,6 +418,7 @@ void MTLBackend::capabilities_init(MTLContext *ctx)
GCaps.depth_blitting_workaround = false;
GCaps.use_main_context_workaround = false;
GCaps.broken_amd_driver = false;
+ GCaps.clear_viewport_workaround = true;
/* Metal related workarounds. */
/* Minimum per-vertex stride is 4 bytes in Metal.
diff --git a/source/blender/gpu/metal/mtl_batch.hh b/source/blender/gpu/metal/mtl_batch.hh
new file mode 100644
index 00000000000..9e179e662b5
--- /dev/null
+++ b/source/blender/gpu/metal/mtl_batch.hh
@@ -0,0 +1,135 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup gpu
+ *
+ * GPU geometry batch
+ * Contains VAOs + VBOs + Shader representing a drawable entity.
+ */
+
+#pragma once
+
+#include "MEM_guardedalloc.h"
+#include "gpu_batch_private.hh"
+#include "mtl_index_buffer.hh"
+#include "mtl_primitive.hh"
+#include "mtl_shader.hh"
+#include "mtl_vertex_buffer.hh"
+
+namespace blender::gpu {
+
+class MTLContext;
+class MTLShaderInterface;
+
+#define GPU_VAO_STATIC_LEN 64
+
+struct VertexBufferID {
+ uint32_t id : 16;
+ uint32_t is_instance : 15;
+ uint32_t used : 1;
+};
+
+class MTLBatch : public Batch {
+
+ /* Vertex Bind-state Caching for a given shader interface used with the Batch. */
+ struct VertexDescriptorShaderInterfacePair {
+ MTLVertexDescriptor vertex_descriptor{};
+ const ShaderInterface *interface = nullptr;
+ uint16_t attr_mask{};
+ int num_buffers{};
+ VertexBufferID bufferIds[GPU_BATCH_VBO_MAX_LEN] = {};
+ /* Cache life index compares a cache entry with the active MTLBatch state.
+ * This is initially set to the cache life index of MTLBatch. If the batch has been modified,
+ * this index is incremented to cheaply invalidate existing cache entries. */
+ uint32_t cache_life_index = 0;
+ };
+
+ class MTLVertexDescriptorCache {
+
+ private:
+ MTLBatch *batch_;
+
+ VertexDescriptorShaderInterfacePair cache_[GPU_VAO_STATIC_LEN] = {};
+ MTLContext *cache_context_ = nullptr;
+ uint32_t cache_life_index_ = 0;
+
+ public:
+ MTLVertexDescriptorCache(MTLBatch *batch) : batch_(batch){};
+ VertexDescriptorShaderInterfacePair *find(const ShaderInterface *interface);
+ bool insert(VertexDescriptorShaderInterfacePair &data);
+
+ private:
+ void vertex_descriptor_cache_init(MTLContext *ctx);
+ void vertex_descriptor_cache_clear();
+ void vertex_descriptor_cache_ensure();
+ };
+
+ private:
+ MTLShader *active_shader_ = nullptr;
+ bool shader_in_use_ = false;
+ MTLVertexDescriptorCache vao_cache = {this};
+
+ /* Topology emulation. */
+ gpu::MTLBuffer *emulated_topology_buffer_ = nullptr;
+ GPUPrimType emulated_topology_type_;
+ uint32_t topology_buffer_input_v_count_ = 0;
+ uint32_t topology_buffer_output_v_count_ = 0;
+
+ public:
+ MTLBatch(){};
+ ~MTLBatch(){};
+
+ void draw(int v_first, int v_count, int i_first, int i_count) override;
+ void draw_indirect(GPUStorageBuf *indirect_buf, intptr_t offset) override
+ {
+ /* TODO(Metal): Support indirect draw commands. */
+ }
+ void multi_draw_indirect(GPUStorageBuf *indirect_buf,
+ int count,
+ intptr_t offset,
+ intptr_t stride) override
+ {
+ /* TODO(Metal): Support indirect draw commands. */
+ }
+
+ /* Returns an initialized RenderComandEncoder for drawing if all is good.
+ * Otherwise, nil. */
+ id<MTLRenderCommandEncoder> bind(uint v_first, uint v_count, uint i_first, uint i_count);
+ void unbind();
+
+ /* Convenience getters. */
+ MTLIndexBuf *elem_() const
+ {
+ return static_cast<MTLIndexBuf *>(unwrap(elem));
+ }
+ MTLVertBuf *verts_(const int index) const
+ {
+ return static_cast<MTLVertBuf *>(unwrap(verts[index]));
+ }
+ MTLVertBuf *inst_(const int index) const
+ {
+ return static_cast<MTLVertBuf *>(unwrap(inst[index]));
+ }
+ MTLShader *active_shader_get() const
+ {
+ return active_shader_;
+ }
+
+ private:
+ void shader_bind();
+ void draw_advanced(int v_first, int v_count, int i_first, int i_count);
+ int prepare_vertex_binding(MTLVertBuf *verts,
+ MTLRenderPipelineStateDescriptor &desc,
+ const MTLShaderInterface *interface,
+ uint16_t &attr_mask,
+ bool instanced);
+
+ id<MTLBuffer> get_emulated_toplogy_buffer(GPUPrimType &in_out_prim_type, uint32_t &v_count);
+
+ void prepare_vertex_descriptor_and_bindings(
+ MTLVertBuf **buffers, int &num_buffers, int v_first, int v_count, int i_first, int i_count);
+
+ MEM_CXX_CLASS_ALLOC_FUNCS("MTLBatch");
+};
+
+} // namespace blender::gpu
diff --git a/source/blender/gpu/metal/mtl_batch.mm b/source/blender/gpu/metal/mtl_batch.mm
new file mode 100644
index 00000000000..988fb9b793b
--- /dev/null
+++ b/source/blender/gpu/metal/mtl_batch.mm
@@ -0,0 +1,998 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup gpu
+ *
+ * Metal implementation of GPUBatch.
+ */
+
+#include "BLI_assert.h"
+#include "BLI_span.hh"
+
+#include "BKE_global.h"
+
+#include "GPU_common.h"
+#include "gpu_batch_private.hh"
+#include "gpu_shader_private.hh"
+
+#include "mtl_batch.hh"
+#include "mtl_context.hh"
+#include "mtl_debug.hh"
+#include "mtl_index_buffer.hh"
+#include "mtl_shader.hh"
+#include "mtl_vertex_buffer.hh"
+
+#include <string>
+
+namespace blender::gpu {
+
+/* -------------------------------------------------------------------- */
+/** \name Creation & Deletion
+ * \{ */
+void MTLBatch::draw(int v_first, int v_count, int i_first, int i_count)
+{
+ if (this->flag & GPU_BATCH_INVALID) {
+ this->shader_in_use_ = false;
+ }
+ this->draw_advanced(v_first, v_count, i_first, i_count);
+}
+
+void MTLBatch::shader_bind()
+{
+ if (active_shader_ && active_shader_->is_valid()) {
+ active_shader_->bind();
+ shader_in_use_ = true;
+ }
+}
+
+void MTLBatch::MTLVertexDescriptorCache::vertex_descriptor_cache_init(MTLContext *ctx)
+{
+ BLI_assert(ctx != nullptr);
+ this->vertex_descriptor_cache_clear();
+ cache_context_ = ctx;
+}
+
+void MTLBatch::MTLVertexDescriptorCache::vertex_descriptor_cache_clear()
+{
+ cache_life_index_++;
+ cache_context_ = nullptr;
+}
+
+void MTLBatch::MTLVertexDescriptorCache::vertex_descriptor_cache_ensure()
+{
+ if (this->cache_context_ != nullptr) {
+
+ /* Invalidate vertex descriptor bindings cache if batch has changed. */
+ if (batch_->flag & GPU_BATCH_DIRTY) {
+ batch_->flag &= ~GPU_BATCH_DIRTY;
+ this->vertex_descriptor_cache_clear();
+ }
+ }
+
+ /* Initialize cache if not ready. */
+ if (cache_context_ == nullptr) {
+ this->vertex_descriptor_cache_init(MTLContext::get());
+ }
+}
+
+MTLBatch::VertexDescriptorShaderInterfacePair *MTLBatch::MTLVertexDescriptorCache::find(
+ const ShaderInterface *interface)
+{
+ this->vertex_descriptor_cache_ensure();
+ for (int i = 0; i < GPU_VAO_STATIC_LEN; ++i) {
+ if (cache_[i].interface == interface && cache_[i].cache_life_index == cache_life_index_) {
+ return &cache_[i];
+ }
+ }
+ return nullptr;
+}
+
+bool MTLBatch::MTLVertexDescriptorCache::insert(
+ MTLBatch::VertexDescriptorShaderInterfacePair &data)
+{
+ vertex_descriptor_cache_ensure();
+ for (int i = 0; i < GPU_VAO_STATIC_LEN; ++i) {
+ if (cache_[i].interface == nullptr || cache_[i].cache_life_index != cache_life_index_) {
+ cache_[i] = data;
+ cache_[i].cache_life_index = cache_life_index_;
+ return true;
+ }
+ }
+ return false;
+}
+
+int MTLBatch::prepare_vertex_binding(MTLVertBuf *verts,
+ MTLRenderPipelineStateDescriptor &desc,
+ const MTLShaderInterface *interface,
+ uint16_t &attr_mask,
+ bool instanced)
+{
+
+ const GPUVertFormat *format = &verts->format;
+ /* Whether the current vertex buffer has been added to the buffer layout descriptor. */
+ bool buffer_added = false;
+ /* Per-vertex stride of current vertex buffer. */
+ int buffer_stride = format->stride;
+ /* Buffer binding index of the vertex buffer once added to the buffer layout descriptor. */
+ int buffer_index = -1;
+ int attribute_offset = 0;
+
+ if (!active_shader_->get_uses_ssbo_vertex_fetch()) {
+ BLI_assert(
+ buffer_stride >= 4 &&
+ "In Metal, Vertex buffer stride should be 4. SSBO Vertex fetch is not affected by this");
+ }
+
+ /* Iterate over GPUVertBuf vertex format and find attributes matching those in the active
+ * shader's interface. */
+ for (uint32_t a_idx = 0; a_idx < format->attr_len; a_idx++) {
+ const GPUVertAttr *a = &format->attrs[a_idx];
+
+ if (format->deinterleaved) {
+ attribute_offset += ((a_idx == 0) ? 0 : format->attrs[a_idx - 1].size) * verts->vertex_len;
+ buffer_stride = a->size;
+ }
+ else {
+ attribute_offset = a->offset;
+ }
+
+ /* Find attribute with the matching name. Attributes may have multiple compatible
+ * name aliases. */
+ for (uint32_t n_idx = 0; n_idx < a->name_len; n_idx++) {
+ const char *name = GPU_vertformat_attr_name_get(format, a, n_idx);
+ const ShaderInput *input = interface->attr_get(name);
+
+ if (input == nullptr || input->location == -1) {
+ /* Vertex/instance buffers provided have attribute data for attributes which are not needed
+ * by this particular shader. This shader only needs binding information for the attributes
+ * has in the shader interface. */
+ MTL_LOG_WARNING(
+ "MTLBatch: Could not find attribute with name '%s' (defined in active vertex format) "
+ "in the shader interface for shader '%s'\n",
+ name,
+ interface->get_name());
+ continue;
+ }
+
+ /* Fetch metal attribute information. */
+ const MTLShaderInputAttribute &mtl_attr = interface->get_attribute(input->location);
+ BLI_assert(mtl_attr.location >= 0);
+ /* Verify that the attribute location from the shader interface
+ * matches the attribute location returned. */
+ BLI_assert(mtl_attr.location == input->location);
+
+ /* Check if attribute is already present in the given slot. */
+ if ((~attr_mask) & (1 << mtl_attr.location)) {
+ MTL_LOG_INFO(
+ " -- [Batch] Skipping attribute with input location %d (As one is already bound)\n",
+ mtl_attr.location);
+ }
+ else {
+
+ /* Update attribute used-slot mask. */
+ attr_mask &= ~(1 << mtl_attr.location);
+
+ /* Add buffer layout entry in descriptor if it has not yet been added
+ * for current vertex buffer. */
+ if (!buffer_added) {
+ buffer_index = desc.vertex_descriptor.num_vert_buffers;
+ desc.vertex_descriptor.buffer_layouts[buffer_index].step_function =
+ (instanced) ? MTLVertexStepFunctionPerInstance : MTLVertexStepFunctionPerVertex;
+ desc.vertex_descriptor.buffer_layouts[buffer_index].step_rate = 1;
+ desc.vertex_descriptor.buffer_layouts[buffer_index].stride = buffer_stride;
+ desc.vertex_descriptor.num_vert_buffers++;
+ buffer_added = true;
+
+ MTL_LOG_INFO(" -- [Batch] Adding source %s buffer (Index: %d, Stride: %d)\n",
+ (instanced) ? "instance" : "vertex",
+ buffer_index,
+ buffer_stride);
+ }
+ else {
+ /* Ensure stride is correct for de-interleaved attributes. */
+ desc.vertex_descriptor.buffer_layouts[buffer_index].stride = buffer_stride;
+ }
+
+ /* Handle Matrix/Array vertex attribute types.
+ * Metal does not natively support these as attribute types, so we handle these cases
+ * by stacking together compatible types (e.g. 4xVec4 for Mat4) and combining
+ * the data in the shader.
+ * The generated Metal shader will contain a generated input binding, which reads
+ * in individual attributes and merges them into the desired type after vertex
+ * assembly. e.g. a Mat4 (Float4x4) will generate 4 Float4 attributes. */
+ if (a->comp_len == 16 || a->comp_len == 12 || a->comp_len == 8) {
+ BLI_assert_msg(
+ a->comp_len == 16,
+ "only mat4 attributes currently supported -- Not ready to handle other long "
+ "component length attributes yet");
+
+ /* SSBO Vertex Fetch Attribute safety checks. */
+ if (active_shader_->get_uses_ssbo_vertex_fetch()) {
+ /* When using SSBO vertex fetch, we do not need to expose split attributes,
+ * A matrix can be read directly as a whole block of contiguous data. */
+ MTLSSBOAttribute ssbo_attr(mtl_attr.index,
+ buffer_index,
+ attribute_offset,
+ buffer_stride,
+ GPU_SHADER_ATTR_TYPE_MAT4,
+ instanced);
+ active_shader_->ssbo_vertex_fetch_bind_attribute(ssbo_attr);
+ desc.vertex_descriptor.ssbo_attributes[desc.vertex_descriptor.num_ssbo_attributes] =
+ ssbo_attr;
+ desc.vertex_descriptor.num_ssbo_attributes++;
+ }
+ else {
+
+ /* Handle Mat4 attributes. */
+ if (a->comp_len == 16) {
+ /* Debug safety checks. */
+ BLI_assert_msg(mtl_attr.matrix_element_count == 4,
+ "mat4 type expected but there are fewer components");
+ BLI_assert_msg(mtl_attr.size == 16, "Expecting subtype 'vec4' with 16 bytes");
+ BLI_assert_msg(
+ mtl_attr.format == MTLVertexFormatFloat4,
+ "Per-attribute vertex format MUST be float4 for an input type of 'mat4'");
+
+ /* We have found the 'ROOT' attribute. A mat4 contains 4 consecutive float4 attribute
+ * locations we must map to. */
+ for (int i = 0; i < a->comp_len / 4; i++) {
+ desc.vertex_descriptor.attributes[mtl_attr.location + i].format =
+ MTLVertexFormatFloat4;
+ /* Data is consecutive in the buffer for the whole matrix, each float4 will shift
+ * the offset by 16 bytes. */
+ desc.vertex_descriptor.attributes[mtl_attr.location + i].offset =
+ attribute_offset + i * 16;
+ /* All source data for a matrix is in the same singular buffer. */
+ desc.vertex_descriptor.attributes[mtl_attr.location + i].buffer_index =
+ buffer_index;
+
+ /* Update total attribute account. */
+ desc.vertex_descriptor.num_attributes = max_ii(
+ mtl_attr.location + i + 1, desc.vertex_descriptor.num_attributes);
+ MTL_LOG_INFO("-- Sub-Attrib Location: %d, offset: %d, buffer index: %d\n",
+ mtl_attr.location + i,
+ attribute_offset + i * 16,
+ buffer_index);
+ }
+ MTL_LOG_INFO(
+ "Float4x4 attribute type added for '%s' at attribute locations: %d to %d\n",
+ name,
+ mtl_attr.location,
+ mtl_attr.location + 3);
+ }
+
+ /* Ensure we are not exceeding the attribute limit. */
+ BLI_assert(desc.vertex_descriptor.num_attributes <= MTL_MAX_VERTEX_INPUT_ATTRIBUTES);
+ }
+ }
+ else {
+
+ /* Handle Any required format conversions.
+ * NOTE(Metal): If there is a mis-match between the format of an attribute
+ * in the shader interface, and the specified format in the VertexBuffer VertexFormat,
+ * we need to perform a format conversion.
+ *
+ * The Metal API can perform certain conversions internally during vertex assembly:
+ * - Type Normalization e.g short2 to float2 between 0.0 to 1.0.
+ * - Type Truncation e.g. Float4 to Float2.
+ * - Type expansion e,g, Float3 to Float4 (Following 0,0,0,1 for assignment to empty
+ * elements).
+ *
+ * Certain conversion cannot be performed however, and in these cases, we need to
+ * instruct the shader to generate a specialized version with a conversion routine upon
+ * attribute read.
+ * - This handles cases such as conversion between types e.g. Integer to float without
+ * normalization.
+ *
+ * For more information on the supported and unsupported conversions, see:
+ * https://developer.apple.com/documentation/metal/mtlvertexattributedescriptor/1516081-format?language=objc
+ */
+ MTLVertexFormat converted_format;
+ bool can_use_internal_conversion = mtl_convert_vertex_format(
+ mtl_attr.format,
+ (GPUVertCompType)a->comp_type,
+ a->comp_len,
+ (GPUVertFetchMode)a->fetch_mode,
+ &converted_format);
+ bool is_floating_point_format = (a->comp_type == GPU_COMP_F32);
+
+ if (can_use_internal_conversion) {
+ desc.vertex_descriptor.attributes[mtl_attr.location].format = converted_format;
+ desc.vertex_descriptor.attributes[mtl_attr.location].format_conversion_mode =
+ is_floating_point_format ? (GPUVertFetchMode)GPU_FETCH_FLOAT :
+ (GPUVertFetchMode)GPU_FETCH_INT;
+ BLI_assert(converted_format != MTLVertexFormatInvalid);
+ }
+ else {
+ /* The internal implicit conversion is not supported.
+ * In this case, we need to handle conversion inside the shader.
+ * This is handled using `format_conversion_mode`.
+ * `format_conversion_mode` is assigned the blender-specified fetch mode (GPU_FETCH_*).
+ * This then controls how a given attribute is interpreted. The data will be read
+ * as specified and then converted appropriately to the correct form.
+ *
+ * e.g. if `GPU_FETCH_INT_TO_FLOAT` is specified, the specialized read-routine
+ * in the shader will read the data as an int, and cast this to floating point
+ * representation. (Rather than reading the source data as float).
+ *
+ * NOTE: Even if full conversion is not supported, we may still partially perform an
+ * implicit conversion where possible, such as vector truncation or expansion. */
+ MTLVertexFormat converted_format;
+ bool can_convert = mtl_vertex_format_resize(
+ mtl_attr.format, a->comp_len, &converted_format);
+ desc.vertex_descriptor.attributes[mtl_attr.location].format = can_convert ?
+ converted_format :
+ mtl_attr.format;
+ desc.vertex_descriptor.attributes[mtl_attr.location].format_conversion_mode =
+ (GPUVertFetchMode)a->fetch_mode;
+ BLI_assert(desc.vertex_descriptor.attributes[mtl_attr.location].format !=
+ MTLVertexFormatInvalid);
+ }
+ desc.vertex_descriptor.attributes[mtl_attr.location].offset = attribute_offset;
+ desc.vertex_descriptor.attributes[mtl_attr.location].buffer_index = buffer_index;
+ desc.vertex_descriptor.num_attributes = ((mtl_attr.location + 1) >
+ desc.vertex_descriptor.num_attributes) ?
+ (mtl_attr.location + 1) :
+ desc.vertex_descriptor.num_attributes;
+
+ /* SSBO Vertex Fetch attribute bind. */
+ if (active_shader_->get_uses_ssbo_vertex_fetch()) {
+ BLI_assert_msg(desc.vertex_descriptor.attributes[mtl_attr.location].format ==
+ mtl_attr.format,
+ "SSBO Vertex Fetch does not support attribute conversion.");
+
+ MTLSSBOAttribute ssbo_attr(
+ mtl_attr.index,
+ buffer_index,
+ attribute_offset,
+ buffer_stride,
+ MTLShader::ssbo_vertex_type_to_attr_type(
+ desc.vertex_descriptor.attributes[mtl_attr.location].format),
+ instanced);
+
+ active_shader_->ssbo_vertex_fetch_bind_attribute(ssbo_attr);
+ desc.vertex_descriptor.ssbo_attributes[desc.vertex_descriptor.num_ssbo_attributes] =
+ ssbo_attr;
+ desc.vertex_descriptor.num_ssbo_attributes++;
+ }
+
+ /* NOTE: We are setting num_attributes to be up to the maximum found index, because of
+ * this, it is possible that we may skip over certain attributes if they were not in the
+ * source GPUVertFormat. */
+ MTL_LOG_INFO(
+ " -- Batch Attribute(%d): ORIG Shader Format: %d, ORIG Vert format: %d, Vert "
+ "components: %d, Fetch Mode %d --> FINAL FORMAT: %d\n",
+ mtl_attr.location,
+ (int)mtl_attr.format,
+ (int)a->comp_type,
+ (int)a->comp_len,
+ (int)a->fetch_mode,
+ (int)desc.vertex_descriptor.attributes[mtl_attr.location].format);
+
+ MTL_LOG_INFO(
+ " -- [Batch] matching %s attribute '%s' (Attribute Index: %d, Buffer index: %d, "
+ "offset: %d)\n",
+ (instanced) ? "instance" : "vertex",
+ name,
+ mtl_attr.location,
+ buffer_index,
+ attribute_offset);
+ }
+ }
+ }
+ }
+ if (buffer_added) {
+ return buffer_index;
+ }
+ return -1;
+}
+
+id<MTLRenderCommandEncoder> MTLBatch::bind(uint v_first, uint v_count, uint i_first, uint i_count)
+{
+ /* Setup draw call and render pipeline state here. Called by every draw, but setup here so that
+ * MTLDrawList only needs to perform setup a single time. */
+ BLI_assert(this);
+
+ /* Fetch Metal device. */
+ MTLContext *ctx = MTLContext::get();
+ if (!ctx) {
+ BLI_assert_msg(false, "No context available for rendering.");
+ return nil;
+ }
+
+ /* Verify Shader. */
+ active_shader_ = (shader) ? static_cast<MTLShader *>(unwrap(shader)) : nullptr;
+
+ if (active_shader_ == nullptr || !active_shader_->is_valid()) {
+ /* Skip drawing if there is no valid Metal shader.
+ * This will occur if the path through which the shader is prepared
+ * is invalid (e.g. Python without create-info), or, the source shader uses a geometry pass. */
+ BLI_assert_msg(false, "No valid Metal shader!");
+ return nil;
+ }
+
+ /* Check if using SSBO Fetch Mode.
+ * This is an alternative drawing mode to geometry shaders, wherein vertex buffers
+ * are bound as readable (random-access) GPU buffers and certain descriptor properties
+ * are passed using Shader uniforms. */
+ bool uses_ssbo_fetch = active_shader_->get_uses_ssbo_vertex_fetch();
+
+ /* Prepare Vertex Descriptor and extract VertexBuffers to bind. */
+ MTLVertBuf *buffers[GPU_BATCH_VBO_MAX_LEN] = {nullptr};
+ int num_buffers = 0;
+
+ /* Ensure Index Buffer is ready. */
+ MTLIndexBuf *mtl_elem = static_cast<MTLIndexBuf *>(reinterpret_cast<IndexBuf *>(this->elem));
+ if (mtl_elem != NULL) {
+ mtl_elem->upload_data();
+ }
+
+ /* Populate vertex descriptor with attribute binding information.
+ * The vertex descriptor and buffer layout descriptors describe
+ * how vertex data from bound vertex buffers maps to the
+ * shader's input.
+ * A unique vertex descriptor will result in a new PipelineStateObject
+ * being generated for the currently bound shader. */
+ prepare_vertex_descriptor_and_bindings(buffers, num_buffers, v_first, v_count, i_first, i_count);
+
+ /* Prepare Vertex Buffers - Run before RenderCommandEncoder in case BlitCommandEncoder buffer
+ * data operations are required. */
+ for (int i = 0; i < num_buffers; i++) {
+ MTLVertBuf *buf_at_index = buffers[i];
+ if (buf_at_index == NULL) {
+ BLI_assert_msg(
+ false,
+ "Total buffer count does not match highest buffer index, could be gaps in bindings");
+ continue;
+ }
+
+ MTLVertBuf *mtlvbo = static_cast<MTLVertBuf *>(reinterpret_cast<VertBuf *>(buf_at_index));
+ mtlvbo->bind();
+ }
+
+ /* Ensure render pass is active and fetch active RenderCommandEncoder. */
+ id<MTLRenderCommandEncoder> rec = ctx->ensure_begin_render_pass();
+
+ /* Fetch RenderPassState to enable resource binding for active pass. */
+ MTLRenderPassState &rps = ctx->main_command_buffer.get_render_pass_state();
+
+ /* Debug Check: Ensure Frame-buffer instance is not dirty. */
+ BLI_assert(!ctx->main_command_buffer.get_active_framebuffer()->get_dirty());
+
+ /* Bind Shader. */
+ this->shader_bind();
+
+ /* GPU debug markers. */
+ if (G.debug & G_DEBUG_GPU) {
+ [rec pushDebugGroup:[NSString stringWithFormat:@"batch_bind%@(shader: %s)",
+ this->elem ? @"(indexed)" : @"",
+ active_shader_->get_interface()->get_name()]];
+ [rec insertDebugSignpost:[NSString
+ stringWithFormat:@"batch_bind%@(shader: %s)",
+ this->elem ? @"(indexed)" : @"",
+ active_shader_->get_interface()->get_name()]];
+ }
+
+ /* Ensure Context Render Pipeline State is fully setup and ready to execute the draw. */
+ MTLPrimitiveType mtl_prim_type = gpu_prim_type_to_metal(this->prim_type);
+ if (!ctx->ensure_render_pipeline_state(mtl_prim_type)) {
+ printf("FAILED TO ENSURE RENDER PIPELINE STATE");
+ BLI_assert(false);
+
+ if (G.debug & G_DEBUG_GPU) {
+ [rec popDebugGroup];
+ }
+ return nil;
+ }
+
+ /*** Bind Vertex Buffers and Index Buffers **/
+
+ /* SSBO Vertex Fetch Buffer bindings. */
+ if (uses_ssbo_fetch) {
+
+ /* SSBO Vertex Fetch - Bind Index Buffer to appropriate slot -- if used. */
+ id<MTLBuffer> idx_buffer = nil;
+ GPUPrimType final_prim_type = this->prim_type;
+
+ if (mtl_elem != nullptr) {
+
+ /* Fetch index buffer. This function can situationally return an optimized
+ * index buffer of a different primitive type. If this is the case, `final_prim_type`
+ * and `v_count` will be updated with the new format.
+ * NOTE: For indexed rendering, v_count represents the number of indices. */
+ idx_buffer = mtl_elem->get_index_buffer(final_prim_type, v_count);
+ BLI_assert(idx_buffer != nil);
+
+ /* Update uniforms for SSBO-vertex-fetch-mode indexed rendering to flag usage. */
+ int &uniform_ssbo_index_mode_u16 = active_shader_->uni_ssbo_uses_index_mode_u16;
+ BLI_assert(uniform_ssbo_index_mode_u16 != -1);
+ int uses_index_mode_u16 = (mtl_elem->index_type_ == GPU_INDEX_U16) ? 1 : 0;
+ active_shader_->uniform_int(uniform_ssbo_index_mode_u16, 1, 1, &uses_index_mode_u16);
+ }
+ else {
+ idx_buffer = ctx->get_null_buffer();
+ }
+ rps.bind_vertex_buffer(idx_buffer, 0, MTL_SSBO_VERTEX_FETCH_IBO_INDEX);
+
+ /* Ensure all attributes are set */
+ active_shader_->ssbo_vertex_fetch_bind_attributes_end(rec);
+
+ /* Bind NULL Buffers for unused vertex data slots. */
+ id<MTLBuffer> null_buffer = ctx->get_null_buffer();
+ BLI_assert(null_buffer != nil);
+ for (int i = num_buffers; i < MTL_SSBO_VERTEX_FETCH_MAX_VBOS; i++) {
+ if (rps.cached_vertex_buffer_bindings[i].metal_buffer == nil) {
+ rps.bind_vertex_buffer(null_buffer, 0, i);
+ }
+ }
+
+ /* Flag whether Indexed rendering is used or not. */
+ int &uniform_ssbo_use_indexed = active_shader_->uni_ssbo_uses_indexed_rendering;
+ BLI_assert(uniform_ssbo_use_indexed != -1);
+ int uses_indexed_rendering = (mtl_elem != NULL) ? 1 : 0;
+ active_shader_->uniform_int(uniform_ssbo_use_indexed, 1, 1, &uses_indexed_rendering);
+
+ /* Set SSBO-fetch-mode status uniforms. */
+ BLI_assert(active_shader_->uni_ssbo_input_prim_type_loc != -1);
+ BLI_assert(active_shader_->uni_ssbo_input_vert_count_loc != -1);
+ GPU_shader_uniform_vector_int(reinterpret_cast<GPUShader *>(wrap(active_shader_)),
+ active_shader_->uni_ssbo_input_prim_type_loc,
+ 1,
+ 1,
+ (const int *)(&final_prim_type));
+ GPU_shader_uniform_vector_int(reinterpret_cast<GPUShader *>(wrap(active_shader_)),
+ active_shader_->uni_ssbo_input_vert_count_loc,
+ 1,
+ 1,
+ (const int *)(&v_count));
+ }
+
+ /* Bind Vertex Buffers. */
+ for (int i = 0; i < num_buffers; i++) {
+ MTLVertBuf *buf_at_index = buffers[i];
+ if (buf_at_index == NULL) {
+ BLI_assert_msg(
+ false,
+ "Total buffer count does not match highest buffer index, could be gaps in bindings");
+ continue;
+ }
+ /* Buffer handle. */
+ MTLVertBuf *mtlvbo = static_cast<MTLVertBuf *>(reinterpret_cast<VertBuf *>(buf_at_index));
+ mtlvbo->flag_used();
+
+ /* Fetch buffer from MTLVertexBuffer and bind. */
+ id<MTLBuffer> mtl_buffer = mtlvbo->get_metal_buffer();
+
+ BLI_assert(mtl_buffer != nil);
+ rps.bind_vertex_buffer(mtl_buffer, 0, i);
+ }
+
+ if (G.debug & G_DEBUG_GPU) {
+ [rec popDebugGroup];
+ }
+
+ /* Return Render Command Encoder used with setup. */
+ return rec;
+}
+
+void MTLBatch::unbind()
+{
+}
+
+void MTLBatch::prepare_vertex_descriptor_and_bindings(
+ MTLVertBuf **buffers, int &num_buffers, int v_first, int v_count, int i_first, int i_count)
+{
+
+ /* Here we populate the MTLContext vertex descriptor and resolve which buffers need to be bound.
+ */
+ MTLStateManager *state_manager = static_cast<MTLStateManager *>(
+ MTLContext::get()->state_manager);
+ MTLRenderPipelineStateDescriptor &desc = state_manager->get_pipeline_descriptor();
+ const MTLShaderInterface *interface = active_shader_->get_interface();
+ uint16_t attr_mask = interface->get_enabled_attribute_mask();
+
+ /* Reset vertex descriptor to default state. */
+ desc.reset_vertex_descriptor();
+
+ /* Fetch Vertex and Instance Buffers. */
+ Span<MTLVertBuf *> mtl_verts(reinterpret_cast<MTLVertBuf **>(this->verts),
+ GPU_BATCH_VBO_MAX_LEN);
+ Span<MTLVertBuf *> mtl_inst(reinterpret_cast<MTLVertBuf **>(this->inst),
+ GPU_BATCH_INST_VBO_MAX_LEN);
+
+ /* SSBO Vertex fetch also passes vertex descriptor information into the shader. */
+ if (active_shader_->get_uses_ssbo_vertex_fetch()) {
+ active_shader_->ssbo_vertex_fetch_bind_attributes_begin();
+ }
+
+ /* Resolve Metal vertex buffer bindings. */
+ /* Vertex Descriptors
+ * ------------------
+ * Vertex Descriptors are required to generate a pipeline state, based on the current Batch's
+ * buffer bindings. These bindings are a unique matching, depending on what input attributes a
+ * batch has in its buffers, and those which are supported by the shader interface.
+
+ * We iterate through the buffers and resolve which attributes satisfy the requirements of the
+ * currently bound shader. We cache this data, for a given Batch<->ShderInterface pairing in a
+ * VAO cache to avoid the need to recalculate this data. */
+ bool buffer_is_instanced[GPU_BATCH_VBO_MAX_LEN] = {false};
+
+ VertexDescriptorShaderInterfacePair *descriptor = this->vao_cache.find(interface);
+ if (descriptor) {
+ desc.vertex_descriptor = descriptor->vertex_descriptor;
+ attr_mask = descriptor->attr_mask;
+ num_buffers = descriptor->num_buffers;
+
+ for (int bid = 0; bid < GPU_BATCH_VBO_MAX_LEN; ++bid) {
+ if (descriptor->bufferIds[bid].used) {
+ if (descriptor->bufferIds[bid].is_instance) {
+ buffers[bid] = mtl_inst[descriptor->bufferIds[bid].id];
+ buffer_is_instanced[bid] = true;
+ }
+ else {
+ buffers[bid] = mtl_verts[descriptor->bufferIds[bid].id];
+ buffer_is_instanced[bid] = false;
+ }
+ }
+ }
+
+ /* Use cached ssbo attribute binding data. */
+ if (active_shader_->get_uses_ssbo_vertex_fetch()) {
+ BLI_assert(desc.vertex_descriptor.uses_ssbo_vertex_fetch);
+ for (int attr_id = 0; attr_id < desc.vertex_descriptor.num_ssbo_attributes; attr_id++) {
+ active_shader_->ssbo_vertex_fetch_bind_attribute(
+ desc.vertex_descriptor.ssbo_attributes[attr_id]);
+ }
+ }
+ }
+ else {
+ VertexDescriptorShaderInterfacePair pair{};
+ pair.interface = interface;
+
+ for (int i = 0; i < GPU_BATCH_VBO_MAX_LEN; ++i) {
+ pair.bufferIds[i].id = -1;
+ pair.bufferIds[i].is_instance = 0;
+ pair.bufferIds[i].used = 0;
+ }
+ /* NOTE: Attribute extraction order from buffer is the reverse of the OpenGL as we flag once an
+ * attribute is found, rather than pre-setting the mask. */
+ /* Extract Instance attributes (These take highest priority). */
+ for (int v = 0; v < GPU_BATCH_INST_VBO_MAX_LEN; v++) {
+ if (mtl_inst[v]) {
+ MTL_LOG_INFO(" -- [Batch] Checking bindings for bound instance buffer %p\n", mtl_inst[v]);
+ int buffer_ind = this->prepare_vertex_binding(
+ mtl_inst[v], desc, interface, attr_mask, true);
+ if (buffer_ind >= 0) {
+ buffers[buffer_ind] = mtl_inst[v];
+ buffer_is_instanced[buffer_ind] = true;
+
+ pair.bufferIds[buffer_ind].id = v;
+ pair.bufferIds[buffer_ind].used = 1;
+ pair.bufferIds[buffer_ind].is_instance = 1;
+ num_buffers = ((buffer_ind + 1) > num_buffers) ? (buffer_ind + 1) : num_buffers;
+ }
+ }
+ }
+
+ /* Extract Vertex attributes (First-bound vertex buffer takes priority). */
+ for (int v = 0; v < GPU_BATCH_VBO_MAX_LEN; v++) {
+ if (mtl_verts[v] != NULL) {
+ MTL_LOG_INFO(" -- [Batch] Checking bindings for bound vertex buffer %p\n", mtl_verts[v]);
+ int buffer_ind = this->prepare_vertex_binding(
+ mtl_verts[v], desc, interface, attr_mask, false);
+ if (buffer_ind >= 0) {
+ buffers[buffer_ind] = mtl_verts[v];
+ buffer_is_instanced[buffer_ind] = false;
+
+ pair.bufferIds[buffer_ind].id = v;
+ pair.bufferIds[buffer_ind].used = 1;
+ pair.bufferIds[buffer_ind].is_instance = 0;
+ num_buffers = ((buffer_ind + 1) > num_buffers) ? (buffer_ind + 1) : num_buffers;
+ }
+ }
+ }
+
+ /* Add to VertexDescriptor cache */
+ desc.vertex_descriptor.uses_ssbo_vertex_fetch = active_shader_->get_uses_ssbo_vertex_fetch();
+ pair.attr_mask = attr_mask;
+ pair.vertex_descriptor = desc.vertex_descriptor;
+ pair.num_buffers = num_buffers;
+ if (!this->vao_cache.insert(pair)) {
+ printf(
+ "[Performance Warning] cache is full (Size: %d), vertex descriptor will not be cached\n",
+ GPU_VAO_STATIC_LEN);
+ }
+ }
+
+/* DEBUG: verify if our attribute bindings have been fully provided as expected. */
+#if MTL_DEBUG_SHADER_ATTRIBUTES == 1
+ if (attr_mask != 0) {
+ for (uint16_t mask = 1, a = 0; a < 16; a++, mask <<= 1) {
+ if (attr_mask & mask) {
+ /* Fallback for setting default attributes, for missed slots. Attributes flagged with
+ * 'MTLVertexFormatInvalid' in the vertex descriptor are bound to a NULL buffer during PSO
+ * creation. */
+ MTL_LOG_WARNING("MTLBatch: Missing expected attribute '%s' at index '%d' for shader: %s\n",
+ this->active_shader->interface->attributes[a].name,
+ a,
+ interface->name);
+ /* Ensure any assigned attribute has not been given an invalid format. This should not
+ * occur and may be the result of an unsupported attribute type conversion. */
+ BLI_assert(desc.attributes[a].format == MTLVertexFormatInvalid);
+ }
+ }
+ }
+#endif
+}
+
+void MTLBatch::draw_advanced(int v_first, int v_count, int i_first, int i_count)
+{
+
+#if TRUST_NO_ONE
+ BLI_assert(v_count > 0 && i_count > 0);
+#endif
+
+ /* Setup RenderPipelineState for batch. */
+ MTLContext *ctx = reinterpret_cast<MTLContext *>(GPU_context_active_get());
+ id<MTLRenderCommandEncoder> rec = this->bind(v_first, v_count, i_first, i_count);
+ if (rec == nil) {
+ return;
+ }
+
+ /* Fetch IndexBuffer and resolve primitive type. */
+ MTLIndexBuf *mtl_elem = static_cast<MTLIndexBuf *>(reinterpret_cast<IndexBuf *>(this->elem));
+ MTLPrimitiveType mtl_prim_type = gpu_prim_type_to_metal(this->prim_type);
+
+ /* Render using SSBO Vertex Fetch. */
+ if (active_shader_->get_uses_ssbo_vertex_fetch()) {
+
+ /* Submit draw call with modified vertex count, which reflects vertices per primitive defined
+ * in the USE_SSBO_VERTEX_FETCH pragma. */
+ int num_input_primitives = gpu_get_prim_count_from_type(v_count, this->prim_type);
+ int output_num_verts = num_input_primitives *
+ active_shader_->get_ssbo_vertex_fetch_output_num_verts();
+ BLI_assert_msg(
+ mtl_vertex_count_fits_primitive_type(
+ output_num_verts, active_shader_->get_ssbo_vertex_fetch_output_prim_type()),
+ "Output Vertex count is not compatible with the requested output vertex primitive type");
+ [rec drawPrimitives:active_shader_->get_ssbo_vertex_fetch_output_prim_type()
+ vertexStart:0
+ vertexCount:output_num_verts
+ instanceCount:i_count
+ baseInstance:i_first];
+ ctx->main_command_buffer.register_draw_counters(output_num_verts * i_count);
+ }
+ /* Perform regular draw. */
+ else if (mtl_elem == NULL) {
+
+ /* Primitive Type toplogy emulation. */
+ if (mtl_needs_topology_emulation(this->prim_type)) {
+
+ /* Generate index buffer for primitive types requiring emulation. */
+ GPUPrimType emulated_prim_type = this->prim_type;
+ uint32_t emulated_v_count = v_count;
+ id<MTLBuffer> generated_index_buffer = this->get_emulated_toplogy_buffer(emulated_prim_type,
+ emulated_v_count);
+ BLI_assert(generated_index_buffer != nil);
+
+ MTLPrimitiveType emulated_mtl_prim_type = gpu_prim_type_to_metal(emulated_prim_type);
+
+ /* Temp: Disable culling for emulated primitive types.
+ * TODO(Metal): Support face winding in topology buffer. */
+ [rec setCullMode:MTLCullModeNone];
+
+ if (generated_index_buffer != nil) {
+ BLI_assert(emulated_mtl_prim_type == MTLPrimitiveTypeTriangle ||
+ emulated_mtl_prim_type == MTLPrimitiveTypeLine);
+ if (emulated_mtl_prim_type == MTLPrimitiveTypeTriangle) {
+ BLI_assert(emulated_v_count % 3 == 0);
+ }
+ if (emulated_mtl_prim_type == MTLPrimitiveTypeLine) {
+ BLI_assert(emulated_v_count % 2 == 0);
+ }
+
+ /* Set depth stencil state (requires knowledge of primitive type). */
+ ctx->ensure_depth_stencil_state(emulated_mtl_prim_type);
+
+ [rec drawIndexedPrimitives:emulated_mtl_prim_type
+ indexCount:emulated_v_count
+ indexType:MTLIndexTypeUInt32
+ indexBuffer:generated_index_buffer
+ indexBufferOffset:0
+ instanceCount:i_count
+ baseVertex:v_first
+ baseInstance:i_first];
+ }
+ else {
+ printf("[Note] Cannot draw batch -- Emulated Topology mode: %u not yet supported\n",
+ this->prim_type);
+ }
+ }
+ else {
+ /* Set depth stencil state (requires knowledge of primitive type). */
+ ctx->ensure_depth_stencil_state(mtl_prim_type);
+
+ /* Issue draw call. */
+ [rec drawPrimitives:mtl_prim_type
+ vertexStart:v_first
+ vertexCount:v_count
+ instanceCount:i_count
+ baseInstance:i_first];
+ }
+ ctx->main_command_buffer.register_draw_counters(v_count * i_count);
+ }
+ /* Perform indexed draw. */
+ else {
+
+ MTLIndexType index_type = MTLIndexBuf::gpu_index_type_to_metal(mtl_elem->index_type_);
+ uint32_t base_index = mtl_elem->index_base_;
+ uint32_t index_size = (mtl_elem->index_type_ == GPU_INDEX_U16) ? 2 : 4;
+ uint32_t v_first_ofs = ((v_first + mtl_elem->index_start_) * index_size);
+ BLI_assert_msg((v_first_ofs % index_size) == 0,
+ "Index offset is not 2/4-byte aligned as per METAL spec");
+
+ /* Fetch index buffer. May return an index buffer of a differing format,
+ * if index buffer optimization is used. In these cases, final_prim_type and
+ * index_count get updated with the new properties. */
+ GPUPrimType final_prim_type = this->prim_type;
+ uint index_count = v_count;
+
+ id<MTLBuffer> index_buffer = mtl_elem->get_index_buffer(final_prim_type, index_count);
+ mtl_prim_type = gpu_prim_type_to_metal(final_prim_type);
+ BLI_assert(index_buffer != nil);
+
+ if (index_buffer != nil) {
+
+ /* Set depth stencil state (requires knowledge of primitive type). */
+ ctx->ensure_depth_stencil_state(mtl_prim_type);
+
+ /* Issue draw call. */
+ [rec drawIndexedPrimitives:mtl_prim_type
+ indexCount:index_count
+ indexType:index_type
+ indexBuffer:index_buffer
+ indexBufferOffset:v_first_ofs
+ instanceCount:i_count
+ baseVertex:base_index
+ baseInstance:i_first];
+ ctx->main_command_buffer.register_draw_counters(index_count * i_count);
+ }
+ else {
+ BLI_assert_msg(false, "Index buffer does not have backing Metal buffer");
+ }
+ }
+
+ /* End of draw. */
+ this->unbind();
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Topology emulation and optimization
+ * \{ */
+
+id<MTLBuffer> MTLBatch::get_emulated_toplogy_buffer(GPUPrimType &in_out_prim_type,
+ uint32_t &in_out_v_count)
+{
+
+ BLI_assert(in_out_v_count > 0);
+ /* Determine emulated primitive types. */
+ GPUPrimType input_prim_type = in_out_prim_type;
+ uint32_t v_count = in_out_v_count;
+ GPUPrimType output_prim_type;
+ switch (input_prim_type) {
+ case GPU_PRIM_POINTS:
+ case GPU_PRIM_LINES:
+ case GPU_PRIM_TRIS:
+ BLI_assert_msg(false, "Optimal primitive types should not reach here.");
+ return nil;
+ break;
+ case GPU_PRIM_LINES_ADJ:
+ case GPU_PRIM_TRIS_ADJ:
+ BLI_assert_msg(false, "Adjacency primitive types should not reach here.");
+ return nil;
+ break;
+ case GPU_PRIM_LINE_STRIP:
+ case GPU_PRIM_LINE_LOOP:
+ case GPU_PRIM_LINE_STRIP_ADJ:
+ output_prim_type = GPU_PRIM_LINES;
+ break;
+ case GPU_PRIM_TRI_STRIP:
+ case GPU_PRIM_TRI_FAN:
+ output_prim_type = GPU_PRIM_TRIS;
+ break;
+ default:
+ BLI_assert_msg(false, "Invalid primitive type.");
+ return nil;
+ }
+
+ /* Check if topology buffer exists and is valid. */
+ if (this->emulated_topology_buffer_ != nullptr &&
+ (emulated_topology_type_ != input_prim_type || topology_buffer_input_v_count_ != v_count)) {
+
+ /* Release existing topology buffer. */
+ emulated_topology_buffer_->free();
+ emulated_topology_buffer_ = nullptr;
+ }
+
+ /* Generate new topology index buffer. */
+ if (this->emulated_topology_buffer_ == nullptr) {
+ /* Calculate IB len. */
+ uint32_t output_prim_count = 0;
+ switch (input_prim_type) {
+ case GPU_PRIM_LINE_STRIP:
+ case GPU_PRIM_LINE_STRIP_ADJ:
+ output_prim_count = v_count - 1;
+ break;
+ case GPU_PRIM_LINE_LOOP:
+ output_prim_count = v_count;
+ break;
+ case GPU_PRIM_TRI_STRIP:
+ case GPU_PRIM_TRI_FAN:
+ output_prim_count = v_count - 2;
+ break;
+ default:
+ BLI_assert_msg(false, "Cannot generate optimized topology buffer for other types.");
+ break;
+ }
+ uint32_t output_IB_elems = output_prim_count * ((output_prim_type == GPU_PRIM_TRIS) ? 3 : 2);
+
+ /* Allocate buffer. */
+ uint32_t buffer_bytes = output_IB_elems * 4;
+ BLI_assert(buffer_bytes > 0);
+ this->emulated_topology_buffer_ = MTLContext::get_global_memory_manager().allocate(
+ buffer_bytes, true);
+
+ /* Populate. */
+ uint32_t *data = (uint32_t *)this->emulated_topology_buffer_->get_host_ptr();
+ BLI_assert(data != nullptr);
+
+ /* TODO(Metal): Support inverse winding modes. */
+ bool winding_clockwise = false;
+ UNUSED_VARS(winding_clockwise);
+
+ switch (input_prim_type) {
+ /* Line Loop. */
+ case GPU_PRIM_LINE_LOOP: {
+ int line = 0;
+ for (line = 0; line < output_prim_count - 1; line++) {
+ data[line * 3 + 0] = line + 0;
+ data[line * 3 + 1] = line + 1;
+ }
+ /* Closing line. */
+ data[line * 2 + 0] = line + 0;
+ data[line * 2 + 1] = 0;
+ } break;
+
+ /* Triangle Fan. */
+ case GPU_PRIM_TRI_FAN: {
+ for (int triangle = 0; triangle < output_prim_count; triangle++) {
+ data[triangle * 3 + 0] = 0; /* Always 0 */
+ data[triangle * 3 + 1] = triangle + 1;
+ data[triangle * 3 + 2] = triangle + 2;
+ }
+ } break;
+
+ default:
+ BLI_assert_msg(false, "Other primitive types do not require emulation.");
+ return nil;
+ }
+
+ /* Flush. */
+ this->emulated_topology_buffer_->flush();
+ /* Assign members relating to current cached IB. */
+ topology_buffer_input_v_count_ = v_count;
+ topology_buffer_output_v_count_ = output_IB_elems;
+ emulated_topology_type_ = input_prim_type;
+ }
+
+ /* Return. */
+ in_out_v_count = topology_buffer_output_v_count_;
+ in_out_prim_type = output_prim_type;
+ return (emulated_topology_buffer_) ? emulated_topology_buffer_->get_metal_buffer() : nil;
+}
+
+/** \} */
+
+} // blender::gpu
diff --git a/source/blender/gpu/metal/mtl_command_buffer.mm b/source/blender/gpu/metal/mtl_command_buffer.mm
index 0e13e8d4690..a9cabbb111f 100644
--- a/source/blender/gpu/metal/mtl_command_buffer.mm
+++ b/source/blender/gpu/metal/mtl_command_buffer.mm
@@ -54,6 +54,7 @@ id<MTLCommandBuffer> MTLCommandBufferManager::ensure_begin()
MTLCommandBufferDescriptor *desc = [[MTLCommandBufferDescriptor alloc] init];
desc.errorOptions = MTLCommandBufferErrorOptionEncoderExecutionStatus;
desc.retainedReferences = YES;
+ BLI_assert(context_.queue != nil);
active_command_buffer_ = [context_.queue commandBufferWithDescriptor:desc];
}
else {
@@ -498,7 +499,7 @@ bool MTLCommandBufferManager::insert_memory_barrier(eGPUBarrier barrier_bits,
/* Rendering. */
case MTL_RENDER_COMMAND_ENCODER: {
/* Currently flagging both stages -- can use bits above to filter on stage type --
- * though full barrier is safe for now*/
+ * though full barrier is safe for now. */
MTLRenderStages before_stage_flags = 0;
MTLRenderStages after_stage_flags = 0;
if (before_stages & GPU_BARRIER_STAGE_VERTEX &&
@@ -611,40 +612,187 @@ void MTLRenderPassState::bind_vertex_sampler(MTLSamplerBinding &sampler_binding,
bool use_argument_buffer_for_samplers,
uint slot)
{
- /* TODO(Metal): Implement RenderCommandEncoder vertex sampler binding utility. This will be
- * implemented alongside MTLShader. */
+ /* Range check. */
+ const MTLShaderInterface *shader_interface = ctx.pipeline_state.active_shader->get_interface();
+ BLI_assert(slot >= 0);
+ BLI_assert(slot <= shader_interface->get_max_texture_index());
+ BLI_assert(slot < MTL_MAX_TEXTURE_SLOTS);
+ UNUSED_VARS_NDEBUG(shader_interface);
+
+ /* If sampler state has not changed for the given slot, we do not need to fetch. */
+ if (this->cached_vertex_sampler_state_bindings[slot].sampler_state == nil ||
+ !(this->cached_vertex_sampler_state_bindings[slot].binding_state == sampler_binding.state) ||
+ use_argument_buffer_for_samplers) {
+
+ id<MTLSamplerState> sampler_state = (sampler_binding.state == DEFAULT_SAMPLER_STATE) ?
+ ctx.get_default_sampler_state() :
+ ctx.get_sampler_from_state(sampler_binding.state);
+ if (!use_argument_buffer_for_samplers) {
+ /* Update binding and cached state. */
+ id<MTLRenderCommandEncoder> rec = this->cmd.get_active_render_command_encoder();
+ BLI_assert(rec != nil);
+ [rec setVertexSamplerState:sampler_state atIndex:slot];
+ this->cached_vertex_sampler_state_bindings[slot].binding_state = sampler_binding.state;
+ this->cached_vertex_sampler_state_bindings[slot].sampler_state = sampler_state;
+ }
+
+ /* Flag last binding type. */
+ this->cached_vertex_sampler_state_bindings[slot].is_arg_buffer_binding =
+ use_argument_buffer_for_samplers;
+
+ /* Always assign to argument buffer samplers binding array - Efficiently ensures the value in
+ * the samplers array is always up to date. */
+ ctx.samplers_.mtl_sampler[slot] = sampler_state;
+ ctx.samplers_.mtl_sampler_flags[slot] = sampler_binding.state;
+ }
}
void MTLRenderPassState::bind_fragment_sampler(MTLSamplerBinding &sampler_binding,
bool use_argument_buffer_for_samplers,
uint slot)
{
- /* TODO(Metal): Implement RenderCommandEncoder fragment sampler binding utility. This will be
- * implemented alongside MTLShader. */
+ /* Range check. */
+ const MTLShaderInterface *shader_interface = ctx.pipeline_state.active_shader->get_interface();
+ BLI_assert(slot >= 0);
+ BLI_assert(slot <= shader_interface->get_max_texture_index());
+ BLI_assert(slot < MTL_MAX_TEXTURE_SLOTS);
+ UNUSED_VARS_NDEBUG(shader_interface);
+
+ /* If sampler state has not changed for the given slot, we do not need to fetch*/
+ if (this->cached_fragment_sampler_state_bindings[slot].sampler_state == nil ||
+ !(this->cached_fragment_sampler_state_bindings[slot].binding_state ==
+ sampler_binding.state) ||
+ use_argument_buffer_for_samplers) {
+
+ id<MTLSamplerState> sampler_state = (sampler_binding.state == DEFAULT_SAMPLER_STATE) ?
+ ctx.get_default_sampler_state() :
+ ctx.get_sampler_from_state(sampler_binding.state);
+ if (!use_argument_buffer_for_samplers) {
+ /* Update binding and cached state. */
+ id<MTLRenderCommandEncoder> rec = this->cmd.get_active_render_command_encoder();
+ BLI_assert(rec != nil);
+ [rec setFragmentSamplerState:sampler_state atIndex:slot];
+ this->cached_fragment_sampler_state_bindings[slot].binding_state = sampler_binding.state;
+ this->cached_fragment_sampler_state_bindings[slot].sampler_state = sampler_state;
+ }
+
+ /* Flag last binding type */
+ this->cached_fragment_sampler_state_bindings[slot].is_arg_buffer_binding =
+ use_argument_buffer_for_samplers;
+
+ /* Always assign to argument buffer samplers binding array - Efficiently ensures the value in
+ * the samplers array is always up to date. */
+ ctx.samplers_.mtl_sampler[slot] = sampler_state;
+ ctx.samplers_.mtl_sampler_flags[slot] = sampler_binding.state;
+ }
}
void MTLRenderPassState::bind_vertex_buffer(id<MTLBuffer> buffer, uint buffer_offset, uint index)
{
- /* TODO(Metal): Implement RenderCommandEncoder vertex buffer binding utility. This will be
- * implemented alongside the full MTLMemoryManager. */
+ BLI_assert(index >= 0);
+ BLI_assert(buffer_offset >= 0);
+ BLI_assert(buffer != nil);
+
+ BufferBindingCached &current_vert_ubo_binding = this->cached_vertex_buffer_bindings[index];
+ if (current_vert_ubo_binding.offset != buffer_offset ||
+ current_vert_ubo_binding.metal_buffer != buffer || current_vert_ubo_binding.is_bytes) {
+
+ id<MTLRenderCommandEncoder> rec = this->cmd.get_active_render_command_encoder();
+ BLI_assert(rec != nil);
+
+ if (current_vert_ubo_binding.metal_buffer == buffer) {
+ /* If buffer is the same, but offset has changed. */
+ [rec setVertexBufferOffset:buffer_offset atIndex:index];
+ }
+ else {
+ /* Bind Vertex Buffer. */
+ [rec setVertexBuffer:buffer offset:buffer_offset atIndex:index];
+ }
+
+ /* Update Bind-state cache. */
+ this->cached_vertex_buffer_bindings[index].is_bytes = false;
+ this->cached_vertex_buffer_bindings[index].metal_buffer = buffer;
+ this->cached_vertex_buffer_bindings[index].offset = buffer_offset;
+ }
}
void MTLRenderPassState::bind_fragment_buffer(id<MTLBuffer> buffer, uint buffer_offset, uint index)
{
- /* TODO(Metal): Implement RenderCommandEncoder fragment buffer binding utility. This will be
- * implemented alongside the full MTLMemoryManager. */
+ BLI_assert(index >= 0);
+ BLI_assert(buffer_offset >= 0);
+ BLI_assert(buffer != nil);
+
+ BufferBindingCached &current_frag_ubo_binding = this->cached_fragment_buffer_bindings[index];
+ if (current_frag_ubo_binding.offset != buffer_offset ||
+ current_frag_ubo_binding.metal_buffer != buffer || current_frag_ubo_binding.is_bytes) {
+
+ id<MTLRenderCommandEncoder> rec = this->cmd.get_active_render_command_encoder();
+ BLI_assert(rec != nil);
+
+ if (current_frag_ubo_binding.metal_buffer == buffer) {
+ /* If buffer is the same, but offset has changed. */
+ [rec setFragmentBufferOffset:buffer_offset atIndex:index];
+ }
+ else {
+ /* Bind Fragment Buffer */
+ [rec setFragmentBuffer:buffer offset:buffer_offset atIndex:index];
+ }
+
+ /* Update Bind-state cache */
+ this->cached_fragment_buffer_bindings[index].is_bytes = false;
+ this->cached_fragment_buffer_bindings[index].metal_buffer = buffer;
+ this->cached_fragment_buffer_bindings[index].offset = buffer_offset;
+ }
}
void MTLRenderPassState::bind_vertex_bytes(void *bytes, uint length, uint index)
{
- /* TODO(Metal): Implement RenderCommandEncoder vertex bytes binding utility. This will be
- * implemented alongside the full MTLMemoryManager. */
+ /* Bytes always updated as source data may have changed. */
+ BLI_assert(index >= 0 && index < MTL_MAX_UNIFORM_BUFFER_BINDINGS);
+ BLI_assert(length > 0);
+ BLI_assert(bytes != nullptr);
+
+ if (length < MTL_MAX_SET_BYTES_SIZE) {
+ id<MTLRenderCommandEncoder> rec = this->cmd.get_active_render_command_encoder();
+ [rec setVertexBytes:bytes length:length atIndex:index];
+ }
+ else {
+ /* We have run over the setBytes limit, bind buffer instead. */
+ MTLTemporaryBuffer range =
+ ctx.get_scratchbuffer_manager().scratch_buffer_allocate_range_aligned(length, 256);
+ memcpy(range.data, bytes, length);
+ this->bind_vertex_buffer(range.metal_buffer, range.buffer_offset, index);
+ }
+
+ /* Update Bind-state cache */
+ this->cached_vertex_buffer_bindings[index].is_bytes = true;
+ this->cached_vertex_buffer_bindings[index].metal_buffer = nil;
+ this->cached_vertex_buffer_bindings[index].offset = -1;
}
void MTLRenderPassState::bind_fragment_bytes(void *bytes, uint length, uint index)
{
- /* TODO(Metal): Implement RenderCommandEncoder fragment bytes binding utility. This will be
- * implemented alongside the full MTLMemoryManager. */
+ /* Bytes always updated as source data may have changed. */
+ BLI_assert(index >= 0 && index < MTL_MAX_UNIFORM_BUFFER_BINDINGS);
+ BLI_assert(length > 0);
+ BLI_assert(bytes != nullptr);
+
+ if (length < MTL_MAX_SET_BYTES_SIZE) {
+ id<MTLRenderCommandEncoder> rec = this->cmd.get_active_render_command_encoder();
+ [rec setFragmentBytes:bytes length:length atIndex:index];
+ }
+ else {
+ /* We have run over the setBytes limit, bind buffer instead. */
+ MTLTemporaryBuffer range =
+ ctx.get_scratchbuffer_manager().scratch_buffer_allocate_range_aligned(length, 256);
+ memcpy(range.data, bytes, length);
+ this->bind_fragment_buffer(range.metal_buffer, range.buffer_offset, index);
+ }
+
+ /* Update Bind-state cache. */
+ this->cached_fragment_buffer_bindings[index].is_bytes = true;
+ this->cached_fragment_buffer_bindings[index].metal_buffer = nil;
+ this->cached_fragment_buffer_bindings[index].offset = -1;
}
/** \} */
diff --git a/source/blender/gpu/metal/mtl_common.hh b/source/blender/gpu/metal/mtl_common.hh
index b6f9c0050a9..5c322efa3f9 100644
--- a/source/blender/gpu/metal/mtl_common.hh
+++ b/source/blender/gpu/metal/mtl_common.hh
@@ -3,7 +3,9 @@
#ifndef __MTL_COMMON
#define __MTL_COMMON
-// -- Renderer Options --
+/** -- Renderer Options -- */
+/* Number of frames over which rolling averages are taken. */
+#define MTL_FRAME_AVERAGE_COUNT 5
#define MTL_MAX_DRAWABLES 3
#define MTL_MAX_SET_BYTES_SIZE 4096
#define MTL_FORCE_WAIT_IDLE 0
diff --git a/source/blender/gpu/metal/mtl_context.hh b/source/blender/gpu/metal/mtl_context.hh
index e996193e722..6229afcef79 100644
--- a/source/blender/gpu/metal/mtl_context.hh
+++ b/source/blender/gpu/metal/mtl_context.hh
@@ -12,6 +12,10 @@
#include "GPU_common_types.h"
#include "GPU_context.h"
+#include "intern/GHOST_Context.h"
+#include "intern/GHOST_ContextCGL.h"
+#include "intern/GHOST_Window.h"
+
#include "mtl_backend.hh"
#include "mtl_capabilities.hh"
#include "mtl_common.hh"
@@ -248,7 +252,7 @@ struct MTLContextTextureUtils {
/* Depth texture updates are not directly supported with Blit operations, similarly, we cannot
* use a compute shader to write to depth, so we must instead render to a depth target.
* These processes use vertex/fragment shaders to render texture data from an intermediate
- * source, in order to prime the depth buffer*/
+ * source, in order to prime the depth buffer. */
blender::Map<DepthTextureUpdateRoutineSpecialisation, GPUShader *> depth_2d_update_shaders;
GPUShader *fullscreen_blit_shader = nullptr;
@@ -348,7 +352,7 @@ struct MTLSamplerArray {
{
uint32_t hash = this->num_samplers;
for (int i = 0; i < this->num_samplers; i++) {
- hash ^= (uint32_t)this->mtl_sampler_flags[i] << (i % 3);
+ hash ^= uint32_t(this->mtl_sampler_flags[i]) << (i % 3);
}
return hash;
}
@@ -570,12 +574,44 @@ class MTLCommandBufferManager {
class MTLContext : public Context {
friend class MTLBackend;
+ friend class MTLRenderPassState;
+
+ public:
+ /* Swap-chain and latency management. */
+ static std::atomic<int> max_drawables_in_flight;
+ static std::atomic<int64_t> avg_drawable_latency_us;
+ static int64_t frame_latency[MTL_FRAME_AVERAGE_COUNT];
+
+ public:
+ /* Shaders and Pipeline state. */
+ MTLContextGlobalShaderPipelineState pipeline_state;
+
+ /* Metal API Resource Handles. */
+ id<MTLCommandQueue> queue = nil;
+ id<MTLDevice> device = nil;
+
+#ifndef NDEBUG
+ /* Label for Context debug name assignment. */
+ NSString *label = nil;
+#endif
+
+ /* Memory Management. */
+ MTLScratchBufferManager memory_manager;
+ static MTLBufferPool global_memory_manager;
+
+ /* CommandBuffer managers. */
+ MTLCommandBufferManager main_command_buffer;
private:
- /* Null buffers for empty/uninitialized bindings.
- * Null attribute buffer follows default attribute format of OpenGL Back-end. */
- id<MTLBuffer> null_buffer_; /* All zero's. */
- id<MTLBuffer> null_attribute_buffer_; /* Value float4(0.0,0.0,0.0,1.0). */
+ /* Parent Context. */
+ GHOST_ContextCGL *ghost_context_;
+
+ /* Render Passes and Frame-buffers. */
+ id<MTLTexture> default_fbo_mtltexture_ = nil;
+ gpu::MTLTexture *default_fbo_gputexture_ = nullptr;
+
+ /* Depth-stencil state cache. */
+ blender::Map<MTLContextDepthStencilState, id<MTLDepthStencilState>> depth_stencil_state_cache;
/* Compute and specialization caches. */
MTLContextTextureUtils texture_utils_;
@@ -601,23 +637,20 @@ class MTLContext : public Context {
gpu::MTLBuffer *visibility_buffer_ = nullptr;
bool visibility_is_dirty_ = false;
- public:
- /* Shaders and Pipeline state. */
- MTLContextGlobalShaderPipelineState pipeline_state;
-
- /* Metal API Resource Handles. */
- id<MTLCommandQueue> queue = nil;
- id<MTLDevice> device = nil;
-
- /* Memory Management */
- MTLScratchBufferManager memory_manager;
- static MTLBufferPool global_memory_manager;
+ /* Null buffers for empty/uninitialized bindings.
+ * Null attribute buffer follows default attribute format of OpenGL Backend. */
+ id<MTLBuffer> null_buffer_; /* All zero's. */
+ id<MTLBuffer> null_attribute_buffer_; /* Value float4(0.0,0.0,0.0,1.0). */
- /* CommandBuffer managers. */
- MTLCommandBufferManager main_command_buffer;
+ /** Dummy Resources */
+ /* Maximum of 32 texture types. Though most combinations invalid. */
+ gpu::MTLTexture *dummy_textures_[GPU_TEXTURE_BUFFER] = {nullptr};
+ GPUVertFormat dummy_vertformat_;
+ GPUVertBuf *dummy_verts_ = nullptr;
+ public:
/* GPUContext interface. */
- MTLContext(void *ghost_window);
+ MTLContext(void *ghost_window, void *ghost_context);
~MTLContext();
static void check_error(const char *info);
@@ -673,6 +706,35 @@ class MTLContext : public Context {
void pipeline_state_init();
MTLShader *get_active_shader();
+ /* These functions ensure that the current RenderCommandEncoder has
+ * the correct global state assigned. This should be called prior
+ * to every draw call, to ensure that all state is applied and up
+ * to date. We handle:
+ *
+ * - Buffer bindings (Vertex buffers, Uniforms, UBOs, transform feedback)
+ * - Texture bindings
+ * - Sampler bindings (+ argument buffer bindings)
+ * - Dynamic Render pipeline state (on encoder)
+ * - Baking Pipeline State Objects (PSOs) for current shader, based
+ * on final pipeline state.
+ *
+ * `ensure_render_pipeline_state` will return false if the state is
+ * invalid and cannot be applied. This should cancel a draw call. */
+ bool ensure_render_pipeline_state(MTLPrimitiveType prim_type);
+ bool ensure_uniform_buffer_bindings(
+ id<MTLRenderCommandEncoder> rec,
+ const MTLShaderInterface *shader_interface,
+ const MTLRenderPipelineStateInstance *pipeline_state_instance);
+ void ensure_texture_bindings(id<MTLRenderCommandEncoder> rec,
+ MTLShaderInterface *shader_interface,
+ const MTLRenderPipelineStateInstance *pipeline_state_instance);
+ void ensure_depth_stencil_state(MTLPrimitiveType prim_type);
+
+ id<MTLBuffer> get_null_buffer();
+ id<MTLBuffer> get_null_attribute_buffer();
+ gpu::MTLTexture *get_dummy_texture(eGPUTextureType type);
+ void free_dummy_resources();
+
/* State assignment. */
void set_viewport(int origin_x, int origin_y, int width, int height);
void set_scissor(int scissor_x, int scissor_y, int scissor_width, int scissor_height);
@@ -720,9 +782,37 @@ class MTLContext : public Context {
{
return MTLContext::global_memory_manager;
}
- /* Uniform Buffer Bindings to command encoders. */
- id<MTLBuffer> get_null_buffer();
- id<MTLBuffer> get_null_attribute_buffer();
+
+ /* Swap-chain and latency management. */
+ static void latency_resolve_average(int64_t frame_latency_us)
+ {
+ int64_t avg = 0;
+ int64_t frame_c = 0;
+ for (int i = MTL_FRAME_AVERAGE_COUNT - 1; i > 0; i--) {
+ MTLContext::frame_latency[i] = MTLContext::frame_latency[i - 1];
+ avg += MTLContext::frame_latency[i];
+ frame_c += (MTLContext::frame_latency[i] > 0) ? 1 : 0;
+ }
+ MTLContext::frame_latency[0] = frame_latency_us;
+ avg += MTLContext::frame_latency[0];
+ if (frame_c > 0) {
+ avg /= frame_c;
+ }
+ else {
+ avg = 0;
+ }
+ MTLContext::avg_drawable_latency_us = avg;
+ }
+
+ private:
+ void set_ghost_context(GHOST_ContextHandle ghostCtxHandle);
+ void set_ghost_window(GHOST_WindowHandle ghostWinHandle);
};
+/* GHOST Context callback and present. */
+void present(MTLRenderPassDescriptor *blit_descriptor,
+ id<MTLRenderPipelineState> blit_pso,
+ id<MTLTexture> swapchain_texture,
+ id<CAMetalDrawable> drawable);
+
} // namespace blender::gpu
diff --git a/source/blender/gpu/metal/mtl_context.mm b/source/blender/gpu/metal/mtl_context.mm
index a66645e5fb5..50576379f0d 100644
--- a/source/blender/gpu/metal/mtl_context.mm
+++ b/source/blender/gpu/metal/mtl_context.mm
@@ -5,13 +5,29 @@
*/
#include "mtl_context.hh"
#include "mtl_debug.hh"
+#include "mtl_framebuffer.hh"
+#include "mtl_immediate.hh"
+#include "mtl_memory.hh"
+#include "mtl_primitive.hh"
#include "mtl_shader.hh"
#include "mtl_shader_interface.hh"
#include "mtl_state.hh"
+#include "mtl_uniform_buffer.hh"
#include "DNA_userdef_types.h"
#include "GPU_capabilities.h"
+#include "GPU_matrix.h"
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+#include "GPU_uniform_buffer.h"
+#include "GPU_vertex_buffer.h"
+#include "intern/gpu_matrix_private.h"
+
+#include "PIL_time.h"
+
+#include <fstream>
+#include <string>
using namespace blender;
using namespace blender::gpu;
@@ -21,21 +37,118 @@ namespace blender::gpu {
/* Global memory manager. */
MTLBufferPool MTLContext::global_memory_manager;
+/* Swap-chain and latency management. */
+std::atomic<int> MTLContext::max_drawables_in_flight = 0;
+std::atomic<int64_t> MTLContext::avg_drawable_latency_us = 0;
+int64_t MTLContext::frame_latency[MTL_FRAME_AVERAGE_COUNT] = {0};
+
+/* -------------------------------------------------------------------- */
+/** \name GHOST Context interaction.
+ * \{ */
+
+void MTLContext::set_ghost_context(GHOST_ContextHandle ghostCtxHandle)
+{
+ GHOST_Context *ghost_ctx = reinterpret_cast<GHOST_Context *>(ghostCtxHandle);
+ BLI_assert(ghost_ctx != nullptr);
+
+ /* Release old MTLTexture handle */
+ if (default_fbo_mtltexture_) {
+ [default_fbo_mtltexture_ release];
+ default_fbo_mtltexture_ = nil;
+ }
+
+ /* Release Framebuffer attachments */
+ MTLFrameBuffer *mtl_front_left = static_cast<MTLFrameBuffer *>(this->front_left);
+ MTLFrameBuffer *mtl_back_left = static_cast<MTLFrameBuffer *>(this->back_left);
+ mtl_front_left->remove_all_attachments();
+ mtl_back_left->remove_all_attachments();
+
+ GHOST_ContextCGL *ghost_cgl_ctx = dynamic_cast<GHOST_ContextCGL *>(ghost_ctx);
+ if (ghost_cgl_ctx != NULL) {
+ default_fbo_mtltexture_ = ghost_cgl_ctx->metalOverlayTexture();
+
+ MTL_LOG_INFO(
+ "Binding GHOST context CGL %p to GPU context %p. (Device: %p, queue: %p, texture: %p)\n",
+ ghost_cgl_ctx,
+ this,
+ this->device,
+ this->queue,
+ default_fbo_gputexture_);
+
+ /* Check if the GHOST Context provides a default framebuffer: */
+ if (default_fbo_mtltexture_) {
+
+ /* Release old GPUTexture handle */
+ if (default_fbo_gputexture_) {
+ GPU_texture_free(wrap(static_cast<Texture *>(default_fbo_gputexture_)));
+ default_fbo_gputexture_ = nullptr;
+ }
+
+ /* Retain handle */
+ [default_fbo_mtltexture_ retain];
+
+ /*** Create front and back-buffers ***/
+ /* Create gpu::MTLTexture objects */
+ default_fbo_gputexture_ = new gpu::MTLTexture(
+ "MTL_BACKBUFFER", GPU_RGBA16F, GPU_TEXTURE_2D, default_fbo_mtltexture_);
+
+ /* Update frame-buffers with new texture attachments. */
+ mtl_front_left->add_color_attachment(default_fbo_gputexture_, 0, 0, 0);
+ mtl_back_left->add_color_attachment(default_fbo_gputexture_, 0, 0, 0);
+#ifndef NDEBUG
+ this->label = default_fbo_mtltexture_.label;
+#endif
+ }
+ else {
+
+ /* Add default texture for cases where no other framebuffer is bound */
+ if (!default_fbo_gputexture_) {
+ default_fbo_gputexture_ = static_cast<gpu::MTLTexture *>(
+ unwrap(GPU_texture_create_2d(__func__, 16, 16, 1, GPU_RGBA16F, nullptr)));
+ }
+ mtl_back_left->add_color_attachment(default_fbo_gputexture_, 0, 0, 0);
+
+ MTL_LOG_INFO(
+ "-- Bound context %p for GPU context: %p is offscreen and does not have a default "
+ "framebuffer\n",
+ ghost_cgl_ctx,
+ this);
+#ifndef NDEBUG
+ this->label = @"Offscreen Metal Context";
+#endif
+ }
+ }
+ else {
+ MTL_LOG_INFO(
+ "[ERROR] Failed to bind GHOST context to MTLContext -- GHOST_ContextCGL is null "
+ "(GhostContext: %p, GhostContext_CGL: %p)\n",
+ ghost_ctx,
+ ghost_cgl_ctx);
+ BLI_assert(false);
+ }
+}
+
+void MTLContext::set_ghost_window(GHOST_WindowHandle ghostWinHandle)
+{
+ GHOST_Window *ghostWin = reinterpret_cast<GHOST_Window *>(ghostWinHandle);
+ this->set_ghost_context((GHOST_ContextHandle)(ghostWin ? ghostWin->getContext() : NULL));
+}
+
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name MTLContext
* \{ */
/* Placeholder functions */
-MTLContext::MTLContext(void *ghost_window) : memory_manager(*this), main_command_buffer(*this)
+MTLContext::MTLContext(void *ghost_window, void *ghost_context)
+ : memory_manager(*this), main_command_buffer(*this)
{
/* Init debug. */
debug::mtl_debug_init();
- /* Device creation.
- * TODO(Metal): This is a temporary initialization path to enable testing of features
- * and shader compilation tests. Future functionality should fetch the existing device
- * from GHOST_ContextCGL.mm. Plumbing to be updated in future. */
- this->device = MTLCreateSystemDefaultDevice();
+ /* Initialize Render-pass and Frame-buffer State. */
+ this->back_left = nullptr;
/* Initialize command buffer state. */
this->main_command_buffer.prepare();
@@ -47,10 +160,35 @@ MTLContext::MTLContext(void *ghost_window) : memory_manager(*this), main_command
is_inside_frame_ = false;
current_frame_index_ = 0;
- /* Prepare null data buffer */
+ /* Prepare null data buffer. */
null_buffer_ = nil;
null_attribute_buffer_ = nil;
+ /* Zero-initialize MTL textures. */
+ default_fbo_mtltexture_ = nil;
+ default_fbo_gputexture_ = nullptr;
+
+ /** Fetch GHOSTContext and fetch Metal device/queue. */
+ ghost_window_ = ghost_window;
+ if (ghost_window_ && ghost_context == NULL) {
+ /* NOTE(Metal): Fetch ghost_context from ghost_window if it is not provided.
+ * Regardless of whether windowed or not, we need access to the GhostContext
+ * for presentation, and device/queue access. */
+ GHOST_Window *ghostWin = reinterpret_cast<GHOST_Window *>(ghost_window_);
+ ghost_context = (ghostWin ? ghostWin->getContext() : NULL);
+ }
+ BLI_assert(ghost_context);
+ this->ghost_context_ = static_cast<GHOST_ContextCGL *>(ghost_context);
+ this->queue = (id<MTLCommandQueue>)this->ghost_context_->metalCommandQueue();
+ this->device = (id<MTLDevice>)this->ghost_context_->metalDevice();
+ BLI_assert(this->queue);
+ BLI_assert(this->device);
+ [this->queue retain];
+ [this->device retain];
+
+ /* Register present callback. */
+ this->ghost_context_->metalRegisterPresentCallback(&present);
+
/* Create FrameBuffer handles. */
MTLFrameBuffer *mtl_front_left = new MTLFrameBuffer(this, "front_left");
MTLFrameBuffer *mtl_back_left = new MTLFrameBuffer(this, "back_left");
@@ -66,6 +204,7 @@ MTLContext::MTLContext(void *ghost_window) : memory_manager(*this), main_command
/* Initialize Metal modules. */
this->memory_manager.init();
this->state_manager = new MTLStateManager(this);
+ this->imm = new MTLImmediate(this);
/* Ensure global memory manager is initialized. */
MTLContext::global_memory_manager.init(this->device);
@@ -99,9 +238,29 @@ MTLContext::~MTLContext()
this->end_frame();
}
}
+
+ /* Release Memory Manager */
+ this->get_scratchbuffer_manager().free();
+
/* Release update/blit shaders. */
this->get_texture_utils().cleanup();
+ /* Detach resource references */
+ GPU_texture_unbind_all();
+
+ /* Unbind UBOs */
+ for (int i = 0; i < MTL_MAX_UNIFORM_BUFFER_BINDINGS; i++) {
+ if (this->pipeline_state.ubo_bindings[i].bound &&
+ this->pipeline_state.ubo_bindings[i].ubo != nullptr) {
+ GPUUniformBuf *ubo = wrap(
+ static_cast<UniformBuf *>(this->pipeline_state.ubo_bindings[i].ubo));
+ GPU_uniformbuf_unbind(ubo);
+ }
+ }
+
+ /* Release Dummy resources */
+ this->free_dummy_resources();
+
/* Release Sampler States. */
for (int i = 0; i < GPU_SAMPLER_MAX; i++) {
if (sampler_state_cache_[i] != nil) {
@@ -109,12 +268,28 @@ MTLContext::~MTLContext()
sampler_state_cache_[i] = nil;
}
}
+
+ /* Empty cached sampler argument buffers. */
+ for (auto entry : cached_sampler_buffers_.values()) {
+ entry->free();
+ }
+ cached_sampler_buffers_.clear();
+
+ /* Free null buffers. */
if (null_buffer_) {
[null_buffer_ release];
}
if (null_attribute_buffer_) {
[null_attribute_buffer_ release];
}
+
+ /* Free Metal objects. */
+ if (this->queue) {
+ [this->queue release];
+ }
+ if (this->device) {
+ [this->device release];
+ }
}
void MTLContext::begin_frame()
@@ -146,20 +321,49 @@ void MTLContext::check_error(const char *info)
void MTLContext::activate()
{
- /* TODO(Metal): Implement. */
+ /* Make sure no other context is already bound to this thread. */
+ BLI_assert(is_active_ == false);
+ is_active_ = true;
+ thread_ = pthread_self();
+
+ /* Re-apply ghost window/context for resizing */
+ if (ghost_window_) {
+ this->set_ghost_window((GHOST_WindowHandle)ghost_window_);
+ }
+ else if (ghost_context_) {
+ this->set_ghost_context((GHOST_ContextHandle)ghost_context_);
+ }
+
+ /* Reset UBO bind state. */
+ for (int i = 0; i < MTL_MAX_UNIFORM_BUFFER_BINDINGS; i++) {
+ if (this->pipeline_state.ubo_bindings[i].bound &&
+ this->pipeline_state.ubo_bindings[i].ubo != nullptr) {
+ this->pipeline_state.ubo_bindings[i].bound = false;
+ this->pipeline_state.ubo_bindings[i].ubo = nullptr;
+ }
+ }
+
+ /* Ensure imm active. */
+ immActivate();
}
+
void MTLContext::deactivate()
{
- /* TODO(Metal): Implement. */
+ BLI_assert(this->is_active_on_thread());
+ /* Flush context on deactivate. */
+ this->flush();
+ is_active_ = false;
+ immDeactivate();
}
void MTLContext::flush()
{
- /* TODO(Metal): Implement. */
+ this->main_command_buffer.submit(false);
}
+
void MTLContext::finish()
{
- /* TODO(Metal): Implement. */
+ this->main_command_buffer.submit(true);
}
void MTLContext::memory_statistics_get(int *total_mem, int *free_mem)
@@ -200,9 +404,8 @@ id<MTLRenderCommandEncoder> MTLContext::ensure_begin_render_pass()
/* Ensure command buffer workload submissions are optimal --
* Though do not split a batch mid-IMM recording. */
- /* TODO(Metal): Add IMM Check once MTLImmediate has been implemented. */
- if (this->main_command_buffer.do_break_submission()/*&&
- !((MTLImmediate *)(this->imm))->imm_is_recording()*/) {
+ if (this->main_command_buffer.do_break_submission() &&
+ !((MTLImmediate *)(this->imm))->imm_is_recording()) {
this->flush();
}
@@ -293,6 +496,72 @@ id<MTLBuffer> MTLContext::get_null_attribute_buffer()
return null_attribute_buffer_;
}
+gpu::MTLTexture *MTLContext::get_dummy_texture(eGPUTextureType type)
+{
+ /* Decrement 1 from texture type as they start from 1 and go to 32 (inclusive). Remap to 0..31 */
+ gpu::MTLTexture *dummy_tex = dummy_textures_[type - 1];
+ if (dummy_tex != nullptr) {
+ return dummy_tex;
+ }
+ else {
+ GPUTexture *tex = nullptr;
+ switch (type) {
+ case GPU_TEXTURE_1D:
+ tex = GPU_texture_create_1d("Dummy 1D", 128, 1, GPU_RGBA8, nullptr);
+ break;
+ case GPU_TEXTURE_1D_ARRAY:
+ tex = GPU_texture_create_1d_array("Dummy 1DArray", 128, 1, 1, GPU_RGBA8, nullptr);
+ break;
+ case GPU_TEXTURE_2D:
+ tex = GPU_texture_create_2d("Dummy 2D", 128, 128, 1, GPU_RGBA8, nullptr);
+ break;
+ case GPU_TEXTURE_2D_ARRAY:
+ tex = GPU_texture_create_2d_array("Dummy 2DArray", 128, 128, 1, 1, GPU_RGBA8, nullptr);
+ break;
+ case GPU_TEXTURE_3D:
+ tex = GPU_texture_create_3d(
+ "Dummy 3D", 128, 128, 1, 1, GPU_RGBA8, GPU_DATA_UBYTE, nullptr);
+ break;
+ case GPU_TEXTURE_CUBE:
+ tex = GPU_texture_create_cube("Dummy Cube", 128, 1, GPU_RGBA8, nullptr);
+ break;
+ case GPU_TEXTURE_CUBE_ARRAY:
+ tex = GPU_texture_create_cube_array("Dummy CubeArray", 128, 1, 1, GPU_RGBA8, nullptr);
+ break;
+ case GPU_TEXTURE_BUFFER:
+ if (!dummy_verts_) {
+ GPU_vertformat_clear(&dummy_vertformat_);
+ GPU_vertformat_attr_add(&dummy_vertformat_, "dummy", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ dummy_verts_ = GPU_vertbuf_create_with_format_ex(&dummy_vertformat_, GPU_USAGE_STATIC);
+ GPU_vertbuf_data_alloc(dummy_verts_, 64);
+ }
+ tex = GPU_texture_create_from_vertbuf("Dummy TextureBuffer", dummy_verts_);
+ break;
+ default:
+ BLI_assert_msg(false, "Unrecognised texture type");
+ return nullptr;
+ }
+ gpu::MTLTexture *metal_tex = static_cast<gpu::MTLTexture *>(reinterpret_cast<Texture *>(tex));
+ dummy_textures_[type - 1] = metal_tex;
+ return metal_tex;
+ }
+ return nullptr;
+}
+
+void MTLContext::free_dummy_resources()
+{
+ for (int tex = 0; tex < GPU_TEXTURE_BUFFER; tex++) {
+ if (dummy_textures_[tex]) {
+ GPU_texture_free(
+ reinterpret_cast<GPUTexture *>(static_cast<Texture *>(dummy_textures_[tex])));
+ dummy_textures_[tex] = nullptr;
+ }
+ }
+ if (dummy_verts_) {
+ GPU_vertbuf_discard(dummy_verts_);
+ }
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -439,6 +708,757 @@ void MTLContext::set_scissor_enabled(bool scissor_enabled)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Command Encoder and pipeline state
+ * These utilities ensure that all of the globally bound resources and state have been
+ * correctly encoded within the current RenderCommandEncoder. This involves managing
+ * buffer bindings, texture bindings, depth stencil state and dynamic pipeline state.
+ *
+ * We will also trigger compilation of new PSOs where the input state has changed
+ * and is required.
+ * All of this setup is required in order to perform a valid draw call.
+ * \{ */
+
+bool MTLContext::ensure_render_pipeline_state(MTLPrimitiveType mtl_prim_type)
+{
+ BLI_assert(this->pipeline_state.initialised);
+
+ /* Check if an active shader is bound. */
+ if (!this->pipeline_state.active_shader) {
+ MTL_LOG_WARNING("No Metal shader for bound GL shader\n");
+ return false;
+ }
+
+ /* Also ensure active shader is valid. */
+ if (!this->pipeline_state.active_shader->is_valid()) {
+ MTL_LOG_WARNING(
+ "Bound active shader is not valid (Missing/invalid implementation for Metal).\n", );
+ return false;
+ }
+
+ /* Apply global state. */
+ this->state_manager->apply_state();
+
+ /* Main command buffer tracks the current state of the render pass, based on bound
+ * MTLFrameBuffer. */
+ MTLRenderPassState &rps = this->main_command_buffer.get_render_pass_state();
+
+ /* Debug Check: Ensure Framebuffer instance is not dirty. */
+ BLI_assert(!this->main_command_buffer.get_active_framebuffer()->get_dirty());
+
+ /* Fetch shader interface. */
+ MTLShaderInterface *shader_interface = this->pipeline_state.active_shader->get_interface();
+ if (shader_interface == nullptr) {
+ MTL_LOG_WARNING("Bound active shader does not have a valid shader interface!\n", );
+ return false;
+ }
+
+ /* Fetch shader and bake valid PipelineStateObject (PSO) based on current
+ * shader and state combination. This PSO represents the final GPU-executable
+ * permutation of the shader. */
+ MTLRenderPipelineStateInstance *pipeline_state_instance =
+ this->pipeline_state.active_shader->bake_current_pipeline_state(
+ this, mtl_prim_type_to_topology_class(mtl_prim_type));
+ if (!pipeline_state_instance) {
+ MTL_LOG_ERROR("Failed to bake Metal pipeline state for shader: %s\n",
+ shader_interface->get_name());
+ return false;
+ }
+
+ bool result = false;
+ if (pipeline_state_instance->pso) {
+
+ /* Fetch render command encoder. A render pass should already be active.
+ * This will be NULL if invalid. */
+ id<MTLRenderCommandEncoder> rec =
+ this->main_command_buffer.get_active_render_command_encoder();
+ BLI_assert(rec);
+ if (rec == nil) {
+ MTL_LOG_ERROR("ensure_render_pipeline_state called while render pass is not active.\n");
+ return false;
+ }
+
+ /* Bind Render Pipeline State. */
+ BLI_assert(pipeline_state_instance->pso);
+ if (rps.bound_pso != pipeline_state_instance->pso) {
+ [rec setRenderPipelineState:pipeline_state_instance->pso];
+ rps.bound_pso = pipeline_state_instance->pso;
+ }
+
+ /** Ensure resource bindings. */
+ /* Texture Bindings. */
+ /* We will iterate through all texture bindings on the context and determine if any of the
+ * active slots match those in our shader interface. If so, textures will be bound. */
+ if (shader_interface->get_total_textures() > 0) {
+ this->ensure_texture_bindings(rec, shader_interface, pipeline_state_instance);
+ }
+
+ /* Transform feedback buffer binding. */
+ /* TOOD(Metal): Include this code once MTLVertBuf is merged. We bind the vertex buffer to which
+ * transform feedback data will be written. */
+ // GPUVertBuf *tf_vbo =
+ // this->pipeline_state.active_shader->get_transform_feedback_active_buffer();
+ // if (tf_vbo != nullptr && pipeline_state_instance->transform_feedback_buffer_index >= 0) {
+
+ // /* Ensure primitive type is either GPU_LINES, GPU_TRIANGLES or GPU_POINT */
+ // BLI_assert(mtl_prim_type == MTLPrimitiveTypeLine ||
+ // mtl_prim_type == MTLPrimitiveTypeTriangle ||
+ // mtl_prim_type == MTLPrimitiveTypePoint);
+
+ // /* Fetch active transform feedback buffer from vertbuf */
+ // MTLVertBuf *tf_vbo_mtl = static_cast<MTLVertBuf *>(reinterpret_cast<VertBuf *>(tf_vbo));
+ // int tf_buffer_offset = 0;
+ // id<MTLBuffer> tf_buffer_mtl = tf_vbo_mtl->get_metal_buffer(&tf_buffer_offset);
+
+ // if (tf_buffer_mtl != nil && tf_buffer_offset >= 0) {
+ // [rec setVertexBuffer:tf_buffer_mtl
+ // offset:tf_buffer_offset
+ // atIndex:pipeline_state_instance->transform_feedback_buffer_index];
+ // printf("Successfully bound VBO: %p for transform feedback (MTL Buffer: %p)\n",
+ // tf_vbo_mtl,
+ // tf_buffer_mtl);
+ // }
+ // }
+
+ /* Matrix Bindings. */
+ /* This is now called upon shader bind. We may need to re-evaluate this though,
+ * as was done here to ensure uniform changes between draws were tracked.
+ * NOTE(Metal): We may be able to remove this. */
+ GPU_matrix_bind(reinterpret_cast<struct GPUShader *>(
+ static_cast<Shader *>(this->pipeline_state.active_shader)));
+
+ /* Bind Uniforms */
+ this->ensure_uniform_buffer_bindings(rec, shader_interface, pipeline_state_instance);
+
+ /* Bind Null attribute buffer, if needed. */
+ if (pipeline_state_instance->null_attribute_buffer_index >= 0) {
+ if (G.debug & G_DEBUG_GPU) {
+ MTL_LOG_INFO("Binding null attribute buffer at index: %d\n",
+ pipeline_state_instance->null_attribute_buffer_index);
+ }
+ rps.bind_vertex_buffer(this->get_null_attribute_buffer(),
+ 0,
+ pipeline_state_instance->null_attribute_buffer_index);
+ }
+
+ /** Dynamic Per-draw Render State on RenderCommandEncoder. */
+ /* State: Viewport. */
+ if (this->pipeline_state.dirty_flags & MTL_PIPELINE_STATE_VIEWPORT_FLAG) {
+ MTLViewport viewport;
+ viewport.originX = (double)this->pipeline_state.viewport_offset_x;
+ viewport.originY = (double)this->pipeline_state.viewport_offset_y;
+ viewport.width = (double)this->pipeline_state.viewport_width;
+ viewport.height = (double)this->pipeline_state.viewport_height;
+ viewport.znear = this->pipeline_state.depth_stencil_state.depth_range_near;
+ viewport.zfar = this->pipeline_state.depth_stencil_state.depth_range_far;
+ [rec setViewport:viewport];
+
+ this->pipeline_state.dirty_flags = (this->pipeline_state.dirty_flags &
+ ~MTL_PIPELINE_STATE_VIEWPORT_FLAG);
+ }
+
+ /* State: Scissor. */
+ if (this->pipeline_state.dirty_flags & MTL_PIPELINE_STATE_SCISSOR_FLAG) {
+
+ /* Get FrameBuffer associated with active RenderCommandEncoder. */
+ MTLFrameBuffer *render_fb = this->main_command_buffer.get_active_framebuffer();
+
+ MTLScissorRect scissor;
+ if (this->pipeline_state.scissor_enabled) {
+ scissor.x = this->pipeline_state.scissor_x;
+ scissor.y = this->pipeline_state.scissor_y;
+ scissor.width = this->pipeline_state.scissor_width;
+ scissor.height = this->pipeline_state.scissor_height;
+
+ /* Some scissor assignments exceed the bounds of the viewport due to implicitly added
+ * padding to the width/height - Clamp width/height. */
+ BLI_assert(scissor.x >= 0 && scissor.x < render_fb->get_width());
+ BLI_assert(scissor.y >= 0 && scissor.y < render_fb->get_height());
+ scissor.width = min_ii(scissor.width, render_fb->get_width() - scissor.x);
+ scissor.height = min_ii(scissor.height, render_fb->get_height() - scissor.y);
+ BLI_assert(scissor.width > 0 && (scissor.x + scissor.width <= render_fb->get_width()));
+ BLI_assert(scissor.height > 0 && (scissor.height <= render_fb->get_height()));
+ }
+ else {
+ /* Scissor is disabled, reset to default size as scissor state may have been previously
+ * assigned on this encoder. */
+ scissor.x = 0;
+ scissor.y = 0;
+ scissor.width = render_fb->get_width();
+ scissor.height = render_fb->get_height();
+ }
+
+ /* Scissor state can still be flagged as changed if it is toggled on and off, without
+ * parameters changing between draws. */
+ if (memcmp(&scissor, &rps.last_scissor_rect, sizeof(MTLScissorRect))) {
+ [rec setScissorRect:scissor];
+ rps.last_scissor_rect = scissor;
+ }
+ this->pipeline_state.dirty_flags = (this->pipeline_state.dirty_flags &
+ ~MTL_PIPELINE_STATE_SCISSOR_FLAG);
+ }
+
+ /* State: Face winding. */
+ if (this->pipeline_state.dirty_flags & MTL_PIPELINE_STATE_FRONT_FACING_FLAG) {
+ /* We need to invert the face winding in Metal, to account for the inverted-Y coordinate
+ * system. */
+ MTLWinding winding = (this->pipeline_state.front_face == GPU_CLOCKWISE) ?
+ MTLWindingClockwise :
+ MTLWindingCounterClockwise;
+ [rec setFrontFacingWinding:winding];
+ this->pipeline_state.dirty_flags = (this->pipeline_state.dirty_flags &
+ ~MTL_PIPELINE_STATE_FRONT_FACING_FLAG);
+ }
+
+ /* State: cull-mode. */
+ if (this->pipeline_state.dirty_flags & MTL_PIPELINE_STATE_CULLMODE_FLAG) {
+
+ MTLCullMode mode = MTLCullModeNone;
+ if (this->pipeline_state.culling_enabled) {
+ switch (this->pipeline_state.cull_mode) {
+ case GPU_CULL_NONE:
+ mode = MTLCullModeNone;
+ break;
+ case GPU_CULL_FRONT:
+ mode = MTLCullModeFront;
+ break;
+ case GPU_CULL_BACK:
+ mode = MTLCullModeBack;
+ break;
+ default:
+ BLI_assert_unreachable();
+ break;
+ }
+ }
+ [rec setCullMode:mode];
+ this->pipeline_state.dirty_flags = (this->pipeline_state.dirty_flags &
+ ~MTL_PIPELINE_STATE_CULLMODE_FLAG);
+ }
+
+ /* Pipeline state is now good. */
+ result = true;
+ }
+ return result;
+}
+
+/* Bind uniform buffers to an active render command encoder using the rendering state of the
+ * current context -> Active shader, Bound UBOs). */
+bool MTLContext::ensure_uniform_buffer_bindings(
+ id<MTLRenderCommandEncoder> rec,
+ const MTLShaderInterface *shader_interface,
+ const MTLRenderPipelineStateInstance *pipeline_state_instance)
+{
+ /* Fetch Render Pass state. */
+ MTLRenderPassState &rps = this->main_command_buffer.get_render_pass_state();
+
+ /* Shader owned push constant block for uniforms.. */
+ bool active_shader_changed = (rps.last_bound_shader_state.shader_ !=
+ this->pipeline_state.active_shader ||
+ rps.last_bound_shader_state.shader_ == nullptr ||
+ rps.last_bound_shader_state.pso_index_ !=
+ pipeline_state_instance->shader_pso_index);
+
+ const MTLShaderUniformBlock &push_constant_block = shader_interface->get_push_constant_block();
+ if (push_constant_block.size > 0) {
+
+ /* Fetch uniform buffer base binding index from pipeline_state_instance - There buffer index
+ * will be offset by the number of bound VBOs. */
+ uint32_t block_size = push_constant_block.size;
+ uint32_t buffer_index = pipeline_state_instance->base_uniform_buffer_index +
+ push_constant_block.buffer_index;
+
+ /* Only need to rebind block if push constants have been modified -- or if no data is bound for
+ * the current RenderCommandEncoder. */
+ if (this->pipeline_state.active_shader->get_push_constant_is_dirty() ||
+ active_shader_changed || !rps.cached_vertex_buffer_bindings[buffer_index].is_bytes ||
+ !rps.cached_fragment_buffer_bindings[buffer_index].is_bytes || true) {
+
+ /* Bind push constant data. */
+ BLI_assert(this->pipeline_state.active_shader->get_push_constant_data() != nullptr);
+ rps.bind_vertex_bytes(
+ this->pipeline_state.active_shader->get_push_constant_data(), block_size, buffer_index);
+ rps.bind_fragment_bytes(
+ this->pipeline_state.active_shader->get_push_constant_data(), block_size, buffer_index);
+
+ /* Only need to rebind block if it has been modified. */
+ this->pipeline_state.active_shader->push_constant_bindstate_mark_dirty(false);
+ }
+ }
+ rps.last_bound_shader_state.set(this->pipeline_state.active_shader,
+ pipeline_state_instance->shader_pso_index);
+
+ /* Bind Global GPUUniformBuffers */
+ /* Iterate through expected UBOs in the shader interface, and check if the globally bound ones
+ * match. This is used to support the gpu_uniformbuffer module, where the uniform data is global,
+ * and not owned by the shader instance. */
+ for (const uint ubo_index : IndexRange(shader_interface->get_total_uniform_blocks())) {
+ const MTLShaderUniformBlock &ubo = shader_interface->get_uniform_block(ubo_index);
+
+ if (ubo.buffer_index >= 0) {
+
+ /* Uniform Buffer index offset by 1 as the first shader buffer binding slot is reserved for
+ * the uniform PushConstantBlock. */
+ const uint32_t buffer_index = ubo.buffer_index + 1;
+ int ubo_offset = 0;
+ id<MTLBuffer> ubo_buffer = nil;
+ int ubo_size = 0;
+
+ bool bind_dummy_buffer = false;
+ if (this->pipeline_state.ubo_bindings[ubo_index].bound) {
+
+ /* Fetch UBO global-binding properties from slot. */
+ ubo_offset = 0;
+ ubo_buffer = this->pipeline_state.ubo_bindings[ubo_index].ubo->get_metal_buffer(
+ &ubo_offset);
+ ubo_size = this->pipeline_state.ubo_bindings[ubo_index].ubo->get_size();
+
+ /* Use dummy zero buffer if no buffer assigned -- this is an optimization to avoid
+ * allocating zero buffers. */
+ if (ubo_buffer == nil) {
+ bind_dummy_buffer = true;
+ }
+ else {
+ BLI_assert(ubo_buffer != nil);
+ BLI_assert(ubo_size > 0);
+
+ if (pipeline_state_instance->reflection_data_available) {
+ /* NOTE: While the vertex and fragment stages have different UBOs, the indices in each
+ * case will be the same for the same UBO.
+ * We also determine expected size and then ensure buffer of the correct size
+ * exists in one of the vertex/fragment shader binding tables. This path is used
+ * to verify that the size of the bound UBO matches what is expected in the shader. */
+ uint32_t expected_size =
+ (buffer_index <
+ pipeline_state_instance->buffer_bindings_reflection_data_vert.size()) ?
+ pipeline_state_instance->buffer_bindings_reflection_data_vert[buffer_index]
+ .size :
+ 0;
+ if (expected_size == 0) {
+ expected_size =
+ (buffer_index <
+ pipeline_state_instance->buffer_bindings_reflection_data_frag.size()) ?
+ pipeline_state_instance->buffer_bindings_reflection_data_frag[buffer_index]
+ .size :
+ 0;
+ }
+ BLI_assert_msg(
+ expected_size > 0,
+ "Shader interface expects UBO, but shader reflection data reports that it "
+ "is not present");
+
+ /* If ubo size is smaller than the size expected by the shader, we need to bind the
+ * dummy buffer, which will be big enough, to avoid an OOB error. */
+ if (ubo_size < expected_size) {
+ MTL_LOG_INFO(
+ "[Error][UBO] UBO (UBO Name: %s) bound at index: %d with size %d (Expected size "
+ "%d) (Shader Name: %s) is too small -- binding NULL buffer. This is likely an "
+ "over-binding, which is not used, but we need this to avoid validation "
+ "issues\n",
+ shader_interface->get_name_at_offset(ubo.name_offset),
+ buffer_index,
+ ubo_size,
+ expected_size,
+ shader_interface->get_name());
+ bind_dummy_buffer = true;
+ }
+ }
+ }
+ }
+ else {
+ MTL_LOG_INFO(
+ "[Warning][UBO] Shader '%s' expected UBO '%s' to be bound at buffer index: %d -- but "
+ "nothing was bound -- binding dummy buffer\n",
+ shader_interface->get_name(),
+ shader_interface->get_name_at_offset(ubo.name_offset),
+ buffer_index);
+ bind_dummy_buffer = true;
+ }
+
+ if (bind_dummy_buffer) {
+ /* Perform Dummy binding. */
+ ubo_offset = 0;
+ ubo_buffer = this->get_null_buffer();
+ ubo_size = [ubo_buffer length];
+ }
+
+ if (ubo_buffer != nil) {
+
+ uint32_t buffer_bind_index = pipeline_state_instance->base_uniform_buffer_index +
+ buffer_index;
+
+ /* Bind Vertex UBO. */
+ if (bool(ubo.stage_mask & ShaderStage::VERTEX)) {
+ BLI_assert(buffer_bind_index >= 0 &&
+ buffer_bind_index < MTL_MAX_UNIFORM_BUFFER_BINDINGS);
+ rps.bind_vertex_buffer(ubo_buffer, ubo_offset, buffer_bind_index);
+ }
+
+ /* Bind Fragment UBOs. */
+ if (bool(ubo.stage_mask & ShaderStage::FRAGMENT)) {
+ BLI_assert(buffer_bind_index >= 0 &&
+ buffer_bind_index < MTL_MAX_UNIFORM_BUFFER_BINDINGS);
+ rps.bind_fragment_buffer(ubo_buffer, ubo_offset, buffer_bind_index);
+ }
+ }
+ else {
+ MTL_LOG_WARNING(
+ "[UBO] Shader '%s' has UBO '%s' bound at buffer index: %d -- but MTLBuffer "
+ "is NULL!\n",
+ shader_interface->get_name(),
+ shader_interface->get_name_at_offset(ubo.name_offset),
+ buffer_index);
+ }
+ }
+ }
+ return true;
+}
+
+/* Ensure texture bindings are correct and up to date for current draw call. */
+void MTLContext::ensure_texture_bindings(
+ id<MTLRenderCommandEncoder> rec,
+ MTLShaderInterface *shader_interface,
+ const MTLRenderPipelineStateInstance *pipeline_state_instance)
+{
+ BLI_assert(shader_interface != nil);
+ BLI_assert(rec != nil);
+
+ /* Fetch Render Pass state. */
+ MTLRenderPassState &rps = this->main_command_buffer.get_render_pass_state();
+
+ @autoreleasepool {
+ int vertex_arg_buffer_bind_index = -1;
+ int fragment_arg_buffer_bind_index = -1;
+
+ /* Argument buffers are used for samplers, when the limit of 16 is exceeded. */
+ bool use_argument_buffer_for_samplers = shader_interface->get_use_argument_buffer_for_samplers(
+ &vertex_arg_buffer_bind_index, &fragment_arg_buffer_bind_index);
+
+ /* Loop through expected textures in shader interface and resolve bindings with currently
+ * bound textures.. */
+ for (const uint t : IndexRange(shader_interface->get_max_texture_index() + 1)) {
+ /* Ensure the bound texture is compatible with the shader interface. If the
+ * shader does not expect a texture to be bound for the current slot, we skip
+ * binding.
+ * NOTE: Global texture bindings may be left over from prior draw calls. */
+ const MTLShaderTexture &shader_texture_info = shader_interface->get_texture(t);
+ if (!shader_texture_info.used) {
+ /* Skip unused binding points if explicit indices are specified. */
+ continue;
+ }
+
+ int slot = shader_texture_info.slot_index;
+ if (slot >= 0 && slot < GPU_max_textures()) {
+ bool bind_dummy_texture = true;
+ if (this->pipeline_state.texture_bindings[slot].used) {
+ gpu::MTLTexture *bound_texture =
+ this->pipeline_state.texture_bindings[slot].texture_resource;
+ MTLSamplerBinding &bound_sampler = this->pipeline_state.sampler_bindings[slot];
+ BLI_assert(bound_texture);
+ BLI_assert(bound_sampler.used);
+
+ if (shader_texture_info.type == bound_texture->type_) {
+ /* Bind texture and sampler if the bound texture matches the type expected by the
+ * shader. */
+ id<MTLTexture> tex = bound_texture->get_metal_handle();
+
+ if (bool(shader_texture_info.stage_mask & ShaderStage::VERTEX)) {
+ rps.bind_vertex_texture(tex, slot);
+ rps.bind_vertex_sampler(bound_sampler, use_argument_buffer_for_samplers, slot);
+ }
+
+ if (bool(shader_texture_info.stage_mask & ShaderStage::FRAGMENT)) {
+ rps.bind_fragment_texture(tex, slot);
+ rps.bind_fragment_sampler(bound_sampler, use_argument_buffer_for_samplers, slot);
+ }
+
+ /* Texture state resolved, no need to bind dummy texture */
+ bind_dummy_texture = false;
+ }
+ else {
+ /* Texture type for bound texture (e.g. Texture2DArray) does not match what was
+ * expected in the shader interface. This is a problem and we will need to bind
+ * a dummy texture to ensure correct API usage. */
+ MTL_LOG_WARNING(
+ "(Shader '%s') Texture %p bound to slot %d is incompatible -- Wrong "
+ "texture target type. (Expecting type %d, actual type %d) (binding "
+ "name:'%s')(texture name:'%s')\n",
+ shader_interface->get_name(),
+ bound_texture,
+ slot,
+ shader_texture_info.type,
+ bound_texture->type_,
+ shader_interface->get_name_at_offset(shader_texture_info.name_offset),
+ bound_texture->get_name());
+ }
+ }
+ else {
+ MTL_LOG_WARNING(
+ "Shader '%s' expected texture to be bound to slot %d -- No texture was "
+ "bound. (name:'%s')\n",
+ shader_interface->get_name(),
+ slot,
+ shader_interface->get_name_at_offset(shader_texture_info.name_offset));
+ }
+
+ /* Bind Dummy texture -- will temporarily resolve validation issues while incorrect formats
+ * are provided -- as certain configurations may not need any binding. These issues should
+ * be fixed in the high-level, if problems crop up. */
+ if (bind_dummy_texture) {
+ if (bool(shader_texture_info.stage_mask & ShaderStage::VERTEX)) {
+ rps.bind_vertex_texture(
+ get_dummy_texture(shader_texture_info.type)->get_metal_handle(), slot);
+
+ /* Bind default sampler state. */
+ MTLSamplerBinding default_binding = {true, DEFAULT_SAMPLER_STATE};
+ rps.bind_vertex_sampler(default_binding, use_argument_buffer_for_samplers, slot);
+ }
+ if (bool(shader_texture_info.stage_mask & ShaderStage::FRAGMENT)) {
+ rps.bind_fragment_texture(
+ get_dummy_texture(shader_texture_info.type)->get_metal_handle(), slot);
+
+ /* Bind default sampler state. */
+ MTLSamplerBinding default_binding = {true, DEFAULT_SAMPLER_STATE};
+ rps.bind_fragment_sampler(default_binding, use_argument_buffer_for_samplers, slot);
+ }
+ }
+ }
+ else {
+ MTL_LOG_WARNING(
+ "Shader %p expected texture to be bound to slot %d -- Slot exceeds the "
+ "hardware/API limit of '%d'. (name:'%s')\n",
+ this->pipeline_state.active_shader,
+ slot,
+ GPU_max_textures(),
+ shader_interface->get_name_at_offset(shader_texture_info.name_offset));
+ }
+ }
+
+ /* Construct and Bind argument buffer.
+ * NOTE(Metal): Samplers use an argument buffer when the limit of 16 samplers is exceeded. */
+ if (use_argument_buffer_for_samplers) {
+#ifndef NDEBUG
+ /* Debug check to validate each expected texture in the shader interface has a valid
+ * sampler object bound to the context. We will need all of these to be valid
+ * when constructing the sampler argument buffer. */
+ for (const uint i : IndexRange(shader_interface->get_max_texture_index() + 1)) {
+ const MTLShaderTexture &texture = shader_interface->get_texture(i);
+ if (texture.used) {
+ BLI_assert(this->samplers_.mtl_sampler[i] != nil);
+ }
+ }
+#endif
+
+ /* Check to ensure the buffer binding index for the argument buffer has been assigned.
+ * This PSO property will be set if we expect to use argument buffers, and the shader
+ * uses any amount of textures. */
+ BLI_assert(vertex_arg_buffer_bind_index >= 0 || fragment_arg_buffer_bind_index >= 0);
+ if (vertex_arg_buffer_bind_index >= 0 || fragment_arg_buffer_bind_index >= 0) {
+ /* Offset binding index to be relative to the start of static uniform buffer binding slots.
+ * The first N slots, prior to `pipeline_state_instance->base_uniform_buffer_index` are
+ * used by vertex and index buffer bindings, and the number of buffers present will vary
+ * between PSOs. */
+ int arg_buffer_idx = (pipeline_state_instance->base_uniform_buffer_index +
+ vertex_arg_buffer_bind_index);
+ assert(arg_buffer_idx < 32);
+ id<MTLArgumentEncoder> argument_encoder = shader_interface->find_argument_encoder(
+ arg_buffer_idx);
+ if (argument_encoder == nil) {
+ argument_encoder = [pipeline_state_instance->vert
+ newArgumentEncoderWithBufferIndex:arg_buffer_idx];
+ shader_interface->insert_argument_encoder(arg_buffer_idx, argument_encoder);
+ }
+
+ /* Generate or Fetch argument buffer sampler configuration.
+ * NOTE(Metal): we need to base sampler counts off of the maximal texture
+ * index. This is not the most optimal, but in practice, not a use-case
+ * when argument buffers are required.
+ * This is because with explicit texture indices, the binding indices
+ * should match across draws, to allow the high-level to optimize bind-points. */
+ gpu::MTLBuffer *encoder_buffer = nullptr;
+ this->samplers_.num_samplers = shader_interface->get_max_texture_index() + 1;
+
+ gpu::MTLBuffer **cached_smp_buffer_search = this->cached_sampler_buffers_.lookup_ptr(
+ this->samplers_);
+ if (cached_smp_buffer_search != nullptr) {
+ encoder_buffer = *cached_smp_buffer_search;
+ }
+ else {
+ /* Populate argument buffer with current global sampler bindings. */
+ int size = [argument_encoder encodedLength];
+ int alignment = max_uu([argument_encoder alignment], 256);
+ int size_align_delta = (size % alignment);
+ int aligned_alloc_size = ((alignment > 1) && (size_align_delta > 0)) ?
+ size + (alignment - (size % alignment)) :
+ size;
+
+ /* Allocate buffer to store encoded sampler arguments. */
+ encoder_buffer = MTLContext::get_global_memory_manager().allocate(aligned_alloc_size,
+ true);
+ BLI_assert(encoder_buffer);
+ BLI_assert(encoder_buffer->get_metal_buffer());
+ [argument_encoder setArgumentBuffer:encoder_buffer->get_metal_buffer() offset:0];
+ [argument_encoder
+ setSamplerStates:this->samplers_.mtl_sampler
+ withRange:NSMakeRange(0, shader_interface->get_max_texture_index() + 1)];
+ encoder_buffer->flush();
+
+ /* Insert into cache. */
+ this->cached_sampler_buffers_.add_new(this->samplers_, encoder_buffer);
+ }
+
+ BLI_assert(encoder_buffer != nullptr);
+ int vert_buffer_index = (pipeline_state_instance->base_uniform_buffer_index +
+ vertex_arg_buffer_bind_index);
+ rps.bind_vertex_buffer(encoder_buffer->get_metal_buffer(), 0, vert_buffer_index);
+
+ /* Fragment shader shares its argument buffer binding with the vertex shader, So no need to
+ * re-encode. We can use the same argument buffer. */
+ if (fragment_arg_buffer_bind_index >= 0) {
+ BLI_assert(fragment_arg_buffer_bind_index);
+ int frag_buffer_index = (pipeline_state_instance->base_uniform_buffer_index +
+ fragment_arg_buffer_bind_index);
+ rps.bind_fragment_buffer(encoder_buffer->get_metal_buffer(), 0, frag_buffer_index);
+ }
+ }
+ }
+ }
+}
+
+/* Encode latest depth-stencil state. */
+void MTLContext::ensure_depth_stencil_state(MTLPrimitiveType prim_type)
+{
+ /* Check if we need to update state. */
+ if (!(this->pipeline_state.dirty_flags & MTL_PIPELINE_STATE_DEPTHSTENCIL_FLAG)) {
+ return;
+ }
+
+ /* Fetch render command encoder. */
+ id<MTLRenderCommandEncoder> rec = this->main_command_buffer.get_active_render_command_encoder();
+ BLI_assert(rec);
+
+ /* Fetch Render Pass state. */
+ MTLRenderPassState &rps = this->main_command_buffer.get_render_pass_state();
+
+ /** Prepare Depth-stencil state based on current global pipeline state. */
+ MTLFrameBuffer *fb = this->get_current_framebuffer();
+ bool hasDepthTarget = fb->has_depth_attachment();
+ bool hasStencilTarget = fb->has_stencil_attachment();
+
+ if (hasDepthTarget || hasStencilTarget) {
+ /* Update FrameBuffer State. */
+ this->pipeline_state.depth_stencil_state.has_depth_target = hasDepthTarget;
+ this->pipeline_state.depth_stencil_state.has_stencil_target = hasStencilTarget;
+
+ /* Check if current MTLContextDepthStencilState maps to an existing state object in
+ * the Depth-stencil state cache. */
+ id<MTLDepthStencilState> ds_state = nil;
+ id<MTLDepthStencilState> *depth_stencil_state_lookup =
+ this->depth_stencil_state_cache.lookup_ptr(this->pipeline_state.depth_stencil_state);
+
+ /* If not, populate DepthStencil state descriptor. */
+ if (depth_stencil_state_lookup == nullptr) {
+
+ MTLDepthStencilDescriptor *ds_state_desc = [[[MTLDepthStencilDescriptor alloc] init]
+ autorelease];
+
+ if (hasDepthTarget) {
+ ds_state_desc.depthWriteEnabled =
+ this->pipeline_state.depth_stencil_state.depth_write_enable;
+ ds_state_desc.depthCompareFunction =
+ this->pipeline_state.depth_stencil_state.depth_test_enabled ?
+ this->pipeline_state.depth_stencil_state.depth_function :
+ MTLCompareFunctionAlways;
+ }
+
+ if (hasStencilTarget) {
+ ds_state_desc.backFaceStencil.readMask =
+ this->pipeline_state.depth_stencil_state.stencil_read_mask;
+ ds_state_desc.backFaceStencil.writeMask =
+ this->pipeline_state.depth_stencil_state.stencil_write_mask;
+ ds_state_desc.backFaceStencil.stencilFailureOperation =
+ this->pipeline_state.depth_stencil_state.stencil_op_back_stencil_fail;
+ ds_state_desc.backFaceStencil.depthFailureOperation =
+ this->pipeline_state.depth_stencil_state.stencil_op_back_depth_fail;
+ ds_state_desc.backFaceStencil.depthStencilPassOperation =
+ this->pipeline_state.depth_stencil_state.stencil_op_back_depthstencil_pass;
+ ds_state_desc.backFaceStencil.stencilCompareFunction =
+ (this->pipeline_state.depth_stencil_state.stencil_test_enabled) ?
+ this->pipeline_state.depth_stencil_state.stencil_func :
+ MTLCompareFunctionAlways;
+
+ ds_state_desc.frontFaceStencil.readMask =
+ this->pipeline_state.depth_stencil_state.stencil_read_mask;
+ ds_state_desc.frontFaceStencil.writeMask =
+ this->pipeline_state.depth_stencil_state.stencil_write_mask;
+ ds_state_desc.frontFaceStencil.stencilFailureOperation =
+ this->pipeline_state.depth_stencil_state.stencil_op_front_stencil_fail;
+ ds_state_desc.frontFaceStencil.depthFailureOperation =
+ this->pipeline_state.depth_stencil_state.stencil_op_front_depth_fail;
+ ds_state_desc.frontFaceStencil.depthStencilPassOperation =
+ this->pipeline_state.depth_stencil_state.stencil_op_front_depthstencil_pass;
+ ds_state_desc.frontFaceStencil.stencilCompareFunction =
+ (this->pipeline_state.depth_stencil_state.stencil_test_enabled) ?
+ this->pipeline_state.depth_stencil_state.stencil_func :
+ MTLCompareFunctionAlways;
+ }
+
+ /* Bake new DS state. */
+ ds_state = [this->device newDepthStencilStateWithDescriptor:ds_state_desc];
+
+ /* Store state in cache. */
+ BLI_assert(ds_state != nil);
+ this->depth_stencil_state_cache.add_new(this->pipeline_state.depth_stencil_state, ds_state);
+ }
+ else {
+ ds_state = *depth_stencil_state_lookup;
+ BLI_assert(ds_state != nil);
+ }
+
+ /* Bind Depth Stencil State to render command encoder. */
+ BLI_assert(ds_state != nil);
+ if (ds_state != nil) {
+ if (rps.bound_ds_state != ds_state) {
+ [rec setDepthStencilState:ds_state];
+ rps.bound_ds_state = ds_state;
+ }
+ }
+
+ /* Apply dynamic depth-stencil state on encoder. */
+ if (hasStencilTarget) {
+ uint32_t stencil_ref_value =
+ (this->pipeline_state.depth_stencil_state.stencil_test_enabled) ?
+ this->pipeline_state.depth_stencil_state.stencil_ref :
+ 0;
+ if (stencil_ref_value != rps.last_used_stencil_ref_value) {
+ [rec setStencilReferenceValue:stencil_ref_value];
+ rps.last_used_stencil_ref_value = stencil_ref_value;
+ }
+ }
+
+ if (hasDepthTarget) {
+ bool doBias = false;
+ switch (prim_type) {
+ case MTLPrimitiveTypeTriangle:
+ case MTLPrimitiveTypeTriangleStrip:
+ doBias = this->pipeline_state.depth_stencil_state.depth_bias_enabled_for_tris;
+ break;
+ case MTLPrimitiveTypeLine:
+ case MTLPrimitiveTypeLineStrip:
+ doBias = this->pipeline_state.depth_stencil_state.depth_bias_enabled_for_lines;
+ break;
+ case MTLPrimitiveTypePoint:
+ doBias = this->pipeline_state.depth_stencil_state.depth_bias_enabled_for_points;
+ break;
+ }
+ [rec setDepthBias:(doBias) ? this->pipeline_state.depth_stencil_state.depth_bias : 0
+ slopeScale:(doBias) ? this->pipeline_state.depth_stencil_state.depth_slope_scale : 0
+ clamp:0];
+ }
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Visibility buffer control for MTLQueryPool.
* \{ */
@@ -605,4 +1625,148 @@ id<MTLSamplerState> MTLContext::get_default_sampler_state()
/** \} */
+/* -------------------------------------------------------------------- */
+/** \name Swap-chain management and Metal presentation.
+ * \{ */
+
+void present(MTLRenderPassDescriptor *blit_descriptor,
+ id<MTLRenderPipelineState> blit_pso,
+ id<MTLTexture> swapchain_texture,
+ id<CAMetalDrawable> drawable)
+{
+
+ MTLContext *ctx = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
+ BLI_assert(ctx);
+
+ /* Flush any outstanding work. */
+ ctx->flush();
+
+ /* Always pace CPU to maximum of 3 drawables in flight.
+ * nextDrawable may have more in flight if backing swapchain
+ * textures are re-allocate, such as during resize events.
+ *
+ * Determine frames in flight based on current latency. If
+ * we are in a high-latency situation, limit frames in flight
+ * to increase app responsiveness and keep GPU execution under control.
+ * If latency improves, increase frames in flight to improve overall
+ * performance. */
+ int perf_max_drawables = MTL_MAX_DRAWABLES;
+ if (MTLContext::avg_drawable_latency_us > 185000) {
+ perf_max_drawables = 1;
+ }
+ else if (MTLContext::avg_drawable_latency_us > 85000) {
+ perf_max_drawables = 2;
+ }
+
+ while (MTLContext::max_drawables_in_flight > min_ii(perf_max_drawables, MTL_MAX_DRAWABLES)) {
+ PIL_sleep_ms(2);
+ }
+
+ /* Present is submitted in its own CMD Buffer to ensure drawable reference released as early as
+ * possible. This command buffer is separate as it does not utilize the global state
+ * for rendering as the main context does. */
+ id<MTLCommandBuffer> cmdbuf = [ctx->queue commandBuffer];
+ MTLCommandBufferManager::num_active_cmd_bufs++;
+
+ if (MTLCommandBufferManager::sync_event != nil) {
+ /* Ensure command buffer ordering. */
+ [cmdbuf encodeWaitForEvent:MTLCommandBufferManager::sync_event
+ value:MTLCommandBufferManager::event_signal_val];
+ }
+
+ /* Do Present Call and final Blit to MTLDrawable. */
+ id<MTLRenderCommandEncoder> enc = [cmdbuf renderCommandEncoderWithDescriptor:blit_descriptor];
+ [enc setRenderPipelineState:blit_pso];
+ [enc setFragmentTexture:swapchain_texture atIndex:0];
+ [enc drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:3];
+ [enc endEncoding];
+
+ /* Present drawable. */
+ BLI_assert(drawable);
+ [cmdbuf presentDrawable:drawable];
+
+ /* Ensure freed buffers have usage tracked against active CommandBuffer submissions. */
+ MTLSafeFreeList *cmd_free_buffer_list =
+ MTLContext::get_global_memory_manager().get_current_safe_list();
+ BLI_assert(cmd_free_buffer_list);
+
+ id<MTLCommandBuffer> cmd_buffer_ref = cmdbuf;
+ [cmd_buffer_ref retain];
+
+ /* Increment drawables in flight limiter. */
+ MTLContext::max_drawables_in_flight++;
+ std::chrono::time_point submission_time = std::chrono::high_resolution_clock::now();
+
+ /* Increment free pool reference and decrement upon command buffer completion. */
+ cmd_free_buffer_list->increment_reference();
+ [cmdbuf addCompletedHandler:^(id<MTLCommandBuffer> cb) {
+ /* Flag freed buffers associated with this CMD buffer as ready to be freed. */
+ cmd_free_buffer_list->decrement_reference();
+ [cmd_buffer_ref release];
+
+ /* Decrement count */
+ MTLCommandBufferManager::num_active_cmd_bufs--;
+ MTL_LOG_INFO("[Metal] Active command buffers: %d\n",
+ MTLCommandBufferManager::num_active_cmd_bufs);
+
+ /* Drawable count and latency management. */
+ MTLContext::max_drawables_in_flight--;
+ std::chrono::time_point completion_time = std::chrono::high_resolution_clock::now();
+ int64_t microseconds_per_frame = std::chrono::duration_cast<std::chrono::microseconds>(
+ completion_time - submission_time)
+ .count();
+ MTLContext::latency_resolve_average(microseconds_per_frame);
+
+ MTL_LOG_INFO("Frame Latency: %f ms (Rolling avg: %f ms Drawables: %d)\n",
+ ((float)microseconds_per_frame) / 1000.0f,
+ ((float)MTLContext::avg_drawable_latency_us) / 1000.0f,
+ perf_max_drawables);
+ }];
+
+ if (MTLCommandBufferManager::sync_event == nil) {
+ MTLCommandBufferManager::sync_event = [ctx->device newEvent];
+ BLI_assert(MTLCommandBufferManager::sync_event);
+ [MTLCommandBufferManager::sync_event retain];
+ }
+ BLI_assert(MTLCommandBufferManager::sync_event != nil);
+
+ MTLCommandBufferManager::event_signal_val++;
+ [cmdbuf encodeSignalEvent:MTLCommandBufferManager::sync_event
+ value:MTLCommandBufferManager::event_signal_val];
+
+ [cmdbuf commit];
+
+ /* When debugging, fetch advanced command buffer errors. */
+ if (G.debug & G_DEBUG_GPU) {
+ [cmdbuf waitUntilCompleted];
+ NSError *error = [cmdbuf error];
+ if (error != nil) {
+ NSLog(@"%@", error);
+ BLI_assert(false);
+
+ @autoreleasepool {
+ const char *stringAsChar = [[NSString stringWithFormat:@"%@", error] UTF8String];
+
+ std::ofstream outfile;
+ outfile.open("command_buffer_error.txt", std::fstream::out | std::fstream::app);
+ outfile << stringAsChar;
+ outfile.close();
+ }
+ }
+ else {
+ @autoreleasepool {
+ NSString *str = @"Command buffer completed successfully!\n";
+ const char *stringAsChar = [str UTF8String];
+
+ std::ofstream outfile;
+ outfile.open("command_buffer_error.txt", std::fstream::out | std::fstream::app);
+ outfile << stringAsChar;
+ outfile.close();
+ }
+ }
+ }
+}
+
+/** \} */
+
} // blender::gpu
diff --git a/source/blender/gpu/metal/mtl_drawlist.hh b/source/blender/gpu/metal/mtl_drawlist.hh
new file mode 100644
index 00000000000..47055f3d7f4
--- /dev/null
+++ b/source/blender/gpu/metal/mtl_drawlist.hh
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup gpu
+ *
+ * Implementation of Multi Draw Indirect using OpenGL.
+ * Fallback if the needed extensions are not supported.
+ */
+
+#pragma once
+
+#include "BLI_sys_types.h"
+#include "GPU_batch.h"
+#include "MEM_guardedalloc.h"
+#include "gpu_drawlist_private.hh"
+
+#include "mtl_batch.hh"
+#include "mtl_context.hh"
+
+namespace blender::gpu {
+
+/**
+ * Implementation of Multi Draw Indirect using OpenGL.
+ **/
+class MTLDrawList : public DrawList {
+
+ private:
+ /** Batch for which we are recording commands for. */
+ MTLBatch *batch_;
+ /** Mapped memory bounds. */
+ void *data_;
+ /** Length of the mapped buffer (in byte). */
+ size_t data_size_;
+ /** Current offset inside the mapped buffer (in byte). */
+ size_t command_offset_;
+ /** Current number of command recorded inside the mapped buffer. */
+ uint32_t command_len_;
+ /** Is UINT_MAX if not drawing indexed geom. Also Avoid dereferencing batch. */
+ uint32_t base_index_;
+ /** Also Avoid dereferencing batch. */
+ uint32_t v_first_, v_count_;
+ /** Length of whole the buffer (in byte). */
+ uint32_t buffer_size_;
+
+ public:
+ MTLDrawList(int length);
+ ~MTLDrawList();
+
+ void append(GPUBatch *batch, int i_first, int i_count) override;
+ void submit() override;
+
+ private:
+ void init();
+
+ MEM_CXX_CLASS_ALLOC_FUNCS("MTLDrawList");
+};
+
+} // namespace blender::gpu
diff --git a/source/blender/gpu/metal/mtl_drawlist.mm b/source/blender/gpu/metal/mtl_drawlist.mm
new file mode 100644
index 00000000000..99194d2b72c
--- /dev/null
+++ b/source/blender/gpu/metal/mtl_drawlist.mm
@@ -0,0 +1,284 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup gpu
+ *
+ * Implementation of Multi Draw Indirect using OpenGL.
+ * Fallback if the needed extensions are not supported.
+ */
+
+#include "BLI_assert.h"
+
+#include "GPU_batch.h"
+#include "mtl_common.hh"
+#include "mtl_drawlist.hh"
+#include "mtl_primitive.hh"
+
+using namespace blender::gpu;
+
+namespace blender::gpu {
+
+/* Indirect draw call structure for reference. */
+/* MTLDrawPrimitivesIndirectArguments --
+ * https://developer.apple.com/documentation/metal/mtldrawprimitivesindirectarguments?language=objc
+ */
+/* struct MTLDrawPrimitivesIndirectArguments {
+ * uint32_t vertexCount;
+ * uint32_t instanceCount;
+ * uint32_t vertexStart;
+ * uint32_t baseInstance;
+};*/
+
+/* MTLDrawIndexedPrimitivesIndirectArguments --
+ * https://developer.apple.com/documentation/metal/mtldrawindexedprimitivesindirectarguments?language=objc
+ */
+/* struct MTLDrawIndexedPrimitivesIndirectArguments {
+ * uint32_t indexCount;
+ * uint32_t instanceCount;
+ * uint32_t indexStart;
+ * uint32_t baseVertex;
+ * uint32_t baseInstance;
+};*/
+
+#define MDI_ENABLED (buffer_size_ != 0)
+#define MDI_DISABLED (buffer_size_ == 0)
+#define MDI_INDEXED (base_index_ != UINT_MAX)
+
+MTLDrawList::MTLDrawList(int length)
+{
+ BLI_assert(length > 0);
+ batch_ = nullptr;
+ command_len_ = 0;
+ base_index_ = 0;
+ command_offset_ = 0;
+ data_size_ = 0;
+ buffer_size_ = sizeof(MTLDrawIndexedPrimitivesIndirectArguments) * length;
+ data_ = (void *)MEM_mallocN(buffer_size_, __func__);
+}
+
+MTLDrawList::~MTLDrawList()
+{
+ if (data_) {
+ MEM_freeN(data_);
+ data_ = nullptr;
+ }
+}
+
+void MTLDrawList::init()
+{
+ MTLContext *ctx = reinterpret_cast<MTLContext *>(GPU_context_active_get());
+ BLI_assert(ctx);
+ BLI_assert(MDI_ENABLED);
+ BLI_assert(data_ == nullptr);
+ UNUSED_VARS_NDEBUG(ctx);
+
+ batch_ = nullptr;
+ command_len_ = 0;
+ BLI_assert(data_);
+
+ command_offset_ = 0;
+}
+
+void MTLDrawList::append(GPUBatch *gpu_batch, int i_first, int i_count)
+{
+ /* Fallback when MultiDrawIndirect is not supported/enabled. */
+ MTLShader *shader = static_cast<MTLShader *>(unwrap(gpu_batch->shader));
+ bool requires_ssbo = (shader->get_uses_ssbo_vertex_fetch());
+ bool requires_emulation = mtl_needs_topology_emulation(gpu_batch->prim_type);
+ if (MDI_DISABLED || requires_ssbo || requires_emulation) {
+ GPU_batch_draw_advanced(gpu_batch, 0, 0, i_first, i_count);
+ return;
+ }
+
+ if (data_ == nullptr) {
+ this->init();
+ }
+ BLI_assert(data_);
+
+ MTLBatch *mtl_batch = static_cast<MTLBatch *>(gpu_batch);
+ BLI_assert(mtl_batch);
+ if (mtl_batch != batch_) {
+ /* Submit existing calls. */
+ this->submit();
+
+ /* Begin new batch. */
+ batch_ = mtl_batch;
+
+ /* Cached for faster access. */
+ MTLIndexBuf *el = batch_->elem_();
+ base_index_ = el ? el->index_base_ : UINT_MAX;
+ v_first_ = el ? el->index_start_ : 0;
+ v_count_ = el ? el->index_len_ : batch_->verts_(0)->vertex_len;
+ }
+
+ if (v_count_ == 0) {
+ /* Nothing to draw. */
+ return;
+ }
+
+ if (MDI_INDEXED) {
+ MTLDrawIndexedPrimitivesIndirectArguments *cmd =
+ reinterpret_cast<MTLDrawIndexedPrimitivesIndirectArguments *>((char *)data_ +
+ command_offset_);
+ cmd->indexStart = v_first_;
+ cmd->indexCount = v_count_;
+ cmd->instanceCount = i_count;
+ cmd->baseVertex = base_index_;
+ cmd->baseInstance = i_first;
+ }
+ else {
+ MTLDrawPrimitivesIndirectArguments *cmd =
+ reinterpret_cast<MTLDrawPrimitivesIndirectArguments *>((char *)data_ + command_offset_);
+ cmd->vertexStart = v_first_;
+ cmd->vertexCount = v_count_;
+ cmd->instanceCount = i_count;
+ cmd->baseInstance = i_first;
+ }
+
+ size_t command_size = MDI_INDEXED ? sizeof(MTLDrawIndexedPrimitivesIndirectArguments) :
+ sizeof(MTLDrawPrimitivesIndirectArguments);
+
+ command_offset_ += command_size;
+ command_len_++;
+
+ /* Check if we can fit at least one other command. */
+ if (command_offset_ + command_size > buffer_size_) {
+ this->submit();
+ }
+
+ return;
+}
+
+void MTLDrawList::submit()
+{
+ /* Metal does not support MDI from the host side, but we still benefit from only executing the
+ * batch bind a single time, rather than per-draw.
+ * NOTE(Metal): Consider using #MTLIndirectCommandBuffer to achieve similar behavior. */
+ if (command_len_ == 0) {
+ return;
+ }
+
+ /* Something's wrong if we get here without MDI support. */
+ BLI_assert(MDI_ENABLED);
+ BLI_assert(data_);
+
+ /* Host-side MDI Currently unsupported on Metal. */
+ bool can_use_MDI = false;
+
+ /* Verify context. */
+ MTLContext *ctx = reinterpret_cast<MTLContext *>(GPU_context_active_get());
+ BLI_assert(ctx);
+
+ /* Execute indirect draw calls. */
+ MTLShader *shader = static_cast<MTLShader *>(unwrap(batch_->shader));
+ bool SSBO_MODE = (shader->get_uses_ssbo_vertex_fetch());
+ if (SSBO_MODE) {
+ can_use_MDI = false;
+ BLI_assert(false);
+ return;
+ }
+
+ /* Heuristic to determine whether using indirect drawing is more efficient. */
+ size_t command_size = MDI_INDEXED ? sizeof(MTLDrawIndexedPrimitivesIndirectArguments) :
+ sizeof(MTLDrawPrimitivesIndirectArguments);
+ const bool is_finishing_a_buffer = (command_offset_ + command_size > buffer_size_);
+ can_use_MDI = can_use_MDI && (is_finishing_a_buffer || command_len_ > 2);
+
+ /* Bind Batch to setup render pipeline state. */
+ id<MTLRenderCommandEncoder> rec = batch_->bind(0, 0, 0, 0);
+ if (!rec) {
+ BLI_assert_msg(false, "A RenderCommandEncoder should always be available!\n");
+ return;
+ }
+
+ /* Common properties. */
+ MTLPrimitiveType mtl_prim_type = gpu_prim_type_to_metal(batch_->prim_type);
+
+ /* Execute multi-draw indirect. */
+ if (can_use_MDI && false) {
+ /* Metal Doesn't support MDI -- Singular Indirect draw calls are supported,
+ * but Multi-draw is not.
+ * TODO(Metal): Consider using #IndirectCommandBuffers to provide similar
+ * behavior. */
+ }
+ else {
+
+ /* Execute draws manually. */
+ if (MDI_INDEXED) {
+ MTLDrawIndexedPrimitivesIndirectArguments *cmd =
+ (MTLDrawIndexedPrimitivesIndirectArguments *)data_;
+ MTLIndexBuf *mtl_elem = static_cast<MTLIndexBuf *>(
+ reinterpret_cast<IndexBuf *>(batch_->elem));
+ BLI_assert(mtl_elem);
+ MTLIndexType index_type = MTLIndexBuf::gpu_index_type_to_metal(mtl_elem->index_type_);
+ uint32_t index_size = (mtl_elem->index_type_ == GPU_INDEX_U16) ? 2 : 4;
+ uint32_t v_first_ofs = (mtl_elem->index_start_ * index_size);
+ uint32_t index_count = cmd->indexCount;
+
+ /* Fetch index buffer. May return an index buffer of a differing format,
+ * if index buffer optimization is used. In these cases, mtl_prim_type and
+ * index_count get updated with the new properties. */
+ GPUPrimType final_prim_type = batch_->prim_type;
+ id<MTLBuffer> index_buffer = mtl_elem->get_index_buffer(final_prim_type, index_count);
+ BLI_assert(index_buffer != nil);
+
+ /* Final primitive type. */
+ mtl_prim_type = gpu_prim_type_to_metal(final_prim_type);
+
+ if (index_buffer != nil) {
+
+ /* Set depth stencil state (requires knowledge of primitive type). */
+ ctx->ensure_depth_stencil_state(mtl_prim_type);
+
+ for (int i = 0; i < command_len_; i++, cmd++) {
+ [rec drawIndexedPrimitives:mtl_prim_type
+ indexCount:index_count
+ indexType:index_type
+ indexBuffer:index_buffer
+ indexBufferOffset:v_first_ofs
+ instanceCount:cmd->instanceCount
+ baseVertex:cmd->baseVertex
+ baseInstance:cmd->baseInstance];
+ ctx->main_command_buffer.register_draw_counters(cmd->indexCount * cmd->instanceCount);
+ }
+ }
+ else {
+ BLI_assert_msg(false, "Index buffer does not have backing Metal buffer");
+ }
+ }
+ else {
+ MTLDrawPrimitivesIndirectArguments *cmd = (MTLDrawPrimitivesIndirectArguments *)data_;
+
+ /* Verify if topology emulation is required. */
+ if (mtl_needs_topology_emulation(batch_->prim_type)) {
+ BLI_assert_msg(false, "topology emulation cases should use fallback.");
+ }
+ else {
+
+ /* Set depth stencil state (requires knowledge of primitive type). */
+ ctx->ensure_depth_stencil_state(mtl_prim_type);
+
+ for (int i = 0; i < command_len_; i++, cmd++) {
+ [rec drawPrimitives:mtl_prim_type
+ vertexStart:cmd->vertexStart
+ vertexCount:cmd->vertexCount
+ instanceCount:cmd->instanceCount
+ baseInstance:cmd->baseInstance];
+ ctx->main_command_buffer.register_draw_counters(cmd->vertexCount * cmd->instanceCount);
+ }
+ }
+ }
+ }
+
+ /* Unbind batch. */
+ batch_->unbind();
+
+ /* Reset command offsets. */
+ command_len_ = 0;
+ command_offset_ = 0;
+
+ /* Avoid keeping reference to the batch. */
+ batch_ = nullptr;
+}
+
+} // namespace blender::gpu
diff --git a/source/blender/gpu/metal/mtl_immediate.hh b/source/blender/gpu/metal/mtl_immediate.hh
new file mode 100644
index 00000000000..8d852282ac8
--- /dev/null
+++ b/source/blender/gpu/metal/mtl_immediate.hh
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup gpu
+ *
+ * Mimics old style opengl immediate mode drawing.
+ */
+
+#pragma once
+
+#include "MEM_guardedalloc.h"
+#include "gpu_immediate_private.hh"
+
+#include <Cocoa/Cocoa.h>
+#include <Metal/Metal.h>
+#include <QuartzCore/QuartzCore.h>
+
+namespace blender::gpu {
+
+class MTLImmediate : public Immediate {
+ private:
+ MTLContext *context_ = nullptr;
+ MTLTemporaryBuffer current_allocation_;
+ MTLPrimitiveTopologyClass metal_primitive_mode_;
+ MTLPrimitiveType metal_primitive_type_;
+ bool has_begun_ = false;
+
+ public:
+ MTLImmediate(MTLContext *ctx);
+ ~MTLImmediate();
+
+ uchar *begin() override;
+ void end() override;
+ bool imm_is_recording()
+ {
+ return has_begun_;
+ }
+};
+
+} // namespace blender::gpu
diff --git a/source/blender/gpu/metal/mtl_immediate.mm b/source/blender/gpu/metal/mtl_immediate.mm
new file mode 100644
index 00000000000..ee48bdd6ee1
--- /dev/null
+++ b/source/blender/gpu/metal/mtl_immediate.mm
@@ -0,0 +1,401 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup gpu
+ *
+ * Mimics old style opengl immediate mode drawing.
+ */
+
+#include "BKE_global.h"
+
+#include "GPU_vertex_format.h"
+#include "gpu_context_private.hh"
+#include "gpu_shader_private.hh"
+#include "gpu_vertex_format_private.h"
+
+#include "mtl_context.hh"
+#include "mtl_debug.hh"
+#include "mtl_immediate.hh"
+#include "mtl_primitive.hh"
+#include "mtl_shader.hh"
+
+namespace blender::gpu {
+
+MTLImmediate::MTLImmediate(MTLContext *ctx)
+{
+ context_ = ctx;
+}
+
+MTLImmediate::~MTLImmediate()
+{
+}
+
+uchar *MTLImmediate::begin()
+{
+ BLI_assert(!has_begun_);
+
+ /* Determine primitive type. */
+ metal_primitive_type_ = gpu_prim_type_to_metal(this->prim_type);
+ metal_primitive_mode_ = mtl_prim_type_to_topology_class(metal_primitive_type_);
+ has_begun_ = true;
+
+ /* Allocate a range of data and return host-accessible pointer. */
+ const size_t bytes_needed = vertex_buffer_size(&vertex_format, vertex_len);
+ current_allocation_ = context_->get_scratchbuffer_manager()
+ .scratch_buffer_allocate_range_aligned(bytes_needed, 256);
+ [current_allocation_.metal_buffer retain];
+ return reinterpret_cast<uchar *>(current_allocation_.data);
+}
+
+void MTLImmediate::end()
+{
+ /* Ensure we're between a `imm::begin` / `imm:end` pair. */
+ BLI_assert(has_begun_);
+ BLI_assert(prim_type != GPU_PRIM_NONE);
+
+ /* Verify context is valid, vertex data is written and a valid shader is bound. */
+ if (context_ && this->vertex_idx > 0 && this->shader) {
+
+ MTLShader *active_mtl_shader = static_cast<MTLShader *>(unwrap(shader));
+
+ /* Skip draw if Metal shader is not valid. */
+ if (active_mtl_shader == nullptr || !active_mtl_shader->is_valid() ||
+ active_mtl_shader->get_interface() == nullptr) {
+
+ const char *ptr = (active_mtl_shader) ? active_mtl_shader->name_get() : nullptr;
+ MTL_LOG_WARNING(
+ "MTLImmediate::end -- cannot perform draw as active shader is NULL or invalid (likely "
+ "unimplemented) (shader %p '%s')\n",
+ active_mtl_shader,
+ ptr);
+ return;
+ }
+
+ /* Ensure we are inside a render pass and fetch active RenderCommandEncoder. */
+ id<MTLRenderCommandEncoder> rec = context_->ensure_begin_render_pass();
+ BLI_assert(rec != nil);
+
+ /* Fetch active render pipeline state. */
+ MTLRenderPassState &rps = context_->main_command_buffer.get_render_pass_state();
+
+ /* Bind Shader. */
+ GPU_shader_bind(this->shader);
+
+ /* Debug markers for frame-capture and detailed error messages. */
+ if (G.debug & G_DEBUG_GPU) {
+ [rec pushDebugGroup:[NSString
+ stringWithFormat:@"immEnd(verts: %d, shader: %s)",
+ this->vertex_idx,
+ active_mtl_shader->get_interface()->get_name()]];
+ [rec insertDebugSignpost:[NSString stringWithFormat:@"immEnd(verts: %d, shader: %s)",
+ this->vertex_idx,
+ active_mtl_shader->get_interface()
+ ->get_name()]];
+ }
+
+ /* Populate pipeline state vertex descriptor. */
+ MTLStateManager *state_manager = static_cast<MTLStateManager *>(
+ MTLContext::get()->state_manager);
+ MTLRenderPipelineStateDescriptor &desc = state_manager->get_pipeline_descriptor();
+ const MTLShaderInterface *interface = active_mtl_shader->get_interface();
+
+ /* Reset vertex descriptor to default state. */
+ desc.reset_vertex_descriptor();
+
+ desc.vertex_descriptor.num_attributes = interface->get_total_attributes();
+ desc.vertex_descriptor.num_vert_buffers = 1;
+
+ for (int i = 0; i < desc.vertex_descriptor.num_attributes; i++) {
+ desc.vertex_descriptor.attributes[i].format = MTLVertexFormatInvalid;
+ }
+ desc.vertex_descriptor.uses_ssbo_vertex_fetch =
+ active_mtl_shader->get_uses_ssbo_vertex_fetch();
+ desc.vertex_descriptor.num_ssbo_attributes = 0;
+
+ /* SSBO Vertex Fetch -- Verify Attributes. */
+ if (active_mtl_shader->get_uses_ssbo_vertex_fetch()) {
+ active_mtl_shader->ssbo_vertex_fetch_bind_attributes_begin();
+
+ /* Disable Indexed rendering in SSBO vertex fetch. */
+ int uniform_ssbo_use_indexed = active_mtl_shader->uni_ssbo_uses_indexed_rendering;
+ BLI_assert_msg(uniform_ssbo_use_indexed != -1,
+ "Expected valid uniform location for ssbo_uses_indexed_rendering.");
+ int uses_indexed_rendering = 0;
+ active_mtl_shader->uniform_int(uniform_ssbo_use_indexed, 1, 1, &uses_indexed_rendering);
+ }
+
+ /* Populate Vertex descriptor and verify attributes.
+ * TODO(Metal): Cache this vertex state based on Vertex format and shaders. */
+ for (int i = 0; i < interface->get_total_attributes(); i++) {
+
+ /* NOTE: Attribute in VERTEX FORMAT does not necessarily share the same array index as
+ * attributes in shader interface. */
+ GPUVertAttr *attr = nullptr;
+ const MTLShaderInputAttribute &mtl_shader_attribute = interface->get_attribute(i);
+
+ /* Scan through vertex_format attributes until one with a name matching the shader interface
+ * is found. */
+ for (uint32_t a_idx = 0; a_idx < this->vertex_format.attr_len && attr == nullptr; a_idx++) {
+ GPUVertAttr *check_attribute = &this->vertex_format.attrs[a_idx];
+
+ /* Attributes can have multiple name aliases associated with them. */
+ for (uint32_t n_idx = 0; n_idx < check_attribute->name_len; n_idx++) {
+ const char *name = GPU_vertformat_attr_name_get(
+ &this->vertex_format, check_attribute, n_idx);
+
+ if (strcmp(name, interface->get_name_at_offset(mtl_shader_attribute.name_offset)) == 0) {
+ attr = check_attribute;
+ break;
+ }
+ }
+ }
+
+ BLI_assert_msg(attr != nullptr,
+ "Could not find expected attribute in immediate mode vertex format.");
+ if (attr == nullptr) {
+ MTL_LOG_ERROR(
+ "MTLImmediate::end Could not find matching attribute '%s' from Shader Interface in "
+ "Vertex Format! - TODO: Bind Dummy attribute\n",
+ interface->get_name_at_offset(mtl_shader_attribute.name_offset));
+ return;
+ }
+
+ /* Determine whether implicit type conversion between input vertex format
+ * and shader interface vertex format is supported. */
+ MTLVertexFormat convertedFormat;
+ bool can_use_implicit_conversion = mtl_convert_vertex_format(
+ mtl_shader_attribute.format,
+ (GPUVertCompType)attr->comp_type,
+ attr->comp_len,
+ (GPUVertFetchMode)attr->fetch_mode,
+ &convertedFormat);
+
+ if (can_use_implicit_conversion) {
+ /* Metal API can implicitly convert some formats during vertex assembly:
+ * - Converting from a normalized short2 format to float2
+ * - Type truncation e.g. Float4 to Float2.
+ * - Type expansion from Float3 to Float4.
+ * - Note: extra components are filled with the corresponding components of (0,0,0,1).
+ * (See
+ * https://developer.apple.com/documentation/metal/mtlvertexattributedescriptor/1516081-format)
+ */
+ bool is_floating_point_format = (attr->comp_type == GPU_COMP_F32);
+ desc.vertex_descriptor.attributes[i].format = convertedFormat;
+ desc.vertex_descriptor.attributes[i].format_conversion_mode =
+ (is_floating_point_format) ? (GPUVertFetchMode)GPU_FETCH_FLOAT :
+ (GPUVertFetchMode)GPU_FETCH_INT;
+ BLI_assert(convertedFormat != MTLVertexFormatInvalid);
+ }
+ else {
+ /* Some conversions are NOT valid, e.g. Int4 to Float4
+ * - In this case, we need to implement a conversion routine inside the shader.
+ * - This is handled using the format_conversion_mode flag
+ * - This flag is passed into the PSO as a function specialization,
+ * and will generate an appropriate conversion function when reading the vertex attribute
+ * value into local shader storage.
+ * (If no explicit conversion is needed, the function specialize to a pass-through). */
+ MTLVertexFormat converted_format;
+ bool can_convert = mtl_vertex_format_resize(
+ mtl_shader_attribute.format, attr->comp_len, &converted_format);
+ desc.vertex_descriptor.attributes[i].format = (can_convert) ? converted_format :
+ mtl_shader_attribute.format;
+ desc.vertex_descriptor.attributes[i].format_conversion_mode = (GPUVertFetchMode)
+ attr->fetch_mode;
+ BLI_assert(desc.vertex_descriptor.attributes[i].format != MTLVertexFormatInvalid);
+ }
+ /* Using attribute offset in vertex format, as this will be correct */
+ desc.vertex_descriptor.attributes[i].offset = attr->offset;
+ desc.vertex_descriptor.attributes[i].buffer_index = mtl_shader_attribute.buffer_index;
+
+ /* SSBO Vertex Fetch Attribute bind. */
+ if (active_mtl_shader->get_uses_ssbo_vertex_fetch()) {
+ BLI_assert_msg(mtl_shader_attribute.buffer_index == 0,
+ "All attributes should be in buffer index zero");
+ MTLSSBOAttribute ssbo_attr(
+ mtl_shader_attribute.index,
+ mtl_shader_attribute.buffer_index,
+ attr->offset,
+ this->vertex_format.stride,
+ MTLShader::ssbo_vertex_type_to_attr_type(desc.vertex_descriptor.attributes[i].format),
+ false);
+ desc.vertex_descriptor.ssbo_attributes[desc.vertex_descriptor.num_ssbo_attributes] =
+ ssbo_attr;
+ desc.vertex_descriptor.num_ssbo_attributes++;
+ active_mtl_shader->ssbo_vertex_fetch_bind_attribute(ssbo_attr);
+ }
+ }
+
+ /* Buffer bindings for singular vertex buffer. */
+ desc.vertex_descriptor.buffer_layouts[0].step_function = MTLVertexStepFunctionPerVertex;
+ desc.vertex_descriptor.buffer_layouts[0].step_rate = 1;
+ desc.vertex_descriptor.buffer_layouts[0].stride = this->vertex_format.stride;
+ BLI_assert(this->vertex_format.stride > 0);
+
+ /* SSBO Vertex Fetch -- Verify Attributes. */
+ if (active_mtl_shader->get_uses_ssbo_vertex_fetch()) {
+ active_mtl_shader->ssbo_vertex_fetch_bind_attributes_end(rec);
+
+ /* Set Status uniforms. */
+ BLI_assert_msg(active_mtl_shader->uni_ssbo_input_prim_type_loc != -1,
+ "ssbo_input_prim_type uniform location invalid!");
+ BLI_assert_msg(active_mtl_shader->uni_ssbo_input_vert_count_loc != -1,
+ "ssbo_input_vert_count uniform location invalid!");
+ GPU_shader_uniform_vector_int(reinterpret_cast<GPUShader *>(wrap(active_mtl_shader)),
+ active_mtl_shader->uni_ssbo_input_prim_type_loc,
+ 1,
+ 1,
+ (const int *)(&this->prim_type));
+ GPU_shader_uniform_vector_int(reinterpret_cast<GPUShader *>(wrap(active_mtl_shader)),
+ active_mtl_shader->uni_ssbo_input_vert_count_loc,
+ 1,
+ 1,
+ (const int *)(&this->vertex_idx));
+ }
+
+ MTLPrimitiveType mtl_prim_type = gpu_prim_type_to_metal(this->prim_type);
+ if (context_->ensure_render_pipeline_state(mtl_prim_type)) {
+
+ /* Issue draw call. */
+ BLI_assert(this->vertex_idx > 0);
+
+ /* Metal API does not support triangle fan, so we can emulate this
+ * input data by generating an index buffer to re-map indices to
+ * a TriangleList.
+ *
+ * NOTE(Metal): Consider caching generated triangle fan index buffers.
+ * For immediate mode, generating these is currently very cheap, as we use
+ * fast scratch buffer allocations. Though we may benefit from caching of
+ * frequently used buffer sizes. */
+ if (mtl_needs_topology_emulation(this->prim_type)) {
+
+ /* Debug safety check for SSBO FETCH MODE. */
+ if (active_mtl_shader->get_uses_ssbo_vertex_fetch()) {
+ BLI_assert(false && "Topology emulation not supported with SSBO Vertex Fetch mode");
+ }
+
+ /* Emulate Tri-fan. */
+ if (this->prim_type == GPU_PRIM_TRI_FAN) {
+ /* Prepare Triangle-Fan emulation index buffer on CPU based on number of input
+ * vertices. */
+ uint32_t base_vert_count = this->vertex_idx;
+ uint32_t num_triangles = max_ii(base_vert_count - 2, 0);
+ uint32_t fan_index_count = num_triangles * 3;
+ BLI_assert(num_triangles > 0);
+
+ uint32_t alloc_size = sizeof(uint32_t) * fan_index_count;
+ uint32_t *index_buffer = nullptr;
+
+ MTLTemporaryBuffer allocation =
+ context_->get_scratchbuffer_manager().scratch_buffer_allocate_range_aligned(
+ alloc_size, 128);
+ index_buffer = (uint32_t *)allocation.data;
+
+ int a = 0;
+ for (int i = 0; i < num_triangles; i++) {
+ index_buffer[a++] = 0;
+ index_buffer[a++] = i + 1;
+ index_buffer[a++] = i + 2;
+ }
+
+ @autoreleasepool {
+
+ id<MTLBuffer> index_buffer_mtl = nil;
+ uint32_t index_buffer_offset = 0;
+
+ /* Region of scratch buffer used for topology emulation element data.
+ * NOTE(Metal): We do not need to manually flush as the entire scratch
+ * buffer for current command buffer is flushed upon submission. */
+ index_buffer_mtl = allocation.metal_buffer;
+ index_buffer_offset = allocation.buffer_offset;
+
+ /* Set depth stencil state (requires knowledge of primitive type). */
+ context_->ensure_depth_stencil_state(MTLPrimitiveTypeTriangle);
+
+ /* Bind Vertex Buffer. */
+ rps.bind_vertex_buffer(
+ current_allocation_.metal_buffer, current_allocation_.buffer_offset, 0);
+
+ /* Draw. */
+ [rec drawIndexedPrimitives:MTLPrimitiveTypeTriangle
+ indexCount:fan_index_count
+ indexType:MTLIndexTypeUInt32
+ indexBuffer:index_buffer_mtl
+ indexBufferOffset:index_buffer_offset];
+ }
+ }
+ else {
+ /* TODO(Metal): Topology emulation for line loop.
+ * NOTE(Metal): This is currently not used anywhere and modified at the high
+ * level for efficiency in such cases. */
+ BLI_assert_msg(false, "LineLoop requires emulation support in immediate mode.");
+ }
+ }
+ else {
+ MTLPrimitiveType primitive_type = metal_primitive_type_;
+ int vertex_count = this->vertex_idx;
+
+ /* Bind Vertex Buffer. */
+ rps.bind_vertex_buffer(
+ current_allocation_.metal_buffer, current_allocation_.buffer_offset, 0);
+
+ /* Set depth stencil state (requires knowledge of primitive type). */
+ context_->ensure_depth_stencil_state(primitive_type);
+
+ if (active_mtl_shader->get_uses_ssbo_vertex_fetch()) {
+
+ /* Bind Null Buffers for empty/missing bind slots. */
+ id<MTLBuffer> null_buffer = context_->get_null_buffer();
+ BLI_assert(null_buffer != nil);
+ for (int i = 1; i < MTL_SSBO_VERTEX_FETCH_MAX_VBOS; i++) {
+
+ /* We only need to ensure a buffer is bound to the context, its contents do not matter
+ * as it will not be used. */
+ if (rps.cached_vertex_buffer_bindings[i].metal_buffer == nil) {
+ rps.bind_vertex_buffer(null_buffer, 0, i);
+ }
+ }
+
+ /* SSBO vertex fetch - Nullify elements buffer. */
+ if (rps.cached_vertex_buffer_bindings[MTL_SSBO_VERTEX_FETCH_IBO_INDEX].metal_buffer ==
+ nil) {
+ rps.bind_vertex_buffer(null_buffer, 0, MTL_SSBO_VERTEX_FETCH_IBO_INDEX);
+ }
+
+ /* Submit draw call with modified vertex count, which reflects vertices per primitive
+ * defined in the USE_SSBO_VERTEX_FETCH `pragma`. */
+ int num_input_primitives = gpu_get_prim_count_from_type(vertex_count, this->prim_type);
+ int output_num_verts = num_input_primitives *
+ active_mtl_shader->get_ssbo_vertex_fetch_output_num_verts();
+#ifndef NDEBUG
+ BLI_assert(
+ mtl_vertex_count_fits_primitive_type(
+ output_num_verts, active_mtl_shader->get_ssbo_vertex_fetch_output_prim_type()) &&
+ "Output Vertex count is not compatible with the requested output vertex primitive "
+ "type");
+#endif
+ [rec drawPrimitives:active_mtl_shader->get_ssbo_vertex_fetch_output_prim_type()
+ vertexStart:0
+ vertexCount:output_num_verts];
+ context_->main_command_buffer.register_draw_counters(output_num_verts);
+ }
+ else {
+ /* Regular draw. */
+ [rec drawPrimitives:primitive_type vertexStart:0 vertexCount:vertex_count];
+ context_->main_command_buffer.register_draw_counters(vertex_count);
+ }
+ }
+ }
+ if (G.debug & G_DEBUG_GPU) {
+ [rec popDebugGroup];
+ }
+ }
+
+ /* Reset allocation after draw submission. */
+ has_begun_ = false;
+ if (current_allocation_.metal_buffer) {
+ [current_allocation_.metal_buffer release];
+ current_allocation_.metal_buffer = nil;
+ }
+}
+
+} // blender::gpu
diff --git a/source/blender/gpu/metal/mtl_index_buffer.mm b/source/blender/gpu/metal/mtl_index_buffer.mm
index 2195ab7538d..9712dce7b40 100644
--- a/source/blender/gpu/metal/mtl_index_buffer.mm
+++ b/source/blender/gpu/metal/mtl_index_buffer.mm
@@ -138,7 +138,7 @@ void MTLIndexBuf::update_sub(uint32_t start, uint32_t len, const void *data)
BLI_assert(ibo_ != nullptr);
/* Otherwise, we will inject a data update, using staged data, into the command stream.
- * Stage update contents in temporary buffer*/
+ * Stage update contents in temporary buffer. */
MTLContext *ctx = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
BLI_assert(ctx);
MTLTemporaryBuffer range = ctx->get_scratchbuffer_manager().scratch_buffer_allocate_range(len);
diff --git a/source/blender/gpu/metal/mtl_memory.hh b/source/blender/gpu/metal/mtl_memory.hh
index df80df6543f..bd354376b12 100644
--- a/source/blender/gpu/metal/mtl_memory.hh
+++ b/source/blender/gpu/metal/mtl_memory.hh
@@ -340,13 +340,13 @@ class MTLBufferPool {
private:
/* Memory statistics. */
- long long int total_allocation_bytes_ = 0;
+ int64_t total_allocation_bytes_ = 0;
#if MTL_DEBUG_MEMORY_STATISTICS == 1
/* Debug statistics. */
std::atomic<int> per_frame_allocation_count_;
- std::atomic<long long int> allocations_in_pool_;
- std::atomic<long long int> buffers_in_pool_;
+ std::atomic<int64_t> allocations_in_pool_;
+ std::atomic<int64_t> buffers_in_pool_;
#endif
/* Metal resources. */
diff --git a/source/blender/gpu/metal/mtl_pso_descriptor_state.hh b/source/blender/gpu/metal/mtl_pso_descriptor_state.hh
index 1906350679a..04ceb5bdf03 100644
--- a/source/blender/gpu/metal/mtl_pso_descriptor_state.hh
+++ b/source/blender/gpu/metal/mtl_pso_descriptor_state.hh
@@ -28,8 +28,8 @@ struct MTLVertexAttributeDescriptorPSO {
uint64_t hash() const
{
- return (uint64_t)((uint64_t)this->format ^ (this->offset << 4) ^ (this->buffer_index << 8) ^
- (this->format_conversion_mode << 12));
+ return uint64_t((uint64_t(this->format) ^ (this->offset << 4) ^ (this->buffer_index << 8) ^
+ (this->format_conversion_mode << 12)));
}
};
@@ -46,8 +46,7 @@ struct MTLVertexBufferLayoutDescriptorPSO {
uint64_t hash() const
{
- return (uint64_t)((uint64_t)this->step_function ^ (this->step_rate << 4) ^
- (this->stride << 8));
+ return uint64_t(uint64_t(this->step_function) ^ (this->step_rate << 4) ^ (this->stride << 8));
}
};
@@ -217,34 +216,46 @@ struct MTLRenderPipelineStateDescriptor {
* has collisions. */
uint64_t hash = this->vertex_descriptor.hash();
- hash ^= (uint64_t)this->num_color_attachments << 16; /* up to 6 (3 bits). */
- hash ^= (uint64_t)this->depth_attachment_format << 18; /* up to 555 (9 bits). */
- hash ^= (uint64_t)this->stencil_attachment_format << 20; /* up to 555 (9 bits). */
- hash ^= (uint64_t)(*(
- (uint64_t *)&this->vertex_descriptor.prim_topology_class)); /* Up to 3 (2 bits). */
+ hash ^= uint64_t(this->num_color_attachments) << 16; /* up to 6 (3 bits). */
+ hash ^= uint64_t(this->depth_attachment_format) << 18; /* up to 555 (9 bits). */
+ hash ^= uint64_t(this->stencil_attachment_format) << 20; /* up to 555 (9 bits). */
+ hash ^= uint64_t(
+ *((uint64_t *)&this->vertex_descriptor.prim_topology_class)); /* Up to 3 (2 bits). */
/* Only include elements in Hash if they are needed - avoids variable null assignments
* influencing hash. */
if (this->num_color_attachments > 0) {
- hash ^= (uint64_t)this->color_write_mask << 22; /* 4 bit bit-mask. */
- hash ^= (uint64_t)this->alpha_blend_op << 26; /* Up to 4 (3 bits). */
- hash ^= (uint64_t)this->rgb_blend_op << 29; /* Up to 4 (3 bits). */
- hash ^= (uint64_t)this->dest_alpha_blend_factor << 32; /* Up to 18 (5 bits). */
- hash ^= (uint64_t)this->dest_rgb_blend_factor << 37; /* Up to 18 (5 bits). */
- hash ^= (uint64_t)this->src_alpha_blend_factor << 42; /* Up to 18 (5 bits). */
- hash ^= (uint64_t)this->src_rgb_blend_factor << 47; /* Up to 18 (5 bits). */
+ hash ^= uint64_t(this->color_write_mask) << 22; /* 4 bit bit-mask. */
+ hash ^= uint64_t(this->alpha_blend_op) << 26; /* Up to 4 (3 bits). */
+ hash ^= uint64_t(this->rgb_blend_op) << 29; /* Up to 4 (3 bits). */
+ hash ^= uint64_t(this->dest_alpha_blend_factor) << 32; /* Up to 18 (5 bits). */
+ hash ^= uint64_t(this->dest_rgb_blend_factor) << 37; /* Up to 18 (5 bits). */
+ hash ^= uint64_t(this->src_alpha_blend_factor) << 42; /* Up to 18 (5 bits). */
+ hash ^= uint64_t(this->src_rgb_blend_factor) << 47; /* Up to 18 (5 bits). */
}
for (const uint c : IndexRange(GPU_FB_MAX_COLOR_ATTACHMENT)) {
- hash ^= (uint64_t)this->color_attachment_format[c] << (c + 52); // up to 555 (9 bits)
+ hash ^= uint64_t(this->color_attachment_format[c]) << (c + 52); /* Up to 555 (9 bits). */
}
- hash |= (uint64_t)((this->blending_enabled && (this->num_color_attachments > 0)) ? 1 : 0)
- << 62;
- hash ^= (uint64_t)this->point_size;
+ hash |= uint64_t((this->blending_enabled && (this->num_color_attachments > 0)) ? 1 : 0) << 62;
+ hash ^= uint64_t(this->point_size);
return hash;
}
+
+ /* Reset the Vertex Descriptor to default. */
+ void reset_vertex_descriptor()
+ {
+ vertex_descriptor.num_attributes = 0;
+ vertex_descriptor.num_vert_buffers = 0;
+ for (int i = 0; i < GPU_VERT_ATTR_MAX_LEN; i++) {
+ vertex_descriptor.attributes[i].format = MTLVertexFormatInvalid;
+ vertex_descriptor.attributes[i].offset = 0;
+ }
+ vertex_descriptor.uses_ssbo_vertex_fetch = false;
+ vertex_descriptor.num_ssbo_attributes = 0;
+ }
};
} // namespace blender::gpu
diff --git a/source/blender/gpu/metal/mtl_shader.hh b/source/blender/gpu/metal/mtl_shader.hh
index 64d9d1cf849..5485b32dd31 100644
--- a/source/blender/gpu/metal/mtl_shader.hh
+++ b/source/blender/gpu/metal/mtl_shader.hh
@@ -261,8 +261,6 @@ class MTLShader : public Shader {
bool get_push_constant_is_dirty();
void push_constant_bindstate_mark_dirty(bool is_dirty);
- void vertformat_from_shader(GPUVertFormat *format) const override;
-
/* DEPRECATED: Kept only because of BGL API. (Returning -1 in METAL). */
int program_handle_get() const override
{
diff --git a/source/blender/gpu/metal/mtl_shader.mm b/source/blender/gpu/metal/mtl_shader.mm
index 23097f312f0..006d3394378 100644
--- a/source/blender/gpu/metal/mtl_shader.mm
+++ b/source/blender/gpu/metal/mtl_shader.mm
@@ -129,6 +129,7 @@ MTLShader::~MTLShader()
if (shd_builder_ != nullptr) {
delete shd_builder_;
+ shd_builder_ = nullptr;
}
}
@@ -209,6 +210,7 @@ bool MTLShader::finalize(const shader::ShaderCreateInfo *info)
/* Release temporary compilation resources. */
delete shd_builder_;
+ shd_builder_ = nullptr;
return false;
}
}
@@ -279,6 +281,7 @@ bool MTLShader::finalize(const shader::ShaderCreateInfo *info)
/* Release temporary compilation resources. */
delete shd_builder_;
+ shd_builder_ = nullptr;
return false;
}
}
@@ -324,6 +327,7 @@ bool MTLShader::finalize(const shader::ShaderCreateInfo *info)
/* Release temporary compilation resources. */
delete shd_builder_;
+ shd_builder_ = nullptr;
return true;
}
@@ -536,27 +540,6 @@ void MTLShader::push_constant_bindstate_mark_dirty(bool is_dirty)
push_constant_modified_ = is_dirty;
}
-void MTLShader::vertformat_from_shader(GPUVertFormat *format) const
-{
- GPU_vertformat_clear(format);
-
- const MTLShaderInterface *mtl_interface = static_cast<const MTLShaderInterface *>(interface);
- for (const uint attr_id : IndexRange(mtl_interface->get_total_attributes())) {
- const MTLShaderInputAttribute &attr = mtl_interface->get_attribute(attr_id);
-
- /* Extract type parameters from Metal type. */
- GPUVertCompType comp_type = comp_type_from_vert_format(attr.format);
- uint comp_len = comp_count_from_vert_format(attr.format);
- GPUVertFetchMode fetch_mode = fetchmode_from_vert_format(attr.format);
-
- GPU_vertformat_attr_add(format,
- mtl_interface->get_name_at_offset(attr.name_offset),
- comp_type,
- comp_len,
- fetch_mode);
- }
-}
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -1167,6 +1150,7 @@ void MTLShader::ssbo_vertex_fetch_bind_attribute(const MTLSSBOAttribute &ssbo_at
MTLShaderInterface *mtl_interface = this->get_interface();
BLI_assert(ssbo_attr.mtl_attribute_index >= 0 &&
ssbo_attr.mtl_attribute_index < mtl_interface->get_total_attributes());
+ UNUSED_VARS_NDEBUG(mtl_interface);
/* Update bind-mask to verify this attribute has been used. */
BLI_assert((ssbo_vertex_attribute_bind_mask_ & (1 << ssbo_attr.mtl_attribute_index)) ==
diff --git a/source/blender/gpu/metal/mtl_shader_generator.hh b/source/blender/gpu/metal/mtl_shader_generator.hh
index 43890ca0170..63e2e6d5924 100644
--- a/source/blender/gpu/metal/mtl_shader_generator.hh
+++ b/source/blender/gpu/metal/mtl_shader_generator.hh
@@ -497,7 +497,7 @@ inline std::string get_stage_class_name(ShaderStage stage)
inline bool is_builtin_type(std::string type)
{
/* Add Types as needed. */
- /* TODO(Metal): Consider replacing this with a switch and constexpr hash and switch.
+ /* TODO(Metal): Consider replacing this with a switch and `constexpr` hash and switch.
* Though most efficient and maintainable approach to be determined. */
static std::map<std::string, eMTLDataType> glsl_builtin_types = {
{"float", MTL_DATATYPE_FLOAT},
diff --git a/source/blender/gpu/metal/mtl_shader_generator.mm b/source/blender/gpu/metal/mtl_shader_generator.mm
index 977e97dbd82..4a2be0753bb 100644
--- a/source/blender/gpu/metal/mtl_shader_generator.mm
+++ b/source/blender/gpu/metal/mtl_shader_generator.mm
@@ -724,10 +724,6 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info)
}
if (msl_iface.uses_ssbo_vertex_fetch_mode) {
ss_vertex << "#define MTL_SSBO_VERTEX_FETCH 1" << std::endl;
- ss_vertex << "#define MTL_SSBO_VERTEX_FETCH_MAX_VBOS " << MTL_SSBO_VERTEX_FETCH_MAX_VBOS
- << std::endl;
- ss_vertex << "#define MTL_SSBO_VERTEX_FETCH_IBO_INDEX " << MTL_SSBO_VERTEX_FETCH_IBO_INDEX
- << std::endl;
for (const MSLVertexInputAttribute &attr : msl_iface.vertex_input_attributes) {
ss_vertex << "#define SSBO_ATTR_TYPE_" << attr.name << " " << attr.type << std::endl;
}
diff --git a/source/blender/gpu/metal/mtl_shader_interface.mm b/source/blender/gpu/metal/mtl_shader_interface.mm
index 3703d5b5684..97a82345761 100644
--- a/source/blender/gpu/metal/mtl_shader_interface.mm
+++ b/source/blender/gpu/metal/mtl_shader_interface.mm
@@ -117,9 +117,7 @@ uint32_t MTLShaderInterface::add_uniform_block(uint32_t name_offset,
MTLShaderUniformBlock &uni_block = ubos_[total_uniform_blocks_];
uni_block.name_offset = name_offset;
- /* We offset the buffer binding index by one, as the first slot is reserved for push constant
- * data. */
- uni_block.buffer_index = buffer_index + 1;
+ uni_block.buffer_index = buffer_index;
uni_block.size = size;
uni_block.current_offset = 0;
uni_block.stage_mask = ShaderStage::BOTH;
@@ -297,8 +295,10 @@ void MTLShaderInterface::prepare_common_shader_inputs()
current_input->name_hash = BLI_hash_string(this->get_name_at_offset(shd_ubo.name_offset));
/* Location refers to the index in the ubos_ array. */
current_input->location = ubo_index;
- /* Final binding location refers to the buffer binding index within the shader (Relative to
- * MTL_uniform_buffer_base_index). */
+ /* Binding location refers to the UBO bind slot in
+ * #MTLContextGlobalShaderPipelineState::ubo_bindings. The buffer bind index [[buffer(N)]]
+ * within the shader will apply an offset for bound vertex buffers and the default uniform
+ * PushConstantBlock. */
current_input->binding = shd_ubo.buffer_index;
current_input++;
}
diff --git a/source/blender/gpu/metal/mtl_texture.hh b/source/blender/gpu/metal/mtl_texture.hh
index be6f3a3a02b..28b55306707 100644
--- a/source/blender/gpu/metal/mtl_texture.hh
+++ b/source/blender/gpu/metal/mtl_texture.hh
@@ -108,10 +108,10 @@ struct TextureReadRoutineSpecialisation {
uint64_t hash() const
{
blender::DefaultHash<std::string> string_hasher;
- return (uint64_t)string_hasher(this->input_data_type + this->output_data_type +
- std::to_string((this->component_count_input << 8) +
- this->component_count_output +
- (this->depth_format_mode << 28)));
+ return uint64_t(string_hasher(this->input_data_type + this->output_data_type +
+ std::to_string((this->component_count_input << 8) +
+ this->component_count_output +
+ (this->depth_format_mode << 28))));
}
};
@@ -138,12 +138,12 @@ struct MTLSamplerState {
operator uint() const
{
- return (uint)state;
+ return uint(state);
}
operator uint64_t() const
{
- return (uint64_t)state;
+ return uint64_t(state);
}
};
@@ -200,7 +200,7 @@ class MTLTexture : public Texture {
TEXTURE_VIEW_SWIZZLE_DIRTY = (1 << 0),
TEXTURE_VIEW_MIP_DIRTY = (1 << 1)
};
- id<MTLTexture> mip_swizzle_view_;
+ id<MTLTexture> mip_swizzle_view_ = nil;
char tex_swizzle_mask_[4];
MTLTextureSwizzleChannels mtl_swizzle_mask_;
bool mip_range_dirty_ = false;
@@ -216,7 +216,6 @@ class MTLTexture : public Texture {
/* VBO. */
MTLVertBuf *vert_buffer_;
id<MTLBuffer> vert_buffer_mtl_;
- int vert_buffer_offset_;
/* Core parameters and sub-resources. */
eGPUTextureUsage gpu_image_usage_flags_;
@@ -247,7 +246,7 @@ class MTLTexture : public Texture {
void mip_range_set(int min, int max) override;
void *read(int mip, eGPUDataFormat type) override;
- /* Remove once no longer required -- will just return 0 for now in MTL path*/
+ /* Remove once no longer required -- will just return 0 for now in MTL path. */
uint gl_bindcode_get() const override;
bool texture_is_baked();
@@ -256,6 +255,14 @@ class MTLTexture : public Texture {
return name_;
}
+ id<MTLBuffer> get_vertex_buffer() const
+ {
+ if (resource_mode_ == MTL_TEXTURE_MODE_VBO) {
+ return vert_buffer_mtl_;
+ }
+ return nil;
+ }
+
protected:
bool init_internal() override;
bool init_internal(GPUVertBuf *vbo) override;
@@ -324,8 +331,6 @@ class MTLTexture : public Texture {
int height);
GPUFrameBuffer *get_blit_framebuffer(uint dst_slice, uint dst_mip);
- MEM_CXX_CLASS_ALLOC_FUNCS("gpu::MTLTexture")
-
/* Texture Update function Utilities. */
/* Metal texture updating does not provide the same range of functionality for type conversion
* and format compatibility as are available in OpenGL. To achieve the same level of
@@ -357,9 +362,9 @@ class MTLTexture : public Texture {
*/
struct TextureUpdateParams {
int mip_index;
- int extent[3]; /* Width, Height, Slice on 2D Array tex*/
- int offset[3]; /* Width, Height, Slice on 2D Array tex*/
- uint unpack_row_length; /* Number of pixels between bytes in input data */
+ int extent[3]; /* Width, Height, Slice on 2D Array tex. */
+ int offset[3]; /* Width, Height, Slice on 2D Array tex. */
+ uint unpack_row_length; /* Number of pixels between bytes in input data. */
};
id<MTLComputePipelineState> texture_update_1d_get_kernel(
@@ -383,7 +388,7 @@ class MTLTexture : public Texture {
/* Depth texture updates are not directly supported with Blit operations, similarly, we cannot
* use a compute shader to write to depth, so we must instead render to a depth target.
* These processes use vertex/fragment shaders to render texture data from an intermediate
- * source, in order to prime the depth buffer*/
+ * source, in order to prime the depth buffer. */
GPUShader *depth_2d_update_sh_get(DepthTextureUpdateRoutineSpecialisation specialization);
void update_sub_depth_2d(
@@ -392,8 +397,8 @@ class MTLTexture : public Texture {
/* Texture Read function utilities -- Follows a similar mechanism to the updating routines */
struct TextureReadParams {
int mip_index;
- int extent[3]; /* Width, Height, Slice on 2D Array tex*/
- int offset[3]; /* Width, Height, Slice on 2D Array tex*/
+ int extent[3]; /* Width, Height, Slice on 2D Array tex. */
+ int offset[3]; /* Width, Height, Slice on 2D Array tex. */
};
id<MTLComputePipelineState> texture_read_1d_get_kernel(
@@ -415,6 +420,8 @@ class MTLTexture : public Texture {
/* fullscreen blit utilities. */
GPUShader *fullscreen_blit_sh_get();
+
+ MEM_CXX_CLASS_ALLOC_FUNCS("MTLTexture")
};
/* Utility */
diff --git a/source/blender/gpu/metal/mtl_texture.mm b/source/blender/gpu/metal/mtl_texture.mm
index 2b7c2333bff..29dcc8d32ee 100644
--- a/source/blender/gpu/metal/mtl_texture.mm
+++ b/source/blender/gpu/metal/mtl_texture.mm
@@ -12,6 +12,7 @@
#include "GPU_batch_presets.h"
#include "GPU_capabilities.h"
#include "GPU_framebuffer.h"
+#include "GPU_immediate.h"
#include "GPU_platform.h"
#include "GPU_state.h"
@@ -20,6 +21,7 @@
#include "mtl_context.hh"
#include "mtl_debug.hh"
#include "mtl_texture.hh"
+#include "mtl_vertex_buffer.hh"
#include "GHOST_C-api.h"
@@ -50,7 +52,6 @@ void gpu::MTLTexture::mtl_texture_init()
/* VBO. */
vert_buffer_ = nullptr;
vert_buffer_mtl_ = nil;
- vert_buffer_offset_ = -1;
/* Default Swizzle. */
tex_swizzle_mask_[0] = 'r';
@@ -169,26 +170,39 @@ void gpu::MTLTexture::bake_mip_swizzle_view()
id<MTLTexture> gpu::MTLTexture::get_metal_handle()
{
- /* ensure up to date and baked. */
- this->ensure_baked();
-
/* Verify VBO texture shares same buffer. */
if (resource_mode_ == MTL_TEXTURE_MODE_VBO) {
- int r_offset = -1;
+ id<MTLBuffer> buf = vert_buffer_->get_metal_buffer();
+
+ /* Source vertex buffer has been re-generated, require re-initialization. */
+ if (buf != vert_buffer_mtl_) {
+ MTL_LOG_INFO(
+ "MTLTexture '%p' using MTL_TEXTURE_MODE_VBO requires re-generation due to updated "
+ "Vertex-Buffer.\n",
+ this);
+ /* Clear state. */
+ this->reset();
+
+ /* Re-initialize. */
+ this->init_internal(wrap(vert_buffer_));
+
+ /* Update for assertion check below. */
+ buf = vert_buffer_->get_metal_buffer();
+ }
- /* TODO(Metal): Fetch buffer from MTLVertBuf when implemented. */
- id<MTLBuffer> buf = nil; /*vert_buffer_->get_metal_buffer(&r_offset);*/
+ /* Ensure buffer is valid.
+ * Fetch-vert buffer handle directly in-case it changed above. */
BLI_assert(vert_buffer_mtl_ != nil);
- BLI_assert(buf == vert_buffer_mtl_ && r_offset == vert_buffer_offset_);
-
- UNUSED_VARS(buf);
- UNUSED_VARS_NDEBUG(r_offset);
+ BLI_assert(vert_buffer_->get_metal_buffer() == vert_buffer_mtl_);
}
+ /* ensure up to date and baked. */
+ this->ensure_baked();
+
if (is_baked_) {
/* For explicit texture views, ensure we always return the texture view. */
if (resource_mode_ == MTL_TEXTURE_MODE_TEXTURE_VIEW) {
- BLI_assert(mip_swizzle_view_ && "Texture view should always have a valid handle.");
+ BLI_assert_msg(mip_swizzle_view_, "Texture view should always have a valid handle.");
}
if (mip_swizzle_view_ != nil || texture_view_dirty_flags_) {
@@ -208,7 +222,7 @@ id<MTLTexture> gpu::MTLTexture::get_metal_handle_base()
/* For explicit texture views, always return the texture view. */
if (resource_mode_ == MTL_TEXTURE_MODE_TEXTURE_VIEW) {
- BLI_assert(mip_swizzle_view_ && "Texture view should always have a valid handle.");
+ BLI_assert_msg(mip_swizzle_view_, "Texture view should always have a valid handle.");
if (mip_swizzle_view_ != nil || texture_view_dirty_flags_) {
bake_mip_swizzle_view();
}
@@ -290,7 +304,6 @@ void gpu::MTLTexture::blit(gpu::MTLTexture *dst,
/* Execute graphics draw call to perform the blit. */
GPUBatch *quad = GPU_batch_preset_quad();
-
GPU_batch_set_shader(quad, shader);
float w = dst->width_get();
@@ -915,7 +928,7 @@ void gpu::MTLTexture::generate_mipmap()
/* Ensure texture is baked. */
this->ensure_baked();
- BLI_assert(is_baked_ && texture_ && "MTLTexture is not valid");
+ BLI_assert_msg(is_baked_ && texture_, "MTLTexture is not valid");
if (mipmaps_ == 1 || mtl_max_mips_ == 1) {
MTL_LOG_WARNING("Call to generate mipmaps on texture with 'mipmaps_=1\n'");
@@ -1231,7 +1244,7 @@ void gpu::MTLTexture::read_internal(int mip,
depth_format_mode = 4;
break;
default:
- BLI_assert(false && "Unhandled depth read format case");
+ BLI_assert_msg(false, "Unhandled depth read format case");
break;
}
}
@@ -1445,11 +1458,84 @@ bool gpu::MTLTexture::init_internal()
bool gpu::MTLTexture::init_internal(GPUVertBuf *vbo)
{
- /* Zero initialize. */
- this->prepare_internal();
+ if (this->format_ == GPU_DEPTH24_STENCIL8) {
+ /* Apple Silicon requires GPU_DEPTH32F_STENCIL8 instead of GPU_DEPTH24_STENCIL8. */
+ this->format_ = GPU_DEPTH32F_STENCIL8;
+ }
+
+ MTLPixelFormat mtl_format = gpu_texture_format_to_metal(this->format_);
+ mtl_max_mips_ = 1;
+ mipmaps_ = 0;
+ this->mip_range_set(0, 0);
+
+ /* Create texture from GPUVertBuf's buffer. */
+ MTLVertBuf *mtl_vbo = static_cast<MTLVertBuf *>(unwrap(vbo));
+ mtl_vbo->bind();
+ mtl_vbo->flag_used();
+
+ /* Get Metal Buffer. */
+ id<MTLBuffer> source_buffer = mtl_vbo->get_metal_buffer();
+ BLI_assert(source_buffer);
+
+ /* Verify size. */
+ if (w_ <= 0) {
+ MTL_LOG_WARNING("Allocating texture buffer of width 0!\n");
+ w_ = 1;
+ }
+
+ /* Verify Texture and vertex buffer alignment. */
+ int bytes_per_pixel = get_mtl_format_bytesize(mtl_format);
+ int bytes_per_row = bytes_per_pixel * w_;
+
+ MTLContext *mtl_ctx = MTLContext::get();
+ uint32_t align_requirement = static_cast<uint32_t>(
+ [mtl_ctx->device minimumLinearTextureAlignmentForPixelFormat:mtl_format]);
+
+ /* Verify per-vertex size aligns with texture size. */
+ const GPUVertFormat *format = GPU_vertbuf_get_format(vbo);
+ BLI_assert(bytes_per_pixel == format->stride &&
+ "Pixel format stride MUST match the texture format stride -- These being different "
+ "is likely caused by Metal's VBO padding to a minimum of 4-bytes per-vertex");
+ UNUSED_VARS_NDEBUG(format);
+
+ /* Create texture descriptor. */
+ BLI_assert(type_ == GPU_TEXTURE_BUFFER);
+ texture_descriptor_ = [[MTLTextureDescriptor alloc] init];
+ texture_descriptor_.pixelFormat = mtl_format;
+ texture_descriptor_.textureType = MTLTextureTypeTextureBuffer;
+ texture_descriptor_.width = w_;
+ texture_descriptor_.height = 1;
+ texture_descriptor_.depth = 1;
+ texture_descriptor_.arrayLength = 1;
+ texture_descriptor_.mipmapLevelCount = mtl_max_mips_;
+ texture_descriptor_.usage =
+ MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite |
+ MTLTextureUsagePixelFormatView; /* TODO(Metal): Optimize usage flags. */
+ texture_descriptor_.storageMode = [source_buffer storageMode];
+ texture_descriptor_.sampleCount = 1;
+ texture_descriptor_.cpuCacheMode = [source_buffer cpuCacheMode];
+ texture_descriptor_.hazardTrackingMode = [source_buffer hazardTrackingMode];
+
+ texture_ = [source_buffer
+ newTextureWithDescriptor:texture_descriptor_
+ offset:0
+ bytesPerRow:ceil_to_multiple_u(bytes_per_row, align_requirement)];
+ aligned_w_ = bytes_per_row / bytes_per_pixel;
+
+ BLI_assert(texture_);
+ texture_.label = [NSString stringWithUTF8String:this->get_name()];
+ is_baked_ = true;
+ is_dirty_ = false;
+ resource_mode_ = MTL_TEXTURE_MODE_VBO;
- /* TODO(Metal): Add implementation for GPU Vert buf. */
- return false;
+ /* Track Status. */
+ vert_buffer_ = mtl_vbo;
+ vert_buffer_mtl_ = source_buffer;
+ /* Cleanup. */
+ [texture_descriptor_ release];
+ texture_descriptor_ = nullptr;
+
+ return true;
}
bool gpu::MTLTexture::init_internal(const GPUTexture *src, int mip_offset, int layer_offset)
@@ -1494,7 +1580,6 @@ bool gpu::MTLTexture::texture_is_baked()
/* Prepare texture parameters after initialization, but before baking. */
void gpu::MTLTexture::prepare_internal()
{
-
/* Derive implicit usage flags for Depth/Stencil attachments. */
if (format_flag_ & GPU_FORMAT_DEPTH || format_flag_ & GPU_FORMAT_STENCIL) {
gpu_image_usage_flags_ |= GPU_TEXTURE_USAGE_ATTACHMENT;
@@ -1659,7 +1744,7 @@ void gpu::MTLTexture::ensure_baked()
/* Determine Resource Mode. */
resource_mode_ = MTL_TEXTURE_MODE_DEFAULT;
- /* Create texture. */
+ /* Standard texture allocation. */
texture_ = [ctx->device newTextureWithDescriptor:texture_descriptor_];
[texture_descriptor_ release];
diff --git a/source/blender/gpu/metal/mtl_texture_util.mm b/source/blender/gpu/metal/mtl_texture_util.mm
index 928393fb39e..33a62e2e3ef 100644
--- a/source/blender/gpu/metal/mtl_texture_util.mm
+++ b/source/blender/gpu/metal/mtl_texture_util.mm
@@ -22,13 +22,7 @@
/* Utility file for secondary functionality which supports mtl_texture.mm. */
extern char datatoc_compute_texture_update_msl[];
-extern char datatoc_depth_2d_update_vert_glsl[];
-extern char datatoc_depth_2d_update_float_frag_glsl[];
-extern char datatoc_depth_2d_update_int24_frag_glsl[];
-extern char datatoc_depth_2d_update_int32_frag_glsl[];
extern char datatoc_compute_texture_read_msl[];
-extern char datatoc_gpu_shader_fullscreen_blit_vert_glsl[];
-extern char datatoc_gpu_shader_fullscreen_blit_frag_glsl[];
namespace blender::gpu {
@@ -40,7 +34,7 @@ MTLPixelFormat gpu_texture_format_to_metal(eGPUTextureFormat tex_format)
{
switch (tex_format) {
- /* Formats texture & renderbuffer. */
+ /* Formats texture & render-buffer. */
case GPU_RGBA8UI:
return MTLPixelFormatRGBA8Uint;
case GPU_RGBA8I:
@@ -447,42 +441,34 @@ GPUShader *gpu::MTLTexture::depth_2d_update_sh_get(
return *result;
}
- const char *fragment_source = nullptr;
+ const char *depth_2d_info_variant = nullptr;
switch (specialization.data_mode) {
case MTL_DEPTH_UPDATE_MODE_FLOAT:
- fragment_source = datatoc_depth_2d_update_float_frag_glsl;
+ depth_2d_info_variant = "depth_2d_update_float";
break;
case MTL_DEPTH_UPDATE_MODE_INT24:
- fragment_source = datatoc_depth_2d_update_int24_frag_glsl;
+ depth_2d_info_variant = "depth_2d_update_int24";
break;
case MTL_DEPTH_UPDATE_MODE_INT32:
- fragment_source = datatoc_depth_2d_update_int32_frag_glsl;
+ depth_2d_info_variant = "depth_2d_update_int32";
break;
default:
BLI_assert(false && "Invalid format mode\n");
return nullptr;
}
- GPUShader *shader = GPU_shader_create(datatoc_depth_2d_update_vert_glsl,
- fragment_source,
- nullptr,
- nullptr,
- nullptr,
- "depth_2d_update_sh_get");
+ GPUShader *shader = GPU_shader_create_from_info_name(depth_2d_info_variant);
mtl_context->get_texture_utils().depth_2d_update_shaders.add_new(specialization, shader);
return shader;
}
GPUShader *gpu::MTLTexture::fullscreen_blit_sh_get()
{
-
MTLContext *mtl_context = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
BLI_assert(mtl_context != nullptr);
if (mtl_context->get_texture_utils().fullscreen_blit_shader == nullptr) {
- const char *vertex_source = datatoc_gpu_shader_fullscreen_blit_vert_glsl;
- const char *fragment_source = datatoc_gpu_shader_fullscreen_blit_frag_glsl;
- GPUShader *shader = GPU_shader_create(
- vertex_source, fragment_source, nullptr, nullptr, nullptr, "fullscreen_blit");
+ GPUShader *shader = GPU_shader_create_from_info_name("fullscreen_blit");
+
mtl_context->get_texture_utils().fullscreen_blit_shader = shader;
}
return mtl_context->get_texture_utils().fullscreen_blit_shader;
@@ -614,7 +600,7 @@ id<MTLComputePipelineState> gpu::MTLTexture::mtl_texture_read_impl(
stringWithUTF8String:datatoc_compute_texture_read_msl];
/* Defensive Debug Checks. */
- long long int depth_scale_factor = 1;
+ int64_t depth_scale_factor = 1;
if (specialization_params.depth_format_mode > 0) {
BLI_assert(specialization_params.component_count_input == 1);
BLI_assert(specialization_params.component_count_output == 1);
diff --git a/source/blender/gpu/metal/mtl_vertex_buffer.hh b/source/blender/gpu/metal/mtl_vertex_buffer.hh
new file mode 100644
index 00000000000..2cc8b0a9636
--- /dev/null
+++ b/source/blender/gpu/metal/mtl_vertex_buffer.hh
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#pragma once
+
+#include <Cocoa/Cocoa.h>
+#include <Metal/Metal.h>
+#include <QuartzCore/QuartzCore.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "GPU_vertex_buffer.h"
+#include "gpu_vertex_buffer_private.hh"
+#include "mtl_context.hh"
+
+namespace blender::gpu {
+
+class MTLVertBuf : public VertBuf {
+ friend class gpu::MTLTexture; /* For buffer texture. */
+ friend class MTLShader; /* For transform feedback. */
+ friend class MTLBatch;
+ friend class MTLContext; /* For transform feedback. */
+
+ private:
+ /** Metal buffer allocation. **/
+ gpu::MTLBuffer *vbo_ = nullptr;
+ /** Texture used if the buffer is bound as buffer texture. Init on first use. */
+ struct ::GPUTexture *buffer_texture_ = nullptr;
+ /** Defines whether the buffer handle is wrapped by this MTLVertBuf, i.e. we do not own it and
+ * should not free it. */
+ bool is_wrapper_ = false;
+ /** Requested allocation size for Metal buffer.
+ * Differs from raw buffer size as alignment is not included. */
+ uint64_t alloc_size_ = 0;
+ /** Whether existing allocation has been submitted for use by the GPU. */
+ bool contents_in_flight_ = false;
+
+ /* Fetch Metal buffer and offset into allocation if necessary.
+ * Access limited to friend classes. */
+ id<MTLBuffer> get_metal_buffer()
+ {
+ vbo_->debug_ensure_used();
+ return vbo_->get_metal_buffer();
+ }
+
+ public:
+ MTLVertBuf();
+ ~MTLVertBuf();
+
+ void bind();
+ void flag_used();
+
+ void update_sub(uint start, uint len, const void *data) override;
+
+ const void *read() const override;
+ void *unmap(const void *mapped_data) const override;
+
+ void wrap_handle(uint64_t handle) override;
+
+ protected:
+ void acquire_data() override;
+ void resize_data() override;
+ void release_data() override;
+ void upload_data() override;
+ void duplicate_data(VertBuf *dst) override;
+ void bind_as_ssbo(uint binding) override;
+ void bind_as_texture(uint binding) override;
+
+ MEM_CXX_CLASS_ALLOC_FUNCS("MTLVertBuf");
+};
+
+} // namespace blender::gpu
diff --git a/source/blender/gpu/metal/mtl_vertex_buffer.mm b/source/blender/gpu/metal/mtl_vertex_buffer.mm
new file mode 100644
index 00000000000..1c7201ce5f9
--- /dev/null
+++ b/source/blender/gpu/metal/mtl_vertex_buffer.mm
@@ -0,0 +1,368 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup gpu
+ */
+#include "mtl_vertex_buffer.hh"
+#include "mtl_debug.hh"
+
+namespace blender::gpu {
+
+MTLVertBuf::MTLVertBuf() : VertBuf()
+{
+}
+
+MTLVertBuf::~MTLVertBuf()
+{
+ this->release_data();
+}
+
+void MTLVertBuf::acquire_data()
+{
+ /* Discard previous data, if any. */
+ MEM_SAFE_FREE(data);
+ if (usage_ == GPU_USAGE_DEVICE_ONLY) {
+ data = nullptr;
+ }
+ else {
+ data = (uchar *)MEM_mallocN(sizeof(uchar) * this->size_alloc_get(), __func__);
+ }
+}
+
+void MTLVertBuf::resize_data()
+{
+ if (usage_ == GPU_USAGE_DEVICE_ONLY) {
+ data = nullptr;
+ }
+ else {
+ data = (uchar *)MEM_reallocN(data, sizeof(uchar) * this->size_alloc_get());
+ }
+}
+
+void MTLVertBuf::release_data()
+{
+ if (vbo_ != nullptr) {
+ vbo_->free();
+ vbo_ = nullptr;
+ is_wrapper_ = false;
+ }
+
+ GPU_TEXTURE_FREE_SAFE(buffer_texture_);
+
+ MEM_SAFE_FREE(data);
+}
+
+void MTLVertBuf::duplicate_data(VertBuf *dst_)
+{
+ BLI_assert(MTLContext::get() != NULL);
+ MTLVertBuf *src = this;
+ MTLVertBuf *dst = static_cast<MTLVertBuf *>(dst_);
+
+ /* Ensure buffer has been initialized. */
+ src->bind();
+
+ if (src->vbo_) {
+
+ /* Fetch active context. */
+ MTLContext *ctx = MTLContext::get();
+ BLI_assert(ctx);
+
+ /* Ensure destination does not have an active VBO. */
+ BLI_assert(dst->vbo_ == nullptr);
+
+ /* Allocate VBO for destination vertbuf. */
+ uint length = src->vbo_->get_size();
+ dst->vbo_ = MTLContext::get_global_memory_manager().allocate(
+ length, (dst->get_usage_type() != GPU_USAGE_DEVICE_ONLY));
+ dst->alloc_size_ = length;
+
+ /* Fetch Metal buffer handles. */
+ id<MTLBuffer> src_buffer = src->vbo_->get_metal_buffer();
+ id<MTLBuffer> dest_buffer = dst->vbo_->get_metal_buffer();
+
+ /* Use blit encoder to copy data to duplicate buffer allocation. */
+ id<MTLBlitCommandEncoder> enc = ctx->main_command_buffer.ensure_begin_blit_encoder();
+ if (G.debug & G_DEBUG_GPU) {
+ [enc insertDebugSignpost:@"VertexBufferDuplicate"];
+ }
+ [enc copyFromBuffer:src_buffer
+ sourceOffset:0
+ toBuffer:dest_buffer
+ destinationOffset:0
+ size:length];
+
+ /* Flush results back to host buffer, if one exists. */
+ if (dest_buffer.storageMode == MTLStorageModeManaged) {
+ [enc synchronizeResource:dest_buffer];
+ }
+
+ if (G.debug & G_DEBUG_GPU) {
+ [enc insertDebugSignpost:@"VertexBufferDuplicateEnd"];
+ }
+
+ /* Mark as in-use, as contents are updated via GPU command. */
+ src->flag_used();
+ }
+
+ /* Copy raw CPU data. */
+ if (data != nullptr) {
+ dst->data = (uchar *)MEM_dupallocN(src->data);
+ }
+}
+
+void MTLVertBuf::upload_data()
+{
+ this->bind();
+}
+
+void MTLVertBuf::bind()
+{
+ /* Determine allocation size. Set minimum allocation size to be
+ * the maximal of a single attribute to avoid validation and
+ * correctness errors. */
+ uint64_t required_size_raw = sizeof(uchar) * this->size_used_get();
+ uint64_t required_size = max_ulul(required_size_raw, 128);
+
+ if (required_size_raw == 0) {
+ MTL_LOG_WARNING("Warning: Vertex buffer required_size = 0\n");
+ }
+
+ /* If the vertex buffer has already been allocated, but new data is ready,
+ * or the usage size has changed, we release the existing buffer and
+ * allocate a new buffer to ensure we do not overwrite in-use GPU resources.
+ *
+ * NOTE: We only need to free the existing allocation if contents have been
+ * submitted to the GPU. Otherwise we can simply upload new data to the
+ * existing buffer, if it will fit.
+ *
+ * NOTE: If a buffer is re-sized, but no new data is provided, the previous
+ * contents are copied into the newly allocated buffer. */
+ bool requires_reallocation = (vbo_ != nullptr) && (alloc_size_ != required_size);
+ bool new_data_ready = (this->flag & GPU_VERTBUF_DATA_DIRTY) && this->data;
+
+ gpu::MTLBuffer *prev_vbo = nullptr;
+ GPUVertBufStatus prev_flag = this->flag;
+
+ if (vbo_ != nullptr) {
+ if (requires_reallocation || (new_data_ready && contents_in_flight_)) {
+ /* Track previous VBO to copy data from. */
+ prev_vbo = vbo_;
+
+ /* Reset current allocation status. */
+ vbo_ = nullptr;
+ is_wrapper_ = false;
+ alloc_size_ = 0;
+
+ /* Flag as requiring data upload. */
+ if (requires_reallocation) {
+ this->flag &= ~GPU_VERTBUF_DATA_UPLOADED;
+ }
+ }
+ }
+
+ /* Create MTLBuffer of requested size. */
+ if (vbo_ == nullptr) {
+ vbo_ = MTLContext::get_global_memory_manager().allocate(
+ required_size, (this->get_usage_type() != GPU_USAGE_DEVICE_ONLY));
+ vbo_->set_label(@"Vertex Buffer");
+ BLI_assert(vbo_ != nullptr);
+ BLI_assert(vbo_->get_metal_buffer() != nil);
+
+ is_wrapper_ = false;
+ alloc_size_ = required_size;
+ contents_in_flight_ = false;
+ }
+
+ /* Upload new data, if provided. */
+ if (new_data_ready) {
+
+ /* Only upload data if usage size is greater than zero.
+ * Do not upload data for device-only buffers. */
+ if (required_size_raw > 0 && usage_ != GPU_USAGE_DEVICE_ONLY) {
+
+ /* Debug: Verify allocation is large enough. */
+ BLI_assert(vbo_->get_size() >= required_size_raw);
+
+ /* Fetch mapped buffer host ptr and upload data. */
+ void *dst_data = vbo_->get_host_ptr();
+ memcpy((uint8_t *)dst_data, this->data, required_size_raw);
+ vbo_->flush_range(0, required_size_raw);
+ }
+
+ /* If static usage, free host-side data. */
+ if (usage_ == GPU_USAGE_STATIC) {
+ MEM_SAFE_FREE(data);
+ }
+
+ /* Flag data as having been uploaded. */
+ this->flag &= ~GPU_VERTBUF_DATA_DIRTY;
+ this->flag |= GPU_VERTBUF_DATA_UPLOADED;
+ }
+ else if (requires_reallocation) {
+
+ /* If buffer has been re-sized, copy existing data if host
+ * data had been previously uploaded. */
+ BLI_assert(prev_vbo != nullptr);
+
+ if (prev_flag & GPU_VERTBUF_DATA_UPLOADED) {
+
+ /* Fetch active context. */
+ MTLContext *ctx = MTLContext::get();
+ BLI_assert(ctx);
+
+ id<MTLBuffer> copy_prev_buffer = prev_vbo->get_metal_buffer();
+ id<MTLBuffer> copy_new_buffer = vbo_->get_metal_buffer();
+ BLI_assert(copy_prev_buffer != nil);
+ BLI_assert(copy_new_buffer != nil);
+
+ /* Ensure a blit command encoder is active for buffer copy operation. */
+ id<MTLBlitCommandEncoder> enc = ctx->main_command_buffer.ensure_begin_blit_encoder();
+ [enc copyFromBuffer:copy_prev_buffer
+ sourceOffset:0
+ toBuffer:copy_new_buffer
+ destinationOffset:0
+ size:min_ii([copy_new_buffer length], [copy_prev_buffer length])];
+
+ /* Flush newly copied data back to host-side buffer, if one exists.
+ * Ensures data and cache coherency for managed MTLBuffers. */
+ if (copy_new_buffer.storageMode == MTLStorageModeManaged) {
+ [enc synchronizeResource:copy_new_buffer];
+ }
+
+ /* For VBOs flagged as static, release host data as it will no longer be needed. */
+ if (usage_ == GPU_USAGE_STATIC) {
+ MEM_SAFE_FREE(data);
+ }
+
+ /* Flag data as uploaded. */
+ this->flag |= GPU_VERTBUF_DATA_UPLOADED;
+
+ /* Flag as in-use, as contents have been updated via GPU commands. */
+ this->flag_used();
+ }
+ }
+
+ /* Release previous buffer if re-allocated. */
+ if (prev_vbo != nullptr) {
+ prev_vbo->free();
+ }
+
+ /* Ensure buffer has been created. */
+ BLI_assert(vbo_ != nullptr);
+}
+
+/* Update Sub currently only used by hair */
+void MTLVertBuf::update_sub(uint start, uint len, const void *data)
+{
+ /* Fetch and verify active context. */
+ MTLContext *ctx = reinterpret_cast<MTLContext *>(unwrap(GPU_context_active_get()));
+ BLI_assert(ctx);
+ BLI_assert(ctx->device);
+
+ /* Ensure vertbuf has been created. */
+ this->bind();
+ BLI_assert(start + len <= alloc_size_);
+
+ /* Create temporary scratch buffer allocation for sub-range of data. */
+ MTLTemporaryBuffer scratch_allocation =
+ ctx->get_scratchbuffer_manager().scratch_buffer_allocate_range_aligned(len, 256);
+ memcpy(scratch_allocation.data, data, len);
+ [scratch_allocation.metal_buffer
+ didModifyRange:NSMakeRange(scratch_allocation.buffer_offset, len)];
+ id<MTLBuffer> data_buffer = scratch_allocation.metal_buffer;
+ uint data_buffer_offset = scratch_allocation.buffer_offset;
+
+ BLI_assert(vbo_ != nullptr && data != nullptr);
+ BLI_assert((start + len) <= vbo_->get_size());
+
+ /* Fetch destination buffer. */
+ id<MTLBuffer> dst_buffer = vbo_->get_metal_buffer();
+
+ /* Ensure blit command encoder for copying data. */
+ id<MTLBlitCommandEncoder> enc = ctx->main_command_buffer.ensure_begin_blit_encoder();
+ [enc copyFromBuffer:data_buffer
+ sourceOffset:data_buffer_offset
+ toBuffer:dst_buffer
+ destinationOffset:start
+ size:len];
+
+ /* Flush modified buffer back to host buffer, if one exists. */
+ if (dst_buffer.storageMode == MTLStorageModeManaged) {
+ [enc synchronizeResource:dst_buffer];
+ }
+}
+
+void MTLVertBuf::bind_as_ssbo(uint binding)
+{
+ /* TODO(Metal): Support binding of buffers as SSBOs.
+ * Pending overall compute support for Metal backend. */
+ MTL_LOG_WARNING("MTLVertBuf::bind_as_ssbo not yet implemented!\n");
+ this->flag_used();
+}
+
+void MTLVertBuf::bind_as_texture(uint binding)
+{
+ /* Ensure allocations are ready, and data uploaded. */
+ this->bind();
+ BLI_assert(vbo_ != nullptr);
+
+ /* If vertex buffer updated, release existing texture and re-create. */
+ id<MTLBuffer> buf = this->get_metal_buffer();
+ if (buffer_texture_ != nullptr) {
+ gpu::MTLTexture *mtl_buffer_tex = static_cast<gpu::MTLTexture *>(
+ unwrap(this->buffer_texture_));
+ id<MTLBuffer> tex_buf = mtl_buffer_tex->get_vertex_buffer();
+ if (tex_buf != buf) {
+ GPU_TEXTURE_FREE_SAFE(buffer_texture_);
+ buffer_texture_ = nullptr;
+ }
+ }
+
+ /* Create texture from vertex buffer. */
+ if (buffer_texture_ == nullptr) {
+ buffer_texture_ = GPU_texture_create_from_vertbuf("vertbuf_as_texture", wrap(this));
+ }
+
+ /* Verify successful creation and bind. */
+ BLI_assert(buffer_texture_ != nullptr);
+ GPU_texture_bind(buffer_texture_, binding);
+}
+
+const void *MTLVertBuf::read() const
+{
+ BLI_assert(vbo_ != nullptr);
+ BLI_assert(usage_ != GPU_USAGE_DEVICE_ONLY);
+ void *return_ptr = vbo_->get_host_ptr();
+ BLI_assert(return_ptr != nullptr);
+
+ return return_ptr;
+}
+
+void *MTLVertBuf::unmap(const void *mapped_data) const
+{
+ void *result = MEM_mallocN(alloc_size_, __func__);
+ memcpy(result, mapped_data, alloc_size_);
+ return result;
+}
+
+void MTLVertBuf::wrap_handle(uint64_t handle)
+{
+ BLI_assert(vbo_ == nullptr);
+
+ /* Attempt to cast to Metal buffer handle. */
+ BLI_assert(handle != 0);
+ id<MTLBuffer> buffer = reinterpret_cast<id<MTLBuffer>>((void *)handle);
+
+ is_wrapper_ = true;
+ vbo_ = new gpu::MTLBuffer(buffer);
+
+ /* We assume the data is already on the device, so no need to allocate or send it. */
+ flag = GPU_VERTBUF_DATA_UPLOADED;
+}
+
+void MTLVertBuf::flag_used()
+{
+ contents_in_flight_ = true;
+}
+
+} // namespace blender::gpu
diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc
index 9051003bcd5..ffbba7dcd8c 100644
--- a/source/blender/gpu/opengl/gl_backend.cc
+++ b/source/blender/gpu/opengl/gl_backend.cc
@@ -351,7 +351,7 @@ static void detect_workarounds()
}
/* Somehow fixes armature display issues (see T69743). */
if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_ANY) &&
- (strstr(version, "Build 20.19.15.4285"))) {
+ strstr(version, "Build 20.19.15.4285")) {
GCaps.use_main_context_workaround = true;
}
/* See T70187: merging vertices fail. This has been tested from `18.2.2` till `19.3.0~dev`
@@ -431,6 +431,12 @@ static void detect_workarounds()
/* Minimum Per-Vertex stride is 1 byte for OpenGL. */
GCaps.minimum_per_vertex_stride = 1;
+ /* Force disable per feature. */
+ if (G.debug & G_DEBUG_GPU_FORCE_DISABLE_SSBO) {
+ printf("\n");
+ printf("GL: Force disabling SSBO support from commandline arguments.\n");
+ GCaps.shader_storage_buffer_objects_support = false;
+ }
} // namespace blender::gpu
/** Internal capabilities. */
diff --git a/source/blender/gpu/opengl/gl_backend.hh b/source/blender/gpu/opengl/gl_backend.hh
index 8646d94e2fd..39a4dd80279 100644
--- a/source/blender/gpu/opengl/gl_backend.hh
+++ b/source/blender/gpu/opengl/gl_backend.hh
@@ -61,7 +61,7 @@ class GLBackend : public GPUBackend {
GLTexture::samplers_update();
};
- Context *context_alloc(void *ghost_window) override
+ Context *context_alloc(void *ghost_window, void * /*ghost_context*/) override
{
return new GLContext(ghost_window, shared_orphan_list_);
};
diff --git a/source/blender/gpu/opengl/gl_batch.cc b/source/blender/gpu/opengl/gl_batch.cc
index ff8867fe3e6..28105e326ee 100644
--- a/source/blender/gpu/opengl/gl_batch.cc
+++ b/source/blender/gpu/opengl/gl_batch.cc
@@ -272,8 +272,8 @@ void GLBatch::bind(int i_first)
#if GPU_TRACK_INDEX_RANGE
/* Can be removed if GL 4.3 is required. */
- if (!GLContext::fixed_restart_index_support && (elem != nullptr)) {
- glPrimitiveRestartIndex(this->elem_()->restart_index());
+ if (!GLContext::fixed_restart_index_support) {
+ glPrimitiveRestartIndex((elem != nullptr) ? this->elem_()->restart_index() : 0xFFFFFFFFu);
}
#endif
diff --git a/source/blender/gpu/opengl/gl_context.cc b/source/blender/gpu/opengl/gl_context.cc
index 31bd7e0c4dd..375194c09f3 100644
--- a/source/blender/gpu/opengl/gl_context.cc
+++ b/source/blender/gpu/opengl/gl_context.cc
@@ -191,11 +191,11 @@ void GLSharedOrphanLists::orphans_clear()
lists_mutex.lock();
if (!buffers.is_empty()) {
- glDeleteBuffers((uint)buffers.size(), buffers.data());
+ glDeleteBuffers(uint(buffers.size()), buffers.data());
buffers.clear();
}
if (!textures.is_empty()) {
- glDeleteTextures((uint)textures.size(), textures.data());
+ glDeleteTextures(uint(textures.size()), textures.data());
textures.clear();
}
lists_mutex.unlock();
@@ -208,11 +208,11 @@ void GLContext::orphans_clear()
lists_mutex_.lock();
if (!orphaned_vertarrays_.is_empty()) {
- glDeleteVertexArrays((uint)orphaned_vertarrays_.size(), orphaned_vertarrays_.data());
+ glDeleteVertexArrays(uint(orphaned_vertarrays_.size()), orphaned_vertarrays_.data());
orphaned_vertarrays_.clear();
}
if (!orphaned_framebuffers_.is_empty()) {
- glDeleteFramebuffers((uint)orphaned_framebuffers_.size(), orphaned_framebuffers_.data());
+ glDeleteFramebuffers(uint(orphaned_framebuffers_.size()), orphaned_framebuffers_.data());
orphaned_framebuffers_.clear();
}
lists_mutex_.unlock();
diff --git a/source/blender/gpu/opengl/gl_debug.cc b/source/blender/gpu/opengl/gl_debug.cc
index 4c9f766c93c..5c23286c166 100644
--- a/source/blender/gpu/opengl/gl_debug.cc
+++ b/source/blender/gpu/opengl/gl_debug.cc
@@ -49,13 +49,13 @@ namespace blender::gpu::debug {
# define APIENTRY
#endif
-static void APIENTRY debug_callback(GLenum UNUSED(source),
+static void APIENTRY debug_callback(GLenum /*source*/,
GLenum type,
- GLuint UNUSED(id),
+ GLuint /*id*/,
GLenum severity,
- GLsizei UNUSED(length),
+ GLsizei /*length*/,
const GLchar *message,
- const GLvoid *UNUSED(userParm))
+ const GLvoid * /*userParm*/)
{
if (ELEM(type, GL_DEBUG_TYPE_PUSH_GROUP, GL_DEBUG_TYPE_POP_GROUP)) {
/* The debug layer will emit a message each time a debug group is pushed or popped.
@@ -80,7 +80,7 @@ static void APIENTRY debug_callback(GLenum UNUSED(source),
const bool use_color = CLG_color_support_get(&LOG);
if (ELEM(severity, GL_DEBUG_SEVERITY_LOW, GL_DEBUG_SEVERITY_NOTIFICATION)) {
- if (((LOG.type->flag & CLG_FLAG_USE) && (LOG.type->level >= CLG_SEVERITY_INFO))) {
+ if ((LOG.type->flag & CLG_FLAG_USE) && (LOG.type->level >= CLG_SEVERITY_INFO)) {
const char *format = use_color ? "\033[2m%s\033[0m" : "%s";
CLG_logf(LOG.type, CLG_SEVERITY_INFO, "Notification", "", format, message);
}
@@ -110,7 +110,7 @@ static void APIENTRY debug_callback(GLenum UNUSED(source),
break;
}
- if (((LOG.type->flag & CLG_FLAG_USE) && (LOG.type->level <= clog_severity))) {
+ if ((LOG.type->flag & CLG_FLAG_USE) && (LOG.type->level <= clog_severity)) {
CLG_logf(LOG.type, clog_severity, debug_groups, "", "%s", message);
if (severity == GL_DEBUG_SEVERITY_HIGH) {
/* Focus on error message. */
diff --git a/source/blender/gpu/opengl/gl_framebuffer.cc b/source/blender/gpu/opengl/gl_framebuffer.cc
index bd9fba4250d..e94f5b66b97 100644
--- a/source/blender/gpu/opengl/gl_framebuffer.cc
+++ b/source/blender/gpu/opengl/gl_framebuffer.cc
@@ -207,6 +207,11 @@ void GLFrameBuffer::update_attachments()
this->size_set(size[0], size[1]);
srgb_ = (GPU_texture_format(attach.tex) == GPU_SRGB8_A8);
}
+ else {
+ /* Empty frame-buffer. */
+ glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, width_);
+ glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, height_);
+ }
dirty_attachments_ = false;
@@ -347,7 +352,7 @@ void GLFrameBuffer::clear_attachment(GPUAttachmentType type,
if (type == GPU_FB_DEPTH_STENCIL_ATTACHMENT) {
BLI_assert(data_format == GPU_DATA_UINT_24_8);
- float depth = ((*(uint32_t *)clear_value) & 0x00FFFFFFu) / (float)0x00FFFFFFu;
+ float depth = ((*(uint32_t *)clear_value) & 0x00FFFFFFu) / float(0x00FFFFFFu);
int stencil = ((*(uint32_t *)clear_value) >> 24);
glClearBufferfi(GL_DEPTH_STENCIL, 0, depth, stencil);
}
@@ -356,7 +361,7 @@ void GLFrameBuffer::clear_attachment(GPUAttachmentType type,
glClearBufferfv(GL_DEPTH, 0, (GLfloat *)clear_value);
}
else if (data_format == GPU_DATA_UINT) {
- float depth = *(uint32_t *)clear_value / (float)0xFFFFFFFFu;
+ float depth = *(uint32_t *)clear_value / float(0xFFFFFFFFu);
glClearBufferfv(GL_DEPTH, 0, &depth);
}
else {
diff --git a/source/blender/gpu/opengl/gl_framebuffer.hh b/source/blender/gpu/opengl/gl_framebuffer.hh
index 8ee04a584bd..edc05322153 100644
--- a/source/blender/gpu/opengl/gl_framebuffer.hh
+++ b/source/blender/gpu/opengl/gl_framebuffer.hh
@@ -32,7 +32,7 @@ class GLFrameBuffer : public FrameBuffer {
/** State Manager of the same contexts. */
GLStateManager *state_manager_ = nullptr;
/** Copy of the GL state. Contains ONLY color attachments enums for slot binding. */
- GLenum gl_attachments_[GPU_FB_MAX_COLOR_ATTACHMENT];
+ GLenum gl_attachments_[GPU_FB_MAX_COLOR_ATTACHMENT] = {0};
/** Internal frame-buffers are immutable. */
bool immutable_;
/** True is the frame-buffer has its first color target using the GPU_SRGB8_A8 format. */
diff --git a/source/blender/gpu/opengl/gl_index_buffer.hh b/source/blender/gpu/opengl/gl_index_buffer.hh
index 974c01d2b65..78159db764c 100644
--- a/source/blender/gpu/opengl/gl_index_buffer.hh
+++ b/source/blender/gpu/opengl/gl_index_buffer.hh
@@ -35,11 +35,9 @@ class GLIndexBuf : public IndexBuf {
{
additional_vertex_offset += index_start_;
if (index_type_ == GPU_INDEX_U32) {
- return reinterpret_cast<void *>(static_cast<intptr_t>(additional_vertex_offset) *
- sizeof(GLuint));
+ return reinterpret_cast<void *>(intptr_t(additional_vertex_offset) * sizeof(GLuint));
}
- return reinterpret_cast<void *>(static_cast<intptr_t>(additional_vertex_offset) *
- sizeof(GLushort));
+ return reinterpret_cast<void *>(intptr_t(additional_vertex_offset) * sizeof(GLushort));
}
GLuint restart_index() const
diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc
index 1f2ef36716e..dafcf4dbf33 100644
--- a/source/blender/gpu/opengl/gl_shader.cc
+++ b/source/blender/gpu/opengl/gl_shader.cc
@@ -568,7 +568,7 @@ std::string GLShader::fragment_interface_declare(const ShaderCreateInfo &info) c
std::string pre_main;
ss << "\n/* Interfaces. */\n";
- const Vector<StageInterfaceInfo *> &in_interfaces = (info.geometry_source_.is_empty()) ?
+ const Vector<StageInterfaceInfo *> &in_interfaces = info.geometry_source_.is_empty() ?
info.vertex_out_interfaces_ :
info.geometry_out_interfaces_;
for (const StageInterfaceInfo *iface : in_interfaces) {
@@ -1138,7 +1138,7 @@ void GLShader::uniform_int(int location, int comp_len, int array_size, const int
int GLShader::program_handle_get() const
{
- return (int)this->shader_program_;
+ return int(this->shader_program_);
}
/** \} */
diff --git a/source/blender/gpu/opengl/gl_shader_interface.cc b/source/blender/gpu/opengl/gl_shader_interface.cc
index b230706b020..ef97d74bf81 100644
--- a/source/blender/gpu/opengl/gl_shader_interface.cc
+++ b/source/blender/gpu/opengl/gl_shader_interface.cc
@@ -200,6 +200,9 @@ static Type gpu_type_from_gl_type(int gl_type)
GLShaderInterface::GLShaderInterface(GLuint program)
{
+ GLuint last_program;
+ glGetIntegerv(GL_CURRENT_PROGRAM, (GLint *)&last_program);
+
/* Necessary to make #glUniform works. */
glUseProgram(program);
@@ -295,7 +298,7 @@ GLShaderInterface::GLShaderInterface(GLuint program)
enabled_attr_mask_ |= (1 << input->location);
/* Used in `GPU_shader_get_attribute_info`. */
- attr_types_[input->location] = (uint8_t)gpu_type_from_gl_type(type);
+ attr_types_[input->location] = uint8_t(gpu_type_from_gl_type(type));
}
/* Uniform Blocks */
@@ -385,6 +388,8 @@ GLShaderInterface::GLShaderInterface(GLuint program)
// this->debug_print();
this->sort_inputs();
+
+ glUseProgram(last_program);
}
GLShaderInterface::GLShaderInterface(GLuint program, const shader::ShaderCreateInfo &info)
@@ -442,6 +447,9 @@ GLShaderInterface::GLShaderInterface(GLuint program, const shader::ShaderCreateI
uint32_t name_buffer_offset = 0;
/* Necessary to make #glUniform works. TODO(fclem) Remove. */
+ GLuint last_program;
+ glGetIntegerv(GL_CURRENT_PROGRAM, (GLint *)&last_program);
+
glUseProgram(program);
/* Attributes */
@@ -457,7 +465,7 @@ GLShaderInterface::GLShaderInterface(GLuint program, const shader::ShaderCreateI
enabled_attr_mask_ |= (1 << input->location);
/* Used in `GPU_shader_get_attribute_info`. */
- attr_types_[input->location] = (uint8_t)attr.type;
+ attr_types_[input->location] = uint8_t(attr.type);
}
input++;
@@ -552,6 +560,8 @@ GLShaderInterface::GLShaderInterface(GLuint program, const shader::ShaderCreateI
this->sort_inputs();
// this->debug_print();
+
+ glUseProgram(last_program);
}
GLShaderInterface::~GLShaderInterface()
diff --git a/source/blender/gpu/opengl/gl_vertex_array.cc b/source/blender/gpu/opengl/gl_vertex_array.cc
index 6897ac9f4a2..9a6df38cb05 100644
--- a/source/blender/gpu/opengl/gl_vertex_array.cc
+++ b/source/blender/gpu/opengl/gl_vertex_array.cc
@@ -47,7 +47,7 @@ static uint16_t vbo_bind(const ShaderInterface *interface,
}
/* This is in fact an offset in memory. */
- const GLvoid *pointer = (const GLubyte *)(intptr_t)(offset + v_first * stride);
+ const GLvoid *pointer = (const GLubyte *)intptr_t(offset + v_first * stride);
const GLenum type = to_gl(static_cast<GPUVertCompType>(a->comp_type));
for (uint n_idx = 0; n_idx < a->name_len; n_idx++) {
@@ -137,7 +137,7 @@ void GLVertArray::update_bindings(const GLuint vao,
GLContext *ctx = GLContext::get();
/* This replaces glVertexAttrib4f(a, 0.0f, 0.0f, 0.0f, 1.0f); with a more modern style.
* Fix issues for some drivers (see T75069). */
- glBindVertexBuffer(a, ctx->default_attr_vbo_, (intptr_t)0, (intptr_t)0);
+ glBindVertexBuffer(a, ctx->default_attr_vbo_, intptr_t(0), intptr_t(0));
glEnableVertexAttribArray(a);
glVertexAttribFormat(a, 4, GL_FLOAT, GL_FALSE, 0);
glVertexAttribBinding(a, a);
diff --git a/source/blender/gpu/opengl/gl_vertex_buffer.cc b/source/blender/gpu/opengl/gl_vertex_buffer.cc
index 6942a220892..d186c2025b3 100644
--- a/source/blender/gpu/opengl/gl_vertex_buffer.cc
+++ b/source/blender/gpu/opengl/gl_vertex_buffer.cc
@@ -142,9 +142,9 @@ void *GLVertBuf::unmap(const void *mapped_data) const
void GLVertBuf::wrap_handle(uint64_t handle)
{
BLI_assert(vbo_id_ == 0);
- BLI_assert(glIsBuffer(static_cast<uint>(handle)));
+ BLI_assert(glIsBuffer(uint(handle)));
is_wrapper_ = true;
- vbo_id_ = static_cast<uint>(handle);
+ vbo_id_ = uint(handle);
/* We assume the data is already on the device, so no need to allocate or send it. */
flag = GPU_VERTBUF_DATA_UPLOADED;
}
diff --git a/source/blender/gpu/shaders/common/gpu_shader_common_math.glsl b/source/blender/gpu/shaders/common/gpu_shader_common_math.glsl
index 5f640f64056..1e858bd4760 100644
--- a/source/blender/gpu/shaders/common/gpu_shader_common_math.glsl
+++ b/source/blender/gpu/shaders/common/gpu_shader_common_math.glsl
@@ -126,7 +126,7 @@ void math_pingpong(float a, float b, float c, out float result)
result = (b != 0.0) ? abs(fract((a - b) / (b * 2.0)) * b * 2.0 - b) : 0.0;
}
-/* Adapted from godotengine math_funcs.h. */
+/* Adapted from GODOT-engine math_funcs.h. */
void math_wrap(float a, float b, float c, out float result)
{
result = wrap(a, b, c);
diff --git a/source/blender/gpu/shaders/common/gpu_shader_common_math_utils.glsl b/source/blender/gpu/shaders/common/gpu_shader_common_math_utils.glsl
index 1ba22b4c5da..47f8e26db0b 100644
--- a/source/blender/gpu/shaders/common/gpu_shader_common_math_utils.glsl
+++ b/source/blender/gpu/shaders/common/gpu_shader_common_math_utils.glsl
@@ -132,7 +132,7 @@ vec3 fallback_pow(vec3 a, float b, vec3 fallback)
fallback_pow(a.z, b, fallback.z));
}
-/* Matirx Math */
+/* Matrix Math */
/* Return a 2D rotation matrix with the angle that the input 2D vector makes with the x axis. */
mat2 vector_to_rotation_matrix(vec2 vector)
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl
index 662589fb2ce..cd8ff73b833 100644
--- a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl
@@ -6,7 +6,7 @@ vec3 compute_masks(vec2 uv)
bool right_half = uv.x > outRectSize.x * 0.5;
float corner_rad;
- /* Correct aspect ratio for 2D views not using uniform scalling.
+ /* Correct aspect ratio for 2D views not using uniform scaling.
* uv is already in pixel space so a uniform scale should give us a ratio of 1. */
float ratio = (butCo != -2.0) ? (dFdy(uv.y) / dFdx(uv.x)) : 1.0;
vec2 uv_sdf = uv;
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl
index c102b422211..d6c93df9849 100644
--- a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl
@@ -124,8 +124,8 @@ vec2 do_tria()
}
else if (triaType == 4.0) {
/* ROUNDBOX_TRIA_CHECK */
- /* A bit more hacky: We use the two trias joined together to render
- * both sides of the checkmark with different length. */
+ /* A bit more hacky: We use the two triangles joined together to render
+ * both sides of the check-mark with different length. */
pos = arrow_pos[min(vidx, 2)]; /* Only keep 1 triangle. */
pos.y = tria2 ? -pos.y : pos.y; /* Mirror along X */
pos = pos.x * vec2(0.0872, -0.996) + pos.y * vec2(0.996, 0.0872); /* Rotate (85deg) */
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_polyline_frag.glsl b/source/blender/gpu/shaders/gpu_shader_3D_polyline_frag.glsl
index 27740c8d71b..f912bad8a14 100644
--- a/source/blender/gpu/shaders/gpu_shader_3D_polyline_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_3D_polyline_frag.glsl
@@ -7,7 +7,7 @@ void main()
discard;
}
#endif
- fragColor = interp.color;
+ fragColor = interp.final_color;
if (lineSmooth) {
fragColor.a *= clamp((lineWidth + SMOOTH_WIDTH) * 0.5 - abs(interp.smoothline), 0.0, 1.0);
}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_polyline_geom.glsl b/source/blender/gpu/shaders/gpu_shader_3D_polyline_geom.glsl
index 1c824023234..6d23e03c835 100644
--- a/source/blender/gpu/shaders/gpu_shader_3D_polyline_geom.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_3D_polyline_geom.glsl
@@ -18,14 +18,14 @@ vec4 clip_line_point_homogeneous_space(vec4 p, vec4 q)
void do_vertex(const int i, vec4 pos, vec2 ofs)
{
#if defined(UNIFORM)
- interp_out.color = color;
+ interp_out.final_color = color;
#elif defined(FLAT)
/* WATCH: Assuming last provoking vertex. */
- interp_out.color = interp_in[1].color;
+ interp_out.final_color = interp_in[1].final_color;
#elif defined(SMOOTH)
- interp_out.color = interp_in[i].color;
+ interp_out.final_color = interp_in[i].final_color;
#endif
#ifdef CLIP
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert.glsl
index d4ef3e6142f..5119db2437c 100644
--- a/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert.glsl
@@ -3,7 +3,7 @@ void main()
{
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
#ifndef UNIFORM
- interp.color = color;
+ interp.final_color = color;
#endif
#ifdef CLIP
interp.clip = dot(ModelMatrix * vec4(pos, 1.0), ClipPlane);
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert_no_geom.glsl b/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert_no_geom.glsl
new file mode 100644
index 00000000000..4c1aebd9caf
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert_no_geom.glsl
@@ -0,0 +1,162 @@
+
+#pragma USE_SSBO_VERTEX_FETCH(TriangleList, 6)
+
+/* Local vars to store results per input vertex. */
+#if !defined(UNIFORM)
+vec4 finalColor_g[2];
+#endif
+
+#ifdef CLIP
+float clip_g[2];
+#endif
+
+#define SMOOTH_WIDTH 1.0
+
+/* Clips point to near clip plane before perspective divide. */
+vec4 clip_line_point_homogeneous_space(vec4 p, vec4 q)
+{
+ if (p.z < -p.w) {
+ /* Just solves p + (q - p) * A; for A when p.z / p.w = -1.0. */
+ float denom = q.z - p.z + q.w - p.w;
+ if (denom == 0.0) {
+ /* No solution. */
+ return p;
+ }
+ float A = (-p.z - p.w) / denom;
+ p = p + (q - p) * A;
+ }
+ return p;
+}
+
+void do_vertex(int index, vec4 pos, vec2 ofs, float flip)
+{
+#if defined(UNIFORM)
+ interp.final_color = color;
+
+#elif defined(FLAT)
+ /* WATCH: Assuming last provoking vertex. */
+ interp.final_color = finalColor_g[index];
+
+#elif defined(SMOOTH)
+ interp.final_color = finalColor_g[index];
+#endif
+
+#ifdef CLIP
+ interp.clip = clip_g[index];
+#endif
+
+ interp.smoothline = flip * (lineWidth + SMOOTH_WIDTH * float(lineSmooth)) * 0.5;
+ gl_Position = pos;
+ gl_Position.xy += flip * ofs * pos.w;
+}
+
+void main()
+{
+ /** Determine output quad primitive structure. */
+ /* Index of the quad primitive. Each quad corresponds to one line in the input primitive. */
+ int quad_id = gl_VertexID / 6;
+
+ /* Determine vertex within the quad (A, B, C)(A, C, D).*/
+ int quad_vertex_id = gl_VertexID % 6;
+
+ uint src_index_a;
+ uint src_index_b;
+ if (vertex_fetch_get_input_prim_type() == GPU_PRIM_LINE_STRIP) {
+ src_index_a = quad_id;
+ src_index_b = quad_id + 1;
+ }
+ else if (vertex_fetch_get_input_prim_type() == GPU_PRIM_LINES) {
+ src_index_a = quad_id * 2;
+ src_index_b = quad_id * 2 + 1;
+ }
+ else if (vertex_fetch_get_input_prim_type() == GPU_PRIM_LINE_LOOP) {
+ src_index_a = quad_id;
+ src_index_b = quad_id + 1;
+ if (quad_id == vertex_fetch_get_input_vert_count() - 1) {
+ src_index_b = 0;
+ }
+ }
+ else {
+ src_index_a = 0;
+ src_index_b = 0;
+ }
+
+ /* Fetch input attributes for line prims -- either provided as vec2 or vec3 -- So we need to
+ * query the type. */
+ vec3 in_pos0, in_pos1;
+ in_pos0 = vec3(0.0);
+ in_pos1 = vec3(0.0);
+ if (vertex_fetch_get_attr_type(pos) == GPU_SHADER_ATTR_TYPE_VEC4) {
+ in_pos0 = vertex_fetch_attribute(src_index_a, pos, vec4).xyz;
+ in_pos1 = vertex_fetch_attribute(src_index_b, pos, vec4).xyz;
+ }
+ else if (vertex_fetch_get_attr_type(pos) == GPU_SHADER_ATTR_TYPE_VEC3) {
+ in_pos0 = vertex_fetch_attribute(src_index_a, pos, vec3);
+ in_pos1 = vertex_fetch_attribute(src_index_b, pos, vec3);
+ }
+ else if (vertex_fetch_get_attr_type(pos) == GPU_SHADER_ATTR_TYPE_VEC2) {
+ in_pos0 = vec3(vertex_fetch_attribute(src_index_a, pos, vec2), 0.0);
+ in_pos1 = vec3(vertex_fetch_attribute(src_index_b, pos, vec2), 0.0);
+ }
+#if !defined(UNIFORM)
+ vec4 in_color0 = vec4(0.0);
+ vec4 in_color1 = vec4(0.0);
+
+ if (vertex_fetch_get_attr_type(color) == GPU_SHADER_ATTR_TYPE_VEC4) {
+ in_color0 = vertex_fetch_attribute(src_index_a, color, vec4);
+ in_color1 = vertex_fetch_attribute(src_index_b, color, vec4);
+ }
+ else if (vertex_fetch_get_attr_type(color) == GPU_SHADER_ATTR_TYPE_VEC3) {
+ in_color0 = vec4(vertex_fetch_attribute(src_index_a, color, vec3), 1.0);
+ in_color1 = vec4(vertex_fetch_attribute(src_index_b, color, vec3), 1.0);
+ }
+ else if (vertex_fetch_get_attr_type(color) == GPU_SHADER_ATTR_TYPE_UCHAR4_NORM) {
+ in_color0 = vec4(vertex_fetch_attribute(src_index_a, color, uchar4)) / vec4(255.0);
+ in_color1 = vec4(vertex_fetch_attribute(src_index_b, color, uchar4)) / vec4(255.0);
+ }
+ else if (vertex_fetch_get_attr_type(color) == GPU_SHADER_ATTR_TYPE_UCHAR3_NORM) {
+ in_color0 = vec4(vec3(vertex_fetch_attribute(src_index_a, color, uchar3)) / vec3(255.0), 1.0);
+ in_color1 = vec4(vec3(vertex_fetch_attribute(src_index_b, color, uchar3)) / vec3(255.0), 1.0);
+ }
+#endif
+
+ /* Calculate Vertex shader for both points in Line. */
+ vec4 out_pos0 = ModelViewProjectionMatrix * vec4(in_pos0, 1.0);
+ vec4 out_pos1 = ModelViewProjectionMatrix * vec4(in_pos1, 1.0);
+#if !defined(UNIFORM)
+ finalColor_g[0] = in_color0;
+ finalColor_g[1] = in_color1;
+#endif
+#ifdef CLIP
+ clip_g[0] = dot(ModelMatrix * vec4(in_pos0, 1.0), ClipPlane);
+ clip_g[1] = dot(ModelMatrix * vec4(in_pos1, 1.0), ClipPlane);
+#endif
+
+ /*** Geometry Shader Alternative. ***/
+ vec4 p0 = clip_line_point_homogeneous_space(out_pos0, out_pos1);
+ vec4 p1 = clip_line_point_homogeneous_space(out_pos1, out_pos0);
+ vec2 e = normalize(((p1.xy / p1.w) - (p0.xy / p0.w)) * viewportSize.xy);
+
+#if 0 /* Hard turn when line direction changes quadrant. */
+ e = abs(e);
+ vec2 ofs = (e.x > e.y) ? vec2(0.0, 1.0 / e.x) : vec2(1.0 / e.y, 0.0);
+#else /* Use perpendicular direction. */
+ vec2 ofs = vec2(-e.y, e.x);
+#endif
+
+ ofs /= viewportSize.xy;
+ ofs *= lineWidth + SMOOTH_WIDTH * float(lineSmooth);
+
+ if (quad_vertex_id == 0) {
+ do_vertex(0, p0, ofs, 1.0);
+ }
+ else if (quad_vertex_id == 1 || quad_vertex_id == 3) {
+ do_vertex(0, p0, ofs, -1.0);
+ }
+ else if (quad_vertex_id == 2 || quad_vertex_id == 5) {
+ do_vertex(1, p1, ofs, 1.0);
+ }
+ else if (quad_vertex_id == 4) {
+ do_vertex(1, p1, ofs, -1.0);
+ }
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl
index 94707de71ed..38734d5bbaf 100644
--- a/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl
@@ -67,7 +67,7 @@ vec3 orco_get(vec3 local_pos, mat4 modelmatinv, vec4 orco_madd[2], vec4 orco)
/* If the object does not have any deformation, the orco layer calculation is done on the fly
* using the orco_madd factors.
* We know when there is no orco layer when orco.w is 1.0 because it uses the generic vertex
- * attrib (which is [0,0,0,1]). */
+ * attribute (which is [0,0,0,1]). */
if (orco.w == 0.0) {
return orco.xyz * 0.5 + 0.5;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_icon_frag.glsl b/source/blender/gpu/shaders/gpu_shader_icon_frag.glsl
new file mode 100644
index 00000000000..4452349f23c
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_icon_frag.glsl
@@ -0,0 +1,42 @@
+/**
+ * Draw the icons, leaving a semi-transparent rectangle on top of the icon.
+ *
+ * The top-left corner of the rectangle is rounded and drawned with anti-alias.
+ * The anti-alias is done by transitioning from the outer to the inner radius of
+ * the rounded corner, and the rectangle sides.
+ */
+
+void main()
+{
+ /* Top-left rounded corner parameters. */
+ const float circle_radius_outer = 0.1;
+ const float circle_radius_inner = 0.075;
+
+ /**
+ * Add a bit transparency to see a bit of the icon, without
+ * getting on the way of readability. */
+ const float mask_transparency = 0.25;
+
+ vec2 circle_center = vec2(circle_radius_outer - text_width, 0.5);
+ fragColor = texture(image, texCoord_interp) * color;
+
+ /* radius in icon space (1 is the icon width). */
+ float radius = length(mask_coord_interp - circle_center);
+ float mask = smoothstep(circle_radius_inner, circle_radius_outer, radius);
+
+ bool lower_half = mask_coord_interp.y < circle_center.y;
+ bool right_half = mask_coord_interp.x > circle_center.x;
+
+ if (right_half && mask_coord_interp.y < circle_center.y + circle_radius_outer) {
+ mask = smoothstep(circle_center.y + circle_radius_inner,
+ circle_center.y + circle_radius_outer,
+ mask_coord_interp.y);
+ }
+ if (lower_half && mask_coord_interp.x > circle_center.x - circle_radius_outer) {
+ mask = smoothstep(circle_center.x - circle_radius_inner,
+ circle_center.x - circle_radius_outer,
+ mask_coord_interp.x);
+ }
+
+ fragColor = mix(vec4(0.0), fragColor, max(mask_transparency, mask));
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_icon_vert.glsl b/source/blender/gpu/shaders/gpu_shader_icon_vert.glsl
new file mode 100644
index 00000000000..25f64bfe0b6
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_icon_vert.glsl
@@ -0,0 +1,37 @@
+/**
+ * Simple shader that just draw one icon at the specified location
+ * does not need any vertex input (producing less call to immBegin/End)
+ */
+
+void main()
+{
+ vec2 uv;
+ vec2 co;
+
+ if (gl_VertexID == 0) {
+ co = rect_geom.xw;
+ uv = rect_icon.xw;
+ mask_coord_interp = vec2(0, 1);
+ }
+ else if (gl_VertexID == 1) {
+ co = rect_geom.xy;
+ uv = rect_icon.xy;
+ mask_coord_interp = vec2(0, 0);
+ }
+ else if (gl_VertexID == 2) {
+ co = rect_geom.zw;
+ uv = rect_icon.zw;
+ mask_coord_interp = vec2(1, 1);
+ }
+ else {
+ co = rect_geom.zy;
+ uv = rect_icon.zy;
+ mask_coord_interp = vec2(1, 0);
+ }
+
+ /* Put origin in lower right corner. */
+ mask_coord_interp.x -= 1;
+
+ gl_Position = ModelViewProjectionMatrix * vec4(co, 0.0f, 1.0f);
+ texCoord_interp = uv;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_text_vert.glsl b/source/blender/gpu/shaders/gpu_shader_text_vert.glsl
index 47527d907f4..87e464b6cce 100644
--- a/source/blender/gpu/shaders/gpu_shader_text_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_text_vert.glsl
@@ -6,7 +6,7 @@ void main()
glyph_dim = abs(glyph_size);
interp_size = int(glyph_size.x < 0) + int(glyph_size.y < 0);
- /* Quad expension using instanced rendering. */
+ /* Quad expansion using instanced rendering. */
float x = float(gl_VertexID % 2);
float y = float(gl_VertexID / 2);
vec2 quad = vec2(x, y);
diff --git a/source/blender/gpu/shaders/infos/gpu_interface_info.hh b/source/blender/gpu/shaders/infos/gpu_interface_info.hh
index d77c65e48a7..060def16f81 100644
--- a/source/blender/gpu/shaders/infos/gpu_interface_info.hh
+++ b/source/blender/gpu/shaders/infos/gpu_interface_info.hh
@@ -18,3 +18,6 @@ GPU_SHADER_INTERFACE_INFO(smooth_radii_outline_iface, "").smooth(Type::VEC4, "ra
GPU_SHADER_INTERFACE_INFO(flat_color_smooth_tex_coord_interp_iface, "")
.flat(Type::VEC4, "finalColor")
.smooth(Type::VEC2, "texCoord_interp");
+GPU_SHADER_INTERFACE_INFO(smooth_icon_interp_iface, "")
+ .smooth(Type::VEC2, "texCoord_interp")
+ .smooth(Type::VEC2, "mask_coord_interp");
diff --git a/source/blender/gpu/shaders/infos/gpu_shader_3D_polyline_info.hh b/source/blender/gpu/shaders/infos/gpu_shader_3D_polyline_info.hh
index 396ee64454c..23f6790abfc 100644
--- a/source/blender/gpu/shaders/infos/gpu_shader_3D_polyline_info.hh
+++ b/source/blender/gpu/shaders/infos/gpu_shader_3D_polyline_info.hh
@@ -9,7 +9,7 @@
#include "gpu_shader_create_info.hh"
GPU_SHADER_INTERFACE_INFO(gpu_shader_3D_polyline_iface, "interp")
- .smooth(Type::VEC4, "color")
+ .smooth(Type::VEC4, "final_color")
.smooth(Type::FLOAT, "clip")
.no_perspective(Type::FLOAT, "smoothline");
@@ -29,12 +29,31 @@ GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline)
.fragment_source("gpu_shader_3D_polyline_frag.glsl")
.additional_info("gpu_srgb_to_framebuffer_space");
+GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_no_geom)
+ .define("SMOOTH_WIDTH", "1.0")
+ .push_constant(Type::MAT4, "ModelViewProjectionMatrix")
+ .push_constant(Type::VEC2, "viewportSize")
+ .push_constant(Type::FLOAT, "lineWidth")
+ .push_constant(Type::BOOL, "lineSmooth")
+ .vertex_in(0, Type::VEC3, "pos")
+ .vertex_out(gpu_shader_3D_polyline_iface)
+ .fragment_out(0, Type::VEC4, "fragColor")
+ .vertex_source("gpu_shader_3D_polyline_vert_no_geom.glsl")
+ .fragment_source("gpu_shader_3D_polyline_frag.glsl")
+ .additional_info("gpu_srgb_to_framebuffer_space");
+
GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_uniform_color)
.do_static_compilation(true)
.define("UNIFORM")
.push_constant(Type::VEC4, "color")
.additional_info("gpu_shader_3D_polyline");
+GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_uniform_color_no_geom)
+ // .do_static_compilation(true) /* TODO fix on GL */
+ .define("UNIFORM")
+ .push_constant(Type::VEC4, "color")
+ .additional_info("gpu_shader_3D_polyline_no_geom");
+
GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_uniform_color_clipped)
.do_static_compilation(true)
/* TODO(fclem): Put in a UBO to fit the 128byte requirement. */
@@ -43,14 +62,34 @@ GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_uniform_color_clipped)
.define("CLIP")
.additional_info("gpu_shader_3D_polyline_uniform_color");
+GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_uniform_color_clipped_no_geom)
+ // .do_static_compilation(true) /* TODO fix on GL */
+ /* TODO(fclem): Put in an UBO to fit the 128byte requirement. */
+ .push_constant(Type::MAT4, "ModelMatrix")
+ .push_constant(Type::VEC4, "ClipPlane")
+ .define("CLIP")
+ .additional_info("gpu_shader_3D_polyline_uniform_color_no_geom");
+
GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_flat_color)
.do_static_compilation(true)
.define("FLAT")
.vertex_in(1, Type::VEC4, "color")
.additional_info("gpu_shader_3D_polyline");
+GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_flat_color_no_geom)
+ // .do_static_compilation(true) /* TODO fix on GL */
+ .define("FLAT")
+ .vertex_in(1, Type::VEC4, "color")
+ .additional_info("gpu_shader_3D_polyline_no_geom");
+
GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_smooth_color)
.do_static_compilation(true)
.define("SMOOTH")
.vertex_in(1, Type::VEC4, "color")
.additional_info("gpu_shader_3D_polyline");
+
+GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_smooth_color_no_geom)
+ // .do_static_compilation(true) /* TODO fix on GL */
+ .define("SMOOTH")
+ .vertex_in(1, Type::VEC4, "color")
+ .additional_info("gpu_shader_3D_polyline_no_geom");
diff --git a/source/blender/gpu/shaders/infos/gpu_shader_icon_info.hh b/source/blender/gpu/shaders/infos/gpu_shader_icon_info.hh
new file mode 100644
index 00000000000..3d4077bdb09
--- /dev/null
+++ b/source/blender/gpu/shaders/infos/gpu_shader_icon_info.hh
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "gpu_interface_info.hh"
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(gpu_shader_icon)
+ .vertex_out(smooth_icon_interp_iface)
+ .fragment_out(0, Type::VEC4, "fragColor")
+ .push_constant(Type::MAT4, "ModelViewProjectionMatrix")
+ .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "rect_icon")
+ .push_constant(Type::VEC4, "rect_geom")
+ .push_constant(Type::FLOAT, "text_width")
+ .sampler(0, ImageType::FLOAT_2D, "image")
+ .vertex_source("gpu_shader_icon_vert.glsl")
+ .fragment_source("gpu_shader_icon_frag.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_attribute.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_attribute.glsl
index bacf089deb1..8d0016a2206 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_attribute.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_attribute.glsl
@@ -29,6 +29,31 @@ void node_attribute_uniform(vec4 attr, const float attr_hash, out vec4 out_attr)
out_attr = attr_load_uniform(attr, floatBitsToUint(attr_hash));
}
+vec4 attr_load_layer(const uint attr_hash)
+{
+#ifdef VLATTR_LIB
+ /* The first record of the buffer stores the length. */
+ uint left = 0, right = drw_layer_attrs[0].buffer_length;
+
+ while (left < right) {
+ uint mid = (left + right) / 2;
+ uint hash = drw_layer_attrs[mid].hash_code;
+
+ if (hash < attr_hash) {
+ left = mid + 1;
+ }
+ else if (hash > attr_hash) {
+ right = mid;
+ }
+ else {
+ return drw_layer_attrs[mid].data;
+ }
+ }
+#endif
+
+ return vec4(0.0);
+}
+
void node_attribute(
vec4 attr, out vec4 outcol, out vec3 outvec, out float outf, out float outalpha)
{
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
index 0d8f2272c10..0833809cc42 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
@@ -91,7 +91,7 @@ void node_bsdf_principled(vec4 base_color,
diffuse_data.sss_id = uint(do_sss);
/* NOTE(@fclem): We need to blend the reflection color but also need to avoid applying the
- * weights so we compule the ratio. */
+ * weights so we compute the ratio. */
float reflection_weight = specular_weight + glass_reflection_weight;
float reflection_weight_inv = safe_rcp(reflection_weight);
specular_weight *= reflection_weight_inv;
@@ -150,7 +150,7 @@ void node_bsdf_principled(vec4 base_color,
refraction_data.ior = ior;
/* Ref. T98190: Defines are optimizations for old compilers.
- * Might become unecessary with EEVEE-Next. */
+ * Might become unnecessary with EEVEE-Next. */
if (do_diffuse == 0.0 && do_refraction == 0.0 && do_clearcoat != 0.0) {
#ifdef PRINCIPLED_CLEARCOAT
/* Metallic & Clearcoat case. */
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_sky.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_sky.glsl
index b6aad5904ff..c4b47bc1756 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_sky.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_sky.glsl
@@ -144,7 +144,47 @@ void node_tex_sky_hosekwilkie(vec3 co,
color = vec4(dot(xyz_to_r, xyz), dot(xyz_to_g, xyz), dot(xyz_to_b, xyz), 1);
}
-void node_tex_sky_nishita(vec3 co, out vec4 color)
+void node_tex_sky_nishita(vec3 co,
+ float sun_rotation,
+ vec3 xyz_to_r,
+ vec3 xyz_to_g,
+ vec3 xyz_to_b,
+ sampler2DArray ima,
+ float layer,
+ out vec4 color)
{
- color = vec4(1.0);
+ vec3 spherical = sky_spherical_coordinates(co);
+
+ vec3 xyz;
+ if (co.z < -0.4) {
+ /* too far below the horizon, just return black */
+ color = vec4(0, 0, 0, 1);
+ }
+ else {
+ /* evaluate longitudinal position on the map */
+ float x = (spherical.y + M_PI + sun_rotation) / M_2PI;
+ if (x > 1.0) {
+ x -= 1.0;
+ }
+
+ float fade;
+ float y;
+ if (co.z < 0.0) {
+ /* we're below the horizon, so extend the map by blending from values at the horizon
+ * to zero according to a cubic falloff */
+ fade = 1.0 + co.z * 2.5;
+ fade = fade * fade * fade;
+ y = 0.0;
+ }
+ else {
+ /* we're above the horizon, so compute the lateral position by inverting the remapped
+ * coordinates that are preserve to have more detail near the horizon. */
+ fade = 1.0;
+ y = sqrt((M_PI_2 - spherical.x) / M_PI_2);
+ }
+
+ /* look up color in the precomputed map and convert to RGB */
+ xyz = fade * texture(ima, vec3(x, y, layer)).rgb;
+ color = vec4(dot(xyz_to_r, xyz), dot(xyz_to_g, xyz), dot(xyz_to_b, xyz), 1);
+ }
}
diff --git a/source/blender/gpu/shaders/opengl/glsl_shader_defines.glsl b/source/blender/gpu/shaders/opengl/glsl_shader_defines.glsl
index 0515a737e6e..706bae3e940 100644
--- a/source/blender/gpu/shaders/opengl/glsl_shader_defines.glsl
+++ b/source/blender/gpu/shaders/opengl/glsl_shader_defines.glsl
@@ -1,5 +1,5 @@
-/* Texture format tokens -- Type explictness required by other Graphics APIs. */
+/* Texture format tokens -- Type explicitness required by other Graphics APIs. */
#define depth2D sampler2D
#define depth2DArray sampler2DArray
#define depth2DMS sampler2DMS
diff --git a/source/blender/gpu/tests/gpu_testing.cc b/source/blender/gpu/tests/gpu_testing.cc
index 224a9afcf59..67e296b11d5 100644
--- a/source/blender/gpu/tests/gpu_testing.cc
+++ b/source/blender/gpu/tests/gpu_testing.cc
@@ -19,7 +19,7 @@ void GPUTest::SetUp()
ghost_system = GHOST_CreateSystem();
ghost_context = GHOST_CreateOpenGLContext(ghost_system, glSettings);
GHOST_ActivateOpenGLContext(ghost_context);
- context = GPU_context_create(nullptr);
+ context = GPU_context_create(nullptr, ghost_context);
GPU_init();
}
diff --git a/source/blender/gpu/vulkan/vk_backend.cc b/source/blender/gpu/vulkan/vk_backend.cc
new file mode 100644
index 00000000000..00bc43333d6
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_backend.cc
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "vk_backend.hh"
+
+#include "vk_batch.hh"
+#include "vk_context.hh"
+#include "vk_drawlist.hh"
+#include "vk_framebuffer.hh"
+#include "vk_index_buffer.hh"
+#include "vk_query.hh"
+#include "vk_shader.hh"
+#include "vk_storage_buffer.hh"
+#include "vk_texture.hh"
+#include "vk_uniform_buffer.hh"
+#include "vk_vertex_buffer.hh"
+
+namespace blender::gpu {
+
+void VKBackend::delete_resources()
+{
+}
+
+void VKBackend::samplers_update()
+{
+}
+
+void VKBackend::compute_dispatch(int /*groups_x_len*/, int /*groups_y_len*/, int /*groups_z_len*/)
+{
+}
+
+void VKBackend::compute_dispatch_indirect(StorageBuf * /*indirect_buf*/)
+{
+}
+
+Context *VKBackend::context_alloc(void * /*ghost_window*/, void * /*ghost_context*/)
+{
+ return new VKContext();
+}
+
+Batch *VKBackend::batch_alloc()
+{
+ return new VKBatch();
+}
+
+DrawList *VKBackend::drawlist_alloc(int /*list_length*/)
+{
+ return new VKDrawList();
+}
+
+FrameBuffer *VKBackend::framebuffer_alloc(const char *name)
+{
+ return new VKFrameBuffer(name);
+}
+
+IndexBuf *VKBackend::indexbuf_alloc()
+{
+ return new VKIndexBuffer();
+}
+
+QueryPool *VKBackend::querypool_alloc()
+{
+ return new VKQueryPool();
+}
+
+Shader *VKBackend::shader_alloc(const char *name)
+{
+ return new VKShader(name);
+}
+
+Texture *VKBackend::texture_alloc(const char *name)
+{
+ return new VKTexture(name);
+}
+
+UniformBuf *VKBackend::uniformbuf_alloc(int size, const char *name)
+{
+ return new VKUniformBuffer(size, name);
+}
+
+StorageBuf *VKBackend::storagebuf_alloc(int size, GPUUsageType /*usage*/, const char *name)
+{
+ return new VKStorageBuffer(size, name);
+}
+
+VertBuf *VKBackend::vertbuf_alloc()
+{
+ return new VKVertexBuffer();
+}
+
+void VKBackend::render_begin()
+{
+}
+
+void VKBackend::render_end()
+{
+}
+
+void VKBackend::render_step()
+{
+}
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_backend.hh b/source/blender/gpu/vulkan/vk_backend.hh
new file mode 100644
index 00000000000..549478586e8
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_backend.hh
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#pragma once
+
+#include "gpu_backend.hh"
+
+namespace blender::gpu {
+
+class VKBackend : public GPUBackend {
+ public:
+ void delete_resources() override;
+
+ void samplers_update() override;
+ void compute_dispatch(int groups_x_len, int groups_y_len, int groups_z_len) override;
+ void compute_dispatch_indirect(StorageBuf *indirect_buf) override;
+
+ Context *context_alloc(void *ghost_window, void *ghost_context) override;
+
+ Batch *batch_alloc() override;
+ DrawList *drawlist_alloc(int list_length) override;
+ FrameBuffer *framebuffer_alloc(const char *name) override;
+ IndexBuf *indexbuf_alloc() override;
+ QueryPool *querypool_alloc() override;
+ Shader *shader_alloc(const char *name) override;
+ Texture *texture_alloc(const char *name) override;
+ UniformBuf *uniformbuf_alloc(int size, const char *name) override;
+ StorageBuf *storagebuf_alloc(int size, GPUUsageType usage, const char *name) override;
+ VertBuf *vertbuf_alloc() override;
+
+ /* Render Frame Coordination --
+ * Used for performing per-frame actions globally */
+ void render_begin() override;
+ void render_end() override;
+ void render_step() override;
+};
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_batch.cc b/source/blender/gpu/vulkan/vk_batch.cc
new file mode 100644
index 00000000000..a25f98a2e24
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_batch.cc
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "vk_batch.hh"
+
+namespace blender::gpu {
+
+void VKBatch::draw(int /*v_first*/, int /*v_count*/, int /*i_first*/, int /*i_count*/)
+{
+}
+
+void VKBatch::draw_indirect(GPUStorageBuf * /*indirect_buf*/, intptr_t /*offset*/)
+{
+}
+
+void VKBatch::multi_draw_indirect(GPUStorageBuf * /*indirect_buf*/,
+ int /*count*/,
+ intptr_t /*offset*/,
+ intptr_t /*stride*/)
+{
+}
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_batch.hh b/source/blender/gpu/vulkan/vk_batch.hh
new file mode 100644
index 00000000000..0f6df41606d
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_batch.hh
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#pragma once
+
+#include "gpu_batch_private.hh"
+
+namespace blender::gpu {
+
+class VKBatch : public Batch {
+ public:
+ void draw(int v_first, int v_count, int i_first, int i_count) override;
+ void draw_indirect(GPUStorageBuf *indirect_buf, intptr_t offset) override;
+ void multi_draw_indirect(GPUStorageBuf *indirect_buf,
+ int count,
+ intptr_t offset,
+ intptr_t stride) override;
+};
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_context.cc b/source/blender/gpu/vulkan/vk_context.cc
new file mode 100644
index 00000000000..55b29ea4e2f
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_context.cc
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "vk_context.hh"
+
+namespace blender::gpu {
+
+void VKContext::activate()
+{
+}
+
+void VKContext::deactivate()
+{
+}
+
+void VKContext::begin_frame()
+{
+}
+
+void VKContext::end_frame()
+{
+}
+
+void VKContext::flush()
+{
+}
+
+void VKContext::finish()
+{
+}
+
+void VKContext::memory_statistics_get(int * /*total_mem*/, int * /*free_mem*/)
+{
+}
+
+void VKContext::debug_group_begin(const char *, int)
+{
+}
+
+void VKContext::debug_group_end()
+{
+}
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_context.hh b/source/blender/gpu/vulkan/vk_context.hh
new file mode 100644
index 00000000000..17292b891b6
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_context.hh
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#pragma once
+
+#include "gpu_context_private.hh"
+
+namespace blender::gpu {
+
+class VKContext : public Context {
+ public:
+ VKContext()
+ {
+ }
+
+ void activate() override;
+ void deactivate() override;
+ void begin_frame() override;
+ void end_frame() override;
+
+ void flush() override;
+ void finish() override;
+
+ void memory_statistics_get(int *total_mem, int *free_mem) override;
+
+ void debug_group_begin(const char *, int) override;
+ void debug_group_end() override;
+};
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_drawlist.cc b/source/blender/gpu/vulkan/vk_drawlist.cc
new file mode 100644
index 00000000000..c8f3c736bb8
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_drawlist.cc
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "vk_drawlist.hh"
+
+namespace blender::gpu {
+
+void VKDrawList::append(GPUBatch * /*batch*/, int /*i_first*/, int /*i_count*/)
+{
+}
+
+void VKDrawList::submit()
+{
+}
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_drawlist.hh b/source/blender/gpu/vulkan/vk_drawlist.hh
new file mode 100644
index 00000000000..4707bf4bb26
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_drawlist.hh
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#pragma once
+
+#include "gpu_drawlist_private.hh"
+
+namespace blender::gpu {
+
+class VKDrawList : public DrawList {
+ public:
+ void append(GPUBatch *batch, int i_first, int i_count) override;
+ void submit() override;
+};
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_framebuffer.cc b/source/blender/gpu/vulkan/vk_framebuffer.cc
new file mode 100644
index 00000000000..48b0685bf38
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_framebuffer.cc
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "vk_framebuffer.hh"
+
+namespace blender::gpu {
+
+void VKFrameBuffer::bind(bool /*enabled_srgb*/)
+{
+}
+
+bool VKFrameBuffer::check(char /*err_out*/[256])
+{
+ return false;
+}
+
+void VKFrameBuffer::clear(eGPUFrameBufferBits /*buffers*/,
+ const float /*clear_col*/[4],
+ float /*clear_depth*/,
+ uint /*clear_stencil*/)
+{
+}
+
+void VKFrameBuffer::clear_multi(const float (*/*clear_col*/)[4])
+{
+}
+
+void VKFrameBuffer::clear_attachment(GPUAttachmentType /*type*/,
+ eGPUDataFormat /*data_format*/,
+ const void * /*clear_value*/)
+{
+}
+
+void VKFrameBuffer::attachment_set_loadstore_op(GPUAttachmentType /*type*/,
+ eGPULoadOp /*load_action*/,
+ eGPUStoreOp /*store_action*/)
+{
+}
+
+void VKFrameBuffer::read(eGPUFrameBufferBits /*planes*/,
+ eGPUDataFormat /*format*/,
+ const int /*area*/[4],
+ int /*channel_len*/,
+ int /*slot*/,
+ void * /*r_data*/)
+{
+}
+
+void VKFrameBuffer::blit_to(eGPUFrameBufferBits /*planes*/,
+ int /*src_slot*/,
+ FrameBuffer * /*dst*/,
+ int /*dst_slot*/,
+ int /*dst_offset_x*/,
+ int /*dst_offset_y*/)
+{
+}
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_framebuffer.hh b/source/blender/gpu/vulkan/vk_framebuffer.hh
new file mode 100644
index 00000000000..632d45ce709
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_framebuffer.hh
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#pragma once
+
+#include "gpu_framebuffer_private.hh"
+
+namespace blender::gpu {
+
+class VKFrameBuffer : public FrameBuffer {
+ public:
+ VKFrameBuffer(const char *name) : FrameBuffer(name)
+ {
+ }
+
+ void bind(bool enabled_srgb) override;
+ bool check(char err_out[256]) override;
+ void clear(eGPUFrameBufferBits buffers,
+ const float clear_col[4],
+ float clear_depth,
+ uint clear_stencil) override;
+ void clear_multi(const float (*clear_col)[4]) override;
+ void clear_attachment(GPUAttachmentType type,
+ eGPUDataFormat data_format,
+ const void *clear_value) override;
+
+ void attachment_set_loadstore_op(GPUAttachmentType type,
+ eGPULoadOp load_action,
+ eGPUStoreOp store_action) override;
+
+ void read(eGPUFrameBufferBits planes,
+ eGPUDataFormat format,
+ const int area[4],
+ int channel_len,
+ int slot,
+ void *r_data) override;
+
+ void blit_to(eGPUFrameBufferBits planes,
+ int src_slot,
+ FrameBuffer *dst,
+ int dst_slot,
+ int dst_offset_x,
+ int dst_offset_y) override;
+};
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_index_buffer.cc b/source/blender/gpu/vulkan/vk_index_buffer.cc
new file mode 100644
index 00000000000..119a617a159
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_index_buffer.cc
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "vk_index_buffer.hh"
+
+namespace blender::gpu {
+
+void VKIndexBuffer::upload_data()
+{
+}
+
+void VKIndexBuffer::bind_as_ssbo(uint /*binding*/)
+{
+}
+
+const uint32_t *VKIndexBuffer::read() const
+{
+ return 0;
+}
+
+void VKIndexBuffer::update_sub(uint /*start*/, uint /*len*/, const void * /*data*/)
+{
+}
+
+void VKIndexBuffer::strip_restart_indices()
+{
+}
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_index_buffer.hh b/source/blender/gpu/vulkan/vk_index_buffer.hh
new file mode 100644
index 00000000000..f002d5581c7
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_index_buffer.hh
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#pragma once
+
+#include "gpu_index_buffer_private.hh"
+
+namespace blender::gpu {
+
+class VKIndexBuffer : public IndexBuf {
+ public:
+ void upload_data() override;
+
+ void bind_as_ssbo(uint binding) override;
+
+ const uint32_t *read() const override;
+
+ void update_sub(uint start, uint len, const void *data) override;
+
+ private:
+ void strip_restart_indices() override;
+};
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_query.cc b/source/blender/gpu/vulkan/vk_query.cc
new file mode 100644
index 00000000000..e24fe54e5d0
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_query.cc
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "vk_query.hh"
+
+namespace blender::gpu {
+
+void VKQueryPool::init(GPUQueryType /*type*/)
+{
+}
+
+void VKQueryPool::begin_query()
+{
+}
+
+void VKQueryPool::end_query()
+{
+}
+
+void VKQueryPool::get_occlusion_result(MutableSpan<uint32_t> /*r_values*/)
+{
+}
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_query.hh b/source/blender/gpu/vulkan/vk_query.hh
new file mode 100644
index 00000000000..36558ef9549
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_query.hh
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#pragma once
+
+#include "gpu_query.hh"
+
+namespace blender::gpu {
+
+class VKQueryPool : public QueryPool {
+ public:
+ void init(GPUQueryType type) override;
+ void begin_query() override;
+ void end_query() override;
+ void get_occlusion_result(MutableSpan<uint32_t> r_values) override;
+};
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_shader.cc b/source/blender/gpu/vulkan/vk_shader.cc
new file mode 100644
index 00000000000..d628f3eb851
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_shader.cc
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "vk_shader.hh"
+
+namespace blender::gpu {
+void VKShader::vertex_shader_from_glsl(MutableSpan<const char *> /*sources*/)
+{
+}
+
+void VKShader::geometry_shader_from_glsl(MutableSpan<const char *> /*sources*/)
+{
+}
+
+void VKShader::fragment_shader_from_glsl(MutableSpan<const char *> /*sources*/)
+{
+}
+
+void VKShader::compute_shader_from_glsl(MutableSpan<const char *> /*sources*/)
+{
+}
+
+bool VKShader::finalize(const shader::ShaderCreateInfo * /*info*/)
+{
+ return false;
+}
+
+void VKShader::transform_feedback_names_set(Span<const char *> /*name_list*/,
+ eGPUShaderTFBType /*geom_type*/)
+{
+}
+
+bool VKShader::transform_feedback_enable(GPUVertBuf *)
+{
+ return false;
+}
+
+void VKShader::transform_feedback_disable()
+{
+}
+
+void VKShader::bind()
+{
+}
+
+void VKShader::unbind()
+{
+}
+
+void VKShader::uniform_float(int /*location*/,
+ int /*comp_len*/,
+ int /*array_size*/,
+ const float * /*data*/)
+{
+}
+void VKShader::uniform_int(int /*location*/,
+ int /*comp_len*/,
+ int /*array_size*/,
+ const int * /*data*/)
+{
+}
+
+std::string VKShader::resources_declare(const shader::ShaderCreateInfo & /*info*/) const
+{
+ return std::string();
+}
+
+std::string VKShader::vertex_interface_declare(const shader::ShaderCreateInfo & /*info*/) const
+{
+ return std::string();
+}
+
+std::string VKShader::fragment_interface_declare(const shader::ShaderCreateInfo & /*info*/) const
+{
+ return std::string();
+}
+
+std::string VKShader::geometry_interface_declare(const shader::ShaderCreateInfo & /*info*/) const
+{
+ return std::string();
+}
+
+std::string VKShader::geometry_layout_declare(const shader::ShaderCreateInfo & /*info*/) const
+{
+ return std::string();
+}
+
+std::string VKShader::compute_layout_declare(const shader::ShaderCreateInfo & /*info*/) const
+{
+ return std::string();
+}
+
+int VKShader::program_handle_get() const
+{
+ return -1;
+}
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_shader.hh b/source/blender/gpu/vulkan/vk_shader.hh
new file mode 100644
index 00000000000..9ab0aca67eb
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_shader.hh
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#pragma once
+
+#include "gpu_shader_private.hh"
+
+namespace blender::gpu {
+
+class VKShader : public Shader {
+ public:
+ VKShader(const char *name) : Shader(name)
+ {
+ }
+
+ void vertex_shader_from_glsl(MutableSpan<const char *> sources) override;
+ void geometry_shader_from_glsl(MutableSpan<const char *> sources) override;
+ void fragment_shader_from_glsl(MutableSpan<const char *> sources) override;
+ void compute_shader_from_glsl(MutableSpan<const char *> sources) override;
+ bool finalize(const shader::ShaderCreateInfo *info = nullptr) override;
+
+ void transform_feedback_names_set(Span<const char *> name_list,
+ eGPUShaderTFBType geom_type) override;
+ bool transform_feedback_enable(GPUVertBuf *) override;
+ void transform_feedback_disable() override;
+
+ void bind() override;
+ void unbind() override;
+
+ void uniform_float(int location, int comp_len, int array_size, const float *data) override;
+ void uniform_int(int location, int comp_len, int array_size, const int *data) override;
+
+ std::string resources_declare(const shader::ShaderCreateInfo &info) const override;
+ std::string vertex_interface_declare(const shader::ShaderCreateInfo &info) const override;
+ std::string fragment_interface_declare(const shader::ShaderCreateInfo &info) const override;
+ std::string geometry_interface_declare(const shader::ShaderCreateInfo &info) const override;
+ std::string geometry_layout_declare(const shader::ShaderCreateInfo &info) const override;
+ std::string compute_layout_declare(const shader::ShaderCreateInfo &info) const override;
+
+ /* DEPRECATED: Kept only because of BGL API. */
+ int program_handle_get() const override;
+};
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_storage_buffer.cc b/source/blender/gpu/vulkan/vk_storage_buffer.cc
new file mode 100644
index 00000000000..2b6fda0547d
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_storage_buffer.cc
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "vk_vertex_buffer.hh"
+
+#include "vk_storage_buffer.hh"
+
+namespace blender::gpu {
+
+void VKStorageBuffer::update(const void * /*data*/)
+{
+}
+
+void VKStorageBuffer::bind(int /*slot*/)
+{
+}
+
+void VKStorageBuffer::unbind()
+{
+}
+
+void VKStorageBuffer::clear(eGPUTextureFormat /* internal_format*/,
+ eGPUDataFormat /*data_format*/,
+ void * /*data*/)
+{
+}
+void VKStorageBuffer::copy_sub(VertBuf * /*src*/,
+ uint /*dst_offset*/,
+ uint /*src_offset*/,
+ uint /*copy_size*/)
+{
+}
+
+void VKStorageBuffer::read(void * /*data*/)
+{
+}
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_storage_buffer.hh b/source/blender/gpu/vulkan/vk_storage_buffer.hh
new file mode 100644
index 00000000000..a51f89f627a
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_storage_buffer.hh
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#pragma once
+
+#include "GPU_texture.h"
+
+#include "gpu_storage_buffer_private.hh"
+
+namespace blender::gpu {
+
+class VKStorageBuffer : public StorageBuf {
+ public:
+ VKStorageBuffer(int size, const char *name) : StorageBuf(size, name)
+ {
+ }
+
+ void update(const void *data) override;
+ void bind(int slot) override;
+ void unbind() override;
+ void clear(eGPUTextureFormat internal_format, eGPUDataFormat data_format, void *data) override;
+ void copy_sub(VertBuf *src, uint dst_offset, uint src_offset, uint copy_size) override;
+ void read(void *data) override;
+};
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_texture.cc b/source/blender/gpu/vulkan/vk_texture.cc
new file mode 100644
index 00000000000..ea5379e6572
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_texture.cc
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "vk_texture.hh"
+
+namespace blender::gpu {
+
+void VKTexture::generate_mipmap()
+{
+}
+
+void VKTexture::copy_to(Texture * /*tex*/)
+{
+}
+
+void VKTexture::clear(eGPUDataFormat /*format*/, const void * /*data*/)
+{
+}
+
+void VKTexture::swizzle_set(const char /*swizzle_mask*/[4])
+{
+}
+
+void VKTexture::stencil_texture_mode_set(bool /*use_stencil*/)
+{
+}
+
+void VKTexture::mip_range_set(int /*min*/, int /*max*/)
+{
+}
+
+void *VKTexture::read(int /*mip*/, eGPUDataFormat /*format*/)
+{
+ return nullptr;
+}
+
+void VKTexture::update_sub(int /*mip*/,
+ int /*offset*/[3],
+ int /*extent*/[3],
+ eGPUDataFormat /*format*/,
+ const void * /*data*/)
+{
+}
+
+/* TODO(fclem): Legacy. Should be removed at some point. */
+uint VKTexture::gl_bindcode_get() const
+{
+ return 0;
+}
+
+bool VKTexture::init_internal()
+{
+ return false;
+}
+
+bool VKTexture::init_internal(GPUVertBuf * /*vbo*/)
+{
+ return false;
+}
+
+bool VKTexture::init_internal(const GPUTexture * /*src*/, int /*mip_offset*/, int /*layer_offset*/)
+{
+ return false;
+}
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_texture.hh b/source/blender/gpu/vulkan/vk_texture.hh
new file mode 100644
index 00000000000..93094b7e540
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_texture.hh
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#pragma once
+
+#include "gpu_texture_private.hh"
+
+namespace blender::gpu {
+
+class VKTexture : public Texture {
+ public:
+ VKTexture(const char *name) : Texture(name)
+ {
+ }
+
+ void generate_mipmap() override;
+ void copy_to(Texture *tex) override;
+ void clear(eGPUDataFormat format, const void *data) override;
+ void swizzle_set(const char swizzle_mask[4]) override;
+ void stencil_texture_mode_set(bool use_stencil) override;
+ void mip_range_set(int min, int max) override;
+ void *read(int mip, eGPUDataFormat format) override;
+ void update_sub(
+ int mip, int offset[3], int extent[3], eGPUDataFormat format, const void *data) override;
+
+ /* TODO(fclem): Legacy. Should be removed at some point. */
+ uint gl_bindcode_get() const override;
+
+ protected:
+ bool init_internal() override;
+ bool init_internal(GPUVertBuf *vbo) override;
+ bool init_internal(const GPUTexture *src, int mip_offset, int layer_offset) override;
+};
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_uniform_buffer.cc b/source/blender/gpu/vulkan/vk_uniform_buffer.cc
new file mode 100644
index 00000000000..8ef5b19273a
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_uniform_buffer.cc
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "vk_uniform_buffer.hh"
+
+namespace blender::gpu {
+
+void VKUniformBuffer::update(const void * /*data*/)
+{
+}
+
+void VKUniformBuffer::bind(int /*slot*/)
+{
+}
+
+void VKUniformBuffer::unbind()
+{
+}
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_uniform_buffer.hh b/source/blender/gpu/vulkan/vk_uniform_buffer.hh
new file mode 100644
index 00000000000..f086a7aa391
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_uniform_buffer.hh
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#pragma once
+
+#include "gpu_uniform_buffer_private.hh"
+
+namespace blender::gpu {
+
+class VKUniformBuffer : public UniformBuf {
+ public:
+ VKUniformBuffer(int size, const char *name) : UniformBuf(size, name)
+ {
+ }
+
+ void update(const void *data) override;
+ void bind(int slot) override;
+ void unbind() override;
+};
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_vertex_buffer.cc b/source/blender/gpu/vulkan/vk_vertex_buffer.cc
new file mode 100644
index 00000000000..5791e20fb30
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_vertex_buffer.cc
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "vk_vertex_buffer.hh"
+
+namespace blender::gpu {
+
+void VKVertexBuffer::bind_as_ssbo(uint /*binding*/)
+{
+}
+
+void VKVertexBuffer::bind_as_texture(uint /*binding*/)
+{
+}
+
+void VKVertexBuffer::wrap_handle(uint64_t /*handle*/)
+{
+}
+
+void VKVertexBuffer::update_sub(uint /*start*/, uint /*len*/, const void * /*data*/)
+{
+}
+
+const void *VKVertexBuffer::read() const
+{
+ return nullptr;
+}
+
+void *VKVertexBuffer::unmap(const void * /*mapped_data*/) const
+{
+ return nullptr;
+}
+
+void VKVertexBuffer::acquire_data()
+{
+}
+
+void VKVertexBuffer::resize_data()
+{
+}
+
+void VKVertexBuffer::release_data()
+{
+}
+
+void VKVertexBuffer::upload_data()
+{
+}
+
+void VKVertexBuffer::duplicate_data(VertBuf * /*dst*/)
+{
+}
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/vulkan/vk_vertex_buffer.hh b/source/blender/gpu/vulkan/vk_vertex_buffer.hh
new file mode 100644
index 00000000000..84ccc65bcdf
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_vertex_buffer.hh
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#pragma once
+
+#include "gpu_vertex_buffer_private.hh"
+
+namespace blender::gpu {
+
+class VKVertexBuffer : public VertBuf {
+ public:
+ void bind_as_ssbo(uint binding) override;
+ void bind_as_texture(uint binding) override;
+ void wrap_handle(uint64_t handle) override;
+
+ void update_sub(uint start, uint len, const void *data) override;
+ const void *read() const override;
+ void *unmap(const void *mapped_data) const override;
+
+ protected:
+ void acquire_data() override;
+ void resize_data() override;
+ void release_data() override;
+ void upload_data() override;
+ void duplicate_data(VertBuf *dst) override;
+};
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c
index 6d99fde9df6..c467e48d21e 100644
--- a/source/blender/ikplugin/intern/iksolver_plugin.c
+++ b/source/blender/ikplugin/intern/iksolver_plugin.c
@@ -406,7 +406,7 @@ static void execute_posetree(struct Depsgraph *depsgraph,
}
copy_v3_v3(rootmat[3], pchan->pose_head);
- mul_m4_m4m4(imat, ob->obmat, rootmat);
+ mul_m4_m4m4(imat, ob->object_to_world, rootmat);
invert_m4_m4(goalinv, imat);
for (target = tree->targets.first; target; target = target->next) {
@@ -465,7 +465,7 @@ static void execute_posetree(struct Depsgraph *depsgraph,
/* end effector in world space */
copy_m4_m4(end_pose, pchan->pose_mat);
copy_v3_v3(end_pose[3], pchan->pose_tail);
- mul_m4_series(world_pose, goalinv, ob->obmat, end_pose);
+ mul_m4_series(world_pose, goalinv, ob->object_to_world, end_pose);
/* blend position */
goalpos[0] = fac * goalpos[0] + mfac * world_pose[3][0];
diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp
index b9f7dd98073..2878bbb6da7 100644
--- a/source/blender/ikplugin/intern/itasc_plugin.cpp
+++ b/source/blender/ikplugin/intern/itasc_plugin.cpp
@@ -60,7 +60,7 @@ using Vector3 = float[3];
using Vector4 = float[4];
struct IK_Target;
using ErrorCallback = void (*)(const iTaSC::ConstraintValues *values,
- unsigned int nvalues,
+ uint nvalues,
IK_Target *iktarget);
/* one structure for each target in the scene */
@@ -75,7 +75,7 @@ struct IK_Target {
ErrorCallback errorCallback;
std::string targetName;
std::string constraintName;
- unsigned short controlType;
+ ushort controlType;
short channel; /* index in IK channel array of channel on which this target is defined */
short ee; /* end effector number */
bool simulation; /* true when simulation mode is used (update feedback) */
@@ -586,10 +586,10 @@ static bool target_callback(const iTaSC::Timestamp &timestamp,
float chanmat[4][4];
copy_m4_m4(chanmat, pchan->pose_mat);
copy_v3_v3(chanmat[3], pchan->pose_tail);
- mul_m4_series(restmat, target->owner->obmat, chanmat, target->eeRest);
+ mul_m4_series(restmat, target->owner->object_to_world, chanmat, target->eeRest);
}
else {
- mul_m4_m4m4(restmat, target->owner->obmat, target->eeRest);
+ mul_m4_m4m4(restmat, target->owner->object_to_world, target->eeRest);
}
/* blend the target */
blend_m4_m4m4(tarmat, restmat, tarmat, constraint->enforce);
@@ -620,10 +620,10 @@ static bool base_callback(const iTaSC::Timestamp &timestamp,
ikscene->baseFrame.setValue(&chanmat[0][0]);
/* iTaSC armature is scaled to object scale, scale the base frame too */
ikscene->baseFrame.p *= ikscene->blScale;
- mul_m4_m4m4(rootmat, ikscene->blArmature->obmat, chanmat);
+ mul_m4_m4m4(rootmat, ikscene->blArmature->object_to_world, chanmat);
}
else {
- copy_m4_m4(rootmat, ikscene->blArmature->obmat);
+ copy_m4_m4(rootmat, ikscene->blArmature->object_to_world);
ikscene->baseFrame = iTaSC::F_identity;
}
next.setValue(&rootmat[0][0]);
@@ -704,7 +704,7 @@ static bool base_callback(const iTaSC::Timestamp &timestamp,
static bool copypose_callback(const iTaSC::Timestamp &timestamp,
iTaSC::ConstraintValues *const _values,
- unsigned int _nvalues,
+ uint _nvalues,
void *_param)
{
IK_Target *iktarget = (IK_Target *)_param;
@@ -749,7 +749,7 @@ static bool copypose_callback(const iTaSC::Timestamp &timestamp,
}
static void copypose_error(const iTaSC::ConstraintValues *values,
- unsigned int nvalues,
+ uint nvalues,
IK_Target *iktarget)
{
iTaSC::ConstraintSingleValue *value;
@@ -761,7 +761,7 @@ static void copypose_error(const iTaSC::ConstraintValues *values,
for (i = 0, error = 0.0, value = values->values; i < values->number; i++, value++) {
error += KDL::sqr(value->y - value->yd);
}
- iktarget->blenderConstraint->lin_error = (float)KDL::sqrt(error);
+ iktarget->blenderConstraint->lin_error = float(KDL::sqrt(error));
values++;
}
if (iktarget->controlType & iTaSC::CopyPose::CTL_ROTATION) {
@@ -769,14 +769,14 @@ static void copypose_error(const iTaSC::ConstraintValues *values,
for (i = 0, error = 0.0, value = values->values; i < values->number; i++, value++) {
error += KDL::sqr(value->y - value->yd);
}
- iktarget->blenderConstraint->rot_error = (float)KDL::sqrt(error);
+ iktarget->blenderConstraint->rot_error = float(KDL::sqrt(error));
values++;
}
}
static bool distance_callback(const iTaSC::Timestamp &timestamp,
iTaSC::ConstraintValues *const _values,
- unsigned int _nvalues,
+ uint _nvalues,
void *_param)
{
IK_Target *iktarget = (IK_Target *)_param;
@@ -826,15 +826,15 @@ static bool distance_callback(const iTaSC::Timestamp &timestamp,
}
static void distance_error(const iTaSC::ConstraintValues *values,
- unsigned int _nvalues,
+ uint _nvalues,
IK_Target *iktarget)
{
- iktarget->blenderConstraint->lin_error = (float)(values->values[0].y - values->values[0].yd);
+ iktarget->blenderConstraint->lin_error = float(values->values[0].y - values->values[0].yd);
}
static bool joint_callback(const iTaSC::Timestamp &timestamp,
iTaSC::ConstraintValues *const _values,
- unsigned int _nvalues,
+ uint _nvalues,
void *_param)
{
IK_Channel *ikchan = (IK_Channel *)_param;
@@ -909,7 +909,7 @@ static bool joint_callback(const iTaSC::Timestamp &timestamp,
break;
}
if (dof >= 0) {
- for (unsigned int i = 0; i < _nvalues; i++, dof++) {
+ for (uint i = 0; i < _nvalues; i++, dof++) {
_values[i].values[0].yd = ikchan->jointValue[dof];
_values[i].alpha = chan->ikrotweight;
_values[i].feedback = ikparam->feedback;
@@ -1065,7 +1065,7 @@ static void convert_pose(IK_Scene *ikscene)
int a, joint;
/* assume uniform scaling and take Y scale as general scale for the armature */
- scale = len_v3(ikscene->blArmature->obmat[1]);
+ scale = len_v3(ikscene->blArmature->object_to_world[1]);
rot = ikscene->jointArray(0);
for (joint = a = 0, ikchan = ikscene->channels;
a < ikscene->numchan && joint < ikscene->numjoint;
@@ -1105,7 +1105,7 @@ static void BKE_pose_rest(IK_Scene *ikscene)
int a, joint;
/* assume uniform scaling and take Y scale as general scale for the armature */
- scale = len_v3(ikscene->blArmature->obmat[1]);
+ scale = len_v3(ikscene->blArmature->object_to_world[1]);
/* rest pose is 0 */
SetToZero(ikscene->jointArray);
/* except for transY joints */
@@ -1139,7 +1139,7 @@ static IK_Scene *convert_tree(
KDL::Frame initPose;
Bone *bone;
int a, numtarget;
- unsigned int t;
+ uint t;
float length;
bool ret = true;
double *rot;
@@ -1183,7 +1183,7 @@ static IK_Scene *convert_tree(
}
ikscene->blArmature = ob;
/* assume uniform scaling and take Y scale as general scale for the armature */
- ikscene->blScale = len_v3(ob->obmat[1]);
+ ikscene->blScale = len_v3(ob->object_to_world[1]);
ikscene->blInvScale = (ikscene->blScale < KDL::epsilon) ? 0.0f : 1.0f / ikscene->blScale;
std::string joint;
@@ -1483,7 +1483,7 @@ static IK_Scene *convert_tree(
}
/* set the weight */
e_matrix &Wq = arm->getWq();
- assert(Wq.cols() == (int)weights.size());
+ assert(Wq.cols() == int(weights.size()));
for (int q = 0; q < Wq.cols(); q++) {
Wq(q, q) = weights[q];
}
@@ -1512,7 +1512,7 @@ static IK_Scene *convert_tree(
iktarget->bldepsgraph = depsgraph;
condata = (bKinematicConstraint *)iktarget->blenderConstraint->data;
pchan = tree->pchan[iktarget->channel];
- unsigned int controltype, bone_count;
+ uint controltype, bone_count;
double bone_length;
float mat[4][4];
@@ -1667,7 +1667,7 @@ static void create_scene(struct Depsgraph *depsgraph, Scene *scene, Object *ob,
static int init_scene(Object *ob)
{
/* check also if scaling has changed */
- float scale = len_v3(ob->obmat[1]);
+ float scale = len_v3(ob->object_to_world[1]);
IK_Scene *scene;
if (ob->pose->ikdata) {
@@ -1783,7 +1783,7 @@ static void execute_scene(struct Depsgraph *depsgraph,
for (i = ikscene->targets.size(); i > 0; i--) {
IK_Target *iktarget = ikscene->targets[i - 1];
if (!(iktarget->blenderConstraint->flag & CONSTRAINT_OFF) && iktarget->constraint) {
- unsigned int nvalues;
+ uint nvalues;
const iTaSC::ConstraintValues *values;
values = iktarget->constraint->getControlParameters(&nvalues);
iktarget->errorCallback(values, nvalues, iktarget);
@@ -1826,9 +1826,9 @@ static void execute_scene(struct Depsgraph *depsgraph,
}
if (joint->getType() == KDL::Joint::TransY) {
/* stretch bones have a TY joint, compute the scale */
- scale = (float)(q[0] / q_rest[0]);
+ scale = float(q[0] / q_rest[0]);
/* the length is the joint itself */
- length = (float)q[0];
+ length = float(q[0]);
}
else {
scale = 1.0f;
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 7e652e31506..a05bc51fcea 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -358,14 +358,14 @@ struct IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim,
* Will rebuild all used indices and proxies at once.
*/
void IMB_anim_index_rebuild(struct IndexBuildContext *context,
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress);
/**
* Finish rebuilding proxies/time-codes and free temporary contexts used.
*/
-void IMB_anim_index_rebuild_finish(struct IndexBuildContext *context, short stop);
+void IMB_anim_index_rebuild_finish(struct IndexBuildContext *context, bool stop);
/**
* Return the length (in frames) of the given \a anim.
@@ -895,6 +895,13 @@ eGPUTextureFormat IMB_gpu_get_texture_format(const struct ImBuf *ibuf,
bool use_grayscale);
/**
+ * Ensures that values stored in the float rect can safely loaded into half float gpu textures.
+ *
+ * Does nothing when given image_buffer doesn't contain a float rect.
+ */
+void IMB_gpu_clamp_half_float(struct ImBuf *image_buffer);
+
+/**
* The `ibuf` is only here to detect the storage type. The produced texture will have undefined
* content. It will need to be populated by using #IMB_update_gpu_texture_sub().
*/
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index 03bb11d0cf6..81e9420c8ba 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -125,7 +125,7 @@ enum eImbFileType {
typedef struct ImbFormatOptions {
short flag;
- /** quality serves dual purpose as quality number for jpeg or compression amount for png */
+ /** Quality serves dual purpose as quality number for JPEG or compression amount for PNG. */
char quality;
} ImbFormatOptions;
diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h
index b55a6f653b8..ac287856fa9 100644
--- a/source/blender/imbuf/IMB_thumbs.h
+++ b/source/blender/imbuf/IMB_thumbs.h
@@ -87,8 +87,6 @@ struct ImBuf *IMB_thumb_load_blend(const char *blen_path,
*/
struct ImBuf *IMB_thumb_load_font(const char *filepath, unsigned int x, unsigned int y);
bool IMB_thumb_load_font_get_hash(char *r_hash);
-void IMB_thumb_clear_translations(void);
-void IMB_thumb_ensure_translations(void);
/* Threading */
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index 42b587c3c81..2860944e948 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -402,7 +402,7 @@ bool imb_addrectImBuf(ImBuf *ibuf)
ibuf->mall |= IB_rect;
ibuf->flags |= IB_rect;
if (ibuf->planes > 32) {
- return (addzbufImBuf(ibuf));
+ return addzbufImBuf(ibuf);
}
return true;
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index 4e6a52f8464..94c0555dcf0 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -131,7 +131,7 @@ static int an_stringdec(const char *string, char *head, char *tail, ushort *numl
strcpy(head, string);
head[nums] = '\0';
*numlen = nume - nums + 1;
- return ((int)atoi(&(string[nums])));
+ return (int)atoi(&(string[nums]));
}
tail[0] = '\0';
strcpy(head, string);
@@ -1093,12 +1093,19 @@ static int ffmpeg_seek_by_byte(AVFormatContext *pFormatCtx)
static int64_t ffmpeg_get_seek_pts(struct anim *anim, int64_t pts_to_search)
{
- /* Step back half a frame position to make sure that we get the requested
- * frame and not the one after it. This is a workaround as ffmpeg will
- * sometimes not seek to a frame after the requested pts even if
- * AVSEEK_FLAG_BACKWARD is specified.
+ /* FFmpeg seeks internally using DTS values instead of PTS. In some files DTS and PTS values are
+ * offset and sometimes ffmpeg fails to take this into account when seeking.
+ * Therefore we need to seek backwards a certain offset to make sure the frame we want is in
+ * front of us. It is not possible to determine the exact needed offset, this value is determined
+ * experimentally. Note: Too big offset can impact performance. Current 3 frame offset has no
+ * measurable impact.
*/
- return pts_to_search - (ffmpeg_steps_per_frame_get(anim) / 2);
+ int64_t seek_pts = pts_to_search - (ffmpeg_steps_per_frame_get(anim) * 3);
+
+ if (seek_pts < 0) {
+ seek_pts = 0;
+ }
+ return seek_pts;
}
/* This gives us an estimate of which pts our requested frame will have.
@@ -1406,6 +1413,10 @@ static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position, IMB_Timecode_Typ
ffmpeg_decode_video_frame_scan(anim, pts_to_search);
+ /* Update resolution as it can change per-frame with WebM. See T100741 & T100081. */
+ anim->x = anim->pCodecCtx->width;
+ anim->y = anim->pCodecCtx->height;
+
IMB_freeImBuf(anim->cur_frame_final);
/* Certain versions of FFmpeg have a bug in libswscale which ends up in crash
diff --git a/source/blender/imbuf/intern/bmp.c b/source/blender/imbuf/intern/bmp.c
index af9b62f1a74..495ec286de3 100644
--- a/source/blender/imbuf/intern/bmp.c
+++ b/source/blender/imbuf/intern/bmp.c
@@ -135,7 +135,7 @@ ImBuf *imb_bmp_decode(const uchar *mem, size_t size, int flags, char colorspace[
}
/* Validate and cross-check offsets and sizes. */
- if (x < 1 || !(ELEM(depth, 1, 4, 8, 16, 24, 32))) {
+ if (x < 1 || !ELEM(depth, 1, 4, 8, 16, 24, 32)) {
return NULL;
}
diff --git a/source/blender/imbuf/intern/cache.c b/source/blender/imbuf/intern/cache.c
index 4e1563c62ab..98d33ac061f 100644
--- a/source/blender/imbuf/intern/cache.c
+++ b/source/blender/imbuf/intern/cache.c
@@ -167,7 +167,7 @@ void imb_tile_cache_tile_free(ImBuf *ibuf, int tx, int ty)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Init/Exit
+/** \name Initialize/Exit
* \{ */
static void imb_thread_cache_init(ImThreadTileCache *cache)
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c
index 494bf37cfe7..be8fab26301 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.c
+++ b/source/blender/imbuf/intern/cineon/dpxlib.c
@@ -4,7 +4,7 @@
/** \file
* \ingroup imbcineon
*
- * Dpx image file format library routines.
+ * DPX image file format library routines.
*/
#include "dpxlib.h"
diff --git a/source/blender/imbuf/intern/cineon/logImageCore.c b/source/blender/imbuf/intern/cineon/logImageCore.c
index 8188d0d04b9..9ec48447884 100644
--- a/source/blender/imbuf/intern/cineon/logImageCore.c
+++ b/source/blender/imbuf/intern/cineon/logImageCore.c
@@ -365,7 +365,7 @@ static int logImageSetData12(LogImageFile *logImage, LogImageElement logElement,
for (size_t y = 0; y < logImage->height; y++) {
for (size_t x = 0; x < logImage->width * logImage->depth; x++) {
row[x] = swap_ushort(
- ((ushort)float_uint(data[y * logImage->width * logImage->depth + x], 4095)) << 4,
+ (ushort)float_uint(data[y * logImage->width * logImage->depth + x], 4095) << 4,
logImage->isMSB);
}
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index ea5f4ec275d..0678c224e6b 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -31,6 +31,7 @@
#include "BLI_math_color.h"
#include "BLI_rect.h"
#include "BLI_string.h"
+#include "BLI_task.h"
#include "BLI_threads.h"
#include "BKE_appdir.h"
@@ -668,7 +669,7 @@ void colormanagement_init(void)
configdir = BKE_appdir_folder_id(BLENDER_DATAFILES, "colormanagement");
if (configdir) {
- BLI_join_dirfile(configfile, sizeof(configfile), configdir, BCM_CONFIG_FILE);
+ BLI_path_join(configfile, sizeof(configfile), configdir, BCM_CONFIG_FILE);
#ifdef WIN32
{
@@ -2249,6 +2250,43 @@ void IMB_colormanagement_imbuf_to_byte_texture(uchar *out_buffer,
}
}
+typedef struct ImbufByteToFloatData {
+ OCIO_ConstCPUProcessorRcPtr *processor;
+ int width;
+ int offset, stride;
+ const uchar *in_buffer;
+ float *out_buffer;
+ bool use_premultiply;
+} ImbufByteToFloatData;
+
+static void imbuf_byte_to_float_cb(void *__restrict userdata,
+ const int y,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ ImbufByteToFloatData *data = userdata;
+
+ const size_t in_offset = data->offset + y * data->stride;
+ const size_t out_offset = y * data->width;
+ const uchar *in = data->in_buffer + in_offset * 4;
+ float *out = data->out_buffer + out_offset * 4;
+
+ /* Convert to scene linear, to sRGB and premultiply. */
+ for (int x = 0; x < data->width; x++, in += 4, out += 4) {
+ float pixel[4];
+ rgba_uchar_to_float(pixel, in);
+ if (data->processor) {
+ OCIO_cpuProcessorApplyRGB(data->processor, pixel);
+ }
+ else {
+ srgb_to_linearrgb_v3_v3(pixel, pixel);
+ }
+ if (data->use_premultiply) {
+ mul_v3_fl(pixel, pixel[3]);
+ }
+ copy_v4_v4(out, pixel);
+ }
+}
+
void IMB_colormanagement_imbuf_to_float_texture(float *out_buffer,
const int offset_x,
const int offset_y,
@@ -2307,34 +2345,25 @@ void IMB_colormanagement_imbuf_to_float_texture(float *out_buffer,
const uchar *in_buffer = (uchar *)ibuf->rect;
const bool use_premultiply = IMB_alpha_affects_rgb(ibuf) && store_premultiplied;
- /* TODO(brecht): make this multi-threaded, or at least process in batches. */
OCIO_ConstCPUProcessorRcPtr *processor = (ibuf->rect_colorspace) ?
colorspace_to_scene_linear_cpu_processor(
ibuf->rect_colorspace) :
NULL;
- for (int y = 0; y < height; y++) {
- const size_t in_offset = (offset_y + y) * ibuf->x + offset_x;
- const size_t out_offset = y * width;
- const uchar *in = in_buffer + in_offset * 4;
- float *out = out_buffer + out_offset * 4;
-
- /* Convert to scene linear, to sRGB and premultiply. */
- for (int x = 0; x < width; x++, in += 4, out += 4) {
- float pixel[4];
- rgba_uchar_to_float(pixel, in);
- if (processor) {
- OCIO_cpuProcessorApplyRGB(processor, pixel);
- }
- else {
- srgb_to_linearrgb_v3_v3(pixel, pixel);
- }
- if (use_premultiply) {
- mul_v3_fl(pixel, pixel[3]);
- }
- copy_v4_v4(out, pixel);
- }
- }
+ ImbufByteToFloatData data = {
+ .processor = processor,
+ .width = width,
+ .offset = offset_y * ibuf->x + offset_x,
+ .stride = ibuf->x,
+ .in_buffer = in_buffer,
+ .out_buffer = out_buffer,
+ .use_premultiply = use_premultiply,
+ };
+
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.use_threading = (height > 128);
+ BLI_task_parallel_range(0, height, &data, imbuf_byte_to_float_cb, &settings);
}
}
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h
index 144babf5d92..679028b16d3 100644
--- a/source/blender/imbuf/intern/dds/ColorBlock.h
+++ b/source/blender/imbuf/intern/dds/ColorBlock.h
@@ -21,9 +21,9 @@
/** Uncompressed 4x4 color block. */
struct ColorBlock {
ColorBlock() = default;
- /** Init the color block from an array of colors. */
+ /** Initialize the color block from an array of colors. */
ColorBlock(const uint *linearImage);
- /** Init the color block with the contents of the given block. */
+ /** Initialize the color block with the contents of the given block. */
ColorBlock(const ColorBlock &block);
/** Initialize this color block. */
ColorBlock(const Image *img, uint x, uint y);
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
index 4e5dc9ce560..272014ea5eb 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
@@ -872,8 +872,8 @@ DirectDrawSurface::DirectDrawSurface(uchar *mem, uint size) : stream(mem, size),
mem_read(stream, header);
/* Some ATI2 compressed normal maps do not have their
- * normal flag set, so force it here (the original nvtt don't do
- * this, but the decompressor has a -forcenormal flag). */
+ * normal flag set, so force it here (the original `nvtt` don't do
+ * this, but the decompressor has a `-forcenormal` flag). */
if (header.pf.fourcc == FOURCC_ATI2) {
header.setNormalFlag(true);
}
@@ -942,7 +942,7 @@ bool DirectDrawSurface::isSupported() const
if (isTextureCube() &&
(header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) != DDSCAPS2_CUBEMAP_ALL_FACES) {
- /* Cubemaps must contain all faces. */
+ /* Cube-maps must contain all faces. */
return false;
}
@@ -1464,19 +1464,19 @@ 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",
- (int)((header.pf.fourcc >> 0) & 0xFF),
- (int)((header.pf.fourcc >> 8) & 0xFF),
- (int)((header.pf.fourcc >> 16) & 0xFF),
- (int)((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",
- (int)(header.pf.bitcount >> 0) & 0xFF,
- (int)(header.pf.bitcount >> 8) & 0xFF,
- (int)(header.pf.bitcount >> 16) & 0xFF,
- (int)(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/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index 4530959e5ac..f4775fa5fe8 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -219,7 +219,7 @@ void bilinear_interpolation(const ImBuf *in, ImBuf *out, float u, float v, int x
return;
}
- /* gcc warns these could be uninitialized, but its ok. */
+ /* GCC warns these could be uninitialized, but its ok. */
pixel_from_buffer(out, &outI, &outF, xout, yout);
bilinear_interpolation_color(in, outI, outF, u, v);
diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c
index 00396c01d99..d824b87f493 100644
--- a/source/blender/imbuf/intern/indexer.c
+++ b/source/blender/imbuf/intern/indexer.c
@@ -215,7 +215,7 @@ struct anim_index *IMB_indexer_open(const char *name)
return NULL;
}
- if (((ENDIAN_ORDER == B_ENDIAN) != (header[8] == 'V'))) {
+ if ((ENDIAN_ORDER == B_ENDIAN) != (header[8] == 'V')) {
for (i = 0; i < idx->num_entries; i++) {
BLI_endian_switch_int32(&idx->entries[i].frameno);
BLI_endian_switch_uint64(&idx->entries[i].seek_pos);
@@ -377,9 +377,9 @@ static void get_index_dir(struct anim *anim, char *index_dir, size_t index_dir_l
{
if (!anim->index_dir[0]) {
char filename[FILE_MAXFILE];
- BLI_split_dirfile(anim->name, index_dir, filename, index_dir_len, sizeof(filename));
- BLI_path_append(index_dir, index_dir_len, "BL_proxy");
- BLI_path_append(index_dir, index_dir_len, filename);
+ char dirname[FILE_MAXDIR];
+ BLI_split_dirfile(anim->name, dirname, filename, index_dir_len, sizeof(filename));
+ BLI_path_join(index_dir, index_dir_len, dirname, "BL_proxy", filename);
}
else {
BLI_strncpy(index_dir, anim->index_dir, index_dir_len);
@@ -426,7 +426,7 @@ static bool get_proxy_filepath(struct anim *anim,
return false;
}
- BLI_join_dirfile(filepath, FILE_MAXFILE + FILE_MAXDIR, index_dir, proxy_name);
+ BLI_path_join(filepath, FILE_MAXFILE + FILE_MAXDIR, index_dir, proxy_name);
return true;
}
@@ -457,7 +457,7 @@ static void get_tc_filename(struct anim *anim, IMB_Timecode_Type tc, char *filep
get_index_dir(anim, index_dir, sizeof(index_dir));
- BLI_join_dirfile(filepath, FILE_MAXFILE + FILE_MAXDIR, index_dir, index_name);
+ BLI_path_join(filepath, FILE_MAXFILE + FILE_MAXDIR, index_dir, index_name);
}
/* ----------------------------------------------------------------------
@@ -498,7 +498,9 @@ static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
rv->anim = anim;
get_proxy_filepath(rv->anim, rv->proxy_size, filepath, true);
- BLI_make_existing_file(filepath);
+ if (!BLI_make_existing_file(filepath)) {
+ return NULL;
+ }
rv->of = avformat_alloc_context();
rv->of->oformat = av_guess_format("avi", NULL, NULL);
@@ -905,6 +907,14 @@ static IndexBuildContext *index_ffmpeg_create_context(struct anim *anim,
}
}
+ if (context->proxy_ctx[0] == NULL && context->proxy_ctx[1] == NULL &&
+ context->proxy_ctx[2] == NULL && context->proxy_ctx[3] == NULL) {
+ avformat_close_input(&context->iFormatCtx);
+ avcodec_free_context(&context->iCodecCtx);
+ MEM_freeN(context);
+ return NULL; /* Nothing to transcode. */
+ }
+
for (i = 0; i < num_indexers; i++) {
if (tcs_in_use & tc_types[i]) {
char filepath[FILE_MAX];
@@ -921,7 +931,7 @@ static IndexBuildContext *index_ffmpeg_create_context(struct anim *anim,
return (IndexBuildContext *)context;
}
-static void index_rebuild_ffmpeg_finish(FFmpegIndexBuilderContext *context, int stop)
+static void index_rebuild_ffmpeg_finish(FFmpegIndexBuilderContext *context, const bool stop)
{
int i;
@@ -1002,8 +1012,8 @@ static void index_rebuild_ffmpeg_proc_decoded_frame(FFmpegIndexBuilderContext *c
}
static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context,
- const short *stop,
- short *do_update,
+ const bool *stop,
+ bool *do_update,
float *progress)
{
AVFrame *in_frame = av_frame_alloc();
@@ -1012,12 +1022,13 @@ static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context,
stream_size = avio_size(context->iFormatCtx->pb);
- context->frame_rate = av_q2d(context->iStream->r_frame_rate);
+ context->frame_rate = av_q2d(av_guess_frame_rate(context->iFormatCtx, context->iStream, NULL));
context->pts_time_base = av_q2d(context->iStream->time_base);
while (av_read_frame(context->iFormatCtx, next_packet) >= 0) {
- float next_progress =
- (float)((int)floor(((double)next_packet->pos) * 100 / ((double)stream_size) + 0.5)) / 100;
+ float next_progress = (float)(int)floor(
+ ((double)next_packet->pos) * 100 / ((double)stream_size) + 0.5) /
+ 100;
if (*progress != next_progress) {
*progress = next_progress;
@@ -1292,7 +1303,7 @@ static IndexBuildContext *index_fallback_create_context(struct anim *anim,
return (IndexBuildContext *)context;
}
-static void index_rebuild_fallback_finish(FallbackIndexBuilderContext *context, int stop)
+static void index_rebuild_fallback_finish(FallbackIndexBuilderContext *context, const bool stop)
{
struct anim *anim = context->anim;
char filepath[FILE_MAX];
@@ -1319,8 +1330,8 @@ static void index_rebuild_fallback_finish(FallbackIndexBuilderContext *context,
}
static void index_rebuild_fallback(FallbackIndexBuilderContext *context,
- const short *stop,
- short *do_update,
+ const bool *stop,
+ bool *do_update,
float *progress)
{
int count = IMB_anim_get_duration(context->anim, IMB_TC_NONE);
@@ -1459,9 +1470,9 @@ IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim,
void IMB_anim_index_rebuild(struct IndexBuildContext *context,
/* NOLINTNEXTLINE: readability-non-const-parameter. */
- short *stop,
+ bool *stop,
/* NOLINTNEXTLINE: readability-non-const-parameter. */
- short *do_update,
+ bool *do_update,
/* NOLINTNEXTLINE: readability-non-const-parameter. */
float *progress)
{
@@ -1483,7 +1494,7 @@ void IMB_anim_index_rebuild(struct IndexBuildContext *context,
UNUSED_VARS(stop, do_update, progress);
}
-void IMB_anim_index_rebuild_finish(IndexBuildContext *context, short stop)
+void IMB_anim_index_rebuild_finish(IndexBuildContext *context, const bool stop)
{
switch (context->anim_type) {
#ifdef WITH_FFMPEG
diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c
index a8150fd1648..29dfcc1b8f8 100644
--- a/source/blender/imbuf/intern/iris.c
+++ b/source/blender/imbuf/intern/iris.c
@@ -88,7 +88,7 @@ typedef struct MFileOffset {
#define DIRTY_FLAG_EOF (1 << 0)
#define DIRTY_FLAG_ENCODING (1 << 1)
-/* funcs */
+/* Functions. */
static void readheader(MFileOffset *inf, IMAGE *image);
static int writeheader(FILE *outf, IMAGE *image);
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
index f57d4382672..4320f870d64 100644
--- a/source/blender/imbuf/intern/jp2.c
+++ b/source/blender/imbuf/intern/jp2.c
@@ -125,7 +125,7 @@ struct BufInfo {
static void opj_read_from_buffer_free(void *UNUSED(p_user_data))
{
- /* nop */
+ /* NOP. */
}
static OPJ_SIZE_T opj_read_from_buffer(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data)
@@ -746,17 +746,17 @@ static void cinema_setup_encoder(opj_cparameters_t *parameters,
for (i = 0; i < parameters->tcp_numlayers; i++) {
temp_rate = 0;
if (img_fol->rates[i] == 0) {
- parameters->tcp_rates[0] = ((float)(image->numcomps * image->comps[0].w *
- image->comps[0].h * image->comps[0].prec)) /
+ parameters->tcp_rates[0] = (float)(image->numcomps * image->comps[0].w *
+ image->comps[0].h * image->comps[0].prec) /
(CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
}
else {
- temp_rate = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h *
- image->comps[0].prec)) /
+ temp_rate = (float)(image->numcomps * image->comps[0].w * image->comps[0].h *
+ image->comps[0].prec) /
(img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
if (temp_rate > CINEMA_24_CS) {
- parameters->tcp_rates[i] = ((float)(image->numcomps * image->comps[0].w *
- image->comps[0].h * image->comps[0].prec)) /
+ parameters->tcp_rates[i] = (float)(image->numcomps * image->comps[0].w *
+ image->comps[0].h * image->comps[0].prec) /
(CINEMA_24_CS * 8 * image->comps[0].dx *
image->comps[0].dy);
}
@@ -772,17 +772,17 @@ static void cinema_setup_encoder(opj_cparameters_t *parameters,
for (i = 0; i < parameters->tcp_numlayers; i++) {
temp_rate = 0;
if (img_fol->rates[i] == 0) {
- parameters->tcp_rates[0] = ((float)(image->numcomps * image->comps[0].w *
- image->comps[0].h * image->comps[0].prec)) /
+ parameters->tcp_rates[0] = (float)(image->numcomps * image->comps[0].w *
+ image->comps[0].h * image->comps[0].prec) /
(CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
}
else {
- temp_rate = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h *
- image->comps[0].prec)) /
+ temp_rate = (float)(image->numcomps * image->comps[0].w * image->comps[0].h *
+ image->comps[0].prec) /
(img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
if (temp_rate > CINEMA_48_CS) {
- parameters->tcp_rates[0] = ((float)(image->numcomps * image->comps[0].w *
- image->comps[0].h * image->comps[0].prec)) /
+ parameters->tcp_rates[0] = (float)(image->numcomps * image->comps[0].w *
+ image->comps[0].h * image->comps[0].prec) /
(CINEMA_48_CS * 8 * image->comps[0].dx *
image->comps[0].dy);
}
@@ -885,7 +885,10 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
memset(&cmptparm, 0, sizeof(opj_image_cmptparm_t[4]));
for (i = 0; i < numcomps; i++) {
cmptparm[i].prec = prec;
+ /* Deprecated in openjpeg 2.5. */
+#if (OPJ_VERSION_MAJOR < 2) || (OPJ_VERSION_MAJOR == 2 && OPJ_VERSION_MINOR < 5)
cmptparm[i].bpp = prec;
+#endif
cmptparm[i].sgnd = 0;
cmptparm[i].dx = subsampling_dx;
cmptparm[i].dy = subsampling_dy;
diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c
index e03765fea92..e2d49cad374 100644
--- a/source/blender/imbuf/intern/jpeg.c
+++ b/source/blender/imbuf/intern/jpeg.c
@@ -209,7 +209,7 @@ static void memory_source(j_decompress_ptr cinfo, const uchar *buffer, size_t si
*/
#define INPUT_2BYTES(cinfo, V, action) \
MAKESTMT(MAKE_BYTE_AVAIL(cinfo, action); bytes_in_buffer--; \
- V = ((uint)GETJOCTET(*next_input_byte++)) << 8; \
+ V = (uint)GETJOCTET(*next_input_byte++) << 8; \
MAKE_BYTE_AVAIL(cinfo, action); \
bytes_in_buffer--; \
V += GETJOCTET(*next_input_byte++);)
diff --git a/source/blender/imbuf/intern/oiio/openimageio_api.cpp b/source/blender/imbuf/intern/oiio/openimageio_api.cpp
index 5c7b7d9fae4..f8d00b5222f 100644
--- a/source/blender/imbuf/intern/oiio/openimageio_api.cpp
+++ b/source/blender/imbuf/intern/oiio/openimageio_api.cpp
@@ -193,7 +193,7 @@ struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspac
}
ImageSpec spec, config;
- config.attribute("oiio:UnassociatedAlpha", (int)1);
+ config.attribute("oiio:UnassociatedAlpha", int(1));
if (!in->open(filename, spec, config)) {
std::cerr << __func__ << ": ImageInput::open() failed:" << std::endl
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index b4ccdfab9a5..d2bdb5041c5 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -73,15 +73,6 @@
#include "MEM_guardedalloc.h"
-extern "C" {
-
-/* The following prevents a linking error in debug mode for MSVC using the libs in SVN. */
-#if defined(WITH_OPENEXR) && defined(_WIN32) && defined(DEBUG) && _MSC_VER < 1900
-_CRTIMP void __cdecl _invalid_parameter_noinfo(void)
-{
-}
-#endif
-}
#include "BLI_blenlib.h"
#include "BLI_fileops.h"
#include "BLI_math_color.h"
@@ -465,7 +456,7 @@ static void openexr_header_metadata(Header *header, struct ImBuf *ibuf)
static void openexr_header_metadata_callback(void *data,
const char *propname,
char *prop,
- int UNUSED(len))
+ int /*len*/)
{
Header *header = (Header *)data;
header->insert(propname, StringAttribute(prop));
@@ -552,10 +543,10 @@ static bool imb_save_openexr_half(ImBuf *ibuf, const char *name, const int flags
from = (uchar *)ibuf->rect + 4 * i * width;
for (int j = ibuf->x; j > 0; j--) {
- to->r = srgb_to_linearrgb((float)from[0] / 255.0f);
- to->g = srgb_to_linearrgb((float)from[1] / 255.0f);
- to->b = srgb_to_linearrgb((float)from[2] / 255.0f);
- to->a = channels >= 4 ? (float)from[3] / 255.0f : 1.0f;
+ to->r = srgb_to_linearrgb(float(from[0]) / 255.0f);
+ to->g = srgb_to_linearrgb(float(from[1]) / 255.0f);
+ to->b = srgb_to_linearrgb(float(from[2]) / 255.0f);
+ to->a = channels >= 4 ? float(from[3]) / 255.0f : 1.0f;
to++;
from += 4;
}
@@ -708,7 +699,8 @@ struct ExrHandle {
ListBase channels; /* flattened out, ExrChannel */
ListBase layers; /* hierarchical, pointing in end to ExrChannel */
- int num_half_channels; /* used during filr save, allows faster temporary buffers allocation */
+ /** Used during file save, allows faster temporary buffers allocation. */
+ int num_half_channels;
};
/* flattened out channel */
@@ -819,7 +811,7 @@ static void imb_exr_get_views(MultiPartInputFile &file, StringVector &views)
}
}
-/* Multilayer Blender files have the view name in all the passes (even the default view one) */
+/* Multi-layer Blender files have the view name in all the passes (even the default view one). */
static void imb_exr_insert_view_name(char *name_full, const char *passname, const char *viewname)
{
BLI_assert(!ELEM(name_full, passname, viewname));
@@ -837,7 +829,7 @@ static void imb_exr_insert_view_name(char *name_full, const char *passname, cons
len = BLI_str_rpartition(passname, delims, &sep, &token);
if (sep) {
- BLI_snprintf(name_full, EXR_PASS_MAXNAME, "%.*s.%s.%s", (int)len, passname, viewname, token);
+ BLI_snprintf(name_full, EXR_PASS_MAXNAME, "%.*s.%s.%s", int(len), passname, viewname, token);
}
else {
BLI_snprintf(name_full, EXR_PASS_MAXNAME, "%s.%s", passname, viewname);
@@ -1170,7 +1162,7 @@ void IMB_exr_write_channels(void *handle)
ExrChannel *echan;
if (data->channels.first) {
- const size_t num_pixels = ((size_t)data->width) * data->height;
+ const size_t num_pixels = size_t(data->width) * data->height;
half *rect_half = nullptr, *current_rect_half = nullptr;
/* We allocate temporary storage for half pixels for all the channels at once. */
@@ -1441,7 +1433,7 @@ void IMB_exr_close(void *handle)
/* ********* */
-/* get a substring from the end of the name, separated by '.' */
+/** Get a sub-string from the end of the name, separated by '.'. */
static int imb_exr_split_token(const char *str, const char *end, const char **token)
{
const char delims[] = {'.', '\0'};
@@ -1453,7 +1445,7 @@ static int imb_exr_split_token(const char *str, const char *end, const char **to
*token = str;
}
- return (int)(end - *token);
+ return int(end - *token);
}
static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *passname)
@@ -1462,7 +1454,7 @@ static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *pa
const char *end = name + strlen(name);
const char *token;
- /* some multilayers have the combined buffer with names A B G R saved */
+ /* Some multi-layers have the combined buffer with names A B G R saved. */
if (name[1] == 0) {
echan->chan_id = BLI_toupper_ascii(name[0]);
layname[0] = '\0';
@@ -1497,7 +1489,7 @@ static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *pa
bool ok = false;
if (len == 2) {
- /* some multilayers are using two-letter channels name,
+ /* Some multi-layers are using two-letter channels name,
* like, MX or NZ, which is basically has structure of
* <pass_prefix><component>
*
@@ -1550,7 +1542,7 @@ static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *pa
/* all preceding tokens combined as layer name */
if (end > name) {
- BLI_strncpy(layname, name, (int)(end - name) + 1);
+ BLI_strncpy(layname, name, int(end - name) + 1);
}
else {
layname[0] = '\0';
@@ -1669,29 +1661,29 @@ static bool imb_exr_multilayer_parse_channels_from_file(ExrHandle *data)
if (ELEM(pass->totchan, 3, 4)) {
if (pass->chan[0]->chan_id == 'B' || pass->chan[1]->chan_id == 'B' ||
pass->chan[2]->chan_id == 'B') {
- lookup[(uint)'R'] = 0;
- lookup[(uint)'G'] = 1;
- lookup[(uint)'B'] = 2;
- lookup[(uint)'A'] = 3;
+ lookup[uint('R')] = 0;
+ lookup[uint('G')] = 1;
+ lookup[uint('B')] = 2;
+ lookup[uint('A')] = 3;
}
else if (pass->chan[0]->chan_id == 'Y' || pass->chan[1]->chan_id == 'Y' ||
pass->chan[2]->chan_id == 'Y') {
- lookup[(uint)'X'] = 0;
- lookup[(uint)'Y'] = 1;
- lookup[(uint)'Z'] = 2;
- lookup[(uint)'W'] = 3;
+ lookup[uint('X')] = 0;
+ lookup[uint('Y')] = 1;
+ lookup[uint('Z')] = 2;
+ lookup[uint('W')] = 3;
}
else {
- lookup[(uint)'U'] = 0;
- lookup[(uint)'V'] = 1;
- lookup[(uint)'A'] = 2;
+ lookup[uint('U')] = 0;
+ lookup[uint('V')] = 1;
+ lookup[uint('A')] = 2;
}
for (int a = 0; a < pass->totchan; a++) {
echan = pass->chan[a];
- echan->rect = pass->rect + lookup[(uint)echan->chan_id];
+ echan->rect = pass->rect + lookup[uint(echan->chan_id)];
echan->xstride = pass->totchan;
echan->ystride = data->width * pass->totchan;
- pass->chan_id[(uint)lookup[(uint)echan->chan_id]] = echan->chan_id;
+ pass->chan_id[uint(lookup[uint(echan->chan_id)])] = echan->chan_id;
}
}
else { /* unknown */
@@ -1867,7 +1859,7 @@ static bool imb_exr_is_multilayer_file(MultiPartInputFile &file)
* channels without a layer name will be single layer. */
channels.layers(layerNames);
- return (!layerNames.empty());
+ return !layerNames.empty();
}
static void imb_exr_type_by_channels(ChannelList &channels,
@@ -2014,8 +2006,8 @@ struct ImBuf *imb_load_openexr(const uchar *mem,
if (hasXDensity(file->header(0))) {
/* Convert inches to meters. */
- ibuf->ppm[0] = (double)xDensity(file->header(0)) / 0.0254;
- ibuf->ppm[1] = ibuf->ppm[0] * (double)file->header(0).pixelAspectRatio();
+ ibuf->ppm[0] = double(xDensity(file->header(0))) / 0.0254;
+ ibuf->ppm[1] = ibuf->ppm[0] * double(file->header(0).pixelAspectRatio());
}
ibuf->ftype = IMB_FTYPE_OPENEXR;
@@ -2114,7 +2106,7 @@ struct ImBuf *imb_load_openexr(const uchar *mem,
#endif
if (num_rgb_channels == 0 && has_luma && exr_has_chroma(*file)) {
- for (size_t a = 0; a < (size_t)ibuf->x * ibuf->y; a++) {
+ for (size_t a = 0; a < size_t(ibuf->x) * ibuf->y; a++) {
float *color = ibuf->rect_float + a * 4;
ycc_to_rgb(color[0] * 255.0f,
color[1] * 255.0f,
@@ -2127,7 +2119,7 @@ struct ImBuf *imb_load_openexr(const uchar *mem,
}
else if (num_rgb_channels <= 1) {
/* Convert 1 to 3 channels. */
- for (size_t a = 0; a < (size_t)ibuf->x * ibuf->y; a++) {
+ for (size_t a = 0; a < size_t(ibuf->x) * ibuf->y; a++) {
float *color = ibuf->rect_float + a * 4;
if (num_rgb_channels <= 1) {
color[1] = color[0];
@@ -2167,7 +2159,7 @@ struct ImBuf *imb_load_openexr(const uchar *mem,
}
struct ImBuf *imb_load_filepath_thumbnail_openexr(const char *filepath,
- const int UNUSED(flags),
+ const int /*flags*/,
const size_t max_thumb_size,
char colorspace[],
size_t *r_width,
@@ -2221,10 +2213,10 @@ struct ImBuf *imb_load_filepath_thumbnail_openexr(const char *filepath,
colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT);
}
- float scale_factor = MIN2((float)max_thumb_size / (float)source_w,
- (float)max_thumb_size / (float)source_h);
- int dest_w = (int)(source_w * scale_factor);
- int dest_h = (int)(source_h * scale_factor);
+ float scale_factor = MIN2(float(max_thumb_size) / float(source_w),
+ float(max_thumb_size) / float(source_h));
+ int dest_w = int(source_w * scale_factor);
+ int dest_h = int(source_h * scale_factor);
struct ImBuf *ibuf = IMB_allocImBuf(dest_w, dest_h, 32, IB_rectfloat);
@@ -2235,13 +2227,13 @@ struct ImBuf *imb_load_filepath_thumbnail_openexr(const char *filepath,
for (int h = 0; h < dest_h; h++) {
/* Load the single source row that corresponds with destination row. */
- int source_y = (int)((float)h / scale_factor) + dw.min.y;
+ int source_y = int(float(h) / scale_factor) + dw.min.y;
file->setFrameBuffer(&pixels[0] - dw.min.x - source_y * source_w, 1, source_w);
file->readPixels(source_y);
for (int w = 0; w < dest_w; w++) {
/* For each destination pixel find single corresponding source pixel. */
- int source_x = (int)(MIN2((w / scale_factor), dw.max.x - 1));
+ int source_x = int(MIN2((w / scale_factor), dw.max.x - 1));
float *dest_px = &ibuf->rect_float[(h * dest_w + w) * 4];
dest_px[0] = pixels[source_x].r;
dest_px[1] = pixels[source_x].g;
diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c
index df6959ca90b..1736329cbff 100644
--- a/source/blender/imbuf/intern/png.c
+++ b/source/blender/imbuf/intern/png.c
@@ -129,7 +129,7 @@ bool imb_savepng(struct ImBuf *ibuf, const char *filepath, int flags)
/* use the jpeg quality setting for compression */
int compression;
- compression = (int)(((float)(ibuf->foptions.quality) / 11.1111f));
+ compression = (int)((float)(ibuf->foptions.quality) / 11.1111f);
compression = compression < 0 ? 0 : (compression > 9 ? 9 : compression);
if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) {
diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c
index 4159aa851c4..81fdac40ee6 100644
--- a/source/blender/imbuf/intern/rectop.c
+++ b/source/blender/imbuf/intern/rectop.c
@@ -810,7 +810,7 @@ void IMB_rectblend(ImBuf *dbuf,
else {
for (x = width; x > 0; x--, dr++, or ++, sr++, cmr++) {
uchar *src = (uchar *)sr;
- float mask = (float)mask_max * ((float)(*cmr));
+ float mask = (float)mask_max * (float)(*cmr);
if (texmaskrect) {
mask *= ((float)(*tmr++) / 65535.0f);
@@ -908,7 +908,7 @@ void IMB_rectblend(ImBuf *dbuf,
/* no destination mask buffer, do regular blend with masktexture if present */
else {
for (x = width; x > 0; x--, drf += 4, orf += 4, srf += 4, cmr++) {
- float mask = (float)mask_max * ((float)(*cmr));
+ float mask = (float)mask_max * (float)(*cmr);
if (texmaskrect) {
mask *= ((float)(*tmr++) / 65535.0f);
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index 05bee77a6cb..42c19ce1a7e 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -91,7 +91,7 @@ struct ImBuf *IMB_half_x(struct ImBuf *ibuf1)
}
if (ibuf1->x <= 1) {
- return (IMB_dupImBuf(ibuf1));
+ return IMB_dupImBuf(ibuf1);
}
ibuf2 = IMB_allocImBuf((ibuf1->x) / 2, ibuf1->y, ibuf1->planes, ibuf1->flags);
@@ -244,7 +244,7 @@ struct ImBuf *IMB_half_y(struct ImBuf *ibuf1)
}
if (ibuf1->y <= 1) {
- return (IMB_dupImBuf(ibuf1));
+ return IMB_dupImBuf(ibuf1);
}
ibuf2 = IMB_allocImBuf(ibuf1->x, (ibuf1->y) / 2, ibuf1->planes, ibuf1->flags);
@@ -441,10 +441,10 @@ ImBuf *IMB_onehalf(struct ImBuf *ibuf1)
}
if (ibuf1->x <= 1) {
- return (IMB_half_y(ibuf1));
+ return IMB_half_y(ibuf1);
}
if (ibuf1->y <= 1) {
- return (IMB_half_x(ibuf1));
+ return IMB_half_x(ibuf1);
}
ibuf2 = IMB_allocImBuf((ibuf1->x) / 2, (ibuf1->y) / 2, ibuf1->planes, ibuf1->flags);
@@ -828,7 +828,7 @@ static void q_scale_float(
}
/**
- * q_scale_linear_interpolation (derived from ppmqscale, http://libdv.sf.net)
+ * q_scale_linear_interpolation (derived from `ppmqscale`, http://libdv.sf.net)
*
* q stands for quick _and_ quality :)
*
diff --git a/source/blender/imbuf/intern/thumbs_font.c b/source/blender/imbuf/intern/thumbs_font.c
index 65848bfb55e..c3ed81698d9 100644
--- a/source/blender/imbuf/intern/thumbs_font.c
+++ b/source/blender/imbuf/intern/thumbs_font.c
@@ -6,94 +6,39 @@
#include "BLI_fileops.h"
#include "BLI_hash_md5.h"
-#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-#include "IMB_thumbs.h"
+#include "IMB_thumbs.h" /* own include. */
/* XXX, bad level call */
#include "../../blenfont/BLF_api.h"
-#include "../../blentranslation/BLT_translation.h"
-#define THUMB_TXT_ITEMS \
- N_("AaBbCc"), N_("The quick"), N_("brown fox"), N_("jumps over"), N_("the lazy dog"),
+/* Only change if we need to update the previews in the on-disk cache. */
+#define FONT_THUMB_VERSION "1.0.0"
-static const char *thumb_str[] = {THUMB_TXT_ITEMS};
-
-static const char *i18n_thumb_str[] = {THUMB_TXT_ITEMS};
-
-#undef THUMB_TXT_ITEMS
-
-void IMB_thumb_clear_translations(void)
-{
- for (int i = ARRAY_SIZE(thumb_str); i-- > 0;) {
- i18n_thumb_str[i] = NULL;
- }
-}
-
-void IMB_thumb_ensure_translations(void)
-{
- for (int i = ARRAY_SIZE(thumb_str); i-- > 0;) {
- i18n_thumb_str[i] = BLT_translate_do(BLT_I18NCONTEXT_DEFAULT, thumb_str[i]);
- }
-}
-
-struct ImBuf *IMB_thumb_load_font(const char *filepath, uint x, uint y)
+struct ImBuf *IMB_thumb_load_font(const char *filename, uint x, uint y)
{
- const int font_size = y / 4;
+ struct ImBuf *ibuf = IMB_allocImBuf(x, y, 32, IB_rect | IB_metadata);
- struct ImBuf *ibuf;
- float font_color[4];
+ /* fill with white and zero alpha */
+ const float col[4] = {1.0f, 1.0f, 1.0f, 0.0f};
+ IMB_rectfill(ibuf, col);
- /* create a white image (theme color is used for drawing) */
- font_color[0] = font_color[1] = font_color[2] = 1.0f;
-
- /* fill with zero alpha */
- font_color[3] = 0.0f;
-
- ibuf = IMB_allocImBuf(x, y, 32, IB_rect | IB_metadata);
- IMB_rectfill(ibuf, font_color);
-
- /* draw with full alpha */
- font_color[3] = 1.0f;
-
- BLF_thumb_preview(filepath,
- thumb_str,
- i18n_thumb_str,
- ARRAY_SIZE(thumb_str),
- font_color,
- font_size,
- (uchar *)ibuf->rect,
- ibuf->x,
- ibuf->y,
- ibuf->channels);
+ if (!BLF_thumb_preview(filename, (uchar *)ibuf->rect, ibuf->x, ibuf->y, ibuf->channels)) {
+ IMB_freeImBuf(ibuf);
+ ibuf = NULL;
+ }
return ibuf;
}
bool IMB_thumb_load_font_get_hash(char *r_hash)
{
- char buf[1024];
- char *str = buf;
- size_t len = 0;
-
- int draw_str_lines = ARRAY_SIZE(thumb_str);
- int i;
-
uchar digest[16];
-
- len += BLI_strncpy_rlen(str + len, THUMB_DEFAULT_HASH, sizeof(buf) - len);
-
- for (i = 0; (i < draw_str_lines) && (len < sizeof(buf)); i++) {
- len += BLI_strncpy_rlen(str + len,
- i18n_thumb_str[i] != NULL ? i18n_thumb_str[i] : thumb_str[i],
- sizeof(buf) - len);
- }
-
- BLI_hash_md5_buffer(str, len, digest);
+ BLI_hash_md5_buffer(FONT_THUMB_VERSION, sizeof(FONT_THUMB_VERSION), digest);
r_hash[0] = '\0';
BLI_hash_md5_to_hexdigest(digest, r_hash);
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index f4829386aac..0e20d0748db 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -142,7 +142,7 @@ static tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n)
}
/* all set -> do the read (copy) */
- srcAddr = (void *)(&(mfile->mem[mfile->offset]));
+ srcAddr = (void *)&(mfile->mem[mfile->offset]);
memcpy((void *)data, srcAddr, nCopy);
mfile->offset += nCopy; /* advance file ptr by copied bytes */
return nCopy;
@@ -437,7 +437,7 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image)
}
/* simple RGBA image */
- if (!(ELEM(bitspersample, 32, 16))) {
+ if (!ELEM(bitspersample, 32, 16)) {
success |= TIFFReadRGBAImage(image, ibuf->x, ibuf->y, tmpibuf->rect, 0);
}
/* contiguous channels: RGBRGBRGB */
diff --git a/source/blender/imbuf/intern/transform.cc b/source/blender/imbuf/intern/transform.cc
index 276d31c0557..6d3452c64db 100644
--- a/source/blender/imbuf/intern/transform.cc
+++ b/source/blender/imbuf/intern/transform.cc
@@ -134,8 +134,7 @@ class NoDiscard : public BaseDiscard {
*
* Will never discard any pixels.
*/
- bool should_discard(const TransformUserData &UNUSED(user_data),
- const float UNUSED(uv[2])) override
+ bool should_discard(const TransformUserData & /*user_data*/, const float /*uv*/[2]) override
{
return false;
}
@@ -165,7 +164,7 @@ class PixelPointer {
public:
void init_pixel_pointer(const ImBuf *image_buffer, int x, int y)
{
- const size_t offset = (y * (size_t)image_buffer->x + x) * NumChannels;
+ const size_t offset = (y * size_t(image_buffer->x) + x) * NumChannels;
if constexpr (std::is_same_v<StorageType, float>) {
pointer = image_buffer->rect_float + offset;
@@ -216,12 +215,12 @@ class BaseUVWrapping {
*/
class PassThroughUV : public BaseUVWrapping {
public:
- float modify_u(const ImBuf *UNUSED(source_buffer), float u) override
+ float modify_u(const ImBuf * /*source_buffer*/, float u) override
{
return u;
}
- float modify_v(const ImBuf *UNUSED(source_buffer), float v) override
+ float modify_v(const ImBuf * /*source_buffer*/, float v) override
{
return v;
}
@@ -235,7 +234,7 @@ class WrapRepeatUV : public BaseUVWrapping {
float modify_u(const ImBuf *source_buffer, float u) override
{
- int x = (int)floor(u);
+ int x = int(floor(u));
x = x % source_buffer->x;
if (x < 0) {
x += source_buffer->x;
@@ -245,7 +244,7 @@ class WrapRepeatUV : public BaseUVWrapping {
float modify_v(const ImBuf *source_buffer, float v) override
{
- int y = (int)floor(v);
+ int y = int(floor(v));
y = y % source_buffer->y;
if (y < 0) {
y += source_buffer->y;
@@ -349,8 +348,8 @@ class Sampler {
BLI_STATIC_ASSERT(std::is_same_v<StorageType, float>);
/* ImBuf in must have a valid rect or rect_float, assume this is already checked */
- int x1 = (int)(u);
- int y1 = (int)(v);
+ int x1 = int(u);
+ int y1 = int(v);
/* Break when sample outside image is requested. */
if (x1 < 0 || x1 >= source->x || y1 < 0 || y1 >= source->y) {
@@ -360,7 +359,7 @@ class Sampler {
return;
}
- const size_t offset = ((size_t)source->x * y1 + x1) * NumChannels;
+ const size_t offset = (size_t(source->x) * y1 + x1) * NumChannels;
const float *dataF = source->rect_float + offset;
for (int i = 0; i < NumChannels; i++) {
r_sample[i] = dataF[i];
diff --git a/source/blender/imbuf/intern/util_gpu.c b/source/blender/imbuf/intern/util_gpu.c
index 6f1275e1812..35cdefbaaeb 100644
--- a/source/blender/imbuf/intern/util_gpu.c
+++ b/source/blender/imbuf/intern/util_gpu.c
@@ -174,6 +174,7 @@ static void *imb_gpu_get_data(const ImBuf *ibuf,
/* Other colorspace, store as float texture to avoid precision loss. */
data_rect = MEM_mallocN(sizeof(float[4]) * ibuf->x * ibuf->y, __func__);
*r_freedata = freedata = true;
+ is_float_rect = true;
if (data_rect == NULL) {
return NULL;
@@ -300,6 +301,16 @@ GPUTexture *IMB_create_gpu_texture(const char *name,
int size[2] = {GPU_texture_size_with_limit(ibuf->x), GPU_texture_size_with_limit(ibuf->y)};
bool do_rescale = (ibuf->x != size[0]) || (ibuf->y != size[1]);
+ /* Correct the smaller size to maintain the original aspect ratio of the image. */
+ if (do_rescale && ibuf->x != ibuf->y) {
+ if (size[0] > size[1]) {
+ size[1] = (int)(ibuf->y * ((float)size[0] / ibuf->x));
+ }
+ else {
+ size[0] = (int)(ibuf->x * ((float)size[1] / ibuf->y));
+ }
+ }
+
#ifdef WITH_DDS
if (ibuf->ftype == IMB_FTYPE_DDS) {
eGPUTextureFormat compressed_format;
@@ -370,3 +381,19 @@ eGPUTextureFormat IMB_gpu_get_texture_format(const ImBuf *ibuf,
return gpu_texture_format;
}
+
+void IMB_gpu_clamp_half_float(ImBuf *image_buffer)
+{
+ const float half_min = -65504;
+ const float half_max = 65504;
+ if (!image_buffer->rect_float) {
+ return;
+ }
+
+ int rect_float_len = image_buffer->x * image_buffer->y *
+ (image_buffer->channels == 0 ? 4 : image_buffer->channels);
+
+ for (int i = 0; i < rect_float_len; i++) {
+ image_buffer->rect_float[i] = clamp_f(image_buffer->rect_float[i], half_min, half_max);
+ }
+}
diff --git a/source/blender/imbuf/intern/webp.c b/source/blender/imbuf/intern/webp.c
index 27c26fb19c1..3031b8c3e33 100644
--- a/source/blender/imbuf/intern/webp.c
+++ b/source/blender/imbuf/intern/webp.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
- * \ingroup imbuf
+ * \ingroup imbuf
*/
#ifdef _WIN32
diff --git a/source/blender/io/alembic/exporter/abc_archive.cc b/source/blender/io/alembic/exporter/abc_archive.cc
index 9c8a36958d5..55e172db241 100644
--- a/source/blender/io/alembic/exporter/abc_archive.cc
+++ b/source/blender/io/alembic/exporter/abc_archive.cc
@@ -130,13 +130,13 @@ static TimeSamplingPtr create_time_sampling(double scene_fps,
get_shutter_samples(scene_fps, params, nr_of_samples, true, samples);
- TimeSamplingType ts(static_cast<uint32_t>(samples.size()), 1.0 / scene_fps);
+ TimeSamplingType ts(uint32_t(samples.size()), 1.0 / scene_fps);
return TimeSamplingPtr(new TimeSampling(ts, samples)); // NOLINT: modernize-make-shared
}
static void get_frames(double scene_fps,
const AlembicExportParams &params,
- unsigned int nr_of_samples,
+ uint nr_of_samples,
std::set<double> &r_frames)
{
/* Get one set of shutter samples, then add those around each frame to export. */
diff --git a/source/blender/io/alembic/exporter/abc_export_capi.cc b/source/blender/io/alembic/exporter/abc_export_capi.cc
index dfca89e2c6d..1ac4eacc997 100644
--- a/source/blender/io/alembic/exporter/abc_export_capi.cc
+++ b/source/blender/io/alembic/exporter/abc_export_capi.cc
@@ -72,8 +72,8 @@ static void report_job_duration(const ExportJobData *data)
static void export_startjob(void *customdata,
/* Cannot be const, this function implements wm_jobs_start_callback.
* NOLINTNEXTLINE: readability-non-const-parameter. */
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress)
{
ExportJobData *data = static_cast<ExportJobData *>(customdata);
@@ -144,8 +144,8 @@ static void export_startjob(void *customdata,
}
/* Update the scene for the next frame to render. */
- scene->r.cfra = static_cast<int>(frame);
- scene->r.subframe = static_cast<float>(frame - scene->r.cfra);
+ scene->r.cfra = int(frame);
+ scene->r.subframe = float(frame - scene->r.cfra);
BKE_scene_graph_update_for_newframe(data->depsgraph);
CLOG_INFO(&LOG, 2, "Exporting frame %.2f", frame);
@@ -230,7 +230,7 @@ bool ABC_export(Scene *scene,
}
else {
/* Fake a job context, so that we don't need NULL pointer checks while exporting. */
- short stop = 0, do_update = 0;
+ bool stop = false, do_update = false;
float progress = 0.0f;
blender::io::alembic::export_startjob(job, &stop, &do_update, &progress);
diff --git a/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc b/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc
index 514ce389e36..712b04f3992 100644
--- a/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc
+++ b/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc
@@ -14,6 +14,7 @@
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
+#include "BKE_layer.h"
#include "BKE_modifier.h"
namespace blender::io::alembic {
@@ -34,7 +35,8 @@ void SubdivModifierDisabler::disable_modifiers()
Scene *scene = DEG_get_input_scene(depsgraph_);
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph_);
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *object = base->object;
if (object->type != OB_MESH) {
diff --git a/source/blender/io/alembic/exporter/abc_writer_curves.cc b/source/blender/io/alembic/exporter/abc_writer_curves.cc
index 4717d3ec26e..e5e8053d7d3 100644
--- a/source/blender/io/alembic/exporter/abc_writer_curves.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_curves.cc
@@ -142,7 +142,7 @@ void ABCCurveWriter::do_write(HierarchyContext &context)
}
}
- orders.push_back(static_cast<uint8_t>(nurbs->orderu));
+ orders.push_back(uint8_t(nurbs->orderu));
vert_counts.push_back(verts.size() - current_point_count);
}
diff --git a/source/blender/io/alembic/exporter/abc_writer_hair.cc b/source/blender/io/alembic/exporter/abc_writer_hair.cc
index 4f09aee3ea9..13136372c56 100644
--- a/source/blender/io/alembic/exporter/abc_writer_hair.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_hair.cc
@@ -118,7 +118,7 @@ void ABCHairWriter::write_hair_sample(const HierarchyContext &context,
{
/* Get untransformed vertices, there's a xform under the hair. */
float inv_mat[4][4];
- invert_m4_m4_safe(inv_mat, context.object->obmat);
+ invert_m4_m4_safe(inv_mat, context.object->object_to_world);
MTFace *mtface = (MTFace *)CustomData_get_layer(&mesh->fdata, CD_MTFACE);
MFace *mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
@@ -190,7 +190,7 @@ void ABCHairWriter::write_hair_sample(const HierarchyContext &context,
for (int n = 0; n < mesh->totface; n++) {
MFace *face = &mface[n];
MTFace *tface = mtface + n;
- unsigned int vtx[4];
+ uint vtx[4];
vtx[0] = face->v1;
vtx[1] = face->v2;
vtx[2] = face->v3;
@@ -241,7 +241,7 @@ void ABCHairWriter::write_hair_child_sample(const HierarchyContext &context,
{
/* Get untransformed vertices, there's a xform under the hair. */
float inv_mat[4][4];
- invert_m4_m4_safe(inv_mat, context.object->obmat);
+ invert_m4_m4_safe(inv_mat, context.object->object_to_world);
MFace *mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
MTFace *mtface = (MTFace *)CustomData_get_layer(&mesh->fdata, CD_MTFACE);
diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc
index 7d38cd1ec88..084d26198bc 100644
--- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc
@@ -476,16 +476,17 @@ static void get_edge_creases(struct Mesh *mesh,
std::vector<int32_t> &lengths,
std::vector<float> &sharpnesses)
{
- const float factor = 1.0f / 255.0f;
-
indices.clear();
lengths.clear();
sharpnesses.clear();
+ const float *creases = static_cast<const float *>(CustomData_get_layer(&mesh->edata, CD_CREASE));
+ if (!creases) {
+ return;
+ }
const Span<MEdge> edges = mesh->edges();
-
for (const int i : edges.index_range()) {
- const float sharpness = static_cast<float>(edges[i].crease) * factor;
+ const float sharpness = creases[i];
if (sharpness != 0.0f) {
indices.push_back(edges[i].v1);
diff --git a/source/blender/io/alembic/exporter/abc_writer_points.cc b/source/blender/io/alembic/exporter/abc_writer_points.cc
index 29370978b54..9372bffc3ca 100644
--- a/source/blender/io/alembic/exporter/abc_writer_points.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_points.cc
@@ -85,7 +85,7 @@ void ABCPointsWriter::do_write(HierarchyContext &context)
sim.ob = context.object;
sim.psys = psys;
- psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
+ psys_sim_data_init(&sim);
uint64_t index = 0;
for (int p = 0; p < psys->totpart; p++) {
@@ -101,7 +101,7 @@ void ABCPointsWriter::do_write(HierarchyContext &context)
}
/* location */
- mul_v3_m4v3(pos, context.object->imat, state.co);
+ mul_v3_m4v3(pos, context.object->world_to_object, state.co);
/* velocity */
sub_v3_v3v3(vel, state.co, psys->particles[p].prev_state.co);
@@ -113,10 +113,7 @@ void ABCPointsWriter::do_write(HierarchyContext &context)
ids.push_back(index++);
}
- if (psys->lattice_deform_data) {
- BKE_lattice_deform_data_destroy(psys->lattice_deform_data);
- psys->lattice_deform_data = nullptr;
- }
+ psys_sim_data_free(&sim);
Alembic::Abc::P3fArraySample psample(points);
Alembic::Abc::UInt64ArraySample idsample(ids);
diff --git a/source/blender/io/alembic/intern/abc_axis_conversion.cc b/source/blender/io/alembic/intern/abc_axis_conversion.cc
index 00e5890e9d3..c7d2a3e1bf4 100644
--- a/source/blender/io/alembic/intern/abc_axis_conversion.cc
+++ b/source/blender/io/alembic/intern/abc_axis_conversion.cc
@@ -134,15 +134,15 @@ void create_transform_matrix(Object *obj,
if (mode == ABC_MATRIX_LOCAL && obj->parent) {
/* Note that this produces another matrix than the local matrix, due to
* constraints and modifiers as well as the obj->parentinv matrix. */
- invert_m4_m4(obj->parent->imat, obj->parent->obmat);
- mul_m4_m4m4(zup_mat, obj->parent->imat, obj->obmat);
+ invert_m4_m4(obj->parent->world_to_object, obj->parent->object_to_world);
+ mul_m4_m4m4(zup_mat, obj->parent->world_to_object, obj->object_to_world);
}
else {
- copy_m4_m4(zup_mat, obj->obmat);
+ copy_m4_m4(zup_mat, obj->object_to_world);
}
if (proxy_from) {
- mul_m4_m4m4(zup_mat, proxy_from->obmat, zup_mat);
+ mul_m4_m4m4(zup_mat, proxy_from->object_to_world, zup_mat);
}
copy_m44_axis_swap(r_yup_mat, zup_mat, ABC_YUP_FROM_ZUP);
diff --git a/source/blender/io/alembic/intern/abc_customdata.cc b/source/blender/io/alembic/intern/abc_customdata.cc
index 5494bfaa6e8..3349f9fc30b 100644
--- a/source/blender/io/alembic/intern/abc_customdata.cc
+++ b/source/blender/io/alembic/intern/abc_customdata.cc
@@ -322,14 +322,14 @@ static void read_uvs(const CDStreamConfig &config,
MLoop *mloops = config.mloop;
MLoopUV *mloopuvs = static_cast<MLoopUV *>(data);
- unsigned int uv_index, loop_index, rev_loop_index;
+ uint uv_index, loop_index, rev_loop_index;
BLI_assert(uv_scope != ABC_UV_SCOPE_NONE);
const bool do_uvs_per_loop = (uv_scope == ABC_UV_SCOPE_LOOP);
for (int i = 0; i < config.totpoly; i++) {
MPoly &poly = mpolys[i];
- unsigned int rev_loop_offset = poly.loopstart + poly.totloop - 1;
+ uint rev_loop_offset = poly.loopstart + poly.totloop - 1;
for (int f = 0; f < poly.totloop; f++) {
rev_loop_index = rev_loop_offset - f;
diff --git a/source/blender/io/alembic/intern/abc_reader_camera.cc b/source/blender/io/alembic/intern/abc_reader_camera.cc
index 830526a11ac..e7a319730b6 100644
--- a/source/blender/io/alembic/intern/abc_reader_camera.cc
+++ b/source/blender/io/alembic/intern/abc_reader_camera.cc
@@ -77,11 +77,11 @@ void AbcCameraReader::readObjectData(Main *bmain, const ISampleSelector &sample_
bcam->stereo.convergence_distance = convergence_plane.getValue(sample_sel);
}
- const float lens = static_cast<float>(cam_sample.getFocalLength());
- const float apperture_x = static_cast<float>(cam_sample.getHorizontalAperture());
- const float apperture_y = static_cast<float>(cam_sample.getVerticalAperture());
- const float h_film_offset = static_cast<float>(cam_sample.getHorizontalFilmOffset());
- const float v_film_offset = static_cast<float>(cam_sample.getVerticalFilmOffset());
+ const float lens = float(cam_sample.getFocalLength());
+ const float apperture_x = float(cam_sample.getHorizontalAperture());
+ const float apperture_y = float(cam_sample.getVerticalAperture());
+ const float h_film_offset = float(cam_sample.getHorizontalFilmOffset());
+ const float v_film_offset = float(cam_sample.getVerticalFilmOffset());
const float film_aspect = apperture_x / apperture_y;
bcam->lens = lens;
@@ -89,10 +89,10 @@ void AbcCameraReader::readObjectData(Main *bmain, const ISampleSelector &sample_
bcam->sensor_y = apperture_y * 10;
bcam->shiftx = h_film_offset / apperture_x;
bcam->shifty = v_film_offset / apperture_y / film_aspect;
- bcam->clip_start = max_ff(0.1f, static_cast<float>(cam_sample.getNearClippingPlane()));
- bcam->clip_end = static_cast<float>(cam_sample.getFarClippingPlane());
- bcam->dof.focus_distance = static_cast<float>(cam_sample.getFocusDistance());
- bcam->dof.aperture_fstop = static_cast<float>(cam_sample.getFStop());
+ bcam->clip_start = max_ff(0.1f, float(cam_sample.getNearClippingPlane()));
+ bcam->clip_end = float(cam_sample.getFarClippingPlane());
+ bcam->dof.focus_distance = float(cam_sample.getFocusDistance());
+ bcam->dof.aperture_fstop = float(cam_sample.getFStop());
m_object = BKE_object_add_only_object(bmain, OB_CAMERA, m_object_name.c_str());
m_object->data = bcam;
diff --git a/source/blender/io/alembic/intern/abc_reader_curves.cc b/source/blender/io/alembic/intern/abc_reader_curves.cc
index d8859acdf5f..24bdae3ac50 100644
--- a/source/blender/io/alembic/intern/abc_reader_curves.cc
+++ b/source/blender/io/alembic/intern/abc_reader_curves.cc
@@ -152,7 +152,7 @@ void AbcCurveReader::read_curve_sample(Curve *cu,
break;
case Alembic::AbcGeom::kVariableOrder:
if (orders && orders->size() > i) {
- nu->orderu = static_cast<short>((*orders)[i]);
+ nu->orderu = short((*orders)[i]);
break;
}
ATTR_FALLTHROUGH;
diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc
index c07aaa37988..2531bd62609 100644
--- a/source/blender/io/alembic/intern/abc_reader_mesh.cc
+++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc
@@ -133,7 +133,7 @@ static void read_mverts_interp(MVert *mverts,
const Imath::V3f &floor_pos = (*positions)[i];
const Imath::V3f &ceil_pos = (*ceil_positions)[i];
- interp_v3_v3v3(tmp, floor_pos.getValue(), ceil_pos.getValue(), static_cast<float>(weight));
+ interp_v3_v3v3(tmp, floor_pos.getValue(), ceil_pos.getValue(), float(weight));
copy_zup_from_yup(mvert.co, tmp);
}
}
@@ -188,9 +188,9 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data)
const bool do_uvs = (mloopuvs && uvs && uvs_indices);
const bool do_uvs_per_loop = do_uvs && mesh_data.uv_scope == ABC_UV_SCOPE_LOOP;
BLI_assert(!do_uvs || mesh_data.uv_scope != ABC_UV_SCOPE_NONE);
- unsigned int loop_index = 0;
- unsigned int rev_loop_index = 0;
- unsigned int uv_index = 0;
+ uint loop_index = 0;
+ uint rev_loop_index = 0;
+ uint uv_index = 0;
bool seen_invalid_geometry = false;
for (int i = 0; i < face_counts->size(); i++) {
@@ -448,7 +448,7 @@ static void read_velocity(const V3fArraySamplePtr &velocities,
const CDStreamConfig &config,
const float velocity_scale)
{
- const int num_velocity_vectors = static_cast<int>(velocities->size());
+ const int num_velocity_vectors = int(velocities->size());
if (num_velocity_vectors != config.mesh->totvert) {
/* Files containing videogrammetry data may be malformed and export velocity data on missing
* frames (most likely by copying the last valid data). */
@@ -763,7 +763,7 @@ Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
std::map<std::string, int> mat_map;
bke::MutableAttributeAccessor attributes = new_mesh->attributes_for_write();
bke::SpanAttributeWriter<int> material_indices =
- attributes.lookup_or_add_for_write_only_span<int>("material_index", ATTR_DOMAIN_FACE);
+ attributes.lookup_or_add_for_write_span<int>("material_index", ATTR_DOMAIN_FACE);
assign_facesets_to_material_indices(sample_sel, material_indices.span, mat_map);
material_indices.finish();
}
@@ -823,8 +823,8 @@ void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, const ISampleSel
{
std::map<std::string, int> mat_map;
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
- bke::SpanAttributeWriter<int> material_indices =
- attributes.lookup_or_add_for_write_only_span<int>("material_index", ATTR_DOMAIN_FACE);
+ bke::SpanAttributeWriter<int> material_indices = attributes.lookup_or_add_for_write_span<int>(
+ "material_index", ATTR_DOMAIN_FACE);
assign_facesets_to_material_indices(sample_sel, material_indices.span, mat_map);
material_indices.finish();
utils::assign_materials(bmain, m_object, mat_map);
@@ -903,8 +903,6 @@ static void read_vertex_creases(Mesh *mesh,
vertex_crease_data[idx] = (*sharpnesses)[i];
}
-
- mesh->cd_flag |= ME_CDFLAG_VERT_CREASE;
}
static void read_edge_creases(Mesh *mesh,
@@ -918,6 +916,9 @@ static void read_edge_creases(Mesh *mesh,
MutableSpan<MEdge> edges = mesh->edges_for_write();
EdgeHash *edge_hash = BLI_edgehash_new_ex(__func__, edges.size());
+ float *creases = static_cast<float *>(
+ CustomData_add_layer(&mesh->edata, CD_CREASE, CD_SET_DEFAULT, nullptr, edges.size()));
+
for (const int i : edges.index_range()) {
MEdge *edge = &edges[i];
BLI_edgehash_insert(edge_hash, edge->v1, edge->v2, edge);
@@ -939,13 +940,11 @@ static void read_edge_creases(Mesh *mesh,
}
if (edge) {
- edge->crease = unit_float_to_uchar_clamp((*sharpnesses)[s]);
+ creases[edge - edges.data()] = unit_float_to_uchar_clamp((*sharpnesses)[s]);
}
}
BLI_edgehash_free(edge_hash, nullptr);
-
- mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
}
/* ************************************************************************** */
diff --git a/source/blender/io/alembic/intern/abc_reader_object.cc b/source/blender/io/alembic/intern/abc_reader_object.cc
index db056c0eef6..f3a07eaad3f 100644
--- a/source/blender/io/alembic/intern/abc_reader_object.cc
+++ b/source/blender/io/alembic/intern/abc_reader_object.cc
@@ -110,7 +110,7 @@ static Imath::M44d blend_matrices(const Imath::M44d &m0,
convert_matrix_datatype(m0, mat0);
convert_matrix_datatype(m1, mat1);
- interp_m4_m4m4(ret, mat0, mat1, static_cast<float>(weight));
+ interp_m4_m4m4(ret, mat0, mat1, float(weight));
return convert_matrix_datatype(ret);
}
@@ -133,11 +133,11 @@ Imath::M44d get_matrix(const IXformSchema &schema, const chrono_t time)
}
struct Mesh *AbcObjectReader::read_mesh(struct Mesh *existing_mesh,
- const Alembic::Abc::ISampleSelector &UNUSED(sample_sel),
- int UNUSED(read_flag),
- const char *UNUSED(velocity_name),
- const float UNUSED(velocity_scale),
- const char **UNUSED(err_str))
+ const Alembic::Abc::ISampleSelector & /*sample_sel*/,
+ int /*read_flag*/,
+ const char * /*velocity_name*/,
+ const float /*velocity_scale*/,
+ const char ** /*err_str*/)
{
return existing_mesh;
}
@@ -165,7 +165,7 @@ void AbcObjectReader::setupObjectTransform(const chrono_t time)
/* Apply the matrix to the object. */
BKE_object_apply_mat4(m_object, transform_from_alembic, true, false);
- BKE_object_to_mat4(m_object, m_object->obmat);
+ BKE_object_to_mat4(m_object, m_object->object_to_world);
if (!is_constant || m_settings->always_add_cache_reader) {
bConstraint *con = BKE_constraint_add_for_object(
diff --git a/source/blender/io/alembic/intern/abc_reader_transform.cc b/source/blender/io/alembic/intern/abc_reader_transform.cc
index 0d3227fc718..71682531378 100644
--- a/source/blender/io/alembic/intern/abc_reader_transform.cc
+++ b/source/blender/io/alembic/intern/abc_reader_transform.cc
@@ -55,7 +55,7 @@ bool AbcEmptyReader::accepts_object_type(
return true;
}
-void AbcEmptyReader::readObjectData(Main *bmain, const ISampleSelector &UNUSED(sample_sel))
+void AbcEmptyReader::readObjectData(Main *bmain, const ISampleSelector & /*sample_sel*/)
{
m_object = BKE_object_add_only_object(bmain, OB_EMPTY, m_object_name.c_str());
m_object->data = nullptr;
diff --git a/source/blender/io/alembic/intern/abc_util.cc b/source/blender/io/alembic/intern/abc_util.cc
index 90f73d25c22..846a3622d62 100644
--- a/source/blender/io/alembic/intern/abc_util.cc
+++ b/source/blender/io/alembic/intern/abc_util.cc
@@ -73,7 +73,7 @@ Imath::M44d convert_matrix_datatype(float mat[4][4])
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- m[i][j] = static_cast<double>(mat[i][j]);
+ m[i][j] = double(mat[i][j]);
}
}
@@ -84,7 +84,7 @@ void convert_matrix_datatype(const Imath::M44d &xform, float r_mat[4][4])
{
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- r_mat[i][j] = static_cast<float>(xform[i][j]);
+ r_mat[i][j] = float(xform[i][j]);
}
}
}
diff --git a/source/blender/io/alembic/intern/alembic_capi.cc b/source/blender/io/alembic/intern/alembic_capi.cc
index 86622719f6e..f6c11f6a684 100644
--- a/source/blender/io/alembic/intern/alembic_capi.cc
+++ b/source/blender/io/alembic/intern/alembic_capi.cc
@@ -427,8 +427,8 @@ struct ImportJobData {
ArchiveReader *archive;
std::vector<AbcObjectReader *> readers;
- short *stop;
- short *do_update;
+ bool *stop;
+ bool *do_update;
float *progress;
char error_code;
@@ -446,7 +446,7 @@ static void report_job_duration(const ImportJobData *data)
std::cout << '\n';
}
-static void import_startjob(void *user_data, short *stop, short *do_update, float *progress)
+static void import_startjob(void *user_data, bool *stop, bool *do_update, float *progress)
{
SCOPE_TIMER("Alembic import, objects reading and creation");
@@ -502,7 +502,7 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
/* Create objects and set scene frame range. */
- const float size = static_cast<float>(data->readers.size());
+ const float size = float(data->readers.size());
size_t i = 0;
chrono_t min_time = std::numeric_limits<chrono_t>::max();
@@ -542,8 +542,8 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
scene->r.cfra = scene->r.sfra;
}
else if (min_time < max_time) {
- scene->r.sfra = static_cast<int>(round(min_time * FPS));
- scene->r.efra = static_cast<int>(round(max_time * FPS));
+ scene->r.sfra = int(round(min_time * FPS));
+ scene->r.efra = int(round(max_time * FPS));
scene->r.cfra = scene->r.sfra;
}
}
@@ -601,21 +601,19 @@ static void import_endjob(void *user_data)
else {
Base *base;
LayerCollection *lc;
+ const Scene *scene = data->scene;
ViewLayer *view_layer = data->view_layer;
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
lc = BKE_layer_collection_get_active(view_layer);
- /* Add all objects to the collection (don't do sync for each object). */
- BKE_layer_collection_resync_forbid();
for (AbcObjectReader *reader : data->readers) {
Object *ob = reader->object();
BKE_collection_object_add(data->bmain, lc->collection, ob);
}
- /* Sync the collection, and do view layer operations. */
- BKE_layer_collection_resync_allow();
- BKE_main_collection_sync(data->bmain);
+ /* Sync and do the view layer operations. */
+ BKE_view_layer_synced_ensure(scene, view_layer);
for (AbcObjectReader *reader : data->readers) {
Object *ob = reader->object();
base = BKE_view_layer_base_find(view_layer, ob);
@@ -717,7 +715,7 @@ bool ABC_import(bContext *C,
}
else {
/* Fake a job context, so that we don't need NULL pointer checks while importing. */
- short stop = 0, do_update = 0;
+ bool stop = false, do_update = false;
float progress = 0.0f;
import_startjob(job, &stop, &do_update, &progress);
diff --git a/source/blender/io/avi/intern/avi.c b/source/blender/io/avi/intern/avi.c
index 8bf4f8124a3..3da93f51cfc 100644
--- a/source/blender/io/avi/intern/avi.c
+++ b/source/blender/io/avi/intern/avi.c
@@ -38,14 +38,14 @@ static char DEBUG_FCC[4];
(void)0
/* local functions */
-char *fcc_to_char(unsigned int fcc);
-char *tcc_to_char(unsigned int tcc);
+char *fcc_to_char(uint fcc);
+char *tcc_to_char(uint tcc);
/* implementation */
-unsigned int GET_FCC(FILE *fp)
+uint GET_FCC(FILE *fp)
{
- unsigned char tmp[4];
+ uchar tmp[4];
tmp[0] = getc(fp);
tmp[1] = getc(fp);
@@ -55,7 +55,7 @@ unsigned int GET_FCC(FILE *fp)
return FCC(tmp);
}
-unsigned int GET_TCC(FILE *fp)
+uint GET_TCC(FILE *fp)
{
char tmp[5];
@@ -67,7 +67,7 @@ unsigned int GET_TCC(FILE *fp)
return FCC(tmp);
}
-char *fcc_to_char(unsigned int fcc)
+char *fcc_to_char(uint fcc)
{
DEBUG_FCC[0] = (fcc)&127;
DEBUG_FCC[1] = (fcc >> 8) & 127;
@@ -77,7 +77,7 @@ char *fcc_to_char(unsigned int fcc)
return DEBUG_FCC;
}
-char *tcc_to_char(unsigned int tcc)
+char *tcc_to_char(uint tcc)
{
DEBUG_FCC[0] = (tcc)&127;
DEBUG_FCC[1] = (tcc >> 8) & 127;
@@ -129,7 +129,7 @@ static bool fcc_is_data(int fcc)
fccs[2] = fcc >> 16;
fccs[3] = fcc >> 24;
- if (!isdigit(fccs[0]) || !isdigit(fccs[1]) || (!ELEM(fccs[2], 'd', 'w'))) {
+ if (!isdigit(fccs[0]) || !isdigit(fccs[1]) || !ELEM(fccs[2], 'd', 'w')) {
return 0;
}
if (!ELEM(fccs[3], 'b', 'c')) {
@@ -917,7 +917,7 @@ AviError AVI_write_frame(AviMovie *movie, int frame_num, ...)
va_start(ap, frame_num);
for (stream = 0; stream < movie->header->Streams; stream++) {
- unsigned int tbuf = 0;
+ uint tbuf = 0;
format = va_arg(ap, AviFormat);
buffer = va_arg(ap, void *);
diff --git a/source/blender/io/avi/intern/avi_codecs.c b/source/blender/io/avi/intern/avi_codecs.c
index cbb96e12930..ba897ef808a 100644
--- a/source/blender/io/avi/intern/avi_codecs.c
+++ b/source/blender/io/avi/intern/avi_codecs.c
@@ -14,6 +14,8 @@
#include "avi_rgb.h"
#include "avi_rgb32.h"
+#include "BLI_string.h"
+
void *avi_format_convert(
AviMovie *movie, int stream, void *buffer, AviFormat from, AviFormat to, size_t *size)
{
@@ -68,10 +70,10 @@ int avi_get_data_id(AviFormat format, int stream)
char fcc[5];
if (avi_get_format_type(format) == FCC("vids")) {
- sprintf(fcc, "%2.2ddc", stream);
+ BLI_snprintf(fcc, sizeof(fcc), "%2.2ddc", stream);
}
else if (avi_get_format_type(format) == FCC("auds")) {
- sprintf(fcc, "%2.2ddc", stream);
+ BLI_snprintf(fcc, sizeof(fcc), "%2.2ddc", stream);
}
else {
return 0;
diff --git a/source/blender/io/avi/intern/avi_mjpeg.c b/source/blender/io/avi/intern/avi_mjpeg.c
index fb42274fef2..de75fe8d69e 100644
--- a/source/blender/io/avi/intern/avi_mjpeg.c
+++ b/source/blender/io/avi/intern/avi_mjpeg.c
@@ -22,10 +22,8 @@
#include "avi_mjpeg.h"
-static void jpegmemdestmgr_build(j_compress_ptr cinfo, unsigned char *buffer, size_t bufsize);
-static void jpegmemsrcmgr_build(j_decompress_ptr dinfo,
- const unsigned char *buffer,
- size_t bufsize);
+static void jpegmemdestmgr_build(j_compress_ptr cinfo, uchar *buffer, size_t bufsize);
+static void jpegmemsrcmgr_build(j_decompress_ptr dinfo, const uchar *buffer, size_t bufsize);
static size_t numbytes;
@@ -215,11 +213,7 @@ static void std_huff_tables(j_decompress_ptr dinfo)
sizeof(val_ac_chrominance));
}
-static int Decode_JPEG(unsigned char *inBuffer,
- unsigned char *outBuffer,
- unsigned int width,
- unsigned int height,
- size_t bufsize)
+static int Decode_JPEG(uchar *inBuffer, uchar *outBuffer, uint width, uint height, size_t bufsize)
{
struct jpeg_decompress_struct dinfo;
struct jpeg_error_mgr jerr;
@@ -272,16 +266,12 @@ static int Decode_JPEG(unsigned char *inBuffer,
return 1;
}
-static void Compress_JPEG(int quality,
- unsigned char *outbuffer,
- const unsigned char *inBuffer,
- int width,
- int height,
- size_t bufsize)
+static void Compress_JPEG(
+ int quality, uchar *outbuffer, const uchar *inBuffer, int width, int height, size_t bufsize)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
- unsigned char marker[60];
+ uchar marker[60];
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
@@ -339,7 +329,7 @@ static void Compress_JPEG(int quality,
jpeg_destroy_compress(&cinfo);
}
-static void interlace(unsigned char *to, unsigned char *from, int width, int height)
+static void interlace(uchar *to, uchar *from, int width, int height)
{
size_t i, rowstride = width * 3;
@@ -353,7 +343,7 @@ static void interlace(unsigned char *to, unsigned char *from, int width, int hei
}
}
-static void deinterlace(int odd, unsigned char *to, unsigned char *from, int width, int height)
+static void deinterlace(int odd, uchar *to, uchar *from, int width, int height)
{
size_t i, rowstride = width * 3;
@@ -367,20 +357,17 @@ static void deinterlace(int odd, unsigned char *to, unsigned char *from, int wid
}
}
-void *avi_converter_from_mjpeg(AviMovie *movie,
- int stream,
- unsigned char *buffer,
- const size_t *size)
+void *avi_converter_from_mjpeg(AviMovie *movie, int stream, uchar *buffer, const size_t *size)
{
int deint;
- unsigned char *buf;
+ uchar *buf;
(void)stream; /* unused */
buf = imb_alloc_pixels(movie->header->Height,
movie->header->Width,
3,
- sizeof(unsigned char),
+ sizeof(uchar),
"avi.avi_converter_from_mjpeg 1");
if (!buf) {
return NULL;
@@ -394,7 +381,7 @@ void *avi_converter_from_mjpeg(AviMovie *movie,
buffer = imb_alloc_pixels(movie->header->Height,
movie->header->Width,
3,
- sizeof(unsigned char),
+ sizeof(uchar),
"avi.avi_converter_from_mjpeg 2");
if (buffer) {
interlace(buffer, buf, movie->header->Width, movie->header->Height);
@@ -407,9 +394,9 @@ void *avi_converter_from_mjpeg(AviMovie *movie,
return buf;
}
-void *avi_converter_to_mjpeg(AviMovie *movie, int stream, unsigned char *buffer, size_t *size)
+void *avi_converter_to_mjpeg(AviMovie *movie, int stream, uchar *buffer, size_t *size)
{
- unsigned char *buf;
+ uchar *buf;
size_t bufsize = *size;
numbytes = 0;
@@ -418,7 +405,7 @@ void *avi_converter_to_mjpeg(AviMovie *movie, int stream, unsigned char *buffer,
buf = imb_alloc_pixels(movie->header->Height,
movie->header->Width,
3,
- sizeof(unsigned char),
+ sizeof(uchar),
"avi.avi_converter_to_mjpeg 1");
if (!buf) {
return NULL;
@@ -441,7 +428,7 @@ void *avi_converter_to_mjpeg(AviMovie *movie, int stream, unsigned char *buffer,
buf = imb_alloc_pixels(movie->header->Height,
movie->header->Width,
3,
- sizeof(unsigned char),
+ sizeof(uchar),
"avi.avi_converter_to_mjpeg 1");
if (buf) {
@@ -488,7 +475,7 @@ static void jpegmemdestmgr_term_destination(j_compress_ptr cinfo)
MEM_freeN(cinfo->dest);
}
-static void jpegmemdestmgr_build(j_compress_ptr cinfo, unsigned char *buffer, size_t bufsize)
+static void jpegmemdestmgr_build(j_compress_ptr cinfo, uchar *buffer, size_t bufsize)
{
cinfo->dest = MEM_mallocN(sizeof(*(cinfo->dest)), "avi.jpegmemdestmgr_build");
@@ -511,7 +498,7 @@ static void jpegmemsrcmgr_init_source(j_decompress_ptr dinfo)
static boolean jpegmemsrcmgr_fill_input_buffer(j_decompress_ptr dinfo)
{
- unsigned char *buf = (unsigned char *)dinfo->src->next_input_byte - 2;
+ uchar *buf = (uchar *)dinfo->src->next_input_byte - 2;
/* if we get called, must have run out of data */
WARNMS(dinfo, JWRN_JPEG_EOF);
@@ -542,9 +529,7 @@ static void jpegmemsrcmgr_term_source(j_decompress_ptr dinfo)
MEM_freeN(dinfo->src);
}
-static void jpegmemsrcmgr_build(j_decompress_ptr dinfo,
- const unsigned char *buffer,
- size_t bufsize)
+static void jpegmemsrcmgr_build(j_decompress_ptr dinfo, const uchar *buffer, size_t bufsize)
{
dinfo->src = MEM_mallocN(sizeof(*(dinfo->src)), "avi.jpegmemsrcmgr_build");
diff --git a/source/blender/io/avi/intern/avi_mjpeg.h b/source/blender/io/avi/intern/avi_mjpeg.h
index 79fa0fe9995..aa74d771646 100644
--- a/source/blender/io/avi/intern/avi_mjpeg.h
+++ b/source/blender/io/avi/intern/avi_mjpeg.h
@@ -7,8 +7,5 @@
#pragma once
-void *avi_converter_from_mjpeg(AviMovie *movie,
- int stream,
- unsigned char *buffer,
- const size_t *size);
-void *avi_converter_to_mjpeg(AviMovie *movie, int stream, unsigned char *buffer, size_t *size);
+void *avi_converter_from_mjpeg(AviMovie *movie, int stream, uchar *buffer, const size_t *size);
+void *avi_converter_to_mjpeg(AviMovie *movie, int stream, uchar *buffer, size_t *size);
diff --git a/source/blender/io/avi/intern/avi_rgb.c b/source/blender/io/avi/intern/avi_rgb.c
index ffc3d0477fa..71022361df1 100644
--- a/source/blender/io/avi/intern/avi_rgb.c
+++ b/source/blender/io/avi/intern/avi_rgb.c
@@ -21,12 +21,9 @@
/* implementation */
-void *avi_converter_from_avi_rgb(AviMovie *movie,
- int stream,
- unsigned char *buffer,
- const size_t *size)
+void *avi_converter_from_avi_rgb(AviMovie *movie, int stream, uchar *buffer, const size_t *size)
{
- unsigned char *buf;
+ uchar *buf;
AviBitmapInfoHeader *bi;
short bits = 32;
@@ -38,24 +35,24 @@ void *avi_converter_from_avi_rgb(AviMovie *movie,
}
if (bits == 16) {
- unsigned short *pxl;
- unsigned char *to;
+ ushort *pxl;
+ uchar *to;
#ifdef __BIG_ENDIAN__
- unsigned char *pxla;
+ uchar *pxla;
#endif
buf = imb_alloc_pixels(
- movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "fromavirgbbuf");
+ movie->header->Height, movie->header->Width, 3, sizeof(uchar), "fromavirgbbuf");
if (buf) {
size_t y = movie->header->Height;
to = buf;
while (y--) {
- pxl = (unsigned short *)(buffer + y * movie->header->Width * 2);
+ pxl = (ushort *)(buffer + y * movie->header->Width * 2);
#ifdef __BIG_ENDIAN__
- pxla = (unsigned char *)pxl;
+ pxla = (uchar *)pxl;
#endif
size_t x = movie->header->Width;
@@ -82,7 +79,7 @@ void *avi_converter_from_avi_rgb(AviMovie *movie,
}
buf = imb_alloc_pixels(
- movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "fromavirgbbuf");
+ movie->header->Height, movie->header->Width, 3, sizeof(uchar), "fromavirgbbuf");
if (buf) {
size_t rowstride = movie->header->Width * 3;
@@ -110,9 +107,9 @@ void *avi_converter_from_avi_rgb(AviMovie *movie,
return buf;
}
-void *avi_converter_to_avi_rgb(AviMovie *movie, int stream, unsigned char *buffer, size_t *size)
+void *avi_converter_to_avi_rgb(AviMovie *movie, int stream, uchar *buffer, size_t *size)
{
- unsigned char *buf;
+ uchar *buf;
(void)stream; /* unused */
diff --git a/source/blender/io/avi/intern/avi_rgb32.c b/source/blender/io/avi/intern/avi_rgb32.c
index 84ae023fcdd..fcb83ffe47d 100644
--- a/source/blender/io/avi/intern/avi_rgb32.c
+++ b/source/blender/io/avi/intern/avi_rgb32.c
@@ -17,15 +17,15 @@
#include "AVI_avi.h"
#include "avi_rgb32.h"
-void *avi_converter_from_rgb32(AviMovie *movie, int stream, unsigned char *buffer, size_t *size)
+void *avi_converter_from_rgb32(AviMovie *movie, int stream, uchar *buffer, size_t *size)
{
- unsigned char *buf;
+ uchar *buf;
(void)stream; /* unused */
*size = (size_t)movie->header->Height * (size_t)movie->header->Width * 3;
buf = imb_alloc_pixels(
- movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "fromrgb32buf");
+ movie->header->Height, movie->header->Width, 3, sizeof(uchar), "fromrgb32buf");
if (!buf) {
return NULL;
}
@@ -46,16 +46,16 @@ void *avi_converter_from_rgb32(AviMovie *movie, int stream, unsigned char *buffe
return buf;
}
-void *avi_converter_to_rgb32(AviMovie *movie, int stream, unsigned char *buffer, size_t *size)
+void *avi_converter_to_rgb32(AviMovie *movie, int stream, uchar *buffer, size_t *size)
{
- unsigned char *buf;
- unsigned char *to, *from;
+ uchar *buf;
+ uchar *to, *from;
(void)stream; /* unused */
*size = (size_t)movie->header->Height * (size_t)movie->header->Width * 4;
buf = imb_alloc_pixels(
- movie->header->Height, movie->header->Width, 4, sizeof(unsigned char), "torgb32buf");
+ movie->header->Height, movie->header->Width, 4, sizeof(uchar), "torgb32buf");
if (!buf) {
return NULL;
}
diff --git a/source/blender/io/collada/AnimationExporter.cpp b/source/blender/io/collada/AnimationExporter.cpp
index 7df9df1f460..24d2072f840 100644
--- a/source/blender/io/collada/AnimationExporter.cpp
+++ b/source/blender/io/collada/AnimationExporter.cpp
@@ -43,7 +43,8 @@ bool AnimationExporter::open_animation_container(bool has_container, Object *ob)
{
if (!has_container) {
char anim_id[200];
- sprintf(anim_id, "action_container-%s", translate_id(id_name(ob)).c_str());
+ BLI_snprintf(
+ anim_id, sizeof(anim_id), "action_container-%s", translate_id(id_name(ob)).c_str());
openAnimation(anim_id, encode_xml(id_name(ob)));
}
return true;
@@ -687,7 +688,7 @@ std::string AnimationExporter::collada_interpolation_source(const BCAnimationCur
std::vector<float> frames;
curve.get_frames(frames);
- for (unsigned int i = 0; i < curve.sample_count(); i++) {
+ for (uint i = 0; i < curve.sample_count(); i++) {
float frame = frames[i];
int ipo = curve.get_interpolation_type(frame);
if (ipo == BEZT_IPO_BEZ) {
diff --git a/source/blender/io/collada/AnimationImporter.cpp b/source/blender/io/collada/AnimationImporter.cpp
index cc91c3eeac9..826d7864067 100644
--- a/source/blender/io/collada/AnimationImporter.cpp
+++ b/source/blender/io/collada/AnimationImporter.cpp
@@ -55,7 +55,7 @@ void AnimationImporter::add_bezt(FCurve *fcu,
float value,
eBezTriple_Interpolation ipo)
{
- // float fps = (float)FPS;
+ // float fps = float(FPS);
BezTriple bez;
memset(&bez, 0, sizeof(BezTriple));
bez.vec[1][0] = frame;
@@ -72,9 +72,9 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
COLLADAFW::FloatOrDoubleArray &input = curve->getInputValues();
COLLADAFW::FloatOrDoubleArray &output = curve->getOutputValues();
- float fps = (float)FPS;
+ float fps = float(FPS);
size_t dim = curve->getOutDimension();
- unsigned int i;
+ uint i;
std::vector<FCurve *> &fcurves = curve_map[curve->getUniqueId()];
@@ -91,7 +91,7 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
fcu->array_index = 0;
fcu->auto_smoothing = U.auto_smoothing_new;
- for (unsigned int j = 0; j < curve->getKeyCount(); j++) {
+ for (uint j = 0; j < curve->getKeyCount(); j++) {
BezTriple bez;
memset(&bez, 0, sizeof(BezTriple));
@@ -106,7 +106,7 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
COLLADAFW::FloatOrDoubleArray &outtan = curve->getOutTangentValues();
/* In-tangent. */
- unsigned int index = 2 * (j * dim + i);
+ uint index = 2 * (j * dim + i);
bez.vec[0][0] = bc_get_float_value(intan, index) * fps;
bez.vec[0][1] = bc_get_float_value(intan, index + 1);
@@ -141,14 +141,14 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
default:
fprintf(stderr,
"Output dimension of %d is not yet supported (animation id = %s)\n",
- (int)dim,
+ int(dim),
curve->getOriginalId().c_str());
}
}
void AnimationImporter::fcurve_deg_to_rad(FCurve *cu)
{
- for (unsigned int i = 0; i < cu->totvert; i++) {
+ for (uint i = 0; i < cu->totvert; i++) {
/* TODO: convert handles too. */
cu->bezt[i].vec[1][1] *= DEG2RADF(1.0f);
cu->bezt[i].vec[0][1] *= DEG2RADF(1.0f);
@@ -158,7 +158,7 @@ void AnimationImporter::fcurve_deg_to_rad(FCurve *cu)
void AnimationImporter::fcurve_scale(FCurve *cu, int scale)
{
- for (unsigned int i = 0; i < cu->totvert; i++) {
+ for (uint i = 0; i < cu->totvert; i++) {
/* TODO: convert handles too. */
cu->bezt[i].vec[1][1] *= scale;
cu->bezt[i].vec[0][1] *= scale;
@@ -262,7 +262,7 @@ AnimationImporter::~AnimationImporter()
}
if (!unused_curves.empty()) {
- fprintf(stderr, "removed %d unused curves\n", (int)unused_curves.size());
+ fprintf(stderr, "removed %d unused curves\n", int(unused_curves.size()));
}
}
@@ -332,8 +332,8 @@ void AnimationImporter::read_node_transform(COLLADAFW::Node *node, Object *ob)
float mat[4][4];
TransformReader::get_node_mat(mat, node, &uid_animated_map, ob);
if (ob) {
- copy_m4_m4(ob->obmat, mat);
- BKE_object_apply_mat4(ob, ob->obmat, false, false);
+ copy_m4_m4(ob->object_to_world, mat);
+ BKE_object_apply_mat4(ob, ob->object_to_world, false, false);
}
}
@@ -484,7 +484,7 @@ void AnimationImporter::find_frames(std::vector<float> *frames, std::vector<FCur
for (iter = curves->begin(); iter != curves->end(); iter++) {
FCurve *fcu = *iter;
- for (unsigned int k = 0; k < fcu->totvert; k++) {
+ for (uint k = 0; k < fcu->totvert; k++) {
/* get frame value from bezTriple */
float fra = fcu->bezt[k].vec[1][0];
/* if frame already not added add frame to frames */
@@ -525,12 +525,12 @@ void AnimationImporter::Assign_transform_animations(
bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
/* to check if the no of curves are valid */
- bool xyz = ((tm_type == COLLADAFW::Transformation::TRANSLATE ||
- tm_type == COLLADAFW::Transformation::SCALE) &&
- binding->animationClass == COLLADAFW::AnimationList::POSITION_XYZ);
+ bool xyz =
+ (ELEM(tm_type, COLLADAFW::Transformation::TRANSLATE, COLLADAFW::Transformation::SCALE) &&
+ binding->animationClass == COLLADAFW::AnimationList::POSITION_XYZ);
if (!((!xyz && curves->size() == 1) || (xyz && curves->size() == 3) || is_matrix)) {
- fprintf(stderr, "expected %d curves, got %d\n", xyz ? 3 : 1, (int)curves->size());
+ fprintf(stderr, "expected %d curves, got %d\n", xyz ? 3 : 1, int(curves->size()));
return;
}
@@ -649,7 +649,7 @@ void AnimationImporter::Assign_color_animations(const COLLADAFW::UniqueId &listi
const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings();
/* all the curves belonging to the current binding */
std::vector<FCurve *> animcurves;
- for (unsigned int j = 0; j < bindings.getCount(); j++) {
+ for (uint j = 0; j < bindings.getCount(); j++) {
animcurves = curve_map[bindings[j].animation];
switch (bindings[j].animationClass) {
@@ -699,7 +699,7 @@ void AnimationImporter::Assign_float_animations(const COLLADAFW::UniqueId &listi
const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings();
/* all the curves belonging to the current binding */
std::vector<FCurve *> animcurves;
- for (unsigned int j = 0; j < bindings.getCount(); j++) {
+ for (uint j = 0; j < bindings.getCount(); j++) {
animcurves = curve_map[bindings[j].animation];
BLI_strncpy(rna_path, anim_type, sizeof(rna_path));
@@ -756,7 +756,7 @@ void AnimationImporter::Assign_lens_animations(const COLLADAFW::UniqueId &listid
const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings();
/* all the curves belonging to the current binding */
std::vector<FCurve *> animcurves;
- for (unsigned int j = 0; j < bindings.getCount(); j++) {
+ for (uint j = 0; j < bindings.getCount(); j++) {
animcurves = curve_map[bindings[j].animation];
BLI_strncpy(rna_path, anim_type, sizeof(rna_path));
@@ -767,7 +767,7 @@ void AnimationImporter::Assign_lens_animations(const COLLADAFW::UniqueId &listid
for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
FCurve *fcu = *iter;
- for (unsigned int i = 0; i < fcu->totvert; i++) {
+ for (uint i = 0; i < fcu->totvert; i++) {
fcu->bezt[i].vec[0][1] = convert_to_focal_length(
fcu->bezt[i].vec[0][1], fov_type, aspect, cam->sensor_x);
fcu->bezt[i].vec[1][1] = convert_to_focal_length(
@@ -817,7 +817,7 @@ void AnimationImporter::apply_matrix_curves(Object *ob,
}
/* new curves to assign matrix transform animation */
FCurve *newcu[10]; /* if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale */
- unsigned int totcu = 10;
+ uint totcu = 10;
const char *tm_str = nullptr;
char rna_path[200];
for (int i = 0; i < totcu; i++) {
@@ -1033,7 +1033,7 @@ void AnimationImporter::translate_Animations(
const COLLADAFW::TransformationPointerArray &nodeTransforms = node->getTransformations();
/* for each transformation in node */
- for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) {
+ for (uint i = 0; i < nodeTransforms.getCount(); i++) {
COLLADAFW::Transformation *transform = nodeTransforms[i];
COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType();
@@ -1053,7 +1053,7 @@ void AnimationImporter::translate_Animations(
animlist->getAnimationBindings();
/* all the curves belonging to the current binding */
std::vector<FCurve *> animcurves;
- for (unsigned int j = 0; j < bindings.getCount(); j++) {
+ for (uint j = 0; j < bindings.getCount(); j++) {
animcurves = curve_map[bindings[j].animation];
if (is_matrix) {
apply_matrix_curves(ob, animcurves, root, node, transform);
@@ -1092,7 +1092,7 @@ void AnimationImporter::translate_Animations(
ListBase *AnimCurves = &(act->curves);
const COLLADAFW::InstanceLightPointerArray &nodeLights = node->getInstanceLights();
- for (unsigned int i = 0; i < nodeLights.getCount(); i++) {
+ for (uint i = 0; i < nodeLights.getCount(); i++) {
const COLLADAFW::Light *light = (COLLADAFW::Light *)
FW_object_map[nodeLights[i]->getInstanciatedObjectId()];
@@ -1130,7 +1130,7 @@ void AnimationImporter::translate_Animations(
ListBase *AnimCurves = &(act->curves);
const COLLADAFW::InstanceCameraPointerArray &nodeCameras = node->getInstanceCameras();
- for (unsigned int i = 0; i < nodeCameras.getCount(); i++) {
+ for (uint i = 0; i < nodeCameras.getCount(); i++) {
const COLLADAFW::Camera *camera = (COLLADAFW::Camera *)
FW_object_map[nodeCameras[i]->getInstanciatedObjectId()];
@@ -1184,9 +1184,9 @@ void AnimationImporter::translate_Animations(
}
const COLLADAFW::InstanceGeometryPointerArray &nodeGeoms = node->getInstanceGeometries();
- for (unsigned int i = 0; i < nodeGeoms.getCount(); i++) {
+ for (uint i = 0; i < nodeGeoms.getCount(); i++) {
const COLLADAFW::MaterialBindingArray &matBinds = nodeGeoms[i]->getMaterialBindings();
- for (unsigned int j = 0; j < matBinds.getCount(); j++) {
+ for (uint j = 0; j < matBinds.getCount(); j++) {
const COLLADAFW::UniqueId &matuid = matBinds[j].getReferencedMaterial();
const COLLADAFW::Effect *ef = (COLLADAFW::Effect *)(FW_object_map[matuid]);
if (ef != nullptr) { /* can be NULL T28909. */
@@ -1273,7 +1273,7 @@ void AnimationImporter::add_bone_animation_sampled(Object *ob,
/* new curves to assign matrix transform animation */
FCurve *newcu[10]; /* if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale. */
- unsigned int totcu = 10;
+ uint totcu = 10;
const char *tm_str = nullptr;
char rna_path[200];
for (int i = 0; i < totcu; i++) {
@@ -1381,7 +1381,7 @@ AnimationImporter::AnimMix *AnimationImporter::get_animation_type(
const COLLADAFW::TransformationPointerArray &nodeTransforms = node->getTransformations();
/* for each transformation in node */
- for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) {
+ for (uint i = 0; i < nodeTransforms.getCount(); i++) {
COLLADAFW::Transformation *transform = nodeTransforms[i];
const COLLADAFW::UniqueId &listid = transform->getAnimationList();
@@ -1395,7 +1395,7 @@ AnimationImporter::AnimMix *AnimationImporter::get_animation_type(
}
const COLLADAFW::InstanceLightPointerArray &nodeLights = node->getInstanceLights();
- for (unsigned int i = 0; i < nodeLights.getCount(); i++) {
+ for (uint i = 0; i < nodeLights.getCount(); i++) {
const COLLADAFW::Light *light = (COLLADAFW::Light *)
FW_object_map[nodeLights[i]->getInstanciatedObjectId()];
types->light = setAnimType(&(light->getColor()), (types->light), LIGHT_COLOR);
@@ -1408,7 +1408,7 @@ AnimationImporter::AnimMix *AnimationImporter::get_animation_type(
}
const COLLADAFW::InstanceCameraPointerArray &nodeCameras = node->getInstanceCameras();
- for (unsigned int i = 0; i < nodeCameras.getCount(); i++) {
+ for (uint i = 0; i < nodeCameras.getCount(); i++) {
const COLLADAFW::Camera *camera = (COLLADAFW::Camera *)
FW_object_map[nodeCameras[i]->getInstanciatedObjectId()];
if (camera == nullptr) {
@@ -1440,9 +1440,9 @@ AnimationImporter::AnimMix *AnimationImporter::get_animation_type(
}
const COLLADAFW::InstanceGeometryPointerArray &nodeGeoms = node->getInstanceGeometries();
- for (unsigned int i = 0; i < nodeGeoms.getCount(); i++) {
+ for (uint i = 0; i < nodeGeoms.getCount(); i++) {
const COLLADAFW::MaterialBindingArray &matBinds = nodeGeoms[i]->getMaterialBindings();
- for (unsigned int j = 0; j < matBinds.getCount(); j++) {
+ for (uint j = 0; j < matBinds.getCount(); j++) {
const COLLADAFW::UniqueId &matuid = matBinds[j].getReferencedMaterial();
const COLLADAFW::Effect *ef = (COLLADAFW::Effect *)(FW_object_map[matuid]);
if (ef != nullptr) { /* can be NULL T28909. */
@@ -1490,7 +1490,7 @@ void AnimationImporter::find_frames_old(std::vector<float> *frames,
/* for each <rotate>, <translate>, etc. there is a separate Transformation */
const COLLADAFW::TransformationPointerArray &nodeTransforms = node->getTransformations();
- unsigned int i;
+ uint i;
/* find frames at which to sample plus convert all rotation keys to radians */
for (i = 0; i < nodeTransforms.getCount(); i++) {
COLLADAFW::Transformation *transform = nodeTransforms[i];
@@ -1508,10 +1508,11 @@ void AnimationImporter::find_frames_old(std::vector<float> *frames,
if (bindings.getCount()) {
/* for each AnimationBinding get the fcurves which animate the transform */
- for (unsigned int j = 0; j < bindings.getCount(); j++) {
+ for (uint j = 0; j < bindings.getCount(); j++) {
std::vector<FCurve *> &curves = curve_map[bindings[j].animation];
- bool xyz = ((nodeTmType == COLLADAFW::Transformation::TRANSLATE ||
- nodeTmType == COLLADAFW::Transformation::SCALE) &&
+ bool xyz = (ELEM(nodeTmType,
+ COLLADAFW::Transformation::TRANSLATE,
+ COLLADAFW::Transformation::SCALE) &&
bindings[j].animationClass == COLLADAFW::AnimationList::POSITION_XYZ);
if ((!xyz && curves.size() == 1) || (xyz && curves.size() == 3) || is_matrix) {
@@ -1525,7 +1526,7 @@ void AnimationImporter::find_frames_old(std::vector<float> *frames,
fcurve_deg_to_rad(fcu);
}
- for (unsigned int k = 0; k < fcu->totvert; k++) {
+ for (uint k = 0; k < fcu->totvert; k++) {
/* get frame value from bezTriple */
float fra = fcu->bezt[k].vec[1][0];
/* if frame already not added add frame to frames */
@@ -1536,7 +1537,7 @@ void AnimationImporter::find_frames_old(std::vector<float> *frames,
}
}
else {
- fprintf(stderr, "expected %d curves, got %d\n", xyz ? 3 : 1, (int)curves.size());
+ fprintf(stderr, "expected %d curves, got %d\n", xyz ? 3 : 1, int(curves.size()));
}
}
}
@@ -1573,7 +1574,7 @@ Object *AnimationImporter::translate_animation_OLD(
find_frames_old(&frames, node, tm_type);
- unsigned int i;
+ uint i;
float irest_dae[4][4];
float rest[4][4], irest[4][4];
@@ -1632,7 +1633,7 @@ Object *AnimationImporter::translate_animation_OLD(
/* new curves */
FCurve *newcu[10]; /* if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale */
- unsigned int totcu = is_matrix ? 10 : (is_rotation ? 4 : 3);
+ uint totcu = is_matrix ? 10 : (is_rotation ? 4 : 3);
for (i = 0; i < totcu; i++) {
@@ -1825,7 +1826,7 @@ void AnimationImporter::evaluate_transform_at_frame(float mat[4][4],
unit_m4(mat);
- for (unsigned int i = 0; i < tms.getCount(); i++) {
+ for (uint i = 0; i < tms.getCount(); i++) {
COLLADAFW::Transformation *tm = tms[i];
COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
float m[4][4];
@@ -1883,8 +1884,11 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm,
const COLLADAFW::UniqueId &listid = tm->getAnimationList();
COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
- if (type != COLLADAFW::Transformation::ROTATE && type != COLLADAFW::Transformation::SCALE &&
- type != COLLADAFW::Transformation::TRANSLATE && type != COLLADAFW::Transformation::MATRIX) {
+ if (!ELEM(type,
+ COLLADAFW::Transformation::ROTATE,
+ COLLADAFW::Transformation::SCALE,
+ COLLADAFW::Transformation::TRANSLATE,
+ COLLADAFW::Transformation::MATRIX)) {
fprintf(stderr, "animation of transformation %d is not supported yet\n", type);
return false;
}
@@ -1909,7 +1913,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm,
dae_translate_to_v3(tm, vec);
}
- for (unsigned int index = 0; index < bindings.getCount(); index++) {
+ for (uint index = 0; index < bindings.getCount(); index++) {
const COLLADAFW::AnimationList::AnimationBinding &binding = bindings[index];
std::vector<FCurve *> &curves = curve_map[binding.animation];
COLLADAFW::AnimationList::AnimationClass animclass = binding.animationClass;
@@ -1934,7 +1938,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm,
if (type == COLLADAFW::Transformation::ROTATE) {
if (curves.size() != 1) {
- fprintf(stderr, "expected 1 curve, got %d\n", (int)curves.size());
+ fprintf(stderr, "expected 1 curve, got %d\n", int(curves.size()));
return false;
}
@@ -1946,7 +1950,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm,
COLLADABU::Math::Vector3 &axis = ((COLLADAFW::Rotate *)tm)->getRotationAxis();
- float ax[3] = {(float)axis[0], (float)axis[1], (float)axis[2]};
+ float ax[3] = {float(axis[0]), float(axis[1]), float(axis[2])};
float angle = evaluate_fcurve(curves[0], fra);
axis_angle_to_mat4(mat, ax, angle);
@@ -1957,10 +1961,10 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm,
if ((!is_xyz && curves.size() != 1) || (is_xyz && curves.size() != 3)) {
if (is_xyz) {
- fprintf(stderr, "%s: expected 3 curves, got %d\n", path, (int)curves.size());
+ fprintf(stderr, "%s: expected 3 curves, got %d\n", path, int(curves.size()));
}
else {
- fprintf(stderr, "%s: expected 1 curve, got %d\n", path, (int)curves.size());
+ fprintf(stderr, "%s: expected 1 curve, got %d\n", path, int(curves.size()));
}
return false;
}
@@ -1989,7 +1993,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm,
/* for now, of matrix animation,
* support only the case when all values are packed into one animation */
if (curves.size() != 16) {
- fprintf(stderr, "%s: expected 16 curves, got %d\n", path, (int)curves.size());
+ fprintf(stderr, "%s: expected 16 curves, got %d\n", path, int(curves.size()));
return false;
}
@@ -2062,7 +2066,7 @@ bool AnimationImporter::calc_joint_parent_mat_rest(float mat[4][4],
}
COLLADAFW::NodePointerArray &children = node->getChildNodes();
- for (unsigned int i = 0; i < children.getCount(); i++) {
+ for (uint i = 0; i < children.getCount(); i++) {
if (calc_joint_parent_mat_rest(mat, m, children[i], end)) {
return true;
}
@@ -2093,7 +2097,7 @@ Object *AnimationImporter::get_joint_object(COLLADAFW::Node *root,
if (par_job) {
float temp[4][4], ipar[4][4];
- invert_m4_m4(ipar, par_job->obmat);
+ invert_m4_m4(ipar, par_job->object_to_world);
copy_m4_m4(temp, mat);
mul_m4_m4m4(mat, ipar, temp);
}
diff --git a/source/blender/io/collada/ArmatureImporter.cpp b/source/blender/io/collada/ArmatureImporter.cpp
index f056488fe93..7de08f89b7d 100644
--- a/source/blender/io/collada/ArmatureImporter.cpp
+++ b/source/blender/io/collada/ArmatureImporter.cpp
@@ -114,7 +114,7 @@ int ArmatureImporter::create_bone(SkinInfo *skin,
Object *ob_arm = skin->BKE_armature_from_object();
if (ob_arm) {
float invmat[4][4];
- invert_m4_m4(invmat, ob_arm->obmat);
+ invert_m4_m4(invmat, ob_arm->object_to_world);
mul_m4_m4m4(mat, invmat, mat);
}
@@ -190,7 +190,7 @@ int ArmatureImporter::create_bone(SkinInfo *skin,
COLLADAFW::NodePointerArray &children = node->getChildNodes();
- for (unsigned int i = 0; i < children.getCount(); i++) {
+ for (uint i = 0; i < children.getCount(); i++) {
int cl = create_bone(skin, children[i], bone, children.getCount(), mat, arm, layer_labels);
if (cl > chain_length) {
chain_length = cl;
@@ -708,7 +708,7 @@ void ArmatureImporter::set_pose(Object *ob_arm,
copy_m4_m4(mat, obmat);
float invObmat[4][4];
- invert_m4_m4(invObmat, ob_arm->obmat);
+ invert_m4_m4(invObmat, ob_arm->object_to_world);
mul_m4_m4m4(pchan->pose_mat, invObmat, mat);
}
@@ -719,7 +719,7 @@ void ArmatureImporter::set_pose(Object *ob_arm,
#endif
COLLADAFW::NodePointerArray &children = root_node->getChildNodes();
- for (unsigned int i = 0; i < children.getCount(); i++) {
+ for (uint i = 0; i < children.getCount(); i++) {
set_pose(ob_arm, children[i], bone_name, mat);
}
}
@@ -727,7 +727,7 @@ void ArmatureImporter::set_pose(Object *ob_arm,
bool ArmatureImporter::node_is_decomposed(const COLLADAFW::Node *node)
{
const COLLADAFW::TransformationPointerArray &nodeTransforms = node->getTransformations();
- for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) {
+ for (uint i = 0; i < nodeTransforms.getCount(); i++) {
COLLADAFW::Transformation *transform = nodeTransforms[i];
COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType();
if (tm_type == COLLADAFW::Transformation::MATRIX) {
@@ -879,7 +879,7 @@ bool ArmatureImporter::write_skin_controller_data(const COLLADAFW::SkinControlle
/* store join inv bind matrix to use it later in armature construction */
const COLLADAFW::Matrix4Array &inv_bind_mats = data->getInverseBindMatrices();
- for (unsigned int i = 0; i < data->getJointsCount(); i++) {
+ for (uint i = 0; i < data->getJointsCount(); i++) {
skin.add_joint(inv_bind_mats[i]);
}
diff --git a/source/blender/io/collada/BCAnimationCurve.cpp b/source/blender/io/collada/BCAnimationCurve.cpp
index fe90dc5d5fa..ac7fa81883a 100644
--- a/source/blender/io/collada/BCAnimationCurve.cpp
+++ b/source/blender/io/collada/BCAnimationCurve.cpp
@@ -329,8 +329,7 @@ bool BCAnimationCurve::is_transform_curve() const
bool BCAnimationCurve::is_rotation_curve() const
{
std::string channel_type = this->get_channel_type();
- return (channel_type == "rotation" || channel_type == "rotation_euler" ||
- channel_type == "rotation_quaternion");
+ return ELEM(channel_type, "rotation", "rotation_euler", "rotation_quaternion");
}
float BCAnimationCurve::get_value(const float frame)
@@ -426,10 +425,10 @@ bool BCAnimationCurve::add_value_from_rna(const int frame_index)
if ((array_index >= 0) && (array_index < RNA_property_array_length(&ptr, prop))) {
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
- value = (float)RNA_property_boolean_get_index(&ptr, prop, array_index);
+ value = float(RNA_property_boolean_get_index(&ptr, prop, array_index));
break;
case PROP_INT:
- value = (float)RNA_property_int_get_index(&ptr, prop, array_index);
+ value = float(RNA_property_int_get_index(&ptr, prop, array_index));
break;
case PROP_FLOAT:
value = RNA_property_float_get_index(&ptr, prop, array_index);
@@ -449,16 +448,16 @@ bool BCAnimationCurve::add_value_from_rna(const int frame_index)
/* not an array */
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
- value = (float)RNA_property_boolean_get(&ptr, prop);
+ value = float(RNA_property_boolean_get(&ptr, prop));
break;
case PROP_INT:
- value = (float)RNA_property_int_get(&ptr, prop);
+ value = float(RNA_property_int_get(&ptr, prop));
break;
case PROP_FLOAT:
value = RNA_property_float_get(&ptr, prop);
break;
case PROP_ENUM:
- value = (float)RNA_property_enum_get(&ptr, prop);
+ value = float(RNA_property_enum_get(&ptr, prop));
break;
default:
fprintf(stderr,
diff --git a/source/blender/io/collada/BCMath.cpp b/source/blender/io/collada/BCMath.cpp
index d48e46ca115..6e052ee960d 100644
--- a/source/blender/io/collada/BCMath.cpp
+++ b/source/blender/io/collada/BCMath.cpp
@@ -140,9 +140,9 @@ void BCMatrix::sanitize(Matrix &mat, int precision)
{
for (auto &row : mat) {
for (float &cell : row) {
- double val = (double)cell;
+ double val = double(cell);
val = double_round(val, precision);
- cell = (float)val;
+ cell = float(val);
}
}
}
@@ -169,7 +169,7 @@ void BCMatrix::get_matrix(DMatrix &mat, const bool transposed, const int precisi
for (int j = 0; j < 4; j++) {
float val = (transposed) ? matrix[j][i] : matrix[i][j];
if (precision >= 0) {
- val = floor((val * pow(10, precision) + 0.5)) / pow(10, precision);
+ val = floor(val * pow(10, precision) + 0.5) / pow(10, precision);
}
mat[i][j] = val;
}
@@ -185,7 +185,7 @@ void BCMatrix::get_matrix(Matrix &mat,
for (int j = 0; j < 4; j++) {
float val = (transposed) ? matrix[j][i] : matrix[i][j];
if (precision >= 0) {
- val = floor((val * pow(10, precision) + 0.5)) / pow(10, precision);
+ val = floor(val * pow(10, precision) + 0.5) / pow(10, precision);
}
mat[i][j] = val;
}
diff --git a/source/blender/io/collada/BCSampleData.cpp b/source/blender/io/collada/BCSampleData.cpp
index 42b436ec6fb..422ecdc598f 100644
--- a/source/blender/io/collada/BCSampleData.cpp
+++ b/source/blender/io/collada/BCSampleData.cpp
@@ -51,7 +51,7 @@ bool BCSample::get_value(std::string channel_target, const int array_index, floa
else if (channel_type == "scale") {
*val = matrix->scale()[array_index];
}
- else if (channel_type == "rotation" || channel_type == "rotation_euler") {
+ else if (ELEM(channel_type, "rotation", "rotation_euler")) {
*val = matrix->rotation()[array_index];
}
else if (channel_type == "rotation_quaternion") {
diff --git a/source/blender/io/collada/BlenderContext.cpp b/source/blender/io/collada/BlenderContext.cpp
index 5f54f38a0ab..807488233ce 100644
--- a/source/blender/io/collada/BlenderContext.cpp
+++ b/source/blender/io/collada/BlenderContext.cpp
@@ -9,21 +9,25 @@
#include "BlenderContext.h"
#include "ExportSettings.h"
+#include "BKE_layer.h"
#include "BKE_scene.h"
-bool bc_is_base_node(LinkNode *export_set, Object *ob, ViewLayer *view_layer)
+#include "BLI_listbase.h"
+
+bool bc_is_base_node(LinkNode *export_set, Object *ob, const Scene *scene, ViewLayer *view_layer)
{
- Object *root = bc_get_highest_exported_ancestor_or_self(export_set, ob, view_layer);
+ Object *root = bc_get_highest_exported_ancestor_or_self(export_set, ob, scene, view_layer);
return (root == ob);
}
Object *bc_get_highest_exported_ancestor_or_self(LinkNode *export_set,
Object *ob,
+ const Scene *scene,
ViewLayer *view_layer)
{
Object *ancestor = ob;
while (ob->parent) {
- if (bc_is_in_Export_set(export_set, ob->parent, view_layer)) {
+ if (bc_is_in_Export_set(export_set, ob->parent, scene, view_layer)) {
ancestor = ob->parent;
}
ob = ob->parent;
@@ -31,10 +35,13 @@ Object *bc_get_highest_exported_ancestor_or_self(LinkNode *export_set,
return ancestor;
}
-void bc_get_children(std::vector<Object *> &child_set, Object *ob, ViewLayer *view_layer)
+void bc_get_children(std::vector<Object *> &child_set,
+ Object *ob,
+ const Scene *scene,
+ ViewLayer *view_layer)
{
- Base *base;
- for (base = (Base *)view_layer->object_bases.first; base; base = base->next) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *cob = base->object;
if (cob->parent == ob) {
switch (ob->type) {
@@ -51,7 +58,10 @@ void bc_get_children(std::vector<Object *> &child_set, Object *ob, ViewLayer *vi
}
}
-bool bc_is_in_Export_set(LinkNode *export_set, Object *ob, ViewLayer *view_layer)
+bool bc_is_in_Export_set(LinkNode *export_set,
+ Object *ob,
+ const Scene *scene,
+ ViewLayer *view_layer)
{
bool to_export = (BLI_linklist_index(export_set, ob) != -1);
@@ -60,9 +70,9 @@ bool bc_is_in_Export_set(LinkNode *export_set, Object *ob, ViewLayer *view_layer
* export list, but it contains children to export. */
std::vector<Object *> children;
- bc_get_children(children, ob, view_layer);
+ bc_get_children(children, ob, scene, view_layer);
for (Object *child : children) {
- if (bc_is_in_Export_set(export_set, child, view_layer)) {
+ if (bc_is_in_Export_set(export_set, child, scene, view_layer)) {
to_export = true;
break;
}
diff --git a/source/blender/io/collada/BlenderContext.h b/source/blender/io/collada/BlenderContext.h
index 6fdb043b3dc..8a782b74e52 100644
--- a/source/blender/io/collada/BlenderContext.h
+++ b/source/blender/io/collada/BlenderContext.h
@@ -22,8 +22,11 @@ extern "C" {
static const BC_global_forward_axis BC_DEFAULT_FORWARD = BC_GLOBAL_FORWARD_Y;
static const BC_global_up_axis BC_DEFAULT_UP = BC_GLOBAL_UP_Z;
-bool bc_is_in_Export_set(LinkNode *export_set, Object *ob, ViewLayer *view_layer);
-bool bc_is_base_node(LinkNode *export_set, Object *ob, ViewLayer *view_layer);
+bool bc_is_in_Export_set(LinkNode *export_set,
+ Object *ob,
+ const Scene *scene,
+ ViewLayer *view_layer);
+bool bc_is_base_node(LinkNode *export_set, Object *ob, const Scene *scene, ViewLayer *view_layer);
/**
* Returns the highest selected ancestor
* returns NULL if no ancestor is selected
@@ -32,6 +35,7 @@ bool bc_is_base_node(LinkNode *export_set, Object *ob, ViewLayer *view_layer);
*/
Object *bc_get_highest_exported_ancestor_or_self(LinkNode *export_set,
Object *ob,
+ const Scene *scene,
ViewLayer *view_layer);
int bc_is_marked(Object *ob);
void bc_remove_mark(Object *ob);
diff --git a/source/blender/io/collada/CMakeLists.txt b/source/blender/io/collada/CMakeLists.txt
index 3289a7c6e66..43cc0642921 100644
--- a/source/blender/io/collada/CMakeLists.txt
+++ b/source/blender/io/collada/CMakeLists.txt
@@ -2,7 +2,7 @@
# Copyright 2006 Blender Foundation. All rights reserved.
remove_strict_flags()
-FIND_FILE(OPENCOLLADA_ANIMATION_CLIP
+find_file(OPENCOLLADA_ANIMATION_CLIP
NAMES
COLLADAFWAnimationClip.h
PATHS
@@ -14,7 +14,7 @@ if(OPENCOLLADA_ANIMATION_CLIP)
add_definitions(-DWITH_OPENCOLLADA_ANIMATION_CLIP)
endif()
-# In cmake version 3.21 and up, we can instead use the NO_CACHE option for
+# In CMAKE version 3.21 and up, we can instead use the NO_CACHE option for
# find_file so we don't need to clear it from the cache here.
unset(OPENCOLLADA_ANIMATION_CLIP CACHE)
@@ -122,9 +122,4 @@ if(WITH_BUILDINFO)
add_definitions(-DWITH_BUILDINFO)
endif()
-if(CMAKE_COMPILER_IS_GNUCXX)
- # COLLADAFWArray.h gives error with gcc 4.5
- string(APPEND CMAKE_CXX_FLAGS " -fpermissive")
-endif()
-
blender_add_lib(bf_collada "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/io/collada/CameraExporter.cpp b/source/blender/io/collada/CameraExporter.cpp
index 45a73914256..7c3f304b722 100644
--- a/source/blender/io/collada/CameraExporter.cpp
+++ b/source/blender/io/collada/CameraExporter.cpp
@@ -51,7 +51,7 @@ void CamerasExporter::operator()(Object *ob, Scene *sce)
case CAM_PERSP: {
COLLADASW::PerspectiveOptic persp(mSW);
persp.setXFov(RAD2DEGF(focallength_to_fov(cam->lens, cam->sensor_x)), "xfov");
- persp.setAspectRatio((float)(sce->r.xsch) / (float)(sce->r.ysch), false, "aspect_ratio");
+ persp.setAspectRatio(float(sce->r.xsch) / float(sce->r.ysch), false, "aspect_ratio");
persp.setZFar(cam->clip_end, false, "zfar");
persp.setZNear(cam->clip_start, false, "znear");
COLLADASW::Camera ccam(mSW, &persp, cam_id, cam_name);
@@ -64,7 +64,7 @@ void CamerasExporter::operator()(Object *ob, Scene *sce)
default: {
COLLADASW::OrthographicOptic ortho(mSW);
ortho.setXMag(cam->ortho_scale / 2, "xmag");
- ortho.setAspectRatio((float)(sce->r.xsch) / (float)(sce->r.ysch), false, "aspect_ratio");
+ ortho.setAspectRatio(float(sce->r.xsch) / float(sce->r.ysch), false, "aspect_ratio");
ortho.setZFar(cam->clip_end, false, "zfar");
ortho.setZNear(cam->clip_start, false, "znear");
COLLADASW::Camera ccam(mSW, &ortho, cam_id, cam_name);
diff --git a/source/blender/io/collada/ControllerExporter.cpp b/source/blender/io/collada/ControllerExporter.cpp
index 6bf8d904a41..62bcdc5bf4c 100644
--- a/source/blender/io/collada/ControllerExporter.cpp
+++ b/source/blender/io/collada/ControllerExporter.cpp
@@ -406,7 +406,7 @@ void ControllerExporter::add_bind_shape_mat(Object *ob)
bc_add_global_transform(f_obmat, export_settings.get_global_transform());
}
- // UnitConverter::mat4_to_dae_double(bind_mat, ob->obmat);
+ // UnitConverter::mat4_to_dae_double(bind_mat, ob->object_to_world);
UnitConverter::mat4_to_dae_double(bind_mat, f_obmat);
if (this->export_settings.get_limit_precision()) {
BCMatrix::sanitize(bind_mat, LIMITTED_PRECISION);
@@ -523,7 +523,7 @@ std::string ControllerExporter::add_inv_bind_mats_source(Object *ob_arm,
}
/* make world-space matrix (bind_mat is armature-space) */
- mul_m4_m4m4(world, ob_arm->obmat, bind_mat);
+ mul_m4_m4m4(world, ob_arm->object_to_world, bind_mat);
if (!has_bindmat) {
if (export_settings.get_apply_global_orientation()) {
diff --git a/source/blender/io/collada/DocumentExporter.cpp b/source/blender/io/collada/DocumentExporter.cpp
index 56adbca13bd..07392e9c4ce 100644
--- a/source/blender/io/collada/DocumentExporter.cpp
+++ b/source/blender/io/collada/DocumentExporter.cpp
@@ -145,7 +145,7 @@ static COLLADABU::NativeString make_temp_filepath(const char *name, const char *
name = "untitled";
}
- BLI_join_dirfile(tempfile, sizeof(tempfile), BKE_tempdir_session(), name);
+ BLI_path_join(tempfile, sizeof(tempfile), BKE_tempdir_session(), name);
if (extension) {
BLI_path_extension_ensure(tempfile, FILE_MAX, extension);
diff --git a/source/blender/io/collada/DocumentImporter.cpp b/source/blender/io/collada/DocumentImporter.cpp
index 1ffe412b3ed..dae1c4ba894 100644
--- a/source/blender/io/collada/DocumentImporter.cpp
+++ b/source/blender/io/collada/DocumentImporter.cpp
@@ -90,8 +90,12 @@ DocumentImporter::DocumentImporter(bContext *C, const ImportSettings *import_set
CTX_data_scene(C),
view_layer,
import_settings),
- mesh_importer(
- &unit_converter, &armature_importer, CTX_data_main(C), CTX_data_scene(C), view_layer),
+ mesh_importer(&unit_converter,
+ import_settings->custom_normals,
+ &armature_importer,
+ CTX_data_main(C),
+ CTX_data_scene(C),
+ view_layer),
anim_importer(C, &unit_converter, &armature_importer, CTX_data_scene(C))
{
}
@@ -116,7 +120,7 @@ bool DocumentImporter::import()
loader.registerExtraDataCallbackHandler(ehandler);
/* deselect all to select new objects */
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(CTX_data_scene(mContext), view_layer);
std::string mFilename = std::string(this->import_settings->filepath);
const std::string encodedFilename = bc_url_encode(mFilename);
@@ -209,7 +213,7 @@ void DocumentImporter::finish()
/* Write nodes to scene */
fprintf(stderr, "+-- Import Scene --------\n");
const COLLADAFW::NodePointerArray &roots = (*sit)->getRootNodes();
- for (unsigned int i = 0; i < roots.getCount(); i++) {
+ for (uint i = 0; i < roots.getCount(); i++) {
std::vector<Object *> *objects_done = write_node(roots[i], nullptr, sce, nullptr, false);
objects_to_scale->insert(
objects_to_scale->end(), objects_done->begin(), objects_done->end());
@@ -230,14 +234,14 @@ void DocumentImporter::finish()
for (const COLLADAFW::VisualScene *vscene : vscenes) {
const COLLADAFW::NodePointerArray &roots = vscene->getRootNodes();
- for (unsigned int i = 0; i < roots.getCount(); i++) {
+ for (uint i = 0; i < roots.getCount(); i++) {
translate_anim_recursive(roots[i], nullptr, nullptr);
}
}
if (!libnode_ob.empty()) {
- fprintf(stderr, "| Cleanup: free %d library nodes\n", (int)libnode_ob.size());
+ fprintf(stderr, "| Cleanup: free %d library nodes\n", int(libnode_ob.size()));
/* free all library_nodes */
std::vector<Object *>::iterator it;
for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) {
@@ -288,7 +292,7 @@ void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node,
Object *ob;
#endif
- unsigned int i;
+ uint i;
if (node->getType() == COLLADAFW::Node::JOINT && par == nullptr) {
/* For Skeletons without root node we have to simulate the
@@ -408,8 +412,8 @@ Object *DocumentImporter::create_instance_node(Object *source_ob,
}
}
/* calc new matrix and apply */
- mul_m4_m4m4(obn->obmat, obn->obmat, mat);
- BKE_object_apply_mat4(obn, obn->obmat, false, false);
+ mul_m4_m4m4(obn->object_to_world, obn->object_to_world, mat);
+ BKE_object_apply_mat4(obn, obn->object_to_world, false, false);
}
}
else {
@@ -420,7 +424,7 @@ Object *DocumentImporter::create_instance_node(Object *source_ob,
COLLADAFW::NodePointerArray &children = source_node->getChildNodes();
if (children.getCount()) {
- for (unsigned int i = 0; i < children.getCount(); i++) {
+ for (uint i = 0; i < children.getCount(); i++) {
COLLADAFW::Node *child_node = children[i];
const COLLADAFW::UniqueId &child_id = child_node->getUniqueId();
if (object_map.find(child_id) == object_map.end()) {
@@ -430,7 +434,7 @@ Object *DocumentImporter::create_instance_node(Object *source_ob,
Object *new_child = nullptr;
if (inodes.getCount()) { /* \todo loop through instance nodes */
const COLLADAFW::UniqueId &id = inodes[0]->getInstanciatedObjectId();
- fprintf(stderr, "Doing %d child nodes\n", (int)node_map.count(id));
+ fprintf(stderr, "Doing %d child nodes\n", int(node_map.count(id)));
new_child = create_instance_node(
object_map.find(id)->second, node_map[id], child_node, sce, is_library_node);
}
@@ -671,7 +675,7 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node,
ob = *objects_done->begin();
}
- for (unsigned int i = 0; i < child_nodes.getCount(); i++) {
+ for (uint i = 0; i < child_nodes.getCount(); i++) {
std::vector<Object *> *child_objects;
child_objects = write_node(child_nodes[i], node, sce, ob, is_library_node);
delete child_objects;
@@ -716,7 +720,7 @@ bool DocumentImporter::writeLibraryNodes(const COLLADAFW::LibraryNodes *libraryN
const COLLADAFW::NodePointerArray &nodes = libraryNodes->getNodes();
fprintf(stderr, "+-- Read Library nodes ----------\n");
- for (unsigned int i = 0; i < nodes.getCount(); i++) {
+ for (uint i = 0; i < nodes.getCount(); i++) {
std::vector<Object *> *child_objects;
child_objects = write_node(nodes[i], nullptr, sce, nullptr, true);
delete child_objects;
@@ -865,7 +869,7 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera)
double ymag = 2 * camera->getYMag().getValue();
double aspect = camera->getAspectRatio().getValue();
double xmag = aspect * ymag;
- cam->ortho_scale = (float)xmag;
+ cam->ortho_scale = float(xmag);
} break;
case CAM_PERSP:
default: {
@@ -886,7 +890,7 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera)
case COLLADAFW::Camera::X_AND_Y: {
switch (cam->type) {
case CAM_ORTHO:
- cam->ortho_scale = (float)camera->getXMag().getValue() * 2;
+ cam->ortho_scale = float(camera->getXMag().getValue()) * 2;
break;
case CAM_PERSP:
default: {
@@ -899,7 +903,7 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera)
case COLLADAFW::Camera::SINGLE_Y: {
switch (cam->type) {
case CAM_ORTHO:
- cam->ortho_scale = (float)camera->getYMag().getValue();
+ cam->ortho_scale = float(camera->getYMag().getValue());
break;
case CAM_PERSP:
default: {
@@ -933,7 +937,7 @@ bool DocumentImporter::writeImage(const COLLADAFW::Image *image)
const char *workpath;
BLI_split_dir_part(this->import_settings->filepath, dir, sizeof(dir));
- BLI_join_dirfile(absolute_path, sizeof(absolute_path), dir, imagepath.c_str());
+ BLI_path_join(absolute_path, sizeof(absolute_path), dir, imagepath.c_str());
if (BLI_exists(absolute_path)) {
workpath = absolute_path;
}
@@ -1178,7 +1182,7 @@ bool DocumentImporter::addExtraTags(const COLLADAFW::UniqueId &uid, ExtraTags *e
bool DocumentImporter::is_armature(COLLADAFW::Node *node)
{
COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes();
- for (unsigned int i = 0; i < child_nodes.getCount(); i++) {
+ for (uint i = 0; i < child_nodes.getCount(); i++) {
if (child_nodes[i]->getType() == COLLADAFW::Node::JOINT) {
return true;
}
diff --git a/source/blender/io/collada/EffectExporter.cpp b/source/blender/io/collada/EffectExporter.cpp
index 40ce20617fc..e8a715633e1 100644
--- a/source/blender/io/collada/EffectExporter.cpp
+++ b/source/blender/io/collada/EffectExporter.cpp
@@ -217,7 +217,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
create_image_samplers(ep, material_image_map, active_uv);
#if 0
- unsigned int a, b;
+ uint a, b;
for (a = 0, b = 0; a < tex_indices.size(); a++) {
MTex *t = ma->mtex[tex_indices[a]];
Image *ima = t->tex->ima;
diff --git a/source/blender/io/collada/ExportSettings.h b/source/blender/io/collada/ExportSettings.h
index b3f192fdac6..e4c1b41fdde 100644
--- a/source/blender/io/collada/ExportSettings.h
+++ b/source/blender/io/collada/ExportSettings.h
@@ -81,7 +81,10 @@ typedef struct ExportSettings {
#ifdef __cplusplus
}
-void bc_get_children(std::vector<Object *> &child_set, Object *ob, ViewLayer *view_layer);
+void bc_get_children(std::vector<Object *> &child_set,
+ Object *ob,
+ const Scene *scene,
+ ViewLayer *view_layer);
class BCExportSettings {
@@ -271,7 +274,7 @@ class BCExportSettings {
bool is_export_root(Object *ob)
{
- return bc_is_base_node(get_export_set(), ob, get_view_layer());
+ return bc_is_base_node(get_export_set(), ob, get_scene(), get_view_layer());
}
};
diff --git a/source/blender/io/collada/ExtraHandler.cpp b/source/blender/io/collada/ExtraHandler.cpp
index b281f0e1a0a..d9c193ddbb5 100644
--- a/source/blender/io/collada/ExtraHandler.cpp
+++ b/source/blender/io/collada/ExtraHandler.cpp
@@ -43,7 +43,7 @@ bool ExtraHandler::textData(const char *text, size_t textLength)
}
bool ExtraHandler::parseElement(const char *profileName,
- const unsigned long &elementHash,
+ const ulong &elementHash,
const COLLADAFW::UniqueId &uniqueId)
{
/* implement for backwards compatibility, new version added object parameter */
@@ -51,7 +51,7 @@ bool ExtraHandler::parseElement(const char *profileName,
}
bool ExtraHandler::parseElement(const char *profileName,
- const unsigned long &elementHash,
+ const ulong &elementHash,
const COLLADAFW::UniqueId &uniqueId,
COLLADAFW::Object *object)
{
diff --git a/source/blender/io/collada/ExtraTags.cpp b/source/blender/io/collada/ExtraTags.cpp
index 398718f1133..9fb7bbb2295 100644
--- a/source/blender/io/collada/ExtraTags.cpp
+++ b/source/blender/io/collada/ExtraTags.cpp
@@ -49,7 +49,7 @@ float ExtraTags::asFloat(std::string tag, bool *ok)
return -1.0f;
}
*ok = true;
- return (float)atof(tags[tag].c_str());
+ return float(atof(tags[tag].c_str()));
}
std::string ExtraTags::asString(std::string tag, bool *ok)
@@ -67,7 +67,7 @@ bool ExtraTags::setData(std::string tag, short *data)
bool ok = false;
int tmp = asInt(tag, &ok);
if (ok) {
- *data = (short)tmp;
+ *data = short(tmp);
}
return ok;
}
@@ -97,7 +97,7 @@ bool ExtraTags::setData(std::string tag, char *data)
bool ok = false;
int tmp = asInt(tag, &ok);
if (ok) {
- *data = (char)tmp;
+ *data = char(tmp);
}
return ok;
}
diff --git a/source/blender/io/collada/GeometryExporter.cpp b/source/blender/io/collada/GeometryExporter.cpp
index e60900ccdb6..f6f9026481c 100644
--- a/source/blender/io/collada/GeometryExporter.cpp
+++ b/source/blender/io/collada/GeometryExporter.cpp
@@ -64,7 +64,7 @@ void GeometryExporter::operator()(Object *ob)
exportedGeometry.insert(geom_id);
- bool has_color = (bool)CustomData_has_layer(&me->fdata, CD_MCOL);
+ bool has_color = bool(CustomData_has_layer(&me->fdata, CD_MCOL));
create_normals(nor, norind, me);
@@ -77,7 +77,7 @@ void GeometryExporter::operator()(Object *ob)
/* writes <source> for normal coords */
createNormalsSource(geom_id, me, nor);
- bool has_uvs = (bool)CustomData_has_layer(&me->ldata, CD_MLOOPUV);
+ bool has_uvs = bool(CustomData_has_layer(&me->ldata, CD_MLOOPUV));
/* writes <source> for uv coords if mesh has uv coords */
if (has_uvs) {
@@ -147,7 +147,7 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb)
exportedGeometry.insert(geom_id);
- bool has_color = (bool)CustomData_has_layer(&me->fdata, CD_MCOL);
+ bool has_color = bool(CustomData_has_layer(&me->fdata, CD_MCOL));
create_normals(nor, norind, me);
@@ -160,7 +160,7 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb)
/* writes <source> for normal coords */
createNormalsSource(geom_id, me, nor);
- bool has_uvs = (bool)CustomData_has_layer(&me->ldata, CD_MLOOPUV);
+ bool has_uvs = bool(CustomData_has_layer(&me->ldata, CD_MLOOPUV));
/* writes <source> for uv coords if mesh has uv coords */
if (has_uvs) {
@@ -203,7 +203,7 @@ void GeometryExporter::createLooseEdgeList(Object *ob, Mesh *me, std::string &ge
const Span<MEdge> edges = me->edges();
int totedges = me->totedge;
int edges_in_linelist = 0;
- std::vector<unsigned int> edge_list;
+ std::vector<uint> edge_list;
int index;
/* Find all loose edges in Mesh
@@ -244,7 +244,7 @@ void GeometryExporter::createLooseEdgeList(Object *ob, Mesh *me, std::string &ge
static void prepareToAppendValues(bool is_triangulated,
COLLADASW::PrimitivesBase &primitive_list,
- std::vector<unsigned long> &vcount_list)
+ std::vector<ulong> &vcount_list)
{
/* performs the actual writing */
if (is_triangulated) {
@@ -285,7 +285,7 @@ static COLLADASW::PrimitivesBase *create_primitive_list(bool is_triangulated,
static bool collect_vertex_counts_per_poly(Mesh *me,
int material_index,
- std::vector<unsigned long> &vcount_list)
+ std::vector<ulong> &vcount_list)
{
const Span<MPoly> polys = me->polys();
const blender::bke::AttributeAccessor attributes = me->attributes();
@@ -325,7 +325,7 @@ void GeometryExporter::create_mesh_primitive_list(short material_index,
const Span<MPoly> polys = me->polys();
const Span<MLoop> loops = me->loops();
- std::vector<unsigned long> vcount_list;
+ std::vector<ulong> vcount_list;
bool is_triangulated = collect_vertex_counts_per_poly(me, material_index, vcount_list);
int polygon_count = vcount_list.size();
@@ -522,7 +522,7 @@ std::string GeometryExporter::makeTexcoordSourceId(std::string &geom_id,
suffix[0] = '\0';
}
else {
- sprintf(suffix, "-%d", layer_index);
+ BLI_snprintf(suffix, sizeof(suffix), "-%d", layer_index);
}
return getIdBySemantics(geom_id, COLLADASW::InputSemantic::TEXCOORD) + suffix;
}
@@ -585,7 +585,7 @@ void GeometryExporter::createNormalsSource(std::string geom_id, Mesh *me, std::v
COLLADASW::FloatSourceF source(mSW);
source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL));
source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL) + ARRAY_ID_SUFFIX);
- source.setAccessorCount((unsigned long)nor.size());
+ source.setAccessorCount(ulong(nor.size()));
source.setAccessorStride(3);
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
param.push_back("X");
@@ -612,7 +612,7 @@ void GeometryExporter::create_normals(std::vector<Normal> &normals,
std::vector<BCPolygonNormalsIndices> &polygons_normals,
Mesh *me)
{
- std::map<Normal, unsigned int> shared_normal_indices;
+ std::map<Normal, uint> shared_normal_indices;
int last_normal_index = -1;
const Span<MVert> verts = me->verts();
@@ -645,7 +645,7 @@ void GeometryExporter::create_normals(std::vector<Normal> &normals,
BCPolygonNormalsIndices poly_indices;
for (int loop_index = 0; loop_index < mpoly->totloop; loop_index++) {
- unsigned int loop_idx = mpoly->loopstart + loop_index;
+ uint loop_idx = mpoly->loopstart + loop_index;
if (use_vertex_normals) {
float normalized[3];
diff --git a/source/blender/io/collada/ImageExporter.cpp b/source/blender/io/collada/ImageExporter.cpp
index 1223abbaf95..070eb36de31 100644
--- a/source/blender/io/collada/ImageExporter.cpp
+++ b/source/blender/io/collada/ImageExporter.cpp
@@ -70,7 +70,7 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
BLI_strncpy(export_file, name.c_str(), sizeof(export_file));
BKE_image_path_ensure_ext_from_imformat(export_file, &imageFormat);
- BLI_join_dirfile(export_path, sizeof(export_path), export_dir, export_file);
+ BLI_path_join(export_path, sizeof(export_path), export_dir, export_file);
/* make dest directory if it doesn't exist */
BLI_make_existing_file(export_path);
diff --git a/source/blender/io/collada/ImportSettings.h b/source/blender/io/collada/ImportSettings.h
index c92cf580112..2772314900c 100644
--- a/source/blender/io/collada/ImportSettings.h
+++ b/source/blender/io/collada/ImportSettings.h
@@ -8,6 +8,7 @@
typedef struct ImportSettings {
bool import_units;
+ bool custom_normals;
bool find_chains;
bool auto_connect;
bool fix_orientation;
diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp
index b22346d0281..1a28adf50a5 100644
--- a/source/blender/io/collada/MeshImporter.cpp
+++ b/source/blender/io/collada/MeshImporter.cpp
@@ -102,7 +102,7 @@ void WVDataWrapper::print()
COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues();
if (values->getCount()) {
for (int i = 0; i < values->getCount(); i += 2) {
- fprintf(stderr, "%.1f, %.1f\n", (float)(*values)[i], (float)(*values)[i + 1]);
+ fprintf(stderr, "%.1f, %.1f\n", float((*values)[i]), float((*values)[i + 1]));
}
}
} break;
@@ -133,8 +133,8 @@ void UVDataWrapper::getUV(int uv_index, float *uv)
if (values->empty()) {
return;
}
- uv[0] = (float)(*values)[uv_index * stride];
- uv[1] = (float)(*values)[uv_index * stride + 1];
+ uv[0] = float((*values)[uv_index * stride]);
+ uv[1] = float((*values)[uv_index * stride + 1]);
} break;
case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN:
@@ -191,9 +191,14 @@ void VCOLDataWrapper::get_vcol(int v_index, MLoopCol *mloopcol)
}
}
-MeshImporter::MeshImporter(
- UnitConverter *unitconv, ArmatureImporter *arm, Main *bmain, Scene *sce, ViewLayer *view_layer)
+MeshImporter::MeshImporter(UnitConverter *unitconv,
+ bool use_custom_normals,
+ ArmatureImporter *arm,
+ Main *bmain,
+ Scene *sce,
+ ViewLayer *view_layer)
: unitconverter(unitconv),
+ use_custom_normals(use_custom_normals),
m_bmain(bmain),
scene(sce),
view_layer(view_layer),
@@ -203,7 +208,7 @@ MeshImporter::MeshImporter(
}
bool MeshImporter::set_poly_indices(
- MPoly *mpoly, MLoop *mloop, int loop_index, const unsigned int *indices, int loop_count)
+ MPoly *mpoly, MLoop *mloop, int loop_index, const uint *indices, int loop_count)
{
mpoly->loopstart = loop_index;
mpoly->totloop = loop_count;
@@ -271,7 +276,7 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)
const std::string &name = bc_get_dae_name(mesh);
- for (unsigned int i = 0; i < prim_arr.getCount(); i++) {
+ for (uint i = 0; i < prim_arr.getCount(); i++) {
COLLADAFW::MeshPrimitive *mp = prim_arr[i];
COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType();
@@ -279,7 +284,7 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)
const char *type_str = bc_primTypeToStr(type);
/* OpenCollada passes POLYGONS type for <polylist> */
- if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
+ if (ELEM(type, COLLADAFW::MeshPrimitive::POLYLIST, COLLADAFW::MeshPrimitive::POLYGONS)) {
COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
COLLADAFW::Polygons::VertexCountArray &vca = mpvc->getGroupedVerticesVertexCountArray();
@@ -287,7 +292,7 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)
int hole_count = 0;
int nonface_count = 0;
- for (unsigned int j = 0; j < vca.getCount(); j++) {
+ for (uint j = 0; j < vca.getCount(); j++) {
int count = vca[j];
if (abs(count) < 3) {
nonface_count++;
@@ -319,8 +324,9 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)
/* TODO: Add Checker for line syntax here */
}
- else if (type != COLLADAFW::MeshPrimitive::TRIANGLES &&
- type != COLLADAFW::MeshPrimitive::TRIANGLE_FANS) {
+ else if (!ELEM(type,
+ COLLADAFW::MeshPrimitive::TRIANGLES,
+ COLLADAFW::MeshPrimitive::TRIANGLE_FANS)) {
fprintf(stderr, "ERROR: Primitive type %s is not supported.\n", type_str);
return false;
}
@@ -450,7 +456,7 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, me->totpoly);
CustomData_add_layer(&me->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, me->totloop);
- unsigned int totuvset = collada_mesh->getUVCoords().getInputInfosArray().getCount();
+ uint totuvset = collada_mesh->getUVCoords().getInputInfosArray().getCount();
for (int i = 0; i < totuvset; i++) {
if (collada_mesh->getUVCoords().getLength(i) == 0) {
totuvset = 0;
@@ -485,7 +491,7 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
}
}
-unsigned int MeshImporter::get_vertex_count(COLLADAFW::Polygons *mp, int index)
+uint MeshImporter::get_vertex_count(COLLADAFW::Polygons *mp, int index)
{
int type = mp->getPrimitiveType();
int result;
@@ -508,7 +514,7 @@ unsigned int MeshImporter::get_vertex_count(COLLADAFW::Polygons *mp, int index)
return result;
}
-unsigned int MeshImporter::get_loose_edge_count(COLLADAFW::Mesh *mesh)
+uint MeshImporter::get_loose_edge_count(COLLADAFW::Mesh *mesh)
{
COLLADAFW::MeshPrimitiveArray &prim_arr = mesh->getMeshPrimitives();
int loose_edge_count = 0;
@@ -558,7 +564,7 @@ void MeshImporter::mesh_add_edges(Mesh *mesh, int len)
/* set default flags */
medge = &edges[mesh->totedge];
for (int i = 0; i < len; i++, medge++) {
- medge->flag = ME_EDGEDRAW | ME_EDGERENDER | SELECT;
+ medge->flag = ME_EDGEDRAW;
}
mesh->totedge = totedge;
@@ -566,11 +572,11 @@ void MeshImporter::mesh_add_edges(Mesh *mesh, int len)
void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me)
{
- unsigned int loose_edge_count = get_loose_edge_count(mesh);
+ uint loose_edge_count = get_loose_edge_count(mesh);
if (loose_edge_count > 0) {
- unsigned int face_edge_count = me->totedge;
- /* unsigned int total_edge_count = loose_edge_count + face_edge_count; */ /* UNUSED */
+ uint face_edge_count = me->totedge;
+ /* uint total_edge_count = loose_edge_count + face_edge_count; */ /* UNUSED */
mesh_add_edges(me, loose_edge_count);
MutableSpan<MEdge> edges = me->edges_for_write();
@@ -583,11 +589,10 @@ void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me)
int type = mp->getPrimitiveType();
if (type == COLLADAFW::MeshPrimitive::LINES) {
- unsigned int edge_count = mp->getFaceCount();
- unsigned int *indices = mp->getPositionIndices().getData();
+ uint edge_count = mp->getFaceCount();
+ uint *indices = mp->getPositionIndices().getData();
for (int j = 0; j < edge_count; j++, med++) {
- med->crease = 0;
med->flag |= ME_LOOSEEDGE;
med->v1 = indices[2 * j];
med->v2 = indices[2 * j + 1];
@@ -597,9 +602,11 @@ void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me)
}
}
-void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
+void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh,
+ Mesh *me,
+ blender::Vector<blender::float3> &loop_normals)
{
- unsigned int i;
+ uint i;
allocate_poly_data(collada_mesh, me);
@@ -626,8 +633,8 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
/* faces */
size_t prim_totpoly = mp->getFaceCount();
- unsigned int *position_indices = mp->getPositionIndices().getData();
- unsigned int *normal_indices = mp->getNormalIndices().getData();
+ uint *position_indices = mp->getPositionIndices().getData();
+ uint *normal_indices = mp->getNormalIndices().getData();
bool mp_has_normals = primitive_has_useable_normals(mp);
bool mp_has_faces = primitive_has_faces(mp);
@@ -640,24 +647,24 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
/* If MeshPrimitive is TRIANGLE_FANS we split it into triangles
* The first triangle-fan vertex will be the first vertex in every triangle
* XXX The proper function of TRIANGLE_FANS is not tested!!!
- * XXX In particular the handling of the normal_indices looks very wrong to me */
+ * XXX In particular the handling of the normal_indices is very wrong */
+ /* TODO: UV, vertex color and custom normal support */
if (collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLE_FANS) {
- unsigned int grouped_vertex_count = mp->getGroupedVertexElementsCount();
- for (unsigned int group_index = 0; group_index < grouped_vertex_count; group_index++) {
- unsigned int first_vertex = position_indices[0]; /* Store first trifan vertex */
- unsigned int first_normal = normal_indices[0]; /* Store first trifan vertex normal */
- unsigned int vertex_count = mp->getGroupedVerticesVertexCount(group_index);
+ uint grouped_vertex_count = mp->getGroupedVertexElementsCount();
+ for (uint group_index = 0; group_index < grouped_vertex_count; group_index++) {
+ uint first_vertex = position_indices[0]; /* Store first trifan vertex */
+ uint first_normal = normal_indices[0]; /* Store first trifan vertex normal */
+ uint vertex_count = mp->getGroupedVerticesVertexCount(group_index);
- for (unsigned int vertex_index = 0; vertex_index < vertex_count - 2; vertex_index++) {
+ for (uint vertex_index = 0; vertex_index < vertex_count - 2; vertex_index++) {
/* For each triangle store indices of its 3 vertices */
- unsigned int triangle_vertex_indices[3] = {
+ uint triangle_vertex_indices[3] = {
first_vertex, position_indices[1], position_indices[2]};
set_poly_indices(mpoly, mloop, loop_index, triangle_vertex_indices, 3);
if (mp_has_normals) { /* vertex normals, same implementation as for the triangles */
/* The same for vertices normals. */
- unsigned int vertex_normal_indices[3] = {
- first_normal, normal_indices[1], normal_indices[2]};
+ uint vertex_normal_indices[3] = {first_normal, normal_indices[1], normal_indices[2]};
if (!is_flat_face(vertex_normal_indices, nor, 3)) {
mpoly->flag |= ME_SMOOTH;
}
@@ -682,17 +689,18 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
}
}
- if (collada_meshtype == COLLADAFW::MeshPrimitive::POLYLIST ||
- collada_meshtype == COLLADAFW::MeshPrimitive::POLYGONS ||
- collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLES) {
+ if (ELEM(collada_meshtype,
+ COLLADAFW::MeshPrimitive::POLYLIST,
+ COLLADAFW::MeshPrimitive::POLYGONS,
+ COLLADAFW::MeshPrimitive::TRIANGLES)) {
COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
- unsigned int start_index = 0;
+ uint start_index = 0;
COLLADAFW::IndexListArray &index_list_array_uvcoord = mp->getUVCoordIndicesArray();
COLLADAFW::IndexListArray &index_list_array_vcolor = mp->getColorIndicesArray();
int invalid_loop_holes = 0;
- for (unsigned int j = 0; j < prim_totpoly; j++) {
+ for (uint j = 0; j < prim_totpoly; j++) {
/* Vertices in polygon: */
int vcount = get_vertex_count(mpvc, j);
@@ -705,7 +713,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
invalid_loop_holes += 1;
}
- for (unsigned int uvset_index = 0; uvset_index < index_list_array_uvcoord.getCount();
+ for (uint 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_uvcoord[uvset_index];
@@ -727,15 +735,28 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
}
if (mp_has_normals) {
+ /* If it turns out that we have complete custom normals for each MPoly
+ * and we want to use custom normals, this will be overridden. */
if (!is_flat_face(normal_indices, nor, vcount)) {
mpoly->flag |= ME_SMOOTH;
}
+
+ if (use_custom_normals) {
+ /* Store the custom normals for later application. */
+ float vert_normal[3];
+ uint *cur_normal = normal_indices;
+ for (int k = 0; k < vcount; k++, cur_normal++) {
+ get_vector(vert_normal, nor, *cur_normal, 3);
+ normalize_v3(vert_normal);
+ loop_normals.append(vert_normal);
+ }
+ }
}
if (mp->hasColorIndices()) {
int vcolor_count = index_list_array_vcolor.getCount();
- for (unsigned int vcolor_index = 0; vcolor_index < vcolor_count; vcolor_index++) {
+ for (uint vcolor_index = 0; vcolor_index < vcolor_count; vcolor_index++) {
COLLADAFW::IndexList &color_index_list = *mp->getColorIndices(vcolor_index);
COLLADAFW::String colname = extract_vcolname(color_index_list.getName());
@@ -813,10 +834,10 @@ void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData &arr, int i,
return;
}
- v[0] = (float)(*values)[i++];
- v[1] = (float)(*values)[i++];
+ v[0] = float((*values)[i++]);
+ v[1] = float((*values)[i++]);
if (stride >= 3) {
- v[2] = (float)(*values)[i];
+ v[2] = float((*values)[i]);
}
else {
v[2] = 0.0f;
@@ -827,7 +848,7 @@ void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData &arr, int i,
}
}
-bool MeshImporter::is_flat_face(unsigned int *nind, COLLADAFW::MeshVertexData &nor, int count)
+bool MeshImporter::is_flat_face(uint *nind, COLLADAFW::MeshVertexData &nor, int count)
{
float a[3], b[3];
@@ -874,6 +895,16 @@ std::string *MeshImporter::get_geometry_name(const std::string &mesh_name)
return nullptr;
}
+static bool bc_has_out_of_bound_indices(Mesh *me)
+{
+ for (const MLoop &loop : me->loops()) {
+ if (loop.v >= me->totvert) {
+ return true;
+ }
+ }
+ return false;
+}
+
/**
* this function checks if both objects have the same
* materials assigned to Object (in the same order)
@@ -1077,7 +1108,7 @@ Object *MeshImporter::create_mesh_object(
COLLADAFW::MaterialBindingArray &mat_array = geom->getMaterialBindings();
/* loop through geom's materials */
- for (unsigned int i = 0; i < mat_array.getCount(); i++) {
+ for (uint i = 0; i < mat_array.getCount(); i++) {
if (mat_array[i].getReferencedMaterial().isValid()) {
assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid, i);
@@ -1120,8 +1151,37 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom)
this->mesh_geom_map[std::string(me->id.name)] = str_geom_id;
read_vertices(mesh, me);
- read_polys(mesh, me);
+
+ blender::Vector<blender::float3> loop_normals;
+ read_polys(mesh, me, loop_normals);
+
BKE_mesh_calc_edges(me, false, false);
+
+ /* We must apply custom normals after edges have been calculated, because
+ * BKE_mesh_set_custom_normals()'s internals expect me->medge to be populated
+ * and for the MLoops to have correct edge indices. */
+ if (use_custom_normals && !loop_normals.is_empty()) {
+ /* BKE_mesh_set_custom_normals()'s internals also expect that each MLoop
+ * has a valid vertex index, which may not be the case due to the existing
+ * logic in read_polys(). This check isn't necessary in the no-custom-normals
+ * case because the invalid MLoops get stripped in a later step. */
+ if (bc_has_out_of_bound_indices(me)) {
+ fprintf(stderr, "Can't apply custom normals, encountered invalid loop vert indices!\n");
+ }
+ /* There may be a mismatch in lengths if one or more of the MeshPrimitives in
+ * the Geometry had missing or otherwise invalid normals. */
+ else if (me->totloop != loop_normals.size()) {
+ fprintf(stderr,
+ "Can't apply custom normals, me->totloop != loop_normals.size() (%d != %d)\n",
+ me->totloop,
+ int(loop_normals.size()));
+ }
+ else {
+ BKE_mesh_set_custom_normals(me, reinterpret_cast<float(*)[3]>(loop_normals.data()));
+ me->flag |= ME_AUTOSMOOTH;
+ }
+ }
+
/* read_lines() must be called after the face edges have been generated.
* Otherwise the loose edges will be silently deleted again. */
read_lines(mesh, me);
diff --git a/source/blender/io/collada/MeshImporter.h b/source/blender/io/collada/MeshImporter.h
index 1def84e8f99..a59b24d4f24 100644
--- a/source/blender/io/collada/MeshImporter.h
+++ b/source/blender/io/collada/MeshImporter.h
@@ -24,6 +24,7 @@
#include "collada_utils.h"
#include "BLI_edgehash.h"
+#include "BLI_math_vec_types.hh"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
@@ -63,6 +64,7 @@ class VCOLDataWrapper {
class MeshImporter : public MeshImporterBase {
private:
UnitConverter *unitconverter;
+ bool use_custom_normals;
Main *m_bmain;
Scene *scene;
@@ -156,7 +158,7 @@ class MeshImporter : public MeshImporterBase {
*
* TODO: import uv set names.
*/
- void read_polys(COLLADAFW::Mesh *mesh, Mesh *me);
+ void read_polys(COLLADAFW::Mesh *mesh, Mesh *me, blender::Vector<blender::float3> &loop_normals);
/**
* Read all loose edges.
* IMPORTANT: This function assumes that all edges from existing
@@ -179,6 +181,7 @@ class MeshImporter : public MeshImporterBase {
public:
MeshImporter(UnitConverter *unitconv,
+ bool use_custom_normals,
ArmatureImporter *arm,
Main *bmain,
Scene *sce,
diff --git a/source/blender/io/collada/SceneExporter.cpp b/source/blender/io/collada/SceneExporter.cpp
index 1b1da110573..b98ff27c89e 100644
--- a/source/blender/io/collada/SceneExporter.cpp
+++ b/source/blender/io/collada/SceneExporter.cpp
@@ -82,11 +82,13 @@ void SceneExporter::writeNodeList(std::vector<Object *> &child_objects, Object *
void SceneExporter::writeNode(Object *ob)
{
+ const Scene *scene = blender_context.get_scene();
ViewLayer *view_layer = blender_context.get_view_layer();
std::vector<Object *> child_objects;
- bc_get_children(child_objects, ob, view_layer);
- bool can_export = bc_is_in_Export_set(this->export_settings.get_export_set(), ob, view_layer);
+ bc_get_children(child_objects, ob, scene, view_layer);
+ bool can_export = bc_is_in_Export_set(
+ this->export_settings.get_export_set(), ob, scene, view_layer);
/* Add associated armature first if available */
bool armature_exported = false;
@@ -94,7 +96,7 @@ void SceneExporter::writeNode(Object *ob)
if (ob_arm != nullptr) {
armature_exported = bc_is_in_Export_set(
- this->export_settings.get_export_set(), ob_arm, view_layer);
+ this->export_settings.get_export_set(), ob_arm, scene, view_layer);
if (armature_exported && bc_is_marked(ob_arm)) {
writeNode(ob_arm);
bc_remove_mark(ob_arm);
diff --git a/source/blender/io/collada/SkinInfo.cpp b/source/blender/io/collada/SkinInfo.cpp
index 8144e0a499d..b4615635318 100644
--- a/source/blender/io/collada/SkinInfo.cpp
+++ b/source/blender/io/collada/SkinInfo.cpp
@@ -77,7 +77,7 @@ void SkinInfo::transfer_int_array_data_const(const COLLADAFW::IntValuesArray &sr
void SkinInfo::transfer_uint_array_data_const(const COLLADAFW::UIntValuesArray &src,
COLLADAFW::UIntValuesArray &dest)
{
- dest.setData((unsigned int *)src.getData(), src.getCount());
+ dest.setData((uint *)src.getData(), src.getCount());
dest.yieldOwnerShip();
}
@@ -90,7 +90,7 @@ void SkinInfo::borrow_skin_controller_data(const COLLADAFW::SkinControllerData *
/* cannot transfer data for FloatOrDoubleArray, copy values manually */
const COLLADAFW::FloatOrDoubleArray &weight = skin->getWeights();
- for (unsigned int i = 0; i < weight.getValuesCount(); i++) {
+ for (uint i = 0; i < weight.getValuesCount(); i++) {
weights.push_back(bc_get_float_value(weight, i));
}
@@ -118,7 +118,7 @@ void SkinInfo::set_controller(const COLLADAFW::SkinController *co)
/* fill in joint UIDs */
const COLLADAFW::UniqueIdArray &joint_uids = co->getJoints();
- for (unsigned int i = 0; i < joint_uids.getCount(); i++) {
+ for (uint i = 0; i < joint_uids.getCount(); i++) {
joint_data[i].joint_uid = joint_uids[i];
/* store armature pointer */
@@ -181,7 +181,7 @@ bool SkinInfo::uses_joint_or_descendant(COLLADAFW::Node *node)
}
COLLADAFW::NodePointerArray &children = node->getChildNodes();
- for (unsigned int i = 0; i < children.getCount(); i++) {
+ for (uint i = 0; i < children.getCount(); i++) {
if (uses_joint_or_descendant(children[i])) {
return true;
}
@@ -214,12 +214,12 @@ void SkinInfo::link_armature(bContext *C,
ob->partype = PAROBJECT;
BKE_object_workob_calc_parent(scene, ob, &workob);
- invert_m4_m4(ob->parentinv, workob.obmat);
+ invert_m4_m4(ob->parentinv, workob.object_to_world);
DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
#endif
- copy_m4_m4(ob->obmat, bind_shape_matrix);
- BKE_object_apply_mat4(ob, ob->obmat, false, false);
+ copy_m4_m4(ob->object_to_world, bind_shape_matrix);
+ BKE_object_apply_mat4(ob, ob->object_to_world, false, false);
amd->deformflag = ARM_DEF_VGROUP;
@@ -254,9 +254,9 @@ void SkinInfo::link_armature(bContext *C,
*
* get def group by index with BLI_findlink */
- for (unsigned int vertex = 0, weight = 0; vertex < joints_per_vertex.getCount(); vertex++) {
+ for (uint vertex = 0, weight = 0; vertex < joints_per_vertex.getCount(); vertex++) {
- unsigned int limit = weight + joints_per_vertex[vertex];
+ uint limit = weight + joints_per_vertex[vertex];
for (; weight < limit; weight++) {
int joint = joint_indices[weight], joint_weight = weight_indices[weight];
@@ -319,7 +319,7 @@ bool SkinInfo::find_node_in_tree(COLLADAFW::Node *node, COLLADAFW::Node *tree_ro
}
COLLADAFW::NodePointerArray &children = tree_root->getChildNodes();
- for (unsigned int i = 0; i < children.getCount(); i++) {
+ for (uint i = 0; i < children.getCount(); i++) {
if (find_node_in_tree(node, children[i])) {
return true;
}
diff --git a/source/blender/io/collada/TransformReader.cpp b/source/blender/io/collada/TransformReader.cpp
index e5872c28bce..cc1334bd99b 100644
--- a/source/blender/io/collada/TransformReader.cpp
+++ b/source/blender/io/collada/TransformReader.cpp
@@ -33,7 +33,7 @@ void TransformReader::get_node_mat(float mat[4][4],
unit_m4(mat);
- for (unsigned int i = 0; i < node->getTransformations().getCount(); i++) {
+ for (uint i = 0; i < node->getTransformations().getCount(); i++) {
COLLADAFW::Transformation *tm = node->getTransformations()[i];
COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
@@ -87,8 +87,8 @@ void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[
{
COLLADAFW::Rotate *ro = (COLLADAFW::Rotate *)tm;
COLLADABU::Math::Vector3 &axis = ro->getRotationAxis();
- const float angle = (float)DEG2RAD(ro->getRotationAngle());
- const float ax[] = {(float)axis[0], (float)axis[1], (float)axis[2]};
+ const float angle = float(DEG2RAD(ro->getRotationAngle()));
+ const float ax[] = {float(axis[0]), float(axis[1]), float(axis[2])};
#if 0
float quat[4];
axis_angle_to_quat(quat, axis, angle);
@@ -104,15 +104,15 @@ void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float
unit_m4(m);
- m[3][0] = (float)t[0];
- m[3][1] = (float)t[1];
- m[3][2] = (float)t[2];
+ m[3][0] = float(t[0]);
+ m[3][1] = float(t[1]);
+ m[3][2] = float(t[2]);
}
void TransformReader::dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[4][4])
{
COLLADABU::Math::Vector3 &s = ((COLLADAFW::Scale *)tm)->getScale();
- float size[3] = {(float)s[0], (float)s[1], (float)s[2]};
+ float size[3] = {float(s[0]), float(s[1]), float(s[2])};
size_to_mat4(m, size);
}
diff --git a/source/blender/io/collada/collada.cpp b/source/blender/io/collada/collada.cpp
index d559c0b4962..c33363ef205 100644
--- a/source/blender/io/collada/collada.cpp
+++ b/source/blender/io/collada/collada.cpp
@@ -29,6 +29,7 @@ static void print_import_header(ImportSettings &import_settings)
fprintf(stderr, "+-- Collada Import parameters------\n");
fprintf(stderr, "| input file : %s\n", import_settings.filepath);
fprintf(stderr, "| use units : %s\n", (import_settings.import_units) ? "yes" : "no");
+ fprintf(stderr, "| custom normals : %s\n", (import_settings.custom_normals) ? "yes" : "no");
fprintf(stderr, "| autoconnect : %s\n", (import_settings.auto_connect) ? "yes" : "no");
fprintf(stderr, "+-- Armature Import parameters ----\n");
fprintf(stderr, "| find bone chains: %s\n", (import_settings.find_chains) ? "yes" : "no");
@@ -57,6 +58,7 @@ int collada_import(bContext *C, ImportSettings *import_settings)
int collada_export(bContext *C, ExportSettings *export_settings)
{
BlenderContext blender_context(C);
+ const Scene *scene = blender_context.get_scene();
ViewLayer *view_layer = blender_context.get_view_layer();
int includeFilter = OB_REL_NONE;
@@ -72,7 +74,7 @@ int collada_export(bContext *C, ExportSettings *export_settings)
*/
eObjectSet objectSet = (export_settings->selected) ? OB_SET_SELECTED : OB_SET_ALL;
export_settings->export_set = BKE_object_relational_superset(
- view_layer, objectSet, (eObRelationTypes)includeFilter);
+ scene, view_layer, objectSet, (eObRelationTypes)includeFilter);
int export_count = BLI_linklist_count(export_settings->export_set);
diff --git a/source/blender/io/collada/collada_internal.cpp b/source/blender/io/collada/collada_internal.cpp
index da9a4cd4a9b..60e8edaa3bc 100644
--- a/source/blender/io/collada/collada_internal.cpp
+++ b/source/blender/io/collada/collada_internal.cpp
@@ -47,7 +47,7 @@ UnitConverter::UnitSystem UnitConverter::isMetricSystem()
float UnitConverter::getLinearMeter()
{
- return (float)unit.getLinearUnitMeter();
+ return float(unit.getLinearUnitMeter());
}
void UnitConverter::convertVector3(COLLADABU::Math::Vector3 &vec, float *v)
@@ -153,7 +153,7 @@ void UnitConverter::calculate_scale(Scene &sce)
* The COLLADA spec also allows additional chars for member access ('.'), these
* must obviously be removed too, otherwise they would be heavily misinterpreted.
*/
-const unsigned char translate_start_name_map[256] = {
+const uchar translate_start_name_map[256] = {
95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
@@ -172,7 +172,7 @@ const unsigned char translate_start_name_map[256] = {
242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
};
-const unsigned char translate_name_map[256] = {
+const uchar translate_name_map[256] = {
95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
@@ -212,16 +212,16 @@ std::string translate_id(const std::string &id)
}
std::string id_translated = id;
- id_translated[0] = translate_start_name_map[(unsigned int)id_translated[0]];
- for (unsigned int i = 1; i < id_translated.size(); i++) {
- id_translated[i] = translate_name_map[(unsigned int)id_translated[i]];
+ id_translated[0] = translate_start_name_map[uint(id_translated[0])];
+ for (uint i = 1; i < id_translated.size(); i++) {
+ id_translated[i] = translate_name_map[uint(id_translated[i])];
}
/* It's so much workload now, the if () should speed up things. */
if (id_translated != id) {
/* Search duplicates. */
map_string_list::iterator iter = global_id_map.find(id_translated);
if (iter != global_id_map.end()) {
- unsigned int i = 0;
+ uint i = 0;
bool found = false;
for (i = 0; i < iter->second.size(); i++) {
if (id == iter->second[i]) {
diff --git a/source/blender/io/collada/collada_utils.cpp b/source/blender/io/collada/collada_utils.cpp
index 82c471a6524..96ff78a715a 100644
--- a/source/blender/io/collada/collada_utils.cpp
+++ b/source/blender/io/collada/collada_utils.cpp
@@ -66,7 +66,7 @@
#include "ExportSettings.h"
#include "collada_utils.h"
-float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray &array, unsigned int index)
+float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray &array, uint index)
{
if (index >= array.getValuesCount()) {
return 0.0f;
@@ -129,7 +129,7 @@ bool bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space)
const bool keep_transform = false;
if (par && is_parent_space) {
- mul_m4_m4m4(ob->obmat, par->obmat, ob->obmat);
+ mul_m4_m4m4(ob->object_to_world, par->object_to_world, ob->object_to_world);
}
bool ok = ED_object_parent_set(
@@ -197,6 +197,7 @@ Object *bc_add_object(Main *bmain, Scene *scene, ViewLayer *view_layer, int type
LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer);
BKE_collection_object_add(bmain, layer_collection->collection, ob);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob);
/* TODO: is setting active needed? */
BKE_view_layer_base_select_and_set_active(view_layer, base);
@@ -347,10 +348,10 @@ std::string bc_replace_string(std::string data,
void bc_match_scale(Object *ob, UnitConverter &bc_unit, bool scale_to_scene)
{
if (scale_to_scene) {
- mul_m4_m4m4(ob->obmat, bc_unit.get_scale(), ob->obmat);
+ mul_m4_m4m4(ob->object_to_world, bc_unit.get_scale(), ob->object_to_world);
}
- mul_m4_m4m4(ob->obmat, bc_unit.get_rotation(), ob->obmat);
- BKE_object_apply_mat4(ob, ob->obmat, false, false);
+ mul_m4_m4m4(ob->object_to_world, bc_unit.get_rotation(), ob->object_to_world);
+ BKE_object_apply_mat4(ob, ob->object_to_world, false, false);
}
void bc_match_scale(std::vector<Object *> *objects_done,
@@ -709,13 +710,13 @@ float bc_get_property(Bone *bone, std::string key, float def)
if (property) {
switch (property->type) {
case IDP_INT:
- result = (float)(IDP_Int(property));
+ result = float(IDP_Int(property));
break;
case IDP_FLOAT:
- result = (float)(IDP_Float(property));
+ result = float(IDP_Float(property));
break;
case IDP_DOUBLE:
- result = (float)(IDP_Double(property));
+ result = float(IDP_Double(property));
break;
default:
result = def;
@@ -1007,9 +1008,9 @@ void bc_create_restpose_mat(BCExportSettings &export_settings,
void bc_sanitize_v3(float v[3], int precision)
{
for (int i = 0; i < 3; i++) {
- double val = (double)v[i];
+ double val = double(v[i]);
val = double_round(val, precision);
- v[i] = (float)val;
+ v[i] = float(val);
}
}
@@ -1338,7 +1339,7 @@ bool bc_get_float_from_shader(bNode *shader, double &val, std::string nodeid)
bNodeSocket *socket = nodeFindSocket(shader, SOCK_IN, nodeid.c_str());
if (socket) {
bNodeSocketValueFloat *ref = (bNodeSocketValueFloat *)socket->default_value;
- val = (double)ref->value;
+ val = double(ref->value);
return true;
}
return false;
diff --git a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
index 1fbddc45964..d559b0efe82 100644
--- a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
+++ b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
@@ -272,10 +272,11 @@ void AbstractHierarchyIterator::export_graph_construct()
ExportGraph::key_type root_node_id = ObjectIdentifier::for_real_object(nullptr);
export_graph_[root_node_id] = ExportChildren();
- DEG_OBJECT_ITER_BEGIN (depsgraph_,
- object,
- DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
- DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET) {
+ DEGObjectIterSettings deg_iter_settings{};
+ deg_iter_settings.depsgraph = depsgraph_;
+ deg_iter_settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, object) {
/* Non-instanced objects always have their object-parent as export-parent. */
const bool weak_export = mark_as_weak_export(object);
visit_object(object, object->parent, weak_export);
@@ -415,7 +416,7 @@ void AbstractHierarchyIterator::visit_object(Object *object,
context->original_export_path = "";
context->higher_up_export_path = "";
- copy_m4_m4(context->matrix_world, object->obmat);
+ copy_m4_m4(context->matrix_world, object->object_to_world);
ExportGraph::key_type graph_index = determine_graph_index_object(context);
context_update_for_graph_index(context, graph_index);
diff --git a/source/blender/io/common/intern/path_util.cc b/source/blender/io/common/intern/path_util.cc
index 18632b410f8..63ff6cf29ee 100644
--- a/source/blender/io/common/intern/path_util.cc
+++ b/source/blender/io/common/intern/path_util.cc
@@ -28,8 +28,7 @@ std::string path_reference(StringRefNull filepath,
}
else if (mode == PATH_REFERENCE_COPY) {
char filepath_cpy[PATH_MAX];
- BLI_path_join(
- filepath_cpy, PATH_MAX, base_dst.c_str(), BLI_path_basename(filepath_abs), nullptr);
+ BLI_path_join(filepath_cpy, PATH_MAX, base_dst.c_str(), BLI_path_basename(filepath_abs));
copy_set->add(std::make_pair(filepath_abs, filepath_cpy));
BLI_strncpy(filepath_abs, filepath_cpy, PATH_MAX);
mode = PATH_REFERENCE_RELATIVE;
diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.cc b/source/blender/io/gpencil/intern/gpencil_io_base.cc
index b5838ad9485..6cc977bfced 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_base.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_base.cc
@@ -20,6 +20,7 @@
#include "BKE_context.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_geom.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_scene.h"
@@ -78,7 +79,7 @@ void GpencilIO::prepare_camera_params(Scene *scene, const GpencilIOParams *ipara
BKE_camera_params_compute_matrix(&params);
float viewmat[4][4];
- invert_m4_m4(viewmat, cam_ob->obmat);
+ invert_m4_m4(viewmat, cam_ob->object_to_world);
mul_m4_m4m4(persmat_, params.winmat, viewmat);
}
@@ -127,13 +128,15 @@ void GpencilIO::prepare_camera_params(Scene *scene, const GpencilIOParams *ipara
void GpencilIO::create_object_list()
{
+ Scene *scene = CTX_data_scene(params_.C);
ViewLayer *view_layer = CTX_data_view_layer(params_.C);
float3 camera_z_axis;
copy_v3_v3(camera_z_axis, rv3d_->viewinv[2]);
ob_list_.clear();
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *object = base->object;
if (object->type != OB_GPENCIL) {
@@ -149,7 +152,7 @@ void GpencilIO::create_object_list()
/* Save z-depth from view to sort from back to front. */
if (is_camera_) {
- float camera_z = dot_v3v3(camera_z_axis, object->obmat[3]);
+ float camera_z = dot_v3v3(camera_z_axis, object->object_to_world[3]);
ObjectZ obz = {camera_z, object};
ob_list_.append(obz);
}
@@ -157,10 +160,10 @@ void GpencilIO::create_object_list()
float zdepth = 0;
if (rv3d_) {
if (rv3d_->is_persp) {
- zdepth = ED_view3d_calc_zfac(rv3d_, object->obmat[3]);
+ zdepth = ED_view3d_calc_zfac(rv3d_, object->object_to_world[3]);
}
else {
- zdepth = -dot_v3v3(rv3d_->viewinv[2], object->obmat[3]);
+ zdepth = -dot_v3v3(rv3d_->viewinv[2], object->object_to_world[3]);
}
ObjectZ obz = {zdepth * -1.0f, object};
ob_list_.append(obz);
@@ -224,16 +227,16 @@ float2 GpencilIO::gpencil_3D_point_to_render_space(const float3 co)
float2 r_co;
mul_v2_project_m4_v3(&r_co.x, persmat_, &parent_co.x);
- r_co.x = (r_co.x + 1.0f) / 2.0f * (float)render_x_;
- r_co.y = (r_co.y + 1.0f) / 2.0f * (float)render_y_;
+ r_co.x = (r_co.x + 1.0f) / 2.0f * float(render_x_);
+ r_co.y = (r_co.y + 1.0f) / 2.0f * float(render_y_);
/* Invert X axis. */
if (invert_axis_[0]) {
- r_co.x = (float)render_x_ - r_co.x;
+ r_co.x = float(render_x_) - r_co.x;
}
/* Invert Y axis. */
if (invert_axis_[1]) {
- r_co.y = (float)render_y_ - r_co.y;
+ r_co.y = float(render_y_) - r_co.y;
}
return r_co;
@@ -241,7 +244,7 @@ float2 GpencilIO::gpencil_3D_point_to_render_space(const float3 co)
float2 GpencilIO::gpencil_3D_point_to_2D(const float3 co)
{
- const bool is_camera = (bool)(rv3d_->persp == RV3D_CAMOB);
+ const bool is_camera = bool(rv3d_->persp == RV3D_CAMOB);
if (is_camera) {
return gpencil_3D_point_to_render_space(co);
}
@@ -289,9 +292,9 @@ void GpencilIO::prepare_stroke_export_colors(Object *ob, bGPDstroke *gps)
avg_opacity_ += pt.strength;
}
- mul_v4_v4fl(avg_color, avg_color, 1.0f / (float)gps->totpoints);
+ mul_v4_v4fl(avg_color, avg_color, 1.0f / float(gps->totpoints));
interp_v3_v3v3(stroke_color_, stroke_color_, avg_color, avg_color[3]);
- avg_opacity_ /= (float)gps->totpoints;
+ avg_opacity_ /= float(gps->totpoints);
/* Fill color. */
copy_v4_v4(fill_color_, gp_style->fill_rgba);
diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.hh b/source/blender/io/gpencil/intern/gpencil_io_base.hh
index 4987ab34ffc..f712ed839d9 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_base.hh
+++ b/source/blender/io/gpencil/intern/gpencil_io_base.hh
@@ -70,7 +70,7 @@ class GpencilIO {
float stroke_color_[4], fill_color_[4];
/* Geometry functions. */
- /** Convert to screenspace. */
+ /** Convert to screen-space. */
bool gpencil_3D_point_to_screen_space(const float3 co, float2 &r_co);
/** Convert to render space. */
float2 gpencil_3D_point_to_render_space(const float3 co);
diff --git a/source/blender/io/gpencil/intern/gpencil_io_capi.cc b/source/blender/io/gpencil/intern/gpencil_io_capi.cc
index ac5f8cf7c8d..96a6cc66b25 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_capi.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_capi.cc
@@ -108,7 +108,7 @@ static bool gpencil_io_export_pdf(Depsgraph *depsgraph,
case GP_EXPORT_FRAME_SCENE: {
for (int32_t i = iparams->frame_start; i < iparams->frame_end + 1; i++) {
if ((iparams->frame_mode == GP_EXPORT_FRAME_SELECTED) &&
- (!is_keyframe_included(gpd_eval, i, true))) {
+ !is_keyframe_included(gpd_eval, i, true)) {
continue;
}
diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc
index 463032ebb9d..c042ca597c8 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc
@@ -37,7 +37,7 @@
namespace blender ::io ::gpencil {
-static void error_handler(HPDF_STATUS error_no, HPDF_STATUS detail_no, void *UNUSED(user_data))
+static void error_handler(HPDF_STATUS error_no, HPDF_STATUS detail_no, void * /*user_data*/)
{
printf("ERROR: error_no=%04X, detail_no=%u\n", (HPDF_UINT)error_no, (HPDF_UINT)detail_no);
}
@@ -177,7 +177,7 @@ void GpencilExporterPDF::export_gpencil_layers()
/* Apply layer thickness change. */
gps_duplicate->thickness += gpl->line_change;
/* Apply object scale to thickness. */
- gps_duplicate->thickness *= mat4_to_scale(ob->obmat);
+ gps_duplicate->thickness *= mat4_to_scale(ob->object_to_world);
CLAMP_MIN(gps_duplicate->thickness, 1.0f);
/* Fill. */
if ((is_fill) && (params_.flag & GP_EXPORT_FILL)) {
diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc
index 58f12e9b8b1..b85fd33e116 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc
@@ -90,7 +90,8 @@ void GpencilExporterSVG::create_document_header()
pugi::xml_node comment = main_doc_.append_child(pugi::node_comment);
char txt[128];
- sprintf(txt, " Generator: Blender, %s - %s ", SVG_EXPORTER_NAME, SVG_EXPORTER_VERSION);
+ BLI_snprintf(
+ txt, sizeof(txt), " Generator: Blender, %s - %s ", SVG_EXPORTER_NAME, SVG_EXPORTER_VERSION);
comment.set_value(txt);
pugi::xml_node doctype = main_doc_.append_child(pugi::node_doctype);
@@ -147,7 +148,7 @@ void GpencilExporterSVG::export_gpencil_layers()
pugi::xml_node ob_node = frame_node_.append_child("g");
char obtxt[96];
- sprintf(obtxt, "blender_object_%s", ob->id.name + 2);
+ BLI_snprintf(obtxt, sizeof(obtxt), "blender_object_%s", ob->id.name + 2);
ob_node.append_attribute("id").set_value(obtxt);
/* Use evaluated version to get strokes with modifiers. */
@@ -197,7 +198,7 @@ void GpencilExporterSVG::export_gpencil_layers()
/* Apply layer thickness change. */
gps_duplicate->thickness += gpl->line_change;
/* Apply object scale to thickness. */
- gps_duplicate->thickness *= mat4_to_scale(ob->obmat);
+ gps_duplicate->thickness *= mat4_to_scale(ob->object_to_world);
CLAMP_MIN(gps_duplicate->thickness, 1.0f);
const bool is_normalized = ((params_.flag & GP_EXPORT_NORM_THICKNESS) != 0) ||
@@ -402,7 +403,7 @@ std::string GpencilExporterSVG::rgb_to_hexstr(const float color[3])
uint8_t g = color[1] * 255.0f;
uint8_t b = color[2] * 255.0f;
char hex_string[20];
- sprintf(hex_string, "#%02X%02X%02X", r, g, b);
+ BLI_snprintf(hex_string, sizeof(hex_string), "#%02X%02X%02X", r, g, b);
std::string hexstr = hex_string;
diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_base.cc b/source/blender/io/gpencil/intern/gpencil_io_import_base.cc
index 6d4439243fd..f6d02d36a17 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_import_base.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_import_base.cc
@@ -31,7 +31,7 @@ Object *GpencilImporter::create_object()
const float *cur_loc = scene_->cursor.location;
const float rot[3] = {0.0f};
ushort local_view_bits = (params_.v3d && params_.v3d->localvd) ? params_.v3d->local_view_uuid :
- (ushort)0;
+ ushort(0);
Object *ob_gpencil = ED_object_add_type(params_.C,
OB_GPENCIL,
diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc b/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc
index 06460a1beba..23c80900659 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc
@@ -93,8 +93,8 @@ bool GpencilImporterSVG::read()
/* Check frame. */
bGPDframe *gpf = BKE_gpencil_layer_frame_get(gpl, cfra_, GP_GETFRAME_ADD_NEW);
/* Create materials. */
- bool is_stroke = (bool)shape->stroke.type;
- bool is_fill = (bool)shape->fill.type;
+ bool is_stroke = bool(shape->stroke.type);
+ bool is_fill = bool(shape->fill.type);
if ((!is_stroke) && (!is_fill)) {
is_stroke = true;
}
@@ -148,11 +148,11 @@ void GpencilImporterSVG::create_stroke(bGPdata *gpd,
const int32_t mat_index,
const float matrix[4][4])
{
- const bool is_stroke = (bool)shape->stroke.type;
- const bool is_fill = (bool)shape->fill.type;
+ const bool is_stroke = bool(shape->stroke.type);
+ const bool is_fill = bool(shape->fill.type);
const int edges = params_.resolution;
- const float step = 1.0f / (float)(edges - 1);
+ const float step = 1.0f / float(edges - 1);
const int totpoints = (path->npts / 3) * params_.resolution;
@@ -212,19 +212,19 @@ void GpencilImporterSVG::create_stroke(bGPdata *gpd,
}
/* Unpack internal NanoSVG color. */
-static void unpack_nano_color(const unsigned int pack, float r_col[4])
+static void unpack_nano_color(const uint pack, float r_col[4])
{
- unsigned char rgb_u[4];
+ uchar rgb_u[4];
rgb_u[0] = ((pack) >> 0) & 0xFF;
rgb_u[1] = ((pack) >> 8) & 0xFF;
rgb_u[2] = ((pack) >> 16) & 0xFF;
rgb_u[3] = ((pack) >> 24) & 0xFF;
- r_col[0] = (float)rgb_u[0] / 255.0f;
- r_col[1] = (float)rgb_u[1] / 255.0f;
- r_col[2] = (float)rgb_u[2] / 255.0f;
- r_col[3] = (float)rgb_u[3] / 255.0f;
+ r_col[0] = float(rgb_u[0]) / 255.0f;
+ r_col[1] = float(rgb_u[1]) / 255.0f;
+ r_col[2] = float(rgb_u[2]) / 255.0f;
+ r_col[3] = float(rgb_u[3]) / 255.0f;
}
void GpencilImporterSVG::convert_color(const int32_t color, float r_linear_rgba[4])
diff --git a/source/blender/io/stl/CMakeLists.txt b/source/blender/io/stl/CMakeLists.txt
index 3a21da5c579..f7eb933d198 100644
--- a/source/blender/io/stl/CMakeLists.txt
+++ b/source/blender/io/stl/CMakeLists.txt
@@ -2,7 +2,7 @@
set(INC
.
- ./importer
+ importer
../common
../../blenkernel
../../blenlib
diff --git a/source/blender/io/stl/importer/stl_import.cc b/source/blender/io/stl/importer/stl_import.cc
index 097d14b038c..e5fde6658ab 100644
--- a/source/blender/io/stl/importer/stl_import.cc
+++ b/source/blender/io/stl/importer/stl_import.cc
@@ -99,11 +99,12 @@ void importer_main(Main *bmain,
BKE_mesh_validate(mesh, verbose_validate, false);
}
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
LayerCollection *lc = BKE_layer_collection_get_active(view_layer);
Object *obj = BKE_object_add_only_object(bmain, OB_MESH, ob_name);
BKE_mesh_assign_object(bmain, obj, mesh);
BKE_collection_object_add(bmain, lc->collection, obj);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, obj);
BKE_view_layer_base_select_and_set_active(view_layer, base);
diff --git a/source/blender/io/stl/importer/stl_import_ascii_reader.cc b/source/blender/io/stl/importer/stl_import_ascii_reader.cc
index 2edb3c6a114..6a976a2fd2c 100644
--- a/source/blender/io/stl/importer/stl_import_ascii_reader.cc
+++ b/source/blender/io/stl/importer/stl_import_ascii_reader.cc
@@ -97,7 +97,7 @@ class StringBuffer {
start++;
}
fast_float::from_chars_result res = fast_float::from_chars(start, end, out);
- if (res.ec == std::errc::invalid_argument || res.ec == std::errc::result_out_of_range) {
+ if (ELEM(res.ec, std::errc::invalid_argument, std::errc::result_out_of_range)) {
out = 0.0f;
}
start = const_cast<char *>(res.ptr);
diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt
index 1205ae74e6f..06a0f12c571 100644
--- a/source/blender/io/usd/CMakeLists.txt
+++ b/source/blender/io/usd/CMakeLists.txt
@@ -20,13 +20,14 @@ add_definitions(-DTBB_SUPPRESS_DEPRECATED_MESSAGES=1)
# add a USD_HAS_IMAGING define so code can dynamically detect this.
# Cleanup of this variable is done at the end of the file since
# test code further down uses it to add imaging tests.
-FIND_FILE(USD_IMAGING_HEADERS
+find_file(
+ USD_IMAGING_HEADERS
NAMES
capsuleAdapter.h
PATHS
- ${USD_INCLUDE_DIRS}
+ ${USD_INCLUDE_DIRS}
PATH_SUFFIXES
- pxr/usdImaging/usdImaging/
+ pxr/usdImaging/usdImaging/
NO_DEFAULT_PATH
)
@@ -142,7 +143,8 @@ if(WIN32)
set_property(TARGET bf_usd APPEND_STRING PROPERTY INTERFACE_LINK_OPTIONS "$<$<CONFIG:MinSizeRel>:/WHOLEARCHIVE:${USD_RELEASE_LIB}>")
endif()
-# Source: https://github.com/PixarAnimationStudios/USD/blob/master/BUILDING.md#linking-whole-archives
+# Source:
+# https://github.com/PixarAnimationStudios/USD/blob/master/BUILDING.md#linking-whole-archives
if(WIN32)
target_link_libraries(bf_usd INTERFACE ${USD_LIBRARIES})
elseif(APPLE)
@@ -162,7 +164,7 @@ if(WITH_GTESTS)
tests/usd_tests_common.h
)
if(USD_IMAGING_HEADERS)
- LIST(APPEND TEST_SRC tests/usd_imaging_test.cc)
+ list(APPEND TEST_SRC tests/usd_imaging_test.cc)
endif()
set(TEST_INC
@@ -173,6 +175,6 @@ if(WITH_GTESTS)
blender_add_test_lib(bf_io_usd_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
endif()
-# In cmake version 3.21 and up, we can instead use the NO_CACHE option for
-# find_file so we don't need to clear it from the cache here.
+# In CMAKE version 3.21 and up, we can instead use the `NO_CACHE` option for
+# `find_file` so we don't need to clear it from the cache here.
unset(USD_IMAGING_HEADERS CACHE)
diff --git a/source/blender/io/usd/intern/usd_capi_export.cc b/source/blender/io/usd/intern/usd_capi_export.cc
index 1033f85181c..bf25c03fb7a 100644
--- a/source/blender/io/usd/intern/usd_capi_export.cc
+++ b/source/blender/io/usd/intern/usd_capi_export.cc
@@ -57,8 +57,8 @@ static void report_job_duration(const ExportJobData *data)
static void export_startjob(void *customdata,
/* Cannot be const, this function implements wm_jobs_start_callback.
* NOLINTNEXTLINE: readability-non-const-parameter. */
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress)
{
ExportJobData *data = static_cast<ExportJobData *>(customdata);
@@ -96,8 +96,7 @@ static void export_startjob(void *customdata,
}
usd_stage->SetMetadata(pxr::UsdGeomTokens->upAxis, pxr::VtValue(pxr::UsdGeomTokens->z));
- usd_stage->SetMetadata(pxr::UsdGeomTokens->metersPerUnit,
- static_cast<double>(scene->unit.scale_length));
+ usd_stage->SetMetadata(pxr::UsdGeomTokens->metersPerUnit, double(scene->unit.scale_length));
usd_stage->GetRootLayer()->SetDocumentation(std::string("Blender v") +
BKE_blender_version_string());
@@ -120,7 +119,7 @@ static void export_startjob(void *customdata,
}
/* Update the scene for the next frame to render. */
- scene->r.cfra = static_cast<int>(frame);
+ scene->r.cfra = int(frame);
scene->r.subframe = frame - scene->r.cfra;
BKE_scene_graph_update_for_newframe(data->depsgraph);
@@ -206,7 +205,7 @@ bool USD_export(bContext *C,
}
else {
/* Fake a job context, so that we don't need NULL pointer checks while exporting. */
- short stop = 0, do_update = 0;
+ bool stop = false, do_update = false;
float progress = 0.0f;
blender::io::usd::export_startjob(job, &stop, &do_update, &progress);
diff --git a/source/blender/io/usd/intern/usd_capi_import.cc b/source/blender/io/usd/intern/usd_capi_import.cc
index 03af3aed2d0..680e9c758d3 100644
--- a/source/blender/io/usd/intern/usd_capi_import.cc
+++ b/source/blender/io/usd/intern/usd_capi_import.cc
@@ -126,8 +126,8 @@ struct ImportJobData {
USDStageReader *archive;
- short *stop;
- short *do_update;
+ bool *stop;
+ bool *do_update;
float *progress;
char error_code;
@@ -144,7 +144,7 @@ static void report_job_duration(const ImportJobData *data)
std::cout << '\n';
}
-static void import_startjob(void *customdata, short *stop, short *do_update, float *progress)
+static void import_startjob(void *customdata, bool *stop, bool *do_update, float *progress)
{
ImportJobData *data = static_cast<ImportJobData *>(customdata);
@@ -230,7 +230,7 @@ static void import_startjob(void *customdata, short *stop, short *do_update, flo
*data->do_update = true;
*data->progress = 0.2f;
- const float size = static_cast<float>(archive->readers().size());
+ const float size = float(archive->readers().size());
size_t i = 0;
/* Sort readers by name: when creating a lot of objects in Blender,
@@ -310,14 +310,14 @@ static void import_endjob(void *customdata)
else if (data->archive) {
Base *base;
LayerCollection *lc;
+ const Scene *scene = data->scene;
ViewLayer *view_layer = data->view_layer;
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
lc = BKE_layer_collection_get_active(view_layer);
- /* Add all objects to the collection (don't do sync for each object). */
- BKE_layer_collection_resync_forbid();
+ /* Add all objects to the collection. */
for (USDPrimReader *reader : data->archive->readers()) {
if (!reader) {
continue;
@@ -329,9 +329,8 @@ static void import_endjob(void *customdata)
BKE_collection_object_add(data->bmain, lc->collection, ob);
}
- /* Sync the collection, and do view layer operations. */
- BKE_layer_collection_resync_allow();
- BKE_main_collection_sync(data->bmain);
+ /* Sync and do the view layer operations. */
+ BKE_view_layer_synced_ensure(scene, view_layer);
for (USDPrimReader *reader : data->archive->readers()) {
if (!reader) {
continue;
@@ -431,7 +430,7 @@ bool USD_import(struct bContext *C,
}
else {
/* Fake a job context, so that we don't need NULL pointer checks while importing. */
- short stop = 0, do_update = 0;
+ bool stop = false, do_update = false;
float progress = 0.0f;
import_startjob(job, &stop, &do_update, &progress);
diff --git a/source/blender/io/usd/intern/usd_hierarchy_iterator.cc b/source/blender/io/usd/intern/usd_hierarchy_iterator.cc
index 51261c4d91e..fbfda975055 100644
--- a/source/blender/io/usd/intern/usd_hierarchy_iterator.cc
+++ b/source/blender/io/usd/intern/usd_hierarchy_iterator.cc
@@ -141,7 +141,7 @@ AbstractHierarchyWriter *USDHierarchyIterator::create_hair_writer(const Hierarch
}
AbstractHierarchyWriter *USDHierarchyIterator::create_particle_writer(
- const HierarchyContext *UNUSED(context))
+ const HierarchyContext * /*context*/)
{
return nullptr;
}
diff --git a/source/blender/io/usd/intern/usd_reader_camera.cc b/source/blender/io/usd/intern/usd_reader_camera.cc
index 7f1e9fef89d..da51787e437 100644
--- a/source/blender/io/usd/intern/usd_reader_camera.cc
+++ b/source/blender/io/usd/intern/usd_reader_camera.cc
@@ -71,7 +71,7 @@ void USDCameraReader::read_object_data(Main *bmain, const double motionSampleTim
bcam->clip_end = clippingRangeVal.UncheckedGet<pxr::GfVec2f>()[1];
bcam->dof.focus_distance = focalDistanceVal.Get<float>();
- bcam->dof.aperture_fstop = static_cast<float>(fstopVal.Get<float>());
+ bcam->dof.aperture_fstop = float(fstopVal.Get<float>());
if (bcam->type == CAM_ORTHO) {
bcam->ortho_scale = max_ff(verAp.Get<float>(), horAp.Get<float>());
diff --git a/source/blender/io/usd/intern/usd_reader_curve.cc b/source/blender/io/usd/intern/usd_reader_curve.cc
index 0d3c2feb8f3..ca48f3c2391 100644
--- a/source/blender/io/usd/intern/usd_reader_curve.cc
+++ b/source/blender/io/usd/intern/usd_reader_curve.cc
@@ -139,9 +139,9 @@ void USDCurvesReader::read_curve_sample(Curve *cu, const double motionSampleTime
BPoint *bp = nu->bp;
for (int j = 0; j < nu->pntsu; j++, bp++, idx++) {
- bp->vec[0] = (float)usdPoints[idx][0];
- bp->vec[1] = (float)usdPoints[idx][1];
- bp->vec[2] = (float)usdPoints[idx][2];
+ bp->vec[0] = float(usdPoints[idx][0]);
+ bp->vec[1] = float(usdPoints[idx][1]);
+ bp->vec[2] = float(usdPoints[idx][2]);
bp->vec[3] = weight;
bp->f1 = SELECT;
bp->weight = weight;
diff --git a/source/blender/io/usd/intern/usd_reader_curve.h b/source/blender/io/usd/intern/usd_reader_curve.h
index 1e9330b81f1..48fb2c5e2d1 100644
--- a/source/blender/io/usd/intern/usd_reader_curve.h
+++ b/source/blender/io/usd/intern/usd_reader_curve.h
@@ -27,7 +27,7 @@ class USDCurvesReader : public USDGeomReader {
bool valid() const override
{
- return static_cast<bool>(curve_prim_);
+ return bool(curve_prim_);
}
void create_object(Main *bmain, double motionSampleTime) override;
diff --git a/source/blender/io/usd/intern/usd_reader_light.cc b/source/blender/io/usd/intern/usd_reader_light.cc
index 55b9557dfb5..7204ea91896 100644
--- a/source/blender/io/usd/intern/usd_reader_light.cc
+++ b/source/blender/io/usd/intern/usd_reader_light.cc
@@ -203,7 +203,7 @@ void USDLightReader::read_object_data(Main *bmain, const double motionSampleTime
if (pxr::UsdAttribute cone_angle_attr = shaping_api.GetShapingConeAngleAttr()) {
float cone_angle = 0.0f;
if (cone_angle_attr.Get(&cone_angle, motionSampleTime)) {
- blight->spotsize = cone_angle * ((float)M_PI / 180.0f) * 2.0f;
+ blight->spotsize = cone_angle * (float(M_PI) / 180.0f) * 2.0f;
}
}
@@ -226,7 +226,7 @@ void USDLightReader::read_object_data(Main *bmain, const double motionSampleTime
if (pxr::UsdAttribute angle_attr = distant_light.GetAngleAttr()) {
float angle = 0.0f;
if (angle_attr.Get(&angle, motionSampleTime)) {
- blight->sun_angle = angle * (float)M_PI / 180.0f;
+ blight->sun_angle = angle * float(M_PI) / 180.0f;
}
}
}
diff --git a/source/blender/io/usd/intern/usd_reader_material.cc b/source/blender/io/usd/intern/usd_reader_material.cc
index 3546beb022c..d1af4553083 100644
--- a/source/blender/io/usd/intern/usd_reader_material.cc
+++ b/source/blender/io/usd/intern/usd_reader_material.cc
@@ -562,7 +562,7 @@ void USDMaterialReader::follow_connection(const pxr::UsdShadeInput &usd_input,
/* For now, only convert UsdUVTexture and UsdPrimvarReader_float2 inputs. */
if (shader_id == usdtokens::UsdUVTexture) {
- if (strcmp(dest_socket_name, "Normal") == 0) {
+ if (STREQ(dest_socket_name, "Normal")) {
/* The normal texture input requires creating a normal map node. */
float locx = 0.0f;
diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc
index 7cb4c65f166..8138f38fcad 100644
--- a/source/blender/io/usd/intern/usd_reader_mesh.cc
+++ b/source/blender/io/usd/intern/usd_reader_mesh.cc
@@ -33,6 +33,7 @@
#include <pxr/base/vt/value.h>
#include <pxr/usd/sdf/types.h>
#include <pxr/usd/usdGeom/mesh.h>
+#include <pxr/usd/usdGeom/primvarsAPI.h>
#include <pxr/usd/usdGeom/subset.h>
#include <pxr/usd/usdShade/materialBindingAPI.h>
@@ -275,7 +276,7 @@ void USDMeshReader::read_object_data(Main *bmain, const double motionSampleTime)
bool USDMeshReader::valid() const
{
- return static_cast<bool>(mesh_prim_);
+ return bool(mesh_prim_);
}
bool USDMeshReader::topology_changed(const Mesh *existing_mesh, const double motionSampleTime)
@@ -287,11 +288,13 @@ bool USDMeshReader::topology_changed(const Mesh *existing_mesh, const double mot
mesh_prim_.GetFaceVertexCountsAttr().Get(&face_counts_, motionSampleTime);
mesh_prim_.GetPointsAttr().Get(&positions_, motionSampleTime);
+ pxr::UsdGeomPrimvarsAPI primvarsAPI(mesh_prim_);
+
/* TODO(makowalski): Reading normals probably doesn't belong in this function,
* as this is not required to determine if the topology has changed. */
/* If 'normals' and 'primvars:normals' are both specified, the latter has precedence. */
- pxr::UsdGeomPrimvar primvar = mesh_prim_.GetPrimvar(usdtokens::normalsPrimvar);
+ pxr::UsdGeomPrimvar primvar = primvarsAPI.GetPrimvar(usdtokens::normalsPrimvar);
if (primvar.HasValue()) {
primvar.ComputeFlattened(&normals_, motionSampleTime);
normal_interpolation_ = primvar.GetInterpolation();
@@ -342,9 +345,9 @@ void USDMeshReader::read_mpolys(Mesh *mesh)
void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bool load_uvs)
{
- unsigned int loop_index = 0;
- unsigned int rev_loop_index = 0;
- unsigned int uv_index = 0;
+ uint loop_index = 0;
+ uint rev_loop_index = 0;
+ uint uv_index = 0;
const CustomData *ldata = &mesh->ldata;
@@ -355,6 +358,8 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo
std::vector<UVSample> uv_primvars(ldata->totlayer);
+ pxr::UsdGeomPrimvarsAPI primvarsAPI(mesh_prim_);
+
if (has_uvs_) {
for (int layer_idx = 0; layer_idx < ldata->totlayer; layer_idx++) {
const CustomDataLayer *layer = &ldata->layers[layer_idx];
@@ -385,11 +390,11 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo
}
/* Early out if mesh doesn't have primvar. */
- if (!mesh_prim_.HasPrimvar(uv_token)) {
+ if (!primvarsAPI.HasPrimvar(uv_token)) {
continue;
}
- if (pxr::UsdGeomPrimvar uv_primvar = mesh_prim_.GetPrimvar(uv_token)) {
+ if (pxr::UsdGeomPrimvar uv_primvar = primvarsAPI.GetPrimvar(uv_token)) {
uv_primvar.ComputeFlattened(&uv_primvars[layer_idx].uvs, motionSampleTime);
uv_primvars[layer_idx].interpolation = uv_primvar.GetInterpolation();
}
@@ -422,9 +427,9 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo
const UVSample &sample = uv_primvars[layer_idx];
- if (!(ELEM(sample.interpolation,
- pxr::UsdGeomTokens->faceVarying,
- pxr::UsdGeomTokens->vertex))) {
+ if (!ELEM(sample.interpolation,
+ pxr::UsdGeomTokens->faceVarying,
+ pxr::UsdGeomTokens->vertex)) {
std::cerr << "WARNING: unexpected interpolation type " << sample.interpolation
<< " for uv " << layer->name << std::endl;
continue;
@@ -601,7 +606,7 @@ void USDMeshReader::process_normals_vertex_varying(Mesh *mesh)
MutableSpan vert_normals{(float3 *)BKE_mesh_vertex_normals_for_write(mesh), mesh->totvert};
BLI_STATIC_ASSERT(sizeof(normals_[0]) == sizeof(float3), "Expected float3 normals size");
- vert_normals.copy_from({(float3 *)normals_.data(), static_cast<int64_t>(normals_.size())});
+ vert_normals.copy_from({(float3 *)normals_.data(), int64_t(normals_.size())});
BKE_mesh_vertex_normals_clear_dirty(mesh);
}
@@ -804,8 +809,8 @@ void USDMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, const double mot
std::map<pxr::SdfPath, int> mat_map;
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
- bke::SpanAttributeWriter<int> material_indices =
- attributes.lookup_or_add_for_write_only_span<int>("material_index", ATTR_DOMAIN_FACE);
+ bke::SpanAttributeWriter<int> material_indices = attributes.lookup_or_add_for_write_span<int>(
+ "material_index", ATTR_DOMAIN_FACE);
this->assign_facesets_to_material_indices(motionSampleTime, material_indices.span, &mat_map);
material_indices.finish();
/* Build material name map if it's not built yet. */
@@ -835,12 +840,14 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh,
is_left_handed_ = true;
}
+ pxr::UsdGeomPrimvarsAPI primvarsAPI(mesh_prim_);
+
std::vector<pxr::TfToken> uv_tokens;
/* Currently we only handle UV primvars. */
if (read_flag & MOD_MESHSEQ_READ_UV) {
- std::vector<pxr::UsdGeomPrimvar> primvars = mesh_prim_.GetPrimvars();
+ std::vector<pxr::UsdGeomPrimvar> primvars = primvarsAPI.GetPrimvars();
for (pxr::UsdGeomPrimvar p : primvars) {
@@ -865,7 +872,7 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh,
pxr::TfToken interp = p.GetInterpolation();
- if (!(ELEM(interp, pxr::UsdGeomTokens->faceVarying, pxr::UsdGeomTokens->vertex))) {
+ if (!ELEM(interp, pxr::UsdGeomTokens->faceVarying, pxr::UsdGeomTokens->vertex)) {
continue;
}
@@ -914,7 +921,7 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh,
std::map<pxr::SdfPath, int> mat_map;
bke::MutableAttributeAccessor attributes = active_mesh->attributes_for_write();
bke::SpanAttributeWriter<int> material_indices =
- attributes.lookup_or_add_for_write_only_span<int>("material_index", ATTR_DOMAIN_FACE);
+ attributes.lookup_or_add_for_write_span<int>("material_index", ATTR_DOMAIN_FACE);
assign_facesets_to_material_indices(motionSampleTime, material_indices.span, &mat_map);
material_indices.finish();
}
diff --git a/source/blender/io/usd/intern/usd_reader_nurbs.cc b/source/blender/io/usd/intern/usd_reader_nurbs.cc
index d0a5dc1c4b4..0a7058fb100 100644
--- a/source/blender/io/usd/intern/usd_reader_nurbs.cc
+++ b/source/blender/io/usd/intern/usd_reader_nurbs.cc
@@ -33,7 +33,7 @@ static bool set_knots(const pxr::VtDoubleArray &knots, float *&nu_knots)
nu_knots = static_cast<float *>(MEM_callocN(num_knots * sizeof(float), __func__));
for (size_t i = 0; i < num_knots; i++) {
- nu_knots[i] = (float)knots[i];
+ nu_knots[i] = float(knots[i]);
}
return true;
@@ -117,7 +117,7 @@ void USDNurbsReader::read_curve_sample(Curve *cu, const double motionSampleTime)
nu->pntsv = 1;
if (i < orders.size()) {
- nu->orderu = static_cast<short>(orders[i]);
+ nu->orderu = short(orders[i]);
}
else {
nu->orderu = 4;
@@ -141,9 +141,9 @@ void USDNurbsReader::read_curve_sample(Curve *cu, const double motionSampleTime)
BPoint *bp = nu->bp;
for (int j = 0; j < nu->pntsu; j++, bp++, idx++) {
- bp->vec[0] = (float)usdPoints[idx][0];
- bp->vec[1] = (float)usdPoints[idx][1];
- bp->vec[2] = (float)usdPoints[idx][2];
+ bp->vec[0] = float(usdPoints[idx][0]);
+ bp->vec[1] = float(usdPoints[idx][1]);
+ bp->vec[2] = float(usdPoints[idx][2]);
bp->vec[3] = weight;
bp->f1 = SELECT;
bp->weight = weight;
diff --git a/source/blender/io/usd/intern/usd_reader_nurbs.h b/source/blender/io/usd/intern/usd_reader_nurbs.h
index a5441aad3cf..aa3940dc540 100644
--- a/source/blender/io/usd/intern/usd_reader_nurbs.h
+++ b/source/blender/io/usd/intern/usd_reader_nurbs.h
@@ -27,7 +27,7 @@ class USDNurbsReader : public USDGeomReader {
bool valid() const override
{
- return static_cast<bool>(curve_prim_);
+ return bool(curve_prim_);
}
void create_object(Main *bmain, double motionSampleTime) override;
diff --git a/source/blender/io/usd/intern/usd_reader_volume.cc b/source/blender/io/usd/intern/usd_reader_volume.cc
index 13044de5002..fc25dda53b9 100644
--- a/source/blender/io/usd/intern/usd_reader_volume.cc
+++ b/source/blender/io/usd/intern/usd_reader_volume.cc
@@ -65,10 +65,10 @@ void USDVolumeReader::read_object_data(Main *bmain, const double motionSampleTim
filepathAttr.GetTimeSamples(&filePathTimes);
if (!filePathTimes.empty()) {
- int start = static_cast<int>(filePathTimes.front());
- int end = static_cast<int>(filePathTimes.back());
+ int start = int(filePathTimes.front());
+ int end = int(filePathTimes.back());
- volume->is_sequence = static_cast<char>(true);
+ volume->is_sequence = char(true);
volume->frame_start = start;
volume->frame_duration = (end - start) + 1;
}
diff --git a/source/blender/io/usd/intern/usd_reader_volume.h b/source/blender/io/usd/intern/usd_reader_volume.h
index 350fae6ada0..923c3d140c9 100644
--- a/source/blender/io/usd/intern/usd_reader_volume.h
+++ b/source/blender/io/usd/intern/usd_reader_volume.h
@@ -23,7 +23,7 @@ class USDVolumeReader : public USDXformReader {
bool valid() const override
{
- return static_cast<bool>(volume_);
+ return bool(volume_);
}
void create_object(Main *bmain, double motionSampleTime) override;
diff --git a/source/blender/io/usd/intern/usd_writer_hair.cc b/source/blender/io/usd/intern/usd_writer_hair.cc
index 478a9e26274..8ec1447b505 100644
--- a/source/blender/io/usd/intern/usd_writer_hair.cc
+++ b/source/blender/io/usd/intern/usd_writer_hair.cc
@@ -64,7 +64,7 @@ void USDHairWriter::do_write(HierarchyContext &context)
}
}
-bool USDHairWriter::check_is_animated(const HierarchyContext &UNUSED(context)) const
+bool USDHairWriter::check_is_animated(const HierarchyContext & /*context*/) const
{
return true;
}
diff --git a/source/blender/io/usd/intern/usd_writer_material.cc b/source/blender/io/usd/intern/usd_writer_material.cc
index 6862f3835cf..75abae79519 100644
--- a/source/blender/io/usd/intern/usd_writer_material.cc
+++ b/source/blender/io/usd/intern/usd_writer_material.cc
@@ -380,7 +380,7 @@ static void export_in_memory_texture(Image *ima,
BKE_image_path_ensure_ext_from_imformat(file_name, &imageFormat);
char export_path[FILE_MAX];
- BLI_path_join(export_path, FILE_MAX, export_dir.c_str(), file_name, nullptr);
+ BLI_path_join(export_path, FILE_MAX, export_dir.c_str(), file_name);
if (!allow_overwrite && BLI_exists(export_path)) {
return;
@@ -455,7 +455,7 @@ static bNode *traverse_channel(bNodeSocket *input, const short target_type)
static bNode *find_bsdf_node(Material *material)
{
LISTBASE_FOREACH (bNode *, node, &material->nodetree->nodes) {
- if (node->type == SH_NODE_BSDF_PRINCIPLED || node->type == SH_NODE_BSDF_DIFFUSE) {
+ if (ELEM(node->type, SH_NODE_BSDF_PRINCIPLED, SH_NODE_BSDF_DIFFUSE)) {
return node;
}
}
@@ -576,7 +576,7 @@ static std::string get_tex_image_asset_path(bNode *node,
BLI_split_file_part(path.c_str(), file_path, FILE_MAX);
if (export_params.relative_paths) {
- BLI_path_join(exp_path, FILE_MAX, ".", "textures", file_path, nullptr);
+ BLI_path_join(exp_path, FILE_MAX, ".", "textures", file_path);
}
else {
/* Create absolute path in the textures directory. */
@@ -588,7 +588,7 @@ static std::string get_tex_image_asset_path(bNode *node,
char dir_path[FILE_MAX];
BLI_split_dir_part(stage_path.c_str(), dir_path, FILE_MAX);
- BLI_path_join(exp_path, FILE_MAX, dir_path, "textures", file_path, nullptr);
+ BLI_path_join(exp_path, FILE_MAX, dir_path, "textures", file_path);
}
BLI_str_replace_char(exp_path, '\\', '/');
return exp_path;
@@ -645,7 +645,7 @@ static void copy_tiled_textures(Image *ima,
BLI_split_file_part(src_tile_path, dest_filename, sizeof(dest_filename));
char dest_tile_path[FILE_MAX];
- BLI_path_join(dest_tile_path, FILE_MAX, dest_dir.c_str(), dest_filename, nullptr);
+ BLI_path_join(dest_tile_path, FILE_MAX, dest_dir.c_str(), dest_filename);
if (!allow_overwrite && BLI_exists(dest_tile_path)) {
continue;
@@ -680,7 +680,7 @@ static void copy_single_file(Image *ima, const std::string &dest_dir, const bool
BLI_split_file_part(source_path, file_name, FILE_MAX);
char dest_path[FILE_MAX];
- BLI_path_join(dest_path, FILE_MAX, dest_dir.c_str(), file_name, nullptr);
+ BLI_path_join(dest_path, FILE_MAX, dest_dir.c_str(), file_name);
if (!allow_overwrite && BLI_exists(dest_path)) {
return;
@@ -707,7 +707,7 @@ static void export_texture(bNode *node,
const pxr::UsdStageRefPtr stage,
const bool allow_overwrite)
{
- if (node->type != SH_NODE_TEX_IMAGE && node->type != SH_NODE_TEX_ENVIRONMENT) {
+ if (!ELEM(node->type, SH_NODE_TEX_IMAGE, SH_NODE_TEX_ENVIRONMENT)) {
return;
}
@@ -726,7 +726,7 @@ static void export_texture(bNode *node,
BLI_split_dir_part(stage_path.c_str(), usd_dir_path, FILE_MAX);
char tex_dir_path[FILE_MAX];
- BLI_path_join(tex_dir_path, FILE_MAX, usd_dir_path, "textures", SEP_STR, nullptr);
+ BLI_path_join(tex_dir_path, FILE_MAX, usd_dir_path, "textures", SEP_STR);
BLI_dir_create_recursive(tex_dir_path);
diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc
index a39f74c6420..e7d79e888e4 100644
--- a/source/blender/io/usd/intern/usd_writer_mesh.cc
+++ b/source/blender/io/usd/intern/usd_writer_mesh.cc
@@ -4,6 +4,7 @@
#include "usd_hierarchy_iterator.h"
#include <pxr/usd/usdGeom/mesh.h>
+#include <pxr/usd/usdGeom/primvarsAPI.h>
#include <pxr/usd/usdShade/material.h>
#include <pxr/usd/usdShade/materialBindingAPI.h>
@@ -107,6 +108,8 @@ void USDGenericMeshWriter::write_uv_maps(const Mesh *mesh, pxr::UsdGeomMesh usd_
{
pxr::UsdTimeCode timecode = get_export_time_code();
+ pxr::UsdGeomPrimvarsAPI primvarsAPI(usd_mesh.GetPrim());
+
const CustomData *ldata = &mesh->ldata;
for (int layer_idx = 0; layer_idx < ldata->totlayer; layer_idx++) {
const CustomDataLayer *layer = &ldata->layers[layer_idx];
@@ -119,7 +122,7 @@ void USDGenericMeshWriter::write_uv_maps(const Mesh *mesh, pxr::UsdGeomMesh usd_
* for texture coordinates by naming the UV Map as such, without having to guess which UV Map
* is the "standard" one. */
pxr::TfToken primvar_name(pxr::TfMakeValidIdentifier(layer->name));
- pxr::UsdGeomPrimvar uv_coords_primvar = usd_mesh.CreatePrimvar(
+ pxr::UsdGeomPrimvar uv_coords_primvar = primvarsAPI.CreatePrimvar(
primvar_name, pxr::SdfValueTypeNames->TexCoord2fArray, pxr::UsdGeomTokens->faceVarying);
MLoopUV *mloopuv = static_cast<MLoopUV *>(layer->data);
@@ -283,25 +286,22 @@ static void get_loops_polys(const Mesh *mesh, USDMeshData &usd_mesh_data)
static void get_edge_creases(const Mesh *mesh, USDMeshData &usd_mesh_data)
{
- const float factor = 1.0f / 255.0f;
+ const float *creases = static_cast<const float *>(CustomData_get_layer(&mesh->edata, CD_CREASE));
+ if (!creases) {
+ return;
+ }
const Span<MEdge> edges = mesh->edges();
- float sharpness;
for (const int i : edges.index_range()) {
- const MEdge &edge = edges[i];
- if (edge.crease == 0) {
+ const float crease = creases[i];
+ if (crease == 0.0f) {
continue;
}
- if (edge.crease == 255) {
- sharpness = pxr::UsdGeomMesh::SHARPNESS_INFINITE;
- }
- else {
- sharpness = static_cast<float>(edge.crease) * factor;
- }
+ const float sharpness = crease >= 1.0f ? pxr::UsdGeomMesh::SHARPNESS_INFINITE : crease;
- usd_mesh_data.crease_vertex_indices.push_back(edge.v1);
- usd_mesh_data.crease_vertex_indices.push_back(edge.v2);
+ usd_mesh_data.crease_vertex_indices.push_back(edges[i].v1);
+ usd_mesh_data.crease_vertex_indices.push_back(edges[i].v2);
usd_mesh_data.crease_lengths.push_back(2);
usd_mesh_data.crease_sharpnesses.push_back(sharpness);
}
diff --git a/source/blender/io/usd/intern/usd_writer_volume.cc b/source/blender/io/usd/intern/usd_writer_volume.cc
index 12db6d73901..c6a27c5f663 100644
--- a/source/blender/io/usd/intern/usd_writer_volume.cc
+++ b/source/blender/io/usd/intern/usd_writer_volume.cc
@@ -145,14 +145,14 @@ std::optional<std::string> USDVolumeWriter::construct_vdb_file_path(const Volume
BLI_strncpy(vdb_file_name, volume->id.name + 2, FILE_MAXFILE);
const pxr::UsdTimeCode timecode = get_export_time_code();
if (!timecode.IsDefault()) {
- const int frame = (int)timecode.GetValue();
+ const int frame = int(timecode.GetValue());
const int num_frame_digits = frame == 0 ? 1 : integer_digits_i(abs(frame));
BLI_path_frame(vdb_file_name, frame, num_frame_digits);
}
strcat(vdb_file_name, ".vdb");
char vdb_file_path[FILE_MAX];
- BLI_path_join(vdb_file_path, sizeof(vdb_file_path), vdb_directory_path, vdb_file_name, nullptr);
+ BLI_path_join(vdb_file_path, sizeof(vdb_file_path), vdb_directory_path, vdb_file_name);
return vdb_file_path;
}
diff --git a/source/blender/io/usd/tests/usd_imaging_test.cc b/source/blender/io/usd/tests/usd_imaging_test.cc
index 5cd3c042e59..80c232ad099 100644
--- a/source/blender/io/usd/tests/usd_imaging_test.cc
+++ b/source/blender/io/usd/tests/usd_imaging_test.cc
@@ -42,8 +42,8 @@ TEST_F(USDImagingTest, CapsuleAdapterTest)
}
pxr::UsdImagingCapsuleAdapter capsule_adapter;
- pxr::VtValue points_value = pxr::UsdImagingCapsuleAdapter::GetMeshPoints(
- capsule.GetPrim(), pxr::UsdTimeCode::Default());
+ pxr::VtValue points_value = capsule_adapter.GetPoints(capsule.GetPrim(),
+ pxr::UsdTimeCode::Default());
if (!points_value.IsHolding<pxr::VtArray<pxr::GfVec3f>>()) {
FAIL() << "Mesh points value holding unexpected type.";
return;
@@ -52,7 +52,8 @@ TEST_F(USDImagingTest, CapsuleAdapterTest)
pxr::VtArray<pxr::GfVec3f> points = points_value.Get<pxr::VtArray<pxr::GfVec3f>>();
EXPECT_FALSE(points.empty());
- pxr::VtValue topology_value = pxr::UsdImagingCapsuleAdapter::GetMeshTopology();
+ pxr::VtValue topology_value = capsule_adapter.GetTopology(
+ capsule.GetPrim(), pxr::SdfPath(), pxr::UsdTimeCode::Default());
if (!topology_value.IsHolding<pxr::HdMeshTopology>()) {
FAIL() << "Mesh topology value holding unexpected type.";
diff --git a/source/blender/io/usd/tests/usd_tests_common.cc b/source/blender/io/usd/tests/usd_tests_common.cc
index 9f18a289433..ea4e704006d 100644
--- a/source/blender/io/usd/tests/usd_tests_common.cc
+++ b/source/blender/io/usd/tests/usd_tests_common.cc
@@ -29,7 +29,7 @@ std::string register_usd_plugins_for_tests()
}
const size_t path_len = BLI_path_join(
- usd_datafiles_dir, FILE_MAX, release_dir.c_str(), "datafiles", "usd", nullptr);
+ usd_datafiles_dir, FILE_MAX, release_dir.c_str(), "datafiles", "usd");
/* #BLI_path_join removes trailing slashes, but the USD library requires one in order to
* recognize the path as directory. */
diff --git a/source/blender/io/wavefront_obj/CMakeLists.txt b/source/blender/io/wavefront_obj/CMakeLists.txt
index f7958ef4ec6..bfbc715a45f 100644
--- a/source/blender/io/wavefront_obj/CMakeLists.txt
+++ b/source/blender/io/wavefront_obj/CMakeLists.txt
@@ -2,8 +2,8 @@
set(INC
.
- ./exporter
- ./importer
+ exporter
+ importer
../common
../../blenkernel
../../blenlib
diff --git a/source/blender/io/wavefront_obj/IO_wavefront_obj.h b/source/blender/io/wavefront_obj/IO_wavefront_obj.h
index 0a92bbca477..cf6464eeb37 100644
--- a/source/blender/io/wavefront_obj/IO_wavefront_obj.h
+++ b/source/blender/io/wavefront_obj/IO_wavefront_obj.h
@@ -35,7 +35,7 @@ struct OBJExportParams {
/* Geometry Transform options. */
eIOAxis forward_axis;
eIOAxis up_axis;
- float scaling_factor;
+ float global_scale;
/* File Write Options. */
bool export_selected_objects;
@@ -65,6 +65,7 @@ struct OBJImportParams {
char filepath[FILE_MAX];
/** Value 0 disables clamping. */
float clamp_size;
+ float global_scale;
eIOAxis forward_axis;
eIOAxis up_axis;
bool import_vertex_groups;
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc
index f2547e6fc14..5289a8c750a 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc
@@ -7,8 +7,9 @@
#include <algorithm>
#include <cstdio>
+#include "BKE_attribute.hh"
#include "BKE_blender_version.h"
-#include "BKE_geometry_set.hh"
+#include "BKE_mesh.h"
#include "BLI_color.hh"
#include "BLI_enumerable_thread_specific.hh"
@@ -261,7 +262,7 @@ void OBJWriter::write_vertex_coords(FormatHandler &fh,
BLI_assert(tot_count == attribute.size());
obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler &buf, int i) {
- float3 vertex = obj_mesh_data.calc_vertex_coords(i, export_params_.scaling_factor);
+ float3 vertex = obj_mesh_data.calc_vertex_coords(i, export_params_.global_scale);
ColorGeometry4f linear = attribute.get(i);
float srgb[3];
linearrgb_to_srgb_v3_v3(srgb, linear);
@@ -270,7 +271,7 @@ void OBJWriter::write_vertex_coords(FormatHandler &fh,
}
else {
obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler &buf, int i) {
- float3 vertex = obj_mesh_data.calc_vertex_coords(i, export_params_.scaling_factor);
+ float3 vertex = obj_mesh_data.calc_vertex_coords(i, export_params_.global_scale);
buf.write_obj_vertex(vertex[0], vertex[1], vertex[2]);
});
}
@@ -416,15 +417,12 @@ void OBJWriter::write_edges_indices(FormatHandler &fh,
const OBJMesh &obj_mesh_data) const
{
/* NOTE: ensure_mesh_edges should be called before. */
- const int tot_edges = obj_mesh_data.tot_edges();
- for (int edge_index = 0; edge_index < tot_edges; edge_index++) {
- const std::optional<std::array<int, 2>> vertex_indices =
- obj_mesh_data.calc_loose_edge_vert_indices(edge_index);
- if (!vertex_indices) {
- continue;
+ const Span<MEdge> edges = obj_mesh_data.get_mesh()->edges();
+ for (const int i : edges.index_range()) {
+ const MEdge &edge = edges[i];
+ if (edge.flag & ME_LOOSEEDGE) {
+ fh.write_obj_edge(edge.v1 + offsets.vertex_offset + 1, edge.v2 + offsets.vertex_offset + 1);
}
- fh.write_obj_edge((*vertex_indices)[0] + offsets.vertex_offset + 1,
- (*vertex_indices)[1] + offsets.vertex_offset + 1);
}
}
@@ -435,7 +433,7 @@ void OBJWriter::write_nurbs_curve(FormatHandler &fh, const OBJCurve &obj_nurbs_d
const int total_vertices = obj_nurbs_data.total_spline_vertices(spline_idx);
for (int vertex_idx = 0; vertex_idx < total_vertices; vertex_idx++) {
const float3 vertex_coords = obj_nurbs_data.vertex_coordinates(
- spline_idx, vertex_idx, export_params_.scaling_factor);
+ spline_idx, vertex_idx, export_params_.global_scale);
fh.write_obj_vertex(vertex_coords[0], vertex_coords[1], vertex_coords[2]);
}
@@ -503,7 +501,7 @@ static const char *tex_map_type_to_string[] = {
"map_d",
"map_Bump",
};
-BLI_STATIC_ASSERT(ARRAY_SIZE(tex_map_type_to_string) == (int)MTLTexMapType::Count,
+BLI_STATIC_ASSERT(ARRAY_SIZE(tex_map_type_to_string) == int(MTLTexMapType::Count),
"array size mismatch");
/**
@@ -641,7 +639,7 @@ void MTLWriter::write_texture_map(const MTLMaterial &mtl_material,
/* Always emit forward slashes for cross-platform compatibility. */
std::replace(path.begin(), path.end(), '\\', '/');
- fmt_handler_.write_mtl_map(tex_map_type_to_string[(int)texture_key], options, path);
+ fmt_handler_.write_mtl_map(tex_map_type_to_string[int(texture_key)], options, path);
}
static bool is_pbr_map(MTLTexMapType type)
@@ -677,7 +675,7 @@ void MTLWriter::write_materials(const char *blen_filepath,
fmt_handler_.write_string("");
fmt_handler_.write_mtl_newmtl(mtlmat.name);
write_bsdf_properties(mtlmat, write_pbr);
- for (int key = 0; key < (int)MTLTexMapType::Count; key++) {
+ for (int key = 0; key < int(MTLTexMapType::Count); key++) {
const MTLTexMap &tex = mtlmat.texture_maps[key];
if (!tex.is_valid()) {
continue;
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
index 10880b016fb..a95f917869b 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
@@ -124,10 +124,11 @@ void OBJMesh::set_world_axes_transform(const eIOAxis forward, const eIOAxis up)
unit_m3(axes_transform);
/* +Y-forward and +Z-up are the default Blender axis settings. */
mat3_from_axis_conversion(forward, up, IO_AXIS_Y, IO_AXIS_Z, axes_transform);
- mul_m4_m3m4(world_and_axes_transform_, axes_transform, export_object_eval_.obmat);
+ mul_m4_m3m4(world_and_axes_transform_, axes_transform, export_object_eval_.object_to_world);
/* mul_m4_m3m4 does not transform last row of obmat, i.e. location data. */
- mul_v3_m3v3(world_and_axes_transform_[3], axes_transform, export_object_eval_.obmat[3]);
- world_and_axes_transform_[3][3] = export_object_eval_.obmat[3][3];
+ mul_v3_m3v3(
+ world_and_axes_transform_[3], axes_transform, export_object_eval_.object_to_world[3]);
+ world_and_axes_transform_[3][3] = export_object_eval_.object_to_world[3][3];
/* Normals need inverse transpose of the regular matrix to handle non-uniform scale. */
float normal_matrix[3][3];
@@ -182,7 +183,6 @@ void OBJMesh::ensure_mesh_normals() const
void OBJMesh::ensure_mesh_edges() const
{
- BKE_mesh_calc_edges(export_mesh_eval_, true, false);
BKE_mesh_calc_edges_loose(export_mesh_eval_);
}
@@ -265,13 +265,13 @@ const char *OBJMesh::get_object_material_name(const int16_t mat_nr) const
return mat->id.name + 2;
}
-float3 OBJMesh::calc_vertex_coords(const int vert_index, const float scaling_factor) const
+float3 OBJMesh::calc_vertex_coords(const int vert_index, const float global_scale) const
{
float3 r_coords;
const Span<MVert> verts = export_mesh_eval_->verts();
copy_v3_v3(r_coords, verts[vert_index].co);
mul_m4_v3(world_and_axes_transform_, r_coords);
- mul_v3_fl(r_coords, scaling_factor);
+ mul_v3_fl(r_coords, global_scale);
return r_coords;
}
@@ -302,8 +302,16 @@ void OBJMesh::store_uv_coords_and_indices()
}
const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT};
- UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(
- polys.data(), nullptr, loops.data(), mloopuv, polys.size(), totvert, limit, false, false);
+ UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(polys.data(),
+ nullptr,
+ nullptr,
+ loops.data(),
+ mloopuv,
+ polys.size(),
+ totvert,
+ limit,
+ false,
+ false);
uv_indices_.resize(polys.size());
/* At least total vertices of a mesh will be present in its texture map. So
@@ -361,7 +369,7 @@ float3 OBJMesh::calc_poly_normal(const int poly_index) const
static float round_float_to_n_digits(const float f, int round_digits)
{
float scale = powf(10.0, round_digits);
- return ceilf((scale * f - 0.49999999f)) / scale;
+ return ceilf(scale * f - 0.49999999f) / scale;
}
static float3 round_float3_to_n_digits(const float3 &v, int round_digits)
@@ -498,13 +506,4 @@ const char *OBJMesh::get_poly_deform_group_name(const int16_t def_group_index) c
return vertex_group.name;
}
-std::optional<std::array<int, 2>> OBJMesh::calc_loose_edge_vert_indices(const int edge_index) const
-{
- const Span<MEdge> edges = export_mesh_eval_->edges();
- const MEdge &edge = edges[edge_index];
- if (edge.flag & ME_LOOSEEDGE) {
- return std::array<int, 2>{static_cast<int>(edge.v1), static_cast<int>(edge.v2)};
- }
- return std::nullopt;
-}
} // namespace blender::io::obj
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh
index db29f5651ed..89ee6f4dea2 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh
@@ -161,7 +161,7 @@ class OBJMesh : NonCopyable {
/**
* Calculate coordinates of the vertex at the given index.
*/
- float3 calc_vertex_coords(int vert_index, float scaling_factor) const;
+ float3 calc_vertex_coords(int vert_index, float global_scale) const;
/**
* Calculate vertex indices of all vertices of the polygon at the given index.
*/
@@ -216,11 +216,6 @@ class OBJMesh : NonCopyable {
const char *get_poly_deform_group_name(int16_t def_group_index) const;
/**
- * Calculate vertex indices of an edge's corners if it is a loose edge.
- */
- std::optional<std::array<int, 2>> calc_loose_edge_vert_indices(int edge_index) const;
-
- /**
* Calculate the order in which the polygons should be written into the file (sorted by material
* index).
*/
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc
index f8c7da75a70..0231bc79b89 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc
@@ -33,7 +33,7 @@ const char *tex_map_type_to_socket_id[] = {
"Alpha",
"Normal",
};
-BLI_STATIC_ASSERT(ARRAY_SIZE(tex_map_type_to_socket_id) == (int)MTLTexMapType::Count,
+BLI_STATIC_ASSERT(ARRAY_SIZE(tex_map_type_to_socket_id) == int(MTLTexMapType::Count),
"array size mismatch");
/**
@@ -153,7 +153,7 @@ static std::string get_image_filepath(const bNode *tex_node)
if (tex_image->source == IMA_SRC_SEQUENCE) {
char head[FILE_MAX], tail[FILE_MAX];
- unsigned short numlen;
+ ushort numlen;
int framenr = static_cast<NodeTexImage *>(tex_node->storage)->iuser.framenr;
BLI_path_sequence_decode(path, head, tail, &numlen);
BLI_path_sequence_encode(path, head, tail, numlen, framenr);
@@ -312,12 +312,12 @@ static void store_image_textures(const bNode *bsdf_node,
* - finding "Strength" property of the node for `-bm` option.
*/
- for (int key = 0; key < (int)MTLTexMapType::Count; ++key) {
+ for (int key = 0; key < int(MTLTexMapType::Count); ++key) {
MTLTexMap &value = r_mtl_mat.texture_maps[key];
Vector<const bNodeSocket *> linked_sockets;
const bNode *normal_map_node{nullptr};
- if (key == (int)MTLTexMapType::Normal) {
+ if (key == int(MTLTexMapType::Normal)) {
/* Find sockets linked to destination "Normal" socket in P-BSDF node. */
linked_sockets_to_dest_id(bsdf_node, *node_tree, "Normal", linked_sockets);
/* Among the linked sockets, find Normal Map shader node. */
@@ -328,7 +328,7 @@ static void store_image_textures(const bNode *bsdf_node,
}
else {
/* Skip emission map if emission strength is zero. */
- if (key == (int)MTLTexMapType::Emission) {
+ if (key == int(MTLTexMapType::Emission)) {
float emission_strength = 0.0f;
copy_property_from_node(
SOCK_FLOAT, bsdf_node, "Emission Strength", {&emission_strength, 1});
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh
index 9c1bc2f0f8f..2d4edd8979d 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh
@@ -49,11 +49,11 @@ struct MTLTexMap {
struct MTLMaterial {
const MTLTexMap &tex_map_of_type(MTLTexMapType key) const
{
- return texture_maps[(int)key];
+ return texture_maps[int(key)];
}
MTLTexMap &tex_map_of_type(MTLTexMapType key)
{
- return texture_maps[(int)key];
+ return texture_maps[int(key)];
}
std::string name;
@@ -76,7 +76,7 @@ struct MTLMaterial {
float aniso_rot{-1.0f}; /* `anisor` */
int illum_mode{-1};
- MTLTexMap texture_maps[(int)MTLTexMapType::Count];
+ MTLTexMap texture_maps[int(MTLTexMapType::Count)];
/* Only used for Normal Map node: `map_Bump`. */
float normal_strength{-1.0f};
};
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc b/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc
index 172a59e5341..1b1ee5f8386 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc
@@ -31,10 +31,10 @@ void OBJCurve::set_world_axes_transform(const eIOAxis forward, const eIOAxis up)
unit_m3(axes_transform);
/* +Y-forward and +Z-up are the Blender's default axis settings. */
mat3_from_axis_conversion(forward, up, IO_AXIS_Y, IO_AXIS_Z, axes_transform);
- mul_m4_m3m4(world_axes_transform_, axes_transform, export_object_eval_->obmat);
- /* #mul_m4_m3m4 does not transform last row of #Object.obmat, i.e. location data. */
- mul_v3_m3v3(world_axes_transform_[3], axes_transform, export_object_eval_->obmat[3]);
- world_axes_transform_[3][3] = export_object_eval_->obmat[3][3];
+ mul_m4_m3m4(world_axes_transform_, axes_transform, export_object_eval_->object_to_world);
+ /* #mul_m4_m3m4 does not transform last row of #Object.object_to_world, i.e. location data. */
+ mul_v3_m3v3(world_axes_transform_[3], axes_transform, export_object_eval_->object_to_world[3]);
+ world_axes_transform_[3][3] = export_object_eval_->object_to_world[3][3];
}
const char *OBJCurve::get_curve_name() const
@@ -55,14 +55,14 @@ int OBJCurve::total_spline_vertices(const int spline_index) const
float3 OBJCurve::vertex_coordinates(const int spline_index,
const int vertex_index,
- const float scaling_factor) const
+ const float global_scale) const
{
const Nurb *const nurb = static_cast<Nurb *>(BLI_findlink(&export_curve_->nurb, spline_index));
float3 r_coord;
const BPoint &bpoint = nurb->bp[vertex_index];
copy_v3_v3(r_coord, bpoint.vec);
mul_m4_v3(world_axes_transform_, r_coord);
- mul_v3_fl(r_coord, scaling_factor);
+ mul_v3_fl(r_coord, global_scale);
return r_coord;
}
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.hh b/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.hh
index 65389d44f59..3f93112200f 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.hh
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.hh
@@ -37,7 +37,7 @@ class OBJCurve : NonCopyable {
/**
* Get coordinates of the vertex at the given index on the given spline.
*/
- float3 vertex_coordinates(int spline_index, int vertex_index, float scaling_factor) const;
+ float3 vertex_coordinates(int spline_index, int vertex_index, float global_scale) const;
/**
* Get total control points of the NURBS spline at the given index. This is different than total
* vertices of a spline.
diff --git a/source/blender/io/wavefront_obj/exporter/obj_exporter.cc b/source/blender/io/wavefront_obj/exporter/obj_exporter.cc
index a51c017f81d..daf2a06e112 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_exporter.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_exporter.cc
@@ -89,11 +89,12 @@ filter_supported_objects(Depsgraph *depsgraph, const OBJExportParams &export_par
{
Vector<std::unique_ptr<OBJMesh>> r_exportable_meshes;
Vector<std::unique_ptr<OBJCurve>> r_exportable_nurbs;
- const int deg_objects_visibility_flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
- DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
- DEG_ITER_OBJECT_FLAG_VISIBLE |
- DEG_ITER_OBJECT_FLAG_DUPLI;
- DEG_OBJECT_ITER_BEGIN (depsgraph, object, deg_objects_visibility_flags) {
+ DEGObjectIterSettings deg_iter_settings{};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, object) {
if (export_params.export_selected_objects && !(object->base_flag & BASE_SELECTED)) {
continue;
}
diff --git a/source/blender/io/wavefront_obj/importer/importer_mesh_utils.cc b/source/blender/io/wavefront_obj/importer/importer_mesh_utils.cc
index f33753d720d..204237088ab 100644
--- a/source/blender/io/wavefront_obj/importer/importer_mesh_utils.cc
+++ b/source/blender/io/wavefront_obj/importer/importer_mesh_utils.cc
@@ -103,6 +103,9 @@ void transform_object(Object *object, const OBJImportParams &import_params)
IO_AXIS_Y, IO_AXIS_Z, import_params.forward_axis, import_params.up_axis, axes_transform);
copy_m4_m3(obmat, axes_transform);
+ float scale_vec[3] = {
+ import_params.global_scale, import_params.global_scale, import_params.global_scale};
+ rescale_m4(obmat, scale_vec);
BKE_object_apply_mat4(object, obmat, true, false);
if (import_params.clamp_size != 0.0f) {
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
index f92f9894f75..7d5f023af4b 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
@@ -103,10 +103,10 @@ static void geom_add_mrgb_colors(const char *p, const char *end, GlobalVertices
while (p + mrgb_length <= end) {
uint32_t value = 0;
std::from_chars_result res = std::from_chars(p, p + mrgb_length, value, 16);
- if (res.ec == std::errc::invalid_argument || res.ec == std::errc::result_out_of_range) {
+ if (ELEM(res.ec, std::errc::invalid_argument, std::errc::result_out_of_range)) {
return;
}
- unsigned char srgb[4];
+ uchar srgb[4];
srgb[0] = (value >> 16) & 0xFF;
srgb[1] = (value >> 8) & 0xFF;
srgb[2] = value & 0xFF;
@@ -164,7 +164,7 @@ static void geom_add_edge(Geometry *geom,
edge_v1 += edge_v1 < 0 ? r_global_vertices.vertices.size() : -1;
edge_v2 += edge_v2 < 0 ? r_global_vertices.vertices.size() : -1;
BLI_assert(edge_v1 >= 0 && edge_v2 >= 0);
- geom->edges_.append({static_cast<uint>(edge_v1), static_cast<uint>(edge_v2)});
+ geom->edges_.append({uint(edge_v1), uint(edge_v2)});
geom->track_vertex_index(edge_v1);
geom->track_vertex_index(edge_v2);
}
@@ -216,7 +216,7 @@ static void geom_add_polygon(Geometry *geom,
fprintf(stderr,
"Invalid vertex index %i (valid range [0, %zu)), ignoring face\n",
corner.vert_index,
- (size_t)global_vertices.vertices.size());
+ size_t(global_vertices.vertices.size()));
face_valid = false;
}
else {
@@ -228,7 +228,7 @@ static void geom_add_polygon(Geometry *geom,
fprintf(stderr,
"Invalid UV index %i (valid range [0, %zu)), ignoring face\n",
corner.uv_vert_index,
- (size_t)global_vertices.uv_vertices.size());
+ size_t(global_vertices.uv_vertices.size()));
face_valid = false;
}
}
@@ -244,7 +244,7 @@ static void geom_add_polygon(Geometry *geom,
fprintf(stderr,
"Invalid normal index %i (valid range [0, %zu)), ignoring face\n",
corner.vertex_normal_index,
- (size_t)global_vertices.vertex_normals.size());
+ size_t(global_vertices.vertex_normals.size()));
face_valid = false;
}
}
@@ -485,7 +485,7 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries,
/* Parse the buffer (until last newline) that we have so far,
* line by line. */
- StringRef buffer_str{buffer.data(), (int64_t)last_nl};
+ StringRef buffer_str{buffer.data(), int64_t(last_nl)};
while (!buffer_str.is_empty()) {
StringRef line = read_next_line(buffer_str);
const char *p = line.begin(), *end = line.end();
@@ -508,6 +508,15 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries,
}
/* Faces. */
else if (parse_keyword(p, end, "f")) {
+ /* If we don't have a material index assigned yet, get one.
+ * It means "usemtl" state came from the previous object. */
+ if (state_material_index == -1 && !state_material_name.empty() &&
+ curr_geom->material_indices_.is_empty()) {
+ curr_geom->material_indices_.add_new(state_material_name, 0);
+ curr_geom->material_order_.append(state_material_name);
+ state_material_index = 0;
+ }
+
geom_add_polygon(curr_geom,
p,
end,
@@ -524,7 +533,10 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries,
else if (parse_keyword(p, end, "o")) {
state_shaded_smooth = false;
state_group_name = "";
- state_material_name = "";
+ /* Reset object-local material index that's used in face infos.
+ * NOTE: do not reset the material name; that has to carry over
+ * into the next object if needed. */
+ state_material_index = -1;
curr_geom = create_geometry(
curr_geom, GEOM_MESH, StringRef(p, end).trim(), r_all_geometries);
}
@@ -753,7 +765,7 @@ MTLParser::MTLParser(StringRefNull mtl_library, StringRefNull obj_filepath)
{
char obj_file_dir[FILE_MAXDIR];
BLI_split_dir_part(obj_filepath.data(), obj_file_dir, FILE_MAXDIR);
- BLI_path_join(mtl_file_path_, FILE_MAX, obj_file_dir, mtl_library.data(), nullptr);
+ BLI_path_join(mtl_file_path_, FILE_MAX, obj_file_dir, mtl_library.data());
BLI_split_dir_part(mtl_file_path_, mtl_dir_path_, FILE_MAXDIR);
}
@@ -768,7 +780,7 @@ void MTLParser::parse_and_store(Map<string, std::unique_ptr<MTLMaterial>> &r_mat
MTLMaterial *material = nullptr;
- StringRef buffer_str{(const char *)buffer, (int64_t)buffer_len};
+ StringRef buffer_str{(const char *)buffer, int64_t(buffer_len)};
while (!buffer_str.is_empty()) {
const StringRef line = read_next_line(buffer_str);
const char *p = line.begin(), *end = line.end();
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc
index ef05534928a..56ad7fd4563 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc
@@ -166,7 +166,7 @@ void MeshFromGeometry::create_vertices(Mesh *mesh)
if (!mesh_geometry_.vertices_.contains(vi)) {
continue;
}
- int local_vi = (int)mesh_geometry_.global_to_local_vertices_.size();
+ int local_vi = int(mesh_geometry_.global_to_local_vertices_.size());
BLI_assert(local_vi >= 0 && local_vi < mesh->totvert);
copy_v3_v3(verts[local_vi].co, global_vertices_.vertices[vi]);
mesh_geometry_.global_to_local_vertices_.add_new(vi, local_vi);
@@ -254,7 +254,6 @@ void MeshFromGeometry::create_edges(Mesh *mesh)
dst_edge.v1 = mesh_geometry_.global_to_local_vertices_.lookup_default(src_edge.v1, 0);
dst_edge.v2 = mesh_geometry_.global_to_local_vertices_.lookup_default(src_edge.v2, 0);
BLI_assert(dst_edge.v1 < total_verts && dst_edge.v2 < total_verts);
- dst_edge.flag = ME_LOOSEEDGE;
}
/* Set argument `update` to true so that existing, explicitly imported edges can be merged
@@ -275,12 +274,13 @@ void MeshFromGeometry::create_uv_verts(Mesh *mesh)
for (const PolyElem &curr_face : mesh_geometry_.face_elements_) {
for (int idx = 0; idx < curr_face.corner_count_; ++idx) {
const PolyCorner &curr_corner = mesh_geometry_.face_corners_[curr_face.start_index_ + idx];
- if (curr_corner.uv_vert_index >= 0 &&
- curr_corner.uv_vert_index < global_vertices_.uv_vertices.size()) {
- const float2 &mluv_src = global_vertices_.uv_vertices[curr_corner.uv_vert_index];
- copy_v2_v2(mluv_dst[tot_loop_idx].uv, mluv_src);
- tot_loop_idx++;
+ const int uv_index = curr_corner.uv_vert_index;
+ float2 uv(0, 0);
+ if (uv_index >= 0 && uv_index < global_vertices_.uv_vertices.size()) {
+ uv = global_vertices_.uv_vertices[uv_index];
}
+ copy_v2_v2(mluv_dst[tot_loop_idx].uv, uv);
+ tot_loop_idx++;
}
}
}
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc b/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc
index c471b2002de..787b1fc9730 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc
@@ -123,7 +123,7 @@ static Image *load_texture_image(Main *bmain, const MTLTexMap &tex_map, bool rel
/* Try replacing underscores with spaces. */
std::string no_underscore_path{no_quote_path};
std::replace(no_underscore_path.begin(), no_underscore_path.end(), '_', ' ');
- if (no_underscore_path != no_quote_path && no_underscore_path != tex_path) {
+ if (!ELEM(no_underscore_path, no_quote_path, tex_path)) {
image = load_image_at_path(bmain, no_underscore_path, relative_paths);
if (image != nullptr) {
return image;
@@ -356,7 +356,7 @@ static void add_image_textures(Main *bmain,
bool relative_paths)
{
float node_locy = node_locy_top;
- for (int key = 0; key < (int)MTLTexMapType::Count; ++key) {
+ for (int key = 0; key < int(MTLTexMapType::Count); ++key) {
const MTLTexMap &value = mtl_mat.texture_maps[key];
if (!value.is_valid()) {
/* No Image texture node of this map type can be added to this material. */
@@ -375,7 +375,7 @@ static void add_image_textures(Main *bmain,
/* Add normal map node if needed. */
bNode *normal_map = nullptr;
- if (key == (int)MTLTexMapType::Normal) {
+ if (key == int(MTLTexMapType::Normal)) {
normal_map = add_node(ntree, SH_NODE_NORMAL_MAP, node_locx_normalmap, node_locy);
const float bump = std::max(0.0f, mtl_mat.normal_strength);
set_property_of_socket(SOCK_FLOAT, "Strength", {bump}, normal_map);
@@ -396,7 +396,7 @@ static void add_image_textures(Main *bmain,
link_sockets(ntree, image_node, "Color", normal_map, "Color");
link_sockets(ntree, normal_map, "Normal", bsdf, "Normal");
}
- else if (key == (int)MTLTexMapType::Alpha) {
+ else if (key == int(MTLTexMapType::Alpha)) {
link_sockets(ntree, image_node, "Alpha", bsdf, tex_map_type_to_socket_id[key]);
mat->blend_method = MA_BM_BLEND;
}
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_objects.hh b/source/blender/io/wavefront_obj/importer/obj_import_objects.hh
index 04d9a665588..91f09d9e188 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_objects.hh
+++ b/source/blender/io/wavefront_obj/importer/obj_import_objects.hh
@@ -110,7 +110,7 @@ struct Geometry {
int get_vertex_count() const
{
- return (int)vertices_.size();
+ return int(vertices_.size());
}
void track_vertex_index(int index)
{
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc
index 7e282b164b0..a69b4206db6 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc
@@ -94,7 +94,7 @@ const char *parse_float(const char *p,
}
p = drop_plus(p, end);
fast_float::from_chars_result res = fast_float::from_chars(p, end, dst);
- if (res.ec == std::errc::invalid_argument || res.ec == std::errc::result_out_of_range) {
+ if (ELEM(res.ec, std::errc::invalid_argument, std::errc::result_out_of_range)) {
dst = fallback;
}
else if (require_trailing_space && res.ptr < end && !is_whitespace(*res.ptr)) {
@@ -125,7 +125,7 @@ const char *parse_int(const char *p, const char *end, int fallback, int &dst, bo
}
p = drop_plus(p, end);
std::from_chars_result res = std::from_chars(p, end, dst);
- if (res.ec == std::errc::invalid_argument || res.ec == std::errc::result_out_of_range) {
+ if (ELEM(res.ec, std::errc::invalid_argument, std::errc::result_out_of_range)) {
dst = fallback;
}
return res.ptr;
diff --git a/source/blender/io/wavefront_obj/importer/obj_importer.cc b/source/blender/io/wavefront_obj/importer/obj_importer.cc
index 47d7a9e2b27..a42ec47151d 100644
--- a/source/blender/io/wavefront_obj/importer/obj_importer.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_importer.cc
@@ -42,9 +42,6 @@ static void geometry_to_blender_objects(Main *bmain,
{
LayerCollection *lc = BKE_layer_collection_get_active(view_layer);
- /* Don't do collection syncs for each object, will do once after the loop. */
- BKE_layer_collection_resync_forbid();
-
/* Sort objects by name: creating many objects is much faster if the creation
* order is sorted by name. */
blender::parallel_sort(
@@ -73,11 +70,8 @@ static void geometry_to_blender_objects(Main *bmain,
}
}
- /* Sync the collection after all objects are created. */
- BKE_layer_collection_resync_allow();
- BKE_main_collection_sync(bmain);
-
- /* After collection sync, select objects in the view layer and do DEG updates. */
+ /* Do object selections in a separate loop (allows just one view layer sync). */
+ BKE_view_layer_synced_ensure(scene, view_layer);
for (Object *obj : objects) {
Base *base = BKE_view_layer_base_find(view_layer, obj);
BKE_view_layer_base_select_and_set_active(view_layer, base);
@@ -123,7 +117,7 @@ void importer_main(Main *bmain,
}
if (import_params.clear_selection) {
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
}
geometry_to_blender_objects(bmain,
scene,
diff --git a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc
index dcba78ac99e..5de3cdcd851 100644
--- a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc
+++ b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc
@@ -306,7 +306,7 @@ TEST_F(obj_exporter_regression_test, all_tris)
TEST_F(obj_exporter_regression_test, all_quads)
{
OBJExportParamsDefault _export;
- _export.params.scaling_factor = 2.0f;
+ _export.params.global_scale = 2.0f;
_export.params.export_materials = false;
compare_obj_export_to_golden(
"io_tests/blend_geometry/all_quads.blend", "io_tests/obj/all_quads.obj", "", _export.params);
@@ -429,7 +429,7 @@ TEST_F(obj_exporter_regression_test, cubes_positioned)
{
OBJExportParamsDefault _export;
_export.params.export_materials = false;
- _export.params.scaling_factor = 2.0f;
+ _export.params.global_scale = 2.0f;
compare_obj_export_to_golden("io_tests/blend_geometry/cubes_positioned.blend",
"io_tests/obj/cubes_positioned.obj",
"",
diff --git a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.hh b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.hh
index 006d86312b6..a4d452e1309 100644
--- a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.hh
+++ b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.hh
@@ -19,7 +19,7 @@ struct OBJExportParamsDefault {
params.forward_axis = IO_AXIS_NEGATIVE_Z;
params.up_axis = IO_AXIS_Y;
- params.scaling_factor = 1.f;
+ params.global_scale = 1.f;
params.apply_modifiers = true;
params.export_eval_mode = DAG_EVAL_VIEWPORT;
diff --git a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc
index 99e12aed99c..f459e1ab1bd 100644
--- a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc
+++ b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc
@@ -8,6 +8,7 @@
#include "BKE_curve.h"
#include "BKE_customdata.h"
#include "BKE_main.h"
+#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_scene.h"
@@ -22,6 +23,7 @@
#include "DEG_depsgraph_query.h"
#include "DNA_curve_types.h"
+#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_scene_types.h"
@@ -41,6 +43,7 @@ struct Expectation {
float3 normal_first;
float2 uv_first;
float4 color_first = {-1, -1, -1, -1};
+ std::string first_mat;
};
class obj_importer_test : public BlendfileLoadingBaseTest {
@@ -57,6 +60,7 @@ class obj_importer_test : public BlendfileLoadingBaseTest {
}
OBJImportParams params;
+ params.global_scale = 1.0f;
params.clamp_size = 0;
params.forward_axis = IO_AXIS_NEGATIVE_Z;
params.up_axis = IO_AXIS_Y;
@@ -72,12 +76,13 @@ class obj_importer_test : public BlendfileLoadingBaseTest {
depsgraph_create(DAG_EVAL_VIEWPORT);
- const int deg_objects_visibility_flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
- DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
- DEG_ITER_OBJECT_FLAG_VISIBLE |
- DEG_ITER_OBJECT_FLAG_DUPLI;
+ DEGObjectIterSettings deg_iter_settings{};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI;
size_t object_index = 0;
- DEG_OBJECT_ITER_BEGIN (depsgraph, object, deg_objects_visibility_flags) {
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, object) {
if (object_index >= expect_count) {
ADD_FAILURE();
break;
@@ -86,7 +91,7 @@ class obj_importer_test : public BlendfileLoadingBaseTest {
ASSERT_STREQ(object->id.name, exp.name.c_str());
EXPECT_EQ(object->type, exp.type);
EXPECT_V3_NEAR(object->loc, float3(0, 0, 0), 0.0001f);
- if (strcmp(object->id.name, "OBCube") != 0) {
+ if (!STREQ(object->id.name, "OBCube")) {
EXPECT_V3_NEAR(object->rot, float3(M_PI_2, 0, 0), 0.0001f);
}
EXPECT_V3_NEAR(object->scale, float3(1, 1, 1), 0.0001f);
@@ -99,7 +104,7 @@ class obj_importer_test : public BlendfileLoadingBaseTest {
const Span<MVert> verts = mesh->verts();
EXPECT_V3_NEAR(verts.first().co, exp.vert_first, 0.0001f);
EXPECT_V3_NEAR(verts.last().co, exp.vert_last, 0.0001f);
- const float3 *lnors = (const float3 *)(CustomData_get_layer(&mesh->ldata, CD_NORMAL));
+ const float3 *lnors = (const float3 *)CustomData_get_layer(&mesh->ldata, CD_NORMAL);
float3 normal_first = lnors != nullptr ? lnors[0] : float3(0, 0, 0);
EXPECT_V3_NEAR(normal_first, exp.normal_first, 0.0001f);
const MLoopUV *mloopuv = static_cast<const MLoopUV *>(
@@ -107,8 +112,7 @@ class obj_importer_test : public BlendfileLoadingBaseTest {
float2 uv_first = mloopuv ? float2(mloopuv->uv) : float2(0, 0);
EXPECT_V2_NEAR(uv_first, exp.uv_first, 0.0001f);
if (exp.color_first.x >= 0) {
- const float4 *colors = (const float4 *)(CustomData_get_layer(&mesh->vdata,
- CD_PROP_COLOR));
+ const float4 *colors = (const float4 *)CustomData_get_layer(&mesh->vdata, CD_PROP_COLOR);
EXPECT_TRUE(colors != nullptr);
EXPECT_V4_NEAR(colors[0], exp.color_first, 0.0001f);
}
@@ -132,6 +136,10 @@ class obj_importer_test : public BlendfileLoadingBaseTest {
// int cyclic = (nurb->flagu & CU_NURB_CYCLIC) ? 1 : 0;
// EXPECT_EQ(cyclic, exp.mesh_totloop_or_curve_cyclic);
}
+ if (!exp.first_mat.empty()) {
+ Material *mat = BKE_object_material_get(object, 1);
+ ASSERT_STREQ(mat ? mat->id.name : "<null>", exp.first_mat.c_str());
+ }
++object_index;
}
DEG_OBJECT_ITER_END;
@@ -309,7 +317,42 @@ TEST_F(obj_importer_test, import_materials)
{
Expectation expect[] = {
{"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
- {"OBmaterials", OB_MESH, 8, 12, 6, 24, float3(-1, -1, 1), float3(1, -1, -1)},
+ {"OBmaterials",
+ OB_MESH,
+ 8,
+ 12,
+ 6,
+ 24,
+ float3(-1, -1, 1),
+ float3(1, -1, -1),
+ float3(0),
+ float2(0),
+ float4(-1),
+ "MAno_textures_red"},
+ {"OBObjMtlAfter",
+ OB_MESH,
+ 3,
+ 3,
+ 1,
+ 3,
+ float3(3, 0, 0),
+ float3(5, 0, 0),
+ float3(0),
+ float2(0),
+ float4(-1),
+ "MAno_textures_red"},
+ {"OBObjMtlBefore",
+ OB_MESH,
+ 3,
+ 3,
+ 1,
+ 3,
+ float3(6, 0, 0),
+ float3(8, 0, 0),
+ float3(0),
+ float2(0),
+ float4(-1),
+ "MAClay"},
};
import_and_check("materials.obj", expect, std::size(expect), 4, 8);
}
@@ -327,7 +370,9 @@ TEST_F(obj_importer_test, import_cubes_with_textures_rel)
float3(1, 1, -1),
float3(-1, -1, 1),
float3(0, 1, 0),
- float2(0.9935f, 0.0020f)},
+ float2(0.9935f, 0.0020f),
+ float4(-1),
+ "MAMat_BaseRoughEmissNormal10"},
{"OBCubeTexMul",
OB_MESH,
8,
@@ -337,7 +382,9 @@ TEST_F(obj_importer_test, import_cubes_with_textures_rel)
float3(4, -2, -1),
float3(2, -4, 1),
float3(0, 1, 0),
- float2(0.9935f, 0.0020f)},
+ float2(0.9935f, 0.0020f),
+ float4(-1),
+ "MAMat_BaseMul"},
{"OBCubeTiledTex",
OB_MESH,
8,
@@ -347,7 +394,9 @@ TEST_F(obj_importer_test, import_cubes_with_textures_rel)
float3(4, 1, -1),
float3(2, -1, 1),
float3(0, 1, 0),
- float2(0.9935f, 0.0020f)},
+ float2(0.9935f, 0.0020f),
+ float4(-1),
+ "MAMat_BaseTiled"},
{"OBCubeTiledTexFromAnotherFolder",
OB_MESH,
8,
@@ -357,7 +406,9 @@ TEST_F(obj_importer_test, import_cubes_with_textures_rel)
float3(7, 1, -1),
float3(5, -1, 1),
float3(0, 1, 0),
- float2(0.9935f, 0.0020f)},
+ float2(0.9935f, 0.0020f),
+ float4(-1),
+ "MAMat_EmissTiledAnotherFolder"},
};
import_and_check("cubes_with_textures_rel.obj", expect, std::size(expect), 4, 4);
}
@@ -455,7 +506,10 @@ TEST_F(obj_importer_test, import_all_objects)
26,
float3(28, 1, -1),
float3(26, 1, 1),
- float3(-1, 0, 0)},
+ float3(-1, 0, 0),
+ float2(0),
+ float4(-1),
+ "MARed"},
{"OBNurbsCircle",
OB_MESH,
96,
@@ -491,7 +545,10 @@ TEST_F(obj_importer_test, import_all_objects)
26,
float3(4, 1, -1),
float3(2, 1, 1),
- float3(0.5774f, 0.5773f, 0.5774f)},
+ float3(0.5774f, 0.5773f, 0.5774f),
+ float2(0),
+ float4(-1),
+ "MAMaterial"},
{"OBSurface",
OB_MESH,
256,
diff --git a/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc b/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc
index e473d629673..ce3c14a2939 100644
--- a/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc
+++ b/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc
@@ -67,7 +67,7 @@ class obj_mtl_parser_test : public testing::Test {
EXPECT_NEAR(exp.cc_roughness, got.cc_roughness, tol);
EXPECT_NEAR(exp.aniso, got.aniso, tol);
EXPECT_NEAR(exp.aniso_rot, got.aniso_rot, tol);
- for (int key = 0; key < (int)MTLTexMapType::Count; key++) {
+ for (int key = 0; key < int(MTLTexMapType::Count); key++) {
const MTLTexMap &exp_tex = exp.texture_maps[key];
const MTLTexMap &got_tex = got.texture_maps[key];
EXPECT_STREQ(exp_tex.image_path.c_str(), got_tex.image_path.c_str());
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index d64b3d361cf..edd70e0f9d7 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -471,7 +471,7 @@ typedef struct Library {
*/
char filepath_abs[1024];
- /** Set for indirectly linked libs, used in the outliner and while reading. */
+ /** Set for indirectly linked libraries, used in the outliner and while reading. */
struct Library *parent;
struct PackedFile *packedfile;
diff --git a/source/blender/makesdna/DNA_asset_types.h b/source/blender/makesdna/DNA_asset_types.h
index a4e092ff7b1..b5371011ddc 100644
--- a/source/blender/makesdna/DNA_asset_types.h
+++ b/source/blender/makesdna/DNA_asset_types.h
@@ -42,6 +42,10 @@ typedef struct AssetFilterSettings {
* more than that from the file. So pointers to other IDs or ID data are strictly forbidden.
*/
typedef struct AssetMetaData {
+#ifdef __cplusplus
+ ~AssetMetaData();
+#endif
+
/** Runtime type, to reference event callbacks. Only valid for local assets. */
struct AssetTypeInfo *local_type_info;
@@ -114,6 +118,8 @@ typedef struct AssetLibraryReference {
} AssetLibraryReference;
/**
+ * To be replaced by #AssetRepresentation!
+ *
* Not part of the core design, we should try to get rid of it. Only needed to wrap FileDirEntry
* into a type with PropertyGroup as base, so we can have an RNA collection of #AssetHandle's to
* pass to the UI.
diff --git a/source/blender/makesdna/DNA_brush_defaults.h b/source/blender/makesdna/DNA_brush_defaults.h
index 530c056b584..6e88275672a 100644
--- a/source/blender/makesdna/DNA_brush_defaults.h
+++ b/source/blender/makesdna/DNA_brush_defaults.h
@@ -91,6 +91,8 @@
.pose_ik_segments = 1, \
.hardness = 0.0f, \
.automasking_boundary_edges_propagation_steps = 1, \
+ .automasking_cavity_blur_steps = 0,\
+ .automasking_cavity_factor = 1.0f,\
\
/* A kernel radius of 1 has almost no effect (T63233). */ \
.blur_kernel_radius = 2, \
diff --git a/source/blender/makesdna/DNA_brush_enums.h b/source/blender/makesdna/DNA_brush_enums.h
index 988853e6694..72357ea6734 100644
--- a/source/blender/makesdna/DNA_brush_enums.h
+++ b/source/blender/makesdna/DNA_brush_enums.h
@@ -89,6 +89,8 @@ typedef enum eGPDbrush_Flag {
GP_BRUSH_TRIM_STROKE = (1 << 16),
/* Post process convert to outline stroke */
GP_BRUSH_OUTLINE_STROKE = (1 << 17),
+ /* Collide with stroke. */
+ GP_BRUSH_FILL_STROKE_COLLIDE = (1 << 18),
} eGPDbrush_Flag;
typedef enum eGPDbrush_Flag2 {
@@ -118,13 +120,19 @@ typedef enum eGPDbrush_Flag2 {
GP_BRUSH_USE_UV_RAND_PRESS = (1 << 11),
} eGPDbrush_Flag2;
-/* BrushGpencilSettings->gp_fill_draw_mode */
+/* BrushGpencilSettings->fill_draw_mode */
typedef enum eGP_FillDrawModes {
GP_FILL_DMODE_BOTH = 0,
GP_FILL_DMODE_STROKE = 1,
GP_FILL_DMODE_CONTROL = 2,
} eGP_FillDrawModes;
+/* BrushGpencilSettings->fill_extend_mode */
+typedef enum eGP_FillExtendModes {
+ GP_FILL_EMODE_EXTEND = 0,
+ GP_FILL_EMODE_RADIUS = 1,
+} eGP_FillExtendModes;
+
/* BrushGpencilSettings->fill_layer_mode */
typedef enum eGP_FillLayerModes {
GP_FILL_GPLMODE_VISIBLE = 0,
@@ -307,12 +315,6 @@ typedef enum eGP_Sculpt_Mode_Flag {
GP_SCULPT_FLAGMODE_APPLY_THICKNESS = (1 << 2),
/* apply brush to uv data */
GP_SCULPT_FLAGMODE_APPLY_UV = (1 << 3),
- /* Stroke Auto-Masking for sculpt. */
- GP_SCULPT_FLAGMODE_AUTOMASK_STROKE = (1 << 4),
- /* Layer Auto-Masking for sculpt. */
- GP_SCULPT_FLAGMODE_AUTOMASK_LAYER = (1 << 5),
- /* Material Auto-Masking for sculpt. */
- GP_SCULPT_FLAGMODE_AUTOMASK_MATERIAL = (1 << 6),
} eGP_Sculpt_Mode_Flag;
typedef enum eAutomasking_flag {
@@ -320,6 +322,17 @@ typedef enum eAutomasking_flag {
BRUSH_AUTOMASKING_FACE_SETS = (1 << 1),
BRUSH_AUTOMASKING_BOUNDARY_EDGES = (1 << 2),
BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS = (1 << 3),
+ BRUSH_AUTOMASKING_CAVITY_NORMAL = (1 << 4),
+
+ /* NOTE: normal and inverted are mutually exclusive,
+ * inverted has priority if both bits are set. */
+ BRUSH_AUTOMASKING_CAVITY_INVERTED = (1 << 5),
+ BRUSH_AUTOMASKING_CAVITY_ALL = (1 << 4) | (1 << 5),
+ BRUSH_AUTOMASKING_CAVITY_USE_CURVE = (1 << 6),
+ /* (1 << 7) - unused. */
+ BRUSH_AUTOMASKING_BRUSH_NORMAL = (1 << 8),
+ BRUSH_AUTOMASKING_VIEW_NORMAL = (1 << 9),
+ BRUSH_AUTOMASKING_VIEW_OCCLUSION = (1 << 10),
} eAutomasking_flag;
typedef enum ePaintBrush_flag {
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 33f5d8eea12..a415122579e 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -58,11 +58,10 @@ typedef struct BrushGpencilSettings {
/** Factor for transparency. */
float fill_threshold;
- /** Number of pixel to consider the leak is too small (x 2). */
- short fill_leak;
+ char _pad2[2];
/* Type of caps: eGPDstroke_Caps. */
int8_t caps_type;
- char _pad;
+ char _pad[5];
int flag2;
@@ -70,6 +69,8 @@ typedef struct BrushGpencilSettings {
int fill_simplylvl;
/** Type of control lines drawing mode. */
int fill_draw_mode;
+ /** Type of gap filling extension to use. */
+ int fill_extend_mode;
/** Icon identifier. */
int icon_id;
@@ -387,6 +388,11 @@ typedef struct Brush {
struct BrushGpencilSettings *gpencil_settings;
struct BrushCurvesSculptSettings *curves_sculpt_settings;
+
+ int automasking_cavity_blur_steps;
+ float automasking_cavity_factor;
+
+ struct CurveMapping *automasking_cavity_curve;
} Brush;
/* Struct to hold palette colors for sorting. */
diff --git a/source/blender/makesdna/DNA_collection_types.h b/source/blender/makesdna/DNA_collection_types.h
index a3e5eb4e944..75bfc2575a5 100644
--- a/source/blender/makesdna/DNA_collection_types.h
+++ b/source/blender/makesdna/DNA_collection_types.h
@@ -36,6 +36,7 @@ enum eCollectionLineArt_Usage {
COLLECTION_LRT_EXCLUDE = (1 << 1),
COLLECTION_LRT_INTERSECTION_ONLY = (1 << 2),
COLLECTION_LRT_NO_INTERSECTION = (1 << 3),
+ COLLECTION_LRT_FORCE_INTERSECTION = (1 << 4),
};
enum eCollectionLineArt_Flags {
diff --git a/source/blender/makesdna/DNA_color_types.h b/source/blender/makesdna/DNA_color_types.h
index 623d1dd6440..4eb64290032 100644
--- a/source/blender/makesdna/DNA_color_types.h
+++ b/source/blender/makesdna/DNA_color_types.h
@@ -21,6 +21,9 @@ extern "C" {
#define CM_TOT 4
+#define GPU_SKY_WIDTH 512
+#define GPU_SKY_HEIGHT 128
+
typedef struct CurveMapPoint {
float x, y;
/** Shorty for result lookup. */
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 8e0ce68f71a..04887f1223c 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -181,7 +181,7 @@ typedef struct bKinematicConstraint {
float orientweight;
/** CopyPose: for target-less IK. */
float grabtarget[3];
- /** Subtype of IK constraint: eConstraint_IK_Type. */
+ /** Sub-type of IK constraint: #eConstraint_IK_Type. */
short type;
/** Distance: how to limit in relation to clamping sphere: LIMITDIST_... */
short mode;
diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h
index f51b1c790b0..0355ed3febe 100644
--- a/source/blender/makesdna/DNA_customdata_types.h
+++ b/source/blender/makesdna/DNA_customdata_types.h
@@ -116,7 +116,7 @@ typedef enum eCustomDataType {
CD_PROP_BYTE_COLOR = 17,
CD_TANGENT = 18,
CD_MDISPS = 19,
- CD_PREVIEW_MCOL = 20, /* for displaying weightpaint colors */
+ CD_PREVIEW_MCOL = 20, /* For displaying weight-paint colors. */
/* CD_ID_MCOL = 21, */
/* CD_TEXTURE_MLOOPCOL = 22, */ /* UNUSED */
CD_CLOTH_ORCO = 23,
@@ -127,12 +127,7 @@ typedef enum eCustomDataType {
CD_SHAPE_KEYINDEX = 27,
CD_SHAPEKEY = 28,
CD_BWEIGHT = 29,
- /**
- * Usage of #CD_CREASE depends on where on the Mesh the layer is added:
- * - For vertex creasing, this is persistent data across all modes and is stored in the file.
- * - For edge creasing, it is runtime data which is only used in edit-mode before being copied
- * to #MEdge when exiting edit-mode.
- */
+ /** Subdivision sharpness data per edge or per vertex. */
CD_CREASE = 30,
CD_ORIGSPACE_MLOOP = 31,
CD_PREVIEW_MLOOPCOL = 32,
@@ -206,7 +201,6 @@ typedef enum eCustomDataType {
#define CD_MASK_MLOOPTANGENT (1LL << CD_MLOOPTANGENT)
#define CD_MASK_TESSLOOPNORMAL (1LL << CD_TESSLOOPNORMAL)
#define CD_MASK_CUSTOMLOOPNORMAL (1LL << CD_CUSTOMLOOPNORMAL)
-#define CD_MASK_SCULPT_FACE_SETS (1LL << CD_SCULPT_FACE_SETS)
#define CD_MASK_PROP_COLOR (1ULL << CD_PROP_COLOR)
#define CD_MASK_PROP_FLOAT3 (1ULL << CD_PROP_FLOAT3)
#define CD_MASK_PROP_FLOAT2 (1ULL << CD_PROP_FLOAT2)
@@ -215,7 +209,7 @@ typedef enum eCustomDataType {
#define CD_MASK_HAIRLENGTH (1ULL << CD_HAIRLENGTH)
-/** Multires loop data. */
+/** Multi-resolution loop data. */
#define CD_MASK_MULTIRES_GRIDS (CD_MASK_MDISPS | CD_GRID_PAINT_MASK)
/* All data layers. */
diff --git a/source/blender/makesdna/DNA_fileglobal_types.h b/source/blender/makesdna/DNA_fileglobal_types.h
index 0fcf232cdaa..58b8504430a 100644
--- a/source/blender/makesdna/DNA_fileglobal_types.h
+++ b/source/blender/makesdna/DNA_fileglobal_types.h
@@ -29,9 +29,9 @@ typedef struct FileGlobal {
int fileflags;
int globalf;
- /** Commit timestamp from buildinfo. */
+ /** Commit timestamp from `buildinfo`. */
uint64_t build_commit_timestamp;
- /** Hash from buildinfo. */
+ /** Hash from `buildinfo`. */
char build_hash[16];
/** File path where this was saved, for recover (1024 = FILE_MAX). */
char filepath[1024];
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
index 324252ca369..8078283df7a 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
@@ -172,6 +172,19 @@
.curve_intensity = NULL, \
}
+#define _DNA_DEFAULT_OutlineGpencilModifierData \
+ { \
+ .material = NULL, \
+ .layername = "", \
+ .pass_index = 0, \
+ .flag = GP_OUTLINE_KEEP_SHAPE, \
+ .thickness = 1, \
+ .sample_length = 0.0f, \
+ .subdiv = 3, \
+ .layer_pass = 0, \
+ .outline_material = NULL, \
+ }
+
#define _DNA_DEFAULT_SimplifyGpencilModifierData \
{ \
.material = NULL, \
@@ -249,6 +262,18 @@
.mode = 0, \
.sfra = 1, \
.efra = 250, \
+ .segments = NULL, \
+ .segments_len = 1, \
+ .segment_active_index = 0, \
+ }
+
+ #define _DNA_DEFAULT_TimeGpencilModifierSegment \
+ { \
+ .name = "", \
+ .seg_start = 1, \
+ .seg_end = 2, \
+ .seg_mode = 0, \
+ .seg_repeat = 1, \
}
#define _DNA_DEFAULT_TintGpencilModifierData \
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h
index ca1eac0bde8..0932b7107bb 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_types.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h
@@ -47,6 +47,7 @@ typedef enum GpencilModifierType {
eGpencilModifierType_WeightAngle = 23,
eGpencilModifierType_Shrinkwrap = 24,
eGpencilModifierType_Envelope = 25,
+ eGpencilModifierType_Outline = 26,
/* Keep last. */
NUM_GREASEPENCIL_MODIFIER_TYPES,
} GpencilModifierType;
@@ -201,8 +202,18 @@ typedef enum eThickGpencil_Flag {
GP_THICK_WEIGHT_FACTOR = (1 << 7),
} eThickGpencil_Flag;
+typedef struct TimeGpencilModifierSegment {
+ char name[64];
+ /* For path reference. */
+ struct TimeGpencilModifierData *gpmd;
+ int seg_start;
+ int seg_end;
+ int seg_mode;
+ int seg_repeat;
+} TimeGpencilModifierSegment;
typedef struct TimeGpencilModifierData {
GpencilModifierData modifier;
+ struct Material *material;
/** Layer name. */
char layername[64];
/** Custom index for passes. */
@@ -215,7 +226,13 @@ typedef struct TimeGpencilModifierData {
int mode;
/** Start and end frame for custom range. */
int sfra, efra;
+
char _pad[4];
+
+ TimeGpencilModifierSegment *segments;
+ int segments_len;
+ int segment_active_index;
+
} TimeGpencilModifierData;
typedef enum eTimeGpencil_Flag {
@@ -230,8 +247,15 @@ typedef enum eTimeGpencil_Mode {
GP_TIME_MODE_REVERSE = 1,
GP_TIME_MODE_FIX = 2,
GP_TIME_MODE_PINGPONG = 3,
+ GP_TIME_MODE_CHAIN = 4,
} eTimeGpencil_Mode;
+typedef enum eTimeGpencil_Seg_Mode {
+ GP_TIME_SEG_MODE_NORMAL = 0,
+ GP_TIME_SEG_MODE_REVERSE = 1,
+ GP_TIME_SEG_MODE_PINGPONG = 2,
+} eTimeGpencil_Seg_Mode;
+
typedef enum eModifyColorGpencil_Flag {
GP_MODIFY_COLOR_BOTH = 0,
GP_MODIFY_COLOR_STROKE = 1,
@@ -313,6 +337,38 @@ typedef enum eOpacityGpencil_Flag {
GP_OPACITY_WEIGHT_FACTOR = (1 << 8),
} eOpacityGpencil_Flag;
+typedef struct OutlineGpencilModifierData {
+ GpencilModifierData modifier;
+ /** Target stroke origin. */
+ struct Object *object;
+ /** Material for filtering. */
+ struct Material *material;
+ /** Layer name. */
+ char layername[64];
+ /** Custom index for passes. */
+ int pass_index;
+ /** Flags. */
+ int flag;
+ /** Thickness. */
+ int thickness;
+ /** Sample Length. */
+ float sample_length;
+ /** Subdivisions. */
+ int subdiv;
+ /** Custom index for passes. */
+ int layer_pass;
+ /** Material for outline. */
+ struct Material *outline_material;
+} OutlineGpencilModifierData;
+
+typedef enum eOutlineGpencil_Flag {
+ GP_OUTLINE_INVERT_LAYER = (1 << 0),
+ GP_OUTLINE_INVERT_PASS = (1 << 1),
+ GP_OUTLINE_INVERT_LAYERPASS = (1 << 2),
+ GP_OUTLINE_INVERT_MATERIAL = (1 << 3),
+ GP_OUTLINE_KEEP_SHAPE = (1 << 4),
+} eOutlineGpencil_Flag;
+
typedef struct ArrayGpencilModifierData {
GpencilModifierData modifier;
struct Object *object;
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 6a2f25f3975..8b3f4956cfe 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -243,12 +243,15 @@ typedef struct bGPDstroke_Runtime {
/** Runtime falloff factor (only for transform). */
float multi_frame_falloff;
- /** Vertex offset in the VBO where this stroke starts. */
+ /** Triangle offset in the IBO where this stroke starts. */
int stroke_start;
/** Triangle offset in the IBO where this fill starts. */
int fill_start;
+ /** Vertex offset in the VBO where this stroke starts. */
+ int vertex_start;
/** Curve Handles offset in the IBO where this handle starts. */
int curve_start;
+ int _pad0;
/** Original stroke (used to dereference evaluated data) */
struct bGPDstroke *gps_orig;
@@ -347,6 +350,10 @@ typedef enum eGPDstroke_Flag {
/* Flag to indicated that the editcurve has been changed and the stroke needs to be updated with
* the curve data */
GP_STROKE_NEEDS_CURVE_UPDATE = (1 << 9),
+ /* Flag to indicate that a stroke is used only for help, and will not affect rendering or fill */
+ GP_STROKE_HELP = (1 << 10),
+ /* Flag to indicate that a extend stroke collide (fill tool) */
+ GP_STROKE_COLLIDE = (1 << 11),
/* only for use with stroke-buffer (while drawing arrows) */
GP_STROKE_USE_ARROW_START = (1 << 12),
/* only for use with stroke-buffer (while drawing arrows) */
@@ -609,8 +616,9 @@ typedef struct bGPdata_Runtime {
/** Stroke buffer. */
void *sbuffer;
/** Temp batches cleared after drawing. */
- struct GPUBatch *sbuffer_stroke_batch;
- struct GPUBatch *sbuffer_fill_batch;
+ struct GPUVertBuf *sbuffer_position_buf;
+ struct GPUVertBuf *sbuffer_color_buf;
+ struct GPUBatch *sbuffer_batch;
/** Temp stroke used for drawing. */
struct bGPDstroke *sbuffer_gps;
diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h
index b9aadcaf183..6ea35dfb770 100644
--- a/source/blender/makesdna/DNA_layer_types.h
+++ b/source/blender/makesdna/DNA_layer_types.h
@@ -35,8 +35,8 @@ typedef enum eViewLayerEEVEEPassType {
EEVEE_RENDER_PASS_BLOOM = (1 << 14),
EEVEE_RENDER_PASS_AOV = (1 << 15),
/*
- * TODO(jbakker): Clean up confliting bits after EEVEE has been removed.
- * EEVEE_RENDER_PASS_CRYPTOMATTE is for EEVEE, EEVEE_RENDER_PASS_CRYTPOMATTE_* are for
+ * TODO(@jbakker): Clean up conflicting bits after EEVEE has been removed.
+ * #EEVEE_RENDER_PASS_CRYPTOMATTE is for EEVEE, `EEVEE_RENDER_PASS_CRYTPOMATTE_*` are for
* EEVEE-Next.
*/
EEVEE_RENDER_PASS_CRYPTOMATTE = (1 << 16),
@@ -71,27 +71,23 @@ typedef enum eViewLayerCryptomatteFlags {
typedef struct Base {
struct Base *next, *prev;
- /* Flags which are based on the collections flags evaluation, does not
- * include flags from object's restrictions. */
- short flag_from_collection;
+ struct Object *object;
+
+ /* Pointer to an original base. Is initialized for evaluated view layer.
+ * NOTE: Only allowed to be accessed from within active dependency graph. */
+ struct Base *base_orig;
+ unsigned int lay DNA_DEPRECATED;
/* Final flags, including both accumulated collection flags and object's
* restriction flags. */
short flag;
-
+ /* Flags which are based on the collections flags evaluation, does not
+ * include flags from object's restrictions. */
+ short flag_from_collection;
+ short flag_legacy;
unsigned short local_view_bits;
- short sx, sy;
- char _pad1[6];
- struct Object *object;
- unsigned int lay DNA_DEPRECATED;
- int flag_legacy;
unsigned short local_collections_bits;
- short _pad2[3];
-
- /* Pointer to an original base. Is initialized for evaluated view layer.
- * NOTE: Only allowed to be accessed from within active dependency graph. */
- struct Base *base_orig;
- void *_pad;
+ char _pad1[2];
} Base;
typedef struct ViewLayerEngineData {
@@ -138,13 +134,13 @@ typedef struct ViewLayerAOV {
typedef struct ViewLayerLightgroup {
struct ViewLayerLightgroup *next, *prev;
- /* Name of the Lightgroup */
+ /* Name of the Light-group. */
char name[64];
} ViewLayerLightgroup;
-/* Lightgroup membership information. */
+/* Light-group membership information. */
typedef struct LightgroupMembership {
- /* Name of the Lightgroup */
+ /* Name of the Light-group. */
char name[64];
} LightgroupMembership;
@@ -273,6 +269,7 @@ enum {
VIEW_LAYER_RENDER = (1 << 0),
/* VIEW_LAYER_DEPRECATED = (1 << 1), */
VIEW_LAYER_FREESTYLE = (1 << 2),
+ VIEW_LAYER_OUT_OF_SYNC = (1 << 3),
};
/****************************** Deprecated ******************************/
diff --git a/source/blender/makesdna/DNA_lightprobe_types.h b/source/blender/makesdna/DNA_lightprobe_types.h
index d6afaf33052..5b5bc4c7392 100644
--- a/source/blender/makesdna/DNA_lightprobe_types.h
+++ b/source/blender/makesdna/DNA_lightprobe_types.h
@@ -64,7 +64,6 @@ typedef struct LightProbe {
/* Runtime display data */
float distfalloff, distgridinf;
- char _pad[8];
} LightProbe;
/* Probe->type */
diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h
index d335b36950c..3f951583741 100644
--- a/source/blender/makesdna/DNA_mesh_types.h
+++ b/source/blender/makesdna/DNA_mesh_types.h
@@ -19,10 +19,14 @@ namespace blender {
template<typename T> class Span;
template<typename T> class MutableSpan;
namespace bke {
+struct MeshRuntime;
class AttributeAccessor;
class MutableAttributeAccessor;
} // namespace bke
} // namespace blender
+using MeshRuntimeHandle = blender::bke::MeshRuntime;
+#else
+typedef struct MeshRuntimeHandle MeshRuntimeHandle;
#endif
#ifdef __cplusplus
@@ -30,133 +34,14 @@ extern "C" {
#endif
struct AnimData;
-struct BVHCache;
struct Ipo;
struct Key;
struct MCol;
struct MEdge;
struct MFace;
-struct MLoopCol;
struct MLoopTri;
struct MVert;
struct Material;
-struct Mesh;
-struct SubdivCCG;
-struct SubsurfRuntimeData;
-
-#
-#
-typedef struct EditMeshData {
- /** when set, \a vertexNos, polyNos are lazy initialized */
- const float (*vertexCos)[3];
-
- /** lazy initialize (when \a vertexCos is set) */
- float const (*vertexNos)[3];
- float const (*polyNos)[3];
- /** also lazy init but don't depend on \a vertexCos */
- const float (*polyCos)[3];
-} EditMeshData;
-
-/**
- * \warning Typical access is done via
- * #BKE_mesh_runtime_looptri_ensure, #BKE_mesh_runtime_looptri_len.
- */
-struct MLoopTri_Store {
- DNA_DEFINE_CXX_METHODS(MLoopTri_Store)
-
- /* WARNING! swapping between array (ready-to-be-used data) and array_wip
- * (where data is actually computed)
- * shall always be protected by same lock as one used for looptris computing. */
- struct MLoopTri *array, *array_wip;
- int len;
- int len_alloc;
-};
-
-/** Runtime data, not saved in files. */
-typedef struct Mesh_Runtime {
- DNA_DEFINE_CXX_METHODS(Mesh_Runtime)
-
- /* Evaluated mesh for objects which do not have effective modifiers.
- * This mesh is used as a result of modifier stack evaluation.
- * Since modifier stack evaluation is threaded on object level we need some synchronization. */
- struct Mesh *mesh_eval;
- void *eval_mutex;
-
- /* A separate mutex is needed for normal calculation, because sometimes
- * the normals are needed while #eval_mutex is already locked. */
- void *normals_mutex;
-
- /** Needed to ensure some thread-safety during render data pre-processing. */
- void *render_mutex;
-
- /** Lazily initialized SoA data from the #edit_mesh field in #Mesh. */
- struct EditMeshData *edit_data;
-
- /**
- * Data used to efficiently draw the mesh in the viewport, especially useful when
- * the same mesh is used in many objects or instances. See `draw_cache_impl_mesh.cc`.
- */
- void *batch_cache;
-
- /** Cache for derived triangulation of the mesh. */
- struct MLoopTri_Store looptris;
-
- /** Cache for BVH trees generated for the mesh. Defined in 'BKE_bvhutil.c' */
- struct BVHCache *bvh_cache;
-
- /** Cache of non-manifold boundary data for Shrinkwrap Target Project. */
- struct ShrinkwrapBoundaryData *shrinkwrap_data;
-
- /** Needed in case we need to lazily initialize the mesh. */
- CustomData_MeshMasks cd_mask_extra;
-
- struct SubdivCCG *subdiv_ccg;
- int subdiv_ccg_tot_level;
-
- /** Set by modifier stack if only deformed from original. */
- char deformed_only;
- /**
- * Copied from edit-mesh (hint, draw with edit-mesh data when true).
- *
- * Modifiers that edit the mesh data in-place must set this to false
- * (most #eModifierTypeType_NonGeometrical modifiers). Otherwise the edit-mesh
- * data will be used for drawing, missing changes from modifiers. See T79517.
- */
- char is_original_bmesh;
-
- /** #eMeshWrapperType and others. */
- char wrapper_type;
- /**
- * A type mask from wrapper_type,
- * in case there are differences in finalizing logic between types.
- */
- char wrapper_type_finalize;
-
- /**
- * Settings for lazily evaluating the subdivision on the CPU if needed. These are
- * set in the modifier when GPU subdivision can be performed, and owned by the by
- * the modifier in the object.
- */
- struct SubsurfRuntimeData *subsurf_runtime_data;
- void *_pad1;
-
- /**
- * Caches for lazily computed vertex and polygon normals. These are stored here rather than in
- * #CustomData because they can be calculated on a const mesh, and adding custom data layers on a
- * const mesh is not thread-safe.
- */
- char _pad2[6];
- char vert_normals_dirty;
- char poly_normals_dirty;
- float (*vert_normals)[3];
- float (*poly_normals)[3];
-
- /**
- * A #BLI_bitmap containing tags for the center vertices of subdivided polygons, set by the
- * subdivision surface modifier and used by drawing code instead of polygon center face dots.
- */
- uint32_t *subsurf_face_dot_tags;
-} Mesh_Runtime;
typedef struct Mesh {
DNA_DEFINE_CXX_METHODS(Mesh)
@@ -254,24 +139,23 @@ typedef struct Mesh {
float smoothresh;
/**
- * Flag for choosing whether or not so store bevel weight and crease as custom data layers in the
- * edit mesh (they are always stored in #MVert and #MEdge currently). In the future, this data
- * may be stored as generic named attributes (see T89054 and T93602).
- */
- char cd_flag;
-
- /**
* User-defined symmetry flag (#eMeshSymmetryType) that causes editing operations to maintain
* symmetrical geometry. Supported by operations such as transform and weight-painting.
*/
char symmetry;
- /** The length of the #mat array. */
- short totcol;
-
/** Choice between different remesh methods in the UI. */
char remesh_mode;
+ /** The length of the #mat array. */
+ short totcol;
+
+ /**
+ * Deprecated flag for choosing whether to store specific custom data that was built into #Mesh
+ * structs in edit mode. Replaced by separating that data to separate layers. Kept for forward
+ * and backwards compatibility.
+ */
+ char cd_flag DNA_DEPRECATED;
char subdiv DNA_DEPRECATED;
char subdivr DNA_DEPRECATED;
char subsurftype DNA_DEPRECATED;
@@ -285,7 +169,7 @@ typedef struct Mesh {
struct MVert *mvert DNA_DEPRECATED;
/** Deprecated array of mesh edges, kept for reading old files, now stored in #CustomData. */
struct MEdge *medge DNA_DEPRECATED;
- /** Deprecated "Vertex group" data. Kept for reading old files, now stored in #CustomData.*/
+ /** Deprecated "Vertex group" data. Kept for reading old files, now stored in #CustomData. */
struct MDeformVert *dvert DNA_DEPRECATED;
/** Deprecated runtime data for tessellation face UVs and texture, kept for reading old files. */
struct MTFace *mtface DNA_DEPRECATED;
@@ -317,9 +201,13 @@ typedef struct Mesh {
char _pad1[4];
- void *_pad2;
-
- Mesh_Runtime runtime;
+ /**
+ * Data that isn't saved in files, including caches of derived data, temporary data to improve
+ * the editing experience, etc. Runtime data is created when reading files and can be accessed
+ * without null checks, with the exception of some temporary meshes which should allocate and
+ * free the data if they are passed to functions that expect run-time data.
+ */
+ MeshRuntimeHandle *runtime;
#ifdef __cplusplus
/**
* Array of vertex positions (and various other data). Edges and faces are defined by indices
@@ -361,6 +249,10 @@ typedef struct Mesh {
/** Write access to vertex group data. */
blender::MutableSpan<MDeformVert> deform_verts_for_write();
+ /**
+ * Cached triangulation of the mesh.
+ */
+ blender::Span<MLoopTri> looptris() const;
#endif
} Mesh;
@@ -380,16 +272,6 @@ typedef struct TFace {
/* **************** MESH ********************* */
-/** #Mesh_Runtime.wrapper_type */
-typedef enum eMeshWrapperType {
- /** Use mesh data (#Mesh.mvert, #Mesh.medge, #Mesh.mloop, #Mesh.mpoly). */
- ME_WRAPPER_TYPE_MDATA = 0,
- /** Use edit-mesh data (#Mesh.edit_mesh, #Mesh_Runtime.edit_data). */
- ME_WRAPPER_TYPE_BMESH = 1,
- /** Use subdivision mesh data (#Mesh_Runtime.mesh_eval). */
- ME_WRAPPER_TYPE_SUBD = 2,
-} eMeshWrapperType;
-
/** #Mesh.texflag */
enum {
ME_AUTOSPACE = 1,
@@ -438,15 +320,15 @@ enum {
ME_REMESH_REPROJECT_SCULPT_FACE_SETS = 1 << 15,
};
+#ifdef DNA_DEPRECATED_ALLOW
/** #Mesh.cd_flag */
enum {
-#ifdef DNA_DEPRECATED_ALLOW
ME_CDFLAG_VERT_BWEIGHT = 1 << 0,
ME_CDFLAG_EDGE_BWEIGHT = 1 << 1,
-#endif
ME_CDFLAG_EDGE_CREASE = 1 << 2,
ME_CDFLAG_VERT_CREASE = 1 << 3,
};
+#endif
/** #Mesh.remesh_mode */
enum {
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index e621343b818..f1c2dcaae68 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -21,15 +21,19 @@ extern "C" {
/**
* Mesh Vertices.
*
- * Typically accessed from #Mesh.mvert
+ * Typically accessed from #Mesh.verts()
*/
typedef struct MVert {
float co[3];
- char flag;
+ /**
+ * Deprecated flag for storing hide status and selection, which are now stored in separate
+ * generic attributes. Kept for file read and write.
+ */
+ char flag_legacy;
/**
* Deprecated bevel weight storage, now located in #CD_BWEIGHT, except for file read and write.
*/
- char bweight DNA_DEPRECATED;
+ char bweight_legacy;
char _pad[2];
} MVert;
@@ -37,6 +41,7 @@ typedef struct MVert {
#ifdef DNA_DEPRECATED_ALLOW
enum {
+ /** Deprecated selection status. Now stored in ".select_vert" attribute. */
/* SELECT = (1 << 0), */
/** Deprecated hide status. Now stored in ".hide_vert" attribute. */
ME_HIDE = (1 << 4),
@@ -46,36 +51,37 @@ enum {
/**
* Mesh Edges.
*
- * Typically accessed from #Mesh.medge
+ * Typically accessed with #Mesh.edges()
*/
typedef struct MEdge {
/** Un-ordered vertex indices (cannot match). */
unsigned int v1, v2;
- char crease;
+ /** Deprecated edge crease, now located in #CD_CREASE, except for file read and write. */
+ char crease_legacy;
/**
* Deprecated bevel weight storage, now located in #CD_BWEIGHT, except for file read and write.
*/
- char bweight DNA_DEPRECATED;
+ char bweight_legacy;
short flag;
} MEdge;
/** #MEdge.flag */
enum {
+ /** Deprecated selection status. Now stored in ".select_edge" attribute. */
/* SELECT = (1 << 0), */
ME_EDGEDRAW = (1 << 1),
ME_SEAM = (1 << 2),
/** Deprecated hide status. Now stored in ".hide_edge" attribute. */
/* ME_HIDE = (1 << 4), */
- ME_EDGERENDER = (1 << 5),
ME_LOOSEEDGE = (1 << 7),
ME_SHARP = (1 << 9), /* only reason this flag remains a 'short' */
};
/**
- * Mesh Faces
+ * Mesh Faces.
* This only stores the polygon size & flags, the vertex & edge indices are stored in the #MLoop.
*
- * Typically accessed from #Mesh.mpoly.
+ * Typically accessed with #Mesh.polys().
*/
typedef struct MPoly {
/** Offset into loop array and number of loops in the face. */
@@ -83,14 +89,17 @@ typedef struct MPoly {
/** Keep signed since we need to subtract when getting the previous loop. */
int totloop;
/** Deprecated material index. Now stored in the "material_index" attribute, but kept for IO. */
- short mat_nr DNA_DEPRECATED;
+ short mat_nr_legacy;
char flag, _pad;
} MPoly;
/** #MPoly.flag */
enum {
ME_SMOOTH = (1 << 0),
+#ifdef DNA_DEPRECATED_ALLOW
+ /** Deprecated selection status. Now stored in ".select_poly" attribute. */
ME_FACE_SEL = (1 << 1),
+#endif
/** Deprecated hide status. Now stored in ".hide_poly" attribute. */
/* ME_HIDE = (1 << 4), */
};
@@ -99,7 +108,7 @@ enum {
* Mesh Face Corners.
* "Loop" is an internal name for the corner of a polygon (#MPoly).
*
- * Typically accessed from #Mesh.mloop.
+ * Typically accessed with #Mesh.loops().
*/
typedef struct MLoop {
/** Vertex index into an #MVert array. */
@@ -366,7 +375,7 @@ typedef struct MDisps {
/**
* Used for hiding parts of a multires mesh.
- * Essentially the multires equivalent of the mesh ".hide_vert" boolean layer.
+ * Essentially the multires equivalent of the mesh ".hide_vert" boolean attribute.
*
* \note This is a bitmap, keep in sync with type used in BLI_bitmap.h
*/
diff --git a/source/blender/makesdna/DNA_meta_types.h b/source/blender/makesdna/DNA_meta_types.h
index d0c09a0d6ab..b4a66a46efe 100644
--- a/source/blender/makesdna/DNA_meta_types.h
+++ b/source/blender/makesdna/DNA_meta_types.h
@@ -42,7 +42,7 @@ typedef struct MetaElem {
float rad2;
/** Stiffness, how much of the element to fill. */
float s;
- /** Old, only used for backwards compat. use dimensions now. */
+ /** Old, only used for backwards compatibility. use dimensions now. */
float len;
/** Matrix and inverted matrix. */
@@ -63,7 +63,7 @@ typedef struct MetaBall {
/* material of the mother ball will define the material used of all others */
struct Material **mat;
- /** Flag is enum for updates, flag2 is bitflags for settings. */
+ /** Flag is enum for updates, flag2 is bit-flags for settings. */
char flag, flag2;
short totcol;
/** Used to store MB_AUTOSPACE. */
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 787f52f9891..c4180071352 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -195,7 +195,7 @@ typedef struct LatticeModifierData {
ModifierData modifier;
struct Object *object;
- /** Optional vertexgroup name, MAX_VGROUP_NAME. */
+ /** Optional vertex-group name, #MAX_VGROUP_NAME. */
char name[64];
float strength;
short flag;
@@ -212,7 +212,7 @@ typedef struct CurveModifierData {
ModifierData modifier;
struct Object *object;
- /** Optional vertexgroup name, MAX_VGROUP_NAME. */
+ /** Optional vertex-group name, #MAX_VGROUP_NAME. */
char name[64];
/** Axis along which curve deforms. */
short defaxis;
@@ -262,7 +262,7 @@ typedef struct MaskModifierData {
/** Armature to use to in place of hardcoded vgroup. */
struct Object *ob_arm;
- /** Name of vertex group to use to mask, MAX_VGROUP_NAME. */
+ /** Name of vertex group to use to mask, #MAX_VGROUP_NAME. */
char vgroup[64];
/** Using armature or hardcoded vgroup. */
@@ -447,7 +447,7 @@ typedef struct BevelModifierData {
float bevel_angle;
float spread;
/** if the MOD_BEVEL_VWEIGHT option is set,
- * this will be the name of the vert group, MAX_VGROUP_NAME */
+ * this will be the name of the vert group, #MAX_VGROUP_NAME */
char defgrp_name[64];
char _pad1[4];
@@ -565,7 +565,7 @@ typedef struct DisplaceModifierData {
float strength;
int direction;
- /** MAX_VGROUP_NAME. */
+ /** #MAX_VGROUP_NAME. */
char defgrp_name[64];
float midlevel;
int space;
@@ -635,7 +635,7 @@ typedef struct DecimateModifierData {
/** (mode == MOD_DECIM_MODE_DISSOLVE). */
float angle;
- /** MAX_VGROUP_NAME. */
+ /** #MAX_VGROUP_NAME. */
char defgrp_name[64];
float defgrp_factor;
short flag, mode;
@@ -663,7 +663,7 @@ enum {
typedef struct SmoothModifierData {
ModifierData modifier;
float fac;
- /** MAX_VGROUP_NAME. */
+ /** #MAX_VGROUP_NAME. */
char defgrp_name[64];
short flag, repeat;
@@ -684,7 +684,7 @@ typedef struct CastModifierData {
float fac;
float radius;
float size;
- /** MAX_VGROUP_NAME. */
+ /** #MAX_VGROUP_NAME. */
char defgrp_name[64];
short flag;
/** Cast modifier projection type. */
@@ -725,7 +725,7 @@ typedef struct WaveModifierData {
/* End MappingInfoModifierData. */
struct Object *objectcenter;
- /** MAX_VGROUP_NAME. */
+ /** #MAX_VGROUP_NAME. */
char defgrp_name[64];
short flag;
@@ -760,7 +760,7 @@ typedef struct ArmatureModifierData {
struct Object *object;
/** Stored input of previous modifier, for vertex-group blending. */
float (*vert_coords_prev)[3];
- /** MAX_VGROUP_NAME. */
+ /** #MAX_VGROUP_NAME. */
char defgrp_name[64];
} ArmatureModifierData;
@@ -803,11 +803,11 @@ typedef struct HookModifierData {
struct CurveMapping *curfalloff;
- /** If NULL, it's using vertexgroup. */
+ /** If NULL, it's using vertex-group. */
int *indexar;
int indexar_num;
float force;
- /** Optional vertexgroup name, MAX_VGROUP_NAME. */
+ /** Optional vertex-group name, #MAX_VGROUP_NAME. */
char name[64];
void *_pad1;
} HookModifierData;
@@ -946,7 +946,7 @@ typedef struct MeshDeformModifierData {
/** Mesh object. */
struct Object *object;
- /** Optional vertexgroup name, MAX_VGROUP_NAME. */
+ /** Optional vertex-group name, #MAX_VGROUP_NAME. */
char defgrp_name[64];
short gridsize, flag;
@@ -1124,7 +1124,7 @@ typedef struct ShrinkwrapModifierData {
struct Object *target;
/** Additional shrink target. */
struct Object *auxTarget;
- /** Optional vertexgroup name, MAX_VGROUP_NAME. */
+ /** Optional vertex-group name, #MAX_VGROUP_NAME. */
char vgroup_name[64];
/** Distance offset to keep from mesh/projection point. */
float keepDist;
@@ -1171,9 +1171,9 @@ enum {
/** #ShrinkwrapModifierData.shrinkOpts */
enum {
- /** allow shrinkwrap to move the vertex in the positive direction of axis */
+ /** Allow shrink-wrap to move the vertex in the positive direction of axis. */
MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR = (1 << 0),
- /** allow shrinkwrap to move the vertex in the negative direction of axis */
+ /** Allow shrink-wrap to move the vertex in the negative direction of axis. */
MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR = (1 << 1),
/** ignore vertex moves if a vertex ends projected on a front face of the target */
@@ -1207,7 +1207,7 @@ typedef struct SimpleDeformModifierData {
/** Object to control the origin of modifier space coordinates. */
struct Object *origin;
- /** Optional vertexgroup name, MAX_VGROUP_NAME. */
+ /** Optional vertex-group name, #MAX_VGROUP_NAME. */
char vgroup_name[64];
/** Factors to control simple deforms. */
float factor;
@@ -1250,7 +1250,7 @@ typedef struct ShapeKeyModifierData {
typedef struct SolidifyModifierData {
ModifierData modifier;
- /** Name of vertex group to use, MAX_VGROUP_NAME. */
+ /** Name of vertex group to use, #MAX_VGROUP_NAME. */
char defgrp_name[64];
char shell_defgrp_name[64];
char rim_defgrp_name[64];
@@ -1451,7 +1451,7 @@ typedef struct WarpModifierData {
char bone_to[64];
struct CurveMapping *curfalloff;
- /** Optional vertexgroup name, MAX_VGROUP_NAME. */
+ /** Optional vertex-group name, #MAX_VGROUP_NAME. */
char defgrp_name[64];
float strength;
float falloff_radius;
@@ -1484,7 +1484,7 @@ typedef enum {
typedef struct WeightVGEditModifierData {
ModifierData modifier;
- /** Name of vertex group to edit. MAX_VGROUP_NAME. */
+ /** Name of vertex group to edit. #MAX_VGROUP_NAME. */
char defgrp_name[64];
/** Using MOD_WVG_EDIT_* flags. */
@@ -1504,7 +1504,7 @@ typedef struct WeightVGEditModifierData {
/* Masking options. */
/** The global "influence", if no vgroup nor tex is used as mask. */
float mask_constant;
- /** Name of mask vertex group from which to get weight factors. MAX_VGROUP_NAME. */
+ /** Name of mask vertex group from which to get weight factors. #MAX_VGROUP_NAME. */
char mask_defgrp_name[64];
/* Texture masking. */
@@ -1540,9 +1540,9 @@ enum {
typedef struct WeightVGMixModifierData {
ModifierData modifier;
- /** Name of vertex group to modify/weight. MAX_VGROUP_NAME. */
+ /** Name of vertex group to modify/weight. #MAX_VGROUP_NAME. */
char defgrp_name_a[64];
- /** Name of other vertex group to mix in. MAX_VGROUP_NAME. */
+ /** Name of other vertex group to mix in. #MAX_VGROUP_NAME. */
char defgrp_name_b[64];
/** Default weight value for first vgroup. */
float default_weight_a;
@@ -1558,7 +1558,7 @@ typedef struct WeightVGMixModifierData {
/* Masking options. */
/** The global "influence", if no vgroup nor tex is used as mask. */
float mask_constant;
- /** Name of mask vertex group from which to get weight factors. MAX_VGROUP_NAME. */
+ /** Name of mask vertex group from which to get weight factors. #MAX_VGROUP_NAME. */
char mask_defgrp_name[64];
/* Texture masking. */
@@ -1628,7 +1628,7 @@ enum {
typedef struct WeightVGProximityModifierData {
ModifierData modifier;
- /** Name of vertex group to modify/weight. MAX_VGROUP_NAME. */
+ /** Name of vertex group to modify/weight. #MAX_VGROUP_NAME. */
char defgrp_name[64];
/* Mapping stuff. */
@@ -1646,7 +1646,7 @@ typedef struct WeightVGProximityModifierData {
/* Masking options. */
/** The global "influence", if no vgroup nor tex is used as mask. */
float mask_constant;
- /** Name of mask vertex group from which to get weight factors. MAX_VGROUP_NAME. */
+ /** Name of mask vertex group from which to get weight factors. #MAX_VGROUP_NAME. */
char mask_defgrp_name[64];
/* Texture masking. */
@@ -1840,7 +1840,7 @@ typedef struct LaplacianSmoothModifierData {
float lambda, lambda_border;
char _pad1[4];
- /** MAX_VGROUP_NAME. */
+ /** #MAX_VGROUP_NAME. */
char defgrp_name[64];
short flag, repeat;
} LaplacianSmoothModifierData;
@@ -1856,9 +1856,13 @@ enum {
};
typedef struct CorrectiveSmoothDeltaCache {
- /* delta's between the original positions and the smoothed positions */
+ /**
+ * Delta's between the original positions and the smoothed positions,
+ * calculated loop-tangent and which is accumulated into the vertex it uses.
+ * (run-time only).
+ */
float (*deltas)[3];
- unsigned int totverts;
+ unsigned int deltas_num;
/* Value of settings when creating the cache.
* These are used to check if the cache should be recomputed. */
@@ -1883,7 +1887,7 @@ typedef struct CorrectiveSmoothModifierData {
char smooth_type, rest_source;
char _pad[6];
- /** MAX_VGROUP_NAME. */
+ /** #MAX_VGROUP_NAME. */
char defgrp_name[64];
/* runtime-only cache */
@@ -1928,7 +1932,7 @@ typedef struct UVWarpModifierData {
/** Optional name of bone target, MAX_ID_NAME-2. */
char bone_dst[64];
- /** Optional vertexgroup name, MAX_VGROUP_NAME. */
+ /** Optional vertex-group name, #MAX_VGROUP_NAME. */
char vgroup_name[64];
/** MAX_CUSTOMDATA_LAYER_NAME. */
char uvlayer_name[64];
@@ -2009,7 +2013,7 @@ enum {
typedef struct LaplacianDeformModifierData {
ModifierData modifier;
- /** MAX_VGROUP_NAME. */
+ /** #MAX_VGROUP_NAME. */
char anchor_grp_name[64];
int verts_num, repeat;
float *vertexco;
@@ -2031,7 +2035,7 @@ enum {
*/
typedef struct WireframeModifierData {
ModifierData modifier;
- /** MAX_VGROUP_NAME. */
+ /** #MAX_VGROUP_NAME. */
char defgrp_name[64];
float offset;
float offset_fac;
@@ -2055,7 +2059,7 @@ typedef struct WeldModifierData {
/* The limit below which to merge vertices. */
float merge_dist;
- /* Name of vertex group to use to mask, MAX_VGROUP_NAME. */
+ /** Name of vertex group to use to mask, #MAX_VGROUP_NAME. */
char defgrp_name[64];
char mode;
@@ -2103,7 +2107,7 @@ typedef struct DataTransferModifierData {
/** See CDT_MIX_ enum in BKE_customdata.h. */
int mix_mode;
float mix_factor;
- /** MAX_VGROUP_NAME. */
+ /** #MAX_VGROUP_NAME. */
char defgrp_name[64];
int flags;
@@ -2126,7 +2130,7 @@ enum {
/** Set Split Normals modifier. */
typedef struct NormalEditModifierData {
ModifierData modifier;
- /** MAX_VGROUP_NAME. */
+ /** #MAX_VGROUP_NAME. */
char defgrp_name[64];
/** Source of normals, or center of ellipsoid. */
struct Object *target;
@@ -2249,7 +2253,7 @@ enum {
typedef struct WeightedNormalModifierData {
ModifierData modifier;
- /** MAX_VGROUP_NAME. */
+ /** #MAX_VGROUP_NAME. */
char defgrp_name[64];
char mode, flag;
short weight;
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 735f5c7b20a..3161238dc2e 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -135,16 +135,16 @@ typedef struct bNodeSocket {
/** Default input value used for unlinked sockets. */
void *default_value;
- /* execution data */
- /** Local stack index. */
+ /** Local stack index for "node_exec". */
short stack_index;
- /* XXX deprecated, kept for forward compatibility */
- short stack_type DNA_DEPRECATED;
char display_shape;
/* #eAttrDomain used when the geometry nodes modifier creates an attribute for a group
* output. */
char attribute_domain;
+
+ char _pad[2];
+
/* Runtime-only cache of the number of input links, for multi-input sockets. */
short total_inputs;
@@ -170,9 +170,6 @@ typedef struct bNodeSocket {
int own_index DNA_DEPRECATED;
/* XXX deprecated, only used for restoring old group node links */
int to_index DNA_DEPRECATED;
- /* XXX deprecated, still forward compatible since verification
- * restores pointer from matching own_index. */
- struct bNodeSocket *groupsock DNA_DEPRECATED;
/** A link pointer, set in #BKE_ntree_update_main. */
struct bNodeLink *link;
@@ -505,6 +502,7 @@ typedef struct bNodeLink {
#ifdef __cplusplus
bool is_muted() const;
+ bool is_available() const;
#endif
} bNodeLink;
@@ -615,7 +613,7 @@ typedef struct bNodeTree {
void (*progress)(void *, float progress);
/** \warning may be called by different threads */
void (*stats_draw)(void *, const char *str);
- int (*test_break)(void *);
+ bool (*test_break)(void *);
void (*update_draw)(void *);
void *tbh, *prh, *sdh, *udh;
@@ -655,12 +653,12 @@ typedef struct bNodeTree {
/**
* Cached toposort of all nodes. If there are cycles, the returned array is not actually a
* toposort. However, if a connected component does not contain a cycle, this component is sorted
- * correctly. Use #has_link_cycle to check for cycles.
+ * correctly. Use #has_available_link_cycle to check for cycles.
*/
blender::Span<const bNode *> toposort_left_to_right() const;
blender::Span<const bNode *> toposort_right_to_left() const;
/** True when there are any cycles in the node tree. */
- bool has_link_cycle() const;
+ bool has_available_link_cycle() const;
/**
* True when there are nodes or sockets in the node tree that don't use a known type. This can
* happen when nodes don't exist in the current Blender version that existed in the version where
@@ -933,7 +931,7 @@ typedef struct NodeImageMultiFileSocket {
char path[1024];
ImageFormatData format;
- /* multilayer output */
+ /* Multi-layer output. */
/** EXR_TOT_MAXNAME-2 ('.' and channel char are appended). */
char layer[30];
char _pad2[2];
@@ -992,7 +990,7 @@ typedef struct NodeGlare {
char _pad1[4];
} NodeGlare;
-/** Tonemap node. */
+/** Tone-map node. */
typedef struct NodeTonemap {
float key, offset, gamma;
float f, m, a, c;
@@ -1275,7 +1273,7 @@ typedef struct CryptomatteLayer {
typedef struct NodeCryptomatte_Runtime {
/* Contains `CryptomatteLayer`. */
ListBase layers;
- /* Temp storage for the cryptomatte picker. */
+ /* Temp storage for the crypto-matte picker. */
float add[3];
float remove[3];
} NodeCryptomatte_Runtime;
@@ -1499,6 +1497,10 @@ typedef struct NodeGeometryCurveToPoints {
typedef struct NodeGeometryCurveSample {
/* GeometryNodeCurveSampleMode. */
uint8_t mode;
+ int8_t use_all_curves;
+ /* eCustomDataType. */
+ int8_t data_type;
+ char _pad[1];
} NodeGeometryCurveSample;
typedef struct NodeGeometryTransferAttribute {
@@ -1511,6 +1513,15 @@ typedef struct NodeGeometryTransferAttribute {
char _pad[1];
} NodeGeometryTransferAttribute;
+typedef struct NodeGeometrySampleIndex {
+ /* eCustomDataType. */
+ int8_t data_type;
+ /* eAttrDomain. */
+ int8_t domain;
+ int8_t clamp;
+ char _pad[1];
+} NodeGeometrySampleIndex;
+
typedef struct NodeGeometryRaycast {
/* GeometryNodeRaycastMapMode. */
uint8_t mapping;
@@ -1588,6 +1599,8 @@ typedef struct NodeGeometryImageTexture {
typedef struct NodeGeometryViewer {
/* eCustomDataType. */
int8_t data_type;
+ /* eAttrDomain. */
+ int8_t domain;
} NodeGeometryViewer;
typedef struct NodeGeometryUVUnwrap {
@@ -1595,6 +1608,11 @@ typedef struct NodeGeometryUVUnwrap {
uint8_t method;
} NodeGeometryUVUnwrap;
+typedef struct NodeGeometryDistributePointsInVolume {
+ /* GeometryNodePointDistributeVolumeMode. */
+ uint8_t mode;
+} NodeGeometryDistributePointsInVolume;
+
typedef struct NodeFunctionCompare {
/* NodeCompareOperation */
int8_t operation;
@@ -1669,6 +1687,7 @@ enum {
SHD_ATTRIBUTE_GEOMETRY = 0,
SHD_ATTRIBUTE_OBJECT = 1,
SHD_ATTRIBUTE_INSTANCER = 2,
+ SHD_ATTRIBUTE_VIEW_LAYER = 3,
};
/* toon modes */
@@ -2059,6 +2078,21 @@ typedef enum CMPNodeFilterMethod {
CMP_NODE_FILTER_SHARP_DIAMOND = 7,
} CMPNodeFilterMethod;
+/* Levels Node. Stored in custom1. */
+typedef enum CMPNodeLevelsChannel {
+ CMP_NODE_LEVLES_LUMINANCE = 1,
+ CMP_NODE_LEVLES_RED = 2,
+ CMP_NODE_LEVLES_GREEN = 3,
+ CMP_NODE_LEVLES_BLUE = 4,
+ CMP_NODE_LEVLES_LUMINANCE_BT709 = 5,
+} CMPNodeLevelsChannel;
+
+/* Tone Map Node. Stored in NodeTonemap.type. */
+typedef enum CMPNodeToneMapType {
+ CMP_NODE_TONE_MAP_SIMPLE = 0,
+ CMP_NODE_TONE_MAP_PHOTORECEPTOR = 1,
+} CMPNodeToneMapType;
+
/* Plane track deform node. */
enum {
@@ -2176,6 +2210,11 @@ typedef enum GeometryNodeTriangulateQuads {
GEO_NODE_TRIANGULATE_QUAD_LONGEDGE = 4,
} GeometryNodeTriangulateQuads;
+typedef enum GeometryNodeDistributePointsInVolumeMode {
+ GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME_DENSITY_RANDOM = 0,
+ GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME_DENSITY_GRID = 1,
+} GeometryNodeDistributePointsInVolumeMode;
+
typedef enum GeometryNodeDistributePointsOnFacesMode {
GEO_NODE_POINT_DISTRIBUTE_POINTS_ON_FACES_RANDOM = 0,
GEO_NODE_POINT_DISTRIBUTE_POINTS_ON_FACES_POISSON = 1,
diff --git a/source/blender/makesdna/DNA_object_defaults.h b/source/blender/makesdna/DNA_object_defaults.h
index 14683869bc4..2a5796d2aea 100644
--- a/source/blender/makesdna/DNA_object_defaults.h
+++ b/source/blender/makesdna/DNA_object_defaults.h
@@ -23,7 +23,7 @@
\
.constinv = _DNA_DEFAULT_UNIT_M4, \
.parentinv = _DNA_DEFAULT_UNIT_M4, \
- .obmat = _DNA_DEFAULT_UNIT_M4, \
+ .object_to_world = _DNA_DEFAULT_UNIT_M4, \
\
.scale = {1, 1, 1}, \
.dscale = {1, 1, 1}, \
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index add11d61db8..494295f7bb9 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -231,6 +231,7 @@ enum eObjectLineArt_Usage {
OBJECT_LRT_EXCLUDE = (1 << 2),
OBJECT_LRT_INTERSECTION_ONLY = (1 << 3),
OBJECT_LRT_NO_INTERSECTION = (1 << 4),
+ OBJECT_LRT_FORCE_INTERSECTION = (1 << 5),
};
enum eObjectLineArt_Flags {
@@ -321,20 +322,14 @@ typedef struct Object {
float rotAxis[3], drotAxis[3];
/** Axis angle rotation - angle part. */
float rotAngle, drotAngle;
- /** Final world-space matrix with constraints & animsys applied. */
- float obmat[4][4];
+ /** Final transformation matrices with constraints & animsys applied. */
+ float object_to_world[4][4];
+ float world_to_object[4][4];
/** Inverse result of parent, so that object doesn't 'stick' to parent. */
float parentinv[4][4];
/** Inverse result of constraints.
* doesn't include effect of parent or object local transform. */
float constinv[4][4];
- /**
- * Inverse matrix of 'obmat' for any other use than rendering!
- *
- * \note this isn't assured to be valid as with 'obmat',
- * before using this value you should do: `invert_m4_m4(ob->imat, ob->obmat)`
- */
- float imat[4][4];
/** Copy of Base's layer in the scene. */
unsigned int lay DNA_DEPRECATED;
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 268e1412eef..c4f11905e10 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -159,7 +159,7 @@ typedef struct SPHFluidSettings {
char _pad[6];
} SPHFluidSettings;
-/* fluid->flag */
+/** #SPHFluidSettings.flag */
#define SPH_VISCOELASTIC_SPRINGS 1
#define SPH_CURRENT_REST_LENGTH 2
#define SPH_FAC_REPULSION 4
@@ -168,7 +168,7 @@ typedef struct SPHFluidSettings {
#define SPH_FAC_VISCOSITY 32
#define SPH_FAC_REST_LENGTH 64
-/* fluid->solver (numerical ID field, not bitfield) */
+/** #SPHFluidSettings.solver (numerical ID field, not bit-field). */
#define SPH_SOLVER_DDR 0
#define SPH_SOLVER_CLASSICAL 1
@@ -279,7 +279,7 @@ typedef struct ParticleSettings {
struct PartDeflect *pd;
struct PartDeflect *pd2;
- /* modified dm support */
+ /* Evaluated mesh support. */
short use_modifier_stack;
char _pad5[2];
@@ -465,7 +465,7 @@ enum {
#define PART_REACT_MULTIPLE 2
//#define PART_LOOP 4 /* not used anymore */
-/* for dopesheet */
+/* For dope-sheet. */
#define PART_DS_EXPAND 8
#define PART_HAIR_REGROW 16 /* regrow hair for each frame */
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index f184460cba4..8d02b274c65 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -12,8 +12,10 @@
/* XXX(@campbellbarton): temp feature. */
#define DURIAN_CAMERA_SWITCH
-/* check for cyclic set-scene,
- * libs can cause this case which is normally prevented, see (T#####) */
+/**
+ * Check for cyclic set-scene.
+ * Libraries can cause this case which is normally prevented, see (T42009).
+ */
#define USE_SETSCENE_CHECK
#include "DNA_ID.h"
@@ -401,12 +403,12 @@ typedef struct ImageFormatData {
/** R_IMF_PLANES_BW, R_IMF_PLANES_RGB, R_IMF_PLANES_RGBA. */
char planes;
- /** Generic options for all image types, alpha zbuffer. */
+ /** Generic options for all image types, alpha Z-buffer. */
char flag;
- /** (0 - 100), eg: jpeg quality. */
+ /** (0 - 100), eg: JPEG quality. */
char quality;
- /** (0 - 100), eg: png compression. */
+ /** (0 - 100), eg: PNG compression. */
char compress;
/* --- format specific --- */
@@ -470,6 +472,7 @@ typedef struct ImageFormatData {
#define R_IMF_IMTYPE_THEORA 33
#define R_IMF_IMTYPE_PSD 34
#define R_IMF_IMTYPE_WEBP 35
+#define R_IMF_IMTYPE_AV1 36
#define R_IMF_IMTYPE_INVALID 255
@@ -557,7 +560,8 @@ typedef struct BakeData {
char target;
char save_mode;
char margin_type;
- char _pad[5];
+ char view_from;
+ char _pad[4];
struct Object *cage_object;
} BakeData;
@@ -590,6 +594,12 @@ typedef enum eBakeSaveMode {
R_BAKE_SAVE_EXTERNAL = 1,
} eBakeSaveMode;
+/** #BakeData.view_from (char) */
+typedef enum eBakeViewFrom {
+ R_BAKE_VIEW_FROM_ABOVE_SURFACE = 0,
+ R_BAKE_VIEW_FROM_ACTIVE_CAMERA = 1,
+} eBakeViewFrom;
+
/** #BakeData.pass_filter */
typedef enum eBakePassFilter {
R_BAKE_PASS_FILTER_NONE = 0,
@@ -1019,8 +1029,15 @@ typedef struct Sculpt {
float constant_detail;
float detail_percent;
+ int automasking_cavity_blur_steps;
+ float automasking_cavity_factor;
char _pad[4];
+ float automasking_start_normal_limit, automasking_start_normal_falloff;
+ float automasking_view_normal_limit, automasking_view_normal_falloff;
+
+ struct CurveMapping *automasking_cavity_curve;
+ struct CurveMapping *automasking_cavity_curve_op; /* For use by operators */
struct Object *gravity_object;
} Sculpt;
@@ -1138,6 +1155,16 @@ typedef enum eGP_Sculpt_SettingsFlag {
GP_SCULPT_SETT_FLAG_PRIMITIVE_CURVE = (1 << 1),
/** Scale thickness. */
GP_SCULPT_SETT_FLAG_SCALE_THICKNESS = (1 << 3),
+ /* Stroke Auto-Masking for sculpt. */
+ GP_SCULPT_SETT_FLAG_AUTOMASK_STROKE = (1 << 4),
+ /* Stroke Layer Auto-Masking for sculpt. */
+ GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_STROKE = (1 << 5),
+ /* Stroke Material Auto-Masking for sculpt. */
+ GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_STROKE = (1 << 6),
+ /* Active Layer Auto-Masking for sculpt. */
+ GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_ACTIVE = (1 << 7),
+ /* Active Material Auto-Masking for sculpt. */
+ GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_ACTIVE = (1 << 8),
} eGP_Sculpt_SettingsFlag;
/** #GP_Sculpt_Settings.gpencil_selectmode_sculpt */
@@ -1500,12 +1527,12 @@ typedef struct ToolSettings {
/* Transform */
char transform_pivot_point;
char transform_flag;
- /** Snap elements (per spacetype), #eSnapMode. */
+ /** Snap elements (per space-type), #eSnapMode. */
char _pad1[1];
short snap_mode;
char snap_node_mode;
char snap_uv_mode;
- /** Generic flags (per spacetype), #eSnapFlag. */
+ /** Generic flags (per space-type), #eSnapFlag. */
short snap_flag;
short snap_flag_node;
short snap_flag_seq;
@@ -1745,6 +1772,8 @@ typedef struct Scene {
ID id;
/** Animation data (must be immediately after id for utilities to use it). */
struct AnimData *adt;
+ /* runtime (must be immediately after id for utilities to use it). */
+ DrawDataList drawdata;
struct Object *camera;
struct World *world;
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index 9b999e4426f..4d4bd9ef775 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -437,7 +437,7 @@ typedef struct ARegion_Runtime {
* Lazy initialize, zero'd when unset, relative to #ARegion.winrct x/y min. */
rcti visible_rect;
- /* The offset needed to not overlap with window scrollbars. Only used by HUD regions for now. */
+ /* The offset needed to not overlap with window scroll-bars. Only used by HUD regions for now. */
int offset_x, offset_y;
/* Maps uiBlock->name to uiBlock for faster lookups. */
@@ -477,7 +477,7 @@ typedef struct ARegion {
short do_draw_paintcursor;
/** Private, set for indicate drawing overlapped. */
short overlap;
- /** Temporary copy of flag settings for clean fullscreen. */
+ /** Temporary copy of flag settings for clean full-screen. */
short flagfullscreen;
/** Callbacks for this region type. */
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h
index c0f92010c22..d8005b83383 100644
--- a/source/blender/makesdna/DNA_sequence_types.h
+++ b/source/blender/makesdna/DNA_sequence_types.h
@@ -184,7 +184,7 @@ typedef struct Sequence {
/** Old animation system, deprecated for 2.5. */
struct Ipo *ipo DNA_DEPRECATED;
- /** these ID vars should never be NULL but can be when linked libs fail to load,
+ /** these ID vars should never be NULL but can be when linked libraries fail to load,
* so check on access */
struct Scene *scene;
/** Override scene camera. */
diff --git a/source/blender/makesdna/DNA_sound_types.h b/source/blender/makesdna/DNA_sound_types.h
index ba926f0f4fa..65d62b68561 100644
--- a/source/blender/makesdna/DNA_sound_types.h
+++ b/source/blender/makesdna/DNA_sound_types.h
@@ -78,7 +78,7 @@ typedef struct bSound {
/* XXX unused currently (SOUND_TYPE_LIMITER) */
/* float start, end; */
- /* Description of Audio channels, as of eSoundChannels*/
+ /* Description of Audio channels, as of #eSoundChannels. */
int audio_channels;
int samplerate;
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 6e05dd395ba..8dce71fd33e 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -22,6 +22,7 @@
#include "DNA_vec_types.h"
/* Hum ... Not really nice... but needed for spacebuts. */
#include "DNA_view2d_types.h"
+#include "DNA_viewer_path_types.h"
#ifdef __cplusplus
extern "C" {
@@ -666,7 +667,7 @@ typedef struct SpaceSeq {
struct SequencerPreviewOverlay preview_overlay;
struct SequencerTimelineOverlay timeline_overlay;
- /** Multiview current eye - for internal use. */
+ /** Multi-view current eye - for internal use. */
char multiview_eye;
char _pad2[7];
@@ -1080,6 +1081,7 @@ typedef enum eFileSel_File_Types {
FILE_TYPE_DIR = (1 << 30),
FILE_TYPE_BLENDERLIB = (1u << 31),
} eFileSel_File_Types;
+ENUM_OPERATORS(eFileSel_File_Types, FILE_TYPE_BLENDERLIB);
/** Selection Flags in filesel: struct direntry, unsigned char selflag. */
typedef enum eDirEntry_SelectFlag {
@@ -1099,7 +1101,7 @@ typedef struct FileDirEntry {
uint32_t uid; /* FileUID */
/* Name needs freeing if FILE_ENTRY_NAME_FREE is set. Otherwise this is a direct pointer to a
* name buffer. */
- char *name;
+ const char *name;
uint64_t size;
int64_t time;
@@ -1126,7 +1128,7 @@ typedef struct FileDirEntry {
/** If this file represents an asset, its asset data is here. Note that we may show assets of
* external files in which case this is set but not the id above.
* Note comment for FileListInternEntry.local_data, the same applies here! */
- struct AssetMetaData *asset_data;
+ struct AssetRepresentation *asset;
/* The icon_id for the preview image. */
int preview_icon_id;
@@ -1161,6 +1163,10 @@ enum {
FILE_ENTRY_NAME_FREE = 1 << 1,
/* The preview for this entry is being loaded on another thread. */
FILE_ENTRY_PREVIEW_LOADING = 1 << 2,
+ /** For #FILE_TYPE_BLENDERLIB only: Denotes that the ID is known to not have a preview (none was
+ * found in the .blend). Stored so we don't keep trying to find non-existent previews every time
+ * we reload previews. When dealing with heavy files this can have quite an impact. */
+ FILE_ENTRY_BLENDERLIB_NO_PREVIEW = 1 << 3,
};
/** \} */
@@ -1176,6 +1182,12 @@ typedef struct SpaceImageOverlay {
char _pad[4];
} SpaceImageOverlay;
+typedef enum eSpaceImage_GridShapeSource {
+ SI_GRID_SHAPE_DYNAMIC = 0,
+ SI_GRID_SHAPE_FIXED = 1,
+ SI_GRID_SHAPE_PIXEL = 2,
+} eSpaceImage_GridShapeSource;
+
typedef struct SpaceImage {
SpaceLink *next, *prev;
/** Storage of regions for inactive spaces. */
@@ -1212,7 +1224,7 @@ typedef struct SpaceImage {
char pin;
- char pixel_snap_mode;
+ char pixel_round_mode;
char lock;
/** UV draw type. */
@@ -1222,7 +1234,9 @@ typedef struct SpaceImage {
char around;
char gizmo_flag;
- char _pad1[3];
+
+ char grid_shape_source;
+ char _pad1[2];
int flag;
@@ -1230,11 +1244,10 @@ typedef struct SpaceImage {
int tile_grid_shape[2];
/**
- * UV editor custom-grid. Value of `N` will produce `NxN` grid.
- * Use when #SI_CUSTOM_GRID is set.
+ * UV editor custom-grid. Value of `{M,N}` will produce `MxN` grid.
+ * Use when `custom_grid_shape == SI_GRID_SHAPE_FIXED`.
*/
- int custom_grid_subdiv;
- char _pad3[4];
+ int custom_grid_subdiv[2];
MaskSpaceInfo mask_info;
SpaceImageOverlay overlay;
@@ -1254,12 +1267,12 @@ typedef enum eSpaceImage_UVDT_Stretch {
SI_UVDT_STRETCH_AREA = 1,
} eSpaceImage_UVDT_Stretch;
-/** #SpaceImage.pixel_snap_mode */
-typedef enum eSpaceImage_PixelSnapMode {
- SI_PIXEL_SNAP_DISABLED = 0,
- SI_PIXEL_SNAP_CENTER = 1,
- SI_PIXEL_SNAP_CORNER = 2,
-} eSpaceImage_Snap_Mode;
+/** #SpaceImage.pixel_round_mode */
+typedef enum eSpaceImage_PixelRoundMode {
+ SI_PIXEL_ROUND_DISABLED = 0,
+ SI_PIXEL_ROUND_CENTER = 1,
+ SI_PIXEL_ROUND_CORNER = 2,
+} eSpaceImage_PixelRoundMode;
/** #SpaceImage.mode */
typedef enum eSpaceImage_Mode {
@@ -1293,7 +1306,7 @@ typedef enum eSpaceImage_Flag {
SI_FULLWINDOW = (1 << 16),
SI_FLAG_UNUSED_17 = (1 << 17),
- SI_CUSTOM_GRID = (1 << 18),
+ SI_FLAG_UNUSED_18 = (1 << 18),
/**
* This means that the image is drawn until it reaches the view edge,
@@ -1313,6 +1326,8 @@ typedef enum eSpaceImage_Flag {
SI_SHOW_R = (1 << 27),
SI_SHOW_G = (1 << 28),
SI_SHOW_B = (1 << 29),
+
+ SI_GRID_OVER_IMAGE = (1 << 30),
} eSpaceImage_Flag;
typedef enum eSpaceImageOverlay_Flag {
@@ -1630,7 +1645,7 @@ enum {
typedef struct ConsoleLine {
struct ConsoleLine *next, *prev;
- /* keep these 3 vars so as to share free, realloc funcs */
+ /* Keep these 3 vars so as to share free, realloc functions. */
/** Allocated length. */
int len_alloc;
/** Real len - strlen(). */
@@ -1880,32 +1895,6 @@ typedef struct SpreadsheetColumn {
char *display_name;
} SpreadsheetColumn;
-/**
- * An item in SpaceSpreadsheet.context_path.
- * This is a bases struct for the structs below.
- */
-typedef struct SpreadsheetContext {
- struct SpreadsheetContext *next, *prev;
- /* eSpaceSpreadsheet_ContextType. */
- int type;
- char _pad[4];
-} SpreadsheetContext;
-
-typedef struct SpreadsheetContextObject {
- SpreadsheetContext base;
- struct Object *object;
-} SpreadsheetContextObject;
-
-typedef struct SpreadsheetContextModifier {
- SpreadsheetContext base;
- char *modifier_name;
-} SpreadsheetContextModifier;
-
-typedef struct SpreadsheetContextNode {
- SpreadsheetContext base;
- char *node_name;
-} SpreadsheetContextNode;
-
typedef struct SpaceSpreadsheet {
SpaceLink *next, *prev;
/** Storage of regions for inactive spaces. */
@@ -1922,12 +1911,11 @@ typedef struct SpaceSpreadsheet {
ListBase row_filters;
/**
- * List of #SpreadsheetContext.
- * This is a path to the data that is displayed in the spreadsheet.
- * It can be set explicitly by an action of the user (e.g. clicking the preview icon in a
- * geometry node) or it can be derived from context automatically based on some heuristic.
+ * Context that is currently displayed in the editor. This is usually a either a single object
+ * (in original/evaluated mode) or path to a viewer node. This is retrieved from the workspace
+ * but can be pinned so that it stays constant even when the active node changes.
*/
- ListBase context_path;
+ ViewerPath viewer_path;
/* eSpaceSpreadsheet_FilterFlag. */
uint8_t filter_flag;
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index e32d9dbe300..c7d49db130e 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -115,7 +115,7 @@ typedef struct PointDensity {
/** for 'Object' or 'Particle system' type - source object */
struct Object *object;
- /** `index + 1` in ob.particlesystem, non-ID pointer not allowed */
+ /** `index + 1` in ob.particle-system, non-ID pointer not allowed. */
int psys;
/** cache points in world-space, object space, ... ? */
short psys_cache_space;
diff --git a/source/blender/makesdna/DNA_userdef_enums.h b/source/blender/makesdna/DNA_userdef_enums.h
index e90aa0e0f07..dc368819ab0 100644
--- a/source/blender/makesdna/DNA_userdef_enums.h
+++ b/source/blender/makesdna/DNA_userdef_enums.h
@@ -39,6 +39,7 @@ typedef enum eDupli_ID_Flags {
USER_DUP_LATTICE = (1 << 17),
USER_DUP_CAMERA = (1 << 18),
USER_DUP_SPEAKER = (1 << 19),
+ USER_DUP_NTREE = (1 << 20),
USER_DUP_OBDATA = (~0) & ((1 << 24) - 1),
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 8c2c9a0665b..e0804052b45 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -582,7 +582,6 @@ typedef struct bUserAssetLibrary {
typedef struct SolidLight {
int flag;
float smooth;
- char _pad0[8];
float col[4], spec[4], vec[4];
} SolidLight;
@@ -1077,7 +1076,7 @@ typedef enum eWalkNavigation_Flag {
/** #UserDef.uiflag */
typedef enum eUserpref_UI_Flag {
- USER_UIFLAG_UNUSED_0 = (1 << 0), /* cleared */
+ USER_NO_MULTITOUCH_GESTURES = (1 << 0),
USER_UIFLAG_UNUSED_1 = (1 << 1), /* cleared */
USER_WHEELZOOMDIR = (1 << 2),
USER_FILTERFILEEXTS = (1 << 3),
diff --git a/source/blender/makesdna/DNA_view2d_types.h b/source/blender/makesdna/DNA_view2d_types.h
index d08865cefb5..7e53c1e4d37 100644
--- a/source/blender/makesdna/DNA_view2d_types.h
+++ b/source/blender/makesdna/DNA_view2d_types.h
@@ -19,9 +19,9 @@ extern "C" {
typedef struct View2D {
/** Tot - area that data can be drawn in; cur - region of tot that is visible in viewport. */
rctf tot, cur;
- /** Vert - vertical scrollbar region; hor - horizontal scrollbar region. */
+ /** Vert - vertical scroll-bar region; hor - horizontal scroll-bar region. */
rcti vert, hor;
- /** Mask - region (in screenspace) within which 'cur' can be viewed. */
+ /** Mask - region (in screen-space) within which 'cur' can be viewed. */
rcti mask;
/** Min/max sizes of 'cur' rect (only when keepzoom not set). */
@@ -29,7 +29,7 @@ typedef struct View2D {
/** Allowable zoom factor range (only when (keepzoom & V2D_LIMITZOOM)) is set. */
float minzoom, maxzoom;
- /** Scroll - scrollbars to display (bit-flag). */
+ /** Scroll - scroll-bars to display (bit-flag). */
short scroll;
/** Scroll_ui - temp settings used for UI drawing of scrollers. */
short scroll_ui;
@@ -56,7 +56,7 @@ typedef struct View2D {
short around;
/* Usually set externally (as in, not in view2d files). */
- /** Alpha of vertical and horizontal scrollbars (range is [0, 255]). */
+ /** Alpha of vertical and horizontal scroll-bars (range is [0, 255]). */
char alpha_vert, alpha_hor;
char _pad[6];
@@ -124,11 +124,11 @@ enum {
/** Scroller flags for View2D (#View2D.scroll). */
enum {
- /* left scrollbar */
+ /* Left scroll-bar. */
V2D_SCROLL_LEFT = (1 << 0),
V2D_SCROLL_RIGHT = (1 << 1),
V2D_SCROLL_VERTICAL = (V2D_SCROLL_LEFT | V2D_SCROLL_RIGHT),
- /* horizontal scrollbar */
+ /* Horizontal scroll-bar. */
V2D_SCROLL_TOP = (1 << 2),
V2D_SCROLL_BOTTOM = (1 << 3),
/* UNUSED = (1 << 4), */
@@ -137,11 +137,11 @@ enum {
V2D_SCROLL_VERTICAL_HANDLES = (1 << 5),
/* display horizontal scale handles */
V2D_SCROLL_HORIZONTAL_HANDLES = (1 << 6),
- /* induce hiding of scrollbars - set by region drawing in response to size of region */
+ /* Induce hiding of scroll-bar - set by region drawing in response to size of region. */
V2D_SCROLL_VERTICAL_HIDE = (1 << 7),
V2D_SCROLL_HORIZONTAL_HIDE = (1 << 8),
- /* scrollbar extends beyond its available window -
- * set when calculating scrollbars for drawing */
+ /* Scroll-bar extends beyond its available window -
+ * set when calculating scroll-bar for drawing */
V2D_SCROLL_VERTICAL_FULLR = (1 << 9),
V2D_SCROLL_HORIZONTAL_FULLR = (1 << 10),
};
diff --git a/source/blender/makesdna/DNA_view3d_defaults.h b/source/blender/makesdna/DNA_view3d_defaults.h
index b2d17b0ea22..f124bdd5d94 100644
--- a/source/blender/makesdna/DNA_view3d_defaults.h
+++ b/source/blender/makesdna/DNA_view3d_defaults.h
@@ -36,8 +36,10 @@
#define _DNA_DEFAULT_View3DOverlay \
{ \
+ .flag = V3D_OVERLAY_VIEWER_ATTRIBUTE, \
.wireframe_threshold = 1.0f, \
.wireframe_opacity = 1.0f, \
+ .viewer_attribute_opacity = 1.0f, \
.xray_alpha_bone = 0.5f, \
.bone_wire_alpha = 1.0f, \
.fade_alpha = 0.40f, \
@@ -81,7 +83,7 @@
.gridflag = V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_FLOOR | V3D_SHOW_ORTHO_GRID, \
\
.flag = V3D_SELECT_OUTLINE, \
- .flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_ANNOTATION, \
+ .flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_ANNOTATION | V3D_SHOW_VIEWER, \
\
.lens = 50.0f, \
.clip_start = 0.01f, \
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 1ba057d9c40..f3e56ba7039 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -22,6 +22,7 @@ struct wmTimer;
#include "DNA_movieclip_types.h"
#include "DNA_object_types.h"
#include "DNA_view3d_enums.h"
+#include "DNA_viewer_path_types.h"
#ifdef __cplusplus
extern "C" {
@@ -205,6 +206,7 @@ typedef struct View3DOverlay {
float weight_paint_mode_opacity;
float sculpt_mode_mask_opacity;
float sculpt_mode_face_sets_opacity;
+ float viewer_attribute_opacity;
/** Armature edit/pose mode settings. */
float xray_alpha_bone;
@@ -227,8 +229,6 @@ typedef struct View3DOverlay {
float gpencil_vertex_paint_opacity;
/** Handles display type for curves. */
int handle_display;
-
- char _pad[4];
} View3DOverlay;
/** #View3DOverlay.handle_display */
@@ -348,6 +348,9 @@ typedef struct View3D {
View3DShading shading;
View3DOverlay overlay;
+ /** Path to the viewer node that is currently previewed. This is retrieved from the workspace. */
+ ViewerPath viewer_path;
+
/** Runtime evaluation data (keep last). */
View3D_Runtime runtime;
} View3D;
@@ -391,7 +394,7 @@ enum {
#define RV3D_PAINTING (1 << 5)
/*#define RV3D_IS_GAME_ENGINE (1 << 5) */ /* UNUSED */
/**
- * Disable zbuffer offset, skip calls to #ED_view3d_polygon_offset.
+ * Disable Z-buffer offset, skip calls to #ED_view3d_polygon_offset.
* Use when precise surface depth is needed and picking bias isn't, see T45434).
*/
#define RV3D_ZOFFSET_DISABLED 64
@@ -443,7 +446,7 @@ enum {
/** #View3D.flag2 (int) */
#define V3D_HIDE_OVERLAYS (1 << 2)
-#define V3D_FLAG2_UNUSED_3 (1 << 3) /* cleared */
+#define V3D_SHOW_VIEWER (1 << 3)
#define V3D_SHOW_ANNOTATION (1 << 4)
#define V3D_LOCK_CAMERA (1 << 5)
#define V3D_FLAG2_UNUSED_6 (1 << 6) /* cleared */
@@ -528,6 +531,7 @@ enum {
V3D_OVERLAY_HIDE_OBJECT_ORIGINS = (1 << 10),
V3D_OVERLAY_STATS = (1 << 11),
V3D_OVERLAY_FADE_INACTIVE = (1 << 12),
+ V3D_OVERLAY_VIEWER_ATTRIBUTE = (1 << 13),
};
/** #View3DOverlay.edit_flag */
diff --git a/source/blender/makesdna/DNA_viewer_path_types.h b/source/blender/makesdna/DNA_viewer_path_types.h
new file mode 100644
index 00000000000..8f470b66ca0
--- /dev/null
+++ b/source/blender/makesdna/DNA_viewer_path_types.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include "BLI_listbase.h"
+#include "BLI_utildefines.h"
+
+struct ID;
+
+typedef enum ViewerPathElemType {
+ VIEWER_PATH_ELEM_TYPE_ID = 0,
+ VIEWER_PATH_ELEM_TYPE_MODIFIER = 1,
+ VIEWER_PATH_ELEM_TYPE_NODE = 2,
+} ViewerPathElemType;
+
+typedef struct ViewerPathElem {
+ struct ViewerPathElem *next, *prev;
+ int type;
+ char _pad[4];
+} ViewerPathElem;
+
+typedef struct IDViewerPathElem {
+ ViewerPathElem base;
+ struct ID *id;
+} IDViewerPathElem;
+
+typedef struct ModifierViewerPathElem {
+ ViewerPathElem base;
+ char *modifier_name;
+} ModifierViewerPathElem;
+
+typedef struct NodeViewerPathElem {
+ ViewerPathElem base;
+ char *node_name;
+} NodeViewerPathElem;
+
+typedef struct ViewerPath {
+ /** List of #ViewerPathElem. */
+ ListBase path;
+} ViewerPath;
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 47b7aee54d1..7231a995f10 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -70,6 +70,8 @@ enum ReportListFlags {
RPT_STORE = (1 << 1),
RPT_FREE = (1 << 2),
RPT_OP_HOLD = (1 << 3), /* don't move them into the operator global list (caller will use) */
+ /** Don't print (the owner of the #ReportList will handle printing to the `stdout`). */
+ RPT_PRINT_HANDLED_BY_OWNER = (1 << 4),
};
/* These two Lines with # tell makesdna this struct can be excluded. */
@@ -87,13 +89,13 @@ typedef struct Report {
} Report;
/**
- * \note Saved in the wm, don't remove.
+ * \note Saved in the #wmWindowManager, don't remove.
*/
typedef struct ReportList {
ListBase list;
- /** eReportType. */
+ /** #eReportType. */
int printlevel;
- /** eReportType. */
+ /** #eReportType. */
int storelevel;
int flag;
char _pad[4];
@@ -305,7 +307,22 @@ typedef struct wmWindow {
*/
short pie_event_type_last;
- /** Storage for event system. */
+ /**
+ * Storage for event system.
+ *
+ * For the most part this is storage for `wmEvent.xy` & `wmEvent.modifiers`.
+ * newly added key/button events copy the cursor location and modifier state stored here.
+ *
+ * It's also convenient at times to be able to pass this as if it's a regular event.
+ *
+ * - This is not simply the current event being handled.
+ * The type and value is always set to the last press/release events
+ * otherwise cursor motion would always clear these values.
+ *
+ * - The value of `eventstate->modifiers` is set from the last pressed/released modifier key.
+ * This has the down side that the modifier value will be incorrect if users hold both
+ * left/right modifiers then release one. See note in #wm_event_add_ghostevent for details.
+ */
struct wmEvent *eventstate;
/** Keep the last handled event in `event_queue` here (owned and must be freed). */
struct wmEvent *event_last_handled;
@@ -347,7 +364,7 @@ typedef struct wmOperatorTypeMacro {
struct wmOperatorTypeMacro *next, *prev;
/* operator id */
- char idname[64];
+ char idname[64]; /* OP_MAX_TYPENAME */
/* rna pointer to access properties, like keymap */
/** Operator properties, assigned to ptr->data and can be written to a file. */
struct IDProperty *properties;
@@ -534,7 +551,7 @@ typedef struct wmOperator {
/* saved */
/** Used to retrieve type pointer. */
- char idname[64];
+ char idname[64]; /* OP_MAX_TYPENAME */
/** Saved, user-settable properties. */
IDProperty *properties;
diff --git a/source/blender/makesdna/DNA_workspace_types.h b/source/blender/makesdna/DNA_workspace_types.h
index a72689badb1..0cd1144b30d 100644
--- a/source/blender/makesdna/DNA_workspace_types.h
+++ b/source/blender/makesdna/DNA_workspace_types.h
@@ -10,6 +10,7 @@
#include "DNA_ID.h"
#include "DNA_asset_types.h"
+#include "DNA_viewer_path_types.h"
#ifdef __cplusplus
extern "C" {
@@ -59,7 +60,7 @@ typedef struct bToolRef {
/** Use to avoid initializing the same tool multiple times. */
short tag;
- /** #bToolKey (spacetype, mode), used in 'WM_api.h' */
+ /** #bToolKey (space-type, mode), used in 'WM_api.h' */
short space_type;
/**
* Value depends on the 'space_type', object mode for 3D view, image editor has own mode too.
@@ -143,6 +144,13 @@ typedef struct WorkSpace {
/** Workspace-wide active asset library, for asset UIs to use (e.g. asset view UI template). The
* Asset Browser has its own and doesn't use this. */
AssetLibraryReference asset_library_ref;
+
+ /**
+ * Ground truth for the currently active viewer node. When a viewer node is activated its path is
+ * set here. Editors can check here for which node is active (currently the node editor,
+ * spreadsheet and viewport do this).
+ */
+ ViewerPath viewer_path;
} WorkSpace;
/**
@@ -191,8 +199,10 @@ typedef struct WorkSpaceInstanceHook {
WorkSpace *active;
struct WorkSpaceLayout *act_layout;
- /** Needed because we can't change workspaces/layouts in running handler loop,
- * it would break context. */
+ /**
+ * Needed because we can't change work-spaces/layouts in running handler loop,
+ * it would break context.
+ */
WorkSpace *temp_workspace_store;
struct WorkSpaceLayout *temp_layout_store;
} WorkSpaceInstanceHook;
diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt
index 97198117a83..50fd51e88a1 100644
--- a/source/blender/makesdna/intern/CMakeLists.txt
+++ b/source/blender/makesdna/intern/CMakeLists.txt
@@ -3,6 +3,22 @@
# message(STATUS "Configuring makesdna")
+set(INC
+ ..
+ ../../blenlib
+ ../../imbuf
+ ../../../../intern/atomic
+ ../../../../intern/guardedalloc
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+set(INC_SYS
+
+)
+
+set(LIB
+)
+
add_definitions(-DWITH_DNA_GHASH)
# Needed for `mallocn.c`.
@@ -10,14 +26,6 @@ if(HAVE_MALLOC_STATS_H)
add_definitions(-DHAVE_MALLOC_STATS_H)
endif()
-blender_include_dirs(
- ../../../../intern/atomic
- ../../../../intern/guardedalloc
- ../../blenlib
- ../../imbuf
- ..
-)
-
set(dna_header_include_file "${CMAKE_CURRENT_BINARY_DIR}/dna_includes_all.h")
set(dna_header_string_file "${CMAKE_CURRENT_BINARY_DIR}/dna_includes_as_strings.h")
@@ -57,6 +65,8 @@ add_cc_flags_custom_test(makesdna)
add_executable(makesdna ${SRC} ${SRC_DNA_INC})
setup_platform_linker_flags(makesdna)
+blender_target_include_dirs(makesdna ${INC})
+blender_target_include_dirs_sys(makesdna ${INC_SYS})
if(WIN32 AND NOT UNIX)
target_link_libraries(makesdna ${PTHREADS_LIBRARIES})
@@ -80,14 +90,6 @@ add_custom_command(
# -----------------------------------------------------------------------------
# Build bf_dna library
-set(INC
- ${CMAKE_CURRENT_BINARY_DIR}
-)
-
-set(INC_SYS
-
-)
-
set(SRC
dna_defaults.c
dna_genfile.c
@@ -101,9 +103,6 @@ set(SRC
dna_utils.h
)
-set(LIB
-)
-
set_source_files_properties(
${CMAKE_CURRENT_BINARY_DIR}/dna.c
${CMAKE_CURRENT_BINARY_DIR}/dna_type_offsets.h
@@ -117,7 +116,10 @@ blender_add_lib(bf_dna "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
# -----------------------------------------------------------------------------
# Build bf_dna_blenlib library
set(INC
-
+ ..
+ ../../blenlib
+ ../../../../intern/atomic
+ ../../../../intern/guardedalloc
)
set(INC_SYS
diff --git a/source/blender/makesdna/intern/dna_defaults.c b/source/blender/makesdna/intern/dna_defaults.c
index 197a863db72..309756ff2da 100644
--- a/source/blender/makesdna/intern/dna_defaults.c
+++ b/source/blender/makesdna/intern/dna_defaults.c
@@ -302,12 +302,14 @@ SDNA_DEFAULT_DECL_STRUCT(MultiplyGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(NoiseGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(OffsetGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(OpacityGpencilModifierData);
+SDNA_DEFAULT_DECL_STRUCT(OutlineGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(SimplifyGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(SmoothGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(SubdivGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(TextureGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(ThickGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(TimeGpencilModifierData);
+SDNA_DEFAULT_DECL_STRUCT(TimeGpencilModifierSegment);
SDNA_DEFAULT_DECL_STRUCT(TintGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(WeightProxGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(WeightAngleGpencilModifierData);
@@ -542,6 +544,7 @@ const void *DNA_default_table[SDNA_TYPE_MAX] = {
SDNA_DEFAULT_DECL(NoiseGpencilModifierData),
SDNA_DEFAULT_DECL(OffsetGpencilModifierData),
SDNA_DEFAULT_DECL(OpacityGpencilModifierData),
+ SDNA_DEFAULT_DECL(OutlineGpencilModifierData),
SDNA_DEFAULT_DECL(SimplifyGpencilModifierData),
SDNA_DEFAULT_DECL(SmoothGpencilModifierData),
SDNA_DEFAULT_DECL(SubdivGpencilModifierData),
@@ -549,6 +552,7 @@ const void *DNA_default_table[SDNA_TYPE_MAX] = {
SDNA_DEFAULT_DECL(ThickGpencilModifierData),
SDNA_DEFAULT_DECL(TimeGpencilModifierData),
SDNA_DEFAULT_DECL(TintGpencilModifierData),
+ SDNA_DEFAULT_DECL(TimeGpencilModifierSegment),
SDNA_DEFAULT_DECL(WeightAngleGpencilModifierData),
SDNA_DEFAULT_DECL(WeightProxGpencilModifierData),
SDNA_DEFAULT_DECL(LineartGpencilModifierData),
diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c
index 1b424756b0a..b75bf5383de 100644
--- a/source/blender/makesdna/intern/dna_genfile.c
+++ b/source/blender/makesdna/intern/dna_genfile.c
@@ -210,7 +210,7 @@ static int dna_struct_find_nr_ex_impl(
#endif
/* Regular args. */
const char *str,
- unsigned int *index_last)
+ uint *index_last)
{
if (*index_last < structs_len) {
const SDNA_Struct *struct_info = structs[*index_last];
@@ -242,7 +242,7 @@ static int dna_struct_find_nr_ex_impl(
return -1;
}
-int DNA_struct_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index_last)
+int DNA_struct_find_nr_ex(const SDNA *sdna, const char *str, uint *index_last)
{
return dna_struct_find_nr_ex_impl(
/* Expand SDNA. */
@@ -258,7 +258,7 @@ int DNA_struct_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index
index_last);
}
-int DNA_struct_alias_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index_last)
+int DNA_struct_alias_find_nr_ex(const SDNA *sdna, const char *str, uint *index_last)
{
#ifdef WITH_DNA_GHASH
BLI_assert(sdna->alias.structs_map != NULL);
@@ -279,13 +279,13 @@ int DNA_struct_alias_find_nr_ex(const SDNA *sdna, const char *str, unsigned int
int DNA_struct_find_nr(const SDNA *sdna, const char *str)
{
- unsigned int index_last_dummy = UINT_MAX;
+ uint index_last_dummy = UINT_MAX;
return DNA_struct_find_nr_ex(sdna, str, &index_last_dummy);
}
int DNA_struct_alias_find_nr(const SDNA *sdna, const char *str)
{
- unsigned int index_last_dummy = UINT_MAX;
+ uint index_last_dummy = UINT_MAX;
return DNA_struct_alias_find_nr_ex(sdna, str, &index_last_dummy);
}
@@ -497,7 +497,7 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error
sdna->pointer_size = sdna->types_size[struct_info->type] / 2;
- if (struct_info->members_len != 2 || (!ELEM(sdna->pointer_size, 4, 8))) {
+ if (struct_info->members_len != 2 || !ELEM(sdna->pointer_size, 4, 8)) {
*r_error_message = "ListBase struct error! Needs it to calculate pointer-size.";
/* Well, at least `sizeof(ListBase)` is error proof! (ton). */
return false;
@@ -741,7 +741,7 @@ static void cast_primitive_type(const eSDNA_Type old_type,
break;
}
case SDNA_TYPE_USHORT: {
- const ushort value = *((unsigned short *)old_data);
+ const ushort value = *((ushort *)old_data);
old_value_i = value;
old_value_f = (double)value;
break;
@@ -790,13 +790,13 @@ static void cast_primitive_type(const eSDNA_Type old_type,
*new_data = (char)old_value_i;
break;
case SDNA_TYPE_UCHAR:
- *((unsigned char *)new_data) = (unsigned char)old_value_i;
+ *((uchar *)new_data) = (uchar)old_value_i;
break;
case SDNA_TYPE_SHORT:
*((short *)new_data) = (short)old_value_i;
break;
case SDNA_TYPE_USHORT:
- *((unsigned short *)new_data) = (unsigned short)old_value_i;
+ *((ushort *)new_data) = (ushort)old_value_i;
break;
case SDNA_TYPE_INT:
*((int *)new_data) = (int)old_value_i;
diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h
index f25ff5fbbb8..afc907b7780 100644
--- a/source/blender/makesdna/intern/dna_rename_defs.h
+++ b/source/blender/makesdna/intern/dna_rename_defs.h
@@ -96,7 +96,14 @@ DNA_STRUCT_RENAME_ELEM(Object, dup_group, instance_collection)
DNA_STRUCT_RENAME_ELEM(Object, dupfacesca, instance_faces_scale)
DNA_STRUCT_RENAME_ELEM(Object, restrictflag, visibility_flag)
DNA_STRUCT_RENAME_ELEM(Object, size, scale)
+DNA_STRUCT_RENAME_ELEM(Object, obmat, object_to_world)
+DNA_STRUCT_RENAME_ELEM(Object, imat, world_to_object)
DNA_STRUCT_RENAME_ELEM(Object_Runtime, crazyspace_num_verts, crazyspace_verts_num)
+DNA_STRUCT_RENAME_ELEM(MEdge, bweight, bweight_legacy)
+DNA_STRUCT_RENAME_ELEM(MEdge, crease, crease_legacy)
+DNA_STRUCT_RENAME_ELEM(MPoly, mat_nr, mat_nr_legacy)
+DNA_STRUCT_RENAME_ELEM(MVert, bweight, bweight_legacy)
+DNA_STRUCT_RENAME_ELEM(MVert, flag, flag_legacy)
DNA_STRUCT_RENAME_ELEM(ParticleSettings, child_nbr, child_percent)
DNA_STRUCT_RENAME_ELEM(ParticleSettings, dup_group, instance_collection)
DNA_STRUCT_RENAME_ELEM(ParticleSettings, dup_ob, instance_object)
@@ -106,6 +113,7 @@ DNA_STRUCT_RENAME_ELEM(RenderData, bake_filter, bake_margin)
DNA_STRUCT_RENAME_ELEM(RigidBodyWorld, steps_per_second, substeps_per_frame)
DNA_STRUCT_RENAME_ELEM(SDefBind, numverts, verts_num)
DNA_STRUCT_RENAME_ELEM(SDefVert, numbinds, binds_num)
+DNA_STRUCT_RENAME_ELEM(SpaceImage, pixel_snap_mode, pixel_round_mode)
DNA_STRUCT_RENAME_ELEM(SpaceSeq, overlay_type, overlay_frame_type)
DNA_STRUCT_RENAME_ELEM(SurfaceDeformModifierData, num_mesh_verts, mesh_verts_num)
DNA_STRUCT_RENAME_ELEM(SurfaceDeformModifierData, numpoly, target_polys_num)
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index 7b893078b22..0728f69b449 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -431,7 +431,7 @@ static int add_name(const char *str)
*/
buf[i] = 0;
DEBUG_PRINTF(3, "Name before chomping: %s\n", buf);
- if ((strncmp(buf, "(*headdraw", 10) == 0) || (strncmp(buf, "(*windraw", 9) == 0)) {
+ if ((strncmp(buf, "(*headdraw", 10) == 0) || strncmp(buf, "(*windraw", 9) == 0) {
buf[i] = ')';
buf[i + 1] = '(';
buf[i + 2] = 'v';
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index ddc010f27a1..a7eacb03a63 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -159,10 +159,10 @@ PropertyScaleType RNA_property_ui_scale(PropertyRNA *prop);
int RNA_property_flag(PropertyRNA *prop);
int RNA_property_override_flag(PropertyRNA *prop);
/**
- * Get the tags set for \a prop as int bitfield.
+ * Get the tags set for \a prop as int bit-field.
* \note Doesn't perform any validity check on the set bits. #RNA_def_property_tags does this
* in debug builds (to avoid performance issues in non-debug builds), which should be
- * the only way to set tags. Hence, at this point we assume the tag bitfield to be valid.
+ * the only way to set tags. Hence, at this point we assume the tag bit-field to be valid.
*/
int RNA_property_tags(PropertyRNA *prop);
bool RNA_property_builtin(PropertyRNA *prop);
diff --git a/source/blender/makesrna/RNA_enum_items.h b/source/blender/makesrna/RNA_enum_items.h
index 61c5c1a6c72..1604bd97ed4 100644
--- a/source/blender/makesrna/RNA_enum_items.h
+++ b/source/blender/makesrna/RNA_enum_items.h
@@ -19,6 +19,7 @@ DEF_ENUM(rna_enum_object_empty_drawtype_items)
DEF_ENUM(rna_enum_object_gpencil_type_items)
DEF_ENUM(rna_enum_metaelem_type_items)
+DEF_ENUM(rna_enum_color_space_convert_default_items)
DEF_ENUM(rna_enum_proportional_falloff_items)
DEF_ENUM(rna_enum_proportional_falloff_curve_only_items)
DEF_ENUM(rna_enum_snap_source_items)
@@ -210,6 +211,7 @@ DEF_ENUM(rna_enum_attribute_type_items)
DEF_ENUM(rna_enum_color_attribute_type_items)
DEF_ENUM(rna_enum_attribute_type_with_auto_items)
DEF_ENUM(rna_enum_attribute_domain_items)
+DEF_ENUM(rna_enum_attribute_domain_only_mesh_items)
DEF_ENUM(rna_enum_attribute_curves_domain_items)
DEF_ENUM(rna_enum_color_attribute_domain_items)
DEF_ENUM(rna_enum_attribute_domain_without_corner_items)
@@ -229,6 +231,7 @@ DEF_ENUM(rna_enum_transform_orientation_items)
DEF_ENUM(rna_enum_velocity_unit_items)
DEF_ENUM(rna_enum_curves_types)
+DEF_ENUM(rna_enum_curve_normal_modes)
/* Not available to RNA pre-processing (`makesrna`).
* Defined in editors for example. */
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index 5346228050a..b9556a411cf 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -120,7 +120,7 @@ typedef enum PropertyScaleType {
/**
* \note Also update enums in bpy_props.c and rna_rna.c when adding items here.
- * Watch it: these values are written to files as part of node socket button subtypes!
+ * Watch it: these values are written to files as part of node socket button sub-types!
*/
typedef enum PropertySubType {
PROP_NONE = 0,
@@ -179,7 +179,7 @@ typedef enum PropertySubType {
/* Make sure enums are updated with these */
/* HIGHEST FLAG IN USE: 1 << 31
- * FREE FLAGS: 2, 9, 11, 13, 14, 15. */
+ * FREE FLAGS: 9, 11, 13, 14, 15. */
typedef enum PropertyFlag {
/**
* Editable means the property is editable in the user
@@ -299,6 +299,12 @@ typedef enum PropertyFlag {
* properties which denotes whether modifier panel is collapsed or not.
*/
PROP_NO_DEG_UPDATE = (1 << 30),
+
+ /**
+ * Filepaths that refer to output get a special treatment such
+ * as having the +/- operators available in the file browser.
+ **/
+ PROP_PATH_OUTPUT = (1 << 2),
} PropertyFlag;
/**
@@ -355,7 +361,7 @@ typedef enum ParameterFlag {
/**
* This allows for non-breaking API updates,
* when adding non-critical new parameter to a callback function.
- * This way, old py code defining funcs without that parameter would still work.
+ * This way, old Python code defining functions without that parameter would still work.
* WARNING: any parameter after the first PYFUNC_OPTIONAL one will be considered as optional!
* \note only for input parameters!
*/
@@ -719,7 +725,7 @@ typedef enum StructFlag {
STRUCT_CONTAINS_DATABLOCK_IDPROPERTIES = (1 << 8),
/** Added to type-map #BlenderRNA.structs_map */
STRUCT_PUBLIC_NAMESPACE = (1 << 9),
- /** All subtypes are added too. */
+ /** All sub-types are added too. */
STRUCT_PUBLIC_NAMESPACE_INHERIT = (1 << 10),
/**
* When the #PointerRNA.owner_id is NULL, this signifies the property should be accessed
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 7e6e3bcf90e..5c2bdc214d1 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -185,10 +185,33 @@ set(SRC
)
set(INC
- ../../../../intern/clog
-
- # Needed for defaults forward declarations.
+ .
+ ..
+ ../../blenfont
+ ../../blenkernel
+ ../../blenlib
../../blenloader
+ ../../blentranslation
+ ../../bmesh
+ ../../depsgraph
+ ../../draw
+ ../../gpu
+ ../../ikplugin
+ ../../imbuf
+ ../../makesdna
+ ../../modifiers
+ ../../nodes
+ ../../sequencer
+ ../../simulation
+ ../../windowmanager
+ ../../editors/include
+ ../../render
+ ../../../../intern/clog
+ ../../../../intern/cycles/blender
+ ../../../../intern/atomic
+ ../../../../intern/guardedalloc
+ ../../../../intern/memutil
+ ../../../../intern/mantaflow/extern
${CMAKE_BINARY_DIR}/source/blender/makesdna/intern
@@ -369,38 +392,12 @@ if(WITH_GMP)
endif()
# Build makesrna executable
-blender_include_dirs(
- .
- ..
- ../../blenfont
- ../../blenkernel
- ../../blenlib
- ../../blentranslation
- ../../bmesh
- ../../depsgraph
- ../../draw
- ../../gpu
- ../../ikplugin
- ../../imbuf
- ../../makesdna
- ../../modifiers
- ../../nodes/
- ../../sequencer
- ../../simulation
- ../../windowmanager
- ../../editors/include
- ../../render
- ../../../../intern/cycles/blender
- ../../../../intern/atomic
- ../../../../intern/guardedalloc
- ../../../../intern/memutil
- ../../../../intern/mantaflow/extern
-)
-
add_cc_flags_custom_test(makesrna)
add_executable(makesrna ${SRC} ${SRC_RNA_INC} ${SRC_DNA_INC})
setup_platform_linker_flags(makesrna)
+blender_target_include_dirs(makesrna ${INC})
+blender_target_include_dirs_sys(makesrna ${INC_SYS})
target_link_libraries(makesrna bf_dna)
target_link_libraries(makesrna bf_dna_blenlib)
@@ -409,8 +406,9 @@ if(WIN32 AND NOT UNIX)
target_link_libraries(makesrna ${PTHREADS_LIBRARIES})
endif()
-# Output rna_*_gen.c
-# note (linux only): with crashes try add this after COMMAND: valgrind --leak-check=full --track-origins=yes
+# Output `rna_*_gen.c`.
+# NOTE: (Linux only): with crashes try add this after COMMAND:
+# `valgrind --leak-check=full --track-origins=yes`
add_custom_command(
OUTPUT ${GENSRC}
COMMAND "$<TARGET_FILE:makesrna>" ${CMAKE_CURRENT_BINARY_DIR}/ ${CMAKE_CURRENT_BINARY_DIR}/../
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index a7b8488c371..3592ecd84c8 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -564,7 +564,7 @@ static int rna_enum_bitmask(PropertyRNA *prop)
static int rna_color_quantize(PropertyRNA *prop, PropertyDefRNA *dp)
{
- return ((prop->type == PROP_FLOAT) && (ELEM(prop->subtype, PROP_COLOR, PROP_COLOR_GAMMA)) &&
+ return ((prop->type == PROP_FLOAT) && ELEM(prop->subtype, PROP_COLOR, PROP_COLOR_GAMMA) &&
(IS_DNATYPE_FLOAT_COMPAT(dp->dnatype) == 0));
}
@@ -3904,7 +3904,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
}
case PROP_BOOLEAN: {
BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
- unsigned int i;
+ uint i;
if (prop->arraydimension && prop->totarraylength) {
fprintf(f,
@@ -3932,7 +3932,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
}
case PROP_INT: {
IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
- unsigned int i;
+ uint i;
if (prop->arraydimension && prop->totarraylength) {
fprintf(f,
@@ -3960,7 +3960,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
}
case PROP_FLOAT: {
FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
- unsigned int i;
+ uint i;
if (prop->arraydimension && prop->totarraylength) {
fprintf(f,
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index d31a312816a..b2c57846a08 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -1140,7 +1140,7 @@ static void rna_ImagePreview_size_set(PointerRNA *ptr, const int *values, enum e
BKE_previewimg_clear_single(prv_img, size);
if (values[0] && values[1]) {
- prv_img->rect[size] = MEM_callocN(values[0] * values[1] * sizeof(unsigned int), "prv_rect");
+ prv_img->rect[size] = MEM_callocN(values[0] * values[1] * sizeof(uint), "prv_rect");
prv_img->w[size] = values[0];
prv_img->h[size] = values[1];
@@ -1178,7 +1178,7 @@ static void rna_ImagePreview_pixels_get(PointerRNA *ptr, int *values, enum eIcon
BKE_previewimg_ensure(prv_img, size);
- memcpy(values, prv_img->rect[size], prv_img->w[size] * prv_img->h[size] * sizeof(unsigned int));
+ memcpy(values, prv_img->rect[size], prv_img->w[size] * prv_img->h[size] * sizeof(uint));
}
static void rna_ImagePreview_pixels_set(PointerRNA *ptr, const int *values, enum eIconSizes size)
@@ -1190,7 +1190,7 @@ static void rna_ImagePreview_pixels_set(PointerRNA *ptr, const int *values, enum
BLI_assert(prv_img == BKE_previewimg_id_ensure(id));
}
- memcpy(prv_img->rect[size], values, prv_img->w[size] * prv_img->h[size] * sizeof(unsigned int));
+ memcpy(prv_img->rect[size], values, prv_img->w[size] * prv_img->h[size] * sizeof(uint));
prv_img->flag[size] |= PRV_USER_EDITED;
}
@@ -1201,7 +1201,7 @@ static int rna_ImagePreview_pixels_float_get_length(const PointerRNA *ptr,
ID *id = ptr->owner_id;
PreviewImage *prv_img = (PreviewImage *)ptr->data;
- BLI_assert(sizeof(unsigned int) == 4);
+ BLI_assert(sizeof(uint) == 4);
if (id != NULL) {
BLI_assert(prv_img == BKE_previewimg_id_ensure(id));
@@ -1219,11 +1219,11 @@ static void rna_ImagePreview_pixels_float_get(PointerRNA *ptr, float *values, en
ID *id = ptr->owner_id;
PreviewImage *prv_img = (PreviewImage *)ptr->data;
- unsigned char *data = (unsigned char *)prv_img->rect[size];
+ uchar *data = (uchar *)prv_img->rect[size];
const size_t len = prv_img->w[size] * prv_img->h[size] * 4;
size_t i;
- BLI_assert(sizeof(unsigned int) == 4);
+ BLI_assert(sizeof(uint) == 4);
if (id != NULL) {
BLI_assert(prv_img == BKE_previewimg_id_ensure(id));
@@ -1243,11 +1243,11 @@ static void rna_ImagePreview_pixels_float_set(PointerRNA *ptr,
ID *id = ptr->owner_id;
PreviewImage *prv_img = (PreviewImage *)ptr->data;
- unsigned char *data = (unsigned char *)prv_img->rect[size];
+ uchar *data = (uchar *)prv_img->rect[size];
const size_t len = prv_img->w[size] * prv_img->h[size] * 4;
size_t i;
- BLI_assert(sizeof(unsigned int) == 4);
+ BLI_assert(sizeof(uint) == 4);
if (id != NULL) {
BLI_assert(prv_img == BKE_previewimg_id_ensure(id));
@@ -1392,6 +1392,19 @@ static void rna_Library_version_get(PointerRNA *ptr, int *value)
value[2] = lib->subversionfile;
}
+static void rna_Library_reload(Library *lib, bContext *C, ReportList *reports)
+{
+# ifdef WITH_PYTHON
+ BPy_BEGIN_ALLOW_THREADS;
+# endif
+
+ WM_lib_reload(lib, C, reports);
+
+# ifdef WITH_PYTHON
+ BPy_END_ALLOW_THREADS;
+# endif
+}
+
#else
static void rna_def_ID_properties(BlenderRNA *brna)
@@ -2239,7 +2252,7 @@ static void rna_def_library(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_flag(prop, PROP_THICK_WRAP);
- func = RNA_def_function(srna, "reload", "WM_lib_reload");
+ func = RNA_def_function(srna, "reload", "rna_Library_reload");
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func, "Reload this library and all its linked data-blocks");
}
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 835265b1986..2609c76f3b1 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -777,10 +777,10 @@ bool RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test)
return found;
}
-unsigned int RNA_struct_count_properties(StructRNA *srna)
+uint RNA_struct_count_properties(StructRNA *srna)
{
PointerRNA struct_ptr;
- unsigned int counter = 0;
+ uint counter = 0;
RNA_pointer_create(NULL, srna, NULL, &struct_ptr);
@@ -1135,7 +1135,7 @@ char RNA_property_array_item_char(PropertyRNA *prop, int index)
int RNA_property_array_item_index(PropertyRNA *prop, char name)
{
- /* Don't use custom property subtypes in RNA path lookup. */
+ /* Don't use custom property sub-types in RNA path lookup. */
PropertySubType subtype = rna_ensure_property(prop)->subtype;
/* get index based on string name/alias */
@@ -1744,9 +1744,9 @@ int RNA_enum_from_value(const EnumPropertyItem *item, const int value)
return -1;
}
-unsigned int RNA_enum_items_count(const EnumPropertyItem *item)
+uint RNA_enum_items_count(const EnumPropertyItem *item)
{
- unsigned int i = 0;
+ uint i = 0;
while (item->identifier) {
item++;
@@ -3620,7 +3620,7 @@ void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop)
BLI_assert(RNA_property_type(prop) == PROP_POINTER);
- if ((/*idprop=*/rna_idproperty_check(&prop, ptr))) {
+ if (/*idprop=*/rna_idproperty_check(&prop, ptr)) {
/* already exists */
}
else if (prop->flag & PROP_IDPROPERTY) {
@@ -5951,7 +5951,7 @@ void RNA_parameter_list_begin(ParameterList *parms, ParameterIterator *iter)
if (iter->valid) {
iter->size = rna_parameter_size(iter->parm);
- iter->data = (((char *)iter->parms->data)); /* +iter->offset, always 0 */
+ iter->data = ((char *)iter->parms->data); /* +iter->offset, always 0 */
}
}
diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c
index 808578b4746..0b8412367bf 100644
--- a/source/blender/makesrna/intern/rna_access_compare_override.c
+++ b/source/blender/makesrna/intern/rna_access_compare_override.c
@@ -27,6 +27,7 @@
#ifdef DEBUG_OVERRIDE_TIMEIT
# include "PIL_time_utildefines.h"
+# include <stdio.h>
#endif
#include "BKE_armature.h"
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index 4f07cb235fa..fa2ef98d3df 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -1207,6 +1207,7 @@ static void rna_api_animdata_nla_tracks(BlenderRNA *brna, PropertyRNA *cprop)
prop, "rna_NlaTrack_active_get", "rna_NlaTrack_active_set", NULL, NULL);
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Active Track", "Active NLA Track");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ACTION);
/* XXX: should (but doesn't) update the active track in the NLA window */
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_SELECTED, NULL);
}
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index f83ec0dc09b..a2386205013 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -38,6 +38,13 @@
# include "DEG_depsgraph.h"
# include "DEG_depsgraph_build.h"
+static void rna_Armature_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ ID *id = ptr->owner_id;
+
+ DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
+}
+
static void rna_Armature_update_data(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
ID *id = ptr->owner_id;
@@ -1122,7 +1129,7 @@ static void rna_def_bone_common(StructRNA *srna, int editbone)
RNA_define_lib_overridable(false);
}
-/* err... bones should not be directly edited (only editbones should be...) */
+/* Err... bones should not be directly edited (only edit-bones should be...). */
static void rna_def_bone(BlenderRNA *brna)
{
StructRNA *srna;
@@ -1365,6 +1372,7 @@ static void rna_def_armature_bones(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Active Bone", "Armature's active bone");
RNA_def_property_pointer_funcs(prop, NULL, "rna_Armature_act_bone_set", NULL, NULL);
+ RNA_def_property_update(prop, 0, "rna_Armature_update");
/* TODO: redraw. */
/* RNA_def_property_collection_active(prop, prop_act); */
@@ -1389,7 +1397,7 @@ static void rna_def_armature_edit_bones(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_pointer_sdna(prop, NULL, "act_edbone");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Active EditBone", "Armatures active edit bone");
- // RNA_def_property_update(prop, 0, "rna_Armature_act_editbone_update");
+ RNA_def_property_update(prop, 0, "rna_Armature_update");
RNA_def_property_pointer_funcs(prop, NULL, "rna_Armature_act_edit_bone_set", NULL, NULL);
/* TODO: redraw. */
diff --git a/source/blender/makesrna/intern/rna_asset.c b/source/blender/makesrna/intern/rna_asset.c
index a9f52e5c7d9..062f49b847b 100644
--- a/source/blender/makesrna/intern/rna_asset.c
+++ b/source/blender/makesrna/intern/rna_asset.c
@@ -476,6 +476,12 @@ static void rna_def_asset_handle(BlenderRNA *brna)
rna_def_asset_handle_api(srna);
}
+static void rna_def_asset_catalog_path(BlenderRNA *brna)
+{
+ StructRNA *srna = RNA_def_struct(brna, "AssetCatalogPath", NULL);
+ RNA_def_struct_ui_text(srna, "Catalog Path", "");
+}
+
static void rna_def_asset_library_reference(BlenderRNA *brna)
{
StructRNA *srna = RNA_def_struct(brna, "AssetLibraryReference", NULL);
@@ -502,6 +508,7 @@ void RNA_def_asset(BlenderRNA *brna)
rna_def_asset_data(brna);
rna_def_asset_library_reference(brna);
rna_def_asset_handle(brna);
+ rna_def_asset_catalog_path(brna);
RNA_define_animate_sdna(true);
}
diff --git a/source/blender/makesrna/intern/rna_attribute.c b/source/blender/makesrna/intern/rna_attribute.c
index 5e17f22ecf5..e1b6fb429a7 100644
--- a/source/blender/makesrna/intern/rna_attribute.c
+++ b/source/blender/makesrna/intern/rna_attribute.c
@@ -21,6 +21,8 @@
#include "BKE_attribute.h"
#include "BKE_customdata.h"
+#include "BLT_translation.h"
+
#include "WM_types.h"
const EnumPropertyItem rna_enum_attribute_type_items[] = {
@@ -81,6 +83,14 @@ const EnumPropertyItem rna_enum_attribute_domain_items[] = {
{0, NULL, 0, NULL, NULL},
};
+const EnumPropertyItem rna_enum_attribute_domain_only_mesh_items[] = {
+ {ATTR_DOMAIN_POINT, "POINT", 0, "Point", "Attribute on point"},
+ {ATTR_DOMAIN_EDGE, "EDGE", 0, "Edge", "Attribute on mesh edge"},
+ {ATTR_DOMAIN_FACE, "FACE", 0, "Face", "Attribute on mesh faces"},
+ {ATTR_DOMAIN_CORNER, "CORNER", 0, "Face Corner", "Attribute on mesh face corner"},
+ {0, NULL, 0, NULL, NULL},
+};
+
const EnumPropertyItem rna_enum_attribute_domain_without_corner_items[] = {
{ATTR_DOMAIN_POINT, "POINT", 0, "Point", "Attribute on point"},
{ATTR_DOMAIN_EDGE, "EDGE", 0, "Edge", "Attribute on mesh edge"},
@@ -194,7 +204,7 @@ const EnumPropertyItem *rna_enum_attribute_domain_itemf(ID *id,
int totitem = 0, a;
static EnumPropertyItem mesh_vertex_domain_item = {
- ATTR_DOMAIN_POINT, "POINT", 0, "Vertex", "Attribute per point/vertex"};
+ ATTR_DOMAIN_POINT, "POINT", 0, N_("Vertex"), N_("Attribute per point/vertex")};
for (a = 0; rna_enum_attribute_domain_items[a].identifier; a++) {
domain_item = &rna_enum_attribute_domain_items[a];
@@ -321,6 +331,36 @@ static void rna_ByteColorAttributeValue_color_set(PointerRNA *ptr, const float *
linearrgb_to_srgb_uchar4(&mlcol->r, values);
}
+static void rna_ByteColorAttributeValue_color_srgb_get(PointerRNA *ptr, float *values)
+{
+ MLoopCol *col = (MLoopCol *)ptr->data;
+ values[0] = col->r / 255.0f;
+ values[1] = col->g / 255.0f;
+ values[2] = col->b / 255.0f;
+ values[3] = col->a / 255.0f;
+}
+
+static void rna_ByteColorAttributeValue_color_srgb_set(PointerRNA *ptr, const float *values)
+{
+ MLoopCol *col = (MLoopCol *)ptr->data;
+ col->r = round_fl_to_uchar_clamp(values[0] * 255.0f);
+ col->g = round_fl_to_uchar_clamp(values[1] * 255.0f);
+ col->b = round_fl_to_uchar_clamp(values[2] * 255.0f);
+ col->a = round_fl_to_uchar_clamp(values[3] * 255.0f);
+}
+
+static void rna_FloatColorAttributeValue_color_srgb_get(PointerRNA *ptr, float *values)
+{
+ MPropCol *col = (MPropCol *)ptr->data;
+ linearrgb_to_srgb_v4(values, col->color);
+}
+
+static void rna_FloatColorAttributeValue_color_srgb_set(PointerRNA *ptr, const float *values)
+{
+ MPropCol *col = (MPropCol *)ptr->data;
+ srgb_to_linearrgb_v4(col->color, values);
+}
+
/* Int8 Attribute. */
static int rna_ByteIntAttributeValue_get(PointerRNA *ptr)
@@ -715,6 +755,16 @@ static void rna_def_attribute_float_color(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "color");
RNA_def_property_array(prop, 4);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
+
+ prop = RNA_def_property(srna, "color_srgb", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_ui_text(prop, "Color", "RGBA color in sRGB color space");
+ RNA_def_property_float_sdna(prop, NULL, "color");
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_float_funcs(prop,
+ "rna_FloatColorAttributeValue_color_srgb_get",
+ "rna_FloatColorAttributeValue_color_srgb_set",
+ NULL);
+ RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
}
static void rna_def_attribute_byte_color(BlenderRNA *brna)
@@ -756,6 +806,16 @@ static void rna_def_attribute_byte_color(BlenderRNA *brna)
NULL);
RNA_def_property_ui_text(prop, "Color", "RGBA color in scene linear color space");
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
+
+ prop = RNA_def_property(srna, "color_srgb", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_float_funcs(prop,
+ "rna_ByteColorAttributeValue_color_srgb_get",
+ "rna_ByteColorAttributeValue_color_srgb_set",
+ NULL);
+ RNA_def_property_ui_text(prop, "Color", "RGBA color in sRGB color space");
+ RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
}
static void rna_def_attribute_int(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index 789a8b381b6..ce51b52de39 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -92,6 +92,19 @@ static const EnumPropertyItem rna_enum_brush_texture_slot_map_texture_mode_items
#endif
/* clang-format off */
+/* Note: we don't actually turn these into a single enum bit-mask property,
+ * instead we construct individual boolean properties. */
+const EnumPropertyItem RNA_automasking_flags[] = {
+ {BRUSH_AUTOMASKING_TOPOLOGY, "use_automasking_topology", 0,"Topology", "Affect only vertices connected to the active vertex under the brush"},
+ {BRUSH_AUTOMASKING_FACE_SETS, "use_automasking_face_sets", 0,"Face Sets", "Affect only vertices that share Face Sets with the active vertex"},
+ {BRUSH_AUTOMASKING_BOUNDARY_EDGES, "use_automasking_boundary_edges", 0,"Mesh Boundary Auto-Masking", "Do not affect non manifold boundary edges"},
+ {BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS, "use_automasking_boundary_face_sets", 0,"Face Sets Boundary Automasking", "Do not affect vertices that belong to a Face Set boundary"},
+ {BRUSH_AUTOMASKING_CAVITY_NORMAL, "use_automasking_cavity", 0,"Cavity Mask", "Do not affect vertices on peaks, based on the surface curvature"},
+ {BRUSH_AUTOMASKING_CAVITY_INVERTED, "use_automasking_cavity_inverted", 0,"Inverted Cavity Mask", "Do not affect vertices within crevices, based on the surface curvature"},
+ {BRUSH_AUTOMASKING_CAVITY_USE_CURVE, "use_automasking_custom_cavity_curve", 0,"Custom Cavity Curve", "Use custom curve"},
+ {0, NULL, 0, NULL, NULL}
+};
+
const EnumPropertyItem rna_enum_brush_sculpt_tool_items[] = {
{SCULPT_TOOL_DRAW, "DRAW", ICON_BRUSH_SCULPT_DRAW, "Draw", ""},
{SCULPT_TOOL_DRAW_SHARP, "DRAW_SHARP", ICON_BRUSH_SCULPT_DRAW, "Draw Sharp", ""},
@@ -286,6 +299,11 @@ static EnumPropertyItem rna_enum_gpencil_fill_draw_modes_items[] = {
{GP_FILL_DMODE_CONTROL, "CONTROL", 0, "Edit Lines", "Use edit lines as fill boundary limits"},
{0, NULL, 0, NULL, NULL}};
+static EnumPropertyItem rna_enum_gpencil_fill_extend_modes_items[] = {
+ {GP_FILL_EMODE_EXTEND, "EXTEND", 0, "Extend", "Extend strokes in straight lines"},
+ {GP_FILL_EMODE_RADIUS, "RADIUS", 0, "Radius", "Connect endpoints that are close together"},
+ {0, NULL, 0, NULL, NULL}};
+
static EnumPropertyItem rna_enum_gpencil_fill_layers_modes_items[] = {
{GP_FILL_GPLMODE_VISIBLE, "VISIBLE", 0, "Visible", "Visible layers"},
{GP_FILL_GPLMODE_ACTIVE, "ACTIVE", 0, "Active", "Only active layer"},
@@ -972,7 +990,9 @@ static void rna_BrushGpencilSettings_default_eraser_update(Main *bmain,
static void rna_BrushGpencilSettings_use_material_pin_update(bContext *C, PointerRNA *ptr)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
Brush *brush = (Brush *)ptr->owner_id;
@@ -1077,6 +1097,32 @@ static const EnumPropertyItem *rna_BrushTextureSlot_map_mode_itemf(bContext *C,
# undef rna_enum_brush_texture_slot_map_sculpt_mode_items
}
+static void rna_Brush_automasking_invert_cavity_set(PointerRNA *ptr, bool val)
+{
+ Brush *brush = (Brush *)ptr->data;
+
+ if (val) {
+ brush->automasking_flags &= ~BRUSH_AUTOMASKING_CAVITY_NORMAL;
+ brush->automasking_flags |= BRUSH_AUTOMASKING_CAVITY_INVERTED;
+ }
+ else {
+ brush->automasking_flags &= ~BRUSH_AUTOMASKING_CAVITY_INVERTED;
+ }
+}
+
+static void rna_Brush_automasking_cavity_set(PointerRNA *ptr, bool val)
+{
+ Brush *brush = (Brush *)ptr->data;
+
+ if (val) {
+ brush->automasking_flags &= ~BRUSH_AUTOMASKING_CAVITY_INVERTED;
+ brush->automasking_flags |= BRUSH_AUTOMASKING_CAVITY_NORMAL;
+ }
+ else {
+ brush->automasking_flags &= ~BRUSH_AUTOMASKING_CAVITY_NORMAL;
+ }
+}
+
#else
static void rna_def_brush_texture_slot(BlenderRNA *brna)
@@ -1484,14 +1530,6 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
- /* fill leak size */
- prop = RNA_def_property(srna, "fill_leak", PROP_INT, PROP_PIXEL);
- RNA_def_property_int_sdna(prop, NULL, "fill_leak");
- RNA_def_property_range(prop, 0, 100);
- RNA_def_property_ui_text(prop, "Leak Size", "Size in pixels to consider the leak closed");
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
-
/* fill factor size */
prop = RNA_def_property(srna, "fill_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fill_factor");
@@ -1643,7 +1681,14 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_float_default(prop, 0.0f);
RNA_def_property_ui_text(
- prop, "Stroke Extension", "Strokes end extension for closing gaps, use zero to disable");
+ prop, "Closure Size", "Strokes end extension for closing gaps, use zero to disable");
+ RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
+
+ prop = RNA_def_property(srna, "fill_extend_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "fill_extend_mode");
+ RNA_def_property_enum_items(prop, rna_enum_gpencil_fill_extend_modes_items);
+ RNA_def_property_ui_text(
+ prop, "Closure Mode", "Types of stroke extensions used for closing gaps");
RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
/* Number of pixels to dilate fill area. Negative values contract the filled area. */
@@ -1874,26 +1919,6 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
- prop = RNA_def_property(srna, "use_automasking_stroke", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(
- prop, NULL, "sculpt_mode_flag", GP_SCULPT_FLAGMODE_AUTOMASK_STROKE);
- RNA_def_property_ui_text(prop, "Auto-Masking Strokes", "Mask strokes below brush cursor");
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
- prop = RNA_def_property(srna, "use_automasking_layer", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "sculpt_mode_flag", GP_SCULPT_FLAGMODE_AUTOMASK_LAYER);
- RNA_def_property_ui_text(prop, "Auto-Masking Layer", "Mask strokes using active layer");
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
- prop = RNA_def_property(srna, "use_automasking_material", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(
- prop, NULL, "sculpt_mode_flag", GP_SCULPT_FLAGMODE_AUTOMASK_MATERIAL);
- RNA_def_property_ui_text(prop, "Auto-Masking Material", "Mask strokes using active material");
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
/* Material */
prop = RNA_def_property(srna, "material", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Material");
@@ -1921,7 +1946,14 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_fill_extend", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_FILL_SHOW_EXTENDLINES);
RNA_def_property_boolean_default(prop, true);
- RNA_def_property_ui_text(prop, "Show Extend Lines", "Show help lines for stroke extension");
+ RNA_def_property_ui_text(prop, "Visual Aids", "Show help lines for stroke extension");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+
+ prop = RNA_def_property(srna, "use_collide_strokes", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_FILL_STROKE_COLLIDE);
+ RNA_def_property_boolean_default(prop, false);
+ RNA_def_property_ui_text(
+ prop, "Strokes Collision", "Check if extend lines collide with strokes");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
prop = RNA_def_property(srna, "show_fill", PROP_BOOLEAN, PROP_NONE);
@@ -3172,32 +3204,67 @@ static void rna_def_brush(BlenderRNA *brna)
"When locked keep using the plane origin of surface where stroke was initiated");
RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop = RNA_def_property(srna, "use_automasking_topology", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_TOPOLOGY);
- RNA_def_property_ui_text(prop,
- "Topology Auto-Masking",
- "Affect only vertices connected to the active vertex under the brush");
+ const EnumPropertyItem *entry = RNA_automasking_flags;
+ do {
+ prop = RNA_def_property(srna, entry->identifier, PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", entry->value);
+ RNA_def_property_ui_text(prop, entry->name, entry->description);
+
+ if (entry->value == BRUSH_AUTOMASKING_CAVITY_NORMAL) {
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_Brush_automasking_cavity_set");
+ }
+ else if (entry->value == BRUSH_AUTOMASKING_CAVITY_INVERTED) {
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_Brush_automasking_invert_cavity_set");
+ }
+
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+ } while ((++entry)->identifier);
+
+ prop = RNA_def_property(srna, "automasking_cavity_factor", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "automasking_cavity_factor");
+ RNA_def_property_ui_text(prop, "Cavity Factor", "The contrast of the cavity mask");
+ RNA_def_property_range(prop, 0.0f, 5.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop = RNA_def_property(srna, "use_automasking_face_sets", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_FACE_SETS);
- RNA_def_property_ui_text(prop,
- "Face Sets Auto-Masking",
- "Affect only vertices that share Face Sets with the active vertex");
+ prop = RNA_def_property(srna, "automasking_cavity_blur_steps", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "automasking_cavity_blur_steps");
+ RNA_def_property_int_default(prop, 0);
+ RNA_def_property_ui_text(prop, "Blur Steps", "The number of times the cavity mask is blurred");
+ RNA_def_property_range(prop, 0, 25);
+ RNA_def_property_ui_range(prop, 0, 10, 1, 1);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "automasking_cavity_curve", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "automasking_cavity_curve");
+ RNA_def_property_struct_type(prop, "CurveMapping");
+ RNA_def_property_ui_text(prop, "Cavity Curve", "Curve used for the sensitivity");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop = RNA_def_property(srna, "use_automasking_boundary_edges", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_BOUNDARY_EDGES);
+ prop = RNA_def_property(srna, "use_automasking_start_normal", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_BRUSH_NORMAL);
RNA_def_property_ui_text(
- prop, "Mesh Boundary Auto-Masking", "Do not affect non manifold boundary edges");
+ prop,
+ "Area Normal",
+ "Affect only vertices with a similar normal to where the stroke starts");
RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop = RNA_def_property(srna, "use_automasking_boundary_face_sets", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(
- prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS);
- RNA_def_property_ui_text(prop,
- "Face Sets Boundary Automasking",
- "Do not affect vertices that belong to a Face Set boundary");
+ prop = RNA_def_property(srna, "use_automasking_view_normal", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_VIEW_NORMAL);
+ RNA_def_property_ui_text(
+ prop, "View Normal", "Affect only vertices with a normal that faces the viewer");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "use_automasking_view_occlusion", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_VIEW_OCCLUSION);
+ RNA_def_property_ui_text(
+ prop,
+ "Occlusion",
+ "Only affect vertices that are not occluded by other faces. (Slower performance)");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "use_scene_spacing", PROP_ENUM, PROP_NONE);
@@ -3529,6 +3596,10 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Use Vertex", "Use this brush in grease pencil vertex color mode");
+ prop = RNA_def_property(srna, "use_paint_sculpt_curves", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "ob_mode", OB_MODE_SCULPT_CURVES);
+ RNA_def_property_ui_text(prop, "Use Sculpt", "Use this brush in sculpt curves mode");
+
/* texture */
prop = RNA_def_property(srna, "texture_slot", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "BrushTextureSlot");
@@ -3572,13 +3643,13 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Mask Texture Overlay Alpha", "");
RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop = RNA_def_property(srna, "cursor_color_add", PROP_FLOAT, PROP_COLOR);
+ prop = RNA_def_property(srna, "cursor_color_add", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "add_col");
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Add Color", "Color of cursor when adding");
RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop = RNA_def_property(srna, "cursor_color_subtract", PROP_FLOAT, PROP_COLOR);
+ prop = RNA_def_property(srna, "cursor_color_subtract", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "sub_col");
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Subtract Color", "Color of cursor when subtracting");
diff --git a/source/blender/makesrna/intern/rna_collection.c b/source/blender/makesrna/intern/rna_collection.c
index 84ddea368e7..833495dce7a 100644
--- a/source/blender/makesrna/intern/rna_collection.c
+++ b/source/blender/makesrna/intern/rna_collection.c
@@ -599,6 +599,11 @@ void RNA_def_collections(BlenderRNA *brna)
0,
"No Intersection",
"Include this collection but do not generate intersection lines"},
+ {COLLECTION_LRT_FORCE_INTERSECTION,
+ "FORCE_INTERSECTION",
+ 0,
+ "Force Intersection",
+ "Generate intersection lines even with objects that disabled intersection"},
{0, NULL, 0, NULL, NULL}};
prop = RNA_def_property(srna, "lineart_usage", PROP_ENUM, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index b68d87587e7..2ba82da09bb 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -15,11 +15,22 @@
#include "BKE_node_tree_update.h"
#include "RNA_define.h"
+#include "RNA_enum_types.h"
#include "rna_internal.h"
#include "WM_api.h"
#include "WM_types.h"
+const EnumPropertyItem rna_enum_color_space_convert_default_items[] = {
+ {0,
+ "NONE",
+ 0,
+ "None",
+ "Do not perform any color transform on load, treat colors as in scene linear space "
+ "already"},
+ {0, NULL, 0, NULL, NULL},
+};
+
#ifdef RNA_RUNTIME
# include "RNA_access.h"
@@ -1190,16 +1201,6 @@ static void rna_def_colormanage(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL},
};
- static const EnumPropertyItem color_space_items[] = {
- {0,
- "NONE",
- 0,
- "None",
- "Do not perform any color transform on load, treat colors as in scene linear space "
- "already"},
- {0, NULL, 0, NULL, NULL},
- };
-
/* ** Display Settings ** */
srna = RNA_def_struct(brna, "ColorManagedDisplaySettings", NULL);
RNA_def_struct_path_func(srna, "rna_ColorManagedDisplaySettings_path");
@@ -1279,7 +1280,7 @@ static void rna_def_colormanage(BlenderRNA *brna)
prop = RNA_def_property(srna, "name", PROP_ENUM, PROP_NONE);
RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_enum_items(prop, color_space_items);
+ RNA_def_property_enum_items(prop, rna_enum_color_space_convert_default_items);
RNA_def_property_enum_funcs(prop,
"rna_ColorManagedColorspaceSettings_colorspace_get",
"rna_ColorManagedColorspaceSettings_colorspace_set",
@@ -1309,7 +1310,7 @@ static void rna_def_colormanage(BlenderRNA *brna)
prop = RNA_def_property(srna, "name", PROP_ENUM, PROP_NONE);
RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
- RNA_def_property_enum_items(prop, color_space_items);
+ RNA_def_property_enum_items(prop, rna_enum_color_space_convert_default_items);
RNA_def_property_enum_funcs(prop,
"rna_ColorManagedColorspaceSettings_colorspace_get",
"rna_ColorManagedColorspaceSettings_colorspace_set",
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index 3a90d631c63..126300f0425 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -1947,22 +1947,23 @@ static void rna_def_curve_nurb(BlenderRNA *brna)
prop = RNA_def_property(srna, "order_u", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "orderu");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_range(prop, 2, 6);
- RNA_def_property_ui_text(
- prop,
- "Order U",
- "NURBS order in the U direction (for splines and surfaces, higher values "
- "let points influence a greater area)");
+ RNA_def_property_range(prop, 2, 64);
+ RNA_def_property_ui_range(prop, 2, 6, 1, -1);
+ RNA_def_property_ui_text(prop,
+ "Order U",
+ "NURBS order in the U direction. Higher values make each point "
+ "influence a greater area, but have worse performance");
RNA_def_property_update(prop, 0, "rna_Nurb_update_knot_u");
prop = RNA_def_property(srna, "order_v", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "orderv");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_range(prop, 2, 6);
+ RNA_def_property_range(prop, 2, 64);
+ RNA_def_property_ui_range(prop, 2, 6, 1, -1);
RNA_def_property_ui_text(prop,
"Order V",
- "NURBS order in the V direction (for surfaces only, higher values "
- "let points influence a greater area)");
+ "NURBS order in the V direction. Higher values make each point "
+ "influence a greater area, but have worse performance");
RNA_def_property_update(prop, 0, "rna_Nurb_update_knot_v");
prop = RNA_def_property(srna, "resolution_u", PROP_INT, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_curves.c b/source/blender/makesrna/intern/rna_curves.c
index 17290d1c582..a01a2bcb8cd 100644
--- a/source/blender/makesrna/intern/rna_curves.c
+++ b/source/blender/makesrna/intern/rna_curves.c
@@ -26,6 +26,12 @@ const EnumPropertyItem rna_enum_curves_types[] = {
{0, NULL, 0, NULL, NULL},
};
+const EnumPropertyItem rna_enum_curve_normal_modes[] = {
+ {NORMAL_MODE_MINIMUM_TWIST, "MINIMUM_TWIST", ICON_NONE, "Minimum Twist", ""},
+ {NORMAL_MODE_Z_UP, "Z_UP", ICON_NONE, "Z Up", ""},
+ {0, NULL, 0, NULL, NULL},
+};
+
#ifdef RNA_RUNTIME
# include "BLI_math_vector.h"
@@ -60,12 +66,23 @@ static void rna_Curves_curve_offset_data_begin(CollectionPropertyIterator *iter,
NULL);
}
+static float (*get_curves_positions(Curves *curves))[3]
+{
+ return (float(*)[3])CustomData_get_layer_named(
+ &curves->geometry.point_data, CD_PROP_FLOAT3, "position");
+}
+
+static const float (*get_curves_positions_const(const Curves *curves))[3]
+{
+ return (const float(*)[3])CustomData_get_layer_named(
+ &curves->geometry.point_data, CD_PROP_FLOAT3, "position");
+}
+
static int rna_CurvePoint_index_get_const(const PointerRNA *ptr)
{
const Curves *curves = rna_curves(ptr);
const float(*co)[3] = ptr->data;
- const float(*positions)[3] = (const float(*)[3])CustomData_get_layer_named(
- &curves->geometry.point_data, CD_PROP_FLOAT3, "position");
+ const float(*positions)[3] = get_curves_positions_const(curves);
return (int)(co - positions);
}
@@ -75,13 +92,27 @@ static int rna_Curves_position_data_length(PointerRNA *ptr)
return curves->geometry.point_num;
}
+int rna_Curves_position_data_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
+{
+ Curves *curves = rna_curves(ptr);
+ if (index < 0 || index >= curves->geometry.point_num) {
+ return false;
+ }
+ r_ptr->owner_id = &curves->id;
+ r_ptr->type = &RNA_FloatVectorAttributeValue;
+ r_ptr->data = &get_curves_positions(curves)[index];
+ return true;
+}
+
static void rna_Curves_position_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
- const Curves *curves = rna_curves(ptr);
- const float(*positions)[3] = (const float(*)[3])CustomData_get_layer_named(
- &curves->geometry.point_data, CD_PROP_FLOAT3, "position");
- rna_iterator_array_begin(
- iter, (void *)positions, sizeof(float[3]), curves->geometry.point_num, false, NULL);
+ Curves *curves = rna_curves(ptr);
+ rna_iterator_array_begin(iter,
+ get_curves_positions(curves),
+ sizeof(float[3]),
+ curves->geometry.point_num,
+ false,
+ NULL);
}
static int rna_CurvePoint_index_get(PointerRNA *ptr)
@@ -126,6 +157,18 @@ static char *rna_CurvePoint_path(const PointerRNA *ptr)
return BLI_sprintfN("points[%d]", rna_CurvePoint_index_get_const(ptr));
}
+int rna_Curves_points_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
+{
+ Curves *curves = rna_curves(ptr);
+ if (index < 0 || index >= curves->geometry.point_num) {
+ return false;
+ }
+ r_ptr->owner_id = &curves->id;
+ r_ptr->type = &RNA_CurvePoint;
+ r_ptr->data = &get_curves_positions(curves)[index];
+ return true;
+}
+
static int rna_CurveSlice_index_get_const(const PointerRNA *ptr)
{
Curves *curves = rna_curves(ptr);
@@ -280,7 +323,7 @@ static void rna_def_curves(BlenderRNA *brna)
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_Curves_position_data_length",
- NULL,
+ "rna_Curves_points_lookup_int",
NULL,
NULL);
RNA_def_property_ui_text(prop, "Points", "Control points of all curves");
@@ -295,7 +338,7 @@ static void rna_def_curves(BlenderRNA *brna)
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_Curves_position_data_length",
- NULL,
+ "rna_Curves_position_data_lookup_int",
NULL,
NULL);
RNA_def_property_struct_type(prop, "FloatVectorAttributeValue");
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index 44b642d0fcc..b7856794da2 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -147,7 +147,7 @@ PropertyDefRNA *rna_findlink(ListBase *listbase, const char *identifier)
for (link = listbase->first; link; link = link->next) {
PropertyRNA *prop = ((PropertyDefRNA *)link)->prop;
- if (prop && (STREQ(prop->identifier, identifier))) {
+ if (prop && STREQ(prop->identifier, identifier)) {
return (PropertyDefRNA *)link;
}
}
@@ -916,8 +916,8 @@ StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRN
DefRNA.laststruct = srna;
if (srnafrom) {
- /* copy from struct to derive stuff, a bit clumsy since we can't
- * use MEM_dupallocN, data structs may not be alloced but builtin */
+ /* Copy from struct to derive stuff, a bit clumsy since we can't
+ * use #MEM_dupallocN, data structs may not be allocated but builtin. */
memcpy(srna, srnafrom, sizeof(StructRNA));
srna->cont.prophash = NULL;
BLI_listbase_clear(&srna->cont.properties);
@@ -2753,7 +2753,7 @@ void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, co
return;
}
- if ((/* dp= */ rna_def_property_sdna(prop, structname, propname))) {
+ if (/* dp= */ rna_def_property_sdna(prop, structname, propname)) {
if (prop->arraydimension) {
prop->arraydimension = 0;
prop->totarraylength = 0;
diff --git a/source/blender/makesrna/intern/rna_depsgraph.c b/source/blender/makesrna/intern/rna_depsgraph.c
index ff107d0b833..9af76de2a2b 100644
--- a/source/blender/makesrna/intern/rna_depsgraph.c
+++ b/source/blender/makesrna/intern/rna_depsgraph.c
@@ -61,6 +61,14 @@ void **rna_DepsgraphIterator_instance(PointerRNA *ptr)
}
# endif
+/* Temporary hack for Cycles until it is changed to work with the C API directly. */
+DupliObject *rna_hack_DepsgraphObjectInstance_dupli_object_get(PointerRNA *ptr)
+{
+ RNA_DepsgraphIterator *di = ptr->data;
+ DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data;
+ return deg_iter->dupli_object_current;
+}
+
static PointerRNA rna_DepsgraphObjectInstance_object_get(PointerRNA *ptr)
{
RNA_DepsgraphIterator *di = ptr->data;
@@ -160,7 +168,7 @@ static void rna_DepsgraphObjectInstance_matrix_world_get(PointerRNA *ptr, float
/* We can return actual object's matrix here, no reason to return identity matrix
* when this is not actually an instance... */
Object *ob = (Object *)di->iter.current;
- copy_m4_m4((float(*)[4])mat, ob->obmat);
+ copy_m4_m4((float(*)[4])mat, ob->object_to_world);
}
}
@@ -300,10 +308,14 @@ static void rna_Depsgraph_objects_begin(CollectionPropertyIterator *iter, Pointe
{
iter->internal.custom = MEM_callocN(sizeof(BLI_Iterator), __func__);
DEGObjectIterData *data = MEM_callocN(sizeof(DEGObjectIterData), __func__);
+ DEGObjectIterSettings *deg_iter_settings = MEM_callocN(sizeof(DEGObjectIterSettings), __func__);
+ deg_iter_settings->depsgraph = (Depsgraph *)ptr->data;
+ deg_iter_settings->flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET;
- data->graph = (Depsgraph *)ptr->data;
- data->flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE |
- DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET;
+ data->settings = deg_iter_settings;
+ data->graph = deg_iter_settings->depsgraph;
+ data->flag = deg_iter_settings->flags;
((BLI_Iterator *)iter->internal.custom)->valid = true;
DEG_iterator_objects_begin(iter->internal.custom, data);
@@ -318,7 +330,9 @@ static void rna_Depsgraph_objects_next(CollectionPropertyIterator *iter)
static void rna_Depsgraph_objects_end(CollectionPropertyIterator *iter)
{
+ DEGObjectIterData *data = (DEGObjectIterData *)((BLI_Iterator *)iter->internal.custom)->data;
DEG_iterator_objects_end(iter->internal.custom);
+ MEM_freeN(data->settings);
MEM_freeN(((BLI_Iterator *)iter->internal.custom)->data);
MEM_freeN(iter->internal.custom);
}
@@ -349,11 +363,16 @@ static void rna_Depsgraph_object_instances_begin(CollectionPropertyIterator *ite
{
RNA_Depsgraph_Instances_Iterator *di_it = iter->internal.custom = MEM_callocN(sizeof(*di_it),
__func__);
+ DEGObjectIterSettings *deg_iter_settings = MEM_callocN(sizeof(DEGObjectIterSettings), __func__);
+ deg_iter_settings->depsgraph = (Depsgraph *)ptr->data;
+ deg_iter_settings->flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI;
DEGObjectIterData *data = &di_it->deg_data[0];
- data->graph = (Depsgraph *)ptr->data;
- data->flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
- DEG_ITER_OBJECT_FLAG_VISIBLE | DEG_ITER_OBJECT_FLAG_DUPLI;
+ data->settings = deg_iter_settings;
+ data->graph = deg_iter_settings->depsgraph;
+ data->flag = deg_iter_settings->flags;
di_it->iterators[0].iter.valid = true;
DEG_iterator_objects_begin(&di_it->iterators[0].iter, data);
@@ -392,6 +411,11 @@ static void rna_Depsgraph_object_instances_end(CollectionPropertyIterator *iter)
iter->internal.custom;
for (int i = 0; i < ARRAY_SIZE(di_it->iterators); i++) {
RNA_DepsgraphIterator *di = &di_it->iterators[i];
+ DEGObjectIterData *data = &di_it->deg_data[i];
+ if (i == 0) {
+ /* Is shared between both iterators. */
+ MEM_freeN(data->settings);
+ }
DEG_iterator_objects_end(&di->iter);
# ifdef WITH_PYTHON
@@ -740,14 +764,13 @@ static void rna_def_depsgraph(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "Scene");
RNA_def_property_pointer_funcs(prop, "rna_Depsgraph_scene_eval_get", NULL, NULL, NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Scene", "Original scene dependency graph is built for");
+ RNA_def_property_ui_text(prop, "Scene", "Scene at its evaluated state");
prop = RNA_def_property(srna, "view_layer_eval", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ViewLayer");
RNA_def_property_pointer_funcs(prop, "rna_Depsgraph_view_layer_eval_get", NULL, NULL, NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(
- prop, "View Layer", "Original view layer dependency graph is built for");
+ RNA_def_property_ui_text(prop, "View Layer", "View layer at its evaluated state");
/* Iterators. */
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index 727d329781d..9fe7dda0e20 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -2416,7 +2416,7 @@ static void rna_def_fcurve(BlenderRNA *brna)
prop, "Color Mode", "Method used to determine color of F-Curve in Graph Editor");
RNA_def_property_update(prop, NC_ANIMATION, NULL);
- prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
+ prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Color", "Color of the F-Curve in the Graph Editor");
diff --git a/source/blender/makesrna/intern/rna_fluid.c b/source/blender/makesrna/intern/rna_fluid.c
index 384ce8f04fb..bd601d0a736 100644
--- a/source/blender/makesrna/intern/rna_fluid.c
+++ b/source/blender/makesrna/intern/rna_fluid.c
@@ -20,6 +20,8 @@
#include "BKE_modifier.h"
#include "BKE_pointcache.h"
+#include "BLT_translation.h"
+
#include "DNA_fluid_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_force_types.h"
@@ -570,14 +572,14 @@ static const EnumPropertyItem *rna_Fluid_cachetype_mesh_itemf(bContext *UNUSED(C
tmp.value = FLUID_DOMAIN_FILE_BIN_OBJECT;
tmp.identifier = "BOBJECT";
- tmp.name = "Binary Object";
- tmp.description = "Binary object file format (.bobj.gz)";
+ tmp.name = N_("Binary Object");
+ tmp.description = N_("Binary object file format (.bobj.gz)");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = FLUID_DOMAIN_FILE_OBJECT;
tmp.identifier = "OBJECT";
- tmp.name = "Object";
- tmp.description = "Object file format (.obj)";
+ tmp.name = N_("Object");
+ tmp.description = N_("Object file format (.obj)");
RNA_enum_item_add(&item, &totitem, &tmp);
RNA_enum_item_end(&item, &totitem);
@@ -597,15 +599,15 @@ static const EnumPropertyItem *rna_Fluid_cachetype_volume_itemf(bContext *UNUSED
tmp.value = FLUID_DOMAIN_FILE_UNI;
tmp.identifier = "UNI";
- tmp.name = "Uni Cache";
- tmp.description = "Uni file format (.uni)";
+ tmp.name = N_("Uni Cache");
+ tmp.description = N_("Uni file format (.uni)");
RNA_enum_item_add(&item, &totitem, &tmp);
# ifdef WITH_OPENVDB
tmp.value = FLUID_DOMAIN_FILE_OPENVDB;
tmp.identifier = "OPENVDB";
- tmp.name = "OpenVDB";
- tmp.description = "OpenVDB file format (.vdb)";
+ tmp.name = N_("OpenVDB");
+ tmp.description = N_("OpenVDB file format (.vdb)");
RNA_enum_item_add(&item, &totitem, &tmp);
# endif
@@ -615,8 +617,8 @@ static const EnumPropertyItem *rna_Fluid_cachetype_volume_itemf(bContext *UNUSED
fds->cache_noise_format == FLUID_DOMAIN_FILE_RAW) {
tmp.value = FLUID_DOMAIN_FILE_RAW;
tmp.identifier = "RAW";
- tmp.name = "Raw Cache";
- tmp.description = "Raw file format (.raw)";
+ tmp.name = N_("Raw Cache");
+ tmp.description = N_("Raw file format (.raw)");
RNA_enum_item_add(&item, &totitem, &tmp);
}
@@ -637,8 +639,8 @@ static const EnumPropertyItem *rna_Fluid_cachetype_particle_itemf(bContext *UNUS
tmp.value = FLUID_DOMAIN_FILE_UNI;
tmp.identifier = "UNI";
- tmp.name = "Uni Cache";
- tmp.description = "Uni file format";
+ tmp.name = N_("Uni Cache");
+ tmp.description = N_("Uni file format");
RNA_enum_item_add(&item, &totitem, &tmp);
RNA_enum_item_end(&item, &totitem);
@@ -676,136 +678,136 @@ static const EnumPropertyItem *rna_Fluid_cobafield_itemf(bContext *UNUSED(C),
tmp.value = FLUID_DOMAIN_FIELD_FLAGS;
tmp.identifier = "FLAGS";
tmp.icon = 0;
- tmp.name = "Flags";
- tmp.description = "Flag grid of the fluid domain";
+ tmp.name = N_("Flags");
+ tmp.description = N_("Flag grid of the fluid domain");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = FLUID_DOMAIN_FIELD_PRESSURE;
tmp.identifier = "PRESSURE";
tmp.icon = 0;
- tmp.name = "Pressure";
- tmp.description = "Pressure field of the fluid domain";
+ tmp.name = N_("Pressure");
+ tmp.description = N_("Pressure field of the fluid domain");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = FLUID_DOMAIN_FIELD_VELOCITY_X;
tmp.identifier = "VELOCITY_X";
tmp.icon = 0;
- tmp.name = "X Velocity";
- tmp.description = "X component of the velocity field";
+ tmp.name = N_("X Velocity");
+ tmp.description = N_("X component of the velocity field");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = FLUID_DOMAIN_FIELD_VELOCITY_Y;
tmp.identifier = "VELOCITY_Y";
tmp.icon = 0;
- tmp.name = "Y Velocity";
- tmp.description = "Y component of the velocity field";
+ tmp.name = N_("Y Velocity");
+ tmp.description = N_("Y component of the velocity field");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = FLUID_DOMAIN_FIELD_VELOCITY_Z;
tmp.identifier = "VELOCITY_Z";
tmp.icon = 0;
- tmp.name = "Z Velocity";
- tmp.description = "Z component of the velocity field";
+ tmp.name = N_("Z Velocity");
+ tmp.description = N_("Z component of the velocity field");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = FLUID_DOMAIN_FIELD_FORCE_X;
tmp.identifier = "FORCE_X";
tmp.icon = 0;
- tmp.name = "X Force";
- tmp.description = "X component of the force field";
+ tmp.name = N_("X Force");
+ tmp.description = N_("X component of the force field");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = FLUID_DOMAIN_FIELD_FORCE_Y;
tmp.identifier = "FORCE_Y";
tmp.icon = 0;
- tmp.name = "Y Force";
- tmp.description = "Y component of the force field";
+ tmp.name = N_("Y Force");
+ tmp.description = N_("Y component of the force field");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = FLUID_DOMAIN_FIELD_FORCE_Z;
tmp.identifier = "FORCE_Z";
tmp.icon = 0;
- tmp.name = "Z Force";
- tmp.description = "Z component of the force field";
+ tmp.name = N_("Z Force");
+ tmp.description = N_("Z component of the force field");
RNA_enum_item_add(&item, &totitem, &tmp);
if (settings->type == FLUID_DOMAIN_TYPE_GAS) {
tmp.value = FLUID_DOMAIN_FIELD_COLOR_R;
tmp.identifier = "COLOR_R";
tmp.icon = 0;
- tmp.name = "Red";
- tmp.description = "Red component of the color field";
+ tmp.name = N_("Red");
+ tmp.description = N_("Red component of the color field");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = FLUID_DOMAIN_FIELD_COLOR_G;
tmp.identifier = "COLOR_G";
tmp.icon = 0;
- tmp.name = "Green";
- tmp.description = "Green component of the color field";
+ tmp.name = N_("Green");
+ tmp.description = N_("Green component of the color field");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = FLUID_DOMAIN_FIELD_COLOR_B;
tmp.identifier = "COLOR_B";
tmp.icon = 0;
- tmp.name = "Blue";
- tmp.description = "Blue component of the color field";
+ tmp.name = N_("Blue");
+ tmp.description = N_("Blue component of the color field");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = FLUID_DOMAIN_FIELD_DENSITY;
tmp.identifier = "DENSITY";
tmp.icon = 0;
- tmp.name = "Density";
- tmp.description = "Quantity of soot in the fluid";
+ tmp.name = N_("Density");
+ tmp.description = N_("Quantity of soot in the fluid");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = FLUID_DOMAIN_FIELD_FLAME;
tmp.identifier = "FLAME";
tmp.icon = 0;
- tmp.name = "Flame";
- tmp.description = "Flame field";
+ tmp.name = N_("Flame");
+ tmp.description = N_("Flame field");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = FLUID_DOMAIN_FIELD_FUEL;
tmp.identifier = "FUEL";
tmp.icon = 0;
- tmp.name = "Fuel";
- tmp.description = "Fuel field";
+ tmp.name = N_("Fuel");
+ tmp.description = N_("Fuel field");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = FLUID_DOMAIN_FIELD_HEAT;
tmp.identifier = "HEAT";
tmp.icon = 0;
- tmp.name = "Heat";
- tmp.description = "Temperature of the fluid";
+ tmp.name = N_("Heat");
+ tmp.description = N_("Temperature of the fluid");
RNA_enum_item_add(&item, &totitem, &tmp);
}
else if (settings->type == FLUID_DOMAIN_TYPE_LIQUID) {
tmp.value = FLUID_DOMAIN_FIELD_PHI;
tmp.identifier = "PHI";
tmp.icon = 0;
- tmp.name = "Fluid Levelset";
- tmp.description = "Levelset representation of the fluid";
+ tmp.name = N_("Fluid Level Set");
+ tmp.description = N_("Level set representation of the fluid");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = FLUID_DOMAIN_FIELD_PHI_IN;
tmp.identifier = "PHI_IN";
tmp.icon = 0;
- tmp.name = "Inflow Levelset";
- tmp.description = "Levelset representation of the inflow";
+ tmp.name = N_("Inflow Level Set");
+ tmp.description = N_("Level set representation of the inflow");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = FLUID_DOMAIN_FIELD_PHI_OUT;
tmp.identifier = "PHI_OUT";
tmp.icon = 0;
- tmp.name = "Outflow Levelset";
- tmp.description = "Levelset representation of the outflow";
+ tmp.name = N_("Outflow Level Set");
+ tmp.description = N_("Level set representation of the outflow");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = FLUID_DOMAIN_FIELD_PHI_OBSTACLE;
tmp.identifier = "PHI_OBSTACLE";
tmp.icon = 0;
- tmp.name = "Obstacle Levelset";
- tmp.description = "Levelset representation of the obstacles";
+ tmp.name = N_("Obstacle Level Set");
+ tmp.description = N_("Level set representation of the obstacles");
RNA_enum_item_add(&item, &totitem, &tmp);
}
@@ -829,23 +831,23 @@ static const EnumPropertyItem *rna_Fluid_data_depth_itemf(bContext *UNUSED(C),
tmp.value = VDB_PRECISION_FULL_FLOAT;
tmp.identifier = "32";
tmp.icon = 0;
- tmp.name = "Full";
- tmp.description = "Full float (Use 32 bit for all data)";
+ tmp.name = N_("Full");
+ tmp.description = N_("Full float (Use 32 bit for all data)");
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = VDB_PRECISION_HALF_FLOAT;
tmp.identifier = "16";
tmp.icon = 0;
- tmp.name = "Half";
- tmp.description = "Half float (Use 16 bit for all data)";
+ tmp.name = N_("Half");
+ tmp.description = N_("Half float (Use 16 bit for all data)");
RNA_enum_item_add(&item, &totitem, &tmp);
if (settings->type == FLUID_DOMAIN_TYPE_LIQUID) {
tmp.value = VDB_PRECISION_MINI_FLOAT;
tmp.identifier = "8";
tmp.icon = 0;
- tmp.name = "Mini";
- tmp.description = "Mini float (Use 8 bit where possible, otherwise use 16 bit)";
+ tmp.name = N_("Mini");
+ tmp.description = N_("Mini float (Use 8 bit where possible, otherwise use 16 bit)");
RNA_enum_item_add(&item, &totitem, &tmp);
}
@@ -1192,16 +1194,16 @@ static const EnumPropertyItem *rna_Fluid_flowsource_itemf(bContext *UNUSED(C),
tmp.value = FLUID_FLOW_SOURCE_MESH;
tmp.identifier = "MESH";
tmp.icon = ICON_META_CUBE;
- tmp.name = "Mesh";
- tmp.description = "Emit fluid from mesh surface or volume";
+ tmp.name = N_("Mesh");
+ tmp.description = N_("Emit fluid from mesh surface or volume");
RNA_enum_item_add(&item, &totitem, &tmp);
if (settings->type != FLUID_FLOW_TYPE_LIQUID) {
tmp.value = FLUID_FLOW_SOURCE_PARTICLES;
tmp.identifier = "PARTICLES";
tmp.icon = ICON_PARTICLES;
- tmp.name = "Particle System";
- tmp.description = "Emit smoke from particles";
+ tmp.name = N_("Particle System");
+ tmp.description = N_("Emit smoke from particles");
RNA_enum_item_add(&item, &totitem, &tmp);
}
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index cf0ff546d41..a55a1b0ffcd 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -334,13 +334,13 @@ static int rna_GPencilLayer_active_frame_editable(PointerRNA *ptr, const char **
static void set_parent(bGPDlayer *gpl, Object *par, const int type, const char *substr)
{
if (type == PAROBJECT) {
- invert_m4_m4(gpl->inverse, par->obmat);
+ invert_m4_m4(gpl->inverse, par->object_to_world);
gpl->parent = par;
gpl->partype |= PAROBJECT;
gpl->parsubstr[0] = 0;
}
else if (type == PARSKEL) {
- invert_m4_m4(gpl->inverse, par->obmat);
+ invert_m4_m4(gpl->inverse, par->object_to_world);
gpl->parent = par;
gpl->partype |= PARSKEL;
gpl->parsubstr[0] = 0;
@@ -349,7 +349,7 @@ static void set_parent(bGPDlayer *gpl, Object *par, const int type, const char *
bPoseChannel *pchan = BKE_pose_channel_find_name(par->pose, substr);
if (pchan) {
float tmp_mat[4][4];
- mul_m4_m4m4(tmp_mat, par->obmat, pchan->pose_mat);
+ mul_m4_m4m4(tmp_mat, par->object_to_world, pchan->pose_mat);
invert_m4_m4(gpl->inverse, tmp_mat);
gpl->parent = par;
@@ -357,7 +357,7 @@ static void set_parent(bGPDlayer *gpl, Object *par, const int type, const char *
BLI_strncpy(gpl->parsubstr, substr, sizeof(gpl->parsubstr));
}
else {
- invert_m4_m4(gpl->inverse, par->obmat);
+ invert_m4_m4(gpl->inverse, par->object_to_world);
gpl->parent = par;
gpl->partype |= PAROBJECT;
gpl->parsubstr[0] = 0;
diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c
index 2dfd9d46665..320ef169ae5 100644
--- a/source/blender/makesrna/intern/rna_gpencil_modifier.c
+++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c
@@ -9,11 +9,8 @@
#include <stdlib.h>
#include "DNA_armature_types.h"
-#include "DNA_brush_types.h"
-#include "DNA_cachefile_types.h"
#include "DNA_gpencil_modifier_types.h"
#include "DNA_gpencil_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
@@ -21,20 +18,13 @@
#include "MEM_guardedalloc.h"
-#include "BLI_math.h"
-#include "BLI_rand.h"
+#include "BLI_math_base.h"
+#include "BLI_math_rotation.h"
#include "BLI_string_utils.h"
#include "BLT_translation.h"
#include "BKE_animsys.h"
-#include "BKE_data_transfer.h"
-#include "BKE_dynamicpaint.h"
-#include "BKE_effect.h"
-#include "BKE_fluid.h" /* For BKE_fluid_modifier_free & BKE_fluid_modifier_create_type_data */
-#include "BKE_mesh_mapping.h"
-#include "BKE_mesh_remap.h"
-#include "BKE_multires.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -82,7 +72,7 @@ const EnumPropertyItem rna_enum_object_greasepencil_modifier_type_items[] = {
"Generate dot-dash styled strokes"},
{eGpencilModifierType_Envelope,
"GP_ENVELOPE",
- ICON_MOD_SKIN,
+ ICON_MOD_ENVELOPE,
"Envelope",
"Create an envelope shape"},
{eGpencilModifierType_Length,
@@ -105,6 +95,11 @@ const EnumPropertyItem rna_enum_object_greasepencil_modifier_type_items[] = {
ICON_GP_MULTIFRAME_EDITING,
"Multiple Strokes",
"Produce multiple strokes along one stroke"},
+ {eGpencilModifierType_Outline,
+ "GP_OUTLINE",
+ ICON_MOD_OUTLINE,
+ "Outline",
+ "Convert stroke to perimeter"},
{eGpencilModifierType_Simplify,
"GP_SIMPLIFY",
ICON_MOD_SIMPLIFY,
@@ -196,7 +191,19 @@ static const EnumPropertyItem rna_enum_time_mode_items[] = {
{GP_TIME_MODE_NORMAL, "NORMAL", 0, "Regular", "Apply offset in usual animation direction"},
{GP_TIME_MODE_REVERSE, "REVERSE", 0, "Reverse", "Apply offset in reverse animation direction"},
{GP_TIME_MODE_FIX, "FIX", 0, "Fixed Frame", "Keep frame and do not change with time"},
- {GP_TIME_MODE_PINGPONG, "PINGPONG", 0, "Ping Pong", "Loop back and forth"},
+ {GP_TIME_MODE_PINGPONG, "PINGPONG", 0, "Ping Pong", "Loop back and forth starting in reverse"},
+ {GP_TIME_MODE_CHAIN, "CHAIN", 0, "Chain", "List of chained animation segments"},
+ {0, NULL, 0, NULL, NULL},
+};
+
+static const EnumPropertyItem rna_enum_time_seg_mode_items[] = {
+ {GP_TIME_SEG_MODE_NORMAL, "NORMAL", 0, "Regular", "Apply offset in usual animation direction"},
+ {GP_TIME_SEG_MODE_REVERSE,
+ "REVERSE",
+ 0,
+ "Reverse",
+ "Apply offset in reverse animation direction"},
+ {GP_TIME_SEG_MODE_PINGPONG, "PINGPONG", 0, "Ping Pong", "Loop back and forth"},
{0, NULL, 0, NULL, NULL},
};
@@ -286,6 +293,8 @@ static StructRNA *rna_GpencilModifier_refine(struct PointerRNA *ptr)
return &RNA_BuildGpencilModifier;
case eGpencilModifierType_Opacity:
return &RNA_OpacityGpencilModifier;
+ case eGpencilModifierType_Outline:
+ return &RNA_OutlineGpencilModifier;
case eGpencilModifierType_Lattice:
return &RNA_LatticeGpencilModifier;
case eGpencilModifierType_Length:
@@ -668,6 +677,37 @@ static void rna_OpacityGpencilModifier_material_set(PointerRNA *ptr,
rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
}
+static void rna_OutlineGpencilModifier_object_set(PointerRNA *ptr,
+ PointerRNA value,
+ struct ReportList *UNUSED(reports))
+{
+ OutlineGpencilModifierData *omd = ptr->data;
+ Object *ob = (Object *)value.data;
+
+ omd->object = ob;
+ id_lib_extern((ID *)ob);
+}
+
+static void rna_OutlineGpencilModifier_material_set(PointerRNA *ptr,
+ PointerRNA value,
+ struct ReportList *reports)
+{
+ OutlineGpencilModifierData *omd = (OutlineGpencilModifierData *)ptr->data;
+ Material **ma_target = &omd->material;
+
+ rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
+static void rna_OutlineStrokeGpencilModifier_material_set(PointerRNA *ptr,
+ PointerRNA value,
+ struct ReportList *reports)
+{
+ OutlineGpencilModifierData *omd = (OutlineGpencilModifierData *)ptr->data;
+ Material **ma_target = &omd->outline_material;
+
+ rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
static void rna_LatticeGpencilModifier_material_set(PointerRNA *ptr,
PointerRNA value,
struct ReportList *reports)
@@ -753,7 +793,32 @@ static void rna_GpencilDash_segments_begin(CollectionPropertyIterator *iter, Poi
iter, dmd->segments, sizeof(DashGpencilModifierSegment), dmd->segments_len, false, NULL);
}
+static void rna_GpencilTime_segments_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ TimeGpencilModifierData *gpmd = (TimeGpencilModifierData *)ptr->data;
+ rna_iterator_array_begin(
+ iter, gpmd->segments, sizeof(TimeGpencilModifierSegment), gpmd->segments_len, false, NULL);
+}
+
+static char *rna_TimeGpencilModifierSegment_path(const PointerRNA *ptr)
+{
+ TimeGpencilModifierSegment *ds = (TimeGpencilModifierSegment *)ptr->data;
+
+ TimeGpencilModifierData *gpmd = (TimeGpencilModifierData *)ds->gpmd;
+
+ BLI_assert(gpmd != NULL);
+
+ char name_esc[sizeof(gpmd->modifier.name) * 2];
+ BLI_str_escape(name_esc, gpmd->modifier.name, sizeof(name_esc));
+
+ char ds_name_esc[sizeof(ds->name) * 2];
+ BLI_str_escape(ds_name_esc, ds->name, sizeof(ds_name_esc));
+
+ return BLI_sprintfN("grease_pencil_modifiers[\"%s\"].segments[\"%s\"]", name_esc, ds_name_esc);
+}
+
static char *rna_DashGpencilModifierSegment_path(const PointerRNA *ptr)
+
{
const DashGpencilModifierSegment *ds = (DashGpencilModifierSegment *)ptr->data;
@@ -781,6 +846,17 @@ static bool dash_segment_name_exists_fn(void *arg, const char *name)
return false;
}
+static bool time_segment_name_exists_fn(void *arg, const char *name)
+{
+ const TimeGpencilModifierData *gpmd = (const TimeGpencilModifierData *)arg;
+ for (int i = 0; i < gpmd->segments_len; i++) {
+ if (STREQ(gpmd->segments[i].name, name) && gpmd->segments[i].name != name) {
+ return true;
+ }
+ }
+ return false;
+}
+
static void rna_DashGpencilModifierSegment_name_set(PointerRNA *ptr, const char *value)
{
DashGpencilModifierSegment *ds = ptr->data;
@@ -804,6 +880,29 @@ static void rna_DashGpencilModifierSegment_name_set(PointerRNA *ptr, const char
BKE_animdata_fix_paths_rename_all(NULL, prefix, oldname, ds->name);
}
+static void rna_TimeGpencilModifierSegment_name_set(PointerRNA *ptr, const char *value)
+{
+ TimeGpencilModifierSegment *ds = ptr->data;
+
+ char oldname[sizeof(ds->name)];
+ BLI_strncpy(oldname, ds->name, sizeof(ds->name));
+
+ BLI_strncpy_utf8(ds->name, value, sizeof(ds->name));
+
+ BLI_assert(ds->gpmd != NULL);
+ BLI_uniquename_cb(
+ time_segment_name_exists_fn, ds->gpmd, "Segment", '.', ds->name, sizeof(ds->name));
+
+ char name_esc[sizeof(ds->gpmd->modifier.name) * 2];
+ BLI_str_escape(name_esc, ds->gpmd->modifier.name, sizeof(name_esc));
+
+ char prefix[36 + sizeof(name_esc) + 1];
+ SNPRINTF(prefix, "grease_pencil_modifiers[\"%s\"].segments", name_esc);
+
+ /* Fix all the animation data which may link to this. */
+ BKE_animdata_fix_paths_rename_all(NULL, prefix, oldname, ds->name);
+}
+
static int rna_ShrinkwrapGpencilModifier_face_cull_get(PointerRNA *ptr)
{
ShrinkwrapGpencilModifierData *swm = (ShrinkwrapGpencilModifierData *)ptr->data;
@@ -1680,6 +1779,38 @@ static void rna_def_modifier_gpenciltime(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ srna = RNA_def_struct(brna, "TimeGpencilModifierSegment", NULL);
+ RNA_def_struct_ui_text(srna, "Time Modifier Segment", "Configuration for a single dash segment");
+ RNA_def_struct_sdna(srna, "TimeGpencilModifierSegment");
+ RNA_def_struct_path_func(srna, "rna_TimeGpencilModifierSegment_path");
+
+ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Name", "Name of the dash segment");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_TimeGpencilModifierSegment_name_set");
+ RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER | NA_RENAME, NULL);
+ RNA_def_struct_name_property(srna, prop);
+
+ prop = RNA_def_property(srna, "seg_start", PROP_INT, PROP_NONE);
+ RNA_def_property_range(prop, 0, INT16_MAX);
+ RNA_def_property_ui_text(prop, "Frame Start", "First frame of the segment");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "seg_end", PROP_INT, PROP_NONE);
+ RNA_def_property_range(prop, 0, INT16_MAX);
+ RNA_def_property_ui_text(prop, "End", "Last frame of the segment");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "seg_repeat", PROP_INT, PROP_NONE);
+ RNA_def_property_range(prop, 1, INT16_MAX);
+ RNA_def_property_ui_text(prop, "Repeat", "Number of cycle repeats");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "seg_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "seg_mode");
+ RNA_def_property_enum_items(prop, rna_enum_time_seg_mode_items);
+ RNA_def_property_ui_text(prop, "Mode", "");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
srna = RNA_def_struct(brna, "TimeGpencilModifier", "GpencilModifier");
RNA_def_struct_ui_text(srna, "Time Offset Modifier", "Time offset modifier");
@@ -1688,6 +1819,24 @@ static void rna_def_modifier_gpenciltime(BlenderRNA *brna)
RNA_define_lib_overridable(true);
+ prop = RNA_def_property(srna, "segments", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_struct_type(prop, "TimeGpencilModifierSegment");
+ RNA_def_property_collection_sdna(prop, NULL, "segments", NULL);
+ RNA_def_property_collection_funcs(prop,
+ "rna_GpencilTime_segments_begin",
+ "rna_iterator_array_next",
+ "rna_iterator_array_end",
+ "rna_iterator_array_get",
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ RNA_def_property_ui_text(prop, "Segments", "");
+
+ prop = RNA_def_property(srna, "segment_active_index", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Active Dash Segment Index", "Active index in the segment list");
+
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, rna_enum_time_mode_items);
@@ -1972,6 +2121,107 @@ static void rna_def_modifier_gpencilopacity(BlenderRNA *brna)
RNA_define_lib_overridable(false);
}
+static void rna_def_modifier_gpenciloutline(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "OutlineGpencilModifier", "GpencilModifier");
+ RNA_def_struct_ui_text(srna, "Outline Modifier", "Outline of Strokes modifier from camera view");
+ RNA_def_struct_sdna(srna, "OutlineGpencilModifierData");
+ RNA_def_struct_ui_icon(srna, ICON_MOD_OUTLINE);
+
+ RNA_define_lib_overridable(true);
+
+ prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "layername");
+ RNA_def_property_ui_text(prop, "Layer", "Layer name");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "material", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_pointer_funcs(prop,
+ NULL,
+ "rna_OutlineGpencilModifier_material_set",
+ NULL,
+ "rna_GpencilModifier_material_poll");
+ RNA_def_property_ui_text(prop, "Material", "Material used for filtering effect");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "pass_index");
+ RNA_def_property_range(prop, 0, 100);
+ RNA_def_property_ui_text(prop, "Pass", "Pass index");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OUTLINE_INVERT_LAYER);
+ RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "invert_materials", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OUTLINE_INVERT_MATERIAL);
+ RNA_def_property_ui_text(prop, "Inverse Materials", "Inverse filter");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "invert_material_pass", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OUTLINE_INVERT_PASS);
+ RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "layer_pass", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "layer_pass");
+ RNA_def_property_range(prop, 0, 100);
+ RNA_def_property_ui_text(prop, "Pass", "Layer pass index");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "invert_layer_pass", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OUTLINE_INVERT_LAYERPASS);
+ RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "thickness", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "thickness");
+ RNA_def_property_range(prop, 1, 1000);
+ RNA_def_property_ui_text(prop, "Thickness", "Thickness of the perimeter stroke");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "sample_length", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "sample_length");
+ RNA_def_property_ui_range(prop, 0.0f, 100.0f, 0.1f, 2);
+ RNA_def_property_ui_text(prop, "Sample Length", "");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "subdivision", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "subdiv");
+ RNA_def_property_range(prop, 0, 10);
+ RNA_def_property_ui_text(prop, "Subdivisions", "Number of subdivisions");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "use_keep_shape", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OUTLINE_KEEP_SHAPE);
+ RNA_def_property_ui_text(prop, "Keep Shape", "Try to keep global shape");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "outline_material", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_pointer_funcs(prop,
+ NULL,
+ "rna_OutlineStrokeGpencilModifier_material_set",
+ NULL,
+ "rna_GpencilModifier_material_poll");
+ RNA_def_property_ui_text(prop, "Outline Material", "Material used for outline strokes");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Target Object", "Target object to define stroke start");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_OutlineGpencilModifier_object_set", NULL, NULL);
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_dependency_update");
+
+ RNA_define_lib_overridable(false);
+}
+
static void rna_def_modifier_gpencilarray(BlenderRNA *brna)
{
StructRNA *srna;
@@ -4170,7 +4420,7 @@ static void rna_def_modifier_gpencilenvelope(BlenderRNA *brna)
srna = RNA_def_struct(brna, "EnvelopeGpencilModifier", "GpencilModifier");
RNA_def_struct_ui_text(srna, "Envelope Modifier", "Envelope stroke effect modifier");
RNA_def_struct_sdna(srna, "EnvelopeGpencilModifierData");
- RNA_def_struct_ui_icon(srna, ICON_MOD_SKIN);
+ RNA_def_struct_ui_icon(srna, ICON_MOD_ENVELOPE);
RNA_define_lib_overridable(true);
@@ -4353,6 +4603,7 @@ void RNA_def_greasepencil_modifier(BlenderRNA *brna)
rna_def_modifier_gpencilarray(brna);
rna_def_modifier_gpencilbuild(brna);
rna_def_modifier_gpencilopacity(brna);
+ rna_def_modifier_gpenciloutline(brna);
rna_def_modifier_gpencillattice(brna);
rna_def_modifier_gpencilmirror(brna);
rna_def_modifier_gpencilhook(brna);
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index b7ab7689dd7..4e7c06bd37c 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -177,7 +177,7 @@ void rna_Image_generated_color_set(PointerRNA *ptr, const float values[4])
{
Image *ima = (Image *)(ptr->data);
ImageTile *base_tile = BKE_image_get_tile(ima, 0);
- for (unsigned int i = 0; i < 4; i++) {
+ for (uint i = 0; i < 4; i++) {
base_tile->gen_color[i] = CLAMPIS(values[i], 0.0f, FLT_MAX);
}
}
@@ -625,7 +625,7 @@ static void rna_Image_pixels_get(PointerRNA *ptr, float *values)
}
else {
for (i = 0; i < size; i++) {
- values[i] = ((unsigned char *)ibuf->rect)[i] * (1.0f / 255.0f);
+ values[i] = ((uchar *)ibuf->rect)[i] * (1.0f / 255.0f);
}
}
}
@@ -650,7 +650,7 @@ static void rna_Image_pixels_set(PointerRNA *ptr, const float *values)
}
else {
for (i = 0; i < size; i++) {
- ((unsigned char *)ibuf->rect)[i] = unit_float_to_uchar_clamp(values[i]);
+ ((uchar *)ibuf->rect)[i] = unit_float_to_uchar_clamp(values[i]);
}
}
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 3d5c1810558..ea829e5cd86 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -24,7 +24,7 @@ struct AssetLibraryReference;
struct FreestyleSettings;
struct ID;
struct IDOverrideLibrary;
-struct IDOverrideLibraryPropertyOperation;
+struct IDOverrideLibraryenOperation;
struct IDProperty;
struct Main;
struct Object;
@@ -322,7 +322,9 @@ void rna_object_vcollayer_name_set(struct PointerRNA *ptr,
PointerRNA rna_object_shapekey_index_get(struct ID *id, int value);
int rna_object_shapekey_index_set(struct ID *id, PointerRNA value, int current);
-void rna_def_object_type_visibility_flags_common(StructRNA *srna, int noteflag);
+void rna_def_object_type_visibility_flags_common(StructRNA *srna,
+ int noteflag,
+ const char *update_func);
int rna_object_type_visibility_icon_get_common(int object_type_exclude_viewport,
const int *object_type_exclude_select);
diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c
index 6ab9d3a46ad..b08d4b60fcc 100644
--- a/source/blender/makesrna/intern/rna_layer.c
+++ b/source/blender/makesrna/intern/rna_layer.c
@@ -50,8 +50,10 @@
static PointerRNA rna_ViewLayer_active_layer_collection_get(PointerRNA *ptr)
{
+ const Scene *scene = (const Scene *)ptr->owner_id;
ViewLayer *view_layer = (ViewLayer *)ptr->data;
- LayerCollection *lc = view_layer->active_collection;
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LayerCollection *lc = BKE_view_layer_active_collection_get(view_layer);
return rna_pointer_inherit_refine(ptr, &RNA_LayerCollection, lc);
}
@@ -59,8 +61,10 @@ static void rna_ViewLayer_active_layer_collection_set(PointerRNA *ptr,
PointerRNA value,
struct ReportList *UNUSED(reports))
{
+ const Scene *scene = (const Scene *)ptr->owner_id;
ViewLayer *view_layer = (ViewLayer *)ptr->data;
LayerCollection *lc = (LayerCollection *)value.data;
+ BKE_view_layer_synced_ensure(scene, view_layer);
const int index = BKE_layer_collection_findindex(view_layer, lc);
if (index != -1) {
BKE_layer_collection_activate(view_layer, lc);
@@ -69,18 +73,22 @@ static void rna_ViewLayer_active_layer_collection_set(PointerRNA *ptr,
static PointerRNA rna_LayerObjects_active_object_get(PointerRNA *ptr)
{
+ const Scene *scene = (Scene *)ptr->owner_id;
ViewLayer *view_layer = (ViewLayer *)ptr->data;
+ BKE_view_layer_synced_ensure(scene, view_layer);
return rna_pointer_inherit_refine(
- ptr, &RNA_Object, view_layer->basact ? view_layer->basact->object : NULL);
+ ptr, &RNA_Object, BKE_view_layer_active_object_get(view_layer));
}
static void rna_LayerObjects_active_object_set(PointerRNA *ptr,
PointerRNA value,
struct ReportList *reports)
{
+ const Scene *scene = (Scene *)ptr->owner_id;
ViewLayer *view_layer = (ViewLayer *)ptr->data;
if (value.data) {
Object *ob = value.data;
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *basact_test = BKE_view_layer_base_find(view_layer, ob);
if (basact_test != NULL) {
view_layer->basact = basact_test;
@@ -197,7 +205,7 @@ static void rna_LayerObjects_selected_begin(CollectionPropertyIterator *iter, Po
{
ViewLayer *view_layer = (ViewLayer *)ptr->data;
rna_iterator_listbase_begin(
- iter, &view_layer->object_bases, rna_ViewLayer_objects_selected_skip);
+ iter, BKE_view_layer_object_bases_get(view_layer), rna_ViewLayer_objects_selected_skip);
}
static void rna_ViewLayer_update_tagged(ID *id_ptr,
@@ -245,7 +253,7 @@ static void rna_ObjectBase_hide_viewport_update(bContext *C, PointerRNA *UNUSED(
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- BKE_layer_collection_sync(scene, view_layer);
+ BKE_view_layer_need_resync_tag(view_layer);
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
@@ -309,13 +317,13 @@ static void rna_LayerCollection_exclude_update(Main *bmain, Scene *UNUSED(scene)
const bool exclude = (lc->flag & LAYER_COLLECTION_EXCLUDE) != 0;
BKE_layer_collection_set_flag(lc, LAYER_COLLECTION_EXCLUDE, exclude);
- BKE_layer_collection_sync(scene, view_layer);
+ BKE_view_layer_need_resync_tag(view_layer);
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
if (!exclude) {
/* We need to update animation of objects added back to the scene through enabling this view
* layer. */
- FOREACH_OBJECT_BEGIN (view_layer, ob) {
+ FOREACH_OBJECT_BEGIN (scene, view_layer, ob) {
DEG_id_tag_update(&ob->id, ID_RECALC_ANIMATION);
}
FOREACH_OBJECT_END;
@@ -334,7 +342,7 @@ static void rna_LayerCollection_update(Main *UNUSED(bmain), Scene *UNUSED(scene)
LayerCollection *lc = (LayerCollection *)ptr->data;
ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, lc);
- BKE_layer_collection_sync(scene, view_layer);
+ BKE_view_layer_need_resync_tag(view_layer);
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
@@ -347,9 +355,63 @@ static bool rna_LayerCollection_has_objects(LayerCollection *lc)
return (lc->runtime_flag & LAYER_COLLECTION_HAS_OBJECTS) != 0;
}
-static bool rna_LayerCollection_has_selected_objects(LayerCollection *lc, ViewLayer *view_layer)
+static bool rna_LayerCollection_has_selected_objects(LayerCollection *lc,
+ Main *bmain,
+ ViewLayer *view_layer)
{
- return BKE_layer_collection_has_selected_objects(view_layer, lc);
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
+ LISTBASE_FOREACH (ViewLayer *, scene_view_layer, &scene->view_layers) {
+ if (scene_view_layer == view_layer) {
+ return BKE_layer_collection_has_selected_objects(scene, view_layer, lc);
+ }
+ }
+ }
+ return false;
+}
+
+void rna_LayerCollection_children_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ Scene *scene = (Scene *)ptr->owner_id;
+ LayerCollection *lc = (LayerCollection *)ptr->data;
+ ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, lc);
+ BKE_view_layer_synced_ensure(scene, view_layer);
+
+ rna_iterator_listbase_begin(iter, &lc->layer_collections, NULL);
+}
+
+static bool rna_LayerCollection_children_lookupint(struct PointerRNA *ptr,
+ int key,
+ struct PointerRNA *r_ptr)
+{
+ Scene *scene = (Scene *)ptr->owner_id;
+ LayerCollection *lc = (LayerCollection *)ptr->data;
+ ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, lc);
+ BKE_view_layer_synced_ensure(scene, view_layer);
+
+ LayerCollection *child = BLI_findlink(&lc->layer_collections, key);
+ if (!child) {
+ return false;
+ }
+ RNA_pointer_create(ptr->owner_id, &RNA_LayerCollection, child, r_ptr);
+ return true;
+}
+
+static bool rna_LayerCollection_children_lookupstring(struct PointerRNA *ptr,
+ const char *key,
+ struct PointerRNA *r_ptr)
+{
+ Scene *scene = (Scene *)ptr->owner_id;
+ LayerCollection *lc = (LayerCollection *)ptr->data;
+ ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, lc);
+ BKE_view_layer_synced_ensure(scene, view_layer);
+
+ LISTBASE_FOREACH (LayerCollection *, child, &lc->layer_collections) {
+ if (STREQ(child->collection->id.name + 2, key)) {
+ RNA_pointer_create(ptr->owner_id, &RNA_LayerCollection, child, r_ptr);
+ return true;
+ }
+ }
+ return false;
}
#else
@@ -382,6 +444,15 @@ static void rna_def_layer_collection(BlenderRNA *brna)
RNA_def_property_collection_sdna(prop, NULL, "layer_collections", NULL);
RNA_def_property_struct_type(prop, "LayerCollection");
RNA_def_property_ui_text(prop, "Children", "Child layer collections");
+ RNA_def_property_collection_funcs(prop,
+ "rna_LayerCollection_children_begin",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "rna_LayerCollection_children_lookupint",
+ "rna_LayerCollection_children_lookupstring",
+ NULL);
/* Restriction flags. */
prop = RNA_def_property(srna, "exclude", PROP_BOOLEAN, PROP_NONE);
@@ -442,6 +513,7 @@ static void rna_def_layer_collection(BlenderRNA *brna)
func = RNA_def_function(
srna, "has_selected_objects", "rna_LayerCollection_has_selected_objects");
+ RNA_def_function_flag(func, FUNC_USE_MAIN);
RNA_def_function_ui_description(func, "");
prop = RNA_def_pointer(
func, "view_layer", "ViewLayer", "", "View layer the layer collection belongs to");
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index 1f21fa3fab9..35678f2f1dd 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -629,6 +629,7 @@ static bAction *rna_Main_actions_new(Main *bmain, const char *name)
bAction *act = BKE_action_add(bmain, safe_name);
id_fake_user_clear(&act->id);
+ id_us_min(&act->id);
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
@@ -701,6 +702,7 @@ static Mask *rna_Main_mask_new(Main *bmain, const char *name)
rna_idname_validate(name, safe_name);
Mask *mask = BKE_mask_new(bmain, safe_name);
+ id_us_min(&mask->id);
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 252d2e657b5..1616684cb6a 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -142,7 +142,6 @@ static void rna_Material_texpaint_begin(CollectionPropertyIterator *iter, Pointe
static void rna_Material_active_paint_texture_index_update(bContext *C, PointerRNA *ptr)
{
Main *bmain = CTX_data_main(C);
- bScreen *screen;
Material *ma = (Material *)ptr->owner_id;
if (ma->use_nodes && ma->nodetree) {
@@ -157,25 +156,7 @@ static void rna_Material_active_paint_texture_index_update(bContext *C, PointerR
TexPaintSlot *slot = &ma->texpaintslot[ma->paint_active_slot];
Image *image = slot->ima;
if (image) {
- for (screen = bmain->screens.first; screen; screen = screen->id.next) {
- wmWindow *win = ED_screen_window_find(screen, bmain->wm.first);
- if (win == NULL) {
- continue;
- }
-
- ScrArea *area;
- for (area = screen->areabase.first; area; area = area->next) {
- SpaceLink *sl;
- for (sl = area->spacedata.first; sl; sl = sl->next) {
- if (sl->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = (SpaceImage *)sl;
- if (!sima->pin) {
- ED_space_image_set(bmain, sima, image, true);
- }
- }
- }
- }
- }
+ ED_space_image_sync(bmain, image, false);
}
/* For compatibility reasons with vertex paint we activate the color attribute. */
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 28ceb0d1d9d..f13132b5b7c 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -108,7 +108,7 @@ static CustomData *rna_mesh_vdata(const PointerRNA *ptr)
Mesh *me = rna_mesh(ptr);
return rna_mesh_vdata_helper(me);
}
-static CustomData *rna_mesh_edata(PointerRNA *ptr)
+static CustomData *rna_mesh_edata(const PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
return rna_mesh_edata_helper(me);
@@ -239,6 +239,16 @@ static bool rna_Mesh_has_vertex_bevel_weight_get(PointerRNA *ptr)
return CustomData_has_layer(rna_mesh_vdata(ptr), CD_BWEIGHT);
}
+static bool rna_Mesh_has_edge_crease_get(PointerRNA *ptr)
+{
+ return CustomData_has_layer(rna_mesh_edata(ptr), CD_CREASE);
+}
+
+static bool rna_Mesh_has_vertex_crease_get(PointerRNA *ptr)
+{
+ return CustomData_has_layer(rna_mesh_vdata(ptr), CD_CREASE);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -396,12 +406,39 @@ static int rna_MeshLoopTriangle_index_get(PointerRNA *ptr)
{
const Mesh *mesh = rna_mesh(ptr);
const MLoopTri *ltri = (MLoopTri *)ptr->data;
- const int index = (int)(ltri - mesh->runtime.looptris.array);
+ const int index = (int)(ltri - BKE_mesh_runtime_looptri_ensure(mesh));
BLI_assert(index >= 0);
- BLI_assert(index < mesh->runtime.looptris.len);
+ BLI_assert(index < BKE_mesh_runtime_looptri_len(mesh));
return index;
}
+static void rna_Mesh_loop_triangles_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ const Mesh *mesh = rna_mesh(ptr);
+ const MLoopTri *looptris = BKE_mesh_runtime_looptri_ensure(mesh);
+ rna_iterator_array_begin(
+ iter, (void *)looptris, sizeof(MLoopTri), BKE_mesh_runtime_looptri_len(mesh), false, NULL);
+}
+
+static int rna_Mesh_loop_triangles_length(PointerRNA *ptr)
+{
+ const Mesh *mesh = rna_mesh(ptr);
+ return BKE_mesh_runtime_looptri_len(mesh);
+}
+
+int rna_Mesh_loop_triangles_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
+{
+ const Mesh *mesh = rna_mesh(ptr);
+ if (index < 0 || index >= BKE_mesh_runtime_looptri_len(mesh)) {
+ return false;
+ }
+ /* Casting away const is okay because this RNA type doesn't allow changing the value. */
+ r_ptr->owner_id = (ID *)&mesh->id;
+ r_ptr->type = &RNA_MeshLoopTriangle;
+ r_ptr->data = (void *)&BKE_mesh_runtime_looptri_ensure(mesh)[index];
+ return true;
+}
+
static void rna_MeshVertex_normal_get(PointerRNA *ptr, float *value)
{
Mesh *mesh = rna_mesh(ptr);
@@ -436,6 +473,32 @@ static void rna_MeshVertex_hide_set(PointerRNA *ptr, bool value)
hide_vert[index] = value;
}
+static bool rna_MeshVertex_select_get(PointerRNA *ptr)
+{
+ const Mesh *mesh = rna_mesh(ptr);
+ const bool *select_vert = (const bool *)CustomData_get_layer_named(
+ &mesh->vdata, CD_PROP_BOOL, ".select_vert");
+ const int index = rna_MeshVertex_index_get(ptr);
+ return select_vert == NULL ? false : select_vert[index];
+}
+
+static void rna_MeshVertex_select_set(PointerRNA *ptr, bool value)
+{
+ Mesh *mesh = rna_mesh(ptr);
+ bool *select_vert = (bool *)CustomData_duplicate_referenced_layer_named(
+ &mesh->vdata, CD_PROP_BOOL, ".select_vert", mesh->totvert);
+ if (!select_vert) {
+ if (!value) {
+ /* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */
+ return;
+ }
+ select_vert = (bool *)CustomData_add_layer_named(
+ &mesh->vdata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, mesh->totvert, ".select_vert");
+ }
+ const int index = rna_MeshVertex_index_get(ptr);
+ select_vert[index] = value;
+}
+
static float rna_MeshVertex_bevel_weight_get(PointerRNA *ptr)
{
const Mesh *mesh = rna_mesh(ptr);
@@ -472,14 +535,19 @@ static void rna_MEdge_bevel_weight_set(PointerRNA *ptr, float value)
static float rna_MEdge_crease_get(PointerRNA *ptr)
{
- MEdge *medge = (MEdge *)ptr->data;
- return medge->crease / 255.0f;
+ const Mesh *mesh = rna_mesh(ptr);
+ const int index = rna_MeshEdge_index_get(ptr);
+ const float *values = (const float *)CustomData_get_layer(&mesh->edata, CD_CREASE);
+ return values == NULL ? 0.0f : values[index];
}
static void rna_MEdge_crease_set(PointerRNA *ptr, float value)
{
- MEdge *medge = (MEdge *)ptr->data;
- medge->crease = round_fl_to_uchar_clamp(value * 255.0f);
+ Mesh *mesh = rna_mesh(ptr);
+ const int index = rna_MeshEdge_index_get(ptr);
+ float *values = (float *)CustomData_add_layer(
+ &mesh->edata, CD_CREASE, CD_SET_DEFAULT, NULL, mesh->totedge);
+ values[index] = clamp_f(value, 0.0f, 1.0f);
}
static void rna_MeshLoop_normal_get(PointerRNA *ptr, float *values)
@@ -581,6 +649,32 @@ static void rna_MeshPolygon_hide_set(PointerRNA *ptr, bool value)
hide_poly[index] = value;
}
+static bool rna_MeshPolygon_select_get(PointerRNA *ptr)
+{
+ const Mesh *mesh = rna_mesh(ptr);
+ const bool *select_poly = (const bool *)CustomData_get_layer_named(
+ &mesh->pdata, CD_PROP_BOOL, ".select_poly");
+ const int index = rna_MeshPolygon_index_get(ptr);
+ return select_poly == NULL ? false : select_poly[index];
+}
+
+static void rna_MeshPolygon_select_set(PointerRNA *ptr, bool value)
+{
+ Mesh *mesh = rna_mesh(ptr);
+ bool *select_poly = (bool *)CustomData_duplicate_referenced_layer_named(
+ &mesh->pdata, CD_PROP_BOOL, ".select_poly", mesh->totpoly);
+ if (!select_poly) {
+ if (!value) {
+ /* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */
+ return;
+ }
+ select_poly = (bool *)CustomData_add_layer_named(
+ &mesh->pdata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, mesh->totpoly, ".select_poly");
+ }
+ const int index = rna_MeshPolygon_index_get(ptr);
+ select_poly[index] = value;
+}
+
static int rna_MeshPolygon_material_index_get(PointerRNA *ptr)
{
const Mesh *mesh = rna_mesh(ptr);
@@ -641,9 +735,9 @@ static void rna_MeshLoopTriangle_normal_get(PointerRNA *ptr, float *values)
MLoopTri *lt = (MLoopTri *)ptr->data;
const MVert *verts = BKE_mesh_verts(me);
const MLoop *loops = BKE_mesh_loops(me);
- unsigned int v1 = loops[lt->tri[0]].v;
- unsigned int v2 = loops[lt->tri[1]].v;
- unsigned int v3 = loops[lt->tri[2]].v;
+ uint v1 = loops[lt->tri[0]].v;
+ uint v2 = loops[lt->tri[1]].v;
+ uint v3 = loops[lt->tri[2]].v;
normal_tri_v3(values, verts[v1].co, verts[v2].co, verts[v3].co);
}
@@ -672,9 +766,9 @@ static float rna_MeshLoopTriangle_area_get(PointerRNA *ptr)
MLoopTri *lt = (MLoopTri *)ptr->data;
const MVert *verts = BKE_mesh_verts(me);
const MLoop *loops = BKE_mesh_loops(me);
- unsigned int v1 = loops[lt->tri[0]].v;
- unsigned int v2 = loops[lt->tri[1]].v;
- unsigned int v3 = loops[lt->tri[2]].v;
+ uint v1 = loops[lt->tri[0]].v;
+ uint v2 = loops[lt->tri[1]].v;
+ uint v3 = loops[lt->tri[2]].v;
return area_tri_v3(verts[v1].co, verts[v2].co, verts[v3].co);
}
@@ -1165,6 +1259,31 @@ static int rna_MeshVertexCreaseLayer_data_length(PointerRNA *ptr)
/* End vertex creases */
+/* Edge creases */
+
+DEFINE_CUSTOMDATA_LAYER_COLLECTION(edge_crease, edata, CD_CREASE)
+
+static char *rna_EdgeCustomData_data_path(const PointerRNA *ptr, const char *collection, int type);
+static char *rna_MeshEdgeCreaseLayer_path(const PointerRNA *ptr)
+{
+ return rna_EdgeCustomData_data_path(ptr, "edge_creases", CD_CREASE);
+}
+
+static void rna_MeshEdgeCreaseLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ Mesh *me = rna_mesh(ptr);
+ CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
+ rna_iterator_array_begin(iter, layer->data, sizeof(float), me->totedge, 0, NULL);
+}
+
+static int rna_MeshEdgeCreaseLayer_data_length(PointerRNA *ptr)
+{
+ Mesh *me = rna_mesh(ptr);
+ return me->totedge;
+}
+
+/* End edge creases */
+
/* Paint mask */
DEFINE_CUSTOMDATA_LAYER_COLLECTION(vertex_paint_mask, vdata, CD_PAINT_MASK)
@@ -1285,7 +1404,7 @@ static void rna_MeshPoly_vertices_get(PointerRNA *ptr, int *values)
MPoly *mp = (MPoly *)ptr->data;
const MLoop *loops = BKE_mesh_loops(me);
const MLoop *ml = &loops[mp->loopstart];
- unsigned int i;
+ uint i;
for (i = mp->totloop; i > 0; i--, values++, ml++) {
*values = ml->v;
}
@@ -1298,7 +1417,7 @@ static void rna_MeshPoly_vertices_set(PointerRNA *ptr, const int *values)
MLoop *loops = BKE_mesh_loops_for_write(me);
MLoop *ml = &loops[mp->loopstart];
- unsigned int i;
+ uint i;
for (i = mp->totloop; i > 0; i--, values++, ml++) {
ml->v = *values;
}
@@ -1341,6 +1460,32 @@ static void rna_MeshEdge_hide_set(PointerRNA *ptr, bool value)
hide_edge[index] = value;
}
+static bool rna_MeshEdge_select_get(PointerRNA *ptr)
+{
+ const Mesh *mesh = rna_mesh(ptr);
+ const bool *select_edge = (const bool *)CustomData_get_layer_named(
+ &mesh->edata, CD_PROP_BOOL, ".select_edge");
+ const int index = rna_MeshEdge_index_get(ptr);
+ return select_edge == NULL ? false : select_edge[index];
+}
+
+static void rna_MeshEdge_select_set(PointerRNA *ptr, bool value)
+{
+ Mesh *mesh = rna_mesh(ptr);
+ bool *select_edge = (bool *)CustomData_duplicate_referenced_layer_named(
+ &mesh->edata, CD_PROP_BOOL, ".select_edge", mesh->totedge);
+ if (!select_edge) {
+ if (!value) {
+ /* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */
+ return;
+ }
+ select_edge = (bool *)CustomData_add_layer_named(
+ &mesh->edata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, mesh->totedge, ".select_edge");
+ }
+ const int index = rna_MeshEdge_index_get(ptr);
+ select_edge[index] = value;
+}
+
static int rna_MeshLoopTriangle_material_index_get(PointerRNA *ptr)
{
const Mesh *me = rna_mesh(ptr);
@@ -1384,8 +1529,9 @@ static char *rna_MeshPolygon_path(const PointerRNA *ptr)
static char *rna_MeshLoopTriangle_path(const PointerRNA *ptr)
{
- return BLI_sprintfN("loop_triangles[%d]",
- (int)((MLoopTri *)ptr->data - rna_mesh(ptr)->runtime.looptris.array));
+ return BLI_sprintfN(
+ "loop_triangles[%d]",
+ (int)((MLoopTri *)ptr->data - BKE_mesh_runtime_looptri_ensure(rna_mesh(ptr))));
}
static char *rna_MeshEdge_path(const PointerRNA *ptr)
@@ -1424,6 +1570,27 @@ static char *rna_VertCustomData_data_path(const PointerRNA *ptr, const char *col
return NULL;
}
+static char *rna_EdgeCustomData_data_path(const PointerRNA *ptr, const char *collection, int type)
+{
+ const CustomDataLayer *cdl;
+ const Mesh *me = rna_mesh(ptr);
+ const CustomData *edata = rna_mesh_edata(ptr);
+ int a, b, totedge = (me->edit_mesh) ? 0 : me->totedge;
+
+ for (cdl = edata->layers, a = 0; a < edata->totlayer; cdl++, a++) {
+ if (cdl->type == type) {
+ b = ((char *)ptr->data - ((char *)cdl->data)) / CustomData_sizeof(type);
+ if (b >= 0 && b < totedge) {
+ char name_esc[sizeof(cdl->name) * 2];
+ BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
+ return BLI_sprintfN("%s[\"%s\"].data[%d]", collection, name_esc, b);
+ }
+ }
+ }
+
+ return NULL;
+}
+
static char *rna_PolyCustomData_data_path(const PointerRNA *ptr, const char *collection, int type)
{
const CustomDataLayer *cdl;
@@ -1571,6 +1738,19 @@ static int rna_Mesh_vertex_normals_length(PointerRNA *ptr)
return mesh->totvert;
}
+int rna_Mesh_vertex_normals_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
+{
+ const Mesh *mesh = rna_mesh(ptr);
+ if (index < 0 || index >= mesh->totvert) {
+ return false;
+ }
+ /* Casting away const is okay because this RNA type doesn't allow changing the value. */
+ r_ptr->owner_id = (ID *)&mesh->id;
+ r_ptr->type = &RNA_MeshNormalValue;
+ r_ptr->data = (float *)BKE_mesh_vertex_normals_ensure(mesh)[index];
+ return true;
+}
+
static void rna_Mesh_poly_normals_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
const Mesh *mesh = rna_mesh(ptr);
@@ -1584,6 +1764,19 @@ static int rna_Mesh_poly_normals_length(PointerRNA *ptr)
return mesh->totpoly;
}
+int rna_Mesh_poly_normals_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
+{
+ const Mesh *mesh = rna_mesh(ptr);
+ if (index < 0 || index >= mesh->totpoly) {
+ return false;
+ }
+ /* Casting away const is okay because this RNA type doesn't allow changing the value. */
+ r_ptr->owner_id = (ID *)&mesh->id;
+ r_ptr->type = &RNA_MeshNormalValue;
+ r_ptr->data = (float *)BKE_mesh_poly_normals_ensure(mesh)[index];
+ return true;
+}
+
static char *rna_MeshUVLoop_path(const PointerRNA *ptr)
{
return rna_LoopCustomData_data_path(ptr, "uv_layers", CD_MLOOPUV);
@@ -1943,6 +2136,7 @@ static void UNUSED_FUNCTION(rna_mesh_unused)(void)
(void)rna_Mesh_face_map_active_index_get;
(void)rna_Mesh_face_map_active_set;
(void)rna_Mesh_vertex_crease_index_range;
+ (void)rna_Mesh_edge_crease_index_range;
/* end unused function block */
}
@@ -2052,7 +2246,7 @@ static void rna_def_mvert(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Normal", "Vertex Normal");
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT);
+ RNA_def_property_boolean_funcs(prop, "rna_MeshVertex_select_get", "rna_MeshVertex_select_set");
RNA_def_property_ui_text(prop, "Select", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
@@ -2128,7 +2322,7 @@ static void rna_def_medge(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT);
+ RNA_def_property_boolean_funcs(prop, "rna_MeshEdge_select_get", "rna_MeshEdge_select_set");
RNA_def_property_ui_text(prop, "Select", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
@@ -2342,7 +2536,7 @@ static void rna_def_mpolygon(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_FACE_SEL);
+ RNA_def_property_boolean_funcs(prop, "rna_MeshPolygon_select_get", "rna_MeshPolygon_select_set");
RNA_def_property_ui_text(prop, "Select", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
@@ -3265,6 +3459,40 @@ static void rna_def_vertex_creases(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
}
+static void rna_def_edge_creases(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "MeshEdgeCreaseLayer", NULL);
+ RNA_def_struct_ui_text(srna, "Mesh Edge Crease Layer", "Per-edge crease");
+ RNA_def_struct_sdna(srna, "CustomDataLayer");
+ RNA_def_struct_path_func(srna, "rna_MeshEdgeCreaseLayer_path");
+
+ prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_struct_type(prop, "MeshEdgeCrease");
+ RNA_def_property_ui_text(prop, "Data", "");
+ RNA_def_property_collection_funcs(prop,
+ "rna_MeshEdgeCreaseLayer_data_begin",
+ "rna_iterator_array_next",
+ "rna_iterator_array_end",
+ "rna_iterator_array_get",
+ "rna_MeshEdgeCreaseLayer_data_length",
+ NULL,
+ NULL,
+ NULL);
+
+ /* EdgeCrease struct */
+ srna = RNA_def_struct(brna, "MeshEdgeCrease", NULL);
+ RNA_def_struct_sdna(srna, "MFloatProperty");
+ RNA_def_struct_ui_text(srna, "Float Property", "");
+
+ prop = RNA_def_property(srna, "value", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "f");
+ RNA_def_property_ui_text(prop, "Value", "");
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
+}
+
static void rna_def_paint_mask(BlenderRNA *brna, PropertyRNA *UNUSED(cprop))
{
StructRNA *srna;
@@ -3462,7 +3690,7 @@ static void rna_def_mesh(BlenderRNA *brna)
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_Mesh_vertex_normals_length",
- NULL,
+ "rna_Mesh_vertex_normals_lookup_int",
NULL,
NULL);
@@ -3479,12 +3707,20 @@ static void rna_def_mesh(BlenderRNA *brna)
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_Mesh_poly_normals_length",
- NULL,
+ "rna_Mesh_poly_normals_lookup_int",
NULL,
NULL);
prop = RNA_def_property(srna, "loop_triangles", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "runtime.looptris.array", "runtime.looptris.len");
+ RNA_def_property_collection_funcs(prop,
+ "rna_Mesh_loop_triangles_begin",
+ "rna_iterator_array_next",
+ "rna_iterator_array_end",
+ "rna_iterator_array_get",
+ "rna_Mesh_loop_triangles_length",
+ "rna_Mesh_loop_triangles_lookup_int",
+ NULL,
+ NULL);
RNA_def_property_struct_type(prop, "MeshLoopTriangle");
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
RNA_def_property_ui_text(prop, "Loop Triangles", "Tessellation of mesh polygons into triangles");
@@ -3739,6 +3975,24 @@ static void rna_def_mesh(BlenderRNA *brna)
rna_def_vertex_creases(brna);
/* End vertex crease */
+ /* Vertex Crease */
+ prop = RNA_def_property(srna, "edge_creases", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_struct_type(prop, "MeshEdgeCreaseLayer");
+ RNA_def_property_collection_sdna(prop, NULL, "edata.layers", "edata.totlayer");
+ RNA_def_property_collection_funcs(prop,
+ "rna_Mesh_edge_creases_begin",
+ NULL,
+ NULL,
+ NULL,
+ "rna_Mesh_edge_creases_length",
+ NULL,
+ NULL,
+ NULL);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
+ RNA_def_property_ui_text(prop, "Edge Creases", "Sharpness of the edges for subdivision");
+ rna_def_edge_creases(brna);
+ /* End edge crease */
+
/* Paint mask */
prop = RNA_def_property(srna, "vertex_paint_masks", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "vdata.layers", "vdata.totlayer");
@@ -3770,6 +4024,7 @@ static void rna_def_mesh(BlenderRNA *brna)
"Size of the voxel in object space used for volume evaluation. Lower "
"values preserve finer details");
RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
+ RNA_def_property_flag(prop, PROP_NO_DEG_UPDATE);
prop = RNA_def_property(srna, "remesh_voxel_adaptivity", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "remesh_voxel_adaptivity");
@@ -3781,11 +4036,13 @@ static void rna_def_mesh(BlenderRNA *brna)
"Reduces the final face count by simplifying geometry where detail is not needed, "
"generating triangles. A value greater than 0 disables Fix Poles");
RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
+ RNA_def_property_flag(prop, PROP_NO_DEG_UPDATE);
prop = RNA_def_property(srna, "use_remesh_fix_poles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_REMESH_FIX_POLES);
RNA_def_property_ui_text(prop, "Fix Poles", "Produces less poles and a better topology flow");
RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
+ RNA_def_property_flag(prop, PROP_NO_DEG_UPDATE);
prop = RNA_def_property(srna, "use_remesh_preserve_volume", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_REMESH_REPROJECT_VOLUME);
@@ -3794,29 +4051,34 @@ static void rna_def_mesh(BlenderRNA *brna)
"Preserve Volume",
"Projects the mesh to preserve the volume and details of the original mesh");
RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
+ RNA_def_property_flag(prop, PROP_NO_DEG_UPDATE);
prop = RNA_def_property(srna, "use_remesh_preserve_paint_mask", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_REMESH_REPROJECT_PAINT_MASK);
RNA_def_property_ui_text(prop, "Preserve Paint Mask", "Keep the current mask on the new mesh");
RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
+ RNA_def_property_flag(prop, PROP_NO_DEG_UPDATE);
prop = RNA_def_property(srna, "use_remesh_preserve_sculpt_face_sets", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_REMESH_REPROJECT_SCULPT_FACE_SETS);
RNA_def_property_ui_text(
prop, "Preserve Face Sets", "Keep the current Face Sets on the new mesh");
RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
+ RNA_def_property_flag(prop, PROP_NO_DEG_UPDATE);
prop = RNA_def_property(srna, "use_remesh_preserve_vertex_colors", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_REMESH_REPROJECT_VERTEX_COLORS);
RNA_def_property_ui_text(
prop, "Preserve Vertex Colors", "Keep the current vertex colors on the new mesh");
RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
+ RNA_def_property_flag(prop, PROP_NO_DEG_UPDATE);
prop = RNA_def_property(srna, "remesh_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "remesh_mode");
RNA_def_property_enum_items(prop, rna_enum_mesh_remesh_mode_items);
RNA_def_property_ui_text(prop, "Remesh Mode", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
+ RNA_def_property_flag(prop, PROP_NO_DEG_UPDATE);
/* End remesh */
@@ -3884,6 +4146,17 @@ static void rna_def_mesh(BlenderRNA *brna)
prop, "Has Vertex Bevel Weight", "True if the mesh has an vertex bevel weight layer");
RNA_def_property_boolean_funcs(prop, "rna_Mesh_has_vertex_bevel_weight_get", NULL);
+ prop = RNA_def_property(srna, "has_crease_edge", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Has Edge Crease", "True if the mesh has an edge crease layer");
+ RNA_def_property_boolean_funcs(prop, "rna_Mesh_has_edge_crease_get", NULL);
+
+ prop = RNA_def_property(srna, "has_crease_vertex", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(
+ prop, "Has Vertex Crease", "True if the mesh has an vertex crease layer");
+ RNA_def_property_boolean_funcs(prop, "rna_Mesh_has_vertex_crease_get", NULL);
+
prop = RNA_def_property(srna, "texco_mesh", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "texcomesh");
RNA_def_property_flag(prop, PROP_EDITABLE);
@@ -3936,16 +4209,6 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_ui_icon(prop, ICON_VERTEXSEL, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_Mesh_update_vertmask");
- /* customdata flags */
-
- prop = RNA_def_property(srna, "use_customdata_vertex_crease", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_VERT_CREASE);
- RNA_def_property_ui_text(prop, "Store Vertex Crease", "");
-
- prop = RNA_def_property(srna, "use_customdata_edge_crease", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_EDGE_CREASE);
- RNA_def_property_ui_text(prop, "Store Edge Crease", "");
-
/* readonly editmesh info - use for extrude menu */
prop = RNA_def_property(srna, "total_vert_sel", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_funcs(prop, "rna_Mesh_tot_vert_get", NULL, NULL);
diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c
index 524e3134f9c..de033408170 100644
--- a/source/blender/makesrna/intern/rna_nla.c
+++ b/source/blender/makesrna/intern/rna_nla.c
@@ -822,6 +822,7 @@ static void rna_def_nlastrip(BlenderRNA *brna)
RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_repeat_set", NULL);
/* these limits have currently be chosen arbitrarily, but could be extended
* (minimum should still be > 0 though) if needed... */
+ RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0.1f, 1000.0f);
RNA_def_property_ui_text(prop, "Repeat", "Number of times to repeat the action range");
RNA_def_property_update(
@@ -832,6 +833,7 @@ static void rna_def_nlastrip(BlenderRNA *brna)
RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_scale_set", NULL);
/* these limits can be extended, but beyond this, we can get some crazy+annoying bugs
* due to numeric errors */
+ RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0.0001f, 1000.0f);
RNA_def_property_ui_text(prop, "Scale", "Scaling factor for action");
RNA_def_property_update(
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index caeee35a80a..cfec020c739 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -13,6 +13,7 @@
#include "BLT_translation.h"
+#include "DNA_curves_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
@@ -827,21 +828,21 @@ static const EnumPropertyItem *rna_node_static_type_itemf(bContext *UNUSED(C),
tmp.value = NODE_CUSTOM;
tmp.identifier = "CUSTOM";
- tmp.name = "Custom";
- tmp.description = "Custom Node";
+ tmp.name = N_("Custom");
+ tmp.description = N_("Custom Node");
tmp.icon = ICON_NONE;
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = NODE_CUSTOM_GROUP;
tmp.identifier = "CUSTOM GROUP";
- tmp.name = "CustomGroup";
- tmp.description = "Custom Group Node";
+ tmp.name = N_("CustomGroup");
+ tmp.description = N_("Custom Group Node");
tmp.icon = ICON_NONE;
RNA_enum_item_add(&item, &totitem, &tmp);
tmp.value = NODE_UNDEFINED;
tmp.identifier = "UNDEFINED";
- tmp.name = "UNDEFINED";
+ tmp.name = N_("UNDEFINED");
tmp.description = "";
tmp.icon = ICON_NONE;
RNA_enum_item_add(&item, &totitem, &tmp);
@@ -1892,7 +1893,7 @@ static void rna_Node_unregister(Main *UNUSED(bmain), StructRNA *type)
}
/* Generic internal registration function.
- * Can be used to implement callbacks for registerable RNA node subtypes.
+ * Can be used to implement callbacks for registerable RNA node sub-types.
*/
static bNodeType *rna_Node_register_base(Main *bmain,
ReportList *reports,
@@ -2199,18 +2200,6 @@ static const EnumPropertyItem *rna_GeometryNodeAttributeType_type_with_socket_it
generic_attribute_type_supported_with_socket);
}
-static bool transfer_attribute_type_supported(const EnumPropertyItem *item)
-{
- return ELEM(
- item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3, CD_PROP_COLOR, CD_PROP_BOOL, CD_PROP_INT32);
-}
-static const EnumPropertyItem *rna_NodeGeometryTransferAttribute_type_itemf(
- bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
-{
- *r_free = true;
- return itemf_function_check(rna_enum_attribute_type_items, transfer_attribute_type_supported);
-}
-
static bool attribute_statistic_type_supported(const EnumPropertyItem *item)
{
return ELEM(item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3);
@@ -2436,21 +2425,13 @@ static bNodeSocket *rna_Node_inputs_new(ID *id,
const char *name,
const char *identifier)
{
-
- if (ELEM(node->type, NODE_GROUP_INPUT, NODE_FRAME)) {
- BKE_report(reports, RPT_ERROR, "Unable to create socket");
+ if (node->type != NODE_CUSTOM) {
+ BKE_report(reports, RPT_ERROR, "Cannot add socket to built-in node");
return NULL;
}
- /* Adding an input to a group node is not working,
- * simpler to add it to its underlying nodetree. */
- if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id != NULL) {
- return rna_NodeTree_inputs_new((bNodeTree *)node->id, bmain, reports, type, name);
- }
bNodeTree *ntree = (bNodeTree *)id;
- bNodeSocket *sock;
-
- sock = nodeAddSocket(ntree, node, SOCK_IN, type, identifier, name);
+ bNodeSocket *sock = nodeAddSocket(ntree, node, SOCK_IN, type, identifier, name);
if (sock == NULL) {
BKE_report(reports, RPT_ERROR, "Unable to create socket");
@@ -2471,20 +2452,13 @@ static bNodeSocket *rna_Node_outputs_new(ID *id,
const char *name,
const char *identifier)
{
- if (ELEM(node->type, NODE_GROUP_OUTPUT, NODE_FRAME)) {
- BKE_report(reports, RPT_ERROR, "Unable to create socket");
+ if (node->type != NODE_CUSTOM) {
+ BKE_report(reports, RPT_ERROR, "Cannot add socket to built-in node");
return NULL;
}
- /* Adding an output to a group node is not working,
- * simpler to add it to its underlying nodetree. */
- if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id != NULL) {
- return rna_NodeTree_outputs_new((bNodeTree *)node->id, bmain, reports, type, name);
- }
bNodeTree *ntree = (bNodeTree *)id;
- bNodeSocket *sock;
-
- sock = nodeAddSocket(ntree, node, SOCK_OUT, type, identifier, name);
+ bNodeSocket *sock = nodeAddSocket(ntree, node, SOCK_OUT, type, identifier, name);
if (sock == NULL) {
BKE_report(reports, RPT_ERROR, "Unable to create socket");
@@ -2500,6 +2474,11 @@ static bNodeSocket *rna_Node_outputs_new(ID *id,
static void rna_Node_socket_remove(
ID *id, bNode *node, Main *bmain, ReportList *reports, bNodeSocket *sock)
{
+ if (node->type != NODE_CUSTOM) {
+ BKE_report(reports, RPT_ERROR, "Unable to remove socket from built-in node");
+ return;
+ }
+
bNodeTree *ntree = (bNodeTree *)id;
if (BLI_findindex(&node->inputs, sock) == -1 && BLI_findindex(&node->outputs, sock) == -1) {
@@ -2513,8 +2492,13 @@ static void rna_Node_socket_remove(
}
}
-static void rna_Node_inputs_clear(ID *id, bNode *node, Main *bmain)
+static void rna_Node_inputs_clear(ID *id, bNode *node, Main *bmain, ReportList *reports)
{
+ if (node->type != NODE_CUSTOM) {
+ BKE_report(reports, RPT_ERROR, "Unable to remove sockets from built-in node");
+ return;
+ }
+
bNodeTree *ntree = (bNodeTree *)id;
bNodeSocket *sock, *nextsock;
@@ -2527,8 +2511,13 @@ static void rna_Node_inputs_clear(ID *id, bNode *node, Main *bmain)
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
-static void rna_Node_outputs_clear(ID *id, bNode *node, Main *bmain)
+static void rna_Node_outputs_clear(ID *id, bNode *node, Main *bmain, ReportList *reports)
{
+ if (node->type != NODE_CUSTOM) {
+ BKE_report(reports, RPT_ERROR, "Unable to remove socket from built-in node");
+ return;
+ }
+
bNodeTree *ntree = (bNodeTree *)id;
bNodeSocket *sock, *nextsock;
@@ -2541,8 +2530,14 @@ static void rna_Node_outputs_clear(ID *id, bNode *node, Main *bmain)
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
-static void rna_Node_inputs_move(ID *id, bNode *node, Main *bmain, int from_index, int to_index)
+static void rna_Node_inputs_move(
+ ID *id, bNode *node, Main *bmain, ReportList *reports, int from_index, int to_index)
{
+ if (node->type != NODE_CUSTOM) {
+ BKE_report(reports, RPT_ERROR, "Unable to move sockets in built-in node");
+ return;
+ }
+
bNodeTree *ntree = (bNodeTree *)id;
bNodeSocket *sock;
@@ -2573,8 +2568,14 @@ static void rna_Node_inputs_move(ID *id, bNode *node, Main *bmain, int from_inde
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
-static void rna_Node_outputs_move(ID *id, bNode *node, Main *bmain, int from_index, int to_index)
+static void rna_Node_outputs_move(
+ ID *id, bNode *node, Main *bmain, ReportList *reports, int from_index, int to_index)
{
+ if (node->type != NODE_CUSTOM) {
+ BKE_report(reports, RPT_ERROR, "Unable to move sockets in built-in node");
+ return;
+ }
+
bNodeTree *ntree = (bNodeTree *)id;
bNodeSocket *sock;
@@ -3585,7 +3586,7 @@ static void rna_difference_matte_t2_set(PointerRNA *ptr, float value)
chroma->t2 = value;
}
-/* Button Set Funcs for Matte Nodes */
+/* Button Set Functions for Matte Nodes */
static void rna_Matte_t1_set(PointerRNA *ptr, float value)
{
bNode *node = (bNode *)ptr->data;
@@ -5253,6 +5254,11 @@ static void def_sh_attribute(StructRNA *srna)
"The attribute is associated with the instancer particle system or object, "
"falling back to the Object mode if the attribute isn't found, or the object "
"is not instanced"},
+ {SHD_ATTRIBUTE_VIEW_LAYER,
+ "VIEW_LAYER",
+ 0,
+ "View Layer",
+ "The attribute is associated with the View Layer, Scene or World that is being rendered"},
{0, NULL, 0, NULL, NULL},
};
PropertyRNA *prop;
@@ -5515,6 +5521,7 @@ static void def_sh_tex_image(StructRNA *srna)
RNA_def_property_enum_items(prop, prop_image_extension);
RNA_def_property_ui_text(
prop, "Extension", "How the image is extrapolated past its original bounds");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_IMAGE);
RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NONE);
@@ -5579,6 +5586,7 @@ static void def_geo_image_texture(StructRNA *srna)
RNA_def_property_enum_items(prop, prop_image_extension);
RNA_def_property_ui_text(
prop, "Extension", "How the image is extrapolated past its original bounds");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_IMAGE);
RNA_def_property_update(prop, 0, "rna_Node_update");
}
@@ -6817,11 +6825,11 @@ static void def_cmp_levels(StructRNA *srna)
PropertyRNA *prop;
static const EnumPropertyItem channel_items[] = {
- {1, "COMBINED_RGB", 0, "Combined", "Combined RGB"},
- {2, "RED", 0, "Red", "Red Channel"},
- {3, "GREEN", 0, "Green", "Green Channel"},
- {4, "BLUE", 0, "Blue", "Blue Channel"},
- {5, "LUMINANCE", 0, "Luminance", "Luminance Channel"},
+ {CMP_NODE_LEVLES_LUMINANCE, "COMBINED_RGB", 0, "Combined", "Combined RGB"},
+ {CMP_NODE_LEVLES_RED, "RED", 0, "Red", "Red Channel"},
+ {CMP_NODE_LEVLES_GREEN, "GREEN", 0, "Green", "Green Channel"},
+ {CMP_NODE_LEVLES_BLUE, "BLUE", 0, "Blue", "Blue Channel"},
+ {CMP_NODE_LEVLES_LUMINANCE_BT709, "LUMINANCE", 0, "Luminance", "Luminance Channel"},
{0, NULL, 0, NULL, NULL},
};
@@ -7039,11 +7047,11 @@ static void rna_def_cmp_output_file_slots_api(BlenderRNA *brna,
func = RNA_def_function(srna, "clear", "rna_Node_inputs_clear");
RNA_def_function_ui_description(func, "Remove all file slots from this node");
- RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS);
func = RNA_def_function(srna, "move", "rna_Node_inputs_move");
RNA_def_function_ui_description(func, "Move a file slot to another position");
- RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS);
parm = RNA_def_int(
func, "from_index", -1, 0, INT_MAX, "From Index", "Index of the socket to move", 0, 10000);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
@@ -7060,6 +7068,7 @@ static void def_cmp_output_file(BlenderRNA *brna, StructRNA *srna)
prop = RNA_def_property(srna, "base_path", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "base_path");
RNA_def_property_ui_text(prop, "Base Path", "Base output path for the image");
+ RNA_def_property_flag(prop, PROP_PATH_OUTPUT);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "active_input_index", PROP_INT, PROP_NONE);
@@ -7326,19 +7335,9 @@ static void def_cmp_convert_color_space(StructRNA *srna)
PropertyRNA *prop;
RNA_def_struct_sdna_from(srna, "NodeConvertColorSpace", "storage");
- static const EnumPropertyItem color_space_items[] = {
- {0,
- "NONE",
- 0,
- "None",
- "Do not perform any color transform on load, treat colors as in scene linear space "
- "already"},
- {0, NULL, 0, NULL, NULL},
- };
-
prop = RNA_def_property(srna, "from_color_space", PROP_ENUM, PROP_NONE);
RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
- RNA_def_property_enum_items(prop, color_space_items);
+ RNA_def_property_enum_items(prop, rna_enum_color_space_convert_default_items);
RNA_def_property_enum_funcs(prop,
"rna_NodeConvertColorSpace_from_color_space_get",
"rna_NodeConvertColorSpace_from_color_space_set",
@@ -7348,7 +7347,7 @@ static void def_cmp_convert_color_space(StructRNA *srna)
prop = RNA_def_property(srna, "to_color_space", PROP_ENUM, PROP_NONE);
RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
- RNA_def_property_enum_items(prop, color_space_items);
+ RNA_def_property_enum_items(prop, rna_enum_color_space_convert_default_items);
RNA_def_property_enum_funcs(prop,
"rna_NodeConvertColorSpace_to_color_space_get",
"rna_NodeConvertColorSpace_to_color_space_set",
@@ -9445,10 +9444,26 @@ static void def_geo_curve_sample(StructRNA *srna)
RNA_def_struct_sdna_from(srna, "NodeGeometryCurveSample", "storage");
- PropertyRNA *prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+ PropertyRNA *prop;
+ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, mode_items);
RNA_def_property_ui_text(prop, "Mode", "Method for sampling input");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+
+ prop = RNA_def_property(srna, "use_all_curves", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop,
+ "All Curves",
+ "Sample lengths based on the total lengh of all curves, rather than "
+ "using a length inside each selected curve");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+
+ prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
+ RNA_def_property_enum_funcs(
+ prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_with_socket_itemf");
+ RNA_def_property_enum_default(prop, CD_PROP_FLOAT);
+ RNA_def_property_ui_text(prop, "Data Type", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
static void def_geo_triangulate(StructRNA *srna)
@@ -9614,6 +9629,31 @@ static void def_geo_extrude_mesh(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
+static void def_geo_distribute_points_in_volume(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ static const EnumPropertyItem mode_items[] = {
+ {GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME_DENSITY_RANDOM,
+ "DENSITY_RANDOM",
+ 0,
+ "Random",
+ "Distribute points randomly inside of the volume"},
+ {GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME_DENSITY_GRID,
+ "DENSITY_GRID",
+ 0,
+ "Grid",
+ "Distribute the points in a grid pattern inside of the volume"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ RNA_def_struct_sdna_from(srna, "NodeGeometryDistributePointsInVolume", "storage");
+ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, mode_items);
+ RNA_def_property_ui_text(prop, "Distribution Method", "Method to use for scattering points");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+}
+
static void def_geo_distribute_points_on_faces(StructRNA *srna)
{
PropertyRNA *prop;
@@ -9684,6 +9724,17 @@ static void def_geo_curve_set_handle_positions(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
+static void def_geo_set_curve_normal(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom1");
+ RNA_def_property_enum_items(prop, rna_enum_curve_normal_modes);
+ RNA_def_property_ui_text(prop, "Mode", "Mode for curve normal evaluation");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+}
+
static void def_geo_curve_handle_type_selection(StructRNA *srna)
{
PropertyRNA *prop;
@@ -10398,53 +10449,68 @@ static void def_geo_curve_trim(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
-static void def_geo_transfer_attribute(StructRNA *srna)
+static void def_geo_sample_index(StructRNA *srna)
{
- static EnumPropertyItem mapping_items[] = {
- {GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED,
- "NEAREST_FACE_INTERPOLATED",
- 0,
- "Nearest Face Interpolated",
- "Transfer the attribute from the nearest face on a surface (loose points and edges are "
- "ignored)"},
- {GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST,
- "NEAREST",
- 0,
- "Nearest",
- "Transfer the element from the nearest element (using face and edge centers for the "
- "distance computation)"},
- {GEO_NODE_ATTRIBUTE_TRANSFER_INDEX,
- "INDEX",
- 0,
- "Index",
- "Transfer the data from the element with the corresponding index in the target geometry"},
- {0, NULL, 0, NULL, NULL},
- };
-
PropertyRNA *prop;
- RNA_def_struct_sdna_from(srna, "NodeGeometryTransferAttribute", "storage");
-
- prop = RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "mode");
- RNA_def_property_enum_items(prop, mapping_items);
- RNA_def_property_ui_text(prop, "Mapping", "Mapping between geometries");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+ RNA_def_struct_sdna_from(srna, "NodeGeometrySampleIndex", "storage");
prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
- RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_NodeGeometryTransferAttribute_type_itemf");
+ RNA_def_property_enum_funcs(
+ prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_with_socket_itemf");
RNA_def_property_enum_default(prop, CD_PROP_FLOAT);
- RNA_def_property_ui_text(prop, "Data Type", "The type for the source and result data");
+ RNA_def_property_ui_text(prop, "Data Type", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
prop = RNA_def_property(srna, "domain", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_attribute_domain_items);
RNA_def_property_enum_default(prop, ATTR_DOMAIN_POINT);
- RNA_def_property_ui_text(prop, "Domain", "The domain to use on the target geometry");
+ RNA_def_property_ui_text(prop, "Domain", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "clamp", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop,
+ "Clamp",
+ "Clamp the indices to the size of the attribute domain instead of "
+ "outputting a default value for invalid indices");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
+static void def_geo_sample_nearest_surface(StructRNA *srna)
+{
+ PropertyRNA *prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom1");
+ RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
+ RNA_def_property_enum_funcs(
+ prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_with_socket_itemf");
+ RNA_def_property_enum_default(prop, CD_PROP_FLOAT);
+ RNA_def_property_ui_text(prop, "Data Type", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+}
+
+static void def_geo_sample_nearest(StructRNA *srna)
+{
+ PropertyRNA *prop = RNA_def_property(srna, "domain", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom2");
+ RNA_def_property_enum_items(prop, rna_enum_attribute_domain_only_mesh_items);
+ RNA_def_property_enum_default(prop, ATTR_DOMAIN_POINT);
+ RNA_def_property_ui_text(prop, "Domain", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+}
+
+static void def_geo_sample_uv_surface(StructRNA *srna)
+{
+ PropertyRNA *prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom1");
+ RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
+ RNA_def_property_enum_funcs(
+ prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_with_socket_itemf");
+ RNA_def_property_enum_default(prop, CD_PROP_FLOAT);
+ RNA_def_property_ui_text(prop, "Data Type", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+}
+
static void def_geo_input_material(StructRNA *srna)
{
PropertyRNA *prop;
@@ -10786,6 +10852,12 @@ static void def_geo_viewer(StructRNA *srna)
RNA_def_property_enum_default(prop, CD_PROP_FLOAT);
RNA_def_property_ui_text(prop, "Data Type", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update");
+
+ prop = RNA_def_property(srna, "domain", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_enum_attribute_domain_with_auto_items);
+ RNA_def_property_enum_default(prop, ATTR_DOMAIN_POINT);
+ RNA_def_property_ui_text(prop, "Domain", "Domain to evaluate the field on");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_geo_realize_instances(StructRNA *srna)
@@ -12054,11 +12126,11 @@ static void rna_def_node_sockets_api(BlenderRNA *brna, PropertyRNA *cprop, int i
func = RNA_def_function(srna, "clear", clearfunc);
RNA_def_function_ui_description(func, "Remove all sockets from this node");
- RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS);
func = RNA_def_function(srna, "move", movefunc);
RNA_def_function_ui_description(func, "Move a socket to another position");
- RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS);
parm = RNA_def_int(
func, "from_index", -1, 0, INT_MAX, "From Index", "Index of the socket to move", 0, 10000);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
@@ -12176,7 +12248,7 @@ static void rna_def_node(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Custom Color", "Use custom color for the node");
RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
- prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
+ prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Color", "Custom color of the node body");
@@ -12646,6 +12718,7 @@ static void rna_def_nodetree(BlenderRNA *brna)
RNA_def_property_int_funcs(
prop, "rna_NodeTree_active_input_get", "rna_NodeTree_active_input_set", NULL);
RNA_def_property_ui_text(prop, "Active Input", "Index of the active input");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_NODE, NULL);
prop = RNA_def_property(srna, "outputs", PROP_COLLECTION, PROP_NONE);
@@ -12659,6 +12732,7 @@ static void rna_def_nodetree(BlenderRNA *brna)
RNA_def_property_int_funcs(
prop, "rna_NodeTree_active_output_get", "rna_NodeTree_active_output_set", NULL);
RNA_def_property_ui_text(prop, "Active Output", "Index of the active output");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_NODE, NULL);
/* exposed as a function for runtime interface type properties */
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index cfc3a832166..1d6b3d5d69e 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -356,7 +356,8 @@ static void rna_Object_internal_update_draw(Main *UNUSED(bmain),
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((Object *)ptr->owner_id, ((Object *)ptr->owner_id)->obmat, false, true);
+ BKE_object_apply_mat4(
+ (Object *)ptr->owner_id, ((Object *)ptr->owner_id)->object_to_world, false, true);
rna_Object_internal_update(bmain, scene, ptr);
}
@@ -381,7 +382,7 @@ static void rna_MaterialIndex_update(Main *UNUSED(bmain), Scene *UNUSED(scene),
{
Object *ob = (Object *)ptr->owner_id;
if (ob && ob->type == OB_GPENCIL) {
- /* notifying material property in topbar */
+ /* Notifying material property in top-bar. */
WM_main_add_notifier(NC_SPACE | ND_SPACE_VIEW3D, NULL);
}
}
@@ -407,7 +408,7 @@ static void rna_Object_matrix_local_set(PointerRNA *ptr, const float values[16])
Object *ob = (Object *)ptr->owner_id;
float local_mat[4][4];
- /* Localspace matrix is truly relative to the parent,
+ /* Local-space matrix is truly relative to the parent,
* but parameters stored in object are relative to parentinv matrix.
* Undo the parent inverse part before applying it as local matrix. */
if (ob->parent) {
@@ -497,12 +498,6 @@ static void rna_Object_dependency_update(Main *bmain, Scene *UNUSED(scene), Poin
void rna_Object_data_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
- Object *object = (Object *)ptr->data;
-
- if (object->mode == OB_MODE_SCULPT) {
- BKE_sculpt_ensure_orig_mesh_data(object);
- }
-
rna_Object_internal_update_data_dependency(bmain, scene, ptr);
}
@@ -2928,6 +2923,11 @@ static void rna_def_object_lineart(BlenderRNA *brna)
0,
"No Intersection",
"Include this object but do not generate intersection lines"},
+ {OBJECT_LRT_FORCE_INTERSECTION,
+ "FORCE_INTERSECTION",
+ 0,
+ "Force Intersection",
+ "Generate intersection lines even with objects that disabled intersection"},
{0, NULL, 0, NULL, NULL},
};
@@ -3391,7 +3391,7 @@ static void rna_def_object(BlenderRNA *brna)
/* matrix */
prop = RNA_def_property(srna, "matrix_world", PROP_FLOAT, PROP_MATRIX);
- RNA_def_property_float_sdna(prop, NULL, "obmat");
+ RNA_def_property_float_sdna(prop, NULL, "object_to_world");
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 6967f78026a..366a3597ce6 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -77,13 +77,36 @@ static const EnumPropertyItem space_items[] = {
# include "MEM_guardedalloc.h"
-static void rna_Object_select_set(
- Object *ob, bContext *C, ReportList *reports, bool select, ViewLayer *view_layer)
+static Base *find_view_layer_base_with_synced_ensure(
+ Object *ob, bContext *C, PointerRNA *view_layer_ptr, Scene **r_scene, ViewLayer **r_view_layer)
{
- if (view_layer == NULL) {
+ Scene *scene;
+ ViewLayer *view_layer;
+ if (view_layer_ptr->data) {
+ scene = (Scene *)view_layer_ptr->owner_id;
+ view_layer = view_layer_ptr->data;
+ }
+ else {
+ scene = CTX_data_scene(C);
view_layer = CTX_data_view_layer(C);
}
- Base *base = BKE_view_layer_base_find(view_layer, ob);
+ if (r_scene != NULL) {
+ *r_scene = scene;
+ }
+ if (r_view_layer != NULL) {
+ *r_view_layer = view_layer;
+ }
+
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ return BKE_view_layer_base_find(view_layer, ob);
+}
+
+static void rna_Object_select_set(
+ Object *ob, bContext *C, ReportList *reports, bool select, PointerRNA *view_layer_ptr)
+{
+ Scene *scene;
+ ViewLayer *view_layer;
+ Base *base = find_view_layer_base_with_synced_ensure(ob, C, view_layer_ptr, &scene, &view_layer);
if (!base) {
if (select) {
@@ -98,19 +121,14 @@ static void rna_Object_select_set(
ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
- Scene *scene = CTX_data_scene(C);
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene);
ED_outliner_select_sync_from_object_tag(C);
}
-static bool rna_Object_select_get(Object *ob, bContext *C, ViewLayer *view_layer)
+static bool rna_Object_select_get(Object *ob, bContext *C, PointerRNA *view_layer_ptr)
{
- if (view_layer == NULL) {
- view_layer = CTX_data_view_layer(C);
- }
- Base *base = BKE_view_layer_base_find(view_layer, ob);
-
+ Base *base = find_view_layer_base_with_synced_ensure(ob, C, view_layer_ptr, NULL, NULL);
if (!base) {
return false;
}
@@ -119,13 +137,11 @@ static bool rna_Object_select_get(Object *ob, bContext *C, ViewLayer *view_layer
}
static void rna_Object_hide_set(
- Object *ob, bContext *C, ReportList *reports, bool hide, ViewLayer *view_layer)
+ Object *ob, bContext *C, ReportList *reports, bool hide, PointerRNA *view_layer_ptr)
{
- if (view_layer == NULL) {
- view_layer = CTX_data_view_layer(C);
- }
- Base *base = BKE_view_layer_base_find(view_layer, ob);
-
+ Scene *scene;
+ ViewLayer *view_layer;
+ Base *base = find_view_layer_base_with_synced_ensure(ob, C, view_layer_ptr, &scene, &view_layer);
if (!base) {
if (hide) {
BKE_reportf(reports,
@@ -144,19 +160,14 @@ static void rna_Object_hide_set(
base->flag &= ~BASE_HIDDEN;
}
- Scene *scene = CTX_data_scene(C);
- BKE_layer_collection_sync(scene, view_layer);
+ BKE_view_layer_need_resync_tag(view_layer);
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
-static bool rna_Object_hide_get(Object *ob, bContext *C, ViewLayer *view_layer)
+static bool rna_Object_hide_get(Object *ob, bContext *C, PointerRNA *view_layer_ptr)
{
- if (view_layer == NULL) {
- view_layer = CTX_data_view_layer(C);
- }
- Base *base = BKE_view_layer_base_find(view_layer, ob);
-
+ Base *base = find_view_layer_base_with_synced_ensure(ob, C, view_layer_ptr, NULL, NULL);
if (!base) {
return false;
}
@@ -164,15 +175,15 @@ static bool rna_Object_hide_get(Object *ob, bContext *C, ViewLayer *view_layer)
return ((base->flag & BASE_HIDDEN) != 0);
}
-static bool rna_Object_visible_get(Object *ob, bContext *C, ViewLayer *view_layer, View3D *v3d)
+static bool rna_Object_visible_get(Object *ob,
+ bContext *C,
+ PointerRNA *view_layer_ptr,
+ View3D *v3d)
{
- if (view_layer == NULL) {
- view_layer = CTX_data_view_layer(C);
- }
+ Base *base = find_view_layer_base_with_synced_ensure(ob, C, view_layer_ptr, NULL, NULL);
if (v3d == NULL) {
v3d = CTX_wm_view3d(C);
}
- Base *base = BKE_view_layer_base_find(view_layer, ob);
if (!base) {
return false;
@@ -181,31 +192,19 @@ static bool rna_Object_visible_get(Object *ob, bContext *C, ViewLayer *view_laye
return BASE_VISIBLE(v3d, base);
}
-static bool rna_Object_holdout_get(Object *ob, bContext *C, ViewLayer *view_layer)
+static bool rna_Object_holdout_get(Object *ob, bContext *C, PointerRNA *view_layer_ptr)
{
- if (view_layer == NULL) {
- view_layer = CTX_data_view_layer(C);
- }
- Base *base = BKE_view_layer_base_find(view_layer, ob);
-
+ Base *base = find_view_layer_base_with_synced_ensure(ob, C, view_layer_ptr, NULL, NULL);
if (!base) {
return false;
}
- return ((base->flag & BASE_HOLDOUT) != 0);
+ return ((base->flag & BASE_HOLDOUT) != 0) || ((ob->visibility_flag & OB_HOLDOUT) != 0);
}
-static bool rna_Object_indirect_only_get(Object *ob, bContext *C, ViewLayer *view_layer)
+static bool rna_Object_indirect_only_get(Object *ob, bContext *C, PointerRNA *view_layer_ptr)
{
- if (view_layer == NULL) {
- view_layer = CTX_data_view_layer(C);
- }
- Base *base = BKE_view_layer_base_find(view_layer, ob);
-
- if (!base) {
- return false;
- }
-
+ Base *base = find_view_layer_base_with_synced_ensure(ob, C, view_layer_ptr, NULL, NULL);
return ((base->flag & BASE_INDIRECT_ONLY) != 0);
}
@@ -227,6 +226,7 @@ static Base *rna_Object_local_view_property_helper(bScreen *screen,
view_layer = WM_window_get_active_view_layer(win);
}
+ BKE_view_layer_synced_ensure(win ? WM_window_get_active_scene(win) : NULL, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob);
if (base == NULL) {
BKE_reportf(
@@ -831,6 +831,7 @@ void RNA_api_object(StructRNA *srna)
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_pointer(
func, "view_layer", "ViewLayer", "", "Use this instead of the active view layer");
+ RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
parm = RNA_def_boolean(func, "result", 0, "", "Object selected");
RNA_def_function_return(func, parm);
@@ -842,6 +843,7 @@ void RNA_api_object(StructRNA *srna)
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_pointer(
func, "view_layer", "ViewLayer", "", "Use this instead of the active view layer");
+ RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
func = RNA_def_function(srna, "hide_get", "rna_Object_hide_get");
RNA_def_function_ui_description(
@@ -850,6 +852,7 @@ void RNA_api_object(StructRNA *srna)
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_pointer(
func, "view_layer", "ViewLayer", "", "Use this instead of the active view layer");
+ RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
parm = RNA_def_boolean(func, "result", 0, "", "Object hidden");
RNA_def_function_return(func, parm);
@@ -861,6 +864,7 @@ void RNA_api_object(StructRNA *srna)
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_pointer(
func, "view_layer", "ViewLayer", "", "Use this instead of the active view layer");
+ RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
func = RNA_def_function(srna, "visible_get", "rna_Object_visible_get");
RNA_def_function_ui_description(func,
@@ -869,6 +873,7 @@ void RNA_api_object(StructRNA *srna)
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_pointer(
func, "view_layer", "ViewLayer", "", "Use this instead of the active view layer");
+ RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
parm = RNA_def_pointer(
func, "viewport", "SpaceView3D", "", "Use this instead of the active 3D viewport");
parm = RNA_def_boolean(func, "result", 0, "", "Object visible");
@@ -879,6 +884,7 @@ void RNA_api_object(StructRNA *srna)
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_pointer(
func, "view_layer", "ViewLayer", "", "Use this instead of the active view layer");
+ RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
parm = RNA_def_boolean(func, "result", 0, "", "Object holdout");
RNA_def_function_return(func, parm);
@@ -889,6 +895,7 @@ void RNA_api_object(StructRNA *srna)
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_pointer(
func, "view_layer", "ViewLayer", "", "Use this instead of the active view layer");
+ RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
parm = RNA_def_boolean(func, "result", 0, "", "Object indirect only");
RNA_def_function_return(func, parm);
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 40e7f6e65c2..a56e7d28ef7 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -471,7 +471,7 @@ static void rna_ParticleSystem_co_hair(
if (step >= 0 && step <= max_k) {
copy_v3_v3(n_co, (cache + step)->co);
mul_m4_v3(particlesystem->imat, n_co);
- mul_m4_v3(object->obmat, n_co);
+ mul_m4_v3(object->object_to_world, n_co);
}
}
@@ -1188,7 +1188,7 @@ static void rna_ParticleTarget_name_get(PointerRNA *ptr, char *str)
if (psys) {
if (pt->ob) {
- sprintf(str, "%s: %s", pt->ob->id.name + 2, psys->name);
+ BLI_sprintf(str, "%s: %s", pt->ob->id.name + 2, psys->name);
}
else {
strcpy(str, psys->name);
@@ -1315,7 +1315,7 @@ static void rna_ParticleDupliWeight_name_get(PointerRNA *ptr, char *str)
ParticleDupliWeight *dw = ptr->data;
if (dw->ob) {
- sprintf(str, "%s: %i", dw->ob->id.name + 2, dw->count);
+ BLI_sprintf(str, "%s: %i", dw->ob->id.name + 2, dw->count);
}
else {
strcpy(str, "No object");
@@ -3431,7 +3431,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Loop Count", "Number of times the keys are looped");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
- /* modified dm support */
+ /* Evaluated mesh support. */
prop = RNA_def_property(srna, "use_modifier_stack", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "use_modifier_stack", 0);
RNA_def_property_ui_text(
diff --git a/source/blender/makesrna/intern/rna_path.cc b/source/blender/makesrna/intern/rna_path.cc
index 96f46f5dbe6..e3898bbd682 100644
--- a/source/blender/makesrna/intern/rna_path.cc
+++ b/source/blender/makesrna/intern/rna_path.cc
@@ -583,7 +583,7 @@ bool RNA_path_resolve_elements(PointerRNA *ptr, const char *path, ListBase *r_el
}
char *RNA_path_append(const char *path,
- const PointerRNA *UNUSED(ptr),
+ const PointerRNA * /*ptr*/,
PropertyRNA *prop,
int intkey,
const char *strkey)
@@ -708,7 +708,7 @@ const char *RNA_path_array_index_token_find(const char *rna_path, const Property
if (UNLIKELY(rna_path[0] == '\0')) {
return nullptr;
}
- size_t rna_path_len = (size_t)strlen(rna_path) - 1;
+ size_t rna_path_len = size_t(strlen(rna_path)) - 1;
if (rna_path[rna_path_len] != ']') {
return nullptr;
}
@@ -861,7 +861,7 @@ static char *rna_idp_path(PointerRNA *ptr,
IDProperty *array = IDP_IDPArray(iter);
if (needle >= array && needle < (iter->len + array)) { /* found! */
link.name = iter->name;
- link.index = (int)(needle - array);
+ link.index = int(needle - array);
path = rna_idp_path_create(&link);
break;
}
@@ -1333,7 +1333,7 @@ char *RNA_path_struct_property_py(PointerRNA *ptr, PropertyRNA *prop, int index)
return ret;
}
-char *RNA_path_property_py(const PointerRNA *UNUSED(ptr), PropertyRNA *prop, int index)
+char *RNA_path_property_py(const PointerRNA * /*ptr*/, PropertyRNA *prop, int index)
{
const bool is_rna = (prop->magic == RNA_MAGIC);
const char *propname = RNA_property_identifier(prop);
diff --git a/source/blender/makesrna/intern/rna_pointcloud.c b/source/blender/makesrna/intern/rna_pointcloud.c
index df09bff1aea..904d011fa04 100644
--- a/source/blender/makesrna/intern/rna_pointcloud.c
+++ b/source/blender/makesrna/intern/rna_pointcloud.c
@@ -33,12 +33,22 @@ static PointCloud *rna_pointcloud(const PointerRNA *ptr)
return (PointCloud *)ptr->owner_id;
}
+static float (*get_pointcloud_positions(PointCloud *pointcloud))[3]
+{
+ return (float(*)[3])CustomData_get_layer_named(&pointcloud->pdata, CD_PROP_FLOAT3, "position");
+}
+
+static const float (*get_pointcloud_positions_const(const PointCloud *pointcloud))[3]
+{
+ return (const float(*)[3])CustomData_get_layer_named(
+ &pointcloud->pdata, CD_PROP_FLOAT3, "position");
+}
+
static int rna_Point_index_get_const(const PointerRNA *ptr)
{
const PointCloud *pointcloud = rna_pointcloud(ptr);
const float(*co)[3] = ptr->data;
- const float(*positions)[3] = (const float(*)[3])CustomData_get_layer_named(
- &pointcloud->pdata, CD_PROP_FLOAT3, "position");
+ const float(*positions)[3] = get_pointcloud_positions_const(pointcloud);
return (int)(co - positions);
}
@@ -55,11 +65,25 @@ static int rna_PointCloud_points_length(PointerRNA *ptr)
static void rna_PointCloud_points_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
- const PointCloud *pointcloud = rna_pointcloud(ptr);
- const float(*positions)[3] = (const float(*)[3])CustomData_get_layer_named(
- &pointcloud->pdata, CD_PROP_FLOAT3, "position");
- rna_iterator_array_begin(
- iter, (void *)positions, sizeof(float[3]), pointcloud->totpoint, false, NULL);
+ PointCloud *pointcloud = rna_pointcloud(ptr);
+ rna_iterator_array_begin(iter,
+ get_pointcloud_positions(pointcloud),
+ sizeof(float[3]),
+ pointcloud->totpoint,
+ false,
+ NULL);
+}
+
+int rna_PointCloud_points_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
+{
+ PointCloud *pointcloud = rna_pointcloud(ptr);
+ if (index < 0 || index >= pointcloud->totpoint) {
+ return false;
+ }
+ r_ptr->owner_id = &pointcloud->id;
+ r_ptr->type = &RNA_Point;
+ r_ptr->data = &get_pointcloud_positions(pointcloud)[index];
+ return true;
}
static void rna_Point_location_get(PointerRNA *ptr, float value[3])
@@ -157,7 +181,7 @@ static void rna_def_pointcloud(BlenderRNA *brna)
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_PointCloud_points_length",
- NULL,
+ "rna_PointCloud_points_lookup_int",
NULL,
NULL);
RNA_def_property_ui_text(prop, "Points", "");
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 57f75fe892c..54ccba24247 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -160,6 +160,7 @@ const EnumPropertyItem rna_enum_property_flag_items[] = {
0,
"Update on every keystroke in textedit 'mode'",
""},
+ {PROP_PATH_OUTPUT, "OUTPUT_PATH", 0, "Output Path", ""},
{0, NULL, 0, NULL, NULL},
};
@@ -464,7 +465,7 @@ static void rna_Struct_property_tags_begin(CollectionPropertyIterator *iter, Poi
/* here ptr->data should always be the same as iter->parent.type */
StructRNA *srna = (StructRNA *)ptr->data;
const EnumPropertyItem *tag_defines = RNA_struct_property_tag_defines(srna);
- unsigned int tag_count = tag_defines ? RNA_enum_items_count(tag_defines) : 0;
+ uint tag_count = tag_defines ? RNA_enum_items_count(tag_defines) : 0;
rna_iterator_array_begin(
iter, (void *)tag_defines, sizeof(EnumPropertyItem), tag_count, 0, NULL);
@@ -729,6 +730,12 @@ static bool rna_Property_is_library_editable_flag_get(PointerRNA *ptr)
return (prop->flag & PROP_LIB_EXCEPTION) != 0;
}
+static bool rna_Property_is_path_output_flag_get(PointerRNA *ptr)
+{
+ PropertyRNA *prop = (PropertyRNA *)ptr->data;
+ return (prop->flag & PROP_PATH_OUTPUT) != 0;
+}
+
static int rna_Property_tags_get(PointerRNA *ptr)
{
return RNA_property_tags(ptr->data);
@@ -3023,6 +3030,12 @@ static void rna_def_property(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Library Editable", "Property is editable from linked instances (changes not saved)");
+ prop = RNA_def_property(srna, "is_path_output", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_boolean_funcs(prop, "rna_Property_is_path_output_flag_get", NULL);
+ RNA_def_property_ui_text(
+ prop, "Path Output", "Property is a filename, filepath or directory output");
+
prop = RNA_def_property(srna, "tags", PROP_ENUM, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_items(prop, dummy_prop_tags);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index e2b3276c45f..fde8fcf651c 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -476,6 +476,20 @@ const EnumPropertyItem rna_enum_bake_save_mode_items[] = {
{0, NULL, 0, NULL, NULL},
};
+const EnumPropertyItem rna_enum_bake_view_from_items[] = {
+ {R_BAKE_VIEW_FROM_ABOVE_SURFACE,
+ "ABOVE_SURFACE",
+ 0,
+ "Above Surface",
+ "Cast rays from above the surface"},
+ {R_BAKE_VIEW_FROM_ACTIVE_CAMERA,
+ "ACTIVE_CAMERA",
+ 0,
+ "Active Camera",
+ "Use the active camera's position to cast rays"},
+ {0, NULL, 0, NULL, NULL},
+};
+
#define R_IMF_VIEWS_ENUM_IND \
{R_IMF_VIEWS_INDIVIDUAL, \
"INDIVIDUAL", \
@@ -706,7 +720,9 @@ static void rna_GPencil_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UN
static void rna_Gpencil_extend_selection(bContext *C, PointerRNA *UNUSED(ptr))
{
/* Extend selection to all points in all selected strokes. */
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if ((ob) && (ob->type == OB_GPENCIL)) {
bGPdata *gpd = (bGPdata *)ob->data;
@@ -1236,8 +1252,10 @@ static void rna_ImageFormatSettings_file_format_set(PointerRNA *ptr, int value)
(is_render ? IMA_CHAN_FLAG_BW : 0);
/* ensure depth and color settings match */
- if (((imf->planes == R_IMF_PLANES_BW) && !(chan_flag & IMA_CHAN_FLAG_BW)) ||
- ((imf->planes == R_IMF_PLANES_RGBA) && !(chan_flag & IMA_CHAN_FLAG_ALPHA))) {
+ if ((imf->planes == R_IMF_PLANES_BW) && !(chan_flag & IMA_CHAN_FLAG_BW)) {
+ imf->planes = R_IMF_PLANES_RGBA;
+ }
+ if ((imf->planes == R_IMF_PLANES_RGBA) && !(chan_flag & IMA_CHAN_FLAG_RGBA)) {
imf->planes = R_IMF_PLANES_RGB;
}
@@ -1317,12 +1335,12 @@ static const EnumPropertyItem *rna_ImageFormatSettings_color_mode_itemf(bContext
RenderData *rd = &scene->r;
if (BKE_ffmpeg_alpha_channel_is_supported(rd)) {
- chan_flag |= IMA_CHAN_FLAG_ALPHA;
+ chan_flag |= IMA_CHAN_FLAG_RGBA;
}
}
# endif
- if (chan_flag == (IMA_CHAN_FLAG_BW | IMA_CHAN_FLAG_RGB | IMA_CHAN_FLAG_ALPHA)) {
+ if (chan_flag == (IMA_CHAN_FLAG_BW | IMA_CHAN_FLAG_RGB | IMA_CHAN_FLAG_RGBA)) {
return rna_enum_image_color_mode_items;
}
else {
@@ -1335,7 +1353,7 @@ static const EnumPropertyItem *rna_ImageFormatSettings_color_mode_itemf(bContext
if (chan_flag & IMA_CHAN_FLAG_RGB) {
RNA_enum_item_add(&item, &totitem, &IMAGE_COLOR_MODE_RGB);
}
- if (chan_flag & IMA_CHAN_FLAG_ALPHA) {
+ if (chan_flag & IMA_CHAN_FLAG_RGBA) {
RNA_enum_item_add(&item, &totitem, &IMAGE_COLOR_MODE_RGBA);
}
@@ -1862,13 +1880,17 @@ static void rna_Scene_editmesh_select_mode_set(PointerRNA *ptr, const bool *valu
/* Update select mode in all the workspaces in mesh edit mode. */
wmWindowManager *wm = G_MAIN->wm.first;
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
-
- if (view_layer && view_layer->basact) {
- Mesh *me = BKE_mesh_from_object(view_layer->basact->object);
- if (me && me->edit_mesh && me->edit_mesh->selectmode != flag) {
- me->edit_mesh->selectmode = flag;
- EDBM_selectmode_set(me->edit_mesh);
+ if (view_layer) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *object = BKE_view_layer_active_object_get(view_layer);
+ if (object) {
+ Mesh *me = BKE_mesh_from_object(object);
+ if (me && me->edit_mesh && me->edit_mesh->selectmode != flag) {
+ me->edit_mesh->selectmode = flag;
+ EDBM_selectmode_set(me->edit_mesh);
+ }
}
}
}
@@ -1877,11 +1899,14 @@ static void rna_Scene_editmesh_select_mode_set(PointerRNA *ptr, const bool *valu
static void rna_Scene_editmesh_select_mode_update(bContext *C, PointerRNA *UNUSED(ptr))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Mesh *me = NULL;
- if (view_layer->basact) {
- me = BKE_mesh_from_object(view_layer->basact->object);
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *object = BKE_view_layer_active_object_get(view_layer);
+ if (object) {
+ me = BKE_mesh_from_object(object);
if (me && me->edit_mesh == NULL) {
me = NULL;
}
@@ -2220,11 +2245,14 @@ static char *rna_SequencerToolSettings_path(const PointerRNA *UNUSED(ptr))
/* generic function to recalc geometry */
static void rna_EditMesh_update(bContext *C, PointerRNA *UNUSED(ptr))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Mesh *me = NULL;
- if (view_layer->basact) {
- me = BKE_mesh_from_object(view_layer->basact->object);
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *object = BKE_view_layer_active_object_get(view_layer);
+ if (object) {
+ me = BKE_mesh_from_object(object);
if (me && me->edit_mesh == NULL) {
me = NULL;
}
@@ -2248,7 +2276,9 @@ static char *rna_MeshStatVis_path(const PointerRNA *UNUSED(ptr))
* given its own notifier. */
static void rna_Scene_update_active_object_data(bContext *C, PointerRNA *UNUSED(ptr))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ob) {
@@ -2565,8 +2595,8 @@ static const EnumPropertyItem *rna_TransformOrientation_impl_itemf(Scene *scene,
if (include_default) {
tmp.identifier = "DEFAULT";
- tmp.name = "Default";
- tmp.description = "Use the scene orientation";
+ tmp.name = N_("Default");
+ tmp.description = N_("Use the scene orientation");
tmp.value = V3D_ORIENT_DEFAULT;
tmp.icon = ICON_OBJECT_ORIGIN;
RNA_enum_item_add(&item, &totitem, &tmp);
@@ -4587,6 +4617,7 @@ void rna_def_view_layer_common(BlenderRNA *brna, StructRNA *srna, const bool sce
prop = RNA_def_property(srna, "use_pass_object_index", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_INDEXOB);
RNA_def_property_ui_text(prop, "Object Index", "Deliver object index pass");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_SCENE);
if (scene) {
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
}
@@ -5397,6 +5428,11 @@ static void rna_def_bake_data(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Save Mode", "Where to save baked image textures");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ prop = RNA_def_property(srna, "view_from", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_enum_bake_view_from_items);
+ RNA_def_property_ui_text(prop, "View From", "Source of reflection ray directions");
+ 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);
@@ -5909,7 +5945,8 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna)
{AV_CODEC_ID_PNG, "PNG", 0, "PNG", ""},
{AV_CODEC_ID_QTRLE, "QTRLE", 0, "QT rle / QT Animation", ""},
{AV_CODEC_ID_THEORA, "THEORA", 0, "Theora", ""},
- {AV_CODEC_ID_VP9, "WEBM", 0, "WEBM / VP9", ""},
+ {AV_CODEC_ID_VP9, "WEBM", 0, "WebM / VP9", ""},
+ {AV_CODEC_ID_AV1, "AV1", 0, "AV1", ""},
{0, NULL, 0, NULL, NULL},
};
@@ -6539,6 +6576,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
"Output Path",
"Directory/name to save animations, # characters defines the position "
"and length of frame numbers");
+ RNA_def_property_flag(prop, PROP_PATH_OUTPUT);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
/* Render result EXR cache. */
@@ -7824,6 +7862,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_ui_text(prop, "World", "World used for rendering the scene");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_WORLD);
RNA_def_property_update(prop, NC_SCENE | ND_WORLD, "rna_Scene_world_update");
prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index 42523508c14..c5e7c6a6e91 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -9,6 +9,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -33,6 +34,8 @@
#include "bmesh.h"
+extern const EnumPropertyItem RNA_automasking_flags[];
+
const EnumPropertyItem rna_enum_particle_edit_hair_brush_items[] = {
{PE_BRUSH_COMB, "COMB", 0, "Comb", "Comb hairs"},
{PE_BRUSH_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth hairs"},
@@ -165,6 +168,7 @@ static void rna_ParticleEdit_redo(bContext *C, PointerRNA *UNUSED(ptr))
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
PTCacheEdit *edit = PE_get_current(depsgraph, scene, ob);
@@ -185,6 +189,7 @@ static void rna_ParticleEdit_update(bContext *C, PointerRNA *UNUSED(ptr))
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ob) {
@@ -215,7 +220,9 @@ static const EnumPropertyItem *rna_ParticleEdit_tool_itemf(bContext *C,
PropertyRNA *UNUSED(prop),
bool *UNUSED(r_free))
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
# if 0
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
@@ -374,6 +381,7 @@ static void rna_Sculpt_update(bContext *C, PointerRNA *UNUSED(ptr))
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ob) {
@@ -389,12 +397,13 @@ static void rna_Sculpt_update(bContext *C, PointerRNA *UNUSED(ptr))
static void rna_Sculpt_ShowMask_update(bContext *C, PointerRNA *UNUSED(ptr))
{
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *object = BKE_view_layer_active_object_get(view_layer);
if (object == NULL || object->sculpt == NULL) {
return;
}
- Scene *scene = CTX_data_scene(C);
Sculpt *sd = scene->toolsettings->sculpt;
object->sculpt->show_mask = ((sd->flags & SCULPT_HIDE_MASK) == 0);
if (object->sculpt->pbvh != NULL) {
@@ -488,6 +497,7 @@ static void rna_ImaPaint_mode_update(bContext *C, PointerRNA *UNUSED(ptr))
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ob && ob->type == OB_MESH) {
@@ -505,6 +515,7 @@ static void rna_ImaPaint_stencil_update(bContext *C, PointerRNA *UNUSED(ptr))
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ob && ob->type == OB_MESH) {
@@ -524,25 +535,11 @@ static void rna_ImaPaint_canvas_update(bContext *C, PointerRNA *UNUSED(ptr))
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
- bScreen *screen;
Image *ima = scene->toolsettings->imapaint.canvas;
- for (screen = bmain->screens.first; screen; screen = screen->id.next) {
- ScrArea *area;
- for (area = screen->areabase.first; area; area = area->next) {
- SpaceLink *slink;
- for (slink = area->spacedata.first; slink; slink = slink->next) {
- if (slink->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = (SpaceImage *)slink;
-
- if (!sima->pin) {
- ED_space_image_set(bmain, sima, ima, true);
- }
- }
- }
- }
- }
+ ED_space_image_sync(bmain, ima, false);
if (ob && ob->type == OB_MESH) {
ED_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
@@ -589,6 +586,31 @@ static char *rna_GPencilSculptGuide_path(const PointerRNA *UNUSED(ptr))
return BLI_strdup("tool_settings.gpencil_sculpt.guide");
}
+static void rna_Sculpt_automasking_invert_cavity_set(PointerRNA *ptr, bool val)
+{
+ Sculpt *sd = (Sculpt *)ptr->data;
+
+ if (val) {
+ sd->automasking_flags &= ~BRUSH_AUTOMASKING_CAVITY_NORMAL;
+ sd->automasking_flags |= BRUSH_AUTOMASKING_CAVITY_INVERTED;
+ }
+ else {
+ sd->automasking_flags &= ~BRUSH_AUTOMASKING_CAVITY_INVERTED;
+ }
+}
+
+static void rna_Sculpt_automasking_cavity_set(PointerRNA *ptr, bool val)
+{
+ Sculpt *sd = (Sculpt *)ptr->data;
+
+ if (val) {
+ sd->automasking_flags &= ~BRUSH_AUTOMASKING_CAVITY_INVERTED;
+ sd->automasking_flags |= BRUSH_AUTOMASKING_CAVITY_NORMAL;
+ }
+ else {
+ sd->automasking_flags &= ~BRUSH_AUTOMASKING_CAVITY_NORMAL;
+ }
+}
#else
static void rna_def_paint_curve(BlenderRNA *brna)
@@ -874,32 +896,98 @@ static void rna_def_sculpt(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_update");
- prop = RNA_def_property(srna, "use_automasking_topology", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_TOPOLOGY);
- RNA_def_property_ui_text(prop,
- "Topology Auto-Masking",
- "Affect only vertices connected to the active vertex under the brush");
+ const EnumPropertyItem *entry = RNA_automasking_flags;
+ do {
+ prop = RNA_def_property(srna, entry->identifier, PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", entry->value);
+ RNA_def_property_ui_text(prop, entry->name, entry->description);
+
+ if (entry->value == BRUSH_AUTOMASKING_CAVITY_NORMAL) {
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_Sculpt_automasking_cavity_set");
+ }
+ else if (entry->value == BRUSH_AUTOMASKING_CAVITY_INVERTED) {
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_Sculpt_automasking_invert_cavity_set");
+ }
+
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+ } while ((++entry)->identifier);
+
+ prop = RNA_def_property(srna, "automasking_cavity_factor", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "automasking_cavity_factor");
+ RNA_def_property_ui_text(prop, "Cavity Factor", "The contrast of the cavity mask");
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_range(prop, 0.0f, 5.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
- prop = RNA_def_property(srna, "use_automasking_face_sets", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_FACE_SETS);
- RNA_def_property_ui_text(prop,
- "Face Sets Auto-Masking",
- "Affect only vertices that share Face Sets with the active vertex");
+ prop = RNA_def_property(srna, "automasking_cavity_blur_steps", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "automasking_cavity_blur_steps");
+ RNA_def_property_ui_text(prop, "Blur Steps", "The number of times the cavity mask is blurred");
+ RNA_def_property_int_default(prop, 0);
+ RNA_def_property_range(prop, 0, 25);
+ RNA_def_property_ui_range(prop, 0, 10, 1, 1);
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
+ prop = RNA_def_property(srna, "automasking_cavity_curve", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "automasking_cavity_curve");
+ RNA_def_property_struct_type(prop, "CurveMapping");
+ RNA_def_property_ui_text(prop, "Cavity Curve", "Curve used for the sensitivity");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
- prop = RNA_def_property(srna, "use_automasking_boundary_edges", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_BOUNDARY_EDGES);
+ prop = RNA_def_property(srna, "automasking_cavity_curve_op", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "automasking_cavity_curve_op");
+ RNA_def_property_struct_type(prop, "CurveMapping");
+ RNA_def_property_ui_text(prop, "Cavity Curve", "Curve used for the sensitivity");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
+ prop = RNA_def_property(srna, "use_automasking_start_normal", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_BRUSH_NORMAL);
RNA_def_property_ui_text(
- prop, "Mesh Boundary Auto-Masking", "Do not affect non manifold boundary edges");
+ prop,
+ "Area Normal",
+ "Affect only vertices with a similar normal to where the stroke starts");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
- prop = RNA_def_property(srna, "use_automasking_boundary_face_sets", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(
- prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS);
- RNA_def_property_ui_text(prop,
- "Face Sets Boundary Auto-Masking",
- "Do not affect vertices that belong to a Face Set boundary");
+ prop = RNA_def_property(srna, "use_automasking_view_normal", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_VIEW_NORMAL);
+ RNA_def_property_ui_text(
+ prop, "View Normal", "Affect only vertices with a normal that faces the viewer");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
+ prop = RNA_def_property(srna, "use_automasking_view_occlusion", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_VIEW_OCCLUSION);
+ RNA_def_property_ui_text(
+ prop,
+ "Occlusion",
+ "Only affect vertices that are not occluded by other faces. (Slower performance)");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
+ prop = RNA_def_property(srna, "automasking_start_normal_limit", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "automasking_start_normal_limit");
+ RNA_def_property_range(prop, 0.0001f, M_PI);
+ RNA_def_property_ui_text(prop, "Area Normal Limit", "The range of angles that will be affected");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
+ prop = RNA_def_property(srna, "automasking_start_normal_falloff", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "automasking_start_normal_falloff");
+ RNA_def_property_range(prop, 0.0001f, 1.0f);
+ RNA_def_property_ui_text(
+ prop, "Area Normal Falloff", "Extend the angular range with a falloff gradient");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
+ prop = RNA_def_property(srna, "automasking_view_normal_limit", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "automasking_view_normal_limit");
+ RNA_def_property_range(prop, 0.0001f, M_PI);
+ RNA_def_property_ui_text(prop, "View Normal Limit", "The range of angles that will be affected");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
+ prop = RNA_def_property(srna, "automasking_view_normal_falloff", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "automasking_view_normal_falloff");
+ RNA_def_property_range(prop, 0.0001f, 1.0f);
+ RNA_def_property_ui_text(
+ prop, "View Normal Falloff", "Extend the angular range with a falloff gradient");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "symmetrize_direction", PROP_ENUM, PROP_NONE);
@@ -1550,6 +1638,36 @@ static void rna_def_gpencil_sculpt(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+ prop = RNA_def_property(srna, "use_automasking_stroke", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SCULPT_SETT_FLAG_AUTOMASK_STROKE);
+ RNA_def_property_ui_text(prop, "Auto-Masking Strokes", "Affect only strokes below the cursor");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
+ prop = RNA_def_property(srna, "use_automasking_layer_stroke", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_STROKE);
+ RNA_def_property_ui_text(prop, "Auto-Masking Layer", "Affect only strokes below the cursor");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
+ prop = RNA_def_property(srna, "use_automasking_material_stroke", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_STROKE);
+ RNA_def_property_ui_text(prop, "Auto-Masking Material", "Affect only strokes below the cursor");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
+ prop = RNA_def_property(srna, "use_automasking_layer_active", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_ACTIVE);
+ RNA_def_property_ui_text(prop, "Auto-Masking Layer", "Affect only the Active Layer");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
+ prop = RNA_def_property(srna, "use_automasking_material_active", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_ACTIVE);
+ RNA_def_property_ui_text(prop, "Auto-Masking Material", "Affect only the Active Material");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
/* custom falloff curve */
prop = RNA_def_property(srna, "multiframe_falloff_curve", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "cur_falloff");
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index aa40ee846bf..a10c64e292e 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -330,7 +330,6 @@ static void rna_Sequence_start_frame_final_set(PointerRNA *ptr, int value)
Scene *scene = (Scene *)ptr->owner_id;
SEQ_time_left_handle_frame_set(scene, seq, value);
- SEQ_transform_fix_single_image_seq_offsets(scene, seq);
do_sequence_frame_change_update(scene, seq);
SEQ_relations_invalidate_cache_composite(scene, seq);
}
@@ -341,7 +340,6 @@ static void rna_Sequence_end_frame_final_set(PointerRNA *ptr, int value)
Scene *scene = (Scene *)ptr->owner_id;
SEQ_time_right_handle_frame_set(scene, seq, value);
- SEQ_transform_fix_single_image_seq_offsets(scene, seq);
do_sequence_frame_change_update(scene, seq);
SEQ_relations_invalidate_cache_composite(scene, seq);
}
@@ -778,7 +776,7 @@ static void rna_Sequence_filepath_get(PointerRNA *ptr, char *value)
{
Sequence *seq = (Sequence *)(ptr->data);
- BLI_join_dirfile(value, FILE_MAX, seq->strip->dir, seq->strip->stripdata->name);
+ BLI_path_join(value, FILE_MAX, seq->strip->dir, seq->strip->stripdata->name);
}
static int rna_Sequence_filepath_length(PointerRNA *ptr)
@@ -786,7 +784,7 @@ static int rna_Sequence_filepath_length(PointerRNA *ptr)
Sequence *seq = (Sequence *)(ptr->data);
char path[FILE_MAX];
- BLI_join_dirfile(path, sizeof(path), seq->strip->dir, seq->strip->stripdata->name);
+ BLI_path_join(path, sizeof(path), seq->strip->dir, seq->strip->stripdata->name);
return strlen(path);
}
@@ -804,7 +802,7 @@ static void rna_Sequence_proxy_filepath_get(PointerRNA *ptr, char *value)
{
StripProxy *proxy = (StripProxy *)(ptr->data);
- BLI_join_dirfile(value, FILE_MAX, proxy->dir, proxy->file);
+ BLI_path_join(value, FILE_MAX, proxy->dir, proxy->file);
}
static int rna_Sequence_proxy_filepath_length(PointerRNA *ptr)
@@ -812,7 +810,7 @@ static int rna_Sequence_proxy_filepath_length(PointerRNA *ptr)
StripProxy *proxy = (StripProxy *)(ptr->data);
char path[FILE_MAX];
- BLI_join_dirfile(path, sizeof(path), proxy->dir, proxy->file);
+ BLI_path_join(path, sizeof(path), proxy->dir, proxy->file);
return strlen(path);
}
@@ -2247,6 +2245,7 @@ static void rna_def_editor(BlenderRNA *brna)
prop = RNA_def_property(srna, "proxy_storage", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, editing_storage_items);
RNA_def_property_ui_text(prop, "Proxy Storage", "How to store proxies for this project");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_SEQUENCE);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, "rna_SequenceEditor_update_cache");
prop = RNA_def_property(srna, "proxy_dir", PROP_STRING, PROP_DIRPATH);
@@ -2892,6 +2891,7 @@ static void rna_def_wipe(StructRNA *srna)
RNA_def_property_enum_sdna(prop, NULL, "forward");
RNA_def_property_enum_items(prop, wipe_direction_items);
RNA_def_property_ui_text(prop, "Direction", "Wipe direction");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_SEQUENCE);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update");
prop = RNA_def_property(srna, "transition_type", PROP_ENUM, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 5fa1033bcd4..af15311031b 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -19,6 +19,7 @@
#include "BKE_movieclip.h"
#include "BKE_node.h"
#include "BKE_studiolight.h"
+#include "BKE_viewer_path.h"
#include "ED_asset.h"
#include "ED_spreadsheet.h"
@@ -430,7 +431,11 @@ static const EnumPropertyItem rna_enum_shading_color_type_items[] = {
{V3D_SHADING_OBJECT_COLOR, "OBJECT", 0, "Object", "Show object color"},
{V3D_SHADING_RANDOM_COLOR, "RANDOM", 0, "Random", "Show random object color"},
{V3D_SHADING_VERTEX_COLOR, "VERTEX", 0, "Attribute", "Show active color attribute"},
- {V3D_SHADING_TEXTURE_COLOR, "TEXTURE", 0, "Texture", "Show texture"},
+ {V3D_SHADING_TEXTURE_COLOR,
+ "TEXTURE",
+ 0,
+ "Texture",
+ "Show the texture from the active image texture node using the active UV map coordinates"},
{0, NULL, 0, NULL, NULL},
};
@@ -540,6 +545,7 @@ static const EnumPropertyItem rna_enum_curve_display_handle_items[] = {
# include "BLI_string.h"
# include "BKE_anim_data.h"
+# include "BKE_asset.h"
# include "BKE_brush.h"
# include "BKE_colortools.h"
# include "BKE_context.h"
@@ -1006,6 +1012,13 @@ static PointerRNA rna_SpaceView3D_region_3d_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_RegionView3D, regiondata);
}
+static void rna_SpaceView3D_object_type_visibility_update(Main *UNUSED(bmain),
+ Scene *scene,
+ PointerRNA *UNUSED(ptr))
+{
+ DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
+}
+
static void rna_SpaceView3D_region_quadviews_begin(CollectionPropertyIterator *iter,
PointerRNA *ptr)
{
@@ -1550,7 +1563,7 @@ static void rna_SpaceView3D_use_local_collections_update(bContext *C, PointerRNA
View3D *v3d = (View3D *)ptr->data;
if (ED_view3d_local_collections_set(bmain, v3d)) {
- BKE_layer_collection_local_sync(view_layer, v3d);
+ BKE_layer_collection_local_sync(scene, view_layer, v3d);
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
}
}
@@ -1694,7 +1707,9 @@ static bool rna_SpaceImageEditor_show_uvedit_get(PointerRNA *ptr)
Object *obedit = NULL;
wmWindow *win = ED_screen_window_find(screen, G_MAIN->wm.first);
if (win != NULL) {
+ Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ BKE_view_layer_synced_ensure(scene, view_layer);
obedit = BKE_view_layer_edit_object_get(view_layer);
}
return ED_space_image_show_uvedit(sima, obedit);
@@ -1707,7 +1722,9 @@ static bool rna_SpaceImageEditor_show_maskedit_get(PointerRNA *ptr)
Object *obedit = NULL;
wmWindow *win = ED_screen_window_find(screen, G_MAIN->wm.first);
if (win != NULL) {
+ Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ BKE_view_layer_synced_ensure(scene, view_layer);
obedit = BKE_view_layer_edit_object_get(view_layer);
}
return ED_space_image_check_show_maskedit(sima, obedit);
@@ -1903,6 +1920,15 @@ static void rna_SpaceUVEditor_tile_grid_shape_set(PointerRNA *ptr, const int *va
}
}
+static void rna_SpaceUVEditor_custom_grid_subdiv_set(PointerRNA *ptr, const int *values)
+{
+ SpaceImage *data = (SpaceImage *)(ptr->data);
+
+ for (int i = 0; i < 2; i++) {
+ data->custom_grid_subdiv[i] = CLAMPIS(values[i], 1, 5000);
+ }
+}
+
/* Space Text Editor */
static void rna_SpaceTextEditor_word_wrap_set(PointerRNA *ptr, bool value)
@@ -2205,9 +2231,11 @@ static void rna_SpaceDopeSheetEditor_action_set(PointerRNA *ptr,
static void rna_SpaceDopeSheetEditor_action_update(bContext *C, PointerRNA *ptr)
{
SpaceAction *saction = (SpaceAction *)(ptr->data);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Main *bmain = CTX_data_main(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obact = BKE_view_layer_active_object_get(view_layer);
if (obact == NULL) {
return;
@@ -2280,7 +2308,9 @@ static void rna_SpaceDopeSheetEditor_mode_update(bContext *C, PointerRNA *ptr)
{
SpaceAction *saction = (SpaceAction *)(ptr->data);
ScrArea *area = CTX_wm_area(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obact = BKE_view_layer_active_object_get(view_layer);
/* special exceptions for ShapeKey Editor mode */
@@ -2753,18 +2783,24 @@ static PointerRNA rna_FileBrowser_FileSelectEntry_asset_data_get(PointerRNA *ptr
{
const FileDirEntry *entry = ptr->data;
+ if (!entry->asset) {
+ return PointerRNA_NULL;
+ }
+
+ AssetMetaData *asset_data = BKE_asset_representation_metadata_get(entry->asset);
+
/* Note that the owning ID of the RNA pointer (`ptr->owner_id`) has to be set carefully:
* Local IDs (`entry->id`) own their asset metadata themselves. Asset metadata from other blend
* files are owned by the file browser (`entry`). Only if this is set correctly, we can tell from
* the metadata RNA pointer if the metadata is stored locally and can thus be edited or not. */
- if (entry->id) {
+ if (BKE_asset_representation_is_local_id(entry->asset)) {
PointerRNA id_ptr;
RNA_id_pointer_create(entry->id, &id_ptr);
- return rna_pointer_inherit_refine(&id_ptr, &RNA_AssetMetaData, entry->asset_data);
+ return rna_pointer_inherit_refine(&id_ptr, &RNA_AssetMetaData, asset_data);
}
- return rna_pointer_inherit_refine(ptr, &RNA_AssetMetaData, entry->asset_data);
+ return rna_pointer_inherit_refine(ptr, &RNA_AssetMetaData, asset_data);
}
static int rna_FileBrowser_FileSelectEntry_name_editable(PointerRNA *ptr, const char **r_info)
@@ -2774,7 +2810,7 @@ static int rna_FileBrowser_FileSelectEntry_name_editable(PointerRNA *ptr, const
/* This actually always returns 0 (the name is never editable) but we want to get a disabled
* message returned to `r_info` in some cases. */
- if (entry->asset_data) {
+ if (entry->asset) {
PointerRNA asset_data_ptr = rna_FileBrowser_FileSelectEntry_asset_data_get(ptr);
/* Get disabled hint from asset metadata polling. */
rna_AssetMetaData_editable(&asset_data_ptr, r_info);
@@ -3283,59 +3319,21 @@ const EnumPropertyItem *rna_SpaceSpreadsheet_attribute_domain_itemf(bContext *UN
return item_array;
}
-static SpreadsheetContext *rna_SpaceSpreadsheet_context_path_append(SpaceSpreadsheet *sspreadsheet,
- int type)
-{
- SpreadsheetContext *context = ED_spreadsheet_context_new(type);
- BLI_addtail(&sspreadsheet->context_path, context);
- ED_spreadsheet_context_path_update_tag(sspreadsheet);
- WM_main_add_notifier(NC_SPACE | ND_SPACE_SPREADSHEET, NULL);
- return context;
-}
-
-static void rna_SpaceSpreadsheet_context_path_clear(SpaceSpreadsheet *sspreadsheet)
+static StructRNA *rna_viewer_path_elem_refine(PointerRNA *ptr)
{
- ED_spreadsheet_context_path_clear(sspreadsheet);
- ED_spreadsheet_context_path_update_tag(sspreadsheet);
- WM_main_add_notifier(NC_SPACE | ND_SPACE_SPREADSHEET, NULL);
-}
-
-static StructRNA *rna_spreadsheet_context_refine(PointerRNA *ptr)
-{
- SpreadsheetContext *context = ptr->data;
- switch (context->type) {
- case SPREADSHEET_CONTEXT_OBJECT:
- return &RNA_SpreadsheetContextObject;
- case SPREADSHEET_CONTEXT_MODIFIER:
- return &RNA_SpreadsheetContextModifier;
- case SPREADSHEET_CONTEXT_NODE:
- return &RNA_SpreadsheetContextNode;
+ ViewerPathElem *elem = ptr->data;
+ switch (elem->type) {
+ case VIEWER_PATH_ELEM_TYPE_ID:
+ return &RNA_IDViewerPathElem;
+ case VIEWER_PATH_ELEM_TYPE_MODIFIER:
+ return &RNA_ModifierViewerPathElem;
+ case VIEWER_PATH_ELEM_TYPE_NODE:
+ return &RNA_NodeViewerPathElem;
}
BLI_assert_unreachable();
return NULL;
}
-static void rna_spreadsheet_context_update(Main *UNUSED(bmain),
- Scene *UNUSED(scene),
- PointerRNA *ptr)
-{
- bScreen *screen = (bScreen *)ptr->owner_id;
- LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
- SpaceLink *sl = area->spacedata.first;
- if (sl->spacetype == SPACE_SPREADSHEET) {
- SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
- ED_spreadsheet_context_path_update_tag(sspreadsheet);
- }
- }
-}
-
-static void rna_SpaceSpreadsheet_context_path_guess(SpaceSpreadsheet *sspreadsheet, bContext *C)
-{
- ED_spreadsheet_context_path_guess(C, sspreadsheet);
- ED_spreadsheet_context_path_update_tag(sspreadsheet);
- WM_main_add_notifier(NC_SPACE | ND_SPACE_SPREADSHEET, NULL);
-}
-
static void rna_FileAssetSelectParams_catalog_id_get(PointerRNA *ptr, char *value)
{
const FileAssetSelectParams *params = ptr->data;
@@ -3571,10 +3569,17 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL},
};
- static const EnumPropertyItem pixel_snap_mode_items[] = {
- {SI_PIXEL_SNAP_DISABLED, "DISABLED", 0, "Disabled", "Don't snap to pixels"},
- {SI_PIXEL_SNAP_CORNER, "CORNER", 0, "Corner", "Snap to pixel corners"},
- {SI_PIXEL_SNAP_CENTER, "CENTER", 0, "Center", "Snap to pixel centers"},
+ static const EnumPropertyItem pixel_round_mode_items[] = {
+ {SI_PIXEL_ROUND_DISABLED, "DISABLED", 0, "Disabled", "Don't round to pixels"},
+ {SI_PIXEL_ROUND_CORNER, "CORNER", 0, "Corner", "Round to pixel corners"},
+ {SI_PIXEL_ROUND_CENTER, "CENTER", 0, "Center", "Round to pixel centers"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ static const EnumPropertyItem grid_shape_source_items[] = {
+ {SI_GRID_SHAPE_DYNAMIC, "DYNAMIC", 0, "Dynamic", "Dynamic grid"},
+ {SI_GRID_SHAPE_FIXED, "FIXED", 0, "Fixed", "Manually set grid divisions"},
+ {SI_GRID_SHAPE_PIXEL, "PIXEL", 0, "Pixel", "Grid aligns with pixels from image"},
{0, NULL, 0, NULL, NULL},
};
@@ -3645,15 +3650,23 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
prop, "Tile Grid Shape", "How many tiles will be shown in the background");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
- prop = RNA_def_property(srna, "use_custom_grid", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_CUSTOM_GRID);
+ prop = RNA_def_property(srna, "show_grid_over_image", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_GRID_OVER_IMAGE);
RNA_def_property_boolean_default(prop, true);
- RNA_def_property_ui_text(prop, "Custom Grid", "Use a grid with a user-defined number of steps");
+ RNA_def_property_ui_text(prop, "Grid Over Image", "Show the grid over the image");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
+
+ prop = RNA_def_property(srna, "grid_shape_source", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, grid_shape_source_items);
+ RNA_def_property_ui_text(prop, "Grid Shape Source", "Specify source for the grid shape");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
- prop = RNA_def_property(srna, "custom_grid_subdivisions", PROP_INT, PROP_NONE);
+ prop = RNA_def_property(srna, "custom_grid_subdivisions", PROP_INT, PROP_XYZ);
RNA_def_property_int_sdna(prop, NULL, "custom_grid_subdiv");
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_int_default(prop, 10);
RNA_def_property_range(prop, 1, 5000);
+ RNA_def_property_int_funcs(prop, NULL, "rna_SpaceUVEditor_custom_grid_subdiv_set", NULL);
RNA_def_property_ui_text(
prop, "Dynamic Grid Size", "Number of grid units in UV space that make one UV Unit");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
@@ -3664,11 +3677,9 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "UV Opacity", "Opacity of UV overlays");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
- /* TODO: move edge and face drawing options here from `G.f`. */
-
- prop = RNA_def_property(srna, "pixel_snap_mode", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, pixel_snap_mode_items);
- RNA_def_property_ui_text(prop, "Snap to Pixels", "Snap UVs to pixels while editing");
+ prop = RNA_def_property(srna, "pixel_round_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, pixel_round_mode_items);
+ RNA_def_property_ui_text(prop, "Round to Pixels", "Round UVs to pixels while editing");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
prop = RNA_def_property(srna, "lock_bounds", PROP_BOOLEAN, PROP_NONE);
@@ -4038,6 +4049,7 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
prop = RNA_def_property(srna, "cavity_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, cavity_type_items);
RNA_def_property_ui_text(prop, "Cavity Type", "Way to display the cavity shading");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_EDITOR_VIEW3D);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D | NS_VIEW3D_SHADING, NULL);
prop = RNA_def_property(srna, "curvature_ridge_factor", PROP_FLOAT, PROP_FACTOR);
@@ -4147,6 +4159,7 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
prop = RNA_def_property(srna, "background_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, background_type_items);
RNA_def_property_ui_text(prop, "Background", "Way to display the background");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_EDITOR_VIEW3D);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D | NS_VIEW3D_SHADING, NULL);
prop = RNA_def_property(srna, "background_color", PROP_FLOAT, PROP_COLOR);
@@ -4479,6 +4492,20 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ prop = RNA_def_property(srna, "show_viewer_attribute", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_VIEWER_ATTRIBUTE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Viewer Node", "Show attribute overlay for active viewer node");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "viewer_attribute_opacity", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "overlay.viewer_attribute_opacity");
+ RNA_def_property_ui_text(
+ prop, "Viewer Attribute Opacity", "Opacity of the attribute that is currently visualized");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
prop = RNA_def_property(srna, "show_paint_wire", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "overlay.paint_flag", V3D_OVERLAY_PAINT_WIRE);
RNA_def_property_ui_text(prop, "Show Wire", "Use wireframe display in painting modes");
@@ -5121,7 +5148,8 @@ static void rna_def_space_view3d(BlenderRNA *brna)
prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_mirror_xr_session_update");
rna_def_object_type_visibility_flags_common(srna,
- NC_SPACE | ND_SPACE_VIEW3D | NS_VIEW3D_SHADING);
+ NC_SPACE | ND_SPACE_VIEW3D | NS_VIEW3D_SHADING,
+ "rna_SpaceView3D_object_type_visibility_update");
/* Helper for drawing the icon. */
prop = RNA_def_property(srna, "icon_from_show_object_viewport", PROP_INT, PROP_NONE);
@@ -5130,6 +5158,11 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Visibility Icon", "");
+ prop = RNA_def_property(srna, "show_viewer", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHOW_VIEWER);
+ RNA_def_property_ui_text(prop, "Show Viewer", "Display non-final geometry from viewer nodes");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D | NS_VIEW3D_SHADING, NULL);
+
/* Nested Structs */
prop = RNA_def_property(srna, "shading", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
@@ -5306,6 +5339,7 @@ static void rna_def_space_properties(BlenderRNA *brna)
RNA_def_property_enum_funcs(
prop, NULL, "rna_SpaceProperties_context_set", "rna_SpaceProperties_context_itemf");
RNA_def_property_ui_text(prop, "", "");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID);
RNA_def_property_update(
prop, NC_SPACE | ND_SPACE_PROPERTIES, "rna_SpaceProperties_context_update");
@@ -6056,7 +6090,7 @@ static void rna_def_space_dopesheet(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "SpaceAction");
RNA_def_struct_ui_text(srna, "Space Dope Sheet Editor", "Dope Sheet space data");
- rna_def_space_generic_show_region_toggles(srna, (1 << RGN_TYPE_UI));
+ rna_def_space_generic_show_region_toggles(srna, (1 << RGN_TYPE_UI) | (1 << RGN_TYPE_HUD));
/* data */
prop = RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
@@ -6369,7 +6403,7 @@ static void rna_def_space_nla(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "SpaceNla");
RNA_def_struct_ui_text(srna, "Space Nla Editor", "NLA editor space data");
- rna_def_space_generic_show_region_toggles(srna, (1 << RGN_TYPE_UI));
+ rna_def_space_generic_show_region_toggles(srna, (1 << RGN_TYPE_UI) | (1 << RGN_TYPE_HUD));
/* display */
prop = RNA_def_property(srna, "show_seconds", PROP_BOOLEAN, PROP_NONE);
@@ -6603,6 +6637,7 @@ static void rna_def_fileselect_entry(BlenderRNA *brna)
prop,
"Data-block Type",
"The type of the data-block, if the file represents one ('NONE' otherwise)");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID);
prop = RNA_def_property(srna, "local_id", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ID");
@@ -6673,7 +6708,7 @@ static void rna_def_fileselect_params(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Title", "Title for the file browser");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- /* Use BYTESTRING rather than DIRPATH as subtype so UI code doesn't add OT_directory_browse
+ /* Use BYTESTRING rather than DIRPATH as sub-type so UI code doesn't add OT_directory_browse
* button when displaying this prop in the file browser (it would just open a file browser). That
* should be the only effective difference between the two. */
prop = RNA_def_property(srna, "directory", PROP_STRING, PROP_BYTESTRING);
@@ -7355,12 +7390,14 @@ static void rna_def_space_node(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "texfrom");
RNA_def_property_enum_items(prop, texture_id_type_items);
RNA_def_property_ui_text(prop, "Texture Type", "Type of data to take texture from");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE, NULL);
prop = RNA_def_property(srna, "shader_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "shaderfrom");
RNA_def_property_enum_items(prop, shader_type_items);
RNA_def_property_ui_text(prop, "Shader Type", "Type of data to take shader from");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE, NULL);
prop = RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE);
@@ -7556,6 +7593,7 @@ static void rna_def_space_clip(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, rna_enum_clip_editor_mode_items);
RNA_def_property_ui_text(prop, "Mode", "Editing context being displayed");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_MOVIECLIP);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, "rna_SpaceClipEditor_clip_mode_update");
/* view */
@@ -7906,93 +7944,77 @@ static void rna_def_spreadsheet_row_filter(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SPREADSHEET, NULL);
}
-static const EnumPropertyItem spreadsheet_context_type_items[] = {
- {SPREADSHEET_CONTEXT_OBJECT, "OBJECT", ICON_NONE, "Object", ""},
- {SPREADSHEET_CONTEXT_MODIFIER, "MODIFIER", ICON_NONE, "Modifier", ""},
- {SPREADSHEET_CONTEXT_NODE, "NODE", ICON_NONE, "Node", ""},
+static const EnumPropertyItem viewer_path_elem_type_items[] = {
+ {VIEWER_PATH_ELEM_TYPE_ID, "ID", ICON_NONE, "ID", ""},
+ {VIEWER_PATH_ELEM_TYPE_MODIFIER, "MODIFIER", ICON_NONE, "Modifier", ""},
+ {VIEWER_PATH_ELEM_TYPE_NODE, "NODE", ICON_NONE, "Node", ""},
{0, NULL, 0, NULL, NULL},
};
-static void rna_def_space_spreadsheet_context(BlenderRNA *brna)
+static void rna_def_viewer_path_elem(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
- srna = RNA_def_struct(brna, "SpreadsheetContext", NULL);
- RNA_def_struct_ui_text(srna, "Spreadsheet Context", "Element of spreadsheet context path");
- RNA_def_struct_refine_func(srna, "rna_spreadsheet_context_refine");
+ srna = RNA_def_struct(brna, "ViewerPathElem", NULL);
+ RNA_def_struct_ui_text(srna, "Viewer Path Element", "Element of a viewer path");
+ RNA_def_struct_refine_func(srna, "rna_viewer_path_elem_refine");
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, spreadsheet_context_type_items);
- RNA_def_property_ui_text(prop, "Type", "Type of the context");
+ RNA_def_property_enum_items(prop, viewer_path_elem_type_items);
+ RNA_def_property_ui_text(prop, "Type", "Type of the path element");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
- rna_def_space_generic_show_region_toggles(srna,
- (1 << RGN_TYPE_CHANNELS) | (1 << RGN_TYPE_FOOTER));
}
-static void rna_def_space_spreadsheet_context_object(BlenderRNA *brna)
+static void rna_def_id_viewer_path_elem(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
- srna = RNA_def_struct(brna, "SpreadsheetContextObject", "SpreadsheetContext");
+ srna = RNA_def_struct(brna, "IDViewerPathElem", "ViewerPathElem");
- prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
- RNA_def_property_struct_type(prop, "Object");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SPREADSHEET, "rna_spreadsheet_context_update");
+ prop = RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE);
+ RNA_def_property_ui_text(prop, "ID", "");
}
-static void rna_def_space_spreadsheet_context_modifier(BlenderRNA *brna)
+static void rna_def_modifier_viewer_path_elem(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
- srna = RNA_def_struct(brna, "SpreadsheetContextModifier", "SpreadsheetContext");
+ srna = RNA_def_struct(brna, "ModifierViewerPathElem", "ViewerPathElem");
prop = RNA_def_property(srna, "modifier_name", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Modifier Name", "");
- RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SPREADSHEET, "rna_spreadsheet_context_update");
}
-static void rna_def_space_spreadsheet_context_node(BlenderRNA *brna)
+static void rna_def_node_viewer_path_elem(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
- srna = RNA_def_struct(brna, "SpreadsheetContextNode", "SpreadsheetContext");
+ srna = RNA_def_struct(brna, "NodeViewerPathElem", "ViewerPathElem");
prop = RNA_def_property(srna, "node_name", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Node Name", "");
- RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SPREADSHEET, "rna_spreadsheet_context_update");
}
-static void rna_def_space_spreadsheet_context_path(BlenderRNA *brna, PropertyRNA *cprop)
+static void rna_def_viewer_path(BlenderRNA *brna)
{
StructRNA *srna;
- PropertyRNA *parm;
- FunctionRNA *func;
-
- RNA_def_property_srna(cprop, "SpreadsheetContextPath");
- srna = RNA_def_struct(brna, "SpreadsheetContextPath", NULL);
- RNA_def_struct_sdna(srna, "SpaceSpreadsheet");
+ PropertyRNA *prop;
- func = RNA_def_function(srna, "append", "rna_SpaceSpreadsheet_context_path_append");
- RNA_def_function_ui_description(func, "Append a context path element");
- parm = RNA_def_property(func, "type", PROP_ENUM, PROP_NONE);
- RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
- RNA_def_property_enum_items(parm, spreadsheet_context_type_items);
- parm = RNA_def_pointer(
- func, "context", "SpreadsheetContext", "", "Newly created context path element");
- RNA_def_function_return(func, parm);
+ rna_def_viewer_path_elem(brna);
+ rna_def_id_viewer_path_elem(brna);
+ rna_def_modifier_viewer_path_elem(brna);
+ rna_def_node_viewer_path_elem(brna);
- func = RNA_def_function(srna, "clear", "rna_SpaceSpreadsheet_context_path_clear");
- RNA_def_function_ui_description(func, "Clear entire context path");
+ srna = RNA_def_struct(brna, "ViewerPath", NULL);
+ RNA_def_struct_ui_text(srna, "Viewer Path", "Path to data that is viewed");
- func = RNA_def_function(srna, "guess", "rna_SpaceSpreadsheet_context_path_guess");
- RNA_def_function_ui_description(func, "Guess the context path from the current context");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ prop = RNA_def_property(srna, "path", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_struct_type(prop, "ViewerPathElem");
+ RNA_def_property_ui_text(prop, "Viewer Path", NULL);
}
static void rna_def_space_spreadsheet(BlenderRNA *brna)
@@ -8019,11 +8041,6 @@ static void rna_def_space_spreadsheet(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL},
};
- rna_def_space_spreadsheet_context(brna);
- rna_def_space_spreadsheet_context_object(brna);
- rna_def_space_spreadsheet_context_modifier(brna);
- rna_def_space_spreadsheet_context_node(brna);
-
srna = RNA_def_struct(brna, "SpaceSpreadsheet", "Space");
RNA_def_struct_ui_text(srna, "Space Spreadsheet", "Spreadsheet space data");
@@ -8040,15 +8057,14 @@ static void rna_def_space_spreadsheet(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Use Filter", "");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SPREADSHEET, NULL);
- prop = RNA_def_property(srna, "display_context_path_collapsed", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "display_viewer_path_collapsed", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SPREADSHEET_FLAG_CONTEXT_PATH_COLLAPSED);
RNA_def_property_ui_text(prop, "Display Context Path Collapsed", "");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SPREADSHEET, NULL);
- prop = RNA_def_property(srna, "context_path", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_struct_type(prop, "SpreadsheetContext");
- RNA_def_property_ui_text(prop, "Context Path", "Context path to the data being displayed");
- rna_def_space_spreadsheet_context_path(brna, prop);
+ prop = RNA_def_property(srna, "viewer_path", PROP_POINTER, PROP_NONE);
+ RNA_def_property_ui_text(
+ prop, "Viewer Path", "Path to the data that is displayed in the spreadsheet");
prop = RNA_def_property(srna, "show_only_selected", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "filter_flag", SPREADSHEET_FILTER_SELECTED_ONLY);
@@ -8173,6 +8189,7 @@ static void rna_def_space_assets(BlenderRNA *brna)
void RNA_def_space(BlenderRNA *brna)
{
rna_def_space(brna);
+ rna_def_viewer_path(brna);
rna_def_space_image(brna);
rna_def_space_sequencer(brna);
rna_def_space_text(brna);
diff --git a/source/blender/makesrna/intern/rna_space_api.c b/source/blender/makesrna/intern/rna_space_api.c
index b3896919275..9790a85e1c8 100644
--- a/source/blender/makesrna/intern/rna_space_api.c
+++ b/source/blender/makesrna/intern/rna_space_api.c
@@ -119,7 +119,9 @@ void RNA_api_space_text(StructRNA *srna)
RNA_def_function_output(func, parm);
}
-void rna_def_object_type_visibility_flags_common(StructRNA *srna, int noteflag)
+void rna_def_object_type_visibility_flags_common(StructRNA *srna,
+ int noteflag,
+ const char *update_func)
{
PropertyRNA *prop;
@@ -173,7 +175,7 @@ void rna_def_object_type_visibility_flags_common(StructRNA *srna, int noteflag)
RNA_def_property_boolean_negative_sdna(
prop, NULL, view_mask_member[mask_index], info[type_index].type_mask);
RNA_def_property_ui_text(prop, info[type_index].name, "");
- RNA_def_property_update(prop, noteflag, NULL);
+ RNA_def_property_update(prop, noteflag, update_func);
}
}
}
diff --git a/source/blender/makesrna/intern/rna_test.c b/source/blender/makesrna/intern/rna_test.c
index ed3be815235..96b732c3aba 100644
--- a/source/blender/makesrna/intern/rna_test.c
+++ b/source/blender/makesrna/intern/rna_test.c
@@ -103,7 +103,7 @@ void RNA_def_test(BlenderRNA *brna)
# ifdef UNIT_TEST
StructRNA *srna;
PropertyRNA *prop;
- unsigned short dimsize[] = {MARRAY_DIMSIZE};
+ ushort dimsize[] = {MARRAY_DIMSIZE};
srna = RNA_def_struct(brna, "Test", NULL);
RNA_def_struct_sdna(srna, "Test");
diff --git a/source/blender/makesrna/intern/rna_text.c b/source/blender/makesrna/intern/rna_text.c
index e9c67d71ceb..4f756c163d1 100644
--- a/source/blender/makesrna/intern/rna_text.c
+++ b/source/blender/makesrna/intern/rna_text.c
@@ -231,6 +231,7 @@ static void rna_def_text(BlenderRNA *brna)
prop = RNA_def_property(srna, "indentation", PROP_ENUM, PROP_NONE); /* as an enum */
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flags");
RNA_def_property_enum_items(prop, indentation_items);
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_TEXT);
RNA_def_property_ui_text(prop, "Indentation", "Use tabs or spaces for indentation");
prop = RNA_def_property(srna, "lines", PROP_COLLECTION, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index 3b28dc70e9e..2254db4edaf 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -24,6 +24,8 @@
#include "BKE_node_tree_update.h"
#include "BKE_paint.h"
+#include "BLT_translation.h"
+
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -1191,6 +1193,7 @@ static void rna_def_texture_image(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_image_extension);
RNA_def_property_ui_text(
prop, "Extension", "How the image is extrapolated past its original bounds");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_IMAGE);
RNA_def_property_update(prop, 0, "rna_Texture_update");
prop = RNA_def_property(srna, "repeat_x", PROP_INT, PROP_NONE);
@@ -1235,7 +1238,7 @@ static void rna_def_texture_image(BlenderRNA *brna)
# if 0
/* XXX: did this as an array, but needs better descriptions than "1 2 3 4"
- * perhaps a new subtype could be added?
+ * perhaps a new sub-type could be added?
* --I actually used single values for this, maybe change later with a RNA_Rect thing? */
prop = RNA_def_property(srna, "crop_rectangle", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "cropxmin");
diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c
index b9acd57430b..44df0db9ade 100644
--- a/source/blender/makesrna/intern/rna_tracking.c
+++ b/source/blender/makesrna/intern/rna_tracking.c
@@ -13,6 +13,8 @@
#include "BKE_node_tree_update.h"
#include "BKE_tracking.h"
+#include "BLT_translation.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
@@ -1638,7 +1640,7 @@ static void rna_def_trackingTrack(BlenderRNA *brna)
RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
/* color */
- prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
+ prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(
@@ -2197,6 +2199,7 @@ static void rna_def_trackingTracks(BlenderRNA *brna)
prop, "rna_tracking_active_track_get", "rna_tracking_active_track_set", NULL, NULL);
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
RNA_def_property_ui_text(prop, "Active Track", "Active track in this tracking data object");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_MOVIECLIP);
}
static void rna_def_trackingPlaneTracks(BlenderRNA *brna)
@@ -2257,6 +2260,7 @@ static void rna_def_trackingObjectTracks(BlenderRNA *brna)
prop, "rna_tracking_active_track_get", "rna_tracking_active_track_set", NULL, NULL);
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
RNA_def_property_ui_text(prop, "Active Track", "Active track in this tracking data object");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_MOVIECLIP);
}
static void rna_def_trackingObjectPlaneTracks(BlenderRNA *brna)
@@ -2278,6 +2282,7 @@ static void rna_def_trackingObjectPlaneTracks(BlenderRNA *brna)
NULL);
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
RNA_def_property_ui_text(prop, "Active Track", "Active track in this tracking data object");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_MOVIECLIP);
}
static void rna_def_trackingObject(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index fc68e8421d7..eac29ac5e61 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -1785,6 +1785,10 @@ void RNA_api_ui_layout(StructRNA *srna)
parm = RNA_def_pointer(func, "socket", "NodeSocket", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ func = RNA_def_function(srna, "template_node_asset_menu_items", "uiTemplateNodeAssetMenuItems");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ parm = RNA_def_string(func, "catalog_path", NULL, 0, "", "");
+
func = RNA_def_function(srna, "template_texture_user", "uiTemplateTextureUser");
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 a0acbdcd2a3..fdb98781943 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -403,11 +403,11 @@ static void rna_userdef_anim_update(Main *UNUSED(bmain),
USERDEF_TAG_DIRTY;
}
-static void rna_userdef_tablet_api_update(Main *UNUSED(bmain),
- Scene *UNUSED(scene),
- PointerRNA *UNUSED(ptr))
+static void rna_userdef_input_devices(Main *UNUSED(bmain),
+ Scene *UNUSED(scene),
+ PointerRNA *UNUSED(ptr))
{
- WM_init_tablet_api();
+ WM_init_input_devices();
USERDEF_TAG_DIRTY;
}
@@ -574,7 +574,7 @@ static void rna_Userdef_disk_cache_dir_update(Main *UNUSED(bmain),
{
if (U.sequencer_disk_cache_dir[0] != '\0') {
BLI_path_abs(U.sequencer_disk_cache_dir, BKE_main_blendfile_path_from_global());
- BLI_path_slash_ensure(U.sequencer_disk_cache_dir);
+ BLI_path_slash_ensure(U.sequencer_disk_cache_dir, sizeof(U.sequencer_disk_cache_dir));
BLI_path_make_safe(U.sequencer_disk_cache_dir);
}
@@ -1685,7 +1685,7 @@ static void rna_def_userdef_theme_space_common(StructRNA *srna)
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
/* buttons */
- /* if (! ELEM(spacetype, SPACE_PROPERTIES, SPACE_OUTLINER)) { */
+ // if (!ELEM(spacetype, SPACE_PROPERTIES, SPACE_OUTLINER)) {
prop = RNA_def_property(srna, "button", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Region Background", "");
@@ -1737,7 +1737,7 @@ static void rna_def_userdef_theme_space_common(StructRNA *srna)
RNA_def_property_ui_text(prop, "Tab Outline", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
- /* } */
+ // }
}
static void rna_def_userdef_theme_space_gradient(BlenderRNA *brna)
@@ -4085,6 +4085,7 @@ static void rna_def_userdef_studiolights(BlenderRNA *brna)
STUDIOLIGHT_TYPE_WORLD,
"Type",
"The type for the new studio light");
+ RNA_def_property_translation_context(parm, BLT_I18NCONTEXT_ID_LIGHT);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_pointer(func, "studio_light", "StudioLight", "", "Newly created StudioLight");
RNA_def_function_return(func, parm);
@@ -4145,6 +4146,7 @@ static void rna_def_userdef_studiolight(BlenderRNA *brna)
RNA_def_property_enum_funcs(prop, "rna_UserDef_studiolight_type_get", NULL, NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Type", "");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_LIGHT);
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(
@@ -5259,6 +5261,12 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Duplicate Volume", "Causes volume data to be duplicated with the object");
+ prop = RNA_def_property(srna, "use_duplicate_node_tree", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "dupflag", USER_DUP_NTREE);
+ RNA_def_property_ui_text(prop,
+ "Duplicate Node Tree",
+ "Make copies of node groups when duplicating nodes in the node editor");
+
/* Currently only used for insert offset (aka auto-offset),
* maybe also be useful for later stuff though. */
prop = RNA_def_property(srna, "node_margin", PROP_INT, PROP_PIXEL);
@@ -5767,6 +5775,14 @@ static void rna_def_userdef_input(BlenderRNA *brna)
RNA_def_property_enum_items(prop, view_zoom_axes);
RNA_def_property_ui_text(prop, "Zoom Axis", "Axis of mouse movement to zoom in or out on");
+ prop = RNA_def_property(srna, "use_multitouch_gestures", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "uiflag", USER_NO_MULTITOUCH_GESTURES);
+ RNA_def_property_ui_text(
+ prop,
+ "Multi-touch Gestures",
+ "Use multi-touch gestures for navigation with touchpad, instead of scroll wheel emulation");
+ RNA_def_property_update(prop, 0, "rna_userdef_input_devices");
+
prop = RNA_def_property(srna, "invert_mouse_zoom", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_ZOOM_INVERT);
RNA_def_property_ui_text(
@@ -5902,7 +5918,7 @@ static void rna_def_userdef_input(BlenderRNA *brna)
"Tablet API",
"Select the tablet API to use for pressure sensitivity (may require "
"restarting Blender for changes to take effect)");
- RNA_def_property_update(prop, 0, "rna_userdef_tablet_api_update");
+ RNA_def_property_update(prop, 0, "rna_userdef_input_devices");
# ifdef WITH_INPUT_NDOF
/* 3D mouse settings */
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index ac1803b0a11..eebe595820e 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -99,13 +99,6 @@ static const EnumPropertyItem event_ndof_type_items[] = {
{NDOF_BUTTON_DOMINANT, "NDOF_BUTTON_DOMINANT", 0, "Dominant", ""},
{NDOF_BUTTON_PLUS, "NDOF_BUTTON_PLUS", 0, "Plus", ""},
{NDOF_BUTTON_MINUS, "NDOF_BUTTON_MINUS", 0, "Minus", ""},
-# if 0 /* Never used (converted to keyboard events by GHOST). */
- /* keyboard emulation */
- {NDOF_BUTTON_ESC, "NDOF_BUTTON_ESC", 0, "Esc"},
- {NDOF_BUTTON_ALT, "NDOF_BUTTON_ALT", 0, "Alt"},
- {NDOF_BUTTON_SHIFT, "NDOF_BUTTON_SHIFT", 0, "Shift"},
- {NDOF_BUTTON_CTRL, "NDOF_BUTTON_CTRL", 0, "Ctrl"},
-# endif
/* general-purpose buttons */
{NDOF_BUTTON_1, "NDOF_BUTTON_1", 0, "Button 1", ""},
{NDOF_BUTTON_2, "NDOF_BUTTON_2", 0, "Button 2", ""},
@@ -120,6 +113,21 @@ static const EnumPropertyItem event_ndof_type_items[] = {
{NDOF_BUTTON_A, "NDOF_BUTTON_A", 0, "Button A", ""},
{NDOF_BUTTON_B, "NDOF_BUTTON_B", 0, "Button B", ""},
{NDOF_BUTTON_C, "NDOF_BUTTON_C", 0, "Button C", ""},
+ /* View buttons. */
+ {NDOF_BUTTON_V1, "NDOF_BUTTON_V1", 0, "View 1", ""},
+ {NDOF_BUTTON_V2, "NDOF_BUTTON_V2", 0, "View 2", ""},
+ {NDOF_BUTTON_V3, "NDOF_BUTTON_V3", 0, "View 3", ""},
+# if 0 /* Never used (converted to keyboard events by GHOST). */
+ /* keyboard emulation */
+ {NDOF_BUTTON_ESC, "NDOF_BUTTON_ESC", 0, "Esc"},
+ {NDOF_BUTTON_ENTER, "NDOF_BUTTON_ENTER", 0, "Enter"},
+ {NDOF_BUTTON_DELETE, "NDOF_BUTTON_DELETE", 0, "Delete"},
+ {NDOF_BUTTON_TAB, "NDOF_BUTTON_TAB", 0, "Tab"},
+ {NDOF_BUTTON_SPACE, "NDOF_BUTTON_SPACE", 0, "Space"},
+ {NDOF_BUTTON_ALT, "NDOF_BUTTON_ALT", 0, "Alt"},
+ {NDOF_BUTTON_SHIFT, "NDOF_BUTTON_SHIFT", 0, "Shift"},
+ {NDOF_BUTTON_CTRL, "NDOF_BUTTON_CTRL", 0, "Ctrl"},
+# endif
{0, NULL, 0, NULL, NULL},
};
#endif /* RNA_RUNTIME */
@@ -1644,12 +1652,7 @@ static StructRNA *rna_MacroOperator_register(Main *bmain,
return NULL;
}
- if (strlen(identifier) >= sizeof(dummyop.idname)) {
- BKE_reportf(reports,
- RPT_ERROR,
- "Registering operator class: '%s' is too long, maximum length is %d",
- identifier,
- (int)sizeof(dummyop.idname));
+ if (!WM_operator_py_idname_ok_or_report(reports, identifier, dummyot.idname)) {
return NULL;
}
@@ -1661,10 +1664,6 @@ static StructRNA *rna_MacroOperator_register(Main *bmain,
}
}
- if (!WM_operator_py_idname_ok_or_report(reports, identifier, dummyot.idname)) {
- return NULL;
- }
-
char idname_conv[sizeof(dummyop.idname)];
WM_operator_bl_idname(idname_conv, dummyot.idname); /* convert the idname from python */
@@ -1867,8 +1866,9 @@ static void rna_def_operator_common(StructRNA *srna)
/* Registration */
prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->idname");
- /* Without setting the length the pointer size would be used. -3 because `.` -> `_OT_`. */
- RNA_def_property_string_maxlength(prop, OP_MAX_TYPENAME - 3);
+ /* String stored here is the 'BL' identifier (`OPMODULE_OT_my_op`),
+ * not the 'python' identifier (`opmodule.my_op`). */
+ RNA_def_property_string_maxlength(prop, OP_MAX_TYPENAME);
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_idname_set");
// RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_flag(prop, PROP_REGISTER);
@@ -2357,6 +2357,7 @@ static void rna_def_window(BlenderRNA *brna)
"rna_Window_screen_set",
NULL,
"rna_Window_screen_assign_poll");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_SCREEN);
RNA_def_property_flag(prop, PROP_NEVER_NULL | PROP_EDITABLE | PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_workspace_screen_update");
diff --git a/source/blender/makesrna/intern/rna_xr.c b/source/blender/makesrna/intern/rna_xr.c
index dcfa1bbca51..c803e5dc9a8 100644
--- a/source/blender/makesrna/intern/rna_xr.c
+++ b/source/blender/makesrna/intern/rna_xr.c
@@ -2052,7 +2052,7 @@ static void rna_def_xr_session_settings(BlenderRNA *brna)
"Allow the VR tracking origin to be defined independently of the headset location");
RNA_def_property_update(prop, NC_WM | ND_XR_DATA_CHANGED, NULL);
- rna_def_object_type_visibility_flags_common(srna, NC_WM | ND_XR_DATA_CHANGED);
+ rna_def_object_type_visibility_flags_common(srna, NC_WM | ND_XR_DATA_CHANGED, NULL);
/* Helper for drawing the icon. */
prop = RNA_def_property(srna, "icon_from_show_object_viewport", PROP_INT, PROP_NONE);
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index 8bace2e048c..e3a88e61cbd 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -43,7 +43,7 @@ set(SRC
intern/MOD_collision.c
intern/MOD_correctivesmooth.c
intern/MOD_curve.c
- intern/MOD_datatransfer.c
+ intern/MOD_datatransfer.cc
intern/MOD_decimate.c
intern/MOD_displace.c
intern/MOD_dynamicpaint.c
@@ -63,10 +63,10 @@ set(SRC
intern/MOD_meshdeform.c
intern/MOD_meshsequencecache.cc
intern/MOD_mirror.c
- intern/MOD_multires.c
+ intern/MOD_multires.cc
intern/MOD_nodes.cc
intern/MOD_none.c
- intern/MOD_normal_edit.c
+ intern/MOD_normal_edit.cc
intern/MOD_ocean.c
intern/MOD_particleinstance.c
intern/MOD_particlesystem.cc
@@ -81,23 +81,23 @@ set(SRC
intern/MOD_solidify.c
intern/MOD_solidify_extrude.c
intern/MOD_solidify_nonmanifold.c
- intern/MOD_subsurf.c
+ intern/MOD_subsurf.cc
intern/MOD_surface.c
intern/MOD_surfacedeform.c
intern/MOD_triangulate.c
intern/MOD_ui_common.c
- intern/MOD_util.c
- intern/MOD_uvproject.c
- intern/MOD_uvwarp.c
+ intern/MOD_util.cc
+ intern/MOD_uvproject.cc
+ intern/MOD_uvwarp.cc
intern/MOD_volume_displace.cc
intern/MOD_volume_to_mesh.cc
intern/MOD_warp.c
- intern/MOD_wave.c
- intern/MOD_weighted_normal.c
+ intern/MOD_wave.cc
+ intern/MOD_weighted_normal.cc
intern/MOD_weightvg_util.c
- intern/MOD_weightvgedit.c
- intern/MOD_weightvgmix.c
- intern/MOD_weightvgproximity.c
+ intern/MOD_weightvgedit.cc
+ intern/MOD_weightvgmix.cc
+ intern/MOD_weightvgproximity.cc
intern/MOD_weld.cc
intern/MOD_wireframe.c
diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h
index 4576ac68413..62b496017c4 100644
--- a/source/blender/modifiers/MOD_modifiertypes.h
+++ b/source/blender/modifiers/MOD_modifiertypes.h
@@ -76,10 +76,10 @@ extern ModifierTypeInfo modifierType_MeshToVolume;
extern ModifierTypeInfo modifierType_VolumeDisplace;
extern ModifierTypeInfo modifierType_VolumeToMesh;
-/* MOD_util.c */
+/* MOD_util.cc */
/**
- * Only called by `BKE_modifier.h/modifier.c`
+ * Only called by `BKE_modifier.h/modifier.cc`
*/
void modifier_type_init(ModifierTypeInfo *types[]);
diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c
index 43f650e025c..8e627f9964d 100644
--- a/source/blender/modifiers/intern/MOD_armature.c
+++ b/source/blender/modifiers/intern/MOD_armature.c
@@ -68,9 +68,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla
tamd->vert_coords_prev = NULL;
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *UNUSED(md),
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *UNUSED(md), CustomData_MeshMasks *r_cddata_masks)
{
/* ask for vertexgroups */
r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index 7feff30968f..2d725af7fe4 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -293,8 +293,6 @@ static void mesh_merge_transform(Mesh *result,
for (i = 0; i < cap_nverts; i++, mv++) {
mul_m4_v3(cap_offset, mv->co);
- /* Reset MVert flags for caps */
- mv->flag = 0;
}
/* We have to correct normals too, if we do not tag them as dirty later! */
@@ -458,13 +456,13 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
float result_mat[4][4];
if (ctx->object) {
- invert_m4_m4(obinv, ctx->object->obmat);
+ invert_m4_m4(obinv, ctx->object->object_to_world);
}
else {
unit_m4(obinv);
}
- mul_m4_series(result_mat, offset, obinv, amd->offset_ob->obmat);
+ mul_m4_series(result_mat, offset, obinv, amd->offset_ob->object_to_world);
copy_m4_m4(offset, result_mat);
}
@@ -476,7 +474,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
Object *curve_ob = amd->curve_ob;
CurveCache *curve_cache = curve_ob->runtime.curve_cache;
if (curve_cache != NULL && curve_cache->anim_path_accum_length != NULL) {
- float scale_fac = mat4_to_scale(curve_ob->obmat);
+ float scale_fac = mat4_to_scale(curve_ob->object_to_world);
length = scale_fac * BKE_anim_path_get_length(curve_cache);
}
}
diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c
index 668843188ab..48d355d8ca7 100644
--- a/source/blender/modifiers/intern/MOD_bevel.c
+++ b/source/blender/modifiers/intern/MOD_bevel.c
@@ -64,9 +64,7 @@ static void copyData(const ModifierData *md_src, ModifierData *md_dst, const int
bmd_dst->custom_profile = BKE_curveprofile_copy(bmd_src->custom_profile);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
BevelModifierData *bmd = (BevelModifierData *)md;
diff --git a/source/blender/modifiers/intern/MOD_boolean.cc b/source/blender/modifiers/intern/MOD_boolean.cc
index b266e71e99a..21f05158e8b 100644
--- a/source/blender/modifiers/intern/MOD_boolean.cc
+++ b/source/blender/modifiers/intern/MOD_boolean.cc
@@ -78,9 +78,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(bmd, DNA_struct_default_get(BooleanModifierData), modifier);
}
-static bool isDisabled(const struct Scene *UNUSED(scene),
- ModifierData *md,
- bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene * /*scene*/, ModifierData *md, bool /*useRenderParams*/)
{
BooleanModifierData *bmd = (BooleanModifierData *)md;
Collection *col = bmd->collection;
@@ -141,8 +139,8 @@ static Mesh *get_quick_mesh(
float imat[4][4];
float omat[4][4];
- invert_m4_m4(imat, ob_self->obmat);
- mul_m4_m4m4(omat, imat, ob_operand_ob->obmat);
+ invert_m4_m4(imat, ob_self->object_to_world);
+ mul_m4_m4m4(omat, imat, ob_operand_ob->object_to_world);
MutableSpan<MVert> verts = result->verts_for_write();
for (const int i : verts.index_range()) {
@@ -169,7 +167,7 @@ static Mesh *get_quick_mesh(
/**
* Compare selected/unselected.
*/
-static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data))
+static int bm_face_isect_pair(BMFace *f, void * /*user_data*/)
{
return BM_elem_flag_test(f, BM_FACE_TAG) ? 1 : 0;
}
@@ -229,7 +227,8 @@ static BMesh *BMD_mesh_bm_create(
SCOPED_TIMER(__func__);
#endif
- *r_is_flip = (is_negative_m4(object->obmat) != is_negative_m4(operand_ob->obmat));
+ *r_is_flip = (is_negative_m4(object->object_to_world) !=
+ is_negative_m4(operand_ob->object_to_world));
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh, mesh_operand_ob);
@@ -296,8 +295,8 @@ static void BMD_mesh_intersection(BMesh *bm,
float imat[4][4];
float omat[4][4];
- invert_m4_m4(imat, object->obmat);
- mul_m4_m4m4(omat, imat, operand_ob->obmat);
+ invert_m4_m4(imat, object->object_to_world);
+ mul_m4_m4m4(omat, imat, operand_ob->object_to_world);
BMVert *eve;
i = 0;
@@ -416,7 +415,7 @@ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd,
}
meshes.append(mesh);
- obmats.append((float4x4 *)&ctx->object->obmat);
+ obmats.append((float4x4 *)&ctx->object->object_to_world);
material_remaps.append({});
if (mesh->totcol == 0) {
/* Necessary for faces using the default material when there are no material slots. */
@@ -433,7 +432,7 @@ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd,
}
BKE_mesh_wrapper_ensure_mdata(mesh_operand);
meshes.append(mesh_operand);
- obmats.append((float4x4 *)&bmd->object->obmat);
+ obmats.append((float4x4 *)&bmd->object->object_to_world);
material_remaps.append(get_material_remap(*bmd->object, *mesh_operand, materials));
}
else if (bmd->flag & eBooleanModifierFlag_Collection) {
@@ -448,7 +447,7 @@ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd,
}
BKE_mesh_wrapper_ensure_mdata(collection_mesh);
meshes.append(collection_mesh);
- obmats.append((float4x4 *)&ob->obmat);
+ obmats.append((float4x4 *)&ob->object_to_world);
material_remaps.append(get_material_remap(*ob, *collection_mesh, materials));
}
}
@@ -458,14 +457,15 @@ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd,
const bool use_self = (bmd->flag & eBooleanModifierFlag_Self) != 0;
const bool hole_tolerant = (bmd->flag & eBooleanModifierFlag_HoleTolerant) != 0;
- Mesh *result = blender::meshintersect::direct_mesh_boolean(meshes,
- obmats,
- *(float4x4 *)&ctx->object->obmat,
- material_remaps,
- use_self,
- hole_tolerant,
- bmd->operation,
- nullptr);
+ Mesh *result = blender::meshintersect::direct_mesh_boolean(
+ meshes,
+ obmats,
+ *(float4x4 *)&ctx->object->object_to_world,
+ material_remaps,
+ use_self,
+ hole_tolerant,
+ bmd->operation,
+ nullptr);
MEM_SAFE_FREE(result->mat);
result->mat = (Material **)MEM_malloc_arrayN(materials.size(), sizeof(Material *), __func__);
result->totcol = materials.size();
@@ -570,16 +570,14 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
return result;
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *UNUSED(md),
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData * /*md*/, CustomData_MeshMasks *r_cddata_masks)
{
r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
r_cddata_masks->emask |= CD_MASK_MEDGE;
r_cddata_masks->fmask |= CD_MASK_MTFACE;
}
-static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
@@ -601,7 +599,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
modifier_panel_end(layout, ptr);
}
-static void solver_options_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void solver_options_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c
index 3f0c212999f..b6e1b5e88c1 100644
--- a/source/blender/modifiers/intern/MOD_cast.c
+++ b/source/blender/modifiers/intern/MOD_cast.c
@@ -23,6 +23,7 @@
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"
#include "BKE_screen.h"
@@ -63,9 +64,7 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
return false;
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
CastModifierData *cmd = (CastModifierData *)md;
@@ -127,13 +126,13 @@ static void sphere_do(CastModifierData *cmd,
* we use its location, transformed to ob's local space */
if (ctrl_ob) {
if (flag & MOD_CAST_USE_OB_TRANSFORM) {
- invert_m4_m4(imat, ctrl_ob->obmat);
- mul_m4_m4m4(mat, imat, ob->obmat);
+ invert_m4_m4(imat, ctrl_ob->object_to_world);
+ mul_m4_m4m4(mat, imat, ob->object_to_world);
invert_m4_m4(imat, mat);
}
- invert_m4_m4(ob->imat, ob->obmat);
- mul_v3_m4v3(center, ob->imat, ctrl_ob->obmat[3]);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
+ mul_v3_m4v3(center, ob->world_to_object, ctrl_ob->object_to_world[3]);
}
/* now we check which options the user wants */
@@ -276,13 +275,13 @@ static void cuboid_do(CastModifierData *cmd,
if (ctrl_ob) {
if (flag & MOD_CAST_USE_OB_TRANSFORM) {
- invert_m4_m4(imat, ctrl_ob->obmat);
- mul_m4_m4m4(mat, imat, ob->obmat);
+ invert_m4_m4(imat, ctrl_ob->object_to_world);
+ mul_m4_m4m4(mat, imat, ob->object_to_world);
invert_m4_m4(imat, mat);
}
- invert_m4_m4(ob->imat, ob->obmat);
- mul_v3_m4v3(center, ob->imat, ctrl_ob->obmat[3]);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
+ mul_v3_m4v3(center, ob->world_to_object, ctrl_ob->object_to_world[3]);
}
if ((flag & MOD_CAST_SIZE_FROM_RADIUS) && has_radius) {
@@ -496,7 +495,7 @@ static void deformVertsEM(ModifierData *md,
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, verts_num, false);
}
- if (mesh && mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA) {
+ if (mesh && BKE_mesh_wrapper_type(mesh) == ME_WRAPPER_TYPE_MDATA) {
BLI_assert(mesh->totvert == verts_num);
}
diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c
index 8f4a675b797..dcb4803b08a 100644
--- a/source/blender/modifiers/intern/MOD_cloth.c
+++ b/source/blender/modifiers/intern/MOD_cloth.c
@@ -147,9 +147,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
DEG_add_depends_on_transform_relation(ctx->node, "Cloth Modifier");
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
ClothModifierData *clmd = (ClothModifierData *)md;
diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c
index e38bf96500e..82faf08b349 100644
--- a/source/blender/modifiers/intern/MOD_collision.c
+++ b/source/blender/modifiers/intern/MOD_collision.c
@@ -149,7 +149,7 @@ static void deformVerts(ModifierData *md,
for (uint i = 0; i < mvert_num; i++) {
/* we save global positions */
- mul_m4_v3(ob->obmat, collmd->x[i].co);
+ mul_m4_v3(ob->object_to_world, collmd->x[i].co);
}
collmd->xnew = MEM_dupallocN(collmd->x); /* Frame end position. */
@@ -188,7 +188,7 @@ static void deformVerts(ModifierData *md,
for (uint i = 0; i < mvert_num; i++) {
/* we save global positions */
- mul_m4_v3(ob->obmat, collmd->xnew[i].co);
+ mul_m4_v3(ob->object_to_world, collmd->xnew[i].co);
/* detect motion */
is_static = is_static && equals_v3v3(collmd->x[i].co, collmd->xnew[i].co);
diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c
index 16f2205796c..5a9f7c657eb 100644
--- a/source/blender/modifiers/intern/MOD_correctivesmooth.c
+++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c
@@ -49,10 +49,10 @@
#include "PIL_time.h"
#ifdef DEBUG_TIME
# include "PIL_time_utildefines.h"
+
#endif
-/* minor optimization, calculate this inline */
-#define USE_TANGENT_CALC_INLINE
+#include "BLI_strict_flags.h"
static void initData(ModifierData *md)
{
@@ -65,8 +65,6 @@ static void initData(ModifierData *md)
csmd->delta_cache.deltas = NULL;
}
-#include "BLI_strict_flags.h"
-
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
const CorrectiveSmoothModifierData *csmd = (const CorrectiveSmoothModifierData *)md;
@@ -79,7 +77,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla
}
tcsmd->delta_cache.deltas = NULL;
- tcsmd->delta_cache.totverts = 0;
+ tcsmd->delta_cache.deltas_num = 0;
}
static void freeBind(CorrectiveSmoothModifierData *csmd)
@@ -96,9 +94,7 @@ static void freeData(ModifierData *md)
freeBind(csmd);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
@@ -134,25 +130,24 @@ static void mesh_get_boundaries(Mesh *mesh, float *smooth_weights)
const MEdge *medge = BKE_mesh_edges(mesh);
const MPoly *mpoly = BKE_mesh_polys(mesh);
const MLoop *mloop = BKE_mesh_loops(mesh);
- uint mpoly_num, medge_num, i;
- ushort *boundaries;
- mpoly_num = (uint)mesh->totpoly;
- medge_num = (uint)mesh->totedge;
+ const uint mpoly_num = (uint)mesh->totpoly;
+ const uint medge_num = (uint)mesh->totedge;
- boundaries = MEM_calloc_arrayN(medge_num, sizeof(*boundaries), __func__);
+ /* Flag boundary edges so only boundaries are set to 1. */
+ uint8_t *boundaries = MEM_calloc_arrayN(medge_num, sizeof(*boundaries), __func__);
- /* count the number of adjacent faces */
- for (i = 0; i < mpoly_num; i++) {
+ for (uint i = 0; i < mpoly_num; i++) {
const MPoly *p = &mpoly[i];
const int totloop = p->totloop;
int j;
for (j = 0; j < totloop; j++) {
- boundaries[mloop[p->loopstart + j].e]++;
+ uint8_t *e_value = &boundaries[mloop[p->loopstart + j].e];
+ *e_value |= (uint8_t)((*e_value) + 1);
}
}
- for (i = 0; i < medge_num; i++) {
+ for (uint i = 0; i < medge_num; i++) {
if (boundaries[i] == 1) {
smooth_weights[medge[i].v1] = 0.0f;
smooth_weights[medge[i].v2] = 0.0f;
@@ -393,69 +388,61 @@ static void smooth_verts(CorrectiveSmoothModifierData *csmd,
}
/**
- * finalize after accumulation.
+ * Calculate an orthogonal 3x3 matrix from 2 edge vectors.
+ * \return false if this loop should be ignored (have zero influence).
*/
-static void calc_tangent_ortho(float ts[3][3])
+static bool calc_tangent_loop(const float v_dir_prev[3],
+ const float v_dir_next[3],
+ float r_tspace[3][3])
{
- float v_tan_a[3], v_tan_b[3];
- float t_vec_a[3], t_vec_b[3];
-
- normalize_v3(ts[2]);
-
- copy_v3_v3(v_tan_a, ts[0]);
- copy_v3_v3(v_tan_b, ts[1]);
-
- cross_v3_v3v3(ts[1], ts[2], v_tan_a);
- mul_v3_fl(ts[1], dot_v3v3(ts[1], v_tan_b) < 0.0f ? -1.0f : 1.0f);
-
- /* Orthogonalize tangent. */
- mul_v3_v3fl(t_vec_a, ts[2], dot_v3v3(ts[2], v_tan_a));
- sub_v3_v3v3(ts[0], v_tan_a, t_vec_a);
-
- /* Orthogonalize bi-tangent. */
- mul_v3_v3fl(t_vec_a, ts[2], dot_v3v3(ts[2], ts[1]));
- mul_v3_v3fl(t_vec_b, ts[0], dot_v3v3(ts[0], ts[1]) / dot_v3v3(v_tan_a, v_tan_a));
- sub_v3_v3(ts[1], t_vec_a);
- sub_v3_v3(ts[1], t_vec_b);
-
- normalize_v3(ts[0]);
- normalize_v3(ts[1]);
+ if (UNLIKELY(compare_v3v3(v_dir_prev, v_dir_next, FLT_EPSILON * 10.0f))) {
+ /* As there are no weights, the value doesn't matter just initialize it. */
+ unit_m3(r_tspace);
+ return false;
+ }
+
+ copy_v3_v3(r_tspace[0], v_dir_prev);
+ copy_v3_v3(r_tspace[1], v_dir_next);
+
+ cross_v3_v3v3(r_tspace[2], v_dir_prev, v_dir_next);
+ normalize_v3(r_tspace[2]);
+
+ /* Make orthogonal using `r_tspace[2]` as a basis.
+ *
+ * NOTE: while it seems more logical to use `v_dir_prev` & `v_dir_next` as separate X/Y axis
+ * (instead of combining them as is done here). It's not necessary as the directions of the
+ * axis aren't important as long as the difference between tangent matrices is equivalent.
+ * Some computations can be skipped by combining the two directions,
+ * using the cross product for the 3rd axes. */
+ add_v3_v3(r_tspace[0], r_tspace[1]);
+ normalize_v3(r_tspace[0]);
+ cross_v3_v3v3(r_tspace[1], r_tspace[2], r_tspace[0]);
+
+ return true;
}
/**
- * accumulate edge-vectors from all polys.
+ * \param r_tangent_spaces: Loop aligned array of tangents.
+ * \param r_tangent_weights: Loop aligned array of weights (may be NULL).
+ * \param r_tangent_weights_per_vertex: Vertex aligned array, accumulating weights for each loop
+ * (may be NULL).
*/
-static void calc_tangent_loop_accum(const float v_dir_prev[3],
- const float v_dir_next[3],
- float r_tspace[3][3])
-{
- add_v3_v3v3(r_tspace[1], v_dir_prev, v_dir_next);
-
- if (compare_v3v3(v_dir_prev, v_dir_next, FLT_EPSILON * 10.0f) == false) {
- const float weight = fabsf(acosf(dot_v3v3(v_dir_next, v_dir_prev)));
- float nor[3];
-
- cross_v3_v3v3(nor, v_dir_prev, v_dir_next);
- normalize_v3(nor);
-
- cross_v3_v3v3(r_tspace[0], r_tspace[1], nor);
-
- mul_v3_fl(nor, weight);
- /* accumulate weighted normals */
- add_v3_v3(r_tspace[2], nor);
- }
-}
-
-static void calc_tangent_spaces(Mesh *mesh, float (*vertexCos)[3], float (*r_tangent_spaces)[3][3])
+static void calc_tangent_spaces(const Mesh *mesh,
+ const float (*vertexCos)[3],
+ float (*r_tangent_spaces)[3][3],
+ float *r_tangent_weights,
+ float *r_tangent_weights_per_vertex)
{
const uint mpoly_num = (uint)mesh->totpoly;
-#ifndef USE_TANGENT_CALC_INLINE
- const uint mvert_num = (uint)dm->getNumVerts(dm);
-#endif
+ const uint mvert_num = (uint)mesh->totvert;
const MPoly *mpoly = BKE_mesh_polys(mesh);
const MLoop *mloop = BKE_mesh_loops(mesh);
uint i;
+ if (r_tangent_weights_per_vertex != NULL) {
+ copy_vn_fl(r_tangent_weights_per_vertex, (int)mvert_num, 0.0f);
+ }
+
for (i = 0; i < mpoly_num; i++) {
const MPoly *mp = &mpoly[i];
const MLoop *l_next = &mloop[mp->loopstart];
@@ -471,7 +458,8 @@ static void calc_tangent_spaces(Mesh *mesh, float (*vertexCos)[3], float (*r_tan
normalize_v3(v_dir_prev);
for (; l_next != l_term; l_prev = l_curr, l_curr = l_next, l_next++) {
- float(*ts)[3] = r_tangent_spaces[l_curr->v];
+ uint l_index = (uint)(l_curr - mloop);
+ float(*ts)[3] = r_tangent_spaces[l_index];
/* re-use the previous value */
#if 0
@@ -481,19 +469,22 @@ static void calc_tangent_spaces(Mesh *mesh, float (*vertexCos)[3], float (*r_tan
sub_v3_v3v3(v_dir_next, vertexCos[l_curr->v], vertexCos[l_next->v]);
normalize_v3(v_dir_next);
- calc_tangent_loop_accum(v_dir_prev, v_dir_next, ts);
+ if (calc_tangent_loop(v_dir_prev, v_dir_next, ts)) {
+ if (r_tangent_weights != NULL) {
+ const float weight = fabsf(acosf(dot_v3v3(v_dir_next, v_dir_prev)));
+ r_tangent_weights[l_index] = weight;
+ r_tangent_weights_per_vertex[l_curr->v] += weight;
+ }
+ }
+ else {
+ if (r_tangent_weights != NULL) {
+ r_tangent_weights[l_index] = 0;
+ }
+ }
copy_v3_v3(v_dir_prev, v_dir_next);
}
}
-
- /* do inline */
-#ifndef USE_TANGENT_CALC_INLINE
- for (i = 0; i < mvert_num; i++) {
- float(*ts)[3] = r_tangent_spaces[i];
- calc_tangent_ortho(ts);
- }
-#endif
}
static void store_cache_settings(CorrectiveSmoothModifierData *csmd)
@@ -524,38 +515,42 @@ static void calc_deltas(CorrectiveSmoothModifierData *csmd,
const float (*rest_coords)[3],
uint verts_num)
{
+ const MLoop *mloop = BKE_mesh_loops(mesh);
+ const uint loops_num = (uint)mesh->totloop;
+
float(*smooth_vertex_coords)[3] = MEM_dupallocN(rest_coords);
float(*tangent_spaces)[3][3];
- uint i;
- tangent_spaces = MEM_calloc_arrayN(verts_num, sizeof(float[3][3]), __func__);
+ uint l_index;
- if (csmd->delta_cache.totverts != verts_num) {
+ tangent_spaces = MEM_malloc_arrayN(loops_num, sizeof(float[3][3]), __func__);
+
+ if (csmd->delta_cache.deltas_num != loops_num) {
MEM_SAFE_FREE(csmd->delta_cache.deltas);
}
/* allocate deltas if they have not yet been allocated, otherwise we will just write over them */
if (!csmd->delta_cache.deltas) {
- csmd->delta_cache.totverts = verts_num;
- csmd->delta_cache.deltas = MEM_malloc_arrayN(verts_num, sizeof(float[3]), __func__);
+ csmd->delta_cache.deltas_num = loops_num;
+ csmd->delta_cache.deltas = MEM_malloc_arrayN(loops_num, sizeof(float[3]), __func__);
}
smooth_verts(csmd, mesh, dvert, defgrp_index, smooth_vertex_coords, verts_num);
- calc_tangent_spaces(mesh, smooth_vertex_coords, tangent_spaces);
+ calc_tangent_spaces(mesh, smooth_vertex_coords, tangent_spaces, NULL, NULL);
- for (i = 0; i < verts_num; i++) {
- float imat[3][3], delta[3];
+ copy_vn_fl(&csmd->delta_cache.deltas[0][0], (int)loops_num * 3, 0.0f);
-#ifdef USE_TANGENT_CALC_INLINE
- calc_tangent_ortho(tangent_spaces[i]);
-#endif
+ for (l_index = 0; l_index < loops_num; l_index++) {
+ const int v_index = (int)mloop[l_index].v;
+ float delta[3];
+ sub_v3_v3v3(delta, rest_coords[v_index], smooth_vertex_coords[v_index]);
- sub_v3_v3v3(delta, rest_coords[i], smooth_vertex_coords[i]);
- if (UNLIKELY(!invert_m3_m3(imat, tangent_spaces[i]))) {
- transpose_m3_m3(imat, tangent_spaces[i]);
+ float imat[3][3];
+ if (UNLIKELY(!invert_m3_m3(imat, tangent_spaces[l_index]))) {
+ transpose_m3_m3(imat, tangent_spaces[l_index]);
}
- mul_v3_m3v3(csmd->delta_cache.deltas[i], imat, delta);
+ mul_v3_m3v3(csmd->delta_cache.deltas[l_index], imat, delta);
}
MEM_freeN(tangent_spaces);
@@ -578,6 +573,9 @@ static void correctivesmooth_modifier_do(ModifierData *md,
((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO) &&
(((ID *)ob->data)->recalc & ID_RECALC_ALL));
+ const MLoop *mloop = BKE_mesh_loops(mesh);
+ const uint loops_num = (uint)mesh->totloop;
+
bool use_only_smooth = (csmd->flag & MOD_CORRECTIVESMOOTH_ONLY_SMOOTH) != 0;
const MDeformVert *dvert = NULL;
int defgrp_index;
@@ -640,7 +638,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
}
/* check to see if our deltas are still valid */
- if (!csmd->delta_cache.deltas || (csmd->delta_cache.totverts != verts_num) ||
+ if (!csmd->delta_cache.deltas || (csmd->delta_cache.deltas_num != loops_num) ||
force_delta_cache_update) {
const float(*rest_coords)[3];
bool is_rest_coords_alloc = false;
@@ -688,27 +686,38 @@ static void correctivesmooth_modifier_do(ModifierData *md,
smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, verts_num);
{
- uint i;
+ uint l_index;
float(*tangent_spaces)[3][3];
+ float *tangent_weights;
+
+ float *tangent_weights_per_vertex;
const float scale = csmd->scale;
- /* calloc, since values are accumulated */
- tangent_spaces = MEM_calloc_arrayN(verts_num, sizeof(float[3][3]), __func__);
- calc_tangent_spaces(mesh, vertexCos, tangent_spaces);
+ tangent_spaces = MEM_malloc_arrayN(loops_num, sizeof(float[3][3]), __func__);
+ tangent_weights = MEM_malloc_arrayN(loops_num, sizeof(float), __func__);
+ tangent_weights_per_vertex = MEM_malloc_arrayN(verts_num, sizeof(float), __func__);
- for (i = 0; i < verts_num; i++) {
- float delta[3];
+ calc_tangent_spaces(
+ mesh, vertexCos, tangent_spaces, tangent_weights, tangent_weights_per_vertex);
-#ifdef USE_TANGENT_CALC_INLINE
- calc_tangent_ortho(tangent_spaces[i]);
-#endif
+ for (l_index = 0; l_index < loops_num; l_index++) {
+ const uint v_index = mloop[l_index].v;
+ const float weight = tangent_weights[l_index] / tangent_weights_per_vertex[v_index];
+ if (UNLIKELY(!(weight > 0.0f))) {
+ /* Catches zero & divide by zero. */
+ continue;
+ }
- mul_v3_m3v3(delta, tangent_spaces[i], csmd->delta_cache.deltas[i]);
- madd_v3_v3fl(vertexCos[i], delta, scale);
+ float delta[3];
+ mul_v3_m3v3(delta, tangent_spaces[l_index], csmd->delta_cache.deltas[l_index]);
+ mul_v3_fl(delta, weight);
+ madd_v3_v3fl(vertexCos[v_index], delta, scale);
}
MEM_freeN(tangent_spaces);
+ MEM_freeN(tangent_weights);
+ MEM_freeN(tangent_weights_per_vertex);
}
#ifdef DEBUG_TIME
@@ -720,7 +729,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
/* when the modifier fails to execute */
error:
MEM_SAFE_FREE(csmd->delta_cache.deltas);
- csmd->delta_cache.totverts = 0;
+ csmd->delta_cache.deltas_num = 0;
}
static void deformVerts(ModifierData *md,
@@ -829,7 +838,7 @@ static void blendRead(BlendDataReader *reader, ModifierData *md)
/* runtime only */
csmd->delta_cache.deltas = NULL;
- csmd->delta_cache.totverts = 0;
+ csmd->delta_cache.deltas_num = 0;
}
ModifierTypeInfo modifierType_CorrectiveSmooth = {
diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c
index 2043c1096c1..16c97d486da 100644
--- a/source/blender/modifiers/intern/MOD_curve.c
+++ b/source/blender/modifiers/intern/MOD_curve.c
@@ -51,9 +51,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(cmd, DNA_struct_default_get(CurveModifierData), modifier);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
CurveModifierData *cmd = (CurveModifierData *)md;
diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.cc
index 2d917310818..25e8eb8fa20 100644
--- a/source/blender/modifiers/intern/MOD_datatransfer.c
+++ b/source/blender/modifiers/intern/MOD_datatransfer.cc
@@ -50,7 +50,7 @@ static void initData(ModifierData *md)
DataTransferModifierData *dtmd = (DataTransferModifierData *)md;
int i;
- dtmd->ob_source = NULL;
+ dtmd->ob_source = nullptr;
dtmd->data_types = 0;
dtmd->vmap_mode = MREMAP_MODE_VERT_NEAREST;
@@ -73,9 +73,7 @@ static void initData(ModifierData *md)
dtmd->flags = MOD_DATATRANSFER_OBSRC_TRANSFORM;
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
DataTransferModifierData *dtmd = (DataTransferModifierData *)md;
@@ -117,7 +115,7 @@ static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *u
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
DataTransferModifierData *dtmd = (DataTransferModifierData *)md;
- if (dtmd->ob_source != NULL) {
+ if (dtmd->ob_source != nullptr) {
CustomData_MeshMasks cddata_masks = {0};
BKE_object_data_transfer_dttypes_to_cdmask(dtmd->data_types, &cddata_masks);
BKE_mesh_remap_calc_source_cddata_masks_from_map_modes(
@@ -135,9 +133,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
}
}
-static bool isDisabled(const struct Scene *UNUSED(scene),
- ModifierData *md,
- bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene * /*scene*/, ModifierData *md, bool /*useRenderParams*/)
{
/* If no source object, bypass. */
DataTransferModifierData *dtmd = (DataTransferModifierData *)md;
@@ -161,7 +157,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
ReportList reports;
/* Only used to check whether we are operating on org data or not... */
- Mesh *me = ctx->object->data;
+ const Mesh *me = static_cast<const Mesh *>(ctx->object->data);
Object *ob_source = dtmd->ob_source;
@@ -173,7 +169,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
SpaceTransform space_transform_data;
SpaceTransform *space_transform = (dtmd->flags & MOD_DATATRANSFER_OBSRC_TRANSFORM) ?
&space_transform_data :
- NULL;
+ nullptr;
if (space_transform) {
BLI_SPACE_TRANSFORM_SETUP(space_transform, ctx->object, ob_source);
@@ -188,7 +184,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
(dtmd->data_types & DT_TYPES_AFFECT_MESH)) {
/* We need to duplicate data here, otherwise setting custom normals, edges' sharpness, etc.,
* could modify org mesh, see T43671. */
- result = (Mesh *)BKE_id_copy_ex(NULL, &me_mod->id, NULL, LIB_ID_COPY_LOCALIZE);
+ result = (Mesh *)BKE_id_copy_ex(nullptr, &me_mod->id, nullptr, LIB_ID_COPY_LOCALIZE);
}
BKE_reports_init(&reports, RPT_STORE);
@@ -217,7 +213,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
dtmd->defgrp_name,
invert_vgroup,
&reports)) {
- result->runtime.is_original_bmesh = false;
+ result->runtime->is_original_bmesh = false;
}
if (BKE_reports_contain(&reports, RPT_ERROR)) {
@@ -233,7 +229,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
return result;
}
-static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *sub, *row;
uiLayout *layout = panel->layout;
@@ -249,7 +245,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropDecorate(sub, false);
uiItemR(sub, ptr, "use_object_transform", 0, "", ICON_ORIENTATION_GLOBAL);
- uiItemR(layout, ptr, "mix_mode", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "mix_mode", 0, nullptr, ICON_NONE);
row = uiLayoutRow(layout, false);
uiLayoutSetActive(row,
@@ -257,44 +253,44 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
CDT_MIX_NOMIX,
CDT_MIX_REPLACE_ABOVE_THRESHOLD,
CDT_MIX_REPLACE_BELOW_THRESHOLD));
- uiItemR(row, ptr, "mix_factor", 0, NULL, ICON_NONE);
+ uiItemR(row, ptr, "mix_factor", 0, nullptr, ICON_NONE);
- modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
+ modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", nullptr);
uiItemO(layout, IFACE_("Generate Data Layers"), ICON_NONE, "OBJECT_OT_datalayout_transfer");
modifier_panel_end(layout, ptr);
}
-static void vertex_panel_draw_header(const bContext *UNUSED(C), Panel *panel)
+static void vertex_panel_draw_header(const bContext * /*C*/, Panel *panel)
{
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
uiLayout *layout = panel->layout;
- uiItemR(layout, ptr, "use_vert_data", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_vert_data", 0, nullptr, ICON_NONE);
}
-static void vertex_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void vertex_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
bool use_vert_data = RNA_boolean_get(ptr, "use_vert_data");
uiLayoutSetActive(layout, use_vert_data);
- uiItemR(layout, ptr, "data_types_verts", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "data_types_verts", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
uiLayoutSetPropSep(layout, true);
uiItemR(layout, ptr, "vert_mapping", 0, IFACE_("Mapping"), ICON_NONE);
}
-static void vertex_vgroup_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void vertex_vgroup_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
uiLayoutSetActive(layout, RNA_enum_get(ptr, "data_types_verts") & DT_TYPE_MDEFORMVERT);
@@ -304,59 +300,59 @@ static void vertex_vgroup_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(layout, ptr, "layers_vgroup_select_dst", 0, IFACE_("Layer Mapping"), ICON_NONE);
}
-static void edge_panel_draw_header(const bContext *UNUSED(C), Panel *panel)
+static void edge_panel_draw_header(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
- uiItemR(layout, ptr, "use_edge_data", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_edge_data", 0, nullptr, ICON_NONE);
}
-static void edge_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void edge_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
uiLayoutSetActive(layout, RNA_boolean_get(ptr, "use_edge_data"));
- uiItemR(layout, ptr, "data_types_edges", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "data_types_edges", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
uiLayoutSetPropSep(layout, true);
uiItemR(layout, ptr, "edge_mapping", 0, IFACE_("Mapping"), ICON_NONE);
}
-static void face_corner_panel_draw_header(const bContext *UNUSED(C), Panel *panel)
+static void face_corner_panel_draw_header(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
- uiItemR(layout, ptr, "use_loop_data", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_loop_data", 0, nullptr, ICON_NONE);
}
-static void face_corner_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void face_corner_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
uiLayoutSetActive(layout, RNA_boolean_get(ptr, "use_loop_data"));
- uiItemR(layout, ptr, "data_types_loops", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "data_types_loops", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
uiLayoutSetPropSep(layout, true);
uiItemR(layout, ptr, "loop_mapping", 0, IFACE_("Mapping"), ICON_NONE);
}
-static void vert_vcol_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void vert_vcol_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
uiLayoutSetPropSep(layout, true);
@@ -368,11 +364,11 @@ static void vert_vcol_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(layout, ptr, "layers_vcol_vert_select_dst", 0, IFACE_("Layer Mapping"), ICON_NONE);
}
-static void face_corner_vcol_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void face_corner_vcol_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
uiLayoutSetPropSep(layout, true);
@@ -384,11 +380,11 @@ static void face_corner_vcol_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(layout, ptr, "layers_vcol_loop_select_dst", 0, IFACE_("Layer Mapping"), ICON_NONE);
}
-static void face_corner_uv_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void face_corner_uv_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
uiLayoutSetPropSep(layout, true);
@@ -396,39 +392,39 @@ static void face_corner_uv_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(layout, ptr, "layers_uv_select_src", 0, IFACE_("Layer Selection"), ICON_NONE);
uiItemR(layout, ptr, "layers_uv_select_dst", 0, IFACE_("Layer Mapping"), ICON_NONE);
- uiItemR(layout, ptr, "islands_precision", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "islands_precision", 0, nullptr, ICON_NONE);
}
-static void face_panel_draw_header(const bContext *UNUSED(C), Panel *panel)
+static void face_panel_draw_header(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
- uiItemR(layout, ptr, "use_poly_data", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_poly_data", 0, nullptr, ICON_NONE);
}
-static void face_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void face_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
uiLayoutSetActive(layout, RNA_boolean_get(ptr, "use_poly_data"));
- uiItemR(layout, ptr, "data_types_polys", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "data_types_polys", 0, nullptr, ICON_NONE);
uiLayoutSetPropSep(layout, true);
uiItemR(layout, ptr, "poly_mapping", 0, IFACE_("Mapping"), ICON_NONE);
}
-static void advanced_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void advanced_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *row, *sub;
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
uiLayoutSetPropSep(layout, true);
@@ -438,7 +434,7 @@ static void advanced_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_max_distance"));
uiItemR(sub, ptr, "max_distance", 0, "", ICON_NONE);
- uiItemR(layout, ptr, "ray_radius", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "ray_radius", 0, nullptr, ICON_NONE);
}
static void panelRegister(ARegionType *region_type)
@@ -447,11 +443,15 @@ static void panelRegister(ARegionType *region_type)
region_type, eModifierType_DataTransfer, panel_draw);
PanelType *vertex_panel = modifier_subpanel_register(
region_type, "vertex", "", vertex_panel_draw_header, vertex_panel_draw, panel_type);
- modifier_subpanel_register(
- region_type, "vertex_vgroup", "Vertex Groups", NULL, vertex_vgroup_panel_draw, vertex_panel);
+ modifier_subpanel_register(region_type,
+ "vertex_vgroup",
+ "Vertex Groups",
+ nullptr,
+ vertex_vgroup_panel_draw,
+ vertex_panel);
modifier_subpanel_register(
- region_type, "vert_vcol", "Colors", NULL, vert_vcol_panel_draw, vertex_panel);
+ region_type, "vert_vcol", "Colors", nullptr, vert_vcol_panel_draw, vertex_panel);
modifier_subpanel_register(
region_type, "edge", "", edge_panel_draw_header, edge_panel_draw, panel_type);
@@ -465,16 +465,16 @@ static void panelRegister(ARegionType *region_type)
modifier_subpanel_register(region_type,
"face_corner_vcol",
"Colors",
- NULL,
+ nullptr,
face_corner_vcol_panel_draw,
face_corner_panel);
modifier_subpanel_register(
- region_type, "face_corner_uv", "UVs", NULL, face_corner_uv_panel_draw, face_corner_panel);
+ region_type, "face_corner_uv", "UVs", nullptr, face_corner_uv_panel_draw, face_corner_panel);
modifier_subpanel_register(
region_type, "face", "", face_panel_draw_header, face_panel_draw, panel_type);
modifier_subpanel_register(
- region_type, "advanced", "Topology Mapping", NULL, advanced_panel_draw, panel_type);
+ region_type, "advanced", "Topology Mapping", nullptr, advanced_panel_draw, panel_type);
}
#undef DT_TYPES_AFFECT_MESH
@@ -491,24 +491,24 @@ ModifierTypeInfo modifierType_DataTransfer = {
/* copyData */ BKE_modifier_copydata_generic,
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
+ /* deformVerts */ nullptr,
+ /* deformMatrices */ nullptr,
+ /* deformVertsEM */ nullptr,
+ /* deformMatricesEM */ nullptr,
/* modifyMesh */ modifyMesh,
- /* modifyGeometrySet */ NULL,
+ /* modifyGeometrySet */ nullptr,
/* initData */ initData,
/* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
+ /* freeData */ nullptr,
/* isDisabled */ isDisabled,
/* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
+ /* dependsOnTime */ nullptr,
/* dependsOnNormals */ dependsOnNormals,
/* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* foreachTexLink */ nullptr,
+ /* freeRuntimeData */ nullptr,
/* panelRegister */ panelRegister,
- /* blendWrite */ NULL,
- /* blendRead */ NULL,
+ /* blendWrite */ nullptr,
+ /* blendRead */ nullptr,
};
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index 1615fb28007..059ded4f873 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -54,9 +54,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(dmd, DNA_struct_default_get(DecimateModifierData), modifier);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
DecimateModifierData *dmd = (DecimateModifierData *)md;
diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c
index ddaea289246..fc12a9c2aad 100644
--- a/source/blender/modifiers/intern/MOD_displace.c
+++ b/source/blender/modifiers/intern/MOD_displace.c
@@ -59,9 +59,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(dmd, DNA_struct_default_get(DisplaceModifierData), modifier);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
DisplaceModifierData *dmd = (DisplaceModifierData *)md;
@@ -324,7 +322,7 @@ static void displaceModifier_do(DisplaceModifierData *dmd,
}
else if (ELEM(direction, MOD_DISP_DIR_X, MOD_DISP_DIR_Y, MOD_DISP_DIR_Z, MOD_DISP_DIR_RGB_XYZ) &&
use_global_direction) {
- copy_m4_m4(local_mat, ob->obmat);
+ copy_m4_m4(local_mat, ob->object_to_world);
}
DisplaceUserdata data = {NULL};
diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c
index c23367f9b9b..c19c231d44c 100644
--- a/source/blender/modifiers/intern/MOD_dynamicpaint.c
+++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c
@@ -74,9 +74,7 @@ static void freeData(ModifierData *md)
dynamicPaint_Modifier_free(pmd);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c
index c8f1ef73d5e..b0806fed91c 100644
--- a/source/blender/modifiers/intern/MOD_explode.c
+++ b/source/blender/modifiers/intern/MOD_explode.c
@@ -5,6 +5,8 @@
* \ingroup modifiers
*/
+#define DNA_DEPRECATED_ALLOW /* For #ME_FACE_SEL. */
+
#include "BLI_utildefines.h"
#include "BLI_edgehash.h"
@@ -76,9 +78,7 @@ static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *UNUSED(md))
{
return true;
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
ExplodeModifierData *emd = (ExplodeModifierData *)md;
@@ -985,9 +985,9 @@ static Mesh *explodeMesh(ExplodeModifierData *emd,
MTFace *mtface = CustomData_get_layer_named(&explode->fdata, CD_MTFACE, emd->uvname);
/* getting back to object space */
- invert_m4_m4(imat, ctx->object->obmat);
+ invert_m4_m4(imat, ctx->object->object_to_world);
- psmd->psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
+ psys_sim_data_init(&sim);
const MVert *mesh_verts = BKE_mesh_verts(mesh);
MVert *explode_verts = BKE_mesh_verts_for_write(explode);
@@ -1020,7 +1020,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd,
psys_get_particle_state(&sim, ed_v2, &state, 1);
vertco = explode_verts[v].co;
- mul_m4_v3(ctx->object->obmat, vertco);
+ mul_m4_v3(ctx->object->object_to_world, vertco);
sub_v3_v3(vertco, birth.co);
@@ -1112,10 +1112,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd,
BKE_mesh_calc_edges_tessface(explode);
BKE_mesh_convert_mfaces_to_mpolys(explode);
- if (psmd->psys->lattice_deform_data) {
- BKE_lattice_deform_data_destroy(psmd->psys->lattice_deform_data);
- psmd->psys->lattice_deform_data = NULL;
- }
+ psys_sim_data_free(&sim);
return explode;
}
diff --git a/source/blender/modifiers/intern/MOD_fluid.c b/source/blender/modifiers/intern/MOD_fluid.c
index 3ab6d08ee15..0a2b01fe101 100644
--- a/source/blender/modifiers/intern/MOD_fluid.c
+++ b/source/blender/modifiers/intern/MOD_fluid.c
@@ -78,9 +78,7 @@ static void freeData(ModifierData *md)
#endif /* WITH_FLUID */
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
FluidModifierData *fmd = (FluidModifierData *)md;
diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c
index 1336b896cae..231c65998e0 100644
--- a/source/blender/modifiers/intern/MOD_hook.c
+++ b/source/blender/modifiers/intern/MOD_hook.c
@@ -68,9 +68,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla
thmd->indexar = MEM_dupallocN(hmd->indexar);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
HookModifierData *hmd = (HookModifierData *)md;
@@ -340,14 +338,14 @@ static void deformVerts_do(HookModifierData *hmd,
/* get world-space matrix of target, corrected for the space the verts are in */
if (hmd->subtarget[0] && pchan) {
/* bone target if there's a matching pose-channel */
- mul_m4_m4m4(dmat, ob_target->obmat, pchan->pose_mat);
+ mul_m4_m4m4(dmat, ob_target->object_to_world, pchan->pose_mat);
}
else {
/* just object target */
- copy_m4_m4(dmat, ob_target->obmat);
+ copy_m4_m4(dmat, ob_target->object_to_world);
}
- invert_m4_m4(ob->imat, ob->obmat);
- mul_m4_series(hd.mat, ob->imat, dmat, hmd->parentinv);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
+ mul_m4_series(hd.mat, ob->world_to_object, dmat, hmd->parentinv);
/* --- done with 'hd' init --- */
/* Regarding index range checking below.
diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c
index 479ea25b09e..b2b97bc0d08 100644
--- a/source/blender/modifiers/intern/MOD_laplaciandeform.c
+++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c
@@ -747,9 +747,7 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
return 1;
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)md;
diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
index 13193d7eb11..1534708ac72 100644
--- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c
+++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
@@ -66,8 +66,6 @@ struct BLaplacianSystem {
};
typedef struct BLaplacianSystem LaplacianSystem;
-static void required_data_mask(Object *ob, ModifierData *md, CustomData_MeshMasks *r_cddata_masks);
-static bool is_disabled(const struct Scene *scene, ModifierData *md, bool useRenderParams);
static float compute_volume(const float center[3],
float (*vertexCos)[3],
const MPoly *mpoly,
@@ -511,9 +509,7 @@ static bool is_disabled(const struct Scene *UNUSED(scene),
return 0;
}
-static void required_data_mask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
LaplacianSmoothModifierData *smd = (LaplacianSmoothModifierData *)md;
diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c
index 81b60b660c6..ede2d7b581e 100644
--- a/source/blender/modifiers/intern/MOD_lattice.c
+++ b/source/blender/modifiers/intern/MOD_lattice.c
@@ -47,9 +47,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(lmd, DNA_struct_default_get(LatticeModifierData), modifier);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
LatticeModifierData *lmd = (LatticeModifierData *)md;
diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc
index b3ee6a1f4ca..659a1625079 100644
--- a/source/blender/modifiers/intern/MOD_mask.cc
+++ b/source/blender/modifiers/intern/MOD_mask.cc
@@ -64,9 +64,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(mmd, DNA_struct_default_get(MaskModifierData), modifier);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *UNUSED(md),
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData * /*md*/, CustomData_MeshMasks *r_cddata_masks)
{
r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
}
@@ -609,7 +607,7 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh,
cut_edge.v1 = dst_loops[mp_dst.loopstart].v;
cut_edge.v2 = cut_dst_loop.v;
BLI_assert(cut_edge.v1 != cut_edge.v2);
- cut_edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
+ cut_edge.flag = ME_EDGEDRAW;
edge_index++;
/* Only handle one of the cuts per iteration. */
@@ -638,7 +636,7 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh,
* 2. Find edges and polygons only using those vertices.
* 3. Create a new mesh that only uses the found vertices, edges and polygons.
*/
-static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
+static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext * /*ctx*/, Mesh *mesh)
{
MaskModifierData *mmd = reinterpret_cast<MaskModifierData *>(md);
const bool invert_mask = mmd->flag & MOD_MASK_INV;
@@ -652,7 +650,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx)
}
/* Quick test to see if we can return early. */
- if (!(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) || (mesh->totvert == 0) ||
+ if (!ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP) || (mesh->totvert == 0) ||
BLI_listbase_is_empty(&mesh->vertex_group_names)) {
return mesh;
}
@@ -781,9 +779,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx)
return result;
}
-static bool isDisabled(const struct Scene *UNUSED(scene),
- ModifierData *md,
- bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene * /*scene*/, ModifierData *md, bool /*useRenderParams*/)
{
MaskModifierData *mmd = reinterpret_cast<MaskModifierData *>(md);
@@ -795,7 +791,7 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
return mmd->ob_arm && mmd->ob_arm->type != OB_ARMATURE;
}
-static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *sub, *row;
uiLayout *layout = panel->layout;
diff --git a/source/blender/modifiers/intern/MOD_mesh_to_volume.cc b/source/blender/modifiers/intern/MOD_mesh_to_volume.cc
index 0471beadcc1..fa7f0690675 100644
--- a/source/blender/modifiers/intern/MOD_mesh_to_volume.cc
+++ b/source/blender/modifiers/intern/MOD_mesh_to_volume.cc
@@ -75,7 +75,7 @@ static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *u
walk(userData, ob, (ID **)&mvmd->object, IDWALK_CB_NOP);
}
-static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
@@ -134,8 +134,8 @@ static Volume *mesh_to_volume(ModifierData *md,
}
BKE_mesh_wrapper_ensure_mdata(mesh);
- const float4x4 mesh_to_own_object_space_transform = float4x4(ctx->object->imat) *
- float4x4(object_to_convert->obmat);
+ const float4x4 mesh_to_own_object_space_transform = float4x4(ctx->object->world_to_object) *
+ float4x4(object_to_convert->object_to_world);
geometry::MeshToVolumeResolution resolution;
resolution.mode = (MeshToVolumeModifierResolutionMode)mvmd->resolution_mode;
if (resolution.mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT) {
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index 04d17cec10d..2aaaee2ccc7 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -119,9 +119,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla
}
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
@@ -360,8 +358,8 @@ static void meshdeformModifier_do(ModifierData *md,
}
/* compute matrices to go in and out of cage object space */
- invert_m4_m4(imat, ob_target->obmat);
- mul_m4_m4m4(cagemat, imat, ob->obmat);
+ invert_m4_m4(imat, ob_target->object_to_world);
+ mul_m4_m4m4(cagemat, imat, ob->object_to_world);
mul_m4_m4m4(cmat, mmd->bindmat, cagemat);
invert_m4_m4(iobmat, cmat);
copy_m3_m4(icagemat, iobmat);
diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.cc b/source/blender/modifiers/intern/MOD_meshsequencecache.cc
index f30e6a95787..13931179b35 100644
--- a/source/blender/modifiers/intern/MOD_meshsequencecache.cc
+++ b/source/blender/modifiers/intern/MOD_meshsequencecache.cc
@@ -98,9 +98,7 @@ static void freeData(ModifierData *md)
}
}
-static bool isDisabled(const struct Scene *UNUSED(scene),
- ModifierData *md,
- bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene * /*scene*/, ModifierData *md, bool /*useRenderParams*/)
{
MeshSeqCacheModifierData *mcmd = reinterpret_cast<MeshSeqCacheModifierData *>(md);
@@ -135,7 +133,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
CacheFile *cache_file = mcmd->cache_file;
const float frame = DEG_get_ctime(ctx->depsgraph);
- const double time = BKE_cachefile_time_offset(cache_file, (double)frame, FPS);
+ const double time = BKE_cachefile_time_offset(cache_file, double(frame), FPS);
const char *err_str = nullptr;
if (!mcmd->reader || !STREQ(mcmd->reader_object_path, mcmd->object_path)) {
@@ -305,7 +303,7 @@ static void panel_draw(const bContext *C, Panel *panel)
modifier_panel_end(layout, ptr);
}
-static void velocity_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void velocity_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
@@ -322,7 +320,7 @@ static void velocity_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(layout, ptr, "velocity_scale", 0, nullptr, ICON_NONE);
}
-static void time_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void time_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
@@ -391,7 +389,7 @@ static void panelRegister(ARegionType *region_type)
panel_type);
}
-static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md)
+static void blendRead(BlendDataReader * /*reader*/, ModifierData *md)
{
MeshSeqCacheModifierData *msmcd = reinterpret_cast<MeshSeqCacheModifierData *>(md);
msmcd->reader = nullptr;
diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.cc
index cdad834f9b4..2bc3763c46b 100644
--- a/source/blender/modifiers/intern/MOD_multires.c
+++ b/source/blender/modifiers/intern/MOD_multires.cc
@@ -5,7 +5,7 @@
* \ingroup modifiers
*/
-#include <stddef.h>
+#include <cstddef>
#include "MEM_guardedalloc.h"
@@ -45,10 +45,10 @@
#include "MOD_modifiertypes.h"
#include "MOD_ui_common.h"
-typedef struct MultiresRuntimeData {
+struct MultiresRuntimeData {
/* Cached subdivision surface descriptor, with topology and settings. */
struct Subdiv *subdiv;
-} MultiresRuntimeData;
+};
static void initData(ModifierData *md)
{
@@ -62,9 +62,7 @@ static void initData(ModifierData *md)
md->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT | UI_SUBPANEL_DATA_EXPAND_1;
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
MultiresModifierData *mmd = (MultiresModifierData *)md;
if (mmd->flags & eMultiresModifierFlag_UseCustomNormals) {
@@ -89,11 +87,11 @@ static void copyData(const ModifierData *md_src, ModifierData *md_dst, const int
static void freeRuntimeData(void *runtime_data_v)
{
- if (runtime_data_v == NULL) {
+ if (runtime_data_v == nullptr) {
return;
}
MultiresRuntimeData *runtime_data = (MultiresRuntimeData *)runtime_data_v;
- if (runtime_data->subdiv != NULL) {
+ if (runtime_data->subdiv != nullptr) {
BKE_subdiv_free(runtime_data->subdiv);
}
MEM_freeN(runtime_data);
@@ -108,8 +106,9 @@ static void freeData(ModifierData *md)
static MultiresRuntimeData *multires_ensure_runtime(MultiresModifierData *mmd)
{
MultiresRuntimeData *runtime_data = (MultiresRuntimeData *)mmd->modifier.runtime;
- if (runtime_data == NULL) {
- runtime_data = MEM_callocN(sizeof(*runtime_data), "subsurf runtime");
+ if (runtime_data == nullptr) {
+ runtime_data = static_cast<MultiresRuntimeData *>(
+ MEM_callocN(sizeof(*runtime_data), __func__));
mmd->modifier.runtime = runtime_data;
}
return runtime_data;
@@ -191,8 +190,8 @@ static Mesh *multires_as_ccg(MultiresModifierData *mmd,
/* NOTE: CCG becomes an owner of Subdiv descriptor, so can not share
* this pointer. Not sure if it's needed, but might have a second look
* on the ownership model here. */
- MultiresRuntimeData *runtime_data = mmd->modifier.runtime;
- runtime_data->subdiv = NULL;
+ MultiresRuntimeData *runtime_data = static_cast<MultiresRuntimeData *>(mmd->modifier.runtime);
+ runtime_data->subdiv = nullptr;
return result;
}
@@ -212,8 +211,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
MultiresRuntimeData *runtime_data = multires_ensure_runtime(mmd);
Subdiv *subdiv = subdiv_descriptor_ensure(mmd, &subdiv_settings, mesh);
- if (subdiv == NULL) {
- /* Happens on bad topology, ut also on empty input mesh. */
+ if (subdiv == nullptr) {
+ /* Happens on bad topology, also on empty input mesh. */
return result;
}
const bool use_clnors = mmd->flags & eMultiresModifierFlag_UseCustomNormals &&
@@ -231,23 +230,23 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco && !for_render && !sculpt_base_mesh) {
/* NOTE: CCG takes ownership over Subdiv. */
result = multires_as_ccg(mmd, ctx, mesh, subdiv);
- result->runtime.subdiv_ccg_tot_level = mmd->totlvl;
+ result->runtime->subdiv_ccg_tot_level = mmd->totlvl;
/* TODO(sergey): Usually it is sculpt stroke's update variants which
* takes care of this, but is possible that we need this before the
* stroke: i.e. when exiting blender right after stroke is done.
* Annoying and not so much black-boxed as far as sculpting goes, and
* surely there is a better way of solving this. */
- if (ctx->object->sculpt != NULL) {
+ if (ctx->object->sculpt != nullptr) {
SculptSession *sculpt_session = ctx->object->sculpt;
- sculpt_session->subdiv_ccg = result->runtime.subdiv_ccg;
+ sculpt_session->subdiv_ccg = result->runtime->subdiv_ccg;
sculpt_session->multires.active = true;
sculpt_session->multires.modifier = mmd;
sculpt_session->multires.level = mmd->sculptlvl;
sculpt_session->totvert = mesh->totvert;
sculpt_session->totpoly = mesh->totpoly;
- sculpt_session->mvert = NULL;
- sculpt_session->mpoly = NULL;
- sculpt_session->mloop = NULL;
+ sculpt_session->mvert = nullptr;
+ sculpt_session->mpoly = nullptr;
+ sculpt_session->mloop = nullptr;
}
// BKE_subdiv_stats_print(&subdiv->stats);
}
@@ -262,8 +261,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
result = multires_as_mesh(mmd, ctx, mesh, subdiv);
if (use_clnors) {
- float(*lnors)[3] = CustomData_get_layer(&result->ldata, CD_NORMAL);
- BLI_assert(lnors != NULL);
+ float(*lnors)[3] = static_cast<float(*)[3]>(CustomData_get_layer(&result->ldata, CD_NORMAL));
+ BLI_assert(lnors != nullptr);
BKE_mesh_set_custom_normals(result, lnors);
CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
CustomData_set_layer_flag(&result->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
@@ -308,8 +307,8 @@ static void deformMatrices(ModifierData *md,
MultiresRuntimeData *runtime_data = multires_ensure_runtime(mmd);
Subdiv *subdiv = subdiv_descriptor_ensure(mmd, &subdiv_settings, mesh);
- if (subdiv == NULL) {
- /* Happens on bad topology, ut also on empty input mesh. */
+ if (subdiv == nullptr) {
+ /* Happens on bad topology, also on empty input mesh. */
return;
}
BKE_subdiv_displacement_attach_from_multires(subdiv, mesh, mmd);
@@ -324,7 +323,7 @@ static void panel_draw(const bContext *C, Panel *panel)
uiLayout *col;
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
uiLayoutSetPropSep(layout, true);
@@ -339,12 +338,12 @@ static void panel_draw(const bContext *C, Panel *panel)
uiItemR(col, ptr, "use_sculpt_base_mesh", 0, IFACE_("Sculpt Base Mesh"), ICON_NONE);
UI_block_lock_clear(block);
- uiItemR(layout, ptr, "show_only_control_edges", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "show_only_control_edges", 0, nullptr, ICON_NONE);
modifier_panel_end(layout, ptr);
}
-static void subdivisions_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void subdivisions_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *row;
uiLayout *layout = panel->layout;
@@ -372,7 +371,7 @@ static void subdivisions_panel_draw(const bContext *UNUSED(C), Panel *panel)
"OBJECT_OT_multires_subdivide",
IFACE_("Subdivide"),
ICON_NONE,
- NULL,
+ nullptr,
WM_OP_EXEC_DEFAULT,
0,
&op_ptr);
@@ -384,7 +383,7 @@ static void subdivisions_panel_draw(const bContext *UNUSED(C), Panel *panel)
"OBJECT_OT_multires_subdivide",
IFACE_("Simple"),
ICON_NONE,
- NULL,
+ nullptr,
WM_OP_EXEC_DEFAULT,
0,
&op_ptr);
@@ -394,7 +393,7 @@ static void subdivisions_panel_draw(const bContext *UNUSED(C), Panel *panel)
"OBJECT_OT_multires_subdivide",
IFACE_("Linear"),
ICON_NONE,
- NULL,
+ nullptr,
WM_OP_EXEC_DEFAULT,
0,
&op_ptr);
@@ -407,7 +406,7 @@ static void subdivisions_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemO(layout, IFACE_("Delete Higher"), ICON_NONE, "OBJECT_OT_multires_higher_levels_delete");
}
-static void shape_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void shape_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *row;
uiLayout *layout = panel->layout;
@@ -422,12 +421,12 @@ static void shape_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemO(row, IFACE_("Apply Base"), ICON_NONE, "OBJECT_OT_multires_base_apply");
}
-static void generate_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void generate_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *col, *row;
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
MultiresModifierData *mmd = (MultiresModifierData *)ptr->data;
bool is_external = RNA_boolean_get(ptr, "is_external");
@@ -443,19 +442,19 @@ static void generate_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemO(row, IFACE_("Pack External"), ICON_NONE, "OBJECT_OT_multires_external_pack");
uiLayoutSetPropSep(col, true);
row = uiLayoutRow(col, false);
- uiItemR(row, ptr, "filepath", 0, NULL, ICON_NONE);
+ uiItemR(row, ptr, "filepath", 0, nullptr, ICON_NONE);
}
else {
uiItemO(col, IFACE_("Save External..."), ICON_NONE, "OBJECT_OT_multires_external_save");
}
}
-static void advanced_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void advanced_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *col;
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
bool has_displacement = RNA_int_get(ptr, "total_levels") != 0;
@@ -463,27 +462,27 @@ static void advanced_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetActive(layout, !has_displacement);
- uiItemR(layout, ptr, "quality", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "quality", 0, nullptr, ICON_NONE);
col = uiLayoutColumn(layout, false);
uiLayoutSetActive(col, true);
- uiItemR(col, ptr, "uv_smooth", 0, NULL, ICON_NONE);
- uiItemR(col, ptr, "boundary_smooth", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "uv_smooth", 0, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "boundary_smooth", 0, nullptr, ICON_NONE);
- uiItemR(layout, ptr, "use_creases", 0, NULL, ICON_NONE);
- uiItemR(layout, ptr, "use_custom_normals", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_creases", 0, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "use_custom_normals", 0, nullptr, ICON_NONE);
}
static void panelRegister(ARegionType *region_type)
{
PanelType *panel_type = modifier_panel_register(region_type, eModifierType_Multires, panel_draw);
modifier_subpanel_register(
- region_type, "subdivide", "Subdivision", NULL, subdivisions_panel_draw, panel_type);
- modifier_subpanel_register(region_type, "shape", "Shape", NULL, shape_panel_draw, panel_type);
+ region_type, "subdivide", "Subdivision", nullptr, subdivisions_panel_draw, panel_type);
+ modifier_subpanel_register(region_type, "shape", "Shape", nullptr, shape_panel_draw, panel_type);
modifier_subpanel_register(
- region_type, "generate", "Generate", NULL, generate_panel_draw, panel_type);
+ region_type, "generate", "Generate", nullptr, generate_panel_draw, panel_type);
modifier_subpanel_register(
- region_type, "advanced", "Advanced", NULL, advanced_panel_draw, panel_type);
+ region_type, "advanced", "Advanced", nullptr, advanced_panel_draw, panel_type);
}
ModifierTypeInfo modifierType_Multires = {
@@ -498,24 +497,24 @@ ModifierTypeInfo modifierType_Multires = {
/* copyData */ copyData,
- /* deformVerts */ NULL,
+ /* deformVerts */ nullptr,
/* deformMatrices */ deformMatrices,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
+ /* deformVertsEM */ nullptr,
+ /* deformMatricesEM */ nullptr,
/* modifyMesh */ modifyMesh,
- /* modifyGeometrySet */ NULL,
+ /* modifyGeometrySet */ nullptr,
/* initData */ initData,
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
+ /* isDisabled */ nullptr,
+ /* updateDepsgraph */ nullptr,
+ /* dependsOnTime */ nullptr,
/* dependsOnNormals */ dependsOnNormals,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
+ /* foreachIDLink */ nullptr,
+ /* foreachTexLink */ nullptr,
/* freeRuntimeData */ freeRuntimeData,
/* panelRegister */ panelRegister,
- /* blendWrite */ NULL,
- /* blendRead */ NULL,
+ /* blendWrite */ nullptr,
+ /* blendRead */ nullptr,
};
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index ffd78a90638..15d7e494c04 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -33,6 +33,7 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
+#include "DNA_view3d_types.h"
#include "DNA_windowmanager_types.h"
#include "BKE_attribute_math.hh"
@@ -80,6 +81,7 @@
#include "ED_screen.h"
#include "ED_spreadsheet.h"
#include "ED_undo.h"
+#include "ED_viewer_path.hh"
#include "NOD_geometry.h"
#include "NOD_geometry_nodes_lazy_function.hh"
@@ -114,7 +116,9 @@ using blender::StringRef;
using blender::StringRefNull;
using blender::Vector;
using blender::bke::AttributeMetaData;
+using blender::bke::AttributeValidator;
using blender::fn::Field;
+using blender::fn::FieldOperation;
using blender::fn::GField;
using blender::fn::ValueOrField;
using blender::fn::ValueOrFieldCPPType;
@@ -201,6 +205,9 @@ static bool node_needs_own_transform_relation(const bNode &node)
return storage.transform_space == GEO_NODE_TRANSFORM_SPACE_RELATIVE;
}
+ if (node.type == GEO_NODE_SELF_OBJECT) {
+ return true;
+ }
if (node.type == GEO_NODE_DEFORM_CURVES_ON_SURFACE) {
return true;
}
@@ -342,7 +349,7 @@ static bool check_tree_for_time_node(const bNodeTree &tree,
return false;
}
-static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *md)
+static bool dependsOnTime(struct Scene * /*scene*/, ModifierData *md)
{
const NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md);
const bNodeTree *tree = nmd->node_group;
@@ -380,9 +387,7 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void
walk(userData, ob, md, "texture");
}
-static bool isDisabled(const struct Scene *UNUSED(scene),
- ModifierData *md,
- bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene * /*scene*/, ModifierData *md, bool /*useRenderParams*/)
{
NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md);
@@ -438,8 +443,8 @@ id_property_create_from_socket(const bNodeSocket &socket)
auto property = bke::idprop::create(socket.identifier, value->value);
IDPropertyUIDataFloat *ui_data = (IDPropertyUIDataFloat *)IDP_ui_data_ensure(property.get());
ui_data->base.rna_subtype = value->subtype;
- ui_data->min = ui_data->soft_min = (double)value->min;
- ui_data->max = ui_data->soft_max = (double)value->max;
+ ui_data->min = ui_data->soft_min = double(value->min);
+ ui_data->max = ui_data->soft_max = double(value->max);
ui_data->default_value = value->value;
return property;
}
@@ -461,8 +466,8 @@ id_property_create_from_socket(const bNodeSocket &socket)
socket.identifier, Span<float>{value->value[0], value->value[1], value->value[2]});
IDPropertyUIDataFloat *ui_data = (IDPropertyUIDataFloat *)IDP_ui_data_ensure(property.get());
ui_data->base.rna_subtype = value->subtype;
- ui_data->min = ui_data->soft_min = (double)value->min;
- ui_data->max = ui_data->soft_max = (double)value->max;
+ ui_data->min = ui_data->soft_min = double(value->min);
+ ui_data->max = ui_data->soft_max = double(value->max);
ui_data->default_array = (double *)MEM_mallocN(sizeof(double[3]), "mod_prop_default");
ui_data->default_array_len = 3;
for (const int i : IndexRange(3)) {
@@ -574,7 +579,7 @@ static void init_socket_cpp_value_from_property(const IDProperty &property,
value = IDP_Float(&property);
}
else if (property.type == IDP_DOUBLE) {
- value = (float)IDP_Double(&property);
+ value = float(IDP_Double(&property));
}
new (r_value) ValueOrField<float>(value);
break;
@@ -823,25 +828,6 @@ static void initialize_group_input(NodesModifierData &nmd,
}
}
-static Vector<SpaceSpreadsheet *> find_spreadsheet_editors(Main *bmain)
-{
- wmWindowManager *wm = (wmWindowManager *)bmain->wm.first;
- if (wm == nullptr) {
- return {};
- }
- Vector<SpaceSpreadsheet *> spreadsheets;
- LISTBASE_FOREACH (wmWindow *, window, &wm->windows) {
- bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook);
- LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
- SpaceLink *sl = (SpaceLink *)area->spacedata.first;
- if (sl->spacetype == SPACE_SPREADSHEET) {
- spreadsheets.append((SpaceSpreadsheet *)sl);
- }
- }
- }
- return spreadsheets;
-}
-
static const lf::FunctionNode &find_viewer_lf_node(const bNode &viewer_bnode)
{
return *blender::nodes::ensure_geometry_nodes_lazy_function_graph(viewer_bnode.owner_tree())
@@ -853,50 +839,33 @@ static const lf::FunctionNode &find_group_lf_node(const bNode &group_bnode)
->mapping.group_node_map.lookup(&group_bnode);
}
-static void find_side_effect_nodes_for_spreadsheet(
- const SpaceSpreadsheet &sspreadsheet,
+static void find_side_effect_nodes_for_viewer_path(
+ const ViewerPath &viewer_path,
const NodesModifierData &nmd,
const ModifierEvalContext &ctx,
- const bNodeTree &root_tree,
MultiValueMap<blender::ComputeContextHash, const lf::FunctionNode *> &r_side_effect_nodes)
{
- Vector<SpreadsheetContext *> context_path = sspreadsheet.context_path;
- if (context_path.size() < 3) {
+ const std::optional<blender::ed::viewer_path::ViewerPathForGeometryNodesViewer> parsed_path =
+ blender::ed::viewer_path::parse_geometry_nodes_viewer(viewer_path);
+ if (!parsed_path.has_value()) {
return;
}
- if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) {
+ if (parsed_path->object != DEG_get_original_object(ctx.object)) {
return;
}
- if (context_path[1]->type != SPREADSHEET_CONTEXT_MODIFIER) {
+ if (parsed_path->modifier_name != nmd.modifier.name) {
return;
}
- SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context_path[0];
- if (object_context->object != DEG_get_original_object(ctx.object)) {
- return;
- }
- SpreadsheetContextModifier *modifier_context = (SpreadsheetContextModifier *)context_path[1];
- if (StringRef(modifier_context->modifier_name) != nmd.modifier.name) {
- return;
- }
- for (SpreadsheetContext *context : context_path.as_span().drop_front(2)) {
- if (context->type != SPREADSHEET_CONTEXT_NODE) {
- return;
- }
- }
blender::ComputeContextBuilder compute_context_builder;
- compute_context_builder.push<blender::bke::ModifierComputeContext>(nmd.modifier.name);
-
- const Span<SpreadsheetContextNode *> nested_group_contexts =
- context_path.as_span().drop_front(2).drop_back(1).cast<SpreadsheetContextNode *>();
- const SpreadsheetContextNode *last_context = (SpreadsheetContextNode *)context_path.last();
+ compute_context_builder.push<blender::bke::ModifierComputeContext>(parsed_path->modifier_name);
+ const bNodeTree *group = nmd.node_group;
Stack<const bNode *> group_node_stack;
- const bNodeTree *group = &root_tree;
- for (SpreadsheetContextNode *node_context : nested_group_contexts) {
+ for (const StringRefNull group_node_name : parsed_path->group_node_names) {
const bNode *found_node = nullptr;
for (const bNode *node : group->group_nodes()) {
- if (STREQ(node->name, node_context->node_name)) {
+ if (node->name == group_node_name) {
found_node = node;
break;
}
@@ -907,14 +876,17 @@ static void find_side_effect_nodes_for_spreadsheet(
if (found_node->id == nullptr) {
return;
}
+ if (found_node->is_muted()) {
+ return;
+ }
group_node_stack.push(found_node);
- group = reinterpret_cast<const bNodeTree *>(found_node->id);
- compute_context_builder.push<blender::bke::NodeGroupComputeContext>(node_context->node_name);
+ group = reinterpret_cast<bNodeTree *>(found_node->id);
+ compute_context_builder.push<blender::bke::NodeGroupComputeContext>(group_node_name);
}
const bNode *found_viewer_node = nullptr;
for (const bNode *viewer_node : group->nodes_by_type("GeometryNodeViewer")) {
- if (STREQ(viewer_node->name, last_context->node_name)) {
+ if (viewer_node->name == parsed_path->viewer_node_name) {
found_viewer_node = viewer_node;
break;
}
@@ -938,16 +910,29 @@ static void find_side_effect_nodes_for_spreadsheet(
static void find_side_effect_nodes(
const NodesModifierData &nmd,
const ModifierEvalContext &ctx,
- const bNodeTree &tree,
MultiValueMap<blender::ComputeContextHash, const lf::FunctionNode *> &r_side_effect_nodes)
{
Main *bmain = DEG_get_bmain(ctx.depsgraph);
-
- /* Based on every visible spreadsheet context path, get a list of sockets that need to have their
- * intermediate geometries cached for display. */
- Vector<SpaceSpreadsheet *> spreadsheets = find_spreadsheet_editors(bmain);
- for (SpaceSpreadsheet *sspreadsheet : spreadsheets) {
- find_side_effect_nodes_for_spreadsheet(*sspreadsheet, nmd, ctx, tree, r_side_effect_nodes);
+ wmWindowManager *wm = (wmWindowManager *)bmain->wm.first;
+ if (wm == nullptr) {
+ return;
+ }
+ LISTBASE_FOREACH (const wmWindow *, window, &wm->windows) {
+ const bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook);
+ const WorkSpace *workspace = BKE_workspace_active_get(window->workspace_hook);
+ find_side_effect_nodes_for_viewer_path(workspace->viewer_path, nmd, ctx, r_side_effect_nodes);
+ LISTBASE_FOREACH (const ScrArea *, area, &screen->areabase) {
+ const SpaceLink *sl = static_cast<SpaceLink *>(area->spacedata.first);
+ if (sl->spacetype == SPACE_SPREADSHEET) {
+ const SpaceSpreadsheet &sspreadsheet = *reinterpret_cast<const SpaceSpreadsheet *>(sl);
+ find_side_effect_nodes_for_viewer_path(
+ sspreadsheet.viewer_path, nmd, ctx, r_side_effect_nodes);
+ }
+ if (sl->spacetype == SPACE_VIEW3D) {
+ const View3D &v3d = *reinterpret_cast<const View3D *>(sl);
+ find_side_effect_nodes_for_viewer_path(v3d.viewer_path, nmd, ctx, r_side_effect_nodes);
+ }
+ }
}
}
@@ -1046,13 +1031,15 @@ static Vector<OutputAttributeToStore> compute_attributes_to_store(
blender::fn::FieldEvaluator field_evaluator{field_context, domain_size};
for (const OutputAttributeInfo &output_info : outputs_info) {
const CPPType &type = output_info.field.cpp_type();
+ const AttributeValidator validator = attributes.lookup_validator(output_info.name);
OutputAttributeToStore store{
component_type,
domain,
output_info.name,
GMutableSpan{
type, MEM_malloc_arrayN(domain_size, type.size(), __func__), domain_size}};
- field_evaluator.add_with_destination(output_info.field, store.data);
+ GField field = validator.validate_field_if_necessary(output_info.field);
+ field_evaluator.add_with_destination(std::move(field), store.data);
attributes_to_store.append(store);
}
field_evaluator.evaluate();
@@ -1142,8 +1129,7 @@ static GeometrySet compute_geometry(
Array<bool> param_set_outputs(graph_outputs.size(), false);
blender::nodes::GeometryNodesLazyFunctionLogger lf_logger(lf_graph_info);
- blender::nodes::GeometryNodesLazyFunctionSideEffectProvider lf_side_effect_provider(
- lf_graph_info);
+ blender::nodes::GeometryNodesLazyFunctionSideEffectProvider lf_side_effect_provider;
lf::GraphExecutor graph_executor{
lf_graph_info.graph, graph_inputs, graph_outputs, &lf_logger, &lf_side_effect_provider};
@@ -1156,7 +1142,7 @@ static GeometrySet compute_geometry(
geo_nodes_modifier_data.eval_log = eval_log.get();
}
MultiValueMap<blender::ComputeContextHash, const lf::FunctionNode *> r_side_effect_nodes;
- find_side_effect_nodes(*nmd, *ctx, btree, r_side_effect_nodes);
+ find_side_effect_nodes(*nmd, *ctx, r_side_effect_nodes);
geo_nodes_modifier_data.side_effect_nodes = &r_side_effect_nodes;
blender::nodes::GeoNodesLFUserData user_data;
user_data.modifier_data = &geo_nodes_modifier_data;
@@ -1556,15 +1542,18 @@ static void add_attribute_search_or_value_buttons(const bContext &C,
const std::string rna_path_attribute_name = "[\"" + std::string(socket_id_esc) +
attribute_name_suffix + "\"]";
+ /* We're handling this manually in this case. */
+ uiLayoutSetPropDecorate(layout, false);
+
uiLayout *split = uiLayoutSplit(layout, 0.4f, false);
uiLayout *name_row = uiLayoutRow(split, false);
uiLayoutSetAlignment(name_row, UI_LAYOUT_ALIGN_RIGHT);
uiItemL(name_row, socket.name, ICON_NONE);
- uiLayout *row = uiLayoutRow(split, true);
+ uiLayout *prop_row = uiLayoutRow(split, true);
PointerRNA props;
- uiItemFullO(row,
+ uiItemFullO(prop_row,
"object.geometry_nodes_input_attribute_toggle",
"",
ICON_SPREADSHEET,
@@ -1577,12 +1566,12 @@ static void add_attribute_search_or_value_buttons(const bContext &C,
const int use_attribute = RNA_int_get(md_ptr, rna_path_use_attribute.c_str()) != 0;
if (use_attribute) {
- add_attribute_search_button(C, row, nmd, md_ptr, rna_path_attribute_name, socket, false);
- uiItemL(row, "", ICON_BLANK1);
+ add_attribute_search_button(C, prop_row, nmd, md_ptr, rna_path_attribute_name, socket, false);
+ uiItemL(layout, "", ICON_BLANK1);
}
else {
- uiItemR(row, md_ptr, rna_path.c_str(), 0, "", ICON_NONE);
- uiItemDecoratorR(row, md_ptr, rna_path.c_str(), -1);
+ uiItemR(prop_row, md_ptr, rna_path.c_str(), 0, "", ICON_NONE);
+ uiItemDecoratorR(layout, md_ptr, rna_path.c_str(), -1);
}
}
@@ -1612,44 +1601,39 @@ static void draw_property_for_socket(const bContext &C,
char rna_path[sizeof(socket_id_esc) + 4];
BLI_snprintf(rna_path, ARRAY_SIZE(rna_path), "[\"%s\"]", socket_id_esc);
+ uiLayout *row = uiLayoutRow(layout, true);
+ uiLayoutSetPropDecorate(row, true);
+
/* Use #uiItemPointerR to draw pointer properties because #uiItemR would not have enough
* information about what type of ID to select for editing the values. This is because
* pointer IDProperties contain no information about their type. */
switch (socket.type) {
case SOCK_OBJECT: {
- uiItemPointerR(
- layout, md_ptr, rna_path, bmain_ptr, "objects", socket.name, ICON_OBJECT_DATA);
+ uiItemPointerR(row, md_ptr, rna_path, bmain_ptr, "objects", socket.name, ICON_OBJECT_DATA);
break;
}
case SOCK_COLLECTION: {
- uiItemPointerR(layout,
- md_ptr,
- rna_path,
- bmain_ptr,
- "collections",
- socket.name,
- ICON_OUTLINER_COLLECTION);
+ uiItemPointerR(
+ row, md_ptr, rna_path, bmain_ptr, "collections", socket.name, ICON_OUTLINER_COLLECTION);
break;
}
case SOCK_MATERIAL: {
- uiItemPointerR(layout, md_ptr, rna_path, bmain_ptr, "materials", socket.name, ICON_MATERIAL);
+ uiItemPointerR(row, md_ptr, rna_path, bmain_ptr, "materials", socket.name, ICON_MATERIAL);
break;
}
case SOCK_TEXTURE: {
- uiItemPointerR(layout, md_ptr, rna_path, bmain_ptr, "textures", socket.name, ICON_TEXTURE);
+ uiItemPointerR(row, md_ptr, rna_path, bmain_ptr, "textures", socket.name, ICON_TEXTURE);
break;
}
case SOCK_IMAGE: {
- uiItemPointerR(layout, md_ptr, rna_path, bmain_ptr, "images", socket.name, ICON_IMAGE);
+ uiItemPointerR(row, md_ptr, rna_path, bmain_ptr, "images", socket.name, ICON_IMAGE);
break;
}
default: {
if (input_has_attribute_toggle(*nmd->node_group, socket_index)) {
- add_attribute_search_or_value_buttons(C, layout, *nmd, md_ptr, socket);
+ add_attribute_search_or_value_buttons(C, row, *nmd, md_ptr, socket);
}
else {
- uiLayout *row = uiLayoutRow(layout, false);
- uiLayoutSetPropDecorate(row, true);
uiItemR(row, md_ptr, rna_path, 0, socket.name, ICON_NONE);
}
}
@@ -1748,7 +1732,7 @@ static void output_attribute_panel_draw(const bContext *C, Panel *panel)
}
}
-static void internal_dependencies_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void internal_dependencies_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
@@ -1761,7 +1745,7 @@ static void internal_dependencies_panel_draw(const bContext *UNUSED(C), Panel *p
}
tree_log->ensure_used_named_attributes();
- const Map<std::string, NamedAttributeUsage> &usage_by_attribute =
+ const Map<StringRefNull, NamedAttributeUsage> &usage_by_attribute =
tree_log->used_named_attributes;
if (usage_by_attribute.is_empty()) {
@@ -1836,7 +1820,7 @@ static void panelRegister(ARegionType *region_type)
panel_type);
}
-static void blendWrite(BlendWriter *writer, const ID *UNUSED(id_owner), const ModifierData *md)
+static void blendWrite(BlendWriter *writer, const ID * /*id_owner*/, const ModifierData *md)
{
const NodesModifierData *nmd = reinterpret_cast<const NodesModifierData *>(md);
@@ -1887,9 +1871,7 @@ static void freeData(ModifierData *md)
clear_runtime_data(nmd);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *UNUSED(md),
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData * /*md*/, CustomData_MeshMasks *r_cddata_masks)
{
/* We don't know what the node tree will need. If there are vertex groups, it is likely that the
* node tree wants to access them. */
diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.cc
index 6e94acaa9eb..7d422826cf8 100644
--- a/source/blender/modifiers/intern/MOD_normal_edit.c
+++ b/source/blender/modifiers/intern/MOD_normal_edit.cc
@@ -4,7 +4,7 @@
* \ingroup modifiers
*/
-#include <string.h>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -56,15 +56,15 @@ static void generate_vert_coordinates(Mesh *mesh,
const MVert *mv = BKE_mesh_verts(mesh);
for (int i = 0; i < mesh->totvert; i++, mv++) {
copy_v3_v3(r_cos[i], mv->co);
- if (r_size != NULL && ob_center == NULL) {
+ if (r_size != nullptr && ob_center == nullptr) {
minmax_v3v3_v3(min_co, max_co, r_cos[i]);
}
}
/* Get size (i.e. deformation of the spheroid generating normals),
* either from target object, or own geometry. */
- if (r_size != NULL) {
- if (ob_center != NULL) {
+ if (r_size != nullptr) {
+ if (ob_center != nullptr) {
/* Using 'scale' as 'size' here. The input object is typically an empty
* who's scale is used to define an ellipsoid instead of a simple sphere. */
@@ -88,19 +88,19 @@ static void generate_vert_coordinates(Mesh *mesh,
}
}
- if (ob_center != NULL) {
+ if (ob_center != nullptr) {
float inv_obmat[4][4];
/* Translate our coordinates so that center of ob_center is at (0, 0, 0). */
/* Get ob_center (world) coordinates in ob local coordinates.
* No need to take into account ob_center's space here, see T44027. */
- invert_m4_m4(inv_obmat, ob->obmat);
- mul_v3_m4v3(diff, inv_obmat, ob_center->obmat[3]);
+ invert_m4_m4(inv_obmat, ob->object_to_world);
+ mul_v3_m4v3(diff, inv_obmat, ob_center->object_to_world[3]);
negate_v3(diff);
do_diff = true;
}
- else if (offset != NULL && !is_zero_v3(offset)) {
+ else if (offset != nullptr && !is_zero_v3(offset)) {
negate_v3_v3(diff, offset);
do_diff = true;
@@ -129,12 +129,12 @@ static void mix_normals(const float mix_factor,
const int loops_num)
{
/* Mix with org normals... */
- float *facs = NULL, *wfac;
+ float *facs = nullptr, *wfac;
float(*no_new)[3], (*no_old)[3];
int i;
if (dvert) {
- facs = MEM_malloc_arrayN((size_t)loops_num, sizeof(*facs), __func__);
+ facs = static_cast<float *>(MEM_malloc_arrayN(size_t(loops_num), sizeof(*facs), __func__));
BKE_defvert_extract_vgroup_to_loopweights(
dvert, defgrp_index, verts_num, mloop, loops_num, use_invert_vgroup, facs);
}
@@ -164,7 +164,7 @@ static void mix_normals(const float mix_factor,
*no_new,
*no_old,
*no_new,
- (mix_limit < (float)M_PI) ? min_ff(fac, mix_limit / angle_v3v3(*no_new, *no_old)) : fac);
+ (mix_limit < float(M_PI)) ? min_ff(fac, mix_limit / angle_v3v3(*no_new, *no_old)) : fac);
}
MEM_SAFE_FREE(facs);
@@ -180,7 +180,7 @@ static bool polygons_check_flip(MLoop *mloop,
const int polys_num)
{
const MPoly *mp;
- MDisps *mdisp = CustomData_get_layer(ldata, CD_MDISPS);
+ MDisps *mdisp = static_cast<MDisps *>(CustomData_get_layer(ldata, CD_MDISPS));
int i;
bool flipped = false;
@@ -209,7 +209,7 @@ static bool polygons_check_flip(MLoop *mloop,
}
static void normalEditModifier_do_radial(NormalEditModifierData *enmd,
- const ModifierEvalContext *UNUSED(ctx),
+ const ModifierEvalContext * /*ctx*/,
Object *ob,
Mesh *mesh,
short (*clnors)[2],
@@ -235,11 +235,13 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd,
const bool do_polynors_fix = (enmd->flag & MOD_NORMALEDIT_NO_POLYNORS_FIX) == 0;
int i;
- float(*cos)[3] = MEM_malloc_arrayN((size_t)verts_num, sizeof(*cos), __func__);
- float(*nos)[3] = MEM_malloc_arrayN((size_t)loops_num, sizeof(*nos), __func__);
+ float(*cos)[3] = static_cast<float(*)[3]>(
+ MEM_malloc_arrayN(size_t(verts_num), sizeof(*cos), __func__));
+ float(*nos)[3] = static_cast<float(*)[3]>(
+ MEM_malloc_arrayN(size_t(loops_num), sizeof(*nos), __func__));
float size[3];
- BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)verts_num, __func__);
+ BLI_bitmap *done_verts = BLI_BITMAP_NEW(size_t(verts_num), __func__);
generate_vert_coordinates(mesh, ob, ob_target, enmd->offset, verts_num, cos, size);
@@ -346,7 +348,7 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd,
}
static void normalEditModifier_do_directional(NormalEditModifierData *enmd,
- const ModifierEvalContext *UNUSED(ctx),
+ const ModifierEvalContext * /*ctx*/,
Object *ob,
Mesh *mesh,
short (*clnors)[2],
@@ -372,7 +374,8 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd,
const bool do_polynors_fix = (enmd->flag & MOD_NORMALEDIT_NO_POLYNORS_FIX) == 0;
const bool use_parallel_normals = (enmd->flag & MOD_NORMALEDIT_USE_DIRECTION_PARALLEL) != 0;
- float(*nos)[3] = MEM_malloc_arrayN((size_t)loops_num, sizeof(*nos), __func__);
+ float(*nos)[3] = static_cast<float(*)[3]>(
+ MEM_malloc_arrayN(size_t(loops_num), sizeof(*nos), __func__));
float target_co[3];
int i;
@@ -380,8 +383,8 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd,
/* Get target's center coordinates in ob local coordinates. */
float mat[4][4];
- invert_m4_m4(mat, ob->obmat);
- mul_m4_m4m4(mat, mat, ob_target->obmat);
+ invert_m4_m4(mat, ob->object_to_world);
+ mul_m4_m4m4(mat, mat, ob_target->object_to_world);
copy_v3_v3(target_co, mat[3]);
if (use_parallel_normals) {
@@ -395,10 +398,11 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd,
}
}
else {
- float(*cos)[3] = MEM_malloc_arrayN((size_t)verts_num, sizeof(*cos), __func__);
- generate_vert_coordinates(mesh, ob, ob_target, NULL, verts_num, cos, NULL);
+ float(*cos)[3] = static_cast<float(*)[3]>(
+ MEM_malloc_arrayN(size_t(verts_num), sizeof(*cos), __func__));
+ generate_vert_coordinates(mesh, ob, ob_target, nullptr, verts_num, cos, nullptr);
- BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)verts_num, __func__);
+ BLI_bitmap *done_verts = BLI_BITMAP_NEW(size_t(verts_num), __func__);
const MLoop *ml;
float(*no)[3];
@@ -485,7 +489,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
const bool use_invert_vgroup = ((enmd->flag & MOD_NORMALEDIT_INVERT_VGROUP) != 0);
const bool use_current_clnors = !((enmd->mix_mode == MOD_NORMALEDIT_MIX_COPY) &&
(enmd->mix_factor == 1.0f) && (enmd->defgrp_name[0] == '\0') &&
- (enmd->mix_limit == (float)M_PI));
+ (enmd->mix_limit == float(M_PI)));
/* Do not run that modifier at all if autosmooth is disabled! */
if (!is_valid_target_with_error(ctx->object, enmd) || mesh->totloop == 0) {
@@ -509,11 +513,11 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
}
Mesh *result;
- if (BKE_mesh_edges(mesh) == BKE_mesh_edges(((Mesh *)ob->data))) {
+ if (BKE_mesh_edges(mesh) == BKE_mesh_edges((Mesh *)ob->data)) {
/* We need to duplicate data here, otherwise setting custom normals
* (which may also affect sharp edges) could
* modify original mesh, see T43671. */
- result = (Mesh *)BKE_id_copy_ex(NULL, &mesh->id, NULL, LIB_ID_COPY_LOCALIZE);
+ result = (Mesh *)BKE_id_copy_ex(nullptr, &mesh->id, nullptr, LIB_ID_COPY_LOCALIZE);
}
else {
result = mesh;
@@ -531,17 +535,19 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
int defgrp_index;
const MDeformVert *dvert;
- float(*loopnors)[3] = NULL;
+ float(*loopnors)[3] = nullptr;
CustomData *ldata = &result->ldata;
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(result);
const float(*poly_normals)[3] = BKE_mesh_poly_normals_ensure(result);
- short(*clnors)[2] = CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL);
+ short(*clnors)[2] = static_cast<short(*)[2]>(CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL));
if (use_current_clnors) {
- clnors = CustomData_duplicate_referenced_layer(ldata, CD_CUSTOMLOOPNORMAL, loops_num);
- loopnors = MEM_malloc_arrayN((size_t)loops_num, sizeof(*loopnors), __func__);
+ clnors = static_cast<short(*)[2]>(
+ CustomData_duplicate_referenced_layer(ldata, CD_CUSTOMLOOPNORMAL, loops_num));
+ loopnors = static_cast<float(*)[3]>(
+ MEM_malloc_arrayN(size_t(loops_num), sizeof(*loopnors), __func__));
BKE_mesh_normals_loop_split(verts,
vert_normals,
@@ -556,13 +562,14 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
polys_num,
true,
result->smoothresh,
- NULL,
+ nullptr,
clnors,
- NULL);
+ nullptr);
}
- if (clnors == NULL) {
- clnors = CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, NULL, loops_num);
+ if (clnors == nullptr) {
+ clnors = static_cast<short(*)[2]>(
+ CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, nullptr, loops_num));
}
MOD_get_vgroup(ob, result, enmd->defgrp_name, &dvert, &defgrp_index);
@@ -616,7 +623,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
MEM_SAFE_FREE(loopnors);
- result->runtime.is_original_bmesh = false;
+ result->runtime->is_original_bmesh = false;
return result;
}
@@ -630,9 +637,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(enmd, DNA_struct_default_get(NormalEditModifierData), modifier);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
NormalEditModifierData *enmd = (NormalEditModifierData *)md;
@@ -644,7 +649,7 @@ static void requiredDataMask(Object *UNUSED(ob),
}
}
-static bool dependsOnNormals(ModifierData *UNUSED(md))
+static bool dependsOnNormals(ModifierData * /*md*/)
{
return true;
}
@@ -656,9 +661,7 @@ static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *u
walk(userData, ob, (ID **)&enmd->target, IDWALK_CB_NOP);
}
-static bool isDisabled(const struct Scene *UNUSED(scene),
- ModifierData *md,
- bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene * /*scene*/, ModifierData *md, bool /*useRenderParams*/)
{
NormalEditModifierData *enmd = (NormalEditModifierData *)md;
@@ -679,7 +682,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
return normalEditModifier_do((NormalEditModifierData *)md, ctx, ctx->object, mesh);
}
-static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *col;
uiLayout *layout = panel->layout;
@@ -689,21 +692,21 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
int mode = RNA_enum_get(ptr, "mode");
- uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
uiLayoutSetPropSep(layout, true);
- uiItemR(layout, ptr, "target", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "target", 0, nullptr, ICON_NONE);
col = uiLayoutColumn(layout, false);
uiLayoutSetActive(col, mode == MOD_NORMALEDIT_MODE_DIRECTIONAL);
- uiItemR(col, ptr, "use_direction_parallel", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_direction_parallel", 0, nullptr, ICON_NONE);
modifier_panel_end(layout, ptr);
}
/* This panel could be open by default, but it isn't currently. */
-static void mix_mode_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void mix_mode_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *row;
uiLayout *layout = panel->layout;
@@ -713,13 +716,13 @@ static void mix_mode_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropSep(layout, true);
- uiItemR(layout, ptr, "mix_mode", 0, NULL, ICON_NONE);
- uiItemR(layout, ptr, "mix_factor", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "mix_mode", 0, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "mix_factor", 0, nullptr, ICON_NONE);
- modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
+ modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", nullptr);
row = uiLayoutRow(layout, true);
- uiItemR(row, ptr, "mix_limit", 0, NULL, ICON_NONE);
+ uiItemR(row, ptr, "mix_limit", 0, nullptr, ICON_NONE);
uiItemR(row,
ptr,
"no_polynors_fix",
@@ -728,11 +731,11 @@ static void mix_mode_panel_draw(const bContext *UNUSED(C), Panel *panel)
(RNA_boolean_get(ptr, "no_polynors_fix") ? ICON_LOCKED : ICON_UNLOCKED));
}
-static void offset_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void offset_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
int mode = RNA_enum_get(ptr, "mode");
PointerRNA target_ptr = RNA_pointer_get(ptr, "target");
@@ -744,15 +747,16 @@ static void offset_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropSep(layout, true);
uiLayoutSetActive(layout, needs_object_offset);
- uiItemR(layout, ptr, "offset", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "offset", 0, nullptr, ICON_NONE);
}
static void panelRegister(ARegionType *region_type)
{
PanelType *panel_type = modifier_panel_register(
region_type, eModifierType_NormalEdit, panel_draw);
- modifier_subpanel_register(region_type, "mix", "Mix", NULL, mix_mode_panel_draw, panel_type);
- modifier_subpanel_register(region_type, "offset", "Offset", NULL, offset_panel_draw, panel_type);
+ modifier_subpanel_register(region_type, "mix", "Mix", nullptr, mix_mode_panel_draw, panel_type);
+ modifier_subpanel_register(
+ region_type, "offset", "Offset", nullptr, offset_panel_draw, panel_type);
}
ModifierTypeInfo modifierType_NormalEdit = {
@@ -767,24 +771,24 @@ ModifierTypeInfo modifierType_NormalEdit = {
/* copyData */ BKE_modifier_copydata_generic,
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
+ /* deformVerts */ nullptr,
+ /* deformMatrices */ nullptr,
+ /* deformVertsEM */ nullptr,
+ /* deformMatricesEM */ nullptr,
/* modifyMesh */ modifyMesh,
- /* modifyGeometrySet */ NULL,
+ /* modifyGeometrySet */ nullptr,
/* initData */ initData,
/* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
+ /* freeData */ nullptr,
/* isDisabled */ isDisabled,
/* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
+ /* dependsOnTime */ nullptr,
/* dependsOnNormals */ dependsOnNormals,
/* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* foreachTexLink */ nullptr,
+ /* freeRuntimeData */ nullptr,
/* panelRegister */ panelRegister,
- /* blendWrite */ NULL,
- /* blendRead */ NULL,
+ /* blendWrite */ nullptr,
+ /* blendRead */ nullptr,
};
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c
index d3b02659380..bee1bd7795a 100644
--- a/source/blender/modifiers/intern/MOD_ocean.c
+++ b/source/blender/modifiers/intern/MOD_ocean.c
@@ -130,9 +130,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla
}
#ifdef WITH_OCEANSIM
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
OceanModifierData *omd = (OceanModifierData *)md;
@@ -141,8 +139,7 @@ static void requiredDataMask(Object *UNUSED(ob),
}
}
#else /* WITH_OCEANSIM */
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *UNUSED(md),
+static void requiredDataMask(ModifierData *UNUSED(md),
CustomData_MeshMasks *UNUSED(r_cddata_masks))
{
}
@@ -595,7 +592,7 @@ static void spray_panel_draw_header(const bContext *UNUSED(C), Panel *panel)
row = uiLayoutRow(layout, false);
uiLayoutSetActive(row, use_foam);
- uiItemR(row, ptr, "use_spray", 0, IFACE_("Spray"), ICON_NONE);
+ uiItemR(row, ptr, "use_spray", 0, CTX_IFACE_(BLT_I18NCONTEXT_ID_MESH, "Spray"), ICON_NONE);
}
static void spray_panel_draw(const bContext *UNUSED(C), Panel *panel)
diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c
index 6c69e616f83..46e14dd6bfb 100644
--- a/source/blender/modifiers/intern/MOD_particleinstance.c
+++ b/source/blender/modifiers/intern/MOD_particleinstance.c
@@ -52,9 +52,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(pimd, DNA_struct_default_get(ParticleInstanceModifierData), modifier);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
@@ -275,7 +273,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
break;
case eParticleInstanceSpace_Local:
/* get particle states in the particle object's local space */
- invert_m4_m4(spacemat, pimd->ob->obmat);
+ invert_m4_m4(spacemat, pimd->ob->object_to_world);
break;
default:
/* should not happen */
@@ -305,7 +303,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
maxedge += totedge;
}
- psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
+ psys_sim_data_init(&sim);
if (psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) {
float min[3], max[3];
@@ -516,10 +514,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
p_skip++;
}
- if (psys->lattice_deform_data) {
- BKE_lattice_deform_data_destroy(psys->lattice_deform_data);
- psys->lattice_deform_data = NULL;
- }
+ psys_sim_data_free(&sim);
if (size) {
MEM_freeN(size);
diff --git a/source/blender/modifiers/intern/MOD_particlesystem.cc b/source/blender/modifiers/intern/MOD_particlesystem.cc
index 0c04c6fc062..66291520176 100644
--- a/source/blender/modifiers/intern/MOD_particlesystem.cc
+++ b/source/blender/modifiers/intern/MOD_particlesystem.cc
@@ -87,9 +87,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla
tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0;
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
@@ -125,7 +123,7 @@ static void deformVerts(ModifierData *md,
}
}
- /* clear old dm */
+ /* Clear old evaluated mesh. */
bool had_mesh_final = (psmd->mesh_final != nullptr);
if (psmd->mesh_final) {
BKE_id_free(nullptr, psmd->mesh_final);
@@ -161,7 +159,7 @@ static void deformVerts(ModifierData *md,
BKE_mesh_tessface_ensure(psmd->mesh_final);
- if (!psmd->mesh_final->runtime.deformed_only) {
+ if (!psmd->mesh_final->runtime->deformed_only) {
/* Get the original mesh from the object, this is what the particles
* are attached to so in case of non-deform modifiers we need to remap
* them to the final mesh (typically subdivision surfaces). */
@@ -251,7 +249,7 @@ static void deformVertsEM(ModifierData *md,
}
#endif
-static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c
index 4241ca5a591..d6241fcb290 100644
--- a/source/blender/modifiers/intern/MOD_remesh.c
+++ b/source/blender/modifiers/intern/MOD_remesh.c
@@ -67,10 +67,9 @@ static void init_dualcon_mesh(DualConInput *input, Mesh *mesh)
input->mloop = (void *)BKE_mesh_loops(mesh);
input->loop_stride = sizeof(MLoop);
- BKE_mesh_runtime_looptri_ensure(mesh);
- input->looptri = (void *)mesh->runtime.looptris.array;
+ input->looptri = (void *)BKE_mesh_runtime_looptri_ensure(mesh);
input->tri_stride = sizeof(MLoopTri);
- input->tottri = mesh->runtime.looptris.len;
+ input->tottri = BKE_mesh_runtime_looptri_len(mesh);
INIT_MINMAX(input->min, input->max);
BKE_mesh_minmax(mesh, input->min, input->max);
diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c
index acaeb9b2777..4ba274dbd8a 100644
--- a/source/blender/modifiers/intern/MOD_screw.c
+++ b/source/blender/modifiers/intern/MOD_screw.c
@@ -41,6 +41,8 @@
#include "MOD_modifiertypes.h"
#include "MOD_ui_common.h"
+#include "BLI_strict_flags.h"
+
static void initData(ModifierData *md)
{
ScrewModifierData *ltmd = (ScrewModifierData *)md;
@@ -50,16 +52,12 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(ltmd, DNA_struct_default_get(ScrewModifierData), modifier);
}
-#include "BLI_strict_flags.h"
-
/** Used for gathering edge connectivity. */
typedef struct ScrewVertConnect {
/** Distance from the center axis. */
float dist_sq;
/** Location relative to the transformed axis. */
float co[3];
- /** Calc normal of the vertex. */
- float no[3];
/** 2 verts on either side of this one. */
uint v[2];
/** Edges on either side, a bit of a waste since each edge ref's 2 edges. */
@@ -276,8 +274,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
if (ob_axis != NULL) {
/* Calculate the matrix relative to the axis object. */
- invert_m4_m4(mtx_tmp_a, ctx->object->obmat);
- copy_m4_m4(mtx_tx_inv, ob_axis->obmat);
+ invert_m4_m4(mtx_tmp_a, ctx->object->object_to_world);
+ copy_m4_m4(mtx_tx_inv, ob_axis->object_to_world);
mul_m4_m4m4(mtx_tx, mtx_tmp_a, mtx_tx_inv);
/* Calculate the axis vector. */
@@ -381,9 +379,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* The `screw_ofs` cannot change from now on. */
const bool do_remove_doubles = (ltmd->flag & MOD_SCREW_MERGE) && (screw_ofs == 0.0f);
- /* Only calculate normals if `do_remove_doubles` since removing doubles frees the normals. */
- const bool do_normal_create = (ltmd->flag & MOD_SCREW_NORMAL_CALC) &&
- (do_remove_doubles == false);
result = BKE_mesh_new_nomain_from_template(
mesh, (int)maxVerts, (int)maxEdges, 0, (int)maxPolys * 4, (int)maxPolys);
@@ -444,7 +439,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
for (i = 0; i < totedge; i++, med_orig++, med_new++) {
med_new->v1 = med_orig->v1;
med_new->v2 = med_orig->v2;
- med_new->crease = med_orig->crease;
med_new->flag = med_orig->flag & ~ME_LOOSEEDGE;
/* Tag #MVert as not loose. */
@@ -480,9 +474,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
}
- float(*vert_normals_new)[3] = do_normal_create ? BKE_mesh_vertex_normals_for_write(result) :
- NULL;
-
if (ltmd->flag & MOD_SCREW_NORMAL_CALC) {
/* Normal Calculation (for face flipping)
@@ -511,15 +502,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
vc = vert_connect;
/* Copy Vert Locations */
- /* - We can do this in a later loop - only do here if no normal calc */
- if (!totedge) {
- for (i = 0; i < totvert; i++, mv_orig++, mv_new++) {
- copy_v3_v3(mv_new->co, mv_orig->co);
- /* No edges: this is really a dummy normal. */
- normalize_v3_v3(vc->no, mv_new->co);
- }
- }
- else {
+ if (totedge != 0) {
// printf("\n\n\n\n\nStarting Modifier\n");
/* set edge users */
med_new = medge_new;
@@ -771,77 +754,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
}
}
-
- /* *VERTEX NORMALS*
- * we know the surrounding edges are ordered correctly now
- * so its safe to create vertex normals.
- *
- * calculate vertex normals that can be propagated on lathing
- * use edge connectivity work this out */
- if (do_normal_create) {
- if (SV_IS_VALID(vc->v[0])) {
- if (SV_IS_VALID(vc->v[1])) {
- /* 2 edges connected. */
- /* make 2 connecting vert locations relative to the middle vert */
- sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co);
- sub_v3_v3v3(tmp_vec2, mvert_new[vc->v[1]].co, mvert_new[i].co);
- /* normalize so both edges have the same influence, no matter their length */
- normalize_v3(tmp_vec1);
- normalize_v3(tmp_vec2);
-
- /* vc_no_tmp1 - this line is the average direction of both connecting edges
- *
- * Use the edge order to make the subtraction, flip the normal the right way
- * edge should be there but check just in case... */
- if (vc->e[0]->v1 == i) {
- sub_v3_v3(tmp_vec1, tmp_vec2);
- }
- else {
- sub_v3_v3v3(tmp_vec1, tmp_vec2, tmp_vec1);
- }
- }
- else {
- /* only 1 edge connected - same as above except
- * don't need to average edge direction */
- if (vc->e[0]->v2 == i) {
- sub_v3_v3v3(tmp_vec1, mvert_new[i].co, mvert_new[vc->v[0]].co);
- }
- else {
- sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co);
- }
- }
-
- /* tmp_vec2 - is a line 90d from the pivot to the vec
- * This is used so the resulting normal points directly away from the middle */
- cross_v3_v3v3(tmp_vec2, axis_vec, vc->co);
-
- if (UNLIKELY(is_zero_v3(tmp_vec2))) {
- /* we're _on_ the axis, so copy it based on our winding */
- if (vc->e[0]->v2 == i) {
- negate_v3_v3(vc->no, axis_vec);
- }
- else {
- copy_v3_v3(vc->no, axis_vec);
- }
- }
- else {
- /* edge average vector and right angle to the pivot make the normal */
- cross_v3_v3v3(vc->no, tmp_vec1, tmp_vec2);
- }
- }
- else {
- copy_v3_v3(vc->no, vc->co);
- }
-
- /* we won't be looping on this data again so copy normals here */
- if ((angle < 0.0f) != do_flip) {
- negate_v3(vc->no);
- }
-
- normalize_v3(vc->no);
- copy_v3_v3(vert_normals_new[i], vc->no);
- }
- /* Done with normals */
}
}
}
@@ -882,14 +794,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
mv_new = &mvert_new[varray_stride]; /* advance to the next slice */
for (j = 0; j < totvert; j++, mv_new_base++, mv_new++) {
- /* set normal */
- if (vert_connect) {
- if (do_normal_create) {
- /* Set the normal now its transformed. */
- mul_v3_m3v3(vert_normals_new[mv_new - mvert_new], mat3, vert_connect[j].no);
- }
- }
-
/* set location */
copy_v3_v3(mv_new->co, mv_new_base->co);
@@ -910,7 +814,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* add the new edge */
med_new->v1 = varray_stride + j;
med_new->v2 = med_new->v1 - totvert;
- med_new->flag = ME_EDGEDRAW | ME_EDGERENDER;
+ med_new->flag = ME_EDGEDRAW;
if (!BLI_BITMAP_TEST(vert_tag, j)) {
med_new->flag |= ME_LOOSEEDGE;
}
@@ -931,7 +835,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
for (i = 0; i < totvert; i++) {
med_new->v1 = i;
med_new->v2 = varray_stride + i;
- med_new->flag = ME_EDGEDRAW | ME_EDGERENDER;
+ med_new->flag = ME_EDGEDRAW;
if (!BLI_BITMAP_TEST(vert_tag, i)) {
med_new->flag |= ME_LOOSEEDGE;
}
@@ -1064,7 +968,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
med_new->v1 = i1;
med_new->v2 = i2;
med_new->flag = med_new_firstloop->flag;
- med_new->crease = med_new_firstloop->crease;
med_new++;
}
i1 += totvert;
@@ -1092,7 +995,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
med_new->v1 = i1;
med_new->v2 = i2;
med_new->flag = med_new_firstloop->flag & ~ME_LOOSEEDGE;
- med_new->crease = med_new_firstloop->crease;
med_new++;
}
@@ -1133,10 +1035,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
MEM_freeN(vert_loop_map);
}
- if (do_normal_create) {
- BKE_mesh_vertex_normals_clear_dirty(result);
- }
-
if (do_remove_doubles) {
result = mesh_remove_doubles_on_axis(result,
mvert_new,
diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c
index cd36d82e746..df8b9d53a2f 100644
--- a/source/blender/modifiers/intern/MOD_shrinkwrap.c
+++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c
@@ -48,9 +48,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(ShrinkwrapModifierData), modifier);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c
index b49e47fa589..0de89850bc9 100644
--- a/source/blender/modifiers/intern/MOD_simpledeform.c
+++ b/source/blender/modifiers/intern/MOD_simpledeform.c
@@ -414,9 +414,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(SimpleDeformModifierData), modifier);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index ae8fcb42553..897a25711cd 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -1464,7 +1464,7 @@ static void quad_from_tris(BMEdge *e, BMFace *adj[2], BMVert *ndx[4])
ndx[j] = tri[0][i];
/* When the triangle edge cuts across our quad-to-be,
* throw in the second triangle's vertex */
- if ((ELEM(tri[0][i], e->v1, e->v2)) &&
+ if (ELEM(tri[0][i], e->v1, e->v2) &&
(tri[0][(i + 1) % 3] == e->v1 || tri[0][(i + 1) % 3] == e->v2)) {
j++;
ndx[j] = opp;
@@ -1734,7 +1734,7 @@ static void skin_smooth_hulls(BMesh *bm,
}
}
- /* Add temporary shapekey layer to store original coordinates */
+ /* Add temporary shape-key layer to store original coordinates. */
BM_data_layer_add(bm, &bm->vdata, CD_SHAPEKEY);
skey = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY) - 1;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
@@ -2007,9 +2007,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
return result;
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *UNUSED(md),
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *UNUSED(md), CustomData_MeshMasks *r_cddata_masks)
{
r_cddata_masks->vmask |= CD_MASK_MVERT_SKIN | CD_MASK_MDEFORMVERT;
}
diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c
index 76332c61e1e..72fc945675c 100644
--- a/source/blender/modifiers/intern/MOD_smooth.c
+++ b/source/blender/modifiers/intern/MOD_smooth.c
@@ -63,9 +63,7 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
return false;
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
SmoothModifierData *smd = (SmoothModifierData *)md;
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index 3e2d590c928..1c1649a5ed8 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -53,9 +53,7 @@ static void initData(ModifierData *md)
# pragma GCC diagnostic error "-Wsign-conversion"
#endif
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
SolidifyModifierData *smd = (SolidifyModifierData *)md;
@@ -110,7 +108,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(layout, ptr, "use_even_offset", 0, NULL, ICON_NONE);
}
- col = uiLayoutColumnWithHeading(layout, false, IFACE_("Rim"));
+ col = uiLayoutColumnWithHeading(layout, false, CTX_IFACE_(BLT_I18NCONTEXT_ID_MESH, "Rim"));
uiItemR(col, ptr, "use_rim", 0, IFACE_("Fill"), ICON_NONE);
sub = uiLayoutColumn(col, false);
uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_rim"));
@@ -164,7 +162,8 @@ static void materials_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(layout, ptr, "material_offset", 0, NULL, ICON_NONE);
col = uiLayoutColumn(layout, true);
uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_rim"));
- uiItemR(col, ptr, "material_offset_rim", 0, IFACE_("Rim"), ICON_NONE);
+ uiItemR(
+ col, ptr, "material_offset_rim", 0, CTX_IFACE_(BLT_I18NCONTEXT_ID_MESH, "Rim"), ICON_NONE);
}
static void edge_data_panel_draw(const bContext *UNUSED(C), Panel *panel)
@@ -183,7 +182,7 @@ static void edge_data_panel_draw(const bContext *UNUSED(C), Panel *panel)
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "edge_crease_inner", 0, IFACE_("Crease Inner"), ICON_NONE);
uiItemR(col, ptr, "edge_crease_outer", 0, IFACE_("Outer"), ICON_NONE);
- uiItemR(col, ptr, "edge_crease_rim", 0, IFACE_("Rim"), ICON_NONE);
+ uiItemR(col, ptr, "edge_crease_rim", 0, CTX_IFACE_(BLT_I18NCONTEXT_ID_MESH, "Rim"), ICON_NONE);
}
uiItemR(layout, ptr, "bevel_convex", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
}
@@ -218,7 +217,13 @@ static void vertex_group_panel_draw(const bContext *UNUSED(C), Panel *panel)
col = uiLayoutColumn(layout, false);
uiItemPointerR(
col, ptr, "shell_vertex_group", &ob_ptr, "vertex_groups", IFACE_("Shell"), ICON_NONE);
- uiItemPointerR(col, ptr, "rim_vertex_group", &ob_ptr, "vertex_groups", IFACE_("Rim"), ICON_NONE);
+ uiItemPointerR(col,
+ ptr,
+ "rim_vertex_group",
+ &ob_ptr,
+ "vertex_groups",
+ CTX_IFACE_(BLT_I18NCONTEXT_ID_MESH, "Rim"),
+ ICON_NONE);
}
static void panelRegister(ARegionType *region_type)
diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c
index 1456254c31f..08e9569bd95 100644
--- a/source/blender/modifiers/intern/MOD_solidify_extrude.c
+++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c
@@ -1024,16 +1024,18 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
NULL;
float nor[3];
#endif
- const uchar crease_rim = smd->crease_rim * 255.0f;
- const uchar crease_outer = smd->crease_outer * 255.0f;
- const uchar crease_inner = smd->crease_inner * 255.0f;
+ const float crease_rim = smd->crease_rim;
+ const float crease_outer = smd->crease_outer;
+ const float crease_inner = smd->crease_inner;
int *origindex_edge;
int *orig_ed;
uint j;
+ float *result_edge_crease = NULL;
if (crease_rim || crease_outer || crease_inner) {
- result->cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ result_edge_crease = (float *)CustomData_add_layer(
+ &result->edata, CD_CREASE, CD_SET_DEFAULT, NULL, result->totedge);
}
/* add faces & edges */
@@ -1043,7 +1045,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
for (i = 0; i < rimVerts; i++, ed++) {
ed->v1 = new_vert_arr[i];
ed->v2 = (do_shell ? new_vert_arr[i] : i) + verts_num;
- ed->flag |= ME_EDGEDRAW | ME_EDGERENDER;
+ ed->flag |= ME_EDGEDRAW;
if (orig_ed) {
*orig_ed = ORIGINDEX_NONE;
@@ -1051,7 +1053,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
}
if (crease_rim) {
- ed->crease = crease_rim;
+ result_edge_crease[ed - medge] = crease_rim;
}
}
@@ -1140,16 +1142,16 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
}
if (crease_outer) {
/* crease += crease_outer; without wrapping */
- char *cr = &(ed->crease);
- int tcr = *cr + crease_outer;
- *cr = tcr > 255 ? 255 : tcr;
+ float *cr = &(result_edge_crease[ed - medge]);
+ float tcr = *cr + crease_outer;
+ *cr = tcr > 1.0f ? 1.0f : tcr;
}
if (crease_inner) {
/* crease += crease_inner; without wrapping */
- char *cr = &(medge[edges_num + (do_shell ? eidx : i)].crease);
- int tcr = *cr + crease_inner;
- *cr = tcr > 255 ? 255 : tcr;
+ float *cr = &(result_edge_crease[edges_num + (do_shell ? eidx : i)]);
+ float tcr = *cr + crease_inner;
+ *cr = tcr > 1.0f ? 1.0f : tcr;
}
#ifdef SOLIDIFY_SIDE_NORMALS
diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
index d3aff5c58c5..9d0b5c30b5e 100644
--- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
+++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
@@ -192,6 +192,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
/* These might be null. */
const float *orig_vert_bweight = CustomData_get_layer(&mesh->vdata, CD_BWEIGHT);
const float *orig_edge_bweight = CustomData_get_layer(&mesh->edata, CD_BWEIGHT);
+ const float *orig_edge_crease = CustomData_get_layer(&mesh->edata, CD_CREASE);
uint new_verts_num = 0;
uint new_edges_num = 0;
@@ -1984,12 +1985,13 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
/* Get vertex crease layer and ensure edge creases are active if vertex creases are found, since
* they will introduce edge creases in the used custom interpolation method. */
const float *vertex_crease = CustomData_get_layer(&mesh->vdata, CD_CREASE);
+ float *result_edge_crease = NULL;
if (vertex_crease) {
- result->cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ result_edge_crease = (float *)CustomData_add_layer(
+ &result->edata, CD_CREASE, CD_SET_DEFAULT, NULL, result->totedge);
/* delete all vertex creases in the result if a rim is used. */
if (do_rim) {
CustomData_free_layers(&result->vdata, CD_CREASE, result->totvert);
- result->cd_flag &= (char)(~ME_CDFLAG_VERT_CREASE);
}
}
@@ -2004,7 +2006,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
if (g->new_vert != MOD_SOLIDIFY_EMPTY_TAG) {
CustomData_copy_data(&mesh->vdata, &result->vdata, (int)i, (int)g->new_vert, 1);
copy_v3_v3(mvert[g->new_vert].co, g->co);
- mvert[g->new_vert].flag = orig_mvert[i].flag;
}
}
}
@@ -2041,10 +2042,14 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
BLI_assert(v2 != MOD_SOLIDIFY_EMPTY_TAG);
medge[insert].v1 = v1;
medge[insert].v2 = v2;
- medge[insert].flag = orig_medge[(*l)->old_edge].flag | ME_EDGEDRAW | ME_EDGERENDER;
- medge[insert].crease = orig_medge[(*l)->old_edge].crease;
+ medge[insert].flag = orig_medge[(*l)->old_edge].flag | ME_EDGEDRAW;
+ if (result_edge_crease) {
+ result_edge_crease[insert] = orig_edge_crease ? orig_edge_crease[(*l)->old_edge] :
+ 0.0f;
+ }
if (result_edge_bweight) {
- result_edge_bweight[insert] = orig_edge_bweight[(*l)->old_edge];
+ result_edge_bweight[insert] = orig_edge_bweight ? orig_edge_bweight[(*l)->old_edge] :
+ 0.0f;
}
if (bevel_convex != 0.0f && (*l)->faces[1] != NULL) {
result_edge_bweight[insert] = clamp_f(
@@ -2118,12 +2123,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
EdgeGroup *g2 = gs;
EdgeGroup *last_g = NULL;
EdgeGroup *first_g = NULL;
- char mv_crease = vertex_crease ? (char)(vertex_crease[i] * 255.0f) : 0;
+ float mv_crease = vertex_crease ? vertex_crease[i] : 0.0f;
float mv_bweight = orig_vert_bweight ? orig_vert_bweight[i] : 0.0f;
/* Data calculation cache. */
- char max_crease;
- char last_max_crease = 0;
- char first_max_crease = 0;
+ float max_crease;
+ float last_max_crease = 0.0f;
+ float first_max_crease = 0.0f;
float max_bweight;
float last_max_bweight = 0.0f;
float first_max_bweight = 0.0f;
@@ -2139,14 +2144,24 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
BLI_assert(g->edges_len >= 2);
if (g->edges_len == 2) {
- max_crease = min_cc(orig_medge[g->edges[0]->old_edge].crease,
- orig_medge[g->edges[1]->old_edge].crease);
+ if (result_edge_crease) {
+ if (orig_edge_crease) {
+ max_crease = min_ff(orig_edge_crease[g->edges[0]->old_edge],
+ orig_edge_crease[g->edges[1]->old_edge]);
+ }
+ else {
+ max_crease = 0.0f;
+ }
+ }
}
else {
for (uint k = 1; k < g->edges_len - 1; k++) {
- const MEdge *ed = orig_medge + g->edges[k]->old_edge;
- if (ed->crease > max_crease) {
- max_crease = ed->crease;
+ const uint orig_edge_index = g->edges[k]->old_edge;
+ const MEdge *ed = &orig_medge[orig_edge_index];
+ if (result_edge_crease) {
+ if (orig_edge_crease && orig_edge_crease[orig_edge_index] > max_crease) {
+ max_crease = orig_edge_crease[orig_edge_index];
+ }
}
if (g->edges[k]->new_edge != MOD_SOLIDIFY_EMPTY_TAG) {
if (result_edge_bweight) {
@@ -2191,9 +2206,11 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
medge[edge_index].v1 = last_g->new_vert;
medge[edge_index].v2 = g->new_vert;
- medge[edge_index].flag = ME_EDGEDRAW | ME_EDGERENDER |
- ((last_flag | flag) & (ME_SEAM | ME_SHARP));
- medge[edge_index].crease = max_cc(mv_crease, min_cc(last_max_crease, max_crease));
+ medge[edge_index].flag = ME_EDGEDRAW | ((last_flag | flag) & (ME_SEAM | ME_SHARP));
+ if (result_edge_crease) {
+ result_edge_crease[edge_index] = max_ff(mv_crease,
+ min_ff(last_max_crease, max_crease));
+ }
if (result_edge_bweight) {
result_edge_bweight[edge_index] = max_ff(mv_bweight,
min_ff(last_max_bweight, max_bweight));
@@ -2222,10 +2239,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
last_g->open_face_edge = edge_index;
medge[edge_index].v1 = last_g->new_vert;
medge[edge_index].v2 = first_g->new_vert;
- medge[edge_index].flag = ME_EDGEDRAW | ME_EDGERENDER |
+ medge[edge_index].flag = ME_EDGEDRAW |
((last_flag | first_flag) & (ME_SEAM | ME_SHARP));
- medge[edge_index].crease = max_cc(mv_crease,
- min_cc(last_max_crease, first_max_crease));
+ if (result_edge_crease) {
+ result_edge_crease[edge_index] = max_ff(mv_crease,
+ min_ff(last_max_crease, first_max_crease));
+ }
if (result_edge_bweight) {
result_edge_bweight[edge_index] = max_ff(
mv_bweight, min_ff(last_max_bweight, first_max_bweight));
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.cc
index 8faf2bdbea2..5e77f0ffa9e 100644
--- a/source/blender/modifiers/intern/MOD_subsurf.c
+++ b/source/blender/modifiers/intern/MOD_subsurf.cc
@@ -5,9 +5,9 @@
* \ingroup modifiers
*/
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
+#include <cstddef>
+#include <cstdio>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -61,9 +61,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(SubsurfModifierData), modifier);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
SubsurfModifierData *smd = (SubsurfModifierData *)md;
if (smd->flags & eSubsurfModifierFlag_UseCustomNormals) {
@@ -93,16 +91,16 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla
BKE_modifier_copydata_generic(md, target, flag);
- tsmd->emCache = tsmd->mCache = NULL;
+ tsmd->emCache = tsmd->mCache = nullptr;
}
static void freeRuntimeData(void *runtime_data_v)
{
- if (runtime_data_v == NULL) {
+ if (runtime_data_v == nullptr) {
return;
}
SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)runtime_data_v;
- if (runtime_data->subdiv != NULL) {
+ if (runtime_data->subdiv != nullptr) {
BKE_subdiv_free(runtime_data->subdiv);
}
MEM_freeN(runtime_data);
@@ -113,12 +111,12 @@ static void freeData(ModifierData *md)
SubsurfModifierData *smd = (SubsurfModifierData *)md;
if (smd->mCache) {
- ccgSubSurf_free(smd->mCache);
- smd->mCache = NULL;
+ ccgSubSurf_free(static_cast<CCGSubSurf *>(smd->mCache));
+ smd->mCache = nullptr;
}
if (smd->emCache) {
- ccgSubSurf_free(smd->emCache);
- smd->emCache = NULL;
+ ccgSubSurf_free(static_cast<CCGSubSurf *>(smd->emCache));
+ smd->emCache = nullptr;
}
freeRuntimeData(smd->modifier.runtime);
}
@@ -210,7 +208,7 @@ static void subdiv_cache_mesh_wrapper_settings(const ModifierEvalContext *ctx,
runtime_data->calc_loop_normals = false; /* Set at the end of modifier stack evaluation. */
runtime_data->use_loop_normals = (smd->flags & eSubsurfModifierFlag_UseCustomNormals);
- mesh->runtime.subsurf_runtime_data = runtime_data;
+ mesh->runtime->subsurf_runtime_data = runtime_data;
}
/* Modifier itself. */
@@ -237,7 +235,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Same check as in `DRW_mesh_batch_cache_create_requested` to keep both code coherent. The
* difference is that here we do not check for the final edit mesh pointer as it is not yet
* assigned at this stage of modifier stack evaluation. */
- const bool is_editmode = (mesh->edit_mesh != NULL);
+ const bool is_editmode = (mesh->edit_mesh != nullptr);
const int required_mode = BKE_subsurf_modifier_eval_required_mode(is_render_mode, is_editmode);
if (BKE_subsurf_modifier_can_do_gpu_subdiv(scene, ctx->object, mesh, smd, required_mode)) {
subdiv_cache_mesh_wrapper_settings(ctx, mesh, smd, runtime_data);
@@ -246,7 +244,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
Subdiv *subdiv = BKE_subsurf_modifier_subdiv_descriptor_ensure(runtime_data, mesh, false);
- if (subdiv == NULL) {
+ if (subdiv == nullptr) {
/* Happens on bad topology, but also on empty input mesh. */
return result;
}
@@ -267,8 +265,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
if (use_clnors) {
- float(*lnors)[3] = CustomData_get_layer(&result->ldata, CD_NORMAL);
- BLI_assert(lnors != NULL);
+ float(*lnors)[3] = static_cast<float(*)[3]>(CustomData_get_layer(&result->ldata, CD_NORMAL));
+ BLI_assert(lnors != nullptr);
BKE_mesh_set_custom_normals(result, lnors);
CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
CustomData_set_layer_flag(&result->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
@@ -301,7 +299,7 @@ static void deformMatrices(ModifierData *md,
}
SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)smd->modifier.runtime;
Subdiv *subdiv = BKE_subsurf_modifier_subdiv_descriptor_ensure(runtime_data, mesh, false);
- if (subdiv == NULL) {
+ if (subdiv == nullptr) {
/* Happens on bad topology, but also on empty input mesh. */
return;
}
@@ -321,9 +319,9 @@ static bool get_show_adaptive_options(const bContext *C, Panel *panel)
}
/* Only show adaptive options if this is the last modifier. */
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
- ModifierData *md = ptr->data;
- if (md->next != NULL) {
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
+ ModifierData *md = static_cast<ModifierData *>(ptr->data);
+ if (md->next != nullptr) {
return false;
}
@@ -352,8 +350,8 @@ static void panel_draw(const bContext *C, Panel *panel)
/* Only test for adaptive subdivision if built with cycles. */
bool show_adaptive_options = false;
bool ob_use_adaptive_subdivision = false;
- PointerRNA cycles_ptr = {NULL};
- PointerRNA ob_cycles_ptr = {NULL};
+ PointerRNA cycles_ptr = {nullptr};
+ PointerRNA ob_cycles_ptr = {nullptr};
#ifdef WITH_CYCLES
PointerRNA scene_ptr;
Scene *scene = CTX_data_scene(C);
@@ -370,7 +368,7 @@ static void panel_draw(const bContext *C, Panel *panel)
UNUSED_VARS(C);
#endif
- uiItemR(layout, ptr, "subdivision_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "subdivision_type", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
uiLayoutSetPropSep(layout, true);
@@ -383,7 +381,7 @@ static void panel_draw(const bContext *C, Panel *panel)
ICON_NONE);
}
if (ob_use_adaptive_subdivision && show_adaptive_options) {
- uiItemR(layout, &ob_cycles_ptr, "dicing_rate", 0, NULL, ICON_NONE);
+ uiItemR(layout, &ob_cycles_ptr, "dicing_rate", 0, nullptr, ICON_NONE);
float render = MAX2(RNA_float_get(&cycles_ptr, "dicing_rate") *
RNA_float_get(&ob_cycles_ptr, "dicing_rate"),
0.1f);
@@ -408,11 +406,11 @@ static void panel_draw(const bContext *C, Panel *panel)
uiItemR(col, ptr, "render_levels", 0, IFACE_("Render"), ICON_NONE);
}
- uiItemR(layout, ptr, "show_only_control_edges", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "show_only_control_edges", 0, nullptr, ICON_NONE);
- SubsurfModifierData *smd = ptr->data;
- Object *ob = ob_ptr.data;
- Mesh *mesh = ob->data;
+ SubsurfModifierData *smd = static_cast<SubsurfModifierData *>(ptr->data);
+ const Object *ob = static_cast<const Object *>(ob_ptr.data);
+ const Mesh *mesh = static_cast<const Mesh *>(ob->data);
if (BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(smd, mesh)) {
uiItemL(layout, "Autosmooth or custom normals detected, disabling GPU subdivision", ICON_INFO);
}
@@ -445,30 +443,30 @@ static void advanced_panel_draw(const bContext *C, Panel *panel)
uiLayoutSetPropSep(layout, true);
uiLayoutSetActive(layout, !(show_adaptive_options && ob_use_adaptive_subdivision));
- uiItemR(layout, ptr, "use_limit_surface", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_limit_surface", 0, nullptr, ICON_NONE);
uiLayout *col = uiLayoutColumn(layout, true);
uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_limit_surface"));
- uiItemR(col, ptr, "quality", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "quality", 0, nullptr, ICON_NONE);
- uiItemR(layout, ptr, "uv_smooth", 0, NULL, ICON_NONE);
- uiItemR(layout, ptr, "boundary_smooth", 0, NULL, ICON_NONE);
- uiItemR(layout, ptr, "use_creases", 0, NULL, ICON_NONE);
- uiItemR(layout, ptr, "use_custom_normals", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "uv_smooth", 0, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "boundary_smooth", 0, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "use_creases", 0, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "use_custom_normals", 0, nullptr, ICON_NONE);
}
static void panelRegister(ARegionType *region_type)
{
PanelType *panel_type = modifier_panel_register(region_type, eModifierType_Subsurf, panel_draw);
modifier_subpanel_register(
- region_type, "advanced", "Advanced", NULL, advanced_panel_draw, panel_type);
+ region_type, "advanced", "Advanced", nullptr, advanced_panel_draw, panel_type);
}
-static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md)
+static void blendRead(BlendDataReader * /*reader*/, ModifierData *md)
{
SubsurfModifierData *smd = (SubsurfModifierData *)md;
- smd->emCache = smd->mCache = NULL;
+ smd->emCache = smd->mCache = nullptr;
}
ModifierTypeInfo modifierType_Subsurf = {
@@ -484,24 +482,24 @@ ModifierTypeInfo modifierType_Subsurf = {
/* copyData */ copyData,
- /* deformVerts */ NULL,
+ /* deformVerts */ nullptr,
/* deformMatrices */ deformMatrices,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
+ /* deformVertsEM */ nullptr,
+ /* deformMatricesEM */ nullptr,
/* modifyMesh */ modifyMesh,
- /* modifyGeometrySet */ NULL,
+ /* modifyGeometrySet */ nullptr,
/* initData */ initData,
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ isDisabled,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
+ /* updateDepsgraph */ nullptr,
+ /* dependsOnTime */ nullptr,
/* dependsOnNormals */ dependsOnNormals,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
+ /* foreachIDLink */ nullptr,
+ /* foreachTexLink */ nullptr,
/* freeRuntimeData */ freeRuntimeData,
/* panelRegister */ panelRegister,
- /* blendWrite */ NULL,
+ /* blendWrite */ nullptr,
/* blendRead */ blendRead,
};
diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c
index c5e117635b5..a34d66f394b 100644
--- a/source/blender/modifiers/intern/MOD_surface.c
+++ b/source/blender/modifiers/intern/MOD_surface.c
@@ -154,7 +154,7 @@ static void deformVerts(ModifierData *md,
MVert *verts = BKE_mesh_verts_for_write(surmd->mesh);
for (i = 0, x = surmd->x, v = surmd->v; i < mesh_verts_num; i++, x++, v++) {
float *vec = verts[i].co;
- mul_m4_v3(ctx->object->obmat, vec);
+ mul_m4_v3(ctx->object->object_to_world, vec);
if (init) {
v->co[0] = v->co[1] = v->co[2] = 0.0f;
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index e0083b37ef0..6a9321a78a2 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -192,9 +192,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(SurfaceDeformModifierData), modifier);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
@@ -1331,7 +1329,7 @@ static void deformVert(void *__restrict userdata,
const SDefDeformData *const data = (SDefDeformData *)userdata;
const SDefBind *sdbind = data->bind_verts[index].binds;
const int sdbind_num = data->bind_verts[index].binds_num;
- const unsigned int vertex_idx = data->bind_verts[index].vertex_idx;
+ const uint vertex_idx = data->bind_verts[index].vertex_idx;
float *const vertexCos = data->vertexCos[vertex_idx];
float norm[3], temp[3], offset[3];
@@ -1468,8 +1466,8 @@ static void surfacedeformModifier_do(ModifierData *md,
ob, md);
float tmp_mat[4][4];
- invert_m4_m4(tmp_mat, ob->obmat);
- mul_m4_m4m4(smd_orig->mat, tmp_mat, ob_target->obmat);
+ invert_m4_m4(tmp_mat, ob->object_to_world);
+ mul_m4_m4m4(smd_orig->mat, tmp_mat, ob_target->object_to_world);
/* Avoid converting edit-mesh data, binding is an exception. */
BKE_mesh_wrapper_ensure_mdata(target);
@@ -1505,7 +1503,7 @@ static void surfacedeformModifier_do(ModifierData *md,
ob, md, "Target polygons changed from %u to %u", smd->target_polys_num, target_polys_num);
return;
}
- if (smd->target_verts_num != 0 && smd->target_verts_num != target_verts_num) {
+ if (!ELEM(smd->target_verts_num, 0, target_verts_num)) {
if (smd->target_verts_num > target_verts_num) {
/* Number of vertices on the target did reduce. There is no usable recovery from this. */
BKE_modifier_set_error(ob,
diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c
index e8280bc9c97..5bae6090758 100644
--- a/source/blender/modifiers/intern/MOD_triangulate.c
+++ b/source/blender/modifiers/intern/MOD_triangulate.c
@@ -86,7 +86,7 @@ static Mesh *triangulate_mesh(Mesh *mesh,
/* force drawing of all edges (seems to be omitted in CDDM_from_bmesh) */
for (i = 0; i < edges_num; i++, me++) {
- me->flag |= ME_EDGEDRAW | ME_EDGERENDER;
+ me->flag |= ME_EDGEDRAW;
}
return result;
diff --git a/source/blender/modifiers/intern/MOD_ui_common.c b/source/blender/modifiers/intern/MOD_ui_common.c
index c027cae8cdb..0f6c40610a0 100644
--- a/source/blender/modifiers/intern/MOD_ui_common.c
+++ b/source/blender/modifiers/intern/MOD_ui_common.c
@@ -326,8 +326,34 @@ static void modifier_panel_header(const bContext *C, Panel *panel)
}
} /* Tessellation point for curve-typed objects. */
else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) {
+ /* Smooth modifier can work with tessellated curves only (works on mesh edges explicitly). */
+ if (md->type == eModifierType_Smooth) {
+ /* Add button (appearing to be OFF) and add tip why this can't be changed. */
+ sub = uiLayoutRow(row, true);
+ uiBlock *block = uiLayoutGetBlock(sub);
+ static int apply_on_spline_always_off_hack = 0;
+ uiBut *but = uiDefIconButBitI(block,
+ UI_BTYPE_TOGGLE,
+ eModifierMode_ApplyOnSpline,
+ 0,
+ ICON_SURFACE_DATA,
+ 0,
+ 0,
+ UI_UNIT_X - 2,
+ UI_UNIT_Y,
+ &apply_on_spline_always_off_hack,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ TIP_("Apply on Spline"));
+ UI_but_disable(
+ but, TIP_("This modifier can only deform filled curve/surface, not the control points"));
+ buttons_number++;
+ }
/* Some modifiers can work with pre-tessellated curves only. */
- if (ELEM(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
+ else if (ELEM(
+ md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
/* Add button (appearing to be ON) and add tip why this can't be changed. */
sub = uiLayoutRow(row, true);
uiBlock *block = uiLayoutGetBlock(sub);
diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.cc
index bc1a04d65ce..a94fc6732a0 100644
--- a/source/blender/modifiers/intern/MOD_util.c
+++ b/source/blender/modifiers/intern/MOD_util.cc
@@ -5,7 +5,7 @@
* \ingroup modifiers
*/
-#include <string.h>
+#include <cstring>
#include "BLI_utildefines.h"
@@ -46,7 +46,7 @@ void MOD_init_texture(MappingInfoModifierData *dmd, const ModifierEvalContext *c
{
Tex *tex = dmd->texture;
- if (tex == NULL) {
+ if (tex == nullptr) {
return;
}
@@ -57,7 +57,7 @@ void MOD_init_texture(MappingInfoModifierData *dmd, const ModifierEvalContext *c
/* TODO: to be renamed to get_texture_coords once we are done with moving modifiers to Mesh. */
void MOD_get_texture_coords(MappingInfoModifierData *dmd,
- const ModifierEvalContext *UNUSED(ctx),
+ const ModifierEvalContext * /*ctx*/,
Object *ob,
Mesh *mesh,
float (*cos)[3],
@@ -69,21 +69,21 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd,
float mapref_imat[4][4];
if (texmapping == MOD_DISP_MAP_OBJECT) {
- if (dmd->map_object != NULL) {
+ if (dmd->map_object != nullptr) {
Object *map_object = dmd->map_object;
if (dmd->map_bone[0] != '\0') {
bPoseChannel *pchan = BKE_pose_channel_find_name(map_object->pose, dmd->map_bone);
if (pchan) {
float mat_bone_world[4][4];
- mul_m4_m4m4(mat_bone_world, map_object->obmat, pchan->pose_mat);
+ mul_m4_m4m4(mat_bone_world, map_object->object_to_world, pchan->pose_mat);
invert_m4_m4(mapref_imat, mat_bone_world);
}
else {
- invert_m4_m4(mapref_imat, map_object->obmat);
+ invert_m4_m4(mapref_imat, map_object->object_to_world);
}
}
else {
- invert_m4_m4(mapref_imat, map_object->obmat);
+ invert_m4_m4(mapref_imat, map_object->object_to_world);
}
}
else { /* if there is no map object, default to local */
@@ -102,7 +102,8 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd,
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, dmd->uvlayer_name, uvname);
- const MLoopUV *mloop_uv = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname);
+ const MLoopUV *mloop_uv = static_cast<const MLoopUV *>(
+ CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname));
/* verts are given the UV from the first face that uses them */
for (i = 0, mp = mpoly; i < polys_num; i++, mp++) {
@@ -134,17 +135,17 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd,
for (i = 0; i < verts_num; i++, mv++, r_texco++) {
switch (texmapping) {
case MOD_DISP_MAP_LOCAL:
- copy_v3_v3(*r_texco, cos != NULL ? *cos : mv->co);
+ copy_v3_v3(*r_texco, cos != nullptr ? *cos : mv->co);
break;
case MOD_DISP_MAP_GLOBAL:
- mul_v3_m4v3(*r_texco, ob->obmat, cos != NULL ? *cos : mv->co);
+ mul_v3_m4v3(*r_texco, ob->object_to_world, cos != nullptr ? *cos : mv->co);
break;
case MOD_DISP_MAP_OBJECT:
- mul_v3_m4v3(*r_texco, ob->obmat, cos != NULL ? *cos : mv->co);
+ mul_v3_m4v3(*r_texco, ob->object_to_world, cos != nullptr ? *cos : mv->co);
mul_m4_v3(mapref_imat, *r_texco);
break;
}
- if (cos != NULL) {
+ if (cos != nullptr) {
cos++;
}
}
@@ -154,8 +155,8 @@ void MOD_previous_vcos_store(ModifierData *md, const float (*vert_coords)[3])
{
while ((md = md->next) && md->type == eModifierType_Armature) {
ArmatureModifierData *amd = (ArmatureModifierData *)md;
- if (amd->multi && amd->vert_coords_prev == NULL) {
- amd->vert_coords_prev = MEM_dupallocN(vert_coords);
+ if (amd->multi && amd->vert_coords_prev == nullptr) {
+ amd->vert_coords_prev = static_cast<float(*)[3]>(MEM_dupallocN(vert_coords));
}
else {
break;
@@ -171,25 +172,26 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob,
const int verts_num,
const bool use_orco)
{
- if (mesh != NULL) {
+ if (mesh != nullptr) {
/* pass */
}
else if (ob->type == OB_MESH) {
if (em) {
- mesh = BKE_mesh_wrapper_from_editmesh_with_coords(em, NULL, vertexCos, ob->data);
+ mesh = BKE_mesh_wrapper_from_editmesh_with_coords(
+ em, nullptr, vertexCos, static_cast<const Mesh *>(ob->data));
}
else {
/* TODO(sybren): after modifier conversion of DM to Mesh is done, check whether
* we really need a copy here. Maybe the CoW ob->data can be directly used. */
Mesh *mesh_prior_modifiers = BKE_object_get_pre_modified_mesh(ob);
- mesh = (Mesh *)BKE_id_copy_ex(NULL,
+ mesh = (Mesh *)BKE_id_copy_ex(nullptr,
&mesh_prior_modifiers->id,
- NULL,
+ nullptr,
(LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_CD_REFERENCE));
- mesh->runtime.deformed_only = 1;
+ mesh->runtime->deformed_only = 1;
}
- if (em != NULL) {
+ if (em != nullptr) {
/* pass */
}
/* TODO(sybren): after modifier conversion of DM to Mesh is done, check whether
@@ -210,13 +212,13 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob,
/* Currently, that may not be the case every time
* (texts e.g. tend to give issues,
* also when deforming curve points instead of generated curve geometry... ). */
- if (mesh != NULL && mesh->totvert != verts_num) {
- BKE_id_free(NULL, mesh);
- mesh = NULL;
+ if (mesh != nullptr && mesh->totvert != verts_num) {
+ BKE_id_free(nullptr, mesh);
+ mesh = nullptr;
}
}
- if (mesh && mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA) {
+ if (mesh && mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_MDATA) {
BLI_assert(mesh->totvert == verts_num);
}
@@ -232,7 +234,7 @@ void MOD_get_vgroup(
*dvert = BKE_mesh_deform_verts(mesh);
}
else {
- *dvert = NULL;
+ *dvert = nullptr;
}
}
else {
@@ -241,7 +243,7 @@ void MOD_get_vgroup(
*dvert = BKE_lattice_deform_verts_get(ob);
}
else {
- *dvert = NULL;
+ *dvert = nullptr;
}
}
}
@@ -251,7 +253,7 @@ void MOD_depsgraph_update_object_bone_relation(struct DepsNodeHandle *node,
const char *bonename,
const char *description)
{
- if (object == NULL) {
+ if (object == nullptr) {
return;
}
if (bonename[0] != '\0' && object->type == OB_ARMATURE) {
diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.cc
index 8db92fefd31..895572d9477 100644
--- a/source/blender/modifiers/intern/MOD_uvproject.c
+++ b/source/blender/modifiers/intern/MOD_uvproject.cc
@@ -52,9 +52,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(umd, DNA_struct_default_get(UVProjectModifierData), modifier);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *UNUSED(md),
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData * /*md*/, CustomData_MeshMasks *r_cddata_masks)
{
/* ask for UV coordinates */
r_cddata_masks->lmask |= CD_MASK_MLOOPUV;
@@ -73,7 +71,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
UVProjectModifierData *umd = (UVProjectModifierData *)md;
bool do_add_own_transform = false;
for (int i = 0; i < umd->projectors_num; i++) {
- if (umd->projectors[i] != NULL) {
+ if (umd->projectors[i] != nullptr) {
DEG_add_object_relation(
ctx->node, umd->projectors[i], DEG_OB_COMP_TRANSFORM, "UV Project Modifier");
do_add_own_transform = true;
@@ -84,20 +82,19 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
}
}
-typedef struct Projector {
+struct Projector {
Object *ob; /* object this projector is derived from */
float projmat[4][4]; /* projection matrix */
float normal[3]; /* projector normal in world space */
void *uci; /* optional uv-project info (panorama projection) */
-} Projector;
+};
static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
- const ModifierEvalContext *UNUSED(ctx),
+ const ModifierEvalContext * /*ctx*/,
Object *ob,
Mesh *mesh)
{
float(*coords)[3], (*co)[3];
- MLoopUV *mloop_uv;
int i, verts_num, polys_num, loops_num;
const MPoly *mp;
Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
@@ -110,7 +107,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
int free_uci = 0;
for (i = 0; i < umd->projectors_num; i++) {
- if (umd->projectors[i] != NULL) {
+ if (umd->projectors[i] != nullptr) {
projectors[projectors_num++].ob = umd->projectors[i];
}
}
@@ -123,7 +120,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
* (e.g. if a preceding modifier could not preserve it). */
if (!CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) {
CustomData_add_layer_named(
- &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, NULL, mesh->totloop, umd->uvlayer_name);
+ &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh->totloop, umd->uvlayer_name);
}
/* make sure we're using an existing layer */
@@ -133,17 +130,18 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
for (i = 0; i < projectors_num; i++) {
float tmpmat[4][4];
float offsetmat[4][4];
- Camera *cam = NULL;
+ Camera *cam = nullptr;
/* calculate projection matrix */
- invert_m4_m4(projectors[i].projmat, projectors[i].ob->obmat);
+ invert_m4_m4(projectors[i].projmat, projectors[i].ob->object_to_world);
- projectors[i].uci = NULL;
+ projectors[i].uci = nullptr;
if (projectors[i].ob->type == OB_CAMERA) {
cam = (Camera *)projectors[i].ob->data;
if (cam->type == CAM_PANO) {
- projectors[i].uci = BLI_uvproject_camera_info(projectors[i].ob, NULL, aspx, aspy);
- BLI_uvproject_camera_info_scale(projectors[i].uci, scax, scay);
+ projectors[i].uci = BLI_uvproject_camera_info(projectors[i].ob, nullptr, aspx, aspy);
+ BLI_uvproject_camera_info_scale(
+ static_cast<ProjCameraInfo *>(projectors[i].uci), scax, scay);
free_uci = 1;
}
else {
@@ -180,25 +178,25 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
projectors[i].normal[0] = 0;
projectors[i].normal[1] = 0;
projectors[i].normal[2] = 1;
- mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal);
+ mul_mat3_m4_v3(projectors[i].ob->object_to_world, projectors[i].normal);
}
polys_num = mesh->totpoly;
loops_num = mesh->totloop;
/* make sure we are not modifying the original UV map */
- mloop_uv = CustomData_duplicate_referenced_layer_named(
- &mesh->ldata, CD_MLOOPUV, uvname, loops_num);
+ MLoopUV *mloop_uv = static_cast<MLoopUV *>(
+ CustomData_duplicate_referenced_layer_named(&mesh->ldata, CD_MLOOPUV, uvname, loops_num));
coords = BKE_mesh_vert_coords_alloc(mesh, &verts_num);
/* Convert coords to world-space. */
for (i = 0, co = coords; i < verts_num; i++, co++) {
- mul_m4_v3(ob->obmat, *co);
+ mul_m4_v3(ob->object_to_world, *co);
}
/* if only one projector, project coords to UVs */
- if (projectors_num == 1 && projectors[0].uci == NULL) {
+ if (projectors_num == 1 && projectors[0].uci == nullptr) {
for (i = 0, co = coords; i < verts_num; i++, co++) {
mul_project_m4_v3(projectors[0].projmat, *co);
}
@@ -215,7 +213,8 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
do {
uint lidx = mp->loopstart + fidx;
uint vidx = loops[lidx].v;
- BLI_uvproject_from_camera(mloop_uv[lidx].uv, coords[vidx], projectors[0].uci);
+ BLI_uvproject_from_camera(
+ mloop_uv[lidx].uv, coords[vidx], static_cast<ProjCameraInfo *>(projectors[0].uci));
} while (fidx--);
}
else {
@@ -258,7 +257,8 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
do {
uint lidx = mp->loopstart + fidx;
uint vidx = loops[lidx].v;
- BLI_uvproject_from_camera(mloop_uv[lidx].uv, coords[vidx], best_projector->uci);
+ BLI_uvproject_from_camera(
+ mloop_uv[lidx].uv, coords[vidx], static_cast<ProjCameraInfo *>(best_projector->uci));
} while (fidx--);
}
else {
@@ -283,7 +283,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
}
}
- mesh->runtime.is_original_bmesh = false;
+ mesh->runtime->is_original_bmesh = false;
return mesh;
}
@@ -298,7 +298,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
return result;
}
-static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *sub;
uiLayout *layout = panel->layout;
@@ -310,7 +310,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropSep(layout, true);
- uiItemPointerR(layout, ptr, "uv_layer", &obj_data_ptr, "uv_layers", NULL, ICON_NONE);
+ uiItemPointerR(layout, ptr, "uv_layer", &obj_data_ptr, "uv_layers", nullptr, ICON_NONE);
/* Aspect and Scale are only used for camera projectors. */
bool has_camera = false;
@@ -325,17 +325,17 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
sub = uiLayoutColumn(layout, true);
uiLayoutSetActive(sub, has_camera);
- uiItemR(sub, ptr, "aspect_x", 0, NULL, ICON_NONE);
+ uiItemR(sub, ptr, "aspect_x", 0, nullptr, ICON_NONE);
uiItemR(sub, ptr, "aspect_y", 0, IFACE_("Y"), ICON_NONE);
sub = uiLayoutColumn(layout, true);
uiLayoutSetActive(sub, has_camera);
- uiItemR(sub, ptr, "scale_x", 0, NULL, ICON_NONE);
+ uiItemR(sub, ptr, "scale_x", 0, nullptr, ICON_NONE);
uiItemR(sub, ptr, "scale_y", 0, IFACE_("Y"), ICON_NONE);
uiItemR(layout, ptr, "projector_count", 0, IFACE_("Projectors"), ICON_NONE);
RNA_BEGIN (ptr, projector_ptr, "projectors") {
- uiItemR(layout, &projector_ptr, "object", 0, NULL, ICON_NONE);
+ uiItemR(layout, &projector_ptr, "object", 0, nullptr, ICON_NONE);
}
RNA_END;
@@ -359,24 +359,24 @@ ModifierTypeInfo modifierType_UVProject = {
/* copyData */ BKE_modifier_copydata_generic,
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
+ /* deformVerts */ nullptr,
+ /* deformMatrices */ nullptr,
+ /* deformVertsEM */ nullptr,
+ /* deformMatricesEM */ nullptr,
/* modifyMesh */ modifyMesh,
- /* modifyGeometrySet */ NULL,
+ /* modifyGeometrySet */ nullptr,
/* initData */ initData,
/* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
+ /* freeData */ nullptr,
+ /* isDisabled */ nullptr,
/* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
+ /* dependsOnTime */ nullptr,
+ /* dependsOnNormals */ nullptr,
/* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* foreachTexLink */ nullptr,
+ /* freeRuntimeData */ nullptr,
/* panelRegister */ panelRegister,
- /* blendWrite */ NULL,
- /* blendRead */ NULL,
+ /* blendWrite */ nullptr,
+ /* blendRead */ nullptr,
};
diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.cc
index ba6e18f6b7e..a96b28b4e2e 100644
--- a/source/blender/modifiers/intern/MOD_uvwarp.c
+++ b/source/blender/modifiers/intern/MOD_uvwarp.cc
@@ -4,7 +4,7 @@
* \ingroup modifiers
*/
-#include <string.h>
+#include <cstring>
#include "BLI_utildefines.h"
@@ -58,9 +58,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(umd, DNA_struct_default_get(UVWarpModifierData), modifier);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
UVWarpModifierData *umd = (UVWarpModifierData *)md;
@@ -74,14 +72,14 @@ static void matrix_from_obj_pchan(float mat[4][4], Object *ob, const char *bonen
{
bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bonename);
if (pchan) {
- mul_m4_m4m4(mat, ob->obmat, pchan->pose_mat);
+ mul_m4_m4m4(mat, ob->object_to_world, pchan->pose_mat);
}
else {
- copy_m4_m4(mat, ob->obmat);
+ copy_m4_m4(mat, ob->object_to_world);
}
}
-typedef struct UVWarpData {
+struct UVWarpData {
const MPoly *mpoly;
const MLoop *mloop;
MLoopUV *mloopuv;
@@ -91,13 +89,13 @@ typedef struct UVWarpData {
float (*warp_mat)[4];
bool invert_vgroup;
-} UVWarpData;
+};
static void uv_warp_compute(void *__restrict userdata,
const int i,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
- const UVWarpData *data = userdata;
+ const UVWarpData *data = static_cast<const UVWarpData *>(userdata);
const MPoly *mp = &data->mpoly[i];
const MLoop *ml = &data->mloop[mp->loopstart];
@@ -132,7 +130,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
{
UVWarpModifierData *umd = (UVWarpModifierData *)md;
int polys_num, loops_num;
- MLoopUV *mloopuv;
const MDeformVert *dvert;
int defgrp_index;
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
@@ -146,7 +143,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
return mesh;
}
- if (!ELEM(NULL, umd->object_src, umd->object_dst)) {
+ if (!ELEM(nullptr, umd->object_src, umd->object_dst)) {
float mat_src[4][4];
float mat_dst[4][4];
float imat_dst[4][4];
@@ -201,25 +198,25 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
loops_num = mesh->totloop;
/* make sure we are not modifying the original UV map */
- mloopuv = CustomData_duplicate_referenced_layer_named(
- &mesh->ldata, CD_MLOOPUV, uvname, loops_num);
+ MLoopUV *mloopuv = static_cast<MLoopUV *>(
+ CustomData_duplicate_referenced_layer_named(&mesh->ldata, CD_MLOOPUV, uvname, loops_num));
MOD_get_vgroup(ctx->object, mesh, umd->vgroup_name, &dvert, &defgrp_index);
- UVWarpData data = {
- .mpoly = polys,
- .mloop = loops,
- .mloopuv = mloopuv,
- .dvert = dvert,
- .defgrp_index = defgrp_index,
- .warp_mat = warp_mat,
- .invert_vgroup = invert_vgroup,
- };
+ UVWarpData data{};
+ data.mpoly = polys;
+ data.mloop = loops;
+ data.mloopuv = mloopuv;
+ data.dvert = dvert;
+ data.defgrp_index = defgrp_index;
+ data.warp_mat = warp_mat;
+ data.invert_vgroup = invert_vgroup;
+
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (polys_num > 1000);
BLI_task_parallel_range(0, polys_num, &data, uv_warp_compute, &settings);
- mesh->runtime.is_original_bmesh = false;
+ mesh->runtime->is_original_bmesh = false;
return mesh;
}
@@ -244,7 +241,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
DEG_add_depends_on_transform_relation(ctx->node, "UVWarp Modifier");
}
-static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *col;
uiLayout *layout = panel->layout;
@@ -257,53 +254,53 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropSep(layout, true);
- uiItemPointerR(layout, ptr, "uv_layer", &obj_data_ptr, "uv_layers", NULL, ICON_NONE);
+ uiItemPointerR(layout, ptr, "uv_layer", &obj_data_ptr, "uv_layers", nullptr, ICON_NONE);
col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "center", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "center", 0, nullptr, ICON_NONE);
col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "axis_u", 0, IFACE_("Axis U"), ICON_NONE);
uiItemR(col, ptr, "axis_v", 0, IFACE_("V"), ICON_NONE);
col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "object_from", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "object_from", 0, nullptr, ICON_NONE);
warp_obj_ptr = RNA_pointer_get(ptr, "object_from");
if (!RNA_pointer_is_null(&warp_obj_ptr) && RNA_enum_get(&warp_obj_ptr, "type") == OB_ARMATURE) {
PointerRNA warp_obj_data_ptr = RNA_pointer_get(&warp_obj_ptr, "data");
- uiItemPointerR(col, ptr, "bone_from", &warp_obj_data_ptr, "bones", NULL, ICON_NONE);
+ uiItemPointerR(col, ptr, "bone_from", &warp_obj_data_ptr, "bones", nullptr, ICON_NONE);
}
uiItemR(col, ptr, "object_to", 0, IFACE_("To"), ICON_NONE);
warp_obj_ptr = RNA_pointer_get(ptr, "object_to");
if (!RNA_pointer_is_null(&warp_obj_ptr) && RNA_enum_get(&warp_obj_ptr, "type") == OB_ARMATURE) {
PointerRNA warp_obj_data_ptr = RNA_pointer_get(&warp_obj_ptr, "data");
- uiItemPointerR(col, ptr, "bone_to", &warp_obj_data_ptr, "bones", NULL, ICON_NONE);
+ uiItemPointerR(col, ptr, "bone_to", &warp_obj_data_ptr, "bones", nullptr, ICON_NONE);
}
- modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
+ modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", nullptr);
modifier_panel_end(layout, ptr);
}
-static void transform_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void transform_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
uiLayoutSetPropSep(layout, true);
- uiItemR(layout, ptr, "offset", 0, NULL, ICON_NONE);
- uiItemR(layout, ptr, "scale", 0, NULL, ICON_NONE);
- uiItemR(layout, ptr, "rotation", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "offset", 0, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "scale", 0, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "rotation", 0, nullptr, ICON_NONE);
}
static void panelRegister(ARegionType *region_type)
{
PanelType *panel_type = modifier_panel_register(region_type, eModifierType_UVWarp, panel_draw);
modifier_subpanel_register(
- region_type, "offset", "Transform", NULL, transform_panel_draw, panel_type);
+ region_type, "offset", "Transform", nullptr, transform_panel_draw, panel_type);
}
ModifierTypeInfo modifierType_UVWarp = {
@@ -318,24 +315,24 @@ ModifierTypeInfo modifierType_UVWarp = {
/* copyData */ BKE_modifier_copydata_generic,
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
+ /* deformVerts */ nullptr,
+ /* deformMatrices */ nullptr,
+ /* deformVertsEM */ nullptr,
+ /* deformMatricesEM */ nullptr,
/* modifyMesh */ modifyMesh,
- /* modifyGeometrySet */ NULL,
+ /* modifyGeometrySet */ nullptr,
/* initData */ initData,
/* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
+ /* freeData */ nullptr,
+ /* isDisabled */ nullptr,
/* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
+ /* dependsOnTime */ nullptr,
+ /* dependsOnNormals */ nullptr,
/* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* foreachTexLink */ nullptr,
+ /* freeRuntimeData */ nullptr,
/* panelRegister */ panelRegister,
- /* blendWrite */ NULL,
- /* blendRead */ NULL,
+ /* blendWrite */ nullptr,
+ /* blendRead */ nullptr,
};
diff --git a/source/blender/modifiers/intern/MOD_volume_displace.cc b/source/blender/modifiers/intern/MOD_volume_displace.cc
index d9b94d79348..2d6f8c100e7 100644
--- a/source/blender/modifiers/intern/MOD_volume_displace.cc
+++ b/source/blender/modifiers/intern/MOD_volume_displace.cc
@@ -84,7 +84,7 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void
walk(userData, ob, md, "texture");
}
-static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *md)
+static bool dependsOnTime(struct Scene * /*scene*/, ModifierData *md)
{
VolumeDisplaceModifierData *vdmd = reinterpret_cast<VolumeDisplaceModifierData *>(md);
if (vdmd->texture) {
@@ -213,7 +213,7 @@ struct DisplaceGridOp {
const float sample_radius = vdmd.texture_sample_radius * std::abs(vdmd.strength) /
max_voxel_side_length / 2.0f;
openvdb::tools::dilateActiveValues(temp_grid->tree(),
- static_cast<int>(std::ceil(sample_radius)),
+ int(std::ceil(sample_radius)),
openvdb::tools::NN_FACE_EDGE,
openvdb::tools::EXPAND_TILES);
@@ -254,15 +254,16 @@ struct DisplaceGridOp {
return index_to_object;
}
case MOD_VOLUME_DISPLACE_MAP_GLOBAL: {
- const openvdb::Mat4s object_to_world = matrix_to_openvdb(ctx.object->obmat);
+ const openvdb::Mat4s object_to_world = matrix_to_openvdb(ctx.object->object_to_world);
return index_to_object * object_to_world;
}
case MOD_VOLUME_DISPLACE_MAP_OBJECT: {
if (vdmd.texture_map_object == nullptr) {
return index_to_object;
}
- const openvdb::Mat4s object_to_world = matrix_to_openvdb(ctx.object->obmat);
- const openvdb::Mat4s world_to_texture = matrix_to_openvdb(vdmd.texture_map_object->imat);
+ const openvdb::Mat4s object_to_world = matrix_to_openvdb(ctx.object->object_to_world);
+ const openvdb::Mat4s world_to_texture = matrix_to_openvdb(
+ vdmd.texture_map_object->world_to_object);
return index_to_object * object_to_world * world_to_texture;
}
}
diff --git a/source/blender/modifiers/intern/MOD_volume_to_mesh.cc b/source/blender/modifiers/intern/MOD_volume_to_mesh.cc
index 0065012db97..2a8883dc2eb 100644
--- a/source/blender/modifiers/intern/MOD_volume_to_mesh.cc
+++ b/source/blender/modifiers/intern/MOD_volume_to_mesh.cc
@@ -77,7 +77,7 @@ static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *u
walk(userData, ob, (ID **)&vmmd->object, IDWALK_CB_NOP);
}
-static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
@@ -157,8 +157,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
volume_grid);
openvdb::math::Transform::Ptr transform = local_grid->transform().copy();
- transform->postMult(openvdb::Mat4d(((float *)vmmd->object->obmat)));
- openvdb::Mat4d imat = openvdb::Mat4d((float *)ctx->object->imat);
+ transform->postMult(openvdb::Mat4d((float *)vmmd->object->object_to_world));
+ openvdb::Mat4d imat = openvdb::Mat4d((float *)ctx->object->world_to_object);
/* `imat` had floating point issues and wasn't affine. */
imat.setCol(3, openvdb::Vec4d(0, 0, 0, 1));
transform->postMult(imat);
diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c
index ab6b2941d2f..791eed28a71 100644
--- a/source/blender/modifiers/intern/MOD_warp.c
+++ b/source/blender/modifiers/intern/MOD_warp.c
@@ -70,9 +70,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla
twmd->curfalloff = BKE_curvemapping_copy(wmd->curfalloff);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
WarpModifierData *wmd = (WarpModifierData *)md;
@@ -95,11 +93,11 @@ static void matrix_from_obj_pchan(float mat[4][4],
bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bonename);
if (pchan) {
float mat_bone_world[4][4];
- mul_m4_m4m4(mat_bone_world, ob->obmat, pchan->pose_mat);
+ mul_m4_m4m4(mat_bone_world, ob->object_to_world, pchan->pose_mat);
mul_m4_m4m4(mat, obinv, mat_bone_world);
}
else {
- mul_m4_m4m4(mat, obinv, ob->obmat);
+ mul_m4_m4m4(mat, obinv, ob->object_to_world);
}
}
@@ -217,7 +215,7 @@ static void warpModifier_do(WarpModifierData *wmd,
BKE_curvemapping_init(wmd->curfalloff);
}
- invert_m4_m4(obinv, ob->obmat);
+ invert_m4_m4(obinv, ob->object_to_world);
/* Checks that the objects/bones are available. */
matrix_from_obj_pchan(mat_from, obinv, wmd->object_from, wmd->bone_from);
diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.cc
index a6b274909c0..dce006bda92 100644
--- a/source/blender/modifiers/intern/MOD_wave.c
+++ b/source/blender/modifiers/intern/MOD_wave.cc
@@ -21,6 +21,7 @@
#include "BKE_context.h"
#include "BKE_deform.h"
#include "BKE_editmesh.h"
+#include "BKE_editmesh_cache.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_mesh.h"
@@ -55,7 +56,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(wmd, DNA_struct_default_get(WaveModifierData), modifier);
}
-static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *UNUSED(md))
+static bool dependsOnTime(Scene * /*scene*/, ModifierData * /*md*/)
{
return true;
}
@@ -79,15 +80,15 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
WaveModifierData *wmd = (WaveModifierData *)md;
bool need_transform_relation = false;
- if (wmd->objectcenter != NULL) {
+ if (wmd->objectcenter != nullptr) {
DEG_add_object_relation(ctx->node, wmd->objectcenter, DEG_OB_COMP_TRANSFORM, "Wave Modifier");
need_transform_relation = true;
}
- if (wmd->texture != NULL) {
+ if (wmd->texture != nullptr) {
DEG_add_generic_id_relation(ctx->node, &wmd->texture->id, "Wave Modifier");
- if ((wmd->texmapping == MOD_DISP_MAP_OBJECT) && wmd->map_object != NULL) {
+ if ((wmd->texmapping == MOD_DISP_MAP_OBJECT) && wmd->map_object != nullptr) {
MOD_depsgraph_update_object_bone_relation(
ctx->node, wmd->map_object, wmd->map_bone, "Wave Modifier");
need_transform_relation = true;
@@ -102,9 +103,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
}
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
WaveModifierData *wmd = (WaveModifierData *)md;
@@ -137,24 +136,24 @@ static void waveModifier_do(WaveModifierData *md,
const MDeformVert *dvert;
int defgrp_index;
float ctime = DEG_get_ctime(ctx->depsgraph);
- float minfac = (float)(1.0 / exp(wmd->width * wmd->narrow * wmd->width * wmd->narrow));
+ float minfac = float(1.0 / exp(wmd->width * wmd->narrow * wmd->width * wmd->narrow));
float lifefac = wmd->height;
- float(*tex_co)[3] = NULL;
+ float(*tex_co)[3] = nullptr;
const int wmd_axis = wmd->flag & (MOD_WAVE_X | MOD_WAVE_Y);
const float falloff = wmd->falloff;
float falloff_fac = 1.0f; /* when falloff == 0.0f this stays at 1.0f */
const bool invert_group = (wmd->flag & MOD_WAVE_INVERT_VGROUP) != 0;
- const float(*vert_normals)[3] = NULL;
- if ((wmd->flag & MOD_WAVE_NORM) && (mesh != NULL)) {
+ const float(*vert_normals)[3] = nullptr;
+ if ((wmd->flag & MOD_WAVE_NORM) && (mesh != nullptr)) {
vert_normals = BKE_mesh_vertex_normals_ensure(mesh);
}
- if (wmd->objectcenter != NULL) {
+ if (wmd->objectcenter != nullptr) {
float mat[4][4];
/* get the control object's location in local coordinates */
- invert_m4_m4(ob->imat, ob->obmat);
- mul_m4_m4m4(mat, ob->imat, wmd->objectcenter->obmat);
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
+ mul_m4_m4m4(mat, ob->world_to_object, wmd->objectcenter->object_to_world);
wmd->startx = mat[3][0];
wmd->starty = mat[3][1];
@@ -177,14 +176,14 @@ static void waveModifier_do(WaveModifierData *md,
lifefac = 0.0;
}
else {
- lifefac = (float)(wmd->height * (1.0f - sqrtf(lifefac / wmd->damp)));
+ lifefac = float(wmd->height * (1.0f - sqrtf(lifefac / wmd->damp)));
}
}
}
Tex *tex_target = wmd->texture;
- if (mesh != NULL && tex_target != NULL) {
- tex_co = MEM_malloc_arrayN(verts_num, sizeof(*tex_co), "waveModifier_do tex_co");
+ if (mesh != nullptr && tex_target != nullptr) {
+ tex_co = static_cast<float(*)[3]>(MEM_malloc_arrayN(verts_num, sizeof(*tex_co), __func__));
MOD_get_texture_coords((MappingInfoModifierData *)wmd, ctx, ob, mesh, vertexCos, tex_co);
MOD_init_texture((MappingInfoModifierData *)wmd, ctx);
@@ -229,7 +228,7 @@ static void waveModifier_do(WaveModifierData *md,
amplit -= (ctime - wmd->timeoffs) * wmd->speed;
if (wmd->flag & MOD_WAVE_CYCL) {
- amplit = (float)fmodf(amplit - wmd->width, 2.0f * wmd->width) + wmd->width;
+ amplit = float(fmodf(amplit - wmd->width, 2.0f * wmd->width)) + wmd->width;
}
if (falloff != 0.0f) {
@@ -254,7 +253,7 @@ static void waveModifier_do(WaveModifierData *md,
/* GAUSSIAN */
if ((falloff_fac != 0.0f) && (amplit > -wmd->width) && (amplit < wmd->width)) {
amplit = amplit * wmd->narrow;
- amplit = (float)(1.0f / expf(amplit * amplit) - minfac);
+ amplit = float(1.0f / expf(amplit * amplit) - minfac);
/* Apply texture. */
if (tex_co) {
@@ -297,58 +296,58 @@ static void deformVerts(ModifierData *md,
int verts_num)
{
WaveModifierData *wmd = (WaveModifierData *)md;
- Mesh *mesh_src = NULL;
+ Mesh *mesh_src = nullptr;
if (wmd->flag & MOD_WAVE_NORM) {
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, vertexCos, verts_num, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, vertexCos, verts_num, false);
}
- else if (wmd->texture != NULL || wmd->defgrp_name[0] != '\0') {
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false);
+ else if (wmd->texture != nullptr || wmd->defgrp_name[0] != '\0') {
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false);
}
waveModifier_do(wmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
+ if (!ELEM(mesh_src, nullptr, mesh)) {
+ BKE_id_free(nullptr, mesh_src);
}
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
- struct BMEditMesh *editData,
+ BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
int verts_num)
{
WaveModifierData *wmd = (WaveModifierData *)md;
- Mesh *mesh_src = NULL;
+ Mesh *mesh_src = nullptr;
if (wmd->flag & MOD_WAVE_NORM) {
mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, vertexCos, verts_num, false);
}
- else if (wmd->texture != NULL || wmd->defgrp_name[0] != '\0') {
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, verts_num, false);
+ else if (wmd->texture != nullptr || wmd->defgrp_name[0] != '\0') {
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr, verts_num, false);
}
/* TODO(@campbellbarton): use edit-mode data only (remove this line). */
- if (mesh_src != NULL) {
+ if (mesh_src != nullptr) {
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
waveModifier_do(wmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
- if (!ELEM(mesh_src, NULL, mesh)) {
+ if (!ELEM(mesh_src, nullptr, mesh)) {
/* Important not to free `vertexCos` owned by the caller. */
- EditMeshData *edit_data = mesh_src->runtime.edit_data;
+ EditMeshData *edit_data = mesh_src->runtime->edit_data;
if (edit_data->vertexCos == vertexCos) {
- edit_data->vertexCos = NULL;
+ edit_data->vertexCos = nullptr;
}
- BKE_id_free(NULL, mesh_src);
+ BKE_id_free(nullptr, mesh_src);
}
}
-static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *sub, *row, *col;
uiLayout *layout = panel->layout;
@@ -359,10 +358,12 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropSep(layout, true);
row = uiLayoutRowWithHeading(layout, true, IFACE_("Motion"));
- uiItemR(row, ptr, "use_x", UI_ITEM_R_TOGGLE | UI_ITEM_R_FORCE_BLANK_DECORATE, NULL, ICON_NONE);
- uiItemR(row, ptr, "use_y", UI_ITEM_R_TOGGLE | UI_ITEM_R_FORCE_BLANK_DECORATE, NULL, ICON_NONE);
+ uiItemR(
+ row, ptr, "use_x", UI_ITEM_R_TOGGLE | UI_ITEM_R_FORCE_BLANK_DECORATE, nullptr, ICON_NONE);
+ uiItemR(
+ row, ptr, "use_y", UI_ITEM_R_TOGGLE | UI_ITEM_R_FORCE_BLANK_DECORATE, nullptr, ICON_NONE);
- uiItemR(layout, ptr, "use_cyclic", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_cyclic", 0, nullptr, ICON_NONE);
row = uiLayoutRowWithHeading(layout, true, IFACE_("Along Normals"));
uiItemR(row, ptr, "use_normal", 0, "", ICON_NONE);
@@ -374,21 +375,21 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "falloff_radius", 0, IFACE_("Falloff"), ICON_NONE);
- uiItemR(col, ptr, "height", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(col, ptr, "width", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(col, ptr, "narrowness", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(col, ptr, "height", UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "width", UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "narrowness", UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
- modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
+ modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", nullptr);
modifier_panel_end(layout, ptr);
}
-static void position_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void position_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *col;
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
uiLayoutSetPropSep(layout, true);
@@ -399,12 +400,12 @@ static void position_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(col, ptr, "start_position_y", 0, "Y", ICON_NONE);
}
-static void time_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void time_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *col;
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
uiLayoutSetPropSep(layout, true);
@@ -412,7 +413,7 @@ static void time_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(col, ptr, "time_offset", 0, IFACE_("Offset"), ICON_NONE);
uiItemR(col, ptr, "lifetime", 0, IFACE_("Life"), ICON_NONE);
uiItemR(col, ptr, "damping_time", 0, IFACE_("Damping"), ICON_NONE);
- uiItemR(col, ptr, "speed", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(col, ptr, "speed", UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
}
static void texture_panel_draw(const bContext *C, Panel *panel)
@@ -425,7 +426,7 @@ static void texture_panel_draw(const bContext *C, Panel *panel)
int texture_coords = RNA_enum_get(ptr, "texture_coords");
- uiTemplateID(layout, C, ptr, "texture", "texture.new", NULL, NULL, 0, ICON_NONE, NULL);
+ uiTemplateID(layout, C, ptr, "texture", "texture.new", nullptr, nullptr, 0, ICON_NONE, nullptr);
uiLayoutSetPropSep(layout, true);
@@ -448,7 +449,7 @@ static void texture_panel_draw(const bContext *C, Panel *panel)
}
else if (texture_coords == MOD_DISP_MAP_UV && RNA_enum_get(&ob_ptr, "type") == OB_MESH) {
PointerRNA obj_data_ptr = RNA_pointer_get(&ob_ptr, "data");
- uiItemPointerR(col, ptr, "uv_layer", &obj_data_ptr, "uv_layers", NULL, ICON_NONE);
+ uiItemPointerR(col, ptr, "uv_layer", &obj_data_ptr, "uv_layers", nullptr, ICON_NONE);
}
}
@@ -456,10 +457,10 @@ static void panelRegister(ARegionType *region_type)
{
PanelType *panel_type = modifier_panel_register(region_type, eModifierType_Wave, panel_draw);
modifier_subpanel_register(
- region_type, "position", "Start Position", NULL, position_panel_draw, panel_type);
- modifier_subpanel_register(region_type, "time", "Time", NULL, time_panel_draw, panel_type);
+ region_type, "position", "Start Position", nullptr, position_panel_draw, panel_type);
+ modifier_subpanel_register(region_type, "time", "Time", nullptr, time_panel_draw, panel_type);
modifier_subpanel_register(
- region_type, "texture", "Texture", NULL, texture_panel_draw, panel_type);
+ region_type, "texture", "Texture", nullptr, texture_panel_draw, panel_type);
}
ModifierTypeInfo modifierType_Wave = {
@@ -475,23 +476,23 @@ ModifierTypeInfo modifierType_Wave = {
/* copyData */ BKE_modifier_copydata_generic,
/* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
+ /* deformMatrices */ nullptr,
/* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* modifyMesh */ NULL,
- /* modifyGeometrySet */ NULL,
+ /* deformMatricesEM */ nullptr,
+ /* modifyMesh */ nullptr,
+ /* modifyGeometrySet */ nullptr,
/* initData */ initData,
/* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
+ /* freeData */ nullptr,
+ /* isDisabled */ nullptr,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ dependsOnNormals,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ foreachTexLink,
- /* freeRuntimeData */ NULL,
+ /* freeRuntimeData */ nullptr,
/* panelRegister */ panelRegister,
- /* blendWrite */ NULL,
- /* blendRead */ NULL,
+ /* blendWrite */ nullptr,
+ /* blendRead */ nullptr,
};
diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.c b/source/blender/modifiers/intern/MOD_weighted_normal.cc
index ba441581770..1ebd5423d39 100644
--- a/source/blender/modifiers/intern/MOD_weighted_normal.c
+++ b/source/blender/modifiers/intern/MOD_weighted_normal.cc
@@ -39,10 +39,10 @@
#define CLNORS_VALID_VEC_LEN (1e-6f)
-typedef struct ModePair {
+struct ModePair {
float val; /* Contains mode based value (face area / corner angle). */
int index; /* Index value per poly or per loop. */
-} ModePair;
+};
/* Sorting function used in modifier, sorts in decreasing order. */
static int modepair_cmp_by_val_inverse(const void *p1, const void *p2)
@@ -55,21 +55,21 @@ static int modepair_cmp_by_val_inverse(const void *p1, const void *p2)
/* There will be one of those per vertex
* (simple case, computing one normal per vertex), or per smooth fan. */
-typedef struct WeightedNormalDataAggregateItem {
+struct WeightedNormalDataAggregateItem {
float normal[3];
int loops_num; /* Count number of loops using this item so far. */
float curr_val; /* Current max val for this item. */
int curr_strength; /* Current max strength encountered for this item. */
-} WeightedNormalDataAggregateItem;
+};
#define NUM_CACHED_INVERSE_POWERS_OF_WEIGHT 128
-typedef struct WeightedNormalData {
- const int verts_num;
- const int edges_num;
- const int loops_num;
- const int polys_num;
+struct WeightedNormalData {
+ int verts_num;
+ int edges_num;
+ int loops_num;
+ int polys_num;
const MVert *mvert;
const float (*vert_normals)[3];
@@ -77,19 +77,19 @@ typedef struct WeightedNormalData {
const MLoop *mloop;
short (*clnors)[2];
- const bool has_clnors; /* True if clnors already existed, false if we had to create them. */
- const float split_angle;
+ bool has_clnors; /* True if clnors already existed, false if we had to create them. */
+ float split_angle;
const MPoly *mpoly;
const float (*polynors)[3];
const int *poly_strength;
const MDeformVert *dvert;
- const int defgrp_index;
- const bool use_invert_vgroup;
+ int defgrp_index;
+ bool use_invert_vgroup;
- const float weight;
- const short mode;
+ float weight;
+ short mode;
/* Lower-level, internal processing data. */
float cached_inverse_powers_of_weight[NUM_CACHED_INVERSE_POWERS_OF_WEIGHT];
@@ -99,7 +99,7 @@ typedef struct WeightedNormalData {
ModePair *mode_pair;
int *loop_to_poly;
-} WeightedNormalData;
+};
/**
* Check strength of given poly compared to those found so far for that given item
@@ -109,7 +109,7 @@ static bool check_item_poly_strength(WeightedNormalData *wn_data,
WeightedNormalDataAggregateItem *item_data,
const int mp_index)
{
- BLI_assert(wn_data->poly_strength != NULL);
+ BLI_assert(wn_data->poly_strength != nullptr);
const int mp_strength = wn_data->poly_strength[mp_index];
@@ -141,9 +141,9 @@ static void aggregate_item_normal(WeightedNormalModifierData *wnmd,
float *cached_inverse_powers_of_weight = wn_data->cached_inverse_powers_of_weight;
- const bool has_vgroup = dvert != NULL;
+ const bool has_vgroup = dvert != nullptr;
const bool vert_of_group = has_vgroup &&
- BKE_defvert_find_index(&dvert[mv_index], defgrp_index) != NULL;
+ BKE_defvert_find_index(&dvert[mv_index], defgrp_index) != nullptr;
if (has_vgroup &&
((vert_of_group && use_invert_vgroup) || (!vert_of_group && !use_invert_vgroup))) {
@@ -204,23 +204,24 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
const bool has_clnors = wn_data->has_clnors;
const float split_angle = wn_data->split_angle;
- MLoopNorSpaceArray lnors_spacearr = {NULL};
+ MLoopNorSpaceArray lnors_spacearr = {nullptr};
const bool keep_sharp = (wnmd->flag & MOD_WEIGHTEDNORMAL_KEEP_SHARP) != 0;
const bool use_face_influence = (wnmd->flag & MOD_WEIGHTEDNORMAL_FACE_INFLUENCE) != 0 &&
- poly_strength != NULL;
- const bool has_vgroup = dvert != NULL;
+ poly_strength != nullptr;
+ const bool has_vgroup = dvert != nullptr;
- float(*loop_normals)[3] = NULL;
+ float(*loop_normals)[3] = nullptr;
- WeightedNormalDataAggregateItem *items_data = NULL;
+ WeightedNormalDataAggregateItem *items_data = nullptr;
int items_num = 0;
if (keep_sharp) {
BLI_bitmap *done_loops = BLI_BITMAP_NEW(loops_num, __func__);
/* This will give us loop normal spaces,
* we do not actually care about computed loop_normals for now... */
- loop_normals = MEM_calloc_arrayN((size_t)loops_num, sizeof(*loop_normals), __func__);
+ loop_normals = static_cast<float(*)[3]>(
+ MEM_calloc_arrayN(size_t(loops_num), sizeof(*loop_normals), __func__));
BKE_mesh_normals_loop_split(mvert,
wn_data->vert_normals,
verts_num,
@@ -235,11 +236,12 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
true,
split_angle,
&lnors_spacearr,
- has_clnors ? clnors : NULL,
+ has_clnors ? clnors : nullptr,
loop_to_poly);
items_num = lnors_spacearr.spaces_num;
- items_data = MEM_calloc_arrayN((size_t)items_num, sizeof(*items_data), __func__);
+ items_data = static_cast<WeightedNormalDataAggregateItem *>(
+ MEM_calloc_arrayN(size_t(items_num), sizeof(*items_data), __func__));
/* In this first loop, we assign each WeightedNormalDataAggregateItem
* to its smooth fan of loops (aka lnor space). */
@@ -281,7 +283,8 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
}
else {
items_num = verts_num;
- items_data = MEM_calloc_arrayN((size_t)items_num, sizeof(*items_data), __func__);
+ items_data = static_cast<WeightedNormalDataAggregateItem *>(
+ MEM_calloc_arrayN(size_t(items_num), sizeof(*items_data), __func__));
if (use_face_influence) {
for (int item_index = 0; item_index < items_num; item_index++) {
items_data[item_index].curr_strength = FACE_STRENGTH_WEAK;
@@ -301,7 +304,9 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
for (; ml_index < ml_index_end; ml_index++) {
const int mv_index = mloop[ml_index].v;
WeightedNormalDataAggregateItem *item_data =
- keep_sharp ? lnors_spacearr.lspacearr[ml_index]->user_data : &items_data[mv_index];
+ keep_sharp ? static_cast<WeightedNormalDataAggregateItem *>(
+ lnors_spacearr.lspacearr[ml_index]->user_data) :
+ &items_data[mv_index];
aggregate_item_normal(
wnmd, wn_data, item_data, mv_index, mp_index, mp_val, use_face_influence);
@@ -310,7 +315,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
break;
case MOD_WEIGHTEDNORMAL_MODE_ANGLE:
case MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE:
- BLI_assert(loop_to_poly != NULL);
+ BLI_assert(loop_to_poly != nullptr);
for (int i = 0; i < loops_num; i++) {
const int ml_index = mode_pair[i].index;
@@ -319,7 +324,9 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
const int mp_index = loop_to_poly[ml_index];
const int mv_index = mloop[ml_index].v;
WeightedNormalDataAggregateItem *item_data =
- keep_sharp ? lnors_spacearr.lspacearr[ml_index]->user_data : &items_data[mv_index];
+ keep_sharp ? static_cast<WeightedNormalDataAggregateItem *>(
+ lnors_spacearr.lspacearr[ml_index]->user_data) :
+ &items_data[mv_index];
aggregate_item_normal(
wnmd, wn_data, item_data, mv_index, mp_index, ml_val, use_face_influence);
@@ -342,7 +349,8 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
* (before this modifier is applied, at start of this function),
* so no need to recompute them here. */
for (int ml_index = 0; ml_index < loops_num; ml_index++) {
- WeightedNormalDataAggregateItem *item_data = lnors_spacearr.lspacearr[ml_index]->user_data;
+ WeightedNormalDataAggregateItem *item_data = static_cast<WeightedNormalDataAggregateItem *>(
+ lnors_spacearr.lspacearr[ml_index]->user_data);
if (!is_zero_v3(item_data->normal)) {
copy_v3_v3(loop_normals[ml_index], item_data->normal);
}
@@ -371,8 +379,8 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
/* NOTE: in theory, we could avoid this extra allocation & copying...
* But think we can live with it for now,
* and it makes code simpler & cleaner. */
- float(*vert_normals)[3] = MEM_calloc_arrayN(
- (size_t)verts_num, sizeof(*loop_normals), __func__);
+ float(*vert_normals)[3] = static_cast<float(*)[3]>(
+ MEM_calloc_arrayN(size_t(verts_num), sizeof(*loop_normals), __func__));
for (int ml_index = 0; ml_index < loops_num; ml_index++) {
const int mv_index = mloop[ml_index].v;
@@ -395,7 +403,8 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
MEM_freeN(vert_normals);
}
else {
- loop_normals = MEM_calloc_arrayN((size_t)loops_num, sizeof(*loop_normals), __func__);
+ loop_normals = static_cast<float(*)[3]>(
+ MEM_calloc_arrayN(size_t(loops_num), sizeof(*loop_normals), __func__));
BKE_mesh_normals_loop_split(mvert,
wn_data->vert_normals,
@@ -410,8 +419,8 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
polys_num,
true,
split_angle,
- NULL,
- has_clnors ? clnors : NULL,
+ nullptr,
+ has_clnors ? clnors : nullptr,
loop_to_poly);
for (int ml_index = 0; ml_index < loops_num; ml_index++) {
@@ -453,7 +462,8 @@ static void wn_face_area(WeightedNormalModifierData *wnmd, WeightedNormalData *w
const MPoly *mp;
int mp_index;
- ModePair *face_area = MEM_malloc_arrayN((size_t)polys_num, sizeof(*face_area), __func__);
+ ModePair *face_area = static_cast<ModePair *>(
+ MEM_malloc_arrayN(size_t(polys_num), sizeof(*face_area), __func__));
ModePair *f_area = face_area;
for (mp_index = 0, mp = mpoly; mp_index < polys_num; mp_index++, mp++, f_area++) {
@@ -479,21 +489,24 @@ static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData
const MPoly *mp;
int mp_index;
- int *loop_to_poly = MEM_malloc_arrayN((size_t)loops_num, sizeof(*loop_to_poly), __func__);
+ int *loop_to_poly = static_cast<int *>(
+ MEM_malloc_arrayN(size_t(loops_num), sizeof(*loop_to_poly), __func__));
- ModePair *corner_angle = MEM_malloc_arrayN((size_t)loops_num, sizeof(*corner_angle), __func__);
+ ModePair *corner_angle = static_cast<ModePair *>(
+ MEM_malloc_arrayN(size_t(loops_num), sizeof(*corner_angle), __func__));
for (mp_index = 0, mp = mpoly; mp_index < polys_num; mp_index++, mp++) {
const MLoop *ml_start = &mloop[mp->loopstart];
- float *index_angle = MEM_malloc_arrayN((size_t)mp->totloop, sizeof(*index_angle), __func__);
+ float *index_angle = static_cast<float *>(
+ MEM_malloc_arrayN(size_t(mp->totloop), sizeof(*index_angle), __func__));
BKE_mesh_calc_poly_angles(mp, ml_start, mvert, index_angle);
ModePair *c_angl = &corner_angle[mp->loopstart];
float *angl = index_angle;
for (int ml_index = mp->loopstart; ml_index < mp->loopstart + mp->totloop;
ml_index++, c_angl++, angl++) {
- c_angl->val = (float)M_PI - *angl;
+ c_angl->val = float(M_PI) - *angl;
c_angl->index = ml_index;
loop_to_poly[ml_index] = mp_index;
@@ -520,15 +533,18 @@ static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalD
const MPoly *mp;
int mp_index;
- int *loop_to_poly = MEM_malloc_arrayN((size_t)loops_num, sizeof(*loop_to_poly), __func__);
+ int *loop_to_poly = static_cast<int *>(
+ MEM_malloc_arrayN(size_t(loops_num), sizeof(*loop_to_poly), __func__));
- ModePair *combined = MEM_malloc_arrayN((size_t)loops_num, sizeof(*combined), __func__);
+ ModePair *combined = static_cast<ModePair *>(
+ MEM_malloc_arrayN(size_t(loops_num), sizeof(*combined), __func__));
for (mp_index = 0, mp = mpoly; mp_index < polys_num; mp_index++, mp++) {
const MLoop *ml_start = &mloop[mp->loopstart];
float face_area = BKE_mesh_calc_poly_area(mp, ml_start, mvert);
- float *index_angle = MEM_malloc_arrayN((size_t)mp->totloop, sizeof(*index_angle), __func__);
+ float *index_angle = static_cast<float *>(
+ MEM_malloc_arrayN(size_t(mp->totloop), sizeof(*index_angle), __func__));
BKE_mesh_calc_poly_angles(mp, ml_start, mvert, index_angle);
ModePair *cmbnd = &combined[mp->loopstart];
@@ -536,7 +552,7 @@ static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalD
for (int ml_index = mp->loopstart; ml_index < mp->loopstart + mp->totloop;
ml_index++, cmbnd++, angl++) {
/* In this case val is product of corner angle and face area. */
- cmbnd->val = ((float)M_PI - *angl) * face_area;
+ cmbnd->val = (float(M_PI) - *angl) * face_area;
cmbnd->index = ml_index;
loop_to_poly[ml_index] = mp_index;
@@ -573,7 +589,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
Mesh *result;
- result = (Mesh *)BKE_id_copy_ex(NULL, &mesh->id, NULL, LIB_ID_COPY_LOCALIZE);
+ result = (Mesh *)BKE_id_copy_ex(nullptr, &mesh->id, nullptr, LIB_ID_COPY_LOCALIZE);
const int verts_num = result->totvert;
const int edges_num = result->totedge;
@@ -590,59 +606,59 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
* If weight < 50 then more weight given to faces with lesser vals. However current calculation
* does not converge to min/max.
*/
- float weight = ((float)wnmd->weight) / 50.0f;
+ float weight = float(wnmd->weight) / 50.0f;
if (wnmd->weight == 100) {
- weight = (float)SHRT_MAX;
+ weight = float(SHRT_MAX);
}
else if (wnmd->weight == 1) {
- weight = 1 / (float)SHRT_MAX;
+ weight = 1 / float(SHRT_MAX);
}
else if ((weight - 1) * 25 > 1) {
weight = (weight - 1) * 25;
}
const float split_angle = mesh->smoothresh;
- short(*clnors)[2] = CustomData_get_layer(&result->ldata, CD_CUSTOMLOOPNORMAL);
+ short(*clnors)[2] = static_cast<short(*)[2]>(
+ CustomData_get_layer(&result->ldata, CD_CUSTOMLOOPNORMAL));
/* Keep info whether we had clnors,
* it helps when generating clnor spaces and default normals. */
- const bool has_clnors = clnors != NULL;
+ const bool has_clnors = clnors != nullptr;
if (!clnors) {
- clnors = CustomData_add_layer(
- &result->ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, NULL, loops_num);
+ clnors = static_cast<short(*)[2]>(CustomData_add_layer(
+ &result->ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, nullptr, loops_num));
}
const MDeformVert *dvert;
int defgrp_index;
MOD_get_vgroup(ctx->object, mesh, wnmd->defgrp_name, &dvert, &defgrp_index);
- WeightedNormalData wn_data = {
- .verts_num = verts_num,
- .edges_num = edges_num,
- .loops_num = loops_num,
- .polys_num = polys_num,
+ WeightedNormalData wn_data{};
+ wn_data.verts_num = verts_num;
+ wn_data.edges_num = edges_num;
+ wn_data.loops_num = loops_num;
+ wn_data.polys_num = polys_num;
- .mvert = mvert,
- .vert_normals = BKE_mesh_vertex_normals_ensure(result),
- .medge = medge,
+ wn_data.mvert = mvert;
+ wn_data.vert_normals = BKE_mesh_vertex_normals_ensure(result);
+ wn_data.medge = medge;
- .mloop = mloop,
- .clnors = clnors,
- .has_clnors = has_clnors,
- .split_angle = split_angle,
+ wn_data.mloop = mloop;
+ wn_data.clnors = clnors;
+ wn_data.has_clnors = has_clnors;
+ wn_data.split_angle = split_angle;
- .mpoly = mpoly,
- .polynors = BKE_mesh_poly_normals_ensure(mesh),
- .poly_strength = CustomData_get_layer_named(
- &result->pdata, CD_PROP_INT32, MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID),
+ wn_data.mpoly = mpoly;
+ wn_data.polynors = BKE_mesh_poly_normals_ensure(mesh);
+ wn_data.poly_strength = static_cast<const int *>(CustomData_get_layer_named(
+ &result->pdata, CD_PROP_INT32, MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID));
- .dvert = dvert,
- .defgrp_index = defgrp_index,
- .use_invert_vgroup = (wnmd->flag & MOD_WEIGHTEDNORMAL_INVERT_VGROUP) != 0,
+ wn_data.dvert = dvert;
+ wn_data.defgrp_index = defgrp_index;
+ wn_data.use_invert_vgroup = (wnmd->flag & MOD_WEIGHTEDNORMAL_INVERT_VGROUP) != 0;
- .weight = weight,
- .mode = wnmd->mode,
- };
+ wn_data.weight = weight;
+ wn_data.mode = wnmd->mode;
switch (wnmd->mode) {
case MOD_WEIGHTEDNORMAL_MODE_FACE:
@@ -660,7 +676,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
MEM_SAFE_FREE(wn_data.mode_pair);
MEM_SAFE_FREE(wn_data.items_data);
- result->runtime.is_original_bmesh = false;
+ result->runtime->is_original_bmesh = false;
return result;
}
@@ -674,9 +690,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(wnmd, DNA_struct_default_get(WeightedNormalModifierData), modifier);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
WeightedNormalModifierData *wnmd = (WeightedNormalModifierData *)md;
@@ -691,12 +705,12 @@ static void requiredDataMask(Object *UNUSED(ob),
}
}
-static bool dependsOnNormals(ModifierData *UNUSED(md))
+static bool dependsOnNormals(ModifierData * /*md*/)
{
return true;
}
-static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *col;
uiLayout *layout = panel->layout;
@@ -706,16 +720,16 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropSep(layout, true);
- uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "mode", 0, nullptr, ICON_NONE);
uiItemR(layout, ptr, "weight", 0, IFACE_("Weight"), ICON_NONE);
uiItemR(layout, ptr, "thresh", 0, IFACE_("Threshold"), ICON_NONE);
col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "keep_sharp", 0, NULL, ICON_NONE);
- uiItemR(col, ptr, "use_face_influence", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "keep_sharp", 0, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "use_face_influence", 0, nullptr, ICON_NONE);
- modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
+ modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", nullptr);
modifier_panel_end(layout, ptr);
}
@@ -737,24 +751,24 @@ ModifierTypeInfo modifierType_WeightedNormal = {
/* copyData */ BKE_modifier_copydata_generic,
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
+ /* deformVerts */ nullptr,
+ /* deformMatrices */ nullptr,
+ /* deformVertsEM */ nullptr,
+ /* deformMatricesEM */ nullptr,
/* modifyMesh */ modifyMesh,
- /* modifyGeometrySet */ NULL,
+ /* modifyGeometrySet */ nullptr,
/* initData */ initData,
/* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
+ /* freeData */ nullptr,
+ /* isDisabled */ nullptr,
+ /* updateDepsgraph */ nullptr,
+ /* dependsOnTime */ nullptr,
/* dependsOnNormals */ dependsOnNormals,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* foreachIDLink */ nullptr,
+ /* foreachTexLink */ nullptr,
+ /* freeRuntimeData */ nullptr,
/* panelRegister */ panelRegister,
- /* blendWrite */ NULL,
- /* blendRead */ NULL,
+ /* blendWrite */ nullptr,
+ /* blendRead */ nullptr,
};
diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.h b/source/blender/modifiers/intern/MOD_weightvg_util.h
index 2d86518aaa0..f6ff03fae18 100644
--- a/source/blender/modifiers/intern/MOD_weightvg_util.h
+++ b/source/blender/modifiers/intern/MOD_weightvg_util.h
@@ -7,6 +7,10 @@
#pragma once
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct CurveMapping;
struct MDeformVert;
struct MDeformWeight;
@@ -101,3 +105,7 @@ void weightvg_update_vg(struct MDeformVert *dvert,
* Common vertex weight mask interface elements for the modifier panels.
*/
void weightvg_ui_common(const bContext *C, PointerRNA *ob_ptr, PointerRNA *ptr, uiLayout *layout);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.cc
index 4002718d06c..e4fbca633f7 100644
--- a/source/blender/modifiers/intern/MOD_weightvgedit.c
+++ b/source/blender/modifiers/intern/MOD_weightvgedit.cc
@@ -5,7 +5,7 @@
* \ingroup modifiers
*/
-#include <string.h>
+#include <cstring>
#include "BLI_utildefines.h"
@@ -81,9 +81,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla
twmd->cmap_curve = BKE_curvemapping_copy(wmd->cmap_curve);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
@@ -98,7 +96,7 @@ static void requiredDataMask(Object *UNUSED(ob),
/* No need to ask for CD_PREVIEW_MLOOPCOL... */
}
-static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *md)
+static bool dependsOnTime(Scene * /*scene*/, ModifierData *md)
{
WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
@@ -126,10 +124,10 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
bool need_transform_relation = false;
- if (wmd->mask_texture != NULL) {
+ if (wmd->mask_texture != nullptr) {
DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGEdit Modifier");
- if (wmd->mask_tex_map_obj != NULL && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
+ if (wmd->mask_tex_map_obj != nullptr && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
MOD_depsgraph_update_object_bone_relation(
ctx->node, wmd->mask_tex_map_obj, wmd->mask_tex_map_bone, "WeightVGEdit Modifier");
need_transform_relation = true;
@@ -144,9 +142,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
}
}
-static bool isDisabled(const struct Scene *UNUSED(scene),
- ModifierData *md,
- bool UNUSED(useRenderParams))
+static bool isDisabled(const Scene * /*scene*/, ModifierData *md, bool /*useRenderParams*/)
{
WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
/* If no vertex group, bypass. */
@@ -155,11 +151,11 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- BLI_assert(mesh != NULL);
+ BLI_assert(mesh != nullptr);
WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
- MDeformWeight **dw = NULL;
+ MDeformWeight **dw = nullptr;
float *org_w; /* Array original weights. */
float *new_w; /* Array new weights. */
int i;
@@ -190,7 +186,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT);
- /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
+ /* If no vertices were ever added to an object's vgroup, dvert might be nullptr. */
if (!has_mdef) {
/* If this modifier is not allowed to add vertices, just return. */
if (!do_add) {
@@ -206,9 +202,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
/* Get org weights, assuming 0.0 for vertices not in given vgroup. */
- org_w = MEM_malloc_arrayN(verts_num, sizeof(float), "WeightVGEdit Modifier, org_w");
- new_w = MEM_malloc_arrayN(verts_num, sizeof(float), "WeightVGEdit Modifier, new_w");
- dw = MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), "WeightVGEdit Modifier, dw");
+ org_w = static_cast<float *>(MEM_malloc_arrayN(verts_num, sizeof(float), __func__));
+ new_w = static_cast<float *>(MEM_malloc_arrayN(verts_num, sizeof(float), __func__));
+ dw = static_cast<MDeformWeight **>(
+ MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), __func__));
for (i = 0; i < verts_num; i++) {
dw[i] = BKE_defvert_find_index(&dvert[i], defgrp_index);
if (dw[i]) {
@@ -223,7 +220,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
const bool do_invert_mapping = (wmd->edit_flags & MOD_WVG_INVERT_FALLOFF) != 0;
const bool do_normalize = (wmd->edit_flags & MOD_WVG_EDIT_WEIGHTS_NORMALIZE) != 0;
if (do_invert_mapping || wmd->falloff_type != MOD_WVG_MAPPING_NONE) {
- RNG *rng = NULL;
+ RNG *rng = nullptr;
if (wmd->falloff_type == MOD_WVG_MAPPING_RANDOM) {
rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ctx->object->id.name + 2));
@@ -237,10 +234,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
/* Do masking. */
- struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
weightvg_do_mask(ctx,
verts_num,
- NULL,
+ nullptr,
org_w,
new_w,
ctx->object,
@@ -261,7 +258,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
defgrp_index,
dw,
verts_num,
- NULL,
+ nullptr,
org_w,
do_add,
wmd->add_threshold,
@@ -272,7 +269,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* If weight preview enabled... */
#if 0 /* XXX Currently done in mod stack :/ */
if (do_prev) {
- DM_update_weight_mcol(ob, dm, 0, org_w, 0, NULL);
+ DM_update_weight_mcol(ob, dm, 0, org_w, 0, nullptr);
}
#endif
@@ -281,13 +278,13 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
MEM_freeN(new_w);
MEM_freeN(dw);
- mesh->runtime.is_original_bmesh = false;
+ mesh->runtime->is_original_bmesh = false;
/* Return the vgroup-modified mesh. */
return mesh;
}
-static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *sub, *col, *row;
uiLayout *layout = panel->layout;
@@ -298,9 +295,9 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropSep(layout, true);
col = uiLayoutColumn(layout, true);
- uiItemPointerR(col, ptr, "vertex_group", &ob_ptr, "vertex_groups", NULL, ICON_NONE);
+ uiItemPointerR(col, ptr, "vertex_group", &ob_ptr, "vertex_groups", nullptr, ICON_NONE);
- uiItemR(layout, ptr, "default_weight", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "default_weight", UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
col = uiLayoutColumnWithHeading(layout, false, IFACE_("Group Add"));
row = uiLayoutRow(col, true);
@@ -324,12 +321,12 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(sub, ptr, "remove_threshold", UI_ITEM_R_SLIDER, IFACE_("Threshold"), ICON_NONE);
uiItemDecoratorR(row, ptr, "remove_threshold", 0);
- uiItemR(layout, ptr, "normalize", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "normalize", 0, nullptr, ICON_NONE);
modifier_panel_end(layout, ptr);
}
-static void falloff_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void falloff_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *row, *sub;
uiLayout *layout = panel->layout;
@@ -364,12 +361,12 @@ static void panelRegister(ARegionType *region_type)
PanelType *panel_type = modifier_panel_register(
region_type, eModifierType_WeightVGEdit, panel_draw);
modifier_subpanel_register(
- region_type, "falloff", "Falloff", NULL, falloff_panel_draw, panel_type);
+ region_type, "falloff", "Falloff", nullptr, falloff_panel_draw, panel_type);
modifier_subpanel_register(
- region_type, "influence", "Influence", NULL, influence_panel_draw, panel_type);
+ region_type, "influence", "Influence", nullptr, influence_panel_draw, panel_type);
}
-static void blendWrite(BlendWriter *writer, const ID *UNUSED(id_owner), const ModifierData *md)
+static void blendWrite(BlendWriter *writer, const ID * /*id_owner*/, const ModifierData *md)
{
const WeightVGEditModifierData *wmd = (const WeightVGEditModifierData *)md;
@@ -402,12 +399,12 @@ ModifierTypeInfo modifierType_WeightVGEdit = {
/* copyData */ copyData,
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
+ /* deformVerts */ nullptr,
+ /* deformMatrices */ nullptr,
+ /* deformVertsEM */ nullptr,
+ /* deformMatricesEM */ nullptr,
/* modifyMesh */ modifyMesh,
- /* modifyGeometrySet */ NULL,
+ /* modifyGeometrySet */ nullptr,
/* initData */ initData,
/* requiredDataMask */ requiredDataMask,
@@ -415,10 +412,10 @@ ModifierTypeInfo modifierType_WeightVGEdit = {
/* isDisabled */ isDisabled,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
+ /* dependsOnNormals */ nullptr,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ foreachTexLink,
- /* freeRuntimeData */ NULL,
+ /* freeRuntimeData */ nullptr,
/* panelRegister */ panelRegister,
/* blendWrite */ blendWrite,
/* blendRead */ blendRead,
diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.cc
index 1481ffad82c..d860e93d535 100644
--- a/source/blender/modifiers/intern/MOD_weightvgmix.c
+++ b/source/blender/modifiers/intern/MOD_weightvgmix.cc
@@ -129,9 +129,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(wmd, DNA_struct_default_get(WeightVGMixModifierData), modifier);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
@@ -146,7 +144,7 @@ static void requiredDataMask(Object *UNUSED(ob),
/* No need to ask for CD_PREVIEW_MLOOPCOL... */
}
-static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *md)
+static bool dependsOnTime(Scene * /*scene*/, ModifierData *md)
{
WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
@@ -174,10 +172,10 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
bool need_transform_relation = false;
- if (wmd->mask_texture != NULL) {
+ if (wmd->mask_texture != nullptr) {
DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGMix Modifier");
- if (wmd->mask_tex_map_obj != NULL && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
+ if (wmd->mask_tex_map_obj != nullptr && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
MOD_depsgraph_update_object_bone_relation(
ctx->node, wmd->mask_tex_map_obj, wmd->mask_tex_map_bone, "WeightVGMix Modifier");
need_transform_relation = true;
@@ -192,9 +190,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
}
}
-static bool isDisabled(const struct Scene *UNUSED(scene),
- ModifierData *md,
- bool UNUSED(useRenderParams))
+static bool isDisabled(const Scene * /*scene*/, ModifierData *md, bool /*useRenderParams*/)
{
WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
/* If no vertex group, bypass. */
@@ -203,14 +199,14 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- BLI_assert(mesh != NULL);
+ BLI_assert(mesh != nullptr);
WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
MDeformWeight **dw1, **tdw1, **dw2, **tdw2;
float *org_w;
float *new_w;
- int *tidx, *indices = NULL;
+ int *tidx, *indices = nullptr;
int index_num = 0;
int i;
const bool invert_vgroup_mask = (wmd->flag & MOD_WVG_MIX_INVERT_VGROUP_MASK) != 0;
@@ -255,7 +251,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT);
- /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
+ /* If no vertices were ever added to an object's vgroup, dvert might be nullptr. */
if (!has_mdef) {
/* If not affecting all vertices, just return. */
if (wmd->mix_set != MOD_WVG_SET_ALL) {
@@ -271,9 +267,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
/* Find out which vertices to work on. */
- tidx = MEM_malloc_arrayN(verts_num, sizeof(int), "WeightVGMix Modifier, tidx");
- tdw1 = MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw1");
- tdw2 = MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw2");
+ tidx = static_cast<int *>(MEM_malloc_arrayN(verts_num, sizeof(int), __func__));
+ tdw1 = static_cast<MDeformWeight **>(
+ MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), __func__));
+ tdw2 = static_cast<MDeformWeight **>(
+ MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), __func__));
switch (wmd->mix_set) {
case MOD_WVG_SET_A:
/* All vertices in first vgroup. */
@@ -283,7 +281,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
tdw1[index_num] = dw;
tdw2[index_num] = (defgrp_index_other >= 0) ?
BKE_defvert_find_index(&dvert[i], defgrp_index_other) :
- NULL;
+ nullptr;
tidx[index_num++] = i;
}
}
@@ -293,7 +291,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
for (i = 0; i < verts_num; i++) {
MDeformWeight *dw = (defgrp_index_other >= 0) ?
BKE_defvert_find_index(&dvert[i], defgrp_index_other) :
- NULL;
+ nullptr;
if (dw) {
tdw1[index_num] = BKE_defvert_find_index(&dvert[i], defgrp_index);
tdw2[index_num] = dw;
@@ -307,7 +305,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
MDeformWeight *adw = BKE_defvert_find_index(&dvert[i], defgrp_index);
MDeformWeight *bdw = (defgrp_index_other >= 0) ?
BKE_defvert_find_index(&dvert[i], defgrp_index_other) :
- NULL;
+ nullptr;
if (adw || bdw) {
tdw1[index_num] = adw;
tdw2[index_num] = bdw;
@@ -321,7 +319,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
MDeformWeight *adw = BKE_defvert_find_index(&dvert[i], defgrp_index);
MDeformWeight *bdw = (defgrp_index_other >= 0) ?
BKE_defvert_find_index(&dvert[i], defgrp_index_other) :
- NULL;
+ nullptr;
if (adw && bdw) {
tdw1[index_num] = adw;
tdw2[index_num] = bdw;
@@ -336,7 +334,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
tdw1[i] = BKE_defvert_find_index(&dvert[i], defgrp_index);
tdw2[i] = (defgrp_index_other >= 0) ?
BKE_defvert_find_index(&dvert[i], defgrp_index_other) :
- NULL;
+ nullptr;
}
index_num = -1;
break;
@@ -349,12 +347,14 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
return mesh;
}
if (index_num != -1) {
- indices = MEM_malloc_arrayN(index_num, sizeof(int), "WeightVGMix Modifier, indices");
+ indices = static_cast<int *>(MEM_malloc_arrayN(index_num, sizeof(int), __func__));
memcpy(indices, tidx, sizeof(int) * index_num);
- dw1 = MEM_malloc_arrayN(index_num, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw1");
+ dw1 = static_cast<MDeformWeight **>(
+ MEM_malloc_arrayN(index_num, sizeof(MDeformWeight *), __func__));
memcpy(dw1, tdw1, sizeof(MDeformWeight *) * index_num);
MEM_freeN(tdw1);
- dw2 = MEM_malloc_arrayN(index_num, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw2");
+ dw2 = static_cast<MDeformWeight **>(
+ MEM_malloc_arrayN(index_num, sizeof(MDeformWeight *), __func__));
memcpy(dw2, tdw2, sizeof(MDeformWeight *) * index_num);
MEM_freeN(tdw2);
}
@@ -367,8 +367,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
MEM_freeN(tidx);
- org_w = MEM_malloc_arrayN(index_num, sizeof(float), "WeightVGMix Modifier, org_w");
- new_w = MEM_malloc_arrayN(index_num, sizeof(float), "WeightVGMix Modifier, new_w");
+ org_w = static_cast<float *>(MEM_malloc_arrayN(index_num, sizeof(float), __func__));
+ new_w = static_cast<float *>(MEM_malloc_arrayN(index_num, sizeof(float), __func__));
/* Mix weights. */
for (i = 0; i < index_num; i++) {
@@ -390,7 +390,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
/* Do masking. */
- struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
weightvg_do_mask(ctx,
index_num,
indices,
@@ -438,13 +438,13 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
MEM_freeN(dw2);
MEM_SAFE_FREE(indices);
- mesh->runtime.is_original_bmesh = false;
+ mesh->runtime->is_original_bmesh = false;
/* Return the vgroup-modified mesh. */
return mesh;
}
-static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
@@ -453,20 +453,20 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropSep(layout, true);
- modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group_a", "invert_vertex_group_a", NULL);
+ modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group_a", "invert_vertex_group_a", nullptr);
modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group_b", "invert_vertex_group_b", IFACE_("B"));
uiItemS(layout);
- uiItemR(layout, ptr, "default_weight_a", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "default_weight_a", 0, nullptr, ICON_NONE);
uiItemR(layout, ptr, "default_weight_b", 0, IFACE_("B"), ICON_NONE);
uiItemS(layout);
- uiItemR(layout, ptr, "mix_set", 0, NULL, ICON_NONE);
- uiItemR(layout, ptr, "mix_mode", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "mix_set", 0, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "mix_mode", 0, nullptr, ICON_NONE);
- uiItemR(layout, ptr, "normalize", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "normalize", 0, nullptr, ICON_NONE);
modifier_panel_end(layout, ptr);
}
@@ -486,7 +486,7 @@ static void panelRegister(ARegionType *region_type)
PanelType *panel_type = modifier_panel_register(
region_type, eModifierType_WeightVGMix, panel_draw);
modifier_subpanel_register(
- region_type, "influence", "Influence", NULL, influence_panel_draw, panel_type);
+ region_type, "influence", "Influence", nullptr, influence_panel_draw, panel_type);
}
ModifierTypeInfo modifierType_WeightVGMix = {
@@ -501,24 +501,24 @@ ModifierTypeInfo modifierType_WeightVGMix = {
/* copyData */ BKE_modifier_copydata_generic,
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
+ /* deformVerts */ nullptr,
+ /* deformMatrices */ nullptr,
+ /* deformVertsEM */ nullptr,
+ /* deformMatricesEM */ nullptr,
/* modifyMesh */ modifyMesh,
- /* modifyGeometrySet */ NULL,
+ /* modifyGeometrySet */ nullptr,
/* initData */ initData,
/* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
+ /* freeData */ nullptr,
/* isDisabled */ isDisabled,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
+ /* dependsOnNormals */ nullptr,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ foreachTexLink,
- /* freeRuntimeData */ NULL,
+ /* freeRuntimeData */ nullptr,
/* panelRegister */ panelRegister,
- /* blendWrite */ NULL,
- /* blendRead */ NULL,
+ /* blendWrite */ nullptr,
+ /* blendRead */ nullptr,
};
diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.cc
index 80c49745003..e4e03a2cbc9 100644
--- a/source/blender/modifiers/intern/MOD_weightvgproximity.c
+++ b/source/blender/modifiers/intern/MOD_weightvgproximity.cc
@@ -69,7 +69,7 @@
/* Util macro. */
#define OUT_OF_MEMORY() ((void)printf("WeightVGProximity: Out of memory.\n"))
-typedef struct Vert2GeomData {
+struct Vert2GeomData {
/* Read-only data */
float (*v_cos)[3];
@@ -79,17 +79,17 @@ typedef struct Vert2GeomData {
/* Write data, but not needing locking (two different threads will never write same index). */
float *dist[3];
-} Vert2GeomData;
+};
/**
* Data which is localized to each computed chunk
* (i.e. thread-safe, and with continuous subset of index range).
*/
-typedef struct Vert2GeomDataChunk {
+struct Vert2GeomDataChunk {
/* Read-only data */
float last_hit_co[3][3];
bool is_init[3];
-} Vert2GeomDataChunk;
+};
/**
* Callback used by BLI_task 'for loop' helper.
@@ -98,8 +98,8 @@ static void vert2geom_task_cb_ex(void *__restrict userdata,
const int iter,
const TaskParallelTLS *__restrict tls)
{
- Vert2GeomData *data = userdata;
- Vert2GeomDataChunk *data_chunk = tls->userdata_chunk;
+ Vert2GeomData *data = static_cast<Vert2GeomData *>(userdata);
+ Vert2GeomDataChunk *data_chunk = static_cast<Vert2GeomDataChunk *>(tls->userdata_chunk);
float tmp_co[3];
int i;
@@ -151,17 +151,17 @@ static void get_vert2geom_distance(int verts_num,
Mesh *target,
const SpaceTransform *loc2trgt)
{
- Vert2GeomData data = {0};
+ Vert2GeomData data{};
Vert2GeomDataChunk data_chunk = {{{0}}};
- BVHTreeFromMesh treeData_v = {NULL};
- BVHTreeFromMesh treeData_e = {NULL};
- BVHTreeFromMesh treeData_f = {NULL};
+ BVHTreeFromMesh treeData_v = {nullptr};
+ BVHTreeFromMesh treeData_e = {nullptr};
+ BVHTreeFromMesh treeData_f = {nullptr};
if (dist_v) {
/* Create a BVH-tree of the given target's verts. */
BKE_bvhtree_from_mesh_get(&treeData_v, target, BVHTREE_FROM_VERTS, 2);
- if (treeData_v.tree == NULL) {
+ if (treeData_v.tree == nullptr) {
OUT_OF_MEMORY();
return;
}
@@ -169,7 +169,7 @@ static void get_vert2geom_distance(int verts_num,
if (dist_e) {
/* Create a BVH-tree of the given target's edges. */
BKE_bvhtree_from_mesh_get(&treeData_e, target, BVHTREE_FROM_EDGES, 2);
- if (treeData_e.tree == NULL) {
+ if (treeData_e.tree == nullptr) {
OUT_OF_MEMORY();
return;
}
@@ -177,7 +177,7 @@ static void get_vert2geom_distance(int verts_num,
if (dist_f) {
/* Create a BVH-tree of the given target's faces. */
BKE_bvhtree_from_mesh_get(&treeData_f, target, BVHTREE_FROM_LOOPTRI, 2);
- if (treeData_f.tree == NULL) {
+ if (treeData_f.tree == nullptr) {
OUT_OF_MEMORY();
return;
}
@@ -223,9 +223,9 @@ static void get_vert2ob_distance(
while (i-- > 0) {
/* Get world-coordinates of the vertex (constraints and anim included). */
- mul_v3_m4v3(v_wco, ob->obmat, v_cos[i]);
+ mul_v3_m4v3(v_wco, ob->object_to_world, v_cos[i]);
/* Return distance between both coordinates. */
- dist[i] = len_v3v3(v_wco, obr->obmat[3]);
+ dist[i] = len_v3v3(v_wco, obr->object_to_world[3]);
}
}
@@ -235,7 +235,7 @@ static void get_vert2ob_distance(
*/
static float get_ob2ob_distance(const Object *ob, const Object *obr)
{
- return len_v3v3(ob->obmat[3], obr->obmat[3]);
+ return len_v3v3(ob->object_to_world[3], obr->object_to_world[3]);
}
/**
@@ -285,7 +285,7 @@ static void do_map(Object *ob,
}
if (do_invert_mapping || mode != MOD_WVG_MAPPING_NONE) {
- RNG *rng = NULL;
+ RNG *rng = nullptr;
if (mode == MOD_WVG_MAPPING_RANDOM) {
rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name + 2));
@@ -330,9 +330,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla
twmd->cmap_curve = BKE_curvemapping_copy(wmd->cmap_curve);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
@@ -347,14 +345,14 @@ static void requiredDataMask(Object *UNUSED(ob),
/* No need to ask for CD_PREVIEW_MLOOPCOL... */
}
-static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *md)
+static bool dependsOnTime(Scene * /*scene*/, ModifierData *md)
{
WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
if (wmd->mask_texture) {
return BKE_texture_dependsOnTime(wmd->mask_texture);
}
- return 0;
+ return false;
}
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
@@ -376,10 +374,10 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
bool need_transform_relation = false;
- if (wmd->proximity_ob_target != NULL) {
+ if (wmd->proximity_ob_target != nullptr) {
DEG_add_object_relation(
ctx->node, wmd->proximity_ob_target, DEG_OB_COMP_TRANSFORM, "WeightVGProximity Modifier");
- if (wmd->proximity_ob_target->data != NULL &&
+ if (wmd->proximity_ob_target->data != nullptr &&
wmd->proximity_mode == MOD_WVG_PROXIMITY_GEOMETRY) {
DEG_add_object_relation(
ctx->node, wmd->proximity_ob_target, DEG_OB_COMP_GEOMETRY, "WeightVGProximity Modifier");
@@ -387,10 +385,10 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
need_transform_relation = true;
}
- if (wmd->mask_texture != NULL) {
+ if (wmd->mask_texture != nullptr) {
DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGProximity Modifier");
- if (wmd->mask_tex_map_obj != NULL && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
+ if (wmd->mask_tex_map_obj != nullptr && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
MOD_depsgraph_update_object_bone_relation(
ctx->node, wmd->mask_tex_map_obj, wmd->mask_tex_map_bone, "WeightVGProximity Modifier");
need_transform_relation = true;
@@ -405,9 +403,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
}
}
-static bool isDisabled(const struct Scene *UNUSED(scene),
- ModifierData *md,
- bool UNUSED(useRenderParams))
+static bool isDisabled(const Scene * /*scene*/, ModifierData *md, bool /*useRenderParams*/)
{
WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
/* If no vertex group, bypass. */
@@ -415,23 +411,23 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
return true;
}
/* If no target object, bypass. */
- return (wmd->proximity_ob_target == NULL);
+ return (wmd->proximity_ob_target == nullptr);
}
static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- BLI_assert(mesh != NULL);
+ BLI_assert(mesh != nullptr);
WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
MDeformWeight **dw, **tdw;
- float(*v_cos)[3] = NULL; /* The vertices coordinates. */
+ float(*v_cos)[3] = nullptr; /* The vertices coordinates. */
Object *ob = ctx->object;
- Object *obr = NULL; /* Our target object. */
+ Object *obr = nullptr; /* Our target object. */
int defgrp_index;
- float *tw = NULL;
- float *org_w = NULL;
- float *new_w = NULL;
- int *tidx, *indices = NULL;
+ float *tw = nullptr;
+ float *org_w = nullptr;
+ float *new_w = nullptr;
+ int *tidx, *indices = nullptr;
int index_num = 0;
int i;
const bool invert_vgroup_mask = (wmd->proximity_flags & MOD_WVG_PROXIMITY_INVERT_VGROUP_MASK) !=
@@ -458,7 +454,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Get our target object. */
obr = wmd->proximity_ob_target;
- if (obr == NULL) {
+ if (obr == nullptr) {
return mesh;
}
@@ -468,7 +464,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
return mesh;
}
const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT);
- /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
+ /* If no vertices were ever added to an object's vgroup, dvert might be nullptr. */
/* As this modifier never add vertices to vgroup, just return. */
if (!has_mdef) {
return mesh;
@@ -481,9 +477,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
/* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight. */
- tidx = MEM_malloc_arrayN(verts_num, sizeof(int), "WeightVGProximity Modifier, tidx");
- tw = MEM_malloc_arrayN(verts_num, sizeof(float), "WeightVGProximity Modifier, tw");
- tdw = MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), "WeightVGProximity Modifier, tdw");
+ tidx = static_cast<int *>(MEM_malloc_arrayN(verts_num, sizeof(int), __func__));
+ tw = static_cast<float *>(MEM_malloc_arrayN(verts_num, sizeof(float), __func__));
+ tdw = static_cast<MDeformWeight **>(
+ MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), __func__));
for (i = 0; i < verts_num; i++) {
MDeformWeight *_dw = BKE_defvert_find_index(&dvert[i], defgrp_index);
if (_dw) {
@@ -500,11 +497,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
return mesh;
}
if (index_num != verts_num) {
- indices = MEM_malloc_arrayN(index_num, sizeof(int), "WeightVGProximity Modifier, indices");
+ indices = static_cast<int *>(MEM_malloc_arrayN(index_num, sizeof(int), __func__));
memcpy(indices, tidx, sizeof(int) * index_num);
- org_w = MEM_malloc_arrayN(index_num, sizeof(float), "WeightVGProximity Modifier, org_w");
+ org_w = static_cast<float *>(MEM_malloc_arrayN(index_num, sizeof(float), __func__));
memcpy(org_w, tw, sizeof(float) * index_num);
- dw = MEM_malloc_arrayN(index_num, sizeof(MDeformWeight *), "WeightVGProximity Modifier, dw");
+ dw = static_cast<MDeformWeight **>(
+ MEM_malloc_arrayN(index_num, sizeof(MDeformWeight *), __func__));
memcpy(dw, tdw, sizeof(MDeformWeight *) * index_num);
MEM_freeN(tw);
MEM_freeN(tdw);
@@ -513,20 +511,20 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
org_w = tw;
dw = tdw;
}
- new_w = MEM_malloc_arrayN(index_num, sizeof(float), "WeightVGProximity Modifier, new_w");
+ new_w = static_cast<float *>(MEM_malloc_arrayN(index_num, sizeof(float), __func__));
MEM_freeN(tidx);
/* Get our vertex coordinates. */
if (index_num != verts_num) {
- float(*tv_cos)[3] = BKE_mesh_vert_coords_alloc(mesh, NULL);
- v_cos = MEM_malloc_arrayN(index_num, sizeof(float[3]), "WeightVGProximity Modifier, v_cos");
+ float(*tv_cos)[3] = BKE_mesh_vert_coords_alloc(mesh, nullptr);
+ v_cos = static_cast<float(*)[3]>(MEM_malloc_arrayN(index_num, sizeof(float[3]), __func__));
for (i = 0; i < index_num; i++) {
copy_v3_v3(v_cos[i], tv_cos[indices[i]]);
}
MEM_freeN(tv_cos);
}
else {
- v_cos = BKE_mesh_vert_coords_alloc(mesh, NULL);
+ v_cos = BKE_mesh_vert_coords_alloc(mesh, nullptr);
}
/* Compute wanted distances. */
@@ -545,19 +543,22 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
Mesh *target_mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(obr);
/* We must check that we do have a valid target_mesh! */
- if (target_mesh != NULL) {
+ if (target_mesh != nullptr) {
/* TODO: edit-mode versions of the BVH lookup functions are available so it could be
* avoided. */
BKE_mesh_wrapper_ensure_mdata(target_mesh);
SpaceTransform loc2trgt;
- float *dists_v = use_trgt_verts ? MEM_malloc_arrayN(index_num, sizeof(float), "dists_v") :
- NULL;
- float *dists_e = use_trgt_edges ? MEM_malloc_arrayN(index_num, sizeof(float), "dists_e") :
- NULL;
- float *dists_f = use_trgt_faces ? MEM_malloc_arrayN(index_num, sizeof(float), "dists_f") :
- NULL;
+ float *dists_v = use_trgt_verts ? static_cast<float *>(MEM_malloc_arrayN(
+ index_num, sizeof(float), __func__)) :
+ nullptr;
+ float *dists_e = use_trgt_edges ? static_cast<float *>(MEM_malloc_arrayN(
+ index_num, sizeof(float), __func__)) :
+ nullptr;
+ float *dists_f = use_trgt_faces ? static_cast<float *>(MEM_malloc_arrayN(
+ index_num, sizeof(float), __func__)) :
+ nullptr;
BLI_SPACE_TRANSFORM_SETUP(&loc2trgt, ob, obr);
get_vert2geom_distance(
@@ -597,7 +598,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
wmd->cmap_curve);
/* Do masking. */
- struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
weightvg_do_mask(ctx,
index_num,
indices,
@@ -638,13 +639,13 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
TIMEIT_END(perf);
#endif
- mesh->runtime.is_original_bmesh = false;
+ mesh->runtime->is_original_bmesh = false;
/* Return the vgroup-modified mesh. */
return mesh;
}
-static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *col;
uiLayout *layout = panel->layout;
@@ -654,25 +655,25 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropSep(layout, true);
- uiItemPointerR(layout, ptr, "vertex_group", &ob_ptr, "vertex_groups", NULL, ICON_NONE);
+ uiItemPointerR(layout, ptr, "vertex_group", &ob_ptr, "vertex_groups", nullptr, ICON_NONE);
- uiItemR(layout, ptr, "target", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "target", 0, nullptr, ICON_NONE);
uiItemS(layout);
- uiItemR(layout, ptr, "proximity_mode", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "proximity_mode", 0, nullptr, ICON_NONE);
if (RNA_enum_get(ptr, "proximity_mode") == MOD_WVG_PROXIMITY_GEOMETRY) {
uiItemR(layout, ptr, "proximity_geometry", UI_ITEM_R_EXPAND, IFACE_("Geometry"), ICON_NONE);
}
col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "min_dist", 0, NULL, ICON_NONE);
- uiItemR(col, ptr, "max_dist", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "min_dist", 0, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "max_dist", 0, nullptr, ICON_NONE);
- uiItemR(layout, ptr, "normalize", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "normalize", 0, nullptr, ICON_NONE);
}
-static void falloff_panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void falloff_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *row, *sub;
uiLayout *layout = panel->layout;
@@ -708,12 +709,12 @@ static void panelRegister(ARegionType *region_type)
PanelType *panel_type = modifier_panel_register(
region_type, eModifierType_WeightVGProximity, panel_draw);
modifier_subpanel_register(
- region_type, "falloff", "Falloff", NULL, falloff_panel_draw, panel_type);
+ region_type, "falloff", "Falloff", nullptr, falloff_panel_draw, panel_type);
modifier_subpanel_register(
- region_type, "influence", "Influence", NULL, influence_panel_draw, panel_type);
+ region_type, "influence", "Influence", nullptr, influence_panel_draw, panel_type);
}
-static void blendWrite(BlendWriter *writer, const ID *UNUSED(id_owner), const ModifierData *md)
+static void blendWrite(BlendWriter *writer, const ID * /*id_owner*/, const ModifierData *md)
{
const WeightVGProximityModifierData *wmd = (const WeightVGProximityModifierData *)md;
@@ -746,12 +747,12 @@ ModifierTypeInfo modifierType_WeightVGProximity = {
/* copyData */ copyData,
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
+ /* deformVerts */ nullptr,
+ /* deformMatrices */ nullptr,
+ /* deformVertsEM */ nullptr,
+ /* deformMatricesEM */ nullptr,
/* modifyMesh */ modifyMesh,
- /* modifyGeometrySet */ NULL,
+ /* modifyGeometrySet */ nullptr,
/* initData */ initData,
/* requiredDataMask */ requiredDataMask,
@@ -759,10 +760,10 @@ ModifierTypeInfo modifierType_WeightVGProximity = {
/* isDisabled */ isDisabled,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
+ /* dependsOnNormals */ nullptr,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ foreachTexLink,
- /* freeRuntimeData */ NULL,
+ /* freeRuntimeData */ nullptr,
/* panelRegister */ panelRegister,
/* blendWrite */ blendWrite,
/* blendRead */ blendRead,
diff --git a/source/blender/modifiers/intern/MOD_weld.cc b/source/blender/modifiers/intern/MOD_weld.cc
index 19b0bf62fea..bbd440f377e 100644
--- a/source/blender/modifiers/intern/MOD_weld.cc
+++ b/source/blender/modifiers/intern/MOD_weld.cc
@@ -127,7 +127,7 @@ static std::optional<Mesh *> calculate_weld(const Mesh &mesh, const WeldModifier
return nullptr;
}
-static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
+static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext * /*ctx*/, Mesh *mesh)
{
const WeldModifierData &wmd = reinterpret_cast<WeldModifierData &>(*md);
@@ -147,9 +147,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(wmd, DNA_struct_default_get(WeldModifierData), modifier);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
WeldModifierData *wmd = (WeldModifierData *)md;
@@ -159,7 +157,7 @@ static void requiredDataMask(Object *UNUSED(ob),
}
}
-static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+static void panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
diff --git a/source/blender/modifiers/intern/MOD_wireframe.c b/source/blender/modifiers/intern/MOD_wireframe.c
index 5799da5d156..85696bed162 100644
--- a/source/blender/modifiers/intern/MOD_wireframe.c
+++ b/source/blender/modifiers/intern/MOD_wireframe.c
@@ -41,9 +41,7 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(wmd, DNA_struct_default_get(WireframeModifierData), modifier);
}
-static void requiredDataMask(Object *UNUSED(ob),
- ModifierData *md,
- CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
{
WireframeModifierData *wmd = (WireframeModifierData *)md;
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index e042458ca19..2398aefc67a 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -50,7 +50,7 @@ set(SRC
intern/node_multi_function.cc
intern/node_socket.cc
intern/node_socket_declarations.cc
- intern/node_util.c
+ intern/node_util.cc
intern/socket_search_link.cc
NOD_common.h
@@ -60,6 +60,7 @@ set(SRC
NOD_geometry.h
NOD_geometry_exec.hh
NOD_geometry_nodes_lazy_function.hh
+ NOD_geometry_nodes_log.hh
NOD_math_functions.hh
NOD_multi_function.hh
NOD_node_declaration.hh
@@ -102,20 +103,6 @@ if(WITH_BULLET)
add_definitions(-DWITH_BULLET)
endif()
-if(WITH_PYTHON)
- list(APPEND INC
- ../python
- )
- list(APPEND INC_SYS
- ${PYTHON_INCLUDE_DIRS}
- )
- list(APPEND LIB
- ${PYTHON_LINKFLAGS}
- ${PYTHON_LIBRARIES}
- )
- add_definitions(-DWITH_PYTHON)
-endif()
-
if(WITH_TBB)
list(APPEND INC_SYS
${TBB_INCLUDE_DIRS}
diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h
index e16cd7a253f..3b886bd55c6 100644
--- a/source/blender/nodes/NOD_geometry.h
+++ b/source/blender/nodes/NOD_geometry.h
@@ -46,9 +46,12 @@ void register_node_type_geo_curve_spline_type(void);
void register_node_type_geo_curve_subdivide(void);
void register_node_type_geo_curve_to_mesh(void);
void register_node_type_geo_curve_to_points(void);
+void register_node_type_geo_curve_topology_curve_of_point(void);
+void register_node_type_geo_curve_topology_points_of_curve(void);
void register_node_type_geo_curve_trim(void);
void register_node_type_geo_deform_curves_on_surface(void);
void register_node_type_geo_delete_geometry(void);
+void register_node_type_geo_distribute_points_in_volume(void);
void register_node_type_geo_distribute_points_on_faces(void);
void register_node_type_geo_dual_mesh(void);
void register_node_type_geo_duplicate_elements(void);
@@ -95,6 +98,7 @@ void register_node_type_geo_join_geometry(void);
void register_node_type_geo_material_replace(void);
void register_node_type_geo_material_selection(void);
void register_node_type_geo_merge_by_distance(void);
+void register_node_type_geo_mesh_face_set_boundaries(void);
void register_node_type_geo_mesh_primitive_circle(void);
void register_node_type_geo_mesh_primitive_cone(void);
void register_node_type_geo_mesh_primitive_cube(void);
@@ -107,7 +111,15 @@ void register_node_type_geo_mesh_subdivide(void);
void register_node_type_geo_mesh_to_curve(void);
void register_node_type_geo_mesh_to_points(void);
void register_node_type_geo_mesh_to_volume(void);
+void register_node_type_geo_mesh_topology_corners_of_face(void);
+void register_node_type_geo_mesh_topology_corners_of_vertex(void);
+void register_node_type_geo_mesh_topology_edges_of_corner(void);
+void register_node_type_geo_mesh_topology_edges_of_vertex(void);
+void register_node_type_geo_mesh_topology_face_of_corner(void);
+void register_node_type_geo_mesh_topology_offset_corner_in_face(void);
+void register_node_type_geo_mesh_topology_vertex_of_corner(void);
void register_node_type_geo_object_info(void);
+void register_node_type_geo_offset_point_in_curve(void);
void register_node_type_geo_points_to_vertices(void);
void register_node_type_geo_points_to_volume(void);
void register_node_type_geo_points(void);
@@ -116,12 +128,18 @@ void register_node_type_geo_raycast(void);
void register_node_type_geo_realize_instances(void);
void register_node_type_geo_remove_attribute(void);
void register_node_type_geo_rotate_instances(void);
+void register_node_type_geo_sample_index(void);
+void register_node_type_geo_sample_nearest_surface(void);
+void register_node_type_geo_sample_nearest(void);
+void register_node_type_geo_sample_uv_surface(void);
void register_node_type_geo_scale_elements(void);
void register_node_type_geo_scale_instances(void);
void register_node_type_geo_select_by_handle_type(void);
void register_node_type_geo_separate_components(void);
void register_node_type_geo_separate_geometry(void);
+void register_node_type_geo_self_object(void);
void register_node_type_geo_set_curve_handles(void);
+void register_node_type_geo_set_curve_normal(void);
void register_node_type_geo_set_curve_radius(void);
void register_node_type_geo_set_curve_tilt(void);
void register_node_type_geo_set_id(void);
@@ -137,7 +155,6 @@ void register_node_type_geo_string_join(void);
void register_node_type_geo_string_to_curves(void);
void register_node_type_geo_subdivision_surface(void);
void register_node_type_geo_switch(void);
-void register_node_type_geo_transfer_attribute(void);
void register_node_type_geo_transform(void);
void register_node_type_geo_translate_instances(void);
void register_node_type_geo_triangulate(void);
diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh
index 16669f7cfce..73e82f741ab 100644
--- a/source/blender/nodes/NOD_geometry_exec.hh
+++ b/source/blender/nodes/NOD_geometry_exec.hh
@@ -237,13 +237,13 @@ class GeoNodeExecParams {
* Add an error message displayed at the top of the node when displaying the node tree,
* and potentially elsewhere in Blender.
*/
- void error_message_add(const NodeWarningType type, std::string message) const;
+ void error_message_add(const NodeWarningType type, StringRef message) const;
std::string attribute_producer_name() const;
void set_default_remaining_outputs();
- void used_named_attribute(std::string attribute_name, NamedAttributeUsage usage);
+ void used_named_attribute(StringRef attribute_name, NamedAttributeUsage usage);
private:
/* Utilities for detecting common errors at when using this class. */
diff --git a/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh b/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh
index 3137dc41857..240a0115f68 100644
--- a/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh
+++ b/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh
@@ -124,6 +124,11 @@ struct GeometryNodesLazyFunctionGraphInfo {
* Mappings between the lazy-function graph and the #bNodeTree.
*/
GeometryNodeLazyFunctionGraphMapping mapping;
+ /**
+ * Approximate number of nodes in the graph if all sub-graphs were inlined.
+ * This can be used as a simple heuristic for the complexity of the node group.
+ */
+ int num_inline_nodes_approximate = 0;
GeometryNodesLazyFunctionGraphInfo();
~GeometryNodesLazyFunctionGraphInfo();
@@ -148,6 +153,9 @@ class GeometryNodesLazyFunctionLogger : public fn::lazy_function::GraphExecutor:
void dump_when_input_is_set_twice(const lf::InputSocket &target_socket,
const lf::OutputSocket &from_socket,
const lf::Context &context) const override;
+ void log_before_node_execute(const lf::FunctionNode &node,
+ const lf::Params &params,
+ const lf::Context &context) const override;
};
/**
@@ -157,12 +165,7 @@ class GeometryNodesLazyFunctionLogger : public fn::lazy_function::GraphExecutor:
*/
class GeometryNodesLazyFunctionSideEffectProvider
: public fn::lazy_function::GraphExecutor::SideEffectProvider {
- private:
- const GeometryNodesLazyFunctionGraphInfo &lf_graph_info_;
-
public:
- GeometryNodesLazyFunctionSideEffectProvider(
- const GeometryNodesLazyFunctionGraphInfo &lf_graph_info);
Vector<const lf::FunctionNode *> get_nodes_with_side_effects(
const lf::Context &context) const override;
};
diff --git a/source/blender/nodes/NOD_geometry_nodes_log.hh b/source/blender/nodes/NOD_geometry_nodes_log.hh
index dd4868b6ba0..5a2203a76b7 100644
--- a/source/blender/nodes/NOD_geometry_nodes_log.hh
+++ b/source/blender/nodes/NOD_geometry_nodes_log.hh
@@ -33,6 +33,7 @@
#include "BKE_attribute.h"
#include "BKE_geometry_set.hh"
+#include "BKE_viewer_path.h"
#include "FN_field.hh"
@@ -156,7 +157,6 @@ class GeometryInfoLog : public ValueLog {
class ViewerNodeLog {
public:
GeometrySet geometry;
- GField field;
};
using Clock = std::chrono::steady_clock;
@@ -175,31 +175,31 @@ class GeoTreeLogger {
LinearAllocator<> *allocator = nullptr;
struct WarningWithNode {
- std::string node_name;
+ StringRefNull node_name;
NodeWarning warning;
};
struct SocketValueLog {
- std::string node_name;
- std::string socket_identifier;
+ StringRefNull node_name;
+ StringRefNull socket_identifier;
destruct_ptr<ValueLog> value;
};
struct NodeExecutionTime {
- std::string node_name;
+ StringRefNull node_name;
TimePoint start;
TimePoint end;
};
struct ViewerNodeLogWithNode {
- std::string node_name;
+ StringRefNull node_name;
destruct_ptr<ViewerNodeLog> viewer_log;
};
struct AttributeUsageWithNode {
- std::string node_name;
- std::string attribute_name;
+ StringRefNull node_name;
+ StringRefNull attribute_name;
NamedAttributeUsage usage;
};
struct DebugMessage {
- std::string node_name;
- std::string message;
+ StringRefNull node_name;
+ StringRefNull message;
};
Vector<WarningWithNode> node_warnings;
@@ -214,7 +214,7 @@ class GeoTreeLogger {
~GeoTreeLogger();
void log_value(const bNode &node, const bNodeSocket &socket, GPointer value);
- void log_viewer_node(const bNode &viewer_node, const GeometrySet &geometry, const GField &field);
+ void log_viewer_node(const bNode &viewer_node, GeometrySet geometry);
};
/**
@@ -235,12 +235,12 @@ class GeoNodeLog {
*/
std::chrono::nanoseconds run_time{0};
/** Maps from socket identifiers to their values. */
- Map<std::string, ValueLog *> input_values_;
- Map<std::string, ValueLog *> output_values_;
+ Map<StringRefNull, ValueLog *> input_values_;
+ Map<StringRefNull, ValueLog *> output_values_;
/** Maps from attribute name to their usage flags. */
- Map<std::string, NamedAttributeUsage> used_named_attributes;
+ Map<StringRefNull, NamedAttributeUsage> used_named_attributes;
/** Messages that are used for debugging purposes during development. */
- Vector<std::string> debug_messages;
+ Vector<StringRefNull> debug_messages;
GeoNodeLog();
~GeoNodeLog();
@@ -269,12 +269,12 @@ class GeoTreeLog {
bool reduced_debug_messages_ = false;
public:
- Map<std::string, GeoNodeLog> nodes;
- Map<std::string, ViewerNodeLog *, 0> viewer_node_logs;
+ Map<StringRefNull, GeoNodeLog> nodes;
+ Map<StringRefNull, ViewerNodeLog *, 0> viewer_node_logs;
Vector<NodeWarning> all_warnings;
std::chrono::nanoseconds run_time_sum{0};
Vector<const GeometryAttributeInfo *> existing_attributes;
- Map<std::string, NamedAttributeUsage> used_named_attributes;
+ Map<StringRefNull, NamedAttributeUsage> used_named_attributes;
GeoTreeLog(GeoModifierLog *modifier_log, Vector<GeoTreeLogger *> tree_loggers);
~GeoTreeLog();
@@ -333,8 +333,7 @@ class GeoModifierLog {
* Utility accessor to logged data.
*/
static GeoTreeLog *get_tree_log_for_node_editor(const SpaceNode &snode);
- static const ViewerNodeLog *find_viewer_node_log_for_spreadsheet(
- const SpaceSpreadsheet &sspreadsheet);
+ static const ViewerNodeLog *find_viewer_node_log_for_path(const ViewerPath &viewer_path);
};
} // namespace blender::nodes::geo_eval_log
diff --git a/source/blender/nodes/NOD_node_declaration.hh b/source/blender/nodes/NOD_node_declaration.hh
index 42755b2e8dd..13f8af4ddf5 100644
--- a/source/blender/nodes/NOD_node_declaration.hh
+++ b/source/blender/nodes/NOD_node_declaration.hh
@@ -65,6 +65,8 @@ struct FieldInferencingInterface {
Vector<OutputFieldDependency> outputs;
};
+using ImplicitInputValueFn = std::function<void(const bNode &node, void *r_value)>;
+
/**
* Describes a single input or output socket. This is subclassed for different socket types.
*/
@@ -103,6 +105,10 @@ class SocketDeclaration {
/** Utility method to make the socket available if there is a straightforward way to do so. */
std::function<void(bNode &)> make_available_fn_;
+ /** Some input sockets can have non-trivial values in the case when they are unlinked. This
+ * callback computes the default input of a values in geometry nodes when nothing is linked. */
+ std::unique_ptr<ImplicitInputValueFn> implicit_input_fn_;
+
friend NodeDeclarationBuilder;
template<typename SocketDecl> friend class SocketDeclarationBuilder;
@@ -140,6 +146,11 @@ class SocketDeclaration {
bool compositor_skip_realization() const;
bool compositor_expects_single_value() const;
+ const ImplicitInputValueFn *implicit_input_fn() const
+ {
+ return implicit_input_fn_.get();
+ }
+
protected:
void set_common_flags(bNodeSocket &socket) const;
bool matches_common_data(const bNodeSocket &socket) const;
@@ -225,10 +236,11 @@ class SocketDeclarationBuilder : public BaseSocketDeclarationBuilder {
}
/** The input supports a field and is a field by default when nothing is connected. */
- Self &implicit_field()
+ Self &implicit_field(ImplicitInputValueFn fn)
{
this->hide_value();
decl_->input_field_type_ = InputSocketFieldType::Implicit;
+ decl_->implicit_input_fn_ = std::make_unique<ImplicitInputValueFn>(std::move(fn));
return *(Self *)this;
}
@@ -348,6 +360,13 @@ class NodeDeclarationBuilder {
eNodeSocketInOut in_out);
};
+namespace implicit_field_inputs {
+void position(const bNode &node, void *r_value);
+void normal(const bNode &node, void *r_value);
+void index(const bNode &node, void *r_value);
+void id_or_index(const bNode &node, void *r_value);
+} // namespace implicit_field_inputs
+
/* -------------------------------------------------------------------- */
/** \name #OutputFieldDependency Inline Methods
* \{ */
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index d587da823f1..9671f8148ec 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -303,8 +303,11 @@ DefNode(GeometryNode, GEO_NODE_CURVE_SPLINE_PARAMETER,0, "SPLINE_PARAMETER", Spl
DefNode(GeometryNode, GEO_NODE_CURVE_SPLINE_TYPE, def_geo_curve_spline_type,"CURVE_SPLINE_TYPE", CurveSplineType, "Set Spline Type", "Change the type of curves")
DefNode(GeometryNode, GEO_NODE_CURVE_TO_MESH, 0, "CURVE_TO_MESH", CurveToMesh, "Curve to Mesh", "Convert curves into a mesh, optionally with a custom profile shape defined by curves")
DefNode(GeometryNode, GEO_NODE_CURVE_TO_POINTS, def_geo_curve_to_points, "CURVE_TO_POINTS", CurveToPoints, "Curve to Points", "Generate a point cloud by sampling positions along curves")
+DefNode(GeometryNode, GEO_NODE_CURVE_TOPOLOGY_CURVE_OF_POINT, 0, "CURVE_OF_POINT", CurveOfPoint, "Curve of Point", "Retrieve the curve a control point is part of")
+DefNode(GeometryNode, GEO_NODE_CURVE_TOPOLOGY_POINTS_OF_CURVE, 0, "POINTS_OF_CURVE", PointsOfCurve, "Points of Curve", "Retrieve a point index within a curve")
DefNode(GeometryNode, GEO_NODE_DEFORM_CURVES_ON_SURFACE, 0, "DEFORM_CURVES_ON_SURFACE", DeformCurvesOnSurface, "Deform Curves on Surface", "Translate and rotate curves based on changes between the object's original and evaluated surface mesh")
DefNode(GeometryNode, GEO_NODE_DELETE_GEOMETRY, def_geo_delete_geometry, "DELETE_GEOMETRY", DeleteGeometry, "Delete Geometry", "Remove selected elements of a geometry")
+DefNode(GeometryNode, GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME, def_geo_distribute_points_in_volume, "DISTRIBUTE_POINTS_IN_VOLUME", DistributePointsInVolume, "Distribute Points in Volume", "Generate points inside a volume")
DefNode(GeometryNode, GEO_NODE_DISTRIBUTE_POINTS_ON_FACES, def_geo_distribute_points_on_faces, "DISTRIBUTE_POINTS_ON_FACES", DistributePointsOnFaces, "Distribute Points on Faces", "Generate points spread out on the surface of a mesh")
DefNode(GeometryNode, GEO_NODE_DUAL_MESH, 0, "DUAL_MESH", DualMesh, "Dual Mesh", "Convert Faces into vertices and vertices into faces")
DefNode(GeometryNode, GEO_NODE_DUPLICATE_ELEMENTS, def_geo_duplicate_elements, "DUPLICATE_ELEMENTS", DuplicateElements, "Duplicate Elements", "Generate an arbitrary number copies of each selected input element")
@@ -317,7 +320,7 @@ DefNode(GeometryNode, GEO_NODE_FILLET_CURVE, def_geo_curve_fillet, "FILLET_CURVE
DefNode(GeometryNode, GEO_NODE_FLIP_FACES, 0, "FLIP_FACES", FlipFaces, "Flip Faces", "Reverse the order of the vertices and edges of selected faces, flipping their normal direction")
DefNode(GeometryNode, GEO_NODE_GEOMETRY_TO_INSTANCE, 0, "GEOMETRY_TO_INSTANCE", GeometryToInstance, "Geometry to Instance", "Convert each input geometry into an instance, which can be much faster than the Join Geometry node when the inputs are large")
DefNode(GeometryNode, GEO_NODE_IMAGE_TEXTURE, def_geo_image_texture, "IMAGE_TEXTURE", ImageTexture, "Image Texture", "Sample values from an image texture")
-DefNode(GeometryNode, GEO_NODE_INPUT_CURVE_HANDLES, 0, "INPUT_CURVE_HANDLES",InputCurveHandlePositions,"Curve Handle Positions", "Retrieve the position of each Bézier control point's handles")
+DefNode(GeometryNode, GEO_NODE_INPUT_CURVE_HANDLES, 0, "INPUT_CURVE_HANDLES", InputCurveHandlePositions,"Curve Handle Positions", "Retrieve the position of each Bézier control point's handles")
DefNode(GeometryNode, GEO_NODE_INPUT_CURVE_TILT, 0, "INPUT_CURVE_TILT", InputCurveTilt, "Curve Tilt", "Retrieve the angle at each control point used to twist the curve's normal around its tangent")
DefNode(GeometryNode, GEO_NODE_INPUT_ID, 0, "INPUT_ID", InputID, "ID", "Retrieve a stable random identifier value from the \"id\" attribute on the point domain, or the index if the attribute does not exist")
DefNode(GeometryNode, GEO_NODE_INPUT_INDEX, 0, "INDEX", InputIndex, "Index", "Retrieve an integer value indicating the position of each element in the list, starting at zero")
@@ -352,6 +355,7 @@ DefNode(GeometryNode, GEO_NODE_JOIN_GEOMETRY, 0, "JOIN_GEOMETRY", JoinGeometry,
DefNode(GeometryNode, GEO_NODE_MATERIAL_SELECTION, 0, "MATERIAL_SELECTION", MaterialSelection, "Material Selection", "Provide a selection of faces that use the specified material")
DefNode(GeometryNode, GEO_NODE_MERGE_BY_DISTANCE, def_geo_merge_by_distance,"MERGE_BY_DISTANCE", MergeByDistance, "Merge by Distance", "Merge vertices or points within a given distance")
DefNode(GeometryNode, GEO_NODE_MESH_BOOLEAN, def_geo_boolean, "MESH_BOOLEAN", MeshBoolean, "Mesh Boolean", "Cut, subtract, or join multiple mesh inputs")
+DefNode(GeometryNode, GEO_NODE_MESH_FACE_SET_BOUNDARIES, 0, "MESH_FACE_SET_BOUNDARIES", MeshFaceSetBoundaries, "Face Set Boundaries", "Find edges on the boundaries between face sets")
DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CIRCLE, def_geo_mesh_circle, "MESH_PRIMITIVE_CIRCLE", MeshCircle, "Mesh Circle", "Generate a circular ring of edges")
DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CONE, def_geo_mesh_cone, "MESH_PRIMITIVE_CONE",MeshCone, "Cone", "Generate a cone mesh")
DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CUBE, 0, "MESH_PRIMITIVE_CUBE",MeshCube, "Cube", "Generate a cuboid mesh with variable side lengths and subdivisions")
@@ -363,7 +367,15 @@ DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_UV_SPHERE, 0, "MESH_PRIMITIVE_UV_S
DefNode(GeometryNode, GEO_NODE_MESH_TO_CURVE, 0, "MESH_TO_CURVE", MeshToCurve, "Mesh to Curve", "Generate a curve from a mesh")
DefNode(GeometryNode, GEO_NODE_MESH_TO_POINTS, def_geo_mesh_to_points, "MESH_TO_POINTS", MeshToPoints, "Mesh to Points", "Generate a point cloud from a mesh's vertices")
DefNode(GeometryNode, GEO_NODE_MESH_TO_VOLUME, def_geo_mesh_to_volume, "MESH_TO_VOLUME", MeshToVolume, "Mesh to Volume", "Create a fog volume with the shape of the input mesh's surface")
+DefNode(GeometryNode, GEO_NODE_MESH_TOPOLOGY_CORNERS_OF_FACE, 0, "CORNERS_OF_FACE", CornersOfFace, "Corners of Face", "Retrieve corners that make up a face")
+DefNode(GeometryNode, GEO_NODE_MESH_TOPOLOGY_CORNERS_OF_VERTEX, 0, "CORNERS_OF_VERTEX", CornersOfVertex, "Corners of Vertex", "Retrieve face corners connected to vertices")
+DefNode(GeometryNode, GEO_NODE_MESH_TOPOLOGY_EDGES_OF_CORNER, 0, "EDGES_OF_CORNER", EdgesOfCorner, "Edges of Corner", "Retrieve the edges on both sides of a face corner")
+DefNode(GeometryNode, GEO_NODE_MESH_TOPOLOGY_EDGES_OF_VERTEX, 0, "EDGES_OF_VERTEX", EdgesOfVertex, "Edges of Vertex", "Retrieve the edges connected to each vertex")
+DefNode(GeometryNode, GEO_NODE_MESH_TOPOLOGY_FACE_OF_CORNER, 0, "FACE_OF_CORNER", FaceOfCorner, "Face of Corner", "Retrieve the face each face corner is part of")
+DefNode(GeometryNode, GEO_NODE_MESH_TOPOLOGY_OFFSET_CORNER_IN_FACE, 0, "OFFSET_CORNER_IN_FACE", OffsetCornerInFace, "Offset Corner in Face", "Retrieve corners in the same face as another")
+DefNode(GeometryNode, GEO_NODE_MESH_TOPOLOGY_VERTEX_OF_CORNER, 0, "VERTEX_OF_CORNER", VertexOfCorner, "Vertex of Corner", "Retrieve the vertex each face corner is attached to")
DefNode(GeometryNode, GEO_NODE_OBJECT_INFO, def_geo_object_info, "OBJECT_INFO", ObjectInfo, "Object Info", "Retrieve information from an object")
+DefNode(GeometryNode, GEO_NODE_OFFSET_POINT_IN_CURVE, 0, "OFFSET_POINT_IN_CURVE", OffsetPointInCurve, "Offset Point in Curve", "Offset a control point index within its curve")
DefNode(GeometryNode, GEO_NODE_POINTS_TO_VERTICES, 0, "POINTS_TO_VERTICES", PointsToVertices, "Points to Vertices", "Generate a mesh vertex for each point cloud point")
DefNode(GeometryNode, GEO_NODE_POINTS_TO_VOLUME, def_geo_points_to_volume, "POINTS_TO_VOLUME", PointsToVolume, "Points to Volume", "Generate a fog volume sphere around every point")
DefNode(GeometryNode, GEO_NODE_POINTS, 0, "POINTS", Points, "Points", "Generate a point cloud with positions and radii defined by fields")
@@ -376,11 +388,17 @@ DefNode(GeometryNode, GEO_NODE_RESAMPLE_CURVE, def_geo_curve_resample, "RESAMPLE
DefNode(GeometryNode, GEO_NODE_REVERSE_CURVE, 0, "REVERSE_CURVE", ReverseCurve, "Reverse Curve", "Swap the start and end of splines")
DefNode(GeometryNode, GEO_NODE_ROTATE_INSTANCES, 0, "ROTATE_INSTANCES", RotateInstances, "Rotate Instances", "Rotate geometry instances in local or global space")
DefNode(GeometryNode, GEO_NODE_SAMPLE_CURVE, def_geo_curve_sample, "SAMPLE_CURVE", SampleCurve, "Sample Curve", "Retrieve data from a point on a curve at a certain distance from its start")
+DefNode(GeometryNode, GEO_NODE_SAMPLE_INDEX, def_geo_sample_index, "SAMPLE_INDEX", SampleIndex, "Sample Index", "Retrieve values from specific geometry elements")
+DefNode(GeometryNode, GEO_NODE_SAMPLE_NEAREST_SURFACE, def_geo_sample_nearest_surface, "SAMPLE_NEAREST_SURFACE", SampleNearestSurface, "Sample Nearest Surface", "Calculate the interpolated value of a mesh attribute on the closest point of its surface")
+DefNode(GeometryNode, GEO_NODE_SAMPLE_NEAREST, def_geo_sample_nearest, "SAMPLE_NEAREST", SampleNearest, "Sample Nearest", "Find the element of a geometry closest to a position")
+DefNode(GeometryNode, GEO_NODE_SAMPLE_UV_SURFACE, def_geo_sample_uv_surface, "SAMPLE_UV_SURFACE", SampleUVSurface, "Sample UV Surface", "Calculate the interpolated values of a mesh attribute at a UV coordinate")
DefNode(GeometryNode, GEO_NODE_SCALE_ELEMENTS, def_geo_scale_elements, "SCALE_ELEMENTS", ScaleElements, "Scale Elements", "Scale groups of connected edges and faces")
DefNode(GeometryNode, GEO_NODE_SCALE_INSTANCES, 0, "SCALE_INSTANCES", ScaleInstances, "Scale Instances", "Scale geometry instances in local or global space")
DefNode(GeometryNode, GEO_NODE_SEPARATE_COMPONENTS, 0, "SEPARATE_COMPONENTS",SeparateComponents, "Separate Components","Split a geometry into a separate output for each type of data in the geometry")
DefNode(GeometryNode, GEO_NODE_SEPARATE_GEOMETRY, def_geo_separate_geometry,"SEPARATE_GEOMETRY", SeparateGeometry, "Separate Geometry", "Split a geometry into two geometry outputs based on a selection")
+DefNode(GeometryNode, GEO_NODE_SELF_OBJECT, 0, "SELF_OBJECT", SelfObject, "Self Object", "Retrieve the object that contains the geometry nodes modifier currently being executed")
DefNode(GeometryNode, GEO_NODE_SET_CURVE_HANDLES, def_geo_curve_set_handle_positions, "SET_CURVE_HANDLES", SetCurveHandlePositions, "Set Handle Positions", "Set the positions for the handles of Bézier curves")
+DefNode(GeometryNode, GEO_NODE_SET_CURVE_NORMAL, def_geo_set_curve_normal, "SET_CURVE_NORMAL", SetCurveNormal, "Set Curve Normal", "Set the evaluation mode for curve normals")
DefNode(GeometryNode, GEO_NODE_SET_CURVE_RADIUS, 0, "SET_CURVE_RADIUS", SetCurveRadius, "Set Curve Radius", "Set the radius of the curve at each control point")
DefNode(GeometryNode, GEO_NODE_SET_CURVE_TILT, 0, "SET_CURVE_TILT", SetCurveTilt, "Set Curve Tilt", "Set the tilt angle at each curve control point")
DefNode(GeometryNode, GEO_NODE_SET_ID, 0, "SET_ID", SetID, "Set ID", "Set the id attribute on the input geometry, mainly used internally for randomizing")
@@ -399,7 +417,6 @@ DefNode(GeometryNode, GEO_NODE_SUBDIVIDE_CURVE, 0, "SUBDIVIDE_CURVE", SubdivideC
DefNode(GeometryNode, GEO_NODE_SUBDIVIDE_MESH, 0, "SUBDIVIDE_MESH", SubdivideMesh, "Subdivide Mesh", "Divide mesh faces into smaller ones without changing the shape or volume, using linear interpolation to place the new vertices")
DefNode(GeometryNode, GEO_NODE_SUBDIVISION_SURFACE, def_geo_subdivision_surface, "SUBDIVISION_SURFACE",SubdivisionSurface, "Subdivision Surface","Divide mesh faces to form a smooth surface, using the Catmull-Clark subdivision method")
DefNode(GeometryNode, GEO_NODE_SWITCH, def_geo_switch, "SWITCH", Switch, "Switch", "Switch between two inputs")
-DefNode(GeometryNode, GEO_NODE_TRANSFER_ATTRIBUTE, def_geo_transfer_attribute, "ATTRIBUTE_TRANSFER", AttributeTransfer, "Transfer Attribute", "Retrieve values from a source geometry and provides them as a field by interpolating them with the context geometry")
DefNode(GeometryNode, GEO_NODE_TRANSFORM, 0, "TRANSFORM", Transform, "Transform", "Translate, rotate or scale the geometry")
DefNode(GeometryNode, GEO_NODE_TRANSLATE_INSTANCES, 0, "TRANSLATE_INSTANCES",TranslateInstances, "Translate Instances","Move top-level geometry instances in local or global space")
DefNode(GeometryNode, GEO_NODE_TRIANGULATE, def_geo_triangulate, "TRIANGULATE", Triangulate, "Triangulate", "Convert all faces in a mesh to triangular faces")
diff --git a/source/blender/nodes/composite/CMakeLists.txt b/source/blender/nodes/composite/CMakeLists.txt
index 2537e8e93cc..8bcc2a393d3 100644
--- a/source/blender/nodes/composite/CMakeLists.txt
+++ b/source/blender/nodes/composite/CMakeLists.txt
@@ -18,6 +18,8 @@ set(INC
../../render
../../windowmanager
../../compositor/realtime_compositor
+ ../../compositor/realtime_compositor/algorithms
+ ../../compositor/realtime_compositor/cached_resources
../../../../intern/guardedalloc
# dna_type_offsets.h
diff --git a/source/blender/nodes/composite/node_composite_tree.cc b/source/blender/nodes/composite/node_composite_tree.cc
index 9792c55b590..37d4fe852be 100644
--- a/source/blender/nodes/composite/node_composite_tree.cc
+++ b/source/blender/nodes/composite/node_composite_tree.cc
@@ -36,11 +36,8 @@
# include "COM_compositor.h"
#endif
-static void composite_get_from_context(const bContext *C,
- bNodeTreeType *UNUSED(treetype),
- bNodeTree **r_ntree,
- ID **r_id,
- ID **r_from)
+static void composite_get_from_context(
+ const bContext *C, bNodeTreeType * /*treetype*/, bNodeTree **r_ntree, ID **r_id, ID **r_from)
{
Scene *scene = CTX_data_scene(C);
@@ -49,7 +46,7 @@ static void composite_get_from_context(const bContext *C,
*r_ntree = scene->nodetree;
}
-static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func)
+static void foreach_nodeclass(Scene * /*scene*/, void *calldata, bNodeClassCallback func)
{
func(calldata, NODE_CLASS_INPUT, N_("Input"));
func(calldata, NODE_CLASS_OUTPUT, N_("Output"));
@@ -64,7 +61,7 @@ static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCa
func(calldata, NODE_CLASS_LAYOUT, N_("Layout"));
}
-static void free_node_cache(bNodeTree *UNUSED(ntree), bNode *node)
+static void free_node_cache(bNodeTree * /*ntree*/, bNode *node)
{
LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
if (sock->cache) {
@@ -158,7 +155,7 @@ static void update(bNodeTree *ntree)
ntree_update_reroute_nodes(ntree);
}
-static void composite_node_add_init(bNodeTree *UNUSED(bnodetree), bNode *bnode)
+static void composite_node_add_init(bNodeTree * /*bnodetree*/, bNode *bnode)
{
/* Composite node will only show previews for input classes
* by default, other will be hidden
@@ -168,7 +165,7 @@ static void composite_node_add_init(bNodeTree *UNUSED(bnodetree), bNode *bnode)
}
}
-static bool composite_node_tree_socket_type_valid(bNodeTreeType *UNUSED(ntreetype),
+static bool composite_node_tree_socket_type_valid(bNodeTreeType * /*ntreetype*/,
bNodeSocketType *socket_type)
{
return nodeIsStaticSocketType(socket_type) &&
diff --git a/source/blender/nodes/composite/node_composite_util.cc b/source/blender/nodes/composite/node_composite_util.cc
index 575a32b1785..ae3352c0d1b 100644
--- a/source/blender/nodes/composite/node_composite_util.cc
+++ b/source/blender/nodes/composite/node_composite_util.cc
@@ -9,9 +9,7 @@
#include "node_composite_util.hh"
-bool cmp_node_poll_default(bNodeType *UNUSED(ntype),
- bNodeTree *ntree,
- const char **r_disabled_hint)
+bool cmp_node_poll_default(bNodeType * /*ntype*/, bNodeTree *ntree, const char **r_disabled_hint)
{
if (!STREQ(ntree->idname, "CompositorNodeTree")) {
*r_disabled_hint = TIP_("Not a compositor node tree");
@@ -20,7 +18,7 @@ bool cmp_node_poll_default(bNodeType *UNUSED(ntype),
return true;
}
-void cmp_node_update_default(bNodeTree *UNUSED(ntree), bNode *node)
+void cmp_node_update_default(bNodeTree * /*ntree*/, bNode *node)
{
LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
if (sock->cache) {
diff --git a/source/blender/nodes/composite/nodes/node_composite_alpha_over.cc b/source/blender/nodes/composite/nodes/node_composite_alpha_over.cc
index 12f81da3d1c..dffdc4a9408 100644
--- a/source/blender/nodes/composite/nodes/node_composite_alpha_over.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_alpha_over.cc
@@ -37,12 +37,12 @@ static void cmp_node_alphaover_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_alphaover_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_alphaover_init(bNodeTree * /*ntree*/, bNode *node)
{
node->storage = MEM_cnew<NodeTwoFloats>(__func__);
}
-static void node_composit_buts_alphaover(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_alphaover(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
@@ -108,7 +108,7 @@ void register_node_type_cmp_alphaover()
cmp_node_type_base(&ntype, CMP_NODE_ALPHAOVER, "Alpha Over", NODE_CLASS_OP_COLOR);
ntype.declare = file_ns::cmp_node_alphaover_declare;
ntype.draw_buttons = file_ns::node_composit_buts_alphaover;
- node_type_init(&ntype, file_ns::node_alphaover_init);
+ ntype.initfunc = file_ns::node_alphaover_init;
node_type_storage(
&ntype, "NodeTwoFloats", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_antialiasing.cc b/source/blender/nodes/composite/nodes/node_composite_antialiasing.cc
index 55fe3366526..8c77df08211 100644
--- a/source/blender/nodes/composite/nodes/node_composite_antialiasing.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_antialiasing.cc
@@ -22,7 +22,7 @@ static void cmp_node_antialiasing_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_antialiasing(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_antialiasing(bNodeTree * /*ntree*/, bNode *node)
{
NodeAntiAliasingData *data = MEM_cnew<NodeAntiAliasingData>(__func__);
@@ -33,7 +33,7 @@ static void node_composit_init_antialiasing(bNodeTree *UNUSED(ntree), bNode *nod
node->storage = data;
}
-static void node_composit_buts_antialiasing(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_antialiasing(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
@@ -74,7 +74,7 @@ void register_node_type_cmp_antialiasing()
ntype.draw_buttons = file_ns::node_composit_buts_antialiasing;
ntype.flag |= NODE_PREVIEW;
node_type_size(&ntype, 170, 140, 200);
- node_type_init(&ntype, file_ns::node_composit_init_antialiasing);
+ ntype.initfunc = file_ns::node_composit_init_antialiasing;
node_type_storage(
&ntype, "NodeAntiAliasingData", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_bilateralblur.cc b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.cc
index ac9a6c89aa4..65990677ae3 100644
--- a/source/blender/nodes/composite/nodes/node_composite_bilateralblur.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.cc
@@ -34,7 +34,7 @@ static void cmp_node_bilateralblur_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_bilateralblur(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_bilateralblur(bNodeTree * /*ntree*/, bNode *node)
{
NodeBilateralBlurData *nbbd = MEM_cnew<NodeBilateralBlurData>(__func__);
node->storage = nbbd;
@@ -43,9 +43,7 @@ static void node_composit_init_bilateralblur(bNodeTree *UNUSED(ntree), bNode *no
nbbd->sigma_space = 5.0;
}
-static void node_composit_buts_bilateralblur(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_composit_buts_bilateralblur(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
@@ -121,7 +119,7 @@ void register_node_type_cmp_bilateralblur()
cmp_node_type_base(&ntype, CMP_NODE_BILATERALBLUR, "Bilateral Blur", NODE_CLASS_OP_FILTER);
ntype.declare = file_ns::cmp_node_bilateralblur_declare;
ntype.draw_buttons = file_ns::node_composit_buts_bilateralblur;
- node_type_init(&ntype, file_ns::node_composit_init_bilateralblur);
+ ntype.initfunc = file_ns::node_composit_init_bilateralblur;
node_type_storage(
&ntype, "NodeBilateralBlurData", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_blur.cc b/source/blender/nodes/composite/nodes/node_composite_blur.cc
index 630f18361e3..6eacc685c7e 100644
--- a/source/blender/nodes/composite/nodes/node_composite_blur.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_blur.cc
@@ -5,11 +5,7 @@
* \ingroup cmpnodes
*/
-#include <cstdint>
-
-#include "BLI_array.hh"
#include "BLI_assert.h"
-#include "BLI_index_range.hh"
#include "BLI_math_base.hh"
#include "BLI_math_vec_types.hh"
#include "BLI_math_vector.hh"
@@ -19,12 +15,13 @@
#include "UI_interface.h"
#include "UI_resources.h"
-#include "RE_pipeline.h"
-
+#include "GPU_shader.h"
#include "GPU_state.h"
#include "GPU_texture.h"
#include "COM_node_operation.hh"
+#include "COM_symmetric_blur_weights.hh"
+#include "COM_symmetric_separable_blur_weights.hh"
#include "COM_utilities.hh"
#include "node_composite_util.hh"
@@ -42,14 +39,14 @@ static void cmp_node_blur_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_blur(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_blur(bNodeTree * /*ntree*/, bNode *node)
{
NodeBlurData *data = MEM_cnew<NodeBlurData>(__func__);
data->filtertype = R_FILTER_GAUSS;
node->storage = data;
}
-static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_blur(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col, *row;
@@ -92,192 +89,7 @@ static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), Point
using namespace blender::realtime_compositor;
-/* A helper class that computes and caches a 1D GPU texture containing the weights of the separable
- * filter of the given type and radius. The filter is assumed to be symmetric, because the filter
- * functions are all even functions. Consequently, only the positive half of the filter is computed
- * and the shader takes that into consideration. */
-class SymmetricSeparableBlurWeights {
- private:
- float radius_ = 1.0f;
- int type_ = R_FILTER_GAUSS;
- GPUTexture *texture_ = nullptr;
-
- public:
- ~SymmetricSeparableBlurWeights()
- {
- if (texture_) {
- GPU_texture_free(texture_);
- }
- }
-
- /* Check if a texture containing the weights was already computed for the given filter type and
- * radius. If such texture exists, do nothing, otherwise, free the already computed texture and
- * recompute it with the given filter type and radius. */
- void update(float radius, int type)
- {
- if (texture_ && type == type_ && radius == radius_) {
- return;
- }
-
- if (texture_) {
- GPU_texture_free(texture_);
- }
-
- /* The size of filter is double the radius plus 1, but since the filter is symmetric, we only
- * compute half of it and no doubling happens. We add 1 to make sure the filter size is always
- * odd and there is a center weight. */
- const int size = math::ceil(radius) + 1;
- Array<float> weights(size);
-
- float sum = 0.0f;
-
- /* First, compute the center weight. */
- const float center_weight = RE_filter_value(type, 0.0f);
- weights[0] = center_weight;
- sum += center_weight;
-
- /* Second, compute the other weights in the positive direction, making sure to add double the
- * weight to the sum of weights because the filter is symmetric and we only loop over half of
- * it. Skip the center weight already computed by dropping the front index. */
- const float scale = radius > 0.0f ? 1.0f / radius : 0.0f;
- for (const int i : weights.index_range().drop_front(1)) {
- const float weight = RE_filter_value(type, i * scale);
- weights[i] = weight;
- sum += weight * 2.0f;
- }
-
- /* Finally, normalize the weights. */
- for (const int i : weights.index_range()) {
- weights[i] /= sum;
- }
-
- texture_ = GPU_texture_create_1d("Weights", size, 1, GPU_R16F, weights.data());
-
- type_ = type;
- radius_ = radius;
- }
-
- void bind_as_texture(GPUShader *shader, const char *texture_name)
- {
- const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name);
- GPU_texture_bind(texture_, texture_image_unit);
- }
-
- void unbind_as_texture()
- {
- GPU_texture_unbind(texture_);
- }
-};
-
-/* A helper class that computes and caches a 2D GPU texture containing the weights of the filter of
- * the given type and radius. The filter is assumed to be symmetric, because the filter functions
- * are evaluated on the normalized distance to the center. Consequently, only the upper right
- * quadrant are computed and the shader takes that into consideration. */
-class SymmetricBlurWeights {
- private:
- int type_ = R_FILTER_GAUSS;
- float2 radius_ = float2(1.0f);
- GPUTexture *texture_ = nullptr;
-
- public:
- ~SymmetricBlurWeights()
- {
- if (texture_) {
- GPU_texture_free(texture_);
- }
- }
-
- /* Check if a texture containing the weights was already computed for the given filter type and
- * radius. If such texture exists, do nothing, otherwise, free the already computed texture and
- * recompute it with the given filter type and radius. */
- void update(float2 radius, int type)
- {
- if (texture_ && type == type_ && radius == radius_) {
- return;
- }
-
- if (texture_) {
- GPU_texture_free(texture_);
- }
-
- /* The full size of filter is double the radius plus 1, but since the filter is symmetric, we
- * only compute a single quadrant of it and so no doubling happens. We add 1 to make sure the
- * filter size is always odd and there is a center weight. */
- const float2 scale = math::safe_divide(float2(1.0f), radius);
- const int2 size = int2(math::ceil(radius)) + int2(1);
- Array<float> weights(size.x * size.y);
-
- float sum = 0.0f;
-
- /* First, compute the center weight. */
- const float center_weight = RE_filter_value(type, 0.0f);
- weights[0] = center_weight;
- sum += center_weight;
-
- /* Then, compute the weights along the positive x axis, making sure to add double the weight to
- * the sum of weights because the filter is symmetric and we only loop over the positive half
- * of the x axis. Skip the center weight already computed by dropping the front index. */
- for (const int x : IndexRange(size.x).drop_front(1)) {
- const float weight = RE_filter_value(type, x * scale.x);
- weights[x] = weight;
- sum += weight * 2.0f;
- }
-
- /* Then, compute the weights along the positive y axis, making sure to add double the weight to
- * the sum of weights because the filter is symmetric and we only loop over the positive half
- * of the y axis. Skip the center weight already computed by dropping the front index. */
- for (const int y : IndexRange(size.y).drop_front(1)) {
- const float weight = RE_filter_value(type, y * scale.y);
- weights[size.x * y] = weight;
- sum += weight * 2.0f;
- }
-
- /* Then, compute the other weights in the upper right quadrant, making sure to add quadruple
- * the weight to the sum of weights because the filter is symmetric and we only loop over one
- * quadrant of it. Skip the weights along the y and x axis already computed by dropping the
- * front index. */
- for (const int y : IndexRange(size.y).drop_front(1)) {
- for (const int x : IndexRange(size.x).drop_front(1)) {
- const float weight = RE_filter_value(type, math::length(float2(x, y) * scale));
- weights[size.x * y + x] = weight;
- sum += weight * 4.0f;
- }
- }
-
- /* Finally, normalize the weights. */
- for (const int y : IndexRange(size.y)) {
- for (const int x : IndexRange(size.x)) {
- weights[size.x * y + x] /= sum;
- }
- }
-
- texture_ = GPU_texture_create_2d("Weights", size.x, size.y, 1, GPU_R16F, weights.data());
-
- type_ = type;
- radius_ = radius;
- }
-
- void bind_as_texture(GPUShader *shader, const char *texture_name)
- {
- const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name);
- GPU_texture_bind(texture_, texture_image_unit);
- }
-
- void unbind_as_texture()
- {
- GPU_texture_unbind(texture_);
- }
-};
-
class BlurOperation : public NodeOperation {
- private:
- /* Cached symmetric blur weights. */
- SymmetricBlurWeights blur_weights_;
- /* Cached symmetric blur weights for the separable horizontal pass. */
- SymmetricSeparableBlurWeights blur_horizontal_weights_;
- /* Cached symmetric blur weights for the separable vertical pass. */
- SymmetricSeparableBlurWeights blur_vertical_weights_;
-
public:
using NodeOperation::NodeOperation;
@@ -308,13 +120,16 @@ class BlurOperation : public NodeOperation {
const Result &input_image = get_input("Image");
input_image.bind_as_texture(shader, "input_tx");
- blur_weights_.update(compute_blur_radius(), node_storage(bnode()).filtertype);
- blur_weights_.bind_as_texture(shader, "weights_tx");
+ const float2 blur_radius = compute_blur_radius();
+
+ const SymmetricBlurWeights &weights = context().cache_manager().get_symmetric_blur_weights(
+ node_storage(bnode()).filtertype, blur_radius);
+ weights.bind_as_texture(shader, "weights_tx");
Domain domain = compute_domain();
if (get_extend_bounds()) {
/* Add a radius amount of pixels in both sides of the image, hence the multiply by 2. */
- domain.size += int2(math::ceil(compute_blur_radius())) * 2;
+ domain.size += int2(math::ceil(blur_radius)) * 2;
}
Result &output_image = get_result("Image");
@@ -326,7 +141,7 @@ class BlurOperation : public NodeOperation {
GPU_shader_unbind();
output_image.unbind_as_image();
input_image.unbind_as_texture();
- blur_weights_.unbind_as_texture();
+ weights.unbind_as_texture();
}
GPUTexture *execute_separable_blur_horizontal_pass()
@@ -341,12 +156,16 @@ class BlurOperation : public NodeOperation {
const Result &input_image = get_input("Image");
input_image.bind_as_texture(shader, "input_tx");
- blur_horizontal_weights_.update(compute_blur_radius().x, node_storage(bnode()).filtertype);
- blur_horizontal_weights_.bind_as_texture(shader, "weights_tx");
+ const float2 blur_radius = compute_blur_radius();
+
+ const SymmetricSeparableBlurWeights &weights =
+ context().cache_manager().get_symmetric_separable_blur_weights(
+ node_storage(bnode()).filtertype, blur_radius.x);
+ weights.bind_as_texture(shader, "weights_tx");
Domain domain = compute_domain();
if (get_extend_bounds()) {
- domain.size.x += static_cast<int>(math::ceil(compute_blur_radius().x)) * 2;
+ domain.size.x += int(math::ceil(blur_radius.x)) * 2;
}
/* We allocate an output image of a transposed size, that is, with a height equivalent to the
@@ -367,7 +186,7 @@ class BlurOperation : public NodeOperation {
GPU_shader_unbind();
input_image.unbind_as_texture();
- blur_horizontal_weights_.unbind_as_texture();
+ weights.unbind_as_texture();
GPU_texture_image_unbind(horizontal_pass_result);
return horizontal_pass_result;
@@ -386,8 +205,12 @@ class BlurOperation : public NodeOperation {
const int texture_image_unit = GPU_shader_get_texture_binding(shader, "input_tx");
GPU_texture_bind(horizontal_pass_result, texture_image_unit);
- blur_vertical_weights_.update(compute_blur_radius().y, node_storage(bnode()).filtertype);
- blur_vertical_weights_.bind_as_texture(shader, "weights_tx");
+ const float2 blur_radius = compute_blur_radius();
+
+ const SymmetricSeparableBlurWeights &weights =
+ context().cache_manager().get_symmetric_separable_blur_weights(
+ node_storage(bnode()).filtertype, blur_radius.y);
+ weights.bind_as_texture(shader, "weights_tx");
Domain domain = compute_domain();
if (get_extend_bounds()) {
@@ -405,7 +228,7 @@ class BlurOperation : public NodeOperation {
GPU_shader_unbind();
output_image.unbind_as_image();
- blur_vertical_weights_.unbind_as_texture();
+ weights.unbind_as_texture();
GPU_texture_unbind(horizontal_pass_result);
}
@@ -501,7 +324,7 @@ void register_node_type_cmp_blur()
ntype.declare = file_ns::cmp_node_blur_declare;
ntype.draw_buttons = file_ns::node_composit_buts_blur;
ntype.flag |= NODE_PREVIEW;
- node_type_init(&ntype, file_ns::node_composit_init_blur);
+ ntype.initfunc = file_ns::node_composit_init_blur;
node_type_storage(
&ntype, "NodeBlurData", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_bokehblur.cc b/source/blender/nodes/composite/nodes/node_composite_bokehblur.cc
index 9c0617ee8c3..f09bf1f5afd 100644
--- a/source/blender/nodes/composite/nodes/node_composite_bokehblur.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_bokehblur.cc
@@ -43,13 +43,13 @@ static void cmp_node_bokehblur_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_bokehblur(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_bokehblur(bNodeTree * /*ntree*/, bNode *node)
{
node->custom3 = 4.0f;
node->custom4 = 16.0f;
}
-static void node_composit_buts_bokehblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_bokehblur(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "use_variable_size", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
// uiItemR(layout, ptr, "f_stop", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE); /* UNUSED */
@@ -70,10 +70,20 @@ class BokehBlurOperation : public NodeOperation {
return;
}
+ if (get_input("Size").is_single_value() || !get_variable_size()) {
+ execute_constant_size();
+ }
+ else {
+ execute_variable_size();
+ }
+ }
+
+ void execute_constant_size()
+ {
GPUShader *shader = shader_manager().get("compositor_blur");
GPU_shader_bind(shader);
- GPU_shader_uniform_1i(shader, "radius", compute_blur_radius());
+ GPU_shader_uniform_1i(shader, "radius", int(compute_blur_radius()));
GPU_shader_uniform_1b(shader, "extend_bounds", get_extend_bounds());
const Result &input_image = get_input("Image");
@@ -88,7 +98,7 @@ class BokehBlurOperation : public NodeOperation {
Domain domain = compute_domain();
if (get_extend_bounds()) {
/* Add a radius amount of pixels in both sides of the image, hence the multiply by 2. */
- domain.size += int2(compute_blur_radius() * 2);
+ domain.size += int2(int(compute_blur_radius()) * 2);
}
Result &output_image = get_result("Image");
@@ -104,7 +114,42 @@ class BokehBlurOperation : public NodeOperation {
input_mask.unbind_as_texture();
}
- int compute_blur_radius()
+ void execute_variable_size()
+ {
+ GPUShader *shader = shader_manager().get("compositor_blur_variable_size");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_1f(shader, "base_size", compute_blur_radius());
+ GPU_shader_uniform_1i(shader, "search_radius", get_max_size());
+
+ const Result &input_image = get_input("Image");
+ input_image.bind_as_texture(shader, "input_tx");
+
+ const Result &input_weights = get_input("Bokeh");
+ input_weights.bind_as_texture(shader, "weights_tx");
+
+ const Result &input_size = get_input("Size");
+ input_size.bind_as_texture(shader, "size_tx");
+
+ const Result &input_mask = get_input("Bounding box");
+ input_mask.bind_as_texture(shader, "mask_tx");
+
+ const Domain domain = compute_domain();
+ Result &output_image = get_result("Image");
+ output_image.allocate_texture(domain);
+ output_image.bind_as_image(shader, "output_img");
+
+ compute_dispatch_threads_at_least(shader, domain.size);
+
+ GPU_shader_unbind();
+ output_image.unbind_as_image();
+ input_image.unbind_as_texture();
+ input_weights.unbind_as_texture();
+ input_size.unbind_as_texture();
+ input_mask.unbind_as_texture();
+ }
+
+ float compute_blur_radius()
{
const int2 image_size = get_input("Image").domain().size;
const int max_size = math::max(image_size.x, image_size.y);
@@ -124,7 +169,7 @@ class BokehBlurOperation : public NodeOperation {
return true;
}
- if (compute_blur_radius() == 0) {
+ if (compute_blur_radius() == 0.0f) {
return true;
}
@@ -142,6 +187,16 @@ class BokehBlurOperation : public NodeOperation {
{
return bnode().custom1 & CMP_NODEFLAG_BLUR_EXTEND_BOUNDS;
}
+
+ bool get_variable_size()
+ {
+ return bnode().custom1 & CMP_NODEFLAG_BLUR_VARIABLE_SIZE;
+ }
+
+ int get_max_size()
+ {
+ return static_cast<int>(bnode().custom4);
+ }
};
static NodeOperation *get_compositor_operation(Context &context, DNode node)
@@ -160,7 +215,7 @@ void register_node_type_cmp_bokehblur()
cmp_node_type_base(&ntype, CMP_NODE_BOKEHBLUR, "Bokeh Blur", NODE_CLASS_OP_FILTER);
ntype.declare = file_ns::cmp_node_bokehblur_declare;
ntype.draw_buttons = file_ns::node_composit_buts_bokehblur;
- node_type_init(&ntype, file_ns::node_composit_init_bokehblur);
+ ntype.initfunc = file_ns::node_composit_init_bokehblur;
ntype.get_compositor_operation = file_ns::get_compositor_operation;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/composite/nodes/node_composite_bokehimage.cc b/source/blender/nodes/composite/nodes/node_composite_bokehimage.cc
index 81cc8990d35..8b817d3a677 100644
--- a/source/blender/nodes/composite/nodes/node_composite_bokehimage.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_bokehimage.cc
@@ -29,7 +29,7 @@ static void cmp_node_bokehimage_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_bokehimage(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_bokehimage(bNodeTree * /*ntree*/, bNode *node)
{
NodeBokehImage *data = MEM_cnew<NodeBokehImage>(__func__);
data->angle = 0.0f;
@@ -40,7 +40,7 @@ static void node_composit_init_bokehimage(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = data;
}
-static void node_composit_buts_bokehimage(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_bokehimage(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "flaps", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
uiItemR(layout, ptr, "angle", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
@@ -122,7 +122,7 @@ void register_node_type_cmp_bokehimage()
ntype.declare = file_ns::cmp_node_bokehimage_declare;
ntype.draw_buttons = file_ns::node_composit_buts_bokehimage;
ntype.flag |= NODE_PREVIEW;
- node_type_init(&ntype, file_ns::node_composit_init_bokehimage);
+ ntype.initfunc = file_ns::node_composit_init_bokehimage;
node_type_storage(
&ntype, "NodeBokehImage", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_boxmask.cc b/source/blender/nodes/composite/nodes/node_composite_boxmask.cc
index 3cf0932e1b3..17b5d64de91 100644
--- a/source/blender/nodes/composite/nodes/node_composite_boxmask.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_boxmask.cc
@@ -32,7 +32,7 @@ static void cmp_node_boxmask_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Mask"));
}
-static void node_composit_init_boxmask(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_boxmask(bNodeTree * /*ntree*/, bNode *node)
{
NodeBoxMask *data = MEM_cnew<NodeBoxMask>(__func__);
data->x = 0.5;
@@ -43,7 +43,7 @@ static void node_composit_init_boxmask(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = data;
}
-static void node_composit_buts_boxmask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_boxmask(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *row;
@@ -157,7 +157,7 @@ void register_node_type_cmp_boxmask()
cmp_node_type_base(&ntype, CMP_NODE_MASK_BOX, "Box Mask", NODE_CLASS_MATTE);
ntype.declare = file_ns::cmp_node_boxmask_declare;
ntype.draw_buttons = file_ns::node_composit_buts_boxmask;
- node_type_init(&ntype, file_ns::node_composit_init_boxmask);
+ ntype.initfunc = file_ns::node_composit_init_boxmask;
node_type_storage(&ntype, "NodeBoxMask", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_brightness.cc b/source/blender/nodes/composite/nodes/node_composite_brightness.cc
index fa22f551de6..08794914e91 100644
--- a/source/blender/nodes/composite/nodes/node_composite_brightness.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_brightness.cc
@@ -28,14 +28,12 @@ static void cmp_node_brightcontrast_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_brightcontrast(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_brightcontrast(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = 1;
}
-static void node_composit_buts_brightcontrast(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_composit_buts_brightcontrast(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "use_premultiply", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
}
@@ -83,7 +81,7 @@ void register_node_type_cmp_brightcontrast()
cmp_node_type_base(&ntype, CMP_NODE_BRIGHTCONTRAST, "Bright/Contrast", NODE_CLASS_OP_COLOR);
ntype.declare = file_ns::cmp_node_brightcontrast_declare;
ntype.draw_buttons = file_ns::node_composit_buts_brightcontrast;
- node_type_init(&ntype, file_ns::node_composit_init_brightcontrast);
+ ntype.initfunc = file_ns::node_composit_init_brightcontrast;
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/composite/nodes/node_composite_channel_matte.cc b/source/blender/nodes/composite/nodes/node_composite_channel_matte.cc
index 3b825017da8..be02f1ecd00 100644
--- a/source/blender/nodes/composite/nodes/node_composite_channel_matte.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_channel_matte.cc
@@ -31,7 +31,7 @@ static void cmp_node_channel_matte_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Matte"));
}
-static void node_composit_init_channel_matte(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_channel_matte(bNodeTree * /*ntree*/, bNode *node)
{
NodeChroma *c = MEM_cnew<NodeChroma>(__func__);
node->storage = c;
@@ -46,9 +46,7 @@ static void node_composit_init_channel_matte(bNodeTree *UNUSED(ntree), bNode *no
node->custom2 = 2; /* Green Channel. */
}
-static void node_composit_buts_channel_matte(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_composit_buts_channel_matte(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col, *row;
@@ -184,7 +182,7 @@ void register_node_type_cmp_channel_matte()
ntype.declare = file_ns::cmp_node_channel_matte_declare;
ntype.draw_buttons = file_ns::node_composit_buts_channel_matte;
ntype.flag |= NODE_PREVIEW;
- node_type_init(&ntype, file_ns::node_composit_init_channel_matte);
+ ntype.initfunc = file_ns::node_composit_init_channel_matte;
node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_chroma_matte.cc b/source/blender/nodes/composite/nodes/node_composite_chroma_matte.cc
index e5ce87169d4..4e035fcf5e0 100644
--- a/source/blender/nodes/composite/nodes/node_composite_chroma_matte.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_chroma_matte.cc
@@ -36,7 +36,7 @@ static void cmp_node_chroma_matte_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Matte"));
}
-static void node_composit_init_chroma_matte(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_chroma_matte(bNodeTree * /*ntree*/, bNode *node)
{
NodeChroma *c = MEM_cnew<NodeChroma>(__func__);
node->storage = c;
@@ -47,7 +47,7 @@ static void node_composit_init_chroma_matte(bNodeTree *UNUSED(ntree), bNode *nod
c->fstrength = 1.0f;
}
-static void node_composit_buts_chroma_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_chroma_matte(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
@@ -121,7 +121,7 @@ void register_node_type_cmp_chroma_matte()
ntype.declare = file_ns::cmp_node_chroma_matte_declare;
ntype.draw_buttons = file_ns::node_composit_buts_chroma_matte;
ntype.flag |= NODE_PREVIEW;
- node_type_init(&ntype, file_ns::node_composit_init_chroma_matte);
+ ntype.initfunc = file_ns::node_composit_init_chroma_matte;
node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_color_matte.cc b/source/blender/nodes/composite/nodes/node_composite_color_matte.cc
index 08329601f14..9233f61205d 100644
--- a/source/blender/nodes/composite/nodes/node_composite_color_matte.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_color_matte.cc
@@ -32,7 +32,7 @@ static void cmp_node_color_matte_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Matte"));
}
-static void node_composit_init_color_matte(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_color_matte(bNodeTree * /*ntree*/, bNode *node)
{
NodeChroma *c = MEM_cnew<NodeChroma>(__func__);
node->storage = c;
@@ -43,7 +43,7 @@ static void node_composit_init_color_matte(bNodeTree *UNUSED(ntree), bNode *node
c->fstrength = 1.0f;
}
-static void node_composit_buts_color_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_color_matte(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
@@ -119,7 +119,7 @@ void register_node_type_cmp_color_matte()
ntype.declare = file_ns::cmp_node_color_matte_declare;
ntype.draw_buttons = file_ns::node_composit_buts_color_matte;
ntype.flag |= NODE_PREVIEW;
- node_type_init(&ntype, file_ns::node_composit_init_color_matte);
+ ntype.initfunc = file_ns::node_composit_init_color_matte;
node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_color_spill.cc b/source/blender/nodes/composite/nodes/node_composite_color_spill.cc
index 29401d7b20f..cd129d53d6b 100644
--- a/source/blender/nodes/composite/nodes/node_composite_color_spill.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_color_spill.cc
@@ -36,7 +36,7 @@ static void cmp_node_color_spill_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_color_spill(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_color_spill(bNodeTree * /*ntree*/, bNode *node)
{
NodeColorspill *ncs = MEM_cnew<NodeColorspill>(__func__);
node->storage = ncs;
@@ -47,7 +47,7 @@ static void node_composit_init_color_spill(bNodeTree *UNUSED(ntree), bNode *node
ncs->unspill = 0; /* do not use unspill */
}
-static void node_composit_buts_color_spill(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_color_spill(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *row, *col;
@@ -196,7 +196,7 @@ void register_node_type_cmp_color_spill()
cmp_node_type_base(&ntype, CMP_NODE_COLOR_SPILL, "Color Spill", NODE_CLASS_MATTE);
ntype.declare = file_ns::cmp_node_color_spill_declare;
ntype.draw_buttons = file_ns::node_composit_buts_color_spill;
- node_type_init(&ntype, file_ns::node_composit_init_color_spill);
+ ntype.initfunc = file_ns::node_composit_init_color_spill;
node_type_storage(
&ntype, "NodeColorspill", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_colorbalance.cc b/source/blender/nodes/composite/nodes/node_composite_colorbalance.cc
index e05fbf00a25..aade1b639ab 100644
--- a/source/blender/nodes/composite/nodes/node_composite_colorbalance.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_colorbalance.cc
@@ -23,7 +23,7 @@
* (sRGB conversion happens for LGG),
* but this keeps settings comparable. */
-void ntreeCompositColorBalanceSyncFromLGG(bNodeTree *UNUSED(ntree), bNode *node)
+void ntreeCompositColorBalanceSyncFromLGG(bNodeTree * /*ntree*/, bNode *node)
{
NodeColorBalance *n = (NodeColorBalance *)node->storage;
@@ -34,7 +34,7 @@ void ntreeCompositColorBalanceSyncFromLGG(bNodeTree *UNUSED(ntree), bNode *node)
}
}
-void ntreeCompositColorBalanceSyncFromCDL(bNodeTree *UNUSED(ntree), bNode *node)
+void ntreeCompositColorBalanceSyncFromCDL(bNodeTree * /*ntree*/, bNode *node)
{
NodeColorBalance *n = (NodeColorBalance *)node->storage;
@@ -64,7 +64,7 @@ static void cmp_node_colorbalance_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_colorbalance(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_colorbalance(bNodeTree * /*ntree*/, bNode *node)
{
NodeColorBalance *n = MEM_cnew<NodeColorBalance>(__func__);
@@ -78,7 +78,7 @@ static void node_composit_init_colorbalance(bNodeTree *UNUSED(ntree), bNode *nod
node->storage = n;
}
-static void node_composit_buts_colorbalance(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_colorbalance(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *split, *col, *row;
@@ -123,9 +123,7 @@ static void node_composit_buts_colorbalance(uiLayout *layout, bContext *UNUSED(C
}
}
-static void node_composit_buts_colorbalance_ex(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_composit_buts_colorbalance_ex(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "correction_method", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
@@ -212,7 +210,7 @@ void register_node_type_cmp_colorbalance()
ntype.draw_buttons = file_ns::node_composit_buts_colorbalance;
ntype.draw_buttons_ex = file_ns::node_composit_buts_colorbalance_ex;
node_type_size(&ntype, 400, 200, 400);
- node_type_init(&ntype, file_ns::node_composit_init_colorbalance);
+ ntype.initfunc = file_ns::node_composit_init_colorbalance;
node_type_storage(
&ntype, "NodeColorBalance", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_colorcorrection.cc b/source/blender/nodes/composite/nodes/node_composite_colorcorrection.cc
index 92b10fc1877..5ff190ac2e4 100644
--- a/source/blender/nodes/composite/nodes/node_composite_colorcorrection.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_colorcorrection.cc
@@ -35,7 +35,7 @@ static void cmp_node_colorcorrection_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_colorcorrection(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_colorcorrection(bNodeTree * /*ntree*/, bNode *node)
{
NodeColorCorrection *n = MEM_cnew<NodeColorCorrection>(__func__);
n->startmidtones = 0.2f;
@@ -64,9 +64,7 @@ static void node_composit_init_colorcorrection(bNodeTree *UNUSED(ntree), bNode *
node->storage = n;
}
-static void node_composit_buts_colorcorrection(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_composit_buts_colorcorrection(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *row;
@@ -155,7 +153,7 @@ static void node_composit_buts_colorcorrection(uiLayout *layout,
}
static void node_composit_buts_colorcorrection_ex(uiLayout *layout,
- bContext *UNUSED(C),
+ bContext * /*C*/,
PointerRNA *ptr)
{
uiLayout *row;
@@ -355,7 +353,7 @@ void register_node_type_cmp_colorcorrection()
ntype.draw_buttons = file_ns::node_composit_buts_colorcorrection;
ntype.draw_buttons_ex = file_ns::node_composit_buts_colorcorrection_ex;
node_type_size(&ntype, 400, 200, 600);
- node_type_init(&ntype, file_ns::node_composit_init_colorcorrection);
+ ntype.initfunc = file_ns::node_composit_init_colorcorrection;
node_type_storage(
&ntype, "NodeColorCorrection", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_common.cc b/source/blender/nodes/composite/nodes/node_composite_common.cc
index 8dd88d098c4..cd119684a79 100644
--- a/source/blender/nodes/composite/nodes/node_composite_common.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_common.cc
@@ -32,7 +32,7 @@ void register_node_type_cmp_group()
node_type_size(&ntype, 140, 60, 400);
ntype.labelfunc = node_group_label;
- node_type_group_update(&ntype, node_group_update);
+ ntype.group_update_func = node_group_update;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_composite.cc b/source/blender/nodes/composite/nodes/node_composite_composite.cc
index 68061bb434d..24fe4e2d986 100644
--- a/source/blender/nodes/composite/nodes/node_composite_composite.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_composite.cc
@@ -30,7 +30,7 @@ static void cmp_node_composite_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Float>(N_("Z")).default_value(1.0f).min(0.0f).max(1.0f);
}
-static void node_composit_buts_composite(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_composite(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "use_alpha", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc b/source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc
index e36da39cca1..24928acedd9 100644
--- a/source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc
@@ -24,7 +24,7 @@ static void CMP_NODE_CONVERT_COLOR_SPACE_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_convert_colorspace(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_convert_colorspace(bNodeTree * /*ntree*/, bNode *node)
{
NodeConvertColorSpace *ncs = static_cast<NodeConvertColorSpace *>(
MEM_callocN(sizeof(NodeConvertColorSpace), "node colorspace"));
@@ -42,7 +42,7 @@ static void node_composit_init_convert_colorspace(bNodeTree *UNUSED(ntree), bNod
}
static void node_composit_buts_convert_colorspace(uiLayout *layout,
- bContext *UNUSED(C),
+ bContext * /*C*/,
PointerRNA *ptr)
{
uiItemR(layout, ptr, "from_color_space", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
@@ -78,7 +78,7 @@ void register_node_type_cmp_convert_color_space(void)
ntype.declare = file_ns::CMP_NODE_CONVERT_COLOR_SPACE_declare;
ntype.draw_buttons = file_ns::node_composit_buts_convert_colorspace;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, file_ns::node_composit_init_convert_colorspace);
+ ntype.initfunc = file_ns::node_composit_init_convert_colorspace;
node_type_storage(
&ntype, "NodeConvertColorSpace", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_crop.cc b/source/blender/nodes/composite/nodes/node_composite_crop.cc
index 13d02a707be..4539d2af92d 100644
--- a/source/blender/nodes/composite/nodes/node_composite_crop.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_crop.cc
@@ -37,7 +37,7 @@ static void cmp_node_crop_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_crop(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_crop(bNodeTree * /*ntree*/, bNode *node)
{
NodeTwoXYs *nxy = MEM_cnew<NodeTwoXYs>(__func__);
node->storage = nxy;
@@ -47,7 +47,7 @@ static void node_composit_init_crop(bNodeTree *UNUSED(ntree), bNode *node)
nxy->y2 = 0;
}
-static void node_composit_buts_crop(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_crop(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
@@ -230,7 +230,7 @@ void register_node_type_cmp_crop()
cmp_node_type_base(&ntype, CMP_NODE_CROP, "Crop", NODE_CLASS_DISTORT);
ntype.declare = file_ns::cmp_node_crop_declare;
ntype.draw_buttons = file_ns::node_composit_buts_crop;
- node_type_init(&ntype, file_ns::node_composit_init_crop);
+ ntype.initfunc = file_ns::node_composit_init_crop;
node_type_storage(&ntype, "NodeTwoXYs", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc
index 7e5544381a4..e95a306976c 100644
--- a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc
@@ -234,7 +234,7 @@ static bNodeSocketTemplate cmp_node_cryptomatte_out[] = {
{-1, ""},
};
-static void node_init_cryptomatte(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init_cryptomatte(bNodeTree * /*ntree*/, bNode *node)
{
NodeCryptomatte *user = MEM_cnew<NodeCryptomatte>(__func__);
node->storage = user;
@@ -262,7 +262,7 @@ static void node_free_cryptomatte(bNode *node)
}
}
-static void node_copy_cryptomatte(bNodeTree *UNUSED(dest_ntree),
+static void node_copy_cryptomatte(bNodeTree * /*dst_ntree*/,
bNode *dest_node,
const bNode *src_node)
{
@@ -275,7 +275,7 @@ static void node_copy_cryptomatte(bNodeTree *UNUSED(dest_ntree),
dest_node->storage = dest_nc;
}
-static bool node_poll_cryptomatte(bNodeType *UNUSED(ntype),
+static bool node_poll_cryptomatte(bNodeType * /*ntype*/,
bNodeTree *ntree,
const char **r_disabled_hint)
{
@@ -331,7 +331,7 @@ void register_node_type_cmp_cryptomatte()
node_type_socket_templates(
&ntype, file_ns::cmp_node_cryptomatte_in, file_ns::cmp_node_cryptomatte_out);
node_type_size(&ntype, 240, 100, 700);
- node_type_init(&ntype, file_ns::node_init_cryptomatte);
+ ntype.initfunc = file_ns::node_init_cryptomatte;
ntype.initfunc_api = file_ns::node_init_api_cryptomatte;
ntype.poll = file_ns::node_poll_cryptomatte;
node_type_storage(
@@ -415,9 +415,10 @@ void register_node_type_cmp_cryptomatte_legacy()
static bNodeType ntype;
- cmp_node_type_base(&ntype, CMP_NODE_CRYPTOMATTE_LEGACY, "Cryptomatte", NODE_CLASS_MATTE);
+ cmp_node_type_base(
+ &ntype, CMP_NODE_CRYPTOMATTE_LEGACY, "Cryptomatte (Legacy)", NODE_CLASS_MATTE);
node_type_socket_templates(&ntype, nullptr, file_ns::cmp_node_cryptomatte_out);
- node_type_init(&ntype, legacy_file_ns::node_init_cryptomatte_legacy);
+ ntype.initfunc = legacy_file_ns::node_init_cryptomatte_legacy;
node_type_storage(
&ntype, "NodeCryptomatte", file_ns::node_free_cryptomatte, file_ns::node_copy_cryptomatte);
ntype.gather_link_search_ops = nullptr;
diff --git a/source/blender/nodes/composite/nodes/node_composite_curves.cc b/source/blender/nodes/composite/nodes/node_composite_curves.cc
index bf45e219730..5799c6c1a09 100644
--- a/source/blender/nodes/composite/nodes/node_composite_curves.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_curves.cc
@@ -29,7 +29,7 @@ static void cmp_node_time_declare(NodeDeclarationBuilder &b)
}
/* custom1 = start_frame, custom2 = end_frame */
-static void node_composit_init_curves_time(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_curves_time(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = 1;
node->custom2 = 250;
@@ -80,8 +80,7 @@ class TimeCurveOperation : public NodeOperation {
if (get_start_time() == get_end_time()) {
return 0.0f;
}
- return static_cast<float>(frame_number - get_start_time()) /
- static_cast<float>(get_end_time() - get_start_time());
+ return float(frame_number - get_start_time()) / float(get_end_time() - get_start_time());
}
};
@@ -101,7 +100,7 @@ void register_node_type_cmp_curve_time()
cmp_node_type_base(&ntype, CMP_NODE_TIME, "Time Curve", NODE_CLASS_INPUT);
ntype.declare = file_ns::cmp_node_time_declare;
node_type_size(&ntype, 200, 140, 320);
- node_type_init(&ntype, file_ns::node_composit_init_curves_time);
+ ntype.initfunc = file_ns::node_composit_init_curves_time;
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
@@ -122,12 +121,12 @@ static void cmp_node_curve_vec_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Vector"));
}
-static void node_composit_init_curve_vec(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_curve_vec(bNodeTree * /*ntree*/, bNode *node)
{
node->storage = BKE_curvemapping_add(3, -1.0f, -1.0f, 1.0f, 1.0f);
}
-static void node_buts_curvevec(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_buts_curvevec(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiTemplateCurveMapping(layout, ptr, "mapping", 'v', false, false, false, false);
}
@@ -196,7 +195,7 @@ void register_node_type_cmp_curve_vec()
ntype.declare = file_ns::cmp_node_curve_vec_declare;
ntype.draw_buttons = file_ns::node_buts_curvevec;
node_type_size(&ntype, 200, 140, 320);
- node_type_init(&ntype, file_ns::node_composit_init_curve_vec);
+ ntype.initfunc = file_ns::node_composit_init_curve_vec;
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
@@ -223,7 +222,7 @@ static void cmp_node_rgbcurves_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_curve_rgb(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_curve_rgb(bNodeTree * /*ntree*/, bNode *node)
{
node->storage = BKE_curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f);
}
@@ -333,7 +332,7 @@ void register_node_type_cmp_curve_rgb()
cmp_node_type_base(&ntype, CMP_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR);
ntype.declare = file_ns::cmp_node_rgbcurves_declare;
node_type_size(&ntype, 200, 140, 320);
- node_type_init(&ntype, file_ns::node_composit_init_curve_rgb);
+ ntype.initfunc = file_ns::node_composit_init_curve_rgb;
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_defocus.cc b/source/blender/nodes/composite/nodes/node_composite_defocus.cc
index 94b4908a1bd..584cca87740 100644
--- a/source/blender/nodes/composite/nodes/node_composite_defocus.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_defocus.cc
@@ -27,7 +27,7 @@ static void cmp_node_defocus_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_defocus(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_defocus(bNodeTree * /*ntree*/, bNode *node)
{
/* defocus node */
NodeDefocus *nbd = MEM_cnew<NodeDefocus>(__func__);
@@ -111,7 +111,7 @@ void register_node_type_cmp_defocus()
cmp_node_type_base(&ntype, CMP_NODE_DEFOCUS, "Defocus", NODE_CLASS_OP_FILTER);
ntype.declare = file_ns::cmp_node_defocus_declare;
ntype.draw_buttons = file_ns::node_composit_buts_defocus;
- node_type_init(&ntype, file_ns::node_composit_init_defocus);
+ ntype.initfunc = file_ns::node_composit_init_defocus;
node_type_storage(&ntype, "NodeDefocus", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_denoise.cc b/source/blender/nodes/composite/nodes/node_composite_denoise.cc
index 0452e7cd943..9ae02dab505 100644
--- a/source/blender/nodes/composite/nodes/node_composite_denoise.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_denoise.cc
@@ -28,7 +28,7 @@ static void cmp_node_denoise_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_denonise(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_denonise(bNodeTree * /*ntree*/, bNode *node)
{
NodeDenoise *ndg = MEM_cnew<NodeDenoise>(__func__);
ndg->hdr = true;
@@ -36,7 +36,7 @@ static void node_composit_init_denonise(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = ndg;
}
-static void node_composit_buts_denoise(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_denoise(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
#ifndef WITH_OPENIMAGEDENOISE
uiItemL(layout, IFACE_("Disabled, built without OpenImageDenoise"), ICON_ERROR);
@@ -82,7 +82,7 @@ void register_node_type_cmp_denoise()
cmp_node_type_base(&ntype, CMP_NODE_DENOISE, "Denoise", NODE_CLASS_OP_FILTER);
ntype.declare = file_ns::cmp_node_denoise_declare;
ntype.draw_buttons = file_ns::node_composit_buts_denoise;
- node_type_init(&ntype, file_ns::node_composit_init_denonise);
+ ntype.initfunc = file_ns::node_composit_init_denonise;
node_type_storage(&ntype, "NodeDenoise", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_despeckle.cc b/source/blender/nodes/composite/nodes/node_composite_despeckle.cc
index aa6725b8750..28ef022459b 100644
--- a/source/blender/nodes/composite/nodes/node_composite_despeckle.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_despeckle.cc
@@ -33,13 +33,13 @@ static void cmp_node_despeckle_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_despeckle(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_despeckle(bNodeTree * /*ntree*/, bNode *node)
{
node->custom3 = 0.5f;
node->custom4 = 0.5f;
}
-static void node_composit_buts_despeckle(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_despeckle(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
@@ -115,7 +115,7 @@ void register_node_type_cmp_despeckle()
ntype.declare = file_ns::cmp_node_despeckle_declare;
ntype.draw_buttons = file_ns::node_composit_buts_despeckle;
ntype.flag |= NODE_PREVIEW;
- node_type_init(&ntype, file_ns::node_composit_init_despeckle);
+ ntype.initfunc = file_ns::node_composit_init_despeckle;
ntype.get_compositor_operation = file_ns::get_compositor_operation;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/composite/nodes/node_composite_diff_matte.cc b/source/blender/nodes/composite/nodes/node_composite_diff_matte.cc
index 8912d00a9be..c3fb0885c4d 100644
--- a/source/blender/nodes/composite/nodes/node_composite_diff_matte.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_diff_matte.cc
@@ -32,7 +32,7 @@ static void cmp_node_diff_matte_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Matte"));
}
-static void node_composit_init_diff_matte(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_diff_matte(bNodeTree * /*ntree*/, bNode *node)
{
NodeChroma *c = MEM_cnew<NodeChroma>(__func__);
node->storage = c;
@@ -40,7 +40,7 @@ static void node_composit_init_diff_matte(bNodeTree *UNUSED(ntree), bNode *node)
c->t2 = 0.1f;
}
-static void node_composit_buts_diff_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_diff_matte(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
@@ -101,7 +101,7 @@ void register_node_type_cmp_diff_matte()
ntype.declare = file_ns::cmp_node_diff_matte_declare;
ntype.draw_buttons = file_ns::node_composit_buts_diff_matte;
ntype.flag |= NODE_PREVIEW;
- node_type_init(&ntype, file_ns::node_composit_init_diff_matte);
+ ntype.initfunc = file_ns::node_composit_init_diff_matte;
node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_dilate.cc b/source/blender/nodes/composite/nodes/node_composite_dilate.cc
index 551dfacb276..cc4e09d4d0d 100644
--- a/source/blender/nodes/composite/nodes/node_composite_dilate.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_dilate.cc
@@ -5,25 +5,20 @@
* \ingroup cmpnodes
*/
-#include <cmath>
-
-#include "BLI_array.hh"
#include "BLI_assert.h"
#include "BLI_math_base.hh"
-
-#include "DNA_scene_types.h"
+#include "BLI_math_vec_types.hh"
#include "RNA_access.h"
#include "UI_interface.h"
#include "UI_resources.h"
-#include "RE_pipeline.h"
-
#include "GPU_shader.h"
#include "GPU_state.h"
#include "GPU_texture.h"
+#include "COM_morphological_distance_feather_weights.hh"
#include "COM_node_operation.hh"
#include "COM_utilities.hh"
@@ -41,14 +36,14 @@ static void cmp_node_dilate_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Mask"));
}
-static void node_composit_init_dilateerode(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_dilateerode(bNodeTree * /*ntree*/, bNode *node)
{
NodeDilateErode *data = MEM_cnew<NodeDilateErode>(__func__);
data->falloff = PROP_SMOOTH;
node->storage = data;
}
-static void node_composit_buts_dilateerode(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_dilateerode(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
uiItemR(layout, ptr, "distance", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
@@ -64,161 +59,7 @@ static void node_composit_buts_dilateerode(uiLayout *layout, bContext *UNUSED(C)
using namespace blender::realtime_compositor;
-/* Computes a falloff that is equal to 1 at an input of zero and decrease to zero at an input of 1,
- * with the rate of decrease depending on the falloff type. */
-static float compute_distance_falloff(float x, int falloff_type)
-{
- x = 1.0f - x;
-
- switch (falloff_type) {
- case PROP_SMOOTH:
- return 3.0f * x * x - 2.0f * x * x * x;
- case PROP_SPHERE:
- return std::sqrt(2.0f * x - x * x);
- case PROP_ROOT:
- return std::sqrt(x);
- case PROP_SHARP:
- return x * x;
- case PROP_INVSQUARE:
- return x * (2.0f - x);
- case PROP_LIN:
- return x;
- default:
- BLI_assert_unreachable();
- return x;
- }
-}
-
-/* A helper class that computes and caches 1D GPU textures containing the weights of the separable
- * Gaussian filter of the given radius as well as an inverse distance falloff of the given type and
- * radius. The weights and falloffs are symmetric, because the Gaussian and falloff functions are
- * all even functions. Consequently, only the positive half of the filter is computed and the
- * shader takes that into consideration. */
-class SymmetricSeparableMorphologicalDistanceFeatherWeights {
- private:
- int radius_ = 1;
- int falloff_type_ = PROP_SMOOTH;
- GPUTexture *weights_texture_ = nullptr;
- GPUTexture *distance_falloffs_texture_ = nullptr;
-
- public:
- ~SymmetricSeparableMorphologicalDistanceFeatherWeights()
- {
- if (weights_texture_) {
- GPU_texture_free(weights_texture_);
- }
-
- if (distance_falloffs_texture_) {
- GPU_texture_free(distance_falloffs_texture_);
- }
- }
-
- /* Check if textures containing the weights and distance falloffs were already computed for the
- * given distance falloff type and radius. If such textures exists, do nothing, otherwise, free
- * the already computed textures and recompute it with the given distance falloff type and
- * radius. */
- void update(int radius, int falloff_type)
- {
- if (weights_texture_ && distance_falloffs_texture_ && falloff_type == falloff_type_ &&
- radius == radius_) {
- return;
- }
-
- radius_ = radius;
- falloff_type_ = falloff_type;
-
- compute_weights();
- compute_distance_falloffs();
- }
-
- void compute_weights()
- {
- if (weights_texture_) {
- GPU_texture_free(weights_texture_);
- }
-
- /* The size of filter is double the radius plus 1, but since the filter is symmetric, we only
- * compute half of it and no doubling happens. We add 1 to make sure the filter size is always
- * odd and there is a center weight. */
- const int size = radius_ + 1;
- Array<float> weights(size);
-
- float sum = 0.0f;
-
- /* First, compute the center weight. */
- const float center_weight = RE_filter_value(R_FILTER_GAUSS, 0.0f);
- weights[0] = center_weight;
- sum += center_weight;
-
- /* Second, compute the other weights in the positive direction, making sure to add double the
- * weight to the sum of weights because the filter is symmetric and we only loop over half of
- * it. Skip the center weight already computed by dropping the front index. */
- const float scale = radius_ > 0.0f ? 1.0f / radius_ : 0.0f;
- for (const int i : weights.index_range().drop_front(1)) {
- const float weight = RE_filter_value(R_FILTER_GAUSS, i * scale);
- weights[i] = weight;
- sum += weight * 2.0f;
- }
-
- /* Finally, normalize the weights. */
- for (const int i : weights.index_range()) {
- weights[i] /= sum;
- }
-
- weights_texture_ = GPU_texture_create_1d("Weights", size, 1, GPU_R16F, weights.data());
- }
-
- void compute_distance_falloffs()
- {
- if (distance_falloffs_texture_) {
- GPU_texture_free(distance_falloffs_texture_);
- }
-
- /* The size of the distance falloffs is double the radius plus 1, but since the falloffs are
- * symmetric, we only compute half of them and no doubling happens. We add 1 to make sure the
- * falloffs size is always odd and there is a center falloff. */
- const int size = radius_ + 1;
- Array<float> falloffs(size);
-
- /* Compute the distance falloffs in the positive direction only, because the falloffs are
- * symmetric. */
- const float scale = radius_ > 0.0f ? 1.0f / radius_ : 0.0f;
- for (const int i : falloffs.index_range()) {
- falloffs[i] = compute_distance_falloff(i * scale, falloff_type_);
- }
-
- distance_falloffs_texture_ = GPU_texture_create_1d(
- "Distance Factors", size, 1, GPU_R16F, falloffs.data());
- }
-
- void bind_weights_as_texture(GPUShader *shader, const char *texture_name)
- {
- const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name);
- GPU_texture_bind(weights_texture_, texture_image_unit);
- }
-
- void unbind_weights_as_texture()
- {
- GPU_texture_unbind(weights_texture_);
- }
-
- void bind_distance_falloffs_as_texture(GPUShader *shader, const char *texture_name)
- {
- const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name);
- GPU_texture_bind(distance_falloffs_texture_, texture_image_unit);
- }
-
- void unbind_distance_falloffs_as_texture()
- {
- GPU_texture_unbind(distance_falloffs_texture_);
- }
-};
-
class DilateErodeOperation : public NodeOperation {
- private:
- /* Cached symmetric blur weights and distance falloffs for the distance feature method. */
- SymmetricSeparableMorphologicalDistanceFeatherWeights distance_feather_weights_;
-
public:
using NodeOperation::NodeOperation;
@@ -393,7 +234,7 @@ class DilateErodeOperation : public NodeOperation {
/* See the discussion in the implementation for more information. */
int get_morphological_distance_threshold_radius()
{
- return static_cast<int>(math::ceil(get_inset())) + math::abs(get_distance());
+ return int(math::ceil(get_inset())) + math::abs(get_distance());
}
/* ----------------------------------------
@@ -414,9 +255,11 @@ class DilateErodeOperation : public NodeOperation {
const Result &input_image = get_input("Mask");
input_image.bind_as_texture(shader, "input_tx");
- distance_feather_weights_.update(math::abs(get_distance()), node_storage(bnode()).falloff);
- distance_feather_weights_.bind_weights_as_texture(shader, "weights_tx");
- distance_feather_weights_.bind_distance_falloffs_as_texture(shader, "falloffs_tx");
+ const MorphologicalDistanceFeatherWeights &weights =
+ context().cache_manager().get_morphological_distance_feather_weights(
+ node_storage(bnode()).falloff, math::abs(get_distance()));
+ weights.bind_weights_as_texture(shader, "weights_tx");
+ weights.bind_distance_falloffs_as_texture(shader, "falloffs_tx");
/* We allocate an output image of a transposed size, that is, with a height equivalent to the
* width of the input and vice versa. This is done as a performance optimization. The shader
@@ -437,8 +280,8 @@ class DilateErodeOperation : public NodeOperation {
GPU_shader_unbind();
input_image.unbind_as_texture();
- distance_feather_weights_.unbind_weights_as_texture();
- distance_feather_weights_.unbind_distance_falloffs_as_texture();
+ weights.unbind_weights_as_texture();
+ weights.unbind_distance_falloffs_as_texture();
GPU_texture_image_unbind(horizontal_pass_result);
return horizontal_pass_result;
@@ -453,9 +296,11 @@ class DilateErodeOperation : public NodeOperation {
const int texture_image_unit = GPU_shader_get_texture_binding(shader, "input_tx");
GPU_texture_bind(horizontal_pass_result, texture_image_unit);
- distance_feather_weights_.update(math::abs(get_distance()), node_storage(bnode()).falloff);
- distance_feather_weights_.bind_weights_as_texture(shader, "weights_tx");
- distance_feather_weights_.bind_distance_falloffs_as_texture(shader, "falloffs_tx");
+ const MorphologicalDistanceFeatherWeights &weights =
+ context().cache_manager().get_morphological_distance_feather_weights(
+ node_storage(bnode()).falloff, math::abs(get_distance()));
+ weights.bind_weights_as_texture(shader, "weights_tx");
+ weights.bind_distance_falloffs_as_texture(shader, "falloffs_tx");
const Domain domain = compute_domain();
Result &output_image = get_result("Mask");
@@ -468,8 +313,8 @@ class DilateErodeOperation : public NodeOperation {
GPU_shader_unbind();
output_image.unbind_as_image();
- distance_feather_weights_.unbind_weights_as_texture();
- distance_feather_weights_.unbind_distance_falloffs_as_texture();
+ weights.unbind_weights_as_texture();
+ weights.unbind_distance_falloffs_as_texture();
GPU_texture_unbind(horizontal_pass_result);
}
@@ -535,7 +380,7 @@ void register_node_type_cmp_dilateerode()
cmp_node_type_base(&ntype, CMP_NODE_DILATEERODE, "Dilate/Erode", NODE_CLASS_OP_FILTER);
ntype.draw_buttons = file_ns::node_composit_buts_dilateerode;
ntype.declare = file_ns::cmp_node_dilate_declare;
- node_type_init(&ntype, file_ns::node_composit_init_dilateerode);
+ ntype.initfunc = file_ns::node_composit_init_dilateerode;
node_type_storage(
&ntype, "NodeDilateErode", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_directionalblur.cc b/source/blender/nodes/composite/nodes/node_composite_directionalblur.cc
index 6e6bec70283..452c83ef1b5 100644
--- a/source/blender/nodes/composite/nodes/node_composite_directionalblur.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_directionalblur.cc
@@ -32,7 +32,7 @@ static void cmp_node_directional_blur_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_dblur(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_dblur(bNodeTree * /*ntree*/, bNode *node)
{
NodeDBlurData *ndbd = MEM_cnew<NodeDBlurData>(__func__);
node->storage = ndbd;
@@ -41,7 +41,7 @@ static void node_composit_init_dblur(bNodeTree *UNUSED(ntree), bNode *node)
ndbd->center_y = 0.5;
}
-static void node_composit_buts_dblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_dblur(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
@@ -199,7 +199,7 @@ void register_node_type_cmp_dblur()
cmp_node_type_base(&ntype, CMP_NODE_DBLUR, "Directional Blur", NODE_CLASS_OP_FILTER);
ntype.declare = file_ns::cmp_node_directional_blur_declare;
ntype.draw_buttons = file_ns::node_composit_buts_dblur;
- node_type_init(&ntype, file_ns::node_composit_init_dblur);
+ ntype.initfunc = file_ns::node_composit_init_dblur;
node_type_storage(
&ntype, "NodeDBlurData", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_distance_matte.cc b/source/blender/nodes/composite/nodes/node_composite_distance_matte.cc
index 6a786571f43..16f79f4e730 100644
--- a/source/blender/nodes/composite/nodes/node_composite_distance_matte.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_distance_matte.cc
@@ -32,7 +32,7 @@ static void cmp_node_distance_matte_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Matte"));
}
-static void node_composit_init_distance_matte(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_distance_matte(bNodeTree * /*ntree*/, bNode *node)
{
NodeChroma *c = MEM_cnew<NodeChroma>(__func__);
node->storage = c;
@@ -41,9 +41,7 @@ static void node_composit_init_distance_matte(bNodeTree *UNUSED(ntree), bNode *n
c->t2 = 0.1f;
}
-static void node_composit_buts_distance_matte(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_composit_buts_distance_matte(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col, *row;
@@ -125,7 +123,7 @@ void register_node_type_cmp_distance_matte()
ntype.declare = file_ns::cmp_node_distance_matte_declare;
ntype.draw_buttons = file_ns::node_composit_buts_distance_matte;
ntype.flag |= NODE_PREVIEW;
- node_type_init(&ntype, file_ns::node_composit_init_distance_matte);
+ ntype.initfunc = file_ns::node_composit_init_distance_matte;
node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_double_edge_mask.cc b/source/blender/nodes/composite/nodes/node_composite_double_edge_mask.cc
index fec7879ed78..553058cf545 100644
--- a/source/blender/nodes/composite/nodes/node_composite_double_edge_mask.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_double_edge_mask.cc
@@ -24,7 +24,7 @@ static void cmp_node_double_edge_mask_declare(NodeDeclarationBuilder &b)
}
static void node_composit_buts_double_edge_mask(uiLayout *layout,
- bContext *UNUSED(C),
+ bContext * /*C*/,
PointerRNA *ptr)
{
uiLayout *col;
diff --git a/source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc b/source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc
index 7c031b354e5..f06b64f10b5 100644
--- a/source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc
@@ -32,7 +32,7 @@ static void cmp_node_ellipsemask_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Mask"));
}
-static void node_composit_init_ellipsemask(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_ellipsemask(bNodeTree * /*ntree*/, bNode *node)
{
NodeEllipseMask *data = MEM_cnew<NodeEllipseMask>(__func__);
data->x = 0.5;
@@ -43,7 +43,7 @@ static void node_composit_init_ellipsemask(bNodeTree *UNUSED(ntree), bNode *node
node->storage = data;
}
-static void node_composit_buts_ellipsemask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_ellipsemask(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *row;
row = uiLayoutRow(layout, true);
@@ -156,7 +156,7 @@ void register_node_type_cmp_ellipsemask()
ntype.declare = file_ns::cmp_node_ellipsemask_declare;
ntype.draw_buttons = file_ns::node_composit_buts_ellipsemask;
node_type_size(&ntype, 260, 110, 320);
- node_type_init(&ntype, file_ns::node_composit_init_ellipsemask);
+ ntype.initfunc = file_ns::node_composit_init_ellipsemask;
node_type_storage(
&ntype, "NodeEllipseMask", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_filter.cc b/source/blender/nodes/composite/nodes/node_composite_filter.cc
index bd7b443e17e..816d1009ffe 100644
--- a/source/blender/nodes/composite/nodes/node_composite_filter.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_filter.cc
@@ -33,7 +33,7 @@ static void cmp_node_filter_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_buts_filter(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_filter(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "filter_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_flip.cc b/source/blender/nodes/composite/nodes/node_composite_flip.cc
index aaa2b565ed2..07c96eb4d22 100644
--- a/source/blender/nodes/composite/nodes/node_composite_flip.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_flip.cc
@@ -31,7 +31,7 @@ static void cmp_node_flip_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_buts_flip(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_flip(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "axis", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_glare.cc b/source/blender/nodes/composite/nodes/node_composite_glare.cc
index 33577d5caf8..4352f519e4c 100644
--- a/source/blender/nodes/composite/nodes/node_composite_glare.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_glare.cc
@@ -22,7 +22,7 @@ static void cmp_node_glare_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_glare(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_glare(bNodeTree * /*ntree*/, bNode *node)
{
NodeGlare *ndg = MEM_cnew<NodeGlare>(__func__);
ndg->quality = 1;
@@ -39,7 +39,7 @@ static void node_composit_init_glare(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = ndg;
}
-static void node_composit_buts_glare(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_glare(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "glare_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
uiItemR(layout, ptr, "quality", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
@@ -105,7 +105,7 @@ void register_node_type_cmp_glare()
cmp_node_type_base(&ntype, CMP_NODE_GLARE, "Glare", NODE_CLASS_OP_FILTER);
ntype.declare = file_ns::cmp_node_glare_declare;
ntype.draw_buttons = file_ns::node_composit_buts_glare;
- node_type_init(&ntype, file_ns::node_composit_init_glare);
+ ntype.initfunc = file_ns::node_composit_init_glare;
node_type_storage(&ntype, "NodeGlare", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_huecorrect.cc b/source/blender/nodes/composite/nodes/node_composite_huecorrect.cc
index 6333860a19b..2e09e44eddc 100644
--- a/source/blender/nodes/composite/nodes/node_composite_huecorrect.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_huecorrect.cc
@@ -31,7 +31,7 @@ static void cmp_node_huecorrect_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_huecorrect(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_huecorrect(bNodeTree * /*ntree*/, bNode *node)
{
node->storage = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
@@ -106,7 +106,7 @@ void register_node_type_cmp_huecorrect()
cmp_node_type_base(&ntype, CMP_NODE_HUECORRECT, "Hue Correct", NODE_CLASS_OP_COLOR);
ntype.declare = file_ns::cmp_node_huecorrect_declare;
node_type_size(&ntype, 320, 140, 500);
- node_type_init(&ntype, file_ns::node_composit_init_huecorrect);
+ ntype.initfunc = file_ns::node_composit_init_huecorrect;
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_id_mask.cc b/source/blender/nodes/composite/nodes/node_composite_id_mask.cc
index ac8456cb931..a71b3f132c0 100644
--- a/source/blender/nodes/composite/nodes/node_composite_id_mask.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_id_mask.cc
@@ -22,7 +22,7 @@ static void cmp_node_idmask_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Alpha"));
}
-static void node_composit_buts_id_mask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_id_mask(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "index", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
uiItemR(layout, ptr, "use_antialiasing", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.cc b/source/blender/nodes/composite/nodes/node_composite_image.cc
index 4d1eff0b940..322f1eecf91 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_image.cc
@@ -80,7 +80,7 @@ static void cmp_node_image_add_pass_output(bNodeTree *ntree,
const char *passname,
int rres_index,
eNodeSocketDatatype type,
- int UNUSED(is_rlayers),
+ int /*is_rlayers*/,
LinkNodePair *available_sockets,
int *prev_index)
{
@@ -273,8 +273,8 @@ static void cmp_node_rlayer_create_outputs_cb(void *userdata,
Scene *scene,
ViewLayer *view_layer,
const char *name,
- int UNUSED(channels),
- const char *UNUSED(chanid),
+ int /*channels*/,
+ const char * /*chanid*/,
eNodeSocketDatatype type)
{
CreateOutputUserData &data = *(CreateOutputUserData *)userdata;
@@ -426,7 +426,7 @@ static void node_composit_free_image(bNode *node)
MEM_freeN(node->storage);
}
-static void node_composit_copy_image(bNodeTree *UNUSED(dest_ntree),
+static void node_composit_copy_image(bNodeTree * /*dst_ntree*/,
bNode *dest_node,
const bNode *src_node)
{
@@ -660,10 +660,10 @@ void register_node_type_cmp_image()
static bNodeType ntype;
cmp_node_type_base(&ntype, CMP_NODE_IMAGE, "Image", NODE_CLASS_INPUT);
- node_type_init(&ntype, file_ns::node_composit_init_image);
+ ntype.initfunc = file_ns::node_composit_init_image;
node_type_storage(
&ntype, "ImageUser", file_ns::node_composit_free_image, file_ns::node_composit_copy_image);
- node_type_update(&ntype, file_ns::cmp_node_image_update);
+ ntype.updatefunc = file_ns::cmp_node_image_update;
ntype.get_compositor_operation = file_ns::get_compositor_operation;
ntype.labelfunc = node_image_label;
ntype.flag |= NODE_PREVIEW;
@@ -685,7 +685,7 @@ const char *node_cmp_rlayers_sock_to_pass(int sock_index)
}
const char *name = cmp_node_rlayers_out[sock_index].name;
/* Exception for alpha, which is derived from Combined. */
- return (STREQ(name, "Alpha")) ? RE_PASSNAME_COMBINED : name;
+ return STREQ(name, "Alpha") ? RE_PASSNAME_COMBINED : name;
}
namespace blender::nodes::node_composite_render_layer_cc {
@@ -710,7 +710,7 @@ static void node_composit_init_rlayers(const bContext *C, PointerRNA *ptr)
}
}
-static bool node_composit_poll_rlayers(bNodeType *UNUSED(ntype),
+static bool node_composit_poll_rlayers(bNodeType * /*ntype*/,
bNodeTree *ntree,
const char **r_disabled_hint)
{
@@ -749,7 +749,7 @@ static void node_composit_free_rlayers(bNode *node)
}
}
-static void node_composit_copy_rlayers(bNodeTree *UNUSED(dest_ntree),
+static void node_composit_copy_rlayers(bNodeTree * /*dst_ntree*/,
bNode *dest_node,
const bNode *src_node)
{
@@ -797,8 +797,7 @@ static void node_composit_buts_viewlayers(uiLayout *layout, bContext *C, Pointer
PropertyRNA *prop = RNA_struct_find_property(ptr, "layer");
const char *layer_name;
- if (!(RNA_property_enum_identifier(
- C, ptr, prop, RNA_property_enum_get(ptr, prop), &layer_name))) {
+ if (!RNA_property_enum_identifier(C, ptr, prop, RNA_property_enum_get(ptr, prop), &layer_name)) {
return;
}
@@ -851,7 +850,7 @@ class RenderLayerOperation : public NodeOperation {
/* Other output passes are not supported for now, so allocate them as invalid. */
for (const bNodeSocket *output : this->node()->output_sockets()) {
- if (!STREQ(output->identifier, "Image") && !STREQ(output->identifier, "Alpha")) {
+ if (!STR_ELEM(output->identifier, "Image", "Alpha")) {
get_result(output->identifier).allocate_invalid();
}
}
@@ -880,8 +879,8 @@ void register_node_type_cmp_rlayers()
ntype.flag |= NODE_PREVIEW;
node_type_storage(
&ntype, nullptr, file_ns::node_composit_free_rlayers, file_ns::node_composit_copy_rlayers);
- node_type_update(&ntype, file_ns::cmp_node_rlayers_update);
- node_type_init(&ntype, node_cmp_rlayers_outputs);
+ ntype.updatefunc = file_ns::cmp_node_rlayers_update;
+ ntype.initfunc = node_cmp_rlayers_outputs;
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/composite/nodes/node_composite_inpaint.cc b/source/blender/nodes/composite/nodes/node_composite_inpaint.cc
index f6e46bef299..c26021b16bd 100644
--- a/source/blender/nodes/composite/nodes/node_composite_inpaint.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_inpaint.cc
@@ -22,7 +22,7 @@ static void cmp_node_inpaint_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_buts_inpaint(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_inpaint(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "distance", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_invert.cc b/source/blender/nodes/composite/nodes/node_composite_invert.cc
index 4bfcc7b6b9c..c8787ebb01b 100644
--- a/source/blender/nodes/composite/nodes/node_composite_invert.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_invert.cc
@@ -32,12 +32,12 @@ static void cmp_node_invert_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Color"));
}
-static void node_composit_init_invert(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_invert(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 |= CMP_CHAN_RGB;
}
-static void node_composit_buts_invert(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_invert(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
@@ -96,7 +96,7 @@ void register_node_type_cmp_invert()
cmp_node_type_base(&ntype, CMP_NODE_INVERT, "Invert", NODE_CLASS_OP_COLOR);
ntype.declare = file_ns::cmp_node_invert_declare;
ntype.draw_buttons = file_ns::node_composit_buts_invert;
- node_type_init(&ntype, file_ns::node_composit_init_invert);
+ ntype.initfunc = file_ns::node_composit_init_invert;
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/composite/nodes/node_composite_keying.cc b/source/blender/nodes/composite/nodes/node_composite_keying.cc
index 8b584e216cd..b2add06c541 100644
--- a/source/blender/nodes/composite/nodes/node_composite_keying.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_keying.cc
@@ -33,7 +33,7 @@ static void cmp_node_keying_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Edges"));
}
-static void node_composit_init_keying(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_keying(bNodeTree * /*ntree*/, bNode *node)
{
NodeKeyingData *data = MEM_cnew<NodeKeyingData>(__func__);
@@ -47,7 +47,7 @@ static void node_composit_init_keying(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = data;
}
-static void node_composit_buts_keying(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_keying(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
/* bNode *node = (bNode*)ptr->data; */ /* UNUSED */
@@ -95,7 +95,7 @@ void register_node_type_cmp_keying()
cmp_node_type_base(&ntype, CMP_NODE_KEYING, "Keying", NODE_CLASS_MATTE);
ntype.declare = file_ns::cmp_node_keying_declare;
ntype.draw_buttons = file_ns::node_composit_buts_keying;
- node_type_init(&ntype, file_ns::node_composit_init_keying);
+ ntype.initfunc = file_ns::node_composit_init_keying;
node_type_storage(
&ntype, "NodeKeyingData", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_lensdist.cc b/source/blender/nodes/composite/nodes/node_composite_lensdist.cc
index 260fccf66d0..e11ed0fbfb6 100644
--- a/source/blender/nodes/composite/nodes/node_composite_lensdist.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_lensdist.cc
@@ -52,14 +52,14 @@ static void cmp_node_lensdist_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_lensdist(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_lensdist(bNodeTree * /*ntree*/, bNode *node)
{
NodeLensDist *nld = MEM_cnew<NodeLensDist>(__func__);
nld->jit = nld->proj = nld->fit = 0;
node->storage = nld;
}
-static void node_composit_buts_lensdist(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_lensdist(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
@@ -250,7 +250,7 @@ void register_node_type_cmp_lensdist()
cmp_node_type_base(&ntype, CMP_NODE_LENSDIST, "Lens Distortion", NODE_CLASS_DISTORT);
ntype.declare = file_ns::cmp_node_lensdist_declare;
ntype.draw_buttons = file_ns::node_composit_buts_lensdist;
- node_type_init(&ntype, file_ns::node_composit_init_lensdist);
+ ntype.initfunc = file_ns::node_composit_init_lensdist;
node_type_storage(
&ntype, "NodeLensDist", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_levels.cc b/source/blender/nodes/composite/nodes/node_composite_levels.cc
index 2f1ebeb79b5..29212c7a76f 100644
--- a/source/blender/nodes/composite/nodes/node_composite_levels.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_levels.cc
@@ -5,9 +5,18 @@
* \ingroup cmpnodes
*/
+#include <cmath>
+
+#include "BLI_assert.h"
+#include "BLI_math_vec_types.hh"
+#include "BLI_math_vector.hh"
+
#include "UI_interface.h"
#include "UI_resources.h"
+#include "IMB_colormanagement.h"
+
+#include "COM_algorithm_parallel_reduction.hh"
#include "COM_node_operation.hh"
#include "node_composite_util.hh"
@@ -18,17 +27,19 @@ namespace blender::nodes::node_composite_levels_cc {
static void cmp_node_levels_declare(NodeDeclarationBuilder &b)
{
- b.add_input<decl::Color>(N_("Image")).default_value({0.0f, 0.0f, 0.0f, 1.0f});
+ b.add_input<decl::Color>(N_("Image"))
+ .default_value({0.0f, 0.0f, 0.0f, 1.0f})
+ .compositor_domain_priority(0);
b.add_output<decl::Float>(N_("Mean"));
b.add_output<decl::Float>(N_("Std Dev"));
}
-static void node_composit_init_view_levels(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_view_levels(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = 1; /* All channels. */
}
-static void node_composit_buts_view_levels(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_view_levels(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "channel", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
@@ -36,13 +47,140 @@ static void node_composit_buts_view_levels(uiLayout *layout, bContext *UNUSED(C)
using namespace blender::realtime_compositor;
class LevelsOperation : public NodeOperation {
+ private:
+ constexpr static float luminance_coefficients_bt709_[3] = {0.2126f, 0.7152f, 0.0722f};
+
public:
using NodeOperation::NodeOperation;
void execute() override
{
- get_result("Mean").allocate_invalid();
- get_result("Std Dev").allocate_invalid();
+ if (get_input("Image").is_single_value()) {
+ execute_single_value();
+ return;
+ }
+
+ const float mean = compute_mean();
+
+ Result &mean_result = get_result("Mean");
+ if (mean_result.should_compute()) {
+ mean_result.allocate_single_value();
+ mean_result.set_float_value(mean);
+ }
+
+ Result &standard_deviation_result = get_result("Std Dev");
+ if (standard_deviation_result.should_compute()) {
+ const float standard_deviation = compute_standard_deviation(mean);
+ standard_deviation_result.allocate_single_value();
+ standard_deviation_result.set_float_value(standard_deviation);
+ }
+ }
+
+ void execute_single_value()
+ {
+ Result &standard_deviation_result = get_result("Std Dev");
+ if (standard_deviation_result.should_compute()) {
+ standard_deviation_result.allocate_single_value();
+ standard_deviation_result.set_float_value(0.0f);
+ }
+
+ Result &mean_result = get_result("Mean");
+ if (!mean_result.should_compute()) {
+ return;
+ }
+
+ mean_result.allocate_single_value();
+ const float3 input = float3(get_input("Image").get_color_value());
+
+ switch (get_channel()) {
+ case CMP_NODE_LEVLES_RED:
+ mean_result.set_float_value(input.x);
+ break;
+ case CMP_NODE_LEVLES_GREEN:
+ mean_result.set_float_value(input.y);
+ break;
+ case CMP_NODE_LEVLES_BLUE:
+ mean_result.set_float_value(input.z);
+ break;
+ case CMP_NODE_LEVLES_LUMINANCE_BT709:
+ mean_result.set_float_value(math::dot(input, float3(luminance_coefficients_bt709_)));
+ break;
+ case CMP_NODE_LEVLES_LUMINANCE: {
+ float luminance_coefficients[3];
+ IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
+ mean_result.set_float_value(math::dot(input, float3(luminance_coefficients)));
+ break;
+ }
+ default:
+ BLI_assert_unreachable();
+ break;
+ }
+ }
+
+ float compute_mean()
+ {
+ const Result &input = get_input("Image");
+ return compute_sum() / (input.domain().size.x * input.domain().size.y);
+ }
+
+ float compute_sum()
+ {
+ const Result &input = get_input("Image");
+ switch (get_channel()) {
+ case CMP_NODE_LEVLES_RED:
+ return sum_red(context(), input.texture());
+ case CMP_NODE_LEVLES_GREEN:
+ return sum_green(context(), input.texture());
+ case CMP_NODE_LEVLES_BLUE:
+ return sum_blue(context(), input.texture());
+ case CMP_NODE_LEVLES_LUMINANCE_BT709:
+ return sum_luminance(context(), input.texture(), float3(luminance_coefficients_bt709_));
+ case CMP_NODE_LEVLES_LUMINANCE: {
+ float luminance_coefficients[3];
+ IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
+ return sum_luminance(context(), input.texture(), float3(luminance_coefficients));
+ }
+ default:
+ BLI_assert_unreachable();
+ return 0.0f;
+ }
+ }
+
+ float compute_standard_deviation(float mean)
+ {
+ const Result &input = get_input("Image");
+ const float sum = compute_sum_squared_difference(mean);
+ return std::sqrt(sum / (input.domain().size.x * input.domain().size.y));
+ }
+
+ float compute_sum_squared_difference(float subtrahend)
+ {
+ const Result &input = get_input("Image");
+ switch (get_channel()) {
+ case CMP_NODE_LEVLES_RED:
+ return sum_red_squared_difference(context(), input.texture(), subtrahend);
+ case CMP_NODE_LEVLES_GREEN:
+ return sum_green_squared_difference(context(), input.texture(), subtrahend);
+ case CMP_NODE_LEVLES_BLUE:
+ return sum_blue_squared_difference(context(), input.texture(), subtrahend);
+ case CMP_NODE_LEVLES_LUMINANCE_BT709:
+ return sum_luminance_squared_difference(
+ context(), input.texture(), float3(luminance_coefficients_bt709_), subtrahend);
+ case CMP_NODE_LEVLES_LUMINANCE: {
+ float luminance_coefficients[3];
+ IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
+ return sum_luminance_squared_difference(
+ context(), input.texture(), float3(luminance_coefficients), subtrahend);
+ }
+ default:
+ BLI_assert_unreachable();
+ return 0.0f;
+ }
+ }
+
+ CMPNodeLevelsChannel get_channel()
+ {
+ return static_cast<CMPNodeLevelsChannel>(bnode().custom1);
}
};
@@ -63,7 +201,7 @@ void register_node_type_cmp_view_levels()
ntype.declare = file_ns::cmp_node_levels_declare;
ntype.draw_buttons = file_ns::node_composit_buts_view_levels;
ntype.flag |= NODE_PREVIEW;
- node_type_init(&ntype, file_ns::node_composit_init_view_levels);
+ ntype.initfunc = file_ns::node_composit_init_view_levels;
ntype.get_compositor_operation = file_ns::get_compositor_operation;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/composite/nodes/node_composite_luma_matte.cc b/source/blender/nodes/composite/nodes/node_composite_luma_matte.cc
index 59ae62ec411..325f5dbd870 100644
--- a/source/blender/nodes/composite/nodes/node_composite_luma_matte.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_luma_matte.cc
@@ -31,7 +31,7 @@ static void cmp_node_luma_matte_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Matte"));
}
-static void node_composit_init_luma_matte(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_luma_matte(bNodeTree * /*ntree*/, bNode *node)
{
NodeChroma *c = MEM_cnew<NodeChroma>(__func__);
node->storage = c;
@@ -39,7 +39,7 @@ static void node_composit_init_luma_matte(bNodeTree *UNUSED(ntree), bNode *node)
c->t2 = 0.0f;
}
-static void node_composit_buts_luma_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_luma_matte(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
@@ -104,7 +104,7 @@ void register_node_type_cmp_luma_matte()
ntype.declare = file_ns::cmp_node_luma_matte_declare;
ntype.draw_buttons = file_ns::node_composit_buts_luma_matte;
ntype.flag |= NODE_PREVIEW;
- node_type_init(&ntype, file_ns::node_composit_init_luma_matte);
+ ntype.initfunc = file_ns::node_composit_init_luma_matte;
node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_map_range.cc b/source/blender/nodes/composite/nodes/node_composite_map_range.cc
index e72869efa93..0dace651742 100644
--- a/source/blender/nodes/composite/nodes/node_composite_map_range.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_map_range.cc
@@ -48,7 +48,7 @@ static void cmp_node_map_range_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Value"));
}
-static void node_composit_buts_map_range(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_map_range(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
diff --git a/source/blender/nodes/composite/nodes/node_composite_map_uv.cc b/source/blender/nodes/composite/nodes/node_composite_map_uv.cc
index 4f660d62c3b..86f85ed7031 100644
--- a/source/blender/nodes/composite/nodes/node_composite_map_uv.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_map_uv.cc
@@ -23,7 +23,7 @@ static void cmp_node_map_uv_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_buts_map_uv(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_map_uv(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "alpha", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_map_value.cc b/source/blender/nodes/composite/nodes/node_composite_map_value.cc
index e30de39605d..ea80e7b03a8 100644
--- a/source/blender/nodes/composite/nodes/node_composite_map_value.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_map_value.cc
@@ -34,12 +34,12 @@ static void cmp_node_map_value_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Value"));
}
-static void node_composit_init_map_value(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_map_value(bNodeTree * /*ntree*/, bNode *node)
{
node->storage = BKE_texture_mapping_add(TEXMAP_TYPE_POINT);
}
-static void node_composit_buts_map_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_map_value(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *sub, *col;
@@ -116,7 +116,7 @@ void register_node_type_cmp_map_value()
cmp_node_type_base(&ntype, CMP_NODE_MAP_VALUE, "Map Value", NODE_CLASS_OP_VECTOR);
ntype.declare = file_ns::cmp_node_map_value_declare;
ntype.draw_buttons = file_ns::node_composit_buts_map_value;
- node_type_init(&ntype, file_ns::node_composit_init_map_value);
+ ntype.initfunc = file_ns::node_composit_init_map_value;
node_type_storage(&ntype, "TexMapping", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_mask.cc b/source/blender/nodes/composite/nodes/node_composite_mask.cc
index 2372dbae3f2..895ef62a82d 100644
--- a/source/blender/nodes/composite/nodes/node_composite_mask.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_mask.cc
@@ -23,7 +23,7 @@ static void cmp_node_mask_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Mask"));
}
-static void node_composit_init_mask(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_mask(bNodeTree * /*ntree*/, bNode *node)
{
NodeMask *data = MEM_cnew<NodeMask>(__func__);
data->size_x = data->size_y = 256;
@@ -33,7 +33,7 @@ static void node_composit_init_mask(bNodeTree *UNUSED(ntree), bNode *node)
node->custom3 = 0.5f; /* shutter */
}
-static void node_mask_label(const bNodeTree *UNUSED(ntree),
+static void node_mask_label(const bNodeTree * /*ntree*/,
const bNode *node,
char *label,
int maxlen)
@@ -104,7 +104,7 @@ void register_node_type_cmp_mask()
cmp_node_type_base(&ntype, CMP_NODE_MASK, "Mask", NODE_CLASS_INPUT);
ntype.declare = file_ns::cmp_node_mask_declare;
ntype.draw_buttons = file_ns::node_composit_buts_mask;
- node_type_init(&ntype, file_ns::node_composit_init_mask);
+ ntype.initfunc = file_ns::node_composit_init_mask;
ntype.labelfunc = file_ns::node_mask_label;
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_math.cc b/source/blender/nodes/composite/nodes/node_composite_math.cc
index 4baf057913e..e1dda06a41e 100644
--- a/source/blender/nodes/composite/nodes/node_composite_math.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_math.cc
@@ -96,7 +96,7 @@ void register_node_type_cmp_math()
cmp_node_type_base(&ntype, CMP_NODE_MATH, "Math", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_math_declare;
ntype.labelfunc = node_math_label;
- node_type_update(&ntype, node_math_update);
+ ntype.updatefunc = node_math_update;
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.cc b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.cc
index 88638586594..aad6eb3ce5e 100644
--- a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.cc
@@ -26,7 +26,7 @@ static void cmp_node_moviedistortion_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void label(const bNodeTree *UNUSED(ntree), const bNode *node, char *label, int maxlen)
+static void label(const bNodeTree * /*ntree*/, const bNode *node, char *label, int maxlen)
{
if (node->custom1 == 0) {
BLI_strncpy(label, IFACE_("Undistortion"), maxlen);
@@ -54,7 +54,7 @@ static void storage_free(bNode *node)
node->storage = nullptr;
}
-static void storage_copy(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
+static void storage_copy(bNodeTree * /*dst_ntree*/, bNode *dest_node, const bNode *src_node)
{
if (src_node->storage) {
dest_node->storage = BKE_tracking_distortion_copy((MovieDistortion *)src_node->storage);
diff --git a/source/blender/nodes/composite/nodes/node_composite_normalize.cc b/source/blender/nodes/composite/nodes/node_composite_normalize.cc
index 21765825468..34fd63e5805 100644
--- a/source/blender/nodes/composite/nodes/node_composite_normalize.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_normalize.cc
@@ -5,7 +5,9 @@
* \ingroup cmpnodes
*/
+#include "COM_algorithm_parallel_reduction.hh"
#include "COM_node_operation.hh"
+#include "COM_utilities.hh"
#include "node_composite_util.hh"
@@ -15,19 +17,60 @@ namespace blender::nodes::node_composite_normalize_cc {
static void cmp_node_normalize_declare(NodeDeclarationBuilder &b)
{
- b.add_input<decl::Float>(N_("Value")).default_value(1.0f).min(0.0f).max(1.0f);
+ b.add_input<decl::Float>(N_("Value"))
+ .default_value(1.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .compositor_domain_priority(0);
b.add_output<decl::Float>(N_("Value"));
}
using namespace blender::realtime_compositor;
class NormalizeOperation : public NodeOperation {
+ private:
+ /* The normalize operation is specifically designed to normalize Z Depth information. But since Z
+ * Depth can contain near infinite values, normalization is limited to [-range_, range], meaning
+ * that values outside of that range will be ignored when computing the maximum and minimum for
+ * normalization and will eventually be 0 or 1 if they are less than or larger than the range
+ * respectively. */
+ constexpr static float range_ = 10000.0f;
+
public:
using NodeOperation::NodeOperation;
void execute() override
{
- get_input("Value").pass_through(get_result("Value"));
+ Result &input_image = get_input("Value");
+ Result &output_image = get_result("Value");
+ if (input_image.is_single_value()) {
+ input_image.pass_through(output_image);
+ return;
+ }
+
+ const float maximum = maximum_float_in_range(
+ context(), input_image.texture(), -range_, range_);
+ const float minimum = minimum_float_in_range(
+ context(), input_image.texture(), -range_, range_);
+ const float scale = (maximum != minimum) ? (1.0f / (maximum - minimum)) : 0.0f;
+
+ GPUShader *shader = shader_manager().get("compositor_normalize");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_1f(shader, "minimum", minimum);
+ GPU_shader_uniform_1f(shader, "scale", scale);
+
+ input_image.bind_as_texture(shader, "input_tx");
+
+ const Domain domain = compute_domain();
+ output_image.allocate_texture(domain);
+ output_image.bind_as_image(shader, "output_img");
+
+ compute_dispatch_threads_at_least(shader, domain.size);
+
+ GPU_shader_unbind();
+ output_image.unbind_as_image();
+ input_image.unbind_as_texture();
}
};
diff --git a/source/blender/nodes/composite/nodes/node_composite_output_file.cc b/source/blender/nodes/composite/nodes/node_composite_output_file.cc
index 5ed383977a5..f64e448842d 100644
--- a/source/blender/nodes/composite/nodes/node_composite_output_file.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_output_file.cc
@@ -231,9 +231,7 @@ static void free_output_file(bNode *node)
MEM_freeN(node->storage);
}
-static void copy_output_file(bNodeTree *UNUSED(dest_ntree),
- bNode *dest_node,
- const bNode *src_node)
+static void copy_output_file(bNodeTree * /*dst_ntree*/, bNode *dest_node, const bNode *src_node)
{
bNodeSocket *src_sock, *dest_sock;
@@ -282,7 +280,7 @@ static void update_output_file(bNodeTree *ntree, bNode *node)
}
}
-static void node_composit_buts_file_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_file_output(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
PointerRNA imfptr = RNA_pointer_get(ptr, "format");
const bool multilayer = RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER;
@@ -472,7 +470,7 @@ void register_node_type_cmp_output_file()
ntype.flag |= NODE_PREVIEW;
node_type_storage(
&ntype, "NodeImageMultiFile", file_ns::free_output_file, file_ns::copy_output_file);
- node_type_update(&ntype, file_ns::update_output_file);
+ ntype.updatefunc = file_ns::update_output_file;
ntype.get_compositor_operation = file_ns::get_compositor_operation;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/composite/nodes/node_composite_pixelate.cc b/source/blender/nodes/composite/nodes/node_composite_pixelate.cc
index c4e42f8247d..c65bb7bb747 100644
--- a/source/blender/nodes/composite/nodes/node_composite_pixelate.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_pixelate.cc
@@ -36,7 +36,10 @@ class PixelateOperation : public NodeOperation {
* matches its apparent size, that is, its size after the domain transformation. The pixelate
* node has no effect if the input is scaled-up. See the compute_domain method for more
* information. */
- get_input("Color").pass_through(get_result("Color"));
+ Result &result = get_result("Color");
+ get_input("Color").pass_through(result);
+
+ result.get_realization_options().interpolation = Interpolation::Nearest;
}
/* Compute a smaller-sized domain that matches the apparent size of the input while having a unit
diff --git a/source/blender/nodes/composite/nodes/node_composite_premulkey.cc b/source/blender/nodes/composite/nodes/node_composite_premulkey.cc
index c814ea5f738..85e37e12231 100644
--- a/source/blender/nodes/composite/nodes/node_composite_premulkey.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_premulkey.cc
@@ -26,7 +26,7 @@ static void cmp_node_premulkey_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_buts_premulkey(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_premulkey(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mapping", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_rotate.cc b/source/blender/nodes/composite/nodes/node_composite_rotate.cc
index 35caa3cd242..4cc1166b373 100644
--- a/source/blender/nodes/composite/nodes/node_composite_rotate.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_rotate.cc
@@ -33,12 +33,12 @@ static void cmp_node_rotate_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_rotate(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_rotate(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = 1; /* Bilinear Filter. */
}
-static void node_composit_buts_rotate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_rotate(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "filter_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
@@ -95,7 +95,7 @@ void register_node_type_cmp_rotate()
cmp_node_type_base(&ntype, CMP_NODE_ROTATE, "Rotate", NODE_CLASS_DISTORT);
ntype.declare = file_ns::cmp_node_rotate_declare;
ntype.draw_buttons = file_ns::node_composit_buts_rotate;
- node_type_init(&ntype, file_ns::node_composit_init_rotate);
+ ntype.initfunc = file_ns::node_composit_init_rotate;
ntype.get_compositor_operation = file_ns::get_compositor_operation;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/composite/nodes/node_composite_scale.cc b/source/blender/nodes/composite/nodes/node_composite_scale.cc
index eb2d7162c69..a4e28326d9d 100644
--- a/source/blender/nodes/composite/nodes/node_composite_scale.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_scale.cc
@@ -54,7 +54,7 @@ static void node_composite_update_scale(bNodeTree *ntree, bNode *node)
}
}
-static void node_composit_buts_scale(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_scale(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "space", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
@@ -88,7 +88,6 @@ class ScaleOperation : public NodeOperation {
get_translation(), 0.0f, get_scale());
result.transform(transformation);
- result.get_realization_options().interpolation = Interpolation::Bilinear;
}
float2 get_scale()
@@ -222,7 +221,7 @@ void register_node_type_cmp_scale()
cmp_node_type_base(&ntype, CMP_NODE_SCALE, "Scale", NODE_CLASS_DISTORT);
ntype.declare = file_ns::cmp_node_scale_declare;
ntype.draw_buttons = file_ns::node_composit_buts_scale;
- node_type_update(&ntype, file_ns::node_composite_update_scale);
+ ntype.updatefunc = file_ns::node_composite_update_scale;
ntype.get_compositor_operation = file_ns::get_compositor_operation;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/composite/nodes/node_composite_scene_time.cc b/source/blender/nodes/composite/nodes/node_composite_scene_time.cc
index 1f5317378bb..3a7e7dc78bd 100644
--- a/source/blender/nodes/composite/nodes/node_composite_scene_time.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_scene_time.cc
@@ -38,7 +38,7 @@ class SceneTimeOperation : public NodeOperation {
{
Result &result = get_result("Frame");
result.allocate_single_value();
- result.set_float_value(static_cast<float>(context().get_frame_number()));
+ result.set_float_value(float(context().get_frame_number()));
}
};
diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcomb_color.cc b/source/blender/nodes/composite/nodes/node_composite_sepcomb_color.cc
index f6792d7ce61..118ab6ccdf8 100644
--- a/source/blender/nodes/composite/nodes/node_composite_sepcomb_color.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_sepcomb_color.cc
@@ -8,7 +8,7 @@
#include "node_composite_util.hh"
-static void node_cmp_combsep_color_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_cmp_combsep_color_init(bNodeTree * /*ntree*/, bNode *node)
{
NodeCMPCombSepColor *data = MEM_cnew<NodeCMPCombSepColor>(__func__);
data->mode = CMP_NODE_COMBSEP_COLOR_RGB;
@@ -75,7 +75,7 @@ static void cmp_node_separate_color_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Alpha"));
}
-static void cmp_node_separate_color_update(bNodeTree *UNUSED(ntree), bNode *node)
+static void cmp_node_separate_color_update(bNodeTree * /*ntree*/, bNode *node)
{
const NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)node->storage;
node_cmp_combsep_color_label(&node->outputs, (CMPNodeCombSepColorMode)storage->mode);
@@ -137,10 +137,10 @@ void register_node_type_cmp_separate_color()
cmp_node_type_base(&ntype, CMP_NODE_SEPARATE_COLOR, "Separate Color", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_separate_color_declare;
- node_type_init(&ntype, node_cmp_combsep_color_init);
+ ntype.initfunc = node_cmp_combsep_color_init;
node_type_storage(
&ntype, "NodeCMPCombSepColor", node_free_standard_storage, node_copy_standard_storage);
- node_type_update(&ntype, file_ns::cmp_node_separate_color_update);
+ ntype.updatefunc = file_ns::cmp_node_separate_color_update;
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
nodeRegisterType(&ntype);
@@ -181,7 +181,7 @@ static void cmp_node_combine_color_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void cmp_node_combine_color_update(bNodeTree *UNUSED(ntree), bNode *node)
+static void cmp_node_combine_color_update(bNodeTree * /*ntree*/, bNode *node)
{
const NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)node->storage;
node_cmp_combsep_color_label(&node->inputs, (CMPNodeCombSepColorMode)storage->mode);
@@ -243,10 +243,10 @@ void register_node_type_cmp_combine_color()
cmp_node_type_base(&ntype, CMP_NODE_COMBINE_COLOR, "Combine Color", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_combine_color_declare;
- node_type_init(&ntype, node_cmp_combsep_color_init);
+ ntype.initfunc = node_cmp_combsep_color_init;
node_type_storage(
&ntype, "NodeCMPCombSepColor", node_free_standard_storage, node_copy_standard_storage);
- node_type_update(&ntype, file_ns::cmp_node_combine_color_update);
+ ntype.updatefunc = file_ns::cmp_node_combine_color_update;
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcomb_hsva.cc b/source/blender/nodes/composite/nodes/node_composite_sepcomb_hsva.cc
index b655c0db106..3483285793a 100644
--- a/source/blender/nodes/composite/nodes/node_composite_sepcomb_hsva.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_sepcomb_hsva.cc
@@ -54,7 +54,8 @@ void register_node_type_cmp_sephsva()
static bNodeType ntype;
- cmp_node_type_base(&ntype, CMP_NODE_SEPHSVA_LEGACY, "Separate HSVA", NODE_CLASS_CONVERTER);
+ cmp_node_type_base(
+ &ntype, CMP_NODE_SEPHSVA_LEGACY, "Separate HSVA (Legacy)", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_sephsva_declare;
ntype.gather_link_search_ops = nullptr;
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
@@ -107,7 +108,8 @@ void register_node_type_cmp_combhsva()
static bNodeType ntype;
- cmp_node_type_base(&ntype, CMP_NODE_COMBHSVA_LEGACY, "Combine HSVA", NODE_CLASS_CONVERTER);
+ cmp_node_type_base(
+ &ntype, CMP_NODE_COMBHSVA_LEGACY, "Combine HSVA (Legacy)", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_combhsva_declare;
ntype.gather_link_search_ops = nullptr;
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcomb_rgba.cc b/source/blender/nodes/composite/nodes/node_composite_sepcomb_rgba.cc
index 1f4c9fd153f..9308052454d 100644
--- a/source/blender/nodes/composite/nodes/node_composite_sepcomb_rgba.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_sepcomb_rgba.cc
@@ -54,7 +54,8 @@ void register_node_type_cmp_seprgba()
static bNodeType ntype;
- cmp_node_type_base(&ntype, CMP_NODE_SEPRGBA_LEGACY, "Separate RGBA", NODE_CLASS_CONVERTER);
+ cmp_node_type_base(
+ &ntype, CMP_NODE_SEPRGBA_LEGACY, "Separate RGBA (Legacy)", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_seprgba_declare;
ntype.gather_link_search_ops = nullptr;
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
@@ -107,7 +108,8 @@ void register_node_type_cmp_combrgba()
static bNodeType ntype;
- cmp_node_type_base(&ntype, CMP_NODE_COMBRGBA_LEGACY, "Combine RGBA", NODE_CLASS_CONVERTER);
+ cmp_node_type_base(
+ &ntype, CMP_NODE_COMBRGBA_LEGACY, "Combine RGBA (Legacy)", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_combrgba_declare;
ntype.gather_link_search_ops = nullptr;
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcomb_ycca.cc b/source/blender/nodes/composite/nodes/node_composite_sepcomb_ycca.cc
index bebe6abe115..7c1461b4f6e 100644
--- a/source/blender/nodes/composite/nodes/node_composite_sepcomb_ycca.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_sepcomb_ycca.cc
@@ -28,7 +28,7 @@ static void cmp_node_sepycca_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("A"));
}
-static void node_composit_init_mode_sepycca(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_mode_sepycca(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = 1; /* BLI_YCC_ITU_BT709 */
}
@@ -81,9 +81,10 @@ void register_node_type_cmp_sepycca()
static bNodeType ntype;
- cmp_node_type_base(&ntype, CMP_NODE_SEPYCCA_LEGACY, "Separate YCbCrA", NODE_CLASS_CONVERTER);
+ cmp_node_type_base(
+ &ntype, CMP_NODE_SEPYCCA_LEGACY, "Separate YCbCrA (Legacy)", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_sepycca_declare;
- node_type_init(&ntype, file_ns::node_composit_init_mode_sepycca);
+ ntype.initfunc = file_ns::node_composit_init_mode_sepycca;
ntype.gather_link_search_ops = nullptr;
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
@@ -115,7 +116,7 @@ static void cmp_node_combycca_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_mode_combycca(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_mode_combycca(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = 1; /* BLI_YCC_ITU_BT709 */
}
@@ -168,9 +169,10 @@ void register_node_type_cmp_combycca()
static bNodeType ntype;
- cmp_node_type_base(&ntype, CMP_NODE_COMBYCCA_LEGACY, "Combine YCbCrA", NODE_CLASS_CONVERTER);
+ cmp_node_type_base(
+ &ntype, CMP_NODE_COMBYCCA_LEGACY, "Combine YCbCrA (Legacy)", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_combycca_declare;
- node_type_init(&ntype, file_ns::node_composit_init_mode_combycca);
+ ntype.initfunc = file_ns::node_composit_init_mode_combycca;
ntype.gather_link_search_ops = nullptr;
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcomb_yuva.cc b/source/blender/nodes/composite/nodes/node_composite_sepcomb_yuva.cc
index 1f0eb04cfc3..b12e70ad9b8 100644
--- a/source/blender/nodes/composite/nodes/node_composite_sepcomb_yuva.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_sepcomb_yuva.cc
@@ -54,7 +54,8 @@ void register_node_type_cmp_sepyuva()
static bNodeType ntype;
- cmp_node_type_base(&ntype, CMP_NODE_SEPYUVA_LEGACY, "Separate YUVA", NODE_CLASS_CONVERTER);
+ cmp_node_type_base(
+ &ntype, CMP_NODE_SEPYUVA_LEGACY, "Separate YUVA (Legacy)", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_sepyuva_declare;
ntype.gather_link_search_ops = nullptr;
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
@@ -107,7 +108,8 @@ void register_node_type_cmp_combyuva()
static bNodeType ntype;
- cmp_node_type_base(&ntype, CMP_NODE_COMBYUVA_LEGACY, "Combine YUVA", NODE_CLASS_CONVERTER);
+ cmp_node_type_base(
+ &ntype, CMP_NODE_COMBYUVA_LEGACY, "Combine YUVA (Legacy)", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_combyuva_declare;
ntype.gather_link_search_ops = nullptr;
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_setalpha.cc b/source/blender/nodes/composite/nodes/node_composite_setalpha.cc
index df3aca2c665..99c4dae4a92 100644
--- a/source/blender/nodes/composite/nodes/node_composite_setalpha.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_setalpha.cc
@@ -33,14 +33,14 @@ static void cmp_node_setalpha_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_setalpha(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_setalpha(bNodeTree * /*ntree*/, bNode *node)
{
NodeSetAlpha *settings = MEM_cnew<NodeSetAlpha>(__func__);
node->storage = settings;
settings->mode = CMP_NODE_SETALPHA_MODE_APPLY;
}
-static void node_composit_buts_set_alpha(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_set_alpha(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
}
@@ -81,7 +81,7 @@ void register_node_type_cmp_setalpha()
cmp_node_type_base(&ntype, CMP_NODE_SETALPHA, "Set Alpha", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_setalpha_declare;
ntype.draw_buttons = file_ns::node_composit_buts_set_alpha;
- node_type_init(&ntype, file_ns::node_composit_init_setalpha);
+ ntype.initfunc = file_ns::node_composit_init_setalpha;
node_type_storage(
&ntype, "NodeSetAlpha", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_split_viewer.cc b/source/blender/nodes/composite/nodes/node_composite_split_viewer.cc
index 085de69e63e..b4e698f5096 100644
--- a/source/blender/nodes/composite/nodes/node_composite_split_viewer.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_split_viewer.cc
@@ -29,7 +29,7 @@ static void cmp_node_split_viewer_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Color>(N_("Image"), "Image_001");
}
-static void node_composit_init_splitviewer(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_splitviewer(bNodeTree * /*ntree*/, bNode *node)
{
ImageUser *iuser = MEM_cnew<ImageUser>(__func__);
node->storage = iuser;
@@ -39,7 +39,7 @@ static void node_composit_init_splitviewer(bNodeTree *UNUSED(ntree), bNode *node
node->id = (ID *)BKE_image_ensure_viewer(G.main, IMA_TYPE_COMPOSITE, "Viewer Node");
}
-static void node_composit_buts_splitviewer(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_splitviewer(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *row, *col;
@@ -125,7 +125,7 @@ void register_node_type_cmp_splitviewer()
ntype.declare = file_ns::cmp_node_split_viewer_declare;
ntype.draw_buttons = file_ns::node_composit_buts_splitviewer;
ntype.flag |= NODE_PREVIEW;
- node_type_init(&ntype, file_ns::node_composit_init_splitviewer);
+ ntype.initfunc = file_ns::node_composit_init_splitviewer;
node_type_storage(&ntype, "ImageUser", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_sunbeams.cc b/source/blender/nodes/composite/nodes/node_composite_sunbeams.cc
index 4b9264d7e35..798e60e9482 100644
--- a/source/blender/nodes/composite/nodes/node_composite_sunbeams.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_sunbeams.cc
@@ -20,7 +20,7 @@ static void cmp_node_sunbeams_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void init(bNodeTree *UNUSED(ntree), bNode *node)
+static void init(bNodeTree * /*ntree*/, bNode *node)
{
NodeSunBeams *data = MEM_cnew<NodeSunBeams>(__func__);
@@ -29,7 +29,7 @@ static void init(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = data;
}
-static void node_composit_buts_sunbeams(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_sunbeams(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "source", UI_ITEM_R_SPLIT_EMPTY_NAME | UI_ITEM_R_EXPAND, "", ICON_NONE);
uiItemR(layout,
@@ -68,7 +68,7 @@ void register_node_type_cmp_sunbeams()
cmp_node_type_base(&ntype, CMP_NODE_SUNBEAMS, "Sun Beams", NODE_CLASS_OP_FILTER);
ntype.declare = file_ns::cmp_node_sunbeams_declare;
ntype.draw_buttons = file_ns::node_composit_buts_sunbeams;
- node_type_init(&ntype, file_ns::init);
+ ntype.initfunc = file_ns::init;
node_type_storage(
&ntype, "NodeSunBeams", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_switch.cc b/source/blender/nodes/composite/nodes/node_composite_switch.cc
index 767802cc442..c62ae652029 100644
--- a/source/blender/nodes/composite/nodes/node_composite_switch.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_switch.cc
@@ -23,7 +23,7 @@ static void cmp_node_switch_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_buts_switch(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_switch(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "check", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_switchview.cc b/source/blender/nodes/composite/nodes/node_composite_switchview.cc
index e74c3b6007a..9974e55cc1a 100644
--- a/source/blender/nodes/composite/nodes/node_composite_switchview.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_switchview.cc
@@ -129,8 +129,8 @@ static void init_switch_view(const bContext *C, PointerRNA *ptr)
}
static void node_composit_buts_switch_view_ex(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *UNUSED(ptr))
+ bContext * /*C*/,
+ PointerRNA * /*ptr*/)
{
uiItemFullO(layout,
"NODE_OT_switch_view_update",
@@ -173,7 +173,7 @@ void register_node_type_cmp_switch_view()
node_type_socket_templates(&ntype, nullptr, file_ns::cmp_node_switch_view_out);
ntype.draw_buttons_ex = file_ns::node_composit_buts_switch_view_ex;
ntype.initfunc_api = file_ns::init_switch_view;
- node_type_update(&ntype, file_ns::cmp_node_switch_view_update);
+ ntype.updatefunc = file_ns::cmp_node_switch_view_update;
ntype.get_compositor_operation = file_ns::get_compositor_operation;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/composite/nodes/node_composite_tonemap.cc b/source/blender/nodes/composite/nodes/node_composite_tonemap.cc
index 4cc3d4f32a3..febbb9ddec5 100644
--- a/source/blender/nodes/composite/nodes/node_composite_tonemap.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_tonemap.cc
@@ -5,24 +5,39 @@
* \ingroup cmpnodes
*/
+#include <cmath>
+
+#include "BLI_assert.h"
+#include "BLI_math_base.hh"
+#include "BLI_math_vec_types.hh"
+#include "BLI_math_vector.hh"
+
#include "RNA_access.h"
#include "UI_interface.h"
#include "UI_resources.h"
+#include "IMB_colormanagement.h"
+
+#include "COM_algorithm_parallel_reduction.hh"
#include "COM_node_operation.hh"
+#include "COM_utilities.hh"
#include "node_composite_util.hh"
namespace blender::nodes::node_composite_tonemap_cc {
+NODE_STORAGE_FUNCS(NodeTonemap)
+
static void cmp_node_tonemap_declare(NodeDeclarationBuilder &b)
{
- b.add_input<decl::Color>(N_("Image")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
+ b.add_input<decl::Color>(N_("Image"))
+ .default_value({1.0f, 1.0f, 1.0f, 1.0f})
+ .compositor_domain_priority(0);
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_tonemap(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_tonemap(bNodeTree * /*ntree*/, bNode *node)
{
NodeTonemap *ntm = MEM_cnew<NodeTonemap>(__func__);
ntm->type = 1;
@@ -38,7 +53,7 @@ static void node_composit_init_tonemap(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = ntm;
}
-static void node_composit_buts_tonemap(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_tonemap(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
@@ -68,7 +83,236 @@ class ToneMapOperation : public NodeOperation {
void execute() override
{
- get_input("Image").pass_through(get_result("Image"));
+ Result &input_image = get_input("Image");
+ Result &output_image = get_result("Image");
+ if (input_image.is_single_value()) {
+ input_image.pass_through(output_image);
+ return;
+ }
+
+ switch (get_type()) {
+ case CMP_NODE_TONE_MAP_SIMPLE:
+ execute_simple();
+ return;
+ case CMP_NODE_TONE_MAP_PHOTORECEPTOR:
+ execute_photoreceptor();
+ return;
+ default:
+ BLI_assert_unreachable();
+ return;
+ }
+ }
+
+ /* Tone mapping based on equation (3) from Reinhard, Erik, et al. "Photographic tone reproduction
+ * for digital images." Proceedings of the 29th annual conference on Computer graphics and
+ * interactive techniques. 2002. */
+ void execute_simple()
+ {
+ const float luminance_scale = compute_luminance_scale();
+ const float luminance_scale_blend_factor = compute_luminance_scale_blend_factor();
+ const float gamma = node_storage(bnode()).gamma;
+ const float inverse_gamma = gamma != 0.0f ? 1.0f / gamma : 0.0f;
+
+ GPUShader *shader = shader_manager().get("compositor_tone_map_simple");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_1f(shader, "luminance_scale", luminance_scale);
+ GPU_shader_uniform_1f(shader, "luminance_scale_blend_factor", luminance_scale_blend_factor);
+ GPU_shader_uniform_1f(shader, "inverse_gamma", inverse_gamma);
+
+ const Result &input_image = get_input("Image");
+ input_image.bind_as_texture(shader, "input_tx");
+
+ const Domain domain = compute_domain();
+ Result &output_image = get_result("Image");
+ output_image.allocate_texture(domain);
+ output_image.bind_as_image(shader, "output_img");
+
+ compute_dispatch_threads_at_least(shader, domain.size);
+
+ GPU_shader_unbind();
+ output_image.unbind_as_image();
+ input_image.unbind_as_texture();
+ }
+
+ /* Computes the scaling factor in equation (2) from Reinhard's 2002 paper. */
+ float compute_luminance_scale()
+ {
+ const float geometric_mean = compute_geometric_mean_of_luminance();
+ return geometric_mean != 0.0 ? node_storage(bnode()).key / geometric_mean : 0.0f;
+ }
+
+ /* Computes equation (1) from Reinhard's 2002 paper. However, note that the equation in the paper
+ * is most likely wrong, and the intention is actually to compute the geometric mean through a
+ * logscale arithmetic mean, that is, the division should happen inside the exponential function,
+ * not outside of it. That's because the sum of the log luminance will be a very large negative
+ * number, whose exponential will almost always be zero, which is unexpected and useless. */
+ float compute_geometric_mean_of_luminance()
+ {
+ return std::exp(compute_average_log_luminance());
+ }
+
+ /* Equation (3) from Reinhard's 2002 paper blends between high luminance scaling for high
+ * luminance values and low luminance scaling for low luminance values. This is done by adding 1
+ * to the denominator, since for low luminance values, the denominator will be close to 1 and for
+ * high luminance values, the 1 in the denominator will be relatively insignificant. But the
+ * response of such function is not always ideal, so in this implementation, the 1 was exposed as
+ * a parameter to the user for more flexibility. */
+ float compute_luminance_scale_blend_factor()
+ {
+ return node_storage(bnode()).offset;
+ }
+
+ /* Tone mapping based on equation (1) and the trilinear interpolation between equations (6) and
+ * (7) from Reinhard, Erik, and Kate Devlin. "Dynamic range reduction inspired by photoreceptor
+ * physiology." IEEE transactions on visualization and computer graphics 11.1 (2005): 13-24. */
+ void execute_photoreceptor()
+ {
+ const float4 global_adaptation_level = compute_global_adaptation_level();
+ const float contrast = compute_contrast();
+ const float intensity = compute_intensity();
+ const float chromatic_adaptation = get_chromatic_adaptation();
+ const float light_adaptation = get_light_adaptation();
+
+ GPUShader *shader = shader_manager().get("compositor_tone_map_photoreceptor");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_4fv(shader, "global_adaptation_level", global_adaptation_level);
+ GPU_shader_uniform_1f(shader, "contrast", contrast);
+ GPU_shader_uniform_1f(shader, "intensity", intensity);
+ GPU_shader_uniform_1f(shader, "chromatic_adaptation", chromatic_adaptation);
+ GPU_shader_uniform_1f(shader, "light_adaptation", light_adaptation);
+
+ float luminance_coefficients[3];
+ IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
+ GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
+
+ const Result &input_image = get_input("Image");
+ input_image.bind_as_texture(shader, "input_tx");
+
+ const Domain domain = compute_domain();
+ Result &output_image = get_result("Image");
+ output_image.allocate_texture(domain);
+ output_image.bind_as_image(shader, "output_img");
+
+ compute_dispatch_threads_at_least(shader, domain.size);
+
+ GPU_shader_unbind();
+ output_image.unbind_as_image();
+ input_image.unbind_as_texture();
+ }
+
+ /* Computes the global adaptation level from the trilinear interpolation equations constructed
+ * from equations (6) and (7) in Reinhard's 2005 paper. */
+ float4 compute_global_adaptation_level()
+ {
+ const float4 average_color = compute_average_color();
+ const float average_luminance = compute_average_luminance();
+ const float chromatic_adaptation = get_chromatic_adaptation();
+ return math::interpolate(float4(average_luminance), average_color, chromatic_adaptation);
+ }
+
+ float4 compute_average_color()
+ {
+ /* The average color will reduce to zero if chromatic adaptation is zero, so just return zero
+ * in this case to avoid needlessly computing the average. See the trilinear interpolation
+ * equations constructed from equations (6) and (7) in Reinhard's 2005 paper. */
+ if (get_chromatic_adaptation() == 0.0f) {
+ return float4(0.0f);
+ }
+
+ const Result &input = get_input("Image");
+ return sum_color(context(), input.texture()) / (input.domain().size.x * input.domain().size.y);
+ }
+
+ float compute_average_luminance()
+ {
+ /* The average luminance will reduce to zero if chromatic adaptation is one, so just return
+ * zero in this case to avoid needlessly computing the average. See the trilinear interpolation
+ * equations constructed from equations (6) and (7) in Reinhard's 2005 paper. */
+ if (get_chromatic_adaptation() == 1.0f) {
+ return 0.0f;
+ }
+
+ float luminance_coefficients[3];
+ IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
+ const Result &input = get_input("Image");
+ float sum = sum_luminance(context(), input.texture(), luminance_coefficients);
+ return sum / (input.domain().size.x * input.domain().size.y);
+ }
+
+ /* Computes equation (5) from Reinhard's 2005 paper. */
+ float compute_intensity()
+ {
+ return std::exp(-node_storage(bnode()).f);
+ }
+
+ /* If the contrast is not zero, return it, otherwise, a zero contrast denote automatic derivation
+ * of the contrast value based on equations (2) and (4) from Reinhard's 2005 paper. */
+ float compute_contrast()
+ {
+ if (node_storage(bnode()).m != 0.0f) {
+ return node_storage(bnode()).m;
+ }
+
+ const float log_maximum_luminance = compute_log_maximum_luminance();
+ const float log_minimum_luminance = compute_log_minimum_luminance();
+
+ /* This is merely to guard against zero division later. */
+ if (log_maximum_luminance == log_minimum_luminance) {
+ return 1.0f;
+ }
+
+ const float average_log_luminance = compute_average_log_luminance();
+ const float dynamic_range = log_maximum_luminance - log_minimum_luminance;
+ const float luminance_key = (log_maximum_luminance - average_log_luminance) / (dynamic_range);
+
+ return 0.3f + 0.7f * std::pow(luminance_key, 1.4f);
+ }
+
+ float compute_average_log_luminance()
+ {
+ const Result &input_image = get_input("Image");
+
+ float luminance_coefficients[3];
+ IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
+ const float sum_of_log_luminance = sum_log_luminance(
+ context(), input_image.texture(), luminance_coefficients);
+
+ return sum_of_log_luminance / (input_image.domain().size.x * input_image.domain().size.y);
+ }
+
+ float compute_log_maximum_luminance()
+ {
+ float luminance_coefficients[3];
+ IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
+ const float maximum = maximum_luminance(
+ context(), get_input("Image").texture(), luminance_coefficients);
+ return std::log(math::max(maximum, 1e-5f));
+ }
+
+ float compute_log_minimum_luminance()
+ {
+ float luminance_coefficients[3];
+ IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
+ const float minimum = minimum_luminance(
+ context(), get_input("Image").texture(), luminance_coefficients);
+ return std::log(math::max(minimum, 1e-5f));
+ }
+
+ float get_chromatic_adaptation()
+ {
+ return node_storage(bnode()).c;
+ }
+
+ float get_light_adaptation()
+ {
+ return node_storage(bnode()).a;
+ }
+
+ CMPNodeToneMapType get_type()
+ {
+ return static_cast<CMPNodeToneMapType>(node_storage(bnode()).type);
}
};
@@ -88,7 +332,7 @@ void register_node_type_cmp_tonemap()
cmp_node_type_base(&ntype, CMP_NODE_TONEMAP, "Tonemap", NODE_CLASS_OP_COLOR);
ntype.declare = file_ns::cmp_node_tonemap_declare;
ntype.draw_buttons = file_ns::node_composit_buts_tonemap;
- node_type_init(&ntype, file_ns::node_composit_init_tonemap);
+ ntype.initfunc = file_ns::node_composit_init_tonemap;
node_type_storage(&ntype, "NodeTonemap", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_transform.cc b/source/blender/nodes/composite/nodes/node_composite_transform.cc
index 7c5866d2d06..0eaa860b45f 100644
--- a/source/blender/nodes/composite/nodes/node_composite_transform.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_transform.cc
@@ -49,7 +49,7 @@ static void cmp_node_transform_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_buts_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_transform(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "filter_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_translate.cc b/source/blender/nodes/composite/nodes/node_composite_translate.cc
index e0f87ff604a..154be2d428a 100644
--- a/source/blender/nodes/composite/nodes/node_composite_translate.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_translate.cc
@@ -39,13 +39,13 @@ static void cmp_node_translate_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Image"));
}
-static void node_composit_init_translate(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_translate(bNodeTree * /*ntree*/, bNode *node)
{
NodeTranslateData *data = MEM_cnew<NodeTranslateData>(__func__);
node->storage = data;
}
-static void node_composit_buts_translate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_translate(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "use_relative", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
uiItemR(layout, ptr, "wrap_axis", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
@@ -110,7 +110,7 @@ void register_node_type_cmp_translate()
cmp_node_type_base(&ntype, CMP_NODE_TRANSLATE, "Translate", NODE_CLASS_DISTORT);
ntype.declare = file_ns::cmp_node_translate_declare;
ntype.draw_buttons = file_ns::node_composit_buts_translate;
- node_type_init(&ntype, file_ns::node_composit_init_translate);
+ ntype.initfunc = file_ns::node_composit_init_translate;
node_type_storage(
&ntype, "NodeTranslateData", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_val_to_rgb.cc b/source/blender/nodes/composite/nodes/node_composite_val_to_rgb.cc
index 03a7bc61924..d083051e9d2 100644
--- a/source/blender/nodes/composite/nodes/node_composite_val_to_rgb.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_val_to_rgb.cc
@@ -35,7 +35,7 @@ static void cmp_node_valtorgb_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Alpha"));
}
-static void node_composit_init_valtorgb(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_valtorgb(bNodeTree * /*ntree*/, bNode *node)
{
node->storage = BKE_colorband_add(true);
}
@@ -134,7 +134,7 @@ void register_node_type_cmp_valtorgb()
cmp_node_type_base(&ntype, CMP_NODE_VALTORGB, "ColorRamp", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_valtorgb_declare;
node_type_size(&ntype, 240, 200, 320);
- node_type_init(&ntype, file_ns::node_composit_init_valtorgb);
+ ntype.initfunc = file_ns::node_composit_init_valtorgb;
node_type_storage(&ntype, "ColorBand", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_vec_blur.cc b/source/blender/nodes/composite/nodes/node_composite_vec_blur.cc
index 515478da75d..6a44fcb1650 100644
--- a/source/blender/nodes/composite/nodes/node_composite_vec_blur.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_vec_blur.cc
@@ -29,7 +29,7 @@ static void cmp_node_vec_blur_declare(NodeDeclarationBuilder &b)
}
/* custom1: iterations, custom2: max_speed (0 = no_limit). */
-static void node_composit_init_vecblur(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_vecblur(bNodeTree * /*ntree*/, bNode *node)
{
NodeBlurData *nbd = MEM_cnew<NodeBlurData>(__func__);
node->storage = nbd;
@@ -37,7 +37,7 @@ static void node_composit_init_vecblur(bNodeTree *UNUSED(ntree), bNode *node)
nbd->fac = 1.0f;
}
-static void node_composit_buts_vecblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_vecblur(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
@@ -81,7 +81,7 @@ void register_node_type_cmp_vecblur()
cmp_node_type_base(&ntype, CMP_NODE_VECBLUR, "Vector Blur", NODE_CLASS_OP_FILTER);
ntype.declare = file_ns::cmp_node_vec_blur_declare;
ntype.draw_buttons = file_ns::node_composit_buts_vecblur;
- node_type_init(&ntype, file_ns::node_composit_init_vecblur);
+ ntype.initfunc = file_ns::node_composit_init_vecblur;
node_type_storage(
&ntype, "NodeBlurData", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_viewer.cc b/source/blender/nodes/composite/nodes/node_composite_viewer.cc
index 4e82b31ca47..682b0626ccd 100644
--- a/source/blender/nodes/composite/nodes/node_composite_viewer.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_viewer.cc
@@ -35,7 +35,7 @@ static void cmp_node_viewer_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Float>(N_("Z")).default_value(1.0f).min(0.0f).max(1.0f);
}
-static void node_composit_init_viewer(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_composit_init_viewer(bNodeTree * /*ntree*/, bNode *node)
{
ImageUser *iuser = MEM_cnew<ImageUser>(__func__);
node->storage = iuser;
@@ -46,12 +46,12 @@ static void node_composit_init_viewer(bNodeTree *UNUSED(ntree), bNode *node)
node->id = (ID *)BKE_image_ensure_viewer(G.main, IMA_TYPE_COMPOSITE, "Viewer Node");
}
-static void node_composit_buts_viewer(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_viewer(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "use_alpha", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
}
-static void node_composit_buts_viewer_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_viewer_ex(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
@@ -196,7 +196,7 @@ void register_node_type_cmp_viewer()
ntype.draw_buttons = file_ns::node_composit_buts_viewer;
ntype.draw_buttons_ex = file_ns::node_composit_buts_viewer_ex;
ntype.flag |= NODE_PREVIEW;
- node_type_init(&ntype, file_ns::node_composit_init_viewer);
+ ntype.initfunc = file_ns::node_composit_init_viewer;
node_type_storage(&ntype, "ImageUser", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
diff --git a/source/blender/nodes/composite/nodes/node_composite_zcombine.cc b/source/blender/nodes/composite/nodes/node_composite_zcombine.cc
index e5f460099e9..c1d9442e9ad 100644
--- a/source/blender/nodes/composite/nodes/node_composite_zcombine.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_zcombine.cc
@@ -26,7 +26,7 @@ static void cmp_node_zcombine_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Z"));
}
-static void node_composit_buts_zcombine(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_zcombine(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
diff --git a/source/blender/nodes/function/node_function_util.cc b/source/blender/nodes/function/node_function_util.cc
index d956f91a91d..82459815b77 100644
--- a/source/blender/nodes/function/node_function_util.cc
+++ b/source/blender/nodes/function/node_function_util.cc
@@ -5,7 +5,7 @@
#include "NOD_socket_search_link.hh"
-static bool fn_node_poll_default(bNodeType *UNUSED(ntype),
+static bool fn_node_poll_default(bNodeType * /*ntype*/,
bNodeTree *ntree,
const char **r_disabled_hint)
{
diff --git a/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc b/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc
index e5c89567d44..9e21fc86871 100644
--- a/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc
+++ b/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc
@@ -26,7 +26,7 @@ static void fn_node_align_euler_to_vector_declare(NodeDeclarationBuilder &b)
}
static void fn_node_align_euler_to_vector_layout(uiLayout *layout,
- bContext *UNUSED(C),
+ bContext * /*C*/,
PointerRNA *ptr)
{
uiItemR(layout, ptr, "axis", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
@@ -159,7 +159,7 @@ class MF_AlignEulerToVector : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<float3> &input_rotations = params.readonly_single_input<float3>(0, "Rotation");
const VArray<float> &factors = params.readonly_single_input<float>(1, "Factor");
diff --git a/source/blender/nodes/function/nodes/node_fn_boolean_math.cc b/source/blender/nodes/function/nodes/node_fn_boolean_math.cc
index 5fc28509a49..3027a81807b 100644
--- a/source/blender/nodes/function/nodes/node_fn_boolean_math.cc
+++ b/source/blender/nodes/function/nodes/node_fn_boolean_math.cc
@@ -22,7 +22,7 @@ static void fn_node_boolean_math_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Bool>(N_("Boolean"));
}
-static void fn_node_boolean_math_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void fn_node_boolean_math_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
}
@@ -34,7 +34,7 @@ static void node_boolean_math_update(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, sockB, !ELEM(node->custom1, NODE_BOOLEAN_MATH_NOT));
}
-static void node_boolean_math_label(const bNodeTree *UNUSED(ntree),
+static void node_boolean_math_label(const bNodeTree * /*tree*/,
const bNode *node,
char *label,
int maxlen)
@@ -131,7 +131,7 @@ void register_node_type_fn_boolean_math()
fn_node_type_base(&ntype, FN_NODE_BOOLEAN_MATH, "Boolean Math", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::fn_node_boolean_math_declare;
ntype.labelfunc = file_ns::node_boolean_math_label;
- node_type_update(&ntype, file_ns::node_boolean_math_update);
+ ntype.updatefunc = file_ns::node_boolean_math_update;
ntype.build_multi_function = file_ns::fn_node_boolean_math_build_multi_function;
ntype.draw_buttons = file_ns::fn_node_boolean_math_layout;
ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
diff --git a/source/blender/nodes/function/nodes/node_fn_combine_color.cc b/source/blender/nodes/function/nodes/node_fn_combine_color.cc
index 450cd166e78..c5dd5dfff1a 100644
--- a/source/blender/nodes/function/nodes/node_fn_combine_color.cc
+++ b/source/blender/nodes/function/nodes/node_fn_combine_color.cc
@@ -31,18 +31,18 @@ static void fn_node_combine_color_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Color"));
};
-static void fn_node_combine_color_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void fn_node_combine_color_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
-static void fn_node_combine_color_update(bNodeTree *UNUSED(ntree), bNode *node)
+static void fn_node_combine_color_update(bNodeTree * /*tree*/, bNode *node)
{
const NodeCombSepColor &storage = node_storage(*node);
node_combsep_color_label(&node->inputs, (NodeCombSepColorMode)storage.mode);
}
-static void fn_node_combine_color_init(bNodeTree *UNUSED(tree), bNode *node)
+static void fn_node_combine_color_init(bNodeTree * /*tree*/, bNode *node)
{
NodeCombSepColor *data = MEM_cnew<NodeCombSepColor>(__func__);
data->mode = NODE_COMBSEP_COLOR_RGB;
@@ -97,8 +97,8 @@ void register_node_type_fn_combine_color(void)
fn_node_type_base(&ntype, FN_NODE_COMBINE_COLOR, "Combine Color", NODE_CLASS_CONVERTER);
ntype.declare = blender::nodes::fn_node_combine_color_declare;
- node_type_update(&ntype, blender::nodes::fn_node_combine_color_update);
- node_type_init(&ntype, blender::nodes::fn_node_combine_color_init);
+ ntype.updatefunc = blender::nodes::fn_node_combine_color_update;
+ ntype.initfunc = blender::nodes::fn_node_combine_color_init;
node_type_storage(
&ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
ntype.build_multi_function = blender::nodes::fn_node_combine_color_build_multi_function;
diff --git a/source/blender/nodes/function/nodes/node_fn_compare.cc b/source/blender/nodes/function/nodes/node_fn_compare.cc
index 122d1a3c93e..c0eb3e9ffd5 100644
--- a/source/blender/nodes/function/nodes/node_fn_compare.cc
+++ b/source/blender/nodes/function/nodes/node_fn_compare.cc
@@ -44,7 +44,7 @@ static void fn_node_compare_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Bool>(N_("Result"));
}
-static void geo_node_compare_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void geo_node_compare_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
const NodeFunctionCompare &data = node_storage(*static_cast<const bNode *>(ptr->data));
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
@@ -82,7 +82,7 @@ static void node_compare_update(bNodeTree *ntree, bNode *node)
data->data_type == SOCK_VECTOR);
}
-static void node_compare_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_compare_init(bNodeTree * /*tree*/, bNode *node)
{
NodeFunctionCompare *data = MEM_cnew<NodeFunctionCompare>(__func__);
data->operation = NODE_COMPARE_GREATER_THAN;
@@ -148,7 +148,7 @@ static void node_compare_gather_link_searches(GatherLinkSearchOpParams &params)
}
}
-static void node_compare_label(const bNodeTree *UNUSED(ntree),
+static void node_compare_label(const bNodeTree * /*tree*/,
const bNode *node,
char *label,
int maxlen)
@@ -582,8 +582,8 @@ void register_node_type_fn_compare()
fn_node_type_base(&ntype, FN_NODE_COMPARE, "Compare", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::fn_node_compare_declare;
ntype.labelfunc = file_ns::node_compare_label;
- node_type_update(&ntype, file_ns::node_compare_update);
- node_type_init(&ntype, file_ns::node_compare_init);
+ ntype.updatefunc = file_ns::node_compare_update;
+ ntype.initfunc = file_ns::node_compare_init;
node_type_storage(
&ntype, "NodeFunctionCompare", node_free_standard_storage, node_copy_standard_storage);
ntype.build_multi_function = file_ns::fn_node_compare_build_multi_function;
diff --git a/source/blender/nodes/function/nodes/node_fn_float_to_int.cc b/source/blender/nodes/function/nodes/node_fn_float_to_int.cc
index aad2f532d20..aa039309b3f 100644
--- a/source/blender/nodes/function/nodes/node_fn_float_to_int.cc
+++ b/source/blender/nodes/function/nodes/node_fn_float_to_int.cc
@@ -21,12 +21,12 @@ static void fn_node_float_to_int_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Int>(N_("Integer"));
}
-static void fn_node_float_to_int_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void fn_node_float_to_int_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "rounding_mode", 0, "", ICON_NONE);
}
-static void node_float_to_int_label(const bNodeTree *UNUSED(ntree),
+static void node_float_to_int_label(const bNodeTree * /*tree*/,
const bNode *node,
char *label,
int maxlen)
@@ -43,13 +43,13 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode)
{
static auto exec_preset = fn::CustomMF_presets::AllSpanOrSingle();
static fn::CustomMF_SI_SO<float, int> round_fn{
- "Round", [](float a) { return (int)round(a); }, exec_preset};
+ "Round", [](float a) { return int(round(a)); }, exec_preset};
static fn::CustomMF_SI_SO<float, int> floor_fn{
- "Floor", [](float a) { return (int)floor(a); }, exec_preset};
+ "Floor", [](float a) { return int(floor(a)); }, exec_preset};
static fn::CustomMF_SI_SO<float, int> ceil_fn{
- "Ceiling", [](float a) { return (int)ceil(a); }, exec_preset};
+ "Ceiling", [](float a) { return int(ceil(a)); }, exec_preset};
static fn::CustomMF_SI_SO<float, int> trunc_fn{
- "Truncate", [](float a) { return (int)trunc(a); }, exec_preset};
+ "Truncate", [](float a) { return int(trunc(a)); }, exec_preset};
switch (static_cast<FloatToIntRoundingMode>(bnode.custom1)) {
case FN_NODE_FLOAT_TO_INT_ROUND:
diff --git a/source/blender/nodes/function/nodes/node_fn_input_bool.cc b/source/blender/nodes/function/nodes/node_fn_input_bool.cc
index 717f4d1ac6b..62e0358b0ae 100644
--- a/source/blender/nodes/function/nodes/node_fn_input_bool.cc
+++ b/source/blender/nodes/function/nodes/node_fn_input_bool.cc
@@ -14,7 +14,7 @@ static void fn_node_input_bool_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Bool>(N_("Boolean"));
}
-static void fn_node_input_bool_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void fn_node_input_bool_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "boolean", UI_ITEM_R_EXPAND, IFACE_("Value"), ICON_NONE);
@@ -27,7 +27,7 @@ static void fn_node_input_bool_build_multi_function(NodeMultiFunctionBuilder &bu
builder.construct_and_set_matching_fn<fn::CustomMF_Constant<bool>>(node_storage->boolean);
}
-static void fn_node_input_bool_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void fn_node_input_bool_init(bNodeTree * /*tree*/, bNode *node)
{
NodeInputBool *data = MEM_cnew<NodeInputBool>(__func__);
node->storage = data;
@@ -43,7 +43,7 @@ void register_node_type_fn_input_bool()
fn_node_type_base(&ntype, FN_NODE_INPUT_BOOL, "Boolean", 0);
ntype.declare = file_ns::fn_node_input_bool_declare;
- node_type_init(&ntype, file_ns::fn_node_input_bool_init);
+ ntype.initfunc = file_ns::fn_node_input_bool_init;
node_type_storage(
&ntype, "NodeInputBool", node_free_standard_storage, node_copy_standard_storage);
ntype.build_multi_function = file_ns::fn_node_input_bool_build_multi_function;
diff --git a/source/blender/nodes/function/nodes/node_fn_input_color.cc b/source/blender/nodes/function/nodes/node_fn_input_color.cc
index cdad1542c66..af4c340efe7 100644
--- a/source/blender/nodes/function/nodes/node_fn_input_color.cc
+++ b/source/blender/nodes/function/nodes/node_fn_input_color.cc
@@ -14,7 +14,7 @@ static void fn_node_input_color_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Color"));
}
-static void fn_node_input_color_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void fn_node_input_color_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiTemplateColorPicker(layout, ptr, "color", true, false, false, true);
uiItemR(layout, ptr, "color", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
@@ -29,7 +29,7 @@ static void fn_node_input_color_build_multi_function(
builder.construct_and_set_matching_fn<blender::fn::CustomMF_Constant<ColorGeometry4f>>(color);
}
-static void fn_node_input_color_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void fn_node_input_color_init(bNodeTree * /*tree*/, bNode *node)
{
NodeInputColor *data = MEM_cnew<NodeInputColor>(__func__);
copy_v4_fl4(data->color, 0.5f, 0.5f, 0.5f, 1.0f);
@@ -46,7 +46,7 @@ void register_node_type_fn_input_color()
fn_node_type_base(&ntype, FN_NODE_INPUT_COLOR, "Color", NODE_CLASS_INPUT);
ntype.declare = file_ns::fn_node_input_color_declare;
- node_type_init(&ntype, file_ns::fn_node_input_color_init);
+ ntype.initfunc = file_ns::fn_node_input_color_init;
node_type_storage(
&ntype, "NodeInputColor", node_free_standard_storage, node_copy_standard_storage);
ntype.build_multi_function = file_ns::fn_node_input_color_build_multi_function;
diff --git a/source/blender/nodes/function/nodes/node_fn_input_int.cc b/source/blender/nodes/function/nodes/node_fn_input_int.cc
index 16506b5f9b8..c339d2a348e 100644
--- a/source/blender/nodes/function/nodes/node_fn_input_int.cc
+++ b/source/blender/nodes/function/nodes/node_fn_input_int.cc
@@ -14,7 +14,7 @@ static void fn_node_input_int_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Int>(N_("Integer"));
}
-static void fn_node_input_int_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void fn_node_input_int_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "integer", UI_ITEM_R_EXPAND, "", ICON_NONE);
@@ -27,7 +27,7 @@ static void fn_node_input_int_build_multi_function(NodeMultiFunctionBuilder &bui
builder.construct_and_set_matching_fn<fn::CustomMF_Constant<int>>(node_storage->integer);
}
-static void fn_node_input_int_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void fn_node_input_int_init(bNodeTree * /*tree*/, bNode *node)
{
NodeInputInt *data = MEM_cnew<NodeInputInt>(__func__);
node->storage = data;
@@ -43,7 +43,7 @@ void register_node_type_fn_input_int()
fn_node_type_base(&ntype, FN_NODE_INPUT_INT, "Integer", 0);
ntype.declare = file_ns::fn_node_input_int_declare;
- node_type_init(&ntype, file_ns::fn_node_input_int_init);
+ ntype.initfunc = file_ns::fn_node_input_int_init;
node_type_storage(
&ntype, "NodeInputInt", node_free_standard_storage, node_copy_standard_storage);
ntype.build_multi_function = file_ns::fn_node_input_int_build_multi_function;
diff --git a/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc b/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc
index 88dc95aa026..b61bd6b5e22 100644
--- a/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc
+++ b/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc
@@ -26,7 +26,7 @@ class MF_SpecialCharacters : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
MutableSpan<std::string> lb = params.uninitialized_single_output<std::string>(0, "Line Break");
MutableSpan<std::string> tab = params.uninitialized_single_output<std::string>(1, "Tab");
diff --git a/source/blender/nodes/function/nodes/node_fn_input_string.cc b/source/blender/nodes/function/nodes/node_fn_input_string.cc
index 129d19f4f04..9da17ef9a67 100644
--- a/source/blender/nodes/function/nodes/node_fn_input_string.cc
+++ b/source/blender/nodes/function/nodes/node_fn_input_string.cc
@@ -13,7 +13,7 @@ static void fn_node_input_string_declare(NodeDeclarationBuilder &b)
b.add_output<decl::String>(N_("String"));
}
-static void fn_node_input_string_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void fn_node_input_string_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "string", 0, "", ICON_NONE);
}
@@ -26,7 +26,7 @@ static void fn_node_input_string_build_multi_function(NodeMultiFunctionBuilder &
builder.construct_and_set_matching_fn<fn::CustomMF_Constant<std::string>>(std::move(string));
}
-static void fn_node_input_string_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void fn_node_input_string_init(bNodeTree * /*tree*/, bNode *node)
{
node->storage = MEM_callocN(sizeof(NodeInputString), __func__);
}
@@ -43,9 +43,7 @@ static void fn_node_input_string_free(bNode *node)
MEM_freeN(storage);
}
-static void fn_node_string_copy(bNodeTree *UNUSED(dest_ntree),
- bNode *dest_node,
- const bNode *src_node)
+static void fn_node_string_copy(bNodeTree * /*dst_ntree*/, bNode *dest_node, const bNode *src_node)
{
NodeInputString *source_storage = (NodeInputString *)src_node->storage;
NodeInputString *destination_storage = (NodeInputString *)MEM_dupallocN(source_storage);
@@ -67,7 +65,7 @@ void register_node_type_fn_input_string()
fn_node_type_base(&ntype, FN_NODE_INPUT_STRING, "String", NODE_CLASS_INPUT);
ntype.declare = file_ns::fn_node_input_string_declare;
- node_type_init(&ntype, file_ns::fn_node_input_string_init);
+ ntype.initfunc = file_ns::fn_node_input_string_init;
node_type_storage(
&ntype, "NodeInputString", file_ns::fn_node_input_string_free, file_ns::fn_node_string_copy);
ntype.build_multi_function = file_ns::fn_node_input_string_build_multi_function;
diff --git a/source/blender/nodes/function/nodes/node_fn_input_vector.cc b/source/blender/nodes/function/nodes/node_fn_input_vector.cc
index de894a4038d..f6feda4cad0 100644
--- a/source/blender/nodes/function/nodes/node_fn_input_vector.cc
+++ b/source/blender/nodes/function/nodes/node_fn_input_vector.cc
@@ -14,7 +14,7 @@ static void fn_node_input_vector_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Vector"));
}
-static void fn_node_input_vector_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void fn_node_input_vector_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "vector", UI_ITEM_R_EXPAND, "", ICON_NONE);
@@ -28,7 +28,7 @@ static void fn_node_input_vector_build_multi_function(NodeMultiFunctionBuilder &
builder.construct_and_set_matching_fn<fn::CustomMF_Constant<float3>>(vector);
}
-static void fn_node_input_vector_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void fn_node_input_vector_init(bNodeTree * /*tree*/, bNode *node)
{
NodeInputVector *data = MEM_cnew<NodeInputVector>(__func__);
node->storage = data;
@@ -44,7 +44,7 @@ void register_node_type_fn_input_vector()
fn_node_type_base(&ntype, FN_NODE_INPUT_VECTOR, "Vector", 0);
ntype.declare = file_ns::fn_node_input_vector_declare;
- node_type_init(&ntype, file_ns::fn_node_input_vector_init);
+ ntype.initfunc = file_ns::fn_node_input_vector_init;
node_type_storage(
&ntype, "NodeInputVector", node_free_standard_storage, node_copy_standard_storage);
ntype.build_multi_function = file_ns::fn_node_input_vector_build_multi_function;
diff --git a/source/blender/nodes/function/nodes/node_fn_random_value.cc b/source/blender/nodes/function/nodes/node_fn_random_value.cc
index 360695299cb..c923e6e7d16 100644
--- a/source/blender/nodes/function/nodes/node_fn_random_value.cc
+++ b/source/blender/nodes/function/nodes/node_fn_random_value.cc
@@ -33,7 +33,7 @@ static void fn_node_random_value_declare(NodeDeclarationBuilder &b)
.subtype(PROP_FACTOR)
.supports_field()
.make_available([](bNode &node) { node_storage(node).data_type = CD_PROP_BOOL; });
- b.add_input<decl::Int>(N_("ID")).implicit_field();
+ b.add_input<decl::Int>(N_("ID")).implicit_field(implicit_field_inputs::id_or_index);
b.add_input<decl::Int>(N_("Seed")).default_value(0).min(-10000).max(10000).supports_field();
b.add_output<decl::Vector>(N_("Value")).dependent_field();
@@ -42,12 +42,12 @@ static void fn_node_random_value_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Bool>(N_("Value"), "Value_003").dependent_field();
}
-static void fn_node_random_value_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void fn_node_random_value_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
}
-static void fn_node_random_value_init(bNodeTree *UNUSED(tree), bNode *node)
+static void fn_node_random_value_init(bNodeTree * /*tree*/, bNode *node)
{
NodeRandomValue *data = MEM_cnew<NodeRandomValue>(__func__);
data->data_type = CD_PROP_FLOAT;
@@ -218,8 +218,8 @@ void register_node_type_fn_random_value()
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_RANDOM_VALUE, "Random Value", NODE_CLASS_CONVERTER);
- node_type_init(&ntype, file_ns::fn_node_random_value_init);
- node_type_update(&ntype, file_ns::fn_node_random_value_update);
+ ntype.initfunc = file_ns::fn_node_random_value_init;
+ ntype.updatefunc = file_ns::fn_node_random_value_update;
ntype.draw_buttons = file_ns::fn_node_random_value_layout;
ntype.declare = file_ns::fn_node_random_value_declare;
ntype.build_multi_function = file_ns::fn_node_random_value_build_multi_function;
diff --git a/source/blender/nodes/function/nodes/node_fn_rotate_euler.cc b/source/blender/nodes/function/nodes/node_fn_rotate_euler.cc
index 299c0f7a932..19afadb7a33 100644
--- a/source/blender/nodes/function/nodes/node_fn_rotate_euler.cc
+++ b/source/blender/nodes/function/nodes/node_fn_rotate_euler.cc
@@ -46,7 +46,7 @@ static void fn_node_rotate_euler_update(bNodeTree *ntree, bNode *node)
ntree, angle_socket, ELEM(node->custom1, FN_NODE_ROTATE_EULER_TYPE_AXIS_ANGLE));
}
-static void fn_node_rotate_euler_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void fn_node_rotate_euler_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "type", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
uiItemR(layout, ptr, "space", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
@@ -132,7 +132,7 @@ void register_node_type_fn_rotate_euler()
fn_node_type_base(&ntype, FN_NODE_ROTATE_EULER, "Rotate Euler", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::fn_node_rotate_euler_declare;
ntype.draw_buttons = file_ns::fn_node_rotate_euler_layout;
- node_type_update(&ntype, file_ns::fn_node_rotate_euler_update);
+ ntype.updatefunc = file_ns::fn_node_rotate_euler_update;
ntype.build_multi_function = file_ns::fn_node_rotate_euler_build_multi_function;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/function/nodes/node_fn_separate_color.cc b/source/blender/nodes/function/nodes/node_fn_separate_color.cc
index 19613427835..e3efb76d155 100644
--- a/source/blender/nodes/function/nodes/node_fn_separate_color.cc
+++ b/source/blender/nodes/function/nodes/node_fn_separate_color.cc
@@ -19,18 +19,18 @@ static void fn_node_separate_color_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Alpha"));
};
-static void fn_node_separate_color_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void fn_node_separate_color_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
-static void fn_node_separate_color_update(bNodeTree *UNUSED(ntree), bNode *node)
+static void fn_node_separate_color_update(bNodeTree * /*tree*/, bNode *node)
{
const NodeCombSepColor &storage = node_storage(*node);
node_combsep_color_label(&node->outputs, (NodeCombSepColorMode)storage.mode);
}
-static void fn_node_separate_color_init(bNodeTree *UNUSED(tree), bNode *node)
+static void fn_node_separate_color_init(bNodeTree * /*tree*/, bNode *node)
{
NodeCombSepColor *data = MEM_cnew<NodeCombSepColor>(__func__);
data->mode = NODE_COMBSEP_COLOR_RGB;
@@ -56,7 +56,7 @@ class SeparateRGBAFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
"Color");
@@ -117,7 +117,7 @@ class SeparateHSVAFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
"Color");
@@ -157,7 +157,7 @@ class SeparateHSLAFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
"Color");
@@ -213,8 +213,8 @@ void register_node_type_fn_separate_color(void)
fn_node_type_base(&ntype, FN_NODE_SEPARATE_COLOR, "Separate Color", NODE_CLASS_CONVERTER);
ntype.declare = blender::nodes::fn_node_separate_color_declare;
- node_type_update(&ntype, blender::nodes::fn_node_separate_color_update);
- node_type_init(&ntype, blender::nodes::fn_node_separate_color_init);
+ ntype.updatefunc = blender::nodes::fn_node_separate_color_update;
+ ntype.initfunc = blender::nodes::fn_node_separate_color_init;
node_type_storage(
&ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
ntype.build_multi_function = blender::nodes::fn_node_separate_color_build_multi_function;
diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt
index 31c00cc6b82..2b8de906a77 100644
--- a/source/blender/nodes/geometry/CMakeLists.txt
+++ b/source/blender/nodes/geometry/CMakeLists.txt
@@ -56,9 +56,12 @@ set(SRC
nodes/node_geo_curve_subdivide.cc
nodes/node_geo_curve_to_mesh.cc
nodes/node_geo_curve_to_points.cc
+ nodes/node_geo_curve_topology_curve_of_point.cc
+ nodes/node_geo_curve_topology_points_of_curve.cc
nodes/node_geo_curve_trim.cc
nodes/node_geo_deform_curves_on_surface.cc
nodes/node_geo_delete_geometry.cc
+ nodes/node_geo_distribute_points_in_volume.cc
nodes/node_geo_distribute_points_on_faces.cc
nodes/node_geo_dual_mesh.cc
nodes/node_geo_duplicate_elements.cc
@@ -105,6 +108,7 @@ set(SRC
nodes/node_geo_material_replace.cc
nodes/node_geo_material_selection.cc
nodes/node_geo_merge_by_distance.cc
+ nodes/node_geo_mesh_face_set_boundaries.cc
nodes/node_geo_mesh_primitive_circle.cc
nodes/node_geo_mesh_primitive_cone.cc
nodes/node_geo_mesh_primitive_cube.cc
@@ -117,7 +121,15 @@ set(SRC
nodes/node_geo_mesh_to_curve.cc
nodes/node_geo_mesh_to_points.cc
nodes/node_geo_mesh_to_volume.cc
+ nodes/node_geo_mesh_topology_corners_of_face.cc
+ nodes/node_geo_mesh_topology_corners_of_vertex.cc
+ nodes/node_geo_mesh_topology_edges_of_corner.cc
+ nodes/node_geo_mesh_topology_edges_of_vertex.cc
+ nodes/node_geo_mesh_topology_face_of_corner.cc
+ nodes/node_geo_mesh_topology_offset_corner_in_face.cc
+ nodes/node_geo_mesh_topology_vertex_of_corner.cc
nodes/node_geo_object_info.cc
+ nodes/node_geo_offset_point_in_curve.cc
nodes/node_geo_points.cc
nodes/node_geo_points_to_vertices.cc
nodes/node_geo_points_to_volume.cc
@@ -126,11 +138,17 @@ set(SRC
nodes/node_geo_realize_instances.cc
nodes/node_geo_remove_attribute.cc
nodes/node_geo_rotate_instances.cc
+ nodes/node_geo_sample_index.cc
+ nodes/node_geo_sample_nearest.cc
+ nodes/node_geo_sample_nearest_surface.cc
+ nodes/node_geo_sample_uv_surface.cc
nodes/node_geo_scale_elements.cc
nodes/node_geo_scale_instances.cc
+ nodes/node_geo_self_object.cc
nodes/node_geo_separate_components.cc
nodes/node_geo_separate_geometry.cc
nodes/node_geo_set_curve_handles.cc
+ nodes/node_geo_set_curve_normal.cc
nodes/node_geo_set_curve_radius.cc
nodes/node_geo_set_curve_tilt.cc
nodes/node_geo_set_id.cc
@@ -146,7 +164,6 @@ set(SRC
nodes/node_geo_string_to_curves.cc
nodes/node_geo_subdivision_surface.cc
nodes/node_geo_switch.cc
- nodes/node_geo_transfer_attribute.cc
nodes/node_geo_transform.cc
nodes/node_geo_translate_instances.cc
nodes/node_geo_triangulate.cc
@@ -187,20 +204,6 @@ if(WITH_BULLET)
add_definitions(-DWITH_BULLET)
endif()
-if(WITH_PYTHON)
- list(APPEND INC
- ../../python
- )
- list(APPEND INC_SYS
- ${PYTHON_INCLUDE_DIRS}
- )
- list(APPEND LIB
- ${PYTHON_LINKFLAGS}
- ${PYTHON_LIBRARIES}
- )
- add_definitions(-DWITH_PYTHON)
-endif()
-
if(WITH_TBB)
list(APPEND INC_SYS
${TBB_INCLUDE_DIRS}
diff --git a/source/blender/nodes/geometry/node_geometry_tree.cc b/source/blender/nodes/geometry/node_geometry_tree.cc
index c6914bbcb0c..1339024b776 100644
--- a/source/blender/nodes/geometry/node_geometry_tree.cc
+++ b/source/blender/nodes/geometry/node_geometry_tree.cc
@@ -26,13 +26,12 @@
bNodeTreeType *ntreeType_Geometry;
-static void geometry_node_tree_get_from_context(const bContext *C,
- bNodeTreeType *UNUSED(treetype),
- bNodeTree **r_ntree,
- ID **r_id,
- ID **r_from)
+static void geometry_node_tree_get_from_context(
+ const bContext *C, bNodeTreeType * /*treetype*/, bNodeTree **r_ntree, ID **r_id, ID **r_from)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ob == nullptr) {
@@ -46,7 +45,7 @@ static void geometry_node_tree_get_from_context(const bContext *C,
}
if (md->type == eModifierType_Nodes) {
- NodesModifierData *nmd = (NodesModifierData *)md;
+ const NodesModifierData *nmd = reinterpret_cast<const NodesModifierData *>(md);
if (nmd->node_group != nullptr) {
*r_from = &ob->id;
*r_id = &ob->id;
@@ -63,7 +62,7 @@ static void geometry_node_tree_update(bNodeTree *ntree)
ntree_update_reroute_nodes(ntree);
}
-static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func)
+static void foreach_nodeclass(Scene * /*scene*/, void *calldata, bNodeClassCallback func)
{
func(calldata, NODE_CLASS_INPUT, N_("Input"));
func(calldata, NODE_CLASS_GEOMETRY, N_("Geometry"));
@@ -86,7 +85,7 @@ static bool geometry_node_tree_validate_link(eNodeSocketDatatype type_a,
return type_a == type_b;
}
-static bool geometry_node_tree_socket_type_valid(bNodeTreeType *UNUSED(ntreetype),
+static bool geometry_node_tree_socket_type_valid(bNodeTreeType * /*treetype*/,
bNodeSocketType *socket_type)
{
return nodeIsStaticSocketType(socket_type) && ELEM(socket_type->type,
diff --git a/source/blender/nodes/geometry/node_geometry_util.cc b/source/blender/nodes/geometry/node_geometry_util.cc
index 8f673d2264e..8b962d39b3c 100644
--- a/source/blender/nodes/geometry/node_geometry_util.cc
+++ b/source/blender/nodes/geometry/node_geometry_util.cc
@@ -36,14 +36,12 @@ std::optional<eCustomDataType> node_data_type_to_custom_data_type(const eNodeSoc
std::optional<eCustomDataType> node_socket_to_custom_data_type(const bNodeSocket &socket)
{
- return node_data_type_to_custom_data_type(static_cast<eNodeSocketDatatype>(socket.type));
+ return node_data_type_to_custom_data_type(eNodeSocketDatatype(socket.type));
}
} // namespace blender::nodes
-bool geo_node_poll_default(bNodeType *UNUSED(ntype),
- bNodeTree *ntree,
- const char **r_disabled_hint)
+bool geo_node_poll_default(bNodeType * /*ntype*/, bNodeTree *ntree, const char **r_disabled_hint)
{
if (!STREQ(ntree->idname, "GeometryNodeTree")) {
*r_disabled_hint = TIP_("Not a geometry node tree");
diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh
index 4db4d8bb097..adcf47f57fe 100644
--- a/source/blender/nodes/geometry/node_geometry_util.hh
+++ b/source/blender/nodes/geometry/node_geometry_util.hh
@@ -24,6 +24,8 @@
#include "node_util.h"
+struct BVHTreeFromMesh;
+
void geo_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass);
bool geo_node_poll_default(struct bNodeType *ntype,
struct bNodeTree *ntree,
@@ -78,7 +80,34 @@ void separate_geometry(GeometrySet &geometry_set,
const Field<bool> &selection_field,
bool &r_is_error);
+void get_closest_in_bvhtree(BVHTreeFromMesh &tree_data,
+ const VArray<float3> &positions,
+ const IndexMask mask,
+ const MutableSpan<int> r_indices,
+ const MutableSpan<float> r_distances_sq,
+ const MutableSpan<float3> r_positions);
+
+int apply_offset_in_cyclic_range(IndexRange range, int start_index, int offset);
+
std::optional<eCustomDataType> node_data_type_to_custom_data_type(eNodeSocketDatatype type);
std::optional<eCustomDataType> node_socket_to_custom_data_type(const bNodeSocket &socket);
+class FieldAtIndexInput final : public bke::GeometryFieldInput {
+ private:
+ Field<int> index_field_;
+ GField value_field_;
+ eAttrDomain value_field_domain_;
+
+ public:
+ FieldAtIndexInput(Field<int> index_field, GField value_field, eAttrDomain value_field_domain);
+
+ GVArray get_varray_for_context(const bke::GeometryFieldContext &context,
+ const IndexMask mask) const final;
+
+ std::optional<eAttrDomain> preferred_domain(const GeometryComponent & /*component*/) const final
+ {
+ return value_field_domain_;
+ }
+};
+
} // namespace blender::nodes
diff --git a/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc b/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc
index 13a9cdc8600..33a58cada1b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc
@@ -70,13 +70,13 @@ static void node_declare(NodeDeclarationBuilder &b)
.description(N_(total_out_description));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeAccumulateField *data = MEM_cnew<NodeAccumulateField>(__func__);
data->data_type = CD_PROP_FLOAT;
@@ -87,13 +87,13 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeAccumulateField &storage = node_storage(*node);
- const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
+ const eCustomDataType data_type = eCustomDataType(storage.data_type);
- bNodeSocket *sock_in_vector = (bNodeSocket *)node->inputs.first;
+ bNodeSocket *sock_in_vector = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *sock_in_float = sock_in_vector->next;
bNodeSocket *sock_in_int = sock_in_float->next;
- bNodeSocket *sock_out_vector = (bNodeSocket *)node->outputs.first;
+ bNodeSocket *sock_out_vector = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *sock_out_float = sock_out_vector->next;
bNodeSocket *sock_out_int = sock_out_float->next;
@@ -285,6 +285,12 @@ template<typename T> class AccumulateFieldInput final : public bke::GeometryFiel
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(
+ const GeometryComponent & /*component*/) const override
+ {
+ return source_domain_;
+ }
};
template<typename T> class TotalFieldInput final : public bke::GeometryFieldInput {
@@ -355,6 +361,12 @@ template<typename T> class TotalFieldInput final : public bke::GeometryFieldInpu
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(
+ const GeometryComponent & /*component*/) const override
+ {
+ return source_domain_;
+ }
};
template<typename T> std::string identifier_suffix()
@@ -373,8 +385,8 @@ template<typename T> std::string identifier_suffix()
static void node_geo_exec(GeoNodeExecParams params)
{
const NodeAccumulateField &storage = node_storage(params.node());
- const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
- const eAttrDomain source_domain = static_cast<eAttrDomain>(storage.domain);
+ const eCustomDataType data_type = eCustomDataType(storage.data_type);
+ const eAttrDomain source_domain = eAttrDomain(storage.domain);
Field<int> group_index_field = params.extract_input<Field<int>>("Group Index");
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
@@ -413,8 +425,8 @@ void register_node_type_geo_accumulate_field()
geo_node_type_base(&ntype, GEO_NODE_ACCUMULATE_FIELD, "Accumulate Field", NODE_CLASS_CONVERTER);
ntype.geometry_node_execute = file_ns::node_geo_exec;
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
ntype.draw_buttons = file_ns::node_layout;
ntype.declare = file_ns::node_declare;
ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc
index 8c11288efdd..1a0cb14f451 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc
@@ -30,7 +30,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Int>(N_("Attribute"), "Attribute_004").field_source();
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
@@ -38,7 +38,7 @@ static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryAttributeCapture *data = MEM_cnew<NodeGeometryAttributeCapture>(__func__);
data->data_type = CD_PROP_FLOAT;
@@ -50,9 +50,9 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryAttributeCapture &storage = node_storage(*node);
- const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
+ const eCustomDataType data_type = eCustomDataType(storage.data_type);
- bNodeSocket *socket_value_geometry = (bNodeSocket *)node->inputs.first;
+ bNodeSocket *socket_value_geometry = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *socket_value_vector = socket_value_geometry->next;
bNodeSocket *socket_value_float = socket_value_vector->next;
bNodeSocket *socket_value_color4f = socket_value_float->next;
@@ -65,7 +65,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, socket_value_boolean, data_type == CD_PROP_BOOL);
nodeSetSocketAvailability(ntree, socket_value_int32, data_type == CD_PROP_INT32);
- bNodeSocket *out_socket_value_geometry = (bNodeSocket *)node->outputs.first;
+ bNodeSocket *out_socket_value_geometry = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *out_socket_value_vector = out_socket_value_geometry->next;
bNodeSocket *out_socket_value_float = out_socket_value_vector->next;
bNodeSocket *out_socket_value_color4f = out_socket_value_float->next;
@@ -106,33 +106,6 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
}
}
-static void try_capture_field_on_geometry(GeometryComponent &component,
- const AttributeIDRef &attribute_id,
- const eAttrDomain domain,
- const GField &field)
-{
- const int domain_size = component.attribute_domain_size(domain);
- if (domain_size == 0) {
- return;
- }
- bke::GeometryFieldContext field_context{component, domain};
- MutableAttributeAccessor attributes = *component.attributes_for_write();
- const IndexMask mask{IndexMask(domain_size)};
-
- const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(field.cpp_type());
- GAttributeWriter output_attribute = attributes.lookup_or_add_for_write(
- attribute_id, domain, data_type);
- if (!output_attribute) {
- return;
- }
-
- fn::FieldEvaluator evaluator{field_context, &mask};
- evaluator.add_with_destination(field, output_attribute.varray);
- evaluator.evaluate();
-
- output_attribute.finish();
-}
-
static StringRefNull identifier_suffix(eCustomDataType data_type)
{
switch (data_type) {
@@ -165,8 +138,8 @@ static void node_geo_exec(GeoNodeExecParams params)
}
const NodeGeometryAttributeCapture &storage = node_storage(params.node());
- const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
- const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain);
+ const eCustomDataType data_type = eCustomDataType(storage.data_type);
+ const eAttrDomain domain = eAttrDomain(storage.domain);
const std::string output_identifier = "Attribute" + identifier_suffix(data_type);
@@ -206,7 +179,7 @@ static void node_geo_exec(GeoNodeExecParams params)
if (geometry_set.has_instances()) {
GeometryComponent &component = geometry_set.get_component_for_write(
GEO_COMPONENT_TYPE_INSTANCES);
- try_capture_field_on_geometry(component, anonymous_id.get(), domain, field);
+ bke::try_capture_field_on_geometry(component, anonymous_id.get(), domain, field);
}
}
else {
@@ -217,7 +190,7 @@ static void node_geo_exec(GeoNodeExecParams params)
for (const GeometryComponentType type : types) {
if (geometry_set.has(type)) {
GeometryComponent &component = geometry_set.get_component_for_write(type);
- try_capture_field_on_geometry(component, anonymous_id.get(), domain, field);
+ bke::try_capture_field_on_geometry(component, anonymous_id.get(), domain, field);
}
}
});
@@ -268,8 +241,8 @@ void register_node_type_geo_attribute_capture()
"NodeGeometryAttributeCapture",
node_free_standard_storage,
node_copy_standard_storage);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
ntype.declare = file_ns::node_declare;
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.draw_buttons = file_ns::node_layout;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc
index f6ea6073459..d31366f9c93 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc
@@ -30,19 +30,19 @@ static void node_declare(NodeDeclarationBuilder &b)
});
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "component", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
node->custom1 = GEO_COMPONENT_TYPE_MESH;
}
static void node_update(bNodeTree *ntree, bNode *node)
{
- bNodeSocket *point_socket = (bNodeSocket *)node->outputs.first;
+ bNodeSocket *point_socket = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *edge_socket = point_socket->next;
bNodeSocket *face_socket = edge_socket->next;
bNodeSocket *face_corner_socket = face_socket->next;
@@ -132,7 +132,7 @@ void register_node_type_geo_attribute_domain_size()
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_layout;
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
ntype.updatefunc = file_ns::node_update;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc
index af0007c2fa4..e381133af30 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc
@@ -40,13 +40,13 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Variance"), "Variance_001");
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
node->custom1 = CD_PROP_FLOAT;
node->custom2 = ATTR_DOMAIN_POINT;
@@ -54,12 +54,12 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
- bNodeSocket *socket_geo = (bNodeSocket *)node->inputs.first;
+ bNodeSocket *socket_geo = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *socket_selection = socket_geo->next;
bNodeSocket *socket_float_attr = socket_selection->next;
bNodeSocket *socket_float3_attr = socket_float_attr->next;
- bNodeSocket *socket_float_mean = (bNodeSocket *)node->outputs.first;
+ bNodeSocket *socket_float_mean = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *socket_float_median = socket_float_mean->next;
bNodeSocket *socket_float_sum = socket_float_median->next;
bNodeSocket *socket_float_min = socket_float_sum->next;
@@ -77,7 +77,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
bNodeSocket *socket_vector_std = socket_vector_range->next;
bNodeSocket *socket_vector_variance = socket_vector_std->next;
- const eCustomDataType data_type = static_cast<eCustomDataType>(node->custom1);
+ const eCustomDataType data_type = eCustomDataType(node->custom1);
nodeSetSocketAvailability(ntree, socket_float_attr, data_type == CD_PROP_FLOAT);
nodeSetSocketAvailability(ntree, socket_float_mean, data_type == CD_PROP_FLOAT);
@@ -184,8 +184,8 @@ static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.get_input<GeometrySet>("Geometry");
const bNode &node = params.node();
- const eCustomDataType data_type = static_cast<eCustomDataType>(node.custom1);
- const eAttrDomain domain = static_cast<eAttrDomain>(node.custom2);
+ const eCustomDataType data_type = eCustomDataType(node.custom1);
+ const eAttrDomain domain = eAttrDomain(node.custom2);
Vector<const GeometryComponent *> components = geometry_set.get_components_for_read();
const Field<bool> selection_field = params.get_input<Field<bool>>("Selection");
@@ -396,8 +396,8 @@ void register_node_type_geo_attribute_statistic()
&ntype, GEO_NODE_ATTRIBUTE_STATISTIC, "Attribute Statistic", NODE_CLASS_ATTRIBUTE);
ntype.declare = file_ns::node_declare;
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.draw_buttons = file_ns::node_layout;
ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
index c8c58945bce..61780ee25bb 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
@@ -24,7 +24,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Bool>(N_("Intersecting Edges")).field_source();
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
}
@@ -37,7 +37,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
{
GeometryNodeBooleanOperation operation = (GeometryNodeBooleanOperation)node->custom1;
- bNodeSocket *geometry_1_socket = (bNodeSocket *)node->inputs.first;
+ bNodeSocket *geometry_1_socket = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *geometry_2_socket = geometry_1_socket->next;
switch (operation) {
@@ -55,7 +55,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
}
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
node->custom1 = GEO_NODE_BOOLEAN_DIFFERENCE;
}
@@ -148,7 +148,8 @@ static void node_geo_exec(GeoNodeExecParams params)
}
MEM_SAFE_FREE(result->mat);
- result->mat = (Material **)MEM_malloc_arrayN(materials.size(), sizeof(Material *), __func__);
+ result->mat = static_cast<Material **>(
+ MEM_malloc_arrayN(materials.size(), sizeof(Material *), __func__));
result->totcol = materials.size();
MutableSpan(result->mat, result->totcol).copy_from(materials);
@@ -190,7 +191,7 @@ void register_node_type_geo_boolean()
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_layout;
ntype.updatefunc = file_ns::node_update;
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
ntype.geometry_node_execute = file_ns::node_geo_exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc b/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc
index 54a061993a3..6c41dbbe34c 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc
@@ -8,6 +8,7 @@
#include "UI_resources.h"
#include "BKE_collection.h"
+#include "BKE_instances.hh"
#include "node_geometry_util.hh"
@@ -30,12 +31,12 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "transform_space", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void node_node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryCollectionInfo *data = MEM_cnew<NodeGeometryCollectionInfo>(__func__);
data->transform_space = GEO_NODE_TRANSFORM_SPACE_ORIGINAL;
@@ -57,8 +58,8 @@ static void node_geo_exec(GeoNodeExecParams params)
return;
}
const Object *self_object = params.self_object();
- const bool is_recursive = BKE_collection_has_object_recursive_instanced(collection,
- (Object *)self_object);
+ const bool is_recursive = BKE_collection_has_object_recursive_instanced(
+ collection, const_cast<Object *>(self_object));
if (is_recursive) {
params.error_message_add(NodeWarningType::Error, "Collection contains current object");
params.set_default_remaining_outputs();
@@ -69,8 +70,7 @@ static void node_geo_exec(GeoNodeExecParams params)
const bool use_relative_transform = (storage.transform_space ==
GEO_NODE_TRANSFORM_SPACE_RELATIVE);
- GeometrySet geometry_set_out;
- InstancesComponent &instances = geometry_set_out.get_component_for_write<InstancesComponent>();
+ std::unique_ptr<bke::Instances> instances = std::make_unique<bke::Instances>();
const bool separate_children = params.get_input<bool>("Separate Children");
if (separate_children) {
@@ -84,7 +84,7 @@ static void node_geo_exec(GeoNodeExecParams params)
children_objects.append(collection_object->ob);
}
- instances.reserve(children_collections.size() + children_objects.size());
+ instances->reserve(children_collections.size() + children_objects.size());
Vector<InstanceListEntry> entries;
entries.reserve(children_collections.size() + children_objects.size());
@@ -93,26 +93,26 @@ static void node_geo_exec(GeoNodeExecParams params)
if (!reset_children) {
add_v3_v3(transform.values[3], child_collection->instance_offset);
if (use_relative_transform) {
- mul_m4_m4_pre(transform.values, self_object->imat);
+ mul_m4_m4_pre(transform.values, self_object->world_to_object);
}
else {
sub_v3_v3(transform.values[3], collection->instance_offset);
}
}
- const int handle = instances.add_reference(*child_collection);
+ const int handle = instances->add_reference(*child_collection);
entries.append({handle, &(child_collection->id.name[2]), transform});
}
for (Object *child_object : children_objects) {
- const int handle = instances.add_reference(*child_object);
+ const int handle = instances->add_reference(*child_object);
float4x4 transform = float4x4::identity();
if (!reset_children) {
if (use_relative_transform) {
- transform = self_object->imat;
+ transform = self_object->world_to_object;
}
else {
sub_v3_v3(transform.values[3], collection->instance_offset);
}
- mul_m4_m4_post(transform.values, child_object->obmat);
+ mul_m4_m4_post(transform.values, child_object->object_to_world);
}
entries.append({handle, &(child_object->id.name[2]), transform});
}
@@ -123,21 +123,21 @@ static void node_geo_exec(GeoNodeExecParams params)
return BLI_strcasecmp_natural(a.name, b.name) < 0;
});
for (const InstanceListEntry &entry : entries) {
- instances.add_instance(entry.handle, entry.transform);
+ instances->add_instance(entry.handle, entry.transform);
}
}
else {
float4x4 transform = float4x4::identity();
if (use_relative_transform) {
copy_v3_v3(transform.values[3], collection->instance_offset);
- mul_m4_m4_pre(transform.values, self_object->imat);
+ mul_m4_m4_pre(transform.values, self_object->world_to_object);
}
- const int handle = instances.add_reference(*collection);
- instances.add_instance(handle, transform);
+ const int handle = instances->add_reference(*collection);
+ instances->add_instance(handle, transform);
}
- params.set_output("Geometry", geometry_set_out);
+ params.set_output("Geometry", GeometrySet::create_with_instances(instances.release()));
}
} // namespace blender::nodes::node_geo_collection_info_cc
@@ -150,7 +150,7 @@ void register_node_type_geo_collection_info()
geo_node_type_base(&ntype, GEO_NODE_COLLECTION_INFO, "Collection Info", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
- node_type_init(&ntype, file_ns::node_node_init);
+ ntype.initfunc = file_ns::node_node_init;
node_type_storage(&ntype,
"NodeGeometryCollectionInfo",
node_free_standard_storage,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_common.cc b/source/blender/nodes/geometry/nodes/node_geo_common.cc
index 531d37c3a89..90fb7e10570 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_common.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_common.cc
@@ -23,7 +23,7 @@ void register_node_type_geo_group()
node_type_size(&ntype, 140, 60, 400);
ntype.labelfunc = node_group_label;
- node_type_group_update(&ntype, node_group_update);
+ ntype.group_update_func = node_group_update;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
index c8b692651e9..278d7c4bd24 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
@@ -56,7 +56,7 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords)
# if 0 /* Disabled because it only works for meshes, not predictable enough. */
/* Copy custom data on vertices, like vertex groups etc. */
if (mesh && original_index < mesh->totvert) {
- CustomData_copy_data(&mesh->vdata, &result->vdata, (int)original_index, (int)i, 1);
+ CustomData_copy_data(&mesh->vdata, &result->vdata, int(original_index), int(i), 1);
}
# endif
/* Copy the position of the original point. */
@@ -81,13 +81,13 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords)
int v_to;
plConvexHullGetLoop(hull, i, &v_from, &v_to);
- mloop_src[i].v = (uint)v_from;
+ mloop_src[i].v = uint(v_from);
/* Add edges for ascending order loops only. */
if (v_from < v_to) {
MEdge &edge = edges[edge_index];
edge.v1 = v_from;
edge.v2 = v_to;
- edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
+ edge.flag = ME_EDGEDRAW;
/* Write edge index into both loops that have it. */
int reverse_index = plConvexHullGetReversedLoopIndex(hull, i);
@@ -101,7 +101,7 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords)
MEdge &edge = edges[0];
edge.v1 = 0;
edge.v2 = 1;
- edge.flag |= ME_EDGEDRAW | ME_EDGERENDER | ME_LOOSEEDGE;
+ edge.flag |= ME_EDGEDRAW | ME_LOOSEEDGE;
edge_index++;
}
BLI_assert(edge_index == edges_num);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc
index 28d979facac..4161ec7e7ad 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc
@@ -42,7 +42,7 @@ class EndpointFieldInput final : public bke::CurvesFieldInput {
GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const final
+ const IndexMask /*mask*/) const final
{
if (domain != ATTR_DOMAIN_POINT) {
return {};
@@ -90,6 +90,11 @@ class EndpointFieldInput final : public bke::CurvesFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const CurvesGeometry & /*curves*/) const
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc
index c675ee472cd..a14661b4a50 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc
@@ -27,12 +27,12 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Mesh"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryCurveFill *data = MEM_cnew<NodeGeometryCurveFill>(__func__);
@@ -85,12 +85,12 @@ static Mesh *cdt_to_mesh(const meshintersect::CDT_result<double> &result)
MutableSpan<MLoop> loops = mesh->loops_for_write();
for (const int i : IndexRange(result.vert.size())) {
- copy_v3_v3(verts[i].co, float3((float)result.vert[i].x, (float)result.vert[i].y, 0.0f));
+ copy_v3_v3(verts[i].co, float3(float(result.vert[i].x), float(result.vert[i].y), 0.0f));
}
for (const int i : IndexRange(result.edge.size())) {
edges[i].v1 = result.edge[i].first;
edges[i].v2 = result.edge[i].second;
- edges[i].flag = ME_EDGEDRAW | ME_EDGERENDER;
+ edges[i].flag = ME_EDGEDRAW;
}
int i_loop = 0;
for (const int i : IndexRange(result.face.size())) {
@@ -155,7 +155,7 @@ void register_node_type_geo_curve_fill()
geo_node_type_base(&ntype, GEO_NODE_FILL_CURVE, "Fill Curve", NODE_CLASS_GEOMETRY);
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
node_type_storage(
&ntype, "NodeGeometryCurveFill", node_free_standard_storage, node_copy_standard_storage);
ntype.declare = file_ns::node_declare;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
index 4586bb24464..7a6fa799013 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
@@ -32,12 +32,12 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryCurveFillet *data = MEM_cnew<NodeGeometryCurveFillet>(__func__);
data->mode = GEO_NODE_CURVE_FILLET_BEZIER;
@@ -48,7 +48,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryCurveFillet &storage = node_storage(*node);
const GeometryNodeCurveFilletMode mode = (GeometryNodeCurveFilletMode)storage.mode;
- bNodeSocket *poly_socket = ((bNodeSocket *)node->inputs.first)->next;
+ bNodeSocket *poly_socket = static_cast<bNodeSocket *>(node->inputs.first)->next;
nodeSetSocketAvailability(ntree, poly_socket, mode == GEO_NODE_CURVE_FILLET_POLY);
}
@@ -121,8 +121,8 @@ void register_node_type_geo_curve_fillet()
node_type_storage(
&ntype, "NodeGeometryCurveFillet", node_free_standard_storage, node_copy_standard_storage);
ntype.declare = file_ns::node_declare;
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
ntype.geometry_node_execute = file_ns::node_geo_exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc
index b34b22e995d..9f0d40bb0d7 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc
@@ -16,13 +16,13 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Bool>(N_("Selection")).field_source();
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
uiItemR(layout, ptr, "handle_type", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryCurveSelectHandles *data = MEM_cnew<NodeGeometryCurveSelectHandles>(__func__);
@@ -97,7 +97,7 @@ class HandleTypeFieldInput final : public bke::CurvesFieldInput {
uint64_t hash() const override
{
- return get_default_hash_2((int)mode_, (int)type_);
+ return get_default_hash_2(int(mode_), int(type_));
}
bool is_equal_to(const fn::FieldNode &other) const override
@@ -108,6 +108,11 @@ class HandleTypeFieldInput final : public bke::CurvesFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const CurvesGeometry & /*curves*/) const
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
@@ -133,7 +138,7 @@ void register_node_type_geo_curve_handle_type_selection()
&ntype, GEO_NODE_CURVE_HANDLE_TYPE_SELECTION, "Handle Type Selection", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
ntype.geometry_node_execute = file_ns::node_geo_exec;
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
node_type_storage(&ntype,
"NodeGeometryCurveSelectHandles",
node_free_standard_storage,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_arc.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_arc.cc
index ba8c9a893c2..e0148730710 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_arc.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_arc.cc
@@ -88,12 +88,12 @@ static void node_declare(NodeDeclarationBuilder &b)
.make_available(enable_points);
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryCurvePrimitiveArc *data = MEM_cnew<NodeGeometryCurvePrimitiveArc>(__func__);
@@ -106,7 +106,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
const NodeGeometryCurvePrimitiveArc &storage = node_storage(*node);
const GeometryNodeCurvePrimitiveArcMode mode = (GeometryNodeCurvePrimitiveArcMode)storage.mode;
- bNodeSocket *start_socket = ((bNodeSocket *)node->inputs.first)->next;
+ bNodeSocket *start_socket = static_cast<bNodeSocket *>(node->inputs.first)->next;
bNodeSocket *middle_socket = start_socket->next;
bNodeSocket *end_socket = middle_socket->next;
@@ -116,7 +116,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
bNodeSocket *offset_angle_socket = sweep_angle_socket->next;
- bNodeSocket *center_out_socket = ((bNodeSocket *)node->outputs.first)->next;
+ bNodeSocket *center_out_socket = static_cast<bNodeSocket *>(node->outputs.first)->next;
bNodeSocket *normal_out_socket = center_out_socket->next;
bNodeSocket *radius_out_socket = normal_out_socket->next;
@@ -151,7 +151,7 @@ static bool colinear_f3_f3_f3(const float3 p1, const float3 p2, const float3 p3)
{
const float3 a = math::normalize(p2 - p1);
const float3 b = math::normalize(p3 - p1);
- return (ELEM(a, b, b * -1.0f));
+ return ELEM(a, b, b * -1.0f);
}
static Curves *create_arc_curve_from_points(const int resolution,
@@ -359,8 +359,8 @@ void register_node_type_geo_curve_primitive_arc()
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_CURVE_PRIMITIVE_ARC, "Arc", NODE_CLASS_GEOMETRY);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
node_type_storage(&ntype,
"NodeGeometryCurvePrimitiveArc",
node_free_standard_storage,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_bezier_segment.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_bezier_segment.cc
index 875664c41fa..59c17365261 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_bezier_segment.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_bezier_segment.cc
@@ -41,12 +41,12 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryCurvePrimitiveBezierSegment *data =
MEM_cnew<NodeGeometryCurvePrimitiveBezierSegment>(__func__);
@@ -119,7 +119,7 @@ void register_node_type_geo_curve_primitive_bezier_segment()
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_CURVE_PRIMITIVE_BEZIER_SEGMENT, "Bezier Segment", NODE_CLASS_GEOMETRY);
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
node_type_storage(&ntype,
"NodeGeometryCurvePrimitiveBezierSegment",
node_free_standard_storage,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_circle.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_circle.cc
index c33ba3e2a4c..75f2116b237 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_circle.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_circle.cc
@@ -56,12 +56,12 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Center")).make_available(endable_points);
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryCurvePrimitiveCircle *data = MEM_cnew<NodeGeometryCurvePrimitiveCircle>(__func__);
@@ -75,12 +75,12 @@ static void node_update(bNodeTree *ntree, bNode *node)
const GeometryNodeCurvePrimitiveCircleMode mode = (GeometryNodeCurvePrimitiveCircleMode)
storage.mode;
- bNodeSocket *start_socket = ((bNodeSocket *)node->inputs.first)->next;
+ bNodeSocket *start_socket = static_cast<bNodeSocket *>(node->inputs.first)->next;
bNodeSocket *middle_socket = start_socket->next;
bNodeSocket *end_socket = middle_socket->next;
bNodeSocket *radius_socket = end_socket->next;
- bNodeSocket *center_socket = ((bNodeSocket *)node->outputs.first)->next;
+ bNodeSocket *center_socket = static_cast<bNodeSocket *>(node->outputs.first)->next;
nodeSetSocketAvailability(
ntree, start_socket, mode == GEO_NODE_CURVE_PRIMITIVE_CIRCLE_TYPE_POINTS);
@@ -98,7 +98,7 @@ static bool colinear_f3_f3_f3(const float3 p1, const float3 p2, const float3 p3)
{
const float3 a = math::normalize(p2 - p1);
const float3 b = math::normalize(p3 - p1);
- return (ELEM(a, b, b * -1.0f));
+ return ELEM(a, b, b * -1.0f);
}
static Curves *create_point_circle_curve(
@@ -144,7 +144,7 @@ static Curves *create_point_circle_curve(
/* Get the radius from the center-point to p1. */
const float r = math::distance(p1, center);
- const float theta_step = ((2 * M_PI) / (float)resolution);
+ const float theta_step = ((2 * M_PI) / float(resolution));
for (const int i : IndexRange(resolution)) {
/* Formula for a circle around a point and 2 unit vectors perpendicular
@@ -217,8 +217,8 @@ void register_node_type_geo_curve_primitive_circle()
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_CURVE_PRIMITIVE_CIRCLE, "Curve Circle", NODE_CLASS_GEOMETRY);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
node_type_storage(&ntype,
"NodeGeometryCurvePrimitiveCircle",
node_free_standard_storage,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_line.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_line.cc
index 4cfa606d8eb..d4ce1923178 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_line.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_line.cc
@@ -39,12 +39,12 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryCurvePrimitiveLine *data = MEM_cnew<NodeGeometryCurvePrimitiveLine>(__func__);
@@ -57,7 +57,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
const NodeGeometryCurvePrimitiveLine &storage = node_storage(*node);
const GeometryNodeCurvePrimitiveLineMode mode = (GeometryNodeCurvePrimitiveLineMode)storage.mode;
- bNodeSocket *p2_socket = ((bNodeSocket *)node->inputs.first)->next;
+ bNodeSocket *p2_socket = static_cast<bNodeSocket *>(node->inputs.first)->next;
bNodeSocket *direction_socket = p2_socket->next;
bNodeSocket *length_socket = direction_socket->next;
@@ -119,8 +119,8 @@ void register_node_type_geo_curve_primitive_line()
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_CURVE_PRIMITIVE_LINE, "Curve Line", NODE_CLASS_GEOMETRY);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
node_type_storage(&ntype,
"NodeGeometryCurvePrimitiveLine",
node_free_standard_storage,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadrilateral.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadrilateral.cc
index fec4e31701f..d4e37a98372 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadrilateral.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadrilateral.cc
@@ -68,12 +68,12 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryCurvePrimitiveQuad *data = MEM_cnew<NodeGeometryCurvePrimitiveQuad>(__func__);
data->mode = GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_RECTANGLE;
@@ -83,10 +83,9 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryCurvePrimitiveQuad &storage = node_storage(*node);
- GeometryNodeCurvePrimitiveQuadMode mode = static_cast<GeometryNodeCurvePrimitiveQuadMode>(
- storage.mode);
+ GeometryNodeCurvePrimitiveQuadMode mode = GeometryNodeCurvePrimitiveQuadMode(storage.mode);
- bNodeSocket *width = ((bNodeSocket *)node->inputs.first);
+ bNodeSocket *width = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *height = width->next;
bNodeSocket *bottom = height->next;
bNodeSocket *top = bottom->next;
@@ -140,7 +139,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
search_link_ops_for_declarations(params, declaration.outputs());
}
else if (params.node_tree().typeinfo->validate_link(
- static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_FLOAT)) {
+ eNodeSocketDatatype(params.other_socket().type), SOCK_FLOAT)) {
params.add_item(IFACE_("Width"),
SocketSearchOp{"Width", GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_RECTANGLE});
params.add_item(IFACE_("Height"),
@@ -275,8 +274,8 @@ void register_node_type_geo_curve_primitive_quadrilateral()
ntype.declare = file_ns::node_declare;
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.draw_buttons = file_ns::node_layout;
- node_type_update(&ntype, file_ns::node_update);
- node_type_init(&ntype, file_ns::node_init);
+ ntype.updatefunc = file_ns::node_update;
+ ntype.initfunc = file_ns::node_init;
node_type_storage(&ntype,
"NodeGeometryCurvePrimitiveQuad",
node_free_standard_storage,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_spiral.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_spiral.cc
index 4aaf57d57cb..66284fe77db 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_spiral.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_spiral.cc
@@ -43,9 +43,9 @@ static Curves *create_spiral_curve(const float rotations,
const bool direction)
{
const int totalpoints = std::max(int(resolution * rotations), 1);
- const float delta_radius = (end_radius - start_radius) / (float)totalpoints;
- const float delta_height = height / (float)totalpoints;
- const float delta_theta = (M_PI * 2 * rotations) / (float)totalpoints *
+ const float delta_radius = (end_radius - start_radius) / float(totalpoints);
+ const float delta_height = height / float(totalpoints);
+ const float delta_theta = (M_PI * 2 * rotations) / float(totalpoints) *
(direction ? 1.0f : -1.0f);
Curves *curves_id = bke::curves_new_nomain_single(totalpoints + 1, CURVE_TYPE_POLY);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
index 41eafe2a741..23a71af448d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
@@ -26,12 +26,12 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryCurveResample *data = MEM_cnew<NodeGeometryCurveResample>(__func__);
@@ -44,7 +44,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
const NodeGeometryCurveResample &storage = node_storage(*node);
const GeometryNodeCurveResampleMode mode = (GeometryNodeCurveResampleMode)storage.mode;
- bNodeSocket *count_socket = ((bNodeSocket *)node->inputs.first)->next->next;
+ bNodeSocket *count_socket = static_cast<bNodeSocket *>(node->inputs.first)->next->next;
bNodeSocket *length_socket = count_socket->next;
nodeSetSocketAvailability(ntree, count_socket, mode == GEO_NODE_CURVE_RESAMPLE_COUNT);
@@ -123,8 +123,8 @@ void register_node_type_geo_curve_resample()
ntype.draw_buttons = file_ns::node_layout;
node_type_storage(
&ntype, "NodeGeometryCurveResample", node_free_standard_storage, node_copy_standard_storage);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
ntype.geometry_node_execute = file_ns::node_geo_exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
index 0169ead5bd2..040ebf55ec5 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
@@ -19,6 +19,8 @@ static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
+ GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set);
+
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
if (!geometry_set.has_curves()) {
return;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
index e80b600a740..c1f631a86fa 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_devirtualize_parameters.hh"
+#include "BLI_generic_array.hh"
#include "BLI_length_parameterize.hh"
#include "BKE_curves.hh"
@@ -8,6 +9,8 @@
#include "UI_interface.h"
#include "UI_resources.h"
+#include "NOD_socket_search_link.hh"
+
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_curve_sample_cc {
@@ -16,9 +19,16 @@ NODE_STORAGE_FUNCS(NodeGeometryCurveSample)
static void node_declare(NodeDeclarationBuilder &b)
{
- b.add_input<decl::Geometry>(N_("Curve"))
+ b.add_input<decl::Geometry>(N_("Curves"))
.only_realized_data()
.supported_type(GEO_COMPONENT_TYPE_CURVE);
+
+ b.add_input<decl::Float>(N_("Value"), "Value_Float").hide_value().supports_field();
+ b.add_input<decl::Int>(N_("Value"), "Value_Int").hide_value().supports_field();
+ b.add_input<decl::Vector>(N_("Value"), "Value_Vector").hide_value().supports_field();
+ b.add_input<decl::Color>(N_("Value"), "Value_Color").hide_value().supports_field();
+ b.add_input<decl::Bool>(N_("Value"), "Value_Bool").hide_value().supports_field();
+
b.add_input<decl::Float>(N_("Factor"))
.min(0.0f)
.max(1.0f)
@@ -30,20 +40,34 @@ static void node_declare(NodeDeclarationBuilder &b)
.subtype(PROP_DISTANCE)
.supports_field()
.make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_SAMPLE_LENGTH; });
+ b.add_input<decl::Int>(N_("Curve Index")).supports_field().make_available([](bNode &node) {
+ node_storage(node).use_all_curves = false;
+ });
+
+ b.add_output<decl::Float>(N_("Value"), "Value_Float").dependent_field();
+ b.add_output<decl::Int>(N_("Value"), "Value_Int").dependent_field();
+ b.add_output<decl::Vector>(N_("Value"), "Value_Vector").dependent_field();
+ b.add_output<decl::Color>(N_("Value"), "Value_Color").dependent_field();
+ b.add_output<decl::Bool>(N_("Value"), "Value_Bool").dependent_field();
+
b.add_output<decl::Vector>(N_("Position")).dependent_field();
b.add_output<decl::Vector>(N_("Tangent")).dependent_field();
b.add_output<decl::Vector>(N_("Normal")).dependent_field();
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
+ uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "use_all_curves", 0, nullptr, ICON_NONE);
}
-static void node_type_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryCurveSample *data = MEM_cnew<NodeGeometryCurveSample>(__func__);
- data->mode = GEO_NODE_CURVE_SAMPLE_LENGTH;
+ data->mode = GEO_NODE_CURVE_SAMPLE_FACTOR;
+ data->use_all_curves = false;
+ data->data_type = CD_PROP_FLOAT;
node->storage = data;
}
@@ -51,16 +75,62 @@ static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryCurveSample &storage = node_storage(*node);
const GeometryNodeCurveSampleMode mode = (GeometryNodeCurveSampleMode)storage.mode;
+ const eCustomDataType data_type = eCustomDataType(storage.data_type);
+
+ bNodeSocket *in_socket_float = static_cast<bNodeSocket *>(node->inputs.first)->next;
+ bNodeSocket *in_socket_int32 = in_socket_float->next;
+ bNodeSocket *in_socket_vector = in_socket_int32->next;
+ bNodeSocket *in_socket_color4f = in_socket_vector->next;
+ bNodeSocket *in_socket_bool = in_socket_color4f->next;
- bNodeSocket *factor = ((bNodeSocket *)node->inputs.first)->next;
+ bNodeSocket *factor = in_socket_bool->next;
bNodeSocket *length = factor->next;
+ bNodeSocket *curve_index = length->next;
nodeSetSocketAvailability(ntree, factor, mode == GEO_NODE_CURVE_SAMPLE_FACTOR);
nodeSetSocketAvailability(ntree, length, mode == GEO_NODE_CURVE_SAMPLE_LENGTH);
+ nodeSetSocketAvailability(ntree, curve_index, !storage.use_all_curves);
+
+ nodeSetSocketAvailability(ntree, in_socket_vector, data_type == CD_PROP_FLOAT3);
+ nodeSetSocketAvailability(ntree, in_socket_float, data_type == CD_PROP_FLOAT);
+ nodeSetSocketAvailability(ntree, in_socket_color4f, data_type == CD_PROP_COLOR);
+ nodeSetSocketAvailability(ntree, in_socket_bool, data_type == CD_PROP_BOOL);
+ nodeSetSocketAvailability(ntree, in_socket_int32, data_type == CD_PROP_INT32);
+
+ bNodeSocket *out_socket_float = static_cast<bNodeSocket *>(node->outputs.first);
+ bNodeSocket *out_socket_int32 = out_socket_float->next;
+ bNodeSocket *out_socket_vector = out_socket_int32->next;
+ bNodeSocket *out_socket_color4f = out_socket_vector->next;
+ bNodeSocket *out_socket_bool = out_socket_color4f->next;
+
+ nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3);
+ nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT);
+ nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR);
+ nodeSetSocketAvailability(ntree, out_socket_bool, data_type == CD_PROP_BOOL);
+ nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32);
+}
+
+static void node_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+ const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
+ search_link_ops_for_declarations(params, declaration.inputs().take_front(4));
+ search_link_ops_for_declarations(params, declaration.outputs().take_front(3));
+
+ const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type(
+ eNodeSocketDatatype(params.other_socket().type));
+ if (type && *type != CD_PROP_STRING) {
+ /* The input and output sockets have the same name. */
+ params.add_item(IFACE_("Value"), [type](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("GeometryNodeSampleCurve");
+ node_storage(node).data_type = *type;
+ params.update_and_connect_available_socket(node, "Value");
+ });
+ }
}
static void sample_indices_and_lengths(const Span<float> accumulated_lengths,
const Span<float> sample_lengths,
+ const GeometryNodeCurveSampleMode length_mode,
const IndexMask mask,
MutableSpan<int> r_segment_indices,
MutableSpan<float> r_length_in_segment)
@@ -70,10 +140,13 @@ static void sample_indices_and_lengths(const Span<float> accumulated_lengths,
mask.to_best_mask_type([&](const auto mask) {
for (const int64_t i : mask) {
+ const float sample_length = length_mode == GEO_NODE_CURVE_SAMPLE_FACTOR ?
+ sample_lengths[i] * total_length :
+ sample_lengths[i];
int segment_i;
float factor_in_segment;
length_parameterize::sample_at_length(accumulated_lengths,
- std::clamp(sample_lengths[i], 0.0f, total_length),
+ std::clamp(sample_length, 0.0f, total_length),
segment_i,
factor_in_segment,
&hint);
@@ -89,6 +162,7 @@ static void sample_indices_and_lengths(const Span<float> accumulated_lengths,
static void sample_indices_and_factors_to_compressed(const Span<float> accumulated_lengths,
const Span<float> sample_lengths,
+ const GeometryNodeCurveSampleMode length_mode,
const IndexMask mask,
MutableSpan<int> r_segment_indices,
MutableSpan<float> r_factor_in_segment)
@@ -96,16 +170,32 @@ static void sample_indices_and_factors_to_compressed(const Span<float> accumulat
const float total_length = accumulated_lengths.last();
length_parameterize::SampleSegmentHint hint;
- mask.to_best_mask_type([&](const auto mask) {
- for (const int64_t i : IndexRange(mask.size())) {
- const float length = sample_lengths[mask[i]];
- length_parameterize::sample_at_length(accumulated_lengths,
- std::clamp(length, 0.0f, total_length),
- r_segment_indices[i],
- r_factor_in_segment[i],
- &hint);
- }
- });
+ switch (length_mode) {
+ case GEO_NODE_CURVE_SAMPLE_FACTOR:
+ mask.to_best_mask_type([&](const auto mask) {
+ for (const int64_t i : IndexRange(mask.size())) {
+ const float length = sample_lengths[mask[i]] * total_length;
+ length_parameterize::sample_at_length(accumulated_lengths,
+ std::clamp(length, 0.0f, total_length),
+ r_segment_indices[i],
+ r_factor_in_segment[i],
+ &hint);
+ }
+ });
+ break;
+ case GEO_NODE_CURVE_SAMPLE_LENGTH:
+ mask.to_best_mask_type([&](const auto mask) {
+ for (const int64_t i : IndexRange(mask.size())) {
+ const float length = sample_lengths[mask[i]];
+ length_parameterize::sample_at_length(accumulated_lengths,
+ std::clamp(length, 0.0f, total_length),
+ r_segment_indices[i],
+ r_factor_in_segment[i],
+ &hint);
+ }
+ });
+ break;
+ }
}
/**
@@ -115,10 +205,12 @@ static void sample_indices_and_factors_to_compressed(const Span<float> accumulat
class SampleFloatSegmentsFunction : public fn::MultiFunction {
private:
Array<float> accumulated_lengths_;
+ GeometryNodeCurveSampleMode length_mode_;
public:
- SampleFloatSegmentsFunction(Array<float> accumulated_lengths)
- : accumulated_lengths_(std::move(accumulated_lengths))
+ SampleFloatSegmentsFunction(Array<float> accumulated_lengths,
+ const GeometryNodeCurveSampleMode length_mode)
+ : accumulated_lengths_(std::move(accumulated_lengths)), length_mode_(length_mode)
{
static fn::MFSignature signature = create_signature();
this->set_signature(&signature);
@@ -134,14 +226,15 @@ class SampleFloatSegmentsFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArraySpan<float> lengths = params.readonly_single_input<float>(0, "Length");
MutableSpan<int> indices = params.uninitialized_single_output<int>(1, "Curve Index");
MutableSpan<float> lengths_in_segments = params.uninitialized_single_output<float>(
2, "Length in Curve");
- sample_indices_and_lengths(accumulated_lengths_, lengths, mask, indices, lengths_in_segments);
+ sample_indices_and_lengths(
+ accumulated_lengths_, lengths, length_mode_, mask, indices, lengths_in_segments);
}
};
@@ -153,15 +246,27 @@ class SampleCurveFunction : public fn::MultiFunction {
* that the curve is not freed before the function can execute.
*/
GeometrySet geometry_set_;
+ GField src_field_;
+ GeometryNodeCurveSampleMode length_mode_;
+
+ fn::MFSignature signature_;
+
+ std::optional<bke::CurvesFieldContext> source_context_;
+ std::unique_ptr<FieldEvaluator> source_evaluator_;
+ const GVArray *source_data_;
public:
- SampleCurveFunction(GeometrySet geometry_set) : geometry_set_(std::move(geometry_set))
+ SampleCurveFunction(GeometrySet geometry_set,
+ const GeometryNodeCurveSampleMode length_mode,
+ const GField &src_field)
+ : geometry_set_(std::move(geometry_set)), src_field_(src_field), length_mode_(length_mode)
{
- static fn::MFSignature signature = create_signature();
- this->set_signature(&signature);
+ signature_ = create_signature();
+ this->set_signature(&signature_);
+ this->evaluate_source();
}
- static fn::MFSignature create_signature()
+ fn::MFSignature create_signature()
{
blender::fn::MFSignatureBuilder signature{"Sample Curve"};
signature.single_input<int>("Curve Index");
@@ -169,10 +274,11 @@ class SampleCurveFunction : public fn::MultiFunction {
signature.single_output<float3>("Position");
signature.single_output<float3>("Tangent");
signature.single_output<float3>("Normal");
+ signature.single_output("Value", src_field_.cpp_type());
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
MutableSpan<float3> sampled_positions = params.uninitialized_single_output_if_required<float3>(
2, "Position");
@@ -180,6 +286,7 @@ class SampleCurveFunction : public fn::MultiFunction {
3, "Tangent");
MutableSpan<float3> sampled_normals = params.uninitialized_single_output_if_required<float3>(
4, "Normal");
+ GMutableSpan sampled_values = params.uninitialized_single_output_if_required(5, "Value");
auto return_default = [&]() {
if (!sampled_positions.is_empty()) {
@@ -202,6 +309,7 @@ class SampleCurveFunction : public fn::MultiFunction {
if (curves.points_num() == 0) {
return return_default();
}
+ curves.ensure_can_interpolate_to_evaluated();
Span<float3> evaluated_positions = curves.evaluated_positions();
Span<float3> evaluated_tangents;
Span<float3> evaluated_normals;
@@ -218,18 +326,40 @@ class SampleCurveFunction : public fn::MultiFunction {
Array<int> indices;
Array<float> factors;
+ GArray<> src_original_values(source_data_->type());
+ GArray<> src_evaluated_values(source_data_->type());
+
+ auto fill_invalid = [&](const IndexMask mask) {
+ if (!sampled_positions.is_empty()) {
+ sampled_positions.fill_indices(mask, float3(0));
+ }
+ if (!sampled_tangents.is_empty()) {
+ sampled_tangents.fill_indices(mask, float3(0));
+ }
+ if (!sampled_normals.is_empty()) {
+ sampled_normals.fill_indices(mask, float3(0));
+ }
+ if (!sampled_values.is_empty()) {
+ attribute_math::convert_to_static_type(source_data_->type(), [&](auto dummy) {
+ using T = decltype(dummy);
+ sampled_values.typed<T>().fill_indices(mask, {});
+ });
+ }
+ };
auto sample_curve = [&](const int curve_i, const IndexMask mask) {
+ const Span<float> accumulated_lengths = curves.evaluated_lengths_for_curve(curve_i,
+ cyclic[curve_i]);
+ if (accumulated_lengths.is_empty()) {
+ fill_invalid(mask);
+ return;
+ }
/* Store the sampled indices and factors in arrays the size of the mask.
* Then, during interpolation, move the results back to the masked indices. */
indices.reinitialize(mask.size());
factors.reinitialize(mask.size());
sample_indices_and_factors_to_compressed(
- curves.evaluated_lengths_for_curve(curve_i, cyclic[curve_i]),
- lengths,
- mask,
- indices,
- factors);
+ accumulated_lengths, lengths, length_mode_, mask, indices, factors);
const IndexRange evaluated_points = curves.evaluated_points_for_curve(curve_i);
if (!sampled_positions.is_empty()) {
@@ -254,54 +384,67 @@ class SampleCurveFunction : public fn::MultiFunction {
sampled_normals[i] = math::normalize(sampled_normals[i]);
}
}
+ if (!sampled_values.is_empty()) {
+ const IndexRange points = curves.points_for_curve(curve_i);
+ src_original_values.reinitialize(points.size());
+ source_data_->materialize_compressed_to_uninitialized(points, src_original_values.data());
+ src_evaluated_values.reinitialize(curves.evaluated_points_for_curve(curve_i).size());
+ curves.interpolate_to_evaluated(curve_i, src_original_values, src_evaluated_values);
+ attribute_math::convert_to_static_type(source_data_->type(), [&](auto dummy) {
+ using T = decltype(dummy);
+ const Span<T> src_evaluated_values_typed = src_evaluated_values.as_span().typed<T>();
+ MutableSpan<T> sampled_values_typed = sampled_values.typed<T>();
+ length_parameterize::interpolate_to_masked<T>(
+ src_evaluated_values_typed, indices, factors, mask, sampled_values_typed);
+ });
+ }
};
- if (curve_indices.is_single()) {
- sample_curve(curve_indices.get_internal_single(), mask);
+ if (const std::optional<int> curve_i = curve_indices.get_if_single()) {
+ if (curves.curves_range().contains(*curve_i)) {
+ sample_curve(*curve_i, mask);
+ }
+ else {
+ fill_invalid(mask);
+ }
}
else {
+ Vector<int64_t> invalid_indices;
MultiValueMap<int, int64_t> indices_per_curve;
devirtualize_varray(curve_indices, [&](const auto curve_indices) {
for (const int64_t i : mask) {
- indices_per_curve.add(curve_indices[i], i);
+ const int curve_i = curve_indices[i];
+ if (curves.curves_range().contains(curve_i)) {
+ indices_per_curve.add(curve_i, i);
+ }
+ else {
+ invalid_indices.append(i);
+ }
}
});
for (const int curve_i : indices_per_curve.keys()) {
sample_curve(curve_i, IndexMask(indices_per_curve.lookup(curve_i)));
}
+ fill_invalid(IndexMask(invalid_indices));
}
}
-};
-/**
- * Pre-process the lengths or factors used for the sampling, turning factors into lengths, and
- * clamping between zero and the total length of the curves. Do this as a separate operation in the
- * field tree to make the sampling simpler, and to let the evaluator optimize better.
- *
- * \todo Use a mutable single input instead when they are supported.
- */
-static Field<float> get_length_input_field(GeoNodeExecParams params,
- const GeometryNodeCurveSampleMode mode,
- const float curves_total_length)
-{
- if (mode == GEO_NODE_CURVE_SAMPLE_LENGTH) {
- return params.extract_input<Field<float>>("Length");
+ private:
+ void evaluate_source()
+ {
+ const Curves &curves_id = *geometry_set_.get_curves_for_read();
+ const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
+ source_context_.emplace(bke::CurvesFieldContext{curves, ATTR_DOMAIN_POINT});
+ source_evaluator_ = std::make_unique<FieldEvaluator>(*source_context_, curves.points_num());
+ source_evaluator_->add(src_field_);
+ source_evaluator_->evaluate();
+ source_data_ = &source_evaluator_->get_evaluated(0);
}
-
- /* Convert the factor to a length. */
- Field<float> factor_field = params.get_input<Field<float>>("Factor");
- auto clamp_fn = std::make_unique<fn::CustomMF_SI_SO<float, float>>(
- __func__,
- [curves_total_length](float factor) { return factor * curves_total_length; },
- fn::CustomMF_presets::AllSpanOrSingle());
-
- return Field<float>(FieldOperation::Create(std::move(clamp_fn), {std::move(factor_field)}), 0);
-}
+};
static Array<float> curve_accumulated_lengths(const bke::CurvesGeometry &curves)
{
- curves.ensure_evaluated_lengths();
Array<float> curve_lengths(curves.curves_num());
const VArray<bool> cyclic = curves.cyclic();
@@ -313,9 +456,56 @@ static Array<float> curve_accumulated_lengths(const bke::CurvesGeometry &curves)
return curve_lengths;
}
+static GField get_input_attribute_field(GeoNodeExecParams &params, const eCustomDataType data_type)
+{
+ switch (data_type) {
+ case CD_PROP_FLOAT:
+ return params.extract_input<Field<float>>("Value_Float");
+ case CD_PROP_FLOAT3:
+ return params.extract_input<Field<float3>>("Value_Vector");
+ case CD_PROP_COLOR:
+ return params.extract_input<Field<ColorGeometry4f>>("Value_Color");
+ case CD_PROP_BOOL:
+ return params.extract_input<Field<bool>>("Value_Bool");
+ case CD_PROP_INT32:
+ return params.extract_input<Field<int>>("Value_Int");
+ default:
+ BLI_assert_unreachable();
+ }
+ return {};
+}
+
+static void output_attribute_field(GeoNodeExecParams &params, GField field)
+{
+ switch (bke::cpp_type_to_custom_data_type(field.cpp_type())) {
+ case CD_PROP_FLOAT: {
+ params.set_output("Value_Float", Field<float>(field));
+ break;
+ }
+ case CD_PROP_FLOAT3: {
+ params.set_output("Value_Vector", Field<float3>(field));
+ break;
+ }
+ case CD_PROP_COLOR: {
+ params.set_output("Value_Color", Field<ColorGeometry4f>(field));
+ break;
+ }
+ case CD_PROP_BOOL: {
+ params.set_output("Value_Bool", Field<bool>(field));
+ break;
+ }
+ case CD_PROP_INT32: {
+ params.set_output("Value_Int", Field<int>(field));
+ break;
+ }
+ default:
+ break;
+ }
+}
+
static void node_geo_exec(GeoNodeExecParams params)
{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Curves");
if (!geometry_set.has_curves()) {
params.set_default_remaining_outputs();
return;
@@ -328,34 +518,49 @@ static void node_geo_exec(GeoNodeExecParams params)
return;
}
- Array<float> curve_lengths = curve_accumulated_lengths(curves);
- const float total_length = curve_lengths.last();
- if (total_length == 0.0f) {
- params.set_default_remaining_outputs();
- return;
- }
+ curves.ensure_evaluated_lengths();
const NodeGeometryCurveSample &storage = node_storage(params.node());
const GeometryNodeCurveSampleMode mode = (GeometryNodeCurveSampleMode)storage.mode;
- Field<float> length_field = get_length_input_field(params, mode, total_length);
+ const eCustomDataType data_type = eCustomDataType(storage.data_type);
- auto sample_fn = std::make_unique<SampleCurveFunction>(std::move(geometry_set));
+ Field<float> length_field = params.extract_input<Field<float>>(
+ mode == GEO_NODE_CURVE_SAMPLE_FACTOR ? "Factor" : "Length");
+ GField src_values_field = get_input_attribute_field(params, data_type);
std::shared_ptr<FieldOperation> sample_op;
if (curves.curves_num() == 1) {
- sample_op = FieldOperation::Create(std::move(sample_fn),
- {fn::make_constant_field<int>(0), std::move(length_field)});
+ sample_op = FieldOperation::Create(
+ std::make_unique<SampleCurveFunction>(
+ std::move(geometry_set), mode, std::move(src_values_field)),
+ {fn::make_constant_field<int>(0), std::move(length_field)});
}
else {
- auto index_fn = std::make_unique<SampleFloatSegmentsFunction>(std::move(curve_lengths));
- auto index_op = FieldOperation::Create(std::move(index_fn), {std::move(length_field)});
- sample_op = FieldOperation::Create(std::move(sample_fn),
- {Field<int>(index_op, 0), Field<float>(index_op, 1)});
+ if (storage.use_all_curves) {
+ auto index_fn = std::make_unique<SampleFloatSegmentsFunction>(
+ curve_accumulated_lengths(curves), mode);
+ auto index_op = FieldOperation::Create(std::move(index_fn), {std::move(length_field)});
+ Field<int> curve_index = Field<int>(index_op, 0);
+ Field<float> length_in_curve = Field<float>(index_op, 1);
+ sample_op = FieldOperation::Create(
+ std::make_unique<SampleCurveFunction>(
+ std::move(geometry_set), GEO_NODE_CURVE_SAMPLE_LENGTH, std::move(src_values_field)),
+ {std::move(curve_index), std::move(length_in_curve)});
+ }
+ else {
+ Field<int> curve_index = params.extract_input<Field<int>>("Curve Index");
+ Field<float> length_in_curve = std::move(length_field);
+ sample_op = FieldOperation::Create(
+ std::make_unique<SampleCurveFunction>(
+ std::move(geometry_set), mode, std::move(src_values_field)),
+ {std::move(curve_index), std::move(length_in_curve)});
+ }
}
params.set_output("Position", Field<float3>(sample_op, 0));
params.set_output("Tangent", Field<float3>(sample_op, 1));
params.set_output("Normal", Field<float3>(sample_op, 2));
+ output_attribute_field(params, GField(sample_op, 3));
}
} // namespace blender::nodes::node_geo_curve_sample_cc
@@ -369,11 +574,11 @@ void register_node_type_geo_curve_sample()
geo_node_type_base(&ntype, GEO_NODE_SAMPLE_CURVE, "Sample Curve", NODE_CLASS_GEOMETRY);
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.declare = file_ns::node_declare;
- node_type_init(&ntype, file_ns::node_type_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
node_type_storage(
&ntype, "NodeGeometryCurveSample", node_free_standard_storage, node_copy_standard_storage);
ntype.draw_buttons = file_ns::node_layout;
-
+ ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc
index 8bb24821064..46377329fb4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc
@@ -20,13 +20,13 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
uiItemR(layout, ptr, "handle_type", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryCurveSetHandles *data = MEM_cnew<NodeGeometryCurveSetHandles>(__func__);
@@ -120,7 +120,7 @@ void register_node_type_geo_curve_set_handle_type()
&ntype, GEO_NODE_CURVE_SET_HANDLE_TYPE, "Set Handle Type", NODE_CLASS_GEOMETRY);
ntype.declare = file_ns::node_declare;
ntype.geometry_node_execute = file_ns::node_geo_exec;
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
node_type_storage(&ntype,
"NodeGeometryCurveSetHandles",
node_free_standard_storage,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc
index b5d8d1f020a..159a4661df0 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc
@@ -106,7 +106,7 @@ static Array<float> curve_length_point_domain(const bke::CurvesGeometry &curves)
}
static VArray<float> construct_curve_parameter_varray(const bke::CurvesGeometry &curves,
- const IndexMask UNUSED(mask),
+ const IndexMask /*mask*/,
const eAttrDomain domain)
{
VArray<bool> cyclic = curves.cyclic();
@@ -117,15 +117,18 @@ static VArray<float> construct_curve_parameter_varray(const bke::CurvesGeometry
threading::parallel_for(curves.curves_range(), 1024, [&](IndexRange range) {
for (const int i_curve : range) {
- const float total_length = curves.evaluated_length_total_for_curve(i_curve,
- cyclic[i_curve]);
MutableSpan<float> curve_lengths = lengths.slice(curves.points_for_curve(i_curve));
+ const float total_length = curve_lengths.last();
if (total_length > 0.0f) {
const float factor = 1.0f / total_length;
for (float &value : curve_lengths) {
value *= factor;
}
}
+ else if (curve_lengths.size() == 1) {
+ /* The curve is a single point. */
+ curve_lengths[0] = 0.0f;
+ }
else {
/* It is arbitrary what to do in those rare cases when all the points are
* in the same position. In this case we are just arbitrarily giving a valid
@@ -165,7 +168,7 @@ static VArray<float> construct_curve_parameter_varray(const bke::CurvesGeometry
}
static VArray<float> construct_curve_length_parameter_varray(const bke::CurvesGeometry &curves,
- const IndexMask UNUSED(mask),
+ const IndexMask /*mask*/,
const eAttrDomain domain)
{
curves.ensure_evaluated_lengths();
@@ -184,7 +187,7 @@ static VArray<float> construct_curve_length_parameter_varray(const bke::CurvesGe
}
static VArray<int> construct_index_on_spline_varray(const bke::CurvesGeometry &curves,
- const IndexMask UNUSED(mask),
+ const IndexMask /*mask*/,
const eAttrDomain domain)
{
if (domain == ATTR_DOMAIN_POINT) {
@@ -280,6 +283,11 @@ class IndexOnSplineFieldInput final : public bke::CurvesFieldInput {
{
return dynamic_cast<const IndexOnSplineFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const CurvesGeometry & /*curves*/) const
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc
index 4d7e5f13969..4b8251aadd3 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc
@@ -20,12 +20,12 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "spline_type", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryCurveSplineType *data = MEM_cnew<NodeGeometryCurveSplineType>(__func__);
@@ -87,7 +87,7 @@ void register_node_type_geo_curve_spline_type()
geo_node_type_base(&ntype, GEO_NODE_CURVE_SPLINE_TYPE, "Set Spline Type", NODE_CLASS_GEOMETRY);
ntype.declare = file_ns::node_declare;
ntype.geometry_node_execute = file_ns::node_geo_exec;
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
node_type_storage(&ntype,
"NodeGeometryCurveSplineType",
node_free_standard_storage,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
index 919d0056bca..5a1d2461c72 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
@@ -29,6 +29,8 @@ static void node_geo_exec(GeoNodeExecParams params)
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
Field<int> cuts_field = params.extract_input<Field<int>>("Cuts");
+ GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set);
+
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
if (!geometry_set.has_curves()) {
return;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
index 0ddf06dc8c7..268c927f782 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
@@ -4,8 +4,11 @@
#include "BLI_task.hh"
#include "BLI_timeit.hh"
+#include "DNA_pointcloud_types.h"
+
#include "BKE_pointcloud.h"
-#include "BKE_spline.hh"
+
+#include "GEO_resample_curves.hh"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -37,12 +40,12 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Rotation")).field_source();
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryCurveToPoints *data = MEM_cnew<NodeGeometryCurveToPoints>(__func__);
@@ -55,16 +58,16 @@ static void node_update(bNodeTree *ntree, bNode *node)
const NodeGeometryCurveToPoints &storage = node_storage(*node);
const GeometryNodeCurveResampleMode mode = (GeometryNodeCurveResampleMode)storage.mode;
- bNodeSocket *count_socket = ((bNodeSocket *)node->inputs.first)->next;
+ bNodeSocket *count_socket = static_cast<bNodeSocket *>(node->inputs.first)->next;
bNodeSocket *length_socket = count_socket->next;
nodeSetSocketAvailability(ntree, count_socket, mode == GEO_NODE_CURVE_RESAMPLE_COUNT);
nodeSetSocketAvailability(ntree, length_socket, mode == GEO_NODE_CURVE_RESAMPLE_LENGTH);
}
-static void curve_create_default_rotation_attribute(Span<float3> tangents,
- Span<float3> normals,
- MutableSpan<float3> rotations)
+static void fill_rotation_attribute(const Span<float3> tangents,
+ const Span<float3> normals,
+ MutableSpan<float3> rotations)
{
threading::parallel_for(IndexRange(rotations.size()), 512, [&](IndexRange range) {
for (const int i : range) {
@@ -74,239 +77,30 @@ static void curve_create_default_rotation_attribute(Span<float3> tangents,
});
}
-static Array<int> calculate_spline_point_offsets(GeoNodeExecParams &params,
- const GeometryNodeCurveResampleMode mode,
- const CurveEval &curve,
- const Span<SplinePtr> splines)
-{
- const int size = curve.splines().size();
- switch (mode) {
- case GEO_NODE_CURVE_RESAMPLE_COUNT: {
- const int count = params.get_input<int>("Count");
- if (count < 1) {
- return {0};
- }
- Array<int> offsets(size + 1);
- int offset = 0;
- for (const int i : IndexRange(size)) {
- offsets[i] = offset;
- if (splines[i]->evaluated_points_num() > 0) {
- offset += count;
- }
- }
- offsets.last() = offset;
- return offsets;
- }
- case GEO_NODE_CURVE_RESAMPLE_LENGTH: {
- /* Don't allow asymptotic count increase for low resolution values. */
- const float resolution = std::max(params.get_input<float>("Length"), 0.0001f);
- Array<int> offsets(size + 1);
- int offset = 0;
- for (const int i : IndexRange(size)) {
- offsets[i] = offset;
- if (splines[i]->evaluated_points_num() > 0) {
- offset += splines[i]->length() / resolution + 1;
- }
- }
- offsets.last() = offset;
- return offsets;
- }
- case GEO_NODE_CURVE_RESAMPLE_EVALUATED: {
- return curve.evaluated_point_offsets();
- }
- }
- BLI_assert_unreachable();
- return {0};
-}
-
-/**
- * \note Relies on the fact that all attributes on point clouds are stored contiguously.
- */
-static GMutableSpan ensure_point_attribute(PointCloudComponent &points,
- const AttributeIDRef &attribute_id,
- const eCustomDataType data_type)
-{
- GAttributeWriter attribute = points.attributes_for_write()->lookup_or_add_for_write(
- attribute_id, ATTR_DOMAIN_POINT, data_type);
- GMutableSpan span = attribute.varray.get_internal_span();
- attribute.finish();
- return span;
-}
-
-template<typename T>
-static MutableSpan<T> ensure_point_attribute(PointCloudComponent &points,
- const AttributeIDRef &attribute_id)
-{
- AttributeWriter<T> attribute = points.attributes_for_write()->lookup_or_add_for_write<T>(
- attribute_id, ATTR_DOMAIN_POINT);
- MutableSpan<T> span = attribute.varray.get_internal_span();
- attribute.finish();
- return span;
-}
-
-namespace {
-struct AnonymousAttributeIDs {
- StrongAnonymousAttributeID tangent_id;
- StrongAnonymousAttributeID normal_id;
- StrongAnonymousAttributeID rotation_id;
-};
-
-struct ResultAttributes {
- MutableSpan<float3> positions;
- MutableSpan<float> radii;
-
- Map<AttributeIDRef, GMutableSpan> point_attributes;
-
- MutableSpan<float3> tangents;
- MutableSpan<float3> normals;
- MutableSpan<float3> rotations;
-};
-} // namespace
-
-static ResultAttributes create_attributes_for_transfer(PointCloudComponent &points,
- const CurveEval &curve,
- const AnonymousAttributeIDs &attributes)
+static PointCloud *pointcloud_from_curves(bke::CurvesGeometry curves,
+ const AttributeIDRef &tangent_id,
+ const AttributeIDRef &normal_id,
+ const AttributeIDRef &rotation_id)
{
- ResultAttributes outputs;
-
- outputs.positions = ensure_point_attribute<float3>(points, "position");
- outputs.radii = ensure_point_attribute<float>(points, "radius");
-
- if (attributes.tangent_id) {
- outputs.tangents = ensure_point_attribute<float3>(points, attributes.tangent_id.get());
- }
- if (attributes.normal_id) {
- outputs.normals = ensure_point_attribute<float3>(points, attributes.normal_id.get());
- }
- if (attributes.rotation_id) {
- outputs.rotations = ensure_point_attribute<float3>(points, attributes.rotation_id.get());
+ PointCloud *pointcloud = BKE_pointcloud_new_nomain(0);
+ pointcloud->totpoint = curves.points_num();
+
+ if (rotation_id) {
+ MutableAttributeAccessor attributes = curves.attributes_for_write();
+ const VArraySpan<float3> tangents = attributes.lookup<float3>(tangent_id, ATTR_DOMAIN_POINT);
+ const VArraySpan<float3> normals = attributes.lookup<float3>(normal_id, ATTR_DOMAIN_POINT);
+ SpanAttributeWriter<float3> rotations = attributes.lookup_or_add_for_write_only_span<float3>(
+ rotation_id, ATTR_DOMAIN_POINT);
+ fill_rotation_attribute(tangents, normals, rotations.span);
+ rotations.finish();
}
- /* Because of the invariants of the curve component, we use the attributes of the first spline
- * as a representative for the attribute meta data all splines. Attributes from the spline domain
- * are handled separately. */
- curve.splines().first()->attributes.foreach_attribute(
- [&](const AttributeIDRef &id, const AttributeMetaData &meta_data) {
- if (id.should_be_kept()) {
- outputs.point_attributes.add_new(
- id, ensure_point_attribute(points, id, meta_data.data_type));
- }
- return true;
- },
- ATTR_DOMAIN_POINT);
-
- return outputs;
-}
-
-/**
- * TODO: For non-poly splines, this has double copies that could be avoided as part
- * of a general look at optimizing uses of #Spline::interpolate_to_evaluated.
- */
-static void copy_evaluated_point_attributes(const Span<SplinePtr> splines,
- const Span<int> offsets,
- ResultAttributes &data)
-{
- threading::parallel_for(splines.index_range(), 64, [&](IndexRange range) {
- for (const int i : range) {
- const Spline &spline = *splines[i];
- const int offset = offsets[i];
- const int size = offsets[i + 1] - offsets[i];
-
- data.positions.slice(offset, size).copy_from(spline.evaluated_positions());
- spline.interpolate_to_evaluated(spline.radii()).materialize(data.radii.slice(offset, size));
+ /* Move the curve point custom data to the pointcloud, to avoid any copying. */
+ CustomData_free(&pointcloud->pdata, pointcloud->totpoint);
+ pointcloud->pdata = curves.point_data;
+ CustomData_reset(&curves.point_data);
- for (const Map<AttributeIDRef, GMutableSpan>::Item item : data.point_attributes.items()) {
- const AttributeIDRef attribute_id = item.key;
- const GMutableSpan dst = item.value;
-
- BLI_assert(spline.attributes.get_for_read(attribute_id));
- GSpan spline_span = *spline.attributes.get_for_read(attribute_id);
-
- spline.interpolate_to_evaluated(spline_span).materialize(dst.slice(offset, size).data());
- }
-
- if (!data.tangents.is_empty()) {
- data.tangents.slice(offset, size).copy_from(spline.evaluated_tangents());
- }
- if (!data.normals.is_empty()) {
- data.normals.slice(offset, size).copy_from(spline.evaluated_normals());
- }
- }
- });
-}
-
-static void copy_uniform_sample_point_attributes(const Span<SplinePtr> splines,
- const Span<int> offsets,
- ResultAttributes &data)
-{
- threading::parallel_for(splines.index_range(), 64, [&](IndexRange range) {
- for (const int i : range) {
- const Spline &spline = *splines[i];
- const int offset = offsets[i];
- const int num = offsets[i + 1] - offsets[i];
- if (num == 0) {
- continue;
- }
-
- const Array<float> uniform_samples = spline.sample_uniform_index_factors(num);
-
- spline.sample_with_index_factors<float3>(
- spline.evaluated_positions(), uniform_samples, data.positions.slice(offset, num));
- spline.sample_with_index_factors<float>(spline.interpolate_to_evaluated(spline.radii()),
- uniform_samples,
- data.radii.slice(offset, num));
-
- for (const Map<AttributeIDRef, GMutableSpan>::Item item : data.point_attributes.items()) {
- const AttributeIDRef attribute_id = item.key;
- const GMutableSpan dst = item.value;
-
- BLI_assert(spline.attributes.get_for_read(attribute_id));
- GSpan spline_span = *spline.attributes.get_for_read(attribute_id);
-
- spline.sample_with_index_factors(
- spline.interpolate_to_evaluated(spline_span), uniform_samples, dst.slice(offset, num));
- }
-
- if (!data.tangents.is_empty()) {
- Span<float3> src_tangents = spline.evaluated_tangents();
- MutableSpan<float3> sampled_tangents = data.tangents.slice(offset, num);
- spline.sample_with_index_factors<float3>(src_tangents, uniform_samples, sampled_tangents);
- for (float3 &vector : sampled_tangents) {
- vector = math::normalize(vector);
- }
- }
-
- if (!data.normals.is_empty()) {
- Span<float3> src_normals = spline.evaluated_normals();
- MutableSpan<float3> sampled_normals = data.normals.slice(offset, num);
- spline.sample_with_index_factors<float3>(src_normals, uniform_samples, sampled_normals);
- for (float3 &vector : sampled_normals) {
- vector = math::normalize(vector);
- }
- }
- }
- });
-}
-
-static void copy_spline_domain_attributes(const CurveEval &curve,
- const Span<int> offsets,
- PointCloudComponent &points)
-{
- curve.attributes.foreach_attribute(
- [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
- const GSpan curve_attribute = *curve.attributes.get_for_read(attribute_id);
- const CPPType &type = curve_attribute.type();
- const GMutableSpan dst = ensure_point_attribute(points, attribute_id, meta_data.data_type);
-
- for (const int i : curve.splines().index_range()) {
- const int offset = offsets[i];
- const int num = offsets[i + 1] - offsets[i];
- type.fill_assign_n(curve_attribute[i], dst[offset], num);
- }
-
- return true;
- },
- ATTR_DOMAIN_CURVE);
+ return pointcloud;
}
static void node_geo_exec(GeoNodeExecParams params)
@@ -315,73 +109,96 @@ static void node_geo_exec(GeoNodeExecParams params)
const GeometryNodeCurveResampleMode mode = (GeometryNodeCurveResampleMode)storage.mode;
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
- AnonymousAttributeIDs attribute_outputs;
- attribute_outputs.tangent_id = StrongAnonymousAttributeID("Tangent");
- attribute_outputs.normal_id = StrongAnonymousAttributeID("Normal");
- attribute_outputs.rotation_id = StrongAnonymousAttributeID("Rotation");
-
GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set);
- geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
- if (!geometry_set.has_curves()) {
- geometry_set.remove_geometry_during_modify();
- return;
- }
- const std::unique_ptr<CurveEval> curve = curves_to_curve_eval(
- *geometry_set.get_curves_for_read());
- const Span<SplinePtr> splines = curve->splines();
- curve->assert_valid_point_attributes();
-
- const Array<int> offsets = calculate_spline_point_offsets(params, mode, *curve, splines);
- const int total_num = offsets.last();
- if (total_num == 0) {
- geometry_set.remove_geometry_during_modify();
- return;
- }
+ StrongAnonymousAttributeID tangent_anonymous_id;
+ StrongAnonymousAttributeID normal_anonymous_id;
+ StrongAnonymousAttributeID rotation_anonymous_id;
+ const bool rotation_required = params.output_is_required("Rotation");
+ if (params.output_is_required("Tangent") || rotation_required) {
+ tangent_anonymous_id = StrongAnonymousAttributeID("Tangent");
+ }
+ if (params.output_is_required("Normal") || rotation_required) {
+ normal_anonymous_id = StrongAnonymousAttributeID("Normal");
+ }
+ if (rotation_required) {
+ rotation_anonymous_id = StrongAnonymousAttributeID("Rotation");
+ }
- geometry_set.replace_pointcloud(BKE_pointcloud_new_nomain(total_num));
- PointCloudComponent &points = geometry_set.get_component_for_write<PointCloudComponent>();
- ResultAttributes point_attributes = create_attributes_for_transfer(
- points, *curve, attribute_outputs);
+ geometry::ResampleCurvesOutputAttributeIDs resample_attributes;
+ resample_attributes.tangent_id = tangent_anonymous_id.get();
+ resample_attributes.normal_id = normal_anonymous_id.get();
- switch (mode) {
- case GEO_NODE_CURVE_RESAMPLE_COUNT:
- case GEO_NODE_CURVE_RESAMPLE_LENGTH:
- copy_uniform_sample_point_attributes(splines, offsets, point_attributes);
- break;
- case GEO_NODE_CURVE_RESAMPLE_EVALUATED:
- copy_evaluated_point_attributes(splines, offsets, point_attributes);
- break;
+ switch (mode) {
+ case GEO_NODE_CURVE_RESAMPLE_COUNT: {
+ Field<int> count = params.extract_input<Field<int>>("Count");
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry) {
+ if (const Curves *src_curves_id = geometry.get_curves_for_read()) {
+ const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap(
+ src_curves_id->geometry);
+ bke::CurvesGeometry dst_curves = geometry::resample_to_count(
+ src_curves, fn::make_constant_field<bool>(true), count, resample_attributes);
+ PointCloud *pointcloud = pointcloud_from_curves(std::move(dst_curves),
+ resample_attributes.tangent_id,
+ resample_attributes.normal_id,
+ rotation_anonymous_id.get());
+ geometry.remove_geometry_during_modify();
+ geometry.replace_pointcloud(pointcloud);
+ }
+ });
+ break;
}
-
- copy_spline_domain_attributes(*curve, offsets, points);
-
- if (!point_attributes.rotations.is_empty()) {
- curve_create_default_rotation_attribute(
- point_attributes.tangents, point_attributes.normals, point_attributes.rotations);
+ case GEO_NODE_CURVE_RESAMPLE_LENGTH: {
+ Field<float> length = params.extract_input<Field<float>>("Length");
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry) {
+ if (const Curves *src_curves_id = geometry.get_curves_for_read()) {
+ const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap(
+ src_curves_id->geometry);
+ bke::CurvesGeometry dst_curves = geometry::resample_to_length(
+ src_curves, fn::make_constant_field<bool>(true), length, resample_attributes);
+ PointCloud *pointcloud = pointcloud_from_curves(std::move(dst_curves),
+ resample_attributes.tangent_id,
+ resample_attributes.normal_id,
+ rotation_anonymous_id.get());
+ geometry.remove_geometry_during_modify();
+ geometry.replace_pointcloud(pointcloud);
+ }
+ });
+ break;
}
-
- geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_POINT_CLOUD});
- });
+ case GEO_NODE_CURVE_RESAMPLE_EVALUATED:
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry) {
+ if (const Curves *src_curves_id = geometry.get_curves_for_read()) {
+ const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap(
+ src_curves_id->geometry);
+ bke::CurvesGeometry dst_curves = geometry::resample_to_evaluated(
+ src_curves, fn::make_constant_field<bool>(true), resample_attributes);
+ PointCloud *pointcloud = pointcloud_from_curves(std::move(dst_curves),
+ resample_attributes.tangent_id,
+ resample_attributes.normal_id,
+ rotation_anonymous_id.get());
+ geometry.remove_geometry_during_modify();
+ geometry.replace_pointcloud(pointcloud);
+ }
+ });
+ break;
+ }
params.set_output("Points", std::move(geometry_set));
- if (attribute_outputs.tangent_id) {
- params.set_output(
- "Tangent",
- AnonymousAttributeFieldInput::Create<float3>(std::move(attribute_outputs.tangent_id),
- params.attribute_producer_name()));
+ if (tangent_anonymous_id) {
+ params.set_output("Tangent",
+ AnonymousAttributeFieldInput::Create<float3>(
+ std::move(tangent_anonymous_id), params.attribute_producer_name()));
}
- if (attribute_outputs.normal_id) {
- params.set_output(
- "Normal",
- AnonymousAttributeFieldInput::Create<float3>(std::move(attribute_outputs.normal_id),
- params.attribute_producer_name()));
+ if (normal_anonymous_id) {
+ params.set_output("Normal",
+ AnonymousAttributeFieldInput::Create<float3>(
+ std::move(normal_anonymous_id), params.attribute_producer_name()));
}
- if (attribute_outputs.rotation_id) {
- params.set_output(
- "Rotation",
- AnonymousAttributeFieldInput::Create<float3>(std::move(attribute_outputs.rotation_id),
- params.attribute_producer_name()));
+ if (rotation_anonymous_id) {
+ params.set_output("Rotation",
+ AnonymousAttributeFieldInput::Create<float3>(
+ std::move(rotation_anonymous_id), params.attribute_producer_name()));
}
}
@@ -399,7 +216,7 @@ void register_node_type_geo_curve_to_points()
ntype.draw_buttons = file_ns::node_layout;
node_type_storage(
&ntype, "NodeGeometryCurveToPoints", node_free_standard_storage, node_copy_standard_storage);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc
new file mode 100644
index 00000000000..459f45ef8fb
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc
@@ -0,0 +1,131 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BKE_curves.hh"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_curve_topology_curve_of_point_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Int>(N_("Point Index"))
+ .implicit_field(implicit_field_inputs::index)
+ .description(N_("The control point to retrieve data from"));
+ b.add_output<decl::Int>(N_("Curve Index"))
+ .dependent_field()
+ .description(N_("The curve the control point is part of"));
+ b.add_output<decl::Int>(N_("Index in Curve"))
+ .dependent_field()
+ .description(N_("How far along the control point is along its curve"));
+}
+
+class CurveOfPointInput final : public bke::CurvesFieldInput {
+ public:
+ CurveOfPointInput() : bke::CurvesFieldInput(CPPType::get<int>(), "Point Curve Index")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
+ const eAttrDomain domain,
+ const IndexMask /*mask*/) const final
+ {
+ if (domain != ATTR_DOMAIN_POINT) {
+ return {};
+ }
+ return VArray<int>::ForContainer(curves.point_to_curve_map());
+ }
+
+ uint64_t hash() const override
+ {
+ return 413209687345908697;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const override
+ {
+ if (dynamic_cast<const CurveOfPointInput *>(&other)) {
+ return true;
+ }
+ return false;
+ }
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
+};
+
+class PointIndexInCurveInput final : public bke::CurvesFieldInput {
+ public:
+ PointIndexInCurveInput() : bke::CurvesFieldInput(CPPType::get<int>(), "Point Index in Curve")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
+ const eAttrDomain domain,
+ const IndexMask /*mask*/) const final
+ {
+ if (domain != ATTR_DOMAIN_POINT) {
+ return {};
+ }
+ const Span<int> offsets = curves.offsets();
+ Array<int> point_to_curve_map = curves.point_to_curve_map();
+ return VArray<int>::ForFunc(
+ curves.points_num(),
+ [offsets, point_to_curve_map = std::move(point_to_curve_map)](const int point_i) {
+ const int curve_i = point_to_curve_map[point_i];
+ return point_i - offsets[curve_i];
+ });
+ }
+
+ uint64_t hash() const final
+ {
+ return 9834765987345677;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const final
+ {
+ if (dynamic_cast<const PointIndexInCurveInput *>(&other)) {
+ return true;
+ }
+ return false;
+ }
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/)
+ {
+ return ATTR_DOMAIN_POINT;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ const Field<int> point_index = params.extract_input<Field<int>>("Point Index");
+ if (params.output_is_required("Curve Index")) {
+ params.set_output(
+ "Curve Index",
+ Field<int>(std::make_shared<FieldAtIndexInput>(
+ point_index, Field<int>(std::make_shared<CurveOfPointInput>()), ATTR_DOMAIN_POINT)));
+ }
+ if (params.output_is_required("Index in Curve")) {
+ params.set_output("Index in Curve",
+ Field<int>(std::make_shared<FieldAtIndexInput>(
+ point_index,
+ Field<int>(std::make_shared<PointIndexInCurveInput>()),
+ ATTR_DOMAIN_POINT)));
+ }
+}
+
+} // namespace blender::nodes::node_geo_curve_topology_curve_of_point_cc
+
+void register_node_type_geo_curve_topology_curve_of_point()
+{
+ namespace file_ns = blender::nodes::node_geo_curve_topology_curve_of_point_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(
+ &ntype, GEO_NODE_CURVE_TOPOLOGY_CURVE_OF_POINT, "Curve of Point", NODE_CLASS_INPUT);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.declare = file_ns::node_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc
new file mode 100644
index 00000000000..7f69503831f
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc
@@ -0,0 +1,192 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BKE_curves.hh"
+
+#include "BLI_task.hh"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_curve_topology_points_of_curve_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Int>(N_("Curve Index"))
+ .implicit_field(implicit_field_inputs::index)
+ .description(N_("The curve to retrieve data from. Defaults to the curve from the context"));
+ b.add_input<decl::Float>(N_("Weights"))
+ .supports_field()
+ .hide_value()
+ .description(N_("Values used to sort the curve's points. Uses indices by default"));
+ b.add_input<decl::Int>(N_("Sort Index"))
+ .min(0)
+ .supports_field()
+ .description(N_("Which of the sorted points to output"));
+ b.add_output<decl::Int>(N_("Point Index"))
+ .dependent_field()
+ .description(N_("A point of the curve, chosen by the sort index"));
+ b.add_output<decl::Int>(N_("Total"))
+ .dependent_field()
+ .description(N_("The number of points in the curve"));
+}
+
+class PointsOfCurveInput final : public bke::CurvesFieldInput {
+ const Field<int> curve_index_;
+ const Field<int> sort_index_;
+ const Field<float> sort_weight_;
+
+ public:
+ PointsOfCurveInput(Field<int> curve_index, Field<int> sort_index, Field<float> sort_weight)
+ : bke::CurvesFieldInput(CPPType::get<int>(), "Point of Curve"),
+ curve_index_(std::move(curve_index)),
+ sort_index_(std::move(sort_index)),
+ sort_weight_(std::move(sort_weight))
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
+ const eAttrDomain domain,
+ const IndexMask mask) const final
+ {
+ const bke::CurvesFieldContext context{curves, domain};
+ fn::FieldEvaluator evaluator{context, &mask};
+ evaluator.add(curve_index_);
+ evaluator.add(sort_index_);
+ evaluator.evaluate();
+ const VArray<int> curve_indices = evaluator.get_evaluated<int>(0);
+ const VArray<int> indices_in_sort = evaluator.get_evaluated<int>(1);
+
+ const bke::CurvesFieldContext point_context{curves, ATTR_DOMAIN_POINT};
+ fn::FieldEvaluator point_evaluator{point_context, curves.points_num()};
+ point_evaluator.add(sort_weight_);
+ point_evaluator.evaluate();
+ const VArray<float> all_sort_weights = point_evaluator.get_evaluated<float>(0);
+
+ Array<int> point_of_curve(mask.min_array_size());
+ threading::parallel_for(mask.index_range(), 256, [&](const IndexRange range) {
+ /* Reuse arrays to avoid allocation. */
+ Array<float> sort_weights;
+ Array<int> sort_indices;
+
+ for (const int selection_i : mask.slice(range)) {
+ const int curve_i = curve_indices[selection_i];
+ const int index_in_sort = indices_in_sort[selection_i];
+ if (!curves.curves_range().contains(curve_i)) {
+ point_of_curve[selection_i] = 0;
+ continue;
+ }
+
+ const IndexRange points = curves.points_for_curve(curve_i);
+
+ /* Retrieve the weights for each point. */
+ sort_weights.reinitialize(points.size());
+ all_sort_weights.materialize_compressed(IndexMask(points), sort_weights.as_mutable_span());
+
+ /* Sort a separate array of compressed indices corresponding to the compressed weights.
+ * This allows using `materialize_compressed` to avoid virtual function call overhead
+ * when accessing values in the sort weights. However, it means a separate array of
+ * indices within the compressed array is necessary for sorting. */
+ sort_indices.reinitialize(points.size());
+ std::iota(sort_indices.begin(), sort_indices.end(), 0);
+ std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) {
+ return sort_weights[a] < sort_weights[b];
+ });
+
+ const int index_in_sort_wrapped = mod_i(index_in_sort, points.size());
+ point_of_curve[selection_i] = points[sort_indices[index_in_sort_wrapped]];
+ }
+ });
+
+ return VArray<int>::ForContainer(std::move(point_of_curve));
+ }
+
+ uint64_t hash() const override
+ {
+ return 26978695677882;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const override
+ {
+ if (const auto *typed = dynamic_cast<const PointsOfCurveInput *>(&other)) {
+ return typed->curve_index_ == curve_index_ && typed->sort_index_ == sort_index_ &&
+ typed->sort_weight_ == sort_weight_;
+ }
+ return false;
+ }
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/) const final
+ {
+ return ATTR_DOMAIN_CURVE;
+ }
+};
+
+class CurvePointCountInput final : public bke::CurvesFieldInput {
+ public:
+ CurvePointCountInput() : bke::CurvesFieldInput(CPPType::get<int>(), "Curve Point Count")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
+ const eAttrDomain domain,
+ const IndexMask /*mask*/) const final
+ {
+ if (domain != ATTR_DOMAIN_CURVE) {
+ return {};
+ }
+ return VArray<int>::ForFunc(curves.curves_num(), [&, curves](const int64_t curve_i) {
+ return curves.points_num_for_curve(curve_i);
+ });
+ }
+
+ uint64_t hash() const final
+ {
+ return 903847569873762;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const final
+ {
+ if (dynamic_cast<const CurvePointCountInput *>(&other)) {
+ return true;
+ }
+ return false;
+ }
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/) const final
+ {
+ return ATTR_DOMAIN_CURVE;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ const Field<int> curve_index = params.extract_input<Field<int>>("Curve Index");
+ if (params.output_is_required("Total")) {
+ params.set_output("Total",
+ Field<int>(std::make_shared<FieldAtIndexInput>(
+ curve_index,
+ Field<int>(std::make_shared<CurvePointCountInput>()),
+ ATTR_DOMAIN_CURVE)));
+ }
+ if (params.output_is_required("Point Index")) {
+ params.set_output("Point Index",
+ Field<int>(std::make_shared<PointsOfCurveInput>(
+ curve_index,
+ params.extract_input<Field<int>>("Sort Index"),
+ params.extract_input<Field<float>>("Weights"))));
+ }
+}
+
+} // namespace blender::nodes::node_geo_curve_topology_points_of_curve_cc
+
+void register_node_type_geo_curve_topology_points_of_curve()
+{
+ namespace file_ns = blender::nodes::node_geo_curve_topology_points_of_curve_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(
+ &ntype, GEO_NODE_CURVE_TOPOLOGY_POINTS_OF_CURVE, "Points of Curve", NODE_CLASS_INPUT);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.declare = file_ns::node_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
index 443f67be421..b0c2f3117fa 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BKE_curves.hh"
-#include "BKE_spline.hh"
#include "BLI_task.hh"
#include "UI_interface.h"
@@ -9,17 +8,18 @@
#include "NOD_socket_search_link.hh"
+#include "GEO_trim_curves.hh"
+
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_curve_trim_cc {
-using blender::attribute_math::mix2;
-
NODE_STORAGE_FUNCS(NodeGeometryCurveTrim)
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
+ b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
b.add_input<decl::Float>(N_("Start"))
.min(0.0f)
.max(1.0f)
@@ -47,12 +47,12 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryCurveTrim *data = MEM_cnew<NodeGeometryCurveTrim>(__func__);
@@ -65,7 +65,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
const NodeGeometryCurveTrim &storage = node_storage(*node);
const GeometryNodeCurveSampleMode mode = (GeometryNodeCurveSampleMode)storage.mode;
- bNodeSocket *start_fac = ((bNodeSocket *)node->inputs.first)->next;
+ bNodeSocket *start_fac = static_cast<bNodeSocket *>(node->inputs.first)->next->next;
bNodeSocket *end_fac = start_fac->next;
bNodeSocket *start_len = end_fac->next;
bNodeSocket *end_len = start_len->next;
@@ -96,8 +96,8 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
search_link_ops_for_declarations(params, declaration.inputs().take_front(1));
if (params.in_out() == SOCK_IN) {
- if (params.node_tree().typeinfo->validate_link(
- static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_FLOAT)) {
+ if (params.node_tree().typeinfo->validate_link(eNodeSocketDatatype(params.other_socket().type),
+ SOCK_FLOAT)) {
params.add_item(IFACE_("Start (Factor)"),
SocketSearchOp{"Start", GEO_NODE_CURVE_SAMPLE_FACTOR});
params.add_item(IFACE_("End (Factor)"), SocketSearchOp{"End", GEO_NODE_CURVE_SAMPLE_FACTOR});
@@ -108,396 +108,9 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
}
}
-struct TrimLocation {
- /* Control point index at the start side of the trim location. */
- int left_index;
- /* Control point index at the end of the trim location's segment. */
- int right_index;
- /* The factor between the left and right indices. */
- float factor;
-};
-
-template<typename T>
-static void shift_slice_to_start(MutableSpan<T> data, const int start_index, const int num)
-{
- BLI_assert(start_index + num - 1 <= data.size());
- memmove(data.data(), &data[start_index], sizeof(T) * num);
-}
-
-/* Shift slice to start of span and modifies start and end data. */
-template<typename T>
-static void linear_trim_data(const TrimLocation &start,
- const TrimLocation &end,
- MutableSpan<T> data)
-{
- const int num = end.right_index - start.left_index + 1;
-
- if (start.left_index > 0) {
- shift_slice_to_start<T>(data, start.left_index, num);
- }
-
- const T start_data = mix2<T>(start.factor, data.first(), data[1]);
- const T end_data = mix2<T>(end.factor, data[num - 2], data[num - 1]);
-
- data.first() = start_data;
- data[num - 1] = end_data;
-}
-
-/**
- * Identical operation as #linear_trim_data, but copy data to a new #MutableSpan rather than
- * modifying the original data.
- */
-template<typename T>
-static void linear_trim_to_output_data(const TrimLocation &start,
- const TrimLocation &end,
- Span<T> src,
- MutableSpan<T> dst)
-{
- const int num = end.right_index - start.left_index + 1;
-
- const T start_data = mix2<T>(start.factor, src[start.left_index], src[start.right_index]);
- const T end_data = mix2<T>(end.factor, src[end.left_index], src[end.right_index]);
-
- dst.copy_from(src.slice(start.left_index, num));
- dst.first() = start_data;
- dst.last() = end_data;
-}
-
-/* Look up the control points to the left and right of factor, and get the factor between them. */
-static TrimLocation lookup_control_point_position(const Spline::LookupResult &lookup,
- const BezierSpline &spline)
-{
- Span<int> offsets = spline.control_point_offsets();
-
- const int *offset = std::lower_bound(offsets.begin(), offsets.end(), lookup.evaluated_index);
- const int index = offset - offsets.begin();
-
- const int left = offsets[index] > lookup.evaluated_index ? index - 1 : index;
- const int right = left == (spline.size() - 1) ? 0 : left + 1;
-
- const float offset_in_segment = lookup.evaluated_index + lookup.factor - offsets[left];
- const int segment_eval_num = offsets[left + 1] - offsets[left];
- const float factor = std::clamp(offset_in_segment / segment_eval_num, 0.0f, 1.0f);
-
- return {left, right, factor};
-}
-
-static void trim_poly_spline(Spline &spline,
- const Spline::LookupResult &start_lookup,
- const Spline::LookupResult &end_lookup)
-{
- /* Poly splines have a 1 to 1 mapping between control points and evaluated points. */
- const TrimLocation start = {
- start_lookup.evaluated_index, start_lookup.next_evaluated_index, start_lookup.factor};
- const TrimLocation end = {
- end_lookup.evaluated_index, end_lookup.next_evaluated_index, end_lookup.factor};
-
- const int num = end.right_index - start.left_index + 1;
-
- linear_trim_data<float3>(start, end, spline.positions());
- linear_trim_data<float>(start, end, spline.radii());
- linear_trim_data<float>(start, end, spline.tilts());
-
- spline.attributes.foreach_attribute(
- [&](const AttributeIDRef &attribute_id, const AttributeMetaData &UNUSED(meta_data)) {
- std::optional<GMutableSpan> src = spline.attributes.get_for_write(attribute_id);
- BLI_assert(src);
- attribute_math::convert_to_static_type(src->type(), [&](auto dummy) {
- using T = decltype(dummy);
- linear_trim_data<T>(start, end, src->typed<T>());
- });
- return true;
- },
- ATTR_DOMAIN_POINT);
-
- spline.resize(num);
-}
-
-/**
- * Trim NURB splines by converting to a poly spline.
- */
-static PolySpline trim_nurbs_spline(const Spline &spline,
- const Spline::LookupResult &start_lookup,
- const Spline::LookupResult &end_lookup)
-{
- /* Since this outputs a poly spline, the evaluated indices are the control point indices. */
- const TrimLocation start = {
- start_lookup.evaluated_index, start_lookup.next_evaluated_index, start_lookup.factor};
- const TrimLocation end = {
- end_lookup.evaluated_index, end_lookup.next_evaluated_index, end_lookup.factor};
-
- const int num = end.right_index - start.left_index + 1;
-
- /* Create poly spline and copy trimmed data to it. */
- PolySpline new_spline;
- new_spline.resize(num);
-
- /* Copy generic attribute data. */
- spline.attributes.foreach_attribute(
- [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
- std::optional<GSpan> src = spline.attributes.get_for_read(attribute_id);
- BLI_assert(src);
- if (!new_spline.attributes.create(attribute_id, meta_data.data_type)) {
- BLI_assert_unreachable();
- return false;
- }
- std::optional<GMutableSpan> dst = new_spline.attributes.get_for_write(attribute_id);
- BLI_assert(dst);
-
- attribute_math::convert_to_static_type(src->type(), [&](auto dummy) {
- using T = decltype(dummy);
- VArray<T> eval_data = spline.interpolate_to_evaluated<T>(src->typed<T>());
- linear_trim_to_output_data<T>(
- start, end, eval_data.get_internal_span(), dst->typed<T>());
- });
- return true;
- },
- ATTR_DOMAIN_POINT);
-
- linear_trim_to_output_data<float3>(
- start, end, spline.evaluated_positions(), new_spline.positions());
-
- VArray<float> evaluated_radii = spline.interpolate_to_evaluated(spline.radii());
- linear_trim_to_output_data<float>(
- start, end, evaluated_radii.get_internal_span(), new_spline.radii());
-
- VArray<float> evaluated_tilts = spline.interpolate_to_evaluated(spline.tilts());
- linear_trim_to_output_data<float>(
- start, end, evaluated_tilts.get_internal_span(), new_spline.tilts());
-
- return new_spline;
-}
-
-/**
- * Trim Bezier splines by adjusting the first and last handles
- * and control points to maintain the original shape.
- */
-static void trim_bezier_spline(Spline &spline,
- const Spline::LookupResult &start_lookup,
- const Spline::LookupResult &end_lookup)
-{
- BezierSpline &bezier_spline = static_cast<BezierSpline &>(spline);
-
- const TrimLocation start = lookup_control_point_position(start_lookup, bezier_spline);
- TrimLocation end = lookup_control_point_position(end_lookup, bezier_spline);
-
- const Span<int> control_offsets = bezier_spline.control_point_offsets();
-
- /* The number of control points in the resulting spline. */
- const int num = end.right_index - start.left_index + 1;
-
- /* Trim the spline attributes. Done before end.factor recalculation as it needs
- * the original end.factor value. */
- linear_trim_data<float>(start, end, bezier_spline.radii());
- linear_trim_data<float>(start, end, bezier_spline.tilts());
- spline.attributes.foreach_attribute(
- [&](const AttributeIDRef &attribute_id, const AttributeMetaData &UNUSED(meta_data)) {
- std::optional<GMutableSpan> src = spline.attributes.get_for_write(attribute_id);
- BLI_assert(src);
- attribute_math::convert_to_static_type(src->type(), [&](auto dummy) {
- using T = decltype(dummy);
- linear_trim_data<T>(start, end, src->typed<T>());
- });
- return true;
- },
- ATTR_DOMAIN_POINT);
-
- /* Recalculate end.factor if the `num` is two, because the adjustment in the
- * position of the control point of the spline to the left of the new end point will change the
- * factor between them. */
- if (num == 2) {
- if (start_lookup.factor == 1.0f) {
- end.factor = 0.0f;
- }
- else {
- end.factor = (end_lookup.evaluated_index + end_lookup.factor -
- (start_lookup.evaluated_index + start_lookup.factor)) /
- (control_offsets[end.right_index] -
- (start_lookup.evaluated_index + start_lookup.factor));
- end.factor = std::clamp(end.factor, 0.0f, 1.0f);
- }
- }
-
- BezierSpline::InsertResult start_point = bezier_spline.calculate_segment_insertion(
- start.left_index, start.right_index, start.factor);
-
- /* Update the start control point parameters so they are used calculating the new end point. */
- bezier_spline.positions()[start.left_index] = start_point.position;
- bezier_spline.handle_positions_right()[start.left_index] = start_point.right_handle;
- bezier_spline.handle_positions_left()[start.right_index] = start_point.handle_next;
-
- const BezierSpline::InsertResult end_point = bezier_spline.calculate_segment_insertion(
- end.left_index, end.right_index, end.factor);
-
- /* If `num` is two, then the start point right handle needs to change to reflect the end point
- * previous handle update. */
- if (num == 2) {
- start_point.right_handle = end_point.handle_prev;
- }
-
- /* Shift control point position data to start at beginning of array. */
- if (start.left_index > 0) {
- shift_slice_to_start(bezier_spline.positions(), start.left_index, num);
- shift_slice_to_start(bezier_spline.handle_positions_left(), start.left_index, num);
- shift_slice_to_start(bezier_spline.handle_positions_right(), start.left_index, num);
- }
-
- bezier_spline.positions().first() = start_point.position;
- bezier_spline.positions()[num - 1] = end_point.position;
-
- bezier_spline.handle_positions_left().first() = start_point.left_handle;
- bezier_spline.handle_positions_left()[num - 1] = end_point.left_handle;
-
- bezier_spline.handle_positions_right().first() = start_point.right_handle;
- bezier_spline.handle_positions_right()[num - 1] = end_point.right_handle;
-
- /* If there is at least one control point between the endpoints, update the control
- * point handle to the right of the start point and to the left of the end point. */
- if (num > 2) {
- bezier_spline.handle_positions_left()[start.right_index - start.left_index] =
- start_point.handle_next;
- bezier_spline.handle_positions_right()[end.left_index - start.left_index] =
- end_point.handle_prev;
- }
-
- bezier_spline.resize(num);
-}
-
-static void trim_spline(SplinePtr &spline,
- const Spline::LookupResult start,
- const Spline::LookupResult end)
-{
- switch (spline->type()) {
- case CURVE_TYPE_BEZIER:
- trim_bezier_spline(*spline, start, end);
- break;
- case CURVE_TYPE_POLY:
- trim_poly_spline(*spline, start, end);
- break;
- case CURVE_TYPE_NURBS:
- spline = std::make_unique<PolySpline>(trim_nurbs_spline(*spline, start, end));
- break;
- case CURVE_TYPE_CATMULL_ROM:
- BLI_assert_unreachable();
- spline = {};
- }
- spline->mark_cache_invalid();
-}
-
-template<typename T>
-static void to_single_point_data(const TrimLocation &trim, MutableSpan<T> data)
-{
- data.first() = mix2<T>(trim.factor, data[trim.left_index], data[trim.right_index]);
-}
-template<typename T>
-static void to_single_point_data(const TrimLocation &trim, Span<T> src, MutableSpan<T> dst)
-{
- dst.first() = mix2<T>(trim.factor, src[trim.left_index], src[trim.right_index]);
-}
-
-static void to_single_point_bezier(Spline &spline, const Spline::LookupResult &lookup)
-{
- BezierSpline &bezier = static_cast<BezierSpline &>(spline);
-
- const TrimLocation trim = lookup_control_point_position(lookup, bezier);
-
- const BezierSpline::InsertResult new_point = bezier.calculate_segment_insertion(
- trim.left_index, trim.right_index, trim.factor);
- bezier.positions().first() = new_point.position;
- bezier.handle_types_left().first() = BEZIER_HANDLE_FREE;
- bezier.handle_types_right().first() = BEZIER_HANDLE_FREE;
- bezier.handle_positions_left().first() = new_point.left_handle;
- bezier.handle_positions_right().first() = new_point.right_handle;
-
- to_single_point_data<float>(trim, bezier.radii());
- to_single_point_data<float>(trim, bezier.tilts());
- spline.attributes.foreach_attribute(
- [&](const AttributeIDRef &attribute_id, const AttributeMetaData &UNUSED(meta_data)) {
- std::optional<GMutableSpan> data = spline.attributes.get_for_write(attribute_id);
- attribute_math::convert_to_static_type(data->type(), [&](auto dummy) {
- using T = decltype(dummy);
- to_single_point_data<T>(trim, data->typed<T>());
- });
- return true;
- },
- ATTR_DOMAIN_POINT);
- spline.resize(1);
-}
-
-static void to_single_point_poly(Spline &spline, const Spline::LookupResult &lookup)
-{
- const TrimLocation trim{lookup.evaluated_index, lookup.next_evaluated_index, lookup.factor};
-
- to_single_point_data<float3>(trim, spline.positions());
- to_single_point_data<float>(trim, spline.radii());
- to_single_point_data<float>(trim, spline.tilts());
- spline.attributes.foreach_attribute(
- [&](const AttributeIDRef &attribute_id, const AttributeMetaData &UNUSED(meta_data)) {
- std::optional<GMutableSpan> data = spline.attributes.get_for_write(attribute_id);
- attribute_math::convert_to_static_type(data->type(), [&](auto dummy) {
- using T = decltype(dummy);
- to_single_point_data<T>(trim, data->typed<T>());
- });
- return true;
- },
- ATTR_DOMAIN_POINT);
- spline.resize(1);
-}
-
-static PolySpline to_single_point_nurbs(const Spline &spline, const Spline::LookupResult &lookup)
-{
- /* Since this outputs a poly spline, the evaluated indices are the control point indices. */
- const TrimLocation trim{lookup.evaluated_index, lookup.next_evaluated_index, lookup.factor};
-
- /* Create poly spline and copy trimmed data to it. */
- PolySpline new_spline;
- new_spline.resize(1);
-
- spline.attributes.foreach_attribute(
- [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
- new_spline.attributes.create(attribute_id, meta_data.data_type);
- std::optional<GSpan> src = spline.attributes.get_for_read(attribute_id);
- std::optional<GMutableSpan> dst = new_spline.attributes.get_for_write(attribute_id);
- attribute_math::convert_to_static_type(src->type(), [&](auto dummy) {
- using T = decltype(dummy);
- VArray<T> eval_data = spline.interpolate_to_evaluated<T>(src->typed<T>());
- to_single_point_data<T>(trim, eval_data.get_internal_span(), dst->typed<T>());
- });
- return true;
- },
- ATTR_DOMAIN_POINT);
-
- to_single_point_data<float3>(trim, spline.evaluated_positions(), new_spline.positions());
-
- VArray<float> evaluated_radii = spline.interpolate_to_evaluated(spline.radii());
- to_single_point_data<float>(trim, evaluated_radii.get_internal_span(), new_spline.radii());
-
- VArray<float> evaluated_tilts = spline.interpolate_to_evaluated(spline.tilts());
- to_single_point_data<float>(trim, evaluated_tilts.get_internal_span(), new_spline.tilts());
-
- return new_spline;
-}
-
-static void to_single_point_spline(SplinePtr &spline, const Spline::LookupResult &lookup)
-{
- switch (spline->type()) {
- case CURVE_TYPE_BEZIER:
- to_single_point_bezier(*spline, lookup);
- break;
- case CURVE_TYPE_POLY:
- to_single_point_poly(*spline, lookup);
- break;
- case CURVE_TYPE_NURBS:
- spline = std::make_unique<PolySpline>(to_single_point_nurbs(*spline, lookup));
- break;
- case CURVE_TYPE_CATMULL_ROM:
- BLI_assert_unreachable();
- spline = {};
- }
-}
-
static void geometry_set_curve_trim(GeometrySet &geometry_set,
const GeometryNodeCurveSampleMode mode,
+ Field<bool> &selection_field,
Field<float> &start_field,
Field<float> &end_field)
{
@@ -505,68 +118,29 @@ static void geometry_set_curve_trim(GeometrySet &geometry_set,
return;
}
const Curves &src_curves_id = *geometry_set.get_curves_for_read();
- const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(src_curves_id.geometry);
+ const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap(src_curves_id.geometry);
+ if (src_curves.curves_num() == 0) {
+ return;
+ }
- bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_CURVE};
- fn::FieldEvaluator evaluator{field_context, curves.curves_num()};
+ bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_CURVE};
+ fn::FieldEvaluator evaluator{field_context, src_curves.curves_num()};
+ evaluator.add(selection_field);
evaluator.add(start_field);
evaluator.add(end_field);
evaluator.evaluate();
- const VArray<float> starts = evaluator.get_evaluated<float>(0);
- const VArray<float> ends = evaluator.get_evaluated<float>(1);
-
- std::unique_ptr<CurveEval> curve = curves_to_curve_eval(src_curves_id);
- MutableSpan<SplinePtr> splines = curve->splines();
-
- threading::parallel_for(splines.index_range(), 128, [&](IndexRange range) {
- for (const int i : range) {
- SplinePtr &spline = splines[i];
-
- /* Currently trimming cyclic splines is not supported. It could be in the future though. */
- if (spline->is_cyclic()) {
- continue;
- }
- if (spline->evaluated_edges_num() == 0) {
- continue;
- }
+ const IndexMask selection = evaluator.get_evaluated_as_mask(0);
+ const VArray<float> starts = evaluator.get_evaluated<float>(1);
+ const VArray<float> ends = evaluator.get_evaluated<float>(2);
- const float length = spline->length();
- if (length == 0.0f) {
- continue;
- }
-
- const float start = starts[i];
- const float end = ends[i];
-
- /* When the start and end samples are reversed, instead of implicitly reversing the spline
- * or switching the parameters, create a single point spline with the end sample point. */
- if (end <= start) {
- if (mode == GEO_NODE_CURVE_SAMPLE_LENGTH) {
- to_single_point_spline(spline,
- spline->lookup_evaluated_length(std::clamp(start, 0.0f, length)));
- }
- else {
- to_single_point_spline(spline,
- spline->lookup_evaluated_factor(std::clamp(start, 0.0f, 1.0f)));
- }
- continue;
- }
-
- if (mode == GEO_NODE_CURVE_SAMPLE_LENGTH) {
- trim_spline(spline,
- spline->lookup_evaluated_length(std::clamp(start, 0.0f, length)),
- spline->lookup_evaluated_length(std::clamp(end, 0.0f, length)));
- }
- else {
- trim_spline(spline,
- spline->lookup_evaluated_factor(std::clamp(start, 0.0f, 1.0f)),
- spline->lookup_evaluated_factor(std::clamp(end, 0.0f, 1.0f)));
- }
- }
- });
+ if (selection.is_empty()) {
+ return;
+ }
- Curves *dst_curves_id = curve_eval_to_curves(*curve);
+ bke::CurvesGeometry dst_curves = geometry::trim_curves(
+ src_curves, selection, starts, ends, mode);
+ Curves *dst_curves_id = bke::curves_new_nomain(std::move(dst_curves));
bke::curves_copy_parameters(src_curves_id, *dst_curves_id);
geometry_set.replace_curves(dst_curves_id);
}
@@ -579,18 +153,19 @@ static void node_geo_exec(GeoNodeExecParams params)
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set);
+ Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
if (mode == GEO_NODE_CURVE_SAMPLE_FACTOR) {
Field<float> start_field = params.extract_input<Field<float>>("Start");
Field<float> end_field = params.extract_input<Field<float>>("End");
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
- geometry_set_curve_trim(geometry_set, mode, start_field, end_field);
+ geometry_set_curve_trim(geometry_set, mode, selection_field, start_field, end_field);
});
}
else if (mode == GEO_NODE_CURVE_SAMPLE_LENGTH) {
Field<float> start_field = params.extract_input<Field<float>>("Start_001");
Field<float> end_field = params.extract_input<Field<float>>("End_001");
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
- geometry_set_curve_trim(geometry_set, mode, start_field, end_field);
+ geometry_set_curve_trim(geometry_set, mode, selection_field, start_field, end_field);
});
}
@@ -610,8 +185,8 @@ void register_node_type_geo_curve_trim()
ntype.declare = file_ns::node_declare;
node_type_storage(
&ntype, "NodeGeometryCurveTrim", node_free_standard_storage, node_copy_standard_storage);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc
index 3f6155460ed..dabd2a1a9f2 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc
@@ -310,12 +310,11 @@ static void node_geo_exec(GeoNodeExecParams params)
ATTR_DOMAIN_CORNER);
const VArraySpan<float3> rest_positions = mesh_attributes_eval.lookup<float3>(rest_position_name,
ATTR_DOMAIN_POINT);
- const Span<float2> surface_uv_coords = curves.surface_uv_coords();
+ const VArraySpan<float2> surface_uv_coords = curves.attributes().lookup_or_default(
+ "surface_uv_coordinate", ATTR_DOMAIN_CURVE, float2(0));
- const Span<MLoopTri> looptris_orig{BKE_mesh_runtime_looptri_ensure(surface_mesh_orig),
- BKE_mesh_runtime_looptri_len(surface_mesh_orig)};
- const Span<MLoopTri> looptris_eval{BKE_mesh_runtime_looptri_ensure(surface_mesh_eval),
- BKE_mesh_runtime_looptri_len(surface_mesh_eval)};
+ const Span<MLoopTri> looptris_orig = surface_mesh_orig->looptris();
+ const Span<MLoopTri> looptris_eval = surface_mesh_eval->looptris();
const ReverseUVSampler reverse_uv_sampler_orig{uv_map_orig, looptris_orig};
const ReverseUVSampler reverse_uv_sampler_eval{uv_map_eval, looptris_eval};
@@ -381,19 +380,23 @@ static void node_geo_exec(GeoNodeExecParams params)
invalid_uv_count);
/* Then also deform edit curve information for use in sculpt mode. */
const CurvesGeometry &curves_orig = CurvesGeometry::wrap(edit_hints->curves_id_orig.geometry);
- deform_curves(curves_orig,
- *surface_mesh_orig,
- *surface_mesh_eval,
- surface_uv_coords,
- reverse_uv_sampler_orig,
- reverse_uv_sampler_eval,
- corner_normals_orig,
- corner_normals_eval,
- rest_positions,
- transforms.surface_to_curves,
- edit_hint_positions,
- edit_hint_rotations,
- invalid_uv_count);
+ const VArraySpan<float2> surface_uv_coords_orig = curves_orig.attributes().lookup_or_default(
+ "surface_uv_coordinate", ATTR_DOMAIN_CURVE, float2(0));
+ if (!surface_uv_coords_orig.is_empty()) {
+ deform_curves(curves_orig,
+ *surface_mesh_orig,
+ *surface_mesh_eval,
+ surface_uv_coords_orig,
+ reverse_uv_sampler_orig,
+ reverse_uv_sampler_eval,
+ corner_normals_orig,
+ corner_normals_eval,
+ rest_positions,
+ transforms.surface_to_curves,
+ edit_hint_positions,
+ edit_hint_rotations,
+ invalid_uv_count);
+ }
}
curves.tag_positions_changed();
diff --git a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
index 851ca622d6b..8ed97f2019f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
@@ -4,6 +4,7 @@
#include "UI_resources.h"
#include "BLI_array.hh"
+#include "BLI_array_utils.hh"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -12,6 +13,7 @@
#include "BKE_attribute_math.hh"
#include "BKE_curves.hh"
#include "BKE_customdata.h"
+#include "BKE_instances.hh"
#include "BKE_mesh.h"
#include "BKE_pointcloud.h"
@@ -22,15 +24,9 @@ namespace blender::nodes::node_geo_delete_geometry_cc {
using blender::bke::CustomDataAttributes;
template<typename T>
-static void copy_data_based_on_mask(Span<T> data, MutableSpan<T> r_data, IndexMask mask)
-{
- for (const int i_out : mask.index_range()) {
- r_data[i_out] = data[mask[i_out]];
- }
-}
-
-template<typename T>
-static void copy_data_based_on_map(Span<T> src, MutableSpan<T> dst, Span<int> index_map)
+static void copy_data_based_on_map(const Span<T> src,
+ const Span<int> index_map,
+ MutableSpan<T> dst)
{
for (const int i_src : index_map.index_range()) {
const int i_dst = index_map[i_src];
@@ -54,26 +50,17 @@ static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes
if (!attribute) {
continue;
}
-
/* Only copy if it is on a domain we want. */
if (!domains.contains(attribute.domain)) {
continue;
}
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
-
GSpanAttributeWriter result_attribute = dst_attributes.lookup_or_add_for_write_only_span(
attribute_id, attribute.domain, data_type);
-
if (!result_attribute) {
continue;
}
-
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
- using T = decltype(dummy);
- VArraySpan<T> span{attribute.varray.typed<T>()};
- MutableSpan<T> out_span = result_attribute.span.typed<T>();
- out_span.copy_from(span);
- });
+ attribute.varray.materialize(result_attribute.span.data());
result_attribute.finish();
}
}
@@ -94,26 +81,19 @@ static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKin
if (!attribute) {
continue;
}
-
/* Only copy if it is on a domain we want. */
if (domain != attribute.domain) {
continue;
}
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
-
GSpanAttributeWriter result_attribute = dst_attributes.lookup_or_add_for_write_only_span(
attribute_id, attribute.domain, data_type);
-
if (!result_attribute) {
continue;
}
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
- using T = decltype(dummy);
- VArraySpan<T> span{attribute.varray.typed<T>()};
- MutableSpan<T> out_span = result_attribute.span.typed<T>();
- copy_data_based_on_mask(span, out_span, mask);
- });
+ array_utils::gather(attribute.varray, mask, result_attribute.span);
+
result_attribute.finish();
}
}
@@ -130,16 +110,13 @@ static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind
if (!attribute) {
continue;
}
-
/* Only copy if it is on a domain we want. */
if (domain != attribute.domain) {
continue;
}
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
-
GSpanAttributeWriter result_attribute = dst_attributes.lookup_or_add_for_write_only_span(
attribute_id, attribute.domain, data_type);
-
if (!result_attribute) {
continue;
}
@@ -148,7 +125,7 @@ static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind
using T = decltype(dummy);
VArraySpan<T> span{attribute.varray.typed<T>()};
MutableSpan<T> out_span = result_attribute.span.typed<T>();
- copy_data_based_on_map(span, out_span, index_map);
+ copy_data_based_on_map(span, index_map, out_span);
});
result_attribute.finish();
}
@@ -392,8 +369,8 @@ static void separate_point_cloud_selection(GeometrySet &geometry_set,
static void delete_selected_instances(GeometrySet &geometry_set,
const Field<bool> &selection_field)
{
- InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
- bke::GeometryFieldContext field_context{instances, ATTR_DOMAIN_INSTANCE};
+ bke::Instances &instances = *geometry_set.get_instances_for_write();
+ bke::InstancesFieldContext field_context{instances};
fn::FieldEvaluator evaluator{field_context, instances.instances_num()};
evaluator.set_selection(selection_field);
@@ -404,7 +381,7 @@ static void delete_selected_instances(GeometrySet &geometry_set,
return;
}
- instances.remove_instances(selection);
+ instances.remove(selection);
}
static void compute_selected_verts_from_vertex_selection(const Span<bool> vertex_selection,
@@ -1159,11 +1136,11 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
const bNode *node = static_cast<bNode *>(ptr->data);
const NodeGeometryDeleteGeometry &storage = node_storage(*node);
- const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain);
+ const eAttrDomain domain = eAttrDomain(storage.domain);
uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
/* Only show the mode when it is relevant. */
@@ -1172,7 +1149,7 @@ static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
}
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryDeleteGeometry *data = MEM_cnew<NodeGeometryDeleteGeometry>(__func__);
data->domain = ATTR_DOMAIN_POINT;
@@ -1192,7 +1169,7 @@ static void node_geo_exec(GeoNodeExecParams params)
params.extract_input<Field<bool>>("Selection"));
const NodeGeometryDeleteGeometry &storage = node_storage(params.node());
- const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain);
+ const eAttrDomain domain = eAttrDomain(storage.domain);
const GeometryNodeDeleteGeometryMode mode = (GeometryNodeDeleteGeometryMode)storage.mode;
if (domain == ATTR_DOMAIN_INSTANCE) {
@@ -1225,7 +1202,7 @@ void register_node_type_geo_delete_geometry()
node_free_standard_storage,
node_copy_standard_storage);
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
ntype.declare = file_ns::node_declare;
ntype.geometry_node_execute = file_ns::node_geo_exec;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_in_volume.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_in_volume.cc
new file mode 100644
index 00000000000..f2e66e03d26
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_in_volume.cc
@@ -0,0 +1,288 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifdef WITH_OPENVDB
+# include <openvdb/openvdb.h>
+# include <openvdb/tools/Interpolation.h>
+# include <openvdb/tools/PointScatter.h>
+#endif
+
+#include "DNA_node_types.h"
+#include "DNA_pointcloud_types.h"
+
+#include "BKE_pointcloud.h"
+#include "BKE_volume.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "DEG_depsgraph_query.h"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes {
+
+NODE_STORAGE_FUNCS(NodeGeometryDistributePointsInVolume)
+
+static void geo_node_distribute_points_in_volume_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>(N_("Volume")).supported_type(GEO_COMPONENT_TYPE_VOLUME);
+ b.add_input<decl::Float>(N_("Density"))
+ .default_value(1.0f)
+ .min(0.0f)
+ .max(100000.0f)
+ .subtype(PROP_NONE)
+ .description(N_("Number of points to sample per unit volume"));
+ b.add_input<decl::Int>(N_("Seed"))
+ .min(-10000)
+ .max(10000)
+ .description(N_("Seed used by the random number generator to generate random points"));
+ b.add_input<decl::Vector>(N_("Spacing"))
+ .default_value({0.3, 0.3, 0.3})
+ .min(0.0001f)
+ .subtype(PROP_XYZ)
+ .description(N_("Spacing between grid points"));
+ b.add_input<decl::Float>(N_("Threshold"))
+ .default_value(0.1f)
+ .min(0.0f)
+ .max(FLT_MAX)
+ .description(N_("Minimum density of a volume cell to contain a grid point"));
+ b.add_output<decl::Geometry>(N_("Points"));
+}
+
+static void geo_node_distribute_points_in_volume_layout(uiLayout *layout,
+ bContext * /*C*/,
+ PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
+}
+
+static void node_distribute_points_in_volume_init(bNodeTree * /*tree*/, bNode *node)
+{
+ NodeGeometryDistributePointsInVolume *data = MEM_cnew<NodeGeometryDistributePointsInVolume>(
+ __func__);
+ data->mode = GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME_DENSITY_RANDOM;
+ node->storage = data;
+}
+
+static void node_distribute_points_in_volume_update(bNodeTree *ntree, bNode *node)
+{
+ const NodeGeometryDistributePointsInVolume &storage = node_storage(*node);
+ GeometryNodeDistributePointsInVolumeMode mode = GeometryNodeDistributePointsInVolumeMode(
+ storage.mode);
+
+ bNodeSocket *sock_density = static_cast<bNodeSocket *>(node->inputs.first)->next;
+ bNodeSocket *sock_seed = sock_density->next;
+ bNodeSocket *sock_spacing = sock_seed->next;
+ bNodeSocket *sock_threshold = sock_spacing->next;
+
+ nodeSetSocketAvailability(
+ ntree, sock_density, mode == GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME_DENSITY_RANDOM);
+ nodeSetSocketAvailability(
+ ntree, sock_seed, mode == GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME_DENSITY_RANDOM);
+ nodeSetSocketAvailability(
+ ntree, sock_spacing, mode == GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME_DENSITY_GRID);
+ nodeSetSocketAvailability(
+ ntree, sock_threshold, mode == GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME_DENSITY_GRID);
+}
+
+#ifdef WITH_OPENVDB
+/* Implements the interface required by #openvdb::tools::NonUniformPointScatter. */
+class PositionsVDBWrapper {
+ private:
+ float3 offset_fix_;
+ Vector<float3> &vector_;
+
+ public:
+ PositionsVDBWrapper(Vector<float3> &vector, const float3 offset_fix)
+ : offset_fix_(offset_fix), vector_(vector)
+ {
+ }
+ PositionsVDBWrapper(const PositionsVDBWrapper &wrapper) = default;
+
+ void add(const openvdb::Vec3R &pos)
+ {
+ vector_.append(float3(float(pos[0]), float(pos[1]), float(pos[2])) + offset_fix_);
+ }
+};
+
+/* Use #std::mt19937 as a random number generator,
+ * it has a very long period and thus there should be no visible patterns in the generated points.
+ */
+using RNGType = std::mt19937;
+/* Non-uniform scatter allows the amount of points to be scaled with the volume's density. */
+using NonUniformPointScatterVDB =
+ openvdb::tools::NonUniformPointScatter<PositionsVDBWrapper, RNGType>;
+
+static void point_scatter_density_random(const openvdb::FloatGrid &grid,
+ const float density,
+ const int seed,
+ Vector<float3> &r_positions)
+{
+ /* Offset points by half a voxel so that grid points are aligned with world grid points. */
+ const float3 offset_fix = {0.5f * float(grid.voxelSize().x()),
+ 0.5f * float(grid.voxelSize().y()),
+ 0.5f * float(grid.voxelSize().z())};
+ /* Setup and call into OpenVDB's point scatter API. */
+ PositionsVDBWrapper vdb_position_wrapper = PositionsVDBWrapper(r_positions, offset_fix);
+ RNGType random_generator(seed);
+ NonUniformPointScatterVDB point_scatter(vdb_position_wrapper, density, random_generator);
+ point_scatter(grid);
+}
+
+static void point_scatter_density_grid(const openvdb::FloatGrid &grid,
+ const float3 spacing,
+ const float threshold,
+ Vector<float3> &r_positions)
+{
+ const openvdb::Vec3d half_voxel(0.5, 0.5, 0.5);
+ const openvdb::Vec3d voxel_spacing(double(spacing.x) / grid.voxelSize().x(),
+ double(spacing.y) / grid.voxelSize().y(),
+ double(spacing.z) / grid.voxelSize().z());
+
+ /* Abort if spacing is zero. */
+ const double min_spacing = std::min(voxel_spacing.x(),
+ std::min(voxel_spacing.y(), voxel_spacing.z()));
+ if (std::abs(min_spacing) < 0.0001) {
+ return;
+ }
+
+ /* Iterate through tiles and voxels on the grid. */
+ for (openvdb::FloatGrid::ValueOnCIter cell = grid.cbeginValueOn(); cell; ++cell) {
+ /* Check if the cell's value meets the minimum threshold. */
+ if (cell.getValue() < threshold) {
+ continue;
+ }
+ /* Compute the bounding box of each tile/voxel. */
+ const openvdb::CoordBBox bbox = cell.getBoundingBox();
+ const openvdb::Vec3d box_min = bbox.min().asVec3d() - half_voxel;
+ const openvdb::Vec3d box_max = bbox.max().asVec3d() + half_voxel;
+
+ /* Pick a starting point rounded up to the nearest possible point. */
+ double abs_spacing_x = std::abs(voxel_spacing.x());
+ double abs_spacing_y = std::abs(voxel_spacing.y());
+ double abs_spacing_z = std::abs(voxel_spacing.z());
+ const openvdb::Vec3d start(ceil(box_min.x() / abs_spacing_x) * abs_spacing_x,
+ ceil(box_min.y() / abs_spacing_y) * abs_spacing_y,
+ ceil(box_min.z() / abs_spacing_z) * abs_spacing_z);
+
+ /* Iterate through all possible points in box. */
+ for (double x = start.x(); x < box_max.x(); x += abs_spacing_x) {
+ for (double y = start.y(); y < box_max.y(); y += abs_spacing_y) {
+ for (double z = start.z(); z < box_max.z(); z += abs_spacing_z) {
+ /* Transform with grid matrix and add point. */
+ const openvdb::Vec3d idx_pos(x, y, z);
+ const openvdb::Vec3d local_pos = grid.indexToWorld(idx_pos + half_voxel);
+ r_positions.append({float(local_pos.x()), float(local_pos.y()), float(local_pos.z())});
+ }
+ }
+ }
+ }
+}
+
+#endif /* WITH_OPENVDB */
+
+static void geo_node_distribute_points_in_volume_exec(GeoNodeExecParams params)
+{
+#ifdef WITH_OPENVDB
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Volume");
+
+ const NodeGeometryDistributePointsInVolume &storage = node_storage(params.node());
+ const GeometryNodeDistributePointsInVolumeMode mode = GeometryNodeDistributePointsInVolumeMode(
+ storage.mode);
+
+ float density;
+ int seed;
+ float3 spacing{0, 0, 0};
+ float threshold;
+ if (mode == GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME_DENSITY_RANDOM) {
+ density = params.extract_input<float>("Density");
+ seed = params.extract_input<int>("Seed");
+ }
+ else if (mode == GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME_DENSITY_GRID) {
+ spacing = params.extract_input<float3>("Spacing");
+ threshold = params.extract_input<float>("Threshold");
+ }
+
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
+ if (!geometry_set.has_volume()) {
+ geometry_set.keep_only({GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_INSTANCES});
+ return;
+ }
+ const VolumeComponent *component = geometry_set.get_component_for_read<VolumeComponent>();
+ const Volume *volume = component->get_for_read();
+ BKE_volume_load(volume, DEG_get_bmain(params.depsgraph()));
+
+ Vector<float3> positions;
+
+ for (const int i : IndexRange(BKE_volume_num_grids(volume))) {
+ const VolumeGrid *volume_grid = BKE_volume_grid_get_for_read(volume, i);
+ if (volume_grid == nullptr) {
+ continue;
+ }
+
+ openvdb::GridBase::ConstPtr base_grid = BKE_volume_grid_openvdb_for_read(volume,
+ volume_grid);
+ if (!base_grid) {
+ continue;
+ }
+
+ if (!base_grid->isType<openvdb::FloatGrid>()) {
+ continue;
+ }
+
+ const openvdb::FloatGrid::ConstPtr grid = openvdb::gridConstPtrCast<openvdb::FloatGrid>(
+ base_grid);
+
+ if (mode == GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME_DENSITY_RANDOM) {
+ point_scatter_density_random(*grid, density, seed, positions);
+ }
+ else if (mode == GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME_DENSITY_GRID) {
+ point_scatter_density_grid(*grid, spacing, threshold, positions);
+ }
+ }
+
+ PointCloud *pointcloud = BKE_pointcloud_new_nomain(positions.size());
+ bke::MutableAttributeAccessor point_attributes = pointcloud->attributes_for_write();
+ bke::SpanAttributeWriter<float3> point_positions =
+ point_attributes.lookup_or_add_for_write_only_span<float3>("position", ATTR_DOMAIN_POINT);
+ bke::SpanAttributeWriter<float> point_radii =
+ point_attributes.lookup_or_add_for_write_only_span<float>("radius", ATTR_DOMAIN_POINT);
+
+ point_positions.span.copy_from(positions);
+ point_radii.span.fill(0.05f);
+ point_positions.finish();
+ point_radii.finish();
+
+ geometry_set.replace_pointcloud(pointcloud);
+ geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_POINT_CLOUD});
+ });
+
+ params.set_output("Points", std::move(geometry_set));
+
+#else
+ params.set_default_remaining_outputs();
+ params.error_message_add(NodeWarningType::Error,
+ TIP_("Disabled, Blender was compiled without OpenVDB"));
+#endif
+}
+} // namespace blender::nodes
+
+void register_node_type_geo_distribute_points_in_volume()
+{
+ static bNodeType ntype;
+ geo_node_type_base(&ntype,
+ GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME,
+ "Distribute Points in Volume",
+ NODE_CLASS_GEOMETRY);
+ node_type_storage(&ntype,
+ "NodeGeometryDistributePointsInVolume",
+ node_free_standard_storage,
+ node_copy_standard_storage);
+ ntype.initfunc = blender::nodes::node_distribute_points_in_volume_init;
+ ntype.updatefunc = blender::nodes::node_distribute_points_in_volume_update;
+ node_type_size(&ntype, 170, 100, 320);
+ ntype.declare = blender::nodes::geo_node_distribute_points_in_volume_declare;
+ ntype.geometry_node_execute = blender::nodes::geo_node_distribute_points_in_volume_exec;
+ ntype.draw_buttons = blender::nodes::geo_node_distribute_points_in_volume_layout;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
index b84ee33e26f..7c9501608a3 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
@@ -62,15 +62,15 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Rotation")).subtype(PROP_EULER).field_source();
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "distribute_method", 0, "", ICON_NONE);
}
static void node_point_distribute_points_on_faces_update(bNodeTree *ntree, bNode *node)
{
- bNodeSocket *sock_distance_min = (bNodeSocket *)BLI_findlink(&node->inputs, 2);
- bNodeSocket *sock_density_max = (bNodeSocket *)sock_distance_min->next;
+ bNodeSocket *sock_distance_min = static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 2));
+ bNodeSocket *sock_density_max = static_cast<bNodeSocket *>(sock_distance_min->next);
bNodeSocket *sock_density = sock_density_max->next;
bNodeSocket *sock_density_factor = sock_density->next;
nodeSetSocketAvailability(ntree,
@@ -107,8 +107,7 @@ static void sample_mesh_surface(const Mesh &mesh,
{
const Span<MVert> verts = mesh.verts();
const Span<MLoop> loops = mesh.loops();
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
- BKE_mesh_runtime_looptri_len(&mesh)};
+ const Span<MLoopTri> looptris = mesh.looptris();
for (const int looptri_index : looptris.index_range()) {
const MLoopTri &looptri = looptris[looptri_index];
@@ -186,7 +185,7 @@ BLI_NOINLINE static void update_elimination_mask_for_close_points(
kdtree,
positions[i],
minimum_distance,
- [](void *user_data, int index, const float *UNUSED(co), float UNUSED(dist_sq)) {
+ [](void *user_data, int index, const float * /*co*/, float /*dist_sq*/) {
CallbackData &callback_data = *static_cast<CallbackData *>(user_data);
if (index != callback_data.index) {
callback_data.elimination_mask[index] = true;
@@ -204,8 +203,7 @@ BLI_NOINLINE static void update_elimination_mask_based_on_density_factors(
const Span<int> looptri_indices,
const MutableSpan<bool> elimination_mask)
{
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
- BKE_mesh_runtime_looptri_len(&mesh)};
+ const Span<MLoopTri> looptris = mesh.looptris();
for (const int i : bary_coords.index_range()) {
if (elimination_mask[i]) {
continue;
@@ -352,8 +350,7 @@ BLI_NOINLINE static void compute_attribute_outputs(const Mesh &mesh,
const Span<MVert> verts = mesh.verts();
const Span<MLoop> loops = mesh.loops();
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
- BKE_mesh_runtime_looptri_len(&mesh)};
+ const Span<MLoopTri> looptris = mesh.looptris();
for (const int i : bary_coords.index_range()) {
const int looptri_index = looptri_indices[i];
@@ -382,13 +379,8 @@ BLI_NOINLINE static void compute_attribute_outputs(const Mesh &mesh,
}
ids.finish();
-
- if (normals) {
- normals.finish();
- }
- if (rotations) {
- rotations.finish();
- }
+ normals.finish();
+ rotations.finish();
}
static Array<float> calc_full_density_factors_with_selection(const Mesh &mesh,
@@ -519,8 +511,8 @@ static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
- const GeometryNodeDistributePointsOnFacesMode method =
- static_cast<GeometryNodeDistributePointsOnFacesMode>(params.node().custom1);
+ const GeometryNodeDistributePointsOnFacesMode method = GeometryNodeDistributePointsOnFacesMode(
+ params.node().custom1);
const int seed = params.get_input<int>("Seed") * 5383843;
const Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
@@ -533,6 +525,8 @@ static void node_geo_exec(GeoNodeExecParams params)
attribute_outputs.rotation_id = StrongAnonymousAttributeID("Rotation");
}
+ lazy_threading::send_hint();
+
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
point_distribution_calculate(
geometry_set, selection_field, method, seed, attribute_outputs, params);
@@ -569,7 +563,7 @@ void register_node_type_geo_distribute_points_on_faces()
GEO_NODE_DISTRIBUTE_POINTS_ON_FACES,
"Distribute Points on Faces",
NODE_CLASS_GEOMETRY);
- node_type_update(&ntype, file_ns::node_point_distribute_points_on_faces_update);
+ ntype.updatefunc = file_ns::node_point_distribute_points_on_faces_update;
node_type_size(&ntype, 170, 100, 320);
ntype.declare = file_ns::node_declare;
ntype.geometry_node_execute = file_ns::node_geo_exec;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc
index 84e63845b84..9b1c13bf563 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "BLI_array_utils.hh"
#include "BLI_task.hh"
#include "DNA_mesh_types.h"
@@ -105,18 +106,6 @@ static void copy_data_based_on_pairs(Span<T> data,
}
}
-/* Copy using the map. */
-template<typename T>
-static void copy_data_based_on_new_to_old_map(Span<T> data,
- MutableSpan<T> r_data,
- const Span<int> new_to_old_map)
-{
- for (const int i : r_data.index_range()) {
- const int old_i = new_to_old_map[i];
- r_data[i] = data[old_i];
- }
-}
-
/**
* Transfers the attributes from the original mesh to the new mesh using the following logic:
* - If the attribute was on the face domain it is now on the point domain, and this is true
@@ -168,7 +157,6 @@ static void transfer_attributes(
src_attribute.varray.type());
GSpanAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write_only_span(
attribute_id, out_domain, data_type);
-
if (!dst_attribute) {
continue;
}
@@ -177,20 +165,24 @@ static void transfer_attributes(
using T = decltype(dummy);
VArraySpan<T> span{src_attribute.varray.typed<T>()};
MutableSpan<T> dst_span = dst_attribute.span.typed<T>();
- if (src_attribute.domain == ATTR_DOMAIN_FACE) {
- dst_span.take_front(span.size()).copy_from(span);
- if (keep_boundaries) {
- copy_data_based_on_pairs(span, dst_span, boundary_vertex_to_relevant_face_map);
- }
- }
- else if (src_attribute.domain == ATTR_DOMAIN_POINT) {
- copy_data_based_on_vertex_types(span, dst_span, vertex_types, keep_boundaries);
- }
- else if (src_attribute.domain == ATTR_DOMAIN_EDGE) {
- copy_data_based_on_new_to_old_map(span, dst_span, new_to_old_edges_map);
- }
- else {
- copy_data_based_on_new_to_old_map(span, dst_span, new_to_old_face_corners_map);
+ switch (src_attribute.domain) {
+ case ATTR_DOMAIN_POINT:
+ copy_data_based_on_vertex_types(span, dst_span, vertex_types, keep_boundaries);
+ break;
+ case ATTR_DOMAIN_EDGE:
+ array_utils::gather(span, new_to_old_edges_map, dst_span);
+ break;
+ case ATTR_DOMAIN_FACE:
+ dst_span.take_front(span.size()).copy_from(span);
+ if (keep_boundaries) {
+ copy_data_based_on_pairs(span, dst_span, boundary_vertex_to_relevant_face_map);
+ }
+ break;
+ case ATTR_DOMAIN_CORNER:
+ array_utils::gather(span, new_to_old_face_corners_map, dst_span);
+ break;
+ default:
+ BLI_assert_unreachable();
}
});
dst_attribute.finish();
diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
index d2a3c339301..f048ec11f77 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "BLI_array_utils.hh"
#include "BLI_map.hh"
#include "BLI_noise.hh"
#include "BLI_span.hh"
@@ -11,6 +12,7 @@
#include "BKE_attribute_math.hh"
#include "BKE_curves.hh"
+#include "BKE_instances.hh"
#include "BKE_mesh.h"
#include "BKE_pointcloud.h"
@@ -40,14 +42,14 @@ static void node_declare(NodeDeclarationBuilder &b)
.description(N_("The indices of the duplicates for each element"));
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryDuplicateElements *data = MEM_cnew<NodeGeometryDuplicateElements>(__func__);
data->domain = ATTR_DOMAIN_POINT;
node->storage = data;
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
}
@@ -104,16 +106,6 @@ static void threaded_slice_fill(Span<int> offsets,
});
}
-template<typename T>
-static void threaded_mapped_copy(const Span<int> mapping, const Span<T> src, MutableSpan<T> dst)
-{
- threading::parallel_for(mapping.index_range(), 512, [&](IndexRange range) {
- for (const int i : range) {
- dst[i] = src[mapping[i]];
- }
- });
-}
-
static void copy_hashed_ids(const Span<int> src, const int hash, MutableSpan<int> dst)
{
for (const int i : src.index_range()) {
@@ -439,17 +431,17 @@ static void copy_face_attributes_without_id(GeometrySet &geometry_set,
MutableSpan<T> dst = dst_attribute.span.typed<T>();
switch (out_domain) {
- case ATTR_DOMAIN_FACE:
- threaded_slice_fill<T>(offsets, selection, src, dst);
+ case ATTR_DOMAIN_POINT:
+ array_utils::gather(src, vert_mapping, dst);
break;
case ATTR_DOMAIN_EDGE:
- threaded_mapped_copy<T>(edge_mapping, src, dst);
+ array_utils::gather(src, edge_mapping, dst);
break;
- case ATTR_DOMAIN_POINT:
- threaded_mapped_copy<T>(vert_mapping, src, dst);
+ case ATTR_DOMAIN_FACE:
+ threaded_slice_fill<T>(offsets, selection, src, dst);
break;
case ATTR_DOMAIN_CORNER:
- threaded_mapped_copy<T>(loop_mapping, src, dst);
+ array_utils::gather(src, loop_mapping, dst);
break;
default:
break;
@@ -652,7 +644,7 @@ static void copy_edge_attributes_without_id(GeometrySet &geometry_set,
threaded_slice_fill<T>(offsets, selection, src, dst);
break;
case ATTR_DOMAIN_POINT:
- threaded_mapped_copy<T>(point_mapping, src, dst);
+ array_utils::gather(src, point_mapping, dst);
break;
default:
break;
@@ -1031,10 +1023,9 @@ static void duplicate_instances(GeometrySet &geometry_set,
return;
}
- const InstancesComponent &src_instances =
- *geometry_set.get_component_for_read<InstancesComponent>();
+ const bke::Instances &src_instances = *geometry_set.get_instances_for_read();
- bke::GeometryFieldContext field_context{src_instances, ATTR_DOMAIN_INSTANCE};
+ bke::InstancesFieldContext field_context{src_instances};
FieldEvaluator evaluator{field_context, src_instances.instances_num()};
evaluator.add(count_field);
evaluator.set_selection(selection_field);
@@ -1048,20 +1039,20 @@ static void duplicate_instances(GeometrySet &geometry_set,
return;
}
- GeometrySet dst_geometry;
- InstancesComponent &dst_instances = dst_geometry.get_component_for_write<InstancesComponent>();
- dst_instances.resize(offsets.last());
+ std::unique_ptr<bke::Instances> dst_instances = std::make_unique<bke::Instances>();
+
+ dst_instances->resize(offsets.last());
for (const int i_selection : selection.index_range()) {
const IndexRange range = range_for_offsets_index(offsets, i_selection);
if (range.size() == 0) {
continue;
}
- const int old_handle = src_instances.instance_reference_handles()[i_selection];
- const InstanceReference reference = src_instances.references()[old_handle];
- const int new_handle = dst_instances.add_reference(reference);
- const float4x4 transform = src_instances.instance_transforms()[i_selection];
- dst_instances.instance_transforms().slice(range).fill(transform);
- dst_instances.instance_reference_handles().slice(range).fill(new_handle);
+ const int old_handle = src_instances.reference_handles()[i_selection];
+ const bke::InstanceReference reference = src_instances.references()[old_handle];
+ const int new_handle = dst_instances->add_reference(reference);
+ const float4x4 transform = src_instances.transforms()[i_selection];
+ dst_instances->transforms().slice(range).fill(transform);
+ dst_instances->reference_handles().slice(range).fill(new_handle);
}
copy_attributes_without_id(geometry_set,
@@ -1069,18 +1060,18 @@ static void duplicate_instances(GeometrySet &geometry_set,
ATTR_DOMAIN_INSTANCE,
offsets,
selection,
- *src_instances.attributes(),
- *dst_instances.attributes_for_write());
+ src_instances.attributes(),
+ dst_instances->attributes_for_write());
if (attribute_outputs.duplicate_index) {
- create_duplicate_index_attribute(*dst_instances.attributes_for_write(),
+ create_duplicate_index_attribute(dst_instances->attributes_for_write(),
ATTR_DOMAIN_INSTANCE,
selection,
attribute_outputs,
offsets);
}
- geometry_set = std::move(dst_geometry);
+ geometry_set = GeometrySet::create_with_instances(dst_instances.release());
}
/** \} */
@@ -1158,7 +1149,7 @@ void register_node_type_geo_duplicate_elements()
node_free_standard_storage,
node_copy_standard_storage);
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
ntype.draw_buttons = file_ns::node_layout;
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.declare = file_ns::node_declare;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc
index 9ef9ee8ad6e..f0bd01a012b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc
@@ -106,6 +106,11 @@ class PathToEdgeSelectionFieldInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_EDGE;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
index c7f4b78946d..0062abba909 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "BLI_array_utils.hh"
#include "BLI_disjoint_set.hh"
#include "BLI_task.hh"
#include "BLI_vector_set.hh"
@@ -24,7 +25,10 @@ static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Mesh").supported_type(GEO_COMPONENT_TYPE_MESH);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).supports_field().hide_value();
- b.add_input<decl::Vector>(N_("Offset")).subtype(PROP_TRANSLATION).implicit_field().hide_value();
+ b.add_input<decl::Vector>(N_("Offset"))
+ .subtype(PROP_TRANSLATION)
+ .implicit_field(implicit_field_inputs::normal)
+ .hide_value();
b.add_input<decl::Float>(N_("Offset Scale")).default_value(1.0f).supports_field();
b.add_input<decl::Bool>(N_("Individual")).default_value(true);
b.add_output<decl::Geometry>("Mesh");
@@ -32,14 +36,14 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Bool>(N_("Side")).field_source();
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryExtrudeMesh *data = MEM_cnew<NodeGeometryExtrudeMesh>(__func__);
data->mode = GEO_NODE_EXTRUDE_MESH_FACES;
@@ -49,9 +53,9 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryExtrudeMesh &storage = node_storage(*node);
- const GeometryNodeExtrudeMeshMode mode = static_cast<GeometryNodeExtrudeMeshMode>(storage.mode);
+ const GeometryNodeExtrudeMeshMode mode = GeometryNodeExtrudeMeshMode(storage.mode);
- bNodeSocket *individual_socket = (bNodeSocket *)node->inputs.last;
+ bNodeSocket *individual_socket = static_cast<bNodeSocket *>(node->inputs.last);
nodeSetSocketAvailability(ntree, individual_socket, mode == GEO_NODE_EXTRUDE_MESH_FACES);
}
@@ -132,6 +136,9 @@ static CustomData &get_customdata(Mesh &mesh, const eAttrDomain domain)
}
}
+/**
+ * \note The result may be an empty span.
+ */
static MutableSpan<int> get_orig_index_layer(Mesh &mesh, const eAttrDomain domain)
{
const bke::AttributeAccessor attributes = mesh.attributes();
@@ -147,8 +154,7 @@ static MEdge new_edge(const int v1, const int v2)
MEdge edge;
edge.v1 = v1;
edge.v2 = v2;
- edge.crease = 0;
- edge.flag = (ME_EDGEDRAW | ME_EDGERENDER);
+ edge.flag = ME_EDGEDRAW;
return edge;
}
@@ -157,7 +163,6 @@ static MEdge new_loose_edge(const int v1, const int v2)
MEdge edge;
edge.v1 = v1;
edge.v2 = v2;
- edge.crease = 0;
edge.flag = ME_LOOSEEDGE;
return edge;
}
@@ -171,24 +176,6 @@ static MPoly new_poly(const int loopstart, const int totloop)
return poly;
}
-template<typename T> void copy_with_indices(MutableSpan<T> dst, Span<T> src, Span<int> indices)
-{
- BLI_assert(dst.size() == indices.size());
- for (const int i : dst.index_range()) {
- dst[i] = src[indices[i]];
- }
-}
-
-template<typename T> void copy_with_mask(MutableSpan<T> dst, Span<T> src, IndexMask mask)
-{
- BLI_assert(dst.size() == mask.size());
- threading::parallel_for(mask.index_range(), 512, [&](const IndexRange range) {
- for (const int i : range) {
- dst[i] = src[mask[i]];
- }
- });
-}
-
/**
* \param get_mix_indices_fn: Returns a Span of indices of the source points to mix for every
* result point.
@@ -256,28 +243,29 @@ static void extrude_mesh_vertices(Mesh &mesh,
if (!ELEM(meta_data.domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE)) {
return true;
}
+ if (meta_data.data_type == CD_PROP_STRING) {
+ return true;
+ }
GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span(
id, meta_data.domain, meta_data.data_type);
- attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
- using T = decltype(dummy);
- MutableSpan<T> data = attribute.span.typed<T>();
- switch (attribute.domain) {
- case ATTR_DOMAIN_POINT: {
- /* New vertices copy the attribute values from their source vertex. */
- copy_with_mask(data.slice(new_vert_range), data.as_span(), selection);
- break;
- }
- case ATTR_DOMAIN_EDGE: {
+ switch (attribute.domain) {
+ case ATTR_DOMAIN_POINT:
+ /* New vertices copy the attribute values from their source vertex. */
+ array_utils::gather(attribute.span, selection, attribute.span.slice(new_vert_range));
+ break;
+ case ATTR_DOMAIN_EDGE:
+ attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
+ using T = decltype(dummy);
+ MutableSpan<T> data = attribute.span.typed<T>();
/* New edge values are mixed from of all the edges connected to the source vertex. */
copy_with_mixing(data.slice(new_edge_range), data.as_span(), [&](const int i) {
return vert_to_edge_map[selection[i]].as_span();
});
- break;
- }
- default:
- BLI_assert_unreachable();
- }
- });
+ });
+ break;
+ default:
+ BLI_assert_unreachable();
+ }
attribute.finish();
return true;
@@ -288,7 +276,6 @@ static void extrude_mesh_vertices(Mesh &mesh,
for (const int i : range) {
const float3 offset = offsets[selection[i]];
add_v3_v3(new_verts[i].co, offset);
- new_verts[i].flag = 0;
}
});
});
@@ -296,6 +283,9 @@ static void extrude_mesh_vertices(Mesh &mesh,
MutableSpan<int> vert_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_POINT);
vert_orig_indices.slice(new_vert_range).fill(ORIGINDEX_NONE);
+ MutableSpan<int> new_edge_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_EDGE);
+ new_edge_orig_indices.slice(new_edge_range).fill(ORIGINDEX_NONE);
+
if (attribute_outputs.top_id) {
save_selection_as_attribute(
mesh, attribute_outputs.top_id.get(), ATTR_DOMAIN_POINT, new_vert_range);
@@ -500,6 +490,9 @@ static void extrude_mesh_edges(Mesh &mesh,
MutableAttributeAccessor attributes = mesh.attributes_for_write();
attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
+ if (meta_data.data_type == CD_PROP_STRING) {
+ return true;
+ }
GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span(
id, meta_data.domain, meta_data.data_type);
if (!attribute) {
@@ -512,13 +505,14 @@ static void extrude_mesh_edges(Mesh &mesh,
switch (attribute.domain) {
case ATTR_DOMAIN_POINT: {
/* New vertices copy the attribute values from their source vertex. */
- copy_with_indices(data.slice(new_vert_range), data.as_span(), new_vert_indices);
+ array_utils::gather(
+ data.as_span(), new_vert_indices.as_span(), data.slice(new_vert_range));
break;
}
case ATTR_DOMAIN_EDGE: {
/* Edges parallel to original edges copy the edge attributes from the original edges. */
MutableSpan<T> duplicate_data = data.slice(duplicate_edge_range);
- copy_with_mask(duplicate_data, data.as_span(), edge_selection);
+ array_utils::gather(data.as_span(), edge_selection, duplicate_data);
/* Edges connected to original vertices mix values of selected connected edges. */
MutableSpan<T> connect_data = data.slice(connect_edge_range);
@@ -611,7 +605,6 @@ static void extrude_mesh_edges(Mesh &mesh,
threading::parallel_for(new_verts.index_range(), 1024, [&](const IndexRange range) {
for (const int i : range) {
add_v3_v3(new_verts[i].co, offset);
- new_verts[i].flag = 0;
}
});
}
@@ -619,7 +612,6 @@ static void extrude_mesh_edges(Mesh &mesh,
threading::parallel_for(new_verts.index_range(), 1024, [&](const IndexRange range) {
for (const int i : range) {
add_v3_v3(new_verts[i].co, vert_offsets[new_vert_indices[i]]);
- new_verts[i].flag = 0;
}
});
}
@@ -631,6 +623,9 @@ static void extrude_mesh_edges(Mesh &mesh,
edge_orig_indices.slice(connect_edge_range).fill(ORIGINDEX_NONE);
edge_orig_indices.slice(duplicate_edge_range).fill(ORIGINDEX_NONE);
+ MutableSpan<int> poly_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_FACE);
+ poly_orig_indices.slice(new_poly_range).fill(ORIGINDEX_NONE);
+
if (attribute_outputs.top_id) {
save_selection_as_attribute(
mesh, attribute_outputs.top_id.get(), ATTR_DOMAIN_EDGE, duplicate_edge_range);
@@ -882,6 +877,9 @@ static void extrude_mesh_face_regions(Mesh &mesh,
MutableAttributeAccessor attributes = mesh.attributes_for_write();
attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
+ if (meta_data.data_type == CD_PROP_STRING) {
+ return true;
+ }
GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span(
id, meta_data.domain, meta_data.data_type);
if (!attribute) {
@@ -894,17 +892,18 @@ static void extrude_mesh_face_regions(Mesh &mesh,
switch (attribute.domain) {
case ATTR_DOMAIN_POINT: {
/* New vertices copy the attributes from their original vertices. */
- copy_with_indices(data.slice(new_vert_range), data.as_span(), new_vert_indices);
+ array_utils::gather(
+ data.as_span(), new_vert_indices.as_span(), data.slice(new_vert_range));
break;
}
case ATTR_DOMAIN_EDGE: {
/* Edges parallel to original edges copy the edge attributes from the original edges. */
MutableSpan<T> boundary_data = data.slice(boundary_edge_range);
- copy_with_indices(boundary_data, data.as_span(), boundary_edge_indices);
+ array_utils::gather(data.as_span(), boundary_edge_indices.as_span(), boundary_data);
/* Edges inside of face regions also just duplicate their source data. */
MutableSpan<T> new_inner_data = data.slice(new_inner_edge_range);
- copy_with_indices(new_inner_data, data.as_span(), new_inner_edge_indices);
+ array_utils::gather(data.as_span(), new_inner_edge_indices.as_span(), new_inner_data);
/* Edges connected to original vertices mix values of selected connected edges. */
MutableSpan<T> connect_data = data.slice(connect_edge_range);
@@ -916,8 +915,8 @@ static void extrude_mesh_face_regions(Mesh &mesh,
case ATTR_DOMAIN_FACE: {
/* New faces on the side of extrusions get the values from the corresponding selected
* face. */
- copy_with_indices(
- data.slice(side_poly_range), data.as_span(), edge_extruded_face_indices);
+ array_utils::gather(
+ data.as_span(), edge_extruded_face_indices.as_span(), data.slice(side_poly_range));
break;
}
case ATTR_DOMAIN_CORNER: {
@@ -1001,10 +1000,6 @@ static void extrude_mesh_face_regions(Mesh &mesh,
});
}
- for (MVert &vert : verts.slice(new_vert_range)) {
- vert.flag = 0;
- }
-
MutableSpan<int> vert_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_POINT);
vert_orig_indices.slice(new_vert_range).fill(ORIGINDEX_NONE);
@@ -1140,6 +1135,9 @@ static void extrude_individual_mesh_faces(Mesh &mesh,
MutableAttributeAccessor attributes = mesh.attributes_for_write();
attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
+ if (meta_data.data_type == CD_PROP_STRING) {
+ return true;
+ }
GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span(
id, meta_data.domain, meta_data.data_type);
if (!attribute) {
@@ -1262,7 +1260,6 @@ static void extrude_individual_mesh_faces(Mesh &mesh,
const IndexRange poly_corner_range = selected_corner_range(index_offsets, i_selection);
for (MVert &vert : new_verts.slice(poly_corner_range)) {
add_v3_v3(vert.co, poly_offset[poly_selection[i_selection]]);
- vert.flag = 0;
}
}
});
@@ -1314,7 +1311,7 @@ static void node_geo_exec(GeoNodeExecParams params)
Field<float3> offset_field = params.extract_input<Field<float3>>("Offset");
Field<float> scale_field = params.extract_input<Field<float>>("Offset Scale");
const NodeGeometryExtrudeMesh &storage = node_storage(params.node());
- GeometryNodeExtrudeMeshMode mode = static_cast<GeometryNodeExtrudeMeshMode>(storage.mode);
+ GeometryNodeExtrudeMeshMode mode = GeometryNodeExtrudeMeshMode(storage.mode);
/* Create a combined field from the offset and the scale so the field evaluator
* can take care of the multiplication and to simplify each extrude function. */
@@ -1383,8 +1380,8 @@ void register_node_type_geo_extrude_mesh()
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_EXTRUDE_MESH, "Extrude Mesh", NODE_CLASS_GEOMETRY);
ntype.declare = file_ns::node_declare;
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
ntype.geometry_node_execute = file_ns::node_geo_exec;
node_type_storage(
&ntype, "NodeGeometryExtrudeMesh", node_free_standard_storage, node_copy_standard_storage);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc b/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc
index c8df5785fed..fc1e2cb2503 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc
@@ -11,6 +11,63 @@
#include "NOD_socket_search_link.hh"
+namespace blender::nodes {
+
+FieldAtIndexInput::FieldAtIndexInput(Field<int> index_field,
+ GField value_field,
+ eAttrDomain value_field_domain)
+ : bke::GeometryFieldInput(value_field.cpp_type(), "Field at Index"),
+ index_field_(std::move(index_field)),
+ value_field_(std::move(value_field)),
+ value_field_domain_(value_field_domain)
+{
+}
+
+GVArray FieldAtIndexInput::get_varray_for_context(const bke::GeometryFieldContext &context,
+ const IndexMask mask) const
+{
+ const std::optional<AttributeAccessor> attributes = context.attributes();
+ if (!attributes) {
+ return {};
+ }
+
+ const bke::GeometryFieldContext value_field_context{
+ context.geometry(), context.type(), value_field_domain_};
+ FieldEvaluator value_evaluator{value_field_context,
+ attributes->domain_size(value_field_domain_)};
+ value_evaluator.add(value_field_);
+ value_evaluator.evaluate();
+ const GVArray &values = value_evaluator.get_evaluated(0);
+
+ FieldEvaluator index_evaluator{context, &mask};
+ index_evaluator.add(index_field_);
+ index_evaluator.evaluate();
+ const VArray<int> indices = index_evaluator.get_evaluated<int>(0);
+
+ GVArray output_array;
+ attribute_math::convert_to_static_type(*type_, [&](auto dummy) {
+ using T = decltype(dummy);
+ Array<T> dst_array(mask.min_array_size());
+ VArray<T> src_values = values.typed<T>();
+ threading::parallel_for(mask.index_range(), 1024, [&](const IndexRange range) {
+ for (const int i : mask.slice(range)) {
+ const int index = indices[i];
+ if (src_values.index_range().contains(index)) {
+ dst_array[i] = src_values[index];
+ }
+ else {
+ dst_array[i] = {};
+ }
+ }
+ });
+ output_array = VArray<T>::ForContainer(std::move(dst_array));
+ });
+
+ return output_array;
+}
+
+} // namespace blender::nodes
+
namespace blender::nodes::node_geo_field_at_index_cc {
static void node_declare(NodeDeclarationBuilder &b)
@@ -30,13 +87,13 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Bool>(N_("Value"), "Value_Bool").field_source();
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
node->custom1 = ATTR_DOMAIN_POINT;
node->custom2 = CD_PROP_FLOAT;
@@ -44,7 +101,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
- const eCustomDataType data_type = static_cast<eCustomDataType>(node->custom2);
+ const eCustomDataType data_type = eCustomDataType(node->custom2);
bNodeSocket *sock_index = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *sock_in_float = sock_index->next;
@@ -89,60 +146,6 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
}
}
-class FieldAtIndex final : public bke::GeometryFieldInput {
- private:
- Field<int> index_field_;
- GField value_field_;
- eAttrDomain value_field_domain_;
-
- public:
- FieldAtIndex(Field<int> index_field, GField value_field, eAttrDomain value_field_domain)
- : bke::GeometryFieldInput(value_field.cpp_type(), "Field at Index"),
- index_field_(std::move(index_field)),
- value_field_(std::move(value_field)),
- value_field_domain_(value_field_domain)
- {
- }
-
- GVArray get_varray_for_context(const bke::GeometryFieldContext &context,
- const IndexMask mask) const final
- {
- const bke::GeometryFieldContext value_field_context{
- context.geometry(), context.type(), value_field_domain_};
- FieldEvaluator value_evaluator{value_field_context,
- context.attributes()->domain_size(value_field_domain_)};
- value_evaluator.add(value_field_);
- value_evaluator.evaluate();
- const GVArray &values = value_evaluator.get_evaluated(0);
-
- FieldEvaluator index_evaluator{context, &mask};
- index_evaluator.add(index_field_);
- index_evaluator.evaluate();
- const VArray<int> indices = index_evaluator.get_evaluated<int>(0);
-
- GVArray output_array;
- attribute_math::convert_to_static_type(*type_, [&](auto dummy) {
- using T = decltype(dummy);
- Array<T> dst_array(mask.min_array_size());
- VArray<T> src_values = values.typed<T>();
- threading::parallel_for(mask.index_range(), 1024, [&](const IndexRange range) {
- for (const int i : mask.slice(range)) {
- const int index = indices[i];
- if (index >= 0 && index < src_values.size()) {
- dst_array[i] = src_values[index];
- }
- else {
- dst_array[i] = {};
- }
- }
- });
- output_array = VArray<T>::ForContainer(std::move(dst_array));
- });
-
- return output_array;
- }
-};
-
static StringRefNull identifier_suffix(eCustomDataType data_type)
{
switch (data_type) {
@@ -165,16 +168,16 @@ static StringRefNull identifier_suffix(eCustomDataType data_type)
static void node_geo_exec(GeoNodeExecParams params)
{
const bNode &node = params.node();
- const eAttrDomain domain = static_cast<eAttrDomain>(node.custom1);
- const eCustomDataType data_type = static_cast<eCustomDataType>(node.custom2);
+ const eAttrDomain domain = eAttrDomain(node.custom1);
+ const eCustomDataType data_type = eCustomDataType(node.custom2);
Field<int> index_field = params.extract_input<Field<int>>("Index");
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
static const std::string identifier = "Value_" + identifier_suffix(data_type);
Field<T> value_field = params.extract_input<Field<T>>(identifier);
- Field<T> output_field{
- std::make_shared<FieldAtIndex>(std::move(index_field), std::move(value_field), domain)};
+ Field<T> output_field{std::make_shared<FieldAtIndexInput>(
+ std::move(index_field), std::move(value_field), domain)};
params.set_output(identifier, std::move(output_field));
});
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc
index 613425716d4..95a0013a9e1 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc
@@ -47,6 +47,9 @@ static void mesh_flip_faces(Mesh &mesh, const Field<bool> &selection_field)
MutableAttributeAccessor attributes = mesh.attributes_for_write();
attributes.for_all(
[&](const bke::AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
+ if (meta_data.data_type == CD_PROP_STRING) {
+ return true;
+ }
if (meta_data.domain == ATTR_DOMAIN_CORNER) {
GSpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span(
attribute_id, ATTR_DOMAIN_CORNER, meta_data.data_type);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_geometry_to_instance.cc b/source/blender/nodes/geometry/nodes/node_geo_geometry_to_instance.cc
index 8e64209a418..45808ff9996 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_geometry_to_instance.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_geometry_to_instance.cc
@@ -1,5 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "BKE_instances.hh"
+
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_geometry_to_instance_cc {
@@ -13,15 +15,13 @@ static void node_declare(NodeDeclarationBuilder &b)
static void node_geo_exec(GeoNodeExecParams params)
{
Vector<GeometrySet> geometries = params.extract_input<Vector<GeometrySet>>("Geometry");
- GeometrySet instances_geometry;
- InstancesComponent &instances_component =
- instances_geometry.get_component_for_write<InstancesComponent>();
+ std::unique_ptr<bke::Instances> instances = std::make_unique<bke::Instances>();
for (GeometrySet &geometry : geometries) {
geometry.ensure_owns_direct_data();
- const int handle = instances_component.add_reference(std::move(geometry));
- instances_component.add_instance(handle, float4x4::identity());
+ const int handle = instances->add_reference(std::move(geometry));
+ instances->add_instance(handle, float4x4::identity());
}
- params.set_output("Instances", std::move(instances_geometry));
+ params.set_output("Instances", GeometrySet::create_with_instances(instances.release()));
}
} // namespace blender::nodes::node_geo_geometry_to_instance_cc
diff --git a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc
index 33802d00d2b..0d339620047 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc
@@ -24,20 +24,20 @@ static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Image>(N_("Image")).hide_label();
b.add_input<decl::Vector>(N_("Vector"))
- .implicit_field()
- .description(("Texture coordinates from 0 to 1"));
+ .implicit_field(implicit_field_inputs::position)
+ .description("Texture coordinates from 0 to 1");
b.add_input<decl::Int>(N_("Frame")).min(0).max(MAXFRAMEF);
b.add_output<decl::Color>(N_("Color")).no_muted_links().dependent_field();
b.add_output<decl::Float>(N_("Alpha")).no_muted_links().dependent_field();
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "interpolation", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
uiItemR(layout, ptr, "extension", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryImageTexture *tex = MEM_cnew<NodeGeometryImageTexture>(__func__);
node->storage = tex;
@@ -122,9 +122,9 @@ class ImageFieldsFunction : public fn::MultiFunction {
static float frac(const float x, int *ix)
{
- const int i = (int)x - ((x < 0.0f) ? 1 : 0);
+ const int i = int(x) - ((x < 0.0f) ? 1 : 0);
*ix = i;
- return x - (float)i;
+ return x - float(i);
}
static float4 image_cubic_texture_lookup(const ImBuf *ibuf,
@@ -135,8 +135,8 @@ class ImageFieldsFunction : public fn::MultiFunction {
const int width = ibuf->x;
const int height = ibuf->y;
int pix, piy, nix, niy;
- const float tx = frac(px * (float)width - 0.5f, &pix);
- const float ty = frac(py * (float)height - 0.5f, &piy);
+ const float tx = frac(px * float(width) - 0.5f, &pix);
+ const float ty = frac(py * float(height) - 0.5f, &piy);
int ppix, ppiy, nnix, nniy;
switch (extension) {
@@ -189,22 +189,22 @@ class ImageFieldsFunction : public fn::MultiFunction {
v[2] = ((-0.5f * ty + 0.5f) * ty + 0.5f) * ty + (1.0f / 6.0f);
v[3] = (1.0f / 6.0f) * ty * ty * ty;
- return (v[0] * (u[0] * (image_pixel_lookup(ibuf, xc[0], yc[0])) +
- u[1] * (image_pixel_lookup(ibuf, xc[1], yc[0])) +
- u[2] * (image_pixel_lookup(ibuf, xc[2], yc[0])) +
- u[3] * (image_pixel_lookup(ibuf, xc[3], yc[0])))) +
- (v[1] * (u[0] * (image_pixel_lookup(ibuf, xc[0], yc[1])) +
- u[1] * (image_pixel_lookup(ibuf, xc[1], yc[1])) +
- u[2] * (image_pixel_lookup(ibuf, xc[2], yc[1])) +
- u[3] * (image_pixel_lookup(ibuf, xc[3], yc[1])))) +
- (v[2] * (u[0] * (image_pixel_lookup(ibuf, xc[0], yc[2])) +
- u[1] * (image_pixel_lookup(ibuf, xc[1], yc[2])) +
- u[2] * (image_pixel_lookup(ibuf, xc[2], yc[2])) +
- u[3] * (image_pixel_lookup(ibuf, xc[3], yc[2])))) +
- (v[3] * (u[0] * (image_pixel_lookup(ibuf, xc[0], yc[3])) +
- u[1] * (image_pixel_lookup(ibuf, xc[1], yc[3])) +
- u[2] * (image_pixel_lookup(ibuf, xc[2], yc[3])) +
- u[3] * (image_pixel_lookup(ibuf, xc[3], yc[3]))));
+ return (v[0] * (u[0] * image_pixel_lookup(ibuf, xc[0], yc[0]) +
+ u[1] * image_pixel_lookup(ibuf, xc[1], yc[0]) +
+ u[2] * image_pixel_lookup(ibuf, xc[2], yc[0]) +
+ u[3] * image_pixel_lookup(ibuf, xc[3], yc[0]))) +
+ (v[1] * (u[0] * image_pixel_lookup(ibuf, xc[0], yc[1]) +
+ u[1] * image_pixel_lookup(ibuf, xc[1], yc[1]) +
+ u[2] * image_pixel_lookup(ibuf, xc[2], yc[1]) +
+ u[3] * image_pixel_lookup(ibuf, xc[3], yc[1]))) +
+ (v[2] * (u[0] * image_pixel_lookup(ibuf, xc[0], yc[2]) +
+ u[1] * image_pixel_lookup(ibuf, xc[1], yc[2]) +
+ u[2] * image_pixel_lookup(ibuf, xc[2], yc[2]) +
+ u[3] * image_pixel_lookup(ibuf, xc[3], yc[2]))) +
+ (v[3] * (u[0] * image_pixel_lookup(ibuf, xc[0], yc[3]) +
+ u[1] * image_pixel_lookup(ibuf, xc[1], yc[3]) +
+ u[2] * image_pixel_lookup(ibuf, xc[2], yc[3]) +
+ u[3] * image_pixel_lookup(ibuf, xc[3], yc[3])));
}
static float4 image_linear_texture_lookup(const ImBuf *ibuf,
@@ -215,8 +215,8 @@ class ImageFieldsFunction : public fn::MultiFunction {
const int width = ibuf->x;
const int height = ibuf->y;
int pix, piy, nix, niy;
- const float nfx = frac(px * (float)width - 0.5f, &pix);
- const float nfy = frac(py * (float)height - 0.5f, &piy);
+ const float nfx = frac(px * float(width) - 0.5f, &pix);
+ const float nfy = frac(py * float(height) - 0.5f, &piy);
switch (extension) {
case SHD_IMAGE_EXTENSION_CLIP: {
@@ -257,8 +257,8 @@ class ImageFieldsFunction : public fn::MultiFunction {
const int width = ibuf->x;
const int height = ibuf->y;
int ix, iy;
- const float tx = frac(px * (float)width, &ix);
- const float ty = frac(py * (float)height, &iy);
+ const float tx = frac(px * float(width), &ix);
+ const float ty = frac(py * float(height), &iy);
switch (extension) {
case SHD_IMAGE_EXTENSION_REPEAT: {
@@ -285,14 +285,14 @@ class ImageFieldsFunction : public fn::MultiFunction {
}
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<float3> &vectors = params.readonly_single_input<float3>(0, "Vector");
MutableSpan<ColorGeometry4f> r_color = params.uninitialized_single_output<ColorGeometry4f>(
1, "Color");
MutableSpan<float> r_alpha = params.uninitialized_single_output_if_required<float>(2, "Alpha");
- MutableSpan<float4> color_data{(float4 *)r_color.data(), r_color.size()};
+ MutableSpan<float4> color_data{reinterpret_cast<float4 *>(r_color.data()), r_color.size()};
/* Sample image texture. */
switch (interpolation_) {
@@ -402,7 +402,7 @@ void register_node_type_geo_image_texture()
geo_node_type_base(&ntype, GEO_NODE_IMAGE_TEXTURE, "Image Texture", NODE_CLASS_TEXTURE);
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_layout;
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
node_type_storage(
&ntype, "NodeGeometryImageTexture", node_free_standard_storage, node_copy_standard_storage);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc
index bff2e7831c6..2979d0e4639 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc
@@ -84,6 +84,11 @@ class HandlePositionFieldInput final : public bke::CurvesFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const CurvesGeometry & /*curves*/) const
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_instance_rotation.cc b/source/blender/nodes/geometry/nodes/node_geo_input_instance_rotation.cc
index 8c5a92904ab..f78815ebe74 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_instance_rotation.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_instance_rotation.cc
@@ -2,6 +2,8 @@
#include "node_geometry_util.hh"
+#include "BKE_instances.hh"
+
namespace blender::nodes::node_geo_input_instance_rotation_cc {
static void node_declare(NodeDeclarationBuilder &b)
@@ -15,12 +17,9 @@ class InstanceRotationFieldInput final : public bke::InstancesFieldInput {
{
}
- GVArray get_varray_for_context(const InstancesComponent &instances,
- IndexMask UNUSED(mask)) const final
+ GVArray get_varray_for_context(const bke::Instances &instances, IndexMask /*mask*/) const final
{
- auto rotation_fn = [&](const int i) -> float3 {
- return instances.instance_transforms()[i].to_euler();
- };
+ auto rotation_fn = [&](const int i) -> float3 { return instances.transforms()[i].to_euler(); };
return VArray<float3>::ForFunc(instances.instances_num(), rotation_fn);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_instance_scale.cc b/source/blender/nodes/geometry/nodes/node_geo_input_instance_scale.cc
index b79e73915b7..12ac48f8f11 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_instance_scale.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_instance_scale.cc
@@ -2,6 +2,8 @@
#include "node_geometry_util.hh"
+#include "BKE_instances.hh"
+
namespace blender::nodes::node_geo_input_instance_scale_cc {
static void node_declare(NodeDeclarationBuilder &b)
@@ -15,12 +17,9 @@ class InstanceScaleFieldInput final : public bke::InstancesFieldInput {
{
}
- GVArray get_varray_for_context(const InstancesComponent &instances,
- IndexMask UNUSED(mask)) const final
+ GVArray get_varray_for_context(const bke::Instances &instances, IndexMask /*mask*/) const final
{
- auto scale_fn = [&](const int i) -> float3 {
- return instances.instance_transforms()[i].scale();
- };
+ auto scale_fn = [&](const int i) -> float3 { return instances.transforms()[i].scale(); };
return VArray<float3>::ForFunc(instances.instances_num(), scale_fn);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_material.cc b/source/blender/nodes/geometry/nodes/node_geo_input_material.cc
index 19882c4966d..943193a0d82 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_material.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_material.cc
@@ -12,14 +12,14 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Material>(N_("Material"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "material", 0, "", ICON_NONE);
}
static void node_geo_exec(GeoNodeExecParams params)
{
- Material *material = (Material *)params.node().id;
+ Material *material = reinterpret_cast<Material *>(params.node().id);
params.set_output("Material", material);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc
index f2e7379b3a2..29730ab8dc4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc
@@ -62,7 +62,7 @@ class AngleFieldInput final : public bke::MeshFieldInput {
GVArray get_varray_for_context(const Mesh &mesh,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const final
+ const IndexMask /*mask*/) const final
{
const Span<MVert> verts = mesh.verts();
const Span<MPoly> polys = mesh.polys();
@@ -95,6 +95,11 @@ class AngleFieldInput final : public bke::MeshFieldInput {
{
return dynamic_cast<const AngleFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_EDGE;
+ }
};
class SignedAngleFieldInput final : public bke::MeshFieldInput {
@@ -106,7 +111,7 @@ class SignedAngleFieldInput final : public bke::MeshFieldInput {
GVArray get_varray_for_context(const Mesh &mesh,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const final
+ const IndexMask /*mask*/) const final
{
const Span<MVert> verts = mesh.verts();
const Span<MEdge> edges = mesh.edges();
@@ -162,6 +167,11 @@ class SignedAngleFieldInput final : public bke::MeshFieldInput {
{
return dynamic_cast<const SignedAngleFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_EDGE;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc
index bfe8753c039..97c950988e7 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc
@@ -26,7 +26,7 @@ class EdgeNeighborCountFieldInput final : public bke::MeshFieldInput {
GVArray get_varray_for_context(const Mesh &mesh,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const final
+ const IndexMask /*mask*/) const final
{
const Span<MLoop> loops = mesh.loops();
Array<int> face_count(mesh.totedge, 0);
@@ -48,6 +48,11 @@ class EdgeNeighborCountFieldInput final : public bke::MeshFieldInput {
{
return dynamic_cast<const EdgeNeighborCountFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_EDGE;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc
index c8ceae239a4..513ddd76055 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc
@@ -25,15 +25,15 @@ static void node_declare(NodeDeclarationBuilder &b)
.description(N_("The position of the second vertex in the edge"));
}
-enum VertexNumber { VERTEX_ONE, VERTEX_TWO };
+enum class VertNumber { V1, V2 };
static VArray<int> construct_edge_verts_gvarray(const Mesh &mesh,
- const VertexNumber vertex,
+ const VertNumber vertex,
const eAttrDomain domain)
{
const Span<MEdge> edges = mesh.edges();
if (domain == ATTR_DOMAIN_EDGE) {
- if (vertex == VERTEX_ONE) {
+ if (vertex == VertNumber::V1) {
return VArray<int>::ForFunc(edges.size(),
[edges](const int i) -> int { return edges[i].v1; });
}
@@ -42,12 +42,12 @@ static VArray<int> construct_edge_verts_gvarray(const Mesh &mesh,
return {};
}
-class EdgeVerticesFieldInput final : public bke::MeshFieldInput {
+class EdgeVertsInput final : public bke::MeshFieldInput {
private:
- VertexNumber vertex_;
+ VertNumber vertex_;
public:
- EdgeVerticesFieldInput(VertexNumber vertex)
+ EdgeVertsInput(VertNumber vertex)
: bke::MeshFieldInput(CPPType::get<int>(), "Edge Vertices Field"), vertex_(vertex)
{
category_ = Category::Generated;
@@ -55,34 +55,38 @@ class EdgeVerticesFieldInput final : public bke::MeshFieldInput {
GVArray get_varray_for_context(const Mesh &mesh,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const final
+ const IndexMask /*mask*/) const final
{
return construct_edge_verts_gvarray(mesh, vertex_, domain);
}
uint64_t hash() const override
{
- return vertex_ == VERTEX_ONE ? 23847562893465 : 92384598734567;
+ return vertex_ == VertNumber::V1 ? 23847562893465 : 92384598734567;
}
bool is_equal_to(const fn::FieldNode &other) const override
{
- if (const EdgeVerticesFieldInput *other_field = dynamic_cast<const EdgeVerticesFieldInput *>(
- &other)) {
+ if (const EdgeVertsInput *other_field = dynamic_cast<const EdgeVertsInput *>(&other)) {
return vertex_ == other_field->vertex_;
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_EDGE;
+ }
};
static VArray<float3> construct_edge_positions_gvarray(const Mesh &mesh,
- const VertexNumber vertex,
+ const VertNumber vertex,
const eAttrDomain domain)
{
const Span<MVert> verts = mesh.verts();
const Span<MEdge> edges = mesh.edges();
- if (vertex == VERTEX_ONE) {
+ if (vertex == VertNumber::V1) {
return mesh.attributes().adapt_domain<float3>(
VArray<float3>::ForFunc(edges.size(),
[verts, edges](const int i) { return verts[edges[i].v1].co; }),
@@ -98,10 +102,10 @@ static VArray<float3> construct_edge_positions_gvarray(const Mesh &mesh,
class EdgePositionFieldInput final : public bke::MeshFieldInput {
private:
- VertexNumber vertex_;
+ VertNumber vertex_;
public:
- EdgePositionFieldInput(VertexNumber vertex)
+ EdgePositionFieldInput(VertNumber vertex)
: bke::MeshFieldInput(CPPType::get<float3>(), "Edge Position Field"), vertex_(vertex)
{
category_ = Category::Generated;
@@ -109,14 +113,14 @@ class EdgePositionFieldInput final : public bke::MeshFieldInput {
GVArray get_varray_for_context(const Mesh &mesh,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const final
+ IndexMask /*mask*/) const final
{
return construct_edge_positions_gvarray(mesh, vertex_, domain);
}
uint64_t hash() const override
{
- return vertex_ == VERTEX_ONE ? 987456978362 : 374587679866;
+ return vertex_ == VertNumber::V1 ? 987456978362 : 374587679866;
}
bool is_equal_to(const fn::FieldNode &other) const override
@@ -127,14 +131,19 @@ class EdgePositionFieldInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_EDGE;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
{
- Field<int> vertex_field_1{std::make_shared<EdgeVerticesFieldInput>(VERTEX_ONE)};
- Field<int> vertex_field_2{std::make_shared<EdgeVerticesFieldInput>(VERTEX_TWO)};
- Field<float3> position_field_1{std::make_shared<EdgePositionFieldInput>(VERTEX_ONE)};
- Field<float3> position_field_2{std::make_shared<EdgePositionFieldInput>(VERTEX_TWO)};
+ Field<int> vertex_field_1{std::make_shared<EdgeVertsInput>(VertNumber::V1)};
+ Field<int> vertex_field_2{std::make_shared<EdgeVertsInput>(VertNumber::V2)};
+ Field<float3> position_field_1{std::make_shared<EdgePositionFieldInput>(VertNumber::V1)};
+ Field<float3> position_field_2{std::make_shared<EdgePositionFieldInput>(VertNumber::V2)};
params.set_output("Vertex Index 1", std::move(vertex_field_1));
params.set_output("Vertex Index 2", std::move(vertex_field_2));
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc
index be921c1f1c5..aec1c27a4fc 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc
@@ -40,7 +40,7 @@ class FaceAreaFieldInput final : public bke::MeshFieldInput {
GVArray get_varray_for_context(const Mesh &mesh,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const final
+ const IndexMask /*mask*/) const final
{
return construct_face_area_varray(mesh, domain);
}
@@ -55,6 +55,11 @@ class FaceAreaFieldInput final : public bke::MeshFieldInput {
{
return dynamic_cast<const FaceAreaFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_FACE;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc
index 72c45de7b0f..7b084995fc3 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc
@@ -40,7 +40,8 @@ class PlanarFieldInput final : public bke::MeshFieldInput {
const Span<MVert> verts = mesh.verts();
const Span<MPoly> polys = mesh.polys();
const Span<MLoop> loops = mesh.loops();
- const Span<float3> poly_normals{(float3 *)BKE_mesh_poly_normals_ensure(&mesh), mesh.totpoly};
+ const Span<float3> poly_normals{
+ reinterpret_cast<const float3 *>(BKE_mesh_poly_normals_ensure(&mesh)), mesh.totpoly};
bke::MeshFieldContext context{mesh, ATTR_DOMAIN_FACE};
fn::FieldEvaluator evaluator{context, polys.size()};
@@ -86,6 +87,11 @@ class PlanarFieldInput final : public bke::MeshFieldInput {
{
return dynamic_cast<const PlanarFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_FACE;
+ }
};
static void geo_node_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc
index 9e85eae3a31..f1724ef4a41 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc
@@ -51,7 +51,7 @@ class FaceNeighborCountFieldInput final : public bke::MeshFieldInput {
GVArray get_varray_for_context(const Mesh &mesh,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const final
+ const IndexMask /*mask*/) const final
{
return construct_neighbor_count_varray(mesh, domain);
}
@@ -66,6 +66,11 @@ class FaceNeighborCountFieldInput final : public bke::MeshFieldInput {
{
return dynamic_cast<const FaceNeighborCountFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_FACE;
+ }
};
static VArray<int> construct_vertex_count_varray(const Mesh &mesh, const eAttrDomain domain)
@@ -87,7 +92,7 @@ class FaceVertexCountFieldInput final : public bke::MeshFieldInput {
GVArray get_varray_for_context(const Mesh &mesh,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const final
+ const IndexMask /*mask*/) const final
{
return construct_vertex_count_varray(mesh, domain);
}
@@ -102,6 +107,11 @@ class FaceVertexCountFieldInput final : public bke::MeshFieldInput {
{
return dynamic_cast<const FaceVertexCountFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_FACE;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc
index 9d7735e707d..6b54828b042 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc
@@ -31,7 +31,7 @@ class IslandFieldInput final : public bke::MeshFieldInput {
GVArray get_varray_for_context(const Mesh &mesh,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const final
+ const IndexMask /*mask*/) const final
{
const Span<MEdge> edges = mesh.edges();
@@ -61,6 +61,11 @@ class IslandFieldInput final : public bke::MeshFieldInput {
{
return dynamic_cast<const IslandFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
class IslandCountFieldInput final : public bke::MeshFieldInput {
@@ -72,7 +77,7 @@ class IslandCountFieldInput final : public bke::MeshFieldInput {
GVArray get_varray_for_context(const Mesh &mesh,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const final
+ const IndexMask /*mask*/) const final
{
const Span<MEdge> edges = mesh.edges();
@@ -100,6 +105,11 @@ class IslandCountFieldInput final : public bke::MeshFieldInput {
{
return dynamic_cast<const IslandCountFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc
index ab44a6c8515..5b1b32c7b9c 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc
@@ -43,7 +43,7 @@ class VertexCountFieldInput final : public bke::MeshFieldInput {
GVArray get_varray_for_context(const Mesh &mesh,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const final
+ const IndexMask /*mask*/) const final
{
return construct_vertex_count_gvarray(mesh, domain);
}
@@ -58,6 +58,11 @@ class VertexCountFieldInput final : public bke::MeshFieldInput {
{
return dynamic_cast<const VertexCountFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
static VArray<int> construct_face_count_gvarray(const Mesh &mesh, const eAttrDomain domain)
@@ -83,7 +88,7 @@ class VertexFaceCountFieldInput final : public bke::MeshFieldInput {
GVArray get_varray_for_context(const Mesh &mesh,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const final
+ const IndexMask /*mask*/) const final
{
return construct_face_count_gvarray(mesh, domain);
}
@@ -98,6 +103,11 @@ class VertexFaceCountFieldInput final : public bke::MeshFieldInput {
{
return dynamic_cast<const VertexFaceCountFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc
index da09d3650e3..9d1f90ba0f3 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc
@@ -22,12 +22,12 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Int>(N_("Attribute"), "Attribute_Int").field_source();
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryInputNamedAttribute *data = MEM_cnew<NodeGeometryInputNamedAttribute>(__func__);
data->data_type = CD_PROP_FLOAT;
@@ -37,9 +37,9 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryInputNamedAttribute &storage = node_storage(*node);
- const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
+ const eCustomDataType data_type = eCustomDataType(storage.data_type);
- bNodeSocket *socket_vector = (bNodeSocket *)node->outputs.first;
+ bNodeSocket *socket_vector = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *socket_float = socket_vector->next;
bNodeSocket *socket_color4f = socket_float->next;
bNodeSocket *socket_boolean = socket_color4f->next;
@@ -59,7 +59,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
if (params.in_out() == SOCK_OUT) {
const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type(
- static_cast<eNodeSocketDatatype>(params.other_socket().type));
+ eNodeSocketDatatype(params.other_socket().type));
if (type && *type != CD_PROP_STRING) {
/* The input and output sockets have the same name. */
params.add_item(IFACE_("Attribute"), [type](LinkSearchOpParams &params) {
@@ -74,7 +74,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
static void node_geo_exec(GeoNodeExecParams params)
{
const NodeGeometryInputNamedAttribute &storage = node_storage(params.node());
- const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
+ const eCustomDataType data_type = eCustomDataType(storage.data_type);
const std::string name = params.extract_input<std::string>("Name");
@@ -126,7 +126,7 @@ void register_node_type_geo_input_named_attribute()
ntype.draw_buttons = file_ns::node_layout;
ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
ntype.updatefunc = file_ns::node_update;
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
node_type_storage(&ntype,
"NodeGeometryInputNamedAttribute",
node_free_standard_storage,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_scene_time.cc b/source/blender/nodes/geometry/nodes/node_geo_input_scene_time.cc
index 0222ccbbd02..74d10c286a0 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_scene_time.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_scene_time.cc
@@ -18,7 +18,7 @@ static void node_exec(GeoNodeExecParams params)
{
const Scene *scene = DEG_get_input_scene(params.depsgraph());
const float scene_ctime = BKE_scene_ctime_get(scene);
- const double frame_rate = (((double)scene->r.frs_sec) / (double)scene->r.frs_sec_base);
+ const double frame_rate = (double(scene->r.frs_sec) / double(scene->r.frs_sec_base));
params.set_output("Seconds", float(scene_ctime / frame_rate));
params.set_output("Frame", scene_ctime);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc b/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc
index a54daabde3b..00c92e30443 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc
@@ -143,6 +143,11 @@ class ShortestEdgePathsNextVertFieldInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
class ShortestEdgePathsCostFieldInput final : public bke::MeshFieldInput {
@@ -206,6 +211,11 @@ class ShortestEdgePathsCostFieldInput final : public bke::MeshFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc
index 07dc158ff48..5a42949d4c8 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc
@@ -41,7 +41,7 @@ class SplineCountFieldInput final : public bke::CurvesFieldInput {
GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const final
+ const IndexMask /*mask*/) const final
{
return construct_curve_point_count_gvarray(curves, domain);
}
@@ -56,6 +56,11 @@ class SplineCountFieldInput final : public bke::CurvesFieldInput {
{
return dynamic_cast<const SplineCountFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/) const final
+ {
+ return ATTR_DOMAIN_CURVE;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
index ea3d060f03c..aa27fa70e64 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
@@ -95,7 +95,7 @@ class TangentFieldInput final : public bke::CurvesFieldInput {
GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const final
+ const IndexMask /*mask*/) const final
{
return construct_curve_tangent_gvarray(curves, domain);
}
@@ -110,6 +110,11 @@ class TangentFieldInput final : public bke::CurvesFieldInput {
{
return dynamic_cast<const TangentFieldInput *>(&other) != nullptr;
}
+
+ std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
index d54d082311f..64546684186 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
@@ -2,6 +2,7 @@
#include "DNA_collection_types.h"
+#include "BLI_array_utils.hh"
#include "BLI_hash.h"
#include "BLI_task.hh"
@@ -9,6 +10,7 @@
#include "UI_resources.h"
#include "BKE_attribute_math.hh"
+#include "BKE_instances.hh"
#include "node_geometry_util.hh"
@@ -25,7 +27,7 @@ static void node_declare(NodeDeclarationBuilder &b)
.description(N_("Choose instances from the \"Instance\" input at each point instead of "
"instancing the entire geometry"));
b.add_input<decl::Int>(N_("Instance Index"))
- .implicit_field()
+ .implicit_field(implicit_field_inputs::id_or_index)
.description(N_(
"Index of the instance that used for each point. This is only used when Pick Instances "
"is on. By default the point index is used"));
@@ -43,7 +45,7 @@ static void node_declare(NodeDeclarationBuilder &b)
}
static void add_instances_from_component(
- InstancesComponent &dst_component,
+ bke::Instances &dst_component,
const GeometryComponent &src_component,
const GeometrySet &instance,
const GeoNodeExecParams &params,
@@ -80,25 +82,23 @@ static void add_instances_from_component(
const int select_len = selection.index_range().size();
dst_component.resize(start_len + select_len);
- MutableSpan<int> dst_handles = dst_component.instance_reference_handles().slice(start_len,
- select_len);
- MutableSpan<float4x4> dst_transforms = dst_component.instance_transforms().slice(start_len,
- select_len);
+ MutableSpan<int> dst_handles = dst_component.reference_handles().slice(start_len, select_len);
+ MutableSpan<float4x4> dst_transforms = dst_component.transforms().slice(start_len, select_len);
VArray<float3> positions = src_component.attributes()->lookup_or_default<float3>(
"position", domain, {0, 0, 0});
- const InstancesComponent *src_instances = instance.get_component_for_read<InstancesComponent>();
+ const bke::Instances *src_instances = instance.get_instances_for_read();
/* Maps handles from the source instances to handles on the new instance. */
Array<int> handle_mapping;
/* Only fill #handle_mapping when it may be used below. */
if (src_instances != nullptr &&
(!pick_instance.is_single() || pick_instance.get_internal_single())) {
- Span<InstanceReference> src_references = src_instances->references();
+ Span<bke::InstanceReference> src_references = src_instances->references();
handle_mapping.reinitialize(src_references.size());
for (const int src_instance_handle : src_references.index_range()) {
- const InstanceReference &reference = src_references[src_instance_handle];
+ const bke::InstanceReference &reference = src_references[src_instance_handle];
const int dst_instance_handle = dst_component.add_reference(reference);
handle_mapping[src_instance_handle] = dst_instance_handle;
}
@@ -106,7 +106,7 @@ static void add_instances_from_component(
const int full_instance_handle = dst_component.add_reference(instance);
/* Add this reference last, because it is the most likely one to be removed later on. */
- const int empty_reference_handle = dst_component.add_reference(InstanceReference());
+ const int empty_reference_handle = dst_component.add_reference(bke::InstanceReference());
threading::parallel_for(selection.index_range(), 1024, [&](IndexRange selection_range) {
for (const int range_i : selection_range) {
@@ -129,12 +129,11 @@ static void add_instances_from_component(
const int index = mod_i(original_index, std::max(src_instances_num, 1));
if (index < src_instances_num) {
/* Get the reference to the source instance. */
- const int src_handle = src_instances->instance_reference_handles()[index];
+ const int src_handle = src_instances->reference_handles()[index];
dst_handle = handle_mapping[src_handle];
/* Take transforms of the source instance into account. */
- mul_m4_m4_post(dst_transform.values,
- src_instances->instance_transforms()[index].values);
+ mul_m4_m4_post(dst_transform.values, src_instances->transforms()[index].values);
}
}
}
@@ -157,7 +156,7 @@ static void add_instances_from_component(
}
}
- bke::CustomDataAttributes &instance_attributes = dst_component.instance_attributes();
+ bke::CustomDataAttributes &instance_attributes = dst_component.custom_data_attributes();
for (const auto item : attributes_to_propagate.items()) {
const AttributeIDRef &attribute_id = item.key;
const AttributeKind attribute_kind = item.value;
@@ -174,18 +173,7 @@ static void add_instances_from_component(
dst_attribute_opt = instance_attributes.get_for_write(attribute_id);
}
BLI_assert(dst_attribute_opt);
- const GMutableSpan dst_attribute = dst_attribute_opt->slice(start_len, select_len);
- threading::parallel_for(selection.index_range(), 1024, [&](IndexRange selection_range) {
- attribute_math::convert_to_static_type(attribute_kind.data_type, [&](auto dummy) {
- using T = decltype(dummy);
- VArray<T> src = src_attribute.typed<T>();
- MutableSpan<T> dst = dst_attribute.typed<T>();
- for (const int range_i : selection_range) {
- const int i = selection[range_i];
- dst[range_i] = src[i];
- }
- });
- });
+ array_utils::gather(src_attribute, selection, dst_attribute_opt->slice(start_len, select_len));
}
}
@@ -196,7 +184,15 @@ static void node_geo_exec(GeoNodeExecParams params)
instance.ensure_owns_direct_data();
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
- InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
+ /* It's important not to invalidate the existing #InstancesComponent because it owns references
+ * to other geometry sets that are processed by this node. */
+ InstancesComponent &instances_component =
+ geometry_set.get_component_for_write<InstancesComponent>();
+ bke::Instances *dst_instances = instances_component.get_for_write();
+ if (dst_instances == nullptr) {
+ dst_instances = new bke::Instances();
+ instances_component.replace(dst_instances);
+ }
const Array<GeometryComponentType> types{
GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE};
@@ -208,14 +204,13 @@ static void node_geo_exec(GeoNodeExecParams params)
for (const GeometryComponentType type : types) {
if (geometry_set.has(type)) {
- add_instances_from_component(instances,
+ add_instances_from_component(*dst_instances,
*geometry_set.get_component_for_read(type),
instance,
params,
attributes_to_propagate);
}
}
-
geometry_set.remove_geometry_during_modify();
});
@@ -223,8 +218,9 @@ static void node_geo_exec(GeoNodeExecParams params)
* process them needlessly.
* This should eventually be moved into the loop above, but currently this is quite tricky
* because it might remove references that the loop still wants to iterate over. */
- InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
- instances.remove_unused_references();
+ if (bke::Instances *instances = geometry_set.get_instances_for_write()) {
+ instances->remove_unused_references();
+ }
params.set_output("Instances", std::move(geometry_set));
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc
index ec2f1b00e6c..acd00d119ab 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc
@@ -3,6 +3,7 @@
#include "DNA_pointcloud_types.h"
#include "BKE_attribute_math.hh"
+#include "BKE_instances.hh"
#include "BKE_pointcloud.h"
#include "node_geometry_util.hh"
@@ -13,7 +14,7 @@ static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Instances")).only_instances();
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
- b.add_input<decl::Vector>(N_("Position")).implicit_field();
+ b.add_input<decl::Vector>(N_("Position")).implicit_field(implicit_field_inputs::position);
b.add_input<decl::Float>(N_("Radius"))
.default_value(0.05f)
.min(0.0f)
@@ -27,7 +28,7 @@ static void convert_instances_to_points(GeometrySet &geometry_set,
Field<float> radius_field,
const Field<bool> selection_field)
{
- const InstancesComponent &instances = *geometry_set.get_component_for_read<InstancesComponent>();
+ const bke::Instances &instances = *geometry_set.get_instances_for_read();
const bke::InstancesFieldContext context{instances};
fn::FieldEvaluator evaluator{context, instances.instances_num()};
@@ -70,7 +71,7 @@ static void convert_instances_to_points(GeometrySet &geometry_set,
const AttributeIDRef &attribute_id = item.key;
const AttributeKind attribute_kind = item.value;
- const GVArray src = instances.attributes()->lookup_or_default(
+ const GVArray src = instances.attributes().lookup_or_default(
attribute_id, ATTR_DOMAIN_INSTANCE, attribute_kind.data_type);
BLI_assert(src);
GSpanAttributeWriter dst = point_attributes.lookup_or_add_for_write_only_span(
diff --git a/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc b/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc
index 8e38ef14aba..d4e18321665 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc
@@ -28,13 +28,13 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Bool>(N_("Value"), "Value_Bool").field_source();
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
node->custom1 = ATTR_DOMAIN_POINT;
node->custom2 = CD_PROP_FLOAT;
@@ -42,7 +42,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
- const eCustomDataType data_type = static_cast<eCustomDataType>(node->custom2);
+ const eCustomDataType data_type = eCustomDataType(node->custom2);
bNodeSocket *sock_in_float = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *sock_in_int = sock_in_float->next;
@@ -111,6 +111,12 @@ class InterpolateDomain final : public bke::GeometryFieldInput {
return attributes.adapt_domain(
GVArray::ForGArray(std::move(values)), src_domain_, context.domain());
}
+
+ std::optional<eAttrDomain> preferred_domain(
+ const GeometryComponent & /*component*/) const override
+ {
+ return src_domain_;
+ }
};
static StringRefNull identifier_suffix(eCustomDataType data_type)
@@ -135,8 +141,8 @@ static StringRefNull identifier_suffix(eCustomDataType data_type)
static void node_geo_exec(GeoNodeExecParams params)
{
const bNode &node = params.node();
- const eAttrDomain domain = static_cast<eAttrDomain>(node.custom1);
- const eCustomDataType data_type = static_cast<eCustomDataType>(node.custom2);
+ const eAttrDomain domain = eAttrDomain(node.custom1);
+ const eCustomDataType data_type = eCustomDataType(node.custom2);
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
index 9fdf7fe7d31..ea2646a9786 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
@@ -2,6 +2,8 @@
#include "GEO_realize_instances.hh"
+#include "BKE_instances.hh"
+
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_join_geometry_cc {
@@ -29,6 +31,9 @@ static Map<AttributeIDRef, AttributeMetaData> get_final_attribute_info(
if (attribute_id.is_named() && ignored_attributes.contains(attribute_id.name())) {
return true;
}
+ if (meta_data.data_type == CD_PROP_STRING) {
+ return true;
+ }
info.add_or_modify(
attribute_id,
[&](AttributeMetaData *meta_data_final) { *meta_data_final = meta_data; },
@@ -97,40 +102,44 @@ static void join_attributes(Span<const GeometryComponent *> src_components,
static void join_components(Span<const InstancesComponent *> src_components, GeometrySet &result)
{
- InstancesComponent &dst_component = result.get_component_for_write<InstancesComponent>();
+ std::unique_ptr<bke::Instances> dst_instances = std::make_unique<bke::Instances>();
int tot_instances = 0;
for (const InstancesComponent *src_component : src_components) {
- tot_instances += src_component->instances_num();
+ tot_instances += src_component->get_for_read()->instances_num();
}
- dst_component.reserve(tot_instances);
+ dst_instances->reserve(tot_instances);
for (const InstancesComponent *src_component : src_components) {
- Span<InstanceReference> src_references = src_component->references();
+ const bke::Instances &src_instances = *src_component->get_for_read();
+
+ Span<bke::InstanceReference> src_references = src_instances.references();
Array<int> handle_map(src_references.size());
for (const int src_handle : src_references.index_range()) {
- handle_map[src_handle] = dst_component.add_reference(src_references[src_handle]);
+ handle_map[src_handle] = dst_instances->add_reference(src_references[src_handle]);
}
- Span<float4x4> src_transforms = src_component->instance_transforms();
- Span<int> src_reference_handles = src_component->instance_reference_handles();
+ Span<float4x4> src_transforms = src_instances.transforms();
+ Span<int> src_reference_handles = src_instances.reference_handles();
for (const int i : src_transforms.index_range()) {
const int src_handle = src_reference_handles[i];
const int dst_handle = handle_map[src_handle];
const float4x4 &transform = src_transforms[i];
- dst_component.add_instance(dst_handle, transform);
+ dst_instances->add_instance(dst_handle, transform);
}
}
+
+ result.replace_instances(dst_instances.release());
+ InstancesComponent &dst_component = result.get_component_for_write<InstancesComponent>();
join_attributes(to_base_components(src_components), dst_component, {"position"});
}
-static void join_components(Span<const VolumeComponent *> src_components, GeometrySet &result)
+static void join_components(Span<const VolumeComponent *> /*src_components*/,
+ GeometrySet & /*result*/)
{
/* Not yet supported. Joining volume grids with the same name requires resampling of at least one
* of the grids. The cell size of the resulting volume has to be determined somehow. */
- VolumeComponent &dst_component = result.get_component_for_write<VolumeComponent>();
- UNUSED_VARS(src_components, dst_component);
}
template<typename Component>
@@ -152,25 +161,23 @@ static void join_component_type(Span<GeometrySet> src_geometry_sets, GeometrySet
return;
}
- GeometrySet instances_geometry_set;
- InstancesComponent &instances =
- instances_geometry_set.get_component_for_write<InstancesComponent>();
-
if constexpr (is_same_any_v<Component, InstancesComponent, VolumeComponent>) {
join_components(components, result);
}
else {
+ std::unique_ptr<bke::Instances> instances = std::make_unique<bke::Instances>();
for (const Component *component : components) {
GeometrySet tmp_geo;
tmp_geo.add(*component);
- const int handle = instances.add_reference(InstanceReference{tmp_geo});
- instances.add_instance(handle, float4x4::identity());
+ const int handle = instances->add_reference(bke::InstanceReference{tmp_geo});
+ instances->add_instance(handle, float4x4::identity());
}
geometry::RealizeInstancesOptions options;
options.keep_original_ids = true;
options.realize_instance_attributes = false;
- GeometrySet joined_components = geometry::realize_instances(instances_geometry_set, options);
+ GeometrySet joined_components = geometry::realize_instances(
+ GeometrySet::create_with_instances(instances.release()), options);
result.add(joined_components.get_component_for_write<Component>());
}
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
index 628688f3b47..dfb4181926e 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
@@ -100,6 +100,12 @@ class MaterialSelectionFieldInput final : public bke::GeometryFieldInput {
}
return false;
}
+
+ std::optional<eAttrDomain> preferred_domain(
+ const GeometryComponent & /*component*/) const override
+ {
+ return ATTR_DOMAIN_FACE;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc b/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc
index f64f997810e..8ab8c4afaa9 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc
@@ -24,14 +24,14 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryMergeByDistance *data = MEM_cnew<NodeGeometryMergeByDistance>(__func__);
data->mode = GEO_NODE_MERGE_BY_DISTANCE_MODE_ALL;
@@ -132,7 +132,7 @@ void register_node_type_geo_merge_by_distance()
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_MERGE_BY_DISTANCE, "Merge by Distance", NODE_CLASS_GEOMETRY);
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
node_type_storage(&ntype,
"NodeGeometryMergeByDistance",
node_free_standard_storage,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc
new file mode 100644
index 00000000000..1b9852cf7b9
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_mesh.h"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_mesh_face_set_boundaries_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Int>(N_("Face Set"))
+ .default_value(0)
+ .hide_value()
+ .supports_field()
+ .description(N_("An identifier for the group of each face. All contiguous faces with the "
+ "same value are in the same region"));
+ b.add_output<decl::Bool>(N_("Boundary Edges"))
+ .field_source()
+ .description(N_("The edges that lie on the boundaries between the different face sets"));
+}
+
+class BoundaryFieldInput final : public bke::MeshFieldInput {
+ private:
+ const Field<int> face_set;
+
+ public:
+ BoundaryFieldInput(const Field<int> face_set)
+ : bke::MeshFieldInput(CPPType::get<bool>(), "Boundary Field"), face_set(face_set)
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const Mesh &mesh,
+ const eAttrDomain domain,
+ const IndexMask /*mask*/) const final
+ {
+ const bke::MeshFieldContext face_context{mesh, ATTR_DOMAIN_FACE};
+ FieldEvaluator face_evaluator{face_context, mesh.totpoly};
+ face_evaluator.add(face_set);
+ face_evaluator.evaluate();
+ const VArray<int> face_set = face_evaluator.get_evaluated<int>(0);
+
+ Array<bool> boundary(mesh.totedge, false);
+ Array<bool> edge_visited(mesh.totedge, false);
+ Array<int> edge_face_set(mesh.totedge, 0);
+ const Span<MPoly> polys = mesh.polys();
+ const Span<MLoop> loops = mesh.loops();
+ for (const int i : polys.index_range()) {
+ const MPoly &poly = polys[i];
+ for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
+ const int edge = loop.e;
+ if (edge_visited[edge]) {
+ if (edge_face_set[edge] != face_set[i]) {
+ /* This edge is connected to two faces on different face sets. */
+ boundary[edge] = true;
+ }
+ }
+ edge_visited[edge] = true;
+ edge_face_set[edge] = face_set[i];
+ }
+ }
+ return mesh.attributes().adapt_domain<bool>(
+ VArray<bool>::ForContainer(std::move(boundary)), ATTR_DOMAIN_EDGE, domain);
+ }
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_EDGE;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ const Field<int> face_set_field = params.extract_input<Field<int>>("Face Set");
+ Field<bool> face_set_boundaries{std::make_shared<BoundaryFieldInput>(face_set_field)};
+ params.set_output("Boundary Edges", std::move(face_set_boundaries));
+}
+
+} // namespace blender::nodes::node_geo_mesh_face_set_boundaries_cc
+
+void register_node_type_geo_mesh_face_set_boundaries()
+{
+ namespace file_ns = blender::nodes::node_geo_mesh_face_set_boundaries_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(
+ &ntype, GEO_NODE_MESH_FACE_SET_BOUNDARIES, "Face Set Boundaries", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc
index 801b3c78060..14f38efbd42 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc
@@ -29,14 +29,14 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Mesh"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
uiItemR(layout, ptr, "fill_type", 0, nullptr, ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryMeshCircle *node_storage = MEM_cnew<NodeGeometryMeshCircle>(__func__);
@@ -115,7 +115,7 @@ static Mesh *create_circle_mesh(const float radius,
MutableSpan<MLoop> loops = mesh->loops_for_write();
/* Assign vertex coordinates. */
- const float angle_delta = 2.0f * (M_PI / static_cast<float>(verts_num));
+ const float angle_delta = 2.0f * (M_PI / float(verts_num));
for (const int i : IndexRange(verts_num)) {
const float angle = i * angle_delta;
copy_v3_v3(verts[i].co, float3(std::cos(angle) * radius, std::sin(angle) * radius, 0.0f));
@@ -127,7 +127,7 @@ static Mesh *create_circle_mesh(const float radius,
/* Create outer edges. */
const short edge_flag = (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NONE) ?
ME_LOOSEEDGE :
- (ME_EDGEDRAW | ME_EDGERENDER); /* NGON or TRIANGLE_FAN */
+ ME_EDGEDRAW; /* NGON or TRIANGLE_FAN */
for (const int i : IndexRange(verts_num)) {
MEdge &edge = edges[i];
edge.v1 = i;
@@ -141,7 +141,7 @@ static Mesh *create_circle_mesh(const float radius,
MEdge &edge = edges[verts_num + i];
edge.v1 = verts_num;
edge.v2 = i;
- edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
+ edge.flag = ME_EDGEDRAW;
}
}
@@ -205,7 +205,7 @@ void register_node_type_geo_mesh_primitive_circle()
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_MESH_PRIMITIVE_CIRCLE, "Mesh Circle", NODE_CLASS_GEOMETRY);
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
node_type_storage(
&ntype, "NodeGeometryMeshCircle", node_free_standard_storage, node_copy_standard_storage);
ntype.geometry_node_execute = file_ns::node_geo_exec;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
index edf14f664c5..dca91d2dc61 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
@@ -258,7 +258,7 @@ int ConeConfig::calculate_total_corners()
static void calculate_cone_verts(const MutableSpan<MVert> &verts, const ConeConfig &config)
{
Array<float2> circle(config.circle_segments);
- const float angle_delta = 2.0f * (M_PI / static_cast<float>(config.circle_segments));
+ const float angle_delta = 2.0f * (M_PI / float(config.circle_segments));
float angle = 0.0f;
for (const int i : IndexRange(config.circle_segments)) {
circle[i].x = std::cos(angle);
@@ -275,8 +275,7 @@ static void calculate_cone_verts(const MutableSpan<MVert> &verts, const ConeConf
/* Top fill including the outer edge of the fill. */
if (!config.top_is_point) {
- const float top_fill_radius_delta = config.radius_top /
- static_cast<float>(config.fill_segments);
+ const float top_fill_radius_delta = config.radius_top / float(config.fill_segments);
for (const int i : IndexRange(config.fill_segments)) {
const float top_fill_radius = top_fill_radius_delta * (i + 1);
for (const int j : IndexRange(config.circle_segments)) {
@@ -289,8 +288,8 @@ static void calculate_cone_verts(const MutableSpan<MVert> &verts, const ConeConf
/* Rings along the side. */
const float side_radius_delta = (config.radius_bottom - config.radius_top) /
- static_cast<float>(config.side_segments);
- const float height_delta = 2.0f * config.height / static_cast<float>(config.side_segments);
+ float(config.side_segments);
+ const float height_delta = 2.0f * config.height / float(config.side_segments);
for (const int i : IndexRange(config.side_segments - 1)) {
const float ring_radius = config.radius_top + (side_radius_delta * (i + 1));
const float ring_height = config.height - (height_delta * (i + 1));
@@ -303,8 +302,7 @@ static void calculate_cone_verts(const MutableSpan<MVert> &verts, const ConeConf
/* Bottom fill including the outer edge of the fill. */
if (!config.bottom_is_point) {
- const float bottom_fill_radius_delta = config.radius_bottom /
- static_cast<float>(config.fill_segments);
+ const float bottom_fill_radius_delta = config.radius_bottom / float(config.fill_segments);
for (const int i : IndexRange(config.fill_segments)) {
const float bottom_fill_radius = config.radius_bottom - (i * bottom_fill_radius_delta);
for (const int j : IndexRange(config.circle_segments)) {
@@ -331,7 +329,7 @@ static void calculate_cone_edges(const MutableSpan<MEdge> &edges, const ConeConf
MEdge &edge = edges[edge_index++];
edge.v1 = config.first_vert;
edge.v2 = config.first_ring_verts_start + i;
- edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
+ edge.flag = ME_EDGEDRAW;
}
}
@@ -344,7 +342,7 @@ static void calculate_cone_edges(const MutableSpan<MEdge> &edges, const ConeConf
MEdge &edge = edges[edge_index++];
edge.v1 = this_ring_vert_start + j;
edge.v2 = this_ring_vert_start + ((j + 1) % config.circle_segments);
- edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
+ edge.flag = ME_EDGEDRAW;
}
if (i == config.tot_edge_rings - 1) {
/* There is one fewer ring of connecting edges. */
@@ -355,7 +353,7 @@ static void calculate_cone_edges(const MutableSpan<MEdge> &edges, const ConeConf
MEdge &edge = edges[edge_index++];
edge.v1 = this_ring_vert_start + j;
edge.v2 = next_ring_vert_start + j;
- edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
+ edge.flag = ME_EDGEDRAW;
}
}
@@ -365,7 +363,7 @@ static void calculate_cone_edges(const MutableSpan<MEdge> &edges, const ConeConf
MEdge &edge = edges[edge_index++];
edge.v1 = config.last_ring_verts_start + i;
edge.v2 = config.last_vert;
- edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
+ edge.flag = ME_EDGEDRAW;
}
}
}
@@ -485,7 +483,7 @@ static void calculate_selection_outputs(Mesh *mesh,
/* Populate "Top" selection output. */
if (attribute_outputs.top_id) {
const bool face = !config.top_is_point && config.fill_type != GEO_NODE_MESH_CIRCLE_FILL_NONE;
- SpanAttributeWriter<bool> selection = attributes.lookup_or_add_for_write_only_span<bool>(
+ SpanAttributeWriter<bool> selection = attributes.lookup_or_add_for_write_span<bool>(
attribute_outputs.top_id.get(), face ? ATTR_DOMAIN_FACE : ATTR_DOMAIN_POINT);
if (config.top_is_point) {
@@ -501,7 +499,7 @@ static void calculate_selection_outputs(Mesh *mesh,
if (attribute_outputs.bottom_id) {
const bool face = !config.bottom_is_point &&
config.fill_type != GEO_NODE_MESH_CIRCLE_FILL_NONE;
- SpanAttributeWriter<bool> selection = attributes.lookup_or_add_for_write_only_span<bool>(
+ SpanAttributeWriter<bool> selection = attributes.lookup_or_add_for_write_span<bool>(
attribute_outputs.bottom_id.get(), face ? ATTR_DOMAIN_FACE : ATTR_DOMAIN_POINT);
if (config.bottom_is_point) {
@@ -518,7 +516,7 @@ static void calculate_selection_outputs(Mesh *mesh,
/* Populate "Side" selection output. */
if (attribute_outputs.side_id) {
- SpanAttributeWriter<bool> selection = attributes.lookup_or_add_for_write_only_span<bool>(
+ SpanAttributeWriter<bool> selection = attributes.lookup_or_add_for_write_span<bool>(
attribute_outputs.side_id.get(), ATTR_DOMAIN_FACE);
selection.span.slice(config.side_faces_start, config.side_faces_len).fill(true);
@@ -544,7 +542,7 @@ static void calculate_cone_uvs(Mesh *mesh, const ConeConfig &config)
Array<float2> circle(config.circle_segments);
float angle = 0.0f;
- const float angle_delta = 2.0f * M_PI / static_cast<float>(config.circle_segments);
+ const float angle_delta = 2.0f * M_PI / float(config.circle_segments);
for (const int i : IndexRange(config.circle_segments)) {
circle[i].x = std::cos(angle) * 0.225f;
circle[i].y = std::sin(angle) * 0.225f;
@@ -556,9 +554,8 @@ static void calculate_cone_uvs(Mesh *mesh, const ConeConfig &config)
/* Left circle of the UV representing the top fill or top cone tip. */
if (config.top_is_point || config.fill_type != GEO_NODE_MESH_CIRCLE_FILL_NONE) {
const float2 center_left(0.25f, 0.25f);
- const float radius_factor_delta = 1.0f / (config.top_is_point ?
- static_cast<float>(config.side_segments) :
- static_cast<float>(config.fill_segments));
+ const float radius_factor_delta = 1.0f / (config.top_is_point ? float(config.side_segments) :
+ float(config.fill_segments));
const int left_circle_segment_count = config.top_is_point ? config.side_segments :
config.fill_segments;
@@ -595,8 +592,8 @@ static void calculate_cone_uvs(Mesh *mesh, const ConeConfig &config)
if (!config.top_is_point && !config.bottom_is_point) {
/* Mesh is a truncated cone or cylinder. The sides are unwrapped into a rectangle. */
const float bottom = (config.fill_type == GEO_NODE_MESH_CIRCLE_FILL_NONE) ? 0.0f : 0.5f;
- const float x_delta = 1.0f / static_cast<float>(config.circle_segments);
- const float y_delta = (1.0f - bottom) / static_cast<float>(config.side_segments);
+ const float x_delta = 1.0f / float(config.circle_segments);
+ const float y_delta = (1.0f - bottom) / float(config.side_segments);
for (const int i : IndexRange(config.side_segments)) {
for (const int j : IndexRange(config.circle_segments)) {
@@ -612,8 +609,8 @@ static void calculate_cone_uvs(Mesh *mesh, const ConeConfig &config)
if (config.bottom_is_point || config.fill_type != GEO_NODE_MESH_CIRCLE_FILL_NONE) {
const float2 center_right(0.75f, 0.25f);
const float radius_factor_delta = 1.0f / (config.bottom_is_point ?
- static_cast<float>(config.side_segments) :
- static_cast<float>(config.fill_segments));
+ float(config.side_segments) :
+ float(config.fill_segments));
const int right_circle_segment_count = config.bottom_is_point ? config.side_segments :
config.fill_segments;
@@ -679,7 +676,7 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top,
if (config.height == 0.0f) {
return create_vertex_mesh();
}
- const float z_delta = -2.0f * config.height / static_cast<float>(config.side_segments);
+ const float z_delta = -2.0f * config.height / float(config.side_segments);
const float3 start(0.0f, 0.0f, config.height);
const float3 delta(0.0f, 0.0f, z_delta);
return create_line_mesh(start, delta, config.tot_verts);
@@ -746,7 +743,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Bool>(N_("Side")).field_source();
}
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryMeshCone *node_storage = MEM_cnew<NodeGeometryMeshCone>(__func__);
@@ -757,7 +754,7 @@ static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
- bNodeSocket *vertices_socket = (bNodeSocket *)node->inputs.first;
+ bNodeSocket *vertices_socket = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *rings_socket = vertices_socket->next;
bNodeSocket *fill_subdiv_socket = rings_socket->next;
@@ -767,7 +764,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, fill_subdiv_socket, has_fill);
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
@@ -857,8 +854,8 @@ void register_node_type_geo_mesh_primitive_cone()
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_MESH_PRIMITIVE_CONE, "Cone", NODE_CLASS_GEOMETRY);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
node_type_storage(
&ntype, "NodeGeometryMeshCone", node_free_standard_storage, node_copy_standard_storage);
ntype.geometry_node_execute = file_ns::node_geo_exec;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc
index 301d46e586f..b02b1fbae27 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc
@@ -48,14 +48,14 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Bool>(N_("Bottom")).field_source();
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
uiItemR(layout, ptr, "fill_type", 0, nullptr, ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryMeshCylinder *node_storage = MEM_cnew<NodeGeometryMeshCylinder>(__func__);
@@ -66,7 +66,7 @@ static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
- bNodeSocket *vertices_socket = (bNodeSocket *)node->inputs.first;
+ bNodeSocket *vertices_socket = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *rings_socket = vertices_socket->next;
bNodeSocket *fill_subdiv_socket = rings_socket->next;
@@ -154,8 +154,8 @@ void register_node_type_geo_mesh_primitive_cylinder()
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_MESH_PRIMITIVE_CYLINDER, "Cylinder", NODE_CLASS_GEOMETRY);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
node_type_storage(
&ntype, "NodeGeometryMeshCylinder", node_free_standard_storage, node_copy_standard_storage);
ntype.declare = file_ns::node_declare;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc
index 6f0b8283b72..e8ee057ee5c 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc
@@ -76,8 +76,7 @@ Mesh *create_grid_mesh(const int verts_x,
const int y_edges_start = 0;
const int x_edges_start = verts_x * edges_y;
- const short edge_flag = (edges_x == 0 || edges_y == 0) ? ME_LOOSEEDGE :
- ME_EDGEDRAW | ME_EDGERENDER;
+ const short edge_flag = (edges_x == 0 || edges_y == 0) ? ME_LOOSEEDGE : ME_EDGEDRAW;
/* Build the horizontal edges in the X direction. */
threading::parallel_for(IndexRange(verts_x), 512, [&](IndexRange x_range) {
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc
index aa9a2e9013f..8287c6a6714 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc
@@ -47,7 +47,7 @@ static Mesh *create_ico_sphere_mesh(const int subdivisions, const float radius)
BMeshToMeshParams params{};
params.calc_object_remap = false;
- Mesh *mesh = (Mesh *)BKE_id_new_nomain(ID_ME, nullptr);
+ Mesh *mesh = reinterpret_cast<Mesh *>(BKE_id_new_nomain(ID_ME, nullptr));
BKE_id_material_eval_ensure_default_slot(&mesh->id);
BM_mesh_bm_to_me(nullptr, bm, mesh, &params);
BM_mesh_free(bm);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc
index 4fd6399f4eb..51a4f36507e 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc
@@ -43,7 +43,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Mesh"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
@@ -53,7 +53,7 @@ static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
}
}
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryMeshLine *node_storage = MEM_cnew<NodeGeometryMeshLine>(__func__);
@@ -65,7 +65,7 @@ static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
- bNodeSocket *count_socket = (bNodeSocket *)node->inputs.first;
+ bNodeSocket *count_socket = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *resolution_socket = count_socket->next;
bNodeSocket *start_socket = resolution_socket->next;
bNodeSocket *end_and_offset_socket = start_socket->next;
@@ -97,7 +97,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
return;
}
else if (params.node_tree().typeinfo->validate_link(
- static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_FLOAT)) {
+ eNodeSocketDatatype(params.other_socket().type), SOCK_FLOAT)) {
params.add_item(IFACE_("Count"), [](LinkSearchOpParams &params) {
bNode &node = params.add_node("GeometryNodeMeshLine");
node_storage(node).mode = GEO_NODE_MESH_LINE_MODE_OFFSET;
@@ -153,7 +153,7 @@ static void node_geo_exec(GeoNodeExecParams params)
mesh = create_line_mesh(start, float3(0), count);
}
else {
- const float3 delta = total_delta / (float)(count - 1);
+ const float3 delta = total_delta / float(count - 1);
mesh = create_line_mesh(start, delta, count);
}
}
@@ -214,8 +214,8 @@ void register_node_type_geo_mesh_primitive_line()
geo_node_type_base(&ntype, GEO_NODE_MESH_PRIMITIVE_LINE, "Mesh Line", NODE_CLASS_GEOMETRY);
ntype.declare = file_ns::node_declare;
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
node_type_storage(
&ntype, "NodeGeometryMeshLine", node_free_standard_storage, node_copy_standard_storage);
ntype.geometry_node_execute = file_ns::node_geo_exec;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
index d39e72b7f0a..cfa1c477b28 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
@@ -116,7 +116,7 @@ BLI_NOINLINE static void calculate_sphere_edge_indices(MutableSpan<MEdge> edges,
MEdge &edge = edges[edge_index++];
edge.v1 = 0;
edge.v2 = first_vert_ring_index_start + segment;
- edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
+ edge.flag = ME_EDGEDRAW;
}
int ring_vert_index_start = 1;
@@ -128,7 +128,7 @@ BLI_NOINLINE static void calculate_sphere_edge_indices(MutableSpan<MEdge> edges,
MEdge &edge = edges[edge_index++];
edge.v1 = ring_vert_index_start + segment;
edge.v2 = ring_vert_index_start + ((segment + 1) % segments);
- edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
+ edge.flag = ME_EDGEDRAW;
}
/* Add the edges connecting to the next ring. */
@@ -137,7 +137,7 @@ BLI_NOINLINE static void calculate_sphere_edge_indices(MutableSpan<MEdge> edges,
MEdge &edge = edges[edge_index++];
edge.v1 = ring_vert_index_start + segment;
edge.v2 = next_ring_vert_index_start + segment;
- edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
+ edge.flag = ME_EDGEDRAW;
}
}
ring_vert_index_start += segments;
@@ -150,7 +150,7 @@ BLI_NOINLINE static void calculate_sphere_edge_indices(MutableSpan<MEdge> edges,
MEdge &edge = edges[edge_index++];
edge.v1 = last_vert_index;
edge.v2 = last_vert_ring_start + segment;
- edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
+ edge.flag = ME_EDGEDRAW;
}
}
@@ -266,16 +266,16 @@ BLI_NOINLINE static void calculate_sphere_uvs(Mesh *mesh, const float segments,
const float segments_inv = 1.0f / segments;
for (const int i_segment : IndexRange(segments)) {
- const float segment = static_cast<float>(i_segment);
+ const float segment = float(i_segment);
uvs[loop_index++] = float2((segment + 0.5f) * segments_inv, 0.0f);
uvs[loop_index++] = float2(segment * segments_inv, dy);
uvs[loop_index++] = float2((segment + 1.0f) * segments_inv, dy);
}
for (const int i_ring : IndexRange(1, rings - 2)) {
- const float ring = static_cast<float>(i_ring);
+ const float ring = float(i_ring);
for (const int i_segment : IndexRange(segments)) {
- const float segment = static_cast<float>(i_segment);
+ const float segment = float(i_segment);
uvs[loop_index++] = float2(segment * segments_inv, ring / rings);
uvs[loop_index++] = float2(segment * segments_inv, (ring + 1.0f) / rings);
uvs[loop_index++] = float2((segment + 1.0f) * segments_inv, (ring + 1.0f) / rings);
@@ -284,7 +284,7 @@ BLI_NOINLINE static void calculate_sphere_uvs(Mesh *mesh, const float segments,
}
for (const int i_segment : IndexRange(segments)) {
- const float segment = static_cast<float>(i_segment);
+ const float segment = float(i_segment);
uvs[loop_index++] = float2((segment + 0.5f) * segments_inv, 1.0f);
uvs[loop_index++] = float2((segment + 1.0f) * segments_inv, 1.0f - dy);
uvs[loop_index++] = float2(segment * segments_inv, 1.0f - dy);
@@ -309,7 +309,8 @@ static Mesh *create_uv_sphere_mesh(const float radius, const int segments, const
threading::parallel_invoke(
1024 < segments * rings,
[&]() {
- MutableSpan vert_normals{(float3 *)BKE_mesh_vertex_normals_for_write(mesh), mesh->totvert};
+ MutableSpan vert_normals{
+ reinterpret_cast<float3 *>(BKE_mesh_vertex_normals_for_write(mesh)), mesh->totvert};
calculate_sphere_vertex_data(verts, vert_normals, radius, segments, rings);
BKE_mesh_vertex_normals_clear_dirty(mesh);
},
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc
index a1d6695b33b..d47e0c0f101 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "BLI_array_utils.hh"
#include "BLI_task.hh"
#include "DNA_mesh_types.h"
@@ -23,7 +24,7 @@ static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).supports_field().hide_value();
- b.add_input<decl::Vector>(N_("Position")).implicit_field();
+ b.add_input<decl::Vector>(N_("Position")).implicit_field(implicit_field_inputs::position);
b.add_input<decl::Float>(N_("Radius"))
.default_value(0.05f)
.min(0.0f)
@@ -32,29 +33,18 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Points"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryMeshToPoints *data = MEM_cnew<NodeGeometryMeshToPoints>(__func__);
data->mode = GEO_NODE_MESH_TO_POINTS_VERTICES;
node->storage = data;
}
-static void materialize_compressed_to_uninitialized_threaded(const GVArray &src,
- const IndexMask mask,
- GMutableSpan dst)
-{
- BLI_assert(src.type() == dst.type());
- BLI_assert(mask.size() == dst.size());
- threading::parallel_for(mask.index_range(), 4096, [&](IndexRange range) {
- src.materialize_compressed_to_uninitialized(mask.slice(range), dst.slice(range).data());
- });
-}
-
static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
Field<float3> &position_field,
Field<float> &radius_field,
@@ -88,14 +78,12 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
GSpanAttributeWriter position = dst_attributes.lookup_or_add_for_write_only_span(
"position", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
- materialize_compressed_to_uninitialized_threaded(
- evaluator.get_evaluated(0), selection, position.span);
+ array_utils::gather(evaluator.get_evaluated(0), selection, position.span);
position.finish();
GSpanAttributeWriter radius = dst_attributes.lookup_or_add_for_write_only_span(
"radius", ATTR_DOMAIN_POINT, CD_PROP_FLOAT);
- materialize_compressed_to_uninitialized_threaded(
- evaluator.get_evaluated(1), selection, radius.span);
+ array_utils::gather(evaluator.get_evaluated(1), selection, radius.span);
radius.finish();
Map<AttributeIDRef, AttributeKind> attributes;
@@ -112,7 +100,7 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span(
attribute_id, ATTR_DOMAIN_POINT, data_type);
if (dst && src) {
- materialize_compressed_to_uninitialized_threaded(src, selection, dst.span);
+ array_utils::gather(src, selection, dst.span);
dst.finish();
}
}
@@ -175,7 +163,7 @@ void register_node_type_geo_mesh_to_points()
geo_node_type_base(&ntype, GEO_NODE_MESH_TO_POINTS, "Mesh to Points", NODE_CLASS_GEOMETRY);
ntype.declare = file_ns::node_declare;
ntype.geometry_node_execute = file_ns::node_geo_exec;
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
ntype.draw_buttons = file_ns::node_layout;
node_type_storage(
&ntype, "NodeGeometryMeshToPoints", node_free_standard_storage, node_copy_standard_storage);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_volume.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_volume.cc
index 92814a8bc5e..cf4d058cd31 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_volume.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_volume.cc
@@ -50,33 +50,31 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Volume"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
uiItemR(layout, ptr, "resolution_mode", 0, IFACE_("Resolution"), ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
- NodeGeometryMeshToVolume *data = (NodeGeometryMeshToVolume *)MEM_callocN(
- sizeof(NodeGeometryMeshToVolume), __func__);
+ NodeGeometryMeshToVolume *data = MEM_cnew<NodeGeometryMeshToVolume>(__func__);
data->resolution_mode = MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT;
node->storage = data;
}
static void node_update(bNodeTree *ntree, bNode *node)
{
- NodeGeometryMeshToVolume *data = (NodeGeometryMeshToVolume *)node->storage;
+ NodeGeometryMeshToVolume &data = node_storage(*node);
bNodeSocket *voxel_size_socket = nodeFindSocket(node, SOCK_IN, "Voxel Size");
bNodeSocket *voxel_amount_socket = nodeFindSocket(node, SOCK_IN, "Voxel Amount");
nodeSetSocketAvailability(ntree,
voxel_amount_socket,
- data->resolution_mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT);
- nodeSetSocketAvailability(ntree,
- voxel_size_socket,
- data->resolution_mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE);
+ data.resolution_mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_AMOUNT);
+ nodeSetSocketAvailability(
+ ntree, voxel_size_socket, data.resolution_mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE);
}
#ifdef WITH_OPENVDB
@@ -126,7 +124,7 @@ static Volume *create_volume_from_mesh(const Mesh &mesh, GeoNodeExecParams &para
exterior_band_width,
mesh_to_volume_space_transform);
- Volume *volume = (Volume *)BKE_id_new_nomain(ID_VO, nullptr);
+ Volume *volume = reinterpret_cast<Volume *>(BKE_id_new_nomain(ID_VO, nullptr));
BKE_volume_init_grids(volume);
/* Convert mesh to grid and add to volume. */
@@ -149,7 +147,6 @@ static void node_geo_exec(GeoNodeExecParams params)
{
#ifdef WITH_OPENVDB
GeometrySet geometry_set(params.extract_input<GeometrySet>("Mesh"));
-
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
if (geometry_set.has_mesh()) {
Volume *volume = create_volume_from_mesh(*geometry_set.get_mesh_for_read(), params);
@@ -159,9 +156,9 @@ static void node_geo_exec(GeoNodeExecParams params)
});
params.set_output("Volume", std::move(geometry_set));
#else
+ params.set_default_remaining_outputs();
params.error_message_add(NodeWarningType::Error,
TIP_("Disabled, Blender was compiled without OpenVDB"));
- params.set_default_remaining_outputs();
return;
#endif
}
@@ -177,8 +174,8 @@ void register_node_type_geo_mesh_to_volume()
geo_node_type_base(&ntype, GEO_NODE_MESH_TO_VOLUME, "Mesh to Volume", NODE_CLASS_GEOMETRY);
ntype.declare = file_ns::node_declare;
node_type_size(&ntype, 200, 120, 700);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.draw_buttons = file_ns::node_layout;
node_type_storage(
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc
new file mode 100644
index 00000000000..b464832409c
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc
@@ -0,0 +1,199 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BLI_task.hh"
+
+#include "BKE_mesh.h"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_mesh_topology_corners_of_face_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Int>(N_("Face Index"))
+ .implicit_field(implicit_field_inputs::index)
+ .description(N_("The face to retrieve data from. Defaults to the face from the context"));
+ b.add_input<decl::Float>(N_("Weights"))
+ .supports_field()
+ .hide_value()
+ .description(N_("Values used to sort the face's corners. Uses indices by default"));
+ b.add_input<decl::Int>(N_("Sort Index"))
+ .min(0)
+ .supports_field()
+ .description(N_("Which of the sorted corners to output"));
+ b.add_output<decl::Int>(N_("Corner Index"))
+ .dependent_field()
+ .description(N_("A corner of the face, chosen by the sort index"));
+ b.add_output<decl::Int>(N_("Total"))
+ .dependent_field()
+ .description(N_("The number of corners in the face"));
+}
+
+class CornersOfFaceInput final : public bke::MeshFieldInput {
+ const Field<int> face_index_;
+ const Field<int> sort_index_;
+ const Field<float> sort_weight_;
+
+ public:
+ CornersOfFaceInput(Field<int> face_index, Field<int> sort_index, Field<float> sort_weight)
+ : bke::MeshFieldInput(CPPType::get<int>(), "Corner of Face"),
+ face_index_(std::move(face_index)),
+ sort_index_(std::move(sort_index)),
+ sort_weight_(std::move(sort_weight))
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const Mesh &mesh,
+ const eAttrDomain domain,
+ const IndexMask mask) const final
+ {
+ const Span<MPoly> polys = mesh.polys();
+
+ const bke::MeshFieldContext context{mesh, domain};
+ fn::FieldEvaluator evaluator{context, &mask};
+ evaluator.add(face_index_);
+ evaluator.add(sort_index_);
+ evaluator.evaluate();
+ const VArray<int> face_indices = evaluator.get_evaluated<int>(0);
+ const VArray<int> indices_in_sort = evaluator.get_evaluated<int>(1);
+
+ const bke::MeshFieldContext corner_context{mesh, ATTR_DOMAIN_CORNER};
+ fn::FieldEvaluator corner_evaluator{corner_context, mesh.totloop};
+ corner_evaluator.add(sort_weight_);
+ corner_evaluator.evaluate();
+ const VArray<float> all_sort_weights = corner_evaluator.get_evaluated<float>(0);
+
+ Array<int> corner_of_face(mask.min_array_size());
+ threading::parallel_for(mask.index_range(), 1024, [&](const IndexRange range) {
+ /* Reuse arrays to avoid allocation. */
+ Array<float> sort_weights;
+ Array<int> sort_indices;
+
+ for (const int selection_i : mask.slice(range)) {
+ const int poly_i = face_indices[selection_i];
+ const int index_in_sort = indices_in_sort[selection_i];
+ if (!polys.index_range().contains(poly_i)) {
+ corner_of_face[selection_i] = 0;
+ continue;
+ }
+
+ const MPoly &poly = polys[poly_i];
+ const IndexRange corners(poly.loopstart, poly.totloop);
+
+ /* Retrieve the weights for each corner. */
+ sort_weights.reinitialize(corners.size());
+ all_sort_weights.materialize_compressed(IndexMask(corners),
+ sort_weights.as_mutable_span());
+
+ /* Sort a separate array of compressed indices corresponding to the compressed weights.
+ * This allows using `materialize_compressed` to avoid virtual function call overhead
+ * when accessing values in the sort weights. However, it means a separate array of
+ * indices within the compressed array is necessary for sorting. */
+ sort_indices.reinitialize(corners.size());
+ std::iota(sort_indices.begin(), sort_indices.end(), 0);
+ std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) {
+ return sort_weights[a] < sort_weights[b];
+ });
+
+ const int index_in_sort_wrapped = mod_i(index_in_sort, corners.size());
+ corner_of_face[selection_i] = corners[sort_indices[index_in_sort_wrapped]];
+ }
+ });
+
+ return VArray<int>::ForContainer(std::move(corner_of_face));
+ }
+
+ uint64_t hash() const final
+ {
+ return 6927982716657;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const final
+ {
+ if (const auto *typed = dynamic_cast<const CornersOfFaceInput *>(&other)) {
+ return typed->face_index_ == face_index_ && typed->sort_index_ == sort_index_ &&
+ typed->sort_weight_ == sort_weight_;
+ }
+ return false;
+ }
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_FACE;
+ }
+};
+
+static int get_poly_totloop(const MPoly &poly)
+{
+ return poly.totloop;
+}
+
+class CornersOfFaceCountInput final : public bke::MeshFieldInput {
+ public:
+ CornersOfFaceCountInput() : bke::MeshFieldInput(CPPType::get<int>(), "Face Corner Count")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const Mesh &mesh,
+ const eAttrDomain domain,
+ const IndexMask /*mask*/) const final
+ {
+ if (domain != ATTR_DOMAIN_FACE) {
+ return {};
+ }
+ return VArray<int>::ForDerivedSpan<MPoly, get_poly_totloop>(mesh.polys());
+ }
+
+ uint64_t hash() const final
+ {
+ return 8345908765432698;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const final
+ {
+ if (dynamic_cast<const CornersOfFaceCountInput *>(&other)) {
+ return true;
+ }
+ return false;
+ }
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_FACE;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ const Field<int> face_index = params.extract_input<Field<int>>("Face Index");
+ if (params.output_is_required("Total")) {
+ params.set_output("Total",
+ Field<int>(std::make_shared<FieldAtIndexInput>(
+ face_index,
+ Field<int>(std::make_shared<CornersOfFaceCountInput>()),
+ ATTR_DOMAIN_FACE)));
+ }
+ if (params.output_is_required("Corner Index")) {
+ params.set_output("Corner Index",
+ Field<int>(std::make_shared<CornersOfFaceInput>(
+ face_index,
+ params.extract_input<Field<int>>("Sort Index"),
+ params.extract_input<Field<float>>("Weights"))));
+ }
+}
+
+} // namespace blender::nodes::node_geo_mesh_topology_corners_of_face_cc
+
+void register_node_type_geo_mesh_topology_corners_of_face()
+{
+ namespace file_ns = blender::nodes::node_geo_mesh_topology_corners_of_face_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(
+ &ntype, GEO_NODE_MESH_TOPOLOGY_CORNERS_OF_FACE, "Corners of Face", NODE_CLASS_INPUT);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.declare = file_ns::node_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc
new file mode 100644
index 00000000000..c01c4149864
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc
@@ -0,0 +1,219 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
+
+#include "BLI_task.hh"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_mesh_topology_corners_of_vertex_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Int>(N_("Vertex Index"))
+ .implicit_field(implicit_field_inputs::index)
+ .description(
+ N_("The vertex to retrieve data from. Defaults to the vertex from the context"));
+ b.add_input<decl::Float>(N_("Weights"))
+ .supports_field()
+ .hide_value()
+ .description(
+ N_("Values used to sort corners attached to the vertex. Uses indices by default"));
+ b.add_input<decl::Int>(N_("Sort Index"))
+ .min(0)
+ .supports_field()
+ .description(N_("Which of the sorted corners to output"));
+ b.add_output<decl::Int>(N_("Corner Index"))
+ .dependent_field()
+ .description(N_("A corner connected to the face, chosen by the sort index"));
+ b.add_output<decl::Int>(N_("Total"))
+ .dependent_field()
+ .description(N_("The number of faces or corners connected to each vertex"));
+}
+
+static void convert_span(const Span<int> src, MutableSpan<int64_t> dst)
+{
+ for (const int i : src.index_range()) {
+ dst[i] = src[i];
+ }
+}
+
+class CornersOfVertInput final : public bke::MeshFieldInput {
+ const Field<int> vert_index_;
+ const Field<int> sort_index_;
+ const Field<float> sort_weight_;
+
+ public:
+ CornersOfVertInput(Field<int> vert_index, Field<int> sort_index, Field<float> sort_weight)
+ : bke::MeshFieldInput(CPPType::get<int>(), "Corner of Vertex"),
+ vert_index_(std::move(vert_index)),
+ sort_index_(std::move(sort_index)),
+ sort_weight_(std::move(sort_weight))
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const Mesh &mesh,
+ const eAttrDomain domain,
+ const IndexMask mask) const final
+ {
+ const IndexRange vert_range(mesh.totvert);
+ const Span<MLoop> loops = mesh.loops();
+ Array<Vector<int>> vert_to_loop_map = bke::mesh_topology::build_vert_to_loop_map(loops,
+ mesh.totvert);
+
+ const bke::MeshFieldContext context{mesh, domain};
+ fn::FieldEvaluator evaluator{context, &mask};
+ evaluator.add(vert_index_);
+ evaluator.add(sort_index_);
+ evaluator.evaluate();
+ const VArray<int> vert_indices = evaluator.get_evaluated<int>(0);
+ const VArray<int> indices_in_sort = evaluator.get_evaluated<int>(1);
+
+ const bke::MeshFieldContext corner_context{mesh, ATTR_DOMAIN_CORNER};
+ fn::FieldEvaluator corner_evaluator{corner_context, loops.size()};
+ corner_evaluator.add(sort_weight_);
+ corner_evaluator.evaluate();
+ const VArray<float> all_sort_weights = corner_evaluator.get_evaluated<float>(0);
+
+ Array<int> corner_of_vertex(mask.min_array_size());
+ threading::parallel_for(mask.index_range(), 1024, [&](const IndexRange range) {
+ /* Reuse arrays to avoid allocation. */
+ Array<int64_t> corner_indices;
+ Array<float> sort_weights;
+ Array<int> sort_indices;
+
+ for (const int selection_i : mask.slice(range)) {
+ const int vert_i = vert_indices[selection_i];
+ const int index_in_sort = indices_in_sort[selection_i];
+ if (!vert_range.contains(vert_i)) {
+ corner_of_vertex[selection_i] = 0;
+ continue;
+ }
+
+ const Span<int> corners = vert_to_loop_map[vert_i];
+ if (corners.is_empty()) {
+ corner_of_vertex[selection_i] = 0;
+ continue;
+ }
+
+ /* Retrieve the connected edge indices as 64 bit integers for #materialize_compressed. */
+ corner_indices.reinitialize(corners.size());
+ convert_span(corners, corner_indices);
+
+ /* Retrieve a compressed array of weights for each edge. */
+ sort_weights.reinitialize(corners.size());
+ all_sort_weights.materialize_compressed(IndexMask(corner_indices),
+ sort_weights.as_mutable_span());
+
+ /* Sort a separate array of compressed indices corresponding to the compressed weights.
+ * This allows using `materialize_compressed` to avoid virtual function call overhead
+ * when accessing values in the sort weights. However, it means a separate array of
+ * indices within the compressed array is necessary for sorting. */
+ sort_indices.reinitialize(corners.size());
+ std::iota(sort_indices.begin(), sort_indices.end(), 0);
+ std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) {
+ return sort_weights[a] < sort_weights[b];
+ });
+
+ const int index_in_sort_wrapped = mod_i(index_in_sort, corners.size());
+ corner_of_vertex[selection_i] = corner_indices[sort_indices[index_in_sort_wrapped]];
+ }
+ });
+
+ return VArray<int>::ForContainer(std::move(corner_of_vertex));
+ }
+
+ uint64_t hash() const final
+ {
+ return 3541871368173645;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const final
+ {
+ if (const auto *typed = dynamic_cast<const CornersOfVertInput *>(&other)) {
+ return typed->vert_index_ == vert_index_ && typed->sort_index_ == sort_index_ &&
+ typed->sort_weight_ == sort_weight_;
+ }
+ return false;
+ }
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
+};
+
+class CornersOfVertCountInput final : public bke::MeshFieldInput {
+ public:
+ CornersOfVertCountInput() : bke::MeshFieldInput(CPPType::get<int>(), "Vertex Corner Count")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const Mesh &mesh,
+ const eAttrDomain domain,
+ const IndexMask /*mask*/) const final
+ {
+ if (domain != ATTR_DOMAIN_POINT) {
+ return {};
+ }
+ const Span<MLoop> loops = mesh.loops();
+ Array<int> counts(mesh.totvert, 0);
+ for (const int i : loops.index_range()) {
+ counts[loops[i].v]++;
+ }
+ return VArray<int>::ForContainer(std::move(counts));
+ }
+
+ uint64_t hash() const final
+ {
+ return 253098745374645;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const final
+ {
+ if (dynamic_cast<const CornersOfVertCountInput *>(&other)) {
+ return true;
+ }
+ return false;
+ }
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ const Field<int> vert_index = params.extract_input<Field<int>>("Vertex Index");
+ if (params.output_is_required("Total")) {
+ params.set_output("Total",
+ Field<int>(std::make_shared<FieldAtIndexInput>(
+ vert_index,
+ Field<int>(std::make_shared<CornersOfVertCountInput>()),
+ ATTR_DOMAIN_POINT)));
+ }
+ if (params.output_is_required("Corner Index")) {
+ params.set_output("Corner Index",
+ Field<int>(std::make_shared<CornersOfVertInput>(
+ vert_index,
+ params.extract_input<Field<int>>("Sort Index"),
+ params.extract_input<Field<float>>("Weights"))));
+ }
+}
+} // namespace blender::nodes::node_geo_mesh_topology_corners_of_vertex_cc
+
+void register_node_type_geo_mesh_topology_corners_of_vertex()
+{
+ namespace file_ns = blender::nodes::node_geo_mesh_topology_corners_of_vertex_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(
+ &ntype, GEO_NODE_MESH_TOPOLOGY_CORNERS_OF_VERTEX, "Corners of Vertex", NODE_CLASS_INPUT);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.declare = file_ns::node_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc
new file mode 100644
index 00000000000..e46061e0d65
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc
@@ -0,0 +1,146 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
+
+#include "BLI_task.hh"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_mesh_topology_edges_of_corner_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Int>(N_("Corner Index"))
+ .implicit_field(implicit_field_inputs::index)
+ .description(
+ N_("The corner to retrieve data from. Defaults to the corner from the context"));
+ b.add_output<decl::Int>(N_("Next Edge Index"))
+ .dependent_field()
+ .description(
+ N_("The edge after the corner in the face, in the direction of increasing indices"));
+ b.add_output<decl::Int>(N_("Previous Edge Index"))
+ .dependent_field()
+ .description(
+ N_("The edge before the corner in the face, in the direction of decreasing indices"));
+}
+
+static int get_loop_edge(const MLoop &loop)
+{
+ return loop.e;
+}
+
+class CornerNextEdgeFieldInput final : public bke::MeshFieldInput {
+ public:
+ CornerNextEdgeFieldInput() : bke::MeshFieldInput(CPPType::get<int>(), "Corner Next Edge")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const Mesh &mesh,
+ const eAttrDomain domain,
+ const IndexMask /*mask*/) const final
+ {
+ if (domain != ATTR_DOMAIN_CORNER) {
+ return {};
+ }
+ return VArray<int>::ForDerivedSpan<MLoop, get_loop_edge>(mesh.loops());
+ }
+
+ uint64_t hash() const final
+ {
+ return 1892753404495;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const final
+ {
+ if (dynamic_cast<const CornerNextEdgeFieldInput *>(&other)) {
+ return true;
+ }
+ return false;
+ }
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_CORNER;
+ }
+};
+
+class CornerPreviousEdgeFieldInput final : public bke::MeshFieldInput {
+ public:
+ CornerPreviousEdgeFieldInput() : bke::MeshFieldInput(CPPType::get<int>(), "Corner Previous Edge")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const Mesh &mesh,
+ const eAttrDomain domain,
+ const IndexMask /*mask*/) const final
+ {
+ if (domain != ATTR_DOMAIN_CORNER) {
+ return {};
+ }
+ const Span<MPoly> polys = mesh.polys();
+ const Span<MLoop> loops = mesh.loops();
+ Array<int> loop_to_poly_map = bke::mesh_topology::build_loop_to_poly_map(polys, mesh.totloop);
+ return VArray<int>::ForFunc(
+ mesh.totloop,
+ [polys, loops, loop_to_poly_map = std::move(loop_to_poly_map)](const int corner_i) {
+ const int poly_i = loop_to_poly_map[corner_i];
+ const MPoly &poly = polys[poly_i];
+ const int corner_i_prev = bke::mesh_topology::previous_poly_loop(poly, corner_i);
+ return loops[corner_i_prev].e;
+ });
+ }
+
+ uint64_t hash() const final
+ {
+ return 987298345762465;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const final
+ {
+ if (dynamic_cast<const CornerPreviousEdgeFieldInput *>(&other)) {
+ return true;
+ }
+ return false;
+ }
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_CORNER;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ const Field<int> corner_index = params.extract_input<Field<int>>("Corner Index");
+ if (params.output_is_required("Next Edge Index")) {
+ params.set_output("Next Edge Index",
+ Field<int>(std::make_shared<FieldAtIndexInput>(
+ corner_index,
+ Field<int>(std::make_shared<CornerNextEdgeFieldInput>()),
+ ATTR_DOMAIN_CORNER)));
+ }
+ if (params.output_is_required("Previous Edge Index")) {
+ params.set_output("Previous Edge Index",
+ Field<int>(std::make_shared<FieldAtIndexInput>(
+ corner_index,
+ Field<int>(std::make_shared<CornerPreviousEdgeFieldInput>()),
+ ATTR_DOMAIN_CORNER)));
+ }
+}
+
+} // namespace blender::nodes::node_geo_mesh_topology_edges_of_corner_cc
+
+void register_node_type_geo_mesh_topology_edges_of_corner()
+{
+ namespace file_ns = blender::nodes::node_geo_mesh_topology_edges_of_corner_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(
+ &ntype, GEO_NODE_MESH_TOPOLOGY_EDGES_OF_CORNER, "Edges of Corner", NODE_CLASS_INPUT);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.declare = file_ns::node_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc
new file mode 100644
index 00000000000..7aadc15f7f8
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc
@@ -0,0 +1,221 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
+
+#include "BLI_task.hh"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_mesh_topology_edges_of_vertex_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Int>(N_("Vertex Index"))
+ .implicit_field(implicit_field_inputs::index)
+ .description(
+ N_("The vertex to retrieve data from. Defaults to the vertex from the context"));
+ b.add_input<decl::Float>(N_("Weights"))
+ .supports_field()
+ .hide_value()
+ .description(
+ N_("Values used to sort the edges connected to the vertex. Uses indices by default"));
+ b.add_input<decl::Int>(N_("Sort Index"))
+ .min(0)
+ .supports_field()
+ .description(N_("Which of the sorted edges to output"));
+ b.add_output<decl::Int>(N_("Edge Index"))
+ .dependent_field()
+ .description(N_("An edge connected to the face, chosen by the sort index"));
+ b.add_output<decl::Int>(N_("Total"))
+ .dependent_field()
+ .description(N_("The number of edges connected to each vertex"));
+}
+
+static void convert_span(const Span<int> src, MutableSpan<int64_t> dst)
+{
+ for (const int i : src.index_range()) {
+ dst[i] = src[i];
+ }
+}
+
+class EdgesOfVertInput final : public bke::MeshFieldInput {
+ const Field<int> vert_index_;
+ const Field<int> sort_index_;
+ const Field<float> sort_weight_;
+
+ public:
+ EdgesOfVertInput(Field<int> vert_index, Field<int> sort_index, Field<float> sort_weight)
+ : bke::MeshFieldInput(CPPType::get<int>(), "Edge of Vertex"),
+ vert_index_(std::move(vert_index)),
+ sort_index_(std::move(sort_index)),
+ sort_weight_(std::move(sort_weight))
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const Mesh &mesh,
+ const eAttrDomain domain,
+ const IndexMask mask) const final
+ {
+ const IndexRange vert_range(mesh.totvert);
+ const Span<MEdge> edges = mesh.edges();
+ Array<Vector<int>> vert_to_edge_map = bke::mesh_topology::build_vert_to_edge_map(edges,
+ mesh.totvert);
+
+ const bke::MeshFieldContext context{mesh, domain};
+ fn::FieldEvaluator evaluator{context, &mask};
+ evaluator.add(vert_index_);
+ evaluator.add(sort_index_);
+ evaluator.evaluate();
+ const VArray<int> vert_indices = evaluator.get_evaluated<int>(0);
+ const VArray<int> indices_in_sort = evaluator.get_evaluated<int>(1);
+
+ const bke::MeshFieldContext edge_context{mesh, ATTR_DOMAIN_EDGE};
+ fn::FieldEvaluator edge_evaluator{edge_context, mesh.totedge};
+ edge_evaluator.add(sort_weight_);
+ edge_evaluator.evaluate();
+ const VArray<float> all_sort_weights = edge_evaluator.get_evaluated<float>(0);
+
+ Array<int> edge_of_vertex(mask.min_array_size());
+ threading::parallel_for(mask.index_range(), 1024, [&](const IndexRange range) {
+ /* Reuse arrays to avoid allocation. */
+ Array<int64_t> edge_indices;
+ Array<float> sort_weights;
+ Array<int> sort_indices;
+
+ for (const int selection_i : mask.slice(range)) {
+ const int vert_i = vert_indices[selection_i];
+ const int index_in_sort = indices_in_sort[selection_i];
+ if (!vert_range.contains(vert_i)) {
+ edge_of_vertex[selection_i] = 0;
+ continue;
+ }
+
+ const Span<int> edges = vert_to_edge_map[vert_i];
+ if (edges.is_empty()) {
+ edge_of_vertex[selection_i] = 0;
+ continue;
+ }
+
+ /* Retrieve the connected edge indices as 64 bit integers for #materialize_compressed. */
+ edge_indices.reinitialize(edges.size());
+ convert_span(edges, edge_indices);
+
+ /* Retrieve a compressed array of weights for each edge. */
+ sort_weights.reinitialize(edges.size());
+ all_sort_weights.materialize_compressed(IndexMask(edge_indices),
+ sort_weights.as_mutable_span());
+
+ /* Sort a separate array of compressed indices corresponding to the compressed weights.
+ * This allows using `materialize_compressed` to avoid virtual function call overhead
+ * when accessing values in the sort weights. However, it means a separate array of
+ * indices within the compressed array is necessary for sorting. */
+ sort_indices.reinitialize(edges.size());
+ std::iota(sort_indices.begin(), sort_indices.end(), 0);
+ std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) {
+ return sort_weights[a] < sort_weights[b];
+ });
+
+ const int index_in_sort_wrapped = mod_i(index_in_sort, edges.size());
+ edge_of_vertex[selection_i] = edge_indices[sort_indices[index_in_sort_wrapped]];
+ }
+ });
+
+ return VArray<int>::ForContainer(std::move(edge_of_vertex));
+ }
+
+ uint64_t hash() const final
+ {
+ return 98762349875636;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const final
+ {
+ if (const auto *typed = dynamic_cast<const EdgesOfVertInput *>(&other)) {
+ return typed->vert_index_ == vert_index_ && typed->sort_index_ == sort_index_ &&
+ typed->sort_weight_ == sort_weight_;
+ }
+ return false;
+ }
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
+};
+
+class EdgesOfVertCountInput final : public bke::MeshFieldInput {
+ public:
+ EdgesOfVertCountInput() : bke::MeshFieldInput(CPPType::get<int>(), "Corner Face Index")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const Mesh &mesh,
+ const eAttrDomain domain,
+ const IndexMask /*mask*/) const final
+ {
+ if (domain != ATTR_DOMAIN_POINT) {
+ return {};
+ }
+ const Span<MEdge> edges = mesh.edges();
+ Array<int> counts(mesh.totvert, 0);
+ for (const int i : edges.index_range()) {
+ counts[edges[i].v1]++;
+ counts[edges[i].v2]++;
+ }
+ return VArray<int>::ForContainer(std::move(counts));
+ }
+
+ uint64_t hash() const final
+ {
+ return 436758278618374;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const final
+ {
+ if (dynamic_cast<const EdgesOfVertCountInput *>(&other)) {
+ return true;
+ }
+ return false;
+ }
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_POINT;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ const Field<int> vert_index = params.extract_input<Field<int>>("Vertex Index");
+ if (params.output_is_required("Total")) {
+ params.set_output("Total",
+ Field<int>(std::make_shared<FieldAtIndexInput>(
+ vert_index,
+ Field<int>(std::make_shared<EdgesOfVertCountInput>()),
+ ATTR_DOMAIN_POINT)));
+ }
+ if (params.output_is_required("Edge Index")) {
+ params.set_output("Edge Index",
+ Field<int>(std::make_shared<EdgesOfVertInput>(
+ vert_index,
+ params.extract_input<Field<int>>("Sort Index"),
+ params.extract_input<Field<float>>("Weights"))));
+ }
+}
+
+} // namespace blender::nodes::node_geo_mesh_topology_edges_of_vertex_cc
+
+void register_node_type_geo_mesh_topology_edges_of_vertex()
+{
+ namespace file_ns = blender::nodes::node_geo_mesh_topology_edges_of_vertex_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(
+ &ntype, GEO_NODE_MESH_TOPOLOGY_EDGES_OF_VERTEX, "Edges of Vertex", NODE_CLASS_INPUT);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.declare = file_ns::node_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc
new file mode 100644
index 00000000000..2cf7ed2c687
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_mesh_topology_face_of_corner_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Int>(N_("Corner Index"))
+ .implicit_field(implicit_field_inputs::index)
+ .description(
+ N_("The corner to retrieve data from. Defaults to the corner from the context"));
+ b.add_output<decl::Int>(N_("Face Index"))
+ .dependent_field()
+ .description(N_("The index of the face the corner is a part of"));
+ b.add_output<decl::Int>(N_("Index in Face"))
+ .dependent_field()
+ .description(N_("The index of the corner starting from the first corner in the face"));
+}
+
+class CornerFaceIndexInput final : public bke::MeshFieldInput {
+ public:
+ CornerFaceIndexInput() : bke::MeshFieldInput(CPPType::get<int>(), "Corner Face Index")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const Mesh &mesh,
+ const eAttrDomain domain,
+ const IndexMask /*mask*/) const final
+ {
+ if (domain != ATTR_DOMAIN_CORNER) {
+ return {};
+ }
+ return VArray<int>::ForContainer(
+ bke::mesh_topology::build_loop_to_poly_map(mesh.polys(), mesh.totloop));
+ }
+
+ uint64_t hash() const final
+ {
+ return 2348712958475728;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const final
+ {
+ return dynamic_cast<const CornerFaceIndexInput *>(&other) != nullptr;
+ }
+};
+
+class CornerIndexInFaceInput final : public bke::MeshFieldInput {
+ public:
+ CornerIndexInFaceInput() : bke::MeshFieldInput(CPPType::get<int>(), "Corner Index In Face")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const Mesh &mesh,
+ const eAttrDomain domain,
+ const IndexMask /*mask*/) const final
+ {
+ if (domain != ATTR_DOMAIN_CORNER) {
+ return {};
+ }
+ const Span<MPoly> polys = mesh.polys();
+ Array<int> loop_to_poly_map = bke::mesh_topology::build_loop_to_poly_map(polys, mesh.totloop);
+ return VArray<int>::ForFunc(
+ mesh.totloop, [polys, loop_to_poly_map = std::move(loop_to_poly_map)](const int corner_i) {
+ const int poly_i = loop_to_poly_map[corner_i];
+ return corner_i - polys[poly_i].loopstart;
+ });
+ }
+
+ uint64_t hash() const final
+ {
+ return 97837176448;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const final
+ {
+ if (dynamic_cast<const CornerIndexInFaceInput *>(&other)) {
+ return true;
+ }
+ return false;
+ }
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_CORNER;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ const Field<int> corner_index = params.extract_input<Field<int>>("Corner Index");
+ if (params.output_is_required("Face Index")) {
+ params.set_output("Face Index",
+ Field<int>(std::make_shared<FieldAtIndexInput>(
+ corner_index,
+ Field<int>(std::make_shared<CornerFaceIndexInput>()),
+ ATTR_DOMAIN_CORNER)));
+ }
+ if (params.output_is_required("Index in Face")) {
+ params.set_output("Index in Face",
+ Field<int>(std::make_shared<FieldAtIndexInput>(
+ corner_index,
+ Field<int>(std::make_shared<CornerIndexInFaceInput>()),
+ ATTR_DOMAIN_CORNER)));
+ }
+}
+
+} // namespace blender::nodes::node_geo_mesh_topology_face_of_corner_cc
+
+void register_node_type_geo_mesh_topology_face_of_corner()
+{
+ namespace file_ns = blender::nodes::node_geo_mesh_topology_face_of_corner_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(
+ &ntype, GEO_NODE_MESH_TOPOLOGY_FACE_OF_CORNER, "Face of Corner", NODE_CLASS_INPUT);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.declare = file_ns::node_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc
new file mode 100644
index 00000000000..ef5c9a445f2
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
+
+#include "BLI_task.hh"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_mesh_topology_offset_corner_in_face_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Int>(N_("Corner Index"))
+ .implicit_field(implicit_field_inputs::index)
+ .description(
+ N_("The corner to retrieve data from. Defaults to the corner from the context"));
+ b.add_input<decl::Int>(N_("Offset"))
+ .supports_field()
+ .description(N_("The number of corners to move around the face before finding the result, "
+ "circling around the start of the face if necessary"));
+ b.add_output<decl::Int>(N_("Corner Index"))
+ .dependent_field()
+ .description(N_("The index of the offset corner"));
+}
+
+class OffsetCornerInFaceFieldInput final : public bke::MeshFieldInput {
+ const Field<int> corner_index_;
+ const Field<int> offset_;
+
+ public:
+ OffsetCornerInFaceFieldInput(Field<int> corner_index, Field<int> offset)
+ : bke::MeshFieldInput(CPPType::get<int>(), "Offset Corner in Face"),
+ corner_index_(std::move(corner_index)),
+ offset_(std::move(offset))
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const Mesh &mesh,
+ const eAttrDomain domain,
+ const IndexMask mask) const final
+ {
+ const IndexRange corner_range(mesh.totloop);
+ const Span<MPoly> polys = mesh.polys();
+
+ const bke::MeshFieldContext context{mesh, domain};
+ fn::FieldEvaluator evaluator{context, &mask};
+ evaluator.add(corner_index_);
+ evaluator.add(offset_);
+ evaluator.evaluate();
+ const VArray<int> corner_indices = evaluator.get_evaluated<int>(0);
+ const VArray<int> offsets = evaluator.get_evaluated<int>(1);
+
+ Array<int> loop_to_poly_map = bke::mesh_topology::build_loop_to_poly_map(polys, mesh.totloop);
+
+ Array<int> offset_corners(mask.min_array_size());
+ threading::parallel_for(mask.index_range(), 2048, [&](const IndexRange range) {
+ for (const int selection_i : range) {
+ const int corner_i = corner_indices[selection_i];
+ const int offset = offsets[selection_i];
+ if (!corner_range.contains(corner_i)) {
+ offset_corners[selection_i] = 0;
+ continue;
+ }
+
+ const int poly_i = loop_to_poly_map[corner_i];
+ const IndexRange poly_range(polys[poly_i].loopstart, polys[poly_i].totloop);
+ offset_corners[selection_i] = apply_offset_in_cyclic_range(poly_range, corner_i, offset);
+ }
+ });
+
+ return VArray<int>::ForContainer(std::move(offset_corners));
+ }
+
+ uint64_t hash() const final
+ {
+ return get_default_hash(offset_);
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const final
+ {
+ if (const OffsetCornerInFaceFieldInput *other_field =
+ dynamic_cast<const OffsetCornerInFaceFieldInput *>(&other)) {
+ return other_field->corner_index_ == corner_index_ && other_field->offset_ == offset_;
+ }
+ return false;
+ }
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_CORNER;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ params.set_output("Corner Index",
+ Field<int>(std::make_shared<OffsetCornerInFaceFieldInput>(
+ params.extract_input<Field<int>>("Corner Index"),
+ params.extract_input<Field<int>>("Offset"))));
+}
+
+} // namespace blender::nodes::node_geo_mesh_topology_offset_corner_in_face_cc
+
+void register_node_type_geo_mesh_topology_offset_corner_in_face()
+{
+ namespace file_ns = blender::nodes::node_geo_mesh_topology_offset_corner_in_face_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(&ntype,
+ GEO_NODE_MESH_TOPOLOGY_OFFSET_CORNER_IN_FACE,
+ "Offset Corner in Face",
+ NODE_CLASS_INPUT);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.declare = file_ns::node_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc
new file mode 100644
index 00000000000..9f730367931
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BKE_mesh.h"
+
+#include "BLI_task.hh"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_mesh_topology_vertex_of_corner_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Int>(N_("Corner Index"))
+ .implicit_field(implicit_field_inputs::index)
+ .description(
+ N_("The corner to retrieve data from. Defaults to the corner from the context"));
+ b.add_output<decl::Int>(N_("Vertex Index"))
+ .dependent_field()
+ .description(N_("The vertex the corner is attached to"));
+}
+
+static int get_loop_vert(const MLoop &loop)
+{
+ return loop.v;
+}
+
+class CornerVertFieldInput final : public bke::MeshFieldInput {
+ public:
+ CornerVertFieldInput() : bke::MeshFieldInput(CPPType::get<int>(), "Corner Vertex")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const Mesh &mesh,
+ const eAttrDomain domain,
+ const IndexMask /*mask*/) const final
+ {
+ if (domain != ATTR_DOMAIN_CORNER) {
+ return {};
+ }
+ return VArray<int>::ForDerivedSpan<MLoop, get_loop_vert>(mesh.loops());
+ }
+
+ uint64_t hash() const final
+ {
+ return 30495867093876;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const final
+ {
+ if (dynamic_cast<const CornerVertFieldInput *>(&other)) {
+ return true;
+ }
+ return false;
+ }
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
+ {
+ return ATTR_DOMAIN_CORNER;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ params.set_output("Vertex Index",
+ Field<int>(std::make_shared<FieldAtIndexInput>(
+ params.extract_input<Field<int>>("Corner Index"),
+ Field<int>(std::make_shared<CornerVertFieldInput>()),
+ ATTR_DOMAIN_CORNER)));
+}
+
+} // namespace blender::nodes::node_geo_mesh_topology_vertex_of_corner_cc
+
+void register_node_type_geo_mesh_topology_vertex_of_corner()
+{
+ namespace file_ns = blender::nodes::node_geo_mesh_topology_vertex_of_corner_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(
+ &ntype, GEO_NODE_MESH_TOPOLOGY_VERTEX_OF_CORNER, "Vertex of Corner", NODE_CLASS_INPUT);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.declare = file_ns::node_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_object_info.cc b/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
index 691988249df..f1a9987e721 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
@@ -3,6 +3,7 @@
#include "BLI_math_matrix.h"
#include "BKE_geometry_set_instances.hh"
+#include "BKE_instances.hh"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -25,7 +26,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "transform_space", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
@@ -44,8 +45,8 @@ static void node_geo_exec(GeoNodeExecParams params)
return;
}
- const float4x4 &object_matrix = object->obmat;
- const float4x4 transform = float4x4(self_object->imat) * object_matrix;
+ const float4x4 &object_matrix = object->object_to_world;
+ const float4x4 transform = float4x4(self_object->world_to_object) * object_matrix;
if (transform_space_relative) {
params.set_output("Location", transform.translation());
@@ -68,14 +69,15 @@ static void node_geo_exec(GeoNodeExecParams params)
GeometrySet geometry_set;
if (params.get_input<bool>("As Instance")) {
- InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
- const int handle = instances.add_reference(*object);
+ std::unique_ptr<bke::Instances> instances = std::make_unique<bke::Instances>();
+ const int handle = instances->add_reference(*object);
if (transform_space_relative) {
- instances.add_instance(handle, transform);
+ instances->add_instance(handle, transform);
}
else {
- instances.add_instance(handle, float4x4::identity());
+ instances->add_instance(handle, float4x4::identity());
}
+ geometry_set = GeometrySet::create_with_instances(instances.release());
}
else {
geometry_set = bke::object_get_evaluated_geometry_set(*object);
@@ -88,7 +90,7 @@ static void node_geo_exec(GeoNodeExecParams params)
}
}
-static void node_node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryObjectInfo *data = MEM_cnew<NodeGeometryObjectInfo>(__func__);
data->transform_space = GEO_NODE_TRANSFORM_SPACE_ORIGINAL;
@@ -104,7 +106,7 @@ void register_node_type_geo_object_info()
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_OBJECT_INFO, "Object Info", NODE_CLASS_INPUT);
- node_type_init(&ntype, file_ns::node_node_init);
+ ntype.initfunc = file_ns::node_node_init;
node_type_storage(
&ntype, "NodeGeometryObjectInfo", node_free_standard_storage, node_copy_standard_storage);
ntype.geometry_node_execute = file_ns::node_geo_exec;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc
new file mode 100644
index 00000000000..d71e27e0385
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc
@@ -0,0 +1,169 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BLI_task.hh"
+
+#include "BKE_curves.hh"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes {
+
+int apply_offset_in_cyclic_range(const IndexRange range, const int start_index, const int offset)
+{
+ BLI_assert(range.contains(start_index));
+ const int start_in_range = start_index - range.first();
+ const int offset_in_range = start_in_range + offset;
+ const int mod_offset = offset_in_range % range.size();
+ if (mod_offset >= 0) {
+ return range[mod_offset];
+ }
+ return range.last(-(mod_offset + 1));
+}
+
+} // namespace blender::nodes
+
+namespace blender::nodes::node_geo_offset_point_in_curve_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Int>(N_("Point Index"))
+ .implicit_field(implicit_field_inputs::index)
+ .description(
+ N_("The index of the control point to evaluate. Defaults to the current index"));
+ b.add_input<decl::Int>(N_("Offset"))
+ .supports_field()
+ .description(N_("The number of control points along the curve to traverse"));
+ b.add_output<decl::Bool>(N_("Is Valid Offset"))
+ .dependent_field()
+ .description(N_("Outputs true if the evaluated control point plus the offset "
+ "is a valid index of the original curve"));
+ b.add_output<decl::Int>(N_("Point Index"))
+ .dependent_field()
+ .description(N_("The index of the control point plus the offset within the entire "
+ "curves data-block"));
+}
+
+class ControlPointNeighborFieldInput final : public bke::CurvesFieldInput {
+ private:
+ const Field<int> index_;
+ const Field<int> offset_;
+
+ public:
+ ControlPointNeighborFieldInput(Field<int> index, Field<int> offset)
+ : CurvesFieldInput(CPPType::get<int>(), "Offset Point in Curve"),
+ index_(std::move(index)),
+ offset_(std::move(offset))
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
+ const eAttrDomain domain,
+ const IndexMask mask) const final
+ {
+ const VArray<bool> cyclic = curves.cyclic();
+ const Array<int> parent_curves = curves.point_to_curve_map();
+
+ const bke::CurvesFieldContext context{curves, domain};
+ fn::FieldEvaluator evaluator{context, &mask};
+ evaluator.add(index_);
+ evaluator.add(offset_);
+ evaluator.evaluate();
+ const VArray<int> indices = evaluator.get_evaluated<int>(0);
+ const VArray<int> offsets = evaluator.get_evaluated<int>(1);
+
+ Array<int> output(mask.min_array_size());
+ for (const int i_selection : mask) {
+ const int i_point = std::clamp(indices[i_selection], 0, curves.points_num() - 1);
+ const int i_curve = parent_curves[i_point];
+ const IndexRange curve_points = curves.points_for_curve(i_curve);
+ const int offset_point = i_point + offsets[i_point];
+
+ if (cyclic[i_curve]) {
+ output[i_selection] = apply_offset_in_cyclic_range(
+ curve_points, i_point, offsets[i_selection]);
+ continue;
+ }
+ output[i_selection] = std::clamp(offset_point, 0, curves.points_num() - 1);
+ }
+
+ return VArray<int>::ForContainer(std::move(output));
+ }
+};
+
+class OffsetValidFieldInput final : public bke::CurvesFieldInput {
+ private:
+ const Field<int> index_;
+ const Field<int> offset_;
+
+ public:
+ OffsetValidFieldInput(Field<int> index, Field<int> offset)
+ : CurvesFieldInput(CPPType::get<bool>(), "Offset Valid"),
+ index_(std::move(index)),
+ offset_(std::move(offset))
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
+ const eAttrDomain domain,
+ const IndexMask mask) const final
+ {
+ const VArray<bool> cyclic = curves.cyclic();
+ const Array<int> parent_curves = curves.point_to_curve_map();
+
+ const bke::CurvesFieldContext context{curves, domain};
+ fn::FieldEvaluator evaluator{context, &mask};
+ evaluator.add(index_);
+ evaluator.add(offset_);
+ evaluator.evaluate();
+ const VArray<int> indices = evaluator.get_evaluated<int>(0);
+ const VArray<int> offsets = evaluator.get_evaluated<int>(1);
+
+ Array<bool> output(mask.min_array_size());
+ for (const int i_selection : mask) {
+ const int i_point = indices[i_selection];
+ if (!curves.points_range().contains(i_point)) {
+ output[i_selection] = false;
+ continue;
+ }
+
+ const int i_curve = parent_curves[i_point];
+ const IndexRange curve_points = curves.points_for_curve(i_curve);
+ if (cyclic[i_curve]) {
+ output[i_selection] = true;
+ continue;
+ }
+ output[i_selection] = curve_points.contains(i_point + offsets[i_selection]);
+ };
+ return VArray<bool>::ForContainer(std::move(output));
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ Field<int> index = params.extract_input<Field<int>>("Point Index");
+ Field<int> offset = params.extract_input<Field<int>>("Offset");
+
+ if (params.output_is_required("Point Index")) {
+ Field<int> curve_point_field{std::make_shared<ControlPointNeighborFieldInput>(index, offset)};
+ params.set_output("Point Index", std::move(curve_point_field));
+ }
+ if (params.output_is_required("Is Valid Offset")) {
+ Field<bool> valid_field{std::make_shared<OffsetValidFieldInput>(index, offset)};
+ params.set_output("Is Valid Offset", std::move(valid_field));
+ }
+}
+
+} // namespace blender::nodes::node_geo_offset_point_in_curve_cc
+
+void register_node_type_geo_offset_point_in_curve()
+{
+ namespace file_ns = blender::nodes::node_geo_offset_point_in_curve_cc;
+ static bNodeType ntype;
+ geo_node_type_base(
+ &ntype, GEO_NODE_OFFSET_POINT_IN_CURVE, "Offset Point in Curve", NODE_CLASS_INPUT);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.declare = file_ns::node_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_points.cc b/source/blender/nodes/geometry/nodes/node_geo_points.cc
index 4a294076834..dcbe176b384 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_points.cc
@@ -20,9 +20,10 @@ static void node_declare(NodeDeclarationBuilder &b)
.default_value(float3(0.0f))
.description(N_("The positions of the new points"));
b.add_input<decl::Float>(N_("Radius"))
+ .min(0.0f)
+ .default_value(0.1f)
.supports_field()
.subtype(PROP_DISTANCE)
- .default_value(float(0.1f))
.description(N_("The radii of the new points"));
b.add_output<decl::Geometry>(N_("Geometry"));
}
@@ -43,7 +44,7 @@ class PointsFieldContext : public FieldContext {
GVArray get_varray_for_input(const FieldInput &field_input,
const IndexMask mask,
- ResourceScope &UNUSED(scope)) const
+ ResourceScope & /*scope*/) const
{
const bke::IDAttributeFieldInput *id_field_input =
dynamic_cast<const bke::IDAttributeFieldInput *>(&field_input);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
index ba6bd40a6b6..d0b7f6a455f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
@@ -43,14 +43,14 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Volume"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
uiItemR(layout, ptr, "resolution_mode", 0, IFACE_("Resolution"), ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryPointsToVolume *data = MEM_cnew<NodeGeometryPointsToVolume>(__func__);
data->resolution_mode = GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_AMOUNT;
@@ -83,7 +83,7 @@ struct ParticleList {
size_t size() const
{
- return (size_t)positions.size();
+ return size_t(positions.size());
}
void getPos(size_t n, openvdb::Vec3R &xyz) const
@@ -215,7 +215,7 @@ static void initialize_volume_component_from_points(GeoNodeExecParams &params,
return;
}
- Volume *volume = (Volume *)BKE_id_new_nomain(ID_VO, nullptr);
+ Volume *volume = reinterpret_cast<Volume *>(BKE_id_new_nomain(ID_VO, nullptr));
BKE_volume_init_grids(volume);
const float density = params.get_input<float>("Density");
@@ -231,17 +231,16 @@ static void initialize_volume_component_from_points(GeoNodeExecParams &params,
static void node_geo_exec(GeoNodeExecParams params)
{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Points");
-
#ifdef WITH_OPENVDB
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Points");
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
initialize_volume_component_from_points(params, geometry_set);
});
params.set_output("Volume", std::move(geometry_set));
#else
+ params.set_default_remaining_outputs();
params.error_message_add(NodeWarningType::Error,
TIP_("Disabled, Blender was compiled without OpenVDB"));
- params.set_default_remaining_outputs();
#endif
}
@@ -259,8 +258,8 @@ void register_node_type_geo_points_to_volume()
node_free_standard_storage,
node_copy_standard_storage);
node_type_size(&ntype, 170, 120, 700);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
ntype.declare = file_ns::node_declare;
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.draw_buttons = file_ns::node_layout;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_proximity.cc b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc
index d5233ee35a4..92a409f9db6 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_proximity.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc
@@ -22,17 +22,17 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Geometry>(N_("Target"))
.only_realized_data()
.supported_type({GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD});
- b.add_input<decl::Vector>(N_("Source Position")).implicit_field();
+ b.add_input<decl::Vector>(N_("Source Position")).implicit_field(implicit_field_inputs::position);
b.add_output<decl::Vector>(N_("Position")).dependent_field();
b.add_output<decl::Float>(N_("Distance")).dependent_field();
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "target_element", 0, "", ICON_NONE);
}
-static void geo_proximity_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void geo_proximity_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryProximity *node_storage = MEM_cnew<NodeGeometryProximity>(__func__);
node_storage->target_element = GEO_NODE_PROX_TARGET_FACES;
@@ -151,7 +151,7 @@ class ProximityFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<float3> &src_positions = params.readonly_single_input<float3>(0,
"Source Position");
@@ -211,8 +211,7 @@ static void node_geo_exec(GeoNodeExecParams params)
Field<float3> position_field = params.extract_input<Field<float3>>("Source Position");
auto proximity_fn = std::make_unique<ProximityFunction>(
- std::move(geometry_set_target),
- static_cast<GeometryNodeProximityTargetType>(storage.target_element));
+ std::move(geometry_set_target), GeometryNodeProximityTargetType(storage.target_element));
auto proximity_op = std::make_shared<FieldOperation>(
FieldOperation(std::move(proximity_fn), {std::move(position_field)}));
@@ -229,7 +228,7 @@ void register_node_type_geo_proximity()
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_PROXIMITY, "Geometry Proximity", NODE_CLASS_GEOMETRY);
- node_type_init(&ntype, file_ns::geo_proximity_init);
+ ntype.initfunc = file_ns::geo_proximity_init;
node_type_storage(
&ntype, "NodeGeometryProximity", node_free_standard_storage, node_copy_standard_storage);
ntype.declare = file_ns::node_declare;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc
index f657b128c51..b3dbc9ee866 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc
@@ -31,7 +31,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Bool>(N_("Attribute"), "Attribute_003").hide_value().supports_field();
b.add_input<decl::Int>(N_("Attribute"), "Attribute_004").hide_value().supports_field();
- b.add_input<decl::Vector>(N_("Source Position")).implicit_field();
+ b.add_input<decl::Vector>(N_("Source Position")).implicit_field(implicit_field_inputs::position);
b.add_input<decl::Vector>(N_("Ray Direction"))
.default_value({0.0f, 0.0f, -1.0f})
.supports_field();
@@ -53,13 +53,13 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Int>(N_("Attribute"), "Attribute_004").dependent_field({1, 2, 3, 4, 5, 6});
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
uiItemR(layout, ptr, "mapping", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryRaycast *data = MEM_cnew<NodeGeometryRaycast>(__func__);
data->mapping = GEO_NODE_RAYCAST_INTERPOLATED;
@@ -70,9 +70,9 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryRaycast &storage = node_storage(*node);
- const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
+ const eCustomDataType data_type = eCustomDataType(storage.data_type);
- bNodeSocket *socket_vector = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
+ bNodeSocket *socket_vector = static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 1));
bNodeSocket *socket_float = socket_vector->next;
bNodeSocket *socket_color4f = socket_float->next;
bNodeSocket *socket_boolean = socket_color4f->next;
@@ -84,7 +84,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, socket_boolean, data_type == CD_PROP_BOOL);
nodeSetSocketAvailability(ntree, socket_int32, data_type == CD_PROP_INT32);
- bNodeSocket *out_socket_vector = (bNodeSocket *)BLI_findlink(&node->outputs, 4);
+ bNodeSocket *out_socket_vector = static_cast<bNodeSocket *>(BLI_findlink(&node->outputs, 4));
bNodeSocket *out_socket_float = out_socket_vector->next;
bNodeSocket *out_socket_color4f = out_socket_float->next;
bNodeSocket *out_socket_boolean = out_socket_color4f->next;
@@ -245,7 +245,7 @@ class RaycastFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
/* Hit positions are always necessary for retrieving the attribute from the target if that
* output is required, so always retrieve a span from the evaluator in that case (it's
@@ -386,8 +386,8 @@ static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet target = params.extract_input<GeometrySet>("Target Geometry");
const NodeGeometryRaycast &storage = node_storage(params.node());
- const GeometryNodeRaycastMapMode mapping = (GeometryNodeRaycastMapMode)storage.mapping;
- const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
+ const GeometryNodeRaycastMapMode mapping = GeometryNodeRaycastMapMode(storage.mapping);
+ const eCustomDataType data_type = eCustomDataType(storage.data_type);
if (target.is_empty()) {
params.set_default_remaining_outputs();
@@ -435,8 +435,8 @@ void register_node_type_geo_raycast()
geo_node_type_base(&ntype, GEO_NODE_RAYCAST, "Raycast", NODE_CLASS_GEOMETRY);
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
node_type_storage(
&ntype, "NodeGeometryRaycast", node_free_standard_storage, node_copy_standard_storage);
ntype.declare = file_ns::node_declare;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc
index 1c72d73d151..3ccc8afb0a7 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc
@@ -15,7 +15,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "legacy_behavior", 0, nullptr, ICON_NONE);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc
index 4ed94e67e74..fac92a7500c 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc
@@ -2,6 +2,8 @@
#include "BLI_task.hh"
+#include "BKE_instances.hh"
+
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_rotate_instances_cc {
@@ -16,10 +18,10 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Instances"));
}
-static void rotate_instances(GeoNodeExecParams &params, InstancesComponent &instances_component)
+static void rotate_instances(GeoNodeExecParams &params, bke::Instances &instances)
{
- const bke::InstancesFieldContext context{instances_component};
- fn::FieldEvaluator evaluator{context, instances_component.instances_num()};
+ const bke::InstancesFieldContext context{instances};
+ fn::FieldEvaluator evaluator{context, instances.instances_num()};
evaluator.set_selection(params.extract_input<Field<bool>>("Selection"));
evaluator.add(params.extract_input<Field<float3>>("Rotation"));
evaluator.add(params.extract_input<Field<float3>>("Pivot Point"));
@@ -31,14 +33,14 @@ static void rotate_instances(GeoNodeExecParams &params, InstancesComponent &inst
const VArray<float3> pivots = evaluator.get_evaluated<float3>(1);
const VArray<bool> local_spaces = evaluator.get_evaluated<bool>(2);
- MutableSpan<float4x4> instance_transforms = instances_component.instance_transforms();
+ MutableSpan<float4x4> transforms = instances.transforms();
threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) {
for (const int i_selection : range) {
const int i = selection[i_selection];
const float3 pivot = pivots[i];
const float3 euler = rotations[i];
- float4x4 &instance_transform = instance_transforms[i];
+ float4x4 &instance_transform = transforms[i];
float4x4 rotation_matrix;
float3 used_pivot;
@@ -81,9 +83,8 @@ static void rotate_instances(GeoNodeExecParams &params, InstancesComponent &inst
static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Instances");
- if (geometry_set.has_instances()) {
- InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
- rotate_instances(params, instances);
+ if (bke::Instances *instances = geometry_set.get_instances_for_write()) {
+ rotate_instances(params, *instances);
}
params.set_output("Instances", std::move(geometry_set));
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc
new file mode 100644
index 00000000000..22c18504985
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc
@@ -0,0 +1,337 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BLI_task.hh"
+
+#include "BKE_attribute_math.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "NOD_socket_search_link.hh"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_sample_index_cc {
+
+NODE_STORAGE_FUNCS(NodeGeometrySampleIndex);
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>(N_("Geometry"))
+ .supported_type({GEO_COMPONENT_TYPE_MESH,
+ GEO_COMPONENT_TYPE_POINT_CLOUD,
+ GEO_COMPONENT_TYPE_CURVE,
+ GEO_COMPONENT_TYPE_INSTANCES});
+
+ b.add_input<decl::Float>(N_("Value"), "Value_Float").hide_value().supports_field();
+ b.add_input<decl::Int>(N_("Value"), "Value_Int").hide_value().supports_field();
+ b.add_input<decl::Vector>(N_("Value"), "Value_Vector").hide_value().supports_field();
+ b.add_input<decl::Color>(N_("Value"), "Value_Color").hide_value().supports_field();
+ b.add_input<decl::Bool>(N_("Value"), "Value_Bool").hide_value().supports_field();
+ b.add_input<decl::Int>(N_("Index"))
+ .supports_field()
+ .description(N_("Which element to retrieve a value from on the geometry"));
+
+ b.add_output<decl::Float>(N_("Value"), "Value_Float").dependent_field({6});
+ b.add_output<decl::Int>(N_("Value"), "Value_Int").dependent_field({6});
+ b.add_output<decl::Vector>(N_("Value"), "Value_Vector").dependent_field({6});
+ b.add_output<decl::Color>(N_("Value"), "Value_Color").dependent_field({6});
+ b.add_output<decl::Bool>(N_("Value"), "Value_Bool").dependent_field({6});
+}
+
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
+ uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
+ uiItemR(layout, ptr, "clamp", 0, nullptr, ICON_NONE);
+}
+
+static void node_init(bNodeTree * /*tree*/, bNode *node)
+{
+ NodeGeometrySampleIndex *data = MEM_cnew<NodeGeometrySampleIndex>(__func__);
+ data->data_type = CD_PROP_FLOAT;
+ data->domain = ATTR_DOMAIN_POINT;
+ data->clamp = 0;
+ node->storage = data;
+}
+
+static void node_update(bNodeTree *ntree, bNode *node)
+{
+ const eCustomDataType data_type = eCustomDataType(node_storage(*node).data_type);
+
+ bNodeSocket *in_socket_geometry = static_cast<bNodeSocket *>(node->inputs.first);
+ bNodeSocket *in_socket_float = in_socket_geometry->next;
+ bNodeSocket *in_socket_int32 = in_socket_float->next;
+ bNodeSocket *in_socket_vector = in_socket_int32->next;
+ bNodeSocket *in_socket_color4f = in_socket_vector->next;
+ bNodeSocket *in_socket_bool = in_socket_color4f->next;
+
+ nodeSetSocketAvailability(ntree, in_socket_vector, data_type == CD_PROP_FLOAT3);
+ nodeSetSocketAvailability(ntree, in_socket_float, data_type == CD_PROP_FLOAT);
+ nodeSetSocketAvailability(ntree, in_socket_color4f, data_type == CD_PROP_COLOR);
+ nodeSetSocketAvailability(ntree, in_socket_bool, data_type == CD_PROP_BOOL);
+ nodeSetSocketAvailability(ntree, in_socket_int32, data_type == CD_PROP_INT32);
+
+ bNodeSocket *out_socket_float = static_cast<bNodeSocket *>(node->outputs.first);
+ bNodeSocket *out_socket_int32 = out_socket_float->next;
+ bNodeSocket *out_socket_vector = out_socket_int32->next;
+ bNodeSocket *out_socket_color4f = out_socket_vector->next;
+ bNodeSocket *out_socket_bool = out_socket_color4f->next;
+
+ nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3);
+ nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT);
+ nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR);
+ nodeSetSocketAvailability(ntree, out_socket_bool, data_type == CD_PROP_BOOL);
+ nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32);
+}
+
+static void node_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+ const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
+ search_link_ops_for_declarations(params, declaration.inputs().take_back(1));
+ search_link_ops_for_declarations(params, declaration.inputs().take_front(1));
+
+ const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type(
+ (eNodeSocketDatatype)params.other_socket().type);
+ if (type && *type != CD_PROP_STRING) {
+ /* The input and output sockets have the same name. */
+ params.add_item(IFACE_("Value"), [type](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("GeometryNodeSampleIndex");
+ node_storage(node).data_type = *type;
+ params.update_and_connect_available_socket(node, "Value");
+ });
+ }
+}
+
+static bool component_is_available(const GeometrySet &geometry,
+ const GeometryComponentType type,
+ const eAttrDomain domain)
+{
+ if (!geometry.has(type)) {
+ return false;
+ }
+ const GeometryComponent &component = *geometry.get_component_for_read(type);
+ if (component.is_empty()) {
+ return false;
+ }
+ return component.attribute_domain_size(domain) != 0;
+}
+
+static const GeometryComponent *find_source_component(const GeometrySet &geometry,
+ const eAttrDomain domain)
+{
+ /* Choose the other component based on a consistent order, rather than some more complicated
+ * heuristic. This is the same order visible in the spreadsheet and used in the ray-cast node. */
+ static const Array<GeometryComponentType> supported_types = {GEO_COMPONENT_TYPE_MESH,
+ GEO_COMPONENT_TYPE_POINT_CLOUD,
+ GEO_COMPONENT_TYPE_CURVE,
+ GEO_COMPONENT_TYPE_INSTANCES};
+ for (const GeometryComponentType src_type : supported_types) {
+ if (component_is_available(geometry, src_type, domain)) {
+ return geometry.get_component_for_read(src_type);
+ }
+ }
+
+ return nullptr;
+}
+
+template<typename T>
+void copy_with_indices(const VArray<T> &src,
+ const VArray<int> &indices,
+ const IndexMask mask,
+ MutableSpan<T> dst)
+{
+ const IndexRange src_range = src.index_range();
+ devirtualize_varray2(src, indices, [&](const auto src, const auto indices) {
+ threading::parallel_for(mask.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : mask.slice(range)) {
+ const int index = indices[i];
+ if (src_range.contains(index)) {
+ dst[i] = src[index];
+ }
+ else {
+ dst[i] = {};
+ }
+ }
+ });
+ });
+}
+
+template<typename T>
+void copy_with_clamped_indices(const VArray<T> &src,
+ const VArray<int> &indices,
+ const IndexMask mask,
+ MutableSpan<T> dst)
+{
+ const int last_index = src.index_range().last();
+ devirtualize_varray2(src, indices, [&](const auto src, const auto indices) {
+ threading::parallel_for(mask.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : mask.slice(range)) {
+ const int index = indices[i];
+ dst[i] = src[std::clamp(index, 0, last_index)];
+ }
+ });
+ });
+}
+
+/**
+ * The index-based transfer theoretically does not need realized data when there is only one
+ * instance geometry set in the source. A future optimization could be removing that limitation
+ * internally.
+ */
+class SampleIndexFunction : public fn::MultiFunction {
+ GeometrySet src_geometry_;
+ GField src_field_;
+ eAttrDomain domain_;
+ bool clamp_;
+
+ fn::MFSignature signature_;
+
+ std::optional<bke::GeometryFieldContext> geometry_context_;
+ std::unique_ptr<FieldEvaluator> evaluator_;
+ const GVArray *src_data_ = nullptr;
+
+ public:
+ SampleIndexFunction(GeometrySet geometry,
+ GField src_field,
+ const eAttrDomain domain,
+ const bool clamp)
+ : src_geometry_(std::move(geometry)),
+ src_field_(std::move(src_field)),
+ domain_(domain),
+ clamp_(clamp)
+ {
+ src_geometry_.ensure_owns_direct_data();
+
+ signature_ = this->create_signature();
+ this->set_signature(&signature_);
+
+ this->evaluate_field();
+ }
+
+ fn::MFSignature create_signature()
+ {
+ fn::MFSignatureBuilder signature{"Sample Index"};
+ signature.single_input<int>("Index");
+ signature.single_output("Value", src_field_.cpp_type());
+ return signature.build();
+ }
+
+ void evaluate_field()
+ {
+ const GeometryComponent *component = find_source_component(src_geometry_, domain_);
+ if (component == nullptr) {
+ return;
+ }
+ const int domain_num = component->attribute_domain_size(domain_);
+ geometry_context_.emplace(bke::GeometryFieldContext(*component, domain_));
+ evaluator_ = std::make_unique<FieldEvaluator>(*geometry_context_, domain_num);
+ evaluator_->add(src_field_);
+ evaluator_->evaluate();
+ src_data_ = &evaluator_->get_evaluated(0);
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
+ {
+ const VArray<int> &indices = params.readonly_single_input<int>(0, "Index");
+ GMutableSpan dst = params.uninitialized_single_output(1, "Value");
+
+ const CPPType &type = dst.type();
+ if (src_data_ == nullptr) {
+ type.value_initialize_indices(dst.data(), mask);
+ return;
+ }
+
+ attribute_math::convert_to_static_type(type, [&](auto dummy) {
+ using T = decltype(dummy);
+ if (clamp_) {
+ copy_with_clamped_indices(src_data_->typed<T>(), indices, mask, dst.typed<T>());
+ }
+ else {
+ copy_with_indices(src_data_->typed<T>(), indices, mask, dst.typed<T>());
+ }
+ });
+ }
+};
+
+static GField get_input_attribute_field(GeoNodeExecParams &params, const eCustomDataType data_type)
+{
+ switch (data_type) {
+ case CD_PROP_FLOAT:
+ return params.extract_input<Field<float>>("Value_Float");
+ case CD_PROP_FLOAT3:
+ return params.extract_input<Field<float3>>("Value_Vector");
+ case CD_PROP_COLOR:
+ return params.extract_input<Field<ColorGeometry4f>>("Value_Color");
+ case CD_PROP_BOOL:
+ return params.extract_input<Field<bool>>("Value_Bool");
+ case CD_PROP_INT32:
+ return params.extract_input<Field<int>>("Value_Int");
+ default:
+ BLI_assert_unreachable();
+ }
+ return {};
+}
+
+static void output_attribute_field(GeoNodeExecParams &params, GField field)
+{
+ switch (bke::cpp_type_to_custom_data_type(field.cpp_type())) {
+ case CD_PROP_FLOAT: {
+ params.set_output("Value_Float", Field<float>(field));
+ break;
+ }
+ case CD_PROP_FLOAT3: {
+ params.set_output("Value_Vector", Field<float3>(field));
+ break;
+ }
+ case CD_PROP_COLOR: {
+ params.set_output("Value_Color", Field<ColorGeometry4f>(field));
+ break;
+ }
+ case CD_PROP_BOOL: {
+ params.set_output("Value_Bool", Field<bool>(field));
+ break;
+ }
+ case CD_PROP_INT32: {
+ params.set_output("Value_Int", Field<int>(field));
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry = params.extract_input<GeometrySet>("Geometry");
+ const NodeGeometrySampleIndex &storage = node_storage(params.node());
+ const eCustomDataType data_type = eCustomDataType(storage.data_type);
+ const eAttrDomain domain = eAttrDomain(storage.domain);
+
+ auto fn = std::make_shared<SampleIndexFunction>(std::move(geometry),
+ get_input_attribute_field(params, data_type),
+ domain,
+ bool(storage.clamp));
+ auto op = FieldOperation::Create(std::move(fn), {params.extract_input<Field<int>>("Index")});
+ output_attribute_field(params, GField(std::move(op)));
+}
+
+} // namespace blender::nodes::node_geo_sample_index_cc
+
+void register_node_type_geo_sample_index()
+{
+ namespace file_ns = blender::nodes::node_geo_sample_index_cc;
+
+ static bNodeType ntype;
+
+ geo_node_type_base(&ntype, GEO_NODE_SAMPLE_INDEX, "Sample Index", NODE_CLASS_GEOMETRY);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
+ ntype.declare = file_ns::node_declare;
+ node_type_storage(
+ &ntype, "NodeGeometrySampleIndex", node_free_standard_storage, node_copy_standard_storage);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.draw_buttons = file_ns::node_layout;
+ ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc
new file mode 100644
index 00000000000..7028b013dc6
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc
@@ -0,0 +1,342 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "DNA_pointcloud_types.h"
+
+#include "BKE_bvhutils.h"
+#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes {
+
+void get_closest_in_bvhtree(BVHTreeFromMesh &tree_data,
+ const VArray<float3> &positions,
+ const IndexMask mask,
+ const MutableSpan<int> r_indices,
+ const MutableSpan<float> r_distances_sq,
+ const MutableSpan<float3> r_positions)
+{
+ BLI_assert(positions.size() >= r_indices.size());
+ BLI_assert(positions.size() >= r_distances_sq.size());
+ BLI_assert(positions.size() >= r_positions.size());
+
+ for (const int i : mask) {
+ BVHTreeNearest nearest;
+ nearest.dist_sq = FLT_MAX;
+ const float3 position = positions[i];
+ BLI_bvhtree_find_nearest(
+ tree_data.tree, position, &nearest, tree_data.nearest_callback, &tree_data);
+ if (!r_indices.is_empty()) {
+ r_indices[i] = nearest.index;
+ }
+ if (!r_distances_sq.is_empty()) {
+ r_distances_sq[i] = nearest.dist_sq;
+ }
+ if (!r_positions.is_empty()) {
+ r_positions[i] = nearest.co;
+ }
+ }
+}
+
+} // namespace blender::nodes
+
+namespace blender::nodes::node_geo_sample_nearest_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>(N_("Geometry"))
+ .supported_type({GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD});
+ b.add_input<decl::Vector>(N_("Sample Position")).implicit_field(implicit_field_inputs::position);
+ b.add_output<decl::Int>(N_("Index")).dependent_field({1});
+}
+
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
+}
+
+static void node_init(bNodeTree * /*tree*/, bNode *node)
+{
+ node->custom1 = CD_PROP_FLOAT;
+ node->custom2 = ATTR_DOMAIN_POINT;
+}
+
+static void get_closest_pointcloud_points(const PointCloud &pointcloud,
+ const VArray<float3> &positions,
+ const IndexMask mask,
+ const MutableSpan<int> r_indices,
+ const MutableSpan<float> r_distances_sq)
+{
+ BLI_assert(positions.size() >= r_indices.size());
+ BLI_assert(pointcloud.totpoint > 0);
+
+ BVHTreeFromPointCloud tree_data;
+ BKE_bvhtree_from_pointcloud_get(&tree_data, &pointcloud, 2);
+
+ for (const int i : mask) {
+ BVHTreeNearest nearest;
+ nearest.dist_sq = FLT_MAX;
+ const float3 position = positions[i];
+ BLI_bvhtree_find_nearest(
+ tree_data.tree, position, &nearest, tree_data.nearest_callback, &tree_data);
+ r_indices[i] = nearest.index;
+ if (!r_distances_sq.is_empty()) {
+ r_distances_sq[i] = nearest.dist_sq;
+ }
+ }
+
+ free_bvhtree_from_pointcloud(&tree_data);
+}
+
+static void get_closest_mesh_points(const Mesh &mesh,
+ const VArray<float3> &positions,
+ const IndexMask mask,
+ const MutableSpan<int> r_point_indices,
+ const MutableSpan<float> r_distances_sq,
+ const MutableSpan<float3> r_positions)
+{
+ BLI_assert(mesh.totvert > 0);
+ BVHTreeFromMesh tree_data;
+ BKE_bvhtree_from_mesh_get(&tree_data, &mesh, BVHTREE_FROM_VERTS, 2);
+ get_closest_in_bvhtree(tree_data, positions, mask, r_point_indices, r_distances_sq, r_positions);
+ free_bvhtree_from_mesh(&tree_data);
+}
+
+static void get_closest_mesh_edges(const Mesh &mesh,
+ const VArray<float3> &positions,
+ const IndexMask mask,
+ const MutableSpan<int> r_edge_indices,
+ const MutableSpan<float> r_distances_sq,
+ const MutableSpan<float3> r_positions)
+{
+ BLI_assert(mesh.totedge > 0);
+ BVHTreeFromMesh tree_data;
+ BKE_bvhtree_from_mesh_get(&tree_data, &mesh, BVHTREE_FROM_EDGES, 2);
+ get_closest_in_bvhtree(tree_data, positions, mask, r_edge_indices, r_distances_sq, r_positions);
+ free_bvhtree_from_mesh(&tree_data);
+}
+
+static void get_closest_mesh_looptris(const Mesh &mesh,
+ const VArray<float3> &positions,
+ const IndexMask mask,
+ const MutableSpan<int> r_looptri_indices,
+ const MutableSpan<float> r_distances_sq,
+ const MutableSpan<float3> r_positions)
+{
+ BLI_assert(mesh.totpoly > 0);
+ BVHTreeFromMesh tree_data;
+ BKE_bvhtree_from_mesh_get(&tree_data, &mesh, BVHTREE_FROM_LOOPTRI, 2);
+ get_closest_in_bvhtree(
+ tree_data, positions, mask, r_looptri_indices, r_distances_sq, r_positions);
+ free_bvhtree_from_mesh(&tree_data);
+}
+
+static void get_closest_mesh_polys(const Mesh &mesh,
+ const VArray<float3> &positions,
+ const IndexMask mask,
+ const MutableSpan<int> r_poly_indices,
+ const MutableSpan<float> r_distances_sq,
+ const MutableSpan<float3> r_positions)
+{
+ BLI_assert(mesh.totpoly > 0);
+
+ Array<int> looptri_indices(positions.size());
+ get_closest_mesh_looptris(mesh, positions, mask, looptri_indices, r_distances_sq, r_positions);
+
+ const Span<MLoopTri> looptris = mesh.looptris();
+
+ for (const int i : mask) {
+ const MLoopTri &looptri = looptris[looptri_indices[i]];
+ r_poly_indices[i] = looptri.poly;
+ }
+}
+
+/* The closest corner is defined to be the closest corner on the closest face. */
+static void get_closest_mesh_corners(const Mesh &mesh,
+ const VArray<float3> &positions,
+ const IndexMask mask,
+ const MutableSpan<int> r_corner_indices,
+ const MutableSpan<float> r_distances_sq,
+ const MutableSpan<float3> r_positions)
+{
+ const Span<MVert> verts = mesh.verts();
+ const Span<MPoly> polys = mesh.polys();
+ const Span<MLoop> loops = mesh.loops();
+
+ BLI_assert(mesh.totloop > 0);
+ Array<int> poly_indices(positions.size());
+ get_closest_mesh_polys(mesh, positions, mask, poly_indices, {}, {});
+
+ for (const int i : mask) {
+ const float3 position = positions[i];
+ const int poly_index = poly_indices[i];
+ const MPoly &poly = polys[poly_index];
+
+ /* Find the closest vertex in the polygon. */
+ float min_distance_sq = FLT_MAX;
+ const MVert *closest_mvert;
+ int closest_loop_index = 0;
+ for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
+ const MLoop &loop = loops[loop_index];
+ const int vertex_index = loop.v;
+ const MVert &mvert = verts[vertex_index];
+ const float distance_sq = math::distance_squared(position, float3(mvert.co));
+ if (distance_sq < min_distance_sq) {
+ min_distance_sq = distance_sq;
+ closest_loop_index = loop_index;
+ closest_mvert = &mvert;
+ }
+ }
+ if (!r_corner_indices.is_empty()) {
+ r_corner_indices[i] = closest_loop_index;
+ }
+ if (!r_positions.is_empty()) {
+ r_positions[i] = closest_mvert->co;
+ }
+ if (!r_distances_sq.is_empty()) {
+ r_distances_sq[i] = min_distance_sq;
+ }
+ }
+}
+
+static bool component_is_available(const GeometrySet &geometry,
+ const GeometryComponentType type,
+ const eAttrDomain domain)
+{
+ if (!geometry.has(type)) {
+ return false;
+ }
+ const GeometryComponent &component = *geometry.get_component_for_read(type);
+ if (component.is_empty()) {
+ return false;
+ }
+ return component.attribute_domain_size(domain) != 0;
+}
+
+static const GeometryComponent *find_source_component(const GeometrySet &geometry,
+ const eAttrDomain domain)
+{
+ /* Choose the other component based on a consistent order, rather than some more complicated
+ * heuristic. This is the same order visible in the spreadsheet and used in the ray-cast node. */
+ static const Array<GeometryComponentType> supported_types = {GEO_COMPONENT_TYPE_MESH,
+ GEO_COMPONENT_TYPE_POINT_CLOUD,
+ GEO_COMPONENT_TYPE_CURVE,
+ GEO_COMPONENT_TYPE_INSTANCES};
+ for (const GeometryComponentType src_type : supported_types) {
+ if (component_is_available(geometry, src_type, domain)) {
+ return geometry.get_component_for_read(src_type);
+ }
+ }
+
+ return nullptr;
+}
+
+class SampleNearestFunction : public fn::MultiFunction {
+ GeometrySet source_;
+ eAttrDomain domain_;
+
+ const GeometryComponent *src_component_;
+
+ fn::MFSignature signature_;
+
+ public:
+ SampleNearestFunction(GeometrySet geometry, eAttrDomain domain)
+ : source_(std::move(geometry)), domain_(domain)
+ {
+ source_.ensure_owns_direct_data();
+ signature_ = this->create_signature();
+ this->set_signature(&signature_);
+
+ this->src_component_ = find_source_component(source_, domain_);
+ }
+
+ fn::MFSignature create_signature()
+ {
+ blender::fn::MFSignatureBuilder signature{"Sample Nearest"};
+ signature.single_input<float3>("Position");
+ signature.single_output<int>("Index");
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
+ {
+ const VArray<float3> &positions = params.readonly_single_input<float3>(0, "Position");
+ MutableSpan<int> indices = params.uninitialized_single_output<int>(1, "Index");
+ if (!src_component_) {
+ indices.fill_indices(mask, 0);
+ return;
+ }
+
+ switch (src_component_->type()) {
+ case GEO_COMPONENT_TYPE_MESH: {
+ const MeshComponent &component = *static_cast<const MeshComponent *>(src_component_);
+ const Mesh &mesh = *component.get_for_read();
+ Array<float> distances(mask.min_array_size());
+ switch (domain_) {
+ case ATTR_DOMAIN_POINT:
+ get_closest_mesh_points(mesh, positions, mask, indices, distances, {});
+ break;
+ case ATTR_DOMAIN_EDGE:
+ get_closest_mesh_edges(mesh, positions, mask, indices, distances, {});
+ break;
+ case ATTR_DOMAIN_FACE:
+ get_closest_mesh_polys(mesh, positions, mask, indices, distances, {});
+ break;
+ case ATTR_DOMAIN_CORNER:
+ get_closest_mesh_corners(mesh, positions, mask, indices, distances, {});
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case GEO_COMPONENT_TYPE_POINT_CLOUD: {
+ const PointCloudComponent &component = *static_cast<const PointCloudComponent *>(
+ src_component_);
+ const PointCloud &points = *component.get_for_read();
+ Array<float> distances(mask.min_array_size());
+ get_closest_pointcloud_points(points, positions, mask, indices, distances);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry = params.extract_input<GeometrySet>("Geometry");
+ const eAttrDomain domain = eAttrDomain(params.node().custom2);
+ if (geometry.has_curves() && !geometry.has_mesh() && !geometry.has_pointcloud()) {
+ params.error_message_add(NodeWarningType::Error,
+ TIP_("The source geometry must contain a mesh or a point cloud"));
+ params.set_default_remaining_outputs();
+ return;
+ }
+
+ Field<float3> positions = params.extract_input<Field<float3>>("Sample Position");
+ auto fn = std::make_shared<SampleNearestFunction>(std::move(geometry), domain);
+ auto op = FieldOperation::Create(std::move(fn), {std::move(positions)});
+ params.set_output<Field<int>>("Index", Field<int>(std::move(op)));
+}
+
+} // namespace blender::nodes::node_geo_sample_nearest_cc
+
+void register_node_type_geo_sample_nearest()
+{
+ namespace file_ns = blender::nodes::node_geo_sample_nearest_cc;
+
+ static bNodeType ntype;
+
+ geo_node_type_base(&ntype, GEO_NODE_SAMPLE_NEAREST, "Sample Nearest", NODE_CLASS_GEOMETRY);
+ ntype.initfunc = file_ns::node_init;
+ ntype.declare = file_ns::node_declare;
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.draw_buttons = file_ns::node_layout;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc
new file mode 100644
index 00000000000..503f6264191
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc
@@ -0,0 +1,278 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_attribute_math.hh"
+#include "BKE_bvhutils.h"
+#include "BKE_mesh.h"
+#include "BKE_mesh_sample.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "NOD_socket_search_link.hh"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_sample_nearest_surface_cc {
+
+using namespace blender::bke::mesh_surface_sample;
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
+
+ b.add_input<decl::Float>(N_("Value"), "Value_Float").hide_value().supports_field();
+ b.add_input<decl::Int>(N_("Value"), "Value_Int").hide_value().supports_field();
+ b.add_input<decl::Vector>(N_("Value"), "Value_Vector").hide_value().supports_field();
+ b.add_input<decl::Color>(N_("Value"), "Value_Color").hide_value().supports_field();
+ b.add_input<decl::Bool>(N_("Value"), "Value_Bool").hide_value().supports_field();
+
+ b.add_input<decl::Vector>(N_("Sample Position")).implicit_field(implicit_field_inputs::position);
+
+ b.add_output<decl::Float>(N_("Value"), "Value_Float").dependent_field({6});
+ b.add_output<decl::Int>(N_("Value"), "Value_Int").dependent_field({6});
+ b.add_output<decl::Vector>(N_("Value"), "Value_Vector").dependent_field({6});
+ b.add_output<decl::Color>(N_("Value"), "Value_Color").dependent_field({6});
+ b.add_output<decl::Bool>(N_("Value"), "Value_Bool").dependent_field({6});
+}
+
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
+}
+
+static void node_init(bNodeTree * /*tree*/, bNode *node)
+{
+ node->custom1 = CD_PROP_FLOAT;
+}
+
+static void node_update(bNodeTree *ntree, bNode *node)
+{
+ const eCustomDataType data_type = eCustomDataType(node->custom1);
+
+ bNodeSocket *in_socket_mesh = static_cast<bNodeSocket *>(node->inputs.first);
+ bNodeSocket *in_socket_float = in_socket_mesh->next;
+ bNodeSocket *in_socket_int32 = in_socket_float->next;
+ bNodeSocket *in_socket_vector = in_socket_int32->next;
+ bNodeSocket *in_socket_color4f = in_socket_vector->next;
+ bNodeSocket *in_socket_bool = in_socket_color4f->next;
+
+ nodeSetSocketAvailability(ntree, in_socket_vector, data_type == CD_PROP_FLOAT3);
+ nodeSetSocketAvailability(ntree, in_socket_float, data_type == CD_PROP_FLOAT);
+ nodeSetSocketAvailability(ntree, in_socket_color4f, data_type == CD_PROP_COLOR);
+ nodeSetSocketAvailability(ntree, in_socket_bool, data_type == CD_PROP_BOOL);
+ nodeSetSocketAvailability(ntree, in_socket_int32, data_type == CD_PROP_INT32);
+
+ bNodeSocket *out_socket_float = static_cast<bNodeSocket *>(node->outputs.first);
+ bNodeSocket *out_socket_int32 = out_socket_float->next;
+ bNodeSocket *out_socket_vector = out_socket_int32->next;
+ bNodeSocket *out_socket_color4f = out_socket_vector->next;
+ bNodeSocket *out_socket_bool = out_socket_color4f->next;
+
+ nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3);
+ nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT);
+ nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR);
+ nodeSetSocketAvailability(ntree, out_socket_bool, data_type == CD_PROP_BOOL);
+ nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32);
+}
+
+static void node_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+ const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
+ search_link_ops_for_declarations(params, declaration.inputs().take_back(2));
+ search_link_ops_for_declarations(params, declaration.inputs().take_front(1));
+
+ const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type(
+ (eNodeSocketDatatype)params.other_socket().type);
+ if (type && *type != CD_PROP_STRING) {
+ /* The input and output sockets have the same name. */
+ params.add_item(IFACE_("Value"), [type](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("GeometryNodeSampleNearestSurface");
+ node.custom1 = *type;
+ params.update_and_connect_available_socket(node, "Value");
+ });
+ }
+}
+
+static void get_closest_mesh_looptris(const Mesh &mesh,
+ const VArray<float3> &positions,
+ const IndexMask mask,
+ const MutableSpan<int> r_looptri_indices,
+ const MutableSpan<float> r_distances_sq,
+ const MutableSpan<float3> r_positions)
+{
+ BLI_assert(mesh.totpoly > 0);
+ BVHTreeFromMesh tree_data;
+ BKE_bvhtree_from_mesh_get(&tree_data, &mesh, BVHTREE_FROM_LOOPTRI, 2);
+ get_closest_in_bvhtree(
+ tree_data, positions, mask, r_looptri_indices, r_distances_sq, r_positions);
+ free_bvhtree_from_mesh(&tree_data);
+}
+
+/**
+ * \note Multi-threading for this function is provided by the field evaluator. Since the #call
+ * function could be called many times, calculate the data from the source geometry once and store
+ * it for later.
+ */
+class SampleNearestSurfaceFunction : public fn::MultiFunction {
+ GeometrySet source_;
+ GField src_field_;
+
+ /**
+ * This function is meant to sample the surface of a mesh rather than take the value from
+ * individual elements, so use the most complex domain, ensuring no information is lost. In the
+ * future, it should be possible to use the most complex domain required by the field inputs, to
+ * simplify sampling and avoid domain conversions.
+ */
+ eAttrDomain domain_ = ATTR_DOMAIN_CORNER;
+
+ fn::MFSignature signature_;
+
+ std::optional<bke::MeshFieldContext> source_context_;
+ std::unique_ptr<FieldEvaluator> source_evaluator_;
+ const GVArray *source_data_;
+
+ public:
+ SampleNearestSurfaceFunction(GeometrySet geometry, GField src_field)
+ : source_(std::move(geometry)), src_field_(std::move(src_field))
+ {
+ source_.ensure_owns_direct_data();
+ signature_ = this->create_signature();
+ this->set_signature(&signature_);
+ this->evaluate_source_field();
+ }
+
+ fn::MFSignature create_signature()
+ {
+ blender::fn::MFSignatureBuilder signature{"Sample Nearest Surface"};
+ signature.single_input<float3>("Position");
+ signature.single_output("Value", src_field_.cpp_type());
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
+ {
+ const VArray<float3> &positions = params.readonly_single_input<float3>(0, "Position");
+ GMutableSpan dst = params.uninitialized_single_output_if_required(1, "Value");
+
+ const MeshComponent &mesh_component = *source_.get_component_for_read<MeshComponent>();
+ BLI_assert(mesh_component.has_mesh());
+ const Mesh &mesh = *mesh_component.get_for_read();
+ BLI_assert(mesh.totpoly > 0);
+
+ /* Find closest points on the mesh surface. */
+ Array<int> looptri_indices(mask.min_array_size());
+ Array<float3> sampled_positions(mask.min_array_size());
+ get_closest_mesh_looptris(mesh, positions, mask, looptri_indices, {}, sampled_positions);
+
+ MeshAttributeInterpolator interp(&mesh, mask, sampled_positions, looptri_indices);
+ interp.sample_data(*source_data_, domain_, eAttributeMapMode::INTERPOLATED, dst);
+ }
+
+ private:
+ void evaluate_source_field()
+ {
+ const Mesh &mesh = *source_.get_mesh_for_read();
+ source_context_.emplace(bke::MeshFieldContext{mesh, domain_});
+ const int domain_size = mesh.attributes().domain_size(domain_);
+ source_evaluator_ = std::make_unique<FieldEvaluator>(*source_context_, domain_size);
+ source_evaluator_->add(src_field_);
+ source_evaluator_->evaluate();
+ source_data_ = &source_evaluator_->get_evaluated(0);
+ }
+};
+
+static GField get_input_attribute_field(GeoNodeExecParams &params, const eCustomDataType data_type)
+{
+ switch (data_type) {
+ case CD_PROP_FLOAT:
+ return params.extract_input<Field<float>>("Value_Float");
+ case CD_PROP_FLOAT3:
+ return params.extract_input<Field<float3>>("Value_Vector");
+ case CD_PROP_COLOR:
+ return params.extract_input<Field<ColorGeometry4f>>("Value_Color");
+ case CD_PROP_BOOL:
+ return params.extract_input<Field<bool>>("Value_Bool");
+ case CD_PROP_INT32:
+ return params.extract_input<Field<int>>("Value_Int");
+ default:
+ BLI_assert_unreachable();
+ }
+ return {};
+}
+
+static void output_attribute_field(GeoNodeExecParams &params, GField field)
+{
+ switch (bke::cpp_type_to_custom_data_type(field.cpp_type())) {
+ case CD_PROP_FLOAT: {
+ params.set_output("Value_Float", Field<float>(field));
+ break;
+ }
+ case CD_PROP_FLOAT3: {
+ params.set_output("Value_Vector", Field<float3>(field));
+ break;
+ }
+ case CD_PROP_COLOR: {
+ params.set_output("Value_Color", Field<ColorGeometry4f>(field));
+ break;
+ }
+ case CD_PROP_BOOL: {
+ params.set_output("Value_Bool", Field<bool>(field));
+ break;
+ }
+ case CD_PROP_INT32: {
+ params.set_output("Value_Int", Field<int>(field));
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry = params.extract_input<GeometrySet>("Mesh");
+ const eCustomDataType data_type = eCustomDataType(params.node().custom1);
+ const Mesh *mesh = geometry.get_mesh_for_read();
+ if (mesh == nullptr) {
+ params.set_default_remaining_outputs();
+ return;
+ }
+ if (mesh->totvert == 0) {
+ params.set_default_remaining_outputs();
+ return;
+ }
+ if (mesh->totpoly == 0) {
+ params.error_message_add(NodeWarningType::Error, TIP_("The source mesh must have faces"));
+ params.set_default_remaining_outputs();
+ return;
+ }
+
+ Field<float3> positions = params.extract_input<Field<float3>>("Sample Position");
+ GField field = get_input_attribute_field(params, data_type);
+ auto fn = std::make_shared<SampleNearestSurfaceFunction>(std::move(geometry), std::move(field));
+ auto op = FieldOperation::Create(std::move(fn), {std::move(positions)});
+ output_attribute_field(params, GField(std::move(op)));
+}
+
+} // namespace blender::nodes::node_geo_sample_nearest_surface_cc
+
+void register_node_type_geo_sample_nearest_surface()
+{
+ namespace file_ns = blender::nodes::node_geo_sample_nearest_surface_cc;
+
+ static bNodeType ntype;
+
+ geo_node_type_base(
+ &ntype, GEO_NODE_SAMPLE_NEAREST_SURFACE, "Sample Nearest Surface", NODE_CLASS_GEOMETRY);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
+ ntype.declare = file_ns::node_declare;
+ node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.draw_buttons = file_ns::node_layout;
+ ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc
new file mode 100644
index 00000000000..0a6dd569395
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc
@@ -0,0 +1,294 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BKE_attribute_math.hh"
+#include "BKE_mesh.h"
+#include "BKE_type_conversions.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "GEO_reverse_uv_sampler.hh"
+
+#include "NOD_socket_search_link.hh"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_sample_uv_surface_cc {
+
+using geometry::ReverseUVSampler;
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
+
+ b.add_input<decl::Float>(N_("Value"), "Value_Float").hide_value().supports_field();
+ b.add_input<decl::Int>(N_("Value"), "Value_Int").hide_value().supports_field();
+ b.add_input<decl::Vector>(N_("Value"), "Value_Vector").hide_value().supports_field();
+ b.add_input<decl::Color>(N_("Value"), "Value_Color").hide_value().supports_field();
+ b.add_input<decl::Bool>(N_("Value"), "Value_Bool").hide_value().supports_field();
+
+ b.add_input<decl::Vector>(N_("Source UV Map"))
+ .hide_value()
+ .supports_field()
+ .description(N_("The mesh UV map to sample. Should not have overlapping faces"));
+ b.add_input<decl::Vector>(N_("Sample UV"))
+ .supports_field()
+ .description(N_("The coordinates to sample within the UV map"));
+
+ b.add_output<decl::Float>(N_("Value"), "Value_Float").dependent_field({7});
+ b.add_output<decl::Int>(N_("Value"), "Value_Int").dependent_field({7});
+ b.add_output<decl::Vector>(N_("Value"), "Value_Vector").dependent_field({7});
+ b.add_output<decl::Color>(N_("Value"), "Value_Color").dependent_field({7});
+ b.add_output<decl::Bool>(N_("Value"), "Value_Bool").dependent_field({7});
+
+ b.add_output<decl::Bool>(N_("Is Valid"))
+ .dependent_field({7})
+ .description(N_("Whether the node could find a single face to sample at the UV coordinate"));
+}
+
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
+}
+
+static void node_init(bNodeTree * /*tree*/, bNode *node)
+{
+ node->custom1 = CD_PROP_FLOAT;
+}
+
+static void node_update(bNodeTree *ntree, bNode *node)
+{
+ const eCustomDataType data_type = eCustomDataType(node->custom1);
+
+ bNodeSocket *in_socket_mesh = static_cast<bNodeSocket *>(node->inputs.first);
+ bNodeSocket *in_socket_float = in_socket_mesh->next;
+ bNodeSocket *in_socket_int32 = in_socket_float->next;
+ bNodeSocket *in_socket_vector = in_socket_int32->next;
+ bNodeSocket *in_socket_color4f = in_socket_vector->next;
+ bNodeSocket *in_socket_bool = in_socket_color4f->next;
+
+ nodeSetSocketAvailability(ntree, in_socket_vector, data_type == CD_PROP_FLOAT3);
+ nodeSetSocketAvailability(ntree, in_socket_float, data_type == CD_PROP_FLOAT);
+ nodeSetSocketAvailability(ntree, in_socket_color4f, data_type == CD_PROP_COLOR);
+ nodeSetSocketAvailability(ntree, in_socket_bool, data_type == CD_PROP_BOOL);
+ nodeSetSocketAvailability(ntree, in_socket_int32, data_type == CD_PROP_INT32);
+
+ bNodeSocket *out_socket_float = static_cast<bNodeSocket *>(node->outputs.first);
+ bNodeSocket *out_socket_int32 = out_socket_float->next;
+ bNodeSocket *out_socket_vector = out_socket_int32->next;
+ bNodeSocket *out_socket_color4f = out_socket_vector->next;
+ bNodeSocket *out_socket_bool = out_socket_color4f->next;
+
+ nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3);
+ nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT);
+ nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR);
+ nodeSetSocketAvailability(ntree, out_socket_bool, data_type == CD_PROP_BOOL);
+ nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32);
+}
+
+static void node_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+ const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
+ search_link_ops_for_declarations(params, declaration.inputs().take_back(2));
+ search_link_ops_for_declarations(params, declaration.inputs().take_front(1));
+ search_link_ops_for_declarations(params, declaration.outputs().take_back(1));
+
+ const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type(
+ eNodeSocketDatatype(params.other_socket().type));
+ if (type && *type != CD_PROP_STRING) {
+ /* The input and output sockets have the same name. */
+ params.add_item(IFACE_("Value"), [type](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("GeometryNodeSampleUVSurface");
+ node.custom1 = *type;
+ params.update_and_connect_available_socket(node, "Value");
+ });
+ }
+}
+
+class SampleUVSurfaceFunction : public fn::MultiFunction {
+ GeometrySet source_;
+ Field<float2> src_uv_map_field_;
+ GField src_field_;
+
+ /**
+ * Use the most complex domain for now ensuring no information is lost. In the future, it should
+ * be possible to use the most complex domain required by the field inputs, to simplify sampling
+ * and avoid domain conversions.
+ */
+ eAttrDomain domain_ = ATTR_DOMAIN_CORNER;
+
+ fn::MFSignature signature_;
+
+ std::optional<bke::MeshFieldContext> source_context_;
+ std::unique_ptr<FieldEvaluator> source_evaluator_;
+ const GVArray *source_data_;
+ VArraySpan<float2> source_uv_map_;
+
+ std::optional<ReverseUVSampler> reverse_uv_sampler_;
+
+ public:
+ SampleUVSurfaceFunction(GeometrySet geometry, Field<float2> src_uv_map_field, GField src_field)
+ : source_(std::move(geometry)),
+ src_uv_map_field_(std::move(src_uv_map_field)),
+ src_field_(std::move(src_field))
+ {
+ source_.ensure_owns_direct_data();
+ signature_ = this->create_signature();
+ this->set_signature(&signature_);
+ this->evaluate_source();
+ }
+
+ fn::MFSignature create_signature()
+ {
+ blender::fn::MFSignatureBuilder signature{"Sample UV Surface"};
+ signature.single_input<float2>("Sample UV");
+ signature.single_output("Value", src_field_.cpp_type());
+ signature.single_output<bool>("Is Valid");
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
+ {
+ const VArray<float2> &sample_uvs = params.readonly_single_input<float2>(0, "Sample UV");
+ GMutableSpan dst = params.uninitialized_single_output_if_required(1, "Value");
+ MutableSpan<bool> valid_dst = params.uninitialized_single_output_if_required<bool>(2,
+ "Is Valid");
+
+ const CPPType &type = src_field_.cpp_type();
+ attribute_math::convert_to_static_type(type, [&](auto dummy) {
+ using T = decltype(dummy);
+ const VArray<T> src_typed = source_data_->typed<T>();
+ MutableSpan<T> dst_typed = dst.typed<T>();
+ for (const int i : mask) {
+ const float2 sample_uv = sample_uvs[i];
+ const ReverseUVSampler::Result result = reverse_uv_sampler_->sample(sample_uv);
+ const bool valid = result.type == ReverseUVSampler::ResultType::Ok;
+ if (!dst_typed.is_empty()) {
+ if (valid) {
+ dst_typed[i] = attribute_math::mix3(result.bary_weights,
+ src_typed[result.looptri->tri[0]],
+ src_typed[result.looptri->tri[1]],
+ src_typed[result.looptri->tri[2]]);
+ }
+ else {
+ dst_typed[i] = {};
+ }
+ }
+ if (!valid_dst.is_empty()) {
+ valid_dst[i] = valid;
+ }
+ }
+ });
+ }
+
+ private:
+ void evaluate_source()
+ {
+ const Mesh &mesh = *source_.get_mesh_for_read();
+ source_context_.emplace(bke::MeshFieldContext{mesh, domain_});
+ const int domain_size = mesh.attributes().domain_size(domain_);
+ source_evaluator_ = std::make_unique<FieldEvaluator>(*source_context_, domain_size);
+ source_evaluator_->add(src_uv_map_field_);
+ source_evaluator_->add(src_field_);
+ source_evaluator_->evaluate();
+ source_uv_map_ = source_evaluator_->get_evaluated<float2>(0);
+ source_data_ = &source_evaluator_->get_evaluated(1);
+
+ reverse_uv_sampler_.emplace(source_uv_map_, mesh.looptris());
+ }
+};
+
+static GField get_input_attribute_field(GeoNodeExecParams &params, const eCustomDataType data_type)
+{
+ switch (data_type) {
+ case CD_PROP_FLOAT:
+ return params.extract_input<Field<float>>("Value_Float");
+ case CD_PROP_FLOAT3:
+ return params.extract_input<Field<float3>>("Value_Vector");
+ case CD_PROP_COLOR:
+ return params.extract_input<Field<ColorGeometry4f>>("Value_Color");
+ case CD_PROP_BOOL:
+ return params.extract_input<Field<bool>>("Value_Bool");
+ case CD_PROP_INT32:
+ return params.extract_input<Field<int>>("Value_Int");
+ default:
+ BLI_assert_unreachable();
+ }
+ return {};
+}
+
+static void output_attribute_field(GeoNodeExecParams &params, GField field)
+{
+ switch (bke::cpp_type_to_custom_data_type(field.cpp_type())) {
+ case CD_PROP_FLOAT: {
+ params.set_output("Value_Float", Field<float>(field));
+ break;
+ }
+ case CD_PROP_FLOAT3: {
+ params.set_output("Value_Vector", Field<float3>(field));
+ break;
+ }
+ case CD_PROP_COLOR: {
+ params.set_output("Value_Color", Field<ColorGeometry4f>(field));
+ break;
+ }
+ case CD_PROP_BOOL: {
+ params.set_output("Value_Bool", Field<bool>(field));
+ break;
+ }
+ case CD_PROP_INT32: {
+ params.set_output("Value_Int", Field<int>(field));
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry = params.extract_input<GeometrySet>("Mesh");
+ const eCustomDataType data_type = eCustomDataType(params.node().custom1);
+ const Mesh *mesh = geometry.get_mesh_for_read();
+ if (mesh == nullptr) {
+ params.set_default_remaining_outputs();
+ return;
+ }
+ if (mesh->totpoly == 0 && mesh->totvert != 0) {
+ params.error_message_add(NodeWarningType::Error, TIP_("The source mesh must have faces"));
+ params.set_default_remaining_outputs();
+ return;
+ }
+
+ const CPPType &float2_type = CPPType::get<float2>();
+
+ const bke::DataTypeConversions &conversions = bke::get_implicit_type_conversions();
+ Field<float2> source_uv_map = conversions.try_convert(
+ params.extract_input<Field<float3>>("Source UV Map"), float2_type);
+ GField field = get_input_attribute_field(params, data_type);
+ Field<float2> sample_uvs = conversions.try_convert(
+ params.extract_input<Field<float3>>("Sample UV"), float2_type);
+ auto fn = std::make_shared<SampleUVSurfaceFunction>(
+ std::move(geometry), std::move(source_uv_map), std::move(field));
+ auto op = FieldOperation::Create(std::move(fn), {std::move(sample_uvs)});
+ output_attribute_field(params, GField(op, 0));
+ params.set_output("Is Valid", Field<bool>(op, 1));
+}
+
+} // namespace blender::nodes::node_geo_sample_uv_surface_cc
+
+void register_node_type_geo_sample_uv_surface()
+{
+ namespace file_ns = blender::nodes::node_geo_sample_uv_surface_cc;
+
+ static bNodeType ntype;
+
+ geo_node_type_base(&ntype, GEO_NODE_SAMPLE_UV_SURFACE, "Sample UV Surface", NODE_CLASS_GEOMETRY);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
+ ntype.declare = file_ns::node_declare;
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.draw_buttons = file_ns::node_layout;
+ ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc
index 2ebbf88b8ad..5f1baa23511 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc
@@ -25,7 +25,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Float>(N_("Scale"), "Scale").default_value(1.0f).min(0.0f).supports_field();
b.add_input<decl::Vector>(N_("Center"))
.subtype(PROP_TRANSLATION)
- .implicit_field()
+ .implicit_field(implicit_field_inputs::position)
.description(N_("Origin of the scaling for each element. If multiple elements are "
"connected, their center is averaged"));
b.add_input<decl::Vector>(N_("Axis"))
@@ -36,13 +36,13 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
};
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
uiItemR(layout, ptr, "scale_mode", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
node->custom1 = ATTR_DOMAIN_FACE;
node->custom2 = GEO_NODE_SCALE_ELEMENTS_UNIFORM;
@@ -56,8 +56,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
bNodeSocket *center_socket = scale_float_socket->next;
bNodeSocket *axis_socket = center_socket->next;
- const GeometryNodeScaleElementsMode mode = static_cast<GeometryNodeScaleElementsMode>(
- node->custom2);
+ const GeometryNodeScaleElementsMode mode = GeometryNodeScaleElementsMode(node->custom2);
const bool use_single_axis = mode == GEO_NODE_SCALE_ELEMENTS_SINGLE_AXIS;
nodeSetSocketAvailability(ntree, axis_socket, use_single_axis);
@@ -405,9 +404,8 @@ static void scale_edges_on_axis(Mesh &mesh, const AxisScaleFields &fields)
static void node_geo_exec(GeoNodeExecParams params)
{
const bNode &node = params.node();
- const eAttrDomain domain = static_cast<eAttrDomain>(node.custom1);
- const GeometryNodeScaleElementsMode scale_mode = static_cast<GeometryNodeScaleElementsMode>(
- node.custom2);
+ const eAttrDomain domain = eAttrDomain(node.custom1);
+ const GeometryNodeScaleElementsMode scale_mode = GeometryNodeScaleElementsMode(node.custom2);
GeometrySet geometry = params.extract_input<GeometrySet>("Geometry");
diff --git a/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc
index 21fe724e194..dacb130337f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc
@@ -2,6 +2,8 @@
#include "BLI_task.hh"
+#include "BKE_instances.hh"
+
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_scale_instances_cc {
@@ -19,10 +21,10 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Instances"));
}
-static void scale_instances(GeoNodeExecParams &params, InstancesComponent &instances_component)
+static void scale_instances(GeoNodeExecParams &params, bke::Instances &instances)
{
- const bke::InstancesFieldContext context{instances_component};
- fn::FieldEvaluator evaluator{context, instances_component.instances_num()};
+ const bke::InstancesFieldContext context{instances};
+ fn::FieldEvaluator evaluator{context, instances.instances_num()};
evaluator.set_selection(params.extract_input<Field<bool>>("Selection"));
evaluator.add(params.extract_input<Field<float3>>("Scale"));
evaluator.add(params.extract_input<Field<float3>>("Center"));
@@ -34,13 +36,13 @@ static void scale_instances(GeoNodeExecParams &params, InstancesComponent &insta
const VArray<float3> pivots = evaluator.get_evaluated<float3>(1);
const VArray<bool> local_spaces = evaluator.get_evaluated<bool>(2);
- MutableSpan<float4x4> instance_transforms = instances_component.instance_transforms();
+ MutableSpan<float4x4> transforms = instances.transforms();
threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) {
for (const int i_selection : range) {
const int i = selection[i_selection];
const float3 pivot = pivots[i];
- float4x4 &instance_transform = instance_transforms[i];
+ float4x4 &instance_transform = transforms[i];
if (local_spaces[i]) {
instance_transform *= float4x4::from_location(pivot);
@@ -61,9 +63,8 @@ static void scale_instances(GeoNodeExecParams &params, InstancesComponent &insta
static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Instances");
- if (geometry_set.has_instances()) {
- InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
- scale_instances(params, instances);
+ if (bke::Instances *instances = geometry_set.get_instances_for_write()) {
+ scale_instances(params, *instances);
}
params.set_output("Instances", std::move(geometry_set));
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_self_object.cc b/source/blender/nodes/geometry/nodes/node_geo_self_object.cc
new file mode 100644
index 00000000000..7b33afdb4a0
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_self_object.cc
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_self_object_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Object>(N_("Self Object"));
+}
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ params.set_output("Self Object", const_cast<Object *>(params.self_object()));
+}
+
+} // namespace blender::nodes::node_geo_self_object_cc
+
+void register_node_type_geo_self_object()
+{
+ namespace file_ns = blender::nodes::node_geo_self_object_cc;
+
+ static bNodeType ntype;
+
+ geo_node_type_base(&ntype, GEO_NODE_SELF_OBJECT, "Self Object", NODE_CLASS_INPUT);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.declare = file_ns::node_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc
index d785694f253..d4da5dda647 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc
@@ -23,12 +23,12 @@ static void node_declare(NodeDeclarationBuilder &b)
.description(N_("The parts of the geometry not in the selection"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometrySeparateGeometry *data = MEM_cnew<NodeGeometrySeparateGeometry>(__func__);
data->domain = ATTR_DOMAIN_POINT;
@@ -43,7 +43,7 @@ static void node_geo_exec(GeoNodeExecParams params)
const Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
const NodeGeometrySeparateGeometry &storage = node_storage(params.node());
- const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain);
+ const eAttrDomain domain = eAttrDomain(storage.domain);
auto separate_geometry_maybe_recursively = [&](GeometrySet &geometry_set,
const Field<bool> &selection) {
@@ -87,7 +87,7 @@ void register_node_type_geo_separate_geometry()
node_free_standard_storage,
node_copy_standard_storage);
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
ntype.declare = file_ns::node_declare;
ntype.geometry_node_execute = file_ns::node_geo_exec;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc
index e529ddddabe..48be899bec9 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc
@@ -17,17 +17,21 @@ static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
- b.add_input<decl::Vector>(N_("Position")).implicit_field();
+ b.add_input<decl::Vector>(N_("Position")).implicit_field([](const bNode &node, void *r_value) {
+ const StringRef side = node_storage(node).mode == GEO_NODE_CURVE_HANDLE_LEFT ? "handle_left" :
+ "handle_right";
+ new (r_value) ValueOrField<float3>(bke::AttributeFieldInput::Create<float3>(side));
+ });
b.add_input<decl::Vector>(N_("Offset")).default_value(float3(0.0f, 0.0f, 0.0f)).supports_field();
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometrySetCurveHandlePositions *data = MEM_cnew<NodeGeometrySetCurveHandlePositions>(
__func__);
@@ -170,7 +174,7 @@ void register_node_type_geo_set_curve_handles()
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.declare = file_ns::node_declare;
ntype.minwidth = 100.0f;
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
node_type_storage(&ntype,
"NodeGeometrySetCurveHandlePositions",
node_free_standard_storage,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_normal.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_normal.cc
new file mode 100644
index 00000000000..287c5920134
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_normal.cc
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BKE_curves.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_set_curve_normal_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
+ b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
+ b.add_output<decl::Geometry>(N_("Curve"));
+}
+
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
+}
+
+static void node_init(bNodeTree * /*tree*/, bNode *node)
+{
+ node->custom1 = NORMAL_MODE_MINIMUM_TWIST;
+}
+
+static void set_normal_mode(bke::CurvesGeometry &curves,
+ const NormalMode mode,
+ const Field<bool> &selection_field)
+{
+ bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_CURVE};
+ fn::FieldEvaluator evaluator{field_context, curves.curves_num()};
+ evaluator.set_selection(selection_field);
+ evaluator.evaluate();
+ const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
+ curves.normal_mode_for_write().fill_indices(selection, mode);
+ curves.tag_normals_changed();
+}
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ const NormalMode mode = static_cast<NormalMode>(params.node().custom1);
+
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
+ Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
+
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
+ if (Curves *curves_id = geometry_set.get_curves_for_write()) {
+ bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry);
+ set_normal_mode(curves, mode, selection_field);
+ }
+ });
+
+ params.set_output("Curve", std::move(geometry_set));
+}
+
+} // namespace blender::nodes::node_geo_set_curve_normal_cc
+
+void register_node_type_geo_set_curve_normal()
+{
+ namespace file_ns = blender::nodes::node_geo_set_curve_normal_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(&ntype, GEO_NODE_SET_CURVE_NORMAL, "Set Curve Normal", NODE_CLASS_GEOMETRY);
+ ntype.declare = file_ns::node_declare;
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.initfunc = file_ns::node_init;
+ ntype.draw_buttons = file_ns::node_layout;
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_id.cc b/source/blender/nodes/geometry/nodes/node_geo_set_id.cc
index 5864401223b..e308371b1c2 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_id.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_id.cc
@@ -8,7 +8,7 @@ static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
- b.add_input<decl::Int>(N_("ID")).implicit_field();
+ b.add_input<decl::Int>(N_("ID")).implicit_field(implicit_field_inputs::index);
b.add_output<decl::Geometry>(N_("Geometry"));
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc b/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc
index f6dded56315..bb9ac9b5d4c 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc
@@ -24,11 +24,13 @@ static void set_material_index_in_component(GeometryComponent &component,
MutableAttributeAccessor attributes = *component.attributes_for_write();
bke::GeometryFieldContext field_context{component, domain};
+ const bke::AttributeValidator validator = attributes.lookup_validator("material_index");
AttributeWriter<int> indices = attributes.lookup_or_add_for_write<int>("material_index", domain);
fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.set_selection(selection_field);
- evaluator.add_with_destination(index_field, indices.varray);
+ evaluator.add_with_destination(validator.validate_field_if_necessary(index_field),
+ indices.varray);
evaluator.evaluate();
indices.finish();
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
index 613f140ff0a..e243fe3614c 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
@@ -18,7 +18,7 @@ static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
- b.add_input<decl::Vector>(N_("Position")).implicit_field();
+ b.add_input<decl::Vector>(N_("Position")).implicit_field(implicit_field_inputs::position);
b.add_input<decl::Vector>(N_("Offset")).supports_field().subtype(PROP_TRANSLATION);
b.add_output<decl::Geometry>(N_("Geometry"));
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc b/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
index d46ceac92ba..dcd910b8ad2 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
@@ -24,11 +24,13 @@ static void set_resolution(bke::CurvesGeometry &curves,
MutableAttributeAccessor attributes = curves.attributes_for_write();
AttributeWriter<int> resolutions = attributes.lookup_or_add_for_write<int>("resolution",
ATTR_DOMAIN_CURVE);
+ bke::AttributeValidator validator = attributes.lookup_validator("resolution");
bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_CURVE};
fn::FieldEvaluator evaluator{field_context, curves.curves_num()};
evaluator.set_selection(selection_field);
- evaluator.add_with_destination(resolution_field, resolutions.varray);
+ evaluator.add_with_destination(validator.validate_field_if_necessary(resolution_field),
+ resolutions.varray);
evaluator.evaluate();
resolutions.finish();
diff --git a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc
index 2a590f5bf4a..b71dba98daa 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc
@@ -30,7 +30,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
@@ -38,7 +38,7 @@ static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryStoreNamedAttribute *data = MEM_cnew<NodeGeometryStoreNamedAttribute>(__func__);
data->data_type = CD_PROP_FLOAT;
@@ -49,9 +49,9 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryStoreNamedAttribute &storage = node_storage(*node);
- const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
+ const eCustomDataType data_type = eCustomDataType(storage.data_type);
- bNodeSocket *socket_geometry = (bNodeSocket *)node->inputs.first;
+ bNodeSocket *socket_geometry = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *socket_name = socket_geometry->next;
bNodeSocket *socket_vector = socket_name->next;
bNodeSocket *socket_float = socket_vector->next;
@@ -71,10 +71,11 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
search_link_ops_for_declarations(params, declaration.inputs().take_front(2));
+ search_link_ops_for_declarations(params, declaration.outputs().take_front(1));
if (params.in_out() == SOCK_IN) {
const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type(
- static_cast<eNodeSocketDatatype>(params.other_socket().type));
+ eNodeSocketDatatype(params.other_socket().type));
if (type && *type != CD_PROP_STRING) {
/* The input and output sockets have the same name. */
params.add_item(IFACE_("Value"), [type](LinkSearchOpParams &params) {
@@ -86,54 +87,6 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
}
}
-static void try_capture_field_on_geometry(GeometryComponent &component,
- const StringRef name,
- const eAttrDomain domain,
- const GField &field,
- std::atomic<bool> &r_failure)
-{
- MutableAttributeAccessor attributes = *component.attributes_for_write();
- const int domain_size = attributes.domain_size(domain);
- if (domain_size == 0) {
- return;
- }
-
- bke::GeometryFieldContext field_context{component, domain};
- const IndexMask mask{IndexMask(domain_size)};
-
- const CPPType &type = field.cpp_type();
- const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(type);
-
- /* Could avoid allocating a new buffer if:
- * - We are writing to an attribute that exists already with the correct domain and type.
- * - The field does not depend on that attribute (we can't easily check for that yet). */
- void *buffer = MEM_mallocN(type.size() * domain_size, __func__);
-
- fn::FieldEvaluator evaluator{field_context, &mask};
- evaluator.add_with_destination(field, GMutableSpan{type, buffer, domain_size});
- evaluator.evaluate();
-
- if (GAttributeWriter attribute = attributes.lookup_for_write(name)) {
- if (attribute.domain == domain && attribute.varray.type() == type) {
- attribute.varray.set_all(buffer);
- attribute.finish();
- type.destruct_n(buffer, domain_size);
- MEM_freeN(buffer);
- return;
- }
- }
- attributes.remove(name);
- if (attributes.add(name, domain, data_type, bke::AttributeInitMoveArray{buffer})) {
- return;
- }
-
- /* If the name corresponds to a builtin attribute, removing the attribute might fail if
- * it's required, and adding the attribute might fail if the domain or type is incorrect. */
- type.destruct_n(buffer, domain_size);
- MEM_freeN(buffer);
- r_failure = true;
-}
-
static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
@@ -152,8 +105,8 @@ static void node_geo_exec(GeoNodeExecParams params)
params.used_named_attribute(name, NamedAttributeUsage::Write);
const NodeGeometryStoreNamedAttribute &storage = node_storage(params.node());
- const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
- const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain);
+ const eCustomDataType data_type = eCustomDataType(storage.data_type);
+ const eAttrDomain domain = eAttrDomain(storage.domain);
GField field;
switch (data_type) {
@@ -189,7 +142,9 @@ static void node_geo_exec(GeoNodeExecParams params)
if (geometry_set.has_instances()) {
GeometryComponent &component = geometry_set.get_component_for_write(
GEO_COMPONENT_TYPE_INSTANCES);
- try_capture_field_on_geometry(component, name, domain, field, failure);
+ if (!bke::try_capture_field_on_geometry(component, name, domain, field)) {
+ failure.store(true);
+ }
}
}
else {
@@ -198,7 +153,9 @@ static void node_geo_exec(GeoNodeExecParams params)
{GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE}) {
if (geometry_set.has(type)) {
GeometryComponent &component = geometry_set.get_component_for_write(type);
- try_capture_field_on_geometry(component, name, domain, field, failure);
+ if (!bke::try_capture_field_on_geometry(component, name, domain, field)) {
+ failure.store(true);
+ }
}
}
});
@@ -235,7 +192,7 @@ void register_node_type_geo_store_named_attribute()
node_free_standard_storage,
node_copy_standard_storage);
node_type_size(&ntype, 140, 100, 700);
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
ntype.updatefunc = file_ns::node_update;
ntype.declare = file_ns::node_declare;
ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc
index afd7db6604d..405c2761711 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc
@@ -6,6 +6,7 @@
#include "BKE_curve.h"
#include "BKE_curve_legacy_convert.hh"
#include "BKE_curves.hh"
+#include "BKE_instances.hh"
#include "BKE_vfont.h"
#include "BLI_hash.h"
@@ -76,7 +77,7 @@ static void node_layout(uiLayout *layout, struct bContext *C, PointerRNA *ptr)
uiItemR(layout, ptr, "pivot_mode", 0, IFACE_("Pivot Point"), ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryStringToCurves *data = MEM_cnew<NodeGeometryStringToCurves>(__func__);
@@ -85,7 +86,7 @@ static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
data->align_y = GEO_NODE_STRING_TO_CURVES_ALIGN_Y_TOP_BASELINE;
data->pivot_mode = GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_BOTTOM_LEFT;
node->storage = data;
- node->id = (ID *)BKE_vfont_builtin_get();
+ node->id = reinterpret_cast<ID *>(BKE_vfont_builtin_get());
}
static void node_update(bNodeTree *ntree, bNode *node)
@@ -93,11 +94,11 @@ static void node_update(bNodeTree *ntree, bNode *node)
const NodeGeometryStringToCurves &storage = node_storage(*node);
const GeometryNodeStringToCurvesOverflowMode overflow = (GeometryNodeStringToCurvesOverflowMode)
storage.overflow;
- bNodeSocket *socket_remainder = ((bNodeSocket *)node->outputs.first)->next;
+ bNodeSocket *socket_remainder = static_cast<bNodeSocket *>(node->outputs.first)->next;
nodeSetSocketAvailability(
ntree, socket_remainder, overflow == GEO_NODE_STRING_TO_CURVES_MODE_TRUNCATE);
- bNodeSocket *height_socket = (bNodeSocket *)node->inputs.last;
+ bNodeSocket *height_socket = static_cast<bNodeSocket *>(node->inputs.last);
nodeSetSocketAvailability(
ntree, height_socket, overflow != GEO_NODE_STRING_TO_CURVES_MODE_OVERFLOW);
}
@@ -203,7 +204,7 @@ static std::optional<TextLayout> get_text_layout(GeoNodeExecParams &params)
cu.linedist = line_spacing;
cu.vfont = vfont;
cu.overflow = overflow;
- cu.tb = (TextBox *)MEM_calloc_arrayN(MAXTEXTBOX, sizeof(TextBox), __func__);
+ cu.tb = static_cast<TextBox *>(MEM_calloc_arrayN(MAXTEXTBOX, sizeof(TextBox), __func__));
cu.tb->w = textbox_w;
cu.tb->h = textbox_h;
cu.totbox = 1;
@@ -213,8 +214,8 @@ static std::optional<TextLayout> get_text_layout(GeoNodeExecParams &params)
cu.len = len_bytes;
cu.pos = len_chars;
/* The reason for the additional character here is unknown, but reflects other code elsewhere. */
- cu.str = (char *)MEM_mallocN(len_bytes + sizeof(char32_t), __func__);
- cu.strinfo = (CharInfo *)MEM_callocN((len_chars + 1) * sizeof(CharInfo), __func__);
+ cu.str = static_cast<char *>(MEM_mallocN(len_bytes + sizeof(char32_t), __func__));
+ cu.strinfo = static_cast<CharInfo *>(MEM_callocN((len_chars + 1) * sizeof(CharInfo), __func__));
BLI_strncpy(cu.str, layout.text.c_str(), len_bytes + 1);
struct CharTrans *chartransdata = nullptr;
@@ -226,7 +227,7 @@ static std::optional<TextLayout> get_text_layout(GeoNodeExecParams &params)
nullptr, &cu, FO_DUPLI, nullptr, &r_text, &text_len, &text_free, &chartransdata);
if (text_free) {
- MEM_freeN((void *)r_text);
+ MEM_freeN(const_cast<char32_t *>(r_text));
}
Span<CharInfo> info{cu.strinfo, text_len};
@@ -270,9 +271,9 @@ static std::optional<TextLayout> get_text_layout(GeoNodeExecParams &params)
/* Returns a mapping of UTF-32 character code to instance handle. */
static Map<int, int> create_curve_instances(GeoNodeExecParams &params,
TextLayout &layout,
- InstancesComponent &instances)
+ bke::Instances &instances)
{
- VFont *vfont = (VFont *)params.node().id;
+ VFont *vfont = reinterpret_cast<VFont *>(params.node().id);
Map<int, int> handles;
bool pivot_required = params.output_is_required("Pivot Point");
@@ -315,13 +316,13 @@ static Map<int, int> create_curve_instances(GeoNodeExecParams &params,
return handles;
}
-static void add_instances_from_handles(InstancesComponent &instances,
+static void add_instances_from_handles(bke::Instances &instances,
const Map<int, int> &char_handles,
const TextLayout &layout)
{
instances.resize(layout.positions.size());
- MutableSpan<int> handles = instances.instance_reference_handles();
- MutableSpan<float4x4> transforms = instances.instance_transforms();
+ MutableSpan<int> handles = instances.reference_handles();
+ MutableSpan<float4x4> transforms = instances.transforms();
threading::parallel_for(IndexRange(layout.positions.size()), 256, [&](IndexRange range) {
for (const int i : range) {
@@ -333,9 +334,9 @@ static void add_instances_from_handles(InstancesComponent &instances,
static void create_attributes(GeoNodeExecParams &params,
const TextLayout &layout,
- InstancesComponent &instances)
+ bke::Instances &instances)
{
- MutableAttributeAccessor attributes = *instances.attributes_for_write();
+ MutableAttributeAccessor attributes = instances.attributes_for_write();
if (params.output_is_required("Line")) {
StrongAnonymousAttributeID line_id = StrongAnonymousAttributeID("Line");
@@ -385,13 +386,12 @@ static void node_geo_exec(GeoNodeExecParams params)
}
/* Create and add instances. */
- GeometrySet geometry_set_out;
- InstancesComponent &instances = geometry_set_out.get_component_for_write<InstancesComponent>();
- Map<int, int> char_handles = create_curve_instances(params, *layout, instances);
- add_instances_from_handles(instances, char_handles, *layout);
- create_attributes(params, *layout, instances);
+ std::unique_ptr<bke::Instances> instances = std::make_unique<bke::Instances>();
+ Map<int, int> char_handles = create_curve_instances(params, *layout, *instances);
+ add_instances_from_handles(*instances, char_handles, *layout);
+ create_attributes(params, *layout, *instances);
- params.set_output("Curve Instances", std::move(geometry_set_out));
+ params.set_output("Curve Instances", GeometrySet::create_with_instances(instances.release()));
}
} // namespace blender::nodes::node_geo_string_to_curves_cc
@@ -405,8 +405,8 @@ void register_node_type_geo_string_to_curves()
geo_node_type_base(&ntype, GEO_NODE_STRING_TO_CURVES, "String to Curves", NODE_CLASS_GEOMETRY);
ntype.declare = file_ns::node_declare;
ntype.geometry_node_execute = file_ns::node_geo_exec;
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
node_type_size(&ntype, 190, 120, 700);
node_type_storage(&ntype,
"NodeGeometryStringToCurves",
diff --git a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
index 60c8a89a6bf..7b4608d32a5 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
@@ -39,13 +39,13 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Mesh"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "uv_smooth", 0, "", ICON_NONE);
uiItemR(layout, ptr, "boundary_smooth", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometrySubdivisionSurface *data = MEM_cnew<NodeGeometrySubdivisionSurface>(__func__);
data->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES;
@@ -191,7 +191,7 @@ void register_node_type_geo_subdivision_surface()
ntype.declare = file_ns::node_declare;
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.draw_buttons = file_ns::node_layout;
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
node_type_storage(&ntype,
"NodeGeometrySubdivisionSurface",
diff --git a/source/blender/nodes/geometry/nodes/node_geo_switch.cc b/source/blender/nodes/geometry/nodes/node_geo_switch.cc
index ddc87e3dac4..bd3ac271817 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_switch.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_switch.cc
@@ -73,12 +73,12 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Image>(N_("Output"), "Output_011");
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "input_type", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeSwitch *data = MEM_cnew<NodeSwitch>(__func__);
data->input_type = SOCK_GEOMETRY;
@@ -89,8 +89,8 @@ static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeSwitch &storage = node_storage(*node);
int index = 0;
- bNodeSocket *field_switch = (bNodeSocket *)node->inputs.first;
- bNodeSocket *non_field_switch = (bNodeSocket *)field_switch->next;
+ bNodeSocket *field_switch = static_cast<bNodeSocket *>(node->inputs.first);
+ bNodeSocket *non_field_switch = static_cast<bNodeSocket *>(field_switch->next);
const bool fields_type = ELEM(
storage.input_type, SOCK_FLOAT, SOCK_INT, SOCK_BOOLEAN, SOCK_VECTOR, SOCK_RGBA, SOCK_STRING);
@@ -222,7 +222,7 @@ template<typename T> void switch_no_fields(GeoNodeExecParams &params, const Stri
static void node_geo_exec(GeoNodeExecParams params)
{
const NodeSwitch &storage = node_storage(params.node());
- const eNodeSocketDatatype data_type = static_cast<eNodeSocketDatatype>(storage.input_type);
+ const eNodeSocketDatatype data_type = eNodeSocketDatatype(storage.input_type);
switch (data_type) {
@@ -290,8 +290,8 @@ void register_node_type_geo_switch()
geo_node_type_base(&ntype, GEO_NODE_SWITCH, "Switch", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare;
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
node_type_storage(&ntype, "NodeSwitch", node_free_standard_storage, node_copy_standard_storage);
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.geometry_node_execute_supports_laziness = true;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc
deleted file mode 100644
index afc492c40e4..00000000000
--- a/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc
+++ /dev/null
@@ -1,830 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_generic_array.hh"
-#include "BLI_kdopbvh.h"
-#include "BLI_task.hh"
-
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_pointcloud_types.h"
-
-#include "BKE_attribute_math.hh"
-#include "BKE_bvhutils.h"
-#include "BKE_mesh.h"
-#include "BKE_mesh_runtime.h"
-#include "BKE_mesh_sample.hh"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "NOD_socket_search_link.hh"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_transfer_attribute_cc {
-
-using namespace blender::bke::mesh_surface_sample;
-
-NODE_STORAGE_FUNCS(NodeGeometryTransferAttribute)
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Source"))
- .supported_type({GEO_COMPONENT_TYPE_MESH,
- GEO_COMPONENT_TYPE_POINT_CLOUD,
- GEO_COMPONENT_TYPE_CURVE,
- GEO_COMPONENT_TYPE_INSTANCES});
-
- b.add_input<decl::Vector>(N_("Attribute")).hide_value().supports_field();
- b.add_input<decl::Float>(N_("Attribute"), "Attribute_001").hide_value().supports_field();
- b.add_input<decl::Color>(N_("Attribute"), "Attribute_002").hide_value().supports_field();
- b.add_input<decl::Bool>(N_("Attribute"), "Attribute_003").hide_value().supports_field();
- b.add_input<decl::Int>(N_("Attribute"), "Attribute_004").hide_value().supports_field();
-
- b.add_input<decl::Vector>(N_("Source Position"))
- .implicit_field()
- .make_available([](bNode &node) {
- node_storage(node).mode = GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED;
- });
- b.add_input<decl::Int>(N_("Index")).implicit_field().make_available([](bNode &node) {
- node_storage(node).mode = GEO_NODE_ATTRIBUTE_TRANSFER_INDEX;
- });
-
- b.add_output<decl::Vector>(N_("Attribute")).dependent_field({6, 7});
- b.add_output<decl::Float>(N_("Attribute"), "Attribute_001").dependent_field({6, 7});
- b.add_output<decl::Color>(N_("Attribute"), "Attribute_002").dependent_field({6, 7});
- b.add_output<decl::Bool>(N_("Attribute"), "Attribute_003").dependent_field({6, 7});
- b.add_output<decl::Int>(N_("Attribute"), "Attribute_004").dependent_field({6, 7});
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- const bNode &node = *static_cast<const bNode *>(ptr->data);
- const NodeGeometryTransferAttribute &storage = node_storage(node);
- const GeometryNodeAttributeTransferMode mapping = (GeometryNodeAttributeTransferMode)
- storage.mode;
-
- uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
- uiItemR(layout, ptr, "mapping", 0, "", ICON_NONE);
- if (mapping != GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED) {
- uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
- }
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeGeometryTransferAttribute *data = MEM_cnew<NodeGeometryTransferAttribute>(__func__);
- data->data_type = CD_PROP_FLOAT;
- data->mode = GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED;
- node->storage = data;
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- const NodeGeometryTransferAttribute &storage = node_storage(*node);
- const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
- const GeometryNodeAttributeTransferMode mapping = (GeometryNodeAttributeTransferMode)
- storage.mode;
-
- bNodeSocket *socket_geometry = (bNodeSocket *)node->inputs.first;
- bNodeSocket *socket_vector = socket_geometry->next;
- bNodeSocket *socket_float = socket_vector->next;
- bNodeSocket *socket_color4f = socket_float->next;
- bNodeSocket *socket_boolean = socket_color4f->next;
- bNodeSocket *socket_int32 = socket_boolean->next;
-
- bNodeSocket *socket_positions = socket_int32->next;
- bNodeSocket *socket_indices = socket_positions->next;
-
- nodeSetSocketAvailability(ntree, socket_vector, data_type == CD_PROP_FLOAT3);
- nodeSetSocketAvailability(ntree, socket_float, data_type == CD_PROP_FLOAT);
- nodeSetSocketAvailability(ntree, socket_color4f, data_type == CD_PROP_COLOR);
- nodeSetSocketAvailability(ntree, socket_boolean, data_type == CD_PROP_BOOL);
- nodeSetSocketAvailability(ntree, socket_int32, data_type == CD_PROP_INT32);
-
- nodeSetSocketAvailability(ntree, socket_positions, mapping != GEO_NODE_ATTRIBUTE_TRANSFER_INDEX);
- nodeSetSocketAvailability(ntree, socket_indices, mapping == GEO_NODE_ATTRIBUTE_TRANSFER_INDEX);
-
- bNodeSocket *out_socket_vector = (bNodeSocket *)node->outputs.first;
- bNodeSocket *out_socket_float = out_socket_vector->next;
- bNodeSocket *out_socket_color4f = out_socket_float->next;
- bNodeSocket *out_socket_boolean = out_socket_color4f->next;
- bNodeSocket *out_socket_int32 = out_socket_boolean->next;
-
- nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3);
- nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT);
- nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR);
- nodeSetSocketAvailability(ntree, out_socket_boolean, data_type == CD_PROP_BOOL);
- nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32);
-}
-
-static void node_gather_link_searches(GatherLinkSearchOpParams &params)
-{
- const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
- search_link_ops_for_declarations(params, declaration.inputs().take_back(2));
- search_link_ops_for_declarations(params, declaration.inputs().take_front(1));
-
- const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type(
- (eNodeSocketDatatype)params.other_socket().type);
- if (type && *type != CD_PROP_STRING) {
- /* The input and output sockets have the same name. */
- params.add_item(IFACE_("Attribute"), [type](LinkSearchOpParams &params) {
- bNode &node = params.add_node("GeometryNodeAttributeTransfer");
- node_storage(node).data_type = *type;
- params.update_and_connect_available_socket(node, "Attribute");
- });
- }
-}
-
-static void get_closest_in_bvhtree(BVHTreeFromMesh &tree_data,
- const VArray<float3> &positions,
- const IndexMask mask,
- const MutableSpan<int> r_indices,
- const MutableSpan<float> r_distances_sq,
- const MutableSpan<float3> r_positions)
-{
- BLI_assert(positions.size() >= r_indices.size());
- BLI_assert(positions.size() >= r_distances_sq.size());
- BLI_assert(positions.size() >= r_positions.size());
-
- for (const int i : mask) {
- BVHTreeNearest nearest;
- nearest.dist_sq = FLT_MAX;
- const float3 position = positions[i];
- BLI_bvhtree_find_nearest(
- tree_data.tree, position, &nearest, tree_data.nearest_callback, &tree_data);
- if (!r_indices.is_empty()) {
- r_indices[i] = nearest.index;
- }
- if (!r_distances_sq.is_empty()) {
- r_distances_sq[i] = nearest.dist_sq;
- }
- if (!r_positions.is_empty()) {
- r_positions[i] = nearest.co;
- }
- }
-}
-
-static void get_closest_pointcloud_points(const PointCloud &pointcloud,
- const VArray<float3> &positions,
- const IndexMask mask,
- const MutableSpan<int> r_indices,
- const MutableSpan<float> r_distances_sq)
-{
- BLI_assert(positions.size() >= r_indices.size());
- BLI_assert(pointcloud.totpoint > 0);
-
- BVHTreeFromPointCloud tree_data;
- BKE_bvhtree_from_pointcloud_get(&tree_data, &pointcloud, 2);
-
- for (const int i : mask) {
- BVHTreeNearest nearest;
- nearest.dist_sq = FLT_MAX;
- const float3 position = positions[i];
- BLI_bvhtree_find_nearest(
- tree_data.tree, position, &nearest, tree_data.nearest_callback, &tree_data);
- r_indices[i] = nearest.index;
- if (!r_distances_sq.is_empty()) {
- r_distances_sq[i] = nearest.dist_sq;
- }
- }
-
- free_bvhtree_from_pointcloud(&tree_data);
-}
-
-static void get_closest_mesh_points(const Mesh &mesh,
- const VArray<float3> &positions,
- const IndexMask mask,
- const MutableSpan<int> r_point_indices,
- const MutableSpan<float> r_distances_sq,
- const MutableSpan<float3> r_positions)
-{
- BLI_assert(mesh.totvert > 0);
- BVHTreeFromMesh tree_data;
- BKE_bvhtree_from_mesh_get(&tree_data, &mesh, BVHTREE_FROM_VERTS, 2);
- get_closest_in_bvhtree(tree_data, positions, mask, r_point_indices, r_distances_sq, r_positions);
- free_bvhtree_from_mesh(&tree_data);
-}
-
-static void get_closest_mesh_edges(const Mesh &mesh,
- const VArray<float3> &positions,
- const IndexMask mask,
- const MutableSpan<int> r_edge_indices,
- const MutableSpan<float> r_distances_sq,
- const MutableSpan<float3> r_positions)
-{
- BLI_assert(mesh.totedge > 0);
- BVHTreeFromMesh tree_data;
- BKE_bvhtree_from_mesh_get(&tree_data, &mesh, BVHTREE_FROM_EDGES, 2);
- get_closest_in_bvhtree(tree_data, positions, mask, r_edge_indices, r_distances_sq, r_positions);
- free_bvhtree_from_mesh(&tree_data);
-}
-
-static void get_closest_mesh_looptris(const Mesh &mesh,
- const VArray<float3> &positions,
- const IndexMask mask,
- const MutableSpan<int> r_looptri_indices,
- const MutableSpan<float> r_distances_sq,
- const MutableSpan<float3> r_positions)
-{
- BLI_assert(mesh.totpoly > 0);
- BVHTreeFromMesh tree_data;
- BKE_bvhtree_from_mesh_get(&tree_data, &mesh, BVHTREE_FROM_LOOPTRI, 2);
- get_closest_in_bvhtree(
- tree_data, positions, mask, r_looptri_indices, r_distances_sq, r_positions);
- free_bvhtree_from_mesh(&tree_data);
-}
-
-static void get_closest_mesh_polys(const Mesh &mesh,
- const VArray<float3> &positions,
- const IndexMask mask,
- const MutableSpan<int> r_poly_indices,
- const MutableSpan<float> r_distances_sq,
- const MutableSpan<float3> r_positions)
-{
- BLI_assert(mesh.totpoly > 0);
-
- Array<int> looptri_indices(positions.size());
- get_closest_mesh_looptris(mesh, positions, mask, looptri_indices, r_distances_sq, r_positions);
-
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
- BKE_mesh_runtime_looptri_len(&mesh)};
-
- for (const int i : mask) {
- const MLoopTri &looptri = looptris[looptri_indices[i]];
- r_poly_indices[i] = looptri.poly;
- }
-}
-
-/* The closest corner is defined to be the closest corner on the closest face. */
-static void get_closest_mesh_corners(const Mesh &mesh,
- const VArray<float3> &positions,
- const IndexMask mask,
- const MutableSpan<int> r_corner_indices,
- const MutableSpan<float> r_distances_sq,
- const MutableSpan<float3> r_positions)
-{
- const Span<MVert> verts = mesh.verts();
- const Span<MPoly> polys = mesh.polys();
- const Span<MLoop> loops = mesh.loops();
-
- BLI_assert(mesh.totloop > 0);
- Array<int> poly_indices(positions.size());
- get_closest_mesh_polys(mesh, positions, mask, poly_indices, {}, {});
-
- for (const int i : mask) {
- const float3 position = positions[i];
- const int poly_index = poly_indices[i];
- const MPoly &poly = polys[poly_index];
-
- /* Find the closest vertex in the polygon. */
- float min_distance_sq = FLT_MAX;
- const MVert *closest_mvert;
- int closest_loop_index = 0;
- for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
- const MLoop &loop = loops[loop_index];
- const int vertex_index = loop.v;
- const MVert &mvert = verts[vertex_index];
- const float distance_sq = math::distance_squared(position, float3(mvert.co));
- if (distance_sq < min_distance_sq) {
- min_distance_sq = distance_sq;
- closest_loop_index = loop_index;
- closest_mvert = &mvert;
- }
- }
- if (!r_corner_indices.is_empty()) {
- r_corner_indices[i] = closest_loop_index;
- }
- if (!r_positions.is_empty()) {
- r_positions[i] = closest_mvert->co;
- }
- if (!r_distances_sq.is_empty()) {
- r_distances_sq[i] = min_distance_sq;
- }
- }
-}
-
-template<typename T>
-void copy_with_indices(const VArray<T> &src,
- const IndexMask mask,
- const Span<int> indices,
- const MutableSpan<T> dst)
-{
- if (src.is_empty()) {
- return;
- }
- for (const int i : mask) {
- dst[i] = src[indices[i]];
- }
-}
-
-template<typename T>
-void copy_with_indices_clamped(const VArray<T> &src,
- const IndexMask mask,
- const VArray<int> &indices,
- const MutableSpan<T> dst)
-{
- if (src.is_empty()) {
- return;
- }
- const int max_index = src.size() - 1;
- threading::parallel_for(mask.index_range(), 4096, [&](IndexRange range) {
- for (const int i : range) {
- const int index = mask[i];
- dst[index] = src[std::clamp(indices[index], 0, max_index)];
- }
- });
-}
-
-template<typename T>
-void copy_with_indices_and_comparison(const VArray<T> &src_1,
- const VArray<T> &src_2,
- const Span<float> distances_1,
- const Span<float> distances_2,
- const IndexMask mask,
- const Span<int> indices_1,
- const Span<int> indices_2,
- const MutableSpan<T> dst)
-{
- if (src_1.is_empty() || src_2.is_empty()) {
- return;
- }
- for (const int i : mask) {
- if (distances_1[i] < distances_2[i]) {
- dst[i] = src_1[indices_1[i]];
- }
- else {
- dst[i] = src_2[indices_2[i]];
- }
- }
-}
-
-static bool component_is_available(const GeometrySet &geometry,
- const GeometryComponentType type,
- const eAttrDomain domain)
-{
- if (!geometry.has(type)) {
- return false;
- }
- const GeometryComponent &component = *geometry.get_component_for_read(type);
- if (component.is_empty()) {
- return false;
- }
- return component.attribute_domain_size(domain) != 0;
-}
-
-/**
- * \note Multi-threading for this function is provided by the field evaluator. Since the #call
- * function could be called many times, calculate the data from the source geometry once and store
- * it for later.
- */
-class NearestInterpolatedTransferFunction : public fn::MultiFunction {
- GeometrySet source_;
- GField src_field_;
-
- /**
- * This function is meant to sample the surface of a mesh rather than take the value from
- * individual elements, so use the most complex domain, ensuring no information is lost. In the
- * future, it should be possible to use the most complex domain required by the field inputs, to
- * simplify sampling and avoid domain conversions.
- */
- eAttrDomain domain_ = ATTR_DOMAIN_CORNER;
-
- fn::MFSignature signature_;
-
- std::optional<bke::MeshFieldContext> source_context_;
- std::unique_ptr<FieldEvaluator> source_evaluator_;
- const GVArray *source_data_;
-
- public:
- NearestInterpolatedTransferFunction(GeometrySet geometry, GField src_field)
- : source_(std::move(geometry)), src_field_(std::move(src_field))
- {
- source_.ensure_owns_direct_data();
- signature_ = this->create_signature();
- this->set_signature(&signature_);
- this->evaluate_source_field();
- }
-
- fn::MFSignature create_signature()
- {
- blender::fn::MFSignatureBuilder signature{"Attribute Transfer Nearest Interpolated"};
- signature.single_input<float3>("Position");
- signature.single_output("Attribute", src_field_.cpp_type());
- return signature.build();
- }
-
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
- {
- const VArray<float3> &positions = params.readonly_single_input<float3>(0, "Position");
- GMutableSpan dst = params.uninitialized_single_output_if_required(1, "Attribute");
-
- const MeshComponent &mesh_component = *source_.get_component_for_read<MeshComponent>();
- BLI_assert(mesh_component.has_mesh());
- const Mesh &mesh = *mesh_component.get_for_read();
- BLI_assert(mesh.totpoly > 0);
-
- /* Find closest points on the mesh surface. */
- Array<int> looptri_indices(mask.min_array_size());
- Array<float3> sampled_positions(mask.min_array_size());
- get_closest_mesh_looptris(mesh, positions, mask, looptri_indices, {}, sampled_positions);
-
- MeshAttributeInterpolator interp(&mesh, mask, sampled_positions, looptri_indices);
- interp.sample_data(*source_data_, domain_, eAttributeMapMode::INTERPOLATED, dst);
- }
-
- private:
- void evaluate_source_field()
- {
- const Mesh &mesh = *source_.get_mesh_for_read();
- source_context_.emplace(bke::MeshFieldContext{mesh, domain_});
- const int domain_size = mesh.attributes().domain_size(domain_);
- source_evaluator_ = std::make_unique<FieldEvaluator>(*source_context_, domain_size);
- source_evaluator_->add(src_field_);
- source_evaluator_->evaluate();
- source_data_ = &source_evaluator_->get_evaluated(0);
- }
-};
-
-/**
- * \note Multi-threading for this function is provided by the field evaluator. Since the #call
- * function could be called many times, calculate the data from the source geometry once and store
- * it for later.
- */
-class NearestTransferFunction : public fn::MultiFunction {
- GeometrySet source_;
- GField src_field_;
- eAttrDomain domain_;
-
- fn::MFSignature signature_;
-
- bool use_mesh_;
- bool use_points_;
-
- /* Store data from the source as a virtual array, since we may only access a few indices. */
- std::optional<bke::MeshFieldContext> mesh_context_;
- std::unique_ptr<FieldEvaluator> mesh_evaluator_;
- const GVArray *mesh_data_;
-
- std::optional<bke::PointCloudFieldContext> point_context_;
- std::unique_ptr<FieldEvaluator> point_evaluator_;
- const GVArray *point_data_;
-
- public:
- NearestTransferFunction(GeometrySet geometry, GField src_field, eAttrDomain domain)
- : source_(std::move(geometry)), src_field_(std::move(src_field)), domain_(domain)
- {
- source_.ensure_owns_direct_data();
- signature_ = this->create_signature();
- this->set_signature(&signature_);
-
- this->use_mesh_ = component_is_available(source_, GEO_COMPONENT_TYPE_MESH, domain_);
- this->use_points_ = component_is_available(source_, GEO_COMPONENT_TYPE_POINT_CLOUD, domain_);
-
- this->evaluate_source_field();
- }
-
- fn::MFSignature create_signature()
- {
- blender::fn::MFSignatureBuilder signature{"Attribute Transfer Nearest"};
- signature.single_input<float3>("Position");
- signature.single_output("Attribute", src_field_.cpp_type());
- return signature.build();
- }
-
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
- {
- const VArray<float3> &positions = params.readonly_single_input<float3>(0, "Position");
- GMutableSpan dst = params.uninitialized_single_output_if_required(1, "Attribute");
-
- if (!use_mesh_ && !use_points_) {
- dst.type().value_initialize_indices(dst.data(), mask);
- return;
- }
-
- const Mesh *mesh = use_mesh_ ? source_.get_mesh_for_read() : nullptr;
- const PointCloud *pointcloud = use_points_ ? source_.get_pointcloud_for_read() : nullptr;
-
- const int tot_samples = mask.min_array_size();
-
- Array<int> point_indices;
- Array<float> point_distances;
-
- /* Depending on where what domain the source attribute lives, these indices are either vertex,
- * corner, edge or polygon indices. */
- Array<int> mesh_indices;
- Array<float> mesh_distances;
-
- /* If there is a point cloud, find the closest points. */
- if (use_points_) {
- point_indices.reinitialize(tot_samples);
- if (use_mesh_) {
- point_distances.reinitialize(tot_samples);
- }
- get_closest_pointcloud_points(*pointcloud, positions, mask, point_indices, point_distances);
- }
-
- /* If there is a mesh, find the closest mesh elements. */
- if (use_mesh_) {
- mesh_indices.reinitialize(tot_samples);
- if (use_points_) {
- mesh_distances.reinitialize(tot_samples);
- }
- switch (domain_) {
- case ATTR_DOMAIN_POINT: {
- get_closest_mesh_points(*mesh, positions, mask, mesh_indices, mesh_distances, {});
- break;
- }
- case ATTR_DOMAIN_EDGE: {
- get_closest_mesh_edges(*mesh, positions, mask, mesh_indices, mesh_distances, {});
- break;
- }
- case ATTR_DOMAIN_FACE: {
- get_closest_mesh_polys(*mesh, positions, mask, mesh_indices, mesh_distances, {});
- break;
- }
- case ATTR_DOMAIN_CORNER: {
- get_closest_mesh_corners(*mesh, positions, mask, mesh_indices, mesh_distances, {});
- break;
- }
- default: {
- break;
- }
- }
- }
-
- attribute_math::convert_to_static_type(dst.type(), [&](auto dummy) {
- using T = decltype(dummy);
- if (use_mesh_ && use_points_) {
- VArray<T> src_mesh = mesh_data_->typed<T>();
- VArray<T> src_point = point_data_->typed<T>();
- copy_with_indices_and_comparison(src_mesh,
- src_point,
- mesh_distances,
- point_distances,
- mask,
- mesh_indices,
- point_indices,
- dst.typed<T>());
- }
- else if (use_points_) {
- VArray<T> src_point = point_data_->typed<T>();
- copy_with_indices(src_point, mask, point_indices, dst.typed<T>());
- }
- else if (use_mesh_) {
- VArray<T> src_mesh = mesh_data_->typed<T>();
- copy_with_indices(src_mesh, mask, mesh_indices, dst.typed<T>());
- }
- });
- }
-
- private:
- void evaluate_source_field()
- {
- if (use_mesh_) {
- const Mesh &mesh = *source_.get_mesh_for_read();
- const int domain_size = mesh.attributes().domain_size(domain_);
- mesh_context_.emplace(bke::MeshFieldContext(mesh, domain_));
- mesh_evaluator_ = std::make_unique<FieldEvaluator>(*mesh_context_, domain_size);
- mesh_evaluator_->add(src_field_);
- mesh_evaluator_->evaluate();
- mesh_data_ = &mesh_evaluator_->get_evaluated(0);
- }
-
- if (use_points_) {
- const PointCloud &points = *source_.get_pointcloud_for_read();
- point_context_.emplace(bke::PointCloudFieldContext(points));
- point_evaluator_ = std::make_unique<FieldEvaluator>(*point_context_, points.totpoint);
- point_evaluator_->add(src_field_);
- point_evaluator_->evaluate();
- point_data_ = &point_evaluator_->get_evaluated(0);
- }
- }
-};
-
-static const GeometryComponent *find_source_component(const GeometrySet &geometry,
- const eAttrDomain domain)
-{
- /* Choose the other component based on a consistent order, rather than some more complicated
- * heuristic. This is the same order visible in the spreadsheet and used in the ray-cast node. */
- static const Array<GeometryComponentType> supported_types = {GEO_COMPONENT_TYPE_MESH,
- GEO_COMPONENT_TYPE_POINT_CLOUD,
- GEO_COMPONENT_TYPE_CURVE,
- GEO_COMPONENT_TYPE_INSTANCES};
- for (const GeometryComponentType src_type : supported_types) {
- if (component_is_available(geometry, src_type, domain)) {
- return geometry.get_component_for_read(src_type);
- }
- }
-
- return nullptr;
-}
-
-/**
- * The index-based transfer theoretically does not need realized data when there is only one
- * instance geometry set in the source. A future optimization could be removing that limitation
- * internally.
- */
-class IndexTransferFunction : public fn::MultiFunction {
- GeometrySet src_geometry_;
- GField src_field_;
- eAttrDomain domain_;
-
- fn::MFSignature signature_;
-
- std::optional<bke::GeometryFieldContext> geometry_context_;
- std::unique_ptr<FieldEvaluator> evaluator_;
- const GVArray *src_data_ = nullptr;
-
- public:
- IndexTransferFunction(GeometrySet geometry, GField src_field, const eAttrDomain domain)
- : src_geometry_(std::move(geometry)), src_field_(std::move(src_field)), domain_(domain)
- {
- src_geometry_.ensure_owns_direct_data();
-
- signature_ = this->create_signature();
- this->set_signature(&signature_);
-
- this->evaluate_field();
- }
-
- fn::MFSignature create_signature()
- {
- fn::MFSignatureBuilder signature{"Attribute Transfer Index"};
- signature.single_input<int>("Index");
- signature.single_output("Attribute", src_field_.cpp_type());
- return signature.build();
- }
-
- void evaluate_field()
- {
- const GeometryComponent *component = find_source_component(src_geometry_, domain_);
- if (component == nullptr) {
- return;
- }
- const int domain_num = component->attribute_domain_size(domain_);
- geometry_context_.emplace(bke::GeometryFieldContext(*component, domain_));
- evaluator_ = std::make_unique<FieldEvaluator>(*geometry_context_, domain_num);
- evaluator_->add(src_field_);
- evaluator_->evaluate();
- src_data_ = &evaluator_->get_evaluated(0);
- }
-
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
- {
- const VArray<int> &indices = params.readonly_single_input<int>(0, "Index");
- GMutableSpan dst = params.uninitialized_single_output(1, "Attribute");
-
- const CPPType &type = dst.type();
- if (src_data_ == nullptr) {
- type.value_initialize_indices(dst.data(), mask);
- return;
- }
-
- attribute_math::convert_to_static_type(type, [&](auto dummy) {
- using T = decltype(dummy);
- copy_with_indices_clamped(src_data_->typed<T>(), mask, indices, dst.typed<T>());
- });
- }
-};
-
-static GField get_input_attribute_field(GeoNodeExecParams &params, const eCustomDataType data_type)
-{
- switch (data_type) {
- case CD_PROP_FLOAT:
- return params.extract_input<Field<float>>("Attribute_001");
- case CD_PROP_FLOAT3:
- return params.extract_input<Field<float3>>("Attribute");
- case CD_PROP_COLOR:
- return params.extract_input<Field<ColorGeometry4f>>("Attribute_002");
- case CD_PROP_BOOL:
- return params.extract_input<Field<bool>>("Attribute_003");
- case CD_PROP_INT32:
- return params.extract_input<Field<int>>("Attribute_004");
- default:
- BLI_assert_unreachable();
- }
- return {};
-}
-
-static void output_attribute_field(GeoNodeExecParams &params, GField field)
-{
- switch (bke::cpp_type_to_custom_data_type(field.cpp_type())) {
- case CD_PROP_FLOAT: {
- params.set_output("Attribute_001", Field<float>(field));
- break;
- }
- case CD_PROP_FLOAT3: {
- params.set_output("Attribute", Field<float3>(field));
- break;
- }
- case CD_PROP_COLOR: {
- params.set_output("Attribute_002", Field<ColorGeometry4f>(field));
- break;
- }
- case CD_PROP_BOOL: {
- params.set_output("Attribute_003", Field<bool>(field));
- break;
- }
- case CD_PROP_INT32: {
- params.set_output("Attribute_004", Field<int>(field));
- break;
- }
- default:
- break;
- }
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry = params.extract_input<GeometrySet>("Source");
- const NodeGeometryTransferAttribute &storage = node_storage(params.node());
- const GeometryNodeAttributeTransferMode mapping = (GeometryNodeAttributeTransferMode)
- storage.mode;
- const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
- const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain);
-
- GField field = get_input_attribute_field(params, data_type);
-
- auto return_default = [&]() {
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
- using T = decltype(dummy);
- output_attribute_field(params, fn::make_constant_field<T>(T()));
- });
- };
-
- GField output_field;
- switch (mapping) {
- case GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED: {
- const Mesh *mesh = geometry.get_mesh_for_read();
- if (mesh == nullptr) {
- if (!geometry.is_empty()) {
- params.error_message_add(NodeWarningType::Error,
- TIP_("The source geometry must contain a mesh"));
- }
- return return_default();
- }
- if (mesh->totpoly == 0) {
- /* Don't add a warning for empty meshes. */
- if (mesh->totvert != 0) {
- params.error_message_add(NodeWarningType::Error,
- TIP_("The source mesh must have faces"));
- }
- return return_default();
- }
- auto fn = std::make_unique<NearestInterpolatedTransferFunction>(std::move(geometry),
- std::move(field));
- auto op = std::make_shared<FieldOperation>(
- FieldOperation(std::move(fn), {params.extract_input<Field<float3>>("Source Position")}));
- output_field = GField(std::move(op));
- break;
- }
- case GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST: {
- if (geometry.has_curves() && !geometry.has_mesh() && !geometry.has_pointcloud()) {
- params.error_message_add(NodeWarningType::Error,
- TIP_("The source geometry must contain a mesh or a point cloud"));
- return return_default();
- }
- auto fn = std::make_unique<NearestTransferFunction>(
- std::move(geometry), std::move(field), domain);
- auto op = std::make_shared<FieldOperation>(
- FieldOperation(std::move(fn), {params.extract_input<Field<float3>>("Source Position")}));
- output_field = GField(std::move(op));
- break;
- }
- case GEO_NODE_ATTRIBUTE_TRANSFER_INDEX: {
- Field<int> indices = params.extract_input<Field<int>>("Index");
- auto fn = std::make_unique<IndexTransferFunction>(
- std::move(geometry), std::move(field), domain);
- auto op = std::make_shared<FieldOperation>(
- FieldOperation(std::move(fn), {std::move(indices)}));
- output_field = GField(std::move(op));
- break;
- }
- }
-
- output_attribute_field(params, std::move(output_field));
-}
-
-} // namespace blender::nodes::node_geo_transfer_attribute_cc
-
-void register_node_type_geo_transfer_attribute()
-{
- namespace file_ns = blender::nodes::node_geo_transfer_attribute_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_TRANSFER_ATTRIBUTE, "Transfer Attribute", NODE_CLASS_ATTRIBUTE);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
- node_type_storage(&ntype,
- "NodeGeometryTransferAttribute",
- node_free_standard_storage,
- node_copy_standard_storage);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform.cc b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
index 4130cad3bda..3c8a3f3ca76 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_transform.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
@@ -11,6 +11,7 @@
#include "DNA_volume_types.h"
#include "BKE_curves.hh"
+#include "BKE_instances.hh"
#include "BKE_mesh.h"
#include "BKE_pointcloud.h"
#include "BKE_volume.h"
@@ -67,18 +68,18 @@ static void transform_pointcloud(PointCloud &pointcloud, const float4x4 &transfo
position.finish();
}
-static void translate_instances(InstancesComponent &instances, const float3 translation)
+static void translate_instances(bke::Instances &instances, const float3 translation)
{
- MutableSpan<float4x4> transforms = instances.instance_transforms();
+ MutableSpan<float4x4> transforms = instances.transforms();
for (float4x4 &transform : transforms) {
add_v3_v3(transform.ptr()[3], translation);
}
}
-static void transform_instances(InstancesComponent &instances, const float4x4 &transform)
+static void transform_instances(bke::Instances &instances, const float4x4 &transform)
{
- MutableSpan<float4x4> instance_transforms = instances.instance_transforms();
- for (float4x4 &instance_transform : instance_transforms) {
+ MutableSpan<float4x4> transforms = instances.transforms();
+ for (float4x4 &instance_transform : transforms) {
instance_transform = transform * instance_transform;
}
}
@@ -185,8 +186,8 @@ static void translate_geometry_set(GeoNodeExecParams &params,
if (Volume *volume = geometry.get_volume_for_write()) {
translate_volume(params, *volume, translation, depsgraph);
}
- if (geometry.has_instances()) {
- translate_instances(geometry.get_component_for_write<InstancesComponent>(), translation);
+ if (bke::Instances *instances = geometry.get_instances_for_write()) {
+ translate_instances(*instances, translation);
}
if (bke::CurvesEditHints *curve_edit_hints = geometry.get_curve_edit_hints_for_write()) {
translate_curve_edit_hints(*curve_edit_hints, translation);
@@ -210,8 +211,8 @@ void transform_geometry_set(GeoNodeExecParams &params,
if (Volume *volume = geometry.get_volume_for_write()) {
transform_volume(params, *volume, transform, depsgraph);
}
- if (geometry.has_instances()) {
- transform_instances(geometry.get_component_for_write<InstancesComponent>(), transform);
+ if (bke::Instances *instances = geometry.get_instances_for_write()) {
+ transform_instances(*instances, transform);
}
if (bke::CurvesEditHints *curve_edit_hints = geometry.get_curve_edit_hints_for_write()) {
transform_curve_edit_hints(*curve_edit_hints, transform);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc
index 3e9fe99adb0..23052abddc4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc
@@ -2,6 +2,8 @@
#include "BLI_task.hh"
+#include "BKE_instances.hh"
+
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_translate_instances_cc {
@@ -15,10 +17,10 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Instances"));
}
-static void translate_instances(GeoNodeExecParams &params, InstancesComponent &instances_component)
+static void translate_instances(GeoNodeExecParams &params, bke::Instances &instances)
{
- const bke::InstancesFieldContext context{instances_component};
- fn::FieldEvaluator evaluator{context, instances_component.instances_num()};
+ const bke::InstancesFieldContext context{instances};
+ fn::FieldEvaluator evaluator{context, instances.instances_num()};
evaluator.set_selection(params.extract_input<Field<bool>>("Selection"));
evaluator.add(params.extract_input<Field<float3>>("Translation"));
evaluator.add(params.extract_input<Field<bool>>("Local Space"));
@@ -28,16 +30,16 @@ static void translate_instances(GeoNodeExecParams &params, InstancesComponent &i
const VArray<float3> translations = evaluator.get_evaluated<float3>(0);
const VArray<bool> local_spaces = evaluator.get_evaluated<bool>(1);
- MutableSpan<float4x4> instance_transforms = instances_component.instance_transforms();
+ MutableSpan<float4x4> transforms = instances.transforms();
threading::parallel_for(selection.index_range(), 1024, [&](IndexRange range) {
for (const int i_selection : range) {
const int i = selection[i_selection];
if (local_spaces[i]) {
- instance_transforms[i] *= float4x4::from_location(translations[i]);
+ transforms[i] *= float4x4::from_location(translations[i]);
}
else {
- add_v3_v3(instance_transforms[i].values[3], translations[i]);
+ add_v3_v3(transforms[i].values[3], translations[i]);
}
}
});
@@ -46,9 +48,8 @@ static void translate_instances(GeoNodeExecParams &params, InstancesComponent &i
static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Instances");
- if (geometry_set.has_instances()) {
- InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
- translate_instances(params, instances);
+ if (bke::Instances *instances = geometry_set.get_instances_for_write()) {
+ translate_instances(params, *instances);
}
params.set_output("Instances", std::move(geometry_set));
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc b/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc
index 57487059437..5cb78b3abe8 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc
@@ -23,13 +23,13 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Mesh"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "quad_method", 0, "", ICON_NONE);
uiItemR(layout, ptr, "ngon_method", 0, "", ICON_NONE);
}
-static void geo_triangulate_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void geo_triangulate_init(bNodeTree * /*tree*/, bNode *node)
{
node->custom1 = GEO_NODE_TRIANGULATE_QUAD_SHORTEDGE;
node->custom2 = GEO_NODE_TRIANGULATE_NGON_BEAUTY;
@@ -68,10 +68,8 @@ static void node_geo_exec(GeoNodeExecParams params)
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
const int min_vertices = std::max(params.extract_input<int>("Minimum Vertices"), 4);
- GeometryNodeTriangulateQuads quad_method = static_cast<GeometryNodeTriangulateQuads>(
- params.node().custom1);
- GeometryNodeTriangulateNGons ngon_method = static_cast<GeometryNodeTriangulateNGons>(
- params.node().custom2);
+ GeometryNodeTriangulateQuads quad_method = GeometryNodeTriangulateQuads(params.node().custom1);
+ GeometryNodeTriangulateNGons ngon_method = GeometryNodeTriangulateNGons(params.node().custom2);
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
if (!geometry_set.has_mesh()) {
@@ -102,7 +100,7 @@ void register_node_type_geo_triangulate()
geo_node_type_base(&ntype, GEO_NODE_TRIANGULATE, "Triangulate", NODE_CLASS_GEOMETRY);
ntype.declare = file_ns::node_declare;
- node_type_init(&ntype, file_ns::geo_triangulate_init);
+ ntype.initfunc = file_ns::geo_triangulate_init;
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc
index ccb489f6e29..c2d27cffa93 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc
@@ -114,10 +114,15 @@ class PackIslandsFieldInput final : public bke::MeshFieldInput {
GVArray get_varray_for_context(const Mesh &mesh,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const final
+ const IndexMask /*mask*/) const final
{
return construct_uv_gvarray(mesh, selection_field, uv_field, rotate, margin, domain);
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_CORNER;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc
index 801bc3f4642..eff3b969250 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc
@@ -40,14 +40,14 @@ static void node_declare(NodeDeclarationBuilder &b)
N_("UV coordinates between 0 and 1 for each face corner in the selected faces"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
uiItemR(layout, ptr, "method", 0, "", ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryUVUnwrap *data = MEM_cnew<NodeGeometryUVUnwrap>(__func__);
data->method = GEO_NODE_UV_UNWRAP_METHOD_ANGLE_BASED;
@@ -156,10 +156,15 @@ class UnwrapFieldInput final : public bke::MeshFieldInput {
GVArray get_varray_for_context(const Mesh &mesh,
const eAttrDomain domain,
- IndexMask UNUSED(mask)) const final
+ const IndexMask /*mask*/) const final
{
return construct_uv_gvarray(mesh, selection, seam, fill_holes, margin, method, domain);
}
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_CORNER;
+ }
};
static void node_geo_exec(GeoNodeExecParams params)
@@ -184,7 +189,7 @@ void register_node_type_geo_uv_unwrap()
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_UV_UNWRAP, "UV Unwrap", NODE_CLASS_CONVERTER);
- node_type_init(&ntype, file_ns::node_init);
+ ntype.initfunc = file_ns::node_init;
node_type_storage(
&ntype, "NodeGeometryUVUnwrap", node_free_standard_storage, node_copy_standard_storage);
ntype.declare = file_ns::node_declare;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_viewer.cc b/source/blender/nodes/geometry/nodes/node_geo_viewer.cc
index 6979693e215..53a8cd79f52 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_viewer.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_viewer.cc
@@ -6,7 +6,7 @@
#include "UI_resources.h"
#include "ED_node.h"
-#include "ED_spreadsheet.h"
+#include "ED_viewer_path.hh"
#include "NOD_socket_search_link.hh"
@@ -26,15 +26,21 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Bool>(N_("Value"), "Value_004").supports_field().hide_value();
}
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryViewer *data = MEM_cnew<NodeGeometryViewer>(__func__);
data->data_type = CD_PROP_FLOAT;
+ data->domain = ATTR_DOMAIN_AUTO;
node->storage = data;
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
+}
+
+static void node_layout_ex(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
}
@@ -61,7 +67,7 @@ static eNodeSocketDatatype custom_data_type_to_socket_type(const eCustomDataType
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryViewer &storage = node_storage(*node);
- const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
+ const eCustomDataType data_type = eCustomDataType(storage.data_type);
const eNodeSocketDatatype socket_type = custom_data_type_to_socket_type(data_type);
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
@@ -79,7 +85,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
SpaceNode *snode = CTX_wm_space_node(&params.C);
Main *bmain = CTX_data_main(&params.C);
ED_node_set_active(bmain, snode, &params.node_tree, &viewer_node, nullptr);
- ED_spreadsheet_context_paths_set_geometry_node(bmain, snode, &viewer_node);
+ ed::viewer_path::activate_geometry_node(*bmain, *snode, viewer_node);
};
const std::optional<eCustomDataType> type = node_socket_to_custom_data_type(
@@ -129,10 +135,12 @@ void register_node_type_geo_viewer()
geo_node_type_base(&ntype, GEO_NODE_VIEWER, "Viewer", NODE_CLASS_OUTPUT);
node_type_storage(
&ntype, "NodeGeometryViewer", node_free_standard_storage, node_copy_standard_storage);
- node_type_update(&ntype, file_ns::node_update);
- node_type_init(&ntype, file_ns::node_init);
+ ntype.updatefunc = file_ns::node_update;
+ ntype.initfunc = file_ns::node_init;
ntype.declare = file_ns::node_declare;
- ntype.draw_buttons_ex = file_ns::node_layout;
+ ntype.draw_buttons = file_ns::node_layout;
+ ntype.draw_buttons_ex = file_ns::node_layout_ex;
ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
+ ntype.no_muting = true;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_volume_cube.cc b/source/blender/nodes/geometry/nodes/node_geo_volume_cube.cc
index e964bf03ed2..7d439309380 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_volume_cube.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_volume_cube.cc
@@ -75,13 +75,12 @@ class Grid3DFieldContext : public FieldContext {
int64_t points_num() const
{
- return static_cast<int64_t>(resolution_.x) * static_cast<int64_t>(resolution_.y) *
- static_cast<int64_t>(resolution_.z);
+ return int64_t(resolution_.x) * int64_t(resolution_.y) * int64_t(resolution_.z);
}
GVArray get_varray_for_input(const FieldInput &field_input,
- const IndexMask UNUSED(mask),
- ResourceScope &UNUSED(scope)) const
+ const IndexMask /*mask*/,
+ ResourceScope & /*scope*/) const
{
const bke::AttributeFieldInput *attribute_field_input =
dynamic_cast<const bke::AttributeFieldInput *>(&field_input);
@@ -113,9 +112,9 @@ class Grid3DFieldContext : public FieldContext {
}
};
-#ifdef WITH_OPENVDB
static void node_geo_exec(GeoNodeExecParams params)
{
+#ifdef WITH_OPENVDB
const float3 bounds_min = params.extract_input<float3>("Min");
const float3 bounds_max = params.extract_input<float3>("Max");
@@ -169,7 +168,7 @@ static void node_geo_exec(GeoNodeExecParams params)
grid->transform().postTranslate(
openvdb::math::Vec3<float>(bounds_min.x, bounds_min.y, bounds_min.z));
- Volume *volume = (Volume *)BKE_id_new_nomain(ID_VO, nullptr);
+ Volume *volume = reinterpret_cast<Volume *>(BKE_id_new_nomain(ID_VO, nullptr));
BKE_volume_init_grids(volume);
BKE_volume_grid_add_vdb(*volume, "density", std::move(grid));
@@ -177,16 +176,12 @@ static void node_geo_exec(GeoNodeExecParams params)
GeometrySet r_geometry_set;
r_geometry_set.replace_volume(volume);
params.set_output("Volume", r_geometry_set);
-}
-
#else
-static void node_geo_exec(GeoNodeExecParams params)
-{
+ params.set_default_remaining_outputs();
params.error_message_add(NodeWarningType::Error,
TIP_("Disabled, Blender was compiled without OpenVDB"));
- params.set_default_remaining_outputs();
+#endif
}
-#endif /* WITH_OPENVDB */
} // namespace blender::nodes::node_geo_volume_cube_cc
diff --git a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
index 46708f53087..c076a6c08f3 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
@@ -48,14 +48,14 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Mesh"));
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
uiItemR(layout, ptr, "resolution_mode", 0, IFACE_("Resolution"), ICON_NONE);
}
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometryVolumeToMesh *data = MEM_cnew<NodeGeometryVolumeToMesh>(__func__);
data->resolution_mode = VOLUME_TO_MESH_RESOLUTION_MODE_GRID;
@@ -187,20 +187,19 @@ static Mesh *create_mesh_from_volume(GeometrySet &geometry_set, GeoNodeExecParam
static void node_geo_exec(GeoNodeExecParams params)
{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Volume");
-
#ifdef WITH_OPENVDB
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Volume");
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
Mesh *mesh = create_mesh_from_volume(geometry_set, params);
geometry_set.replace_mesh(mesh);
geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_MESH});
});
+ params.set_output("Mesh", std::move(geometry_set));
#else
+ params.set_default_remaining_outputs();
params.error_message_add(NodeWarningType::Error,
TIP_("Disabled, Blender was compiled without OpenVDB"));
#endif
-
- params.set_output("Mesh", std::move(geometry_set));
}
} // namespace blender::nodes::node_geo_volume_to_mesh_cc
@@ -216,8 +215,8 @@ void register_node_type_geo_volume_to_mesh()
node_type_storage(
&ntype, "NodeGeometryVolumeToMesh", node_free_standard_storage, node_copy_standard_storage);
node_type_size(&ntype, 170, 120, 700);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
+ ntype.initfunc = file_ns::node_init;
+ ntype.updatefunc = file_ns::node_update;
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/intern/derived_node_tree.cc b/source/blender/nodes/intern/derived_node_tree.cc
index e8e0f0fa61c..2ea80008af8 100644
--- a/source/blender/nodes/intern/derived_node_tree.cc
+++ b/source/blender/nodes/intern/derived_node_tree.cc
@@ -58,7 +58,7 @@ void DerivedNodeTree::destruct_context_recursively(DTreeContext *context)
bool DerivedNodeTree::has_link_cycles() const
{
for (const bNodeTree *btree : used_btrees_) {
- if (btree->has_link_cycle()) {
+ if (btree->has_available_link_cycle()) {
return true;
}
}
diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc
index e4d476e6374..197f0997160 100644
--- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc
+++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc
@@ -16,6 +16,7 @@
#include "NOD_multi_function.hh"
#include "NOD_node_declaration.hh"
+#include "BLI_lazy_threading.hh"
#include "BLI_map.hh"
#include "DNA_ID.h"
@@ -27,6 +28,8 @@
#include "FN_field_cpp_type.hh"
#include "FN_lazy_function_graph_executor.hh"
+#include "DEG_depsgraph_query.h"
+
namespace blender::nodes {
using fn::ValueOrField;
@@ -134,13 +137,14 @@ class LazyFunctionForGeometryNode : public LazyFunction {
if (geo_eval_log::GeoModifierLog *modifier_log = user_data->modifier_data->eval_log) {
geo_eval_log::GeoTreeLogger &tree_logger = modifier_log->get_local_tree_logger(
*user_data->compute_context);
- tree_logger.node_execution_times.append({node_.name, start_time, end_time});
+ tree_logger.node_execution_times.append(
+ {tree_logger.allocator->copy_string(node_.name), start_time, end_time});
}
}
};
/**
- * Used to gather all inputs of a multi-input socket. A separate node is necessary, because
+ * Used to gather all inputs of a multi-input socket. A separate node is necessary because
* multi-inputs are not supported in lazy-function graphs.
*/
class LazyFunctionForMultiInput : public LazyFunction {
@@ -154,8 +158,9 @@ class LazyFunctionForMultiInput : public LazyFunction {
base_type_ = get_socket_cpp_type(socket);
BLI_assert(base_type_ != nullptr);
BLI_assert(socket.is_multi_input());
+ const bNodeTree &btree = socket.owner_tree();
for (const bNodeLink *link : socket.directly_linked_links()) {
- if (!link->is_muted()) {
+ if (!(link->is_muted() || nodeIsDanglingReroute(&btree, link->fromnode))) {
inputs_.append({"Input", *base_type_});
}
}
@@ -164,14 +169,14 @@ class LazyFunctionForMultiInput : public LazyFunction {
outputs_.append({"Output", *vector_type});
}
- void execute_impl(lf::Params &params, const lf::Context &UNUSED(context)) const override
+ void execute_impl(lf::Params &params, const lf::Context & /*context*/) const override
{
/* Currently we only have multi-inputs for geometry and string sockets. This could be
* generalized in the future. */
base_type_->to_static_type_tag<GeometrySet, ValueOrField<std::string>>([&](auto type_tag) {
using T = typename decltype(type_tag)::type;
if constexpr (std::is_void_v<T>) {
- /* This type is not support in this node for now. */
+ /* This type is not supported in this node for now. */
BLI_assert_unreachable();
}
else {
@@ -198,7 +203,7 @@ class LazyFunctionForRerouteNode : public LazyFunction {
outputs_.append({"Output", type});
}
- void execute_impl(lf::Params &params, const lf::Context &UNUSED(context)) const override
+ void execute_impl(lf::Params &params, const lf::Context & /*context*/) const override
{
void *input_value = params.try_get_input_data_ptr(0);
void *output_value = params.get_output_data_ptr(0);
@@ -211,6 +216,28 @@ class LazyFunctionForRerouteNode : public LazyFunction {
};
/**
+ * Lazy functions for nodes whose type cannot be found. An undefined function just outputs default
+ * values. It's useful to have so other parts of the conversion don't have to care about undefined
+ * nodes.
+ */
+class LazyFunctionForUndefinedNode : public LazyFunction {
+ public:
+ LazyFunctionForUndefinedNode(const bNode &node, Vector<const bNodeSocket *> &r_used_outputs)
+ {
+ debug_name_ = "Undefined";
+ Vector<const bNodeSocket *> dummy_used_inputs;
+ Vector<lf::Input> dummy_inputs;
+ lazy_function_interface_from_node(
+ node, dummy_used_inputs, r_used_outputs, dummy_inputs, outputs_);
+ }
+
+ void execute_impl(lf::Params &params, const lf::Context & /*context*/) const override
+ {
+ params.set_default_remaining_outputs();
+ }
+};
+
+/**
* Executes a multi-function. If all inputs are single values, the results will also be single
* values. If any input is a field, the outputs will also be fields.
*/
@@ -325,7 +352,7 @@ class LazyFunctionForMutedNode : public LazyFunction {
}
}
- void execute_impl(lf::Params &params, const lf::Context &UNUSED(context)) const override
+ void execute_impl(lf::Params &params, const lf::Context & /*context*/) const override
{
for (const int output_i : outputs_.index_range()) {
if (params.output_was_set(output_i)) {
@@ -397,7 +424,7 @@ class LazyFunctionForMultiFunctionConversion : public LazyFunction {
outputs_.append({"To", to});
}
- void execute_impl(lf::Params &params, const lf::Context &UNUSED(context)) const override
+ void execute_impl(lf::Params &params, const lf::Context & /*context*/) const override
{
const void *from_value = params.try_get_input_data_ptr(0);
void *to_value = params.get_output_data_ptr(0);
@@ -416,18 +443,16 @@ class LazyFunctionForMultiFunctionConversion : public LazyFunction {
*/
class LazyFunctionForMultiFunctionNode : public LazyFunction {
private:
- const bNode &node_;
const NodeMultiFunctions::Item fn_item_;
Vector<const ValueOrFieldCPPType *> input_types_;
Vector<const ValueOrFieldCPPType *> output_types_;
- Vector<const bNodeSocket *> output_sockets_;
public:
LazyFunctionForMultiFunctionNode(const bNode &node,
NodeMultiFunctions::Item fn_item,
Vector<const bNodeSocket *> &r_used_inputs,
Vector<const bNodeSocket *> &r_used_outputs)
- : node_(node), fn_item_(std::move(fn_item))
+ : fn_item_(std::move(fn_item))
{
BLI_assert(fn_item_.fn != nullptr);
debug_name_ = node.name;
@@ -438,10 +463,9 @@ class LazyFunctionForMultiFunctionNode : public LazyFunction {
for (const lf::Output &fn_output : outputs_) {
output_types_.append(dynamic_cast<const ValueOrFieldCPPType *>(fn_output.type));
}
- output_sockets_ = r_used_outputs;
}
- void execute_impl(lf::Params &params, const lf::Context &UNUSED(context)) const override
+ void execute_impl(lf::Params &params, const lf::Context & /*context*/) const override
{
Vector<const void *> input_values(inputs_.size());
Vector<void *> output_values(outputs_.size());
@@ -478,7 +502,7 @@ class LazyFunctionForImplicitInput : public LazyFunction {
outputs_.append({"Output", type});
}
- void execute_impl(lf::Params &params, const lf::Context &UNUSED(context)) const override
+ void execute_impl(lf::Params &params, const lf::Context & /*context*/) const override
{
void *value = params.get_output_data_ptr(0);
init_fn_(value);
@@ -514,21 +538,61 @@ class LazyFunctionForViewerNode : public LazyFunction {
{
GeoNodesLFUserData *user_data = dynamic_cast<GeoNodesLFUserData *>(context.user_data);
BLI_assert(user_data != nullptr);
+ if (user_data->modifier_data == nullptr) {
+ return;
+ }
+ if (user_data->modifier_data->eval_log == nullptr) {
+ return;
+ }
GeometrySet geometry = params.extract_input<GeometrySet>(0);
+ const NodeGeometryViewer *storage = static_cast<NodeGeometryViewer *>(bnode_.storage);
- GField field;
if (use_field_input_) {
const void *value_or_field = params.try_get_input_data_ptr(1);
BLI_assert(value_or_field != nullptr);
const ValueOrFieldCPPType &value_or_field_type = static_cast<const ValueOrFieldCPPType &>(
*inputs_[1].type);
- field = value_or_field_type.as_field(value_or_field);
+ GField field = value_or_field_type.as_field(value_or_field);
+ const eAttrDomain domain = eAttrDomain(storage->domain);
+ const StringRefNull viewer_attribute_name = ".viewer";
+ if (domain == ATTR_DOMAIN_INSTANCE) {
+ if (geometry.has_instances()) {
+ GeometryComponent &component = geometry.get_component_for_write(
+ GEO_COMPONENT_TYPE_INSTANCES);
+ bke::try_capture_field_on_geometry(
+ component, viewer_attribute_name, ATTR_DOMAIN_INSTANCE, field);
+ }
+ }
+ else {
+ geometry.modify_geometry_sets([&](GeometrySet &geometry) {
+ for (const GeometryComponentType type : {GEO_COMPONENT_TYPE_MESH,
+ GEO_COMPONENT_TYPE_POINT_CLOUD,
+ GEO_COMPONENT_TYPE_CURVE}) {
+ if (geometry.has(type)) {
+ GeometryComponent &component = geometry.get_component_for_write(type);
+ eAttrDomain used_domain = domain;
+ if (used_domain == ATTR_DOMAIN_AUTO) {
+ if (const std::optional<eAttrDomain> detected_domain =
+ bke::try_detect_field_domain(component, field)) {
+ used_domain = *detected_domain;
+ }
+ else {
+ used_domain = type == GEO_COMPONENT_TYPE_MESH ? ATTR_DOMAIN_CORNER :
+ ATTR_DOMAIN_POINT;
+ }
+ }
+ bke::try_capture_field_on_geometry(
+ component, viewer_attribute_name, used_domain, field);
+ }
+ }
+ });
+ }
}
geo_eval_log::GeoTreeLogger &tree_logger =
user_data->modifier_data->eval_log->get_local_tree_logger(*user_data->compute_context);
- tree_logger.log_viewer_node(bnode_, geometry, field);
+ tree_logger.log_viewer_node(bnode_, std::move(geometry));
}
};
@@ -539,6 +603,8 @@ class LazyFunctionForViewerNode : public LazyFunction {
class LazyFunctionForGroupNode : public LazyFunction {
private:
const bNode &group_node_;
+ bool has_many_nodes_ = false;
+ bool use_fallback_outputs_ = false;
std::optional<GeometryNodesLazyFunctionLogger> lf_logger_;
std::optional<GeometryNodesLazyFunctionSideEffectProvider> lf_side_effect_provider_;
std::optional<lf::GraphExecutor> graph_executor_;
@@ -557,6 +623,8 @@ class LazyFunctionForGroupNode : public LazyFunction {
bNodeTree *group_btree = reinterpret_cast<bNodeTree *>(group_node_.id);
BLI_assert(group_btree != nullptr);
+ has_many_nodes_ = lf_graph_info.num_inline_nodes_approximate > 1000;
+
Vector<const lf::OutputSocket *> graph_inputs;
for (const lf::OutputSocket *socket : lf_graph_info.mapping.group_input_sockets) {
if (socket != nullptr) {
@@ -573,9 +641,12 @@ class LazyFunctionForGroupNode : public LazyFunction {
}
}
}
+ else {
+ use_fallback_outputs_ = true;
+ }
lf_logger_.emplace(lf_graph_info);
- lf_side_effect_provider_.emplace(lf_graph_info);
+ lf_side_effect_provider_.emplace();
graph_executor_.emplace(lf_graph_info.graph,
std::move(graph_inputs),
std::move(graph_outputs),
@@ -588,6 +659,17 @@ class LazyFunctionForGroupNode : public LazyFunction {
GeoNodesLFUserData *user_data = dynamic_cast<GeoNodesLFUserData *>(context.user_data);
BLI_assert(user_data != nullptr);
+ if (has_many_nodes_) {
+ /* If the called node group has many nodes, it's likely that executing it takes a while even
+ * if every individual node is very small. */
+ lazy_threading::send_hint();
+ }
+ if (use_fallback_outputs_) {
+ /* The node group itself does not have an output node, so use default values as outputs.
+ * The group should still be executed in case it has side effects. */
+ params.set_default_remaining_outputs();
+ }
+
/* The compute context changes when entering a node group. */
bke::NodeGroupComputeContext compute_context{user_data->compute_context, group_node_.name};
GeoNodesLFUserData group_user_data = *user_data;
@@ -599,12 +681,12 @@ class LazyFunctionForGroupNode : public LazyFunction {
graph_executor_->execute(params, group_context);
}
- void *init_storage(LinearAllocator<> &allocator) const
+ void *init_storage(LinearAllocator<> &allocator) const override
{
return graph_executor_->init_storage(allocator);
}
- void destruct_storage(void *storage) const
+ void destruct_storage(void *storage) const override
{
graph_executor_->destruct_storage(storage);
}
@@ -679,6 +761,7 @@ struct GeometryNodesLazyFunctionGraphBuilder {
this->add_default_inputs();
lf_graph_->update_node_indices();
+ lf_graph_info_->num_inline_nodes_approximate += lf_graph_->nodes().size();
}
private:
@@ -776,6 +859,11 @@ struct GeometryNodesLazyFunctionGraphBuilder {
*bnode);
if (fn_item.fn != nullptr) {
this->handle_multi_function_node(*bnode, fn_item);
+ break;
+ }
+ if (node_type == &NodeTypeUndefined) {
+ this->handle_undefined_node(*bnode);
+ break;
}
/* Nodes that don't match any of the criteria above are just ignored. */
break;
@@ -890,6 +978,8 @@ struct GeometryNodesLazyFunctionGraphBuilder {
mapping_->bsockets_by_lf_socket_map.add(&lf_socket, &bsocket);
}
mapping_->group_node_map.add(&bnode, &lf_node);
+ lf_graph_info_->num_inline_nodes_approximate +=
+ group_lf_graph_info->num_inline_nodes_approximate;
}
void handle_geometry_node(const bNode &bnode)
@@ -969,6 +1059,21 @@ struct GeometryNodesLazyFunctionGraphBuilder {
mapping_->viewer_node_map.add(&bnode, &lf_node);
}
+ void handle_undefined_node(const bNode &bnode)
+ {
+ Vector<const bNodeSocket *> used_outputs;
+ auto lazy_function = std::make_unique<LazyFunctionForUndefinedNode>(bnode, used_outputs);
+ lf::FunctionNode &lf_node = lf_graph_->add_function(*lazy_function);
+ lf_graph_info_->functions.append(std::move(lazy_function));
+
+ for (const int i : used_outputs.index_range()) {
+ const bNodeSocket &bsocket = *used_outputs[i];
+ lf::OutputSocket &lf_socket = lf_node.output(i);
+ output_socket_map_.add(&bsocket, &lf_socket);
+ mapping_->bsockets_by_lf_socket_map.add(&lf_socket, &bsocket);
+ }
+ }
+
void handle_links()
{
for (const auto item : output_socket_map_.items()) {
@@ -978,6 +1083,10 @@ struct GeometryNodesLazyFunctionGraphBuilder {
void insert_links_from_socket(const bNodeSocket &from_bsocket, lf::OutputSocket &from_lf_socket)
{
+ if (nodeIsDanglingReroute(&btree_, &from_bsocket.owner_node())) {
+ return;
+ }
+
const Span<const bNodeLink *> links_from_bsocket = from_bsocket.directly_linked_links();
struct TypeWithLinks {
@@ -991,10 +1100,10 @@ struct GeometryNodesLazyFunctionGraphBuilder {
if (link->is_muted()) {
continue;
}
- const bNodeSocket &to_bsocket = *link->tosock;
- if (!to_bsocket.is_available()) {
+ if (!link->is_available()) {
continue;
}
+ const bNodeSocket &to_bsocket = *link->tosock;
const CPPType *to_type = get_socket_cpp_type(to_bsocket);
if (to_type == nullptr) {
continue;
@@ -1044,7 +1153,8 @@ struct GeometryNodesLazyFunctionGraphBuilder {
if (multi_input_link == link) {
break;
}
- if (!multi_input_link->is_muted()) {
+ if (!(multi_input_link->is_muted() ||
+ nodeIsDanglingReroute(&btree_, multi_input_link->fromnode))) {
link_index++;
}
}
@@ -1135,79 +1245,41 @@ struct GeometryNodesLazyFunctionGraphBuilder {
bool try_add_implicit_input(const bNodeSocket &input_bsocket, lf::InputSocket &input_lf_socket)
{
const bNode &bnode = input_bsocket.owner_node();
- const NodeDeclaration *node_declaration = bnode.declaration();
- if (node_declaration == nullptr) {
+ const SocketDeclaration *socket_decl = input_bsocket.runtime->declaration;
+ if (socket_decl == nullptr) {
return false;
}
- const SocketDeclaration &socket_declaration =
- *node_declaration->inputs()[input_bsocket.index()];
- if (socket_declaration.input_field_type() != InputSocketFieldType::Implicit) {
+ if (socket_decl->input_field_type() != InputSocketFieldType::Implicit) {
return false;
}
- const CPPType &type = input_lf_socket.type();
- std::function<void(void *)> init_fn = this->get_implicit_input_init_function(bnode,
- input_bsocket);
- if (!init_fn) {
+ const ImplicitInputValueFn *implicit_input_fn = socket_decl->implicit_input_fn();
+ if (implicit_input_fn == nullptr) {
return false;
}
-
+ std::function<void(void *)> init_fn = [&bnode, implicit_input_fn](void *r_value) {
+ (*implicit_input_fn)(bnode, r_value);
+ };
+ const CPPType &type = input_lf_socket.type();
auto lazy_function = std::make_unique<LazyFunctionForImplicitInput>(type, std::move(init_fn));
lf::Node &lf_node = lf_graph_->add_function(*lazy_function);
lf_graph_info_->functions.append(std::move(lazy_function));
lf_graph_->add_link(lf_node.output(0), input_lf_socket);
return true;
}
-
- std::function<void(void *)> get_implicit_input_init_function(const bNode &bnode,
- const bNodeSocket &bsocket)
- {
- const bNodeSocketType &socket_type = *bsocket.typeinfo;
- if (socket_type.type == SOCK_VECTOR) {
- if (bnode.type == GEO_NODE_SET_CURVE_HANDLES) {
- StringRef side = ((NodeGeometrySetCurveHandlePositions *)bnode.storage)->mode ==
- GEO_NODE_CURVE_HANDLE_LEFT ?
- "handle_left" :
- "handle_right";
- return [side](void *r_value) {
- new (r_value) ValueOrField<float3>(bke::AttributeFieldInput::Create<float3>(side));
- };
- }
- else if (bnode.type == GEO_NODE_EXTRUDE_MESH) {
- return [](void *r_value) {
- new (r_value)
- ValueOrField<float3>(Field<float3>(std::make_shared<bke::NormalFieldInput>()));
- };
- }
- else {
- return [](void *r_value) {
- new (r_value) ValueOrField<float3>(bke::AttributeFieldInput::Create<float3>("position"));
- };
- }
- }
- else if (socket_type.type == SOCK_INT) {
- if (ELEM(bnode.type, FN_NODE_RANDOM_VALUE, GEO_NODE_INSTANCE_ON_POINTS)) {
- return [](void *r_value) {
- new (r_value)
- ValueOrField<int>(Field<int>(std::make_shared<bke::IDAttributeFieldInput>()));
- };
- }
- else {
- return [](void *r_value) {
- new (r_value) ValueOrField<int>(Field<int>(std::make_shared<fn::IndexFieldInput>()));
- };
- }
- }
- return {};
- }
};
const GeometryNodesLazyFunctionGraphInfo *ensure_geometry_nodes_lazy_function_graph(
const bNodeTree &btree)
{
btree.ensure_topology_cache();
- if (btree.has_link_cycle()) {
+ if (btree.has_available_link_cycle()) {
return nullptr;
}
+ if (const ID *id_orig = DEG_get_original_id(const_cast<ID *>(&btree.id))) {
+ if (id_orig->tag & LIB_TAG_MISSING) {
+ return nullptr;
+ }
+ }
std::unique_ptr<GeometryNodesLazyFunctionGraphInfo> &lf_graph_info_ptr =
btree.runtime->geometry_nodes_lazy_function_graph_info;
@@ -1300,12 +1372,6 @@ void GeometryNodesLazyFunctionLogger::dump_when_input_is_set_twice(
user_data->compute_context->print_stack(std::cout, ss.str());
}
-GeometryNodesLazyFunctionSideEffectProvider::GeometryNodesLazyFunctionSideEffectProvider(
- const GeometryNodesLazyFunctionGraphInfo &lf_graph_info)
- : lf_graph_info_(lf_graph_info)
-{
-}
-
Vector<const lf::FunctionNode *> GeometryNodesLazyFunctionSideEffectProvider::
get_nodes_with_side_effects(const lf::Context &context) const
{
@@ -1324,4 +1390,53 @@ GeometryNodesLazyFunctionGraphInfo::~GeometryNodesLazyFunctionGraphInfo()
}
}
+[[maybe_unused]] static void add_thread_id_debug_message(
+ const GeometryNodesLazyFunctionGraphInfo &lf_graph_info,
+ const lf::FunctionNode &node,
+ const lf::Context &context)
+{
+ static std::atomic<int> thread_id_source = 0;
+ static thread_local const int thread_id = thread_id_source.fetch_add(1);
+ static thread_local const std::string thread_id_str = "Thread: " + std::to_string(thread_id);
+
+ GeoNodesLFUserData *user_data = dynamic_cast<GeoNodesLFUserData *>(context.user_data);
+ BLI_assert(user_data != nullptr);
+ if (user_data->modifier_data->eval_log == nullptr) {
+ return;
+ }
+ geo_eval_log::GeoTreeLogger &tree_logger =
+ user_data->modifier_data->eval_log->get_local_tree_logger(*user_data->compute_context);
+
+ /* Find corresponding node based on the socket mapping. */
+ auto check_sockets = [&](const Span<const lf::Socket *> lf_sockets) {
+ for (const lf::Socket *lf_socket : lf_sockets) {
+ const Span<const bNodeSocket *> bsockets =
+ lf_graph_info.mapping.bsockets_by_lf_socket_map.lookup(lf_socket);
+ if (!bsockets.is_empty()) {
+ const bNodeSocket &bsocket = *bsockets[0];
+ const bNode &bnode = bsocket.owner_node();
+ tree_logger.debug_messages.append(
+ {tree_logger.allocator->copy_string(bnode.name), thread_id_str});
+ return true;
+ }
+ }
+ return false;
+ };
+
+ if (check_sockets(node.inputs().cast<const lf::Socket *>())) {
+ return;
+ }
+ check_sockets(node.outputs().cast<const lf::Socket *>());
+}
+
+void GeometryNodesLazyFunctionLogger::log_before_node_execute(const lf::FunctionNode &node,
+ const lf::Params & /*params*/,
+ const lf::Context &context) const
+{
+ /* Enable this to see the threads that invoked a node. */
+ if constexpr (false) {
+ add_thread_id_debug_message(lf_graph_info_, node, context);
+ }
+}
+
} // namespace blender::nodes
diff --git a/source/blender/nodes/intern/geometry_nodes_log.cc b/source/blender/nodes/intern/geometry_nodes_log.cc
index 350b199cd60..0f122307328 100644
--- a/source/blender/nodes/intern/geometry_nodes_log.cc
+++ b/source/blender/nodes/intern/geometry_nodes_log.cc
@@ -6,12 +6,15 @@
#include "BKE_compute_contexts.hh"
#include "BKE_curves.hh"
#include "BKE_node_runtime.hh"
+#include "BKE_viewer_path.h"
#include "FN_field_cpp_type.hh"
#include "DNA_modifier_types.h"
#include "DNA_space_types.h"
+#include "ED_viewer_path.hh"
+
namespace blender::nodes::geo_eval_log {
using fn::FieldInput;
@@ -35,8 +38,8 @@ FieldInfoLog::FieldInfoLog(const GField &field) : type(field.cpp_type())
std::sort(
field_inputs.begin(), field_inputs.end(), [](const FieldInput &a, const FieldInput &b) {
- const int index_a = (int)a.category();
- const int index_b = (int)b.category();
+ const int index_a = int(a.category());
+ const int index_b = int(b.category());
if (index_a == index_b) {
return a.socket_inspection_name().size() < b.socket_inspection_name().size();
}
@@ -66,7 +69,7 @@ GeometryInfoLog::GeometryInfoLog(const GeometrySet &geometry_set)
true,
[&](const bke::AttributeIDRef &attribute_id,
const bke::AttributeMetaData &meta_data,
- const GeometryComponent &UNUSED(component)) {
+ const GeometryComponent & /*component*/) {
if (attribute_id.is_named() && names.add(attribute_id.name())) {
this->attributes.append({attribute_id.name(), meta_data.domain, meta_data.data_type});
}
@@ -98,7 +101,7 @@ GeometryInfoLog::GeometryInfoLog(const GeometrySet &geometry_set)
case GEO_COMPONENT_TYPE_INSTANCES: {
const InstancesComponent &instances_component = *(const InstancesComponent *)component;
InstancesInfo &info = this->instances_info.emplace();
- info.instances_num = instances_component.instances_num();
+ info.instances_num = instances_component.attribute_domain_size(ATTR_DOMAIN_INSTANCE);
break;
}
case GEO_COMPONENT_TYPE_EDIT: {
@@ -148,7 +151,9 @@ void GeoTreeLogger::log_value(const bNode &node, const bNodeSocket &socket, cons
auto store_logged_value = [&](destruct_ptr<ValueLog> value_log) {
auto &socket_values = socket.in_out == SOCK_IN ? this->input_socket_values :
this->output_socket_values;
- socket_values.append({node.name, socket.identifier, std::move(value_log)});
+ socket_values.append({this->allocator->copy_string(node.name),
+ this->allocator->copy_string(socket.identifier),
+ std::move(value_log)});
};
auto log_generic_value = [&](const CPPType &type, const void *value) {
@@ -186,15 +191,12 @@ void GeoTreeLogger::log_value(const bNode &node, const bNodeSocket &socket, cons
}
}
-void GeoTreeLogger::log_viewer_node(const bNode &viewer_node,
- const GeometrySet &geometry,
- const GField &field)
+void GeoTreeLogger::log_viewer_node(const bNode &viewer_node, GeometrySet geometry)
{
destruct_ptr<ViewerNodeLog> log = this->allocator->construct<ViewerNodeLog>();
- log->geometry = geometry;
- log->field = field;
+ log->geometry = std::move(geometry);
log->geometry.ensure_owns_direct_data();
- this->viewer_node_logs.append({viewer_node.name, std::move(log)});
+ this->viewer_node_logs.append({this->allocator->copy_string(viewer_node.name), std::move(log)});
}
void GeoTreeLog::ensure_node_warnings()
@@ -315,11 +317,11 @@ void GeoTreeLog::ensure_used_named_attributes()
return;
}
- auto add_attribute = [&](const StringRef node_name,
- const StringRef attribute_name,
+ auto add_attribute = [&](const StringRefNull node_name,
+ const StringRefNull attribute_name,
const NamedAttributeUsage &usage) {
- this->nodes.lookup_or_add_as(node_name).used_named_attributes.lookup_or_add_as(attribute_name,
- usage) |= usage;
+ this->nodes.lookup_or_add_default(node_name).used_named_attributes.lookup_or_add(
+ attribute_name, usage) |= usage;
this->used_named_attributes.lookup_or_add_as(attribute_name, usage) |= usage;
};
@@ -543,29 +545,17 @@ GeoTreeLog *GeoModifierLog::get_tree_log_for_node_editor(const SpaceNode &snode)
return &modifier_log->get_tree_log(compute_context_builder.hash());
}
-const ViewerNodeLog *GeoModifierLog::find_viewer_node_log_for_spreadsheet(
- const SpaceSpreadsheet &sspreadsheet)
+const ViewerNodeLog *GeoModifierLog::find_viewer_node_log_for_path(const ViewerPath &viewer_path)
{
- Vector<const SpreadsheetContext *> context_path = sspreadsheet.context_path;
- if (context_path.size() < 3) {
- return nullptr;
- }
- if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) {
- return nullptr;
- }
- if (context_path[1]->type != SPREADSHEET_CONTEXT_MODIFIER) {
- return nullptr;
- }
- const SpreadsheetContextObject *object_context =
- reinterpret_cast<const SpreadsheetContextObject *>(context_path[0]);
- const SpreadsheetContextModifier *modifier_context =
- reinterpret_cast<const SpreadsheetContextModifier *>(context_path[1]);
- if (object_context->object == nullptr) {
+ const std::optional<ed::viewer_path::ViewerPathForGeometryNodesViewer> parsed_path =
+ ed::viewer_path::parse_geometry_nodes_viewer(viewer_path);
+ if (!parsed_path.has_value()) {
return nullptr;
}
+ const Object *object = parsed_path->object;
NodesModifierData *nmd = nullptr;
- LISTBASE_FOREACH (ModifierData *, md, &object_context->object->modifiers) {
- if (STREQ(md->name, modifier_context->modifier_name)) {
+ LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
+ if (md->name == parsed_path->modifier_name) {
if (md->type == eModifierType_Nodes) {
nmd = reinterpret_cast<NodesModifierData *>(md);
}
@@ -581,27 +571,16 @@ const ViewerNodeLog *GeoModifierLog::find_viewer_node_log_for_spreadsheet(
static_cast<nodes::geo_eval_log::GeoModifierLog *>(nmd->runtime_eval_log);
ComputeContextBuilder compute_context_builder;
- compute_context_builder.push<bke::ModifierComputeContext>(modifier_context->modifier_name);
- for (const SpreadsheetContext *context : context_path.as_span().drop_front(2).drop_back(1)) {
- if (context->type != SPREADSHEET_CONTEXT_NODE) {
- return nullptr;
- }
- const SpreadsheetContextNode &node_context = *reinterpret_cast<const SpreadsheetContextNode *>(
- context);
- compute_context_builder.push<bke::NodeGroupComputeContext>(node_context.node_name);
+ compute_context_builder.push<bke::ModifierComputeContext>(parsed_path->modifier_name);
+ for (const StringRef group_node_name : parsed_path->group_node_names) {
+ compute_context_builder.push<bke::NodeGroupComputeContext>(group_node_name);
}
const ComputeContextHash context_hash = compute_context_builder.hash();
nodes::geo_eval_log::GeoTreeLog &tree_log = modifier_log->get_tree_log(context_hash);
tree_log.ensure_viewer_node_logs();
- const SpreadsheetContext *last_context = context_path.last();
- if (last_context->type != SPREADSHEET_CONTEXT_NODE) {
- return nullptr;
- }
- const SpreadsheetContextNode &last_node_context =
- *reinterpret_cast<const SpreadsheetContextNode *>(last_context);
const ViewerNodeLog *viewer_log = tree_log.viewer_node_logs.lookup_default(
- last_node_context.node_name, nullptr);
+ parsed_path->viewer_node_name, nullptr);
return viewer_log;
}
diff --git a/source/blender/nodes/intern/node_common.cc b/source/blender/nodes/intern/node_common.cc
index 6402ec3f3d6..975bf0c01ca 100644
--- a/source/blender/nodes/intern/node_common.cc
+++ b/source/blender/nodes/intern/node_common.cc
@@ -22,6 +22,7 @@
#include "BLT_translation.h"
#include "BKE_node.h"
+#include "BKE_node_runtime.hh"
#include "BKE_node_tree_update.h"
#include "RNA_types.h"
@@ -63,7 +64,7 @@ bNodeSocket *node_group_find_output_socket(bNode *groupnode, const char *identif
return find_matching_socket(groupnode->outputs, identifier);
}
-void node_group_label(const bNodeTree *UNUSED(ntree), const bNode *node, char *label, int maxlen)
+void node_group_label(const bNodeTree * /*ntree*/, const bNode *node, char *label, int maxlen)
{
BLI_strncpy(label, (node->id) ? node->id->name + 2 : IFACE_("Missing Data-Block"), maxlen);
}
@@ -82,10 +83,10 @@ bool node_group_poll_instance(bNode *node, bNodeTree *nodetree, const char **dis
return false;
}
-bool nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree, const char **r_disabled_hint)
+bool nodeGroupPoll(const bNodeTree *nodetree,
+ const bNodeTree *grouptree,
+ const char **r_disabled_hint)
{
- bool valid = true;
-
/* unspecified node group, generally allowed
* (if anything, should be avoided on operator level)
*/
@@ -94,18 +95,20 @@ bool nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree, const char **r_dis
}
if (nodetree == grouptree) {
- *r_disabled_hint = TIP_("Nesting a node group inside of itself is not allowed");
+ if (r_disabled_hint) {
+ *r_disabled_hint = TIP_("Nesting a node group inside of itself is not allowed");
+ }
return false;
}
- LISTBASE_FOREACH (bNode *, node, &grouptree->nodes) {
+ LISTBASE_FOREACH (const bNode *, node, &grouptree->nodes) {
if (node->typeinfo->poll_instance &&
- !node->typeinfo->poll_instance(node, nodetree, r_disabled_hint)) {
- valid = false;
- break;
+ !node->typeinfo->poll_instance(
+ const_cast<bNode *>(node), const_cast<bNodeTree *>(nodetree), r_disabled_hint)) {
+ return false;
}
}
- return valid;
+ return true;
}
static void add_new_socket_from_interface(bNodeTree &node_tree,
@@ -216,7 +219,7 @@ void node_group_update(struct bNodeTree *ntree, struct bNode *node)
if (node->id == nullptr) {
nodeRemoveAllSockets(ntree, node);
}
- else if ((ID_IS_LINKED(node->id) && (node->id->tag & LIB_TAG_MISSING))) {
+ else if (ID_IS_LINKED(node->id) && (node->id->tag & LIB_TAG_MISSING)) {
/* Missing data-block, leave sockets unchanged so that when it comes back
* the links remain valid. */
}
@@ -233,7 +236,7 @@ void node_group_update(struct bNodeTree *ntree, struct bNode *node)
/** \name Node Frame
* \{ */
-static void node_frame_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_frame_init(bNodeTree * /*ntree*/, bNode *node)
{
NodeFrame *data = MEM_cnew<NodeFrame>("frame node storage");
node->storage = data;
@@ -250,7 +253,7 @@ void register_node_type_frame()
ntype->free_self = (void (*)(bNodeType *))MEM_freeN;
node_type_base(ntype, NODE_FRAME, "Frame", NODE_CLASS_LAYOUT);
- node_type_init(ntype, node_frame_init);
+ ntype->initfunc = node_frame_init;
node_type_storage(ntype, "NodeFrame", node_free_standard_storage, node_copy_standard_storage);
node_type_size(ntype, 150, 100, 0);
ntype->flag |= NODE_BACKGROUND;
@@ -280,7 +283,7 @@ void register_node_type_reroute()
ntype->free_self = (void (*)(bNodeType *))MEM_freeN;
node_type_base(ntype, NODE_REROUTE, "Reroute", NODE_CLASS_LAYOUT);
- node_type_init(ntype, node_reroute_init);
+ ntype->initfunc = node_reroute_init;
nodeRegisterType(ntype);
}
@@ -376,53 +379,29 @@ void ntree_update_reroute_nodes(bNodeTree *ntree)
}
}
-static bool node_is_connected_to_output_recursive(bNodeTree *ntree, bNode *node)
+bool BKE_node_is_connected_to_output(const bNodeTree *ntree, const bNode *node)
{
- bNodeLink *link;
-
- /* avoid redundant checks, and infinite loops in case of cyclic node links */
- if (node->done) {
- return false;
- }
- node->done = 1;
-
- /* main test, done before child loop so it catches output nodes themselves as well */
- if (node->typeinfo->nclass == NODE_CLASS_OUTPUT && node->flag & NODE_DO_OUTPUT) {
- return true;
+ ntree->ensure_topology_cache();
+ Stack<const bNode *> nodes_to_check;
+ for (const bNodeSocket *socket : node->output_sockets()) {
+ for (const bNodeLink *link : socket->directly_linked_links()) {
+ nodes_to_check.push(link->tonode);
+ }
}
-
- /* test all connected nodes, first positive find is sufficient to return true */
- for (link = (bNodeLink *)ntree->links.first; link; link = link->next) {
- if (link->fromnode == node) {
- if (node_is_connected_to_output_recursive(ntree, link->tonode)) {
- return true;
+ while (!nodes_to_check.is_empty()) {
+ const bNode *next_node = nodes_to_check.pop();
+ for (const bNodeSocket *socket : next_node->output_sockets()) {
+ for (const bNodeLink *link : socket->directly_linked_links()) {
+ if (link->tonode->typeinfo->nclass == NODE_CLASS_OUTPUT &&
+ link->tonode->flag & NODE_DO_OUTPUT) {
+ return true;
+ }
+ nodes_to_check.push(link->tonode);
}
}
}
- return false;
-}
-
-bool BKE_node_is_connected_to_output(bNodeTree *ntree, bNode *node)
-{
- bNode *tnode;
-
- /* clear flags */
- for (tnode = (bNode *)ntree->nodes.first; tnode; tnode = tnode->next) {
- tnode->done = 0;
- }
-
- return node_is_connected_to_output_recursive(ntree, node);
-}
-
-void BKE_node_tree_unlink_id(ID *id, struct bNodeTree *ntree)
-{
- bNode *node;
- for (node = (bNode *)ntree->nodes.first; node; node = node->next) {
- if (node->id == id) {
- node->id = nullptr;
- }
- }
+ return false;
}
/** \} */
@@ -455,62 +434,53 @@ bNodeSocket *node_group_input_find_socket(bNode *node, const char *identifier)
void node_group_input_update(bNodeTree *ntree, bNode *node)
{
bNodeSocket *extsock = (bNodeSocket *)node->outputs.last;
- 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.
- */
- ListBase tmplinks;
+ * so they can be recreated after verification. */
+ Vector<bNodeLink> temp_links;
/* find links from the extension socket and store them */
- BLI_listbase_clear(&tmplinks);
- for (link = (bNodeLink *)ntree->links.first; link; link = linknext) {
- linknext = link->next;
+ LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) {
if (nodeLinkIsHidden(link)) {
continue;
}
if (link->fromsock == extsock) {
- bNodeLink *tlink = MEM_cnew<bNodeLink>("temporary link");
- *tlink = *link;
- BLI_addtail(&tmplinks, tlink);
-
+ temp_links.append(*link);
nodeRemLink(ntree, link);
}
}
/* find valid link to expose */
- exposelink = nullptr;
- for (link = (bNodeLink *)tmplinks.first; link; link = link->next) {
+ bNodeLink *exposelink = nullptr;
+ for (bNodeLink &link : temp_links) {
/* 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.
*/
- if (!is_group_extension_socket(link->tonode, link->tosock)) {
- exposelink = link;
+ if (!is_group_extension_socket(link.tonode, link.tosock)) {
+ exposelink = &link;
break;
}
}
if (exposelink) {
- bNodeSocket *gsock, *newsock;
-
- gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->tonode, exposelink->tosock);
+ bNodeSocket *gsock = ntreeAddSocketInterfaceFromSocket(
+ ntree, exposelink->tonode, exposelink->tosock);
node_group_input_update(ntree, node);
- newsock = node_group_input_find_socket(node, gsock->identifier);
+ bNodeSocket *newsock = node_group_input_find_socket(node, gsock->identifier);
/* redirect links from the extension socket */
- for (link = (bNodeLink *)tmplinks.first; link; link = link->next) {
- bNodeLink *newlink = nodeAddLink(ntree, node, newsock, link->tonode, link->tosock);
+ for (bNodeLink &link : temp_links) {
+ bNodeLink *newlink = nodeAddLink(ntree, node, newsock, link.tonode, link.tosock);
if (newlink->tosock->flag & SOCK_MULTI_INPUT) {
- newlink->multi_input_socket_index = link->multi_input_socket_index;
+ newlink->multi_input_socket_index = link.multi_input_socket_index;
}
}
}
- BLI_freelistN(&tmplinks);
group_verify_socket_list(*ntree, *node, ntree->inputs, node->outputs, SOCK_OUT, true);
}
@@ -522,8 +492,8 @@ void register_node_type_group_input()
node_type_base(ntype, NODE_GROUP_INPUT, "Group Input", NODE_CLASS_INTERFACE);
node_type_size(ntype, 140, 80, 400);
- node_type_init(ntype, node_group_input_init);
- node_type_update(ntype, node_group_input_update);
+ ntype->initfunc = node_group_input_init;
+ ntype->updatefunc = node_group_input_update;
nodeRegisterType(ntype);
}
@@ -547,60 +517,51 @@ bNodeSocket *node_group_output_find_socket(bNode *node, const char *identifier)
void node_group_output_update(bNodeTree *ntree, bNode *node)
{
bNodeSocket *extsock = (bNodeSocket *)node->inputs.last;
- 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.
- */
- ListBase tmplinks;
+ * so they can be recreated after verification. */
+ Vector<bNodeLink> temp_links;
/* find links to the extension socket and store them */
- BLI_listbase_clear(&tmplinks);
- for (link = (bNodeLink *)ntree->links.first; link; link = linknext) {
- linknext = link->next;
+ LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) {
if (nodeLinkIsHidden(link)) {
continue;
}
if (link->tosock == extsock) {
- bNodeLink *tlink = MEM_cnew<bNodeLink>("temporary link");
- *tlink = *link;
- BLI_addtail(&tmplinks, tlink);
-
+ temp_links.append(*link);
nodeRemLink(ntree, link);
}
}
/* find valid link to expose */
- exposelink = nullptr;
- for (link = (bNodeLink *)tmplinks.first; link; link = link->next) {
+ bNodeLink *exposelink = nullptr;
+ for (bNodeLink &link : temp_links) {
/* 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.
*/
- if (!is_group_extension_socket(link->fromnode, link->fromsock)) {
- exposelink = link;
+ if (!is_group_extension_socket(link.fromnode, link.fromsock)) {
+ exposelink = &link;
break;
}
}
if (exposelink) {
- bNodeSocket *gsock, *newsock;
-
/* XXX what if connecting virtual to virtual socket?? */
- gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->fromnode, exposelink->fromsock);
+ bNodeSocket *gsock = ntreeAddSocketInterfaceFromSocket(
+ ntree, exposelink->fromnode, exposelink->fromsock);
node_group_output_update(ntree, node);
- newsock = node_group_output_find_socket(node, gsock->identifier);
+ bNodeSocket *newsock = node_group_output_find_socket(node, gsock->identifier);
/* redirect links to the extension socket */
- for (link = (bNodeLink *)tmplinks.first; link; link = link->next) {
- nodeAddLink(ntree, link->fromnode, link->fromsock, node, newsock);
+ for (bNodeLink &link : temp_links) {
+ nodeAddLink(ntree, link.fromnode, link.fromsock, node, newsock);
}
}
- BLI_freelistN(&tmplinks);
group_verify_socket_list(*ntree, *node, ntree->outputs, node->inputs, SOCK_IN, true);
}
@@ -612,8 +573,8 @@ void register_node_type_group_output()
node_type_base(ntype, NODE_GROUP_OUTPUT, "Group Output", NODE_CLASS_INTERFACE);
node_type_size(ntype, 140, 80, 400);
- node_type_init(ntype, node_group_output_init);
- node_type_update(ntype, node_group_output_update);
+ ntype->initfunc = node_group_output_init;
+ ntype->updatefunc = node_group_output_update;
ntype->no_muting = true;
diff --git a/source/blender/nodes/intern/node_declaration.cc b/source/blender/nodes/intern/node_declaration.cc
index 2cd9c6000c0..f323d035668 100644
--- a/source/blender/nodes/intern/node_declaration.cc
+++ b/source/blender/nodes/intern/node_declaration.cc
@@ -2,6 +2,7 @@
#include "NOD_node_declaration.hh"
+#include "BKE_geometry_fields.hh"
#include "BKE_node.h"
namespace blender::nodes {
@@ -81,4 +82,30 @@ bool SocketDeclaration::matches_common_data(const bNodeSocket &socket) const
return true;
}
+namespace implicit_field_inputs {
+
+void position(const bNode & /*node*/, void *r_value)
+{
+ new (r_value) fn::ValueOrField<float3>(bke::AttributeFieldInput::Create<float3>("position"));
+}
+
+void normal(const bNode & /*node*/, void *r_value)
+{
+ new (r_value)
+ fn::ValueOrField<float3>(fn::Field<float3>(std::make_shared<bke::NormalFieldInput>()));
+}
+
+void index(const bNode & /*node*/, void *r_value)
+{
+ new (r_value) fn::ValueOrField<int>(fn::Field<int>(std::make_shared<fn::IndexFieldInput>()));
+}
+
+void id_or_index(const bNode & /*node*/, void *r_value)
+{
+ new (r_value)
+ fn::ValueOrField<int>(fn::Field<int>(std::make_shared<bke::IDAttributeFieldInput>()));
+}
+
+} // namespace implicit_field_inputs
+
} // namespace blender::nodes
diff --git a/source/blender/nodes/intern/node_exec.cc b/source/blender/nodes/intern/node_exec.cc
index 724d6f1a1e1..af783ca391f 100644
--- a/source/blender/nodes/intern/node_exec.cc
+++ b/source/blender/nodes/intern/node_exec.cc
@@ -162,7 +162,7 @@ bNodeTreeExec *ntree_exec_begin(bNodeExecContext *context,
/* XXX could let callbacks do this for specialized data */
exec = MEM_cnew<bNodeTreeExec>("node tree execution data");
- /* backpointer to node tree */
+ /* Back-pointer to node tree. */
exec->nodetree = ntree;
/* set stack indices */
diff --git a/source/blender/nodes/intern/node_exec.h b/source/blender/nodes/intern/node_exec.h
index dc07f52e23f..55bf409444e 100644
--- a/source/blender/nodes/intern/node_exec.h
+++ b/source/blender/nodes/intern/node_exec.h
@@ -27,7 +27,7 @@ struct bNodeTree;
/* Node execution data */
typedef struct bNodeExec {
- /** Backpointer to node. */
+ /** Back-pointer to node. */
struct bNode *node;
bNodeExecData data;
@@ -37,7 +37,7 @@ typedef struct bNodeExec {
/* Execution Data for each instance of node tree execution */
typedef struct bNodeTreeExec {
- struct bNodeTree *nodetree; /* backpointer to node tree */
+ struct bNodeTree *nodetree; /* Back-pointer to node tree. */
int totnodes; /* total node count */
struct bNodeExec *nodeexec; /* per-node execution data */
diff --git a/source/blender/nodes/intern/node_geometry_exec.cc b/source/blender/nodes/intern/node_geometry_exec.cc
index 1833774fe33..1de92fa8409 100644
--- a/source/blender/nodes/intern/node_geometry_exec.cc
+++ b/source/blender/nodes/intern/node_geometry_exec.cc
@@ -13,18 +13,22 @@
namespace blender::nodes {
-void GeoNodeExecParams::error_message_add(const NodeWarningType type, std::string message) const
+void GeoNodeExecParams::error_message_add(const NodeWarningType type,
+ const StringRef message) const
{
if (geo_eval_log::GeoTreeLogger *tree_logger = this->get_local_tree_logger()) {
- tree_logger->node_warnings.append({node_.name, {type, std::move(message)}});
+ tree_logger->node_warnings.append({tree_logger->allocator->copy_string(node_.name),
+ {type, tree_logger->allocator->copy_string(message)}});
}
}
-void GeoNodeExecParams::used_named_attribute(std::string attribute_name,
+void GeoNodeExecParams::used_named_attribute(const StringRef attribute_name,
const NamedAttributeUsage usage)
{
if (geo_eval_log::GeoTreeLogger *tree_logger = this->get_local_tree_logger()) {
- tree_logger->used_named_attributes.append({node_.name, std::move(attribute_name), usage});
+ tree_logger->used_named_attributes.append({tree_logger->allocator->copy_string(node_.name),
+ tree_logger->allocator->copy_string(attribute_name),
+ usage});
}
}
diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc
index 098f766589d..f2f4519625a 100644
--- a/source/blender/nodes/intern/node_socket.cc
+++ b/source/blender/nodes/intern/node_socket.cc
@@ -59,14 +59,14 @@ struct bNodeSocket *node_add_socket_from_template(struct bNodeTree *ntree,
}
case SOCK_INT: {
bNodeSocketValueInt *dval = (bNodeSocketValueInt *)sock->default_value;
- dval->value = (int)stemp->val1;
- dval->min = (int)stemp->min;
- dval->max = (int)stemp->max;
+ dval->value = int(stemp->val1);
+ dval->min = int(stemp->min);
+ dval->max = int(stemp->max);
break;
}
case SOCK_BOOLEAN: {
bNodeSocketValueBoolean *dval = (bNodeSocketValueBoolean *)sock->default_value;
- dval->value = (int)stemp->val1;
+ dval->value = int(stemp->val1);
break;
}
case SOCK_VECTOR: {
@@ -531,11 +531,11 @@ void node_socket_skip_reroutes(
}
}
-static void standard_node_socket_interface_init_socket(bNodeTree *UNUSED(ntree),
+static void standard_node_socket_interface_init_socket(bNodeTree * /*ntree*/,
const bNodeSocket *interface_socket,
- bNode *UNUSED(node),
+ bNode * /*node*/,
bNodeSocket *sock,
- const char *UNUSED(data_path))
+ const char * /*data_path*/)
{
/* initialize the type value */
sock->type = sock->typeinfo->type;
@@ -549,11 +549,11 @@ static void standard_node_socket_interface_init_socket(bNodeTree *UNUSED(ntree),
}
/* copies settings that are not changed for each socket instance */
-static void standard_node_socket_interface_verify_socket(bNodeTree *UNUSED(ntree),
+static void standard_node_socket_interface_verify_socket(bNodeTree * /*ntree*/,
const bNodeSocket *interface_socket,
- bNode *UNUSED(node),
+ bNode * /*node*/,
bNodeSocket *sock,
- const char *UNUSED(data_path))
+ const char * /*data_path*/)
{
/* sanity check */
if (sock->type != interface_socket->typeinfo->type) {
@@ -594,9 +594,9 @@ static void standard_node_socket_interface_verify_socket(bNodeTree *UNUSED(ntree
}
}
-static void standard_node_socket_interface_from_socket(bNodeTree *UNUSED(ntree),
+static void standard_node_socket_interface_from_socket(bNodeTree * /*ntree*/,
bNodeSocket *stemp,
- bNode *UNUSED(node),
+ bNode * /*node*/,
bNodeSocket *sock)
{
/* initialize settings */
@@ -801,7 +801,7 @@ static bNodeSocketType *make_socket_type_geometry()
{
bNodeSocketType *socktype = make_standard_socket_type(SOCK_GEOMETRY, PROP_NONE);
socktype->base_cpp_type = &blender::CPPType::get<GeometrySet>();
- socktype->get_base_cpp_value = [](const bNodeSocket &UNUSED(socket), void *r_value) {
+ socktype->get_base_cpp_value = [](const bNodeSocket & /*socket*/, void *r_value) {
new (r_value) GeometrySet();
};
socktype->geometry_nodes_cpp_type = socktype->base_cpp_type;
diff --git a/source/blender/nodes/intern/node_socket_declarations.cc b/source/blender/nodes/intern/node_socket_declarations.cc
index b9fb75f30c7..a7d281bcf52 100644
--- a/source/blender/nodes/intern/node_socket_declarations.cc
+++ b/source/blender/nodes/intern/node_socket_declarations.cc
@@ -50,7 +50,7 @@ static bool sockets_can_connect(const SocketDeclaration &socket_decl,
return true;
}
-static bool basic_types_can_connect(const SocketDeclaration &UNUSED(socket_decl),
+static bool basic_types_can_connect(const SocketDeclaration & /*socket_decl*/,
const bNodeSocket &other_socket)
{
return ELEM(other_socket.type, SOCK_FLOAT, SOCK_INT, SOCK_BOOLEAN, SOCK_VECTOR, SOCK_RGBA);
diff --git a/source/blender/nodes/intern/node_util.c b/source/blender/nodes/intern/node_util.cc
index ddab455509d..17be20b4e4b 100644
--- a/source/blender/nodes/intern/node_util.c
+++ b/source/blender/nodes/intern/node_util.cc
@@ -37,7 +37,7 @@
void node_free_curves(bNode *node)
{
- BKE_curvemapping_free(node->storage);
+ BKE_curvemapping_free(static_cast<CurveMapping *>(node->storage));
}
void node_free_standard_storage(bNode *node)
@@ -49,7 +49,7 @@ void node_free_standard_storage(bNode *node)
void node_copy_curves(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
{
- dest_node->storage = BKE_curvemapping_copy(src_node->storage);
+ dest_node->storage = BKE_curvemapping_copy(static_cast<CurveMapping *>(src_node->storage));
}
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree),
@@ -63,7 +63,7 @@ void *node_initexec_curves(bNodeExecContext *UNUSED(context),
bNode *node,
bNodeInstanceKey UNUSED(key))
{
- BKE_curvemapping_init(node->storage);
+ BKE_curvemapping_init(static_cast<CurveMapping *>(node->storage));
return NULL; /* unused return */
}
@@ -87,9 +87,9 @@ void node_sock_label_clear(bNodeSocket *sock)
void node_math_update(bNodeTree *ntree, bNode *node)
{
- bNodeSocket *sock1 = BLI_findlink(&node->inputs, 0);
- bNodeSocket *sock2 = BLI_findlink(&node->inputs, 1);
- bNodeSocket *sock3 = BLI_findlink(&node->inputs, 2);
+ bNodeSocket *sock1 = static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 0));
+ bNodeSocket *sock2 = static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 1));
+ bNodeSocket *sock3 = static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 2));
nodeSetSocketAvailability(ntree,
sock2,
!ELEM(node->custom1,
@@ -305,7 +305,9 @@ static bNodeSocket *node_find_linkable_socket(bNodeTree *ntree,
bNode *node,
bNodeSocket *to_socket)
{
- bNodeSocket *first = to_socket->in_out == SOCK_IN ? node->inputs.first : node->outputs.first;
+ bNodeSocket *first = to_socket->in_out == SOCK_IN ?
+ static_cast<bNodeSocket *>(node->inputs.first) :
+ static_cast<bNodeSocket *>((node->outputs.first));
/* Wrap around the list end. */
bNodeSocket *socket_iter = to_socket->next ? to_socket->next : first;
diff --git a/source/blender/nodes/intern/socket_search_link.cc b/source/blender/nodes/intern/socket_search_link.cc
index 0bd838ff002..b440952b503 100644
--- a/source/blender/nodes/intern/socket_search_link.cc
+++ b/source/blender/nodes/intern/socket_search_link.cc
@@ -125,64 +125,23 @@ void search_link_ops_for_declarations(GatherLinkSearchOpParams &params,
}
}
-static void search_link_ops_for_socket_templates(GatherLinkSearchOpParams &params,
- const bNodeSocketTemplate *templates,
- const eNodeSocketInOut in_out)
-{
- const bNodeType &node_type = params.node_type();
- const bNodeTreeType &node_tree_type = *params.node_tree().typeinfo;
-
- Set<StringRef> socket_names;
- for (const bNodeSocketTemplate *socket_template = templates; socket_template->type != -1;
- socket_template++) {
- eNodeSocketDatatype from = (eNodeSocketDatatype)socket_template->type;
- eNodeSocketDatatype to = (eNodeSocketDatatype)params.other_socket().type;
- if (in_out == SOCK_IN) {
- std::swap(from, to);
- }
- if (node_tree_type.validate_link && !node_tree_type.validate_link(from, to)) {
- continue;
- }
- if (!socket_names.add(socket_template->name)) {
- /* See comment in #search_link_ops_for_declarations. */
- continue;
- }
-
- params.add_item(
- socket_template->name, [socket_template, node_type, in_out](LinkSearchOpParams &params) {
- bNode &node = params.add_node(node_type);
- bNodeSocket *new_node_socket = bke::node_find_enabled_socket(
- node, in_out, socket_template->name);
- if (new_node_socket != nullptr) {
- /* Rely on the way #nodeAddLink switches in/out if necessary. */
- nodeAddLink(&params.node_tree, &params.node, &params.socket, &node, new_node_socket);
- }
- });
- }
-}
-
void search_link_ops_for_basic_node(GatherLinkSearchOpParams &params)
{
const bNodeType &node_type = params.node_type();
+ if (!node_type.declare) {
+ return;
+ }
- if (node_type.declare) {
- if (node_type.declaration_is_dynamic) {
- /* Dynamic declarations (whatever they end up being) aren't supported
- * by this function, but still avoid a crash in release builds. */
- BLI_assert_unreachable();
- return;
- }
+ if (node_type.declaration_is_dynamic) {
+ /* Dynamic declarations (whatever they end up being) aren't supported
+ * by this function, but still avoid a crash in release builds. */
+ BLI_assert_unreachable();
+ return;
+ }
- const NodeDeclaration &declaration = *node_type.fixed_declaration;
+ const NodeDeclaration &declaration = *node_type.fixed_declaration;
- search_link_ops_for_declarations(params, declaration.sockets(params.in_out()));
- }
- else if (node_type.inputs && params.in_out() == SOCK_IN) {
- search_link_ops_for_socket_templates(params, node_type.inputs, SOCK_IN);
- }
- else if (node_type.outputs && params.in_out() == SOCK_OUT) {
- search_link_ops_for_socket_templates(params, node_type.outputs, SOCK_OUT);
- }
+ search_link_ops_for_declarations(params, declaration.sockets(params.in_out()));
}
} // namespace blender::nodes
diff --git a/source/blender/nodes/shader/CMakeLists.txt b/source/blender/nodes/shader/CMakeLists.txt
index 7885ad78225..e6f90449843 100644
--- a/source/blender/nodes/shader/CMakeLists.txt
+++ b/source/blender/nodes/shader/CMakeLists.txt
@@ -132,22 +132,24 @@ set(LIB
bf_nodes
)
-if(WITH_PYTHON)
- list(APPEND INC
- ../../python
- )
+if(WITH_FREESTYLE)
+ add_definitions(-DWITH_FREESTYLE)
+endif()
+
+if(WITH_TBB)
+ add_definitions(-DWITH_TBB)
+ if(WIN32)
+ # TBB includes Windows.h which will define min/max macros
+ # that will collide with the stl versions.
+ add_definitions(-DNOMINMAX)
+ endif()
list(APPEND INC_SYS
- ${PYTHON_INCLUDE_DIRS}
+ ${TBB_INCLUDE_DIRS}
)
+
list(APPEND LIB
- ${PYTHON_LINKFLAGS}
- ${PYTHON_LIBRARIES}
+ ${TBB_LIBRARIES}
)
- add_definitions(-DWITH_PYTHON)
-endif()
-
-if(WITH_FREESTYLE)
- add_definitions(-DWITH_FREESTYLE)
endif()
blender_add_lib(bf_nodes_shader "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/nodes/shader/node_shader_tree.cc b/source/blender/nodes/shader/node_shader_tree.cc
index 57772522299..f177fc95ef8 100644
--- a/source/blender/nodes/shader/node_shader_tree.cc
+++ b/source/blender/nodes/shader/node_shader_tree.cc
@@ -52,7 +52,7 @@
using blender::Array;
using blender::Vector;
-static bool shader_tree_poll(const bContext *C, bNodeTreeType *UNUSED(treetype))
+static bool shader_tree_poll(const bContext *C, bNodeTreeType * /*treetype*/)
{
Scene *scene = CTX_data_scene(C);
const char *engine_id = scene->r.engine;
@@ -63,15 +63,13 @@ static bool shader_tree_poll(const bContext *C, bNodeTreeType *UNUSED(treetype))
!BKE_scene_use_shading_nodes_custom(scene));
}
-static void shader_get_from_context(const bContext *C,
- bNodeTreeType *UNUSED(treetype),
- bNodeTree **r_ntree,
- ID **r_id,
- ID **r_from)
+static void shader_get_from_context(
+ const bContext *C, bNodeTreeType * /*treetype*/, bNodeTree **r_ntree, ID **r_id, ID **r_from)
{
SpaceNode *snode = CTX_wm_space_node(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (snode->shaderfrom == SNODE_SHADER_OBJECT) {
@@ -109,7 +107,7 @@ static void shader_get_from_context(const bContext *C,
}
}
-static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func)
+static void foreach_nodeclass(Scene * /*scene*/, void *calldata, bNodeClassCallback func)
{
func(calldata, NODE_CLASS_INPUT, N_("Input"));
func(calldata, NODE_CLASS_OUTPUT, N_("Output"));
@@ -124,7 +122,7 @@ static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCa
func(calldata, NODE_CLASS_LAYOUT, N_("Layout"));
}
-static void localize(bNodeTree *localtree, bNodeTree *UNUSED(ntree))
+static void localize(bNodeTree *localtree, bNodeTree * /*ntree*/)
{
/* replace muted nodes and reroute nodes by internal links */
LISTBASE_FOREACH_MUTABLE (bNode *, node, &localtree->nodes) {
@@ -152,7 +150,7 @@ static bool shader_validate_link(eNodeSocketDatatype from, eNodeSocketDatatype t
return true;
}
-static bool shader_node_tree_socket_type_valid(bNodeTreeType *UNUSED(ntreetype),
+static bool shader_node_tree_socket_type_valid(bNodeTreeType * /*ntreetype*/,
bNodeSocketType *socket_type)
{
return nodeIsStaticSocketType(socket_type) &&
@@ -299,7 +297,7 @@ static bool ntree_shader_expand_socket_default(bNodeTree *localtree,
BLI_assert(value_socket != nullptr);
src_int = static_cast<bNodeSocketValueInt *>(socket->default_value);
dst_float = static_cast<bNodeSocketValueFloat *>(value_socket->default_value);
- dst_float->value = (float)(src_int->value);
+ dst_float->value = float(src_int->value);
break;
case SOCK_FLOAT:
value_node = nodeAddStaticNode(nullptr, localtree, SH_NODE_VALUE);
@@ -562,7 +560,7 @@ static bNode *ntree_shader_copy_branch(bNodeTree *ntree,
void (*callback)(bNode *node, int user_data),
int user_data)
{
- /* Init tmp flag. */
+ /* Initialize `tmp_flag`. */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
node->tmp_flag = -1;
}
@@ -641,7 +639,7 @@ static bool ntree_shader_implicit_closure_cast(bNodeTree *ntree)
/* Socket already has a link to it. Add weights together. */
static void ntree_weight_tree_merge_weight(bNodeTree *ntree,
- bNode *UNUSED(fromnode),
+ bNode * /*fromnode*/,
bNodeSocket *fromsock,
bNode **tonode,
bNodeSocket **tosock)
@@ -946,7 +944,7 @@ static bool closure_node_filter(const bNode *node)
}
}
-static bool shader_to_rgba_node_gather(bNode *UNUSED(fromnode), bNode *tonode, void *userdata)
+static bool shader_to_rgba_node_gather(bNode * /*fromnode*/, bNode *tonode, void *userdata)
{
Vector<bNode *> &shader_to_rgba_nodes = *(Vector<bNode *> *)userdata;
if (tonode->tmp_flag == -1 && tonode->type == SH_NODE_SHADERTORGB) {
@@ -986,7 +984,7 @@ static void ntree_shader_shader_to_rgba_branch(bNodeTree *ntree, bNode *output_n
}
}
-static bool ntree_branch_node_tag(bNode *fromnode, bNode *tonode, void *UNUSED(userdata))
+static bool ntree_branch_node_tag(bNode *fromnode, bNode *tonode, void * /*userdata*/)
{
fromnode->tmp_flag = 1;
tonode->tmp_flag = 1;
@@ -1128,7 +1126,8 @@ void ntreeShaderEndExecTree(bNodeTreeExec *exec)
bNodeTree *ntree = exec->nodetree;
ntreeShaderEndExecTree_internal(exec);
- /* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
+ /* XXX: clear node-tree back-pointer to exec data,
+ * same problem as noted in #ntreeBeginExecTree. */
ntree->execdata = nullptr;
}
}
diff --git a/source/blender/nodes/shader/node_shader_util.cc b/source/blender/nodes/shader/node_shader_util.cc
index 059d7800fc5..929b11ded3e 100644
--- a/source/blender/nodes/shader/node_shader_util.cc
+++ b/source/blender/nodes/shader/node_shader_util.cc
@@ -13,7 +13,7 @@
#include "node_exec.h"
-bool sh_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree, const char **r_disabled_hint)
+bool sh_node_poll_default(bNodeType * /*ntype*/, bNodeTree *ntree, const char **r_disabled_hint)
{
if (!STREQ(ntree->idname, "ShaderNodeTree")) {
*r_disabled_hint = TIP_("Not a shader node tree");
@@ -22,7 +22,7 @@ bool sh_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree, const char
return true;
}
-static bool sh_fn_poll_default(bNodeType *UNUSED(ntype),
+static bool sh_fn_poll_default(bNodeType * /*ntype*/,
bNodeTree *ntree,
const char **r_disabled_hint)
{
@@ -284,7 +284,7 @@ void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, bNode *output_node
}
}
-void node_shader_gpu_bump_tex_coord(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeLink **link)
+void node_shader_gpu_bump_tex_coord(GPUMaterial *mat, bNode * /*node*/, GPUNodeLink **link)
{
GPU_link(mat, "differentiate_texco", *link, link);
}
@@ -300,7 +300,7 @@ void node_shader_gpu_default_tex_coord(GPUMaterial *mat, bNode *node, GPUNodeLin
void node_shader_gpu_tex_mapping(GPUMaterial *mat,
bNode *node,
GPUNodeStack *in,
- GPUNodeStack *UNUSED(out))
+ GPUNodeStack * /*out*/)
{
NodeTexBase *base = (NodeTexBase *)node->storage;
TexMapping *texmap = &base->tex_mapping;
diff --git a/source/blender/nodes/shader/nodes/node_shader_add_shader.cc b/source/blender/nodes/shader/nodes/node_shader_add_shader.cc
index 330bdc0ba61..8bdc5b91887 100644
--- a/source/blender/nodes/shader/nodes/node_shader_add_shader.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_add_shader.cc
@@ -14,7 +14,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_add_shader(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -32,7 +32,7 @@ void register_node_type_sh_add_shader()
sh_node_type_base(&ntype, SH_NODE_ADD_SHADER, "Add Shader", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_add_shader);
+ ntype.gpu_fn = file_ns::node_shader_gpu_add_shader;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.cc b/source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.cc
index 1e8df2e985d..85c49b47b81 100644
--- a/source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.cc
@@ -17,9 +17,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("AO"));
}
-static void node_shader_buts_ambient_occlusion(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_shader_buts_ambient_occlusion(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "samples", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
uiItemR(layout, ptr, "inside", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
@@ -28,7 +26,7 @@ static void node_shader_buts_ambient_occlusion(uiLayout *layout,
static int node_shader_gpu_ambient_occlusion(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -50,7 +48,7 @@ static int node_shader_gpu_ambient_occlusion(GPUMaterial *mat,
GPU_constant(&f_samples));
}
-static void node_shader_init_ambient_occlusion(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_ambient_occlusion(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = 16; /* samples */
node->custom2 = 0;
@@ -68,8 +66,8 @@ void register_node_type_sh_ambient_occlusion()
sh_node_type_base(&ntype, SH_NODE_AMBIENT_OCCLUSION, "Ambient Occlusion", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_ambient_occlusion;
- node_type_init(&ntype, file_ns::node_shader_init_ambient_occlusion);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_ambient_occlusion);
+ ntype.initfunc = file_ns::node_shader_init_ambient_occlusion;
+ ntype.gpu_fn = file_ns::node_shader_gpu_ambient_occlusion;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_attribute.cc b/source/blender/nodes/shader/nodes/node_shader_attribute.cc
index 65d053e6379..44f5282b688 100644
--- a/source/blender/nodes/shader/nodes/node_shader_attribute.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_attribute.cc
@@ -16,13 +16,13 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Alpha"));
}
-static void node_shader_buts_attribute(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_attribute(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "attribute_type", UI_ITEM_R_SPLIT_EMPTY_NAME, IFACE_("Type"), ICON_NONE);
uiItemR(layout, ptr, "attribute_name", UI_ITEM_R_SPLIT_EMPTY_NAME, IFACE_("Name"), ICON_NONE);
}
-static void node_shader_init_attribute(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_attribute(bNodeTree * /*ntree*/, bNode *node)
{
NodeShaderAttribute *attr = MEM_cnew<NodeShaderAttribute>("NodeShaderAttribute");
node->storage = attr;
@@ -30,7 +30,7 @@ static void node_shader_init_attribute(bNodeTree *UNUSED(ntree), bNode *node)
static int node_shader_gpu_attribute(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -42,6 +42,16 @@ static int node_shader_gpu_attribute(GPUMaterial *mat,
if (is_varying) {
cd_attr = GPU_attribute(mat, CD_AUTO_FROM_NAME, attr->name);
+
+ if (STREQ(attr->name, "color")) {
+ GPU_link(mat, "node_attribute_color", cd_attr, &cd_attr);
+ }
+ else if (STREQ(attr->name, "temperature")) {
+ GPU_link(mat, "node_attribute_temperature", cd_attr, &cd_attr);
+ }
+ }
+ else if (attr->type == SHD_ATTRIBUTE_VIEW_LAYER) {
+ cd_attr = GPU_layer_attribute(mat, attr->name);
}
else {
cd_attr = GPU_uniform_attribute(mat,
@@ -52,13 +62,6 @@ static int node_shader_gpu_attribute(GPUMaterial *mat,
GPU_link(mat, "node_attribute_uniform", cd_attr, GPU_constant(&attr_hash), &cd_attr);
}
- if (STREQ(attr->name, "color")) {
- GPU_link(mat, "node_attribute_color", cd_attr, &cd_attr);
- }
- else if (STREQ(attr->name, "temperature")) {
- GPU_link(mat, "node_attribute_temperature", cd_attr, &cd_attr);
- }
-
GPU_stack_link(mat, node, "node_attribute", in, out, cd_attr);
if (is_varying) {
@@ -83,10 +86,10 @@ void register_node_type_sh_attribute()
sh_node_type_base(&ntype, SH_NODE_ATTRIBUTE, "Attribute", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_attribute;
- node_type_init(&ntype, file_ns::node_shader_init_attribute);
+ ntype.initfunc = file_ns::node_shader_init_attribute;
node_type_storage(
&ntype, "NodeShaderAttribute", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_attribute);
+ ntype.gpu_fn = file_ns::node_shader_gpu_attribute;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_background.cc b/source/blender/nodes/shader/nodes/node_shader_background.cc
index ea5c1f541ea..a1e90757157 100644
--- a/source/blender/nodes/shader/nodes/node_shader_background.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_background.cc
@@ -15,7 +15,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_background(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -33,7 +33,7 @@ void register_node_type_sh_background()
sh_node_type_base(&ntype, SH_NODE_BACKGROUND, "Background", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_background);
+ ntype.gpu_fn = file_ns::node_shader_gpu_background;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bevel.cc b/source/blender/nodes/shader/nodes/node_shader_bevel.cc
index 4ae60af9974..53ce3876772 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bevel.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bevel.cc
@@ -15,19 +15,19 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Normal"));
}
-static void node_shader_buts_bevel(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_bevel(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "samples", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
}
-static void node_shader_init_bevel(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_bevel(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = 4; /* samples */
}
static int gpu_shader_bevel(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -50,8 +50,8 @@ void register_node_type_sh_bevel()
sh_node_type_base(&ntype, SH_NODE_BEVEL, "Bevel", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_bevel;
- node_type_init(&ntype, file_ns::node_shader_init_bevel);
- node_type_gpu(&ntype, file_ns::gpu_shader_bevel);
+ ntype.initfunc = file_ns::node_shader_init_bevel;
+ ntype.gpu_fn = file_ns::gpu_shader_bevel;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_blackbody.cc b/source/blender/nodes/shader/nodes/node_shader_blackbody.cc
index 9f382e5a3bb..a31653de4b2 100644
--- a/source/blender/nodes/shader/nodes/node_shader_blackbody.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_blackbody.cc
@@ -15,7 +15,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_blackbody(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -42,7 +42,7 @@ void register_node_type_sh_blackbody()
sh_node_type_base(&ntype, SH_NODE_BLACKBODY, "Blackbody", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_blackbody);
+ ntype.gpu_fn = file_ns::node_shader_gpu_blackbody;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_brightness.cc b/source/blender/nodes/shader/nodes/node_shader_brightness.cc
index a23783c6d46..0b1930b0434 100644
--- a/source/blender/nodes/shader/nodes/node_shader_brightness.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_brightness.cc
@@ -15,7 +15,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int gpu_shader_brightcontrast(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -32,7 +32,7 @@ void register_node_type_sh_brightcontrast()
sh_node_type_base(&ntype, SH_NODE_BRIGHTCONTRAST, "Bright/Contrast", NODE_CLASS_OP_COLOR);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::gpu_shader_brightcontrast);
+ ntype.gpu_fn = file_ns::gpu_shader_brightcontrast;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.cc
index 761a833f377..48a7c248ea9 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.cc
@@ -28,19 +28,19 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Shader>(N_("BSDF"));
}
-static void node_shader_buts_anisotropic(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_anisotropic(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "distribution", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
-static void node_shader_init_anisotropic(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_anisotropic(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = SHD_GLOSSY_GGX;
}
static int node_shader_gpu_bsdf_anisotropic(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -69,8 +69,8 @@ void register_node_type_sh_bsdf_anisotropic()
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_anisotropic;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, file_ns::node_shader_init_anisotropic);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_anisotropic);
+ ntype.initfunc = file_ns::node_shader_init_anisotropic;
+ ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_anisotropic;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.cc
index 5975e04450e..ba222a1a2c2 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.cc
@@ -20,7 +20,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_bsdf_diffuse(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -45,7 +45,7 @@ void register_node_type_sh_bsdf_diffuse()
sh_node_type_base(&ntype, SH_NODE_BSDF_DIFFUSE, "Diffuse BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_diffuse);
+ ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_diffuse;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc
index 95869f13b7e..00d2ba4a119 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc
@@ -19,14 +19,14 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Shader>(N_("BSDF"));
}
-static void node_shader_init_glass(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_glass(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = SHD_GLOSSY_BECKMANN;
}
static int node_shader_gpu_bsdf_glass(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -57,8 +57,8 @@ void register_node_type_sh_bsdf_glass()
sh_node_type_base(&ntype, SH_NODE_BSDF_GLASS, "Glass BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, file_ns::node_shader_init_glass);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_glass);
+ ntype.initfunc = file_ns::node_shader_init_glass;
+ ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_glass;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.cc
index 07062a9730e..edccd7314d2 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.cc
@@ -18,14 +18,14 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Shader>(N_("BSDF"));
}
-static void node_shader_init_glossy(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_glossy(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = SHD_GLOSSY_GGX;
}
static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -56,8 +56,8 @@ void register_node_type_sh_bsdf_glossy()
sh_node_type_base(&ntype, SH_NODE_BSDF_GLOSSY, "Glossy BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, file_ns::node_shader_init_glossy);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_glossy);
+ ntype.initfunc = file_ns::node_shader_init_glossy;
+ ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_glossy;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair.cc
index 1a1ba13e886..0498dcd0be5 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair.cc
@@ -31,14 +31,14 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Shader>(N_("BSDF"));
}
-static void node_shader_buts_hair(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_hair(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "component", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
static int node_shader_gpu_bsdf_hair(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -58,7 +58,7 @@ void register_node_type_sh_bsdf_hair()
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_hair;
node_type_size(&ntype, 150, 60, 200);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_hair);
+ ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_hair;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.cc
index a0579372a15..fd127cfb8ae 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.cc
@@ -44,7 +44,7 @@ static void node_declare(NodeDeclarationBuilder &b)
.subtype(PROP_FACTOR);
b.add_input<decl::Float>(N_("IOR")).default_value(1.55f).min(0.0f).max(1000.0f);
b.add_input<decl::Float>(N_("Offset"))
- .default_value(2.0f * ((float)M_PI) / 180.0f)
+ .default_value(2.0f * float(M_PI) / 180.0f)
.min(-M_PI_2)
.max(M_PI_2)
.subtype(PROP_ANGLE);
@@ -63,15 +63,13 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Shader>(N_("BSDF"));
}
-static void node_shader_buts_principled_hair(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_shader_buts_principled_hair(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "parametrization", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
/* Initialize the custom Parametrization property to Color. */
-static void node_shader_init_hair_principled(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_hair_principled(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = SHD_PRINCIPLED_HAIR_REFLECTANCE;
}
@@ -110,7 +108,7 @@ static void node_shader_update_hair_principled(bNodeTree *ntree, bNode *node)
static int node_shader_gpu_hair_principled(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -131,9 +129,9 @@ void register_node_type_sh_bsdf_hair_principled()
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_principled_hair;
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- node_type_init(&ntype, file_ns::node_shader_init_hair_principled);
- node_type_update(&ntype, file_ns::node_shader_update_hair_principled);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_hair_principled);
+ ntype.initfunc = file_ns::node_shader_init_hair_principled;
+ ntype.updatefunc = file_ns::node_shader_update_hair_principled;
+ ntype.gpu_fn = file_ns::node_shader_gpu_hair_principled;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc
index 7b72d4b9be4..82bf852455c 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc
@@ -107,13 +107,13 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Shader>(N_("BSDF"));
}
-static void node_shader_buts_principled(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_principled(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "distribution", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
uiItemR(layout, ptr, "subsurface_method", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
-static void node_shader_init_principled(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_principled(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = SHD_GLOSSY_GGX;
node->custom2 = SHD_SUBSURFACE_RANDOM_WALK;
@@ -125,7 +125,7 @@ static void node_shader_init_principled(bNodeTree *UNUSED(ntree), bNode *node)
static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -245,9 +245,9 @@ void register_node_type_sh_bsdf_principled()
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_principled;
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- node_type_init(&ntype, file_ns::node_shader_init_principled);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_principled);
- node_type_update(&ntype, file_ns::node_shader_update_principled);
+ ntype.initfunc = file_ns::node_shader_init_principled;
+ ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_principled;
+ ntype.updatefunc = file_ns::node_shader_update_principled;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.cc
index e814eb223e5..d6ef63015f8 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.cc
@@ -19,14 +19,14 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Shader>(N_("BSDF"));
}
-static void node_shader_init_refraction(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_refraction(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = SHD_GLOSSY_BECKMANN;
}
static int node_shader_gpu_bsdf_refraction(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -55,8 +55,8 @@ void register_node_type_sh_bsdf_refraction()
sh_node_type_base(&ntype, SH_NODE_BSDF_REFRACTION, "Refraction BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, file_ns::node_shader_init_refraction);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_refraction);
+ ntype.initfunc = file_ns::node_shader_init_refraction;
+ ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_refraction;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_toon.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_toon.cc
index c1c092e89c7..ba8e48ce410 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_toon.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_toon.cc
@@ -26,14 +26,14 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Shader>(N_("BSDF"));
}
-static void node_shader_buts_toon(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_toon(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "component", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
static int node_shader_gpu_bsdf_toon(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -59,7 +59,7 @@ void register_node_type_sh_bsdf_toon()
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_toon;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_toon);
+ ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_toon;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.cc
index fd0dd9f93de..fcb3bcdd00a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.cc
@@ -15,7 +15,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_bsdf_translucent(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -39,7 +39,7 @@ void register_node_type_sh_bsdf_translucent()
sh_node_type_base(&ntype, SH_NODE_BSDF_TRANSLUCENT, "Translucent BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_translucent);
+ ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_translucent;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.cc
index 291b3fdb2be..4eba043ff2b 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.cc
@@ -14,7 +14,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_bsdf_transparent(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -35,7 +35,7 @@ void register_node_type_sh_bsdf_transparent()
sh_node_type_base(&ntype, SH_NODE_BSDF_TRANSPARENT, "Transparent BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_transparent);
+ ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_transparent;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.cc
index c86d70aecbf..67351dd7e19 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.cc
@@ -20,7 +20,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_bsdf_velvet(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -44,7 +44,7 @@ void register_node_type_sh_bsdf_velvet()
sh_node_type_base(&ntype, SH_NODE_BSDF_VELVET, "Velvet BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_velvet);
+ ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_velvet;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bump.cc b/source/blender/nodes/shader/nodes/node_shader_bump.cc
index ad2c56d96b5..9439f95d62b 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bump.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bump.cc
@@ -31,14 +31,14 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Normal"));
}
-static void node_shader_buts_bump(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_bump(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "invert", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, 0);
}
static int gpu_shader_bump(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -78,7 +78,7 @@ void register_node_type_sh_bump()
sh_node_type_base(&ntype, SH_NODE_BUMP, "Bump", NODE_CLASS_OP_VECTOR);
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_bump;
- node_type_gpu(&ntype, file_ns::gpu_shader_bump);
+ ntype.gpu_fn = file_ns::gpu_shader_bump;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_camera.cc b/source/blender/nodes/shader/nodes/node_shader_camera.cc
index 99c82582456..2752cd31c56 100644
--- a/source/blender/nodes/shader/nodes/node_shader_camera.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_camera.cc
@@ -18,7 +18,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int gpu_shader_camera(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -35,7 +35,7 @@ void register_node_type_sh_camera()
sh_node_type_base(&ntype, SH_NODE_CAMERA, "Camera Data", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::gpu_shader_camera);
+ ntype.gpu_fn = file_ns::gpu_shader_camera;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_clamp.cc b/source/blender/nodes/shader/nodes/node_shader_clamp.cc
index c8785721dfb..5b7c216c4c3 100644
--- a/source/blender/nodes/shader/nodes/node_shader_clamp.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_clamp.cc
@@ -21,19 +21,19 @@ static void sh_node_clamp_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Result"));
}
-static void node_shader_buts_clamp(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_clamp(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "clamp_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
-static void node_shader_init_clamp(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_clamp(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = NODE_CLAMP_MINMAX; /* clamp type */
}
static int gpu_shader_clamp(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -76,8 +76,8 @@ void register_node_type_sh_clamp()
sh_fn_node_type_base(&ntype, SH_NODE_CLAMP, "Clamp", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_clamp_declare;
ntype.draw_buttons = file_ns::node_shader_buts_clamp;
- node_type_init(&ntype, file_ns::node_shader_init_clamp);
- node_type_gpu(&ntype, file_ns::gpu_shader_clamp);
+ ntype.initfunc = file_ns::node_shader_init_clamp;
+ ntype.gpu_fn = file_ns::gpu_shader_clamp;
ntype.build_multi_function = file_ns::sh_node_clamp_build_multi_function;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc b/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc
index d73ffd89288..f5d405c7678 100644
--- a/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc
@@ -21,14 +21,14 @@ static void sh_node_valtorgb_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Alpha"));
}
-static void node_shader_init_valtorgb(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_valtorgb(bNodeTree * /*ntree*/, bNode *node)
{
node->storage = BKE_colorband_add(true);
}
static int gpu_shader_valtorgb(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -107,7 +107,7 @@ class ColorBandFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<float> &values = params.readonly_single_input<float>(0, "Value");
MutableSpan<ColorGeometry4f> colors = params.uninitialized_single_output<ColorGeometry4f>(
@@ -140,10 +140,10 @@ void register_node_type_sh_valtorgb()
sh_fn_node_type_base(&ntype, SH_NODE_VALTORGB, "ColorRamp", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_valtorgb_declare;
- node_type_init(&ntype, file_ns::node_shader_init_valtorgb);
+ ntype.initfunc = file_ns::node_shader_init_valtorgb;
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
node_type_storage(&ntype, "ColorBand", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::gpu_shader_valtorgb);
+ ntype.gpu_fn = file_ns::gpu_shader_valtorgb;
ntype.build_multi_function = file_ns::sh_node_valtorgb_build_multi_function;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_common.cc b/source/blender/nodes/shader/nodes/node_shader_common.cc
index 20d0d11ba86..9d1d788da9d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_common.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_common.cc
@@ -93,8 +93,8 @@ void register_node_type_sh_group()
node_type_size(&ntype, 140, 60, 400);
ntype.labelfunc = node_group_label;
- node_type_group_update(&ntype, node_group_update);
- node_type_gpu(&ntype, gpu_group_execute);
+ ntype.group_update_func = node_group_update;
+ ntype.gpu_fn = gpu_group_execute;
nodeRegisterType(&ntype);
}
@@ -109,5 +109,5 @@ void register_node_type_sh_custom_group(bNodeType *ntype)
ntype->insert_link = node_insert_link_default;
}
- node_type_gpu(ntype, gpu_group_execute);
+ ntype->gpu_fn = gpu_group_execute;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.cc b/source/blender/nodes/shader/nodes/node_shader_curves.cc
index 4725aef5991..0945c39ee50 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.cc
@@ -12,19 +12,24 @@ namespace blender::nodes::node_shader_curves_cc {
static void sh_node_curve_vec_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Float>(N_("Fac")).min(0.0f).max(1.0f).default_value(1.0f).subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Fac"))
+ .no_muted_links()
+ .min(0.0f)
+ .max(1.0f)
+ .default_value(1.0f)
+ .subtype(PROP_FACTOR);
b.add_input<decl::Vector>(N_("Vector")).min(-1.0f).max(1.0f);
b.add_output<decl::Vector>(N_("Vector"));
}
-static void node_shader_init_curve_vec(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_curve_vec(bNodeTree * /*ntree*/, bNode *node)
{
node->storage = BKE_curvemapping_add(3, -1.0f, -1.0f, 1.0f, 1.0f);
}
static int gpu_shader_curve_vec(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -78,7 +83,7 @@ class CurveVecFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<float> &fac = params.readonly_single_input<float>(0, "Fac");
const VArray<float3> &vec_in = params.readonly_single_input<float3>(1, "Vector");
@@ -111,10 +116,10 @@ void register_node_type_sh_curve_vec()
sh_fn_node_type_base(&ntype, SH_NODE_CURVE_VEC, "Vector Curves", NODE_CLASS_OP_VECTOR);
ntype.declare = file_ns::sh_node_curve_vec_declare;
- node_type_init(&ntype, file_ns::node_shader_init_curve_vec);
+ ntype.initfunc = file_ns::node_shader_init_curve_vec;
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
- node_type_gpu(&ntype, file_ns::gpu_shader_curve_vec);
+ ntype.gpu_fn = file_ns::gpu_shader_curve_vec;
ntype.build_multi_function = file_ns::sh_node_curve_vec_build_multi_function;
nodeRegisterType(&ntype);
@@ -127,19 +132,24 @@ namespace blender::nodes::node_shader_curves_cc {
static void sh_node_curve_rgb_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Float>(N_("Fac")).min(0.0f).max(1.0f).default_value(1.0f).subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Fac"))
+ .no_muted_links()
+ .min(0.0f)
+ .max(1.0f)
+ .default_value(1.0f)
+ .subtype(PROP_FACTOR);
b.add_input<decl::Color>(N_("Color")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
b.add_output<decl::Color>(N_("Color"));
}
-static void node_shader_init_curve_rgb(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_curve_rgb(bNodeTree * /*ntree*/, bNode *node)
{
node->storage = BKE_curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f);
}
static int gpu_shader_curve_rgb(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -218,7 +228,7 @@ class CurveRGBFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<float> &fac = params.readonly_single_input<float>(0, "Fac");
const VArray<ColorGeometry4f> &col_in = params.readonly_single_input<ColorGeometry4f>(1,
@@ -253,10 +263,10 @@ void register_node_type_sh_curve_rgb()
sh_fn_node_type_base(&ntype, SH_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR);
ntype.declare = file_ns::sh_node_curve_rgb_declare;
- node_type_init(&ntype, file_ns::node_shader_init_curve_rgb);
+ ntype.initfunc = file_ns::node_shader_init_curve_rgb;
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
- node_type_gpu(&ntype, file_ns::gpu_shader_curve_rgb);
+ ntype.gpu_fn = file_ns::gpu_shader_curve_rgb;
ntype.build_multi_function = file_ns::sh_node_curve_rgb_build_multi_function;
nodeRegisterType(&ntype);
@@ -270,6 +280,7 @@ static void sh_node_curve_float_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Float>(N_("Factor"))
+ .no_muted_links()
.min(0.0f)
.max(1.0f)
.default_value(1.0f)
@@ -278,14 +289,14 @@ static void sh_node_curve_float_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Value"));
}
-static void node_shader_init_curve_float(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_curve_float(bNodeTree * /*ntree*/, bNode *node)
{
node->storage = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
}
static int gpu_shader_curve_float(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -339,7 +350,7 @@ class CurveFloatFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<float> &fac = params.readonly_single_input<float>(0, "Factor");
const VArray<float> &val_in = params.readonly_single_input<float>(1, "Value");
@@ -372,10 +383,10 @@ void register_node_type_sh_curve_float()
sh_fn_node_type_base(&ntype, SH_NODE_CURVE_FLOAT, "Float Curve", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_curve_float_declare;
- node_type_init(&ntype, file_ns::node_shader_init_curve_float);
+ ntype.initfunc = file_ns::node_shader_init_curve_float;
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
- node_type_gpu(&ntype, file_ns::gpu_shader_curve_float);
+ ntype.gpu_fn = file_ns::gpu_shader_curve_float;
ntype.build_multi_function = file_ns::sh_node_curve_float_build_multi_function;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_displacement.cc b/source/blender/nodes/shader/nodes/node_shader_displacement.cc
index 6591396adda..e71e2168701 100644
--- a/source/blender/nodes/shader/nodes/node_shader_displacement.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_displacement.cc
@@ -14,7 +14,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Displacement"));
}
-static void node_shader_init_displacement(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_displacement(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = SHD_SPACE_OBJECT; /* space */
@@ -28,7 +28,7 @@ static void node_shader_init_displacement(bNodeTree *UNUSED(ntree), bNode *node)
static int gpu_shader_displacement(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -54,8 +54,8 @@ void register_node_type_sh_displacement()
sh_node_type_base(&ntype, SH_NODE_DISPLACEMENT, "Displacement", NODE_CLASS_OP_VECTOR);
ntype.declare = file_ns::node_declare;
- node_type_init(&ntype, file_ns::node_shader_init_displacement);
- node_type_gpu(&ntype, file_ns::gpu_shader_displacement);
+ ntype.initfunc = file_ns::node_shader_init_displacement;
+ ntype.gpu_fn = file_ns::gpu_shader_displacement;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_eevee_specular.cc b/source/blender/nodes/shader/nodes/node_shader_eevee_specular.cc
index d68b0c0c37c..c13300bdac4 100644
--- a/source/blender/nodes/shader/nodes/node_shader_eevee_specular.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_eevee_specular.cc
@@ -41,7 +41,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_eevee_specular(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -64,7 +64,7 @@ static int node_shader_gpu_eevee_specular(GPUMaterial *mat,
GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_GLOSSY);
- float use_clear = (socket_not_zero(6)) ? 1.0f : 0.0f;
+ float use_clear = socket_not_zero(6) ? 1.0f : 0.0f;
return GPU_stack_link(mat, node, "node_eevee_specular", in, out, GPU_constant(&use_clear));
}
@@ -80,7 +80,7 @@ void register_node_type_sh_eevee_specular()
sh_node_type_base(&ntype, SH_NODE_EEVEE_SPECULAR, "Specular BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_eevee_specular);
+ ntype.gpu_fn = file_ns::node_shader_gpu_eevee_specular;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_emission.cc b/source/blender/nodes/shader/nodes/node_shader_emission.cc
index be98f096ce5..df6283f92dc 100644
--- a/source/blender/nodes/shader/nodes/node_shader_emission.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_emission.cc
@@ -15,7 +15,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_emission(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -34,7 +34,7 @@ void register_node_type_sh_emission()
sh_node_type_base(&ntype, SH_NODE_EMISSION, "Emission", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_emission);
+ ntype.gpu_fn = file_ns::node_shader_gpu_emission;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_fresnel.cc b/source/blender/nodes/shader/nodes/node_shader_fresnel.cc
index 7b771d7dafd..1e35942476a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_fresnel.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_fresnel.cc
@@ -14,7 +14,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_fresnel(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -36,7 +36,7 @@ void register_node_type_sh_fresnel()
sh_node_type_base(&ntype, SH_NODE_FRESNEL, "Fresnel", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_fresnel);
+ ntype.gpu_fn = file_ns::node_shader_gpu_fresnel;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_gamma.cc b/source/blender/nodes/shader/nodes/node_shader_gamma.cc
index d1e07c8b363..327d9b134cd 100644
--- a/source/blender/nodes/shader/nodes/node_shader_gamma.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_gamma.cc
@@ -18,7 +18,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_gamma(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -35,7 +35,7 @@ void register_node_type_sh_gamma()
sh_node_type_base(&ntype, SH_NODE_GAMMA, "Gamma", NODE_CLASS_OP_COLOR);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_gamma);
+ ntype.gpu_fn = file_ns::node_shader_gpu_gamma;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_geometry.cc b/source/blender/nodes/shader/nodes/node_shader_geometry.cc
index d23561de7ff..d7d5f4aa91f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_geometry.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_geometry.cc
@@ -20,7 +20,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_geometry(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -68,7 +68,7 @@ void register_node_type_sh_geometry()
sh_node_type_base(&ntype, SH_NODE_NEW_GEOMETRY, "Geometry", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_geometry);
+ ntype.gpu_fn = file_ns::node_shader_gpu_geometry;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_hair_info.cc b/source/blender/nodes/shader/nodes/node_shader_hair_info.cc
index f46556291ce..4511c8a9ae6 100644
--- a/source/blender/nodes/shader/nodes/node_shader_hair_info.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_hair_info.cc
@@ -17,7 +17,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_hair_info(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -39,7 +39,7 @@ void register_node_type_sh_hair_info()
sh_node_type_base(&ntype, SH_NODE_HAIR_INFO, "Curves Info", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_hair_info);
+ ntype.gpu_fn = file_ns::node_shader_gpu_hair_info;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_holdout.cc b/source/blender/nodes/shader/nodes/node_shader_holdout.cc
index 6a21fab28db..f3f8cef5a2d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_holdout.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_holdout.cc
@@ -13,7 +13,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int gpu_shader_rgb(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -31,7 +31,7 @@ void register_node_type_sh_holdout()
sh_node_type_base(&ntype, SH_NODE_HOLDOUT, "Holdout", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::gpu_shader_rgb);
+ ntype.gpu_fn = file_ns::gpu_shader_rgb;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_hueSatVal.cc b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.cc
index a2220ebccc7..7eb02a3bce2 100644
--- a/source/blender/nodes/shader/nodes/node_shader_hueSatVal.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.cc
@@ -21,7 +21,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int gpu_shader_hue_sat(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -39,7 +39,7 @@ void register_node_type_sh_hue_sat()
sh_node_type_base(&ntype, SH_NODE_HUE_SAT, "Hue Saturation Value", NODE_CLASS_OP_COLOR);
ntype.declare = file_ns::node_declare;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_gpu(&ntype, file_ns::gpu_shader_hue_sat);
+ ntype.gpu_fn = file_ns::gpu_shader_hue_sat;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_ies_light.cc b/source/blender/nodes/shader/nodes/node_shader_ies_light.cc
index bc1d662a17a..dee69eaf391 100644
--- a/source/blender/nodes/shader/nodes/node_shader_ies_light.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_ies_light.cc
@@ -15,7 +15,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Fac"));
}
-static void node_shader_buts_ies(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_ies(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *row;
@@ -32,7 +32,7 @@ static void node_shader_buts_ies(uiLayout *layout, bContext *UNUSED(C), PointerR
}
}
-static void node_shader_init_tex_ies(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_tex_ies(bNodeTree * /*ntree*/, bNode *node)
{
NodeShaderTexIES *tex = MEM_cnew<NodeShaderTexIES>("NodeShaderIESLight");
node->storage = tex;
@@ -50,7 +50,7 @@ void register_node_type_sh_tex_ies()
sh_node_type_base(&ntype, SH_NODE_TEX_IES, "IES Texture", NODE_CLASS_TEXTURE);
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_ies;
- node_type_init(&ntype, file_ns::node_shader_init_tex_ies);
+ ntype.initfunc = file_ns::node_shader_init_tex_ies;
node_type_storage(
&ntype, "NodeShaderTexIES", node_free_standard_storage, node_copy_standard_storage);
diff --git a/source/blender/nodes/shader/nodes/node_shader_invert.cc b/source/blender/nodes/shader/nodes/node_shader_invert.cc
index f87455b555d..ba2774e3b8f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_invert.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_invert.cc
@@ -18,7 +18,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int gpu_shader_invert(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -35,7 +35,7 @@ void register_node_type_sh_invert()
sh_node_type_base(&ntype, SH_NODE_INVERT, "Invert", NODE_CLASS_OP_COLOR);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::gpu_shader_invert);
+ ntype.gpu_fn = file_ns::gpu_shader_invert;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_layer_weight.cc b/source/blender/nodes/shader/nodes/node_shader_layer_weight.cc
index 69825e472fb..f589f85fc89 100644
--- a/source/blender/nodes/shader/nodes/node_shader_layer_weight.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_layer_weight.cc
@@ -15,7 +15,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_layer_weight(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -37,7 +37,7 @@ void register_node_type_sh_layer_weight()
sh_node_type_base(&ntype, SH_NODE_LAYER_WEIGHT, "Layer Weight", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_layer_weight);
+ ntype.gpu_fn = file_ns::node_shader_gpu_layer_weight;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_light_falloff.cc b/source/blender/nodes/shader/nodes/node_shader_light_falloff.cc
index 599becb4400..fcaf1b31e77 100644
--- a/source/blender/nodes/shader/nodes/node_shader_light_falloff.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_light_falloff.cc
@@ -16,7 +16,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_light_falloff(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -35,7 +35,7 @@ void register_node_type_sh_light_falloff()
sh_node_type_base(&ntype, SH_NODE_LIGHT_FALLOFF, "Light Falloff", NODE_CLASS_OP_COLOR);
ntype.declare = file_ns::node_declare;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_light_falloff);
+ ntype.gpu_fn = file_ns::node_shader_gpu_light_falloff;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_light_path.cc b/source/blender/nodes/shader/nodes/node_shader_light_path.cc
index 1e4ecbd77b1..b04b2a2f022 100644
--- a/source/blender/nodes/shader/nodes/node_shader_light_path.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_light_path.cc
@@ -24,7 +24,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_light_path(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -42,7 +42,7 @@ void register_node_type_sh_light_path()
sh_node_type_base(&ntype, SH_NODE_LIGHT_PATH, "Light Path", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_light_path);
+ ntype.gpu_fn = file_ns::node_shader_gpu_light_path;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_map_range.cc b/source/blender/nodes/shader/nodes/node_shader_map_range.cc
index 5fc69987c67..a906ee40b42 100644
--- a/source/blender/nodes/shader/nodes/node_shader_map_range.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_map_range.cc
@@ -39,7 +39,7 @@ static void sh_node_map_range_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Vector"));
}
-static void node_shader_buts_map_range(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_map_range(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "data_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
uiItemR(layout, ptr, "interpolation_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
@@ -94,7 +94,7 @@ static void node_shader_update_map_range(bNodeTree *ntree, bNode *node)
}
}
-static void node_shader_init_map_range(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_map_range(bNodeTree * /*ntree*/, bNode *node)
{
NodeMapRange *data = MEM_cnew<NodeMapRange>(__func__);
data->clamp = 1;
@@ -197,7 +197,7 @@ static const char *gpu_shader_get_name(int mode, bool use_vector)
static int gpu_shader_map_range(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -502,11 +502,11 @@ void register_node_type_sh_map_range()
ntype.declare = file_ns::sh_node_map_range_declare;
ntype.draw_buttons = file_ns::node_shader_buts_map_range;
ntype.ui_class = file_ns::node_shader_map_range_ui_class;
- node_type_init(&ntype, file_ns::node_shader_init_map_range);
+ ntype.initfunc = file_ns::node_shader_init_map_range;
node_type_storage(
&ntype, "NodeMapRange", node_free_standard_storage, node_copy_standard_storage);
- node_type_update(&ntype, file_ns::node_shader_update_map_range);
- node_type_gpu(&ntype, file_ns::gpu_shader_map_range);
+ ntype.updatefunc = file_ns::node_shader_update_map_range;
+ ntype.gpu_fn = file_ns::gpu_shader_map_range;
ntype.build_multi_function = file_ns::sh_node_map_range_build_multi_function;
ntype.gather_link_search_ops = file_ns::node_map_range_gather_link_searches;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.cc b/source/blender/nodes/shader/nodes/node_shader_mapping.cc
index 7824ee4861c..f9cac93544f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mapping.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_mapping.cc
@@ -36,7 +36,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Vector"));
}
-static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_mapping(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "vector_type", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
}
@@ -58,7 +58,7 @@ static const char *gpu_shader_get_name(int mode)
static int gpu_shader_mapping(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -87,8 +87,8 @@ void register_node_type_sh_mapping()
sh_node_type_base(&ntype, SH_NODE_MAPPING, "Mapping", NODE_CLASS_OP_VECTOR);
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_mapping;
- node_type_gpu(&ntype, file_ns::gpu_shader_mapping);
- node_type_update(&ntype, file_ns::node_shader_update_mapping);
+ ntype.gpu_fn = file_ns::gpu_shader_mapping;
+ ntype.updatefunc = file_ns::node_shader_update_mapping;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_math.cc b/source/blender/nodes/shader/nodes/node_shader_math.cc
index bd83f8dac37..5fe1bb48cc2 100644
--- a/source/blender/nodes/shader/nodes/node_shader_math.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_math.cc
@@ -82,7 +82,7 @@ static const char *gpu_shader_get_name(int mode)
static int gpu_shader_math(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -190,8 +190,8 @@ void register_node_type_sh_math()
sh_fn_node_type_base(&ntype, SH_NODE_MATH, "Math", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_math_declare;
ntype.labelfunc = node_math_label;
- node_type_gpu(&ntype, file_ns::gpu_shader_math);
- node_type_update(&ntype, node_math_update);
+ ntype.gpu_fn = file_ns::gpu_shader_math;
+ ntype.updatefunc = node_math_update;
ntype.build_multi_function = file_ns::sh_node_math_build_multi_function;
ntype.gather_link_search_ops = file_ns::sh_node_math_gather_link_searches;
diff --git a/source/blender/nodes/shader/nodes/node_shader_mix.cc b/source/blender/nodes/shader/nodes/node_shader_mix.cc
index f785e32832e..bc928ddb49a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mix.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_mix.cc
@@ -23,11 +23,13 @@ static void sh_node_mix_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Float>(N_("Factor"), "Factor_Float")
+ .no_muted_links()
.default_value(0.5f)
.min(0.0f)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Vector>(N_("Factor"), "Factor_Vector")
+ .no_muted_links()
.default_value(float3(0.5f))
.subtype(PROP_FACTOR);
@@ -50,7 +52,7 @@ static void sh_node_mix_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Result"), "Result_Color");
};
-static void sh_node_mix_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void sh_node_mix_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
const NodeShaderMix &data = node_storage(*static_cast<const bNode *>(ptr->data));
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
@@ -67,7 +69,7 @@ static void sh_node_mix_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA
}
}
-static void sh_node_mix_label(const bNodeTree *UNUSED(ntree),
+static void sh_node_mix_label(const bNodeTree * /*ntree*/,
const bNode *node,
char *label,
int maxlen)
@@ -121,6 +123,19 @@ static void sh_node_mix_update(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, sock_factor_vec, use_vector_factor);
}
+class SocketSearchOp {
+ public:
+ std::string socket_name;
+ int type = MA_RAMP_BLEND;
+ void operator()(LinkSearchOpParams &params)
+ {
+ bNode &node = params.add_node("ShaderNodeMix");
+ node_storage(node).data_type = SOCK_RGBA;
+ node_storage(node).blend_type = type;
+ params.update_and_connect_available_socket(node, socket_name);
+ }
+};
+
static void node_mix_gather_link_searches(GatherLinkSearchOpParams &params)
{
const eNodeSocketDatatype sock_type = static_cast<eNodeSocketDatatype>(
@@ -130,6 +145,17 @@ static void node_mix_gather_link_searches(GatherLinkSearchOpParams &params)
const eNodeSocketDatatype type = ELEM(sock_type, SOCK_BOOLEAN, SOCK_INT) ? SOCK_FLOAT :
sock_type;
+ const int weight = ELEM(params.other_socket().type, SOCK_RGBA) ? 0 : -1;
+ const std::string socket_name = params.in_out() == SOCK_IN ? "A" : "Result";
+ for (const EnumPropertyItem *item = rna_enum_ramp_blend_items; item->identifier != nullptr;
+ item++) {
+ if (item->name != nullptr && item->identifier[0] != '\0') {
+ params.add_item(CTX_IFACE_(BLT_I18NCONTEXT_ID_NODETREE, item->name),
+ SocketSearchOp{socket_name, item->value},
+ weight);
+ }
+ }
+
if (params.in_out() == SOCK_OUT) {
params.add_item(IFACE_("Result"), [type](LinkSearchOpParams &params) {
bNode &node = params.add_node("ShaderNodeMix");
@@ -165,7 +191,7 @@ static void node_mix_gather_link_searches(GatherLinkSearchOpParams &params)
}
}
-static void node_mix_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_mix_init(bNodeTree * /*tree*/, bNode *node)
{
NodeShaderMix *data = MEM_cnew<NodeShaderMix>(__func__);
data->data_type = SOCK_FLOAT;
@@ -235,7 +261,7 @@ static const char *gpu_shader_get_name(eNodeSocketDatatype data_type,
static int gpu_shader_mix(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -315,7 +341,7 @@ class MixColorFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<float> &fac = params.readonly_single_input<float>(0, "Factor");
const VArray<ColorGeometry4f> &col1 = params.readonly_single_input<ColorGeometry4f>(1, "A");
@@ -430,9 +456,9 @@ void register_node_type_sh_mix()
sh_fn_node_type_base(&ntype, SH_NODE_MIX, "Mix", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_mix_declare;
ntype.ui_class = file_ns::sh_node_mix_ui_class;
- node_type_gpu(&ntype, file_ns::gpu_shader_mix);
- node_type_update(&ntype, file_ns::sh_node_mix_update);
- node_type_init(&ntype, file_ns::node_mix_init);
+ ntype.gpu_fn = file_ns::gpu_shader_mix;
+ ntype.updatefunc = file_ns::sh_node_mix_update;
+ ntype.initfunc = file_ns::node_mix_init;
node_type_storage(
&ntype, "NodeShaderMix", node_free_standard_storage, node_copy_standard_storage);
ntype.build_multi_function = file_ns::sh_node_mix_build_multi_function;
diff --git a/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc b/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc
index 46ac8f05803..98771098f81 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc
@@ -64,7 +64,7 @@ static const char *gpu_shader_get_name(int mode)
static int gpu_shader_mix_rgb(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -111,7 +111,7 @@ class MixRGBFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<float> &fac = params.readonly_single_input<float>(0, "Fac");
const VArray<ColorGeometry4f> &col1 = params.readonly_single_input<ColorGeometry4f>(1,
@@ -150,10 +150,10 @@ void register_node_type_sh_mix_rgb()
static bNodeType ntype;
- sh_fn_node_type_base(&ntype, SH_NODE_MIX_RGB_LEGACY, "Mix", NODE_CLASS_OP_COLOR);
+ sh_fn_node_type_base(&ntype, SH_NODE_MIX_RGB_LEGACY, "Mix (Legacy)", NODE_CLASS_OP_COLOR);
ntype.declare = file_ns::sh_node_mix_rgb_declare;
ntype.labelfunc = node_blend_label;
- node_type_gpu(&ntype, file_ns::gpu_shader_mix_rgb);
+ ntype.gpu_fn = file_ns::gpu_shader_mix_rgb;
ntype.build_multi_function = file_ns::sh_node_mix_rgb_build_multi_function;
ntype.gather_link_search_ops = nullptr;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_mix_shader.cc b/source/blender/nodes/shader/nodes/node_shader_mix_shader.cc
index 7740bf9b92a..135e3582483 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mix_shader.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_mix_shader.cc
@@ -15,7 +15,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_mix_shader(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -33,7 +33,7 @@ void register_node_type_sh_mix_shader()
sh_node_type_base(&ntype, SH_NODE_MIX_SHADER, "Mix Shader", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_mix_shader);
+ ntype.gpu_fn = file_ns::node_shader_gpu_mix_shader;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_normal.cc b/source/blender/nodes/shader/nodes/node_shader_normal.cc
index f6214dd9c89..c36744524f4 100644
--- a/source/blender/nodes/shader/nodes/node_shader_normal.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_normal.cc
@@ -26,7 +26,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int gpu_shader_normal(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -44,7 +44,7 @@ void register_node_type_sh_normal()
sh_node_type_base(&ntype, SH_NODE_NORMAL, "Normal", NODE_CLASS_OP_VECTOR);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::gpu_shader_normal);
+ ntype.gpu_fn = file_ns::gpu_shader_normal;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_normal_map.cc b/source/blender/nodes/shader/nodes/node_shader_normal_map.cc
index d51d8def945..4338cfd9457 100644
--- a/source/blender/nodes/shader/nodes/node_shader_normal_map.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.cc
@@ -34,7 +34,7 @@ static void node_shader_buts_normal_map(uiLayout *layout, bContext *C, PointerRN
}
}
-static void node_shader_init_normal_map(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_normal_map(bNodeTree * /*ntree*/, bNode *node)
{
NodeShaderNormalMap *attr = MEM_cnew<NodeShaderNormalMap>("NodeShaderNormalMap");
node->storage = attr;
@@ -42,7 +42,7 @@ static void node_shader_init_normal_map(bNodeTree *UNUSED(ntree), bNode *node)
static int gpu_shader_normal_map(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -118,10 +118,10 @@ void register_node_type_sh_normal_map()
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_normal_map;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, file_ns::node_shader_init_normal_map);
+ ntype.initfunc = file_ns::node_shader_init_normal_map;
node_type_storage(
&ntype, "NodeShaderNormalMap", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::gpu_shader_normal_map);
+ ntype.gpu_fn = file_ns::gpu_shader_normal_map;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_object_info.cc b/source/blender/nodes/shader/nodes/node_shader_object_info.cc
index 8985ab6d0e9..daa40d8dc63 100644
--- a/source/blender/nodes/shader/nodes/node_shader_object_info.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_object_info.cc
@@ -17,7 +17,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_object_info(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -37,7 +37,7 @@ void register_node_type_sh_object_info()
sh_node_type_base(&ntype, SH_NODE_OBJECT_INFO, "Object Info", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_object_info);
+ ntype.gpu_fn = file_ns::node_shader_gpu_object_info;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_aov.cc b/source/blender/nodes/shader/nodes/node_shader_output_aov.cc
index 78dabc5c1c2..b668b5313ba 100644
--- a/source/blender/nodes/shader/nodes/node_shader_output_aov.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_output_aov.cc
@@ -16,12 +16,12 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Float>(N_("Value")).default_value(0.0f).min(0.0f).max(1.0f);
}
-static void node_shader_buts_output_aov(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_output_aov(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "name", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
}
-static void node_shader_init_output_aov(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_output_aov(bNodeTree * /*ntree*/, bNode *node)
{
NodeShaderOutputAOV *aov = MEM_cnew<NodeShaderOutputAOV>("NodeShaderOutputAOV");
node->storage = aov;
@@ -29,7 +29,7 @@ static void node_shader_init_output_aov(bNodeTree *UNUSED(ntree), bNode *node)
static int node_shader_gpu_output_aov(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -60,10 +60,10 @@ void register_node_type_sh_output_aov()
sh_node_type_base(&ntype, SH_NODE_OUTPUT_AOV, "AOV Output", NODE_CLASS_OUTPUT);
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_output_aov;
- node_type_init(&ntype, file_ns::node_shader_init_output_aov);
+ ntype.initfunc = file_ns::node_shader_init_output_aov;
node_type_storage(
&ntype, "NodeShaderOutputAOV", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_output_aov);
+ ntype.gpu_fn = file_ns::node_shader_gpu_output_aov;
ntype.no_muting = true;
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_light.cc b/source/blender/nodes/shader/nodes/node_shader_output_light.cc
index 3707806841e..848e6c92e17 100644
--- a/source/blender/nodes/shader/nodes/node_shader_output_light.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_output_light.cc
@@ -11,10 +11,10 @@ static void node_declare(NodeDeclarationBuilder &b)
}
static int node_shader_gpu_output_light(GPUMaterial *mat,
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
+ bNode * /*node*/,
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
- GPUNodeStack *UNUSED(out))
+ GPUNodeStack * /*out*/)
{
GPUNodeLink *outlink_surface;
/* Passthrough node in order to do the right socket conversions. */
@@ -37,7 +37,7 @@ void register_node_type_sh_output_light()
sh_node_type_base(&ntype, SH_NODE_OUTPUT_LIGHT, "Light Output", NODE_CLASS_OUTPUT);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_output_light);
+ ntype.gpu_fn = file_ns::node_shader_gpu_output_light;
ntype.no_muting = true;
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_linestyle.cc b/source/blender/nodes/shader/nodes/node_shader_output_linestyle.cc
index b387aebf5e3..47909985374 100644
--- a/source/blender/nodes/shader/nodes/node_shader_output_linestyle.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_output_linestyle.cc
@@ -28,7 +28,7 @@ static void node_declare(NodeDeclarationBuilder &b)
.subtype(PROP_FACTOR);
}
-static void node_buts_output_linestyle(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_buts_output_linestyle(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *row, *col;
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_material.cc b/source/blender/nodes/shader/nodes/node_shader_output_material.cc
index 133457c167f..ff2628a891b 100644
--- a/source/blender/nodes/shader/nodes/node_shader_output_material.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_output_material.cc
@@ -16,10 +16,10 @@ static void node_declare(NodeDeclarationBuilder &b)
}
static int node_shader_gpu_output_material(GPUMaterial *mat,
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
+ bNode * /*node*/,
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
- GPUNodeStack *UNUSED(out))
+ GPUNodeStack * /*out*/)
{
GPUNodeLink *outlink_surface, *outlink_volume, *outlink_displacement, *outlink_thickness;
/* Passthrough node in order to do the right socket conversions (important for displacement). */
@@ -53,7 +53,7 @@ void register_node_type_sh_output_material()
sh_node_type_base(&ntype, SH_NODE_OUTPUT_MATERIAL, "Material Output", NODE_CLASS_OUTPUT);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_output_material);
+ ntype.gpu_fn = file_ns::node_shader_gpu_output_material;
ntype.no_muting = true;
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_world.cc b/source/blender/nodes/shader/nodes/node_shader_output_world.cc
index b0cf4c80bc5..2d75faa9e80 100644
--- a/source/blender/nodes/shader/nodes/node_shader_output_world.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_output_world.cc
@@ -12,10 +12,10 @@ static void node_declare(NodeDeclarationBuilder &b)
}
static int node_shader_gpu_output_world(GPUMaterial *mat,
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
+ bNode * /*node*/,
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
- GPUNodeStack *UNUSED(out))
+ GPUNodeStack * /*out*/)
{
GPUNodeLink *outlink_surface, *outlink_volume;
if (in[0].link) {
@@ -40,7 +40,7 @@ void register_node_type_sh_output_world()
sh_node_type_base(&ntype, SH_NODE_OUTPUT_WORLD, "World Output", NODE_CLASS_OUTPUT);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_output_world);
+ ntype.gpu_fn = file_ns::node_shader_gpu_output_world;
ntype.no_muting = true;
diff --git a/source/blender/nodes/shader/nodes/node_shader_particle_info.cc b/source/blender/nodes/shader/nodes/node_shader_particle_info.cc
index 71adbd5e5c4..c86bb5866dd 100644
--- a/source/blender/nodes/shader/nodes/node_shader_particle_info.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_particle_info.cc
@@ -24,7 +24,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int gpu_shader_particle_info(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -44,7 +44,7 @@ void register_node_type_sh_particle_info()
sh_node_type_base(&ntype, SH_NODE_PARTICLE_INFO, "Particle Info", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::gpu_shader_particle_info);
+ ntype.gpu_fn = file_ns::gpu_shader_particle_info;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_point_info.cc b/source/blender/nodes/shader/nodes/node_shader_point_info.cc
index 1cddf2acc8a..fffa3abad03 100644
--- a/source/blender/nodes/shader/nodes/node_shader_point_info.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_point_info.cc
@@ -14,7 +14,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_point_info(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -32,7 +32,7 @@ void register_node_type_sh_point_info()
sh_node_type_base(&ntype, SH_NODE_POINT_INFO, "Point Info", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_point_info);
+ ntype.gpu_fn = file_ns::node_shader_gpu_point_info;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_rgb.cc b/source/blender/nodes/shader/nodes/node_shader_rgb.cc
index 3d28f5278a2..d70df4a8e25 100644
--- a/source/blender/nodes/shader/nodes/node_shader_rgb.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_rgb.cc
@@ -16,7 +16,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int gpu_shader_rgb(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack * /*in*/,
GPUNodeStack *out)
{
@@ -35,7 +35,7 @@ void register_node_type_sh_rgb()
sh_node_type_base(&ntype, SH_NODE_RGB, "RGB", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::gpu_shader_rgb);
+ ntype.gpu_fn = file_ns::gpu_shader_rgb;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_rgb_to_bw.cc b/source/blender/nodes/shader/nodes/node_shader_rgb_to_bw.cc
index 7d738cdd719..1e663d1b86f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_rgb_to_bw.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_rgb_to_bw.cc
@@ -19,7 +19,7 @@ static void sh_node_rgbtobw_declare(NodeDeclarationBuilder &b)
static int gpu_shader_rgbtobw(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -36,7 +36,7 @@ void register_node_type_sh_rgbtobw()
sh_node_type_base(&ntype, SH_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_rgbtobw_declare;
- node_type_gpu(&ntype, file_ns::gpu_shader_rgbtobw);
+ ntype.gpu_fn = file_ns::gpu_shader_rgbtobw;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_script.cc b/source/blender/nodes/shader/nodes/node_shader_script.cc
index 4d3d2af6aa6..213de85cb15 100644
--- a/source/blender/nodes/shader/nodes/node_shader_script.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_script.cc
@@ -12,7 +12,7 @@
namespace blender::nodes::node_shader_script_cc {
-static void node_shader_buts_script(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_script(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *row;
@@ -44,7 +44,7 @@ static void node_shader_buts_script_ex(uiLayout *layout, bContext *C, PointerRNA
#endif
}
-static void init(bNodeTree *UNUSED(ntree), bNode *node)
+static void init(bNodeTree * /*ntree*/, bNode *node)
{
NodeShaderScript *nss = MEM_cnew<NodeShaderScript>("shader script node");
node->storage = nss;
@@ -63,9 +63,7 @@ static void node_free_script(bNode *node)
}
}
-static void node_copy_script(bNodeTree *UNUSED(dest_ntree),
- bNode *dest_node,
- const bNode *src_node)
+static void node_copy_script(bNodeTree * /*dst_ntree*/, bNode *dest_node, const bNode *src_node)
{
NodeShaderScript *src_nss = static_cast<NodeShaderScript *>(src_node->storage);
NodeShaderScript *dest_nss = static_cast<NodeShaderScript *>(MEM_dupallocN(src_nss));
@@ -88,7 +86,7 @@ void register_node_type_sh_script()
sh_node_type_base(&ntype, SH_NODE_SCRIPT, "Script", NODE_CLASS_SCRIPT);
ntype.draw_buttons = file_ns::node_shader_buts_script;
ntype.draw_buttons_ex = file_ns::node_shader_buts_script_ex;
- node_type_init(&ntype, file_ns::init);
+ ntype.initfunc = file_ns::init;
node_type_storage(
&ntype, "NodeShaderScript", file_ns::node_free_script, file_ns::node_copy_script);
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_color.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_color.cc
index 8e378ebabce..94e5f19b840 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_color.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_color.cc
@@ -10,7 +10,7 @@
#include "UI_interface.h"
#include "UI_resources.h"
-static void node_combsep_color_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_combsep_color_init(bNodeTree * /*tree*/, bNode *node)
{
NodeCombSepColor *data = MEM_cnew<NodeCombSepColor>(__func__);
data->mode = NODE_COMBSEP_COLOR_RGB;
@@ -31,7 +31,7 @@ static void sh_node_sepcolor_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Blue"));
}
-static void node_sepcolor_update(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_sepcolor_update(bNodeTree * /*ntree*/, bNode *node)
{
const NodeCombSepColor &storage = node_storage(*node);
node_combsep_color_label(&node->outputs, (NodeCombSepColorMode)storage.mode);
@@ -53,7 +53,7 @@ static const char *gpu_shader_get_name(int mode)
static int gpu_shader_sepcolor(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -76,11 +76,11 @@ void register_node_type_sh_sepcolor()
sh_node_type_base(&ntype, SH_NODE_SEPARATE_COLOR, "Separate Color", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_sepcolor_declare;
- node_type_update(&ntype, file_ns::node_sepcolor_update);
- node_type_init(&ntype, node_combsep_color_init);
+ ntype.updatefunc = file_ns::node_sepcolor_update;
+ ntype.initfunc = node_combsep_color_init;
node_type_storage(
&ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::gpu_shader_sepcolor);
+ ntype.gpu_fn = file_ns::gpu_shader_sepcolor;
nodeRegisterType(&ntype);
}
@@ -107,7 +107,7 @@ static void sh_node_combcolor_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Color"));
}
-static void node_combcolor_update(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_combcolor_update(bNodeTree * /*ntree*/, bNode *node)
{
const NodeCombSepColor &storage = node_storage(*node);
node_combsep_color_label(&node->inputs, (NodeCombSepColorMode)storage.mode);
@@ -129,7 +129,7 @@ static const char *gpu_shader_get_name(int mode)
static int gpu_shader_combcolor(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -152,11 +152,11 @@ void register_node_type_sh_combcolor()
sh_node_type_base(&ntype, SH_NODE_COMBINE_COLOR, "Combine Color", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_combcolor_declare;
- node_type_update(&ntype, file_ns::node_combcolor_update);
- node_type_init(&ntype, node_combsep_color_init);
+ ntype.updatefunc = file_ns::node_combcolor_update;
+ ntype.initfunc = node_combsep_color_init;
node_type_storage(
&ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::gpu_shader_combcolor);
+ ntype.gpu_fn = file_ns::gpu_shader_combcolor;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_hsv.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_hsv.cc
index 1c02c5ba074..66ff5f82944 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_hsv.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_hsv.cc
@@ -21,7 +21,7 @@ static void node_declare_sephsv(NodeDeclarationBuilder &b)
static int gpu_shader_sephsv(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -36,9 +36,9 @@ void register_node_type_sh_sephsv()
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_SEPHSV_LEGACY, "Separate HSV", NODE_CLASS_CONVERTER);
+ sh_node_type_base(&ntype, SH_NODE_SEPHSV_LEGACY, "Separate HSV (Legacy)", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare_sephsv;
- node_type_gpu(&ntype, file_ns::gpu_shader_sephsv);
+ ntype.gpu_fn = file_ns::gpu_shader_sephsv;
ntype.gather_link_search_ops = nullptr;
nodeRegisterType(&ntype);
@@ -58,7 +58,7 @@ static void node_declare_combhsv(NodeDeclarationBuilder &b)
static int gpu_shader_combhsv(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -73,9 +73,9 @@ void register_node_type_sh_combhsv()
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_COMBHSV_LEGACY, "Combine HSV", NODE_CLASS_CONVERTER);
+ sh_node_type_base(&ntype, SH_NODE_COMBHSV_LEGACY, "Combine HSV (Legacy)", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare_combhsv;
- node_type_gpu(&ntype, file_ns::gpu_shader_combhsv);
+ ntype.gpu_fn = file_ns::gpu_shader_combhsv;
ntype.gather_link_search_ops = nullptr;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc
index 3fe76b05b5d..28c4eef823f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc
@@ -20,7 +20,7 @@ static void sh_node_seprgb_declare(NodeDeclarationBuilder &b)
static int gpu_shader_seprgb(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -45,7 +45,7 @@ class SeparateRGBFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
"Color");
@@ -76,9 +76,10 @@ void register_node_type_sh_seprgb()
static bNodeType ntype;
- sh_fn_node_type_base(&ntype, SH_NODE_SEPRGB_LEGACY, "Separate RGB", NODE_CLASS_CONVERTER);
+ sh_fn_node_type_base(
+ &ntype, SH_NODE_SEPRGB_LEGACY, "Separate RGB (Legacy)", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_seprgb_declare;
- node_type_gpu(&ntype, file_ns::gpu_shader_seprgb);
+ ntype.gpu_fn = file_ns::gpu_shader_seprgb;
ntype.build_multi_function = file_ns::sh_node_seprgb_build_multi_function;
ntype.gather_link_search_ops = nullptr;
@@ -98,7 +99,7 @@ static void sh_node_combrgb_declare(NodeDeclarationBuilder &b)
static int gpu_shader_combrgb(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -120,9 +121,10 @@ void register_node_type_sh_combrgb()
static bNodeType ntype;
- sh_fn_node_type_base(&ntype, SH_NODE_COMBRGB_LEGACY, "Combine RGB", NODE_CLASS_CONVERTER);
+ sh_fn_node_type_base(
+ &ntype, SH_NODE_COMBRGB_LEGACY, "Combine RGB (Legacy)", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_combrgb_declare;
- node_type_gpu(&ntype, file_ns::gpu_shader_combrgb);
+ ntype.gpu_fn = file_ns::gpu_shader_combrgb;
ntype.build_multi_function = file_ns::sh_node_combrgb_build_multi_function;
ntype.gather_link_search_ops = nullptr;
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc
index d4413036555..131ae16ef1b 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc
@@ -20,7 +20,7 @@ static void sh_node_sepxyz_declare(NodeDeclarationBuilder &b)
static int gpu_shader_sepxyz(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -45,7 +45,7 @@ class MF_SeparateXYZ : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<float3> &vectors = params.readonly_single_input<float3>(0, "XYZ");
MutableSpan<float> xs = params.uninitialized_single_output_if_required<float>(1, "X");
@@ -97,7 +97,7 @@ void register_node_type_sh_sepxyz()
sh_fn_node_type_base(&ntype, SH_NODE_SEPXYZ, "Separate XYZ", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_sepxyz_declare;
- node_type_gpu(&ntype, file_ns::gpu_shader_sepxyz);
+ ntype.gpu_fn = file_ns::gpu_shader_sepxyz;
ntype.build_multi_function = file_ns::sh_node_sepxyz_build_multi_function;
nodeRegisterType(&ntype);
@@ -116,7 +116,7 @@ static void sh_node_combxyz_declare(NodeDeclarationBuilder &b)
static int gpu_shader_combxyz(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -142,7 +142,7 @@ void register_node_type_sh_combxyz()
sh_fn_node_type_base(&ntype, SH_NODE_COMBXYZ, "Combine XYZ", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_combxyz_declare;
- node_type_gpu(&ntype, file_ns::gpu_shader_combxyz);
+ ntype.gpu_fn = file_ns::gpu_shader_combxyz;
ntype.build_multi_function = file_ns::sh_node_combxyz_build_multi_function;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_shader_to_rgb.cc b/source/blender/nodes/shader/nodes/node_shader_shader_to_rgb.cc
index 0404158a803..38ae1f979a8 100644
--- a/source/blender/nodes/shader/nodes/node_shader_shader_to_rgb.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_shader_to_rgb.cc
@@ -14,7 +14,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_shadertorgb(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -34,7 +34,7 @@ void register_node_type_sh_shadertorgb()
sh_node_type_base(&ntype, SH_NODE_SHADERTORGB, "Shader to RGB", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_shadertorgb);
+ ntype.gpu_fn = file_ns::node_shader_gpu_shadertorgb;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_squeeze.cc b/source/blender/nodes/shader/nodes/node_shader_squeeze.cc
index c22420d8d47..31965c5e13e 100644
--- a/source/blender/nodes/shader/nodes/node_shader_squeeze.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_squeeze.cc
@@ -19,7 +19,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int gpu_shader_squeeze(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -36,7 +36,7 @@ void register_node_type_sh_squeeze()
sh_node_type_base(&ntype, SH_NODE_SQUEEZE, "Squeeze Value", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::gpu_shader_squeeze);
+ ntype.gpu_fn = file_ns::gpu_shader_squeeze;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.cc b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.cc
index e3ff4c28604..bcf859251e3 100644
--- a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.cc
@@ -29,12 +29,12 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Shader>(N_("BSSRDF"));
}
-static void node_shader_buts_subsurface(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_subsurface(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "falloff", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
-static void node_shader_init_subsurface_scattering(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_subsurface_scattering(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = SHD_SUBSURFACE_RANDOM_WALK;
node->custom2 = true;
@@ -42,7 +42,7 @@ static void node_shader_init_subsurface_scattering(bNodeTree *UNUSED(ntree), bNo
static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -87,9 +87,9 @@ void register_node_type_sh_subsurface_scattering()
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_subsurface;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, file_ns::node_shader_init_subsurface_scattering);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_subsurface_scattering);
- node_type_update(&ntype, file_ns::node_shader_update_subsurface_scattering);
+ ntype.initfunc = file_ns::node_shader_init_subsurface_scattering;
+ ntype.gpu_fn = file_ns::node_shader_gpu_subsurface_scattering;
+ ntype.updatefunc = file_ns::node_shader_update_subsurface_scattering;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tangent.cc b/source/blender/nodes/shader/nodes/node_shader_tangent.cc
index 8e27ebed21b..9b09eb09bba 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tangent.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tangent.cc
@@ -41,7 +41,7 @@ static void node_shader_buts_tangent(uiLayout *layout, bContext *C, PointerRNA *
}
}
-static void node_shader_init_tangent(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_tangent(bNodeTree * /*ntree*/, bNode *node)
{
NodeShaderTangent *attr = MEM_cnew<NodeShaderTangent>("NodeShaderTangent");
attr->axis = SHD_TANGENT_AXIS_Z;
@@ -50,7 +50,7 @@ static void node_shader_init_tangent(bNodeTree *UNUSED(ntree), bNode *node)
static int node_shader_gpu_tangent(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -89,8 +89,8 @@ void register_node_type_sh_tangent()
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_tangent;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, file_ns::node_shader_init_tangent);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_tangent);
+ ntype.initfunc = file_ns::node_shader_init_tangent;
+ ntype.gpu_fn = file_ns::node_shader_gpu_tangent;
node_type_storage(
&ntype, "NodeShaderTangent", node_free_standard_storage, node_copy_standard_storage);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc
index a1c51a440d0..aaae1369d79 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc
@@ -13,7 +13,10 @@ namespace blender::nodes::node_shader_tex_brick_cc {
static void sh_node_tex_brick_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>(N_("Vector")).min(-10000.0f).max(10000.0f).implicit_field();
+ b.add_input<decl::Vector>(N_("Vector"))
+ .min(-10000.0f)
+ .max(10000.0f)
+ .implicit_field(implicit_field_inputs::position);
b.add_input<decl::Color>(N_("Color1")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
b.add_input<decl::Color>(N_("Color2")).default_value({0.2f, 0.2f, 0.2f, 1.0f});
b.add_input<decl::Color>(N_("Mortar")).default_value({0.0f, 0.0f, 0.0f, 1.0f}).no_muted_links();
@@ -43,7 +46,7 @@ static void sh_node_tex_brick_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Fac"));
}
-static void node_shader_buts_tex_brick(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_tex_brick(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiLayout *col;
@@ -63,7 +66,7 @@ static void node_shader_buts_tex_brick(uiLayout *layout, bContext *UNUSED(C), Po
col, ptr, "squash_frequency", UI_ITEM_R_SPLIT_EMPTY_NAME, IFACE_("Frequency"), ICON_NONE);
}
-static void node_shader_init_tex_brick(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_tex_brick(bNodeTree * /*ntree*/, bNode *node)
{
NodeTexBrick *tex = MEM_cnew<NodeTexBrick>(__func__);
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
@@ -85,7 +88,7 @@ static void node_shader_init_tex_brick(bNodeTree *UNUSED(ntree), bNode *node)
static int node_shader_gpu_tex_brick(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -147,7 +150,7 @@ class BrickFunction : public fn::MultiFunction {
n = (n + 1013) & 0x7fffffff;
n = (n >> 13) ^ n;
const uint nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
- return 0.5f * ((float)nn / 1073741824.0f);
+ return 0.5f * (float(nn) / 1073741824.0f);
}
static float smoothstepf(const float f)
@@ -169,14 +172,14 @@ class BrickFunction : public fn::MultiFunction {
{
float offset = 0.0f;
- const int rownum = (int)floorf(p.y / row_height);
+ const int rownum = int(floorf(p.y / row_height));
if (offset_frequency && squash_frequency) {
brick_width *= (rownum % squash_frequency) ? 1.0f : squash_amount;
offset = (rownum % offset_frequency) ? 0.0f : (brick_width * offset_amount);
}
- const int bricknum = (int)floorf((p.x + offset) / brick_width);
+ const int bricknum = int(floorf((p.x + offset) / brick_width));
const float x = (p.x + offset) - brick_width * bricknum;
const float y = p.y - row_height * rownum;
@@ -200,7 +203,7 @@ class BrickFunction : public fn::MultiFunction {
return float2(tint, mortar);
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
const VArray<ColorGeometry4f> &color1_values = params.readonly_single_input<ColorGeometry4f>(
@@ -280,10 +283,10 @@ void register_node_type_sh_tex_brick()
ntype.declare = file_ns::sh_node_tex_brick_declare;
ntype.draw_buttons = file_ns::node_shader_buts_tex_brick;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, file_ns::node_shader_init_tex_brick);
+ ntype.initfunc = file_ns::node_shader_init_tex_brick;
node_type_storage(
&ntype, "NodeTexBrick", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_brick);
+ ntype.gpu_fn = file_ns::node_shader_gpu_tex_brick;
ntype.build_multi_function = file_ns::sh_node_brick_build_multi_function;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc
index b0e5639c893..bef3eb990eb 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc
@@ -8,7 +8,10 @@ namespace blender::nodes::node_shader_tex_checker_cc {
static void sh_node_tex_checker_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>(N_("Vector")).min(-10000.0f).max(10000.0f).implicit_field();
+ b.add_input<decl::Vector>(N_("Vector"))
+ .min(-10000.0f)
+ .max(10000.0f)
+ .implicit_field(implicit_field_inputs::position);
b.add_input<decl::Color>(N_("Color1")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
b.add_input<decl::Color>(N_("Color2")).default_value({0.2f, 0.2f, 0.2f, 1.0f});
b.add_input<decl::Float>(N_("Scale"))
@@ -20,7 +23,7 @@ static void sh_node_tex_checker_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Fac"));
}
-static void node_shader_init_tex_checker(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_tex_checker(bNodeTree * /*ntree*/, bNode *node)
{
NodeTexChecker *tex = MEM_cnew<NodeTexChecker>(__func__);
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
@@ -31,7 +34,7 @@ static void node_shader_init_tex_checker(bNodeTree *UNUSED(ntree), bNode *node)
static int node_shader_gpu_tex_checker(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -61,7 +64,7 @@ class NodeTexChecker : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
const VArray<ColorGeometry4f> &color1 = params.readonly_single_input<ColorGeometry4f>(
@@ -77,9 +80,9 @@ class NodeTexChecker : public fn::MultiFunction {
/* Avoid precision issues on unit coordinates. */
const float3 p = (vector[i] * scale[i] + 0.000001f) * 0.999999f;
- const int xi = abs((int)(floorf(p.x)));
- const int yi = abs((int)(floorf(p.y)));
- const int zi = abs((int)(floorf(p.z)));
+ const int xi = abs(int(floorf(p.x)));
+ const int yi = abs(int(floorf(p.y)));
+ const int zi = abs(int(floorf(p.z)));
r_fac[i] = ((xi % 2 == yi % 2) == (zi % 2)) ? 1.0f : 0.0f;
}
@@ -108,10 +111,10 @@ void register_node_type_sh_tex_checker()
sh_fn_node_type_base(&ntype, SH_NODE_TEX_CHECKER, "Checker Texture", NODE_CLASS_TEXTURE);
ntype.declare = file_ns::sh_node_tex_checker_declare;
- node_type_init(&ntype, file_ns::node_shader_init_tex_checker);
+ ntype.initfunc = file_ns::node_shader_init_tex_checker;
node_type_storage(
&ntype, "NodeTexChecker", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_checker);
+ ntype.gpu_fn = file_ns::node_shader_gpu_tex_checker;
ntype.build_multi_function = file_ns::sh_node_tex_checker_build_multi_function;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.cc b/source/blender/nodes/shader/nodes/node_shader_tex_coord.cc
index 9727a6089a6..a295bda9d07 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.cc
@@ -21,7 +21,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Reflection"));
}
-static void node_shader_buts_tex_coord(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_tex_coord(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "object", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, 0);
uiItemR(layout, ptr, "from_instancer", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, 0);
@@ -29,7 +29,7 @@ static void node_shader_buts_tex_coord(uiLayout *layout, bContext *UNUSED(C), Po
static int node_shader_gpu_tex_coord(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -38,7 +38,7 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat,
/* Use special matrix to let the shader branch to using the render object's matrix. */
float dummy_matrix[4][4];
dummy_matrix[3][3] = 0.0f;
- GPUNodeLink *inv_obmat = (ob != nullptr) ? GPU_uniform(&ob->imat[0][0]) :
+ GPUNodeLink *inv_obmat = (ob != nullptr) ? GPU_uniform(&ob->world_to_object[0][0]) :
GPU_uniform(&dummy_matrix[0][0]);
/* Optimization: don't request orco if not needed. */
@@ -82,7 +82,7 @@ void register_node_type_sh_tex_coord()
sh_node_type_base(&ntype, SH_NODE_TEX_COORD, "Texture Coordinate", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_tex_coord;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_coord);
+ ntype.gpu_fn = file_ns::node_shader_gpu_tex_coord;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc b/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc
index 2739a75ed21..60059a8f1c5 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc
@@ -11,7 +11,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Color")).no_muted_links();
}
-static void node_shader_init_tex_environment(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_tex_environment(bNodeTree * /*ntree*/, bNode *node)
{
NodeTexEnvironment *tex = MEM_cnew<NodeTexEnvironment>("NodeTexEnvironment");
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
@@ -24,7 +24,7 @@ static void node_shader_init_tex_environment(bNodeTree *UNUSED(ntree), bNode *no
static int node_shader_gpu_tex_environment(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -125,10 +125,10 @@ void register_node_type_sh_tex_environment()
sh_node_type_base(&ntype, SH_NODE_TEX_ENVIRONMENT, "Environment Texture", NODE_CLASS_TEXTURE);
ntype.declare = file_ns::node_declare;
- node_type_init(&ntype, file_ns::node_shader_init_tex_environment);
+ ntype.initfunc = file_ns::node_shader_init_tex_environment;
node_type_storage(
&ntype, "NodeTexEnvironment", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_environment);
+ ntype.gpu_fn = file_ns::node_shader_gpu_tex_environment;
ntype.labelfunc = node_image_label;
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc
index 37c72ec1f17..f7bff442420 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc
@@ -11,17 +11,19 @@ namespace blender::nodes::node_shader_tex_gradient_cc {
static void sh_node_tex_gradient_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>(N_("Vector")).hide_value().implicit_field();
+ b.add_input<decl::Vector>(N_("Vector"))
+ .hide_value()
+ .implicit_field(implicit_field_inputs::position);
b.add_output<decl::Color>(N_("Color")).no_muted_links();
b.add_output<decl::Float>(N_("Fac")).no_muted_links();
}
-static void node_shader_buts_tex_gradient(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_tex_gradient(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "gradient_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
-static void node_shader_init_tex_gradient(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_tex_gradient(bNodeTree * /*ntree*/, bNode *node)
{
NodeTexGradient *tex = MEM_cnew<NodeTexGradient>(__func__);
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
@@ -33,7 +35,7 @@ static void node_shader_init_tex_gradient(bNodeTree *UNUSED(ntree), bNode *node)
static int node_shader_gpu_tex_gradient(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -65,7 +67,7 @@ class GradientFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
@@ -155,10 +157,10 @@ void register_node_type_sh_tex_gradient()
sh_fn_node_type_base(&ntype, SH_NODE_TEX_GRADIENT, "Gradient Texture", NODE_CLASS_TEXTURE);
ntype.declare = file_ns::sh_node_tex_gradient_declare;
ntype.draw_buttons = file_ns::node_shader_buts_tex_gradient;
- node_type_init(&ntype, file_ns::node_shader_init_tex_gradient);
+ ntype.initfunc = file_ns::node_shader_init_tex_gradient;
node_type_storage(
&ntype, "NodeTexGradient", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_gradient);
+ ntype.gpu_fn = file_ns::node_shader_gpu_tex_gradient;
ntype.build_multi_function = file_ns::sh_node_gradient_tex_build_multi_function;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc
index c9588949761..9f4f885fee1 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc
@@ -8,12 +8,12 @@ namespace blender::nodes::node_shader_tex_image_cc {
static void sh_node_tex_image_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>(N_("Vector")).implicit_field();
+ b.add_input<decl::Vector>(N_("Vector")).implicit_field(implicit_field_inputs::position);
b.add_output<decl::Color>(N_("Color")).no_muted_links();
b.add_output<decl::Float>(N_("Alpha")).no_muted_links();
}
-static void node_shader_init_tex_image(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_tex_image(bNodeTree * /*ntree*/, bNode *node)
{
NodeTexImage *tex = MEM_cnew<NodeTexImage>(__func__);
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
@@ -25,7 +25,7 @@ static void node_shader_init_tex_image(bNodeTree *UNUSED(ntree), bNode *node)
static int node_shader_gpu_tex_image(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -163,10 +163,10 @@ void register_node_type_sh_tex_image()
sh_node_type_base(&ntype, SH_NODE_TEX_IMAGE, "Image Texture", NODE_CLASS_TEXTURE);
ntype.declare = file_ns::sh_node_tex_image_declare;
- node_type_init(&ntype, file_ns::node_shader_init_tex_image);
+ ntype.initfunc = file_ns::node_shader_init_tex_image;
node_type_storage(
&ntype, "NodeTexImage", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_image);
+ ntype.gpu_fn = file_ns::node_shader_gpu_tex_image;
ntype.labelfunc = node_image_label;
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc b/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc
index 205d3b89016..f68f1747b21 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc
@@ -11,19 +11,19 @@ namespace blender::nodes::node_shader_tex_magic_cc {
static void sh_node_tex_magic_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>(N_("Vector")).implicit_field();
+ b.add_input<decl::Vector>(N_("Vector")).implicit_field(implicit_field_inputs::position);
b.add_input<decl::Float>(N_("Scale")).min(-1000.0f).max(1000.0f).default_value(5.0f);
b.add_input<decl::Float>(N_("Distortion")).min(-1000.0f).max(1000.0f).default_value(1.0f);
b.add_output<decl::Color>(N_("Color")).no_muted_links();
b.add_output<decl::Float>(N_("Fac")).no_muted_links();
}
-static void node_shader_buts_tex_magic(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_tex_magic(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "turbulence_depth", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
}
-static void node_shader_init_tex_magic(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_tex_magic(bNodeTree * /*ntree*/, bNode *node)
{
NodeTexMagic *tex = MEM_cnew<NodeTexMagic>(__func__);
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
@@ -35,7 +35,7 @@ static void node_shader_init_tex_magic(bNodeTree *UNUSED(ntree), bNode *node)
static int node_shader_gpu_tex_magic(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -70,7 +70,7 @@ class MagicFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
const VArray<float> &scale = params.readonly_single_input<float>(1, "Scale");
@@ -177,10 +177,10 @@ void register_node_type_sh_tex_magic()
sh_fn_node_type_base(&ntype, SH_NODE_TEX_MAGIC, "Magic Texture", NODE_CLASS_TEXTURE);
ntype.declare = file_ns::sh_node_tex_magic_declare;
ntype.draw_buttons = file_ns::node_shader_buts_tex_magic;
- node_type_init(&ntype, file_ns::node_shader_init_tex_magic);
+ ntype.initfunc = file_ns::node_shader_init_tex_magic;
node_type_storage(
&ntype, "NodeTexMagic", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_magic);
+ ntype.gpu_fn = file_ns::node_shader_gpu_tex_magic;
ntype.build_multi_function = file_ns::sh_node_magic_tex_build_multi_function;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc
index a2241c2327f..e79b12b78b9 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc
@@ -15,7 +15,9 @@ NODE_STORAGE_FUNCS(NodeTexMusgrave)
static void sh_node_tex_musgrave_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>(N_("Vector")).hide_value().implicit_field();
+ b.add_input<decl::Vector>(N_("Vector"))
+ .hide_value()
+ .implicit_field(implicit_field_inputs::position);
b.add_input<decl::Float>(N_("W")).min(-1000.0f).max(1000.0f).make_available([](bNode &node) {
/* Default to 1 instead of 4, because it is much faster. */
node_storage(node).dimensions = 1;
@@ -29,13 +31,13 @@ static void sh_node_tex_musgrave_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Fac")).no_muted_links();
}
-static void node_shader_buts_tex_musgrave(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_tex_musgrave(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "musgrave_dimensions", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
uiItemR(layout, ptr, "musgrave_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
-static void node_shader_init_tex_musgrave(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_tex_musgrave(bNodeTree * /*ntree*/, bNode *node)
{
NodeTexMusgrave *tex = MEM_cnew<NodeTexMusgrave>(__func__);
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
@@ -83,7 +85,7 @@ static const char *gpu_shader_name_get(const int type, const int dimensions)
static int node_shader_gpu_tex_musgrave(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -192,7 +194,7 @@ class MusgraveFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
auto get_vector = [&](int param_index) -> VArray<float3> {
return params.readonly_single_input<float3>(param_index, "Vector");
@@ -533,11 +535,11 @@ void register_node_type_sh_tex_musgrave()
ntype.declare = file_ns::sh_node_tex_musgrave_declare;
ntype.draw_buttons = file_ns::node_shader_buts_tex_musgrave;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, file_ns::node_shader_init_tex_musgrave);
+ ntype.initfunc = file_ns::node_shader_init_tex_musgrave;
node_type_storage(
&ntype, "NodeTexMusgrave", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_musgrave);
- node_type_update(&ntype, file_ns::node_shader_update_tex_musgrave);
+ ntype.gpu_fn = file_ns::node_shader_gpu_tex_musgrave;
+ ntype.updatefunc = file_ns::node_shader_update_tex_musgrave;
ntype.build_multi_function = file_ns::sh_node_musgrave_build_multi_function;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc b/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc
index 87fb1aeac29..d72e9c3c451 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc
@@ -15,7 +15,7 @@ NODE_STORAGE_FUNCS(NodeTexNoise)
static void sh_node_tex_noise_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>(N_("Vector")).implicit_field();
+ b.add_input<decl::Vector>(N_("Vector")).implicit_field(implicit_field_inputs::position);
b.add_input<decl::Float>(N_("W")).min(-1000.0f).max(1000.0f).make_available([](bNode &node) {
/* Default to 1 instead of 4, because it is much faster. */
node_storage(node).dimensions = 1;
@@ -32,12 +32,12 @@ static void sh_node_tex_noise_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Color")).no_muted_links();
}
-static void node_shader_buts_tex_noise(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_tex_noise(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "noise_dimensions", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
-static void node_shader_init_tex_noise(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_tex_noise(bNodeTree * /*ntree*/, bNode *node)
{
NodeTexNoise *tex = MEM_cnew<NodeTexNoise>(__func__);
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
@@ -59,7 +59,7 @@ static const char *gpu_shader_get_name(const int dimensions)
static int node_shader_gpu_tex_noise(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -120,7 +120,7 @@ class NoiseFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
int param = ELEM(dimensions_, 2, 3, 4) + ELEM(dimensions_, 1, 4);
const VArray<float> &scale = params.readonly_single_input<float>(param++, "Scale");
@@ -249,11 +249,11 @@ void register_node_type_sh_tex_noise()
sh_fn_node_type_base(&ntype, SH_NODE_TEX_NOISE, "Noise Texture", NODE_CLASS_TEXTURE);
ntype.declare = file_ns::sh_node_tex_noise_declare;
ntype.draw_buttons = file_ns::node_shader_buts_tex_noise;
- node_type_init(&ntype, file_ns::node_shader_init_tex_noise);
+ ntype.initfunc = file_ns::node_shader_init_tex_noise;
node_type_storage(
&ntype, "NodeTexNoise", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_noise);
- node_type_update(&ntype, file_ns::node_shader_update_tex_noise);
+ ntype.gpu_fn = file_ns::node_shader_gpu_tex_noise;
+ ntype.updatefunc = file_ns::node_shader_update_tex_noise;
ntype.build_multi_function = file_ns::sh_node_noise_build_multi_function;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_pointdensity.cc b/source/blender/nodes/shader/nodes/node_shader_tex_pointdensity.cc
index fcd1d4973ff..4005265e49a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_pointdensity.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_pointdensity.cc
@@ -17,9 +17,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Density"));
}
-static void node_shader_buts_tex_pointdensity(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_shader_buts_tex_pointdensity(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
NodeShaderTexPointDensity *shader_point_density = (NodeShaderTexPointDensity *)node->storage;
@@ -63,7 +61,7 @@ static void node_shader_buts_tex_pointdensity(uiLayout *layout,
}
}
-static void node_shader_init_tex_pointdensity(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_tex_pointdensity(bNodeTree * /*ntree*/, bNode *node)
{
NodeShaderTexPointDensity *point_density = MEM_new<NodeShaderTexPointDensity>("new pd node");
point_density->resolution = 100;
@@ -83,7 +81,7 @@ static void node_shader_free_tex_pointdensity(bNode *node)
MEM_freeN(point_density);
}
-static void node_shader_copy_tex_pointdensity(bNodeTree *UNUSED(dest_ntree),
+static void node_shader_copy_tex_pointdensity(bNodeTree * /*dst_ntree*/,
bNode *dest_node,
const bNode *src_node)
{
@@ -105,7 +103,7 @@ void register_node_type_sh_tex_pointdensity()
sh_node_type_base(&ntype, SH_NODE_TEX_POINTDENSITY, "Point Density", NODE_CLASS_TEXTURE);
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_tex_pointdensity;
- node_type_init(&ntype, file_ns::node_shader_init_tex_pointdensity);
+ ntype.initfunc = file_ns::node_shader_init_tex_pointdensity;
node_type_storage(&ntype,
"NodeShaderTexPointDensity",
file_ns::node_shader_free_tex_pointdensity,
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc b/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc
index f5a4d087dbd..faa0c0f0888 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc
@@ -4,6 +4,8 @@
#include "node_shader_util.hh"
#include "sky_model.h"
+#include "BLI_task.hh"
+
#include "BKE_context.h"
#include "BKE_scene.h"
@@ -36,7 +38,7 @@ static void node_shader_buts_tex_sky(uiLayout *layout, bContext *C, PointerRNA *
if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_NISHITA) {
Scene *scene = CTX_data_scene(C);
if (BKE_scene_uses_blender_eevee(scene)) {
- uiItemL(layout, TIP_("Nishita not available in Eevee"), ICON_ERROR);
+ uiItemL(layout, TIP_("Sun disc not available in Eevee"), ICON_ERROR);
}
uiItemR(layout, ptr, "sun_disc", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, 0);
@@ -60,7 +62,7 @@ static void node_shader_buts_tex_sky(uiLayout *layout, bContext *C, PointerRNA *
}
}
-static void node_shader_init_tex_sky(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_tex_sky(bNodeTree * /*ntree*/, bNode *node)
{
NodeTexSky *tex = MEM_cnew<NodeTexSky>("NodeTexSky");
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
@@ -144,7 +146,7 @@ static void sky_precompute_old(SkyModelPreetham *sunsky, const float sun_angles[
static int node_shader_gpu_tex_sky(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -179,7 +181,7 @@ static int node_shader_gpu_tex_sky(GPUMaterial *mat,
GPU_uniform(xyz_to_rgb.g),
GPU_uniform(xyz_to_rgb.b));
}
- if (tex->sky_model == 1) {
+ else if (tex->sky_model == 1) {
/* Hosek / Wilkie */
sun_angles[0] = fmin(M_PI_2, sun_angles[0]); /* clamp to horizon */
SKY_ArHosekSkyModelState *sky_state = SKY_arhosek_xyz_skymodelstate_alloc_init(
@@ -187,12 +189,12 @@ static int node_shader_gpu_tex_sky(GPUMaterial *mat,
/* Pass sky_state->configs[3][9] as 3*(vec4+vec4)+vec3 */
float config_x07[8], config_y07[8], config_z07[8], config_xyz8[3];
for (int i = 0; i < 8; ++i) {
- config_x07[i] = (float)sky_state->configs[0][i];
- config_y07[i] = (float)sky_state->configs[1][i];
- config_z07[i] = (float)sky_state->configs[2][i];
+ config_x07[i] = float(sky_state->configs[0][i]);
+ config_y07[i] = float(sky_state->configs[1][i]);
+ config_z07[i] = float(sky_state->configs[2][i]);
}
for (int i = 0; i < 3; ++i) {
- config_xyz8[i] = (float)sky_state->configs[i][8];
+ config_xyz8[i] = float(sky_state->configs[i][8]);
}
float radiance[3];
for (int i = 0; i < 3; i++) {
@@ -219,8 +221,52 @@ static int node_shader_gpu_tex_sky(GPUMaterial *mat,
GPU_uniform(xyz_to_rgb.g),
GPU_uniform(xyz_to_rgb.b));
}
+ else {
+ /* Nishita */
+
+ Array<float> pixels(4 * GPU_SKY_WIDTH * GPU_SKY_HEIGHT);
+
+ threading::parallel_for(IndexRange(GPU_SKY_HEIGHT), 2, [&](IndexRange range) {
+ SKY_nishita_skymodel_precompute_texture(pixels.data(),
+ 4,
+ range.first(),
+ range.one_after_last(),
+ GPU_SKY_WIDTH,
+ GPU_SKY_HEIGHT,
+ tex->sun_elevation,
+ tex->altitude,
+ tex->air_density,
+ tex->dust_density,
+ tex->ozone_density);
+ });
+
+ float sun_rotation = fmodf(tex->sun_rotation, 2.0f * M_PI);
+ if (sun_rotation < 0.0f) {
+ sun_rotation += 2.0f * M_PI;
+ }
+ sun_rotation = 2.0f * M_PI - sun_rotation;
+
+ XYZ_to_RGB xyz_to_rgb;
+ get_XYZ_to_RGB_for_gpu(&xyz_to_rgb);
- return GPU_stack_link(mat, node, "node_tex_sky_nishita", in, out);
+ eGPUSamplerState sampler = GPU_SAMPLER_REPEAT | GPU_SAMPLER_FILTER;
+ /* To fix pole issue we clamp the v coordinate. */
+ sampler &= ~GPU_SAMPLER_REPEAT_T;
+ float layer;
+ GPUNodeLink *sky_texture = GPU_image_sky(
+ mat, GPU_SKY_WIDTH, GPU_SKY_HEIGHT, pixels.data(), &layer, sampler);
+ return GPU_stack_link(mat,
+ node,
+ "node_tex_sky_nishita",
+ in,
+ out,
+ GPU_constant(&sun_rotation),
+ GPU_uniform(xyz_to_rgb.r),
+ GPU_uniform(xyz_to_rgb.g),
+ GPU_uniform(xyz_to_rgb.b),
+ sky_texture,
+ GPU_constant(&layer));
+ }
}
static void node_shader_update_sky(bNodeTree *ntree, bNode *node)
@@ -262,11 +308,11 @@ void register_node_type_sh_tex_sky()
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_tex_sky;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, file_ns::node_shader_init_tex_sky);
+ ntype.initfunc = file_ns::node_shader_init_tex_sky;
node_type_storage(&ntype, "NodeTexSky", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_sky);
+ ntype.gpu_fn = file_ns::node_shader_gpu_tex_sky;
/* Remove vector input for Nishita sky model. */
- node_type_update(&ntype, file_ns::node_shader_update_sky);
+ ntype.updatefunc = file_ns::node_shader_update_sky;
ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc
index fc6a5ef72b6..f07ef1b6c60 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc
@@ -15,7 +15,9 @@ NODE_STORAGE_FUNCS(NodeTexVoronoi)
static void sh_node_tex_voronoi_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>(N_("Vector")).hide_value().implicit_field();
+ b.add_input<decl::Vector>(N_("Vector"))
+ .hide_value()
+ .implicit_field(implicit_field_inputs::position);
b.add_input<decl::Float>(N_("W")).min(-1000.0f).max(1000.0f).make_available([](bNode &node) {
/* Default to 1 instead of 4, because it is much faster. */
node_storage(node).dimensions = 1;
@@ -49,7 +51,7 @@ static void sh_node_tex_voronoi_declare(NodeDeclarationBuilder &b)
});
}
-static void node_shader_buts_tex_voronoi(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_tex_voronoi(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "voronoi_dimensions", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
uiItemR(layout, ptr, "feature", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
@@ -60,7 +62,7 @@ static void node_shader_buts_tex_voronoi(uiLayout *layout, bContext *UNUSED(C),
}
}
-static void node_shader_init_tex_voronoi(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_tex_voronoi(bNodeTree * /*ntree*/, bNode *node)
{
NodeTexVoronoi *tex = MEM_cnew<NodeTexVoronoi>(__func__);
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
@@ -119,7 +121,7 @@ static const char *gpu_shader_get_name(const int feature, const int dimensions)
static int node_shader_gpu_tex_voronoi(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -173,7 +175,7 @@ static void node_shader_update_tex_voronoi(bNodeTree *ntree, bNode *node)
outWSock,
storage.feature != SHD_VORONOI_DISTANCE_TO_EDGE &&
storage.feature != SHD_VORONOI_N_SPHERE_RADIUS &&
- (ELEM(storage.dimensions, 1, 4)));
+ ELEM(storage.dimensions, 1, 4));
nodeSetSocketAvailability(ntree, outRadiusSock, storage.feature == SHD_VORONOI_N_SPHERE_RADIUS);
}
@@ -234,7 +236,7 @@ class VoronoiMinowskiFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
auto get_vector = [&](int param_index) -> VArray<float3> {
return params.readonly_single_input<float3>(param_index, "Vector");
@@ -670,7 +672,7 @@ class VoronoiMetricFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
auto get_vector = [&](int param_index) -> VArray<float3> {
return params.readonly_single_input<float3>(param_index, "Vector");
@@ -1177,7 +1179,7 @@ class VoronoiEdgeFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
auto get_vector = [&](int param_index) -> VArray<float3> {
return params.readonly_single_input<float3>(param_index, "Vector");
@@ -1345,11 +1347,11 @@ void register_node_type_sh_tex_voronoi()
sh_fn_node_type_base(&ntype, SH_NODE_TEX_VORONOI, "Voronoi Texture", NODE_CLASS_TEXTURE);
ntype.declare = file_ns::sh_node_tex_voronoi_declare;
ntype.draw_buttons = file_ns::node_shader_buts_tex_voronoi;
- node_type_init(&ntype, file_ns::node_shader_init_tex_voronoi);
+ ntype.initfunc = file_ns::node_shader_init_tex_voronoi;
node_type_storage(
&ntype, "NodeTexVoronoi", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_voronoi);
- node_type_update(&ntype, file_ns::node_shader_update_tex_voronoi);
+ ntype.gpu_fn = file_ns::node_shader_gpu_tex_voronoi;
+ ntype.updatefunc = file_ns::node_shader_update_tex_voronoi;
ntype.build_multi_function = file_ns::sh_node_voronoi_build_multi_function;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc
index 8475101dbaf..f4effe28815 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc
@@ -13,7 +13,7 @@ namespace blender::nodes::node_shader_tex_wave_cc {
static void sh_node_tex_wave_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>(N_("Vector")).implicit_field();
+ b.add_input<decl::Vector>(N_("Vector")).implicit_field(implicit_field_inputs::position);
b.add_input<decl::Float>(N_("Scale")).min(-1000.0f).max(1000.0f).default_value(5.0f);
b.add_input<decl::Float>(N_("Distortion")).min(-1000.0f).max(1000.0f).default_value(0.0f);
b.add_input<decl::Float>(N_("Detail")).min(0.0f).max(15.0f).default_value(2.0f);
@@ -28,7 +28,7 @@ static void sh_node_tex_wave_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Fac")).no_muted_links();
}
-static void node_shader_buts_tex_wave(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_tex_wave(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "wave_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
int type = RNA_enum_get(ptr, "wave_type");
@@ -42,7 +42,7 @@ static void node_shader_buts_tex_wave(uiLayout *layout, bContext *UNUSED(C), Poi
uiItemR(layout, ptr, "wave_profile", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
-static void node_shader_init_tex_wave(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_tex_wave(bNodeTree * /*ntree*/, bNode *node)
{
NodeTexWave *tex = MEM_cnew<NodeTexWave>(__func__);
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
@@ -56,7 +56,7 @@ static void node_shader_init_tex_wave(bNodeTree *UNUSED(ntree), bNode *node)
static int node_shader_gpu_tex_wave(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -113,7 +113,7 @@ class WaveFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
const VArray<float> &scale = params.readonly_single_input<float>(1, "Scale");
@@ -224,9 +224,9 @@ void register_node_type_sh_tex_wave()
ntype.declare = file_ns::sh_node_tex_wave_declare;
ntype.draw_buttons = file_ns::node_shader_buts_tex_wave;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, file_ns::node_shader_init_tex_wave);
+ ntype.initfunc = file_ns::node_shader_init_tex_wave;
node_type_storage(&ntype, "NodeTexWave", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_wave);
+ ntype.gpu_fn = file_ns::node_shader_gpu_tex_wave;
ntype.build_multi_function = file_ns::sh_node_wave_tex_build_multi_function;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc
index 64075a903ab..58787a9afa3 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc
@@ -13,7 +13,10 @@ namespace blender::nodes::node_shader_tex_white_noise_cc {
static void sh_node_tex_white_noise_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>(N_("Vector")).min(-10000.0f).max(10000.0f).implicit_field();
+ b.add_input<decl::Vector>(N_("Vector"))
+ .min(-10000.0f)
+ .max(10000.0f)
+ .implicit_field(implicit_field_inputs::position);
b.add_input<decl::Float>(N_("W")).min(-10000.0f).max(10000.0f).make_available([](bNode &node) {
/* Default to 1 instead of 4, because it is faster. */
node.custom1 = 1;
@@ -22,12 +25,12 @@ static void sh_node_tex_white_noise_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Color"));
}
-static void node_shader_buts_white_noise(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_white_noise(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "noise_dimensions", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
-static void node_shader_init_tex_white_noise(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_tex_white_noise(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = 3;
}
@@ -43,7 +46,7 @@ static const char *gpu_shader_get_name(const int dimensions)
static int gpu_shader_tex_white_noise(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -94,7 +97,7 @@ class WhiteNoiseFunction : public fn::MultiFunction {
return signature.build();
}
- void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
int param = ELEM(dimensions_, 2, 3, 4) + ELEM(dimensions_, 1, 4);
@@ -177,7 +180,7 @@ class WhiteNoiseFunction : public fn::MultiFunction {
static void sh_node_noise_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const bNode &node = builder.node();
- builder.construct_and_set_matching_fn<WhiteNoiseFunction>((int)node.custom1);
+ builder.construct_and_set_matching_fn<WhiteNoiseFunction>(int(node.custom1));
}
} // namespace blender::nodes::node_shader_tex_white_noise_cc
@@ -191,9 +194,9 @@ void register_node_type_sh_tex_white_noise()
sh_fn_node_type_base(&ntype, SH_NODE_TEX_WHITE_NOISE, "White Noise Texture", NODE_CLASS_TEXTURE);
ntype.declare = file_ns::sh_node_tex_white_noise_declare;
ntype.draw_buttons = file_ns::node_shader_buts_white_noise;
- node_type_init(&ntype, file_ns::node_shader_init_tex_white_noise);
- node_type_gpu(&ntype, file_ns::gpu_shader_tex_white_noise);
- node_type_update(&ntype, file_ns::node_shader_update_tex_white_noise);
+ ntype.initfunc = file_ns::node_shader_init_tex_white_noise;
+ ntype.gpu_fn = file_ns::gpu_shader_tex_white_noise;
+ ntype.updatefunc = file_ns::node_shader_update_tex_white_noise;
ntype.build_multi_function = file_ns::sh_node_noise_build_multi_function;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_uv_along_stroke.cc b/source/blender/nodes/shader/nodes/node_shader_uv_along_stroke.cc
index fa98cb3aa27..6923d51ab51 100644
--- a/source/blender/nodes/shader/nodes/node_shader_uv_along_stroke.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_uv_along_stroke.cc
@@ -13,7 +13,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("UV"));
}
-static void node_shader_buts_uvalongstroke(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_uvalongstroke(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "use_tips", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, 0);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_uvmap.cc b/source/blender/nodes/shader/nodes/node_shader_uvmap.cc
index 53228f0a314..483e06f1192 100644
--- a/source/blender/nodes/shader/nodes/node_shader_uvmap.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_uvmap.cc
@@ -31,7 +31,7 @@ static void node_shader_buts_uvmap(uiLayout *layout, bContext *C, PointerRNA *pt
}
}
-static void node_shader_init_uvmap(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_uvmap(bNodeTree * /*ntree*/, bNode *node)
{
NodeShaderUVMap *attr = MEM_cnew<NodeShaderUVMap>("NodeShaderUVMap");
node->storage = attr;
@@ -39,7 +39,7 @@ static void node_shader_init_uvmap(bNodeTree *UNUSED(ntree), bNode *node)
static int node_shader_gpu_uvmap(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -70,10 +70,10 @@ void register_node_type_sh_uvmap()
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_uvmap;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, file_ns::node_shader_init_uvmap);
+ ntype.initfunc = file_ns::node_shader_init_uvmap;
node_type_storage(
&ntype, "NodeShaderUVMap", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_uvmap);
+ ntype.gpu_fn = file_ns::node_shader_gpu_uvmap;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_value.cc b/source/blender/nodes/shader/nodes/node_shader_value.cc
index 14dbb3b25eb..c190438c417 100644
--- a/source/blender/nodes/shader/nodes/node_shader_value.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_value.cc
@@ -16,7 +16,7 @@ static void sh_node_value_declare(NodeDeclarationBuilder &b)
static int gpu_shader_value(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack * /*in*/,
GPUNodeStack *out)
{
@@ -42,7 +42,7 @@ void register_node_type_sh_value()
sh_fn_node_type_base(&ntype, SH_NODE_VALUE, "Value", NODE_CLASS_INPUT);
ntype.declare = file_ns::sh_node_value_declare;
- node_type_gpu(&ntype, file_ns::gpu_shader_value);
+ ntype.gpu_fn = file_ns::gpu_shader_value;
ntype.build_multi_function = file_ns::sh_node_value_build_multi_function;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_displacement.cc b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.cc
index 9996e91177a..c9e4f9c8e14 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_displacement.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.cc
@@ -13,14 +13,14 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Displacement"));
}
-static void node_shader_init_vector_displacement(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_vector_displacement(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = SHD_SPACE_TANGENT; /* space */
}
static int gpu_shader_vector_displacement(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -52,8 +52,8 @@ void register_node_type_sh_vector_displacement()
sh_node_type_base(
&ntype, SH_NODE_VECTOR_DISPLACEMENT, "Vector Displacement", NODE_CLASS_OP_VECTOR);
ntype.declare = file_ns::node_declare;
- node_type_init(&ntype, file_ns::node_shader_init_vector_displacement);
- node_type_gpu(&ntype, file_ns::gpu_shader_vector_displacement);
+ ntype.initfunc = file_ns::node_shader_init_vector_displacement;
+ ntype.gpu_fn = file_ns::gpu_shader_vector_displacement;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc
index d01e03f9d71..f7cf70aa8e1 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc
@@ -28,7 +28,7 @@ static void sh_node_vector_math_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Value"));
}
-static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_vect_math(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "operation", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
@@ -141,7 +141,7 @@ static const char *gpu_shader_get_name(int mode)
static int gpu_shader_vector_math(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -322,8 +322,8 @@ void register_node_type_sh_vect_math()
ntype.declare = file_ns::sh_node_vector_math_declare;
ntype.draw_buttons = file_ns::node_shader_buts_vect_math;
ntype.labelfunc = node_vector_math_label;
- node_type_gpu(&ntype, file_ns::gpu_shader_vector_math);
- node_type_update(&ntype, file_ns::node_shader_update_vector_math);
+ ntype.gpu_fn = file_ns::gpu_shader_vector_math;
+ ntype.updatefunc = file_ns::node_shader_update_vector_math;
ntype.build_multi_function = file_ns::sh_node_vector_math_build_multi_function;
ntype.gather_link_search_ops = file_ns::sh_node_vector_math_gather_link_searches;
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc
index a036fc52d84..bdf7360873d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc
@@ -29,7 +29,7 @@ static void sh_node_vector_rotate_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Vector"));
}
-static void node_shader_buts_vector_rotate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_vector_rotate(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "rotation_type", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
uiItemR(layout, ptr, "invert", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, 0);
@@ -55,7 +55,7 @@ static const char *gpu_shader_get_name(int mode)
static int gpu_shader_vector_rotate(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -212,8 +212,8 @@ void register_node_type_sh_vector_rotate()
sh_fn_node_type_base(&ntype, SH_NODE_VECTOR_ROTATE, "Vector Rotate", NODE_CLASS_OP_VECTOR);
ntype.declare = file_ns::sh_node_vector_rotate_declare;
ntype.draw_buttons = file_ns::node_shader_buts_vector_rotate;
- node_type_gpu(&ntype, file_ns::gpu_shader_vector_rotate);
- node_type_update(&ntype, file_ns::node_shader_update_vector_rotate);
+ ntype.gpu_fn = file_ns::gpu_shader_vector_rotate;
+ ntype.updatefunc = file_ns::node_shader_update_vector_rotate;
ntype.build_multi_function = file_ns::sh_node_vector_rotate_build_multi_function;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_transform.cc b/source/blender/nodes/shader/nodes/node_shader_vector_transform.cc
index 159bd238212..03fb954f088 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_transform.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_transform.cc
@@ -21,7 +21,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Vector"));
}
-static void node_shader_buts_vect_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_vect_transform(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout,
ptr,
@@ -33,7 +33,7 @@ static void node_shader_buts_vect_transform(uiLayout *layout, bContext *UNUSED(C
uiItemR(layout, ptr, "convert_to", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
-static void node_shader_init_vect_transform(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_vect_transform(bNodeTree * /*ntree*/, bNode *node)
{
NodeShaderVectTransform *vect = MEM_cnew<NodeShaderVectTransform>("NodeShaderVectTransform");
@@ -88,7 +88,7 @@ static const char *get_gpufn_name_from_to(short from, short to, bool is_directio
static int gpu_shader_vect_transform(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -144,10 +144,10 @@ void register_node_type_sh_vect_transform()
sh_node_type_base(&ntype, SH_NODE_VECT_TRANSFORM, "Vector Transform", NODE_CLASS_OP_VECTOR);
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_vect_transform;
- node_type_init(&ntype, file_ns::node_shader_init_vect_transform);
+ ntype.initfunc = file_ns::node_shader_init_vect_transform;
node_type_storage(
&ntype, "NodeShaderVectTransform", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::gpu_shader_vect_transform);
+ ntype.gpu_fn = file_ns::gpu_shader_vect_transform;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc
index c636cc976e6..8f7e30b99df 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc
@@ -29,7 +29,7 @@ static void node_shader_buts_vertex_color(uiLayout *layout, bContext *C, Pointer
}
}
-static void node_shader_init_vertex_color(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_vertex_color(bNodeTree * /*ntree*/, bNode *node)
{
NodeShaderVertexColor *vertexColor = MEM_cnew<NodeShaderVertexColor>("NodeShaderVertexColor");
node->storage = vertexColor;
@@ -37,7 +37,7 @@ static void node_shader_init_vertex_color(bNodeTree *UNUSED(ntree), bNode *node)
static int node_shader_gpu_vertex_color(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -69,10 +69,10 @@ void register_node_type_sh_vertex_color()
sh_node_type_base(&ntype, SH_NODE_VERTEX_COLOR, "Color Attribute", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_vertex_color;
- node_type_init(&ntype, file_ns::node_shader_init_vertex_color);
+ ntype.initfunc = file_ns::node_shader_init_vertex_color;
node_type_storage(
&ntype, "NodeShaderVertexColor", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_vertex_color);
+ ntype.gpu_fn = file_ns::node_shader_gpu_vertex_color;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_absorption.cc b/source/blender/nodes/shader/nodes/node_shader_volume_absorption.cc
index 930fa6e5fb9..e50331585e3 100644
--- a/source/blender/nodes/shader/nodes/node_shader_volume_absorption.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_volume_absorption.cc
@@ -15,7 +15,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_volume_absorption(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -33,7 +33,7 @@ void register_node_type_sh_volume_absorption()
sh_node_type_base(&ntype, SH_NODE_VOLUME_ABSORPTION, "Volume Absorption", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_volume_absorption);
+ ntype.gpu_fn = file_ns::node_shader_gpu_volume_absorption;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_info.cc b/source/blender/nodes/shader/nodes/node_shader_volume_info.cc
index 1f31e9c605f..6a1bc070f68 100644
--- a/source/blender/nodes/shader/nodes/node_shader_volume_info.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_volume_info.cc
@@ -14,9 +14,9 @@ static void node_declare(NodeDeclarationBuilder &b)
}
static int node_shader_gpu_volume_info(GPUMaterial *mat,
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *UNUSED(in),
+ bNode * /*node*/,
+ bNodeExecData * /*execdata*/,
+ GPUNodeStack * /*in*/,
GPUNodeStack *out)
{
if (out[0].hasoutput) {
@@ -49,7 +49,7 @@ void register_node_type_sh_volume_info()
sh_node_type_base(&ntype, SH_NODE_VOLUME_INFO, "Volume Info", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_volume_info);
+ ntype.gpu_fn = file_ns::node_shader_gpu_volume_info;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_principled.cc b/source/blender/nodes/shader/nodes/node_shader_volume_principled.cc
index 4c4122a905f..4ff57042fe4 100644
--- a/source/blender/nodes/shader/nodes/node_shader_volume_principled.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_volume_principled.cc
@@ -33,7 +33,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Shader>(N_("Volume"));
}
-static void node_shader_init_volume_principled(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_init_volume_principled(bNodeTree * /*ntree*/, bNode *node)
{
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
if (STREQ(sock->name, "Density Attribute")) {
@@ -59,7 +59,7 @@ static void attribute_post_process(GPUMaterial *mat,
static int node_shader_gpu_volume_principled(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -142,8 +142,8 @@ void register_node_type_sh_volume_principled()
sh_node_type_base(&ntype, SH_NODE_VOLUME_PRINCIPLED, "Principled Volume", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- node_type_init(&ntype, file_ns::node_shader_init_volume_principled);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_volume_principled);
+ ntype.initfunc = file_ns::node_shader_init_volume_principled;
+ ntype.gpu_fn = file_ns::node_shader_gpu_volume_principled;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_scatter.cc b/source/blender/nodes/shader/nodes/node_shader_volume_scatter.cc
index 0c6859ad1fb..b87792eef2e 100644
--- a/source/blender/nodes/shader/nodes/node_shader_volume_scatter.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_volume_scatter.cc
@@ -20,7 +20,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_volume_scatter(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -38,7 +38,7 @@ void register_node_type_sh_volume_scatter()
sh_node_type_base(&ntype, SH_NODE_VOLUME_SCATTER, "Volume Scatter", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_volume_scatter);
+ ntype.gpu_fn = file_ns::node_shader_gpu_volume_scatter;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_wavelength.cc b/source/blender/nodes/shader/nodes/node_shader_wavelength.cc
index 34fa639dd07..6fa495c3ead 100644
--- a/source/blender/nodes/shader/nodes/node_shader_wavelength.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_wavelength.cc
@@ -15,7 +15,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_wavelength(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -41,7 +41,7 @@ void register_node_type_sh_wavelength()
sh_node_type_base(&ntype, SH_NODE_WAVELENGTH, "Wavelength", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_gpu(&ntype, file_ns::node_shader_gpu_wavelength);
+ ntype.gpu_fn = file_ns::node_shader_gpu_wavelength;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_wireframe.cc b/source/blender/nodes/shader/nodes/node_shader_wireframe.cc
index 6a1acda3353..b125e7221a6 100644
--- a/source/blender/nodes/shader/nodes/node_shader_wireframe.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_wireframe.cc
@@ -14,14 +14,14 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Fac"));
}
-static void node_shader_buts_wireframe(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_wireframe(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "use_pixel_size", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, 0);
}
static int node_shader_gpu_wireframe(GPUMaterial *mat,
bNode *node,
- bNodeExecData *UNUSED(execdata),
+ bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
@@ -47,7 +47,7 @@ void register_node_type_sh_wireframe()
sh_node_type_base(&ntype, SH_NODE_WIREFRAME, "Wireframe", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_shader_buts_wireframe;
- node_type_gpu(&ntype, file_ns::node_shader_gpu_wireframe);
+ ntype.gpu_fn = file_ns::node_shader_gpu_wireframe;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/CMakeLists.txt b/source/blender/nodes/texture/CMakeLists.txt
index 2ccdf4c0bc9..2d704ac2228 100644
--- a/source/blender/nodes/texture/CMakeLists.txt
+++ b/source/blender/nodes/texture/CMakeLists.txt
@@ -2,7 +2,7 @@
set(INC
.
- ../
+ ..
../intern
../../editors/include
../../blenkernel
@@ -57,21 +57,6 @@ set(LIB
bf_nodes
)
-if(WITH_PYTHON)
- list(APPEND INC
- ../../python
- )
- list(APPEND INC_SYS
- ${PYTHON_INCLUDE_DIRS}
- )
- list(APPEND LIB
- ${PYTHON_LINKFLAGS}
- ${PYTHON_LIBRARIES}
- )
- add_definitions(-DWITH_PYTHON)
-endif()
-
-
blender_add_lib(bf_nodes_texture "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
# RNA_prototypes.h
diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c
index 3f8ff85306d..99146f1a25c 100644
--- a/source/blender/nodes/texture/node_texture_tree.c
+++ b/source/blender/nodes/texture/node_texture_tree.c
@@ -47,6 +47,7 @@ static void texture_get_from_context(const bContext *C,
SpaceNode *snode = CTX_wm_space_node(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
Tex *tx = NULL;
@@ -250,7 +251,7 @@ bNodeTreeExec *ntreeTexBeginExecTree(bNodeTree *ntree)
exec = ntreeTexBeginExecTree_internal(&context, ntree, NODE_INSTANCE_KEY_BASE);
- /* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
+ /* XXX this should not be necessary, but is still used for compositor/shading/texture nodes,
* which only store the ntree pointer. Should be fixed at some point!
*/
ntree->execdata = exec;
@@ -307,7 +308,8 @@ void ntreeTexEndExecTree(bNodeTreeExec *exec)
bNodeTree *ntree = exec->nodetree;
ntreeTexEndExecTree_internal(exec);
- /* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
+ /* XXX: clear node-tree back-pointer to exec data,
+ * same problem as noted in #ntreeBeginExecTree. */
ntree->execdata = NULL;
}
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_at.c b/source/blender/nodes/texture/nodes/node_texture_at.c
index 74f279d65c7..e2e635b7d92 100644
--- a/source/blender/nodes/texture/nodes/node_texture_at.c
+++ b/source/blender/nodes/texture/nodes/node_texture_at.c
@@ -45,7 +45,7 @@ void register_node_type_tex_at(void)
tex_node_type_base(&ntype, TEX_NODE_AT, "At", NODE_CLASS_DISTORT);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_size(&ntype, 140, 100, 320);
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.exec_fn = exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_bricks.c b/source/blender/nodes/texture/nodes/node_texture_bricks.c
index bfd43560c2d..b68bf4fcb8d 100644
--- a/source/blender/nodes/texture/nodes/node_texture_bricks.c
+++ b/source/blender/nodes/texture/nodes/node_texture_bricks.c
@@ -106,8 +106,8 @@ void register_node_type_tex_bricks(void)
tex_node_type_base(&ntype, TEX_NODE_BRICKS, "Bricks", NODE_CLASS_PATTERN);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, init);
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.initfunc = init;
+ ntype.exec_fn = exec;
ntype.flag |= NODE_PREVIEW;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/texture/nodes/node_texture_checker.c b/source/blender/nodes/texture/nodes/node_texture_checker.c
index 08f87cb7875..d66eb7e6953 100644
--- a/source/blender/nodes/texture/nodes/node_texture_checker.c
+++ b/source/blender/nodes/texture/nodes/node_texture_checker.c
@@ -56,7 +56,7 @@ void register_node_type_tex_checker(void)
tex_node_type_base(&ntype, TEX_NODE_CHECKER, "Checker", NODE_CLASS_PATTERN);
node_type_socket_templates(&ntype, inputs, outputs);
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.exec_fn = exec;
ntype.flag |= NODE_PREVIEW;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/texture/nodes/node_texture_combine_color.c b/source/blender/nodes/texture/nodes/node_texture_combine_color.c
index 459553bc950..e6a8080bb48 100644
--- a/source/blender/nodes/texture/nodes/node_texture_combine_color.c
+++ b/source/blender/nodes/texture/nodes/node_texture_combine_color.c
@@ -69,8 +69,8 @@ void register_node_type_tex_combine_color(void)
tex_node_type_base(&ntype, TEX_NODE_COMBINE_COLOR, "Combine Color", NODE_CLASS_OP_COLOR);
node_type_socket_templates(&ntype, inputs, outputs);
- node_type_exec(&ntype, NULL, NULL, exec);
- node_type_update(&ntype, update);
+ ntype.exec_fn = exec;
+ ntype.updatefunc = update;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_common.c b/source/blender/nodes/texture/nodes/node_texture_common.c
index 96345b00a82..8ff4ad61387 100644
--- a/source/blender/nodes/texture/nodes/node_texture_common.c
+++ b/source/blender/nodes/texture/nodes/node_texture_common.c
@@ -155,8 +155,10 @@ void register_node_type_tex_group(void)
node_type_size(&ntype, 140, 60, 400);
ntype.labelfunc = node_group_label;
- node_type_group_update(&ntype, node_group_update);
- node_type_exec(&ntype, group_initexec, group_freeexec, group_execute);
+ ntype.group_update_func = node_group_update;
+ ntype.init_exec_fn = group_initexec;
+ ntype.free_exec_fn = group_freeexec;
+ ntype.exec_fn = group_execute;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_compose.c b/source/blender/nodes/texture/nodes/node_texture_compose.c
index ef14062c72d..d41566be74c 100644
--- a/source/blender/nodes/texture/nodes/node_texture_compose.c
+++ b/source/blender/nodes/texture/nodes/node_texture_compose.c
@@ -42,9 +42,10 @@ void register_node_type_tex_compose(void)
{
static bNodeType ntype;
- tex_node_type_base(&ntype, TEX_NODE_COMPOSE_LEGACY, "Combine RGBA", NODE_CLASS_OP_COLOR);
+ tex_node_type_base(
+ &ntype, TEX_NODE_COMPOSE_LEGACY, "Combine RGBA (Legacy)", NODE_CLASS_OP_COLOR);
node_type_socket_templates(&ntype, inputs, outputs);
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.exec_fn = exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_coord.c b/source/blender/nodes/texture/nodes/node_texture_coord.c
index e74dfd378d9..1babea310f4 100644
--- a/source/blender/nodes/texture/nodes/node_texture_coord.c
+++ b/source/blender/nodes/texture/nodes/node_texture_coord.c
@@ -35,7 +35,7 @@ void register_node_type_tex_coord(void)
tex_node_type_base(&ntype, TEX_NODE_COORD, "Coordinates", NODE_CLASS_INPUT);
node_type_socket_templates(&ntype, NULL, outputs);
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.exec_fn = exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_curves.c b/source/blender/nodes/texture/nodes/node_texture_curves.c
index dee4531746f..bdee2adb1ba 100644
--- a/source/blender/nodes/texture/nodes/node_texture_curves.c
+++ b/source/blender/nodes/texture/nodes/node_texture_curves.c
@@ -52,9 +52,10 @@ void register_node_type_tex_curve_time(void)
tex_node_type_base(&ntype, TEX_NODE_CURVE_TIME, "Time", NODE_CLASS_INPUT);
node_type_socket_templates(&ntype, NULL, time_outputs);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- node_type_init(&ntype, time_init);
+ ntype.initfunc = time_init;
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
- node_type_exec(&ntype, node_initexec_curves, NULL, time_exec);
+ ntype.init_exec_fn = node_initexec_curves;
+ ntype.exec_fn = time_exec;
nodeRegisterType(&ntype);
}
@@ -101,9 +102,10 @@ void register_node_type_tex_curve_rgb(void)
tex_node_type_base(&ntype, TEX_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR);
node_type_socket_templates(&ntype, rgb_inputs, rgb_outputs);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- node_type_init(&ntype, rgb_init);
+ ntype.initfunc = rgb_init;
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
- node_type_exec(&ntype, node_initexec_curves, NULL, rgb_exec);
+ ntype.init_exec_fn = node_initexec_curves;
+ ntype.exec_fn = rgb_exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_decompose.c b/source/blender/nodes/texture/nodes/node_texture_decompose.c
index 2d42fa4602e..ae7e80a6aab 100644
--- a/source/blender/nodes/texture/nodes/node_texture_decompose.c
+++ b/source/blender/nodes/texture/nodes/node_texture_decompose.c
@@ -64,7 +64,7 @@ void register_node_type_tex_decompose(void)
tex_node_type_base(&ntype, TEX_NODE_DECOMPOSE_LEGACY, "Separate RGBA", NODE_CLASS_OP_COLOR);
node_type_socket_templates(&ntype, inputs, outputs);
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.exec_fn = 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 e236b6743a6..19918a9896e 100644
--- a/source/blender/nodes/texture/nodes/node_texture_distance.c
+++ b/source/blender/nodes/texture/nodes/node_texture_distance.c
@@ -46,7 +46,7 @@ void register_node_type_tex_distance(void)
tex_node_type_base(&ntype, TEX_NODE_DISTANCE, "Distance", NODE_CLASS_CONVERTER);
node_type_socket_templates(&ntype, inputs, outputs);
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.exec_fn = exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_hueSatVal.c b/source/blender/nodes/texture/nodes/node_texture_hueSatVal.c
index 989d94953f7..454b58f4665 100644
--- a/source/blender/nodes/texture/nodes/node_texture_hueSatVal.c
+++ b/source/blender/nodes/texture/nodes/node_texture_hueSatVal.c
@@ -94,7 +94,7 @@ void register_node_type_tex_hue_sat(void)
tex_node_type_base(&ntype, TEX_NODE_HUE_SAT, "Hue Saturation Value", NODE_CLASS_OP_COLOR);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.exec_fn = 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 e94c78b41ea..8b859421762 100644
--- a/source/blender/nodes/texture/nodes/node_texture_image.c
+++ b/source/blender/nodes/texture/nodes/node_texture_image.c
@@ -94,9 +94,9 @@ void register_node_type_tex_image(void)
tex_node_type_base(&ntype, TEX_NODE_IMAGE, "Image", NODE_CLASS_INPUT);
node_type_socket_templates(&ntype, NULL, outputs);
- node_type_init(&ntype, init);
+ ntype.initfunc = init;
node_type_storage(&ntype, "ImageUser", node_free_standard_storage, node_copy_standard_storage);
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.exec_fn = exec;
ntype.labelfunc = node_image_label;
ntype.flag |= NODE_PREVIEW;
diff --git a/source/blender/nodes/texture/nodes/node_texture_invert.c b/source/blender/nodes/texture/nodes/node_texture_invert.c
index 6343f5f2caa..526d47bef9c 100644
--- a/source/blender/nodes/texture/nodes/node_texture_invert.c
+++ b/source/blender/nodes/texture/nodes/node_texture_invert.c
@@ -49,7 +49,7 @@ void register_node_type_tex_invert(void)
tex_node_type_base(&ntype, TEX_NODE_INVERT, "Invert", NODE_CLASS_OP_COLOR);
node_type_socket_templates(&ntype, inputs, outputs);
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.exec_fn = exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_math.c b/source/blender/nodes/texture/nodes/node_texture_math.c
index 5867d6b91e1..505ba51b4d8 100644
--- a/source/blender/nodes/texture/nodes/node_texture_math.c
+++ b/source/blender/nodes/texture/nodes/node_texture_math.c
@@ -322,8 +322,8 @@ void register_node_type_tex_math(void)
tex_node_type_base(&ntype, TEX_NODE_MATH, "Math", NODE_CLASS_CONVERTER);
node_type_socket_templates(&ntype, inputs, outputs);
ntype.labelfunc = node_math_label;
- node_type_exec(&ntype, NULL, NULL, exec);
- node_type_update(&ntype, node_math_update);
+ ntype.exec_fn = exec;
+ ntype.updatefunc = node_math_update;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_mixRgb.c b/source/blender/nodes/texture/nodes/node_texture_mixRgb.c
index cd6b54c4cf8..15ca2280fe1 100644
--- a/source/blender/nodes/texture/nodes/node_texture_mixRgb.c
+++ b/source/blender/nodes/texture/nodes/node_texture_mixRgb.c
@@ -56,7 +56,7 @@ void register_node_type_tex_mix_rgb(void)
tex_node_type_base(&ntype, TEX_NODE_MIX_RGB, "Mix", NODE_CLASS_OP_COLOR);
node_type_socket_templates(&ntype, inputs, outputs);
ntype.labelfunc = node_blend_label;
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.exec_fn = 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 b300ba9ef77..b640880ba9b 100644
--- a/source/blender/nodes/texture/nodes/node_texture_output.c
+++ b/source/blender/nodes/texture/nodes/node_texture_output.c
@@ -83,7 +83,7 @@ static void unique_name(bNode *node)
BLI_strncpy(new_name, name, sizeof(tno->name));
name = new_name;
}
- sprintf(new_name + new_len - 4, ".%03d", ++suffix);
+ BLI_sprintf(new_name + new_len - 4, ".%03d", ++suffix);
}
if (new_name[0] != '\0') {
@@ -138,9 +138,9 @@ void register_node_type_tex_output(void)
tex_node_type_base(&ntype, TEX_NODE_OUTPUT, "Output", NODE_CLASS_OUTPUT);
node_type_socket_templates(&ntype, inputs, NULL);
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, init);
+ ntype.initfunc = init;
node_type_storage(&ntype, "TexNodeOutput", node_free_standard_storage, copy);
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.exec_fn = exec;
ntype.flag |= NODE_PREVIEW;
ntype.no_muting = true;
diff --git a/source/blender/nodes/texture/nodes/node_texture_proc.c b/source/blender/nodes/texture/nodes/node_texture_proc.c
index d925c9f3554..f23c4f55820 100644
--- a/source/blender/nodes/texture/nodes/node_texture_proc.c
+++ b/source/blender/nodes/texture/nodes/node_texture_proc.c
@@ -254,9 +254,9 @@ static void init(bNodeTree *UNUSED(ntree), bNode *node)
tex_node_type_base(&ntype, TEX_NODE_PROC + TEXTYPE, Name, NODE_CLASS_TEXTURE); \
node_type_socket_templates(&ntype, name##_inputs, outputs); \
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE); \
- node_type_init(&ntype, init); \
+ ntype.initfunc = init; \
node_type_storage(&ntype, "Tex", node_free_standard_storage, node_copy_standard_storage); \
- node_type_exec(&ntype, NULL, NULL, name##_exec); \
+ ntype.exec_fn = name##_exec; \
ntype.flag |= NODE_PREVIEW; \
\
nodeRegisterType(&ntype); \
diff --git a/source/blender/nodes/texture/nodes/node_texture_rotate.c b/source/blender/nodes/texture/nodes/node_texture_rotate.c
index 0bd2de76a9c..b31adefcbba 100644
--- a/source/blender/nodes/texture/nodes/node_texture_rotate.c
+++ b/source/blender/nodes/texture/nodes/node_texture_rotate.c
@@ -81,7 +81,7 @@ void register_node_type_tex_rotate(void)
tex_node_type_base(&ntype, TEX_NODE_ROTATE, "Rotate", NODE_CLASS_DISTORT);
node_type_socket_templates(&ntype, inputs, outputs);
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.exec_fn = exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_scale.c b/source/blender/nodes/texture/nodes/node_texture_scale.c
index d565146cf09..93a4db7677c 100644
--- a/source/blender/nodes/texture/nodes/node_texture_scale.c
+++ b/source/blender/nodes/texture/nodes/node_texture_scale.c
@@ -54,7 +54,7 @@ void register_node_type_tex_scale(void)
tex_node_type_base(&ntype, TEX_NODE_SCALE, "Scale", NODE_CLASS_DISTORT);
node_type_socket_templates(&ntype, inputs, outputs);
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.exec_fn = exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_separate_color.c b/source/blender/nodes/texture/nodes/node_texture_separate_color.c
index a482a3f3421..030f7d79043 100644
--- a/source/blender/nodes/texture/nodes/node_texture_separate_color.c
+++ b/source/blender/nodes/texture/nodes/node_texture_separate_color.c
@@ -95,8 +95,8 @@ void register_node_type_tex_separate_color(void)
tex_node_type_base(&ntype, TEX_NODE_SEPARATE_COLOR, "Separate Color", NODE_CLASS_OP_COLOR);
node_type_socket_templates(&ntype, inputs, outputs);
- node_type_exec(&ntype, NULL, NULL, exec);
- node_type_update(&ntype, update);
+ ntype.exec_fn = exec;
+ ntype.updatefunc = update;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_texture.c b/source/blender/nodes/texture/nodes/node_texture_texture.c
index 79cd8bbb1df..163a6516a58 100644
--- a/source/blender/nodes/texture/nodes/node_texture_texture.c
+++ b/source/blender/nodes/texture/nodes/node_texture_texture.c
@@ -78,7 +78,7 @@ void register_node_type_tex_texture(void)
tex_node_type_base(&ntype, TEX_NODE_TEXTURE, "Texture", NODE_CLASS_INPUT);
node_type_socket_templates(&ntype, inputs, outputs);
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.exec_fn = exec;
ntype.flag |= NODE_PREVIEW;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/texture/nodes/node_texture_translate.c b/source/blender/nodes/texture/nodes/node_texture_translate.c
index 7ce7722938d..a8c12116097 100644
--- a/source/blender/nodes/texture/nodes/node_texture_translate.c
+++ b/source/blender/nodes/texture/nodes/node_texture_translate.c
@@ -50,7 +50,7 @@ void register_node_type_tex_translate(void)
tex_node_type_base(&ntype, TEX_NODE_TRANSLATE, "Translate", NODE_CLASS_DISTORT);
node_type_socket_templates(&ntype, inputs, outputs);
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.exec_fn = exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_valToNor.c b/source/blender/nodes/texture/nodes/node_texture_valToNor.c
index 492aadf3281..d0fc5229e06 100644
--- a/source/blender/nodes/texture/nodes/node_texture_valToNor.c
+++ b/source/blender/nodes/texture/nodes/node_texture_valToNor.c
@@ -66,7 +66,7 @@ void register_node_type_tex_valtonor(void)
tex_node_type_base(&ntype, TEX_NODE_VALTONOR, "Value to Normal", NODE_CLASS_CONVERTER);
node_type_socket_templates(&ntype, inputs, outputs);
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.exec_fn = exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_valToRgb.c b/source/blender/nodes/texture/nodes/node_texture_valToRgb.c
index e41e83555fc..b2acef407e2 100644
--- a/source/blender/nodes/texture/nodes/node_texture_valToRgb.c
+++ b/source/blender/nodes/texture/nodes/node_texture_valToRgb.c
@@ -50,9 +50,9 @@ void register_node_type_tex_valtorgb(void)
tex_node_type_base(&ntype, TEX_NODE_VALTORGB, "ColorRamp", NODE_CLASS_CONVERTER);
node_type_socket_templates(&ntype, valtorgb_in, valtorgb_out);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- node_type_init(&ntype, valtorgb_init);
+ ntype.initfunc = valtorgb_init;
node_type_storage(&ntype, "ColorBand", node_free_standard_storage, node_copy_standard_storage);
- node_type_exec(&ntype, NULL, NULL, valtorgb_exec);
+ ntype.exec_fn = valtorgb_exec;
nodeRegisterType(&ntype);
}
@@ -91,7 +91,7 @@ void register_node_type_tex_rgbtobw(void)
tex_node_type_base(&ntype, TEX_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTER);
node_type_socket_templates(&ntype, rgbtobw_in, rgbtobw_out);
- node_type_exec(&ntype, NULL, NULL, rgbtobw_exec);
+ ntype.exec_fn = rgbtobw_exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_viewer.c b/source/blender/nodes/texture/nodes/node_texture_viewer.c
index 72da751f8ef..1f31d62ed38 100644
--- a/source/blender/nodes/texture/nodes/node_texture_viewer.c
+++ b/source/blender/nodes/texture/nodes/node_texture_viewer.c
@@ -38,7 +38,7 @@ void register_node_type_tex_viewer(void)
tex_node_type_base(&ntype, TEX_NODE_VIEWER, "Viewer", NODE_CLASS_OUTPUT);
node_type_socket_templates(&ntype, inputs, NULL);
- node_type_exec(&ntype, NULL, NULL, exec);
+ ntype.exec_fn = exec;
ntype.no_muting = true;
ntype.flag |= NODE_PREVIEW;
diff --git a/source/blender/python/CMakeLists.txt b/source/blender/python/CMakeLists.txt
index 9f6ee359d67..f82499ba1d4 100644
--- a/source/blender/python/CMakeLists.txt
+++ b/source/blender/python/CMakeLists.txt
@@ -1,5 +1,9 @@
# SPDX-License-Identifier: GPL-2.0-or-later
+if(WITH_PYTHON_MODULE)
+ add_definitions(-DPy_ENABLE_SHARED)
+endif()
+
add_subdirectory(intern)
add_subdirectory(generic)
add_subdirectory(gpu)
diff --git a/source/blender/python/bmesh/bmesh_py_api.c b/source/blender/python/bmesh/bmesh_py_api.c
index 2e6d1698da9..cc413ad7924 100644
--- a/source/blender/python/bmesh/bmesh_py_api.c
+++ b/source/blender/python/bmesh/bmesh_py_api.c
@@ -156,14 +156,14 @@ PyDoc_STRVAR(BPy_BM_doc,
".. include:: include__bmesh.rst\n");
static struct PyModuleDef BPy_BM_module_def = {
PyModuleDef_HEAD_INIT,
- "bmesh", /* m_name */
- BPy_BM_doc, /* m_doc */
- 0, /* m_size */
- BPy_BM_methods, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "bmesh",
+ /*m_doc*/ BPy_BM_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ BPy_BM_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPyInit_bmesh(void)
diff --git a/source/blender/python/bmesh/bmesh_py_geometry.c b/source/blender/python/bmesh/bmesh_py_geometry.c
index f2af8599807..aed197bc353 100644
--- a/source/blender/python/bmesh/bmesh_py_geometry.c
+++ b/source/blender/python/bmesh/bmesh_py_geometry.c
@@ -62,14 +62,14 @@ PyDoc_STRVAR(BPy_BM_utils_doc,
"This module provides access to bmesh geometry evaluation functions.");
static struct PyModuleDef BPy_BM_geometry_module_def = {
PyModuleDef_HEAD_INIT,
- "bmesh.geometry", /* m_name */
- BPy_BM_utils_doc, /* m_doc */
- 0, /* m_size */
- BPy_BM_geometry_methods, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "bmesh.geometry",
+ /*m_doc*/ BPy_BM_utils_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ BPy_BM_geometry_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPyInit_bmesh_geometry(void)
diff --git a/source/blender/python/bmesh/bmesh_py_ops.c b/source/blender/python/bmesh/bmesh_py_ops.c
index 37e2b009f55..e5ca170599f 100644
--- a/source/blender/python/bmesh/bmesh_py_ops.c
+++ b/source/blender/python/bmesh/bmesh_py_ops.c
@@ -146,82 +146,54 @@ static PyGetSetDef bpy_bmesh_op_getseters[] = {
* ===== */
static PyTypeObject bmesh_op_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "BMeshOpFunc", /* tp_name */
- sizeof(BPy_BMeshOpFunc), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- NULL, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL,
- /* tp_compare */ /* DEPRECATED in python 3.0! */
- (reprfunc)bpy_bmesh_op_repr, /* tp_repr */
-
- /* Method suites for standard classes */
-
- NULL, /* PyNumberMethods *tp_as_number; */
- NULL, /* PySequenceMethods *tp_as_sequence; */
- NULL, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- NULL, /* hashfunc tp_hash; */
- (ternaryfunc)BPy_BMO_call, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
-
- /* will only use these if this is a subtype of a py class */
- NULL, /* getattrofunc tp_getattro; */
- NULL, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons ***/
- NULL, /* richcmpfunc tp_richcompare; */
-
- /*** weak reference enabler ***/
- 0,
- /*** Added in release 2.2 ***/
- /* Iterators */
- NULL, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
-
- /*** Attribute descriptor and subclassing stuff ***/
- NULL, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- bpy_bmesh_op_getseters, /* struct PyGetSetDef *tp_getset; */
- NULL, /* struct _typeobject *tp_base; */
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- 0, /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- NULL, /* newfunc tp_new; */
- /* Low-level free-memory routine */
- NULL, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL,
+ /*tp_name*/ PyVarObject_HEAD_INIT(NULL, 0) "BMeshOpFunc",
+ /*tp_basicsize*/ sizeof(BPy_BMeshOpFunc),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ NULL,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ (reprfunc)bpy_bmesh_op_repr,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ NULL,
+ /*tp_as_mapping*/ NULL,
+ /*tp_hash*/ NULL,
+ /*tp_call*/ (ternaryfunc)BPy_BMO_call,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ NULL,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ NULL,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ bpy_bmesh_op_getseters,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ NULL,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
/* bmesh module 'bmesh.ops'
@@ -263,14 +235,14 @@ static struct PyMethodDef BPy_BM_ops_methods[] = {
PyDoc_STRVAR(BPy_BM_ops_doc, "Access to BMesh operators");
static struct PyModuleDef BPy_BM_ops_module_def = {
PyModuleDef_HEAD_INIT,
- "bmesh.ops", /* m_name */
- BPy_BM_ops_doc, /* m_doc */
- 0, /* m_size */
- BPy_BM_ops_methods, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "bmesh.ops",
+ /*m_doc*/ BPy_BM_ops_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ BPy_BM_ops_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPyInit_bmesh_ops(void)
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c
index 35d5cb6a994..72473fce64d 100644
--- a/source/blender/python/bmesh/bmesh_py_ops_call.c
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.c
@@ -234,7 +234,7 @@ static int bpy_slot_from_py(BMesh *bm,
return -1;
}
const ushort size = pymat->col_num;
- if ((size != pymat->row_num) || (!ELEM(size, 3, 4))) {
+ if ((size != pymat->row_num) || !ELEM(size, 3, 4)) {
PyErr_Format(PyExc_TypeError,
"%.200s: keyword \"%.200s\" expected a 3x3 or 4x4 matrix",
opname,
@@ -738,7 +738,7 @@ PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw)
BMOperator bmop;
if ((PyTuple_GET_SIZE(args) == 1) && (py_bm = (BPy_BMesh *)PyTuple_GET_ITEM(args, 0)) &&
- (BPy_BMesh_Check(py_bm))) {
+ BPy_BMesh_Check(py_bm)) {
BPY_BM_CHECK_OBJ(py_bm);
bm = py_bm->bm;
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index d592a583817..12267ef5b13 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -7,6 +7,7 @@
#include "BLI_math.h"
#include "BLI_sort.h"
+#include "BLI_string.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
@@ -3118,7 +3119,7 @@ static Py_ssize_t bpy_bmelemseq_length(BPy_BMElemSeq *self)
}
}
-static PyObject *bpy_bmelemseq_subscript_int(BPy_BMElemSeq *self, int keynum)
+static PyObject *bpy_bmelemseq_subscript_int(BPy_BMElemSeq *self, Py_ssize_t keynum)
{
BPY_BM_CHECK_OBJ(self);
@@ -3313,31 +3314,30 @@ static int bpy_bmelem_ass_subscript(BPy_BMElem *self, BPy_BMLayerItem *key, PyOb
}
static PySequenceMethods bpy_bmelemseq_as_sequence = {
- (lenfunc)bpy_bmelemseq_length, /* sq_length */
- NULL, /* sq_concat */
- NULL, /* sq_repeat */
- (ssizeargfunc)bpy_bmelemseq_subscript_int,
- /* sq_item */ /* Only set this so PySequence_Check() returns True */
- NULL, /* sq_slice */
- (ssizeobjargproc)NULL, /* sq_ass_item */
- NULL, /* *was* sq_ass_slice */
- (objobjproc)bpy_bmelemseq_contains, /* sq_contains */
- (binaryfunc)NULL, /* sq_inplace_concat */
- (ssizeargfunc)NULL, /* sq_inplace_repeat */
+ /*sq_length*/ (lenfunc)bpy_bmelemseq_length,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /* Only set this so `PySequence_Check()` returns True. */
+ /*sq_item*/ (ssizeargfunc)bpy_bmelemseq_subscript_int,
+ /*was_sq_slice*/ NULL,
+ /*sq_ass_item*/ NULL,
+ /*was_sq_ass_slice*/ NULL,
+ /*sq_contains*/ (objobjproc)bpy_bmelemseq_contains,
+ /*sq_inplace_concat*/ NULL,
+ /*sq_inplace_repeat*/ NULL,
};
static PyMappingMethods bpy_bmelemseq_as_mapping = {
- (lenfunc)bpy_bmelemseq_length, /* mp_length */
- (binaryfunc)bpy_bmelemseq_subscript, /* mp_subscript */
- (objobjargproc)NULL, /* mp_ass_subscript */
+ /*mp_len*/ (lenfunc)bpy_bmelemseq_length,
+ /*mp_subscript*/ (binaryfunc)bpy_bmelemseq_subscript,
+ /*mp_ass_subscript*/ (objobjargproc)NULL,
};
/* for customdata access */
static PyMappingMethods bpy_bm_elem_as_mapping = {
- (lenfunc)NULL,
- /* mp_length */ /* keep this empty, messes up 'if elem: ...' test */
- (binaryfunc)bpy_bmelem_subscript, /* mp_subscript */
- (objobjargproc)bpy_bmelem_ass_subscript, /* mp_ass_subscript */
+ /*mp_len*/ (lenfunc)NULL, /* Keep this empty, messes up `if elem: ...` test. */
+ /*mp_subscript*/ (binaryfunc)bpy_bmelem_subscript,
+ /*mp_ass_subscript*/ (objobjargproc)bpy_bmelem_ass_subscript,
};
/* Iterator
@@ -3736,14 +3736,14 @@ void BPy_BM_init_types(void)
static struct PyModuleDef BPy_BM_types_module_def = {
PyModuleDef_HEAD_INIT,
- "bmesh.types", /* m_name */
- NULL, /* m_doc */
- 0, /* m_size */
- NULL, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "bmesh.types",
+ /*m_doc*/ NULL,
+ /*m_size*/ 0,
+ /*m_methods*/ NULL,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPyInit_bmesh_types(void)
@@ -4247,16 +4247,16 @@ char *BPy_BMElem_StringFromHType_ex(const char htype, char ret[32])
/* zero to ensure string is always NULL terminated */
char *ret_ptr = ret;
if (htype & BM_VERT) {
- ret_ptr += sprintf(ret_ptr, "/%s", BPy_BMVert_Type.tp_name);
+ ret_ptr += BLI_sprintf(ret_ptr, "/%s", BPy_BMVert_Type.tp_name);
}
if (htype & BM_EDGE) {
- ret_ptr += sprintf(ret_ptr, "/%s", BPy_BMEdge_Type.tp_name);
+ ret_ptr += BLI_sprintf(ret_ptr, "/%s", BPy_BMEdge_Type.tp_name);
}
if (htype & BM_FACE) {
- ret_ptr += sprintf(ret_ptr, "/%s", BPy_BMFace_Type.tp_name);
+ ret_ptr += BLI_sprintf(ret_ptr, "/%s", BPy_BMFace_Type.tp_name);
}
if (htype & BM_LOOP) {
- ret_ptr += sprintf(ret_ptr, "/%s", BPy_BMLoop_Type.tp_name);
+ ret_ptr += BLI_sprintf(ret_ptr, "/%s", BPy_BMLoop_Type.tp_name);
}
ret[0] = '(';
*ret_ptr++ = ')';
@@ -4273,10 +4273,10 @@ char *BPy_BMElem_StringFromHType(const char htype)
/* -------------------------------------------------------------------- */
/* keep at bottom */
-/* this function is called on free, it should stay quite fast */
+/* This function is called on free, it should stay quite fast */
static void bm_dealloc_editmode_warn(BPy_BMesh *self)
{
if (self->flag & BPY_BMFLAG_IS_WRAPPED) {
- /* currently nop - this works without warnings now */
+ /* Currently NOP - this works without warnings now. */
}
}
diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c
index 58bfb922327..1288083f8e7 100644
--- a/source/blender/python/bmesh/bmesh_py_types_customdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c
@@ -740,7 +740,8 @@ static PyObject *bpy_bmlayercollection_subscript_str(BPy_BMLayerCollection *self
return NULL;
}
-static PyObject *bpy_bmlayercollection_subscript_int(BPy_BMLayerCollection *self, int keynum)
+static PyObject *bpy_bmlayercollection_subscript_int(BPy_BMLayerCollection *self,
+ Py_ssize_t keynum)
{
Py_ssize_t len;
BPY_BM_CHECK_OBJ(self);
@@ -871,23 +872,23 @@ static int bpy_bmlayercollection_contains(BPy_BMLayerCollection *self, PyObject
}
static PySequenceMethods bpy_bmlayercollection_as_sequence = {
- (lenfunc)bpy_bmlayercollection_length, /* sq_length */
- NULL, /* sq_concat */
- NULL, /* sq_repeat */
- (ssizeargfunc)bpy_bmlayercollection_subscript_int,
- /* sq_item */ /* Only set this so PySequence_Check() returns True */
- NULL, /* sq_slice */
- (ssizeobjargproc)NULL, /* sq_ass_item */
- NULL, /* *was* sq_ass_slice */
- (objobjproc)bpy_bmlayercollection_contains, /* sq_contains */
- (binaryfunc)NULL, /* sq_inplace_concat */
- (ssizeargfunc)NULL, /* sq_inplace_repeat */
+ /*sq_length*/ (lenfunc)bpy_bmlayercollection_length,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /* Only set this so `PySequence_Check()` returns True. */
+ /*sq_item*/ (ssizeargfunc)bpy_bmlayercollection_subscript_int,
+ /*was_sq_slice*/ NULL, /* DEPRECATED. */
+ /*sq_ass_item*/ NULL,
+ /*was_sq_ass_slice*/ NULL, /* DEPRECATED. */
+ /*sq_contains*/ (objobjproc)bpy_bmlayercollection_contains,
+ /*sq_inplace_concat*/ NULL,
+ /*sq_inplace_repeat*/ NULL,
};
static PyMappingMethods bpy_bmlayercollection_as_mapping = {
- (lenfunc)bpy_bmlayercollection_length, /* mp_length */
- (binaryfunc)bpy_bmlayercollection_subscript, /* mp_subscript */
- (objobjargproc)NULL, /* mp_ass_subscript */
+ /*mp_len*/ (lenfunc)bpy_bmlayercollection_length,
+ /*mp_subscript*/ (binaryfunc)bpy_bmlayercollection_subscript,
+ /*mp_ass_subscript*/ (objobjargproc)NULL,
};
/* Iterator
diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
index d4455fd3668..9bd98f2df53 100644
--- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
@@ -298,7 +298,7 @@ static int mathutils_bmloopcol_set(BaseMathObject *bmo, int UNUSED(subtype))
static int mathutils_bmloopcol_get_index(BaseMathObject *bmo, int subtype, int UNUSED(index))
{
- /* lazy, avoid repeteing the case statement */
+ /* Lazy, avoid repeating the case statement. */
if (mathutils_bmloopcol_get(bmo, subtype) == -1) {
return -1;
}
@@ -309,7 +309,7 @@ static int mathutils_bmloopcol_set_index(BaseMathObject *bmo, int subtype, int i
{
const float f = bmo->data[index];
- /* lazy, avoid repeteing the case statement */
+ /* Lazy, avoid repeating the case statement. */
if (mathutils_bmloopcol_get(bmo, subtype) == -1) {
return -1;
}
@@ -391,7 +391,7 @@ typedef struct BPy_BMDeformVert {
/* Mapping Protocols
* ================= */
-static int bpy_bmdeformvert_len(BPy_BMDeformVert *self)
+static Py_ssize_t bpy_bmdeformvert_len(BPy_BMDeformVert *self)
{
return self->data->totweight;
}
@@ -486,26 +486,24 @@ static int bpy_bmdeformvert_contains(BPy_BMDeformVert *self, PyObject *value)
/* only defined for __contains__ */
static PySequenceMethods bpy_bmdeformvert_as_sequence = {
- (lenfunc)bpy_bmdeformvert_len, /* sq_length */
- NULL, /* sq_concat */
- NULL, /* sq_repeat */
-
+ /*sq_length*/ (lenfunc)bpy_bmdeformvert_len,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
/* NOTE: if this is set #PySequence_Check() returns True,
* but in this case we don't want to be treated as a seq. */
- NULL, /* sq_item */
-
- NULL, /* sq_slice */
- NULL, /* sq_ass_item */
- NULL, /* *was* sq_ass_slice */
- (objobjproc)bpy_bmdeformvert_contains, /* sq_contains */
- (binaryfunc)NULL, /* sq_inplace_concat */
- (ssizeargfunc)NULL, /* sq_inplace_repeat */
+ /*sq_item*/ NULL,
+ /*was_sq_slice*/ NULL, /* DEPRECATED. */
+ /*sq_ass_item*/ NULL,
+ /*was_sq_ass_slice*/ NULL, /* DEPRECATED. */
+ /*sq_contains*/ (objobjproc)bpy_bmdeformvert_contains,
+ /*sq_inplace_concat*/ NULL,
+ /*sq_inplace_repeat*/ NULL,
};
static PyMappingMethods bpy_bmdeformvert_as_mapping = {
- (lenfunc)bpy_bmdeformvert_len,
- (binaryfunc)bpy_bmdeformvert_subscript,
- (objobjargproc)bpy_bmdeformvert_ass_subscript,
+ /*mp_len*/ (lenfunc)bpy_bmdeformvert_len,
+ /*mp_subscript*/ (binaryfunc)bpy_bmdeformvert_subscript,
+ /*mp_ass_subscript*/ (objobjargproc)bpy_bmdeformvert_ass_subscript,
};
/* Methods
diff --git a/source/blender/python/bmesh/bmesh_py_types_select.c b/source/blender/python/bmesh/bmesh_py_types_select.c
index 93bce055b12..ed25caee74d 100644
--- a/source/blender/python/bmesh/bmesh_py_types_select.c
+++ b/source/blender/python/bmesh/bmesh_py_types_select.c
@@ -163,7 +163,7 @@ static Py_ssize_t bpy_bmeditselseq_length(BPy_BMEditSelSeq *self)
return BLI_listbase_count(&self->bm->selected);
}
-static PyObject *bpy_bmeditselseq_subscript_int(BPy_BMEditSelSeq *self, int keynum)
+static PyObject *bpy_bmeditselseq_subscript_int(BPy_BMEditSelSeq *self, Py_ssize_t keynum)
{
BMEditSelection *ese;
@@ -291,23 +291,23 @@ static int bpy_bmeditselseq_contains(BPy_BMEditSelSeq *self, PyObject *value)
}
static PySequenceMethods bpy_bmeditselseq_as_sequence = {
- (lenfunc)bpy_bmeditselseq_length, /* sq_length */
- NULL, /* sq_concat */
- NULL, /* sq_repeat */
- (ssizeargfunc)bpy_bmeditselseq_subscript_int,
- /* sq_item */ /* Only set this so PySequence_Check() returns True */
- NULL, /* sq_slice */
- (ssizeobjargproc)NULL, /* sq_ass_item */
- NULL, /* *was* sq_ass_slice */
- (objobjproc)bpy_bmeditselseq_contains, /* sq_contains */
- (binaryfunc)NULL, /* sq_inplace_concat */
- (ssizeargfunc)NULL, /* sq_inplace_repeat */
+ /*sq_length*/ (lenfunc)bpy_bmeditselseq_length,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /* Only set this so `PySequence_Check()` returns True. */
+ /*sq_item*/ (ssizeargfunc)bpy_bmeditselseq_subscript_int,
+ /*sq_slice */ NULL,
+ /*sq_ass_item */ NULL,
+ /*was_sq_ass_slice*/ NULL,
+ /*sq_contains*/ (objobjproc)bpy_bmeditselseq_contains,
+ /*sq_inplace_concat*/ NULL,
+ /*sq_inplace_repeat*/ NULL,
};
static PyMappingMethods bpy_bmeditselseq_as_mapping = {
- (lenfunc)bpy_bmeditselseq_length, /* mp_length */
- (binaryfunc)bpy_bmeditselseq_subscript, /* mp_subscript */
- (objobjargproc)NULL, /* mp_ass_subscript */
+ /*mp_len*/ (lenfunc)bpy_bmeditselseq_length,
+ /*mp_subscript*/ (binaryfunc)bpy_bmeditselseq_subscript,
+ /*mp_ass_subscript*/ (objobjargproc)NULL,
};
/* Iterator
diff --git a/source/blender/python/bmesh/bmesh_py_utils.c b/source/blender/python/bmesh/bmesh_py_utils.c
index 6630eb4924e..5eca6f854f6 100644
--- a/source/blender/python/bmesh/bmesh_py_utils.c
+++ b/source/blender/python/bmesh/bmesh_py_utils.c
@@ -818,14 +818,14 @@ static struct PyMethodDef BPy_BM_utils_methods[] = {
PyDoc_STRVAR(BPy_BM_utils_doc, "This module provides access to blenders bmesh data structures.");
static struct PyModuleDef BPy_BM_utils_module_def = {
PyModuleDef_HEAD_INIT,
- "bmesh.utils", /* m_name */
- BPy_BM_utils_doc, /* m_doc */
- 0, /* m_size */
- BPy_BM_utils_methods, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "bmesh.utils",
+ /*m_doc*/ BPy_BM_utils_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ BPy_BM_utils_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPyInit_bmesh_utils(void)
diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c
index 36ab1e86d92..fe64b247d43 100644
--- a/source/blender/python/generic/bgl.c
+++ b/source/blender/python/generic/bgl.c
@@ -417,11 +417,11 @@ static PyObject *Method_ShaderSource(PyObject *self, PyObject *args);
/* Buffer sequence methods */
-static int Buffer_len(Buffer *self);
-static PyObject *Buffer_item(Buffer *self, int i);
-static PyObject *Buffer_slice(Buffer *self, int begin, int end);
-static int Buffer_ass_item(Buffer *self, int i, PyObject *v);
-static int Buffer_ass_slice(Buffer *self, int begin, int end, PyObject *seq);
+static Py_ssize_t Buffer_len(Buffer *self);
+static PyObject *Buffer_item(Buffer *self, Py_ssize_t i);
+static PyObject *Buffer_slice(Buffer *self, Py_ssize_t begin, Py_ssize_t end);
+static int Buffer_ass_item(Buffer *self, Py_ssize_t i, PyObject *v);
+static int Buffer_ass_slice(Buffer *self, Py_ssize_t begin, Py_ssize_t end, PyObject *seq);
static PyObject *Buffer_subscript(Buffer *self, PyObject *item);
static int Buffer_ass_subscript(Buffer *self, PyObject *item, PyObject *value);
@@ -491,22 +491,22 @@ static bool compare_dimensions(int ndim, const int *dim1, const Py_ssize_t *dim2
* \{ */
static PySequenceMethods Buffer_SeqMethods = {
- (lenfunc)Buffer_len, /* sq_length */
- (binaryfunc)NULL, /* sq_concat */
- (ssizeargfunc)NULL, /* sq_repeat */
- (ssizeargfunc)Buffer_item, /* sq_item */
- (ssizessizeargfunc)NULL, /* sq_slice, deprecated, handled in Buffer_item */
- (ssizeobjargproc)Buffer_ass_item, /* sq_ass_item */
- (ssizessizeobjargproc)NULL, /* sq_ass_slice, deprecated handled in Buffer_ass_item */
- (objobjproc)NULL, /* sq_contains */
- (binaryfunc)NULL, /* sq_inplace_concat */
- (ssizeargfunc)NULL, /* sq_inplace_repeat */
+ /*sq_length*/ (lenfunc)Buffer_len,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /*sq_item*/ (ssizeargfunc)Buffer_item,
+ /*was_sq_slice*/ NULL, /* DEPRECATED. Handled by #Buffer_item. */
+ /*sq_ass_item*/ (ssizeobjargproc)Buffer_ass_item,
+ /*was_sq_ass_slice*/ NULL, /* DEPRECATED. Handled by #Buffer_ass_item. */
+ /*sq_contains*/ NULL,
+ /*sq_inplace_concat*/ NULL,
+ /*sq_inplace_repeat*/ NULL,
};
static PyMappingMethods Buffer_AsMapping = {
- (lenfunc)Buffer_len,
- (binaryfunc)Buffer_subscript,
- (objobjargproc)Buffer_ass_subscript,
+ /*mp_len*/ (lenfunc)Buffer_len,
+ /*mp_subscript*/ (binaryfunc)Buffer_subscript,
+ /*mp_ass_subscript*/ (objobjargproc)Buffer_ass_subscript,
};
static void Buffer_dealloc(Buffer *self);
@@ -568,72 +568,55 @@ static PyGetSetDef Buffer_getseters[] = {
};
PyTypeObject BGL_bufferType = {
- PyVarObject_HEAD_INIT(NULL, 0) "bgl.Buffer", /* tp_name */
- sizeof(Buffer), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)Buffer_dealloc, /* tp_dealloc */
- (printfunc)NULL, /* tp_print */
- NULL, /* tp_getattr */
- NULL, /* tp_setattr */
- NULL, /* tp_compare */
- (reprfunc)Buffer_repr, /* tp_repr */
- NULL, /* tp_as_number */
- &Buffer_SeqMethods, /* tp_as_sequence */
- &Buffer_AsMapping, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- NULL, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
- NULL, /* getattrofunc tp_getattro; */
- NULL, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons ***/
- NULL, /* richcmpfunc tp_richcompare; */
-
- /*** weak reference enabler ***/
- 0, /* long tp_weaklistoffset; */
-
- /*** Added in release 2.2 ***/
- /* Iterators */
- NULL, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
- /*** Attribute descriptor and subclassing stuff ***/
- Buffer_methods, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- Buffer_getseters, /* struct PyGetSetDef *tp_getset; */
- NULL, /*tp_base*/
- NULL, /*tp_dict*/
- NULL, /*tp_descr_get*/
- NULL, /*tp_descr_set*/
- 0, /*tp_dictoffset*/
- NULL, /*tp_init*/
- NULL, /*tp_alloc*/
- Buffer_new, /*tp_new*/
- NULL, /*tp_free*/
- NULL, /*tp_is_gc*/
- NULL, /*tp_bases*/
- NULL, /*tp_mro*/
- NULL, /*tp_cache*/
- NULL, /*tp_subclasses*/
- NULL, /*tp_weaklist*/
- NULL, /*tp_del*/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "bgl.Buffer",
+ /*tp_basicsize*/ sizeof(Buffer),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)Buffer_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ (reprfunc)Buffer_repr,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ &Buffer_SeqMethods,
+ /*tp_as_mapping*/ &Buffer_AsMapping,
+ /*tp_hash*/ NULL,
+ /*tp_call*/ NULL,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ NULL,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ Buffer_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ Buffer_getseters,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ Buffer_new,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
static Buffer *BGL_MakeBuffer_FromData(
@@ -732,7 +715,7 @@ static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject
if (PyLong_Check(length_ob)) {
ndimensions = 1;
- if (((dimensions[0] = PyLong_AsLong(length_ob)) < 1)) {
+ if ((dimensions[0] = PyLong_AsLong(length_ob)) < 1) {
PyErr_SetString(PyExc_AttributeError,
"dimensions must be between 1 and " STRINGIFY(MAX_DIMENSIONS));
return NULL;
@@ -811,12 +794,12 @@ static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject
/* Buffer sequence methods */
-static int Buffer_len(Buffer *self)
+static Py_ssize_t Buffer_len(Buffer *self)
{
return self->dimensions[0];
}
-static PyObject *Buffer_item(Buffer *self, int i)
+static PyObject *Buffer_item(Buffer *self, Py_ssize_t i)
{
if (i >= self->dimensions[0] || i < 0) {
PyErr_SetString(PyExc_IndexError, "array index out of range");
@@ -854,10 +837,9 @@ static PyObject *Buffer_item(Buffer *self, int i)
return NULL;
}
-static PyObject *Buffer_slice(Buffer *self, int begin, int end)
+static PyObject *Buffer_slice(Buffer *self, Py_ssize_t begin, Py_ssize_t end)
{
PyObject *list;
- int count;
if (begin < 0) {
begin = 0;
@@ -871,13 +853,13 @@ static PyObject *Buffer_slice(Buffer *self, int begin, int end)
list = PyList_New(end - begin);
- for (count = begin; count < end; count++) {
+ for (Py_ssize_t count = begin; count < end; count++) {
PyList_SET_ITEM(list, count - begin, Buffer_item(self, count));
}
return list;
}
-static int Buffer_ass_item(Buffer *self, int i, PyObject *v)
+static int Buffer_ass_item(Buffer *self, Py_ssize_t i, PyObject *v)
{
if (i >= self->dimensions[0] || i < 0) {
PyErr_SetString(PyExc_IndexError, "array assignment index out of range");
@@ -912,10 +894,11 @@ static int Buffer_ass_item(Buffer *self, int i, PyObject *v)
}
}
-static int Buffer_ass_slice(Buffer *self, int begin, int end, PyObject *seq)
+static int Buffer_ass_slice(Buffer *self, Py_ssize_t begin, Py_ssize_t end, PyObject *seq)
{
PyObject *item;
- int count, err = 0;
+ int err = 0;
+ Py_ssize_t count;
if (begin < 0) {
begin = 0;
@@ -935,7 +918,7 @@ static int Buffer_ass_slice(Buffer *self, int begin, int end, PyObject *seq)
return -1;
}
- /* re-use count var */
+ /* Re-use count variable. */
if ((count = PySequence_Size(seq)) != (end - begin)) {
PyErr_Format(PyExc_TypeError,
"buffer[:] = value, size mismatch in assignment. "
@@ -1393,14 +1376,14 @@ BGL_Wrap(TexImage3DMultisample,
static struct PyModuleDef BGL_module_def = {
PyModuleDef_HEAD_INIT,
- "bgl", /* m_name */
- NULL, /* m_doc */
- 0, /* m_size */
- NULL, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "bgl",
+ /*m_doc*/ NULL,
+ /*m_size*/ 0,
+ /*m_methods*/ NULL,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
static void py_module_dict_add_int(PyObject *dict, const char *name, int value)
diff --git a/source/blender/python/generic/bl_math_py_api.c b/source/blender/python/generic/bl_math_py_api.c
index 19958a99df9..47a1687d20b 100644
--- a/source/blender/python/generic/bl_math_py_api.c
+++ b/source/blender/python/generic/bl_math_py_api.c
@@ -129,14 +129,14 @@ static PyMethodDef M_bl_math_methods[] = {
static struct PyModuleDef M_bl_math_module_def = {
PyModuleDef_HEAD_INIT,
- "bl_math", /* m_name */
- M_bl_math_doc, /* m_doc */
- 0, /* m_size */
- M_bl_math_methods, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "bl_math",
+ /*m_doc*/ M_bl_math_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ M_bl_math_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyMODINIT_FUNC BPyInit_bl_math(void)
diff --git a/source/blender/python/generic/blf_py_api.c b/source/blender/python/generic/blf_py_api.c
index 11b71256327..2b7c5ed7e55 100644
--- a/source/blender/python/generic/blf_py_api.c
+++ b/source/blender/python/generic/blf_py_api.c
@@ -48,27 +48,32 @@ static PyObject *py_blf_position(PyObject *UNUSED(self), PyObject *args)
}
PyDoc_STRVAR(py_blf_size_doc,
- ".. function:: size(fontid, size, dpi)\n"
+ ".. function:: size(fontid, size, dpi=72)\n"
"\n"
- " Set the size and DPI for drawing text.\n"
+ " Set the size for drawing text.\n"
"\n"
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
"font use 0.\n"
" :type fontid: int\n"
" :arg size: Point size of the font.\n"
" :type size: float\n"
- " :arg dpi: dots per inch value to use for drawing.\n"
+ " :arg dpi: DEPRECATED: Defaults to 72 when omitted.\n"
" :type dpi: int\n");
static PyObject *py_blf_size(PyObject *UNUSED(self), PyObject *args)
{
- int fontid, dpi;
+ int fontid, dpi = -1;
float size;
- if (!PyArg_ParseTuple(args, "ifi:blf.size", &fontid, &size, &dpi)) {
+ if (!PyArg_ParseTuple(args, "if|i:blf.size", &fontid, &size, &dpi)) {
return NULL;
}
- BLF_size(fontid, size, dpi);
+ if (dpi != -1) {
+ size *= (float)dpi / 72.0f;
+ PyErr_WarnEx(PyExc_DeprecationWarning, "'dpi' is deprecated and assumed to be always 72.", 1);
+ }
+
+ BLF_size(fontid, size);
Py_RETURN_NONE;
}
@@ -461,14 +466,14 @@ static PyMethodDef BLF_methods[] = {
PyDoc_STRVAR(BLF_doc, "This module provides access to Blender's text drawing functions.");
static struct PyModuleDef BLF_module_def = {
PyModuleDef_HEAD_INIT,
- "blf", /* m_name */
- BLF_doc, /* m_doc */
- 0, /* m_size */
- BLF_methods, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "blf",
+ /*m_doc*/ BLF_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ BLF_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPyInit_blf(void)
diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c
index 333ab9487d1..9a6568355af 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -909,6 +909,11 @@ static int BPy_IDGroup_Iter_clear(BPy_IDGroup_Iter *self)
return 0;
}
+static int BPy_IDGroup_Iter_is_gc(BPy_IDGroup_Iter *self)
+{
+ return (self->group != NULL);
+}
+
static bool BPy_Group_Iter_same_size_or_raise_error(BPy_IDGroup_Iter *self)
{
if (self->len_init == self->group->prop->len) {
@@ -1000,6 +1005,7 @@ static void IDGroup_Iter_init_type(void)
SHARED_MEMBER_SET(tp_flags, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC);
SHARED_MEMBER_SET(tp_traverse, (traverseproc)BPy_IDGroup_Iter_traverse);
SHARED_MEMBER_SET(tp_clear, (inquiry)BPy_IDGroup_Iter_clear);
+ SHARED_MEMBER_SET(tp_is_gc, (inquiry)BPy_IDGroup_Iter_is_gc);
SHARED_MEMBER_SET(tp_iter, PyObject_SelfIter);
#undef SHARED_MEMBER_SET
@@ -1015,6 +1021,7 @@ static PyObject *IDGroup_Iter_New_WithType(BPy_IDProperty *group,
iter->group = group;
if (group != NULL) {
Py_INCREF(group);
+ BLI_assert(!PyObject_GC_IsTracked((PyObject *)iter));
PyObject_GC_Track(iter);
iter->cur = (reversed ? group->prop->data.group.last : group->prop->data.group.first);
iter->len_init = group->prop->len;
@@ -1086,6 +1093,11 @@ static int BPy_IDGroup_View_clear(BPy_IDGroup_View *self)
return 0;
}
+static int BPy_IDGroup_View_is_gc(BPy_IDGroup_View *self)
+{
+ return (self->group != NULL);
+}
+
/* View Specific API's (Key/Value/Items). */
static PyObject *BPy_Group_ViewKeys_iter(BPy_IDGroup_View *self)
@@ -1144,36 +1156,36 @@ static int BPy_Group_ViewItems_Contains(BPy_IDGroup_View *self, PyObject *value)
}
static PySequenceMethods BPy_IDGroup_ViewKeys_as_sequence = {
- (lenfunc)BPy_Group_View_len, /* sq_length */
- 0, /* sq_concat */
- 0, /* sq_repeat */
- 0, /* sq_item */
- 0, /* sq_slice */
- 0, /* sq_ass_item */
- 0, /* sq_ass_slice */
- (objobjproc)BPy_Group_ViewKeys_Contains, /* sq_contains */
+ /*sq_length*/ (lenfunc)BPy_Group_View_len,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /*sq_item*/ NULL,
+ /*was_sq_slice*/ NULL,
+ /*sq_ass_item*/ NULL,
+ /*was_sq_ass_slice*/ NULL,
+ /*sq_contains*/ (objobjproc)BPy_Group_ViewKeys_Contains,
};
static PySequenceMethods BPy_IDGroup_ViewValues_as_sequence = {
- (lenfunc)BPy_Group_View_len, /* sq_length */
- 0, /* sq_concat */
- 0, /* sq_repeat */
- 0, /* sq_item */
- 0, /* sq_slice */
- 0, /* sq_ass_item */
- 0, /* sq_ass_slice */
- (objobjproc)BPy_Group_ViewValues_Contains, /* sq_contains */
+ /*sq_length*/ (lenfunc)BPy_Group_View_len,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /*sq_item*/ NULL,
+ /*was_sq_slice*/ NULL,
+ /*sq_ass_item*/ NULL,
+ /*was_sq_ass_slice*/ NULL,
+ /*sq_contains*/ (objobjproc)BPy_Group_ViewValues_Contains,
};
static PySequenceMethods BPy_IDGroup_ViewItems_as_sequence = {
- (lenfunc)BPy_Group_View_len, /* sq_length */
- 0, /* sq_concat */
- 0, /* sq_repeat */
- 0, /* sq_item */
- 0, /* sq_slice */
- 0, /* sq_ass_item */
- 0, /* sq_ass_slice */
- (objobjproc)BPy_Group_ViewItems_Contains, /* sq_contains */
+ /*sq_length*/ (lenfunc)BPy_Group_View_len,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /*sq_item*/ NULL,
+ /*was_sq_slice*/ NULL,
+ /*sq_ass_item*/ NULL,
+ /*was_sq_ass_slice*/ NULL,
+ /*sq_contains*/ (objobjproc)BPy_Group_ViewItems_Contains,
};
/* Methods. */
@@ -1233,6 +1245,7 @@ static void IDGroup_View_init_type(void)
SHARED_MEMBER_SET(tp_flags, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC);
SHARED_MEMBER_SET(tp_traverse, (traverseproc)BPy_IDGroup_View_traverse);
SHARED_MEMBER_SET(tp_clear, (inquiry)BPy_IDGroup_View_clear);
+ SHARED_MEMBER_SET(tp_is_gc, (inquiry)BPy_IDGroup_View_is_gc);
SHARED_MEMBER_SET(tp_methods, BPy_IDGroup_View_methods);
#undef SHARED_MEMBER_SET
@@ -1538,84 +1551,76 @@ static struct PyMethodDef BPy_IDGroup_methods[] = {
* \{ */
static PySequenceMethods BPy_IDGroup_Seq = {
- (lenfunc)BPy_IDGroup_Map_Len, /* lenfunc sq_length */
- NULL, /* binaryfunc sq_concat */
- NULL, /* ssizeargfunc sq_repeat */
- NULL,
- /* ssizeargfunc sq_item */ /* TODO: setting this will allow PySequence_Check to return True. */
- NULL, /* intintargfunc ***was_sq_slice*** */
- NULL, /* intobjargproc sq_ass_item */
- NULL, /* ssizeobjargproc ***was_sq_ass_slice*** */
- (objobjproc)BPy_IDGroup_Contains, /* objobjproc sq_contains */
- NULL, /* binaryfunc sq_inplace_concat */
- NULL, /* ssizeargfunc sq_inplace_repeat */
+ /*sq_length*/ (lenfunc)BPy_IDGroup_Map_Len,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /* TODO: setting this will allow `PySequence_Check()` to return True. */
+ /*sq_item*/ NULL,
+ /*was_sq_slice*/ NULL, /* DEPRECATED. */
+ /*sq_ass_item*/ NULL,
+ /*was_sq_ass_slice*/ NULL, /* DEPRECATED. */
+ /*sq_contains*/ (objobjproc)BPy_IDGroup_Contains,
+ /*sq_inplace_concat*/ NULL,
+ /*sq_inplace_repeat*/ NULL,
};
static PyMappingMethods BPy_IDGroup_Mapping = {
- (lenfunc)BPy_IDGroup_Map_Len, /* inquiry mp_length */
- (binaryfunc)BPy_IDGroup_Map_GetItem, /* binaryfunc mp_subscript */
- (objobjargproc)BPy_IDGroup_Map_SetItem, /* objobjargproc mp_ass_subscript */
+ /*mp_len*/ (lenfunc)BPy_IDGroup_Map_Len,
+ /*mp_subscript*/ (binaryfunc)BPy_IDGroup_Map_GetItem,
+ /*mp_ass_subscript*/ (objobjargproc)BPy_IDGroup_Map_SetItem,
};
PyTypeObject BPy_IDGroup_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
- /* For printing, in format "<module>.<name>" */
- "IDPropertyGroup", /* char *tp_name; */
- sizeof(BPy_IDProperty), /* int tp_basicsize; */
- 0, /* tp_itemsize; For allocation */
-
- /* Methods to implement standard operations */
-
- NULL, /* destructor tp_dealloc; */
- 0, /* tp_vectorcall_offset */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL, /* cmpfunc tp_compare; */
- (reprfunc)BPy_IDGroup_repr, /* reprfunc tp_repr; */
-
- /* Method suites for standard classes */
-
- NULL, /* PyNumberMethods *tp_as_number; */
- &BPy_IDGroup_Seq, /* PySequenceMethods *tp_as_sequence; */
- &BPy_IDGroup_Mapping, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- (hashfunc)BPy_IDGroup_hash, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
- NULL, /* getattrofunc tp_getattro; */
- NULL, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons ***/
- NULL, /* richcmpfunc tp_richcompare; */
-
- /*** weak reference enabler ***/
- 0, /* long tp_weaklistoffset; */
-
- /*** Added in release 2.2 ***/
- /* Iterators */
- (getiterfunc)BPy_IDGroup_iter, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
- /*** Attribute descriptor and subclassing stuff ***/
- BPy_IDGroup_methods, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- BPy_IDGroup_getseters, /* struct PyGetSetDef *tp_getset; */
+ /* For printing, in format `<module>.<name>`. */
+ /*tp_name*/ "IDPropertyGroup",
+ /*tp_basicsize*/ sizeof(BPy_IDProperty),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ NULL,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ (reprfunc)BPy_IDGroup_repr,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ &BPy_IDGroup_Seq,
+ /*tp_as_mapping*/ &BPy_IDGroup_Mapping,
+ /*tp_hash*/ (hashfunc)BPy_IDGroup_hash,
+ /*tp_call*/ NULL,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ NULL,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ (getiterfunc)BPy_IDGroup_iter,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ BPy_IDGroup_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ BPy_IDGroup_getseters,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ NULL,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
/** \} */
@@ -1690,12 +1695,12 @@ static PyMethodDef BPy_IDArray_methods[] = {
{NULL, NULL, 0, NULL},
};
-static int BPy_IDArray_Len(BPy_IDArray *self)
+static Py_ssize_t BPy_IDArray_Len(BPy_IDArray *self)
{
return self->prop->len;
}
-static PyObject *BPy_IDArray_GetItem(BPy_IDArray *self, int index)
+static PyObject *BPy_IDArray_GetItem(BPy_IDArray *self, Py_ssize_t index)
{
if (index < 0 || index >= self->prop->len) {
PyErr_SetString(PyExc_IndexError, "index out of range!");
@@ -1717,7 +1722,7 @@ static PyObject *BPy_IDArray_GetItem(BPy_IDArray *self, int index)
return NULL;
}
-static int BPy_IDArray_SetItem(BPy_IDArray *self, int index, PyObject *value)
+static int BPy_IDArray_SetItem(BPy_IDArray *self, Py_ssize_t index, PyObject *value)
{
if (index < 0 || index >= self->prop->len) {
PyErr_SetString(PyExc_RuntimeError, "index out of range!");
@@ -1755,17 +1760,16 @@ static int BPy_IDArray_SetItem(BPy_IDArray *self, int index, PyObject *value)
}
static PySequenceMethods BPy_IDArray_Seq = {
- (lenfunc)BPy_IDArray_Len, /* inquiry sq_length */
- NULL, /* binaryfunc sq_concat */
- NULL, /* intargfunc sq_repeat */
- (ssizeargfunc)BPy_IDArray_GetItem, /* intargfunc sq_item */
- NULL, /* intintargfunc sq_slice */
- (ssizeobjargproc)BPy_IDArray_SetItem, /* intobjargproc sq_ass_item */
- NULL, /* intintobjargproc sq_ass_slice */
- NULL, /* objobjproc sq_contains */
- /* Added in release 2.0 */
- NULL, /* binaryfunc sq_inplace_concat */
- NULL, /* intargfunc sq_inplace_repeat */
+ /*sq_length*/ (lenfunc)BPy_IDArray_Len,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /*sq_item*/ (ssizeargfunc)BPy_IDArray_GetItem,
+ /*was_sq_slice*/ NULL, /* DEPRECATED. */
+ /*sq_ass_item*/ (ssizeobjargproc)BPy_IDArray_SetItem,
+ /*was_sq_ass_slice*/ NULL, /* DEPRECATED. */
+ /*sq_contains*/ NULL,
+ /*sq_inplace_concat*/ NULL,
+ /*sq_inplace_repeat*/ NULL,
};
/* sequence slice (get): idparr[a:b] */
@@ -1913,9 +1917,9 @@ static int BPy_IDArray_ass_subscript(BPy_IDArray *self, PyObject *item, PyObject
}
static PyMappingMethods BPy_IDArray_AsMapping = {
- (lenfunc)BPy_IDArray_Len,
- (binaryfunc)BPy_IDArray_subscript,
- (objobjargproc)BPy_IDArray_ass_subscript,
+ /*mp_len*/ (lenfunc)BPy_IDArray_Len,
+ /*mp_subscript*/ (binaryfunc)BPy_IDArray_subscript,
+ /*mp_ass_subscript*/ (objobjargproc)BPy_IDArray_ass_subscript,
};
static int itemsize_by_idarray_type(int array_type)
@@ -1958,8 +1962,8 @@ static void BPy_IDArray_releasebuffer(BPy_IDArray *UNUSED(self), Py_buffer *view
}
static PyBufferProcs BPy_IDArray_Buffer = {
- (getbufferproc)BPy_IDArray_getbuffer,
- (releasebufferproc)BPy_IDArray_releasebuffer,
+ /*bf_getbuffer*/ (getbufferproc)BPy_IDArray_getbuffer,
+ /*bf_releasebuffer*/ (releasebufferproc)BPy_IDArray_releasebuffer,
};
/** \} */
@@ -1970,83 +1974,55 @@ static PyBufferProcs BPy_IDArray_Buffer = {
PyTypeObject BPy_IDArray_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
- /* For printing, in format "<module>.<name>" */
- "IDPropertyArray", /* char *tp_name; */
- sizeof(BPy_IDArray), /* int tp_basicsize; */
- 0, /* tp_itemsize; For allocation */
-
- /* Methods to implement standard operations */
-
- NULL, /* destructor tp_dealloc; */
- 0, /* tp_vectorcall_offset */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL, /* cmpfunc tp_compare; */
- (reprfunc)BPy_IDArray_repr, /* reprfunc tp_repr; */
-
- /* Method suites for standard classes */
-
- NULL, /* PyNumberMethods *tp_as_number; */
- &BPy_IDArray_Seq, /* PySequenceMethods *tp_as_sequence; */
- &BPy_IDArray_AsMapping, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- NULL, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
- NULL, /* getattrofunc tp_getattro; */
- NULL, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- &BPy_IDArray_Buffer, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons ***/
- NULL, /* richcmpfunc tp_richcompare; */
-
- /*** weak reference enabler ***/
- 0, /* long tp_weaklistoffset; */
-
- /*** Added in release 2.2 ***/
- /* Iterators */
- NULL, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
-
- /*** Attribute descriptor and subclassing stuff ***/
- BPy_IDArray_methods, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- BPy_IDArray_getseters, /* struct PyGetSetDef *tp_getset; */
- NULL, /* struct _typeobject *tp_base; */
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- 0, /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- NULL, /* newfunc tp_new; */
- /* Low-level free-memory routine */
- NULL, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL,
+ /* For printing, in format `<module>.<name>`. */
+ /*tp_name*/ "IDPropertyArray",
+ /*tp_basicsize*/ sizeof(BPy_IDArray),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ NULL,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ (reprfunc)BPy_IDArray_repr,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ &BPy_IDArray_Seq,
+ /*tp_as_mapping*/ &BPy_IDArray_AsMapping,
+ /*tp_hash*/ NULL,
+ /*tp_call*/ NULL,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ &BPy_IDArray_Buffer,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ NULL,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ BPy_IDArray_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ BPy_IDArray_getseters,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ NULL,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
/** \} */
@@ -2087,6 +2063,7 @@ static BPy_IDGroup_View *IDGroup_View_New_WithType(BPy_IDProperty *group, PyType
iter->group = group;
if (group != NULL) {
Py_INCREF(group);
+ BLI_assert(!PyObject_GC_IsTracked((PyObject *)iter));
PyObject_GC_Track(iter);
}
return iter;
@@ -2115,14 +2092,14 @@ static PyObject *BPy_IDGroup_ViewItems_CreatePyObject(BPy_IDProperty *group)
static struct PyModuleDef IDProp_types_module_def = {
PyModuleDef_HEAD_INIT,
- "idprop.types", /* m_name */
- NULL, /* m_doc */
- 0, /* m_size */
- NULL, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "idprop.types",
+ /*m_doc*/ NULL,
+ /*m_size*/ 0,
+ /*m_methods*/ NULL,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
static PyObject *BPyInit_idprop_types(void)
@@ -2164,14 +2141,14 @@ PyDoc_STRVAR(IDProp_module_doc,
"This module provides access id property types (currently mainly for docs).");
static struct PyModuleDef IDProp_module_def = {
PyModuleDef_HEAD_INIT,
- "idprop", /* m_name */
- IDProp_module_doc, /* m_doc */
- 0, /* m_size */
- IDProp_methods, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "idprop",
+ /*m_doc*/ IDProp_module_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ IDProp_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPyInit_idprop(void)
diff --git a/source/blender/python/generic/idprop_py_ui_api.c b/source/blender/python/generic/idprop_py_ui_api.c
index 890ba997548..4487a885a6c 100644
--- a/source/blender/python/generic/idprop_py_ui_api.c
+++ b/source/blender/python/generic/idprop_py_ui_api.c
@@ -660,63 +660,55 @@ static Py_hash_t BPy_IDPropertyUIManager_hash(BPy_IDPropertyUIManager *self)
PyTypeObject BPy_IDPropertyUIManager_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
- /* For printing, in format "<module>.<name>" */
- "IDPropertyUIManager", /* char *tp_name; */
- sizeof(BPy_IDPropertyUIManager), /* int tp_basicsize; */
- 0, /* tp_itemsize; For allocation */
-
- /* Methods to implement standard operations */
-
- NULL, /* destructor tp_dealloc; */
- 0, /* tp_vectorcall_offset */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL, /* cmpfunc tp_compare; */
- (reprfunc)BPy_IDPropertyUIManager_repr, /* reprfunc tp_repr; */
-
- /* Method suites for standard classes */
-
- NULL, /* PyNumberMethods *tp_as_number; */
- NULL, /* PySequenceMethods *tp_as_sequence; */
- NULL, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- (hashfunc)BPy_IDPropertyUIManager_hash, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
- NULL, /* getattrofunc tp_getattro; */
- NULL, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons ***/
- NULL, /* richcmpfunc tp_richcompare; */
-
- /*** weak reference enabler ***/
- 0, /* long tp_weaklistoffset; */
-
- /*** Added in release 2.2 ***/
- /* Iterators */
- NULL, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
- /*** Attribute descriptor and subclassing stuff ***/
- BPy_IDPropertyUIManager_methods, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- NULL, /* struct PyGetSetDef *tp_getset; */
+ /* For printing, in format `<module>.<name>`. */
+ /*tp_name*/ "IDPropertyUIManager",
+ /*tp_basicsize*/ sizeof(BPy_IDPropertyUIManager),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ NULL,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ (reprfunc)BPy_IDPropertyUIManager_repr,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ NULL,
+ /*tp_as_mapping*/ NULL,
+ /*tp_hash*/ (hashfunc)BPy_IDPropertyUIManager_hash,
+ /*tp_call*/ NULL,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ NULL,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ BPy_IDPropertyUIManager_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ NULL,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ NULL,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
void IDPropertyUIData_Init_Types()
diff --git a/source/blender/python/generic/imbuf_py_api.c b/source/blender/python/generic/imbuf_py_api.c
index 056af83cc49..77d450d496e 100644
--- a/source/blender/python/generic/imbuf_py_api.c
+++ b/source/blender/python/generic/imbuf_py_api.c
@@ -150,13 +150,13 @@ static PyObject *py_imbuf_crop(Py_ImBuf *self, PyObject *args, PyObject *kw)
}
if (/* X range. */
- (!(crop.xmin >= 0 && crop.xmax < self->ibuf->x)) ||
+ !(crop.xmin >= 0 && crop.xmax < self->ibuf->x) ||
/* Y range. */
- (!(crop.ymin >= 0 && crop.ymax < self->ibuf->y)) ||
+ !(crop.ymin >= 0 && crop.ymax < self->ibuf->y) ||
/* X order. */
- (!(crop.xmin <= crop.xmax)) ||
+ !(crop.xmin <= crop.xmax) ||
/* Y order. */
- (!(crop.ymin <= crop.ymax))) {
+ !(crop.ymin <= crop.ymax)) {
PyErr_SetString(PyExc_ValueError, "ImBuf crop min/max not in range");
return NULL;
}
@@ -348,63 +348,54 @@ static Py_hash_t py_imbuf_hash(Py_ImBuf *self)
PyTypeObject Py_ImBuf_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
- /* For printing, in format "<module>.<name>" */
- "ImBuf", /* tp_name */
- sizeof(Py_ImBuf), /* int tp_basicsize; */
- 0, /* tp_itemsize; For allocation */
-
- /* Methods to implement standard operations */
-
- (destructor)py_imbuf_dealloc, /* destructor tp_dealloc; */
- 0, /* tp_vectorcall_offset */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL, /* cmpfunc tp_compare; */
- (reprfunc)py_imbuf_repr, /* reprfunc tp_repr; */
-
- /* Method suites for standard classes */
-
- NULL, /* PyNumberMethods *tp_as_number; */
- NULL, /* PySequenceMethods *tp_as_sequence; */
- NULL, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- (hashfunc)py_imbuf_hash, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
- NULL, /* getattrofunc tp_getattro; */
- NULL, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons ***/
- NULL, /* richcmpfunc tp_richcompare; */
-
- /*** weak reference enabler ***/
- 0, /* long tp_weaklistoffset; */
-
- /*** Added in release 2.2 ***/
- /* Iterators */
- NULL, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
- /*** Attribute descriptor and subclassing stuff ***/
- Py_ImBuf_methods, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- Py_ImBuf_getseters, /* struct PyGetSetDef *tp_getset; */
+ /*tp_name*/ "ImBuf",
+ /*tp_basicsize*/ sizeof(Py_ImBuf),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)py_imbuf_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ (reprfunc)py_imbuf_repr,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ NULL,
+ /*tp_as_mapping*/ NULL,
+ /*tp_hash*/ (hashfunc)py_imbuf_hash,
+ /*tp_call*/ NULL,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ NULL,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ Py_ImBuf_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ Py_ImBuf_getseters,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ NULL,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
static PyObject *Py_ImBuf_CreatePyObject(ImBuf *ibuf)
@@ -566,14 +557,14 @@ PyDoc_STRVAR(IMB_doc,
":class:`bpy.types.Image` data-block context.\n");
static struct PyModuleDef IMB_module_def = {
PyModuleDef_HEAD_INIT,
- "imbuf", /* m_name */
- IMB_doc, /* m_doc */
- 0, /* m_size */
- IMB_methods, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "imbuf",
+ /*m_doc*/ IMB_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ IMB_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPyInit_imbuf(void)
@@ -610,14 +601,14 @@ PyDoc_STRVAR(IMB_types_doc,
static struct PyModuleDef IMB_types_module_def = {
PyModuleDef_HEAD_INIT,
- "imbuf.types", /* m_name */
- IMB_types_doc, /* m_doc */
- 0, /* m_size */
- NULL, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "imbuf.types",
+ /*m_doc*/ IMB_types_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ NULL,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPyInit_imbuf_types(void)
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index 007a2fdbb8e..9e140bbe7bd 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -28,8 +28,8 @@
# include "BLI_string.h"
-/* Only for BLI_strncpy_wchar_from_utf8,
- * should replace with py funcs but too late in release now. */
+/* Only for #BLI_strncpy_wchar_from_utf8,
+ * should replace with Python functions but too late in release now. */
# include "BLI_string_utf8.h"
#endif
@@ -1475,7 +1475,7 @@ bool PyC_RunString_AsNumber(const char *imports[],
PyErr_Clear();
}
- if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
+ if (imports && !PyC_NameSpace_ImportArray(py_dict, imports)) {
ok = false;
}
else if ((retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict)) == NULL) {
@@ -1533,7 +1533,7 @@ bool PyC_RunString_AsIntPtr(const char *imports[],
py_dict = PyC_DefaultNameSpace(filename);
- if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
+ if (imports && !PyC_NameSpace_ImportArray(py_dict, imports)) {
ok = false;
}
else if ((retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict)) == NULL) {
@@ -1572,7 +1572,7 @@ bool PyC_RunString_AsStringAndSize(const char *imports[],
py_dict = PyC_DefaultNameSpace(filename);
- if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
+ if (imports && !PyC_NameSpace_ImportArray(py_dict, imports)) {
ok = false;
}
else if ((retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict)) == NULL) {
diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h
index 91ebef8d0b0..51e36892cbd 100644
--- a/source/blender/python/generic/py_capi_utils.h
+++ b/source/blender/python/generic/py_capi_utils.h
@@ -275,8 +275,8 @@ bool PyC_StructFmt_type_is_int_any(char format);
bool PyC_StructFmt_type_is_byte(char format);
bool PyC_StructFmt_type_is_bool(char format);
-#endif /* __PY_CAPI_UTILS_H__ */
-
#ifdef __cplusplus
}
#endif
+
+#endif /* __PY_CAPI_UTILS_H__ */
diff --git a/source/blender/python/gpu/gpu_py_api.c b/source/blender/python/gpu/gpu_py_api.c
index a2075566f31..8f5897be649 100644
--- a/source/blender/python/gpu/gpu_py_api.c
+++ b/source/blender/python/gpu/gpu_py_api.c
@@ -32,8 +32,14 @@ PyDoc_STRVAR(pygpu_doc,
"Some higher level functions can be found in the `gpu_extras` module.");
static struct PyModuleDef pygpu_module_def = {
PyModuleDef_HEAD_INIT,
- .m_name = "gpu",
- .m_doc = pygpu_doc,
+ /*m_name*/ "gpu",
+ /*m_doc*/ pygpu_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ NULL,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPyInit_gpu(void)
diff --git a/source/blender/python/gpu/gpu_py_batch.c b/source/blender/python/gpu/gpu_py_batch.c
index 533e5154d83..a36b1dfd1b5 100644
--- a/source/blender/python/gpu/gpu_py_batch.c
+++ b/source/blender/python/gpu/gpu_py_batch.c
@@ -111,6 +111,7 @@ static PyObject *pygpu_batch__tp_new(PyTypeObject *UNUSED(type), PyObject *args,
Py_INCREF(py_indexbuf);
}
+ BLI_assert(!PyObject_GC_IsTracked((PyObject *)ret));
PyObject_GC_Track(ret);
#endif
@@ -127,7 +128,7 @@ PyDoc_STRVAR(pygpu_batch_vertbuf_add_doc,
" vertex buffer for vertex positions and vertex normals.\n"
" Current a batch can have at most " STRINGIFY(GPU_BATCH_VBO_MAX_LEN) " vertex buffers.\n"
"\n"
-" :param buf: The vertex buffer that will be added to the batch.\n"
+" :arg buf: The vertex buffer that will be added to the batch.\n"
" :type buf: :class:`gpu.types.GPUVertBuf`\n"
);
static PyObject *pygpu_batch_vertbuf_add(BPyGPUBatch *self, BPyGPUVertBuf *py_buf)
@@ -171,7 +172,7 @@ PyDoc_STRVAR(
" This function does not need to be called when you always\n"
" set the shader when calling :meth:`gpu.types.GPUBatch.draw`.\n"
"\n"
- " :param program: The program/shader the batch will use in future draw calls.\n"
+ " :arg program: The program/shader the batch will use in future draw calls.\n"
" :type program: :class:`gpu.types.GPUShader`\n");
static PyObject *pygpu_batch_program_set(BPyGPUBatch *self, BPyGPUShader *py_shader)
{
@@ -209,7 +210,7 @@ PyDoc_STRVAR(pygpu_batch_draw_doc,
"\n"
" Run the drawing program with the parameters assigned to the batch.\n"
"\n"
- " :param program: Program that performs the drawing operations.\n"
+ " :arg program: Program that performs the drawing operations.\n"
" If ``None`` is passed, the last program set to this batch will run.\n"
" :type program: :class:`gpu.types.GPUShader`\n");
static PyObject *pygpu_batch_draw(BPyGPUBatch *self, PyObject *args)
@@ -273,6 +274,11 @@ static int pygpu_batch__tp_clear(BPyGPUBatch *self)
return 0;
}
+static int pygpu_batch__tp_is_gc(BPyGPUBatch *self)
+{
+ return self->references != NULL;
+}
+
#endif
static void pygpu_batch__tp_dealloc(BPyGPUBatch *self)
@@ -313,6 +319,7 @@ PyTypeObject BPyGPUBatch_Type = {
.tp_doc = pygpu_batch__tp_doc,
.tp_traverse = (traverseproc)pygpu_batch__tp_traverse,
.tp_clear = (inquiry)pygpu_batch__tp_clear,
+ .tp_is_gc = (inquiry)pygpu_batch__tp_is_gc,
#else
.tp_flags = Py_TPFLAGS_DEFAULT,
#endif
diff --git a/source/blender/python/gpu/gpu_py_buffer.c b/source/blender/python/gpu/gpu_py_buffer.c
index 020535d002a..51bda9b4941 100644
--- a/source/blender/python/gpu/gpu_py_buffer.c
+++ b/source/blender/python/gpu/gpu_py_buffer.c
@@ -61,7 +61,7 @@ static bool pygpu_buffer_pyobj_as_shape(PyObject *shape_obj,
Py_ssize_t shape_len = 0;
if (PyLong_Check(shape_obj)) {
shape_len = 1;
- if (((r_shape[0] = PyLong_AsLong(shape_obj)) < 1)) {
+ if ((r_shape[0] = PyLong_AsLong(shape_obj)) < 1) {
PyErr_SetString(PyExc_AttributeError, "dimension must be greater than or equal to 1");
return false;
}
@@ -100,7 +100,7 @@ static bool pygpu_buffer_pyobj_as_shape(PyObject *shape_obj,
}
else {
PyErr_Format(PyExc_TypeError,
- "invalid second argument argument expected a sequence "
+ "invalid second argument expected a sequence "
"or an int, not a %.200s",
Py_TYPE(shape_obj)->tp_name);
}
@@ -153,12 +153,13 @@ static BPyGPUBuffer *pygpu_buffer_make_from_data(PyObject *parent,
if (parent) {
Py_INCREF(parent);
buffer->parent = parent;
+ BLI_assert(!PyObject_GC_IsTracked((PyObject *)buffer));
PyObject_GC_Track(buffer);
}
return buffer;
}
-static PyObject *pygpu_buffer__sq_item(BPyGPUBuffer *self, int i)
+static PyObject *pygpu_buffer__sq_item(BPyGPUBuffer *self, Py_ssize_t i)
{
if (i >= self->shape[0] || i < 0) {
PyErr_SetString(PyExc_IndexError, "array index out of range");
@@ -199,10 +200,10 @@ static PyObject *pygpu_buffer__sq_item(BPyGPUBuffer *self, int i)
static PyObject *pygpu_buffer_to_list(BPyGPUBuffer *self)
{
- int i, len = self->shape[0];
+ const Py_ssize_t len = self->shape[0];
PyObject *list = PyList_New(len);
- for (i = 0; i < len; i++) {
+ for (Py_ssize_t i = 0; i < len; i++) {
PyList_SET_ITEM(list, i, pygpu_buffer__sq_item(self, i));
}
@@ -312,7 +313,7 @@ static PyObject *pygpu_buffer__tp_repr(BPyGPUBuffer *self)
return repr;
}
-static int pygpu_buffer__sq_ass_item(BPyGPUBuffer *self, int i, PyObject *v);
+static int pygpu_buffer__sq_ass_item(BPyGPUBuffer *self, Py_ssize_t i, PyObject *v);
static int pygpu_buffer_ass_slice(BPyGPUBuffer *self,
Py_ssize_t begin,
@@ -422,9 +423,14 @@ static PyObject *pygpu_buffer__tp_new(PyTypeObject *UNUSED(type), PyObject *args
return (PyObject *)buffer;
}
+static int pygpu_buffer__tp_is_gc(BPyGPUBuffer *self)
+{
+ return self->parent != NULL;
+}
+
/* BPyGPUBuffer sequence methods */
-static int pygpu_buffer__sq_length(BPyGPUBuffer *self)
+static Py_ssize_t pygpu_buffer__sq_length(BPyGPUBuffer *self)
{
return self->shape[0];
}
@@ -452,7 +458,7 @@ static PyObject *pygpu_buffer_slice(BPyGPUBuffer *self, Py_ssize_t begin, Py_ssi
return list;
}
-static int pygpu_buffer__sq_ass_item(BPyGPUBuffer *self, int i, PyObject *v)
+static int pygpu_buffer__sq_ass_item(BPyGPUBuffer *self, Py_ssize_t i, PyObject *v)
{
if (i >= self->shape[0] || i < 0) {
PyErr_SetString(PyExc_IndexError, "array assignment index out of range");
@@ -573,22 +579,22 @@ static PyGetSetDef pygpu_buffer_getseters[] = {
};
static PySequenceMethods pygpu_buffer__tp_as_sequence = {
- (lenfunc)pygpu_buffer__sq_length, /* sq_length */
- (binaryfunc)NULL, /* sq_concat */
- (ssizeargfunc)NULL, /* sq_repeat */
- (ssizeargfunc)pygpu_buffer__sq_item, /* sq_item */
- (ssizessizeargfunc)NULL, /* sq_slice, deprecated, handled in pygpu_buffer__sq_item */
- (ssizeobjargproc)pygpu_buffer__sq_ass_item, /* sq_ass_item */
- (ssizessizeobjargproc)NULL, /* sq_ass_slice, deprecated handled in pygpu_buffer__sq_ass_item */
- (objobjproc)NULL, /* sq_contains */
- (binaryfunc)NULL, /* sq_inplace_concat */
- (ssizeargfunc)NULL, /* sq_inplace_repeat */
+ /*sq_length*/ (lenfunc)pygpu_buffer__sq_length,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /*sq_item*/ (ssizeargfunc)pygpu_buffer__sq_item,
+ /*was_sq_slice*/ NULL, /* DEPRECATED. Handled by #pygpu_buffer__sq_item. */
+ /*sq_ass_item*/ (ssizeobjargproc)pygpu_buffer__sq_ass_item,
+ /*was_sq_ass_slice*/ NULL, /* DEPRECATED. Handled by #pygpu_buffer__sq_ass_item. */
+ /*sq_contains*/ NULL,
+ /*sq_inplace_concat*/ NULL,
+ /*sq_inplace_repeat*/ NULL,
};
static PyMappingMethods pygpu_buffer__tp_as_mapping = {
- (lenfunc)pygpu_buffer__sq_length,
- (binaryfunc)pygpu_buffer__mp_subscript,
- (objobjargproc)pygpu_buffer__mp_ass_subscript,
+ /*mp_len*/ (lenfunc)pygpu_buffer__sq_length,
+ /*mp_subscript*/ (binaryfunc)pygpu_buffer__mp_subscript,
+ /*mp_ass_subscript*/ (objobjargproc)pygpu_buffer__mp_ass_subscript,
};
#ifdef PYGPU_BUFFER_PROTOCOL
@@ -642,8 +648,8 @@ static void pygpu_buffer__bf_releasebuffer(PyObject *UNUSED(exporter), Py_buffer
}
static PyBufferProcs pygpu_buffer__tp_as_buffer = {
- (getbufferproc)pygpu_buffer__bf_getbuffer,
- (releasebufferproc)pygpu_buffer__bf_releasebuffer,
+ /*bf_getbuffer*/ (getbufferproc)pygpu_buffer__bf_getbuffer,
+ /*bf_releasebuffer*/ (releasebufferproc)pygpu_buffer__bf_releasebuffer,
};
#endif
@@ -655,7 +661,7 @@ PyDoc_STRVAR(
"\n"
" :arg format: Format type to interpret the buffer.\n"
" Possible values are `FLOAT`, `INT`, `UINT`, `UBYTE`, `UINT_24_8` and `10_11_11_REV`.\n"
- " :type type: str\n"
+ " :type format: str\n"
" :arg dimensions: Array describing the dimensions.\n"
" :type dimensions: int\n"
" :arg data: Optional data array.\n"
@@ -677,6 +683,7 @@ PyTypeObject BPyGPU_BufferType = {
.tp_methods = pygpu_buffer__tp_methods,
.tp_getset = pygpu_buffer_getseters,
.tp_new = pygpu_buffer__tp_new,
+ .tp_is_gc = (inquiry)pygpu_buffer__tp_is_gc,
};
static size_t pygpu_buffer_calc_size(const int format,
diff --git a/source/blender/python/gpu/gpu_py_capabilities.c b/source/blender/python/gpu/gpu_py_capabilities.c
index b892167cd76..2345982eb42 100644
--- a/source/blender/python/gpu/gpu_py_capabilities.c
+++ b/source/blender/python/gpu/gpu_py_capabilities.c
@@ -191,6 +191,40 @@ static PyObject *pygpu_extensions_get(PyObject *UNUSED(self))
return ret;
}
+PyDoc_STRVAR(pygpu_compute_shader_support_get_doc,
+ ".. function:: compute_shader_support_get()\n"
+ "\n"
+ " Are compute shaders supported.\n"
+ "\n"
+ " :return: True when supported, False when not supported.\n"
+ " :rtype: bool\n");
+static PyObject *pygpu_compute_shader_support_get(PyObject *UNUSED(self))
+{
+ return PyBool_FromLong(GPU_compute_shader_support());
+}
+
+PyDoc_STRVAR(pygpu_shader_storage_buffer_objects_support_get_doc,
+ ".. function:: shader_storage_buffer_objects_support_get()\n"
+ "\n"
+ " Are SSBO's supported.\n"
+ "\n"
+ " :return: True when supported, False when not supported.\n"
+ " :rtype: bool\n");
+static PyObject *pygpu_shader_storage_buffer_objects_support_get(PyObject *UNUSED(self))
+{
+ return PyBool_FromLong(GPU_shader_storage_buffer_objects_support());
+}
+PyDoc_STRVAR(pygpu_shader_image_load_store_support_get_doc,
+ ".. function:: shader_image_load_store_support_get()\n"
+ "\n"
+ " Is image load/store supported.\n"
+ "\n"
+ " :return: True when supported, False when not supported.\n"
+ " :rtype: bool\n");
+static PyObject *pygpu_shader_image_load_store_support_get(PyObject *UNUSED(self))
+{
+ return PyBool_FromLong(GPU_shader_image_load_store_support());
+}
/** \} */
/* -------------------------------------------------------------------- */
@@ -247,15 +281,34 @@ static struct PyMethodDef pygpu_capabilities__tp_methods[] = {
METH_NOARGS,
pygpu_max_varying_floats_get_doc},
{"extensions_get", (PyCFunction)pygpu_extensions_get, METH_NOARGS, pygpu_extensions_get_doc},
+
+ {"compute_shader_support_get",
+ (PyCFunction)pygpu_compute_shader_support_get,
+ METH_NOARGS,
+ pygpu_compute_shader_support_get_doc},
+ {"shader_storage_buffer_objects_support_get",
+ (PyCFunction)pygpu_shader_storage_buffer_objects_support_get,
+ METH_NOARGS,
+ pygpu_shader_storage_buffer_objects_support_get_doc},
+ {"shader_image_load_store_support_get",
+ (PyCFunction)pygpu_shader_image_load_store_support_get,
+ METH_NOARGS,
+ pygpu_shader_image_load_store_support_get_doc},
+
{NULL, NULL, 0, NULL},
};
PyDoc_STRVAR(pygpu_capabilities__tp_doc, "This module provides access to the GPU capabilities.");
static PyModuleDef pygpu_capabilities_module_def = {
PyModuleDef_HEAD_INIT,
- .m_name = "gpu.capabilities",
- .m_doc = pygpu_capabilities__tp_doc,
- .m_methods = pygpu_capabilities__tp_methods,
+ /*m_name*/ "gpu.capabilities",
+ /*m_doc*/ pygpu_capabilities__tp_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ pygpu_capabilities__tp_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *bpygpu_capabilities_init(void)
diff --git a/source/blender/python/gpu/gpu_py_element.c b/source/blender/python/gpu/gpu_py_element.c
index d52a97c0c84..46f1d4d49eb 100644
--- a/source/blender/python/gpu/gpu_py_element.c
+++ b/source/blender/python/gpu/gpu_py_element.c
@@ -180,7 +180,7 @@ PyDoc_STRVAR(pygpu_IndexBuf__tp_doc,
" :arg type: The primitive type this index buffer is composed of.\n"
" Possible values are `POINTS`, `LINES`, `TRIS` and `LINE_STRIP_ADJ`.\n"
" :type type: str\n"
- " :param seq: Indices this index buffer will contain.\n"
+ " :arg seq: Indices this index buffer will contain.\n"
" Whether a 1D or 2D sequence is required depends on the type.\n"
" Optionally the sequence can support the buffer protocol.\n"
" :type seq: 1D or 2D sequence\n");
diff --git a/source/blender/python/gpu/gpu_py_framebuffer.c b/source/blender/python/gpu/gpu_py_framebuffer.c
index 9bb2a9137f4..2de8c680b23 100644
--- a/source/blender/python/gpu/gpu_py_framebuffer.c
+++ b/source/blender/python/gpu/gpu_py_framebuffer.c
@@ -421,9 +421,10 @@ PyDoc_STRVAR(pygpu_framebuffer_viewport_set_doc,
" Set the viewport for this framebuffer object.\n"
" Note: The viewport state is not saved upon framebuffer rebind.\n"
"\n"
- " :param x, y: lower left corner of the viewport_set rectangle, in pixels.\n"
- " :param xsize, ysize: width and height of the viewport_set.\n"
- " :type x, y, xsize, ysize: int\n");
+ " :arg x, y: lower left corner of the viewport_set rectangle, in pixels.\n"
+ " :type x, y: int\n"
+ " :arg xsize, ysize: width and height of the viewport_set.\n"
+ " :type xsize, ysize: int\n");
static PyObject *pygpu_framebuffer_viewport_set(BPyGPUFrameBuffer *self,
PyObject *args,
void *UNUSED(type))
@@ -462,16 +463,16 @@ PyDoc_STRVAR(
"\n"
" Read a block of pixels from the frame buffer.\n"
"\n"
- " :param x, y: Lower left corner of a rectangular block of pixels.\n"
- " :param xsize, ysize: Dimensions of the pixel rectangle.\n"
+ " :arg x, y: Lower left corner of a rectangular block of pixels.\n"
+ " :arg xsize, ysize: Dimensions of the pixel rectangle.\n"
" :type x, y, xsize, ysize: int\n"
- " :param channels: Number of components to read.\n"
+ " :arg channels: Number of components to read.\n"
" :type channels: int\n"
- " :param slot: The framebuffer slot to read data from.\n"
+ " :arg slot: The framebuffer slot to read data from.\n"
" :type slot: int\n"
- " :param format: The format that describes the content of a single channel.\n"
+ " :arg format: The format that describes the content of a single channel.\n"
" Possible values are `FLOAT`, `INT`, `UINT`, `UBYTE`, `UINT_24_8` and `10_11_11_REV`.\n"
- " :type type: str\n"
+ " :type format: str\n"
" :arg data: Optional Buffer object to fill with the pixels values.\n"
" :type data: :class:`gpu.types.Buffer`\n"
" :return: The Buffer with the read pixels.\n"
@@ -569,9 +570,10 @@ PyDoc_STRVAR(pygpu_framebuffer_read_depth_doc,
"\n"
" Read a pixel depth block from the frame buffer.\n"
"\n"
- " :param x, y: Lower left corner of a rectangular block of pixels.\n"
- " :param xsize, ysize: Dimensions of the pixel rectangle.\n"
- " :type x, y, xsize, ysize: int\n"
+ " :arg x, y: Lower left corner of a rectangular block of pixels.\n"
+ " :type x, y: int\n"
+ " :arg xsize, ysize: Dimensions of the pixel rectangle.\n"
+ " :type xsize, ysize: int\n"
" :arg data: Optional Buffer object to fill with the pixels values.\n"
" :type data: :class:`gpu.types.Buffer`\n"
" :return: The Buffer with the read pixels.\n"
diff --git a/source/blender/python/gpu/gpu_py_matrix.c b/source/blender/python/gpu/gpu_py_matrix.c
index a47e3dc8a5f..7d80f763162 100644
--- a/source/blender/python/gpu/gpu_py_matrix.c
+++ b/source/blender/python/gpu/gpu_py_matrix.c
@@ -266,7 +266,7 @@ PyDoc_STRVAR(pygpu_matrix_multiply_matrix_doc,
"\n"
" Multiply the current stack matrix.\n"
"\n"
- " :param matrix: A 4x4 matrix.\n"
+ " :arg matrix: A 4x4 matrix.\n"
" :type matrix: :class:`mathutils.Matrix`\n");
static PyObject *pygpu_matrix_multiply_matrix(PyObject *UNUSED(self), PyObject *value)
{
@@ -283,7 +283,7 @@ PyDoc_STRVAR(pygpu_matrix_scale_doc,
"\n"
" Scale the current stack matrix.\n"
"\n"
- " :param scale: Scale the current stack matrix.\n"
+ " :arg scale: Scale the current stack matrix.\n"
" :type scale: sequence of 2 or 3 floats\n");
static PyObject *pygpu_matrix_scale(PyObject *UNUSED(self), PyObject *value)
{
@@ -305,7 +305,7 @@ static PyObject *pygpu_matrix_scale(PyObject *UNUSED(self), PyObject *value)
PyDoc_STRVAR(pygpu_matrix_scale_uniform_doc,
".. function:: scale_uniform(scale)\n"
"\n"
- " :param scale: Scale the current stack matrix.\n"
+ " :arg scale: Scale the current stack matrix.\n"
" :type scale: float\n");
static PyObject *pygpu_matrix_scale_uniform(PyObject *UNUSED(self), PyObject *value)
{
@@ -323,7 +323,7 @@ PyDoc_STRVAR(pygpu_matrix_translate_doc,
"\n"
" Scale the current stack matrix.\n"
"\n"
- " :param offset: Translate the current stack matrix.\n"
+ " :arg offset: Translate the current stack matrix.\n"
" :type offset: sequence of 2 or 3 floats\n");
static PyObject *pygpu_matrix_translate(PyObject *UNUSED(self), PyObject *value)
{
@@ -373,7 +373,7 @@ PyDoc_STRVAR(pygpu_matrix_load_matrix_doc,
"\n"
" Load a matrix into the stack.\n"
"\n"
- " :param matrix: A 4x4 matrix.\n"
+ " :arg matrix: A 4x4 matrix.\n"
" :type matrix: :class:`mathutils.Matrix`\n");
static PyObject *pygpu_matrix_load_matrix(PyObject *UNUSED(self), PyObject *value)
{
@@ -390,7 +390,7 @@ PyDoc_STRVAR(pygpu_matrix_load_projection_matrix_doc,
"\n"
" Load a projection matrix into the stack.\n"
"\n"
- " :param matrix: A 4x4 matrix.\n"
+ " :arg matrix: A 4x4 matrix.\n"
" :type matrix: :class:`mathutils.Matrix`\n");
static PyObject *pygpu_matrix_load_projection_matrix(PyObject *UNUSED(self), PyObject *value)
{
@@ -528,9 +528,14 @@ static struct PyMethodDef pygpu_matrix__tp_methods[] = {
PyDoc_STRVAR(pygpu_matrix__tp_doc, "This module provides access to the matrix stack.");
static PyModuleDef pygpu_matrix_module_def = {
PyModuleDef_HEAD_INIT,
- .m_name = "gpu.matrix",
- .m_doc = pygpu_matrix__tp_doc,
- .m_methods = pygpu_matrix__tp_methods,
+ /*m_name*/ "gpu.matrix",
+ /*m_doc*/ pygpu_matrix__tp_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ pygpu_matrix__tp_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *bpygpu_matrix_init(void)
diff --git a/source/blender/python/gpu/gpu_py_platform.c b/source/blender/python/gpu/gpu_py_platform.c
index b877e3ceb98..5f9f653a3c4 100644
--- a/source/blender/python/gpu/gpu_py_platform.c
+++ b/source/blender/python/gpu/gpu_py_platform.c
@@ -11,6 +11,7 @@
#include "BLI_utildefines.h"
+#include "GPU_context.h"
#include "GPU_platform.h"
#include "gpu_py_platform.h" /* Own include. */
@@ -83,6 +84,30 @@ static PyObject *pygpu_platform_device_type_get(PyObject *UNUSED(self))
return PyUnicode_FromString("UNKNOWN");
}
+PyDoc_STRVAR(pygpu_platform_backend_type_get_doc,
+ ".. function:: backend_type_get()\n"
+ "\n"
+ " Get actuve GPU backend.\n"
+ "\n"
+ " :return: Backend type ('OPENGL', 'VULKAN', 'METAL', 'NONE', 'UNKNOWN').\n"
+ " :rtype: str\n");
+static PyObject *pygpu_platform_backend_type_get(PyObject *UNUSED(self))
+{
+ switch (GPU_backend_get_type()) {
+ case GPU_BACKEND_VULKAN:
+ return PyUnicode_FromString("VULKAN");
+ case GPU_BACKEND_METAL:
+ return PyUnicode_FromString("METAL");
+ case GPU_BACKEND_NONE:
+ return PyUnicode_FromString("NONE");
+ case GPU_BACKEND_OPENGL:
+ return PyUnicode_FromString("OPENGL");
+ case GPU_BACKEND_ANY:
+ break;
+ }
+ return PyUnicode_FromString("UNKNOWN");
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -106,15 +131,24 @@ static struct PyMethodDef pygpu_platform__tp_methods[] = {
(PyCFunction)pygpu_platform_device_type_get,
METH_NOARGS,
pygpu_platform_device_type_get_doc},
+ {"backend_type_get",
+ (PyCFunction)pygpu_platform_backend_type_get,
+ METH_NOARGS,
+ pygpu_platform_backend_type_get_doc},
{NULL, NULL, 0, NULL},
};
PyDoc_STRVAR(pygpu_platform__tp_doc, "This module provides access to GPU Platform definitions.");
static PyModuleDef pygpu_platform_module_def = {
PyModuleDef_HEAD_INIT,
- .m_name = "gpu.platform",
- .m_doc = pygpu_platform__tp_doc,
- .m_methods = pygpu_platform__tp_methods,
+ /*m_name*/ "gpu.platform",
+ /*m_doc*/ pygpu_platform__tp_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ pygpu_platform__tp_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *bpygpu_platform_init(void)
diff --git a/source/blender/python/gpu/gpu_py_select.c b/source/blender/python/gpu/gpu_py_select.c
index 8869ea38e32..02e06e0ffd5 100644
--- a/source/blender/python/gpu/gpu_py_select.c
+++ b/source/blender/python/gpu/gpu_py_select.c
@@ -31,7 +31,7 @@ PyDoc_STRVAR(pygpu_select_load_id_doc,
"\n"
" Set the selection ID.\n"
"\n"
- " :param id: Number (32-bit uint).\n"
+ " :arg id: Number (32-bit uint).\n"
" :type select: int\n");
static PyObject *pygpu_select_load_id(PyObject *UNUSED(self), PyObject *value)
{
@@ -58,9 +58,14 @@ static struct PyMethodDef pygpu_select__tp_methods[] = {
PyDoc_STRVAR(pygpu_select__tp_doc, "This module provides access to selection.");
static PyModuleDef pygpu_select_module_def = {
PyModuleDef_HEAD_INIT,
- .m_name = "gpu.select",
- .m_doc = pygpu_select__tp_doc,
- .m_methods = pygpu_select__tp_methods,
+ /*m_name*/ "gpu.select",
+ /*m_doc*/ pygpu_select__tp_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ pygpu_select__tp_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *bpygpu_select_init(void)
diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c
index fbc45124147..7222cb1696a 100644
--- a/source/blender/python/gpu/gpu_py_shader.c
+++ b/source/blender/python/gpu/gpu_py_shader.c
@@ -163,7 +163,7 @@ PyDoc_STRVAR(pygpu_shader_uniform_from_name_doc,
"\n"
" Get uniform location by name.\n"
"\n"
- " :param name: Name of the uniform variable whose location is to be queried.\n"
+ " :arg name: Name of the uniform variable whose location is to be queried.\n"
" :type name: str\n"
" :return: Location of the uniform variable.\n"
" :rtype: int\n");
@@ -184,16 +184,15 @@ static PyObject *pygpu_shader_uniform_from_name(BPyGPUShader *self, PyObject *ar
return PyLong_FromLong(uniform);
}
-PyDoc_STRVAR(
- pygpu_shader_uniform_block_from_name_doc,
- ".. method:: uniform_block_from_name(name)\n"
- "\n"
- " Get uniform block location by name.\n"
- "\n"
- " :param name: Name of the uniform block variable whose location is to be queried.\n"
- " :type name: str\n"
- " :return: The location of the uniform block variable.\n"
- " :rtype: int\n");
+PyDoc_STRVAR(pygpu_shader_uniform_block_from_name_doc,
+ ".. method:: uniform_block_from_name(name)\n"
+ "\n"
+ " Get uniform block location by name.\n"
+ "\n"
+ " :arg name: Name of the uniform block variable whose location is to be queried.\n"
+ " :type name: str\n"
+ " :return: The location of the uniform block variable.\n"
+ " :rtype: int\n");
static PyObject *pygpu_shader_uniform_block_from_name(BPyGPUShader *self, PyObject *arg)
{
const char *name = PyUnicode_AsUTF8(arg);
@@ -245,11 +244,11 @@ PyDoc_STRVAR(pygpu_shader_uniform_vector_float_doc,
"\n"
" Set the buffer to fill the uniform.\n"
"\n"
- " :param location: Location of the uniform variable to be modified.\n"
+ " :arg location: Location of the uniform variable to be modified.\n"
" :type location: int\n"
- " :param buffer: The data that should be set. Can support the buffer protocol.\n"
+ " :arg buffer: The data that should be set. Can support the buffer protocol.\n"
" :type buffer: sequence of floats\n"
- " :param length: Size of the uniform data type:\n\n"
+ " :arg length: Size of the uniform data type:\n\n"
" - 1: float\n"
" - 2: vec2 or float[2]\n"
" - 3: vec3 or float[3]\n"
@@ -257,7 +256,7 @@ PyDoc_STRVAR(pygpu_shader_uniform_vector_float_doc,
" - 9: mat3\n"
" - 16: mat4\n"
" :type length: int\n"
- " :param count: Specifies the number of elements, vector or matrices that are to "
+ " :arg count: Specifies the number of elements, vector or matrices that are to "
"be modified.\n"
" :type count: int\n");
static PyObject *pygpu_shader_uniform_vector_float(BPyGPUShader *self, PyObject *args)
@@ -271,6 +270,7 @@ static PyObject *pygpu_shader_uniform_vector_float(BPyGPUShader *self, PyObject
return NULL;
}
+ GPU_shader_bind(self->shader);
GPU_shader_uniform_vector(self->shader, location, length, count, pybuffer.buf);
PyBuffer_Release(&pybuffer);
@@ -293,6 +293,7 @@ static PyObject *pygpu_shader_uniform_vector_int(BPyGPUShader *self, PyObject *a
return NULL;
}
+ GPU_shader_bind(self->shader);
GPU_shader_uniform_vector_int(self->shader, location, length, count, pybuffer.buf);
PyBuffer_Release(&pybuffer);
@@ -301,14 +302,14 @@ static PyObject *pygpu_shader_uniform_vector_int(BPyGPUShader *self, PyObject *a
}
PyDoc_STRVAR(pygpu_shader_uniform_bool_doc,
- ".. method:: uniform_bool(name, seq)\n"
+ ".. method:: uniform_bool(name, value)\n"
"\n"
" Specify the value of a uniform variable for the current program object.\n"
"\n"
- " :param name: Name of the uniform variable whose value is to be changed.\n"
+ " :arg name: Name of the uniform variable whose value is to be changed.\n"
" :type name: str\n"
- " :param seq: Value that will be used to update the specified uniform variable.\n"
- " :type seq: sequence of bools\n");
+ " :arg value: Value that will be used to update the specified uniform variable.\n"
+ " :type value: bool or sequence of bools\n");
static PyObject *pygpu_shader_uniform_bool(BPyGPUShader *self, PyObject *args)
{
const char *error_prefix = "GPUShader.uniform_bool";
@@ -324,15 +325,14 @@ static PyObject *pygpu_shader_uniform_bool(BPyGPUShader *self, PyObject *args)
int values[4];
int length;
- int ret;
- {
+ int ret = -1;
+ if (PySequence_Check(params.seq)) {
PyObject *seq_fast = PySequence_Fast(params.seq, error_prefix);
if (seq_fast == NULL) {
PyErr_Format(PyExc_TypeError,
"%s: expected a sequence, got %s",
error_prefix,
Py_TYPE(params.seq)->tp_name);
- ret = -1;
}
else {
length = PySequence_Fast_GET_SIZE(seq_fast);
@@ -341,7 +341,6 @@ static PyObject *pygpu_shader_uniform_bool(BPyGPUShader *self, PyObject *args)
"%s: invalid sequence length. expected 1..4, got %d",
error_prefix,
length);
- ret = -1;
}
else {
ret = PyC_AsArray_FAST(
@@ -350,6 +349,15 @@ static PyObject *pygpu_shader_uniform_bool(BPyGPUShader *self, PyObject *args)
Py_DECREF(seq_fast);
}
}
+ else if (((values[0] = (int)PyLong_AsLong(params.seq)) != -1) && ELEM(values[0], 0, 1)) {
+ length = 1;
+ ret = 0;
+ }
+ else {
+ PyErr_Format(
+ PyExc_ValueError, "expected a bool or sequence, got %s", Py_TYPE(params.seq)->tp_name);
+ }
+
if (ret == -1) {
return NULL;
}
@@ -360,6 +368,7 @@ static PyObject *pygpu_shader_uniform_bool(BPyGPUShader *self, PyObject *args)
return NULL;
}
+ GPU_shader_bind(self->shader);
GPU_shader_uniform_vector_int(self->shader, location, length, 1, values);
Py_RETURN_NONE;
@@ -370,9 +379,9 @@ PyDoc_STRVAR(pygpu_shader_uniform_float_doc,
"\n"
" Specify the value of a uniform variable for the current program object.\n"
"\n"
- " :param name: Name of the uniform variable whose value is to be changed.\n"
+ " :arg name: Name of the uniform variable whose value is to be changed.\n"
" :type name: str\n"
- " :param value: Value that will be used to update the specified uniform variable.\n"
+ " :arg value: Value that will be used to update the specified uniform variable.\n"
" :type value: single number or sequence of numbers\n");
static PyObject *pygpu_shader_uniform_float(BPyGPUShader *self, PyObject *args)
{
@@ -429,6 +438,7 @@ static PyObject *pygpu_shader_uniform_float(BPyGPUShader *self, PyObject *args)
return NULL;
}
+ GPU_shader_bind(self->shader);
GPU_shader_uniform_vector(self->shader, location, length, 1, values);
Py_RETURN_NONE;
@@ -439,9 +449,9 @@ PyDoc_STRVAR(pygpu_shader_uniform_int_doc,
"\n"
" Specify the value of a uniform variable for the current program object.\n"
"\n"
- " :param name: name of the uniform variable whose value is to be changed.\n"
+ " :arg name: name of the uniform variable whose value is to be changed.\n"
" :type name: str\n"
- " :param seq: Value that will be used to update the specified uniform variable.\n"
+ " :arg seq: Value that will be used to update the specified uniform variable.\n"
" :type seq: sequence of numbers\n");
static PyObject *pygpu_shader_uniform_int(BPyGPUShader *self, PyObject *args)
{
@@ -500,6 +510,7 @@ static PyObject *pygpu_shader_uniform_int(BPyGPUShader *self, PyObject *args)
return NULL;
}
+ GPU_shader_bind(self->shader);
GPU_shader_uniform_vector_int(self->shader, location, length, 1, values);
Py_RETURN_NONE;
@@ -510,9 +521,9 @@ PyDoc_STRVAR(pygpu_shader_uniform_sampler_doc,
"\n"
" Specify the value of a texture uniform variable for the current GPUShader.\n"
"\n"
- " :param name: name of the uniform variable whose texture is to be specified.\n"
+ " :arg name: name of the uniform variable whose texture is to be specified.\n"
" :type name: str\n"
- " :param texture: Texture to attach.\n"
+ " :arg texture: Texture to attach.\n"
" :type texture: :class:`gpu.types.GPUTexture`\n");
static PyObject *pygpu_shader_uniform_sampler(BPyGPUShader *self, PyObject *args)
{
@@ -523,6 +534,7 @@ static PyObject *pygpu_shader_uniform_sampler(BPyGPUShader *self, PyObject *args
return NULL;
}
+ GPU_shader_bind(self->shader);
int slot = GPU_shader_get_texture_binding(self->shader, name);
GPU_texture_bind(py_texture->tex, slot);
GPU_shader_uniform_1i(self->shader, name, slot);
@@ -536,9 +548,9 @@ PyDoc_STRVAR(
"\n"
" Specify the value of an uniform buffer object variable for the current GPUShader.\n"
"\n"
- " :param name: name of the uniform variable whose UBO is to be specified.\n"
+ " :arg name: name of the uniform variable whose UBO is to be specified.\n"
" :type name: str\n"
- " :param ubo: Uniform Buffer to attach.\n"
+ " :arg ubo: Uniform Buffer to attach.\n"
" :type texture: :class:`gpu.types.GPUUniformBuf`\n");
static PyObject *pygpu_shader_uniform_block(BPyGPUShader *self, PyObject *args)
{
@@ -557,21 +569,21 @@ static PyObject *pygpu_shader_uniform_block(BPyGPUShader *self, PyObject *args)
return NULL;
}
+ GPU_shader_bind(self->shader);
GPU_uniformbuf_bind(py_ubo->ubo, binding);
Py_RETURN_NONE;
}
-PyDoc_STRVAR(
- pygpu_shader_attr_from_name_doc,
- ".. method:: attr_from_name(name)\n"
- "\n"
- " Get attribute location by name.\n"
- "\n"
- " :param name: The name of the attribute variable whose location is to be queried.\n"
- " :type name: str\n"
- " :return: The location of an attribute variable.\n"
- " :rtype: int\n");
+PyDoc_STRVAR(pygpu_shader_attr_from_name_doc,
+ ".. method:: attr_from_name(name)\n"
+ "\n"
+ " Get attribute location by name.\n"
+ "\n"
+ " :arg name: The name of the attribute variable whose location is to be queried.\n"
+ " :type name: str\n"
+ " :return: The location of an attribute variable.\n"
+ " :rtype: int\n");
static PyObject *pygpu_shader_attr_from_name(BPyGPUShader *self, PyObject *arg)
{
const char *name = PyUnicode_AsUTF8(arg);
@@ -743,17 +755,17 @@ PyDoc_STRVAR(
" ``fragOutput = blender_srgb_to_framebuffer_space(fragOutput)``\n"
" to transform the output sRGB colors to the frame-buffer color-space.\n"
"\n"
- " :param vertexcode: Vertex shader code.\n"
+ " :arg vertexcode: Vertex shader code.\n"
" :type vertexcode: str\n"
- " :param fragcode: Fragment shader code.\n"
+ " :arg fragcode: Fragment shader code.\n"
" :type value: str\n"
- " :param geocode: Geometry shader code.\n"
+ " :arg geocode: Geometry shader code.\n"
" :type value: str\n"
- " :param libcode: Code with functions and presets to be shared between shaders.\n"
+ " :arg libcode: Code with functions and presets to be shared between shaders.\n"
" :type value: str\n"
- " :param defines: Preprocessor directives.\n"
+ " :arg defines: Preprocessor directives.\n"
" :type value: str\n"
- " :param name: Name of shader code, for debugging purposes.\n"
+ " :arg name: Name of shader code, for debugging purposes.\n"
" :type value: str\n");
PyTypeObject BPyGPUShader_Type = {
PyVarObject_HEAD_INIT(NULL, 0).tp_name = "GPUShader",
@@ -812,9 +824,9 @@ PyDoc_STRVAR(
"``CLIPPED`` value to the config parameter. Note that in this case you also need to "
"manually set the value of ``mat4 ModelMatrix``.\n"
"\n"
- " :param shader_name: One of the builtin shader names.\n"
+ " :arg shader_name: One of the builtin shader names.\n"
" :type shader_name: str\n"
- " :param config: One of these types of shader configuration:\n"
+ " :arg config: One of these types of shader configuration:\n"
"\n"
" - ``DEFAULT``\n"
" - ``CLIPPED``\n"
@@ -858,7 +870,7 @@ PyDoc_STRVAR(pygpu_shader_create_from_info_doc,
"\n"
" Create shader from a GPUShaderCreateInfo.\n"
"\n"
- " :param shader_info: GPUShaderCreateInfo\n"
+ " :arg shader_info: GPUShaderCreateInfo\n"
" :type shader_info: :class:`bpy.types.GPUShaderCreateInfo`\n"
" :return: Shader object corresponding to the given name.\n"
" :rtype: :class:`bpy.types.GPUShader`\n");
@@ -911,9 +923,14 @@ PyDoc_STRVAR(pygpu_shader_module__tp_doc,
"\n" PYDOC_BUILTIN_SHADER_DESCRIPTION);
static PyModuleDef pygpu_shader_module_def = {
PyModuleDef_HEAD_INIT,
- .m_name = "gpu.shader",
- .m_doc = pygpu_shader_module__tp_doc,
- .m_methods = pygpu_shader_module__tp_methods,
+ /*m_name*/ "gpu.shader",
+ /*m_doc*/ pygpu_shader_module__tp_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ pygpu_shader_module__tp_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
/** \} */
diff --git a/source/blender/python/gpu/gpu_py_shader_create_info.cc b/source/blender/python/gpu/gpu_py_shader_create_info.cc
index c9e49c5cc4b..6b1be057752 100644
--- a/source/blender/python/gpu/gpu_py_shader_create_info.cc
+++ b/source/blender/python/gpu/gpu_py_shader_create_info.cc
@@ -35,9 +35,9 @@ using blender::gpu::shader::Qualifier;
" - ``READ``\n" \
" - ``WRITE``\n"
static const struct PyC_FlagSet pygpu_qualifiers[] = {
- {(int)Qualifier::NO_RESTRICT, "NO_RESTRICT"},
- {(int)Qualifier::READ, "READ"},
- {(int)Qualifier::WRITE, "WRITE"},
+ {int(Qualifier::NO_RESTRICT), "NO_RESTRICT"},
+ {int(Qualifier::READ), "READ"},
+ {int(Qualifier::WRITE), "WRITE"},
{0, nullptr},
};
#endif
@@ -59,21 +59,21 @@ static const struct PyC_FlagSet pygpu_qualifiers[] = {
" - ``IVEC4``\n" \
" - ``BOOL``\n"
const struct PyC_StringEnumItems pygpu_attrtype_items[] = {
- {(int)Type::FLOAT, "FLOAT"},
- {(int)Type::VEC2, "VEC2"},
- {(int)Type::VEC3, "VEC3"},
- {(int)Type::VEC4, "VEC4"},
- {(int)Type::MAT3, "MAT3"},
- {(int)Type::MAT4, "MAT4"},
- {(int)Type::UINT, "UINT"},
- {(int)Type::UVEC2, "UVEC2"},
- {(int)Type::UVEC3, "UVEC3"},
- {(int)Type::UVEC4, "UVEC4"},
- {(int)Type::INT, "INT"},
- {(int)Type::IVEC2, "IVEC2"},
- {(int)Type::IVEC3, "IVEC3"},
- {(int)Type::IVEC4, "IVEC4"},
- {(int)Type::BOOL, "BOOL"},
+ {int(Type::FLOAT), "FLOAT"},
+ {int(Type::VEC2), "VEC2"},
+ {int(Type::VEC3), "VEC3"},
+ {int(Type::VEC4), "VEC4"},
+ {int(Type::MAT3), "MAT3"},
+ {int(Type::MAT4), "MAT4"},
+ {int(Type::UINT), "UINT"},
+ {int(Type::UVEC2), "UVEC2"},
+ {int(Type::UVEC3), "UVEC3"},
+ {int(Type::UVEC4), "UVEC4"},
+ {int(Type::INT), "INT"},
+ {int(Type::IVEC2), "IVEC2"},
+ {int(Type::IVEC3), "IVEC3"},
+ {int(Type::IVEC4), "IVEC4"},
+ {int(Type::BOOL), "BOOL"},
{0, nullptr},
};
@@ -111,45 +111,45 @@ const struct PyC_StringEnumItems pygpu_attrtype_items[] = {
" - ``DEPTH_CUBE``\n" \
" - ``DEPTH_CUBE_ARRAY``\n"
static const struct PyC_StringEnumItems pygpu_imagetype_items[] = {
- {(int)ImageType::FLOAT_BUFFER, "FLOAT_BUFFER"},
- {(int)ImageType::FLOAT_1D, "FLOAT_1D"},
- {(int)ImageType::FLOAT_1D_ARRAY, "FLOAT_1D_ARRAY"},
- {(int)ImageType::FLOAT_2D, "FLOAT_2D"},
- {(int)ImageType::FLOAT_2D_ARRAY, "FLOAT"},
- {(int)ImageType::FLOAT_3D, "FLOAT_2D_ARRAY"},
- {(int)ImageType::FLOAT_CUBE, "FLOAT_CUBE"},
- {(int)ImageType::FLOAT_CUBE_ARRAY, "FLOAT_CUBE_ARRAY"},
- {(int)ImageType::INT_BUFFER, "INT_BUFFER"},
- {(int)ImageType::INT_1D, "INT_1D"},
- {(int)ImageType::INT_1D_ARRAY, "INT_1D_ARRAY"},
- {(int)ImageType::INT_2D, "INT_2D"},
- {(int)ImageType::INT_2D_ARRAY, "INT_2D_ARRAY"},
- {(int)ImageType::INT_3D, "INT_3D"},
- {(int)ImageType::INT_CUBE, "INT_CUBE"},
- {(int)ImageType::INT_CUBE_ARRAY, "INT_CUBE_ARRAY"},
- {(int)ImageType::UINT_BUFFER, "UINT_BUFFER"},
- {(int)ImageType::UINT_1D, "UINT_1D"},
- {(int)ImageType::UINT_1D_ARRAY, "UINT_1D_ARRAY"},
- {(int)ImageType::UINT_2D, "UINT_2D"},
- {(int)ImageType::UINT_2D_ARRAY, "UINT_2D_ARRAY"},
- {(int)ImageType::UINT_3D, "UINT_3D"},
- {(int)ImageType::UINT_CUBE, "UINT_CUBE"},
- {(int)ImageType::UINT_CUBE_ARRAY, "UINT_CUBE_ARRAY"},
- {(int)ImageType::SHADOW_2D, "SHADOW_2D"},
- {(int)ImageType::SHADOW_2D_ARRAY, "SHADOW_2D_ARRAY"},
- {(int)ImageType::SHADOW_CUBE, "SHADOW_CUBE"},
- {(int)ImageType::SHADOW_CUBE_ARRAY, "SHADOW_CUBE_ARRAY"},
- {(int)ImageType::DEPTH_2D, "DEPTH_2D"},
- {(int)ImageType::DEPTH_2D_ARRAY, "DEPTH_2D_ARRAY"},
- {(int)ImageType::DEPTH_CUBE, "DEPTH_CUBE"},
- {(int)ImageType::DEPTH_CUBE_ARRAY, "DEPTH_CUBE_ARRAY"},
+ {int(ImageType::FLOAT_BUFFER), "FLOAT_BUFFER"},
+ {int(ImageType::FLOAT_1D), "FLOAT_1D"},
+ {int(ImageType::FLOAT_1D_ARRAY), "FLOAT_1D_ARRAY"},
+ {int(ImageType::FLOAT_2D), "FLOAT_2D"},
+ {int(ImageType::FLOAT_2D_ARRAY), "FLOAT"},
+ {int(ImageType::FLOAT_3D), "FLOAT_2D_ARRAY"},
+ {int(ImageType::FLOAT_CUBE), "FLOAT_CUBE"},
+ {int(ImageType::FLOAT_CUBE_ARRAY), "FLOAT_CUBE_ARRAY"},
+ {int(ImageType::INT_BUFFER), "INT_BUFFER"},
+ {int(ImageType::INT_1D), "INT_1D"},
+ {int(ImageType::INT_1D_ARRAY), "INT_1D_ARRAY"},
+ {int(ImageType::INT_2D), "INT_2D"},
+ {int(ImageType::INT_2D_ARRAY), "INT_2D_ARRAY"},
+ {int(ImageType::INT_3D), "INT_3D"},
+ {int(ImageType::INT_CUBE), "INT_CUBE"},
+ {int(ImageType::INT_CUBE_ARRAY), "INT_CUBE_ARRAY"},
+ {int(ImageType::UINT_BUFFER), "UINT_BUFFER"},
+ {int(ImageType::UINT_1D), "UINT_1D"},
+ {int(ImageType::UINT_1D_ARRAY), "UINT_1D_ARRAY"},
+ {int(ImageType::UINT_2D), "UINT_2D"},
+ {int(ImageType::UINT_2D_ARRAY), "UINT_2D_ARRAY"},
+ {int(ImageType::UINT_3D), "UINT_3D"},
+ {int(ImageType::UINT_CUBE), "UINT_CUBE"},
+ {int(ImageType::UINT_CUBE_ARRAY), "UINT_CUBE_ARRAY"},
+ {int(ImageType::SHADOW_2D), "SHADOW_2D"},
+ {int(ImageType::SHADOW_2D_ARRAY), "SHADOW_2D_ARRAY"},
+ {int(ImageType::SHADOW_CUBE), "SHADOW_CUBE"},
+ {int(ImageType::SHADOW_CUBE_ARRAY), "SHADOW_CUBE_ARRAY"},
+ {int(ImageType::DEPTH_2D), "DEPTH_2D"},
+ {int(ImageType::DEPTH_2D_ARRAY), "DEPTH_2D_ARRAY"},
+ {int(ImageType::DEPTH_CUBE), "DEPTH_CUBE"},
+ {int(ImageType::DEPTH_CUBE_ARRAY), "DEPTH_CUBE_ARRAY"},
{0, nullptr},
};
static const struct PyC_StringEnumItems pygpu_dualblend_items[] = {
- {(int)DualBlend::NONE, "NONE"},
- {(int)DualBlend::SRC_0, "SRC_0"},
- {(int)DualBlend::SRC_1, "SRC_1"},
+ {int(DualBlend::NONE), "NONE"},
+ {int(DualBlend::SRC_0), "SRC_0"},
+ {int(DualBlend::SRC_1), "SRC_1"},
{0, nullptr},
};
@@ -189,11 +189,11 @@ PyDoc_STRVAR(pygpu_interface_info_smooth_doc,
"\n"
" Add an attribute with qualifier of type `smooth` to the interface block.\n"
"\n"
- " :param type: One of these types:\n"
+ " :arg type: One of these types:\n"
"\n" PYDOC_TYPE_LIST
"\n"
" :type type: str\n"
- " :param name: name of the attribute.\n"
+ " :arg name: name of the attribute.\n"
" :type name: str\n");
static PyObject *pygpu_interface_info_smooth(BPyGPUStageInterfaceInfo *self, PyObject *args)
{
@@ -213,11 +213,11 @@ PyDoc_STRVAR(pygpu_interface_info_flat_doc,
"\n"
" Add an attribute with qualifier of type `flat` to the interface block.\n"
"\n"
- " :param type: One of these types:\n"
+ " :arg type: One of these types:\n"
"\n" PYDOC_TYPE_LIST
"\n"
" :type type: str\n"
- " :param name: name of the attribute.\n"
+ " :arg name: name of the attribute.\n"
" :type name: str\n");
static PyObject *pygpu_interface_info_flat(BPyGPUStageInterfaceInfo *self, PyObject *args)
{
@@ -238,11 +238,11 @@ PyDoc_STRVAR(
"\n"
" Add an attribute with qualifier of type `no_perspective` to the interface block.\n"
"\n"
- " :param type: One of these types:\n"
+ " :arg type: One of these types:\n"
"\n" PYDOC_TYPE_LIST
"\n"
" :type type: str\n"
- " :param name: name of the attribute.\n"
+ " :arg name: name of the attribute.\n"
" :type name: str\n");
static PyObject *pygpu_interface_info_no_perspective(BPyGPUStageInterfaceInfo *self,
PyObject *args)
@@ -281,8 +281,7 @@ PyDoc_STRVAR(pygpu_interface_info_name_doc,
"Name of the interface block.\n"
"\n"
":type: str");
-static PyObject *pygpu_interface_info_name_get(BPyGPUStageInterfaceInfo *self,
- void *UNUSED(closure))
+static PyObject *pygpu_interface_info_name_get(BPyGPUStageInterfaceInfo *self, void * /*closure*/)
{
StageInterfaceInfo *interface = reinterpret_cast<StageInterfaceInfo *>(self->interface);
return PyUnicode_FromString(interface->name.c_str());
@@ -303,7 +302,7 @@ static PyGetSetDef pygpu_interface_info__tp_getseters[] = {
/** \name GPUStageInterfaceInfo Type
* \{ */
-static PyObject *pygpu_interface_info__tp_new(PyTypeObject *UNUSED(type),
+static PyObject *pygpu_interface_info__tp_new(PyTypeObject * /*type*/,
PyObject *args,
PyObject *kwds)
{
@@ -370,7 +369,7 @@ PyDoc_STRVAR(pygpu_interface_info__tp_doc,
"\n"
" List of varyings between shader stages.\n\n"
"\n"
- " :param name: Name of the interface block.\n"
+ " :arg name: Name of the interface block.\n"
" :type value: str\n");
constexpr PyTypeObject pygpu_interface_info_type()
{
@@ -403,13 +402,13 @@ PyDoc_STRVAR(pygpu_shader_info_vertex_in_doc,
"\n"
" Add a vertex shader input attribute.\n"
"\n"
- " :param slot: The attribute index.\n"
+ " :arg slot: The attribute index.\n"
" :type slot: int\n"
- " :param type: One of these types:\n"
+ " :arg type: One of these types:\n"
"\n" PYDOC_TYPE_LIST
"\n"
" :type type: str\n"
- " :param name: name of the attribute.\n"
+ " :arg name: name of the attribute.\n"
" :type name: str\n");
static PyObject *pygpu_shader_info_vertex_in(BPyGPUShaderCreateInfo *self, PyObject *args)
{
@@ -436,7 +435,7 @@ PyDoc_STRVAR(pygpu_shader_info_vertex_out_doc,
"\n"
" Add a vertex shader output interface block.\n"
"\n"
- " :param interface: Object describing the block.\n"
+ " :arg interface: Object describing the block.\n"
" :type interface: :class:`gpu.types.GPUStageInterfaceInfo`\n");
static PyObject *pygpu_shader_info_vertex_out(BPyGPUShaderCreateInfo *self,
BPyGPUStageInterfaceInfo *o)
@@ -462,15 +461,15 @@ PyDoc_STRVAR(pygpu_shader_info_fragment_out_doc,
"\n"
" Specify a fragment output corresponding to a framebuffer target slot.\n"
"\n"
- " :param slot: The attribute index.\n"
+ " :arg slot: The attribute index.\n"
" :type slot: int\n"
- " :param type: One of these types:\n"
+ " :arg type: One of these types:\n"
"\n" PYDOC_TYPE_LIST
"\n"
" :type type: str\n"
- " :param name: Name of the attribute.\n"
+ " :arg name: Name of the attribute.\n"
" :type name: str\n"
- " :param blend: Dual Source Blending Index. It can be 'NONE', 'SRC_0' or 'SRC_1'.\n"
+ " :arg blend: Dual Source Blending Index. It can be 'NONE', 'SRC_0' or 'SRC_1'.\n"
" :type blend: str\n");
static PyObject *pygpu_shader_info_fragment_out(BPyGPUShaderCreateInfo *self,
PyObject *args,
@@ -479,7 +478,7 @@ static PyObject *pygpu_shader_info_fragment_out(BPyGPUShaderCreateInfo *self,
int slot;
struct PyC_StringEnum pygpu_type = {pygpu_attrtype_items};
const char *name;
- struct PyC_StringEnum blend_type = {pygpu_dualblend_items, (int)DualBlend::NONE};
+ struct PyC_StringEnum blend_type = {pygpu_dualblend_items, int(DualBlend::NONE)};
static const char *_keywords[] = {"slot", "type", "name", "blend", nullptr};
static _PyArg_Parser _parser = {
@@ -521,12 +520,12 @@ PyDoc_STRVAR(
"\n"
" Specify a uniform variable whose type can be one of those declared in `typedef_source`.\n"
"\n"
- " :param slot: The uniform variable index.\n"
+ " :arg slot: The uniform variable index.\n"
" :type slot: int\n"
- " :param type_name: Name of the data type. It can be a struct type defined in the source "
+ " :arg type_name: Name of the data type. It can be a struct type defined in the source "
"passed through the :meth:`gpu.types.GPUShaderCreateInfo.typedef_source`.\n"
" :type type_name: str\n"
- " :param name: The uniform variable name.\n"
+ " :arg name: The uniform variable name.\n"
" :type name: str\n");
static PyObject *pygpu_shader_info_uniform_buf(BPyGPUShaderCreateInfo *self, PyObject *args)
{
@@ -556,19 +555,19 @@ PyDoc_STRVAR(
"\n"
" Specify an image resource used for arbitrary load and store operations.\n"
"\n"
- " :param slot: The image resource index.\n"
+ " :arg slot: The image resource index.\n"
" :type slot: int\n"
- " :param format: The GPUTexture format that is passed to the shader. Possible values are:\n"
+ " :arg format: The GPUTexture format that is passed to the shader. Possible values are:\n"
"" PYDOC_TEX_FORMAT_ITEMS
" :type format: str\n"
- " :param type: The data type describing how the image is to be read in the shader. "
+ " :arg type: The data type describing how the image is to be read in the shader. "
"Possible values are:\n"
"\n" PYDOC_IMAGE_TYPES
"\n"
" :type type: str\n"
- " :param name: The image resource name.\n"
+ " :arg name: The image resource name.\n"
" :type name: str\n"
- " :param qualifiers: Set containing values that describe how the image resource is to be "
+ " :arg qualifiers: Set containing values that describe how the image resource is to be "
"read or written. Possible values are:\n"
"" PYDOC_QUALIFIERS
""
@@ -636,14 +635,14 @@ PyDoc_STRVAR(
"\n"
" Specify an image texture sampler.\n"
"\n"
- " :param slot: The image texture sampler index.\n"
+ " :arg slot: The image texture sampler index.\n"
" :type slot: int\n"
- " :param type: The data type describing the format of each sampler unit. Possible values "
+ " :arg type: The data type describing the format of each sampler unit. Possible values "
"are:\n"
"\n" PYDOC_IMAGE_TYPES
"\n"
" :type type: str\n"
- " :param name: The image texture sampler name.\n"
+ " :arg name: The image texture sampler name.\n"
" :type name: str\n");
static PyObject *pygpu_shader_info_sampler(BPyGPUShaderCreateInfo *self, PyObject *args)
{
@@ -748,13 +747,13 @@ PyDoc_STRVAR(pygpu_shader_info_push_constant_doc,
"\n"
" Specify a global access constant.\n"
"\n"
- " :param type: One of these types:\n"
+ " :arg type: One of these types:\n"
"\n" PYDOC_TYPE_LIST
"\n"
" :type type: str\n"
- " :param name: Name of the constant.\n"
+ " :arg name: Name of the constant.\n"
" :type name: str\n"
- " :param size: If not zero, indicates that the constant is an array with the "
+ " :arg size: If not zero, indicates that the constant is an array with the "
"specified size.\n"
" :type size: uint\n");
static PyObject *pygpu_shader_info_push_constant(BPyGPUShaderCreateInfo *self,
@@ -812,7 +811,7 @@ PyDoc_STRVAR(
"\n"
" \"void main {gl_Position = vec4(pos, 1.0);}\"\n"
"\n"
- " :param source: The vertex shader source code.\n"
+ " :arg source: The vertex shader source code.\n"
" :type source: str\n"
"\n"
" .. seealso:: `GLSL Cross Compilation "
@@ -853,7 +852,7 @@ PyDoc_STRVAR(
"\n"
" \"void main {fragColor = vec4(0.0, 0.0, 0.0, 1.0);}\"\n"
"\n"
- " :param source: The fragment shader source code.\n"
+ " :arg source: The fragment shader source code.\n"
" :type source: str\n"
"\n"
" .. seealso:: `GLSL Cross Compilation "
@@ -894,7 +893,7 @@ PyDoc_STRVAR(pygpu_shader_info_typedef_source_doc,
"\n"
" \"struct MyType {int foo; float bar;};\"\n"
"\n"
- " :param source: The source code defining types.\n"
+ " :arg source: The source code defining types.\n"
" :type source: str\n");
static PyObject *pygpu_shader_info_typedef_source(BPyGPUShaderCreateInfo *self, PyObject *o)
{
@@ -933,9 +932,9 @@ PyDoc_STRVAR(pygpu_shader_info_define_doc,
"\n"
" #define name value\n"
"\n"
- " :param name: Token name.\n"
+ " :arg name: Token name.\n"
" :type name: str\n"
- " :param value: Text that replaces token occurrences.\n"
+ " :arg value: Text that replaces token occurrences.\n"
" :type value: str\n");
static PyObject *pygpu_shader_info_define(BPyGPUShaderCreateInfo *self, PyObject *args)
{
@@ -1014,12 +1013,10 @@ static struct PyMethodDef pygpu_shader_info__tp_methods[] = {
/** \} */
/* -------------------------------------------------------------------- */
-/** \name GPUShaderCreateInfo Init
+/** \name GPUShaderCreateInfo Initialization
* \{ */
-static PyObject *pygpu_shader_info__tp_new(PyTypeObject *UNUSED(type),
- PyObject *args,
- PyObject *kwds)
+static PyObject *pygpu_shader_info__tp_new(PyTypeObject * /*type*/, PyObject *args, PyObject *kwds)
{
if (PyTuple_Size(args) || kwds) {
PyErr_SetString(PyExc_TypeError, "no args or keywords are expected");
diff --git a/source/blender/python/gpu/gpu_py_state.c b/source/blender/python/gpu/gpu_py_state.c
index fb69bb316c4..f17a3fecfdd 100644
--- a/source/blender/python/gpu/gpu_py_state.c
+++ b/source/blender/python/gpu/gpu_py_state.c
@@ -72,7 +72,7 @@ PyDoc_STRVAR(
"\n"
" Defines the fixed pipeline blending equation.\n"
"\n"
- " :param mode: The type of blend mode.\n"
+ " :arg mode: The type of blend mode.\n"
" * ``NONE`` No blending.\n"
" * ``ALPHA`` The original color channels are interpolated according to the alpha "
"value.\n"
@@ -114,7 +114,7 @@ PyDoc_STRVAR(pygpu_state_clip_distances_set_doc,
"\n"
" Sets the number of `gl_ClipDistance` planes used for clip geometry.\n"
"\n"
- " :param distances_enabled: Number of clip distances enabled.\n"
+ " :arg distances_enabled: Number of clip distances enabled.\n"
" :type distances_enabled: int\n");
static PyObject *pygpu_state_clip_distances_set(PyObject *UNUSED(self), PyObject *value)
{
@@ -136,7 +136,7 @@ PyDoc_STRVAR(pygpu_state_depth_test_set_doc,
"\n"
" Defines the depth_test equation.\n"
"\n"
- " :param mode: The depth test equation name.\n"
+ " :arg mode: The depth test equation name.\n"
" Possible values are `NONE`, `ALWAYS`, `LESS`, `LESS_EQUAL`, `EQUAL`, "
"`GREATER` and `GREATER_EQUAL`.\n"
" :type mode: str\n");
@@ -166,7 +166,7 @@ PyDoc_STRVAR(pygpu_state_depth_mask_set_doc,
"\n"
" Write to depth component.\n"
"\n"
- " :param value: True for writing to the depth component.\n"
+ " :arg value: True for writing to the depth component.\n"
" :type near: bool\n");
static PyObject *pygpu_state_depth_mask_set(PyObject *UNUSED(self), PyObject *value)
{
@@ -193,9 +193,10 @@ PyDoc_STRVAR(pygpu_state_viewport_set_doc,
" Specifies the viewport of the active framebuffer.\n"
" Note: The viewport state is not saved upon framebuffer rebind.\n"
"\n"
- " :param x, y: lower left corner of the viewport_set rectangle, in pixels.\n"
- " :param width, height: width and height of the viewport_set.\n"
- " :type x, y, xsize, ysize: int\n");
+ " :arg x, y: lower left corner of the viewport_set rectangle, in pixels.\n"
+ " :type x, y: int\n"
+ " :arg xsize, ysize: width and height of the viewport_set.\n"
+ " :type xsize, ysize: int\n");
static PyObject *pygpu_state_viewport_set(PyObject *UNUSED(self), PyObject *args)
{
int x, y, xsize, ysize;
@@ -230,7 +231,7 @@ PyDoc_STRVAR(pygpu_state_line_width_set_doc,
"\n"
" Specify the width of rasterized lines.\n"
"\n"
- " :param size: New width.\n"
+ " :arg size: New width.\n"
" :type mode: float\n");
static PyObject *pygpu_state_line_width_set(PyObject *UNUSED(self), PyObject *value)
{
@@ -258,7 +259,7 @@ PyDoc_STRVAR(pygpu_state_point_size_set_doc,
"\n"
" Specify the diameter of rasterized points.\n"
"\n"
- " :param size: New diameter.\n"
+ " :arg size: New diameter.\n"
" :type mode: float\n");
static PyObject *pygpu_state_point_size_set(PyObject *UNUSED(self), PyObject *value)
{
@@ -276,7 +277,7 @@ PyDoc_STRVAR(pygpu_state_color_mask_set_doc,
"\n"
" Enable or disable writing of frame buffer color components.\n"
"\n"
- " :param r, g, b, a: components red, green, blue, and alpha.\n"
+ " :arg r, g, b, a: components red, green, blue, and alpha.\n"
" :type r, g, b, a: bool\n");
static PyObject *pygpu_state_color_mask_set(PyObject *UNUSED(self), PyObject *args)
{
@@ -294,7 +295,7 @@ PyDoc_STRVAR(pygpu_state_face_culling_set_doc,
"\n"
" Specify whether none, front-facing or back-facing facets can be culled.\n"
"\n"
- " :param mode: `NONE`, `FRONT` or `BACK`.\n"
+ " :arg mode: `NONE`, `FRONT` or `BACK`.\n"
" :type mode: str\n");
static PyObject *pygpu_state_face_culling_set(PyObject *UNUSED(self), PyObject *value)
{
@@ -312,7 +313,7 @@ PyDoc_STRVAR(pygpu_state_front_facing_set_doc,
"\n"
" Specifies the orientation of front-facing polygons.\n"
"\n"
- " :param invert: True for clockwise polygons as front-facing.\n"
+ " :arg invert: True for clockwise polygons as front-facing.\n"
" :type mode: bool\n");
static PyObject *pygpu_state_front_facing_set(PyObject *UNUSED(self), PyObject *value)
{
@@ -331,7 +332,7 @@ PyDoc_STRVAR(pygpu_state_program_point_size_set_doc,
" If enabled, the derived point size is taken from the (potentially clipped) "
"shader builtin gl_PointSize.\n"
"\n"
- " :param enable: True for shader builtin gl_PointSize.\n"
+ " :arg enable: True for shader builtin gl_PointSize.\n"
" :type enable: bool\n");
static PyObject *pygpu_state_program_point_size_set(PyObject *UNUSED(self), PyObject *value)
{
@@ -430,9 +431,14 @@ static struct PyMethodDef pygpu_state__tp_methods[] = {
PyDoc_STRVAR(pygpu_state__tp_doc, "This module provides access to the gpu state.");
static PyModuleDef pygpu_state_module_def = {
PyModuleDef_HEAD_INIT,
- .m_name = "gpu.state",
- .m_doc = pygpu_state__tp_doc,
- .m_methods = pygpu_state__tp_methods,
+ /*m_name*/ "gpu.state",
+ /*m_doc*/ pygpu_state__tp_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ pygpu_state__tp_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *bpygpu_state_init(void)
diff --git a/source/blender/python/gpu/gpu_py_texture.c b/source/blender/python/gpu/gpu_py_texture.c
index 7a23f7ac91f..11b44a2a35e 100644
--- a/source/blender/python/gpu/gpu_py_texture.c
+++ b/source/blender/python/gpu/gpu_py_texture.c
@@ -280,9 +280,9 @@ PyDoc_STRVAR(
"\n"
" Fill texture with specific value.\n"
"\n"
- " :param format: The format that describes the content of a single item.\n"
+ " :arg format: The format that describes the content of a single item.\n"
" Possible values are `FLOAT`, `INT`, `UINT`, `UBYTE`, `UINT_24_8` and `10_11_11_REV`.\n"
- " :type type: str\n"
+ " :type format: str\n"
" :arg value: sequence each representing the value to fill.\n"
" :type value: sequence of 1, 2, 3 or 4 values\n");
static PyObject *pygpu_texture_clear(BPyGPUTexture *self, PyObject *args, PyObject *kwds)
@@ -565,9 +565,14 @@ static struct PyMethodDef pygpu_texture__m_methods[] = {
PyDoc_STRVAR(pygpu_texture__m_doc, "This module provides utils for textures.");
static PyModuleDef pygpu_texture_module_def = {
PyModuleDef_HEAD_INIT,
- .m_name = "gpu.texture",
- .m_doc = pygpu_texture__m_doc,
- .m_methods = pygpu_texture__m_methods,
+ /*m_name*/ "gpu.texture",
+ /*m_doc*/ pygpu_texture__m_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ pygpu_texture__m_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
/** \} */
diff --git a/source/blender/python/gpu/gpu_py_types.c b/source/blender/python/gpu/gpu_py_types.c
index eccbebbd8dd..b5cabd93b42 100644
--- a/source/blender/python/gpu/gpu_py_types.c
+++ b/source/blender/python/gpu/gpu_py_types.c
@@ -19,7 +19,14 @@
static struct PyModuleDef pygpu_types_module_def = {
PyModuleDef_HEAD_INIT,
- .m_name = "gpu.types",
+ /*m_name*/ "gpu.types",
+ /*m_doc*/ NULL,
+ /*m_size*/ 0,
+ /*m_methods*/ NULL,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *bpygpu_types_init(void)
diff --git a/source/blender/python/gpu/gpu_py_vertex_buffer.c b/source/blender/python/gpu/gpu_py_vertex_buffer.c
index ab2ff59a689..fd36c0a2d71 100644
--- a/source/blender/python/gpu/gpu_py_vertex_buffer.c
+++ b/source/blender/python/gpu/gpu_py_vertex_buffer.c
@@ -261,9 +261,9 @@ PyDoc_STRVAR(pygpu_vertbuf_attr_fill_doc,
"\n"
" Insert data into the buffer for a single attribute.\n"
"\n"
- " :param id: Either the name or the id of the attribute.\n"
+ " :arg id: Either the name or the id of the attribute.\n"
" :type id: int or str\n"
- " :param data: Sequence of data that should be stored in the buffer\n"
+ " :arg data: Sequence of data that should be stored in the buffer\n"
" :type data: sequence of floats, ints, vectors or matrices\n");
static PyObject *pygpu_vertbuf_attr_fill(BPyGPUVertBuf *self, PyObject *args, PyObject *kwds)
{
@@ -327,10 +327,10 @@ PyDoc_STRVAR(pygpu_vertbuf__tp_doc,
"\n"
" Contains a VBO.\n"
"\n"
- " :param format: Vertex format.\n"
- " :type buf: :class:`gpu.types.GPUVertFormat`\n"
- " :param len: Amount of vertices that will fit into this buffer.\n"
- " :type type: `int`\n");
+ " :arg format: Vertex format.\n"
+ " :type format: :class:`gpu.types.GPUVertFormat`\n"
+ " :arg len: Amount of vertices that will fit into this buffer.\n"
+ " :type len: int\n");
PyTypeObject BPyGPUVertBuf_Type = {
PyVarObject_HEAD_INIT(NULL, 0).tp_name = "GPUVertBuf",
.tp_basicsize = sizeof(BPyGPUVertBuf),
diff --git a/source/blender/python/gpu/gpu_py_vertex_format.c b/source/blender/python/gpu/gpu_py_vertex_format.c
index 40a0e5d1e9f..ac0ec6bdc01 100644
--- a/source/blender/python/gpu/gpu_py_vertex_format.c
+++ b/source/blender/python/gpu/gpu_py_vertex_format.c
@@ -63,15 +63,15 @@ PyDoc_STRVAR(
"\n"
" Add a new attribute to the format.\n"
"\n"
- " :param id: Name the attribute. Often `position`, `normal`, ...\n"
+ " :arg id: Name the attribute. Often `position`, `normal`, ...\n"
" :type id: str\n"
- " :param comp_type: The data type that will be used store the value in memory.\n"
+ " :arg comp_type: The data type that will be used store the value in memory.\n"
" Possible values are `I8`, `U8`, `I16`, `U16`, `I32`, `U32`, `F32` and `I10`.\n"
" :type comp_type: str\n"
- " :param len: How many individual values the attribute consists of\n"
+ " :arg len: How many individual values the attribute consists of\n"
" (e.g. 2 for uv coordinates).\n"
" :type len: int\n"
- " :param fetch_mode: How values from memory will be converted when used in the shader.\n"
+ " :arg fetch_mode: How values from memory will be converted when used in the shader.\n"
" This is mainly useful for memory optimizations when you want to store values with\n"
" reduced precision. E.g. you can store a float in only 1 byte but it will be\n"
" converted to a normal 4 byte float when used.\n"
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index 7fe0b9455e6..36d53d69eff 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -29,6 +29,8 @@
#include "GPU_state.h"
+#include "WM_api.h" /* For #WM_ghost_backend */
+
#include "bpy.h"
#include "bpy_app.h"
#include "bpy_capi_utils.h"
@@ -322,7 +324,7 @@ static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObj
return NULL;
}
- path = BKE_appdir_folder_id_version(type.value_found, (major * 100) + minor, false);
+ path = BKE_appdir_resource_path_id_with_version(type.value_found, false, (major * 100) + minor);
return PyC_UnicodeFromByte(path ? path : "");
}
@@ -536,6 +538,17 @@ static PyObject *bpy_rna_enum_items_static(PyObject *UNUSED(self))
return result;
}
+/* This is only exposed for (Unix/Linux), see: #GHOST_ISystem::getSystemBackend for details. */
+PyDoc_STRVAR(bpy_ghost_backend_doc,
+ ".. function:: _ghost_backend()\n"
+ "\n"
+ " :return: An identifier for the GHOST back-end.\n"
+ " :rtype: string\n");
+static PyObject *bpy_ghost_backend(PyObject *UNUSED(self))
+{
+ return PyUnicode_FromString(WM_ghost_backend());
+}
+
static PyMethodDef bpy_methods[] = {
{"script_paths", (PyCFunction)bpy_script_paths, METH_NOARGS, bpy_script_paths_doc},
{"blend_paths",
@@ -552,10 +565,6 @@ static PyMethodDef bpy_methods[] = {
(PyCFunction)bpy_resource_path,
METH_VARARGS | METH_KEYWORDS,
bpy_resource_path_doc},
- {"_driver_secure_code_test",
- (PyCFunction)bpy_driver_secure_code_test,
- METH_VARARGS | METH_KEYWORDS,
- bpy_driver_secure_code_test_doc},
{"escape_identifier", (PyCFunction)bpy_escape_identifier, METH_O, bpy_escape_identifier_doc},
{"unescape_identifier",
(PyCFunction)bpy_unescape_identifier,
@@ -566,6 +575,14 @@ static PyMethodDef bpy_methods[] = {
(PyCFunction)bpy_rna_enum_items_static,
METH_NOARGS,
bpy_rna_enum_items_static_doc},
+
+ /* Private functions (not part of the public API and may be removed at any time). */
+ {"_driver_secure_code_test",
+ (PyCFunction)bpy_driver_secure_code_test,
+ METH_VARARGS | METH_KEYWORDS,
+ bpy_driver_secure_code_test_doc},
+ {"_ghost_backend", (PyCFunction)bpy_ghost_backend, METH_NOARGS, bpy_ghost_backend_doc},
+
{NULL, NULL, 0, NULL},
};
@@ -655,7 +672,7 @@ void BPy_init_modules(struct bContext *C)
PyModule_AddObject(mod, m->ml_name, (PyObject *)PyCFunction_New(m, NULL));
}
- /* register funcs (bpy_rna.c) */
+ /* Register functions (`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.h b/source/blender/python/intern/bpy.h
index 313385b7f5d..f62542bb342 100644
--- a/source/blender/python/intern/bpy.h
+++ b/source/blender/python/intern/bpy.h
@@ -12,7 +12,7 @@ extern "C" {
struct bContext;
-/** Creates the bpy module and adds it to `sys.modules` for importing. */
+/** Creates the `bpy` module and adds it to `sys.modules` for importing. */
void BPy_init_modules(struct bContext *C);
extern PyObject *bpy_package_py;
diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c
index a0129157b95..70cf231bc26 100644
--- a/source/blender/python/intern/bpy_app.c
+++ b/source/blender/python/intern/bpy_app.c
@@ -559,7 +559,7 @@ PyObject *BPY_app_struct(void)
BlenderAppType.tp_hash = (hashfunc)
_Py_HashPointer; /* without this we can't do set(sys.modules) T29635. */
- /* kindof a hack ontop of PyStructSequence */
+ /* Kind of a hack on top of #PyStructSequence. */
py_struct_seq_getset_init();
py_struct_seq_method_init();
diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c
index 8c5fb22eab1..3580481941d 100644
--- a/source/blender/python/intern/bpy_app_handlers.c
+++ b/source/blender/python/intern/bpy_app_handlers.c
@@ -132,7 +132,7 @@ static PyObject *bpy_app_handlers_persistent_new(PyTypeObject *UNUSED(type),
return NULL;
}
-/* dummy type because decorators can't be PyCFunctions */
+/** Dummy type because decorators can't be a #PyCFunction. */
static PyTypeObject BPyPersistent_Type = {
#if defined(_MSC_VER)
@@ -140,46 +140,54 @@ static PyTypeObject BPyPersistent_Type = {
#else
PyVarObject_HEAD_INIT(&PyType_Type, 0)
#endif
-
- "persistent", /* tp_name */
- 0, /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- 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 */
- 0, /* 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 */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- bpy_app_handlers_persistent_new, /* tp_new */
- 0, /* tp_free */
+ /*tp_name*/ "persistent",
+ /*tp_basicsize*/ 0,
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ NULL,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ NULL,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ NULL,
+ /*tp_as_mapping*/ NULL,
+ /*tp_hash*/ NULL,
+ /*tp_call*/ NULL,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ NULL,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ NULL,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ NULL,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ bpy_app_handlers_persistent_new,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
static PyObject *py_cb_array[BKE_CB_EVT_TOT] = {NULL};
diff --git a/source/blender/python/intern/bpy_app_icons.c b/source/blender/python/intern/bpy_app_icons.c
index 918d96d9f44..65edbb597ca 100644
--- a/source/blender/python/intern/bpy_app_icons.c
+++ b/source/blender/python/intern/bpy_app_icons.c
@@ -162,14 +162,14 @@ static struct PyMethodDef M_AppIcons_methods[] = {
static struct PyModuleDef M_AppIcons_module_def = {
PyModuleDef_HEAD_INIT,
- "bpy.app.icons", /* m_name */
- NULL, /* m_doc */
- 0, /* m_size */
- M_AppIcons_methods, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "bpy.app.icons",
+ /*m_doc*/ NULL,
+ /*m_size*/ 0,
+ /*m_methods*/ M_AppIcons_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPY_app_icons_module(void)
diff --git a/source/blender/python/intern/bpy_app_timers.c b/source/blender/python/intern/bpy_app_timers.c
index 4adc200357b..e5de5121e9e 100644
--- a/source/blender/python/intern/bpy_app_timers.c
+++ b/source/blender/python/intern/bpy_app_timers.c
@@ -164,14 +164,14 @@ static struct PyMethodDef M_AppTimers_methods[] = {
static struct PyModuleDef M_AppTimers_module_def = {
PyModuleDef_HEAD_INIT,
- "bpy.app.timers", /* m_name */
- NULL, /* m_doc */
- 0, /* m_size */
- M_AppTimers_methods, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "bpy.app.timers",
+ /*m_doc*/ NULL,
+ /*m_size*/ 0,
+ /*m_methods*/ M_AppTimers_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPY_app_timers_module(void)
diff --git a/source/blender/python/intern/bpy_app_translations.c b/source/blender/python/intern/bpy_app_translations.c
index 152c871c9be..1f5565eb0a7 100644
--- a/source/blender/python/intern/bpy_app_translations.c
+++ b/source/blender/python/intern/bpy_app_translations.c
@@ -424,7 +424,7 @@ static PyObject *app_translations_contexts_make(void)
}
#define SetObjString(item) \
- PyStructSequence_SET_ITEM(translations_contexts, pos++, PyUnicode_FromString((item)))
+ PyStructSequence_SET_ITEM(translations_contexts, pos++, PyUnicode_FromString(item))
#define SetObjNone() \
PyStructSequence_SET_ITEM(translations_contexts, pos++, Py_INCREF_RET(Py_None))
@@ -773,84 +773,54 @@ PyDoc_STRVAR(app_translations_doc,
"\n");
static PyTypeObject BlenderAppTranslationsType = {
PyVarObject_HEAD_INIT(NULL, 0)
- /* tp_name */
- "bpy.app._translations_type",
- /* tp_basicsize */
- sizeof(BlenderAppTranslations),
- 0, /* tp_itemsize */
- /* methods */
- /* No destructor, this is a singleton! */
- NULL, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL,
- /* tp_compare */ /* DEPRECATED in python 3.0! */
- NULL, /* tp_repr */
-
- /* Method suites for standard classes */
- NULL, /* PyNumberMethods *tp_as_number; */
- NULL, /* PySequenceMethods *tp_as_sequence; */
- NULL, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
- NULL, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
- NULL, /* getattrofunc tp_getattro; */
- NULL, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT, /* long tp_flags; */
-
- app_translations_doc, /* char *tp_doc; Documentation string */
-
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons ***/
- NULL, /* richcmpfunc tp_richcompare; */
-
- /*** weak reference enabler ***/
- 0, /* long tp_weaklistoffset */
-
- /*** Added in release 2.2 ***/
- /* Iterators */
- NULL, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
-
- /*** Attribute descriptor and subclassing stuff ***/
- app_translations_methods, /* struct PyMethodDef *tp_methods; */
- app_translations_members, /* struct PyMemberDef *tp_members; */
- app_translations_getseters, /* struct PyGetSetDef *tp_getset; */
- NULL, /* struct _typeobject *tp_base; */
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- 0, /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- /* newfunc tp_new; */
- (newfunc)app_translations_new,
- /* Low-level free-memory routine */
- app_translations_free, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL,
+ /*tp_name*/ "bpy.app._translations_type",
+ /*tp_basicsize*/ sizeof(BlenderAppTranslations),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ NULL,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ NULL,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ NULL,
+ /*tp_as_mapping*/ NULL,
+ /*tp_hash*/ NULL,
+ /*tp_call*/ NULL,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT,
+ /*tp_doc*/ app_translations_doc,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ NULL,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ app_translations_methods,
+ /*tp_members*/ app_translations_members,
+ /*tp_getset*/ app_translations_getseters,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ (newfunc)app_translations_new,
+ /*tp_free*/ app_translations_free,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
PyObject *BPY_app_translations_struct(void)
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index 04aa203d198..9f2714405a9 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -225,7 +225,7 @@ static void bpy_pydriver_namespace_update_depsgraph(struct Depsgraph *depsgraph)
}
if ((g_pydriver_state_prev.depsgraph == NULL) ||
- ((depsgraph != g_pydriver_state_prev.depsgraph->ptr.data))) {
+ (depsgraph != g_pydriver_state_prev.depsgraph->ptr.data)) {
PyObject *item = bpy_pydriver_depsgraph_as_pyobject(depsgraph);
PyDict_SetItem(bpy_pydriver_Dict, bpy_intern_str_depsgraph, item);
Py_DECREF(item);
diff --git a/source/blender/python/intern/bpy_gizmo_wrap.c b/source/blender/python/intern/bpy_gizmo_wrap.c
index ad235e691c4..99720e7a1ba 100644
--- a/source/blender/python/intern/bpy_gizmo_wrap.c
+++ b/source/blender/python/intern/bpy_gizmo_wrap.c
@@ -150,7 +150,7 @@ void BPY_RNA_gizmo_wrapper(wmGizmoType *gzt, void *userdata)
/* don't do translations here yet */
#if 0
- /* Use i18n context from rna_ext.srna if possible (py gizmogroups). */
+ /* Use i18n context from rna_ext.srna if possible (py gizmo-groups). */
if (gt->rna_ext.srna) {
RNA_def_struct_translation_context(gt->srna, RNA_struct_translation_context(gt->rna_ext.srna));
}
diff --git a/source/blender/python/intern/bpy_gizmo_wrap.h b/source/blender/python/intern/bpy_gizmo_wrap.h
index 6a876747e22..7d5edebed0f 100644
--- a/source/blender/python/intern/bpy_gizmo_wrap.h
+++ b/source/blender/python/intern/bpy_gizmo_wrap.h
@@ -13,7 +13,7 @@ struct wmGizmoType;
extern "C" {
#endif
-/* exposed to rna/wm api */
+/* Exposed to RNA/WM API. */
void BPY_RNA_gizmo_wrapper(struct wmGizmoType *gzt, void *userdata);
void BPY_RNA_gizmogroup_wrapper(struct wmGizmoGroupType *gzgt, void *userdata);
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 3a095f4b9f3..a83dc464e43 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -768,14 +768,14 @@ extern void main_python_exit(void);
static struct PyModuleDef bpy_proxy_def = {
PyModuleDef_HEAD_INIT,
- "bpy", /* m_name */
- NULL, /* m_doc */
- 0, /* m_size */
- NULL, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- bpy_module_free, /* m_free */
+ /*m_name*/ "bpy",
+ /*m_doc*/ NULL,
+ /*m_size*/ 0,
+ /*m_methods*/ NULL,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ bpy_module_free,
};
typedef struct {
diff --git a/source/blender/python/intern/bpy_interface_run.c b/source/blender/python/intern/bpy_interface_run.c
index 886f5ee278d..49f5261ba19 100644
--- a/source/blender/python/intern/bpy_interface_run.c
+++ b/source/blender/python/intern/bpy_interface_run.c
@@ -259,7 +259,7 @@ static bool bpy_run_string_impl(bContext *C,
py_dict = PyC_DefaultNameSpace("<blender string>");
- if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
+ if (imports && !PyC_NameSpace_ImportArray(py_dict, imports)) {
Py_DECREF(py_dict);
retval = NULL;
}
diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c
index 9754599eeed..acc6e2cf448 100644
--- a/source/blender/python/intern/bpy_library_load.c
+++ b/source/blender/python/intern/bpy_library_load.c
@@ -84,82 +84,55 @@ static void bpy_lib_dealloc(BPy_Library *self)
}
static PyTypeObject bpy_lib_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "bpy_lib", /* tp_name */
- sizeof(BPy_Library), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- (destructor)bpy_lib_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL,
- /* tp_compare */ /* DEPRECATED in python 3.0! */
- NULL, /* tp_repr */
-
- /* Method suites for standard classes */
-
- NULL, /* PyNumberMethods *tp_as_number; */
- NULL, /* PySequenceMethods *tp_as_sequence; */
- NULL, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- NULL, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
-
- /* will only use these if this is a subtype of a py class */
- PyObject_GenericGetAttr, /* getattrofunc tp_getattro; */
- NULL, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons (subclassed) ***/
- NULL, /* richcmpfunc tp_richcompare; */
-
- /*** weak reference enabler ***/
- 0,
- /*** Added in release 2.2 ***/
- /* Iterators */
- NULL, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
-
- /*** Attribute descriptor and subclassing stuff ***/
- bpy_lib_methods, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- NULL, /* struct PyGetSetDef *tp_getset; */
- NULL, /* struct _typeobject *tp_base; */
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- offsetof(BPy_Library, dict), /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- NULL, /* newfunc tp_new; */
- /* Low-level free-memory routine */
- NULL, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL,
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "bpy_lib",
+ /*tp_basicsize*/ sizeof(BPy_Library),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)bpy_lib_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ NULL,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ NULL,
+ /*tp_as_mapping*/ NULL,
+ /*tp_hash*/ NULL,
+ /*tp_call*/ NULL,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ PyObject_GenericGetAttr,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ NULL,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ bpy_lib_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ NULL,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ offsetof(BPy_Library, dict),
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ NULL,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
PyDoc_STRVAR(
diff --git a/source/blender/python/intern/bpy_msgbus.c b/source/blender/python/intern/bpy_msgbus.c
index 10165bf6b0d..835ef8f7f1f 100644
--- a/source/blender/python/intern/bpy_msgbus.c
+++ b/source/blender/python/intern/bpy_msgbus.c
@@ -42,7 +42,7 @@
" - :class:`bpy.types.Property` instance.\n" \
" - :class:`bpy.types.Struct` type.\n" \
" - (:class:`bpy.types.Struct`, str) type and property name.\n" \
- " :type key: Muliple\n"
+ " :type key: Multiple\n"
/**
* There are multiple ways we can get RNA from Python,
@@ -265,7 +265,7 @@ static PyObject *bpy_msgbus_subscribe_rna(PyObject *UNUSED(self), PyObject *args
}
if (py_options &&
- (pyrna_enum_bitfield_from_set(py_options_enum, py_options, &options, error_prefix)) == -1) {
+ (pyrna_enum_bitfield_from_set(py_options_enum, py_options, &options, error_prefix) == -1)) {
return NULL;
}
@@ -393,8 +393,14 @@ static struct PyMethodDef BPy_msgbus_methods[] = {
static struct PyModuleDef _bpy_msgbus_def = {
PyModuleDef_HEAD_INIT,
- .m_name = "msgbus",
- .m_methods = BPy_msgbus_methods,
+ /*m_name*/ "msgbus",
+ /*m_doc*/ NULL,
+ /*m_size*/ 0,
+ /*m_methods*/ BPy_msgbus_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPY_msgbus_module(void)
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index 95879b02295..546e67a521f 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -289,7 +289,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
reports = MEM_mallocN(sizeof(ReportList), "wmOperatorReportList");
/* Own so these don't move into global reports. */
- BKE_reports_init(reports, RPT_STORE | RPT_OP_HOLD);
+ BKE_reports_init(reports, RPT_STORE | RPT_OP_HOLD | RPT_PRINT_HANDLED_BY_OWNER);
#ifdef BPY_RELEASE_GIL
/* release GIL, since a thread could be started from an operator
@@ -493,14 +493,14 @@ static struct PyMethodDef bpy_ops_methods[] = {
static struct PyModuleDef bpy_ops_module = {
PyModuleDef_HEAD_INIT,
- "_bpy.ops",
- NULL,
- -1, /* multiple "initialization" just copies the module dict. */
- bpy_ops_methods,
- NULL,
- NULL,
- NULL,
- NULL,
+ /*m_name*/ "_bpy.ops",
+ /*m_doc*/ NULL,
+ /*m_size*/ -1, /* multiple "initialization" just copies the module dict. */
+ /*m_methods*/ bpy_ops_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPY_operator_module(void)
diff --git a/source/blender/python/intern/bpy_operator_wrap.h b/source/blender/python/intern/bpy_operator_wrap.h
index de3779332da..4b8ceba5f0c 100644
--- a/source/blender/python/intern/bpy_operator_wrap.h
+++ b/source/blender/python/intern/bpy_operator_wrap.h
@@ -12,10 +12,11 @@ struct wmOperatorType;
extern "C" {
#endif
-/* these are used for operator methods, used by bpy_operator.c */
+/** These are used for operator methods, used by `bpy_operator.c`. */
PyObject *PYOP_wrap_macro_define(PyObject *self, PyObject *args);
-/* exposed to rna/wm api */
+/* Exposed to RNA/WM API. */
+
/**
* Generic function used by all Python defined operators
* it's passed as an argument to #WM_operatortype_append_ptr in for operator registration.
diff --git a/source/blender/python/intern/bpy_path.c b/source/blender/python/intern/bpy_path.c
index f3a1a7cb1df..6b9a09b636b 100644
--- a/source/blender/python/intern/bpy_path.c
+++ b/source/blender/python/intern/bpy_path.c
@@ -22,14 +22,14 @@ extern const char *imb_ext_audio[];
/*----------------------------MODULE INIT-------------------------*/
static struct PyModuleDef _bpy_path_module_def = {
PyModuleDef_HEAD_INIT,
- "_bpy_path", /* m_name */
- NULL, /* m_doc */
- 0, /* m_size */
- NULL, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "_bpy_path",
+ /*m_doc*/ NULL,
+ /*m_size*/ 0,
+ /*m_methods*/ NULL,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPyInit__bpy_path(void)
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index 3f2154189e8..dec4c65e48d 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -307,6 +307,7 @@ static PyObject *bpy_prop_deferred_data_CreatePyObject(PyObject *fn, PyObject *k
Py_INCREF(kw);
}
self->kw = kw;
+ BLI_assert(!PyObject_GC_IsTracked((PyObject *)self));
PyObject_GC_Track(self);
return (PyObject *)self;
}
@@ -394,7 +395,7 @@ static int bpy_prop_array_length_parse(PyObject *o, void *p)
if (PyLong_CheckExact(o)) {
int size;
- if (((size = PyLong_AsLong(o)) == -1)) {
+ if ((size = PyLong_AsLong(o)) == -1) {
PyErr_Format(
PyExc_ValueError, "expected number or sequence of numbers, got %s", Py_TYPE(o)->tp_name);
return 0;
@@ -427,7 +428,7 @@ static int bpy_prop_array_length_parse(PyObject *o, void *p)
PyObject **seq_items = PySequence_Fast_ITEMS(seq_fast);
for (int i = 0; i < seq_len; i++) {
int size;
- if (((size = PyLong_AsLong(seq_items[i])) == -1)) {
+ if ((size = PyLong_AsLong(seq_items[i])) == -1) {
Py_DECREF(seq_fast);
PyErr_Format(PyExc_ValueError,
"expected number in sequence, got %s at index %d",
@@ -4620,21 +4621,25 @@ static int props_clear(PyObject *UNUSED(self))
return 0;
}
-static struct PyModuleDef props_module = {
- PyModuleDef_HEAD_INIT,
- "bpy.props",
+PyDoc_STRVAR(
+ props_module_doc,
"This module defines properties to extend Blender's internal data. The result of these "
"functions"
" is used to assign properties to classes registered with Blender and can't be used "
"directly.\n"
"\n"
- ".. note:: All parameters to these functions must be passed as keywords.\n",
- -1, /* multiple "initialization" just copies the module dict. */
- props_methods,
- NULL,
- props_visit,
- props_clear,
- NULL,
+ ".. note:: All parameters to these functions must be passed as keywords.\n");
+
+static struct PyModuleDef props_module = {
+ PyModuleDef_HEAD_INIT,
+ /*m_name*/ "bpy.props",
+ /*m_doc*/ props_module_doc,
+ /*m_size*/ -1, /* multiple "initialization" just copies the module dict. */
+ /*m_methods*/ props_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ props_visit,
+ /*m_clear*/ props_clear,
+ /*m_free*/ NULL,
};
PyObject *BPY_rna_props(void)
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 941e0adfc1d..c61cab5aa6f 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -380,10 +380,10 @@ static short pyrna_rotation_euler_order_get(PointerRNA *ptr,
const short order_fallback,
PropertyRNA **r_prop_eul_order);
-/* bpyrna vector/euler/quat callbacks. */
+/* `bpyrna` vector/euler/quaternion callbacks. */
static uchar mathutils_rna_array_cb_index = -1; /* Index for our callbacks. */
-/* Subtype not used much yet. */
+/* Sub-type not used much yet. */
# define MATHUTILS_CB_SUBTYPE_EUL 0
# define MATHUTILS_CB_SUBTYPE_VEC 1
# define MATHUTILS_CB_SUBTYPE_QUAT 2
@@ -993,7 +993,7 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self)
}
if (len != -1) {
- sprintf(--c, "[%d]", len);
+ BLI_sprintf(--c, "[%d]", len);
}
/* If a pointer, try to print name of pointer target too. */
@@ -1174,6 +1174,7 @@ static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference)
if (reference) {
self->reference = reference;
Py_INCREF(reference);
+ BLI_assert(!PyObject_GC_IsTracked((PyObject *)self));
PyObject_GC_Track(self);
}
}
@@ -1397,7 +1398,7 @@ PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
buf = RNA_property_string_get_alloc(ptr, prop, buf_fixed, sizeof(buf_fixed), &buf_len);
#ifdef USE_STRING_COERCE
- /* Only file paths get special treatment, they may contain non utf-8 chars. */
+ /* Only file paths get special treatment, they may contain non UTF-8 chars. */
if (subtype == PROP_BYTESTRING) {
ret = PyBytes_FromStringAndSize(buf, buf_len);
}
@@ -1810,7 +1811,7 @@ static int pyrna_py_to_prop(
* 'self.properties -> self'
* class mixing. If this causes problems in the future it should be removed.
*/
- if ((ptr_type == &RNA_AnyType) && (BPy_StructRNA_Check(value))) {
+ if ((ptr_type == &RNA_AnyType) && BPy_StructRNA_Check(value)) {
const StructRNA *base_type = RNA_struct_base_child_of(
((const BPy_StructRNA *)value)->ptr.type, NULL);
if (ELEM(base_type, &RNA_Operator, &RNA_Gizmo)) {
@@ -1956,7 +1957,7 @@ static int pyrna_py_to_prop(
BKE_reports_init(&reports, RPT_STORE);
RNA_property_pointer_set(
ptr, prop, (param == NULL) ? PointerRNA_NULL : param->ptr, &reports);
- const int err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true));
+ const int err = BPy_reports_to_error(&reports, PyExc_RuntimeError, true);
if (err == -1) {
Py_XDECREF(value_new);
return -1;
@@ -2327,7 +2328,7 @@ static int pyrna_prop_collection_ass_subscript_int(BPy_PropertyRNA *self,
return 0;
}
-static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, int keynum)
+static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, Py_ssize_t keynum)
{
int len;
@@ -2478,7 +2479,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
ID *id = itemptr.data; /* Always an ID. */
- if (id->lib == lib && (STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2))) {
+ if (id->lib == lib && STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2)) {
found = true;
if (r_ptr) {
*r_ptr = itemptr;
@@ -2882,7 +2883,7 @@ static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject
if (key_slice->start == Py_None && key_slice->stop == Py_None) {
/* NOTE: no significant advantage with optimizing [:] slice as with collections,
* but include here for consistency with collection slice func */
- const Py_ssize_t len = (Py_ssize_t)pyrna_prop_array_length(self);
+ const Py_ssize_t len = pyrna_prop_array_length(self);
return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
}
@@ -3250,41 +3251,67 @@ static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self,
/* For slice only. */
static PyMappingMethods pyrna_prop_array_as_mapping = {
- (lenfunc)pyrna_prop_array_length, /* mp_length */
- (binaryfunc)pyrna_prop_array_subscript, /* mp_subscript */
- (objobjargproc)pyrna_prop_array_ass_subscript, /* mp_ass_subscript */
+ /*mp_len*/ (lenfunc)pyrna_prop_array_length,
+ /*mp_subscript*/ (binaryfunc)pyrna_prop_array_subscript,
+ /*mp_ass_subscript*/ (objobjargproc)pyrna_prop_array_ass_subscript,
};
static PyMappingMethods pyrna_prop_collection_as_mapping = {
- (lenfunc)pyrna_prop_collection_length, /* mp_length */
- (binaryfunc)pyrna_prop_collection_subscript, /* mp_subscript */
- (objobjargproc)pyrna_prop_collection_ass_subscript, /* mp_ass_subscript */
+ /*mp_len*/ (lenfunc)pyrna_prop_collection_length,
+ /*mp_subscript*/ (binaryfunc)pyrna_prop_collection_subscript,
+ /*mp_ass_subscript*/ (objobjargproc)pyrna_prop_collection_ass_subscript,
};
/* Only for fast bool's, large structs, assign nb_bool on init. */
static PyNumberMethods pyrna_prop_array_as_number = {
- NULL, /* nb_add */
- NULL, /* nb_subtract */
- NULL, /* nb_multiply */
- NULL, /* nb_remainder */
- NULL, /* nb_divmod */
- NULL, /* nb_power */
- NULL, /* nb_negative */
- NULL, /* nb_positive */
- NULL, /* nb_absolute */
- (inquiry)pyrna_prop_array_bool, /* nb_bool */
+ /*nb_add*/ NULL,
+ /*nb_subtract*/ NULL,
+ /*nb_multiply*/ NULL,
+ /*nb_remainder*/ NULL,
+ /*nb_divmod*/ NULL,
+ /*nb_power*/ NULL,
+ /*nb_negative*/ NULL,
+ /*nb_positive*/ NULL,
+ /*nb_absolute*/ NULL,
+ /*nb_bool*/ (inquiry)pyrna_prop_array_bool,
};
static PyNumberMethods pyrna_prop_collection_as_number = {
- NULL, /* nb_add */
- NULL, /* nb_subtract */
- NULL, /* nb_multiply */
- NULL, /* nb_remainder */
- NULL, /* nb_divmod */
- NULL, /* nb_power */
- NULL, /* nb_negative */
- NULL, /* nb_positive */
- NULL, /* nb_absolute */
- (inquiry)pyrna_prop_collection_bool, /* nb_bool */
+ /*nb_add*/ NULL,
+ /*nb_subtract*/ NULL,
+ /*nb_multiply*/ NULL,
+ /*nb_remainder*/ NULL,
+ /*nb_divmod*/ NULL,
+ /*nb_power*/ NULL,
+ /*nb_negative*/ NULL,
+ /*nb_positive*/ NULL,
+ /*nb_absolute*/ NULL,
+ /*nb_bool*/ (inquiry)pyrna_prop_collection_bool,
+ /*nb_invert*/ NULL,
+ /*nb_lshift*/ NULL,
+ /*nb_rshift*/ NULL,
+ /*nb_and*/ NULL,
+ /*nb_xor*/ NULL,
+ /*nb_or*/ NULL,
+ /*nb_int*/ NULL,
+ /*nb_reserved*/ NULL,
+ /*nb_float*/ NULL,
+ /*nb_inplace_add*/ NULL,
+ /*nb_inplace_subtract*/ NULL,
+ /*nb_inplace_multiply*/ NULL,
+ /*nb_inplace_remainder*/ NULL,
+ /*nb_inplace_power*/ NULL,
+ /*nb_inplace_lshift*/ NULL,
+ /*nb_inplace_rshift*/ NULL,
+ /*nb_inplace_and*/ NULL,
+ /*nb_inplace_xor*/ NULL,
+ /*nb_inplace_or*/ NULL,
+ /*nb_floor_divide*/ NULL,
+ /*nb_true_divide*/ NULL,
+ /*nb_inplace_floor_divide*/ NULL,
+ /*nb_inplace_true_divide*/ NULL,
+ /*nb_index*/ NULL,
+ /*nb_matrix_multiply*/ NULL,
+ /*nb_inplace_matrix_multiply*/ NULL,
};
static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value)
@@ -3344,46 +3371,46 @@ static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
}
static PySequenceMethods pyrna_prop_array_as_sequence = {
- (lenfunc)pyrna_prop_array_length,
- NULL, /* sq_concat */
- NULL, /* sq_repeat */
- (ssizeargfunc)pyrna_prop_array_subscript_int,
- /* sq_item */ /* Only set this so PySequence_Check() returns True */
- NULL, /* sq_slice */
- (ssizeobjargproc)prop_subscript_ass_array_int, /* sq_ass_item */
- NULL, /* *was* sq_ass_slice */
- (objobjproc)pyrna_prop_array_contains, /* sq_contains */
- (binaryfunc)NULL, /* sq_inplace_concat */
- (ssizeargfunc)NULL, /* sq_inplace_repeat */
+ /*sq_length*/ (lenfunc)pyrna_prop_array_length,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /* Only set this so `PySequence_Check()` returns True. */
+ /*sq_item*/ (ssizeargfunc)pyrna_prop_array_subscript_int,
+ /*sq_slice*/ NULL,
+ /*sq_ass_item*/ (ssizeobjargproc)prop_subscript_ass_array_int,
+ /* was_sq_ass_slice */ NULL, /* DEPRECATED. */
+ /*sq_contains*/ (objobjproc)pyrna_prop_array_contains,
+ /*sq_inplace_concat*/ NULL,
+ /*sq_inplace_repeat*/ NULL,
};
static PySequenceMethods pyrna_prop_collection_as_sequence = {
- (lenfunc)pyrna_prop_collection_length,
- NULL, /* sq_concat */
- NULL, /* sq_repeat */
- (ssizeargfunc)pyrna_prop_collection_subscript_int,
- /* sq_item */ /* Only set this so PySequence_Check() returns True */
- NULL, /* *was* sq_slice */
- (ssizeobjargproc) /* pyrna_prop_collection_ass_subscript_int */
- NULL /* let mapping take this one */, /* sq_ass_item */
- NULL, /* *was* sq_ass_slice */
- (objobjproc)pyrna_prop_collection_contains, /* sq_contains */
- (binaryfunc)NULL, /* sq_inplace_concat */
- (ssizeargfunc)NULL, /* sq_inplace_repeat */
+ /*sq_length*/ (lenfunc)pyrna_prop_collection_length,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /* Only set this so PySequence_Check() returns True */
+ /*sq_item*/ (ssizeargfunc)pyrna_prop_collection_subscript_int,
+ /*was_sq_slice*/ NULL, /* DEPRECATED. */
+ /* Let mapping take this one: #pyrna_prop_collection_ass_subscript_int */
+ /*sq_ass_item*/ NULL,
+ /*was_sq_ass_slice*/ NULL, /* DEPRECATED. */
+ /*sq_contains*/ (objobjproc)pyrna_prop_collection_contains,
+ /*sq_inplace_concat*/ NULL,
+ /*sq_inplace_repeat*/ NULL,
};
static PySequenceMethods pyrna_struct_as_sequence = {
- NULL, /* Can't set the len otherwise it can evaluate as false */
- NULL, /* sq_concat */
- NULL, /* sq_repeat */
- NULL,
- /* sq_item */ /* Only set this so PySequence_Check() returns True */
- NULL, /* *was* sq_slice */
- NULL, /* sq_ass_item */
- NULL, /* *was* sq_ass_slice */
- (objobjproc)pyrna_struct_contains, /* sq_contains */
- (binaryfunc)NULL, /* sq_inplace_concat */
- (ssizeargfunc)NULL, /* sq_inplace_repeat */
+ /*sq_length*/ NULL, /* Can't set the len otherwise it can evaluate as false */
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /* Only set this so `PySequence_Check()` returns True. */
+ /*sq_item*/ NULL,
+ /*was_sq_slice*/ NULL, /* DEPRECATED. */
+ /*sq_ass_item */ NULL,
+ /*was_sq_ass_slice*/ NULL, /* DEPRECATED. */
+ /*sq_contains*/ (objobjproc)pyrna_struct_contains,
+ /*sq_inplace_concat*/ NULL,
+ /*sq_inplace_repeat*/ NULL,
};
static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key)
@@ -3456,9 +3483,9 @@ static int pyrna_struct_ass_subscript(BPy_StructRNA *self, PyObject *key, PyObje
}
static PyMappingMethods pyrna_struct_as_mapping = {
- (lenfunc)NULL, /* mp_length */
- (binaryfunc)pyrna_struct_subscript, /* mp_subscript */
- (objobjargproc)pyrna_struct_ass_subscript, /* mp_ass_subscript */
+ /*mp_length*/ (lenfunc)NULL,
+ /*mp_subscript*/ (binaryfunc)pyrna_struct_subscript,
+ /*mp_ass_subscript*/ (objobjargproc)pyrna_struct_ass_subscript,
};
PyDoc_STRVAR(pyrna_struct_keys_doc,
@@ -3470,8 +3497,10 @@ PyDoc_STRVAR(pyrna_struct_keys_doc,
" :return: custom property keys.\n"
" :rtype: :class:`idprop.type.IDPropertyGroupViewKeys`\n"
"\n" BPY_DOC_ID_PROP_TYPE_NOTE);
-static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self)
+static PyObject *pyrna_struct_keys(BPy_StructRNA *self)
{
+ PYRNA_STRUCT_CHECK_OBJ(self);
+
if (RNA_struct_idprops_check(self->ptr.type) == 0) {
PyErr_SetString(PyExc_TypeError, "bpy_struct.keys(): this type doesn't support IDProperties");
return NULL;
@@ -3491,8 +3520,10 @@ PyDoc_STRVAR(pyrna_struct_items_doc,
" :return: custom property key, value pairs.\n"
" :rtype: :class:`idprop.type.IDPropertyGroupViewItems`\n"
"\n" BPY_DOC_ID_PROP_TYPE_NOTE);
-static PyObject *pyrna_struct_items(BPy_PropertyRNA *self)
+static PyObject *pyrna_struct_items(BPy_StructRNA *self)
{
+ PYRNA_STRUCT_CHECK_OBJ(self);
+
if (RNA_struct_idprops_check(self->ptr.type) == 0) {
PyErr_SetString(PyExc_TypeError, "bpy_struct.items(): this type doesn't support IDProperties");
return NULL;
@@ -3512,8 +3543,10 @@ PyDoc_STRVAR(pyrna_struct_values_doc,
" :return: custom property values.\n"
" :rtype: :class:`idprop.type.IDPropertyGroupViewValues`\n"
"\n" BPY_DOC_ID_PROP_TYPE_NOTE);
-static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
+static PyObject *pyrna_struct_values(BPy_StructRNA *self)
{
+ PYRNA_STRUCT_CHECK_OBJ(self);
+
if (RNA_struct_idprops_check(self->ptr.type) == 0) {
PyErr_SetString(PyExc_TypeError,
"bpy_struct.values(): this type doesn't support IDProperties");
@@ -4074,7 +4107,7 @@ static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr)
{
const char *idname;
- /* For looping over attrs and funcs. */
+ /* For looping over attributes and functions. */
PointerRNA tptr;
PropertyRNA *iterprop;
@@ -5573,7 +5606,7 @@ static PyObject *pyprop_array_foreach_getset(BPy_PropertyArrayRNA *self,
}
else {
const char f = buf.format ? buf.format[0] : 0;
- if ((prop_type == PROP_INT && (buf.itemsize != sizeof(int) || (!ELEM(f, 'l', 'i')))) ||
+ if ((prop_type == PROP_INT && (buf.itemsize != sizeof(int) || !ELEM(f, 'l', 'i'))) ||
(prop_type == PROP_FLOAT && (buf.itemsize != sizeof(float) || f != 'f'))) {
PyBuffer_Release(&buf);
PyErr_Format(PyExc_TypeError, "incorrect sequence item type: %s", buf.format);
@@ -5937,7 +5970,7 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
len = RNA_property_array_length(ptr, prop);
}
- /* Resolve the array from a new pytype. */
+ /* Resolve the array from a new Python type. */
/* TODO(Kazanbas): make multi-dimensional sequences here. */
@@ -6403,7 +6436,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
BKE_reports_init(&reports, RPT_STORE);
RNA_function_call(C, &reports, self_ptr, self_func, &parms);
- err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true));
+ err = BPy_reports_to_error(&reports, PyExc_RuntimeError, true);
/* Return value. */
if (err != -1) {
@@ -6482,606 +6515,415 @@ static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void *UNUSED(closure)
return ret;
}
-/* Subclasses of pyrna_struct_Type which support idprop definitions use this as a metaclass. */
-/* NOTE: tp_base member is set to &PyType_Type on init. */
+/**
+ * Sub-classes of #pyrna_struct_Type which support idprop definitions use this as a meta-class.
+ * \note tp_base member is set to `&PyType_Type` on initialization.
+ */
PyTypeObject pyrna_struct_meta_idprop_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "bpy_struct_meta_idprop", /* tp_name */
-
- /* NOTE: would be PyTypeObject, but subtypes of Type must be PyHeapTypeObject's. */
- sizeof(PyHeapTypeObject), /* tp_basicsize */
-
- 0, /* tp_itemsize */
- /* methods */
- NULL, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL,
- /* tp_compare */ /* deprecated in Python 3.0! */
- NULL, /* tp_repr */
-
- /* Method suites for standard classes */
- NULL, /* PyNumberMethods *tp_as_number; */
- NULL, /* PySequenceMethods *tp_as_sequence; */
- NULL, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
- NULL, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
- NULL /* (getattrofunc) pyrna_struct_meta_idprop_getattro */, /* getattrofunc tp_getattro; */
- (setattrofunc)pyrna_struct_meta_idprop_setattro, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons ***/
- NULL, /* richcmpfunc tp_richcompare; */
-
- /*** weak reference enabler ***/
- 0, /* long tp_weaklistoffset; */
-
- /*** Added in release 2.2 ***/
- /* Iterators */
- NULL, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
-
- /*** Attribute descriptor and subclassing stuff ***/
- NULL, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- NULL, /* struct PyGetSetDef *tp_getset; */
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "bpy_struct_meta_idprop",
+ /* NOTE: would be `sizeof(PyTypeObject)`,
+ * but sub-types of Type must be #PyHeapTypeObject's. */
+ /*tp_basicsize*/ sizeof(PyHeapTypeObject),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ NULL,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ NULL,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ NULL,
+ /*tp_as_mapping*/ NULL,
+ /*tp_hash*/ NULL,
+ /*tp_call*/ NULL,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ NULL, /* Sub-classed: #pyrna_struct_meta_idprop_getattro. */
+ /*tp_setattro*/ (setattrofunc)pyrna_struct_meta_idprop_setattro,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ NULL,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ NULL,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ NULL,
#if defined(_MSC_VER)
- NULL, /* defer assignment */
+ /*tp_base*/ NULL, /* Defer assignment. */
#else
- &PyType_Type, /* struct _typeobject *tp_base; */
+ /*tp_base*/ &PyType_Type,
#endif
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- 0, /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- NULL, /* newfunc tp_new; */
- /* Low-level free-memory routine */
- NULL, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ NULL,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
/*-----------------------BPy_StructRNA method def------------------------------*/
PyTypeObject pyrna_struct_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "bpy_struct", /* tp_name */
- sizeof(BPy_StructRNA), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- (destructor)pyrna_struct_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL,
- /* tp_compare */ /* DEPRECATED in Python 3.0! */
- (reprfunc)pyrna_struct_repr, /* tp_repr */
-
- /* Method suites for standard classes */
-
- NULL, /* PyNumberMethods *tp_as_number; */
- &pyrna_struct_as_sequence, /* PySequenceMethods *tp_as_sequence; */
- &pyrna_struct_as_mapping, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- (hashfunc)pyrna_struct_hash, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
- (reprfunc)pyrna_struct_str, /* reprfunc tp_str; */
- (getattrofunc)pyrna_struct_getattro, /* getattrofunc tp_getattro; */
- (setattrofunc)pyrna_struct_setattro, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "bpy_struct",
+ /*tp_basicsize*/ sizeof(BPy_StructRNA),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)pyrna_struct_dealloc,
+ /*tp_vectorcall_offset */ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ (reprfunc)pyrna_struct_repr,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ &pyrna_struct_as_sequence,
+ /*tp_as_mapping*/ &pyrna_struct_as_mapping,
+ /*tp_hash*/ (hashfunc)pyrna_struct_hash,
+ /*tp_call*/ NULL,
+ /*tp_str*/ (reprfunc)pyrna_struct_str,
+ /*tp_getattro*/ (getattrofunc)pyrna_struct_getattro,
+ /*tp_setattro*/ (setattrofunc)pyrna_struct_setattro,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
#ifdef USE_PYRNA_STRUCT_REFERENCE
| Py_TPFLAGS_HAVE_GC
#endif
- , /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
-/*** Assigned meaning in release 2.0 ***/
-/* call function for all accessible objects */
+ ,
+ /*tp_doc*/ NULL,
#ifdef USE_PYRNA_STRUCT_REFERENCE
- (traverseproc)pyrna_struct_traverse, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- (inquiry)pyrna_struct_clear, /* inquiry tp_clear; */
+ /*tp_traverse*/ (traverseproc)pyrna_struct_traverse,
+ /*tp_clear*/ (inquiry)pyrna_struct_clear,
#else
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
#endif /* !USE_PYRNA_STRUCT_REFERENCE */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons ***/
- (richcmpfunc)pyrna_struct_richcmp, /* richcmpfunc tp_richcompare; */
-
-/*** weak reference enabler ***/
+ /*tp_richcompare*/ (richcmpfunc)pyrna_struct_richcmp,
#ifdef USE_WEAKREFS
- offsetof(BPy_StructRNA, in_weakreflist), /* long tp_weaklistoffset; */
+ /*tp_weaklistoffset*/ offsetof(BPy_StructRNA, in_weakreflist),
#else
0,
#endif
- /*** Added in release 2.2 ***/
- /* Iterators */
- NULL, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
-
- /*** Attribute descriptor and subclassing stuff ***/
- pyrna_struct_methods, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- pyrna_struct_getseters, /* struct PyGetSetDef *tp_getset; */
- NULL, /* struct _typeobject *tp_base; */
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- 0, /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- pyrna_struct_new, /* newfunc tp_new; */
- /* Low-level free-memory routine */
- NULL, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ pyrna_struct_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ pyrna_struct_getseters,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ pyrna_struct_new,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
/*-----------------------BPy_PropertyRNA method def------------------------------*/
PyTypeObject pyrna_prop_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop", /* tp_name */
- sizeof(BPy_PropertyRNA), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- (destructor)pyrna_prop_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL,
- /* tp_compare */ /* DEPRECATED in Python 3.0! */
- (reprfunc)pyrna_prop_repr, /* tp_repr */
-
- /* Method suites for standard classes */
-
- NULL, /* PyNumberMethods *tp_as_number; */
- NULL, /* PySequenceMethods *tp_as_sequence; */
- NULL, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- (hashfunc)pyrna_prop_hash, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
- (reprfunc)pyrna_prop_str, /* reprfunc tp_str; */
-
- /* will only use these if this is a subtype of a py class */
- NULL, /* getattrofunc tp_getattro; */
- NULL, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons ***/
- (richcmpfunc)pyrna_prop_richcmp, /* richcmpfunc tp_richcompare; */
-
-/*** weak reference enabler ***/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "bpy_prop",
+ /*tp_basicsize*/ sizeof(BPy_PropertyRNA),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)pyrna_prop_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ (reprfunc)pyrna_prop_repr,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ NULL,
+ /*tp_as_mapping*/ NULL,
+ /*tp_hash*/ (hashfunc)pyrna_prop_hash,
+ /*tp_call*/ NULL,
+ /*tp_str*/ (reprfunc)pyrna_prop_str,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ (richcmpfunc)pyrna_prop_richcmp,
#ifdef USE_WEAKREFS
- offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */
+ /*tp_weaklistoffset*/ offsetof(BPy_PropertyRNA, in_weakreflist),
#else
- 0,
+ /*tp_weaklistoffset*/ 0,
#endif
-
- /*** Added in release 2.2 ***/
- /* Iterators */
- NULL, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
-
- /*** Attribute descriptor and subclassing stuff ***/
- pyrna_prop_methods, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- pyrna_prop_getseters, /* struct PyGetSetDef *tp_getset; */
- NULL, /* struct _typeobject *tp_base; */
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- 0, /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- pyrna_prop_new, /* newfunc tp_new; */
- /* Low-level free-memory routine */
- NULL, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ pyrna_prop_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ pyrna_prop_getseters,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ pyrna_prop_new,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
PyTypeObject pyrna_prop_array_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop_array", /* tp_name */
- sizeof(BPy_PropertyArrayRNA), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- (destructor)pyrna_prop_array_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL,
- /* tp_compare */ /* DEPRECATED in Python 3.0! */
- (reprfunc)pyrna_prop_array_repr, /* tp_repr */
-
- /* Method suites for standard classes */
-
- &pyrna_prop_array_as_number, /* PyNumberMethods *tp_as_number; */
- &pyrna_prop_array_as_sequence, /* PySequenceMethods *tp_as_sequence; */
- &pyrna_prop_array_as_mapping, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- NULL, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
-
- /* will only use these if this is a subtype of a py class */
- (getattrofunc)pyrna_prop_array_getattro, /* getattrofunc tp_getattro; */
- NULL, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons (subclassed) ***/
- NULL, /* richcmpfunc tp_richcompare; */
-
-/*** weak reference enabler ***/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "bpy_prop_array",
+ /*tp_basicsize*/ sizeof(BPy_PropertyArrayRNA),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)pyrna_prop_array_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ (reprfunc)pyrna_prop_array_repr,
+ /*tp_as_number*/ &pyrna_prop_array_as_number,
+ /*tp_as_sequence*/ &pyrna_prop_array_as_sequence,
+ /*tp_as_mapping*/ &pyrna_prop_array_as_mapping,
+ /*tp_hash*/ NULL,
+ /*tp_call*/ NULL,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ (getattrofunc)pyrna_prop_array_getattro,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ NULL,
#ifdef USE_WEAKREFS
- offsetof(BPy_PropertyArrayRNA, in_weakreflist), /* long tp_weaklistoffset; */
+ /*tp_weaklistoffset*/ offsetof(BPy_PropertyArrayRNA, in_weakreflist),
#else
- 0,
+ /*tp_weaklistoffset*/ 0,
#endif
- /*** Added in release 2.2 ***/
- /* Iterators */
- (getiterfunc)pyrna_prop_array_iter, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
-
- /*** Attribute descriptor and subclassing stuff ***/
- pyrna_prop_array_methods, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- NULL /*pyrna_prop_getseters*/, /* struct PyGetSetDef *tp_getset; */
- &pyrna_prop_Type, /* struct _typeobject *tp_base; */
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- 0, /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- NULL, /* newfunc tp_new; */
- /* Low-level free-memory routine */
- NULL, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL,
+ /*tp_iter*/ (getiterfunc)pyrna_prop_array_iter,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ pyrna_prop_array_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ NULL /* Sub-classed: #pyrna_prop_getseters. */,
+ /*tp_base*/ &pyrna_prop_Type,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ NULL,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
PyTypeObject pyrna_prop_collection_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop_collection", /* tp_name */
- sizeof(BPy_PropertyRNA), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- (destructor)pyrna_prop_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL,
- /* tp_compare */ /* DEPRECATED in Python 3.0! */
- NULL,
- /* subclassed */ /* tp_repr */
-
- /* Method suites for standard classes */
-
- &pyrna_prop_collection_as_number, /* PyNumberMethods *tp_as_number; */
- &pyrna_prop_collection_as_sequence, /* PySequenceMethods *tp_as_sequence; */
- &pyrna_prop_collection_as_mapping, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- NULL, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
-
- /* will only use these if this is a subtype of a py class */
- (getattrofunc)pyrna_prop_collection_getattro, /* getattrofunc tp_getattro; */
- (setattrofunc)pyrna_prop_collection_setattro, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons (subclassed) ***/
- NULL, /* richcmpfunc tp_richcompare; */
-
-/*** weak reference enabler ***/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "bpy_prop_collection",
+ /*tp_basicsize*/ sizeof(BPy_PropertyRNA),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)pyrna_prop_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ NULL, /* Sub-classed, no need to define. */
+ /*tp_as_number*/ &pyrna_prop_collection_as_number,
+ /*tp_as_sequence*/ &pyrna_prop_collection_as_sequence,
+ /*tp_as_mapping*/ &pyrna_prop_collection_as_mapping,
+ /*tp_hash*/ NULL,
+ /*tp_call*/ NULL,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ (getattrofunc)pyrna_prop_collection_getattro,
+ /*tp_setattro*/ (setattrofunc)pyrna_prop_collection_setattro,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ NULL,
#ifdef USE_WEAKREFS
- offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */
+ /*tp_weaklistoffset*/ offsetof(BPy_PropertyRNA, in_weakreflist),
#else
- 0,
+ /*tp_weaklistoffset*/ 0,
#endif
-
- /*** Added in release 2.2 ***/
- /* Iterators */
- (getiterfunc)pyrna_prop_collection_iter, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
-
- /*** Attribute descriptor and subclassing stuff ***/
- pyrna_prop_collection_methods, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- NULL /*pyrna_prop_getseters*/, /* struct PyGetSetDef *tp_getset; */
- &pyrna_prop_Type, /* struct _typeobject *tp_base; */
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- 0, /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- NULL, /* newfunc tp_new; */
- /* Low-level free-memory routine */
- NULL, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL,
+ /*tp_iter*/ (getiterfunc)pyrna_prop_collection_iter,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ pyrna_prop_collection_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ NULL /*Sub-classed: see #pyrna_prop_getseters. */,
+ /*tp_base*/ &pyrna_prop_Type,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ NULL,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
/* only for add/remove/move methods */
static PyTypeObject pyrna_prop_collection_idprop_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop_collection_idprop", /* tp_name */
- sizeof(BPy_PropertyRNA), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- (destructor)pyrna_prop_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL,
- /* tp_compare */ /* DEPRECATED in Python 3.0! */
- NULL,
- /* subclassed */ /* tp_repr */
-
- /* Method suites for standard classes */
-
- NULL, /* PyNumberMethods *tp_as_number; */
- NULL, /* PySequenceMethods *tp_as_sequence; */
- NULL, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- NULL, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
-
- /* will only use these if this is a subtype of a py class */
- NULL, /* getattrofunc tp_getattro; */
- NULL, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons (subclassed) ***/
- NULL, /* richcmpfunc tp_richcompare; */
-
-/*** weak reference enabler ***/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "bpy_prop_collection_idprop",
+ /*tp_basicsize*/ sizeof(BPy_PropertyRNA),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)pyrna_prop_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_compare*/ NULL, /* DEPRECATED. */
+ /*tp_repr*/ NULL, /* Sub-classed, no need to define. */
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ NULL,
+ /*tp_as_mapping*/ NULL,
+ /*tp_hash*/ NULL,
+ /*tp_call*/ NULL,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ NULL,
#ifdef USE_WEAKREFS
- offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */
+ /*tp_weaklistoffset*/ offsetof(BPy_PropertyRNA, in_weakreflist),
#else
- 0,
+ /*tp_weaklistoffset*/ 0,
#endif
-
- /*** Added in release 2.2 ***/
- /* Iterators */
- NULL, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
-
- /*** Attribute descriptor and subclassing stuff ***/
- pyrna_prop_collection_idprop_methods, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- NULL /*pyrna_prop_getseters*/, /* struct PyGetSetDef *tp_getset; */
- &pyrna_prop_collection_Type, /* struct _typeobject *tp_base; */
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- 0, /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- NULL, /* newfunc tp_new; */
- /* Low-level free-memory routine */
- NULL, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ pyrna_prop_collection_idprop_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ NULL /* Sub-classed: #pyrna_prop_getseters. */,
+ /*tp_base*/ &pyrna_prop_collection_Type,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ NULL,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
/*-----------------------BPy_PropertyRNA method def------------------------------*/
PyTypeObject pyrna_func_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "bpy_func", /* tp_name */
- sizeof(BPy_FunctionRNA), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- NULL, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL,
- /* tp_compare */ /* DEPRECATED in Python 3.0! */
- (reprfunc)pyrna_func_repr, /* tp_repr */
-
- /* Method suites for standard classes */
-
- NULL, /* PyNumberMethods *tp_as_number; */
- NULL, /* PySequenceMethods *tp_as_sequence; */
- NULL, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- NULL, /* hashfunc tp_hash; */
- (ternaryfunc)pyrna_func_call, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
-
- /* will only use these if this is a subtype of a py class */
- NULL, /* getattrofunc tp_getattro; */
- NULL, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons ***/
- NULL, /* richcmpfunc tp_richcompare; */
-
-/*** weak reference enabler ***/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "bpy_func",
+ /*tp_basicsize*/ sizeof(BPy_FunctionRNA),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ NULL,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ (reprfunc)pyrna_func_repr,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ NULL,
+ /*tp_as_mapping*/ NULL,
+ /*tp_hash*/ NULL,
+ /*tp_call*/ (ternaryfunc)pyrna_func_call,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ NULL,
#ifdef USE_WEAKREFS
- offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */
+ /*tp_weaklistoffset*/ offsetof(BPy_PropertyRNA, in_weakreflist),
#else
- 0,
+ /*tp_weaklistoffset*/ 0,
#endif
-
- /*** Added in release 2.2 ***/
- /* Iterators */
- NULL, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
-
- /*** Attribute descriptor and subclassing stuff ***/
- NULL, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- pyrna_func_getseters, /* struct PyGetSetDef *tp_getset; */
- NULL, /* struct _typeobject *tp_base; */
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- 0, /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- NULL, /* newfunc tp_new; */
- /* Low-level free-memory routine */
- NULL, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ NULL,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ pyrna_func_getseters,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ NULL,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
#ifdef USE_PYRNA_ITER
@@ -7097,87 +6939,59 @@ static void pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA *se
static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self);
static PyTypeObject pyrna_prop_collection_iter_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop_collection_iter", /* tp_name */
- sizeof(BPy_PropertyCollectionIterRNA), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- (destructor)pyrna_prop_collection_iter_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL,
- /* tp_compare */ /* DEPRECATED in Python 3.0! */
- NULL,
- /* subclassed */ /* tp_repr */
-
- /* Method suites for standard classes */
-
- NULL, /* PyNumberMethods *tp_as_number; */
- NULL, /* PySequenceMethods *tp_as_sequence; */
- NULL, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- NULL, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
-
- /* will only use these if this is a subtype of a py class */
- PyObject_GenericGetAttr, /* getattrofunc tp_getattro; */
- NULL, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons (subclassed) ***/
- NULL, /* richcmpfunc tp_richcompare; */
-
-/*** weak reference enabler ***/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "bpy_prop_collection_iter",
+ /*tp_basicsize*/ sizeof(BPy_PropertyCollectionIterRNA),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)pyrna_prop_collection_iter_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ NULL, /* No need to define, sub-classed. */
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ NULL,
+ /*tp_as_mapping*/ NULL,
+ /*tp_hash*/ NULL,
+ /*tp_call*/ NULL,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ PyObject_GenericGetAttr,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ NULL,
# ifdef USE_WEAKREFS
- offsetof(BPy_PropertyCollectionIterRNA, in_weakreflist), /* long tp_weaklistoffset; */
+ /*tp_weaklistoffset*/ offsetof(BPy_PropertyCollectionIterRNA, in_weakreflist),
# else
- 0,
+ /*tp_weaklistoffset*/ 0,
# endif
- /*** Added in release 2.2 ***/
- /* Iterators */
- PyObject_SelfIter, /* getiterfunc tp_iter; */
- (iternextfunc)pyrna_prop_collection_iter_next, /* iternextfunc tp_iternext; */
-
- /*** Attribute descriptor and subclassing stuff ***/
- NULL, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- NULL, /* struct PyGetSetDef *tp_getset; */
- NULL, /* struct _typeobject *tp_base; */
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- 0, /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- NULL, /* newfunc tp_new; */
- /* Low-level free-memory routine */
- NULL, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL,
+ /*tp_iter*/ PyObject_SelfIter,
+ /*tp_iternext*/ (iternextfunc)pyrna_prop_collection_iter_next,
+ /*tp_methods*/ NULL,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ NULL,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ NULL,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
static PyObject *pyrna_prop_collection_iter_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop)
@@ -7252,7 +7066,7 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
PyC_ObSpit("RNA WAS SET - ", RNA_struct_py_type_get(srna));
}
- Py_XDECREF(((PyObject *)RNA_struct_py_type_get(srna)));
+ Py_XDECREF((PyObject *)RNA_struct_py_type_get(srna));
RNA_struct_py_type_set(srna, (void *)newclass); /* Store for later use */
@@ -7308,7 +7122,7 @@ static PyObject *pyrna_srna_PyBase(StructRNA *srna) //, PyObject *bpy_types_dic
if (base && base != srna) {
// printf("debug subtype %s %p\n", RNA_struct_identifier(srna), srna);
py_base = pyrna_srna_Subtype(base); //, bpy_types_dict);
- Py_DECREF(py_base); /* Srna owns, this is only to pass as an arg. */
+ Py_DECREF(py_base); /* `srna` owns, this is only to pass as an argument. */
}
if (py_base == NULL) {
@@ -7667,7 +7481,7 @@ bool pyrna_id_FromPyObject(PyObject *obj, ID **id)
bool pyrna_id_CheckPyObject(PyObject *obj)
{
- return BPy_StructRNA_Check(obj) && (RNA_struct_is_ID(((BPy_StructRNA *)obj)->ptr.type));
+ return BPy_StructRNA_Check(obj) && RNA_struct_is_ID(((BPy_StructRNA *)obj)->ptr.type);
}
void BPY_rna_init(void)
@@ -7864,14 +7678,14 @@ static struct PyMethodDef bpy_types_module_methods[] = {
PyDoc_STRVAR(bpy_types_module_doc, "Access to internal Blender types");
static struct PyModuleDef bpy_types_module_def = {
PyModuleDef_HEAD_INIT,
- "bpy.types", /* m_name */
- bpy_types_module_doc, /* m_doc */
- sizeof(struct BPy_TypesModule_State), /* m_size */
- bpy_types_module_methods, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "bpy.types",
+ /*m_doc*/ bpy_types_module_doc,
+ /*m_size*/ sizeof(struct BPy_TypesModule_State),
+ /*m_methods*/ bpy_types_module_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPY_rna_types(void)
@@ -8461,7 +8275,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr,
#undef BPY_REPLACEMENT_STRING
- if (item == NULL && (((flag & PROP_REGISTER_OPTIONAL) != PROP_REGISTER_OPTIONAL))) {
+ if (item == NULL && ((flag & PROP_REGISTER_OPTIONAL) != PROP_REGISTER_OPTIONAL)) {
PyErr_Format(PyExc_AttributeError,
"expected %.200s, %.200s class to have an \"%.200s\" attribute",
class_type,
@@ -8735,10 +8549,10 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
else if (ret_len == 1) {
err = pyrna_py_to_prop(&funcptr, pret_single, retdata_single, ret, "");
- /* when calling operator funcs only gives Function.result with
- * no line number since the func has finished calling on error,
- * re-raise the exception with more info since it would be slow to
- * create prefix on every call (when there are no errors) */
+ /* When calling operator functions only gives `Function.result` with no line number
+ * since the function has finished calling on error, re-raise the exception with more
+ * information since it would be slow to create prefix on every call
+ * (when there are no errors). */
if (err == -1) {
PyC_Err_Format_Prefix(PyExc_RuntimeError,
"class %.200s, function %.200s: incompatible return value ",
@@ -8795,7 +8609,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
ReportList *reports;
/* Alert the user, else they won't know unless they see the console. */
if ((!is_staticmethod) && (!is_classmethod) && (ptr->data) &&
- (RNA_struct_is_a(ptr->type, &RNA_Operator)) &&
+ RNA_struct_is_a(ptr->type, &RNA_Operator) &&
(is_valid_wm == (CTX_wm_manager(C) != NULL))) {
wmOperator *op = ptr->data;
reports = op->reports;
@@ -8846,7 +8660,7 @@ static void bpy_class_free(void *pyob_ptr)
}
/**
- * \note This isn't essential to run on startup, since subtypes will lazy initialize.
+ * \note This isn't essential to run on startup, since sub-types will lazy initialize.
* But keep running in debug mode so we get immediate notification of bad class hierarchy
* or any errors in "bpy_types.py" at load time, so errors don't go unnoticed.
*/
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index 91fa0ea2c8d..d7778da6213 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -218,11 +218,13 @@ void pyrna_struct_type_extend_capi(struct StructRNA *srna,
struct PyMethodDef *py_method,
struct PyGetSetDef *py_getset);
-/* called before stopping python */
+/* Called before stopping Python. */
+
void pyrna_alloc_types(void);
void pyrna_free_types(void);
-/* primitive type conversion */
+/* Primitive type conversion. */
+
int pyrna_py_to_array(
PointerRNA *ptr, PropertyRNA *prop, char *param_data, PyObject *py, const char *error_prefix);
int pyrna_py_to_array_index(PointerRNA *ptr,
diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c
index 8506ec97bc3..48ba028edf0 100644
--- a/source/blender/python/intern/bpy_rna_array.c
+++ b/source/blender/python/intern/bpy_rna_array.c
@@ -927,7 +927,7 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyArrayRNA *self,
/* just in case check */
len = RNA_property_multi_array_length(ptr, prop, arraydim);
if (index >= len || index < 0) {
- /* this shouldn't happen because higher level funcs must check for invalid index */
+ /* This shouldn't happen because higher level functions must check for invalid index. */
CLOG_WARN(BPY_LOG_RNA, "invalid index %d for array with length=%d", index, len);
PyErr_SetString(PyExc_IndexError, "out of range");
diff --git a/source/blender/python/intern/bpy_rna_data.c b/source/blender/python/intern/bpy_rna_data.c
index cc0b4aa57d5..2dc0b8dc999 100644
--- a/source/blender/python/intern/bpy_rna_data.c
+++ b/source/blender/python/intern/bpy_rna_data.c
@@ -60,84 +60,56 @@ static void bpy_rna_data_context_dealloc(BPy_DataContext *self)
Py_CLEAR(self->data_rna);
PyObject_GC_Del(self);
}
-
static PyTypeObject bpy_rna_data_context_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "bpy_rna_data_context", /* tp_name */
- sizeof(BPy_DataContext), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- (destructor)bpy_rna_data_context_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL,
- /* tp_compare */ /* DEPRECATED in python 3.0! */
- NULL, /* tp_repr */
-
- /* Method suites for standard classes */
-
- NULL, /* PyNumberMethods *tp_as_number; */
- NULL, /* PySequenceMethods *tp_as_sequence; */
- NULL, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- NULL, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
-
- /* will only use these if this is a subtype of a py class */
- NULL, /* getattrofunc tp_getattro; */
- NULL, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- (traverseproc)bpy_rna_data_context_traverse, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- (inquiry)bpy_rna_data_context_clear, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons (subclassed) ***/
- NULL, /* richcmpfunc tp_richcompare; */
-
- /*** weak reference enabler ***/
- 0,
- /*** Added in release 2.2 ***/
- /* Iterators */
- NULL, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
-
- /*** Attribute descriptor and subclassing stuff ***/
- bpy_rna_data_context_methods, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- NULL, /* struct PyGetSetDef *tp_getset; */
- NULL, /* struct _typeobject *tp_base; */
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- 0, /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- NULL, /* newfunc tp_new; */
- /* Low-level free-memory routine */
- NULL, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL,
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "bpy_rna_data_context",
+ /*tp_basicsize*/ sizeof(BPy_DataContext),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)bpy_rna_data_context_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ NULL,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ NULL,
+ /*tp_as_mapping*/ NULL,
+ /*tp_hash*/ NULL,
+ /*tp_call*/ NULL,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ (traverseproc)bpy_rna_data_context_traverse,
+ /*tp_clear*/ (inquiry)bpy_rna_data_context_clear,
+ /*tp_richcompare*/ NULL,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ bpy_rna_data_context_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ NULL,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ NULL,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
PyDoc_STRVAR(bpy_rna_data_context_load_doc,
@@ -183,6 +155,7 @@ static PyObject *bpy_rna_data_context_enter(BPy_DataContext *self)
self->data_rna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
+ BLI_assert(!PyObject_GC_IsTracked((PyObject *)self));
PyObject_GC_Track(self);
return (PyObject *)self->data_rna;
diff --git a/source/blender/python/intern/bpy_rna_operator.c b/source/blender/python/intern/bpy_rna_operator.c
index fd6cc93ed32..e0a4356dc18 100644
--- a/source/blender/python/intern/bpy_rna_operator.c
+++ b/source/blender/python/intern/bpy_rna_operator.c
@@ -84,7 +84,7 @@ PyDoc_STRVAR(BPY_rna_operator_poll_message_set_doc,
" When message is callable, "
"additional user defined positional arguments are passed to the message function.\n"
"\n"
- " :param message: The message or a function that returns the message.\n"
+ " :arg message: The message or a function that returns the message.\n"
" :type message: string or a callable that returns a string or None.\n");
static PyObject *BPY_rna_operator_poll_message_set(PyObject *UNUSED(self), PyObject *args)
diff --git a/source/blender/python/intern/bpy_rna_types_capi.c b/source/blender/python/intern/bpy_rna_types_capi.c
index c3a07847aff..2b830eb9ffe 100644
--- a/source/blender/python/intern/bpy_rna_types_capi.c
+++ b/source/blender/python/intern/bpy_rna_types_capi.c
@@ -185,16 +185,16 @@ PyDoc_STRVAR(
" It will be called every time the specified region in the space type will be drawn.\n"
" Note: All arguments are positional only for now.\n"
"\n"
- " :param callback:\n"
+ " :arg callback:\n"
" A function that will be called when the region is drawn.\n"
" It gets the specified arguments as input.\n"
" :type callback: function\n"
- " :param args: Arguments that will be passed to the callback.\n"
+ " :arg args: Arguments that will be passed to the callback.\n"
" :type args: tuple\n"
- " :param region_type: The region type the callback draws in; usually ``WINDOW``. "
+ " :arg region_type: The region type the callback draws in; usually ``WINDOW``. "
"(:class:`bpy.types.Region.type`)\n"
" :type region_type: str\n"
- " :param draw_type: Usually ``POST_PIXEL`` for 2D drawing and ``POST_VIEW`` for 3D drawing. "
+ " :arg draw_type: Usually ``POST_PIXEL`` for 2D drawing and ``POST_VIEW`` for 3D drawing. "
"In some cases ``PRE_VIEW`` can be used. ``BACKDROP`` can be used for backdrops in the node "
"editor.\n"
" :type draw_type: str\n"
@@ -206,9 +206,9 @@ PyDoc_STRVAR(pyrna_draw_handler_remove_doc,
"\n"
" Remove a draw handler that was added previously.\n"
"\n"
- " :param handler: The draw handler that should be removed.\n"
+ " :arg handler: The draw handler that should be removed.\n"
" :type handler: object\n"
- " :param region_type: Region type the callback was added to.\n"
+ " :arg region_type: Region type the callback was added to.\n"
" :type region_type: str\n");
static struct PyMethodDef pyrna_space_methods[] = {
diff --git a/source/blender/python/intern/bpy_traceback.c b/source/blender/python/intern/bpy_traceback.c
index 1f2458c752f..428263fd4c4 100644
--- a/source/blender/python/intern/bpy_traceback.c
+++ b/source/blender/python/intern/bpy_traceback.c
@@ -25,7 +25,7 @@ static const char *traceback_filepath(PyTracebackObject *tb, PyObject **coerce)
return PyBytes_AS_STRING(*coerce);
}
-/* copied from pythonrun.c, 3.10.0 */
+/* Copied from `pythonrun.c`, 3.10.0 */
_Py_static_string(PyId_string, "<string>");
static int parse_syntax_error(PyObject *err,
diff --git a/source/blender/python/intern/bpy_utils_previews.c b/source/blender/python/intern/bpy_utils_previews.c
index aa79ac56347..83e74816020 100644
--- a/source/blender/python/intern/bpy_utils_previews.c
+++ b/source/blender/python/intern/bpy_utils_previews.c
@@ -163,14 +163,14 @@ PyDoc_STRVAR(
"(low-level API, not exposed to final users).");
static struct PyModuleDef bpy_utils_previews_module = {
PyModuleDef_HEAD_INIT,
- "bpy._utils_previews",
- bpy_utils_previews_doc,
- 0,
- bpy_utils_previews_methods,
- NULL,
- NULL,
- NULL,
- NULL,
+ /*m_name*/ "bpy._utils_previews",
+ /*m_doc*/ bpy_utils_previews_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ bpy_utils_previews_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPY_utils_previews_module(void)
diff --git a/source/blender/python/intern/bpy_utils_units.c b/source/blender/python/intern/bpy_utils_units.c
index 1e5856a3285..95d7f4f2eb7 100644
--- a/source/blender/python/intern/bpy_utils_units.c
+++ b/source/blender/python/intern/bpy_utils_units.c
@@ -90,7 +90,7 @@ static PyObject *py_structseq_from_strings(PyTypeObject *py_type,
const char **str_iter;
PyStructSequence_Field *desc;
- /* initialize array */
+ /* Initialize array. */
/* We really populate the contexts' fields here! */
for (str_iter = str_items, desc = py_sseq_desc->fields; *str_iter; str_iter++, desc++) {
desc->name = (char *)*str_iter;
@@ -101,7 +101,7 @@ static PyObject *py_structseq_from_strings(PyTypeObject *py_type,
PyStructSequence_InitType(py_type, py_sseq_desc);
- /* initialize pytype */
+ /* Initialize the Python type. */
py_struct_seq = PyStructSequence_New(py_type);
BLI_assert(py_struct_seq != NULL);
@@ -336,14 +336,14 @@ PyDoc_STRVAR(bpyunits_doc, "This module contains some data/methods regarding uni
static struct PyModuleDef bpyunits_module = {
PyModuleDef_HEAD_INIT,
- "bpy.utils.units",
- bpyunits_doc,
- -1, /* multiple "initialization" just copies the module dict. */
- bpyunits_methods,
- NULL,
- NULL,
- NULL,
- NULL,
+ /*m_name*/ "bpy.utils.units",
+ /*m_doc*/ bpyunits_doc,
+ /*m_size*/ -1, /* multiple "initialization" just copies the module dict. */
+ /*m_methods*/ bpyunits_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyObject *BPY_utils_units(void)
diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c
index dcb6d7f3bc6..ef5339c3aa3 100644
--- a/source/blender/python/mathutils/mathutils.c
+++ b/source/blender/python/mathutils/mathutils.c
@@ -47,8 +47,7 @@ static int mathutils_array_parse_fast(float *array,
i = size;
do {
i--;
- if (((array[i] = PyFloat_AsDouble((item = value_fast_items[i]))) == -1.0f) &&
- PyErr_Occurred()) {
+ if (((array[i] = PyFloat_AsDouble(item = value_fast_items[i])) == -1.0f) && PyErr_Occurred()) {
PyErr_Format(PyExc_TypeError,
"%.200s: sequence index %d expected a number, "
"found '%.200s' type, ",
@@ -317,7 +316,7 @@ int mathutils_int_array_parse(int *array, int array_dim, PyObject *value, const
i = size;
while (i > 0) {
i--;
- if (((array[i] = PyC_Long_AsI32((item = value_fast_items[i]))) == -1) && PyErr_Occurred()) {
+ if (((array[i] = PyC_Long_AsI32(item = value_fast_items[i])) == -1) && PyErr_Occurred()) {
PyErr_Format(PyExc_TypeError, "%.200s: sequence index %d expected an int", error_prefix, i);
size = -1;
break;
@@ -698,6 +697,18 @@ int BaseMathObject_clear(BaseMathObject *self)
return 0;
}
+/** Only to validate assumptions when debugging. */
+#ifndef NDEBUG
+static bool BaseMathObject_is_tracked(BaseMathObject *self)
+{
+ PyObject *cb_user = self->cb_user;
+ self->cb_user = (void *)(uintptr_t)-1;
+ bool is_tracked = PyObject_GC_IsTracked((PyObject *)self);
+ self->cb_user = cb_user;
+ return is_tracked;
+}
+#endif /* NDEBUG */
+
void BaseMathObject_dealloc(BaseMathObject *self)
{
/* only free non wrapped */
@@ -706,11 +717,46 @@ void BaseMathObject_dealloc(BaseMathObject *self)
}
if (self->cb_user) {
+ BLI_assert(BaseMathObject_is_tracked(self) == true);
PyObject_GC_UnTrack(self);
BaseMathObject_clear(self);
}
+ else if (!BaseMathObject_CheckExact(self)) {
+ /* Sub-classed types get an extra track (in Pythons internal `subtype_dealloc` function). */
+ BLI_assert(BaseMathObject_is_tracked(self) == true);
+ PyObject_GC_UnTrack(self);
+ BLI_assert(BaseMathObject_is_tracked(self) == false);
+ }
+
+ Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); /* breaks sub-types. */
+}
+
+int BaseMathObject_is_gc(BaseMathObject *self)
+{
+ return self->cb_user != NULL;
+}
+
+PyObject *_BaseMathObject_new_impl(PyTypeObject *root_type, PyTypeObject *base_type)
+{
+ PyObject *obj;
+ if (ELEM(base_type, NULL, root_type)) {
+ obj = _PyObject_GC_New(root_type);
+ if (obj) {
+ BLI_assert(BaseMathObject_is_tracked((BaseMathObject *)obj) == false);
+ }
+ }
+ else {
+ /* Calls Generic allocation function which always tracks
+ * (because `root_type` is flagged for GC). */
+ obj = base_type->tp_alloc(base_type, 0);
+ if (obj) {
+ BLI_assert(BaseMathObject_is_tracked((BaseMathObject *)obj) == true);
+ PyObject_GC_UnTrack(obj);
+ BLI_assert(BaseMathObject_is_tracked((BaseMathObject *)obj) == false);
+ }
+ }
- Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); /* breaks subtypes. */
+ return obj;
}
/*----------------------------MODULE INIT-------------------------*/
@@ -720,14 +766,14 @@ static struct PyMethodDef M_Mathutils_methods[] = {
static struct PyModuleDef M_Mathutils_module_def = {
PyModuleDef_HEAD_INIT,
- "mathutils", /* m_name */
- M_Mathutils_doc, /* m_doc */
- 0, /* m_size */
- M_Mathutils_methods, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "mathutils",
+ /*m_doc*/ M_Mathutils_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ M_Mathutils_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
/* submodules only */
diff --git a/source/blender/python/mathutils/mathutils.h b/source/blender/python/mathutils/mathutils.h
index 84386e99d18..f4beaf92ad4 100644
--- a/source/blender/python/mathutils/mathutils.h
+++ b/source/blender/python/mathutils/mathutils.h
@@ -6,7 +6,7 @@
* \ingroup pymathutils
*/
-/* Can cast different mathutils types to this, use for generic funcs */
+/* Can cast different mathutils types to this, use for generic functions. */
#include "BLI_compiler_attrs.h"
@@ -17,11 +17,12 @@ extern char BaseMathObject_is_frozen_doc[];
extern char BaseMathObject_is_valid_doc[];
extern char BaseMathObject_owner_doc[];
+PyObject *_BaseMathObject_new_impl(PyTypeObject *root_type, PyTypeObject *base_type);
+
#define BASE_MATH_NEW(struct_name, root_type, base_type) \
- ((struct_name *)((base_type ? (base_type)->tp_alloc(base_type, 0) : \
- _PyObject_GC_New(&(root_type)))))
+ ((struct_name *)_BaseMathObject_new_impl(&root_type, base_type))
-/** BaseMathObject.flag */
+/** #BaseMathObject.flag */
enum {
/**
* Do not own the memory used in this vector,
@@ -43,9 +44,9 @@ enum {
float *_data; \
/** If this vector references another object, otherwise NULL, *Note* this owns its reference */ \
PyObject *cb_user; \
- /** Which user funcs do we adhere to, RNA, etc */ \
+ /** Which user functions do we adhere to, RNA, etc */ \
unsigned char cb_type; \
- /** Subtype: location, rotation... \
+ /** Sub-type: location, rotation... \
* to avoid defining many new functions for every attribute of the same type */ \
unsigned char cb_subtype; \
/** Wrapped data type. */ \
@@ -76,6 +77,7 @@ PyObject *BaseMathObject_freeze(BaseMathObject *self);
int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg);
int BaseMathObject_clear(BaseMathObject *self);
void BaseMathObject_dealloc(BaseMathObject *self);
+int BaseMathObject_is_gc(BaseMathObject *self);
PyMODINIT_FUNC PyInit_mathutils(void);
diff --git a/source/blender/python/mathutils/mathutils_Color.c b/source/blender/python/mathutils/mathutils_Color.c
index 88e8d880360..1a1ea1a2535 100644
--- a/source/blender/python/mathutils/mathutils_Color.c
+++ b/source/blender/python/mathutils/mathutils_Color.c
@@ -14,7 +14,9 @@
#include "../generic/py_capi_utils.h"
#include "../generic/python_utildefines.h"
-#include "IMB_colormanagement.h"
+#ifndef MATH_STANDALONE
+# include "IMB_colormanagement.h"
+#endif
#ifndef MATH_STANDALONE
# include "BLI_dynstr.h"
@@ -71,9 +73,8 @@ static PyObject *Color_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
case 0:
break;
case 1:
- if ((mathutils_array_parse(
- col, COLOR_SIZE, COLOR_SIZE, PyTuple_GET_ITEM(args, 0), "mathutils.Color()")) ==
- -1) {
+ if (mathutils_array_parse(
+ col, COLOR_SIZE, COLOR_SIZE, PyTuple_GET_ITEM(args, 0), "mathutils.Color()") == -1) {
return NULL;
}
break;
@@ -92,6 +93,8 @@ static PyObject *Color_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
/** \name Color Methods: Color Space Conversion
* \{ */
+#ifndef MATH_STANDALONE
+
PyDoc_STRVAR(Color_from_scene_linear_to_srgb_doc,
".. function:: from_scene_linear_to_srgb()\n"
"\n"
@@ -204,6 +207,8 @@ static PyObject *Color_from_rec709_linear_to_scene_linear(ColorObject *self)
return Color_CreatePyObject(col, Py_TYPE(self));
}
+#endif /* MATH_STANDALONE */
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -346,13 +351,13 @@ static Py_hash_t Color_hash(ColorObject *self)
* \{ */
/** Sequence length: `len(object)`. */
-static int Color_len(ColorObject *UNUSED(self))
+static Py_ssize_t Color_len(ColorObject *UNUSED(self))
{
return COLOR_SIZE;
}
/** Sequence accessor (get): `x = object[i]`. */
-static PyObject *Color_item(ColorObject *self, int i)
+static PyObject *Color_item(ColorObject *self, Py_ssize_t i)
{
if (i < 0) {
i = COLOR_SIZE - i;
@@ -373,7 +378,7 @@ static PyObject *Color_item(ColorObject *self, int i)
}
/** Sequence accessor (set): `object[i] = x`. */
-static int Color_ass_item(ColorObject *self, int i, PyObject *value)
+static int Color_ass_item(ColorObject *self, Py_ssize_t i, PyObject *value)
{
float f;
@@ -820,59 +825,61 @@ static PyObject *Color_neg(ColorObject *self)
* \{ */
static PySequenceMethods Color_SeqMethods = {
- (lenfunc)Color_len, /*sq_length*/
- (binaryfunc)NULL, /*sq_concat*/
- (ssizeargfunc)NULL, /*sq_repeat*/
- (ssizeargfunc)Color_item, /*sq_item*/
- NULL, /*sq_slice(DEPRECATED)*/
- (ssizeobjargproc)Color_ass_item, /*sq_ass_item*/
- NULL, /*sq_ass_slice(DEPRECATED)*/
- (objobjproc)NULL, /*sq_contains*/
- (binaryfunc)NULL, /*sq_inplace_concat*/
- (ssizeargfunc)NULL, /*sq_inplace_repeat*/
+ /*sq_length*/ (lenfunc)Color_len,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /*sq_item*/ (ssizeargfunc)Color_item,
+ /*was_sq_slice*/ NULL, /* DEPRECATED. */
+ /*sq_ass_item*/ (ssizeobjargproc)Color_ass_item,
+ /*was_sq_ass_slice*/ NULL, /* DEPRECATED. */
+ /*sq_contains*/ NULL,
+ /*sq_inplace_concat*/ NULL,
+ /*sq_inplace_repeat*/ NULL,
};
static PyMappingMethods Color_AsMapping = {
- (lenfunc)Color_len,
- (binaryfunc)Color_subscript,
- (objobjargproc)Color_ass_subscript,
+ /*mp_len*/ (lenfunc)Color_len,
+ /*mp_subscript*/ (binaryfunc)Color_subscript,
+ /*mp_ass_subscript*/ (objobjargproc)Color_ass_subscript,
};
static PyNumberMethods Color_NumMethods = {
- (binaryfunc)Color_add, /*nb_add*/
- (binaryfunc)Color_sub, /*nb_subtract*/
- (binaryfunc)Color_mul, /*nb_multiply*/
- NULL, /*nb_remainder*/
- NULL, /*nb_divmod*/
- NULL, /*nb_power*/
- (unaryfunc)Color_neg, /*nb_negative*/
- (unaryfunc)Color_copy, /*tp_positive*/
- (unaryfunc)NULL, /*tp_absolute*/
- (inquiry)NULL, /*tp_bool*/
- (unaryfunc)NULL, /*nb_invert*/
- NULL, /*nb_lshift*/
- (binaryfunc)NULL, /*nb_rshift*/
- NULL, /*nb_and*/
- NULL, /*nb_xor*/
- NULL, /*nb_or*/
- NULL, /*nb_int*/
- NULL, /*nb_reserved*/
- NULL, /*nb_float*/
- Color_iadd, /*nb_inplace_add*/
- Color_isub, /*nb_inplace_subtract*/
- Color_imul, /*nb_inplace_multiply*/
- NULL, /*nb_inplace_remainder*/
- NULL, /*nb_inplace_power*/
- NULL, /*nb_inplace_lshift*/
- NULL, /*nb_inplace_rshift*/
- NULL, /*nb_inplace_and*/
- NULL, /*nb_inplace_xor*/
- NULL, /*nb_inplace_or*/
- NULL, /*nb_floor_divide*/
- Color_div, /*nb_true_divide*/
- NULL, /*nb_inplace_floor_divide*/
- Color_idiv, /*nb_inplace_true_divide*/
- NULL, /*nb_index*/
+ /*nb_add*/ (binaryfunc)Color_add,
+ /*nb_subtract*/ (binaryfunc)Color_sub,
+ /*nb_multiply*/ (binaryfunc)Color_mul,
+ /*nb_remainder*/ NULL,
+ /*nb_divmod*/ NULL,
+ /*nb_power*/ NULL,
+ /*nb_negative*/ (unaryfunc)Color_neg,
+ /*tp_positive*/ (unaryfunc)Color_copy,
+ /*tp_absolute*/ NULL,
+ /*tp_bool*/ NULL,
+ /*nb_invert*/ NULL,
+ /*nb_lshift*/ NULL,
+ /*nb_rshift*/ NULL,
+ /*nb_and*/ NULL,
+ /*nb_xor*/ NULL,
+ /*nb_or*/ NULL,
+ /*nb_int*/ NULL,
+ /*nb_reserved*/ NULL,
+ /*nb_float*/ NULL,
+ /*nb_inplace_add*/ Color_iadd,
+ /*nb_inplace_subtract*/ Color_isub,
+ /*nb_inplace_multiply*/ Color_imul,
+ /*nb_inplace_remainder*/ NULL,
+ /*nb_inplace_power*/ NULL,
+ /*nb_inplace_lshift*/ NULL,
+ /*nb_inplace_rshift*/ NULL,
+ /*nb_inplace_and*/ NULL,
+ /*nb_inplace_xor*/ NULL,
+ /*nb_inplace_or*/ NULL,
+ /*nb_floor_divide*/ NULL,
+ /*nb_true_divide*/ Color_div,
+ /*nb_inplace_floor_divide*/ NULL,
+ /*nb_inplace_true_divide*/ Color_idiv,
+ /*nb_index*/ NULL,
+ /*nb_matrix_multiply*/ NULL,
+ /*nb_inplace_matrix_multiply*/ NULL,
};
/** \} */
@@ -1050,7 +1057,8 @@ static struct PyMethodDef Color_methods[] = {
/* base-math methods */
{"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
- /* Color-space methods. */
+/* Color-space methods. */
+#ifndef MATH_STANDALONE
{"from_scene_linear_to_srgb",
(PyCFunction)Color_from_scene_linear_to_srgb,
METH_NOARGS,
@@ -1083,6 +1091,8 @@ static struct PyMethodDef Color_methods[] = {
(PyCFunction)Color_from_rec709_linear_to_scene_linear,
METH_NOARGS,
Color_from_rec709_linear_to_scene_linear_doc},
+#endif /* MATH_STANDALONE */
+
{NULL, NULL, 0, NULL},
};
@@ -1092,6 +1102,10 @@ static struct PyMethodDef Color_methods[] = {
/** \name Color Type: Python Object Definition
* \{ */
+#ifdef MATH_STANDALONE
+# define Color_str NULL
+#endif
+
PyDoc_STRVAR(
color_doc,
".. class:: Color(rgb)\n"
@@ -1102,60 +1116,64 @@ PyDoc_STRVAR(
" the OpenColorIO configuration. The notable exception is user interface theming colors, "
" which are in sRGB color space.\n"
"\n"
- " :param rgb: (r, g, b) color values\n"
+ " :arg rgb: (r, g, b) color values\n"
" :type rgb: 3d vector\n");
PyTypeObject color_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "Color", /* tp_name */
- sizeof(ColorObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)BaseMathObject_dealloc, /* tp_dealloc */
- (printfunc)NULL, /* tp_print */
- NULL, /* tp_getattr */
- NULL, /* tp_setattr */
- NULL, /* tp_compare */
- (reprfunc)Color_repr, /* tp_repr */
- &Color_NumMethods, /* tp_as_number */
- &Color_SeqMethods, /* tp_as_sequence */
- &Color_AsMapping, /* tp_as_mapping */
- (hashfunc)Color_hash, /* tp_hash */
- NULL, /* tp_call */
-#ifndef MATH_STANDALONE
- (reprfunc)Color_str, /* tp_str */
-#else
- NULL, /* tp_str */
-#endif
- NULL, /* tp_getattro */
- NULL, /* tp_setattro */
- NULL, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
- color_doc, /* tp_doc */
- (traverseproc)BaseMathObject_traverse, /* tp_traverse */
- (inquiry)BaseMathObject_clear, /* tp_clear */
- (richcmpfunc)Color_richcmpr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- NULL, /* tp_iter */
- NULL, /* tp_iternext */
- Color_methods, /* tp_methods */
- NULL, /* tp_members */
- Color_getseters, /* tp_getset */
- NULL, /* tp_base */
- NULL, /* tp_dict */
- NULL, /* tp_descr_get */
- NULL, /* tp_descr_set */
- 0, /* tp_dictoffset */
- NULL, /* tp_init */
- NULL, /* tp_alloc */
- Color_new, /* tp_new */
- NULL, /* tp_free */
- NULL, /* tp_is_gc */
- NULL, /* tp_bases */
- NULL, /* tp_mro */
- NULL, /* tp_cache */
- NULL, /* tp_subclasses */
- NULL, /* tp_weaklist */
- NULL, /* tp_del */
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "Color",
+ /*tp_basicsize*/ sizeof(ColorObject),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)BaseMathObject_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ (reprfunc)Color_repr,
+ /*tp_as_number*/ &Color_NumMethods,
+ /*tp_as_sequence*/ &Color_SeqMethods,
+ /*tp_as_mapping*/ &Color_AsMapping,
+ /*tp_hash*/ (hashfunc)Color_hash,
+ /*tp_call*/ NULL,
+ /*tp_str*/ (reprfunc)Color_str,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ /*tp_doc*/ color_doc,
+ /*tp_traverse*/ (traverseproc)BaseMathObject_traverse,
+ /*tp_clear*/ (inquiry)BaseMathObject_clear,
+ /*tp_richcompare*/ (richcmpfunc)Color_richcmpr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ Color_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ Color_getseters,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ Color_new,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ (inquiry)BaseMathObject_is_gc,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
+#ifdef MATH_STANDALONE
+# define Color_str
+#endif
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -1226,6 +1244,7 @@ PyObject *Color_CreatePyObject_cb(PyObject *cb_user, uchar cb_type, uchar cb_sub
self->cb_user = cb_user;
self->cb_type = cb_type;
self->cb_subtype = cb_subtype;
+ BLI_assert(!PyObject_GC_IsTracked((PyObject *)self));
PyObject_GC_Track(self);
}
diff --git a/source/blender/python/mathutils/mathutils_Euler.c b/source/blender/python/mathutils/mathutils_Euler.c
index f49868dfba7..551e5d6706d 100644
--- a/source/blender/python/mathutils/mathutils_Euler.c
+++ b/source/blender/python/mathutils/mathutils_Euler.c
@@ -32,10 +32,10 @@ static const char *euler_order_str(EulerObject *self)
short euler_order_from_string(const char *str, const char *error_prefix)
{
- if ((str[0] && str[1] && str[2] && str[3] == '\0')) {
+ if (str[0] && str[1] && str[2] && str[3] == '\0') {
#ifdef __LITTLE_ENDIAN__
-# define MAKE_ID3(a, b, c) (((a)) | ((b) << 8) | ((c) << 16))
+# define MAKE_ID3(a, b, c) ((a) | ((b) << 8) | ((c) << 16))
#else
# define MAKE_ID3(a, b, c) (((a) << 24) | ((b) << 16) | ((c) << 8))
#endif
@@ -215,7 +215,7 @@ static PyObject *Euler_rotate_axis(EulerObject *self, PyObject *args)
return NULL;
}
- if (!(ELEM(axis, 'X', 'Y', 'Z'))) {
+ if (!ELEM(axis, 'X', 'Y', 'Z')) {
PyErr_SetString(PyExc_ValueError,
"Euler.rotate_axis(): "
"expected axis to be 'X', 'Y' or 'Z'");
@@ -434,13 +434,13 @@ static Py_hash_t Euler_hash(EulerObject *self)
* \{ */
/** Sequence length: `len(object)`. */
-static int Euler_len(EulerObject *UNUSED(self))
+static Py_ssize_t Euler_len(EulerObject *UNUSED(self))
{
return EULER_SIZE;
}
/** Sequence accessor (get): `x = object[i]`. */
-static PyObject *Euler_item(EulerObject *self, int i)
+static PyObject *Euler_item(EulerObject *self, Py_ssize_t i)
{
if (i < 0) {
i = EULER_SIZE - i;
@@ -461,7 +461,7 @@ static PyObject *Euler_item(EulerObject *self, int i)
}
/** Sequence accessor (set): `object[i] = x`. */
-static int Euler_ass_item(EulerObject *self, int i, PyObject *value)
+static int Euler_ass_item(EulerObject *self, Py_ssize_t i, PyObject *value)
{
float f;
@@ -636,22 +636,22 @@ static int Euler_ass_subscript(EulerObject *self, PyObject *item, PyObject *valu
* \{ */
static PySequenceMethods Euler_SeqMethods = {
- (lenfunc)Euler_len, /*sq_length*/
- (binaryfunc)NULL, /*sq_concat*/
- (ssizeargfunc)NULL, /*sq_repeat*/
- (ssizeargfunc)Euler_item, /*sq_item*/
- (ssizessizeargfunc)NULL, /*sq_slice(DEPRECATED)*/
- (ssizeobjargproc)Euler_ass_item, /*sq_ass_item*/
- (ssizessizeobjargproc)NULL, /*sq_ass_slice(DEPRECATED)*/
- (objobjproc)NULL, /*sq_contains*/
- (binaryfunc)NULL, /*sq_inplace_concat*/
- (ssizeargfunc)NULL, /*sq_inplace_repeat*/
+ /*sq_length*/ (lenfunc)Euler_len,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /*sq_item*/ (ssizeargfunc)Euler_item,
+ /*was_sq_slice*/ NULL, /* DEPRECATED. */
+ /*sq_ass_item*/ (ssizeobjargproc)Euler_ass_item,
+ /*was_sq_ass_slice*/ NULL, /* DEPRECATED. */
+ /*sq_contains*/ NULL,
+ /*sq_inplace_concat*/ NULL,
+ /*sq_inplace_repeat*/ NULL,
};
static PyMappingMethods Euler_AsMapping = {
- (lenfunc)Euler_len,
- (binaryfunc)Euler_subscript,
- (objobjargproc)Euler_ass_subscript,
+ /*mp_len*/ (lenfunc)Euler_len,
+ /*mp_subscript*/ (binaryfunc)Euler_subscript,
+ /*mp_ass_subscript*/ (objobjargproc)Euler_ass_subscript,
};
/** \} */
@@ -766,6 +766,10 @@ static struct PyMethodDef Euler_methods[] = {
/** \name Euler Type: Python Object Definition
* \{ */
+#ifdef MATH_STANDALONE
+# define Euler_str NULL
+#endif
+
PyDoc_STRVAR(
euler_doc,
".. class:: Euler(angles, order='XYZ')\n"
@@ -774,62 +778,66 @@ PyDoc_STRVAR(
"\n"
" .. seealso:: `Euler angles <https://en.wikipedia.org/wiki/Euler_angles>`__ on Wikipedia.\n"
"\n"
- " :param angles: Three angles, in radians.\n"
+ " :arg angles: Three angles, in radians.\n"
" :type angles: 3d vector\n"
- " :param order: Optional order of the angles, a permutation of ``XYZ``.\n"
+ " :arg order: Optional order of the angles, a permutation of ``XYZ``.\n"
" :type order: str\n");
PyTypeObject euler_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "Euler", /* tp_name */
- sizeof(EulerObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)BaseMathObject_dealloc, /* tp_dealloc */
- (printfunc)NULL, /* tp_print */
- NULL, /* tp_getattr */
- NULL, /* tp_setattr */
- NULL, /* tp_compare */
- (reprfunc)Euler_repr, /* tp_repr */
- NULL, /* tp_as_number */
- &Euler_SeqMethods, /* tp_as_sequence */
- &Euler_AsMapping, /* tp_as_mapping */
- (hashfunc)Euler_hash, /* tp_hash */
- NULL, /* tp_call */
-#ifndef MATH_STANDALONE
- (reprfunc)Euler_str, /* tp_str */
-#else
- NULL, /* tp_str */
-#endif
- NULL, /* tp_getattro */
- NULL, /* tp_setattro */
- NULL, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
- euler_doc, /* tp_doc */
- (traverseproc)BaseMathObject_traverse, /* tp_traverse */
- (inquiry)BaseMathObject_clear, /* tp_clear */
- (richcmpfunc)Euler_richcmpr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- NULL, /* tp_iter */
- NULL, /* tp_iternext */
- Euler_methods, /* tp_methods */
- NULL, /* tp_members */
- Euler_getseters, /* tp_getset */
- NULL, /* tp_base */
- NULL, /* tp_dict */
- NULL, /* tp_descr_get */
- NULL, /* tp_descr_set */
- 0, /* tp_dictoffset */
- NULL, /* tp_init */
- NULL, /* tp_alloc */
- Euler_new, /* tp_new */
- NULL, /* tp_free */
- NULL, /* tp_is_gc */
- NULL, /* tp_bases */
- NULL, /* tp_mro */
- NULL, /* tp_cache */
- NULL, /* tp_subclasses */
- NULL, /* tp_weaklist */
- NULL, /* tp_del */
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "Euler",
+ /*tp_basicsize*/ sizeof(EulerObject),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)BaseMathObject_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ (reprfunc)Euler_repr,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ &Euler_SeqMethods,
+ /*tp_as_mapping*/ &Euler_AsMapping,
+ /*tp_hash*/ (hashfunc)Euler_hash,
+ /*tp_call*/ NULL,
+ /*tp_str*/ (reprfunc)Euler_str,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ /*tp_doc*/ euler_doc,
+ /*tp_traverse*/ (traverseproc)BaseMathObject_traverse,
+ /*tp_clear*/ (inquiry)BaseMathObject_clear,
+ /*tp_richcompare*/ (richcmpfunc)Euler_richcmpr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ Euler_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ Euler_getseters,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ Euler_new,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ (inquiry)BaseMathObject_is_gc,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
+#ifdef MATH_STANDALONE
+# undef Euler_str
+#endif
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -904,6 +912,7 @@ PyObject *Euler_CreatePyObject_cb(PyObject *cb_user,
self->cb_user = cb_user;
self->cb_type = cb_type;
self->cb_subtype = cb_subtype;
+ BLI_assert(!PyObject_GC_IsTracked((PyObject *)self));
PyObject_GC_Track(self);
}
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index 8405b966a4e..21ad79bc94d 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -725,7 +725,7 @@ static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args)
"cannot create a 2x2 rotation matrix around arbitrary axis");
return NULL;
}
- if ((ELEM(matSize, 3, 4)) && (axis == NULL) && (vec == NULL)) {
+ if (ELEM(matSize, 3, 4) && (axis == NULL) && (vec == NULL)) {
PyErr_SetString(PyExc_ValueError,
"Matrix.Rotation(): "
"axis of rotation for 3d and 4d matrices is required");
@@ -2379,7 +2379,7 @@ static Py_hash_t Matrix_hash(MatrixObject *self)
* \{ */
/** Sequence length: `len(object)`. */
-static int Matrix_len(MatrixObject *self)
+static Py_ssize_t Matrix_len(MatrixObject *self)
{
return self->row_num;
}
@@ -2388,7 +2388,7 @@ static int Matrix_len(MatrixObject *self)
* Sequence accessor (get): `x = object[i]`.
* \note the wrapped vector gives direct access to the matrix data.
*/
-static PyObject *Matrix_item_row(MatrixObject *self, int row)
+static PyObject *Matrix_item_row(MatrixObject *self, Py_ssize_t row)
{
if (BaseMath_ReadCallback_ForWrite(self) == -1) {
return NULL;
@@ -2407,7 +2407,7 @@ static PyObject *Matrix_item_row(MatrixObject *self, int row)
* Sequence accessor (get): `x = object.col[i]`.
* \note the wrapped vector gives direct access to the matrix data.
*/
-static PyObject *Matrix_item_col(MatrixObject *self, int col)
+static PyObject *Matrix_item_col(MatrixObject *self, Py_ssize_t col)
{
if (BaseMath_ReadCallback_ForWrite(self) == -1) {
return NULL;
@@ -2964,61 +2964,61 @@ static PyObject *Matrix_imatmul(PyObject *m1, PyObject *m2)
* \{ */
static PySequenceMethods Matrix_SeqMethods = {
- (lenfunc)Matrix_len, /*sq_length*/
- (binaryfunc)NULL, /*sq_concat*/
- (ssizeargfunc)NULL, /*sq_repeat*/
- (ssizeargfunc)Matrix_item_row, /*sq_item*/
- (ssizessizeargfunc)NULL, /*sq_slice(DEPRECATED)*/
- (ssizeobjargproc)Matrix_ass_item_row, /*sq_ass_item*/
- (ssizessizeobjargproc)NULL, /*sq_ass_slice(DEPRECATED)*/
- (objobjproc)NULL, /*sq_contains*/
- (binaryfunc)NULL, /*sq_inplace_concat*/
- (ssizeargfunc)NULL, /*sq_inplace_repeat*/
+ /*sq_length*/ (lenfunc)Matrix_len,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /*sq_item*/ (ssizeargfunc)Matrix_item_row,
+ /*was_sq_slice*/ NULL, /* DEPRECATED. */
+ /*sq_ass_item*/ (ssizeobjargproc)Matrix_ass_item_row,
+ /*was_sq_ass_slice*/ NULL, /* DEPRECATED. */
+ /*sq_contains*/ NULL,
+ /*sq_inplace_concat*/ NULL,
+ /*sq_inplace_repeat*/ NULL,
};
static PyMappingMethods Matrix_AsMapping = {
- (lenfunc)Matrix_len,
- (binaryfunc)Matrix_subscript,
- (objobjargproc)Matrix_ass_subscript,
+ /*mp_len*/ (lenfunc)Matrix_len,
+ /*mp_subscript*/ (binaryfunc)Matrix_subscript,
+ /*mp_ass_subscript*/ (objobjargproc)Matrix_ass_subscript,
};
static PyNumberMethods Matrix_NumMethods = {
- (binaryfunc)Matrix_add, /*nb_add*/
- (binaryfunc)Matrix_sub, /*nb_subtract*/
- (binaryfunc)Matrix_mul, /*nb_multiply*/
- NULL, /*nb_remainder*/
- NULL, /*nb_divmod*/
- NULL, /*nb_power*/
- (unaryfunc)0, /*nb_negative*/
- (unaryfunc)0, /*tp_positive*/
- (unaryfunc)0, /*tp_absolute*/
- (inquiry)0, /*tp_bool*/
- (unaryfunc)Matrix_inverted_noargs, /*nb_invert*/
- NULL, /*nb_lshift*/
- (binaryfunc)0, /*nb_rshift*/
- NULL, /*nb_and*/
- NULL, /*nb_xor*/
- NULL, /*nb_or*/
- NULL, /*nb_int*/
- NULL, /*nb_reserved*/
- NULL, /*nb_float*/
- NULL, /*nb_inplace_add*/
- NULL, /*nb_inplace_subtract*/
- (binaryfunc)Matrix_imul, /*nb_inplace_multiply*/
- NULL, /*nb_inplace_remainder*/
- NULL, /*nb_inplace_power*/
- NULL, /*nb_inplace_lshift*/
- NULL, /*nb_inplace_rshift*/
- NULL, /*nb_inplace_and*/
- NULL, /*nb_inplace_xor*/
- NULL, /*nb_inplace_or*/
- NULL, /*nb_floor_divide*/
- NULL, /*nb_true_divide*/
- NULL, /*nb_inplace_floor_divide*/
- NULL, /*nb_inplace_true_divide*/
- NULL, /*nb_index*/
- (binaryfunc)Matrix_matmul, /*nb_matrix_multiply*/
- (binaryfunc)Matrix_imatmul, /*nb_inplace_matrix_multiply*/
+ /*nb_add*/ (binaryfunc)Matrix_add,
+ /*nb_subtract*/ (binaryfunc)Matrix_sub,
+ /*nb_multiply*/ (binaryfunc)Matrix_mul,
+ /*nb_remainder*/ NULL,
+ /*nb_divmod*/ NULL,
+ /*nb_power*/ NULL,
+ /*nb_negative*/ NULL,
+ /*tp_positive*/ NULL,
+ /*tp_absolute*/ NULL,
+ /*tp_bool*/ NULL,
+ /*nb_invert*/ (unaryfunc)Matrix_inverted_noargs,
+ /*nb_lshift*/ NULL,
+ /*nb_rshift*/ NULL,
+ /*nb_and*/ NULL,
+ /*nb_xor*/ NULL,
+ /*nb_or*/ NULL,
+ /*nb_int*/ NULL,
+ /*nb_reserved*/ NULL,
+ /*nb_float*/ NULL,
+ /*nb_inplace_add*/ NULL,
+ /*nb_inplace_subtract*/ NULL,
+ /*nb_inplace_multiply*/ (binaryfunc)Matrix_imul,
+ /*nb_inplace_remainder*/ NULL,
+ /*nb_inplace_power*/ NULL,
+ /*nb_inplace_lshift*/ NULL,
+ /*nb_inplace_rshift*/ NULL,
+ /*nb_inplace_and*/ NULL,
+ /*nb_inplace_xor*/ NULL,
+ /*nb_inplace_or*/ NULL,
+ /*nb_floor_divide*/ NULL,
+ /*nb_true_divide*/ NULL,
+ /*nb_inplace_floor_divide*/ NULL,
+ /*nb_inplace_true_divide*/ NULL,
+ /*nb_index*/ NULL,
+ /*nb_matrix_multiply*/ (binaryfunc)Matrix_matmul,
+ /*nb_inplace_matrix_multiply*/ (binaryfunc)Matrix_imatmul,
};
/** \} */
@@ -3314,6 +3314,10 @@ static struct PyMethodDef Matrix_methods[] = {
/** \name Matrix Type: Python Object Definition
* \{ */
+#ifdef MATH_STANDALONE
+# define Matrix_str NULL
+#endif
+
PyDoc_STRVAR(
matrix_doc,
".. class:: Matrix([rows])\n"
@@ -3321,61 +3325,64 @@ PyDoc_STRVAR(
" This object gives access to Matrices in Blender, supporting square and rectangular\n"
" matrices from 2x2 up to 4x4.\n"
"\n"
- " :param rows: Sequence of rows.\n"
- " When omitted, a 4x4 identity matrix is constructed.\n"
+ " :arg rows: Sequence of rows. When omitted, a 4x4 identity matrix is constructed.\n"
" :type rows: 2d number sequence\n");
PyTypeObject matrix_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "Matrix", /*tp_name*/
- sizeof(MatrixObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)BaseMathObject_dealloc, /*tp_dealloc*/
- (printfunc)NULL, /*tp_print*/
- NULL, /*tp_getattr*/
- NULL, /*tp_setattr*/
- NULL, /*tp_compare*/
- (reprfunc)Matrix_repr, /*tp_repr*/
- &Matrix_NumMethods, /*tp_as_number*/
- &Matrix_SeqMethods, /*tp_as_sequence*/
- &Matrix_AsMapping, /*tp_as_mapping*/
- (hashfunc)Matrix_hash, /*tp_hash*/
- NULL, /*tp_call*/
-#ifndef MATH_STANDALONE
- (reprfunc)Matrix_str, /*tp_str*/
-#else
- NULL, /*tp_str*/
-#endif
- NULL, /*tp_getattro*/
- NULL, /*tp_setattro*/
- NULL, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
- matrix_doc, /*tp_doc*/
- (traverseproc)BaseMathObject_traverse, /* tp_traverse */
- (inquiry)BaseMathObject_clear, /*tp_clear*/
- (richcmpfunc)Matrix_richcmpr, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- NULL, /*tp_iter*/
- NULL, /*tp_iternext*/
- Matrix_methods, /*tp_methods*/
- NULL, /*tp_members*/
- Matrix_getseters, /*tp_getset*/
- NULL, /*tp_base*/
- NULL, /*tp_dict*/
- NULL, /*tp_descr_get*/
- NULL, /*tp_descr_set*/
- 0, /*tp_dictoffset*/
- NULL, /*tp_init*/
- NULL, /*tp_alloc*/
- Matrix_new, /*tp_new*/
- NULL, /*tp_free*/
- NULL, /*tp_is_gc*/
- NULL, /*tp_bases*/
- NULL, /*tp_mro*/
- NULL, /*tp_cache*/
- NULL, /*tp_subclasses*/
- NULL, /*tp_weaklist*/
- NULL, /*tp_del*/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "Matrix",
+ /*tp_basicsize*/ sizeof(MatrixObject),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)BaseMathObject_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ (reprfunc)Matrix_repr,
+ /*tp_as_number*/ &Matrix_NumMethods,
+ /*tp_as_sequence*/ &Matrix_SeqMethods,
+ /*tp_as_mapping*/ &Matrix_AsMapping,
+ /*tp_hash*/ (hashfunc)Matrix_hash,
+ /*tp_call*/ NULL,
+ /*tp_str*/ (reprfunc)Matrix_str,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ /*tp_doc*/ matrix_doc,
+ /*tp_traverse*/ (traverseproc)BaseMathObject_traverse,
+ /*tp_clear*/ (inquiry)BaseMathObject_clear,
+ /*tp_richcompare*/ (richcmpfunc)Matrix_richcmpr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ Matrix_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ Matrix_getseters,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ Matrix_new,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ (inquiry)BaseMathObject_is_gc,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
+#ifdef MATH_STANDALONE
+# undef Matrix_str
+#endif
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -3475,6 +3482,7 @@ PyObject *Matrix_CreatePyObject_cb(
self->cb_user = cb_user;
self->cb_type = cb_type;
self->cb_subtype = cb_subtype;
+ BLI_assert(!PyObject_GC_IsTracked((PyObject *)self));
PyObject_GC_Track(self);
}
return (PyObject *)self;
@@ -3625,15 +3633,15 @@ static int MatrixAccess_len(MatrixAccessObject *self)
return (self->type == MAT_ACCESS_ROW) ? self->matrix_user->row_num : self->matrix_user->col_num;
}
-static PyObject *MatrixAccess_slice(MatrixAccessObject *self, int begin, int end)
+static PyObject *MatrixAccess_slice(MatrixAccessObject *self, Py_ssize_t begin, Py_ssize_t end)
{
PyObject *tuple;
- int count;
+ Py_ssize_t count;
/* row/col access */
MatrixObject *matrix_user = self->matrix_user;
int matrix_access_len;
- PyObject *(*Matrix_item_new)(MatrixObject *, int);
+ PyObject *(*Matrix_item_new)(MatrixObject *, Py_ssize_t);
if (self->type == MAT_ACCESS_ROW) {
matrix_access_len = matrix_user->row_num;
@@ -3752,9 +3760,9 @@ static PyObject *MatrixAccess_iter(MatrixAccessObject *self)
}
static PyMappingMethods MatrixAccess_AsMapping = {
- (lenfunc)MatrixAccess_len,
- (binaryfunc)MatrixAccess_subscript,
- (objobjargproc)MatrixAccess_ass_subscript,
+ /*mp_len*/ (lenfunc)MatrixAccess_len,
+ /*mp_subscript*/ (binaryfunc)MatrixAccess_subscript,
+ /*mp_ass_subscript*/ (objobjargproc)MatrixAccess_ass_subscript,
};
/** \} */
@@ -3764,31 +3772,55 @@ static PyMappingMethods MatrixAccess_AsMapping = {
* \{ */
PyTypeObject matrix_access_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "MatrixAccess", /*tp_name*/
- sizeof(MatrixAccessObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)MatrixAccess_dealloc, /*tp_dealloc*/
- (printfunc)NULL, /*tp_print*/
- NULL, /*tp_getattr*/
- NULL, /*tp_setattr*/
- NULL, /*tp_compare*/
- NULL, /*tp_repr*/
- NULL, /*tp_as_number*/
- NULL /* &MatrixAccess_SeqMethods */ /* TODO */, /*tp_as_sequence*/
- &MatrixAccess_AsMapping, /*tp_as_mapping*/
- NULL, /*tp_hash*/
- NULL, /*tp_call*/
- NULL, /*tp_str*/
- NULL, /*tp_getattro*/
- NULL, /*tp_setattro*/
- NULL, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
- NULL, /*tp_doc*/
- (traverseproc)MatrixAccess_traverse, /*tp_traverse*/
- (inquiry)MatrixAccess_clear, /*tp_clear*/
- NULL /* (richcmpfunc)MatrixAccess_richcmpr */ /* TODO*/, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- (getiterfunc)MatrixAccess_iter, /* getiterfunc tp_iter; */
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "MatrixAccess",
+ /*tp_basicsize*/ sizeof(MatrixAccessObject),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)MatrixAccess_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ NULL,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ NULL /* &MatrixAccess_SeqMethods */ /* TODO */,
+ /*tp_as_mapping*/ &MatrixAccess_AsMapping,
+ /*tp_hash*/ NULL,
+ /*tp_call*/ NULL,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ (traverseproc)MatrixAccess_traverse,
+ /*tp_clear*/ (inquiry)MatrixAccess_clear,
+ /*tp_richcompare*/ NULL /* MatrixAccess_richcmpr */ /* TODO*/,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ (getiterfunc)MatrixAccess_iter,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ NULL,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ NULL,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ NULL,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
/** \} */
diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c
index a5ea09bef48..f2348713433 100644
--- a/source/blender/python/mathutils/mathutils_Quaternion.c
+++ b/source/blender/python/mathutils/mathutils_Quaternion.c
@@ -830,7 +830,7 @@ static PyObject *Quaternion_richcmpr(PyObject *a, PyObject *b, int op)
return NULL;
}
- ok = (EXPP_VectorsAreEqual(quatA->quat, quatB->quat, QUAT_SIZE, 1)) ? 0 : -1;
+ ok = EXPP_VectorsAreEqual(quatA->quat, quatB->quat, QUAT_SIZE, 1) ? 0 : -1;
}
switch (op) {
@@ -881,13 +881,13 @@ static Py_hash_t Quaternion_hash(QuaternionObject *self)
* \{ */
/** Sequence length: `len(object)`. */
-static int Quaternion_len(QuaternionObject *UNUSED(self))
+static Py_ssize_t Quaternion_len(QuaternionObject *UNUSED(self))
{
return QUAT_SIZE;
}
/** Sequence accessor (get): `x = object[i]`. */
-static PyObject *Quaternion_item(QuaternionObject *self, int i)
+static PyObject *Quaternion_item(QuaternionObject *self, Py_ssize_t i)
{
if (i < 0) {
i = QUAT_SIZE - i;
@@ -908,7 +908,7 @@ static PyObject *Quaternion_item(QuaternionObject *self, int i)
}
/** Sequence accessor (set): `object[i] = x`. */
-static int Quaternion_ass_item(QuaternionObject *self, int i, PyObject *ob)
+static int Quaternion_ass_item(QuaternionObject *self, Py_ssize_t i, PyObject *ob)
{
float f;
@@ -1177,7 +1177,7 @@ static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2)
}
}
else if (quat1) { /* QUAT * FLOAT */
- if ((((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0)) {
+ if (((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0) {
return quat_mul_float(quat1, scalar);
}
}
@@ -1342,61 +1342,61 @@ static PyObject *Quaternion_neg(QuaternionObject *self)
* \{ */
static PySequenceMethods Quaternion_SeqMethods = {
- (lenfunc)Quaternion_len, /*sq_length*/
- (binaryfunc)NULL, /*sq_concat*/
- (ssizeargfunc)NULL, /*sq_repeat*/
- (ssizeargfunc)Quaternion_item, /*sq_item*/
- (ssizessizeargfunc)NULL, /*sq_slice(deprecated)*/
- (ssizeobjargproc)Quaternion_ass_item, /*sq_ass_item*/
- (ssizessizeobjargproc)NULL, /*sq_ass_slice(deprecated)*/
- (objobjproc)NULL, /*sq_contains*/
- (binaryfunc)NULL, /*sq_inplace_concat*/
- (ssizeargfunc)NULL, /*sq_inplace_repeat*/
+ /*sq_length*/ (lenfunc)Quaternion_len,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /*sq_item*/ (ssizeargfunc)Quaternion_item,
+ /*was_sq_slice*/ NULL, /* DEPRECATED. */
+ /*sq_ass_item*/ (ssizeobjargproc)Quaternion_ass_item,
+ /*was_sq_ass_slice*/ NULL, /* DEPRECATED. */
+ /*sq_contains*/ NULL,
+ /*sq_inplace_concat*/ NULL,
+ /*sq_inplace_repeat*/ NULL,
};
static PyMappingMethods Quaternion_AsMapping = {
- (lenfunc)Quaternion_len,
- (binaryfunc)Quaternion_subscript,
- (objobjargproc)Quaternion_ass_subscript,
+ /*mp_len*/ (lenfunc)Quaternion_len,
+ /*mp_subscript*/ (binaryfunc)Quaternion_subscript,
+ /*mp_ass_subscript*/ (objobjargproc)Quaternion_ass_subscript,
};
static PyNumberMethods Quaternion_NumMethods = {
- (binaryfunc)Quaternion_add, /*nb_add*/
- (binaryfunc)Quaternion_sub, /*nb_subtract*/
- (binaryfunc)Quaternion_mul, /*nb_multiply*/
- NULL, /*nb_remainder*/
- NULL, /*nb_divmod*/
- NULL, /*nb_power*/
- (unaryfunc)Quaternion_neg, /*nb_negative*/
- (unaryfunc)Quaternion_copy, /*tp_positive*/
- (unaryfunc)0, /*tp_absolute*/
- (inquiry)0, /*tp_bool*/
- (unaryfunc)0, /*nb_invert*/
- NULL, /*nb_lshift*/
- (binaryfunc)0, /*nb_rshift*/
- NULL, /*nb_and*/
- NULL, /*nb_xor*/
- NULL, /*nb_or*/
- NULL, /*nb_int*/
- NULL, /*nb_reserved*/
- NULL, /*nb_float*/
- NULL, /*nb_inplace_add*/
- NULL, /*nb_inplace_subtract*/
- (binaryfunc)Quaternion_imul, /*nb_inplace_multiply*/
- NULL, /*nb_inplace_remainder*/
- NULL, /*nb_inplace_power*/
- NULL, /*nb_inplace_lshift*/
- NULL, /*nb_inplace_rshift*/
- NULL, /*nb_inplace_and*/
- NULL, /*nb_inplace_xor*/
- NULL, /*nb_inplace_or*/
- NULL, /*nb_floor_divide*/
- NULL, /*nb_true_divide*/
- NULL, /*nb_inplace_floor_divide*/
- NULL, /*nb_inplace_true_divide*/
- NULL, /*nb_index*/
- (binaryfunc)Quaternion_matmul, /*nb_matrix_multiply*/
- (binaryfunc)Quaternion_imatmul, /*nb_inplace_matrix_multiply*/
+ /*nb_add*/ (binaryfunc)Quaternion_add,
+ /*nb_subtract*/ (binaryfunc)Quaternion_sub,
+ /*nb_multiply*/ (binaryfunc)Quaternion_mul,
+ /*nb_remainder*/ NULL,
+ /*nb_divmod*/ NULL,
+ /*nb_power*/ NULL,
+ /*nb_negative*/ (unaryfunc)Quaternion_neg,
+ /*tp_positive*/ (unaryfunc)Quaternion_copy,
+ /*tp_absolute*/ NULL,
+ /*tp_bool*/ NULL,
+ /*nb_invert*/ NULL,
+ /*nb_lshift*/ NULL,
+ /*nb_rshift*/ NULL,
+ /*nb_and*/ NULL,
+ /*nb_xor*/ NULL,
+ /*nb_or*/ NULL,
+ /*nb_int*/ NULL,
+ /*nb_reserved*/ NULL,
+ /*nb_float*/ NULL,
+ /*nb_inplace_add*/ NULL,
+ /*nb_inplace_subtract*/ NULL,
+ /*nb_inplace_multiply*/ (binaryfunc)Quaternion_imul,
+ /*nb_inplace_remainder*/ NULL,
+ /*nb_inplace_power*/ NULL,
+ /*nb_inplace_lshift*/ NULL,
+ /*nb_inplace_rshift*/ NULL,
+ /*nb_inplace_and*/ NULL,
+ /*nb_inplace_xor*/ NULL,
+ /*nb_inplace_or*/ NULL,
+ /*nb_floor_divide*/ NULL,
+ /*nb_true_divide*/ NULL,
+ /*nb_inplace_floor_divide*/ NULL,
+ /*nb_inplace_true_divide*/ NULL,
+ /*nb_index*/ NULL,
+ /*nb_matrix_multiply*/ (binaryfunc)Quaternion_matmul,
+ /*nb_inplace_matrix_multiply*/ (binaryfunc)Quaternion_imatmul,
};
/** \} */
@@ -1657,14 +1657,18 @@ static struct PyMethodDef Quaternion_methods[] = {
/** \name Quaternion Type: Python Object Definition
* \{ */
+#ifdef MATH_STANDALONE
+# define Quaternion_str NULL
+#endif
+
PyDoc_STRVAR(quaternion_doc,
".. class:: Quaternion([seq, [angle]])\n"
"\n"
" This object gives access to Quaternions in Blender.\n"
"\n"
- " :param seq: size 3 or 4\n"
+ " :arg seq: size 3 or 4\n"
" :type seq: :class:`Vector`\n"
- " :param angle: rotation angle, in radians\n"
+ " :arg angle: rotation angle, in radians\n"
" :type angle: float\n"
"\n"
" The constructor takes arguments in various forms:\n"
@@ -1682,57 +1686,61 @@ PyDoc_STRVAR(quaternion_doc,
"\n"
" .. seealso:: :meth:`to_axis_angle`\n");
PyTypeObject quaternion_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "Quaternion", /* tp_name */
- sizeof(QuaternionObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)BaseMathObject_dealloc, /* tp_dealloc */
- (printfunc)NULL, /* tp_print */
- NULL, /* tp_getattr */
- NULL, /* tp_setattr */
- NULL, /* tp_compare */
- (reprfunc)Quaternion_repr, /* tp_repr */
- &Quaternion_NumMethods, /* tp_as_number */
- &Quaternion_SeqMethods, /* tp_as_sequence */
- &Quaternion_AsMapping, /* tp_as_mapping */
- (hashfunc)Quaternion_hash, /* tp_hash */
- NULL, /* tp_call */
-#ifndef MATH_STANDALONE
- (reprfunc)Quaternion_str, /* tp_str */
-#else
- NULL, /* tp_str */
-#endif
- NULL, /* tp_getattro */
- NULL, /* tp_setattro */
- NULL, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
- quaternion_doc, /* tp_doc */
- (traverseproc)BaseMathObject_traverse, /* tp_traverse */
- (inquiry)BaseMathObject_clear, /* tp_clear */
- (richcmpfunc)Quaternion_richcmpr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- NULL, /* tp_iter */
- NULL, /* tp_iternext */
- Quaternion_methods, /* tp_methods */
- NULL, /* tp_members */
- Quaternion_getseters, /* tp_getset */
- NULL, /* tp_base */
- NULL, /* tp_dict */
- NULL, /* tp_descr_get */
- NULL, /* tp_descr_set */
- 0, /* tp_dictoffset */
- NULL, /* tp_init */
- NULL, /* tp_alloc */
- Quaternion_new, /* tp_new */
- NULL, /* tp_free */
- NULL, /* tp_is_gc */
- NULL, /* tp_bases */
- NULL, /* tp_mro */
- NULL, /* tp_cache */
- NULL, /* tp_subclasses */
- NULL, /* tp_weaklist */
- NULL, /* tp_del */
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "Quaternion",
+ /*tp_basicsize*/ sizeof(QuaternionObject),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)BaseMathObject_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ (reprfunc)Quaternion_repr,
+ /*tp_as_number*/ &Quaternion_NumMethods,
+ /*tp_as_sequence*/ &Quaternion_SeqMethods,
+ /*tp_as_mapping*/ &Quaternion_AsMapping,
+ /*tp_hash*/ (hashfunc)Quaternion_hash,
+ /*tp_call*/ NULL,
+ /*tp_str*/ (reprfunc)Quaternion_str,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ /*tp_doc*/ quaternion_doc,
+ /*tp_traverse*/ (traverseproc)BaseMathObject_traverse,
+ /*tp_clear*/ (inquiry)BaseMathObject_clear,
+ /*tp_richcompare*/ (richcmpfunc)Quaternion_richcmpr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ Quaternion_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ Quaternion_getseters,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ Quaternion_new,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ (inquiry)BaseMathObject_is_gc,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
+#ifdef MATH_STANDALONE
+# undef Quaternion_str
+#endif
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -1800,6 +1808,7 @@ PyObject *Quaternion_CreatePyObject_cb(PyObject *cb_user, uchar cb_type, uchar c
self->cb_user = cb_user;
self->cb_type = cb_type;
self->cb_subtype = cb_subtype;
+ BLI_assert(!PyObject_GC_IsTracked((PyObject *)self));
PyObject_GC_Track(self);
}
diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c
index 0c9cbd6ccfa..c5a002a6058 100644
--- a/source/blender/python/mathutils/mathutils_Vector.c
+++ b/source/blender/python/mathutils/mathutils_Vector.c
@@ -1667,7 +1667,7 @@ static Py_hash_t Vector_hash(VectorObject *self)
* \{ */
/** Sequence length: `len(object)`. */
-static int Vector_len(VectorObject *self)
+static Py_ssize_t Vector_len(VectorObject *self)
{
return self->vec_num;
}
@@ -1699,7 +1699,7 @@ static PyObject *vector_item_internal(VectorObject *self, int i, const bool is_a
}
/** Sequence accessor (get): `x = object[i]`. */
-static PyObject *Vector_item(VectorObject *self, int i)
+static PyObject *Vector_item(VectorObject *self, Py_ssize_t i)
{
return vector_item_internal(self, i, false);
}
@@ -1747,7 +1747,7 @@ static int vector_ass_item_internal(VectorObject *self, int i, PyObject *value,
}
/** Sequence accessor (set): `object[i] = x`. */
-static int Vector_ass_item(VectorObject *self, int i, PyObject *value)
+static int Vector_ass_item(VectorObject *self, Py_ssize_t i, PyObject *value)
{
return vector_ass_item_internal(self, i, value, false);
}
@@ -2387,61 +2387,61 @@ static PyObject *Vector_neg(VectorObject *self)
* \{ */
static PySequenceMethods Vector_SeqMethods = {
- (lenfunc)Vector_len, /*sq_length*/
- (binaryfunc)NULL, /*sq_concat*/
- (ssizeargfunc)NULL, /*sq_repeat*/
- (ssizeargfunc)Vector_item, /*sq_item*/
- NULL, /*sq_slice(DEPRECATED)*/
- (ssizeobjargproc)Vector_ass_item, /*sq_ass_item*/
- NULL, /*sq_ass_slice(DEPRECATED)*/
- (objobjproc)NULL, /*sq_contains*/
- (binaryfunc)NULL, /*sq_inplace_concat */
- (ssizeargfunc)NULL, /*sq_inplace_repeat */
+ /*sq_length*/ (lenfunc)Vector_len,
+ /*sq_concat*/ NULL,
+ /*sq_repeat*/ NULL,
+ /*sq_item*/ (ssizeargfunc)Vector_item,
+ /*was_sq_slice*/ NULL, /* DEPRECATED. */
+ /*sq_ass_item*/ (ssizeobjargproc)Vector_ass_item,
+ /*was_sq_ass_slice*/ NULL, /* DEPRECATED. */
+ /*sq_contains*/ NULL,
+ /*sq_inplace_concat */ NULL,
+ /*sq_inplace_repeat */ NULL,
};
static PyMappingMethods Vector_AsMapping = {
- (lenfunc)Vector_len,
- (binaryfunc)Vector_subscript,
- (objobjargproc)Vector_ass_subscript,
+ /*mp_len*/ (lenfunc)Vector_len,
+ /*mp_subscript*/ (binaryfunc)Vector_subscript,
+ /*mp_ass_subscript*/ (objobjargproc)Vector_ass_subscript,
};
static PyNumberMethods Vector_NumMethods = {
- (binaryfunc)Vector_add, /*nb_add*/
- (binaryfunc)Vector_sub, /*nb_subtract*/
- (binaryfunc)Vector_mul, /*nb_multiply*/
- NULL, /*nb_remainder*/
- NULL, /*nb_divmod*/
- NULL, /*nb_power*/
- (unaryfunc)Vector_neg, /*nb_negative*/
- (unaryfunc)Vector_copy, /*tp_positive*/
- (unaryfunc)NULL, /*tp_absolute*/
- (inquiry)NULL, /*tp_bool*/
- (unaryfunc)NULL, /*nb_invert*/
- NULL, /*nb_lshift*/
- (binaryfunc)NULL, /*nb_rshift*/
- NULL, /*nb_and*/
- NULL, /*nb_xor*/
- NULL, /*nb_or*/
- NULL, /*nb_int*/
- NULL, /*nb_reserved*/
- NULL, /*nb_float*/
- Vector_iadd, /*nb_inplace_add*/
- Vector_isub, /*nb_inplace_subtract*/
- Vector_imul, /*nb_inplace_multiply*/
- NULL, /*nb_inplace_remainder*/
- NULL, /*nb_inplace_power*/
- NULL, /*nb_inplace_lshift*/
- NULL, /*nb_inplace_rshift*/
- NULL, /*nb_inplace_and*/
- NULL, /*nb_inplace_xor*/
- NULL, /*nb_inplace_or*/
- NULL, /*nb_floor_divide*/
- Vector_div, /*nb_true_divide*/
- NULL, /*nb_inplace_floor_divide*/
- Vector_idiv, /*nb_inplace_true_divide*/
- NULL, /*nb_index*/
- (binaryfunc)Vector_matmul, /*nb_matrix_multiply*/
- (binaryfunc)Vector_imatmul, /*nb_inplace_matrix_multiply*/
+ /*nb_add*/ (binaryfunc)Vector_add,
+ /*nb_subtract*/ (binaryfunc)Vector_sub,
+ /*nb_multiply*/ (binaryfunc)Vector_mul,
+ /*nb_remainder*/ NULL,
+ /*nb_divmod*/ NULL,
+ /*nb_power*/ NULL,
+ /*nb_negative*/ (unaryfunc)Vector_neg,
+ /*tp_positive*/ (unaryfunc)Vector_copy,
+ /*tp_absolute*/ NULL,
+ /*tp_bool*/ NULL,
+ /*nb_invert*/ NULL,
+ /*nb_lshift*/ NULL,
+ /*nb_rshift*/ NULL,
+ /*nb_and*/ NULL,
+ /*nb_xor*/ NULL,
+ /*nb_or*/ NULL,
+ /*nb_int*/ NULL,
+ /*nb_reserved*/ NULL,
+ /*nb_float*/ NULL,
+ /*nb_inplace_add*/ Vector_iadd,
+ /*nb_inplace_subtract*/ Vector_isub,
+ /*nb_inplace_multiply*/ Vector_imul,
+ /*nb_inplace_remainder*/ NULL,
+ /*nb_inplace_power*/ NULL,
+ /*nb_inplace_lshift*/ NULL,
+ /*nb_inplace_rshift*/ NULL,
+ /*nb_inplace_and*/ NULL,
+ /*nb_inplace_xor*/ NULL,
+ /*nb_inplace_or*/ NULL,
+ /*nb_floor_divide*/ NULL,
+ /*nb_true_divide*/ Vector_div,
+ /*nb_inplace_floor_divide*/ NULL,
+ /*nb_inplace_true_divide*/ Vector_idiv,
+ /*nb_index*/ NULL,
+ /*nb_matrix_multiply*/ (binaryfunc)Vector_matmul,
+ /*nb_inplace_matrix_multiply*/ (binaryfunc)Vector_imatmul,
};
/** \} */
@@ -2680,7 +2680,7 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure
size_from = axis_from;
}
- else if (((void)PyErr_Clear()), /* run but ignore the result */
+ else if ((void)PyErr_Clear(), /* run but ignore the result */
(size_from = mathutils_array_parse(
vec_assign, 2, 4, value, "mathutils.Vector.**** = swizzle assignment")) == -1) {
return -1;
@@ -3183,97 +3183,72 @@ static struct PyMethodDef Vector_methods[] = {
* both get sent to Vector_mul and it needs to sort out the order
* \{ */
+#ifdef MATH_STANDALONE
+# define Vector_str NULL
+#endif
+
PyDoc_STRVAR(vector_doc,
".. class:: Vector(seq)\n"
"\n"
" This object gives access to Vectors in Blender.\n"
"\n"
- " :param seq: Components of the vector, must be a sequence of at least two\n"
+ " :arg seq: Components of the vector, must be a sequence of at least two\n"
" :type seq: sequence of numbers\n");
PyTypeObject vector_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
- /* For printing, in format "<module>.<name>" */
- "Vector", /* char *tp_name; */
- sizeof(VectorObject), /* int tp_basicsize; */
- 0, /* tp_itemsize; For allocation */
-
- /* Methods to implement standard operations */
-
- (destructor)BaseMathObject_dealloc, /* destructor tp_dealloc; */
- 0, /* tp_vectorcall_offset */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL, /* cmpfunc tp_compare; */
- (reprfunc)Vector_repr, /* reprfunc tp_repr; */
-
- /* Method suites for standard classes */
-
- &Vector_NumMethods, /* PyNumberMethods *tp_as_number; */
- &Vector_SeqMethods, /* PySequenceMethods *tp_as_sequence; */
- &Vector_AsMapping, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
+ /*tp_name*/ "Vector",
+ /*tp_basicsize*/ sizeof(VectorObject),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)BaseMathObject_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ (reprfunc)Vector_repr,
+ /*tp_as_number*/ &Vector_NumMethods,
+ /*tp_as_sequence*/ &Vector_SeqMethods,
+ /*tp_as_mapping*/ &Vector_AsMapping,
+ /*tp_hash*/ (hashfunc)Vector_hash,
+ /*tp_call*/ NULL,
+ /*tp_str*/ (reprfunc)Vector_str,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ /*tp_doc*/ vector_doc,
+ /*tp_traverse*/ (traverseproc)BaseMathObject_traverse,
+ /*tp_clear*/ (inquiry)BaseMathObject_clear,
+ /*tp_richcompare*/ (richcmpfunc)Vector_richcmpr,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ Vector_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ Vector_getseters,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ NULL,
+ /*tp_new*/ Vector_new,
+ /*tp_free*/ NULL,
+ /*tp_is_gc*/ (inquiry)BaseMathObject_is_gc,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
+};
- (hashfunc)Vector_hash, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
-#ifndef MATH_STANDALONE
- (reprfunc)Vector_str, /* reprfunc tp_str; */
-#else
- NULL, /* reprfunc tp_str; */
+#ifdef MATH_STANDALONE
+# undef Vector_str NULL
#endif
- NULL, /* getattrofunc tp_getattro; */
- NULL, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
- vector_doc, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
-
- /* call function for all accessible objects */
- (traverseproc)BaseMathObject_traverse, /* tp_traverse */
-
- /* delete references to contained objects */
- (inquiry)BaseMathObject_clear, /* tp_clear */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons ***/
- (richcmpfunc)Vector_richcmpr, /* richcmpfunc tp_richcompare; */
-
- /*** weak reference enabler ***/
- 0, /* long tp_weaklistoffset; */
-
- /*** Added in release 2.2 ***/
- /* Iterators */
- NULL, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
-
- /*** Attribute descriptor and subclassing stuff ***/
- Vector_methods, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- Vector_getseters, /* struct PyGetSetDef *tp_getset; */
- NULL, /* struct _typeobject *tp_base; */
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- 0, /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- Vector_new, /* newfunc tp_new; */
- /* Low-level free-memory routine */
- NULL, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL,
-};
/** \} */
@@ -3304,7 +3279,7 @@ PyObject *Vector_CreatePyObject(const float *vec, const int vec_num, PyTypeObjec
self->vec = vec_alloc;
self->vec_num = vec_num;
- /* init callbacks as NULL */
+ /* Initialize callbacks as NULL. */
self->cb_user = NULL;
self->cb_type = self->cb_subtype = 0;
@@ -3339,7 +3314,7 @@ PyObject *Vector_CreatePyObject_wrap(float *vec, const int vec_num, PyTypeObject
if (self) {
self->vec_num = vec_num;
- /* init callbacks as NULL */
+ /* Initialize callbacks as NULL. */
self->cb_user = NULL;
self->cb_type = self->cb_subtype = 0;
@@ -3357,6 +3332,7 @@ PyObject *Vector_CreatePyObject_cb(PyObject *cb_user, int vec_num, uchar cb_type
self->cb_user = cb_user;
self->cb_type = cb_type;
self->cb_subtype = cb_subtype;
+ BLI_assert(!PyObject_GC_IsTracked((PyObject *)self));
PyObject_GC_Track(self);
}
diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c
index 4bdb1adcdde..7b6c444515b 100644
--- a/source/blender/python/mathutils/mathutils_bvhtree.c
+++ b/source/blender/python/mathutils/mathutils_bvhtree.c
@@ -1235,52 +1235,55 @@ static PyMethodDef py_bvhtree_methods[] = {
};
PyTypeObject PyBVHTree_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "BVHTree", /* tp_name */
- sizeof(PyBVHTree), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- (destructor)py_bvhtree__tp_dealloc, /* tp_dealloc */
- (printfunc)NULL, /* tp_print */
- NULL, /* tp_getattr */
- NULL, /* tp_setattr */
- NULL, /* tp_compare */
- NULL, /* tp_repr */
- NULL, /* tp_as_number */
- NULL, /* tp_as_sequence */
- NULL, /* tp_as_mapping */
- NULL, /* tp_hash */
- NULL, /* tp_call */
- NULL, /* tp_str */
- NULL, /* tp_getattro */
- NULL, /* tp_setattro */
- NULL, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- NULL, /* Documentation string */
- NULL, /* tp_traverse */
- NULL, /* tp_clear */
- NULL, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- NULL, /* tp_iter */
- NULL, /* tp_iternext */
- py_bvhtree_methods, /* tp_methods */
- NULL, /* tp_members */
- NULL, /* tp_getset */
- NULL, /* tp_base */
- NULL, /* tp_dict */
- NULL, /* tp_descr_get */
- NULL, /* tp_descr_set */
- 0, /* tp_dictoffset */
- NULL, /* tp_init */
- (allocfunc)PyType_GenericAlloc, /* tp_alloc */
- (newfunc)PyType_GenericNew, /* tp_new */
- (freefunc)0, /* tp_free */
- NULL, /* tp_is_gc */
- NULL, /* tp_bases */
- NULL, /* tp_mro */
- NULL, /* tp_cache */
- NULL, /* tp_subclasses */
- NULL, /* tp_weaklist */
- (destructor)NULL, /* tp_del */
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "BVHTree",
+ /*tp_basicsize*/ sizeof(PyBVHTree),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)py_bvhtree__tp_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ NULL,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ NULL,
+ /*tp_as_mapping*/ NULL,
+ /*tp_hash*/ NULL,
+ /*tp_call*/ NULL,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT,
+ /*tp_doc*/ NULL,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ NULL,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ py_bvhtree_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ NULL,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ NULL,
+ /*tp_alloc*/ (allocfunc)PyType_GenericAlloc,
+ /*tp_new*/ (newfunc)PyType_GenericNew,
+ /*tp_free*/ (freefunc)0,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ (destructor)NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
/* -------------------------------------------------------------------- */
@@ -1290,14 +1293,14 @@ PyDoc_STRVAR(py_bvhtree_doc,
"BVH tree structures for proximity searches and ray casts on geometry.");
static struct PyModuleDef bvhtree_moduledef = {
PyModuleDef_HEAD_INIT,
- "mathutils.bvhtree", /* m_name */
- py_bvhtree_doc, /* m_doc */
- 0, /* m_size */
- NULL, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "mathutils.bvhtree",
+ /*m_doc*/ py_bvhtree_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ NULL,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyMODINIT_FUNC PyInit_mathutils_bvhtree(void)
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 28deebcf5ac..59a3bc40b1c 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -185,6 +185,13 @@ static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject
return NULL;
}
+ /* Zero 3rd axis of 2D vectors. */
+ if (ix_vec_num == 2) {
+ lines[1][2] = 0.0f;
+ lines[2][2] = 0.0f;
+ lines[3][2] = 0.0f;
+ }
+
result = isect_line_line_v3(UNPACK4(lines), i1, i2);
/* The return-code isn't exposed,
* this way we can check know how close the lines are. */
@@ -1465,7 +1472,7 @@ static PyObject *M_Geometry_convex_hull_2d(PyObject *UNUSED(self), PyObject *poi
int *index_map;
Py_ssize_t len_ret, i;
- index_map = MEM_mallocN(sizeof(*index_map) * len * 2, __func__);
+ index_map = MEM_mallocN(sizeof(*index_map) * len, __func__);
/* Non Python function */
len_ret = BLI_convexhull_2d(points, len, index_map);
@@ -1786,14 +1793,14 @@ static PyMethodDef M_Geometry_methods[] = {
static struct PyModuleDef M_Geometry_module_def = {
PyModuleDef_HEAD_INIT,
- "mathutils.geometry", /* m_name */
- M_Geometry_doc, /* m_doc */
- 0, /* m_size */
- M_Geometry_methods, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "mathutils.geometry",
+ /*m_doc*/ M_Geometry_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ M_Geometry_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
/*----------------------------MODULE INIT-------------------------*/
diff --git a/source/blender/python/mathutils/mathutils_interpolate.c b/source/blender/python/mathutils/mathutils_interpolate.c
index 10f42d9b070..76a0fc55774 100644
--- a/source/blender/python/mathutils/mathutils_interpolate.c
+++ b/source/blender/python/mathutils/mathutils_interpolate.c
@@ -89,14 +89,14 @@ static PyMethodDef M_Interpolate_methods[] = {
static struct PyModuleDef M_Interpolate_module_def = {
PyModuleDef_HEAD_INIT,
- "mathutils.interpolate", /* m_name */
- M_Interpolate_doc, /* m_doc */
- 0, /* m_size */
- M_Interpolate_methods, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "mathutils.interpolate",
+ /*m_doc*/ M_Interpolate_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ M_Interpolate_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
/*----------------------------MODULE INIT-------------------------*/
diff --git a/source/blender/python/mathutils/mathutils_kdtree.c b/source/blender/python/mathutils/mathutils_kdtree.c
index f5a27c6f90f..ace8ccdeb2a 100644
--- a/source/blender/python/mathutils/mathutils_kdtree.c
+++ b/source/blender/python/mathutils/mathutils_kdtree.c
@@ -372,66 +372,70 @@ PyDoc_STRVAR(py_KDtree_doc,
"\n"
" :class:`KDTree.balance` must have been called before using any of the ``find`` "
"methods.\n");
+
PyTypeObject PyKDTree_Type = {
- PyVarObject_HEAD_INIT(NULL, 0) "KDTree", /* tp_name */
- sizeof(PyKDTree), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- (destructor)PyKDTree__tp_dealloc, /* tp_dealloc */
- (printfunc)NULL, /* tp_print */
- NULL, /* tp_getattr */
- NULL, /* tp_setattr */
- NULL, /* tp_compare */
- NULL, /* tp_repr */
- NULL, /* tp_as_number */
- NULL, /* tp_as_sequence */
- NULL, /* tp_as_mapping */
- NULL, /* tp_hash */
- NULL, /* tp_call */
- NULL, /* tp_str */
- NULL, /* tp_getattro */
- NULL, /* tp_setattro */
- NULL, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- py_KDtree_doc, /* Documentation string */
- NULL, /* tp_traverse */
- NULL, /* tp_clear */
- NULL, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- NULL, /* tp_iter */
- NULL, /* tp_iternext */
- (struct PyMethodDef *)PyKDTree_methods, /* tp_methods */
- NULL, /* tp_members */
- NULL, /* tp_getset */
- NULL, /* tp_base */
- NULL, /* tp_dict */
- NULL, /* tp_descr_get */
- NULL, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)PyKDTree__tp_init, /* tp_init */
- (allocfunc)PyType_GenericAlloc, /* tp_alloc */
- (newfunc)PyType_GenericNew, /* tp_new */
- (freefunc)0, /* tp_free */
- NULL, /* tp_is_gc */
- NULL, /* tp_bases */
- NULL, /* tp_mro */
- NULL, /* tp_cache */
- NULL, /* tp_subclasses */
- NULL, /* tp_weaklist */
- (destructor)NULL, /* tp_del */
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "KDTree",
+ /*tp_basicsize*/ sizeof(PyKDTree),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ (destructor)PyKDTree__tp_dealloc,
+ /*tp_vectorcall_offset*/ 0,
+ /*tp_getattr*/ NULL,
+ /*tp_setattr*/ NULL,
+ /*tp_as_async*/ NULL,
+ /*tp_repr*/ NULL,
+ /*tp_as_number*/ NULL,
+ /*tp_as_sequence*/ NULL,
+ /*tp_as_mapping*/ NULL,
+ /*tp_hash*/ NULL,
+ /*tp_call*/ NULL,
+ /*tp_str*/ NULL,
+ /*tp_getattro*/ NULL,
+ /*tp_setattro*/ NULL,
+ /*tp_as_buffer*/ NULL,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT,
+ /*Documentation string*/ py_KDtree_doc,
+ /*tp_traverse*/ NULL,
+ /*tp_clear*/ NULL,
+ /*tp_richcompare*/ NULL,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ NULL,
+ /*tp_iternext*/ NULL,
+ /*tp_methods*/ (struct PyMethodDef *)PyKDTree_methods,
+ /*tp_members*/ NULL,
+ /*tp_getset*/ NULL,
+ /*tp_base*/ NULL,
+ /*tp_dict*/ NULL,
+ /*tp_descr_get*/ NULL,
+ /*tp_descr_set*/ NULL,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ (initproc)PyKDTree__tp_init,
+ /*tp_alloc*/ (allocfunc)PyType_GenericAlloc,
+ /*tp_new*/ (newfunc)PyType_GenericNew,
+ /*tp_free*/ (freefunc)0,
+ /*tp_is_gc*/ NULL,
+ /*tp_bases*/ NULL,
+ /*tp_mro*/ NULL,
+ /*tp_cache*/ NULL,
+ /*tp_subclasses*/ NULL,
+ /*tp_weaklist*/ NULL,
+ /*tp_del*/ (destructor)NULL,
+ /*tp_version_tag*/ 0,
+ /*tp_finalize*/ NULL,
+ /*tp_vectorcall*/ NULL,
};
PyDoc_STRVAR(py_kdtree_doc, "Generic 3-dimensional kd-tree to perform spatial searches.");
static struct PyModuleDef kdtree_moduledef = {
PyModuleDef_HEAD_INIT,
- "mathutils.kdtree", /* m_name */
- py_kdtree_doc, /* m_doc */
- 0, /* m_size */
- NULL, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "mathutils.kdtree",
+ /*m_doc*/ py_kdtree_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ NULL,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
PyMODINIT_FUNC PyInit_mathutils_kdtree(void)
diff --git a/source/blender/python/mathutils/mathutils_noise.c b/source/blender/python/mathutils/mathutils_noise.c
index 3a3297f27f7..869201bbcfd 100644
--- a/source/blender/python/mathutils/mathutils_noise.c
+++ b/source/blender/python/mathutils/mathutils_noise.c
@@ -40,7 +40,7 @@
*
* Any feedback is very welcome.
* http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
- * email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space). */
+ * email: `m-mat @ math.sci.hiroshima-u.ac.jp` (remove space). */
/* Period parameters */
#define N 624
@@ -120,7 +120,7 @@ static void setRndSeed(int seed)
}
}
-/* float number in range [0, 1) using the mersenne twister rng */
+/* Float number in range [0, 1) using the mersenne twister random number generator. */
static float frand(void)
{
ulong y;
@@ -1085,14 +1085,14 @@ static PyMethodDef M_Noise_methods[] = {
static struct PyModuleDef M_Noise_module_def = {
PyModuleDef_HEAD_INIT,
- "mathutils.noise", /* m_name */
- M_Noise_doc, /* m_doc */
- 0, /* m_size */
- M_Noise_methods, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "mathutils.noise",
+ /*m_doc*/ M_Noise_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ M_Noise_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
/*----------------------------MODULE INIT-------------------------*/
diff --git a/source/blender/render/RE_multires_bake.h b/source/blender/render/RE_multires_bake.h
index a478f124892..70ce46bc195 100644
--- a/source/blender/render/RE_multires_bake.h
+++ b/source/blender/render/RE_multires_bake.h
@@ -43,8 +43,8 @@ typedef struct MultiresBakeRender {
float user_scale; /* User scale used to scale displacement when baking derivative map. */
- short *stop;
- short *do_update;
+ bool *stop;
+ bool *do_update;
float *progress;
} MultiresBakeRender;
diff --git a/source/blender/render/RE_pipeline.h b/source/blender/render/RE_pipeline.h
index 6007a64a054..d12162c0b9a 100644
--- a/source/blender/render/RE_pipeline.h
+++ b/source/blender/render/RE_pipeline.h
@@ -101,7 +101,6 @@ typedef struct RenderResult {
/* target image size */
int rectx, recty;
- short sample_nr;
/* The following rect32, rectf and rectz buffers are for temporary storage only,
* for RenderResult structs created in #RE_AcquireResultImage - which do not have RenderView */
@@ -124,8 +123,7 @@ typedef struct RenderResult {
/* multiView maps to a StringVector in OpenEXR */
ListBase views; /* RenderView */
- /* allowing live updates: */
- rcti renrect;
+ /* Render layer to display. */
RenderLayer *renlay;
/* for render results in Image, verify validity for sequences */
@@ -400,7 +398,7 @@ void RE_display_update_cb(struct Render *re,
void RE_stats_draw_cb(struct Render *re, void *handle, void (*f)(void *handle, RenderStats *rs));
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, bool lock));
-void RE_test_break_cb(struct Render *re, void *handle, int (*f)(void *handle));
+void RE_test_break_cb(struct Render *re, void *handle, bool (*f)(void *handle));
void RE_current_scene_update_cb(struct Render *re,
void *handle,
void (*f)(void *handle, struct Scene *scene));
diff --git a/source/blender/render/intern/bake.c b/source/blender/render/intern/bake.c
index c383d13e4e1..d9f7f9fa0af 100644
--- a/source/blender/render/intern/bake.c
+++ b/source/blender/render/intern/bake.c
@@ -456,7 +456,7 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval
TriTessFace *triangles;
/* calculate normal for each polygon only once */
- unsigned int mpoly_prev = UINT_MAX;
+ uint mpoly_prev = UINT_MAX;
float no[3];
const MVert *verts = BKE_mesh_verts(me);
@@ -590,7 +590,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low,
me_highpoly[i] = highpoly[i].me;
BKE_mesh_runtime_looptri_ensure(me_highpoly[i]);
- if (me_highpoly[i]->runtime.looptris.len != 0) {
+ if (BKE_mesh_runtime_looptri_len(me_highpoly[i]) != 0) {
/* Create a BVH-tree for each `highpoly` object. */
BKE_bvhtree_from_mesh_get(&treeData[i], me_highpoly[i], BVHTREE_FROM_LOOPTRI, 2);
@@ -747,6 +747,7 @@ void RE_bake_pixels_populate(Mesh *me,
BKE_mesh_recalc_looptri(loops, polys, verts, me->totloop, me->totpoly, looptri);
const int *material_indices = BKE_mesh_material_indices(me);
+ const int materials_num = targets->materials_num;
for (int i = 0; i < tottri; i++) {
const MLoopTri *lt = &looptri[i];
@@ -754,7 +755,10 @@ void RE_bake_pixels_populate(Mesh *me,
bd.primitive_id = i;
/* Find images matching this material. */
- Image *image = targets->material_to_image[material_indices ? material_indices[lt->poly] : 0];
+ const int material_index = (material_indices && materials_num) ?
+ clamp_i(material_indices[lt->poly], 0, materials_num - 1) :
+ 0;
+ Image *image = targets->material_to_image[material_index];
for (int image_id = 0; image_id < targets->images_num; image_id++) {
BakeImage *bk_image = &targets->images[image_id];
if (bk_image->image != image) {
@@ -967,7 +971,7 @@ void RE_bake_normal_world_to_object(const BakePixel pixel_array[],
size_t i;
float iobmat[4][4];
- invert_m4_m4(iobmat, ob->obmat);
+ invert_m4_m4(iobmat, ob->object_to_world);
for (i = 0; i < pixels_num; i++) {
size_t offset;
diff --git a/source/blender/render/intern/engine.cc b/source/blender/render/intern/engine.cc
index 0024ebe38f7..acca657f7dc 100644
--- a/source/blender/render/intern/engine.cc
+++ b/source/blender/render/intern/engine.cc
@@ -306,7 +306,7 @@ static void render_result_to_bake(RenderEngine *engine, RenderResult *rr)
/* Render Results */
-static HighlightedTile highlighted_tile_from_result_get(Render *UNUSED(re), RenderResult *result)
+static HighlightedTile highlighted_tile_from_result_get(Render * /*re*/, RenderResult *result)
{
HighlightedTile tile;
tile.rect = result->tilerect;
@@ -798,7 +798,7 @@ void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe)
DEG_ids_clear_recalc(engine->depsgraph, false);
Render *re = engine->re;
- double cfra = (double)frame + (double)subframe;
+ double cfra = double(frame) + double(subframe);
CLAMP(cfra, MINAFRAME, MAXFRAME);
BKE_scene_frame_set(re->scene, cfra);
@@ -969,6 +969,40 @@ static void engine_render_view_layer(Render *re,
engine_depsgraph_exit(engine);
}
+/* Callback function for engine_render_create_result to add all render passes to the result. */
+static void engine_render_add_result_pass_cb(void *user_data,
+ struct Scene *UNUSED(scene),
+ struct ViewLayer *view_layer,
+ const char *name,
+ int channels,
+ const char *chanid,
+ eNodeSocketDatatype UNUSED(type))
+{
+ RenderResult *rr = (RenderResult *)user_data;
+ RE_create_render_pass(rr, name, channels, chanid, view_layer->name, RR_ALL_VIEWS, false);
+}
+
+static RenderResult *engine_render_create_result(Render *re)
+{
+ RenderResult *rr = render_result_new(re, &re->disprect, RR_ALL_LAYERS, RR_ALL_VIEWS);
+ if (rr == nullptr) {
+ return nullptr;
+ }
+
+ FOREACH_VIEW_LAYER_TO_RENDER_BEGIN (re, view_layer) {
+ RE_engine_update_render_passes(
+ re->engine, re->scene, view_layer, engine_render_add_result_pass_cb, rr);
+ }
+ FOREACH_VIEW_LAYER_TO_RENDER_END;
+
+ /* Preview does not support deferred render result allocation. */
+ if (re->r.scemode & R_BUTS_PREVIEW) {
+ render_result_passes_allocated_ensure(rr);
+ }
+
+ return rr;
+}
+
bool RE_engine_render(Render *re, bool do_all)
{
RenderEngineType *type = RE_engines_find(re->r.engine);
@@ -1002,10 +1036,12 @@ bool RE_engine_render(Render *re, bool do_all)
return true;
}
- /* update animation here so any render layer animation is applied before
- * creating the render result */
- if ((re->r.scemode & (R_NO_FRAME_UPDATE | R_BUTS_PREVIEW)) == 0) {
- render_update_anim_renderdata(re, &re->scene->r, &re->scene->view_layers);
+ /* Create engine. */
+ RenderEngine *engine = re->engine;
+
+ if (!engine) {
+ engine = RE_engine_create(type);
+ re->engine = engine;
}
/* create render result */
@@ -1015,7 +1051,7 @@ bool RE_engine_render(Render *re, bool do_all)
render_result_free(re->result);
}
- re->result = render_result_new(re, &re->disprect, RR_ALL_LAYERS, RR_ALL_VIEWS);
+ re->result = engine_render_create_result(re);
}
BLI_rw_mutex_unlock(&re->resultmutex);
@@ -1024,6 +1060,9 @@ bool RE_engine_render(Render *re, bool do_all)
if (re->draw_lock) {
re->draw_lock(re->dlh, false);
}
+ /* Free engine. */
+ RE_engine_free(engine);
+ re->engine = nullptr;
/* Too small image is handled earlier, here it could only happen if
* there was no sufficient memory to allocate all passes.
*/
@@ -1036,14 +1075,6 @@ bool RE_engine_render(Render *re, bool do_all)
re->i.cfra = re->scene->r.cfra;
BLI_strncpy(re->i.scene_name, re->scene->id.name + 2, sizeof(re->i.scene_name));
- /* render */
- RenderEngine *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 */
diff --git a/source/blender/render/intern/initrender.cc b/source/blender/render/intern/initrender.cc
index 1ea93cbf6c8..591791587fe 100644
--- a/source/blender/render/intern/initrender.cc
+++ b/source/blender/render/intern/initrender.cc
@@ -128,7 +128,7 @@ float RE_filter_value(int type, float x)
case R_FILTER_FAST_GAUSS: {
const float two_gaussfac2 = 2.0f * gaussfac * gaussfac;
x *= 3.0f * gaussfac;
- return 1.0f / sqrtf((float)M_PI * two_gaussfac2) * expf(-x * x / two_gaussfac2);
+ return 1.0f / sqrtf(float(M_PI) * two_gaussfac2) * expf(-x * x / two_gaussfac2);
}
case R_FILTER_MITCH:
diff --git a/source/blender/render/intern/multires_bake.c b/source/blender/render/intern/multires_bake.c
index 79eddd20bdf..cfb91e86ad9 100644
--- a/source/blender/render/intern/multires_bake.c
+++ b/source/blender/render/intern/multires_bake.c
@@ -89,7 +89,7 @@ typedef struct {
char *texels;
const MResolvePixelData *data;
MFlushPixel flush_pixel;
- short *do_update;
+ bool *do_update;
} MBakeRast;
typedef struct {
@@ -134,7 +134,7 @@ static void init_bake_rast(MBakeRast *bake_rast,
const ImBuf *ibuf,
const MResolvePixelData *data,
MFlushPixel flush_pixel,
- short *do_update)
+ bool *do_update)
{
BakeImBufuserData *userdata = (BakeImBufuserData *)ibuf->userdata;
@@ -996,7 +996,7 @@ static void apply_tangmat_callback(DerivedMesh *lores_dm,
rrgbf[3] = 1.0f;
}
else {
- unsigned char *rrgb = (unsigned char *)ibuf->rect + pixel * 4;
+ uchar *rrgb = (uchar *)ibuf->rect + pixel * 4;
rgb_float_to_uchar(rrgb, vec);
rrgb[3] = 255;
}
@@ -1009,8 +1009,8 @@ static void apply_tangmat_callback(DerivedMesh *lores_dm,
/* Must be a power of two. */
# define MAX_NUMBER_OF_AO_RAYS 1024
-static unsigned short ao_random_table_1[MAX_NUMBER_OF_AO_RAYS];
-static unsigned short ao_random_table_2[MAX_NUMBER_OF_AO_RAYS];
+static ushort ao_random_table_1[MAX_NUMBER_OF_AO_RAYS];
+static ushort ao_random_table_2[MAX_NUMBER_OF_AO_RAYS];
static void init_ao_random(void)
{
@@ -1022,18 +1022,18 @@ static void init_ao_random(void)
}
}
-static unsigned short get_ao_random1(const int i)
+static ushort get_ao_random1(const int i)
{
return ao_random_table_1[i & (MAX_NUMBER_OF_AO_RAYS - 1)];
}
-static unsigned short get_ao_random2(const int i)
+static ushort get_ao_random2(const int i)
{
return ao_random_table_2[i & (MAX_NUMBER_OF_AO_RAYS - 1)];
}
-static void build_permutation_table(unsigned short permutation[],
- unsigned short temp_permutation[],
+static void build_permutation_table(ushort permutation[],
+ ushort temp_permutation[],
const int number_of_rays,
const int is_first_perm_table)
{
@@ -1044,9 +1044,9 @@ static void build_permutation_table(unsigned short permutation[],
}
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);
- const unsigned short entry = rnd % nr_entries_left;
+ const uint nr_entries_left = number_of_rays - i;
+ ushort rnd = is_first_perm_table != false ? get_ao_random1(i) : get_ao_random2(i);
+ const ushort entry = rnd % nr_entries_left;
/* pull entry */
permutation[i] = temp_permutation[entry];
@@ -1116,7 +1116,7 @@ static void *init_ao_data(MultiresBakeRender *bkr, ImBuf *UNUSED(ibuf))
{
MAOBakeData *ao_data;
DerivedMesh *lodm = bkr->lores_dm;
- unsigned short *temp_permutation_table;
+ ushort *temp_permutation_table;
size_t permutation_size;
init_ao_random();
@@ -1131,7 +1131,7 @@ static void *init_ao_data(MultiresBakeRender *bkr, ImBuf *UNUSED(ibuf))
create_ao_raytree(bkr, ao_data);
/* initialize permutation tables */
- permutation_size = sizeof(unsigned short) * bkr->number_of_rays;
+ permutation_size = sizeof(ushort) * bkr->number_of_rays;
ao_data->permutation_table_1 = MEM_callocN(permutation_size, "multires AO baker perm1");
ao_data->permutation_table_2 = MEM_callocN(permutation_size, "multires AO baker perm2");
temp_permutation_table = MEM_callocN(permutation_size, "multires AO baker temp perm");
@@ -1273,9 +1273,9 @@ static void apply_ao_callback(DerivedMesh *lores_dm,
/* use N-Rooks to distribute our N ray samples across
* a multi-dimensional domain (2D)
*/
- const unsigned short I =
+ const ushort I =
ao_data->permutation_table_1[(i + perm_ofs) % ao_data->number_of_rays];
- const unsigned short J = ao_data->permutation_table_2[i];
+ const ushort J = ao_data->permutation_table_2[i];
const float JitPh = (get_ao_random2(I + perm_ofs) & (MAX_NUMBER_OF_AO_RAYS - 1)) /
((float)MAX_NUMBER_OF_AO_RAYS);
@@ -1317,7 +1317,7 @@ static void apply_ao_callback(DerivedMesh *lores_dm,
rrgbf[3] = 1.0f;
}
else {
- unsigned char *rrgb = (unsigned char *)ibuf->rect + pixel * 4;
+ uchar *rrgb = (uchar *)ibuf->rect + pixel * 4;
rrgb[0] = rrgb[1] = rrgb[2] = unit_float_to_uchar_clamp(value);
rrgb[3] = 255;
}
@@ -1393,7 +1393,7 @@ static void bake_ibuf_normalize_displacement(ImBuf *ibuf,
}
if (ibuf->rect) {
- unsigned char *cp = (unsigned char *)(ibuf->rect + i);
+ uchar *cp = (uchar *)(ibuf->rect + i);
cp[0] = cp[1] = cp[2] = unit_float_to_uchar_clamp(normalized_displacement);
cp[3] = 255;
}
diff --git a/source/blender/render/intern/pipeline.cc b/source/blender/render/intern/pipeline.cc
index d9ffb09c5a4..17cf3b7ff74 100644
--- a/source/blender/render/intern/pipeline.cc
+++ b/source/blender/render/intern/pipeline.cc
@@ -162,29 +162,27 @@ static bool do_write_image_or_movie(Render *re,
const char *name_override);
/* default callbacks, set in each new render */
-static void result_nothing(void *UNUSED(arg), RenderResult *UNUSED(rr))
+static void result_nothing(void * /*arg*/, RenderResult * /*rr*/)
{
}
-static void result_rcti_nothing(void *UNUSED(arg),
- RenderResult *UNUSED(rr),
- struct rcti *UNUSED(rect))
+static void result_rcti_nothing(void * /*arg*/, RenderResult * /*rr*/, struct rcti * /*rect*/)
{
}
-static void current_scene_nothing(void *UNUSED(arg), Scene *UNUSED(scene))
+static void current_scene_nothing(void * /*arg*/, Scene * /*scene*/)
{
}
-static void stats_nothing(void *UNUSED(arg), RenderStats *UNUSED(rs))
+static void stats_nothing(void * /*arg*/, RenderStats * /*rs*/)
{
}
-static void float_nothing(void *UNUSED(arg), float UNUSED(val))
+static void float_nothing(void * /*arg*/, float /*val*/)
{
}
-static int default_break(void *UNUSED(arg))
+static bool default_break(void * /*arg*/)
{
return G.is_break == true;
}
-static void stats_background(void *UNUSED(arg), RenderStats *rs)
+static void stats_background(void * /*arg*/, RenderStats *rs)
{
if (rs->infostr == nullptr) {
return;
@@ -263,13 +261,10 @@ RenderResult *RE_MultilayerConvert(
return render_result_new_from_exr(exrhandle, colorspace, predivide, rectx, recty);
}
-RenderLayer *render_get_active_layer(Render *re, RenderResult *rr)
+RenderLayer *render_get_single_layer(Render *re, RenderResult *rr)
{
- ViewLayer *view_layer = static_cast<ViewLayer *>(
- BLI_findlink(&re->view_layers, re->active_view_layer));
-
- if (view_layer) {
- RenderLayer *rl = RE_GetRenderLayer(rr, view_layer->name);
+ if (re->single_view_layer[0]) {
+ RenderLayer *rl = RE_GetRenderLayer(rr, re->single_view_layer);
if (rl) {
return rl;
@@ -387,8 +382,8 @@ void RE_AcquireResultImageViews(Render *re, RenderResult *rr)
RenderView *rv = static_cast<RenderView *>(rr->views.first);
rr->have_combined = (rv->rectf != nullptr);
- /* active layer */
- RenderLayer *rl = render_get_active_layer(re, re->result);
+ /* single layer */
+ RenderLayer *rl = render_get_single_layer(re, re->result);
if (rl) {
if (rv->rectf == nullptr) {
@@ -445,7 +440,7 @@ void RE_AcquireResultImage(Render *re, RenderResult *rr, const int view_id)
rr->rect32 = rv->rect32;
/* active layer */
- rl = render_get_active_layer(re, re->result);
+ rl = render_get_single_layer(re, re->result);
if (rl) {
if (rv->rectf == nullptr) {
@@ -475,7 +470,7 @@ void RE_ReleaseResultImage(Render *re)
}
}
-void RE_ResultGet32(Render *re, unsigned int *rect)
+void RE_ResultGet32(Render *re, uint *rect)
{
RenderResult rres;
const int view_id = BKE_scene_multiview_view_id_get(&re->r, re->viewname);
@@ -491,10 +486,7 @@ void RE_ResultGet32(Render *re, unsigned int *rect)
RE_ReleaseResultImageViews(re, &rres);
}
-void RE_AcquiredResultGet32(Render *re,
- RenderResult *result,
- unsigned int *rect,
- const int view_id)
+void RE_AcquiredResultGet32(Render *re, RenderResult *result, uint *rect, const int view_id)
{
render_result_rect_get_pixels(result,
rect,
@@ -588,9 +580,6 @@ void RE_FreeRender(Render *re)
BLI_mutex_end(&re->engine_draw_mutex);
BLI_mutex_end(&re->highlighted_tiles_mutex);
- BLI_freelistN(&re->view_layers);
- BLI_freelistN(&re->r.views);
-
BKE_curvemapping_free_data(&re->r.mblur_shutter_curve);
if (re->highlighted_tiles != nullptr) {
@@ -710,19 +699,18 @@ static void re_init_resolution(Render *re, Render *source, int winx, int winy, r
void render_copy_renderdata(RenderData *to, RenderData *from)
{
- BLI_freelistN(&to->views);
+ /* Mostly shallow copy referencing pointers in scene renderdata. */
BKE_curvemapping_free_data(&to->mblur_shutter_curve);
memcpy(to, from, sizeof(*to));
- BLI_duplicatelist(&to->views, &from->views);
BKE_curvemapping_copy_data(&to->mblur_shutter_curve, &from->mblur_shutter_curve);
}
void RE_InitState(Render *re,
Render *source,
RenderData *rd,
- ListBase *render_layers,
+ ListBase * /*render_layers*/,
ViewLayer *single_layer,
int winx,
int winy,
@@ -736,9 +724,7 @@ void RE_InitState(Render *re,
/* copy render data and render layers for thread safety */
render_copy_renderdata(&re->r, rd);
- BLI_freelistN(&re->view_layers);
- BLI_duplicatelist(&re->view_layers, render_layers);
- re->active_view_layer = 0;
+ re->single_view_layer[0] = '\0';
if (source) {
/* reuse border flags from source renderer */
@@ -762,16 +748,13 @@ void RE_InitState(Render *re,
if (re->rectx < 1 || re->recty < 1 ||
(BKE_imtype_is_movie(rd->im_format.imtype) && (re->rectx < 16 || re->recty < 16))) {
BKE_report(re->reports, RPT_ERROR, "Image too small");
- re->ok = 0;
+ re->ok = false;
return;
}
if (single_layer) {
- int index = BLI_findindex(render_layers, single_layer);
- if (index != -1) {
- re->active_view_layer = index;
- re->r.scemode |= R_SINGLE_LAYER;
- }
+ STRNCPY(re->single_view_layer, single_layer->name);
+ re->r.scemode |= R_SINGLE_LAYER;
}
/* if preview render, we try to keep old result */
@@ -784,13 +767,16 @@ void RE_InitState(Render *re,
re->result = nullptr;
}
else if (re->result) {
- ViewLayer *active_render_layer = static_cast<ViewLayer *>(
- BLI_findlink(&re->view_layers, re->active_view_layer));
bool have_layer = false;
- LISTBASE_FOREACH (RenderLayer *, rl, &re->result->layers) {
- if (STREQ(rl->name, active_render_layer->name)) {
- have_layer = true;
+ if (re->single_view_layer[0] == '\0' && re->result->layers.first) {
+ have_layer = true;
+ }
+ else {
+ LISTBASE_FOREACH (RenderLayer *, rl, &re->result->layers) {
+ if (STREQ(rl->name, re->single_view_layer)) {
+ have_layer = true;
+ }
}
}
@@ -822,27 +808,6 @@ void RE_InitState(Render *re,
RE_point_density_fix_linking();
}
-void render_update_anim_renderdata(Render *re, RenderData *rd, ListBase *render_layers)
-{
- /* filter */
- re->r.gauss = rd->gauss;
-
- /* motion blur */
- re->r.blurfac = rd->blurfac;
-
- /* freestyle */
- re->r.line_thickness_mode = rd->line_thickness_mode;
- re->r.unit_line_thickness = rd->unit_line_thickness;
-
- /* render layers */
- BLI_freelistN(&re->view_layers);
- BLI_duplicatelist(&re->view_layers, render_layers);
-
- /* render views */
- BLI_freelistN(&re->r.views);
- BLI_duplicatelist(&re->r.views, &rd->views);
-}
-
void RE_display_init_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr))
{
re->display_init = f;
@@ -882,7 +847,7 @@ void RE_draw_lock_cb(Render *re, void *handle, void (*f)(void *handle, bool lock
re->dlh = handle;
}
-void RE_test_break_cb(Render *re, void *handle, int (*f)(void *handle))
+void RE_test_break_cb(Render *re, void *handle, bool (*f)(void *handle))
{
re->test_break = f;
re->tbh = handle;
@@ -926,7 +891,7 @@ void *RE_gl_context_get(Render *re)
void *RE_gpu_context_get(Render *re)
{
if (re->gpu_context == nullptr) {
- re->gpu_context = GPU_context_create(nullptr);
+ re->gpu_context = GPU_context_create(nullptr, re->gl_context);
}
return re->gpu_context;
}
@@ -984,7 +949,7 @@ static void render_result_uncrop(Render *re)
re->result = rres;
/* Weak, the display callback wants an active render-layer pointer. */
- re->result->renlay = render_get_active_layer(re, re->result);
+ re->result->renlay = render_get_single_layer(re, re->result);
BLI_rw_mutex_unlock(&re->resultmutex);
@@ -1222,7 +1187,7 @@ static void do_render_compositor(Render *re)
/* Weak: the display callback wants an active render-layer pointer. */
if (re->result != nullptr) {
- re->result->renlay = render_get_active_layer(re, re->result);
+ re->result->renlay = render_get_single_layer(re, re->result);
re->display_update(re->duh, re->result, nullptr);
}
}
@@ -1241,7 +1206,7 @@ static void renderresult_stampinfo(Render *re)
BKE_image_stamp_buf(re->scene,
ob_camera_eval,
(re->r.stamp & R_STAMP_STRIPMETA) ? rres.stamp_data : nullptr,
- (unsigned char *)rres.rect32,
+ (uchar *)rres.rect32,
rres.rectf,
rres.rectx,
rres.recty,
@@ -1371,7 +1336,7 @@ static void do_render_sequencer(Render *re)
/* set overall progress of sequence rendering */
if (re->r.efra != re->r.sfra) {
- re->progress(re->prh, (float)(cfra - re->r.sfra) / (re->r.efra - re->r.sfra));
+ re->progress(re->prh, float(cfra - re->r.sfra) / (re->r.efra - re->r.sfra));
}
else {
re->progress(re->prh, 1.0f);
@@ -1439,7 +1404,7 @@ static bool check_valid_compositing_camera(Scene *scene, Object *camera_override
if (node->type == CMP_NODE_R_LAYERS && (node->flag & NODE_MUTED) == 0) {
Scene *sce = node->id ? (Scene *)node->id : scene;
if (sce->camera == nullptr) {
- sce->camera = BKE_view_layer_camera_find(BKE_view_layer_default_render(sce));
+ sce->camera = BKE_view_layer_camera_find(sce, BKE_view_layer_default_render(sce));
}
if (sce->camera == nullptr) {
/* all render layers nodes need camera */
@@ -1497,7 +1462,7 @@ static int check_valid_camera(Scene *scene, Object *camera_override, ReportList
const char *err_msg = "No camera found in scene \"%s\"";
if (camera_override == nullptr && scene->camera == nullptr) {
- scene->camera = BKE_view_layer_camera_find(BKE_view_layer_default_render(scene));
+ scene->camera = BKE_view_layer_camera_find(scene, BKE_view_layer_default_render(scene));
}
if (!check_valid_camera_multiview(scene, scene->camera, reports)) {
@@ -1511,7 +1476,8 @@ static int check_valid_camera(Scene *scene, Object *camera_override, ReportList
(seq->scene != nullptr)) {
if (!seq->scene_camera) {
if (!seq->scene->camera &&
- !BKE_view_layer_camera_find(BKE_view_layer_default_render(seq->scene))) {
+ !BKE_view_layer_camera_find(seq->scene,
+ BKE_view_layer_default_render(seq->scene))) {
/* camera could be unneeded due to composite nodes */
Object *override = (seq->scene == scene) ? camera_override : nullptr;
@@ -1612,7 +1578,7 @@ bool RE_is_rendering_allowed(Scene *scene,
static void update_physics_cache(Render *re,
Scene *scene,
ViewLayer *view_layer,
- int UNUSED(anim_init))
+ int /*anim_init*/)
{
PTCacheBaker baker;
@@ -1639,15 +1605,15 @@ const char *RE_GetActiveRenderView(Render *re)
return re->viewname;
}
-/* evaluating scene options for general Blender render */
-static int render_init_from_main(Render *re,
- const RenderData *rd,
- Main *bmain,
- Scene *scene,
- ViewLayer *single_layer,
- Object *camera_override,
- int anim,
- int anim_init)
+/** Evaluating scene options for general Blender render. */
+static bool render_init_from_main(Render *re,
+ const RenderData *rd,
+ Main *bmain,
+ Scene *scene,
+ ViewLayer *single_layer,
+ Object *camera_override,
+ int anim,
+ int anim_init)
{
int winx, winy;
rcti disprect;
@@ -1680,9 +1646,8 @@ static int render_init_from_main(Render *re,
/* not too nice, but it survives anim-border render */
if (anim) {
- render_update_anim_renderdata(re, &scene->r, &scene->view_layers);
re->disprect = disprect;
- return 1;
+ return true;
}
/*
@@ -1704,7 +1669,7 @@ static int render_init_from_main(Render *re,
RE_InitState(re, nullptr, &scene->r, &scene->view_layers, single_layer, winx, winy, &disprect);
if (!re->ok) { /* if an error was printed, abort */
- return 0;
+ return false;
}
/* initstate makes new result, have to send changed tags around */
@@ -1713,7 +1678,7 @@ static int render_init_from_main(Render *re,
re->display_init(re->dih, re->result);
re->display_clear(re->dch, re->result);
- return 1;
+ return true;
}
void RE_SetReports(Render *re, ReportList *reports)
@@ -1866,7 +1831,7 @@ static bool use_eevee_for_freestyle_render(Render *re)
void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, int render)
{
- re->result_ok = 0;
+ re->result_ok = false;
if (render_init_from_main(re, &scene->r, bmain, scene, nullptr, nullptr, 0, 0)) {
if (render) {
char scene_engine[32];
@@ -1880,7 +1845,7 @@ void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, int render
change_renderdata_engine(re, scene_engine);
}
}
- re->result_ok = 1;
+ re->result_ok = true;
}
void RE_RenderFreestyleExternal(Render *re)
@@ -1894,12 +1859,10 @@ void RE_RenderFreestyleExternal(Render *re)
LISTBASE_FOREACH (RenderView *, rv, &re->result->views) {
RE_SetActiveRenderView(re, rv->name);
- ViewLayer *active_view_layer = static_cast<ViewLayer *>(
- BLI_findlink(&re->view_layers, re->active_view_layer));
FRS_begin_stroke_rendering(re);
- LISTBASE_FOREACH (ViewLayer *, view_layer, &re->view_layers) {
- if ((re->r.scemode & R_SINGLE_LAYER) && view_layer != active_view_layer) {
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &re->scene->view_layers) {
+ if ((re->r.scemode & R_SINGLE_LAYER) && !STREQ(view_layer->name, re->single_view_layer)) {
continue;
}
@@ -2327,7 +2290,7 @@ void RE_RenderAnim(Render *re,
if (is_movie == false && do_write_file) {
if (rd.mode & R_TOUCH) {
if (!is_multiview_name) {
- if ((BLI_file_size(name) == 0)) {
+ if (BLI_file_size(name) == 0) {
/* BLI_exists(name) is implicit */
BLI_delete(name, false, false);
}
@@ -2342,7 +2305,7 @@ void RE_RenderAnim(Render *re,
BKE_scene_multiview_filepath_get(srv, name, filepath);
- if ((BLI_file_size(filepath) == 0)) {
+ if (BLI_file_size(filepath) == 0) {
/* BLI_exists(filepath) is implicit */
BLI_delete(filepath, false, false);
}
@@ -2390,6 +2353,9 @@ void RE_RenderAnim(Render *re,
void RE_PreviewRender(Render *re, Main *bmain, Scene *sce)
{
+ /* Ensure within GPU render boundary. */
+ GPU_render_begin();
+
Object *camera;
int winx, winy;
@@ -2410,6 +2376,9 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce)
RE_engine_free(re->engine);
re->engine = nullptr;
}
+
+ /* Close GPU render boundary. */
+ GPU_render_end();
}
/* NOTE: repeated win/disprect calc... solve that nicer, also in compo. */
diff --git a/source/blender/render/intern/pipeline.h b/source/blender/render/intern/pipeline.h
index 689e4509da3..e5da3cb8830 100644
--- a/source/blender/render/intern/pipeline.h
+++ b/source/blender/render/intern/pipeline.h
@@ -17,14 +17,7 @@ struct RenderResult;
extern "C" {
#endif
-struct RenderLayer *render_get_active_layer(struct Render *re, struct RenderResult *rr);
-/**
- * Update some variables that can be animated, and otherwise wouldn't be due to
- * #RenderData getting copied once at the start of animation render.
- */
-void render_update_anim_renderdata(struct Render *re,
- struct RenderData *rd,
- struct ListBase *render_layers);
+struct RenderLayer *render_get_single_layer(struct Render *re, struct RenderResult *rr);
void render_copy_renderdata(struct RenderData *to, struct RenderData *from);
#ifdef __cplusplus
diff --git a/source/blender/render/intern/render_result.cc b/source/blender/render/intern/render_result.cc
index 8b7a07e2b3f..1cd95831ddf 100644
--- a/source/blender/render/intern/render_result.cc
+++ b/source/blender/render/intern/render_result.cc
@@ -169,7 +169,7 @@ static void render_layer_allocate_pass(RenderResult *rr, RenderPass *rp)
return;
}
- const size_t rectsize = ((size_t)rr->rectx) * rr->recty * rp->channels;
+ const size_t rectsize = size_t(rr->rectx) * rr->recty * rp->channels;
rp->rect = MEM_cnew_array<float>(rectsize, rp->name);
if (STREQ(rp->name, RE_PASSNAME_VECTOR)) {
@@ -251,8 +251,6 @@ RenderResult *render_result_new(Render *re,
rr = MEM_cnew<RenderResult>("new render result");
rr->rectx = rectx;
rr->recty = recty;
- rr->renrect.xmin = 0;
- rr->renrect.xmax = rectx;
/* tilerect is relative coordinates within render disprect. do not subtract crop yet */
rr->tilerect.xmin = partrct->xmin - re->disprect.xmin;
@@ -264,7 +262,7 @@ RenderResult *render_result_new(Render *re,
render_result_views_new(rr, &re->r);
- /* check renderdata for amount of layers */
+ /* Check render-data for amount of layers. */
FOREACH_VIEW_LAYER_TO_RENDER_BEGIN (re, view_layer) {
if (layername && layername[0]) {
if (!STREQ(view_layer->name, layername)) {
@@ -292,90 +290,8 @@ RenderResult *render_result_new(Render *re,
}
}
-#define RENDER_LAYER_ADD_PASS_SAFE(rr, rl, channels, name, viewname, chan_id) \
- do { \
- if (render_layer_add_pass(rr, rl, channels, name, viewname, chan_id, false) == nullptr) { \
- render_result_free(rr); \
- return nullptr; \
- } \
- } while (false)
-
/* A render-layer should always have a "Combined" pass. */
render_layer_add_pass(rr, rl, 4, "Combined", view, "RGBA", false);
-
- if (view_layer->passflag & SCE_PASS_Z) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_Z, view, "Z");
- }
- if (view_layer->passflag & SCE_PASS_VECTOR) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, RE_PASSNAME_VECTOR, view, "XYZW");
- }
- if (view_layer->passflag & SCE_PASS_NORMAL) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_NORMAL, view, "XYZ");
- }
- if (view_layer->passflag & SCE_PASS_POSITION) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_POSITION, view, "XYZ");
- }
- if (view_layer->passflag & SCE_PASS_UV) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_UV, view, "UVA");
- }
- if (view_layer->passflag & SCE_PASS_EMIT) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_EMIT, view, "RGB");
- }
- if (view_layer->passflag & SCE_PASS_AO) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_AO, view, "RGB");
- }
- if (view_layer->passflag & SCE_PASS_ENVIRONMENT) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_ENVIRONMENT, view, "RGB");
- }
- if (view_layer->passflag & SCE_PASS_SHADOW) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SHADOW, view, "RGB");
- }
- if (view_layer->passflag & SCE_PASS_INDEXOB) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_INDEXOB, view, "X");
- }
- if (view_layer->passflag & SCE_PASS_INDEXMA) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_INDEXMA, view, "X");
- }
- if (view_layer->passflag & SCE_PASS_MIST) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_MIST, view, "Z");
- }
- if (view_layer->passflag & SCE_PASS_DIFFUSE_DIRECT) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE_DIRECT, view, "RGB");
- }
- if (view_layer->passflag & SCE_PASS_DIFFUSE_INDIRECT) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE_INDIRECT, view, "RGB");
- }
- if (view_layer->passflag & SCE_PASS_DIFFUSE_COLOR) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE_COLOR, view, "RGB");
- }
- if (view_layer->passflag & SCE_PASS_GLOSSY_DIRECT) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_GLOSSY_DIRECT, view, "RGB");
- }
- if (view_layer->passflag & SCE_PASS_GLOSSY_INDIRECT) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_GLOSSY_INDIRECT, view, "RGB");
- }
- if (view_layer->passflag & SCE_PASS_GLOSSY_COLOR) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_GLOSSY_COLOR, view, "RGB");
- }
- if (view_layer->passflag & SCE_PASS_TRANSM_DIRECT) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_TRANSM_DIRECT, view, "RGB");
- }
- if (view_layer->passflag & SCE_PASS_TRANSM_INDIRECT) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_TRANSM_INDIRECT, view, "RGB");
- }
- if (view_layer->passflag & SCE_PASS_TRANSM_COLOR) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_TRANSM_COLOR, view, "RGB");
- }
- if (view_layer->passflag & SCE_PASS_SUBSURFACE_DIRECT) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_DIRECT, view, "RGB");
- }
- if (view_layer->passflag & SCE_PASS_SUBSURFACE_INDIRECT) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_INDIRECT, view, "RGB");
- }
- if (view_layer->passflag & SCE_PASS_SUBSURFACE_COLOR) {
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_COLOR, view, "RGB");
- }
-#undef RENDER_LAYER_ADD_PASS_SAFE
}
}
FOREACH_VIEW_LAYER_TO_RENDER_END;
@@ -405,7 +321,7 @@ RenderResult *render_result_new(Render *re,
rl->layflag = SCE_LAY_FLAG_DEFAULT;
rl->passflag = SCE_PASS_COMBINED;
- re->active_view_layer = 0;
+ re->single_view_layer[0] = '\0';
}
/* Border render; calculate offset for use in compositor. compo is centralized coords. */
@@ -413,11 +329,6 @@ RenderResult *render_result_new(Render *re,
rr->xof = re->disprect.xmin + BLI_rcti_cent_x(&re->disprect) - (re->winx / 2);
rr->yof = re->disprect.ymin + BLI_rcti_cent_y(&re->disprect) - (re->winy / 2);
- /* Preview does not support deferred render result allocation. */
- if (re->r.scemode & R_BUTS_PREVIEW) {
- render_result_passes_allocated_ensure(rr);
- }
-
return rr;
}
@@ -654,8 +565,8 @@ static int order_render_passes(const void *a, const void *b)
/* 1 if `a` is after `b`. */
RenderPass *rpa = (RenderPass *)a;
RenderPass *rpb = (RenderPass *)b;
- unsigned int passtype_a = passtype_from_name(rpa->name);
- unsigned int passtype_b = passtype_from_name(rpb->name);
+ uint passtype_a = passtype_from_name(rpa->name);
+ uint passtype_b = passtype_from_name(rpb->name);
/* Render passes with default type always go first. */
if (passtype_b && !passtype_a) {
@@ -780,7 +691,7 @@ static void do_merge_tile(
copylen = tilex = rrpart->rectx;
tiley = rrpart->recty;
- ofs = (((size_t)rrpart->tilerect.ymin) * rr->rectx + rrpart->tilerect.xmin);
+ ofs = (size_t(rrpart->tilerect.ymin) * rr->rectx + rrpart->tilerect.xmin);
target += pixsize * ofs;
copylen *= sizeof(float) * pixsize;
@@ -857,8 +768,8 @@ void render_result_single_layer_end(Render *re)
/* reconstruct render result layers */
int nr = 0;
- LISTBASE_FOREACH (ViewLayer *, view_layer, &re->view_layers) {
- if (nr == re->active_view_layer) {
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &re->scene->view_layers) {
+ if (STREQ(view_layer->name, re->single_view_layer)) {
BLI_addtail(&re->result->layers, rl);
}
else {
@@ -964,7 +875,7 @@ static void render_result_exr_file_cache_path(Scene *sce,
sce->id.name + 2,
path_hexdigest);
- BLI_join_dirfile(r_path, FILE_CACHE_MAX, root, filename_full);
+ BLI_path_join(r_path, FILE_CACHE_MAX, root, filename_full);
if (BLI_path_is_rel(r_path)) {
BLI_path_abs(r_path, dirname);
}
@@ -1026,7 +937,7 @@ ImBuf *RE_render_result_rect_to_ibuf(RenderResult *rr,
RenderView *rv = RE_RenderViewGetById(rr, view_id);
/* if not exists, BKE_imbuf_write makes one */
- ibuf->rect = (unsigned int *)rv->rect32;
+ ibuf->rect = (uint *)rv->rect32;
ibuf->rect_float = rv->rectf;
ibuf->zbuf_float = rv->rectz;
@@ -1055,7 +966,7 @@ ImBuf *RE_render_result_rect_to_ibuf(RenderResult *rr,
/* Color -> gray-scale. */
/* editing directly would alter the render view */
- if (imf->planes == R_IMF_PLANES_BW) {
+ if (imf->planes == R_IMF_PLANES_BW && imf->imtype != R_IMF_IMTYPE_MULTILAYER) {
ImBuf *ibuf_bw = IMB_dupImBuf(ibuf);
IMB_color_to_bw(ibuf_bw);
IMB_freeImBuf(ibuf);
@@ -1112,7 +1023,7 @@ void render_result_rect_fill_zero(RenderResult *rr, const int view_id)
}
void render_result_rect_get_pixels(RenderResult *rr,
- unsigned int *rect,
+ uint *rect,
int rectx,
int recty,
const ColorManagedViewSettings *view_settings,
@@ -1125,14 +1036,8 @@ void render_result_rect_get_pixels(RenderResult *rr,
memcpy(rect, rv->rect32, sizeof(int) * rr->rectx * rr->recty);
}
else if (rv && rv->rectf) {
- IMB_display_buffer_transform_apply((unsigned char *)rect,
- rv->rectf,
- rr->rectx,
- rr->recty,
- 4,
- view_settings,
- display_settings,
- true);
+ IMB_display_buffer_transform_apply(
+ (uchar *)rect, rv->rectf, rr->rectx, rr->recty, 4, view_settings, display_settings, true);
}
else {
/* else fill with black */
diff --git a/source/blender/render/intern/render_result.h b/source/blender/render/intern/render_result.h
index 2e76efba8a3..6e971d45d31 100644
--- a/source/blender/render/intern/render_result.h
+++ b/source/blender/render/intern/render_result.h
@@ -136,10 +136,11 @@ void render_result_views_shallowdelete(struct RenderResult *rr);
{ \
int nr_; \
ViewLayer *iter_; \
- for (nr_ = 0, iter_ = static_cast<ViewLayer *>((re_)->view_layers.first); iter_ != NULL; \
+ for (nr_ = 0, iter_ = static_cast<ViewLayer *>((re_)->scene->view_layers.first); \
+ iter_ != NULL; \
iter_ = iter_->next, nr_++) { \
if (!G.background && (re_)->r.scemode & R_SINGLE_LAYER) { \
- if (nr_ != re->active_view_layer) { \
+ if (!STREQ(iter_->name, re->single_view_layer)) { \
continue; \
} \
} \
diff --git a/source/blender/render/intern/render_types.h b/source/blender/render/intern/render_types.h
index 29bac6e2766..418acbca3b1 100644
--- a/source/blender/render/intern/render_types.h
+++ b/source/blender/render/intern/render_types.h
@@ -39,7 +39,8 @@ struct Render {
int slot;
/* state settings */
- short flag, ok, result_ok;
+ short flag;
+ bool ok, result_ok;
/* result of rendering */
RenderResult *result;
@@ -76,8 +77,7 @@ struct Render {
struct Main *main;
Scene *scene;
RenderData r;
- ListBase view_layers;
- int active_view_layer;
+ char single_view_layer[MAX_NAME];
struct Object *camera_override;
ThreadMutex highlighted_tiles_mutex;
@@ -108,7 +108,7 @@ struct Render {
void (*draw_lock)(void *handle, bool lock);
void *dlh;
- int (*test_break)(void *handle);
+ bool (*test_break)(void *handle);
void *tbh;
RenderStats i;
diff --git a/source/blender/render/intern/texture_image.c b/source/blender/render/intern/texture_image.c
index 38a569877c0..60a769348e8 100644
--- a/source/blender/render/intern/texture_image.c
+++ b/source/blender/render/intern/texture_image.c
@@ -889,7 +889,7 @@ static void alpha_clip_aniso(
/* TXF alpha: we're doing the same alpha-clip here as box-sample, but I'm doubting
* if this is actually correct for the all the filtering algorithms. */
- if (!(ELEM(extflag, TXC_REPT, TXC_EXTD))) {
+ if (!ELEM(extflag, TXC_REPT, TXC_EXTD)) {
rf.xmin = minx * (ibuf->x);
rf.xmax = maxx * (ibuf->x);
rf.ymin = miny * (ibuf->y);
diff --git a/source/blender/render/intern/texture_margin.cc b/source/blender/render/intern/texture_margin.cc
index 66ab7ba6e2e..3366111ed33 100644
--- a/source/blender/render/intern/texture_margin.cc
+++ b/source/blender/render/intern/texture_margin.cc
@@ -14,6 +14,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -44,7 +45,7 @@ class TextureMarginMap {
/** Maps UV-edges to their corresponding UV-edge. */
Vector<int> loop_adjacency_map_;
/** Maps UV-edges to their corresponding polygon. */
- Vector<int> loop_to_poly_map_;
+ Array<int> loop_to_poly_map_;
int w_, h_;
float uv_offset_[2];
@@ -245,8 +246,8 @@ class TextureMarginMap {
for (int i = 0; i < maxPolygonSteps; i++) {
/* Force to pixel grid. */
- int nx = (int)round(destX);
- int ny = (int)round(destY);
+ int nx = int(round(destX));
+ int ny = int(round(destY));
uint32_t polygon_from_map = get_pixel(nx, ny);
if (other_poly == polygon_from_map) {
found_pixel_in_polygon = true;
@@ -289,13 +290,8 @@ class TextureMarginMap {
void build_tables()
{
- loop_to_poly_map_.resize(totloop_);
- for (int i = 0; i < totpoly_; i++) {
- for (int j = 0; j < mpoly_[i].totloop; j++) {
- int l = j + mpoly_[i].loopstart;
- loop_to_poly_map_[l] = i;
- }
- }
+ loop_to_poly_map_ = blender::bke::mesh_topology::build_loop_to_poly_map({mpoly_, totpoly_},
+ totloop_);
loop_adjacency_map_.resize(totloop_, -1);
@@ -351,7 +347,7 @@ class TextureMarginMap {
uint32_t poly = loop_to_poly_map_[otherloop];
if (lookup_pixel(x, y, poly, &destx, &desty, &foundpoly, &found_dist)) {
- if (mindist < 0.f || found_dist < mindist) {
+ if (mindist < 0.0f || found_dist < mindist) {
mindist = found_dist;
*r_other_poly = foundpoly;
*r_destx = destx;
@@ -562,8 +558,8 @@ static void generate_margin(ImBuf *ibuf,
* 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 T18685. */
- vec[a][0] = (uv[0] - uv_offset[0]) * (float)ibuf->x - (0.5f + 0.001f);
- vec[a][1] = (uv[1] - uv_offset[1]) * (float)ibuf->y - (0.5f + 0.002f);
+ vec[a][0] = (uv[0] - uv_offset[0]) * float(ibuf->x) - (0.5f + 0.001f);
+ vec[a][1] = (uv[1] - uv_offset[1]) * float(ibuf->y) - (0.5f + 0.002f);
}
/* NOTE: we need the top bit for the dijkstra distance map. */
diff --git a/source/blender/render/intern/texture_pointdensity.c b/source/blender/render/intern/texture_pointdensity.c
index 2a2b62be1f0..09173aaa0e3 100644
--- a/source/blender/render/intern/texture_pointdensity.c
+++ b/source/blender/render/intern/texture_pointdensity.c
@@ -174,11 +174,11 @@ static void pointdensity_cache_psys(
sim.psys = psys;
sim.psmd = psys_get_modifier(ob, psys);
- /* in case ob->imat isn't up-to-date */
- invert_m4_m4(ob->imat, ob->obmat);
+ /* in case ob->world_to_object isn't up-to-date */
+ invert_m4_m4(ob->world_to_object, ob->object_to_world);
total_particles = psys->totpart + psys->totchild;
- psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
+ psys_sim_data_init(&sim);
pd->point_tree = BLI_bvhtree_new(total_particles, 0.0, 4, 6);
pd->totpoints = total_particles;
@@ -235,7 +235,7 @@ static void pointdensity_cache_psys(
copy_v3_v3(partco, state.co);
if (pd->psys_cache_space == TEX_PD_OBJECTSPACE) {
- mul_m4_v3(ob->imat, partco);
+ mul_m4_v3(ob->world_to_object, partco);
}
else if (pd->psys_cache_space == TEX_PD_OBJECTLOC) {
sub_v3_v3(partco, ob->loc);
@@ -258,10 +258,7 @@ static void pointdensity_cache_psys(
BLI_bvhtree_balance(pd->point_tree);
- if (psys->lattice_deform_data) {
- BKE_lattice_deform_data_destroy(psys->lattice_deform_data);
- psys->lattice_deform_data = NULL;
- }
+ psys_sim_data_free(&sim);
}
static void pointdensity_cache_vertex_color(PointDensity *pd,
@@ -399,12 +396,12 @@ static void pointdensity_cache_object(PointDensity *pd, Object *ob)
case TEX_PD_OBJECTSPACE:
break;
case TEX_PD_OBJECTLOC:
- mul_m4_v3(ob->obmat, co);
+ mul_m4_v3(ob->object_to_world, co);
sub_v3_v3(co, ob->loc);
break;
case TEX_PD_WORLDSPACE:
default:
- mul_m4_v3(ob->obmat, co);
+ mul_m4_v3(ob->object_to_world, co);
break;
}
@@ -778,9 +775,9 @@ static void particle_system_minmax(Depsgraph *depsgraph,
sim.psys = psys;
sim.psmd = psys_get_modifier(object, psys);
- invert_m4_m4(imat, object->obmat);
+ invert_m4_m4(imat, object->object_to_world);
total_particles = psys->totpart + psys->totchild;
- psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
+ psys_sim_data_init(&sim);
for (i = 0, pa = psys->particles; i < total_particles; i++, pa++) {
float co_object[3], co_min[3], co_max[3];
@@ -796,10 +793,7 @@ static void particle_system_minmax(Depsgraph *depsgraph,
minmax_v3v3_v3(min, max, co_max);
}
- if (psys->lattice_deform_data) {
- BKE_lattice_deform_data_destroy(psys->lattice_deform_data);
- psys->lattice_deform_data = NULL;
- }
+ psys_sim_data_free(&sim);
}
void RE_point_density_cache(struct Depsgraph *depsgraph, PointDensity *pd)
diff --git a/source/blender/sequencer/SEQ_proxy.h b/source/blender/sequencer/SEQ_proxy.h
index 00747f4b9cf..caf123afbcf 100644
--- a/source/blender/sequencer/SEQ_proxy.h
+++ b/source/blender/sequencer/SEQ_proxy.h
@@ -29,8 +29,8 @@ bool SEQ_proxy_rebuild_context(struct Main *bmain,
struct ListBase *queue,
bool build_only_on_bad_performance);
void SEQ_proxy_rebuild(struct SeqIndexBuildContext *context,
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress);
void SEQ_proxy_rebuild_finish(struct SeqIndexBuildContext *context, bool stop);
void SEQ_proxy_set(struct Sequence *seq, bool value);
diff --git a/source/blender/sequencer/SEQ_render.h b/source/blender/sequencer/SEQ_render.h
index 9c163de4230..e2672eef8b9 100644
--- a/source/blender/sequencer/SEQ_render.h
+++ b/source/blender/sequencer/SEQ_render.h
@@ -66,8 +66,8 @@ void SEQ_render_thumbnails(const struct SeqRenderData *context,
struct Sequence *seq,
struct Sequence *seq_orig,
float frame_step,
- rctf *view_area,
- const short *stop);
+ const struct rctf *view_area,
+ const bool *stop);
/**
* Get cached thumbnails.
*/
@@ -82,7 +82,7 @@ struct ImBuf *SEQ_get_thumbnail(const struct SeqRenderData *context,
float SEQ_render_thumbnail_first_frame_get(const struct Scene *scene,
struct Sequence *seq,
float frame_step,
- struct rctf *view_area);
+ const struct rctf *view_area);
/**
* Get frame for first thumbnail.
*/
@@ -102,8 +102,8 @@ int SEQ_render_thumbnails_guaranteed_set_frame_step_get(const struct Scene *scen
void SEQ_render_thumbnails_base_set(const struct SeqRenderData *context,
struct Sequence *seq,
struct Sequence *seq_orig,
- rctf *view_area,
- const short *stop);
+ const struct rctf *view_area,
+ const bool *stop);
void SEQ_render_init_colorspace(struct Sequence *seq);
void SEQ_render_new_render_data(struct Main *bmain,
diff --git a/source/blender/sequencer/SEQ_time.h b/source/blender/sequencer/SEQ_time.h
index 69dc20d39ca..11dbe0dab0a 100644
--- a/source/blender/sequencer/SEQ_time.h
+++ b/source/blender/sequencer/SEQ_time.h
@@ -42,7 +42,19 @@ void SEQ_timeline_expand_boundbox(const struct Scene *scene,
void SEQ_timeline_boundbox(const struct Scene *scene,
const struct ListBase *seqbase,
struct rctf *rect);
+/**
+ * Get FPS rate of source media. Movie, scene and movie-clip strips are supported.
+ * Returns 0 for unsupported strip or if media can't be loaded.
+ */
float SEQ_time_sequence_get_fps(struct Scene *scene, struct Sequence *seq);
+/**
+ * Find start or end position of next or previous strip.
+ * \param scene: Video editing scene
+ * \param timeline_frame: reference frame for searching
+ * \param side: direction of searching, `SEQ_SIDE_LEFT`, `SEQ_SIDE_RIGHT` or `SEQ_SIDE_BOTH`.
+ * \param do_center: find closest strip center if true, otherwise finds closest handle position.
+ * \param do_unselected: only find closest position of unselected strip.
+ */
int SEQ_time_find_next_prev_edit(struct Scene *scene,
int timeline_frame,
short side,
@@ -61,20 +73,68 @@ int SEQ_time_find_next_prev_edit(struct Scene *scene,
bool SEQ_time_strip_intersects_frame(const struct Scene *scene,
const struct Sequence *seq,
int timeline_frame);
+/**
+ * Returns true if strip has frames without content to render.
+ */
bool SEQ_time_has_still_frames(const struct Scene *scene, const struct Sequence *seq);
+/**
+ * Returns true if at beginning of strip there is no content to be rendered.
+ */
bool SEQ_time_has_left_still_frames(const struct Scene *scene, const struct Sequence *seq);
+/**
+ * Returns true if at end of strip there is no content to be rendered.
+ */
bool SEQ_time_has_right_still_frames(const struct Scene *scene, const struct Sequence *seq);
-
+/**
+ * Get timeline frame where strip boundary starts.
+ */
int SEQ_time_left_handle_frame_get(const struct Scene *scene, const struct Sequence *seq);
+/**
+ * Get timeline frame where strip boundary ends.
+ */
int SEQ_time_right_handle_frame_get(const struct Scene *scene, const struct Sequence *seq);
-void SEQ_time_left_handle_frame_set(const struct Scene *scene, struct Sequence *seq, int val);
-void SEQ_time_right_handle_frame_set(const struct Scene *scene, struct Sequence *seq, int val);
+/**
+ * Set frame where strip boundary starts. This function moves only handle, content is not moved.
+ */
+void SEQ_time_left_handle_frame_set(const struct Scene *scene,
+ struct Sequence *seq,
+ int timeline_frame);
+/**
+ * Set frame where strip boundary ends.
+ * This function moves only handle, content is not moved.
+ */
+void SEQ_time_right_handle_frame_set(const struct Scene *scene,
+ struct Sequence *seq,
+ int timeline_frame);
+/**
+ * Get number of frames (in timeline) that can be rendered.
+ * This can change depending on scene FPS or strip speed factor.
+ */
int SEQ_time_strip_length_get(const struct Scene *scene, const struct Sequence *seq);
+/**
+ * Set strip playback speed.
+ * Strip length is affected by changing speed factor.
+ */
void SEQ_time_speed_factor_set(const struct Scene *scene,
struct Sequence *seq,
const float speed_factor);
+/**
+ * Get timeline frame where strip content starts.
+ */
float SEQ_time_start_frame_get(const struct Sequence *seq);
+/**
+ * Get timeline frame where strip content ends.
+ */
+float SEQ_time_content_end_frame_get(const struct Scene *scene, const struct Sequence *seq);
+/**
+ * Set frame where strip content starts.
+ * This function will also move strip handles.
+ */
void SEQ_time_start_frame_set(const struct Scene *scene, struct Sequence *seq, int timeline_frame);
+/**
+ * Update length of meta-strip after any contained strip length or position has changed.
+ * \note this function is currently only used internally and in versioning code.
+ */
void SEQ_time_update_meta_strip_range(const struct Scene *scene, struct Sequence *seq_meta);
#ifdef __cplusplus
diff --git a/source/blender/sequencer/SEQ_transform.h b/source/blender/sequencer/SEQ_transform.h
index c27a9dc4409..30cf472f55b 100644
--- a/source/blender/sequencer/SEQ_transform.h
+++ b/source/blender/sequencer/SEQ_transform.h
@@ -23,7 +23,6 @@ bool SEQ_transform_sequence_can_be_translated(struct Sequence *seq);
* since they work a bit differently to normal image seq's (during transform).
*/
bool SEQ_transform_single_image_check(struct Sequence *seq);
-void SEQ_transform_fix_single_image_seq_offsets(const struct Scene *scene, struct Sequence *seq);
bool SEQ_transform_test_overlap(const struct Scene *scene,
struct ListBase *seqbasep,
struct Sequence *test);
diff --git a/source/blender/sequencer/intern/animation.c b/source/blender/sequencer/intern/animation.c
index b8b2dda4690..280d2177d89 100644
--- a/source/blender/sequencer/intern/animation.c
+++ b/source/blender/sequencer/intern/animation.c
@@ -75,7 +75,7 @@ void SEQ_offset_animdata(Scene *scene, Sequence *seq, int ofs)
}
GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) {
- unsigned int i;
+ uint i;
if (fcu->bezt) {
for (i = 0; i < fcu->totvert; i++) {
BezTriple *bezt = &fcu->bezt[i];
diff --git a/source/blender/sequencer/intern/disk_cache.c b/source/blender/sequencer/intern/disk_cache.c
index 37830205588..beb2c77b003 100644
--- a/source/blender/sequencer/intern/disk_cache.c
+++ b/source/blender/sequencer/intern/disk_cache.c
@@ -69,7 +69,7 @@
#define COLORSPACE_NAME_MAX 64 /* XXX: defined in IMB intern. */
typedef struct DiskCacheHeaderEntry {
- unsigned char encoding;
+ uchar encoding;
uint64_t frameno;
uint64_t size_compressed;
uint64_t size_raw;
@@ -182,7 +182,7 @@ static void seq_disk_cache_get_files(SeqDiskCache *disk_cache, char *path)
if (is_dir && !FILENAME_IS_CURRPAR(file)) {
char subpath[FILE_MAX];
BLI_strncpy(subpath, fl->path, sizeof(subpath));
- BLI_path_slash_ensure(subpath);
+ BLI_path_slash_ensure(subpath, sizeof(sizeof(subpath)));
seq_disk_cache_get_files(disk_cache, subpath);
}
@@ -291,8 +291,8 @@ static void seq_disk_cache_get_project_dir(SeqDiskCache *disk_cache, char *path,
/* Use suffix, so that the cache directory name does not conflict with the bmain's blend file. */
const char *suffix = "_seq_cache";
strncat(cache_dir, suffix, sizeof(cache_dir) - strlen(cache_dir) - 1);
- BLI_strncpy(path, seq_disk_cache_base_dir(), path_len);
- BLI_path_append(path, path_len, cache_dir);
+
+ BLI_path_join(path, path_len, seq_disk_cache_base_dir(), cache_dir);
}
static void seq_disk_cache_get_dir(
@@ -303,13 +303,13 @@ static void seq_disk_cache_get_dir(
char project_dir[FILE_MAX];
seq_disk_cache_get_project_dir(disk_cache, project_dir, sizeof(project_dir));
- sprintf(scene_name, "%s-%" PRId64, scene->id.name, disk_cache->timestamp);
+ BLI_snprintf(
+ scene_name, sizeof(scene_name), "%s-%" PRId64, scene->id.name, disk_cache->timestamp);
BLI_strncpy(seq_name, seq->name, sizeof(seq_name));
BLI_filename_make_safe(scene_name);
BLI_filename_make_safe(seq_name);
- BLI_strncpy(path, project_dir, path_len);
- BLI_path_append(path, path_len, scene_name);
- BLI_path_append(path, path_len, seq_name);
+
+ BLI_path_join(path, path_len, project_dir, scene_name, seq_name);
}
static void seq_disk_cache_get_file_path(SeqDiskCache *disk_cache,
@@ -320,14 +320,15 @@ static void seq_disk_cache_get_file_path(SeqDiskCache *disk_cache,
seq_disk_cache_get_dir(disk_cache, key->context.scene, key->seq, path, path_len);
int frameno = (int)key->frame_index / DCACHE_IMAGES_PER_FILE;
char cache_filename[FILE_MAXFILE];
- sprintf(cache_filename,
- DCACHE_FNAME_FORMAT,
- key->type,
- key->context.rectx,
- key->context.recty,
- key->context.preview_render_size,
- key->context.view_id,
- frameno);
+ BLI_snprintf(cache_filename,
+ sizeof(cache_filename),
+ DCACHE_FNAME_FORMAT,
+ key->type,
+ key->context.rectx,
+ key->context.recty,
+ key->context.preview_render_size,
+ key->context.view_id,
+ frameno);
BLI_path_append(path, path_len, cache_filename);
}
@@ -350,8 +351,7 @@ static void seq_disk_cache_handle_versioning(SeqDiskCache *disk_cache)
int version = 0;
seq_disk_cache_get_project_dir(disk_cache, filepath, sizeof(filepath));
- BLI_strncpy(path_version_file, filepath, sizeof(path_version_file));
- BLI_path_append(path_version_file, sizeof(path_version_file), "cache_version");
+ BLI_path_join(path_version_file, sizeof(path_version_file), filepath, "cache_version");
if (BLI_exists(filepath) && BLI_is_dir(filepath)) {
FILE *file = BLI_fopen(path_version_file, "r");
@@ -384,7 +384,7 @@ static void seq_disk_cache_delete_invalid_files(SeqDiskCache *disk_cache,
DiskCacheFile *next_file, *cache_file = disk_cache->files.first;
char cache_dir[FILE_MAX];
seq_disk_cache_get_dir(disk_cache, scene, seq, cache_dir, sizeof(cache_dir));
- BLI_path_slash_ensure(cache_dir);
+ BLI_path_slash_ensure(cache_dir, sizeof(cache_dir));
while (cache_file) {
next_file = cache_file->next;
diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c
index 25a6acb8975..3e3fe85ed39 100644
--- a/source/blender/sequencer/intern/effects.c
+++ b/source/blender/sequencer/intern/effects.c
@@ -71,22 +71,22 @@ static void slice_get_byte_buffers(const SeqRenderData *context,
const ImBuf *ibuf3,
const ImBuf *out,
int start_line,
- unsigned char **rect1,
- unsigned char **rect2,
- unsigned char **rect3,
- unsigned char **rect_out)
+ uchar **rect1,
+ uchar **rect2,
+ uchar **rect3,
+ uchar **rect_out)
{
int offset = 4 * start_line * context->rectx;
- *rect1 = (unsigned char *)ibuf1->rect + offset;
- *rect_out = (unsigned char *)out->rect + offset;
+ *rect1 = (uchar *)ibuf1->rect + offset;
+ *rect_out = (uchar *)out->rect + offset;
if (ibuf2) {
- *rect2 = (unsigned char *)ibuf2->rect + offset;
+ *rect2 = (uchar *)ibuf2->rect + offset;
}
if (ibuf3) {
- *rect3 = (unsigned char *)ibuf3->rect + offset;
+ *rect3 = (uchar *)ibuf3->rect + offset;
}
}
@@ -205,11 +205,11 @@ static void init_alpha_over_or_under(Sequence *seq)
}
static void do_alphaover_effect_byte(
- float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
+ float fac, int x, int y, uchar *rect1, uchar *rect2, uchar *out)
{
- unsigned char *cp1 = rect1;
- unsigned char *cp2 = rect2;
- unsigned char *rt = out;
+ uchar *cp1 = rect1;
+ uchar *cp2 = rect2;
+ uchar *rt = out;
for (int i = 0; i < y; i++) {
for (int j = 0; j < x; j++) {
@@ -222,10 +222,10 @@ static void do_alphaover_effect_byte(
float mfac = 1.0f - fac * rt1[3];
if (fac <= 0.0f) {
- *((unsigned int *)rt) = *((unsigned int *)cp2);
+ *((uint *)rt) = *((uint *)cp2);
}
else if (mfac <= 0.0f) {
- *((unsigned int *)rt) = *((unsigned int *)cp1);
+ *((uint *)rt) = *((uint *)cp1);
}
else {
tempc[0] = fac * rt1[0] + mfac * rt2[0];
@@ -294,7 +294,7 @@ static void do_alphaover_effect(const SeqRenderData *context,
do_alphaover_effect_float(fac, context->rectx, total_lines, rect1, rect2, rect_out);
}
else {
- unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
+ uchar *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
slice_get_byte_buffers(
context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
@@ -310,11 +310,11 @@ static void do_alphaover_effect(const SeqRenderData *context,
* \{ */
static void do_alphaunder_effect_byte(
- float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
+ float fac, int x, int y, uchar *rect1, uchar *rect2, uchar *out)
{
- unsigned char *cp1 = rect1;
- unsigned char *cp2 = rect2;
- unsigned char *rt = out;
+ uchar *cp1 = rect1;
+ uchar *cp2 = rect2;
+ uchar *rt = out;
for (int i = 0; i < y; i++) {
for (int j = 0; j < x; j++) {
@@ -328,16 +328,16 @@ static void do_alphaunder_effect_byte(
* 'skybuf' can be crossed in
*/
if (rt2[3] <= 0.0f && fac >= 1.0f) {
- *((unsigned int *)rt) = *((unsigned int *)cp1);
+ *((uint *)rt) = *((uint *)cp1);
}
else if (rt2[3] >= 1.0f) {
- *((unsigned int *)rt) = *((unsigned int *)cp2);
+ *((uint *)rt) = *((uint *)cp2);
}
else {
float temp_fac = (fac * (1.0f - rt2[3]));
if (fac <= 0) {
- *((unsigned int *)rt) = *((unsigned int *)cp2);
+ *((uint *)rt) = *((uint *)cp2);
}
else {
tempc[0] = (temp_fac * rt1[0] + rt2[0]);
@@ -415,7 +415,7 @@ static void do_alphaunder_effect(const SeqRenderData *context,
do_alphaunder_effect_float(fac, context->rectx, total_lines, rect1, rect2, rect_out);
}
else {
- unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
+ uchar *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
slice_get_byte_buffers(
context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
@@ -430,12 +430,11 @@ static void do_alphaunder_effect(const SeqRenderData *context,
/** \name Cross Effect
* \{ */
-static void do_cross_effect_byte(
- float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
+static void do_cross_effect_byte(float fac, int x, int y, uchar *rect1, uchar *rect2, uchar *out)
{
- unsigned char *rt1 = rect1;
- unsigned char *rt2 = rect2;
- unsigned char *rt = out;
+ uchar *rt1 = rect1;
+ uchar *rt2 = rect2;
+ uchar *rt = out;
int temp_fac = (int)(256.0f * fac);
int temp_mfac = 256 - temp_fac;
@@ -496,7 +495,7 @@ static void do_cross_effect(const SeqRenderData *context,
do_cross_effect_float(fac, context->rectx, total_lines, rect1, rect2, rect_out);
}
else {
- unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
+ uchar *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
slice_get_byte_buffers(
context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
@@ -512,8 +511,8 @@ static void do_cross_effect(const SeqRenderData *context,
* \{ */
/* copied code from initrender.c */
-static unsigned short gamtab[65536];
-static unsigned short igamtab1[256];
+static ushort gamtab[65536];
+static ushort igamtab1[256];
static bool gamma_tabs_init = false;
#define RE_GAMMA_TABLE_SIZE 400
@@ -666,11 +665,11 @@ static void free_gammacross(Sequence *UNUSED(seq), const bool UNUSED(do_id_user)
}
static void do_gammacross_effect_byte(
- float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
+ float fac, int x, int y, uchar *rect1, uchar *rect2, uchar *out)
{
- unsigned char *cp1 = rect1;
- unsigned char *cp2 = rect2;
- unsigned char *rt = out;
+ uchar *cp1 = rect1;
+ uchar *cp2 = rect2;
+ uchar *rt = out;
float mfac = 1.0f - fac;
@@ -705,10 +704,13 @@ static void do_gammacross_effect_float(
for (int i = 0; i < y; i++) {
for (int j = 0; j < x; j++) {
- *rt = gammaCorrect(mfac * invGammaCorrect(*rt1) + fac * invGammaCorrect(*rt2));
- rt1++;
- rt2++;
- rt++;
+ rt[0] = gammaCorrect(mfac * invGammaCorrect(rt1[0]) + fac * invGammaCorrect(rt2[0]));
+ rt[1] = gammaCorrect(mfac * invGammaCorrect(rt1[1]) + fac * invGammaCorrect(rt2[1]));
+ rt[2] = gammaCorrect(mfac * invGammaCorrect(rt1[2]) + fac * invGammaCorrect(rt2[2]));
+ rt[3] = gammaCorrect(mfac * invGammaCorrect(rt1[3]) + fac * invGammaCorrect(rt2[3]));
+ rt1 += 4;
+ rt2 += 4;
+ rt += 4;
}
}
}
@@ -744,7 +746,7 @@ static void do_gammacross_effect(const SeqRenderData *context,
do_gammacross_effect_float(fac, context->rectx, total_lines, rect1, rect2, rect_out);
}
else {
- unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
+ uchar *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
slice_get_byte_buffers(
context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
@@ -759,12 +761,11 @@ static void do_gammacross_effect(const SeqRenderData *context,
/** \name Color Add Effect
* \{ */
-static void do_add_effect_byte(
- float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
+static void do_add_effect_byte(float fac, int x, int y, uchar *rect1, uchar *rect2, uchar *out)
{
- unsigned char *cp1 = rect1;
- unsigned char *cp2 = rect2;
- unsigned char *rt = out;
+ uchar *cp1 = rect1;
+ uchar *cp2 = rect2;
+ uchar *rt = out;
int temp_fac = (int)(256.0f * fac);
@@ -824,7 +825,7 @@ static void do_add_effect(const SeqRenderData *context,
do_add_effect_float(fac, context->rectx, total_lines, rect1, rect2, rect_out);
}
else {
- unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
+ uchar *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
slice_get_byte_buffers(
context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
@@ -839,12 +840,11 @@ static void do_add_effect(const SeqRenderData *context,
/** \name Color Subtract Effect
* \{ */
-static void do_sub_effect_byte(
- float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
+static void do_sub_effect_byte(float fac, int x, int y, uchar *rect1, uchar *rect2, uchar *out)
{
- unsigned char *cp1 = rect1;
- unsigned char *cp2 = rect2;
- unsigned char *rt = out;
+ uchar *cp1 = rect1;
+ uchar *cp2 = rect2;
+ uchar *rt = out;
int temp_fac = (int)(256.0f * fac);
@@ -906,7 +906,7 @@ static void do_sub_effect(const SeqRenderData *context,
do_sub_effect_float(fac, context->rectx, total_lines, rect1, rect2, rect_out);
}
else {
- unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
+ uchar *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
slice_get_byte_buffers(
context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
@@ -925,17 +925,16 @@ static void do_sub_effect(const SeqRenderData *context,
#define XOFF 8
#define YOFF 8
-static void do_drop_effect_byte(
- float fac, int x, int y, unsigned char *rect2i, unsigned char *rect1i, unsigned char *outi)
+static void do_drop_effect_byte(float fac, int x, int y, uchar *rect2i, uchar *rect1i, uchar *outi)
{
const int xoff = min_ii(XOFF, x);
const int yoff = min_ii(YOFF, y);
int temp_fac = (int)(70.0f * fac);
- unsigned char *rt2 = rect2i + yoff * 4 * x;
- unsigned char *rt1 = rect1i;
- unsigned char *out = outi;
+ uchar *rt2 = rect2i + yoff * 4 * x;
+ uchar *rt1 = rect1i;
+ uchar *out = outi;
for (int i = 0; i < y - yoff; i++) {
memcpy(out, rt1, sizeof(*out) * xoff * 4);
rt1 += xoff * 4;
@@ -999,12 +998,11 @@ static void do_drop_effect_float(
/** \name Multiply Effect
* \{ */
-static void do_mul_effect_byte(
- float fac, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
+static void do_mul_effect_byte(float fac, int x, int y, uchar *rect1, uchar *rect2, uchar *out)
{
- unsigned char *rt1 = rect1;
- unsigned char *rt2 = rect2;
- unsigned char *rt = out;
+ uchar *rt1 = rect1;
+ uchar *rt2 = rect2;
+ uchar *rt = out;
int temp_fac = (int)(256.0f * fac);
@@ -1069,7 +1067,7 @@ static void do_mul_effect(const SeqRenderData *context,
do_mul_effect_float(fac, context->rectx, total_lines, rect1, rect2, rect_out);
}
else {
- unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
+ uchar *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
slice_get_byte_buffers(
context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
@@ -1084,27 +1082,25 @@ static void do_mul_effect(const SeqRenderData *context,
/** \name Blend Mode Effect
* \{ */
-typedef void (*IMB_blend_func_byte)(unsigned char *dst,
- const unsigned char *src1,
- const unsigned char *src2);
+typedef void (*IMB_blend_func_byte)(uchar *dst, const uchar *src1, const uchar *src2);
typedef void (*IMB_blend_func_float)(float *dst, const float *src1, const float *src2);
BLI_INLINE void apply_blend_function_byte(float fac,
int x,
int y,
- unsigned char *rect1,
- unsigned char *rect2,
- unsigned char *out,
+ uchar *rect1,
+ uchar *rect2,
+ uchar *out,
IMB_blend_func_byte blend_function)
{
- unsigned char *rt1 = rect1;
- unsigned char *rt2 = rect2;
- unsigned char *rt = out;
+ uchar *rt1 = rect1;
+ uchar *rt2 = rect2;
+ uchar *rt = out;
for (int i = 0; i < y; i++) {
for (int j = 0; j < x; j++) {
- unsigned int achannel = rt2[3];
- rt2[3] = (unsigned int)achannel * fac;
+ uint achannel = rt2[3];
+ rt2[3] = (uint)achannel * fac;
blend_function(rt, rt1, rt2);
rt2[3] = achannel;
rt[3] = rt1[3];
@@ -1213,13 +1209,8 @@ static void do_blend_effect_float(
}
}
-static void do_blend_effect_byte(float fac,
- int x,
- int y,
- unsigned char *rect1,
- unsigned char *rect2,
- int btype,
- unsigned char *out)
+static void do_blend_effect_byte(
+ float fac, int x, int y, uchar *rect1, uchar *rect2, int btype, uchar *out)
{
switch (btype) {
case SEQ_TYPE_ADD:
@@ -1309,7 +1300,7 @@ static void do_blend_mode_effect(const SeqRenderData *context,
fac, context->rectx, total_lines, rect1, rect2, seq->blend_mode, rect_out);
}
else {
- unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
+ uchar *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
slice_get_byte_buffers(
context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_blend_effect_byte(
@@ -1360,7 +1351,7 @@ static void do_colormix_effect(const SeqRenderData *context,
fac, context->rectx, total_lines, rect1, rect2, data->blend_effect, rect_out);
}
else {
- unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
+ uchar *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
slice_get_byte_buffers(
context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_blend_effect_byte(
@@ -1665,21 +1656,16 @@ static void copy_wipe_effect(Sequence *dst, Sequence *src, const int UNUSED(flag
dst->effectdata = MEM_dupallocN(src->effectdata);
}
-static void do_wipe_effect_byte(Sequence *seq,
- float fac,
- int x,
- int y,
- unsigned char *rect1,
- unsigned char *rect2,
- unsigned char *out)
+static void do_wipe_effect_byte(
+ Sequence *seq, float fac, int x, int y, uchar *rect1, uchar *rect2, uchar *out)
{
WipeZone wipezone;
WipeVars *wipe = (WipeVars *)seq->effectdata;
precalc_wipe_zone(&wipezone, wipe, x, y);
- unsigned char *cp1 = rect1;
- unsigned char *cp2 = rect2;
- unsigned char *rt = out;
+ uchar *cp1 = rect1;
+ uchar *cp2 = rect2;
+ uchar *rt = out;
for (int i = 0; i < y; i++) {
for (int j = 0; j < x; j++) {
@@ -1809,9 +1795,9 @@ static ImBuf *do_wipe_effect(const SeqRenderData *context,
fac,
context->rectx,
context->recty,
- (unsigned char *)ibuf1->rect,
- (unsigned char *)ibuf2->rect,
- (unsigned char *)out->rect);
+ (uchar *)ibuf1->rect,
+ (uchar *)ibuf2->rect,
+ (uchar *)out->rect);
}
return out;
@@ -2212,9 +2198,9 @@ static void do_glow_effect_byte(Sequence *seq,
float fac,
int x,
int y,
- unsigned char *rect1,
- unsigned char *UNUSED(rect2),
- unsigned char *out)
+ uchar *rect1,
+ uchar *UNUSED(rect2),
+ uchar *out)
{
float *outbuf, *inbuf;
GlowVars *glow = (GlowVars *)seq->effectdata;
@@ -2289,9 +2275,9 @@ static ImBuf *do_glow_effect(const SeqRenderData *context,
fac,
context->rectx,
context->recty,
- (unsigned char *)ibuf1->rect,
+ (uchar *)ibuf1->rect,
NULL,
- (unsigned char *)out->rect);
+ (uchar *)out->rect);
}
return out;
@@ -2353,13 +2339,13 @@ static ImBuf *do_solid_color(const SeqRenderData *context,
int y = out->y;
if (out->rect) {
- unsigned char color[4];
+ uchar color[4];
color[0] = cv->col[0] * 255;
color[1] = cv->col[1] * 255;
color[2] = cv->col[2] * 255;
color[3] = 255;
- unsigned char *rect = (unsigned char *)out->rect;
+ uchar *rect = (uchar *)out->rect;
for (int i = 0; i < y; i++) {
for (int j = 0; j < x; j++) {
@@ -2745,7 +2731,7 @@ static void do_overdrop_effect(const SeqRenderData *context,
do_alphaover_effect_float(fac, x, y, rect1, rect2, rect_out);
}
else {
- unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
+ uchar *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
slice_get_byte_buffers(
context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
@@ -2835,8 +2821,8 @@ static void do_gaussian_blur_effect_byte_x(Sequence *seq,
int y,
int frame_width,
int UNUSED(frame_height),
- const unsigned char *rect,
- unsigned char *out)
+ const uchar *rect,
+ uchar *out)
{
#define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
GaussianBlurVars *data = seq->effectdata;
@@ -2885,8 +2871,8 @@ static void do_gaussian_blur_effect_byte_y(Sequence *seq,
int y,
int UNUSED(frame_width),
int frame_height,
- const unsigned char *rect,
- unsigned char *out)
+ const uchar *rect,
+ uchar *out)
{
#define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
GaussianBlurVars *data = seq->effectdata;
@@ -3032,7 +3018,7 @@ static void do_gaussian_blur_effect_x_cb(const SeqRenderData *context,
rect_out);
}
else {
- unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
+ uchar *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
slice_get_byte_buffers(
context, ibuf, NULL, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
@@ -3043,7 +3029,7 @@ static void do_gaussian_blur_effect_x_cb(const SeqRenderData *context,
total_lines,
context->rectx,
context->recty,
- (unsigned char *)ibuf->rect,
+ (uchar *)ibuf->rect,
rect_out);
}
}
@@ -3071,7 +3057,7 @@ static void do_gaussian_blur_effect_y_cb(const SeqRenderData *context,
rect_out);
}
else {
- unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
+ uchar *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
slice_get_byte_buffers(
context, ibuf, NULL, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
@@ -3082,7 +3068,7 @@ static void do_gaussian_blur_effect_y_cb(const SeqRenderData *context,
total_lines,
context->rectx,
context->recty,
- (unsigned char *)ibuf->rect,
+ (uchar *)ibuf->rect,
rect_out);
}
}
@@ -3348,7 +3334,7 @@ static ImBuf *do_text_effect(const SeqRenderData *context,
}
/* set before return */
- BLF_size(font, proxy_size_comp * data->text_size, 72);
+ BLF_size(font, proxy_size_comp * data->text_size);
const int font_flags = BLF_WORD_WRAP | /* Always allow wrapping. */
((data->flag & SEQ_TEXT_BOLD) ? BLF_BOLD : 0) |
@@ -3358,8 +3344,7 @@ static ImBuf *do_text_effect(const SeqRenderData *context,
/* use max width to enable newlines only */
BLF_wordwrap(font, (data->wrap_width != 0.0f) ? data->wrap_width * width : -1);
- BLF_buffer(
- font, out->rect_float, (unsigned char *)out->rect, width, height, out->channels, display);
+ BLF_buffer(font, out->rect_float, (uchar *)out->rect, width, height, out->channels, display);
line_height = BLF_height_max(font);
diff --git a/source/blender/sequencer/intern/image_cache.c b/source/blender/sequencer/intern/image_cache.c
index 53f076c9681..21ce2cbdf9a 100644
--- a/source/blender/sequencer/intern/image_cache.c
+++ b/source/blender/sequencer/intern/image_cache.c
@@ -98,9 +98,9 @@ static bool seq_cmp_render_data(const SeqRenderData *a, const SeqRenderData *b)
(a->scene->r.views_format != b->scene->r.views_format) || (a->view_id != b->view_id));
}
-static unsigned int seq_hash_render_data(const SeqRenderData *a)
+static uint seq_hash_render_data(const SeqRenderData *a)
{
- unsigned int rval = a->rectx + a->recty;
+ uint rval = a->rectx + a->recty;
rval ^= a->preview_render_size;
rval ^= ((intptr_t)a->bmain) << 6;
@@ -112,12 +112,12 @@ static unsigned int seq_hash_render_data(const SeqRenderData *a)
return rval;
}
-static unsigned int seq_cache_hashhash(const void *key_)
+static uint seq_cache_hashhash(const void *key_)
{
const SeqCacheKey *key = key_;
- unsigned int rval = seq_hash_render_data(&key->context);
+ uint rval = seq_hash_render_data(&key->context);
- rval ^= *(const unsigned int *)&key->frame_index;
+ rval ^= *(const uint *)&key->frame_index;
rval += key->type;
rval ^= ((intptr_t)key->seq) << 6;
@@ -703,8 +703,7 @@ void seq_cache_thumbnail_cleanup(Scene *scene, rctf *view_area_safe)
const int frame_index = key->timeline_frame - SEQ_time_left_handle_frame_get(scene, key->seq);
const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(scene, key->seq);
- const int relative_base_frame = round_fl_to_int((frame_index / (float)frame_step)) *
- frame_step;
+ const int relative_base_frame = round_fl_to_int(frame_index / (float)frame_step) * frame_step;
const int nearest_guaranted_absolute_frame = relative_base_frame +
SEQ_time_left_handle_frame_get(scene, key->seq);
@@ -812,8 +811,11 @@ bool seq_cache_put_if_possible(
return false;
}
-void seq_cache_thumbnail_put(
- const SeqRenderData *context, Sequence *seq, float timeline_frame, ImBuf *i, rctf *view_area)
+void seq_cache_thumbnail_put(const SeqRenderData *context,
+ Sequence *seq,
+ float timeline_frame,
+ ImBuf *i,
+ const rctf *view_area)
{
Scene *scene = context->scene;
diff --git a/source/blender/sequencer/intern/image_cache.h b/source/blender/sequencer/intern/image_cache.h
index a7ae130dc41..7b7e020c926 100644
--- a/source/blender/sequencer/intern/image_cache.h
+++ b/source/blender/sequencer/intern/image_cache.h
@@ -48,7 +48,7 @@ void seq_cache_thumbnail_put(const struct SeqRenderData *context,
struct Sequence *seq,
float timeline_frame,
struct ImBuf *i,
- rctf *view_area);
+ const struct rctf *view_area);
bool seq_cache_put_if_possible(const struct SeqRenderData *context,
struct Sequence *seq,
float timeline_frame,
diff --git a/source/blender/sequencer/intern/modifier.c b/source/blender/sequencer/intern/modifier.c
index b17db8f762e..a962bcdbd06 100644
--- a/source/blender/sequencer/intern/modifier.c
+++ b/source/blender/sequencer/intern/modifier.c
@@ -44,9 +44,9 @@ static bool modifierTypesInit = false;
typedef void (*modifier_apply_threaded_cb)(int width,
int height,
- unsigned char *rect,
+ uchar *rect,
float *rect_float,
- unsigned char *mask_rect,
+ uchar *mask_rect,
const float *mask_rect_float,
void *data_v);
@@ -61,7 +61,7 @@ typedef struct ModifierInitData {
typedef struct ModifierThread {
int width, height;
- unsigned char *rect, *mask_rect;
+ uchar *rect, *mask_rect;
float *rect_float, *mask_rect_float;
void *user_data;
@@ -140,7 +140,7 @@ static void modifier_init_handle(void *handle_v, int start_line, int tot_line, v
handle->user_data = init_data->user_data;
if (ibuf->rect) {
- handle->rect = (unsigned char *)ibuf->rect + offset;
+ handle->rect = (uchar *)ibuf->rect + offset;
}
if (ibuf->rect_float) {
@@ -149,7 +149,7 @@ static void modifier_init_handle(void *handle_v, int start_line, int tot_line, v
if (mask) {
if (mask->rect) {
- handle->mask_rect = (unsigned char *)mask->rect + offset;
+ handle->mask_rect = (uchar *)mask->rect + offset;
}
if (mask->rect_float) {
@@ -345,17 +345,13 @@ static void make_cb_table_float_sop(
}
}
-static void color_balance_byte_byte(StripColorBalance *cb_,
- unsigned char *rect,
- unsigned char *mask_rect,
- int width,
- int height,
- float mul)
+static void color_balance_byte_byte(
+ StripColorBalance *cb_, uchar *rect, uchar *mask_rect, int width, int height, float mul)
{
- // unsigned char cb_tab[3][256];
- unsigned char *cp = rect;
- unsigned char *e = cp + width * 4 * height;
- unsigned char *m = mask_rect;
+ // uchar cb_tab[3][256];
+ uchar *cp = rect;
+ uchar *e = cp + width * 4 * height;
+ uchar *m = mask_rect;
StripColorBalance cb = calc_cb(cb_);
@@ -394,18 +390,18 @@ static void color_balance_byte_byte(StripColorBalance *cb_,
}
static void color_balance_byte_float(StripColorBalance *cb_,
- unsigned char *rect,
+ uchar *rect,
float *rect_float,
- unsigned char *mask_rect,
+ uchar *mask_rect,
int width,
int height,
float mul)
{
float cb_tab[4][256];
int c, i;
- unsigned char *p = rect;
- unsigned char *e = p + width * 4 * height;
- unsigned char *m = mask_rect;
+ uchar *p = rect;
+ uchar *e = p + width * 4 * height;
+ uchar *m = mask_rect;
float *o;
StripColorBalance cb;
@@ -501,7 +497,7 @@ typedef struct ColorBalanceThread {
int width, height;
- unsigned char *rect, *mask_rect;
+ uchar *rect, *mask_rect;
float *rect_float, *mask_rect_float;
bool make_float;
@@ -528,7 +524,7 @@ static void color_balance_init_handle(void *handle_v,
handle->make_float = init_data->make_float;
if (ibuf->rect) {
- handle->rect = (unsigned char *)ibuf->rect + offset;
+ handle->rect = (uchar *)ibuf->rect + offset;
}
if (ibuf->rect_float) {
@@ -537,7 +533,7 @@ static void color_balance_init_handle(void *handle_v,
if (mask) {
if (mask->rect) {
- handle->mask_rect = (unsigned char *)mask->rect + offset;
+ handle->mask_rect = (uchar *)mask->rect + offset;
}
if (mask->rect_float) {
@@ -555,8 +551,8 @@ static void *color_balance_do_thread(void *thread_data_v)
ColorBalanceThread *thread_data = (ColorBalanceThread *)thread_data_v;
StripColorBalance *cb = thread_data->cb;
int width = thread_data->width, height = thread_data->height;
- unsigned char *rect = thread_data->rect;
- unsigned char *mask_rect = thread_data->mask_rect;
+ uchar *rect = thread_data->rect;
+ uchar *mask_rect = thread_data->mask_rect;
float *rect_float = thread_data->rect_float;
float *mask_rect_float = thread_data->mask_rect_float;
float mul = thread_data->mul;
@@ -657,9 +653,9 @@ typedef struct WhiteBalanceThreadData {
static void whiteBalance_apply_threaded(int width,
int height,
- unsigned char *rect,
+ uchar *rect,
float *rect_float,
- unsigned char *mask_rect,
+ uchar *mask_rect,
const float *mask_rect_float,
void *data_v)
{
@@ -765,9 +761,9 @@ static void curves_copy_data(SequenceModifierData *target, SequenceModifierData
static void curves_apply_threaded(int width,
int height,
- unsigned char *rect,
+ uchar *rect,
float *rect_float,
- unsigned char *mask_rect,
+ uchar *mask_rect,
const float *mask_rect_float,
void *data_v)
{
@@ -798,7 +794,7 @@ static void curves_apply_threaded(int width,
}
}
if (rect) {
- unsigned char *pixel = rect + pixel_index;
+ uchar *pixel = rect + pixel_index;
float result[3], tempc[4];
straight_uchar_to_premul_float(tempc, pixel);
@@ -895,9 +891,9 @@ static void hue_correct_copy_data(SequenceModifierData *target, SequenceModifier
static void hue_correct_apply_threaded(int width,
int height,
- unsigned char *rect,
+ uchar *rect,
float *rect_float,
- unsigned char *mask_rect,
+ uchar *mask_rect,
const float *mask_rect_float,
void *data_v)
{
@@ -990,9 +986,9 @@ typedef struct BrightContrastThreadData {
static void brightcontrast_apply_threaded(int width,
int height,
- unsigned char *rect,
+ uchar *rect,
float *rect_float,
- unsigned char *mask_rect,
+ uchar *mask_rect,
const float *mask_rect_float,
void *data_v)
{
@@ -1008,7 +1004,7 @@ static void brightcontrast_apply_threaded(int width,
/*
* The algorithm is by Werner D. Streidt
* (http://visca.com/ffactory/archives/5-99/msg00021.html)
- * Extracted of OpenCV demhist.c
+ * Extracted of OpenCV `demhist.c`.
*/
if (contrast > 0) {
a = 1.0f - delta * 2.0f;
@@ -1026,14 +1022,14 @@ static void brightcontrast_apply_threaded(int width,
int pixel_index = (y * width + x) * 4;
if (rect) {
- unsigned char *pixel = rect + pixel_index;
+ uchar *pixel = rect + pixel_index;
for (c = 0; c < 3; c++) {
i = (float)pixel[c] / 255.0f;
v = a * i + b;
if (mask_rect) {
- unsigned char *m = mask_rect + pixel_index;
+ uchar *m = mask_rect + pixel_index;
float t = (float)m[c] / 255.0f;
v = (float)pixel[c] / 255.0f * (1.0f - t) + v * t;
@@ -1092,9 +1088,9 @@ static SequenceModifierTypeInfo seqModifier_BrightContrast = {
static void maskmodifier_apply_threaded(int width,
int height,
- unsigned char *rect,
+ uchar *rect,
float *rect_float,
- unsigned char *mask_rect,
+ uchar *mask_rect,
const float *mask_rect_float,
void *UNUSED(data_v))
{
@@ -1113,9 +1109,9 @@ static void maskmodifier_apply_threaded(int width,
int pixel_index = (y * width + x) * 4;
if (rect) {
- unsigned char *pixel = rect + pixel_index;
- unsigned char *mask_pixel = mask_rect + pixel_index;
- unsigned char mask = min_iii(mask_pixel[0], mask_pixel[1], mask_pixel[2]);
+ uchar *pixel = rect + pixel_index;
+ uchar *mask_pixel = mask_rect + pixel_index;
+ uchar mask = min_iii(mask_pixel[0], mask_pixel[1], mask_pixel[2]);
/* byte buffer is straight, so only affect on alpha itself,
* this is the only way to alpha-over byte strip after
@@ -1177,7 +1173,7 @@ typedef struct AvgLogLum {
static void tonemapmodifier_init_data(SequenceModifierData *smd)
{
SequencerTonemapModifierData *tmmd = (SequencerTonemapModifierData *)smd;
- /* Same as tonemap compositor node. */
+ /* Same as tone-map compositor node. */
tmmd->type = SEQ_TONEMAP_RD_PHOTORECEPTOR;
tmmd->key = 0.18f;
tmmd->offset = 1.0f;
@@ -1190,9 +1186,9 @@ static void tonemapmodifier_init_data(SequenceModifierData *smd)
static void tonemapmodifier_apply_threaded_simple(int width,
int height,
- unsigned char *rect,
+ uchar *rect,
float *rect_float,
- unsigned char *mask_rect,
+ uchar *mask_rect,
const float *mask_rect_float,
void *data_v)
{
@@ -1249,9 +1245,9 @@ static void tonemapmodifier_apply_threaded_simple(int width,
static void tonemapmodifier_apply_threaded_photoreceptor(int width,
int height,
- unsigned char *rect,
+ uchar *rect,
float *rect_float,
- unsigned char *mask_rect,
+ uchar *mask_rect,
const float *mask_rect_float,
void *data_v)
{
@@ -1319,7 +1315,7 @@ static void tonemapmodifier_apply(struct SequenceModifierData *smd, ImBuf *ibuf,
float lsum = 0.0f;
int p = ibuf->x * ibuf->y;
float *fp = ibuf->rect_float;
- unsigned char *cp = (unsigned char *)ibuf->rect;
+ uchar *cp = (uchar *)ibuf->rect;
float avl, maxl = -FLT_MAX, minl = FLT_MAX;
const float sc = 1.0f / p;
float Lav = 0.0f;
diff --git a/source/blender/sequencer/intern/proxy.c b/source/blender/sequencer/intern/proxy.c
index 4220efab8bf..eaea310f423 100644
--- a/source/blender/sequencer/intern/proxy.c
+++ b/source/blender/sequencer/intern/proxy.c
@@ -106,7 +106,7 @@ bool seq_proxy_get_custom_file_fname(Sequence *seq, char *name, const int view_i
return false;
}
- BLI_join_dirfile(fname, PROXY_MAXFILE, proxy->dir, proxy->file);
+ BLI_path_join(fname, PROXY_MAXFILE, proxy->dir, proxy->file);
BLI_path_abs(fname, BKE_main_blendfile_path_from_global());
if (view_id > 0) {
@@ -325,7 +325,7 @@ static bool seq_proxy_multiview_context_invalid(Sequence *seq, Scene *scene, con
if (view_id == 0) {
char path[FILE_MAX];
- BLI_join_dirfile(path, sizeof(path), seq->strip->dir, seq->strip->stripdata->name);
+ BLI_path_join(path, sizeof(path), seq->strip->dir, seq->strip->stripdata->name);
BLI_path_abs(path, BKE_main_blendfile_path_from_global());
BKE_scene_multiview_view_prefix_get(scene, path, prefix, &ext);
}
@@ -479,10 +479,7 @@ bool SEQ_proxy_rebuild_context(Main *bmain,
return true;
}
-void SEQ_proxy_rebuild(SeqIndexBuildContext *context,
- short *stop,
- short *do_update,
- float *progress)
+void SEQ_proxy_rebuild(SeqIndexBuildContext *context, bool *stop, bool *do_update, float *progress)
{
const bool overwrite = context->overwrite;
SeqRenderData render_context;
@@ -585,8 +582,7 @@ void seq_proxy_index_dir_set(struct anim *anim, const char *base_dir)
char fname[FILE_MAXFILE];
IMB_anim_get_fname(anim, fname, FILE_MAXFILE);
- BLI_strncpy(dir, base_dir, sizeof(dir));
- BLI_path_append(dir, sizeof(dir), fname);
+ BLI_path_join(dir, sizeof(dir), base_dir, fname);
IMB_anim_set_index_dir(anim, dir);
}
diff --git a/source/blender/sequencer/intern/proxy_job.c b/source/blender/sequencer/intern/proxy_job.c
index 8520c06f9a2..d7dfe0130d8 100644
--- a/source/blender/sequencer/intern/proxy_job.c
+++ b/source/blender/sequencer/intern/proxy_job.c
@@ -41,7 +41,7 @@ static void proxy_freejob(void *pjv)
}
/* Only this runs inside thread. */
-static void proxy_startjob(void *pjv, short *stop, short *do_update, float *progress)
+static void proxy_startjob(void *pjv, bool *stop, bool *do_update, float *progress)
{
ProxyJob *pj = pjv;
LinkData *link;
@@ -52,7 +52,7 @@ static void proxy_startjob(void *pjv, short *stop, short *do_update, float *prog
SEQ_proxy_rebuild(context, stop, do_update, progress);
if (*stop) {
- pj->stop = 1;
+ pj->stop = true;
fprintf(stderr, "Canceling proxy rebuild on users request...\n");
break;
}
diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c
index fd3b6103b94..5c6a59a5943 100644
--- a/source/blender/sequencer/intern/render.c
+++ b/source/blender/sequencer/intern/render.c
@@ -123,12 +123,8 @@ void seq_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, bool make_float)
* However, this might also have negative effect by adding weird
* artifacts which will then not happen in final render.
*/
- IMB_colormanagement_transform_byte_threaded((unsigned char *)ibuf->rect,
- ibuf->x,
- ibuf->y,
- ibuf->channels,
- from_colorspace,
- to_colorspace);
+ IMB_colormanagement_transform_byte_threaded(
+ (uchar *)ibuf->rect, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace);
}
else {
/* We perform conversion to a float buffer so we don't worry about
@@ -136,7 +132,7 @@ void seq_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, bool make_float)
*/
imb_addrectfloatImBuf(ibuf, 4);
IMB_colormanagement_transform_from_byte_threaded(ibuf->rect_float,
- (unsigned char *)ibuf->rect,
+ (uchar *)ibuf->rect,
ibuf->x,
ibuf->y,
ibuf->channels,
@@ -942,7 +938,7 @@ static ImBuf *seq_render_image_strip(const SeqRenderData *context,
return NULL;
}
- BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name);
+ BLI_path_join(name, sizeof(name), seq->strip->dir, s_elem->name);
BLI_path_abs(name, BKE_main_blendfile_path_from_global());
/* Try to get a proxy image. */
@@ -1030,6 +1026,15 @@ static ImBuf *seq_render_movie_strip_custom_file_proxy(const SeqRenderData *cont
return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE);
}
+static IMB_Timecode_Type seq_render_movie_strip_timecode_get(Sequence *seq)
+{
+ bool use_timecodes = (seq->flag & SEQ_USE_PROXY) != 0;
+ if (!use_timecodes) {
+ return IMB_TC_NONE;
+ }
+ return seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_NONE;
+}
+
/**
* Render individual view for multi-view or single (default view) for mono-view.
*/
@@ -1053,7 +1058,7 @@ static ImBuf *seq_render_movie_strip_view(const SeqRenderData *context,
else {
ibuf = IMB_anim_absolute(sanim->anim,
frame_index + seq->anim_startofs,
- seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN,
+ seq_render_movie_strip_timecode_get(seq),
psize);
}
@@ -1066,7 +1071,7 @@ static ImBuf *seq_render_movie_strip_view(const SeqRenderData *context,
if (ibuf == NULL) {
ibuf = IMB_anim_absolute(sanim->anim,
frame_index + seq->anim_startofs,
- seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN,
+ seq_render_movie_strip_timecode_get(seq),
IMB_PROXY_NONE);
}
if (ibuf == NULL) {
@@ -1298,15 +1303,15 @@ ImBuf *seq_render_mask(const SeqRenderData *context,
else {
/* pixels */
const float *fp_src;
- unsigned char *ub_dst;
+ uchar *ub_dst;
ibuf = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect);
fp_src = maskbuf;
- ub_dst = (unsigned char *)ibuf->rect;
+ ub_dst = (uchar *)ibuf->rect;
i = context->rectx * context->recty;
while (--i) {
- ub_dst[0] = ub_dst[1] = ub_dst[2] = (unsigned char)(*fp_src * 255.0f); /* already clamped */
+ ub_dst[0] = ub_dst[1] = ub_dst[2] = (uchar)(*fp_src * 255.0f); /* already clamped */
ub_dst[3] = 255;
fp_src += 1;
@@ -1352,7 +1357,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context,
* find render).
* However, when called from within the UI (image preview in sequencer)
* we do want to use scene Render, that way the render result is defined
- * for display in render/imagewindow
+ * for display in render/image-window
*
* Hmm, don't see, why we can't do that all the time,
* and since G.is_rendering is uhm, gone... (Peter)
@@ -1451,7 +1456,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context,
BKE_render_resolution(&scene->r, false, &width, &height);
const char *viewname = BKE_scene_multiview_render_view_name_get(&scene->r, context->view_id);
- unsigned int draw_flags = V3D_OFSDRAW_NONE;
+ uint draw_flags = V3D_OFSDRAW_NONE;
draw_flags |= (use_gpencil) ? V3D_OFSDRAW_SHOW_ANNOTATION : 0;
draw_flags |= (context->scene->r.seq_flag & R_SEQ_OVERRIDE_SCENE_SETTINGS) ?
V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS :
@@ -1506,8 +1511,16 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context,
re = RE_NewSceneRender(scene);
}
- RE_RenderFrame(
- re, context->bmain, scene, have_comp ? NULL : view_layer, camera, frame, 0.0f, false);
+ const float subframe = frame - floorf(frame);
+
+ RE_RenderFrame(re,
+ context->bmain,
+ scene,
+ have_comp ? NULL : view_layer,
+ camera,
+ floorf(frame),
+ subframe,
+ false);
/* restore previous state after it was toggled on & off by RE_RenderFrame */
G.is_rendering = is_rendering;
@@ -1997,7 +2010,7 @@ ImBuf *SEQ_render_give_ibuf_direct(const SeqRenderData *context,
float SEQ_render_thumbnail_first_frame_get(const Scene *scene,
Sequence *seq,
float frame_step,
- rctf *view_area)
+ const rctf *view_area)
{
int first_drawable_frame = max_iii(
SEQ_time_left_handle_frame_get(scene, seq), seq->start, view_area->xmin);
@@ -2089,8 +2102,8 @@ void SEQ_render_thumbnails(const SeqRenderData *context,
Sequence *seq,
Sequence *seq_orig,
float frame_step,
- rctf *view_area,
- const short *stop)
+ const rctf *view_area,
+ const bool *stop)
{
SeqRenderState state;
seq_render_state_init(&state);
@@ -2099,7 +2112,7 @@ void SEQ_render_thumbnails(const SeqRenderData *context,
/* Adding the hold offset value (seq->anim_startofs) to the start frame. Position of image not
* affected, but frame loaded affected. */
float upper_thumb_bound = SEQ_time_has_right_still_frames(scene, seq) ?
- (seq->start + seq->len) :
+ SEQ_time_content_end_frame_get(scene, seq) :
SEQ_time_right_handle_frame_get(scene, seq);
upper_thumb_bound = (upper_thumb_bound > view_area->xmax) ? view_area->xmax + frame_step :
upper_thumb_bound;
@@ -2133,9 +2146,10 @@ void SEQ_render_thumbnails(const SeqRenderData *context,
int SEQ_render_thumbnails_guaranteed_set_frame_step_get(const Scene *scene, const Sequence *seq)
{
- const int content_start = max_ii(SEQ_time_left_handle_frame_get(scene, seq), seq->start);
+ const int content_start = max_ii(SEQ_time_left_handle_frame_get(scene, seq),
+ SEQ_time_start_frame_get(seq));
const int content_end = min_ii(SEQ_time_right_handle_frame_get(scene, seq),
- seq->start + seq->len);
+ SEQ_time_content_end_frame_get(scene, seq));
const int content_len = content_end - content_start;
/* Arbitrary, but due to performance reasons should be as low as possible. */
@@ -2149,8 +2163,8 @@ int SEQ_render_thumbnails_guaranteed_set_frame_step_get(const Scene *scene, cons
void SEQ_render_thumbnails_base_set(const SeqRenderData *context,
Sequence *seq,
Sequence *seq_orig,
- rctf *view_area,
- const short *stop)
+ const rctf *view_area,
+ const bool *stop)
{
SeqRenderState state;
seq_render_state_init(&state);
diff --git a/source/blender/sequencer/intern/sequencer.c b/source/blender/sequencer/intern/sequencer.c
index 4548975574d..c6f4d47ac75 100644
--- a/source/blender/sequencer/intern/sequencer.c
+++ b/source/blender/sequencer/intern/sequencer.c
@@ -171,7 +171,7 @@ static void seq_sequence_free_ex(Scene *scene,
}
if (seq->sound && do_id_user) {
- id_us_min(((ID *)seq->sound));
+ id_us_min((ID *)seq->sound);
}
if (seq->stereo3d_format) {
diff --git a/source/blender/sequencer/intern/sound.c b/source/blender/sequencer/intern/sound.c
index c4992848cb5..69ccbdcb54e 100644
--- a/source/blender/sequencer/intern/sound.c
+++ b/source/blender/sequencer/intern/sound.c
@@ -26,7 +26,8 @@
#include "sequencer.h"
#include "strip_time.h"
-/* Unlike _update_sound_ funcs, these ones take info from audaspace to update sequence length! */
+/* Unlike _update_sound_ functions,
+ * these ones take info from audaspace to update sequence length! */
#ifdef WITH_AUDASPACE
static bool sequencer_refresh_sound_length_recursive(Main *bmain, Scene *scene, ListBase *seqbase)
{
diff --git a/source/blender/sequencer/intern/strip_add.c b/source/blender/sequencer/intern/strip_add.c
index 753a6ee39e0..d98a00aa9a5 100644
--- a/source/blender/sequencer/intern/strip_add.c
+++ b/source/blender/sequencer/intern/strip_add.c
@@ -204,7 +204,7 @@ void SEQ_add_image_init_alpha_mode(Sequence *seq)
char name[FILE_MAX];
ImBuf *ibuf;
- BLI_join_dirfile(name, sizeof(name), seq->strip->dir, seq->strip->stripdata->name);
+ BLI_path_join(name, sizeof(name), seq->strip->dir, seq->strip->stripdata->name);
BLI_path_abs(name, BKE_main_blendfile_path_from_global());
/* Initialize input color space. */
@@ -545,7 +545,7 @@ void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const boo
const bool is_multiview = (seq->flag & SEQ_USE_VIEWS) != 0 &&
(scene->r.scemode & R_MULTIVIEW) != 0;
- BLI_join_dirfile(path, sizeof(path), seq->strip->dir, seq->strip->stripdata->name);
+ BLI_path_join(path, sizeof(path), seq->strip->dir, seq->strip->stripdata->name);
BLI_path_abs(path, BKE_main_blendfile_path_from_global());
SEQ_relations_sequence_free_anim(seq);
@@ -668,7 +668,6 @@ void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const boo
if (lock_range) {
SEQ_time_left_handle_frame_set(scene, seq, prev_startdisp);
SEQ_time_right_handle_frame_set(scene, seq, prev_enddisp);
- SEQ_transform_fix_single_image_seq_offsets(scene, seq);
}
SEQ_relations_invalidate_cache_raw(scene, seq);
diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c
index c35138b280a..69e43f3679c 100644
--- a/source/blender/sequencer/intern/strip_edit.c
+++ b/source/blender/sequencer/intern/strip_edit.c
@@ -258,49 +258,50 @@ bool SEQ_edit_move_strip_to_meta(Scene *scene,
return true;
}
-static void seq_split_set_left_hold_offset(Scene *scene, Sequence *seq, int timeline_frame)
+static void seq_split_set_right_hold_offset(Scene *scene, Sequence *seq, int timeline_frame)
{
- /* Adjust within range of extended stillframes before strip. */
- if (timeline_frame < seq->start) {
- seq->start = timeline_frame - 1;
- seq->anim_endofs += SEQ_time_strip_length_get(scene, seq) - 1;
- seq->startstill = timeline_frame - seq->startdisp - 1;
- seq->endstill = 0;
+ const float content_start = SEQ_time_start_frame_get(seq);
+ const float content_end = SEQ_time_content_end_frame_get(scene, seq);
+
+ /* Adjust within range of extended still-frames before strip. */
+ if (timeline_frame < content_start) {
+ const float offset = content_start + 1 - timeline_frame;
+ seq->start -= offset;
+ seq->startofs += offset;
+ SEQ_time_right_handle_frame_set(scene, seq, timeline_frame);
}
/* Adjust within range of strip contents. */
- else if ((timeline_frame >= seq->start) &&
- (timeline_frame <= (seq->start + SEQ_time_strip_length_get(scene, seq)))) {
+ else if ((timeline_frame >= content_start) && (timeline_frame <= content_end)) {
seq->endofs = 0;
- seq->endstill = 0;
- seq->anim_endofs += (seq->start + SEQ_time_strip_length_get(scene, seq)) - timeline_frame;
+ seq->anim_endofs += (content_end - timeline_frame) * seq->speed_factor;
}
- /* Adjust within range of extended stillframes after strip. */
- else if ((seq->start + SEQ_time_strip_length_get(scene, seq)) < timeline_frame) {
- seq->endstill = timeline_frame - seq->start - SEQ_time_strip_length_get(scene, seq);
+ /* Adjust within range of extended still-frames after strip. */
+ else if (timeline_frame > content_end) {
+ SEQ_time_right_handle_frame_set(scene, seq, timeline_frame);
}
}
-static void seq_split_set_right_hold_offset(Scene *scene, Sequence *seq, int timeline_frame)
+static void seq_split_set_left_hold_offset(Scene *scene, Sequence *seq, int timeline_frame)
{
- /* Adjust within range of extended stillframes before strip. */
- if (timeline_frame < seq->start) {
- seq->startstill = seq->start - timeline_frame;
+ const float content_start = SEQ_time_start_frame_get(seq);
+ const float content_end = SEQ_time_content_end_frame_get(scene, seq);
+
+ /* Adjust within range of extended still-frames before strip. */
+ if (timeline_frame < content_start) {
+ SEQ_time_left_handle_frame_set(scene, seq, timeline_frame);
}
/* Adjust within range of strip contents. */
- else if ((timeline_frame >= seq->start) &&
- (timeline_frame <= (seq->start + SEQ_time_strip_length_get(scene, seq)))) {
- seq->anim_startofs += timeline_frame - seq->start;
+ else if ((timeline_frame >= content_start) && (timeline_frame <= content_end)) {
+ seq->anim_startofs += (timeline_frame - content_start) * seq->speed_factor;
seq->start = timeline_frame;
- seq->startstill = 0;
seq->startofs = 0;
}
- /* Adjust within range of extended stillframes after strip. */
- else if ((seq->start + SEQ_time_strip_length_get(scene, seq)) < timeline_frame) {
- seq->start = timeline_frame;
- seq->startofs = 0;
- seq->anim_startofs += SEQ_time_strip_length_get(scene, seq) - 1;
- seq->endstill = seq->enddisp - timeline_frame - 1;
- seq->startstill = 0;
+ /* Adjust within range of extended still-frames after strip. */
+ else if (timeline_frame > content_end) {
+ const float offset = timeline_frame - content_end + 1;
+ seq->start += offset;
+ seq->endofs += offset;
+ SEQ_time_left_handle_frame_set(scene, seq, timeline_frame);
}
}
diff --git a/source/blender/sequencer/intern/strip_time.c b/source/blender/sequencer/intern/strip_time.c
index 5d8266dbc6e..0b480b22e91 100644
--- a/source/blender/sequencer/intern/strip_time.c
+++ b/source/blender/sequencer/intern/strip_time.c
@@ -53,7 +53,7 @@ float seq_give_frame_index(const Scene *scene, Sequence *seq, float timeline_fra
{
float frame_index;
float sta = SEQ_time_start_frame_get(seq);
- float end = SEQ_time_start_frame_get(seq) + SEQ_time_strip_length_get(scene, seq) - 1;
+ float end = SEQ_time_content_end_frame_get(scene, seq) - 1;
if (seq->type & SEQ_TYPE_EFFECT) {
end = SEQ_time_right_handle_frame_get(scene, seq);
@@ -169,11 +169,16 @@ void SEQ_time_update_meta_strip_range(const Scene *scene, Sequence *seq_meta)
seq_meta->len -= seq_meta->anim_startofs;
seq_meta->len -= seq_meta->anim_endofs;
- seq_update_sound_bounds_recursive(scene, seq_meta);
+ /* Functions `SEQ_time_*_handle_frame_set()` can not be used here, because they are clamped, so
+ * change must be done at once. */
+ seq_meta->startofs = strip_start - seq_meta->start;
+ seq_meta->startdisp = strip_start; /* Only to make files usable in older versions. */
+ seq_meta->endofs = seq_meta->start + SEQ_time_strip_length_get(scene, seq_meta) - strip_end;
+ seq_meta->enddisp = strip_end; /* Only to make files usable in older versions. */
- /* Prevent meta-strip to move in timeline. */
- SEQ_time_left_handle_frame_set(scene, seq_meta, strip_start);
- SEQ_time_right_handle_frame_set(scene, seq_meta, strip_end);
+ seq_update_sound_bounds_recursive(scene, seq_meta);
+ SEQ_time_update_meta_strip_range(scene, seq_sequence_lookup_meta_by_seq(scene, seq_meta));
+ seq_time_update_effects_strip_range(scene, seq_sequence_lookup_effects_by_seq(scene, seq_meta));
}
void seq_time_effect_range_set(const Scene *scene, Sequence *seq)
@@ -465,8 +470,7 @@ bool SEQ_time_has_left_still_frames(const Scene *scene, const Sequence *seq)
bool SEQ_time_has_right_still_frames(const Scene *scene, const Sequence *seq)
{
- return SEQ_time_right_handle_frame_get(scene, seq) >
- SEQ_time_start_frame_get(seq) + SEQ_time_strip_length_get(scene, seq);
+ return SEQ_time_right_handle_frame_get(scene, seq) > SEQ_time_content_end_frame_get(scene, seq);
}
bool SEQ_time_has_still_frames(const Scene *scene, const Sequence *seq)
@@ -474,8 +478,6 @@ bool SEQ_time_has_still_frames(const Scene *scene, const Sequence *seq)
return SEQ_time_has_right_still_frames(scene, seq) || SEQ_time_has_left_still_frames(scene, seq);
}
-/* Length of strip content in frames. This is number of original frames adjusted by playback rate
- * factor */
int SEQ_time_strip_length_get(const Scene *scene, const Sequence *seq)
{
if (seq->type == SEQ_TYPE_SOUND_RAM) {
@@ -485,7 +487,6 @@ int SEQ_time_strip_length_get(const Scene *scene, const Sequence *seq)
return seq->len / seq_time_playback_rate_factor_get(scene, seq);
}
-/* Return timeline frame, where strip content starts. */
float SEQ_time_start_frame_get(const Sequence *seq)
{
return seq->start;
@@ -498,6 +499,11 @@ void SEQ_time_start_frame_set(const Scene *scene, Sequence *seq, int timeline_fr
seq_time_update_effects_strip_range(scene, seq_sequence_lookup_effects_by_seq(scene, seq));
}
+float SEQ_time_content_end_frame_get(const Scene *scene, const Sequence *seq)
+{
+ return SEQ_time_start_frame_get(seq) + SEQ_time_strip_length_get(scene, seq);
+}
+
int SEQ_time_left_handle_frame_get(const Scene *UNUSED(scene), const Sequence *seq)
{
if (seq->seq1 || seq->seq2) {
@@ -513,35 +519,56 @@ int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
return seq->enddisp;
}
- return seq->start + SEQ_time_strip_length_get(scene, seq) - seq->endofs;
+ return SEQ_time_content_end_frame_get(scene, seq) - seq->endofs;
}
-void SEQ_time_left_handle_frame_set(const Scene *scene, Sequence *seq, int val)
+void SEQ_time_left_handle_frame_set(const Scene *scene, Sequence *seq, int timeline_frame)
{
const float right_handle_orig_frame = SEQ_time_right_handle_frame_get(scene, seq);
- if (val >= right_handle_orig_frame) {
- val = right_handle_orig_frame - 1;
+ if (timeline_frame >= right_handle_orig_frame) {
+ timeline_frame = right_handle_orig_frame - 1;
+ }
+
+ float offset = timeline_frame - SEQ_time_start_frame_get(seq);
+
+ if (SEQ_transform_single_image_check(seq)) {
+ /* This strip has only 1 frame of content, that is always stretched to whole strip length.
+ * Therefore, strip start should be moved instead of adjusting offset. */
+ SEQ_time_start_frame_set(scene, seq, timeline_frame);
+ seq->endofs += offset;
+ }
+ else {
+ seq->startofs = offset;
}
- seq->startofs = val - seq->start;
- seq->startdisp = val; /* Only to make files usable in older versions. */
+ seq->startdisp = timeline_frame; /* Only to make files usable in older versions. */
SEQ_time_update_meta_strip_range(scene, seq_sequence_lookup_meta_by_seq(scene, seq));
seq_time_update_effects_strip_range(scene, seq_sequence_lookup_effects_by_seq(scene, seq));
}
-void SEQ_time_right_handle_frame_set(const Scene *scene, Sequence *seq, int val)
+void SEQ_time_right_handle_frame_set(const Scene *scene, Sequence *seq, int timeline_frame)
{
- const float strip_content_end_frame = seq->start + SEQ_time_strip_length_get(scene, seq);
const float left_handle_orig_frame = SEQ_time_left_handle_frame_get(scene, seq);
- if (val <= left_handle_orig_frame) {
- val = left_handle_orig_frame + 1;
+ if (timeline_frame <= left_handle_orig_frame) {
+ timeline_frame = left_handle_orig_frame + 1;
}
- seq->endofs = strip_content_end_frame - val;
- seq->enddisp = val; /* Only to make files usable in older versions. */
+ seq->endofs = SEQ_time_content_end_frame_get(scene, seq) - timeline_frame;
+ seq->enddisp = timeline_frame; /* Only to make files usable in older versions. */
+
+ SEQ_time_update_meta_strip_range(scene, seq_sequence_lookup_meta_by_seq(scene, seq));
+ seq_time_update_effects_strip_range(scene, seq_sequence_lookup_effects_by_seq(scene, seq));
+}
+
+void seq_time_translate_handles(const Scene *scene, Sequence *seq, const int offset)
+{
+ seq->startofs += offset;
+ seq->endofs -= offset;
+ seq->startdisp += offset; /* Only to make files usable in older versions. */
+ seq->enddisp -= offset; /* Only to make files usable in older versions. */
SEQ_time_update_meta_strip_range(scene, seq_sequence_lookup_meta_by_seq(scene, seq));
seq_time_update_effects_strip_range(scene, seq_sequence_lookup_effects_by_seq(scene, seq));
diff --git a/source/blender/sequencer/intern/strip_time.h b/source/blender/sequencer/intern/strip_time.h
index db581649f8a..19f549924df 100644
--- a/source/blender/sequencer/intern/strip_time.h
+++ b/source/blender/sequencer/intern/strip_time.h
@@ -40,6 +40,7 @@ void seq_time_gap_info_get(const struct Scene *scene,
struct GapInfo *r_gap_info);
void seq_time_effect_range_set(const struct Scene *scene, Sequence *seq);
void seq_time_update_effects_strip_range(const struct Scene *scene, struct SeqCollection *effects);
+void seq_time_translate_handles(const struct Scene *scene, struct Sequence *seq, const int offset);
#ifdef __cplusplus
}
diff --git a/source/blender/sequencer/intern/strip_transform.c b/source/blender/sequencer/intern/strip_transform.c
index a7361cbb1f9..14875df9445 100644
--- a/source/blender/sequencer/intern/strip_transform.c
+++ b/source/blender/sequencer/intern/strip_transform.c
@@ -82,27 +82,6 @@ bool SEQ_transform_seqbase_isolated_sel_check(ListBase *seqbase)
return true;
}
-void SEQ_transform_fix_single_image_seq_offsets(const Scene *scene, Sequence *seq)
-{
- int left, start;
- if (!SEQ_transform_single_image_check(seq)) {
- return;
- }
-
- /* make sure the image is always at the start since there is only one,
- * adjusting its start should be ok */
- left = SEQ_time_left_handle_frame_get(scene, seq);
- start = seq->start;
- if (start != left) {
- const int offset = left - start;
- SEQ_time_left_handle_frame_set(
- scene, seq, SEQ_time_left_handle_frame_get(scene, seq) - offset);
- SEQ_time_right_handle_frame_set(
- scene, seq, SEQ_time_right_handle_frame_get(scene, seq) - offset);
- seq->start += offset;
- }
-}
-
bool SEQ_transform_sequence_can_be_translated(Sequence *seq)
{
return !(seq->type & SEQ_TYPE_EFFECT) || (SEQ_effect_get_num_inputs(seq->type) == 0);
@@ -146,12 +125,9 @@ void SEQ_transform_translate_sequence(Scene *evil_scene, Sequence *seq, int delt
SEQ_transform_translate_sequence(evil_scene, seq_child, delta);
}
/* Move meta start/end points. */
- SEQ_time_left_handle_frame_set(
- evil_scene, seq, SEQ_time_left_handle_frame_get(evil_scene, seq) + delta);
- SEQ_time_right_handle_frame_set(
- evil_scene, seq, SEQ_time_right_handle_frame_get(evil_scene, seq) + delta);
+ seq_time_translate_handles(evil_scene, seq, delta);
}
- else { /* All other strip types. */
+ else if (seq->seq1 == NULL && seq->seq2 == NULL) { /* All other strip types. */
seq->start += delta;
/* Only to make files usable in older versions. */
seq->startdisp = SEQ_time_left_handle_frame_get(evil_scene, seq);
diff --git a/source/blender/sequencer/intern/utils.c b/source/blender/sequencer/intern/utils.c
index e6c641a5532..5b70bc33e88 100644
--- a/source/blender/sequencer/intern/utils.c
+++ b/source/blender/sequencer/intern/utils.c
@@ -224,7 +224,7 @@ void seq_open_anim_file(Scene *scene, Sequence *seq, bool openfile)
/* reset all the previously created anims */
SEQ_relations_sequence_free_anim(seq);
- BLI_join_dirfile(name, sizeof(name), seq->strip->dir, seq->strip->stripdata->name);
+ BLI_path_join(name, sizeof(name), seq->strip->dir, seq->strip->stripdata->name);
BLI_path_abs(name, BKE_main_blendfile_path_from_global());
proxy = seq->strip->proxy;
@@ -407,7 +407,7 @@ Sequence *SEQ_sequence_from_strip_elem(ListBase *seqbase, StripElem *se)
for (iseq = seqbase->first; iseq; iseq = iseq->next) {
Sequence *seq_found;
if ((iseq->strip && iseq->strip->stripdata) &&
- (ARRAY_HAS_ITEM(se, iseq->strip->stripdata, iseq->len))) {
+ ARRAY_HAS_ITEM(se, iseq->strip->stripdata, iseq->len)) {
break;
}
if ((seq_found = SEQ_sequence_from_strip_elem(&iseq->seqbase, se))) {
diff --git a/source/blender/simulation/intern/SIM_mass_spring.cpp b/source/blender/simulation/intern/SIM_mass_spring.cpp
index f5a6427a6a4..5858e16da6e 100644
--- a/source/blender/simulation/intern/SIM_mass_spring.cpp
+++ b/source/blender/simulation/intern/SIM_mass_spring.cpp
@@ -65,7 +65,7 @@ static bool cloth_get_pressure_weights(ClothModifierData *clmd,
Cloth *cloth = clmd->clothObject;
ClothVertex *verts = cloth->verts;
- for (unsigned int j = 0; j < 3; j++) {
+ for (uint j = 0; j < 3; j++) {
r_weights[j] = verts[vt->tri[j]].pressure_factor;
/* Skip the entire triangle if it has a zero weight. */
@@ -84,10 +84,10 @@ static void cloth_calc_pressure_gradient(ClothModifierData *clmd,
{
Cloth *cloth = clmd->clothObject;
Implicit_Data *data = cloth->implicit;
- unsigned int mvert_num = cloth->mvert_num;
+ uint mvert_num = cloth->mvert_num;
float pt[3];
- for (unsigned int i = 0; i < mvert_num; i++) {
+ for (uint i = 0; i < mvert_num; i++) {
SIM_mass_spring_get_position(data, i, pt);
r_vertex_pressure[i] = dot_v3v3(pt, gradient_vector);
}
@@ -107,7 +107,7 @@ static float cloth_calc_volume(ClothModifierData *clmd)
return 0.0f;
}
- for (unsigned int i = 0; i < cloth->primitive_num; i++) {
+ for (uint i = 0; i < cloth->primitive_num; i++) {
const MVertTri *vt = &tri[i];
if (cloth_get_pressure_weights(clmd, vt, weights)) {
@@ -135,7 +135,7 @@ static float cloth_calc_rest_volume(ClothModifierData *clmd)
return 0.0f;
}
- for (unsigned int i = 0; i < cloth->primitive_num; i++) {
+ for (uint i = 0; i < cloth->primitive_num; i++) {
const MVertTri *vt = &tri[i];
if (cloth_get_pressure_weights(clmd, vt, weights)) {
@@ -159,7 +159,7 @@ static float cloth_calc_average_pressure(ClothModifierData *clmd, const float *v
float total_force = 0;
float total_area = 0;
- for (unsigned int i = 0; i < cloth->primitive_num; i++) {
+ for (uint i = 0; i < cloth->primitive_num; i++) {
const MVertTri *vt = &tri[i];
if (cloth_get_pressure_weights(clmd, vt, weights)) {
@@ -175,13 +175,13 @@ static float cloth_calc_average_pressure(ClothModifierData *clmd, const float *v
return total_force / total_area;
}
-int SIM_cloth_solver_init(Object *UNUSED(ob), ClothModifierData *clmd)
+int SIM_cloth_solver_init(Object * /*ob*/, ClothModifierData *clmd)
{
Cloth *cloth = clmd->clothObject;
ClothVertex *verts = cloth->verts;
const float ZERO[3] = {0.0f, 0.0f, 0.0f};
Implicit_Data *id;
- unsigned int i, nondiag;
+ uint i, nondiag;
nondiag = cloth_count_nondiag_blocks(cloth);
cloth->implicit = id = SIM_mass_spring_solver_create(cloth->mvert_num, nondiag);
@@ -216,7 +216,7 @@ void SIM_cloth_solver_set_positions(ClothModifierData *clmd)
{
Cloth *cloth = clmd->clothObject;
ClothVertex *verts = cloth->verts;
- unsigned int mvert_num = cloth->mvert_num, i;
+ uint mvert_num = cloth->mvert_num, i;
ClothHairData *cloth_hairdata = clmd->hairdata;
Implicit_Data *id = cloth->implicit;
@@ -271,11 +271,8 @@ static void cloth_setup_constraints(ClothModifierData *clmd)
* (edge distance constraints) in a lagrangian solver. Then add forces to help
* guide the implicit solver to that state. This function is called after collisions.
*/
-static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob),
- ClothModifierData *clmd,
- float (*initial_cos)[3],
- float UNUSED(step),
- float dt)
+static int UNUSED_FUNCTION(cloth_calc_helper_forces)(
+ Object * /*ob*/, ClothModifierData *clmd, float (*initial_cos)[3], float /*step*/, float dt)
{
Cloth *cloth = clmd->clothObject;
float(*cos)[3] = (float(*)[3])MEM_callocN(sizeof(float[3]) * cloth->mvert_num,
@@ -552,7 +549,7 @@ static void hair_get_boundbox(ClothModifierData *clmd, float gmin[3], float gmax
{
Cloth *cloth = clmd->clothObject;
Implicit_Data *data = cloth->implicit;
- unsigned int mvert_num = cloth->mvert_num;
+ uint mvert_num = cloth->mvert_num;
int i;
INIT_MINMAX(gmin, gmax);
@@ -564,17 +561,17 @@ static void hair_get_boundbox(ClothModifierData *clmd, float gmin[3], float gmax
}
static void cloth_calc_force(
- Scene *scene, ClothModifierData *clmd, float UNUSED(frame), ListBase *effectors, float time)
+ Scene *scene, ClothModifierData *clmd, float /*frame*/, ListBase *effectors, float time)
{
/* Collect forces and derivatives: F, dFdX, dFdV */
Cloth *cloth = clmd->clothObject;
ClothSimSettings *parms = clmd->sim_parms;
Implicit_Data *data = cloth->implicit;
- unsigned int i = 0;
+ uint i = 0;
float drag = clmd->sim_parms->Cvi * 0.01f; /* viscosity of air scaled in percent */
float gravity[3] = {0.0f, 0.0f, 0.0f};
const MVertTri *tri = cloth->tri;
- unsigned int mvert_num = cloth->mvert_num;
+ uint mvert_num = cloth->mvert_num;
ClothVertex *vert;
#ifdef CLOTH_FORCE_GRAVITY
@@ -591,7 +588,7 @@ static void cloth_calc_force(
SIM_mass_spring_force_gravity(data, i, vert->mass, gravity);
/* Vertex goal springs */
- if ((!(vert->flags & CLOTH_VERT_FLAG_PINNED)) && (vert->goal > FLT_EPSILON)) {
+ if (!(vert->flags & CLOTH_VERT_FLAG_PINNED) && (vert->goal > FLT_EPSILON)) {
float goal_x[3], goal_v[3];
float k;
@@ -1029,8 +1026,8 @@ static void cloth_continuum_step(ClothModifierData *clmd, float dt)
for (i = 0; i < size; i++) {
float x[3], v[3], gvel[3], gvel_smooth[3], gdensity;
- madd_v3_v3v3fl(x, offset, a, (float)i / (float)(size - 1));
- madd_v3_v3fl(x, b, (float)j / (float)(size - 1));
+ madd_v3_v3v3fl(x, offset, a, float(i) / float(size - 1));
+ madd_v3_v3fl(x, b, float(j) / float(size - 1));
zero_v3(v);
SIM_hair_volume_grid_interpolate(grid, x, &gdensity, gvel, gvel_smooth, NULL, NULL);
@@ -1237,7 +1234,7 @@ static void cloth_record_result(ClothModifierData *clmd, ImplicitSolverResult *r
sres->min_iterations = min_ii(sres->min_iterations, result->iterations);
sres->max_iterations = max_ii(sres->max_iterations, result->iterations);
- sres->avg_iterations += (float)result->iterations * dt;
+ sres->avg_iterations += float(result->iterations) * dt;
}
else {
/* error only makes sense for successful iterations */
@@ -1247,7 +1244,7 @@ static void cloth_record_result(ClothModifierData *clmd, ImplicitSolverResult *r
}
sres->min_iterations = sres->max_iterations = result->iterations;
- sres->avg_iterations += (float)result->iterations * dt;
+ sres->avg_iterations += float(result->iterations) * dt;
}
sres->status |= result->status;
@@ -1263,11 +1260,11 @@ int SIM_cloth_solve(
Scene *scene = DEG_get_evaluated_scene(depsgraph);
const bool is_hair = (clmd->hairdata != nullptr);
- unsigned int i = 0;
+ uint i = 0;
float step = 0.0f, tf = clmd->sim_parms->timescale;
Cloth *cloth = clmd->clothObject;
ClothVertex *verts = cloth->verts /*, *cv*/;
- unsigned int mvert_num = cloth->mvert_num;
+ uint mvert_num = cloth->mvert_num;
float dt = clmd->sim_parms->dt * clmd->sim_parms->timescale;
Implicit_Data *id = cloth->implicit;
diff --git a/source/blender/simulation/intern/hair_volume.cpp b/source/blender/simulation/intern/hair_volume.cpp
index 36ac0c3906e..97042f433c2 100644
--- a/source/blender/simulation/intern/hair_volume.cpp
+++ b/source/blender/simulation/intern/hair_volume.cpp
@@ -39,7 +39,7 @@ static float I[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
BLI_INLINE int floor_int(float value)
{
- return value > 0.0f ? (int)value : ((int)value) - 1;
+ return value > 0.0f ? int(value) : int(value) - 1;
}
BLI_INLINE float floor_mod(float value)
@@ -68,7 +68,7 @@ struct HairGrid {
};
#define HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, axis) \
- (min_ii(max_ii((int)((vec[axis] - gmin[axis]) * scale), 0), res[axis] - 2))
+ min_ii(max_ii(int((vec[axis] - gmin[axis]) * scale), 0), res[axis] - 2)
BLI_INLINE int hair_grid_offset(const float vec[3],
const int res[3],
@@ -92,9 +92,9 @@ BLI_INLINE int hair_grid_interp_weights(
k = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 2);
offset = i + (j + k * res[1]) * res[0];
- uvw[0] = (vec[0] - gmin[0]) * scale - (float)i;
- uvw[1] = (vec[1] - gmin[1]) * scale - (float)j;
- uvw[2] = (vec[2] - gmin[2]) * scale - (float)k;
+ uvw[0] = (vec[0] - gmin[0]) * scale - float(i);
+ uvw[1] = (vec[1] - gmin[1]) * scale - float(j);
+ uvw[2] = (vec[2] - gmin[2]) * scale - float(k);
#if 0
BLI_assert(0.0f <= uvw[0] && uvw[0] <= 1.0001f);
@@ -327,14 +327,14 @@ BLI_INLINE int hair_grid_weights(
uvw[1] = (vec[1] - gmin[1]) * scale;
uvw[2] = (vec[2] - gmin[2]) * scale;
- weights[0] = dist_tent_v3f3(uvw, (float)i, (float)j, (float)k);
- weights[1] = dist_tent_v3f3(uvw, (float)(i + 1), (float)j, (float)k);
- weights[2] = dist_tent_v3f3(uvw, (float)i, (float)(j + 1), (float)k);
- weights[3] = dist_tent_v3f3(uvw, (float)(i + 1), (float)(j + 1), (float)k);
- weights[4] = dist_tent_v3f3(uvw, (float)i, (float)j, (float)(k + 1));
- weights[5] = dist_tent_v3f3(uvw, (float)(i + 1), (float)j, (float)(k + 1));
- weights[6] = dist_tent_v3f3(uvw, (float)i, (float)(j + 1), (float)(k + 1));
- weights[7] = dist_tent_v3f3(uvw, (float)(i + 1), (float)(j + 1), (float)(k + 1));
+ weights[0] = dist_tent_v3f3(uvw, float(i), float(j), float(k));
+ weights[1] = dist_tent_v3f3(uvw, float(i + 1), float(j), float(k));
+ weights[2] = dist_tent_v3f3(uvw, float(i), float(j + 1), float(k));
+ weights[3] = dist_tent_v3f3(uvw, float(i + 1), float(j + 1), float(k));
+ weights[4] = dist_tent_v3f3(uvw, float(i), float(j), float(k + 1));
+ weights[5] = dist_tent_v3f3(uvw, float(i + 1), float(j), float(k + 1));
+ weights[6] = dist_tent_v3f3(uvw, float(i), float(j + 1), float(k + 1));
+ weights[7] = dist_tent_v3f3(uvw, float(i + 1), float(j + 1), float(k + 1));
// BLI_assert(fabsf(weights_sum(weights) - 1.0f) < 0.0001f);
@@ -448,12 +448,12 @@ BLI_INLINE void hair_volume_add_segment_2D(HairGrid *grid,
HairGridVert *vert_j = vert + jmin * stride_j;
float loc_j[3] = {loc[0], loc[1], loc[2]};
- loc_j[axis_j] += (float)jmin;
+ loc_j[axis_j] += float(jmin);
for (j = jmin; j <= jmax; j++, vert_j += stride_j, loc_j[axis_j] += 1.0f) {
HairGridVert *vert_k = vert_j + kmin * stride_k;
float loc_k[3] = {loc_j[0], loc_j[1], loc_j[2]};
- loc_k[axis_k] += (float)kmin;
+ loc_k[axis_k] += float(kmin);
for (k = kmin; k <= kmax; k++, vert_k += stride_k, loc_k[axis_k] += 1.0f) {
hair_volume_eval_grid_vertex(vert_k, loc_k, radius, dist_scale, x2, v2, x3, v3);
@@ -542,7 +542,7 @@ void SIM_hair_volume_add_segment(HairGrid *grid,
float shift1, shift2; /* fraction of a full cell shift [0.0, 1.0) */
int jmin, jmax, kmin, kmax;
- h = CLAMPIS((float)i, start0, end0);
+ h = CLAMPIS(float(i), start0, end0);
shift1 = start1 + (h - start0) * inc1;
shift2 = start2 + (h - start0) * inc2;
@@ -565,7 +565,7 @@ void SIM_hair_volume_add_segment(HairGrid *grid,
}
vert0 = grid->verts + i * stride0;
- loc0[axis0] = (float)i;
+ loc0[axis0] = float(i);
loc0[axis1] = 0.0f;
loc0[axis2] = 0.0f;
@@ -618,17 +618,17 @@ BLI_INLINE void hair_volume_eval_grid_vertex_sample(HairGridVert *vert,
}
void SIM_hair_volume_add_segment(HairGrid *grid,
- const float UNUSED(x1[3]),
- const float UNUSED(v1[3]),
+ const float /*x1*/[3],
+ const float /*v1*/[3],
const float x2[3],
const float v2[3],
const float x3[3],
const float v3[3],
- const float UNUSED(x4[3]),
- const float UNUSED(v4[3]),
- const float UNUSED(dir1[3]),
- const float UNUSED(dir2[3]),
- const float UNUSED(dir3[3]))
+ const float /*x4*/[3],
+ const float /*v4*/[3],
+ const float /*dir1*/[3],
+ const float /*dir2*/[3],
+ const float /*dir3*/[3])
{
/* XXX simplified test implementation using a series of discrete sample along the segment,
* instead of finding the closest point for all affected grid vertices. */
@@ -646,7 +646,7 @@ void SIM_hair_volume_add_segment(HairGrid *grid,
float x[3], v[3];
int i, j, k;
- float f = (float)s / (float)(num_samples - 1);
+ float f = float(s) / float(num_samples - 1);
interp_v3_v3v3(x, x2, x3, f);
interp_v3_v3v3(v, v2, v3, f);
@@ -660,7 +660,7 @@ void SIM_hair_volume_add_segment(HairGrid *grid,
for (k = kmin; k <= kmax; k++) {
for (j = jmin; j <= jmax; j++) {
for (i = imin; i <= imax; i++) {
- float loc[3] = {(float)i, (float)j, (float)k};
+ float loc[3] = {float(i), float(j), float(k)};
HairGridVert *vert = grid->verts + i * stride[0] + j * stride[1] + k * stride[2];
hair_volume_eval_grid_vertex_sample(vert, loc, radius, dist_scale, x, v);
@@ -787,7 +787,7 @@ bool SIM_hair_volume_solve_divergence(HairGrid *grid,
vert->density, target_density, target_strength);
/* B vector contains the finite difference approximation of the velocity divergence.
- * NOTE: according to the discretized Navier-Stokes equation the rhs vector
+ * NOTE: according to the discretized Navier-Stokes equation the RHS vector
* and resulting pressure gradient should be multiplied by the (inverse) density;
* however, this is already included in the weighting of hair velocities on the grid!
*/
@@ -802,9 +802,9 @@ bool SIM_hair_volume_solve_divergence(HairGrid *grid,
float col[3];
float fac;
- loc[0] = (float)(i - 1);
- loc[1] = (float)(j - 1);
- loc[2] = (float)(k - 1);
+ loc[0] = float(i - 1);
+ loc[1] = float(j - 1);
+ loc[2] = float(k - 1);
grid_to_world(grid, wloc, loc);
if (divergence > 0.0f) {
@@ -884,7 +884,7 @@ bool SIM_hair_volume_solve_divergence(HairGrid *grid,
for (n = 0; n < neighbors_lo; n++) {
A.insert(neighbor_lo_index[n], u) = -1.0f;
}
- A.insert(u, u) = (float)non_solid_neighbors;
+ A.insert(u, u) = float(non_solid_neighbors);
for (n = 0; n < neighbors_hi; n++) {
A.insert(neighbor_hi_index[n], u) = -1.0f;
}
@@ -968,9 +968,9 @@ bool SIM_hair_volume_solve_divergence(HairGrid *grid,
float col[3];
float fac;
- loc[0] = (float)(i - 1);
- loc[1] = (float)(j - 1);
- loc[2] = (float)(k - 1);
+ loc[0] = float(i - 1);
+ loc[1] = float(j - 1);
+ loc[2] = float(k - 1);
grid_to_world(grid, wloc, loc);
float pressure = p[u];
@@ -1078,7 +1078,7 @@ void SIM_hair_volume_vertex_grid_filter_box(HairVertexGrid *grid, int kernel_siz
}
tot = kernel_size * 2 + 1;
- invD = 1.0f / (float)(tot * tot * tot);
+ invD = 1.0f / float(tot * tot * tot);
/* clear values for convolution */
for (i = 0; i < size; i++) {
@@ -1139,8 +1139,8 @@ HairGrid *SIM_hair_volume_create_vertex_grid(float cellsize,
resmax[i] = resmin[i] + MAX_HAIR_GRID_RES;
}
- gmin_margin[i] = (float)resmin[i] * cellsize;
- gmax_margin[i] = (float)resmax[i] * cellsize;
+ gmin_margin[i] = float(resmin[i]) * cellsize;
+ gmax_margin[i] = float(resmax[i]) * cellsize;
}
size = hair_grid_size(res);
@@ -1187,7 +1187,7 @@ void SIM_hair_volume_grid_geometry(
#if 0
static HairGridVert *hair_volume_create_collision_grid(ClothModifierData *clmd,
lfVector *lX,
- unsigned int numverts)
+ uint numverts)
{
int res = hair_grid_res;
int size = hair_grid_size(res);
@@ -1197,7 +1197,7 @@ static HairGridVert *hair_volume_create_collision_grid(ClothModifierData *clmd,
float gmin[3], gmax[3], scale[3];
/* 2.0f is an experimental value that seems to give good results */
float collfac = 2.0f * clmd->sim_parms->collider_friction;
- unsigned int v = 0;
+ uint v = 0;
int i = 0;
hair_volume_get_boundbox(lX, numverts, gmin, gmax);
diff --git a/source/blender/simulation/intern/implicit_blender.c b/source/blender/simulation/intern/implicit_blender.c
index 4193ef2c7c5..cdfa3ba88c1 100644
--- a/source/blender/simulation/intern/implicit_blender.c
+++ b/source/blender/simulation/intern/implicit_blender.c
@@ -61,12 +61,12 @@ struct Cloth;
/* DEFINITIONS */
typedef float lfVector[3];
typedef struct fmatrix3x3 {
- float m[3][3]; /* 3x3 matrix */
- unsigned int c, r; /* column and row number */
+ float m[3][3]; /* 3x3 matrix */
+ uint c, r; /* column and row number */
// int pinned; /* is this vertex allowed to move? */
- float n1, n2, n3; /* three normal vectors for collision constrains */
- unsigned int vcount; /* vertex count */
- unsigned int scount; /* spring count */
+ float n1, n2, n3; /* three normal vectors for collision constrains */
+ uint vcount; /* vertex count */
+ uint scount; /* spring count */
} fmatrix3x3;
///////////////////////////
@@ -110,9 +110,9 @@ static void print_fvector(float m3[3])
/* long float vector float (*)[3] */
///////////////////////////
/* print long vector on console: for debug output */
-DO_INLINE void print_lfvector(float (*fLongVector)[3], unsigned int verts)
+DO_INLINE void print_lfvector(float (*fLongVector)[3], uint verts)
{
- unsigned int i = 0;
+ uint i = 0;
for (i = 0; i < verts; i++) {
print_fvector(fLongVector[i]);
}
@@ -120,7 +120,7 @@ DO_INLINE void print_lfvector(float (*fLongVector)[3], unsigned int verts)
# endif
/* create long vector */
-DO_INLINE lfVector *create_lfvector(unsigned int verts)
+DO_INLINE lfVector *create_lfvector(uint verts)
{
/* TODO: check if memory allocation was successful */
return (lfVector *)MEM_callocN(verts * sizeof(lfVector), "cloth_implicit_alloc_vector");
@@ -135,30 +135,27 @@ DO_INLINE void del_lfvector(float (*fLongVector)[3])
}
}
/* copy long vector */
-DO_INLINE void cp_lfvector(float (*to)[3], float (*from)[3], unsigned int verts)
+DO_INLINE void cp_lfvector(float (*to)[3], float (*from)[3], uint verts)
{
memcpy(to, from, verts * sizeof(lfVector));
}
/* init long vector with float[3] */
-DO_INLINE void init_lfvector(float (*fLongVector)[3], const float vector[3], unsigned int verts)
+DO_INLINE void init_lfvector(float (*fLongVector)[3], const float vector[3], uint verts)
{
- unsigned int i = 0;
+ uint i = 0;
for (i = 0; i < verts; i++) {
copy_v3_v3(fLongVector[i], vector);
}
}
/* zero long vector with float[3] */
-DO_INLINE void zero_lfvector(float (*to)[3], unsigned int verts)
+DO_INLINE void zero_lfvector(float (*to)[3], uint verts)
{
memset(to, 0.0f, verts * sizeof(lfVector));
}
/* Multiply long vector with scalar. */
-DO_INLINE void mul_lfvectorS(float (*to)[3],
- float (*fLongVector)[3],
- float scalar,
- unsigned int verts)
+DO_INLINE void mul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, uint verts)
{
- unsigned int i = 0;
+ uint i = 0;
for (i = 0; i < verts; i++) {
mul_fvector_S(to[i], fLongVector[i], scalar);
@@ -166,20 +163,15 @@ DO_INLINE void mul_lfvectorS(float (*to)[3],
}
/* Multiply long vector with scalar.
* `A -= B * float` */
-DO_INLINE void submul_lfvectorS(float (*to)[3],
- float (*fLongVector)[3],
- float scalar,
- unsigned int verts)
+DO_INLINE void submul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, uint verts)
{
- unsigned int i = 0;
+ uint i = 0;
for (i = 0; i < verts; i++) {
VECSUBMUL(to[i], fLongVector[i], scalar);
}
}
/* dot product for big vector */
-DO_INLINE float dot_lfvector(float (*fLongVectorA)[3],
- float (*fLongVectorB)[3],
- unsigned int verts)
+DO_INLINE float dot_lfvector(float (*fLongVectorA)[3], float (*fLongVectorB)[3], uint verts)
{
long i = 0;
float temp = 0.0;
@@ -197,22 +189,19 @@ DO_INLINE float dot_lfvector(float (*fLongVectorA)[3],
DO_INLINE void add_lfvector_lfvector(float (*to)[3],
float (*fLongVectorA)[3],
float (*fLongVectorB)[3],
- unsigned int verts)
+ uint verts)
{
- unsigned int i = 0;
+ uint i = 0;
for (i = 0; i < verts; i++) {
add_v3_v3v3(to[i], fLongVectorA[i], fLongVectorB[i]);
}
}
/* `A = B + C * float` -> for big vector. */
-DO_INLINE void add_lfvector_lfvectorS(float (*to)[3],
- float (*fLongVectorA)[3],
- float (*fLongVectorB)[3],
- float bS,
- unsigned int verts)
+DO_INLINE void add_lfvector_lfvectorS(
+ float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, uint verts)
{
- unsigned int i = 0;
+ uint i = 0;
for (i = 0; i < verts; i++) {
VECADDS(to[i], fLongVectorA[i], fLongVectorB[i], bS);
@@ -224,22 +213,19 @@ DO_INLINE void add_lfvectorS_lfvectorS(float (*to)[3],
float aS,
float (*fLongVectorB)[3],
float bS,
- unsigned int verts)
+ uint verts)
{
- unsigned int i = 0;
+ uint i = 0;
for (i = 0; i < verts; i++) {
VECADDSS(to[i], fLongVectorA[i], aS, fLongVectorB[i], bS);
}
}
/* `A = B - C * float` -> for big vector. */
-DO_INLINE void sub_lfvector_lfvectorS(float (*to)[3],
- float (*fLongVectorA)[3],
- float (*fLongVectorB)[3],
- float bS,
- unsigned int verts)
+DO_INLINE void sub_lfvector_lfvectorS(
+ float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, uint verts)
{
- unsigned int i = 0;
+ uint i = 0;
for (i = 0; i < verts; i++) {
VECSUBS(to[i], fLongVectorA[i], fLongVectorB[i], bS);
}
@@ -248,9 +234,9 @@ DO_INLINE void sub_lfvector_lfvectorS(float (*to)[3],
DO_INLINE void sub_lfvector_lfvector(float (*to)[3],
float (*fLongVectorA)[3],
float (*fLongVectorB)[3],
- unsigned int verts)
+ uint verts)
{
- unsigned int i = 0;
+ uint i = 0;
for (i = 0; i < verts; i++) {
sub_v3_v3v3(to[i], fLongVectorA[i], fLongVectorB[i]);
@@ -271,7 +257,7 @@ static void print_fmatrix(float m3[3][3])
static void print_sparse_matrix(fmatrix3x3 *m)
{
if (m) {
- unsigned int i;
+ uint i;
for (i = 0; i < m[0].vcount + m[0].scount; i++) {
printf("%d:\n", i);
print_fmatrix(m[i].m);
@@ -374,7 +360,7 @@ DO_INLINE float det_fmatrix(float m[3][3])
DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3])
{
- unsigned int i, j;
+ uint i, j;
float d;
if ((d = det_fmatrix(from)) == 0) {
@@ -524,7 +510,7 @@ BLI_INLINE void madd_m3_m3fl(float r[3][3], const float m[3][3], float f)
# if 0
static void print_bfmatrix(fmatrix3x3 *m3)
{
- unsigned int i = 0;
+ uint i = 0;
for (i = 0; i < m3[0].vcount + m3[0].scount; i++) {
print_fmatrix(m3[i].m);
@@ -539,7 +525,7 @@ BLI_INLINE void init_fmatrix(fmatrix3x3 *matrix, int r, int c)
}
/* create big matrix */
-DO_INLINE fmatrix3x3 *create_bfmatrix(unsigned int verts, unsigned int springs)
+DO_INLINE fmatrix3x3 *create_bfmatrix(uint verts, uint springs)
{
/* TODO: check if memory allocation was successful */
fmatrix3x3 *temp = (fmatrix3x3 *)MEM_callocN(sizeof(fmatrix3x3) * (verts + springs),
@@ -575,7 +561,7 @@ DO_INLINE void cp_bfmatrix(fmatrix3x3 *to, fmatrix3x3 *from)
/* slow in parallel */
DO_INLINE void init_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
{
- unsigned int i;
+ uint i;
for (i = 0; i < matrix[0].vcount + matrix[0].scount; i++) {
cp_fmatrix(matrix[i].m, m3);
@@ -586,7 +572,7 @@ DO_INLINE void init_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
/* slow in parallel */
DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
{
- unsigned int i, j;
+ uint i, j;
float tmatrix[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
for (i = 0; i < matrix[0].vcount; i++) {
@@ -601,7 +587,7 @@ DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
/* STATUS: verified */
DO_INLINE void mul_bfmatrix_lfvector(float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
{
- unsigned int vcount = from[0].vcount;
+ uint vcount = from[0].vcount;
lfVector *temp = create_lfvector(vcount);
zero_lfvector(to, vcount);
@@ -610,7 +596,7 @@ DO_INLINE void mul_bfmatrix_lfvector(float (*to)[3], fmatrix3x3 *from, lfVector
{
# pragma omp section
{
- for (unsigned int i = from[0].vcount; i < from[0].vcount + from[0].scount; i++) {
+ for (uint i = from[0].vcount; i < from[0].vcount + from[0].scount; i++) {
/* This is the lower triangle of the sparse matrix,
* therefore multiplication occurs with transposed submatrices. */
muladd_fmatrixT_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]);
@@ -618,7 +604,7 @@ DO_INLINE void mul_bfmatrix_lfvector(float (*to)[3], fmatrix3x3 *from, lfVector
}
# pragma omp section
{
- for (unsigned int i = 0; i < from[0].vcount + from[0].scount; i++) {
+ for (uint i = 0; i < from[0].vcount + from[0].scount; i++) {
muladd_fmatrix_fvector(temp[from[i].r], from[i].m, fLongVector[from[i].c]);
}
}
@@ -634,7 +620,7 @@ DO_INLINE void mul_bfmatrix_lfvector(float (*to)[3], fmatrix3x3 *from, lfVector
DO_INLINE void subadd_bfmatrixS_bfmatrixS(
fmatrix3x3 *to, fmatrix3x3 *from, float aS, fmatrix3x3 *matrix, float bS)
{
- unsigned int i = 0;
+ uint i = 0;
/* process diagonal elements */
for (i = 0; i < matrix[0].vcount + matrix[0].scount; i++) {
@@ -757,7 +743,7 @@ BLI_INLINE void root_to_world_m3(Implicit_Data *data,
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
{
- unsigned int i = 0;
+ uint i = 0;
for (i = 0; i < S[0].vcount; i++) {
mul_m3_v3(S[i].m, V[S[i].r]);
@@ -770,11 +756,11 @@ DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S)
{
/* Solves for unknown X in equation AX=B */
- unsigned int conjgrad_loopcount = 0, conjgrad_looplimit = 100;
+ uint conjgrad_loopcount = 0, conjgrad_looplimit = 100;
float conjgrad_epsilon = 0.0001f /* , conjgrad_lasterror=0 */ /* UNUSED */;
lfVector *q, *d, *tmp, *r;
float s, starget, a, s_prev;
- unsigned int numverts = lA[0].vcount;
+ uint numverts = lA[0].vcount;
q = create_lfvector(numverts);
d = create_lfvector(numverts);
tmp = create_lfvector(numverts);
@@ -842,10 +828,10 @@ static int cg_filtered(lfVector *ldV,
ImplicitSolverResult *result)
{
/* Solves for unknown X in equation AX=B */
- unsigned int conjgrad_loopcount = 0, conjgrad_looplimit = 100;
+ uint conjgrad_loopcount = 0, conjgrad_looplimit = 100;
float conjgrad_epsilon = 0.01f;
- unsigned int numverts = lA[0].vcount;
+ uint numverts = lA[0].vcount;
lfVector *fB = create_lfvector(numverts);
lfVector *AdV = create_lfvector(numverts);
lfVector *r = create_lfvector(numverts);
@@ -933,7 +919,7 @@ static int cg_filtered(lfVector *ldV,
/* block diagonalizer */
DO_INLINE void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv)
{
- unsigned int i = 0;
+ uint i = 0;
/* Take only the diagonal blocks of A */
// #pragma omp parallel for private(i) if (lA[0].vcount > CLOTH_OPENMP_LIMIT)
@@ -954,7 +940,7 @@ static int cg_filtered_pre(lfVector *dv,
fmatrix3x3 *P,
fmatrix3x3 *Pinv)
{
- unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit = 100;
+ uint numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit = 100;
float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0;
float conjgrad_epsilon = 0.0001; /* 0.2 is dt for steps=5 */
lfVector *r = create_lfvector(numverts);
@@ -1032,7 +1018,7 @@ static int cg_filtered_pre(lfVector *dv,
fmatrix3x3 *Pinv,
fmatrix3x3 *bigI)
{
- unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit = 100;
+ uint numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit = 100;
float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0, tol = 0;
lfVector *r = create_lfvector(numverts);
lfVector *p = create_lfvector(numverts);
@@ -1137,7 +1123,7 @@ static int cg_filtered_pre(lfVector *dv,
bool SIM_mass_spring_solve_velocities(Implicit_Data *data, float dt, ImplicitSolverResult *result)
{
- unsigned int numverts = data->dFdV[0].vcount;
+ uint numverts = data->dFdV[0].vcount;
lfVector *dFdXmV = create_lfvector(numverts);
zero_lfvector(data->dV, numverts);
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 775b62e7d39..3526a4349b5 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -94,7 +94,7 @@ void WM_init_state_maximized_set(void);
void WM_init_state_start_with_console_set(bool value);
void WM_init_window_focus_set(bool do_it);
void WM_init_native_pixels(bool do_it);
-void WM_init_tablet_api(void);
+void WM_init_input_devices(void);
/**
* Initialize Blender and load the startup file & preferences
@@ -119,6 +119,13 @@ void WM_init_splash(struct bContext *C);
void WM_init_opengl(void);
+/**
+ * Return an identifier for the underlying GHOST implementation.
+ * \warning Use of this function should be limited & never for compatibility checks.
+ * see: #GHOST_ISystem::getSystemBackend for details.
+ */
+const char *WM_ghost_backend(void);
+
void WM_check(struct bContext *C);
void WM_reinit_gizmomap_all(struct Main *bmain);
@@ -334,6 +341,18 @@ void WM_cursor_warp(struct wmWindow *win, int x, int y);
/* Handlers. */
+typedef enum eWM_EventHandlerFlag {
+ /** After this handler all others are ignored. */
+ WM_HANDLER_BLOCKING = (1 << 0),
+ /** Handler accepts double key press events. */
+ WM_HANDLER_ACCEPT_DBL_CLICK = (1 << 1),
+
+ /* Internal. */
+ /** Handler tagged to be freed in #wm_handlers_do(). */
+ WM_HANDLER_DO_FREE = (1 << 7),
+} eWM_EventHandlerFlag;
+ENUM_OPERATORS(eWM_EventHandlerFlag, WM_HANDLER_DO_FREE)
+
typedef bool (*EventHandlerPoll)(const ARegion *region, const struct wmEvent *event);
struct wmEventHandler_Keymap *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap);
struct wmEventHandler_Keymap *WM_event_add_keymap_handler_poll(ListBase *handlers,
@@ -400,7 +419,7 @@ struct wmEventHandler_UI *WM_event_add_ui_handler(const struct bContext *C,
wmUIHandlerFunc handle_fn,
wmUIHandlerRemoveFunc remove_fn,
void *user_data,
- char flag);
+ eWM_EventHandlerFlag flag);
/**
* Return the first modal operator of type \a ot or NULL.
@@ -443,15 +462,6 @@ void WM_event_modal_handler_region_replace(wmWindow *win,
*/
void WM_event_remove_handlers(struct bContext *C, ListBase *handlers);
-/* handler flag */
-enum {
- WM_HANDLER_BLOCKING = (1 << 0), /* after this handler all others are ignored */
- WM_HANDLER_ACCEPT_DBL_CLICK = (1 << 1), /* handler accepts double key press events */
-
- /* internal */
- WM_HANDLER_DO_FREE = (1 << 7), /* handler tagged to be freed in wm_handlers_do() */
-};
-
struct wmEventHandler_Dropbox *WM_event_add_dropbox_handler(ListBase *handlers,
ListBase *dropboxes);
@@ -1292,7 +1302,6 @@ bool WM_drag_is_ID_type(const struct wmDrag *drag, int idcode);
* \note Does not store \a asset in any way, so it's fine to pass a temporary.
*/
wmDragAsset *WM_drag_create_asset_data(const struct AssetHandle *asset,
- struct AssetMetaData *metadata,
const char *path,
int import_type);
struct wmDragAsset *WM_drag_get_asset_data(const struct wmDrag *drag, int idcode);
@@ -1348,17 +1357,18 @@ void wmOrtho2_pixelspace(float x, float y);
void wmGetProjectionMatrix(float mat[4][4], const struct rcti *winrct);
/* threaded Jobs Manager */
-enum {
+typedef enum eWM_JobFlag {
WM_JOB_PRIORITY = (1 << 0),
WM_JOB_EXCL_RENDER = (1 << 1),
WM_JOB_PROGRESS = (1 << 2),
-};
+} eWM_JobFlag;
+ENUM_OPERATORS(enum eWM_JobFlag, WM_JOB_PROGRESS);
/**
* Identifying jobs by owner alone is unreliable, this isn't saved,
* order can change (keep 0 for 'any').
*/
-enum {
+typedef enum eWM_JobType {
WM_JOB_TYPE_ANY = 0,
WM_JOB_TYPE_COMPOSITE,
WM_JOB_TYPE_RENDER,
@@ -1390,7 +1400,7 @@ enum {
WM_JOB_TYPE_SEQ_DRAG_DROP_PREVIEW,
/* add as needed, bake, seq proxy build
* if having hard coded values is a problem */
-};
+} eWM_JobType;
/**
* \return current job or adds new job, but doesn't run it.
@@ -1402,8 +1412,8 @@ struct wmJob *WM_jobs_get(struct wmWindowManager *wm,
struct wmWindow *win,
const void *owner,
const char *name,
- int flag,
- int job_type);
+ eWM_JobFlag flag,
+ eWM_JobType job_type);
/**
* Returns true if job runs, for UI (progress) indicators.
@@ -1425,8 +1435,8 @@ void WM_jobs_timer(struct wmJob *, double timestep, unsigned int note, unsigned
void WM_jobs_delay_start(struct wmJob *, double delay_time);
typedef void (*wm_jobs_start_callback)(void *custom_data,
- short *stop,
- short *do_update,
+ bool *stop,
+ bool *do_update,
float *progress);
void WM_jobs_callbacks(struct wmJob *,
wm_jobs_start_callback startjob,
@@ -1456,7 +1466,7 @@ void WM_jobs_stop(struct wmWindowManager *wm, const void *owner, void *startjob)
*/
void WM_jobs_kill(struct wmWindowManager *wm,
void *owner,
- void (*)(void *, short int *, short int *, float *));
+ void (*)(void *, bool *, bool *, float *));
/**
* Wait until every job ended.
*/
diff --git a/source/blender/windowmanager/WM_toolsystem.h b/source/blender/windowmanager/WM_toolsystem.h
index 96094e9e7ef..e9ad216073e 100644
--- a/source/blender/windowmanager/WM_toolsystem.h
+++ b/source/blender/windowmanager/WM_toolsystem.h
@@ -85,16 +85,19 @@ void WM_toolsystem_ref_sync_from_context(struct Main *bmain,
void WM_toolsystem_init(struct bContext *C);
-int WM_toolsystem_mode_from_spacetype(struct ViewLayer *view_layer,
+int WM_toolsystem_mode_from_spacetype(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct ScrArea *area,
int space_type);
-bool WM_toolsystem_key_from_context(struct ViewLayer *view_layer,
+bool WM_toolsystem_key_from_context(const struct Scene *scene,
+ struct ViewLayer *view_layer,
struct ScrArea *area,
bToolKey *tkey);
void WM_toolsystem_update_from_context_view3d(struct bContext *C);
void WM_toolsystem_update_from_context(struct bContext *C,
struct WorkSpace *workspace,
+ const struct Scene *scene,
struct ViewLayer *view_layer,
struct ScrArea *area);
@@ -145,6 +148,7 @@ void WM_toolsystem_ref_properties_init_for_keymap(struct bToolRef *tref,
void WM_toolsystem_refresh_active(struct bContext *C);
void WM_toolsystem_refresh_screen_area(struct WorkSpace *workspace,
+ const struct Scene *scene,
struct ViewLayer *view_layer,
struct ScrArea *area);
void WM_toolsystem_refresh_screen_window(struct wmWindow *win);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index ba11923d0df..bdd5163ddf1 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -353,11 +353,13 @@ typedef struct wmNotifier {
#define NC_LIGHTPROBE (26 << 24)
/* Changes to asset data in the current .blend. */
#define NC_ASSET (27 << 24)
+/* Changes to the active viewer path. */
+#define NC_VIEWER_PATH (28 << 24)
/* data type, 256 entries is enough, it can overlap */
#define NOTE_DATA 0x00FF0000
-/* NC_WM windowmanager */
+/* NC_WM (window-manager). */
#define ND_FILEREAD (1 << 16)
#define ND_FILESAVE (2 << 16)
#define ND_DATACHANGED (3 << 16)
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
index e165cb6b4f8..1c0f1e03a47 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
@@ -632,7 +632,7 @@ wmKeyMap *wm_gizmogroup_tweak_modal_keymap(wmKeyConfig *keyconf)
STRNCPY(name, "Generic Gizmo Tweak Modal Map");
keymap = WM_modalkeymap_find(keyconf, name);
- /* this function is called for each spacetype, only needs to add map once */
+ /* This function is called for each space-type, only needs to add map once. */
if (keymap && keymap->modal_items) {
return NULL;
}
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c
index 80876dfd798..9f0506f209b 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c
@@ -33,7 +33,7 @@
BLI_INLINE wmGizmoProperty *wm_gizmo_target_property_array(wmGizmo *gz)
{
- return (wmGizmoProperty *)(POINTER_OFFSET(gz, gz->type->struct_size));
+ return (wmGizmoProperty *)POINTER_OFFSET(gz, gz->type->struct_size);
}
wmGizmoProperty *WM_gizmo_target_property_array(wmGizmo *gz)
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.cc b/source/blender/windowmanager/intern/wm_dragdrop.cc
index 94bd33a9765..393149f20f5 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.cc
+++ b/source/blender/windowmanager/intern/wm_dragdrop.cc
@@ -174,8 +174,7 @@ static void wm_dropbox_invoke(bContext *C, wmDrag *drag)
}
}
-wmDrag *WM_drag_data_create(
- bContext *C, int icon, int type, void *poin, double value, unsigned int flags)
+wmDrag *WM_drag_data_create(bContext *C, int icon, int type, void *poin, double value, uint flags)
{
wmDrag *drag = MEM_cnew<wmDrag>(__func__);
@@ -234,8 +233,7 @@ void WM_event_start_prepared_drag(bContext *C, wmDrag *drag)
wm_dropbox_invoke(C, drag);
}
-void WM_event_start_drag(
- bContext *C, int icon, int type, void *poin, double value, unsigned int flags)
+void WM_event_start_drag(bContext *C, int icon, int type, void *poin, double value, uint flags)
{
wmDrag *drag = WM_drag_data_create(C, icon, type, poin, value, flags);
WM_event_start_prepared_drag(C, drag);
@@ -473,7 +471,7 @@ void wm_drop_prepare(bContext *C, wmDrag *drag, wmDropBox *drop)
wm_drags_exit(CTX_wm_manager(C), CTX_wm_window(C));
}
-void wm_drop_end(bContext *C, wmDrag *UNUSED(drag), wmDropBox *UNUSED(drop))
+void wm_drop_end(bContext *C, wmDrag * /*drag*/, wmDropBox * /*drop*/)
{
CTX_store_set(C, nullptr);
}
@@ -498,7 +496,7 @@ void wm_drags_check_ops(bContext *C, const wmEvent *event)
}
}
-wmOperatorCallContext wm_drop_operator_context_get(const wmDropBox *UNUSED(drop))
+wmOperatorCallContext wm_drop_operator_context_get(const wmDropBox * /*drop*/)
{
return WM_OP_INVOKE_DEFAULT;
}
@@ -558,15 +556,12 @@ bool WM_drag_is_ID_type(const wmDrag *drag, int idcode)
return WM_drag_get_local_ID(drag, idcode) || WM_drag_get_asset_data(drag, idcode);
}
-wmDragAsset *WM_drag_create_asset_data(const AssetHandle *asset,
- AssetMetaData *metadata,
- const char *path,
- int import_type)
+wmDragAsset *WM_drag_create_asset_data(const AssetHandle *asset, const char *path, int import_type)
{
wmDragAsset *asset_drag = MEM_new<wmDragAsset>(__func__);
BLI_strncpy(asset_drag->name, ED_asset_handle_get_name(asset), sizeof(asset_drag->name));
- asset_drag->metadata = metadata;
+ asset_drag->metadata = ED_asset_handle_get_metadata(asset);
asset_drag->path = path;
asset_drag->id_type = ED_asset_handle_get_id_type(asset);
asset_drag->import_type = import_type;
@@ -587,7 +582,7 @@ wmDragAsset *WM_drag_get_asset_data(const wmDrag *drag, int idcode)
}
wmDragAsset *asset_drag = static_cast<wmDragAsset *>(drag->poin);
- return (ELEM(idcode, 0, asset_drag->id_type)) ? asset_drag : nullptr;
+ return ELEM(idcode, 0, asset_drag->id_type) ? asset_drag : nullptr;
}
AssetMetaData *WM_drag_get_asset_meta_data(const wmDrag *drag, int idcode)
@@ -735,12 +730,11 @@ void WM_drag_add_asset_list_item(
drag_asset->asset_data.local_id = local_id;
}
else {
- AssetMetaData *metadata = ED_asset_handle_get_metadata(asset);
char asset_blend_path[FILE_MAX_LIBEXTRA];
ED_asset_handle_get_full_library_path(C, asset_library_ref, asset, asset_blend_path);
drag_asset->is_external = true;
drag_asset->asset_data.external_info = WM_drag_create_asset_data(
- asset, metadata, BLI_strdup(asset_blend_path), FILE_ASSET_IMPORT_APPEND);
+ asset, BLI_strdup(asset_blend_path), FILE_ASSET_IMPORT_APPEND);
}
BLI_addtail(&drag->asset_items, drag_asset);
}
@@ -820,10 +814,7 @@ static int wm_drag_imbuf_icon_height_get(const wmDrag *drag)
return round_fl_to_int(drag->imb->y * drag->imbuf_scale);
}
-static void wm_drag_draw_icon(bContext *UNUSED(C),
- wmWindow *UNUSED(win),
- wmDrag *drag,
- const int xy[2])
+static void wm_drag_draw_icon(bContext * /*C*/, wmWindow * /*win*/, wmDrag *drag, const int xy[2])
{
int x, y;
@@ -858,7 +849,8 @@ static void wm_drag_draw_icon(bContext *UNUSED(C),
y = xy[1] - 2 * UI_DPI_FAC;
const uchar text_col[] = {255, 255, 255, 255};
- UI_icon_draw_ex(x, y, drag->icon, U.inv_dpi_fac, 0.8, 0.0f, text_col, false);
+ UI_icon_draw_ex(
+ x, y, drag->icon, U.inv_dpi_fac, 0.8, 0.0f, text_col, false, UI_NO_ICON_OVERLAY_TEXT);
}
}
@@ -869,10 +861,7 @@ static void wm_drag_draw_item_name(wmDrag *drag, const int x, const int y)
UI_fontstyle_draw_simple(fstyle, x, y, WM_drag_get_item_name(drag), text_col);
}
-void WM_drag_draw_item_name_fn(bContext *UNUSED(C),
- wmWindow *UNUSED(win),
- wmDrag *drag,
- const int xy[2])
+void WM_drag_draw_item_name_fn(bContext * /*C*/, wmWindow * /*win*/, wmDrag *drag, const int xy[2])
{
int x = xy[0] + 10 * UI_DPI_FAC;
int y = xy[1] + 1 * UI_DPI_FAC;
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index a3334c79ba0..663a41212ba 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -894,7 +894,8 @@ static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo)
if (area->flag & AREA_FLAG_ACTIVE_TOOL_UPDATE) {
if ((1 << area->spacetype) & WM_TOOLSYSTEM_SPACE_MASK) {
- WM_toolsystem_update_from_context(C, CTX_wm_workspace(C), CTX_data_view_layer(C), area);
+ WM_toolsystem_update_from_context(
+ C, CTX_wm_workspace(C), CTX_data_scene(C), CTX_data_view_layer(C), area);
}
area->flag &= ~AREA_FLAG_ACTIVE_TOOL_UPDATE;
}
diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc
index bc19e2c09c3..c84df617f98 100644
--- a/source/blender/windowmanager/intern/wm_event_system.cc
+++ b/source/blender/windowmanager/intern/wm_event_system.cc
@@ -56,6 +56,8 @@
#include "ED_util.h"
#include "ED_view3d.h"
+#include "GPU_context.h"
+
#include "RNA_access.h"
#include "UI_interface.h"
@@ -323,7 +325,7 @@ void WM_event_add_notifier(const bContext *C, uint type, void *reference)
WM_event_add_notifier_ex(CTX_wm_manager(C), CTX_wm_window(C), type, reference);
}
-void WM_main_add_notifier(unsigned int type, void *reference)
+void WM_main_add_notifier(uint type, void *reference)
{
Main *bmain = G_MAIN;
wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
@@ -357,7 +359,7 @@ void WM_main_remove_notifier_reference(const void *reference)
}
}
-static void wm_main_remap_assetlist(ID *old_id, ID *new_id, void *UNUSED(user_data))
+static void wm_main_remap_assetlist(ID *old_id, ID *new_id, void * /*user_data*/)
{
ED_assetlist_storage_id_remap(old_id, new_id);
}
@@ -484,11 +486,15 @@ static void wm_event_execute_timers(bContext *C)
void wm_event_do_notifiers(bContext *C)
{
+ /* Ensure inside render boundary. */
+ GPU_render_begin();
+
/* Run the timer before assigning `wm` in the unlikely case a timer loads a file, see T80028. */
wm_event_execute_timers(C);
wmWindowManager *wm = CTX_wm_manager(C);
if (wm == nullptr) {
+ GPU_render_end();
return;
}
@@ -561,7 +567,7 @@ void wm_event_do_notifiers(bContext *C)
}
if (note->window == win ||
- (note->window == nullptr && (ELEM(note->reference, nullptr, scene)))) {
+ (note->window == nullptr && ELEM(note->reference, nullptr, scene))) {
if (note->category == NC_SCENE) {
if (note->data == ND_FRAME) {
do_anim = true;
@@ -626,6 +632,7 @@ void wm_event_do_notifiers(bContext *C)
win->screen->id.name + 2,
note->category);
# endif
+ ED_workspace_do_listen(C, note);
ED_screen_do_listen(C, note);
LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) {
@@ -691,6 +698,8 @@ void wm_event_do_notifiers(bContext *C)
/* Auto-run warning. */
wm_test_autorun_warning(C);
+
+ GPU_render_end();
}
static bool wm_event_always_pass(const wmEvent *event)
@@ -1217,7 +1226,7 @@ int WM_operator_repeat_last(bContext *C, wmOperator *op)
op->flag &= ~op_flag;
return ret;
}
-bool WM_operator_repeat_check(const bContext *UNUSED(C), wmOperator *op)
+bool WM_operator_repeat_check(const bContext * /*C*/, wmOperator *op)
{
if (op->type->exec != nullptr) {
return true;
@@ -2177,26 +2186,26 @@ static bool wm_eventmatch(const wmEvent *winevent, const wmKeyMapItem *kmi)
/* Account for rare case of when these keys are used as the 'type' not as modifiers. */
if (kmi->shift != KM_ANY) {
const bool shift = (winevent->modifier & KM_SHIFT) != 0;
- if ((shift != (bool)kmi->shift) &&
+ if ((shift != bool(kmi->shift)) &&
!ELEM(winevent->type, EVT_LEFTSHIFTKEY, EVT_RIGHTSHIFTKEY)) {
return false;
}
}
if (kmi->ctrl != KM_ANY) {
const bool ctrl = (winevent->modifier & KM_CTRL) != 0;
- if (ctrl != (bool)kmi->ctrl && !ELEM(winevent->type, EVT_LEFTCTRLKEY, EVT_RIGHTCTRLKEY)) {
+ if (ctrl != bool(kmi->ctrl) && !ELEM(winevent->type, EVT_LEFTCTRLKEY, EVT_RIGHTCTRLKEY)) {
return false;
}
}
if (kmi->alt != KM_ANY) {
const bool alt = (winevent->modifier & KM_ALT) != 0;
- if (alt != (bool)kmi->alt && !ELEM(winevent->type, EVT_LEFTALTKEY, EVT_RIGHTALTKEY)) {
+ if (alt != bool(kmi->alt) && !ELEM(winevent->type, EVT_LEFTALTKEY, EVT_RIGHTALTKEY)) {
return false;
}
}
if (kmi->oskey != KM_ANY) {
const bool oskey = (winevent->modifier & KM_OSKEY) != 0;
- if ((oskey != (bool)kmi->oskey) && (winevent->type != EVT_OSKEY)) {
+ if ((oskey != bool(kmi->oskey)) && (winevent->type != EVT_OSKEY)) {
return false;
}
}
@@ -2221,7 +2230,7 @@ static wmKeyMapItem *wm_eventmatch_modal_keymap_items(const wmKeyMap *keymap,
/* Should already be handled by #wm_user_modal_keymap_set_items. */
BLI_assert(kmi->propvalue_str[0] == '\0');
if (wm_eventmatch(event, kmi)) {
- if ((keymap->poll_modal_item == nullptr) || (keymap->poll_modal_item(op, kmi->propvalue))) {
+ if ((keymap->poll_modal_item == nullptr) || keymap->poll_modal_item(op, kmi->propvalue)) {
return kmi;
}
}
@@ -2379,7 +2388,7 @@ static int wm_handler_operator_call(bContext *C,
/* When the window changes the modal modifier may have loaded a new blend file
* (the `system_demo_mode` add-on does this), so we have to assume the event,
* operator, area, region etc have all been freed. */
- if ((CTX_wm_window(C) == win)) {
+ if (CTX_wm_window(C) == win) {
wm_event_modalkeymap_end(event, &event_backup);
@@ -4082,9 +4091,9 @@ void WM_event_fileselect_event(wmWindowManager *wm, void *ophandle, int eventval
* An appropriate window is either of the following:
* * A parent window that does not yet contain a modal File Browser. This is determined using
* #ED_fileselect_handler_area_find_any_with_op().
- * * A parent window containing a modal File Browser, but in a maximized/fullscreen state. Users
+ * * A parent window containing a modal File Browser, but in a maximized/full-screen state. Users
* shouldn't be able to put a temporary screen like the modal File Browser into
- * maximized/fullscreen state themselves. So this setup indicates that the File Browser was
+ * maximized/full-screen state themselves. So this setup indicates that the File Browser was
* opened using #USER_TEMP_SPACE_DISPLAY_FULLSCREEN.
*
* If no appropriate parent window can be found from the context window, return the first
@@ -4267,7 +4276,7 @@ void WM_event_modal_handler_region_replace(wmWindow *win,
* it needs to keep old region stored in handler, so don't change it. */
if ((handler->context.region == old_region) && (handler->is_fileselect == false)) {
handler->context.region = new_region;
- handler->context.region_type = new_region ? new_region->regiontype : (int)RGN_TYPE_WINDOW;
+ handler->context.region_type = new_region ? new_region->regiontype : int(RGN_TYPE_WINDOW);
}
}
}
@@ -4448,7 +4457,7 @@ wmEventHandler_Keymap *WM_event_add_keymap_handler_dynamic(
wmEventHandler_Keymap *WM_event_add_keymap_handler_priority(ListBase *handlers,
wmKeyMap *keymap,
- int UNUSED(priority))
+ int /*priority*/)
{
WM_event_remove_keymap_handler(handlers, keymap);
@@ -4526,7 +4535,7 @@ wmEventHandler_UI *WM_event_add_ui_handler(const bContext *C,
wmUIHandlerFunc handle_fn,
wmUIHandlerRemoveFunc remove_fn,
void *user_data,
- const char flag)
+ const eWM_EventHandlerFlag flag)
{
wmEventHandler_UI *handler = MEM_cnew<wmEventHandler_UI>(__func__);
handler->head.type = WM_HANDLER_TYPE_UI;
@@ -4670,16 +4679,16 @@ void WM_event_add_mousemove(wmWindow *win)
static int convert_key(GHOST_TKey key)
{
if (key >= GHOST_kKeyA && key <= GHOST_kKeyZ) {
- return (EVT_AKEY + ((int)key - GHOST_kKeyA));
+ return (EVT_AKEY + (int(key) - GHOST_kKeyA));
}
if (key >= GHOST_kKey0 && key <= GHOST_kKey9) {
- return (EVT_ZEROKEY + ((int)key - GHOST_kKey0));
+ return (EVT_ZEROKEY + (int(key) - GHOST_kKey0));
}
if (key >= GHOST_kKeyNumpad0 && key <= GHOST_kKeyNumpad9) {
- return (EVT_PAD0 + ((int)key - GHOST_kKeyNumpad0));
+ return (EVT_PAD0 + (int(key) - GHOST_kKeyNumpad0));
}
if (key >= GHOST_kKeyF1 && key <= GHOST_kKeyF24) {
- return (EVT_F1KEY + ((int)key - GHOST_kKeyF1));
+ return (EVT_F1KEY + (int(key) - GHOST_kKeyF1));
}
switch (key) {
@@ -4733,7 +4742,8 @@ static int convert_key(GHOST_TKey key)
return EVT_LEFTCTRLKEY;
case GHOST_kKeyRightControl:
return EVT_RIGHTCTRLKEY;
- case GHOST_kKeyOS:
+ case GHOST_kKeyLeftOS:
+ case GHOST_kKeyRightOS:
return EVT_OSKEY;
case GHOST_kKeyLeftAlt:
return EVT_LEFTALTKEY;
@@ -4821,7 +4831,7 @@ static int convert_key(GHOST_TKey key)
#endif
}
- CLOG_WARN(WM_LOG_EVENTS, "unknown event type %d from ghost", (int)key);
+ CLOG_WARN(WM_LOG_EVENTS, "unknown event type %d from ghost", int(key));
return EVENT_NONE;
}
@@ -4934,7 +4944,7 @@ void WM_event_tablet_data_default_set(wmTabletData *tablet_data)
void wm_tablet_data_from_ghost(const GHOST_TabletData *tablet_data, wmTabletData *wmtab)
{
if ((tablet_data != nullptr) && tablet_data->Active != GHOST_kTabletModeNone) {
- wmtab->active = (int)tablet_data->Active;
+ wmtab->active = int(tablet_data->Active);
wmtab->pressure = wm_pressure_curve(tablet_data->Pressure);
wmtab->x_tilt = tablet_data->Xtilt;
wmtab->y_tilt = tablet_data->Ytilt;
@@ -5461,7 +5471,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
* special handling of Latin1 when building without UTF8 support.
* Avoid regressions by adding this conversions, it should eventually be removed. */
if ((event.utf8_buf[0] >= 0x80) && (event.utf8_buf[1] == '\0')) {
- const uint c = (uint)event.utf8_buf[0];
+ const uint c = uint(event.utf8_buf[0]);
int utf8_buf_len = BLI_str_utf8_from_unicode(c, event.utf8_buf, sizeof(event.utf8_buf));
CLOG_ERROR(WM_LOG_EVENTS,
"ghost detected non-ASCII single byte character '%u', converting to utf8 "
@@ -5475,11 +5485,30 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
if (BLI_str_utf8_size(event.utf8_buf) == -1) {
CLOG_ERROR(WM_LOG_EVENTS,
"ghost detected an invalid unicode character '%d'",
- (int)(unsigned char)event.utf8_buf[0]);
+ int(uchar(event.utf8_buf[0])));
event.utf8_buf[0] = '\0';
}
}
+ /* NOTE(@campbellbarton): Setting the modifier state based on press/release
+ * is technically incorrect.
+ *
+ * - The user might hold both left/right modifier keys, then only release one.
+ *
+ * This could be solved by storing a separate flag for the left/right modifiers,
+ * and combine them into `event.modifiers`.
+ *
+ * - The user might have multiple keyboards (or keyboard + NDOF device)
+ * where it's possible to press the same modifier key multiple times.
+ *
+ * This could be solved by tracking the number of held modifier keys,
+ * (this is in fact what LIBXKB does), however doing this relies on all GHOST
+ * back-ends properly reporting every press/release as any mismatch could result
+ * in modifier keys being stuck (which is very bad!).
+ *
+ * To my knowledge users never reported a bug relating to these limitations so
+ * it seems reasonable to keep the current logic. */
+
switch (event.type) {
case EVT_LEFTSHIFTKEY:
case EVT_RIGHTSHIFTKEY: {
@@ -5591,7 +5620,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
case GHOST_kEventNDOFButton: {
GHOST_TEventNDOFButtonData *e = static_cast<GHOST_TEventNDOFButtonData *>(customdata);
- event.type = NDOF_BUTTON_NONE + e->button;
+ event.type = NDOF_BUTTON_INDEX_AS_EVENT(e->button);
switch (e->action) {
case GHOST_kPress:
@@ -5929,11 +5958,12 @@ void WM_window_cursor_keymap_status_refresh(bContext *C, wmWindow *win)
bToolRef *tref = nullptr;
if ((region->regiontype == RGN_TYPE_WINDOW) &&
((1 << area->spacetype) & WM_TOOLSYSTEM_SPACE_MASK)) {
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
WorkSpace *workspace = WM_window_get_active_workspace(win);
bToolKey tkey{};
tkey.space_type = area->spacetype;
- tkey.mode = WM_toolsystem_mode_from_spacetype(view_layer, area, area->spacetype);
+ tkey.mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, area->spacetype);
tref = WM_toolsystem_ref_find(workspace, &tkey);
}
wm_event_cursor_store(&cd->state, win->eventstate, area->spacetype, region->regiontype, tref);
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index eba3c659368..eee2895d704 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -462,8 +462,8 @@ static void wm_init_userdef(Main *bmain)
/* Update the temporary directory from the preferences or fallback to the system default. */
BKE_tempdir_init(U.tempdir);
- /* Update tablet API preference. */
- WM_init_tablet_api();
+ /* Update input device preference. */
+ WM_init_input_devices();
BLO_sanitize_experimental_features_userpref_blend(&U);
}
@@ -1072,6 +1072,12 @@ void wm_homefile_read_ex(bContext *C,
const bool use_data = params_homefile->use_data;
const bool use_userdef = params_homefile->use_userdef;
bool use_factory_settings = params_homefile->use_factory_settings;
+ /* Currently this only impacts preferences as it doesn't make much sense to keep the default
+ * startup open in the case the app-template doesn't happen to define it's own startup.
+ * Unlike preferences where we might want to only reset the app-template part of the preferences
+ * so as not to reset the preferences for all other Blender instances, see: T96427. */
+ const bool use_factory_settings_app_template_only =
+ params_homefile->use_factory_settings_app_template_only;
const bool use_empty_data = params_homefile->use_empty_data;
const char *filepath_startup_override = params_homefile->filepath_startup_override;
const char *app_template_override = params_homefile->app_template_override;
@@ -1164,12 +1170,10 @@ void wm_homefile_read_ex(bContext *C,
const char *const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL);
if (!use_factory_settings) {
if (cfgdir) {
- BLI_path_join(
- filepath_startup, sizeof(filepath_startup), cfgdir, BLENDER_STARTUP_FILE, NULL);
+ BLI_path_join(filepath_startup, sizeof(filepath_startup), cfgdir, BLENDER_STARTUP_FILE);
filepath_startup_is_factory = false;
if (use_userdef) {
- BLI_path_join(
- filepath_userdef, sizeof(filepath_startup), cfgdir, BLENDER_USERPREF_FILE, NULL);
+ BLI_path_join(filepath_userdef, sizeof(filepath_startup), cfgdir, BLENDER_USERPREF_FILE);
}
}
else {
@@ -1184,7 +1188,11 @@ void wm_homefile_read_ex(bContext *C,
/* load preferences before startup.blend */
if (use_userdef) {
- if (!use_factory_settings && BLI_exists(filepath_userdef)) {
+ if (use_factory_settings_app_template_only) {
+ /* Use the current preferences as-is (only load in the app_template preferences). */
+ skip_flags |= BLO_READ_SKIP_USERDEF;
+ }
+ else if (!use_factory_settings && BLI_exists(filepath_userdef)) {
UserDef *userdef = BKE_blendfile_userdef_read(filepath_userdef, NULL);
if (userdef != NULL) {
BKE_blender_userdef_data_set_and_free(userdef);
@@ -1208,12 +1216,9 @@ void wm_homefile_read_ex(bContext *C,
/* note that the path is being set even when 'use_factory_settings == true'
* this is done so we can load a templates factory-settings */
if (!use_factory_settings) {
- BLI_path_join(app_template_config, sizeof(app_template_config), cfgdir, app_template, NULL);
- BLI_path_join(filepath_startup,
- sizeof(filepath_startup),
- app_template_config,
- BLENDER_STARTUP_FILE,
- NULL);
+ BLI_path_join(app_template_config, sizeof(app_template_config), cfgdir, app_template);
+ BLI_path_join(
+ filepath_startup, sizeof(filepath_startup), app_template_config, BLENDER_STARTUP_FILE);
filepath_startup_is_factory = false;
if (BLI_access(filepath_startup, R_OK) != 0) {
filepath_startup[0] = '\0';
@@ -1224,11 +1229,8 @@ void wm_homefile_read_ex(bContext *C,
}
if (filepath_startup[0] == '\0') {
- BLI_path_join(filepath_startup,
- sizeof(filepath_startup),
- app_template_system,
- BLENDER_STARTUP_FILE,
- NULL);
+ BLI_path_join(
+ filepath_startup, sizeof(filepath_startup), app_template_system, BLENDER_STARTUP_FILE);
filepath_startup_is_factory = true;
/* Update defaults only for system templates. */
@@ -1297,16 +1299,14 @@ void wm_homefile_read_ex(bContext *C,
char temp_path[FILE_MAX];
temp_path[0] = '\0';
if (!use_factory_settings) {
- BLI_path_join(
- temp_path, sizeof(temp_path), app_template_config, BLENDER_USERPREF_FILE, NULL);
+ BLI_path_join(temp_path, sizeof(temp_path), app_template_config, BLENDER_USERPREF_FILE);
if (BLI_access(temp_path, R_OK) != 0) {
temp_path[0] = '\0';
}
}
if (temp_path[0] == '\0') {
- BLI_path_join(
- temp_path, sizeof(temp_path), app_template_system, BLENDER_USERPREF_FILE, NULL);
+ BLI_path_join(temp_path, sizeof(temp_path), app_template_system, BLENDER_USERPREF_FILE);
}
if (use_userdef) {
@@ -1410,7 +1410,7 @@ void wm_history_file_read(void)
LinkNode *l;
int num;
- BLI_join_dirfile(name, sizeof(name), cfgdir, BLENDER_HISTORY_FILE);
+ BLI_path_join(name, sizeof(name), cfgdir, BLENDER_HISTORY_FILE);
LinkNode *lines = BLI_file_read_as_lines(name);
@@ -1473,7 +1473,7 @@ static void wm_history_file_write(void)
return;
}
- BLI_join_dirfile(name, sizeof(name), user_config_dir, BLENDER_HISTORY_FILE);
+ BLI_path_join(name, sizeof(name), user_config_dir, BLENDER_HISTORY_FILE);
fp = BLI_fopen(name, "w");
if (fp) {
@@ -1787,7 +1787,7 @@ static bool wm_file_write(bContext *C,
/* NOTE: Ideally we would call `WM_redraw_windows` here to remove any open menus.
* But we can crash if saving from a script, see T92704 & T97627.
* Just checking `!G.background && BLI_thread_is_main()` is not sufficient to fix this.
- * Additionally some some EGL configurations don't support reading the front-buffer
+ * Additionally some EGL configurations don't support reading the front-buffer
* immediately after drawing, see: T98462. In that case off-screen drawing is necessary. */
/* don't forget not to return without! */
@@ -1842,7 +1842,7 @@ static bool wm_file_write(bContext *C,
ED_editors_flush_edits(bmain);
/* XXX(ton): temp solution to solve bug, real fix coming. */
- bmain->recovered = 0;
+ bmain->recovered = false;
if (BLO_write_file(bmain,
filepath,
@@ -1934,7 +1934,7 @@ static void wm_autosave_location(char filepath[FILE_MAX])
}
#endif
- BLI_join_dirfile(filepath, FILE_MAX, tempdir_base, path);
+ BLI_path_join(filepath, FILE_MAX, tempdir_base, path);
}
static void wm_autosave_write(Main *bmain, wmWindowManager *wm)
@@ -2024,7 +2024,7 @@ void wm_autosave_delete(void)
if (BLI_exists(filepath)) {
char str[FILE_MAX];
- BLI_join_dirfile(str, sizeof(str), BKE_tempdir_base(), BLENDER_QUIT_FILE);
+ BLI_path_join(str, sizeof(str), BKE_tempdir_base(), BLENDER_QUIT_FILE);
/* if global undo; remove tempsave, otherwise rename */
if (U.uiflag & USER_GLOBALUNDO) {
@@ -2039,6 +2039,26 @@ void wm_autosave_delete(void)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Shared Operator Properties
+ * \{ */
+
+/** Use for loading factory startup & preferences. */
+static void read_factory_reset_props(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* So it's possible to reset app-template settings without resetting other defaults. */
+ prop = RNA_def_boolean(ot->srna,
+ "use_factory_startup_app_template_only",
+ false,
+ "Factory Startup App-Template Only",
+ "");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Initialize `WM_OT_open_*` Properties
*
* Check if load_ui was set by the caller.
@@ -2106,7 +2126,7 @@ static int wm_homefile_write_exec(bContext *C, wmOperator *op)
/* update keymaps in user preferences */
WM_keyconfig_update(wm);
- BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_STARTUP_FILE, NULL);
+ BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_STARTUP_FILE);
printf("Writing homefile: '%s' ", filepath);
@@ -2258,19 +2278,23 @@ static int wm_userpref_read_exec(bContext *C, wmOperator *op)
const bool use_data = false;
const bool use_userdef = true;
const bool use_factory_settings = STREQ(op->type->idname, "WM_OT_read_factory_userpref");
+ const bool use_factory_settings_app_template_only =
+ (use_factory_settings && RNA_boolean_get(op->ptr, "use_factory_startup_app_template_only"));
UserDef U_backup = U;
- wm_homefile_read(C,
- &(const struct wmHomeFileRead_Params){
- .use_data = use_data,
- .use_userdef = use_userdef,
- .use_factory_settings = use_factory_settings,
- .use_empty_data = false,
- .filepath_startup_override = NULL,
- .app_template_override = WM_init_state_app_template_get(),
- },
- op->reports);
+ wm_homefile_read(
+ C,
+ &(const struct wmHomeFileRead_Params){
+ .use_data = use_data,
+ .use_userdef = use_userdef,
+ .use_factory_settings = use_factory_settings,
+ .use_factory_settings_app_template_only = use_factory_settings_app_template_only,
+ .use_empty_data = false,
+ .filepath_startup_override = NULL,
+ .app_template_override = WM_init_state_app_template_get(),
+ },
+ op->reports);
wm_userpref_read_exceptions(&U, &U_backup);
SET_FLAG_FROM_TEST(G.f, use_factory_settings, G_FLAG_USERPREF_NO_SAVE_ON_EXIT);
@@ -2311,6 +2335,8 @@ void WM_OT_read_factory_userpref(wmOperatorType *ot)
ot->invoke = WM_operator_confirm;
ot->exec = wm_userpref_read_exec;
+
+ read_factory_reset_props(ot);
}
/** \} */
@@ -2353,6 +2379,10 @@ static int wm_homefile_read_exec(bContext *C, wmOperator *op)
"WM_OT_read_factory_settings");
const bool use_factory_settings = use_factory_startup_and_userdef ||
RNA_boolean_get(op->ptr, "use_factory_startup");
+ const bool use_factory_settings_app_template_only =
+ (use_factory_startup_and_userdef &&
+ RNA_boolean_get(op->ptr, "use_factory_startup_app_template_only"));
+
bool use_userdef = false;
char filepath_buf[FILE_MAX];
const char *filepath = NULL;
@@ -2409,16 +2439,18 @@ static int wm_homefile_read_exec(bContext *C, wmOperator *op)
app_template = WM_init_state_app_template_get();
}
- wm_homefile_read(C,
- &(const struct wmHomeFileRead_Params){
- .use_data = true,
- .use_userdef = use_userdef,
- .use_factory_settings = use_factory_settings,
- .use_empty_data = use_empty_data,
- .filepath_startup_override = filepath,
- .app_template_override = app_template,
- },
- op->reports);
+ wm_homefile_read(
+ C,
+ &(const struct wmHomeFileRead_Params){
+ .use_data = true,
+ .use_userdef = use_userdef,
+ .use_factory_settings = use_factory_settings,
+ .use_factory_settings_app_template_only = use_factory_settings_app_template_only,
+ .use_empty_data = use_empty_data,
+ .filepath_startup_override = filepath,
+ .app_template_override = app_template,
+ },
+ op->reports);
if (use_splash) {
WM_init_splash(C);
@@ -2493,6 +2525,7 @@ void WM_OT_read_homefile(wmOperatorType *ot)
* Match naming for `--factory-startup` command line argument. */
prop = RNA_def_boolean(ot->srna, "use_factory_startup", false, "Factory Startup", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ read_factory_reset_props(ot);
read_homefile_props(ot);
@@ -2509,9 +2542,11 @@ void WM_OT_read_factory_settings(wmOperatorType *ot)
ot->invoke = WM_operator_confirm;
ot->exec = wm_homefile_read_exec;
+ /* Omit poll to run in background mode. */
+
+ read_factory_reset_props(ot);
read_homefile_props(ot);
- /* omit poll to run in background mode */
}
/** \} */
@@ -2884,7 +2919,7 @@ void WM_OT_revert_mainfile(wmOperatorType *ot)
bool WM_file_recover_last_session(bContext *C, ReportList *reports)
{
char filepath[FILE_MAX];
- BLI_join_dirfile(filepath, sizeof(filepath), BKE_tempdir_base(), BLENDER_QUIT_FILE);
+ BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_base(), BLENDER_QUIT_FILE);
G.fileflags |= G_FILE_RECOVER_READ;
const bool success = wm_file_read_opwrap(C, filepath, reports);
G.fileflags &= ~G_FILE_RECOVER_READ;
diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c
index f2c41dada48..bbe53bf7355 100644
--- a/source/blender/windowmanager/intern/wm_files_link.c
+++ b/source/blender/windowmanager/intern/wm_files_link.c
@@ -210,7 +210,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "filename", relname);
RNA_string_get(op->ptr, "directory", root);
- BLI_join_dirfile(path, sizeof(path), root, relname);
+ BLI_path_join(path, sizeof(path), root, relname);
/* test if we have a valid data */
if (!BLO_library_path_explode(path, libname, &group, &name)) {
@@ -258,7 +258,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
/* from here down, no error returns */
if (view_layer && RNA_boolean_get(op->ptr, "autoselect")) {
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
}
/* tag everything, all untagged data can be made local
@@ -284,7 +284,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
RNA_BEGIN (op->ptr, itemptr, "files") {
RNA_string_get(&itemptr, "name", relname);
- BLI_join_dirfile(path, sizeof(path), root, relname);
+ BLI_path_join(path, sizeof(path), root, relname);
if (BLO_library_path_explode(path, libname, &group, &name)) {
if (!wm_link_append_item_poll(NULL, path, group, name, do_append)) {
@@ -303,7 +303,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
RNA_BEGIN (op->ptr, itemptr, "files") {
RNA_string_get(&itemptr, "name", relname);
- BLI_join_dirfile(path, sizeof(path), root, relname);
+ BLI_path_join(path, sizeof(path), root, relname);
if (BLO_library_path_explode(path, libname, &group, &name)) {
BlendfileLinkAppendContextItem *item;
@@ -683,7 +683,7 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload)
return OPERATOR_CANCELLED;
}
- BLI_join_dirfile(path, sizeof(path), root, libname);
+ BLI_path_join(path, sizeof(path), root, libname);
if (!BLI_exists(path)) {
BKE_reportf(op->reports,
@@ -739,7 +739,7 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload)
RNA_BEGIN (op->ptr, itemptr, "files") {
RNA_string_get(&itemptr, "name", relname);
- BLI_join_dirfile(path, sizeof(path), root, relname);
+ BLI_path_join(path, sizeof(path), root, relname);
if (BLI_path_cmp(path, lib->filepath_abs) == 0 || !BLO_has_bfile_extension(relname)) {
continue;
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index 2bc1fb1519a..88a292477cf 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -275,14 +275,14 @@ static void wm_gesture_draw_circle(wmGesture *gt)
}
struct LassoFillData {
- unsigned char *px;
+ uchar *px;
int width;
};
static void draw_filled_lasso_px_cb(int x, int x_end, int y, void *user_data)
{
struct LassoFillData *data = user_data;
- unsigned char *col = &(data->px[(y * data->width) + x]);
+ uchar *col = &(data->px[(y * data->width) + x]);
memset(col, 0x10, x_end - x);
}
@@ -310,7 +310,7 @@ static void draw_filled_lasso(wmGesture *gt)
if (BLI_rcti_is_empty(&rect) == false) {
const int w = BLI_rcti_size_x(&rect);
const int h = BLI_rcti_size_y(&rect);
- unsigned char *pixel_buf = MEM_callocN(sizeof(*pixel_buf) * w * h, __func__);
+ uchar *pixel_buf = MEM_callocN(sizeof(*pixel_buf) * w * h, __func__);
struct LassoFillData lasso_fill_data = {pixel_buf, w};
BLI_bitmap_draw_2d_poly_v2i_n(rect.xmin,
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 7ab2e67e4b6..c5d7152246c 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -310,9 +310,6 @@ void WM_init(bContext *C, int argc, const char **argv)
/* For file-system. Called here so can include user preference paths if needed. */
ED_file_init();
- /* That one is generated on demand, we need to be sure it's clear on init. */
- IMB_thumb_clear_translations();
-
if (!G.background) {
GPU_render_begin();
@@ -450,14 +447,14 @@ void WM_exit_ex(bContext *C, const bool do_python)
bool has_edited;
const int fileflags = G.fileflags & ~G_FILE_COMPRESS;
- BLI_join_dirfile(filepath, sizeof(filepath), BKE_tempdir_base(), BLENDER_QUIT_FILE);
+ BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_base(), BLENDER_QUIT_FILE);
has_edited = ED_editors_flush_edits(bmain);
if ((has_edited &&
BLO_write_file(
bmain, filepath, fileflags, &(const struct BlendFileWriteParams){0}, NULL)) ||
- (BLO_memfile_write_file(undo_memfile, filepath))) {
+ BLO_memfile_write_file(undo_memfile, filepath)) {
printf("Saved session recovery to '%s'\n", filepath);
}
}
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c
index d5c4d07e9ed..fcfc83312b8 100644
--- a/source/blender/windowmanager/intern/wm_jobs.c
+++ b/source/blender/windowmanager/intern/wm_jobs.c
@@ -104,12 +104,14 @@ struct wmJob {
/** Only start job after specified time delay */
double start_delay_time;
/** The notifier event timers should send */
- unsigned int note, endnote;
+ uint note, endnote;
/* internal */
const void *owner;
- int flag;
- short suspended, running, ready, do_update, stop, job_type;
+ eWM_JobFlag flag;
+ bool suspended, running, ready;
+ eWM_JobType job_type;
+ bool do_update, stop;
float progress;
/** For display in header, identification */
@@ -152,9 +154,9 @@ static void wm_job_main_thread_yield(wmJob *wm_job)
/**
* Finds if type or owner, compare for it, otherwise any matching job.
*/
-static wmJob *wm_job_find(const wmWindowManager *wm, const void *owner, const int job_type)
+static wmJob *wm_job_find(const wmWindowManager *wm, const void *owner, const eWM_JobType job_type)
{
- if (owner && job_type) {
+ if (owner && (job_type != WM_JOB_TYPE_ANY)) {
LISTBASE_FOREACH (wmJob *, wm_job, &wm->jobs) {
if (wm_job->owner == owner && wm_job->job_type == job_type) {
return wm_job;
@@ -168,7 +170,7 @@ static wmJob *wm_job_find(const wmWindowManager *wm, const void *owner, const in
}
}
}
- else if (job_type) {
+ else if (job_type != WM_JOB_TYPE_ANY) {
LISTBASE_FOREACH (wmJob *, wm_job, &wm->jobs) {
if (wm_job->job_type == job_type) {
return wm_job;
@@ -185,8 +187,8 @@ wmJob *WM_jobs_get(wmWindowManager *wm,
wmWindow *win,
const void *owner,
const char *name,
- int flag,
- int job_type)
+ const eWM_JobFlag flag,
+ const eWM_JobType job_type)
{
wmJob *wm_job = wm_job_find(wm, owner, job_type);
@@ -336,7 +338,7 @@ void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void (*free)(void *
}
}
-void WM_jobs_timer(wmJob *wm_job, double timestep, unsigned int note, unsigned int endnote)
+void WM_jobs_timer(wmJob *wm_job, double timestep, uint note, uint endnote)
{
wm_job->timestep = timestep;
wm_job->note = note;
@@ -593,7 +595,7 @@ void WM_jobs_stop(wmWindowManager *wm, const void *owner, void *startjob)
void WM_jobs_kill(wmWindowManager *wm,
void *owner,
- void (*startjob)(void *, short int *, short int *, float *))
+ void (*startjob)(void *, bool *, bool *, float *))
{
LISTBASE_FOREACH_MUTABLE (wmJob *, wm_job, &wm->jobs) {
if (wm_job->owner == owner || wm_job->startjob == startjob) {
diff --git a/source/blender/windowmanager/intern/wm_operator_props.c b/source/blender/windowmanager/intern/wm_operator_props.c
index 71c948dfbb9..bd3322a8023 100644
--- a/source/blender/windowmanager/intern/wm_operator_props.c
+++ b/source/blender/windowmanager/intern/wm_operator_props.c
@@ -120,16 +120,14 @@ void WM_operator_properties_filesel(wmOperatorType *ot,
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
- if (action == FILE_SAVE) {
- /* NOTE: this is only used to check if we should highlight the filename area red when the
- * filepath is an existing file. */
- prop = RNA_def_boolean(ot->srna,
- "check_existing",
- true,
- "Check Existing",
- "Check and warn on overwriting existing files");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- }
+ /* NOTE: this is only used to check if we should highlight the filename area red when the
+ * filepath is an existing file. */
+ prop = RNA_def_boolean(ot->srna,
+ "check_existing",
+ action == FILE_SAVE,
+ "Check Existing",
+ "Check and warn on overwriting existing files");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
prop = RNA_def_boolean(
ot->srna, "filter_blender", (filter & FILE_TYPE_BLENDER) != 0, "Filter .blend files", "");
diff --git a/source/blender/windowmanager/intern/wm_operator_type.c b/source/blender/windowmanager/intern/wm_operator_type.c
index d1c27504628..1da8159df13 100644
--- a/source/blender/windowmanager/intern/wm_operator_type.c
+++ b/source/blender/windowmanager/intern/wm_operator_type.c
@@ -235,8 +235,8 @@ void WM_operatortype_last_properties_clear_all(void)
{
GHashIterator iter;
- for (WM_operatortype_iter(&iter); (!BLI_ghashIterator_done(&iter));
- (BLI_ghashIterator_step(&iter))) {
+ for (WM_operatortype_iter(&iter); !BLI_ghashIterator_done(&iter);
+ BLI_ghashIterator_step(&iter)) {
wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
if (ot->last_properties) {
diff --git a/source/blender/windowmanager/intern/wm_operator_utils.c b/source/blender/windowmanager/intern/wm_operator_utils.c
index bde072bf000..6fc9300926c 100644
--- a/source/blender/windowmanager/intern/wm_operator_utils.c
+++ b/source/blender/windowmanager/intern/wm_operator_utils.c
@@ -209,10 +209,11 @@ static int op_generic_value_invoke(bContext *C, wmOperator *op, const wmEvent *e
return WM_operator_call_notest(C, op);
}
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
if (objects_len == 0) {
MEM_freeN(objects);
return OPERATOR_CANCELLED;
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 18b5461383f..fa89e7a4caa 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -107,19 +107,32 @@
/** \name Operator API
* \{ */
+#define OP_BL_SEP_STRING "_OT_"
+#define OP_BL_SEP_LEN 4
+
+#define OP_PY_SEP_CHAR '.'
+#define OP_PY_SEP_LEN 1
+
+/* Difference between python 'identifier' and BL/C code one ("." separator replaced by "_OT_"),
+ * and final `\0` char. */
+#define OP_MAX_PY_IDNAME (OP_MAX_TYPENAME - OP_BL_SEP_LEN + OP_PY_SEP_LEN - 1)
+
size_t WM_operator_py_idname(char *dst, const char *src)
{
- const char *sep = strstr(src, "_OT_");
+ const char *sep = strstr(src, OP_BL_SEP_STRING);
if (sep) {
- int ofs = (sep - src);
+ const size_t sep_offset = (size_t)(sep - src);
/* NOTE: we use ascii `tolower` instead of system `tolower`, because the
* latter depends on the locale, and can lead to `idname` mismatch. */
- memcpy(dst, src, sizeof(char) * ofs);
- BLI_str_tolower_ascii(dst, ofs);
+ memcpy(dst, src, sep_offset);
+ BLI_str_tolower_ascii(dst, sep_offset);
- dst[ofs] = '.';
- return BLI_strncpy_rlen(dst + (ofs + 1), sep + 4, OP_MAX_TYPENAME - (ofs + 1)) + (ofs + 1);
+ dst[sep_offset] = OP_PY_SEP_CHAR;
+ return BLI_strncpy_rlen(dst + (sep_offset + OP_PY_SEP_LEN),
+ sep + OP_BL_SEP_LEN,
+ OP_MAX_TYPENAME - sep_offset - OP_PY_SEP_LEN) +
+ (sep_offset + OP_PY_SEP_LEN);
}
/* Should not happen but support just in case. */
return BLI_strncpy_rlen(dst, src, OP_MAX_TYPENAME);
@@ -127,15 +140,19 @@ size_t WM_operator_py_idname(char *dst, const char *src)
size_t WM_operator_bl_idname(char *dst, const char *src)
{
- const char *sep = strchr(src, '.');
- int from_len;
- if (sep && (from_len = strlen(src)) < OP_MAX_TYPENAME - 3) {
- const int ofs = (sep - src);
- memcpy(dst, src, sizeof(char) * ofs);
- BLI_str_toupper_ascii(dst, ofs);
- memcpy(dst + ofs, "_OT_", 4);
- memcpy(dst + (ofs + 4), sep + 1, (from_len - ofs));
- return (from_len - ofs) - 1;
+ const size_t from_len = (size_t)strlen(src);
+
+ const char *sep = strchr(src, OP_PY_SEP_CHAR);
+ if (sep && (from_len <= OP_MAX_PY_IDNAME)) {
+ const size_t sep_offset = (size_t)(sep - src);
+ memcpy(dst, src, sep_offset);
+ BLI_str_toupper_ascii(dst, sep_offset);
+
+ memcpy(dst + sep_offset, OP_BL_SEP_STRING, OP_BL_SEP_LEN);
+ BLI_strncpy(dst + sep_offset + OP_BL_SEP_LEN,
+ sep + OP_PY_SEP_LEN,
+ from_len - sep_offset - OP_PY_SEP_LEN + 1);
+ return from_len + OP_BL_SEP_LEN - OP_PY_SEP_LEN;
}
/* Should not happen but support just in case. */
return BLI_strncpy_rlen(dst, src, OP_MAX_TYPENAME);
@@ -166,14 +183,14 @@ bool WM_operator_py_idname_ok_or_report(ReportList *reports,
}
}
- if (i > (MAX_NAME - 3)) {
+ if (i > OP_MAX_PY_IDNAME) {
BKE_reportf(reports,
RPT_ERROR,
"Registering operator class: '%s', invalid bl_idname '%s', "
"is too long, maximum length is %d",
classname,
idname,
- MAX_NAME - 3);
+ OP_MAX_PY_IDNAME);
return false;
}
@@ -2521,7 +2538,7 @@ static void radial_control_paint_cursor(bContext *UNUSED(C), int x, int y, void
immUnbindProgram();
- BLF_size(fontid, 1.75f * fstyle_points * U.pixelsize, U.dpi);
+ BLF_size(fontid, 1.75f * fstyle_points * U.dpi_fac);
UI_GetThemeColor4fv(TH_TEXT_HI, text_color);
BLF_color4fv(fontid, text_color);
@@ -2740,7 +2757,7 @@ static int radial_control_invoke(bContext *C, wmOperator *op, const wmEvent *eve
}
/* get type, initial, min, and max values of the property */
- switch ((rc->type = RNA_property_type(rc->prop))) {
+ switch (rc->type = RNA_property_type(rc->prop)) {
case PROP_INT: {
int value, min, max, step;
@@ -3673,7 +3690,7 @@ static void WM_OT_doc_view_manual_ui_context(wmOperatorType *ot)
/* -------------------------------------------------------------------- */
/** \name Toggle Stereo 3D Operator
*
- * Turning it fullscreen if needed.
+ * Turning it full-screen if needed.
* \{ */
static void WM_OT_stereo3d_set(wmOperatorType *ot)
@@ -3805,7 +3822,7 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf)
/* WARNING: Name is incorrect, use for non-3d views. */
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "View3D Gesture Circle");
- /* this function is called for each spacetype, only needs to add map once */
+ /* This function is called for each space-type, only needs to add map once. */
if (keymap && keymap->modal_items) {
return;
}
@@ -3838,7 +3855,7 @@ static void gesture_straightline_modal_keymap(wmKeyConfig *keyconf)
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Gesture Straight Line");
- /* this function is called for each spacetype, only needs to add map once */
+ /* This function is called for each space-type, only needs to add map once. */
if (keymap && keymap->modal_items) {
return;
}
@@ -3867,7 +3884,7 @@ static void gesture_box_modal_keymap(wmKeyConfig *keyconf)
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Gesture Box");
- /* this function is called for each spacetype, only needs to add map once */
+ /* This function is called for each space-type, only needs to add map once. */
if (keymap && keymap->modal_items) {
return;
}
@@ -3920,7 +3937,7 @@ static void gesture_lasso_modal_keymap(wmKeyConfig *keyconf)
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Gesture Lasso");
- /* this function is called for each spacetype, only needs to add map once */
+ /* This function is called for each space-type, only needs to add map once. */
if (keymap && keymap->modal_items) {
return;
}
@@ -3955,7 +3972,7 @@ static void gesture_zoom_border_modal_keymap(wmKeyConfig *keyconf)
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Gesture Zoom Border");
- /* this function is called for each spacetype, only needs to add map once */
+ /* This function is called for each space-type, only needs to add map once. */
if (keymap && keymap->modal_items) {
return;
}
diff --git a/source/blender/windowmanager/intern/wm_platform_support.c b/source/blender/windowmanager/intern/wm_platform_support.c
index a0519506d29..ee93621545f 100644
--- a/source/blender/windowmanager/intern/wm_platform_support.c
+++ b/source/blender/windowmanager/intern/wm_platform_support.c
@@ -42,7 +42,7 @@ static bool wm_platform_support_check_approval(const char *platform_support_key,
bool result = false;
char filepath[FILE_MAX];
- BLI_join_dirfile(filepath, sizeof(filepath), cfgdir, BLENDER_PLATFORM_SUPPORT_FILE);
+ BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_PLATFORM_SUPPORT_FILE);
LinkNode *lines = BLI_file_read_as_lines(filepath);
for (LinkNode *line_node = lines; line_node; line_node = line_node->next) {
char *line = line_node->link;
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index 60f3842bc7c..3e5399a6f56 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -59,6 +59,8 @@
#include "DEG_depsgraph.h"
+#include "wm_window_private.h"
+
#include "WM_api.h" /* only for WM_main_playanim */
#ifdef WITH_AUDASPACE
@@ -659,7 +661,7 @@ static void build_pict_list_ex(
int fp_framenr;
struct {
char head[FILE_MAX], tail[FILE_MAX];
- unsigned short digits;
+ ushort digits;
} fp_decoded;
char filepath[FILE_MAX];
@@ -1340,6 +1342,8 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
static void playanim_window_open(const char *title, int posx, int posy, int sizex, int sizey)
{
GHOST_GLSettings glsettings = {0};
+ const eGPUBackendType gpu_backend = GPU_backend_type_selection_get();
+ glsettings.context_type = wm_ghost_drawing_context_type(gpu_backend);
uint32_t scr_w, scr_h;
GHOST_GetMainDisplayDimensions(g_WS.ghost_system, &scr_w, &scr_h);
@@ -1353,10 +1357,9 @@ static void playanim_window_open(const char *title, int posx, int posy, int size
posy,
sizex,
sizey,
- /* could optionally start fullscreen */
+ /* Could optionally start full-screen. */
GHOST_kWindowStateNormal,
false,
- GHOST_kDrawingContextTypeOpenGL,
glsettings);
}
@@ -1539,6 +1542,14 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
GHOST_SetBacktraceHandler((GHOST_TBacktraceFn)BLI_system_backtrace);
g_WS.ghost_system = GHOST_CreateSystem();
+
+ if (UNLIKELY(g_WS.ghost_system == NULL)) {
+ /* GHOST will have reported the back-ends that failed to load. */
+ fprintf(stderr, "GHOST: unable to initialize, exiting!\n");
+ /* This will leak memory, it's preferable to crashing. */
+ exit(1);
+ }
+
GHOST_AddEventConsumer(g_WS.ghost_system, consumer);
playanim_window_open("Blender Animation Player", start_x, start_y, ibuf->x, ibuf->y);
@@ -1549,14 +1560,14 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
// GHOST_ActivateWindowDrawingContext(g_WS.ghost_window);
/* initialize OpenGL immediate mode */
- g_WS.gpu_context = GPU_context_create(g_WS.ghost_window);
+ g_WS.gpu_context = GPU_context_create(g_WS.ghost_window, NULL);
GPU_init();
/* initialize the font */
BLF_init();
BLF_load_font_stack();
ps.fontid = BLF_load_mono_default(false);
- BLF_size(ps.fontid, 11.0f, 72);
+ BLF_size(ps.fontid, 11.0f);
ps.ibufx = ibuf->x;
ps.ibufy = ibuf->y;
diff --git a/source/blender/windowmanager/intern/wm_splash_screen.c b/source/blender/windowmanager/intern/wm_splash_screen.c
index 8fca3deef92..16e5f983bea 100644
--- a/source/blender/windowmanager/intern/wm_splash_screen.c
+++ b/source/blender/windowmanager/intern/wm_splash_screen.c
@@ -140,7 +140,7 @@ static ImBuf *wm_block_splash_image(int width, int *r_height)
char template_directory[FILE_MAX];
if (BKE_appdir_app_template_id_search(
U.app_template, template_directory, sizeof(template_directory))) {
- BLI_join_dirfile(splash_filepath, sizeof(splash_filepath), template_directory, "splash.png");
+ BLI_path_join(splash_filepath, sizeof(splash_filepath), template_directory, "splash.png");
ibuf = IMB_loadiffname(splash_filepath, IB_rect, NULL);
}
}
@@ -218,7 +218,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *region, void *UNUSE
const char *const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL);
if (cfgdir) {
- BLI_path_join(userpref, sizeof(userpref), cfgdir, BLENDER_USERPREF_FILE, NULL);
+ BLI_path_join(userpref, sizeof(userpref), cfgdir, BLENDER_USERPREF_FILE);
}
/* Draw setup screen if no preferences have been saved yet. */
diff --git a/source/blender/windowmanager/intern/wm_toolsystem.c b/source/blender/windowmanager/intern/wm_toolsystem.c
index a3aaef6af31..6e08f607bae 100644
--- a/source/blender/windowmanager/intern/wm_toolsystem.c
+++ b/source/blender/windowmanager/intern/wm_toolsystem.c
@@ -58,6 +58,7 @@ static void toolsystem_refresh_screen_from_active_tool(Main *bmain,
struct bToolRef *WM_toolsystem_ref_from_context(struct bContext *C)
{
WorkSpace *workspace = CTX_wm_workspace(C);
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
ScrArea *area = CTX_wm_area(C);
if ((area == NULL) || ((1 << area->spacetype) & WM_TOOLSYSTEM_SPACE_MASK) == 0) {
@@ -65,7 +66,7 @@ struct bToolRef *WM_toolsystem_ref_from_context(struct bContext *C)
}
const bToolKey tkey = {
.space_type = area->spacetype,
- .mode = WM_toolsystem_mode_from_spacetype(view_layer, area, area->spacetype),
+ .mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, area->spacetype),
};
bToolRef *tref = WM_toolsystem_ref_find(workspace, &tkey);
/* We could return 'area->runtime.tool' in this case. */
@@ -269,6 +270,7 @@ void WM_toolsystem_refresh_all(struct bContext *C, struct WorkSpace *workspace)
void WM_toolsystem_reinit_all(struct bContext *C, wmWindow *win)
{
bScreen *screen = WM_window_get_active_screen(win);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
if (((1 << area->spacetype) & WM_TOOLSYSTEM_SPACE_MASK) == 0) {
@@ -278,7 +280,7 @@ void WM_toolsystem_reinit_all(struct bContext *C, wmWindow *win)
WorkSpace *workspace = WM_window_get_active_workspace(win);
const bToolKey tkey = {
.space_type = area->spacetype,
- .mode = WM_toolsystem_mode_from_spacetype(view_layer, area, area->spacetype),
+ .mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, area->spacetype),
};
bToolRef *tref = WM_toolsystem_ref_find(workspace, &tkey);
if (tref) {
@@ -367,7 +369,8 @@ void WM_toolsystem_ref_sync_from_context(Main *bmain, WorkSpace *workspace, bToo
Scene *scene = WM_window_get_active_scene(win);
ToolSettings *ts = scene->toolsettings;
- const ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ BKE_view_layer_synced_ensure(scene, view_layer);
const Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ob == NULL) {
/* pass */
@@ -438,12 +441,16 @@ static bool toolsystem_key_ensure_check(const bToolKey *tkey)
return false;
}
-int WM_toolsystem_mode_from_spacetype(ViewLayer *view_layer, ScrArea *area, int space_type)
+int WM_toolsystem_mode_from_spacetype(const Scene *scene,
+ ViewLayer *view_layer,
+ ScrArea *area,
+ int space_type)
{
int mode = -1;
switch (space_type) {
case SPACE_VIEW3D: {
/* 'area' may be NULL in this case. */
+ BKE_view_layer_synced_ensure(scene, view_layer);
Object *obact = BKE_view_layer_active_object_get(view_layer);
if (obact != NULL) {
Object *obedit = OBEDIT_FROM_OBACT(obact);
@@ -472,14 +479,17 @@ int WM_toolsystem_mode_from_spacetype(ViewLayer *view_layer, ScrArea *area, int
return mode;
}
-bool WM_toolsystem_key_from_context(ViewLayer *view_layer, ScrArea *area, bToolKey *tkey)
+bool WM_toolsystem_key_from_context(const Scene *scene,
+ ViewLayer *view_layer,
+ ScrArea *area,
+ bToolKey *tkey)
{
int space_type = SPACE_EMPTY;
int mode = -1;
if (area != NULL) {
space_type = area->spacetype;
- mode = WM_toolsystem_mode_from_spacetype(view_layer, area, space_type);
+ mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, space_type);
}
if (mode != -1) {
@@ -505,6 +515,7 @@ void WM_toolsystem_refresh_active(bContext *C)
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
WorkSpace *workspace = WM_window_get_active_workspace(win);
bScreen *screen = WM_window_get_active_screen(win);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
/* Could skip loop for modes that don't depend on space type. */
int space_type_mask_handled = 0;
@@ -516,7 +527,7 @@ void WM_toolsystem_refresh_active(bContext *C)
space_type_mask_handled |= space_type_mask;
const bToolKey tkey = {
.space_type = area->spacetype,
- .mode = WM_toolsystem_mode_from_spacetype(view_layer, area, area->spacetype),
+ .mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, area->spacetype),
};
bToolRef *tref = WM_toolsystem_ref_find(workspace, &tkey);
if (tref != area->runtime.tool) {
@@ -558,11 +569,14 @@ void WM_toolsystem_refresh_active(bContext *C)
}
}
-void WM_toolsystem_refresh_screen_area(WorkSpace *workspace, ViewLayer *view_layer, ScrArea *area)
+void WM_toolsystem_refresh_screen_area(WorkSpace *workspace,
+ const Scene *scene,
+ ViewLayer *view_layer,
+ ScrArea *area)
{
area->runtime.tool = NULL;
area->runtime.is_tool_set = true;
- const int mode = WM_toolsystem_mode_from_spacetype(view_layer, area, area->spacetype);
+ const int mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, area->spacetype);
LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) {
if (tref->space_type == area->spacetype) {
if (tref->mode == mode) {
@@ -581,12 +595,13 @@ void WM_toolsystem_refresh_screen_window(wmWindow *win)
space_type_has_tools[tref->space_type] = true;
}
bScreen *screen = WM_window_get_active_screen(win);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
area->runtime.tool = NULL;
area->runtime.is_tool_set = true;
if (space_type_has_tools[area->spacetype]) {
- WM_toolsystem_refresh_screen_area(workspace, view_layer, area);
+ WM_toolsystem_refresh_screen_area(workspace, scene, view_layer, area);
}
}
}
@@ -610,10 +625,11 @@ static void toolsystem_refresh_screen_from_active_tool(Main *bmain,
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
if (workspace == WM_window_get_active_workspace(win)) {
bScreen *screen = WM_window_get_active_screen(win);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
if (area->spacetype == tref->space_type) {
- int mode = WM_toolsystem_mode_from_spacetype(view_layer, area, area->spacetype);
+ int mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, area->spacetype);
if (mode == tref->mode) {
area->runtime.tool = tref;
area->runtime.is_tool_set = true;
@@ -668,10 +684,11 @@ bToolRef *WM_toolsystem_ref_set_by_id_ex(
bToolRef *WM_toolsystem_ref_set_by_id(bContext *C, const char *name)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
ScrArea *area = CTX_wm_area(C);
bToolKey tkey;
- if (WM_toolsystem_key_from_context(view_layer, area, &tkey)) {
+ if (WM_toolsystem_key_from_context(scene, view_layer, area, &tkey)) {
WorkSpace *workspace = CTX_wm_workspace(C);
return WM_toolsystem_ref_set_by_id_ex(C, workspace, &tkey, name, false);
}
@@ -761,11 +778,12 @@ static bToolRef *toolsystem_reinit_ensure_toolref(bContext *C,
static void wm_toolsystem_update_from_context_view3d_impl(bContext *C, WorkSpace *workspace)
{
+ const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
int space_type = SPACE_VIEW3D;
const bToolKey tkey = {
.space_type = space_type,
- .mode = WM_toolsystem_mode_from_spacetype(view_layer, NULL, space_type),
+ .mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, NULL, space_type),
};
toolsystem_reinit_ensure_toolref(C, workspace, &tkey, NULL);
}
@@ -801,14 +819,12 @@ void WM_toolsystem_update_from_context_view3d(bContext *C)
}
}
-void WM_toolsystem_update_from_context(bContext *C,
- WorkSpace *workspace,
- ViewLayer *view_layer,
- ScrArea *area)
+void WM_toolsystem_update_from_context(
+ bContext *C, WorkSpace *workspace, const Scene *scene, ViewLayer *view_layer, ScrArea *area)
{
const bToolKey tkey = {
.space_type = area->spacetype,
- .mode = WM_toolsystem_mode_from_spacetype(view_layer, area, area->spacetype),
+ .mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, area->spacetype),
};
if (toolsystem_key_ensure_check(&tkey)) {
toolsystem_reinit_ensure_toolref(C, workspace, &tkey, NULL);
@@ -838,14 +854,15 @@ void WM_toolsystem_do_msg_notify_tag_refresh(bContext *C,
}
WorkSpace *workspace = WM_window_get_active_workspace(win);
+ const Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
const bToolKey tkey = {
.space_type = area->spacetype,
- .mode = WM_toolsystem_mode_from_spacetype(view_layer, area, area->spacetype),
+ .mode = WM_toolsystem_mode_from_spacetype(scene, view_layer, area, area->spacetype),
};
WM_toolsystem_refresh(C, workspace, &tkey);
- WM_toolsystem_refresh_screen_area(workspace, view_layer, area);
+ WM_toolsystem_refresh_screen_area(workspace, scene, view_layer, area);
}
static IDProperty *idprops_ensure_named_group(IDProperty *group, const char *idname)
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index b428fd65e7f..265aa08a6b1 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -91,6 +91,9 @@
/* the global to talk to ghost */
static GHOST_SystemHandle g_system = NULL;
+#if !(defined(WIN32) || defined(__APPLE__))
+static const char *g_system_backend_id = NULL;
+#endif
typedef enum eWinOverrideFlag {
WIN_OVERRIDE_GEOM = (1 << 0),
@@ -120,6 +123,36 @@ static struct WMInitStruct {
};
/* -------------------------------------------------------------------- */
+/** \name Modifier Constants
+ * \{ */
+
+static const struct {
+ uint8_t flag;
+ GHOST_TKey ghost_key_pair[2];
+ GHOST_TModifierKey ghost_mask_pair[2];
+} g_modifier_table[] = {
+ {KM_SHIFT,
+ {GHOST_kKeyLeftShift, GHOST_kKeyRightShift},
+ {GHOST_kModifierKeyLeftShift, GHOST_kModifierKeyRightShift}},
+ {KM_CTRL,
+ {GHOST_kKeyLeftControl, GHOST_kKeyRightControl},
+ {GHOST_kModifierKeyLeftControl, GHOST_kModifierKeyRightControl}},
+ {KM_ALT,
+ {GHOST_kKeyLeftAlt, GHOST_kKeyRightAlt},
+ {GHOST_kModifierKeyLeftAlt, GHOST_kModifierKeyRightAlt}},
+ {KM_OSKEY,
+ {GHOST_kKeyLeftOS, GHOST_kKeyRightOS},
+ {GHOST_kModifierKeyLeftOS, GHOST_kModifierKeyRightOS}},
+};
+
+enum ModSide {
+ MOD_SIDE_LEFT = 0,
+ MOD_SIDE_RIGHT = 1,
+};
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Window Open & Close
* \{ */
@@ -128,8 +161,8 @@ static bool wm_window_timer(const bContext *C);
void wm_get_screensize(int *r_width, int *r_height)
{
- unsigned int uiwidth;
- unsigned int uiheight;
+ uint uiwidth;
+ uint uiheight;
GHOST_GetMainDisplayDimensions(g_system, &uiwidth, &uiheight);
*r_width = uiwidth;
@@ -138,8 +171,8 @@ void wm_get_screensize(int *r_width, int *r_height)
void wm_get_desktopsize(int *r_width, int *r_height)
{
- unsigned int uiwidth;
- unsigned int uiheight;
+ uint uiwidth;
+ uint uiheight;
GHOST_GetAllDisplayDimensions(g_system, &uiwidth, &uiheight);
*r_width = uiwidth;
@@ -473,27 +506,22 @@ void WM_window_set_dpi(const wmWindow *win)
* while Windows and Linux use DPI 96. GHOST assumes a default 96 so we
* remap the DPI to Blender's convention. */
auto_dpi *= GHOST_GetNativePixelSize(win->ghostwin);
- int dpi = auto_dpi * U.ui_scale * (72.0 / 96.0f);
+ U.dpi = auto_dpi * U.ui_scale * (72.0 / 96.0f);
/* Automatically set larger pixel size for high DPI. */
- int pixelsize = max_ii(1, (int)(dpi / 64));
+ int pixelsize = max_ii(1, (int)(U.dpi / 64));
/* User adjustment for pixel size. */
pixelsize = max_ii(1, pixelsize + U.ui_line_width);
/* Set user preferences globals for drawing, and for forward compatibility. */
U.pixelsize = pixelsize;
- U.dpi = dpi / pixelsize;
U.virtual_pixel = (pixelsize == 1) ? VIRTUAL_PIXEL_NATIVE : VIRTUAL_PIXEL_DOUBLE;
- U.dpi_fac = ((U.pixelsize * (float)U.dpi) / 72.0f);
+ U.dpi_fac = U.dpi / 72.0f;
U.inv_dpi_fac = 1.0f / U.dpi_fac;
- /* Set user preferences globals for drawing, and for forward compatibility. */
- U.widget_unit = (U.pixelsize * U.dpi * 20 + 36) / 72;
- /* If line thickness differs from scaling factor then adjustments need to be made */
- U.widget_unit += 2 * ((int)U.pixelsize - (int)U.dpi_fac);
-
- /* update font drawing */
- BLF_default_dpi(U.pixelsize * U.dpi);
+ /* Widget unit is 20 pixels at 1X scale. This consists of 18 user-scaled units plus
+ * left and right borders of line-width (pixelsize). */
+ U.widget_unit = (int)roundf(18.0f * U.dpi_fac) + (2 * pixelsize);
}
static void wm_window_update_eventstate(wmWindow *win)
@@ -528,6 +556,9 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm,
glSettings.flags |= GHOST_glDebugContext;
}
+ eGPUBackendType gpu_backend = GPU_backend_type_selection_get();
+ glSettings.context_type = wm_ghost_drawing_context_type(gpu_backend);
+
int scr_w, scr_h;
wm_get_desktopsize(&scr_w, &scr_h);
int posy = (scr_h - win->posy - win->sizey);
@@ -545,11 +576,11 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm,
win->sizey,
(GHOST_TWindowState)win->windowstate,
is_dialog,
- GHOST_kDrawingContextTypeOpenGL,
glSettings);
if (ghostwin) {
- win->gpuctx = GPU_context_create(ghostwin);
+ win->gpuctx = GPU_context_create(ghostwin, NULL);
+ GPU_render_begin();
/* needed so we can detect the graphics card below */
GPU_init();
@@ -591,6 +622,7 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm,
GPU_clear_color(0.55f, 0.55f, 0.55f, 1.0f);
// GHOST_SetWindowState(ghostwin, GHOST_kWindowStateModified);
+ GPU_render_end();
}
else {
wm_window_set_drawable(wm, prev_windrawable, false);
@@ -969,43 +1001,18 @@ void wm_cursor_position_get(wmWindow *win, int *r_x, int *r_y)
wm_cursor_position_from_ghost_client_coords(win, r_x, r_y);
}
-typedef enum {
- SHIFT = 's',
- CONTROL = 'c',
- ALT = 'a',
- OS = 'C',
-} modifierKeyType;
-
/** Check if specified modifier key type is pressed. */
-static bool query_qual(modifierKeyType qual)
-{
- GHOST_TModifierKey left, right;
- switch (qual) {
- case SHIFT:
- left = GHOST_kModifierKeyLeftShift;
- right = GHOST_kModifierKeyRightShift;
- break;
- case CONTROL:
- left = GHOST_kModifierKeyLeftControl;
- right = GHOST_kModifierKeyRightControl;
- break;
- case OS:
- left = right = GHOST_kModifierKeyOS;
- break;
- case ALT:
- default:
- left = GHOST_kModifierKeyLeftAlt;
- right = GHOST_kModifierKeyRightAlt;
- break;
- }
-
- bool val = false;
- GHOST_GetModifierKeyState(g_system, left, &val);
- if (!val) {
- GHOST_GetModifierKeyState(g_system, right, &val);
+static uint8_t wm_ghost_modifier_query(const enum ModSide side)
+{
+ uint8_t result = 0;
+ for (int i = 0; i < ARRAY_SIZE(g_modifier_table); i++) {
+ bool val = false;
+ GHOST_GetModifierKeyState(g_system, g_modifier_table[i].ghost_mask_pair[side], &val);
+ if (val) {
+ result |= g_modifier_table[i].flag;
+ }
}
-
- return val;
+ return result;
}
static void wm_window_set_drawable(wmWindowManager *wm, wmWindow *win, bool activate)
@@ -1127,80 +1134,56 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_pt
win->active = 0; /* XXX */
break;
case GHOST_kEventWindowActivate: {
- const int keymodifier = ((query_qual(SHIFT) ? KM_SHIFT : 0) |
- (query_qual(CONTROL) ? KM_CTRL : 0) |
- (query_qual(ALT) ? KM_ALT : 0) | (query_qual(OS) ? KM_OSKEY : 0));
/* No context change! C->wm->windrawable is drawable, or for area queues. */
wm->winactive = win;
win->active = 1;
+
/* bad ghost support for modifier keys... so on activate we set the modifiers again */
- /* TODO: This is not correct since a modifier may be held when a window is activated...
- * better solve this at ghost level. attempted fix r54450 but it caused bug T34255.
- *
- * For now don't send GHOST_kEventKeyDown events, just set the 'eventstate'.
- */
- GHOST_TEventKeyData kdata = {
- .key = GHOST_kKeyUnknown,
- .utf8_buf = {'\0'},
- .is_repeat = false,
+ const uint8_t keymodifier_sided[2] = {
+ wm_ghost_modifier_query(MOD_SIDE_LEFT),
+ wm_ghost_modifier_query(MOD_SIDE_RIGHT),
};
- if (win->eventstate->modifier & KM_SHIFT) {
- if ((keymodifier & KM_SHIFT) == 0) {
- kdata.key = GHOST_kKeyLeftShift;
- wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, &kdata);
- }
- }
-#ifdef USE_WIN_ACTIVATE
- else {
- if (keymodifier & KM_SHIFT) {
- win->eventstate->modifier |= KM_SHIFT;
- }
- }
-#endif
- if (win->eventstate->modifier & KM_CTRL) {
- if ((keymodifier & KM_CTRL) == 0) {
- kdata.key = GHOST_kKeyLeftControl;
- wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, &kdata);
- }
- }
-#ifdef USE_WIN_ACTIVATE
- else {
- if (keymodifier & KM_CTRL) {
- win->eventstate->modifier |= KM_CTRL;
- }
- }
-#endif
- if (win->eventstate->modifier & KM_ALT) {
- if ((keymodifier & KM_ALT) == 0) {
- kdata.key = GHOST_kKeyLeftAlt;
- wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, &kdata);
- }
- }
-#ifdef USE_WIN_ACTIVATE
- else {
- if (keymodifier & KM_ALT) {
- win->eventstate->modifier |= KM_ALT;
- }
- }
-#endif
- if (win->eventstate->modifier & KM_OSKEY) {
- if ((keymodifier & KM_OSKEY) == 0) {
- kdata.key = GHOST_kKeyOS;
- wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, &kdata);
- }
- }
+ const uint8_t keymodifier = keymodifier_sided[0] | keymodifier_sided[1];
+ const uint8_t keymodifier_eventstate = win->eventstate->modifier;
+ if (keymodifier != keymodifier_eventstate) {
+ GHOST_TEventKeyData kdata = {
+ .key = GHOST_kKeyUnknown,
+ .utf8_buf = {'\0'},
+ .is_repeat = false,
+ };
+ for (int i = 0; i < ARRAY_SIZE(g_modifier_table); i++) {
+ if (keymodifier_eventstate & g_modifier_table[i].flag) {
+ if ((keymodifier & g_modifier_table[i].flag) == 0) {
+ for (int side = 0; side < 2; side++) {
+ if ((keymodifier_sided[side] & g_modifier_table[i].flag) == 0) {
+ kdata.key = g_modifier_table[i].ghost_key_pair[side];
+ wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, &kdata);
+ /* Only ever send one release event
+ * (currently releasing multiple isn't needed and only confuses logic). */
+ break;
+ }
+ }
+ }
+ }
#ifdef USE_WIN_ACTIVATE
- else {
- if (keymodifier & KM_OSKEY) {
- win->eventstate->modifier |= KM_OSKEY;
- }
- }
+ else {
+ if (keymodifier & g_modifier_table[i].flag) {
+ for (int side = 0; side < 2; side++) {
+ if (keymodifier_sided[side] & g_modifier_table[i].flag) {
+ kdata.key = g_modifier_table[i].ghost_key_pair[side];
+ wm_event_add_ghostevent(wm, win, GHOST_kEventKeyDown, &kdata);
+ }
+ }
+ }
+ }
#endif
#undef USE_WIN_ACTIVATE
+ }
+ }
/* keymodifier zero, it hangs on hotkeys that open windows otherwise */
win->eventstate->keymodifier = 0;
@@ -1281,7 +1264,7 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_pt
state_str = "maximized";
}
else if (state == GHOST_kWindowStateFullScreen) {
- state_str = "fullscreen";
+ state_str = "full-screen";
}
else {
state_str = "<unknown>";
@@ -1523,6 +1506,7 @@ static bool wm_window_timer(const bContext *C)
void wm_window_process_events(const bContext *C)
{
BLI_assert(BLI_thread_is_main());
+ GPU_render_begin();
bool has_event = GHOST_ProcessEvents(g_system, false); /* `false` is no wait. */
@@ -1535,6 +1519,7 @@ void wm_window_process_events(const bContext *C)
* processing/dispatching but also handling. */
has_event |= wm_xr_events_handle(CTX_wm_manager(C));
#endif
+ GPU_render_end();
/* When there is no event, sleep 5 milliseconds not to use too much CPU when idle.
*
@@ -1566,6 +1551,16 @@ void wm_ghost_init(bContext *C)
g_system = GHOST_CreateSystem();
+ if (UNLIKELY(g_system == NULL)) {
+ /* GHOST will have reported the back-ends that failed to load. */
+ fprintf(stderr, "GHOST: unable to initialize, exiting!\n");
+ /* This will leak memory, it's preferable to crashing. */
+ exit(1);
+ }
+#if !(defined(WIN32) || defined(__APPLE__))
+ g_system_backend_id = GHOST_SystemBackend();
+#endif
+
GHOST_Debug debug = {0};
if (G.debug & G_DEBUG_GHOST) {
debug.flags |= GHOST_kDebugDefault;
@@ -1610,6 +1605,44 @@ void wm_ghost_exit(void)
g_system = NULL;
}
+const char *WM_ghost_backend(void)
+{
+#if !(defined(WIN32) || defined(__APPLE__))
+ return g_system_backend_id ? g_system_backend_id : "NONE";
+#else
+ /* While this could be supported, at the moment it's only needed with GHOST X11/WAYLAND
+ * to check which was selected and the API call may be removed after that's no longer needed.
+ * Use dummy values to prevent this being used on other systems. */
+ return g_system ? "DEFAULT" : "NONE";
+#endif
+}
+
+GHOST_TDrawingContextType wm_ghost_drawing_context_type(const eGPUBackendType gpu_backend)
+{
+ switch (gpu_backend) {
+ case GPU_BACKEND_NONE:
+ return GHOST_kDrawingContextTypeNone;
+ case GPU_BACKEND_ANY:
+ case GPU_BACKEND_OPENGL:
+ return GHOST_kDrawingContextTypeOpenGL;
+ case GPU_BACKEND_VULKAN:
+ BLI_assert_unreachable();
+ return GHOST_kDrawingContextTypeNone;
+ case GPU_BACKEND_METAL:
+#ifdef WITH_METAL_BACKEND
+ return GHOST_kDrawingContextTypeMetal;
+#else
+ BLI_assert_unreachable();
+ return GHOST_kDrawingContextTypeNone;
+#endif
+ }
+
+ /* Avoid control reaches end of non-void function compilation warning, which could be promoted
+ * to error. */
+ BLI_assert_unreachable();
+ return GHOST_kDrawingContextTypeNone;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -1648,7 +1681,7 @@ wmTimer *WM_event_add_timer(wmWindowManager *wm, wmWindow *win, int event_type,
wmTimer *WM_event_add_timer_notifier(wmWindowManager *wm,
wmWindow *win,
- unsigned int type,
+ uint type,
double timestep)
{
wmTimer *wt = MEM_callocN(sizeof(wmTimer), "window timer");
@@ -2026,12 +2059,14 @@ void WM_init_native_pixels(bool do_it)
/** \name Cursor API
* \{ */
-void WM_init_tablet_api(void)
+void WM_init_input_devices(void)
{
if (UNLIKELY(!g_system)) {
return;
}
+ GHOST_SetMultitouchGestures(g_system, (U.uiflag & USER_NO_MULTITOUCH_GESTURES) == 0);
+
switch (U.tablet_api) {
case USER_TABLET_NATIVE:
GHOST_SetTabletAPI(g_system, GHOST_kTabletWinPointer);
diff --git a/source/blender/windowmanager/intern/wm_window_private.h b/source/blender/windowmanager/intern/wm_window_private.h
index f68d4e3e693..dad3e749817 100644
--- a/source/blender/windowmanager/intern/wm_window_private.h
+++ b/source/blender/windowmanager/intern/wm_window_private.h
@@ -7,8 +7,11 @@
#pragma once
#include "BLI_sys_types.h"
+
#include "GHOST_Types.h"
+#include "GPU_context.h"
+
/* *************** Message box *************** */
/* `WM_ghost_show_message_box` is implemented in `wm_windows.c` it is
* defined here as it was implemented to be used for showing
@@ -21,3 +24,5 @@ void WM_ghost_show_message_box(const char *title,
const char *continue_label,
const char *link,
GHOST_DialogOptions dialog_options);
+
+GHOST_TDrawingContextType wm_ghost_drawing_context_type(const eGPUBackendType gpu_backend);
diff --git a/source/blender/windowmanager/message_bus/intern/wm_message_bus_rna.c b/source/blender/windowmanager/message_bus/intern/wm_message_bus_rna.c
index 5c745c32d2c..e903ac11fba 100644
--- a/source/blender/windowmanager/message_bus/intern/wm_message_bus_rna.c
+++ b/source/blender/windowmanager/message_bus/intern/wm_message_bus_rna.c
@@ -28,8 +28,8 @@
BLI_INLINE uint void_hash_uint(const void *key)
{
- size_t y = (size_t)key >> (sizeof(void *));
- return (unsigned int)y;
+ size_t y = (size_t)key >> sizeof(void *);
+ return (uint)y;
}
static uint wm_msg_rna_gset_hash(const void *key_p)
diff --git a/source/blender/windowmanager/message_bus/intern/wm_message_bus_static.c b/source/blender/windowmanager/message_bus/intern/wm_message_bus_static.c
index 0e4f6a937bd..ad4db2be54d 100644
--- a/source/blender/windowmanager/message_bus/intern/wm_message_bus_static.c
+++ b/source/blender/windowmanager/message_bus/intern/wm_message_bus_static.c
@@ -31,7 +31,7 @@ static bool wm_msg_static_gset_cmp(const void *key_a_p, const void *key_b_p)
{
const wmMsgParams_Static *params_a = &((const wmMsgSubscribeKey_Static *)key_a_p)->msg.params;
const wmMsgParams_Static *params_b = &((const wmMsgSubscribeKey_Static *)key_b_p)->msg.params;
- return !((params_a->event == params_b->event));
+ return !(params_a->event == params_b->event);
}
static void wm_msg_static_gset_key_free(void *key_p)
{
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index 0b54560c56a..0a27b9c1cfd 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -45,12 +45,12 @@ extern void wm_close_and_free_all(bContext *C, ListBase *);
extern void wm_add_default(struct Main *bmain, bContext *C);
extern void wm_clear_default_size(bContext *C);
-/* register to windowmanager for redo or macro */
+/* Register to window-manager for redo or macro. */
/**
* Called on event handling by `event_system.c`.
*
- * All operations get registered in the windowmanager here.
+ * All operations get registered in the window-manager here.
*/
void wm_operator_register(bContext *C, wmOperator *op);
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index edbfe0202de..f49be20e174 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -29,21 +29,21 @@ extern "C" {
/* wmKeyMap is in DNA_windowmanager.h, it's saveable */
/** Custom types for handlers, for signaling, freeing */
-enum eWM_EventHandlerType {
+typedef enum eWM_EventHandlerType {
WM_HANDLER_TYPE_GIZMO = 1,
WM_HANDLER_TYPE_UI,
WM_HANDLER_TYPE_OP,
WM_HANDLER_TYPE_DROPBOX,
WM_HANDLER_TYPE_KEYMAP,
-};
+} eWM_EventHandlerType;
typedef bool (*EventHandlerPoll)(const ARegion *region, const wmEvent *event);
typedef struct wmEventHandler {
struct wmEventHandler *next, *prev;
- enum eWM_EventHandlerType type;
- char flag; /* WM_HANDLER_BLOCKING, ... */
+ eWM_EventHandlerType type;
+ eWM_EventHandlerFlag flag;
EventHandlerPoll poll;
} wmEventHandler;
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index 405b7225bd5..c36c57a12ae 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -252,8 +252,6 @@ enum {
#define _NDOF_MIN NDOF_MOTION
#define _NDOF_BUTTON_MIN NDOF_BUTTON_MENU
- /* used internally, never sent */
- NDOF_BUTTON_NONE = NDOF_MOTION,
/* these two are available from any 3Dconnexion device */
NDOF_BUTTON_MENU = 0x0191, /* 401 */
@@ -281,35 +279,42 @@ enum {
NDOF_BUTTON_DOMINANT = 0x01a3, /* 419 */
NDOF_BUTTON_PLUS = 0x01a4, /* 420 */
NDOF_BUTTON_MINUS = 0x01a5, /* 421 */
+ /* General-purpose buttons. */
+ NDOF_BUTTON_1 = 0x01a6, /* 422 */
+ NDOF_BUTTON_2 = 0x01a7, /* 423 */
+ NDOF_BUTTON_3 = 0x01a8, /* 424 */
+ NDOF_BUTTON_4 = 0x01a9, /* 425 */
+ NDOF_BUTTON_5 = 0x01aa, /* 426 */
+ NDOF_BUTTON_6 = 0x01ab, /* 427 */
+ NDOF_BUTTON_7 = 0x01ac, /* 428 */
+ NDOF_BUTTON_8 = 0x01ad, /* 429 */
+ NDOF_BUTTON_9 = 0x01ae, /* 430 */
+ NDOF_BUTTON_10 = 0x01af, /* 431 */
+ /* more general-purpose buttons */
+ NDOF_BUTTON_A = 0x01b0, /* 432 */
+ NDOF_BUTTON_B = 0x01b1, /* 433 */
+ NDOF_BUTTON_C = 0x01b2, /* 434 */
+ /* Store/restore views. */
+ NDOF_BUTTON_V1 = 0x01b3, /* 435 */
+ NDOF_BUTTON_V2 = 0x01b4, /* 436 */
+ NDOF_BUTTON_V3 = 0x01b5, /* 437 */
/* Disabled as GHOST converts these to keyboard events
* which use regular keyboard event handling logic. */
#if 0
/* keyboard emulation */
- NDOF_BUTTON_ESC = 0x01a6, /* 422 */
- NDOF_BUTTON_ALT = 0x01a7, /* 423 */
- NDOF_BUTTON_SHIFT = 0x01a8, /* 424 */
- NDOF_BUTTON_CTRL = 0x01a9, /* 425 */
+ NDOF_BUTTON_ESC = 0x01b6, /* 438 */
+ NDOF_BUTTON_ENTER = 0x01b7, /* 439 */
+ NDOF_BUTTON_DELETE = 0x01b8, /* 440 */
+ NDOF_BUTTON_TAB = 0x01b9, /* 441 */
+ NDOF_BUTTON_SPACE = 0x01ba, /* 442 */
+ NDOF_BUTTON_ALT = 0x01bb, /* 443 */
+ NDOF_BUTTON_SHIFT = 0x01bc, /* 444 */
+ NDOF_BUTTON_CTRL = 0x01bd, /* 445 */
#endif
- /* general-purpose buttons */
- NDOF_BUTTON_1 = 0x01aa, /* 426 */
- NDOF_BUTTON_2 = 0x01ab, /* 427 */
- NDOF_BUTTON_3 = 0x01ac, /* 428 */
- NDOF_BUTTON_4 = 0x01ad, /* 429 */
- NDOF_BUTTON_5 = 0x01ae, /* 430 */
- NDOF_BUTTON_6 = 0x01af, /* 431 */
- NDOF_BUTTON_7 = 0x01b0, /* 432 */
- NDOF_BUTTON_8 = 0x01b1, /* 433 */
- NDOF_BUTTON_9 = 0x01b2, /* 434 */
- NDOF_BUTTON_10 = 0x01b3, /* 435 */
- /* more general-purpose buttons */
- NDOF_BUTTON_A = 0x01b4, /* 436 */
- NDOF_BUTTON_B = 0x01b5, /* 437 */
- NDOF_BUTTON_C = 0x01b6, /* 438 */
-
-#define _NDOF_MAX NDOF_BUTTON_C
-#define _NDOF_BUTTON_MAX NDOF_BUTTON_C
+#define _NDOF_MAX NDOF_BUTTON_V3
+#define _NDOF_BUTTON_MAX NDOF_BUTTON_V3
/* ********** End of Input devices. ********** */
@@ -449,6 +454,8 @@ enum eEventType_Mask {
(EVT_TYPE_MASK_KEYBOARD | EVT_TYPE_MASK_MOUSE | EVT_TYPE_MASK_NDOF)
#define EVT_TYPE_MASK_HOTKEY_EXCLUDE EVT_TYPE_MASK_KEYBOARD_MODIFIER
+#define NDOF_BUTTON_INDEX_AS_EVENT(i) (_NDOF_BUTTON_MIN + (i))
+
bool WM_event_type_mask_test(int event_type, enum eEventType_Mask mask);
/** \} */
diff --git a/source/blender/windowmanager/wm_files.h b/source/blender/windowmanager/wm_files.h
index 1c09f861c6c..1ab8808b70b 100644
--- a/source/blender/windowmanager/wm_files.h
+++ b/source/blender/windowmanager/wm_files.h
@@ -31,6 +31,8 @@ struct wmHomeFileRead_Params {
* Used for "Restore Factory Settings".
*/
unsigned int use_factory_settings : 1;
+ /** Read factory settings from the app-templates only (keep other defaults). */
+ unsigned int use_factory_settings_app_template_only : 1;
/**
* Load the startup file without any data-blocks.
* Useful for automated content generation, so the file starts without data.
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_action.c b/source/blender/windowmanager/xr/intern/wm_xr_action.c
index a83415c98af..68f6bfc1aff 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_action.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_action.c
@@ -72,8 +72,8 @@ static wmXrAction *action_create(const char *action_name,
strcpy(action->name, action_name);
action->type = type;
- const unsigned int count = (unsigned int)BLI_listbase_count(user_paths);
- unsigned int subaction_idx = 0;
+ const uint count = (uint)BLI_listbase_count(user_paths);
+ uint subaction_idx = 0;
action->count_subaction_paths = count;
action->subaction_paths = MEM_mallocN(sizeof(*action->subaction_paths) * count,
@@ -142,7 +142,7 @@ static void action_destroy(void *val)
char **subaction_paths = action->subaction_paths;
if (subaction_paths) {
- for (unsigned int i = 0; i < action->count_subaction_paths; ++i) {
+ for (uint i = 0; i < action->count_subaction_paths; ++i) {
MEM_SAFE_FREE(subaction_paths[i]);
}
MEM_freeN(subaction_paths);
@@ -241,8 +241,8 @@ bool WM_xr_action_create(wmXrData *xr,
action_flag,
haptic_flag);
- const unsigned int count = (unsigned int)BLI_listbase_count(user_paths);
- unsigned int subaction_idx = 0;
+ const uint count = (uint)BLI_listbase_count(user_paths);
+ uint subaction_idx = 0;
char **subaction_paths = MEM_calloc_arrayN(
count, sizeof(*subaction_paths), "XrAction_SubactionPathPointers");
@@ -336,8 +336,8 @@ bool WM_xr_action_binding_create(wmXrData *xr,
const eXrAxisFlag *axis_flags,
const struct wmXrPose *poses)
{
- const unsigned int count = (unsigned int)BLI_listbase_count(user_paths);
- BLI_assert(count == (unsigned int)BLI_listbase_count(component_paths));
+ const uint count = (uint)BLI_listbase_count(user_paths);
+ BLI_assert(count == (uint)BLI_listbase_count(component_paths));
GHOST_XrActionBindingInfo *binding_infos = MEM_calloc_arrayN(
count, sizeof(*binding_infos), "XrActionBinding_Infos");
@@ -345,7 +345,7 @@ bool WM_xr_action_binding_create(wmXrData *xr,
char **subaction_paths = MEM_calloc_arrayN(
count, sizeof(*subaction_paths), "XrActionBinding_SubactionPathPointers");
- for (unsigned int i = 0; i < count; ++i) {
+ for (uint i = 0; i < count; ++i) {
GHOST_XrActionBindingInfo *binding_info = &binding_infos[i];
const XrUserPath *user_path = BLI_findlink(user_paths, i);
const XrComponentPath *component_path = BLI_findlink(component_paths, i);
@@ -448,12 +448,12 @@ bool WM_xr_controller_pose_actions_set(wmXrData *xr,
}
/* Ensure consistent subaction paths. */
- const unsigned int count = grip_action->count_subaction_paths;
+ const uint count = grip_action->count_subaction_paths;
if (count != aim_action->count_subaction_paths) {
return false;
}
- for (unsigned int i = 0; i < count; ++i) {
+ for (uint i = 0; i < count; ++i) {
if (!STREQ(grip_action->subaction_paths[i], aim_action->subaction_paths[i])) {
return false;
}
@@ -483,7 +483,7 @@ bool WM_xr_action_state_get(const wmXrData *xr,
r_state->type = (int)action->type;
/* Find the action state corresponding to the subaction path. */
- for (unsigned int i = 0; i < action->count_subaction_paths; ++i) {
+ for (uint i = 0; i < action->count_subaction_paths; ++i) {
if (STREQ(subaction_path, action->subaction_paths[i])) {
switch (action->type) {
case XR_BOOLEAN_INPUT:
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_draw.c b/source/blender/windowmanager/xr/intern/wm_xr_draw.c
index 3b1acee2b99..6e32c5a0aae 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_draw.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_draw.c
@@ -213,9 +213,9 @@ static GPUBatch *wm_xr_controller_model_batch_create(GHOST_XrContextHandle xr_co
GPUIndexBuf *ibo = NULL;
if (model_data.count_indices > 0 && ((model_data.count_indices % 3) == 0)) {
GPUIndexBufBuilder ibo_builder;
- const unsigned int prim_len = model_data.count_indices / 3;
+ const uint prim_len = model_data.count_indices / 3;
GPU_indexbuf_init(&ibo_builder, GPU_PRIM_TRIS, prim_len, model_data.count_vertices);
- for (unsigned int i = 0; i < prim_len; ++i) {
+ for (uint i = 0; i < prim_len; ++i) {
const uint32_t *idx = &model_data.indices[i * 3];
GPU_indexbuf_add_tri_verts(&ibo_builder, idx[0], idx[1], idx[2]);
}
@@ -261,8 +261,7 @@ static void wm_xr_controller_model_draw(const XrSessionSettings *settings,
GPU_matrix_push();
GPU_matrix_mul(controller->grip_mat);
- for (unsigned int component_idx = 0; component_idx < model_data.count_components;
- ++component_idx) {
+ for (uint component_idx = 0; component_idx < model_data.count_components; ++component_idx) {
const GHOST_XrControllerModelComponent *component = &model_data.components[component_idx];
GPU_matrix_push();
GPU_matrix_mul(component->transform);
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_operators.c b/source/blender/windowmanager/xr/intern/wm_xr_operators.c
index 3f0c72a4a05..543e5782a5a 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_operators.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_operators.c
@@ -943,7 +943,7 @@ static int wm_xr_navigation_fly_modal(bContext *C, wmOperator *op, const wmEvent
const double time_now = PIL_check_seconds_timer();
mode = (eXrFlyMode)RNA_enum_get(op->ptr, "mode");
- turn = (ELEM(mode, XR_FLY_TURNLEFT, XR_FLY_TURNRIGHT));
+ turn = ELEM(mode, XR_FLY_TURNLEFT, XR_FLY_TURNRIGHT);
locz_lock = RNA_boolean_get(op->ptr, "lock_location_z");
dir_lock = RNA_boolean_get(op->ptr, "lock_direction");
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_session.c b/source/blender/windowmanager/xr/intern/wm_xr_session.c
index a4d2a65830f..aefc3afff66 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_session.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_session.c
@@ -178,7 +178,7 @@ static void wm_xr_session_base_pose_calc(const Scene *scene,
float tmp_quat[4];
float tmp_eul[3];
- mat4_to_loc_quat(r_base_pose->position, tmp_quat, base_pose_object->obmat);
+ mat4_to_loc_quat(r_base_pose->position, tmp_quat, base_pose_object->object_to_world);
/* Only use rotation around Z-axis to align view with floor. */
quat_to_eul(tmp_eul, tmp_quat);
@@ -432,7 +432,7 @@ bool WM_xr_session_state_viewer_pose_matrix_info_get(const wmXrData *xr,
}
bool WM_xr_session_state_controller_grip_location_get(const wmXrData *xr,
- unsigned int subaction_idx,
+ uint subaction_idx,
float r_location[3])
{
if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set ||
@@ -449,7 +449,7 @@ bool WM_xr_session_state_controller_grip_location_get(const wmXrData *xr,
}
bool WM_xr_session_state_controller_grip_rotation_get(const wmXrData *xr,
- unsigned int subaction_idx,
+ uint subaction_idx,
float r_rotation[4])
{
if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set ||
@@ -466,7 +466,7 @@ bool WM_xr_session_state_controller_grip_rotation_get(const wmXrData *xr,
}
bool WM_xr_session_state_controller_aim_location_get(const wmXrData *xr,
- unsigned int subaction_idx,
+ uint subaction_idx,
float r_location[3])
{
if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set ||
@@ -483,7 +483,7 @@ bool WM_xr_session_state_controller_aim_location_get(const wmXrData *xr,
}
bool WM_xr_session_state_controller_aim_rotation_get(const wmXrData *xr,
- unsigned int subaction_idx,
+ uint subaction_idx,
float r_rotation[4])
{
if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set ||
@@ -615,7 +615,7 @@ static void wm_xr_session_controller_data_update(const XrSessionSettings *settin
BLI_assert(grip_action->count_subaction_paths == aim_action->count_subaction_paths);
BLI_assert(grip_action->count_subaction_paths == BLI_listbase_count(&state->controllers));
- unsigned int subaction_idx = 0;
+ uint subaction_idx = 0;
float view_ofs[3], base_mat[4][4], nav_mat[4][4];
if ((settings->flag & XR_SESSION_USE_POSITION_TRACKING) == 0) {
@@ -816,7 +816,7 @@ static void wm_xr_session_haptic_timers_check(ListBase *active_haptic_actions, i
static void wm_xr_session_action_states_interpret(wmXrData *xr,
const char *action_set_name,
wmXrAction *action,
- unsigned int subaction_idx,
+ uint subaction_idx,
ListBase *active_modal_actions,
ListBase *active_haptic_actions,
int64_t time_now,
@@ -960,8 +960,8 @@ static void wm_xr_session_action_states_interpret(wmXrData *xr,
static bool wm_xr_session_action_test_bimanual(const wmXrSessionState *session_state,
wmXrAction *action,
- unsigned int subaction_idx,
- unsigned int *r_subaction_idx_other,
+ uint subaction_idx,
+ uint *r_subaction_idx_other,
const GHOST_XrPose **r_aim_pose_other)
{
if ((action->action_flag & XR_ACTION_BIMANUAL) == 0) {
@@ -971,7 +971,7 @@ static bool wm_xr_session_action_test_bimanual(const wmXrSessionState *session_s
bool bimanual = false;
*r_subaction_idx_other = (subaction_idx == 0) ?
- (unsigned int)min_ii(1, action->count_subaction_paths - 1) :
+ (uint)min_ii(1, action->count_subaction_paths - 1) :
0;
switch (action->type) {
@@ -1018,8 +1018,8 @@ static wmXrActionData *wm_xr_session_event_create(const char *action_set_name,
const wmXrAction *action,
const GHOST_XrPose *controller_aim_pose,
const GHOST_XrPose *controller_aim_pose_other,
- unsigned int subaction_idx,
- unsigned int subaction_idx_other,
+ uint subaction_idx,
+ uint subaction_idx_other,
bool bimanual)
{
wmXrActionData *data = MEM_callocN(sizeof(wmXrActionData), __func__);
@@ -1092,7 +1092,7 @@ static void wm_xr_session_events_dispatch(wmXrData *xr,
{
const char *action_set_name = action_set->name;
- const unsigned int count = GHOST_XrGetActionCount(xr_context, action_set_name);
+ const uint count = GHOST_XrGetActionCount(xr_context, action_set_name);
if (count < 1) {
return;
}
@@ -1109,14 +1109,14 @@ static void wm_xr_session_events_dispatch(wmXrData *xr,
/* Check haptic action timers. */
wm_xr_session_haptic_timers_check(active_haptic_actions, time_now);
- for (unsigned int action_idx = 0; action_idx < count; ++action_idx) {
+ for (uint action_idx = 0; action_idx < count; ++action_idx) {
wmXrAction *action = actions[action_idx];
if (action && action->ot) {
const bool modal = action->ot->modal;
const bool haptic = (GHOST_XrGetActionCustomdata(
xr_context, action_set_name, action->haptic_name) != NULL);
- for (unsigned int subaction_idx = 0; subaction_idx < action->count_subaction_paths;
+ for (uint subaction_idx = 0; subaction_idx < action->count_subaction_paths;
++subaction_idx) {
short val = KM_NOTHING;
@@ -1143,7 +1143,7 @@ static void wm_xr_session_events_dispatch(wmXrData *xr,
const GHOST_XrPose *aim_pose = wm_xr_session_controller_aim_pose_find(
session_state, action->subaction_paths[subaction_idx]);
const GHOST_XrPose *aim_pose_other = NULL;
- unsigned int subaction_idx_other = 0;
+ uint subaction_idx_other = 0;
/* Test for bimanual interaction. */
const bool bimanual = wm_xr_session_action_test_bimanual(
@@ -1242,11 +1242,11 @@ void wm_xr_session_controller_data_populate(const wmXrAction *grip_action,
ListBase *controllers = &state->controllers;
BLI_assert(grip_action->count_subaction_paths == aim_action->count_subaction_paths);
- const unsigned int count = grip_action->count_subaction_paths;
+ const uint count = grip_action->count_subaction_paths;
wm_xr_session_controller_data_free(state);
- for (unsigned int i = 0; i < count; ++i) {
+ for (uint i = 0; i < count; ++i) {
wmXrController *controller = MEM_callocN(sizeof(*controller), __func__);
BLI_assert(STREQ(grip_action->subaction_paths[i], aim_action->subaction_paths[i]));
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index eee64b97e82..bb9e73c0895 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright 2006 Blender Foundation. All rights reserved.
-blender_include_dirs(
+set(INC
../../intern/clog
../../intern/guardedalloc
../blender/blenkernel
@@ -35,17 +35,17 @@ if(WITH_TBB)
endif()
if(WIN32)
- blender_include_dirs(../../intern/utfconv)
+ list(APPEND INC ../../intern/utfconv)
endif()
if(WITH_LIBMV)
- blender_include_dirs(../../intern/libmv)
+ list(APPEND INC ../../intern/libmv)
add_definitions(-DWITH_LIBMV)
endif()
if(WITH_CYCLES)
if(WITH_CYCLES_LOGGING)
- blender_include_dirs(../../intern/cycles/blender)
+ list(APPEND INC ../../intern/cycles/blender)
add_definitions(-DWITH_CYCLES_LOGGING)
endif()
endif()
@@ -55,7 +55,7 @@ if(WITH_CODEC_FFMPEG)
endif()
if(WITH_TBB)
- blender_include_dirs(${TBB_INCLUDE_DIRS})
+ list(APPEND INC ${TBB_INCLUDE_DIRS})
if(WIN32)
# For `pragma` that links `tbbmalloc_proxy.lib`.
link_directories(${LIBDIR}/tbb/lib)
@@ -64,7 +64,7 @@ endif()
if(WITH_PYTHON)
- blender_include_dirs(../blender/python)
+ list(APPEND INC ../blender/python)
add_definitions(-DWITH_PYTHON)
if(WITH_PYTHON_SECURITY)
@@ -78,19 +78,19 @@ endif()
if(WITH_SDL)
if(WITH_SDL_DYNLOAD)
- blender_include_dirs(../../extern/sdlew/include)
+ list(APPEND INC ../../extern/sdlew/include)
add_definitions(-DWITH_SDL_DYNLOAD)
endif()
add_definitions(-DWITH_SDL)
endif()
if(WITH_BINRELOC)
- blender_include_dirs(${BINRELOC_INCLUDE_DIRS})
+ list(APPEND INC ${BINRELOC_INCLUDE_DIRS})
add_definitions(-DWITH_BINRELOC)
endif()
if(WITH_FREESTYLE)
- blender_include_dirs(../blender/freestyle)
+ list(APPEND INC ../blender/freestyle)
add_definitions(-DWITH_FREESTYLE)
endif()
@@ -99,7 +99,7 @@ if(WITH_XR_OPENXR)
endif()
if(WITH_GMP)
- blender_include_dirs(${GMP_INCLUDE_DIRS})
+ list(APPEND INC ${GMP_INCLUDE_DIRS})
add_definitions(-DWITH_GMP)
endif()
@@ -344,10 +344,10 @@ if(UNIX AND NOT APPLE)
elseif(WIN32)
if(WITH_PYTHON_MODULE)
- set(TARGETDIR_BPY $<TARGET_FILE_DIR:blender>)
- set(TARGETDIR_VER $<TARGET_FILE_DIR:blender>/${BLENDER_VERSION})
+ set(TARGETDIR_BPY ${CMAKE_INSTALL_PREFIX_WITH_CONFIG}/bpy)
+ set(TARGETDIR_VER ${CMAKE_INSTALL_PREFIX_WITH_CONFIG}/bpy/${BLENDER_VERSION})
# Important the DLL's are next to `__init__.pyd` otherwise it won't load.
- set(TARGETDIR_LIB $<TARGET_FILE_DIR:blender>)
+ set(TARGETDIR_LIB ${CMAKE_INSTALL_PREFIX_WITH_CONFIG}/bpy)
else()
set(TARGETDIR_VER ${BLENDER_VERSION})
set(TARGETDIR_TEXT .)
@@ -410,6 +410,7 @@ if(WITH_PYTHON)
DESTINATION ${TARGETDIR_VER}
PATTERN ".git" EXCLUDE
PATTERN ".gitignore" EXCLUDE
+ PATTERN ".github" EXCLUDE
PATTERN ".arcconfig" EXCLUDE
PATTERN "__pycache__" EXCLUDE
PATTERN "${ADDON_EXCLUDE_CONDITIONAL}" EXCLUDE
@@ -1075,6 +1076,20 @@ elseif(WIN32)
DESTINATION ${TARGETDIR_VER}/python/lib/site-packages
)
endif()
+
+ if(WITH_PYTHON_MODULE AND TARGETDIR_BPY)
+ install(
+ TARGETS blender
+ LIBRARY DESTINATION ${TARGETDIR_BPY}
+ )
+ endif()
+
+ if(PLATFORM_BUNDLED_LIBRARIES)
+ install(
+ FILES ${PLATFORM_BUNDLED_LIBRARIES}
+ DESTINATION ${TARGETDIR_LIB}
+ )
+ endif()
elseif(APPLE)
if(NOT WITH_PYTHON_MODULE)
# Uppercase name for app bundle.
@@ -1156,10 +1171,10 @@ elseif(APPLE)
)
if(WITH_BLENDER_THUMBNAILER)
- install(
- TARGETS blender-thumbnailer
- DESTINATION Blender.app/Contents/MacOS/
- )
+ install(
+ TARGETS blender-thumbnailer
+ DESTINATION Blender.app/Contents/MacOS/
+ )
endif()
if(PLATFORM_BUNDLED_LIBRARIES AND TARGETDIR_LIB)
@@ -1284,6 +1299,7 @@ if(DEFINED PLATFORM_SYMBOLS_MAP)
set_target_properties(blender PROPERTIES LINK_DEPENDS ${PLATFORM_SYMBOLS_MAP})
endif()
+blender_target_include_dirs(blender ${INC})
# -----------------------------------------------------------------------------
# USD registry.
diff --git a/source/creator/creator.c b/source/creator/creator.c
index 2d8b1e16098..2cd54deeab5 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -24,7 +24,6 @@
#include "DNA_genfile.h"
-#include "BLI_args.h"
#include "BLI_string.h"
#include "BLI_system.h"
#include "BLI_task.h"
@@ -51,6 +50,10 @@
#include "BKE_vfont.h"
#include "BKE_volume.h"
+#ifndef WITH_PYTHON_MODULE
+# include "BLI_args.h"
+#endif
+
#include "DEG_depsgraph.h"
#include "IMB_imbuf.h" /* For #IMB_init. */
@@ -94,6 +97,18 @@
#include "creator_intern.h" /* Own include. */
/* -------------------------------------------------------------------- */
+/** \name Local Defines
+ * \{ */
+
+/* When building as a Python module, don't use special argument handling
+ * so the module loading logic can control the `argv` & `argc`. */
+#if defined(WIN32) && !defined(WITH_PYTHON_MODULE)
+# define USE_WIN32_UNICODE_ARGS
+#endif
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Local Application State
* \{ */
@@ -132,23 +147,34 @@ static void main_callback_setup(void)
/* free data on early exit (if Python calls 'sys.exit()' while parsing args for eg). */
struct CreatorAtExitData {
+#ifndef WITH_PYTHON_MODULE
bArgs *ba;
-#ifdef WIN32
+#endif
+
+#ifdef USE_WIN32_UNICODE_ARGS
const char **argv;
int argv_num;
#endif
+
+#if defined(WITH_PYTHON_MODULE) && !defined(USE_WIN32_UNICODE_ARGS)
+ void *_empty; /* Prevent empty struct error with MSVC. */
+#endif
};
static void callback_main_atexit(void *user_data)
{
struct CreatorAtExitData *app_init_data = user_data;
+#ifndef WITH_PYTHON_MODULE
if (app_init_data->ba) {
BLI_args_destroy(app_init_data->ba);
app_init_data->ba = NULL;
}
+#else
+ UNUSED_VARS(app_init_data); /* May be unused. */
+#endif
-#ifdef WIN32
+#ifdef USE_WIN32_UNICODE_ARGS
if (app_init_data->argv) {
while (app_init_data->argv_num) {
free((void *)app_init_data->argv[--app_init_data->argv_num]);
@@ -156,6 +182,8 @@ static void callback_main_atexit(void *user_data)
free((void *)app_init_data->argv);
app_init_data->argv = NULL;
}
+#else
+ UNUSED_VARS(app_init_data); /* May be unused. */
#endif
}
@@ -233,12 +261,6 @@ void gmp_blender_init_allocator()
/** \name Main Function
* \{ */
-/* When building as a Python module, don't use special argument handling
- * so the module loading logic can control the `argv` & `argc`. */
-#if defined(WIN32) && !defined(WITH_PYTHON_MODULE)
-# define USE_WIN32_UNICODE_ARGS
-#endif
-
/**
* Blender's main function responsibilities are:
* - setup subsystems.
@@ -534,7 +556,7 @@ int main(int argc,
(void)ba;
#endif
-#ifdef WIN32
+#ifdef USE_WIN32_UNICODE_ARGS
argv = NULL;
(void)argv;
#endif
diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c
index b3f5d24ee8c..2ebdcdb35ba 100644
--- a/source/creator/creator_args.c
+++ b/source/creator/creator_args.c
@@ -42,6 +42,8 @@
# include "BKE_scene.h"
# include "BKE_sound.h"
+# include "GPU_context.h"
+
# ifdef WITH_FFMPEG
# include "IMB_imbuf.h"
# endif
@@ -579,6 +581,7 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo
BLI_args_print_arg_doc(ba, "--debug-wintab");
BLI_args_print_arg_doc(ba, "--debug-gpu");
BLI_args_print_arg_doc(ba, "--debug-gpu-force-workarounds");
+ BLI_args_print_arg_doc(ba, "--debug-gpu-disable-ssbo");
BLI_args_print_arg_doc(ba, "--debug-wm");
# ifdef WITH_XR_OPENXR
BLI_args_print_arg_doc(ba, "--debug-xr");
@@ -655,12 +658,18 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo
printf("\t...works as expected.\n\n");
printf("Environment Variables:\n");
- printf(" $BLENDER_USER_CONFIG Directory for user configuration files.\n");
- printf(" $BLENDER_USER_SCRIPTS Directory for user scripts.\n");
- printf(" $BLENDER_SYSTEM_SCRIPTS Directory for system wide scripts.\n");
- printf(" $BLENDER_USER_DATAFILES Directory for user data files (icons, translations, ..).\n");
- printf(" $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
- printf(" $BLENDER_SYSTEM_PYTHON Directory for system Python libraries.\n");
+ printf(" $BLENDER_USER_RESOURCES Top level directory for user files.\n");
+ printf(" (other 'BLENDER_USER_*' variables override when set).\n");
+ printf(" $BLENDER_USER_CONFIG Directory for user configuration files.\n");
+ printf(" $BLENDER_USER_SCRIPTS Directory for user scripts.\n");
+ printf(" $BLENDER_USER_DATAFILES Directory for user data files (icons, translations, ..).\n");
+ printf("\n");
+ printf(" $BLENDER_SYSTEM_RESOURCES Top level directory for system files.\n");
+ printf(" (other 'BLENDER_SYSTEM_*' variables override when set).\n");
+ printf(" $BLENDER_SYSTEM_SCRIPTS Directory for system wide scripts.\n");
+ printf(" $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
+ printf(" $BLENDER_SYSTEM_PYTHON Directory for system Python libraries.\n");
+
# ifdef WITH_OCIO
printf(" $OCIO Path to override the OpenColorIO config file.\n");
# endif
@@ -990,6 +999,9 @@ static const char arg_handle_debug_mode_generic_set_doc_depsgraph_uuid[] =
static const char arg_handle_debug_mode_generic_set_doc_gpu_force_workarounds[] =
"\n\t"
"Enable workarounds for typical GPU issues and disable all GPU extensions.";
+static const char arg_handle_debug_mode_generic_set_doc_gpu_disable_ssbo[] =
+ "\n\t"
+ "Disable usage of shader storage buffer objects.";
static int arg_handle_debug_mode_generic_set(int UNUSED(argc),
const char **UNUSED(argv),
@@ -1101,6 +1113,52 @@ static int arg_handle_debug_gpu_set(int UNUSED(argc),
return 0;
}
+static const char arg_handle_gpu_backend_set_doc[] =
+ "\n"
+ "\tForce to use a specific GPU backend. Valid options: "
+# ifdef WITH_VULKAN_BACKEND
+ "'vulkan', "
+# endif
+# ifdef WITH_METAL_BACKEND
+ "'metal', "
+# endif
+ "'opengl'.";
+static int arg_handle_gpu_backend_set(int argc, const char **argv, void *UNUSED(data))
+{
+ if (argc == 0) {
+ printf("\nError: GPU backend must follow '--gpu-backend'.\n");
+ return 0;
+ }
+
+ eGPUBackendType gpu_backend = GPU_BACKEND_NONE;
+
+ if (STREQ(argv[1], "opengl")) {
+ gpu_backend = GPU_BACKEND_OPENGL;
+ }
+# ifdef WITH_VULKAN_BACKEND
+ else if (STREQ(argv[1], "vulkan")) {
+ gpu_backend = GPU_BACKEND_VULKAN;
+ }
+# endif
+# ifdef WITH_METAL_BACKEND
+ else if (STREQ(argv[1], "metal")) {
+ gpu_backend = GPU_BACKEND_METAL;
+ }
+# endif
+ else {
+ printf("\nError: Unrecognized GPU backend for '--gpu-backend'.\n");
+ return 0;
+ }
+
+ GPU_backend_type_selection_set(gpu_backend);
+ if (!GPU_backend_supported()) {
+ printf("\nError: GPU backend not supported.\n");
+ return 0;
+ }
+
+ return 1;
+}
+
static const char arg_handle_debug_fpe_set_doc[] =
"\n\t"
"Enable floating-point exceptions.";
@@ -1901,7 +1959,7 @@ static int arg_handle_python_exit_code_set(int argc, const char **argv, void *UN
return 1;
}
- app_state.exit_code_on_error.python = (unsigned char)exit_code;
+ app_state.exit_code_on_error.python = (uchar)exit_code;
return 1;
}
printf("\nError: you must specify an exit code number '%s'.\n", arg_id);
@@ -2064,6 +2122,10 @@ void main_args_setup(bContext *C, bArgs *ba)
BLI_args_add(ba, NULL, "--log-show-timestamp", CB(arg_handle_log_show_timestamp_set), ba);
BLI_args_add(ba, NULL, "--log-file", CB(arg_handle_log_file_set), ba);
+ /* GPU backend selection should be part of ARG_PASS_ENVIRONMENT for correct GPU context selection
+ * for anim player. */
+ BLI_args_add(ba, NULL, "--gpu-backend", CB(arg_handle_gpu_backend_set), NULL);
+
/* Pass: Background Mode & Settings
*
* Also and commands that exit after usage. */
@@ -2212,6 +2274,11 @@ void main_args_setup(bContext *C, bArgs *ba)
"--debug-gpu-force-workarounds",
CB_EX(arg_handle_debug_mode_generic_set, gpu_force_workarounds),
(void *)G_DEBUG_GPU_FORCE_WORKAROUNDS);
+ BLI_args_add(ba,
+ NULL,
+ "--debug-gpu-disable-ssbo",
+ CB_EX(arg_handle_debug_mode_generic_set, gpu_disable_ssbo),
+ (void *)G_DEBUG_GPU_FORCE_DISABLE_SSBO);
BLI_args_add(ba, NULL, "--debug-exit-on-error", CB(arg_handle_debug_exit_on_error), NULL);
BLI_args_add(ba, NULL, "--verbose", CB(arg_handle_verbosity_set), NULL);
diff --git a/source/creator/creator_intern.h b/source/creator/creator_intern.h
index c9519f78af9..29ef6d96f15 100644
--- a/source/creator/creator_intern.h
+++ b/source/creator/creator_intern.h
@@ -11,6 +11,10 @@
struct bArgs;
struct bContext;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifndef WITH_PYTHON_MODULE
/* creator_args.c */
@@ -68,14 +72,14 @@ enum {
# define BUILD_DATE
#endif
-/* from buildinfo.c */
+/* From `buildinfo.c`. */
#ifdef BUILD_DATE
extern char build_date[];
extern char build_time[];
extern char build_hash[];
extern unsigned long build_commit_timestamp;
-/* TODO(sergey): ideally size need to be in sync with buildinfo.c */
+/* TODO(@sergey): ideally size need to be in sync with `buildinfo.c`. */
extern char build_commit_date[16];
extern char build_commit_time[16];
@@ -87,3 +91,7 @@ extern char build_cxxflags[];
extern char build_linkflags[];
extern char build_system[];
#endif /* BUILD_DATE */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/creator/creator_signals.c b/source/creator/creator_signals.c
index c016372e6b0..c733ee617cb 100644
--- a/source/creator/creator_signals.c
+++ b/source/creator/creator_signals.c
@@ -66,7 +66,6 @@ static void sig_handle_fpe(int UNUSED(sig))
# endif
/* Handling `Ctrl-C` event in the console. */
-# if !defined(WITH_HEADLESS)
static void sig_handle_blender_esc(int sig)
{
G.is_break = true; /* forces render loop to read queue, not sure if its needed */
@@ -81,7 +80,6 @@ static void sig_handle_blender_esc(int sig)
count++;
}
}
-# endif
static void sig_handle_crash_backtrace(FILE *fp)
{
@@ -103,7 +101,7 @@ static void sig_handle_crash(int signum)
char fname[FILE_MAX];
if (!(G_MAIN && G_MAIN->filepath[0])) {
- BLI_join_dirfile(fname, sizeof(fname), BKE_tempdir_base(), "crash.blend");
+ BLI_path_join(fname, sizeof(fname), BKE_tempdir_base(), "crash.blend");
}
else {
STRNCPY(fname, G_MAIN->filepath);
@@ -124,11 +122,10 @@ static void sig_handle_crash(int signum)
char fname[FILE_MAX];
if (!(G_MAIN && G_MAIN->filepath[0])) {
- BLI_join_dirfile(fname, sizeof(fname), BKE_tempdir_base(), "blender.crash.txt");
+ BLI_path_join(fname, sizeof(fname), BKE_tempdir_base(), "blender.crash.txt");
}
else {
- BLI_join_dirfile(
- fname, sizeof(fname), BKE_tempdir_base(), BLI_path_basename(G_MAIN->filepath));
+ BLI_path_join(fname, sizeof(fname), BKE_tempdir_base(), BLI_path_basename(G_MAIN->filepath));
BLI_path_extension_replace(fname, sizeof(fname), ".crash.txt");
}
diff --git a/source/tools b/source/tools
-Subproject 2a541f164a222ef7bcd036d37687738acee8d94
+Subproject dfa16042bf7149475ad318d29a8202d969982ab
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 6d1c838ad6d..9f634af7143 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -10,31 +10,40 @@ set(TEST_INSTALL_DIR ${CMAKE_INSTALL_PREFIX_WITH_CONFIG})
# Path to Blender and Python executables for all platforms.
if(MSVC)
set(TEST_BLENDER_EXE ${TEST_INSTALL_DIR}/blender.exe)
- set(_default_test_python_exe "${TEST_INSTALL_DIR}/${BLENDER_VERSION_MAJOR}.${BLENDER_VERSION_MINOR}/python/bin/python$<$<CONFIG:Debug>:_d>")
elseif(APPLE)
set(TEST_BLENDER_EXE ${TEST_INSTALL_DIR}/Blender.app/Contents/MacOS/Blender)
- set(_default_test_python_exe ${PYTHON_EXECUTABLE})
else()
if(WITH_INSTALL_PORTABLE)
set(TEST_BLENDER_EXE ${TEST_INSTALL_DIR}/blender)
else()
set(TEST_BLENDER_EXE ${TEST_INSTALL_DIR}/bin/blender)
endif()
- set(_default_test_python_exe ${PYTHON_EXECUTABLE})
endif()
-# The installation directory's Python is the best one to use. However, it can only be there after the install step,
-# which means that Python will never be there on a fresh system. To suit different needs, the user can pass
-# -DTEST_PYTHON_EXE=/path/to/python to CMake.
+# The installation directory's Python is the best one to use. However, it can only be there
+# after the install step, # which means that Python will never be there on a fresh system.
+# To suit different needs, the user can pass `-DTEST_PYTHON_EXE=/path/to/python` to CMake.
if(NOT TEST_PYTHON_EXE)
- set(TEST_PYTHON_EXE ${_default_test_python_exe})
+ set(TEST_PYTHON_EXE ${PYTHON_EXECUTABLE})
message(STATUS "Tests: Using Python executable: ${TEST_PYTHON_EXE}")
elseif(NOT EXISTS ${TEST_PYTHON_EXE})
message(FATAL_ERROR "Tests: TEST_PYTHON_EXE ${TEST_PYTHON_EXE} does not exist")
endif()
-unset(_default_test_python_exe)
+# Include these arguments before all others, they must not interfere with Python execution.
+set(TEST_PYTHON_EXE_EXTRA_ARGS)
+
+# Check if this a Blender managed Python installation, if so, don't add `*.pyc` files.
+if(LIBDIR)
+ path_is_prefix(LIBDIR TEST_PYTHON_EXE _is_prefix)
+ if(_is_prefix)
+ # Keep the Python in Blender's SVN LIBDIR pristine, to avoid conflicts on updating.
+ set(TEST_PYTHON_EXE_EXTRA_ARGS "-B")
+ endif()
+ unset(_is_prefix)
+endif()
+
# For testing with Valgrind
# set(TEST_BLENDER_EXE valgrind --track-origins=yes --error-limit=no ${TEST_BLENDER_EXE})
diff --git a/tests/blender_as_python_module/CMakeLists.txt b/tests/blender_as_python_module/CMakeLists.txt
index 334b3288246..7387d5c41bf 100644
--- a/tests/blender_as_python_module/CMakeLists.txt
+++ b/tests/blender_as_python_module/CMakeLists.txt
@@ -8,8 +8,16 @@ function(add_blender_as_python_module_test testname testscript)
add_test(
NAME ${testname}
- COMMAND ${TEST_PYTHON_EXE} ${testscript} ${ARGN}
+ COMMAND ${TEST_PYTHON_EXE} ${TEST_PYTHON_EXE_EXTRA_ARGS} ${testscript} ${ARGN}
)
+
+ # On macOS, asan library must be loaded early.
+ if(APPLE AND WITH_COMPILER_ASAN)
+ set_tests_properties(
+ ${testname}
+ PROPERTIES ENVIRONMENT DYLD_INSERT_LIBRARIES=${COMPILER_ASAN_LIBRARY}
+ )
+ endif()
endfunction()
-add_blender_as_python_module_test(import_bpy ${CMAKE_CURRENT_LIST_DIR}/import_bpy.py)
+add_blender_as_python_module_test(import_bpy ${CMAKE_CURRENT_LIST_DIR}/import_bpy.py ${CMAKE_INSTALL_PREFIX_WITH_CONFIG})
diff --git a/tests/blender_as_python_module/import_bpy.py b/tests/blender_as_python_module/import_bpy.py
index ea75c0f2fe6..223ed998707 100644
--- a/tests/blender_as_python_module/import_bpy.py
+++ b/tests/blender_as_python_module/import_bpy.py
@@ -1,4 +1,8 @@
# SPDX-License-Identifier: GPL-2.0-or-later
+# Add directory with module to the path.
+import sys
+sys.path.append(sys.argv[1])
+
# Just import bpy and see if there are any dynamic loader errors.
import bpy
diff --git a/tests/gtests/runner/CMakeLists.txt b/tests/gtests/runner/CMakeLists.txt
index 97b95851be8..be0aa65d409 100644
--- a/tests/gtests/runner/CMakeLists.txt
+++ b/tests/gtests/runner/CMakeLists.txt
@@ -27,7 +27,7 @@ else()
endif()
# This builds `bin/tests/blender_test`, but does not add it as a single test.
-BLENDER_SRC_GTEST_EX(
+blender_src_gtest_ex(
NAME blender
SRC "${SRC}"
EXTRA_LIBS "${TEST_LIBS}"
diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt
index ca3070b60ad..14b00ace251 100644
--- a/tests/python/CMakeLists.txt
+++ b/tests/python/CMakeLists.txt
@@ -41,7 +41,7 @@ function(add_python_test testname testscript)
add_test(
NAME ${testname}
- COMMAND ${TEST_PYTHON_EXE} ${testscript} ${ARGN}
+ COMMAND ${TEST_PYTHON_EXE} ${TEST_PYTHON_EXE_EXTRA_ARGS} ${testscript} ${ARGN}
)
set_tests_properties(${testname} PROPERTIES ENVIRONMENT
LSAN_OPTIONS=exitcode=0:$ENV{LSAN_OPTIONS}
@@ -630,15 +630,33 @@ add_blender_test(
)
endif()
+# SVG Import
+if(True)
+ set(_svg_render_tests complex path)
+
+ foreach(render_test ${_svg_render_tests})
+ add_python_test(
+ io_curve_svg_${render_test}
+ ${CMAKE_CURRENT_LIST_DIR}/bl_io_curve_svg_test.py
+ -blender "${TEST_BLENDER_EXE}"
+ -testdir "${TEST_SRC_DIR}/io_tests/svg/${render_test}"
+ -idiff "${OPENIMAGEIO_IDIFF}"
+ -outdir "${TEST_OUT_DIR}/io_curve_svg"
+ )
+ endforeach()
+
+ unset(_svg_render_tests)
+endif()
+
if(WITH_CYCLES OR WITH_OPENGL_RENDER_TESTS)
if(NOT OPENIMAGEIO_IDIFF)
- MESSAGE(WARNING "Disabling render tests because OIIO idiff does not exist")
+ message(WARNING "Disabling render tests because OIIO idiff does not exist")
elseif(NOT EXISTS "${TEST_SRC_DIR}/render/shader")
- MESSAGE(WARNING "Disabling render tests because tests folder does not exist at ${TEST_SRC_DIR}")
+ message(WARNING "Disabling render tests because tests folder does not exist at ${TEST_SRC_DIR}")
elseif(NOT WITH_COMPOSITOR_CPU)
- MESSAGE(WARNING "Disabling render tests because WITH_COMPOSITOR_CPU is disabled")
+ message(WARNING "Disabling render tests because WITH_COMPOSITOR_CPU is disabled")
elseif(NOT WITH_OPENCOLORIO)
- MESSAGE(WARNING "Disabling render tests because WITH_OPENCOLORIO is disabled")
+ message(WARNING "Disabling render tests because WITH_OPENCOLORIO is disabled")
else()
set(render_tests
camera
@@ -677,6 +695,11 @@ if(WITH_CYCLES OR WITH_OPENGL_RENDER_TESTS)
list(APPEND render_tests denoise)
endif()
+ # Disabled until new OpenGL version with deterministic results.
+ #if(WITH_CYCLES_PATH_GUIDING)
+ # list(APPEND render_tests guiding)
+ #endif()
+
if(WITH_OPENGL_RENDER_TESTS)
list(APPEND render_tests grease_pencil)
endif()
@@ -801,15 +824,15 @@ foreach(geo_node_test ${geo_node_tests})
)
endforeach()
else()
- MESSAGE(STATUS "Directory named ${TEST_SRC_DIR}/modeling/geometry_nodes/${geo_node_test}/ Not Found, disabling test.")
+ message(STATUS "Directory named ${TEST_SRC_DIR}/modeling/geometry_nodes/${geo_node_test}/ Not Found, disabling test.")
endif()
endforeach()
if(WITH_OPENGL_DRAW_TESTS)
if(NOT OPENIMAGEIO_IDIFF)
- MESSAGE(STATUS "Disabling OpenGL draw tests because OIIO idiff does not exist")
+ message(STATUS "Disabling OpenGL draw tests because OIIO idiff does not exist")
elseif(NOT EXISTS "${TEST_SRC_DIR}/opengl")
- MESSAGE(STATUS "Disabling OpenGL draw tests because tests folder does not exist at ${TEST_SRC_DIR}")
+ message(STATUS "Disabling OpenGL draw tests because tests folder does not exist at ${TEST_SRC_DIR}")
else()
# Use all subdirectories of opengl folder.
file(GLOB children RELATIVE ${TEST_SRC_DIR}/opengl ${TEST_SRC_DIR}/opengl/*)
@@ -881,7 +904,7 @@ endif()
# SEQUENCER RENDER TESTS
if(NOT OPENIMAGEIO_IDIFF)
- MESSAGE(STATUS "Disabling sequencer render tests because OIIO idiff does not exist")
+ message(STATUS "Disabling sequencer render tests because OIIO idiff does not exist")
else()
set(render_tests
transform
diff --git a/tests/python/bl_blendfile_io.py b/tests/python/bl_blendfile_io.py
index f79ee2a240b..fa63b789751 100644
--- a/tests/python/bl_blendfile_io.py
+++ b/tests/python/bl_blendfile_io.py
@@ -33,7 +33,7 @@ class TestBlendFileSaveLoadBasic(TestHelper):
read_data = self.blender_data_to_tuple(bpy.data, "read_data 1")
# We have orphaned data, which should be removed by file reading, so there should not be equality here.
- assert(orig_data != read_data)
+ assert orig_data != read_data
bpy.data.orphans_purge()
@@ -44,7 +44,7 @@ class TestBlendFileSaveLoadBasic(TestHelper):
read_data = self.blender_data_to_tuple(bpy.data, "read_data 2")
- assert(orig_data == read_data)
+ assert orig_data == read_data
TESTS = (
diff --git a/tests/python/bl_blendfile_liblink.py b/tests/python/bl_blendfile_liblink.py
index 120afba4911..a4ca845da4e 100644
--- a/tests/python/bl_blendfile_liblink.py
+++ b/tests/python/bl_blendfile_liblink.py
@@ -93,9 +93,9 @@ class TestBlendLibLinkSaveLoadBasic(TestBlendLibLinkHelper):
link_dir = os.path.join(output_lib_path, "Mesh")
bpy.ops.wm.link(directory=link_dir, filename="LibMesh", instance_object_data=False)
- assert(len(bpy.data.meshes) == 1)
- assert(len(bpy.data.objects) == 0)
- assert(len(bpy.data.collections) == 0) # Scene's master collection is not listed here
+ assert len(bpy.data.meshes) == 1
+ assert len(bpy.data.objects) == 0
+ assert len(bpy.data.collections) == 0 # Scene's master collection is not listed here
orig_data = self.blender_data_to_tuple(bpy.data, "orig_data")
@@ -106,8 +106,8 @@ class TestBlendLibLinkSaveLoadBasic(TestBlendLibLinkHelper):
read_data = self.blender_data_to_tuple(bpy.data, "read_data")
# Since there is no usage of linked mesh, it is lost during save/reload.
- assert(len(bpy.data.meshes) == 0)
- assert(orig_data != read_data)
+ assert len(bpy.data.meshes) == 0
+ assert orig_data != read_data
# Simple link of a single ObData with obdata instantiation.
self.reset_blender()
@@ -115,9 +115,9 @@ class TestBlendLibLinkSaveLoadBasic(TestBlendLibLinkHelper):
link_dir = os.path.join(output_lib_path, "Mesh")
bpy.ops.wm.link(directory=link_dir, filename="LibMesh", instance_object_data=True)
- assert(len(bpy.data.meshes) == 1)
- assert(len(bpy.data.objects) == 1) # Instance created for the mesh ObData.
- assert(len(bpy.data.collections) == 0) # Scene's master collection is not listed here
+ assert len(bpy.data.meshes) == 1
+ assert len(bpy.data.objects) == 1 # Instance created for the mesh ObData.
+ assert len(bpy.data.collections) == 0 # Scene's master collection is not listed here
orig_data = self.blender_data_to_tuple(bpy.data, "orig_data")
@@ -126,7 +126,7 @@ class TestBlendLibLinkSaveLoadBasic(TestBlendLibLinkHelper):
read_data = self.blender_data_to_tuple(bpy.data, "read_data")
- assert(orig_data == read_data)
+ assert orig_data == read_data
# Simple link of a single Object.
self.reset_blender()
@@ -134,9 +134,9 @@ class TestBlendLibLinkSaveLoadBasic(TestBlendLibLinkHelper):
link_dir = os.path.join(output_lib_path, "Object")
bpy.ops.wm.link(directory=link_dir, filename="LibMesh")
- assert(len(bpy.data.meshes) == 1)
- assert(len(bpy.data.objects) == 1)
- assert(len(bpy.data.collections) == 0) # Scene's master collection is not listed here
+ assert len(bpy.data.meshes) == 1
+ assert len(bpy.data.objects) == 1
+ assert len(bpy.data.collections) == 0 # Scene's master collection is not listed here
orig_data = self.blender_data_to_tuple(bpy.data, "orig_data")
@@ -145,7 +145,7 @@ class TestBlendLibLinkSaveLoadBasic(TestBlendLibLinkHelper):
read_data = self.blender_data_to_tuple(bpy.data, "read_data")
- assert(orig_data == read_data)
+ assert orig_data == read_data
# Simple link of a single Collection, with Empty-instantiation.
self.reset_blender()
@@ -153,9 +153,9 @@ class TestBlendLibLinkSaveLoadBasic(TestBlendLibLinkHelper):
link_dir = os.path.join(output_lib_path, "Collection")
bpy.ops.wm.link(directory=link_dir, filename="LibMesh", instance_collections=True)
- assert(len(bpy.data.meshes) == 1)
- assert(len(bpy.data.objects) == 2) # linked object and local empty instancing the collection
- assert(len(bpy.data.collections) == 1) # Scene's master collection is not listed here
+ assert len(bpy.data.meshes) == 1
+ assert len(bpy.data.objects) == 2 # linked object and local empty instancing the collection
+ assert len(bpy.data.collections) == 1 # Scene's master collection is not listed here
orig_data = self.blender_data_to_tuple(bpy.data, "orig_data")
@@ -164,7 +164,7 @@ class TestBlendLibLinkSaveLoadBasic(TestBlendLibLinkHelper):
read_data = self.blender_data_to_tuple(bpy.data, "read_data")
- assert(orig_data == read_data)
+ assert orig_data == read_data
# Simple link of a single Collection, with ViewLayer-instantiation.
self.reset_blender()
@@ -172,11 +172,11 @@ class TestBlendLibLinkSaveLoadBasic(TestBlendLibLinkHelper):
link_dir = os.path.join(output_lib_path, "Collection")
bpy.ops.wm.link(directory=link_dir, filename="LibMesh", instance_collections=False)
- assert(len(bpy.data.meshes) == 1)
- assert(len(bpy.data.objects) == 1)
- assert(len(bpy.data.collections) == 1) # Scene's master collection is not listed here
+ assert len(bpy.data.meshes) == 1
+ assert len(bpy.data.objects) == 1
+ assert len(bpy.data.collections) == 1 # Scene's master collection is not listed here
# Linked collection should have been added to the scene's master collection children.
- assert(bpy.data.collections[0] in set(bpy.data.scenes[0].collection.children))
+ assert bpy.data.collections[0] in set(bpy.data.scenes[0].collection.children)
orig_data = self.blender_data_to_tuple(bpy.data, "orig_data")
@@ -185,7 +185,7 @@ class TestBlendLibLinkSaveLoadBasic(TestBlendLibLinkHelper):
read_data = self.blender_data_to_tuple(bpy.data, "read_data")
- assert(orig_data == read_data)
+ assert orig_data == read_data
class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
@@ -211,15 +211,15 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
bpy.data.materials[0].use_fake_user,
)
- assert(len(bpy.data.materials) == 1)
- assert(bpy.data.materials[0].library is not None)
- assert(bpy.data.materials[0].users == 2) # Fake user is not cleared when linking.
- assert(len(bpy.data.meshes) == 1)
- assert(bpy.data.meshes[0].library is None)
- assert(bpy.data.meshes[0].use_fake_user is False)
- assert(bpy.data.meshes[0].users == 0)
- assert(len(bpy.data.objects) == 0)
- assert(len(bpy.data.collections) == 0) # Scene's master collection is not listed here
+ assert len(bpy.data.materials) == 1
+ assert bpy.data.materials[0].library is not None
+ assert bpy.data.materials[0].users == 2 # Fake user is not cleared when linking.
+ assert len(bpy.data.meshes) == 1
+ assert bpy.data.meshes[0].library is None
+ assert bpy.data.meshes[0].use_fake_user is False
+ assert bpy.data.meshes[0].users == 0
+ assert len(bpy.data.objects) == 0
+ assert len(bpy.data.collections) == 0 # Scene's master collection is not listed here
# Simple append of a single ObData with obdata instantiation.
self.reset_blender()
@@ -228,16 +228,16 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
instance_object_data=True, set_fake=False, use_recursive=False, do_reuse_local_id=False)
- assert(len(bpy.data.materials) == 1)
- assert(bpy.data.materials[0].library is not None)
- assert(bpy.data.materials[0].users == 2) # Fake user is not cleared when linking.
- assert(len(bpy.data.meshes) == 1)
- assert(bpy.data.meshes[0].library is None)
- assert(bpy.data.meshes[0].use_fake_user is False)
- assert(bpy.data.meshes[0].users == 1)
- assert(len(bpy.data.objects) == 1) # Instance created for the mesh ObData.
- assert(bpy.data.objects[0].library is None)
- assert(len(bpy.data.collections) == 0) # Scene's master collection is not listed here
+ assert len(bpy.data.materials) == 1
+ assert bpy.data.materials[0].library is not None
+ assert bpy.data.materials[0].users == 2 # Fake user is not cleared when linking.
+ assert len(bpy.data.meshes) == 1
+ assert bpy.data.meshes[0].library is None
+ assert bpy.data.meshes[0].use_fake_user is False
+ assert bpy.data.meshes[0].users == 1
+ assert len(bpy.data.objects) == 1 # Instance created for the mesh ObData.
+ assert bpy.data.objects[0].library is None
+ assert len(bpy.data.collections) == 0 # Scene's master collection is not listed here
# Simple append of a single ObData with fake user.
self.reset_blender()
@@ -246,15 +246,15 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
instance_object_data=False, set_fake=True, use_recursive=False, do_reuse_local_id=False)
- assert(len(bpy.data.materials) == 1)
- assert(bpy.data.materials[0].library is not None)
- assert(bpy.data.materials[0].users == 2) # Fake user is not cleared when linking.
- assert(len(bpy.data.meshes) == 1)
- assert(bpy.data.meshes[0].library is None)
- assert(bpy.data.meshes[0].use_fake_user is True)
- assert(bpy.data.meshes[0].users == 1)
- assert(len(bpy.data.objects) == 0)
- assert(len(bpy.data.collections) == 0) # Scene's master collection is not listed here
+ assert len(bpy.data.materials) == 1
+ assert bpy.data.materials[0].library is not None
+ assert bpy.data.materials[0].users == 2 # Fake user is not cleared when linking.
+ assert len(bpy.data.meshes) == 1
+ assert bpy.data.meshes[0].library is None
+ assert bpy.data.meshes[0].use_fake_user is True
+ assert bpy.data.meshes[0].users == 1
+ assert len(bpy.data.objects) == 0
+ assert len(bpy.data.collections) == 0 # Scene's master collection is not listed here
# Simple append of a single Object.
self.reset_blender()
@@ -263,16 +263,16 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
instance_object_data=False, set_fake=False, use_recursive=False, do_reuse_local_id=False)
- assert(len(bpy.data.materials) == 1)
- assert(bpy.data.materials[0].library is not None)
- assert(bpy.data.materials[0].users == 2) # Fake user is not cleared when linking.
- assert(len(bpy.data.meshes) == 1)
- assert(bpy.data.meshes[0].library is None)
- assert(bpy.data.meshes[0].users == 1)
- assert(len(bpy.data.objects) == 1)
- assert(bpy.data.objects[0].library is None)
- assert(bpy.data.objects[0].users == 1)
- assert(len(bpy.data.collections) == 0) # Scene's master collection is not listed here
+ assert len(bpy.data.materials) == 1
+ assert bpy.data.materials[0].library is not None
+ assert bpy.data.materials[0].users == 2 # Fake user is not cleared when linking.
+ assert len(bpy.data.meshes) == 1
+ assert bpy.data.meshes[0].library is None
+ assert bpy.data.meshes[0].users == 1
+ assert len(bpy.data.objects) == 1
+ assert bpy.data.objects[0].library is None
+ assert bpy.data.objects[0].users == 1
+ assert len(bpy.data.collections) == 0 # Scene's master collection is not listed here
# Simple recursive append of a single Object.
self.reset_blender()
@@ -281,16 +281,16 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
instance_object_data=False, set_fake=False, use_recursive=True, do_reuse_local_id=False)
- assert(len(bpy.data.materials) == 1)
- assert(bpy.data.materials[0].library is None)
- assert(bpy.data.materials[0].users == 1) # Fake user is cleared when appending.
- assert(len(bpy.data.meshes) == 1)
- assert(bpy.data.meshes[0].library is None)
- assert(bpy.data.meshes[0].users == 1)
- assert(len(bpy.data.objects) == 1)
- assert(bpy.data.objects[0].library is None)
- assert(bpy.data.objects[0].users == 1)
- assert(len(bpy.data.collections) == 0) # Scene's master collection is not listed here
+ assert len(bpy.data.materials) == 1
+ assert bpy.data.materials[0].library is None
+ assert bpy.data.materials[0].users == 1 # Fake user is cleared when appending.
+ assert len(bpy.data.meshes) == 1
+ assert bpy.data.meshes[0].library is None
+ assert bpy.data.meshes[0].users == 1
+ assert len(bpy.data.objects) == 1
+ assert bpy.data.objects[0].library is None
+ assert bpy.data.objects[0].users == 1
+ assert len(bpy.data.collections) == 0 # Scene's master collection is not listed here
# Simple recursive append of a single Collection.
self.reset_blender()
@@ -299,17 +299,17 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
instance_object_data=False, set_fake=False, use_recursive=True, do_reuse_local_id=False)
- assert(len(bpy.data.materials) == 1)
- assert(bpy.data.materials[0].library is None)
- assert(bpy.data.materials[0].users == 1) # Fake user is cleared when appending.
- assert(bpy.data.meshes[0].library is None)
- assert(bpy.data.meshes[0].users == 1)
- assert(len(bpy.data.objects) == 1)
- assert(bpy.data.objects[0].library is None)
- assert(bpy.data.objects[0].users == 1)
- assert(len(bpy.data.collections) == 1) # Scene's master collection is not listed here
- assert(bpy.data.collections[0].library is None)
- assert(bpy.data.collections[0].users == 1)
+ assert len(bpy.data.materials) == 1
+ assert bpy.data.materials[0].library is None
+ assert bpy.data.materials[0].users == 1 # Fake user is cleared when appending.
+ assert bpy.data.meshes[0].library is None
+ assert bpy.data.meshes[0].users == 1
+ assert len(bpy.data.objects) == 1
+ assert bpy.data.objects[0].library is None
+ assert bpy.data.objects[0].users == 1
+ assert len(bpy.data.collections) == 1 # Scene's master collection is not listed here
+ assert bpy.data.collections[0].library is None
+ assert bpy.data.collections[0].users == 1
class TestBlendLibAppendReuseID(TestBlendLibLinkHelper):
@@ -328,51 +328,51 @@ class TestBlendLibAppendReuseID(TestBlendLibLinkHelper):
bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
instance_object_data=False, set_fake=False, use_recursive=True, do_reuse_local_id=False)
- assert(len(bpy.data.meshes) == 1)
- assert(bpy.data.meshes[0].library is None)
- assert(bpy.data.meshes[0].use_fake_user is False)
- assert(bpy.data.meshes[0].users == 1)
- assert(bpy.data.meshes[0].library_weak_reference is not None)
- assert(bpy.data.meshes[0].library_weak_reference.filepath == output_lib_path)
- assert(bpy.data.meshes[0].library_weak_reference.id_name == "MELibMesh")
- assert(len(bpy.data.objects) == 1)
+ assert len(bpy.data.meshes) == 1
+ assert bpy.data.meshes[0].library is None
+ assert bpy.data.meshes[0].use_fake_user is False
+ assert bpy.data.meshes[0].users == 1
+ assert bpy.data.meshes[0].library_weak_reference is not None
+ assert bpy.data.meshes[0].library_weak_reference.filepath == output_lib_path
+ assert bpy.data.meshes[0].library_weak_reference.id_name == "MELibMesh"
+ assert len(bpy.data.objects) == 1
for ob in bpy.data.objects:
- assert(ob.library is None)
- assert(ob.library_weak_reference is None)
- assert(len(bpy.data.collections) == 0) # Scene's master collection is not listed here
+ assert ob.library is None
+ assert ob.library_weak_reference is None
+ assert len(bpy.data.collections) == 0 # Scene's master collection is not listed here
bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
instance_object_data=False, set_fake=False, use_recursive=True, do_reuse_local_id=True)
- assert(len(bpy.data.meshes) == 1)
- assert(bpy.data.meshes[0].library is None)
- assert(bpy.data.meshes[0].use_fake_user is False)
- assert(bpy.data.meshes[0].users == 2)
- assert(bpy.data.meshes[0].library_weak_reference is not None)
- assert(bpy.data.meshes[0].library_weak_reference.filepath == output_lib_path)
- assert(bpy.data.meshes[0].library_weak_reference.id_name == "MELibMesh")
- assert(len(bpy.data.objects) == 2)
+ assert len(bpy.data.meshes) == 1
+ assert bpy.data.meshes[0].library is None
+ assert bpy.data.meshes[0].use_fake_user is False
+ assert bpy.data.meshes[0].users == 2
+ assert bpy.data.meshes[0].library_weak_reference is not None
+ assert bpy.data.meshes[0].library_weak_reference.filepath == output_lib_path
+ assert bpy.data.meshes[0].library_weak_reference.id_name == "MELibMesh"
+ assert len(bpy.data.objects) == 2
for ob in bpy.data.objects:
- assert(ob.library is None)
- assert(ob.library_weak_reference is None)
- assert(len(bpy.data.collections) == 0) # Scene's master collection is not listed here
+ assert ob.library is None
+ assert ob.library_weak_reference is None
+ assert len(bpy.data.collections) == 0 # Scene's master collection is not listed here
bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
instance_object_data=False, set_fake=False, use_recursive=True, do_reuse_local_id=False)
- assert(len(bpy.data.meshes) == 2)
- assert(bpy.data.meshes[0].library_weak_reference is None)
- assert(bpy.data.meshes[1].library is None)
- assert(bpy.data.meshes[1].use_fake_user is False)
- assert(bpy.data.meshes[1].users == 1)
- assert(bpy.data.meshes[1].library_weak_reference is not None)
- assert(bpy.data.meshes[1].library_weak_reference.filepath == output_lib_path)
- assert(bpy.data.meshes[1].library_weak_reference.id_name == "MELibMesh")
- assert(len(bpy.data.objects) == 3)
+ assert len(bpy.data.meshes) == 2
+ assert bpy.data.meshes[0].library_weak_reference is None
+ assert bpy.data.meshes[1].library is None
+ assert bpy.data.meshes[1].use_fake_user is False
+ assert bpy.data.meshes[1].users == 1
+ assert bpy.data.meshes[1].library_weak_reference is not None
+ assert bpy.data.meshes[1].library_weak_reference.filepath == output_lib_path
+ assert bpy.data.meshes[1].library_weak_reference.id_name == "MELibMesh"
+ assert len(bpy.data.objects) == 3
for ob in bpy.data.objects:
- assert(ob.library is None)
- assert(ob.library_weak_reference is None)
- assert(len(bpy.data.collections) == 0) # Scene's master collection is not listed here
+ assert ob.library is None
+ assert ob.library_weak_reference is None
+ assert len(bpy.data.collections) == 0 # Scene's master collection is not listed here
class TestBlendLibLibraryReload(TestBlendLibLinkHelper):
@@ -390,9 +390,9 @@ class TestBlendLibLibraryReload(TestBlendLibLinkHelper):
link_dir = os.path.join(output_lib_path, "Object")
bpy.ops.wm.link(directory=link_dir, filename="LibMesh")
- assert(len(bpy.data.meshes) == 1)
- assert(len(bpy.data.objects) == 1)
- assert(len(bpy.data.collections) == 0) # Scene's master collection is not listed here
+ assert len(bpy.data.meshes) == 1
+ assert len(bpy.data.objects) == 1
+ assert len(bpy.data.collections) == 0 # Scene's master collection is not listed here
orig_data = self.blender_data_to_tuple(bpy.data, "orig_data")
@@ -402,7 +402,7 @@ class TestBlendLibLibraryReload(TestBlendLibLinkHelper):
print(orig_data)
print(reload_data)
- assert(orig_data == reload_data)
+ assert orig_data == reload_data
class TestBlendLibLibraryRelocate(TestBlendLibLinkHelper):
@@ -420,9 +420,9 @@ class TestBlendLibLibraryRelocate(TestBlendLibLinkHelper):
link_dir = os.path.join(output_lib_path, "Object")
bpy.ops.wm.link(directory=link_dir, filename="LibMesh")
- assert(len(bpy.data.meshes) == 1)
- assert(len(bpy.data.objects) == 1)
- assert(len(bpy.data.collections) == 0) # Scene's master collection is not listed here
+ assert len(bpy.data.meshes) == 1
+ assert len(bpy.data.objects) == 1
+ assert len(bpy.data.collections) == 0 # Scene's master collection is not listed here
orig_data = self.blender_data_to_tuple(bpy.data, "orig_data")
@@ -436,7 +436,7 @@ class TestBlendLibLibraryRelocate(TestBlendLibLinkHelper):
print(orig_data)
print(relocate_data)
- assert(orig_data == relocate_data)
+ assert orig_data == relocate_data
class TestBlendLibDataLibrariesLoad(TestBlendLibLinkHelper):
@@ -454,21 +454,21 @@ class TestBlendLibDataLibrariesLoad(TestBlendLibLinkHelper):
with bpy.data.libraries.load(filepath=output_lib_path) as lib_ctx:
lib_src, lib_link = lib_ctx
- assert(len(lib_src.meshes) == 1)
- assert(len(lib_src.objects) == 1)
- assert(len(lib_src.collections) == 1)
+ assert len(lib_src.meshes) == 1
+ assert len(lib_src.objects) == 1
+ assert len(lib_src.collections) == 1
- assert(len(lib_link.meshes) == 0)
- assert(len(lib_link.objects) == 0)
- assert(len(lib_link.collections) == 0)
+ assert len(lib_link.meshes) == 0
+ assert len(lib_link.objects) == 0
+ assert len(lib_link.collections) == 0
lib_link.collections.append(lib_src.collections[0])
# Linking happens when living the context manager.
- assert(len(bpy.data.meshes) == 1)
- assert(len(bpy.data.objects) == 1) # This code does no instantiation.
- assert(len(bpy.data.collections) == 1)
+ assert len(bpy.data.meshes) == 1
+ assert len(bpy.data.objects) == 1 # This code does no instantiation.
+ assert len(bpy.data.collections) == 1
TESTS = (
diff --git a/tests/python/bl_blendfile_library_overrides.py b/tests/python/bl_blendfile_library_overrides.py
index 3ba99bd61e4..6890bb1e660 100644
--- a/tests/python/bl_blendfile_library_overrides.py
+++ b/tests/python/bl_blendfile_library_overrides.py
@@ -57,49 +57,49 @@ class TestLibraryOverrides(TestHelper, unittest.TestCase):
local_id = obj.override_create()
self.assertIsNotNone(local_id.override_library)
self.assertIsNone(local_id.data.override_library)
- assert(len(local_id.override_library.properties) == 0)
+ assert len(local_id.override_library.properties) == 0
# #### Generate an override property & operation automatically by editing the local override data.
local_id.location.y = 1.0
local_id.override_library.operations_update()
- assert(len(local_id.override_library.properties) == 1)
+ assert len(local_id.override_library.properties) == 1
override_prop = local_id.override_library.properties[0]
- assert(override_prop.rna_path == "location")
- assert(len(override_prop.operations) == 1)
+ assert override_prop.rna_path == "location"
+ assert len(override_prop.operations) == 1
override_operation = override_prop.operations[0]
- assert(override_operation.operation == 'REPLACE')
+ assert override_operation.operation == 'REPLACE'
# Setting location.y overrode all elements in the location array. -1 is a wildcard.
- assert(override_operation.subitem_local_index == -1)
+ assert override_operation.subitem_local_index == -1
# #### Reset the override to its linked reference data.
local_id.override_library.reset()
- assert(len(local_id.override_library.properties) == 0)
- assert(local_id.location == local_id.override_library.reference.location)
+ assert len(local_id.override_library.properties) == 0
+ assert local_id.location == local_id.override_library.reference.location
# #### Generate an override property & operation manually using the API.
override_property = local_id.override_library.properties.add(rna_path="location")
override_property.operations.add(operation='REPLACE')
- assert(len(local_id.override_library.properties) == 1)
+ assert len(local_id.override_library.properties) == 1
override_prop = local_id.override_library.properties[0]
- assert(override_prop.rna_path == "location")
- assert(len(override_prop.operations) == 1)
+ assert override_prop.rna_path == "location"
+ assert len(override_prop.operations) == 1
override_operation = override_prop.operations[0]
- assert(override_operation.operation == 'REPLACE')
+ assert override_operation.operation == 'REPLACE'
# Setting location.y overrode all elements in the location array. -1 is a wildcard.
- assert(override_operation.subitem_local_index == -1)
+ assert override_operation.subitem_local_index == -1
override_property = local_id.override_library.properties[0]
override_property.operations.remove(override_property.operations[0])
local_id.override_library.properties.remove(override_property)
- assert(len(local_id.override_library.properties) == 0)
+ assert len(local_id.override_library.properties) == 0
# #### Delete the override.
local_id_name = local_id.name
- assert(bpy.data.objects.get((local_id_name, None), None) == local_id)
+ assert bpy.data.objects.get((local_id_name, None), None) == local_id
local_id.override_library.destroy()
- assert(bpy.data.objects.get((local_id_name, None), None) is None)
+ assert bpy.data.objects.get((local_id_name, None), None) is None
def test_link_permissive(self):
"""
@@ -119,39 +119,39 @@ class TestLibraryOverrides(TestHelper, unittest.TestCase):
local_id = obj.override_create()
self.assertIsNotNone(local_id.override_library)
self.assertIsNone(local_id.data.override_library)
- assert(len(local_id.override_library.properties) == 1)
+ assert len(local_id.override_library.properties) == 1
override_prop = local_id.override_library.properties[0]
- assert(override_prop.rna_path == "scale")
- assert(len(override_prop.operations) == 1)
+ assert override_prop.rna_path == "scale"
+ assert len(override_prop.operations) == 1
override_operation = override_prop.operations[0]
- assert(override_operation.operation == 'NOOP')
- assert(override_operation.subitem_local_index == -1)
+ assert override_operation.operation == 'NOOP'
+ assert override_operation.subitem_local_index == -1
local_id.location.y = 1.0
local_id.scale.x = 0.5
# `scale.x` will apply, but will be reverted when the library overrides
# are updated. This is by design so python scripts can still alter the
# properties locally what is a typical usecase in productions.
- assert(local_id.scale.x == 0.5)
- assert(local_id.location.y == 1.0)
+ assert local_id.scale.x == 0.5
+ assert local_id.location.y == 1.0
local_id.override_library.operations_update()
- assert(local_id.scale.x == 1.0)
- assert(local_id.location.y == 1.0)
+ assert local_id.scale.x == 1.0
+ assert local_id.location.y == 1.0
- assert(len(local_id.override_library.properties) == 2)
+ assert len(local_id.override_library.properties) == 2
override_prop = local_id.override_library.properties[0]
- assert(override_prop.rna_path == "scale")
- assert(len(override_prop.operations) == 1)
+ assert override_prop.rna_path == "scale"
+ assert len(override_prop.operations) == 1
override_operation = override_prop.operations[0]
- assert(override_operation.operation == 'NOOP')
- assert(override_operation.subitem_local_index == -1)
+ assert override_operation.operation == 'NOOP'
+ assert override_operation.subitem_local_index == -1
override_prop = local_id.override_library.properties[1]
- assert(override_prop.rna_path == "location")
- assert(len(override_prop.operations) == 1)
+ assert override_prop.rna_path == "location"
+ assert len(override_prop.operations) == 1
override_operation = override_prop.operations[0]
- assert(override_operation.operation == 'REPLACE')
- assert (override_operation.subitem_local_index == -1)
+ assert override_operation.operation == 'REPLACE'
+ assert override_operation.subitem_local_index == -1
class TestLibraryTemplate(TestHelper, unittest.TestCase):
@@ -169,16 +169,16 @@ class TestLibraryTemplate(TestHelper, unittest.TestCase):
mesh = bpy.data.meshes.new(TestLibraryTemplate.MESH_LIBRARY_PERMISSIVE)
obj = bpy.data.objects.new(TestLibraryTemplate.OBJECT_LIBRARY_PERMISSIVE, object_data=mesh)
bpy.context.collection.objects.link(obj)
- assert(obj.override_library is None)
+ assert obj.override_library is None
obj.override_template_create()
- assert(obj.override_library is not None)
- assert(len(obj.override_library.properties) == 0)
+ assert obj.override_library is not None
+ assert len(obj.override_library.properties) == 0
prop = obj.override_library.properties.add(rna_path='scale')
- assert(len(obj.override_library.properties) == 1)
- assert(len(prop.operations) == 0)
+ assert len(obj.override_library.properties) == 1
+ assert len(prop.operations) == 0
operation = prop.operations.add(operation='NOOP')
- assert(len(prop.operations) == 1)
- assert(operation.operation == 'NOOP')
+ assert len(prop.operations) == 1
+ assert operation.operation == 'NOOP'
class TestLibraryOverridesResync(TestHelper, unittest.TestCase):
@@ -237,30 +237,30 @@ class TestLibraryOverridesResync(TestHelper, unittest.TestCase):
)
linked_collection_container = bpy.data.collections[TestLibraryOverridesResync.DATA_NAME_CONTAINER]
- assert(linked_collection_container.library is not None)
- assert(linked_collection_container.override_library is None)
- assert(len(bpy.data.collections) == 2)
- assert(all(id_.library is not None for id_ in bpy.data.collections))
- assert(len(bpy.data.objects) == 4)
- assert(all(id_.library is not None for id_ in bpy.data.objects))
- assert(len(bpy.data.meshes) == 1)
- assert(all(id_.library is not None for id_ in bpy.data.meshes))
- assert(len(bpy.data.armatures) == 1)
- assert(all(id_.library is not None for id_ in bpy.data.armatures))
+ assert linked_collection_container.library is not None
+ assert linked_collection_container.override_library is None
+ assert len(bpy.data.collections) == 2
+ assert all(id_.library is not None for id_ in bpy.data.collections)
+ assert len(bpy.data.objects) == 4
+ assert all(id_.library is not None for id_ in bpy.data.objects)
+ assert len(bpy.data.meshes) == 1
+ assert all(id_.library is not None for id_ in bpy.data.meshes)
+ assert len(bpy.data.armatures) == 1
+ assert all(id_.library is not None for id_ in bpy.data.armatures)
override_collection_container = linked_collection_container.override_hierarchy_create(
bpy.context.scene,
bpy.context.view_layer,
)
- assert(override_collection_container.library is None)
- assert(override_collection_container.override_library is not None)
+ assert override_collection_container.library is None
+ assert override_collection_container.override_library is not None
# Objects and collections are duplicated as overrides, but meshes and armatures remain only linked data.
- assert(len(bpy.data.collections) == 4)
- assert(all((id_.library is None and id_.override_library is not None) for id_ in bpy.data.collections[:2]))
- assert(len(bpy.data.objects) == 8)
- assert(all((id_.library is None and id_.override_library is not None) for id_ in bpy.data.objects[:4]))
- assert(len(bpy.data.meshes) == 1)
- assert(len(bpy.data.armatures) == 1)
+ assert len(bpy.data.collections) == 4
+ assert all((id_.library is None and id_.override_library is not None) for id_ in bpy.data.collections[:2])
+ assert len(bpy.data.objects) == 8
+ assert all((id_.library is None and id_.override_library is not None) for id_ in bpy.data.objects[:4])
+ assert len(bpy.data.meshes) == 1
+ assert len(bpy.data.armatures) == 1
bpy.ops.wm.save_as_mainfile(filepath=str(self.test_output_path), check_existing=False, compress=False)
@@ -279,21 +279,21 @@ class TestLibraryOverridesResync(TestHelper, unittest.TestCase):
bpy.ops.wm.open_mainfile(filepath=str(self.test_output_path))
override_collection_container = bpy.data.collections[TestLibraryOverridesResync.DATA_NAME_CONTAINER]
- assert(override_collection_container.library is None)
- assert(override_collection_container.override_library is not None)
+ assert override_collection_container.library is None
+ assert override_collection_container.override_library is not None
# Objects and collections are duplicated as overrides, but meshes and armatures remain only linked data.
- assert(len(bpy.data.collections) == 4)
- assert(all((id_.library is None and id_.override_library is not None) for id_ in bpy.data.collections[:2]))
- assert(len(bpy.data.objects) == 8)
- assert(all((id_.library is None and id_.override_library is not None) for id_ in bpy.data.objects[:4]))
- assert(len(bpy.data.meshes) == 1)
- assert(len(bpy.data.armatures) == 1)
+ assert len(bpy.data.collections) == 4
+ assert all((id_.library is None and id_.override_library is not None) for id_ in bpy.data.collections[:2])
+ assert len(bpy.data.objects) == 8
+ assert all((id_.library is None and id_.override_library is not None) for id_ in bpy.data.objects[:4])
+ assert len(bpy.data.meshes) == 1
+ assert len(bpy.data.armatures) == 1
obj_armature = bpy.data.objects[TestLibraryOverridesResync.DATA_NAME_RIG]
obj_ctrl2 = bpy.data.objects[TestLibraryOverridesResync.DATA_NAME_CONTROLLER_2]
- assert(obj_armature.library is None and obj_armature.override_library is not None)
- assert(obj_ctrl2.library is None and obj_ctrl2.override_library is not None)
- assert(obj_armature.constraints[0].target == obj_ctrl2)
+ assert obj_armature.library is None and obj_armature.override_library is not None
+ assert obj_ctrl2.library is None and obj_ctrl2.override_library is not None
+ assert obj_armature.constraints[0].target == obj_ctrl2
TESTS = (
diff --git a/tests/python/bl_io_curve_svg_test.py b/tests/python/bl_io_curve_svg_test.py
new file mode 100644
index 00000000000..f36036a5b52
--- /dev/null
+++ b/tests/python/bl_io_curve_svg_test.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: Apache-2.0
+
+import argparse
+import os
+import sys
+from pathlib import Path
+
+
+def get_arguments(filepath, output_filepath):
+ dirname = os.path.dirname(filepath)
+ basedir = os.path.dirname(dirname)
+
+ args = [
+ "--background",
+ "-noaudio",
+ "--factory-startup",
+ "--enable-autoexec",
+ "--debug-memory",
+ "--debug-exit-on-error",
+ filepath,
+ "-E", "CYCLES",
+ "-o", output_filepath,
+ "-F", "PNG",
+ "--python", os.path.join(basedir, "util", "import_svg.py"),
+ "-f", "1",
+ ]
+
+ return args
+
+
+def create_argparse():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-blender", nargs="+")
+ parser.add_argument("-testdir", nargs=1)
+ parser.add_argument("-outdir", nargs=1)
+ parser.add_argument("-idiff", nargs=1)
+ return parser
+
+
+def main():
+ parser = create_argparse()
+ args = parser.parse_args()
+
+ blender = args.blender[0]
+ test_dir = args.testdir[0]
+ idiff = args.idiff[0]
+ output_dir = args.outdir[0]
+
+ from modules import render_report
+ report = render_report.Report('IO Curve SVG', output_dir, idiff)
+ report.set_pixelated(True)
+
+ test_dir_name = Path(test_dir).name
+ if test_dir_name == 'complex':
+ report.set_fail_percent(0.01)
+
+ ok = report.run(test_dir, blender, get_arguments, batch=True)
+
+ sys.exit(not ok)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/python/bl_keymap_validate.py b/tests/python/bl_keymap_validate.py
index 83d41c8a9f6..11da4d562b0 100644
--- a/tests/python/bl_keymap_validate.py
+++ b/tests/python/bl_keymap_validate.py
@@ -228,7 +228,7 @@ def keyconfig_activate_and_extract_data(
bpy.ops.preferences.keyconfig_activate(filepath=filepath)
# If called multiple times, something strange is happening.
- assert(len(args_collected) == 1)
+ assert len(args_collected) == 1
args, _kw = args_collected[0]
# Ignore the type check as `temp_fn_argument_extractor` is a generic function
# which doesn't contain type information of the function being wrapped.
diff --git a/tests/python/bl_load_addons.py b/tests/python/bl_load_addons.py
index b94c56541af..8c90a1f93b8 100644
--- a/tests/python/bl_load_addons.py
+++ b/tests/python/bl_load_addons.py
@@ -14,7 +14,7 @@ import sys
import importlib
BLACKLIST_DIRS = (
- os.path.join(bpy.utils.resource_path('USER'), "scripts"),
+ bpy.utils.user_resource('SCRIPTS'),
) + tuple(addon_utils.paths()[1:])
BLACKLIST_ADDONS = set()
@@ -57,7 +57,7 @@ def disable_addons():
addons = bpy.context.preferences.addons
for mod_name in list(addons.keys()):
addon_utils.disable(mod_name, default_set=True)
- assert(bool(addons) is False)
+ assert bool(addons) is False
def test_load_addons():
@@ -97,13 +97,13 @@ def reload_addons(do_reload=True, do_reverse=True):
mod_name = mod.__name__
print("\tenabling:", mod_name)
addon_utils.enable(mod_name, default_set=True)
- assert(mod_name in addons)
+ assert mod_name in addons
for mod in modules:
mod_name = mod.__name__
print("\tdisabling:", mod_name)
addon_utils.disable(mod_name, default_set=True)
- assert(not (mod_name in addons))
+ assert not (mod_name in addons)
# now test reloading
if do_reload:
diff --git a/tests/python/bl_load_py_modules.py b/tests/python/bl_load_py_modules.py
index 7ad5895ce86..48087179554 100644
--- a/tests/python/bl_load_py_modules.py
+++ b/tests/python/bl_load_py_modules.py
@@ -42,7 +42,7 @@ if not bpy.app.build_options.xr_openxr:
BLACKLIST.add("viewport_vr_preview")
BLACKLIST_DIRS = (
- os.path.join(bpy.utils.resource_path('USER'), "scripts"),
+ os.path.join(bpy.utils.user_resource('SCRIPTS')),
) + tuple(addon_utils.paths()[1:])
@@ -161,7 +161,7 @@ def load_modules():
sys.path[:] = sys_path_back
# check we load what we ask for.
- assert(os.path.samefile(mod_imp.__file__, submod_full))
+ assert os.path.samefile(mod_imp.__file__, submod_full)
modules.append(mod_imp)
except Exception:
diff --git a/tests/python/bl_mesh_modifiers.py b/tests/python/bl_mesh_modifiers.py
index 640cf1c30f2..5498316b267 100644
--- a/tests/python/bl_mesh_modifiers.py
+++ b/tests/python/bl_mesh_modifiers.py
@@ -55,8 +55,8 @@ def render_gl(context, filepath, shade):
def render_gl_all_modes(context, obj, filepath=""):
- assert(obj is not None)
- assert(filepath != "")
+ assert obj is not None
+ assert filepath != ""
scene = context.scene
@@ -91,7 +91,7 @@ def render_gl_all_modes(context, obj, filepath=""):
render_gl(context, filepath + "_wp_wire", shade='WIREFRAME')
- assert(1)
+ assert 1
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
diff --git a/tests/python/bl_pyapi_idprop.py b/tests/python/bl_pyapi_idprop.py
index ddb5be03594..ddce132dd5a 100644
--- a/tests/python/bl_pyapi_idprop.py
+++ b/tests/python/bl_pyapi_idprop.py
@@ -22,7 +22,7 @@ class TestHelper:
def setUp(self):
self._id = bpy.context.scene
self._id.pop("cycles", None)
- assert(len(self._id.keys()) == 0)
+ assert len(self._id.keys()) == 0
def tearDown(self):
for key in list(self._id.keys()):
diff --git a/tests/python/bl_rna_manual_reference.py b/tests/python/bl_rna_manual_reference.py
index 257c8b7601a..958cc46ae29 100644
--- a/tests/python/bl_rna_manual_reference.py
+++ b/tests/python/bl_rna_manual_reference.py
@@ -15,12 +15,12 @@ import bpy
def test_data():
import rna_manual_reference
- assert(isinstance(rna_manual_reference.url_manual_mapping, tuple))
+ assert isinstance(rna_manual_reference.url_manual_mapping, tuple)
for i, value in enumerate(rna_manual_reference.url_manual_mapping):
try:
- assert(len(value) == 2)
- assert(isinstance(value[0], str))
- assert(isinstance(value[1], str))
+ assert len(value) == 2
+ assert isinstance(value[0], str)
+ assert isinstance(value[1], str)
except:
print("Expected a tuple of 2 strings, instead item %d is a %s: %r" % (i, type(value), value))
import traceback
diff --git a/tests/python/bl_run_operators.py b/tests/python/bl_run_operators.py
index ccb0814e5eb..19e1d41d8cf 100644
--- a/tests/python/bl_run_operators.py
+++ b/tests/python/bl_run_operators.py
@@ -83,7 +83,7 @@ op_blacklist = (
"object.voxel_remesh",
"mesh.paint_mask_slice",
"paint.mask_flood_fill",
- "sculpt.dirty_mask",
+ "sculpt.mask_from_cavity",
# TODO: use empty temp dir to avoid behavior depending on local setup.
"view3d.pastebuffer",
# Needs active window.
diff --git a/tests/python/bl_run_operators_event_simulate.py b/tests/python/bl_run_operators_event_simulate.py
index d218e6b1bc0..e17eaef0480 100644
--- a/tests/python/bl_run_operators_event_simulate.py
+++ b/tests/python/bl_run_operators_event_simulate.py
@@ -461,7 +461,7 @@ class BlenderAction(argparse.Action):
except ArgumentTypeError as ex:
raise ArgumentTypeError("Invalid 'action' arguments \"%s\" at index %d, %s" % (value, index, str(ex)))
# Validation should never yield any events.
- assert(not dummy_result)
+ assert not dummy_result
return (op, args, kwargs)
diff --git a/tests/python/collada/CMakeLists.txt b/tests/python/collada/CMakeLists.txt
index ecc092250c9..27388337de6 100644
--- a/tests/python/collada/CMakeLists.txt
+++ b/tests/python/collada/CMakeLists.txt
@@ -47,5 +47,5 @@ endmacro()
# Tests are disabled because they only work on Windows
# Tests will be redone completely to work reliable
#
-# COLLADA_TEST(mesh simple mesh_simple.blend)
-# COLLADA_TEST(animation simple suzannes_parent_inverse.blend)
+# collada_test(mesh simple mesh_simple.blend)
+# collada_test(animation simple suzannes_parent_inverse.blend)
diff --git a/tests/python/cycles_render_tests.py b/tests/python/cycles_render_tests.py
index 10ba2ce552a..c7e12dd5b7c 100644
--- a/tests/python/cycles_render_tests.py
+++ b/tests/python/cycles_render_tests.py
@@ -33,7 +33,7 @@ BLACKLIST_OPTIX = [
]
BLACKLIST_METAL = [
- # No MNEE for Metal currently
+ # MNEE only works on Metal with macOS >= 13
"underwater_caustics.blend",
]
@@ -56,6 +56,8 @@ BLACKLIST_GPU = [
# Inconsistent handling of overlapping objects.
"T41143.blend",
"visibility_particles.blend",
+ # No path guiding on GPU.
+ "guiding*.blend",
]
diff --git a/tests/python/modifiers.py b/tests/python/modifiers.py
index 11d696c3bed..93448841dfd 100644
--- a/tests/python/modifiers.py
+++ b/tests/python/modifiers.py
@@ -16,10 +16,12 @@ seed(0)
def get_generate_modifiers_list(test_object_name, randomize=False):
"""
Construct a list of 'Generate' modifiers with default parameters.
- :param test_object_name: str - name of test object. Some modifiers like boolean need an extra parameter beside
- the default one. E.g. boolean needs object, mask needs vertex group etc...
- The extra parameter name will be <test_object_name>_<modifier_type>
- :param randomize: bool - if True shuffle the list of modifiers.
+ :arg test_object_name: Name of test object. Some modifiers like boolean need an extra parameter beside
+ the default one. E.g. boolean needs object, mask needs vertex group etc...
+ The extra parameter name will be <test_object_name>_<modifier_type>
+ :type test_object_name: str
+ :arg randomize: If True shuffle the list of modifiers.
+ :type randomize: bool
:return: list of 'Generate' modifiers with default parameters.
"""
diff --git a/tests/python/modules/mesh_test.py b/tests/python/modules/mesh_test.py
index 5b01bfeee94..b698540c367 100644
--- a/tests/python/modules/mesh_test.py
+++ b/tests/python/modules/mesh_test.py
@@ -43,10 +43,10 @@ class ModifierSpec:
def __init__(self, modifier_name: str, modifier_type: str, modifier_parameters: dict, frame_end=0):
"""
Constructs a modifier spec.
- :param modifier_name: str - name of object modifier, e.g. "myFirstSubsurfModif"
- :param modifier_type: str - type of object modifier, e.g. "SUBSURF"
- :param modifier_parameters: dict - {name : val} dictionary giving modifier parameters, e.g. {"quality" : 4}
- :param frame_end: int - frame at which simulation needs to be baked or modifier needs to be applied.
+ :arg modifier_name: str - name of object modifier, e.g. "myFirstSubsurfModif"
+ :arg modifier_type: str - type of object modifier, e.g. "SUBSURF"
+ :arg modifier_parameters: dict - {name : val} dictionary giving modifier parameters, e.g. {"quality" : 4}
+ :arg frame_end: int - frame at which simulation needs to be baked or modifier needs to be applied.
"""
self.modifier_name = modifier_name
self.modifier_type = modifier_type
@@ -66,10 +66,10 @@ class ParticleSystemSpec:
def __init__(self, modifier_name: str, modifier_type: str, modifier_parameters: dict, frame_end: int):
"""
Constructs a particle system spec.
- :param modifier_name: str - name of object modifier, e.g. "Particles"
- :param modifier_type: str - type of object modifier, e.g. "PARTICLE_SYSTEM"
- :param modifier_parameters: dict - {name : val} dictionary giving modifier parameters, e.g. {"seed" : 1}
- :param frame_end: int - the last frame of the simulation at which the modifier is applied
+ :arg modifier_name: str - name of object modifier, e.g. "Particles"
+ :arg modifier_type: str - type of object modifier, e.g. "PARTICLE_SYSTEM"
+ :arg modifier_parameters: dict - {name : val} dictionary giving modifier parameters, e.g. {"seed" : 1}
+ :arg frame_end: int - the last frame of the simulation at which the modifier is applied
"""
self.modifier_name = modifier_name
self.modifier_type = modifier_type
@@ -97,11 +97,11 @@ class OperatorSpecEditMode:
):
"""
Constructs an OperatorSpecEditMode. Raises ValueError if selec_mode is invalid.
- :param operator_name: str - name of mesh operator from bpy.ops.mesh, e.g. "bevel" or "fill"
- :param operator_parameters: dict - {name : val} dictionary containing operator parameters.
- :param select_mode: str - mesh selection mode, must be either 'VERT', 'EDGE' or 'FACE'
- :param selection: sequence - vertices/edges/faces indices to select, e.g. [0, 9, 10].
- :param: select_history: bool - load selection into bmesh selection history.
+ :arg operator_name: str - name of mesh operator from bpy.ops.mesh, e.g. "bevel" or "fill"
+ :arg operator_parameters: dict - {name : val} dictionary containing operator parameters.
+ :arg select_mode: str - mesh selection mode, must be either 'VERT', 'EDGE' or 'FACE'
+ :arg selection: sequence - vertices/edges/faces indices to select, e.g. [0, 9, 10].
+ :arg: select_history: bool - load selection into bmesh selection history.
"""
self.operator_name = operator_name
self.operator_parameters = operator_parameters
@@ -125,8 +125,8 @@ class OperatorSpecObjectMode:
def __init__(self, operator_name: str, operator_parameters: dict):
"""
- :param operator_name: str - name of the object operator from bpy.ops.object, e.g. "shade_smooth" or "shape_keys"
- :param operator_parameters: dict - contains operator parameters.
+ :arg operator_name: str - name of the object operator from bpy.ops.object, e.g. "shade_smooth" or "shape_keys"
+ :arg operator_parameters: dict - contains operator parameters.
"""
self.operator_name = operator_name
self.operator_parameters = operator_parameters
@@ -144,9 +144,9 @@ class DeformModifierSpec:
def __init__(self, frame_number: int, modifier_list: list, object_operator_spec: OperatorSpecObjectMode = None):
"""
Constructs a Deform Modifier spec (for user input)
- :param frame_number: int - the frame at which animated keyframe is inserted
- :param modifier_list: ModifierSpec - contains modifiers
- :param object_operator_spec: OperatorSpecObjectMode - contains object operators
+ :arg frame_number: int - the frame at which animated keyframe is inserted
+ :arg modifier_list: ModifierSpec - contains modifiers
+ :arg object_operator_spec: OperatorSpecObjectMode - contains object operators
"""
self.frame_number = frame_number
self.modifier_list = modifier_list
@@ -163,12 +163,12 @@ class MeshTest(ABC):
def __init__(self, test_object_name, exp_object_name, test_name=None, threshold=None, do_compare=True):
"""
- :param test_object_name: str - Name of object of mesh type to run the operations on.
- :param exp_object_name: str - Name of object of mesh type that has the expected
+ :arg test_object_name: str - Name of object of mesh type to run the operations on.
+ :arg exp_object_name: str - Name of object of mesh type that has the expected
geometry after running the operations.
- :param test_name: str - Name of the test.
- :param threshold: exponent: To allow variations and accept difference to a certain degree.
- :param do_compare: bool - True if we want to compare the test and expected objects, False otherwise.
+ :arg test_name: str - Name of the test.
+ :arg threshold: exponent: To allow variations and accept difference to a certain degree.
+ :arg do_compare: bool - True if we want to compare the test and expected objects, False otherwise.
"""
self.test_object_name = test_object_name
self.exp_object_name = exp_object_name
@@ -302,10 +302,10 @@ class MeshTest(ABC):
def do_selection(self, mesh: bpy.types.Mesh, select_mode: str, selection, select_history: bool):
"""
Do selection on a mesh.
- :param mesh: bpy.types.Mesh - input mesh
- :param: select_mode: str - selection mode. Must be 'VERT', 'EDGE' or 'FACE'
- :param: selection: sequence - indices of selection.
- :param: select_history: bool - load selection into bmesh selection history
+ :arg mesh: bpy.types.Mesh - input mesh
+ :arg: select_mode: str - selection mode. Must be 'VERT', 'EDGE' or 'FACE'
+ :arg: selection: sequence - indices of selection.
+ :arg: select_history: bool - load selection into bmesh selection history
Example: select_mode='VERT' and selection={1,2,3} selects veritces 1, 2 and 3 of input mesh
"""
@@ -366,9 +366,9 @@ class MeshTest(ABC):
def compare_meshes(evaluated_object, expected_object, threshold):
"""
Compares evaluated object mesh with expected object mesh.
- :param evaluated_object: first object for comparison.
- :param expected_object: second object for comparison.
- :param threshold: exponent: To allow variations and accept difference to a certain degree.
+ :arg evaluated_object: first object for comparison.
+ :arg expected_object: second object for comparison.
+ :arg threshold: exponent: To allow variations and accept difference to a certain degree.
:return: dict: Contains results of different comparisons.
"""
objects = bpy.data.objects
@@ -439,14 +439,14 @@ class SpecMeshTest(MeshTest):
"""
Constructor for SpecMeshTest.
- :param test_name: str - Name of the test.
- :param test_object_name: str - Name of object of mesh type to run the operations on.
- :param exp_object_name: str - Name of object of mesh type that has the expected
- geometry after running the operations.
- :param operations_stack: list - stack holding operations to perform on the test_object.
- :param apply_modifier: bool - True if we want to apply the modifiers right after adding them to the object.
- - True if we want to apply the modifier to list of modifiers, after some operation.
- This affects operations of type ModifierSpec and DeformModifierSpec.
+ :arg test_name: str - Name of the test.
+ :arg test_object_name: str - Name of object of mesh type to run the operations on.
+ :arg exp_object_name: str - Name of object of mesh type that has the expected
+ geometry after running the operations.
+ :arg operations_stack: list - stack holding operations to perform on the test_object.
+ :arg apply_modifier: bool - True if we want to apply the modifiers right after adding them to the object.
+ - True if we want to apply the modifier to list of modifiers, after some operation.
+ This affects operations of type ModifierSpec and DeformModifierSpec.
"""
super().__init__(test_object_name, exp_object_name, test_name, threshold)
@@ -491,9 +491,9 @@ class SpecMeshTest(MeshTest):
def _set_parameters_impl(self, modifier, modifier_parameters, nested_settings_path, modifier_name):
"""
Doing a depth first traversal of the modifier parameters and setting their values.
- :param: modifier: Of type modifier, its altered to become a setting in recursion.
- :param: modifier_parameters : dict or sequence, a simple/nested dictionary of modifier parameters.
- :param: nested_settings_path : list(stack): helps in tracing path to each node.
+ :arg: modifier: Of type modifier, its altered to become a setting in recursion.
+ :arg: modifier_parameters : dict or sequence, a simple/nested dictionary of modifier parameters.
+ :arg: nested_settings_path : list(stack): helps in tracing path to each node.
"""
if not isinstance(modifier_parameters, dict):
param_setting = None
@@ -540,8 +540,8 @@ class SpecMeshTest(MeshTest):
def _add_modifier(self, test_object, modifier_spec: ModifierSpec):
"""
Add modifier to object.
- :param test_object: bpy.types.Object - Blender object to apply modifier on.
- :param modifier_spec: ModifierSpec - ModifierSpec object with parameters
+ :arg test_object: bpy.types.Object - Blender object to apply modifier on.
+ :arg modifier_spec: ModifierSpec - ModifierSpec object with parameters
"""
bakers_list = ['CLOTH', 'SOFT_BODY', 'DYNAMIC_PAINT', 'FLUID']
scene = bpy.context.scene
@@ -645,8 +645,8 @@ class SpecMeshTest(MeshTest):
def _apply_operator_edit_mode(self, test_object, operator: OperatorSpecEditMode):
"""
Apply operator on test object.
- :param test_object: bpy.types.Object - Blender object to apply operator on.
- :param operator: OperatorSpecEditMode - OperatorSpecEditMode object with parameters.
+ :arg test_object: bpy.types.Object - Blender object to apply operator on.
+ :arg operator: OperatorSpecEditMode - OperatorSpecEditMode object with parameters.
"""
self.do_selection(
test_object.data,
@@ -695,7 +695,7 @@ class SpecMeshTest(MeshTest):
def _apply_deform_modifier(self, test_object, operation: list):
"""
- param: operation: list: List of modifiers or combination of modifier and object operator.
+ arg: operation: list: List of modifiers or combination of modifier and object operator.
"""
scene = bpy.context.scene
@@ -761,7 +761,7 @@ class RunTest:
def __init__(self, tests, apply_modifiers=False, do_compare=False):
"""
Construct a test suite.
- :param tests: list - list of modifier or operator test cases. Each element in the list must contain the
+ :arg tests: list - list of modifier or operator test cases. Each element in the list must contain the
following
in the correct order:
0) test_name: str - unique test name
@@ -825,7 +825,7 @@ class RunTest:
def run_test(self, test_name: str):
"""
Run a single test from self.tests list
- :param test_name: int - name of test
+ :arg test_name: int - name of test
:return: bool - True if test passed, False otherwise.
"""
case = None
diff --git a/tests/python/modules/render_report.py b/tests/python/modules/render_report.py
index 15d46d6d127..5dcb73b65cc 100755
--- a/tests/python/modules/render_report.py
+++ b/tests/python/modules/render_report.py
@@ -166,6 +166,9 @@ class Report:
def set_fail_threshold(self, threshold):
self.fail_threshold = threshold
+ def set_fail_percent(self, percent):
+ self.fail_percent = percent
+
def set_reference_dir(self, reference_dir):
self.reference_dir = reference_dir
diff --git a/tests/python/modules/test_utils.py b/tests/python/modules/test_utils.py
index 6aba3a75263..60c0c668835 100755
--- a/tests/python/modules/test_utils.py
+++ b/tests/python/modules/test_utils.py
@@ -46,8 +46,8 @@ class AbstractBlenderRunnerTest(unittest.TestCase):
Returns Blender's stdout + stderr combined into one string.
- :param filepath: taken relative to self.testdir.
- :param timeout: in seconds
+ :arg filepath: taken relative to self.testdir.
+ :arg timeout: in seconds
"""
assert self.blender, "Path to Blender binary is to be set in setUpClass()"
diff --git a/tests/python/view_layer/CMakeLists.txt b/tests/python/view_layer/CMakeLists.txt
index 56dc1c8b5e9..8052d375d23 100644
--- a/tests/python/view_layer/CMakeLists.txt
+++ b/tests/python/view_layer/CMakeLists.txt
@@ -20,7 +20,7 @@ set(TEST_BLENDER_EXE $<TARGET_FILE:blender> --background -noaudio --factory-star
# ------------------------------------------------------------------------------
-macro(VIEW_LAYER_TEST test_name)
+macro(view_layer_test test_name)
# Adds ${CMAKE_CURRENT_LIST_DIR} to sys.path so that the tests can import
# things from view_layer_common.py
add_test(view_layer_${test_name} ${TEST_BLENDER_EXE}
@@ -31,129 +31,129 @@ macro(VIEW_LAYER_TEST test_name)
)
endmacro()
-VIEW_LAYER_TEST(active_collection)
-VIEW_LAYER_TEST(background_set)
-VIEW_LAYER_TEST(collection_new_sync)
-VIEW_LAYER_TEST(collection_rename_a)
-VIEW_LAYER_TEST(collection_rename_b)
-# VIEW_LAYER_TEST(evaluation_render_settings_a)
-# VIEW_LAYER_TEST(evaluation_render_settings_b)
-# VIEW_LAYER_TEST(evaluation_render_settings_c)
-# VIEW_LAYER_TEST(evaluation_render_settings_d)
-# VIEW_LAYER_TEST(evaluation_render_settings_e)
-# VIEW_LAYER_TEST(evaluation_render_settings_f)
-# VIEW_LAYER_TEST(evaluation_render_settings_g)
-# VIEW_LAYER_TEST(evaluation_render_settings_h)
-# VIEW_LAYER_TEST(evaluation_render_settings_i)
-VIEW_LAYER_TEST(evaluation_visibility_a)
-VIEW_LAYER_TEST(evaluation_visibility_b)
-VIEW_LAYER_TEST(evaluation_visibility_c)
-VIEW_LAYER_TEST(evaluation_visibility_d)
-VIEW_LAYER_TEST(evaluation_visibility_e)
-VIEW_LAYER_TEST(evaluation_visibility_f)
-VIEW_LAYER_TEST(evaluation_visibility_g)
-VIEW_LAYER_TEST(evaluation_visibility_h)
-VIEW_LAYER_TEST(evaluation_visibility_i)
-VIEW_LAYER_TEST(evaluation_visibility_j)
-VIEW_LAYER_TEST(evaluation_selectability_a)
-VIEW_LAYER_TEST(evaluation_selectability_b)
-VIEW_LAYER_TEST(evaluation_selectability_c)
-VIEW_LAYER_TEST(evaluation_selectability_d)
-VIEW_LAYER_TEST(evaluation_selectability_e)
-VIEW_LAYER_TEST(evaluation_selectability_f)
-VIEW_LAYER_TEST(group_a)
-VIEW_LAYER_TEST(group_b)
-VIEW_LAYER_TEST(group_c)
-VIEW_LAYER_TEST(group_d)
-VIEW_LAYER_TEST(group_e)
-VIEW_LAYER_TEST(object_add_cylinder)
-VIEW_LAYER_TEST(object_add_empty)
-VIEW_LAYER_TEST(object_add_torus)
-VIEW_LAYER_TEST(object_add_no_collection_cylinder)
-VIEW_LAYER_TEST(object_add_no_collection_empty)
-VIEW_LAYER_TEST(object_add_no_collection_torus)
-VIEW_LAYER_TEST(object_copy)
-VIEW_LAYER_TEST(object_delete_a)
-VIEW_LAYER_TEST(object_delete_b)
-VIEW_LAYER_TEST(object_link_a)
-VIEW_LAYER_TEST(object_link_b)
-VIEW_LAYER_TEST(object_link_c)
-VIEW_LAYER_TEST(operator_context)
-VIEW_LAYER_TEST(make_single_user)
-VIEW_LAYER_TEST(move_above_below_scene_collection_a)
-VIEW_LAYER_TEST(move_above_below_scene_collection_b)
-VIEW_LAYER_TEST(move_above_below_scene_collection_c)
-VIEW_LAYER_TEST(move_above_below_scene_collection_d)
-VIEW_LAYER_TEST(move_above_below_scene_collection_e)
-VIEW_LAYER_TEST(move_above_below_scene_collection_f)
-VIEW_LAYER_TEST(move_above_below_scene_collection_g)
-VIEW_LAYER_TEST(move_above_below_scene_collection_h)
-VIEW_LAYER_TEST(move_above_below_scene_collection_i)
-VIEW_LAYER_TEST(move_above_below_scene_collection_sync_a)
-VIEW_LAYER_TEST(move_above_below_scene_collection_sync_b)
-VIEW_LAYER_TEST(move_above_below_scene_collection_sync_c)
-VIEW_LAYER_TEST(move_above_below_scene_collection_sync_d)
-VIEW_LAYER_TEST(move_above_below_scene_collection_sync_e)
-VIEW_LAYER_TEST(move_above_below_scene_collection_sync_f)
-VIEW_LAYER_TEST(move_above_below_scene_collection_sync_g)
-VIEW_LAYER_TEST(move_above_below_scene_collection_sync_h)
-VIEW_LAYER_TEST(move_above_below_scene_collection_sync_i)
-VIEW_LAYER_TEST(move_into_scene_collection_a)
-VIEW_LAYER_TEST(move_into_scene_collection_b)
-VIEW_LAYER_TEST(move_into_scene_collection_c)
-VIEW_LAYER_TEST(move_into_scene_collection_d)
-VIEW_LAYER_TEST(move_into_scene_collection_e)
-VIEW_LAYER_TEST(move_into_scene_collection_f)
-VIEW_LAYER_TEST(move_into_scene_collection_g)
-VIEW_LAYER_TEST(move_into_scene_collection_h)
-VIEW_LAYER_TEST(move_into_scene_collection_i)
-VIEW_LAYER_TEST(move_into_scene_collection_j)
-VIEW_LAYER_TEST(move_into_scene_collection_k)
-VIEW_LAYER_TEST(move_into_scene_collection_l)
-VIEW_LAYER_TEST(move_into_scene_collection_sync_a)
-VIEW_LAYER_TEST(move_into_scene_collection_sync_b)
-VIEW_LAYER_TEST(move_into_scene_collection_sync_c)
-VIEW_LAYER_TEST(move_into_scene_collection_sync_d)
-VIEW_LAYER_TEST(move_into_scene_collection_sync_e)
-VIEW_LAYER_TEST(move_into_scene_collection_sync_f)
-VIEW_LAYER_TEST(move_into_scene_collection_sync_g)
-VIEW_LAYER_TEST(move_into_scene_collection_sync_h)
-VIEW_LAYER_TEST(move_into_scene_collection_sync_i)
-VIEW_LAYER_TEST(move_into_scene_collection_sync_j)
-VIEW_LAYER_TEST(move_into_scene_collection_sync_k)
-VIEW_LAYER_TEST(move_into_scene_collection_sync_l)
-VIEW_LAYER_TEST(move_above_below_layer_collection_a)
-VIEW_LAYER_TEST(move_above_below_layer_collection_b)
-VIEW_LAYER_TEST(move_above_below_layer_collection_c)
-VIEW_LAYER_TEST(move_above_below_layer_collection_d)
-VIEW_LAYER_TEST(move_above_below_layer_collection_e)
-VIEW_LAYER_TEST(move_above_below_layer_collection_f)
-VIEW_LAYER_TEST(move_above_below_layer_collection_g)
-VIEW_LAYER_TEST(move_above_below_layer_collection_h)
-VIEW_LAYER_TEST(move_above_below_layer_collection_i)
-VIEW_LAYER_TEST(move_above_below_layer_collection_j)
-VIEW_LAYER_TEST(move_above_below_layer_collection_k)
-VIEW_LAYER_TEST(move_above_below_layer_collection_l)
-VIEW_LAYER_TEST(move_into_layer_collection_a)
-VIEW_LAYER_TEST(move_into_layer_collection_b)
-VIEW_LAYER_TEST(move_into_layer_collection_c)
-VIEW_LAYER_TEST(move_into_layer_collection_d)
-VIEW_LAYER_TEST(move_into_layer_collection_e)
-VIEW_LAYER_TEST(move_into_layer_collection_f)
-VIEW_LAYER_TEST(move_into_layer_collection_g)
-VIEW_LAYER_TEST(move_into_layer_collection_h)
-VIEW_LAYER_TEST(move_into_layer_collection_i)
-VIEW_LAYER_TEST(move_into_layer_collection_j)
-VIEW_LAYER_TEST(layer_linking)
-VIEW_LAYER_TEST(layer_syncing)
-VIEW_LAYER_TEST(scene_collection_delete)
-VIEW_LAYER_TEST(scene_copy_a)
-VIEW_LAYER_TEST(scene_copy_b)
-VIEW_LAYER_TEST(scene_copy_c)
-VIEW_LAYER_TEST(scene_copy_d)
-VIEW_LAYER_TEST(scene_copy_e)
-VIEW_LAYER_TEST(scene_copy_f)
-VIEW_LAYER_TEST(scene_delete)
-VIEW_LAYER_TEST(scene_objects)
-VIEW_LAYER_TEST(scene_write_read)
-VIEW_LAYER_TEST(view_layer_rename)
+view_layer_test(active_collection)
+view_layer_test(background_set)
+view_layer_test(collection_new_sync)
+view_layer_test(collection_rename_a)
+view_layer_test(collection_rename_b)
+# view_layer_test(evaluation_render_settings_a)
+# view_layer_test(evaluation_render_settings_b)
+# view_layer_test(evaluation_render_settings_c)
+# view_layer_test(evaluation_render_settings_d)
+# view_layer_test(evaluation_render_settings_e)
+# view_layer_test(evaluation_render_settings_f)
+# view_layer_test(evaluation_render_settings_g)
+# view_layer_test(evaluation_render_settings_h)
+# view_layer_test(evaluation_render_settings_i)
+view_layer_test(evaluation_visibility_a)
+view_layer_test(evaluation_visibility_b)
+view_layer_test(evaluation_visibility_c)
+view_layer_test(evaluation_visibility_d)
+view_layer_test(evaluation_visibility_e)
+view_layer_test(evaluation_visibility_f)
+view_layer_test(evaluation_visibility_g)
+view_layer_test(evaluation_visibility_h)
+view_layer_test(evaluation_visibility_i)
+view_layer_test(evaluation_visibility_j)
+view_layer_test(evaluation_selectability_a)
+view_layer_test(evaluation_selectability_b)
+view_layer_test(evaluation_selectability_c)
+view_layer_test(evaluation_selectability_d)
+view_layer_test(evaluation_selectability_e)
+view_layer_test(evaluation_selectability_f)
+view_layer_test(group_a)
+view_layer_test(group_b)
+view_layer_test(group_c)
+view_layer_test(group_d)
+view_layer_test(group_e)
+view_layer_test(object_add_cylinder)
+view_layer_test(object_add_empty)
+view_layer_test(object_add_torus)
+view_layer_test(object_add_no_collection_cylinder)
+view_layer_test(object_add_no_collection_empty)
+view_layer_test(object_add_no_collection_torus)
+view_layer_test(object_copy)
+view_layer_test(object_delete_a)
+view_layer_test(object_delete_b)
+view_layer_test(object_link_a)
+view_layer_test(object_link_b)
+view_layer_test(object_link_c)
+view_layer_test(operator_context)
+view_layer_test(make_single_user)
+view_layer_test(move_above_below_scene_collection_a)
+view_layer_test(move_above_below_scene_collection_b)
+view_layer_test(move_above_below_scene_collection_c)
+view_layer_test(move_above_below_scene_collection_d)
+view_layer_test(move_above_below_scene_collection_e)
+view_layer_test(move_above_below_scene_collection_f)
+view_layer_test(move_above_below_scene_collection_g)
+view_layer_test(move_above_below_scene_collection_h)
+view_layer_test(move_above_below_scene_collection_i)
+view_layer_test(move_above_below_scene_collection_sync_a)
+view_layer_test(move_above_below_scene_collection_sync_b)
+view_layer_test(move_above_below_scene_collection_sync_c)
+view_layer_test(move_above_below_scene_collection_sync_d)
+view_layer_test(move_above_below_scene_collection_sync_e)
+view_layer_test(move_above_below_scene_collection_sync_f)
+view_layer_test(move_above_below_scene_collection_sync_g)
+view_layer_test(move_above_below_scene_collection_sync_h)
+view_layer_test(move_above_below_scene_collection_sync_i)
+view_layer_test(move_into_scene_collection_a)
+view_layer_test(move_into_scene_collection_b)
+view_layer_test(move_into_scene_collection_c)
+view_layer_test(move_into_scene_collection_d)
+view_layer_test(move_into_scene_collection_e)
+view_layer_test(move_into_scene_collection_f)
+view_layer_test(move_into_scene_collection_g)
+view_layer_test(move_into_scene_collection_h)
+view_layer_test(move_into_scene_collection_i)
+view_layer_test(move_into_scene_collection_j)
+view_layer_test(move_into_scene_collection_k)
+view_layer_test(move_into_scene_collection_l)
+view_layer_test(move_into_scene_collection_sync_a)
+view_layer_test(move_into_scene_collection_sync_b)
+view_layer_test(move_into_scene_collection_sync_c)
+view_layer_test(move_into_scene_collection_sync_d)
+view_layer_test(move_into_scene_collection_sync_e)
+view_layer_test(move_into_scene_collection_sync_f)
+view_layer_test(move_into_scene_collection_sync_g)
+view_layer_test(move_into_scene_collection_sync_h)
+view_layer_test(move_into_scene_collection_sync_i)
+view_layer_test(move_into_scene_collection_sync_j)
+view_layer_test(move_into_scene_collection_sync_k)
+view_layer_test(move_into_scene_collection_sync_l)
+view_layer_test(move_above_below_layer_collection_a)
+view_layer_test(move_above_below_layer_collection_b)
+view_layer_test(move_above_below_layer_collection_c)
+view_layer_test(move_above_below_layer_collection_d)
+view_layer_test(move_above_below_layer_collection_e)
+view_layer_test(move_above_below_layer_collection_f)
+view_layer_test(move_above_below_layer_collection_g)
+view_layer_test(move_above_below_layer_collection_h)
+view_layer_test(move_above_below_layer_collection_i)
+view_layer_test(move_above_below_layer_collection_j)
+view_layer_test(move_above_below_layer_collection_k)
+view_layer_test(move_above_below_layer_collection_l)
+view_layer_test(move_into_layer_collection_a)
+view_layer_test(move_into_layer_collection_b)
+view_layer_test(move_into_layer_collection_c)
+view_layer_test(move_into_layer_collection_d)
+view_layer_test(move_into_layer_collection_e)
+view_layer_test(move_into_layer_collection_f)
+view_layer_test(move_into_layer_collection_g)
+view_layer_test(move_into_layer_collection_h)
+view_layer_test(move_into_layer_collection_i)
+view_layer_test(move_into_layer_collection_j)
+view_layer_test(layer_linking)
+view_layer_test(layer_syncing)
+view_layer_test(scene_collection_delete)
+view_layer_test(scene_copy_a)
+view_layer_test(scene_copy_b)
+view_layer_test(scene_copy_c)
+view_layer_test(scene_copy_d)
+view_layer_test(scene_copy_e)
+view_layer_test(scene_copy_f)
+view_layer_test(scene_delete)
+view_layer_test(scene_objects)
+view_layer_test(scene_write_read)
+view_layer_test(view_layer_rename)